diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..729361864 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,20 @@ +The AUTHORS file: + +This file should collect a trace of all the legal paperwork that you have +exchanged with contributors for your particular package. This information is +very useful for registering the copyright of your package. The file might +have an introductory blurb similar to this one: + + Authors of PACKAGE + + The following contributions warranted legal paper exchanges + with [the Free Software Foundation | Your Name]. + Also see files ChangeLog and THANKS + +Then, list who the contributors are and what files they have worked on. +Indicate whether they created the file, or whether they modified it. For +example: + + Random J. Hacker: + entire files -> foo1.c , foo2.c , foo3.c + modifications -> foo4.c , foo5.c diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..38ac3c19a --- /dev/null +++ b/ChangeLog @@ -0,0 +1,563 @@ +MaNGOS 0.12 (??? ??? 2008) + + MaNGOS 0.12 - Codename "???" - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + ==== Game Features ==== + + ==== Server Features ==== + + ==== Statistics ==== + * Fixed Bugs: ??? + * Total number of changes: ??? + +MaNGOS 0.11 (Jul 22 2008) + + MaNGOS 0.11 - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + ==== Game Features ==== + + * Added: Support for show possible blocked damage, armor penetration, negative stats and other data in client. + * Added: Support for show aura charges in client. + * Added: Support for spell casting delay at damage dependence from casting partly interrupts amount, apply interrupts in spell direct damage case also. + * Added: Support for form requirement check for item/itemset casts at equip. Correctly cast at equip and cast/remove at form switch. + * Added: Support for correct speed bonus stacking. + * Added: Support for instant honor updating. + * Added: Support for cap experience received from high level creatures. + * Added: Support mining/herbalism mode for skinning of special creatures. + * Added: Support for more battleground types, many improvements in battlegrounds work. + * Added: Support for quests work with player title rewards, check for shareable quests base at quest flags. + * Added: Support for quest rewarding with mail send after specific delay with possible items sent. + * Added: Support for boss +3 target dependent level for attack rolls and chances. + * Added: Support for dodge chance calculations depends from agility and level (use dbc based values) instead wrong hardcoded values. + * Added: Support for defense/weapon skills maxed in PvP fight. + * Added: Support for bilinear interpolation use for height calculation between existed map point data for better ground height selection for point. + * Added: Support for corpse reclaim delay dependence from character death count in last period. + * Added: Support for creatures movement flags storing in DB and setup from scripts, also store extra flags to mark creatures that can't parry/block/counterattack or not provide xp at kill. + * Added: Support for offhand expertize. + * Added: Support for generation of pet passive auras by DBC data. + * Improved: Re-Implemented group/friend/enemy/pet area auras. + * Improved: Finished fill spell_affect DB table allow have related spells correct working. Now only required update table at client switch. + * Improved: Allow DoTs/HoTs ticks from dead caster if its not required caster alive state. + * Improved: Better spell targeting selection code. + * Improved: Removed outdated honor diminishing return support. + * Improved: Fixed well known unexpected sit at stun bug. + * Improved: More correct show and work with faction reputation. + * Improved: Finish update to expected level dependent mana/health stats data for player's classes. + * Improved: Better creature corpse despawn time selection. Corpse instant despawn after skinning. + * Improved: Better check in front spell target requirement. + * Improved: Show parry/dodge/block/crit calculation in client for same level creature enemy. + * Improved: Correctly show item random property in all cases, including random property with suffix factor, in inspect and in equipped state at other player. + * Improved: Use correct way to check binding items and check enchants apply in trade slot. + * Improved: Rewritten mana regen calculation, also implement creature in combat mana regeneration delay. + * Improved: Fixed long time existed problem with unexpected auto start melee attack after spell casting. + * Improved: Re-implemented diminishing returns system. + * Improved: Re-implemented fear movement. + * Improved: Rewritten distract/dispel/spell steal effects. + * Improved: Updated pet name generation data in DB. + * Improved: Better work combat enter/leave system in PvP/PvE cases. + * Improved: Many items and item set effects start work. + * plus lots of fixes for auras, effects, spells, talents, and more. + + ==== Server Features ==== + + * Added: New sql/tools directory for useful SQL queries for check and restore DB integrity. + * Added: Own counter for HIGHGUID_PET low guids. Use it for pets. This let have lot more range for pet guids, and then more creature guid for instances spawns/totems. + * Added: Replace existed random generators by Mersenne Twister random number generator. + * Added: Support for Russian, Spanish Mexico, traditional and simplified Chinese clients to ad.exe. + * Added: Support for using the failed_logins field in the account table. Support IP/account temporary ban at max allowed failed logins for account. + * Added: Support for --enable-doxygen to enable doc generation at configure use at Unix/Linux. + * Added: Anti-freeze system. + * Added: AD.EXE now also extracts DBC files. It also now searches for patch files dynamically. + * Improved: Updated MySQL client libs to 5.0.56. + * Improved: Better checking DB data at server loading. + * Improved: Apply reserver names check to pet/charter names also. + * Improved: Move hardcoded base fishing skill for zone from code to new DB table. + * Improved: Removed `spell_learn_skill` and `PlayerCreateInfo_skill` tables, use DBC data instead. + * Improved: Many improvements in Gamemaster chat commands. + * Improved: Many improvements in config options. + * Improved: Better scripting support (DB base and C++ based scripts). + + ==== Statistics ==== + * Fixed Bugs: 194 + * Total number of changes: 708 + +MaNGOS 0.10 (Apr 18 2008) + + MaNGOS 0.10 - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + ==== Game Features ==== + + * Added: Implement talent inspecting. + * Added: Implement unique equipped items support, including gems. + * Added: Check instances where mount using allowed. Still need implement in-building check. + * Added: Implement master looter loot mode. + * Added: Implement quest related lootable gameobject activating only for characters with active quest. + * Added: Implement multi-map taxi flights, allow teleport to instances/battleground in taxi flight time. + * Added: Allow equip 2hand weapon in case swap with equipped mainhand/offhand weapon pair. + * Added: Implement player confirmation request at player summon attempt. + * Added: Implement support items with limited lifetime. + * Added: Implement chance additional items crafting with appropriate profession specialization. + * Added: Implement FFA PvP zones and FFA PvP server type. + * Added: Implement Guild Banks. + * Added: Implement expertise and better rating work. + * Added: Implement dialog status show for gameobject like yellow exclamation signs above gameobject if quest available. + * Added: Implement money requirement show for gossip box open. + * Added: Apply reputation discounts to trainer spell prices. + * Added: Implement death at fall to void/textures. + * Added: Support dead by default creatures. + * Added: Implemented work some nice items like "safe" teleport items. + * Added: Implement correct stacking elixirs/flasks. + * Added: Implement Fishing hole gameobjects work. + * Added: Implement support correctly sitting at chairs with different height and slots. + * Added: Implement normalized weapon damage use where it expected. + * Improved: Limit player money amount by 214748g 36s 46c. + * Improved: Allow join to LFG channel if character registered in LFG tool. + * Improved: Better detection and calculation in fall damage. + * Improved: Update XP generation for high levels and use coefficients dependent from new/old continents position. + * Improved: Better immunity/resisted/interrupting spell work. + * Improved: Better check area/zone/map/mapset limited spells at cast and zone leave. + * Improved: Fixed long time existed problems with client crash at group member using transports. + * Improved: Add/update lot spell_affect/spell_proc_event tables content that let work many talents, spells, and item effects. + * Improved: Better mail system work, use it for problematic items at character loading, and sending honor marks if need. + * Improved: Use correct coefficients for damage/healing spell bonuses for many spells. + * Improved: Restore work weather system. + * Improved: More correct spell affects stacking at target, and spell icons stacking in spellbook. + * Improved: More correct work explicit target positive aura rank auto-selection and implemented area auras rank auto-selection. + * Improved: Correct work permanent skill bonuses. + * Improved: Prevent lost money at unexpected double pay for learned spell with lags. + * Improved: More correct show for other players character state under different spell affects and in time spell casting. + * Improved: More correct random item enchantment bonuses selection and work code. + * Improved: Better battlegrounds work. + * Improved: Implement default open doors/pushed buttons support. + * plus lots of fixes for auras, effects, spells, talents, and more. + + ==== Server Features ==== + + * Added: broken spells check at use and loading. + * Added: Implement pid file support. + * Added: Extract and include svn revision version data in binaries at build. + * Added: Implement binding socket to specific network interface (IP address) instead all interfaces using new config option. + * Added: Implement support 64-bit binaries building at Windows. + * Added: Enable the LARGEADDRESSAWARE flag for Visual Studio 2003 mangosd and realmd projects. + * Improved: Allow Gamemasters see any creature/gameobject including invisible/stealth, allow select unselectable units. + * Improved: Many server-side check for casts (while shapeshifted, other caster and target reqirents) to prevent cheating. + * Improved: better loot system implementation including more loot conditions support and simplify loot managment for DB creators. + * Improved: better DB content error reporting at server load.` + * Improved: Many improvements in Gamemaster chat commands. + * Improved: Update sockets library to v.2.2.9 version. + * Improved: More arena support but not full yet. + * Improved: Less amount data sent to clients, including in spell casting time. + * Improved: Fixed/finish PostgreSql support. + * Improved: Better scripting support (DB base and C++ based scripts). + + ==== Statistics ==== + * Fixed Bugs: 784 + * Total number of changes: 804 + +MaNGOS 0.9 (Dec 14 2007) + + MaNGOS 0.9 - Codename "Flight Master" - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + ==== Game Features ==== + * Added: support for recipe discovery, + * Added: support for allowing use of an item only in a specific map or area, + * Added: support for free-for-all quest/non-quest loot items, additional loot conditions, + * Improved: a more correct implementation of XP gain (level dependent) when in a group, + * Improved: fixed creature killed from DoTs but remaining stuck with 1/3 health, + * Improved: spell and melee crit chance now calculated from DBC data and combat rating coefficients, + * Improved: a more correct implementation of mana/health regeneration calculation, including quick health regeneration in a polymorphed state, + * Improved: better support for quests with multiple speakto goals, less dependent on DB for quest flag calculation, + * Improved: more functionality added to battlegrounds, including correctly showing battleground scores, + * Improved: a more correct implementation of reputation gain for other factions from the same team, + * Improved: better support for simple database scripts (quest-start/end, buttons, spells) + * plus lots of fixes for auras, effects, spells, talents, and more. + + ==== Server Features ==== + * Added: support for running mangosd/realmd as Windows services, + * Added: support for auto-generation of mangosd/realmd crash reports (Windows version only), + * Added: support for Visual Studio 2008 Express and Pro, + * Added: support for new Char.log for basic character operations, including save dump of character data on deletion, and logging client IP, + * Added: support for players queue at login, + * Improved: better DB content error reporting at server load, + * Improved: division of Mangos DataBase to MangosDB(WorldDB) and CharactersDB. + * Improved: better support for older autoconf / automake versions, + * Improved: existing chat and console commands for server gamemasters/administrators, and added new commands. + + ==== Statistics ==== + * Fixed Bugs: 161 + * Total number of changes: 228 + +MaNGOS 0.8 (Oct 16, 2007) + + MaNGOS 0.8 - Codename "Innkeeper" - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + Important License Change Notice: MaNGOS still is licensed under the terms + of the GPL v2, but we now have added an exception to officially allow our + users to link MaNGOS against the OpenSSL libraries. + + ==== Game Features ==== + * Added: a new threat manager was introduced, + * Added: log more GM activities, + * Added: many new features for creatures and game objects working, + * Added: support for client build 6898, aka version 2.1.3, + * Added: support for custom creature equipment and display, + * Added: support for daily quests, + * Added: support for different fishing loot in sub-zones, + * Added: support for gender specific models, + * Added: support for instance specific scripts and data, + * Added: support for localization of names, texts, etc., + * Added: support for multiple battleground instances, + * Added: support for scripted game object buttons, + * Improved: battlegrounds should be mostly working, only a few issues left, + * Improved: dungeon system has seen a few improvements, + * Improved: formulas for most aspects of the game, + * Improved: many player level up values have been corrected, + * Improved: pet and demon handling has seen a lot of improvements, + * Improved: properly divide loot and reputation in groups, + * Rewritten: battleground queue system, + * Rewritten: invisibility detection, + * plus lots of fixes for auras, effects, spells, talents, and more. + + ==== Server Features ==== + * Added: support for database transactions, + * Added: support for height maps -- named vmaps -- to tackle the LOS issue, + * Added: support for OpenBSD and FreeBSD building, + * Fixed: lots of memory leaks closed, + * Fixed: Numerous bug fixes to the core, + * Improved: database queries adding performance boosts here and there, + + ==== Statistics ==== + * Fixed Bugs: 528 + * Total number of changes: 558 + +MaNGOS 0.7 (Jul 9, 2007) + + MaNGOS 0.7 - Codename "Eye of the Storm" -adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + +==== Game Features ==== + * Fixed: random item enchantment display in the auction/mail/group loot dialogs. The item properties are also properly applied to the items at creation. + * Added: support for opening gameobjects/items using their specific keys. Implemented key requirements for entering instances. + * Added: a threat based aggro system along with threat bonuses from spells. + * Implemented many additional spell effects and auras. The spell system is one step closer to completeness. + * Improved: creature/player hostility checks using more accurate faction hostility data. Hostility is checked when casting spells including area-of-effect spells. + * Fixed: parry/dodge related code. + * Improved rage generation formula on blocked attacks/armor reduction etc. + * Fixed: creature movement problems after creature stun/roots and creature orientation in some cases. + * Fixed: some small problems in the player inventory system. + * Added: support for all resurrection methods for various classes. Resurrection from corpse is also implemented. + * Fixed: showing cooldown for items and spells, server side check and saving to the database is also implemented. + * Added: support for gift creation. + * Improved: the pet system and more improvements will follow in next release. + * Added: keyring support. + * Improved: many features related to raids/groups. + * Added: support for in game guild creation. Guild system can be considered finished. Arena team creation is also partly implemented. + * Added: target immunity. The targetable flag and the creature type limitation for spell targeting, which is now check when creating the target list, allows area spells against specific creature types like undeads/demons to work. + * Added: support for diminishing duration of stun/fear/etc effects. + * Rewrote: pet stable code along with improvements and bug fixes. + * Added: support for who list filters. + * Added: the instance system. + * Fixed: the weather system, now common weather is shown for all players in the same zone. + * Improved: the mail system and implemented the delay for mails containing items. + * Added: an initial version of the battleground system. One type of battleground is mostly done, still needs more work. + * Added: the jewelry profession, prospecting and support for inserting gems in sockets including meta gems bonuses. + * Added: support for multi-mining veins. + * Added: support for auto-renaming of characters on login at the request of GMs. + * Added: a new, more correct visibility system, invisibility is also implemented correctly now. + * Improved: durability cost calculation. + + ==== Server Features ==== + * Added: full support for 2.0.x client branch. + * Added/improved: many GM-commands. + * Added: many checks for DB data at server load to simplify detecting problems and DB development. + * Moved: many data stored in code to the DB and cached most static DB data at server load to speed up runtime access to it. + * Added: support for saving next spawn time for creatures/GOs which is now used it at grid/server load. + * Improved: the script system allowing more item/creature/GO scripts with more features to be written easily. + * Added: size checking for all packets received from the to prevent crashes at wrong data. Many other received data check were also added to prevent cheating. + * Improved: the compatibility with 64-bit platforms. + * Added: support for account password encryption in the DB to increase secure security. + * Added: support for a log directory and the date info is now added to log name. + * Updated: the network library to a recent version. + * Fixed: many memory leaks and crases sources. + * Added: DBC locale support that can be set from mangosd.conf. + + ==== Statistics ==== + * Fixed Bugs: 390 + * Total number of changes: 923 + +MaNGOS 0.6 (Jan 29, 2007) + + MaNGOS 0.6 - Codename "Black Dragonflight" - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + ==== Game Features ==== + * Creature and game object respawning has finally been fixed and is considered finished. + * Many improvements to decrease time for saving player data, and transaction support for save operations has been added. + * Many item fixes for using / equipping/ enhancing function (some errors still remain and have to be resolved). + * All professions work now (many fixes have been implemented, you may now enjoy fishing). + * Mail and auction house system has been rewritten, finally should work as it supposed to be. + * Spell system has received a HUGE number of improvements, and should feel much better. (Still many problems are left to be fixed, most notable include procflag spell casting, also many effects and auras are not implemented yet). + * Pet-stable implemented. Many improvements in hunter and warlock pet system (Problems with pet casting exists, various other minor bugs too). + * Rest system can be considered finished. + * Quest system has been rewritten (some problems remain unresolved). + * Implemented PvP system, and support PvE and PvP realm types. + * Duel system has been rewritten and can be considered complete (minor bugs still remain: e.g. characters sometimes may be killed in duels by channeled spells, or after duels finished by pets still attacking). + * Guild system improvements, including guild charter, guild master, and guild tabard work. (Some bugs reported about losing tabard style, etc). + * Some taxi system fixes and improvements. Switched to use DBC only data for taxi system work. + * Group related code has been rewritten, and extended to support raid groups. + * Loot code improvements and implementing group loot modes (except master loot mode). + * Correct implementation for creature skinning has been added. + * Unlearning talents, and unlearning spells with first rank received from unlearned talent implemented. + * Transports (ships/zeppelins) system implemented (still have some synchronization problems). + * Many fixes in combat system (Still have many problems). + * Enchanting in trade slot implemented as last not implemented part of trade system. Many other fixes. + * Rogue stealth for other players implemented and many fixes in druid forms. + + ==== Server Features ==== + * Full support for 1.12.x client branch has been implemented. + * Many GM-commands added and improved including GM mode state and GM invisibility. + * Many cheating preventing checks added and code rewrites. + * DB-based scripting support added for quest emote scripts and spell event scripts. + * Many improvements in less client-server data amount transferring. + + ==== Statistics ==== + * Fixed Bugs: 306 + * Total number of changes: 874 + +MaNGOS 0.5 (Sep 20, 2006) + + MaNGOS 0.5 - Codename "Stable Master" - adds further improvements to the + server core as well as to the majority of game classes and the game content + database. + + Most noteable changes include cleaning up the database backend, adding proper + support for game clients of version 1.10.2, and closing lots of threading and + memory related bugs. Cross-platform support has been improved as well, MaNGOS + should build and run on FreeBSD as well. + + Feature-wise, support for pets, totems, more spells, talents, etc. have been + added, as well as lots of quest related features. + + ==== Statistics ==== + * Fixed Bugs: 544 + * Total number of changes: 1828. + +MaNGOS 0.1 (Dec 04, 2005) + + MaNGOS 0.1 - Codename "Lightbringer" -adds further improvements to the server + core as well as to the majority of game classes and the game content database. + A complete list of all updated items follows below: + + === Game Features === + * Add all AI files to the build process on Windows + * Added: Better item information updates. + * Added: Check on death for invalid duel status. + * Added: Client now shows full Creature information. + * Added: Creature::_RealtimSetCreatureInfo procedure which only sets changed values for realtime usage. + * Added: DEBUG_LOG for logging debug messages. Works with --debug-info switch on Linux and debug build on Windows. + * Added: Extra information for NPC and item information transmissions. + * Added: GM command .modify spell spellflatID,val,mark. + * Added: Guild structures, creation, saving data to DB. + * Added: Initial support for binding heart stones to a location. + * Added: Initial support for Guilds. Loading from DB, class, creation and management functions, plus some opcodes supported. + * Added: Initial support for item stacks. + * Added item page text display for detailed item info. + * Added: Level 3 command for Guild creation. + * Added: Linux Makefiles will now install mangosd.conf to sysconfdir when running "make install" after build. + * Added pragma's to disable stupid compiler warnings. Code now compiles cleanly. + * Added: Random generation of damage values for weapons based on their level. + * Added: RandomMovementGenerator. Template not yet implemented. + * Added SharedDefines.h (and updated some enums with more values). + * Added: Sheath code. + * Added: Some DB cleaning tools, hard-coded damage can be removed now. + * Added: some movement related classes. + * Added: SQL tables for guilds. + * Added: Support for additional spells. + * Added support for AIM system ( Artificial Intelligence and Movement ). + * Added: Support for client 1.8.3. + * Added support for Guild System, still has some bugs, about 85% done. + * Added support for Honor System, initial support is done, calculations need love. + * Added support for IP logging of players. + * Added: Support for page texts. + * Added: Support for QuestAreaPoints. + * Added support for reputation. + * Added: Support for tutorials. + * added the opcode name in the world.log for bether cheking + * Added: Weapon damage genrator now adds extra damage types for some items. + * Add Tools,DBC Editer,you can use it to edit all .dbc File, + * AI delivery + * Fix duel flag object position + * Fixed and sped up the players array code. + * Fixed: Armor settings. + * Fixed: Bug fixes for crash and other stuff. + * Fixed: Character bug on login closed. + * Fixed character creation bug + * Fixed: Commented wrong lines in last commit. Now correct ones commented. + * Fixed: Creation of item spells. + * Fixed: Creature::SaveToDB() code fixed. I messed it up while trying to sort out NPC corpse issue. Now back to normal. + * Fixed dead NPC issue. + * Fixed: Double Jump bug fixed with a temporary solution. + * Fixed: Fixed duplicate inclusion of Opcodes.cpp and Opcodes_1_7_x.cpp in game and mangosd directory for VC7 build. + * Fixed: Friendly NPCs attacking. + * Fixed Game Objects, now signs other objects all display. + * fixed gametickets at last,added error handling,character can have only 1 gmticket + * Fixed: Handle the bad data for guid and LOW/HIGH GUID. + * Fixed: Intel C++ VC project now compiles. + * Fixed: Item query code fixed. Item now display most stats (90%). + * Fixed: ItemQuery opcode. This prevents a crash when talking to some vendors. + * Fixed: Minor fixes for Creatures health, added some comments. + * Fixed: NPC texts. + * Fixed: One of the lines in ObjectAccessor.cpp wa removed by accident in changeset #356, causing nearby creatures not roaming, thus not attacking for aggressors. + * Fixed: Proper comparison for maxhealth. + * Fixed: Release build for 1.8 and default Grid ON + * Fixed: Resolve dead NPCs, maxhealth setting. + * Fixed Skill check for equiping Items. + * Fixed: Small fix for Windows build in ObjectAccessor::Update(const uint32 &diff). + * Fixed: Talent modifiers. + * Fixed: Talent percent work. + * Fixed: Vendors now load and display items. + * Fix: now the player can only equip item, if have the proper skill + * Fix two player in the same zone cores. Fix mem leaks in 1.8 mask deletion. And fix core dump for npc handler due to GUI only takes lower part. + * Function _ApplyItemMods() is protected... then i created a public function ApplyItemMods() that calls it... Object Oriented Project, guys! + * Function SetStanding() has been created. Now needs to put it on places where the standing of the reputation is increased. + * Initial delivery of the AI framework.. + * Major CPU usage improvements with grid system disabled. + * msg of ignore list fixed + * Now Faction.dbc is being loaded. + * Progress bar code enhanced. + * Put back compression. Apparently the core problem of two players is NOT solved cuz I can still replicate it. + * Removed: All ENABLE_GRID_SYSTEM defines removed. + * Removed: Some operation out of Creature::Updated. Resolve dead NPCs. + * Reputation: first step. List of factions has been created. Some opcodes are working now. + * Reputation: second step. _LoadReputation, _SaveReputation, LoadReputationFromDBC functions have been created. Now all reputation factions are into factions list. + * Reputation System is now fixed. All functions are fixed. Load and save to DB are fine. The file reputation.sql has been updated. + * Reputation table has been created... update your Data Base! + * Resolved: Outstanding issues in phase 2 of grid system, still some left. + * Small reputation table sql fix for compatability. Remove latin character requirement. + * Started adding Enchant spell code. + * Started writing local items cache. (disabled) + * Still working on reputation... now FactionTemplate.dbc is loaded. + * Trainer code fixed. Items now disappear when you learn them. + * Trainer code update. + * Updated: Added guild sql files to Linux Makefile. + * Updated: Adjusted Item Query code. + * Updated: AtWar flag will now bet set for hostile fractions by LoadReputationFromDBC function. + * Updated: Changed transmission of item information. + * Updated: Creature display updates. + * Updated: Deliver Grid system phase 2 for VC7. The Grid System (TGS) completed. + * Updated: Display nicer statistics on daemon startup. + * Updated: FactionTemplate now hashed. + * Updated Game Objects. Looting works, loot template missing, support for Herbs, Mines, Locks missing. + * Updated: Item text pages now display additional information. + * Updated mail support. Now fully works. + * Updated: More debug cleanings. + * Updated: More grid optimizations. + * Updated: only updated creatures/objects near adjacent cell of where player stands. Also intersection of cell between player should update once. + * Updated: On Quest completion your faction reputation will increase properly. + * Updated: Quest and NPC text loading modified to suit the new tables. + * Updated: Quest code will now read the Creature_ID from the table. + * Updated: Removed some obsolete code. + * Updated: Rewrote urand() procedure to fix conflicted SVN. + * Updated: _SetCreatureTemplate() must be run in an update. When set on creation, it has no effect. + * Updated: Spell time recution talents now fully work. + * Updated: The Grid System (TGS) is now on by default. Not support grid off. Next, (1) deliver phase 2 stuff and (2) remove ifdef and ALL old classes. + * Updated: TRUNCATE is faster than DELETE + + === Server Features === + * Added CLI interface for server. Needs to be enabled on compile-time. + * Reorganized Spell System, separated effects to a diferent file, for better fixing. + + ==== Statistics ==== + * Fixed Bugs: #14, #17, #20, #22, #23, #24, #25, #26 + * Total number of changes: 193. + +MaNGOS 0.0.3 (Nov 15, 2005) + + MaNGOS 0.0.3 - Codename "Mango Carpet" - was mainly a bug fix release, which + never was published on the web, and just marks a point in development where + a damn lot of bugs had been fixed, but we still felt the need for further work + to be done before a release could be pushed to the world. + +MaNGOS 0.0.2 (Oct 31, 2005) + + MaNGOS 0.0.2 - Codename "Library" - adds another bunch of improvements, bug + fixes and major enhancements to the overall functionality of the daemon. A + complete list of all updated items follows below: + + ==== Game Features ==== + * Added support for area exploration. + * Added support for duels. + * Added support for ticket system. + * Added support for trading. + * Added support for NPC movement when there are no waypoints defined. + * Added support for NPC gossip, now handling options, and providing default options. + * Added attack code for creatures. + * Added default data for realm list. + * Fixed character logout. Players can only log out when not in combat. + * Fixed friends and ignore lists. + * Fixed game objects to have proper sizes. + * Fixed item swapping. + * Fixed player factions. + * Fixed vendors. They now work without requiring gossip texts defined, as long as they have objects to sell. + * Updated command descriptions to be more meaningful. + * Updated default data for player creation. Actions, items, skills and spells moved to database. + + ==== Server Features ==== + * Added support for building with Intel C++ compiler on Windows. + * Added support for building with debug info on Linux. Use --with-debug-info switch to include debug info. + * Added support for building with 1.8.x protocol as default protocol. Use the 1.8.x build configurations in Visual Studio or --enable-18x switch on Linux. + * Added support for building with 1.7.x protocol. Use the 1.7.x build configurations in Visual Studio or --enable-17x switch on Linux. + * Added support for internal httpd server added for those not running Apache. --enable-httpd-integrated will add it. Windows solution available. + * Added support for displaying progress bars for daemon startup loading. + * Added support for on demand Grid Loading/Unloading system, which is disabled by default. + * Added core application framework. + * Added support for console commands (setgm,ban,create,info) + * Added command line switch -c for pointing to a custom configuration file. By default file from _MANGOSD_CONFIG (defined in src/mangosd/Master.h.in) will be used. + * Fixed ZThread build process. + * Fixed segmentation fault on zone map test due to access of array out of bound. Also, change m_ZoneIDmap to use bitset instead of the 4 bytes bool. + * Fixed memory leak problems. The creation of new TYPE[] must delete with [] for correctness otherwise n-1 members are leaked. + + ==== Statistics ==== + * Fixed Bugs: #4, #7, #12, #13, #16, #18, #19 + * Total number of changes: 225. + +MaNGOS 0.0.1 (Sept 13, 2005) + + MaNGOS 0.0.1 - Codename "Endeavour" - contains a great number of new features, + improvements and bug fixes. The following list contains all of them: + + * NPC gossips now hash by Guid instead of ID. ID is meaningless and we should revisit its usage. + * Fixed client crash issue. GameObject still not interactive. Flags issues. + * Introduced new gameobjecttemplate table as well new map files. + * Added SCP-to-SQL converter to contrib/scp-to-sql/. + * MySQL 4.0 branch now is minimum requirement. + * Server causes client to core on unintialized memory. Also, remove some debug statement which causes problem when the DB is large + * Creature loot now reads from the creatureloot table. Use a new algorithm to select loot items that mimic the probabilities assigned in each item. + * Fixed configuration file, added proper settings for packet logging. + * Added default data for player creation and command help. + * Added GM command: .addspw #entry-id. Spawns a creature from creaturetemplate table by given #entry-id. + * Server randomly cores if DBC file failed to load. Fixes by intializing all DBC class internal variables. + * Daemon version and path to daemon configuration now set by build system on compile time. + * Allow connections from client release 4544 + * Update solution and project files for latest Visual Studio .NET 2005 Beta 2 release. + * Fixed compiler error for gcc 4.0 or higher. Calling templated base class methods has to be explicit from 4.0 or higher on. + * Added contrib/ subdirectory for third-party tools. + * Applied MaNGOS code indention schema. + * Initial code checked into repository. + + ==== Statistics ==== + * Fixed Bugs: #2, #3, #9, #10, #11 + * Total number of changes: 53. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..0d815cf1e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,58 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = dep doc sql src + +## Additional files to include when running 'make dist' +# Win32 project workspace for Visual Studio .NET 2003 +EXTRA_DIST = \ + win/mangosdVC71.sln \ + win/VC71/framework.vcproj \ + win/VC71/game.vcproj \ + win/VC71/mangosd.vcproj \ + win/VC71/realmd.vcproj \ + win/VC71/shared.vcproj \ + win/VC71/zlib.vcproj \ + win/VC71/g3dlite.vcproj \ + win/VC71/zthread.vcproj + +# Win32 project workspace for Visual Studio .NET 2005 +EXTRA_DIST += \ + win/mangosdVC80.sln \ + win/VC80/framework.vcproj \ + win/VC80/game.vcproj \ + win/VC80/mangosd.vcproj \ + win/VC80/realmd.vcproj \ + win/VC80/shared.vcproj \ + win/VC80/zlib.vcproj \ + win/VC80/g3dlite.vcproj \ + win/VC80/zthread.vcproj + +# Win32 project workspace for Visual Studio .NET 2008 +EXTRA_DIST += \ + win/mangosdVC90.sln \ + win/VC90/framework.vcproj \ + win/VC90/game.vcproj \ + win/VC90/mangosd.vcproj \ + win/VC90/realmd.vcproj \ + win/VC90/shared.vcproj \ + win/VC90/zlib.vcproj \ + win/VC90/g3dlite.vcproj \ + win/VC90/zthread.vcproj + diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..0cac6a689 --- /dev/null +++ b/NEWS @@ -0,0 +1,107 @@ += MaNGOS -- History of visible changes = + +Copyright (c) 2005-2008 MaNGOS project + +See the COPYING file for copying conditions. + +Visit our project website for documentation, and more: +http://getmangos.com/ + +Visit our forums for support: +http://getmangos.com/community/ + +Please submit bug reports at: +http://mangos.lighthouseapp.com/ + +Version 0.12 + * Under discussion. + * Upgrade to client version 2.4.3 (build 8606). + +Version 0.11 + * Lots of improvements in the spell system. + * Now use Mersenne Twister random number generator. + * MySQL client libs updated to 5.0.56. + * Upgrade to client version 2.4.2 (build 8278). + +Version 0.10 + * master looter lot mode, + * FFA PvP zones and FFA PvP server type support, + * Guild Banks, + * unique equipped items support, including gems, + * talent inspecting, + * PostgreSql support, + * sockets library updated to v.2.2.9 version, + * 64-bit binaries building at Windows, + * Upgrade to client version 2.3.0 (build 7561). + +Version 0.9 + * recipes discovery system support, + * more auras, effects, spells, and talents working, + * players queue at login support, + * mangosd/realmd as Windows services support, + * autogeneration mangosd/realmd crash reports (Windows only), + * Visual Studio 2008 Express and Pro support, + * division Mangos DataBase to MangosDB(WorldDB) and CharactersDB. + * Upgrade to client version 2.2.3 (build 7359). + +Version 0.8 + * battleground support, + * gender specific creatures, + * game objects triggering more scripts, + * more auras, effects, spells, and talents working, + * dungeon specific data, + * localization support for data, + * vmaps for line of sight handling, + * build support for OpenBSD and FreeBSD, + * Upgrade to client version 2.1.3 (build 6898). + +Version 0.7, Codename "Eye of the Storm" + * Full rewrite of the GNU autotools based build system, in order to + smooth and clean up the build process. + * Full rewrite of the Windows build system, allowing MaNGOS to be built + from Visual C++ 2003 Toolkit, Visual C++ 2003, Visual C++ 2005. + * Upgrade to client version 2.0.12 (build 6546). + +Version 0.6, Codename "Black Dragonflight" + * MaNGOS development moved to http://sourceforge.net/projects/mangos/ + * A lots of speed improvements to data handling and data transfer have been + completed. + * Mail, auction house, profession, creature, and game object systems have seen + a lot of improvements and can be considered feature complete. Some minor bugs + still are left. + * Rest system has been finished. + * Initial pet stable support has been added. + * PvP and duel system have seen lots of improvements + * Guilds are not just a myth anymore. Coming closer to full guild support. + * Taxi and transport system is close to a fully working system. + * A lot more has been added. + +Version 0.5, Codename "Stable Master" + * Core stability improvements, lots of threading and memory usage related + bugs have been resolved. + * MySQL Database backend has been cleaned up. + * Proper support for game clients of version 1.10.2 has been added. + * Support for auras, pets, spells, talents, totems, etc. has been added + or improved. + * Cross-platform issues have been resolved, MaNGOS should now build on + more platforms, including FreeBSD. + +Version 0.1, Codename "Lightbringer" + * AI system + * Grid system + * Lots a game features working. + * Lovely optimizations for the beloved server. + +Version 0.0.3, Codename "Mango Carpet" + * Interim release, not gone public. + +Version 0.0.2, Codename "Library" + * Most data conversions working. + * Database cleanup. + * More features working. + * Many bugs fixed. + +Version 0.0.1, Codename "Endeavour" + * Data converter added. + * Build system improvements. + * Bug fixing and code cleaning. diff --git a/THANKS b/THANKS new file mode 100644 index 000000000..5d5e8fded --- /dev/null +++ b/THANKS @@ -0,0 +1,35 @@ +The THANKS file: + +All distributions should contain a `THANKS' file containing a two column list +of the contributors, one per line, alphabetically sorted. The left column gives +the contributor's name, while the right column gives the last known good email +address for this contributor. This list should be introduced with a wording +similar to this one: + + MaNGOS THANKS file + + MaNGOS has originally been written by Team Python and WoW Daemon Team. Many + people further contributed to MaNGOS by reporting problems, suggesting various + improvements or submitting actual code. + + Here is a list of these people. Help me keep it complete and exempt of errors. + + Special thanks should also go out to the WowwoW team. We have gained help from + them many times in the creation of this project. Keep up the good work guys. + + Thanks should also go out to the Ludmilla team, who are also providing the + community with a great server. We have not gained too much help from them, + but we have recieved some. + +The easiest policy with this file is to thank everyone who contributes to the +project, without judging the value of the contribution. + +Unlike `AUTHORS', the `THANKS' file is not maintained for legal reasons. It is +maintained to thank all the contributors that helped you out in your project. +The `AUTHORS' file can not be used for this purpose because certain +contributions, like bug reports or ideas and suggestions do not require legal +paper exchanges. + +You can also decide to send some kind of special greeting when you initially +add a name to your `THANKS' file. The mere presense of a name in `THANKS' is +then a flag to you that the initial greeting has been sent. diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..48f3b8412 --- /dev/null +++ b/configure.ac @@ -0,0 +1,333 @@ +# Copyright (C) 2005-2008 MaNGOS project +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +## Process this file with autoconf to produce a configure script. + +# TODO: create m4 directory and put the checks there, because this file got realy poluted ( by Derex ) + +## Prelude, basic settings for Autoconf +# PACKAGE: mangos +# VERSION: 0.12.0 (trunk) +# BUG-REPORT-ADDRESS: mangos-devs@lists.sourceforge.net +AC_INIT( [mangos], [0.12.0], [mangos-devs@lists.sourceforge.net]) +AC_CONFIG_SRCDIR([src/shared/Base.cpp]) + +## Prelude, basic settings for Automake +# Turn on all warnings and error messages, and enforce GNU +# standards for the package. +AM_INIT_AUTOMAKE([-Wall -Werror gnu tar-pax]) +AM_MAINTAINER_MODE + +## Prevent the configure script from continuing any further if +# configuration is being performed in the top-level directory. +# The idea is to prevent this ,because some maintainers tend +# to break parallel build trees (a.k.a. VPATH builds). +if test "$srcdir" = "." && test "$enable_maintainer_mode" != "yes"; then + AC_MSG_ERROR( + [ + Please configure and build in a directory other than the + top-level source directory. This is needed because a lot + of maintainers tend to break parallel build trees + (a.k.a. VPATH builds). This is kinda real ensurance they + will not do it (by enforcing everybody to do VPATH builds). + + For example, try the following from the top-level source + directory: + + mkdir objdir + cd objdir + ../configure + make + + This will create a build space in the directory `objdir' and + start a build in that directory. + + If however you realy want to disable this error, + use --enable-maintainer-mode switch. + ]) +fi + +## Disable building of static libraries by default +AC_DISABLE_STATIC + +## Check for required dependencies. + +## Check for a valid build environment. +# Valid equals having: +# - a C++ compiler compliant with the ISO98 C++ specification. +# - a working library tool for creating convenience libraries. +# - a working linker for creating static and shared libraries. +AC_PROG_CC +AC_PROG_CXX +AM_PROG_CC_C_O +AC_PROG_LIBTOOL +AC_PROG_INSTALL + +# Check for doxygen +AC_ARG_ENABLE(doxygen, AC_HELP_STRING([--enable-doxygen], [turn on generating documentation])) + +enable_doxygen_support=no + +if test "x$enable_doxygen" = "xyes"; +then + AC_PATH_PROG(DOXYGEN, doxygen, no) + if test "x$DOXYGEN" = "xno"; then + AC_MSG_ERROR([You need to install the doxygen package]) + fi + enable_doxygen_support=yes +fi +AM_CONDITIONAL(DOXYGEN_ENABLED, test x$enable_doxygen_support = xyes) + +## Check for required libraries. +AC_CHECK_LIB( pthread, pthread_create, [], + [LDFLAGS="-pthread $LDFLAGS" + AC_TRY_LINK([char pthread_create();], + pthread_create();, + [], [AC_MSG_ERROR([Missing pthread])]) + ]) +AC_CHECK_LIB( z, compress, [ZLIB=-lz],[AC_MSG_ERROR([Missing zlib])] ) +AC_CHECK_LIB( compat, ftime, [COMPATLIB=-lcompat] ) +AC_CHECK_LIB( crypto, SHA1_Init, [SSLLIB=-lssl], [AC_MSG_ERROR([Missing openssl])]) + +AC_ARG_WITH(postgresql, +[ --with-postgresql Use PostgreSQL as a backend (default: no)], +[case "${withval}" in + yes) DO_POSTGRESQL=yes ;; + no) DO_POSTGRESQL=no ;; + maybe) DO_POSTGRESQL=maybe ;; + *) AC_MSG_ERROR(Bad value ${withval} for --with-postgresql) ;; + esac], +[DO_POSTGRESQL=no]) + +AC_ARG_WITH(mysql, +[ --with-mysql Use MySQL as a backend (default: yes)], +[case "${withval}" in + yes) DO_MYSQL=yes ;; + no) DO_MYSQL=no ;; + maybe) DO_MYSQL=maybe ;; + *) AC_MSG_ERROR(Bad value ${withval} for --with-mysql) ;; + esac], +[DO_MYSQL=yes]) + +# here Postgre +AC_MSG_CHECKING(whether to build/link POSTGRESQL) +if test "x$DO_POSTGRESQL" = "xyes"; then +DO_MYSQL=no +POSTGRE_INCLUDES="-I/usr/include/postgresql $POSTGRE_INCLUDES" +POSTGRE_LIBS="-L/usr/lib/postresql -lpq -lz -lpthread -lcrypt -lnsl -lm -lpthread -L/usr/lib -lssl -lcrypto $POSTGRE_LIBS " +CXXFLAGS="-DDO_POSTGRESQL $CXXFLAGS" +fi +AC_MSG_RESULT($DO_POSTGRESQL) + +# here mysql +AC_MSG_CHECKING(whether to build/link MYSQL) +if test "x$DO_MYSQL" = "xyes"; then +AC_MSG_RESULT($DO_MYSQL) +AC_PATH_PROGS(MYSQL_CONFIG, mysql_config, mysql_config, $PATH) + if test -x "$MYSQL_CONFIG" + then + # MySQL v4 uses --include while v3 uses --cflags + MYSQL_INCLUDES="`$MYSQL_CONFIG --include`" || \ + MYSQL_INCLUDES="`$MYSQL_CONFIG --cflags`" + MYSQL_LIBS="`$MYSQL_CONFIG --libs_r`" + CXXFLAGS="-DDO_MYSQL $CXXFLAGS" + fi +else +AC_MSG_RESULT($DO_MYSQL) +fi + +## Check for options +# Include debug info in library? +AC_MSG_CHECKING(whether to include debug info in library) +MANGOSD_DEBUG_INFO=no +AC_ARG_WITH(debug-info, +[ +Debugging options: + + --with-debug-info Include debug info in library], +[ + if test "$withval" = "yes" ; then + CFLAGS="-g -DMANGOS_DEBUG $CFLAGS" + CXXFLAGS="-g -DMANGOS_DEBUG $CXXFLAGS" + MANGOSD_DEBUG_INFO=yes + elif test "$withval" != "no" ; then + AC_MSG_ERROR(Please choose yes or no) + fi +]) +AC_MSG_RESULT($MANGOSD_DEBUG_INFO) + + +# Enable CLI console? +AC_MSG_CHECKING(whether cli console is enabled) +MANGOSD_ENABLE_CLI=no +AC_ARG_ENABLE(cli, +[ --enable-cli Turn on command console system], +[ + if test "$enableval" = "yes" ; then + CFLAGS="-DENABLE_CLI $CFLAGS" + CXXFLAGS="-DENABLE_CLI $CXXFLAGS" + MANGOSD_ENABLE_CLI=yes + elif test "$withval" != "no" ; then + AC_MSG_ERROR(Please choose yes or no) + fi +]) +AC_MSG_RESULT($MANGOSD_ENABLE_CLI) + +# Enable remote console? +AC_MSG_CHECKING(whether remote console is enabled) +MANGOSD_ENABLE_RA=no +AC_ARG_ENABLE(ra, +[ --enable-ra Turn on remote console system], +[ + if test "$enableval" = "yes" ; then + CFLAGS="-DENABLE_RA $CFLAGS" + CXXFLAGS="-DENABLE_RA $CXXFLAGS" + MANGOSD_ENABLE_RA=yes + elif test "$withval" != "no" ; then + AC_MSG_ERROR(Please choose yes or no) + fi +]) +AC_MSG_RESULT($MANGOSD_ENABLE_RA) + +## Check for required header files. +AC_HEADER_STDC +AC_HEADER_DIRENT +AC_CHECK_HEADERS([ arpa/inet.h fcntl.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/socket.h sys/timeb.h sys/time.h termios.h unistd.h ]) + +AC_CHECK_HEADERS([pthread.h]) +AC_CHECK_HEADERS([openssl/md5.h openssl/rand.h openssl/ssl.h openssl/sha.h openssl/bn.h]) +AC_CHECK_HEADERS([mysql.h mysql/mysql.h]) +AC_CHECK_HEADERS([libpq-fe.h]) +AC_CHECK_HEADERS([zlib.h]) + +## Check for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM +AC_TYPE_UINT64_T +AC_C_VOLATILE +AC_CHECK_TYPES([ptrdiff_t]) + +## Check for required library functions. +AC_FUNC_CLOSEDIR_VOID +AC_FUNC_ERROR_AT_LINE +AC_FUNC_MALLOC +AC_FUNC_MEMCMP +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([atexit ftime gethostbyaddr gethostbyname gethostname gettimeofday memmove memset pow realpath select socket sqrt strchr strdup strerror strstr]) + +## Check what to do with ACE library +AC_LANG_PUSH([C++]) +AC_CHECK_HEADER([ace/Reactor.h], [have_ace_headers=yes], [have_ace_headers=no]) +AC_CHECK_LIB([ACE], [main], [have_ace_lib=yes], [have_ace_lib=no]) +AC_LANG_POP([C++]) + +AC_MSG_CHECKING([whether to build ACE]) +if test X$have_ace_headers = Xyes -a X$have_ace_lib = Xyes; +then + need_to_build_ace=no + AC_MSG_RESULT([no]) +else + if test X$have_ace_headers = Xno -a X$have_ace_lib = Xno; then + need_to_build_ace=yes + AC_MSG_RESULT([yes]) + else + if test X$have_ace_headers = Xyes; then + AC_MSG_ERROR([looks like you have ACE headers, but you do not have ACE libs installed]) + else + need_to_build_ace=yes + AC_MSG_RESULT([yes, over-install]) + fi + fi +fi + +if test X$need_to_build_ace = Xyes; then + MANGOS_INCLUDES="-I\$(top_srcdir)/dep/ACE_wrappers -I\$(top_builddir)/dep/ACE_wrappers $MANGOS_INCLUDES" + MANGOS_LIBS="\$(top_builddir)/dep/ACE_wrappers/ace/libACE.la $MANGOS_LIBS" +else + MANGOS_LIBS="-lACE $MANGOS_LIBS" +fi + +AM_CONDITIONAL([MANGOS_BUILD_ACE], [test X$need_to_build_ace = Xyes]) + + +## Unify all additional includes/libs in one variable. +# TODO this looks kinda ugly, but when we add m4 folder I will make it look very pritey ( by Derex ). +MANGOS_INCLUDES="$POSTGRE_INCLUDES $MYSQL_INCLUDES $MANGOS_INCLUDES" +MANGOS_LIBS="$POSTGRE_LIBS $MYSQL_LIBS $ZLIB $COMPATLIB $SSLLIB $MANGOS_LIBS" + +## Export defined variables +AC_SUBST(DOXYGEN) +AC_SUBST(MANGOSD_DEBUG_INFO) +AC_SUBST(MANGOSD_ENABLE_CLI) +AC_SUBST(MANGOSD_ENABLE_RA) + +## Additional CPPFLAGS and LDFLAGS. +AC_SUBST(MANGOS_INCLUDES) +AC_SUBST(MANGOS_LIBS) + +## Set output files. +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([ + dep/include/Makefile + dep/lib/Makefile + dep/src/Makefile + dep/src/g3dlite/Makefile + dep/src/sockets/Makefile + dep/src/zlib/Makefile + dep/src/zthread/Makefile + dep/Makefile + doc/Doxyfile + doc/Makefile + Makefile + sql/Makefile + sql/tools/Makefile + sql/updates/Makefile + src/Makefile + src/tools/Makefile + src/tools/gensvnrevision/Makefile + src/framework/Makefile + src/shared/Makefile + src/shared/Auth/Makefile + src/shared/Config/Makefile + src/shared/Database/Makefile + src/shared/vmap/Makefile + src/shared/SystemConfig.h + src/game/Makefile + src/realmd/Makefile + src/realmd/realmd.conf.dist + src/mangosd/Makefile + src/mangosd/mangosd.conf.dist + src/bindings/Makefile + src/bindings/universal/Makefile +]) + +## Configure ACE, if needed +if test X$need_to_build_ace = Xyes; then + AC_CONFIG_SUBDIRS([dep/ACE_wrappers]) +fi + +AC_CONFIG_COMMANDS([default],[ + echo "" + echo "Configuration of MaNGOS $PACKAGE_VERSION is now complete." + echo "" + ],[PACKAGE_VERSION=$PACKAGE_VERSION]) + +## Disabled Makefiles, until they are ready for a successful make and +# make dist run. + +## Output files. +AC_OUTPUT diff --git a/contrib/Makefile.am b/contrib/Makefile.am new file mode 100644 index 000000000..653e691a1 --- /dev/null +++ b/contrib/Makefile.am @@ -0,0 +1,23 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = extractor + +## Additional files to include when running 'make dist' +# Nothing yet. diff --git a/contrib/dbcEditer/BcdEditer.ini b/contrib/dbcEditer/BcdEditer.ini new file mode 100644 index 000000000..99284e8b9 --- /dev/null +++ b/contrib/dbcEditer/BcdEditer.ini @@ -0,0 +1,34 @@ +[TaxiNodes.dbc] +ColType2=0 +ColType3=1 +ColType4=1 +[SpellRange.dbc] +ColType2=0 +ColType3=0 +ColType1=0 +[Talent.dbc] +ColType1=0 +ColType5=0 +ColType4=0 +[test.dbc] +ColType1=0 +ColType3=1 +ColType2=0 +[TalentTab.dbc] +ColType15=2 +[TalentTab_new.dbc] +ColType15=2 +[SpellIcon.dbc] +ColType2=0 +ColType1=0 +[FactionGroup.dbc] +ColType12=0 +ColType3=2 +ColType2=0 +ColType8=0 +[gtRegenMPPerSpt.dbc] +ColType1=1 +[gtOCTRegenMP.dbc] +ColType1=1 +[gtOCTRegenHP.dbc] +ColType1=1 diff --git a/contrib/dbcEditer/SearchFrm.cpp b/contrib/dbcEditer/SearchFrm.cpp new file mode 100644 index 000000000..59e198dfb --- /dev/null +++ b/contrib/dbcEditer/SearchFrm.cpp @@ -0,0 +1,26 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "SearchFrm.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFrmSearch *FrmSearch; +//--------------------------------------------------------------------------- +__fastcall TFrmSearch::TFrmSearch(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TFrmSearch::btOkClick(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFrmSearch::btCancelClick(TObject *Sender) +{ + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- diff --git a/contrib/dbcEditer/SearchFrm.ddp b/contrib/dbcEditer/SearchFrm.ddp new file mode 100644 index 000000000..cdc0ee8c2 Binary files /dev/null and b/contrib/dbcEditer/SearchFrm.ddp differ diff --git a/contrib/dbcEditer/SearchFrm.dfm b/contrib/dbcEditer/SearchFrm.dfm new file mode 100644 index 000000000..06a3613a7 --- /dev/null +++ b/contrib/dbcEditer/SearchFrm.dfm @@ -0,0 +1,63 @@ +object FrmSearch: TFrmSearch + Left = 261 + Top = 194 + Width = 324 + Height = 215 + Caption = 'Seach F3 Seach Next' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 96 + TextHeight = 13 + object lbseach: TLabel + Left = 48 + Top = 16 + Width = 57 + Height = 17 + AutoSize = False + Caption = 'Input:' + end + object rgSI: TRadioGroup + Left = 64 + Top = 40 + Width = 185 + Height = 97 + Caption = 'Seach Dir' + ItemIndex = 1 + Items.Strings = ( + 'Seach up' + 'Seach down' + 'Seach up Current rol' + 'Seach down Current rol') + TabOrder = 0 + end + object edSeach: TEdit + Left = 120 + Top = 16 + Width = 121 + Height = 21 + TabOrder = 1 + end + object btOk: TButton + Left = 64 + Top = 152 + Width = 75 + Height = 25 + Caption = 'Ok' + TabOrder = 2 + OnClick = btOkClick + end + object btCancel: TButton + Left = 176 + Top = 152 + Width = 75 + Height = 25 + Caption = 'Cancel' + TabOrder = 3 + OnClick = btCancelClick + end +end diff --git a/contrib/dbcEditer/SearchFrm.h b/contrib/dbcEditer/SearchFrm.h new file mode 100644 index 000000000..246d7e682 --- /dev/null +++ b/contrib/dbcEditer/SearchFrm.h @@ -0,0 +1,29 @@ +//--------------------------------------------------------------------------- + +#ifndef SearchFrmH +#define SearchFrmH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFrmSearch : public TForm +{ +__published: // IDE-managed Components + TRadioGroup *rgSI; + TEdit *edSeach; + TLabel *lbseach; + TButton *btOk; + TButton *btCancel; + void __fastcall btOkClick(TObject *Sender); + void __fastcall btCancelClick(TObject *Sender); +private: // User declarations +public: // User declarations + __fastcall TFrmSearch(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFrmSearch *FrmSearch; +//--------------------------------------------------------------------------- +#endif diff --git a/contrib/dbcEditer/TitleFrm.cpp b/contrib/dbcEditer/TitleFrm.cpp new file mode 100644 index 000000000..a26e93ce5 --- /dev/null +++ b/contrib/dbcEditer/TitleFrm.cpp @@ -0,0 +1,26 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "TitleFrm.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFrmTitle *FrmTitle; +//--------------------------------------------------------------------------- +__fastcall TFrmTitle::TFrmTitle(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TFrmTitle::Button1Click(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFrmTitle::Button2Click(TObject *Sender) +{ + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- diff --git a/contrib/dbcEditer/TitleFrm.ddp b/contrib/dbcEditer/TitleFrm.ddp new file mode 100644 index 000000000..cdc0ee8c2 Binary files /dev/null and b/contrib/dbcEditer/TitleFrm.ddp differ diff --git a/contrib/dbcEditer/TitleFrm.dfm b/contrib/dbcEditer/TitleFrm.dfm new file mode 100644 index 000000000..0d1570f38 --- /dev/null +++ b/contrib/dbcEditer/TitleFrm.dfm @@ -0,0 +1,51 @@ +object FrmTitle: TFrmTitle + Left = 328 + Top = 252 + Width = 235 + Height = 112 + BorderIcons = [biSystemMenu] + Caption = 'Col Title' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poDesktopCenter + PixelsPerInch = 96 + TextHeight = 13 + object Label1: TLabel + Left = 8 + Top = 24 + Width = 65 + Height = 13 + AutoSize = False + Caption = 'Title:' + end + object edTitle: TEdit + Left = 80 + Top = 16 + Width = 121 + Height = 21 + TabOrder = 0 + end + object Button1: TButton + Left = 24 + Top = 48 + Width = 75 + Height = 25 + Caption = 'Ok' + TabOrder = 1 + OnClick = Button1Click + end + object Button2: TButton + Left = 136 + Top = 48 + Width = 75 + Height = 25 + Caption = 'Cancel' + TabOrder = 2 + OnClick = Button2Click + end +end diff --git a/contrib/dbcEditer/TitleFrm.h b/contrib/dbcEditer/TitleFrm.h new file mode 100644 index 000000000..2316d8fec --- /dev/null +++ b/contrib/dbcEditer/TitleFrm.h @@ -0,0 +1,27 @@ +//--------------------------------------------------------------------------- + +#ifndef TitleFrmH +#define TitleFrmH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFrmTitle : public TForm +{ +__published: // IDE-managed Components + TLabel *Label1; + TEdit *edTitle; + TButton *Button1; + TButton *Button2; + void __fastcall Button1Click(TObject *Sender); + void __fastcall Button2Click(TObject *Sender); +private: // User declarations +public: // User declarations + __fastcall TFrmTitle(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFrmTitle *FrmTitle; +//--------------------------------------------------------------------------- +#endif diff --git a/contrib/dbcEditer/bin/BcdEditer.ini b/contrib/dbcEditer/bin/BcdEditer.ini new file mode 100644 index 000000000..a9159ecde --- /dev/null +++ b/contrib/dbcEditer/bin/BcdEditer.ini @@ -0,0 +1,313 @@ +[FactionGroup.dbc] +ColType3=2 +[Spell.dbc] +ColTitle1=Id +ColTitle2=Category +ColTitle3=castUI +ColTitle4=Dispel +ColTitle5=Mechanic +ColTitle6=Attributes +ColTitle7=AttributesEx; +ColTitle8=AttributesEx2; +ColTitle9=AttributesEx3; +ColTitle10=AttributesEx4; +ColTitle11=AttributesEx5; +ColTitle12=AttributesEx6; +ColTitle13=Stances; +ColTitle14=StancesNot; +ColTitle15=Targets; +ColTitle16=TargetCreatureType; +ColTitle17=RequiresSpellFocus; +ColTitle18=FacingCasterFlags; +ColTitle19=CasterAuraState; +ColTitle20=TargetAuraState; +ColTitle21=CasterAuraStateNot; +ColTitle22=TargetAuraStateNot; +ColTitle23=CastingTimeIndex; +ColTitle24=RecoveryTime; +ColTitle25=CategoryRecoveryTime; +ColTitle26=InterruptFlags; +ColTitle27=AuraInterruptFlags; +ColTitle28=ChannelInterruptFlags; +ColTitle29=procFlags; +ColTitle30=procChance; +ColTitle31=procCharges; +ColTitle32=maxLevel; +ColTitle33=baseLevel; +ColTitle34=spellLevel; +ColTitle35=DurationIndex; +ColTitle36=powerType; +ColTitle37=manaCost; +ColTitle38=manaCostPerlevel; +ColTitle39=manaPerSecond; +ColTitle40=manaPerSecondPerLevel; +ColTitle41=rangeIndex; +ColTitle42=floatspeed; +ColTitle43=modalNextSpell;//38 +ColTitle44=StackAmount; +ColTitle45=Totem1 +ColTitle46=Totem2 +ColTitle47=Reagent +ColTitle48=Reagent2 +ColTitle49=Reagent3 +ColTitle50=Reagent4 +ColTitle51=Reagent5 +ColTitle52=Reagent6 +ColTitle53=Reagent7 +ColTitle54=Reagent8 +ColTitle55=ReagentCount1 +ColTitle56=ReagentCount2 +ColTitle57=ReagentCount3 +ColTitle58=ReagentCount4 +ColTitle59=ReagentCount5 +ColTitle60=ReagentCount6 +ColTitle61=ReagentCount7 +ColTitle62=ReagentCount8 + +ColTitle63=EqpItemClass +ColTitle64=EquipItemSubClassMask +ColTitle65=ItemInventoryTypeMask +ColTitle66=Effect +ColTitle67=Effect2 +ColTitle68=Effect3 +ColTitle69=EffectDieSides1 +ColTitle70=EffectDieSides2 +ColTitle71=EffectDieSides3 +ColTitle72=EffectBaseDice1 +ColTitle73=EffectBaseDice2 +ColTitle74=EffectBaseDice3 +ColTitle75=EffectDicePerLevel1 +ColTitle76=EffectDicePerLevel2 +ColTitle77=EffectDicePerLevel3 +ColTitle78=EffectRealPointsPerLevel1 +ColTitle79=EffectRealPointsPerLevel2 +ColTitle80=EffectRealPointsPerLevel3 +ColTitle81=BasePoints1 +ColTitle82=BasePoints2 +ColTitle83=BasePoints3 +ColTitle84=EffectMechanic1 +ColTitle85=EffectMechanic2 +ColTitle86=EffectMechanic3 + + +ColTitle87=ImplicTargA1 +ColTitle88=ImplicTargA2 +ColTitle89=ImplicTargA3 +ColTitle90=ImplicTargB1 +ColTitle91=ImplicTargB2 +ColTitle92=ImplicTargB3 +ColTitle93=RadiusIndex1 +ColTitle94=RadiusIndex2 +ColTitle95=RadiusIndex3 +ColTitle96=ApplyAuraName1 +ColTitle97=ApplyAuraName2 +ColTitle98=ApplyAuraName3 +ColTitle99=Amplitude1 +ColTitle100=Amplitude2 +ColTitle101=Amplitude3 +ColTitle102=MultiVal1 +ColTitle103=MultiVal2 +ColTitle104=MultiVal3 +ColTitle105=ChainTarg1 +ColTitle106=ChainTarg2 +ColTitle107=ChainTarg3 +ColTitle108=EffectItemType1 +ColTitle109=EffectItemType2 +ColTitle110=EffectItemType3 +ColTitle111=EffectMiscVal1 +ColTitle112=EffectMiscVal2 +ColTitle113=EffectMiscVal3 +ColTitle114=EffectMiscValB1 +ColTitle115=EffectMiscValB2 +ColTitle116=EffectMiscValB3 +ColTitle117=EffectTriggerSpell1 +ColTitle118=EffectTriggerSpell2 +ColTitle119=EffectTriggerSpell3 +ColTitle120=EffectPointsPerComboPoint1 +ColTitle121=EffectPointsPerComboPoint2 +ColTitle122=EffectPointsPerComboPoint3 +ColTitle123=SpellVisual +ColTitle125=SpellIconID +ColTitle126=activeIconID +ColTitle127=spellPriority +ColTitle128=SpellName1 +ColTitle129=SpellName2 +ColTitle130=SpellName3 +ColTitle131=SpellName4 +ColTitle132=SpellName5 +ColTitle133=SpellName6 +ColTitle134=SpellName7 +ColTitle135=SpellName8 +ColTitle136=SpellName9 +ColTitle137=SpellName10 +ColTitle138=SpellName11 +ColTitle139=SpellName12 +ColTitle140=SpellName13 +ColTitle141=SpellName14 +ColTitle142=SpellName15 +ColTitle143=SpellName16 +ColTitle144=SpellNameFlag +ColTitle145=Rank1 +ColTitle146=Rank2 +ColTitle147=Rank3 +ColTitle148=Rank4 +ColTitle149=Rank5 +ColTitle150=Rank6 +ColTitle151=Rank7 +ColTitle152=Rank8 +ColTitle153=Rank9 +ColTitle154=Rank10 +ColTitle155=Rank11 +ColTitle156=Rank12 +ColTitle157=Rank13 +ColTitle158=Rank14 +ColTitle159=Rank15 +ColTitle160=Rank16 +ColTitle161=RankFlags +ColTitle162=Description1 +ColTitle163=Description2 +ColTitle164=Description3 +ColTitle165=Description4 +ColTitle166=Description5 +ColTitle167=Description6 +ColTitle168=Description7 +ColTitle169=Description8 +ColTitle170=Description9 +ColTitle171=Description10 +ColTitle172=Description11 +ColTitle173=Description12 +ColTitle174=Description13 +ColTitle175=Description14 +ColTitle176=Description15 +ColTitle177=Description16 +ColTitle178=DescriptionFlags +ColTitle179=ToolTip1 +ColTitle180=ToolTip2 +ColTitle181=ToolTip3 +ColTitle182=ToolTip4 +ColTitle183=ToolTip5 +ColTitle184=ToolTip6 +ColTitle185=ToolTip7 +ColTitle186=ToolTip8 +ColTitle187=ToolTip9 +ColTitle188=ToolTip10 +ColTitle189=ToolTip11 +ColTitle190=ToolTip12 +ColTitle191=ToolTip13 +ColTitle192=ToolTip14 +ColTitle193=ToolTip15 +ColTitle194=ToolTip16 +ColTitle195=ToolTipFlags +ColTitle196=ManaCostPercentage +ColTitle197=StartRecoveryCategory +ColTitle198=StartRecoveryTime +ColTitle199=MaxTargetLevel +ColTitle200=SpellFamilyName +ColTitle201=SpellFamilyFlags1 +ColTitle202=SpellFamilyFlags2 +ColTitle203=MaxAffectedTargets +ColTitle204=DmgClass +ColTitle205=PreventionType +ColTitle206=StanceBarOrder +ColTitle207=DmgMultiplier1 +ColTitle208=DmgMultiplier2 +ColTitle209=DmgMultiplier3 +ColTitle210=MinFactionId +ColTitle211=MinReputation +ColTitle212=RequiredAuraVision +ColTitle213=TotemCategory1 +ColTitle214=TotemCategory2 +ColTitle215=AreaId +ColTitle216=SchoolMask +ColType102=1 +ColType103=1 +ColType104=1 +ColType128=2 +ColType129=2 +ColType130=2 +ColType131=2 +ColType132=2 +ColType133=2 +ColType134=2 +ColType135=2 +ColType136=2 +ColType137=2 +ColType138=2 +ColType139=2 +ColType140=2 +ColType141=2 +ColType142=2 +ColType143=2 +ColType145=2 +ColType146=2 +ColType147=2 +ColType148=2 +ColType149=2 +ColType150=2 +ColType151=2 +ColType152=2 +ColType153=2 +ColType154=2 +ColType155=2 +ColType157=2 +ColType156=2 +ColType158=2 +ColType159=2 +ColType160=2 +ColType162=2 +ColType163=2 +ColType164=2 +ColType165=2 +ColType166=2 +ColType167=2 +ColType168=2 +ColType169=2 +ColType170=2 +ColType171=2 +ColType172=2 +ColType173=2 +ColType174=2 +ColType175=2 +ColType176=2 +ColType177=2 +ColType179=2 +ColType180=2 +ColType181=2 +ColType182=2 +ColType183=2 +ColType184=2 +ColType185=2 +ColType186=2 +ColType187=2 +ColType188=2 +ColType189=2 +ColType190=2 +ColType191=2 +ColType192=2 +ColType193=2 +ColType194=2 +ColType208=1 +ColType209=1 +ColType207=1 +[Map.dbc] +ColType2=2 +ColType8=0 +[AreaTrigger.dbc] +ColTitle3=x +ColTitle4=y +ColTitle5=z +ColTitle1=id +ColTitle2=map +ColType3=1 +ColType4=1 +ColType5=1 +ColType6=1 +ColType7=1 +ColType8=1 +ColType9=1 +ColType10=1 +ColTitle6=radius +ColTitle7=box x +ColTitle8=box y +ColTitle9=box z +ColTitle10=box orientation diff --git a/contrib/dbcEditer/bin/bcbsmp60.bpl b/contrib/dbcEditer/bin/bcbsmp60.bpl new file mode 100644 index 000000000..32ebe0d1d Binary files /dev/null and b/contrib/dbcEditer/bin/bcbsmp60.bpl differ diff --git a/contrib/dbcEditer/bin/borlndmm.dll b/contrib/dbcEditer/bin/borlndmm.dll new file mode 100644 index 000000000..5a8eec327 Binary files /dev/null and b/contrib/dbcEditer/bin/borlndmm.dll differ diff --git a/contrib/dbcEditer/bin/cc3260mt.dll b/contrib/dbcEditer/bin/cc3260mt.dll new file mode 100644 index 000000000..fef4636a1 Binary files /dev/null and b/contrib/dbcEditer/bin/cc3260mt.dll differ diff --git a/contrib/dbcEditer/bin/dclusr60.bpl b/contrib/dbcEditer/bin/dclusr60.bpl new file mode 100644 index 000000000..002a741f6 Binary files /dev/null and b/contrib/dbcEditer/bin/dclusr60.bpl differ diff --git a/contrib/dbcEditer/bin/indy60.bpl b/contrib/dbcEditer/bin/indy60.bpl new file mode 100644 index 000000000..f3cb7d6ca Binary files /dev/null and b/contrib/dbcEditer/bin/indy60.bpl differ diff --git a/contrib/dbcEditer/bin/pjDbcEditer.exe b/contrib/dbcEditer/bin/pjDbcEditer.exe new file mode 100644 index 000000000..9b11ec746 Binary files /dev/null and b/contrib/dbcEditer/bin/pjDbcEditer.exe differ diff --git a/contrib/dbcEditer/bin/rtl60.bpl b/contrib/dbcEditer/bin/rtl60.bpl new file mode 100644 index 000000000..96a55c64d Binary files /dev/null and b/contrib/dbcEditer/bin/rtl60.bpl differ diff --git a/contrib/dbcEditer/bin/update.txt b/contrib/dbcEditer/bin/update.txt new file mode 100644 index 000000000..c03af17dd --- /dev/null +++ b/contrib/dbcEditer/bin/update.txt @@ -0,0 +1,11 @@ +1.4°æ¸üР+ 1.ÐÞÕýÍ˳öʱÓÐʱÍ˲»³öµÄbug + 2.¼ÓÈë¿É²éÕҵŦÄÜ + 3.¼ÓÈëÁÐÇл»ÀàÐͺóÁ¢¼´Ë¢Ð + 4.¼ÓÈë¿ÉÒÔµ±Ç°µ¥Ôª¸ñдÈë´ò¿ªÎļþµÄ¹¦ÄÜ + 5.¼ÓÈëÿһÁеĿí¶È¿Éµ÷Õû + 6.¼ÓÈëÖ§³ÖÎı¾ÏÔʾ£¬µ«²»ÄÜÐ޸ģ¬Îı¾Ð޸ĺ󲻻á´æÈë + +1.41°æ + 1.¿ÉÒԹ̶¨ºÍÈ¡ÏûµÚÒ»ÁУ¬ÒÔ·½±ã²é¿´Spell ID + 2.¿ÉÒÔÐд棬Áд棬ÐÐÇ壬ÁÐÇ壬µ÷ÓüÆËãÆ÷ \ No newline at end of file diff --git a/contrib/dbcEditer/bin/vcl60.bpl b/contrib/dbcEditer/bin/vcl60.bpl new file mode 100644 index 000000000..0f0cc71ce Binary files /dev/null and b/contrib/dbcEditer/bin/vcl60.bpl differ diff --git a/contrib/dbcEditer/bin/vclx60.bpl b/contrib/dbcEditer/bin/vclx60.bpl new file mode 100644 index 000000000..6fe6ac6f5 Binary files /dev/null and b/contrib/dbcEditer/bin/vclx60.bpl differ diff --git a/contrib/dbcEditer/dbcedit.cpp b/contrib/dbcEditer/dbcedit.cpp new file mode 100644 index 000000000..2812a3f70 --- /dev/null +++ b/contrib/dbcEditer/dbcedit.cpp @@ -0,0 +1,769 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "dbcedit.h" +#include "stdio.h" +#include "IdGlobal.hpp" +#include +#include "TitleFrm.h" +#include +#include "thOpenSource.h" +#include "SearchFrm.h" +//#include "SysUtils.hpp" + + +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFrmMain *FrmMain; +//--------------------------------------------------------------------------- +__fastcall TFrmMain::TFrmMain(TComponent* Owner) + : TForm(Owner) +{ + OpenOk=false; + Term=false; +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::btOpenClick(TObject *Sender) +{ + if(OpenDialog1->Execute()){ + if (FileExists(OpenDialog1->FileName)){ + OpenOk=false; + if(thOpen){ + thOpen->Terminate(); + } + thOpen = new thOpenFile(false); + //thOpen->Priority = tpTimeCritical; + pnFileName->Caption = OpenDialog1->FileName; + }else{ + OpenOk=false; + pnFileName->Caption = ""; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFrmMain::btSaveClick(TObject *Sender) +{ + //CurrentOpenFile; + if(OpenOk){ + SaveToFile(CurrentOpenFile.c_str()); + }else{ + ShowMessage("Îļþδ´ò¿ªÍê³É£¡"); + } +} +//--------------------------------------------------------------------------- + +void TFrmMain::SaveToFile(const char * pszFileName) +{ + char szFileName[255]; + FILE *stream; + + + + + fnsplit(pszFileName, 0, 0, szFileName, 0); + strcat(szFileName, "_new.dbc"); + + + AnsiString NewFileName=ExtractFilePath(Application->ExeName)+szFileName;//=pszFileName; + int iFileHandle; //Îļþ¾ä±ú + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(CurrentOpenFile); + + DWORD w; + + CopyFileTo(pszFileName,NewFileName); + + iFileHandle = FileOpen(NewFileName, fmOpenRead|fmOpenWrite);//´ò¿ªÎļþ + + if ((stream = fopen(CurrentOpenFile.c_str(), "r+")) + == NULL) + { + ShowMessage("´ò¿ªÎļþ³ö´í"); + return; + } + + + int iVal; + float fVal; + bool isFloat; + int ColType; + + FileSeek(iFileHandle,0x14,0); + TIniFile *ini; + ini = new TIniFile( iniSetFile ); + + for(int i=1; iRowCount; i++) + { + for(int j=1; jColCount; j++) + { + if(j==1){ //ID + iVal=StrToInt(sgEdit->Cells[j][i]); + FileWrite(iFileHandle, &iVal, 4); + }else{ + + //ColType= ini->ReadInteger(SectionName,"ColType"+IntToStr(j-1),0); + //thOpen->ColType[10000]; + + switch (thOpen->ColType[j]) + { + case 0: //ÕûÐÍ + iVal=StrToFloat(sgEdit->Cells[j][i]); + FileWrite(iFileHandle, &iVal, 4); + break; + case 1: //¸¡µã + fVal=StrToFloat(sgEdit->Cells[j][i]); + FileWrite(iFileHandle, &fVal, 4); + break; + case 2: //Îı¾ + fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(j-1))*4, 0); + fread(&iVal, 4, 1, stream); + FileWrite(iFileHandle, &iVal, 4); + break; + default: //ÕûÐÍ + iVal=StrToFloat(sgEdit->Cells[j][i]); + FileWrite(iFileHandle, &iVal, 4); + } + } + } + } + FileClose(iFileHandle); + fclose(stream); + + delete ini; + ShowMessage("Save To File:"+NewFileName); +} +void __fastcall TFrmMain::btIntTypeClick(TObject *Sender) +{ +if(OpenOk==true){ + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(CurrentOpenFile); + TIniFile *ini; + ini = new TIniFile( iniSetFile ); + ini->WriteInteger(SectionName,"ColType"+IntToStr(sgEdit->Col),0); + delete ini; + thOpen->ColType[sgEdit->Col]=0; + //ÖØдò¿ª¶ÔÓ¦ÁеÄÖµ + //OpenFileCol(AnsiString FileName,int ColType); + OpenFileCol(CurrentOpenFile,sgEdit->Col,0); +} +} +//--------------------------------------------------------------------------- + + +void __fastcall TFrmMain::btFloatTypeClick(TObject *Sender) +{ +if(OpenOk==true){ + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(CurrentOpenFile); + TIniFile *ini; + ini = new TIniFile( iniSetFile ); + ini->WriteInteger(SectionName,"ColType"+IntToStr(sgEdit->Col),1); + delete ini; + thOpen->ColType[sgEdit->Col]=1; + OpenFileCol(CurrentOpenFile,sgEdit->Col,1); +} +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::PopupMenu1Popup(TObject *Sender) +{ +if(OpenOk==true){ + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(CurrentOpenFile); + int ColType; + TIniFile *ini; + ini = new TIniFile( iniSetFile ); + ColType=ini->ReadInteger(SectionName,"ColType"+IntToStr(sgEdit->Col),0); + delete ini; + switch (ColType) + { + case 0: + btIntType->Checked=true; + btFloatType->Checked=false; + btTxtType->Checked=false; + break; + case 1: + btIntType->Checked=false; + btFloatType->Checked=true; + btTxtType->Checked=false; + break; + case 2: + btIntType->Checked=false; + btFloatType->Checked=false; + btTxtType->Checked=true; + break; + default: + btIntType->Checked=true; + btFloatType->Checked=false; + } +} +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::N1Click(TObject *Sender) +{ + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(CurrentOpenFile); + int ColType; + FrmTitle->edTitle->Text=sgEdit->Cells[sgEdit->Col][0]; + if(FrmTitle->ShowModal()==mrOk){ + TIniFile *ini; + ini = new TIniFile( iniSetFile ); + ini->WriteString(SectionName,"ColTitle"+IntToStr(sgEdit->Col),FrmTitle->edTitle->Text); + delete ini; + sgEdit->Cells[sgEdit->Col][0]=FrmTitle->edTitle->Text; + } +} +//--------------------------------------------------------------------------- + + + +void __fastcall TFrmMain::FormDestroy(TObject *Sender) +{ + if(thOpen){ + thOpen->Terminate(); + SleepEx(200,0); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::ToolButton1Click(TObject *Sender) +{ + bool SeFlag=true; + if(FrmSearch->ShowModal()==mrOk){ + switch (FrmSearch->rgSI->ItemIndex) + { + case 0: //ÏòÉÏÕÒ; + for(int i=sgEdit->ColCount*sgEdit->Row+sgEdit->Col-1;i>sgEdit->ColCount;i--){ + if(i%sgEdit->ColCount!=0){ + if( 0==CompareStr(sgEdit->Cells[i-sgEdit->ColCount*(i/sgEdit->ColCount)][i/sgEdit->ColCount], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Col=i-sgEdit->ColCount*i/sgEdit->ColCount; + sgEdit->Row=i/sgEdit->ColCount; + SeFlag=false; + break; + } + } + } + if(SeFlag) ShowMessage("Seach Top£¬Find Nothing."); + break; + case 1: //ÏòÏÂÕÒ; + for(int i=sgEdit->ColCount*sgEdit->Row+sgEdit->Col+1;iColCount*sgEdit->RowCount;i++){ + if(i%sgEdit->ColCount!=0){ + if( 0==CompareStr(sgEdit->Cells[i-sgEdit->ColCount*(i/sgEdit->ColCount)][i/sgEdit->ColCount], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Col=i-sgEdit->ColCount*(i/sgEdit->ColCount); + sgEdit->Row=i/sgEdit->ColCount; + SeFlag=false; + break; + } + } + } + if(SeFlag) ShowMessage("Seach End£¬Find Nothing"); + break; + case 2: //µ±Ç°ÁÐÏòÉÏÕÒ; + for(int i=sgEdit->Row;i>1;i--){ + if( 0==CompareStr(sgEdit->Cells[sgEdit->Col][i], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Row=i; + SeFlag=false; + break; + } + } + if(SeFlag) ShowMessage("Seach col top£¬Find Nothing"); + break; + case 3: //µ±Ç°ÁÐÏòÏÂÕÒ; + for(int i=sgEdit->Row;iRowCount;i++){ + if( 0==CompareStr(sgEdit->Cells[sgEdit->Col][i], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Row=i; + SeFlag=false; + break; + } + } + if(SeFlag) ShowMessage("Seach col end£¬Find Nothing."); + break; + } + } +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::sgEditKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + + bool SeFlag=true; + if(Key==VK_F3){ + switch (FrmSearch->rgSI->ItemIndex) + { + case 0: //ÏòÉÏÕÒ; + for(int i=sgEdit->ColCount*sgEdit->Row+sgEdit->Col-1;i>sgEdit->ColCount;i--){ + if(i%sgEdit->ColCount!=0){ + if( 0==CompareStr(sgEdit->Cells[i-sgEdit->ColCount*(i/sgEdit->ColCount)][i/sgEdit->ColCount], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Col=i-sgEdit->ColCount*i/sgEdit->ColCount; + sgEdit->Row=i/sgEdit->ColCount; + SeFlag=false; + break; + } + } + } + if(SeFlag) ShowMessage("Seach Top£¬Find Nothing."); + break; + case 1: //ÏòÏÂÕÒ; + for(int i=sgEdit->ColCount*sgEdit->Row+sgEdit->Col+1;iColCount*sgEdit->RowCount;i++){ + if(i%sgEdit->ColCount!=0){ + if( 0==CompareStr(sgEdit->Cells[i-sgEdit->ColCount*(i/sgEdit->ColCount)][i/sgEdit->ColCount], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Col=i-sgEdit->ColCount*(i/sgEdit->ColCount); + sgEdit->Row=i/sgEdit->ColCount; + SeFlag=false; + break; + } + } + } + if(SeFlag) ShowMessage("Seach End£¬Find Nothing."); + break; + case 2: //µ±Ç°ÁÐÏòÉÏÕÒ; + for(int i=sgEdit->Row;i>1;i--){ + if( 0==CompareStr(sgEdit->Cells[sgEdit->Col][i], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Row=i; + SeFlag=false; + break; + } + } + if(SeFlag) ShowMessage("Seach col Top£¬Find Nothing."); + break; + case 3: //µ±Ç°ÁÐÏòÏÂÕÒ; + for(int i=sgEdit->Row;iRowCount;i++){ + if( 0==CompareStr(sgEdit->Cells[sgEdit->Col][i], + FrmSearch->edSeach->Text)){ //ÕÒµ½ÁË + sgEdit->Row=i; + SeFlag=false; + break; + } + } + if(SeFlag) ShowMessage("Seach col end£¬Find Nothing."); + break; + } + } +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::sgEditSelectCell(TObject *Sender, int ACol, + int ARow, bool &CanSelect) +{ +// +} +//--------------------------------------------------------------------------- +void __fastcall TFrmMain::OpenFileCol(AnsiString FileName,int ColIndex,int ColType) +{ + int iFileHandle; //Îļþ¾ä±ú + char Txtbuf[255]; + int iVal; + float fVal; + FILE *stream; + long curpos, length; + DWORD dwRows, dwCols, dwRowLen, dwTextLen; + + DWORD dwTextStartPos; + char* pTextPtr ; + + + if ((stream = fopen(FileName.c_str(), "r+")) + == NULL) + { + ShowMessage("Open File Error"); + return; + } + + curpos = ftell(stream); + fseek(stream, 0L, SEEK_END); + length = ftell(stream); + + + switch (ColType) + { + case 0: //ÕûÐÍÖµ Int + for(int i=0;iRowCount-1;i++){ + fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(ColIndex-1))*4, 0); + fread(&iVal, 4, 1, stream); + sgEdit->Cells[ColIndex][i+1]=IntToStr(iVal); + } + break; + case 1: //¸¡µãÖµ Float + for(int i=0;iRowCount-1;i++){ + fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(ColIndex-1))*4, 0); + fread(&fVal, 4, 1, stream); + sgEdit->Cells[ColIndex][i+1]=FloatToStr(fVal); + } + break; + case 2: //Îı¾ Text + fseek(stream,0x4,0); + fread(&iVal, 4, 1, stream); + dwRows= iVal; + fread(&iVal, 4, 1, stream); + dwCols = iVal; + fread(&iVal, 4, 1, stream); + dwRowLen = iVal; + fread(&iVal, 4, 1, stream); + dwTextLen = iVal; + + dwTextStartPos = dwRows*dwRowLen+20; + for(int i=0;iRowCount-1;i++){ + fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(ColIndex-1))*4, 0); + fread(&iVal, 4, 1, stream); + sgEdit->Cells[ColIndex][i+1]=IntToStr(iVal); + if(dwTextStartPos + iVal < length){ + fseek(stream,dwTextStartPos + iVal,0); + fread(Txtbuf, 1, 255, stream); + //pTextPtr = pBuff + dwTextStartPos + lTemp; + sgEdit->Cells[ColIndex][i+1]=Txtbuf; + }else{ + sgEdit->Cells[ColIndex][i+1]="This Col Not Text!"; + } + } + break; + } + fclose(stream); +} +void __fastcall TFrmMain::Timer1Timer(TObject *Sender) +{ + if(OpenOk){ + lbOpState->Caption = "Open File Ok."; + }else{ + lbOpState->Caption = "Open Now....."; + } +} +//--------------------------------------------------------------------------- +//µ±Ç°¸ñ×ÓдÈëÐÞ¸ÄÎļþÖÐ +void __fastcall TFrmMain::N4Click(TObject *Sender) +{ + if(!thOpen) return; + + int iFileHandle; //Îļþ¾ä±ú + char buf[4]; + int iVal; + float fVal; + FILE *stream; +/* + if ((stream = fopen(CurrentOpenFile.c_str(), "r+")) + == NULL) + { + ShowMessage("´ò¿ªÎļþ³ö´í"); + return; + } +*/ + iFileHandle = FileOpen(CurrentOpenFile, fmOpenRead|fmOpenWrite);//´ò¿ªÎļþ + + switch (thOpen->ColType[sgEdit->Col]) + { + case 0: //ÕûÐÍÖµ + //for(int i=0;iRowCount-1;i++){ + /* + fseek(stream, 0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4, 0); + iVal=StrToInt(sgEdit->Cells[sgEdit->Col][sgEdit->Row]); + memcpy(buf, &iVal, 4); + for(int i=0;i<4;i++) + fwrite(buf+i, 1, 1, stream); + */ + iVal=StrToInt(sgEdit->Cells[sgEdit->Col][sgEdit->Row]); + memcpy(buf, &iVal, 4); + FileSeek(iFileHandle,0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4,0); + FileWrite(iFileHandle,buf,4); + //} + break; + case 1: //¸¡µãÖµ + //fseek(stream, 0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4, 0); + //fVal=StrToFloat(sgEdit->Cells[sgEdit->Col][sgEdit->Row]); + //fwrite(&fVal, 4, 1, stream); + fVal=StrToFloat(sgEdit->Cells[sgEdit->Col][sgEdit->Row]); + memcpy(buf, &fVal, 4); + FileSeek(iFileHandle,0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4,0); + FileWrite(iFileHandle,buf,4); + break; + case 2: //Îı¾²»Ð´Èë + break; + } + + // fclose(stream); + FileClose(iFileHandle); +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::btTxtTypeClick(TObject *Sender) +{ +if(OpenOk==true){ + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(CurrentOpenFile); + TIniFile *ini; + ini = new TIniFile( iniSetFile ); + ini->WriteInteger(SectionName,"ColType"+IntToStr(sgEdit->Col),2); + delete ini; + thOpen->ColType[sgEdit->Col]=2; + OpenFileCol(CurrentOpenFile,sgEdit->Col,2); +} +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::ToolButton3Click(TObject *Sender) +{ + int OldCol; + int OldRow; + OldRow=sgEdit->Row; + OldCol=sgEdit->Col; + if(sgEdit->FixedCols==1){ + sgEdit->FixedCols =2; + if(OldCol!=1) + sgEdit->Col=OldCol; + sgEdit->Row=OldRow; + }else{ + sgEdit->FixedCols =1; + sgEdit->Row=OldRow; + if(OldCol!=2) + sgEdit->Col=OldCol; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::btRowSaveClick(TObject *Sender) +{ +if(OpenOk==false) return; + + int iFileHandle; //Îļþ¾ä±ú + char Txtbuf[255]; + int iVal; + char buf[4]; + float fVal; + FILE *stream; + long curpos, length; + DWORD dwRows, dwCols, dwRowLen, dwTextLen; + + DWORD dwTextStartPos; + char* pTextPtr ; + + + //if ((stream = fopen(CurrentOpenFile.c_str(), "r+")) + // == NULL) + //{ + // ShowMessage("´ò¿ªÎļþ³ö´í"); + // return; + //} + + //curpos = ftell(stream); + //fseek(stream, 0L, SEEK_END); + //length = ftell(stream); + iFileHandle = FileOpen(CurrentOpenFile, fmOpenRead|fmOpenWrite);//´ò¿ªÎļþ + +for(int i=0;iColCount-1;i++){ + switch (thOpen->ColType[i]) + { + case 0: //ÕûÐÍÖµ sgEdit->Row + //fseek(stream, 0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+i)*4, 0); + //iVal=StrToInt(sgEdit->Cells[i+1][sgEdit->Row]); + //fwrite(&iVal, 4, 1, stream); + iVal=StrToInt(sgEdit->Cells[i+1][sgEdit->Row]); + memcpy(buf, &iVal, 4); + FileSeek(iFileHandle,0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+i)*4,0); + FileWrite(iFileHandle,buf,4); + break; + case 1: //¸¡µãÖµ + //fseek(stream, 0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+i)*4, 0); + //fVal=StrToFloat(sgEdit->Cells[i+1][sgEdit->Row]); + //fwrite(&fVal, 4, 1, stream); + fVal=StrToFloat(sgEdit->Cells[i+1][sgEdit->Row]); + memcpy(buf, &fVal, 4); + FileSeek(iFileHandle,0x14+((sgEdit->Row-1)*(sgEdit->ColCount-1)+i)*4,0); + FileWrite(iFileHandle,buf,4); + break; + case 2: //Îı¾ ²»´æ + break; + } +} + //fclose(stream); + FileClose(iFileHandle); + ShowMessage("The "+IntToStr(sgEdit->Row)+" Row Write Ok!"); +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::btColSaveClick(TObject *Sender) +{ +if(OpenOk==false) return; + + int iFileHandle; //Îļþ¾ä±ú + char Txtbuf[255]; + int iVal; + char buf[4]; + float fVal; + FILE *stream; + long curpos, length; + DWORD dwRows, dwCols, dwRowLen, dwTextLen; + + DWORD dwTextStartPos; + char* pTextPtr ; + + iFileHandle = FileOpen(CurrentOpenFile, fmOpenRead|fmOpenWrite);//´ò¿ªÎļþ + + //if ((stream = fopen(CurrentOpenFile.c_str(), "r+")) + // == NULL) + //{ + // ShowMessage("´ò¿ªÎļþ³ö´í"); + // return; + //} + + //curpos = ftell(stream); + //fseek(stream, 0L, SEEK_END); + //length = ftell(stream); + + + switch (thOpen->ColType[sgEdit->Col]) + { + case 0: //ÕûÐÍÖµ + for(int i=0;iRowCount-1;i++){ + //fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4, 0); + //iVal=StrToInt(sgEdit->Cells[sgEdit->Col][i+1]); + //fwrite(&iVal, 4, 1, stream); + iVal=StrToInt(sgEdit->Cells[sgEdit->Col][i+1]); + memcpy(buf, &iVal, 4); + FileSeek(iFileHandle,0x14+(i*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4,0); + FileWrite(iFileHandle,buf,4); + } + break; + case 1: //¸¡µãÖµ + for(int i=0;iRowCount-1;i++){ + //fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4, 0); + //fVal=StrToFloat(sgEdit->Cells[sgEdit->Col][i+1]); + //fwrite(&fVal, 4, 1, stream); + fVal=StrToFloat(sgEdit->Cells[sgEdit->Col][i+1]); + memcpy(buf, &fVal, 4); + FileSeek(iFileHandle,0x14+(i*(sgEdit->ColCount-1)+(sgEdit->Col-1))*4,0); + FileWrite(iFileHandle,buf,4); + } + break; + case 2: //Îı¾ ²»´æ + break; + } + //fclose(stream); + + FileClose(iFileHandle); + ShowMessage("The "+IntToStr(sgEdit->Col)+"Col Write Ok!"); +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::btRowClearClick(TObject *Sender) +{ +if(OpenOk==false) return; + + int iFileHandle; //Îļþ¾ä±ú + char Txtbuf[255]; + int iVal; + float fVal; + FILE *stream; + long curpos, length; + DWORD dwRows, dwCols, dwRowLen, dwTextLen; + + DWORD dwTextStartPos; + char* pTextPtr ; + + + if ((stream = fopen(CurrentOpenFile.c_str(), "r+")) + == NULL) + { + ShowMessage("Open File Error!"); + return; + } + + curpos = ftell(stream); + fseek(stream, 0L, SEEK_END); + length = ftell(stream); + +for(int i=1;iColCount-1;i++){ + switch (thOpen->ColType[i]) + { + case 0: //ÕûÐÍÖµ sgEdit->Row + //fseek(stream, 0x14+(sgEdit->Row*(sgEdit->ColCount-1)+i)*4, 0); + //iVal=StrToInt(sgEdit->Cells[i+1][sgEdit->Row]); + //fwrite(&iVal, 4, 1, stream); + sgEdit->Cells[i+1][sgEdit->Row]="0"; + break; + case 1: //¸¡µãÖµ + //fseek(stream, 0x14+(sgEdit->Row*(sgEdit->ColCount-1)+i)*4, 0); + //fVal=StrToFloat(sgEdit->Cells[i+1][sgEdit->Row]); + //fwrite(&fVal, 4, 1, stream); + sgEdit->Cells[i+1][sgEdit->Row]="0"; + break; + case 2: //Îı¾ ²»´æ + break; + } +} + fclose(stream); +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::btColClearClick(TObject *Sender) +{ +if(OpenOk==false) return; + + int iFileHandle; //Îļþ¾ä±ú + char Txtbuf[255]; + int iVal; + float fVal; + FILE *stream; + long curpos, length; + DWORD dwRows, dwCols, dwRowLen, dwTextLen; + + DWORD dwTextStartPos; + char* pTextPtr ; + + + if ((stream = fopen(CurrentOpenFile.c_str(), "r+")) + == NULL) + { + ShowMessage("Open File Error!"); + return; + } + + curpos = ftell(stream); + fseek(stream, 0L, SEEK_END); + length = ftell(stream); + + + switch (thOpen->ColType[sgEdit->Col]) + { + case 0: //ÕûÐÍÖµ + for(int i=0;iRowCount-1;i++){ + //fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(ColIndex-1))*4, 0); + //iVal=StrToInt(sgEdit->Cells[ColIndex][i+1]); + //fwrite(&iVal, 4, 1, stream); + sgEdit->Cells[sgEdit->Col][i+1]="0"; + } + break; + case 1: //¸¡µãÖµ + for(int i=0;iRowCount-1;i++){ + //fseek(stream, 0x14+(i*(sgEdit->ColCount-1)+(ColIndex-1))*4, 0); + //fVal=StrToFloat(sgEdit->Cells[ColIndex][i+1]); + //fwrite(&fVal, 4, 1, stream); + sgEdit->Cells[sgEdit->Col][i+1]="0"; + } + break; + case 2: //Îı¾ ²»´æ + break; + } + fclose(stream); +} +//--------------------------------------------------------------------------- + +void __fastcall TFrmMain::ToolButton4Click(TObject *Sender) +{ + AnsiString Cmd; + Cmd = "calc.exe"; + WinExec(Cmd.c_str(), SW_SHOWNORMAL); +} +//--------------------------------------------------------------------------- + + diff --git a/contrib/dbcEditer/dbcedit.ddp b/contrib/dbcEditer/dbcedit.ddp new file mode 100644 index 000000000..cdc0ee8c2 Binary files /dev/null and b/contrib/dbcEditer/dbcedit.ddp differ diff --git a/contrib/dbcEditer/dbcedit.dfm b/contrib/dbcEditer/dbcedit.dfm new file mode 100644 index 000000000..0750c97cd --- /dev/null +++ b/contrib/dbcEditer/dbcedit.dfm @@ -0,0 +1,1259 @@ +object FrmMain: TFrmMain + Left = 162 + Top = 122 + Width = 544 + Height = 375 + Caption = 'Dbc Editer v1.4.2 Vendy QQ:11177905' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 13 + object Panel1: TPanel + Left = 0 + Top = 33 + Width = 536 + Height = 315 + Align = alClient + Caption = 'Panel1' + TabOrder = 0 + object sgEdit: TStringGrid + Left = 1 + Top = 1 + Width = 534 + Height = 287 + Align = alClient + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goRowSizing, goColSizing, goEditing] + PopupMenu = PopupMenu1 + TabOrder = 0 + OnKeyDown = sgEditKeyDown + OnSelectCell = sgEditSelectCell + end + object pnFileName: TPanel + Left = 1 + Top = 288 + Width = 534 + Height = 26 + Align = alBottom + Alignment = taLeftJustify + Caption = 'pnFileName' + Font.Charset = DEFAULT_CHARSET + Font.Color = clRed + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + object lbOpState: TLabel + Left = 444 + Top = 1 + Width = 89 + Height = 24 + Align = alRight + AutoSize = False + Caption = #25171#24320#25991#20214#29366#24577 + end + end + end + object CoolBar1: TCoolBar + Left = 0 + Top = 0 + Width = 536 + Height = 33 + Bands = < + item + Control = ToolBar1 + ImageIndex = -1 + Width = 532 + end> + object ToolBar1: TToolBar + Left = 9 + Top = 0 + Width = 519 + Height = 25 + Caption = 'ToolBar1' + Images = ImageList1 + TabOrder = 0 + object btOpen: TToolButton + Left = 0 + Top = 2 + Caption = 'btOpen' + ImageIndex = 7 + OnClick = btOpenClick + end + object btSave: TToolButton + Left = 23 + Top = 2 + Caption = 'btSave' + Enabled = False + Grouped = True + ImageIndex = 8 + OnClick = btSaveClick + end + object ToolButton2: TToolButton + Left = 46 + Top = 2 + Width = 8 + Caption = 'ToolButton2' + ImageIndex = 10 + Style = tbsSeparator + end + object ToolButton1: TToolButton + Left = 54 + Top = 2 + Caption = 'ToolButton1' + ImageIndex = 9 + OnClick = ToolButton1Click + end + object ToolButton3: TToolButton + Left = 77 + Top = 2 + Caption = 'ToolButton3' + ImageIndex = 10 + OnClick = ToolButton3Click + end + object ToolButton5: TToolButton + Left = 100 + Top = 2 + Width = 8 + Caption = 'ToolButton5' + ImageIndex = 12 + Style = tbsSeparator + end + object ToolButton4: TToolButton + Left = 108 + Top = 2 + Caption = 'ToolButton4' + ImageIndex = 11 + OnClick = ToolButton4Click + end + end + end + object OpenDialog1: TOpenDialog + Filter = '.dbc|*.dbc' + Left = 216 + Top = 96 + end + object PopupMenu1: TPopupMenu + OnPopup = PopupMenu1Popup + Left = 264 + Top = 96 + object N1: TMenuItem + Caption = 'Set Current Col Title' + OnClick = N1Click + end + object N2: TMenuItem + Caption = 'Set Current Col Type' + object btIntType: TMenuItem + Caption = 'INT' + OnClick = btIntTypeClick + end + object btFloatType: TMenuItem + Caption = 'FLOAT' + OnClick = btFloatTypeClick + end + object btTxtType: TMenuItem + Caption = 'TEXT' + OnClick = btTxtTypeClick + end + end + object N4: TMenuItem + Caption = 'Write Current Grid' + OnClick = N4Click + end + object btRowSave: TMenuItem + Caption = 'Write Current Row' + OnClick = btRowSaveClick + end + object btColSave: TMenuItem + Caption = 'Write Current Col' + OnClick = btColSaveClick + end + object btRowClear: TMenuItem + Caption = 'Clear Current Row' + OnClick = btRowClearClick + end + object btColClear: TMenuItem + Caption = 'Clear Current Col' + OnClick = btColClearClick + end + end + object ImageList1: TImageList + Left = 352 + Top = 112 + Bitmap = { + 494C010118001D00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000008000000001002000000000000080 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000008000000080000000800000008000000080000000800000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF000000FF00FFFFFF00FFFFFF00FFFFFF000000FF000000FF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008000 + 000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF008000 + 000080000000000000000000000000000000000000000000000000000000FFFF + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF + 000000FF00000000000000000000000000000000000000000000000000000000 + 00000000FF0080808000000000000000000000000000000000000000FF008080 + 8000000000000000000000000000000000000000000000000000800000008000 + 000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF008000 + 0000800000008000000000000000000000000000000000000000FFFFFF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF00FFFFFF000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF00808080000000000000000000000000000000FF00808080000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000FFFFFF00FFFFFF00FFFFFF00800000008000 + 00008000000080000000000000000000000000000000FFFFFF000000FF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF000000FF00FFFFFF0000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF008080800000000000000000000000FF0080808000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000FFFFFF00FFFFFF00FFFFFF00800000008000 + 0000800000008000000080000000000000000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF0080808000000000000000FF008080800000000000000000000000 + 0000000000000000000000000000000000008000000080000000800000008000 + 0000800000008000000080000000FFFFFF00FFFFFF00FFFFFF00800000008000 + 0000800000008000000080000000000000000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF00808080000000FF00808080000000000000000000000000000000 + 0000000000000000000000000000000000008000000080000000800000008000 + 0000800000008000000080000000FFFFFF00FFFFFF00FFFFFF00800000008000 + 000080000000800000008000000000000000FFFFFF000000FF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000000FF00FFFFFF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF000000FF000000FF000000FF000000FF000000FF000000FF008080 + 8000000000000000000000000000000000008000000080000000800000008000 + 0000800000008000000080000000FFFFFF00FFFFFF00FFFFFF00800000008000 + 000080000000800000008000000000000000FFFFFF000000FF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000000FF00FFFFFF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF0080808000808080008080800080808000808080000000FF008080 + 8000000000000000000000000000000000008000000080000000800000008000 + 0000800000008000000080000000FFFFFF00FFFFFF00FFFFFF00800000008000 + 000080000000800000008000000000000000FFFFFF000000FF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000000FF00FFFFFF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF0080808000000000000000000000000000000000000000FF008080 + 8000000000000000000000000000000000000000000080000000800000008000 + 000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00800000008000 + 0000800000008000000080000000000000000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF00808080000000000000000000000000000000FF000000FF008080 + 8000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000080000000000000000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF000000FF000000FF000000FF00000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000FF000000FF000000FF000000FF000000FF00808080000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 00008000000080000000FFFFFF00FFFFFF00FFFFFF0080000000800000008000 + 00008000000080000000000000000000000000000000FFFFFF000000FF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF000000FF00FFFFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008080800080808000808080008080800080808000000000000000 + 0000000000000000000000000000000000000000000000000000800000008000 + 00008000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00800000008000 + 0000800000000000000000000000000000000000000000000000FFFFFF000000 + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 + FF00FFFFFF000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008000 + 00008000000080000000FFFFFF00FFFFFF00FFFFFF0080000000800000008000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000800000008000000080000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000FF000000FF00FFFFFF00FFFFFF00FFFFFF000000FF000000FF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000800000008000000080000000800000008000 + 0000800000008000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000000000000000000000000 + 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF + 000000FF00000000000000000000000000000000000000000000000000000000 + 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF + 000000FF00000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000080000000800000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000008000 + 0000FFFFFF00FFFFFF0080000000800000008000000080000000800000008000 + 00008000000080000000FFFFFF00800000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000008000 + 0000FFFFFF00FFFFFF0080000000800000008000000080000000800000008000 + 0000800000008000000080000000800000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000008000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00800000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000080000000FFFFFF008000 + 000080000000800000008000000080000000800000008000000080000000FFFF + FF00800000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000080000000FFFFFF008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00800000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 00008000000080000000FFFFFF00800000008000000080000000800000008000 + 0000FFFFFF008000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000FF00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000000000000000000000000000080000000800000008000 + 00008000000080000000800000008000000080000000FFFFFF00800000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008000 + 0000C0C0C0008000000080000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008000000080000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000080000000C0C0 + C000800000008000000080000000000000000000000000000000000000000000 + 0000000000000000000000000000800000008000000080000000000000000000 + 0000000000000000000000000000000000000000000000000000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0000000 + 0000C0C0C0000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000C0C0C0008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000800000008000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C0C0C00000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000080000000C0C0C000800000008000 + 000080000000000000000000000000000000000000000000000080808000C0C0 + C000FFFFFF008080800000000000800000000000000000000000000000000000 + 00000000800000000000000000000000000000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C00000FFFF0000FFFF0000FFFF00C0C0C000C0C0 + C000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF008000000000000000000000000000000000000000000000000000 + 0000C0C0C000C0C0C000C0C0C000FFFFFF008080800080000000800000008000 + 0000000000000000000000000000000000000000000080808000C0C0C000C0C0 + C000C0C0C000FFFFFF0080808000000000000000000000000000000000000000 + 80000000800000000000000000000000000000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C000808080008080800080808000C0C0C000C0C0 + C00000000000C0C0C00000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 000080000000800000000000000000000000000000000000000080808000C0C0 + C000C0C0C000C0C0C000C0C0C000C0C0C000FFFFFF0080808000000000000000 + 00000000000000000000000000000000000000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C000FFFFFF00000000000000000000000000000080000000 + 8000000080000000800000008000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C0C0C000C0C0C000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000FFFFFF008000000000000000000000000000000000000000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000FFFFFF00000000000000 + 00000000000000000000000000000000000000000000C0C0C000FFFFFF00FFFF + 0000C0C0C000C0C0C000C0C0C000000000000000000000000000000000000000 + 80000000800000000000000000000000800000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0000000 + 0000C0C0C00000000000C0C0C000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 00008000000080000000000000000000000000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0000000 + 0000000000000000000000000000000000000000000080808000FFFFFF00FFFF + FF00C0C0C000C0C0C00080808000000000000000000000000000000000000000 + 0000000080000000000000000000000080000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C0C0 + C00000000000C0C0C00000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0080000000000000000000000000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0000000 + 000000000000000000000000000000000000000000000000000080808000C0C0 + C000C0C0C0008080800000000000000000000000000000000000000000000000 + 000000000000000000000000000000008000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0000C0C0C00000000000C0C0C000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0080000000000000000000000000000000C0C0C000FFFFFF00FFFF + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000008000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000FFFFFF000000000000000000000000000000000000000000FFFFFF000000 + 0000000000000000000000000000000000000000000080000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0080000000000000000000000000000000C0C0C000FFFFFF00FFFF + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000008000000000000000 + 0000000080000000000000000000000000000000000000000000000000000000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000000000000000000000000000000000000FFFFFF00FFFF + FF00FFFF0000FFFF0000C0C0C000C0C0C000C0C0C000C0C0C000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000008000000000000000 + 0000000080000000800000000000000000000000000000000000000000000000 + 000000000000FFFFFF000000000000000000000000000000000000000000FFFF + FF00000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000FFFFFF00800000000000000000000000000000000000000080808000FFFF + FF00FFFFFF00FFFFFF00C0C0C000C0C0C000C0C0C00080808000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000080000000 + 8000000080000000800000008000000000000000000000000000000000000000 + 000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000000000000000000000000000000000080000000800000008000 + 0000800000008000000080000000800000008000000080000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C0000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000080000000800000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000080000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008080000080 + 8000000000000000000000000000000000000000000000000000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008080000080 + 8000000000000000000000000000000000000000000000000000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 00000000000000000000000000000000000000000000FFFFFF00000000000000 + 0000FFFFFF000000000000000000000000000000000000000000FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000800000008000 + 0000800000000000000000000000000000000000000000000000008080000080 + 8000000000000000000000000000000000000000000000000000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF000000000080808000C0C0C000C0C0C0008080 + 80000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000800000008000 + 0000800000000000000000000000000000000000000000000000008080000080 + 8000000000000000000000000000000000000000000000000000000000000000 + 00000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF000000000080808000C0C0C000C0C0C000FFFF00008080 + 80008080800000000000000000000000000000000000FFFFFF00000000000000 + 0000FFFFFF000000000000000000000000000000000000000000FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008080000080 + 8000008080000080800000808000008080000080800000808000008080000080 + 80000080800000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0000000000C0C0C000C0C0C000C0C0C000C0C0C0008080 + 8000C0C0C00000000000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000800000008000 + 0000800000000000000000000000000000000000000000000000008080000080 + 8000000000000000000000000000000000000000000000000000000000000000 + 00000080800000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0000000000C0C0C000FFFF0000C0C0C000C0C0C0008080 + 8000C0C0C00000000000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000800000008000 + 0000800000000000000000000000000000000000000000000000008080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF000000000080808000FFFF0000FFFF0000C0C0C0008080 + 80008080800000000000000000000000000000000000FFFFFF00000000000000 + 0000FFFFFF00FFFFFF00FFFFFF0000000000C0C0C00000000000FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008000 + 0000800000008000000000000000000000000000000000000000008080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF000000000080808000C0C0C000C0C0C0008080 + 80000000000000000000000000000000000000000000FFFFFF0000000000C0C0 + C00000000000FFFFFF0000000000C0C0C00000000000C0C0C000000000000000 + 0000000000000000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000008000000080000000000000000000000000000000008080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 00000000000000000000000000000000000000000000FFFFFF00FFFFFF000000 + 0000C0C0C00000000000C0C0C00000000000C0C0C00000000000C0C0C000C0C0 + C000C0C0C0000000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000800000008000000080000000000000000000 + 0000000000008000000080000000800000000000000000000000008080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C0000000000000808000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C0C0C00000000000C0C0C00000000000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C00080000000800000000000000000000000000000000000 + 0000000000000000000000000000800000008000000080000000000000000000 + 0000000000008000000080000000800000000000000000000000008080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C0000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C0C0C00000000000C0C0C000C0C0C000C0C0C000C0C0 + C000C0C0C000C0C0C00080000000800000000000000000000000000000000000 + 0000000000000000000000000000800000008000000080000000000000000000 + 0000000000008000000080000000800000000000000000000000008080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C00000000000C0C0C000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000C0C0C000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000C0C0C000C0C0C000C0C0C000C0C0C000C0C0 + C000C0C0C0000000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000008000000080000000800000008000 + 0000800000008000000080000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000000000000008080000080 + 8000008080000080800000808000008080000080800000808000008080000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000000FFFF00000000000080 + 8000008080000080800000808000008080000080800000808000008080000080 + 8000000000000000000000000000000000000000000000000000000000008000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF000000000000000000000000000000000000000000FFFFFF0000FFFF000000 + 0000008080000080800000808000008080000080800000808000008080000080 + 8000008080000000000000000000000000000000000000000000000000008000 + 0000000000000000000000000000000000000000000080000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000000FFFF00FFFFFF0000FF + FF00000000000080800000808000008080000080800000808000008080000080 + 8000008080000080800000000000000000000000000000000000800000000000 + 0000000000000000000000000000000000000000000000000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF000000000000000000000000000000000000000000FFFFFF0000FFFF00FFFF + FF0000FFFF000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000800000000000 + 0000000000000000000000000000000000000000000000000000000000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000000FFFF00FFFFFF0000FF + FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000 + 0000000000000000000000000000000000000000000000000000800000000000 + 0000000000000000000000000000000000000000000000000000800000000000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF000000000000000000000000000000000000000000FFFFFF0000FFFF00FFFF + FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF00000000000000 + 0000000000000000000000000000000000000000000000000000000000008000 + 0000000000000000000000000000000000008000000080000000000000000000 + 0000000000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000000FFFF00FFFFFF0000FF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000008000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008000000080000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000080000000800000008000000080000000800000008000 + 0000800000008000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000000000000000000000800000000000000000000000800000008000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000800000008000000080000000800000008000 + 0000800000008000000080000000800000000000000000000000000000000000 + 0000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000000000000000000000800000000000000080000000000000000000 + 0000800000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000080808000008080008080 + 8000008080008080800080000000FFFFFF000000000000000000000000000000 + 00000000000000000000FFFFFF00800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000000000000000000000800000000000000080000000000000000000 + 0000800000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000080000000FFFFFF0000000000000000000000 + 00000000000000000000FFFFFF00800000000000000000808000808080000080 + 8000808080000080800080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008000000080000000800000000000000080000000000000000000 + 0000800000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000080808000008080008080 + 8000008080008080800080000000FFFFFF00000000000000000000000000FFFF + FF00800000008000000080000000800000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000800000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000800000000000000080000000800000008000 + 0000000000000000000000000000000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF0000000000000000000000 + 00000000000000000000FFFFFF00800000000000000000808000808080000080 + 8000808080000080800080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080000000FFFFFF0080000000000000000000000000000000800000008000 + 0000800000008000000080000000000000000000000000000000000000000000 + 0000800000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000800000000000000080000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF000000 + 000000000000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00800000000000000080808000008080008080 + 8000008080008080800080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00800000008000000000000000000000000000000000000000800000008000 + 0000800000008000000000000000000000000000000000000000000000000000 + 0000000000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF000000000000000000FFFF + FF00800000008000000080000000800000000000000000808000808080000080 + 8000808080000080800080000000800000008000000080000000800000008000 + 0000800000000000000000000000000000000000000000000000800000008000 + 0000800000000000000000000000000000000000000000000000000000000000 + 0000000000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF000000 + 000000000000000000000000000080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF0080000000FFFFFF0080000000000000000000000080808000008080008080 + 8000008080008080800000808000808080000080800080808000008080008080 + 8000008080000000000000000000000000000000000000000000800000008000 + 0000000000008000000000000000000000000000000000000000000000000000 + 0000000000008000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0080000000FFFFFF00FFFFFF00FFFFFF00FFFF + FF00800000008000000000000000000000000000000000808000808080000000 + 0000000000000000000000000000000000000000000000000000000000008080 + 8000808080000000000000000000000000000000000000000000800000000000 + 0000000000000000000080000000800000000000000000000000000000000000 + 0000800000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF000000 + 000000000000FFFFFF0000000000800000008000000080000000800000008000 + 0000800000000000000000000000000000000000000080808000808080000000 + 0000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C000000000008080 + 8000008080000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008000000080000000800000008000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF0000000000FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000808000808080000080 + 80000000000000FFFF00000000000000000000FFFF0000000000808080000080 + 8000808080000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000FFFF0000FFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000800000000100010000000000000400000000000000000000 + 000000000000000000000000FFFFFF0000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000FFF7FFFFFC3FFFFFFFFBFFFFE00FF01F + E001FFFFC007E00FE003F3CF8003C007E7F7F39F80018003E7C3F33F00010001 + E7EFF27F00000001E7F7F0FF00000001E7FBF00F00000001E7C3F00F00000001 + E77FF3CF00010001E77FF38F00010001A37FF81F80018003C6BFF83FC003C007 + EDDFFFFFE007E00FFFFFFFFFF01FF01FFFFFFC00FFF7FFF78003FC00FFFBFFFB + 8003FC00E001E0018003FC00E003E0038003E000E7F7E7F78003E000E7DDE707 + 8003E000E7EBE7BF8003E007E7F7E7DF80038007E7EBE70F80038007E75DE7FF + 80038007E77FE5DF8003801FE77FE6BF8003801FA37FA37F8003801FC6BFC6BF + FFFF801FEDDFEDDFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFE1FF3FC0078003 + FFC1FE3F80038003FF83C07F00018003F00780F700018003C00F00E700018003 + 801F00C100008003801F00E600008003000F00F680008003000F81FEC0008003 + 000FC3BFE0018003000FFFB7E0078003801FFFB3F0078003801FFFC1F0038003 + C03FFFF3F803FFFFF0FFFFF7FFFFFFFFFFFFFFFFFFFFFFFFC001000C000FF9FF + 80010008000FF9FF80010001000FF3C780010003000F73C780010003000F27FF + 80010003000F07C780010003000F00C780010003000F01E380010007000403F1 + 8001000F000006388001000F00000E388001000FF8001E388001001FFC003F01 + 8001003FFE047F83FFFF007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFEFFDC007001FFFFFC7FFC007000FFFFFC3FBC0070007EFFFE3F7C0070003 + EF83F1E7C0070001DFC3F8CFC0070000DFE3FC1FC007001FDFD3FE3FC007001F + EF3BFC1FC007001FF0FFF8CFC0078FF1FFFFE1E7C00FFFF9FFFFC3F3C01FFF75 + FFFFC7FDC03FFF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFFFFFC00FFFF + F6CFFE008000FFFFF6B7FE000000FFFFF6B7FE000000FFFFF8B780000000FFF7 + FE8F80000001C1F7FE3F80000003C3FBFF7F80000003C7FBFE3F80010003CBFB + FEBF80030003DCF7FC9F80070003FF0FFDDF807F0003FFFFFDDF80FF8007FFFF + FDDF81FFF87FFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 + 000000000000} + end + object Timer1: TTimer + Interval = 300 + OnTimer = Timer1Timer + Left = 440 + Top = 48 + end +end diff --git a/contrib/dbcEditer/dbcedit.h b/contrib/dbcEditer/dbcedit.h new file mode 100644 index 000000000..a603768ea --- /dev/null +++ b/contrib/dbcEditer/dbcedit.h @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- + +#ifndef dbceditH +#define dbceditH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thOpenSource.h" + +union TypePtr +{ + long* l; + DWORD* dw; + WORD* w; + char* c; + void* p; + float* f; + + TypePtr(void* in) :p(in) + { + } +}; + +#define TAG(x) (DWORD)( (((DWORD)x&0x0000ff00)<<8)+(((DWORD)x&0x000000ff)<<24)+(((DWORD)x&0x00ff0000)>>8)+(((DWORD)x&0xff000000)>>24) ) + + +//--------------------------------------------------------------------------- +class TFrmMain : public TForm +{ +__published: // IDE-managed Components + TPanel *Panel1; + TCoolBar *CoolBar1; + TToolBar *ToolBar1; + TToolButton *btOpen; + TToolButton *btSave; + TStringGrid *sgEdit; + TOpenDialog *OpenDialog1; + TPopupMenu *PopupMenu1; + TMenuItem *N1; + TMenuItem *N2; + TMenuItem *btIntType; + TMenuItem *btFloatType; + TMenuItem *btTxtType; + TImageList *ImageList1; + TPanel *pnFileName; + TToolButton *ToolButton1; + TToolButton *ToolButton2; + TTimer *Timer1; + TLabel *lbOpState; + TMenuItem *N4; + TToolButton *ToolButton3; + TMenuItem *btRowSave; + TMenuItem *btColSave; + TMenuItem *btRowClear; + TMenuItem *btColClear; + TToolButton *ToolButton4; + TToolButton *ToolButton5; + void __fastcall btOpenClick(TObject *Sender); + void __fastcall btSaveClick(TObject *Sender); + void __fastcall btIntTypeClick(TObject *Sender); + void __fastcall btFloatTypeClick(TObject *Sender); + void __fastcall PopupMenu1Popup(TObject *Sender); + void __fastcall N1Click(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall ToolButton1Click(TObject *Sender); + void __fastcall sgEditKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall sgEditSelectCell(TObject *Sender, int ACol, + int ARow, bool &CanSelect); + void __fastcall Timer1Timer(TObject *Sender); + void __fastcall N4Click(TObject *Sender); + void __fastcall btTxtTypeClick(TObject *Sender); + void __fastcall ToolButton3Click(TObject *Sender); + void __fastcall btRowSaveClick(TObject *Sender); + void __fastcall btColSaveClick(TObject *Sender); + void __fastcall btRowClearClick(TObject *Sender); + void __fastcall btColClearClick(TObject *Sender); + void __fastcall ToolButton4Click(TObject *Sender); +private: // User declarations + + + thOpenFile *thOpen; + bool Term; + +public: // User declarations + bool OpenOk; + + AnsiString CurrentOpenFile; + __fastcall TFrmMain(TComponent* Owner); + void SaveToFile(const char * pszFileName); + void __fastcall OpenFileCol(AnsiString FileName,int ColIndex,int ColType); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFrmMain *FrmMain; +//--------------------------------------------------------------------------- +#endif diff --git a/contrib/dbcEditer/pjDbcEditer.bpr b/contrib/dbcEditer/pjDbcEditer.bpr new file mode 100644 index 000000000..522df6660 --- /dev/null +++ b/contrib/dbcEditer/pjDbcEditer.bpr @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=2052 +CodePage=936 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +Launcher= +UseLauncher=0 +DebugCWD= +HostApplication= +RemoteHost= +RemotePath= +RemoteLauncher= +RemoteCWD= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + +[CORBA] +AddServerUnit=1 +AddClientUnit=1 +PrecompiledHeaders=1 + +[Language] +ActiveLang= +ProjectLang= +RootDir= + + \ No newline at end of file diff --git a/contrib/dbcEditer/pjDbcEditer.cpp b/contrib/dbcEditer/pjDbcEditer.cpp new file mode 100644 index 000000000..db3a8bde8 --- /dev/null +++ b/contrib/dbcEditer/pjDbcEditer.cpp @@ -0,0 +1,37 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +//--------------------------------------------------------------------------- +USEFORM("dbcedit.cpp", FrmMain); +USEFORM("TitleFrm.cpp", FrmTitle); +USEFORM("SearchFrm.cpp", FrmSearch); +//--------------------------------------------------------------------------- +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + try + { + Application->Initialize(); + Application->CreateForm(__classid(TFrmMain), &FrmMain); + Application->CreateForm(__classid(TFrmTitle), &FrmTitle); + Application->CreateForm(__classid(TFrmSearch), &FrmSearch); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + catch (...) + { + try + { + throw Exception(""); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + } + return 0; +} +//--------------------------------------------------------------------------- diff --git a/contrib/dbcEditer/pjDbcEditer.exe b/contrib/dbcEditer/pjDbcEditer.exe new file mode 100644 index 000000000..9b11ec746 Binary files /dev/null and b/contrib/dbcEditer/pjDbcEditer.exe differ diff --git a/contrib/dbcEditer/pjDbcEditer.res b/contrib/dbcEditer/pjDbcEditer.res new file mode 100644 index 000000000..d1c532760 Binary files /dev/null and b/contrib/dbcEditer/pjDbcEditer.res differ diff --git a/contrib/dbcEditer/pjDbcEditer.tds b/contrib/dbcEditer/pjDbcEditer.tds new file mode 100644 index 000000000..1995524a2 Binary files /dev/null and b/contrib/dbcEditer/pjDbcEditer.tds differ diff --git a/contrib/dbcEditer/thOpenSource.cpp b/contrib/dbcEditer/thOpenSource.cpp new file mode 100644 index 000000000..7df4debfe --- /dev/null +++ b/contrib/dbcEditer/thOpenSource.cpp @@ -0,0 +1,182 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "thOpenSource.h" +#include "dbcedit.h" +#include "stdio.h" +#include +#include +#include +#pragma package(smart_init) +//--------------------------------------------------------------------------- + +// Important: Methods and properties of objects in VCL can only be +// used in a method called using Synchronize, for example: +// +// Synchronize(UpdateCaption); +// +// where UpdateCaption could look like: +// +// void __fastcall thOpenFile::UpdateCaption() +// { +// Form1->Caption = "Updated in a thread"; +// } +//--------------------------------------------------------------------------- + +__fastcall thOpenFile::thOpenFile(bool CreateSuspended) + : TThread(CreateSuspended) +{ + +} +//--------------------------------------------------------------------------- +void __fastcall thOpenFile::Execute() +{ + //---- Place thread code here ---- + //if(!Terminated){ + // FrmMain->LoadAndModify(FrmMain->OpenDialog1->FileName.c_str()); + // FrmMain->OpenOk=true; + //} + thEnd=false; + RunOpen(); + FrmMain->OpenOk=true; + thEnd=true; + +} +//--------------------------------------------------------------------------- +void __fastcall thOpenFile::RunOpen() +{ + LoadAndModify(FrmMain->OpenDialog1->FileName.c_str()); + //OpenOk=true; +} + +void thOpenFile::ReadAndModifyFromBuff(char *pBuff, DWORD dwSize, const char* pszFileName) +{ + char szErrorMsg[MAX_PATH]; + char szNewFileName[MAX_PATH]; + DWORD w; + TIniFile *ini; + + + TypePtr p(pBuff); + if('WDBC' != TAG(*p.dw)) + { + _snprintf(szErrorMsg, 512, "[%s]Not Wow's dbc file!", pszFileName); + ShowMessage(szErrorMsg); + return; + } + p.dw++; + + DWORD dwRows, dwCols, dwRowLen, dwTextLen; + dwRows = *p.dw++; + dwCols = *p.dw++; + dwRowLen = *p.dw++; + dwTextLen = *p.dw++; + + FrmMain->sgEdit->RowCount = dwRows+1; + FrmMain->sgEdit->ColCount = dwCols+1; + + for(int i=0; isgEdit->RowCount; i++){ + FrmMain->sgEdit->Cells[0][i]=IntToStr(i); + if(Terminated) return; + } + //É趨ÁбêÌâ + AnsiString iniSetFile=ExtractFilePath(Application->ExeName)+"BcdEditer.ini"; + AnsiString SectionName=ExtractFileName(FrmMain->CurrentOpenFile); + + ini = new TIniFile( iniSetFile ); + for(int j=0; jsgEdit->ColCount; j++){ + FrmMain->sgEdit->Cells[j][0]= ini->ReadString(SectionName,"ColTitle"+IntToStr(j),IntToStr(j)); + //sgEdit->Cells[j][0]=IntToStr(j); + ColType[j]=ini->ReadInteger(SectionName,"ColType"+IntToStr(j),0); + if(Terminated) return; + } + delete ini; + + //int *ColType = new int[dwCols]; + + DWORD dwTextStartPos = dwRows*dwRowLen+20; + char* pTextPtr = pBuff + dwTextStartPos; + char pszTemp[MAX_PATH]; + float fTemp; + long lTemp; + DWORD i, j; + BOOL* pbString = new BOOL[dwRows*dwCols]; + float newTmp; + //int ColType; + + ini = new TIniFile( iniSetFile ); + + for(i=0; isgEdit->Cells[j+1][i+1]=IntToStr(lTemp); + else{ + + //ColType= ini->ReadInteger(SectionName,"ColType"+IntToStr(j),0); + + switch (ColType[j+1]) + { + case 0: //ÕûÐÍ + FrmMain->sgEdit->Cells[j+1][i+1]=IntToStr(lTemp); + break; + case 1: //¸¡µã + FrmMain->sgEdit->Cells[j+1][i+1]=FloatToStr(fTemp); + break; + case 2: //Îı¾ Îı¾ÀàÐÍÖ»ÄÜ¿´£¬²»Äܱ༭ + if(dwTextStartPos + lTemp < dwSize){ + pTextPtr = pBuff + dwTextStartPos + lTemp; + FrmMain->sgEdit->Cells[j+1][i+1]=pTextPtr; + }else{ + FrmMain->sgEdit->Cells[j+1][i+1]="¸ÃÁв»ÊÇÎı¾"; + } + break; + default: //ÕûÐÍ + FrmMain->sgEdit->Cells[j+1][i+1]=IntToStr(lTemp); + } + } + p.c += 4; + } + } + + delete [] pbString; + //delete [] ColType; + delete ini; + +} + +void thOpenFile::LoadAndModify(const char * pszFileName) +{ + HANDLE hFile = NULL; + hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if(hFile == INVALID_HANDLE_VALUE)return; + + DWORD r = 0, nFileSize = 0; + nFileSize = GetFileSize(hFile, NULL); + char* pTmpBuf = new char[nFileSize]; + if(pTmpBuf==NULL) + { + CloseHandle(hFile); + return; + } + ReadFile(hFile, pTmpBuf, nFileSize, &r, NULL); + + FrmMain->CurrentOpenFile=pszFileName; + FrmMain->btSave->Enabled=true; + + ReadAndModifyFromBuff(pTmpBuf, nFileSize, pszFileName); + + //SAFE_DELETE_ARRAY(pTmpBuf); + delete [] pTmpBuf; + CloseHandle(hFile); + +} diff --git a/contrib/dbcEditer/thOpenSource.h b/contrib/dbcEditer/thOpenSource.h new file mode 100644 index 000000000..edf6bd064 --- /dev/null +++ b/contrib/dbcEditer/thOpenSource.h @@ -0,0 +1,24 @@ +//--------------------------------------------------------------------------- + +#ifndef thOpenSourceH +#define thOpenSourceH +//--------------------------------------------------------------------------- +#include +//--------------------------------------------------------------------------- +class thOpenFile : public TThread +{ +private: +protected: + void __fastcall Execute(); + void __fastcall RunOpen(); +public: + bool thEnd; + int ColType[10000]; + + __fastcall thOpenFile(bool CreateSuspended); + void LoadAndModify(const char * pszFileName); + void ReadAndModifyFromBuff(char *pBuff, DWORD dwSize, const char* pszFileName); + +}; +//--------------------------------------------------------------------------- +#endif diff --git a/contrib/dbcformat/DBC Store.exe b/contrib/dbcformat/DBC Store.exe new file mode 100755 index 000000000..f0e001495 Binary files /dev/null and b/contrib/dbcformat/DBC Store.exe differ diff --git a/contrib/dbcformat/dbc.desc b/contrib/dbcformat/dbc.desc new file mode 100644 index 000000000..470108cab --- /dev/null +++ b/contrib/dbcformat/dbc.desc @@ -0,0 +1,241 @@ +ENTRY ItemSetEntry + +UNUSED INDEX setid +UNUSED STR setname +UNKNOWN[7] +UNUSED UINT flags//, const +UNUSED UINT required_item_id[8] +UNKNOWN[48] +UINT spells[8] +UINT items_to_triggerspell[8] //items_to_triggerspell[0] -- for spells[0] +UINT required_skill_id//only 2 items sets have requirements +UINT required_skill_value + +ENDENTRY + + +ENTRY TalentEntry + + INDEX TalentID + UINT TalentTree + UNKNOWN [2] + UINT RankID[5] + UNKNOWN[12] + +ENDENTRY + + +ENTRY emoteentry + + INDEX Id + UNUSED STR name + UINT textid + UNUSED UINT textid2 + UNUSED UINT textid3 + UNUSED UINT textid4 + UNKNOWN + UNUSED UINT textid5 + UNKNOWN + UNUSED UINT textid6 + UNKNOWN[9] + +ENDENTRY + +ENTRY SpellEntry + + INDEX Id + UINT School + UNKNOWN [2] + UINT Category + UNKNOWN + UINT Attributes + UINT AttributesEx + UNKNOWN [3] + UINT Targets + UINT TargetCreatureType + UINT RequiresSpellFocus + UNKNOWN + UINT CasterAuraState + UINT CastingTimeIndex + UINT RecoveryTime + UINT CategoryRecoveryTime + UINT InterruptFlags + UINT AuraInterruptFlags + UINT ChannelInterruptFlags + UINT procFlags + UINT procChance + UINT procCharges + UINT maxLevel + UINT baseLevel + UINT spellLevel + UINT DurationIndex + UINT powerType + UINT manaCost + UINT manaCostPerlevel + UINT manaPerSecond + UINT manaPerSecondPerLevel + UINT rangeIndex + FLOAT speed + UINT modalNextSpell + UNKNOWN + UINT Totem[2] + UINT Reagent[8] + UINT ReagentCount[8] + UINT EquippedItemClass + UINT EquippedItemSubClass + UINT Effect[3] // 59 - 61 + UINT EffectDieSides[3] + UINT EffectBaseDice[3] + FLOAT EffectDicePerLevel[3] + FLOAT EffectRealPointsPerLevel[3] + INT EffectBasePoints[3] // 74 - 76 + UNKNOWN [3] + UINT EffectImplicitTargetA[3] // 80 - 82 + UINT EffectImplicitTargetB[3] // 83 - 85 + UINT EffectRadiusIndex[3] + UINT EffectApplyAuraName[3] // 89 - 91 + UINT EffectAmplitude[3] + UINT Effectunknown[3] + UINT EffectChainTarget[3] + UINT EffectItemType[3] + UINT EffectMiscValue[3] // 104 - 106 + UINT EffectTriggerSpell[3] + FLOAT EffectPointsPerComboPoint[3] + UINT SpellVisual + UNKNOWN + UINT SpellIconID + UINT activeIconID + UINT spellPriority + UNUSED STR Name + UNUSED STR NameAlt1 + UNUSED STR NameAlt2 + UNUSED STR NameAlt3 + UNUSED STR NameAlt4 + UNUSED STR NameAlt5 + UNUSED STR NameAlt6 + UNUSED STR NameAlt7 + UNUSED STR NameFlags + UINT Rank + UINT RankAlt1 + UINT RankAlt2 + UINT RankAlt3 + UINT RankAlt4 + UINT RankAlt5 + UINT RankAlt6 + UINT RankAlt7 + UINT RankFlags + UNUSED STR Description + UNUSED STR DescriptionAlt1 + UNUSED STR DescriptionAlt2 + UNUSED STR DescriptionAlt3 + UNUSED STR DescriptionAlt4 + UNUSED STR DescriptionAlt5 + UNUSED STR DescriptionAlt6 + UNUSED STR DescriptionAlt7 + UNUSED UINT DescriptionFlags + UNUSED STR BuffDescription + UNUSED STR BuffDescriptionAlt1 + UNUSED STR BuffDescriptionAlt2 + UNUSED STR BuffDescriptionAlt3 + UNUSED STR BuffDescriptionAlt4 + UNUSED STR BuffDescriptionAlt5 + UNUSED STR BuffDescriptionAlt6 + UNUSED STR BuffDescriptionAlt7 + UINT ManaCostPercentage + UINT StartRecoveryCategory + UINT StartRecoveryTime + UINT field156 //nice name + UNKNOWN[2] + UINT SpellFamilyName + UNKNOWN[11] +ENDENTRY + +ENTRY SpellCastTime + INDEX ID + UINT CastTime + UNKNOWN[2] +ENDENTRY + +ENTRY SpellRadius + INDEX ID + FLOAT Radius + UNKNOWN + FLOAT Radius2 +ENDENTRY + +ENTRY SpellRange + INDEX ID + FLOAT minRange + FLOAT maxRange + UNKNOWN[18] + UNKNOWN//some flag +ENDENTRY + +ENTRY SpellDuration + INDEX ID + UINT Duration1 + UINT Duration2 + UINT Duration3 +ENDENTRY + +ENTRY AreaTableEntry + + UINT ID + UNUSED UINT map + UINT zone + INDEX exploreFlag + UNKNOWN[6] + UINT area_level + UNUSED STR name + UNKNOWN[9] + +ENDENTRY + + +ENTRY FactionEntry + INDEX ID + INT reputationListID + + UNKNOWN[7] + UINT something1 + UINT something2 + UINT something3 + UINT something4 + UINT something5 + UINT something6 + UINT something7 + UINT something8 + UINT something9 + UINT faction + + UNUSED STR name + UNKNOWN[17] + +ENDENTRY + + +ENTRY FactionTemplateEntry + INDEX ID + UINT faction + UNKNOWN + UINT fightsupport + UINT friendly + UINT hostile + UNKNOWN[8] +ENDENTRY + + +ENTRY ItemDisplayTemplateEntry + + UINT ID + UNUSED STR modelFile + UNKNOWN + UNUSED STR imageFile + UNKNOWN + UNUSED STR invImageFile + UNKNOWN[5] + UINT seed + UNKNOWN [10] + UINT randomPropertyID + +ENDENTRY diff --git a/contrib/extractor/Makefile.am b/contrib/extractor/Makefile.am new file mode 100644 index 000000000..b84617069 --- /dev/null +++ b/contrib/extractor/Makefile.am @@ -0,0 +1,10 @@ +# The top-level input Makefile for mpq-tools + +# Any directories which should be built and installed. +SUBDIRS = libmpq + +# The directories which are part of the distribution. +DIST_SUBDIRS = $(SUBDIRS) + +EXTRA_DIST = \ + README.linux diff --git a/contrib/extractor/README.linux b/contrib/extractor/README.linux new file mode 100644 index 000000000..e1ebdb8bb --- /dev/null +++ b/contrib/extractor/README.linux @@ -0,0 +1,13 @@ +Linux instructions +------------------ + +1. Configure and build MaNGOS. +2. cd contrib/map_extractor/libmpq/ +3. make +4. cd .. +5. make +6. run ad + +if there are any problems create folder named .deps in contrib/map_extractor/ +it is old bug from first extractor and i am too lasy to fix it :) + diff --git a/contrib/extractor/System.cpp b/contrib/extractor/System.cpp new file mode 100644 index 000000000..090fc557e --- /dev/null +++ b/contrib/extractor/System.cpp @@ -0,0 +1,320 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#include +#include +#include + +#ifdef WIN32 +#include "direct.h" +#else +#include +#endif + +#include "dbcfile.h" +#include "mpq_libmpq.h" + +extern unsigned int iRes; +extern ArchiveSet gOpenArchives; + +bool ConvertADT(char*,char*); + +typedef struct{ + char name[64]; + unsigned int id; +}map_id; + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; + +map_id * map_ids; +uint16 * areas; +char output_path[128]="."; +char input_path[128]="."; + +enum Extract +{ + EXTRACT_MAP = 1, + EXTRACT_DBC = 2 +}; +int extract = EXTRACT_MAP | EXTRACT_DBC; + +static char* const langs[]={"deDE", "enGB", "enUS", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; +#define LANG_COUNT 12 + +#define ADT_RES 64 + +void CreateDir( const std::string& Path ) +{ + #ifdef WIN32 + _mkdir( Path.c_str()); + #else + mkdir( Path.c_str(), 0777 ); + #endif +} + +bool FileExists( const char* FileName ) +{ + if( FILE* fp = fopen( FileName, "rb" ) ) + { + fclose( fp ); + return true; + } + + return false; +} + +void Usage(char* prg) +{ + printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"", + prg,prg); + exit(1); +} + +void HandleArgs(int argc, char * arg[]) +{ + for(int c=1;c 0 && extract < 4)) + Usage(arg[0]); + } + else + Usage(arg[0]); + break; + } + } +} + +uint32 ReadMapDBC() +{ + printf("Read Map.dbc file... "); + DBCFile dbc("DBFilesClient\\Map.dbc"); + dbc.open(); + + uint32 map_count=dbc.getRecordCount(); + map_ids=new map_id[map_count]; + for(unsigned int x=0;x dbcfiles; + + // get DBC file list + for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i) + { + vector files = (*i)->GetFileList(); + for (vector::iterator iter = files.begin(); iter != files.end(); ++iter) + if (iter->rfind(".dbc") == iter->length() - strlen(".dbc")) + dbcfiles.insert(*iter); + } + + std::string path = output_path; + path += "/dbc/"; + CreateDir(path); + + // extract DBCs + int count = 0; + for (set::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter) + { + string filename = output_path; + filename += "/dbc/"; + filename += (iter->c_str() + strlen("DBFilesClient\\")); + + //cout << filename << endl; + + FILE *output=fopen(filename.c_str(),"wb"); + if(!output) + { + printf("Can't create the output file '%s'\n",filename.c_str()); + continue; + } + MPQFile m(iter->c_str()); + if(!m.isEof()) + fwrite(m.getPointer(),1,m.getSize(),output); + + fclose(output); + ++count; + } + printf("Extracted %u DBC files\n", count); +} + +int GetLocale() +{ + for (int i = 0; i < LANG_COUNT; i++) + { + char tmp1[512]; + sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]); + if (FileExists(tmp1)) + { + printf("Detected locale: %s\n", langs[i]); + return i; + } + } + + printf("Could not detect locale.\n"); + return -1; +} + +void LoadMPQFiles(int const locale) +{ + char filename[512]; + + sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]); + new MPQArchive(filename); + + for(int i = 1; i < 5; ++i) + { + char ext[3] = ""; + if(i > 1) + sprintf(ext, "-%i", i); + + sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext); + if(!FileExists(filename)) + break; + new MPQArchive(filename); + } + + //need those files only if extract maps + if(extract & EXTRACT_MAP) + { + sprintf(filename,"%s/Data/common.MPQ",input_path); + new MPQArchive(filename); + sprintf(filename,"%s/Data/expansion.MPQ",input_path); + new MPQArchive(filename); + + for(int i = 1; i < 5; ++i) + { + char ext[3] = ""; + if(i > 1) + sprintf(ext, "-%i", i); + + sprintf(filename,"%s/Data/patch%s.MPQ",input_path,ext); + if(!FileExists(filename)) + break; + new MPQArchive(filename); + } + } +} + +int main(int argc, char * arg[]) +{ + printf("Map & DBC Extractor\n"); + printf("===================\n"); + + HandleArgs(argc, arg); + + int const locale = GetLocale(); + if(locale < 0) + return 1; + + LoadMPQFiles(locale); + + if(extract & EXTRACT_DBC) + ExtractDBCFiles(); + + if(extract & EXTRACT_MAP) + ExtractMapsFromMpq(); + + //Close MPQs + for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i) + (*i)->close(); + gOpenArchives.clear(); + + return 0; +} diff --git a/contrib/extractor/VC71_AD.sln b/contrib/extractor/VC71_AD.sln new file mode 100644 index 000000000..f914661b1 --- /dev/null +++ b/contrib/extractor/VC71_AD.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ad", "VC71_ad.vcproj", "{D7552D4F-408F-4F8E-859B-366659150CF4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.Build.0 = Debug|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.ActiveCfg = Release|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/extractor/VC71_ad.vcproj b/contrib/extractor/VC71_ad.vcproj new file mode 100644 index 000000000..b11541382 --- /dev/null +++ b/contrib/extractor/VC71_ad.vcproj @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/extractor/VC80_AD.sln b/contrib/extractor/VC80_AD.sln new file mode 100644 index 000000000..1c46986e8 --- /dev/null +++ b/contrib/extractor/VC80_AD.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ad", "VC80_ad.vcproj", "{D7552D4F-408F-4F8E-859B-366659150CF4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.Build.0 = Debug|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.ActiveCfg = Release|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/extractor/VC80_ad.vcproj b/contrib/extractor/VC80_ad.vcproj new file mode 100644 index 000000000..ddf423c4b --- /dev/null +++ b/contrib/extractor/VC80_ad.vcproj @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/extractor/VC90_AD.sln b/contrib/extractor/VC90_AD.sln new file mode 100644 index 000000000..68dd66e1f --- /dev/null +++ b/contrib/extractor/VC90_AD.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ad", "VC90_ad.vcproj", "{D7552D4F-408F-4F8E-859B-366659150CF4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.Build.0 = Debug|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.ActiveCfg = Release|Win32 + {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/extractor/VC90_ad.vcproj b/contrib/extractor/VC90_ad.vcproj new file mode 100644 index 000000000..148c33643 --- /dev/null +++ b/contrib/extractor/VC90_ad.vcproj @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/extractor/ad b/contrib/extractor/ad new file mode 100755 index 000000000..564eceaaa Binary files /dev/null and b/contrib/extractor/ad differ diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe new file mode 100755 index 000000000..e9606e8e0 Binary files /dev/null and b/contrib/extractor/ad.exe differ diff --git a/contrib/extractor/adt.cpp b/contrib/extractor/adt.cpp new file mode 100644 index 000000000..c6cb5dba0 --- /dev/null +++ b/contrib/extractor/adt.cpp @@ -0,0 +1,500 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#ifdef WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "adt.h" +#include "mpq_libmpq.h" + +//#include +unsigned int iRes=256; +extern uint16*areas; + +vec wmoc; + +Cell * cell; +uint32 wmo_count; +mcell *mcells; + +int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; +int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; + +bool LoadADT(char* filename) +{ + size_t size; + MPQFile mf(filename); + + if(mf.isEof()) + { + //printf("No such file.\n"); + return false; + } + mcells=new mcell; + + wmoc.x =65*TILESIZE; + wmoc.z =65*TILESIZE; + + size_t mcnk_offsets[256], mcnk_sizes[256]; + + wmo_count=0; + bool found=false; + //uint32 fs=mf.getSize()-3; + //while (mf.getPos()ch[i][j])); + } + + /* + for(uint32 t=0;t3) testi = 3; + if(testj>3) testj = 3; + return (holes & holetab_h[testi] & holetab_v[testj])!=0; +} + +inline +void LoadMapChunk(MPQFile & mf, chunk*_chunk) +{ + float h; + uint32 fourcc; + uint32 size; + MapChunkHeader header; + + mf.seekRelative(4); + mf.read(&size, 4); + + size_t lastpos = mf.getPos() + size; + mf.read(&header, 0x80); + _chunk->area_id =header.areaid ; + _chunk->flag =0; + + float xbase = header.xpos; + float ybase = header.ypos; + float zbase = header.zpos; + zbase = TILESIZE*32-zbase; + xbase = TILESIZE*32-xbase; + if(wmoc.x >xbase)wmoc.x =xbase; + if(wmoc.z >zbase)wmoc.z =zbase; + int chunkflags = header.flags; + float zmin=999999999.0f; + float zmax=-999999999.0f; + //must be there, bl!zz uses some crazy format + int nTextures; + while (mf.getPos() < lastpos) + { + mf.read(&fourcc,4); + mf.read(&size, 4); + //if(size!=580) + // printf("\n sz=%d",size); + size_t nextpos = mf.getPos() + size; + if(fourcc==0x4d435654) // MCVT + { + for (int j=0; j<17; j++) + for (int i=0; i<((j%2)?8:9); i++) + { + mf.read(&h,4); + float z=h+ybase; + if (j%2) + { + if(isHole(header.holes,i,j)) + _chunk->v8[i][j/2] = -1000; + else + _chunk->v8[i][j/2] = z; + } + else + { + if(isHole(header.holes,i,j)) + _chunk->v9[i][j/2] = -1000; + else + _chunk->v9[i][j/2] = z; + } + + if(z>zmax)zmax=z; + //if(zwaterlevel[i][j]=-999999; // no liquid/water + } + else + { + float maxheight; + mf.read(&maxheight, 4); + + for(int j=0;j<9;j++) + for(int i=0;i<9;i++) + { + mf.read(&h, 4); + mf.read(&h, 4); + if(h > maxheight) + _chunk->waterlevel[i][j]=-999999; + else + _chunk->waterlevel[i][j]=h; + } + + if(chunkflags & 4 || chunkflags & 8) + _chunk->flag |=1; + if(chunkflags & 16) + _chunk->flag |=2; + } + break; + } + else if (fourcc==0x4d434c59) // MCLY + { + // texture info + nTextures = (int)size; + } + else if (fourcc==0x4d43414c) // MCAL + { + if (nTextures<=0) + continue; + } + + mf.seek(nextpos); + } +} + +double solve (vec *v,vec *p) +{ + double a = v[0].y *(v[1].z - v[2].z) + v[1].y *(v[2].z - v[0].z) + v[2].y *(v[0].z - v[1].z); + double b = v[0].z *(v[1].x - v[2].x) + v[1].z *(v[2].x - v[0].x) + v[2].z *(v[0].x - v[1].x); + double c = v[0].x *(v[1].y - v[2].y) + v[1].x *(v[2].y - v[0].y) + v[2].x *(v[0].y - v[1].y); + double d = v[0].x *(v[1].y*v[2].z - v[2].y*v[1].z) + v[1].x* (v[2].y*v[0].z - v[0].y*v[2].z) + v[2].x* (v[0].y*v[1].z - v[1].y*v[0].z); + //-d + + //plane equation ax+by+cz+d=0 + return ((a*p->x+c*p->z-d)/b); +} + +inline +double GetZ(double x,double z) +{ + vec v[3]; + vec p; + + //bool inWMO=false; + + //if(!inWMO) + { + //find out quadrant + int xc=(int)(x/UNITSIZE); + int zc=(int)(z/UNITSIZE); + if(xc>127)xc=127; + if(zc>127)zc=127; + + double lx=x-xc*UNITSIZE; + double lz=z-zc*UNITSIZE; + p.x=lx; + p.z=lz; + + v[0].x=UNITSIZE/2; + v[0].y =cell->v8[xc][zc]; + v[0].z=UNITSIZE/2; + + if(lx>lz) + { + v[1].x=UNITSIZE; + v[1].y =cell->v9[xc+1][zc]; + v[1].z=0; + } + else + { + v[1].x=0.0; + v[1].y =cell->v9[xc][zc+1]; + v[1].z=UNITSIZE; + } + + if(lz>UNITSIZE-lx) + { + v[2].x=UNITSIZE; + v[2].y =cell->v9[xc+1][zc+1]; + v[2].z=UNITSIZE; + } + else + { + v[2].x=0; + v[2].y=cell->v9[xc][zc]; + v[2].z=0; + } + + return -solve(v,&p); + } +} + +inline +void TransformWaterData() +{ + cell= new Cell; + + for(int x=0;x<128;x++) + for(int y=0;y<128;y++) + cell->v9[x][y] = mcells->ch[x/8][y/8].waterlevel[x%8][y%8]; + + //and the last 1 + cell->v9[128][128] = mcells->ch[15][15].waterlevel[8][8]; +} + +inline +void TransformData() +{ + cell= new Cell; + + for(int x=0;x<128;x++) + { + for(int y=0;y<128;y++) + { + cell->v8[x][y] = (float)mcells->ch[x/8][y/8].v8[x%8][y%8]; + cell->v9[x][y] = (float)mcells->ch[x/8][y/8].v9[x%8][y%8]; + } + + //extra 1 point on bounds + cell->v9[x][128] = (float)mcells->ch[x/8][15].v9[x%8][8]; + //x==y + cell->v9[128][x] = (float)mcells->ch[15][x/8].v9[8][x%8]; + + } + + //and the last 1 + cell->v9[128][128] = (float)mcells->ch[15][15].v9[8][8]; + + delete mcells; +} + +const char MAP_MAGIC[] = "MAP_2.00"; + +bool ConvertADT(char * filename,char * filename2) +{ + //if(!strstr(filename,"oth_32_48"))return false; + if(!LoadADT(filename)) + return false; + + FILE *output=fopen(filename2,"wb"); + if(!output) + { + printf("Can't create the output file '%s'\n",filename2); + return false; + } + + // write magic header + fwrite(MAP_MAGIC,1,8,output); + + for(unsigned int x=0;x<16;x++) + { + for(unsigned int y=0;y<16;y++) + { + if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id < 0x102D) + { + if(areas[mcells->ch[y][x].area_id]==0xffff) + printf("\nCan't find area flag for areaid %u.\n",mcells->ch[y][x].area_id); + + fwrite(&areas[mcells->ch[y][x].area_id],1,2,output); + } + else + { + uint16 flag=0xffff; + fwrite(&flag,1,2,output); + } + } + } + + for(unsigned int x=0;x<16;x++) + for(unsigned int y=0;y<16;y++) + fwrite(&mcells->ch[y][x].flag,1,1,output); + + TransformWaterData(); + + for(unsigned int x=0;x<128;x++) + for(unsigned int y=0;y<128;y++) + fwrite(&cell->v9[y][x],1,sizeof(float),output); + + delete cell; + TransformData(); + + for(unsigned int x=0;x::iterator it = wmos.begin(); it != wmos.end(); ++it) + wmomanager.delbyname(*it); + + wmos.clear(); + wmois.clear(); + + for (std::vector::iterator it = wmomodel.begin(); it != wmomodel.end(); ++it) + { + it->tr.clear(); + + } + //printf("\n %d \n",in); + wmomodel.clear(); + //polygons.clear();*/ + return true; +} diff --git a/contrib/extractor/adt.h b/contrib/extractor/adt.h new file mode 100644 index 000000000..bae687f6b --- /dev/null +++ b/contrib/extractor/adt.h @@ -0,0 +1,53 @@ +#ifndef ADT_H +#define ADT_H + +#define TILESIZE (533.33333f) +#define CHUNKSIZE ((TILESIZE) / 16.0f) +#define UNITSIZE (CHUNKSIZE / 8.0f) + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +class Liquid; +typedef struct { +float x; +float y; +float z; +}svec; + +typedef struct { +double x; +double y; +double z; +}vec; + +typedef struct{ + vec v[3]; +}triangle; + +typedef struct{ +float v9[16*8+1][16*8+1]; +float v8[16*8][16*8]; +}Cell; + +typedef struct{ +double v9[9][9]; +double v8[8][8]; +uint16 area_id; +//Liquid *lq; +float waterlevel[9][9]; +uint8 flag; +}chunk; + +class WMO; +class WMOManager; +void fixname(std::string &name); + +typedef struct +{ +chunk ch[16][16]; +}mcell; +class MPQFile; +void LoadMapChunk(MPQFile &,chunk*); +bool LoadWMO(char* filename); +#endif diff --git a/contrib/extractor/dbcfile.cpp b/contrib/extractor/dbcfile.cpp new file mode 100644 index 000000000..acfb35482 --- /dev/null +++ b/contrib/extractor/dbcfile.cpp @@ -0,0 +1,69 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#include "dbcfile.h" +#include "mpq_libmpq.h" + +DBCFile::DBCFile(const std::string &filename): + filename(filename), + data(0) +{ + +} +void DBCFile::open() +{ + MPQFile f(filename.c_str()); + char header[4]; + unsigned int na,nb,es,ss; + + f.read(header,4); // Number of records + assert(header[0]=='W' && header[1]=='D' && header[2]=='B' && header[3] == 'C'); + f.read(&na,4); // Number of records + f.read(&nb,4); // Number of fields + f.read(&es,4); // Size of a record + f.read(&ss,4); // String size + + recordSize = es; + recordCount = na; + fieldCount = nb; + stringSize = ss; + assert(fieldCount*4 == recordSize); + + data = new unsigned char[recordSize*recordCount+stringSize]; + stringTable = data + recordSize*recordCount; + f.read(data,recordSize*recordCount+stringSize); + f.close(); +} +DBCFile::~DBCFile() +{ + delete [] data; +} + +DBCFile::Record DBCFile::getRecord(size_t id) +{ + assert(data); + return Record(*this, data + id*recordSize); +} + +size_t DBCFile::getMaxId() +{ + assert(data); + + size_t maxId = 0; + for(size_t i = 0; i < getRecordCount(); ++i) + { + if(maxId < getRecord(i).getUInt(0)) + maxId = getRecord(i).getUInt(0); + } + return maxId; +} + +DBCFile::Iterator DBCFile::begin() +{ + assert(data); + return Iterator(*this, data); +} +DBCFile::Iterator DBCFile::end() +{ + assert(data); + return Iterator(*this, stringTable); +} diff --git a/contrib/extractor/dbcfile.h b/contrib/extractor/dbcfile.h new file mode 100644 index 000000000..521ca6742 --- /dev/null +++ b/contrib/extractor/dbcfile.h @@ -0,0 +1,118 @@ +#ifndef DBCFILE_H +#define DBCFILE_H +#include +#include + +class DBCFile +{ +public: + DBCFile(const std::string &filename); + ~DBCFile(); + + // Open database. It must be openened before it can be used. + void open(); + + // Database exceptions + class Exception + { + public: + Exception(const std::string &message): message(message) + { } + virtual ~Exception() + { } + const std::string &getMessage() {return message;} + private: + std::string message; + }; + class NotFound: public Exception + { + public: + NotFound(): Exception("Key was not found") + { } + }; + // Iteration over database + class Iterator; + class Record + { + public: + float getFloat(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+field*4); + } + unsigned int getUInt(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+field*4); + } + int getInt(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+field*4); + } + const char *getString(size_t field) const + { + assert(field < file.fieldCount); + size_t stringOffset = getUInt(field); + assert(stringOffset < file.stringSize); + return reinterpret_cast(file.stringTable + stringOffset); + } + private: + Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} + unsigned char *offset; + DBCFile &file; + + friend class DBCFile; + friend class DBCFile::Iterator; + }; + /** Iterator that iterates over records + */ + class Iterator + { + public: + Iterator(DBCFile &file, unsigned char *offset): + record(file, offset) {} + /// Advance (prefix only) + Iterator & operator++() { + record.offset += record.file.recordSize; + return *this; + } + /// Return address of current instance + Record const & operator*() const { return record; } + const Record* operator->() const { + return &record; + } + /// Comparison + bool operator==(const Iterator &b) const + { + return record.offset == b.record.offset; + } + bool operator!=(const Iterator &b) const + { + return record.offset != b.record.offset; + } + private: + Record record; + }; + + // Get record by id + Record getRecord(size_t id); + /// Get begin iterator over records + Iterator begin(); + /// Get begin iterator over records + Iterator end(); + /// Trivial + size_t getRecordCount() const { return recordCount;} + size_t getFieldCount() const { return fieldCount; } + size_t getMaxId(); +private: + std::string filename; + size_t recordSize; + size_t recordCount; + size_t fieldCount; + size_t stringSize; + unsigned char *data; + unsigned char *stringTable; +}; + +#endif diff --git a/contrib/extractor/debug/zlib.lib b/contrib/extractor/debug/zlib.lib new file mode 100644 index 000000000..ffd7d9a26 Binary files /dev/null and b/contrib/extractor/debug/zlib.lib differ diff --git a/contrib/extractor/libmpq/Makefile.am b/contrib/extractor/libmpq/Makefile.am new file mode 100644 index 000000000..192bd1369 --- /dev/null +++ b/contrib/extractor/libmpq/Makefile.am @@ -0,0 +1,23 @@ +# The input Makefile for the main mpq-tools + +lib_LTLIBRARIES = libmpq.la +noinst_HEADERS = explode.h huffman.h wave.h common.h + +# The directory where the include files will be installed. +libmpq_includedir = $(includedir)/libmpq + +# Which header files to install. +libmpq_include_HEADERS = mpq.h + +libmpq_la_SOURCES = $(GENERAL_SRCS) +libmpq_la_LDFLAGS = -release $(LIBMPQ_VERSION) +libmpq_la_LIBADD = @Z_LIBS@ + +GENERAL_SRCS = \ + common.c \ + huffman.c \ + extract.c \ + explode.c \ + mpq.c \ + parser.c \ + wave.c diff --git a/contrib/extractor/libmpq/common.cpp b/contrib/extractor/libmpq/common.cpp new file mode 100644 index 000000000..7b9020875 --- /dev/null +++ b/contrib/extractor/libmpq/common.cpp @@ -0,0 +1,801 @@ +/* + * common.c -- shared functions used by mpq-tools. + * + * Copyright (C) 2003 Maik Broemme + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: common.c,v 1.12 2004/02/12 00:42:54 mbroemme Exp $ + */ +#define _CRT_SECURE_NO_DEPRECATE +//#include +#include +//#include +#include +#include +#include +#include "mpq.h" +#include "common.h" +#include + +/* + * This function decrypts a MPQ block. + */ +int libmpq_decrypt_block(mpq_archive *mpq_a, unsigned int *block, unsigned int length, unsigned int seed1) { + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; + + /* Round to unsigned int's */ + length >>= 2; + while (length-- > 0) { + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = *block ^ (seed1 + seed2); + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + *block++ = ch; + } + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function decrypts the hashtable for the + * file informations. + */ +int libmpq_decrypt_hashtable(mpq_archive *mpq_a, unsigned char *pbKey) { + unsigned int seed1 = 0x7FED7FED; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; /* One key character */ + unsigned int *pdwTable = (unsigned int *)(mpq_a->hashtable); + unsigned int length = mpq_a->header->hashtablesize * 4; + + /* Prepare seeds */ + while (*pbKey != 0) { + ch = toupper(*pbKey++); + seed1 = mpq_a->buf[0x300 + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + + /* Decrypt it */ + seed2 = 0xEEEEEEEE; + while (length-- > 0) { + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = *pdwTable ^ (seed1 + seed2); + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + *pdwTable++ = ch; + } + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function decrypts the blocktable. + */ +int libmpq_decrypt_blocktable(mpq_archive *mpq_a, unsigned char *pbKey) { + unsigned int seed1 = 0x7FED7FED; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; /* One key character */ + unsigned int *pdwTable = (unsigned int *)(mpq_a->blocktable); + unsigned int length = mpq_a->header->blocktablesize * 4; + + /* Prepare seeds */ + while(*pbKey != 0) { + ch = toupper(*pbKey++); + seed1 = mpq_a->buf[0x300 + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + + /* Decrypt it */ + seed2 = 0xEEEEEEEE; + while(length-- > 0) { + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = *pdwTable ^ (seed1 + seed2); + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + *pdwTable++ = ch; + } + return LIBMPQ_TOOLS_SUCCESS; +} + +int libmpq_read_listfile(mpq_archive *mpq_a, FILE *fp) { + int mpq_size; + int mpq_ht_size; + int mpq_bt_size; + int mpq_blocksize; + int mpq_files; + int mpq_csize; + int mpq_fsize; + int entries; + char listdb_version[10]; + char libmpq_version[10]; + int listdb_temp_version = 0; + int libmpq_temp_version = 0; + + /* first check header and version */ + if (libmpq_conf_get_value(fp, "LIBMPQ_VERSION", mpq_a->mpq_l->mpq_version, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_version))) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } else { + + /* copy to temp buffer for removing . characters */ + sprintf(listdb_version, (char *)mpq_a->mpq_l->mpq_version); + + /* remove . characters from listfile version */ + libmpq_conf_delete_char(listdb_version, "."); + + /* get libmpq version */ + sprintf(libmpq_version, "%i%i%i",LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION); + + /* convert to number */ + listdb_temp_version = atoi(listdb_version); + libmpq_temp_version = atoi(libmpq_version); + + /* check if installed libmpq version is valid for listfile version */ + if ((libmpq_temp_version < listdb_temp_version) || (libmpq_temp_version == 0) || (listdb_temp_version == 0)) { + return LIBMPQ_CONF_EFILE_VERSION; + } + } + + /* check listfile header, the following entries must be set */ + if (libmpq_conf_get_value(fp, "MPQ_SIZE", &mpq_size, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_HASHTABLE_SIZE", &mpq_ht_size, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_BLOCKTABLE_SIZE", &mpq_bt_size, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_BLOCKSIZE", &mpq_blocksize, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_FILES", &mpq_files, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_COMPRESSED_SIZE", &mpq_csize, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_UNCOMPRESSED_SIZE", &mpq_fsize, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_NAME", mpq_a->mpq_l->mpq_name, LIBMPQ_CONF_TYPE_CHAR, PATH_MAX)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_TYPE", mpq_a->mpq_l->mpq_type, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_type))) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + + /* these are optional parameters, if they are empty we set the struct members empty */ + libmpq_conf_get_value(fp, "MPQ_GAME", mpq_a->mpq_l->mpq_game, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_game)); + libmpq_conf_get_value(fp, "MPQ_GAME_VERSION", mpq_a->mpq_l->mpq_game_version, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_game_version)); + + /* check if we found a valid listfile for the given archive */ + if (mpq_a->header->hashtablesize == mpq_ht_size && mpq_a->header->blocktablesize == mpq_bt_size && mpq_a->blocksize == mpq_blocksize && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_ARCHIVE_SIZE) == mpq_size && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) == mpq_files && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_COMPRESSED_SIZE) == mpq_csize && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_UNCOMPRESSED_SIZE) == mpq_fsize) { + + /* check if the filelist is correct */ + if (!libmpq_conf_get_array(fp, "FILE_NAMES", (char ***)&mpq_a->mpq_l->mpq_files, &entries)) { + + /* we have a corrupt filelist, so return */ + return LIBMPQ_CONF_EFILE_LIST_CORRUPT; + } else { + + /* now check if filelist entries matches number of files in the archive. */ + if (entries != libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES)) { + libmpq_free_listfile((char **)mpq_a->mpq_l->mpq_files); + mpq_a->mpq_l->mpq_files = NULL; + return LIBMPQ_CONF_EFILE_LIST_CORRUPT; + } + } + } + + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function frees up the space reserved by libmpq_get_listfile() + */ +int libmpq_free_listfile(char **filelist) { + int i = 0; + while (filelist[i]) { + free(filelist[i++]); + } + free(filelist); + + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function reads the directory and the subdirectories + * of the listfile database and adds a entry to the lisfile + * array. + */ +/*int libmpq_detect_listfile_rec(char path[PATH_MAX], char ***filelist, int *fl_count, int *fl_size) { + char nextpath[PATH_MAX]; + DIR *dp = opendir(path); + FILE *fp; + struct dirent *entry; + struct stat statbuf; + char buf[LIBMPQ_CONF_BUFSIZE]; + + if (dp == NULL) { + return LIBMPQ_CONF_EOPEN_DIR; + } else { + while ((entry = readdir(dp)) != NULL) { + if (strncmp(entry->d_name, ".", 1) == 0 || strncmp(entry->d_name, "..", 2) == 0) { + continue; + } + if (strnlen(path, PATH_MAX) + strnlen(entry->d_name, PATH_MAX) + 2 > sizeof nextpath) { + continue; + } + + snprintf(nextpath, PATH_MAX, "%s/%s", path, entry->d_name); + + // check if file extension matches listdb file extension + if (strncmp(&entry->d_name[strlen(entry->d_name) - strlen(LIBMPQ_CONF_EXT)], LIBMPQ_CONF_EXT, strlen(LIBMPQ_CONF_EXT)) == 0) { + + // check if it is really a listdb file + if ((fp = fopen(nextpath, "r")) != NULL ) { + while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { + char *line; + + buf[strlen(buf) - 1] = '\0'; + + // skip whitespace + for (line = buf; isspace(*line); line++) { + continue; + } + + // skip empty line + if (line[0] == '\0') { + continue; + } + + // skip comments + if (line[0] == '#') { + continue; + } + + //search for listdb header; dirty but works :) + if (!strncasecmp(line, LIBMPQ_CONF_HEADER, strlen(LIBMPQ_CONF_HEADER))) { + + // set the next filelist entry to a copy of the file path + (*filelist)[(*fl_count)++] = strdup(nextpath); + + // increase the array size + if ((*fl_count) == (*fl_size)) { + (*filelist) = realloc((*filelist), ((*fl_size) + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); + (*fl_size) += LIBMPQ_CONF_FL_INCREMENT; + } + + // header found so we could stop reading the file. + break; + } + } + fclose(fp); + } + } + + if (stat(nextpath, &statbuf) < 0) { + continue; + } + + // if entry ia a subdirectory, read it + if (S_ISDIR(statbuf.st_mode)) { + libmpq_detect_listfile_rec(nextpath, filelist, fl_count, fl_size); + } + } + closedir(dp); + } + + return LIBMPQ_TOOLS_SUCCESS; +} +*/ + +/* + * This functions tries to get file decryption key. The trick comes from block + * positions which are stored at the begin of each compressed file. We know the + * file size, that means we know number of blocks that means we know the first + * int value in block position. And if we know encrypted and decrypted value, + * we can find the decryption key. + */ +int libmpq_detect_fileseed(mpq_archive *mpq_a, unsigned int *block, unsigned int decrypted) { + unsigned int saveseed1; + unsigned int temp = *block ^ decrypted; /* temp = seed1 + seed2 */ + int i = 0; + temp -= 0xEEEEEEEE; /* temp = seed1 + mpq_a->buf[0x400 + (seed1 & 0xFF)] */ + + for (i = 0; i < 0x100; i++) { /* Try all 255 possibilities */ + unsigned int seed1; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; + + /* Try the first unsigned int's (We exactly know the value) */ + seed1 = temp - mpq_a->buf[0x400 + i]; + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = block[0] ^ (seed1 + seed2); + + if (ch != decrypted) { + continue; + } + + /* Add 1 because we are decrypting block positions */ + saveseed1 = seed1 + 1; + + /* + * If OK, continue and test the second value. We don't know exactly the value, + * but we know that the second one has lower 16 bits set to zero + * (no compressed block is larger than 0xFFFF bytes) + */ + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = block[1] ^ (seed1 + seed2); + if ((ch & 0xFFFF0000) == 0) { + return saveseed1; + } + } + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function initialize the decryption buffer + */ +int libmpq_init_buffer(mpq_archive *mpq_a) { + unsigned int seed = 0x00100001; + unsigned int index1 = 0; + unsigned int index2 = 0; + int i; + + memset(mpq_a->buf, 0, sizeof(mpq_a->buf)); + + /* Initialize the decryption buffer. */ + for (index1 = 0; index1 < 0x100; index1++) { + for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100) { + unsigned int temp1, temp2; + seed = (seed * 125 + 3) % 0x2AAAAB; + temp1 = (seed & 0xFFFF) << 0x10; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp2 = (seed & 0xFFFF); + + mpq_a->buf[index2] = (temp1 | temp2); + } + } + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This functions fills the mpq_hash structure with the + * hashtable found in the MPQ file. The hashtable will + * be decrypted for later use. + */ +int libmpq_read_hashtable(mpq_archive *mpq_a) { + unsigned int bytes = 0; + int rb = 0; + + /* + * Allocate memory. Note that the block table should be as large as the + * hash table. (for later file additions) + */ + mpq_a->hashtable = (mpq_hash *)malloc(sizeof(mpq_hash) * mpq_a->header->hashtablesize); + + if (!mpq_a->hashtable) { + return LIBMPQ_EALLOCMEM; + } + + /* Read the hash table into the buffer */ + bytes = mpq_a->header->hashtablesize * sizeof(mpq_hash); + + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_a->header->hashtablepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_a->header->hashtablepos, SEEK_SET); + #endif + + rb = _read(mpq_a->fd, mpq_a->hashtable, bytes); + if (rb != bytes) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* Decrypt hash table and check if it is correctly decrypted */ + mpq_hash *mpq_h_end = mpq_a->hashtable + mpq_a->header->hashtablesize; + mpq_hash *mpq_h = NULL; + + libmpq_decrypt_hashtable(mpq_a, (unsigned char *)"(hash table)"); + + /* Check hash table if is correctly decrypted */ + for (mpq_h = mpq_a->hashtable; mpq_h < mpq_h_end; mpq_h++) { + if (mpq_h->locale != 0xFFFFFFFF && (mpq_h->locale & 0xFFFF0000) != 0) { + return LIBMPQ_EFILE_FORMAT; + } + + /* Remember the highest block table entry */ + if (mpq_h->blockindex < LIBMPQ_HASH_ENTRY_DELETED && mpq_h->blockindex > 0) { + mpq_a->maxblockindex = mpq_h->blockindex; + } + } + + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This functions fills the mpq_block structure with the + * blocktable found in the MPQ file. The blocktable will + * be decrypted for later use. + * + * NOTICE: Some MPQs have decrypted block table, e.g. + * cracked Diablo versions. + */ +int libmpq_read_blocktable(mpq_archive *mpq_a) { + unsigned int bytes = 0; + int rb = 0; + + /* + * Allocate memory. Note that the block table should be as large as the + * hash table. (for later file additions) + */ + mpq_a->blocktable = (mpq_block *)malloc(sizeof(mpq_block) * mpq_a->header->hashtablesize); + mpq_a->blockbuf = (unsigned char *)malloc(mpq_a->blocksize); + + if (!mpq_a->blocktable || !mpq_a->blockbuf) { + return LIBMPQ_EALLOCMEM; + } + + /* Read the block table into the buffer */ + bytes = mpq_a->header->blocktablesize * sizeof(mpq_block); + memset(mpq_a->blocktable, 0, mpq_a->header->blocktablesize * sizeof(mpq_block)); + + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_a->header->blocktablepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_a->header->blocktablepos, SEEK_SET); + #endif + + rb = _read(mpq_a->fd, mpq_a->blocktable, bytes); + if (rb != bytes) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* + * Decrypt block table. Some MPQs don't have encrypted block table, + * e.g. cracked Diablo version. We have to check if block table is + * already decrypted + */ + mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->maxblockindex + 1; + mpq_block *mpq_b = NULL; + unsigned int archivesize = mpq_a->header->archivesize + mpq_a->mpqpos; + + if (mpq_a->header->offset != mpq_a->blocktable->filepos) { + libmpq_decrypt_blocktable(mpq_a, (unsigned char *)"(block table)"); + } + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + if (mpq_b->filepos > archivesize || mpq_b->csize > archivesize) { + if ((mpq_a->flags & LIBMPQ_FLAG_PROTECTED) == 0) { + return LIBMPQ_EFILE_FORMAT; + } + } + mpq_b->filepos += mpq_a->mpqpos; + } + + return LIBMPQ_TOOLS_SUCCESS; +} + +int libmpq_file_read_block(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int blockpos, char *buffer, unsigned int blockbytes) { + unsigned char *tempbuf = NULL; /* Buffer for reading compressed data from the file */ + unsigned int readpos; /* Reading position from the file */ + unsigned int toread = 0; /* Number of bytes to read */ + unsigned int blocknum; /* Block number (needed for decrypt) */ + unsigned int bytesread = 0; /* Total number of bytes read */ + unsigned int nblocks; /* Number of blocks to load */ + unsigned int i; + + /* Test parameters. Block position and block size must be block-aligned, block size nonzero */ + if ((blockpos & (mpq_a->blocksize - 1)) || blockbytes == 0) { + return 0; + } + + /* Check the end of file */ + if ((blockpos + blockbytes) > mpq_f->mpq_b->fsize) { + blockbytes = mpq_f->mpq_b->fsize - blockpos; + } + blocknum = blockpos / mpq_a->blocksize; + nblocks = blockbytes / mpq_a->blocksize; + if (blockbytes % mpq_a->blocksize) { + nblocks++; + } + + /* If file has variable block positions, we have to load them */ + if ((mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) && mpq_f->blockposloaded == FALSE) { + unsigned int nread; + + if (mpq_f->mpq_b->filepos != mpq_a->filepos) { + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + + #endif + } + + /* Read block positions from begin of file. */ + nread = (mpq_f->nblocks + 1) * sizeof(int); + nread = _read(mpq_a->fd, mpq_f->blockpos, nread); + + /* + * If the archive is protected some way, perform additional check + * Sometimes, the file appears not to be encrypted, but it is. + */ + /*if (mpq_f->blockpos[0] != nread) { + mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED; + }*/ + + if ((mpq_f->mpq_b->flags & LIBMPQ_FILE_HAS_METADATA) == 0) { + if (mpq_f->blockpos[0] != nread) { + mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED; + } + } + + /* Decrypt loaded block positions if necessary */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) { + + /* If we don't know the file seed, try to find it. */ + if (mpq_f->seed == 0) { + mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread); + } + + /* If we don't know the file seed, sorry but we cannot extract the file. */ + if (mpq_f->seed == 0) { + return 0; + } + + /* Decrypt block positions */ + libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1); + + /* + * Check if the block positions are correctly decrypted + * I don't know why, but sometimes it will result invalid + * block positions on some files. + */ + if (mpq_f->blockpos[0] != nread) { + + /* Try once again to detect file seed and decrypt the blocks */ + + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + #endif + + nread = _read(mpq_a->fd, mpq_f->blockpos, (mpq_f->nblocks + 1) * sizeof(int)); + mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread); + libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1); + + /* Check if the block positions are correctly decrypted. */ + if (mpq_f->blockpos[0] != nread) { + return 0; + } + } + } + + /* Update mpq_f's variables */ + mpq_f->blockposloaded = TRUE; + mpq_a->filepos = mpq_f->mpq_b->filepos + nread; + } + + /* Get file position and number of bytes to read */ + readpos = blockpos; + toread = blockbytes; + + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + readpos = mpq_f->blockpos[blocknum]; + toread = mpq_f->blockpos[blocknum + nblocks] - readpos; + } + + readpos += mpq_f->mpq_b->filepos; + + /* Get work buffer for store read data */ + if ((tempbuf = (unsigned char *)malloc(toread)) == NULL) { + /* Hmmm... We should add a better error handling here :) */ + return 0; + } + + /* Set file pointer, if necessary. */ + if (mpq_a->filepos != readpos) { + + #ifdef WIN32 + mpq_a->filepos = _lseeki64(mpq_a->fd, readpos, SEEK_SET); + #else + mpq_a->filepos = lseek64(mpq_a->fd, readpos, SEEK_SET); + #endif + + } + + /* 15018F87 - Read all requested blocks. */ + bytesread = _read(mpq_a->fd, tempbuf, toread); + mpq_a->filepos = readpos + bytesread; + + /* Block processing part. */ + unsigned int blockstart = 0; /* Index of block start in work buffer. */ + unsigned int blocksize = min(blockbytes, mpq_a->blocksize); + unsigned int index = blocknum; /* Current block index. */ + bytesread = 0; /* Clear read byte counter */ + + /* Walk through all blocks. */ + for (i = 0; i < nblocks; i++, index++) { + int outlength = mpq_a->blocksize; + + /* Get current block length */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + blocksize = mpq_f->blockpos[index + 1] - mpq_f->blockpos[index]; + } + + /* If block is encrypted, we have to decrypt it. */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) { + if (mpq_f->seed == 0) { + return 0; + } + libmpq_decrypt_block(mpq_a, (unsigned int *)&tempbuf[blockstart], blocksize, mpq_f->seed + index); + } + + /* + * If the block is really compressed, recompress it. + * WARNING: Some block may not be compressed, it can + * only be determined by comparing uncompressed and + * compressed size! + */ + if (blocksize < blockbytes) { + + /* Is the file compressed with PKWARE Data Compression Library? */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) { + libmpq_pkzip_decompress(buffer, &outlength, (char *)&tempbuf[blockstart], blocksize); + } + + /* + * Is it a file compressed by Blizzard's multiple compression ? + * Note that Storm.dll v 1.0.9 distributed with Warcraft III + * passes the full path name of the opened archive as the new + * last parameter. + */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) { + libmpq_multi_decompress(buffer, &outlength, (char *)&tempbuf[blockstart], blocksize); + } + bytesread += outlength; + buffer += outlength; + } else { + memcpy(buffer, tempbuf, blocksize); + bytesread += blocksize; + buffer += blocksize; + } + blockstart += blocksize; + } + + /* Delete input buffer, if necessary. */ + free(tempbuf); + + return bytesread; +} + +int libmpq_file_read_file(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int filepos, char *buffer, unsigned int toread) { + unsigned int bytesread = 0; /* Number of bytes read from the file */ + unsigned int blockpos; /* Position in the file aligned to the whole blocks */ + unsigned int loaded = 0; + + /* File position is greater or equal to file size? */ + if (filepos >= mpq_f->mpq_b->fsize) { + return 0; + } + + /* If to few bytes in the file remaining, cut them */ + if ((mpq_f->mpq_b->fsize - filepos) < toread) { + toread = (mpq_f->mpq_b->fsize - filepos); + } + + /* Block position in the file */ + blockpos = filepos & ~(mpq_a->blocksize - 1); + + /* + * Load the first block, if noncomplete. It may be loaded in the cache buffer. + * We have to check if this block is loaded. If not, load it. + */ + if ((filepos % mpq_a->blocksize) != 0) { + /* Number of bytes remaining in the buffer */ + unsigned int tocopy; + unsigned int loaded = mpq_a->blocksize; + + /* Check if data are loaded in the cache */ + if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) { + + /* Load one MPQ block into archive buffer */ + loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char *)mpq_a->blockbuf, mpq_a->blocksize); + if (loaded == 0) { + return 0; + } + + /* Save lastly accessed file and block position for later use */ + mpq_f->accessed = TRUE; + mpq_a->blockpos = blockpos; + mpq_a->bufpos = filepos % mpq_a->blocksize; + } + tocopy = loaded - mpq_a->bufpos; + if (tocopy > toread) { + tocopy = toread; + } + + /* Copy data from block buffer into target buffer */ + memcpy(buffer, mpq_a->blockbuf + mpq_a->bufpos, tocopy); + + /* Update pointers */ + toread -= tocopy; + bytesread += tocopy; + buffer += tocopy; + blockpos += mpq_a->blocksize; + mpq_a->bufpos += tocopy; + + /* If all, return. */ + if (toread == 0) { + return bytesread; + } + } + + /* Load the whole ("middle") blocks only if there are more or equal one block */ + if (toread > mpq_a->blocksize) { + unsigned int blockbytes = toread & ~(mpq_a->blocksize - 1); + loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, buffer, blockbytes); + if (loaded == 0) { + return 0; + } + + /* Update pointers */ + toread -= loaded; + bytesread += loaded; + buffer += loaded; + blockpos += loaded; + + /* If all, return. */ + if (toread == 0) { + return bytesread; + } + } + + /* Load the terminating block */ + if (toread > 0) { + unsigned int tocopy = mpq_a->blocksize; + + /* Check if data are loaded in the cache */ + if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) { + + /* Load one MPQ block into archive buffer */ + tocopy = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char *)mpq_a->blockbuf, mpq_a->blocksize); + if (tocopy == 0) { + return 0; + } + + /* Save lastly accessed file and block position for later use */ + mpq_f->accessed = TRUE; + mpq_a->blockpos = blockpos; + } + mpq_a->bufpos = 0; + + /* Check number of bytes read */ + if (tocopy > toread) { + tocopy = toread; + } + + memcpy(buffer, mpq_a->blockbuf, tocopy); + bytesread += tocopy; + mpq_a->bufpos = tocopy; + } + + /* Return what we've read */ + return bytesread; +} diff --git a/contrib/extractor/libmpq/common.h b/contrib/extractor/libmpq/common.h new file mode 100644 index 000000000..ad2c0f101 --- /dev/null +++ b/contrib/extractor/libmpq/common.h @@ -0,0 +1,66 @@ +/* + * common.h -- defines and structs used by the config files. + * + * Copyright (C) 2003 Maik Broemme + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: common.h,v 1.4 2004/02/12 00:41:55 mbroemme Exp $ + */ + +#define LIBMPQ_CONF_FL_INCREMENT 512 /* i hope we did not need more :) */ +#define LIBMPQ_CONF_EXT ".conf" /* listdb file seems to be valid with this extension */ +#define LIBMPQ_CONF_HEADER "LIBMPQ_VERSION" /* listdb file must include this entry to be valid */ +#define LIBMPQ_CONF_BUFSIZE 4096 /* maximum number of bytes a line in the file could contain */ + +#define LIBMPQ_CONF_TYPE_CHAR 1 /* value in config file is from type char */ +#define LIBMPQ_CONF_TYPE_INT 2 /* value in config file is from type int */ + +#define LIBMPQ_CONF_EOPEN_DIR -1 /* error on open directory */ +#define LIBMPQ_CONF_EVALUE_NOT_FOUND -2 /* value for the option was not found */ + +#if defined( __GNUC__ ) + #include + #include + + #define _lseek lseek + #define _read read + #define _open open + #define _write write + #define _close close + #define _strdup strdup + + #ifndef O_BINARY + #define O_BINARY 0 + #endif +#else + #include +#endif + +#ifndef min + #define min(a, b) ((a < b) ? a : b) +#endif + +int libmpq_init_buffer(mpq_archive *mpq_a); +int libmpq_read_hashtable(mpq_archive *mpq_a); +int libmpq_read_blocktable(mpq_archive *mpq_a); +int libmpq_file_read_file(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int filepos, char *buffer, unsigned int toread); +int libmpq_read_listfile(mpq_archive *mpq_a, FILE *fp); + +int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int type, int size); +char *libmpq_conf_delete_char(char *buf, char *chars); +int libmpq_conf_get_array(FILE *fp, char *search_value, char ***filelist, int *entries); +int libmpq_free_listfile(char **filelist); +int libmpq_read_listfile(mpq_archive *mpq_a, FILE *fp); diff --git a/contrib/extractor/libmpq/explode.cpp b/contrib/extractor/libmpq/explode.cpp new file mode 100644 index 000000000..bcf9e7857 --- /dev/null +++ b/contrib/extractor/libmpq/explode.cpp @@ -0,0 +1,428 @@ +/* + * explode.c -- explode function of PKWARE data compression library. + * + * Copyright (C) 2003 Maik Broemme + * + * This source was adepted from the C++ version of pkware.cpp included + * in stormlib. The C++ version belongs to the following authors, + * + * Ladislav Zezula + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "mpq.h" +#include "explode.h" + +/* Tables */ +static unsigned char pkzip_dist_bits[] = { + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +static unsigned char pkzip_dist_code[] = { + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 +}; + +static unsigned char pkzip_clen_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 +}; + +static unsigned short pkzip_len_base[] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 +}; + +static unsigned char pkzip_slen_bits[] = { + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 +}; + +static unsigned char pkzip_len_code[] = { + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 +}; + +static unsigned char pkzip_bits_asc[] = { + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D +}; + +static unsigned short pkzip_code_asc[] = { + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 +}; + +/* Local variables */ +static char copyright[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +/* Local functions */ +static void libmpq_pkzip_gen_decode_tabs(long count, unsigned char *bits, unsigned char *code, unsigned char *buf2) { + long i; + + for (i = count-1; i >= 0; i--) { /* EBX - count */ + unsigned long idx1 = code[i]; + unsigned long idx2 = 1 << bits[i]; + do { + buf2[idx1] = (unsigned char)i; + idx1 += idx2; + } while (idx1 < 0x100); + } +} + +static void libmpq_pkzip_gen_asc_tabs(pkzip_data_cmp *mpq_pkzip) { + unsigned short *code_asc = &pkzip_code_asc[0xFF]; + unsigned long acc, add; + unsigned short count; + + for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) { + unsigned char *bits_asc = mpq_pkzip->bits_asc + count; + unsigned char bits_tmp = *bits_asc; + + if (bits_tmp <= 8) { + add = (1 << bits_tmp); + acc = *code_asc; + do { + mpq_pkzip->offs_2c34[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x100); + } else { + if ((acc = (*code_asc & 0xFF)) != 0) { + mpq_pkzip->offs_2c34[acc] = 0xFF; + if (*code_asc & 0x3F) { + bits_tmp -= 4; + *bits_asc = bits_tmp; + add = (1 << bits_tmp); + acc = *code_asc >> 4; + do { + mpq_pkzip->offs_2d34[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x100); + } else { + bits_tmp -= 6; + *bits_asc = bits_tmp; + add = (1 << bits_tmp); + acc = *code_asc >> 6; + do { + mpq_pkzip->offs_2e34[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x80); + } + } else { + bits_tmp -= 8; + *bits_asc = bits_tmp; + add = (1 << bits_tmp); + acc = *code_asc >> 8; + do { + mpq_pkzip->offs_2eb4[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x100); + } + } + } +} + +/* + * Skips given number of bits in bit buffer. Result is stored in mpq_pkzip->bit_buf + * If no data in input buffer, returns true + */ +static int libmpq_pkzip_skip_bits(pkzip_data_cmp *mpq_pkzip, unsigned long bits) { + /* If number of bits required is less than number of (bits in the buffer) ? */ + if (bits <= mpq_pkzip->extra_bits) { + mpq_pkzip->extra_bits -= bits; + mpq_pkzip->bit_buf >>= bits; + return 0; + } + + /* Load input buffer if necessary */ + mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits; + if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) { + mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf); + if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) { + return 1; + } + mpq_pkzip->in_pos = 0; + } + + /* Update bit buffer */ + mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8); + mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits); + mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8; + return 0; +} + +/* + * Decompress the imploded data using coded literals. + * Returns: 0x000 - 0x0FF : One byte from compressed file. + * 0x100 - 0x305 : Copy previous block (0x100 = 1 byte) + * 0x306 : Out of buffer (?) + */ +static unsigned long libmpq_pkzip_explode_lit(pkzip_data_cmp *mpq_pkzip) { + unsigned long bits; /* Number of bits to skip */ + unsigned long value; /* Position in buffers */ + + /* Test the current bit in byte buffer. If is not set, simply return the next byte. */ + if (mpq_pkzip->bit_buf & 1) { + + /* Skip current bit in the buffer. */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) { + return 0x306; + } + + /* The next bits are position in buffers. */ + value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)]; + + /* Get number of bits to skip */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->slen_bits[value])) { + return 0x306; + } + if ((bits = mpq_pkzip->clen_bits[value]) != 0) { + unsigned long val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1); + if (libmpq_pkzip_skip_bits(mpq_pkzip, bits)) { + if ((value + val2) != 0x10E) { + return 0x306; + } + } + value = mpq_pkzip->len_base[value] + val2; + } + return value + 0x100; /* Return number of bytes to repeat */ + } + + /* Skip one bit */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) { + return 0x306; + } + + /* If the binary compression type, read 8 bits and return them as one byte. */ + if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) { + value = mpq_pkzip->bit_buf & 0xFF; + if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) { + return 0x306; + } + return value; + } + + /* When ASCII compression ... */ + if (mpq_pkzip->bit_buf & 0xFF) { + value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF]; + if (value == 0xFF) { + if (mpq_pkzip->bit_buf & 0x3F) { + if (libmpq_pkzip_skip_bits(mpq_pkzip, 4)) { + return 0x306; + } + value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF]; + } else { + if (libmpq_pkzip_skip_bits(mpq_pkzip, 6)) { + return 0x306; + } + value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F]; + } + } + } else { + if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) { + return 0x306; + } + value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF]; + } + return libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value; +} + +/* + * Retrieves the number of bytes to move back. + */ +static unsigned long libmpq_pkzip_explode_dist(pkzip_data_cmp *mpq_pkzip, unsigned long length) { + unsigned long pos = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)]; + unsigned long skip = mpq_pkzip->dist_bits[pos]; /* Number of bits to skip */ + + /* Skip the appropriate number of bits */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, skip) == 1) { + return 0; + } + if (length == 2) { + pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03); + if (libmpq_pkzip_skip_bits(mpq_pkzip, 2) == 1) { + return 0; + } + } else { + pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask); + + /* Skip the bits */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) { + return 0; + } + } + return pos + 1; +} + +static unsigned long libmpq_pkzip_expand(pkzip_data_cmp *mpq_pkzip) { + unsigned int copy_bytes; /* Number of bytes to copy */ + unsigned long one_byte; /* One byte from compressed file */ + unsigned long result; + + mpq_pkzip->out_pos = 0x1000; /* Initialize output buffer position */ + + /* If end of data or error, terminate decompress */ + while ((result = one_byte = libmpq_pkzip_explode_lit(mpq_pkzip)) < 0x305) { + + /* If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" */ + if (one_byte >= 0x100) { + unsigned char *source; /* ECX */ + unsigned char *target; /* EDX */ + unsigned long copy_length = one_byte - 0xFE; + unsigned long move_back; + + /* Get length of data to copy */ + if ((move_back = libmpq_pkzip_explode_dist(mpq_pkzip, copy_length)) == 0) { + result = 0x306; + break; + } + + /* Target and source pointer */ + target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos]; + source = target - move_back; + mpq_pkzip->out_pos += copy_length; + while (copy_length-- > 0) { + *target++ = *source++; + } + } else { + mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (unsigned char)one_byte; + } + + /* + * If number of extracted bytes has reached 1/2 of output buffer, + * flush output buffer. + */ + if (mpq_pkzip->out_pos >= 0x2000) { + + /* Copy decompressed data into user buffer. */ + copy_bytes = 0x1000; + mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param); + + /* If there are some data left, keep them alive */ + memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000); + mpq_pkzip->out_pos -= 0x1000; + } + } + copy_bytes = mpq_pkzip->out_pos - 0x1000; + mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param); + return result; +} + +/* + * Main exploding function. + */ +unsigned int libmpq_pkzip_explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param) { + + pkzip_data_cmp *mpq_pkzip = (pkzip_data_cmp *)work_buf; + + /* Set the whole work buffer to zeros */ + memset(mpq_pkzip, 0, sizeof(pkzip_data_cmp)); + + /* Initialize work struct and load compressed data */ + mpq_pkzip->read_buf = read_buf; + mpq_pkzip->write_buf = write_buf; + mpq_pkzip->param = param; + mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf); + mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param); + if (mpq_pkzip->in_bytes <= 4) { + return LIBMPQ_PKZIP_CMP_BAD_DATA; + } + mpq_pkzip->cmp_type = mpq_pkzip->in_buf[0]; /* Get the compression type */ + mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1]; /* Get the dictionary size */ + mpq_pkzip->bit_buf = mpq_pkzip->in_buf[2]; /* Initialize 16-bit bit buffer */ + mpq_pkzip->extra_bits = 0; /* Extra (over 8) bits */ + mpq_pkzip->in_pos = 3; /* Position in input buffer */ + + /* Test for the valid dictionary size */ + if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) { + return LIBMPQ_PKZIP_CMP_INV_DICTSIZE; + } + mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits); /* Shifted by 'sar' instruction */ + if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) { + if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) { + return LIBMPQ_PKZIP_CMP_INV_MODE; + } + memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc)); + libmpq_pkzip_gen_asc_tabs(mpq_pkzip); + } + memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits)); + libmpq_pkzip_gen_decode_tabs(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2); + memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits)); + memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base)); + memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits)); + libmpq_pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1); + if (libmpq_pkzip_expand(mpq_pkzip) != 0x306) { + return LIBMPQ_PKZIP_CMP_NO_ERROR; + } + return LIBMPQ_PKZIP_CMP_ABORT; +} diff --git a/contrib/extractor/libmpq/explode.h b/contrib/extractor/libmpq/explode.h new file mode 100644 index 000000000..1f916f778 --- /dev/null +++ b/contrib/extractor/libmpq/explode.h @@ -0,0 +1,86 @@ +/* + * explode.h -- header file for PKWARE data decompression library + * used by mpq-tools. + * + * Copyright (C) 2003 Maik Broemme + * + * This source was adepted from the C++ version of pklib.h included + * in stormlib. The C++ version belongs to the following authors, + * + * Ladislav Zezula + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _EXPLODE_H +#define _EXPLODE_H + +#define LIBMPQ_PKZIP_EXP_BUFFER_SIZE 12596 /* Size of decompress buffer */ +#define LIBMPQ_PKZIP_CMP_BINARY 0 /* Binary compression */ +#define LIBMPQ_PKZIP_CMP_ASCII 1 /* Ascii compression */ +#define LIBMPQ_PKZIP_CMP_NO_ERROR 0 +#define LIBMPQ_PKZIP_CMP_INV_DICTSIZE 1 +#define LIBMPQ_PKZIP_CMP_INV_MODE 2 +#define LIBMPQ_PKZIP_CMP_BAD_DATA 3 +#define LIBMPQ_PKZIP_CMP_ABORT 4 + +/* Compression structure (size: 12596 bytes on x86-32) */ +typedef struct { + unsigned long offs0000; /* 0000 */ + unsigned long cmp_type; /* 0004 - Compression type (LIBMPQ_PZIP_CMP_BINARY or LIBMPQ_PKZIP_CMP_ASCII) */ + unsigned long out_pos; /* 0008 - Position in output buffer */ + unsigned long dsize_bits; /* 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) */ + unsigned long dsize_mask; /* 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) */ + unsigned long bit_buf; /* 0014 - 16-bit buffer for processing input data */ + unsigned long extra_bits; /* 0018 - Number of extra (above 8) bits in bit buffer */ + unsigned int in_pos; /* 001C - Position in in_buf */ + unsigned long in_bytes; /* 0020 - Number of bytes in input buffer */ + void *param; /* 0024 - Custom parameter */ + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); /* 0028 */ + void (*write_buf)(char *buf, unsigned int *size, void *param); /* 002C */ + unsigned char out_buf[0x2000]; /* 0030 - Output circle buffer. Starting position is 0x1000 */ + unsigned char offs_2030[0x204]; /* 2030 - ??? */ + unsigned char in_buf[0x800]; /* 2234 - Buffer for data to be decompressed */ + unsigned char pos1[0x100]; /* 2A34 - Positions in buffers */ + unsigned char pos2[0x100]; /* 2B34 - Positions in buffers */ + unsigned char offs_2c34[0x100]; /* 2C34 - Buffer for */ + unsigned char offs_2d34[0x100]; /* 2D34 - Buffer for */ + unsigned char offs_2e34[0x80]; /* 2EB4 - Buffer for */ + unsigned char offs_2eb4[0x100]; /* 2EB4 - Buffer for */ + unsigned char bits_asc[0x100]; /* 2FB4 - Buffer for */ + unsigned char dist_bits[0x40]; /* 30B4 - Numbers of bytes to skip copied block length */ + unsigned char slen_bits[0x10]; /* 30F4 - Numbers of bits for skip copied block length */ + unsigned char clen_bits[0x10]; /* 3104 - Number of valid bits for copied block */ + unsigned short len_base[0x10]; /* 3114 - Buffer for */ +} pkzip_data_cmp; +// __attribute__ ((packed)) pkzip_data_cmp; + +typedef struct { + char *in_buf; /* Pointer to input data buffer */ + unsigned int in_pos; /* Current offset in input data buffer */ + int in_bytes; /* Number of bytes in the input buffer */ + char *out_buf; /* Pointer to output data buffer */ + unsigned int out_pos; /* Position in the output buffer */ + int max_out; /* Maximum number of bytes in the output buffer */ +} pkzip_data; + +extern unsigned int libmpq_pkzip_explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param +); + +#endif /* _EXPLODE_H */ diff --git a/contrib/extractor/libmpq/extract.cpp b/contrib/extractor/libmpq/extract.cpp new file mode 100644 index 000000000..41472b3c4 --- /dev/null +++ b/contrib/extractor/libmpq/extract.cpp @@ -0,0 +1,262 @@ +/* + * extract.c -- global extracting function for all known file compressions + * in a MPQ archive. + * + * Copyright (C) 2003 Maik Broemme + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#define HAVE_LIBZ +#ifdef HAVE_LIBZ +#include +#endif + +#include "mpq.h" +#include "explode.h" +#include "huffman.h" + +#include "wave.h" + +/* + * Support functions for PKWARE data compression library. + * + * Function loads data from the input buffer. Used by mpq_pkzip + * "implode" and "explode" function as user-defined callback. + * Returns number of bytes loaded. + * + * char * buf - Pointer to a buffer where to store loaded data + * unsigned int * size - Max. number of bytes to read + * void * param - Custom pointer, parameter of implode/explode + */ +static unsigned int libmpq_pkzip_read_input_data(char *buf, unsigned int *size, void *param) { + pkzip_data *info = (pkzip_data *)param; + unsigned int max_avail = (info->in_bytes - info->in_pos); + unsigned int to_read = *size; + + /* Check the case when not enough data available */ + if (to_read > max_avail) { + to_read = max_avail; + } + + /* Load data and increment offsets */ + memcpy(buf, info->in_buf + info->in_pos, to_read); + info->in_pos += to_read; + + return to_read; +} + +/* + * Support functions for PKWARE data compression library. + * + * Function for store output data. Used by mpq_pkzip "implode" and + * "explode" as user-defined callback. + * + * char * buf - Pointer to data to be written + * unsigned int * size - Number of bytes to write + * void * param - Custom pointer, parameter of implode/explode + */ +static void libmpq_pkzip_write_output_data(char *buf, unsigned int *size, void *param) { + pkzip_data *info = (pkzip_data *)param; + unsigned int max_write = (info->max_out - info->out_pos); + unsigned int to_write = *size; + + /* Check the case when not enough space in the output buffer */ + if (to_write > max_write) { + to_write = max_write; + } + + /* Write output data and increments offsets */ + memcpy(info->out_buf + info->out_pos, buf, to_write); + info->out_pos += to_write; +} + +int libmpq_pkzip_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) { + pkzip_data info; /* Data information */ + char *work_buf = (char *)malloc(LIBMPQ_PKZIP_EXP_BUFFER_SIZE); /* mpq_pkzip work buffer */ + + /* Fill data information structure */ + info.in_buf = in_buf; + info.in_pos = 0; + info.in_bytes = in_length; + info.out_buf = out_buf; + info.out_pos = 0; + info.max_out = *out_length; + + /* Do the decompression */ + libmpq_pkzip_explode(libmpq_pkzip_read_input_data, libmpq_pkzip_write_output_data, work_buf, &info); + *out_length = info.out_pos; + free(work_buf); + return 0; +} + +int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_buf, int in_length) { + *out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 1); + return 1; +} + +int libmpq_wave_decompress_stereo(char *out_buf, int *out_length, char *in_buf, int in_length) { + *out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 2); + return 1; +} + +int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) { +#ifdef HAVE_LIBZ + z_stream z; /* Stream information for zlib */ + int result; + + /* Fill the stream structure for zlib */ + z.next_in = (Bytef *)in_buf; + z.avail_in = (uInt)in_length; + z.total_in = in_length; + z.next_out = (Bytef *)out_buf; + z.avail_out = *out_length; + z.total_out = 0; + z.zalloc = NULL; + z.zfree = NULL; + + /* Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 */ + if ((result = inflateInit(&z)) == 0) { + + /* Call zlib to decompress the data */ + result = inflate(&z, Z_FINISH); + *out_length = z.total_out; + inflateEnd(&z); + } + return result; +#else + memset(out_buf, '0', *out_length); + return 0; +#endif +} + +/* + * Huffmann decompression routine. The in_length parameter is not used, but needs + * to be specified due to compatibility reasons. + * + * 1500F5F0 + */ +int libmpq_huff_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) { + struct huffman_tree *ht = (huffman_tree *)malloc(sizeof(struct huffman_tree)); + struct huffman_input_stream *is = (huffman_input_stream *)malloc(sizeof(struct huffman_input_stream)); + struct huffman_tree_item *hi = (huffman_tree_item *)malloc(sizeof(struct huffman_tree_item)); + memset(ht, 0, sizeof(struct huffman_tree)); + memset(is, 0, sizeof(struct huffman_input_stream)); + memset(hi, 0, sizeof(struct huffman_tree_item)); + + /* Initialize input stream */ + is->bit_buf = *(unsigned long *)in_buf; + in_buf += sizeof(unsigned long); + is->in_buf = (unsigned char *)in_buf; + is->bits = 32; + + /* Initialize the Huffmann tree for decompression */ + libmpq_huff_init_tree(ht, hi, LIBMPQ_HUFF_DECOMPRESS); + + *out_length = libmpq_huff_do_decompress(ht, is, (unsigned char *)out_buf, *out_length); + + free(hi); + free(is); + free(ht); + return 0; +} + +int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length) { + char *temp_buf = NULL; /* Temporary storage for decompressed data */ + char *work_buf = NULL; /* Where to store decompressed data */ + int out_length = *pout_length; /* For storage number of output bytes */ + unsigned fDecompressions1; /* Decompressions applied to the block */ + unsigned fDecompressions2; /* Just another copy of decompressions applied to the block */ + int count = 0; /* Counter for every use */ + int entries = (sizeof(dcmp_table) / sizeof(decompress_table)); + int i; + + /* If the input length is the same as output, do nothing. */ + if (in_length == out_length) { + if (in_buf == out_buf) { + return 1; + } + memcpy(out_buf, in_buf, in_length); + return 1; + } + + /* Get applied compression types and decrement data length */ + fDecompressions1 = fDecompressions2 = (unsigned char)*in_buf++; + in_length--; + + /* Search decompression table type and get all types of compression */ + for (i = 0; i < entries; i++) { + /* We have to apply this decompression? */ + if (fDecompressions1 & dcmp_table[i].mask) { + count++; + } + + /* Clear this flag from temporary variable. */ + fDecompressions2 &= ~dcmp_table[i].mask; + } + + /* + * Check if there is some method unhandled + * (E.g. compressed by future versions) + */ + if (fDecompressions2 != 0) { + printf("Unknown Compression\n"); + return 0; + } + + /* If there is more than only one compression, we have to allocate extra buffer */ + if (count >= 2) { + temp_buf = (char *)malloc(out_length); + } + + /* Apply all decompressions */ + for (i = 0, count = 0; i < entries; i++) { + + /* If not used this kind of compression, skip the loop */ + if (fDecompressions1 & dcmp_table[i].mask) { + + /* If odd case, use target buffer for output, otherwise use allocated tempbuf */ + work_buf = (count++ & 1) ? temp_buf : out_buf; + out_length = *pout_length; + + /* Decompress buffer using corresponding function */ + dcmp_table[i].decompress(work_buf, &out_length, in_buf, in_length); + + /* Move output length to src length for next compression */ + in_length = out_length; + in_buf = work_buf; + } + } + + /* If output buffer is not the same like target buffer, we have to copy data */ + if (work_buf != out_buf) { + memcpy(out_buf, in_buf, out_length); + } + *pout_length = out_length; + + /* Delete temporary buffer, if necessary */ + if (temp_buf != NULL) { + free(temp_buf); + } + return 1; +} diff --git a/contrib/extractor/libmpq/huffman.cpp b/contrib/extractor/libmpq/huffman.cpp new file mode 100644 index 000000000..b63eee43e --- /dev/null +++ b/contrib/extractor/libmpq/huffman.cpp @@ -0,0 +1,833 @@ +/* + * huffman.c -- functions do decompress files in MPQ files which + * uses a modified huffman version. + * + * Copyright (C) 2003 Maik Broemme + * + * Differences between C++ and C version: + * + * - Removed the object oriented stuff. + * - Replaced the goto things with some better C code. + * + * This source was adepted from the C++ version of huffman.cpp included + * in stormlib. The C++ version belongs to the following authors, + * + * Ladislav Zezula + * ShadowFlare + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include + +#include "mpq.h" +#include "huffman.h" + +unsigned char table1502A630[] = { + + /* Data for compression type 0x00 */ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, + + /* Data for compression type 0x01 */ + 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, + 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, + 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, + 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, + 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, + 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, + 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, + 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, + 0x00, 0x00, + + /* Data for compression type 0x02 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, + 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, + 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, + 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x03 */ + 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, + 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, + 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, + 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, + 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, + 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, + 0x00, 0x00, + + /* Data for compression type 0x04 */ + 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x05 */ + 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, + 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, + 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, + 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x06 */ + 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x07 */ + 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x08 */ + 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, + 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, + 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +/* Gets previous Huffman tree item (?) */ +struct huffman_tree_item *libmpq_huff_get_prev_item(struct huffman_tree_item *hi, long value) { + if (PTR_INT(hi->prev) < 0) { + return PTR_NOT(hi->prev); + } + if (value < 0) { + value = hi - hi->next->prev; + } + return hi->prev + value; +} + +/* 1500BC90 */ +static void libmpq_huff_remove_item(struct huffman_tree_item *hi) { + struct huffman_tree_item *temp; /* EDX */ + + if (hi->next != NULL) { + temp = hi->prev; + if (PTR_INT(temp) <= 0) { + temp = PTR_NOT(temp); + } else { + temp += (hi - hi->next->prev); + } + temp->next = hi->next; + hi->next->prev = hi->prev; + hi->next = hi->prev = NULL; + } +} + +static void libmpq_huff_insert_item(struct huffman_tree_item **p_item, struct huffman_tree_item *item, unsigned long where, struct huffman_tree_item *item2) { + struct huffman_tree_item *next = item->next; /* EDI - next to the first item */ + struct huffman_tree_item *prev = item->prev; /* ESI - prev to the first item */ + struct huffman_tree_item *prev2; /* Pointer to previous item */ + long next2; /* Pointer to the next item */ + + /* The same code like in mpq_huff_remove_item(); */ + if (next != 0) { /* If the first item already has next one */ + if (PTR_INT(prev) < 0) { + prev = PTR_NOT(prev); + } else { + prev += (item - next->prev); + } + + /* + * 150083C1 + * Remove the item from the tree + */ + prev->next = next; + next->prev = prev; + + /* Invalidate 'prev' and 'next' pointer */ + item->next = 0; + item->prev = 0; + } + + if (item2 == NULL) { /* EDX - If the second item is not entered, */ + item2 = PTR_PTR(&p_item[1]); /* take the first tree item */ + } + + switch (where) { + case SWITCH_ITEMS: /* Switch the two items */ + item->next = item2->next; /* item2->next (Pointer to pointer to first) */ + item->prev = item2->next->prev; + item2->next->prev = item; + item2->next = item; /* Set the first item */ + return; + case INSERT_ITEM: /* Insert as the last item */ + item->next = item2; /* Set next item (or pointer to pointer to first item) */ + item->prev = item2->prev; /* Set prev item (or last item in the tree) */ + next2 = PTR_INT(p_item[0]); /* Usually NULL */ + prev2 = item2->prev; /* Prev item to the second (or last tree item) */ + if (PTR_INT(prev2) < 0) { + prev2 = PTR_NOT(prev); + prev2->next = item; + item2->prev = item; /* Next after last item */ + return; + } + if (next2 < 0) { + next2 = item2 - item2->next->prev; + } + prev2 += next2; + prev2->next = item; + item2->prev = item; /* Set the next/last item */ + return; + default: + return; + } +} + +/* Builds Huffman tree. Called with the first 8 bits loaded from input stream. */ +static void libmpq_huff_build_tree(struct huffman_tree *ht, unsigned int cmp_type) { + unsigned long max_byte; /* [ESP+10] - The greatest character found in table */ + unsigned char *byte_array; /* [ESP+1C] - Pointer to unsigned char in table1502A630 */ + unsigned long i; /* egcs in linux doesn't like multiple for loops without an explicit i */ + unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ + struct huffman_tree_item **p_item; /* [ESP+14] - Pointer to Huffman tree item pointer array */ + struct huffman_tree_item *child1; + + /* Loop while pointer has a negative value. */ + while (PTR_INT(ht->last) > 0) { /* ESI - Last entry */ + struct huffman_tree_item *temp; /* EAX */ + + if (ht->last->next != NULL) { /* ESI->next */ + libmpq_huff_remove_item(ht->last); + } + ht->item3058 = PTR_PTR(&ht->item3054);/* [EDI+4] */ + ht->last->prev = ht->item3058; /* EAX */ + temp = libmpq_huff_get_prev_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050)); + temp->next = ht->last; + ht->item3054 = ht->last; + } + + /* Clear all pointers in huffman tree item array. */ + memset(ht->items306C, 0, sizeof(ht->items306C)); + + max_byte = 0; /* Greatest character found init to zero. */ + p_item = (struct huffman_tree_item **)&ht->items306C; /* Pointer to current entry in huffman tree item pointer array */ + + /* Ensure we have low 8 bits only */ + cmp_type &= 0xFF; + byte_array = table1502A630 + cmp_type * 258; /* EDI also */ + + for (i = 0; i < 0x100; i++, p_item++) { + struct huffman_tree_item *item = ht->item3058; /* Item to be created */ + struct huffman_tree_item *p_item3 = ht->item3058; + unsigned char one_byte = byte_array[i]; + + /* Skip all the bytes which are zero. */ + if (byte_array[i] == 0) { + continue; + } + + /* If not valid pointer, take the first available item in the array. */ + if (PTR_INT(item) <= 0) { + item = &ht->items0008[ht->items++]; + } + + /* Insert this item as the top of the tree. */ + libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); + + item->parent = NULL; /* Invalidate child and parent */ + item->child = NULL; + *p_item = item; /* Store pointer into pointer array */ + + item->dcmp_byte = i; /* Store counter */ + item->byte_value = one_byte; /* Store byte value */ + if (one_byte >= max_byte) { + max_byte = one_byte; + continue; + } + + /* Find the first item which has byte value greater than current one byte */ + found = 0; + if (PTR_INT((p_item3 = ht->last)) > 0) {/* EDI - Pointer to the last item */ + + /* 15006AF7 */ + if (p_item3 != NULL) { + do { /* 15006AFB */ + if (p_item3->byte_value >= one_byte) { + found = 1; + break; + } + p_item3 = p_item3->prev; + } while (PTR_INT(p_item3) > 0); + } + } + + if (found == 0) { + p_item3 = NULL; + } + + /* 15006B09 */ + if (item->next != NULL) { + libmpq_huff_remove_item(item); + } + + /* 15006B15 */ + if (p_item3 == NULL) { + p_item3 = PTR_PTR(&ht->first); + } + + /* 15006B1F */ + item->next = p_item3->next; + item->prev = p_item3->next->prev; + p_item3->next->prev = item; + p_item3->next = item; + } + + /* 15006B4A */ + for (; i < 0x102; i++) { + struct huffman_tree_item **p_item2 = &ht->items306C[i]; /* EDI */ + + /* 15006B59 */ + struct huffman_tree_item *item2 = ht->item3058; /* ESI */ + if (PTR_INT(item2) <= 0) { + item2 = &ht->items0008[ht->items++]; + } + libmpq_huff_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL); + + /* 15006B89 */ + item2->dcmp_byte = i; + item2->byte_value = 1; + item2->parent = NULL; + item2->child = NULL; + *p_item2++ = item2; + } + + /* 15006BAA */ + if (PTR_INT((child1 = ht->last)) > 0) { /* EDI - last item (first child to item */ + struct huffman_tree_item *child2; /* EBP */ + struct huffman_tree_item *item; /* ESI */ + + /* 15006BB8 */ + while (PTR_INT((child2 = child1->prev)) > 0) { + if (PTR_INT((item = ht->item3058)) <= 0) { + item = &ht->items0008[ht->items++]; + } + /* 15006BE3 */ + libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); + + /* 15006BF3 */ + item->parent = NULL; + item->child = NULL; + + /* + * EDX = child2->byte_value + child1->byte_value; + * EAX = child1->byte_value; + * ECX = max_byte; The greatest character (0xFF usually) + */ + item->byte_value = child1->byte_value + child2->byte_value; /* 0x02 */ + item->child = child1; /* Prev item in the */ + child1->parent = item; + child2->parent = item; + + /* EAX = item->byte_value; */ + if (item->byte_value >= max_byte) { + max_byte = item->byte_value; + } else { + struct huffman_tree_item *p_item2 = child2->prev; /* EDI */ + found = 0; + if (PTR_INT(p_item2) > 0) { + + /* 15006C2D */ + do { + if (p_item2->byte_value >= item->byte_value) { + found = 1; + break; + } + p_item2 = p_item2->prev; + } while (PTR_INT(p_item2) > 0); + } + if (found == 0) { + p_item2 = NULL; + } + if (item->next != 0) { + struct huffman_tree_item *temp4 = libmpq_huff_get_prev_item(item, -1); + temp4->next = item->next; /* The first item changed */ + item->next->prev = item->prev; /* First->prev changed to negative value */ + item->next = NULL; + item->prev = NULL; + } + + /* 15006C62 */ + if (p_item2 == NULL) { + p_item2 = PTR_PTR(&ht->first); + } + item->next = p_item2->next; /* Set item with 0x100 byte value */ + item->prev = p_item2->next->prev; /* Set item with 0x17 byte value */ + p_item2->next->prev = item; /* Changed prev of item with */ + p_item2->next = item; + } + + /* 15006C7B */ + if (PTR_INT((child1 = child2->prev)) <= 0) { + break; + } + } + } + + /* 15006C88 */ + ht->offs0004 = 1; +} + +/* Gets the whole byte from the input stream. */ +static unsigned long libmpq_huff_get_8bits(struct huffman_input_stream *is) { + unsigned long one_byte; + + if (is->bits <= 8) { + is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; + is->in_buf += sizeof(unsigned short); + is->bits += 16; + } + + one_byte = (is->bit_buf & 0xFF); + is->bit_buf >>= 8; + is->bits -= 8; + + return one_byte; +} + +/* Gets 7 bits from the stream. */ +static unsigned long libmpq_huff_get_7bits(struct huffman_input_stream *is) { + if (is->bits <= 7) { + is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; + is->in_buf += sizeof(unsigned short); + is->bits += 16; + } + + /* Get 7 bits from input stream. */ + return (is->bit_buf & 0x7F); +} + +/* Gets one bit from input stream. */ +unsigned long libmpq_huff_get_bit(struct huffman_input_stream *is) { + unsigned long bit = (is->bit_buf & 1); + + is->bit_buf >>= 1; + if (--is->bits == 0) { + is->bit_buf = *(unsigned long *)is->in_buf; + is->in_buf += sizeof(unsigned long); + is->bits = 32; + } + return bit; +} + +static struct huffman_tree_item *libmpq_huff_call1500E740(struct huffman_tree *ht, unsigned int value) { + struct huffman_tree_item *p_item1 = ht->item3058; /* EDX */ + struct huffman_tree_item *p_item2; /* EAX */ + struct huffman_tree_item *p_next; + struct huffman_tree_item *p_prev; + struct huffman_tree_item **pp_item; + + if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) { + if((p_item2 = &ht->items0008[ht->items++]) != NULL) { + p_item1 = p_item2; + } else { + p_item1 = ht->first; + } + } else { + p_item1 = p_item2; + } + + p_next = p_item1->next; + if (p_next != NULL) { + p_prev = p_item1->prev; + if (PTR_INT(p_prev) <= 0) { + p_prev = PTR_NOT(p_prev); + } else { + p_prev += (p_item1 - p_item1->next->prev); + } + + p_prev->next = p_next; + p_next->prev = p_prev; + p_item1->next = NULL; + p_item1->prev = NULL; + } + pp_item = &ht->first; /* ESI */ + if (value > 1) { + + /* ECX = ht->first->next; */ + p_item1->next = *pp_item; + p_item1->prev = (*pp_item)->prev; + + (*pp_item)->prev = p_item2; + *pp_item = p_item1; + + p_item2->parent = NULL; + p_item2->child = NULL; + } else { + p_item1->next = (struct huffman_tree_item *)pp_item; + p_item1->prev = pp_item[1]; + /* EDI = ht->item305C; */ + p_prev = pp_item[1]; /* ECX */ + if (p_prev <= 0) { + p_prev = PTR_NOT(p_prev); + p_prev->next = p_item1; + p_prev->prev = p_item2; + + p_item2->parent = NULL; + p_item2->child = NULL; + } else { + if (PTR_INT(ht->item305C) < 0) { + p_prev += (struct huffman_tree_item *)pp_item - (*pp_item)->prev; + } else { + p_prev += PTR_INT(ht->item305C); + } + + p_prev->next = p_item1; + pp_item[1] = p_item2; + p_item2->parent = NULL; + p_item2->child = NULL; + } + } + return p_item2; +} + +static void libmpq_huff_call1500E820(struct huffman_tree *ht, struct huffman_tree_item *p_item) { + struct huffman_tree_item *p_item1; /* EDI */ + struct huffman_tree_item *p_item2 = NULL; /* EAX */ + struct huffman_tree_item *p_item3; /* EDX */ + struct huffman_tree_item *p_prev; /* EBX */ + + for (; p_item != NULL; p_item = p_item->parent) { + p_item->byte_value++; + + for (p_item1 = p_item; ; p_item1 = p_prev) { + p_prev = p_item1->prev; + if (PTR_INT(p_prev) <= 0) { + p_prev = NULL; + break; + } + if (p_prev->byte_value >= p_item->byte_value) { + break; + } + } + + if (p_item1 == p_item) { + continue; + } + + if (p_item1->next != NULL) { + p_item2 = libmpq_huff_get_prev_item(p_item1, -1); + p_item2->next = p_item1->next; + p_item1->next->prev = p_item1->prev; + p_item1->next = NULL; + p_item1->prev = NULL; + } + p_item2 = p_item->next; + p_item1->next = p_item2; + p_item1->prev = p_item2->prev; + p_item2->prev = p_item1; + p_item->next = p_item1; + if ((p_item2 = p_item1) != NULL) { + p_item2 = libmpq_huff_get_prev_item(p_item, -1); + p_item2->next = p_item->next; + p_item->next->prev = p_item->prev; + p_item->next = NULL; + p_item->prev = NULL; + } + + if (p_prev == NULL) { + p_prev = PTR_PTR(&ht->first); + } + p_item2 = p_prev->next; + p_item->next = p_item2; + p_item->prev = p_item2->prev; + p_item2->prev = p_item; + p_prev->next = p_item; + + p_item3 = p_item1->parent->child; + p_item2 = p_item->parent; + if (p_item2->child == p_item) { + p_item2->child = p_item1; + } + + if (p_item3 == p_item1) { + p_item1->parent->child = p_item; + } + + p_item2 = p_item->parent; + p_item->parent = p_item1->parent; + p_item1->parent = p_item2; + ht->offs0004++; + } +} + +int libmpq_huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, unsigned char *out_buf, unsigned int out_length) { + unsigned int n8bits; /* 8 bits loaded from input stream */ + unsigned int n7bits; /* 7 bits loaded from input stream */ + unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ + unsigned int dcmp_byte = 0; + unsigned long bit_count; + struct huffman_decompress *qd; + unsigned int has_qd; /* Can we use quick decompression? */ + struct huffman_tree_item *p_item1; + struct huffman_tree_item *p_item2; + unsigned char *out_pos = out_buf; + + /* Test the output length. Must not be non zero. */ + if (out_length == 0) { + return 0; + } + + /* Get the compression type from the input stream. */ + n8bits = libmpq_huff_get_8bits(is); + + /* Build the Huffman tree */ + libmpq_huff_build_tree(ht, n8bits); + ht->cmp0 = (n8bits == 0) ? TRUE : FALSE; + + for(;;) { + n7bits = libmpq_huff_get_7bits(is); /* Get 7 bits from input stream */ + + /* + * Try to use quick decompression. Check huffman_decompress array for corresponding item. + * If found, use the result byte instead. + */ + qd = &ht->qd3474[n7bits]; + + /* If there is a quick-pass possible (ebx) */ + has_qd = (qd->offs00 >= ht->offs0004) ? TRUE : FALSE; + + /* If we can use quick decompress, use it. */ + if (has_qd) { + found = 0; + if (qd->bits > 7) { + is->bit_buf >>= 7; + is->bits -= 7; + p_item1 = qd->p_item; + found = 1; + } + if (found == 0) { + is->bit_buf >>= qd->bits; + is->bits -= qd->bits; + dcmp_byte = qd->dcmp_byte; + } + } else { + found = 1; + p_item1 = ht->first->next->prev; + if (PTR_INT(p_item1) <= 0) { + p_item1 = NULL; + } + } + + if (found == 1) { + bit_count = 0; + p_item2 = NULL; + do { + p_item1 = p_item1->child; /* Move down by one level */ + if (libmpq_huff_get_bit(is)) { /* If current bit is set, move to previous */ + p_item1 = p_item1->prev; + } + if (++bit_count == 7) { /* If we are at 7th bit, save current huffman tree item. */ + p_item2 = p_item1; + } + } while (p_item1->child != NULL); /* Walk until tree has no deeper level */ + + if (has_qd == FALSE) { + if (bit_count > 7) { + qd->offs00 = ht->offs0004; + qd->bits = bit_count; + qd->p_item = p_item2; + } else { + unsigned long index = n7bits & (0xFFFFFFFF >> (32 - bit_count)); + unsigned long add = (1 << bit_count); + + for (qd = &ht->qd3474[index]; index <= 0x7F; index += add, qd += add) { + qd->offs00 = ht->offs0004; + qd->bits = bit_count; + qd->dcmp_byte = p_item1->dcmp_byte; + } + } + } + dcmp_byte = p_item1->dcmp_byte; + } + + if (dcmp_byte == 0x101) { /* Huffman tree needs to be modified */ + n8bits = libmpq_huff_get_8bits(is); + p_item1 = (ht->last <= 0) ? NULL : ht->last; + + p_item2 = libmpq_huff_call1500E740(ht, 1); + p_item2->parent = p_item1; + p_item2->dcmp_byte = p_item1->dcmp_byte; + p_item2->byte_value = p_item1->byte_value; + ht->items306C[p_item2->dcmp_byte] = p_item2; + + p_item2 = libmpq_huff_call1500E740(ht, 1); + p_item2->parent = p_item1; + p_item2->dcmp_byte = n8bits; + p_item2->byte_value = 0; + ht->items306C[p_item2->dcmp_byte] = p_item2; + + p_item1->child = p_item2; + libmpq_huff_call1500E820(ht, p_item2); + if (ht->cmp0 == 0) { + libmpq_huff_call1500E820(ht, ht->items306C[n8bits]); + } + dcmp_byte = n8bits; + } + + if (dcmp_byte == 0x100) { + break; + } + + *out_pos++ = (unsigned char)dcmp_byte; + if (--out_length == 0) { + break; + } + if (ht->cmp0) { + libmpq_huff_call1500E820(ht, ht->items306C[dcmp_byte]); + } + } + return (out_pos - out_buf); +} + +int libmpq_huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi, unsigned int cmp) { + int count; + + /* Clear links for all the items in the tree */ + for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) { + hi->next = hi->prev = NULL; + } + + ht->item3050 = NULL; + ht->item3054 = PTR_PTR(&ht->item3054); + ht->item3058 = PTR_NOT(ht->item3054); + + ht->item305C = NULL; + ht->first = PTR_PTR(&ht->first); + ht->last = PTR_NOT(ht->first); + + ht->offs0004 = 1; + ht->items = 0; + + /* Clear all huffman_decompress items. Do this only if preparing for decompression */ + if (cmp == LIBMPQ_HUFF_DECOMPRESS) { + for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress); count++) { + ht->qd3474[count].offs00 = 0; + } + } + + return 0; +} diff --git a/contrib/extractor/libmpq/huffman.h b/contrib/extractor/libmpq/huffman.h new file mode 100644 index 000000000..1f8eae54e --- /dev/null +++ b/contrib/extractor/libmpq/huffman.h @@ -0,0 +1,105 @@ +/* + * huffman.h -- structures used for huffman compression. + * + * Copyright (C) 2003 Maik Broemme + * + * This source was adepted from the C++ version of huffman.h included + * in stormlib. The C++ version belongs to the following authors, + * + * Ladislav Zezula + * ShadowFlare + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _HUFFMAN_H +#define _HUFFMAN_H + +#define PTR_NOT(ptr) (struct huffman_tree_item *)(~(unsigned long)(ptr)) +#define PTR_PTR(ptr) ((struct huffman_tree_item *)(ptr)) +#define PTR_INT(ptr) (long)(ptr) + +#define INSERT_ITEM 1 +#define SWITCH_ITEMS 2 /* Switch the item1 and item2 */ + +/* + * Input stream for Huffmann decompression + */ +struct huffman_input_stream { + unsigned char *in_buf; /* 00 - Input data */ + unsigned long bit_buf; /* 04 - Input bit buffer */ + unsigned int bits; /* 08 - Number of bits remaining in 'byte' */ +}; + +/* + * Huffmann tree item. + */ +struct huffman_tree_item { + struct huffman_tree_item *next; /* 00 - Pointer to next huffman_tree_item */ + struct huffman_tree_item *prev; /* 04 - Pointer to prev huffman_tree_item (< 0 if none) */ + unsigned long dcmp_byte; /* 08 - Index of this item in item pointer array, decompressed byte value */ + unsigned long byte_value; /* 0C - Some byte value */ + struct huffman_tree_item *parent; /* 10 - Pointer to parent huffman_tree_item (NULL if none) */ + struct huffman_tree_item *child; /* 14 - Pointer to child huffman_tree_item */ +}; + +/* + * Structure used for quick decompress. The 'bits' contains + * number of bits and dcmp_byte contains result decompressed byte + * value. After each walk through Huffman tree are filled all entries + * which are multiplies of number of bits loaded from input stream. + * These entries contain number of bits and result value. At the next + * 7 bits is tested this structure first. If corresponding entry found, + * decompression routine will not walk through Huffman tree and + * directly stores output byte to output stream. + */ +struct huffman_decompress { + unsigned long offs00; /* 00 - 1 if resolved */ + unsigned long bits; /* 04 - Bit count */ + union { + unsigned long dcmp_byte; /* 08 - Byte value for decompress (if bitCount <= 7) */ + struct huffman_tree_item *p_item; /* 08 - THTreeItem (if number of bits is greater than 7 */ + }; +}; + +/* + * Structure for Huffman tree. + */ +struct huffman_tree { + unsigned long cmp0; /* 0000 - 1 if compression type 0 */ + unsigned long offs0004; /* 0004 - Some flag */ + + struct huffman_tree_item items0008[0x203]; /* 0008 - huffman tree items */ + + /* Sometimes used as huffman tree item */ + struct huffman_tree_item *item3050; /* 3050 - Always NULL (?) */ + struct huffman_tree_item *item3054; /* 3054 - Pointer to huffman_tree_item */ + struct huffman_tree_item *item3058; /* 3058 - Pointer to huffman_tree_item (< 0 if invalid) */ + + /* Sometimes used as huffman tree item */ + struct huffman_tree_item *item305C; /* 305C - Usually NULL */ + struct huffman_tree_item *first; /* 3060 - Pointer to top (first) Huffman tree item */ + struct huffman_tree_item *last; /* 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) */ + unsigned long items; /* 3068 - Number of used huffman tree items */ + + struct huffman_tree_item *items306C[0x102]; /* 306C - huffman_tree_item pointer array */ + struct huffman_decompress qd3474[0x80]; /* 3474 - Array for quick decompression */ + + //unsigned char table1502A630[]; /* Some table to make struct size flexible */ +}; + +int libmpq_huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi, unsigned int cmp); +int libmpq_huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, unsigned char *out_buf, unsigned int out_length); +#endif /* _HUFFMAN_H */ diff --git a/contrib/extractor/libmpq/mpq.cpp b/contrib/extractor/libmpq/mpq.cpp new file mode 100644 index 000000000..dda89a3b9 --- /dev/null +++ b/contrib/extractor/libmpq/mpq.cpp @@ -0,0 +1,626 @@ +/* + * mpq.c -- functions for developers using libmpq. + * + * Copyright (C) 2003 Maik Broemme + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: mpq.c,v 1.6 2004/02/12 00:49:00 mbroemme Exp $ + */ +#define _CRT_SECURE_NO_DEPRECATE + +#include +#include +//#include +//#include +#include +#include +#include +#include "mpq.h" +#include "common.h" + +/* + * This function returns version information. + * format: MAJOR.MINOR.PATCH + */ +char *libmpq_version() { + static char version[10]; + sprintf(version, "%i.%i.%i", LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION); + return version; +} + +/* + * This function reads a file and verify if it is a legit MPQ archive + * or not. Then it fills the mpq_header structure and reads the hash + * table. + */ +int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) { + int fd = 0; + int rb = 0; + int ncnt = FALSE; + struct stat fileinfo; + + /* allocate memory */ + mpq_a->mpq_l = (mpq_list *)malloc(sizeof(mpq_list)); + memset(mpq_a->mpq_l, 0, sizeof(mpq_list)); + mpq_a->header = (mpq_header *)malloc(sizeof(mpq_header)); + memset(mpq_a->header, 0, sizeof(mpq_header)); + + /* Check if file exists and is readable */ + fd = _open((char *)mpq_filename, O_RDONLY | O_BINARY); + if (fd == LIBMPQ_EFILE) { + return LIBMPQ_EFILE; + } + + /* fill the structures with informations */ + strcpy((char *)mpq_a->filename, (char *)mpq_filename); + libmpq_init_buffer(mpq_a); + mpq_a->fd = fd; + mpq_a->header->id = 0; + mpq_a->maxblockindex = 0; + mpq_a->mpq_l->mpq_files = NULL; + + mpq_a->mpqpos = 0; //k + + while (!ncnt) { + mpq_a->header->id = 0; + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET); + #endif + rb = _read(mpq_a->fd, mpq_a->header, sizeof(mpq_header)); + + /* if different number of bytes read, break the loop */ + if (rb != sizeof(mpq_header)) { + return LIBMPQ_EFILE_FORMAT; + } + + /* special offset for protected MPQs */ + if (mpq_a->header->offset == LIBMPQ_HEADER_W3M) { + mpq_a->flags |= LIBMPQ_FLAG_PROTECTED; + mpq_a->header->offset = sizeof(mpq_header); + } + + /* if valid signature has been found, break the loop */ + if (mpq_a->header->id == LIBMPQ_ID_MPQ) { + ncnt = true; + } + /*if (mpq_a->header->id == LIBMPQ_ID_MPQ && + mpq_a->header->offset == sizeof(mpq_header) && + mpq_a->header->hashtablepos < mpq_a->header->archivesize && + mpq_a->header->blocktablepos < mpq_a->header->archivesize) { + ncnt = TRUE; + }*/ + + /* move to the next possible offset */ + if (!ncnt) { + mpq_a->mpqpos += 0x200; + } + } + + /* get the right positions of the hash table and the block table. */ + mpq_a->blocksize = (0x200 << mpq_a->header->blocksize); + fstat(mpq_a->fd, &fileinfo); + + /* Normal MPQs must have position of */ + /*if (mpq_a->header->hashtablepos + mpq_a->mpqpos < fileinfo.st_size && + mpq_a->header->blocktablepos + mpq_a->mpqpos < fileinfo.st_size) { + mpq_a->header->hashtablepos += mpq_a->mpqpos; + mpq_a->header->blocktablepos += mpq_a->mpqpos; + } else { + return LIBMPQ_EFILE_FORMAT; + }*/ + + /* Try to read and decrypt the hashtable */ + if (libmpq_read_hashtable(mpq_a) != 0) { + return LIBMPQ_EHASHTABLE; + } + + /* Try to read and decrypt the blocktable */ + if (libmpq_read_blocktable(mpq_a) != 0) { + return LIBMPQ_EBLOCKTABLE; + } + + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function closes the file descriptor opened by + * mpq_open_archive(); and frees the decryption buffer. + */ +int libmpq_archive_close(mpq_archive *mpq_a) { + memset(mpq_a->buf, 0, sizeof(mpq_a->buf)); + + /* free the allocated memory. */ + free(mpq_a->header); + free(mpq_a->mpq_l); + + /* Check if file descriptor is valid. */ + if ((_close(mpq_a->fd)) == LIBMPQ_EFILE) { + return LIBMPQ_EFILE; + } + + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function returns the value for the given infotype. + * If an error occurs something < 0 is returned. + */ +int libmpq_archive_info(mpq_archive *mpq_a, unsigned int infotype) { + unsigned int filecount = 0; + unsigned int fsize = 0; + unsigned int csize = 0; + mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->header->blocktablesize; + mpq_block *mpq_b = NULL; + + switch (infotype) { + case LIBMPQ_MPQ_ARCHIVE_SIZE: + return mpq_a->header->archivesize; + case LIBMPQ_MPQ_HASHTABLE_SIZE: + return mpq_a->header->hashtablesize; + case LIBMPQ_MPQ_BLOCKTABLE_SIZE: + return mpq_a->header->blocktablesize; + case LIBMPQ_MPQ_BLOCKSIZE: + return mpq_a->blocksize; + case LIBMPQ_MPQ_NUMFILES: + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + filecount++; + } + return filecount; + case LIBMPQ_MPQ_COMPRESSED_SIZE: + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + csize += mpq_b->csize; + } + return csize; + case LIBMPQ_MPQ_UNCOMPRESSED_SIZE: + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + fsize += mpq_b->fsize; + } + return fsize; + default: + return LIBMPQ_TOOLS_SUCCESS; + } +} + +/* + * This function returns some useful file information. + */ +int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const int number) { + int blockindex = number; //-1; + int i = 0; + mpq_block *mpq_b = NULL; + mpq_hash *mpq_h = NULL; + + /* check if given number is not out of range */ + if (number < 1 || number > mpq_a->header->blocktablesize) { + return LIBMPQ_EINV_RANGE; + } + + /* search for correct hashtable */ + /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { + if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { + blockindex = (mpq_a->hashtable[i]).blockindex; + mpq_h = &(mpq_a->hashtable[i]); + break; + } + }*/ + + /* check if file was found */ + /*if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { + return LIBMPQ_EFILE_NOT_FOUND; + }*/ + + /* check if sizes are correct */ + mpq_b = mpq_a->blocktable + blockindex; + if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* check if file exists */ + if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + switch (infotype) { + case LIBMPQ_FILE_COMPRESSED_SIZE: + return mpq_b->csize; + case LIBMPQ_FILE_UNCOMPRESSED_SIZE: + return mpq_b->fsize; + case LIBMPQ_FILE_COMPRESSION_TYPE: + if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) { + return LIBMPQ_FILE_COMPRESS_PKWARE; + } + if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) { + return LIBMPQ_FILE_COMPRESS_MULTI; + } + default: + return LIBMPQ_TOOLS_SUCCESS; + } +} + +/* + * This function searches the listfile for the filename. + * On success it returns the filename, otherwiese a name + * like file000001.xxx and if number is out of range it + * returns NULL. + */ +char *libmpq_file_name(mpq_archive *mpq_a, const int number) { + static char tempfile[PATH_MAX]; + + /* check if we are in the range of available files. */ + if (number > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || number < 1) { + return NULL; + } + + /* this is safe because we built a fallback filelist, if something was wrong. */ + sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[number - 1], number); + + return tempfile; +} + +/* + * This function returns the number to the given + * filename. + */ +int libmpq_file_number(mpq_archive *mpq_a, const char *name) { + int i; + char tempfile[PATH_MAX]; + + for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) { + sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i + 1); + if (strncmp(tempfile, name, strlen(name)) == 0) { + + /* if file found return the number */ + return i + 1; + } + } + + /* if no matching entry found return LIBMPQ_EFILE_NOT_FOUND */ + return LIBMPQ_EFILE_NOT_FOUND; +} + +/* + * This function verifies if a given file (by number + * or name) is in the opened mpq archive. On success + * it returns 0, otherwise LIBMPQ_EFILE_NOT_FOUND. + */ +int libmpq_file_check(mpq_archive *mpq_a, void *file, int type) { + int found = 0; + int i; + char tempfile[PATH_MAX]; + + switch (type) { + case LIBMPQ_FILE_TYPE_INT: + + /* check if we are in the range of available files. */ + if (*(int *)file > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || *(int *)file < 1) { + return LIBMPQ_EFILE_NOT_FOUND; + } else { + return LIBMPQ_TOOLS_SUCCESS; + } + case LIBMPQ_FILE_TYPE_CHAR: + for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) { + sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i); + if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) { + + /* if file found break */ + found = 1; + break; + } + } + + /* if a file was found return 0 */ + if (found == 1) { + return LIBMPQ_TOOLS_SUCCESS; + } else { + return LIBMPQ_EFILE_NOT_FOUND; + } + default: + return LIBMPQ_TOOLS_SUCCESS; + } +} + +/* + * This function extracts a file from a MPQ archive + * by the given number. + */ +int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename) { + int blockindex = number; //-1; + int fd = 0; + int i = 0; + char buffer[0x1000]; + //char tempfile[PATH_MAX]; + unsigned int transferred = 1; + mpq_file *mpq_f = NULL; + mpq_block *mpq_b = NULL; + mpq_hash *mpq_h = NULL; + +/* if (number < 1 || number > mpq_a->header->blocktablesize) { + return LIBMPQ_EINV_RANGE; + }*/ +/* + sprintf(tempfile, libmpq_file_name(mpq_a, number)); +*/ + /* check if mpq_f->filename could be written here. */ + fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644); + if (fd == LIBMPQ_EFILE) { + return LIBMPQ_EFILE; + } + + /* search for correct hashtable */ + /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { + if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { + blockindex = (mpq_a->hashtable[i]).blockindex; + mpq_h = &(mpq_a->hashtable[i]); + break; + } + }*/ + + /* check if file was found */ + if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* check if sizes are correct */ + mpq_b = mpq_a->blocktable + blockindex; + if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* check if file exists */ + if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* allocate memory for file structure */ + mpq_f = (mpq_file *)malloc(sizeof(mpq_file)); + if (!mpq_f) { + return LIBMPQ_EALLOCMEM; + } + + /* initialize file structure */ + memset(mpq_f, 0, sizeof(mpq_file)); + mpq_f->fd = fd; + mpq_f->mpq_b = mpq_b; + mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize; + mpq_f->mpq_h = mpq_h; + mpq_f->accessed = FALSE; + mpq_f->blockposloaded = FALSE; + sprintf((char *)mpq_f->filename, filename); + + /* allocate buffers for decompression. */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + + /* + * Allocate buffer for block positions. At the begin of file are stored + * unsigned ints holding positions of each block relative from begin of + * file in the archive. + */ + if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) { + return LIBMPQ_EALLOCMEM; + } + } + + while (transferred > 0) { + transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer)); + if (transferred == 0) { + break; + } else { + mpq_f->accessed = TRUE; + mpq_f->filepos += transferred; + } + + transferred = _write(mpq_f->fd, buffer, transferred); + if (transferred == 0) { + break; + } + } + + _close(fd); + + /* freeing the file structure */ + free(mpq_f); + return LIBMPQ_TOOLS_SUCCESS; +} + +/* + * This function tries to get the filenames for the hashes. It uses + * an internal listfile database and gets the correct listfile from + * some specific archive informations. + */ + +int libmpq_listfile_open(mpq_archive *mpq_a, char file[PATH_MAX]) { + FILE *fp; + //char **filelist; + int i = 0; + //int fl_count; + //int fl_size; + int fl_count_fb; + int fl_size_fb; + int result = LIBMPQ_TOOLS_SUCCESS; + struct stat statbuf; + + /* get file status */ + if (stat(file, &statbuf) < 0) { + result = LIBMPQ_CONF_EFILE_NOT_FOUND; + } + + /* check if file is a filename or directory */ + /*if (S_ISDIR(statbuf.st_mode)) { + + // allocate memory for the file list + filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); + fl_count = 0; + fl_size = LIBMPQ_CONF_FL_INCREMENT; + + // check if it is a valid listfile + if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) { + filelist == NULL; + } + + filelist[fl_count] = NULL; + + // return if no listfile was found + if (filelist == NULL) { + result = LIBMPQ_CONF_EFILE_NOT_FOUND; + } + + for (i = 0; filelist[i]; i++) { + if ((fp = fopen(filelist[i], "r")) != NULL ) { + result = libmpq_read_listfile(mpq_a, fp); + fclose(fp); + } + } + + // freeing the listfile struct + libmpq_free_listfile(filelist); + }*/ + + /* if file is a regular file use it */ + //if (S_ISREG(statbuf.st_mode)) { + + /* if specific listfile was forced. */ + if ((fp = fopen(file, "r")) != NULL ) { + result = libmpq_read_listfile(mpq_a, fp); + fclose(fp); + } else { + result = LIBMPQ_CONF_EFILE_OPEN; + } + //} + + /* if error occured we need to create a fallback filelist. */ + if (mpq_a->mpq_l->mpq_files == NULL) { + + /* allocate memory for the file list */ + mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); + fl_count_fb = 0; + fl_size_fb = LIBMPQ_CONF_FL_INCREMENT; + + for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) { + + /* set the next filelist entry to a copy of the file */ + mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx"); + + /* increase the array size */ + if (fl_count_fb == fl_size_fb) { + mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); + fl_size_fb += LIBMPQ_CONF_FL_INCREMENT; + } + } + mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL; + + /* if no error occurs and no listfile was assigned, we think there was no matching listfile. */ + if (result == 0) { + result = LIBMPQ_CONF_EFILE_NOT_FOUND; + } + } + + return result; +} + +/* + * This function frees the allocated memory for the listfile. + */ +int libmpq_listfile_close(mpq_archive *mpq_a) { + int i = 0; + + /* safety check if we really have a filelist. */ + if (mpq_a->mpq_l->mpq_files != NULL) { + /* freeing the filelist */ + while (mpq_a->mpq_l->mpq_files[i]) { + free(mpq_a->mpq_l->mpq_files[i++]); + } + free(mpq_a->mpq_l->mpq_files); + } + return 0; +} + +int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest) { + int blockindex = number; //-1; + int i = 0; + mpq_file *mpq_f = NULL; + mpq_block *mpq_b = NULL; + int success = 0; + + /*if (number < 1 || number > mpq_a->header->blocktablesize) { + return LIBMPQ_EINV_RANGE; + }*/ + + /* search for correct hashtable */ + /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { + if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { + blockindex = (mpq_a->hashtable[i]).blockindex; + mpq_h = &(mpq_a->hashtable[i]); + break; + } + }*/ + + /* check if file was found */ + if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* check if sizes are correct */ + mpq_b = mpq_a->blocktable + blockindex; + if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* check if file exists */ + if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* allocate memory for file structure */ + mpq_f = (mpq_file*)malloc(sizeof(mpq_file)); + if (!mpq_f) { + return LIBMPQ_EALLOCMEM; + } + + /* initialize file structure */ + memset(mpq_f, 0, sizeof(mpq_file)); + mpq_f->mpq_b = mpq_b; + mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize; + mpq_f->mpq_h = &mpq_h; + mpq_f->accessed = FALSE; + mpq_f->blockposloaded = FALSE; + + /* allocate buffers for decompression. */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + + /* + * Allocate buffer for block positions. At the begin of file are stored + * unsigned ints holding positions of each block relative from begin of + * file in the archive. + */ + if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) { + return LIBMPQ_EALLOCMEM; + } + } + + if(libmpq_file_read_file(mpq_a, mpq_f, 0, (char*)dest, mpq_b->fsize) == mpq_b->fsize) + success = 1; + + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + // Free buffer for block positions + + free(mpq_f->blockpos); + } + /* freeing the file structure */ + free(mpq_f); + return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT; +} diff --git a/contrib/extractor/libmpq/mpq.h b/contrib/extractor/libmpq/mpq.h new file mode 100644 index 000000000..0a136f95f --- /dev/null +++ b/contrib/extractor/libmpq/mpq.h @@ -0,0 +1,225 @@ +/* + * mpq.h -- some default types and defines. + * + * Copyright (C) 2003 Maik Broemme + * + * This source was adepted from the C++ version of StormLib.h and + * StormPort.h included in stormlib. The C++ version belongs to + * the following authors, + * + * Ladislav Zezula + * Marko Friedemann + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: mpq.h,v 1.8 2004/02/12 00:45:50 mbroemme Exp $ + */ + +#ifndef _MPQ_H +#define _MPQ_H + +#include + +#ifndef PATH_MAX + #define PATH_MAX 260 +#endif + + +#define LIBMPQ_MAJOR_VERSION 0 /* Major version number... maybe sometimes we reach version 1 :) */ +#define LIBMPQ_MINOR_VERSION 3 /* Minor version number - increased only for small changes */ +#define LIBMPQ_PATCH_VERSION 0 /* Patchlevel - changed on bugfixes etc... */ + +#define LIBMPQ_TOOLS_SUCCESS 0 /* return value for all functions which success */ +#define LIBMPQ_TOOLS_BUFSIZE 0x500 /* buffer size for the decryption engine */ + +#define LIBMPQ_EFILE -1 /* error on file operation */ +#define LIBMPQ_EFILE_FORMAT -2 /* bad file format */ +#define LIBMPQ_EFILE_CORRUPT -3 /* file corrupt */ +#define LIBMPQ_EFILE_NOT_FOUND -4 /* file in archive not found */ +#define LIBMPQ_EFILE_READ -5 /* Read error in archive */ +#define LIBMPQ_EALLOCMEM -6 /* maybe not enough memory? :) */ +#define LIBMPQ_EFREEMEM -7 /* can not free memory */ +#define LIBMPQ_EINV_RANGE -8 /* Given filenumber is out of range */ +#define LIBMPQ_EHASHTABLE -9 /* error in reading hashtable */ +#define LIBMPQ_EBLOCKTABLE -10 /* error in reading blocktable */ + +#define LIBMPQ_ID_MPQ 0x1A51504D /* MPQ archive header ID ('MPQ\x1A') */ +#define LIBMPQ_HEADER_W3M 0x6D9E4B86 /* special value used by W3M Map Protector */ +#define LIBMPQ_FLAG_PROTECTED 0x00000002 /* Set on protected MPQs (like W3M maps) */ +#define LIBMPQ_HASH_ENTRY_DELETED 0xFFFFFFFE /* Block index for deleted hash entry */ + +#define LIBMPQ_FILE_COMPRESS_PKWARE 0x00000100 /* Compression made by PKWARE Data Compression Library */ +#define LIBMPQ_FILE_COMPRESS_MULTI 0x00000200 /* Multiple compressions */ +#define LIBMPQ_FILE_COMPRESSED 0x0000FF00 /* File is compressed */ +#define LIBMPQ_FILE_EXISTS 0x80000000 /* Set if file exists, reset when the file was deleted */ +#define LIBMPQ_FILE_ENCRYPTED 0x00010000 /* Indicates whether file is encrypted */ +#define LIBMPQ_FILE_HAS_METADATA 0x04000000 + +#define LIBMPQ_FILE_COMPRESSED_SIZE 1 /* MPQ compressed filesize of given file */ +#define LIBMPQ_FILE_UNCOMPRESSED_SIZE 2 /* MPQ uncompressed filesize of given file */ +#define LIBMPQ_FILE_COMPRESSION_TYPE 3 /* MPQ compression type of given file */ +#define LIBMPQ_FILE_TYPE_INT 4 /* file is given by number */ +#define LIBMPQ_FILE_TYPE_CHAR 5 /* file is given by name */ + +#define LIBMPQ_MPQ_ARCHIVE_SIZE 1 /* MPQ archive size */ +#define LIBMPQ_MPQ_HASHTABLE_SIZE 2 /* MPQ archive hashtable size */ +#define LIBMPQ_MPQ_BLOCKTABLE_SIZE 3 /* MPQ archive blocktable size */ +#define LIBMPQ_MPQ_BLOCKSIZE 4 /* MPQ archive blocksize */ +#define LIBMPQ_MPQ_NUMFILES 5 /* Number of files in the MPQ archive */ +#define LIBMPQ_MPQ_COMPRESSED_SIZE 6 /* Compressed archive size */ +#define LIBMPQ_MPQ_UNCOMPRESSED_SIZE 7 /* Uncompressed archive size */ + +#define LIBMPQ_HUFF_DECOMPRESS 0 /* Defines that we want to decompress using huffman trees. */ + +#define LIBMPQ_CONF_EFILE_OPEN -1 /* error if a specific listfile was forced and could not be opened. */ +#define LIBMPQ_CONF_EFILE_CORRUPT -2 /* listfile seems to be corrupt */ +#define LIBMPQ_CONF_EFILE_LIST_CORRUPT -3 /* listfile seems correct, but filelist is broken */ +#define LIBMPQ_CONF_EFILE_NOT_FOUND -4 /* error if no matching listfile found */ +#define LIBMPQ_CONF_EFILE_VERSION -5 /* libmpq version does not match required listfile version */ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +/* +#ifndef min +#define min(a, b) ((a < b) ? a : b) +#endif +*/ + +typedef unsigned int mpq_buffer[LIBMPQ_TOOLS_BUFSIZE]; +typedef int (*DECOMPRESS)(char *, int *, char *, int); +typedef struct { + unsigned long mask; /* Decompression bit */ + DECOMPRESS decompress; /* Decompression function */ +} decompress_table; + +/* MPQ file header */ +typedef struct { + unsigned int id; /* The 0x1A51504D ('MPQ\x1A') signature */ + unsigned int offset; /* Offset of the first file (Relative to MPQ start) */ + unsigned int archivesize; /* Size of MPQ archive */ + unsigned short offsetsc; /* 0000 for SC and BW */ + unsigned short blocksize; /* Size of file block is (0x200 << blockSize) */ + unsigned int hashtablepos; /* File position of hashTable */ + unsigned int blocktablepos; /* File position of blockTable. Each entry has 16 bytes */ + unsigned int hashtablesize; /* Number of entries in hash table */ + unsigned int blocktablesize; /* Number of entries in the block table */ +} mpq_header; +//} __attribute__ ((packed)) mpq_header; + + +/* Hash entry. All files in the archive are searched by their hashes. */ +typedef struct { + unsigned int name1; /* The first two unsigned ints */ + unsigned int name2; /* are the encrypted file name */ + unsigned int locale; /* Locale information. */ + unsigned int blockindex; /* Index to file description block */ +} mpq_hash; + +/* File description block contains informations about the file */ +typedef struct { + unsigned int filepos; /* Block file starting position in the archive */ + unsigned int csize; /* Compressed file size */ + unsigned int fsize; /* Uncompressed file size */ + unsigned int flags; /* Flags */ +} mpq_block; + +/* File handle structure used since Diablo 1.00 (0x38 bytes) */ +typedef struct { + unsigned char filename[PATH_MAX]; /* filename of the actual file in the archive */ + int fd; /* File handle */ + unsigned int seed; /* Seed used for file decrypt */ + unsigned int filepos; /* Current file position */ + unsigned int offset; + unsigned int nblocks; /* Number of blocks in the file (incl. the last noncomplete one) */ + unsigned int *blockpos; /* Position of each file block (only for compressed files) */ + int blockposloaded; /* TRUE if block positions loaded */ + unsigned int offset2; /* (Number of bytes somewhere ?) */ + mpq_hash *mpq_h; /* Hash table entry */ + mpq_block *mpq_b; /* File block pointer */ + + /* Non-Storm.dll members */ + + unsigned int accessed; /* Was something from the file already read? */ +} mpq_file; + +/* List handle structure */ +typedef struct { + unsigned char mpq_version[10]; /* libmpq version required by the listfile */ + unsigned char mpq_name[PATH_MAX]; /* mpq archive name without full path */ + unsigned char mpq_type[20]; /* mpq archive type */ + unsigned char mpq_game[40]; /* blizzard title the file matches */ + unsigned char mpq_game_version[10]; /* game version */ + unsigned char **mpq_files; /* filelist */ +} mpq_list; + +/* Archive handle structure used since Diablo 1.00 */ +typedef struct { + unsigned char filename[PATH_MAX]; /* Opened archive file name */ + int fd; /* File handle */ + unsigned int blockpos; /* Position of loaded block in the file */ + unsigned int blocksize; /* Size of file block */ + unsigned char *blockbuf; /* Buffer (cache) for file block */ + unsigned int bufpos; /* Position in block buffer */ + unsigned int mpqpos; /* MPQ archive position in the file */ + unsigned int filepos; /* Current file pointer */ + unsigned int openfiles; /* Number of open files + 1 */ + mpq_buffer buf; /* MPQ buffer */ + mpq_header *header; /* MPQ file header */ + mpq_hash *hashtable; /* Hash table */ + mpq_block *blocktable; /* Block table */ + + /* Non-Storm.dll members */ + + mpq_list *mpq_l; /* Handle to file list from database */ + + unsigned int flags; /* See LIBMPQ_TOOLS_FLAG_XXXXX */ + unsigned int maxblockindex; /* The highest block table entry */ +} mpq_archive; + +extern char *libmpq_version(); +extern int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename); +extern int libmpq_archive_close(mpq_archive *mpq_a); +extern int libmpq_archive_info(mpq_archive *mpq_a, unsigned int infotype); +//extern int libmpq_file_extract(mpq_archive *mpq_a, const int number); +extern int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const int number); +extern char *libmpq_file_name(mpq_archive *mpq_a, const int number); +extern int libmpq_file_number(mpq_archive *mpq_a, const char *name); +extern int libmpq_file_check(mpq_archive *mpq_a, void *file, int type); +extern int libmpq_listfile_open(mpq_archive *mpq_a, char file[PATH_MAX]); +extern int libmpq_listfile_close(mpq_archive *mpq_a); + +extern int libmpq_pkzip_decompress(char *out_buf, int *out_length, char *in_buf, int in_length); +extern int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_length); +extern int libmpq_huff_decompress(char *out_buf, int *out_length, char *in_buf, int in_length); +extern int libmpq_wave_decompress_stereo(char *out_buf, int *out_length, char *in_buf, int in_length); +extern int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_buf, int in_length); +extern int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length); + +static decompress_table dcmp_table[] = { + {0x08, libmpq_pkzip_decompress}, /* Decompression with Pkware Data Compression Library */ + {0x02, libmpq_zlib_decompress}, /* Decompression with the "zlib" library */ + {0x01, libmpq_huff_decompress}, /* Huffmann decompression */ + {0x80, libmpq_wave_decompress_stereo}, /* WAVE decompression for stereo waves */ + {0x40, libmpq_wave_decompress_mono} /* WAVE decompression for mono waves */ +}; + +int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename); +int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest); +#endif /* _MPQ_H */ diff --git a/contrib/extractor/libmpq/parser.cpp b/contrib/extractor/libmpq/parser.cpp new file mode 100644 index 000000000..b7a70400f --- /dev/null +++ b/contrib/extractor/libmpq/parser.cpp @@ -0,0 +1,294 @@ +/* + * parser.c -- functions used to parse list or config file. + * + * Copyright (C) 2003 Maik Broemme + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: parser.c,v 1.5 2004/02/12 00:47:53 mbroemme Exp $ + */ +#define _CRT_SECURE_NO_DEPRECATE + +#include +#include +#include +#include "mpq.h" +#include "common.h" +#include + +/* + * This function deletes the specified characters, but leaves + * escape sequences unaffected. This means that " would be + * deleted but \" would not. + */ +char *libmpq_conf_delete_char(char *buf, char *chars) { + static char *temp; + char ch; + + temp = buf; + + /* strip out special chars like " */ + while (temp = strpbrk(temp, chars)) { + ch = temp[0]; + memmove(&temp[0], &temp[1], strlen(temp)); + if (ch == '\\') { + temp++; + } + } + + return buf; +} + +/* + * This function parses a line for the value to the given option. It + * return 1 on success and the byte array or 0 and null. + */ +int libmpq_conf_parse_line(char *line, char *search_value, char *return_value, int size) { + int level = 0; + int found = 0; + int i = 0; + int pos = 0; + + /* search value */ + while (*(++line)) { + + /* check for spaces */ + if (!isspace(*line) && level == 1) { + + /* we found our value so break */ + found = 1; + break; + } + + /* check for '=' so the value follows as next parameter */ + if (*line == '=' && level == 0) { + level = 1; + } + } + + /* now search for comment in this line */ + for (i = 0; i < strlen(line); i++) { + if (line[i] == '#') { + pos = i - 1; + break; + } + } + + /* now set end of byte array behind value, but only if comment was found */ + if (pos != 0) { + for (i = pos; i >= 0; i--) { + if (line[i] != ' ' && line[i] != '\t') { + line[i + 1] = '\0'; + break; + } + } + } + + /* now check if line has trailing spaces */ + for (i = strlen(line); i >= 0; i--) { + if (line[i] != ' ' && line[i] != '\t') { + line[i + 1] = '\0'; + break; + } + } + + /* now check if value is quoted with "" and if there is a char behind. */ + for (i = strlen(line); i >= 0; i--) { + if (line[i] == '"') { + line[i + 1] = '\0'; + break; + } + } + + /* return the values */ + strncpy(return_value, line, size); + return found; +} + +/* + * This function returns the value for a given option in the + * listdb or config file. On success it returns 1, otherwise 0. + */ +int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int type, int size) { + char buf[LIBMPQ_CONF_BUFSIZE]; + int found = 0; + int result = LIBMPQ_TOOLS_SUCCESS; + + while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { + char *line; + + buf[strlen(buf) - 1] = '\0'; + + /* skip whitespace */ + for (line = buf; isspace(*line); line++) { + continue; + } + + /* skip empty line */ + if (line[0] == '\0') { + continue; + } + + /* skip comments */ + if (line[0] == '#') { + continue; + } + + /* process the line */ + //if (!strncasecmp(line, search_value, strlen(search_value))) { + if (!strcmp(line, search_value)) { + found = libmpq_conf_parse_line(line, search_value, line, LIBMPQ_CONF_BUFSIZE); + if (found == 1) { + libmpq_conf_delete_char(line, "\"\\"); + + switch (type) { + case LIBMPQ_CONF_TYPE_INT: + + /* if it is no valid number it is safe to return 0 */ + *(int *)return_value = atoi(line); + break; + default: + strncpy((char *)return_value, line, size); + break; + } + + /* value found, so rewind stream */ + break; + } + } + } + + /* if value was not found */ + if (found == 0) { + switch (type) { + case LIBMPQ_CONF_TYPE_INT: + *(int *)return_value = 0; + result = LIBMPQ_CONF_EVALUE_NOT_FOUND; + break; + default: + strncpy((char *)return_value, "", size); + result = LIBMPQ_CONF_EVALUE_NOT_FOUND; + break; + } + } + fseek(fp, 0L, SEEK_SET); + + return result; +} + +/* + * This function returns a pointer to a byte array, with all values + * found in the config file. As second value it returns th number of + * entries in the byte array. On success it returns 1, otherwise 0. + */ +int libmpq_conf_get_array(FILE *fp, char *search_value, char ***filelist, int *entries) { + char buf[LIBMPQ_CONF_BUFSIZE]; + char temp[LIBMPQ_CONF_BUFSIZE]; + int level = 0; + int array_start = 0; + int array_end = 0; + int fl_count; + int fl_size; + int found = 0; + int i = 0; + + *entries = 0; + + /* allocate memory for the file list */ + (*filelist) = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); + fl_count = 0; + fl_size = LIBMPQ_CONF_FL_INCREMENT; + + while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { + char *line; + + buf[strlen(buf) - 1] = '\0'; + + /* skip whitespace */ + for (line = buf; isspace(*line); line++) { + continue; + } + + /* skip empty line */ + if (line[0] == '\0') { + continue; + } + + /* skip comments */ + if (line[0] == '#') { + continue; + } + + /* check for array end ) */ + if (*line == ')') { + array_end = 1; + break; + } + + /* process entries between () */ + if (array_start == 1 && array_end == 0) { + + /* add dummy option to use with libmpq_conf_parse_line() */ + strncpy(temp, "MPQ_BUFFER = ", LIBMPQ_CONF_BUFSIZE); + strncat(temp, line, LIBMPQ_CONF_BUFSIZE); + found = libmpq_conf_parse_line(temp, "MPQ_BUFFER", temp, LIBMPQ_CONF_BUFSIZE); + + if (found == 1) { + libmpq_conf_delete_char(temp, "\"\\"); + + /* set the next filelist entry to a copy of the file */ + (*filelist)[fl_count++] = _strdup(temp); + + /* increase the array size */ + if (fl_count == fl_size) { + (*filelist) = (char **)realloc((*filelist), (fl_size + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); + fl_size += LIBMPQ_CONF_FL_INCREMENT; + } + + /* increase number of entries */ + (*entries)++; + } + } + + /* process the line and search array start */ + //if (!strncasecmp(line, search_value, strlen(search_value))) { + if (!strcmp(line, search_value)) { + + /* search value */ + while (*(++line)) { + + /* check for array start ( */ + if (*line == '(' && level == 1) { + + /* we found our value so break */ + array_start = 1; + break; + } + + /* check for '=' so the value follows as next parameter */ + if (*line == '=' && level == 0) { + level = 1; + } + } + } + } + + /* we got all files, so rewind stream */ + fseek(fp, 0L, SEEK_SET); + + (*filelist)[fl_count] = NULL; + + return found; +} diff --git a/contrib/extractor/libmpq/wave.cpp b/contrib/extractor/libmpq/wave.cpp new file mode 100644 index 000000000..8edc1f7fa --- /dev/null +++ b/contrib/extractor/libmpq/wave.cpp @@ -0,0 +1,185 @@ +/* + * wave.c -- this file contains decompression methods used by Storm.dll + * to decompress wave files. + * + * Copyright (C) 2003 Maik Broemme + * + * This source was adepted from the C++ version of wave.cpp included + * in stormlib. The C++ version belongs to the following authors, + * + * Ladislav Zezula + * Tom Amigo + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "wave.h" + +/* Tables necessary dor decompression */ +static unsigned long wave_table_1503f120[] = { + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, + 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008 +}; + +static unsigned long wave_table_1503f1a0[] = { + 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, + 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F, + 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042, + 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F, + 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133, + 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292, + 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583, + 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0, + 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954, + 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B, + 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462, + 0x00007FFF +}; + +/* + * Decompress a wave file, mono or stereo + * + * Offset: 1500F230 + */ +int libmpq_wave_decompress(unsigned char *out_buf, int out_length, unsigned char *in_buf, int in_length, int channels) { + byte_and_short out; + byte_and_short in; + unsigned char *in_end = in_buf + in_length; /* End on input buffer */ + unsigned long index; + long nr_array1[2]; + long nr_array2[2]; + int count = 0; + + out.pb = out_buf; + in.pb = in_buf; + nr_array1[0] = 0x2C; + nr_array1[1] = 0x2C; + in.pw++; + + /* 15007AD7 */ + for (count = 0; count < channels; count++) { + long temp; + temp = *(short *)in.pw++; + nr_array2[count] = temp; + if (out_length < 2) { + return out.pb - out_buf; + } + *out.pw++ = (unsigned short)temp; + out_length -= 2; + } + index = channels - 1; + while (in.pb < in_end) { + unsigned char one_byte = *in.pb++; + if (channels == 2) { + index = (index == 0) ? 1 : 0; + } + + /* + * Get one byte from input buffer + * 15007B25 + */ + if (one_byte & 0x80) { + /* 15007B32 */ + switch(one_byte & 0x7F) { + case 0: /* 15007B8E */ + if (nr_array1[index] != 0) { + nr_array1[index]--; + } + if (out_length < 2) { + break; + } + *out.pw++ = (unsigned short)nr_array2[index]; + out_length -= 2; + continue; + case 1: /* 15007B72 */ + nr_array1[index] += 8; /* EBX also */ + if (nr_array1[index] > 0x58) { + nr_array1[index] = 0x58; + } + if (channels == 2) { + index = (index == 0) ? 1 : 0; + } + continue; + case 2: + continue; + default: + nr_array1[index] -= 8; + if (nr_array1[index] < 0) { + nr_array1[index] = 0; + } + if (channels != 2) { + continue; + } + index = (index == 0) ? 1 : 0; + continue; + } + } else { + unsigned long temp1 = wave_table_1503f1a0[nr_array1[index]]; /* EDI */ + unsigned long temp2 = temp1 >> in_buf[1]; /* ESI */ + long temp3 = nr_array2[index]; /* ECX */ + if (one_byte & 0x01) { /* EBX = one_byte */ + temp2 += (temp1 >> 0); + } + if (one_byte & 0x02) { + temp2 += (temp1 >> 1); + } + if (one_byte & 0x04) { + temp2 += (temp1 >> 2); + } + if (one_byte & 0x08) { + temp2 += (temp1 >> 3); + } + if (one_byte & 0x10) { + temp2 += (temp1 >> 4); + } + if (one_byte & 0x20) { + temp2 += (temp1 >> 5); + } + if(one_byte & 0x40) { + temp3 -= temp2; + if (temp3 <= (long)0xFFFF8000) { + temp3 = (long)0xFFFF8000; + } + } else { + temp3 += temp2; + if (temp3 >= 0x7FFF) { + temp3 = 0x7FFF; + } + } + nr_array2[index] = temp3; + if (out_length < 2) { + break; + } + + temp2 = nr_array1[index]; + one_byte &= 0x1F; + *out.pw++ = (unsigned short)temp3; + out_length -= 2; + temp2 += wave_table_1503f120[one_byte]; + nr_array1[index] = temp2; + + if (nr_array1[index] < 0) { + nr_array1[index] = 0; + } else { + if (nr_array1[index] > 0x58) { + nr_array1[index] = 0x58; + } + } + } + } + return (out.pb - out_buf); +} diff --git a/contrib/extractor/libmpq/wave.h b/contrib/extractor/libmpq/wave.h new file mode 100644 index 000000000..8920880a0 --- /dev/null +++ b/contrib/extractor/libmpq/wave.h @@ -0,0 +1,37 @@ +/* + * wave.h -- header file for WAVe unplode functions used by mpq-tools. + * + * Copyright (C) 2003 Maik Broemme + * + * This source was adepted from the C++ version of wave.h included + * in stormlib. The C++ version belongs to the following authors, + * + * Ladislav Zezula + * Tom Amigo + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _WAVE_H +#define _WAVE_H + +typedef union { + unsigned short *pw; + unsigned char *pb; +} byte_and_short; + +int libmpq_wave_decompress(unsigned char *out_buf, int out_length, unsigned char *in_buf, int in_length, int channels); + +#endif /* _WAVE_H */ diff --git a/contrib/extractor/libmpq/zconf.h b/contrib/extractor/libmpq/zconf.h new file mode 100644 index 000000000..3cea897ed --- /dev/null +++ b/contrib/extractor/libmpq/zconf.h @@ -0,0 +1,323 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflatePrime z_deflatePrime +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +#define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/contrib/extractor/libmpq/zlib.h b/contrib/extractor/libmpq/zlib.h new file mode 100644 index 000000000..92edf96ff --- /dev/null +++ b/contrib/extractor/libmpq/zlib.h @@ -0,0 +1,1200 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.1, November 17th, 2003 + + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.1" +#define ZLIB_VERNUM 0x1210 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by the in-memory functions is the zlib + format, which is a zlib wrapper documented in RFC 1950, wrapped around a + deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + This library does not provide any functions to write gzip files in memory. + However such functions could be easily written using zlib's deflate function, + the documentation in the gzip RFC, and the examples in gzio.c. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it get to the next deflate block boundary. When decoding the zlib + or gzip format, this will cause inflate() to return immediately after the + header and before the first block. When doing a raw inflate, inflate() will + go ahead and process the first block, and will return when it gets to the end + of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/contrib/extractor/mpq_libmpq.cpp b/contrib/extractor/mpq_libmpq.cpp new file mode 100644 index 000000000..98d114c57 --- /dev/null +++ b/contrib/extractor/mpq_libmpq.cpp @@ -0,0 +1,133 @@ +#include "mpq_libmpq.h" +#include + +ArchiveSet gOpenArchives; + +MPQArchive::MPQArchive(const char* filename) +{ + int result = libmpq_archive_open(&mpq_a, (unsigned char*)filename); + printf("Opening %s\n", filename); + if(result) { + switch(result) { + case LIBMPQ_EFILE : /* error on file operation */ + printf("Error opening archive '%s': File operation Error\n", filename); + break; + case LIBMPQ_EFILE_FORMAT : /* bad file format */ + printf("Error opening archive '%s': Bad file format\n", filename); + break; + case LIBMPQ_EFILE_CORRUPT : /* file corrupt */ + printf("Error opening archive '%s': File corrupt\n", filename); + break; + case LIBMPQ_EFILE_NOT_FOUND : /* file in archive not found */ + printf("Error opening archive '%s': File in archive not found\n", filename); + break; + case LIBMPQ_EFILE_READ : /* Read error in archive */ + printf("Error opening archive '%s': Read error in archive\n", filename); + break; + case LIBMPQ_EALLOCMEM : /* maybe not enough memory? :) */ + printf("Error opening archive '%s': Maybe not enough memory\n", filename); + break; + case LIBMPQ_EFREEMEM : /* can not free memory */ + printf("Error opening archive '%s': Cannot free memory\n", filename); + break; + case LIBMPQ_EINV_RANGE : /* Given filenumber is out of range */ + printf("Error opening archive '%s': Given filenumber is out of range\n", filename); + break; + case LIBMPQ_EHASHTABLE : /* error in reading hashtable */ + printf("Error opening archive '%s': Error in reading hashtable\n", filename); + break; + case LIBMPQ_EBLOCKTABLE : /* error in reading blocktable */ + printf("Error opening archive '%s': Error in reading blocktable\n", filename); + break; + default: + printf("Error opening archive '%s': Unknown error\n", filename); + break; + } + return; + } + gOpenArchives.push_front(this); +} + +void MPQArchive::close() +{ + //gOpenArchives.erase(erase(&mpq_a); + libmpq_archive_close(&mpq_a); +} + +MPQFile::MPQFile(const char* filename): + eof(false), + buffer(0), + pointer(0), + size(0) +{ + for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) + { + mpq_archive &mpq_a = (*i)->mpq_a; + + mpq_hash hash = (*i)->GetHashEntry(filename); + uint32 blockindex = hash.blockindex; + + if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) { + continue; //file not found + } + + int fileno = blockindex; + + //int fileno = libmpq_file_number(&mpq_a, filename); + //if(fileno == LIBMPQ_EFILE_NOT_FOUND) + // continue; + + // Found! + size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, fileno); + // HACK: in patch.mpq some files don't want to open and give 1 for filesize + if (size<=1) { + eof = true; + buffer = 0; + return; + } + buffer = new char[size]; + + //libmpq_file_getdata + libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer); + return; + + } + eof = true; + buffer = 0; +} + +size_t MPQFile::read(void* dest, size_t bytes) +{ + if (eof) return 0; + + size_t rpos = pointer + bytes; + if (rpos > size) { + bytes = size - pointer; + eof = true; + } + + memcpy(dest, &(buffer[pointer]), bytes); + + pointer = rpos; + + return bytes; +} + +void MPQFile::seek(int offset) +{ + pointer = offset; + eof = (pointer >= size); +} + +void MPQFile::seekRelative(int offset) +{ + pointer += offset; + eof = (pointer >= size); +} + +void MPQFile::close() +{ + if (buffer) delete[] buffer; + buffer = 0; + eof = true; +} diff --git a/contrib/extractor/mpq_libmpq.h b/contrib/extractor/mpq_libmpq.h new file mode 100644 index 000000000..542e7b21d --- /dev/null +++ b/contrib/extractor/mpq_libmpq.h @@ -0,0 +1,124 @@ +#define _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_WARNINGS + +#ifndef MPQ_H +#define MPQ_H + +#include "libmpq/mpq.h" +#include +#include +#include +#include +#include + +using namespace std; + +typedef unsigned int uint32; +class MPQArchive +{ + +public: + mpq_archive mpq_a; + + MPQArchive(const char* filename); + void close(); + + uint32 HashString(const char* Input, uint32 Offset) { + uint32 seed1 = 0x7fed7fed; + uint32 seed2 = 0xeeeeeeee; + + for (uint32 i = 0; i < strlen(Input); i++) { + uint32 val = toupper(Input[i]); + seed1 = mpq_a.buf[Offset + val] ^ (seed1 + seed2); + seed2 = val + seed1 + seed2 + (seed2 << 5) + 3; + } + + return seed1; + } + mpq_hash GetHashEntry(const char* Filename) { + uint32 index = HashString(Filename, 0); + index &= mpq_a.header->hashtablesize - 1; + uint32 name1 = HashString(Filename, 0x100); + uint32 name2 = HashString(Filename, 0x200); + + for(uint32 i = index; i < mpq_a.header->hashtablesize; ++i) { + mpq_hash hash = mpq_a.hashtable[i]; + if (hash.name1 == name1 && hash.name2 == name2) return hash; + } + + mpq_hash nullhash; + nullhash.blockindex = 0xFFFFFFFF; + return nullhash; + } + + vector GetFileList() { + vector filelist; + + mpq_hash hash = GetHashEntry("(listfile)"); + uint32 blockindex = hash.blockindex; + + if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) + return filelist; + + uint32 size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, blockindex); + char *buffer = new char[size]; + + libmpq_file_getdata(&mpq_a, hash, blockindex, (unsigned char*)buffer); + + char seps[] = "\n"; + char *token; + + token = strtok( buffer, seps ); + uint32 counter = 0; + while ((token != NULL) && (counter < size)) { + //cout << token << endl; + token[strlen(token) - 1] = 0; + string s = token; + filelist.push_back(s); + counter += strlen(token) + 2; + token = strtok(NULL, seps); + } + + delete buffer; + return filelist; + } +}; +typedef std::deque ArchiveSet; + +class MPQFile +{ + //MPQHANDLE handle; + bool eof; + char *buffer; + size_t pointer,size; + + // disable copying + MPQFile(const MPQFile &f) {} + void operator=(const MPQFile &f) {} + +public: + MPQFile(const char* filename); // filenames are not case sensitive + ~MPQFile() { close(); } + size_t read(void* dest, size_t bytes); + size_t getSize() { return size; } + size_t getPos() { return pointer; } + char* getBuffer() { return buffer; } + char* getPointer() { return buffer + pointer; } + bool isEof() { return eof; } + void seek(int offset); + void seekRelative(int offset); + void close(); +}; + +inline void flipcc(char *fcc) +{ + char t; + t=fcc[0]; + fcc[0]=fcc[3]; + fcc[3]=t; + t=fcc[1]; + fcc[1]=fcc[2]; + fcc[2]=t; +} + +#endif diff --git a/contrib/extractor/release/zlib.lib b/contrib/extractor/release/zlib.lib new file mode 100644 index 000000000..42dded3ce Binary files /dev/null and b/contrib/extractor/release/zlib.lib differ diff --git a/contrib/vmap_assembler/VC71/vmap_assembler.vcproj b/contrib/vmap_assembler/VC71/vmap_assembler.vcproj new file mode 100644 index 000000000..aaaeb4dfc --- /dev/null +++ b/contrib/vmap_assembler/VC71/vmap_assembler.vcproj @@ -0,0 +1,322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/vmap_assembler/VC80/vmap_assembler.vcproj b/contrib/vmap_assembler/VC80/vmap_assembler.vcproj new file mode 100644 index 000000000..3b3a58a05 --- /dev/null +++ b/contrib/vmap_assembler/VC80/vmap_assembler.vcproj @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/vmap_assembler/splitConfig.txt b/contrib/vmap_assembler/splitConfig.txt new file mode 100644 index 000000000..de8fd67bd --- /dev/null +++ b/contrib/vmap_assembler/splitConfig.txt @@ -0,0 +1,17 @@ +# list of map names + +509 #AhnQiraj +469 #BlackwingLair +189 #MonasteryInstances +030 #PVPZone01 +037 #PVPZone02 +033 #Shadowfang +533 #Stratholme Raid +209 #TanarisInstance +309 #Zul'gurub +560 #HillsbradPast +534 #HyjalPast +532 #Karazahn +543 #HellfireRampart +568 #ZulAman +564 #BlackTemple diff --git a/contrib/vmap_assembler/vmap_assembler.cpp b/contrib/vmap_assembler/vmap_assembler.cpp new file mode 100644 index 000000000..233d4ba3c --- /dev/null +++ b/contrib/vmap_assembler/vmap_assembler.cpp @@ -0,0 +1,118 @@ +#include +#include +#include + +#include "TileAssembler.h" + +//======================================================= +// remove last return or LF and tailing SPACE +// remove all char after a # + +void chompAndTrim(std::string& str) +{ + for(unsigned int i=0;i0) { + char lc = str[str.length()-1]; + if(lc == '\r' || lc == '\n' || lc == ' ') { + str = str.substr(0,str.length()-1); + } else { + break; + } + } +} + +//======================================================= +/** +This callback method is called for each model found in the dir file. +return true if it should be included in the vmap +*/ +bool modelNameFilter(char *pName) +{ +#if 0 + bool result; + result = !Wildcard::wildcardfit("*bush[0-9]*", pName); + if(result) result = !Wildcard::wildcardfit("*shrub[0-9]*", pName); + if(result) result = !Wildcard::wildcardfit("*_Bushes_*", pName); + if(result) result = !Wildcard::wildcardfit("*_Bush_*", pName); + if(!result) { + printf("%s",pName); + } +#endif + return true; +} + +//======================================================= +/** +File contains map names that should be split into tiles +A '#' at the beginning of a line defines a comment +*/ + +bool readConfigFile(char *pConffile, VMAP::TileAssembler* pTa) +{ + bool result = false; + char buffer[501]; + FILE *cf = fopen(pConffile, "rb"); + if(cf) { + while(fgets(buffer, 500, cf)) { + std::string name = std::string(buffer); + size_t pos = name.find_first_not_of(' '); + name = name.substr(pos); + chompAndTrim(name); // just to be sure + if(name[0] != '#' && name.size() >0) { // comment? + unsigned int mapId = atoi(name.c_str()); + pTa->addWorldAreaMapId(mapId); + } + } + fclose(cf); + result = true; + } + return(result); +} +//======================================================= +int main(int argc, char* argv[]) +{ + if(argc == 3 || argc == 4) + { + bool ok = true; + char *src = argv[1]; + char *dest = argv[2]; + char *conffile = NULL; + if(argc >= 4) { + conffile = argv[3]; + } + VMAP::TileAssembler* ta = new VMAP::TileAssembler(std::string(src), std::string(dest)); + ta->setModelNameFilterMethod(modelNameFilter); + + /* + All the names in the list are considered to be world maps or huge instances. + These maps will be spilt into tiles in the vmap assemble process + */ + if(conffile != NULL) { + ok = readConfigFile(conffile, ta); + if(!ok) { + printf("Can not open file config file: %s\n", conffile); + } + } + if(ok) { ok = ta->convertWorld(); } + if(ok) { + printf("Ok, all done\n"); + } else { + printf("exit with errors\n"); + return 1; + } + delete ta; + } + else + { + printf("\nusage: %s [config file name]\n", argv[0]); + return 1; + } + return 0; +} diff --git a/contrib/vmap_assembler/vmap_assemblerVC71.sln b/contrib/vmap_assembler/vmap_assemblerVC71.sln new file mode 100644 index 000000000..8fc035419 --- /dev/null +++ b/contrib/vmap_assembler/vmap_assemblerVC71.sln @@ -0,0 +1,23 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmap_assembler", "VC71\vmap_assembler.vcproj", "{572FFF74-480C-4472-8ABF-81733BB4049D}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug.ActiveCfg = Debug|Win32 + {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug.Build.0 = Debug|Win32 + {572FFF74-480C-4472-8ABF-81733BB4049D}.Release.ActiveCfg = Release|Win32 + {572FFF74-480C-4472-8ABF-81733BB4049D}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/contrib/vmap_assembler/vmap_assemblerVC80.sln b/contrib/vmap_assembler/vmap_assemblerVC80.sln new file mode 100644 index 000000000..66489bd0a --- /dev/null +++ b/contrib/vmap_assembler/vmap_assemblerVC80.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmap_assembler", "VC80\vmap_assembler.vcproj", "{572FFF74-480C-4472-8ABF-81733BB4049D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.ActiveCfg = Debug|Win32 + {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.Build.0 = Debug|Win32 + {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.ActiveCfg = Release|Win32 + {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/vmap_debugger/G3D/AABSPTree.h b/contrib/vmap_debugger/G3D/AABSPTree.h new file mode 100644 index 000000000..543f06a88 --- /dev/null +++ b/contrib/vmap_debugger/G3D/AABSPTree.h @@ -0,0 +1,1620 @@ +/** + @file AABSPTree.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2004-01-11 + @edited 2007-02-16 + + Copyright 2000-2007, Morgan McGuire. + All rights reserved. + + */ + +#ifndef G3D_AABSPTREE_H +#define G3D_AABSPTREE_H + +#include "VMapTools.h" + +#include "G3D/platform.h" +#include "G3D/Array.h" +#include "G3D/Table.h" +#include "G3D/Vector3.h" +#include "G3D/AABox.h" +#include "G3D/Sphere.h" +#include "G3D/Box.h" +#include "G3D/Triangle.h" +#include "G3D/Ray.h" +#include "G3D/GCamera.h" +#if 0 +#include "G3D/BinaryInput.h" +#include "G3D/BinaryOutput.h" +#endif +#include "G3D/CollisionDetection.h" +#include "G3D/GCamera.h" +#include + +// If defined, in debug mode the tree is checked for consistency +// as a way of detecting corruption due to implementation bugs +// #define VERIFY_TREE + +inline void getBounds(const G3D::Vector3& v, G3D::AABox& out) { + out = G3D::AABox(v); +} + + +inline void getBounds(const G3D::AABox& a, G3D::AABox& out) { + out = a; +} + +inline void getBounds(const G3D::Sphere& s, G3D::AABox& out) { + s.getBounds(out); +} + + +inline void getBounds(const G3D::Box& b, G3D::AABox& out) { + b.getBounds(out); +} + + +inline void getBounds(const G3D::Triangle& t, G3D::AABox& out) { + t.getBounds(out); +} + + + +inline void getBounds(const G3D::Vector3* v, G3D::AABox& out) { + out = G3D::AABox(*v); +} + + +inline void getBounds(const G3D::AABox* a, G3D::AABox& out) { + getBounds(*a, out); +} + +inline void getBounds(const G3D::Sphere* s, G3D::AABox& out) { + s->getBounds(out); +} + + +inline void getBounds(const G3D::Box* b, G3D::AABox& out) { + b->getBounds(out); +} + +inline void getBounds(const G3D::Triangle* t, G3D::AABox& out) { + t->getBounds(out); +} +namespace G3D { + namespace _internal { + + /** + Wraps a pointer value so that it can be treated as the instance itself; + convenient for inserting pointers into a Table but using the + object equality instead of pointer equality. + */ + template + class Indirector { + public: + Type* handle; + + inline Indirector(Type* h) : handle(h) {} + + inline Indirector() : handle(NULL) {} + + /** Returns true iff the values referenced by the handles are equivalent. */ + inline bool operator==(const Indirector& m) { + return *handle == *(m.handle); + } + + inline bool operator==(const Type& m) { + return *handle == m; + } + + inline size_t hashCode() const { + return handle->hashCode(); + } + }; + } // namespace internal +} // namespace G3D + +template +struct GHashCode > +{ + size_t operator()(const G3D::_internal::Indirector& key) const { return key.hashCode(); } +}; + +namespace G3D { + +/** + A set that supports spatial queries using an axis-aligned + BSP tree for speed. + + AABSPTree allows you to quickly find objects in 3D that lie within + a box or along a ray. For large sets of objects it is much faster + than testing each object for a collision. + + AABSPTree is as powerful as but more general than a Quad Tree, Oct + Tree, or KD Tree, but less general than an unconstrained BSP tree + (which is much slower to create). + + Internally, objects + are arranged into an axis-aligned BSP-tree according to their + axis-aligned bounds. This increases the cost of insertion to + O(log n) but allows fast overlap queries. + + Template Parameters +
The template parameter T must be one for which + the following functions are all overloaded: + +

void ::getBounds(const T&, G3D::AABox&); +

bool ::operator==(const T&, const T&); +
unsigned int ::hashCode(const T&); +
T::T(); (public constructor of no arguments) + + G3D provides these for common classes like G3D::Vector3 and G3D::Sphere. + If you use a custom class, or a pointer to a custom class, you will need + to define those functions. + + Moving %Set Members +
It is important that objects do not move without updating the + AABSPTree. If the axis-aligned bounds of an object are about + to change, AABSPTree::remove it before they change and + AABSPTree::insert it again afterward. For objects + where the hashCode and == operator are invariant with respect + to the 3D position, + you can use the AABSPTree::update method as a shortcut to + insert/remove an object in one step after it has moved. + + + Note: Do not mutate any value once it has been inserted into AABSPTree. Values + are copied interally. All AABSPTree iterators convert to pointers to constant + values to reinforce this. + + If you want to mutate the objects you intend to store in a AABSPTree + simply insert pointers to your objects instead of the objects + themselves, and ensure that the above operations are defined. (And + actually, because values are copied, if your values are large you may + want to insert pointers anyway, to save space and make the balance + operation faster.) + + Dimensions + Although designed as a 3D-data structure, you can use the AABSPTree + for data distributed along 2 or 1 axes by simply returning bounds + that are always zero along one or more dimensions. + +*/ +namespace _AABSPTree { + + /** Wrapper for a value that includes a cache of its bounds. + Except for the test value used in a set-query operation, there + is only ever one instance of the handle associated with any + value and the memberTable and Nodes maintain pointers to that + heap-allocated value. + */ + template + class Handle { + public: + /** The bounds of each object are constrained to AABox::maxFinite */ + AABox bounds; + + /** Center of bounds. We cache this value to avoid recomputing it + during the median sort, and because MSVC 6 std::sort goes into + an infinite loop if we compute the midpoint on the fly (possibly + a floating point roundoff issue, where B() {} + + inline Handle(const TValue& v) : value(v) { + getBounds(v, bounds); + bounds = bounds.intersect(AABox::maxFinite()); + center = bounds.center(); + } + + inline bool operator==(const Handle& other) const { + return (*value).operator==(*other.value); + } + + inline size_t hashCode() const { + return value->hashCode(); + } + }; + + template<> + class Handle { + public: + /** The bounds of each object are constrained to AABox::maxFinite */ + AABox bounds; + + /** Center of bounds. We cache this value to avoid recomputing it + during the median sort, and because MSVC 6 std::sort goes into + an infinite loop if we compute the midpoint on the fly (possibly + a floating point roundoff issue, where B() {} + + inline Handle(const Triangle& v) : value(v) { + getBounds(v, bounds); + bounds = bounds.intersect(AABox::maxFinite()); + center = bounds.center(); + } + + inline bool operator==(const Handle& other) const { + return value.operator==(other.value); + } + + inline size_t hashCode() const { + return value.hashCode(); + } + }; +} + +template class AABSPTree { +protected: +public: + + + /** Returns the bounds of the sub array. Used by makeNode. */ + static AABox computeBounds( + const Array<_AABSPTree::Handle*>& point, + int beginIndex, + int endIndex) { + + Vector3 lo = Vector3::inf(); + Vector3 hi = -lo; + + for (int p = beginIndex; p <= endIndex; ++p) { + lo = lo.min(point[p]->bounds.low()); + hi = hi.max(point[p]->bounds.high()); + } + + return AABox(lo, hi); + } + + /** Compares centers */ + class CenterComparator { + public: + Vector3::Axis sortAxis; + + CenterComparator(Vector3::Axis a) : sortAxis(a) {} + + inline int operator()(_AABSPTree::Handle* A, const _AABSPTree::Handle* B) const { + float a = A->center[sortAxis]; + float b = B->center[sortAxis]; + + if (a < b) { + return 1; + } else if (a > b) { + return -1; + } else { + return 0; + } + } + }; + + + /** Compares bounds for strict >, <, or overlap*/ + class BoundsComparator { + public: + Vector3::Axis sortAxis; + + BoundsComparator(Vector3::Axis a) : sortAxis(a) {} + + inline int operator()(_AABSPTree::Handle* A, const _AABSPTree::Handle* B) const { + const AABox& a = A->bounds; + const AABox& b = B->bounds; + + if (a.high()[sortAxis] < b.low()[sortAxis]) { + return 1; + } else if (a.low()[sortAxis] > b.high()[sortAxis]) { + return -1; + } else { + return 0; + } + } + }; + + + /** Compares bounds to the sort location */ + class Comparator { + public: + Vector3::Axis sortAxis; + float sortLocation; + + Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {} + + inline int operator()(_AABSPTree::Handle* ignore, const _AABSPTree::Handle* handle) const { + const AABox& box = handle->bounds; + debugAssert(ignore == NULL); + + if (box.high()[sortAxis] < sortLocation) { + // Box is strictly below the sort location + return -1; + } else if (box.low()[sortAxis] > sortLocation) { + // Box is strictly above the sort location + return 1; + } else { + // Box overlaps the sort location + return 0; + } + } + }; + + // Using System::malloc with this class provided no speed improvement. + class Node { + public: + + /** Spatial bounds on all values at this node and its children, based purely on + the parent's splitting planes. May be infinite. */ + AABox splitBounds; + + Vector3::Axis splitAxis; + + /** Location along the specified axis */ + float splitLocation; + + /** child[0] contains all values strictly + smaller than splitLocation along splitAxis. + + child[1] contains all values strictly + larger. + + Both may be NULL if there are not enough + values to bother recursing. + */ + Node* child[2]; + + /** Array of values at this node (i.e., values + straddling the split plane + all values if + this is a leaf node). + + This is an array of pointers because that minimizes + data movement during tree building, which accounts + for about 15% of the time cost of tree building. + */ + Array<_AABSPTree::Handle * > valueArray; + + /** For each object in the value array, a copy of its bounds. + Packing these into an array at the node level + instead putting them in the valueArray improves + cache coherence, which is about a 3x performance + increase when performing intersection computations. + */ + Array boundsArray; + + /** Creates node with NULL children */ + Node() { + splitAxis = Vector3::X_AXIS; + splitLocation = 0; + splitBounds = AABox(-Vector3::inf(), Vector3::inf()); + for (int i = 0; i < 2; ++i) { + child[i] = NULL; + } + } + + /** + Doesn't clone children. + */ + Node(const Node& other) : valueArray(other.valueArray), boundsArray(other.boundsArray) { + splitAxis = other.splitAxis; + splitLocation = other.splitLocation; + splitBounds = other.splitBounds; + for (int i = 0; i < 2; ++i) { + child[i] = NULL; + } + } + + /** Copies the specified subarray of pt into point, NULLs the children. + Assumes a second pass will set splitBounds. */ + Node(const Array<_AABSPTree::Handle * >& pt) : valueArray(pt) { + splitAxis = Vector3::X_AXIS; + splitLocation = 0; + for (int i = 0; i < 2; ++i) { + child[i] = NULL; + } + + boundsArray.resize(valueArray.size()); + for (int i = 0; i < valueArray.size(); ++i) { + boundsArray[i] = valueArray[i]->bounds; + } + } + + /** Deletes the children (but not the values) */ + ~Node() { + for (int i = 0; i < 2; ++i) { + delete child[i]; + } + } + + /** Returns true if this node is a leaf (no children) */ + inline bool isLeaf() const { + return (child[0] == NULL) && (child[1] == NULL); + } + + + /** + Recursively appends all handles and children's handles + to the array. + */ + void getHandles(Array<_AABSPTree::Handle * >& handleArray) const { + handleArray.append(valueArray); + for (int i = 0; i < 2; ++i) { + if (child[i] != NULL) { + child[i]->getHandles(handleArray); + } + } + } + + void verifyNode(const Vector3& lo, const Vector3& hi) { + // debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n", + // splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z); + + debugAssert(lo == splitBounds.low()); + debugAssert(hi == splitBounds.high()); + + for (int i = 0; i < valueArray.length(); ++i) { + const AABox& b = valueArray[i]->bounds; + debugAssert(b == boundsArray[i]); + + for(int axis = 0; axis < 3; ++axis) { + debugAssert(b.low()[axis] <= b.high()[axis]); + debugAssert(b.low()[axis] >= lo[axis]); + debugAssert(b.high()[axis] <= hi[axis]); + } + } + + if (child[0] || child[1]) { + debugAssert(lo[splitAxis] < splitLocation); + debugAssert(hi[splitAxis] > splitLocation); + } + + Vector3 newLo = lo; + newLo[splitAxis] = splitLocation; + Vector3 newHi = hi; + newHi[splitAxis] = splitLocation; + + if (child[0] != NULL) { + child[0]->verifyNode(lo, newHi); + } + + if (child[1] != NULL) { + child[1]->verifyNode(newLo, hi); + } + } + +#if 0 + /** + Stores the locations of the splitting planes (the structure but not the content) + so that the tree can be quickly rebuilt from a previous configuration without + calling balance. + */ + static void serializeStructure(const Node* n, BinaryOutput& bo) { + if (n == NULL) { + bo.writeUInt8(0); + } else { + bo.writeUInt8(1); + n->splitBounds.serialize(bo); + serialize(n->splitAxis, bo); + bo.writeFloat32(n->splitLocation); + for (int c = 0; c < 2; ++c) { + serializeStructure(n->child[c], bo); + } + } + } + + /** Clears the member table */ + static Node* deserializeStructure(BinaryInput& bi) { + if (bi.readUInt8() == 0) { + return NULL; + } else { + Node* n = new Node(); + n->splitBounds.deserialize(bi); + deserialize(n->splitAxis, bi); + n->splitLocation = bi.readFloat32(); + for (int c = 0; c < 2; ++c) { + n->child[c] = deserializeStructure(bi); + } + } + } +#endif + /** Returns the deepest node that completely contains bounds. */ + Node* findDeepestContainingNode(const AABox& bounds) { + + // See which side of the splitting plane the bounds are on + if (bounds.high()[splitAxis] < splitLocation) { + // Bounds are on the low side. Recurse into the child + // if it exists. + if (child[0] != NULL) { + return child[0]->findDeepestContainingNode(bounds); + } + } else if (bounds.low()[splitAxis] > splitLocation) { + // Bounds are on the high side, recurse into the child + // if it exists. + if (child[1] != NULL) { + return child[1]->findDeepestContainingNode(bounds); + } + } + + // There was no containing child, so this node is the + // deepest containing node. + return this; + } + + + /** Appends all members that intersect the box. + If useSphere is true, members that pass the box test + face a second test against the sphere. */ + void getIntersectingMembers( + const AABox& box, + const Sphere& sphere, + Array& members, + bool useSphere) const { + + // Test all values at this node + for (int v = 0; v < boundsArray.size(); ++v) { + const AABox& bounds = boundsArray[v]; + if (bounds.intersects(box) && + (! useSphere || bounds.intersects(sphere))) { + members.append(valueArray[v]->value); + } + } + + // If the left child overlaps the box, recurse into it + if ((child[0] != NULL) && (box.low()[splitAxis] < splitLocation)) { + child[0]->getIntersectingMembers(box, sphere, members, useSphere); + } + + // If the right child overlaps the box, recurse into it + if ((child[1] != NULL) && (box.high()[splitAxis] > splitLocation)) { + child[1]->getIntersectingMembers(box, sphere, members, useSphere); + } + } + + /** + Recurse through the tree, assigning splitBounds fields. + */ + void assignSplitBounds(const AABox& myBounds) { + splitBounds = myBounds; + + AABox childBounds[2]; + myBounds.split(splitAxis, splitLocation, childBounds[0], childBounds[1]); + +# if defined(G3D_DEBUG) && defined(VERIFY_TREE) + // Verify the split + for (int v = 0; v < boundsArray.size(); ++v) { + const AABox& bounds = boundsArray[v]; + debugAssert(myBounds.contains(bounds)); + } +# endif + + for (int c = 0; c < 2; ++c) { + if (child[c]) { + child[c]->assignSplitBounds(childBounds[c]); + } + } + } + + /** Returns true if the ray intersects this node */ + bool intersects(const Ray& ray, float distance) const { + // See if the ray will ever hit this node or its children + Vector3 location; + bool alreadyInsideBounds = false; + bool rayWillHitBounds = + VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox( + ray.origin, ray.direction, splitBounds, location, alreadyInsideBounds); + + bool canHitThisNode = (alreadyInsideBounds || + (rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance)))); + + return canHitThisNode; + } + + template + void intersectRay( + const Ray& ray, + RayCallback& intersectCallback, + float& distance, + bool pStopAtFirstHit, + bool intersectCallbackIsFast) const { + float enterDistance = distance; + + if (! intersects(ray, distance)) { + // The ray doesn't hit this node, so it can't hit the children of the node. + return; + } + + // Test for intersection against every object at this node. + for (int v = 0; v < valueArray.size(); ++v) { + bool canHitThisObject = true; + + if (! intersectCallbackIsFast) { + // See if + Vector3 location; + const AABox& bounds = boundsArray[v]; + bool alreadyInsideBounds = false; + bool rayWillHitBounds = + VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox( + ray.origin, ray.direction, bounds, location, alreadyInsideBounds); + + canHitThisObject = (alreadyInsideBounds || + (rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance)))); + } + + if (canHitThisObject) { + // It is possible that this ray hits this object. Look for the intersection using the + // callback. + const T& value = valueArray[v]->value; + intersectCallback(ray, value, pStopAtFirstHit, distance); + } + if(pStopAtFirstHit && distance < enterDistance) + return; + } + + // There are three cases to consider next: + // + // 1. the ray can start on one side of the splitting plane and never enter the other, + // 2. the ray can start on one side and enter the other, and + // 3. the ray can travel exactly down the splitting plane + + enum {NONE = -1}; + int firstChild = NONE; + int secondChild = NONE; + + if (ray.origin[splitAxis] < splitLocation) { + + // The ray starts on the small side + firstChild = 0; + + if (ray.direction[splitAxis] > 0) { + // The ray will eventually reach the other side + secondChild = 1; + } + + } else if (ray.origin[splitAxis] > splitLocation) { + + // The ray starts on the large side + firstChild = 1; + + if (ray.direction[splitAxis] < 0) { + secondChild = 0; + } + } else { + // The ray starts on the splitting plane + if (ray.direction[splitAxis] < 0) { + // ...and goes to the small side + firstChild = 0; + } else if (ray.direction[splitAxis] > 0) { + // ...and goes to the large side + firstChild = 1; + } + } + + // Test on the side closer to the ray origin. + if ((firstChild != NONE) && child[firstChild]) { + child[firstChild]->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast); + if(pStopAtFirstHit && distance < enterDistance) + return; + } + + if (ray.direction[splitAxis] != 0) { + // See if there was an intersection before hitting the splitting plane. + // If so, there is no need to look on the far side and recursion terminates. + float distanceToSplittingPlane = (splitLocation - ray.origin[splitAxis]) / ray.direction[splitAxis]; + if (distanceToSplittingPlane > distance) { + // We aren't going to hit anything else before hitting the splitting plane, + // so don't bother looking on the far side of the splitting plane at the other + // child. + return; + } + } + + // Test on the side farther from the ray origin. + if ((secondChild != NONE) && child[secondChild]) { + child[secondChild]->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast); + } + + } + }; + + + /** + Recursively subdivides the subarray. + + Clears the source array as soon as it is no longer needed. + + Call assignSplitBounds() on the root node after making a tree. + */ + Node* makeNode( + Array<_AABSPTree::Handle * >& source, + int valuesPerNode, + int numMeanSplits, + Array<_AABSPTree::Handle * >& temp) { + + Node* node = NULL; + + if (source.size() <= valuesPerNode) { + // Make a new leaf node + node = new Node(source); + + // Set the pointers in the memberTable + for (int i = 0; i < source.size(); ++i) { + memberTable.set(Member(source[i]), node); + } + source.clear(); + + } else { + // Make a new internal node + node = new Node(); + + const AABox bounds = computeBounds(source, 0, source.size() - 1); + const Vector3 extent = bounds.high() - bounds.low(); + + Vector3::Axis splitAxis = extent.primaryAxis(); + + float splitLocation; + + // Arrays for holding the children + Array<_AABSPTree::Handle * > lt, gt; + + if (numMeanSplits <= 0) { + + source.medianPartition(lt, node->valueArray, gt, temp, CenterComparator(splitAxis)); + + // Choose the split location to be the center of whatever fell in the center + splitLocation = node->valueArray[0]->center[splitAxis]; + + // Some of the elements in the lt or gt array might really overlap the split location. + // Move them as needed. + for (int i = 0; i < lt.size(); ++i) { + const AABox& bounds = lt[i]->bounds; + if ((bounds.low()[splitAxis] <= splitLocation) && (bounds.high()[splitAxis] >= splitLocation)) { + node->valueArray.append(lt[i]); + // Remove this element and process the new one that + // is swapped in in its place. + lt.fastRemove(i); --i; + } + } + + for (int i = 0; i < gt.size(); ++i) { + const AABox& bounds = gt[i]->bounds; + if ((bounds.low()[splitAxis] <= splitLocation) && (bounds.high()[splitAxis] >= splitLocation)) { + node->valueArray.append(gt[i]); + // Remove this element and process the new one that + // is swapped in in its place. + gt.fastRemove(i); --i; + } + } + + if ((node->valueArray.size() > (source.size() / 2)) && + (source.size() > 6)) { + // This was a bad partition; we ended up putting the splitting plane right in the middle of most of the + // objects. We could try to split on a different axis, or use a different partition (e.g., the extents mean, + // or geometric mean). This implementation falls back on the extents mean, since that case is already handled + // below. + numMeanSplits = 1; + } + } + + // Note: numMeanSplits may have been increased by the code in the previous case above in order to + // force a re-partition. + + if (numMeanSplits > 0) { + // Split along the mean + splitLocation = (bounds.high()[splitAxis] + + bounds.low()[splitAxis]) / 2.0; + + source.partition(NULL, lt, node->valueArray, gt, Comparator(splitAxis, splitLocation)); + + // The Comparator ensures that elements are strictly on the correct side of the split + } + + +# if defined(G3D_DEBUG) && defined(VERIFY_TREE) + debugAssert(lt.size() + node->valueArray.size() + gt.size() == source.size()); + // Verify that all objects ended up on the correct side of the split. + // (i.e., make sure that the Array partition was correct) + for (int i = 0; i < lt.size(); ++i) { + const AABox& bounds = lt[i]->bounds; + debugAssert(bounds.high()[splitAxis] < splitLocation); + } + + for (int i = 0; i < gt.size(); ++i) { + const AABox& bounds = gt[i]->bounds; + debugAssert(bounds.low()[splitAxis] > splitLocation); + } + + for (int i = 0; i < node->valueArray.size(); ++i) { + const AABox& bounds = node->valueArray[i]->bounds; + debugAssert(bounds.high()[splitAxis] >= splitLocation); + debugAssert(bounds.low()[splitAxis] <= splitLocation); + } +# endif + + // The source array is no longer needed + source.clear(); + + node->splitAxis = splitAxis; + node->splitLocation = splitLocation; + + // Update the bounds array and member table + node->boundsArray.resize(node->valueArray.size()); + for (int i = 0; i < node->valueArray.size(); ++i) { + _AABSPTree::Handle * v = node->valueArray[i]; + node->boundsArray[i] = v->bounds; + memberTable.set(Member(v), node); + } + + if (lt.size() > 0) { + node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp); + } + + if (gt.size() > 0) { + node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp); + } + + } + + return node; + } + + /** + Recursively clone the passed in node tree, setting + pointers for members in the memberTable as appropriate. + called by the assignment operator. + */ + Node* cloneTree(Node* src) { + Node* dst = new Node(*src); + + // Make back pointers + for (int i = 0; i < dst->valueArray.size(); ++i) { + memberTable.set(Member(dst->valueArray[i]), dst); + } + + // Clone children + for (int i = 0; i < 2; ++i) { + if (src->child[i] != NULL) { + dst->child[i] = cloneTree(src->child[i]); + } + } + + return dst; + } + + /** + Wrapper for a Handle; used to create a memberTable that acts like Table but + stores only Handle* internally to avoid memory copies. + */ + typedef _internal::Indirector<_AABSPTree::Handle > Member; + + typedef Table MemberTable; + + /** Maps members to the node containing them */ + MemberTable memberTable; + + Node* root; + +public: + + /** To construct a balanced tree, insert the elements and then call + AABSPTree::balance(). */ + AABSPTree() : root(NULL) {} + + + AABSPTree(const AABSPTree& src) : root(NULL) { + *this = src; + } + + + AABSPTree& operator=(const AABSPTree& src) { + delete root; + // Clone tree takes care of filling out the memberTable. + root = cloneTree(src.root); + return *this; + } + + + ~AABSPTree() { + clear(); + } + + /** + Throws out all elements of the set. + */ + void clear() { + typedef typename Table<_internal::Indirector<_AABSPTree::Handle >, Node* >::Iterator It; + + // Delete all handles stored in the member table + It cur = memberTable.begin(); + It end = memberTable.end(); + while (cur != end) { + delete cur->key.handle; + cur->key.handle = NULL; + ++cur; + } + memberTable.clear(); + + // Delete the tree structure itself + delete root; + root = NULL; + } + + size_t size() const { + return memberTable.size(); + } + + /** + Inserts an object into the set if it is not + already present. O(log n) time. Does not + cause the tree to be balanced. + */ + void insert(const T& value) { + if (contains(value)) { + // Already in the set + return; + } + + _AABSPTree::Handle* h = new _AABSPTree::Handle(value); + + if (root == NULL) { + // This is the first node; create a root node + root = new Node(); + } + + Node* node = root->findDeepestContainingNode(h->bounds); + + // Insert into the node + node->valueArray.append(h); + node->boundsArray.append(h->bounds); + + // Insert into the node table + Member m(h); + memberTable.set(m, node); + } + + /** Inserts each elements in the array in turn. If the tree + begins empty (no structure and no elements), this is faster + than inserting each element in turn. You still need to balance + the tree at the end.*/ + void insert(const Array& valueArray) { + if (root == NULL) { + // Optimized case for an empty tree; don't bother + // searching or reallocating the root node's valueArray + // as we incrementally insert. + root = new Node(); + root->valueArray.resize(valueArray.size()); + root->boundsArray.resize(root->valueArray.size()); + for (int i = 0; i < valueArray.size(); ++i) { + // Insert in opposite order so that we have the exact same + // data structure as if we inserted each (i.e., order is reversed + // from array). + _AABSPTree::Handle* h = new _AABSPTree::Handle(valueArray[i]); + int j = valueArray.size() - i - 1; + root->valueArray[j] = h; + root->boundsArray[j] = h->bounds; + memberTable.set(Member(h), root); + } + + } else { + // Insert at appropriate tree depth. + for (int i = 0; i < valueArray.size(); ++i) { + insert(valueArray[i]); + } + } + } + + + /** + Returns true if this object is in the set, otherwise + returns false. O(1) time. + */ + bool contains(const T& value) { + // Temporarily create a handle and member + _AABSPTree::Handle h(value); + return memberTable.containsKey(Member(&h)); + } + + + /** + Removes an object from the set in O(1) time. + It is an error to remove members that are not already + present. May unbalance the tree. + + Removing an element never causes a node (split plane) to be removed... + nodes are only changed when the tree is rebalanced. This behavior + is desirable because it allows the split planes to be serialized, + and then deserialized into an empty tree which can be repopulated. + */ + void remove(const T& value) { + debugAssertM(contains(value), + "Tried to remove an element from a " + "AABSPTree that was not present"); + + // Get the list of elements at the node + _AABSPTree::Handle h(value); + Member m(&h); + + Array<_AABSPTree::Handle * >& list = memberTable[m]->valueArray; + + _AABSPTree::Handle* ptr = NULL; + + // Find the element and remove it + for (int i = list.length() - 1; i >= 0; --i) { + if (list[i]->value == value) { + // This was the element. Grab the pointer so that + // we can delete it below + ptr = list[i]; + + // Remove the handle from the node + list.fastRemove(i); + + // Remove the corresponding bounds + memberTable[m]->boundsArray.fastRemove(i); + break; + } + } + + // Remove the member + memberTable.remove(m); + + // Delete the handle data structure + delete ptr; + ptr = NULL; + } + + + /** + If the element is in the set, it is removed. + The element is then inserted. + + This is useful when the == and hashCode methods + on T are independent of the bounds. In + that case, you may call update(v) to insert an + element for the first time and call update(v) + again every time it moves to keep the tree + up to date. + */ + void update(const T& value) { + if (contains(value)) { + remove(value); + } + insert(value); + } + + + /** + Rebalances the tree (slow). Call when objects + have moved substantially from their original positions + (which unbalances the tree and causes the spatial + queries to be slow). + + @param valuesPerNode Maximum number of elements to put at + a node. + + @param numMeanSplits numMeanSplits = 0 gives a + fully axis aligned BSP-tree, where the balance operation attempts to balance + the tree so that every splitting plane has an equal number of left + and right children (i.e. it is a median split along that axis). + This tends to maximize average performance. + + You can override this behavior by + setting a number of mean (average) splits. numMeanSplits = MAX_INT + creates a full oct-tree, which tends to optimize peak performance at the expense of + average performance. It tends to have better clustering behavior when + members are not uniformly distributed. + */ + void balance(int valuesPerNode = 5, int numMeanSplits = 3) { + if (root == NULL) { + // Tree is empty + return; + } + + // Get all handles and delete the old tree structure + Node* oldRoot = root; + for (int c = 0; c < 2; ++c) { + if (root->child[c] != NULL) { + root->child[c]->getHandles(root->valueArray); + + // Delete the child; this will delete all structure below it + delete root->child[c]; + root->child[c] = NULL; + } + } + + Array<_AABSPTree::Handle * > temp; + // Make a new root. Work with a copy of the value array because + // makeNode clears the source array as it progresses + Array<_AABSPTree::Handle * > copy(oldRoot->valueArray); + root = makeNode(copy, valuesPerNode, numMeanSplits, temp); + + // Throw away the old root node + delete oldRoot; + oldRoot = NULL; + + // Walk the tree, assigning splitBounds. We start with unbounded + // space. This will override the current member table. + root->assignSplitBounds(AABox::maxFinite()); + +# ifdef _DEBUG + // Ensure that the balanced tree is till correct + root->verifyNode(Vector3::minFinite(), Vector3::maxFinite()); +# endif + } + +protected: + + /** + @param parentMask The mask that this node returned from culledBy. + */ + static void getIntersectingMembers( + const Array& plane, + Array& members, + Node* node, + uint32 parentMask) { + + int dummy; + + if (parentMask == 0) { + // None of these planes can cull anything + for (int v = node->valueArray.size() - 1; v >= 0; --v) { + members.append(node->valueArray[v]->value); + } + + // Iterate through child nodes + for (int c = 0; c < 2; ++c) { + if (node->child[c]) { + getIntersectingMembers(plane, members, node->child[c], 0); + } + } + } else { + + // Test values at this node against remaining planes + for (int v = node->boundsArray.size() - 1; v >= 0; --v) { + if (! node->boundsArray[v].culledBy(plane, dummy, parentMask)) { + members.append(node->valueArray[v]->value); + } + } + + uint32 childMask = 0xFFFFFF; + + // Iterate through child nodes + for (int c = 0; c < 2; ++c) { + if (node->child[c] && + ! node->child[c]->splitBounds.culledBy(plane, dummy, parentMask, childMask)) { + // This node was not culled + getIntersectingMembers(plane, members, node->child[c], childMask); + } + } + } + } + +public: + + /** + Returns all members inside the set of planes. + @param members The results are appended to this array. + */ + void getIntersectingMembers(const Array& plane, Array& members) const { + if (root == NULL) { + return; + } + + getIntersectingMembers(plane, members, root, 0xFFFFFF); + } + + /** + Typically used to find all visible + objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects + not culled by frustum. + + Example: +
+        Array  visible;
+        tree.getIntersectingMembers(camera.frustum(), visible);
+        // ... Draw all objects in the visible array.
+      
+ @param members The results are appended to this array. + */ + void getIntersectingMembers(const GCamera::Frustum& frustum, Array& members) const { + Array plane; + + for (int i = 0; i < frustum.faceArray.size(); ++i) { + plane.append(frustum.faceArray[i].plane); + } + + getIntersectingMembers(plane, members); + } + + /** + C++ STL style iterator variable. See beginBoxIntersection(). + The iterator overloads the -> (dereference) operator, so this + acts like a pointer to the current member. + */ + // This iterator turns Node::getIntersectingMembers into a + // coroutine. It first translates that method from recursive to + // stack based, then captures the system state (analogous to a Scheme + // continuation) after each element is appended to the member array, + // and allowing the computation to be restarted. + class BoxIntersectionIterator { + private: + friend class AABSPTree; + + /** True if this is the "end" iterator instance */ + bool isEnd; + + /** The box that we're testing against. */ + AABox box; + + /** Node that we're currently looking at. Undefined if isEnd + is true. */ + Node* node; + + /** Nodes waiting to be processed */ + // We could use backpointers within the tree and careful + // state management to avoid ever storing the stack-- but + // it is much easier this way and only inefficient if the + // caller uses post increment (which they shouldn't!). + Array stack; + + /** The next index of current->valueArray to return. + Undefined when isEnd is true.*/ + int nextValueArrayIndex; + + BoxIntersectionIterator() : isEnd(true) {} + + BoxIntersectionIterator(const AABox& b, const Node* root) : + isEnd(root == NULL), box(b), + node(const_cast(root)), nextValueArrayIndex(-1) { + + // We intentionally start at the "-1" index of the current + // node so we can use the preincrement operator to move + // ourselves to element 0 instead of repeating all of the + // code from the preincrement method. Note that this might + // cause us to become the "end" instance. + ++(*this); + } + + public: + + inline bool operator!=(const BoxIntersectionIterator& other) const { + return ! (*this == other); + } + + bool operator==(const BoxIntersectionIterator& other) const { + if (isEnd) { + return other.isEnd; + } else if (other.isEnd) { + return false; + } else { + // Two non-end iterators; see if they match. This is kind of + // silly; users shouldn't call == on iterators in general unless + // one of them is the end iterator. + if ((box != other.box) || (node != other.node) || + (nextValueArrayIndex != other.nextValueArrayIndex) || + (stack.length() != other.stack.length())) { + return false; + } + + // See if the stacks are the same + for (int i = 0; i < stack.length(); ++i) { + if (stack[i] != other.stack[i]) { + return false; + } + } + + // We failed to find a difference; they must be the same + return true; + } + } + + /** + Pre increment. + */ + BoxIntersectionIterator& operator++() { + ++nextValueArrayIndex; + + bool foundIntersection = false; + while (! isEnd && ! foundIntersection) { + + // Search for the next node if we've exhausted this one + while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) { + // If we entered this loop, then the iterator has exhausted the elements at + // node (possibly because it just switched to a child node with no members). + // This loop continues until it finds a node with members or reaches + // the end of the whole intersection search. + + // If the right child overlaps the box, push it onto the stack for + // processing. + if ((node->child[1] != NULL) && + (box.high()[node->splitAxis] > node->splitLocation)) { + stack.push(node->child[1]); + } + + // If the left child overlaps the box, push it onto the stack for + // processing. + if ((node->child[0] != NULL) && + (box.low()[node->splitAxis] < node->splitLocation)) { + stack.push(node->child[0]); + } + + if (stack.length() > 0) { + // Go on to the next node (which may be either one of the ones we + // just pushed, or one from farther back the tree). + node = stack.pop(); + nextValueArrayIndex = 0; + } else { + // That was the last node; we're done iterating + isEnd = true; + } + } + + // Search for the next intersection at this node until we run out of children + while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) { + if (box.intersects(node->boundsArray[nextValueArrayIndex])) { + foundIntersection = true; + } else { + ++nextValueArrayIndex; + // If we exhaust this node, we'll loop around the master loop + // to find a new node. + } + } + } + + return *this; + } + + private: + /** + Post increment (much slower than preincrement!). Intentionally overloaded to preclude accidentally slow code. + */ + BoxIntersectionIterator operator++(int); + /*{ + BoxIntersectionIterator old = *this; + ++this; + return old; + }*/ + + public: + + /** Overloaded dereference operator so the iterator can masquerade as a pointer + to a member */ + const T& operator*() const { + alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator"); + return node->valueArray[nextValueArrayIndex]->value; + } + + /** Overloaded dereference operator so the iterator can masquerade as a pointer + to a member */ + T const * operator->() const { + alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator"); + return &(stack.last()->valueArray[nextValueArrayIndex]->value); + } + + /** Overloaded cast operator so the iterator can masquerade as a pointer + to a member */ + operator T*() const { + alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator"); + return &(stack.last()->valueArray[nextValueArrayIndex]->value); + } + }; + + + /** + Iterates through the members that intersect the box + */ + BoxIntersectionIterator beginBoxIntersection(const AABox& box) const { + return BoxIntersectionIterator(box, root); + } + + BoxIntersectionIterator endBoxIntersection() const { + // The "end" iterator instance + return BoxIntersectionIterator(); + } + + /** + Appends all members whose bounds intersect the box. + See also AABSPTree::beginBoxIntersection. + */ + void getIntersectingMembers(const AABox& box, Array& members) const { + if (root == NULL) { + return; + } + root->getIntersectingMembers(box, Sphere(Vector3::zero(), 0), members, false); + } + + + /** + Invoke a callback for every member along a ray until the closest intersection is found. + + @param callback either a function or an instance of a class with an overloaded operator() of the form: + + void callback(const Ray& ray, const T& object, float& distance). If the ray hits the object + before travelling distance distance, updates distance with the new distance to + the intersection, otherwise leaves it unmodified. A common example is: + +
+            class Entity {
+            public:
+
+                void intersect(const Ray& ray, float& maxDist, Vector3& outLocation, Vector3& outNormal) {
+                    float d = maxDist;
+
+                    // ... search for intersection distance d
+
+                    if ((d > 0) && (d < maxDist)) {
+                        // Intersection occured
+                        maxDist = d;
+                        outLocation = ...;
+                        outNormal = ...;
+                    }
+                }
+            };
+
+            // Finds the surface normal and location of the first intersection with the scene
+            class Intersection {
+            public:
+                Entity*     closestEntity;
+                Vector3     hitLocation;
+                Vector3     hitNormal;
+
+                void operator()(const Ray& ray, const Entity* entity, float& distance) {
+                    entity->intersect(ray, distance, hitLocation, hitNormal);
+                }
+            };
+
+            AABSPTree scene;
+
+            Intersection intersection;
+            float distance = inf();
+            scene.intersectRay(camera.worldRay(x, y), intersection, distance);
+          
+ + + @param distance When the method is invoked, this is the maximum distance that the tree should search for an intersection. + On return, this is set to the distance to the first intersection encountered. + + @param intersectCallbackIsFast If false, each object's bounds are tested before the intersectCallback is invoked. + If the intersect callback runs at the same speed or faster than AABox-ray intersection, set this to true. + */ + template + void intersectRay( + const Ray& ray, + RayCallback& intersectCallback, + float& distance, + bool pStopAtFirstHit, + bool intersectCallbackIsFast = false) const { + + root->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast); + + } + + + /** + @param members The results are appended to this array. + */ + void getIntersectingMembers(const Sphere& sphere, Array& members) const { + if (root == NULL) { + return; + } + + AABox box; + sphere.getBounds(box); + root->getIntersectingMembers(box, sphere, members, true); + + } +#if 0 + /** + Stores the locations of the splitting planes (the structure but not the content) + so that the tree can be quickly rebuilt from a previous configuration without + calling balance. + */ + void serializeStructure(BinaryOutput& bo) const { + Node::serializeStructure(root, bo); + } + + /** Clears the member table */ + void deserializeStructure(BinaryInput& bi) { + clear(); + root = Node::deserializeStructure(bi); + } +#endif + /** + Returns an array of all members of the set. See also AABSPTree::begin. + */ + void getMembers(Array& members) const { + Array temp; + memberTable.getKeys(temp); + for (int i = 0; i < temp.size(); ++i) { + members.append(temp[i].handle->value); + } + } + + + /** + C++ STL style iterator variable. See begin(). + Overloads the -> (dereference) operator, so this acts like a pointer + to the current member. + */ + class Iterator { + private: + friend class AABSPTree; + + // Note: this is a Table iterator, we are currently defining + // Set iterator + typename Table::Iterator it; + + Iterator(const typename Table::Iterator& it) : it(it) {} + + public: + + inline bool operator!=(const Iterator& other) const { + return !(*this == other); + } + + bool operator==(const Iterator& other) const { + return it == other.it; + } + + /** + Pre increment. + */ + Iterator& operator++() { + ++it; + return *this; + } + + private: + /** + Post increment (slower than preincrement). Intentionally unimplemented to prevent slow code. + */ + Iterator operator++(int);/* { + Iterator old = *this; + ++(*this); + return old; + }*/ + public: + + const T& operator*() const { + return it->key.handle->value; + } + + T* operator->() const { + return &(it->key.handle->value); + } + + operator T*() const { + return &(it->key.handle->value); + } + }; + + + /** + C++ STL style iterator method. Returns the first member. + Use preincrement (++entry) to get to the next element (iteration + order is arbitrary). + Do not modify the set while iterating. + */ + Iterator begin() const { + return Iterator(memberTable.begin()); + } + + + /** + C++ STL style iterator method. Returns one after the last iterator + element. + */ + Iterator end() const { + return Iterator(memberTable.end()); + } +}; + +} + +#endif + + + diff --git a/contrib/vmap_debugger/ModelContainerView.cpp b/contrib/vmap_debugger/ModelContainerView.cpp new file mode 100644 index 000000000..c29666c0b --- /dev/null +++ b/contrib/vmap_debugger/ModelContainerView.cpp @@ -0,0 +1,570 @@ +#include "ModelContainerView.h" + +namespace VMAP +{ + char* gDataDir = NULL; + char* gLogFile = NULL; + //========================================== + + ModelContainerView::ModelContainerView(const G3D::GApp::Settings& settings) : GApp(settings) { + i_App = this; + + iCommandFileRW.setFileName(gLogFile); + iCurrCmdIndex = 0; + iVMapManager = new VMapManager(); + iDrawLine = false; + + iVARAreaRef = VARArea::create(1024*1024*60); + iVARAreaRef2 = VARArea::create(1024*1024*2); + iInstanceId = -1; + iPosSent = false; + + } + //=================================================== + + ModelContainerView::~ModelContainerView(void) + { + Array keys = iTriVarTable.getKeys(); + Array::ConstIterator i = keys.begin(); + while(i != keys.end()) { + VAR* var = iTriVarTable.get(*i); + delete var; + ++i; + } + } + + //=================================================== + + void ModelContainerView::cleanup() { + } + + //=================================================== + Vector3 getViewPos(const ModelContainer* mc, unsigned int pModelNr = 0) { + if(mc->getNSubModel() < pModelNr) { + pModelNr = mc->getNSubModel(); + } + const SubModel sm = mc->getSubModel(pModelNr); + return (sm.getAABoxBounds().low()); + } + + void ModelContainerView::init() { + } + + //========================================== + + void fillSubModelArary(const ModelContainer* pModelContainer, const TreeNode *root, Array& array, Vector3& pLo, Vector3& pHi) { + Vector3 lo = Vector3(inf(), inf(), inf()); + Vector3 hi = Vector3(-inf(), -inf(), -inf()); + + for(int i=0; i< root->getNValues(); i++) { + SubModel sm = pModelContainer->getSubModel(root->getStartPosition() + i); + lo = lo.min(sm.getAABoxBounds().low()); + hi = hi.max(sm.getAABoxBounds().high()); + array.append(sm); + } + + if(root->getChild((TreeNode *) &pModelContainer->getTreeNode(0), 0)) { + fillSubModelArary(pModelContainer, root->getChild((TreeNode *)&pModelContainer->getTreeNode(0), 0), array, lo, hi); + } + if(root->getChild((TreeNode *)&pModelContainer->getTreeNode(0), 1)) { + fillSubModelArary(pModelContainer, root->getChild((TreeNode *)&pModelContainer->getTreeNode(0), 1), array, lo, hi); + } + + float dist1 = (hi -lo).magnitude(); + AABox b; + root->getBounds(b); + float dist2 = (b.high() -b.low()).magnitude(); + if(dist1 > dist2) { + // error + int xxx = 0; + } + + } + + //========================================== + void ModelContainerView::addModelContainer(const std::string& pName,const ModelContainer* pModelContainer) { + // VARArea::UsageHint::WRITE_EVERY_FEW_FRAMES + + int offset=0; + + Array iIndexArray; + Array iGlobArray; + + Array SMArray; + Vector3 lo, hi; + fillSubModelArary(pModelContainer, &pModelContainer->getTreeNode(0), SMArray,lo,hi); + + + for(int i=0; i vArray; + Array iArray; + fillVertexAndIndexArrays(sm, vArray, iArray); + + for(int j=0;jgBoxArray; + ArraygTriArray; + int gCount1 = 0, gCount2 = 0 , gCount3 = 0, gCount4 = 0; + bool myfound=false; + + //=================================================== + + void ModelContainerView::onInit() { + // Called before the application loop beings. Load data here and + // not in the constructor so that common exceptions will be + // automatically caught. + iSky = Sky::fromFile("../../data/sky/"); + + iSkyParameters = SkyParameters(G3D::toSeconds(11, 00, 00, AM)); + iLighting = Lighting::fromSky(iSky, iSkyParameters, Color3::white()); + + // This simple demo has no shadowing, so make all lights unshadowed + iLighting->lightArray.append(iLighting->shadowedLightArray); + iLighting->shadowedLightArray.clear(); + + // Example debug GUI: + //debugPane->addCheckBox("Use explicit checking", &explicitCheck); + debugWindow->setVisible(true); + + toneMap->setEnabled(false); + } + + void ModelContainerView::onGraphics(RenderDevice* rd, Array &posed3D, Array &posed2D) { + Array opaque, transparent; + LightingRef localLighting = toneMap->prepareLighting(iLighting); + SkyParameters localSky = toneMap->prepareSkyParameters(iSkyParameters); + + + toneMap->beginFrame(rd); + rd->setProjectionAndCameraMatrix(defaultCamera); + + rd->setColorClearValue(Color3::black()); + rd->clear(); + //iSky->render(rd, localSky); + + // Setup lighting + rd->enableLighting(); + //rd->setLight(0, localLighting->lightArray[0]); + //rd->setAmbientLightColor(localLighting->ambientAverage()); + + GLight light =GLight::directional(defaultController.pointer()->position() + defaultController.pointer()->lookVector()*2,Color3::white()); + rd->setLight(0,light); + + rd->setColor(Color3::blue()); + + Array keys = iTriVarTable.getKeys(); + Array::ConstIterator i = keys.begin(); + while(i != keys.end()) { + VAR* var = iTriVarTable.get(*i); + Array indexArray = iTriIndexTable.get(*i); + + rd->beginIndexedPrimitives(); + rd->setVertexArray(*var); + rd->sendIndices(RenderDevice::LINES, indexArray); + rd->endIndexedPrimitives(); + ++i; + } + for(int i=0; i 0) + { + rd->setColor(Color3::red()); + rd->beginIndexedPrimitives(); + rd->setVertexArray(iTriDebugVar); + rd->sendIndices(RenderDevice::LINES, iTriDebugArray); + rd->endIndexedPrimitives(); + } + } + //-------- + if(iDrawLine) { + Draw::lineSegment(LineSegment::fromTwoPoints(iPos1, iPos2), rd, iColor, 3); + + if(myfound) { + //Draw::lineSegment(LineSegment::fromTwoPoints(p1, p2), rd, iColor, 3); + //Draw::lineSegment(LineSegment::fromTwoPoints(p2, p3), rd, iColor, 3); + //Draw::lineSegment(LineSegment::fromTwoPoints(p3, p1), rd, iColor, 3); + Draw::sphere(Sphere(p4,0.5),rd, iColor); + //Draw::sphere(Sphere(p5,0.5),rd, Color3::green()); + } + } + + + // Always render the posed models passed in or the Developer Window and + // other Widget features will not appear. + if (posed3D.size() > 0) { + Vector3 lookVector = renderDevice->getCameraToWorldMatrix().lookVector(); + PosedModel::sort(posed3D, lookVector, opaque, transparent); + + for (int i = 0; i < opaque.size(); ++i) { + opaque[i]->render(renderDevice); + } + + for (int i = 0; i < transparent.size(); ++i) { + transparent[i]->render(renderDevice); + } + } + + rd->disableLighting(); + + toneMap->endFrame(rd); + PosedModel2D::sortAndRender(rd, posed2D); + } + + //=================================================== + + void ModelContainerView::fillRenderArray(const SubModel& pSm, Array &pArray, const TreeNode* pTreeNode) { + for(int i=0;igetNValues(); i++) { + pArray.append(pSm.getTriangles()[i+pTreeNode->getStartPosition()]); + } + + if(pTreeNode->getChild(pSm.getTreeNodes(), 0) != 0) { + fillRenderArray(pSm, pArray, pTreeNode->getChild(pSm.getTreeNodes(), 0)); + } + + if(pTreeNode->getChild(pSm.getTreeNodes(), 1) != 0) { + fillRenderArray(pSm, pArray, pTreeNode->getChild(pSm.getTreeNodes(), 1)); + } + } + + //=================================================== + + void ModelContainerView::fillVertexAndIndexArrays(const SubModel& pSm, Array& vArray, Array& iArray) { + Array tbarray; + + fillRenderArray(pSm, tbarray, &pSm.getTreeNode(0)); + MeshBuilder builder; + int len = tbarray.size(); + int count = 0; + for(int i=0;igetInstanceMapTree(pMapId); + std::string dirFileName = iVMapManager->getDirFileName(pMapId); + if(!mt->hasDirFile(dirFileName)) { + dirFileName = iVMapManager->getDirFileName(pMapId, x, y); + } + showMap(mt,dirFileName); + iInstanceId = pMapId; + } + + //==================================================================== + + bool ModelContainerView::loadAndShowTile(int pMapId, int x, int y) { + char buffer[500]; + sprintf(buffer, "%s/vmaps",gDataDir); + bool result = false; + //if(pMapId == 1) return true; //+++ + int val = iVMapManager->loadMap(buffer,(unsigned int) pMapId, x,y); + if(val == VMAP_LOAD_RESULT_OK) { + result = true; + showMap(pMapId,x,y); + } else { + printf("Unable to load %s\n", buffer); + } + return(result); + } + + //======================================================================= + + void ModelContainerView::showMap(MapTree* mt, std::string dirFileName) { + if(mt->hasDirFile(dirFileName)) { + FilesInDir filesInDir = mt->getDirFiles(dirFileName); + if(filesInDir.getRefCount() == 1) { + Array fileNames = filesInDir.getFiles(); + for(int i=0; igetModelContainer(name); + //if(mc->getNSubModel() == 791) { + addModelContainer(name, mc); + //} + } + } + } + } + + //======================================================================= + + bool ModelContainerView::loadAndShowTile(int pMapId) { + char buffer[500]; + sprintf(buffer, "%s/vmaps",gDataDir); + bool result = false; + int val = iVMapManager->loadMap(buffer, (unsigned int) pMapId,-1,-1); + if(val == VMAP_LOAD_RESULT_OK) { + result = true; + MapTree* mt = iVMapManager->getInstanceMapTree(pMapId); + std::string dirFileName = iVMapManager->getDirFileName(pMapId); + iTriVarTable = Table(); + iTriIndexTable = Table >(); // reset table + iInstanceId = pMapId; + showMap(mt,dirFileName); + } + return(result); + } + + //==================================================================== + + void ModelContainerView::processCommand() { + iDrawLine = false; + if(iCurrCmdIndex < iCmdArray.size()) { + bool cmdfound = false; + while(!cmdfound && (iCurrCmdIndex < iCmdArray.size())) { + Command c = iCmdArray[iCurrCmdIndex]; + if(c.getType() == LOAD_TILE) { + iPrevLoadCommands.push_back(c); + if(iPosSent) { + if(loadAndShowTile(c.getInt(2), c.getInt(0), c.getInt(1))) { + printf("load tile mapId=%d, %d, %d\n", c.getInt(2), c.getInt(0), c.getInt(1)); + } else { + printf("ERROR: unable to load tile mapId= %d, %d, %d\n", c.getInt(2), c.getInt(0), c.getInt(1)); + } + cmdfound = true; + } else { + printf("ignore load tile mapId=%d, %d, %d\n", c.getInt(2), c.getInt(0), c.getInt(1)); + } + } else if(c.getType() == LOAD_INSTANCE) { + if(loadAndShowTile(c.getInt(0))) { + printf("load instance %d\n", c.getInt(0)); + } + cmdfound = true; + } else if(c.getType() == UNLOAD_TILE) { + /* + iVMapManager->unloadMap(c.getInt(2), c.getInt(0), c.getInt(1)); + printf("unload tile %d, %d\n", c.getInt(0), c.getInt(1)); + + std::string dirFileName = iVMapManager->getDirFileName(iVMapManager->getMapIdNames(c.getInt(2)).iMapGroupName.c_str(), c.getInt(0), c.getInt(1)); + MapTree* mt = iVMapManager->getInstanceMapTree(c.getInt(2)); + if(mt->hasDirFile(dirFileName)) { + Array fileNames = mt->getDirFiles(dirFileName).getFiles(); + for(int i=0; igetModelContainer(name); + removeModelContainer(name, mc); + } + } + */ + } else if(c.getType() == SET_POS) { + if(!iPosSent) { + int count = 3; + while(iPrevLoadCommands.size() > 0 && count>0) { + Command lc = iPrevLoadCommands.last(); + iPrevLoadCommands.pop_back(); + // first time, load the last map needed + if(loadAndShowTile(lc.getInt(2), lc.getInt(0), lc.getInt(1))) { + printf("load tile mapid=%d, %d, %d\n", lc.getInt(2), lc.getInt(0), lc.getInt(1)); + } else { + printf("ERROR: unable to load tile mapid=%d, %d, %d\n", lc.getInt(2), lc.getInt(0), lc.getInt(1)); + } + --count; + } + } + iPosSent = true; + defaultCamera.setPosition(Vector3(c.getVector(0).x,c.getVector(0).y+3, c.getVector(0).z)); + defaultController.pointer()->setPosition(Vector3(c.getVector(0).x,c.getVector(0).y+3, c.getVector(0).z)); + printf("set pos to %f, %f, %f\n",c.getVector(0).x, c.getVector(0).y, c.getVector(0).z ); + cmdfound = true; + } else if(c.getType() == TEST_VIS) { + printf("TEST line of sight\n"); + iDrawLine = true; + iPos1 = iVMapManager->convertPositionToInternalRep(c.getVector(0).x, c.getVector(0).y, c.getVector(0).z); + iPos2 = iVMapManager->convertPositionToInternalRep(c.getVector(1).x, c.getVector(1).y, c.getVector(1).z); + if(c.getInt(0) != 0) { + iColor = Color3::green(); + } else { + iColor = Color3::red(); + } + cmdfound = true; +/* + { + // draw debug-lines + int count = 0; + for(int i=0; ikeyPressed(GKey::fromString("l"))) { //load + iCmdArray = Array(); + iCommandFileRW.getNewCommands(iCmdArray); + iCurrCmdIndex = 0; + processCommand(); + } + + if(ui->keyPressed(GKey::fromString("r"))) { //restart + iCurrCmdIndex = 0; + } + + if(ui->keyPressed(GKey::fromString("1"))) { //inc count1 + gCount1++; + } + + if(ui->keyPressed(GKey::fromString("h"))) { //inc count1 +#if 0 + i_App->defaultController.getPosition(); + Vector3 pos = i_App->defaultController.getPosition(); + Vector3 pos2 = convertPositionToMangosRep(pos.x, pos.y, pos.z); + //Vector3 pos3 = iVMapManager->convertPositionToInternalRep(pos2.x, pos2.y, pos2.z); + //pos3 = iVMapManager->convertPositionToInternalRep(pos2.x, pos2.y, pos2.z); + + float hight = iVMapManager->getHeight(iInstanceId, pos2.x, pos2.y, pos2.z); + printf("Hight = %f\n",hight); +#endif + } + + + if(ui->keyPressed(GKey::fromString("2"))) { //dec count1 + gCount1--; + if(gCount1 < 0) + gCount1 = 0; + } + + if(ui->keyPressed(GKey::fromString("z"))) { //zero pos + i_App->defaultCamera.setPosition(Vector3(0,0,0)); + printf("set pos to 0, 0, 0\n"); + } + + + if(ui->keyPressed(GKey::fromString("c"))) { //restart + if(iCurrCmdIndex > 0) { + if(iCmdArray[iCurrCmdIndex-1].getType() == TEST_VIS) { + Vector3 p1 = iCmdArray[iCurrCmdIndex-1].getVector(0); + Vector3 p2 = iCmdArray[iCurrCmdIndex-1].getVector(1); + bool result; + int mapId = iCmdArray[iCurrCmdIndex-1].getInt(1); + gCount3 = gCount2 = 0;// debug counter + gBoxArray = Array(); + result = iVMapManager->isInLineOfSight(mapId, p1.x,p1.y,p1.z,p2.x,p2.y,p2.z); + printf("recalc last line of light: result = %d\n", result); + } + } + } + + + if(ui->keyPressed(GKey::LEFT_MOUSE)) { + if( iCurrCmdIndex>0) { + --iCurrCmdIndex; + printf("restart last command\n"); + processCommand(); + } + } + + if(ui->keyPressed(GKey::MIDDLE_MOUSE)) { + processCommand(); + } + + } + //========================================== + + void ModelContainerView::setViewPosition(const Vector3& pPosition) { + //i_App->defaultController.setPosition(pPosition); + i_App->defaultCamera.setPosition(pPosition); + } + + //========================================== + //========================================== +} +G3D_START_AT_MAIN(); +int main(int argc, char** argv) { + if(argc == 3) { + VMAP::gDataDir = argv[1]; + VMAP::gLogFile = argv[2]; + + G3D::GApp::Settings settings; + settings.window.width = 1024; + settings.window.height = 768; + //settings.useDeveloperTools = true; + + VMAP::ModelContainerView modelContainerView(settings); + modelContainerView.run(); + } else { + printf("%s \n",argv[0]); + } +} diff --git a/contrib/vmap_debugger/ModelContainerView.h b/contrib/vmap_debugger/ModelContainerView.h new file mode 100644 index 000000000..28d992a0c --- /dev/null +++ b/contrib/vmap_debugger/ModelContainerView.h @@ -0,0 +1,89 @@ +#ifndef _MODELCONTAINERVIEW_H +#define _MODELCONTAINERVIEW_H + +#include +#include +#include "ModelContainer.h" +#include "DebugCmdLogger.h" +#include "vmapmanager.h" + + + + +namespace VMAP +{ + //========================================== + + + //========================================== + + class ModelContainerView : + public G3D::GApp + { + private: + SkyRef iSky; + LightingRef iLighting; + SkyParameters iSkyParameters; + + VARAreaRef iVARAreaRef; + Table iTriVarTable; + Table > iTriIndexTable; + + VARAreaRef iVARAreaRef2; + VAR iTriDebugVar; + Array iVTriDebugArray; + Array iTriDebugArray; + + //Array iLineIndexArray; + + GApp* i_App; + CommandFileRW iCommandFileRW; + Array iCmdArray; + int iCurrCmdIndex; + + VMapManager* iVMapManager; + + Vector3 iPos1; + Vector3 iPos2; + Color3 iColor; + bool iDrawLine; + int iInstanceId; + bool iPosSent; + Array iPrevLoadCommands; + private: + Vector3 convertPositionToMangosRep(float x, float y, float z) const; + + public: + ModelContainerView(const G3D::GApp::Settings& settings); + + ~ModelContainerView(void); + + void addModelContainer(const std::string& pName,const ModelContainer* pModelContainer); + void removeModelContainer(const std::string& pName, const ModelContainer* pModelContainer); + void setViewPosition(const Vector3& pPosition); + + void onGraphics(RenderDevice* rd, Array &posed3D, Array &posed2D); + virtual void onInit(); + void init(); + void cleanup(); + void onUserInput(UserInput* ui); + + void fillRenderArray(const SubModel& pSm,Array &pArray, const TreeNode* pTreeNode); + void fillVertexAndIndexArrays(const SubModel& pSm, Array& vArray, Array& iArray); + + bool loadAndShowTile(int pMapId, int x, int y); + void showMap(int pMapId, int x, int y); + + void showMap(MapTree* mt, std::string dirFileName); + bool loadAndShowTile(int pMapId); + + + void processCommand(); + + }; + + //========================================== + //========================================== +} + +#endif diff --git a/contrib/vmap_debugger/VC8/Release/vmapdebugger.exe b/contrib/vmap_debugger/VC8/Release/vmapdebugger.exe new file mode 100644 index 000000000..c61082e49 Binary files /dev/null and b/contrib/vmap_debugger/VC8/Release/vmapdebugger.exe differ diff --git a/contrib/vmap_debugger/VC8/vmapdebugger.vcproj b/contrib/vmap_debugger/VC8/vmapdebugger.vcproj new file mode 100644 index 000000000..35ca727ab --- /dev/null +++ b/contrib/vmap_debugger/VC8/vmapdebugger.vcproj @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/vmap_debugger/bin/vmapdebugger.exe b/contrib/vmap_debugger/bin/vmapdebugger.exe new file mode 100644 index 000000000..c61082e49 Binary files /dev/null and b/contrib/vmap_debugger/bin/vmapdebugger.exe differ diff --git a/contrib/vmap_debugger/readme.txt b/contrib/vmap_debugger/readme.txt new file mode 100644 index 000000000..b97715ab0 --- /dev/null +++ b/contrib/vmap_debugger/readme.txt @@ -0,0 +1,121 @@ +Here you find a visual debugging tool. With that you can check it yourself. You need to compile it +yourself or just use the precompiled version. The precompiled version should not need any +additional libraries. If you try to compile it yourself you need G3D library 7.00 and +SDL 1.2.8 or higher. + +There is NO “how to compile support”.... You will manage it, if you need to... + +What does it do? + +The program analyses the content of the vmapcmd.log file created by [b] mangosd compiled +in debug mode [/b] with vmap support. The commands written to disk are read and the result +is displayed in a graphical view. This view shows a wire frame model of the loaded vmaps +and you can move in these maps. Furthermore you can see witch line of sight query where +performed and its result. You are able to perform the ling of sight query again and will see, if +the current version of the vmap source compiled against the debugger, produces the same +result. This last function is useful for debugging the line of sight code. + +The little program is a real hack, but is fits is purpose. + +How to use it: + +[b]Logging[b] +You will need to set _VMAP_LOG_DEBUG when compiling core in debug mode to get this log. +If mangos is compiled in debug mode it will then write the vmapcmd.log file. The file does only +contain the information which vmaps are loaded. I addition to that the file need the +information where your character currently in standing in the maps. This position information +has to be inserted manually. To do that I modified the .announce command to send the +position of the current character to the log file (modification is in the attached patch). + +The line of sight query is only stored in the log file if you enable this kind of logging. This is +done by performing the modified .gm off command. Enabling line of sight and moving your +character a bit will log the queries and there results. Don’t do this for log, it will produce lots +of data, which is hard to analyze later. + +The modified command .gm on will stop the logging of the line of sight calculation. + +What do you have to do for logging? +1. Apply the patch to mangos to modify your .announce, .gmoff and .gmon commands +2. Compile mangos in debug mode +3. Go to the position where you suspect a problem +4. Use .gmon to be sure you will not be attacked when you login +5. Save, Logoff and stop mangosd +6. Delete the vmapcmd.log from the mangos dir. The logger will append to that file. +7. Start mangos +8. Login with your character +9. Send your position to the log file. Do this with the .announce command (.announce +foo) +10. Type .gmoff enabling the line of sight logging +11. Move a bit to get the attention of the mobs +12. Type .gmon to stop the logging + +[b]Analysing the log file[/b] +1. Start the vmap debugger with the path to the mangos data dir and the full path (name) of +the log file +2. The debugger is controlled by single keys and the mouse. Here is a list of key commands. +The result is displayed at the console: + +l – (small L) Load the next block off logging data into the command queue and process the +first command from the queue. When the end is reached a message “end reached” is display at +the console. If you reached the you can press l again. Sending .gm on sets an end mark to the +file. You have to load the next logging block after each .gmon command. + +r – Reload the last command block + +mouse middle click – process the next command from the queue + +mouse left click – reprocess the last command from the queue + +c – recalculate the last line of sight command and send the result to the console + +w,s,a,d – move within the 3D view + +ESC – exit + +TAB – release/grep the mouse + +[b]How to test the included example with the precompiled version with the included +vmapcmd.log file:[b] + +open your console +move to the contrib\vmap_debugger\bin directory +run: vmapdebugger.exe vmapcmd.log +Wait until the block screen is open and arrange the console and the screen, so you can see +both +Press: l (small L not one) +click middle +click middle +click middle + +Now you should see the wire frame model of scholo and the green line of sight line in the +display. The green line means the test was performed and you are seen. A red line means you +are not seen. Move around a bit with the mouse and the w,s,a,d keys. + +Press c +Press ESC + +[b]Problems with your gfx.card[/b] +Maybe the program does not woth with your graphics card. In this case you have dad luck. +One think might help, if not .... I do not know...: + +Here I take 60 MB Ram from Gfx-Card [b]VARArea::create(1024*1024*60)[/b]. That +might cause problems on your system. + +[code] + ModelContainerView::ModelContainerView(GApp* pApp) : GApplet(pApp) { + i_App = pApp; + + iCommandFileRW.setFileName(gLogFile); + iCurrCmdIndex = 0; + iVMapManager = new VMapManager(); + iDrawLine = false; + + iVARAreaRef = VARArea::create(1024*1024*60); + iInstanceId = -1; + + } +[/code] + +This should give all of you who, are interested the chance to check the content and behavior +of the vmaps. + diff --git a/contrib/vmap_debugger/vmapdebugger_VC8.sln b/contrib/vmap_debugger/vmapdebugger_VC8.sln new file mode 100644 index 000000000..7a6d347de --- /dev/null +++ b/contrib/vmap_debugger/vmapdebugger_VC8.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmapdebugger", "VC8\vmapdebugger.vcproj", "{0F6BDF3C-9B6F-45A0-A443-E26E31C8A015}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0F6BDF3C-9B6F-45A0-A443-E26E31C8A015}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F6BDF3C-9B6F-45A0-A443-E26E31C8A015}.Debug|Win32.Build.0 = Debug|Win32 + {0F6BDF3C-9B6F-45A0-A443-E26E31C8A015}.Release|Win32.ActiveCfg = Release|Win32 + {0F6BDF3C-9B6F-45A0-A443-E26E31C8A015}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/vmap_extract_assembler_bin/make vmaps.bat b/contrib/vmap_extract_assembler_bin/make vmaps.bat new file mode 100644 index 000000000..cb6714f4c --- /dev/null +++ b/contrib/vmap_extract_assembler_bin/make vmaps.bat @@ -0,0 +1,46 @@ +@echo off +cls +echo. +echo Welcome to the vmaps extractor and assembler +echo. +echo You need 2GB of free space in disk, CTRL+C to stop process +echo Hit Enter to start . . . +pause>nul +cls +echo. +echo. +echo. +IF EXIST buildings\dir (ECHO The buildings folder already exist do you want to delete it? +echo If YES hit Enter to continue if no CLOSE the program now! . . . +pause>nul +DEL /S /Q buildings) +vmapextract_v2.exe +cls +echo. +echo. +echo. +IF NOT %ERRORLEVEL% LEQ 1 (echo The vmap extract tool finalized with errors. +echo Hit Enter to continue . . . +pause>nul) +cls +echo. +echo. +echo. +echo Vmaps extracted check log.txt for errors, now it's time to assemble the vmaps press any key to continue . . . +pause>nul +md vmaps +vmap_assembler.exe buildings vmaps splitConfig.txt +cls +echo. +echo. +echo. +IF NOT %ERRORLEVEL% LEQ 1 (echo The vmap assembler tool finalized with errors. +echo Hit Enter to continue . . . +pause>nul) +cls +echo. +echo. +echo. +echo Process done! copy vmaps folder to the MaNGOS main directory +echo Press any key to exit . . . +pause>nul \ No newline at end of file diff --git a/contrib/vmap_extract_assembler_bin/makevmaps_SIMPLE.bat b/contrib/vmap_extract_assembler_bin/makevmaps_SIMPLE.bat new file mode 100644 index 000000000..bf01c24ed --- /dev/null +++ b/contrib/vmap_extract_assembler_bin/makevmaps_SIMPLE.bat @@ -0,0 +1,5 @@ +vmapextract_v2.exe +md vmaps +vmap_assembler.exe buildings vmaps splitConfig.txt + +pause \ No newline at end of file diff --git a/contrib/vmap_extract_assembler_bin/readme.txt b/contrib/vmap_extract_assembler_bin/readme.txt new file mode 100644 index 000000000..85abfb237 --- /dev/null +++ b/contrib/vmap_extract_assembler_bin/readme.txt @@ -0,0 +1,4 @@ +execute make vmaps.bat to make vmaps step by sep +execute makevmaps_SIMPLE.bat to so it in one step no quesions final screen [recommended] + +put vmaps folder in mangos main folder to enable LOS [Line Of Sight] \ No newline at end of file diff --git a/contrib/vmap_extract_assembler_bin/splitConfig.txt b/contrib/vmap_extract_assembler_bin/splitConfig.txt new file mode 100644 index 000000000..de8fd67bd --- /dev/null +++ b/contrib/vmap_extract_assembler_bin/splitConfig.txt @@ -0,0 +1,17 @@ +# list of map names + +509 #AhnQiraj +469 #BlackwingLair +189 #MonasteryInstances +030 #PVPZone01 +037 #PVPZone02 +033 #Shadowfang +533 #Stratholme Raid +209 #TanarisInstance +309 #Zul'gurub +560 #HillsbradPast +534 #HyjalPast +532 #Karazahn +543 #HellfireRampart +568 #ZulAman +564 #BlackTemple diff --git a/contrib/vmap_extract_assembler_bin/vmap_assembler.exe b/contrib/vmap_extract_assembler_bin/vmap_assembler.exe new file mode 100644 index 000000000..5cb08f770 Binary files /dev/null and b/contrib/vmap_extract_assembler_bin/vmap_assembler.exe differ diff --git a/contrib/vmap_extract_assembler_bin/vmapextract_v2.exe b/contrib/vmap_extract_assembler_bin/vmapextract_v2.exe new file mode 100644 index 000000000..c38b6e64f Binary files /dev/null and b/contrib/vmap_extract_assembler_bin/vmapextract_v2.exe differ diff --git a/contrib/vmap_extractor_v2/doc/The MoPaQ File Format.txt b/contrib/vmap_extractor_v2/doc/The MoPaQ File Format.txt new file mode 100644 index 000000000..3a8f964cf --- /dev/null +++ b/contrib/vmap_extractor_v2/doc/The MoPaQ File Format.txt @@ -0,0 +1,318 @@ +THE MOPAQ ARCHIVE FORMAT +v0.9 (Thursday, June 30, 2005) +by Justin Olbrantz(Quantam) + +Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quoting +in other works is freely allowed, as long as the source and author of the quote is stated. + +TABLE OF CONTENTS +1. Introduction to the MoPaQ Format +2. The MoPaQ Format + 2.1 General Archive Layout + 2.2 Archive Header + 2.3 Block Table + 2.4 Hash Table + 2.5 File Data + 2.6 Listfile + 2.7 Extended Attributes + 2.8 Weak (Old) Digital Signature + 2.9 Strong (New) Digital Signature +3. Algorithm Source Code + 3.1 Encryption/Decryption + 3.2 Hashing + 3.3 Conversion of FILETIME and time_t + +1. INTRODUCTION TO THE MOPAQ FORMAT +The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard +Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be +a read-only game archive format, and excels at this role. + +The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked. +The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked. + +2. THE MOPAQ FORMAT +All numbers in the MoPaQ format are in little endian. Data types are listed either as int (integer, the number of bits specified), +byte (8 bits), and char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise. +Structure members are listed in the following general form: +offset from the beginning of the structure: data type(array size) member name : member description + +2.1 GENERAL ARCHIVE LAYOUT +- Archive Header +- File Data +- File Data - Special Files +- Hash Table +- Block Table +- Strong Digital signature + +This is the usual archive format, and is not absolutely essential. Some archives have been observed placing the hash table +and file table after the archive header, and before the file data. + +2.2 ARCHIVE HEADER +00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah. +04h: int32 HeaderSize : Size of the archive header. Should be 32. +08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present. +This size is used, among other things, for determining the region to hash in computing the digital signature. +0Ch: int16 Unknown : Unknown +0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector +in the archive. The size of each logical sector the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate +that this should always be 3 (4096 byte sectors). +10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive. +14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive. +18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16. +1Ch: int32 BlockTableEntries : Number of entries in the block table. + +The archive header is the first structure in the archive, at archive offset 0, but the archive does not need to be at offset +0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not +at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the +archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer +versions (due to the strong digital signature not being considered a part of the archive). + +2.3 BLOCK TABLE +The block table contains entries for each region in the archive. Regions may be either files or empty space, which may be +overwritten by new files (typically this space is from deleted file data). The block table is encrypted, using the hash +of "(block table)" as the key. Each entry is structured as follows: + +00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive. Meaningless if the block size is 0. +04h: int32 BlockSize : Size of the block in the archive. +08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file, otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data. +0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified: + 80000000h: Block is a file, and follows the file data format; otherwise, block is free space, and may be overwritten. If the block is not a file, all other flags should be cleared. + 01000000h: File is stored as a single unit, rather than split into sectors. + 00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted. + 00010000h: File is encrypted. + 00000200h: File is compressed. Mutually exclusive to file imploded. + 00000100h: File is imploded. Mutually exclusive to file compressed. + +2.4 HASH TABLE +Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows: + +00h: int32 FilePathHashA : The hash of the file path, using method A. +04h: int32 FilePathHashB : The hash of the file path, using method B. +08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral. +0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed. +0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values: + FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file. + FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file. + +2.5 FILE DATA +00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector's data, relative to the beginning of the file data. Not present if this information is calculatable (see details below). +immediately following SectorOffsetTable: SectorData : Data of each sector in the file, packed end to end (see details below). + +Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may be smaller than this, depending on the size of the file data. This sector size is the size of the raw file data; if the file is compressed, the compressed sector will be smaller or the same size as the uncompressed sector size. Individual sectors in a compressed file may be stored uncompressed; this occurs if and only if the sector could not be compressed by the algorithm used (if the compressed sector size was greater than or equal to the size of the raw data), and is indicated by the sector's compressed size in SectorOffsetTable being equal to the uncompressed size of the sector (which may be calculated from the FileSize). + +If the sector is compressed (but not imploded), a bit mask byte of the compression algorithm(s) used to compress the sector is appended to the beginning of the compressed sector data. This additional byte counts towards the total size of the sector; if the size of the sector (including this byte) exceeds or matches the uncompressed size of the sector data, the sector will be stored uncompressed, and this byte omitted. Multiple compression algorithms may be used on the same sector; in this case, successive compression occurs in the order the algorithms are listed below, and decompression occurs in the opposite order. For implimentations of all of these algorithms, see StormLib. + 40h: IMA ADPCM mono + 80h: IMA ADPCM stereo + 01h: Huffman encoded + 02h: Deflated (see ZLib) + 08h: Imploded (see PKWare Data Compression Library) + 10h: BZip2 compressed (see BZip2) + +If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which +contains the entire file. + +If the file is encrypted, each sector (after compression and appendage of the compression type byte, if applicable) +is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the +directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is +adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset) +XOR FileSize) (StormLib - an open-source implementation of the MoPaQ reading and writing functions, +by Ladislav Zezula - incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the +0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1. + +The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize. +This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors +is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the +SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously. +Note that the SectorOffsetTable will always be present if the file is compressed/imploded and the file is not stored as +a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the +archive's sector size). + +2.6 LISTFILE +The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive. +The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)", +and is simply a non-Unix-style text file with one file path on each line, lines terminated with the bytes 0Dh 0Ah. The file +"(listfile)" may not be listed in the listfile. + +2.7 EXTENDED ATTRIBUTES +The extended attributes are optional file attributes for files in the block table. These attributes were added at times after +the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes. +If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although +the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the +blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file, +in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other +structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some +archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This +file is structured as follows: + +00h: int32 Version : Specifies the extended attributes format version. For now, must be 100. +04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive: + 00000001h: File CRC32s. + 00000002h: File timestamps. + 00000004h: File MD5s. +08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the +archive does not have CRC32s. immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block +in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps. +immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive. +Omitted if the archive does not have MD5s. + +2.8 WEAK DIGITAL SIGNATURE +The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation of the RSASSA-PKCS1-v1_5 +digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak) RSA key (for more information about this +protocol, see the RSA Labs PKCS1 specification). The public key and exponent are stored in a resource in Storm. The signature +is stored uncompressed, unencrypted in the file "(signature)" in the archive. The archive is hashed from the beginning of the +archive (ArchiveOffset in the containing file) to the end of the archive (the length indicated by ArchiveSize); the signature +file is added to the archive before signing, and the space occupied by the file is considered to be all binary 0s during +signing/verification. This file is structured as follows: + +00h: int32 Unknown : Must be 0. +04h: int32 Unknown : must be 0. +08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored in little-endian order. + +2.9 STRONG DIGITAL SIGNATURE +The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and +a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well. +The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize +bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format: + +00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards). +04h: int2048 Signature : The digital signature, stored in little-endian format. + +When the Signature field is decrypted with the public key and exponent, and the result stored in little-endian order, it is structured as follows: + +00h: byte Padding : Must be 0Bh. +01h: byte(235) Padding : Must be BBh. +ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 format. + +3. ALGORITHM SOURCE CODE +3.1 ENCRYPTION/DECRYPTION +I believe this was derived at some point from code in StormLib. Assumes the long type to be 32 bits, and the machine to be little endian order. + +unsigned long dwCryptTable[0x500]; + +void InitializeCryptTable() +{ + unsigned long seed = 0x00100001; + unsigned long index1 = 0; + unsigned long index2 = 0; + int i; + + for (index1 = 0; index1 < 0x100; index1++) + { + for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100) + { + unsigned long temp1, temp2; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp1 = (seed & 0xFFFF) << 0x10; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp2 = (seed & 0xFFFF); + + dwCryptTable[index2] = (temp1 | temp2); + } + } +} + +void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEE; + unsigned long ch; + + assert(lpbyBuffer); + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B); + seed = *lpdwBuffer + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEE; + unsigned long ch; + + assert(lpbyBuffer); + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B); + seed = ch + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +3.2 HASHING +Based on code from StormLib. + +// Different types of hashes to make with HashString +#define MPQ_HASH_TABLE_OFFSET 0 +#define MPQ_HASH_NAME_A 1 +#define MPQ_HASH_NAME_B 2 +#define MPQ_HASH_FILE_KEY 3 + +unsigned long HashString(const char *lpszString, unsigned long dwHashType) +{ + unsigned long seed1 = 0x7FED7FED; + unsigned long seed2 = 0xEEEEEEEE; + int ch; + + while (*lpszString != 0) + { + ch = toupper(*lpszString++); + + seed1 = dwCryptTable[(dwHashType * 0xFF) + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + return seed1; +} + +3.3 CONVERSION OF FILETIME AND time_t + +#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970 + +bool GetTimeFromFileTime(FILETIME &fileTime, time_t &time) +{ + // The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601 + unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime; + + if (nTime < EPOCH_OFFSET) + return false; + + nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970 + nTime /= 10000000ULL; // Convert 100 ns to sec + + time = (time_t)nTime; + + // Test for overflow (FILETIME is 64 bits, time_t is 32 bits) + if ((nTime - (unsigned long long)time) > 0) + return false; + + return true; +} + +void GetFileTimeFromTime(time_t &time, FILETIME &fileTime) +{ + unsigned long long nTime = (unsigned long long)time; + + nTime *= 10000000ULL; + nTime += EPOCH_OFFSET; + + fileTime.dwLowDateTime = (DWORD)nTime; + fileTime.dwHighDateTime = (DWORD)(nTime >> 32); +} diff --git a/contrib/vmap_extractor_v2/doc/The_MoPaQ_File_Format.txt b/contrib/vmap_extractor_v2/doc/The_MoPaQ_File_Format.txt new file mode 100644 index 000000000..6a21eca54 --- /dev/null +++ b/contrib/vmap_extractor_v2/doc/The_MoPaQ_File_Format.txt @@ -0,0 +1,421 @@ +THE MOPAQ ARCHIVE FORMAT +v1.0 (Friday, September 1, 2006) +by Justin Olbrantz(Quantam) + +Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quotation in other works is freely allowed, as long as the source and author of the quote are stated. + +TABLE OF CONTENTS +1. Introduction to the MoPaQ Format +2. The MoPaQ Format + 2.1 General Archive Layout + 2.2 Archive Header + 2.3 Block Table + 2.4 Extended Block Table + 2.5 Hash Table + 2.6 File Data + 2.7 Listfile + 2.8 Extended Attributes + 2.9 Weak (Old) Digital Signature + 2.10 Strong (New) Digital Signature +3. Algorithm Source Code + 3.1 Encryption/Decryption + 3.2 Hashing and File Key Computation + 3.3 Finding Files + 3.4 Deleting Files + 3.5 Conversion of FILETIME and time_t + 3.6 Forming a 64-bit Large Archive Offset from 32-bit and 16-bit Components +4. Revision History + +1. INTRODUCTION TO THE MOPAQ FORMAT +The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be a read-only game archive format, and excels at this role. + +The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked. The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked. + +StormLib - mentioned several times in this specification - is an open-source MoPaQ reading and writing library written by Ladislav Zezula (no affiliation with Blizzard Entertainment). While it's a bit dated, and does not support all of the newer MoPaQ features, it contains source code to the more exotic compression methods used by MoPaQ, such as the PKWare implode algorithm, MoPaQ's huffman compression algorithm, and the IMA ADPCM compression used by MoPaQ. + +2. THE MOPAQ FORMAT +All numbers in the MoPaQ format are in little endian byte order; signed numbers use the two's complement system. Data types are listed either as int (integer, the number of bits specified), byte (8 bits), or char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise. Structure members are listed in the following general form: +offset from the beginning of the structure: data type(array size) member name : member description + +2.1 GENERAL ARCHIVE LAYOUT +- Archive Header +- File Data +- File Data - Special Files +- Hash Table +- Block Table +- Extended Block Table +- Strong Digital signature + +This is the usual archive format, but it is not mandatory. Some archives have been observed placing the hash table and file table after the archive header, and before the file data. + +2.2 ARCHIVE HEADER +00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah. +04h: int32 HeaderSize : Size of the archive header. +08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present. This size is used, among other things, for determining the region to hash in computing the digital signature. This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive is calculated as the size from the beginning of the archive to the end of the hash table, block table, or extended block table (whichever is largest). +0Ch: int16 FormatVersion : MoPaQ format version. MPQAPI will not open archives where this is negative. Known versions: + 0000h: Original format. HeaderSize should be 20h, and large archives are not supported. + 0001h: Burning Crusade format. Header size should be 2Ch, and large archives are supported. +0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors). +10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive. +14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive. +18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for the original MoPaQ format, or less than 2^20 for the Burning Crusade format. +1Ch: int32 BlockTableEntries : Number of entries in the block table. +Fields only present in the Burning Crusade format and later: +20h: int64 ExtendedBlockTableOffset : Offset to the beginning of the extended block table, relative to the beginning of the archive. +28h: int16 HashTableOffsetHigh : High 16 bits of the hash table offset for large archives. +2Ah: int16 BlockTableOffsetHigh : High 16 bits of the block table offset for large archives. + +The archive header is the first structure in the archive, at archive offset 0; however, the archive does not need to be at offset 0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer versions (due to the strong digital signature not being considered a part of the archive). + +2.3 BLOCK TABLE +The block table contains entries for each region in the archive. Regions may be either files, empty space, which may be overwritten by new files (typically this space is from deleted file data), or unused block table entries. Empty space entries should have BlockOffset and BlockSize nonzero, and FileSize and Flags zero; unused block table entries should have BlockSize, FileSize, and Flags zero. The block table is encrypted, using the hash of "(block table)" as the key. Each entry is structured as follows: + +00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive. +04h: int32 BlockSize : Size of the block in the archive. +08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file; otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data. +0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified: + 80000000h: Block is a file, and follows the file data format; otherwise, block is free space or unused. If the block is not a file, all other flags should be cleared, and FileSize should be 0. + 01000000h: File is stored as a single unit, rather than split into sectors. + 00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted. + 00010000h: File is encrypted. + 00000200h: File is compressed. File cannot be imploded. + 00000100h: File is imploded. File cannot be compressed. + +2.4 EXTENDED BLOCK TABLE +The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes). The table contains the upper bits of the archive offsets for each block in the block table. It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block, with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size. + +As of the Burning Crusade Friends and Family beta, this table is not encrypted. + +2.5 HASH TABLE +Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows: + +00h: int32 FilePathHashA : The hash of the file path, using method A. +04h: int32 FilePathHashB : The hash of the file path, using method B. +08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral. +0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed. +0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values: + FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file. + FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file. + +2.6 FILE DATA +The data for each file is composed of the following structure: +00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector, relative to the beginning of the file data. The last entry contains the file size, making it possible to easily calculate the size of any given sector. This table is not present if this information can be calculated (see details below). +immediately following SectorOffsetTable: SECTOR Sectors(SectorsInFile) : Data of each sector in the file, packed end to end (see details below). + +Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may contain less than this, depending on the size of the entire file's data. If the file is compressed or imploded, the sector will be smaller or the same size as the file data it contains. Individual sectors in a compressed or imploded file may be stored uncompressed; this occurs if and only if the file data the sector contains could not be compressed by the algorithm(s) used (if the compressed sector size was greater than or equal to the size of the file data), and is indicated by the sector's size in SectorOffsetTable being equal to the size of the file data in the sector (which may be calculated from the FileSize). + +The format of each sector depends on the kind of sector it is. Uncompressed sectors are simply the the raw file data contained in the sector. Imploded sectors are the raw compressed data following compression with the implode algorithm (these sectors can only be in imploded files). Compressed sectors (only found in compressed - not imploded - files) are compressed with one or more compression algorithms, and have the following structure: +00h: byte CompressionMask : Mask of the compression types applied to this sector. If multiple compression types are used, they are applied in the order listed below, and decompression is performed in the opposite order. This byte counts towards the total sector size, meaning that the sector will be stored uncompressed if the data cannot be compressed by at least two bytes; as well, this byte is encrypted with the sector data, if applicable. The following compression types are defined (for implementations of these algorithms, see StormLib): + 40h: IMA ADPCM mono + 80h: IMA ADPCM stereo + 01h: Huffman encoded + 02h: Deflated (see ZLib) + 08h: Imploded (see PKWare Data Compression Library) + 10h: BZip2 compressed (see BZip2) +01h: byte(SectorSize - 1) SectorData : The compressed data for the sector. + +If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which contains the entire file data. + +If the file is encrypted, each sector (after compression/implosion, if applicable) is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset) XOR FileSize) (StormLib incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the 0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1. + +The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize. This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously. However, the SectorOffsetTable will be present if the file is compressed/imploded and the file is not stored as a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the archive's sector size). + +2.7 LISTFILE +The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive. The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)" (default language and platform), and is simply a text file with file paths separated by ';', 0Dh, 0Ah, or some combination of these. The file "(listfile)" may not be listed in the listfile. + +2.8 EXTENDED ATTRIBUTES +The extended attributes are optional file attributes for files in the block table. These attributes were added at times after the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes. If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file (default language and platform), in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This file is structured as follows: + +00h: int32 Version : Specifies the extended attributes format version. For now, must be 100. +04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive: + 00000001h: File CRC32s. + 00000002h: File timestamps. + 00000004h: File MD5s. +08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have CRC32s. +immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps. +immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have MD5s. + +2.9 WEAK DIGITAL SIGNATURE +The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation of the RSASSA-PKCS1-v1_5 digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak) RSA key (for more information about this protocol, see the RSA Labs PKCS1 specification). The public key and exponent are stored in a resource in Storm, the private key is stored in a separate file, whose filename is passed to MPQAPI (the private key is not stored in MPQAPI). The signature is stored uncompressed, unencrypted in the file "(signature)" (default language and platform) in the archive. The archive is hashed from the beginning of the archive (ArchiveOffset in the containing file) to the end of the archive (the length indicated by ArchiveSize, or calculated in the Burning Crusade MoPaQ format); the signature file is added to the archive before signing, and the space occupied by the file is considered to be all binary 0s during signing/verification. This file is structured as follows: + +00h: int32 Unknown : Must be 0. +04h: int32 Unknown : Must be 0. +08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored in little-endian order. The structure of this, when decrypted, follows the RSASSA-PKCS1-v1_5 specification; this format is rather icky to work with (I wrote a program to verify this signature using nothing but an MD5 function and huge integer functions; it wasn't pleasant), and best left to an encryption library such as Cryto++. + +2.10 STRONG DIGITAL SIGNATURE +The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well. The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format: + +00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards). +04h: int2048 Signature : The digital signature, stored in little-endian format. + +When the Signature field is decrypted with the public key and exponent, and the resulting large integer is stored in little-endian order, it is structured as follows: + +00h: byte Padding : Must be 0Bh. +01h: byte(235) Padding : Must be BBh. +ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 byte order. + +3. ALGORITHM SOURCE CODE +All of the sample code here assumes little endian machine byte order, that the short type is 16 bits, that the long type is 32 bits, and that the long long type is 64 bits. Adjustments must be made if these assumptions are not correct on a given platform. All code not credited otherwise was written by myself in the writing of this specification. + +3.1 ENCRYPTION/DECRYPTION +Based on code from StormLib. + +unsigned long dwCryptTable[0x500]; + +// The encryption and hashing functions use a number table in their procedures. This table must be initialized before the functions are called the first time. +void InitializeCryptTable() +{ + unsigned long seed = 0x00100001; + unsigned long index1 = 0; + unsigned long index2 = 0; + int i; + + for (index1 = 0; index1 < 0x100; index1++) + { + for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100) + { + unsigned long temp1, temp2; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp1 = (seed & 0xFFFF) << 0x10; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp2 = (seed & 0xFFFF); + + dwCryptTable[index2] = (temp1 | temp2); + } + } +} + +void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + assert(lpbyBuffer); + + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEE; + unsigned long ch; + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B); + seed = *lpdwBuffer + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + assert(lpbyBuffer); + + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEEL; + unsigned long ch; + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111L) | (dwKey >> 0x0B); + seed = ch + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +3.2 HASHING AND FILE KEY COMPUTATION +These functions may have been derived from StormLib code at some point in the very distant past. It was so long ago that I don't remember for certain. + +// Different types of hashes to make with HashString +#define MPQ_HASH_TABLE_OFFSET 0 +#define MPQ_HASH_NAME_A 1 +#define MPQ_HASH_NAME_B 2 +#define MPQ_HASH_FILE_KEY 3 + +// Based on code from StormLib. +unsigned long HashString(const char *lpszString, unsigned long dwHashType) +{ + assert(lpszString); + assert(dwHashType <= MPQ_HASH_FILE_KEY); + + unsigned long seed1 = 0x7FED7FEDL; + unsigned long seed2 = 0xEEEEEEEEL; + int ch; + + while (*lpszString != 0) + { + ch = toupper(*lpszString++); + + seed1 = dwCryptTable[(dwHashType * 0x100) + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + return seed1; +} + +#define BLOCK_OFFSET_ADJUSTED_KEY 0x00020000L + +unsigned long ComputeFileKey(const char *lpszFilePath, const BlockTableEntry &blockEntry, unsigned long nArchiveOffset) +{ + assert(lpszFilePath); + + // Find the file name part of the path + const char *lpszFileName = strrchr(lpszFilePath, '\\'); + if (lpszFileName) + lpszFileName++; // Skip the \ + else + lpszFileName = lpszFilePath; + + // Hash the name to get the base key + unsigned long nFileKey = HashString(lpszFileName, MPQ_HASH_FILE_KEY); + + // Offset-adjust the key if necessary + if (blockEntry.Flags & BLOCK_OFFSET_ADJUSTED_KEY) + nFileKey = (nFileKey + blockEntry.BlockOffset) ^ blockEntry.FileSize; + + return nFileKey; +} + +3.3 FINDING FILES + +#define MPQ_HASH_ENTRY_EMPTY 0xFFFFFFFFL +#define MPQ_HASH_ENTRY_DELETED 0xFFFFFFFEL + +bool FindFileInHashTable(const HashTableEntry *lpHashTable, unsigned long nHashTableSize, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform, unsigned long &iFileHashEntry) +{ + assert(lpHashTable); + assert(nHashTableSize); + assert(lpszFilePath); + + // Find the home entry in the hash table for the file + unsigned long iInitEntry = HashString(lpszFilePath, MPQ_HASH_TABLE_OFFSET) & (nHashTableSize - 1); + + // Is there anything there at all? + if (lpHashTable[iInitEntry].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY) + return false; + + // Compute the hashes to compare the hash table entry against + unsigned long nNameHashA = HashString(lpszFilePath, MPQ_HASH_NAME_A), + nNameHashB = HashString(lpszFilePath, MPQ_HASH_NAME_B), + iCurEntry = iInitEntry; + + // Check each entry in the hash table till a termination point is reached + do + { + if (lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_DELETED) + { + if (lpHashTable[iCurEntry].FilePathHashA == nNameHashA + && lpHashTable[iCurEntry].FilePathHashB == nNameHashB + && lpHashTable[iCurEntry].Language == nLang + && lpHashTable[iCurEntry].Platform == nPlatform) + { + iFileHashEntry = iCurEntry; + + return true; + } + } + + iCurEntry = (iCurEntry + 1) & (nHashTableSize - 1); + } while (iCurEntry != iInitEntry && lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_EMPTY); + + return false; +} + +3.4 DELETING FILES + +bool DeleteFile(HashTableEntry *lpHashTable, unsigned long nHashTableSize, BlockTableEntry *lpBlockTable, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform) +{ + assert(lpHashTable); + assert(nHashTableSize); + assert(lpBlockTable); + + // Find the file in the hash table + unsigned long iFileHashEntry; + + if (!FindFileInHashTable(lpHashTable, nHashTableSize, lpszFilePath, nLang, nPlatform, iFileHashEntry)) + return false; + + // Get the block table index before we nuke the hash table entry + unsigned long iFileBlockEntry = lpHashTable[iFileHashEntry].FileBlockIndex; + + // Delete the file's entry in the hash table + memset(&lpHashTable[iFileHashEntry], 0xFF, sizeof(HashTableEntry)); + + // If the next entry is empty, mark this one as empty; otherwise, mark this as deleted. + if (lpHashTable[(iFileHashEntry + 1) & (nHashTableSize - 1)].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY) + lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_EMPTY; + else + lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_DELETED; + + // If the block occupies space, mark the block as free space; otherwise, clear the block table entry. + if (lpBlockTable[iFileBlockEntry].BlockSize > 0) + { + lpBlockTable[iFileBlockEntry].FileSize = 0; + lpBlockTable[iFileBlockEntry].Flags = 0; + } + else + memset(&lpBlockTable[iFileBlockEntry], 0, sizeof(BlockTableEntry); + + return true; +} + +3.5 CONVERSION OF FILETIME AND time_t +This code assumes that the base ("zero") date for time_t is 01/01/1970. This is true on Windows, Unix System V systems, and Mac OS X. It is unknown whether this is true on all other platforms. You'll need to research this yourself, if you plan on porting it somewhere else. + +#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970 + +bool GetTimeFromFileTime(const FILETIME &fileTime, time_t &time) +{ + // The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601 + unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime; + + if (nTime < EPOCH_OFFSET) + return false; + + nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970 + nTime /= 10000000ULL; // Convert 100 ns to sec + + time = (time_t)nTime; + + // Test for overflow (FILETIME is 64 bits, time_t is 32 bits) + if ((nTime - (unsigned long long)time) > 0) + return false; + + return true; +} + +void GetFileTimeFromTime(const time_t &time, FILETIME &fileTime) +{ + unsigned long long nTime = (unsigned long long)time; + + nTime *= 10000000ULL; + nTime += EPOCH_OFFSET; + + fileTime.dwLowDateTime = (DWORD)nTime; + fileTime.dwHighDateTime = (DWORD)(nTime >> 32); +} + +3.6 FORMING A 64-BIT LARGE ARCHIVE OFFSET FROM 32-BIT AND 16-BIT COMPONENTS +unsigned long long MakeLargeArchiveOffset(unsigned long nOffsetLow, unsigned short nOffsetHigh) +{ + return ((unsigned long long)nOffsetHigh << 32) + (unsigned long long)nOffsetLow; +} + +4. REVISION HISTORY +1.0 + - Updated to include most of the changes found in the Burning Crusade Friends and Family beta + +0.91. + - Updated several structure member descriptions + - Listed the full set of characters that can separate list file entries + - Noted that (attributes), (listfile), and (signature) use the default language and platform codes + - Redid part of the file data specs to clarify the format of sectors + - Enhanced descriptions of the different kinds of block table entries + - Added ComputeFileKey, FindFileInHashTable, and DeleteFile source \ No newline at end of file diff --git a/contrib/vmap_extractor_v2/stormdll/StormDll.cpp b/contrib/vmap_extractor_v2/stormdll/StormDll.cpp new file mode 100644 index 000000000..2031180c7 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormdll/StormDll.cpp @@ -0,0 +1,117 @@ +/*****************************************************************************/ +/* Storm.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This is just a dummy module for building import library for Storm.dll */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.04.03 1.00 Lad The first version of Storm.cpp */ +/*****************************************************************************/ + +#include + +#define BUILDING_STORM_CPP +#define STORM_ALTERNATE_NAMES +#include "StormDll.h" + +BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(CloseFile)(HANDLE hFile) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +LCID WINAPI SFILE(SetLocale)(LCID nNewLocale) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(Destroy)() +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SCOMP(Compress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} diff --git a/contrib/vmap_extractor_v2/stormdll/StormDll.def b/contrib/vmap_extractor_v2/stormdll/StormDll.def new file mode 100644 index 000000000..e5cfea38c --- /dev/null +++ b/contrib/vmap_extractor_v2/stormdll/StormDll.def @@ -0,0 +1,25 @@ +; Storm definition file with alternate Storm.dll names +LIBRARY "Storm" + +EXPORTS + StormCloseArchive @252 ; 0x0FC + StormCloseFile @253 ; 0x0FD + StormDestroy @262 ; 0x106 + StormGetFileArchive @264 ; 0x108 + StormGetFileSize @265 ; 0x109 + StormOpenArchive @266 ; 0x10A + StormOpenFile @267 ; 0x10B + StormOpenFileEx @268 ; 0x10C + StormReadFile @269 ; 0x10D + StormSetBasePath @270 ; 0x10E + StormSetFilePointer @271 ; 0x10F + StormSetLocale @272 ; 0x110 + StormGetBasePath @273 ; 0x111 + StormGetArchiveName @275 ; 0x113 + StormGetFileName @276 ; 0x114 + +; StormSetLastError @465 ; 0x + + StormCompress @551 ; 0x227 + StormDecompress @552 ; 0x228 + \ No newline at end of file diff --git a/contrib/vmap_extractor_v2/stormdll/StormDll.h b/contrib/vmap_extractor_v2/stormdll/StormDll.h new file mode 100644 index 000000000..6d67820a2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormdll/StormDll.h @@ -0,0 +1,67 @@ +/*****************************************************************************/ +/* Storm.h Copyright Justin Olbrantz(Quantam) 2000 */ +/*---------------------------------------------------------------------------*/ +/* Storm Interface Library v1.0 for Windows */ +/* */ +/* Author : Justin Olbrantz(Quantam) */ +/* E-mail : omega@dragonfire.net */ +/* WWW : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/ */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.00 1.00 Qua The first version of Storm.h */ +/* 11.04.03 1.00 Lad Added some functions */ +/*****************************************************************************/ + +// We need the Windows data types for the Storm prototypes +#include + +#ifndef __STORM_H__ +#define __STORM_H__ + +// Somethimes is necessary to change the function names so they +// will not conflict with other MPQ tools. +#ifdef STORM_ALTERNATE_NAMES + #define SFILE(Name) Storm##Name + #define SCOMP(Name) Storm##Name +#else + #define SFILE(Name) SFile##Name + #define SCOMP(Name) SComp##Name +#endif + + +// Just in case anyone is still using C out there +#ifdef __cplusplus +extern "C" { +#endif + +// Storm file function prototypes +BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ); +BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ); +BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength); +BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile); +BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile); +BOOL WINAPI SFILE(CloseFile)(HANDLE hFile); +DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh); +BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ); +BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength); +DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod); +BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped); +LCID WINAPI SFILE(SetLocale)(LCID nNewLocale); +BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength); +BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath); + +// Storm (de)compression functions +BOOL WINAPI SCOMP(Compress) (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel); +BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength); + + +#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP) +#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll +#endif + +#ifdef __cplusplus +} +#endif + +#endif // __STORM_H__ diff --git a/contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp b/contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp new file mode 100644 index 000000000..665e5d38e --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp @@ -0,0 +1,697 @@ +/*********************************************************************** +* +* Description: GfxDecode -- functions for reading Diablo's GFX files +* Author: Marko Friedemann +* Created at: Son Jan 27 15:20:43 CET 2002 +* Computer: hangloose.flachland-chemnitz.de +* System: Linux 2.4.16 on i686 +* +* Copyright (c) 2002 BMX-Chemnitz.DE All rights reserved. +* +* --------------------------------------------------------------------- +* included are functions for getting: +* - the framecount of .CEL-files -> celGetFrameCount() +* - single frames of .CEL-files -> celGetFrameData() +* - the framecount of .CL2-files -> cl2GetFrameCount() +* - single directions of .CL2-files (all frames) -> cl2GetDirData() +* - single .PCX-files (256 color; v2, v5) -> pcxGetData() +***********************************************************************/ + +#include +#include +#include + +#include "StormLib.h" + +#define TRANS_COL 256 + +using std::cerr; +using std::vector; + +/****** RAMP stuff ***************************************************** + * for a more detailed description/explanation see below + ***********************************************************************/ +// two variations: one/two ramp(s) +static const uint16_t c_2RampSize = 544; // the frame size +static const uint16_t c_1RampSize = 800; // the frame size + +// ramps (both variations) can be either left or right +static const uint16_t c_RampOffsetLeft[17] = { + 0, // __ + 8, // + 8 note that this __-- + 24, // + 16 "drawing" is __-- + 48, // + 24 upside down! __-- this area + 80, // + 32 __-- is always + 120, // + 40 __-- colored + 168, // + 48 __-- + 224, // + 56 __-- lower ramp ends here (+30 == 254) + 288, // + 64 --__ upper ramp might be missing + 348, // + 60 | --__ + 400, // + 52 | --__ this area + 444, // + 44 | --__ is always + 480, // + 36 | --__ colored + 508, // + 28 | either trans- --__ + 528, // + 20 | parent or colored --__ + 540, // + 12 | --__ +2 Pixels = 544 + 542 // + 2 | this last one doesn't exist, it's those^ 2 pixels +}; + +static const uint16_t c_RampOffsetRight[17] = { + 2, // __ before this, there are 2 Pixels + 14, // + 12 --__ 4^2 - 2 + 34, // + 20 --__ 6^2 - 2 + 62, // + 28 this area --__ 8^2 - 2 + 98, // + 36 is always --__ 10^2 - 2 pattern anyone? ;) + 142, // + 44 colored --__ + 194, // + 52 --__ + 254, // + 60 lower ramp ends here --__ (-30 == 224) + 318, // + 64 upper ramp might be missing __-- + 374, // + 56 __-- | + 422, // + 48 this area __-- | note that this + 462, // + 40 is always __-- | "drawing" + 494, // + 32 colored __-- eiter trans- | is upside down! + 518, // + 24 __-- parent or colored | + 534, // + 16 __-- | + 542, // + 8 __-- +2 Startpixels = 544 | + 542 // + 0 this last one doesn't exist, it | would be EOF +}; + +/****** FrameBuffer class ********************************************** + * holds buffers and size information of the actual target image + * purpose: buffer management and avoidance of ugly globals + **********************************************************************/ +class FrameBuf +{ + protected: + vector vecData; + uint8_t *pCurrRow; + uint8_t *pPalette; + uint16_t uRows; + uint16_t *upYSize; + uint16_t *upMaxX; + public: + uint16_t uCols; + uint16_t uXSize; + uint16_t uMaxBlock; + uint16_t uFrameNum; + bool bHasBlocks; + bool bHasRamps; + FrameBuf( + uint8_t *pPal=NULL, uint16_t frame=0, uint16_t xsize=0, + uint16_t *pysize=NULL, uint16_t *pmaxx=NULL, uint16_t maxblock=0) + { + pCurrRow = new uint8_t[4*xsize]; + pPalette = pPal; + uCols = 0; + uRows = 0; + uXSize = xsize; + uFrameNum = frame; + uMaxBlock = maxblock; + upYSize = pysize; + upMaxX = pmaxx; + bHasBlocks= false; + bHasRamps = false; + } + ~FrameBuf() + { + delete[] pCurrRow; + for (vector ::iterator vi=vecData.begin(); vi!=vecData.end(); vi++) + delete[] *vi; + vecData.clear(); + } + void addLine() + { + ++uRows; + uCols = 0; + vecData.push_back(pCurrRow); + pCurrRow = new uint8_t[4*uXSize]; + } + void addPixel(uint16_t uColorNum) + { + if (uColorNum > TRANS_COL) { + cerr << "\n*** there seemed to be an error, illegal color index " << uColorNum; + cerr << "\n +++ at (" << uCols << "," << uRows << "), see for yourself *** \n\n"; + uColorNum = TRANS_COL; // sane setting to avoid segfaults + } + + memcpy(pCurrRow + 4*uCols, pPalette + 4*uColorNum, 4*sizeof(uint8_t)); + if (++uCols == uXSize) + addLine(); + else if ((uColorNum != TRANS_COL) && (upMaxX != NULL) && (uCols > *upMaxX)) + *upMaxX = uCols; + } + // used to return the actual image data + uint8_t *getData() + { + uint16_t i; + vector ::reverse_iterator vri; + // allocate a buffer to hold the actual image size + uint8_t *tmp = new uint8_t[4*uXSize*uRows]; + + // the lines are upside down inside the vector, use reverse iterator + for (i=0, vri=vecData.rbegin(); vri!=vecData.rend(); vri++, i++) + memcpy(tmp+4*uXSize*i, *vri, 4*uXSize*sizeof(uint8_t)); + + *upYSize = uRows; // set height + + if (uCols > 0) { + cerr << "\n*** there seemed to be an error (last line does not match boundary, " << uCols << " pixels left)"; + cerr << "\n +++ this is often caused by specifying an invalid width, see for yourself *** \n\n"; + } + + return tmp; + } +}; + +uint16_t WINAPI celGetFrameCount(uint8_t *pFileBuf) +{ + uint32_t tmp; + memcpy(&tmp, pFileBuf, sizeof(uint32_t)); + return (uint16_t)tmp; +} + +/***** Block Decoder *************************************************** + * one of three possible decoding techniques necessary for .cel + * possible block contents are either colored (in that case the + * appropriate number of pixels are read) or transparent pixels + * there are neither ramps nor plain pixels allowed here + ***********************************************************************/ +uint8_t *celDecodeBlocks(uint8_t *pFileBuf, FrameBuf *pFrame, uint32_t *framestart) +{ + uint32_t uFilePos=framestart[pFrame->uFrameNum]; + uint8_t cRead=0, i=0; + + if (!pFrame->bHasBlocks) // sanity check + return NULL; + + while (uFilePos < framestart[pFrame->uFrameNum+1]) { + cRead = pFileBuf[uFilePos++]; + + if ((uFilePos == framestart[pFrame->uFrameNum]+1)) + // TODO: what is this 0x0A 0x00 stuff all about? + if ((cRead == 0x0A) && (pFileBuf[uFilePos] == 0x00)) { + uFilePos += 9; + cRead = pFileBuf[uFilePos++]; + } + + if (cRead > 0x7F) + // transparent block (complement, 256-val) + for (i=0; i<256-cRead; i++) + pFrame->addPixel(TRANS_COL); + else if (cRead < pFrame->uMaxBlock + 1) + // pixel block (block size pixels to be read!) + for (i=0; iaddPixel(pFileBuf[uFilePos++]); + else + cerr << "\n*** block mode: illegal block (> max_size) ***\n\n"; + } + return pFrame->getData(); +} + +/***** Ramp Decoder **************************************************** + * the second of three possible decoding techniques necessary for .cel + * each block save the first/last is enclosed by two 0x00 pairs + * those blocks affect _TWO_ rows with one being 2 colored pixels shorter + * the first/last "block" affects only one row + ***********************************************************************/ +uint8_t *celDecodeRamps(uint8_t *pFileBuf, FrameBuf *pFrame, uint32_t *framestart, bool bLeft) +{ + uint32_t uFrameLen = framestart[pFrame->uFrameNum+1]-framestart[pFrame->uFrameNum]; + uint32_t uFilePos=0; + uint16_t uBlockLen=0, i=0, j=0; + bool bFirstLonger=false; + + if (!pFrame->bHasRamps) // sanity check + return NULL; + + if (pFrame->uXSize != 32) // only used in that case + return NULL; + + if (!bLeft) { // get first two pixels for right side ramps + pFrame->addPixel(pFileBuf[framestart[pFrame->uFrameNum]]); + pFrame->addPixel(pFileBuf[framestart[pFrame->uFrameNum]+1]); + } + + // do all the ramp blocks + for (i=0; i<(uFrameLen == c_2RampSize ? 15 : 7); i++) { + uBlockLen = (bLeft ? (c_RampOffsetLeft[i+1] - c_RampOffsetLeft[i]) : (c_RampOffsetRight[i+1] - c_RampOffsetRight[i])); + uFilePos = framestart[pFrame->uFrameNum] + (bLeft ? c_RampOffsetLeft[i] : c_RampOffsetRight[i]) + 2; + bFirstLonger = (i>(bLeft ? 7 : 6)); + if (bLeft) { + // OK, first line, starting with transparency + for (j=0; juXSize - uBlockLen/2 + (bFirstLonger ? 0 : 2); j++) + pFrame->addPixel(TRANS_COL); + // fill it up with the pixel block + for (j=0; jaddPixel(pFileBuf[uFilePos++]); + // second line, starting again with transparency + for (j=0; juXSize - uBlockLen/2 + (bFirstLonger ? 2 : 0); j++) + pFrame->addPixel(TRANS_COL); + // fill the second line with the remaining pixels + for (j=0; jaddPixel(pFileBuf[uFilePos++]); + } else { + if (pFrame->uCols != 0) // fill current line with trans (if not empty) + for (j=pFrame->uXSize - pFrame->uCols; j>0; j--) + pFrame->addPixel(TRANS_COL); + // OK, insert the first pixels into a new line + for (j=0; jaddPixel(pFileBuf[uFilePos++]); + // fill the line with transparency + for (j=0; juXSize - uBlockLen/2 + (bFirstLonger ? 0 : 2); j++) + pFrame->addPixel(TRANS_COL); + // start a second line with the remaining pixels + for (j=0; jaddPixel(pFileBuf[uFilePos++]); + } + } + + // now read the last 0x00 pair and fill up + uBlockLen = (uFrameLen == c_2RampSize ? 30 : 2); // one or two ramps? + uFilePos = framestart[pFrame->uFrameNum] + (bLeft ? c_RampOffsetLeft[i] : c_RampOffsetRight[i]) + 2; + // the transparency for the last (single) 0x00 pair + for (j=0; jaddPixel(TRANS_COL); + if (bLeft) { // left side only: the remaining line + for (j=0; juXSize - uBlockLen; j++) + pFrame->addPixel(pFileBuf[uFilePos++]); + } + + // now the rest of the file (plain) + while (uFilePos < framestart[pFrame->uFrameNum+1]) + pFrame->addPixel(pFileBuf[uFilePos++]); + + // the uppermost line is emtpy when 2 ramps are used + if (uFrameLen == c_2RampSize) + for (j=0; juXSize; j++) + pFrame->addPixel(TRANS_COL); + + return pFrame->getData(); +} + +/***** celGetFrameData ************************************************* + * decode .cel data for given frame and xsize + * Args: + * *vpFileBuf the buffer containing the filecontent + * *palette the palette (4 bytes for each of the 257 entries) + * 256 colors are needed + 1 for alpha + * uXSize this information must be given + * uFrameNume the frame to get + * *uYSize the actual value is returned therein + * *uMaxX this can be used (if != NULL) to get the column + * of the rightmost nontransparent pixel (useable + * eg for fonts) + * + * Returns: an array containing 4 Bytes (RGBA) for each pixel + * + * --------------------------------------------------------------- + * Comments: dirty hack, started from scratch @ 2000-10-11 + * cleanly rewritten during incorporation into ladiks StormLib + * status: structured hack ;) + * + * It took me approx. 6 days to understand the format basics (hex viewer) + * For this I had a little help from a dos tool ("ddecode", from + * www.cowlevel.com, binary only, no sources) which, however, gave + * me the general idea what the pictures are actually supposed to look like. + * + * The fine adjustments, however, took quite some time and a little luck. + * After I had written to various people (mickyk and ladik), which could + * not help me, but wished best luck (thanks, btw, it helped ;)), I tried + * some reverse engineering which was not succesful in the end. + * + * I then had incidentally a new idea of what could be going on @ 2002-01-23. + * It just came to my mind that I could retry some actual painting in + * reverse order (had done that before to no avail) and when looking closer + * at it I realized the "ramp" stuff. This really is the trickiest part and + * it took me some eight days to implement it without breaking the other + * parts of the code. Very odd format indeed. + * + * TODO: learn what 0x0A 0x00 means + **********************************************************************/ +uint8_t * WINAPI celGetFrameData(uint8_t *pFileBuf, uint8_t *palette, uint16_t uXSize, uint16_t uFrameNum, uint16_t *uYSize, uint16_t *uMaxX) +{ + FrameBuf *pFrame; + uint32_t *framestart=NULL, frames=0, uFilePos=0; + uint16_t i, tmpWord=0; + uint8_t cRead=0, *data; + + memcpy(&frames, pFileBuf, sizeof(uint32_t)); + uFilePos += sizeof(uint32_t); + + if (pFileBuf == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (palette == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (uFrameNum > frames-1) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (uYSize == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + // in case we want to know the rightmost pixels column (usable eg. for fonts) + if (uMaxX != NULL) + *uMaxX = 0; + + // get the frame offsets + framestart = new uint32_t[frames+1]; + for (i=0; ibHasRamps = (i==(uFrameLen == c_2RampSize ? 16 : 8)); + if (!pFrame->bHasRamps) { // only one can apply + for (i=0; i<(uFrameLen == c_2RampSize ? 16 : 8); i++) { + memcpy(&tmpWord, pFileBuf+framestart[uFrameNum]+c_RampOffsetRight[i], sizeof(uint16_t)); + if (tmpWord != 0) + break; + } + pFrame->bHasRamps = (i==(uFrameLen == c_2RampSize ? 16 : 8)); // bRampsLeft stays false in this case + } + + if (pFrame->bHasRamps) { // decode ramps and be off (if appropriate) + data = celDecodeRamps(pFileBuf, pFrame, framestart, bRampsLeft); + delete pFrame; + delete[] framestart; + return data; + } + } + + /*********** block detection *************************************** + * 0x0A as start byte seems to be sufficient (though I still dunno + * what the trailing 10 bytes mean); in any other case we act as if + * blocks were to be used and check afterwards if the image looks + * OK (that is, the last line has no pixels in it) + ******************************************************************/ + + cRead = pFileBuf[framestart[uFrameNum]]; + if (cRead == 0x0A) // sufficient + pFrame->bHasBlocks = true; + // if width == 32 && framelen == 32*32, assume plain + else if ((uXSize != 32) || (uFrameLen != 32*32)) { // check needed + uFilePos=framestart[uFrameNum]; + i=0; + // rush through the frame + while (uFilePos < framestart[uFrameNum+1]) { + cRead = pFileBuf[uFilePos++]; + + // transparency blocks + while (cRead > 0x7F) { + i += 256-cRead; + i %= uXSize; + if (uFilePos < framestart[uFrameNum+1]) + cRead = pFileBuf[uFilePos++]; + else + cRead = 0; + } + + // colored pixel block + if (uFilePos < framestart[uFrameNum+1]) { + if (cRead < pFrame->uMaxBlock + 1) { + i+=cRead; + i%=uXSize; + uFilePos+=cRead; + } else { + // when the value is out of valid blockrange + i=1; // trigger error (1%uXSize != 0) + break; + } + } + } + if (i%uXSize == 0) // looks as if we got it right + pFrame->bHasBlocks=true; + } + + if (pFrame->bHasBlocks) { // use block decoder if appropriate + data = celDecodeBlocks(pFileBuf, pFrame, framestart); + delete pFrame; + delete[] framestart; + return data; + } + + // plain mode (#3), read each color index and write the pixel + uFilePos=framestart[uFrameNum]; + while (uFilePos < framestart[uFrameNum+1]) + pFrame->addPixel(pFileBuf[uFilePos++]); + + // cleanup, return image data and height + data = pFrame->getData(); + delete pFrame; + delete[] framestart; + return data; +} + +uint16_t WINAPI cl2GetFrameCount(uint8_t *pFileBuf) +{ + uint32_t tmp; + memcpy(&tmp, pFileBuf, sizeof(uint32_t)); + memcpy(&tmp, pFileBuf+tmp, sizeof(uint32_t)); + return (uint16_t)tmp; +} + +/***** cl2GetDirData *************************************************** + * decodes all frames of a .cl2 for given direction and xsize + * Args: + * *pFileBuf the buffer containing the filecontent + * *palette the palette (4 bytes for each of the 257 entries) + * 256 colors are needed + 1 for alpha + * uXSize this information must be given + * uDirNum the direction to get the frames from + * *uYSize the actual height is returned herein + * + * Returns: arrays containing 4 Bytes (RGBA) for each pixel + * where is read at runtime and handed back via *uFrames + * + * --------------------------------------------------------------- + * Comments: dirty hack, started from scratch @ 2000-10-12 + * + * The format basics are similar to .cel, with the main difference + * that the values read have reverse interpretation. In .cel a value + * greater than 0x7F means transparency, while in .cl2 this means + * color and vice-versa. .cl2 has the additional understanding + * of blocks of the same color (0x80 .. 0xBF) where the one color is + * written multiple times. + * + * .cl2 only uses the block scheme, so there is no detection + * necessary in order to get it right. The only thing still unknown + * is that 0x0A 0x00 stuff... + * + * TODO: learn what 0x0A 0x00 means + ***********************************************************************/ +BYTE ** WINAPI cl2GetDirData(BYTE *pFileBuf, BYTE *palette, WORD uXSize, WORD uDirNum, WORD *uYSize) +{ + FrameBuf *pFrame; + uint32_t frames=0, *framestart=NULL, uFilePos=0; + uint16_t i, fc; + uint8_t cRead=0, **data=NULL; + + if (pFileBuf == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (palette == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (uDirNum > 7) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (uYSize == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + // get direction offsets + uint32_t dirstart[8]; + for (i=0; i<8; i++) { + memcpy(&dirstart[i], pFileBuf+uFilePos, sizeof(uint32_t)); + uFilePos += sizeof(uint32_t); + } + + uFilePos = dirstart[uDirNum]; + + memcpy(&frames, pFileBuf+uFilePos, sizeof(uint32_t)); + uFilePos += sizeof(uint32_t); + + data = new uint8_t*[frames]; + + // get frame offsets + framestart = new uint32_t[frames+1]; + for (i=0; iaddPixel(TRANS_COL); + } else if (cRead < 0xC0) { + // read the next byte and write it <0xBF - cRead> times + for (i=0; i<0xBF - cRead; i++) + pFrame->addPixel(pFileBuf[uFilePos]); + ++uFilePos; + } else // cRead > 0xBF + // read a block of the given size and write it + for (i=0; i < 256-cRead; i++) + pFrame->addPixel(pFileBuf[uFilePos++]); + } + + // got the frame data, save it + data[fc] = pFrame->getData(); + delete pFrame; + } + + delete[] framestart; + return data; +} + +/****** pcxGetData ***************************************************** + * decodes pcx files (256 color, as in diablo mpq) + * Args: + * *pFileBuf the buffer containing the filecontent + * uFileSize the size of the file buffer + * uTransColor the palette entry to be transparent + * *uXSize the actual width is returned herein + * *uYSize the actual height is returned herein + * + * Returns: an array containing 4 Bytes (RGBA) for each pixel + * + * --------------------------------------------------------------- + * Comments: format info and pseudocode taken from: + * Klaus Holtorf, "Das Handbuch der Grafikformate" + * ISBN 3-7723-6393-8 + ***********************************************************************/ +BYTE * WINAPI pcxGetData(BYTE *pFileBuf, DWORD uFileSize, BYTE uTransColor, WORD *uXSize, WORD *uYSize) +{ + uint32_t uFilePos=0; + uint32_t uDataRead=0; // potentially big! (logo.pcx: 550 * 216 * 15 = 1,782,000) + uint16_t i=0; + uint8_t *data, *palette; + uint8_t uColorNum=0, uCount=0; + + struct pcx_header_t { + uint8_t id; + uint8_t version; + uint8_t compressed; + uint8_t bpp; + uint16_t x0; + uint16_t y0; + uint16_t x1; + uint16_t y1; + uint16_t xdpi; + uint16_t ydpi; + uint8_t pal[16][3]; + uint8_t reserved; + uint8_t layers; + uint16_t rowbytes; + uint16_t colortype; + uint8_t pad[58]; + } pcxHeader; + + if (pFileBuf == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (uXSize == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (uYSize == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + // get image information + memcpy(&pcxHeader, pFileBuf, sizeof(struct pcx_header_t)); + *uXSize = (pcxHeader.x1 - pcxHeader.x0 + 1); + *uYSize = (pcxHeader.y1 - pcxHeader.y0 + 1); + + if ((pcxHeader.version != 2) && (pcxHeader.version != 5)) { + cerr << "cannot handle pcx v" << pcxHeader.version << "\n"; + return NULL; + } + + // get palette + palette = new uint8_t[256*4]; + if (pFileBuf[uFileSize - 768 - 1] != 0x0C) { + cerr << "palette error at " << uFileSize - 768 - 1 << "\n"; + return NULL; + } + for (i=0; i<256; i++) { + memcpy(palette+i*4, pFileBuf+uFileSize-768+i*3, 3*sizeof(uint8_t)); + palette[i*4+3] = 0xFF; + } + memset(palette+uTransColor*4, 0, 4*sizeof(uint8_t)); // transparent black + + // start right after the header + uFilePos = sizeof(struct pcx_header_t); + data = new uint8_t[*uXSize * *uYSize * 4]; + while (uDataRead < (uint32_t)(*uXSize * *uYSize)) { + // decompress + uColorNum = pFileBuf[uFilePos++]; + if ((pcxHeader.compressed) && (uColorNum > 0xBF)) { + uCount = (uColorNum & 0x3F); + uColorNum = pFileBuf[uFilePos++]; + } else + uCount = 1; + + // draw count pixels with color val + for (i=0; i 0) + { + dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; + ch = *pdwTable; + *pdwTable++ = ch ^ (dwSeed1 + dwSeed2); + + dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); + dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; + } +} + +void DecryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength) +{ + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; // One key character + + // Prepare seeds + while(*pbKey != 0) + { + ch = toupper(*pbKey++); + + dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + + // Decrypt it + dwSeed2 = 0xEEEEEEEE; + while(dwLength-- > 0) + { + dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; + ch = *pdwTable ^ (dwSeed1 + dwSeed2); + + dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); + dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; + *pdwTable++ = ch; + } +} + +//----------------------------------------------------------------------------- +// Encrypting and decrypting block table + +void EncryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength) +{ + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; // One key character + + // Prepare seeds + while(*pbKey != 0) + { + ch = toupper(*pbKey++); + + dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + + // Decrypt it + dwSeed2 = 0xEEEEEEEE; + while(dwLength-- > 0) + { + dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; + ch = *pdwTable; + *pdwTable++ = ch ^ (dwSeed1 + dwSeed2); + + dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); + dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; + } +} + +void DecryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength) +{ + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; // One key character + + // Prepare seeds + while(*pbKey != 0) + { + ch = toupper(*pbKey++); + + dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + + // Encrypt it + dwSeed2 = 0xEEEEEEEE; + while(dwLength-- > 0) + { + dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; + ch = *pdwTable ^ (dwSeed1 + dwSeed2); + + dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); + dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; + *pdwTable++ = ch; + } +} + +//----------------------------------------------------------------------------- +// Functions tries to get file decryption key. The trick comes from block +// positions which are stored at the begin of each compressed file. We know the +// file size, that means we know number of blocks that means we know the first +// DWORD value in block position. And if we know encrypted and decrypted value, +// we can find the decryption key !!! +// +// hf - MPQ file handle +// block - DWORD array of block positions +// ch - Decrypted value of the first block pos + +DWORD DetectFileSeed(DWORD * block, DWORD decrypted) +{ + DWORD saveSeed1; + DWORD temp = *block ^ decrypted; // temp = seed1 + seed2 + temp -= 0xEEEEEEEE; // temp = seed1 + StormBuffer[0x400 + (seed1 & 0xFF)] + + for(int i = 0; i < 0x100; i++) // Try all 255 possibilities + { + DWORD seed1; + DWORD seed2 = 0xEEEEEEEE; + DWORD ch; + + // Try the first DWORD (We exactly know the value) + seed1 = temp - StormBuffer[0x400 + i]; + seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; + ch = block[0] ^ (seed1 + seed2); + + if(ch != decrypted) + continue; + + // Add 1 because we are decrypting block positions + saveSeed1 = seed1 + 1; + + // If OK, continue and test the second value. We don't know exactly the value, + // but we know that the second one has lower 16 bits set to zero + // (no compressed block is larger than 0xFFFF bytes) + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + + seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; + ch = block[1] ^ (seed1 + seed2); + + if((ch & 0xFFFF0000) == 0) + return saveSeed1; + } + return 0; +} + +// Function tries to detect file seed. It expectes at least two uncompressed bytes +DWORD DetectFileSeed2(DWORD * pdwBlock, UINT nDwords, ...) +{ + va_list argList; + DWORD dwDecrypted[0x10]; + DWORD saveSeed1; + DWORD dwTemp; + DWORD i, j; + + // We need at least two DWORDS to detect the seed + if(nDwords < 0x02 || nDwords > 0x10) + return 0; + + va_start(argList, nDwords); + for(i = 0; i < nDwords; i++) + dwDecrypted[i] = va_arg(argList, DWORD); + va_end(argList); + + dwTemp = (*pdwBlock ^ dwDecrypted[0]) - 0xEEEEEEEE; + for(i = 0; i < 0x100; i++) // Try all 255 possibilities + { + DWORD seed1; + DWORD seed2 = 0xEEEEEEEE; + DWORD ch; + + // Try the first DWORD + seed1 = dwTemp - StormBuffer[0x400 + i]; + seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; + ch = pdwBlock[0] ^ (seed1 + seed2); + + if(ch != dwDecrypted[0]) + continue; + + saveSeed1 = seed1; + + // If OK, continue and test all bytes. + for(j = 1; j < nDwords; j++) + { + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + + seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; + ch = pdwBlock[j] ^ (seed1 + seed2); + + if(ch == dwDecrypted[j] && j == nDwords - 1) + return saveSeed1; + } + } + return 0; +} + + +//----------------------------------------------------------------------------- +// Encrypting and decrypting MPQ blocks + +void EncryptMPQBlock(DWORD * block, DWORD dwLength, DWORD dwSeed1) +{ + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + // Round to DWORDs + dwLength >>= 2; + + while(dwLength-- > 0) + { + dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; + ch = *block; + *block++ = ch ^ (dwSeed1 + dwSeed2); + + dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); + dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; + } +} + +void DecryptMPQBlock(DWORD * block, DWORD dwLength, DWORD dwSeed1) +{ + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + // Round to DWORDs + dwLength >>= 2; + + while(dwLength-- > 0) + { + dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; + ch = *block ^ (dwSeed1 + dwSeed2); + + dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); + dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; + *block++ = ch; + } +} + + +DWORD DecryptHashIndex(TMPQArchive * ha, const char * szFileName) +{ + BYTE * pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + while(*pbKey != 0) + { + ch = toupper(*pbKey++); + + dwSeed1 = StormBuffer[0x000 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + return (dwSeed1 & (ha->pHeader->dwHashTableSize - 1)); +} + +DWORD DecryptName1(const char * szFileName) +{ + BYTE * pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + while(*pbKey != 0) + { + ch = toupper(*pbKey++); + + dwSeed1 = StormBuffer[0x100 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + return dwSeed1; +} + +DWORD DecryptName2(const char * szFileName) +{ + BYTE * pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + int ch; + + while(*pbKey != 0) + { + ch = toupper(*pbKey++); + + dwSeed1 = StormBuffer[0x200 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + return dwSeed1; +} + +DWORD DecryptFileSeed(const char * szFileName) +{ + BYTE * pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; // EBX + DWORD dwSeed2 = 0xEEEEEEEE; // ESI + DWORD ch; + + while(*pbKey != 0) + { + ch = toupper(*pbKey++); // ECX + + dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + return dwSeed1; +} + +TMPQHash * GetHashEntry(TMPQArchive * ha, const char * szFileName) +{ + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash0; // File hash entry (start) + TMPQHash * pHash; // File hash entry (current) + DWORD dwIndex = (DWORD)(DWORD_PTR)szFileName; + DWORD dwName1; + DWORD dwName2; + + // If filename is given by index, we have to search all hash entries for the right index. + if(dwIndex <= ha->pHeader->dwBlockTableSize) + { + // Pass all the hash entries and find the + for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++) + { + if(pHash->dwBlockIndex == dwIndex) + return pHash; + } + return NULL; + } + + // Decrypt name and block index + dwIndex = DecryptHashIndex(ha, szFileName); + dwName1 = DecryptName1(szFileName); + dwName2 = DecryptName2(szFileName); + pHash = pHash0 = ha->pHashTable + dwIndex; + + // Look for hash index + while(pHash->dwBlockIndex != HASH_ENTRY_FREE) + { + if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex != HASH_ENTRY_DELETED) + return pHash; + + // Move to the next hash entry + if(++pHash >= pHashEnd) + pHash = ha->pHashTable; + if(pHash == pHash0) + break; + } + + // File was not found + return NULL; +} + +// Retrieves the locale-specific hash entry +TMPQHash * GetHashEntryEx(TMPQArchive * ha, const char * szFileName, LCID lcLocale) +{ + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash0 = NULL; // Language-neutral hash entry + TMPQHash * pHashX = NULL; // Language-speficic + TMPQHash * pHash = GetHashEntry(ha, szFileName); + + if(pHash != NULL) + { + TMPQHash * pHashStart = pHash; + DWORD dwName1 = pHash->dwName1; + DWORD dwName2 = pHash->dwName2; + + while(pHash->dwBlockIndex != HASH_ENTRY_FREE) + { + if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2) + { + if(pHash->lcLocale == LANG_NEUTRAL) + pHash0 = pHash; + if(pHash->lcLocale == lcLocale) + pHashX = pHash; + + // If both found, break the loop + if(pHash0 != NULL && pHashX != NULL) + break; + } + + if(++pHash >= pHashEnd) + pHash = ha->pHashTable; + if(pHash == pHashStart) + return NULL; + } + + if(lcLocale != LANG_NEUTRAL && pHashX != NULL) + return pHashX; + if(pHash0 != NULL) + return pHash0; + return NULL; + } + + return pHash; +} + +// Encrypts file name and gets the hash entry +// Returns the hash pointer, which is always within the allocated array +TMPQHash * FindFreeHashEntry(TMPQArchive * ha, const char * szFileName) +{ + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash0; // File hash entry (search start) + TMPQHash * pHash; // File hash entry + DWORD dwIndex = DecryptHashIndex(ha, szFileName); + DWORD dwName1 = DecryptName1(szFileName); + DWORD dwName2 = DecryptName2(szFileName); + DWORD dwBlockIndex = 0xFFFFFFFF; + + // Save the starting hash position + pHash = pHash0 = ha->pHashTable + dwIndex; + + // Look for the first free hash entry. Can be also a deleted entry + while(pHash->dwBlockIndex < HASH_ENTRY_DELETED) + { + if(++pHash >= pHashEnd) + pHash = ha->pHashTable; + if(pHash == pHash0) + return NULL; + } + + // Fill the hash entry with the informations about the file name + pHash->dwName1 = dwName1; + pHash->dwName2 = dwName2; + pHash->lcLocale = (USHORT)lcLocale; + pHash->wPlatform = wPlatform; + + // Now we have to find a free block entry + for(dwIndex = 0; dwIndex < ha->pHeader->dwBlockTableSize; dwIndex++) + { + TMPQBlock * pBlock = ha->pBlockTable + dwIndex; + + if((pBlock->dwFlags & MPQ_FILE_EXISTS) == 0) + { + dwBlockIndex = dwIndex; + break; + } + } + + // If no free block entry found, we have to use the index + // at the end of the current block table + if(dwBlockIndex == 0xFFFFFFFF) + dwBlockIndex = ha->pHeader->dwBlockTableSize; + pHash->dwBlockIndex = dwBlockIndex; + return pHash; +} + +//----------------------------------------------------------------------------- +// Checking for valid archive handle and valid file handle + +BOOL IsValidMpqHandle(TMPQArchive * ha) +{ + if(ha == NULL || IsBadReadPtr(ha, sizeof(TMPQArchive))) + return FALSE; + if(ha->pHeader == NULL || IsBadReadPtr(ha->pHeader, sizeof(TMPQHeader))) + return FALSE; + + return (ha->pHeader->dwID == ID_MPQ); +} + +BOOL IsValidFileHandle(TMPQFile * hf) +{ + if(hf == NULL || IsBadReadPtr(hf, sizeof(TMPQFile))) + return FALSE; + + if(hf->hFile != INVALID_HANDLE_VALUE) + return TRUE; + + return IsValidMpqHandle(hf->ha); +} + +// This function writes a local file into the MPQ archive. +// Returns 0 if OK, otherwise error code. +// TODO: Test for archives > 4GB +int AddFileToArchive( + TMPQArchive * ha, + HANDLE hFile, + const char * szArchivedName, + DWORD dwFlags, + DWORD dwQuality, + int nFileType, + BOOL * pbReplaced) +{ + LARGE_INTEGER RelativePos = {0}; + LARGE_INTEGER FilePos = {0}; + LARGE_INTEGER TempPos; + TMPQBlockEx * pBlockEx = NULL; // Entry in the extended block table + TMPQBlock * pBlock = NULL; // Entry in the block table + TMPQHash * pHash = NULL; // Entry in the hash table + DWORD * pdwBlockPos = NULL; // Block position table (compressed files only) + BYTE * pbFileData = NULL; // Uncompressed (source) data + BYTE * pbCompressed = NULL; // Compressed (target) data + BYTE * pbToWrite = NULL; // Data to write to the file + DWORD dwBlockPosLen = 0; // Length of the block table positions + DWORD dwTransferred = 0; // Number of bytes written into archive file + DWORD dwFileSize = 0; // Size of the file to add + DWORD dwSeed1 = 0; // Encryption seed + DWORD nBlocks = 0; // Number of file blocks + DWORD nBlock = 0; // Index of the currently written block + BOOL bReplaced = FALSE; // TRUE if replaced, FALSE if added + int nCmpFirst = nDataCmp; // Compression for the first data block + int nCmpNext = nDataCmp; // Compression for the next data blocks + int nCmp = nDataCmp; // Current compression + int nCmpLevel = -1; // Compression level + int nError = ERROR_SUCCESS; + + // Set the correct compression types + if(dwFlags & MPQ_FILE_COMPRESS_PKWARE) + nCmpFirst = nCmpNext = MPQ_COMPRESSION_PKWARE; + + if(dwFlags & MPQ_FILE_COMPRESS_MULTI) + { + if(nFileType == SFILE_TYPE_DATA) + nCmpFirst = nCmpNext = nDataCmp; + + if(nFileType == SFILE_TYPE_WAVE) + { + nCmpNext = uWaveCmpType[dwQuality]; + nCmpLevel = uWaveCmpLevel[dwQuality]; + } + } + + // Check if the file already exists in the archive + if(nError == ERROR_SUCCESS) + { + if((pHash = GetHashEntryEx(ha, szArchivedName, lcLocale)) != NULL) + { + if(pHash->lcLocale == lcLocale) + { + if((dwFlags & MPQ_FILE_REPLACEEXISTING) == 0) + { + nError = ERROR_ALREADY_EXISTS; + pHash = NULL; + } + else + bReplaced = TRUE; + } + else + pHash = NULL; + } + + if(nError == ERROR_SUCCESS && pHash == NULL) + { + pHash = FindFreeHashEntry(ha, szArchivedName); + if(pHash == NULL) + nError = ERROR_HANDLE_DISK_FULL; + } + } + + // Get the block table entry for the file + if(nError == ERROR_SUCCESS) + { + DWORD dwFileSizeHigh = 0; + + // Get the size of the added file + dwFileSize = GetFileSize(hFile, &dwFileSizeHigh); + if(dwFileSizeHigh != 0) + nError = ERROR_PARAMETER_QUOTA_EXCEEDED; + + // Fix the flags, if the file is too small + if(dwFileSize < 0x04) + dwFlags &= ~(MPQ_FILE_ENCRYPTED | MPQ_FILE_FIXSEED); + if(dwFileSize < 0x20) + dwFlags &= ~MPQ_FILE_COMPRESSED; + + if(pHash->dwBlockIndex == HASH_ENTRY_FREE) + pHash->dwBlockIndex = ha->pHeader->dwBlockTableSize; + + // The block table index cannot be larger than hash table size + if(pHash->dwBlockIndex >= ha->pHeader->dwHashTableSize) + nError = ERROR_HANDLE_DISK_FULL; + } + + // The file will be stored after the end of the last archived file + // (i.e. at old position of archived file + if(nError == ERROR_SUCCESS) + { + TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize; + const char * szTemp = strrchr(szArchivedName, '\\'); + + // Get the position of the first file + RelativePos.QuadPart = ha->pHeader->dwHeaderSize; + + // Find the position of the last file. It has to be after the last archived file + // (Do not use the dwArchiveSize here, because it may or may not + // include the hash table at the end of the file + pBlockEx = ha->pExtBlockTable; + for(pBlock = ha->pBlockTable; pBlock < pBlockEnd; pBlock++, pBlockEx++) + { + if(pBlock->dwFlags & MPQ_FILE_EXISTS) + { + TempPos.HighPart = pBlockEx->wFilePosHigh; + TempPos.LowPart = pBlock->dwFilePos; + TempPos.QuadPart += pBlock->dwCSize; + + if(TempPos.QuadPart > RelativePos.QuadPart) + RelativePos = TempPos; + } + } + + // When format V1, we cannot exceed 4 GB + if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) + { + TempPos.QuadPart = ha->MpqPos.QuadPart + RelativePos.QuadPart; + TempPos.QuadPart += ha->pHeader->dwHashTableSize * sizeof(TMPQHash); + TempPos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock); + TempPos.QuadPart += dwFileSize; + + if(TempPos.HighPart != 0) + nError = ERROR_DISK_FULL; + } + + // Get pointers to both block entries of the file + pBlockEx = ha->pExtBlockTable + pHash->dwBlockIndex; + pBlock = ha->pBlockTable + pHash->dwBlockIndex; + + // Save the file size info + pBlockEx->wFilePosHigh = (USHORT)RelativePos.HighPart; + pBlock->dwFilePos = RelativePos.LowPart; + pBlock->dwFSize = GetFileSize(hFile, NULL); + pBlock->dwFlags = dwFlags | MPQ_FILE_EXISTS; + + // Create seed1 for file encryption + if(szTemp != NULL) + szArchivedName = szTemp + 1; + + if(dwFlags & MPQ_FILE_ENCRYPTED) + { + dwSeed1 = DecryptFileSeed(szArchivedName); + + if(dwFlags & MPQ_FILE_FIXSEED) + dwSeed1 = (dwSeed1 + pBlock->dwFilePos) ^ pBlock->dwFSize; + } + } + + // Allocate buffer for the input data + if(nError == ERROR_SUCCESS) + { + nBlocks = (pBlock->dwFSize / ha->dwBlockSize) + 1; + if(pBlock->dwFSize % ha->dwBlockSize) + nBlocks++; + + pBlock->dwCSize = 0; + if((pbFileData = ALLOCMEM(BYTE, ha->dwBlockSize)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + pbToWrite = pbFileData; + } + + // Allocate buffers for the compressed data + if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_COMPRESSED)) + { + pdwBlockPos = ALLOCMEM(DWORD, nBlocks + 1); + pbCompressed = ALLOCMEM(BYTE, ha->dwBlockSize * 2); + if(pdwBlockPos == NULL || pbCompressed == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + pbToWrite = pbCompressed; + } + + // Set the file position to the point where the file will be stored + if(nError == ERROR_SUCCESS) + { + // Set the file pointer to file data position + FilePos.QuadPart = ha->MpqPos.QuadPart + RelativePos.QuadPart; + if(FilePos.QuadPart != ha->FilePointer.QuadPart) + { + SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN); + ha->FilePointer = FilePos; + } + } + + // Write block positions (if the file will be compressed) + if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_COMPRESSED)) + { + dwBlockPosLen = nBlocks * sizeof(DWORD); + if(dwFlags & MPQ_FILE_HAS_EXTRA) + dwBlockPosLen += sizeof(DWORD); + + memset(pdwBlockPos, 0, dwBlockPosLen); + pdwBlockPos[0] = dwBlockPosLen; + + // Write the block positions + BSWAP_ARRAY32_UNSIGNED((DWORD *)pdwBlockPos, nBlocks); + WriteFile(ha->hFile, pdwBlockPos, dwBlockPosLen, &dwTransferred, NULL); + BSWAP_ARRAY32_UNSIGNED((DWORD *)pdwBlockPos, nBlocks); + + if(dwTransferred == dwBlockPosLen) + pBlock->dwCSize += dwBlockPosLen; + else + nError = GetLastError(); + + // Update the current position in the file + ha->HashTablePos.QuadPart = FilePos.QuadPart + dwTransferred; + } + + // Write all file blocks + if(nError == ERROR_SUCCESS) + { + nCmp = nCmpFirst; + + SetFilePointer(hFile, 0, NULL, FILE_BEGIN); + for(nBlock = 0; nBlock < nBlocks-1; nBlock++) + { + DWORD dwInLength = ha->dwBlockSize; + DWORD dwOutLength = ha->dwBlockSize; + + // Load the block from the file + ReadFile(hFile, pbFileData, ha->dwBlockSize, &dwInLength, NULL); + if(dwInLength == 0) + break; + + // Compress the block, if necessary + dwOutLength = dwInLength; + if(pBlock->dwFlags & MPQ_FILE_COMPRESSED) + { + // Should be enough for compression + int nOutLength = ha->dwBlockSize * 2; + int nCmpType = 0; + + if(pBlock->dwFlags & MPQ_FILE_COMPRESS_PKWARE) + Compress_pklib((char *)pbCompressed, &nOutLength, (char *)pbFileData, dwInLength, &nCmpType, 0); + + if(pBlock->dwFlags & MPQ_FILE_COMPRESS_MULTI) + SCompCompress((char *)pbCompressed, &nOutLength, (char *)pbFileData, dwInLength, nCmp, 0, nCmpLevel); + + // The compressed block size must NOT be the same or greater like + // the original block size. If yes, do not compress the block + // and store the data as-is. + if(nOutLength >= (int)dwInLength) + { + memcpy(pbCompressed, pbFileData, dwInLength); + nOutLength = dwInLength; + } + + // Update block positions + dwOutLength = nOutLength; + pdwBlockPos[nBlock+1] = pdwBlockPos[nBlock] + dwOutLength; + nCmp = nCmpNext; + } + + // Encrypt the block, if necessary + if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED) + { + BSWAP_ARRAY32_UNSIGNED((DWORD *)pbToWrite, dwOutLength / sizeof(DWORD)); + EncryptMPQBlock((DWORD *)pbToWrite, dwOutLength, dwSeed1 + nBlock); + BSWAP_ARRAY32_UNSIGNED((DWORD *)pbToWrite, dwOutLength / sizeof(DWORD)); + } + + // Write the block + WriteFile(ha->hFile, pbToWrite, dwOutLength, &dwTransferred, NULL); + if(dwTransferred != dwOutLength) + { + nError = ERROR_DISK_FULL; + break; + } + + // Update the hash table position and the compressed file size + ha->HashTablePos.QuadPart += dwTransferred; + pBlock->dwCSize += dwOutLength; + } + } + + // Now save the block positions + if(nError == ERROR_SUCCESS && (pBlock->dwFlags & MPQ_FILE_COMPRESSED)) + { + if(dwFlags & MPQ_FILE_HAS_EXTRA) + pdwBlockPos[nBlocks] = pdwBlockPos[nBlocks-1]; + + // If file is encrypted, block positions are also encrypted + if(dwFlags & MPQ_FILE_ENCRYPTED) + EncryptMPQBlock(pdwBlockPos, dwBlockPosLen, dwSeed1 - 1); + + // Set the position back to the block table + SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN); + + // Write block positions to the archive + BSWAP_ARRAY32_UNSIGNED((DWORD *)pdwBlockPos, nBlocks); + WriteFile(ha->hFile, pdwBlockPos, dwBlockPosLen, &dwTransferred, NULL); + if(dwTransferred != dwBlockPosLen) + nError = ERROR_DISK_FULL; + + ha->FilePointer.QuadPart = ha->FilePointer.QuadPart + dwTransferred; + } + + // If success, we have to change the settings + // in MPQ header. If failed, we have to clean hash entry + if(nError == ERROR_SUCCESS) + { + ha->pLastFile = NULL; + ha->dwBlockPos = 0; + ha->dwBuffPos = 0; + ha->dwFlags |= MPQ_FLAG_CHANGED; + + // Add new entry to the block table (if needed) + if(pHash->dwBlockIndex >= ha->pHeader->dwBlockTableSize) + ha->pHeader->dwBlockTableSize++; + + // Hash table size in the TMPQArchive is already set at this point + RelativePos.QuadPart = ha->HashTablePos.QuadPart - ha->MpqPos.QuadPart; + ha->pHeader->dwHashTablePos = RelativePos.LowPart; + ha->pHeader->wHashTablePosHigh = (USHORT)RelativePos.HighPart; + + // Update block table pos + RelativePos.QuadPart += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); + ha->pHeader->wBlockTablePosHigh = (USHORT)RelativePos.HighPart; + ha->pHeader->dwBlockTablePos = RelativePos.LowPart; + ha->BlockTablePos.QuadPart = RelativePos.QuadPart + ha->MpqPos.QuadPart; + + // If the archive size exceeded 4GB, we have to use extended block table pos + RelativePos.QuadPart += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock)); + if(RelativePos.HighPart != 0) + { + ha->pHeader->ExtBlockTablePos = RelativePos; + ha->ExtBlockTablePos.QuadPart = RelativePos.QuadPart + ha->MpqPos.QuadPart; + + RelativePos.QuadPart += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx)); + } + + // Update archive size (only valid for version V1) + ha->MpqSize = RelativePos; + ha->pHeader->dwArchiveSize = ha->MpqSize.LowPart; + } + else + { + // Clear the hash table entry + if(pHash != NULL) + memset(pHash, 0xFF, sizeof(TMPQHash)); + } + + // Cleanup + if(pbCompressed != NULL) + FREEMEM(pbCompressed); + if(pdwBlockPos != NULL) + FREEMEM(pdwBlockPos); + if(pbFileData != NULL) + FREEMEM(pbFileData); + if(pbReplaced != NULL) + *pbReplaced = bReplaced; + return nError; +} + +int SetDataCompression(int nDataCompression) +{ + nDataCmp = nDataCompression; + return 0; +} + +// This method saves MPQ header, hash table and block table. +// TODO: Test for archives > 4GB +int SaveMPQTables(TMPQArchive * ha) +{ + BYTE * pbBuffer = NULL; + DWORD dwBytes; + DWORD dwWritten; + DWORD dwBuffSize = max(ha->pHeader->dwHashTableSize, ha->pHeader->dwBlockTableSize); + int nError = ERROR_SUCCESS; + + // Allocate buffer for encrypted tables + if(nError == ERROR_SUCCESS) + { + // Allocate temporary buffer for tables encryption + pbBuffer = ALLOCMEM(BYTE, sizeof(TMPQHash) * dwBuffSize); + if(pbBuffer == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Write the MPQ Header + if(nError == ERROR_SUCCESS) + { + DWORD dwHeaderSize = ha->pHeader->dwHeaderSize; + + // Write the MPQ header + SetFilePointer(ha->hFile, ha->MpqPos.LowPart, &ha->MpqPos.HighPart, FILE_BEGIN); + + // Convert to little endian for file save + BSWAP_TMPQHEADER(ha->pHeader); + WriteFile(ha->hFile, ha->pHeader, dwHeaderSize, &dwWritten, NULL); + BSWAP_TMPQHEADER(ha->pHeader); + + if(dwWritten != ha->pHeader->dwHeaderSize) + nError = ERROR_DISK_FULL; + } + + // Write the hash table + if(nError == ERROR_SUCCESS) + { + // Copy the hash table to temporary buffer + dwBytes = ha->pHeader->dwHashTableSize * sizeof(TMPQHash); + memcpy(pbBuffer, ha->pHashTable, dwBytes); + + // Convert to little endian for file save + EncryptHashTable((DWORD *)pbBuffer, (BYTE *)"(hash table)", dwBytes >> 2); + BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBuffer, dwBytes / sizeof(DWORD)); + + // Set the file pointer to the offset of the hash table and write it + SetFilePointer(ha->hFile, ha->HashTablePos.LowPart, (PLONG)&ha->HashTablePos.HighPart, FILE_BEGIN); + WriteFile(ha->hFile, pbBuffer, dwBytes, &dwWritten, NULL); + if(dwWritten != dwBytes) + nError = ERROR_DISK_FULL; + } + + // Write the block table + if(nError == ERROR_SUCCESS) + { + // Copy the block table to temporary buffer + dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock); + memcpy(pbBuffer, ha->pBlockTable, dwBytes); + + // Encrypt the block table and write it to the file + EncryptBlockTable((DWORD *)pbBuffer, (BYTE *)"(block table)", dwBytes >> 2); + + // Convert to little endian for file save + BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBuffer, dwBytes / sizeof(DWORD)); + WriteFile(ha->hFile, pbBuffer, dwBytes, &dwWritten, NULL); + if(dwWritten != dwBytes) + nError = ERROR_DISK_FULL; + } + + // Write the extended block table + if(nError == ERROR_SUCCESS && ha->pHeader->ExtBlockTablePos.QuadPart != 0) + { + // We expect format V2 or newer in this case + assert(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2); + + // Copy the block table to temporary buffer + dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx); + memcpy(pbBuffer, ha->pExtBlockTable, dwBytes); + + // Convert to little endian for file save + BSWAP_ARRAY16_UNSIGNED((USHORT *)pbBuffer, dwBytes / sizeof(USHORT)); + WriteFile(ha->hFile, pbBuffer, dwBytes, &dwWritten, NULL); + if(dwWritten != dwBytes) + nError = ERROR_DISK_FULL; + } + + + // Set end of file here + if(nError == ERROR_SUCCESS) + { + SetEndOfFile(ha->hFile); + } + + // Cleanup and exit + if(pbBuffer != NULL) + FREEMEM(pbBuffer); + return nError; +} + +// Frees the MPQ archive +// TODO: Test for archives > 4GB +void FreeMPQArchive(TMPQArchive *& ha) +{ + if(ha != NULL) + { + FREEMEM(ha->pbBlockBuffer); + FREEMEM(ha->pBlockTable); + FREEMEM(ha->pExtBlockTable); + FREEMEM(ha->pHashTable); + if(ha->pListFile != NULL) + SListFileFreeListFile(ha); + + if(ha->hFile != INVALID_HANDLE_VALUE) + CloseHandle(ha->hFile); + FREEMEM(ha); + ha = NULL; + } +} diff --git a/contrib/vmap_extractor_v2/stormlib/SCommon.h b/contrib/vmap_extractor_v2/stormlib/SCommon.h new file mode 100644 index 000000000..b53be0ae2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SCommon.h @@ -0,0 +1,88 @@ +/*****************************************************************************/ +/* SCommon.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Common functions for encryption/decryption from Storm.dll. Included by */ +/* SFile*** functions, do not include and do not use this file directly */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 24.03.03 1.00 Lad The first version of SFileCommon.h */ +/* 12.06.04 1.00 Lad Renamed to SCommon.h */ +/*****************************************************************************/ + +#ifndef __SCOMMON_H__ +#define __SCOMMON_H__ + +//----------------------------------------------------------------------------- +// StormLib private defines + +#define SFILE_TYPE_DATA 0 // Process the file as data file +#define SFILE_TYPE_WAVE 1 // Process the file as WAVe file + +//----------------------------------------------------------------------------- +// External variables + +extern TMPQArchive * pFirstOpen; +extern LCID lcLocale; + +//----------------------------------------------------------------------------- +// Encryption and decryption functions + +int PrepareStormBuffer(); + +void EncryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength); +void DecryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength); +TMPQHash * FindFreeHashEntry(TMPQArchive * ha, const char * szFileName); + +void EncryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength); +void DecryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength); + +DWORD DetectFileSeed(DWORD * block, DWORD decrypted); +DWORD DetectFileSeed2(DWORD * block, UINT nDwords, ...); +void EncryptMPQBlock(DWORD * pdwBlock, DWORD dwLength, DWORD dwSeed1); +void DecryptMPQBlock(DWORD * pdwBlock, DWORD dwLength, DWORD dwSeed1); + +DWORD DecryptHashIndex(TMPQArchive * ha, const char * szFileName); +DWORD DecryptName1 (const char * szFileName); +DWORD DecryptName2 (const char * szFileName); +DWORD DecryptFileSeed (const char * szFileName); + +TMPQHash * GetHashEntry (TMPQArchive * ha, const char * szFileName); +TMPQHash * GetHashEntryEx(TMPQArchive * ha, const char * szFileName, LCID lcLocale); + +//----------------------------------------------------------------------------- +// Compression and decompression functions + +int Compress_pklib (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel); +int Decompress_pklib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength); + +//----------------------------------------------------------------------------- +// Checking functions + +BOOL IsValidMpqHandle(TMPQArchive * ha); +BOOL IsValidFileHandle(TMPQFile * hf); + +//----------------------------------------------------------------------------- +// Other functions + +BOOL SFileOpenArchiveEx(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMPQ, DWORD dwAccessMode = GENERIC_READ); +int AddFileToArchive(TMPQArchive * ha, HANDLE hFile, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality, int nFileType, BOOL * pbReplaced); +int SetDataCompression(int nDataCompression); +int SaveMPQTables(TMPQArchive * ha); +void FreeMPQArchive(TMPQArchive *& ha); + +BOOL CheckWildCard(const char * szString, const char * szWildCard); + +//----------------------------------------------------------------------------- +// Listfile functions + +int SListFileCreateListFile(TMPQArchive * ha); +int SListFileAddNode(TMPQArchive * ha, const char * szAddedFile); +int SListFileRemoveNode(TMPQArchive * ha, const char * szFileName); +int SListFileRenameNode(TMPQArchive * ha, const char * szOldFileName, const char * szNewFileName); +int SListFileFreeListFile(TMPQArchive * ha); + +int SListFileSaveToMpq(TMPQArchive * ha); + +#endif // __SCOMMON_H__ + diff --git a/contrib/vmap_extractor_v2/stormlib/SCompression.cpp b/contrib/vmap_extractor_v2/stormlib/SCompression.cpp new file mode 100644 index 000000000..612ef2cc2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SCompression.cpp @@ -0,0 +1,715 @@ +/*****************************************************************************/ +/* SCompression.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This module serves as a bridge between StormLib code and (de)compression */ +/* functions. All (de)compression calls go (and should only go) through this */ +/* module. No system headers should be included in this module to prevent */ +/* compile-time problems. */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 01.04.03 1.00 Lad The first version of SCompression.cpp */ +/* 19.11.03 1.01 Dan Big endian handling */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +#include + +// Include functions from Pkware Data Compression Library +#include "pklib/pklib.h" + +// Include functions from zlib +#ifndef __SYS_ZLIB +#include "zlib/zlib.h" // Include functions from zlib +#else +#include // If zlib is available on system, use this instead +#endif + +// Include functions from Huffmann compression +#include "huffman/huff.h" + +// Include functions from WAVe compression +#include "wave/wave.h" + +// Include functions from BZip2 compression library +#ifndef __SYS_BZLIB +#include "bzip2/bzlib.h" // Include functions from bzlib +#else +#include // If bzlib is available on system, use this instead +#endif + +//----------------------------------------------------------------------------- +// Local structures + +// Information about the input and output buffers for pklib +typedef struct +{ + char * pInBuff; // Pointer to input data buffer + int nInPos; // Current offset in input data buffer + int nInBytes; // Number of bytes in the input buffer + char * pOutBuff; // Pointer to output data buffer + int nOutPos; // Position in the output buffer + int nMaxOut; // Maximum number of bytes in the output buffer +} TDataInfo; + +// Table of compression functions +typedef int (*COMPRESS)(char *, int *, char *, int, int *, int); +typedef struct +{ + unsigned long dwMask; // Compression mask + COMPRESS Compress; // Compression function +} TCompressTable; + +// Table of decompression functions +typedef int (*DECOMPRESS)(char *, int *, char *, int); +typedef struct +{ + unsigned long dwMask; // Decompression bit + DECOMPRESS Decompress; // Decompression function +} TDecompressTable; + + +/*****************************************************************************/ +/* */ +/* Support functions for Pkware Data Compression Library */ +/* */ +/*****************************************************************************/ + +// Function loads data from the input buffer. Used by Pklib's "implode" +// and "explode" function as user-defined callback +// Returns number of bytes loaded +// +// char * buf - Pointer to a buffer where to store loaded data +// unsigned int * size - Max. number of bytes to read +// void * param - Custom pointer, parameter of implode/explode + +static unsigned int ReadInputData(char * buf, unsigned int * size, void * param) +{ + TDataInfo * pInfo = (TDataInfo *)param; + unsigned int nMaxAvail = (pInfo->nInBytes - pInfo->nInPos); + unsigned int nToRead = *size; + + // Check the case when not enough data available + if(nToRead > nMaxAvail) + nToRead = nMaxAvail; + + // Load data and increment offsets + memcpy(buf, pInfo->pInBuff + pInfo->nInPos, nToRead); + pInfo->nInPos += nToRead; + + return nToRead; +} + +// Function for store output data. Used by Pklib's "implode" and "explode" +// as user-defined callback +// +// char * buf - Pointer to data to be written +// unsigned int * size - Number of bytes to write +// void * param - Custom pointer, parameter of implode/explode + +static void WriteOutputData(char * buf, unsigned int * size, void * param) +{ + TDataInfo * pInfo = (TDataInfo *)param; + unsigned int nMaxWrite = (pInfo->nMaxOut - pInfo->nOutPos); + unsigned int nToWrite = *size; + + // Check the case when not enough space in the output buffer + if(nToWrite > nMaxWrite) + nToWrite = nMaxWrite; + + // Write output data and increments offsets + memcpy(pInfo->pOutBuff + pInfo->nOutPos, buf, nToWrite); + pInfo->nOutPos += nToWrite; +} + +/*****************************************************************************/ +/* */ +/* "80" is IMA ADPCM stereo (de)compression */ +/* "40" is IMA ADPCM mono (de)compression */ +/* */ +/*****************************************************************************/ + +int Compress_wave_mono(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel) +{ + // Prepare the compression level for the next compression + // (After us, the Huffmann compression will be called) + if(0 < nCmpLevel && nCmpLevel <= 2) + { + nCmpLevel = 4; + *pCmpType = 6; + } + else if(nCmpLevel == 3) + { + nCmpLevel = 6; + *pCmpType = 8; + } + else + { + nCmpLevel = 5; + *pCmpType = 7; + } + *pdwOutLength = CompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (short *)pbInBuffer, dwInLength, 1, nCmpLevel); + return 0; +} + +int Decompress_wave_mono(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + *pdwOutLength = DecompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (unsigned char *)pbInBuffer, dwInLength, 1); + return 1; +} + +int Compress_wave_stereo(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel) +{ + // Prepare the compression type for the next compression + // (After us, the Huffmann compression will be called) + if(0 < nCmpLevel && nCmpLevel <= 2) + { + nCmpLevel = 4; + *pCmpType = 6; + } + else if(nCmpLevel == 3) + { + nCmpLevel = 6; + *pCmpType = 8; + } + else + { + nCmpLevel = 5; + *pCmpType = 7; + } + *pdwOutLength = CompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (short *)pbInBuffer, dwInLength, 2, nCmpLevel); + return 0; +} + +int Decompress_wave_stereo(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + *pdwOutLength = DecompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (unsigned char *)pbInBuffer, dwInLength, 2); + return 1; +} + +/*****************************************************************************/ +/* */ +/* The "01" (de)compression is the Huffman (de)compression */ +/* */ +/*****************************************************************************/ + +// 1500F4C0 +int Compress_huff(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int /* nCmpLevel */) +{ + THuffmannTree ht; // Huffmann tree for compression + TOutputStream os; // Output stream + + // Initialize output stream + os.pbOutBuffer = (unsigned char *)pbOutBuffer; + os.dwOutSize = *pdwOutLength; + os.pbOutPos = (unsigned char *)pbOutBuffer; + os.dwBitBuff = 0; + os.nBits = 0; + + // Initialize the Huffmann tree for compression + ht.InitTree(true); + + *pdwOutLength = ht.DoCompression(&os, (unsigned char *)pbInBuffer, dwInLength, *pCmpType); + + // The following code is not necessary to run, because it has no + // effect on the output data. It only clears the huffmann tree, but when + // the tree is on the stack, who cares ? +// ht.UninitTree(); + return 0; +} + +// 1500F5F0 +int Decompress_huff(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int /* dwInLength */) +{ + THuffmannTree ht; + TInputStream is; + + // Initialize input stream +// is.pbInBuffer = (unsigned char *)pbInBuffer; + is.dwBitBuff = BSWAP_INT32_UNSIGNED(*(unsigned long *)pbInBuffer); + pbInBuffer += sizeof(unsigned long); + is.pbInBuffer = (unsigned char *)pbInBuffer; + is.nBits = 32; + + // Initialize the Huffmann tree for compression + ht.InitTree(false); + *pdwOutLength = ht.DoDecompression((unsigned char *)pbOutBuffer, *pdwOutLength, &is); + + // The following code is not necessary to run, because it has no + // effect on the output data. It only clears the huffmann tree, but when + // the tree is on the stack, who cares ? +// ht.UninitTree(); + return 0; +} + +/*****************************************************************************/ +/* */ +/* The "02" (de)compression is the ZLIB (de)compression */ +/* */ +/*****************************************************************************/ + +int Compress_zlib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * /* pCmpType */, int /* nCmpLevel */) +{ + z_stream z; // Stream information for zlib + int nResult; + + // Fill the stream structure for zlib + z.next_in = (Bytef *)pbInBuffer; + z.avail_in = (uInt)dwInLength; + z.total_in = dwInLength; + z.next_out = (Bytef *)pbOutBuffer; + z.avail_out = *pdwOutLength; + z.total_out = 0; + z.zalloc = NULL; + z.zfree = NULL; + + // Initialize the compression structure. Storm.dll uses zlib version 1.1.3 + *pdwOutLength = 0; + if((nResult = deflateInit(&z, Z_DEFAULT_COMPRESSION)) == 0) + { + // Call zlib to compress the data + nResult = deflate(&z, Z_FINISH); + + if(nResult == Z_OK || nResult == Z_STREAM_END) + *pdwOutLength = z.total_out; + + deflateEnd(&z); + } + return nResult; +} + +int Decompress_zlib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + z_stream z; // Stream information for zlib + int nResult; + + // Fill the stream structure for zlib + z.next_in = (Bytef *)pbInBuffer; + z.avail_in = (uInt)dwInLength; + z.total_in = dwInLength; + z.next_out = (Bytef *)pbOutBuffer; + z.avail_out = *pdwOutLength; + z.total_out = 0; + z.zalloc = NULL; + z.zfree = NULL; + + // Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 + if((nResult = inflateInit(&z)) == 0) + { + // Call zlib to decompress the data + nResult = inflate(&z, Z_FINISH); + *pdwOutLength = z.total_out; + inflateEnd(&z); + } + return nResult; +} + +/*****************************************************************************/ +/* */ +/* The "08" (de)compression is the Pkware DCL (de)compression */ +/* */ +/*****************************************************************************/ + +int Compress_pklib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int /* nCmpLevel */) +{ + TDataInfo Info; // Data information + char * work_buf = ALLOCMEM(char, CMP_BUFFER_SIZE);// Pklib's work buffer + unsigned int dict_size; // Dictionary size + unsigned int ctype; // Compression type + + // Fill data information structure + Info.pInBuff = pbInBuffer; + Info.nInPos = 0; + Info.nInBytes = dwInLength; + Info.pOutBuff = pbOutBuffer; + Info.nOutPos = 0; + Info.nMaxOut = *pdwOutLength; + + // Set the compression type and dictionary size + ctype = (*pCmpType == 2) ? CMP_ASCII : CMP_BINARY; + if (dwInLength < 0x600) + dict_size = 0x400; + else if(0x600 <= dwInLength && dwInLength < 0xC00) + dict_size = 0x800; + else + dict_size = 0x1000; + + // Do the compression + implode(ReadInputData, WriteOutputData, work_buf, &Info, &ctype, &dict_size); + *pdwOutLength = Info.nOutPos; + FREEMEM(work_buf); + return 0; +} + +int Decompress_pklib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + TDataInfo Info; // Data information + char * work_buf = ALLOCMEM(char, EXP_BUFFER_SIZE);// Pklib's work buffer + + // Fill data information structure + Info.pInBuff = pbInBuffer; + Info.nInPos = 0; + Info.nInBytes = dwInLength; + Info.pOutBuff = pbOutBuffer; + Info.nOutPos = 0; + Info.nMaxOut = *pdwOutLength; + + // Do the decompression + explode(ReadInputData, WriteOutputData, work_buf, &Info); + + // Fix: If PKLIB is unable to decompress the data, they are uncompressed + if(Info.nOutPos == 0) + { + Info.nOutPos = min(*pdwOutLength, dwInLength); + memcpy(pbOutBuffer, pbInBuffer, Info.nOutPos); + } + + *pdwOutLength = Info.nOutPos; + FREEMEM(work_buf); + return 0; +} + +/*****************************************************************************/ +/* */ +/* The "10" (de)compression is the Bzip2 (de)compression */ +/* */ +/*****************************************************************************/ + +int Compress_bzip2(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel) +{ + bz_stream strm; + int blockSize100k; + int workFactor = 30; + + // Keep compiler happy + nCmpLevel = nCmpLevel; + + // Initialize the BZLIB compression + strm.bzalloc = NULL; + strm.bzfree = NULL; + + // Adjust the block size + blockSize100k = *pCmpType; + if(blockSize100k < 1 || blockSize100k > 9) + blockSize100k = 9; + + // Blizzard uses 9 as blockSize100k, (0 as workFactor) + if(BZ2_bzCompressInit(&strm, blockSize100k, 0, workFactor) == 0) + { + strm.next_in = pbInBuffer; + strm.avail_in = dwInLength; + strm.next_out = pbOutBuffer; + strm.avail_out = *pdwOutLength; + + // Perform the compression + while(BZ2_bzCompress(&strm, (strm.avail_in != 0) ? BZ_RUN : BZ_FINISH) != BZ_STREAM_END); + + // Put the stream into idle state + BZ2_bzCompressEnd(&strm); + *pdwOutLength = strm.total_out_lo32; + } + else + { + *pdwOutLength = 0; + } + + return 0; +} + +int Decompress_bzip2(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + bz_stream strm; + + // Initialize the BZLIB decompression + strm.bzalloc = NULL; + strm.bzfree = NULL; + if(BZ2_bzDecompressInit(&strm, 0, 0) == 0) + { + strm.next_in = pbInBuffer; + strm.avail_in = dwInLength; + strm.next_out = pbOutBuffer; + strm.avail_out = *pdwOutLength; + + // Perform the decompression + while(BZ2_bzDecompress(&strm) != BZ_STREAM_END); + + // Put the stream into idle state + BZ2_bzDecompressEnd(&strm); + *pdwOutLength = strm.total_out_lo32; + } + else + { + // Set zero output length + *pdwOutLength = 0; + } + + return 0; +} + +/*****************************************************************************/ +/* */ +/* SCompCompress */ +/* */ +/*****************************************************************************/ + +// This table contains compress functions which can be applied to +// uncompressed blocks. Each bit set means the corresponding +// compression method/function must be applied. +// +// WAVes compression Data compression +// ------------------ ------------------- +// 1st block - 0x08 0x08 (D, HF, W2, SC, D2) +// Rest blocks - 0x81 0x02 (W3) + +static TCompressTable cmp_table[] = +{ + {MPQ_COMPRESSION_WAVE_MONO, Compress_wave_mono}, // IMA ADPCM mono compression + {MPQ_COMPRESSION_WAVE_STEREO, Compress_wave_stereo}, // IMA ADPCM stereo compression + {MPQ_COMPRESSION_HUFFMANN, Compress_huff}, // Huffmann compression + {MPQ_COMPRESSION_ZLIB, Compress_zlib}, // Compression with the "zlib" library + {MPQ_COMPRESSION_PKWARE, Compress_pklib}, // Compression with Pkware DCL + {MPQ_COMPRESSION_BZIP2, Compress_bzip2} // Compression Bzip2 library +}; + +int WINAPI SCompCompress(char * pbCompressed, int * pdwOutLength, char * pbUncompressed, int dwInLength, + int uCompressions, int nCmpType, int nCmpLevel) +{ + char * pbTempBuff = NULL; // Temporary storage for decompressed data + char * pbOutput = pbCompressed; // Current output buffer + char * pbInput; // Current input buffer + int uCompressions2; + int dwCompressCount = 0; + int dwDoneCount = 0; + int dwOutSize = 0; + int dwInSize = dwInLength; + int dwEntries = (sizeof(cmp_table) / sizeof(TCompressTable)); + int nResult = 1; + int i; + + // Check for valid parameters + if(!pdwOutLength || *pdwOutLength < dwInLength || !pbCompressed || !pbUncompressed) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // Count the compressions + for(i = 0, uCompressions2 = uCompressions; i < dwEntries; i++) + { + if(uCompressions & cmp_table[i].dwMask) + dwCompressCount++; + + uCompressions2 &= ~cmp_table[i].dwMask; + } + + // If a compression remains, do nothing + if(uCompressions2 != 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // If more that one compression, allocate intermediate buffer + if(dwCompressCount >= 2) + pbTempBuff = ALLOCMEM(char, *pdwOutLength + 1); + + // Perform the compressions + pbInput = pbUncompressed; + dwInSize = dwInLength; + for(i = 0, uCompressions2 = uCompressions; i < dwEntries; i++) + { + if(uCompressions2 & cmp_table[i].dwMask) + { + // Set the right output buffer + dwCompressCount--; + pbOutput = (dwCompressCount & 1) ? pbTempBuff : pbCompressed; + + // Perform the partial compression + dwOutSize = *pdwOutLength - 1; + + cmp_table[i].Compress(pbOutput + 1, &dwOutSize, pbInput, dwInSize, &nCmpType, nCmpLevel); + if(dwOutSize == 0) + { + SetLastError(ERROR_GEN_FAILURE); + *pdwOutLength = 0; + nResult = 0; + break; + } + + // If the compression failed, copy the block instead + if(dwOutSize >= dwInSize - 1) + { + if(dwDoneCount > 0) + pbOutput++; + + memcpy(pbOutput, pbInput, dwInSize); + pbInput = pbOutput; + uCompressions &= ~cmp_table[i].dwMask; + dwOutSize = dwInSize; + } + else + { + pbInput = pbOutput + 1; + dwInSize = dwOutSize; + dwDoneCount++; + } + } + } + + // Copy the compressed data to the correct output buffer + if(nResult != 0) + { + if(uCompressions && (dwInSize + 1) < *pdwOutLength) + { + if(pbOutput != pbCompressed && pbOutput != pbCompressed + 1) + memcpy(pbCompressed, pbOutput, dwInSize); + *pbCompressed = (char)uCompressions; + *pdwOutLength = dwInSize + 1; + } + else + { + memmove(pbCompressed, pbUncompressed, dwInSize); + *pdwOutLength = dwInSize; + } + } + + // Cleanup and return + if(pbTempBuff != NULL) + FREEMEM(pbTempBuff); + return nResult; +} + +/*****************************************************************************/ +/* */ +/* SCompDecompress */ +/* */ +/*****************************************************************************/ + +// This table contains decompress functions which can be applied to +// uncompressed blocks. The compression mask is stored in the first byte +// of compressed block +static TDecompressTable dcmp_table[] = +{ + {MPQ_COMPRESSION_BZIP2, Decompress_bzip2}, // Decompression with Bzip2 library + {MPQ_COMPRESSION_PKWARE, Decompress_pklib}, // Decompression with Pkware Data Compression Library + {MPQ_COMPRESSION_ZLIB, Decompress_zlib}, // Decompression with the "zlib" library + {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression + {MPQ_COMPRESSION_WAVE_STEREO, Decompress_wave_stereo}, // IMA ADPCM stereo decompression + {MPQ_COMPRESSION_WAVE_MONO, Decompress_wave_mono} // IMA ADPCM mono decompression +}; + +int WINAPI SCompDecompress(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + char * pbTempBuff = NULL; // Temporary storage for decompressed data + char * pbWorkBuff = NULL; // Where to store decompressed data + int dwOutLength = *pdwOutLength; // For storage number of output bytes + unsigned fDecompressions1; // Decompressions applied to the block + unsigned fDecompressions2; // Just another copy of decompressions applied to the block + int dwCount = 0; // Counter for every use + int dwEntries = (sizeof(dcmp_table) / sizeof(TDecompressTable)); + int nResult = 1; + int i; + + // If the input length is the same as output, do nothing. + if(dwInLength == dwOutLength) + { + if(pbInBuffer == pbOutBuffer) + return 1; + + memcpy(pbOutBuffer, pbInBuffer, dwInLength); + *pdwOutLength = dwInLength; + return 1; + } + + // Get applied compression types and decrement data length + fDecompressions1 = fDecompressions2 = (unsigned char)*pbInBuffer++; + dwInLength--; + + // Search decompression table type and get all types of compression + for(i = 0; i < dwEntries; i++) + { + // We have to apply this decompression ? + if(fDecompressions1 & dcmp_table[i].dwMask) + dwCount++; + + // Clear this flag from temporary variable. + fDecompressions2 &= ~dcmp_table[i].dwMask; + } + + // Check if there is some method unhandled + // (E.g. compressed by future versions) + if(fDecompressions2 != 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // If there is more than only one compression, we have to allocate extra buffer + if(dwCount >= 2) + pbTempBuff = ALLOCMEM(char, dwOutLength); + + // Apply all decompressions + for(i = 0, dwCount = 0; i < dwEntries; i++) + { + // If not used this kind of compression, skip the loop + if(fDecompressions1 & dcmp_table[i].dwMask) + { + // If odd case, use target buffer for output, otherwise use allocated tempbuffer + pbWorkBuff = (dwCount++ & 1) ? pbTempBuff : pbOutBuffer; + dwOutLength = *pdwOutLength; + + // Decompress buffer using corresponding function + dcmp_table[i].Decompress(pbWorkBuff, &dwOutLength, pbInBuffer, dwInLength); + if(dwOutLength == 0) + { + SetLastError(ERROR_GEN_FAILURE); + nResult = 0; + break; + } + + // Move output length to src length for next compression + dwInLength = dwOutLength; + pbInBuffer = pbWorkBuff; + } + } + + // If output buffer is not the same like target buffer, we have to copy data + if(nResult != 0) + { + if(pbWorkBuff != pbOutBuffer) + memcpy(pbOutBuffer, pbInBuffer, dwOutLength); + + } + + // Delete temporary buffer, if necessary + if(pbTempBuff != NULL) + FREEMEM(pbTempBuff); + + *pdwOutLength = dwOutLength; + return nResult; +} + +/*****************************************************************************/ +/* */ +/* SCompSetDataCompression */ +/* */ +/*****************************************************************************/ + +int WINAPI SCompSetDataCompression(int nDataCompression) +{ + int nValidMask = (MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_PKWARE | MPQ_COMPRESSION_BZIP2); + + if((nDataCompression & nValidMask) != nDataCompression) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + SetDataCompression(nDataCompression); + return TRUE; +} + + diff --git a/contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp b/contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp new file mode 100644 index 000000000..9510b15ae --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp @@ -0,0 +1,691 @@ +/*****************************************************************************/ +/* SFileCompactArchive.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Archive compacting function */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 14.04.03 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */ +/* 19.11.03 1.01 Dan Big endian handling */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +/*****************************************************************************/ +/* Local structures */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Local variables */ +/*****************************************************************************/ + +static COMPACTCB CompactCB = NULL; +static void * lpUserData = NULL; + +/*****************************************************************************/ +/* Local functions */ +/*****************************************************************************/ + +// Creates a copy of hash table +static TMPQHash * CopyHashTable(TMPQArchive * ha) +{ + TMPQHash * pHashTableCopy = ALLOCMEM(TMPQHash, ha->pHeader->dwHashTableSize); + + if(pHashTableCopy != NULL) + memcpy(pHashTableCopy, ha->pHashTable, sizeof(TMPQHash) * ha->pHeader->dwHashTableSize); + + return pHashTableCopy; +} + +// TODO: Test for archives > 4GB +static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileSeeds) +{ + TMPQHash * pHashTableCopy = NULL; // Copy of the hash table + TMPQHash * pHash; + TMPQHash * pHashEnd = NULL; // End of the hash table + DWORD dwFileCount = 0; + int nError = ERROR_SUCCESS; + + // First of all, create a copy of hash table + if(nError == ERROR_SUCCESS) + { + if((pHashTableCopy = CopyHashTable(ha)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize; + + // Notify the user + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_CHECKING_FILES, 0, ha->pHeader->dwBlockTableSize); + } + + // Now check all the files from the filelist + if(nError == ERROR_SUCCESS) + { + SFILE_FIND_DATA wf; + HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile); + BOOL bResult = TRUE; + + // Do while some files have been found + while(hFind != NULL && bResult) + { + TMPQHash * pHash = GetHashEntry(ha, wf.cFileName); + + // If the hash table entry has been found, find it's position + // in the hash table copy + if(pHash != NULL) + { + pHash = pHashTableCopy + (pHash - ha->pHashTable); + if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1) + { + TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex; + DWORD dwSeed = 0; + + // Resolve the file seed. Use plain file name for it + if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED) + { + char * szFileName = strrchr(wf.cFileName, '\\'); + + if(szFileName == NULL) + szFileName = wf.cFileName; + else + szFileName++; + + dwSeed = DecryptFileSeed(szFileName); + if(pBlock->dwFlags & MPQ_FILE_FIXSEED) + dwSeed = (dwSeed + pBlock->dwFilePos) ^ pBlock->dwFSize; + } + pFileSeeds[pHash->dwBlockIndex] = dwSeed; + + pHash->dwName1 = 0xFFFFFFFF; + pHash->dwName2 = 0xFFFFFFFF; + pHash->lcLocale = 0xFFFF; + pHash->wPlatform = 0xFFFF; + pHash->dwBlockIndex = 0xFFFFFFFF; + } + } + // Notify the user + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_CHECKING_FILES, ++dwFileCount, ha->pHeader->dwBlockTableSize); + + // Find the next file in the archive + bResult = SFileFindNextFile(hFind, &wf); + } + + if(hFind != NULL) + SFileFindClose(hFind); + } + + // When the filelist checking is complete, parse the hash table copy and find the + if(nError == ERROR_SUCCESS) + { + // Notify the user about checking hash table + dwFileCount = 0; + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, dwFileCount, ha->pHeader->dwBlockTableSize); + + for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++) + { + // If there is an unresolved entry, try to detect its seed. If it fails, + // we cannot complete the work + if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1) + { + HANDLE hFile = NULL; + DWORD dwFlags = 0; + DWORD dwSeed = 0; + + if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, 0, &hFile)) + { + TMPQFile * hf = (TMPQFile *)hFile; + dwFlags = hf->pBlock->dwFlags; + dwSeed = hf->dwSeed1; + SFileCloseFile(hFile); + } + + // If the file is encrypted, we have to check + // If we can apply the file decryption seed + if(dwFlags & MPQ_FILE_ENCRYPTED && dwSeed == 0) + { + nError = ERROR_CAN_NOT_COMPLETE; + break; + } + + // Remember the seed + pFileSeeds[pHash->dwBlockIndex] = dwSeed; + + // Notify the user + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, ++dwFileCount, ha->pHeader->dwBlockTableSize); + } + } + } + + // Delete the copy of hash table + if(pHashTableCopy != NULL) + FREEMEM(pHashTableCopy); + return nError; +} + +// Copies all file blocks into another archive. +// TODO: Test for archives > 4GB +static int CopyMpqFileBlocks( + HANDLE hFile, + TMPQArchive * ha, + TMPQBlockEx * pBlockEx, + TMPQBlock * pBlock, + DWORD dwSeed) +{ + LARGE_INTEGER FilePos = {0}; + DWORD * pdwBlockPos2 = NULL; // File block positions to be written to target file + DWORD * pdwBlockPos = NULL; // File block positions (unencrypted) + BYTE * pbBlock = NULL; // Buffer for the file block + DWORD dwTransferred; // Number of bytes transferred + DWORD dwCSize = 0; // Compressed file size + DWORD dwBytes = 0; // Number of bytes + DWORD dwSeed1 = 0; // File seed used for decryption + DWORD dwSeed2 = 0; // File seed used for encryption + DWORD nBlocks = 0; // Number of file blocks + DWORD nBlock = 0; // Currently processed file block + int nError = ERROR_SUCCESS; + + // When file length is zero, do nothing + if(pBlock->dwFSize == 0) + return ERROR_SUCCESS; + + // Calculate number of blocks in the file + if(nError == ERROR_SUCCESS) + { + nBlocks = pBlock->dwFSize / ha->dwBlockSize; + if(pBlock->dwFSize % ha->dwBlockSize) + nBlocks++; + pbBlock = ALLOCMEM(BYTE, ha->dwBlockSize); + if(pbBlock == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Set the position to the begin of the file within archive + if(nError == ERROR_SUCCESS) + { + FilePos.HighPart = pBlockEx->wFilePosHigh; + FilePos.LowPart = pBlock->dwFilePos; + FilePos.QuadPart += ha->MpqPos.QuadPart; + if(SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN) != FilePos.LowPart) + nError = GetLastError(); + } + + // Remember the position in the destination file + if(nError == ERROR_SUCCESS) + { + FilePos.HighPart = 0; + FilePos.LowPart = SetFilePointer(hFile, 0, &FilePos.HighPart, FILE_CURRENT); + } + + // Resolve decryption seeds. The 'dwSeed' parameter is the decryption + // seed for the file. + if(nError == ERROR_SUCCESS && (pBlock->dwFlags & MPQ_FILE_ENCRYPTED)) + { + dwSeed1 = dwSeed; + if(pBlock->dwFlags & MPQ_FILE_FIXSEED) + dwSeed = (dwSeed1 ^ pBlock->dwFSize) - pBlock->dwFilePos; + + dwSeed2 = dwSeed; + if(pBlock->dwFlags & MPQ_FILE_FIXSEED) + dwSeed2 = (dwSeed + (DWORD)(FilePos.QuadPart - ha->MpqPos.QuadPart)) ^ pBlock->dwFSize; + } + + // Load the file positions from the archive and save it to the target file + // (only if the file is compressed) + if(pBlock->dwFlags & MPQ_FILE_COMPRESSED) + { + // Allocate buffers + if(nError == ERROR_SUCCESS) + { + pdwBlockPos = ALLOCMEM(DWORD, nBlocks + 2); + pdwBlockPos2 = ALLOCMEM(DWORD, nBlocks + 2); + + if(pdwBlockPos == NULL || pdwBlockPos2 == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Load the block positions + if(nError == ERROR_SUCCESS) + { + dwBytes = (nBlocks + 1) * sizeof(DWORD); + if(pBlock->dwFlags & MPQ_FILE_HAS_EXTRA) + dwBytes += sizeof(DWORD); + + ReadFile(ha->hFile, pdwBlockPos, dwBytes, &dwTransferred, NULL); + if(dwTransferred != dwBytes) + nError = ERROR_FILE_CORRUPT; + } + + // Re-encrypt the block table positions + if(nError == ERROR_SUCCESS) + { + BSWAP_ARRAY32_UNSIGNED(pdwBlockPos, dwBytes / sizeof(DWORD)); + if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED) + { + DecryptMPQBlock(pdwBlockPos, dwBytes, dwSeed1 - 1); + if(pdwBlockPos[0] != dwBytes) + nError = ERROR_FILE_CORRUPT; + + memcpy(pdwBlockPos2, pdwBlockPos, dwBytes); + EncryptMPQBlock(pdwBlockPos2, dwBytes, dwSeed2 - 1); + } + else + { + memcpy(pdwBlockPos2, pdwBlockPos, dwBytes); + } + BSWAP_ARRAY32_UNSIGNED(pdwBlockPos2, dwBytes / sizeof(DWORD)); + } + + // Write to the target file + if(nError == ERROR_SUCCESS) + { + WriteFile(hFile, pdwBlockPos2, dwBytes, &dwTransferred, NULL); + dwCSize += dwTransferred; + if(dwTransferred != dwBytes) + nError = ERROR_DISK_FULL; + } + } + + // Now we have to copy all file block. We will do it without + // recompression, because re-compression is not necessary in this case + if(nError == ERROR_SUCCESS) + { + for(nBlock = 0; nBlock < nBlocks; nBlock++) + { + // Fix: The last block must not be exactly the size of one block. + dwBytes = ha->dwBlockSize; + if(nBlock == nBlocks - 1) + { + dwBytes = pBlock->dwFSize - (ha->dwBlockSize * (nBlocks - 1)); + } + + if(pBlock->dwFlags & MPQ_FILE_COMPRESSED) + dwBytes = pdwBlockPos[nBlock+1] - pdwBlockPos[nBlock]; + + // Read the file block + ReadFile(ha->hFile, pbBlock, dwBytes, &dwTransferred, NULL); + if(dwTransferred != dwBytes) + { + nError = ERROR_FILE_CORRUPT; + break; + } + + // If necessary, re-encrypt the block + // Note: Recompression is not necessary here. Unlike encryption, + // the compression does not depend on the position of the file in MPQ. + if((pBlock->dwFlags & MPQ_FILE_ENCRYPTED) && dwSeed1 != dwSeed2) + { + BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBlock, dwBytes/sizeof(DWORD)); + DecryptMPQBlock((DWORD *)pbBlock, dwBytes, dwSeed1 + nBlock); + EncryptMPQBlock((DWORD *)pbBlock, dwBytes, dwSeed2 + nBlock); + BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBlock, dwBytes/sizeof(DWORD)); + } + + // Now write the block back to the file + WriteFile(hFile, pbBlock, dwBytes, &dwTransferred, NULL); + dwCSize += dwTransferred; + if(dwTransferred != dwBytes) + { + nError = ERROR_DISK_FULL; + break; + } + } + } + + // Copy the file extras, if any + // These extras does not seem to be encrypted, and their purpose is unknown + if(nError == ERROR_SUCCESS && (pBlock->dwFlags & MPQ_FILE_HAS_EXTRA)) + { + dwBytes = pdwBlockPos[nBlocks + 1] - pdwBlockPos[nBlocks]; + if(dwBytes != 0) + { + ReadFile(ha->hFile, pbBlock, dwBytes, &dwTransferred, NULL); + if(dwTransferred == dwBytes) + { + WriteFile(hFile, pbBlock, dwBytes, &dwTransferred, NULL); + dwCSize += dwTransferred; + if(dwTransferred != dwBytes) + nError = ERROR_DISK_FULL; + } + else + { + nError = ERROR_FILE_CORRUPT; + } + } + } + + // Update file position in the block table + if(nError == ERROR_SUCCESS) + { + // At this point, number of bytes written should be exactly + // the same like the compressed file size. If it isn't, there's something wrong + // (maybe new archive version ?) + assert(dwCSize == pBlock->dwCSize); + + // Update file pos in the block table + FilePos.QuadPart -= ha->MpqPos.QuadPart; + pBlockEx->wFilePosHigh = (USHORT)FilePos.HighPart; + pBlock->dwFilePos = FilePos.LowPart; + } + + // Cleanup and return + if(pdwBlockPos2 != NULL) + FREEMEM(pdwBlockPos2); + if(pdwBlockPos != NULL) + FREEMEM(pdwBlockPos); + if(pbBlock != NULL) + FREEMEM(pbBlock); + return nError; +} + + +static int CopyNonMpqData( + HANDLE hSrcFile, + HANDLE hTrgFile, + LARGE_INTEGER & DataSizeToCopy) +{ + LARGE_INTEGER DataSize = DataSizeToCopy; + DWORD dwTransferred; + DWORD dwToRead; + char DataBuffer[0x1000]; + int nError = ERROR_SUCCESS; + + while(DataSize.QuadPart > 0) + { + // Get the proper size of data + dwToRead = sizeof(DataBuffer); + if(DataSize.HighPart == 0 && DataSize.LowPart < dwToRead) + dwToRead = DataSize.LowPart; + + // Read the source file + ReadFile(hSrcFile, DataBuffer, dwToRead, &dwTransferred, NULL); + if(dwTransferred != dwToRead) + { + nError = ERROR_CAN_NOT_COMPLETE; + break; + } + + // Write to the target file + WriteFile(hTrgFile, DataBuffer, dwToRead, &dwTransferred, NULL); + if(dwTransferred != dwToRead) + { + nError = ERROR_DISK_FULL; + break; + } + + // Decrement the number of data to be copied + DataSize.QuadPart -= dwTransferred; + } + + return ERROR_SUCCESS; +} + +// TODO: Test for archives > 4GB +static int CopyMpqFiles(HANDLE hFile, TMPQArchive * ha, DWORD * pFileSeeds) +{ + TMPQBlockEx * pBlockEx; + TMPQBlock * pBlock; + DWORD dwSeed1; + DWORD dwIndex; + int nError = ERROR_SUCCESS; + + // Walk through all files and write them to the destination MPQ archive + for(dwIndex = 0; dwIndex < ha->pHeader->dwBlockTableSize; dwIndex++) + { + pBlockEx = ha->pExtBlockTable + dwIndex; + pBlock = ha->pBlockTable + dwIndex; + dwSeed1 = pFileSeeds[dwIndex]; + + // Notify the caller about work + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_COMPACTING_FILES, dwIndex, ha->pHeader->dwBlockTableSize); + +// if(dwIndex == 0x1B9) +// DebugBreak(); + + // Copy all the file blocks + // Debug: Break at (dwIndex == 5973) + if(pBlock->dwFlags & MPQ_FILE_EXISTS) + { + nError = CopyMpqFileBlocks(hFile, ha, pBlockEx, pBlock, dwSeed1); + if(nError != ERROR_SUCCESS) + break; + } + } + + // Cleanup and exit + return nError; +} + + +/*****************************************************************************/ +/* Public functions */ +/*****************************************************************************/ + +BOOL WINAPI SFileSetCompactCallback(HANDLE /* hMPQ */, COMPACTCB aCompactCB, void * lpData) +{ + CompactCB = aCompactCB; + lpUserData = lpData; + return TRUE; +} + +//----------------------------------------------------------------------------- +// Archive compacting (incomplete) + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileCompactArchive(HANDLE hMPQ, const char * szListFile, BOOL /* bReserved */) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + HANDLE hFile = INVALID_HANDLE_VALUE; + DWORD * pFileSeeds = NULL; + char szTempFile[MAX_PATH] = ""; + char * szTemp = NULL; + DWORD dwTransferred; + int nError = ERROR_SUCCESS; + + // Test the valid parameters + if(!IsValidMpqHandle(ha)) + nError = ERROR_INVALID_PARAMETER; + + // Create the table with file seeds + if(nError == ERROR_SUCCESS) + { + if((pFileSeeds = ALLOCMEM(DWORD, ha->pHeader->dwBlockTableSize)) != NULL) + memset(pFileSeeds, 0, sizeof(DWORD) * ha->pHeader->dwBlockTableSize); + else + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // First of all, we have to check of we are able to decrypt all files. + // If not, sorry, but the archive cannot be compacted. + if(nError == ERROR_SUCCESS) + nError = CheckIfAllFilesKnown(ha, szListFile, pFileSeeds); + + // Get the temporary file name and create it + if(nError == ERROR_SUCCESS) + { + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_COPYING_NON_MPQ_DATA, 0, 0); + + strcpy(szTempFile, ha->szFileName); + if((szTemp = strrchr(szTempFile, '.')) != NULL) + strcpy(szTemp + 1, "mp_"); + else + strcat(szTempFile, "_"); + + hFile = CreateFile(szTempFile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); + if(hFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + // Write the data before MPQ header (if any) + if(nError == ERROR_SUCCESS && ha->MpqPos.QuadPart > 0) + { + SetFilePointer(ha->hFile, 0, NULL, FILE_BEGIN); + if(ha->pShunt != NULL) + nError = CopyNonMpqData(ha->hFile, hFile, ha->ShuntPos); + else + nError = CopyNonMpqData(ha->hFile, hFile, ha->MpqPos); + } + + // Write the MPQ shunt (if any) + if(nError == ERROR_SUCCESS && ha->pShunt != NULL) + { + BSWAP_TMPQSHUNT(ha->pShunt); + WriteFile(hFile, ha->pShunt, sizeof(TMPQShunt), &dwTransferred, NULL); + BSWAP_TMPQSHUNT(ha->pShunt); + + if(dwTransferred != sizeof(TMPQShunt)) + nError = ERROR_DISK_FULL; + } + + // Write the data between MPQ shunt and the MPQ header (if any) + if(nError == ERROR_SUCCESS && ha->pShunt != NULL) + { + LARGE_INTEGER BytesToCopy; + + BytesToCopy.QuadPart = ha->MpqPos.QuadPart - (ha->ShuntPos.QuadPart + sizeof(TMPQShunt)); + nError = CopyNonMpqData(ha->hFile, hFile, BytesToCopy); + } + + // Write the MPQ header + if(nError == ERROR_SUCCESS) + { + BSWAP_TMPQHEADER(ha->pHeader); + WriteFile(hFile, ha->pHeader, ha->pHeader->dwHeaderSize, &dwTransferred, NULL); + BSWAP_TMPQHEADER(ha->pHeader); + if(dwTransferred != ha->pHeader->dwHeaderSize) + nError = ERROR_DISK_FULL; + } + + // Write the data between the header and between the first file + // For this, we have to determine where the first file begins + if(nError == ERROR_SUCCESS) + { + LARGE_INTEGER FirstFilePos; + LARGE_INTEGER TempPos; + TMPQBlockEx * pBlockEx = ha->pExtBlockTable; + TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize; + TMPQBlock * pBlock = ha->pBlockTable; + + // Maximum file position + FirstFilePos.HighPart = 0x7FFFFFFF; + FirstFilePos.LowPart = 0xFFFFFFFF; + + // Find the block with the least position in the MPQ + while(pBlock < pBlockEnd) + { + TempPos.HighPart = pBlockEx->wFilePosHigh; + TempPos.LowPart = pBlock->dwFilePos; + if(TempPos.QuadPart < FirstFilePos.QuadPart) + FirstFilePos = TempPos; + + pBlockEx++; + pBlock++; + } + + // Set the position in the source file right after the file header + TempPos.QuadPart = ha->MpqPos.QuadPart + ha->pHeader->dwHeaderSize; + SetFilePointer(ha->hFile, TempPos.LowPart, &TempPos.HighPart, FILE_BEGIN); + + // Get the number of bytes to copy + FirstFilePos.QuadPart -= ha->pHeader->dwHeaderSize; + nError = CopyNonMpqData(ha->hFile, hFile, FirstFilePos); + } + + // Now write all file blocks. + if(nError == ERROR_SUCCESS) + nError = CopyMpqFiles(hFile, ha, pFileSeeds); + + // Now we need to update the tables positions + // (but only if the tables are at the end of the file) + if(nError == ERROR_SUCCESS) + { + LARGE_INTEGER RelativePos; + LARGE_INTEGER FilePos = {0}; + + // Set the hash table position + FilePos.LowPart = SetFilePointer(hFile, 0, &FilePos.HighPart, FILE_CURRENT); + RelativePos.QuadPart = FilePos.QuadPart - ha->MpqPos.QuadPart; + ha->pHeader->wHashTablePosHigh = (USHORT)RelativePos.HighPart; + ha->pHeader->dwHashTablePos = RelativePos.LowPart; + ha->HashTablePos = FilePos; + + // Set the block table position + RelativePos.QuadPart += ha->pHeader->dwHashTableSize * sizeof(TMPQHash); + FilePos.QuadPart += ha->pHeader->dwHashTableSize * sizeof(TMPQHash); + ha->pHeader->wBlockTablePosHigh = (USHORT)RelativePos.HighPart; + ha->pHeader->dwBlockTablePos = RelativePos.LowPart; + ha->BlockTablePos = FilePos; + + // Set the extended block table position + RelativePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock); + FilePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock); + if(ha->ExtBlockTablePos.QuadPart != 0) + { + ha->pHeader->ExtBlockTablePos = RelativePos; + ha->ExtBlockTablePos = FilePos; + + RelativePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx); + FilePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx); + } + + // Set the archive size + ha->pHeader->dwArchiveSize = RelativePos.LowPart; + ha->MpqSize = RelativePos; + } + + // If succeeded, update the tables in the file + if(nError == ERROR_SUCCESS) + { + CloseHandle(ha->hFile); + ha->FilePointer.QuadPart = 0; + ha->hFile = hFile; + hFile = INVALID_HANDLE_VALUE; + nError = SaveMPQTables(ha); + } + + // If all succeeded, switch the archives + if(nError == ERROR_SUCCESS) + { + if(CompactCB != NULL) + CompactCB(lpUserData, CCB_CLOSING_ARCHIVE, 0, 0); + + if(!DeleteFile(ha->szFileName) || // Delete the old archive + !CloseHandle(ha->hFile) || // Close the new archive + !MoveFile(szTempFile, ha->szFileName)) // Rename the temporary archive + nError = GetLastError(); + } + + // Now open the freshly renamed archive file + if(nError == ERROR_SUCCESS) + { + ha->hFile = CreateFile(ha->szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if(ha->hFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + // Invalidate the positions of the archive + if(nError == ERROR_SUCCESS) + { + ha->FilePointer.QuadPart = 0; + ha->pLastFile = NULL; + ha->dwBlockPos = 0; + ha->dwBuffPos = 0; + } + + // Cleanup and return + if(hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + if(pFileSeeds != NULL) + FREEMEM(pFileSeeds); + if(nError != ERROR_SUCCESS) + SetLastError(nError); + DeleteFile(szTempFile); + CompactCB = NULL; + return (nError == ERROR_SUCCESS); +} diff --git a/contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp b/contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp new file mode 100644 index 000000000..2410920fc --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp @@ -0,0 +1,530 @@ +/*****************************************************************************/ +/* SFileCreateArchiveEx.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* MPQ Editing functions */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +//----------------------------------------------------------------------------- +// Defines + +#define DEFAULT_BLOCK_SIZE 3 // Default size of the block + +//----------------------------------------------------------------------------- +// Local tables + +static DWORD PowersOfTwo[] = +{ + 0x0000002, 0x0000004, 0x0000008, + 0x0000010, 0x0000020, 0x0000040, 0x0000080, + 0x0000100, 0x0000200, 0x0000400, 0x0000800, + 0x0001000, 0x0002000, 0x0004000, 0x0008000, + 0x0010000, 0x0020000, 0x0040000, 0x0080000, + 0x0000000 +}; + +/*****************************************************************************/ +/* Public functions */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// Opens or creates a (new) MPQ archive. +// +// szMpqName - Name of the archive to be created. +// +// dwCreationDisposition: +// +// Value Archive exists Archive doesn't exist +// ---------- --------------------- --------------------- +// CREATE_NEW Fails Creates new archive +// CREATE_ALWAYS Overwrites existing Creates new archive +// OPEN_EXISTING Opens the archive Fails +// OPEN_ALWAYS Opens the archive Creates new archive +// +// The above mentioned values can be combined with the following flags: +// +// MPQ_CREATE_ARCHIVE_V1 - Creates MPQ archive version 1 +// MPQ_CREATE_ARCHIVE_V2 - Creates MPQ archive version 2 +// +// dwHashTableSize - Size of the hash table (only if creating a new archive). +// Must be between 2^4 (= 16) and 2^18 (= 262 144) +// +// phMpq - Receives handle to the archive +// + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileCreateArchiveEx(const char * szMpqName, DWORD dwCreationDisposition, DWORD dwHashTableSize, HANDLE * phMPQ) +{ + LARGE_INTEGER MpqPos = {0}; // Position of MPQ header in the file + TMPQArchive * ha = NULL; // MPQ archive handle + HANDLE hFile = INVALID_HANDLE_VALUE; // File handle + DWORD dwTransferred = 0; // Number of bytes written into the archive + USHORT wFormatVersion; + BOOL bFileExists = FALSE; + int nIndex = 0; + int nError = ERROR_SUCCESS; + + // Pre-initialize the result value + if(phMPQ != NULL) + *phMPQ = NULL; + + // Check the parameters, if they are valid + if(szMpqName == NULL || *szMpqName == 0 || phMPQ == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + // Check the value of dwCreationDisposition against file existence + bFileExists = (GetFileAttributes(szMpqName) != 0xFFFFFFFF); + + // Extract format version from the "dwCreationDisposition" + wFormatVersion = (USHORT)(dwCreationDisposition >> 0x10); + dwCreationDisposition &= 0x0000FFFF; + + // If the file exists and open required, do it. + if(bFileExists && (dwCreationDisposition == OPEN_EXISTING || dwCreationDisposition == OPEN_ALWAYS)) + { + // Try to open the archive normal way. If it fails, it means that + // the file exist, but it is not a MPQ archive. + if(SFileOpenArchiveEx(szMpqName, 0, 0, phMPQ, GENERIC_READ | GENERIC_WRITE)) + return TRUE; + } + + // Two error cases + if(dwCreationDisposition == CREATE_NEW && bFileExists) + { + SetLastError(ERROR_ALREADY_EXISTS); + return FALSE; + } + if(dwCreationDisposition == OPEN_EXISTING && bFileExists == FALSE) + { + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + // At this point, we have to create the archive. If the file exists, + // we will convert it to MPQ archive. + // Check the value of hash table size. It has to be a power of two + // and must be between HASH_TABLE_SIZE_MIN and HASH_TABLE_SIZE_MAX + if(dwHashTableSize < HASH_TABLE_SIZE_MIN) + dwHashTableSize = HASH_TABLE_SIZE_MIN; + if(dwHashTableSize > HASH_TABLE_SIZE_MAX) + dwHashTableSize = HASH_TABLE_SIZE_MAX; + + // Round the hash table size up to the nearest power of two + for(nIndex = 0; PowersOfTwo[nIndex] != 0; nIndex++) + { + if(dwHashTableSize <= PowersOfTwo[nIndex]) + { + dwHashTableSize = PowersOfTwo[nIndex]; + break; + } + } + + // Prepare the buffer for decryption engine + if(nError == ERROR_SUCCESS) + nError = PrepareStormBuffer(); + + // Get the position where the MPQ header will begin. + if(nError == ERROR_SUCCESS) + { + hFile = CreateFile(szMpqName, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + dwCreationDisposition, + 0, + NULL); + if(hFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + // Retrieve the file size and round it up to 0x200 bytes + if(nError == ERROR_SUCCESS) + { + MpqPos.LowPart = GetFileSize(hFile, (LPDWORD)&MpqPos.HighPart); + MpqPos.QuadPart += 0x1FF; + MpqPos.LowPart &= 0xFFFFFE00; + + if(wFormatVersion == MPQ_FORMAT_VERSION_1 && MpqPos.HighPart != 0) + nError = ERROR_DISK_FULL; + if(wFormatVersion == MPQ_FORMAT_VERSION_2 && MpqPos.HighPart > 0x0000FFFF) + nError = ERROR_DISK_FULL; + } + + // Move to the end of the file (i.e. begin of the MPQ) + if(nError == ERROR_SUCCESS) + { + if(SetFilePointer(hFile, MpqPos.LowPart, &MpqPos.HighPart, FILE_BEGIN) == 0xFFFFFFFF) + nError = GetLastError(); + } + + // Set the new end of the file to the MPQ header position + if(nError == ERROR_SUCCESS) + { + if(!SetEndOfFile(hFile)) + nError = GetLastError(); + } + + // Create the archive handle + if(nError == ERROR_SUCCESS) + { + if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Fill the MPQ archive handle structure and create the header, + // block buffer, hash table and block table + if(nError == ERROR_SUCCESS) + { + memset(ha, 0, sizeof(TMPQArchive)); + strcpy(ha->szFileName, szMpqName); + ha->hFile = hFile; + ha->dwBlockSize = 0x200 << DEFAULT_BLOCK_SIZE; + ha->MpqPos = MpqPos; + ha->FilePointer = MpqPos; + ha->pHeader = &ha->Header; + ha->pHashTable = ALLOCMEM(TMPQHash, dwHashTableSize); + ha->pBlockTable = ALLOCMEM(TMPQBlock, dwHashTableSize); + ha->pExtBlockTable = ALLOCMEM(TMPQBlockEx, dwHashTableSize); + ha->pbBlockBuffer = ALLOCMEM(BYTE, ha->dwBlockSize); + ha->pListFile = NULL; + ha->dwFlags |= MPQ_FLAG_CHANGED; + + if(!ha->pHashTable || !ha->pBlockTable || !ha->pExtBlockTable || !ha->pbBlockBuffer) + nError = GetLastError(); + hFile = INVALID_HANDLE_VALUE; + } + + // Fill the MPQ header and all buffers + if(nError == ERROR_SUCCESS) + { + LARGE_INTEGER TempPos; + TMPQHeader2 * pHeader = ha->pHeader; + DWORD dwHeaderSize = (wFormatVersion == MPQ_FORMAT_VERSION_2) ? sizeof(TMPQHeader2) : sizeof(TMPQHeader); + + memset(pHeader, 0, sizeof(TMPQHeader2)); + pHeader->dwID = ID_MPQ; + pHeader->dwHeaderSize = dwHeaderSize; + pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash); + pHeader->wFormatVersion = wFormatVersion; + pHeader->wBlockSize = 3; // 0x1000 bytes per block + pHeader->dwHashTableSize = dwHashTableSize; + + // Set proper hash table positions + ha->HashTablePos.QuadPart = ha->MpqPos.QuadPart + pHeader->dwHeaderSize; + ha->pHeader->dwHashTablePos = pHeader->dwHeaderSize; + ha->pHeader->wHashTablePosHigh = 0; + + // Set proper block table positions + ha->BlockTablePos.QuadPart = ha->HashTablePos.QuadPart + + (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); + TempPos.QuadPart = ha->BlockTablePos.QuadPart - ha->MpqPos.QuadPart; + ha->pHeader->dwBlockTablePos = TempPos.LowPart; + ha->pHeader->wBlockTablePosHigh = (USHORT)TempPos.HighPart; + + // For now, we set extended block table positioon top zero unless we add enough + // files to cause the archive size exceed 4 GB + ha->ExtBlockTablePos.QuadPart = 0; + + // Clear all tables + memset(ha->pBlockTable, 0, sizeof(TMPQBlock) * dwHashTableSize); + memset(ha->pExtBlockTable, 0, sizeof(TMPQBlockEx) * dwHashTableSize); + memset(ha->pHashTable, 0xFF, sizeof(TMPQHash) * dwHashTableSize); + } + + // Write the MPQ header to the file + if(nError == ERROR_SUCCESS) + { + DWORD dwHeaderSize = ha->pHeader->dwHeaderSize; + + BSWAP_TMPQHEADER(ha->pHeader); + WriteFile(ha->hFile, ha->pHeader, dwHeaderSize, &dwTransferred, NULL); + BSWAP_TMPQHEADER(ha->pHeader); + + if(dwTransferred != ha->pHeader->dwHeaderSize) + nError = ERROR_DISK_FULL; + + ha->FilePointer.QuadPart = ha->MpqPos.QuadPart + dwTransferred; + ha->MpqSize.QuadPart += dwTransferred; + } + + // Create the internal listfile + if(nError == ERROR_SUCCESS) + nError = SListFileCreateListFile(ha); + + // Try to add the internal listfile + if(nError == ERROR_SUCCESS) + SFileAddListFile((HANDLE)ha, NULL); + + // Cleanup : If an error, delete all buffers and return + if(nError != ERROR_SUCCESS) + { + FreeMPQArchive(ha); + if(hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + SetLastError(nError); + } + + // Return the values + *phMPQ = (HANDLE)ha; + return (nError == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// Changes locale ID of a file + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale) +{ + TMPQFile * hf = (TMPQFile *)hFile; + + // Invalid handle => do nothing + if(IsValidFileHandle(hf) == FALSE || IsValidMpqHandle(hf->ha) == FALSE) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + // If the file has not been open for writing, do nothing. + if(hf->ha->pListFile == NULL) + return ERROR_ACCESS_DENIED; + + hf->pHash->lcLocale = (USHORT)lcNewLocale; + hf->ha->dwFlags |= MPQ_FLAG_CHANGED; + return TRUE; +} + +//----------------------------------------------------------------------------- +// Adds a file into the archive + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileAddFileEx(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality, int nFileType) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + HANDLE hFile = INVALID_HANDLE_VALUE; + BOOL bReplaced = FALSE; // TRUE if replacing file in the archive + int nError = ERROR_SUCCESS; + + if(nError == ERROR_SUCCESS) + { + // Check valid parameters + if(IsValidMpqHandle(ha) == FALSE || szFileName == NULL || *szFileName == 0 || szArchivedName == NULL || *szArchivedName == 0) + nError = ERROR_INVALID_PARAMETER; + + // Check the values of dwFlags + if((dwFlags & MPQ_FILE_COMPRESS_PKWARE) && (dwFlags & MPQ_FILE_COMPRESS_MULTI)) + nError = ERROR_INVALID_PARAMETER; + } + + // If anyone is trying to add listfile, and the archive already has a listfile, + // deny the operation, but return success. + if(nError == ERROR_SUCCESS) + { + if(ha->pListFile != NULL && !_stricmp(szFileName, LISTFILE_NAME)) + return ERROR_SUCCESS; + } + + // Open added file + if(nError == ERROR_SUCCESS) + { + hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL); + if(hFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + if(nError == ERROR_SUCCESS) + nError = AddFileToArchive(ha, hFile, szArchivedName, dwFlags, dwQuality, nFileType, &bReplaced); + + // Add the file into listfile also + if(nError == ERROR_SUCCESS && bReplaced == FALSE) + nError = SListFileAddNode(ha, szArchivedName); + + // Cleanup and exit + if(hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + if(nError != ERROR_SUCCESS) + SetLastError(nError); + return (nError == ERROR_SUCCESS); +} + +// Adds a data file into the archive +// TODO: Test for archives > 4GB +BOOL WINAPI SFileAddFile(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags) +{ + return SFileAddFileEx(hMPQ, szFileName, szArchivedName, dwFlags, 0, SFILE_TYPE_DATA); +} + +// Adds a WAVE file into the archive +// TODO: Test for archives > 4GB +BOOL WINAPI SFileAddWave(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality) +{ + return SFileAddFileEx(hMPQ, szFileName, szArchivedName, dwFlags, dwQuality, SFILE_TYPE_WAVE); +} + +//----------------------------------------------------------------------------- +// BOOL SFileRemoveFile(HANDLE hMPQ, char * szFileName) +// +// This function removes a file from the archive. The file content +// remains there, only the entries in the hash table and in the block +// table are updated. + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileRemoveFile(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + TMPQBlockEx * pBlockEx = NULL; // Block entry of deleted file + TMPQBlock * pBlock = NULL; // Block entry of deleted file + TMPQHash * pHash = NULL; // Hash entry of deleted file + DWORD dwBlockIndex = 0; + int nError = ERROR_SUCCESS; + + // Check the parameters + if(nError == ERROR_SUCCESS) + { + if(IsValidMpqHandle(ha) == FALSE) + nError = ERROR_INVALID_PARAMETER; + if(dwSearchScope != SFILE_OPEN_BY_INDEX && *szFileName == 0) + nError = ERROR_INVALID_PARAMETER; + } + + // Do not allow to remove listfile + if(nError == ERROR_SUCCESS) + { + if(dwSearchScope != SFILE_OPEN_BY_INDEX && !_stricmp(szFileName, LISTFILE_NAME)) + nError = ERROR_ACCESS_DENIED; + } + + // Get hash entry belonging to this file + if(nError == ERROR_SUCCESS) + { + if((pHash = GetHashEntryEx(ha, (char *)szFileName, lcLocale)) == NULL) + nError = ERROR_FILE_NOT_FOUND; + } + + // If index was not found, or is greater than number of files, exit. + if(nError == ERROR_SUCCESS) + { + if((dwBlockIndex = pHash->dwBlockIndex) > ha->pHeader->dwBlockTableSize) + nError = ERROR_FILE_NOT_FOUND; + } + + // Get block and test if the file is not already deleted + if(nError == ERROR_SUCCESS) + { + pBlockEx = ha->pExtBlockTable + dwBlockIndex; + pBlock = ha->pBlockTable + dwBlockIndex; + if((pBlock->dwFlags & MPQ_FILE_EXISTS) == 0) + nError = ERROR_FILE_NOT_FOUND; + } + + // Now invalidate the block entry and the hash entry. Do not make any + // relocations and file copying, use SFileCompactArchive for it. + if(nError == ERROR_SUCCESS) + { + pBlockEx->wFilePosHigh = 0; + pBlock->dwFilePos = 0; + pBlock->dwFSize = 0; + pBlock->dwCSize = 0; + pBlock->dwFlags = 0; + pHash->dwName1 = 0xFFFFFFFF; + pHash->dwName2 = 0xFFFFFFFF; + pHash->lcLocale = 0xFFFF; + pHash->wPlatform = 0xFFFF; + pHash->dwBlockIndex = HASH_ENTRY_DELETED; + + // Update MPQ archive + ha->dwFlags |= MPQ_FLAG_CHANGED; + } + + // Remove the file from the list file + if(nError == ERROR_SUCCESS && lcLocale == LANG_NEUTRAL) + nError = SListFileRemoveNode(ha, szFileName); + + // Resolve error and exit + if(nError != ERROR_SUCCESS) + SetLastError(nError); + return (nError == ERROR_SUCCESS); +} + +// Renames the file within the archive. +// TODO: Test for archives > 4GB +BOOL WINAPI SFileRenameFile(HANDLE hMPQ, const char * szFileName, const char * szNewFileName) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + TMPQHash * pOldHash = NULL; // Hash entry for the original file + TMPQHash * pNewHash = NULL; // Hash entry for the renamed file + DWORD dwBlockIndex = 0; + int nError = ERROR_SUCCESS; + + // Test the valid parameters + if(nError == ERROR_SUCCESS) + { + if(hMPQ == NULL || szNewFileName == NULL || *szNewFileName == 0) + nError = ERROR_INVALID_PARAMETER; + if(szFileName == NULL || *szFileName == 0) + nError = ERROR_INVALID_PARAMETER; + } + + // Do not allow to rename listfile + if(nError == ERROR_SUCCESS) + { + if(!_stricmp(szFileName, LISTFILE_NAME)) + nError = ERROR_ACCESS_DENIED; + } + + // Test if the file already exists in the archive + if(nError == ERROR_SUCCESS) + { + if((pNewHash = GetHashEntryEx(ha, szNewFileName, lcLocale)) != NULL) + nError = ERROR_ALREADY_EXISTS; + } + + // Get the hash table entry for the original file + if(nError == ERROR_SUCCESS) + { + if((pOldHash = GetHashEntryEx(ha, szFileName, lcLocale)) == NULL) + nError = ERROR_FILE_NOT_FOUND; + } + + // Get the hash table entry for the renamed file + if(nError == ERROR_SUCCESS) + { + // Save block table index and remove the hash table entry + dwBlockIndex = pOldHash->dwBlockIndex; + pOldHash->dwName1 = 0xFFFFFFFF; + pOldHash->dwName2 = 0xFFFFFFFF; + pOldHash->lcLocale = 0xFFFF; + pOldHash->wPlatform = 0xFFFF; + pOldHash->dwBlockIndex = HASH_ENTRY_DELETED; + + if((pNewHash = FindFreeHashEntry(ha, szNewFileName)) == NULL) + nError = ERROR_CAN_NOT_COMPLETE; + } + + // Save the block index and clear the hash entry + if(nError == ERROR_SUCCESS) + { + // Copy the block table index + pNewHash->dwBlockIndex = dwBlockIndex; + ha->dwFlags |= MPQ_FLAG_CHANGED; + } + + // Rename the file in the list file + if(nError == ERROR_SUCCESS) + nError = SListFileRenameNode(ha, szFileName, szNewFileName); + + // Resolve error and return + if(nError != ERROR_SUCCESS) + SetLastError(nError); + return (nError == ERROR_SUCCESS); +} + diff --git a/contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp b/contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp new file mode 100644 index 000000000..7f16cde01 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp @@ -0,0 +1,63 @@ +/*****************************************************************************/ +/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Simple extracting utility */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted) +{ + HANDLE hLocalFile = INVALID_HANDLE_VALUE; + HANDLE hMpqFile = NULL; + int nError = ERROR_SUCCESS; + + // Create the local file + if(nError == ERROR_SUCCESS) + { + hLocalFile = CreateFile(szExtracted, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); + if(hLocalFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + // Open the MPQ file + if(nError == ERROR_SUCCESS) + { + if(!SFileOpenFileEx(hMpq, szToExtract, 0, &hMpqFile)) + nError = GetLastError(); + } + + // Copy the file's content + if(nError == ERROR_SUCCESS) + { + char szBuffer[0x1000]; + DWORD dwTransferred = 1; + + while(dwTransferred > 0) + { + SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL); + if(dwTransferred == 0) + break; + + WriteFile(hLocalFile, szBuffer, dwTransferred, &dwTransferred, NULL); + if(dwTransferred == 0) + break; + } + } + + // Close the files + if(hMpqFile != NULL) + SFileCloseFile(hMpqFile); + if(hLocalFile != INVALID_HANDLE_VALUE) + CloseHandle(hLocalFile); + if(nError != ERROR_SUCCESS) + SetLastError(nError); + return (BOOL)(nError == ERROR_SUCCESS); +} diff --git a/contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp b/contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp new file mode 100644 index 000000000..41dbeba90 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp @@ -0,0 +1,291 @@ +/*****************************************************************************/ +/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* A module for file searching within MPQs */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +//----------------------------------------------------------------------------- +// Defines + +#define LISTFILE_CACHE_SIZE 0x1000 + +//----------------------------------------------------------------------------- +// Local functions + +static BOOL IsValidSearchHandle(TMPQSearch * hs) +{ + if(hs == NULL || IsBadReadPtr(hs, sizeof(TMPQSearch))) + return FALSE; + + if(!IsValidMpqHandle(hs->ha)) + return FALSE; + + return TRUE; +} + +// This function compares a string with a wildcard search string. +// returns TRUE, when the string matches with the wildcard. +BOOL CheckWildCard(const char * szString, const char * szWildCard) +{ + char * szTemp; // Temporary helper pointer + int nResult = 0; // For memcmp return values + int nMustNotMatch = 0; // Number of following chars int szString, + // which must not match with szWildCard + int nMustMatch = 0; // Number of the following characters, + // which must match + + // When the string is empty, it does not match with every wildcard + if(*szString == 0) + return FALSE; + + // When the mask is empty, it matches to every wildcard + if(szWildCard == NULL || *szWildCard == 0) + return FALSE; + + // Do normal test + for(;;) + { + switch(*szWildCard) + { + case '*': // Means "every number of characters" + // Skip all asterisks + while(*szWildCard == '*') + szWildCard++; + + // When no more characters in wildcard, it means that the strings match + if(*szWildCard == 0) + return TRUE; + + // The next N characters must not agree + nMustNotMatch |= 0x70000000; + break; + + case '?': // Means "One or no character" + while(*szWildCard == '?') + { + nMustNotMatch++; + szWildCard++; + } + break; + + default: + // If the two characters match + if(toupper(*szString) == toupper(*szWildCard)) + { + // When end of string, they agree + if(*szString == 0) + return TRUE; + + nMustNotMatch = 0; + szWildCard++; + szString++; + break; + } + + // If the next character must match, the string does not match + if(nMustNotMatch == 0) + return FALSE; + + // Count the characters which must match after characters + // that must not match + szTemp = (char *)szWildCard; + nMustMatch = 0; + while(*szTemp != 0 && *szTemp != '*' && *szTemp != '?') + { + nMustMatch++; + szTemp++; + } + + // Now skip characters from szString up to number of chars + // that must not match + nResult = -1; + while(nMustNotMatch > 0 && *szString != 0) + { + if((nResult = _strnicmp(szString, szWildCard, nMustMatch)) == 0) + break; + + szString++; + nMustNotMatch--; + } + + // Make one more comparison + if(nMustNotMatch == 0) + nResult = _strnicmp(szString, szWildCard, nMustMatch); + + // If a match has been found, continue the search + if(nResult == 0) + { + nMustNotMatch = 0; + szWildCard += nMustMatch; + szString += nMustMatch; + break; + } + return FALSE; + } + } +} + +// Performs one MPQ search +// TODO: Test for archives > 4GB +static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData) +{ + TMPQArchive * ha = hs->ha; + TFileNode * pNode; + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash = ha->pHashTable + hs->dwNextIndex; + + // Do until some file found or no more files + while(pHash < pHashEnd) + { + pNode = ha->pListFile[hs->dwNextIndex++]; + + // If this entry is free, do nothing + if(pHash->dwBlockIndex < HASH_ENTRY_FREE && (DWORD_PTR)pNode < HASH_ENTRY_FREE) + { + // Check the file name. + if(CheckWildCard(pNode->szFileName, hs->szSearchMask)) + { + TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex; + + lpFindFileData->lcLocale = pHash->lcLocale; + lpFindFileData->dwFileSize = pBlock->dwFSize; + lpFindFileData->dwFileFlags = pBlock->dwFlags; + lpFindFileData->dwBlockIndex = pHash->dwBlockIndex; + lpFindFileData->dwCompSize = pBlock->dwCSize; + + // Fill the file name and plain file name + strcpy(lpFindFileData->cFileName, pNode->szFileName); + lpFindFileData->szPlainName = strrchr(lpFindFileData->cFileName, '\\'); + if(lpFindFileData->szPlainName == NULL) + lpFindFileData->szPlainName = lpFindFileData->cFileName; + else + lpFindFileData->szPlainName++; + + // Fill the next entry + return ERROR_SUCCESS; + } + } + + pHash++; + } + + // No more files found, return error + return ERROR_NO_MORE_FILES; +} + +// TODO: Test for archives > 4GB +static void FreeMPQSearch(TMPQSearch *& hs) +{ + if(hs != NULL) + { + FREEMEM(hs); + hs = NULL; + } +} + +//----------------------------------------------------------------------------- +// Public functions + +// TODO: Test for archives > 4GB +HANDLE WINAPI SFileFindFirstFile(HANDLE hMPQ, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + TMPQSearch * hs = NULL; // Search object handle + size_t nSize = 0; + int nError = ERROR_SUCCESS; + + // Check for the valid parameters + if(nError == ERROR_SUCCESS) + { + if(!IsValidMpqHandle(ha)) + nError = ERROR_INVALID_PARAMETER; + + if(szMask == NULL || lpFindFileData == NULL) + nError = ERROR_INVALID_PARAMETER; + + if(szListFile == NULL && !IsValidMpqHandle(ha)) + nError = ERROR_INVALID_PARAMETER; + } + + // Include the listfile into the MPQ's internal listfile + // Note that if the listfile name is NULL, do nothing because the + // internal listfile is always included. + if(nError == ERROR_SUCCESS && szListFile != NULL) + nError = SFileAddListFile((HANDLE)ha, szListFile); + + // Allocate the structure for MPQ search + if(nError == ERROR_SUCCESS) + { + nSize = sizeof(TMPQSearch) + strlen(szMask) + 1; + if((hs = (TMPQSearch *)ALLOCMEM(char, nSize)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Perform the first search + if(nError == ERROR_SUCCESS) + { + memset(hs, 0, sizeof(TMPQSearch)); + hs->ha = ha; + hs->dwNextIndex = 0; + strcpy(hs->szSearchMask, szMask); + nError = DoMPQSearch(hs, lpFindFileData); + } + + // Cleanup + if(nError != ERROR_SUCCESS) + { + FreeMPQSearch(hs); + SetLastError(nError); + } + + // Return the result value + return (HANDLE)hs; +} + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) +{ + TMPQSearch * hs = (TMPQSearch *)hFind; + int nError = ERROR_SUCCESS; + + // Check the parameters + if(nError == ERROR_SUCCESS) + { + if(!IsValidSearchHandle(hs) || lpFindFileData == NULL) + nError = ERROR_INVALID_PARAMETER; + } + + if(nError == ERROR_SUCCESS) + nError = DoMPQSearch(hs, lpFindFileData); + + if(nError != ERROR_SUCCESS) + { + SetLastError(nError); + return FALSE; + } + return TRUE; +} + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileFindClose(HANDLE hFind) +{ + TMPQSearch * hs = (TMPQSearch *)hFind; + + // Check the parameters + if(!IsValidSearchHandle(hs)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + FreeMPQSearch(hs); + return TRUE; +} diff --git a/contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp b/contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp new file mode 100644 index 000000000..cadb4e023 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp @@ -0,0 +1,497 @@ +/*****************************************************************************/ +/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */ +/* */ +/* Author : Ladislav Zezula */ +/* E-mail : ladik@zezula.net */ +/* WWW : www.zezula.net */ +/*---------------------------------------------------------------------------*/ +/* Archive functions of Storm.dll */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */ +/* 19.11.03 1.01 Dan Big endian handling */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +/*****************************************************************************/ +/* Local functions */ +/*****************************************************************************/ + +static BOOL IsAviFile(TMPQHeader * pHeader) +{ + DWORD * AviHdr = (DWORD *)pHeader; + + // Test for 'RIFF', 'AVI ' or 'LIST' + return (AviHdr[0] == 'FFIR' && AviHdr[2] == ' IVA' && AviHdr[3] == 'TSIL'); +} + +// This function gets the right positions of the hash table and the block table. +// TODO: Test for archives > 4GB +static int RelocateMpqTablePositions(TMPQArchive * ha) +{ + TMPQHeader2 * pHeader = ha->pHeader; + LARGE_INTEGER FileSize; + LARGE_INTEGER TempSize; + + // Get the size of the file + FileSize.LowPart = GetFileSize(ha->hFile, (LPDWORD)&FileSize.HighPart); + + // Set the proper hash table position + ha->HashTablePos.HighPart = pHeader->wHashTablePosHigh; + ha->HashTablePos.LowPart = pHeader->dwHashTablePos; + ha->HashTablePos.QuadPart += ha->MpqPos.QuadPart; + if(ha->HashTablePos.QuadPart > FileSize.QuadPart) + return ERROR_BAD_FORMAT; + + // Set the proper block table position + ha->BlockTablePos.HighPart = pHeader->wBlockTablePosHigh; + ha->BlockTablePos.LowPart = pHeader->dwBlockTablePos; + ha->BlockTablePos.QuadPart += ha->MpqPos.QuadPart; + if(ha->BlockTablePos.QuadPart > FileSize.QuadPart) + return ERROR_BAD_FORMAT; + + // Set the proper position of the extended block table + if(pHeader->ExtBlockTablePos.QuadPart != 0) + { + ha->ExtBlockTablePos = pHeader->ExtBlockTablePos; + ha->ExtBlockTablePos.QuadPart += ha->MpqPos.QuadPart; + if(ha->ExtBlockTablePos.QuadPart > FileSize.QuadPart) + return ERROR_BAD_FORMAT; + } + + // Size of MPQ archive is computed as the biggest of + // (EndOfBlockTable, EndOfHashTable, EndOfExtBlockTable) + TempSize.QuadPart = ha->HashTablePos.QuadPart + (pHeader->dwHashTableSize * sizeof(TMPQHash)); + if(TempSize.QuadPart > ha->MpqSize.QuadPart) + ha->MpqSize = TempSize; + TempSize.QuadPart = ha->BlockTablePos.QuadPart + (pHeader->dwBlockTableSize * sizeof(TMPQBlock)); + if(TempSize.QuadPart > ha->MpqSize.QuadPart) + ha->MpqSize = TempSize; + TempSize.QuadPart = ha->ExtBlockTablePos.QuadPart + (pHeader->dwBlockTableSize * sizeof(TMPQBlockEx)); + if(TempSize.QuadPart > ha->MpqSize.QuadPart) + ha->MpqSize = TempSize; + + // MPQ size does not include the bytes before MPQ header + ha->MpqSize.QuadPart -= ha->MpqPos.QuadPart; + return ERROR_SUCCESS; +} + + +/*****************************************************************************/ +/* Public functions */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// SFileGetLocale and SFileSetLocale +// Set the locale for all neewly opened archives and files + +LCID WINAPI SFileGetLocale() +{ + return lcLocale; +} + +LCID WINAPI SFileSetLocale(LCID lcNewLocale) +{ + lcLocale = lcNewLocale; + return lcLocale; +} + +//----------------------------------------------------------------------------- +// SFileOpenArchiveEx (not a public function !!!) +// +// szFileName - MPQ archive file name to open +// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives +// dwFlags - If contains MPQ_OPEN_NO_LISTFILE, then the internal list file will not be used. +// phMPQ - Pointer to store open archive handle + +BOOL SFileOpenArchiveEx( + const char * szMpqName, + DWORD dwPriority, + DWORD dwFlags, + HANDLE * phMPQ, + DWORD dwAccessMode) +{ + LARGE_INTEGER TempPos; + TMPQArchive * ha = NULL; // Archive handle + HANDLE hFile = INVALID_HANDLE_VALUE;// Opened archive file handle + DWORD dwMaxBlockIndex = 0; // Maximum value of block entry + DWORD dwBlockTableSize = 0; // Block table size. + DWORD dwTransferred; // Number of bytes read + DWORD dwBytes = 0; // Number of bytes to read + int nError = ERROR_SUCCESS; + + // Check the right parameters + if(nError == ERROR_SUCCESS) + { + if(szMpqName == NULL || *szMpqName == 0 || phMPQ == NULL) + nError = ERROR_INVALID_PARAMETER; + } + + // Ensure that StormBuffer is allocated + if(nError == ERROR_SUCCESS) + nError = PrepareStormBuffer(); + + // Open the MPQ archive file + if(nError == ERROR_SUCCESS) + { + hFile = CreateFile(szMpqName, dwAccessMode, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if(hFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + // Allocate the MPQhandle + if(nError == ERROR_SUCCESS) + { + if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Initialize handle structure and allocate structure for MPQ header + if(nError == ERROR_SUCCESS) + { + memset(ha, 0, sizeof(TMPQArchive)); + strncpy(ha->szFileName, szMpqName, strlen(szMpqName)); + ha->hFile = hFile; + ha->dwPriority = dwPriority; + ha->pHeader = &ha->Header; + ha->pListFile = NULL; + hFile = INVALID_HANDLE_VALUE; + } + + // Find the offset of MPQ header within the file + if(nError == ERROR_SUCCESS) + { + LARGE_INTEGER SearchPos = {0}; + LARGE_INTEGER MpqPos = {0}; + DWORD dwHeaderID; + + for(;;) + { + // Invalidate the MPQ ID and read the eventual header + SetFilePointer(ha->hFile, MpqPos.LowPart, &MpqPos.HighPart, FILE_BEGIN); + ReadFile(ha->hFile, ha->pHeader, sizeof(TMPQHeader2), &dwTransferred, NULL); + dwHeaderID = BSWAP_INT32_UNSIGNED(ha->pHeader->dwID); + + // Special check : Some MPQs are actually AVI files, only with + // changed extension. + if(MpqPos.QuadPart == 0 && IsAviFile(ha->pHeader)) + { + nError = ERROR_AVI_FILE; + break; + } + + // If different number of bytes read, break the loop + if(dwTransferred != sizeof(TMPQHeader2)) + { + nError = ERROR_BAD_FORMAT; + break; + } + + // If there is the MPQ shunt signature, process it + if(dwHeaderID == ID_MPQ_SHUNT && ha->pShunt == NULL) + { + // Fill the shunt header + ha->ShuntPos = MpqPos; + ha->pShunt = &ha->Shunt; + memcpy(ha->pShunt, ha->pHeader, sizeof(TMPQShunt)); + BSWAP_TMPQSHUNT(ha->pShunt); + + // Set the MPQ pos and repeat the search + MpqPos.QuadPart = SearchPos.QuadPart + ha->pShunt->dwHeaderPos; + continue; + } + + // There must be MPQ header signature + if(dwHeaderID == ID_MPQ) + { + BSWAP_TMPQHEADER(ha->pHeader); + + // Save the position where the MPQ header has been found + ha->MpqPos = MpqPos; + + // If valid signature has been found, break the loop + if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) + { + // W3M Map Protectors set some garbage value into the "dwHeaderSize" + // field of MPQ header. This value is apparently ignored by Storm.dll + if(ha->pHeader->dwHeaderSize != sizeof(TMPQHeader) && + ha->pHeader->dwHeaderSize != sizeof(TMPQHeader2)) + { + ha->dwFlags |= MPQ_FLAG_PROTECTED; + ha->pHeader->dwHeaderSize = sizeof(TMPQHeader); + } + + if(ha->pHeader->dwHashTablePos < ha->pHeader->dwArchiveSize && + ha->pHeader->dwBlockTablePos < ha->pHeader->dwArchiveSize) + { + break; + } + } + + if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2) + { + break; + } + + nError = ERROR_NOT_SUPPORTED; + break; + } + + // If a MPQ shunt already has been found, + // and no MPQ header was at potision pointed by the shunt, + // then the archive is corrupt + if(ha->pShunt != NULL) + { + nError = ERROR_BAD_FORMAT; + break; + } + + // Move to the next possible offset + SearchPos.QuadPart += 0x200; + MpqPos = SearchPos; + } + } + + // Relocate tables position + if(nError == ERROR_SUCCESS) + { + // Clear the fields not supported in older formats + if(ha->pHeader->wFormatVersion < MPQ_FORMAT_VERSION_2) + { + ha->pHeader->ExtBlockTablePos.QuadPart = 0; + ha->pHeader->wBlockTablePosHigh = 0; + ha->pHeader->wHashTablePosHigh = 0; + } + + ha->dwBlockSize = (0x200 << ha->pHeader->wBlockSize); + nError = RelocateMpqTablePositions(ha); + } + + // Allocate buffers + if(nError == ERROR_SUCCESS) + { + // + // Note that the block table should be as large as the hash table + // (For later file additions). + // + // I have found a MPQ which has the block table larger than + // the hash table. We should avoid buffer overruns caused by that. + // + dwBlockTableSize = max(ha->pHeader->dwHashTableSize, ha->pHeader->dwBlockTableSize); + + ha->pHashTable = ALLOCMEM(TMPQHash, ha->pHeader->dwHashTableSize); + ha->pBlockTable = ALLOCMEM(TMPQBlock, dwBlockTableSize); + ha->pExtBlockTable = ALLOCMEM(TMPQBlockEx, dwBlockTableSize); + ha->pbBlockBuffer = ALLOCMEM(BYTE, ha->dwBlockSize); + + if(!ha->pHashTable || !ha->pBlockTable || !ha->pExtBlockTable || !ha->pbBlockBuffer) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Read the hash table into memory + if(nError == ERROR_SUCCESS) + { + dwBytes = ha->pHeader->dwHashTableSize * sizeof(TMPQHash); + SetFilePointer(ha->hFile, ha->HashTablePos.LowPart, &ha->HashTablePos.HighPart, FILE_BEGIN); + ReadFile(ha->hFile, ha->pHashTable, dwBytes, &dwTransferred, NULL); + + if(dwTransferred != dwBytes) + nError = ERROR_FILE_CORRUPT; + } + + // Decrypt hash table and check if it is correctly decrypted + if(nError == ERROR_SUCCESS) + { + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash; + + // We have to convert the hash table from LittleEndian + BSWAP_ARRAY32_UNSIGNED((DWORD *)ha->pHashTable, (dwBytes / sizeof(DWORD))); + DecryptHashTable((DWORD *)ha->pHashTable, (BYTE *)"(hash table)", (ha->pHeader->dwHashTableSize * 4)); + + // Check hash table if is correctly decrypted + for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++) + { + // Note: Some MPQs from World of Warcraft have wPlatform set to 0x0100. + + // If not free or deleted hash entry, check for valid values + if(pHash->dwBlockIndex < HASH_ENTRY_DELETED) + { + // The block index should not be larger than size of the block table + if(pHash->dwBlockIndex > ha->pHeader->dwBlockTableSize) + { + nError = ERROR_BAD_FORMAT; + break; + } + + // Remember the highest block table entry + if(pHash->dwBlockIndex > dwMaxBlockIndex) + dwMaxBlockIndex = pHash->dwBlockIndex; + } + } + } + + // Now, read the block table + if(nError == ERROR_SUCCESS) + { + memset(ha->pBlockTable, 0, dwBlockTableSize * sizeof(TMPQBlock)); + + dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock); + SetFilePointer(ha->hFile, ha->BlockTablePos.LowPart, &ha->BlockTablePos.HighPart, FILE_BEGIN); + ReadFile(ha->hFile, ha->pBlockTable, dwBytes, &dwTransferred, NULL); + + // We have to convert every DWORD in ha->block from LittleEndian + BSWAP_ARRAY32_UNSIGNED((DWORD *)ha->pBlockTable, dwBytes / sizeof(DWORD)); + + if(dwTransferred != dwBytes) + nError = ERROR_FILE_CORRUPT; + } + + // Decrypt block table. + // Some MPQs don't have Decrypted block table, e.g. cracked Diablo version + // We have to check if block table is really encrypted + if(nError == ERROR_SUCCESS) + { + TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize; + TMPQBlock * pBlock = ha->pBlockTable; + BOOL bBlockTableEncrypted = FALSE; + + // Verify all blocks entries in the table + // The loop usually stops at the first entry + while(pBlock < pBlockEnd) + { + // The lower 8 bits of the MPQ flags are always zero. + // Note that this may change in next MPQ versions + if(pBlock->dwFlags & 0x000000FF) + { + bBlockTableEncrypted = TRUE; + break; + } + + // Move to the next block table entry + pBlock++; + } + + if(bBlockTableEncrypted) + { + DecryptBlockTable((DWORD *)ha->pBlockTable, + (BYTE *)"(block table)", + (ha->pHeader->dwBlockTableSize * 4)); + } + } + + // Now, read the extended block table. + // For V1 archives, we still will maintain the extended block table + // (it will be filled with zeros) + // TODO: Test with >4GB + if(nError == ERROR_SUCCESS) + { + memset(ha->pExtBlockTable, 0, dwBlockTableSize * sizeof(TMPQBlockEx)); + + if(ha->pHeader->ExtBlockTablePos.QuadPart != 0) + { + dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx); + SetFilePointer(ha->hFile, + ha->ExtBlockTablePos.LowPart, + &ha->ExtBlockTablePos.HighPart, + FILE_BEGIN); + ReadFile(ha->hFile, ha->pExtBlockTable, dwBytes, &dwTransferred, NULL); + + // We have to convert every DWORD in ha->block from LittleEndian + BSWAP_ARRAY16_UNSIGNED((USHORT *)ha->pExtBlockTable, dwBytes / sizeof(USHORT)); + + // The extended block table is not encrypted (so far) + if(dwTransferred != dwBytes) + nError = ERROR_FILE_CORRUPT; + } + } + + // Verify the both block tables (If the MPQ file is not protected) + if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0) + { + TMPQBlockEx * pBlockEx = ha->pExtBlockTable; + TMPQBlock * pBlockEnd = ha->pBlockTable + dwMaxBlockIndex + 1; + TMPQBlock * pBlock = ha->pBlockTable; + + // If the MPQ file is not protected, + // we will check if all sizes in the block table is correct. + // Note that we will not relocate the block table (change from previous versions) + for(; pBlock < pBlockEnd; pBlock++, pBlockEx++) + { + if(pBlock->dwFlags & MPQ_FILE_EXISTS) + { + // Get the 64-bit file position + TempPos.HighPart = pBlockEx->wFilePosHigh; + TempPos.LowPart = pBlock->dwFilePos; + + if(TempPos.QuadPart > ha->MpqSize.QuadPart || pBlock->dwCSize > ha->MpqSize.QuadPart) + { + nError = ERROR_BAD_FORMAT; + break; + } + } + } + } + + // If the user didn't specified otherwise, + // include the internal listfile to the TMPQArchive structure + if((dwFlags & MPQ_OPEN_NO_LISTFILE) == 0) + { + if(nError == ERROR_SUCCESS) + SListFileCreateListFile(ha); + + // Add the internal listfile + if(nError == ERROR_SUCCESS) + SFileAddListFile((HANDLE)ha, NULL); + } + + // Cleanup and exit + if(nError != ERROR_SUCCESS) + { + FreeMPQArchive(ha); + if(hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + SetLastError(nError); + } + else + { + if(pFirstOpen == NULL) + pFirstOpen = ha; + } + *phMPQ = ha; + return (nError == ERROR_SUCCESS); +} + +BOOL WINAPI SFileOpenArchive(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMPQ) +{ + return SFileOpenArchiveEx(szMpqName, dwPriority, dwFlags, phMPQ, GENERIC_READ); +} + +//----------------------------------------------------------------------------- +// BOOL SFileCloseArchive(HANDLE hMPQ); +// + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileCloseArchive(HANDLE hMPQ) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + + if(!IsValidMpqHandle(ha)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if(ha->dwFlags & MPQ_FLAG_CHANGED) + { + SListFileSaveToMpq(ha); + SaveMPQTables(ha); + } + FreeMPQArchive(ha); + return TRUE; +} + diff --git a/contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp b/contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp new file mode 100644 index 000000000..dae312144 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp @@ -0,0 +1,403 @@ +/*****************************************************************************/ +/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +/*****************************************************************************/ +/* Local functions */ +/*****************************************************************************/ + +// TODO: Test for archives > 4GB +static BOOL OpenLocalFile(const char * szFileName, HANDLE * phFile) +{ + TMPQFile * hf = NULL; + HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + + if(hFile != INVALID_HANDLE_VALUE) + { + // Allocate and initialize file handle + size_t nHandleSize = sizeof(TMPQFile) + strlen(szFileName); + if((hf = (TMPQFile *)ALLOCMEM(char, nHandleSize)) != NULL) + { + memset(hf, 0, nHandleSize); + strcpy(hf->szFileName, szFileName); + hf->hFile = hFile; + *phFile = hf; + return TRUE; + } + else + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + *phFile = NULL; + return FALSE; +} + +// TODO: Test for archives > 4GB +static void FreeMPQFile(TMPQFile *& hf) +{ + if(hf != NULL) + { + if(hf->hFile != INVALID_HANDLE_VALUE) + CloseHandle(hf->hFile); + if(hf->pdwBlockPos != NULL) + FREEMEM(hf->pdwBlockPos); + if(hf->pbFileBuffer != NULL) + FREEMEM(hf->pbFileBuffer); + FREEMEM(hf); + hf = NULL; + } +} + +/*****************************************************************************/ +/* Public functions */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// SFileEnumLocales enums all locale versions within MPQ. +// Functions fills all available language identifiers on a file into the buffer +// pointed by plcLocales. There must be enough entries to copy the localed, +// otherwise the function returns ERROR_INSUFFICIENT_BUFFER. + +// TODO: Test for archives > 4GB +int WINAPI SFileEnumLocales( + HANDLE hMPQ, + const char * szFileName, + LCID * plcLocales, + DWORD * pdwMaxLocales, + DWORD dwSearchScope) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + TMPQHash * pHash = NULL; + TMPQHash * pHashEnd = NULL; + DWORD dwLocales = 0; + int nError = ERROR_SUCCESS; + + // Test the parameters + if(nError == ERROR_SUCCESS) + { + if(!IsValidMpqHandle(ha) || pdwMaxLocales == NULL) + nError = ERROR_INVALID_PARAMETER; + if(dwSearchScope == SFILE_OPEN_BY_INDEX && (DWORD_PTR)szFileName > ha->pHeader->dwBlockTableSize) + nError = ERROR_INVALID_PARAMETER; + if(dwSearchScope != SFILE_OPEN_BY_INDEX && *szFileName == 0) + nError = ERROR_INVALID_PARAMETER; + } + + // Retrieve the hash entry for the required file + if(nError == ERROR_SUCCESS) + { + pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + + if(dwSearchScope == SFILE_OPEN_BY_INDEX) + { + for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++) + { + if(pHash->dwBlockIndex == (DWORD_PTR)szFileName) + break; + } + if(pHash == pHashEnd) + pHash = NULL; + } + else + pHash = GetHashEntry(ha, szFileName); + } + + // If the file was not found, sorry + if(nError == ERROR_SUCCESS) + { + if(pHash == NULL) + nError = ERROR_FILE_NOT_FOUND; + } + + // Count the entries which correspond to the same file name + if(nError == ERROR_SUCCESS) + { + TMPQHash * pSaveHash = pHash; + DWORD dwName1 = pHash->dwName1; + DWORD dwName2 = pHash->dwName2; + + // For nameless access, return 1 locale always + if(dwSearchScope == SFILE_OPEN_BY_INDEX) + dwLocales++; + else + { + while(pHash < pHashEnd && pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2) + { + dwLocales++; + pHash++; + } + } + + pHash = pSaveHash; + } + + // Test if there is enough space to copy the locales + if(nError == ERROR_SUCCESS) + { + DWORD dwMaxLocales = *pdwMaxLocales; + + *pdwMaxLocales = dwLocales; + if(dwMaxLocales < dwLocales) + nError = ERROR_INSUFFICIENT_BUFFER; + } + + // Fill all the locales + if(nError == ERROR_SUCCESS) + { + for(DWORD i = 0; i < dwLocales; i++, pHash++) + *plcLocales++ = (LCID)pHash->lcLocale; + } + return nError; +} + +//----------------------------------------------------------------------------- +// SFileHasFile +// +// hMPQ - Handle of opened MPQ archive +// szFileName - Name of file to look for + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileHasFile(HANDLE hMPQ, char * szFileName) +{ + TMPQArchive * ha = (TMPQArchive *)hMPQ; + int nError = ERROR_SUCCESS; + + if(nError == ERROR_SUCCESS) + { + if(ha == NULL) + nError = ERROR_INVALID_PARAMETER; + if(*szFileName == 0) + nError = ERROR_INVALID_PARAMETER; + } + + // Prepare the file opening + if(nError == ERROR_SUCCESS) + { + if(GetHashEntryEx(ha, szFileName, lcLocale) == NULL) + { + nError = ERROR_FILE_NOT_FOUND; + } + } + + // Cleanup + if(nError != ERROR_SUCCESS) + { + SetLastError(nError); + } + + return (nError == ERROR_SUCCESS); +} + + +//----------------------------------------------------------------------------- +// SFileOpenFileEx +// +// hMPQ - Handle of opened MPQ archive +// szFileName - Name of file to open +// dwSearchScope - Where to search +// phFile - Pointer to store opened file handle + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileOpenFileEx(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile) +{ + LARGE_INTEGER FilePos; + TMPQArchive * ha = (TMPQArchive *)hMPQ; + TMPQFile * hf = NULL; + TMPQHash * pHash = NULL; // Hash table index + TMPQBlock * pBlock = NULL; // File block + TMPQBlockEx * pBlockEx = NULL; + DWORD dwHashIndex = 0; // Hash table index + DWORD dwBlockIndex = (DWORD)-1; // Found table index + size_t nHandleSize = 0; // Memory space necessary to allocate TMPQHandle + int nError = ERROR_SUCCESS; + +#ifdef _DEBUG + // Due to increasing numbers of files in MPQs, I had to change the behavior + // of opening by file index. Now, the SFILE_OPEN_BY_INDEX value of dwSearchScope + // must be entered. This check will allow to find code places that are incompatible + // with the new behavior. + if(dwSearchScope != SFILE_OPEN_BY_INDEX && szFileName != NULL) + { + assert((DWORD_PTR)szFileName > 0x10000); + } +#endif + + if(nError == ERROR_SUCCESS) + { + if(ha == NULL && dwSearchScope == SFILE_OPEN_FROM_MPQ) + nError = ERROR_INVALID_PARAMETER; + if(phFile == NULL) + nError = ERROR_INVALID_PARAMETER; + if(dwSearchScope == SFILE_OPEN_BY_INDEX && (DWORD_PTR)szFileName > ha->pHeader->dwBlockTableSize) + nError = ERROR_INVALID_PARAMETER; + if(dwSearchScope != SFILE_OPEN_BY_INDEX && (szFileName == NULL || *szFileName == 0)) + nError = ERROR_INVALID_PARAMETER; + } + + // Prepare the file opening + if(nError == ERROR_SUCCESS) + { + // When the file is given by number, ... + if(dwSearchScope == SFILE_OPEN_BY_INDEX) + { + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + + // Set handle size to be sizeof(TMPQFile) + length of FileXXXXXXXX.xxx + nHandleSize = sizeof(TMPQFile) + 20; + for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++) + { + if((DWORD_PTR)szFileName == pHash->dwBlockIndex) + { + dwHashIndex = (DWORD)(pHash - ha->pHashTable); + dwBlockIndex = pHash->dwBlockIndex; + break; + } + } + } + else + { + // If we have to open a disk file + if(dwSearchScope == SFILE_OPEN_LOCAL_FILE) + return OpenLocalFile(szFileName, phFile); + + nHandleSize = sizeof(TMPQFile) + strlen(szFileName); + if((pHash = GetHashEntryEx(ha, szFileName, lcLocale)) != NULL) + { + dwHashIndex = (DWORD)(pHash - ha->pHashTable); + dwBlockIndex = pHash->dwBlockIndex; + } + } + } + + // Get block index from file name and test it + if(nError == ERROR_SUCCESS) + { + // If index was not found, or is greater than number of files, exit. + if(dwBlockIndex == (DWORD)-1 || dwBlockIndex > ha->pHeader->dwBlockTableSize) + nError = ERROR_FILE_NOT_FOUND; + } + + // Get block and test if the file was not already deleted. + if(nError == ERROR_SUCCESS) + { + // Get both block tables and file position + pBlockEx = ha->pExtBlockTable + dwBlockIndex; + pBlock = ha->pBlockTable + dwBlockIndex; + FilePos.HighPart = pBlockEx->wFilePosHigh; + FilePos.LowPart = pBlock->dwFilePos; + + if(FilePos.QuadPart > ha->MpqSize.QuadPart || + pBlock->dwCSize > ha->MpqSize.QuadPart) + nError = ERROR_FILE_CORRUPT; + if((pBlock->dwFlags & MPQ_FILE_EXISTS) == 0) + nError = ERROR_FILE_NOT_FOUND; + if(pBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS) + nError = ERROR_NOT_SUPPORTED; + } + + // Allocate file handle + if(nError == ERROR_SUCCESS) + { + if((hf = (TMPQFile *)ALLOCMEM(char, nHandleSize)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Initialize file handle + if(nError == ERROR_SUCCESS) + { + memset(hf, 0, nHandleSize); + hf->hFile = INVALID_HANDLE_VALUE; + hf->ha = ha; + hf->pBlockEx = pBlockEx; + hf->pBlock = pBlock; + hf->nBlocks = (hf->pBlock->dwFSize + ha->dwBlockSize - 1) / ha->dwBlockSize; + hf->pHash = pHash; + + hf->MpqFilePos.HighPart = pBlockEx->wFilePosHigh; + hf->MpqFilePos.LowPart = pBlock->dwFilePos; + hf->MpqFilePos.QuadPart += ha->MpqPos.QuadPart; + + hf->dwHashIndex = dwHashIndex; + hf->dwFileIndex = dwBlockIndex; + + // Allocate buffers for decompression. + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) + { + // Allocate buffer for block positions. At the begin of file are stored + // DWORDs holding positions of each block relative from begin of file in the archive + // As for newer MPQs, there may be one additional entry in the block table + // (if the MPQ_FILE_HAS_EXTRA flag is set). + // Allocate the buffer to include this DWORD as well + + if((hf->pdwBlockPos = ALLOCMEM(DWORD, hf->nBlocks + 2)) == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + // Decrypt file seed. Cannot be used if the file is given by index + if(dwSearchScope != SFILE_OPEN_BY_INDEX) + { + if(hf->pBlock->dwFlags & MPQ_FILE_ENCRYPTED) + { + const char * szTemp = strrchr(szFileName, '\\'); + + strcpy(hf->szFileName, szFileName); + if(szTemp != NULL) + szFileName = szTemp + 1; + hf->dwSeed1 = DecryptFileSeed((char *)szFileName); + + if(hf->pBlock->dwFlags & MPQ_FILE_FIXSEED) + { + hf->dwSeed1 = (hf->dwSeed1 + hf->pBlock->dwFilePos) ^ hf->pBlock->dwFSize; + } + } + } + else + { + // If the file is encrypted and not compressed, we cannot detect the file seed + if(SFileGetFileName(hf, hf->szFileName) == FALSE) + nError = GetLastError(); + } + } + + // Cleanup + if(nError != ERROR_SUCCESS) + { + FreeMPQFile(hf); + SetLastError(nError); + } + + *phFile = hf; + return (nError == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// BOOL SFileCloseFile(HANDLE hFile); + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileCloseFile(HANDLE hFile) +{ + TMPQFile * hf = (TMPQFile *)hFile; + + if(!IsValidFileHandle(hf)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + // Set the last accessed file in the archive + if(hf->ha != NULL) + hf->ha->pLastFile = NULL; + + // Free the structure + FreeMPQFile(hf); + return TRUE; +} diff --git a/contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp b/contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp new file mode 100644 index 000000000..27fd1e0f0 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp @@ -0,0 +1,826 @@ +/*****************************************************************************/ +/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */ +/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" + +//----------------------------------------------------------------------------- +// Defines + +#define ID_WAVE 0x46464952 // Signature of WAVes for name breaking +#define ID_EXE 0x00005A4D // Signature of executable files + +//----------------------------------------------------------------------------- +// Local structures + +struct TID2Ext +{ + DWORD dwID; + char * szExt; +}; + +//----------------------------------------------------------------------------- +// ReadMPQBlock +// +// hf - MPQ File handle. +// dwBlockPos - Position of block in the file (relative to file begin) +// buffer - Pointer to target buffer to store blocks. +// dwBlockSize - Number of bytes to read. Must be multiplier of block size. +// +// Returns number of bytes read. + +// TODO: Test for archives > 4GB +static DWORD WINAPI ReadMPQBlocks(TMPQFile * hf, DWORD dwBlockPos, BYTE * buffer, DWORD blockBytes) +{ + LARGE_INTEGER FilePos; + TMPQArchive * ha = hf->ha; // Archive handle + BYTE * tempBuffer = NULL; // Buffer for reading compressed data from the file + DWORD dwFilePos = dwBlockPos; // Reading position from the file + DWORD dwToRead; // Number of bytes to read + DWORD blockNum; // Block number (needed for decrypt) + DWORD dwBytesRead = 0; // Total number of bytes read + DWORD bytesRemain = 0; // Number of data bytes remaining up to the end of the file + DWORD nBlocks; // Number of blocks to load + DWORD i; + + // Test parameters. Block position and block size must be block-aligned, block size nonzero + if((dwBlockPos & (ha->dwBlockSize - 1)) || blockBytes == 0) + return 0; + + // Check the end of file + if((dwBlockPos + blockBytes) > hf->pBlock->dwFSize) + blockBytes = hf->pBlock->dwFSize - dwBlockPos; + + bytesRemain = hf->pBlock->dwFSize - dwBlockPos; + blockNum = dwBlockPos / ha->dwBlockSize; + nBlocks = blockBytes / ha->dwBlockSize; + if(blockBytes % ha->dwBlockSize) + nBlocks++; + + // If file has variable block positions, we have to load them + if((hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) && hf->bBlockPosLoaded == FALSE) + { + // Move file pointer to the begin of the file in the MPQ + if(hf->MpqFilePos.QuadPart != ha->FilePointer.QuadPart) + { + SetFilePointer(ha->hFile, hf->MpqFilePos.LowPart, &hf->MpqFilePos.HighPart, FILE_BEGIN); + } + + // Read block positions from begin of file. + dwToRead = (hf->nBlocks+1) * sizeof(DWORD); + if(hf->pBlock->dwFlags & MPQ_FILE_HAS_EXTRA) + dwToRead += sizeof(DWORD); + + // Read the block pos table and convert the buffer to little endian + ReadFile(ha->hFile, hf->pdwBlockPos, dwToRead, &dwBytesRead, NULL); + BSWAP_ARRAY32_UNSIGNED(hf->pdwBlockPos, (hf->nBlocks+1)); + + // + // If the archive if protected some way, perform additional check + // Sometimes, the file appears not to be encrypted, but it is. + // + // Note: In WoW 1.10+, there's a new flag. With this flag present, + // there's one additional entry in the block table. + // + + if(hf->pdwBlockPos[0] != dwBytesRead) + hf->pBlock->dwFlags |= MPQ_FILE_ENCRYPTED; + + // Decrypt loaded block positions if necessary + if(hf->pBlock->dwFlags & MPQ_FILE_ENCRYPTED) + { + // If we don't know the file seed, try to find it. + if(hf->dwSeed1 == 0) + hf->dwSeed1 = DetectFileSeed(hf->pdwBlockPos, dwBytesRead); + + // If we don't know the file seed, sorry but we cannot extract the file. + if(hf->dwSeed1 == 0) + return 0; + + // Decrypt block positions + DecryptMPQBlock(hf->pdwBlockPos, dwBytesRead, hf->dwSeed1 - 1); + + // Check if the block positions are correctly decrypted + // I don't know why, but sometimes it will result invalid block positions on some files + if(hf->pdwBlockPos[0] != dwBytesRead) + { + // Try once again to detect file seed and decrypt the blocks + // TODO: Test with >4GB + SetFilePointer(ha->hFile, hf->MpqFilePos.LowPart, &hf->MpqFilePos.HighPart, FILE_BEGIN); + ReadFile(ha->hFile, hf->pdwBlockPos, dwToRead, &dwBytesRead, NULL); + + BSWAP_ARRAY32_UNSIGNED(hf->pdwBlockPos, (hf->nBlocks+1)); + hf->dwSeed1 = DetectFileSeed(hf->pdwBlockPos, dwBytesRead); + DecryptMPQBlock(hf->pdwBlockPos, dwBytesRead, hf->dwSeed1 - 1); + + // Check if the block positions are correctly decrypted + if(hf->pdwBlockPos[0] != dwBytesRead) + return 0; + } + } + + // Update hf's variables + ha->FilePointer.QuadPart = hf->MpqFilePos.QuadPart + dwBytesRead; + hf->bBlockPosLoaded = TRUE; + } + + // Get file position and number of bytes to read + dwFilePos = dwBlockPos; + dwToRead = blockBytes; + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) + { + dwFilePos = hf->pdwBlockPos[blockNum]; + dwToRead = hf->pdwBlockPos[blockNum + nBlocks] - dwFilePos; + } + FilePos.QuadPart = hf->MpqFilePos.QuadPart + dwFilePos; + + // Get work buffer for store read data + tempBuffer = buffer; + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) + { + if((tempBuffer = ALLOCMEM(BYTE, dwToRead)) == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + + // Set file pointer, if necessary + if(ha->FilePointer.QuadPart != FilePos.QuadPart) + { + SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN); + } + + // 15018F87 : Read all requested blocks + ReadFile(ha->hFile, tempBuffer, dwToRead, &dwBytesRead, NULL); + ha->FilePointer.QuadPart = FilePos.QuadPart + dwBytesRead; + + // Block processing part. + DWORD blockStart = 0; // Index of block start in work buffer + DWORD blockSize = min(blockBytes, ha->dwBlockSize); + DWORD index = blockNum; // Current block index + + dwBytesRead = 0; // Clear read byte counter + + // Walk through all blocks + for(i = 0; i < nBlocks; i++, index++) + { + BYTE * inputBuffer = tempBuffer + blockStart; + int outLength = ha->dwBlockSize; + + if(bytesRemain < (DWORD)outLength) + outLength = bytesRemain; + + // Get current block length + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) + blockSize = hf->pdwBlockPos[index+1] - hf->pdwBlockPos[index]; + + // If block is encrypted, we have to decrypt it. + if(hf->pBlock->dwFlags & MPQ_FILE_ENCRYPTED) + { + BSWAP_ARRAY32_UNSIGNED((DWORD *)inputBuffer, blockSize / sizeof(DWORD)); + + // If we don't know the seed, try to decode it as WAVE file + if(hf->dwSeed1 == 0) + hf->dwSeed1 = DetectFileSeed2((DWORD *)inputBuffer, 3, ID_WAVE, hf->pBlock->dwFSize - 8, 0x45564157); + + // Let's try MSVC's standard EXE or header + if(hf->dwSeed1 == 0) + hf->dwSeed1 = DetectFileSeed2((DWORD *)inputBuffer, 2, 0x00905A4D, 0x00000003); + + if(hf->dwSeed1 == 0) + return 0; + + DecryptMPQBlock((DWORD *)inputBuffer, blockSize, hf->dwSeed1 + index); + BSWAP_ARRAY32_UNSIGNED((DWORD *)inputBuffer, blockSize / sizeof(DWORD)); + } + + // If the block is really compressed, decompress it. + // WARNING : Some block may not be compressed, it can be determined only + // by comparing uncompressed and compressed size !!! + if(blockSize < (DWORD)outLength) + { + // Is the file compressed with PKWARE Data Compression Library ? + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_PKWARE) + Decompress_pklib((char *)buffer, &outLength, (char *)inputBuffer, (int)blockSize); + + // Is it a file compressed by Blizzard's multiple compression ? + // Note that Storm.dll v 1.0.9 distributed with Warcraft III + // passes the full path name of the opened archive as the new last parameter + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_MULTI) + SCompDecompress((char *)buffer, &outLength, (char *)inputBuffer, (int)blockSize); + dwBytesRead += outLength; + buffer += outLength; + } + else + { + if(buffer != inputBuffer) + memcpy(buffer, inputBuffer, blockSize); + + dwBytesRead += blockSize; + buffer += blockSize; + } + blockStart += blockSize; + bytesRemain -= outLength; + } + + // Delete input buffer, if necessary + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) + FREEMEM(tempBuffer); + + return dwBytesRead; +} + +// When this function is called, it is already ensured that the parameters are valid +// (e.g. the "dwToRead + dwFilePos" is not greater than the file size) +// TODO: Test for archives > 4GB +static DWORD WINAPI ReadMPQFileSingleUnit(TMPQFile * hf, DWORD dwFilePos, BYTE * pbBuffer, DWORD dwToRead) +{ + TMPQArchive * ha = hf->ha; + DWORD dwBytesRead = 0; + + if(ha->FilePointer.QuadPart != hf->MpqFilePos.QuadPart) + { + SetFilePointer(ha->hFile, hf->MpqFilePos.LowPart, &hf->MpqFilePos.HighPart, FILE_BEGIN); + ha->FilePointer = hf->MpqFilePos; + } + + // If the file is really compressed, decompress it. + // Otherwise, read the data as-is to the caller. + if(hf->pBlock->dwCSize < hf->pBlock->dwFSize) + { + if(hf->pbFileBuffer == NULL) + { + BYTE * inputBuffer = NULL; + int outputBufferSize = (int)hf->pBlock->dwFSize; + int inputBufferSize = (int)hf->pBlock->dwCSize; + + hf->pbFileBuffer = ALLOCMEM(BYTE, outputBufferSize); + inputBuffer = ALLOCMEM(BYTE, inputBufferSize); + if(inputBuffer != NULL && hf->pbFileBuffer != NULL) + { + // Read the compressed file data + ReadFile(ha->hFile, inputBuffer, inputBufferSize, &dwBytesRead, NULL); + + // Is the file compressed with PKWARE Data Compression Library ? + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_PKWARE) + Decompress_pklib((char *)hf->pbFileBuffer, &outputBufferSize, (char *)inputBuffer, (int)inputBufferSize); + + // Is it a file compressed by Blizzard's multiple compression ? + // Note that Storm.dll v 1.0.9 distributed with Warcraft III + // passes the full path name of the opened archive as the new last parameter + if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_MULTI) + SCompDecompress((char *)hf->pbFileBuffer, &outputBufferSize, (char *)inputBuffer, (int)inputBufferSize); + } + + // Free the temporary buffer + if(inputBuffer != NULL) + FREEMEM(inputBuffer); + } + + // Copy the file data, if any there + if(hf->pbFileBuffer != NULL) + { + memcpy(pbBuffer, hf->pbFileBuffer + dwFilePos, dwToRead); + dwBytesRead += dwToRead; + } + } + else + { + // Read the uncompressed file data + ReadFile(ha->hFile, pbBuffer, dwToRead, &dwBytesRead, NULL); + dwBytesRead = (int)dwBytesRead; + } + + return (DWORD)dwBytesRead; +} + + +//----------------------------------------------------------------------------- +// ReadMPQFile + +// TODO: Test for archives > 4GB +static DWORD WINAPI ReadMPQFile(TMPQFile * hf, DWORD dwFilePos, BYTE * pbBuffer, DWORD dwToRead) +{ + TMPQArchive * ha = hf->ha; + TMPQBlock * pBlock = hf->pBlock; // Pointer to file block + DWORD dwBytesRead = 0; // Number of bytes read from the file + DWORD dwBlockPos; // Position in the file aligned to the whole blocks + DWORD dwLoaded; + + // File position is greater or equal to file size ? + if(dwFilePos >= pBlock->dwFSize) + return dwBytesRead; + + // If too few bytes in the file remaining, cut them + if((pBlock->dwFSize - dwFilePos) < dwToRead) + dwToRead = (pBlock->dwFSize - dwFilePos); + + // If the file is stored as single unit, handle it separately + if(pBlock->dwFlags & MPQ_FILE_SINGLE_UNIT) + return ReadMPQFileSingleUnit(hf, dwFilePos, pbBuffer, dwToRead); + + // Block position in the file + dwBlockPos = dwFilePos & ~(ha->dwBlockSize - 1); // Position in the block + + // Load the first block, if incomplete. It may be loaded in the cache buffer. + // We have to check if this block is loaded. If not, load it. + if((dwFilePos % ha->dwBlockSize) != 0) + { + // Number of bytes remaining in the buffer + DWORD dwToCopy; + DWORD dwLoaded = ha->dwBlockSize; + + // Check if data are loaded in the cache + if(hf != ha->pLastFile || dwBlockPos != ha->dwBlockPos) + { + // Load one MPQ block into archive buffer + dwLoaded = ReadMPQBlocks(hf, dwBlockPos, ha->pbBlockBuffer, ha->dwBlockSize); + if(dwLoaded == 0) + return (DWORD)-1; + + // Save lastly accessed file and block position for later use + ha->pLastFile = hf; + ha->dwBlockPos = dwBlockPos; + ha->dwBuffPos = dwFilePos % ha->dwBlockSize; + } + dwToCopy = dwLoaded - ha->dwBuffPos; + if(dwToCopy > dwToRead) + dwToCopy = dwToRead; + + // Copy data from block buffer into target buffer + memcpy(pbBuffer, ha->pbBlockBuffer + ha->dwBuffPos, dwToCopy); + + // Update pointers + dwToRead -= dwToCopy; + dwBytesRead += dwToCopy; + pbBuffer += dwToCopy; + dwBlockPos += ha->dwBlockSize; + ha->dwBuffPos += dwToCopy; + + // If all, return. + if(dwToRead == 0) + return dwBytesRead; + } + + // Load the whole ("middle") blocks only if there are more or equal one block + if(dwToRead > ha->dwBlockSize) + { + DWORD dwBlockBytes = dwToRead & ~(ha->dwBlockSize - 1); + + dwLoaded = ReadMPQBlocks(hf, dwBlockPos, pbBuffer, dwBlockBytes); + if(dwLoaded == 0) + return (DWORD)-1; + + // Update pointers + dwToRead -= dwLoaded; + dwBytesRead += dwLoaded; + pbBuffer += dwLoaded; + dwBlockPos += dwLoaded; + + // If all, return. + if(dwToRead == 0) + return dwBytesRead; + } + + // Load the terminating block + if(dwToRead > 0) + { + DWORD dwToCopy = ha->dwBlockSize; + + // Check if data are loaded in the cache + if(hf != ha->pLastFile || dwBlockPos != ha->dwBlockPos) + { + // Load one MPQ block into archive buffer + dwToCopy = ReadMPQBlocks(hf, dwBlockPos, ha->pbBlockBuffer, ha->dwBlockSize); + if(dwToCopy == 0) + return (DWORD)-1; + + // Save lastly accessed file and block position for later use + ha->pLastFile = hf; + ha->dwBlockPos = dwBlockPos; + } + ha->dwBuffPos = 0; + + // Check number of bytes read + if(dwToCopy > dwToRead) + dwToCopy = dwToRead; + + memcpy(pbBuffer, ha->pbBlockBuffer, dwToCopy); + dwBytesRead += dwToCopy; + ha->dwBuffPos = dwToCopy; + } + + // Return what we've read + return dwBytesRead; +} + +//----------------------------------------------------------------------------- +// SFileReadFile + +// TODO: Test for archives > 4GB +BOOL WINAPI SFileReadFile(HANDLE hFile, VOID * lpBuffer, DWORD dwToRead, DWORD * pdwRead, LPOVERLAPPED lpOverlapped) +{ + TMPQFile * hf = (TMPQFile *)hFile; + DWORD dwBytes = 0; // Number of bytes (for everything) + int nError = ERROR_SUCCESS; + + // Zero the number of bytes read + if(pdwRead != NULL) + *pdwRead = 0; + + // Check valid parameters + if(nError == ERROR_SUCCESS) + { + if(hf == NULL || lpBuffer == NULL) + nError = ERROR_INVALID_PARAMETER; + } + + // If direct access to the file, use Win32 for reading + if(nError == ERROR_SUCCESS && hf->hFile != INVALID_HANDLE_VALUE) + { + DWORD dwTransferred; + + ReadFile(hf->hFile, lpBuffer, dwToRead, &dwTransferred, lpOverlapped); + if(dwTransferred < dwToRead) + { + SetLastError(ERROR_HANDLE_EOF); + return FALSE; + } + + if(pdwRead != NULL) + *pdwRead = dwTransferred; + return TRUE; + } + + // Read all the bytes available in the buffer (If any) + if(nError == ERROR_SUCCESS) + { + if(dwToRead > 0) + { + dwBytes = ReadMPQFile(hf, hf->dwFilePos, (BYTE *)lpBuffer, dwToRead); + if(dwBytes == (DWORD)-1) + { + SetLastError(ERROR_CAN_NOT_COMPLETE); + return FALSE; + } + hf->ha->pLastFile = hf; + hf->dwFilePos += dwBytes; + } + if(pdwRead != NULL) + *pdwRead = dwBytes; + } + + // Check number of bytes read. If not OK, return FALSE. + if(dwBytes < dwToRead) + { + SetLastError(ERROR_HANDLE_EOF); + return FALSE; + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// SFileGetFilePos +// +// Returns position of archive file in the archive (relative to begin of file) + +// TODO: Test for archives > 4GB +DWORD WINAPI SFileGetFilePos(HANDLE hFile, DWORD * pdwFilePosHigh) +{ + TMPQFile * hf = (TMPQFile *)hFile; + + if(pdwFilePosHigh != NULL) + *pdwFilePosHigh = 0; + + if(hf == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return (DWORD)-1; + } + + // If opened as plain file, ... + if(hf->hFile != INVALID_HANDLE_VALUE) + return 0; + + // If opened from archive, return file size + if(pdwFilePosHigh != NULL) + *pdwFilePosHigh = hf->MpqFilePos.HighPart; + return hf->MpqFilePos.LowPart; +} + +//----------------------------------------------------------------------------- +// SFileGetFileSize + +// TODO: Test for archives > 4GB +DWORD WINAPI SFileGetFileSize(HANDLE hFile, DWORD * pdwFileSizeHigh) +{ + TMPQFile * hf = (TMPQFile *)hFile; + + if(pdwFileSizeHigh != NULL) + *pdwFileSizeHigh = 0; + + if(hf == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return (DWORD)-1; + } + + // If opened as plain file, ... + if(hf->hFile != INVALID_HANDLE_VALUE) + return GetFileSize(hf->hFile, pdwFileSizeHigh); + + // If opened from archive, return file size + return hf->pBlock->dwFSize; +} + +// TODO: Test for archives > 4GB +DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * pdwFilePosHigh, DWORD dwMethod) +{ + TMPQArchive * ha; + TMPQFile * hf = (TMPQFile *)hFile; + + if(hf == NULL || (pdwFilePosHigh != NULL && *pdwFilePosHigh != 0)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return (DWORD)-1; + } + + // If opened as plain file, call Win32 API + if(hf->hFile != INVALID_HANDLE_VALUE) + return SetFilePointer(hf->hFile, lFilePos, pdwFilePosHigh, dwMethod); + ha = hf->ha; + + switch(dwMethod) + { + case FILE_BEGIN: + // Cannot set pointer before begin of file + if(-lFilePos > (LONG)hf->dwFilePos) + hf->dwFilePos = 0; + else + hf->dwFilePos = lFilePos; + break; + + case FILE_CURRENT: + // Cannot set pointer before begin of file + if(-lFilePos > (LONG)hf->dwFilePos) + hf->dwFilePos = 0; + else + hf->dwFilePos += lFilePos; + break; + + case FILE_END: + // Cannot set file position before begin of file + if(-lFilePos >= (LONG)hf->pBlock->dwFSize) + hf->dwFilePos = 0; + else + hf->dwFilePos = hf->pBlock->dwFSize + lFilePos; + break; + + default: + return ERROR_INVALID_PARAMETER; + } + + if(hf == ha->pLastFile && (hf->dwFilePos & ~(ha->dwBlockSize - 1)) == ha->dwBlockPos) + ha->dwBuffPos = hf->dwFilePos & (ha->dwBlockSize - 1); + else + { + ha->pLastFile = NULL; + ha->dwBuffPos = 0; + } + + return hf->dwFilePos; +} + +//----------------------------------------------------------------------------- +// Tries to retrieve the file name + +static TID2Ext id2ext[] = +{ + {0x1A51504D, "mpq"}, // MPQ archive header ID ('MPQ\x1A') + {0x46464952, "wav"}, // WAVE header 'RIFF' + {0x324B4D53, "smk"}, // Old "Smacker Video" files 'SMK2' + {0x694B4942, "bik"}, // Bink video files (new) + {0x0801050A, "pcx"}, // PCX images used in Diablo I + {0x544E4F46, "fnt"}, // Font files used in Diablo II + {0x6D74683C, "html"}, // HTML ' 4GB +BOOL WINAPI SFileGetFileName(HANDLE hFile, char * szFileName) +{ + TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle + char * szExt = "xxx"; // Default extension + DWORD dwFirstBytes[2]; // The first 4 bytes of the file + DWORD dwFilePos; // Saved file position + int nError = ERROR_SUCCESS; + int i; + + // Pre-zero the output buffer + if(szFileName != NULL) + *szFileName = 0; + + // Check valid parameters + if(nError == ERROR_SUCCESS) + { + if(hf == NULL || szFileName == NULL) + nError = ERROR_INVALID_PARAMETER; + } + + // If the file name is already filled, return it. + if(nError == ERROR_SUCCESS && *hf->szFileName != 0) + { + if(szFileName != hf->szFileName) + strcpy(szFileName, hf->szFileName); + return TRUE; + } + + if(nError == ERROR_SUCCESS) + { + if(hf->dwFileIndex == (DWORD)-1) + nError = ERROR_CAN_NOT_COMPLETE; + } + + // Read the first 8 bytes from the file + if(nError == ERROR_SUCCESS) + { + dwFirstBytes[0] = dwFirstBytes[1] = 0; + dwFilePos = SFileSetFilePointer(hf, 0, NULL, FILE_CURRENT); + if(!SFileReadFile(hFile, &dwFirstBytes, sizeof(dwFirstBytes), NULL)) + nError = GetLastError(); + BSWAP_ARRAY32_UNSIGNED(dwFirstBytes, sizeof(dwFirstBytes) / sizeof(DWORD)); + SFileSetFilePointer(hf, dwFilePos, NULL, FILE_BEGIN); + } + + if(nError == ERROR_SUCCESS) + { + if((dwFirstBytes[0] & 0x0000FFFF) == ID_EXE) + szExt = "exe"; + else if(dwFirstBytes[0] == 0x00000006 && dwFirstBytes[1] == 0x00000001) + szExt = "dc6"; + else + { + for(i = 0; id2ext[i].szExt != NULL; i++) + { + if(id2ext[i].dwID == dwFirstBytes[0]) + { + szExt = id2ext[i].szExt; + break; + } + } + } + + // Create the file name + sprintf(hf->szFileName, "File%08lu.%s", hf->dwFileIndex, szExt); + if(szFileName != hf->szFileName) + strcpy(szFileName, hf->szFileName); + } + return (nError == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// Retrieves an information about an archive or about a file within the archive +// +// hMpqOrFile - Handle to an MPQ archive or to a file +// dwInfoType - Information to obtain + +// TODO: Test for archives > 4GB +DWORD_PTR WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType) +{ + TMPQArchive * ha = (TMPQArchive *)hMpqOrFile; + TMPQFile * hf = (TMPQFile *)hMpqOrFile; + TMPQBlock * pBlockEnd; + TMPQBlock * pBlock; + DWORD dwFileCount = 0; + DWORD dwSeed; + + switch(dwInfoType) + { + case SFILE_INFO_ARCHIVE_SIZE: + if(IsValidMpqHandle(ha)) + return ha->pHeader->dwArchiveSize; + break; + + case SFILE_INFO_HASH_TABLE_SIZE: // Size of the hash table + if(IsValidMpqHandle(ha)) + return ha->pHeader->dwHashTableSize; + break; + + case SFILE_INFO_BLOCK_TABLE_SIZE: // Size of the hash table + if(IsValidMpqHandle(ha)) + return ha->pHeader->dwBlockTableSize; + break; + + case SFILE_INFO_BLOCK_SIZE: + if(IsValidMpqHandle(ha)) + return ha->dwBlockSize; + break; + + case SFILE_INFO_HASH_TABLE: + if(IsValidMpqHandle(ha)) + return (DWORD_PTR)ha->pHashTable; + break; + + case SFILE_INFO_BLOCK_TABLE: + if(IsValidMpqHandle(ha)) + return (DWORD_PTR)ha->pBlockTable; + break; + + case SFILE_INFO_NUM_FILES: + if(IsValidMpqHandle(ha)) + { + pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize; + for(pBlock = ha->pBlockTable; pBlock < pBlockEnd; pBlock++) + { + if(pBlock->dwFlags & MPQ_FILE_EXISTS) + dwFileCount++; + } + return dwFileCount; + } + break; + + case SFILE_INFO_HASH_INDEX: + if(IsValidFileHandle(hf)) + return hf->dwHashIndex; + break; + + case SFILE_INFO_CODENAME1: + if(IsValidFileHandle(hf)) + return hf->pHash->dwName1; + break; + + case SFILE_INFO_CODENAME2: + if(IsValidFileHandle(hf)) + return hf->pHash->dwName2; + break; + + case SFILE_INFO_LOCALEID: + if(IsValidFileHandle(hf)) + return hf->pHash->lcLocale; + break; + + case SFILE_INFO_BLOCKINDEX: + if(IsValidFileHandle(hf)) + return hf->dwFileIndex; + break; + + case SFILE_INFO_FILE_SIZE: + if(IsValidFileHandle(hf)) + return hf->pBlock->dwFSize; + break; + + case SFILE_INFO_COMPRESSED_SIZE: + if(IsValidFileHandle(hf)) + return hf->pBlock->dwCSize; + break; + + case SFILE_INFO_FLAGS: + if(IsValidFileHandle(hf)) + return hf->pBlock->dwFlags; + break; + + case SFILE_INFO_POSITION: + if(IsValidFileHandle(hf)) + return hf->pBlock->dwFilePos; + break; + + case SFILE_INFO_SEED: + if(IsValidFileHandle(hf)) + return hf->dwSeed1; + break; + + case SFILE_INFO_SEED_UNFIXED: + if(IsValidFileHandle(hf)) + { + dwSeed = hf->dwSeed1; + if(hf->pBlock->dwFlags & MPQ_FILE_FIXSEED) + dwSeed = (dwSeed ^ hf->pBlock->dwFSize) - (DWORD)(hf->MpqFilePos.QuadPart - hf->ha->MpqPos.QuadPart); + return dwSeed; + } + break; + } + + // Unknown parameter or invalid handle + SetLastError(ERROR_INVALID_PARAMETER); + return 0xFFFFFFFF; +} diff --git a/contrib/vmap_extractor_v2/stormlib/SListFile.cpp b/contrib/vmap_extractor_v2/stormlib/SListFile.cpp new file mode 100644 index 000000000..c3723d17d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/SListFile.cpp @@ -0,0 +1,561 @@ +/*****************************************************************************/ +/* SListFile.cpp Copyright (c) Ladislav Zezula 2004 */ +/*---------------------------------------------------------------------------*/ +/* Description: */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 12.06.04 1.00 Lad The first version of SListFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "SCommon.h" +#include + +//----------------------------------------------------------------------------- +// Listfile entry structure + +#define LISTFILE_CACHE_SIZE 0x1000 // Size of one cache element +#define NO_MORE_CHARACTERS 256 +#define HASH_TABLE_SIZE 31 // Initial hash table size (should be a prime number) + +// TODO: Check on x64 !!! +#define LISTFILE_ENTRY_DELETED (DWORD_PTR)(-2) +#define LISTFILE_ENTRY_FREE (DWORD_PTR)(-1) + +struct TListFileCache +{ + HANDLE hFile; // Stormlib file handle + char * szMask; // File mask + DWORD dwFileSize; // Total size of the cached file + DWORD dwBuffSize; // File of the cache + DWORD dwFilePos; // Position of the cache in the file + BYTE * pBegin; // The begin of the listfile cache + BYTE * pPos; + BYTE * pEnd; // The last character in the file cache + + BYTE Buffer[1]; // Listfile cache itself +}; + +//----------------------------------------------------------------------------- +// Local functions (cache) + +// Reloads the cache. Returns number of characters +// that has been loaded into the cache. +static int ReloadCache(TListFileCache * pCache) +{ + // Check if there is enough characters in the cache + // If not, we have to reload the next block + if(pCache->pPos >= pCache->pEnd) + { + // If the cache is already at the end, do nothing more + if((pCache->dwFilePos + pCache->dwBuffSize) >= pCache->dwFileSize) + return 0; + + pCache->dwFilePos += pCache->dwBuffSize; + SFileReadFile(pCache->hFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL); + if(pCache->dwBuffSize == 0) + return 0; + + // Set the buffer pointers + pCache->pBegin = + pCache->pPos = &pCache->Buffer[0]; + pCache->pEnd = pCache->pBegin + pCache->dwBuffSize; + } + + return pCache->dwBuffSize; +} + +static size_t ReadLine(TListFileCache * pCache, char * szLine, int nMaxChars) +{ + char * szLineBegin = szLine; + char * szLineEnd = szLine + nMaxChars - 1; + +__BeginLoading: + + // Skip newlines, spaces, tabs and another non-printable stuff + while(pCache->pPos < pCache->pEnd && *pCache->pPos <= 0x20) + pCache->pPos++; + + // Copy the remaining characters + while(pCache->pPos < pCache->pEnd && szLine < szLineEnd) + { + // If we have found a newline, stop loading + if(*pCache->pPos == 0x0D || *pCache->pPos == 0x0A) + break; + + *szLine++ = *pCache->pPos++; + } + + // If we now need to reload the cache, do it + if(pCache->pPos == pCache->pEnd) + { + if(ReloadCache(pCache) > 0) + goto __BeginLoading; + } + + *szLine = 0; + return (szLine - szLineBegin); +} + +//----------------------------------------------------------------------------- +// Local functions (listfile nodes) + +// This function creates the name for the listfile. +// the file will be created under unique name in the temporary directory +static void GetListFileName(TMPQArchive * /* ha */, char * szListFile) +{ + char szTemp[MAX_PATH]; + + // Create temporary file name int TEMP directory + GetTempPath(sizeof(szTemp)-1, szTemp); + GetTempFileName(szTemp, LISTFILE_NAME, 0, szListFile); +} + +// Creates new listfile. The listfile is an array of TListFileNode +// structures. The size of the array is the same like the hash table size, +// the ordering is the same too (listfile item index is the same like +// the index in the MPQ hash table) + +int SListFileCreateListFile(TMPQArchive * ha) +{ + DWORD dwItems = ha->pHeader->dwHashTableSize; + + // The listfile should be NULL now + assert(ha->pListFile == NULL); + + ha->pListFile = ALLOCMEM(TFileNode *, dwItems); + if(ha->pListFile == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + memset(ha->pListFile, 0xFF, dwItems * sizeof(TFileNode *)); + return ERROR_SUCCESS; +} + +// Adds a filename into the listfile. If the file name is already there, +// does nothing. +int SListFileAddNode(TMPQArchive * ha, const char * szFileName) +{ + TFileNode * pNode = NULL; + TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash0 = GetHashEntry(ha, szFileName); + TMPQHash * pHash = pHash0; + DWORD dwHashIndex = 0; + size_t nLength; // File name lentgth + DWORD dwName1; + DWORD dwName2; + + // If the file does not exist within the MPQ, do nothing + if(pHash == NULL) + return ERROR_SUCCESS; + + // If the listfile entry already exists, do nothing + dwHashIndex = (DWORD)(pHash - ha->pHashTable); + dwName1 = pHash->dwName1; + dwName2 = pHash->dwName2; + if((DWORD_PTR)ha->pListFile[dwHashIndex] <= LISTFILE_ENTRY_DELETED) + return ERROR_SUCCESS; + + // Create the listfile node and insert it into the listfile table + nLength = strlen(szFileName); + pNode = (TFileNode *)ALLOCMEM(char, sizeof(TFileNode) + nLength); + pNode->dwRefCount = 0; + pNode->nLength = nLength; + strcpy(pNode->szFileName, szFileName); + + // Fill the nodes for all language versions + while(pHash->dwBlockIndex < LISTFILE_ENTRY_DELETED) + { + if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2) + { + pNode->dwRefCount++; + ha->pListFile[pHash - ha->pHashTable] = pNode; + } + + if(++pHash >= pHashEnd) + pHash = ha->pHashTable; + if(pHash == pHash0) + break; + } + + return ERROR_SUCCESS; +} + +// Removes a filename from the listfile. +// If the name is not there, does nothing +int SListFileRemoveNode(TMPQArchive * ha, const char * szFileName) +{ + TFileNode * pNode = NULL; + TMPQHash * pHash = GetHashEntry(ha, szFileName); + size_t nHashIndex = 0; + + if(pHash != NULL) + { + nHashIndex = pHash - ha->pHashTable; + pNode = ha->pListFile[nHashIndex]; + ha->pListFile[nHashIndex] = (TFileNode *)LISTFILE_ENTRY_DELETED; + + // If the reference count has reached zero, do nothing + if(--pNode->dwRefCount == 0) + FREEMEM(pNode); + } + return ERROR_SUCCESS; +} + + +// Renames a node. We will not deal with the renaming, we'll simply +// remove the old node and insert the new one. +// TODO: Test for archives > 4GB +int SListFileRenameNode(TMPQArchive * ha, const char * szOldFileName, const char * szNewFileName) +{ + SListFileRemoveNode(ha, szOldFileName); + return SListFileAddNode(ha, szNewFileName); +} + +// TODO: Test for archives > 4GB +int SListFileFreeListFile(TMPQArchive * ha) +{ + if(ha->pListFile != NULL) + { + for(DWORD i = 0; i < ha->pHeader->dwHashTableSize; i++) + { + TFileNode * pNode = ha->pListFile[i]; + + if((DWORD_PTR)pNode < LISTFILE_ENTRY_FREE) + { + if(--pNode->dwRefCount == 0) + { + FREEMEM(pNode); + ha->pListFile[i] = (TFileNode *)LISTFILE_ENTRY_FREE; + } + } + } + + FREEMEM(ha->pListFile); + ha->pListFile = NULL; + } + + return ERROR_SUCCESS; +} + +// Saves the whole listfile into the MPQ. +// TODO: Test for archives > 4GB +int SListFileSaveToMpq(TMPQArchive * ha) +{ + TFileNode * pNode = NULL; + TMPQHash * pHashEnd = NULL; + TMPQHash * pHash0 = NULL; + TMPQHash * pHash = NULL; + HANDLE hFile = INVALID_HANDLE_VALUE; + char szListFile[MAX_PATH]; + char szBuffer[MAX_PATH+4]; + DWORD dwTransferred; + size_t nLength = 0; + DWORD dwName1 = 0; + DWORD dwName2 = 0; + LCID lcSave = lcLocale; + int nError = ERROR_SUCCESS; + + // If no listfile, do nothing + if(ha->pListFile == NULL) + return ERROR_SUCCESS; + + // Create the local listfile + if(nError == ERROR_SUCCESS) + { + GetListFileName(ha, szListFile); + hFile = CreateFile(szListFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); + if(hFile == INVALID_HANDLE_VALUE) + nError = GetLastError(); + } + + // Find the hash entry corresponding to listfile + pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + pHash0 = pHash = GetHashEntry(ha, 0); + if(pHash == NULL) + pHash0 = pHash = ha->pHashTable; + + // Save the file + if(nError == ERROR_SUCCESS) + { + for(;;) + { + if(pHash->dwName1 != dwName1 && pHash->dwName2 != dwName2 && pHash->dwBlockIndex < LISTFILE_ENTRY_DELETED) + { + dwName1 = pHash->dwName1; + dwName2 = pHash->dwName2; + pNode = ha->pListFile[pHash - ha->pHashTable]; + + if((DWORD_PTR)pNode < LISTFILE_ENTRY_DELETED) + { + memcpy(szBuffer, pNode->szFileName, pNode->nLength); + szBuffer[pNode->nLength + 0] = 0x0D; + szBuffer[pNode->nLength + 1] = 0x0A; + WriteFile(hFile, szBuffer, (DWORD)(pNode->nLength + 2), &dwTransferred, NULL); + } + } + + if(++pHash >= pHashEnd) + pHash = ha->pHashTable; + if(pHash == pHash0) + break; + } + + // Write the listfile name (if not already there) + if(GetHashEntry(ha, LISTFILE_NAME) == NULL) + { + nLength = strlen(LISTFILE_NAME); + memcpy(szBuffer, LISTFILE_NAME, nLength); + szBuffer[nLength + 0] = 0x0D; + szBuffer[nLength + 1] = 0x0A; + WriteFile(hFile, szBuffer, (DWORD)(nLength + 2), &dwTransferred, NULL); + } + + // Add the listfile into the archive. + SFileSetLocale(LANG_NEUTRAL); + nError = AddFileToArchive(ha, hFile, LISTFILE_NAME, MPQ_FILE_COMPRESS_PKWARE | MPQ_FILE_ENCRYPTED | MPQ_FILE_REPLACEEXISTING, 0, SFILE_TYPE_DATA, NULL); + } + + // Close the temporary file. This will delete it too. + if(hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + + lcLocale = lcSave; + return nError; +} + +//----------------------------------------------------------------------------- +// File functions + +// Adds a listfile into the MPQ archive. +// Note that the function does not remove the +// TODO: Test for archives > 4GB +int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile) +{ + TListFileCache * pCache = NULL; + TMPQArchive * ha = (TMPQArchive *)hMpq; + HANDLE hListFile = NULL; + char szFileName[MAX_PATH + 1]; + DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE; + DWORD dwCacheSize = 0; + DWORD dwFileSize = 0; + size_t nLength = 0; + int nError = ERROR_SUCCESS; + + // If the szListFile is NULL, it means we have to open internal listfile + if(szListFile == NULL) + { + szListFile = LISTFILE_NAME; + dwSearchScope = SFILE_OPEN_FROM_MPQ; + } + + // Open the local/internal listfile + if(nError == ERROR_SUCCESS) + { + if(!SFileOpenFileEx((HANDLE)ha, szListFile, dwSearchScope, &hListFile)) + nError = GetLastError(); + } + + if(nError == ERROR_SUCCESS) + { + dwCacheSize = + dwFileSize = SFileGetFileSize(hListFile, NULL); + + // Try to allocate memory for the complete file. If it fails, + // load the part of the file + pCache = (TListFileCache *)ALLOCMEM(char, (sizeof(TListFileCache) + dwCacheSize)); + if(pCache == NULL) + { + dwCacheSize = LISTFILE_CACHE_SIZE; + pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize); + } + + if(pCache == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + if(nError == ERROR_SUCCESS) + { + // Initialize the file cache + memset(pCache, 0, sizeof(TListFileCache)); + pCache->hFile = hListFile; + pCache->dwFileSize = dwFileSize; + pCache->dwBuffSize = dwCacheSize; + pCache->dwFilePos = 0; + + // Fill the cache + SFileReadFile(hListFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL); + + // Initialize the pointers + pCache->pBegin = + pCache->pPos = &pCache->Buffer[0]; + pCache->pEnd = pCache->pBegin + pCache->dwBuffSize; + + // Load the node tree + while((nLength = ReadLine(pCache, szFileName, sizeof(szFileName) - 1)) > 0) + SListFileAddNode(ha, szFileName); + + // Add well-known names + // Sometimes, they are not in listfile, but they exist in the archive + SListFileAddNode(ha, LISTFILE_NAME); + SListFileAddNode(ha, SIGNATURE_NAME); + SListFileAddNode(ha, ATTRIBUTES_NAME); + } + + // Cleanup & exit + if(pCache != NULL) + SListFileFindClose((HANDLE)pCache); + return nError; +} + +//----------------------------------------------------------------------------- +// Passing through the listfile + +// TODO: Test for archives > 4GB +HANDLE SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData) +{ + TListFileCache * pCache = NULL; + TMPQArchive * ha = (TMPQArchive *)hMpq; + HANDLE hListFile = NULL; + DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE; + DWORD dwCacheSize = 0; + DWORD dwFileSize = 0; + size_t nLength = 0; + int nError = ERROR_SUCCESS; + + // Initialize the structure with zeros + memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); + + // If the szListFile is NULL, it means we have to open internal listfile + if(szListFile == NULL) + { + szListFile = LISTFILE_NAME; + dwSearchScope = SFILE_OPEN_FROM_MPQ; + } + + // Open the local/internal listfile + if(nError == ERROR_SUCCESS) + { + if(!SFileOpenFileEx((HANDLE)ha, szListFile, dwSearchScope, &hListFile)) + nError = GetLastError(); + } + + if(nError == ERROR_SUCCESS) + { + dwCacheSize = + dwFileSize = SFileGetFileSize(hListFile, NULL); + + // Try to allocate memory for the complete file. If it fails, + // load the part of the file + pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize); + if(pCache == NULL) + { + dwCacheSize = LISTFILE_CACHE_SIZE; + pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize); + } + + if(pCache == NULL) + nError = ERROR_NOT_ENOUGH_MEMORY; + } + + if(nError == ERROR_SUCCESS) + { + // Initialize the file cache + memset(pCache, 0, sizeof(TListFileCache)); + pCache->hFile = hListFile; + pCache->dwFileSize = dwFileSize; + pCache->dwBuffSize = dwCacheSize; + pCache->dwFilePos = 0; + if(szMask != NULL) + { + pCache->szMask = ALLOCMEM(char, strlen(szMask) + 1); + strcpy(pCache->szMask, szMask); + } + + // Fill the cache + SFileReadFile(hListFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL); + + // Initialize the pointers + pCache->pBegin = + pCache->pPos = &pCache->Buffer[0]; + pCache->pEnd = pCache->pBegin + pCache->dwBuffSize; + + for(;;) + { + // Read the (next) line + nLength = ReadLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName)); + if(nLength == 0) + { + nError = ERROR_NO_MORE_FILES; + break; + } + + // If some mask entered, check it + if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask)) + break; + } + } + + // Cleanup & exit + if(nError != ERROR_SUCCESS) + { + memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); + SListFileFindClose((HANDLE)pCache); + pCache = NULL; + + SetLastError(nError); + } + return (HANDLE)pCache; +} + +// TODO: Test for archives > 4GB +BOOL SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) +{ + TListFileCache * pCache = (TListFileCache *)hFind; + size_t nLength; + BOOL bResult = FALSE; + int nError = ERROR_SUCCESS; + + for(;;) + { + // Read the (next) line + nLength = ReadLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName)); + if(nLength == 0) + { + nError = ERROR_NO_MORE_FILES; + break; + } + + // If some mask entered, check it + if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask)) + { + bResult = TRUE; + break; + } + } + + if(nError != ERROR_SUCCESS) + SetLastError(nError); + return bResult; +} + +// TODO: Test for archives > 4GB +BOOL SListFileFindClose(HANDLE hFind) +{ + TListFileCache * pCache = (TListFileCache *)hFind; + + if(pCache != NULL) + { + if(pCache->hFile != NULL) + SFileCloseFile(pCache->hFile); + if(pCache->szMask != NULL) + FREEMEM(pCache->szMask); + + FREEMEM(pCache); + return TRUE; + } + + return FALSE; +} + diff --git a/contrib/vmap_extractor_v2/stormlib/StormDll.h b/contrib/vmap_extractor_v2/stormlib/StormDll.h new file mode 100644 index 000000000..6d67820a2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/StormDll.h @@ -0,0 +1,67 @@ +/*****************************************************************************/ +/* Storm.h Copyright Justin Olbrantz(Quantam) 2000 */ +/*---------------------------------------------------------------------------*/ +/* Storm Interface Library v1.0 for Windows */ +/* */ +/* Author : Justin Olbrantz(Quantam) */ +/* E-mail : omega@dragonfire.net */ +/* WWW : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/ */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.00 1.00 Qua The first version of Storm.h */ +/* 11.04.03 1.00 Lad Added some functions */ +/*****************************************************************************/ + +// We need the Windows data types for the Storm prototypes +#include + +#ifndef __STORM_H__ +#define __STORM_H__ + +// Somethimes is necessary to change the function names so they +// will not conflict with other MPQ tools. +#ifdef STORM_ALTERNATE_NAMES + #define SFILE(Name) Storm##Name + #define SCOMP(Name) Storm##Name +#else + #define SFILE(Name) SFile##Name + #define SCOMP(Name) SComp##Name +#endif + + +// Just in case anyone is still using C out there +#ifdef __cplusplus +extern "C" { +#endif + +// Storm file function prototypes +BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ); +BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ); +BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength); +BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile); +BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile); +BOOL WINAPI SFILE(CloseFile)(HANDLE hFile); +DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh); +BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ); +BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength); +DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod); +BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped); +LCID WINAPI SFILE(SetLocale)(LCID nNewLocale); +BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength); +BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath); + +// Storm (de)compression functions +BOOL WINAPI SCOMP(Compress) (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel); +BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength); + + +#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP) +#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll +#endif + +#ifdef __cplusplus +} +#endif + +#endif // __STORM_H__ diff --git a/contrib/vmap_extractor_v2/stormlib/StormLib.h b/contrib/vmap_extractor_v2/stormlib/StormLib.h new file mode 100644 index 000000000..eeb8daa64 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/StormLib.h @@ -0,0 +1,579 @@ +/*****************************************************************************/ +/* StormLib.h Copyright (c) Ladislav Zezula 1999-2005 */ +/*---------------------------------------------------------------------------*/ +/* StormLib library v 5.00 */ +/* */ +/* Author : Ladislav Zezula */ +/* E-mail : ladik@zezula.net */ +/* WWW : http://www.zezula.net */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.99 1.00 Lad Created */ +/* 24.03.03 2.50 Lad Version 2.50 */ +/* 02.04.03 3.00 Lad Version 3.00 with compression */ +/* 11.04.03 3.01 Lad Renamed to StormLib.h for compatibility with */ +/* original headers for Storm.dll */ +/* 10.05.03 3.02 Lad Added Pkware DCL compression */ +/* 26.05.03 4.00 Lad Completed all compressions */ +/* 18.06.03 4.01 Lad Added SFileSetFileLocale */ +/* Added SFileExtractFile */ +/* 26.07.03 4.02 Lad Implemented nameless rename and delete */ +/* 26.07.03 4.03 Lad Added support for protected MPQs */ +/* 28.08.03 4.10 Lad Fixed bugs that caused StormLib incorrectly work */ +/* with Diablo I savegames and with files having full */ +/* hash table */ +/* 08.12.03 4.11 DCH Fixed bug in reading file block larger than 0x1000 */ +/* on certain files. */ +/* Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING */ +/* (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/ +/* 21.12.03 4.50 Lad Completed port for Mac */ +/* Fixed bug in compacting (if fsize is mul of 0x1000) */ +/* Fixed bug in SCompCompress */ +/* 27.05.04 4.51 Lad Changed memory management from new/delete to our */ +/* own macros */ +/* 22.06.04 4.60 Lad Optimized search. Support for multiple listfiles. */ +/* 30.09.04 4.61 Lad Fixed some bugs (Aaargh !!!) */ +/* Correctly works if HashTableSize > BlockTableSize */ +/* 29.12.04 4.70 Lad Fixed compatibility problem with MPQs from WoW */ +/* 14.07.05 5.00 Lad Added the BZLIB compression support */ +/* Added suport of files stored as single unit */ +/* 17.04.06 5.01 Lad Converted to MS Visual Studio 8.0 */ +/* Fixed issue with protected Warcraft 3 protected maps */ +/* 15.05.06 5.02 Lad Fixed issue with WoW 1.10+ */ +/* 07.09.06 5.10 Lad Fixed processing files longer than 2GB */ +/* 22.11.06 6.00 Lad Support for MPQ archives V2 */ +/*****************************************************************************/ + +#ifndef __STORMLIB_H_ +#define __STORMLIB_H_ + +#include "StormPort.h" + +//----------------------------------------------------------------------------- +// Use the apropriate library +// +// The library type is encoded in the library name as the following +// StormLibXYZ.lib +// +// X - D for Debug version, R for Release version +// Y - A for ANSI version, U for Unicode version (Unicode version does not exist yet) +// Z - S for static C library, D for multithreaded DLL C-library +// + +#if defined(_MSC_VER) && !defined (__STORMLIB_SELF__) + #ifdef _DEBUG // DEBUG VERSIONS + #ifdef _DLL + #pragma comment(lib, "StormLibDAD.lib") // Debug Ansi Dynamic version + #else + #pragma comment(lib, "StormLibDAS.lib") // Debug Ansi Static version + #endif + #else // RELEASE VERSIONS + #ifdef _DLL + #pragma comment(lib, "StormLibRAD.lib") // Release Ansi Dynamic version + #else + #pragma comment(lib, "StormLibRAS.lib") // Release Ansi Static version + #endif + #endif +#endif + +//----------------------------------------------------------------------------- +// Defines + +#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A') +#define ID_MPQ_SHUNT 0x1B51504D // MPQ shunt entry ('MPQ\x1B') + +#define ERROR_AVI_FILE 10000 // No MPQ file, but AVI file. + +// Values for SFileCreateArchiveEx +#define HASH_TABLE_SIZE_MIN 0x00002 +#define HASH_TABLE_SIZE_MAX 0x40000 + +#define HASH_ENTRY_DELETED 0xFFFFFFFE // Block index for deleted hash entry +#define HASH_ENTRY_FREE 0xFFFFFFFF // Block index for free hash entry + +// Values for SFileOpenArchive +#define SFILE_OPEN_HARD_DISK_FILE 2 // Open the archive on HDD +#define SFILE_OPEN_CDROM_FILE 3 // Open the archive only if it is on CDROM + +// Values for SFileOpenFile +#define SFILE_OPEN_FROM_MPQ 0 // Open the file from the MPQ archive +#define SFILE_OPEN_BY_INDEX 1 // The 'szFileName' parameter is actually the file index +#define SFILE_OPEN_LOCAL_FILE (DWORD)-1 // Open the file from the MPQ archive + +// Flags for TMPQArchive::dwFlags +#define MPQ_FLAG_CHANGED 0x00000001 // If set, the MPQ has been changed +#define MPQ_FLAG_PROTECTED 0x00000002 // Set on protected MPQs (like W3M maps) + +// Flags for SFileAddFile +#define MPQ_FILE_COMPRESS_PKWARE 0x00000100 // Compression made by PKWARE Data Compression Library +#define MPQ_FILE_COMPRESS_MULTI 0x00000200 // Multiple compressions +#define MPQ_FILE_COMPRESSED 0x0000FF00 // File is compressed +#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates whether file is encrypted +#define MPQ_FILE_FIXSEED 0x00020000 // File decrypt seed has to be fixed +#define MPQ_FILE_SINGLE_UNIT 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam) +#define MPQ_FILE_DUMMY_FILE 0x02000000 // The file is only 1 byte long and its name is a hash +#define MPQ_FILE_HAS_EXTRA 0x04000000 // The file has extra data appended after regular data. + // Must be with compressed files only +#define MPQ_FILE_EXISTS 0x80000000 // Set if file exists, reset when the file was deleted +#define MPQ_FILE_REPLACEEXISTING 0x80000000 // Replace when the file exist (SFileAddFile) + +#define MPQ_FILE_VALID_FLAGS (MPQ_FILE_COMPRESS_PKWARE | \ + MPQ_FILE_COMPRESS_MULTI | \ + MPQ_FILE_ENCRYPTED | \ + MPQ_FILE_FIXSEED | \ + MPQ_FILE_SINGLE_UNIT | \ + MPQ_FILE_DUMMY_FILE | \ + MPQ_FILE_HAS_EXTRA | \ + MPQ_FILE_EXISTS) + +// Compression types for multilpe compressions +#define MPQ_COMPRESSION_HUFFMANN 0x01 // Huffmann compression (used on WAVE files only) +#define MPQ_COMPRESSION_ZLIB 0x02 // ZLIB compression +#define MPQ_COMPRESSION_PKWARE 0x08 // PKWARE DCL compression +#define MPQ_COMPRESSION_BZIP2 0x10 // BZIP2 compression +#define MPQ_COMPRESSION_WAVE_MONO 0x40 // +#define MPQ_COMPRESSION_WAVE_STEREO 0x80 // + + +// Constants for SFileAddWave +#define MPQ_WAVE_QUALITY_HIGH 0 // Best quality, the worst compression +#define MPQ_WAVE_QUALITY_MEDIUM 1 // Medium quality, medium compression +#define MPQ_WAVE_QUALITY_LOW 2 // Low quality, the best compression + +// Constants for SFileGetFileInfo +#define SFILE_INFO_ARCHIVE_SIZE 1 // MPQ size (value from header) +#define SFILE_INFO_HASH_TABLE_SIZE 2 // Size of hash table, in entries +#define SFILE_INFO_BLOCK_TABLE_SIZE 3 // Number of entries in the block table +#define SFILE_INFO_BLOCK_SIZE 4 // Size of file block (in bytes) +#define SFILE_INFO_HASH_TABLE 5 // Pointer to Hash table (TMPQHash *) +#define SFILE_INFO_BLOCK_TABLE 6 // Pointer to Block Table (TMPQBlock *) +#define SFILE_INFO_NUM_FILES 7 // Real number of files within archive +//------ +#define SFILE_INFO_HASH_INDEX 8 // Hash index of file in MPQ +#define SFILE_INFO_CODENAME1 9 // The first codename of the file +#define SFILE_INFO_CODENAME2 10 // The second codename of the file +#define SFILE_INFO_LOCALEID 11 // Locale ID of file in MPQ +#define SFILE_INFO_BLOCKINDEX 12 // Index to Block Table +#define SFILE_INFO_FILE_SIZE 13 // Original file size +#define SFILE_INFO_COMPRESSED_SIZE 14 // Compressed file size +#define SFILE_INFO_FLAGS 15 // File flags +#define SFILE_INFO_POSITION 16 // File position within archive +#define SFILE_INFO_SEED 17 // File decryption seed +#define SFILE_INFO_SEED_UNFIXED 18 // Decryption seed not fixed to file pos and size + +// Values for compact callback +#define CCB_CHECKING_FILES 1 // Checking archive (dwParam1 = current, dwParam2 = total) +#define CCB_CHECKING_HASH_TABLE 2 // Checking hash table (dwParam1 = current, dwParam2 = total) +#define CCB_COPYING_NON_MPQ_DATA 3 // Copying non-MPQ data: No params used +#define CCB_COMPACTING_FILES 4 // Compacting archive (dwParam1 = current, dwParam2 = total) +#define CCB_CLOSING_ARCHIVE 5 // Closing archive: No params used + +#define LISTFILE_NAME "(listfile)" // Name of internal listfile +#define SIGNATURE_NAME "(signature)" // Name of internal signature +#define ATTRIBUTES_NAME "(attributes)" // Name of internal attributes file + +#define STORMLIB_VERSION (0x0600) // Current version of StormLib + +#define MPQ_FORMAT_VERSION_1 0 // Up to The Burning Crusade +#define MPQ_FORMAT_VERSION_2 1 // The Burning Crusade and newer, + +// Flags for SFileOpenArchiveEx +#define MPQ_OPEN_NO_LISTFILE 0x00000001 // Don't add the internal listfile + +// supports archives with size > 4 GB +// Additional flags for SFileCreateArchiveEx +#define MPQ_CREATE_ARCHIVE_V1 0x00000000 // Creates archive with size up to 4GB +#define MPQ_CREATE_ARCHIVE_V2 0x00010000 // Creates archive larger than 4 GB + +//----------------------------------------------------------------------------- +// Structures + +#if (defined(WIN32) || defined(WIN64)) +#include +#else +#pragma pack(1) +#endif + +struct TMPQFile; + +struct TMPQShunt +{ + // The ID_MPQ_SHUNT ('MPQ\x1B') signature + DWORD dwID; + + DWORD dwUnknown; + + // Position of the MPQ header, relative to the begin of the shunt + DWORD dwHeaderPos; +}; + + +// MPQ file header +struct TMPQHeader +{ + // The ID_MPQ ('MPQ\x1A') signature + DWORD dwID; + + // Size of the archive header + DWORD dwHeaderSize; + + // Size of MPQ archive + // This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive + // is calculated as the size from the beginning of the archive to the end of the hash table, + // block table, or extended block table (whichever is largest). + DWORD dwArchiveSize; + + // 0 = Original format + // 1 = Extended format (The Burning Crusade and newer) + USHORT wFormatVersion; + + // Power of two exponent specifying the number of 512-byte disk sectors in each logical sector + // in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift. + // Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors). + USHORT wBlockSize; + + // Offset to the beginning of the hash table, relative to the beginning of the archive. + DWORD dwHashTablePos; + + // Offset to the beginning of the block table, relative to the beginning of the archive. + DWORD dwBlockTablePos; + + // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for + // the original MoPaQ format, or less than 2^20 for the Burning Crusade format. + DWORD dwHashTableSize; + + // Number of entries in the block table + DWORD dwBlockTableSize; +}; + + +// Extended MPQ file header. Valid only if wFormatVersion is 1 or higher +struct TMPQHeader2 : public TMPQHeader +{ + // Offset to the beginning of the extended block table, relative to the beginning of the archive. + LARGE_INTEGER ExtBlockTablePos; + + // High 16 bits of the hash table offset for large archives. + USHORT wHashTablePosHigh; + + // High 16 bits of the block table offset for large archives. + USHORT wBlockTablePosHigh; +}; + + +// Hash entry. All files in the archive are searched by their hashes. +struct TMPQHash +{ + // The hash of the file path, using method A. + DWORD dwName1; + + // The hash of the file path, using method B. + DWORD dwName2; + +#ifdef PLATFORM_LITTLE_ENDIAN + + // The language of the file. This is a Windows LANGID data type, and uses the same values. + // 0 indicates the default language (American English), or that the file is language-neutral. + USHORT lcLocale; + + // The platform the file is used for. 0 indicates the default platform. + // No other values have been observed. + USHORT wPlatform; + +#else + + USHORT wPlatform; + USHORT lcLocale; + +#endif + + // If the hash table entry is valid, this is the index into the block table of the file. + // Otherwise, one of the following two values: + // - FFFFFFFFh: Hash table entry is empty, and has always been empty. + // Terminates searches for a given file. + // - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file). + // Does not terminate searches for a given file. + DWORD dwBlockIndex; +}; + + +// File description block contains informations about the file +struct TMPQBlock +{ + // Offset of the beginning of the block, relative to the beginning of the archive. + DWORD dwFilePos; + + // Compressed file size + DWORD dwCSize; + + // Only valid if the block is a file; otherwise meaningless, and should be 0. + // If the file is compressed, this is the size of the uncompressed file data. + DWORD dwFSize; + + // Flags for the file. See MPQ_FILE_XXXX constants + DWORD dwFlags; +}; + + +// The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes). +// The table contains the upper bits of the archive offsets for each block in the block table. +// It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block, +// with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes +// in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size. +struct TMPQBlockEx +{ + USHORT wFilePosHigh; +}; + + +struct TFileNode +{ + DWORD dwRefCount; // Number of references + // There can be more files that have the same name. + // (e.g. multiple language files). We don't want to + // have an entry for each of them, so the entries will be referenced. + // When a number of node references reaches zero, + // the node will be deleted + + size_t nLength; // File name length + char szFileName[1]; // File name, variable length +}; + +#if (defined(WIN32) || defined(WIN64)) +#include +#else +#pragma options align=reset +#endif + +// Archive handle structure. Note that it does not agree with Storm.dll's structure. +struct TMPQArchive +{ +// TMPQArchive * pNext; // Next archive (used by Storm.dll only) +// TMPQArchive * pPrev; // Previous archive (used by Storm.dll only) + char szFileName[MAX_PATH]; // Opened archive file name + HANDLE hFile; // File handle + DWORD dwPriority; // Priority of the archive + LARGE_INTEGER ShuntPos; // Position of MPQShunt (only valid if a shunt is present) + LARGE_INTEGER MpqPos; // MPQ position in the file, relative to the begin of the file + LARGE_INTEGER MpqSize; // Size of MPQ archive + LARGE_INTEGER HashTablePos; // Offset of the hast table in the MPQ, relative to the begin of the file + LARGE_INTEGER BlockTablePos; // Offset of the hast table in the MPQ, relative to the begin + LARGE_INTEGER ExtBlockTablePos; // Offset of the extended block table, relative to the begin + LARGE_INTEGER FilePointer; // Current position in the file (relative to begin of the file) + + TMPQFile * pLastFile; // Recently read file + DWORD dwBlockPos; // Position of loaded block in the file + DWORD dwBlockSize; // Size of file block + BYTE * pbBlockBuffer; // Buffer (cache) for file block + DWORD dwBuffPos; // Position in block buffer + TMPQShunt * pShunt; // MPQ shunt (NULL if not present in the file) + TMPQHeader2 * pHeader; // MPQ file header + TMPQHash * pHashTable; // Hash table + TMPQBlock * pBlockTable; // Block table + TMPQBlockEx * pExtBlockTable; // Extended block table + + TMPQShunt Shunt; // MPQ shunt. Valid only when ID_MPQ_SHUNT has been found + TMPQHeader2 Header; // MPQ header + + // Non-Storm.dll members + TFileNode ** pListFile; // File name array +// HANDLE hListFile; // Handle to temporary listfile (when open with write access) + DWORD dwFlags; // See MPQ_FLAG_XXXXX +// BOOL bChanged; // TRUE if the archive was changed since open. +// BOOL bProtected; // TRUE if the archive is protected by somehow +}; + + +// File handle structure. Note that it does not agree with Storm.dll structures +struct TMPQFile +{ + HANDLE hFile; // File handle + TMPQArchive * ha; // Archive handle + TMPQHash * pHash; // Hash table entry + TMPQBlockEx * pBlockEx; // Pointer to extended file block entry + TMPQBlock * pBlock; // File block pointer + DWORD dwSeed1; // Seed used for file decrypt + DWORD dwFilePos; // Current file position + LARGE_INTEGER MpqFilePos; // Position of the file data in MPQ archive + // (relative to file begin) + + DWORD * pdwBlockPos; // Position of each file block (only for compressed files) + DWORD nBlocks; // Number of blocks in the file (incl. the last noncomplete one) + BOOL bBlockPosLoaded; // TRUE if block positions loaded + BYTE * pbFileBuffer; // Decompressed file (for single unit files, size is the uncompressed file size) + + DWORD dwHashIndex; // Index to Hash table + DWORD dwFileIndex; // Index to Block table + char szFileName[1]; // File name (variable length) +}; + + +// Used by searching in MPQ archives +struct TMPQSearch +{ + TMPQArchive * ha; // Handle to MPQ, where the search runs + DWORD dwNextIndex; // The next searched hash index + DWORD dwName1; // Lastly found Name1 + DWORD dwName2; // Lastly found Name2 + char szSearchMask[1]; // Search mask (variable length) +}; + + +struct SFILE_FIND_DATA +{ + char cFileName[MAX_PATH]; // Full name of the found file + char * szPlainName; // Pointer to file part + LCID lcLocale; // Locale version + DWORD dwFileSize; // File size in bytes + DWORD dwFileFlags; // File flags (compressed or encrypted) + DWORD dwBlockIndex; // Block index for the file + DWORD dwCompSize; // Compressed file size +}; + +//----------------------------------------------------------------------------- +// Memory management +// +// We use our own macros for allocating/freeing memory. If you want +// to redefine them, please keep the following rules +// +// - The memory allocation must return NULL if not enough memory +// (i.e not to throw exception) +// - It is not necessary to fill the allocated block with zeros +// - Memory freeing function must not test the pointer to NULL. +// + + +__inline void * DebugMalloc(char * szFile, int nLine, int nSize) +{ + void * ptr = malloc(nSize + 100); + char * plain; + + plain = strrchr(szFile, '\\'); + if(plain == NULL) + plain = strrchr(szFile, '/'); + if(plain == NULL) + plain = szFile; + +#if _MSC_VER > 0x1300 + sprintf_s((char *)ptr, nSize+100, "%s(%u)", plain, nLine); +#else + sprintf((char *)ptr, "%s(%u)", plain, nLine); +#endif + + return (char *)ptr + 100; +} + + +__inline void DebugFree(void * ptr) +{ + free((char *)ptr - 100); +} + + +#ifndef ALLOCMEM + #define ALLOCMEM(type, nitems) (type *)malloc((nitems) * sizeof(type)) + #define FREEMEM(ptr) free(ptr) +#endif + +//#define ALLOCMEM(type, nitems) (type *)DebugMalloc(__FILE__, __LINE__, (nitems) * sizeof(type)) +//#define FREEMEM(ptr) DebugFree(ptr) + +//----------------------------------------------------------------------------- +// Functions in StormLib - compatible with Storm.dll + +// Typedefs for functions exported by Storm.dll +typedef LCID (WINAPI * SFILESETLOCALE)(LCID); +typedef BOOL (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *); +typedef BOOL (WINAPI * SFILECLOSEARCHIVE)(HANDLE); +typedef BOOL (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *); +typedef BOOL (WINAPI * SFILECLOSEFILE)(HANDLE); +typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, DWORD *); +typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD); +typedef BOOL (WINAPI * SFILEREADFILE)(HANDLE, VOID *, DWORD, DWORD *, LPOVERLAPPED); + +// Archive opening/closing +LCID WINAPI SFileSetLocale(LCID lcNewLocale); +LCID WINAPI SFileGetLocale(); +BOOL WINAPI SFileOpenArchive(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMPQ); +BOOL WINAPI SFileCloseArchive(HANDLE hMPQ); + +// File opening/closing +BOOL WINAPI SFileOpenFileEx(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile); +BOOL WINAPI SFileCloseFile(HANDLE hFile); + +// File I/O +DWORD WINAPI SFileGetFilePos(HANDLE hFile, DWORD * pdwFilePosHigh = NULL); +DWORD WINAPI SFileGetFileSize(HANDLE hFile, DWORD * pdwFileSizeHigh = NULL); +DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * pdwFilePosHigh, DWORD dwMethod); +BOOL WINAPI SFileReadFile(HANDLE hFile, VOID * lpBuffer, DWORD dwToRead, DWORD * pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL); + +BOOL WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted); + +// Adds another listfile into MPQ. The currently added listfile(s) remain, +// so you can use this API to combining more listfiles. +// Note that this function is internally called by SFileFindFirstFile +int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile); + +//----------------------------------------------------------------------------- +// Functions in StormLib - not implemented in Storm.dll + +// Archive creating and editing +BOOL WINAPI SFileCreateArchiveEx(const char * szMpqName, DWORD dwCreationDisposition, DWORD dwHashTableSize, HANDLE * phMPQ); +BOOL WINAPI SFileAddFile(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags); +BOOL WINAPI SFileAddWave(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality); +BOOL WINAPI SFileRemoveFile(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope = SFILE_OPEN_BY_INDEX); +BOOL WINAPI SFileRenameFile(HANDLE hMPQ, const char * szOldFileName, const char * szNewFileName); +BOOL WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale); + +// Retrieving info about the file +BOOL WINAPI SFileHasFile(HANDLE hMPQ, char * szFileName); +BOOL WINAPI SFileGetFileName(HANDLE hFile, char * szFileName); +DWORD_PTR WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType); + +// File search +// Note that the SFileFindFirstFileEx has been removed. Use SListFileFindFirst/Next +HANDLE WINAPI SFileFindFirstFile(HANDLE hMPQ, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile); +BOOL WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); +BOOL WINAPI SFileFindClose(HANDLE hFind); + +// Listfile search +HANDLE SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData); +BOOL SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); +BOOL SListFileFindClose(HANDLE hFind); + +// Archive compacting +typedef void (WINAPI * COMPACTCB)(void * lpUserData, DWORD dwWorkType, DWORD dwParam1, DWORD dwParam2); +BOOL WINAPI SFileSetCompactCallback(HANDLE hMPQ, COMPACTCB CompactCB, void * lpData); +BOOL WINAPI SFileCompactArchive(HANDLE hMPQ, const char * szListFile = NULL, BOOL bReserved = 0); + +// Locale support +int WINAPI SFileEnumLocales(HANDLE hMPQ, const char * szFileName, LCID * plcLocales, DWORD * pdwMaxLocales, DWORD dwSearchScope = SFILE_OPEN_BY_INDEX); + +// (De)compression +int WINAPI SCompCompress (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCompressions, int nCmpType, int nCmpLevel); +int WINAPI SCompDecompress (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength); + +// Sets the default data compression for files added to MPQ, +// if MPQ_FILE_COMPRESS_MULTI has been specified in call to SFileAddFile +int WINAPI SCompSetDataCompression(int nDataCompression); + +//----------------------------------------------------------------------------- +// Functions from Storm.dll. They use slightly different names for keeping +// possibility to use them together with StormLib (StormXXX instead of SFileXXX) + +#ifdef __LINK_STORM_DLL__ + #define STORM_ALTERNATE_NAMES // Force Storm.h to use alternate fnc names + #include "StormDll.h" +#endif // __LINK_STORM_DLL__ + +//----------------------------------------------------------------------------- +// GFX decode functions. See GfxDecode.cpp for details and description + +USHORT WINAPI celGetFrameCount(BYTE * fileBuf); +BYTE * WINAPI celGetFrameData(BYTE *fileBuf, BYTE *palette, USHORT xsize, USHORT frame, USHORT *ysize, USHORT *maxX=NULL); +USHORT WINAPI cl2GetFrameCount(BYTE *fileBuf); +BYTE ** WINAPI cl2GetDirData(BYTE *fileBuf, BYTE *palette, USHORT xsize, USHORT dir, USHORT *ysize); +BYTE * WINAPI pcxGetData(BYTE *filebuf, DWORD filesize, BYTE transcol, USHORT *xsize, USHORT *ysize); + +#endif // __STORMLIB_H_ diff --git a/contrib/vmap_extractor_v2/stormlib/StormPort.h b/contrib/vmap_extractor_v2/stormlib/StormPort.h new file mode 100644 index 000000000..4cb8d84bd --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/StormPort.h @@ -0,0 +1,278 @@ +/*****************************************************************************/ +/* StormPort.h Copyright (c) Marko Friedemann 2001 */ +/*---------------------------------------------------------------------------*/ +/* Portability module for the StormLib library. Contains a wrapper symbols */ +/* to make the compilation under Linux work */ +/* */ +/* Author: Marko Friedemann */ +/* Created at: Mon Jan 29 18:26:01 CEST 2001 */ +/* Computer: whiplash.flachland-chemnitz.de */ +/* System: Linux 2.4.0 on i686 */ +/* */ +/* Author: Sam Wilkins */ +/* System: Mac OS X and port to big endian processor */ +/* */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 29.01.01 1.00 Mar Created */ +/* 24.03.03 1.01 Lad Some cosmetic changes */ +/* 12.11.03 1.02 Dan Macintosh compatibility */ +/* 24.07.04 1.03 Sam Mac OS X compatibility */ +/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */ +/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */ +/*****************************************************************************/ + +#ifndef __STORMPORT_H__ +#define __STORMPORT_H__ + +// Defines for Windows +#if !defined(PLATFORM_DEFINED) && (defined(WIN32) || defined(WIN64)) + + // In MSVC 8.0, there are some functions declared as deprecated. + #if _MSC_VER >= 1400 + #define _CRT_SECURE_NO_DEPRECATE + #define _CRT_NON_CONFORMING_SWPRINTFS + #endif + + #include + #include + #include + #define PLATFORM_LITTLE_ENDIAN 1 + + #ifdef WIN64 + #define PLATFORM_64BIT + #else + #define PLATFORM_32BIT + #endif + + #define PLATFORM_DEFINED // The platform is known now + +#endif + +// Defines for Mac Carbon +#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac Carbon API + + // Macintosh using Carbon + #include // Mac OS X + #define _stricmp strcasecmp // Case insensitive strcmp has a different name on this platform. + #define _strnicmp strncasecmp + + typedef void * LPCSTR; + typedef unsigned long * LPDWORD; + typedef long * PLONG; + typedef void * LPVOID; + typedef unsigned int UINT; + + #define PKEXPORT + #define __SYS_ZLIB + #define __SYS_BZLIB + #define LANG_NEUTRAL 0 + + #if defined(__BIG_ENDIAN__) + #define PLATFORM_LITTLE_ENDIAN 0 + #else + #define PLATFORM_LITTLE_ENDIAN 1 // Apple is now making Macs with Intel CPUs + #endif + #define PLATFORM_DEFINED // The platform is known now + +#endif + +// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin* +// Ladik : Why the hell Linux does not use some OS-dependent #define ? +#if !defined(PLATFORM_DEFINED) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #define PLATFORM_LITTLE_ENDIAN 1 + #define PLATFORM_DEFINED + #define LANG_NEUTRAL 0 + +#endif /* not __powerc */ + + +#if !defined(WIN32) && !defined(WIN64) + + // Typedefs for ANSI C + typedef unsigned char BYTE; + typedef short SHORT; + typedef unsigned short WORD; + typedef unsigned short USHORT; + typedef long LONG; + typedef unsigned long DWORD; + typedef unsigned long DWORD_PTR; + typedef long LONG_PTR; + typedef long long LONGLONG; +#ifndef __OBJC__ + #define BOOL bool +#endif + typedef void * HANDLE; + typedef void * LPOVERLAPPED; // Unsupported on Linux + typedef char TCHAR; + typedef unsigned long LCID; + + typedef void * LPCSTR; + typedef unsigned long * LPDWORD; + typedef long * PLONG; + typedef void * LPVOID; + typedef unsigned int UINT; + + typedef struct _FILETIME + { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } + FILETIME, *PFILETIME; + + typedef union _LARGE_INTEGER + { + #if PLATFORM_LITTLE_ENDIAN + struct + { + DWORD LowPart; + LONG HighPart; + }; + #else + struct + { + LONG HighPart; + DWORD LowPart; + }; + #endif + LONGLONG QuadPart; + } + LARGE_INTEGER, *PLARGE_INTEGER; + + // Some Windows-specific defines + #ifndef MAX_PATH + #define MAX_PATH 1024 + #endif + + #ifndef TRUE + #define TRUE true + #endif + + #ifndef FALSE + #define FALSE false + #endif + + #define VOID void + #define WINAPI + + #define FILE_BEGIN SEEK_SET + #define FILE_CURRENT SEEK_CUR + #define FILE_END SEEK_END + + #define CREATE_NEW 1 + #define CREATE_ALWAYS 2 + #define OPEN_EXISTING 3 + #define OPEN_ALWAYS 4 + + #define FILE_SHARE_READ 0x00000001L + #define GENERIC_WRITE 0x40000000 + #define GENERIC_READ 0x80000000 + + #define FILE_FLAG_DELETE_ON_CLOSE 1 // Sam: Added these two defines so it would compile. + #define FILE_FLAG_SEQUENTIAL_SCAN 2 + + #define ERROR_SUCCESS 0 + #define ERROR_INVALID_FUNCTION 1 + #define ERROR_FILE_NOT_FOUND 2 + #define ERROR_ACCESS_DENIED 5 + #define ERROR_NOT_ENOUGH_MEMORY 8 + #define ERROR_BAD_FORMAT 11 + #define ERROR_NO_MORE_FILES 18 + #define ERROR_GEN_FAILURE 31 + #define ERROR_HANDLE_EOF 38 + #define ERROR_HANDLE_DISK_FULL 39 + #define ERROR_NOT_SUPPORTED 50 + #define ERROR_INVALID_PARAMETER 87 + #define ERROR_DISK_FULL 112 + #define ERROR_CALL_NOT_IMPLEMENTED 120 + #define ERROR_ALREADY_EXISTS 183 + #define ERROR_CAN_NOT_COMPLETE 1003 + #define ERROR_PARAMETER_QUOTA_EXCEEDED 1283 + #define ERROR_FILE_CORRUPT 1392 + #define ERROR_INSUFFICIENT_BUFFER 4999 + + #define INVALID_HANDLE_VALUE ((HANDLE) -1) + + #ifndef min + #define min(a, b) ((a < b) ? a : b) + #endif + + #ifndef max + #define max(a, b) ((a > b) ? a : b) + #endif + + #define _stricmp strcasecmp + #define _strnicmp strncasecmp + + extern int globalerr; + + void SetLastError(int err); + int GetLastError(); + char *ErrString(int err); + + // Emulation of functions for file I/O available in Win32 + HANDLE CreateFile(const char * lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, void * lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + BOOL CloseHandle(HANDLE hObject); + + DWORD GetFileSize(HANDLE hFile, DWORD * lpFileSizeHigh); + DWORD SetFilePointer(HANDLE, LONG lDistanceToMove, LONG * lpDistanceToMoveHigh, DWORD dwMoveMethod); + BOOL SetEndOfFile(HANDLE hFile); + + BOOL ReadFile(HANDLE hFile, void * lpBuffer, DWORD nNumberOfBytesToRead, DWORD * lpNumberOfBytesRead, void * lpOverLapped); + BOOL WriteFile(HANDLE hFile, const void * lpBuffer, DWORD nNumberOfBytesToWrite, DWORD * lpNumberOfBytesWritten, void * lpOverLapped); + + BOOL IsBadReadPtr(const void * ptr, int size); + DWORD GetFileAttributes(const char * szileName); + + BOOL DeleteFile(const char * lpFileName); + BOOL MoveFile(const char * lpFromFileName, const char * lpToFileName); + void GetTempPath(DWORD szTempLength, char * szTemp); + void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName); + + #define strnicmp strncasecmp + +#endif // !WIN32 + +#if PLATFORM_LITTLE_ENDIAN + #define BSWAP_INT16_UNSIGNED(a) (a) + #define BSWAP_INT16_SIGNED(a) (a) + #define BSWAP_INT32_UNSIGNED(a) (a) + #define BSWAP_INT32_SIGNED(a) (a) + #define BSWAP_ARRAY16_UNSIGNED(a,b) {} + #define BSWAP_ARRAY32_UNSIGNED(a,b) {} + #define BSWAP_TMPQSHUNT(a) {} + #define BSWAP_TMPQHEADER(a) {} +#else + extern unsigned short SwapUShort(unsigned short); + extern unsigned long SwapULong(unsigned long); + extern short SwapShort(unsigned short); + extern long SwapLong(unsigned long); + extern void ConvertUnsignedLongBuffer(unsigned long *buffer, unsigned long nbLongs); + extern void ConvertUnsignedShortBuffer(unsigned short *buffer, unsigned long nbShorts); + extern void ConvertTMPQShunt(void *shunt); + extern void ConvertTMPQHeader(void *header); + #define BSWAP_INT16_UNSIGNED(a) SwapUShort((a)) + #define BSWAP_INT32_UNSIGNED(a) SwapULong((a)) + #define BSWAP_INT16_SIGNED(a) SwapShort((a)) + #define BSWAP_INT32_SIGNED(a) SwapLong((a)) + #define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUnsignedShortBuffer((a),(b)) + #define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUnsignedLongBuffer((a),(b)) + #define BSWAP_TMPQSHUNT(a) ConvertTMPQShunt((a)) + #define BSWAP_TMPQHEADER(a) ConvertTMPQHeader((a)) +#endif + +#endif // __STORMPORT_H__ diff --git a/contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp b/contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp new file mode 100644 index 000000000..0cd827fde --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp @@ -0,0 +1,168 @@ +/******************************************************************** +* +* Description: implementation for StormLib - linux port +* intended to be used in GLdiablo +* +* ----> StormLib was originally developed for Windows by +* Ladislav Zezula (www.zezula.net), and he did +* a _great_ job! Thanks Ladislav! +* +* this is currently a quick and dirty hack to get it working +* don't expect beauty and/or miracles :) +* +* these are function wraps to execute Windows API calls +* as native Macintosh file calls (open/close/read/write/...) +* +* continue you work: added some wrapping functions for GNU/Linux by XPinguin +* +* Author: Marko Friedemann +* Created at: Mon Jan 29 19:01:37 CEST 2001 +* Computer: whiplash.flachland-chemnitz.de +* System: Linux 2.4.0 on i686 +* +* Copyright (c) 2001 BMX-Chemnitz.DE All rights reserved. +* +********************************************************************/ + +#ifndef _WIN32 +#include "StormPort.h" + +int globalerr; + +void SetLastError(int err) +{ + globalerr = err; +} + +int GetLastError() +{ + return(globalerr); +} + +char *ErrString(int err) +{ + switch (err) { + case ERROR_INVALID_FUNCTION: + return "function not implemented"; + case ERROR_FILE_NOT_FOUND: + return "file not found"; + case ERROR_ACCESS_DENIED: + return "access denied"; + case ERROR_NOT_ENOUGH_MEMORY: + return "not enough memory"; + case ERROR_BAD_FORMAT: + return "bad format"; + case ERROR_NO_MORE_FILES: + return "no more files"; + case ERROR_HANDLE_EOF: + return "access beyound EOF"; + case ERROR_HANDLE_DISK_FULL: + return "no space left on device"; + case ERROR_INVALID_PARAMETER: + return "invalid parameter"; + case ERROR_DISK_FULL: + return "no space left on device"; + case ERROR_ALREADY_EXISTS: + return "file exists"; + case ERROR_CAN_NOT_COMPLETE: + return "operation cannot be completed"; + default: + return "unknown error"; + } +} + +HANDLE CreateFile(const char *sFileName, DWORD ulMode, DWORD ulSharing, void *pSecAttrib, DWORD ulCreation, DWORD ulFlags, HANDLE hFile) +{ + switch (ulCreation) { + case OPEN_EXISTING: + return (HANDLE)open(sFileName, O_RDONLY | O_LARGEFILE); + case OPEN_ALWAYS: + return (HANDLE)open(sFileName, O_RDWR | O_CREAT); + case CREATE_NEW: + return (HANDLE)open(sFileName, O_RDWR | O_CREAT | O_TRUNC); + default: + return INVALID_HANDLE_VALUE; + } +} + +BOOL CloseHandle(HANDLE hFile) +{ + return (close((int)hFile) == 0); +} + +DWORD GetFileSize(HANDLE hFile, DWORD *ulOffSetHigh) +{ + if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) + return 0xffffffff; + + struct stat fileinfo; + fstat((int)hFile, &fileinfo); + + return fileinfo.st_size; +} + +DWORD SetFilePointer(HANDLE hFile, LONG lOffSetLow, LONG *pOffSetHigh, DWORD ulMethod) +{ + return lseek64((int)hFile, (off64_t)(*pOffSetHigh) << 32 | (DWORD)lOffSetLow, ulMethod); +} + +BOOL SetEndOfFile(HANDLE hFile) +{ + return (ftruncate((int)hFile, lseek((int)hFile, 0, SEEK_CUR)) == 0); +} + +BOOL ReadFile(HANDLE hFile, void *pBuffer, DWORD ulLen, DWORD *ulRead, void *pOverLapped) +{ + ssize_t count; + if ((count = read((int)hFile, pBuffer, ulLen)) == -1) { + *ulRead = 0; + return false; + } + *ulRead = count; + return true; +} + +BOOL WriteFile(HANDLE hFile, const void *pBuffer, DWORD ulLen, DWORD *ulWritten, void *pOverLapped) +{ + ssize_t count; + if ((count = write((int)hFile, pBuffer, ulLen)) == -1) { + *ulWritten = 0; + return false; + } + *ulWritten = count; + return true; +} + +// Check if a memory block is accessible for reading +BOOL IsBadReadPtr(const void * ptr, int size) +{ + return FALSE; +} + +// Returns attributes of a file +DWORD GetFileAttributes(const char * szFileName) +{ + return 0; +} + +void GetTempPath(DWORD szTempLength, char * szTemp) +{ + strncpy(szTemp, P_tmpdir, szTempLength); +} + +void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName) +{ + strcpy(szLFName, tempnam(lpTempFolderPath, lpFileName)); +} + +BOOL DeleteFile(const char *lpFileName) +{ + return (BOOL)remove(lpFileName); +} + +BOOL MoveFile(const char *lpExistingFileName, const char *lpNewFileName) +{ + return rename(lpExistingFileName, lpNewFileName); +} + +#endif diff --git a/contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp b/contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp new file mode 100644 index 000000000..26f67872a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp @@ -0,0 +1,762 @@ +/******************************************************************** +* +* Description: implementation for StormLib - Macintosh port +* +* these are function wraps to execute Windows API calls +* as native Macintosh file calls (open/close/read/write/...) +* requires Mac OS X +* +* Derived from Marko Friedemann +* StormPort.cpp for Linux +* +* Author: Daniel Chiaramello +* +* Carbonized by: Sam Wilkins +* +********************************************************************/ + +#ifndef _WIN32 || _WIN64 +#include "StormPort.h" +#include "StormLib.h" + +// FUNCTIONS EXTRACTED FROM MOREFILE PACKAGE!!! +// FEEL FREE TO REMOVE THEM AND TO ADD THE ORIGINAL ONES! + +/***************************************************************************** +* BEGIN OF MOREFILES COPY-PASTE +*****************************************************************************/ + +#ifdef __USEPRAGMAINTERNAL + #ifdef __MWERKS__ + #pragma internal on + #endif +#endif + +union TLongAnd4Bytes +{ + unsigned char bytes[4]; + unsigned long uvalue; + signed long svalue; +}; + + +static OSErr FSGetFullPath(const FSRef *ref, UInt8 *fullPath, UInt32 fullPathLength) +{ + OSErr result; + + result = FSRefMakePath(ref, fullPath, fullPathLength); + + return result; +} + +static OSErr FSLocationFromFullPath(const void *fullPath, FSRef *ref) +{ + OSErr result; + + result = FSPathMakeRef((UInt8 *)fullPath, ref, NULL); // Create an FSRef from the path + return result; +} + +/*****************************************************************************/ + +/*****************************************************************************/ + +static OSErr FSCreateCompat(const FSRef *parentRef, OSType creator, OSType fileType, const UniChar *fileName, + UniCharCount nameLength, FSRef *ref) +{ + FSCatalogInfo theCatInfo; + OSErr theErr; + ((FileInfo *)&theCatInfo.finderInfo)->fileCreator = creator; + ((FileInfo *)&theCatInfo.finderInfo)->fileType = fileType; + ((FileInfo *)&theCatInfo.finderInfo)->finderFlags = 0; + SetPt(&((FileInfo *)&theCatInfo.finderInfo)->location, 0, 0); + ((FileInfo *)&theCatInfo.finderInfo)->reservedField = 0; + + theErr = FSCreateFileUnicode(parentRef, nameLength, fileName, kFSCatInfoFinderInfo, &theCatInfo, ref, NULL); + return theErr; +} + + +/*****************************************************************************/ + +static OSErr FSOpenDFCompat(FSRef *ref, char permission, short *refNum) +{ + HFSUniStr255 forkName; + OSErr theErr; + Boolean isFolder, wasChanged; + + theErr = FSResolveAliasFile(ref, TRUE, &isFolder, &wasChanged); + if (theErr != noErr) + return theErr; + + FSGetDataForkName(&forkName); + theErr = FSOpenFork(ref, forkName.length, forkName.unicode, permission, refNum); + return theErr; +} + +/***************************************************************************** +* END OF MOREFILES COPY-PASTE +*****************************************************************************/ + +#pragma mark - + +int globalerr; + +/******************************************************************** +* SwapLong +********************************************************************/ + +unsigned long SwapULong(unsigned long data) +{ + // Apple provided function + uint32_t result; + + __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data)); + return result; + +/* + TLongAnd4Bytes Work; + unsigned char * value_as_4bytes = (unsigned char *)&value; + + Work.bytes[0] = value_as_4bytes[3]; + Work.bytes[1] = value_as_4bytes[2]; + Work.bytes[2] = value_as_4bytes[1]; + Work.bytes[3] = value_as_4bytes[0]; + + return Work.uvalue; +*/ +} + +long SwapLong(unsigned long data) +{ + // Apple provided function + uint32_t result; + + __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data)); + return (long)result; + +/* + TLongAnd4Bytes Work; + unsigned char * value_as_4bytes = (unsigned char *)&value; + + Work.bytes[0] = value_as_4bytes[3]; + Work.bytes[1] = value_as_4bytes[2]; + Work.bytes[2] = value_as_4bytes[1]; + Work.bytes[3] = value_as_4bytes[0]; + + return Work.svalue; +*/ +} + +/******************************************************************** +* SwapShort +********************************************************************/ +unsigned short SwapUShort(unsigned short data) +{ + // Apple provided function + uint16_t result; + __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data)); + return result; +} + +short SwapShort(unsigned short data) +{ + // Apple provided function + uint16_t result; + __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data)); + return (short)result; +} + +/******************************************************************** +* ConvertUnsignedLongBuffer +********************************************************************/ +void ConvertUnsignedLongBuffer(unsigned long *buffer, unsigned long nbLongs) +{ + while (nbLongs-- > 0) + { + *buffer = SwapLong(*buffer); + buffer++; + } +} + +/******************************************************************** +* ConvertUnsignedShortBuffer +********************************************************************/ +void ConvertUnsignedShortBuffer(unsigned short *buffer, unsigned long nbShorts) +{ + while (nbShorts-- > 0) + { + *buffer = SwapShort(*buffer); + buffer++; + } +} + +/******************************************************************** +* ConvertTMPQShunt +********************************************************************/ +void ConvertTMPQShunt(void *shunt) +{ + TMPQShunt * theShunt = (TMPQShunt *)shunt; + + theShunt->dwID = SwapULong(theShunt->dwID); + theShunt->dwUnknown = SwapULong(theShunt->dwUnknown); + theShunt->dwHeaderPos = SwapULong(theShunt->dwHeaderPos); +} + +/******************************************************************** +* ConvertTMPQHeader +********************************************************************/ +void ConvertTMPQHeader(void *header) +{ + TMPQHeader2 * theHeader = (TMPQHeader2 *)header; + + theHeader->dwID = SwapULong(theHeader->dwID); + theHeader->dwHeaderSize = SwapULong(theHeader->dwHeaderSize); + theHeader->dwArchiveSize = SwapULong(theHeader->dwArchiveSize); + theHeader->wFormatVersion = SwapUShort(theHeader->wFormatVersion); + theHeader->wBlockSize = SwapUShort(theHeader->wBlockSize); + theHeader->dwHashTablePos = SwapULong(theHeader->dwHashTablePos); + theHeader->dwBlockTablePos = SwapULong(theHeader->dwBlockTablePos); + theHeader->dwHashTableSize = SwapULong(theHeader->dwHashTableSize); + theHeader->dwBlockTableSize = SwapULong(theHeader->dwBlockTableSize); + + if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) + { + DWORD dwTemp = theHeader->ExtBlockTablePos.LowPart; + theHeader->ExtBlockTablePos.LowPart = theHeader->ExtBlockTablePos.HighPart; + theHeader->ExtBlockTablePos.HighPart = dwTemp; + theHeader->ExtBlockTablePos.LowPart = SwapULong(theHeader->ExtBlockTablePos.LowPart); + theHeader->ExtBlockTablePos.HighPart = SwapULong(theHeader->ExtBlockTablePos.HighPart); + theHeader->wHashTablePosHigh = SwapUShort(theHeader->wHashTablePosHigh); + theHeader->wBlockTablePosHigh = SwapUShort(theHeader->wBlockTablePosHigh); + } +} + +/******************************************************************** +* ConvertTMPQHash +********************************************************************/ +void ConvertHashTable(void *hashtable, DWORD nHashEntries) +{ + TMPQHash * theHash = (TMPQHash *)hashtable; + USHORT lcLocale; + + for(DWORD i = 0; i < nHashEntries; i++, theHash++) + { + lcLocale = theHash->lcLocale; + theHash->lcLocale = theHash->wPlatform; + theHash->wPlatform = lcLocale; + } +} + +#pragma mark - + +/******************************************************************** +* SetLastError +********************************************************************/ +void SetLastError(int err) +{ + globalerr = err; +} + +/******************************************************************** +* GetLastError +********************************************************************/ +int GetLastError() +{ + return globalerr; +} + +/******************************************************************** +* ErrString +********************************************************************/ +char *ErrString(int err) +{ + switch (err) + { + case ERROR_INVALID_FUNCTION: + return "function not implemented"; + case ERROR_FILE_NOT_FOUND: + return "file not found"; + case ERROR_ACCESS_DENIED: + return "access denied"; + case ERROR_NOT_ENOUGH_MEMORY: + return "not enough memory"; + case ERROR_BAD_FORMAT: + return "bad format"; + case ERROR_NO_MORE_FILES: + return "no more files"; + case ERROR_HANDLE_EOF: + return "access beyound EOF"; + case ERROR_HANDLE_DISK_FULL: + return "no space left on device"; + case ERROR_INVALID_PARAMETER: + return "invalid parameter"; + case ERROR_DISK_FULL: + return "no space left on device"; + case ERROR_ALREADY_EXISTS: + return "file exists"; + case ERROR_CAN_NOT_COMPLETE: + return "operation cannot be completed"; + case ERROR_INSUFFICIENT_BUFFER: + return "insufficient buffer"; + default: + return "unknown error"; + } +} + +#pragma mark - + +/******************************************************************** +* GetTempPath - returns a '/' or ':'-terminated path +* szTempLength: length for path +* szTemp: file path +********************************************************************/ +void GetTempPath(DWORD szTempLength, char * szTemp) // I think I'll change this to use FSRefs. +{ + FSRef theFSRef; + OSErr theErr = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, kCreateFolder, &theFSRef); + if (theErr == noErr) + { + theErr = FSGetFullPath(&theFSRef, (UInt8 *)szTemp, MAX_PATH); + if (theErr != noErr) + szTemp[0] = '\0'; + } + else + szTemp[0] = '\0'; + strcat(szTemp, "/"); + + SetLastError(theErr); +} + +/******************************************************************** +* GetTempFileName +* lpTempFolderPath: the temporary folder path, terminated by "/" +* lpFileName: a file name base +* something: unknown +* szLFName: the final path, built from the path, the file name and a random pattern +********************************************************************/ +void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName) +{ +#pragma unused (something) + char tmp[2] = "A"; + + while (true) + { + HANDLE fHandle; + + strcpy(szLFName, lpTempFolderPath); + strcat(szLFName, lpFileName); + strcat(szLFName, tmp); + + if ((fHandle = CreateFile(szLFName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) + // OK we found it! + break; + CloseHandle(fHandle); + tmp[0]++; + } +} + +/******************************************************************** +* DeleteFile +* lpFileName: file path +********************************************************************/ +BOOL DeleteFile(const char * lpFileName) +{ + OSErr theErr; + FSRef theFileRef; + + theErr = FSLocationFromFullPath(lpFileName, &theFileRef); + if (theErr != noErr) + { + SetLastError(theErr); + return FALSE; + } + + theErr = FSDeleteObject(&theFileRef); + + SetLastError(theErr); + + return theErr == noErr; +} + +/******************************************************************** +* MoveFile +* lpFromFileName: old file path +* lpToFileName: new file path +********************************************************************/ +BOOL MoveFile(const char * lpFromFileName, const char * lpToFileName) +{ + OSErr theErr; + FSRef fromFileRef; + FSRef toFileRef; + FSRef parentFolderRef; + + // Get the path to the old file + theErr = FSLocationFromFullPath(lpFromFileName, &fromFileRef); + if (theErr != noErr) + { + SetLastError(theErr); + return false; + } + + // Get the path to the new folder for the file + char folderName[strlen(lpToFileName)]; + CFStringRef folderPathCFString = CFStringCreateWithCString(NULL, lpToFileName, kCFStringEncodingUTF8); + CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, folderPathCFString, kCFURLPOSIXPathStyle, FALSE); + CFURLRef folderURL = CFURLCreateCopyDeletingLastPathComponent(NULL, fileURL); + CFURLGetFileSystemRepresentation(folderURL, TRUE, (UInt8 *)folderName, strlen(lpToFileName)); + theErr = FSLocationFromFullPath(folderName, &parentFolderRef); + CFRelease(fileURL); + CFRelease(folderURL); + CFRelease(folderPathCFString); + + // Move the old file + theErr = FSMoveObject(&fromFileRef, &parentFolderRef, &toFileRef); + if (theErr != noErr) + { + SetLastError(theErr); + return false; + } + + // Get a CFString for the new file name + CFStringRef newFileNameCFString = CFStringCreateWithCString(NULL, lpToFileName, kCFStringEncodingUTF8); + fileURL = CFURLCreateWithFileSystemPath(NULL, newFileNameCFString, kCFURLPOSIXPathStyle, FALSE); + CFRelease(newFileNameCFString); + newFileNameCFString = CFURLCopyLastPathComponent(fileURL); + CFRelease(fileURL); + + // Convert CFString to Unicode and rename the file + UniChar unicodeFileName[256]; + CFStringGetCharacters(newFileNameCFString, CFRangeMake(0, CFStringGetLength(newFileNameCFString)), + unicodeFileName); + theErr = FSRenameUnicode(&toFileRef, CFStringGetLength(newFileNameCFString), unicodeFileName, + kTextEncodingUnknown, NULL); + if (theErr != noErr) + { + SetLastError(theErr); + CFRelease(newFileNameCFString); + return false; + } + + CFRelease(newFileNameCFString); + + SetLastError(theErr); + return true; +} + +/******************************************************************** +* CreateFile +* ulMode: GENERIC_READ | GENERIC_WRITE +* ulSharing: FILE_SHARE_READ +* pSecAttrib: NULL +* ulCreation: OPEN_EXISTING, OPEN_ALWAYS, CREATE_NEW +* ulFlags: 0 +* hFile: NULL +********************************************************************/ +HANDLE CreateFile( const char *sFileName, /* file name */ + DWORD ulMode, /* access mode */ + DWORD ulSharing, /* share mode */ + void *pSecAttrib, /* SD */ + DWORD ulCreation, /* how to create */ + DWORD ulFlags, /* file attributes */ + HANDLE hFile ) /* handle to template file */ +{ +#pragma unused (ulSharing, pSecAttrib, ulFlags, hFile) + + OSErr theErr; + FSRef theFileRef; + FSRef theParentRef; + short fileRef; + char permission; + static OSType gCreator; + static OSType gType; + + theErr = FSLocationFromFullPath(sFileName, &theFileRef); + if (theErr == fnfErr) + { // Create the FSRef for the parent directory. + memset(&theFileRef, 0, sizeof(FSRef)); + UInt8 folderName[MAX_PATH]; + CFStringRef folderPathCFString = CFStringCreateWithCString(NULL, sFileName, kCFStringEncodingUTF8); + CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, folderPathCFString, kCFURLPOSIXPathStyle, FALSE); + CFURLRef folderURL = CFURLCreateCopyDeletingLastPathComponent(NULL, fileURL); + CFURLGetFileSystemRepresentation(folderURL, TRUE, folderName, MAX_PATH); + theErr = FSLocationFromFullPath(folderName, &theParentRef); + CFRelease(fileURL); + CFRelease(folderURL); + CFRelease(folderPathCFString); + } + if (theErr != noErr) + { + SetLastError(theErr); + if (ulCreation == OPEN_EXISTING || theErr != fnfErr) + return INVALID_HANDLE_VALUE; + } + + if (ulCreation != OPEN_EXISTING) + { /* We create the file */ + UniChar unicodeFileName[256]; + CFStringRef filePathCFString = CFStringCreateWithCString(NULL, sFileName, kCFStringEncodingUTF8); + CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, filePathCFString, kCFURLPOSIXPathStyle, FALSE); + CFStringRef fileNameCFString = CFURLCopyLastPathComponent(fileURL); + CFStringGetCharacters(fileNameCFString, CFRangeMake(0, CFStringGetLength(fileNameCFString)), + unicodeFileName); + theErr = FSCreateCompat(&theParentRef, gCreator, gType, unicodeFileName, + CFStringGetLength(fileNameCFString), &theFileRef); + CFRelease(fileNameCFString); + CFRelease(filePathCFString); + CFRelease(fileURL); + if (theErr != noErr) + { + SetLastError(theErr); + return INVALID_HANDLE_VALUE; + } + } + + if (ulMode == GENERIC_READ) + permission = fsRdPerm; + else + { + if (ulMode == GENERIC_WRITE) + permission = fsWrPerm; + else + permission = fsRdWrPerm; + } + theErr = FSOpenDFCompat(&theFileRef, permission, &fileRef); + + SetLastError(theErr); + + if (theErr == noErr) + return (HANDLE)(int)fileRef; + else + return INVALID_HANDLE_VALUE; +} + +/******************************************************************** +* CloseHandle +********************************************************************/ +BOOL CloseHandle( HANDLE hFile ) /* handle to object */ +{ + OSErr theErr; + + if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) + return FALSE; + + theErr = FSCloseFork((short)(int)hFile); + + SetLastError(theErr); + + return theErr != noErr; +} + +/******************************************************************** +* GetFileSize +********************************************************************/ +DWORD GetFileSize( HANDLE hFile, /* handle to file */ + DWORD *ulOffSetHigh ) /* high-order word of file size */ +{ + SInt64 fileLength; + OSErr theErr; + + if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) + { + SetLastError(theErr); + return -1u; + } + + theErr = FSGetForkSize((short)(int)hFile, &fileLength); + if (theErr != noErr) + { + SetLastError(theErr); + return -1u; + } + + if (ulOffSetHigh != NULL) + *ulOffSetHigh = fileLength >> 32; + + SetLastError(theErr); + + return fileLength; +} + +/******************************************************************** +* SetFilePointer +* pOffSetHigh: NULL +* ulMethod: FILE_BEGIN, FILE_CURRENT +********************************************************************/ +DWORD SetFilePointer( HANDLE hFile, /* handle to file */ + LONG lOffSetLow, /* bytes to move pointer */ + LONG *pOffSetHigh, /* bytes to move pointer */ + DWORD ulMethod ) /* starting point */ +{ + OSErr theErr; + + if (ulMethod == FILE_CURRENT) + { + SInt64 bytesToMove; + + if (pOffSetHigh != NULL) + bytesToMove = ((SInt64)*pOffSetHigh << 32) + lOffSetLow; + else + bytesToMove = lOffSetLow; + + SInt64 newPos; + + theErr = FSSetForkPosition((short)(int)hFile, fsFromMark, bytesToMove); + if (theErr != noErr) + { + SetLastError(theErr); + return -1u; + } + + theErr = FSGetForkPosition((short)(int)hFile, &newPos); + if (theErr != noErr) + { + SetLastError(theErr); + return -1u; + } + + if (pOffSetHigh != NULL) + *pOffSetHigh = newPos >> 32; + + SetLastError(theErr); + return newPos; + } + else if (ulMethod == FILE_BEGIN) + { + SInt64 bytesToMove; + + if (pOffSetHigh != NULL) + bytesToMove = ((SInt64)*pOffSetHigh << 32) + lOffSetLow; + else + bytesToMove = lOffSetLow; + + theErr = FSSetForkPosition((short)(int)hFile, fsFromStart, bytesToMove); + if (theErr != noErr) + { + SetLastError(theErr); + return -1u; + } + + SetLastError(theErr); + return lOffSetLow; + } + else + { + SInt64 bytesToMove; + + if (pOffSetHigh != NULL) + bytesToMove = ((SInt64)*pOffSetHigh << 32) + lOffSetLow; + else + bytesToMove = lOffSetLow; + + SInt64 newPos; + + theErr = FSSetForkPosition((short)(int)hFile, fsFromLEOF, bytesToMove); + if (theErr != noErr) + { + SetLastError(theErr); + return -1u; + } + + theErr = FSGetForkPosition((short)(int)hFile, &newPos); + if (theErr != noErr) + { + SetLastError(theErr); + return -1u; + } + + if (pOffSetHigh != NULL) + *pOffSetHigh = newPos >> 32; + + SetLastError(theErr); + return newPos; + } +} + +/******************************************************************** +* SetEndOfFile +********************************************************************/ +BOOL SetEndOfFile( HANDLE hFile ) /* handle to file */ +{ + OSErr theErr; + + theErr = FSSetForkSize((short)(int)hFile, fsAtMark, 0); + + SetLastError(theErr); + + return theErr == noErr; +} + +/******************************************************************** +* ReadFile +* pOverLapped: NULL +********************************************************************/ +BOOL ReadFile( HANDLE hFile, /* handle to file */ + void *pBuffer, /* data buffer */ + DWORD ulLen, /* number of bytes to read */ + DWORD *ulRead, /* number of bytes read */ + void *pOverLapped ) /* overlapped buffer */ +{ +#pragma unused (pOverLapped) + + ByteCount nbCharsRead; + OSErr theErr; + + nbCharsRead = ulLen; + theErr = FSReadFork((short)(int)hFile, fsAtMark, 0, nbCharsRead, pBuffer, &nbCharsRead); + *ulRead = nbCharsRead; + + SetLastError(theErr); + + return theErr == noErr; +} + +/******************************************************************** +* WriteFile +* pOverLapped: NULL +********************************************************************/ +BOOL WriteFile( HANDLE hFile, /* handle to file */ + const void *pBuffer, /* data buffer */ + DWORD ulLen, /* number of bytes to write */ + DWORD *ulWritten, /* number of bytes written */ + void *pOverLapped ) /* overlapped buffer */ +{ +#pragma unused (pOverLapped) + + ByteCount nbCharsToWrite; + OSErr theErr; + + nbCharsToWrite = ulLen; + theErr = FSWriteFork((short)(int)hFile, fsAtMark, 0, nbCharsToWrite, pBuffer, &nbCharsToWrite); + *ulWritten = nbCharsToWrite; + + SetLastError(theErr); + + return theErr == noErr; +} + +// Check if a memory block is accessible for reading. It's probably too +// hard to check on Mac, so sorry, we'll just have to crash +BOOL IsBadReadPtr(const void * ptr, int size) +{ +#pragma unused (ptr, size) + + return FALSE; +} + +// Returns attributes of a file. Actually, it doesn't, it just checks if +// the file exists, since that's all StormLib uses it for +DWORD GetFileAttributes(const char * szFileName) +{ + FSRef theRef; + OSErr theErr; + + theErr = FSLocationFromFullPath(szFileName, &theRef); + + if (theErr != noErr) + return -1u; + else + return 0; +} + +#endif diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES b/contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES new file mode 100644 index 000000000..e31b03a01 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES @@ -0,0 +1,275 @@ + + +0.9.0 +~~~~~ +First version. + + +0.9.0a +~~~~~~ +Removed 'ranlib' from Makefile, since most modern Unix-es +don't need it, or even know about it. + + +0.9.0b +~~~~~~ +Fixed a problem with error reporting in bzip2.c. This does not effect +the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the +program proper) compress and decompress correctly, but give misleading +error messages (internal panics) when an I/O error occurs, instead of +reporting the problem correctly. This shouldn't give any data loss +(as far as I can see), but is confusing. + +Made the inline declarations disappear for non-GCC compilers. + + +0.9.0c +~~~~~~ +Fixed some problems in the library pertaining to some boundary cases. +This makes the library behave more correctly in those situations. The +fixes apply only to features (calls and parameters) not used by +bzip2.c, so the non-fixedness of them in previous versions has no +effect on reliability of bzip2.c. + +In bzlib.c: + * made zero-length BZ_FLUSH work correctly in bzCompress(). + * fixed bzWrite/bzRead to ignore zero-length requests. + * fixed bzread to correctly handle read requests after EOF. + * wrong parameter order in call to bzDecompressInit in + bzBuffToBuffDecompress. Fixed. + +In compress.c: + * changed setting of nGroups in sendMTFValues() so as to + do a bit better on small files. This _does_ effect + bzip2.c. + + +0.9.5a +~~~~~~ +Major change: add a fallback sorting algorithm (blocksort.c) +to give reasonable behaviour even for very repetitive inputs. +Nuked --repetitive-best and --repetitive-fast since they are +no longer useful. + +Minor changes: mostly a whole bunch of small changes/ +bugfixes in the driver (bzip2.c). Changes pertaining to the +user interface are: + + allow decompression of symlink'd files to stdout + decompress/test files even without .bz2 extension + give more accurate error messages for I/O errors + when compressing/decompressing to stdout, don't catch control-C + read flags from BZIP2 and BZIP environment variables + decline to break hard links to a file unless forced with -f + allow -c flag even with no filenames + preserve file ownerships as far as possible + make -s -1 give the expected block size (100k) + add a flag -q --quiet to suppress nonessential warnings + stop decoding flags after --, so files beginning in - can be handled + resolved inconsistent naming: bzcat or bz2cat ? + bzip2 --help now returns 0 + +Programming-level changes are: + + fixed syntax error in GET_LL4 for Borland C++ 5.02 + let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC} + fix overshoot of mode-string end in bzopen_or_bzdopen + wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... } + close file handles under all error conditions + added minor mods so it compiles with DJGPP out of the box + fixed Makefile so it doesn't give problems with BSD make + fix uninitialised memory reads in dlltest.c + +0.9.5b +~~~~~~ +Open stdin/stdout in binary mode for DJGPP. + +0.9.5c +~~~~~~ +Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1 +version could cause the sorted order to be wrong in some extremely +obscure cases. Also changed setting of quadrant in blocksort.c. + +0.9.5d +~~~~~~ +The only functional change is to make bzlibVersion() in the library +return the correct string. This has no effect whatsoever on the +functioning of the bzip2 program or library. Added a couple of casts +so the library compiles without warnings at level 3 in MS Visual +Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other +changes are minor documentation changes. + +1.0 +~~~ +Several minor bugfixes and enhancements: + +* Large file support. The library uses 64-bit counters to + count the volume of data passing through it. bzip2.c + is now compiled with -D_FILE_OFFSET_BITS=64 to get large + file support from the C library. -v correctly prints out + file sizes greater than 4 gigabytes. All these changes have + been made without assuming a 64-bit platform or a C compiler + which supports 64-bit ints, so, except for the C library + aspect, they are fully portable. + +* Decompression robustness. The library/program should be + robust to any corruption of compressed data, detecting and + handling _all_ corruption, instead of merely relying on + the CRCs. What this means is that the program should + never crash, given corrupted data, and the library should + always return BZ_DATA_ERROR. + +* Fixed an obscure race-condition bug only ever observed on + Solaris, in which, if you were very unlucky and issued + control-C at exactly the wrong time, both input and output + files would be deleted. + +* Don't run out of file handles on test/decompression when + large numbers of files have invalid magic numbers. + +* Avoid library namespace pollution. Prefix all exported + symbols with BZ2_. + +* Minor sorting enhancements from my DCC2000 paper. + +* Advance the version number to 1.0, so as to counteract the + (false-in-this-case) impression some people have that programs + with version numbers less than 1.0 are in some way, experimental, + pre-release versions. + +* Create an initial Makefile-libbz2_so to build a shared library. + Yes, I know I should really use libtool et al ... + +* Make the program exit with 2 instead of 0 when decompression + fails due to a bad magic number (ie, an invalid bzip2 header). + Also exit with 1 (as the manual claims :-) whenever a diagnostic + message would have been printed AND the corresponding operation + is aborted, for example + bzip2: Output file xx already exists. + When a diagnostic message is printed but the operation is not + aborted, for example + bzip2: Can't guess original name for wurble -- using wurble.out + then the exit value 0 is returned, unless some other problem is + also detected. + + I think it corresponds more closely to what the manual claims now. + + +1.0.1 +~~~~~ +* Modified dlltest.c so it uses the new BZ2_ naming scheme. +* Modified makefile-msc to fix minor build probs on Win2k. +* Updated README.COMPILATION.PROBLEMS. + +There are no functionality changes or bug fixes relative to version +1.0.0. This is just a documentation update + a fix for minor Win32 +build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is +utterly pointless. Don't bother. + + +1.0.2 +~~~~~ +A bug fix release, addressing various minor issues which have appeared +in the 18 or so months since 1.0.1 was released. Most of the fixes +are to do with file-handling or documentation bugs. To the best of my +knowledge, there have been no data-loss-causing bugs reported in the +compression/decompression engine of 1.0.0 or 1.0.1. + +Note that this release does not improve the rather crude build system +for Unix platforms. The general plan here is to autoconfiscate/ +libtoolise 1.0.2 soon after release, and release the result as 1.1.0 +or perhaps 1.2.0. That, however, is still just a plan at this point. + +Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in +parentheses. + +* Fix an infinite segfault loop in 1.0.1 when a directory is + encountered in -f (force) mode. + (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt) + +* Avoid double fclose() of output file on certain I/O error paths. + (Solar Designer) + +* Don't fail with internal error 1007 when fed a long stream (> 48MB) + of byte 251. Also print useful message suggesting that 1007s may be + caused by bad memory. + (noticed by Juan Pedro Vallejo, fixed by me) + +* Fix uninitialised variable silly bug in demo prog dlltest.c. + (Jorj Bauer) + +* Remove 512-MB limitation on recovered file size for bzip2recover + on selected platforms which support 64-bit ints. At the moment + all GCC supported platforms, and Win32. + (me, Alson van der Meulen) + +* Hard-code header byte values, to give correct operation on platforms + using EBCDIC as their native character set (IBM's OS/390). + (Leland Lucius) + +* Copy file access times correctly. + (Marty Leisner) + +* Add distclean and check targets to Makefile. + (Michael Carmack) + +* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS). + (Rich Ireland, Bo Thorsen) + +* Pass -p (create parent dirs as needed) to mkdir during make install. + (Jeremy Fusco) + +* Dereference symlinks when copying file permissions in -f mode. + (Volker Schmidt) + +* Majorly simplify implementation of uInt64_qrm10. + (Bo Lindbergh) + +* Check the input file still exists before deleting the output one, + when aborting in cleanUpAndFail(). + (Joerg Prante, Robert Linden, Matthias Krings) + +Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer +of bzip2: + +* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore. + +* Spelling changes and minor enhancements in bzip2.1. + +* Avoid race condition between creating the output file and setting its + interim permissions safely, by using fopen_output_safely(). + No changes to bzip2recover since there is no issue with file + permissions there. + +* do not print senseless report with -v when compressing an empty + file. + +* bzcat -f works on non-bzip2 files. + +* do not try to escape shell meta-characters on unix (the shell takes + care of these). + +* added --fast and --best aliases for -1 -9 for gzip compatibility. + + +1.0.3 (15 Feb 05) +~~~~~~~~~~~~~~~~~ +Fixes some minor bugs since the last version, 1.0.2. + +* Further robustification against corrupted compressed data. + There are currently no known bitstreams which can cause the + decompressor to crash, loop or access memory which does not + belong to it. If you are using bzip2 or the library to + decompress bitstreams from untrusted sources, an upgrade + to 1.0.3 is recommended. + +* The documentation has been converted to XML, from which html + and pdf can be derived. + +* Various minor bugs in the documentation have been fixed. + +* Fixes for various compilation warnings with newer versions of + gcc, and on 64-bit platforms. + +* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2. + This has been fixed. diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE b/contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE new file mode 100644 index 000000000..e60845b4d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE @@ -0,0 +1,40 @@ + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2005 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, Cambridge, UK. +jseward@acm.org +bzip2/libbzip2 version 1.0.3 of 15 February 2005 + diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so b/contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so new file mode 100644 index 000000000..458c5a135 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so @@ -0,0 +1,44 @@ + +# This Makefile builds a shared version of the library, +# libbz2.so.1.0.3, with soname libbz2.so.1.0, +# at least on x86-Linux (RedHat 7.2), +# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98). +# Please see the README file for some +# important info about building the library like this. + +SHELL=/bin/sh +CC=gcc +BIGFILES=-D_FILE_OFFSET_BITS=64 +CFLAGS=-fpic -fPIC -Wall -Winline -O -g + +OBJS= blocksort.o \ + huffman.o \ + crctable.o \ + randtable.o \ + compress.o \ + decompress.o \ + bzlib.o + +all: $(OBJS) + $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.3 $(OBJS) + $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.3 + rm -f libbz2.so.1.0 + ln -s libbz2.so.1.0.3 libbz2.so.1.0 + +clean: + rm -f $(OBJS) bzip2.o libbz2.so.1.0.3 libbz2.so.1.0 bzip2-shared + +blocksort.o: blocksort.c + $(CC) $(CFLAGS) -c blocksort.c +huffman.o: huffman.c + $(CC) $(CFLAGS) -c huffman.c +crctable.o: crctable.c + $(CC) $(CFLAGS) -c crctable.c +randtable.o: randtable.c + $(CC) $(CFLAGS) -c randtable.c +compress.o: compress.c + $(CC) $(CFLAGS) -c compress.c +decompress.o: decompress.c + $(CC) $(CFLAGS) -c decompress.c +bzlib.o: bzlib.c + $(CC) $(CFLAGS) -c bzlib.c diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/README b/contrib/vmap_extractor_v2/stormlib/bzip2/README new file mode 100644 index 000000000..1aff4487e --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/README @@ -0,0 +1,185 @@ + +This is the README for bzip2, a block-sorting file compressor, version +1.0.3. This version is fully compatible with the previous public +releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and 1.0.2. + +bzip2-1.0.3 is distributed under a BSD-style license. For details, +see the file LICENSE. + +Complete documentation is available in Postscript form (manual.ps), +PDF (manual.pdf) or html (manual.html). A plain-text version of the +manual page is available as bzip2.txt. A statement about Y2K issues +is now included in the file Y2K_INFO. + + +HOW TO BUILD -- UNIX + +Type `make'. This builds the library libbz2.a and then the +programs bzip2 and bzip2recover. Six self-tests are run. +If the self-tests complete ok, carry on to installation: + +To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type + make install +To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type + make install PREFIX=/xxx/yyy +If you are (justifiably) paranoid and want to see what 'make install' +is going to do, you can first do + make -n install or + make -n install PREFIX=/xxx/yyy respectively. +The -n instructs make to show the commands it would execute, but +not actually execute them. + + +HOW TO BUILD -- UNIX, shared library libbz2.so. + +Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for +Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims +that it works for any other platform, though I suspect it probably +will work for most platforms employing both ELF and gcc. + +bzip2-shared, a client of the shared library, is also built, but not +self-tested. So I suggest you also build using the normal Makefile, +since that conducts a self-test. A second reason to prefer the +version statically linked to the library is that, on x86 platforms, +building shared objects makes a valuable register (%ebx) unavailable +to gcc, resulting in a slowdown of 10%-20%, at least for bzip2. + +Important note for people upgrading .so's from 0.9.0/0.9.5 to version +1.0.X. All the functions in the library have been renamed, from (eg) +bzCompress to BZ2_bzCompress, to avoid namespace pollution. +Unfortunately this means that the libbz2.so created by +Makefile-libbz2_so will not work with any program which used an older +version of the library. Sorry. I do encourage library clients to +make the effort to upgrade to use version 1.0, since it is both faster +and more robust than previous versions. + + +HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc. + +It's difficult for me to support compilation on all these platforms. +My approach is to collect binaries for these platforms, and put them +on the master web page (http://sources.redhat.com/bzip2). Look there. +However (FWIW), bzip2-1.0.X is very standard ANSI C and should compile +unmodified with MS Visual C. If you have difficulties building, you +might want to read README.COMPILATION.PROBLEMS. + +At least using MS Visual C++ 6, you can build from the unmodified +sources by issuing, in a command shell: + nmake -f makefile.msc +(you may need to first run the MSVC-provided script VCVARS32.BAT + so as to set up paths to the MSVC tools correctly). + + +VALIDATION + +Correct operation, in the sense that a compressed file can always be +decompressed to reproduce the original, is obviously of paramount +importance. To validate bzip2, I used a modified version of Mark +Nelson's churn program. Churn is an automated test driver which +recursively traverses a directory structure, using bzip2 to compress +and then decompress each file it encounters, and checking that the +decompressed data is the same as the original. + + + +Please read and be aware of the following: + +WARNING: + + This program (attempts to) compress data by performing several + non-trivial transformations on it. Unless you are 100% familiar + with *all* the algorithms contained herein, and with the + consequences of modifying them, you should NOT meddle with the + compression or decompression machinery. Incorrect changes can and + very likely *will* lead to disastrous loss of data. + + +DISCLAIMER: + + I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE + USE OF THIS PROGRAM, HOWSOEVER CAUSED. + + Every compression of a file implies an assumption that the + compressed file can be decompressed to reproduce the original. + Great efforts in design, coding and testing have been made to + ensure that this program works correctly. However, the complexity + of the algorithms, and, in particular, the presence of various + special cases in the code which occur with very low but non-zero + probability make it impossible to rule out the possibility of bugs + remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS + PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER + SMALL, THAT THE DATA WILL NOT BE RECOVERABLE. + + That is not to say this program is inherently unreliable. Indeed, + I very much hope the opposite is true. bzip2 has been carefully + constructed and extensively tested. + + +PATENTS: + + To the best of my knowledge, bzip2 does not use any patented + algorithms. However, I do not have the resources to carry out + a patent search. Therefore I cannot give any guarantee of the + above statement. + +End of legalities. + + +WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ? + + * Approx 10% faster compression, 30% faster decompression + * -t (test mode) is a lot quicker + * Can decompress concatenated compressed files + * Programming interface, so programs can directly read/write .bz2 files + * Less restrictive (BSD-style) licensing + * Flag handling more compatible with GNU gzip + * Much more documentation, i.e., a proper user manual + * Hopefully, improved portability (at least of the library) + +WHAT'S NEW IN 0.9.5 ? + + * Compression speed is much less sensitive to the input + data than in previous versions. Specifically, the very + slow performance caused by repetitive data is fixed. + * Many small improvements in file and flag handling. + * A Y2K statement. + +WHAT'S NEW IN 1.0.0 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.2 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.3 ? + + See the CHANGES file. + + +I hope you find bzip2 useful. Feel free to contact me at + jseward@bzip.org +if you have any suggestions or queries. Many people mailed me with +comments, suggestions and patches after the releases of bzip-0.15, +bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and +1.0.2, and the changes in bzip2 are largely a result of this feedback. +I thank you for your comments. + +At least for the time being, bzip2's "home" is (or can be reached via) +http://www.bzip.org + +Julian Seward +jseward@bzip.org + +Cambridge, UK. + +18 July 1996 (version 0.15) +25 August 1996 (version 0.21) + 7 August 1997 (bzip2, version 0.1) +29 August 1997 (bzip2, version 0.1pl2) +23 August 1998 (bzip2, version 0.9.0) + 8 June 1999 (bzip2, version 0.9.5) + 4 Sept 1999 (bzip2, version 0.9.5d) + 5 May 2000 (bzip2, version 1.0pre8) +30 December 2001 (bzip2, version 1.0.2pre1) +15 February 2005 (bzip2, version 1.0.3) diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS b/contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS new file mode 100644 index 000000000..f1bc396b7 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS @@ -0,0 +1,39 @@ + +bzip2-1.0.3 should compile without problems on the vast majority of +platforms. Using the supplied Makefile, I've built and tested it +myself for x86-linux and x86_64-linux. With makefile.msc, Visual C++ +6.0 and nmake, you can build a native Win32 version too. Large file +support seems to work correctly on at least alpha-tru64unix and +x86-cygwin32 (on Windows 2000). + +When I say "large file" I mean a file of size 2,147,483,648 (2^31) +bytes or above. Many older OSs can't handle files above this size, +but many newer ones can. Large files are pretty huge -- most files +you'll encounter are not Large Files. + +Earlier versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide +variety of platforms without difficulty, and I hope this version will +continue in that tradition. However, in order to support large files, +I've had to include the define -D_FILE_OFFSET_BITS=64 in the Makefile. +This can cause problems. + +The technique of adding -D_FILE_OFFSET_BITS=64 to get large file +support is, as far as I know, the Recommended Way to get correct large +file support. For more details, see the Large File Support +Specification, published by the Large File Summit, at + http://ftp.sas.com/standards/large.file + +As a general comment, if you get compilation errors which you think +are related to large file support, try removing the above define from +the Makefile, ie, delete the line + BIGFILES=-D_FILE_OFFSET_BITS=64 +from the Makefile, and do 'make clean ; make'. This will give you a +version of bzip2 without large file support, which, for most +applications, is probably not a problem. + +Alternatively, try some of the platform-specific hints listed below. + +You can use the spewG.c program to generate huge files to test bzip2's +large file support, if you are feeling paranoid. Be aware though that +any compilation problems which affect bzip2 will also affect spewG.c, +alas. diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF b/contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF new file mode 100644 index 000000000..0ff209f44 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF @@ -0,0 +1,31 @@ +The script xmlproc.sh takes an xml file as input, +and processes it to create .pdf, .html or .ps output. +It uses format.pl, a perl script to format
 blocks nicely,
+ and add CDATA tags so writers do not have to use eg. < 
+
+The file "entities.xml" must be edited to reflect current
+version, year, etc.
+
+
+Usage:
+
+  xmlproc.sh -v manual.xml
+  Validates an xml file to ensure no dtd-compliance errors
+
+  xmlproc.sh -html manual.xml
+  Output: manual.html
+
+  xmlproc.sh -pdf manual.xml
+  Output: manual.pdf
+
+  xmlproc.sh -ps manual.xml
+  Output: manual.ps
+
+
+Notum bene: 
+- pdfxmltex barfs if given a filename with an underscore in it
+
+- xmltex won't work yet - there's a bug in passivetex
+    which we are all waiting for Sebastian to fix.
+  So we are going the xml -> pdf -> ps route for the time being,
+    using pdfxmltex.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO b/contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO
new file mode 100644
index 000000000..55fd56a2e
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO
@@ -0,0 +1,34 @@
+
+Y2K status of bzip2 and libbzip2, versions 0.1, 0.9.0 and 0.9.5
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Informally speaking:
+   bzip2 is a compression program built on top of libbzip2, 
+   a library which does the real work of compression and 
+   decompression.  As far as I am aware, libbzip2 does not have 
+   any date-related code at all.
+
+   bzip2 itself copies dates from source to destination files 
+   when compressing or decompressing, using the 'stat' and 'utime' 
+   UNIX system calls.  It doesn't examine, manipulate or store the 
+   dates in any way.  So as far as I can see, there shouldn't be any 
+   problem with bzip2 providing 'stat' and 'utime' work correctly 
+   on your system.
+
+   On non-unix platforms (those for which BZ_UNIX in bzip2.c is
+   not set to 1), bzip2 doesn't even do the date copying.
+
+   Overall, informally speaking, I don't think bzip2 or libbzip2 
+   have a Y2K problem.
+
+Formally speaking:
+   I am not prepared to offer you any assurance whatsoever 
+   regarding Y2K issues in my software.  You alone assume the 
+   entire risk of using the software.  The disclaimer of liability 
+   in the LICENSE file in the bzip2 source distribution continues 
+   to apply on this issue as with every other issue pertaining 
+   to the software.
+
+Julian Seward
+Cambridge, UK
+25 August 1999
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/blocksort.c b/contrib/vmap_extractor_v2/stormlib/bzip2/blocksort.c
new file mode 100644
index 000000000..33ec9f5dc
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/blocksort.c
@@ -0,0 +1,1141 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+
+  To get some idea how the block sorting algorithms in this file 
+  work, read my paper 
+     On the Performance of BWT Sorting Algorithms
+  in Proceedings of the IEEE Data Compression Conference 2000,
+  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
+  file implements the algorithm called  cache  in the paper.
+--*/
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+__inline__
+void fallbackSimpleSort ( UInt32* fmap, 
+                          UInt32* eclass, 
+                          Int32   lo, 
+                          Int32   hi )
+{
+   Int32 i, j, tmp;
+   UInt32 ec_tmp;
+
+   if (lo == hi) return;
+
+   if (hi - lo > 3) {
+      for ( i = hi-4; i >= lo; i-- ) {
+         tmp = fmap[i];
+         ec_tmp = eclass[tmp];
+         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+            fmap[j-4] = fmap[j];
+         fmap[j-4] = tmp;
+      }
+   }
+
+   for ( i = hi-1; i >= lo; i-- ) {
+      tmp = fmap[i];
+      ec_tmp = eclass[tmp];
+      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+         fmap[j-1] = fmap[j];
+      fmap[j-1] = tmp;
+   }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      fswap(fmap[yyp1], fmap[yyp2]);  \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+                       stackHi[sp] = hz; \
+                       sp++; }
+
+#define fpop(lz,hz) { sp--;              \
+                      lz = stackLo[sp];  \
+                      hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap, 
+                      UInt32* eclass,
+                      Int32   loSt, 
+                      Int32   hiSt )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m;
+   Int32 sp, lo, hi;
+   UInt32 med, r, r3;
+   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+   r = 0;
+
+   sp = 0;
+   fpush ( loSt, hiSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
+
+      fpop ( lo, hi );
+      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+         fallbackSimpleSort ( fmap, eclass, lo, hi );
+         continue;
+      }
+
+      /* Random partitioning.  Median of 3 sometimes fails to
+         avoid bad cases.  Median of 9 seems to help but 
+         looks rather expensive.  This too seems to work but
+         is cheaper.  Guidance for the magic constants 
+         7621 and 32768 is taken from Sedgewick's algorithms
+         book, chapter 35.
+      */
+      r = ((r * 7621) + 1) % 32768;
+      r3 = r % 3;
+      if (r3 == 0) med = eclass[fmap[lo]]; else
+      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+                   med = eclass[fmap[hi]];
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (1) {
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unLo], fmap[ltLo]); 
+               ltLo++; unLo++; 
+               continue; 
+            };
+            if (n > 0) break;
+            unLo++;
+         }
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unHi], fmap[gtHi]); 
+               gtHi--; unHi--; 
+               continue; 
+            };
+            if (n < 0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+      if (gtHi < ltLo) continue;
+
+      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      if (n - lo > hi - m) {
+         fpush ( lo, n );
+         fpush ( m, hi );
+      } else {
+         fpush ( m, hi );
+         fpush ( lo, n );
+      }
+   }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      eclass exists for [0 .. nblock-1]
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      All other areas of eclass destroyed
+      fmap [0 .. nblock-1] holds sorted order
+      bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define      WORD_BH(zz)  bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    UInt32* bhtab,
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   /*--
+      Initial 1-char radix sort to generate
+      initial fmap and initial BH bits.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        bucket sorting ...\n" );
+   for (i = 0; i < 257;    i++) ftab[i] = 0;
+   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i < nblock; i++) {
+      j = eclass8[i];
+      k = ftab[j] - 1;
+      ftab[j] = k;
+      fmap[k] = i;
+   }
+
+   nBhtab = 2 + (nblock / 32);
+   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+   /*--
+      Inductively refine the buckets.  Kind-of an
+      "exponential radix sort" (!), inspired by the
+      Manber-Myers suffix array construction algorithm.
+   --*/
+
+   /*-- set sentinel bits for block-end detection --*/
+   for (i = 0; i < 32; i++) { 
+      SET_BH(nblock + 2*i);
+      CLEAR_BH(nblock + 2*i + 1);
+   }
+
+   /*-- the log(N) loop --*/
+   H = 1;
+   while (1) {
+
+      if (verb >= 4) 
+         VPrintf1 ( "        depth %6d has ", H );
+
+      j = 0;
+      for (i = 0; i < nblock; i++) {
+         if (ISSET_BH(i)) j = i;
+         k = fmap[i] - H; if (k < 0) k += nblock;
+         eclass[k] = j;
+      }
+
+      nNotDone = 0;
+      r = -1;
+      while (1) {
+
+	 /*-- find the next non-singleton bucket --*/
+         k = r + 1;
+         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (ISSET_BH(k)) {
+            while (WORD_BH(k) == 0xffffffff) k += 32;
+            while (ISSET_BH(k)) k++;
+         }
+         l = k - 1;
+         if (l >= nblock) break;
+         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (!ISSET_BH(k)) {
+            while (WORD_BH(k) == 0x00000000) k += 32;
+            while (!ISSET_BH(k)) k++;
+         }
+         r = k - 1;
+         if (r >= nblock) break;
+
+         /*-- now [l, r] bracket current bucket --*/
+         if (r > l) {
+            nNotDone += (r - l + 1);
+            fallbackQSort3 ( fmap, eclass, l, r );
+
+            /*-- scan bucket and generate header bits-- */
+            cc = -1;
+            for (i = l; i <= r; i++) {
+               cc1 = eclass[fmap[i]];
+               if (cc != cc1) { SET_BH(i); cc = cc1; };
+            }
+         }
+      }
+
+      if (verb >= 4) 
+         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+      H *= 2;
+      if (H > nblock || nNotDone == 0) break;
+   }
+
+   /*-- 
+      Reconstruct the original block in
+      eclass8 [0 .. nblock-1], since the
+      previous phase destroyed it.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        reconstructing block ...\n" );
+   j = 0;
+   for (i = 0; i < nblock; i++) {
+      while (ftabCopy[j] == 0) j++;
+      ftabCopy[j]--;
+      eclass8[fmap[i]] = (UChar)j;
+   }
+   AssertH ( j < 256, 1005 );
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for "normal"       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32  i1, 
+               UInt32  i2,
+               UChar*  block, 
+               UInt16* quadrant,
+               UInt32  nblock,
+               Int32*  budget )
+{
+   Int32  k;
+   UChar  c1, c2;
+   UInt16 s1, s2;
+
+   AssertD ( i1 != i2, "mainGtU" );
+   /* 1 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 2 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 3 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 4 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 5 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 6 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 7 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 8 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 9 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 10 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 11 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 12 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+
+   k = nblock + 8;
+
+   do {
+      /* 1 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 2 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 3 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 4 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 5 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 6 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 7 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 8 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+
+      if (i1 >= nblock) i1 -= nblock;
+      if (i2 >= nblock) i2 -= nblock;
+
+      k -= 8;
+      (*budget)--;
+   }
+      while (k >= 0);
+
+   return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Knuth's increments seem to work better
+   than Incerpi-Sedgewick here.  Possibly
+   because the number of elems to sort is
+   usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+                   9841, 29524, 88573, 265720,
+                   797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+                      UChar*  block,
+                      UInt16* quadrant,
+                      Int32   nblock,
+                      Int32   lo, 
+                      Int32   hi, 
+                      Int32   d,
+                      Int32*  budget )
+{
+   Int32 i, j, h, bigN, hp;
+   UInt32 v;
+
+   bigN = hi - lo + 1;
+   if (bigN < 2) return;
+
+   hp = 0;
+   while (incs[hp] < bigN) hp++;
+   hp--;
+
+   for (; hp >= 0; hp--) {
+      h = incs[hp];
+
+      i = lo + h;
+      while (True) {
+
+         /*-- copy 1 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 2 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 3 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         if (*budget < 0) return;
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+/*--
+   The following is an implementation of
+   an elegant 3-way quicksort for strings,
+   described in a paper "Fast Algorithms for
+   Sorting and Searching Strings", by Robert
+   Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      mswap(ptr[yyp1], ptr[yyp2]);    \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+static 
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+   UChar t;
+   if (a > b) { t = a; a = b; b = t; };
+   if (b > c) { 
+      b = c;
+      if (a > b) b = a;
+   }
+   return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+                          stackHi[sp] = hz; \
+                          stackD [sp] = dz; \
+                          sp++; }
+
+#define mpop(lz,hz,dz) { sp--;             \
+                         lz = stackLo[sp]; \
+                         hz = stackHi[sp]; \
+                         dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz)                                        \
+   { Int32 tz;                                                  \
+     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+                  UChar*  block,
+                  UInt16* quadrant,
+                  Int32   nblock,
+                  Int32   loSt, 
+                  Int32   hiSt, 
+                  Int32   dSt,
+                  Int32*  budget )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+   Int32 sp, lo, hi, d;
+
+   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+   Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+   Int32 nextLo[3];
+   Int32 nextHi[3];
+   Int32 nextD [3];
+
+   sp = 0;
+   mpush ( loSt, hiSt, dSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
+
+      mpop ( lo, hi, d );
+      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
+          d > MAIN_QSORT_DEPTH_THRESH) {
+         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+         if (*budget < 0) return;
+         continue;
+      }
+
+      med = (Int32) 
+            mmed3 ( block[ptr[ lo         ]+d],
+                    block[ptr[ hi         ]+d],
+                    block[ptr[ (lo+hi)>>1 ]+d] );
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (True) {
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unLo]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unLo], ptr[ltLo]); 
+               ltLo++; unLo++; continue; 
+            };
+            if (n >  0) break;
+            unLo++;
+         }
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unHi]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unHi], ptr[gtHi]); 
+               gtHi--; unHi--; continue; 
+            };
+            if (n <  0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+      if (gtHi < ltLo) {
+         mpush(lo, hi, d+1 );
+         continue;
+      }
+
+      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+      mpush (nextLo[0], nextHi[0], nextD[0]);
+      mpush (nextLo[1], nextHi[1], nextD[1]);
+      mpush (nextLo[2], nextHi[2], nextD[2]);
+   }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > N_OVERSHOOT
+      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      All other areas of block32 destroyed
+      ftab [0 .. 65536 ] destroyed
+      ptr [0 .. nblock-1] holds sorted order
+      if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr, 
+                UChar*  block,
+                UInt16* quadrant, 
+                UInt32* ftab,
+                Int32   nblock,
+                Int32   verb,
+                Int32*  budget )
+{
+   Int32  i, j, k, ss, sb;
+   Int32  runningOrder[256];
+   Bool   bigDone[256];
+   Int32  copyStart[256];
+   Int32  copyEnd  [256];
+   UChar  c1;
+   Int32  numQSorted;
+   UInt16 s;
+   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
+
+   /*-- set up the 2-byte frequency table --*/
+   for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+   j = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+      quadrant[i-1] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+      ftab[j]++;
+      quadrant[i-2] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+      ftab[j]++;
+      quadrant[i-3] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+      ftab[j]++;
+   }
+   for (; i >= 0; i--) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+   }
+
+   /*-- (emphasises close relationship of block & quadrant) --*/
+   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+      block   [nblock+i] = block[i];
+      quadrant[nblock+i] = 0;
+   }
+
+   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
+
+   /*-- Complete the initial radix sort --*/
+   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+   s = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+      s = (s >> 8) | (block[i-1] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-1;
+      s = (s >> 8) | (block[i-2] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-2;
+      s = (s >> 8) | (block[i-3] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-3;
+   }
+   for (; i >= 0; i--) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+   }
+
+   /*--
+      Now ftab contains the first loc of every small bucket.
+      Calculate the running order, from smallest to largest
+      big bucket.
+   --*/
+   for (i = 0; i <= 255; i++) {
+      bigDone     [i] = False;
+      runningOrder[i] = i;
+   }
+
+   {
+      Int32 vv;
+      Int32 h = 1;
+      do h = 3 * h + 1; while (h <= 256);
+      do {
+         h = h / 3;
+         for (i = h; i <= 255; i++) {
+            vv = runningOrder[i];
+            j = i;
+            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+               runningOrder[j] = runningOrder[j-h];
+               j = j - h;
+               if (j <= (h - 1)) goto zero;
+            }
+            zero:
+            runningOrder[j] = vv;
+         }
+      } while (h != 1);
+   }
+
+   /*--
+      The main sorting loop.
+   --*/
+
+   numQSorted = 0;
+
+   for (i = 0; i <= 255; i++) {
+
+      /*--
+         Process big buckets, starting with the least full.
+         Basically this is a 3-step process in which we call
+         mainQSort3 to sort the small buckets [ss, j], but
+         also make a big effort to avoid the calls if we can.
+      --*/
+      ss = runningOrder[i];
+
+      /*--
+         Step 1:
+         Complete the big bucket [ss] by quicksorting
+         any unsorted small buckets [ss, j], for j != ss.  
+         Hopefully previous pointer-scanning phases have already
+         completed many of the small buckets [ss, j], so
+         we don't have to sort them at all.
+      --*/
+      for (j = 0; j <= 255; j++) {
+         if (j != ss) {
+            sb = (ss << 8) + j;
+            if ( ! (ftab[sb] & SETMASK) ) {
+               Int32 lo = ftab[sb]   & CLEARMASK;
+               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+               if (hi > lo) {
+                  if (verb >= 4)
+                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
+                                "done %d   this %d\n",
+                                ss, j, numQSorted, hi - lo + 1 );
+                  mainQSort3 ( 
+                     ptr, block, quadrant, nblock, 
+                     lo, hi, BZ_N_RADIX, budget 
+                  );   
+                  numQSorted += (hi - lo + 1);
+                  if (*budget < 0) return;
+               }
+            }
+            ftab[sb] |= SETMASK;
+         }
+      }
+
+      AssertH ( !bigDone[ss], 1006 );
+
+      /*--
+         Step 2:
+         Now scan this big bucket [ss] so as to synthesise the
+         sorted order for small buckets [t, ss] for all t,
+         including, magically, the bucket [ss,ss] too.
+         This will avoid doing Real Work in subsequent Step 1's.
+      --*/
+      {
+         for (j = 0; j <= 255; j++) {
+            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
+            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+         }
+         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1])
+               ptr[ copyStart[c1]++ ] = k;
+         }
+         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1]) 
+               ptr[ copyEnd[c1]-- ] = k;
+         }
+      }
+
+      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+                || 
+                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+                   Necessity for this case is demonstrated by compressing 
+                   a sequence of approximately 48.5 million of character 
+                   251; 1.0.0/1.0.1 will then die here. */
+                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+                1007 )
+
+      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+      /*--
+         Step 3:
+         The [ss] big bucket is now done.  Record this fact,
+         and update the quadrant descriptors.  Remember to
+         update quadrants in the overshoot area too, if
+         necessary.  The "if (i < 255)" test merely skips
+         this updating for the last bucket processed, since
+         updating for the last bucket is pointless.
+
+         The quadrant array provides a way to incrementally
+         cache sort orderings, as they appear, so as to 
+         make subsequent comparisons in fullGtU() complete
+         faster.  For repetitive blocks this makes a big
+         difference (but not big enough to be able to avoid
+         the fallback sorting mechanism, exponential radix sort).
+
+         The precise meaning is: at all times:
+
+            for 0 <= i < nblock and 0 <= j <= nblock
+
+            if block[i] != block[j], 
+
+               then the relative values of quadrant[i] and 
+                    quadrant[j] are meaningless.
+
+               else {
+                  if quadrant[i] < quadrant[j]
+                     then the string starting at i lexicographically
+                     precedes the string starting at j
+
+                  else if quadrant[i] > quadrant[j]
+                     then the string starting at j lexicographically
+                     precedes the string starting at i
+
+                  else
+                     the relative ordering of the strings starting
+                     at i and j has not yet been determined.
+               }
+      --*/
+      bigDone[ss] = True;
+
+      if (i < 255) {
+         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
+         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+         Int32 shifts   = 0;
+
+         while ((bbSize >> shifts) > 65534) shifts++;
+
+         for (j = bbSize-1; j >= 0; j--) {
+            Int32 a2update     = ptr[bbStart + j];
+            UInt16 qVal        = (UInt16)(j >> shifts);
+            quadrant[a2update] = qVal;
+            if (a2update < BZ_N_OVERSHOOT)
+               quadrant[a2update + nblock] = qVal;
+         }
+         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+      }
+
+   }
+
+   if (verb >= 4)
+      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
+                 nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)arr2)  [0 .. nblock-1] holds block
+      arr1 exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)arr2) [0 .. nblock-1] holds block
+      All other areas of block destroyed
+      ftab [ 0 .. 65536 ] destroyed
+      arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+   UInt32* ptr    = s->ptr; 
+   UChar*  block  = s->block;
+   UInt32* ftab   = s->ftab;
+   Int32   nblock = s->nblock;
+   Int32   verb   = s->verbosity;
+   Int32   wfact  = s->workFactor;
+   UInt16* quadrant;
+   Int32   budget;
+   Int32   budgetInit;
+   Int32   i;
+
+   if (nblock < 10000) {
+      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+   } else {
+      /* Calculate the location for quadrant, remembering to get
+         the alignment right.  Assumes that &(block[0]) is at least
+         2-byte aligned -- this should be ok since block is really
+         the first section of arr2.
+      */
+      i = nblock+BZ_N_OVERSHOOT;
+      if (i & 1) i++;
+      quadrant = (UInt16*)(&(block[i]));
+
+      /* (wfact-1) / 3 puts the default-factor-30
+         transition point at very roughly the same place as 
+         with v0.1 and v0.9.0.  
+         Not that it particularly matters any more, since the
+         resulting compressed stream is now the same regardless
+         of whether or not we use the main sort or fallback sort.
+      */
+      if (wfact < 1  ) wfact = 1;
+      if (wfact > 100) wfact = 100;
+      budgetInit = nblock * ((wfact-1) / 3);
+      budget = budgetInit;
+
+      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+      if (verb >= 3) 
+         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
+                    budgetInit - budget,
+                    nblock, 
+                    (float)(budgetInit - budget) /
+                    (float)(nblock==0 ? 1 : nblock) ); 
+      if (budget < 0) {
+         if (verb >= 2) 
+            VPrintf0 ( "    too repetitive; using fallback"
+                       " sorting algorithm\n" );
+         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+      }
+   }
+
+   s->origPtr = -1;
+   for (i = 0; i < s->nblock; i++)
+      if (ptr[i] == 0)
+         { s->origPtr = i; break; };
+
+   AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl
new file mode 100644
index 000000000..66fcd6fe0
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl
@@ -0,0 +1,39 @@
+ 
+
+
+
+ 
+
+
+
+ 
+ 
+   
+    
+      
+     
+  
+
+
+
+
+set       toc,title
+book      toc,title,figure,table,example,equation
+chapter   toc,title
+section   toc
+sect1     toc
+sect2     toc
+sect3     toc
+sect4     nop
+sect5     nop
+qandaset  toc
+qandadiv  nop
+appendix  toc,title
+article/appendix  nop
+article   toc,title
+preface   toc,title
+reference toc,title
+
+
+
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl
new file mode 100644
index 000000000..7f2a7674f
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl
@@ -0,0 +1,257 @@
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+      
+     
+   
+
+
+
+
+ 
+
+
+
+
+
+
+  
+
+
+
+
+  blue
+
+
+
+
+  
+    
+  
+
+
+
+  
+    
+  
+
+
+
+
+  
+  
+  
+    
+      
+    
+  
+  
+    
+      
+        
+          
+          
+          
+        
+      
+    
+    
+          
+    
+  
+  
+    
+      
+        
+      
+    
+    
+      
+        
+      
+    
+  
+
+
+
+
+  
+  
+  
+    
+      
+        
+      
+    
+    
+          
+    
+  
+  
+    
+      
+        
+      
+    
+    
+      
+        
+      
+    
+  
+
+
+
+
+
+  
+    
+  
+    
+  
+  
+    
+      
+    
+  
+
+
+
+
+
+  
+  
+  
+  
+    
+      0pt
+    
+  
+  
+    
+      
+      
+      
+        
+          
+            baseline
+             
+               
+            
+          
+          
+            baseline
+            
+              
+                
+                
+                
+                
+              
+            
+          
+        
+      
+    
+  
+  
+  
+    
+      
+    
+    
+      
+    
+    
+      
+    
+  
+
+
+
+
+
+  
+  
+  
+  
+    
+      0pt
+    
+  
+  
+    
+      
+        
+        
+        
+      
+      
+      
+      
+        
+          
+            baseline
+            
+               
+            
+          
+          
+            baseline
+            
+              
+                
+                
+                
+                
+              
+            
+          
+        
+      
+    
+  
+  
+  
+    
+      
+    
+    
+      
+    
+    
+      
+    
+  
+
+
+
+
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl
new file mode 100644
index 000000000..1785fffbc
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl
@@ -0,0 +1,20 @@
+ 
+ ]>
+
+
+
+
+
+
+
+
+
+
+  
+  
+
+
+
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff b/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff
new file mode 100644
index 000000000..3c2eb859f
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff
@@ -0,0 +1,76 @@
+#!/bin/sh
+# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
+
+# Bzcmp/diff wrapped for bzip2, 
+# adapted from zdiff by Philippe Troin  for Debian GNU/Linux.
+
+# Bzcmp and bzdiff are used to invoke the cmp or the  diff  pro-
+# gram  on compressed files.  All options specified are passed
+# directly to cmp or diff.  If only 1 file is specified,  then
+# the  files  compared  are file1 and an uncompressed file1.gz.
+# If two files are specified, then they are  uncompressed  (if
+# necessary) and fed to cmp or diff.  The exit status from cmp
+# or diff is preserved.
+
+PATH="/usr/bin:$PATH"; export PATH
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+  *cmp) comp=${CMP-cmp}   ;;
+  *)    comp=${DIFF-diff} ;;
+esac
+
+OPTIONS=
+FILES=
+for ARG
+do
+    case "$ARG" in
+    -*)	OPTIONS="$OPTIONS $ARG";;
+     *)	if test -f "$ARG"; then
+            FILES="$FILES $ARG"
+        else
+            echo "${prog}: $ARG not found or not a regular file"
+	    exit 1
+        fi ;;
+    esac
+done
+if test -z "$FILES"; then
+	echo "Usage: $prog [${comp}_options] file [file]"
+	exit 1
+fi
+tmp=`tempfile -d /tmp -p bz` || {
+      echo 'cannot create a temporary file' >&2
+      exit 1
+}
+set $FILES
+if test $# -eq 1; then
+	FILE=`echo "$1" | sed 's/.bz2$//'`
+	bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
+	STAT="$?"
+
+elif test $# -eq 2; then
+	case "$1" in
+        *.bz2)
+                case "$2" in
+	        *.bz2)
+			F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
+                        bzip2 -cdfq "$2" > $tmp
+                        bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp
+                        STAT="$?"
+			/bin/rm -f $tmp;;
+
+                *)      bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
+                        STAT="$?";;
+                esac;;
+        *)      case "$2" in
+	        *.bz2)
+                        bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
+                        STAT="$?";;
+                *)      $comp $OPTIONS "$1" "$2"
+                        STAT="$?";;
+                esac;;
+	esac
+        exit "$STAT"
+else
+	echo "Usage: $prog [${comp}_options] file [file]"
+	exit 1
+fi
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.1
new file mode 100644
index 000000000..adb7a8e72
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.1
@@ -0,0 +1,47 @@
+\"Shamelessly copied from zmore.1 by Philippe Troin 
+\"for Debian GNU/Linux
+.TH BZDIFF 1
+.SH NAME
+bzcmp, bzdiff \- compare bzip2 compressed files
+.SH SYNOPSIS
+.B bzcmp
+[ cmp_options ] file1
+[ file2 ]
+.br
+.B bzdiff
+[ diff_options ] file1
+[ file2 ]
+.SH DESCRIPTION
+.I  Bzcmp
+and 
+.I bzdiff
+are used to invoke the
+.I cmp
+or the
+.I diff
+program on bzip2 compressed files.  All options specified are passed
+directly to
+.I cmp
+or
+.IR diff "."
+If only 1 file is specified, then the files compared are
+.I file1
+and an uncompressed
+.IR file1 ".bz2."
+If two files are specified, then they are uncompressed if necessary and fed to
+.I cmp
+or
+.IR diff "."
+The exit status from 
+.I cmp
+or
+.I diff
+is preserved.
+.SH "SEE ALSO"
+cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1)
+.SH BUGS
+Messages from the
+.I cmp
+or
+.I diff
+programs refer to temporary filenames instead of those specified.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep b/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep
new file mode 100644
index 000000000..dbfc00e8d
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+# Bzgrep wrapped for bzip2, 
+# adapted from zgrep by Philippe Troin  for Debian GNU/Linux.
+## zgrep notice:
+## zgrep -- a wrapper around a grep program that decompresses files as needed
+## Adapted from a version sent by Charles Levert 
+
+PATH="/usr/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+	*egrep)	grep=${EGREP-egrep}	;;
+	*fgrep)	grep=${FGREP-fgrep}	;;
+	*)	grep=${GREP-grep}	;;
+esac
+pat=""
+while test $# -ne 0; do
+  case "$1" in
+  -e | -f) opt="$opt $1"; shift; pat="$1"
+           if test "$grep" = grep; then  # grep is buggy with -e on SVR4
+             grep=egrep
+           fi;;
+  -A | -B) opt="$opt $1 $2"; shift;;
+  -*)	   opt="$opt $1";;
+   *)      if test -z "$pat"; then
+	     pat="$1"
+	   else
+	     break;
+           fi;;
+  esac
+  shift
+done
+
+if test -z "$pat"; then
+  echo "grep through bzip2 files"
+  echo "usage: $prog [grep_options] pattern [files]"
+  exit 1
+fi
+
+list=0
+silent=0
+op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
+case "$op" in
+  *l*) list=1
+esac
+case "$op" in
+  *h*) silent=1
+esac
+
+if test $# -eq 0; then
+  bzip2 -cdfq | $grep $opt "$pat"
+  exit $?
+fi
+
+res=0
+for i do
+  if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
+  if test $list -eq 1; then
+    bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
+    r=$?
+  elif test $# -eq 1 -o $silent -eq 1; then
+    bzip2 -cdfq "$i" | $grep $opt "$pat"
+    r=$?
+  else
+    bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${i}:|"
+    r=$?
+  fi
+  test "$r" -ne 0 && res="$r"
+done
+exit $res
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.1
new file mode 100644
index 000000000..930af8c7f
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.1
@@ -0,0 +1,56 @@
+\"Shamelessly copied from zmore.1 by Philippe Troin 
+\"for Debian GNU/Linux
+.TH BZGREP 1
+.SH NAME
+bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression
+.SH SYNOPSIS
+.B bzgrep
+[ grep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.br
+.B bzegrep
+[ egrep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.br
+.B bzfgrep
+[ fgrep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.SH DESCRIPTION
+.IR  Bzgrep
+is used to invoke the
+.I grep
+on bzip2-compressed files. All options specified are passed directly to
+.I grep.
+If no file is specified, then the standard input is decompressed
+if necessary and fed to grep.
+Otherwise the given files are uncompressed if necessary and fed to
+.I grep.
+.PP
+If
+.I bzgrep
+is invoked as
+.I bzegrep
+or
+.I bzfgrep
+then
+.I egrep
+or
+.I fgrep
+is used instead of
+.I grep.
+If the GREP environment variable is set,
+.I bzgrep
+uses it as the
+.I grep
+program to be invoked. For example:
+
+    for sh:  GREP=fgrep  bzgrep string files
+    for csh: (setenv GREP fgrep; bzgrep string files)
+.SH AUTHOR
+Charles Levert (charles@comm.polymtl.ca). Adapted to bzip2 by Philippe
+Troin  for Debian GNU/Linux.
+.SH "SEE ALSO"
+grep(1), egrep(1), fgrep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css
new file mode 100644
index 000000000..43193d8db
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css
@@ -0,0 +1,74 @@
+/* Colours:
+#74240f  dark brown      h1, h2, h3, h4
+#336699  medium blue     links
+#339999  turquoise       link hover colour
+#202020  almost black    general text
+#761596  purple          md5sum text
+#626262  dark gray       pre border
+#eeeeee  very light gray pre background
+#f2f2f9  very light blue nav table background
+#3366cc  medium blue     nav table border
+*/
+
+a, a:link, a:visited, a:active { color: #336699; }
+a:hover { color: #339999; }
+
+body { font: 80%/126% sans-serif; }
+h1, h2, h3, h4 { color: #74240f; }
+
+dt { color: #336699; font-weight: bold }
+dd { 
+ margin-left: 1.5em; 
+ padding-bottom: 0.8em;
+}
+
+/* -- ruler -- */
+div.hr_blue { 
+  height:  3px; 
+  background:#ffffff url("/images/hr_blue.png") repeat-x; }
+div.hr_blue hr { display:none; }
+
+/* release styles */
+#release p { margin-top: 0.4em; }
+#release .md5sum { color: #761596; }
+
+
+/* ------ styles for docs|manuals|howto ------ */
+/* -- lists -- */
+ul  { 
+ margin:     0px 4px 16px 16px;
+ padding:    0px;
+ list-style: url("/images/li-blue.png"); 
+}
+ul li { 
+ margin-bottom: 10px;
+}
+ul ul	{ 
+ list-style-type:  none; 
+ list-style-image: none; 
+ margin-left:      0px; 
+}
+
+/* header / footer nav tables */
+table.nav {
+ border:     solid 1px #3366cc;
+ background: #f2f2f9;
+ background-color: #f2f2f9;
+ margin-bottom: 0.5em;
+}
+/* don't have underlined links in chunked nav menus */
+table.nav a { text-decoration: none; }
+table.nav a:hover { text-decoration: underline; }
+table.nav td { font-size: 85%; }
+
+code, tt, pre { font-size: 120%; }
+code, tt { color: #761596; }
+
+div.literallayout, pre.programlisting, pre.screen {
+ color:      #000000;
+ padding:    0.5em;
+ background: #eeeeee;
+ border:     1px solid #626262;
+ background-color: #eeeeee;
+ margin: 4px 0px 4px 0px; 
+}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1
new file mode 100644
index 000000000..d2c066156
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1
@@ -0,0 +1,454 @@
+.PU
+.TH bzip2 1
+.SH NAME
+bzip2, bunzip2 \- a block-sorting file compressor, v1.0.3
+.br
+bzcat \- decompresses files to stdout
+.br
+bzip2recover \- recovers data from damaged bzip2 files
+
+.SH SYNOPSIS
+.ll +8
+.B bzip2
+.RB [ " \-cdfkqstvzVL123456789 " ]
+[
+.I "filenames \&..."
+]
+.ll -8
+.br
+.B bunzip2
+.RB [ " \-fkvsVL " ]
+[ 
+.I "filenames \&..."
+]
+.br
+.B bzcat
+.RB [ " \-s " ]
+[ 
+.I "filenames \&..."
+]
+.br
+.B bzip2recover
+.I "filename"
+
+.SH DESCRIPTION
+.I bzip2
+compresses files using the Burrows-Wheeler block sorting
+text compression algorithm, and Huffman coding.  Compression is
+generally considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of the PPM
+family of statistical compressors.
+
+The command-line options are deliberately very similar to 
+those of 
+.I GNU gzip, 
+but they are not identical.
+
+.I bzip2
+expects a list of file names to accompany the
+command-line flags.  Each file is replaced by a compressed version of
+itself, with the name "original_name.bz2".  
+Each compressed file
+has the same modification date, permissions, and, when possible,
+ownership as the corresponding original, so that these properties can
+be correctly restored at decompression time.  File name handling is
+naive in the sense that there is no mechanism for preserving original
+file names, permissions, ownerships or dates in filesystems which lack
+these concepts, or have serious file name length restrictions, such as
+MS-DOS.
+
+.I bzip2
+and
+.I bunzip2
+will by default not overwrite existing
+files.  If you want this to happen, specify the \-f flag.
+
+If no file names are specified,
+.I bzip2
+compresses from standard
+input to standard output.  In this case,
+.I bzip2
+will decline to
+write compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.
+
+.I bunzip2
+(or
+.I bzip2 \-d) 
+decompresses all
+specified files.  Files which were not created by 
+.I bzip2
+will be detected and ignored, and a warning issued.  
+.I bzip2
+attempts to guess the filename for the decompressed file 
+from that of the compressed file as follows:
+
+       filename.bz2    becomes   filename
+       filename.bz     becomes   filename
+       filename.tbz2   becomes   filename.tar
+       filename.tbz    becomes   filename.tar
+       anyothername    becomes   anyothername.out
+
+If the file does not end in one of the recognised endings, 
+.I .bz2, 
+.I .bz, 
+.I .tbz2
+or
+.I .tbz, 
+.I bzip2 
+complains that it cannot
+guess the name of the original file, and uses the original name
+with
+.I .out
+appended.
+
+As with compression, supplying no
+filenames causes decompression from 
+standard input to standard output.
+
+.I bunzip2 
+will correctly decompress a file which is the
+concatenation of two or more compressed files.  The result is the
+concatenation of the corresponding uncompressed files.  Integrity
+testing (\-t) 
+of concatenated 
+compressed files is also supported.
+
+You can also compress or decompress files to the standard output by
+giving the \-c flag.  Multiple files may be compressed and
+decompressed like this.  The resulting outputs are fed sequentially to
+stdout.  Compression of multiple files 
+in this manner generates a stream
+containing multiple compressed file representations.  Such a stream
+can be decompressed correctly only by
+.I bzip2 
+version 0.9.0 or
+later.  Earlier versions of
+.I bzip2
+will stop after decompressing
+the first file in the stream.
+
+.I bzcat
+(or
+.I bzip2 -dc) 
+decompresses all specified files to
+the standard output.
+
+.I bzip2
+will read arguments from the environment variables
+.I BZIP2
+and
+.I BZIP,
+in that order, and will process them
+before any arguments read from the command line.  This gives a 
+convenient way to supply default arguments.
+
+Compression is always performed, even if the compressed 
+file is slightly
+larger than the original.  Files of less than about one hundred bytes
+tend to get larger, since the compression mechanism has a constant
+overhead in the region of 50 bytes.  Random data (including the output
+of most file compressors) is coded at about 8.05 bits per byte, giving
+an expansion of around 0.5%.
+
+As a self-check for your protection, 
+.I 
+bzip2
+uses 32-bit CRCs to
+make sure that the decompressed version of a file is identical to the
+original.  This guards against corruption of the compressed data, and
+against undetected bugs in
+.I bzip2
+(hopefully very unlikely).  The
+chances of data corruption going undetected is microscopic, about one
+chance in four billion for each file processed.  Be aware, though, that
+the check occurs upon decompression, so it can only tell you that
+something is wrong.  It can't help you 
+recover the original uncompressed
+data.  You can use 
+.I bzip2recover
+to try to recover data from
+damaged files.
+
+Return values: 0 for a normal exit, 1 for environmental problems (file
+not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
+compressed file, 3 for an internal consistency error (eg, bug) which
+caused
+.I bzip2
+to panic.
+
+.SH OPTIONS
+.TP
+.B \-c --stdout
+Compress or decompress to standard output.
+.TP
+.B \-d --decompress
+Force decompression.  
+.I bzip2, 
+.I bunzip2 
+and
+.I bzcat 
+are
+really the same program, and the decision about what actions to take is
+done on the basis of which name is used.  This flag overrides that
+mechanism, and forces 
+.I bzip2
+to decompress.
+.TP
+.B \-z --compress
+The complement to \-d: forces compression, regardless of the
+invocation name.
+.TP
+.B \-t --test
+Check integrity of the specified file(s), but don't decompress them.
+This really performs a trial decompression and throws away the result.
+.TP
+.B \-f --force
+Force overwrite of output files.  Normally,
+.I bzip2 
+will not overwrite
+existing output files.  Also forces 
+.I bzip2 
+to break hard links
+to files, which it otherwise wouldn't do.
+
+bzip2 normally declines to decompress files which don't have the
+correct magic header bytes.  If forced (-f), however, it will pass
+such files through unmodified.  This is how GNU gzip behaves.
+.TP
+.B \-k --keep
+Keep (don't delete) input files during compression
+or decompression.
+.TP
+.B \-s --small
+Reduce memory usage, for compression, decompression and testing.  Files
+are decompressed and tested using a modified algorithm which only
+requires 2.5 bytes per block byte.  This means any file can be
+decompressed in 2300k of memory, albeit at about half the normal speed.
+
+During compression, \-s selects a block size of 200k, which limits
+memory use to around the same figure, at the expense of your compression
+ratio.  In short, if your machine is low on memory (8 megabytes or
+less), use \-s for everything.  See MEMORY MANAGEMENT below.
+.TP
+.B \-q --quiet
+Suppress non-essential warning messages.  Messages pertaining to
+I/O errors and other critical events will not be suppressed.
+.TP
+.B \-v --verbose
+Verbose mode -- show the compression ratio for each file processed.
+Further \-v's increase the verbosity level, spewing out lots of
+information which is primarily of interest for diagnostic purposes.
+.TP
+.B \-L --license -V --version
+Display the software version, license terms and conditions.
+.TP
+.B \-1 (or \-\-fast) to \-9 (or \-\-best)
+Set the block size to 100 k, 200 k ..  900 k when compressing.  Has no
+effect when decompressing.  See MEMORY MANAGEMENT below.
+The \-\-fast and \-\-best aliases are primarily for GNU gzip 
+compatibility.  In particular, \-\-fast doesn't make things
+significantly faster.  
+And \-\-best merely selects the default behaviour.
+.TP
+.B \--
+Treats all subsequent arguments as file names, even if they start
+with a dash.  This is so you can handle files with names beginning
+with a dash, for example: bzip2 \-- \-myfilename.
+.TP
+.B \--repetitive-fast --repetitive-best
+These flags are redundant in versions 0.9.5 and above.  They provided
+some coarse control over the behaviour of the sorting algorithm in
+earlier versions, which was sometimes useful.  0.9.5 and above have an
+improved algorithm which renders these flags irrelevant.
+
+.SH MEMORY MANAGEMENT
+.I bzip2 
+compresses large files in blocks.  The block size affects
+both the compression ratio achieved, and the amount of memory needed for
+compression and decompression.  The flags \-1 through \-9
+specify the block size to be 100,000 bytes through 900,000 bytes (the
+default) respectively.  At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+.I bunzip2
+then allocates itself just enough memory to decompress
+the file.  Since block sizes are stored in compressed files, it follows
+that the flags \-1 to \-9 are irrelevant to and so ignored
+during decompression.
+
+Compression and decompression requirements, 
+in bytes, can be estimated as:
+
+       Compression:   400k + ( 8 x block size )
+
+       Decompression: 100k + ( 4 x block size ), or
+                      100k + ( 2.5 x block size )
+
+Larger block sizes give rapidly diminishing marginal returns.  Most of
+the compression comes from the first two or three hundred k of block
+size, a fact worth bearing in mind when using
+.I bzip2
+on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block size.
+
+For files compressed with the default 900k block size,
+.I bunzip2
+will require about 3700 kbytes to decompress.  To support decompression
+of any file on a 4 megabyte machine, 
+.I bunzip2
+has an option to
+decompress using approximately half this amount of memory, about 2300
+kbytes.  Decompression speed is also halved, so you should use this
+option only where necessary.  The relevant flag is -s.
+
+In general, try and use the largest block size memory constraints allow,
+since that maximises the compression achieved.  Compression and
+decompression speed are virtually unaffected by block size.
+
+Another significant point applies to files which fit in a single block
+-- that means most files you'd encounter using a large block size.  The
+amount of real memory touched is proportional to the size of the file,
+since the file is smaller than a block.  For example, compressing a file
+20,000 bytes long with the flag -9 will cause the compressor to
+allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
+kbytes of it.  Similarly, the decompressor will allocate 3700k but only
+touch 100k + 20000 * 4 = 180 kbytes.
+
+Here is a table which summarises the maximum memory usage for different
+block sizes.  Also recorded is the total compressed size for 14 files of
+the Calgary Text Compression Corpus totalling 3,141,622 bytes.  This
+column gives some feel for how compression varies with block size.
+These figures tend to understate the advantage of larger block sizes for
+larger files, since the Corpus is dominated by smaller files.
+
+           Compress   Decompress   Decompress   Corpus
+    Flag     usage      usage       -s usage     Size
+
+     -1      1200k       500k         350k      914704
+     -2      2000k       900k         600k      877703
+     -3      2800k      1300k         850k      860338
+     -4      3600k      1700k        1100k      846899
+     -5      4400k      2100k        1350k      845160
+     -6      5200k      2500k        1600k      838626
+     -7      6100k      2900k        1850k      834096
+     -8      6800k      3300k        2100k      828642
+     -9      7600k      3700k        2350k      828642
+
+.SH RECOVERING DATA FROM DAMAGED FILES
+.I bzip2
+compresses files in blocks, usually 900kbytes long.  Each
+block is handled independently.  If a media or transmission error causes
+a multi-block .bz2
+file to become damaged, it may be possible to
+recover data from the undamaged blocks in the file.
+
+The compressed representation of each block is delimited by a 48-bit
+pattern, which makes it possible to find the block boundaries with
+reasonable certainty.  Each block also carries its own 32-bit CRC, so
+damaged blocks can be distinguished from undamaged ones.
+
+.I bzip2recover
+is a simple program whose purpose is to search for
+blocks in .bz2 files, and write each block out into its own .bz2 
+file.  You can then use
+.I bzip2 
+\-t
+to test the
+integrity of the resulting files, and decompress those which are
+undamaged.
+
+.I bzip2recover
+takes a single argument, the name of the damaged file, 
+and writes a number of files "rec00001file.bz2",
+"rec00002file.bz2", etc, containing the  extracted  blocks.
+The  output  filenames  are  designed  so  that the use of
+wildcards in subsequent processing -- for example,  
+"bzip2 -dc  rec*file.bz2 > recovered_data" -- processes the files in
+the correct order.
+
+.I bzip2recover
+should be of most use dealing with large .bz2
+files,  as  these will contain many blocks.  It is clearly
+futile to use it on damaged single-block  files,  since  a
+damaged  block  cannot  be recovered.  If you wish to minimise 
+any potential data loss through media  or  transmission errors, 
+you might consider compressing with a smaller
+block size.
+
+.SH PERFORMANCE NOTES
+The sorting phase of compression gathers together similar strings in the
+file.  Because of this, files containing very long runs of repeated
+symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
+compress more slowly than normal.  Versions 0.9.5 and above fare much
+better than previous versions in this respect.  The ratio between
+worst-case and average-case compression time is in the region of 10:1.
+For previous versions, this figure was more like 100:1.  You can use the
+\-vvvv option to monitor progress in great detail, if you want.
+
+Decompression speed is unaffected by these phenomena.
+
+.I bzip2
+usually allocates several megabytes of memory to operate
+in, and then charges all over it in a fairly random fashion.  This means
+that performance, both for compressing and decompressing, is largely
+determined by the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss rate have
+been observed to give disproportionately large performance improvements.
+I imagine 
+.I bzip2
+will perform best on machines with very large caches.
+
+.SH CAVEATS
+I/O error messages are not as helpful as they could be.
+.I bzip2
+tries hard to detect I/O errors and exit cleanly, but the details of
+what the problem is sometimes seem rather misleading.
+
+This manual page pertains to version 1.0.3 of
+.I bzip2.  
+Compressed data created by this version is entirely forwards and
+backwards compatible with the previous public releases, versions
+0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and 1.0.2, but with the following
+exception: 0.9.0 and above can correctly decompress multiple
+concatenated compressed files.  0.1pl2 cannot do this; it will stop
+after decompressing just the first file in the stream.
+
+.I bzip2recover
+versions prior to 1.0.2 used 32-bit integers to represent
+bit positions in compressed files, so they could not handle compressed
+files more than 512 megabytes long.  Versions 1.0.2 and above use
+64-bit ints on some platforms which support them (GNU supported
+targets, and Windows).  To establish whether or not bzip2recover was
+built with such a limitation, run it without arguments.  In any event
+you can build yourself an unlimited version if you can recompile it
+with MaybeUInt64 set to be an unsigned 64-bit integer.
+
+
+
+.SH AUTHOR
+Julian Seward, jsewardbzip.org.
+
+http://www.bzip.org
+
+The ideas embodied in
+.I bzip2
+are due to (at least) the following
+people: Michael Burrows and David Wheeler (for the block sorting
+transformation), David Wheeler (again, for the Huffman coder), Peter
+Fenwick (for the structured coding model in the original
+.I bzip,
+and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+.I bzip).  
+I am much
+indebted for their help, support and advice.  See the manual in the
+source distribution for pointers to sources of documentation.  Christian
+von Roques encouraged me to look for faster sorting algorithms, so as to
+speed up compression.  Bela Lubkin encouraged me to improve the
+worst-case compression performance.  
+Donna Robinson XMLised the documentation.
+The bz* scripts are derived from those of GNU gzip.
+Many people sent patches, helped
+with portability problems, lent machines, gave advice and were generally
+helpful.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted
new file mode 100644
index 000000000..129ca835c
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted
@@ -0,0 +1,399 @@
+bzip2(1)                                                 bzip2(1)
+
+
+
+NNAAMMEE
+       bzip2, bunzip2 − a blockâ€sorting file compressor, v1.0.3
+       bzcat − decompresses files to stdout
+       bzip2recover − recovers data from damaged bzip2 files
+
+
+SSYYNNOOPPSSIISS
+       bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
+       bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
+       bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
+       bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
+
+
+DDEESSCCRRIIPPTTIIOONN
+       _b_z_i_p_2  compresses  files  using  the Burrowsâ€Wheeler block
+       sorting text compression algorithm,  and  Huffman  coding.
+       Compression  is  generally  considerably  better than that
+       achieved by more conventional LZ77/LZ78â€based compressors,
+       and  approaches  the performance of the PPM family of sta­
+       tistical compressors.
+
+       The commandâ€line options are deliberately very similar  to
+       those of _G_N_U _g_z_i_p_, but they are not identical.
+
+       _b_z_i_p_2  expects  a list of file names to accompany the com­
+       mandâ€line flags.  Each file is replaced  by  a  compressed
+       version  of  itself,  with  the  name "original_name.bz2".
+       Each compressed file has the same modification date,  per­
+       missions, and, when possible, ownership as the correspond­
+       ing original, so that these properties  can  be  correctly
+       restored  at  decompression  time.   File name handling is
+       naive in the sense that there is no mechanism for preserv­
+       ing  original file names, permissions, ownerships or dates
+       in filesystems which lack these concepts, or have  serious
+       file name length restrictions, such as MSâ€DOS.
+
+       _b_z_i_p_2  and  _b_u_n_z_i_p_2 will by default not overwrite existing
+       files.  If you want this to happen, specify the −f flag.
+
+       If no file names  are  specified,  _b_z_i_p_2  compresses  from
+       standard  input  to  standard output.  In this case, _b_z_i_p_2
+       will decline to write compressed output to a terminal,  as
+       this  would  be  entirely  incomprehensible  and therefore
+       pointless.
+
+       _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses  all  specified  files.
+       Files which were not created by _b_z_i_p_2 will be detected and
+       ignored, and a warning issued.  _b_z_i_p_2  attempts  to  guess
+       the  filename  for  the decompressed file from that of the
+       compressed file as follows:
+
+              filename.bz2    becomes   filename
+              filename.bz     becomes   filename
+              filename.tbz2   becomes   filename.tar
+              filename.tbz    becomes   filename.tar
+              anyothername    becomes   anyothername.out
+
+       If the file does not end in one of the recognised endings,
+       _._b_z_2_,  _._b_z_,  _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
+       guess the name of the original file, and uses the original
+       name with _._o_u_t appended.
+
+       As  with compression, supplying no filenames causes decom­
+       pression from standard input to standard output.
+
+       _b_u_n_z_i_p_2 will correctly decompress a file which is the con­
+       catenation of two or more compressed files.  The result is
+       the concatenation of the corresponding uncompressed files.
+       Integrity testing (−t) of concatenated compressed files is
+       also supported.
+
+       You can also compress or decompress files to the  standard
+       output  by giving the −c flag.  Multiple files may be com­
+       pressed and decompressed like this.  The resulting outputs
+       are  fed  sequentially to stdout.  Compression of multiple
+       files in this manner generates a stream containing  multi­
+       ple compressed file representations.  Such a stream can be
+       decompressed correctly only  by  _b_z_i_p_2  version  0.9.0  or
+       later.   Earlier  versions of _b_z_i_p_2 will stop after decom­
+       pressing the first file in the stream.
+
+       _b_z_c_a_t (or _b_z_i_p_2 _â€_d_c_) decompresses all specified  files  to
+       the standard output.
+
+       _b_z_i_p_2  will  read arguments from the environment variables
+       _B_Z_I_P_2 and _B_Z_I_P_, in  that  order,  and  will  process  them
+       before  any  arguments  read  from the command line.  This
+       gives a convenient way to supply default arguments.
+
+       Compression is always performed, even  if  the  compressed
+       file  is slightly larger than the original.  Files of less
+       than about one hundred bytes tend to get larger, since the
+       compression  mechanism  has  a  constant  overhead  in the
+       region of 50 bytes.  Random data (including the output  of
+       most  file  compressors)  is  coded at about 8.05 bits per
+       byte, giving an expansion of around 0.5%.
+
+       As a selfâ€check for your  protection,  _b_z_i_p_2  uses  32â€bit
+       CRCs  to make sure that the decompressed version of a file
+       is identical to the original.  This guards against corrup­
+       tion  of  the compressed data, and against undetected bugs
+       in _b_z_i_p_2 (hopefully very unlikely).  The chances  of  data
+       corruption  going  undetected  is  microscopic,  about one
+       chance in four billion for each file processed.  Be aware,
+       though,  that  the  check occurs upon decompression, so it
+       can only tell you that something is wrong.  It can’t  help
+       you  recover  the original uncompressed data.  You can use
+       _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
+
+       Return values: 0 for a normal exit,  1  for  environmental
+       problems  (file not found, invalid flags, I/O errors, &c),
+       2 to indicate a corrupt compressed file, 3 for an internal
+       consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
+
+
+OOPPTTIIOONNSS
+       −−cc â€â€â€â€ssttddoouutt
+              Compress or decompress to standard output.
+
+       −−dd â€â€â€â€ddeeccoommpprreessss
+              Force  decompression.  _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
+              really the same program,  and  the  decision  about
+              what  actions to take is done on the basis of which
+              name is used.  This flag overrides that  mechanism,
+              and forces _b_z_i_p_2 to decompress.
+
+       −−zz â€â€â€â€ccoommpprreessss
+              The   complement   to   −d:   forces   compression,
+              regardless of the invocation name.
+
+       −−tt â€â€â€â€tteesstt
+              Check integrity of the specified file(s), but don’t
+              decompress  them.   This  really  performs  a trial
+              decompression and throws away the result.
+
+       −−ff â€â€â€â€ffoorrccee
+              Force overwrite of output files.   Normally,  _b_z_i_p_2
+              will  not  overwrite  existing  output files.  Also
+              forces _b_z_i_p_2 to break hard links to files, which it
+              otherwise wouldn’t do.
+
+              bzip2  normally  declines to decompress files which
+              don’t have the  correct  magic  header  bytes.   If
+              forced  (â€f),  however,  it  will  pass  such files
+              through unmodified.  This is how GNU gzip  behaves.
+
+       −−kk â€â€â€â€kkeeeepp
+              Keep  (don’t delete) input files during compression
+              or decompression.
+
+       −−ss â€â€â€â€ssmmaallll
+              Reduce memory usage, for compression, decompression
+              and  testing.   Files  are  decompressed and tested
+              using a modified algorithm which only requires  2.5
+              bytes  per  block byte.  This means any file can be
+              decompressed in 2300k of memory,  albeit  at  about
+              half the normal speed.
+
+              During  compression,  −s  selects  a  block size of
+              200k, which limits memory use to  around  the  same
+              figure,  at  the expense of your compression ratio.
+              In short, if your  machine  is  low  on  memory  (8
+              megabytes  or  less),  use  −s for everything.  See
+              MEMORY MANAGEMENT below.
+
+       −−qq â€â€â€â€qquuiieett
+              Suppress nonâ€essential warning messages.   Messages
+              pertaining  to I/O errors and other critical events
+              will not be suppressed.
+
+       −−vv â€â€â€â€vveerrbboossee
+              Verbose mode â€â€ show the compression ratio for each
+              file  processed.   Further  −v’s  increase the ver­
+              bosity level, spewing out lots of information which
+              is primarily of interest for diagnostic purposes.
+
+       −−LL â€â€â€â€lliicceennssee â€â€VV â€â€â€â€vveerrssiioonn
+              Display  the  software  version,  license terms and
+              conditions.
+
+       −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt))
+              Set the block size to 100 k, 200 k ..  900  k  when
+              compressing.   Has  no  effect  when decompressing.
+              See MEMORY MANAGEMENT below.  The −−fast and −−best
+              aliases  are  primarily for GNU gzip compatibility.
+              In particular, −−fast doesn’t make things  signifi­
+              cantly  faster.   And  −−best  merely  selects  the
+              default behaviour.
+
+       −−     Treats all subsequent arguments as file names, even
+              if they start with a dash.  This is so you can han­
+              dle files with names beginning  with  a  dash,  for
+              example: bzip2 −†−myfilename.
+
+       −−â€â€rreeppeettiittiivveeâ€â€ffaasstt â€â€â€â€rreeppeettiittiivveeâ€â€bbeesstt
+              These  flags  are  redundant  in versions 0.9.5 and
+              above.  They provided some coarse control over  the
+              behaviour  of the sorting algorithm in earlier ver­
+              sions, which was sometimes useful.  0.9.5 and above
+              have  an  improved  algorithm  which  renders these
+              flags irrelevant.
+
+
+MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
+       _b_z_i_p_2 compresses large files in blocks.   The  block  size
+       affects  both  the  compression  ratio  achieved,  and the
+       amount of memory needed for compression and decompression.
+       The  flags  −1  through  −9  specify  the block size to be
+       100,000 bytes through 900,000 bytes (the default)  respec­
+       tively.   At  decompression  time, the block size used for
+       compression is read from  the  header  of  the  compressed
+       file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
+       to decompress the file.  Since block sizes are  stored  in
+       compressed  files,  it follows that the flags −1 to −9 are
+       irrelevant to and so ignored during decompression.
+
+       Compression and decompression requirements, in bytes,  can
+       be estimated as:
+
+              Compression:   400k + ( 8 x block size )
+
+              Decompression: 100k + ( 4 x block size ), or
+                             100k + ( 2.5 x block size )
+
+       Larger  block  sizes  give  rapidly  diminishing  marginal
+       returns.  Most of the compression comes from the first two
+       or  three hundred k of block size, a fact worth bearing in
+       mind when using _b_z_i_p_2  on  small  machines.   It  is  also
+       important  to  appreciate  that  the  decompression memory
+       requirement is set at compression time by  the  choice  of
+       block size.
+
+       For  files  compressed  with  the default 900k block size,
+       _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress.   To
+       support decompression of any file on a 4 megabyte machine,
+       _b_u_n_z_i_p_2 has an option to  decompress  using  approximately
+       half this amount of memory, about 2300 kbytes.  Decompres­
+       sion speed is also halved, so you should use  this  option
+       only where necessary.  The relevant flag is â€s.
+
+       In general, try and use the largest block size memory con­
+       straints  allow,  since  that  maximises  the  compression
+       achieved.   Compression and decompression speed are virtu­
+       ally unaffected by block size.
+
+       Another significant point applies to files which fit in  a
+       single  block  â€â€  that  means  most files you’d encounter
+       using a large block  size.   The  amount  of  real  memory
+       touched is proportional to the size of the file, since the
+       file is smaller than a block.  For example, compressing  a
+       file  20,000  bytes  long  with the flag â€9 will cause the
+       compressor to allocate around 7600k of  memory,  but  only
+       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
+       decompressor will allocate 3700k but  only  touch  100k  +
+       20000 * 4 = 180 kbytes.
+
+       Here  is a table which summarises the maximum memory usage
+       for different block sizes.  Also  recorded  is  the  total
+       compressed  size for 14 files of the Calgary Text Compres­
+       sion Corpus totalling 3,141,622 bytes.  This column  gives
+       some  feel  for  how  compression  varies with block size.
+       These figures tend to understate the advantage  of  larger
+       block  sizes  for  larger files, since the Corpus is domi­
+       nated by smaller files.
+
+                  Compress   Decompress   Decompress   Corpus
+           Flag     usage      usage       â€s usage     Size
+
+            â€1      1200k       500k         350k      914704
+            â€2      2000k       900k         600k      877703
+            â€3      2800k      1300k         850k      860338
+            â€4      3600k      1700k        1100k      846899
+            â€5      4400k      2100k        1350k      845160
+            â€6      5200k      2500k        1600k      838626
+            â€7      6100k      2900k        1850k      834096
+            â€8      6800k      3300k        2100k      828642
+            â€9      7600k      3700k        2350k      828642
+
+
+RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
+       _b_z_i_p_2 compresses files in blocks, usually 900kbytes  long.
+       Each block is handled independently.  If a media or trans­
+       mission error causes a multiâ€block  .bz2  file  to  become
+       damaged,  it  may  be  possible  to  recover data from the
+       undamaged blocks in the file.
+
+       The compressed representation of each block  is  delimited
+       by  a  48â€bit pattern, which makes it possible to find the
+       block boundaries with reasonable  certainty.   Each  block
+       also  carries its own 32â€bit CRC, so damaged blocks can be
+       distinguished from undamaged ones.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r is a  simple  program  whose  purpose  is  to
+       search  for blocks in .bz2 files, and write each block out
+       into its own .bz2 file.  You can then use _b_z_i_p_2 −t to test
+       the integrity of the resulting files, and decompress those
+       which are undamaged.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­
+       aged    file,    and    writes    a    number   of   files
+       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
+       the   extracted   blocks.   The   output   filenames   are
+       designed  so  that the use of wildcards in subsequent pro­
+       cessing  â€â€ for example, "bzip2 â€dc  rec*file.bz2 > recov­
+       ered_data" â€â€ processes the files in the correct order.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
+       files,  as  these will contain many blocks.  It is clearly
+       futile to use it on damaged singleâ€block  files,  since  a
+       damaged  block  cannot  be recovered.  If you wish to min­
+       imise any potential data loss through media  or  transmis­
+       sion errors, you might consider compressing with a smaller
+       block size.
+
+
+PPEERRFFOORRMMAANNCCEE NNOOTTEESS
+       The sorting phase of compression gathers together  similar
+       strings  in  the  file.  Because of this, files containing
+       very long runs of  repeated  symbols,  like  "aabaabaabaab
+       ..."   (repeated  several hundred times) may compress more
+       slowly than normal.  Versions 0.9.5 and  above  fare  much
+       better  than previous versions in this respect.  The ratio
+       between worstâ€case and averageâ€case compression time is in
+       the  region  of  10:1.  For previous versions, this figure
+       was more like 100:1.  You can use the −vvvv option to mon­
+       itor progress in great detail, if you want.
+
+       Decompression speed is unaffected by these phenomena.
+
+       _b_z_i_p_2  usually  allocates  several  megabytes of memory to
+       operate in, and then charges all over it in a fairly  ran­
+       dom  fashion.   This means that performance, both for com­
+       pressing and decompressing, is largely determined  by  the
+       speed  at  which  your  machine  can service cache misses.
+       Because of this, small changes to the code to  reduce  the
+       miss  rate  have  been observed to give disproportionately
+       large performance improvements.  I imagine _b_z_i_p_2 will per­
+       form best on machines with very large caches.
+
+
+CCAAVVEEAATTSS
+       I/O  error  messages  are not as helpful as they could be.
+       _b_z_i_p_2 tries hard to detect I/O errors  and  exit  cleanly,
+       but  the  details  of  what  the problem is sometimes seem
+       rather misleading.
+
+       This manual page pertains to version 1.0.3 of _b_z_i_p_2_.  Com­
+       pressed  data created by this version is entirely forwards
+       and  backwards  compatible  with   the   previous   public
+       releases,  versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and
+       1.0.2, but with the following exception: 0.9.0  and  above
+       can  correctly decompress multiple concatenated compressed
+       files.  0.1pl2 cannot do this; it will stop  after  decom­
+       pressing just the first file in the stream.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r  versions prior to 1.0.2 used 32â€bit integers
+       to represent bit positions in compressed  files,  so  they
+       could  not handle compressed files more than 512 megabytes
+       long.  Versions 1.0.2 and above use 64â€bit  ints  on  some
+       platforms  which  support them (GNU supported targets, and
+       Windows).  To establish whether or  not  bzip2recover  was
+       built  with  such  a limitation, run it without arguments.
+       In any event you can build yourself an  unlimited  version
+       if  you  can  recompile  it  with MaybeUInt64 set to be an
+       unsigned 64â€bit integer.
+
+
+
+
+AAUUTTHHOORR
+       Julian Seward, jsewardbzip.org.
+
+       http://www.bzip.org
+
+       The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­
+       lowing  people: Michael Burrows and David Wheeler (for the
+       block sorting transformation), David Wheeler  (again,  for
+       the Huffman coder), Peter Fenwick (for the structured cod­
+       ing model in the original _b_z_i_p_, and many refinements), and
+       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
+       arithmetic  coder  in  the  original  _b_z_i_p_)_.   I  am  much
+       indebted for their help, support and advice.  See the man­
+       ual in the source distribution for pointers to sources  of
+       documentation.  Christian von Roques encouraged me to look
+       for faster sorting algorithms, so as to speed up  compres­
+       sion.  Bela Lubkin encouraged me to improve the worstâ€case
+       compression performance.  Donna Robinson XMLised the docu­
+       mentation.   The bz* scripts are derived from those of GNU
+       gzip.  Many people sent patches, helped  with  portability
+       problems,  lent  machines,  gave advice and were generally
+       helpful.
+
+
+
+                                                         bzip2(1)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c
new file mode 100644
index 000000000..79f87a519
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c
@@ -0,0 +1,2107 @@
+
+/*-----------------------------------------------------------*/
+/*--- A block-sorting, lossless compressor        bzip2.c ---*/
+/*-----------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+
+/*----------------------------------------------------*/
+/*--- IMPORTANT                                    ---*/
+/*----------------------------------------------------*/
+
+/*--
+   WARNING:
+      This program and library (attempts to) compress data by 
+      performing several non-trivial transformations on it.  
+      Unless you are 100% familiar with *all* the algorithms 
+      contained herein, and with the consequences of modifying them, 
+      you should NOT meddle with the compression or decompression 
+      machinery.  Incorrect changes can and very likely *will* 
+      lead to disasterous loss of data.
+
+   DISCLAIMER:
+      I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
+      USE OF THIS PROGRAM, HOWSOEVER CAUSED.
+
+      Every compression of a file implies an assumption that the
+      compressed file can be decompressed to reproduce the original.
+      Great efforts in design, coding and testing have been made to
+      ensure that this program works correctly.  However, the
+      complexity of the algorithms, and, in particular, the presence
+      of various special cases in the code which occur with very low
+      but non-zero probability make it impossible to rule out the
+      possibility of bugs remaining in the program.  DO NOT COMPRESS
+      ANY DATA WITH THIS PROGRAM AND/OR LIBRARY UNLESS YOU ARE PREPARED 
+      TO ACCEPT THE POSSIBILITY, HOWEVER SMALL, THAT THE DATA WILL 
+      NOT BE RECOVERABLE.
+
+      That is not to say this program is inherently unreliable.
+      Indeed, I very much hope the opposite is true.  bzip2/libbzip2
+      has been carefully constructed and extensively tested.
+
+   PATENTS:
+      To the best of my knowledge, bzip2/libbzip2 does not use any 
+      patented algorithms.  However, I do not have the resources 
+      available to carry out a full patent search.  Therefore I cannot 
+      give any guarantee of the above statement.
+--*/
+
+
+
+/*----------------------------------------------------*/
+/*--- and now for something much more pleasant :-) ---*/
+/*----------------------------------------------------*/
+
+/*---------------------------------------------*/
+/*--
+  Place a 1 beside your platform, and 0 elsewhere.
+--*/
+
+/*--
+  Generic 32-bit Unix.
+  Also works on 64-bit Unix boxes.
+  This is the default.
+--*/
+#define BZ_UNIX      1
+
+/*--
+  Win32, as seen by Jacob Navia's excellent
+  port of (Chris Fraser & David Hanson)'s excellent
+  lcc compiler.  Or with MS Visual C.
+  This is selected automatically if compiled by a compiler which
+  defines _WIN32, not including the Cygwin GCC.
+--*/
+#define BZ_LCCWIN32  0
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef  BZ_LCCWIN32
+#define BZ_LCCWIN32 1
+#undef  BZ_UNIX
+#define BZ_UNIX 0
+#endif
+
+
+/*---------------------------------------------*/
+/*--
+  Some stuff for all platforms.
+--*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "bzlib.h"
+
+#define ERROR_IF_EOF(i)       { if ((i) == EOF)  ioError(); }
+#define ERROR_IF_NOT_ZERO(i)  { if ((i) != 0)    ioError(); }
+#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
+
+
+/*---------------------------------------------*/
+/*--
+   Platform-specific stuff.
+--*/
+
+#if BZ_UNIX
+#   include 
+#   include 
+#   include 
+#   include 
+#   include 
+#   include 
+
+#   define PATH_SEP    '/'
+#   define MY_LSTAT    lstat
+#   define MY_STAT     stat
+#   define MY_S_ISREG  S_ISREG
+#   define MY_S_ISDIR  S_ISDIR
+
+#   define APPEND_FILESPEC(root, name) \
+      root=snocString((root), (name))
+
+#   define APPEND_FLAG(root, name) \
+      root=snocString((root), (name))
+
+#   define SET_BINARY_MODE(fd) /**/
+
+#   ifdef __GNUC__
+#      define NORETURN __attribute__ ((noreturn))
+#   else
+#      define NORETURN /**/
+#   endif
+
+#   ifdef __DJGPP__
+#     include 
+#     include 
+#     undef MY_LSTAT
+#     undef MY_STAT
+#     define MY_LSTAT stat
+#     define MY_STAT stat
+#     undef SET_BINARY_MODE
+#     define SET_BINARY_MODE(fd)                        \
+        do {                                            \
+           int retVal = setmode ( fileno ( fd ),        \
+                                  O_BINARY );           \
+           ERROR_IF_MINUS_ONE ( retVal );               \
+        } while ( 0 )
+#   endif
+
+#   ifdef __CYGWIN__
+#     include 
+#     include 
+#     undef SET_BINARY_MODE
+#     define SET_BINARY_MODE(fd)                        \
+        do {                                            \
+           int retVal = setmode ( fileno ( fd ),        \
+                                  O_BINARY );           \
+           ERROR_IF_MINUS_ONE ( retVal );               \
+        } while ( 0 )
+#   endif
+#endif /* BZ_UNIX */
+
+
+
+#if BZ_LCCWIN32
+#   include 
+#   include 
+#   include 
+
+#   define NORETURN       /**/
+#   define PATH_SEP       '\\'
+#   define MY_LSTAT       _stat
+#   define MY_STAT        _stat
+#   define MY_S_ISREG(x)  ((x) & _S_IFREG)
+#   define MY_S_ISDIR(x)  ((x) & _S_IFDIR)
+
+#   define APPEND_FLAG(root, name) \
+      root=snocString((root), (name))
+
+#   define APPEND_FILESPEC(root, name)                \
+      root = snocString ((root), (name))
+
+#   define SET_BINARY_MODE(fd)                        \
+      do {                                            \
+         int retVal = setmode ( fileno ( fd ),        \
+                                O_BINARY );           \
+         ERROR_IF_MINUS_ONE ( retVal );               \
+      } while ( 0 )
+
+#endif /* BZ_LCCWIN32 */
+
+
+/*---------------------------------------------*/
+/*--
+  Some more stuff for all platforms :-)
+--*/
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+                                       
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+/*--
+  IntNative is your platform's `native' int size.
+  Only here to avoid probs with 64-bit platforms.
+--*/
+typedef int IntNative;
+
+
+/*---------------------------------------------------*/
+/*--- Misc (file handling) data decls             ---*/
+/*---------------------------------------------------*/
+
+Int32   verbosity;
+Bool    keepInputFiles, smallMode, deleteOutputOnInterrupt;
+Bool    forceOverwrite, testFailsExist, unzFailsExist, noisy;
+Int32   numFileNames, numFilesProcessed, blockSize100k;
+Int32   exitValue;
+
+/*-- source modes; F==file, I==stdin, O==stdout --*/
+#define SM_I2O           1
+#define SM_F2O           2
+#define SM_F2F           3
+
+/*-- operation modes --*/
+#define OM_Z             1
+#define OM_UNZ           2
+#define OM_TEST          3
+
+Int32   opMode;
+Int32   srcMode;
+
+#define FILE_NAME_LEN 1034
+
+Int32   longestFileName;
+Char    inName [FILE_NAME_LEN];
+Char    outName[FILE_NAME_LEN];
+Char    tmpName[FILE_NAME_LEN];
+Char    *progName;
+Char    progNameReally[FILE_NAME_LEN];
+FILE    *outputHandleJustInCase;
+Int32   workFactor;
+
+static void    panic                 ( Char* )   NORETURN;
+static void    ioError               ( void )    NORETURN;
+static void    outOfMemory           ( void )    NORETURN;
+static void    configError           ( void )    NORETURN;
+static void    crcError              ( void )    NORETURN;
+static void    cleanUpAndFail        ( Int32 )   NORETURN;
+static void    compressedStreamEOF   ( void )    NORETURN;
+
+static void    copyFileName ( Char*, Char* );
+static void*   myMalloc     ( Int32 );
+
+
+
+/*---------------------------------------------------*/
+/*--- An implementation of 64-bit ints.  Sigh.    ---*/
+/*--- Roll on widespread deployment of ANSI C9X ! ---*/
+/*---------------------------------------------------*/
+
+typedef
+   struct { UChar b[8]; } 
+   UInt64;
+
+
+static
+void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
+{
+   n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
+   n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
+   n->b[5] = (UChar)((hi32 >> 8)  & 0xFF);
+   n->b[4] = (UChar) (hi32        & 0xFF);
+   n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
+   n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
+   n->b[1] = (UChar)((lo32 >> 8)  & 0xFF);
+   n->b[0] = (UChar) (lo32        & 0xFF);
+}
+
+
+static
+double uInt64_to_double ( UInt64* n )
+{
+   Int32  i;
+   double base = 1.0;
+   double sum  = 0.0;
+   for (i = 0; i < 8; i++) {
+      sum  += base * (double)(n->b[i]);
+      base *= 256.0;
+   }
+   return sum;
+}
+
+
+static
+Bool uInt64_isZero ( UInt64* n )
+{
+   Int32 i;
+   for (i = 0; i < 8; i++)
+      if (n->b[i] != 0) return 0;
+   return 1;
+}
+
+
+/* Divide *n by 10, and return the remainder.  */
+static 
+Int32 uInt64_qrm10 ( UInt64* n )
+{
+   UInt32 rem, tmp;
+   Int32  i;
+   rem = 0;
+   for (i = 7; i >= 0; i--) {
+      tmp = rem * 256 + n->b[i];
+      n->b[i] = tmp / 10;
+      rem = tmp % 10;
+   }
+   return rem;
+}
+
+
+/* ... and the Whole Entire Point of all this UInt64 stuff is
+   so that we can supply the following function.
+*/
+static
+void uInt64_toAscii ( char* outbuf, UInt64* n )
+{
+   Int32  i, q;
+   UChar  buf[32];
+   Int32  nBuf   = 0;
+   UInt64 n_copy = *n;
+   do {
+      q = uInt64_qrm10 ( &n_copy );
+      buf[nBuf] = q + '0';
+      nBuf++;
+   } while (!uInt64_isZero(&n_copy));
+   outbuf[nBuf] = 0;
+   for (i = 0; i < nBuf; i++) 
+      outbuf[i] = buf[nBuf-i-1];
+}
+
+
+/*---------------------------------------------------*/
+/*--- Processing of complete files and streams    ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------*/
+static 
+void compressStream ( FILE *stream, FILE *zStream )
+{
+   BZFILE* bzf = NULL;
+   UChar   ibuf[5000];
+   Int32   nIbuf;
+   UInt32  nbytes_in_lo32, nbytes_in_hi32;
+   UInt32  nbytes_out_lo32, nbytes_out_hi32;
+   Int32   bzerr, bzerr_dummy, ret;
+
+   SET_BINARY_MODE(stream);
+   SET_BINARY_MODE(zStream);
+
+   if (ferror(stream)) goto errhandler_io;
+   if (ferror(zStream)) goto errhandler_io;
+
+   bzf = BZ2_bzWriteOpen ( &bzerr, zStream, 
+                           blockSize100k, verbosity, workFactor );   
+   if (bzerr != BZ_OK) goto errhandler;
+
+   if (verbosity >= 2) fprintf ( stderr, "\n" );
+
+   while (True) {
+
+      if (myfeof(stream)) break;
+      nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
+      if (ferror(stream)) goto errhandler_io;
+      if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
+      if (bzerr != BZ_OK) goto errhandler;
+
+   }
+
+   BZ2_bzWriteClose64 ( &bzerr, bzf, 0, 
+                        &nbytes_in_lo32, &nbytes_in_hi32,
+                        &nbytes_out_lo32, &nbytes_out_hi32 );
+   if (bzerr != BZ_OK) goto errhandler;
+
+   if (ferror(zStream)) goto errhandler_io;
+   ret = fflush ( zStream );
+   if (ret == EOF) goto errhandler_io;
+   if (zStream != stdout) {
+      ret = fclose ( zStream );
+      outputHandleJustInCase = NULL;
+      if (ret == EOF) goto errhandler_io;
+   }
+   outputHandleJustInCase = NULL;
+   if (ferror(stream)) goto errhandler_io;
+   ret = fclose ( stream );
+   if (ret == EOF) goto errhandler_io;
+
+   if (verbosity >= 1) {
+      if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
+	 fprintf ( stderr, " no data compressed.\n");
+      } else {
+	 Char   buf_nin[32], buf_nout[32];
+	 UInt64 nbytes_in,   nbytes_out;
+	 double nbytes_in_d, nbytes_out_d;
+	 uInt64_from_UInt32s ( &nbytes_in, 
+			       nbytes_in_lo32, nbytes_in_hi32 );
+	 uInt64_from_UInt32s ( &nbytes_out, 
+			       nbytes_out_lo32, nbytes_out_hi32 );
+	 nbytes_in_d  = uInt64_to_double ( &nbytes_in );
+	 nbytes_out_d = uInt64_to_double ( &nbytes_out );
+	 uInt64_toAscii ( buf_nin, &nbytes_in );
+	 uInt64_toAscii ( buf_nout, &nbytes_out );
+	 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
+		   "%5.2f%% saved, %s in, %s out.\n",
+		   nbytes_in_d / nbytes_out_d,
+		   (8.0 * nbytes_out_d) / nbytes_in_d,
+		   100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
+		   buf_nin,
+		   buf_nout
+		 );
+      }
+   }
+
+   return;
+
+   errhandler:
+   BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1, 
+                        &nbytes_in_lo32, &nbytes_in_hi32,
+                        &nbytes_out_lo32, &nbytes_out_hi32 );
+   switch (bzerr) {
+      case BZ_CONFIG_ERROR:
+         configError(); break;
+      case BZ_MEM_ERROR:
+         outOfMemory (); break;
+      case BZ_IO_ERROR:
+         errhandler_io:
+         ioError(); break;
+      default:
+         panic ( "compress:unexpected error" );
+   }
+
+   panic ( "compress:end" );
+   /*notreached*/
+}
+
+
+
+/*---------------------------------------------*/
+static 
+Bool uncompressStream ( FILE *zStream, FILE *stream )
+{
+   BZFILE* bzf = NULL;
+   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
+   UChar   obuf[5000];
+   UChar   unused[BZ_MAX_UNUSED];
+   Int32   nUnused;
+   void*   unusedTmpV;
+   UChar*  unusedTmp;
+
+   nUnused = 0;
+   streamNo = 0;
+
+   SET_BINARY_MODE(stream);
+   SET_BINARY_MODE(zStream);
+
+   if (ferror(stream)) goto errhandler_io;
+   if (ferror(zStream)) goto errhandler_io;
+
+   while (True) {
+
+      bzf = BZ2_bzReadOpen ( 
+               &bzerr, zStream, verbosity, 
+               (int)smallMode, unused, nUnused
+            );
+      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+      streamNo++;
+
+      while (bzerr == BZ_OK) {
+         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+         if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
+         if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
+            fwrite ( obuf, sizeof(UChar), nread, stream );
+         if (ferror(stream)) goto errhandler_io;
+      }
+      if (bzerr != BZ_STREAM_END) goto errhandler;
+
+      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+      unusedTmp = (UChar*)unusedTmpV;
+      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+      BZ2_bzReadClose ( &bzerr, bzf );
+      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+      if (nUnused == 0 && myfeof(zStream)) break;
+   }
+
+   closeok:
+   if (ferror(zStream)) goto errhandler_io;
+   ret = fclose ( zStream );
+   if (ret == EOF) goto errhandler_io;
+
+   if (ferror(stream)) goto errhandler_io;
+   ret = fflush ( stream );
+   if (ret != 0) goto errhandler_io;
+   if (stream != stdout) {
+      ret = fclose ( stream );
+      outputHandleJustInCase = NULL;
+      if (ret == EOF) goto errhandler_io;
+   }
+   outputHandleJustInCase = NULL;
+   if (verbosity >= 2) fprintf ( stderr, "\n    " );
+   return True;
+
+   trycat: 
+   if (forceOverwrite) {
+      rewind(zStream);
+      while (True) {
+      	 if (myfeof(zStream)) break;
+      	 nread = fread ( obuf, sizeof(UChar), 5000, zStream );
+      	 if (ferror(zStream)) goto errhandler_io;
+      	 if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
+      	 if (ferror(stream)) goto errhandler_io;
+      }
+      goto closeok;
+   }
+  
+   errhandler:
+   BZ2_bzReadClose ( &bzerr_dummy, bzf );
+   switch (bzerr) {
+      case BZ_CONFIG_ERROR:
+         configError(); break;
+      case BZ_IO_ERROR:
+         errhandler_io:
+         ioError(); break;
+      case BZ_DATA_ERROR:
+         crcError();
+      case BZ_MEM_ERROR:
+         outOfMemory();
+      case BZ_UNEXPECTED_EOF:
+         compressedStreamEOF();
+      case BZ_DATA_ERROR_MAGIC:
+         if (zStream != stdin) fclose(zStream);
+         if (stream != stdout) fclose(stream);
+         if (streamNo == 1) {
+            return False;
+         } else {
+            if (noisy)
+            fprintf ( stderr, 
+                      "\n%s: %s: trailing garbage after EOF ignored\n",
+                      progName, inName );
+            return True;       
+         }
+      default:
+         panic ( "decompress:unexpected error" );
+   }
+
+   panic ( "decompress:end" );
+   return True; /*notreached*/
+}
+
+
+/*---------------------------------------------*/
+static 
+Bool testStream ( FILE *zStream )
+{
+   BZFILE* bzf = NULL;
+   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
+   UChar   obuf[5000];
+   UChar   unused[BZ_MAX_UNUSED];
+   Int32   nUnused;
+   void*   unusedTmpV;
+   UChar*  unusedTmp;
+
+   nUnused = 0;
+   streamNo = 0;
+
+   SET_BINARY_MODE(zStream);
+   if (ferror(zStream)) goto errhandler_io;
+
+   while (True) {
+
+      bzf = BZ2_bzReadOpen ( 
+               &bzerr, zStream, verbosity, 
+               (int)smallMode, unused, nUnused
+            );
+      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+      streamNo++;
+
+      while (bzerr == BZ_OK) {
+         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+         if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
+      }
+      if (bzerr != BZ_STREAM_END) goto errhandler;
+
+      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+
+      unusedTmp = (UChar*)unusedTmpV;
+      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+      BZ2_bzReadClose ( &bzerr, bzf );
+      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+      if (nUnused == 0 && myfeof(zStream)) break;
+
+   }
+
+   if (ferror(zStream)) goto errhandler_io;
+   ret = fclose ( zStream );
+   if (ret == EOF) goto errhandler_io;
+
+   if (verbosity >= 2) fprintf ( stderr, "\n    " );
+   return True;
+
+   errhandler:
+   BZ2_bzReadClose ( &bzerr_dummy, bzf );
+   if (verbosity == 0) 
+      fprintf ( stderr, "%s: %s: ", progName, inName );
+   switch (bzerr) {
+      case BZ_CONFIG_ERROR:
+         configError(); break;
+      case BZ_IO_ERROR:
+         errhandler_io:
+         ioError(); break;
+      case BZ_DATA_ERROR:
+         fprintf ( stderr,
+                   "data integrity (CRC) error in data\n" );
+         return False;
+      case BZ_MEM_ERROR:
+         outOfMemory();
+      case BZ_UNEXPECTED_EOF:
+         fprintf ( stderr,
+                   "file ends unexpectedly\n" );
+         return False;
+      case BZ_DATA_ERROR_MAGIC:
+         if (zStream != stdin) fclose(zStream);
+         if (streamNo == 1) {
+          fprintf ( stderr, 
+                    "bad magic number (file not created by bzip2)\n" );
+            return False;
+         } else {
+            if (noisy)
+            fprintf ( stderr, 
+                      "trailing garbage after EOF ignored\n" );
+            return True;       
+         }
+      default:
+         panic ( "test:unexpected error" );
+   }
+
+   panic ( "test:end" );
+   return True; /*notreached*/
+}
+
+
+/*---------------------------------------------------*/
+/*--- Error [non-] handling grunge                ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+void setExit ( Int32 v )
+{
+   if (v > exitValue) exitValue = v;
+}
+
+
+/*---------------------------------------------*/
+static 
+void cadvise ( void )
+{
+   if (noisy)
+   fprintf (
+      stderr,
+      "\nIt is possible that the compressed file(s) have become corrupted.\n"
+        "You can use the -tvv option to test integrity of such files.\n\n"
+        "You can use the `bzip2recover' program to attempt to recover\n"
+        "data from undamaged sections of corrupted files.\n\n"
+    );
+}
+
+
+/*---------------------------------------------*/
+static 
+void showFileNames ( void )
+{
+   if (noisy)
+   fprintf (
+      stderr,
+      "\tInput file = %s, output file = %s\n",
+      inName, outName 
+   );
+}
+
+
+/*---------------------------------------------*/
+static 
+void cleanUpAndFail ( Int32 ec )
+{
+   IntNative      retVal;
+   struct MY_STAT statBuf;
+
+   if ( srcMode == SM_F2F 
+        && opMode != OM_TEST
+        && deleteOutputOnInterrupt ) {
+
+      /* Check whether input file still exists.  Delete output file
+         only if input exists to avoid loss of data.  Joerg Prante, 5
+         January 2002.  (JRS 06-Jan-2002: other changes in 1.0.2 mean
+         this is less likely to happen.  But to be ultra-paranoid, we
+         do the check anyway.)  */
+      retVal = MY_STAT ( inName, &statBuf );
+      if (retVal == 0) {
+         if (noisy)
+            fprintf ( stderr, 
+                      "%s: Deleting output file %s, if it exists.\n",
+                      progName, outName );
+         if (outputHandleJustInCase != NULL)
+            fclose ( outputHandleJustInCase );
+         retVal = remove ( outName );
+         if (retVal != 0)
+            fprintf ( stderr,
+                      "%s: WARNING: deletion of output file "
+                      "(apparently) failed.\n",
+                      progName );
+      } else {
+         fprintf ( stderr,
+                   "%s: WARNING: deletion of output file suppressed\n",
+                    progName );
+         fprintf ( stderr,
+                   "%s:    since input file no longer exists.  Output file\n",
+                   progName );
+         fprintf ( stderr,
+                   "%s:    `%s' may be incomplete.\n",
+                   progName, outName );
+         fprintf ( stderr, 
+                   "%s:    I suggest doing an integrity test (bzip2 -tv)"
+                   " of it.\n",
+                   progName );
+      }
+   }
+
+   if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
+      fprintf ( stderr, 
+                "%s: WARNING: some files have not been processed:\n"
+                "%s:    %d specified on command line, %d not processed yet.\n\n",
+                progName, progName,
+                numFileNames, numFileNames - numFilesProcessed );
+   }
+   setExit(ec);
+   exit(exitValue);
+}
+
+
+/*---------------------------------------------*/
+static 
+void panic ( Char* s )
+{
+   fprintf ( stderr,
+             "\n%s: PANIC -- internal consistency error:\n"
+             "\t%s\n"
+             "\tThis is a BUG.  Please report it to me at:\n"
+             "\tjseward@bzip.org\n",
+             progName, s );
+   showFileNames();
+   cleanUpAndFail( 3 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void crcError ( void )
+{
+   fprintf ( stderr,
+             "\n%s: Data integrity error when decompressing.\n",
+             progName );
+   showFileNames();
+   cadvise();
+   cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void compressedStreamEOF ( void )
+{
+  if (noisy) {
+    fprintf ( stderr,
+	      "\n%s: Compressed file ends unexpectedly;\n\t"
+	      "perhaps it is corrupted?  *Possible* reason follows.\n",
+	      progName );
+    perror ( progName );
+    showFileNames();
+    cadvise();
+  }
+  cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void ioError ( void )
+{
+   fprintf ( stderr,
+             "\n%s: I/O or other error, bailing out.  "
+             "Possible reason follows.\n",
+             progName );
+   perror ( progName );
+   showFileNames();
+   cleanUpAndFail( 1 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void mySignalCatcher ( IntNative n )
+{
+   fprintf ( stderr,
+             "\n%s: Control-C or similar caught, quitting.\n",
+             progName );
+   cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static 
+void mySIGSEGVorSIGBUScatcher ( IntNative n )
+{
+   if (opMode == OM_Z)
+      fprintf ( 
+      stderr,
+      "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
+      "\n"
+      "   Possible causes are (most likely first):\n"
+      "   (1) This computer has unreliable memory or cache hardware\n"
+      "       (a surprisingly common problem; try a different machine.)\n"
+      "   (2) A bug in the compiler used to create this executable\n"
+      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
+      "   (3) A real bug in bzip2 -- I hope this should never be the case.\n"
+      "   The user's manual, Section 4.3, has more info on (1) and (2).\n"
+      "   \n"
+      "   If you suspect this is a bug in bzip2, or are unsure about (1)\n"
+      "   or (2), feel free to report it to me at: jseward@bzip.org.\n"
+      "   Section 4.3 of the user's manual describes the info a useful\n"
+      "   bug report should have.  If the manual is available on your\n"
+      "   system, please try and read it before mailing me.  If you don't\n"
+      "   have the manual or can't be bothered to read it, mail me anyway.\n"
+      "\n",
+      progName );
+      else
+      fprintf ( 
+      stderr,
+      "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
+      "\n"
+      "   Possible causes are (most likely first):\n"
+      "   (1) The compressed data is corrupted, and bzip2's usual checks\n"
+      "       failed to detect this.  Try bzip2 -tvv my_file.bz2.\n"
+      "   (2) This computer has unreliable memory or cache hardware\n"
+      "       (a surprisingly common problem; try a different machine.)\n"
+      "   (3) A bug in the compiler used to create this executable\n"
+      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
+      "   (4) A real bug in bzip2 -- I hope this should never be the case.\n"
+      "   The user's manual, Section 4.3, has more info on (2) and (3).\n"
+      "   \n"
+      "   If you suspect this is a bug in bzip2, or are unsure about (2)\n"
+      "   or (3), feel free to report it to me at: jseward@bzip.org.\n"
+      "   Section 4.3 of the user's manual describes the info a useful\n"
+      "   bug report should have.  If the manual is available on your\n"
+      "   system, please try and read it before mailing me.  If you don't\n"
+      "   have the manual or can't be bothered to read it, mail me anyway.\n"
+      "\n",
+      progName );
+
+   showFileNames();
+   if (opMode == OM_Z)
+      cleanUpAndFail( 3 ); else
+      { cadvise(); cleanUpAndFail( 2 ); }
+}
+
+
+/*---------------------------------------------*/
+static 
+void outOfMemory ( void )
+{
+   fprintf ( stderr,
+             "\n%s: couldn't allocate enough memory\n",
+             progName );
+   showFileNames();
+   cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static 
+void configError ( void )
+{
+   fprintf ( stderr,
+             "bzip2: I'm not configured correctly for this platform!\n"
+             "\tI require Int32, Int16 and Char to have sizes\n"
+             "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
+             "\tProbably you can fix this by defining them correctly,\n"
+             "\tand recompiling.  Bye!\n" );
+   setExit(3);
+   exit(exitValue);
+}
+
+
+/*---------------------------------------------------*/
+/*--- The main driver machinery                   ---*/
+/*---------------------------------------------------*/
+
+/* All rather crufty.  The main problem is that input files
+   are stat()d multiple times before use.  This should be
+   cleaned up. 
+*/
+
+/*---------------------------------------------*/
+static 
+void pad ( Char *s )
+{
+   Int32 i;
+   if ( (Int32)strlen(s) >= longestFileName ) return;
+   for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
+      fprintf ( stderr, " " );
+}
+
+
+/*---------------------------------------------*/
+static 
+void copyFileName ( Char* to, Char* from ) 
+{
+   if ( strlen(from) > FILE_NAME_LEN-10 )  {
+      fprintf (
+         stderr,
+         "bzip2: file name\n`%s'\n"
+         "is suspiciously (more than %d chars) long.\n"
+         "Try using a reasonable file name instead.  Sorry! :-)\n",
+         from, FILE_NAME_LEN-10
+      );
+      setExit(1);
+      exit(exitValue);
+   }
+
+  strncpy(to,from,FILE_NAME_LEN-10);
+  to[FILE_NAME_LEN-10]='\0';
+}
+
+
+/*---------------------------------------------*/
+static 
+Bool fileExists ( Char* name )
+{
+   FILE *tmp   = fopen ( name, "rb" );
+   Bool exists = (tmp != NULL);
+   if (tmp != NULL) fclose ( tmp );
+   return exists;
+}
+
+
+/*---------------------------------------------*/
+/* Open an output file safely with O_EXCL and good permissions.
+   This avoids a race condition in versions < 1.0.2, in which
+   the file was first opened and then had its interim permissions
+   set safely.  We instead use open() to create the file with
+   the interim permissions required. (--- --- rw-).
+
+   For non-Unix platforms, if we are not worrying about
+   security issues, simple this simply behaves like fopen.
+*/
+FILE* fopen_output_safely ( Char* name, const char* mode )
+{
+#  if BZ_UNIX
+   FILE*     fp;
+   IntNative fh;
+   fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
+   if (fh == -1) return NULL;
+   fp = fdopen(fh, mode);
+   if (fp == NULL) close(fh);
+   return fp;
+#  else
+   return fopen(name, mode);
+#  endif
+}
+
+
+/*---------------------------------------------*/
+/*--
+  if in doubt, return True
+--*/
+static 
+Bool notAStandardFile ( Char* name )
+{
+   IntNative      i;
+   struct MY_STAT statBuf;
+
+   i = MY_LSTAT ( name, &statBuf );
+   if (i != 0) return True;
+   if (MY_S_ISREG(statBuf.st_mode)) return False;
+   return True;
+}
+
+
+/*---------------------------------------------*/
+/*--
+  rac 11/21/98 see if file has hard links to it
+--*/
+static 
+Int32 countHardLinks ( Char* name )
+{  
+   IntNative      i;
+   struct MY_STAT statBuf;
+
+   i = MY_LSTAT ( name, &statBuf );
+   if (i != 0) return 0;
+   return (statBuf.st_nlink - 1);
+}
+
+
+/*---------------------------------------------*/
+/* Copy modification date, access date, permissions and owner from the
+   source to destination file.  We have to copy this meta-info off
+   into fileMetaInfo before starting to compress / decompress it,
+   because doing it afterwards means we get the wrong access time.
+
+   To complicate matters, in compress() and decompress() below, the
+   sequence of tests preceding the call to saveInputFileMetaInfo()
+   involves calling fileExists(), which in turn establishes its result
+   by attempting to fopen() the file, and if successful, immediately
+   fclose()ing it again.  So we have to assume that the fopen() call
+   does not cause the access time field to be updated.
+
+   Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
+   to imply that merely doing open() will not affect the access time.
+   Therefore we merely need to hope that the C library only does
+   open() as a result of fopen(), and not any kind of read()-ahead
+   cleverness.
+
+   It sounds pretty fragile to me.  Whether this carries across
+   robustly to arbitrary Unix-like platforms (or even works robustly
+   on this one, RedHat 7.2) is unknown to me.  Nevertheless ...  
+*/
+#if BZ_UNIX
+static 
+struct MY_STAT fileMetaInfo;
+#endif
+
+static 
+void saveInputFileMetaInfo ( Char *srcName )
+{
+#  if BZ_UNIX
+   IntNative retVal;
+   /* Note use of stat here, not lstat. */
+   retVal = MY_STAT( srcName, &fileMetaInfo );
+   ERROR_IF_NOT_ZERO ( retVal );
+#  endif
+}
+
+
+static 
+void applySavedMetaInfoToOutputFile ( Char *dstName )
+{
+#  if BZ_UNIX
+   IntNative      retVal;
+   struct utimbuf uTimBuf;
+
+   uTimBuf.actime = fileMetaInfo.st_atime;
+   uTimBuf.modtime = fileMetaInfo.st_mtime;
+
+   retVal = chmod ( dstName, fileMetaInfo.st_mode );
+   ERROR_IF_NOT_ZERO ( retVal );
+
+   retVal = utime ( dstName, &uTimBuf );
+   ERROR_IF_NOT_ZERO ( retVal );
+
+   retVal = chown ( dstName, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
+   /* chown() will in many cases return with EPERM, which can
+      be safely ignored.
+   */
+#  endif
+}
+
+
+/*---------------------------------------------*/
+static 
+Bool containsDubiousChars ( Char* name )
+{
+#  if BZ_UNIX
+   /* On unix, files can contain any characters and the file expansion
+    * is performed by the shell.
+    */
+   return False;
+#  else /* ! BZ_UNIX */
+   /* On non-unix (Win* platforms), wildcard characters are not allowed in 
+    * filenames.
+    */
+   for (; *name != '\0'; name++)
+      if (*name == '?' || *name == '*') return True;
+   return False;
+#  endif /* BZ_UNIX */
+}
+
+
+/*---------------------------------------------*/
+#define BZ_N_SUFFIX_PAIRS 4
+
+Char* zSuffix[BZ_N_SUFFIX_PAIRS] 
+   = { ".bz2", ".bz", ".tbz2", ".tbz" };
+Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 
+   = { "", "", ".tar", ".tar" };
+
+static 
+Bool hasSuffix ( Char* s, Char* suffix )
+{
+   Int32 ns = strlen(s);
+   Int32 nx = strlen(suffix);
+   if (ns < nx) return False;
+   if (strcmp(s + ns - nx, suffix) == 0) return True;
+   return False;
+}
+
+static 
+Bool mapSuffix ( Char* name, 
+                 Char* oldSuffix, Char* newSuffix )
+{
+   if (!hasSuffix(name,oldSuffix)) return False;
+   name[strlen(name)-strlen(oldSuffix)] = 0;
+   strcat ( name, newSuffix );
+   return True;
+}
+
+
+/*---------------------------------------------*/
+static 
+void compress ( Char *name )
+{
+   FILE  *inStr;
+   FILE  *outStr;
+   Int32 n, i;
+   struct MY_STAT statBuf;
+
+   deleteOutputOnInterrupt = False;
+
+   if (name == NULL && srcMode != SM_I2O)
+      panic ( "compress: bad modes\n" );
+
+   switch (srcMode) {
+      case SM_I2O: 
+         copyFileName ( inName, "(stdin)" );
+         copyFileName ( outName, "(stdout)" ); 
+         break;
+      case SM_F2F: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, name );
+         strcat ( outName, ".bz2" ); 
+         break;
+      case SM_F2O: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, "(stdout)" ); 
+         break;
+   }
+
+   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+      if (noisy)
+      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                progName, inName, strerror(errno) );
+      setExit(1);
+      return;
+   }
+   for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
+      if (hasSuffix(inName, zSuffix[i])) {
+         if (noisy)
+         fprintf ( stderr, 
+                   "%s: Input file %s already has %s suffix.\n",
+                   progName, inName, zSuffix[i] );
+         setExit(1);
+         return;
+      }
+   }
+   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+      MY_STAT(inName, &statBuf);
+      if ( MY_S_ISDIR(statBuf.st_mode) ) {
+         fprintf( stderr,
+                  "%s: Input file %s is a directory.\n",
+                  progName,inName);
+         setExit(1);
+         return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+      if (noisy)
+      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+      if (forceOverwrite) {
+	 remove(outName);
+      } else {
+	 fprintf ( stderr, "%s: Output file %s already exists.\n",
+		   progName, outName );
+	 setExit(1);
+	 return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite &&
+        (n=countHardLinks ( inName )) > 0) {
+      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+                progName, inName, n, n > 1 ? "s" : "" );
+      setExit(1);
+      return;
+   }
+
+   if ( srcMode == SM_F2F ) {
+      /* Save the file's meta-info before we open it.  Doing it later
+         means we mess up the access times. */
+      saveInputFileMetaInfo ( inName );
+   }
+
+   switch ( srcMode ) {
+
+      case SM_I2O:
+         inStr = stdin;
+         outStr = stdout;
+         if ( isatty ( fileno ( stdout ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't write compressed data to a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2O:
+         inStr = fopen ( inName, "rb" );
+         outStr = stdout;
+         if ( isatty ( fileno ( stdout ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't write compressed data to a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         };
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                      progName, inName, strerror(errno) );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2F:
+         inStr = fopen ( inName, "rb" );
+         outStr = fopen_output_safely ( outName, "wb" );
+         if ( outStr == NULL) {
+            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+                      progName, outName, strerror(errno) );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         }
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                      progName, inName, strerror(errno) );
+            if ( outStr != NULL ) fclose ( outStr );
+            setExit(1);
+            return;
+         };
+         break;
+
+      default:
+         panic ( "compress: bad srcMode" );
+         break;
+   }
+
+   if (verbosity >= 1) {
+      fprintf ( stderr,  "  %s: ", inName );
+      pad ( inName );
+      fflush ( stderr );
+   }
+
+   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
+   outputHandleJustInCase = outStr;
+   deleteOutputOnInterrupt = True;
+   compressStream ( inStr, outStr );
+   outputHandleJustInCase = NULL;
+
+   /*--- If there was an I/O error, we won't get here. ---*/
+   if ( srcMode == SM_F2F ) {
+      applySavedMetaInfoToOutputFile ( outName );
+      deleteOutputOnInterrupt = False;
+      if ( !keepInputFiles ) {
+         IntNative retVal = remove ( inName );
+         ERROR_IF_NOT_ZERO ( retVal );
+      }
+   }
+
+   deleteOutputOnInterrupt = False;
+}
+
+
+/*---------------------------------------------*/
+static 
+void uncompress ( Char *name )
+{
+   FILE  *inStr;
+   FILE  *outStr;
+   Int32 n, i;
+   Bool  magicNumberOK;
+   Bool  cantGuess;
+   struct MY_STAT statBuf;
+
+   deleteOutputOnInterrupt = False;
+
+   if (name == NULL && srcMode != SM_I2O)
+      panic ( "uncompress: bad modes\n" );
+
+   cantGuess = False;
+   switch (srcMode) {
+      case SM_I2O: 
+         copyFileName ( inName, "(stdin)" );
+         copyFileName ( outName, "(stdout)" ); 
+         break;
+      case SM_F2F: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, name );
+         for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
+            if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
+               goto zzz; 
+         cantGuess = True;
+         strcat ( outName, ".out" );
+         break;
+      case SM_F2O: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, "(stdout)" ); 
+         break;
+   }
+
+   zzz:
+   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+      if (noisy)
+      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                progName, inName, strerror(errno) );
+      setExit(1);
+      return;
+   }
+   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+      MY_STAT(inName, &statBuf);
+      if ( MY_S_ISDIR(statBuf.st_mode) ) {
+         fprintf( stderr,
+                  "%s: Input file %s is a directory.\n",
+                  progName,inName);
+         setExit(1);
+         return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+      if (noisy)
+      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
+      if (noisy)
+      fprintf ( stderr, 
+                "%s: Can't guess original name for %s -- using %s\n",
+                progName, inName, outName );
+      /* just a warning, no return */
+   }   
+   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+      if (forceOverwrite) {
+	remove(outName);
+      } else {
+        fprintf ( stderr, "%s: Output file %s already exists.\n",
+                  progName, outName );
+        setExit(1);
+        return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite &&
+        (n=countHardLinks ( inName ) ) > 0) {
+      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+                progName, inName, n, n > 1 ? "s" : "" );
+      setExit(1);
+      return;
+   }
+
+   if ( srcMode == SM_F2F ) {
+      /* Save the file's meta-info before we open it.  Doing it later
+         means we mess up the access times. */
+      saveInputFileMetaInfo ( inName );
+   }
+
+   switch ( srcMode ) {
+
+      case SM_I2O:
+         inStr = stdin;
+         outStr = stdout;
+         if ( isatty ( fileno ( stdin ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't read compressed data from a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2O:
+         inStr = fopen ( inName, "rb" );
+         outStr = stdout;
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+                      progName, inName, strerror(errno) );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2F:
+         inStr = fopen ( inName, "rb" );
+         outStr = fopen_output_safely ( outName, "wb" );
+         if ( outStr == NULL) {
+            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+                      progName, outName, strerror(errno) );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         }
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                      progName, inName, strerror(errno) );
+            if ( outStr != NULL ) fclose ( outStr );
+            setExit(1);
+            return;
+         };
+         break;
+
+      default:
+         panic ( "uncompress: bad srcMode" );
+         break;
+   }
+
+   if (verbosity >= 1) {
+      fprintf ( stderr, "  %s: ", inName );
+      pad ( inName );
+      fflush ( stderr );
+   }
+
+   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
+   outputHandleJustInCase = outStr;
+   deleteOutputOnInterrupt = True;
+   magicNumberOK = uncompressStream ( inStr, outStr );
+   outputHandleJustInCase = NULL;
+
+   /*--- If there was an I/O error, we won't get here. ---*/
+   if ( magicNumberOK ) {
+      if ( srcMode == SM_F2F ) {
+         applySavedMetaInfoToOutputFile ( outName );
+         deleteOutputOnInterrupt = False;
+         if ( !keepInputFiles ) {
+            IntNative retVal = remove ( inName );
+            ERROR_IF_NOT_ZERO ( retVal );
+         }
+      }
+   } else {
+      unzFailsExist = True;
+      deleteOutputOnInterrupt = False;
+      if ( srcMode == SM_F2F ) {
+         IntNative retVal = remove ( outName );
+         ERROR_IF_NOT_ZERO ( retVal );
+      }
+   }
+   deleteOutputOnInterrupt = False;
+
+   if ( magicNumberOK ) {
+      if (verbosity >= 1)
+         fprintf ( stderr, "done\n" );
+   } else {
+      setExit(2);
+      if (verbosity >= 1)
+         fprintf ( stderr, "not a bzip2 file.\n" ); else
+         fprintf ( stderr,
+                   "%s: %s is not a bzip2 file.\n",
+                   progName, inName );
+   }
+
+}
+
+
+/*---------------------------------------------*/
+static 
+void testf ( Char *name )
+{
+   FILE *inStr;
+   Bool allOK;
+   struct MY_STAT statBuf;
+
+   deleteOutputOnInterrupt = False;
+
+   if (name == NULL && srcMode != SM_I2O)
+      panic ( "testf: bad modes\n" );
+
+   copyFileName ( outName, "(none)" );
+   switch (srcMode) {
+      case SM_I2O: copyFileName ( inName, "(stdin)" ); break;
+      case SM_F2F: copyFileName ( inName, name ); break;
+      case SM_F2O: copyFileName ( inName, name ); break;
+   }
+
+   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+      if (noisy)
+      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+      fprintf ( stderr, "%s: Can't open input %s: %s.\n",
+                progName, inName, strerror(errno) );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O ) {
+      MY_STAT(inName, &statBuf);
+      if ( MY_S_ISDIR(statBuf.st_mode) ) {
+         fprintf( stderr,
+                  "%s: Input file %s is a directory.\n",
+                  progName,inName);
+         setExit(1);
+         return;
+      }
+   }
+
+   switch ( srcMode ) {
+
+      case SM_I2O:
+         if ( isatty ( fileno ( stdin ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't read compressed data from a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            setExit(1);
+            return;
+         };
+         inStr = stdin;
+         break;
+
+      case SM_F2O: case SM_F2F:
+         inStr = fopen ( inName, "rb" );
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+                      progName, inName, strerror(errno) );
+            setExit(1);
+            return;
+         };
+         break;
+
+      default:
+         panic ( "testf: bad srcMode" );
+         break;
+   }
+
+   if (verbosity >= 1) {
+      fprintf ( stderr, "  %s: ", inName );
+      pad ( inName );
+      fflush ( stderr );
+   }
+
+   /*--- Now the input handle is sane.  Do the Biz. ---*/
+   outputHandleJustInCase = NULL;
+   allOK = testStream ( inStr );
+
+   if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
+   if (!allOK) testFailsExist = True;
+}
+
+
+/*---------------------------------------------*/
+static 
+void license ( void )
+{
+   fprintf ( stderr,
+
+    "bzip2, a block-sorting file compressor.  "
+    "Version %s.\n"
+    "   \n"
+    "   Copyright (C) 1996-2005 by Julian Seward.\n"
+    "   \n"
+    "   This program is free software; you can redistribute it and/or modify\n"
+    "   it under the terms set out in the LICENSE file, which is included\n"
+    "   in the bzip2-1.0 source distribution.\n"
+    "   \n"
+    "   This program is distributed in the hope that it will be useful,\n"
+    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "   LICENSE file for more details.\n"
+    "   \n",
+    BZ2_bzlibVersion()
+   );
+}
+
+
+/*---------------------------------------------*/
+static 
+void usage ( Char *fullProgName )
+{
+   fprintf (
+      stderr,
+      "bzip2, a block-sorting file compressor.  "
+      "Version %s.\n"
+      "\n   usage: %s [flags and input files in any order]\n"
+      "\n"
+      "   -h --help           print this message\n"
+      "   -d --decompress     force decompression\n"
+      "   -z --compress       force compression\n"
+      "   -k --keep           keep (don't delete) input files\n"
+      "   -f --force          overwrite existing output files\n"
+      "   -t --test           test compressed file integrity\n"
+      "   -c --stdout         output to standard out\n"
+      "   -q --quiet          suppress noncritical error messages\n"
+      "   -v --verbose        be verbose (a 2nd -v gives more)\n"
+      "   -L --license        display software version & license\n"
+      "   -V --version        display software version & license\n"
+      "   -s --small          use less memory (at most 2500k)\n"
+      "   -1 .. -9            set block size to 100k .. 900k\n"
+      "   --fast              alias for -1\n"
+      "   --best              alias for -9\n"
+      "\n"
+      "   If invoked as `bzip2', default action is to compress.\n"
+      "              as `bunzip2',  default action is to decompress.\n"
+      "              as `bzcat', default action is to decompress to stdout.\n"
+      "\n"
+      "   If no file names are given, bzip2 compresses or decompresses\n"
+      "   from standard input to standard output.  You can combine\n"
+      "   short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
+#     if BZ_UNIX
+      "\n"
+#     endif
+      ,
+
+      BZ2_bzlibVersion(),
+      fullProgName
+   );
+}
+
+
+/*---------------------------------------------*/
+static 
+void redundant ( Char* flag )
+{
+   fprintf ( 
+      stderr, 
+      "%s: %s is redundant in versions 0.9.5 and above\n",
+      progName, flag );
+}
+
+
+/*---------------------------------------------*/
+/*--
+  All the garbage from here to main() is purely to
+  implement a linked list of command-line arguments,
+  into which main() copies argv[1 .. argc-1].
+
+  The purpose of this exercise is to facilitate 
+  the expansion of wildcard characters * and ? in 
+  filenames for OSs which don't know how to do it
+  themselves, like MSDOS, Windows 95 and NT.
+
+  The actual Dirty Work is done by the platform-
+  specific macro APPEND_FILESPEC.
+--*/
+
+typedef
+   struct zzzz {
+      Char        *name;
+      struct zzzz *link;
+   }
+   Cell;
+
+
+/*---------------------------------------------*/
+static 
+void *myMalloc ( Int32 n )
+{
+   void* p;
+
+   p = malloc ( (size_t)n );
+   if (p == NULL) outOfMemory ();
+   return p;
+}
+
+
+/*---------------------------------------------*/
+static 
+Cell *mkCell ( void )
+{
+   Cell *c;
+
+   c = (Cell*) myMalloc ( sizeof ( Cell ) );
+   c->name = NULL;
+   c->link = NULL;
+   return c;
+}
+
+
+/*---------------------------------------------*/
+static 
+Cell *snocString ( Cell *root, Char *name )
+{
+   if (root == NULL) {
+      Cell *tmp = mkCell();
+      tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
+      strcpy ( tmp->name, name );
+      return tmp;
+   } else {
+      Cell *tmp = root;
+      while (tmp->link != NULL) tmp = tmp->link;
+      tmp->link = snocString ( tmp->link, name );
+      return root;
+   }
+}
+
+
+/*---------------------------------------------*/
+static 
+void addFlagsFromEnvVar ( Cell** argList, Char* varName ) 
+{
+   Int32 i, j, k;
+   Char *envbase, *p;
+
+   envbase = getenv(varName);
+   if (envbase != NULL) {
+      p = envbase;
+      i = 0;
+      while (True) {
+         if (p[i] == 0) break;
+         p += i;
+         i = 0;
+         while (isspace((Int32)(p[0]))) p++;
+         while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
+         if (i > 0) {
+            k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
+            for (j = 0; j < k; j++) tmpName[j] = p[j];
+            tmpName[k] = 0;
+            APPEND_FLAG(*argList, tmpName);
+         }
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+#define ISFLAG(s) (strcmp(aa->name, (s))==0)
+
+IntNative main ( IntNative argc, Char *argv[] )
+{
+   Int32  i, j;
+   Char   *tmp;
+   Cell   *argList;
+   Cell   *aa;
+   Bool   decode;
+
+   /*-- Be really really really paranoid :-) --*/
+   if (sizeof(Int32) != 4 || sizeof(UInt32) != 4  ||
+       sizeof(Int16) != 2 || sizeof(UInt16) != 2  ||
+       sizeof(Char)  != 1 || sizeof(UChar)  != 1)
+      configError();
+
+   /*-- Initialise --*/
+   outputHandleJustInCase  = NULL;
+   smallMode               = False;
+   keepInputFiles          = False;
+   forceOverwrite          = False;
+   noisy                   = True;
+   verbosity               = 0;
+   blockSize100k           = 9;
+   testFailsExist          = False;
+   unzFailsExist           = False;
+   numFileNames            = 0;
+   numFilesProcessed       = 0;
+   workFactor              = 30;
+   deleteOutputOnInterrupt = False;
+   exitValue               = 0;
+   i = j = 0; /* avoid bogus warning from egcs-1.1.X */
+
+   /*-- Set up signal handlers for mem access errors --*/
+   signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
+#  if BZ_UNIX
+#  ifndef __DJGPP__
+   signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
+#  endif
+#  endif
+
+   copyFileName ( inName,  "(none)" );
+   copyFileName ( outName, "(none)" );
+
+   copyFileName ( progNameReally, argv[0] );
+   progName = &progNameReally[0];
+   for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
+      if (*tmp == PATH_SEP) progName = tmp + 1;
+
+
+   /*-- Copy flags from env var BZIP2, and 
+        expand filename wildcards in arg list.
+   --*/
+   argList = NULL;
+   addFlagsFromEnvVar ( &argList,  "BZIP2" );
+   addFlagsFromEnvVar ( &argList,  "BZIP" );
+   for (i = 1; i <= argc-1; i++)
+      APPEND_FILESPEC(argList, argv[i]);
+
+
+   /*-- Find the length of the longest filename --*/
+   longestFileName = 7;
+   numFileNames    = 0;
+   decode          = True;
+   for (aa = argList; aa != NULL; aa = aa->link) {
+      if (ISFLAG("--")) { decode = False; continue; }
+      if (aa->name[0] == '-' && decode) continue;
+      numFileNames++;
+      if (longestFileName < (Int32)strlen(aa->name) )
+         longestFileName = (Int32)strlen(aa->name);
+   }
+
+
+   /*-- Determine source modes; flag handling may change this too. --*/
+   if (numFileNames == 0)
+      srcMode = SM_I2O; else srcMode = SM_F2F;
+
+
+   /*-- Determine what to do (compress/uncompress/test/cat). --*/
+   /*-- Note that subsequent flag handling may change this. --*/
+   opMode = OM_Z;
+
+   if ( (strstr ( progName, "unzip" ) != 0) ||
+        (strstr ( progName, "UNZIP" ) != 0) )
+      opMode = OM_UNZ;
+
+   if ( (strstr ( progName, "z2cat" ) != 0) ||
+        (strstr ( progName, "Z2CAT" ) != 0) ||
+        (strstr ( progName, "zcat" ) != 0)  ||
+        (strstr ( progName, "ZCAT" ) != 0) )  {
+      opMode = OM_UNZ;
+      srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
+   }
+
+
+   /*-- Look at the flags. --*/
+   for (aa = argList; aa != NULL; aa = aa->link) {
+      if (ISFLAG("--")) break;
+      if (aa->name[0] == '-' && aa->name[1] != '-') {
+         for (j = 1; aa->name[j] != '\0'; j++) {
+            switch (aa->name[j]) {
+               case 'c': srcMode          = SM_F2O; break;
+               case 'd': opMode           = OM_UNZ; break;
+               case 'z': opMode           = OM_Z; break;
+               case 'f': forceOverwrite   = True; break;
+               case 't': opMode           = OM_TEST; break;
+               case 'k': keepInputFiles   = True; break;
+               case 's': smallMode        = True; break;
+               case 'q': noisy            = False; break;
+               case '1': blockSize100k    = 1; break;
+               case '2': blockSize100k    = 2; break;
+               case '3': blockSize100k    = 3; break;
+               case '4': blockSize100k    = 4; break;
+               case '5': blockSize100k    = 5; break;
+               case '6': blockSize100k    = 6; break;
+               case '7': blockSize100k    = 7; break;
+               case '8': blockSize100k    = 8; break;
+               case '9': blockSize100k    = 9; break;
+               case 'V':
+               case 'L': license();            break;
+               case 'v': verbosity++; break;
+               case 'h': usage ( progName );
+                         exit ( 0 );
+                         break;
+               default:  fprintf ( stderr, "%s: Bad flag `%s'\n",
+                                   progName, aa->name );
+                         usage ( progName );
+                         exit ( 1 );
+                         break;
+            }
+         }
+      }
+   }
+   
+   /*-- And again ... --*/
+   for (aa = argList; aa != NULL; aa = aa->link) {
+      if (ISFLAG("--")) break;
+      if (ISFLAG("--stdout"))            srcMode          = SM_F2O;  else
+      if (ISFLAG("--decompress"))        opMode           = OM_UNZ;  else
+      if (ISFLAG("--compress"))          opMode           = OM_Z;    else
+      if (ISFLAG("--force"))             forceOverwrite   = True;    else
+      if (ISFLAG("--test"))              opMode           = OM_TEST; else
+      if (ISFLAG("--keep"))              keepInputFiles   = True;    else
+      if (ISFLAG("--small"))             smallMode        = True;    else
+      if (ISFLAG("--quiet"))             noisy            = False;   else
+      if (ISFLAG("--version"))           license();                  else
+      if (ISFLAG("--license"))           license();                  else
+      if (ISFLAG("--exponential"))       workFactor = 1;             else 
+      if (ISFLAG("--repetitive-best"))   redundant(aa->name);        else
+      if (ISFLAG("--repetitive-fast"))   redundant(aa->name);        else
+      if (ISFLAG("--fast"))              blockSize100k = 1;          else
+      if (ISFLAG("--best"))              blockSize100k = 9;          else
+      if (ISFLAG("--verbose"))           verbosity++;                else
+      if (ISFLAG("--help"))              { usage ( progName ); exit ( 0 ); }
+         else
+         if (strncmp ( aa->name, "--", 2) == 0) {
+            fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
+            usage ( progName );
+            exit ( 1 );
+         }
+   }
+
+   if (verbosity > 4) verbosity = 4;
+   if (opMode == OM_Z && smallMode && blockSize100k > 2) 
+      blockSize100k = 2;
+
+   if (opMode == OM_TEST && srcMode == SM_F2O) {
+      fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
+                progName );
+      exit ( 1 );
+   }
+
+   if (srcMode == SM_F2O && numFileNames == 0)
+      srcMode = SM_I2O;
+
+   if (opMode != OM_Z) blockSize100k = 0;
+
+   if (srcMode == SM_F2F) {
+      signal (SIGINT,  mySignalCatcher);
+      signal (SIGTERM, mySignalCatcher);
+#     if BZ_UNIX
+      signal (SIGHUP,  mySignalCatcher);
+#     endif
+   }
+
+   if (opMode == OM_Z) {
+     if (srcMode == SM_I2O) {
+        compress ( NULL );
+     } else {
+        decode = True;
+        for (aa = argList; aa != NULL; aa = aa->link) {
+           if (ISFLAG("--")) { decode = False; continue; }
+           if (aa->name[0] == '-' && decode) continue;
+           numFilesProcessed++;
+           compress ( aa->name );
+        }
+     }
+   } 
+   else
+
+   if (opMode == OM_UNZ) {
+      unzFailsExist = False;
+      if (srcMode == SM_I2O) {
+         uncompress ( NULL );
+      } else {
+         decode = True;
+         for (aa = argList; aa != NULL; aa = aa->link) {
+            if (ISFLAG("--")) { decode = False; continue; }
+            if (aa->name[0] == '-' && decode) continue;
+            numFilesProcessed++;
+            uncompress ( aa->name );
+         }      
+      }
+      if (unzFailsExist) { 
+         setExit(2); 
+         exit(exitValue);
+      }
+   } 
+
+   else {
+      testFailsExist = False;
+      if (srcMode == SM_I2O) {
+         testf ( NULL );
+      } else {
+         decode = True;
+         for (aa = argList; aa != NULL; aa = aa->link) {
+	    if (ISFLAG("--")) { decode = False; continue; }
+            if (aa->name[0] == '-' && decode) continue;
+            numFilesProcessed++;
+            testf ( aa->name );
+	 }
+      }
+      if (testFailsExist && noisy) {
+         fprintf ( stderr,
+           "\n"
+           "You can use the `bzip2recover' program to attempt to recover\n"
+           "data from undamaged sections of corrupted files.\n\n"
+         );
+         setExit(2);
+         exit(exitValue);
+      }
+   }
+
+   /* Free the argument list memory to mollify leak detectors 
+      (eg) Purify, Checker.  Serves no other useful purpose.
+   */
+   aa = argList;
+   while (aa != NULL) {
+      Cell* aa2 = aa->link;
+      if (aa->name != NULL) free(aa->name);
+      free(aa);
+      aa = aa2;
+   }
+
+   return exitValue;
+}
+
+
+/*-----------------------------------------------------------*/
+/*--- end                                         bzip2.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt
new file mode 100644
index 000000000..bf895b6cb
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt
@@ -0,0 +1,391 @@
+
+NAME
+       bzip2, bunzip2 - a block-sorting file compressor, v1.0.3
+       bzcat - decompresses files to stdout
+       bzip2recover - recovers data from damaged bzip2 files
+
+
+SYNOPSIS
+       bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
+       bunzip2 [ -fkvsVL ] [ filenames ...  ]
+       bzcat [ -s ] [ filenames ...  ]
+       bzip2recover filename
+
+
+DESCRIPTION
+       bzip2  compresses  files  using  the Burrows-Wheeler block
+       sorting text compression algorithm,  and  Huffman  coding.
+       Compression  is  generally  considerably  better than that
+       achieved by more conventional LZ77/LZ78-based compressors,
+       and  approaches  the performance of the PPM family of sta-
+       tistical compressors.
+
+       The command-line options are deliberately very similar  to
+       those of GNU gzip, but they are not identical.
+
+       bzip2  expects  a list of file names to accompany the com-
+       mand-line flags.  Each file is replaced  by  a  compressed
+       version  of  itself,  with  the  name "original_name.bz2".
+       Each compressed file has the same modification date,  per-
+       missions, and, when possible, ownership as the correspond-
+       ing original, so that these properties  can  be  correctly
+       restored  at  decompression  time.   File name handling is
+       naive in the sense that there is no mechanism for preserv-
+       ing  original file names, permissions, ownerships or dates
+       in filesystems which lack these concepts, or have  serious
+       file name length restrictions, such as MS-DOS.
+
+       bzip2  and  bunzip2 will by default not overwrite existing
+       files.  If you want this to happen, specify the -f flag.
+
+       If no file names  are  specified,  bzip2  compresses  from
+       standard  input  to  standard output.  In this case, bzip2
+       will decline to write compressed output to a terminal,  as
+       this  would  be  entirely  incomprehensible  and therefore
+       pointless.
+
+       bunzip2 (or bzip2 -d) decompresses  all  specified  files.
+       Files which were not created by bzip2 will be detected and
+       ignored, and a warning issued.  bzip2  attempts  to  guess
+       the  filename  for  the decompressed file from that of the
+       compressed file as follows:
+
+              filename.bz2    becomes   filename
+              filename.bz     becomes   filename
+              filename.tbz2   becomes   filename.tar
+              filename.tbz    becomes   filename.tar
+              anyothername    becomes   anyothername.out
+
+       If the file does not end in one of the recognised endings,
+       .bz2,  .bz,  .tbz2 or .tbz, bzip2 complains that it cannot
+       guess the name of the original file, and uses the original
+       name with .out appended.
+
+       As  with compression, supplying no filenames causes decom-
+       pression from standard input to standard output.
+
+       bunzip2 will correctly decompress a file which is the con-
+       catenation of two or more compressed files.  The result is
+       the concatenation of the corresponding uncompressed files.
+       Integrity testing (-t) of concatenated compressed files is
+       also supported.
+
+       You can also compress or decompress files to the  standard
+       output  by giving the -c flag.  Multiple files may be com-
+       pressed and decompressed like this.  The resulting outputs
+       are  fed  sequentially to stdout.  Compression of multiple
+       files in this manner generates a stream containing  multi-
+       ple compressed file representations.  Such a stream can be
+       decompressed correctly only  by  bzip2  version  0.9.0  or
+       later.   Earlier  versions of bzip2 will stop after decom-
+       pressing the first file in the stream.
+
+       bzcat (or bzip2 -dc) decompresses all specified  files  to
+       the standard output.
+
+       bzip2  will  read arguments from the environment variables
+       BZIP2 and BZIP, in  that  order,  and  will  process  them
+       before  any  arguments  read  from the command line.  This
+       gives a convenient way to supply default arguments.
+
+       Compression is always performed, even  if  the  compressed
+       file  is slightly larger than the original.  Files of less
+       than about one hundred bytes tend to get larger, since the
+       compression  mechanism  has  a  constant  overhead  in the
+       region of 50 bytes.  Random data (including the output  of
+       most  file  compressors)  is  coded at about 8.05 bits per
+       byte, giving an expansion of around 0.5%.
+
+       As a self-check for your  protection,  bzip2  uses  32-bit
+       CRCs  to make sure that the decompressed version of a file
+       is identical to the original.  This guards against corrup-
+       tion  of  the compressed data, and against undetected bugs
+       in bzip2 (hopefully very unlikely).  The chances  of  data
+       corruption  going  undetected  is  microscopic,  about one
+       chance in four billion for each file processed.  Be aware,
+       though,  that  the  check occurs upon decompression, so it
+       can only tell you that something is wrong.  It can't  help
+       you  recover  the original uncompressed data.  You can use
+       bzip2recover to try to recover data from damaged files.
+
+       Return values: 0 for a normal exit,  1  for  environmental
+       problems  (file not found, invalid flags, I/O errors, &c),
+       2 to indicate a corrupt compressed file, 3 for an internal
+       consistency error (eg, bug) which caused bzip2 to panic.
+
+
+OPTIONS
+       -c --stdout
+              Compress or decompress to standard output.
+
+       -d --decompress
+              Force  decompression.  bzip2, bunzip2 and bzcat are
+              really the same program,  and  the  decision  about
+              what  actions to take is done on the basis of which
+              name is used.  This flag overrides that  mechanism,
+              and forces bzip2 to decompress.
+
+       -z --compress
+              The   complement   to   -d:   forces   compression,
+              regardless of the invocation name.
+
+       -t --test
+              Check integrity of the specified file(s), but don't
+              decompress  them.   This  really  performs  a trial
+              decompression and throws away the result.
+
+       -f --force
+              Force overwrite of output files.   Normally,  bzip2
+              will  not  overwrite  existing  output files.  Also
+              forces bzip2 to break hard links to files, which it
+              otherwise wouldn't do.
+
+              bzip2  normally  declines to decompress files which
+              don't have the  correct  magic  header  bytes.   If
+              forced  (-f),  however,  it  will  pass  such files
+              through unmodified.  This is how GNU gzip  behaves.
+
+       -k --keep
+              Keep  (don't delete) input files during compression
+              or decompression.
+
+       -s --small
+              Reduce memory usage, for compression, decompression
+              and  testing.   Files  are  decompressed and tested
+              using a modified algorithm which only requires  2.5
+              bytes  per  block byte.  This means any file can be
+              decompressed in 2300k of memory,  albeit  at  about
+              half the normal speed.
+
+              During  compression,  -s  selects  a  block size of
+              200k, which limits memory use to  around  the  same
+              figure,  at  the expense of your compression ratio.
+              In short, if your  machine  is  low  on  memory  (8
+              megabytes  or  less),  use  -s for everything.  See
+              MEMORY MANAGEMENT below.
+
+       -q --quiet
+              Suppress non-essential warning messages.   Messages
+              pertaining  to I/O errors and other critical events
+              will not be suppressed.
+
+       -v --verbose
+              Verbose mode -- show the compression ratio for each
+              file  processed.   Further  -v's  increase the ver-
+              bosity level, spewing out lots of information which
+              is primarily of interest for diagnostic purposes.
+
+       -L --license -V --version
+              Display  the  software  version,  license terms and
+              conditions.
+
+       -1 (or --fast) to -9 (or --best)
+              Set the block size to 100 k, 200 k ..  900  k  when
+              compressing.   Has  no  effect  when decompressing.
+              See MEMORY MANAGEMENT below.  The --fast and --best
+              aliases  are  primarily for GNU gzip compatibility.
+              In particular, --fast doesn't make things  signifi-
+              cantly  faster.   And  --best  merely  selects  the
+              default behaviour.
+
+       --     Treats all subsequent arguments as file names, even
+              if they start with a dash.  This is so you can han-
+              dle files with names beginning  with  a  dash,  for
+              example: bzip2 -- -myfilename.
+
+       --repetitive-fast --repetitive-best
+              These  flags  are  redundant  in versions 0.9.5 and
+              above.  They provided some coarse control over  the
+              behaviour  of the sorting algorithm in earlier ver-
+              sions, which was sometimes useful.  0.9.5 and above
+              have  an  improved  algorithm  which  renders these
+              flags irrelevant.
+
+
+MEMORY MANAGEMENT
+       bzip2 compresses large files in blocks.   The  block  size
+       affects  both  the  compression  ratio  achieved,  and the
+       amount of memory needed for compression and decompression.
+       The  flags  -1  through  -9  specify  the block size to be
+       100,000 bytes through 900,000 bytes (the default)  respec-
+       tively.   At  decompression  time, the block size used for
+       compression is read from  the  header  of  the  compressed
+       file, and bunzip2 then allocates itself just enough memory
+       to decompress the file.  Since block sizes are  stored  in
+       compressed  files,  it follows that the flags -1 to -9 are
+       irrelevant to and so ignored during decompression.
+
+       Compression and decompression requirements, in bytes,  can
+       be estimated as:
+
+              Compression:   400k + ( 8 x block size )
+
+              Decompression: 100k + ( 4 x block size ), or
+                             100k + ( 2.5 x block size )
+
+       Larger  block  sizes  give  rapidly  diminishing  marginal
+       returns.  Most of the compression comes from the first two
+       or  three hundred k of block size, a fact worth bearing in
+       mind when using bzip2  on  small  machines.   It  is  also
+       important  to  appreciate  that  the  decompression memory
+       requirement is set at compression time by  the  choice  of
+       block size.
+
+       For  files  compressed  with  the default 900k block size,
+       bunzip2 will require about 3700 kbytes to decompress.   To
+       support decompression of any file on a 4 megabyte machine,
+       bunzip2 has an option to  decompress  using  approximately
+       half this amount of memory, about 2300 kbytes.  Decompres-
+       sion speed is also halved, so you should use  this  option
+       only where necessary.  The relevant flag is -s.
+
+       In general, try and use the largest block size memory con-
+       straints  allow,  since  that  maximises  the  compression
+       achieved.   Compression and decompression speed are virtu-
+       ally unaffected by block size.
+
+       Another significant point applies to files which fit in  a
+       single  block  --  that  means  most files you'd encounter
+       using a large block  size.   The  amount  of  real  memory
+       touched is proportional to the size of the file, since the
+       file is smaller than a block.  For example, compressing  a
+       file  20,000  bytes  long  with the flag -9 will cause the
+       compressor to allocate around 7600k of  memory,  but  only
+       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
+       decompressor will allocate 3700k but  only  touch  100k  +
+       20000 * 4 = 180 kbytes.
+
+       Here  is a table which summarises the maximum memory usage
+       for different block sizes.  Also  recorded  is  the  total
+       compressed  size for 14 files of the Calgary Text Compres-
+       sion Corpus totalling 3,141,622 bytes.  This column  gives
+       some  feel  for  how  compression  varies with block size.
+       These figures tend to understate the advantage  of  larger
+       block  sizes  for  larger files, since the Corpus is domi-
+       nated by smaller files.
+
+                  Compress   Decompress   Decompress   Corpus
+           Flag     usage      usage       -s usage     Size
+
+            -1      1200k       500k         350k      914704
+            -2      2000k       900k         600k      877703
+            -3      2800k      1300k         850k      860338
+            -4      3600k      1700k        1100k      846899
+            -5      4400k      2100k        1350k      845160
+            -6      5200k      2500k        1600k      838626
+            -7      6100k      2900k        1850k      834096
+            -8      6800k      3300k        2100k      828642
+            -9      7600k      3700k        2350k      828642
+
+
+RECOVERING DATA FROM DAMAGED FILES
+       bzip2 compresses files in blocks, usually 900kbytes  long.
+       Each block is handled independently.  If a media or trans-
+       mission error causes a multi-block  .bz2  file  to  become
+       damaged,  it  may  be  possible  to  recover data from the
+       undamaged blocks in the file.
+
+       The compressed representation of each block  is  delimited
+       by  a  48-bit pattern, which makes it possible to find the
+       block boundaries with reasonable  certainty.   Each  block
+       also  carries its own 32-bit CRC, so damaged blocks can be
+       distinguished from undamaged ones.
+
+       bzip2recover is a  simple  program  whose  purpose  is  to
+       search  for blocks in .bz2 files, and write each block out
+       into its own .bz2 file.  You can then use bzip2 -t to test
+       the integrity of the resulting files, and decompress those
+       which are undamaged.
+
+       bzip2recover takes a single argument, the name of the dam-
+       aged    file,    and    writes    a    number   of   files
+       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
+       the   extracted   blocks.   The   output   filenames   are
+       designed  so  that the use of wildcards in subsequent pro-
+       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
+       ered_data" -- processes the files in the correct order.
+
+       bzip2recover should be of most use dealing with large .bz2
+       files,  as  these will contain many blocks.  It is clearly
+       futile to use it on damaged single-block  files,  since  a
+       damaged  block  cannot  be recovered.  If you wish to min-
+       imise any potential data loss through media  or  transmis-
+       sion errors, you might consider compressing with a smaller
+       block size.
+
+
+PERFORMANCE NOTES
+       The sorting phase of compression gathers together  similar
+       strings  in  the  file.  Because of this, files containing
+       very long runs of  repeated  symbols,  like  "aabaabaabaab
+       ..."   (repeated  several hundred times) may compress more
+       slowly than normal.  Versions 0.9.5 and  above  fare  much
+       better  than previous versions in this respect.  The ratio
+       between worst-case and average-case compression time is in
+       the  region  of  10:1.  For previous versions, this figure
+       was more like 100:1.  You can use the -vvvv option to mon-
+       itor progress in great detail, if you want.
+
+       Decompression speed is unaffected by these phenomena.
+
+       bzip2  usually  allocates  several  megabytes of memory to
+       operate in, and then charges all over it in a fairly  ran-
+       dom  fashion.   This means that performance, both for com-
+       pressing and decompressing, is largely determined  by  the
+       speed  at  which  your  machine  can service cache misses.
+       Because of this, small changes to the code to  reduce  the
+       miss  rate  have  been observed to give disproportionately
+       large performance improvements.  I imagine bzip2 will per-
+       form best on machines with very large caches.
+
+
+CAVEATS
+       I/O  error  messages  are not as helpful as they could be.
+       bzip2 tries hard to detect I/O errors  and  exit  cleanly,
+       but  the  details  of  what  the problem is sometimes seem
+       rather misleading.
+
+       This manual page pertains to version 1.0.3 of bzip2.  Com-
+       pressed  data created by this version is entirely forwards
+       and  backwards  compatible  with   the   previous   public
+       releases,  versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and
+       1.0.2, but with the following exception: 0.9.0  and  above
+       can  correctly decompress multiple concatenated compressed
+       files.  0.1pl2 cannot do this; it will stop  after  decom-
+       pressing just the first file in the stream.
+
+       bzip2recover  versions prior to 1.0.2 used 32-bit integers
+       to represent bit positions in compressed  files,  so  they
+       could  not handle compressed files more than 512 megabytes
+       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
+       platforms  which  support them (GNU supported targets, and
+       Windows).  To establish whether or  not  bzip2recover  was
+       built  with  such  a limitation, run it without arguments.
+       In any event you can build yourself an  unlimited  version
+       if  you  can  recompile  it  with MaybeUInt64 set to be an
+       unsigned 64-bit integer.
+
+
+AUTHOR
+       Julian Seward, jsewardbzip.org.
+
+       http://www.bzip.org
+
+       The ideas embodied in bzip2 are due to (at least) the fol-
+       lowing  people: Michael Burrows and David Wheeler (for the
+       block sorting transformation), David Wheeler  (again,  for
+       the Huffman coder), Peter Fenwick (for the structured cod-
+       ing model in the original bzip, and many refinements), and
+       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
+       arithmetic  coder  in  the  original  bzip).   I  am  much
+       indebted for their help, support and advice.  See the man-
+       ual in the source distribution for pointers to sources  of
+       documentation.  Christian von Roques encouraged me to look
+       for faster sorting algorithms, so as to speed up  compres-
+       sion.  Bela Lubkin encouraged me to improve the worst-case
+       compression performance.  Donna Robinson XMLised the docu-
+       mentation.   The bz* scripts are derived from those of GNU
+       gzip.  Many people sent patches, helped  with  portability
+       problems,  lent  machines,  gave advice and were generally
+       helpful.
+
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c
new file mode 100644
index 000000000..5cd405dd4
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c
@@ -0,0 +1,546 @@
+
+/*-----------------------------------------------------------*/
+/*--- Block recoverer program for bzip2                   ---*/
+/*---                                      bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
+
+/*--
+  This program is bzip2recover, a program to attempt data 
+  salvage from damaged files created by the accompanying
+  bzip2-1.0.3 program.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0.3 of 15 February 2005
+--*/
+
+/*--
+  This program is a complete hack and should be rewritten
+  properly.  It isn't very complicated.
+--*/
+
+#include 
+#include 
+#include 
+#include 
+
+
+/* This program records bit locations in the file to be recovered.
+   That means that if 64-bit ints are not supported, we will not
+   be able to recover .bz2 files over 512MB (2^32 bits) long.
+   On GNU supported platforms, we take advantage of the 64-bit
+   int support to circumvent this problem.  Ditto MSVC.
+
+   This change occurred in version 1.0.2; all prior versions have
+   the 512MB limitation.
+*/
+#ifdef __GNUC__
+   typedef  unsigned long long int  MaybeUInt64;
+#  define MaybeUInt64_FMT "%Lu"
+#else
+#ifdef _MSC_VER
+   typedef  unsigned __int64  MaybeUInt64;
+#  define MaybeUInt64_FMT "%I64u"
+#else
+   typedef  unsigned int   MaybeUInt64;
+#  define MaybeUInt64_FMT "%u"
+#endif
+#endif
+
+typedef  unsigned int   UInt32;
+typedef  int            Int32;
+typedef  unsigned char  UChar;
+typedef  char           Char;
+typedef  unsigned char  Bool;
+#define True    ((Bool)1)
+#define False   ((Bool)0)
+
+
+#define BZ_MAX_FILENAME 2000
+
+Char inFileName[BZ_MAX_FILENAME];
+Char outFileName[BZ_MAX_FILENAME];
+Char progName[BZ_MAX_FILENAME];
+
+MaybeUInt64 bytesOut = 0;
+MaybeUInt64 bytesIn  = 0;
+
+
+/*---------------------------------------------------*/
+/*--- Header bytes                                ---*/
+/*---------------------------------------------------*/
+
+#define BZ_HDR_B 0x42                         /* 'B' */
+#define BZ_HDR_Z 0x5a                         /* 'Z' */
+#define BZ_HDR_h 0x68                         /* 'h' */
+#define BZ_HDR_0 0x30                         /* '0' */
+ 
+
+/*---------------------------------------------------*/
+/*--- I/O errors                                  ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+void readError ( void )
+{
+   fprintf ( stderr,
+             "%s: I/O error reading `%s', possible reason follows.\n",
+            progName, inFileName );
+   perror ( progName );
+   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+void writeError ( void )
+{
+   fprintf ( stderr,
+             "%s: I/O error reading `%s', possible reason follows.\n",
+            progName, inFileName );
+   perror ( progName );
+   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+void mallocFail ( Int32 n )
+{
+   fprintf ( stderr,
+             "%s: malloc failed on request for %d bytes.\n",
+            progName, n );
+   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+void tooManyBlocks ( Int32 max_handled_blocks )
+{
+   fprintf ( stderr,
+             "%s: `%s' appears to contain more than %d blocks\n",
+            progName, inFileName, max_handled_blocks );
+   fprintf ( stderr,
+             "%s: and cannot be handled.  To fix, increase\n",
+             progName );
+   fprintf ( stderr, 
+             "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+typedef
+   struct {
+      FILE*  handle;
+      Int32  buffer;
+      Int32  buffLive;
+      Char   mode;
+   }
+   BitStream;
+
+
+/*---------------------------------------------*/
+BitStream* bsOpenReadStream ( FILE* stream )
+{
+   BitStream *bs = malloc ( sizeof(BitStream) );
+   if (bs == NULL) mallocFail ( sizeof(BitStream) );
+   bs->handle = stream;
+   bs->buffer = 0;
+   bs->buffLive = 0;
+   bs->mode = 'r';
+   return bs;
+}
+
+
+/*---------------------------------------------*/
+BitStream* bsOpenWriteStream ( FILE* stream )
+{
+   BitStream *bs = malloc ( sizeof(BitStream) );
+   if (bs == NULL) mallocFail ( sizeof(BitStream) );
+   bs->handle = stream;
+   bs->buffer = 0;
+   bs->buffLive = 0;
+   bs->mode = 'w';
+   return bs;
+}
+
+
+/*---------------------------------------------*/
+void bsPutBit ( BitStream* bs, Int32 bit )
+{
+   if (bs->buffLive == 8) {
+      Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
+      if (retVal == EOF) writeError();
+      bytesOut++;
+      bs->buffLive = 1;
+      bs->buffer = bit & 0x1;
+   } else {
+      bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
+      bs->buffLive++;
+   };
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Returns 0 or 1, or 2 to indicate EOF.
+--*/
+Int32 bsGetBit ( BitStream* bs )
+{
+   if (bs->buffLive > 0) {
+      bs->buffLive --;
+      return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
+   } else {
+      Int32 retVal = getc ( bs->handle );
+      if ( retVal == EOF ) {
+         if (errno != 0) readError();
+         return 2;
+      }
+      bs->buffLive = 7;
+      bs->buffer = retVal;
+      return ( ((bs->buffer) >> 7) & 0x1 );
+   }
+}
+
+
+/*---------------------------------------------*/
+void bsClose ( BitStream* bs )
+{
+   Int32 retVal;
+
+   if ( bs->mode == 'w' ) {
+      while ( bs->buffLive < 8 ) {
+         bs->buffLive++;
+         bs->buffer <<= 1;
+      };
+      retVal = putc ( (UChar) (bs->buffer), bs->handle );
+      if (retVal == EOF) writeError();
+      bytesOut++;
+      retVal = fflush ( bs->handle );
+      if (retVal == EOF) writeError();
+   }
+   retVal = fclose ( bs->handle );
+   if (retVal == EOF) {
+      if (bs->mode == 'w') writeError(); else readError();
+   }
+   free ( bs );
+}
+
+
+/*---------------------------------------------*/
+void bsPutUChar ( BitStream* bs, UChar c )
+{
+   Int32 i;
+   for (i = 7; i >= 0; i--)
+      bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+void bsPutUInt32 ( BitStream* bs, UInt32 c )
+{
+   Int32 i;
+
+   for (i = 31; i >= 0; i--)
+      bsPutBit ( bs, (c >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+Bool endsInBz2 ( Char* name )
+{
+   Int32 n = strlen ( name );
+   if (n <= 4) return False;
+   return
+      (name[n-4] == '.' &&
+       name[n-3] == 'b' &&
+       name[n-2] == 'z' &&
+       name[n-1] == '2');
+}
+
+
+/*---------------------------------------------------*/
+/*---                                             ---*/
+/*---------------------------------------------------*/
+
+/* This logic isn't really right when it comes to Cygwin. */
+#ifdef _WIN32
+#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
+#else
+#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
+#endif
+
+#define BLOCK_HEADER_HI  0x00003141UL
+#define BLOCK_HEADER_LO  0x59265359UL
+
+#define BLOCK_ENDMARK_HI 0x00001772UL
+#define BLOCK_ENDMARK_LO 0x45385090UL
+
+/* Increase if necessary.  However, a .bz2 file with > 50000 blocks
+   would have an uncompressed size of at least 40GB, so the chances
+   are low you'll need to up this.
+*/
+#define BZ_MAX_HANDLED_BLOCKS 50000
+
+MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];
+
+Int32 main ( Int32 argc, Char** argv )
+{
+   FILE*       inFile;
+   FILE*       outFile;
+   BitStream*  bsIn, *bsWr;
+   Int32       b, wrBlock, currBlock, rbCtr;
+   MaybeUInt64 bitsRead;
+
+   UInt32      buffHi, buffLo, blockCRC;
+   Char*       p;
+
+   strcpy ( progName, argv[0] );
+   inFileName[0] = outFileName[0] = 0;
+
+   fprintf ( stderr, 
+             "bzip2recover 1.0.3: extracts blocks from damaged .bz2 files.\n" );
+
+   if (argc != 2) {
+      fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
+                        progName, progName );
+      switch (sizeof(MaybeUInt64)) {
+         case 8:
+            fprintf(stderr, 
+                    "\trestrictions on size of recovered file: None\n");
+            break;
+         case 4:
+            fprintf(stderr, 
+                    "\trestrictions on size of recovered file: 512 MB\n");
+            fprintf(stderr, 
+                    "\tto circumvent, recompile with MaybeUInt64 as an\n"
+                    "\tunsigned 64-bit int.\n");
+            break;
+         default:
+            fprintf(stderr, 
+                    "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
+                    "configuration error.\n");
+            break;
+      }
+      exit(1);
+   }
+
+   if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
+      fprintf ( stderr, 
+                "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
+                progName, (int)strlen(argv[1]) );
+      exit(1);
+   }
+
+   strcpy ( inFileName, argv[1] );
+
+   inFile = fopen ( inFileName, "rb" );
+   if (inFile == NULL) {
+      fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
+      exit(1);
+   }
+
+   bsIn = bsOpenReadStream ( inFile );
+   fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
+
+   bitsRead = 0;
+   buffHi = buffLo = 0;
+   currBlock = 0;
+   bStart[currBlock] = 0;
+
+   rbCtr = 0;
+
+   while (True) {
+      b = bsGetBit ( bsIn );
+      bitsRead++;
+      if (b == 2) {
+         if (bitsRead >= bStart[currBlock] &&
+            (bitsRead - bStart[currBlock]) >= 40) {
+            bEnd[currBlock] = bitsRead-1;
+            if (currBlock > 0)
+               fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
+                                 " to " MaybeUInt64_FMT " (incomplete)\n",
+                         currBlock,  bStart[currBlock], bEnd[currBlock] );
+         } else
+            currBlock--;
+         break;
+      }
+      buffHi = (buffHi << 1) | (buffLo >> 31);
+      buffLo = (buffLo << 1) | (b & 1);
+      if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI 
+             && buffLo == BLOCK_HEADER_LO)
+           || 
+           ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI 
+             && buffLo == BLOCK_ENDMARK_LO)
+         ) {
+         if (bitsRead > 49) {
+            bEnd[currBlock] = bitsRead-49;
+         } else {
+            bEnd[currBlock] = 0;
+         }
+         if (currBlock > 0 &&
+	     (bEnd[currBlock] - bStart[currBlock]) >= 130) {
+            fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
+                              " to " MaybeUInt64_FMT "\n",
+                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
+            rbStart[rbCtr] = bStart[currBlock];
+            rbEnd[rbCtr] = bEnd[currBlock];
+            rbCtr++;
+         }
+         if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
+            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
+         currBlock++;
+
+         bStart[currBlock] = bitsRead;
+      }
+   }
+
+   bsClose ( bsIn );
+
+   /*-- identified blocks run from 1 to rbCtr inclusive. --*/
+
+   if (rbCtr < 1) {
+      fprintf ( stderr,
+                "%s: sorry, I couldn't find any block boundaries.\n",
+                progName );
+      exit(1);
+   };
+
+   fprintf ( stderr, "%s: splitting into blocks\n", progName );
+
+   inFile = fopen ( inFileName, "rb" );
+   if (inFile == NULL) {
+      fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
+      exit(1);
+   }
+   bsIn = bsOpenReadStream ( inFile );
+
+   /*-- placate gcc's dataflow analyser --*/
+   blockCRC = 0; bsWr = 0;
+
+   bitsRead = 0;
+   outFile = NULL;
+   wrBlock = 0;
+   while (True) {
+      b = bsGetBit(bsIn);
+      if (b == 2) break;
+      buffHi = (buffHi << 1) | (buffLo >> 31);
+      buffLo = (buffLo << 1) | (b & 1);
+      if (bitsRead == 47+rbStart[wrBlock]) 
+         blockCRC = (buffHi << 16) | (buffLo >> 16);
+
+      if (outFile != NULL && bitsRead >= rbStart[wrBlock]
+                          && bitsRead <= rbEnd[wrBlock]) {
+         bsPutBit ( bsWr, b );
+      }
+
+      bitsRead++;
+
+      if (bitsRead == rbEnd[wrBlock]+1) {
+         if (outFile != NULL) {
+            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
+            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
+            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
+            bsPutUInt32 ( bsWr, blockCRC );
+            bsClose ( bsWr );
+         }
+         if (wrBlock >= rbCtr) break;
+         wrBlock++;
+      } else
+      if (bitsRead == rbStart[wrBlock]) {
+         /* Create the output file name, correctly handling leading paths. 
+            (31.10.2001 by Sergey E. Kusikov) */
+         Char* split;
+         Int32 ofs, k;
+         for (k = 0; k < BZ_MAX_FILENAME; k++) 
+            outFileName[k] = 0;
+         strcpy (outFileName, inFileName);
+         split = strrchr (outFileName, BZ_SPLIT_SYM);
+         if (split == NULL) {
+            split = outFileName;
+         } else {
+            ++split;
+	 }
+	 /* Now split points to the start of the basename. */
+         ofs  = split - outFileName;
+         sprintf (split, "rec%5d", wrBlock+1);
+         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
+         strcat (outFileName, inFileName + ofs);
+
+         if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
+
+         fprintf ( stderr, "   writing block %d to `%s' ...\n",
+                           wrBlock+1, outFileName );
+
+         outFile = fopen ( outFileName, "wb" );
+         if (outFile == NULL) {
+            fprintf ( stderr, "%s: can't write `%s'\n",
+                      progName, outFileName );
+            exit(1);
+         }
+         bsWr = bsOpenWriteStream ( outFile );
+         bsPutUChar ( bsWr, BZ_HDR_B );    
+         bsPutUChar ( bsWr, BZ_HDR_Z );    
+         bsPutUChar ( bsWr, BZ_HDR_h );    
+         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
+         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
+         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
+         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
+      }
+   }
+
+   fprintf ( stderr, "%s: finished\n", progName );
+   return 0;
+}
+
+
+
+/*-----------------------------------------------------------*/
+/*--- end                                  bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.c b/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.c
new file mode 100644
index 000000000..195f51a78
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.c
@@ -0,0 +1,1617 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+/*--
+   CHANGES
+   ~~~~~~~
+   0.9.0 -- original version.
+
+   0.9.0a/b -- no changes in this file.
+
+   0.9.0c
+      * made zero-length BZ_FLUSH work correctly in bzCompress().
+      * fixed bzWrite/bzRead to ignore zero-length requests.
+      * fixed bzread to correctly handle read requests after EOF.
+      * wrong parameter order in call to bzDecompressInit in
+        bzBuffToBuffDecompress.  Fixed.
+--*/
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+   fprintf(stderr, 
+      "\n\nbzip2/libbzip2: internal error number %d.\n"
+      "This is a bug in bzip2/libbzip2, %s.\n"
+      "Please report it to me at: jseward@bzip.org.  If this happened\n"
+      "when you were using some program which uses libbzip2 as a\n"
+      "component, you should also report this bug to the author(s)\n"
+      "of that program.  Please make an effort to report this bug;\n"
+      "timely and accurate bug reports eventually lead to higher\n"
+      "quality software.  Thanks.  Julian Seward, 15 February 2005.\n\n",
+      errcode,
+      BZ2_bzlibVersion()
+   );
+
+   if (errcode == 1007) {
+   fprintf(stderr,
+      "\n*** A special note about internal error number 1007 ***\n"
+      "\n"
+      "Experience suggests that a common cause of i.e. 1007\n"
+      "is unreliable memory or other hardware.  The 1007 assertion\n"
+      "just happens to cross-check the results of huge numbers of\n"
+      "memory reads/writes, and so acts (unintendedly) as a stress\n"
+      "test of your memory system.\n"
+      "\n"
+      "I suggest the following: try compressing the file again,\n"
+      "possibly monitoring progress in detail with the -vv flag.\n"
+      "\n"
+      "* If the error cannot be reproduced, and/or happens at different\n"
+      "  points in compression, you may have a flaky memory system.\n"
+      "  Try a memory-test program.  I have used Memtest86\n"
+      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
+      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
+      "  power-on test, and may find failures that the BIOS doesn't.\n"
+      "\n"
+      "* If the error can be repeatably reproduced, this is a bug in\n"
+      "  bzip2, and I would very much like to hear about it.  Please\n"
+      "  let me know, and, ideally, save a copy of the file causing the\n"
+      "  problem -- without which I will be unable to investigate it.\n"
+      "\n"
+   );
+   }
+
+   exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+   if (sizeof(int)   != 4) return 0;
+   if (sizeof(short) != 2) return 0;
+   if (sizeof(char)  != 1) return 0;
+   return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+   void* v = malloc ( items * size );
+   return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+   if (addr != NULL) free ( addr );
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+   Int32 i;
+   s->nblock = 0;
+   s->numZ = 0;
+   s->state_out_pos = 0;
+   BZ_INITIALISE_CRC ( s->blockCRC );
+   for (i = 0; i < 256; i++) s->inUse[i] = False;
+   s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+   s->state_in_ch  = 256;
+   s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+   if (s->state_in_ch < 256 && s->state_in_len > 0)
+      return False; else
+      return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit) 
+                    ( bz_stream* strm, 
+                     int        blockSize100k,
+                     int        verbosity,
+                     int        workFactor )
+{
+   Int32   n;
+   EState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL || 
+       blockSize100k < 1 || blockSize100k > 9 ||
+       workFactor < 0 || workFactor > 250)
+     return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(EState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm = strm;
+
+   s->arr1 = NULL;
+   s->arr2 = NULL;
+   s->ftab = NULL;
+
+   n       = 100000 * blockSize100k;
+   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
+   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
+
+   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+      if (s->arr1 != NULL) BZFREE(s->arr1);
+      if (s->arr2 != NULL) BZFREE(s->arr2);
+      if (s->ftab != NULL) BZFREE(s->ftab);
+      if (s       != NULL) BZFREE(s);
+      return BZ_MEM_ERROR;
+   }
+
+   s->blockNo           = 0;
+   s->state             = BZ_S_INPUT;
+   s->mode              = BZ_M_RUNNING;
+   s->combinedCRC       = 0;
+   s->blockSize100k     = blockSize100k;
+   s->nblockMAX         = 100000 * blockSize100k - 19;
+   s->verbosity         = verbosity;
+   s->workFactor        = workFactor;
+
+   s->block             = (UChar*)s->arr2;
+   s->mtfv              = (UInt16*)s->arr1;
+   s->zbits             = NULL;
+   s->ptr               = (UInt32*)s->arr1;
+
+   strm->state          = s;
+   strm->total_in_lo32  = 0;
+   strm->total_in_hi32  = 0;
+   strm->total_out_lo32 = 0;
+   strm->total_out_hi32 = 0;
+   init_RL ( s );
+   prepare_new_block ( s );
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+   Int32 i;
+   UChar ch = (UChar)(s->state_in_ch);
+   for (i = 0; i < s->state_in_len; i++) {
+      BZ_UPDATE_CRC( s->blockCRC, ch );
+   }
+   s->inUse[s->state_in_ch] = True;
+   switch (s->state_in_len) {
+      case 1:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 2:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 3:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      default:
+         s->inUse[s->state_in_len-4] = True;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+         s->nblock++;
+         break;
+   }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+   if (s->state_in_ch < 256) add_pair_to_block ( s );
+   init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
+{                                                 \
+   UInt32 zchh = (UInt32)(zchh0);                 \
+   /*-- fast track the common case --*/           \
+   if (zchh != zs->state_in_ch &&                 \
+       zs->state_in_len == 1) {                   \
+      UChar ch = (UChar)(zs->state_in_ch);        \
+      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
+      zs->inUse[zs->state_in_ch] = True;          \
+      zs->block[zs->nblock] = (UChar)ch;          \
+      zs->nblock++;                               \
+      zs->state_in_ch = zchh;                     \
+   }                                              \
+   else                                           \
+   /*-- general, uncommon cases --*/              \
+   if (zchh != zs->state_in_ch ||                 \
+      zs->state_in_len == 255) {                  \
+      if (zs->state_in_ch < 256)                  \
+         add_pair_to_block ( zs );                \
+      zs->state_in_ch = zchh;                     \
+      zs->state_in_len = 1;                       \
+   } else {                                       \
+      zs->state_in_len++;                         \
+   }                                              \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+   Bool progress_in = False;
+
+   if (s->mode == BZ_M_RUNNING) {
+
+      /*-- fast track the common case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+      }
+
+   } else {
+
+      /*-- general, uncommon case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         /*-- flush/finish end? --*/
+         if (s->avail_in_expect == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+         s->avail_in_expect--;
+      }
+   }
+   return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+   Bool progress_out = False;
+
+   while (True) {
+
+      /*-- no output space? --*/
+      if (s->strm->avail_out == 0) break;
+
+      /*-- block done? --*/
+      if (s->state_out_pos >= s->numZ) break;
+
+      progress_out = True;
+      *(s->strm->next_out) = s->zbits[s->state_out_pos];
+      s->state_out_pos++;
+      s->strm->avail_out--;
+      s->strm->next_out++;
+      s->strm->total_out_lo32++;
+      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+   }
+
+   return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+   Bool progress_in  = False;
+   Bool progress_out = False;
+   EState* s = strm->state;
+   
+   while (True) {
+
+      if (s->state == BZ_S_OUTPUT) {
+         progress_out |= copy_output_until_stop ( s );
+         if (s->state_out_pos < s->numZ) break;
+         if (s->mode == BZ_M_FINISHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+         prepare_new_block ( s );
+         s->state = BZ_S_INPUT;
+         if (s->mode == BZ_M_FLUSHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+      }
+
+      if (s->state == BZ_S_INPUT) {
+         progress_in |= copy_input_until_stop ( s );
+         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+            flush_RL ( s );
+            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->nblock >= s->nblockMAX) {
+            BZ2_compressBlock ( s, False );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->strm->avail_in == 0) {
+            break;
+         }
+      }
+
+   }
+
+   return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+   Bool progress;
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   preswitch:
+   switch (s->mode) {
+
+      case BZ_M_IDLE:
+         return BZ_SEQUENCE_ERROR;
+
+      case BZ_M_RUNNING:
+         if (action == BZ_RUN) {
+            progress = handle_compress ( strm );
+            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+         } 
+         else
+	 if (action == BZ_FLUSH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FLUSHING;
+            goto preswitch;
+         }
+         else
+         if (action == BZ_FINISH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FINISHING;
+            goto preswitch;
+         }
+         else 
+            return BZ_PARAM_ERROR;
+
+      case BZ_M_FLUSHING:
+         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+         s->mode = BZ_M_RUNNING;
+         return BZ_RUN_OK;
+
+      case BZ_M_FINISHING:
+         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (!progress) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+         s->mode = BZ_M_IDLE;
+         return BZ_STREAM_END;
+   }
+   return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+{
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->arr1 != NULL) BZFREE(s->arr1);
+   if (s->arr2 != NULL) BZFREE(s->arr2);
+   if (s->ftab != NULL) BZFREE(s->ftab);
+   BZFREE(strm->state);
+
+   strm->state = NULL;   
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit) 
+                     ( bz_stream* strm, 
+                       int        verbosity,
+                       int        small )
+{
+   DState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(DState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm                  = strm;
+   strm->state              = s;
+   s->state                 = BZ_X_MAGIC_1;
+   s->bsLive                = 0;
+   s->bsBuff                = 0;
+   s->calculatedCombinedCRC = 0;
+   strm->total_in_lo32      = 0;
+   strm->total_in_hi32      = 0;
+   strm->total_out_lo32     = 0;
+   strm->total_out_hi32     = 0;
+   s->smallDecompress       = (Bool)small;
+   s->ll4                   = NULL;
+   s->ll16                  = NULL;
+   s->tt                    = NULL;
+   s->currBlockNo           = 0;
+   s->verbosity             = verbosity;
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+               
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      /* restore */
+      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
+      UChar         c_state_out_ch       = s->state_out_ch;
+      Int32         c_state_out_len      = s->state_out_len;
+      Int32         c_nblock_used        = s->nblock_used;
+      Int32         c_k0                 = s->k0;
+      UInt32*       c_tt                 = s->tt;
+      UInt32        c_tPos               = s->tPos;
+      char*         cs_next_out          = s->strm->next_out;
+      unsigned int  cs_avail_out         = s->strm->avail_out;
+      /* end restore */
+
+      UInt32       avail_out_INIT = cs_avail_out;
+      Int32        s_save_nblockPP = s->save_nblock+1;
+      unsigned int total_out_lo32_old;
+
+      while (True) {
+
+         /* try to finish existing run */
+         if (c_state_out_len > 0) {
+            while (True) {
+               if (cs_avail_out == 0) goto return_notr;
+               if (c_state_out_len == 1) break;
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               c_state_out_len--;
+               cs_next_out++;
+               cs_avail_out--;
+            }
+            s_state_out_len_eq_one:
+            {
+               if (cs_avail_out == 0) { 
+                  c_state_out_len = 1; goto return_notr;
+               };
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               cs_next_out++;
+               cs_avail_out--;
+            }
+         }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used > s_save_nblockPP)
+            return True;
+
+         /* can a new run be started? */
+         if (c_nblock_used == s_save_nblockPP) {
+            c_state_out_len = 0; goto return_notr;
+         };   
+         c_state_out_ch = c_k0;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (k1 != c_k0) { 
+            c_k0 = k1; goto s_state_out_len_eq_one; 
+         };
+         if (c_nblock_used == s_save_nblockPP) 
+            goto s_state_out_len_eq_one;
+   
+         c_state_out_len = 2;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         c_state_out_len = 3;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         c_state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST_C(c_k0); c_nblock_used++;
+      }
+
+      return_notr:
+      total_out_lo32_old = s->strm->total_out_lo32;
+      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+      if (s->strm->total_out_lo32 < total_out_lo32_old)
+         s->strm->total_out_hi32++;
+
+      /* save */
+      s->calculatedBlockCRC = c_calculatedBlockCRC;
+      s->state_out_ch       = c_state_out_ch;
+      s->state_out_len      = c_state_out_len;
+      s->nblock_used        = c_nblock_used;
+      s->k0                 = c_k0;
+      s->tt                 = c_tt;
+      s->tPos               = c_tPos;
+      s->strm->next_out     = cs_next_out;
+      s->strm->avail_out    = cs_avail_out;
+      /* end save */
+   }
+   return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+   Int32 nb, na, mid;
+   nb = 0;
+   na = 256;
+   do {
+      mid = (nb + na) >> 1;
+      if (indx >= cftab[mid]) nb = mid; else na = mid;
+   }
+   while (na - nb != 1);
+   return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); s->nblock_used++;
+      }
+
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+   Bool    corrupt;
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   while (True) {
+      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+      if (s->state == BZ_X_OUTPUT) {
+         if (s->smallDecompress)
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
+         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+            if (s->verbosity >= 3) 
+               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
+                          s->calculatedBlockCRC );
+            if (s->verbosity >= 2) VPrintf0 ( "]" );
+            if (s->calculatedBlockCRC != s->storedBlockCRC)
+               return BZ_DATA_ERROR;
+            s->calculatedCombinedCRC 
+               = (s->calculatedCombinedCRC << 1) | 
+                    (s->calculatedCombinedCRC >> 31);
+            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+            s->state = BZ_X_BLKHDR_1;
+         } else {
+            return BZ_OK;
+         }
+      }
+      if (s->state >= BZ_X_MAGIC_1) {
+         Int32 r = BZ2_decompress ( s );
+         if (r == BZ_STREAM_END) {
+            if (s->verbosity >= 3)
+               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
+                          s->storedCombinedCRC, s->calculatedCombinedCRC );
+            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+               return BZ_DATA_ERROR;
+            return r;
+         }
+         if (s->state != BZ_X_OUTPUT) return r;
+      }
+   }
+
+   AssertH ( 0, 6001 );
+
+   return 0;  /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+{
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->tt   != NULL) BZFREE(s->tt);
+   if (s->ll16 != NULL) BZFREE(s->ll16);
+   if (s->ll4  != NULL) BZFREE(s->ll4);
+
+   BZFREE(strm->state);
+   strm->state = NULL;
+
+   return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff                              ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee)                    \
+{                                         \
+   if (bzerror != NULL) *bzerror = eee;   \
+   if (bzf != NULL) bzf->lastErr = eee;   \
+}
+
+typedef 
+   struct {
+      FILE*     handle;
+      Char      buf[BZ_MAX_UNUSED];
+      Int32     bufN;
+      Bool      writing;
+      bz_stream strm;
+      Int32     lastErr;
+      Bool      initialisedOk;
+   }
+   bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen) 
+                    ( int*  bzerror,      
+                      FILE* f, 
+                      int   blockSize100k, 
+                      int   verbosity,
+                      int   workFactor )
+{
+   Int32   ret;
+   bzFile* bzf = NULL;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL ||
+       (blockSize100k < 1 || blockSize100k > 9) ||
+       (workFactor < 0 || workFactor > 250) ||
+       (verbosity < 0 || verbosity > 4))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+   bzf->initialisedOk = False;
+   bzf->bufN          = 0;
+   bzf->handle        = f;
+   bzf->writing       = True;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+
+   if (workFactor == 0) workFactor = 30;
+   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = 0;
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+             ( int*    bzerror, 
+               BZFILE* b, 
+               void*   buf, 
+               int     len )
+{
+   Int32 n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return; };
+
+   bzf->strm.avail_in = len;
+   bzf->strm.next_in  = buf;
+
+   while (True) {
+      bzf->strm.avail_out = BZ_MAX_UNUSED;
+      bzf->strm.next_out = bzf->buf;
+      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+      if (ret != BZ_RUN_OK)
+         { BZ_SETERR(ret); return; };
+
+      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                       n, bzf->handle );
+         if (n != n2 || ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return; };
+      }
+
+      if (bzf->strm.avail_in == 0)
+         { BZ_SETERR(BZ_OK); return; };
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in,
+                    unsigned int* nbytes_out )
+{
+   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
+                        nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in_lo32,
+                    unsigned int* nbytes_in_hi32,
+                    unsigned int* nbytes_out_lo32,
+                    unsigned int* nbytes_out_hi32 )
+{
+   Int32   n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+   if ((!abandon) && bzf->lastErr == BZ_OK) {
+      while (True) {
+         bzf->strm.avail_out = BZ_MAX_UNUSED;
+         bzf->strm.next_out = bzf->buf;
+         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+            { BZ_SETERR(ret); return; };
+
+         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                          n, bzf->handle );
+            if (n != n2 || ferror(bzf->handle))
+               { BZ_SETERR(BZ_IO_ERROR); return; };
+         }
+
+         if (ret == BZ_STREAM_END) break;
+      }
+   }
+
+   if ( !abandon && !ferror ( bzf->handle ) ) {
+      fflush ( bzf->handle );
+      if (ferror(bzf->handle))
+         { BZ_SETERR(BZ_IO_ERROR); return; };
+   }
+
+   if (nbytes_in_lo32 != NULL)
+      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+   if (nbytes_in_hi32 != NULL)
+      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+   if (nbytes_out_lo32 != NULL)
+      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+   if (nbytes_out_hi32 != NULL)
+      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+   BZ_SETERR(BZ_OK);
+   BZ2_bzCompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen) 
+                   ( int*  bzerror, 
+                     FILE* f, 
+                     int   verbosity,
+                     int   small,
+                     void* unused,
+                     int   nUnused )
+{
+   bzFile* bzf = NULL;
+   int     ret;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL || 
+       (small != 0 && small != 1) ||
+       (verbosity < 0 || verbosity > 4) ||
+       (unused == NULL && nUnused != 0) ||
+       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL) 
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+
+   bzf->initialisedOk = False;
+   bzf->handle        = f;
+   bzf->bufN          = 0;
+   bzf->writing       = False;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+   
+   while (nUnused > 0) {
+      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+      unused = ((void*)( 1 + ((UChar*)(unused))  ));
+      nUnused--;
+   }
+
+   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = bzf->bufN;
+   bzf->strm.next_in  = bzf->buf;
+
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+   if (bzf->initialisedOk)
+      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead) 
+           ( int*    bzerror, 
+             BZFILE* b, 
+             void*   buf, 
+             int     len )
+{
+   Int32   n, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return 0; };
+
+   bzf->strm.avail_out = len;
+   bzf->strm.next_out = buf;
+
+   while (True) {
+
+      if (ferror(bzf->handle)) 
+         { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+         n = fread ( bzf->buf, sizeof(UChar), 
+                     BZ_MAX_UNUSED, bzf->handle );
+         if (ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return 0; };
+         bzf->bufN = n;
+         bzf->strm.avail_in = bzf->bufN;
+         bzf->strm.next_in = bzf->buf;
+      }
+
+      ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+      if (ret != BZ_OK && ret != BZ_STREAM_END)
+         { BZ_SETERR(ret); return 0; };
+
+      if (ret == BZ_OK && myfeof(bzf->handle) && 
+          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+      if (ret == BZ_STREAM_END)
+         { BZ_SETERR(BZ_STREAM_END);
+           return len - bzf->strm.avail_out; };
+      if (bzf->strm.avail_out == 0)
+         { BZ_SETERR(BZ_OK); return len; };
+      
+   }
+
+   return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused) 
+                     ( int*    bzerror, 
+                       BZFILE* b, 
+                       void**  unused, 
+                       int*    nUnused )
+{
+   bzFile* bzf = (bzFile*)b;
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (bzf->lastErr != BZ_STREAM_END)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (unused == NULL || nUnused == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+   BZ_SETERR(BZ_OK);
+   *nUnused = bzf->strm.avail_in;
+   *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress) 
+                         ( char*         dest, 
+                           unsigned int* destLen,
+                           char*         source, 
+                           unsigned int  sourceLen,
+                           int           blockSize100k, 
+                           int           verbosity, 
+                           int           workFactor )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       blockSize100k < 1 || blockSize100k > 9 ||
+       verbosity < 0 || verbosity > 4 ||
+       workFactor < 0 || workFactor > 250) 
+      return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+   if (ret == BZ_FINISH_OK) goto output_overflow;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;   
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow:
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OUTBUFF_FULL;
+
+   errhandler:
+   BZ2_bzCompressEnd ( &strm );
+   return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress) 
+                           ( char*         dest, 
+                             unsigned int* destLen,
+                             char*         source, 
+                             unsigned int  sourceLen,
+                             int           small,
+                             int           verbosity )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       (small != 0 && small != 1) ||
+       verbosity < 0 || verbosity > 4) 
+          return BZ_PARAM_ERROR;
+
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzDecompress ( &strm );
+   if (ret == BZ_OK) goto output_overflow_or_eof;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;
+   BZ2_bzDecompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow_or_eof:
+   if (strm.avail_out > 0) {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_UNEXPECTED_EOF;
+   } else {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_OUTBUFF_FULL;
+   };      
+
+   errhandler:
+   BZ2_bzDecompressEnd ( &strm );
+   return ret; 
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   Code contributed by Yoshioka Tsuneo
+   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+   return version like "0.9.0c".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+   return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#   include 
+#   include 
+#   define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+               ( const char *path,   /* no use when bzdopen */
+                 int fd,             /* no use when bzdopen */
+                 const char *mode,
+                 int open_mode)      /* bzopen: 0, bzdopen:1 */
+{
+   int    bzerr;
+   char   unused[BZ_MAX_UNUSED];
+   int    blockSize100k = 9;
+   int    writing       = 0;
+   char   mode2[10]     = "";
+   FILE   *fp           = NULL;
+   BZFILE *bzfp         = NULL;
+   int    verbosity     = 0;
+   int    workFactor    = 30;
+   int    smallMode     = 0;
+   int    nUnused       = 0; 
+
+   if (mode == NULL) return NULL;
+   while (*mode) {
+      switch (*mode) {
+      case 'r':
+         writing = 0; break;
+      case 'w':
+         writing = 1; break;
+      case 's':
+         smallMode = 1; break;
+      default:
+         if (isdigit((int)(*mode))) {
+            blockSize100k = *mode-BZ_HDR_0;
+         }
+      }
+      mode++;
+   }
+   strcat(mode2, writing ? "w" : "r" );
+   strcat(mode2,"b");   /* binary mode */
+
+   if (open_mode==0) {
+      if (path==NULL || strcmp(path,"")==0) {
+        fp = (writing ? stdout : stdin);
+        SET_BINARY_MODE(fp);
+      } else {
+        fp = fopen(path,mode2);
+      }
+   } else {
+#ifdef BZ_STRICT_ANSI
+      fp = NULL;
+#else
+      fp = _fdopen(fd,mode2);
+#endif
+   }
+   if (fp == NULL) return NULL;
+
+   if (writing) {
+      /* Guard against total chaos and anarchy -- JRS */
+      if (blockSize100k < 1) blockSize100k = 1;
+      if (blockSize100k > 9) blockSize100k = 9; 
+      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+                             verbosity,workFactor);
+   } else {
+      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+                            unused,nUnused);
+   }
+   if (bzfp == NULL) {
+      if (fp != stdin && fp != stdout) fclose(fp);
+      return NULL;
+   }
+   return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   open file for read or write.
+      ex) bzopen("file","w9")
+      case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+               ( const char *path,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+               ( int fd,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+   int bzerr, nread;
+   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+   nread = BZ2_bzRead(&bzerr,b,buf,len);
+   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+      return nread;
+   } else {
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+   int bzerr;
+
+   BZ2_bzWrite(&bzerr,b,buf,len);
+   if(bzerr == BZ_OK){
+      return len;
+   }else{
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+   /* do nothing now... */
+   return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+   int bzerr;
+   FILE *fp = ((bzFile *)b)->handle;
+   
+   if (b==NULL) {return;}
+   if(((bzFile*)b)->writing){
+      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+      if(bzerr != BZ_OK){
+         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+      }
+   }else{
+      BZ2_bzReadClose(&bzerr,b);
+   }
+   if(fp!=stdin && fp!=stdout){
+      fclose(fp);
+   }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   return last error code 
+--*/
+static char *bzerrorstrings[] = {
+       "OK"
+      ,"SEQUENCE_ERROR"
+      ,"PARAM_ERROR"
+      ,"MEM_ERROR"
+      ,"DATA_ERROR"
+      ,"DATA_ERROR_MAGIC"
+      ,"IO_ERROR"
+      ,"UNEXPECTED_EOF"
+      ,"OUTBUFF_FULL"
+      ,"CONFIG_ERROR"
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+   int err = ((bzFile *)b)->lastErr;
+
+   if(err>0) err = 0;
+   *errnum = err;
+   return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.h b/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.h
new file mode 100644
index 000000000..323724394
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.h
@@ -0,0 +1,323 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef 
+   struct {
+      char *next_in;
+      unsigned int avail_in;
+      unsigned int total_in_lo32;
+      unsigned int total_in_hi32;
+
+      char *next_out;
+      unsigned int avail_out;
+      unsigned int total_out_lo32;
+      unsigned int total_out_hi32;
+
+      void *state;
+
+      void *(*bzalloc)(void *,int,int);
+      void (*bzfree)(void *,void *);
+      void *opaque;
+   } 
+   bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include 
+#endif
+
+#ifdef _WIN32
+#   include 
+#   ifdef small
+      /* windows.h define small to char */
+#      undef small
+#   endif
+#   ifdef BZ_EXPORT
+#   define BZ_API(func) WINAPI func
+#   define BZ_EXTERN extern
+#   else
+   /* import windows dll dynamically */
+#   define BZ_API(func) (WINAPI * func)
+#   define BZ_EXTERN
+#   endif
+#else
+#   define BZ_API(func) func
+#   define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
+      bz_stream* strm, 
+      int        blockSize100k, 
+      int        verbosity, 
+      int        workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
+      bz_stream* strm, 
+      int action 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
+      bz_stream *strm, 
+      int       verbosity, 
+      int       small
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
+      bz_stream *strm 
+   );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
+      int*  bzerror,   
+      FILE* f, 
+      int   verbosity, 
+      int   small,
+      void* unused,    
+      int   nUnused 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
+      int*    bzerror, 
+      BZFILE* b 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void**  unused,  
+      int*    nUnused 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
+      int*  bzerror,      
+      FILE* f, 
+      int   blockSize100k, 
+      int   verbosity, 
+      int   workFactor 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in, 
+      unsigned int* nbytes_out 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in_lo32, 
+      unsigned int* nbytes_in_hi32, 
+      unsigned int* nbytes_out_lo32, 
+      unsigned int* nbytes_out_hi32
+   );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           blockSize100k, 
+      int           verbosity, 
+      int           workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           small, 
+      int           verbosity 
+   );
+
+
+/*--
+   Code contributed by Yoshioka Tsuneo
+   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+      void
+   );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+      const char *path,
+      const char *mode
+   );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+      int        fd,
+      const char *mode
+   );
+         
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+      BZFILE* b, 
+      void* buf, 
+      int len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+      BZFILE* b
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+      BZFILE* b
+   );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+      BZFILE *b, 
+      int    *errnum
+   );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib_private.h b/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib_private.h
new file mode 100644
index 000000000..ca76fe62b
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib_private.h
@@ -0,0 +1,537 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include 
+
+#ifndef BZ_NO_STDIO
+#include 
+#include 
+#include 
+#endif
+
+#include "bzlib.h"
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION  "1.0.3, 15-Feb-2005"
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__  /* */
+#endif 
+
+#ifndef BZ_NO_STDIO
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+   { if (!(cond)) {       \
+      fprintf ( stderr,   \
+        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+      exit(1); \
+   }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+#define VPrintf0(zf) \
+   fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+   fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+   fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+   fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+   fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+   fprintf(stderr,zf,za1,za2,za3,za4,za5)
+#else
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg) /* */
+#define VPrintf0(zf) /* */
+#define VPrintf1(zf,za1) /* */
+#define VPrintf2(zf,za1,za2) /* */
+#define VPrintf3(zf,za1,za2,za3) /* */
+#define VPrintf4(zf,za1,za2,za3,za4) /* */
+#define VPrintf5(zf,za1,za2,za3,za4,za5) /* */
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+  
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS                          \
+   Int32 rNToGo;                               \
+   Int32 rTPos                                 \
+
+#define BZ_RAND_INIT_MASK                      \
+   s->rNToGo = 0;                              \
+   s->rTPos  = 0                               \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK                       \
+   if (s->rNToGo == 0) {                       \
+      s->rNToGo = BZ2_rNums[s->rTPos];         \
+      s->rTPos++;                              \
+      if (s->rTPos == 512) s->rTPos = 0;       \
+   }                                           \
+   s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar)              \
+{                                              \
+   crcVar = 0xffffffffL;                       \
+}
+
+#define BZ_FINALISE_CRC(crcVar)                \
+{                                              \
+   crcVar = ~(crcVar);                         \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha)              \
+{                                              \
+   crcVar = (crcVar << 8) ^                    \
+            BZ2_crc32Table[(crcVar >> 24) ^    \
+                           ((UChar)cha)];      \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* mode this stream is in, and whether inputting */
+      /* or outputting data */
+      Int32    mode;
+      Int32    state;
+
+      /* remembers avail_in when flush/finish requested */
+      UInt32   avail_in_expect;
+
+      /* for doing the block sorting */
+      UInt32*  arr1;
+      UInt32*  arr2;
+      UInt32*  ftab;
+      Int32    origPtr;
+
+      /* aliases for arr1 and arr2 */
+      UInt32*  ptr;
+      UChar*   block;
+      UInt16*  mtfv;
+      UChar*   zbits;
+
+      /* for deciding when to use the fallback sorting algorithm */
+      Int32    workFactor;
+
+      /* run-length-encoding of the input */
+      UInt32   state_in_ch;
+      Int32    state_in_len;
+      BZ_RAND_DECLS;
+
+      /* input and output limits and current posns */
+      Int32    nblock;
+      Int32    nblockMAX;
+      Int32    numZ;
+      Int32    state_out_pos;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      UChar    unseqToSeq[256];
+
+      /* the buffer for bit stream creation */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* block and combined CRCs */
+      UInt32   blockCRC;
+      UInt32   combinedCRC;
+
+      /* misc administratium */
+      Int32    verbosity;
+      Int32    blockNo;
+      Int32    blockSize100k;
+
+      /* stuff for coding the MTF values */
+      Int32    nMTF;
+      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+
+      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      /* second dimension: only 3 needed; 4 makes index calculations faster */
+      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+   }
+   EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void 
+BZ2_blockSort ( EState* );
+
+extern void 
+BZ2_compressBlock ( EState*, Bool );
+
+extern void 
+BZ2_bsInitWrite ( EState* );
+
+extern void 
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void 
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE        1
+#define BZ_X_OUTPUT      2
+
+#define BZ_X_MAGIC_1     10
+#define BZ_X_MAGIC_2     11
+#define BZ_X_MAGIC_3     12
+#define BZ_X_MAGIC_4     13
+#define BZ_X_BLKHDR_1    14
+#define BZ_X_BLKHDR_2    15
+#define BZ_X_BLKHDR_3    16
+#define BZ_X_BLKHDR_4    17
+#define BZ_X_BLKHDR_5    18
+#define BZ_X_BLKHDR_6    19
+#define BZ_X_BCRC_1      20
+#define BZ_X_BCRC_2      21
+#define BZ_X_BCRC_3      22
+#define BZ_X_BCRC_4      23
+#define BZ_X_RANDBIT     24
+#define BZ_X_ORIGPTR_1   25
+#define BZ_X_ORIGPTR_2   26
+#define BZ_X_ORIGPTR_3   27
+#define BZ_X_MAPPING_1   28
+#define BZ_X_MAPPING_2   29
+#define BZ_X_SELECTOR_1  30
+#define BZ_X_SELECTOR_2  31
+#define BZ_X_SELECTOR_3  32
+#define BZ_X_CODING_1    33
+#define BZ_X_CODING_2    34
+#define BZ_X_CODING_3    35
+#define BZ_X_MTF_1       36
+#define BZ_X_MTF_2       37
+#define BZ_X_MTF_3       38
+#define BZ_X_MTF_4       39
+#define BZ_X_MTF_5       40
+#define BZ_X_MTF_6       41
+#define BZ_X_ENDHDR_2    42
+#define BZ_X_ENDHDR_3    43
+#define BZ_X_ENDHDR_4    44
+#define BZ_X_ENDHDR_5    45
+#define BZ_X_ENDHDR_6    46
+#define BZ_X_CCRC_1      47
+#define BZ_X_CCRC_2      48
+#define BZ_X_CCRC_3      49
+#define BZ_X_CCRC_4      50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* state indicator for this stream */
+      Int32    state;
+
+      /* for doing the final run-length decoding */
+      UChar    state_out_ch;
+      Int32    state_out_len;
+      Bool     blockRandomised;
+      BZ_RAND_DECLS;
+
+      /* the buffer for bit stream reading */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* misc administratium */
+      Int32    blockSize100k;
+      Bool     smallDecompress;
+      Int32    currBlockNo;
+      Int32    verbosity;
+
+      /* for undoing the Burrows-Wheeler transform */
+      Int32    origPtr;
+      UInt32   tPos;
+      Int32    k0;
+      Int32    unzftab[256];
+      Int32    nblock_used;
+      Int32    cftab[257];
+      Int32    cftabCopy[257];
+
+      /* for undoing the Burrows-Wheeler transform (FAST) */
+      UInt32   *tt;
+
+      /* for undoing the Burrows-Wheeler transform (SMALL) */
+      UInt16   *ll16;
+      UChar    *ll4;
+
+      /* stored and calculated CRCs */
+      UInt32   storedBlockCRC;
+      UInt32   storedCombinedCRC;
+      UInt32   calculatedBlockCRC;
+      UInt32   calculatedCombinedCRC;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      Bool     inUse16[16];
+      UChar    seqToUnseq[256];
+
+      /* for decoding the MTF values */
+      UChar    mtfa   [MTFA_SIZE];
+      Int32    mtfbase[256 / MTFL_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    minLens[BZ_N_GROUPS];
+
+      /* save area for scalars in the main decompress code */
+      Int32    save_i;
+      Int32    save_j;
+      Int32    save_t;
+      Int32    save_alphaSize;
+      Int32    save_nGroups;
+      Int32    save_nSelectors;
+      Int32    save_EOB;
+      Int32    save_groupNo;
+      Int32    save_groupPos;
+      Int32    save_nextSym;
+      Int32    save_nblockMAX;
+      Int32    save_nblock;
+      Int32    save_es;
+      Int32    save_N;
+      Int32    save_curr;
+      Int32    save_zt;
+      Int32    save_zn; 
+      Int32    save_zvec;
+      Int32    save_zj;
+      Int32    save_gSel;
+      Int32    save_gMinlen;
+      Int32*   save_gLimit;
+      Int32*   save_gBase;
+      Int32*   save_gPerm;
+
+   }
+   DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc)                     \
+    s->tPos = s->tt[s->tPos];                 \
+    cccc = (UChar)(s->tPos & 0xff);           \
+    s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc)                   \
+    c_tPos = c_tt[c_tPos];                    \
+    cccc = (UChar)(c_tPos & 0xff);            \
+    c_tPos >>= 8;
+
+#define SET_LL4(i,n)                                          \
+   { if (((i) & 0x1) == 0)                                    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
+   }
+
+#define GET_LL4(i)                             \
+   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n)                          \
+   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
+     SET_LL4(i, n >> 16);                    \
+   }
+
+#define GET_LL(i) \
+   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc)                            \
+      cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
+      s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32 
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32 
+BZ2_decompress ( DState* );
+
+extern void 
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+                           Int32,  Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore b/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore
new file mode 100644
index 000000000..d31404340
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# Bzmore wrapped for bzip2, 
+# adapted from zmore by Philippe Troin  for Debian GNU/Linux.
+
+PATH="/usr/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+	*less)	more=less	;;
+	*)	more=more       ;;
+esac
+
+if test "`echo -n a`" = "-n a"; then
+  # looks like a SysV system:
+  n1=''; n2='\c'
+else
+  n1='-n'; n2=''
+fi
+oldtty=`stty -g 2>/dev/null`
+if stty -cbreak 2>/dev/null; then
+  cb='cbreak'; ncb='-cbreak'
+else
+  # 'stty min 1' resets eof to ^a on both SunOS and SysV!
+  cb='min 1 -icanon'; ncb='icanon eof ^d'
+fi
+if test $? -eq 0 -a -n "$oldtty"; then
+   trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
+else
+   trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
+fi
+
+if test $# = 0; then
+    if test -t 0; then
+	echo usage: $prog files...
+    else
+	bzip2 -cdfq | eval $more
+    fi
+else
+    FIRST=1
+    for FILE
+    do
+	if test $FIRST -eq 0; then
+		echo $n1 "--More--(Next file: $FILE)$n2"
+		stty $cb -echo 2>/dev/null
+		ANS=`dd bs=1 count=1 2>/dev/null` 
+		stty $ncb echo 2>/dev/null
+		echo " "
+		if test "$ANS" = 'e' -o "$ANS" = 'q'; then
+			exit
+		fi
+	fi
+	if test "$ANS" != 's'; then
+		echo "------> $FILE <------"
+		bzip2 -cdfq "$FILE" | eval $more
+	fi
+	if test -t; then
+		FIRST=0
+	fi
+    done
+fi
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1
new file mode 100644
index 000000000..b437d3b03
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1
@@ -0,0 +1,152 @@
+.\"Shamelessly copied from zmore.1 by Philippe Troin 
+.\"for Debian GNU/Linux
+.TH BZMORE 1
+.SH NAME
+bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text
+.SH SYNOPSIS
+.B bzmore
+[ name ...  ]
+.br
+.B bzless
+[ name ...  ]
+.SH NOTE
+In the following description,
+.I bzless
+and
+.I less
+can be used interchangeably with
+.I bzmore
+and
+.I more.
+.SH DESCRIPTION
+.I  Bzmore
+is a filter which allows examination of compressed or plain text files
+one screenful at a time on a soft-copy terminal.
+.I bzmore
+works on files compressed with
+.I bzip2
+and also on uncompressed files.
+If a file does not exist,
+.I bzmore
+looks for a file of the same name with the addition of a .bz2 suffix.
+.PP
+.I Bzmore
+normally pauses after each screenful, printing --More--
+at the bottom of the screen.
+If the user then types a carriage return, one more line is displayed.
+If the user hits a space,
+another screenful is displayed.  Other possibilities are enumerated later.
+.PP
+.I Bzmore
+looks in the file
+.I /etc/termcap
+to determine terminal characteristics,
+and to determine the default window size.
+On a terminal capable of displaying 24 lines,
+the default window size is 22 lines.
+Other sequences which may be typed when
+.I bzmore
+pauses, and their effects, are as follows (\fIi\fP is an optional integer
+argument, defaulting to 1) :
+.PP
+.IP \fIi\|\fP
+display
+.I i
+more lines, (or another screenful if no argument is given)
+.PP
+.IP ^D
+display 11 more lines (a ``scroll'').
+If
+.I i
+is given, then the scroll size is set to \fIi\|\fP.
+.PP
+.IP d
+same as ^D (control-D)
+.PP
+.IP \fIi\|\fPz
+same as typing a space except that \fIi\|\fP, if present, becomes the new
+window size.  Note that the window size reverts back to the default at the
+end of the current file.
+.PP
+.IP \fIi\|\fPs
+skip \fIi\|\fP lines and print a screenful of lines
+.PP
+.IP \fIi\|\fPf
+skip \fIi\fP screenfuls and print a screenful of lines
+.PP
+.IP "q or Q"
+quit reading the current file; go on to the next (if any)
+.PP
+.IP "e or q"
+When the prompt --More--(Next file: 
+.IR file )
+is printed, this command causes bzmore to exit.
+.PP
+.IP s
+When the prompt --More--(Next file: 
+.IR file )
+is printed, this command causes bzmore to skip the next file and continue.
+.PP 
+.IP =
+Display the current line number.
+.PP
+.IP \fIi\|\fP/expr
+search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
+If the pattern is not found,
+.I bzmore
+goes on to the next file (if any).
+Otherwise, a screenful is displayed, starting two lines before the place
+where the expression was found.
+The user's erase and kill characters may be used to edit the regular
+expression.
+Erasing back past the first column cancels the search command.
+.PP
+.IP \fIi\|\fPn
+search for the \fIi\|\fP-th occurrence of the last regular expression entered.
+.PP
+.IP !command
+invoke a shell with \fIcommand\|\fP. 
+The character `!' in "command" are replaced with the
+previous shell command.  The sequence "\\!" is replaced by "!".
+.PP
+.IP ":q or :Q"
+quit reading the current file; go on to the next (if any)
+(same as q or Q).
+.PP
+.IP .
+(dot) repeat the previous command.
+.PP
+The commands take effect immediately, i.e., it is not necessary to
+type a carriage return.
+Up to the time when the command character itself is given,
+the user may hit the line kill character to cancel the numerical
+argument being formed.
+In addition, the user may hit the erase character to redisplay the
+--More-- message.
+.PP
+At any time when output is being sent to the terminal, the user can
+hit the quit key (normally control\-\\).
+.I Bzmore
+will stop sending output, and will display the usual --More--
+prompt.
+The user may then enter one of the above commands in the normal manner.
+Unfortunately, some output is lost when this is done, due to the
+fact that any characters waiting in the terminal's output queue
+are flushed when the quit signal occurs.
+.PP
+The terminal is set to
+.I noecho
+mode by this program so that the output can be continuous.
+What you type will thus not show on your terminal, except for the / and !
+commands.
+.PP
+If the standard output is not a teletype, then
+.I bzmore
+acts just like
+.I bzcat,
+except that a header is printed before each file.
+.SH FILES
+.DT
+/etc/termcap		Terminal data base
+.SH "SEE ALSO"
+more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/compress.c b/contrib/vmap_extractor_v2/stormlib/bzip2/compress.c
new file mode 100644
index 000000000..7e0c29155
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/compress.c
@@ -0,0 +1,716 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+/*--
+   CHANGES
+   ~~~~~~~
+   0.9.0 -- original version.
+
+   0.9.0a/b -- no changes in this file.
+
+   0.9.0c
+      * changed setting of nGroups in sendMTFValues() so as to 
+        do a bit better on small files
+--*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s->bsLive = 0;
+   s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s->bsLive > 0) {
+      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+      s->numZ++;
+      s->bsBuff <<= 8;
+      s->bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s->bsLive >= 8) {                   \
+      s->zbits[s->numZ]                       \
+         = (UChar)(s->bsBuff >> 24);          \
+      s->numZ++;                              \
+      s->bsBuff <<= 8;                        \
+      s->bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s->bsBuff |= (v << (32 - s->bsLive - n));
+   s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u >> 24) & 0xffL );
+   bsW ( s, 8, (u >> 16) & 0xffL );
+   bsW ( s, 8, (u >>  8) & 0xffL );
+   bsW ( s, 8,  u        & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->unseqToSeq[i] = s->nInUse;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s->ptr;
+   UChar* block  = s->block;
+   UInt16* mtfv  = s->mtfv;
+
+   makeMaps_e ( s );
+   EOB = s->nInUse+1;
+
+   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i < s->nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr <= i, "generateMTFValues(1)" );
+      j = ptr[i]-1; if (j < 0) j += s->nblock;
+      ll_i = s->unseqToSeq[block[j]];
+      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend > 0) {
+            zPend--;
+            while (True) {
+               if (zPend & 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s->mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s->mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend < 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &(yy[0]);
+            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend > 0) {
+      zPend--;
+      while (True) {
+         if (zPend & 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s->mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s->mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend < 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+   s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s->mtfv;
+
+   if (s->verbosity >= 3)
+      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
+                "%d+2 syms in use\n", 
+                s->nblock, s->nMTF, s->nInUse );
+
+   alphaSize = s->nInUse+2;
+   for (t = 0; t < BZ_N_GROUPS; t++)
+      for (v = 0; v < alphaSize; v++)
+         s->len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s->nMTF > 0, 3001 );
+   if (s->nMTF < 200)  nGroups = 2; else
+   if (s->nMTF < 600)  nGroups = 3; else
+   if (s->nMTF < 1200) nGroups = 4; else
+   if (s->nMTF < 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s->nMTF;
+      gs = 0;
+      while (nPart > 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq < tFreq && ge < alphaSize-1) {
+            ge++;
+            aFreq += s->mtfFreq[ge];
+         }
+
+         if (ge > gs 
+             && nPart != nGroups && nPart != 1 
+             && ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s->mtfFreq[ge];
+            ge--;
+         }
+
+         if (s->verbosity >= 3)
+            VPrintf5( "      initial group %d, [%d .. %d], "
+                      "has %d syms (%4.1f%%)\n",
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
+ 
+         for (v = 0; v < alphaSize; v++)
+            if (v >= gs && v <= ge) 
+               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s->len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+      for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t < nGroups; t++)
+         for (v = 0; v < alphaSize; v++)
+            s->rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v < alphaSize; v++) {
+            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start & end marks. --*/
+         if (gs >= s->nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge >= s->nMTF) ge = s->nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s->len_pack[icv][0]; \
+               cost23 += s->len_pack[icv][1]; \
+               cost45 += s->len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t < nGroups; t++)
+            if (cost[t] < bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s->selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++)
+               s->rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s->verbosity >= 3) {
+         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
+                   iter+1, totc/8 );
+         for (t = 0; t < nGroups; t++)
+            VPrintf1 ( "%d ", fave[t] );
+         VPrintf0 ( "\n" );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t < nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups < 8, 3002 );
+   AssertH( nSelectors < 32768 &&
+            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i < nGroups; i++) pos[i] = i;
+      for (i = 0; i < nSelectors; i++) {
+         ll_i = s->selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s->selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t < nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i < alphaSize; i++) {
+         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+         if (s->len[t][i] < minLen) minLen = s->len[t][i];
+      }
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen < 1),  3005 );
+      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i < 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j < 16; j++)
+             if (s->inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s->numZ;
+      for (i = 0; i < 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i < 16; i++)
+         if (inUse16[i])
+            for (j = 0; j < 16; j++) {
+               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s->verbosity >= 3) 
+         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s->numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i < nSelectors; i++) { 
+      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s->verbosity >= 3)
+      VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s->numZ;
+
+   for (t = 0; t < nGroups; t++) {
+      Int32 curr = s->len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i < alphaSize; i++) {
+         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s->verbosity >= 3)
+      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s->numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs >= s->nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge >= s->nMTF) ge = s->nMTF-1;
+      AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+      if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &(s->len[s->selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &(s->code[s->selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i <= ge; i++) {
+            bsW ( s, 
+                  s->len  [s->selector[selCtr]] [mtfv[i]],
+                  s->code [s->selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s->verbosity >= 3)
+      VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s->nblock > 0) {
+
+      BZ_FINALISE_CRC ( s->blockCRC );
+      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+      s->combinedCRC ^= s->blockCRC;
+      if (s->blockNo > 1) s->numZ = 0;
+
+      if (s->verbosity >= 2)
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
+                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s->blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+   }
+
+   if (s->nblock > 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s->blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s->origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s->combinedCRC );
+      if (s->verbosity >= 2)
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/crctable.c b/contrib/vmap_extractor_v2/stormlib/bzip2/crctable.c
new file mode 100644
index 000000000..b6dadfc62
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/crctable.c
@@ -0,0 +1,144 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs                                  ---*/
+/*---                                            crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+
+#include "bzlib_private.h"
+
+/*--
+  I think this is an implementation of the AUTODIN-II,
+  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
+  from code by Rob Warnock, in Section 51 of the
+  comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+   /*-- Ugly, innit? --*/
+
+   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/decompress.c b/contrib/vmap_extractor_v2/stormlib/bzip2/decompress.c
new file mode 100644
index 000000000..81c3d2cc3
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/decompress.c
@@ -0,0 +1,666 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery                               ---*/
+/*---                                          decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->seqToUnseq[s->nInUse] = i;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr)                               \
+   { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn)                     \
+   case lll: s->state = lll;                      \
+   while (True) {                                 \
+      if (s->bsLive >= nnn) {                     \
+         UInt32 v;                                \
+         v = (s->bsBuff >>                        \
+             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
+         s->bsLive -= nnn;                        \
+         vvv = v;                                 \
+         break;                                   \
+      }                                           \
+      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
+      s->bsBuff                                   \
+         = (s->bsBuff << 8) |                     \
+           ((UInt32)                              \
+              (*((UChar*)(s->strm->next_in))));   \
+      s->bsLive += 8;                             \
+      s->strm->next_in++;                         \
+      s->strm->avail_in--;                        \
+      s->strm->total_in_lo32++;                   \
+      if (s->strm->total_in_lo32 == 0)            \
+         s->strm->total_in_hi32++;                \
+   }
+
+#define GET_UCHAR(lll,uuu)                        \
+   GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu)                          \
+   GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval)           \
+{                                                 \
+   if (groupPos == 0) {                           \
+      groupNo++;                                  \
+      if (groupNo >= nSelectors)                  \
+         RETURN(BZ_DATA_ERROR);                   \
+      groupPos = BZ_G_SIZE;                       \
+      gSel = s->selector[groupNo];                \
+      gMinlen = s->minLens[gSel];                 \
+      gLimit = &(s->limit[gSel][0]);              \
+      gPerm = &(s->perm[gSel][0]);                \
+      gBase = &(s->base[gSel][0]);                \
+   }                                              \
+   groupPos--;                                    \
+   zn = gMinlen;                                  \
+   GET_BITS(label1, zvec, zn);                    \
+   while (1) {                                    \
+      if (zn > 20 /* the longest code */)         \
+         RETURN(BZ_DATA_ERROR);                   \
+      if (zvec <= gLimit[zn]) break;              \
+      zn++;                                       \
+      GET_BIT(label2, zj);                        \
+      zvec = (zvec << 1) | zj;                    \
+   };                                             \
+   if (zvec - gBase[zn] < 0                       \
+       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
+      RETURN(BZ_DATA_ERROR);                      \
+   lval = gPerm[zvec - gBase[zn]];                \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+   UChar      uc;
+   Int32      retVal;
+   Int32      minLen, maxLen;
+   bz_stream* strm = s->strm;
+
+   /* stuff that needs to be saved/restored */
+   Int32  i;
+   Int32  j;
+   Int32  t;
+   Int32  alphaSize;
+   Int32  nGroups;
+   Int32  nSelectors;
+   Int32  EOB;
+   Int32  groupNo;
+   Int32  groupPos;
+   Int32  nextSym;
+   Int32  nblockMAX;
+   Int32  nblock;
+   Int32  es;
+   Int32  N;
+   Int32  curr;
+   Int32  zt;
+   Int32  zn; 
+   Int32  zvec;
+   Int32  zj;
+   Int32  gSel;
+   Int32  gMinlen;
+   Int32* gLimit;
+   Int32* gBase;
+   Int32* gPerm;
+
+   if (s->state == BZ_X_MAGIC_1) {
+      /*initialise the save area*/
+      s->save_i           = 0;
+      s->save_j           = 0;
+      s->save_t           = 0;
+      s->save_alphaSize   = 0;
+      s->save_nGroups     = 0;
+      s->save_nSelectors  = 0;
+      s->save_EOB         = 0;
+      s->save_groupNo     = 0;
+      s->save_groupPos    = 0;
+      s->save_nextSym     = 0;
+      s->save_nblockMAX   = 0;
+      s->save_nblock      = 0;
+      s->save_es          = 0;
+      s->save_N           = 0;
+      s->save_curr        = 0;
+      s->save_zt          = 0;
+      s->save_zn          = 0;
+      s->save_zvec        = 0;
+      s->save_zj          = 0;
+      s->save_gSel        = 0;
+      s->save_gMinlen     = 0;
+      s->save_gLimit      = NULL;
+      s->save_gBase       = NULL;
+      s->save_gPerm       = NULL;
+   }
+
+   /*restore from the save area*/
+   i           = s->save_i;
+   j           = s->save_j;
+   t           = s->save_t;
+   alphaSize   = s->save_alphaSize;
+   nGroups     = s->save_nGroups;
+   nSelectors  = s->save_nSelectors;
+   EOB         = s->save_EOB;
+   groupNo     = s->save_groupNo;
+   groupPos    = s->save_groupPos;
+   nextSym     = s->save_nextSym;
+   nblockMAX   = s->save_nblockMAX;
+   nblock      = s->save_nblock;
+   es          = s->save_es;
+   N           = s->save_N;
+   curr        = s->save_curr;
+   zt          = s->save_zt;
+   zn          = s->save_zn; 
+   zvec        = s->save_zvec;
+   zj          = s->save_zj;
+   gSel        = s->save_gSel;
+   gMinlen     = s->save_gMinlen;
+   gLimit      = s->save_gLimit;
+   gBase       = s->save_gBase;
+   gPerm       = s->save_gPerm;
+
+   retVal = BZ_OK;
+
+   switch (s->state) {
+
+      GET_UCHAR(BZ_X_MAGIC_1, uc);
+      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_2, uc);
+      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_3, uc)
+      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
+          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+      s->blockSize100k -= BZ_HDR_0;
+
+      if (s->smallDecompress) {
+         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+         s->ll4  = BZALLOC( 
+                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
+                   );
+         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+      } else {
+         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+      }
+
+      GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+      if (uc == 0x17) goto endhdr_2;
+      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_2, uc);
+      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_3, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_4, uc);
+      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_5, uc);
+      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_6, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+      s->currBlockNo++;
+      if (s->verbosity >= 2)
+         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
+ 
+      s->storedBlockCRC = 0;
+      GET_UCHAR(BZ_X_BCRC_1, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_2, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_3, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_4, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+      s->origPtr = 0;
+      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+      if (s->origPtr < 0)
+         RETURN(BZ_DATA_ERROR);
+      if (s->origPtr > 10 + 100000*s->blockSize100k) 
+         RETURN(BZ_DATA_ERROR);
+
+      /*--- Receive the mapping table ---*/
+      for (i = 0; i < 16; i++) {
+         GET_BIT(BZ_X_MAPPING_1, uc);
+         if (uc == 1) 
+            s->inUse16[i] = True; else 
+            s->inUse16[i] = False;
+      }
+
+      for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+      for (i = 0; i < 16; i++)
+         if (s->inUse16[i])
+            for (j = 0; j < 16; j++) {
+               GET_BIT(BZ_X_MAPPING_2, uc);
+               if (uc == 1) s->inUse[i * 16 + j] = True;
+            }
+      makeMaps_d ( s );
+      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+      alphaSize = s->nInUse+2;
+
+      /*--- Now the selectors ---*/
+      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+      for (i = 0; i < nSelectors; i++) {
+         j = 0;
+         while (True) {
+            GET_BIT(BZ_X_SELECTOR_3, uc);
+            if (uc == 0) break;
+            j++;
+            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+         }
+         s->selectorMtf[i] = j;
+      }
+
+      /*--- Undo the MTF values for the selectors. ---*/
+      {
+         UChar pos[BZ_N_GROUPS], tmp, v;
+         for (v = 0; v < nGroups; v++) pos[v] = v;
+   
+         for (i = 0; i < nSelectors; i++) {
+            v = s->selectorMtf[i];
+            tmp = pos[v];
+            while (v > 0) { pos[v] = pos[v-1]; v--; }
+            pos[0] = tmp;
+            s->selector[i] = tmp;
+         }
+      }
+
+      /*--- Now the coding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         GET_BITS(BZ_X_CODING_1, curr, 5);
+         for (i = 0; i < alphaSize; i++) {
+            while (True) {
+               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+               GET_BIT(BZ_X_CODING_2, uc);
+               if (uc == 0) break;
+               GET_BIT(BZ_X_CODING_3, uc);
+               if (uc == 0) curr++; else curr--;
+            }
+            s->len[t][i] = curr;
+         }
+      }
+
+      /*--- Create the Huffman decoding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         minLen = 32;
+         maxLen = 0;
+         for (i = 0; i < alphaSize; i++) {
+            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+            if (s->len[t][i] < minLen) minLen = s->len[t][i];
+         }
+         BZ2_hbCreateDecodeTables ( 
+            &(s->limit[t][0]), 
+            &(s->base[t][0]), 
+            &(s->perm[t][0]), 
+            &(s->len[t][0]),
+            minLen, maxLen, alphaSize
+         );
+         s->minLens[t] = minLen;
+      }
+
+      /*--- Now the MTF values ---*/
+
+      EOB      = s->nInUse+1;
+      nblockMAX = 100000 * s->blockSize100k;
+      groupNo  = -1;
+      groupPos = 0;
+
+      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+      /*-- MTF init --*/
+      {
+         Int32 ii, jj, kk;
+         kk = MTFA_SIZE-1;
+         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+               kk--;
+            }
+            s->mtfbase[ii] = kk + 1;
+         }
+      }
+      /*-- end MTF init --*/
+
+      nblock = 0;
+      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+      while (True) {
+
+         if (nextSym == EOB) break;
+
+         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+            es = -1;
+            N = 1;
+            do {
+               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+               N = N * 2;
+               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+            }
+               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+            es++;
+            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+            s->unzftab[uc] += es;
+
+            if (s->smallDecompress)
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->ll16[nblock] = (UInt16)uc;
+                  nblock++;
+                  es--;
+               }
+            else
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->tt[nblock] = (UInt32)uc;
+                  nblock++;
+                  es--;
+               };
+
+            continue;
+
+         } else {
+
+            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+            /*-- uc = MTF ( nextSym-1 ) --*/
+            {
+               Int32 ii, jj, kk, pp, lno, off;
+               UInt32 nn;
+               nn = (UInt32)(nextSym - 1);
+
+               if (nn < MTFL_SIZE) {
+                  /* avoid general-case expense */
+                  pp = s->mtfbase[0];
+                  uc = s->mtfa[pp+nn];
+                  while (nn > 3) {
+                     Int32 z = pp+nn;
+                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
+                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
+                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
+                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
+                     nn -= 4;
+                  }
+                  while (nn > 0) { 
+                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
+                  };
+                  s->mtfa[pp] = uc;
+               } else { 
+                  /* general case */
+                  lno = nn / MTFL_SIZE;
+                  off = nn % MTFL_SIZE;
+                  pp = s->mtfbase[lno] + off;
+                  uc = s->mtfa[pp];
+                  while (pp > s->mtfbase[lno]) { 
+                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
+                  };
+                  s->mtfbase[lno]++;
+                  while (lno > 0) {
+                     s->mtfbase[lno]--;
+                     s->mtfa[s->mtfbase[lno]] 
+                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s->mtfbase[0]--;
+                  s->mtfa[s->mtfbase[0]] = uc;
+                  if (s->mtfbase[0] == 0) {
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s->mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+            }
+            /*-- end uc = MTF ( nextSym-1 ) --*/
+
+            s->unzftab[s->seqToUnseq[uc]]++;
+            if (s->smallDecompress)
+               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
+            nblock++;
+
+            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+            continue;
+         }
+      }
+
+      /* Now we know what nblock is, we can do a better sanity
+         check on s->origPtr.
+      */
+      if (s->origPtr < 0 || s->origPtr >= nblock)
+         RETURN(BZ_DATA_ERROR);
+
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      s->cftab[0] = 0;
+      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      for (i = 0; i <= 256; i++) {
+         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+            /* s->cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
+      s->state_out_len = 0;
+      s->state_out_ch  = 0;
+      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+      s->state = BZ_X_OUTPUT;
+      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+      if (s->smallDecompress) {
+
+         /*-- Make a copy of cftab, used in generation of T --*/
+         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+         /*-- compute the T vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->ll16[i]);
+            SET_LL(i, s->cftabCopy[uc]);
+            s->cftabCopy[uc]++;
+         }
+
+         /*-- Compute T^(-1) by pointer reversal on T --*/
+         i = s->origPtr;
+         j = GET_LL(i);
+         do {
+            Int32 tmp = GET_LL(j);
+            SET_LL(j, i);
+            i = j;
+            j = tmp;
+         }
+            while (i != s->origPtr);
+
+         s->tPos = s->origPtr;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+         }
+
+      } else {
+
+         /*-- compute the T^(-1) vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->tt[i] & 0xff);
+            s->tt[s->cftab[uc]] |= (i << 8);
+            s->cftab[uc]++;
+         }
+
+         s->tPos = s->tt[s->origPtr] >> 8;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+         }
+
+      }
+
+      RETURN(BZ_OK);
+
+
+
+    endhdr_2:
+
+      GET_UCHAR(BZ_X_ENDHDR_2, uc);
+      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_3, uc);
+      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_4, uc);
+      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_5, uc);
+      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_6, uc);
+      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+      s->storedCombinedCRC = 0;
+      GET_UCHAR(BZ_X_CCRC_1, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_2, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_3, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_4, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+      s->state = BZ_X_IDLE;
+      RETURN(BZ_STREAM_END);
+
+      default: AssertH ( False, 4001 );
+   }
+
+   AssertH ( False, 4002 );
+
+   save_state_and_return:
+
+   s->save_i           = i;
+   s->save_j           = j;
+   s->save_t           = t;
+   s->save_alphaSize   = alphaSize;
+   s->save_nGroups     = nGroups;
+   s->save_nSelectors  = nSelectors;
+   s->save_EOB         = EOB;
+   s->save_groupNo     = groupNo;
+   s->save_groupPos    = groupPos;
+   s->save_nextSym     = nextSym;
+   s->save_nblockMAX   = nblockMAX;
+   s->save_nblock      = nblock;
+   s->save_es          = es;
+   s->save_N           = N;
+   s->save_curr        = curr;
+   s->save_zt          = zt;
+   s->save_zn          = zn;
+   s->save_zvec        = zvec;
+   s->save_zj          = zj;
+   s->save_gSel        = gSel;
+   s->save_gMinlen     = gMinlen;
+   s->save_gLimit      = gLimit;
+   s->save_gBase       = gBase;
+   s->save_gPerm       = gPerm;
+
+   return retVal;   
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                      decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c b/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c
new file mode 100644
index 000000000..eb86bb61a
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c
@@ -0,0 +1,176 @@
+/*
+   minibz2
+      libbz2.dll test program.
+      by Yoshioka Tsuneo(QWF00133@nifty.ne.jp/tsuneo-y@is.aist-nara.ac.jp)
+      This file is Public Domain.
+      welcome any email to me.
+
+   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
+*/
+
+#define BZ_IMPORT
+#include 
+#include 
+#include "bzlib.h"
+#ifdef _WIN32
+#include 
+#endif
+
+
+#ifdef _WIN32
+
+#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 
+
+#include 
+static int BZ2DLLLoaded = 0;
+static HINSTANCE BZ2DLLhLib;
+int BZ2DLLLoadLibrary(void)
+{
+   HINSTANCE hLib;
+
+   if(BZ2DLLLoaded==1){return 0;}
+   hLib=LoadLibrary(BZ2_LIBNAME);
+   if(hLib == NULL){
+      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
+      return -1;
+   }
+   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
+   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
+   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
+   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
+   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
+   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
+   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
+   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
+
+   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
+       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
+       || !BZ2_bzclose || !BZ2_bzerror) {
+      fprintf(stderr,"GetProcAddress failed.\n");
+      return -1;
+   }
+   BZ2DLLLoaded=1;
+   BZ2DLLhLib=hLib;
+   return 0;
+
+}
+int BZ2DLLFreeLibrary(void)
+{
+   if(BZ2DLLLoaded==0){return 0;}
+   FreeLibrary(BZ2DLLhLib);
+   BZ2DLLLoaded=0;
+}
+#endif /* WIN32 */
+
+void usage(void)
+{
+   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
+}
+
+int main(int argc,char *argv[])
+{
+   int decompress = 0;
+   int level = 9;
+   char *fn_r = NULL;
+   char *fn_w = NULL;
+
+#ifdef _WIN32
+   if(BZ2DLLLoadLibrary()<0){
+      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
+      exit(1);
+   }
+   printf("Loading of %s succeeded.  Library version is %s.\n",
+          BZ2_LIBNAME, BZ2_bzlibVersion() );
+#endif
+   while(++argv,--argc){
+      if(**argv =='-' || **argv=='/'){
+         char *p;
+
+         for(p=*argv+1;*p;p++){
+            if(*p=='d'){
+               decompress = 1;
+            }else if('1'<=*p && *p<='9'){
+               level = *p - '0';
+            }else{
+               usage();
+               exit(1);
+            }
+         }
+      }else{
+         break;
+      }
+   }
+   if(argc>=1){
+      fn_r = *argv;
+      argc--;argv++;
+   }else{
+      fn_r = NULL;
+   }
+   if(argc>=1){
+      fn_w = *argv;
+      argc--;argv++;
+   }else{
+      fn_w = NULL;
+   }
+   {
+      int len;
+      char buff[0x1000];
+      char mode[10];
+
+      if(decompress){
+         BZFILE *BZ2fp_r = NULL;
+         FILE *fp_w = NULL;
+
+         if(fn_w){
+            if((fp_w = fopen(fn_w,"wb"))==NULL){
+               printf("can't open [%s]\n",fn_w);
+               perror("reason:");
+               exit(1);
+            }
+         }else{
+            fp_w = stdout;
+         }
+         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
+            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
+            printf("can't bz2openstream\n");
+            exit(1);
+         }
+         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
+            fwrite(buff,1,len,fp_w);
+         }
+         BZ2_bzclose(BZ2fp_r);
+         if(fp_w != stdout) fclose(fp_w);
+      }else{
+         BZFILE *BZ2fp_w = NULL;
+         FILE *fp_r = NULL;
+
+         if(fn_r){
+            if((fp_r = fopen(fn_r,"rb"))==NULL){
+               printf("can't open [%s]\n",fn_r);
+               perror("reason:");
+               exit(1);
+            }
+         }else{
+            fp_r = stdin;
+         }
+         mode[0]='w';
+         mode[1] = '0' + level;
+         mode[2] = '\0';
+
+         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
+            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
+            printf("can't bz2openstream\n");
+            exit(1);
+         }
+         while((len=fread(buff,1,0x1000,fp_r))>0){
+            BZ2_bzwrite(BZ2fp_w,buff,len);
+         }
+         BZ2_bzclose(BZ2fp_w);
+         if(fp_r!=stdin)fclose(fp_r);
+      }
+   }
+#ifdef _WIN32
+   BZ2DLLFreeLibrary();
+#endif
+   return 0;
+}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp b/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp
new file mode 100644
index 000000000..4b1615edc
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp
@@ -0,0 +1,93 @@
+# Microsoft Developer Studio Project File - Name="dlltest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=dlltest - Win32 Debug
+!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚Å‚Í‚ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
+!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
+!MESSAGE 
+!MESSAGE NMAKE /f "dlltest.mak".
+!MESSAGE 
+!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
+!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
+!MESSAGE 
+!MESSAGE NMAKE /f "dlltest.mak" CFG="dlltest - Win32 Debug"
+!MESSAGE 
+!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
+!MESSAGE 
+!MESSAGE "dlltest - Win32 Release" ("Win32 (x86) Console Application" —p)
+!MESSAGE "dlltest - Win32 Debug" ("Win32 (x86) Console Application" —p)
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "dlltest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"minibz2.exe"
+
+!ELSEIF  "$(CFG)" == "dlltest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "dlltest_"
+# PROP BASE Intermediate_Dir "dlltest_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "dlltest_"
+# PROP Intermediate_Dir "dlltest_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"minibz2.exe" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "dlltest - Win32 Release"
+# Name "dlltest - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dlltest.c
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml b/contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml
new file mode 100644
index 000000000..6d0975fdb
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/format.pl b/contrib/vmap_extractor_v2/stormlib/bzip2/format.pl
new file mode 100644
index 000000000..8ab47acd3
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/format.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/perl -w
+use strict;
+
+# get command line values:
+if ( $#ARGV !=1 ) {
+    die "Usage:  $0 xml_infile xml_outfile\n";
+}
+
+my $infile = shift;
+# check infile exists
+die "Can't find file \"$infile\""
+  unless -f $infile;
+# check we can read infile
+if (! -r $infile) {
+    die "Can't read input $infile\n";
+}
+# check we can open infile
+open( INFILE,"<$infile" ) or 
+    die "Can't input $infile $!";
+
+#my $outfile = 'fmt-manual.xml';
+my $outfile = shift;
+#print "Infile: $infile, Outfile: $outfile\n";
+# check we can write to outfile
+open( OUTFILE,">$outfile" ) or 
+    die "Can't output $outfile $! for writing";
+
+my ($prev, $curr, $str);
+$prev = ''; $curr = '';
+while (  ) {
+
+		print OUTFILE $prev;
+    $prev = $curr;
+    $curr = $_;
+    $str = '';
+
+    if ( $prev =~ /$|$/ ) {
+        chomp $prev;
+        $curr = join( '', $prev, "|<\/screen>/ ) {
+        chomp $prev;
+        $curr = join( '', $prev, "]]>", $curr );
+				$prev = '';
+        next;
+    }
+}
+print OUTFILE $curr;
+close INFILE;
+close OUTFILE;
+exit;
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/huffman.c b/contrib/vmap_extractor_v2/stormlib/bzip2/huffman.c
new file mode 100644
index 000000000..5bf190be9
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/huffman.c
@@ -0,0 +1,245 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+  This file is a part of bzip2 and/or libbzip2, a program and
+  library for lossless, block-sorting data compression.
+
+  Copyright (C) 1996-2005 Julian R Seward.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+  2. The origin of this software must not be misrepresented; you must 
+     not claim that you wrote the original software.  If you use this 
+     software in a product, an acknowledgment in the product 
+     documentation would be appreciated but is not required.
+
+  3. Altered source versions must be plainly marked as such, and must
+     not be misrepresented as being the original software.
+
+  4. The name of the author may not be used to endorse or promote 
+     products derived from this software without specific prior written 
+     permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  Julian Seward, Cambridge, UK.
+  jseward@bzip.org
+  bzip2/libbzip2 version 1.0 of 21 March 2000
+
+  This program is based on (at least) the work of:
+     Mike Burrows
+     David Wheeler
+     Peter Fenwick
+     Alistair Moffat
+     Radford Neal
+     Ian H. Witten
+     Robert Sedgewick
+     Jon L. Bentley
+
+  For more information on these sources, see the manual.
+--*/
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2)                           \
+   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
+   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z)                                     \
+{                                                     \
+   Int32 zz, tmp;                                     \
+   zz = z; tmp = heap[zz];                            \
+   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
+      heap[zz] = heap[zz >> 1];                       \
+      zz >>= 1;                                       \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+#define DOWNHEAP(z)                                   \
+{                                                     \
+   Int32 zz, yy, tmp;                                 \
+   zz = z; tmp = heap[zz];                            \
+   while (True) {                                     \
+      yy = zz << 1;                                   \
+      if (yy > nHeap) break;                          \
+      if (yy < nHeap &&                               \
+          weight[heap[yy+1]] < weight[heap[yy]])      \
+         yy++;                                        \
+      if (weight[tmp] < weight[heap[yy]]) break;      \
+      heap[zz] = heap[yy];                            \
+      zz = yy;                                        \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len, 
+                             Int32 *freq,
+                             Int32 alphaSize,
+                             Int32 maxLen )
+{
+   /*--
+      Nodes and heap entries run from 1.  Entry 0
+      for both the heap and nodes is a sentinel.
+   --*/
+   Int32 nNodes, nHeap, n1, n2, i, j, k;
+   Bool  tooLong;
+
+   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
+   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+
+   for (i = 0; i < alphaSize; i++)
+      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+   while (True) {
+
+      nNodes = alphaSize;
+      nHeap = 0;
+
+      heap[0] = 0;
+      weight[0] = 0;
+      parent[0] = -2;
+
+      for (i = 1; i <= alphaSize; i++) {
+         parent[i] = -1;
+         nHeap++;
+         heap[nHeap] = i;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+   
+      while (nHeap > 1) {
+         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         nNodes++;
+         parent[n1] = parent[n2] = nNodes;
+         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+         parent[nNodes] = -1;
+         nHeap++;
+         heap[nHeap] = nNodes;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+      tooLong = False;
+      for (i = 1; i <= alphaSize; i++) {
+         j = 0;
+         k = i;
+         while (parent[k] >= 0) { k = parent[k]; j++; }
+         len[i-1] = j;
+         if (j > maxLen) tooLong = True;
+      }
+      
+      if (! tooLong) break;
+
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i < alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i <= alphaSize; i++) {
+         j = weight[i] >> 8;
+         j = 1 + (j / 2);
+         weight[i] = j << 8;
+      }
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+                         UChar *length,
+                         Int32 minLen,
+                         Int32 maxLen,
+                         Int32 alphaSize )
+{
+   Int32 n, vec, i;
+
+   vec = 0;
+   for (n = minLen; n <= maxLen; n++) {
+      for (i = 0; i < alphaSize; i++)
+         if (length[i] == n) { code[i] = vec; vec++; };
+      vec <<= 1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+                                Int32 *base,
+                                Int32 *perm,
+                                UChar *length,
+                                Int32 minLen,
+                                Int32 maxLen,
+                                Int32 alphaSize )
+{
+   Int32 pp, i, j, vec;
+
+   pp = 0;
+   for (i = minLen; i <= maxLen; i++)
+      for (j = 0; j < alphaSize; j++)
+         if (length[j] == i) { perm[pp] = j; pp++; };
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   vec = 0;
+
+   for (i = minLen; i <= maxLen; i++) {
+      vec += (base[i+1] - base[i]);
+      limit[i] = vec-1;
+      vec <<= 1;
+   }
+   for (i = minLen + 1; i <= maxLen; i++)
+      base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def b/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def
new file mode 100644
index 000000000..2dc0dd891
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def
@@ -0,0 +1,27 @@
+LIBRARY			LIBBZ2
+DESCRIPTION		"libbzip2: library for data compression"
+EXPORTS
+	BZ2_bzCompressInit
+	BZ2_bzCompress
+	BZ2_bzCompressEnd
+	BZ2_bzDecompressInit
+	BZ2_bzDecompress
+	BZ2_bzDecompressEnd
+	BZ2_bzReadOpen
+	BZ2_bzReadClose
+	BZ2_bzReadGetUnused
+	BZ2_bzRead
+	BZ2_bzWriteOpen
+	BZ2_bzWrite
+	BZ2_bzWriteClose
+	BZ2_bzWriteClose64
+	BZ2_bzBuffToBuffCompress
+	BZ2_bzBuffToBuffDecompress
+	BZ2_bzlibVersion
+	BZ2_bzopen
+	BZ2_bzdopen
+	BZ2_bzread
+	BZ2_bzwrite
+	BZ2_bzflush
+	BZ2_bzclose
+	BZ2_bzerror
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp b/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp
new file mode 100644
index 000000000..a21a20f75
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp
@@ -0,0 +1,130 @@
+# Microsoft Developer Studio Project File - Name="libbz2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libbz2 - Win32 Debug
+!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚Å‚Í‚ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
+!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
+!MESSAGE 
+!MESSAGE NMAKE /f "libbz2.mak".
+!MESSAGE 
+!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
+!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
+!MESSAGE 
+!MESSAGE NMAKE /f "libbz2.mak" CFG="libbz2 - Win32 Debug"
+!MESSAGE 
+!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
+!MESSAGE 
+!MESSAGE "libbz2 - Win32 Release" ("Win32 (x86) Dynamic-Link Library" —p)
+!MESSAGE "libbz2 - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" —p)
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "libbz2 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"libbz2.dll"
+
+!ELSEIF  "$(CFG)" == "libbz2 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"libbz2.dll" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "libbz2 - Win32 Release"
+# Name "libbz2 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\blocksort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib_private.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\crctable.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\decompress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\huffman.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libbz2.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\randtable.c
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc b/contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc
new file mode 100644
index 000000000..799a18a5f
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc
@@ -0,0 +1,63 @@
+# Makefile for Microsoft Visual C++ 6.0
+# usage: nmake -f makefile.msc
+# K.M. Syring (syring@gsf.de)
+# Fixed up by JRS for bzip2-0.9.5d release.
+
+CC=cl
+CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64 -nologo
+
+OBJS= blocksort.obj  \
+      huffman.obj    \
+      crctable.obj   \
+      randtable.obj  \
+      compress.obj   \
+      decompress.obj \
+      bzlib.obj
+
+all: lib bzip2 test
+
+bzip2: lib
+	$(CC) $(CFLAGS) -o bzip2 bzip2.c libbz2.lib setargv.obj
+	$(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
+
+lib: $(OBJS)
+	lib /out:libbz2.lib $(OBJS)
+
+test: bzip2
+	type words1
+	.\\bzip2 -1  < sample1.ref > sample1.rb2
+	.\\bzip2 -2  < sample2.ref > sample2.rb2
+	.\\bzip2 -3  < sample3.ref > sample3.rb2
+	.\\bzip2 -d  < sample1.bz2 > sample1.tst
+	.\\bzip2 -d  < sample2.bz2 > sample2.tst
+	.\\bzip2 -ds < sample3.bz2 > sample3.tst
+	@echo All six of the fc's should find no differences.
+	@echo If fc finds an error on sample3.bz2, this could be
+	@echo because WinZip's 'TAR file smart CR/LF conversion'
+	@echo is too clever for its own good.  Disable this option.
+	@echo The correct size for sample3.ref is 120,244.  If it
+	@echo is 150,251, WinZip has messed it up.
+	fc sample1.bz2 sample1.rb2 
+	fc sample2.bz2 sample2.rb2
+	fc sample3.bz2 sample3.rb2
+	fc sample1.tst sample1.ref
+	fc sample2.tst sample2.ref
+	fc sample3.tst sample3.ref
+
+
+
+clean: 
+	del *.obj
+	del libbz2.lib 
+	del bzip2.exe
+	del bzip2recover.exe
+	del sample1.rb2 
+	del sample2.rb2 
+	del sample3.rb2
+	del sample1.tst 
+	del sample2.tst
+	del sample3.tst
+
+.c.obj: 
+	$(CC) $(CFLAGS) -c $*.c -o $*.obj
+
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.html b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.html
new file mode 100644
index 000000000..b28cc79a8
--- /dev/null
+++ b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.html
@@ -0,0 +1,2687 @@
+
+
+
+bzip2 and libbzip2, version 1.0.3
+
+
+
+
+
+
+

+bzip2 and libbzip2, version 1.0.3

+

A program and library for data compression

+
+

+Julian Seward +

+
http://www.bzip.org
+
+

Version 1.0.3 of 15 February 2005

+
+
+

This program, bzip2, the + associated library libbzip2, and + all documentation, are copyright © 1996-2005 Julian Seward. + All rights reserved.

+

Redistribution and use in source and binary forms, with + or without modification, are permitted provided that the + following conditions are met:

+
    +
  • Redistributions of source code must retain the + above copyright notice, this list of conditions and the + following disclaimer.

  • +
  • The origin of this software must not be + misrepresented; you must not claim that you wrote the original + software. If you use this software in a product, an + acknowledgment in the product documentation would be + appreciated but is not required.

  • +
  • Altered source versions must be plainly marked + as such, and must not be misrepresented as being the original + software.

  • +
  • The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission.

  • +
+

THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE.

+

PATENTS: To the best of my knowledge, + bzip2 and + libbzip2 do not use any patented + algorithms. However, I do not have the resources to carry + out a patent search. Therefore I cannot give any guarantee of + the above statement. +

+
+
+
+
+
+ +
+
+

+1. Introduction

+
+
+

bzip2 compresses files +using the Burrows-Wheeler block-sorting text compression +algorithm, and Huffman coding. Compression is generally +considerably better than that achieved by more conventional +LZ77/LZ78-based compressors, and approaches the performance of +the PPM family of statistical compressors.

+

bzip2 is built on top of +libbzip2, a flexible library for +handling compressed data in the +bzip2 format. This manual +describes both how to use the program and how to work with the +library interface. Most of the manual is devoted to this +library, not the program, which is good news if your interest is +only in the program.

+
    +
  • How to use bzip2 describes how to use + bzip2; this is the only part + you need to read if you just want to know how to operate the + program.

  • +
  • Programming with libbzip2 describes the + programming interfaces in detail, and

  • +
  • Miscellanea records some + miscellaneous notes which I thought ought to be recorded + somewhere.

  • +
+
+
+
+

+2. How to use bzip2

+
+
+ +

This chapter contains a copy of the +bzip2 man page, and nothing +else.

+
+
+

+2.1. NAME

+
+
+
    +
  • bzip2, + bunzip2 - a block-sorting file + compressor, v1.0.3

  • +
  • bzcat - + decompresses files to stdout

  • +
  • bzip2recover - + recovers data from damaged bzip2 files

  • +
+
+
+
+

+2.2. SYNOPSIS

+
+
+
    +
  • bzip2 [ + -cdfkqstvzVL123456789 ] [ filenames ... ]

  • +
  • bunzip2 [ + -fkvsVL ] [ filenames ... ]

  • +
  • bzcat [ -s ] [ + filenames ... ]

  • +
  • bzip2recover + filename

  • +
+
+
+
+

+2.3. DESCRIPTION

+
+
+

bzip2 compresses files +using the Burrows-Wheeler block sorting text compression +algorithm, and Huffman coding. Compression is generally +considerably better than that achieved by more conventional +LZ77/LZ78-based compressors, and approaches the performance of +the PPM family of statistical compressors.

+

The command-line options are deliberately very similar to +those of GNU gzip, but they are +not identical.

+

bzip2 expects a list of +file names to accompany the command-line flags. Each file is +replaced by a compressed version of itself, with the name +original_name.bz2. Each +compressed file has the same modification date, permissions, and, +when possible, ownership as the corresponding original, so that +these properties can be correctly restored at decompression time. +File name handling is naive in the sense that there is no +mechanism for preserving original file names, permissions, +ownerships or dates in filesystems which lack these concepts, or +have serious file name length restrictions, such as +MS-DOS.

+

bzip2 and +bunzip2 will by default not +overwrite existing files. If you want this to happen, specify +the -f flag.

+

If no file names are specified, +bzip2 compresses from standard +input to standard output. In this case, +bzip2 will decline to write +compressed output to a terminal, as this would be entirely +incomprehensible and therefore pointless.

+

bunzip2 (or +bzip2 -d) decompresses all +specified files. Files which were not created by +bzip2 will be detected and +ignored, and a warning issued. +bzip2 attempts to guess the +filename for the decompressed file from that of the compressed +file as follows:

+
    +
  • filename.bz2 + becomes + filename

  • +
  • filename.bz + becomes + filename

  • +
  • filename.tbz2 + becomes + filename.tar

  • +
  • filename.tbz + becomes + filename.tar

  • +
  • anyothername + becomes + anyothername.out

  • +
+

If the file does not end in one of the recognised endings, +.bz2, +.bz, +.tbz2 or +.tbz, +bzip2 complains that it cannot +guess the name of the original file, and uses the original name +with .out appended.

+

As with compression, supplying no filenames causes +decompression from standard input to standard output.

+

bunzip2 will correctly +decompress a file which is the concatenation of two or more +compressed files. The result is the concatenation of the +corresponding uncompressed files. Integrity testing +(-t) of concatenated compressed +files is also supported.

+

You can also compress or decompress files to the standard +output by giving the -c flag. +Multiple files may be compressed and decompressed like this. The +resulting outputs are fed sequentially to stdout. Compression of +multiple files in this manner generates a stream containing +multiple compressed file representations. Such a stream can be +decompressed correctly only by +bzip2 version 0.9.0 or later. +Earlier versions of bzip2 will +stop after decompressing the first file in the stream.

+

bzcat (or +bzip2 -dc) decompresses all +specified files to the standard output.

+

bzip2 will read arguments +from the environment variables +BZIP2 and +BZIP, in that order, and will +process them before any arguments read from the command line. +This gives a convenient way to supply default arguments.

+

Compression is always performed, even if the compressed +file is slightly larger than the original. Files of less than +about one hundred bytes tend to get larger, since the compression +mechanism has a constant overhead in the region of 50 bytes. +Random data (including the output of most file compressors) is +coded at about 8.05 bits per byte, giving an expansion of around +0.5%.

+

As a self-check for your protection, +bzip2 uses 32-bit CRCs to make +sure that the decompressed version of a file is identical to the +original. This guards against corruption of the compressed data, +and against undetected bugs in +bzip2 (hopefully very unlikely). +The chances of data corruption going undetected is microscopic, +about one chance in four billion for each file processed. Be +aware, though, that the check occurs upon decompression, so it +can only tell you that something is wrong. It can't help you +recover the original uncompressed data. You can use +bzip2recover to try to recover +data from damaged files.

+

Return values: 0 for a normal exit, 1 for environmental +problems (file not found, invalid flags, I/O errors, etc.), 2 +to indicate a corrupt compressed file, 3 for an internal +consistency error (eg, bug) which caused +bzip2 to panic.

+
+
+
+

+2.4. OPTIONS

+
+
+
+
-c --stdout
+

Compress or decompress to standard + output.

+
-d --decompress
+

Force decompression. + bzip2, + bunzip2 and + bzcat are really the same + program, and the decision about what actions to take is done on + the basis of which name is used. This flag overrides that + mechanism, and forces bzip2 to decompress.

+
-z --compress
+

The complement to + -d: forces compression, + regardless of the invokation name.

+
-t --test
+

Check integrity of the specified file(s), but + don't decompress them. This really performs a trial + decompression and throws away the result.

+
-f --force
+
+

Force overwrite of output files. Normally, + bzip2 will not overwrite + existing output files. Also forces + bzip2 to break hard links to + files, which it otherwise wouldn't do.

+

bzip2 normally declines + to decompress files which don't have the correct magic header + bytes. If forced (-f), + however, it will pass such files through unmodified. This is + how GNU gzip behaves.

+
+
-k --keep
+

Keep (don't delete) input files during + compression or decompression.

+
-s --small
+
+

Reduce memory usage, for compression, + decompression and testing. Files are decompressed and tested + using a modified algorithm which only requires 2.5 bytes per + block byte. This means any file can be decompressed in 2300k + of memory, albeit at about half the normal speed.

+

During compression, -s + selects a block size of 200k, which limits memory use to around + the same figure, at the expense of your compression ratio. In + short, if your machine is low on memory (8 megabytes or less), + use -s for everything. See + MEMORY MANAGEMENT below.

+
+
-q --quiet
+

Suppress non-essential warning messages. + Messages pertaining to I/O errors and other critical events + will not be suppressed.

+
-v --verbose
+

Verbose mode -- show the compression ratio for + each file processed. Further + -v's increase the verbosity + level, spewing out lots of information which is primarily of + interest for diagnostic purposes.

+
-L --license -V --version
+

Display the software version, license terms and + conditions.

+
-1 (or + --fast) to + -9 (or + -best)
+

Set the block size to 100 k, 200 k ... 900 k + when compressing. Has no effect when decompressing. See MEMORY MANAGEMENT below. The + --fast and + --best aliases are primarily + for GNU gzip compatibility. + In particular, --fast doesn't + make things significantly faster. And + --best merely selects the + default behaviour.

+
--
+

Treats all subsequent arguments as file names, + even if they start with a dash. This is so you can handle + files with names beginning with a dash, for example: + bzip2 -- + -myfilename.

+
+--repetitive-fast, --repetitive-best, +
+

These flags are redundant in versions 0.9.5 and + above. They provided some coarse control over the behaviour of + the sorting algorithm in earlier versions, which was sometimes + useful. 0.9.5 and above have an improved algorithm which + renders these flags irrelevant.

+
+
+
+
+

+2.5. MEMORY MANAGEMENT

+
+
+

bzip2 compresses large +files in blocks. The block size affects both the compression +ratio achieved, and the amount of memory needed for compression +and decompression. The flags -1 +through -9 specify the block +size to be 100,000 bytes through 900,000 bytes (the default) +respectively. At decompression time, the block size used for +compression is read from the header of the compressed file, and +bunzip2 then allocates itself +just enough memory to decompress the file. Since block sizes are +stored in compressed files, it follows that the flags +-1 to +-9 are irrelevant to and so +ignored during decompression.

+

Compression and decompression requirements, in bytes, can be +estimated as:

+
Compression:   400k + ( 8 x block size )
+
+Decompression: 100k + ( 4 x block size ), or
+               100k + ( 2.5 x block size )
+

Larger block sizes give rapidly diminishing marginal +returns. Most of the compression comes from the first two or +three hundred k of block size, a fact worth bearing in mind when +using bzip2 on small machines. +It is also important to appreciate that the decompression memory +requirement is set at compression time by the choice of block +size.

+

For files compressed with the default 900k block size, +bunzip2 will require about 3700 +kbytes to decompress. To support decompression of any file on a +4 megabyte machine, bunzip2 has +an option to decompress using approximately half this amount of +memory, about 2300 kbytes. Decompression speed is also halved, +so you should use this option only where necessary. The relevant +flag is -s.

+

In general, try and use the largest block size memory +constraints allow, since that maximises the compression achieved. +Compression and decompression speed are virtually unaffected by +block size.

+

Another significant point applies to files which fit in a +single block -- that means most files you'd encounter using a +large block size. The amount of real memory touched is +proportional to the size of the file, since the file is smaller +than a block. For example, compressing a file 20,000 bytes long +with the flag -9 will cause the +compressor to allocate around 7600k of memory, but only touch +400k + 20000 * 8 = 560 kbytes of it. Similarly, the decompressor +will allocate 3700k but only touch 100k + 20000 * 4 = 180 +kbytes.

+

Here is a table which summarises the maximum memory usage +for different block sizes. Also recorded is the total compressed +size for 14 files of the Calgary Text Compression Corpus +totalling 3,141,622 bytes. This column gives some feel for how +compression varies with block size. These figures tend to +understate the advantage of larger block sizes for larger files, +since the Corpus is dominated by smaller files.

+
        Compress   Decompress   Decompress   Corpus
+Flag     usage      usage       -s usage     Size
+
+ -1      1200k       500k         350k      914704
+ -2      2000k       900k         600k      877703
+ -3      2800k      1300k         850k      860338
+ -4      3600k      1700k        1100k      846899
+ -5      4400k      2100k        1350k      845160
+ -6      5200k      2500k        1600k      838626
+ -7      6100k      2900k        1850k      834096
+ -8      6800k      3300k        2100k      828642
+ -9      7600k      3700k        2350k      828642
+
+
+
+

+2.6. RECOVERING DATA FROM DAMAGED FILES

+
+
+

bzip2 compresses files in +blocks, usually 900kbytes long. Each block is handled +independently. If a media or transmission error causes a +multi-block .bz2 file to become +damaged, it may be possible to recover data from the undamaged +blocks in the file.

+

The compressed representation of each block is delimited by +a 48-bit pattern, which makes it possible to find the block +boundaries with reasonable certainty. Each block also carries +its own 32-bit CRC, so damaged blocks can be distinguished from +undamaged ones.

+

bzip2recover is a simple +program whose purpose is to search for blocks in +.bz2 files, and write each block +out into its own .bz2 file. You +can then use bzip2 -t to test +the integrity of the resulting files, and decompress those which +are undamaged.

+

bzip2recover takes a +single argument, the name of the damaged file, and writes a +number of files rec0001file.bz2, +rec0002file.bz2, etc, containing +the extracted blocks. The output filenames are designed so that +the use of wildcards in subsequent processing -- for example, +bzip2 -dc rec*file.bz2 > +recovered_data -- lists the files in the correct +order.

+

bzip2recover should be of +most use dealing with large .bz2 +files, as these will contain many blocks. It is clearly futile +to use it on damaged single-block files, since a damaged block +cannot be recovered. If you wish to minimise any potential data +loss through media or transmission errors, you might consider +compressing with a smaller block size.

+
+
+
+

+2.7. PERFORMANCE NOTES

+
+
+

The sorting phase of compression gathers together similar +strings in the file. Because of this, files containing very long +runs of repeated symbols, like "aabaabaabaab ..." (repeated +several hundred times) may compress more slowly than normal. +Versions 0.9.5 and above fare much better than previous versions +in this respect. The ratio between worst-case and average-case +compression time is in the region of 10:1. For previous +versions, this figure was more like 100:1. You can use the +-vvvv option to monitor progress +in great detail, if you want.

+

Decompression speed is unaffected by these +phenomena.

+

bzip2 usually allocates +several megabytes of memory to operate in, and then charges all +over it in a fairly random fashion. This means that performance, +both for compressing and decompressing, is largely determined by +the speed at which your machine can service cache misses. +Because of this, small changes to the code to reduce the miss +rate have been observed to give disproportionately large +performance improvements. I imagine +bzip2 will perform best on +machines with very large caches.

+
+
+
+

+2.8. CAVEATS

+
+
+

I/O error messages are not as helpful as they could be. +bzip2 tries hard to detect I/O +errors and exit cleanly, but the details of what the problem is +sometimes seem rather misleading.

+

This manual page pertains to version 1.0.3 of +bzip2. Compressed data created +by this version is entirely forwards and backwards compatible +with the previous public releases, versions 0.1pl2, 0.9.0 and +0.9.5, 1.0.0, 1.0.1 and 1.0.2, but with the following exception: 0.9.0 +and above can correctly decompress multiple concatenated +compressed files. 0.1pl2 cannot do this; it will stop after +decompressing just the first file in the stream.

+

bzip2recover versions +prior to 1.0.2 used 32-bit integers to represent bit positions in +compressed files, so it could not handle compressed files more +than 512 megabytes long. Versions 1.0.2 and above use 64-bit ints +on some platforms which support them (GNU supported targets, and +Windows). To establish whether or not +bzip2recover was built with such +a limitation, run it without arguments. In any event you can +build yourself an unlimited version if you can recompile it with +MaybeUInt64 set to be an +unsigned 64-bit integer.

+
+
+
+

+2.9. AUTHOR

+
+
+

Julian Seward, +jseward@bzip.org

+

The ideas embodied in +bzip2 are due to (at least) the +following people: Michael Burrows and David Wheeler (for the +block sorting transformation), David Wheeler (again, for the +Huffman coder), Peter Fenwick (for the structured coding model in +the original bzip, and many +refinements), and Alistair Moffat, Radford Neal and Ian Witten +(for the arithmetic coder in the original +bzip). I am much indebted for +their help, support and advice. See the manual in the source +distribution for pointers to sources of documentation. Christian +von Roques encouraged me to look for faster sorting algorithms, +so as to speed up compression. Bela Lubkin encouraged me to +improve the worst-case compression performance. +Donna Robinson XMLised the documentation. +Many people sent +patches, helped with portability problems, lent machines, gave +advice and were generally helpful.

+
+
+
+
+

+3.  +Programming with libbzip2 +

+
+
+ +

This chapter describes the programming interface to +libbzip2.

+

For general background information, particularly about +memory use and performance aspects, you'd be well advised to read +How to use bzip2 as well.

+
+
+

+3.1. Top-level structure

+
+
+

libbzip2 is a flexible +library for compressing and decompressing data in the +bzip2 data format. Although +packaged as a single entity, it helps to regard the library as +three separate parts: the low level interface, and the high level +interface, and some utility functions.

+

The structure of +libbzip2's interfaces is similar +to that of Jean-loup Gailly's and Mark Adler's excellent +zlib library.

+

All externally visible symbols have names beginning +BZ2_. This is new in version +1.0. The intention is to minimise pollution of the namespaces of +library clients.

+

To use any part of the library, you need to +#include <bzlib.h> +into your sources.

+
+
+

+3.1.1. Low-level summary

+
+
+

This interface provides services for compressing and +decompressing data in memory. There's no provision for dealing +with files, streams or any other I/O mechanisms, just straight +memory-to-memory work. In fact, this part of the library can be +compiled without inclusion of +stdio.h, which may be helpful +for embedded applications.

+

The low-level part of the library has no global variables +and is therefore thread-safe.

+

Six routines make up the low level interface: +BZ2_bzCompressInit, +BZ2_bzCompress, and +BZ2_bzCompressEnd for +compression, and a corresponding trio +BZ2_bzDecompressInit, +BZ2_bzDecompress and +BZ2_bzDecompressEnd for +decompression. The *Init +functions allocate memory for compression/decompression and do +other initialisations, whilst the +*End functions close down +operations and release memory.

+

The real work is done by +BZ2_bzCompress and +BZ2_bzDecompress. These +compress and decompress data from a user-supplied input buffer to +a user-supplied output buffer. These buffers can be any size; +arbitrary quantities of data are handled by making repeated calls +to these functions. This is a flexible mechanism allowing a +consumer-pull style of activity, or producer-push, or a mixture +of both.

+
+
+
+

+3.1.2. High-level summary

+
+
+

This interface provides some handy wrappers around the +low-level interface to facilitate reading and writing +bzip2 format files +(.bz2 files). The routines +provide hooks to facilitate reading files in which the +bzip2 data stream is embedded +within some larger-scale file structure, or where there are +multiple bzip2 data streams +concatenated end-to-end.

+

For reading files, +BZ2_bzReadOpen, +BZ2_bzRead, +BZ2_bzReadClose and +BZ2_bzReadGetUnused are +supplied. For writing files, +BZ2_bzWriteOpen, +BZ2_bzWrite and +BZ2_bzWriteFinish are +available.

+

As with the low-level library, no global variables are used +so the library is per se thread-safe. However, if I/O errors +occur whilst reading or writing the underlying compressed files, +you may have to consult errno to +determine the cause of the error. In that case, you'd need a C +library which correctly supports +errno in a multithreaded +environment.

+

To make the library a little simpler and more portable, +BZ2_bzReadOpen and +BZ2_bzWriteOpen require you to +pass them file handles (FILE*s) +which have previously been opened for reading or writing +respectively. That avoids portability problems associated with +file operations and file attributes, whilst not being much of an +imposition on the programmer.

+
+
+
+

+3.1.3. Utility functions summary

+
+
+

For very simple needs, +BZ2_bzBuffToBuffCompress and +BZ2_bzBuffToBuffDecompress are +provided. These compress data in memory from one buffer to +another buffer in a single function call. You should assess +whether these functions fulfill your memory-to-memory +compression/decompression requirements before investing effort in +understanding the more general but more complex low-level +interface.

+

Yoshioka Tsuneo +(QWF00133@niftyserve.or.jp / +tsuneo-y@is.aist-nara.ac.jp) has +contributed some functions to give better +zlib compatibility. These +functions are BZ2_bzopen, +BZ2_bzread, +BZ2_bzwrite, +BZ2_bzflush, +BZ2_bzclose, +BZ2_bzerror and +BZ2_bzlibVersion. You may find +these functions more convenient for simple file reading and +writing, than those in the high-level interface. These functions +are not (yet) officially part of the library, and are minimally +documented here. If they break, you get to keep all the pieces. +I hope to document them properly when time permits.

+

Yoshioka also contributed modifications to allow the +library to be built as a Windows DLL.

+
+
+
+
+

+3.2. Error handling

+
+
+

The library is designed to recover cleanly in all +situations, including the worst-case situation of decompressing +random data. I'm not 100% sure that it can always do this, so +you might want to add a signal handler to catch segmentation +violations during decompression if you are feeling especially +paranoid. I would be interested in hearing more about the +robustness of the library to corrupted compressed data.

+

Version 1.0.3 more robust in this respect than any +previous version. Investigations with Valgrind (a tool for detecting +problems with memory management) indicate +that, at least for the few files I tested, all single-bit errors +in the decompressed data are caught properly, with no +segmentation faults, no uses of uninitialised data, no out of +range reads or writes, and no infinite looping in the decompressor. +So it's certainly pretty robust, although +I wouldn't claim it to be totally bombproof.

+

The file bzlib.h contains +all definitions needed to use the library. In particular, you +should definitely not include +bzlib_private.h.

+

In bzlib.h, the various +return values are defined. The following list is not intended as +an exhaustive description of the circumstances in which a given +value may be returned -- those descriptions are given later. +Rather, it is intended to convey the rough meaning of each return +value. The first five actions are normal and not intended to +denote an error situation.

+
+
BZ_OK
+

The requested action was completed + successfully.

+
BZ_RUN_OK, BZ_FLUSH_OK, + BZ_FINISH_OK
+

In + BZ2_bzCompress, the requested + flush/finish/nothing-special action was completed + successfully.

+
BZ_STREAM_END
+

Compression of data was completed, or the + logical stream end was detected during + decompression.

+
+

The following return values indicate an error of some +kind.

+
+
BZ_CONFIG_ERROR
+

Indicates that the library has been improperly + compiled on your platform -- a major configuration error. + Specifically, it means that + sizeof(char), + sizeof(short) and + sizeof(int) are not 1, 2 and + 4 respectively, as they should be. Note that the library + should still work properly on 64-bit platforms which follow + the LP64 programming model -- that is, where + sizeof(long) and + sizeof(void*) are 8. Under + LP64, sizeof(int) is still 4, + so libbzip2, which doesn't + use the long type, is + OK.

+
BZ_SEQUENCE_ERROR
+

When using the library, it is important to call + the functions in the correct sequence and with data structures + (buffers etc) in the correct states. + libbzip2 checks as much as it + can to ensure this is happening, and returns + BZ_SEQUENCE_ERROR if not. + Code which complies precisely with the function semantics, as + detailed below, should never receive this value; such an event + denotes buggy code which you should + investigate.

+
BZ_PARAM_ERROR
+

Returned when a parameter to a function call is + out of range or otherwise manifestly incorrect. As with + BZ_SEQUENCE_ERROR, this + denotes a bug in the client code. The distinction between + BZ_PARAM_ERROR and + BZ_SEQUENCE_ERROR is a bit + hazy, but still worth making.

+
BZ_MEM_ERROR
+

Returned when a request to allocate memory + failed. Note that the quantity of memory needed to decompress + a stream cannot be determined until the stream's header has + been read. So + BZ2_bzDecompress and + BZ2_bzRead may return + BZ_MEM_ERROR even though some + of the compressed data has been read. The same is not true + for compression; once + BZ2_bzCompressInit or + BZ2_bzWriteOpen have + successfully completed, + BZ_MEM_ERROR cannot + occur.

+
BZ_DATA_ERROR
+

Returned when a data integrity error is + detected during decompression. Most importantly, this means + when stored and computed CRCs for the data do not match. This + value is also returned upon detection of any other anomaly in + the compressed data.

+
BZ_DATA_ERROR_MAGIC
+

As a special case of + BZ_DATA_ERROR, it is + sometimes useful to know when the compressed stream does not + start with the correct magic bytes ('B' 'Z' + 'h').

+
BZ_IO_ERROR
+

Returned by + BZ2_bzRead and + BZ2_bzWrite when there is an + error reading or writing in the compressed file, and by + BZ2_bzReadOpen and + BZ2_bzWriteOpen for attempts + to use a file for which the error indicator (viz, + ferror(f)) is set. On + receipt of BZ_IO_ERROR, the + caller should consult errno + and/or perror to acquire + operating-system specific information about the + problem.

+
BZ_UNEXPECTED_EOF
+

Returned by + BZ2_bzRead when the + compressed file finishes before the logical end of stream is + detected.

+
BZ_OUTBUFF_FULL
+

Returned by + BZ2_bzBuffToBuffCompress and + BZ2_bzBuffToBuffDecompress to + indicate that the output data will not fit into the output + buffer provided.

+
+
+
+
+

+3.3. Low-level interface

+
+
+
+
+

+3.3.1. BZ2_bzCompressInit

+
+
+
typedef struct {
+  char *next_in;
+  unsigned int avail_in;
+  unsigned int total_in_lo32;
+  unsigned int total_in_hi32;
+
+  char *next_out;
+  unsigned int avail_out;
+  unsigned int total_out_lo32;
+  unsigned int total_out_hi32;
+
+  void *state;
+
+  void *(*bzalloc)(void *,int,int);
+  void (*bzfree)(void *,void *);
+  void *opaque;
+} bz_stream;
+
+int BZ2_bzCompressInit ( bz_stream *strm, 
+                         int blockSize100k, 
+                         int verbosity,
+                         int workFactor );
+

Prepares for compression. The +bz_stream structure holds all +data pertaining to the compression activity. A +bz_stream structure should be +allocated and initialised prior to the call. The fields of +bz_stream comprise the entirety +of the user-visible data. state +is a pointer to the private data structures required for +compression.

+

Custom memory allocators are supported, via fields +bzalloc, +bzfree, and +opaque. The value +opaque is passed to as the first +argument to all calls to bzalloc +and bzfree, but is otherwise +ignored by the library. The call bzalloc ( +opaque, n, m ) is expected to return a pointer +p to n * +m bytes of memory, and bzfree ( +opaque, p ) should free that memory.

+

If you don't want to use a custom memory allocator, set +bzalloc, +bzfree and +opaque to +NULL, and the library will then +use the standard malloc / +free routines.

+

Before calling +BZ2_bzCompressInit, fields +bzalloc, +bzfree and +opaque should be filled +appropriately, as just described. Upon return, the internal +state will have been allocated and initialised, and +total_in_lo32, +total_in_hi32, +total_out_lo32 and +total_out_hi32 will have been +set to zero. These four fields are used by the library to inform +the caller of the total amount of data passed into and out of the +library, respectively. You should not try to change them. As of +version 1.0, 64-bit counts are maintained, even on 32-bit +platforms, using the _hi32 +fields to store the upper 32 bits of the count. So, for example, +the total amount of data in is (total_in_hi32 +<< 32) + total_in_lo32.

+

Parameter blockSize100k +specifies the block size to be used for compression. It should +be a value between 1 and 9 inclusive, and the actual block size +used is 100000 x this figure. 9 gives the best compression but +takes most memory.

+

Parameter verbosity should +be set to a number between 0 and 4 inclusive. 0 is silent, and +greater numbers give increasingly verbose monitoring/debugging +output. If the library has been compiled with +-DBZ_NO_STDIO, no such output +will appear for any verbosity setting.

+

Parameter workFactor +controls how the compression phase behaves when presented with +worst case, highly repetitive, input data. If compression runs +into difficulties caused by repetitive data, the library switches +from the standard sorting algorithm to a fallback algorithm. The +fallback is slower than the standard algorithm by perhaps a +factor of three, but always behaves reasonably, no matter how bad +the input.

+

Lower values of workFactor +reduce the amount of effort the standard algorithm will expend +before resorting to the fallback. You should set this parameter +carefully; too low, and many inputs will be handled by the +fallback algorithm and so compress rather slowly, too high, and +your average-to-worst case compression times can become very +large. The default value of 30 gives reasonable behaviour over a +wide range of circumstances.

+

Allowable values range from 0 to 250 inclusive. 0 is a +special case, equivalent to using the default value of 30.

+

Note that the compressed output generated is the same +regardless of whether or not the fallback algorithm is +used.

+

Be aware also that this parameter may disappear entirely in +future versions of the library. In principle it should be +possible to devise a good way to automatically choose which +algorithm to use. Such a mechanism would render the parameter +obsolete.

+

Possible return values:

+
BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if strm is NULL 
+  or blockSize < 1 or blockSize > 9
+  or verbosity < 0 or verbosity > 4
+  or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR 
+  if not enough memory is available
+BZ_OK 
+  otherwise
+

Allowable next actions:

+
BZ2_bzCompress
+  if BZ_OK is returned
+  no specific action needed in case of error
+
+
+
+

+3.3.2. BZ2_bzCompress

+
+
+
int BZ2_bzCompress ( bz_stream *strm, int action );
+

Provides more input and/or output buffer space for the +library. The caller maintains input and output buffers, and +calls BZ2_bzCompress to transfer +data between them.

+

Before each call to +BZ2_bzCompress, +next_in should point at the data +to be compressed, and avail_in +should indicate how many bytes the library may read. +BZ2_bzCompress updates +next_in, +avail_in and +total_in to reflect the number +of bytes it has read.

+

Similarly, next_out should +point to a buffer in which the compressed data is to be placed, +with avail_out indicating how +much output space is available. +BZ2_bzCompress updates +next_out, +avail_out and +total_out to reflect the number +of bytes output.

+

You may provide and remove as little or as much data as you +like on each call of +BZ2_bzCompress. In the limit, +it is acceptable to supply and remove data one byte at a time, +although this would be terribly inefficient. You should always +ensure that at least one byte of output space is available at +each call.

+

A second purpose of +BZ2_bzCompress is to request a +change of mode of the compressed stream.

+

Conceptually, a compressed stream can be in one of four +states: IDLE, RUNNING, FLUSHING and FINISHING. Before +initialisation +(BZ2_bzCompressInit) and after +termination (BZ2_bzCompressEnd), +a stream is regarded as IDLE.

+

Upon initialisation +(BZ2_bzCompressInit), the stream +is placed in the RUNNING state. Subsequent calls to +BZ2_bzCompress should pass +BZ_RUN as the requested action; +other actions are illegal and will result in +BZ_SEQUENCE_ERROR.

+

At some point, the calling program will have provided all +the input data it wants to. It will then want to finish up -- in +effect, asking the library to process any data it might have +buffered internally. In this state, +BZ2_bzCompress will no longer +attempt to read data from +next_in, but it will want to +write data to next_out. Because +the output buffer supplied by the user can be arbitrarily small, +the finishing-up operation cannot necessarily be done with a +single call of +BZ2_bzCompress.

+

Instead, the calling program passes +BZ_FINISH as an action to +BZ2_bzCompress. This changes +the stream's state to FINISHING. Any remaining input (ie, +next_in[0 .. avail_in-1]) is +compressed and transferred to the output buffer. To do this, +BZ2_bzCompress must be called +repeatedly until all the output has been consumed. At that +point, BZ2_bzCompress returns +BZ_STREAM_END, and the stream's +state is set back to IDLE. +BZ2_bzCompressEnd should then be +called.

+

Just to make sure the calling program does not cheat, the +library makes a note of avail_in +at the time of the first call to +BZ2_bzCompress which has +BZ_FINISH as an action (ie, at +the time the program has announced its intention to not supply +any more input). By comparing this value with that of +avail_in over subsequent calls +to BZ2_bzCompress, the library +can detect any attempts to slip in more data to compress. Any +calls for which this is detected will return +BZ_SEQUENCE_ERROR. This +indicates a programming mistake which should be corrected.

+

Instead of asking to finish, the calling program may ask +BZ2_bzCompress to take all the +remaining input, compress it and terminate the current +(Burrows-Wheeler) compression block. This could be useful for +error control purposes. The mechanism is analogous to that for +finishing: call BZ2_bzCompress +with an action of BZ_FLUSH, +remove output data, and persist with the +BZ_FLUSH action until the value +BZ_RUN is returned. As with +finishing, BZ2_bzCompress +detects any attempt to provide more input data once the flush has +begun.

+

Once the flush is complete, the stream returns to the +normal RUNNING state.

+

This all sounds pretty complex, but isn't really. Here's a +table which shows which actions are allowable in each state, what +action will be taken, what the next state is, and what the +non-error return values are. Note that you can't explicitly ask +what state the stream is in, but nor do you need to -- it can be +inferred from the values returned by +BZ2_bzCompress.

+
IDLE/any
+  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
+  before BZ2_bzCompressInit.
+  Return value = BZ_SEQUENCE_ERROR
+
+RUNNING/BZ_RUN
+  Compress from next_in to next_out as much as possible.
+  Next state = RUNNING
+  Return value = BZ_RUN_OK
+
+RUNNING/BZ_FLUSH
+  Remember current value of next_in. Compress from next_in
+  to next_out as much as possible, but do not accept any more input.
+  Next state = FLUSHING
+  Return value = BZ_FLUSH_OK
+
+RUNNING/BZ_FINISH
+  Remember current value of next_in. Compress from next_in
+  to next_out as much as possible, but do not accept any more input.
+  Next state = FINISHING
+  Return value = BZ_FINISH_OK
+
+FLUSHING/BZ_FLUSH
+  Compress from next_in to next_out as much as possible, 
+  but do not accept any more input.
+  If all the existing input has been used up and all compressed
+  output has been removed
+    Next state = RUNNING; Return value = BZ_RUN_OK
+  else
+    Next state = FLUSHING; Return value = BZ_FLUSH_OK
+
+FLUSHING/other     
+  Illegal.
+  Return value = BZ_SEQUENCE_ERROR
+
+FINISHING/BZ_FINISH
+  Compress from next_in to next_out as much as possible,
+  but to not accept any more input.  
+  If all the existing input has been used up and all compressed
+  output has been removed
+    Next state = IDLE; Return value = BZ_STREAM_END
+  else
+    Next state = FINISHING; Return value = BZ_FINISHING
+
+FINISHING/other
+  Illegal.
+  Return value = BZ_SEQUENCE_ERROR
+

That still looks complicated? Well, fair enough. The +usual sequence of calls for compressing a load of data is:

+
    +
  1. Get started with + BZ2_bzCompressInit.

  2. +
  3. Shovel data in and shlurp out its compressed form + using zero or more calls of + BZ2_bzCompress with action = + BZ_RUN.

  4. +
  5. Finish up. Repeatedly call + BZ2_bzCompress with action = + BZ_FINISH, copying out the + compressed output, until + BZ_STREAM_END is + returned.

  6. +
  7. Close up and go home. Call + BZ2_bzCompressEnd.

  8. +
+

If the data you want to compress fits into your input +buffer all at once, you can skip the calls of +BZ2_bzCompress ( ..., BZ_RUN ) +and just do the BZ2_bzCompress ( ..., BZ_FINISH +) calls.

+

All required memory is allocated by +BZ2_bzCompressInit. The +compression library can accept any data at all (obviously). So +you shouldn't get any error return values from the +BZ2_bzCompress calls. If you +do, they will be +BZ_SEQUENCE_ERROR, and indicate +a bug in your programming.

+

Trivial other possible return values:

+
BZ_PARAM_ERROR
+  if strm is NULL, or strm->s is NULL
+
+
+
+

+3.3.3. BZ2_bzCompressEnd

+
+
+
int BZ2_bzCompressEnd ( bz_stream *strm );
+

Releases all memory associated with a compression +stream.

+

Possible return values:

+
BZ_PARAM_ERROR  if strm is NULL or strm->s is NULL
+BZ_OK           otherwise
+
+
+
+

+3.3.4. BZ2_bzDecompressInit

+
+
+
int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
+

Prepares for decompression. As with +BZ2_bzCompressInit, a +bz_stream record should be +allocated and initialised before the call. Fields +bzalloc, +bzfree and +opaque should be set if a custom +memory allocator is required, or made +NULL for the normal +malloc / +free routines. Upon return, the +internal state will have been initialised, and +total_in and +total_out will be zero.

+

For the meaning of parameter +verbosity, see +BZ2_bzCompressInit.

+

If small is nonzero, the +library will use an alternative decompression algorithm which +uses less memory but at the cost of decompressing more slowly +(roughly speaking, half the speed, but the maximum memory +requirement drops to around 2300k). See How to use bzip2 +for more information on memory management.

+

Note that the amount of memory needed to decompress a +stream cannot be determined until the stream's header has been +read, so even if +BZ2_bzDecompressInit succeeds, a +subsequent BZ2_bzDecompress +could fail with +BZ_MEM_ERROR.

+

Possible return values:

+
BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if ( small != 0 && small != 1 )
+  or (verbosity <; 0 || verbosity > 4)
+BZ_MEM_ERROR
+  if insufficient memory is available
+

Allowable next actions:

+
BZ2_bzDecompress
+  if BZ_OK was returned
+  no specific action required in case of error
+
+
+
+

+3.3.5. BZ2_bzDecompress

+
+
+
int BZ2_bzDecompress ( bz_stream *strm );
+

Provides more input and/out output buffer space for the +library. The caller maintains input and output buffers, and uses +BZ2_bzDecompress to transfer +data between them.

+

Before each call to +BZ2_bzDecompress, +next_in should point at the +compressed data, and avail_in +should indicate how many bytes the library may read. +BZ2_bzDecompress updates +next_in, +avail_in and +total_in to reflect the number +of bytes it has read.

+

Similarly, next_out should +point to a buffer in which the uncompressed output is to be +placed, with avail_out +indicating how much output space is available. +BZ2_bzCompress updates +next_out, +avail_out and +total_out to reflect the number +of bytes output.

+

You may provide and remove as little or as much data as you +like on each call of +BZ2_bzDecompress. In the limit, +it is acceptable to supply and remove data one byte at a time, +although this would be terribly inefficient. You should always +ensure that at least one byte of output space is available at +each call.

+

Use of BZ2_bzDecompress is +simpler than +BZ2_bzCompress.

+

You should provide input and remove output as described +above, and repeatedly call +BZ2_bzDecompress until +BZ_STREAM_END is returned. +Appearance of BZ_STREAM_END +denotes that BZ2_bzDecompress +has detected the logical end of the compressed stream. +BZ2_bzDecompress will not +produce BZ_STREAM_END until all +output data has been placed into the output buffer, so once +BZ_STREAM_END appears, you are +guaranteed to have available all the decompressed output, and +BZ2_bzDecompressEnd can safely +be called.

+

If case of an error return value, you should call +BZ2_bzDecompressEnd to clean up +and release memory.

+

Possible return values:

+
BZ_PARAM_ERROR
+  if strm is NULL or strm->s is NULL
+  or strm->avail_out < 1
+BZ_DATA_ERROR
+  if a data integrity error is detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+  if the compressed stream doesn't begin with the right magic bytes
+BZ_MEM_ERROR
+  if there wasn't enough memory available
+BZ_STREAM_END
+  if the logical end of the data stream was detected and all
+  output in has been consumed, eg s-->avail_out > 0
+BZ_OK
+  otherwise
+

Allowable next actions:

+
BZ2_bzDecompress
+  if BZ_OK was returned
+BZ2_bzDecompressEnd
+  otherwise
+
+
+
+

+3.3.6. BZ2_bzDecompressEnd

+
+
+
int BZ2_bzDecompressEnd ( bz_stream *strm );
+

Releases all memory associated with a decompression +stream.

+

Possible return values:

+
BZ_PARAM_ERROR
+  if strm is NULL or strm->s is NULL
+BZ_OK
+  otherwise
+

Allowable next actions:

+
  None.
+
+
+
+
+

+3.4. High-level interface

+
+
+

This interface provides functions for reading and writing +bzip2 format files. First, some +general points.

+
    +
  • All of the functions take an + int* first argument, + bzerror. After each call, + bzerror should be consulted + first to determine the outcome of the call. If + bzerror is + BZ_OK, the call completed + successfully, and only then should the return value of the + function (if any) be consulted. If + bzerror is + BZ_IO_ERROR, there was an + error reading/writing the underlying compressed file, and you + should then consult errno / + perror to determine the cause + of the difficulty. bzerror + may also be set to various other values; precise details are + given on a per-function basis below.

  • +
  • If bzerror indicates + an error (ie, anything except + BZ_OK and + BZ_STREAM_END), you should + immediately call + BZ2_bzReadClose (or + BZ2_bzWriteClose, depending on + whether you are attempting to read or to write) to free up all + resources associated with the stream. Once an error has been + indicated, behaviour of all calls except + BZ2_bzReadClose + (BZ2_bzWriteClose) is + undefined. The implication is that (1) + bzerror should be checked + after each call, and (2) if + bzerror indicates an error, + BZ2_bzReadClose + (BZ2_bzWriteClose) should then + be called to clean up.

  • +
  • The FILE* arguments + passed to BZ2_bzReadOpen / + BZ2_bzWriteOpen should be set + to binary mode. Most Unix systems will do this by default, but + other platforms, including Windows and Mac, will not. If you + omit this, you may encounter problems when moving code to new + platforms.

  • +
  • Memory allocation requests are handled by + malloc / + free. At present there is no + facility for user-defined memory allocators in the file I/O + functions (could easily be added, though).

  • +
+
+
+

+3.4.1. BZ2_bzReadOpen

+
+
+
typedef void BZFILE;
+
+BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, 
+                        int verbosity, int small,
+                        void *unused, int nUnused );
+

Prepare to read compressed data from file handle +f. +f should refer to a file which +has been opened for reading, and for which the error indicator +(ferror(f))is not set. If +small is 1, the library will try +to decompress using less memory, at the expense of speed.

+

For reasons explained below, +BZ2_bzRead will decompress the +nUnused bytes starting at +unused, before starting to read +from the file f. At most +BZ_MAX_UNUSED bytes may be +supplied like this. If this facility is not required, you should +pass NULL and +0 for +unused and +nUnused respectively.

+

For the meaning of parameters +small and +verbosity, see +BZ2_bzDecompressInit.

+

The amount of memory needed to decompress a file cannot be +determined until the file's header has been read. So it is +possible that BZ2_bzReadOpen +returns BZ_OK but a subsequent +call of BZ2_bzRead will return +BZ_MEM_ERROR.

+

Possible assignments to +bzerror:

+
BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if f is NULL
+  or small is neither 0 nor 1
+  or ( unused == NULL && nUnused != 0 )
+  or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
+BZ_IO_ERROR
+  if ferror(f) is nonzero
+BZ_MEM_ERROR
+  if insufficient memory is available
+BZ_OK
+  otherwise.
+

Possible return values:

+
Pointer to an abstract BZFILE
+  if bzerror is BZ_OK
+NULL
+  otherwise
+

Allowable next actions:

+
BZ2_bzRead
+  if bzerror is BZ_OK
+BZ2_bzClose
+  otherwise
+
+
+
+

+3.4.2. BZ2_bzRead

+
+
+
int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
+

Reads up to len +(uncompressed) bytes from the compressed file +b into the buffer +buf. If the read was +successful, bzerror is set to +BZ_OK and the number of bytes +read is returned. If the logical end-of-stream was detected, +bzerror will be set to +BZ_STREAM_END, and the number of +bytes read is returned. All other +bzerror values denote an +error.

+

BZ2_bzRead will supply +len bytes, unless the logical +stream end is detected or an error occurs. Because of this, it +is possible to detect the stream end by observing when the number +of bytes returned is less than the number requested. +Nevertheless, this is regarded as inadvisable; you should instead +check bzerror after every call +and watch out for +BZ_STREAM_END.

+

Internally, BZ2_bzRead +copies data from the compressed file in chunks of size +BZ_MAX_UNUSED bytes before +decompressing it. If the file contains more bytes than strictly +needed to reach the logical end-of-stream, +BZ2_bzRead will almost certainly +read some of the trailing data before signalling +BZ_SEQUENCE_END. To collect the +read but unused data once +BZ_SEQUENCE_END has appeared, +call BZ2_bzReadGetUnused +immediately before +BZ2_bzReadClose.

+

Possible assignments to +bzerror:

+
BZ_PARAM_ERROR
+  if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzWriteOpen
+BZ_IO_ERROR
+  if there is an error reading from the compressed file
+BZ_UNEXPECTED_EOF
+  if the compressed file ended before 
+  the logical end-of-stream was detected
+BZ_DATA_ERROR
+  if a data integrity error was detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+  if the stream does not begin with the requisite header bytes 
+  (ie, is not a bzip2 data file).  This is really 
+  a special case of BZ_DATA_ERROR.
+BZ_MEM_ERROR
+  if insufficient memory was available
+BZ_STREAM_END
+  if the logical end of stream was detected.
+BZ_OK
+  otherwise.
+

Possible return values:

+
number of bytes read
+  if bzerror is BZ_OK or BZ_STREAM_END
+undefined
+  otherwise
+

Allowable next actions:

+
collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
+  if bzerror is BZ_OK
+collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
+  if bzerror is BZ_SEQUENCE_END
+BZ2_bzReadClose
+  otherwise
+
+
+
+

+3.4.3. BZ2_bzReadGetUnused

+
+
+
void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, 
+                          void** unused, int* nUnused );
+

Returns data which was read from the compressed file but +was not needed to get to the logical end-of-stream. +*unused is set to the address of +the data, and *nUnused to the +number of bytes. *nUnused will +be set to a value between 0 and +BZ_MAX_UNUSED inclusive.

+

This function may only be called once +BZ2_bzRead has signalled +BZ_STREAM_END but before +BZ2_bzReadClose.

+

Possible assignments to +bzerror:

+
BZ_PARAM_ERROR
+  if b is NULL
+  or unused is NULL or nUnused is NULL
+BZ_SEQUENCE_ERROR
+  if BZ_STREAM_END has not been signalled
+  or if b was opened with BZ2_bzWriteOpen
+BZ_OK
+  otherwise
+

Allowable next actions:

+
BZ2_bzReadClose
+
+
+
+

+3.4.4. BZ2_bzReadClose

+
+
+
void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
+

Releases all memory pertaining to the compressed file +b. +BZ2_bzReadClose does not call +fclose on the underlying file +handle, so you should do that yourself if appropriate. +BZ2_bzReadClose should be called +to clean up after all error situations.

+

Possible assignments to +bzerror:

+
BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzOpenWrite
+BZ_OK
+  otherwise
+

Allowable next actions:

+
none
+
+
+
+

+3.4.5. BZ2_bzWriteOpen

+
+
+
BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, 
+                         int blockSize100k, int verbosity,
+                         int workFactor );
+

Prepare to write compressed data to file handle +f. +f should refer to a file which +has been opened for writing, and for which the error indicator +(ferror(f))is not set.

+

For the meaning of parameters +blockSize100k, +verbosity and +workFactor, see +BZ2_bzCompressInit.

+

All required memory is allocated at this stage, so if the +call completes successfully, +BZ_MEM_ERROR cannot be signalled +by a subsequent call to +BZ2_bzWrite.

+

Possible assignments to +bzerror:

+
BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if f is NULL
+  or blockSize100k < 1 or blockSize100k > 9
+BZ_IO_ERROR
+  if ferror(f) is nonzero
+BZ_MEM_ERROR
+  if insufficient memory is available
+BZ_OK
+  otherwise
+

Possible return values:

+
Pointer to an abstract BZFILE
+  if bzerror is BZ_OK
+NULL
+  otherwise
+

Allowable next actions:

+
BZ2_bzWrite
+  if bzerror is BZ_OK
+  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
+BZ2_bzWriteClose
+  otherwise
+
+
+
+

+3.4.6. BZ2_bzWrite

+
+
+
void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
+

Absorbs len bytes from the +buffer buf, eventually to be +compressed and written to the file.

+

Possible assignments to +bzerror:

+
BZ_PARAM_ERROR
+  if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+  if there is an error writing the compressed file.
+BZ_OK
+  otherwise
+
+
+
+

+3.4.7. BZ2_bzWriteClose

+
+
+
void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
+                       int abandon,
+                       unsigned int* nbytes_in,
+                       unsigned int* nbytes_out );
+
+void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
+                         int abandon,
+                         unsigned int* nbytes_in_lo32,
+                         unsigned int* nbytes_in_hi32,
+                         unsigned int* nbytes_out_lo32,
+                         unsigned int* nbytes_out_hi32 );
+

Compresses and flushes to the compressed file all data so +far supplied by BZ2_bzWrite. +The logical end-of-stream markers are also written, so subsequent +calls to BZ2_bzWrite are +illegal. All memory associated with the compressed file +b is released. +fflush is called on the +compressed file, but it is not +fclose'd.

+

If BZ2_bzWriteClose is +called to clean up after an error, the only action is to release +the memory. The library records the error codes issued by +previous calls, so this situation will be detected automatically. +There is no attempt to complete the compression operation, nor to +fflush the compressed file. You +can force this behaviour to happen even in the case of no error, +by passing a nonzero value to +abandon.

+

If nbytes_in is non-null, +*nbytes_in will be set to be the +total volume of uncompressed data handled. Similarly, +nbytes_out will be set to the +total volume of compressed data written. For compatibility with +older versions of the library, +BZ2_bzWriteClose only yields the +lower 32 bits of these counts. Use +BZ2_bzWriteClose64 if you want +the full 64 bit counts. These two functions are otherwise +absolutely identical.

+

Possible assignments to +bzerror:

+
BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+  if there is an error writing the compressed file
+BZ_OK
+  otherwise
+
+
+
+

+3.4.8. Handling embedded compressed data streams

+
+
+

The high-level library facilitates use of +bzip2 data streams which form +some part of a surrounding, larger data stream.

+
    +
  • For writing, the library takes an open file handle, + writes compressed data to it, + fflushes it but does not + fclose it. The calling + application can write its own data before and after the + compressed data stream, using that same file handle.

  • +
  • Reading is more complex, and the facilities are not as + general as they could be since generality is hard to reconcile + with efficiency. BZ2_bzRead + reads from the compressed file in blocks of size + BZ_MAX_UNUSED bytes, and in + doing so probably will overshoot the logical end of compressed + stream. To recover this data once decompression has ended, + call BZ2_bzReadGetUnused after + the last call of BZ2_bzRead + (the one returning + BZ_STREAM_END) but before + calling + BZ2_bzReadClose.

  • +
+

This mechanism makes it easy to decompress multiple +bzip2 streams placed end-to-end. +As the end of one stream, when +BZ2_bzRead returns +BZ_STREAM_END, call +BZ2_bzReadGetUnused to collect +the unused data (copy it into your own buffer somewhere). That +data forms the start of the next compressed stream. To start +uncompressing that next stream, call +BZ2_bzReadOpen again, feeding in +the unused data via the unused / +nUnused parameters. Keep doing +this until BZ_STREAM_END return +coincides with the physical end of file +(feof(f)). In this situation +BZ2_bzReadGetUnused will of +course return no data.

+

This should give some feel for how the high-level interface +can be used. If you require extra flexibility, you'll have to +bite the bullet and get to grips with the low-level +interface.

+
+
+
+

+3.4.9. Standard file-reading/writing code

+
+
+

Here's how you'd write data to a compressed file:

+
FILE*   f;
+BZFILE* b;
+int     nBuf;
+char    buf[ /* whatever size you like */ ];
+int     bzerror;
+int     nWritten;
+
+f = fopen ( "myfile.bz2", "w" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzWriteOpen( &bzerror, f, 9 );
+if (bzerror != BZ_OK) {
+ BZ2_bzWriteClose ( b );
+ /* handle error */
+}
+
+while ( /* condition */ ) {
+ /* get data to write into buf, and set nBuf appropriately */
+ nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
+ if (bzerror == BZ_IO_ERROR) { 
+   BZ2_bzWriteClose ( &bzerror, b );
+   /* handle error */
+ }
+}
+
+BZ2_bzWriteClose( &bzerror, b );
+if (bzerror == BZ_IO_ERROR) {
+ /* handle error */
+}
+

And to read from a compressed file:

+
FILE*   f;
+BZFILE* b;
+int     nBuf;
+char    buf[ /* whatever size you like */ ];
+int     bzerror;
+int     nWritten;
+
+f = fopen ( "myfile.bz2", "r" );
+if ( !f ) {
+  /* handle error */
+}
+b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
+if ( bzerror != BZ_OK ) {
+  BZ2_bzReadClose ( &bzerror, b );
+  /* handle error */
+}
+
+bzerror = BZ_OK;
+while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
+  nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
+  if ( bzerror == BZ_OK ) {
+    /* do something with buf[0 .. nBuf-1] */
+  }
+}
+if ( bzerror != BZ_STREAM_END ) {
+   BZ2_bzReadClose ( &bzerror, b );
+   /* handle error */
+} else {
+   BZ2_bzReadClose ( &bzerror );
+}
+
+
+
+
+

+3.5. Utility functions

+
+
+
+
+

+3.5.1. BZ2_bzBuffToBuffCompress

+
+
+
int BZ2_bzBuffToBuffCompress( char*         dest,
+                              unsigned int* destLen,
+                              char*         source,
+                              unsigned int  sourceLen,
+                              int           blockSize100k,
+                              int           verbosity,
+                              int           workFactor );
+

Attempts to compress the data in source[0 +.. sourceLen-1] into the destination buffer, +dest[0 .. *destLen-1]. If the +destination buffer is big enough, +*destLen is set to the size of +the compressed data, and BZ_OK +is returned. If the compressed data won't fit, +*destLen is unchanged, and +BZ_OUTBUFF_FULL is +returned.

+

Compression in this manner is a one-shot event, done with a +single call to this function. The resulting compressed data is a +complete bzip2 format data +stream. There is no mechanism for making additional calls to +provide extra input data. If you want that kind of mechanism, +use the low-level interface.

+

For the meaning of parameters +blockSize100k, +verbosity and +workFactor, see +BZ2_bzCompressInit.

+

To guarantee that the compressed data will fit in its +buffer, allocate an output buffer of size 1% larger than the +uncompressed data, plus six hundred extra bytes.

+

BZ2_bzBuffToBuffDecompress +will not write data at or beyond +dest[*destLen], even in case of +buffer overflow.

+

Possible return values:

+
BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if dest is NULL or destLen is NULL
+  or blockSize100k < 1 or blockSize100k > 9
+  or verbosity < 0 or verbosity > 4
+  or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR
+  if insufficient memory is available 
+BZ_OUTBUFF_FULL
+  if the size of the compressed data exceeds *destLen
+BZ_OK
+  otherwise
+
+
+
+

+3.5.2. BZ2_bzBuffToBuffDecompress

+
+
+
int BZ2_bzBuffToBuffDecompress( char*         dest,
+                                unsigned int* destLen,
+                                char*         source,
+                                unsigned int  sourceLen,
+                                int           small,
+                                int           verbosity );
+

Attempts to decompress the data in source[0 +.. sourceLen-1] into the destination buffer, +dest[0 .. *destLen-1]. If the +destination buffer is big enough, +*destLen is set to the size of +the uncompressed data, and BZ_OK +is returned. If the compressed data won't fit, +*destLen is unchanged, and +BZ_OUTBUFF_FULL is +returned.

+

source is assumed to hold +a complete bzip2 format data +stream. +BZ2_bzBuffToBuffDecompress tries +to decompress the entirety of the stream into the output +buffer.

+

For the meaning of parameters +small and +verbosity, see +BZ2_bzDecompressInit.

+

Because the compression ratio of the compressed data cannot +be known in advance, there is no easy way to guarantee that the +output buffer will be big enough. You may of course make +arrangements in your code to record the size of the uncompressed +data, but such a mechanism is beyond the scope of this +library.

+

BZ2_bzBuffToBuffDecompress +will not write data at or beyond +dest[*destLen], even in case of +buffer overflow.

+

Possible return values:

+
BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if dest is NULL or destLen is NULL
+  or small != 0 && small != 1
+  or verbosity < 0 or verbosity > 4
+BZ_MEM_ERROR
+  if insufficient memory is available 
+BZ_OUTBUFF_FULL
+  if the size of the compressed data exceeds *destLen
+BZ_DATA_ERROR
+  if a data integrity error was detected in the compressed data
+BZ_DATA_ERROR_MAGIC
+  if the compressed data doesn't begin with the right magic bytes
+BZ_UNEXPECTED_EOF
+  if the compressed data ends unexpectedly
+BZ_OK
+  otherwise
+
+
+
+
+

+3.6. zlib compatibility functions

+
+
+

Yoshioka Tsuneo has contributed some functions to give +better zlib compatibility. +These functions are BZ2_bzopen, +BZ2_bzread, +BZ2_bzwrite, +BZ2_bzflush, +BZ2_bzclose, +BZ2_bzerror and +BZ2_bzlibVersion. These +functions are not (yet) officially part of the library. If they +break, you get to keep all the pieces. Nevertheless, I think +they work ok.

+
typedef void BZFILE;
+
+const char * BZ2_bzlibVersion ( void );
+

Returns a string indicating the library version.

+
BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
+BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
+

Opens a .bz2 file for +reading or writing, using either its name or a pre-existing file +descriptor. Analogous to fopen +and fdopen.

+
int BZ2_bzread  ( BZFILE* b, void* buf, int len );
+int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
+

Reads/writes data from/to a previously opened +BZFILE. Analogous to +fread and +fwrite.

+
int  BZ2_bzflush ( BZFILE* b );
+void BZ2_bzclose ( BZFILE* b );
+

Flushes/closes a BZFILE. +BZ2_bzflush doesn't actually do +anything. Analogous to fflush +and fclose.

+
const char * BZ2_bzerror ( BZFILE *b, int *errnum )
+

Returns a string describing the more recent error status of +b, and also sets +*errnum to its numerical +value.

+
+
+
+

+3.7. Using the library in a stdio-free environment

+
+
+
+
+

+3.7.1. Getting rid of stdio

+
+
+

In a deeply embedded application, you might want to use +just the memory-to-memory functions. You can do this +conveniently by compiling the library with preprocessor symbol +BZ_NO_STDIO defined. Doing this +gives you a library containing only the following eight +functions:

+

BZ2_bzCompressInit, +BZ2_bzCompress, +BZ2_bzCompressEnd +BZ2_bzDecompressInit, +BZ2_bzDecompress, +BZ2_bzDecompressEnd +BZ2_bzBuffToBuffCompress, +BZ2_bzBuffToBuffDecompress

+

When compiled like this, all functions will ignore +verbosity settings.

+
+
+
+

+3.7.2. Critical error handling

+
+
+

libbzip2 contains a number +of internal assertion checks which should, needless to say, never +be activated. Nevertheless, if an assertion should fail, +behaviour depends on whether or not the library was compiled with +BZ_NO_STDIO set.

+

For a normal compile, an assertion failure yields the +message:

+
+

bzip2/libbzip2: internal error number N.

+

This is a bug in bzip2/libbzip2, 1.0.3 of 15 February 2005. +Please report it to me at: jseward@bzip.org. If this happened +when you were using some program which uses libbzip2 as a +component, you should also report this bug to the author(s) +of that program. Please make an effort to report this bug; +timely and accurate bug reports eventually lead to higher +quality software. Thanks. Julian Seward, 15 February 2005. +

+
+

where N is some error code +number. If N == 1007, it also +prints some extra text advising the reader that unreliable memory +is often associated with internal error 1007. (This is a +frequently-observed-phenomenon with versions 1.0.0/1.0.1).

+

exit(3) is then +called.

+

For a stdio-free library, +assertion failures result in a call to a function declared +as:

+
extern void bz_internal_error ( int errcode );
+

The relevant code is passed as a parameter. You should +supply such a function.

+

In either case, once an assertion failure has occurred, any +bz_stream records involved can +be regarded as invalid. You should not attempt to resume normal +operation with them.

+

You may, of course, change critical error handling to suit +your needs. As I said above, critical errors indicate bugs in +the library and should not occur. All "normal" error situations +are indicated via error return codes from functions, and can be +recovered from.

+
+
+
+
+

+3.8. Making a Windows DLL

+
+
+

Everything related to Windows has been contributed by +Yoshioka Tsuneo +(QWF00133@niftyserve.or.jp / +tsuneo-y@is.aist-nara.ac.jp), so +you should send your queries to him (but perhaps Cc: me, +jseward@bzip.org).

+

My vague understanding of what to do is: using Visual C++ +5.0, open the project file +libbz2.dsp, and build. That's +all.

+

If you can't open the project file for some reason, make a +new one, naming these files: +blocksort.c, +bzlib.c, +compress.c, +crctable.c, +decompress.c, +huffman.c, +randtable.c and +libbz2.def. You will also need +to name the header files bzlib.h +and bzlib_private.h.

+

If you don't use VC++, you may need to define the +proprocessor symbol +_WIN32.

+

Finally, dlltest.c is a +sample program using the DLL. It has a project file, +dlltest.dsp.

+

If you just want a makefile for Visual C, have a look at +makefile.msc.

+

Be aware that if you compile +bzip2 itself on Win32, you must +set BZ_UNIX to 0 and +BZ_LCCWIN32 to 1, in the file +bzip2.c, before compiling. +Otherwise the resulting binary won't work correctly.

+

I haven't tried any of this stuff myself, but it all looks +plausible.

+
+
+
+
+

+4. Miscellanea

+
+
+ +

These are just some random thoughts of mine. Your mileage +may vary.

+
+
+

+4.1. Limitations of the compressed file format

+
+
+

bzip2-1.0.X, +0.9.5 and +0.9.0 use exactly the same file +format as the original version, +bzip2-0.1. This decision was +made in the interests of stability. Creating yet another +incompatible compressed file format would create further +confusion and disruption for users.

+

Nevertheless, this is not a painless decision. Development +work since the release of +bzip2-0.1 in August 1997 has +shown complexities in the file format which slow down +decompression and, in retrospect, are unnecessary. These +are:

+
    +
  • The run-length encoder, which is the first of the + compression transformations, is entirely irrelevant. The + original purpose was to protect the sorting algorithm from the + very worst case input: a string of repeated symbols. But + algorithm steps Q6a and Q6b in the original Burrows-Wheeler + technical report (SRC-124) show how repeats can be handled + without difficulty in block sorting.

  • +
  • +

    The randomisation mechanism doesn't really need to be + there. Udi Manber and Gene Myers published a suffix array + construction algorithm a few years back, which can be employed + to sort any block, no matter how repetitive, in O(N log N) + time. Subsequent work by Kunihiko Sadakane has produced a + derivative O(N (log N)^2) algorithm which usually outperforms + the Manber-Myers algorithm.

    +

    I could have changed to Sadakane's algorithm, but I find + it to be slower than bzip2's + existing algorithm for most inputs, and the randomisation + mechanism protects adequately against bad cases. I didn't + think it was a good tradeoff to make. Partly this is due to + the fact that I was not flooded with email complaints about + bzip2-0.1's performance on + repetitive data, so perhaps it isn't a problem for real + inputs.

    +

    Probably the best long-term solution, and the one I have + incorporated into 0.9.5 and above, is to use the existing + sorting algorithm initially, and fall back to a O(N (log N)^2) + algorithm if the standard algorithm gets into + difficulties.

    +
  • +
  • The compressed file format was never designed to be + handled by a library, and I have had to jump though some hoops + to produce an efficient implementation of decompression. It's + a bit hairy. Try passing + decompress.c through the C + preprocessor and you'll see what I mean. Much of this + complexity could have been avoided if the compressed size of + each block of data was recorded in the data stream.

  • +
  • An Adler-32 checksum, rather than a CRC32 checksum, + would be faster to compute.

  • +
+

It would be fair to say that the +bzip2 format was frozen before I +properly and fully understood the performance consequences of +doing so.

+

Improvements which I was able to incorporate into 0.9.0, +despite using the same file format, are:

+
    +
  • Single array implementation of the inverse BWT. This + significantly speeds up decompression, presumably because it + reduces the number of cache misses.

  • +
  • Faster inverse MTF transform for large MTF values. + The new implementation is based on the notion of sliding blocks + of values.

  • +
  • bzip2-0.9.0 now reads + and writes files with fread + and fwrite; version 0.1 used + putc and + getc. Duh! Well, you live + and learn.

  • +
+

Further ahead, it would be nice to be able to do random +access into files. This will require some careful design of +compressed file formats.

+
+
+
+

+4.2. Portability issues

+
+
+

After some consideration, I have decided not to use GNU +autoconf to configure 0.9.5 or +1.0.

+

autoconf, admirable and +wonderful though it is, mainly assists with portability problems +between Unix-like platforms. But +bzip2 doesn't have much in the +way of portability problems on Unix; most of the difficulties +appear when porting to the Mac, or to Microsoft's operating +systems. autoconf doesn't help +in those cases, and brings in a whole load of new +complexity.

+

Most people should be able to compile the library and +program under Unix straight out-of-the-box, so to speak, +especially if you have a version of GNU C available.

+

There are a couple of +__inline__ directives in the +code. GNU C (gcc) should be +able to handle them. If you're not using GNU C, your C compiler +shouldn't see them at all. If your compiler does, for some +reason, see them and doesn't like them, just +#define +__inline__ to be +/* */. One easy way to do this +is to compile with the flag +-D__inline__=, which should be +understood by most Unix compilers.

+

If you still have difficulties, try compiling with the +macro BZ_STRICT_ANSI defined. +This should enable you to build the library in a strictly ANSI +compliant environment. Building the program itself like this is +dangerous and not supported, since you remove +bzip2's checks against +compressing directories, symbolic links, devices, and other +not-really-a-file entities. This could cause filesystem +corruption!

+

One other thing: if you create a +bzip2 binary for public distribution, +please consider linking it statically (gcc +-static). This avoids all sorts of library-version +issues that others may encounter later on.

+

If you build bzip2 on +Win32, you must set BZ_UNIX to 0 +and BZ_LCCWIN32 to 1, in the +file bzip2.c, before compiling. +Otherwise the resulting binary won't work correctly.

+
+
+
+

+4.3. Reporting bugs

+
+
+

I tried pretty hard to make sure +bzip2 is bug free, both by +design and by testing. Hopefully you'll never need to read this +section for real.

+

Nevertheless, if bzip2 dies +with a segmentation fault, a bus error or an internal assertion +failure, it will ask you to email me a bug report. Experience from +years of feedback of bzip2 users indicates that almost all these +problems can be traced to either compiler bugs or hardware +problems.

+
    +
  • +

    Recompile the program with no optimisation, and + see if it works. And/or try a different compiler. I heard all + sorts of stories about various flavours of GNU C (and other + compilers) generating bad code for + bzip2, and I've run across two + such examples myself.

    +

    2.7.X versions of GNU C are known to generate bad code + from time to time, at high optimisation levels. If you get + problems, try using the flags + -O2 + -fomit-frame-pointer + -fno-strength-reduce. You + should specifically not use + -funroll-loops.

    +

    You may notice that the Makefile runs six tests as part + of the build process. If the program passes all of these, it's + a pretty good (but not 100%) indication that the compiler has + done its job correctly.

    +
  • +
  • +

    If bzip2 + crashes randomly, and the crashes are not repeatable, you may + have a flaky memory subsystem. + bzip2 really hammers your + memory hierarchy, and if it's a bit marginal, you may get these + problems. Ditto if your disk or I/O subsystem is slowly + failing. Yup, this really does happen.

    +

    Try using a different machine of the same type, and see + if you can repeat the problem.

    +
  • +
  • This isn't really a bug, but ... If + bzip2 tells you your file is + corrupted on decompression, and you obtained the file via FTP, + there is a possibility that you forgot to tell FTP to do a + binary mode transfer. That absolutely will cause the file to + be non-decompressible. You'll have to transfer it + again.

  • +
+

If you've incorporated +libbzip2 into your own program +and are getting problems, please, please, please, check that the +parameters you are passing in calls to the library, are correct, +and in accordance with what the documentation says is allowable. +I have tried to make the library robust against such problems, +but I'm sure I haven't succeeded.

+

Finally, if the above comments don't help, you'll have to +send me a bug report. Now, it's just amazing how many people +will send me a bug report saying something like:

+
bzip2 crashed with segmentation fault on my machine
+

and absolutely nothing else. Needless to say, a such a +report is totally, utterly, completely and +comprehensively 100% useless; a waste of your time, my time, and +net bandwidth. With no details at all, there's no way +I can possibly begin to figure out what the problem is.

+

The rules of the game are: facts, facts, facts. Don't omit +them because "oh, they won't be relevant". At the bare +minimum:

+
Machine type.  Operating system version.  
+Exact version of bzip2 (do bzip2 -V).  
+Exact version of the compiler used.  
+Flags passed to the compiler.
+

However, the most important single thing that will help me +is the file that you were trying to compress or decompress at the +time the problem happened. Without that, my ability to do +anything more than speculate about the cause, is limited.

+
+
+
+

+4.4. Did you get the right package?

+
+
+

bzip2 is a resource hog. +It soaks up large amounts of CPU cycles and memory. Also, it +gives very large latencies. In the worst case, you can feed many +megabytes of uncompressed data into the library before getting +any compressed output, so this probably rules out applications +requiring interactive behaviour.

+

These aren't faults of my implementation, I hope, but more +an intrinsic property of the Burrows-Wheeler transform +(unfortunately). Maybe this isn't what you want.

+

If you want a compressor and/or library which is faster, +uses less memory but gets pretty good compression, and has +minimal latency, consider Jean-loup Gailly's and Mark Adler's +work, zlib-1.2.1 and +gzip-1.2.4. Look for them at +http://www.zlib.org and +http://www.gzip.org +respectively.

+

For something faster and lighter still, you might try Markus F +X J Oberhumer's LZO real-time +compression/decompression library, at +http://www.oberhumer.com/opensource.

+
+
+
+

+4.5. Further Reading

+
+
+

bzip2 is not research +work, in the sense that it doesn't present any new ideas. +Rather, it's an engineering exercise based on existing +ideas.

+

Four documents describe essentially all the ideas behind +bzip2:

+

Michael Burrows and D. J. Wheeler:
+  "A block-sorting lossless data compression algorithm"
+   10th May 1994. 
+   Digital SRC Research Report 124.
+   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
+   If you have trouble finding it, try searching at the
+   New Zealand Digital Library, http://www.nzdl.org.
+
+Daniel S. Hirschberg and Debra A. LeLewer
+  "Efficient Decoding of Prefix Codes"
+   Communications of the ACM, April 1990, Vol 33, Number 4.
+   You might be able to get an electronic copy of this
+   from the ACM Digital Library.
+
+David J. Wheeler
+   Program bred3.c and accompanying document bred3.ps.
+   This contains the idea behind the multi-table Huffman coding scheme.
+   ftp://ftp.cl.cam.ac.uk/users/djw3/
+
+Jon L. Bentley and Robert Sedgewick
+  "Fast Algorithms for Sorting and Searching Strings"
+   Available from Sedgewick's web page,
+   www.cs.princeton.edu/~rs
+

+

The following paper gives valuable additional insights into +the algorithm, but is not immediately the basis of any code used +in bzip2.

+

Peter Fenwick:
+   Block Sorting Text Compression
+   Proceedings of the 19th Australasian Computer Science Conference,
+     Melbourne, Australia.  Jan 31 - Feb 2, 1996.
+   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps

+

Kunihiko Sadakane's sorting algorithm, mentioned above, is +available from:

+

http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
+

+

The Manber-Myers suffix array construction algorithm is +described in a paper available from:

+

http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
+

+

Finally, the following papers document some +investigations I made into the performance of sorting +and decompression algorithms:

+

Julian Seward
+   On the Performance of BWT Sorting Algorithms
+   Proceedings of the IEEE Data Compression Conference 2000
+     Snowbird, Utah.  28-30 March 2000.
+
+Julian Seward
+   Space-time Tradeoffs in the Inverse B-W Transform
+   Proceedings of the IEEE Data Compression Conference 2001
+     Snowbird, Utah.  27-29 March 2001.
+

+
+
+
+ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdf b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdf new file mode 100644 index 000000000..394b80925 Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdf differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps new file mode 100644 index 000000000..03831d194 Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml new file mode 100644 index 000000000..1ab5bd71d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml @@ -0,0 +1,2966 @@ + + + %common-ents; +]> + + + + + bzip2 and libbzip2, version 1.0.3 + A program and library for data compression + + &bz-lifespan; + Julian Seward + + Version &bz-version; of &bz-date; + + + + Julian + Seward + + &bz-url; + + + + + + + This program, bzip2, the + associated library libbzip2, and + all documentation, are copyright © &bz-lifespan; Julian Seward. + All rights reserved. + + Redistribution and use in source and binary forms, with + or without modification, are permitted provided that the + following conditions are met: + + + + Redistributions of source code must retain the + above copyright notice, this list of conditions and the + following disclaimer. + + The origin of this software must not be + misrepresented; you must not claim that you wrote the original + software. If you use this software in a product, an + acknowledgment in the product documentation would be + appreciated but is not required. + + Altered source versions must be plainly marked + as such, and must not be misrepresented as being the original + software. + + The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + + + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + + PATENTS: To the best of my knowledge, + bzip2 and + libbzip2 do not use any patented + algorithms. However, I do not have the resources to carry + out a patent search. Therefore I cannot give any guarantee of + the above statement. + + + + + + + + + +Introduction + +bzip2 compresses files +using the Burrows-Wheeler block-sorting text compression +algorithm, and Huffman coding. Compression is generally +considerably better than that achieved by more conventional +LZ77/LZ78-based compressors, and approaches the performance of +the PPM family of statistical compressors. + +bzip2 is built on top of +libbzip2, a flexible library for +handling compressed data in the +bzip2 format. This manual +describes both how to use the program and how to work with the +library interface. Most of the manual is devoted to this +library, not the program, which is good news if your interest is +only in the program. + + + + describes how to use + bzip2; this is the only part + you need to read if you just want to know how to operate the + program. + + describes the + programming interfaces in detail, and + + records some + miscellaneous notes which I thought ought to be recorded + somewhere. + + + + + + + +How to use bzip2 + +This chapter contains a copy of the +bzip2 man page, and nothing +else. + + +NAME + + + + bzip2, + bunzip2 - a block-sorting file + compressor, v1.0.3 + + bzcat - + decompresses files to stdout + + bzip2recover - + recovers data from damaged bzip2 files + + + + + + + +SYNOPSIS + + + + bzip2 [ + -cdfkqstvzVL123456789 ] [ filenames ... ] + + bunzip2 [ + -fkvsVL ] [ filenames ... ] + + bzcat [ -s ] [ + filenames ... ] + + bzip2recover + filename + + + + + + + +DESCRIPTION + +bzip2 compresses files +using the Burrows-Wheeler block sorting text compression +algorithm, and Huffman coding. Compression is generally +considerably better than that achieved by more conventional +LZ77/LZ78-based compressors, and approaches the performance of +the PPM family of statistical compressors. + +The command-line options are deliberately very similar to +those of GNU gzip, but they are +not identical. + +bzip2 expects a list of +file names to accompany the command-line flags. Each file is +replaced by a compressed version of itself, with the name +original_name.bz2. Each +compressed file has the same modification date, permissions, and, +when possible, ownership as the corresponding original, so that +these properties can be correctly restored at decompression time. +File name handling is naive in the sense that there is no +mechanism for preserving original file names, permissions, +ownerships or dates in filesystems which lack these concepts, or +have serious file name length restrictions, such as +MS-DOS. + +bzip2 and +bunzip2 will by default not +overwrite existing files. If you want this to happen, specify +the -f flag. + +If no file names are specified, +bzip2 compresses from standard +input to standard output. In this case, +bzip2 will decline to write +compressed output to a terminal, as this would be entirely +incomprehensible and therefore pointless. + +bunzip2 (or +bzip2 -d) decompresses all +specified files. Files which were not created by +bzip2 will be detected and +ignored, and a warning issued. +bzip2 attempts to guess the +filename for the decompressed file from that of the compressed +file as follows: + + + + filename.bz2 + becomes + filename + + filename.bz + becomes + filename + + filename.tbz2 + becomes + filename.tar + + filename.tbz + becomes + filename.tar + + anyothername + becomes + anyothername.out + + + +If the file does not end in one of the recognised endings, +.bz2, +.bz, +.tbz2 or +.tbz, +bzip2 complains that it cannot +guess the name of the original file, and uses the original name +with .out appended. + +As with compression, supplying no filenames causes +decompression from standard input to standard output. + +bunzip2 will correctly +decompress a file which is the concatenation of two or more +compressed files. The result is the concatenation of the +corresponding uncompressed files. Integrity testing +(-t) of concatenated compressed +files is also supported. + +You can also compress or decompress files to the standard +output by giving the -c flag. +Multiple files may be compressed and decompressed like this. The +resulting outputs are fed sequentially to stdout. Compression of +multiple files in this manner generates a stream containing +multiple compressed file representations. Such a stream can be +decompressed correctly only by +bzip2 version 0.9.0 or later. +Earlier versions of bzip2 will +stop after decompressing the first file in the stream. + +bzcat (or +bzip2 -dc) decompresses all +specified files to the standard output. + +bzip2 will read arguments +from the environment variables +BZIP2 and +BZIP, in that order, and will +process them before any arguments read from the command line. +This gives a convenient way to supply default arguments. + +Compression is always performed, even if the compressed +file is slightly larger than the original. Files of less than +about one hundred bytes tend to get larger, since the compression +mechanism has a constant overhead in the region of 50 bytes. +Random data (including the output of most file compressors) is +coded at about 8.05 bits per byte, giving an expansion of around +0.5%. + +As a self-check for your protection, +bzip2 uses 32-bit CRCs to make +sure that the decompressed version of a file is identical to the +original. This guards against corruption of the compressed data, +and against undetected bugs in +bzip2 (hopefully very unlikely). +The chances of data corruption going undetected is microscopic, +about one chance in four billion for each file processed. Be +aware, though, that the check occurs upon decompression, so it +can only tell you that something is wrong. It can't help you +recover the original uncompressed data. You can use +bzip2recover to try to recover +data from damaged files. + +Return values: 0 for a normal exit, 1 for environmental +problems (file not found, invalid flags, I/O errors, etc.), 2 +to indicate a corrupt compressed file, 3 for an internal +consistency error (eg, bug) which caused +bzip2 to panic. + + + + + +OPTIONS + + + + + -c --stdout + Compress or decompress to standard + output. + + + + -d --decompress + Force decompression. + bzip2, + bunzip2 and + bzcat are really the same + program, and the decision about what actions to take is done on + the basis of which name is used. This flag overrides that + mechanism, and forces bzip2 to decompress. + + + + -z --compress + The complement to + -d: forces compression, + regardless of the invokation name. + + + + -t --test + Check integrity of the specified file(s), but + don't decompress them. This really performs a trial + decompression and throws away the result. + + + + -f --force + Force overwrite of output files. Normally, + bzip2 will not overwrite + existing output files. Also forces + bzip2 to break hard links to + files, which it otherwise wouldn't do. + bzip2 normally declines + to decompress files which don't have the correct magic header + bytes. If forced (-f), + however, it will pass such files through unmodified. This is + how GNU gzip behaves. + + + + + -k --keep + Keep (don't delete) input files during + compression or decompression. + + + + -s --small + Reduce memory usage, for compression, + decompression and testing. Files are decompressed and tested + using a modified algorithm which only requires 2.5 bytes per + block byte. This means any file can be decompressed in 2300k + of memory, albeit at about half the normal speed. + During compression, -s + selects a block size of 200k, which limits memory use to around + the same figure, at the expense of your compression ratio. In + short, if your machine is low on memory (8 megabytes or less), + use -s for everything. See + below. + + + + -q --quiet + Suppress non-essential warning messages. + Messages pertaining to I/O errors and other critical events + will not be suppressed. + + + + -v --verbose + Verbose mode -- show the compression ratio for + each file processed. Further + -v's increase the verbosity + level, spewing out lots of information which is primarily of + interest for diagnostic purposes. + + + + -L --license -V --version + Display the software version, license terms and + conditions. + + + + -1 (or + --fast) to + -9 (or + -best) + Set the block size to 100 k, 200 k ... 900 k + when compressing. Has no effect when decompressing. See below. The + --fast and + --best aliases are primarily + for GNU gzip compatibility. + In particular, --fast doesn't + make things significantly faster. And + --best merely selects the + default behaviour. + + + + -- + Treats all subsequent arguments as file names, + even if they start with a dash. This is so you can handle + files with names beginning with a dash, for example: + bzip2 -- + -myfilename. + + + + --repetitive-fast + --repetitive-best + These flags are redundant in versions 0.9.5 and + above. They provided some coarse control over the behaviour of + the sorting algorithm in earlier versions, which was sometimes + useful. 0.9.5 and above have an improved algorithm which + renders these flags irrelevant. + + + + + + + + +MEMORY MANAGEMENT + +bzip2 compresses large +files in blocks. The block size affects both the compression +ratio achieved, and the amount of memory needed for compression +and decompression. The flags -1 +through -9 specify the block +size to be 100,000 bytes through 900,000 bytes (the default) +respectively. At decompression time, the block size used for +compression is read from the header of the compressed file, and +bunzip2 then allocates itself +just enough memory to decompress the file. Since block sizes are +stored in compressed files, it follows that the flags +-1 to +-9 are irrelevant to and so +ignored during decompression. + +Compression and decompression requirements, in bytes, can be +estimated as: + +Compression: 400k + ( 8 x block size ) + +Decompression: 100k + ( 4 x block size ), or + 100k + ( 2.5 x block size ) + + +Larger block sizes give rapidly diminishing marginal +returns. Most of the compression comes from the first two or +three hundred k of block size, a fact worth bearing in mind when +using bzip2 on small machines. +It is also important to appreciate that the decompression memory +requirement is set at compression time by the choice of block +size. + +For files compressed with the default 900k block size, +bunzip2 will require about 3700 +kbytes to decompress. To support decompression of any file on a +4 megabyte machine, bunzip2 has +an option to decompress using approximately half this amount of +memory, about 2300 kbytes. Decompression speed is also halved, +so you should use this option only where necessary. The relevant +flag is -s. + +In general, try and use the largest block size memory +constraints allow, since that maximises the compression achieved. +Compression and decompression speed are virtually unaffected by +block size. + +Another significant point applies to files which fit in a +single block -- that means most files you'd encounter using a +large block size. The amount of real memory touched is +proportional to the size of the file, since the file is smaller +than a block. For example, compressing a file 20,000 bytes long +with the flag -9 will cause the +compressor to allocate around 7600k of memory, but only touch +400k + 20000 * 8 = 560 kbytes of it. Similarly, the decompressor +will allocate 3700k but only touch 100k + 20000 * 4 = 180 +kbytes. + +Here is a table which summarises the maximum memory usage +for different block sizes. Also recorded is the total compressed +size for 14 files of the Calgary Text Compression Corpus +totalling 3,141,622 bytes. This column gives some feel for how +compression varies with block size. These figures tend to +understate the advantage of larger block sizes for larger files, +since the Corpus is dominated by smaller files. + + + Compress Decompress Decompress Corpus +Flag usage usage -s usage Size + + -1 1200k 500k 350k 914704 + -2 2000k 900k 600k 877703 + -3 2800k 1300k 850k 860338 + -4 3600k 1700k 1100k 846899 + -5 4400k 2100k 1350k 845160 + -6 5200k 2500k 1600k 838626 + -7 6100k 2900k 1850k 834096 + -8 6800k 3300k 2100k 828642 + -9 7600k 3700k 2350k 828642 + + + + + + +RECOVERING DATA FROM DAMAGED FILES + +bzip2 compresses files in +blocks, usually 900kbytes long. Each block is handled +independently. If a media or transmission error causes a +multi-block .bz2 file to become +damaged, it may be possible to recover data from the undamaged +blocks in the file. + +The compressed representation of each block is delimited by +a 48-bit pattern, which makes it possible to find the block +boundaries with reasonable certainty. Each block also carries +its own 32-bit CRC, so damaged blocks can be distinguished from +undamaged ones. + +bzip2recover is a simple +program whose purpose is to search for blocks in +.bz2 files, and write each block +out into its own .bz2 file. You +can then use bzip2 -t to test +the integrity of the resulting files, and decompress those which +are undamaged. + +bzip2recover takes a +single argument, the name of the damaged file, and writes a +number of files rec0001file.bz2, +rec0002file.bz2, etc, containing +the extracted blocks. The output filenames are designed so that +the use of wildcards in subsequent processing -- for example, +bzip2 -dc rec*file.bz2 > +recovered_data -- lists the files in the correct +order. + +bzip2recover should be of +most use dealing with large .bz2 +files, as these will contain many blocks. It is clearly futile +to use it on damaged single-block files, since a damaged block +cannot be recovered. If you wish to minimise any potential data +loss through media or transmission errors, you might consider +compressing with a smaller block size. + + + + + +PERFORMANCE NOTES + +The sorting phase of compression gathers together similar +strings in the file. Because of this, files containing very long +runs of repeated symbols, like "aabaabaabaab ..." (repeated +several hundred times) may compress more slowly than normal. +Versions 0.9.5 and above fare much better than previous versions +in this respect. The ratio between worst-case and average-case +compression time is in the region of 10:1. For previous +versions, this figure was more like 100:1. You can use the +-vvvv option to monitor progress +in great detail, if you want. + +Decompression speed is unaffected by these +phenomena. + +bzip2 usually allocates +several megabytes of memory to operate in, and then charges all +over it in a fairly random fashion. This means that performance, +both for compressing and decompressing, is largely determined by +the speed at which your machine can service cache misses. +Because of this, small changes to the code to reduce the miss +rate have been observed to give disproportionately large +performance improvements. I imagine +bzip2 will perform best on +machines with very large caches. + + + + + + +CAVEATS + +I/O error messages are not as helpful as they could be. +bzip2 tries hard to detect I/O +errors and exit cleanly, but the details of what the problem is +sometimes seem rather misleading. + +This manual page pertains to version &bz-version; of +bzip2. Compressed data created +by this version is entirely forwards and backwards compatible +with the previous public releases, versions 0.1pl2, 0.9.0 and +0.9.5, 1.0.0, 1.0.1 and 1.0.2, but with the following exception: 0.9.0 +and above can correctly decompress multiple concatenated +compressed files. 0.1pl2 cannot do this; it will stop after +decompressing just the first file in the stream. + +bzip2recover versions +prior to 1.0.2 used 32-bit integers to represent bit positions in +compressed files, so it could not handle compressed files more +than 512 megabytes long. Versions 1.0.2 and above use 64-bit ints +on some platforms which support them (GNU supported targets, and +Windows). To establish whether or not +bzip2recover was built with such +a limitation, run it without arguments. In any event you can +build yourself an unlimited version if you can recompile it with +MaybeUInt64 set to be an +unsigned 64-bit integer. + + + + + + +AUTHOR + +Julian Seward, +&bz-email; + +The ideas embodied in +bzip2 are due to (at least) the +following people: Michael Burrows and David Wheeler (for the +block sorting transformation), David Wheeler (again, for the +Huffman coder), Peter Fenwick (for the structured coding model in +the original bzip, and many +refinements), and Alistair Moffat, Radford Neal and Ian Witten +(for the arithmetic coder in the original +bzip). I am much indebted for +their help, support and advice. See the manual in the source +distribution for pointers to sources of documentation. Christian +von Roques encouraged me to look for faster sorting algorithms, +so as to speed up compression. Bela Lubkin encouraged me to +improve the worst-case compression performance. +Donna Robinson XMLised the documentation. +Many people sent +patches, helped with portability problems, lent machines, gave +advice and were generally helpful. + + + + + + + + + +Programming with <computeroutput>libbzip2</computeroutput> + + +This chapter describes the programming interface to +libbzip2. + +For general background information, particularly about +memory use and performance aspects, you'd be well advised to read + as well. + + + +Top-level structure + +libbzip2 is a flexible +library for compressing and decompressing data in the +bzip2 data format. Although +packaged as a single entity, it helps to regard the library as +three separate parts: the low level interface, and the high level +interface, and some utility functions. + +The structure of +libbzip2's interfaces is similar +to that of Jean-loup Gailly's and Mark Adler's excellent +zlib library. + +All externally visible symbols have names beginning +BZ2_. This is new in version +1.0. The intention is to minimise pollution of the namespaces of +library clients. + +To use any part of the library, you need to +#include <bzlib.h> +into your sources. + + + + +Low-level summary + +This interface provides services for compressing and +decompressing data in memory. There's no provision for dealing +with files, streams or any other I/O mechanisms, just straight +memory-to-memory work. In fact, this part of the library can be +compiled without inclusion of +stdio.h, which may be helpful +for embedded applications. + +The low-level part of the library has no global variables +and is therefore thread-safe. + +Six routines make up the low level interface: +BZ2_bzCompressInit, +BZ2_bzCompress, and +BZ2_bzCompressEnd for +compression, and a corresponding trio +BZ2_bzDecompressInit, +BZ2_bzDecompress and +BZ2_bzDecompressEnd for +decompression. The *Init +functions allocate memory for compression/decompression and do +other initialisations, whilst the +*End functions close down +operations and release memory. + +The real work is done by +BZ2_bzCompress and +BZ2_bzDecompress. These +compress and decompress data from a user-supplied input buffer to +a user-supplied output buffer. These buffers can be any size; +arbitrary quantities of data are handled by making repeated calls +to these functions. This is a flexible mechanism allowing a +consumer-pull style of activity, or producer-push, or a mixture +of both. + + + + + +High-level summary + +This interface provides some handy wrappers around the +low-level interface to facilitate reading and writing +bzip2 format files +(.bz2 files). The routines +provide hooks to facilitate reading files in which the +bzip2 data stream is embedded +within some larger-scale file structure, or where there are +multiple bzip2 data streams +concatenated end-to-end. + +For reading files, +BZ2_bzReadOpen, +BZ2_bzRead, +BZ2_bzReadClose and +BZ2_bzReadGetUnused are +supplied. For writing files, +BZ2_bzWriteOpen, +BZ2_bzWrite and +BZ2_bzWriteFinish are +available. + +As with the low-level library, no global variables are used +so the library is per se thread-safe. However, if I/O errors +occur whilst reading or writing the underlying compressed files, +you may have to consult errno to +determine the cause of the error. In that case, you'd need a C +library which correctly supports +errno in a multithreaded +environment. + +To make the library a little simpler and more portable, +BZ2_bzReadOpen and +BZ2_bzWriteOpen require you to +pass them file handles (FILE*s) +which have previously been opened for reading or writing +respectively. That avoids portability problems associated with +file operations and file attributes, whilst not being much of an +imposition on the programmer. + + + + + +Utility functions summary + +For very simple needs, +BZ2_bzBuffToBuffCompress and +BZ2_bzBuffToBuffDecompress are +provided. These compress data in memory from one buffer to +another buffer in a single function call. You should assess +whether these functions fulfill your memory-to-memory +compression/decompression requirements before investing effort in +understanding the more general but more complex low-level +interface. + +Yoshioka Tsuneo +(QWF00133@niftyserve.or.jp / +tsuneo-y@is.aist-nara.ac.jp) has +contributed some functions to give better +zlib compatibility. These +functions are BZ2_bzopen, +BZ2_bzread, +BZ2_bzwrite, +BZ2_bzflush, +BZ2_bzclose, +BZ2_bzerror and +BZ2_bzlibVersion. You may find +these functions more convenient for simple file reading and +writing, than those in the high-level interface. These functions +are not (yet) officially part of the library, and are minimally +documented here. If they break, you get to keep all the pieces. +I hope to document them properly when time permits. + +Yoshioka also contributed modifications to allow the +library to be built as a Windows DLL. + + + + + + + +Error handling + +The library is designed to recover cleanly in all +situations, including the worst-case situation of decompressing +random data. I'm not 100% sure that it can always do this, so +you might want to add a signal handler to catch segmentation +violations during decompression if you are feeling especially +paranoid. I would be interested in hearing more about the +robustness of the library to corrupted compressed data. + +Version 1.0.3 more robust in this respect than any +previous version. Investigations with Valgrind (a tool for detecting +problems with memory management) indicate +that, at least for the few files I tested, all single-bit errors +in the decompressed data are caught properly, with no +segmentation faults, no uses of uninitialised data, no out of +range reads or writes, and no infinite looping in the decompressor. +So it's certainly pretty robust, although +I wouldn't claim it to be totally bombproof. + +The file bzlib.h contains +all definitions needed to use the library. In particular, you +should definitely not include +bzlib_private.h. + +In bzlib.h, the various +return values are defined. The following list is not intended as +an exhaustive description of the circumstances in which a given +value may be returned -- those descriptions are given later. +Rather, it is intended to convey the rough meaning of each return +value. The first five actions are normal and not intended to +denote an error situation. + + + + + BZ_OK + The requested action was completed + successfully. + + + + BZ_RUN_OK, BZ_FLUSH_OK, + BZ_FINISH_OK + In + BZ2_bzCompress, the requested + flush/finish/nothing-special action was completed + successfully. + + + + BZ_STREAM_END + Compression of data was completed, or the + logical stream end was detected during + decompression. + + + + +The following return values indicate an error of some +kind. + + + + + BZ_CONFIG_ERROR + Indicates that the library has been improperly + compiled on your platform -- a major configuration error. + Specifically, it means that + sizeof(char), + sizeof(short) and + sizeof(int) are not 1, 2 and + 4 respectively, as they should be. Note that the library + should still work properly on 64-bit platforms which follow + the LP64 programming model -- that is, where + sizeof(long) and + sizeof(void*) are 8. Under + LP64, sizeof(int) is still 4, + so libbzip2, which doesn't + use the long type, is + OK. + + + + BZ_SEQUENCE_ERROR + When using the library, it is important to call + the functions in the correct sequence and with data structures + (buffers etc) in the correct states. + libbzip2 checks as much as it + can to ensure this is happening, and returns + BZ_SEQUENCE_ERROR if not. + Code which complies precisely with the function semantics, as + detailed below, should never receive this value; such an event + denotes buggy code which you should + investigate. + + + + BZ_PARAM_ERROR + Returned when a parameter to a function call is + out of range or otherwise manifestly incorrect. As with + BZ_SEQUENCE_ERROR, this + denotes a bug in the client code. The distinction between + BZ_PARAM_ERROR and + BZ_SEQUENCE_ERROR is a bit + hazy, but still worth making. + + + + BZ_MEM_ERROR + Returned when a request to allocate memory + failed. Note that the quantity of memory needed to decompress + a stream cannot be determined until the stream's header has + been read. So + BZ2_bzDecompress and + BZ2_bzRead may return + BZ_MEM_ERROR even though some + of the compressed data has been read. The same is not true + for compression; once + BZ2_bzCompressInit or + BZ2_bzWriteOpen have + successfully completed, + BZ_MEM_ERROR cannot + occur. + + + + BZ_DATA_ERROR + Returned when a data integrity error is + detected during decompression. Most importantly, this means + when stored and computed CRCs for the data do not match. This + value is also returned upon detection of any other anomaly in + the compressed data. + + + + BZ_DATA_ERROR_MAGIC + As a special case of + BZ_DATA_ERROR, it is + sometimes useful to know when the compressed stream does not + start with the correct magic bytes ('B' 'Z' + 'h'). + + + + BZ_IO_ERROR + Returned by + BZ2_bzRead and + BZ2_bzWrite when there is an + error reading or writing in the compressed file, and by + BZ2_bzReadOpen and + BZ2_bzWriteOpen for attempts + to use a file for which the error indicator (viz, + ferror(f)) is set. On + receipt of BZ_IO_ERROR, the + caller should consult errno + and/or perror to acquire + operating-system specific information about the + problem. + + + + BZ_UNEXPECTED_EOF + Returned by + BZ2_bzRead when the + compressed file finishes before the logical end of stream is + detected. + + + + BZ_OUTBUFF_FULL + Returned by + BZ2_bzBuffToBuffCompress and + BZ2_bzBuffToBuffDecompress to + indicate that the output data will not fit into the output + buffer provided. + + + + + + + + + +Low-level interface + + + +<computeroutput>BZ2_bzCompressInit</computeroutput> + + +typedef struct { + char *next_in; + unsigned int avail_in; + unsigned int total_in_lo32; + unsigned int total_in_hi32; + + char *next_out; + unsigned int avail_out; + unsigned int total_out_lo32; + unsigned int total_out_hi32; + + void *state; + + void *(*bzalloc)(void *,int,int); + void (*bzfree)(void *,void *); + void *opaque; +} bz_stream; + +int BZ2_bzCompressInit ( bz_stream *strm, + int blockSize100k, + int verbosity, + int workFactor ); + + +Prepares for compression. The +bz_stream structure holds all +data pertaining to the compression activity. A +bz_stream structure should be +allocated and initialised prior to the call. The fields of +bz_stream comprise the entirety +of the user-visible data. state +is a pointer to the private data structures required for +compression. + +Custom memory allocators are supported, via fields +bzalloc, +bzfree, and +opaque. The value +opaque is passed to as the first +argument to all calls to bzalloc +and bzfree, but is otherwise +ignored by the library. The call bzalloc ( +opaque, n, m ) is expected to return a pointer +p to n * +m bytes of memory, and bzfree ( +opaque, p ) should free that memory. + +If you don't want to use a custom memory allocator, set +bzalloc, +bzfree and +opaque to +NULL, and the library will then +use the standard malloc / +free routines. + +Before calling +BZ2_bzCompressInit, fields +bzalloc, +bzfree and +opaque should be filled +appropriately, as just described. Upon return, the internal +state will have been allocated and initialised, and +total_in_lo32, +total_in_hi32, +total_out_lo32 and +total_out_hi32 will have been +set to zero. These four fields are used by the library to inform +the caller of the total amount of data passed into and out of the +library, respectively. You should not try to change them. As of +version 1.0, 64-bit counts are maintained, even on 32-bit +platforms, using the _hi32 +fields to store the upper 32 bits of the count. So, for example, +the total amount of data in is (total_in_hi32 +<< 32) + total_in_lo32. + +Parameter blockSize100k +specifies the block size to be used for compression. It should +be a value between 1 and 9 inclusive, and the actual block size +used is 100000 x this figure. 9 gives the best compression but +takes most memory. + +Parameter verbosity should +be set to a number between 0 and 4 inclusive. 0 is silent, and +greater numbers give increasingly verbose monitoring/debugging +output. If the library has been compiled with +-DBZ_NO_STDIO, no such output +will appear for any verbosity setting. + +Parameter workFactor +controls how the compression phase behaves when presented with +worst case, highly repetitive, input data. If compression runs +into difficulties caused by repetitive data, the library switches +from the standard sorting algorithm to a fallback algorithm. The +fallback is slower than the standard algorithm by perhaps a +factor of three, but always behaves reasonably, no matter how bad +the input. + +Lower values of workFactor +reduce the amount of effort the standard algorithm will expend +before resorting to the fallback. You should set this parameter +carefully; too low, and many inputs will be handled by the +fallback algorithm and so compress rather slowly, too high, and +your average-to-worst case compression times can become very +large. The default value of 30 gives reasonable behaviour over a +wide range of circumstances. + +Allowable values range from 0 to 250 inclusive. 0 is a +special case, equivalent to using the default value of 30. + +Note that the compressed output generated is the same +regardless of whether or not the fallback algorithm is +used. + +Be aware also that this parameter may disappear entirely in +future versions of the library. In principle it should be +possible to devise a good way to automatically choose which +algorithm to use. Such a mechanism would render the parameter +obsolete. + +Possible return values: + + +BZ_CONFIG_ERROR + if the library has been mis-compiled +BZ_PARAM_ERROR + if strm is NULL + or blockSize < 1 or blockSize > 9 + or verbosity < 0 or verbosity > 4 + or workFactor < 0 or workFactor > 250 +BZ_MEM_ERROR + if not enough memory is available +BZ_OK + otherwise + + +Allowable next actions: + + +BZ2_bzCompress + if BZ_OK is returned + no specific action needed in case of error + + + + + + +<computeroutput>BZ2_bzCompress</computeroutput> + + +int BZ2_bzCompress ( bz_stream *strm, int action ); + + +Provides more input and/or output buffer space for the +library. The caller maintains input and output buffers, and +calls BZ2_bzCompress to transfer +data between them. + +Before each call to +BZ2_bzCompress, +next_in should point at the data +to be compressed, and avail_in +should indicate how many bytes the library may read. +BZ2_bzCompress updates +next_in, +avail_in and +total_in to reflect the number +of bytes it has read. + +Similarly, next_out should +point to a buffer in which the compressed data is to be placed, +with avail_out indicating how +much output space is available. +BZ2_bzCompress updates +next_out, +avail_out and +total_out to reflect the number +of bytes output. + +You may provide and remove as little or as much data as you +like on each call of +BZ2_bzCompress. In the limit, +it is acceptable to supply and remove data one byte at a time, +although this would be terribly inefficient. You should always +ensure that at least one byte of output space is available at +each call. + +A second purpose of +BZ2_bzCompress is to request a +change of mode of the compressed stream. + +Conceptually, a compressed stream can be in one of four +states: IDLE, RUNNING, FLUSHING and FINISHING. Before +initialisation +(BZ2_bzCompressInit) and after +termination (BZ2_bzCompressEnd), +a stream is regarded as IDLE. + +Upon initialisation +(BZ2_bzCompressInit), the stream +is placed in the RUNNING state. Subsequent calls to +BZ2_bzCompress should pass +BZ_RUN as the requested action; +other actions are illegal and will result in +BZ_SEQUENCE_ERROR. + +At some point, the calling program will have provided all +the input data it wants to. It will then want to finish up -- in +effect, asking the library to process any data it might have +buffered internally. In this state, +BZ2_bzCompress will no longer +attempt to read data from +next_in, but it will want to +write data to next_out. Because +the output buffer supplied by the user can be arbitrarily small, +the finishing-up operation cannot necessarily be done with a +single call of +BZ2_bzCompress. + +Instead, the calling program passes +BZ_FINISH as an action to +BZ2_bzCompress. This changes +the stream's state to FINISHING. Any remaining input (ie, +next_in[0 .. avail_in-1]) is +compressed and transferred to the output buffer. To do this, +BZ2_bzCompress must be called +repeatedly until all the output has been consumed. At that +point, BZ2_bzCompress returns +BZ_STREAM_END, and the stream's +state is set back to IDLE. +BZ2_bzCompressEnd should then be +called. + +Just to make sure the calling program does not cheat, the +library makes a note of avail_in +at the time of the first call to +BZ2_bzCompress which has +BZ_FINISH as an action (ie, at +the time the program has announced its intention to not supply +any more input). By comparing this value with that of +avail_in over subsequent calls +to BZ2_bzCompress, the library +can detect any attempts to slip in more data to compress. Any +calls for which this is detected will return +BZ_SEQUENCE_ERROR. This +indicates a programming mistake which should be corrected. + +Instead of asking to finish, the calling program may ask +BZ2_bzCompress to take all the +remaining input, compress it and terminate the current +(Burrows-Wheeler) compression block. This could be useful for +error control purposes. The mechanism is analogous to that for +finishing: call BZ2_bzCompress +with an action of BZ_FLUSH, +remove output data, and persist with the +BZ_FLUSH action until the value +BZ_RUN is returned. As with +finishing, BZ2_bzCompress +detects any attempt to provide more input data once the flush has +begun. + +Once the flush is complete, the stream returns to the +normal RUNNING state. + +This all sounds pretty complex, but isn't really. Here's a +table which shows which actions are allowable in each state, what +action will be taken, what the next state is, and what the +non-error return values are. Note that you can't explicitly ask +what state the stream is in, but nor do you need to -- it can be +inferred from the values returned by +BZ2_bzCompress. + + +IDLE/any + Illegal. IDLE state only exists after BZ2_bzCompressEnd or + before BZ2_bzCompressInit. + Return value = BZ_SEQUENCE_ERROR + +RUNNING/BZ_RUN + Compress from next_in to next_out as much as possible. + Next state = RUNNING + Return value = BZ_RUN_OK + +RUNNING/BZ_FLUSH + Remember current value of next_in. Compress from next_in + to next_out as much as possible, but do not accept any more input. + Next state = FLUSHING + Return value = BZ_FLUSH_OK + +RUNNING/BZ_FINISH + Remember current value of next_in. Compress from next_in + to next_out as much as possible, but do not accept any more input. + Next state = FINISHING + Return value = BZ_FINISH_OK + +FLUSHING/BZ_FLUSH + Compress from next_in to next_out as much as possible, + but do not accept any more input. + If all the existing input has been used up and all compressed + output has been removed + Next state = RUNNING; Return value = BZ_RUN_OK + else + Next state = FLUSHING; Return value = BZ_FLUSH_OK + +FLUSHING/other + Illegal. + Return value = BZ_SEQUENCE_ERROR + +FINISHING/BZ_FINISH + Compress from next_in to next_out as much as possible, + but to not accept any more input. + If all the existing input has been used up and all compressed + output has been removed + Next state = IDLE; Return value = BZ_STREAM_END + else + Next state = FINISHING; Return value = BZ_FINISHING + +FINISHING/other + Illegal. + Return value = BZ_SEQUENCE_ERROR + + + +That still looks complicated? Well, fair enough. The +usual sequence of calls for compressing a load of data is: + + + + Get started with + BZ2_bzCompressInit. + + Shovel data in and shlurp out its compressed form + using zero or more calls of + BZ2_bzCompress with action = + BZ_RUN. + + Finish up. Repeatedly call + BZ2_bzCompress with action = + BZ_FINISH, copying out the + compressed output, until + BZ_STREAM_END is + returned. Close up and go home. Call + BZ2_bzCompressEnd. + + + +If the data you want to compress fits into your input +buffer all at once, you can skip the calls of +BZ2_bzCompress ( ..., BZ_RUN ) +and just do the BZ2_bzCompress ( ..., BZ_FINISH +) calls. + +All required memory is allocated by +BZ2_bzCompressInit. The +compression library can accept any data at all (obviously). So +you shouldn't get any error return values from the +BZ2_bzCompress calls. If you +do, they will be +BZ_SEQUENCE_ERROR, and indicate +a bug in your programming. + +Trivial other possible return values: + + +BZ_PARAM_ERROR + if strm is NULL, or strm->s is NULL + + + + + + +<computeroutput>BZ2_bzCompressEnd</computeroutput> + + +int BZ2_bzCompressEnd ( bz_stream *strm ); + + +Releases all memory associated with a compression +stream. + +Possible return values: + + +BZ_PARAM_ERROR if strm is NULL or strm->s is NULL +BZ_OK otherwise + + + + + + +<computeroutput>BZ2_bzDecompressInit</computeroutput> + + +int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small ); + + +Prepares for decompression. As with +BZ2_bzCompressInit, a +bz_stream record should be +allocated and initialised before the call. Fields +bzalloc, +bzfree and +opaque should be set if a custom +memory allocator is required, or made +NULL for the normal +malloc / +free routines. Upon return, the +internal state will have been initialised, and +total_in and +total_out will be zero. + +For the meaning of parameter +verbosity, see +BZ2_bzCompressInit. + +If small is nonzero, the +library will use an alternative decompression algorithm which +uses less memory but at the cost of decompressing more slowly +(roughly speaking, half the speed, but the maximum memory +requirement drops to around 2300k). See +for more information on memory management. + +Note that the amount of memory needed to decompress a +stream cannot be determined until the stream's header has been +read, so even if +BZ2_bzDecompressInit succeeds, a +subsequent BZ2_bzDecompress +could fail with +BZ_MEM_ERROR. + +Possible return values: + + +BZ_CONFIG_ERROR + if the library has been mis-compiled +BZ_PARAM_ERROR + if ( small != 0 && small != 1 ) + or (verbosity <; 0 || verbosity > 4) +BZ_MEM_ERROR + if insufficient memory is available + + +Allowable next actions: + + +BZ2_bzDecompress + if BZ_OK was returned + no specific action required in case of error + + + + + + +<computeroutput>BZ2_bzDecompress</computeroutput> + + +int BZ2_bzDecompress ( bz_stream *strm ); + + +Provides more input and/out output buffer space for the +library. The caller maintains input and output buffers, and uses +BZ2_bzDecompress to transfer +data between them. + +Before each call to +BZ2_bzDecompress, +next_in should point at the +compressed data, and avail_in +should indicate how many bytes the library may read. +BZ2_bzDecompress updates +next_in, +avail_in and +total_in to reflect the number +of bytes it has read. + +Similarly, next_out should +point to a buffer in which the uncompressed output is to be +placed, with avail_out +indicating how much output space is available. +BZ2_bzCompress updates +next_out, +avail_out and +total_out to reflect the number +of bytes output. + +You may provide and remove as little or as much data as you +like on each call of +BZ2_bzDecompress. In the limit, +it is acceptable to supply and remove data one byte at a time, +although this would be terribly inefficient. You should always +ensure that at least one byte of output space is available at +each call. + +Use of BZ2_bzDecompress is +simpler than +BZ2_bzCompress. + +You should provide input and remove output as described +above, and repeatedly call +BZ2_bzDecompress until +BZ_STREAM_END is returned. +Appearance of BZ_STREAM_END +denotes that BZ2_bzDecompress +has detected the logical end of the compressed stream. +BZ2_bzDecompress will not +produce BZ_STREAM_END until all +output data has been placed into the output buffer, so once +BZ_STREAM_END appears, you are +guaranteed to have available all the decompressed output, and +BZ2_bzDecompressEnd can safely +be called. + +If case of an error return value, you should call +BZ2_bzDecompressEnd to clean up +and release memory. + +Possible return values: + + +BZ_PARAM_ERROR + if strm is NULL or strm->s is NULL + or strm->avail_out < 1 +BZ_DATA_ERROR + if a data integrity error is detected in the compressed stream +BZ_DATA_ERROR_MAGIC + if the compressed stream doesn't begin with the right magic bytes +BZ_MEM_ERROR + if there wasn't enough memory available +BZ_STREAM_END + if the logical end of the data stream was detected and all + output in has been consumed, eg s-->avail_out > 0 +BZ_OK + otherwise + + +Allowable next actions: + + +BZ2_bzDecompress + if BZ_OK was returned +BZ2_bzDecompressEnd + otherwise + + + + + + +<computeroutput>BZ2_bzDecompressEnd</computeroutput> + + +int BZ2_bzDecompressEnd ( bz_stream *strm ); + + +Releases all memory associated with a decompression +stream. + +Possible return values: + + +BZ_PARAM_ERROR + if strm is NULL or strm->s is NULL +BZ_OK + otherwise + + +Allowable next actions: + + + None. + + + + + + + + +High-level interface + +This interface provides functions for reading and writing +bzip2 format files. First, some +general points. + + + + All of the functions take an + int* first argument, + bzerror. After each call, + bzerror should be consulted + first to determine the outcome of the call. If + bzerror is + BZ_OK, the call completed + successfully, and only then should the return value of the + function (if any) be consulted. If + bzerror is + BZ_IO_ERROR, there was an + error reading/writing the underlying compressed file, and you + should then consult errno / + perror to determine the cause + of the difficulty. bzerror + may also be set to various other values; precise details are + given on a per-function basis below. + + If bzerror indicates + an error (ie, anything except + BZ_OK and + BZ_STREAM_END), you should + immediately call + BZ2_bzReadClose (or + BZ2_bzWriteClose, depending on + whether you are attempting to read or to write) to free up all + resources associated with the stream. Once an error has been + indicated, behaviour of all calls except + BZ2_bzReadClose + (BZ2_bzWriteClose) is + undefined. The implication is that (1) + bzerror should be checked + after each call, and (2) if + bzerror indicates an error, + BZ2_bzReadClose + (BZ2_bzWriteClose) should then + be called to clean up. + + The FILE* arguments + passed to BZ2_bzReadOpen / + BZ2_bzWriteOpen should be set + to binary mode. Most Unix systems will do this by default, but + other platforms, including Windows and Mac, will not. If you + omit this, you may encounter problems when moving code to new + platforms. + + Memory allocation requests are handled by + malloc / + free. At present there is no + facility for user-defined memory allocators in the file I/O + functions (could easily be added, though). + + + + + + +<computeroutput>BZ2_bzReadOpen</computeroutput> + + +typedef void BZFILE; + +BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, + int verbosity, int small, + void *unused, int nUnused ); + + +Prepare to read compressed data from file handle +f. +f should refer to a file which +has been opened for reading, and for which the error indicator +(ferror(f))is not set. If +small is 1, the library will try +to decompress using less memory, at the expense of speed. + +For reasons explained below, +BZ2_bzRead will decompress the +nUnused bytes starting at +unused, before starting to read +from the file f. At most +BZ_MAX_UNUSED bytes may be +supplied like this. If this facility is not required, you should +pass NULL and +0 for +unused and +nUnused respectively. + +For the meaning of parameters +small and +verbosity, see +BZ2_bzDecompressInit. + +The amount of memory needed to decompress a file cannot be +determined until the file's header has been read. So it is +possible that BZ2_bzReadOpen +returns BZ_OK but a subsequent +call of BZ2_bzRead will return +BZ_MEM_ERROR. + +Possible assignments to +bzerror: + + +BZ_CONFIG_ERROR + if the library has been mis-compiled +BZ_PARAM_ERROR + if f is NULL + or small is neither 0 nor 1 + or ( unused == NULL && nUnused != 0 ) + or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) ) +BZ_IO_ERROR + if ferror(f) is nonzero +BZ_MEM_ERROR + if insufficient memory is available +BZ_OK + otherwise. + + +Possible return values: + + +Pointer to an abstract BZFILE + if bzerror is BZ_OK +NULL + otherwise + + +Allowable next actions: + + +BZ2_bzRead + if bzerror is BZ_OK +BZ2_bzClose + otherwise + + + + + + +<computeroutput>BZ2_bzRead</computeroutput> + + +int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len ); + + +Reads up to len +(uncompressed) bytes from the compressed file +b into the buffer +buf. If the read was +successful, bzerror is set to +BZ_OK and the number of bytes +read is returned. If the logical end-of-stream was detected, +bzerror will be set to +BZ_STREAM_END, and the number of +bytes read is returned. All other +bzerror values denote an +error. + +BZ2_bzRead will supply +len bytes, unless the logical +stream end is detected or an error occurs. Because of this, it +is possible to detect the stream end by observing when the number +of bytes returned is less than the number requested. +Nevertheless, this is regarded as inadvisable; you should instead +check bzerror after every call +and watch out for +BZ_STREAM_END. + +Internally, BZ2_bzRead +copies data from the compressed file in chunks of size +BZ_MAX_UNUSED bytes before +decompressing it. If the file contains more bytes than strictly +needed to reach the logical end-of-stream, +BZ2_bzRead will almost certainly +read some of the trailing data before signalling +BZ_SEQUENCE_END. To collect the +read but unused data once +BZ_SEQUENCE_END has appeared, +call BZ2_bzReadGetUnused +immediately before +BZ2_bzReadClose. + +Possible assignments to +bzerror: + + +BZ_PARAM_ERROR + if b is NULL or buf is NULL or len < 0 +BZ_SEQUENCE_ERROR + if b was opened with BZ2_bzWriteOpen +BZ_IO_ERROR + if there is an error reading from the compressed file +BZ_UNEXPECTED_EOF + if the compressed file ended before + the logical end-of-stream was detected +BZ_DATA_ERROR + if a data integrity error was detected in the compressed stream +BZ_DATA_ERROR_MAGIC + if the stream does not begin with the requisite header bytes + (ie, is not a bzip2 data file). This is really + a special case of BZ_DATA_ERROR. +BZ_MEM_ERROR + if insufficient memory was available +BZ_STREAM_END + if the logical end of stream was detected. +BZ_OK + otherwise. + + +Possible return values: + + +number of bytes read + if bzerror is BZ_OK or BZ_STREAM_END +undefined + otherwise + + +Allowable next actions: + + +collect data from buf, then BZ2_bzRead or BZ2_bzReadClose + if bzerror is BZ_OK +collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused + if bzerror is BZ_SEQUENCE_END +BZ2_bzReadClose + otherwise + + + + + + +<computeroutput>BZ2_bzReadGetUnused</computeroutput> + + +void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, + void** unused, int* nUnused ); + + +Returns data which was read from the compressed file but +was not needed to get to the logical end-of-stream. +*unused is set to the address of +the data, and *nUnused to the +number of bytes. *nUnused will +be set to a value between 0 and +BZ_MAX_UNUSED inclusive. + +This function may only be called once +BZ2_bzRead has signalled +BZ_STREAM_END but before +BZ2_bzReadClose. + +Possible assignments to +bzerror: + + +BZ_PARAM_ERROR + if b is NULL + or unused is NULL or nUnused is NULL +BZ_SEQUENCE_ERROR + if BZ_STREAM_END has not been signalled + or if b was opened with BZ2_bzWriteOpen +BZ_OK + otherwise + + +Allowable next actions: + + +BZ2_bzReadClose + + + + + + +<computeroutput>BZ2_bzReadClose</computeroutput> + + +void BZ2_bzReadClose ( int *bzerror, BZFILE *b ); + + +Releases all memory pertaining to the compressed file +b. +BZ2_bzReadClose does not call +fclose on the underlying file +handle, so you should do that yourself if appropriate. +BZ2_bzReadClose should be called +to clean up after all error situations. + +Possible assignments to +bzerror: + + +BZ_SEQUENCE_ERROR + if b was opened with BZ2_bzOpenWrite +BZ_OK + otherwise + + +Allowable next actions: + + +none + + + + + + +<computeroutput>BZ2_bzWriteOpen</computeroutput> + + +BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, + int blockSize100k, int verbosity, + int workFactor ); + + +Prepare to write compressed data to file handle +f. +f should refer to a file which +has been opened for writing, and for which the error indicator +(ferror(f))is not set. + +For the meaning of parameters +blockSize100k, +verbosity and +workFactor, see +BZ2_bzCompressInit. + +All required memory is allocated at this stage, so if the +call completes successfully, +BZ_MEM_ERROR cannot be signalled +by a subsequent call to +BZ2_bzWrite. + +Possible assignments to +bzerror: + + +BZ_CONFIG_ERROR + if the library has been mis-compiled +BZ_PARAM_ERROR + if f is NULL + or blockSize100k < 1 or blockSize100k > 9 +BZ_IO_ERROR + if ferror(f) is nonzero +BZ_MEM_ERROR + if insufficient memory is available +BZ_OK + otherwise + + +Possible return values: + + +Pointer to an abstract BZFILE + if bzerror is BZ_OK +NULL + otherwise + + +Allowable next actions: + + +BZ2_bzWrite + if bzerror is BZ_OK + (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless) +BZ2_bzWriteClose + otherwise + + + + + + +<computeroutput>BZ2_bzWrite</computeroutput> + + +void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len ); + + +Absorbs len bytes from the +buffer buf, eventually to be +compressed and written to the file. + +Possible assignments to +bzerror: + + +BZ_PARAM_ERROR + if b is NULL or buf is NULL or len < 0 +BZ_SEQUENCE_ERROR + if b was opened with BZ2_bzReadOpen +BZ_IO_ERROR + if there is an error writing the compressed file. +BZ_OK + otherwise + + + + + + +<computeroutput>BZ2_bzWriteClose</computeroutput> + + +void BZ2_bzWriteClose( int *bzerror, BZFILE* f, + int abandon, + unsigned int* nbytes_in, + unsigned int* nbytes_out ); + +void BZ2_bzWriteClose64( int *bzerror, BZFILE* f, + int abandon, + unsigned int* nbytes_in_lo32, + unsigned int* nbytes_in_hi32, + unsigned int* nbytes_out_lo32, + unsigned int* nbytes_out_hi32 ); + + +Compresses and flushes to the compressed file all data so +far supplied by BZ2_bzWrite. +The logical end-of-stream markers are also written, so subsequent +calls to BZ2_bzWrite are +illegal. All memory associated with the compressed file +b is released. +fflush is called on the +compressed file, but it is not +fclose'd. + +If BZ2_bzWriteClose is +called to clean up after an error, the only action is to release +the memory. The library records the error codes issued by +previous calls, so this situation will be detected automatically. +There is no attempt to complete the compression operation, nor to +fflush the compressed file. You +can force this behaviour to happen even in the case of no error, +by passing a nonzero value to +abandon. + +If nbytes_in is non-null, +*nbytes_in will be set to be the +total volume of uncompressed data handled. Similarly, +nbytes_out will be set to the +total volume of compressed data written. For compatibility with +older versions of the library, +BZ2_bzWriteClose only yields the +lower 32 bits of these counts. Use +BZ2_bzWriteClose64 if you want +the full 64 bit counts. These two functions are otherwise +absolutely identical. + +Possible assignments to +bzerror: + + +BZ_SEQUENCE_ERROR + if b was opened with BZ2_bzReadOpen +BZ_IO_ERROR + if there is an error writing the compressed file +BZ_OK + otherwise + + + + + + +Handling embedded compressed data streams + +The high-level library facilitates use of +bzip2 data streams which form +some part of a surrounding, larger data stream. + + + + For writing, the library takes an open file handle, + writes compressed data to it, + fflushes it but does not + fclose it. The calling + application can write its own data before and after the + compressed data stream, using that same file handle. + + Reading is more complex, and the facilities are not as + general as they could be since generality is hard to reconcile + with efficiency. BZ2_bzRead + reads from the compressed file in blocks of size + BZ_MAX_UNUSED bytes, and in + doing so probably will overshoot the logical end of compressed + stream. To recover this data once decompression has ended, + call BZ2_bzReadGetUnused after + the last call of BZ2_bzRead + (the one returning + BZ_STREAM_END) but before + calling + BZ2_bzReadClose. + + + +This mechanism makes it easy to decompress multiple +bzip2 streams placed end-to-end. +As the end of one stream, when +BZ2_bzRead returns +BZ_STREAM_END, call +BZ2_bzReadGetUnused to collect +the unused data (copy it into your own buffer somewhere). That +data forms the start of the next compressed stream. To start +uncompressing that next stream, call +BZ2_bzReadOpen again, feeding in +the unused data via the unused / +nUnused parameters. Keep doing +this until BZ_STREAM_END return +coincides with the physical end of file +(feof(f)). In this situation +BZ2_bzReadGetUnused will of +course return no data. + +This should give some feel for how the high-level interface +can be used. If you require extra flexibility, you'll have to +bite the bullet and get to grips with the low-level +interface. + + + + + +Standard file-reading/writing code + +Here's how you'd write data to a compressed file: + + +FILE* f; +BZFILE* b; +int nBuf; +char buf[ /* whatever size you like */ ]; +int bzerror; +int nWritten; + +f = fopen ( "myfile.bz2", "w" ); +if ( !f ) { + /* handle error */ +} +b = BZ2_bzWriteOpen( &bzerror, f, 9 ); +if (bzerror != BZ_OK) { + BZ2_bzWriteClose ( b ); + /* handle error */ +} + +while ( /* condition */ ) { + /* get data to write into buf, and set nBuf appropriately */ + nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf ); + if (bzerror == BZ_IO_ERROR) { + BZ2_bzWriteClose ( &bzerror, b ); + /* handle error */ + } +} + +BZ2_bzWriteClose( &bzerror, b ); +if (bzerror == BZ_IO_ERROR) { + /* handle error */ +} + + +And to read from a compressed file: + + +FILE* f; +BZFILE* b; +int nBuf; +char buf[ /* whatever size you like */ ]; +int bzerror; +int nWritten; + +f = fopen ( "myfile.bz2", "r" ); +if ( !f ) { + /* handle error */ +} +b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 ); +if ( bzerror != BZ_OK ) { + BZ2_bzReadClose ( &bzerror, b ); + /* handle error */ +} + +bzerror = BZ_OK; +while ( bzerror == BZ_OK && /* arbitrary other conditions */) { + nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ ); + if ( bzerror == BZ_OK ) { + /* do something with buf[0 .. nBuf-1] */ + } +} +if ( bzerror != BZ_STREAM_END ) { + BZ2_bzReadClose ( &bzerror, b ); + /* handle error */ +} else { + BZ2_bzReadClose ( &bzerror ); +} + + + + + + + + +Utility functions + + + +<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> + + +int BZ2_bzBuffToBuffCompress( char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int blockSize100k, + int verbosity, + int workFactor ); + + +Attempts to compress the data in source[0 +.. sourceLen-1] into the destination buffer, +dest[0 .. *destLen-1]. If the +destination buffer is big enough, +*destLen is set to the size of +the compressed data, and BZ_OK +is returned. If the compressed data won't fit, +*destLen is unchanged, and +BZ_OUTBUFF_FULL is +returned. + +Compression in this manner is a one-shot event, done with a +single call to this function. The resulting compressed data is a +complete bzip2 format data +stream. There is no mechanism for making additional calls to +provide extra input data. If you want that kind of mechanism, +use the low-level interface. + +For the meaning of parameters +blockSize100k, +verbosity and +workFactor, see +BZ2_bzCompressInit. + +To guarantee that the compressed data will fit in its +buffer, allocate an output buffer of size 1% larger than the +uncompressed data, plus six hundred extra bytes. + +BZ2_bzBuffToBuffDecompress +will not write data at or beyond +dest[*destLen], even in case of +buffer overflow. + +Possible return values: + + +BZ_CONFIG_ERROR + if the library has been mis-compiled +BZ_PARAM_ERROR + if dest is NULL or destLen is NULL + or blockSize100k < 1 or blockSize100k > 9 + or verbosity < 0 or verbosity > 4 + or workFactor < 0 or workFactor > 250 +BZ_MEM_ERROR + if insufficient memory is available +BZ_OUTBUFF_FULL + if the size of the compressed data exceeds *destLen +BZ_OK + otherwise + + + + + + +<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> + + +int BZ2_bzBuffToBuffDecompress( char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int small, + int verbosity ); + + +Attempts to decompress the data in source[0 +.. sourceLen-1] into the destination buffer, +dest[0 .. *destLen-1]. If the +destination buffer is big enough, +*destLen is set to the size of +the uncompressed data, and BZ_OK +is returned. If the compressed data won't fit, +*destLen is unchanged, and +BZ_OUTBUFF_FULL is +returned. + +source is assumed to hold +a complete bzip2 format data +stream. +BZ2_bzBuffToBuffDecompress tries +to decompress the entirety of the stream into the output +buffer. + +For the meaning of parameters +small and +verbosity, see +BZ2_bzDecompressInit. + +Because the compression ratio of the compressed data cannot +be known in advance, there is no easy way to guarantee that the +output buffer will be big enough. You may of course make +arrangements in your code to record the size of the uncompressed +data, but such a mechanism is beyond the scope of this +library. + +BZ2_bzBuffToBuffDecompress +will not write data at or beyond +dest[*destLen], even in case of +buffer overflow. + +Possible return values: + + +BZ_CONFIG_ERROR + if the library has been mis-compiled +BZ_PARAM_ERROR + if dest is NULL or destLen is NULL + or small != 0 && small != 1 + or verbosity < 0 or verbosity > 4 +BZ_MEM_ERROR + if insufficient memory is available +BZ_OUTBUFF_FULL + if the size of the compressed data exceeds *destLen +BZ_DATA_ERROR + if a data integrity error was detected in the compressed data +BZ_DATA_ERROR_MAGIC + if the compressed data doesn't begin with the right magic bytes +BZ_UNEXPECTED_EOF + if the compressed data ends unexpectedly +BZ_OK + otherwise + + + + + + + + +<computeroutput>zlib</computeroutput> compatibility functions + +Yoshioka Tsuneo has contributed some functions to give +better zlib compatibility. +These functions are BZ2_bzopen, +BZ2_bzread, +BZ2_bzwrite, +BZ2_bzflush, +BZ2_bzclose, +BZ2_bzerror and +BZ2_bzlibVersion. These +functions are not (yet) officially part of the library. If they +break, you get to keep all the pieces. Nevertheless, I think +they work ok. + + +typedef void BZFILE; + +const char * BZ2_bzlibVersion ( void ); + + +Returns a string indicating the library version. + + +BZFILE * BZ2_bzopen ( const char *path, const char *mode ); +BZFILE * BZ2_bzdopen ( int fd, const char *mode ); + + +Opens a .bz2 file for +reading or writing, using either its name or a pre-existing file +descriptor. Analogous to fopen +and fdopen. + + +int BZ2_bzread ( BZFILE* b, void* buf, int len ); +int BZ2_bzwrite ( BZFILE* b, void* buf, int len ); + + +Reads/writes data from/to a previously opened +BZFILE. Analogous to +fread and +fwrite. + + +int BZ2_bzflush ( BZFILE* b ); +void BZ2_bzclose ( BZFILE* b ); + + +Flushes/closes a BZFILE. +BZ2_bzflush doesn't actually do +anything. Analogous to fflush +and fclose. + + +const char * BZ2_bzerror ( BZFILE *b, int *errnum ) + + +Returns a string describing the more recent error status of +b, and also sets +*errnum to its numerical +value. + + + + + +Using the library in a <computeroutput>stdio</computeroutput>-free environment + + + +Getting rid of <computeroutput>stdio</computeroutput> + +In a deeply embedded application, you might want to use +just the memory-to-memory functions. You can do this +conveniently by compiling the library with preprocessor symbol +BZ_NO_STDIO defined. Doing this +gives you a library containing only the following eight +functions: + +BZ2_bzCompressInit, +BZ2_bzCompress, +BZ2_bzCompressEnd +BZ2_bzDecompressInit, +BZ2_bzDecompress, +BZ2_bzDecompressEnd +BZ2_bzBuffToBuffCompress, +BZ2_bzBuffToBuffDecompress + +When compiled like this, all functions will ignore +verbosity settings. + + + + + +Critical error handling + +libbzip2 contains a number +of internal assertion checks which should, needless to say, never +be activated. Nevertheless, if an assertion should fail, +behaviour depends on whether or not the library was compiled with +BZ_NO_STDIO set. + +For a normal compile, an assertion failure yields the +message: + +
+bzip2/libbzip2: internal error number N. +This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;. +Please report it to me at: &bz-email;. If this happened +when you were using some program which uses libbzip2 as a +component, you should also report this bug to the author(s) +of that program. Please make an effort to report this bug; +timely and accurate bug reports eventually lead to higher +quality software. Thanks. Julian Seward, &bz-date;. +
+ +where N is some error code +number. If N == 1007, it also +prints some extra text advising the reader that unreliable memory +is often associated with internal error 1007. (This is a +frequently-observed-phenomenon with versions 1.0.0/1.0.1). + +exit(3) is then +called. + +For a stdio-free library, +assertion failures result in a call to a function declared +as: + + +extern void bz_internal_error ( int errcode ); + + +The relevant code is passed as a parameter. You should +supply such a function. + +In either case, once an assertion failure has occurred, any +bz_stream records involved can +be regarded as invalid. You should not attempt to resume normal +operation with them. + +You may, of course, change critical error handling to suit +your needs. As I said above, critical errors indicate bugs in +the library and should not occur. All "normal" error situations +are indicated via error return codes from functions, and can be +recovered from. + +
+ +
+ + + +Making a Windows DLL + +Everything related to Windows has been contributed by +Yoshioka Tsuneo +(QWF00133@niftyserve.or.jp / +tsuneo-y@is.aist-nara.ac.jp), so +you should send your queries to him (but perhaps Cc: me, +&bz-email;). + +My vague understanding of what to do is: using Visual C++ +5.0, open the project file +libbz2.dsp, and build. That's +all. + +If you can't open the project file for some reason, make a +new one, naming these files: +blocksort.c, +bzlib.c, +compress.c, +crctable.c, +decompress.c, +huffman.c, +randtable.c and +libbz2.def. You will also need +to name the header files bzlib.h +and bzlib_private.h. + +If you don't use VC++, you may need to define the +proprocessor symbol +_WIN32. + +Finally, dlltest.c is a +sample program using the DLL. It has a project file, +dlltest.dsp. + +If you just want a makefile for Visual C, have a look at +makefile.msc. + +Be aware that if you compile +bzip2 itself on Win32, you must +set BZ_UNIX to 0 and +BZ_LCCWIN32 to 1, in the file +bzip2.c, before compiling. +Otherwise the resulting binary won't work correctly. + +I haven't tried any of this stuff myself, but it all looks +plausible. + + + +
+ + + + +Miscellanea + +These are just some random thoughts of mine. Your mileage +may vary. + + + +Limitations of the compressed file format + +bzip2-1.0.X, +0.9.5 and +0.9.0 use exactly the same file +format as the original version, +bzip2-0.1. This decision was +made in the interests of stability. Creating yet another +incompatible compressed file format would create further +confusion and disruption for users. + +Nevertheless, this is not a painless decision. Development +work since the release of +bzip2-0.1 in August 1997 has +shown complexities in the file format which slow down +decompression and, in retrospect, are unnecessary. These +are: + + + + The run-length encoder, which is the first of the + compression transformations, is entirely irrelevant. The + original purpose was to protect the sorting algorithm from the + very worst case input: a string of repeated symbols. But + algorithm steps Q6a and Q6b in the original Burrows-Wheeler + technical report (SRC-124) show how repeats can be handled + without difficulty in block sorting. + + The randomisation mechanism doesn't really need to be + there. Udi Manber and Gene Myers published a suffix array + construction algorithm a few years back, which can be employed + to sort any block, no matter how repetitive, in O(N log N) + time. Subsequent work by Kunihiko Sadakane has produced a + derivative O(N (log N)^2) algorithm which usually outperforms + the Manber-Myers algorithm. + + I could have changed to Sadakane's algorithm, but I find + it to be slower than bzip2's + existing algorithm for most inputs, and the randomisation + mechanism protects adequately against bad cases. I didn't + think it was a good tradeoff to make. Partly this is due to + the fact that I was not flooded with email complaints about + bzip2-0.1's performance on + repetitive data, so perhaps it isn't a problem for real + inputs. + + Probably the best long-term solution, and the one I have + incorporated into 0.9.5 and above, is to use the existing + sorting algorithm initially, and fall back to a O(N (log N)^2) + algorithm if the standard algorithm gets into + difficulties. + + The compressed file format was never designed to be + handled by a library, and I have had to jump though some hoops + to produce an efficient implementation of decompression. It's + a bit hairy. Try passing + decompress.c through the C + preprocessor and you'll see what I mean. Much of this + complexity could have been avoided if the compressed size of + each block of data was recorded in the data stream. + + An Adler-32 checksum, rather than a CRC32 checksum, + would be faster to compute. + + + +It would be fair to say that the +bzip2 format was frozen before I +properly and fully understood the performance consequences of +doing so. + +Improvements which I was able to incorporate into 0.9.0, +despite using the same file format, are: + + + + Single array implementation of the inverse BWT. This + significantly speeds up decompression, presumably because it + reduces the number of cache misses. + + Faster inverse MTF transform for large MTF values. + The new implementation is based on the notion of sliding blocks + of values. + + bzip2-0.9.0 now reads + and writes files with fread + and fwrite; version 0.1 used + putc and + getc. Duh! Well, you live + and learn. + + + +Further ahead, it would be nice to be able to do random +access into files. This will require some careful design of +compressed file formats. + + + + + +Portability issues + +After some consideration, I have decided not to use GNU +autoconf to configure 0.9.5 or +1.0. + +autoconf, admirable and +wonderful though it is, mainly assists with portability problems +between Unix-like platforms. But +bzip2 doesn't have much in the +way of portability problems on Unix; most of the difficulties +appear when porting to the Mac, or to Microsoft's operating +systems. autoconf doesn't help +in those cases, and brings in a whole load of new +complexity. + +Most people should be able to compile the library and +program under Unix straight out-of-the-box, so to speak, +especially if you have a version of GNU C available. + +There are a couple of +__inline__ directives in the +code. GNU C (gcc) should be +able to handle them. If you're not using GNU C, your C compiler +shouldn't see them at all. If your compiler does, for some +reason, see them and doesn't like them, just +#define +__inline__ to be +/* */. One easy way to do this +is to compile with the flag +-D__inline__=, which should be +understood by most Unix compilers. + +If you still have difficulties, try compiling with the +macro BZ_STRICT_ANSI defined. +This should enable you to build the library in a strictly ANSI +compliant environment. Building the program itself like this is +dangerous and not supported, since you remove +bzip2's checks against +compressing directories, symbolic links, devices, and other +not-really-a-file entities. This could cause filesystem +corruption! + +One other thing: if you create a +bzip2 binary for public distribution, +please consider linking it statically (gcc +-static). This avoids all sorts of library-version +issues that others may encounter later on. + +If you build bzip2 on +Win32, you must set BZ_UNIX to 0 +and BZ_LCCWIN32 to 1, in the +file bzip2.c, before compiling. +Otherwise the resulting binary won't work correctly. + + + + + +Reporting bugs + +I tried pretty hard to make sure +bzip2 is bug free, both by +design and by testing. Hopefully you'll never need to read this +section for real. + +Nevertheless, if bzip2 dies +with a segmentation fault, a bus error or an internal assertion +failure, it will ask you to email me a bug report. Experience from +years of feedback of bzip2 users indicates that almost all these +problems can be traced to either compiler bugs or hardware +problems. + + + + Recompile the program with no optimisation, and + see if it works. And/or try a different compiler. I heard all + sorts of stories about various flavours of GNU C (and other + compilers) generating bad code for + bzip2, and I've run across two + such examples myself. + + 2.7.X versions of GNU C are known to generate bad code + from time to time, at high optimisation levels. If you get + problems, try using the flags + -O2 + -fomit-frame-pointer + -fno-strength-reduce. You + should specifically not use + -funroll-loops. + + You may notice that the Makefile runs six tests as part + of the build process. If the program passes all of these, it's + a pretty good (but not 100%) indication that the compiler has + done its job correctly. + + If bzip2 + crashes randomly, and the crashes are not repeatable, you may + have a flaky memory subsystem. + bzip2 really hammers your + memory hierarchy, and if it's a bit marginal, you may get these + problems. Ditto if your disk or I/O subsystem is slowly + failing. Yup, this really does happen. + + Try using a different machine of the same type, and see + if you can repeat the problem. + + This isn't really a bug, but ... If + bzip2 tells you your file is + corrupted on decompression, and you obtained the file via FTP, + there is a possibility that you forgot to tell FTP to do a + binary mode transfer. That absolutely will cause the file to + be non-decompressible. You'll have to transfer it + again. + + + +If you've incorporated +libbzip2 into your own program +and are getting problems, please, please, please, check that the +parameters you are passing in calls to the library, are correct, +and in accordance with what the documentation says is allowable. +I have tried to make the library robust against such problems, +but I'm sure I haven't succeeded. + +Finally, if the above comments don't help, you'll have to +send me a bug report. Now, it's just amazing how many people +will send me a bug report saying something like: + + +bzip2 crashed with segmentation fault on my machine + + +and absolutely nothing else. Needless to say, a such a +report is totally, utterly, completely and +comprehensively 100% useless; a waste of your time, my time, and +net bandwidth. With no details at all, there's no way +I can possibly begin to figure out what the problem is. + +The rules of the game are: facts, facts, facts. Don't omit +them because "oh, they won't be relevant". At the bare +minimum: + + +Machine type. Operating system version. +Exact version of bzip2 (do bzip2 -V). +Exact version of the compiler used. +Flags passed to the compiler. + + +However, the most important single thing that will help me +is the file that you were trying to compress or decompress at the +time the problem happened. Without that, my ability to do +anything more than speculate about the cause, is limited. + + + + + +Did you get the right package? + +bzip2 is a resource hog. +It soaks up large amounts of CPU cycles and memory. Also, it +gives very large latencies. In the worst case, you can feed many +megabytes of uncompressed data into the library before getting +any compressed output, so this probably rules out applications +requiring interactive behaviour. + +These aren't faults of my implementation, I hope, but more +an intrinsic property of the Burrows-Wheeler transform +(unfortunately). Maybe this isn't what you want. + +If you want a compressor and/or library which is faster, +uses less memory but gets pretty good compression, and has +minimal latency, consider Jean-loup Gailly's and Mark Adler's +work, zlib-1.2.1 and +gzip-1.2.4. Look for them at +http://www.zlib.org and +http://www.gzip.org +respectively. + +For something faster and lighter still, you might try Markus F +X J Oberhumer's LZO real-time +compression/decompression library, at +http://www.oberhumer.com/opensource. + + + + + + +Further Reading + +bzip2 is not research +work, in the sense that it doesn't present any new ideas. +Rather, it's an engineering exercise based on existing +ideas. + +Four documents describe essentially all the ideas behind +bzip2: + +Michael Burrows and D. J. Wheeler: + "A block-sorting lossless data compression algorithm" + 10th May 1994. + Digital SRC Research Report 124. + ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz + If you have trouble finding it, try searching at the + New Zealand Digital Library, http://www.nzdl.org. + +Daniel S. Hirschberg and Debra A. LeLewer + "Efficient Decoding of Prefix Codes" + Communications of the ACM, April 1990, Vol 33, Number 4. + You might be able to get an electronic copy of this + from the ACM Digital Library. + +David J. Wheeler + Program bred3.c and accompanying document bred3.ps. + This contains the idea behind the multi-table Huffman coding scheme. + ftp://ftp.cl.cam.ac.uk/users/djw3/ + +Jon L. Bentley and Robert Sedgewick + "Fast Algorithms for Sorting and Searching Strings" + Available from Sedgewick's web page, + www.cs.princeton.edu/~rs + + +The following paper gives valuable additional insights into +the algorithm, but is not immediately the basis of any code used +in bzip2. + +Peter Fenwick: + Block Sorting Text Compression + Proceedings of the 19th Australasian Computer Science Conference, + Melbourne, Australia. Jan 31 - Feb 2, 1996. + ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps + +Kunihiko Sadakane's sorting algorithm, mentioned above, is +available from: + +http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz + + +The Manber-Myers suffix array construction algorithm is +described in a paper available from: + +http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps + + +Finally, the following papers document some +investigations I made into the performance of sorting +and decompression algorithms: + +Julian Seward + On the Performance of BWT Sorting Algorithms + Proceedings of the IEEE Data Compression Conference 2000 + Snowbird, Utah. 28-30 March 2000. + +Julian Seward + Space-time Tradeoffs in the Inverse B-W Transform + Proceedings of the IEEE Data Compression Conference 2001 + Snowbird, Utah. 27-29 March 2001. + + + + + + +
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c b/contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c new file mode 100644 index 000000000..205778a84 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c @@ -0,0 +1,16 @@ + +/* Spew out a long sequence of the byte 251. When fed to bzip2 + versions 1.0.0 or 1.0.1, causes it to die with internal error + 1007 in blocksort.c. This assertion misses an extremely rare + case, which is fixed in this version (1.0.2) and above. +*/ + +#include + +int main () +{ + int i; + for (i = 0; i < 48500000 ; i++) + putchar(251); + return 0; +} diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/randtable.c b/contrib/vmap_extractor_v2/stormlib/bzip2/randtable.c new file mode 100644 index 000000000..940462d69 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/randtable.c @@ -0,0 +1,124 @@ + +/*-------------------------------------------------------------*/ +/*--- Table for randomising repetitive blocks ---*/ +/*--- randtable.c ---*/ +/*-------------------------------------------------------------*/ + +/*-- + This file is a part of bzip2 and/or libbzip2, a program and + library for lossless, block-sorting data compression. + + Copyright (C) 1996-2005 Julian R Seward. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Julian Seward, Cambridge, UK. + jseward@bzip.org + bzip2/libbzip2 version 1.0 of 21 March 2000 + + This program is based on (at least) the work of: + Mike Burrows + David Wheeler + Peter Fenwick + Alistair Moffat + Radford Neal + Ian H. Witten + Robert Sedgewick + Jon L. Bentley + + For more information on these sources, see the manual. +--*/ + + +#include "bzlib_private.h" + + +/*---------------------------------------------*/ +Int32 BZ2_rNums[512] = { + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, + 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, + 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, + 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, + 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, + 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, + 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, + 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, + 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, + 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, + 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, + 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, + 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, + 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, + 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, + 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, + 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, + 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, + 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, + 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, + 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, + 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, + 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, + 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, + 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, + 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, + 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, + 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, + 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, + 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, + 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, + 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, + 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, + 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, + 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 +}; + + +/*-------------------------------------------------------------*/ +/*--- end randtable.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2 b/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2 new file mode 100644 index 000000000..18dea6004 Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2 differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.ref b/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.ref new file mode 100644 index 000000000..a56e52b77 Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.ref differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2 b/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2 new file mode 100644 index 000000000..d5a6160ba Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2 differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.ref b/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.ref new file mode 100644 index 000000000..34af95839 Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.ref differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2 b/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2 new file mode 100644 index 000000000..d90cff920 Binary files /dev/null and b/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2 differ diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref b/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref new file mode 100644 index 000000000..775a2f68e --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref @@ -0,0 +1,30007 @@ +This file is exceedingly boring. If you find yourself +reading it, please (1) take it from me that you can safely +guess what the rest of the file says, and (2) seek professional +help. + +ps. there are no further sarcastic remarks in this file. + +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh +ugh diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c b/contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c new file mode 100644 index 000000000..7934e7658 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c @@ -0,0 +1,39 @@ + +/* spew out a thoroughly gigantic file designed so that bzip2 + can compress it reasonably rapidly. This is to help test + support for large files (> 2GB) in a reasonable amount of time. + I suggest you use the undocumented --exponential option to + bzip2 when compressing the resulting file; this saves a bit of + time. Note: *don't* bother with --exponential when compressing + Real Files; it'll just waste a lot of CPU time :-) + (but is otherwise harmless). +*/ + +#define _FILE_OFFSET_BITS 64 + +#include +#include + +/* The number of megabytes of junk to spew out (roughly) */ +#define MEGABYTES 5000 + +#define N_BUF 1000000 +char buf[N_BUF]; + +int main ( int argc, char** argv ) +{ + int ii, kk, p; + srandom(1); + setbuffer ( stdout, buf, N_BUF ); + for (kk = 0; kk < MEGABYTES * 515; kk+=3) { + p = 25+random()%50; + for (ii = 0; ii < p; ii++) + printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); + for (ii = 0; ii < p-1; ii++) + printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ); + for (ii = 0; ii < p+1; ii++) + printf ( "ccccccccccccccccccccccccccccccccccccc" ); + } + fflush(stdout); + return 0; +} diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c b/contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c new file mode 100644 index 000000000..f0f17fcca --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c @@ -0,0 +1,126 @@ + +/* A test program written to test robustness to decompression of + corrupted data. Usage is + unzcrash filename + and the program will read the specified file, compress it (in memory), + and then repeatedly decompress it, each time with a different bit of + the compressed data inverted, so as to test all possible one-bit errors. + This should not cause any invalid memory accesses. If it does, + I want to know about it! + + p.s. As you can see from the above description, the process is + incredibly slow. A file of size eg 5KB will cause it to run for + many hours. +*/ + +#include +#include +#include "bzlib.h" + +#define M_BLOCK 1000000 + +typedef unsigned char uchar; + +#define M_BLOCK_OUT (M_BLOCK + 1000000) +uchar inbuf[M_BLOCK]; +uchar outbuf[M_BLOCK_OUT]; +uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)]; + +int nIn, nOut, nZ; + +static char *bzerrorstrings[] = { + "OK" + ,"SEQUENCE_ERROR" + ,"PARAM_ERROR" + ,"MEM_ERROR" + ,"DATA_ERROR" + ,"DATA_ERROR_MAGIC" + ,"IO_ERROR" + ,"UNEXPECTED_EOF" + ,"OUTBUFF_FULL" + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ +}; + +void flip_bit ( int bit ) +{ + int byteno = bit / 8; + int bitno = bit % 8; + uchar mask = 1 << bitno; + //fprintf ( stderr, "(byte %d bit %d mask %d)", + // byteno, bitno, (int)mask ); + zbuf[byteno] ^= mask; +} + +int main ( int argc, char** argv ) +{ + FILE* f; + int r; + int bit; + int i; + + if (argc != 2) { + fprintf ( stderr, "usage: unzcrash filename\n" ); + return 1; + } + + f = fopen ( argv[1], "r" ); + if (!f) { + fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] ); + return 1; + } + + nIn = fread ( inbuf, 1, M_BLOCK, f ); + fprintf ( stderr, "%d bytes read\n", nIn ); + + nZ = M_BLOCK; + r = BZ2_bzBuffToBuffCompress ( + zbuf, &nZ, inbuf, nIn, 9, 0, 30 ); + + assert (r == BZ_OK); + fprintf ( stderr, "%d after compression\n", nZ ); + + for (bit = 0; bit < nZ*8; bit++) { + fprintf ( stderr, "bit %d ", bit ); + flip_bit ( bit ); + nOut = M_BLOCK_OUT; + r = BZ2_bzBuffToBuffDecompress ( + outbuf, &nOut, zbuf, nZ, 0, 0 ); + fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] ); + + if (r != BZ_OK) { + fprintf ( stderr, "\n" ); + } else { + if (nOut != nIn) { + fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut ); + return 1; + } else { + for (i = 0; i < nOut; i++) + if (inbuf[i] != outbuf[i]) { + fprintf(stderr, "mismatch at %d\n", i ); + return 1; + } + if (i == nOut) fprintf(stderr, "really ok!\n" ); + } + } + + flip_bit ( bit ); + } + +#if 0 + assert (nOut == nIn); + for (i = 0; i < nOut; i++) { + if (inbuf[i] != outbuf[i]) { + fprintf ( stderr, "difference at %d !\n", i ); + return 1; + } + } +#endif + + fprintf ( stderr, "all ok\n" ); + return 0; +} diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words0 b/contrib/vmap_extractor_v2/stormlib/bzip2/words0 new file mode 100644 index 000000000..164a8ed28 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/words0 @@ -0,0 +1,5 @@ + +If compilation produces errors, or a large number of warnings, +please read README.COMPILATION.PROBLEMS -- you might be able to +adjust the flags in this Makefile to improve matters. + diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words1 b/contrib/vmap_extractor_v2/stormlib/bzip2/words1 new file mode 100644 index 000000000..2e83de9f0 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/words1 @@ -0,0 +1,4 @@ + +Doing 6 tests (3 compress, 3 uncompress) ... +If there's a problem, things might stop at this point. + diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words2 b/contrib/vmap_extractor_v2/stormlib/bzip2/words2 new file mode 100644 index 000000000..203ee39c4 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/words2 @@ -0,0 +1,5 @@ + +Checking test results. If any of the four "cmp"s which follow +report any differences, something is wrong. If you can't easily +figure out what, please let me know (jseward@acm.org). + diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words3 b/contrib/vmap_extractor_v2/stormlib/bzip2/words3 new file mode 100644 index 000000000..7a6b46244 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/words3 @@ -0,0 +1,23 @@ + +If you got this far and the "cmp"s didn't complain, it looks +like you're in business. + +To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type + make install +To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type + make install PREFIX=/xxx/yyy +If you are (justifiably) paranoid and want to see what 'make install' +is going to do, you can first do + make -n install or + make -n install PREFIX=/xxx/yyy respectively. +The -n instructs make to show the commands it would execute, but +not actually execute them. + +Instructions for use are in the preformatted manual page, in the file +bzip2.txt. For more detailed documentation, read the full manual. +It is available in Postscript form (manual.ps), PDF form (manual.pdf), +and HTML form (manual_toc.html). + +You can also do "bzip2 --help" to see some helpful information. +"bzip2 -L" displays the software license. + diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh b/contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh new file mode 100644 index 000000000..6fe4d5748 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# see the README in this directory for usage etc. + +usage() { + echo ''; + echo 'Usage: xmlproc.sh -[option] '; + echo 'Specify a target from:'; + echo '-v verify xml file conforms to dtd'; + echo '-html output in html format (single file)'; + echo '-ps output in postscript format'; + echo '-pdf output in pdf format'; + exit; +} + +if test $# -ne 2; then + usage +fi +# assign the variable for the output type +action=$1; shift +# assign the output filename +xmlfile=$1; shift +# and check user input it correct +if !(test -f $xmlfile); then + echo "No such file: $xmlfile"; + exit; +fi +# some other stuff we will use +OUT=output +xsl_fo=bz-fo.xsl +xsl_html=bz-html.xsl + +basename=$xmlfile +basename=${basename//'.xml'/''} + +fofile="${basename}.fo" +htmlfile="${basename}.html" +pdffile="${basename}.pdf" +psfile="${basename}.ps" +xmlfmtfile="${basename}.fmt" + +# first process the xmlfile with CDATA tags +./format.pl $xmlfile $xmlfmtfile +# so the shell knows where the catalogs live +export XML_CATALOG_FILES=/etc/xml/catalog + +# post-processing tidy up +cleanup() { + echo "Cleaning up: # $@" + while [ $# != 0 ] + do + arg=$1; shift; + echo " deleting $arg"; + rm $arg + done +} + +case $action in + -v) + flags='--noout --xinclude --noblanks --postvalid' + dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd' + xmllint $flags $dtd $xmlfmtfile 2> $OUT + egrep 'error' $OUT + rm $OUT + ;; + + -html) + echo "Creating $htmlfile ..." + xsltproc --nonet --xinclude -o $htmlfile $xsl_html $xmlfmtfile + cleanup $xmlfmtfile + ;; + + -pdf) + echo "Creating $pdffile ..." + xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile + pdfxmltex $fofile >$OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT 0x80000000) */ +/*****************************************************************************/ + +#include +#include + +#include "huff.h" + +// Special for Mac - we have to know if normal pointer greater or less +// than 0x80000000. This variable is used in the PTR_VALID and PTR_INVALID +// macros +static long mul = 1; + +#define PTR_VALID(ptr) (((LONG_PTR)(ptr) * mul) > 0) +#define PTR_INVALID(ptr) (((LONG_PTR)(ptr) * mul) < 0) +#define PTR_INVALID_OR_NULL(ptr) (((LONG_PTR)(ptr) * mul) <= 0) + + +//----------------------------------------------------------------------------- +// Methods of the THTreeItem struct + +// 1501DB70 +THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast) +{ + if(pLast == NULL) + pLast = this + 1; + return pLast; +} + +// Gets previous Huffman tree item (?) +THTreeItem * THTreeItem::GetPrevItem(LONG_PTR value) +{ + if(PTR_INVALID(prev)) + return PTR_NOT(prev); + + if(value == -1 || PTR_INVALID(value)) + value = (long)(this - next->prev); + return prev + value; + +// OLD VERSION +// if(PTR_INT(value) < 0) +// value = PTR_INT((item - item->next->prev)); +// return (THTreeItem *)((char *)prev + value); +} + +// 1500F5E0 +void THTreeItem::ClearItemLinks() +{ + next = prev = NULL; +} + +// 1500BC90 +void THTreeItem::RemoveItem() +{ + THTreeItem * pTemp; // EDX + + if(next != NULL) + { + pTemp = prev; + + if(PTR_INVALID_OR_NULL(pTemp)) + pTemp = PTR_NOT(pTemp); + else + pTemp += (this - next->prev); + + pTemp->next = next; + next->prev = prev; + next = prev = NULL; + } +} + +/* +// OLD VERSION : Removes item from the tree (?) +static void RemoveItem(THTreeItem * item) +{ + THTreeItem * next = item->next; // ESI + THTreeItem * prev = item->prev; // EDX + + if(next == NULL) + return; + + if(PTR_INT(prev) < 0) + prev = PTR_NOT(prev); + else + // ??? usually item == next->prev, so what is it ? + prev = (THTreeItem *)((unsigned char *)prev + (unsigned long)((unsigned char *)item - (unsigned char *)(next->prev))); + + // Remove HTree item from the chain + prev->next = next; // Sets the 'first' pointer + next->prev = item->prev; + + // Invalidate pointers + item->next = NULL; + item->prev = NULL; +} +*/ + +//----------------------------------------------------------------------------- +// TOutputStream functions + +void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits) +{ + dwBitBuff |= (dwBuff << nBits); + nBits += nPutBits; + + // Flush completed bytes + while(nBits >= 8) + { + if(dwOutSize != 0) + { + *pbOutPos++ = (unsigned char)dwBitBuff; + dwOutSize--; + } + + dwBitBuff >>= 8; + nBits -= 8; + } +} + +//----------------------------------------------------------------------------- +// TInputStream functions + +// Gets one bit from input stream +unsigned long TInputStream::GetBit() +{ + unsigned long dwBit = (dwBitBuff & 1); + + dwBitBuff >>= 1; + if(--nBits == 0) + { + dwBitBuff = BSWAP_INT32_UNSIGNED(*(unsigned long *)pbInBuffer); + pbInBuffer += sizeof(unsigned long); + nBits = 32; + } + return dwBit; +} + +// Gets 7 bits from the stream +unsigned long TInputStream::Get7Bits() +{ + if(nBits <= 7) + { + dwBitBuff |= BSWAP_INT16_UNSIGNED(*(unsigned short *)pbInBuffer) << nBits; + pbInBuffer += sizeof(unsigned short); + nBits += 16; + } + + // Get 7 bits from input stream + return (dwBitBuff & 0x7F); +} + +// Gets the whole byte from the input stream. +unsigned long TInputStream::Get8Bits() +{ + unsigned long dwOneByte; + + if(nBits <= 8) + { + dwBitBuff |= BSWAP_INT16_UNSIGNED(*(unsigned short *)pbInBuffer) << nBits; + pbInBuffer += sizeof(unsigned short); + nBits += 16; + } + + dwOneByte = (dwBitBuff & 0xFF); + dwBitBuff >>= 8; + nBits -= 8; + return dwOneByte; +} + +//----------------------------------------------------------------------------- +// Functions for huffmann tree items + +// Inserts item into the tree (?) +static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long where, THTreeItem * item2) +{ + THTreeItem * next = item->next; // EDI - next to the first item + THTreeItem * prev = item->prev; // ESI - prev to the first item + THTreeItem * prev2; // Pointer to previous item + LONG_PTR next2; // Pointer to the next item + + // The same code like in RemoveItem(item); + if(next != 0) // If the first item already has next one + { + if(PTR_INVALID(prev)) + prev = PTR_NOT(prev); + else + prev += (item - next->prev); + + // 150083C1 + // Remove the item from the tree + prev->next = next; + next->prev = prev; + + // Invalidate 'prev' and 'next' pointer + item->next = 0; + item->prev = 0; + } + + if(item2 == NULL) // EDX - If the second item is not entered, + item2 = PTR_PTR(&itemPtr[1]); // take the first tree item + + switch(where) + { + case SWITCH_ITEMS : // Switch the two items + item->next = item2->next; // item2->next (Pointer to pointer to first) + item->prev = item2->next->prev; + item2->next->prev = item; + item2->next = item; // Set the first item + return; + + case INSERT_ITEM: // Insert as the last item + item->next = item2; // Set next item (or pointer to pointer to first item) + item->prev = item2->prev; // Set prev item (or last item in the tree) + + next2 = PTR_INT(itemPtr[0]);// Usually NULL + prev2 = item2->prev; // Prev item to the second (or last tree item) + + if(PTR_INVALID(prev2)) + { + prev2 = PTR_NOT(prev); + + prev2->next = item; + item2->prev = item; // Next after last item + return; + } + + if(PTR_INVALID(next2)) + next2 = (long)(item2 - item2->next->prev); +// next2 = (THTreeItem *)(unsigned long)((unsigned char *)item2 - (unsigned char *)(item2->next->prev)); + +// prev2 = (THTreeItem *)((char *)prev2 + (unsigned long)next2);// ??? + prev2 += next2; + prev2->next = item; + item2->prev = item; // Set the next/last item + return; + + default: + return; + } +} + +//----------------------------------------------------------------------------- +// THuffmannTree class functions + +THuffmannTree::THuffmannTree() +{ + // We have to check if the "this" pointer is less than zero + if((LONG_PTR)this < 0) + mul = -1; +} + +void THuffmannTree::InitTree(bool bCompression) +{ + THTreeItem * pItem; + unsigned int nCount; + + // Clear links for all the items in the tree + for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--) + pItem->ClearItemLinks(); + + pItem3050 = NULL; + pItem3054 = PTR_PTR(&pItem3054); + pItem3058 = PTR_NOT(pItem3054); + + pItem305C = NULL; + pFirst = PTR_PTR(&pFirst); + pLast = PTR_NOT(pFirst); + + offs0004 = 1; + nItems = 0; + + // Clear all TQDecompress items. Do this only if preparing for decompression + if(bCompression == false) + { + for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++) + qd3474[nCount].offs00 = 0; + } +} + +// Builds Huffman tree. Called with the first 8 bits loaded from input stream +void THuffmannTree::BuildTree(unsigned int nCmpType) +{ + unsigned long maxByte; // [ESP+10] - The greatest character found in table + THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array + unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630 + THTreeItem * child1; + unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i + + // Loop while pointer has a valid value + while(PTR_VALID(pLast)) // ESI - Last entry + { + THTreeItem * temp; // EAX + + if(pLast->next != NULL) // ESI->next + pLast->RemoveItem(); + // EDI = &offs3054 + pItem3058 = PTR_PTR(&pItem3054);// [EDI+4] + pLast->prev = pItem3058; // EAX + + temp = PTR_PTR(&pItem3054)->GetPrevItem(PTR_INT(&pItem3050)); + + temp->next = pLast; + pItem3054 = pLast; + } + + // Clear all pointers in HTree item array + memset(items306C, 0, sizeof(items306C)); + + maxByte = 0; // Greatest character found init to zero. + itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array + + // Ensure we have low 8 bits only + nCmpType &= 0xFF; + byteArray = Table1502A630 + nCmpType * 258; // EDI also + + for(i = 0; i < 0x100; i++, itemPtr++) + { + THTreeItem * item = pItem3058; // Item to be created + THTreeItem * pItem3 = pItem3058; + unsigned char oneByte = byteArray[i]; + + // Skip all the bytes which are zero. + if(byteArray[i] == 0) + continue; + + // If not valid pointer, take the first available item in the array + if(PTR_INVALID_OR_NULL(item)) + item = &items0008[nItems++]; + + // Insert this item as the top of the tree + InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL); + + item->parent = NULL; // Invalidate child and parent + item->child = NULL; + *itemPtr = item; // Store pointer into pointer array + + item->dcmpByte = i; // Store counter + item->byteValue = oneByte; // Store byte value + if(oneByte >= maxByte) + { + maxByte = oneByte; + continue; + } + + // Find the first item which has byte value greater than current one byte + if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item + { + // 15006AF7 + if(pItem3 != NULL) + { + do // 15006AFB + { + if(pItem3->byteValue >= oneByte) + goto _15006B09; + pItem3 = pItem3->prev; + } + while(PTR_VALID(pItem3)); + } + } + pItem3 = NULL; + + // 15006B09 + _15006B09: + if(item->next != NULL) + item->RemoveItem(); + + // 15006B15 + if(pItem3 == NULL) + pItem3 = PTR_PTR(&pFirst); + + // 15006B1F + item->next = pItem3->next; + item->prev = pItem3->next->prev; + pItem3->next->prev = item; + pItem3->next = item; + } + + // 15006B4A + for(; i < 0x102; i++) + { + THTreeItem ** itemPtr = &items306C[i]; // EDI + + // 15006B59 + THTreeItem * item = pItem3058; // ESI + if(PTR_INVALID_OR_NULL(item)) + item = &items0008[nItems++]; + + InsertItem(&pItem305C, item, INSERT_ITEM, NULL); + + // 15006B89 + item->dcmpByte = i; + item->byteValue = 1; + item->parent = NULL; + item->child = NULL; + *itemPtr++ = item; + } + + // 15006BAA + if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item + { + THTreeItem * child2; // EBP + THTreeItem * item; // ESI + + // 15006BB8 + while(PTR_VALID(child2 = child1->prev)) + { + if(PTR_INVALID_OR_NULL(item = pItem3058)) + item = &items0008[nItems++]; + + // 15006BE3 + InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL); + + // 15006BF3 + item->parent = NULL; + item->child = NULL; + + //EDX = child2->byteValue + child1->byteValue; + //EAX = child1->byteValue; + //ECX = maxByte; // The greatest character (0xFF usually) + + item->byteValue = child1->byteValue + child2->byteValue; // 0x02 + item->child = child1; // Prev item in the + child1->parent = item; + child2->parent = item; + + // EAX = item->byteValue; + if(item->byteValue >= maxByte) + maxByte = item->byteValue; + else + { + THTreeItem * pItem2 = child2->prev; // EDI + + // 15006C2D + while(PTR_VALID(pItem2)) + { + if(pItem2->byteValue >= item->byteValue) + goto _15006C3B; + pItem2 = pItem2->prev; + } + pItem2 = NULL; + + _15006C3B: + if(item->next != 0) + { + THTreeItem * temp4 = item->GetPrevItem(-1); + + temp4->next = item->next; // The first item changed + item->next->prev = item->prev; // First->prev changed to negative value + item->next = NULL; + item->prev = NULL; + } + + // 15006C62 + if(pItem2 == NULL) + pItem2 = PTR_PTR(&pFirst); + + item->next = pItem2->next; // Set item with 0x100 byte value + item->prev = pItem2->next->prev; // Set item with 0x17 byte value + pItem2->next->prev = item; // Changed prev of item with + pItem2->next = item; + } + + // 15006C7B + if(PTR_INVALID_OR_NULL(child1 = child2->prev)) + break; + } + } + // 15006C88 + offs0004 = 1; +} +/* +// Modifies Huffman tree. Adds new item and changes +void THuffmannTree::ModifyTree(unsigned long dwIndex) +{ + THTreeItem * pItem1 = pItem3058; // ESI + THTreeItem * pSaveLast = (PTR_INT(pLast) <= 0) ? NULL : pLast; // EBX + THTreeItem * temp; // EAX + + // Prepare the first item to insert to the tree + if(PTR_INT(pItem1) <= 0) + pItem1 = &items0008[nItems++]; + + // If item has any next item, remove it from the chain + if(pItem1->next != NULL) + { + THTreeItem * temp = pItem1->GetPrevItem(-1); // EAX + + temp->next = pItem1->next; + pItem1->next->prev = pItem1->prev; + pItem1->next = NULL; + pItem1->prev = NULL; + } + + pItem1->next = PTR_PTR(&pFirst); + pItem1->prev = pLast; + temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C)); + + // 150068E9 + temp->next = pItem1; + pLast = pItem1; + + pItem1->parent = NULL; + pItem1->child = NULL; + + // 150068F6 + pItem1->dcmpByte = pSaveLast->dcmpByte; // Copy item index + pItem1->byteValue = pSaveLast->byteValue; // Copy item byte value + pItem1->parent = pSaveLast; // Set parent to last item + items306C[pSaveLast->dcmpByte] = pItem1; // Insert item into item pointer array + + // Prepare the second item to insert into the tree + if(PTR_INT((pItem1 = pItem3058)) <= 0) + pItem1 = &items0008[nItems++]; + + // 1500692E + if(pItem1->next != NULL) + { + temp = pItem1->GetPrevItem(-1); // EAX + + temp->next = pItem1->next; + pItem1->next->prev = pItem1->prev; + pItem1->next = NULL; + pItem1->prev = NULL; + } + // 1500694C + pItem1->next = PTR_PTR(&pFirst); + pItem1->prev = pLast; + temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C)); + + // 15006968 + temp->next = pItem1; + pLast = pItem1; + + // 1500696E + pItem1->child = NULL; + pItem1->dcmpByte = dwIndex; + pItem1->byteValue = 0; + pItem1->parent = pSaveLast; + pSaveLast->child = pItem1; + items306C[dwIndex] = pItem1; + + do + { + THTreeItem * pItem2 = pItem1; + THTreeItem * pItem3; + unsigned long byteValue; + + // 15006993 + byteValue = ++pItem1->byteValue; + + // Pass through all previous which have its value greater than byteValue + while(PTR_INT((pItem3 = pItem2->prev)) > 0) // EBX + { + if(pItem3->byteValue >= byteValue) + goto _150069AE; + + pItem2 = pItem2->prev; + } + // 150069AC + pItem3 = NULL; + + _150069AE: + if(pItem2 == pItem1) + continue; + + // 150069B2 + // Switch pItem2 with item + InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1); + InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3); + + // 150069D0 + // Switch parents of pItem1 and pItem2 + temp = pItem2->parent->child; + if(pItem1 == pItem1->parent->child) + pItem1->parent->child = pItem2; + + if(pItem2 == temp) + pItem2->parent->child = pItem1; + + // 150069ED + // Switch parents of pItem1 and pItem3 + temp = pItem1->parent; + pItem1 ->parent = pItem2->parent; + pItem2->parent = temp; + offs0004++; + } + while(PTR_INT((pItem1 = pItem1->parent)) > 0); +} + +void THuffmannTree::UninitTree() +{ + while(PTR_INT(pLast) > 0) + { + pItem = pItem305C->Call1501DB70(pLast); + pItem->RemoveItem(); + } + + for(pItem = pFirst; PTR_INT(pItem3058) > 0; pItem = pItem3058) + pItem->RemoveItem(); + PTR_PTR(&pItem3054)->RemoveItem(); + + for(pItem = items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--) + { + pItem--; + pItem->RemoveItem(); + pItem->RemoveItem(); + } +} +*/ + +THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue) +{ + THTreeItem * pItem1 = pItem3058; // EDX + THTreeItem * pItem2; // EAX + THTreeItem * pNext; + THTreeItem * pPrev; + THTreeItem ** ppItem; + + if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL) + { + if((pItem2 = &items0008[nItems++]) != NULL) + pItem1 = pItem2; + else + pItem1 = pFirst; + } + else + pItem1 = pItem2; + + pNext = pItem1->next; + if(pNext != NULL) + { + pPrev = pItem1->prev; + if(PTR_INVALID_OR_NULL(pPrev)) + pPrev = PTR_NOT(pPrev); + else + pPrev += (pItem1 - pItem1->next->prev); + + pPrev->next = pNext; + pNext->prev = pPrev; + pItem1->next = NULL; + pItem1->prev = NULL; + } + + ppItem = &pFirst; // esi + if(nValue > 1) + { + // ecx = pFirst->next; + pItem1->next = *ppItem; + pItem1->prev = (*ppItem)->prev; + + (*ppItem)->prev = pItem2; + *ppItem = pItem1; + + pItem2->parent = NULL; + pItem2->child = NULL; + } + else + { + pItem1->next = (THTreeItem *)ppItem; + pItem1->prev = ppItem[1]; + // edi = pItem305C; + pPrev = ppItem[1]; // ecx + if(PTR_INVALID_OR_NULL(pPrev)) + { + pPrev = PTR_NOT(pPrev); + pPrev->next = pItem1; + pPrev->prev = pItem2; + + pItem2->parent = NULL; + pItem2->child = NULL; + } + else + { + if(PTR_INVALID(pItem305C)) + pPrev += (THTreeItem *)ppItem - (*ppItem)->prev; + else + pPrev += PTR_INT(pItem305C); + + pPrev->next = pItem1; + ppItem[1] = pItem2; + pItem2->parent = NULL; + pItem2->child = NULL; + } + } + return pItem2; +} + +void THuffmannTree::Call1500E820(THTreeItem * pItem) +{ + THTreeItem * pItem1; // edi + THTreeItem * pItem2 = NULL; // eax + THTreeItem * pItem3; // edx + THTreeItem * pPrev; // ebx + + for(; pItem != NULL; pItem = pItem->parent) + { + pItem->byteValue++; + + for(pItem1 = pItem; ; pItem1 = pPrev) + { + pPrev = pItem1->prev; + if(PTR_INVALID_OR_NULL(pPrev)) + { + pPrev = NULL; + break; + } + + if(pPrev->byteValue >= pItem->byteValue) + break; + } + + if(pItem1 == pItem) + continue; + + if(pItem1->next != NULL) + { + pItem2 = pItem1->GetPrevItem(-1); + pItem2->next = pItem1->next; + pItem1->next->prev = pItem1->prev; + pItem1->next = NULL; + pItem1->prev = NULL; + } + + pItem2 = pItem->next; + pItem1->next = pItem2; + pItem1->prev = pItem2->prev; + pItem2->prev = pItem1; + pItem->next = pItem1; + if((pItem2 = pItem1) != NULL) + { + pItem2 = pItem->GetPrevItem(-1); + pItem2->next = pItem->next; + pItem->next->prev = pItem->prev; + pItem->next = NULL; + pItem->prev = NULL; + } + + if(pPrev == NULL) + pPrev = PTR_PTR(&pFirst); + + pItem2 = pPrev->next; + pItem->next = pItem2; + pItem->prev = pItem2->prev; + pItem2->prev = pItem; + pPrev->next = pItem; + + pItem3 = pItem1->parent->child; + pItem2 = pItem->parent; + if(pItem2->child == pItem) + pItem2->child = pItem1; + if(pItem3 == pItem1) + pItem1->parent->child = pItem; + + pItem2 = pItem->parent; + pItem->parent = pItem1->parent; + pItem1->parent = pItem2; + offs0004++; + } +} + +// 1500E920 +unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType) +{ + THTreeItem * pItem1; + THTreeItem * pItem2; + THTreeItem * pItem3; + THTreeItem * pTemp; + unsigned long dwBitBuff; + unsigned int nBits; + unsigned int nBit; + + BuildTree(nCmpType); + bIsCmp0 = (nCmpType == 0); + + // Store the compression type into output buffer + os->dwBitBuff |= (nCmpType << os->nBits); + os->nBits += 8; + + // Flush completed bytes + while(os->nBits >= 8) + { + if(os->dwOutSize != 0) + { + *os->pbOutPos++ = (unsigned char)os->dwBitBuff; + os->dwOutSize--; + } + + os->dwBitBuff >>= 8; + os->nBits -= 8; + } + + for(; nInLength != 0; nInLength--) + { + unsigned char bOneByte = *pbInBuffer++; + + if((pItem1 = items306C[bOneByte]) == NULL) + { + pItem2 = items306C[0x101]; // ecx + pItem3 = pItem2->parent; // eax + dwBitBuff = 0; + nBits = 0; + + for(; pItem3 != NULL; pItem3 = pItem3->parent) + { + nBit = (pItem3->child != pItem2) ? 1 : 0; + dwBitBuff = (dwBitBuff << 1) | nBit; + nBits++; + pItem2 = pItem3; + } + os->PutBits(dwBitBuff, nBits); + + // Store the loaded byte into output stream + os->dwBitBuff |= (bOneByte << os->nBits); + os->nBits += 8; + + // Flush the whole byte(s) + while(os->nBits >= 8) + { + if(os->dwOutSize != 0) + { + *os->pbOutPos++ = (unsigned char)os->dwBitBuff; + os->dwOutSize--; + } + os->dwBitBuff >>= 8; + os->nBits -= 8; + } + + pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast; + pItem2 = Call1500E740(1); + pItem2->dcmpByte = pItem1->dcmpByte; + pItem2->byteValue = pItem1->byteValue; + pItem2->parent = pItem1; + items306C[pItem2->dcmpByte] = pItem2; + + pItem2 = Call1500E740(1); + pItem2->dcmpByte = bOneByte; + pItem2->byteValue = 0; + pItem2->parent = pItem1; + items306C[pItem2->dcmpByte] = pItem2; + pItem1->child = pItem2; + + Call1500E820(pItem2); + + if(bIsCmp0 != 0) + { + Call1500E820(items306C[bOneByte]); + continue; + } + + for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent) + { + pItem1->byteValue++; + pItem2 = pItem1; + + for(;;) + { + pItem3 = pItem2->prev; + if(PTR_INVALID_OR_NULL(pItem3)) + { + pItem3 = NULL; + break; + } + if(pItem3->byteValue >= pItem1->byteValue) + break; + pItem2 = pItem3; + } + + if(pItem2 != pItem1) + { + InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1); + InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3); + + pItem3 = pItem2->parent->child; + if(pItem1->parent->child == pItem1) + pItem1->parent->child = pItem2; + + if(pItem3 == pItem2) + pItem2->parent->child = pItem1; + + pTemp = pItem1->parent; + pItem1->parent = pItem2->parent; + pItem2->parent = pTemp; + offs0004++; + } + } + } +// 1500EB62 + else + { + dwBitBuff = 0; + nBits = 0; + for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent) + { + nBit = (pItem2->child != pItem1) ? 1 : 0; + dwBitBuff = (dwBitBuff << 1) | nBit; + nBits++; + pItem1 = pItem2; + } + os->PutBits(dwBitBuff, nBits); + } + +// 1500EB98 + if(bIsCmp0 != 0) + Call1500E820(items306C[bOneByte]); // 1500EB9D +// 1500EBAF + } // for(; nInLength != 0; nInLength--) + +// 1500EBB8 + pItem1 = items306C[0x100]; + dwBitBuff = 0; + nBits = 0; + for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent) + { + nBit = (pItem2->child != pItem1) ? 1 : 0; + dwBitBuff = (dwBitBuff << 1) | nBit; + nBits++; + pItem1 = pItem2; + } + +// 1500EBE6 + os->PutBits(dwBitBuff, nBits); + +// 1500EBEF + // Flush the remaining bits + while(os->nBits != 0) + { + if(os->dwOutSize != 0) + { + *os->pbOutPos++ = (unsigned char)os->dwBitBuff; + os->dwOutSize--; + } + os->dwBitBuff >>= 8; + os->nBits -= ((os->nBits > 8) ? 8 : os->nBits); + } + + return (unsigned int)(os->pbOutPos - os->pbOutBuffer); +} + +// Decompression using Huffman tree (1500E450) +unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is) +{ + TQDecompress * qd; + THTreeItem * pItem1; + THTreeItem * pItem2; + unsigned char * pbOutPos = pbOutBuffer; + unsigned long nBitCount; + unsigned int nDcmpByte = 0; + unsigned int n8Bits; // 8 bits loaded from input stream + unsigned int n7Bits; // 7 bits loaded from input stream + bool bHasQdEntry; + + // Test the output length. Must not be NULL. + if(dwOutLength == 0) + return 0; + + // Get the compression type from the input stream + n8Bits = is->Get8Bits(); + + // Build the Huffman tree + BuildTree(n8Bits); + bIsCmp0 = (n8Bits == 0) ? 1 : 0; + + for(;;) + { + n7Bits = is->Get7Bits(); // Get 7 bits from input stream + + // Try to use quick decompression. Check TQDecompress array for corresponding item. + // If found, ise the result byte instead. + qd = &qd3474[n7Bits]; + + // If there is a quick-pass possible (ebx) + bHasQdEntry = (qd->offs00 >= offs0004) ? true : false; + + // If we can use quick decompress, use it. + if(bHasQdEntry) + { + if(qd->nBits > 7) + { + is->dwBitBuff >>= 7; + is->nBits -= 7; + pItem1 = qd->pItem; + goto _1500E549; + } + is->dwBitBuff >>= qd->nBits; + is->nBits -= qd->nBits; + nDcmpByte = qd->dcmpByte; + } + else + { + pItem1 = pFirst->next->prev; + if(PTR_INVALID_OR_NULL(pItem1)) + pItem1 = NULL; +_1500E549: + nBitCount = 0; + pItem2 = NULL; + + do + { + pItem1 = pItem1->child; // Move down by one level + if(is->GetBit()) // If current bit is set, move to previous + pItem1 = pItem1->prev; + + if(++nBitCount == 7) // If we are at 7th bit, save current HTree item. + pItem2 = pItem1; + } + while(pItem1->child != NULL); // Walk until tree has no deeper level + + if(bHasQdEntry == false) + { + if(nBitCount > 7) + { + qd->offs00 = offs0004; + qd->nBits = nBitCount; + qd->pItem = pItem2; + } + else + { + unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount)); + unsigned long nAdd = (1 << nBitCount); + + for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd) + { + qd->offs00 = offs0004; + qd->nBits = nBitCount; + qd->dcmpByte = pItem1->dcmpByte; + } + } + } + nDcmpByte = pItem1->dcmpByte; + } + + if(nDcmpByte == 0x101) // Huffman tree needs to be modified + { + n8Bits = is->Get8Bits(); + pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast; + + pItem2 = Call1500E740(1); + pItem2->parent = pItem1; + pItem2->dcmpByte = pItem1->dcmpByte; + pItem2->byteValue = pItem1->byteValue; + items306C[pItem2->dcmpByte] = pItem2; + + pItem2 = Call1500E740(1); + pItem2->parent = pItem1; + pItem2->dcmpByte = n8Bits; + pItem2->byteValue = 0; + items306C[pItem2->dcmpByte] = pItem2; + + pItem1->child = pItem2; + Call1500E820(pItem2); + if(bIsCmp0 == 0) + Call1500E820(items306C[n8Bits]); + + nDcmpByte = n8Bits; + } + + if(nDcmpByte == 0x100) + break; + + *pbOutPos++ = (unsigned char)nDcmpByte; + if(--dwOutLength == 0) + break; + + if(bIsCmp0) + Call1500E820(items306C[nDcmpByte]); + } + + return (unsigned int)(pbOutPos - pbOutBuffer); +} + +/* OLD VERSION +unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is) +{ + THTreeItem * pItem1; // Current item if walking HTree + unsigned long bitCount; // Bit counter if walking HTree + unsigned long oneByte; // 8 bits from bit stream/Pointer to target + unsigned char * outPtr; // Current pointer to output buffer + bool hasQDEntry; // true if entry for quick decompression if filled + THTreeItem * itemAt7 = NULL; // HTree item found at 7th bit + THTreeItem * temp; // For every use + unsigned long dcmpByte = 0; // Decompressed byte value + bool bFlag = 0; + + // Test the output length. Must not be NULL. + if(dwOutLength == 0) + return 0; + + // If too few bits in input bit buffer, we have to load next 16 bits + is->EnsureHasMoreThan8Bits(); + + // Get 8 bits from input stream + oneByte = is->Get8Bits(); + + // Build the Huffman tree + BuildTree(oneByte); + + bIsCmp0 = (oneByte == 0) ? 1 : 0; + outPtr = pbOutBuffer; // Copy pointer to output data + + for(;;) + { + TQDecompress * qd; // For quick decompress + unsigned long sevenBits = is->Get7Bits();// 7 bits from input stream + + // Try to use quick decompression. Check TQDecompress array for corresponding item. + // If found, ise the result byte instead. + qd = &qd3474[sevenBits]; + + // If there is a quick-pass possible + hasQDEntry = (qd->offs00 == offs0004) ? 1 : 0; + + // Start passing the Huffman tree. Set item to tree root item + pItem1 = pFirst; + + // If we can use quick decompress, use it. + bFlag = 1; + if(hasQDEntry == 1) + { + // Check the bit count is greater than 7, move item to 7 levels deeper + if((bitCount = qd->bitCount) > 7) + { + is->dwBitBuff >>= 7; + is->nBits -= 7; + pItem1 = qd->item; // Don't start with root item, but with some deeper-laying + } + else + { + // If OK, use their byte value + is->dwBitBuff >>= bitCount; + is->nBits -= bitCount; + dcmpByte = qd->dcmpByte; + bFlag = 0; + } + } + else + { + pItem1 = pFirst->next->prev; + if(PTR_INT(pItem1) <= 0) + pItem1 = NULL; + } + + if(bFlag == 1) + { + // Walk through Huffman Tree + bitCount = 0; // Clear bit counter + do + { + pItem1 = pItem1->child; + if(is->GetBit() != 0) // If current bit is set, move to previous + pItem1 = pItem1->prev; // item in current level + + if(++bitCount == 7) // If we are at 7th bit, store current HTree item. + itemAt7 = pItem1; // Store Huffman tree item + } + while(pItem1->child != NULL); // Walk until tree has no deeper level + + // If quick decompress entry is not filled yet, fill it. + if(hasQDEntry == 0) + { + if(bitCount > 7) // If we passed more than 7 bits, store bitCount and item + { + qd->offs00 = offs0004; // Value indicates that entry is resolved + qd->bitCount = bitCount; // Number of bits passed + qd->item = itemAt7; // Store item at 7th bit + } + // If we passed less than 7 bits, fill entry and bit count multipliers + else + { + unsigned long index = sevenBits & (0xFFFFFFFF >> (32 - bitCount)); // Index for quick-decompress entry + unsigned long addIndex = (1 << bitCount); // Add value for index + + qd = &qd3474[index]; + + do + { + qd->offs00 = offs0004; + qd->bitCount = bitCount; + qd->dcmpByte = pItem1->dcmpByte; + + index += addIndex; + qd += addIndex; + } + while(index <= 0x7F); + } + } + dcmpByte = pItem1->dcmpByte; + } + + if(dcmpByte == 0x101) // Huffman tree needs to be modified + { + // Check if there is enough bits in the buffer + is->EnsureHasMoreThan8Bits(); + + // Get 8 bits from the buffer + oneByte = is->Get8Bits(); + + // Modify Huffman tree + ModifyTree(oneByte); + + // Get lastly added tree item + pItem1 = items306C[oneByte]; + + if(bIsCmp0 == 0 && pItem1 != NULL) + { + // 15006F15 + do + { + THTreeItem * pItem2 = pItem1; + THTreeItem * pItem3; + unsigned long byteValue; + + byteValue = ++pItem1->byteValue; + + while(PTR_INT((pItem3 = pItem2->prev)) > 0) + { + if(pItem3->byteValue >= byteValue) + goto _15006F30; + + pItem2 = pItem2->prev; + } + pItem3 = NULL; + + _15006F30: + if(pItem2 == pItem1) + continue; + + InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1); + InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3); + + temp = pItem2->parent->child; + if(pItem1 == pItem1->parent->child) + pItem1->parent->child = pItem2; + + if(pItem2 == temp) + pItem2->parent->child = pItem1; + + // Switch parents of pItem1 and pItem3 + temp = pItem1->parent; + pItem1->parent = pItem2->parent; + pItem2->parent = temp; + offs0004++; + } + while(PTR_INT((pItem1 = pItem1->parent)) > 0); + } + dcmpByte = oneByte; + } + + if(dcmpByte != 0x100) // Not at the end of data ? + { + *outPtr++ = (unsigned char)dcmpByte; + if(--dwOutLength > 0) + { + if(bIsCmp0 != 0) + Call1500E820(items306C[pItem1->byteValue]); + } + else + break; + } + else + break; + } + return (unsigned long)(outPtr - pbOutBuffer); +} +*/ + +// Table for (de)compression. Every compression type has 258 entries +unsigned char THuffmannTree::Table1502A630[] = +{ + // Data for compression type 0x00 + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, + + // Data for compression type 0x01 + 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, + 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, + 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, + 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, + 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, + 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, + 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, + 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, + 0x00, 0x00, + + // Data for compression type 0x02 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, + 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, + 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, + 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + // Data for compression type 0x03 + 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, + 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, + 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, + 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, + 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, + 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, + 0x00, 0x00, + + // Data for compression type 0x04 + 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + // Data for compression type 0x05 + 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, + 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, + 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, + 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + // Data for compression type 0x06 + 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + // Data for compression type 0x07 + 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + // Data for compression type 0x08 + 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, + 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, + 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; \ No newline at end of file diff --git a/contrib/vmap_extractor_v2/stormlib/huffman/huff.h b/contrib/vmap_extractor_v2/stormlib/huffman/huff.h new file mode 100644 index 000000000..f06aa771a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/huffman/huff.h @@ -0,0 +1,142 @@ +/*****************************************************************************/ +/* huffman.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad The first version of huffman.h */ +/* 03.05.03 2.00 Lad Added compression */ +/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ +/*****************************************************************************/ + +#ifndef __HUFFMAN_H__ +#define __HUFFMAN_H__ + +#include "../StormPort.h" + +//----------------------------------------------------------------------------- +// Defines + +#define INSERT_ITEM 1 +#define SWITCH_ITEMS 2 // Switch the item1 and item2 + +#define PTR_NOT(ptr) (THTreeItem *)(~(DWORD_PTR)(ptr)) +#define PTR_PTR(ptr) ((THTreeItem *)(ptr)) +#define PTR_INT(ptr) (LONG_PTR)(ptr) + +#ifndef NULL +#define NULL 0 +#endif + +//----------------------------------------------------------------------------- +// Structures and classes + +// Input stream for Huffmann decompression +class TInputStream +{ + public: + + unsigned long GetBit(); + unsigned long Get7Bits(); + unsigned long Get8Bits(); + + unsigned char * pbInBuffer; // 00 - Input data + unsigned long dwBitBuff; // 04 - Input bit buffer + unsigned int nBits; // 08 - Number of bits remaining in 'dwValue' +}; + +// Output stream for Huffmann compression +class TOutputStream +{ + public: + + void PutBits(unsigned long dwBuff, unsigned int nPutBits); + + unsigned char * pbOutBuffer; // 00 : Output buffer + unsigned long dwOutSize; // 04 : Size of output buffer + unsigned char * pbOutPos; // 08 : Current output position + unsigned long dwBitBuff; // 0C : Bit buffer + unsigned long nBits; // 10 : Number of bits in the bit buffer +}; + +// Huffmann tree item (?) +struct THTreeItem +{ + public: + + THTreeItem * Call1501DB70(THTreeItem * pLast); + THTreeItem * GetPrevItem(LONG_PTR value); + void ClearItemLinks(); + void RemoveItem(); + + THTreeItem * next; // 00 - Pointer to next THTreeItem + THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none) + unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value + unsigned long byteValue; // 0C - Some byte value + THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none) + THTreeItem * child; // 14 - Pointer to child THTreeItem + int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive +}; + +// Structure used for quick decompress. The 'bitCount' contains number of bits +// and byte value contains result decompressed byte value. +// After each walk through Huffman tree are filled all entries which are +// multiplies of number of bits loaded from input stream. These entries +// contain number of bits and result value. At the next 7 bits is tested this +// structure first. If corresponding entry found, decompression routine will +// not walk through Huffman tree and directly stores output byte to output stream. +struct TQDecompress +{ + unsigned long offs00; // 00 - 1 if resolved + unsigned long nBits; // 04 - Bit count + union + { + unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7) + THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7 + }; +}; + +// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert +// for the decompression, I do not know actually if the class is really a Hufmann +// tree. If someone knows the decompression details, please let me know +class THuffmannTree +{ + public: + + THuffmannTree(); + void InitTree(bool bCompression); + void BuildTree(unsigned int nCmpType); +// void ModifyTree(unsigned long dwIndex); +// void UninitTree(); + +// void Call15007010(Bit32 dwInLength, THTreeItem * item); + THTreeItem * Call1500E740(unsigned int nValue); + void Call1500E820(THTreeItem * pItem); + unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType); + unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is); + + unsigned long bIsCmp0; // 0000 - 1 if compression type 0 + unsigned long offs0004; // 0004 - Some flag + THTreeItem items0008[0x203]; // 0008 - HTree items + + //- Sometimes used as HTree item ----------- + THTreeItem * pItem3050; // 3050 - Always NULL (?) + THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item + THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid) + + //- Sometimes used as HTree item ----------- + THTreeItem * pItem305C; // 305C - Usually NULL + THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item + THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) + unsigned long nItems; // 3068 - Number of used HTree items + + //------------------------------------------- + THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array + TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression + int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive + + static unsigned char Table1502A630[];// Some table +}; + +#endif // __HUFFMAN_H__ diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/crc32.c b/contrib/vmap_extractor_v2/stormlib/pklib/crc32.c new file mode 100644 index 000000000..a7f52103b --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/pklib/crc32.c @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* crc32.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Pkware Data Compression Library Version 1.11 */ +/* Dissassembled method crc32 - cdecl version */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 09.04.03 1.00 Lad The first version of crc32.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/*****************************************************************************/ + +#include "pklib.h" + +static char CopyRight[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +static unsigned long crc_table[] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + + +unsigned long PKEXPORT crc32pk(char * buffer, unsigned int * psize, unsigned long * old_crc) +{ + unsigned int size = *psize; + unsigned long ch; + unsigned long crc_value = *old_crc; + + while(size-- != 0) + { + ch = *buffer++ ^ (char)crc_value; + crc_value >>= 8; + + crc_value = crc_table[ch & 0x0FF] ^ crc_value; + } + return crc_value; +} diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c b/contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c new file mode 100644 index 000000000..a7f52103b --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* crc32.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Pkware Data Compression Library Version 1.11 */ +/* Dissassembled method crc32 - cdecl version */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 09.04.03 1.00 Lad The first version of crc32.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/*****************************************************************************/ + +#include "pklib.h" + +static char CopyRight[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +static unsigned long crc_table[] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + + +unsigned long PKEXPORT crc32pk(char * buffer, unsigned int * psize, unsigned long * old_crc) +{ + unsigned int size = *psize; + unsigned long ch; + unsigned long crc_value = *old_crc; + + while(size-- != 0) + { + ch = *buffer++ ^ (char)crc_value; + crc_value >>= 8; + + crc_value = crc_table[ch & 0x0FF] ^ crc_value; + } + return crc_value; +} diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/explode.c b/contrib/vmap_extractor_v2/stormlib/pklib/explode.c new file mode 100644 index 000000000..a5b41e3dc --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/pklib/explode.c @@ -0,0 +1,480 @@ +/*****************************************************************************/ +/* explode.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Implode function of PKWARE Data Compression library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ +/* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */ +/* 02.05.03 1.01 Lad Stress test done */ +/*****************************************************************************/ + +#include +#include + +#include "pklib.h" + +//----------------------------------------------------------------------------- +// Tables + +static unsigned char DistBits[] = +{ + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +static unsigned char DistCode[] = +{ + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 +}; + +static unsigned char ExLenBits[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 +}; + +static unsigned short LenBase[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 +}; + +static unsigned char LenBits[] = +{ + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 +}; + +static unsigned char LenCode[] = +{ + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 +}; + +static unsigned char ChBitsAsc[] = +{ + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D +}; + +static unsigned short ChCodeAsc[] = +{ + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 +}; + +//----------------------------------------------------------------------------- +// Local variables + +static char Copyright[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +//----------------------------------------------------------------------------- +// Local functions + +// Copies a block to another location +static void lmemcpy(void * trg, const void * src, size_t count) +{ + memcpy(trg, src, count); +} + +static void GenDecodeTabs(long count, unsigned char * bits, unsigned char * pCode, unsigned char * buffer2) +{ + long i; + + for(i = count-1; i >= 0; i--) // EBX - count + { + unsigned long idx1 = pCode[i]; + unsigned long idx2 = 1 << bits[i]; + + do + { + buffer2[idx1] = (unsigned char)i; + idx1 += idx2; + } + while(idx1 < 0x100); + } +} + +static void GenAscTabs(TDcmpStruct * pWork) +{ + unsigned short * pChCodeAsc = &ChCodeAsc[0xFF]; + unsigned long acc, add; + unsigned short count; + + for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--) + { + unsigned char * pChBitsAsc = pWork->ChBitsAsc + count; + unsigned char bits_asc = *pChBitsAsc; + + if(bits_asc <= 8) + { + add = (1 << bits_asc); + acc = *pChCodeAsc; + + do + { + pWork->offs2C34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + else if((acc = (*pChCodeAsc & 0xFF)) != 0) + { + pWork->offs2C34[acc] = 0xFF; + + if(*pChCodeAsc & 0x3F) + { + bits_asc -= 4; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 4; + do + { + pWork->offs2D34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + else + { + bits_asc -= 6; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 6; + do + { + pWork->offs2E34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x80); + } + } + else + { + bits_asc -= 8; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 8; + do + { + pWork->offs2EB4[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + } +} + +//----------------------------------------------------------------------------- +// Skips given number of bits in bit buffer. Result is stored in pWork->bit_buff +// If no data in input buffer, returns true + +static int WasteBits(TDcmpStruct * pWork, unsigned long nBits) +{ + // If number of bits required is less than number of (bits in the buffer) ? + if(nBits <= pWork->extra_bits) + { + pWork->extra_bits -= nBits; + pWork->bit_buff >>= nBits; + return 0; + } + + // Load input buffer if necessary + pWork->bit_buff >>= pWork->extra_bits; + if(pWork->in_pos == pWork->in_bytes) + { + pWork->in_pos = sizeof(pWork->in_buff); + if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0) + return 1; + pWork->in_pos = 0; + } + + // Update bit buffer + pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8); + pWork->bit_buff >>= (nBits - pWork->extra_bits); + pWork->extra_bits = (pWork->extra_bits - nBits) + 8; + return 0; +} + +//----------------------------------------------------------------------------- +// Returns : 0x000 - 0x0FF : One byte from compressed file. +// 0x100 - 0x305 : Copy previous block (0x100 = 1 byte) +// 0x306 : Out of buffer (?) + +static unsigned long DecodeLit(TDcmpStruct * pWork) +{ + unsigned long nBits; // Number of bits to skip + unsigned long value; // Position in buffers + + // Test the current bit in byte buffer. If is not set, simply return the next byte. + if(pWork->bit_buff & 1) + { + // Skip current bit in the buffer + if(WasteBits(pWork, 1)) + return 0x306; + + // The next bits are position in buffers + value = pWork->position2[(pWork->bit_buff & 0xFF)]; + + // Get number of bits to skip + if(WasteBits(pWork, pWork->LenBits[value])) + return 0x306; + + if((nBits = pWork->ExLenBits[value]) != 0) + { + unsigned long val2 = pWork->bit_buff & ((1 << nBits) - 1); + + if(WasteBits(pWork, nBits)) + { + if((value + val2) != 0x10E) + return 0x306; + } + value = pWork->LenBase[value] + val2; + } + return value + 0x100; // Return number of bytes to repeat + } + + // Waste one bit + if(WasteBits(pWork, 1)) + return 0x306; + + // If the binary compression type, read 8 bits and return them as one byte. + if(pWork->ctype == CMP_BINARY) + { + value = pWork->bit_buff & 0xFF; + if(WasteBits(pWork, 8)) + return 0x306; + return value; + } + + // When ASCII compression ... + if(pWork->bit_buff & 0xFF) + { + value = pWork->offs2C34[pWork->bit_buff & 0xFF]; + + if(value == 0xFF) + { + if(pWork->bit_buff & 0x3F) + { + if(WasteBits(pWork, 4)) + return 0x306; + + value = pWork->offs2D34[pWork->bit_buff & 0xFF]; + } + else + { + if(WasteBits(pWork, 6)) + return 0x306; + + value = pWork->offs2E34[pWork->bit_buff & 0x7F]; + } + } + } + else + { + if(WasteBits(pWork, 8)) + return 0x306; + + value = pWork->offs2EB4[pWork->bit_buff & 0xFF]; + } + + return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value; +} + +//----------------------------------------------------------------------------- +// Retrieves the number of bytes to move back + +static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long dwLength) +{ + unsigned long pos = pWork->position1[(pWork->bit_buff & 0xFF)]; + unsigned long nSkip = pWork->DistBits[pos]; // Number of bits to skip + + // Skip the appropriate number of bits + if(WasteBits(pWork, nSkip) == 1) + return 0; + + if(dwLength == 2) + { + pos = (pos << 2) | (pWork->bit_buff & 0x03); + + if(WasteBits(pWork, 2) == 1) + return 0; + } + else + { + pos = (pos << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask); + + // Skip the bits + if(WasteBits(pWork, pWork->dsize_bits) == 1) + return 0; + } + return pos+1; +} + +static unsigned long Expand(TDcmpStruct * pWork) +{ + unsigned int copyBytes; // Number of bytes to copy + unsigned long oneByte; // One byte from compressed file + unsigned long dwResult; + + pWork->outputPos = 0x1000; // Initialize output buffer position + + // If end of data or error, terminate decompress + while((dwResult = oneByte = DecodeLit(pWork)) < 0x305) + { + // If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" + if(oneByte >= 0x100) + { + unsigned char * source; // ECX + unsigned char * target; // EDX + unsigned long copyLength = oneByte - 0xFE; + unsigned long moveBack; + + // Get length of data to copy + if((moveBack = DecodeDist(pWork, copyLength)) == 0) + { + dwResult = 0x306; + break; + } + + // Target and source pointer + target = &pWork->out_buff[pWork->outputPos]; + source = target - moveBack; + pWork->outputPos += copyLength; + + while(copyLength-- > 0) + *target++ = *source++; + } + else + pWork->out_buff[pWork->outputPos++] = (unsigned char)oneByte; + + // If number of extracted bytes has reached 1/2 of output buffer, + // flush output buffer. + if(pWork->outputPos >= 0x2000) + { + // Copy decompressed data into user buffer + copyBytes = 0x1000; + pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); + + // If there are some data left, keep them alive + lmemcpy(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000); + pWork->outputPos -= 0x1000; + } + } + + copyBytes = pWork->outputPos - 0x1000; + pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); + return dwResult; +} + + +//----------------------------------------------------------------------------- +// Main exploding function. + +unsigned int explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param) +{ + TDcmpStruct * pWork = (TDcmpStruct *)work_buf; + + // Set the whole work buffer to zeros + memset(pWork, 0, sizeof(TDcmpStruct)); + + // Initialize work struct and load compressed data + pWork->read_buf = read_buf; + pWork->write_buf = write_buf; + pWork->param = param; + pWork->in_pos = sizeof(pWork->in_buff); + pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param); + if(pWork->in_bytes <= 4) + return CMP_BAD_DATA; + + pWork->ctype = pWork->in_buff[0]; // Get the compression type + pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size + pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer + pWork->extra_bits = 0; // Extra (over 8) bits + pWork->in_pos = 3; // Position in input buffer + + // Test for the valid dictionary size + if(4 > pWork->dsize_bits || pWork->dsize_bits > 6) + return CMP_INVALID_DICTSIZE; + + pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction + + if(pWork->ctype != CMP_BINARY) + { + if(pWork->ctype != CMP_ASCII) + return CMP_INVALID_MODE; + + lmemcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc)); + GenAscTabs(pWork); + } + + lmemcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits)); + GenDecodeTabs(0x10, pWork->LenBits, LenCode, pWork->position2); + lmemcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits)); + lmemcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase)); + lmemcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits)); + GenDecodeTabs(0x40, pWork->DistBits, DistCode, pWork->position1); + if(Expand(pWork) != 0x306) + return CMP_NO_ERROR; + + return CMP_ABORT; +} diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/implode.c b/contrib/vmap_extractor_v2/stormlib/pklib/implode.c new file mode 100644 index 000000000..68d5301cc --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/pklib/implode.c @@ -0,0 +1,674 @@ +/*****************************************************************************/ +/* implode.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Implode function of PKWARE Data Compression library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.04.03 1.00 Lad First version of implode.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/*****************************************************************************/ + +#include +#include + +#include "pklib.h" + +#if ((1200 < _MSC_VER) && (_MSC_VER < 1400)) +#pragma optimize("", off) // Fucking Microsoft VS.NET 2003 compiler !!! + // (_MSC_VER=1310) +#endif + +//----------------------------------------------------------------------------- +// Defines + +#define DICT_OFFSET 0x204 +#define UNCMP_OFFSET (pWork->dsize_bytes + DICT_OFFSET) + +//----------------------------------------------------------------------------- +// Tables + +static unsigned char DistBits[] = +{ + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +static unsigned char DistCode[] = +{ + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 +}; + +static unsigned char ExLenBits[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 +}; + +static unsigned char LenBits[] = +{ + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 +}; + +static unsigned char LenCode[] = +{ + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 +}; + +static unsigned char ChBitsAsc[] = +{ + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D +}; + +static unsigned short ChCodeAsc[] = +{ + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 +}; + +//----------------------------------------------------------------------------- +// Local variables + +static char Copyright[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +//----------------------------------------------------------------------------- +// Local functions + +// Fills memory block with a character +static void lmemset(void * buff, int c, size_t count) +{ + memset(buff, c, count); +} + +// Copies memory block to another location +static void lmemcpy(void * trg, const void * src, size_t count) +{ + memcpy(trg, src, count); +} + +static void SortBuffer(TCmpStruct * pWork, unsigned char * uncmp_data, unsigned char * work_end) +{ + unsigned short * pin0DC8; + unsigned char * puncmp; + unsigned long offs1, offs2; + unsigned long ndwords; + unsigned int add; + + // Fill 0x480 dwords (0x1200 bytes) + ndwords = (unsigned long)((pWork->out_buff - (char *)pWork->offs0DC8 + 1) >> 2); + if(ndwords <= 1) + ndwords = 1; + memset(pWork->offs0DC8, 0, ndwords << 2); + + for(puncmp = uncmp_data; work_end > puncmp; puncmp++) + pWork->offs0DC8[(puncmp[0] * 4) + (puncmp[1] * 5)]++; + + add = 0; + for(pin0DC8 = pWork->offs0DC8; pin0DC8 < &pWork->offs1FC8; pin0DC8++) + { + add += *pin0DC8; + *pin0DC8 = (unsigned short)add; + } + + for(work_end--; work_end >= uncmp_data; work_end--) + { + offs1 = (work_end[0] * 4) + (work_end[1] * 5); // EAX + offs2 = (unsigned long)(work_end - pWork->work_buff); // EDI + + pWork->offs0DC8[offs1]--; + pWork->offs49D0[pWork->offs0DC8[offs1]] = (unsigned short)offs2; + } +} + +static void FlushBuf(TCmpStruct * pWork) +{ + unsigned char save_ch1; + unsigned char save_ch2; + unsigned int size = 0x800; + + pWork->write_buf(pWork->out_buff, &size, pWork->param); + + save_ch1 = pWork->out_buff[0x800]; + save_ch2 = pWork->out_buff[pWork->out_bytes]; + pWork->out_bytes -= 0x800; + + lmemset(pWork->out_buff, 0, 0x802); + + if(pWork->out_bytes != 0) + pWork->out_buff[0] = save_ch1; + if(pWork->out_bits != 0) + pWork->out_buff[pWork->out_bytes] = save_ch2; +} + +static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff) +{ + unsigned int out_bits; + + // If more than 8 bits to output, do recursion + if(nbits > 8) + { + OutputBits(pWork, 8, bit_buff); + bit_buff >>= 8; + nbits -= 8; + } + + // Add bits to the last out byte in out_buff; + out_bits = pWork->out_bits; + pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits); + pWork->out_bits += nbits; + + // If 8 or more bits, increment number of bytes + if(pWork->out_bits > 8) + { + pWork->out_bytes++; + bit_buff >>= (8 - out_bits); + + pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff; + pWork->out_bits &= 7; + } + else + { + pWork->out_bits &= 7; + if(pWork->out_bits == 0) + pWork->out_bytes++; + } + + // If there is enough compressed bytes, flush them + if(pWork->out_bytes >= 0x800) + FlushBuf(pWork); +} + +static unsigned long FindRep(TCmpStruct * pWork, unsigned char * srcbuff) +{ + unsigned short esp12; + unsigned char * esp14; + unsigned short esp18; + unsigned char * srcbuff2; + unsigned char esp20; + + unsigned char * srcbuff3; + unsigned short * pin0DC8; + unsigned char * pin27CC; + unsigned short * pin49D0; + unsigned long nreps = 1; // EAX + unsigned long ebx, esi; + unsigned short di; + + pin0DC8 = pWork->offs0DC8 + (srcbuff[0] * 4) + (srcbuff[1] * 5); + esi = (unsigned long)(srcbuff - pWork->dsize_bytes - pWork->work_buff + 1); + esp18 = *pin0DC8; + pin49D0 = pWork->offs49D0 + esp18; + + if(*pin49D0 < esi) + { + while(*pin49D0 < esi) + { + pin49D0++; + esp18++; + } + *pin0DC8 = esp18; + } +//--------------------------------------------------------------------------- + srcbuff2 = srcbuff - 1; + pin49D0 = pWork->offs49D0 + esp18; + pin27CC = pWork->work_buff + *pin49D0; + if(srcbuff2 <= pin27CC) + return 0; +//--------------------------------------------------------------------------- + srcbuff3 = srcbuff; + for(;;) + { + if(srcbuff3[nreps-1] == pin27CC[nreps-1] && *srcbuff3 == *pin27CC) + { + // + // The following code does not work when compiled with MSVC.NET 2003 + // optimizing compiler. We have to switch the optimizations off to make it work + // I found that in debug version (where the optimizations are off), the value + // of "pin27CC" gets incremented twice (once at below, once in the "for" loop) + // + + pin27CC++; + srcbuff3++; + + for(ebx = 2; ebx < DICT_OFFSET; ebx++) + { + pin27CC++; + srcbuff3++; + if(*pin27CC != *srcbuff3) + break; + } + + srcbuff3 = srcbuff; + if(ebx >= nreps) + { + pWork->offs0000 = (unsigned int)(srcbuff3 - pin27CC + ebx - 1); + if((nreps = ebx) > 10) + break; + } + } + + pin49D0++; + esp18++; + pin27CC = pWork->work_buff + *pin49D0; + + if(srcbuff2 > pin27CC) + continue; + + return (nreps >= 2) ? nreps : 0; + } +//--------------------------------------------------------------------------- + if(ebx == DICT_OFFSET) + { + pWork->offs0000--; + return ebx; + } +//--------------------------------------------------------------------------- + pin49D0 = pWork->offs49D0 + esp18; + if(pWork->work_buff + pin49D0[1] >= srcbuff2) + return nreps; +//--------------------------------------------------------------------------- + di = 0; + pWork->offs09BC[0] = 0xFFFF; + pWork->offs09BC[1] = di; + esp12 = 1; + + do + { + esi = di; + if(srcbuff[esp12] != srcbuff[esi]) + { + di = pWork->offs09BC[esi]; + if(di != 0xFFFF) + continue; + } + pWork->offs09BC[++esp12] = ++di; + } + while(esp12 < nreps); +//--------------------------------------------------------------------------- + esi = nreps; + pin27CC = pWork->work_buff + pin49D0[0] + nreps; + esp14 = pin27CC; + + for(;;) // 0040268B + { + esi = pWork->offs09BC[esi]; + if(esi == 0xFFFF) + esi = 0; + + pin49D0 = pWork->offs49D0 + esp18; + do + { + pin49D0++; + esp18++; + pin27CC = pWork->work_buff + pin49D0[0]; + if(pin27CC >= srcbuff2) + return nreps; + } + while(pin27CC + esi < esp14); +//--------------------------------------------------------------------------- + esp20 = srcbuff[nreps - 2]; + if(esp20 == pin27CC[nreps - 2]) + { + if(pin27CC + esi != esp14) + { + esp14 = pin27CC; + esi = 0; + } + } + else + { + pin49D0 = pWork->offs49D0 + esp18; + do + { + pin49D0++; + esp18++; + pin27CC = pWork->work_buff + pin49D0[0]; + if(pin27CC >= srcbuff2) + return nreps; + } + while(pin27CC[nreps - 2] != esp20 || pin27CC[0] != *srcbuff); + + esp14 = pin27CC + 2; + esi = 2; + } +//--------------------------------------------------------------------------- + for(; esp14[0] == srcbuff[esi]; esp14++) + { + if(++esi >= DICT_OFFSET) + break; + } + + if(esi < nreps) + continue; + pWork->offs0000 = (unsigned int)(srcbuff - pin27CC - 1); + if(esi <= nreps) + continue; + nreps = esi; + if(esi == DICT_OFFSET) + return nreps; + + do + { + if(srcbuff[esp12] != srcbuff[di]) + { + di = pWork->offs09BC[di]; + if(di != 0xFFFF) + continue; + } + pWork->offs09BC[++esp12] = ++di; + } + while(esp12 < esi); + } +} + +static void WriteCmpData(TCmpStruct * pWork) +{ + unsigned int nreps = 0; // ESP+10 : Number of repeats + unsigned char * uncmp_end; // ESP+14 : End of uncompressed data + unsigned int esp18 = 0; // ESP+18 : + unsigned int bytes_required; // ESP+1C : Number of bytes required to read + unsigned int esp20 = 0; // ESP+20 : + unsigned char * uncmp_begin = pWork->work_buff + UNCMP_OFFSET; // EDI + unsigned long nreps1; + unsigned long save_offs0000 = 0; + + // Store the compression type and dictionary size + pWork->out_buff[0] = (char)pWork->ctype; + pWork->out_buff[1] = (char)pWork->dsize_bits; + pWork->out_bytes = 2; + + // Reset output buffer to zero + lmemset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2); + pWork->out_bits = 0; + + do + { + int total_loaded = 0; + + for(bytes_required = 0x1000; bytes_required != 0; ) + { + int loaded = pWork->read_buf((char *)pWork->work_buff + UNCMP_OFFSET + total_loaded, + &bytes_required, pWork->param); + + if(loaded == 0) + { + if(total_loaded == 0 && esp20 == 0) + goto __Exit; + esp18 = 1; + break; + } + else + { + total_loaded += loaded; + bytes_required -= loaded; + } + } + + uncmp_end = pWork->work_buff + pWork->dsize_bytes + total_loaded; + if(esp18 != 0) + uncmp_end += DICT_OFFSET; + + // + // Warning: Passing "uncmp_end + 1" to the SortBuffer function may cause + // the output to be unpredictable in Storm.dll's compression. Because Storm.dll + // does not pass the zeroed buffer to the "implode" function, the byte after + // uncmp_end contains random data. This causes difference within dictionary + // created in SortBuffer function and may also cause different compressed output. + // We always zero the data before compression, so this thing never occurs. + // Funny is that it is actually not a bug, because if we decompress the data back, + // we'll get the identical data with the original input. + // + switch(esp20) + { + case 0: + SortBuffer(pWork, uncmp_begin, uncmp_end + 1); + esp20++; + if(pWork->dsize_bytes != 0x1000) + esp20++; + break; + + case 1: + SortBuffer(pWork, uncmp_begin - pWork->dsize_bytes + DICT_OFFSET, uncmp_end + 1); + esp20++; + break; + + default: + SortBuffer(pWork, uncmp_begin - pWork->dsize_bytes, uncmp_end + 1); + break; + } + + while(uncmp_end > uncmp_begin) + { + nreps1 = FindRep(pWork, uncmp_begin); + while(nreps1 != 0) + { + if(nreps1 == 2 && pWork->offs0000 >= 0x100) + break; + + if(esp18 != 0 && uncmp_begin + nreps1 > uncmp_end) + goto _004022DB; + + if(nreps1 >= 8 || uncmp_begin + 1 >= uncmp_end) + goto _004022FF; + + save_offs0000 = pWork->offs0000; // ebp + nreps = nreps1; + nreps1 = FindRep(pWork, uncmp_begin + 1); + + if(nreps >= nreps1) + goto _004022F9; + + if(nreps + 1 >= nreps1 && save_offs0000 <= 0x80) + goto _004022F9; + + OutputBits(pWork, pWork->nChBits[*uncmp_begin], pWork->nChCodes[*uncmp_begin]); + uncmp_begin++; + } + +_0040222F: + OutputBits(pWork, pWork->nChBits[*uncmp_begin], pWork->nChCodes[*uncmp_begin]); + uncmp_begin++; +_00402252:; + } + + if(esp18 == 0) + { + uncmp_begin -= 0x1000; + lmemcpy(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + DICT_OFFSET); + } + } + while(esp18 == 0); + +__Exit: + OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]); + if(pWork->out_bits != 0) + pWork->out_bytes++; + pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param); + return; + +_004022DB: + nreps1 = (unsigned long)(uncmp_end - uncmp_begin); + if(nreps1 < 2) + goto _0040222F; + + if(nreps1 != 2 || pWork->offs0000 < 0x100) + goto _004022FF; + goto _0040222F; + +_004022F9: + nreps1 = nreps; + pWork->offs0000 = save_offs0000; + +_004022FF: + OutputBits(pWork, pWork->nChBits[nreps1 + 0xFE], pWork->nChCodes[nreps1 + 0xFE]); + + if(nreps1 == 2) + { + OutputBits(pWork, pWork->dist_bits[pWork->offs0000 >> 2], + pWork->dist_codes[pWork->offs0000 >> 2]); + OutputBits(pWork, 2, pWork->offs0000 & 3); + } + else + { + OutputBits(pWork, pWork->dist_bits[pWork->offs0000 >> pWork->dsize_bits], + pWork->dist_codes[pWork->offs0000 >> pWork->dsize_bits]); + OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->offs0000); + } + uncmp_begin += nreps1; + goto _00402252; +} + +//----------------------------------------------------------------------------- +// Main imploding function + +unsigned int PKEXPORT implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize) +{ + TCmpStruct * pWork = (TCmpStruct *)work_buf; + unsigned int nChCode; + unsigned int nCount; + unsigned int i; + + // Initialize the work buffer. This is not in the Pklib, + // but it seems to be a bug. Storm always pre-fills the data with zeros, + // and always compresses one block only. So the bug will not appear. + // But when a larger data block (size > 0x1000) is compressed, + // it may fail. + memset(pWork, 0, sizeof(TCmpStruct)); + + // Fill the work buffer information + pWork->read_buf = read_buf; + pWork->write_buf = write_buf; + pWork->dsize_bytes = *dsize; + pWork->ctype = *type; + pWork->param = param; + pWork->dsize_bits = 4; + pWork->dsize_mask = 0x0F; + + // Test dictionary size + switch(*dsize) + { + case 0x1000 : + pWork->dsize_bits++; + pWork->dsize_mask |= 0x20; + // No break here !!! + + case 0x0800 : + pWork->dsize_bits++; + pWork->dsize_mask |= 0x10; + // No break here !!! + + case 0x0400 : + break; + + default: + return CMP_INVALID_DICTSIZE; + } + + // Test the compression type + switch(*type) + { + case CMP_BINARY: // We will compress data with binary compression type + for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++) + { + pWork->nChBits[nCount] = 9; + pWork->nChCodes[nCount] = (unsigned short)nChCode; + nChCode = (nChCode & 0x0000FFFF) + 2; + } + break; + + + case CMP_ASCII: // We will compress data with ASCII compression type + for(nCount = 0; nCount < 0x100; nCount++) + { + pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1); + pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2); + } + break; + + default: + return CMP_INVALID_MODE; + } + + for(i = 0; i < 0x10; i++) + { + int nCount2 = 0; // EBX + + if((1 << ExLenBits[i]) == 0) + continue; + + do + { + pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1); + pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1); + + nCount2++; + nCount++; + } + while((1 << ExLenBits[i]) > nCount2); + } + + // Copy the distance codes and distance bits and perform the compression + lmemcpy(&pWork->dist_codes, DistCode, sizeof(DistCode)); + lmemcpy(&pWork->dist_bits, DistBits, sizeof(DistBits)); + WriteCmpData(pWork); + return CMP_NO_ERROR; +} diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/pklib.h b/contrib/vmap_extractor_v2/stormlib/pklib/pklib.h new file mode 100644 index 000000000..881262e38 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/pklib/pklib.h @@ -0,0 +1,137 @@ +/*****************************************************************************/ +/* pklib.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Header file for PKWARE Data Compression Library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 31.03.03 1.00 Lad The first version of pkware.h */ +/*****************************************************************************/ + +#ifndef __PKLIB_H__ +#define __PKLIB_H__ + +#include "../StormPort.h" + +//----------------------------------------------------------------------------- +// Defines + +#define CMP_BINARY 0 // Binary compression +#define CMP_ASCII 1 // Ascii compression + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + +//----------------------------------------------------------------------------- +// Define calling convention + +#ifndef PKEXPORT +#define PKEXPORT //__cdecl // Use for normal __cdecl calling +#endif +//#define PKEXPORT __stdcall +//#define PKEXPORT __fastcall + +//----------------------------------------------------------------------------- +// Internal structures + +// Compression structure +typedef struct +{ + unsigned int offs0000; // 0000 : + unsigned int out_bytes; // 0004 : # bytes available in out_buff + unsigned int out_bits; // 0008 : # of bits available in the last out byte + unsigned int dsize_bits; // 000C : Dict size : 4=0x400, 5=0x800, 6=0x1000 + unsigned int dsize_mask; // 0010 : Dict size : 0x0F=0x400, 0x1F=0x800, 0x3F=0x1000 + unsigned int ctype; // 0014 : Compression type (Ascii or binary) + unsigned int dsize_bytes; // 0018 : Dictionary size in bytes + unsigned char dist_bits[0x40]; // 001C : Distance bits + unsigned char dist_codes[0x40]; // 005C : Distance codes + unsigned char nChBits[0x306]; // 009C : + unsigned short nChCodes[0x306]; // 03A2 : + unsigned short offs09AE; // 09AE : + + void * param; // 09B0 : User parameter + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4 + void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8 + + unsigned short offs09BC[0x204]; // 09BC : + unsigned long offs0DC4; // 0DC4 : + unsigned short offs0DC8[0x900]; // 0DC8 : + unsigned short offs1FC8; // 1FC8 : + char out_buff[0x802]; // 1FCA : Output (compressed) data + unsigned char work_buff[0x2204]; // 27CC : Work buffer + // + DICT_OFFSET => Dictionary + // + UNCMP_OFFSET => Uncompressed data + unsigned short offs49D0[0x2000]; // 49D0 : +} TCmpStruct; + +#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression buffer + + +// Decompression structure +typedef struct +{ + unsigned long offs0000; // 0000 + unsigned long ctype; // 0004 - Compression type (CMP_BINARY or CMP_ASCII) + unsigned long outputPos; // 0008 - Position in output buffer + unsigned long dsize_bits; // 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) + unsigned long dsize_mask; // 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) + unsigned long bit_buff; // 0014 - 16-bit buffer for processing input data + unsigned long extra_bits; // 0018 - Number of extra (above 8) bits in bit buffer + unsigned int in_pos; // 001C - Position in in_buff + unsigned long in_bytes; // 0020 - Number of bytes in input buffer + void * param; // 0024 - Custom parameter + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 0028 + void (*write_buf)(char *buf, unsigned int *size, void *param);// 002C + unsigned char out_buff[0x2000]; // 0030 - Output circle buffer. Starting position is 0x1000 + unsigned char offs2030[0x204]; // 2030 - ??? + unsigned char in_buff[0x800]; // 2234 - Buffer for data to be decompressed + unsigned char position1[0x100]; // 2A34 - Positions in buffers + unsigned char position2[0x100]; // 2B34 - Positions in buffers + unsigned char offs2C34[0x100]; // 2C34 - Buffer for + unsigned char offs2D34[0x100]; // 2D34 - Buffer for + unsigned char offs2E34[0x80]; // 2EB4 - Buffer for + unsigned char offs2EB4[0x100]; // 2EB4 - Buffer for + unsigned char ChBitsAsc[0x100]; // 2FB4 - Buffer for + unsigned char DistBits[0x40]; // 30B4 - Numbers of bytes to skip copied block length + unsigned char LenBits[0x10]; // 30F4 - Numbers of bits for skip copied block length + unsigned char ExLenBits[0x10]; // 3104 - Number of valid bits for copied block + unsigned short LenBase[0x10]; // 3114 - Buffer for +} TDcmpStruct; + +#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompress buffer + +//----------------------------------------------------------------------------- +// Public functions + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int PKEXPORT implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int PKEXPORT explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +// The original name "crc32" was changed to "crc32pk" due +// to compatibility with zlib +unsigned long PKEXPORT crc32pk(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + +#endif // __PKLIB_H__ diff --git a/contrib/vmap_extractor_v2/stormlib/wave/wave.cpp b/contrib/vmap_extractor_v2/stormlib/wave/wave.cpp new file mode 100644 index 000000000..936525f4e --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/wave/wave.cpp @@ -0,0 +1,356 @@ +/*****************************************************************************/ +/* wave.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This module contains decompression methods used by Storm.dll to decompress*/ +/* WAVe files. Thanks to Tom Amigo for releasing his sources. */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ +/* 20.05.03 2.00 Lad Added compression */ +/* 19.11.03 2.01 Dan Big endian handling */ +/*****************************************************************************/ + +#include "wave.h" + +//------------------------------------------------------------------------------ +// Structures + +union TByteAndWordPtr +{ + short * pw; + unsigned char * pb; +}; + +union TWordAndByteArray +{ + short w; + unsigned char b[2]; +}; + +//----------------------------------------------------------------------------- +// Tables necessary dor decompression + +static long Table1503F120[] = +{ + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, + 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008 +}; + +static long Table1503F1A0[] = +{ + 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, + 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F, + 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042, + 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F, + 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133, + 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292, + 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583, + 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0, + 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954, + 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B, + 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462, + 0x00007FFF +}; + +//---------------------------------------------------------------------------- +// CompressWave + +// 1500EF70 +int CompressWave(unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nChannels, int nCmpLevel) +// ECX EDX +{ + TWordAndByteArray Wcmp; + TByteAndWordPtr out; // Pointer to the output buffer + long SInt32Array1[2]; + long SInt32Array2[2]; + long SInt32Array3[2]; + long nBytesRemains = dwOutLength; // Number of bytes remaining + long nWordsRemains; // Number of words remaining +// unsigned char * pbSaveOutBuffer; // Copy of output buffer (actually not used) + unsigned long dwBitBuff; + unsigned long dwStopBit; + unsigned long dwBit; + unsigned long ebx; + unsigned long esi; + long nTableValue; + long nOneWord; + long var_1C; + long var_2C; + int nLength; + int nIndex; + int nValue; + + // If less than 2 bytes remain, don't decompress anything +// pbSaveOutBuffer = pbOutBuffer; + out.pb = pbOutBuffer; + if(nBytesRemains < 2) + return 2; + + Wcmp.b[1] = (unsigned char)(nCmpLevel - 1); + Wcmp.b[0] = (unsigned char)0; + + *out.pw++ = BSWAP_INT16_SIGNED(Wcmp.w); + if((out.pb - pbOutBuffer + (nChannels * 2)) > nBytesRemains) + return (int)(out.pb - pbOutBuffer + (nChannels * 2)); + + SInt32Array1[0] = SInt32Array1[1] = 0x2C; + + for(int i = 0; i < nChannels; i++) + { + nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); + *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord); + SInt32Array2[i] = nOneWord; + } + + // Weird. But it's there + nLength = dwInLength; + if(nLength < 0) // mov eax, dwInLength; cdq; sub eax, edx; + nLength++; + + nLength = (nLength / 2) - (int)(out.pb - pbOutBuffer); + nLength = (nLength < 0) ? 0 : nLength; + + nIndex = nChannels - 1; // edi + nWordsRemains = dwInLength / 2; // eax + + // ebx - nChannels + // ecx - pwOutPos + for(int chnl = nChannels; chnl < nWordsRemains; chnl++) + { + // 1500F030 + if((out.pb - pbOutBuffer + 2) > nBytesRemains) + return (int)(out.pb - pbOutBuffer + 2); + + // Switch index + if(nChannels == 2) + nIndex = (nIndex == 0) ? 1 : 0; + + // Load one word from the input stream + nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); // ecx - nOneWord + SInt32Array3[nIndex] = nOneWord; + + // esi - SInt32Array2[nIndex] + // eax - nValue + nValue = nOneWord - SInt32Array2[nIndex]; + nValue = (nValue < 0) ? ((nValue ^ 0xFFFFFFFF) + 1) : nValue; + + ebx = (nOneWord >= SInt32Array2[nIndex]) ? 0 : 0x40; + + // esi - SInt32Array2[nIndex] + // edx - Table1503F1A0[SInt32Array2[nIndex]] + // edi - (Table1503F1A0[SInt32Array1[nIndex]] >> nCmpLevel) + nTableValue = Table1503F1A0[SInt32Array1[nIndex]]; + dwStopBit = (unsigned long)nCmpLevel; + + // edi - nIndex; + if(nValue < (nTableValue >> nCmpLevel)) + { + if(SInt32Array1[nIndex] != 0) + SInt32Array1[nIndex]--; + *out.pb++ = 0x80; + } + else + { + while(nValue > nTableValue * 2) + { + if(SInt32Array1[nIndex] >= 0x58 || nLength == 0) + break; + + SInt32Array1[nIndex] += 8; + if(SInt32Array1[nIndex] > 0x58) + SInt32Array1[nIndex] = 0x58; + + nTableValue = Table1503F1A0[SInt32Array1[nIndex]]; + *out.pb++ = 0x81; + nLength--; + } + + var_2C = nTableValue >> Wcmp.b[1]; + dwBitBuff = 0; + + esi = (1 << (dwStopBit - 2)); + dwStopBit = (esi <= 0x20) ? esi : 0x20; + + for(var_1C = 0, dwBit = 1; ; dwBit <<= 1) + { +// esi = var_1C + nTableValue; + if((var_1C + nTableValue) <= nValue) + { + var_1C += nTableValue; + dwBitBuff |= dwBit; + } + if(dwBit == dwStopBit) + break; + + nTableValue >>= 1; + } + + nValue = SInt32Array2[nIndex]; + if(ebx != 0) + { + nValue -= (var_1C + var_2C); + if(nValue < -32768) + nValue = -32768; + } + else + { + nValue += (var_1C + var_2C); + if(nValue > 32767) + nValue = 32767; + } + + SInt32Array2[nIndex] = nValue; + *out.pb++ = (unsigned char)(dwBitBuff | ebx); + nTableValue = Table1503F120[dwBitBuff & 0x1F]; + SInt32Array1[nIndex] = SInt32Array1[nIndex] + nTableValue; + if(SInt32Array1[nIndex] < 0) + SInt32Array1[nIndex] = 0; + else if(SInt32Array1[nIndex] > 0x58) + SInt32Array1[nIndex] = 0x58; + } + } + + return (int)(out.pb - pbOutBuffer); +} + +//---------------------------------------------------------------------------- +// DecompressWave + +// 1500F230 +int DecompressWave(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels) +{ + TByteAndWordPtr out; // Output buffer + TByteAndWordPtr in; + unsigned char * pbInBufferEnd = (pbInBuffer + dwInLength); + long SInt32Array1[2]; + long SInt32Array2[2]; + long nOneWord; + int dwOutLengthCopy = dwOutLength; + int nIndex; + + SInt32Array1[0] = SInt32Array1[1] = 0x2C; + out.pb = pbOutBuffer; + in.pb = pbInBuffer; + in.pw++; + + // Fill the Uint32Array2 array by channel values. + for(int i = 0; i < nChannels; i++) + { + nOneWord = BSWAP_INT16_SIGNED(*in.pw++); + SInt32Array2[i] = nOneWord; + if(dwOutLengthCopy < 2) + return (int)(out.pb - pbOutBuffer); + + *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord); + dwOutLengthCopy -= sizeof(short); + } + + // Get the initial index + nIndex = nChannels - 1; + + // Perform the decompression + while(in.pb < pbInBufferEnd) + { + unsigned char nOneByte = *in.pb++; + + // Switch index + if(nChannels == 2) + nIndex = (nIndex == 0) ? 1 : 0; + + // 1500F2A2: Get one byte from input buffer + if(nOneByte & 0x80) + { + switch(nOneByte & 0x7F) + { + case 0: // 1500F315 + if(SInt32Array1[nIndex] != 0) + SInt32Array1[nIndex]--; + + if(dwOutLengthCopy < 2) + return (int)(out.pb - pbOutBuffer); + + *out.pw++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2[nIndex]); + dwOutLength -= sizeof(unsigned short); + break; + + case 1: // 1500F2E8 + SInt32Array1[nIndex] += 8; + if(SInt32Array1[nIndex] > 0x58) + SInt32Array1[nIndex] = 0x58; + + if(nChannels == 2) + nIndex = (nIndex == 0) ? 1 : 0; + break; + + case 2: // 1500F41E + break; + + default: // 1500F2C4 + SInt32Array1[nIndex] -= 8; + if(SInt32Array1[nIndex] < 0) + SInt32Array1[nIndex] = 0; + + if(nChannels == 2) + nIndex = (nIndex == 0) ? 1 : 0; + break; + } + } + else + { + // 1500F349 + long temp1 = Table1503F1A0[SInt32Array1[nIndex]]; // EDI + long temp2 = temp1 >> pbInBuffer[1]; // ESI + long temp3 = SInt32Array2[nIndex]; // ECX + + if(nOneByte & 0x01) // EBX = nOneByte + temp2 += (temp1 >> 0); + + if(nOneByte & 0x02) + temp2 += (temp1 >> 1); + + if(nOneByte & 0x04) + temp2 += (temp1 >> 2); + + if(nOneByte & 0x08) + temp2 += (temp1 >> 3); + + if(nOneByte & 0x10) + temp2 += (temp1 >> 4); + + if(nOneByte & 0x20) + temp2 += (temp1 >> 5); + + if(nOneByte & 0x40) + { + temp3 = temp3 - temp2; + if(temp3 <= -32768) + temp3 = -32768; + } + else + { + temp3 = temp3 + temp2; + if(temp3 >= 32767) + temp3 = 32767; + } + + SInt32Array2[nIndex] = temp3; + if(dwOutLength < 2) + break; + + // Store the output 16-bit value + *out.pw++ = BSWAP_INT16_SIGNED((short)SInt32Array2[nIndex]); + dwOutLength -= 2; + + SInt32Array1[nIndex] += Table1503F120[nOneByte & 0x1F]; + + if(SInt32Array1[nIndex] < 0) + SInt32Array1[nIndex] = 0; + else if(SInt32Array1[nIndex] > 0x58) + SInt32Array1[nIndex] = 0x58; + } + } + return (int)(out.pb - pbOutBuffer); +} diff --git a/contrib/vmap_extractor_v2/stormlib/wave/wave.h b/contrib/vmap_extractor_v2/stormlib/wave/wave.h new file mode 100644 index 000000000..81b5add9c --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/wave/wave.h @@ -0,0 +1,22 @@ +/*****************************************************************************/ +/* Wave.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Header file for WAVe unplode functions */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 31.03.03 1.00 Lad The first version of Wave.h */ +/*****************************************************************************/ + +#ifndef __WAVE_H__ +#define __WAVE_H__ + +//----------------------------------------------------------------------------- +// Functions + +#include "../StormPort.h" + +int CompressWave (unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nCmpType, int nChannels); +int DecompressWave(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels); + +#endif // __WAVE_H__ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog b/contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog new file mode 100644 index 000000000..bf2e3f925 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog @@ -0,0 +1,481 @@ + + ChangeLog file for zlib + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occuring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/FAQ b/contrib/vmap_extractor_v2/stormlib/zlib/FAQ new file mode 100644 index 000000000..47a7d60c6 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/FAQ @@ -0,0 +1,100 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. If you + want a precompiled DLL, see http://www.winimage.com/zLibDll/ . Questions + about the zlib DLL should be sent to Gilles Vollant (info@winimage.com). + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.winimage.com/zLibDll/cmp-z-it.zip + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage + are in the files example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the directories contrib/delphi and contrib/delphi2 in the zlib + distribution. + +11. Can zlib handle .zip archives? + + See the directory contrib/minizip in the zlib distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. Why does "make test" fail on Mac OS X? + + Mac OS X already includes zlib as a shared library, and so -lz links the + shared library instead of the one that the "make" compiled. For zlib + 1.1.3, the two are incompatible due to different compile-time + options. Simply change the -lz in the Makefile to libz.a, and it will use + the compiled library instead of the shared one and the "make test" will + succeed. + +15. I have a question about OttoPDF + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site Joel Hainley jhainley@myndkryme.com. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/INDEX b/contrib/vmap_extractor_v2/stormlib/zlib/INDEX new file mode 100644 index 000000000..8a2457664 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/INDEX @@ -0,0 +1,86 @@ +ChangeLog history of changes +INDEX this file +FAQ Frequently Asked Questions about zlib +Make_vms.com script for Vax/VMS +Makefile makefile for Unix (generated by configure) +Makefile.in makefile for Unix (template for configure) +Makefile.riscos makefile for RISCOS +README guess what +algorithm.txt description of the (de)compression algorithm +configure configure script for Unix +descrip.mms makefile for Vax/VMS +zlib.3 mini man page for zlib (volunteers to write full + man pages from zlib.h welcome. write to jloup@gzip.org) + +amiga/Makefile.sas makefile for Amiga SAS/C +amiga/Makefile.pup makefile for Amiga powerUP SAS/C PPC + +msdos/Makefile.w32 makefile for Microsoft Visual C++ 32-bit +msdos/Makefile.b32 makefile for Borland C++ 32-bit +msdos/Makefile.bor makefile for Borland C/C++ 16-bit +msdos/Makefile.dj2 makefile for DJGPP 2.x +msdos/Makefile.emx makefile for EMX 0.9c (32-bit DOS/OS2) +msdos/Makefile.msc makefile for Microsoft C 16-bit +msdos/Makefile.tc makefile for Turbo C +msdos/Makefile.wat makefile for Watcom C +msdos/zlib.def definition file for Windows DLL +msdos/zlib.rc definition file for Windows DLL + +nt/Makefile.nt makefile for Windows NT +nt/zlib.dnt definition file for Windows NT DLL +nt/Makefile.emx makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel) +nt/Makefile.gcc makefile for Windows NT using GCC (mingw32) + + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +deflate.c +deflate.h +gzio.c +infblock.c +infblock.h +infcodes.c +infcodes.h +inffast.c +inffast.h +inflate.c +inftrees.c +inftrees.h +infutil.c +infutil.h +maketree.c +trees.c +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c + + unsupported contribution by third parties + +contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + +contrib/minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + See http://www.winimage.com/zLibDll/unzip.html + +contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz extractor using zlib + +contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos b/contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos new file mode 100644 index 000000000..d97f44923 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos @@ -0,0 +1,151 @@ +# Project: zlib_1_03 +# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 +# test works out-of-the-box, installs `somewhere' on demand + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + +# change the line below to where _you_ want the library installed. +libdest = lib:zlib + +# Final targets: +@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompr @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompr @.o.zutil +test: @.minigzip @.example @.lib + @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV + @echo running tests: hang on. + @/@.minigzip -f -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -f -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -1 libc + @/@.minigzip -d libc-gz + @diff @.lib @.libc + @echo that should have reported '@.lib and @.libc identical' if you have diff. + @/@.example @.fred @.fred + @echo that will have given lots of hello!'s. + +@.minigzip: @.o.minigzip @.lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs +@.example: @.o.example @.lib C:o.Stubs + Link $(Linkflags) @.o.example @.lib C:o.Stubs + +install: @.lib + cdir $(libdest) + cdir $(libdest).h + @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV + @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV + @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV + @echo okay, installed zlib in $(libdest) + +clean:; remove @.minigzip + remove @.example + remove @.libc + -wipe @.o.* F~r~cV + remove @.fred + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: + +# Dynamic dependencies: +o.example: c.example +o.example: h.zlib +o.example: h.zconf +o.minigzip: c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.adler32: c.adler32 +o.adler32: h.zlib +o.adler32: h.zconf +o.compress: c.compress +o.compress: h.zlib +o.compress: h.zconf +o.crc32: c.crc32 +o.crc32: h.zlib +o.crc32: h.zconf +o.deflate: c.deflate +o.deflate: h.deflate +o.deflate: h.zutil +o.deflate: h.zlib +o.deflate: h.zconf +o.gzio: c.gzio +o.gzio: h.zutil +o.gzio: h.zlib +o.gzio: h.zconf +o.infblock: c.infblock +o.infblock: h.zutil +o.infblock: h.zlib +o.infblock: h.zconf +o.infblock: h.infblock +o.infblock: h.inftrees +o.infblock: h.infcodes +o.infblock: h.infutil +o.infcodes: c.infcodes +o.infcodes: h.zutil +o.infcodes: h.zlib +o.infcodes: h.zconf +o.infcodes: h.inftrees +o.infcodes: h.infblock +o.infcodes: h.infcodes +o.infcodes: h.infutil +o.infcodes: h.inffast +o.inffast: c.inffast +o.inffast: h.zutil +o.inffast: h.zlib +o.inffast: h.zconf +o.inffast: h.inftrees +o.inffast: h.infblock +o.inffast: h.infcodes +o.inffast: h.infutil +o.inffast: h.inffast +o.inflate: c.inflate +o.inflate: h.zutil +o.inflate: h.zlib +o.inflate: h.zconf +o.inflate: h.infblock +o.inftrees: c.inftrees +o.inftrees: h.zutil +o.inftrees: h.zlib +o.inftrees: h.zconf +o.inftrees: h.inftrees +o.inftrees: h.inffixed +o.infutil: c.infutil +o.infutil: h.zutil +o.infutil: h.zlib +o.infutil: h.zconf +o.infutil: h.infblock +o.infutil: h.inftrees +o.infutil: h.infcodes +o.infutil: h.infutil +o.trees: c.trees +o.trees: h.deflate +o.trees: h.zutil +o.trees: h.zlib +o.trees: h.zconf +o.trees: h.trees +o.uncompr: c.uncompr +o.uncompr: h.zlib +o.uncompr: h.zconf +o.zutil: c.zutil +o.zutil: h.zutil +o.zutil: h.zlib +o.zutil: h.zconf diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/README b/contrib/vmap_extractor_v2/stormlib/zlib/README new file mode 100644 index 000000000..29d67146a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/README @@ -0,0 +1,147 @@ +zlib 1.1.4 is a general purpose data compression library. All the code +is thread safe. The data format used by the zlib library +is described by RFCs (Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate +format) and rfc1952.txt (gzip format). These documents are also available in +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage +example of the library is given in the file example.c which also tests that +the library is working correctly. Another example is given in the file +minigzip.c. The compression library itself is composed of all source files +except example.c and minigzip.c. + +To compile all files and run the test program, follow the instructions +given at the top of Makefile. In short "make test; make install" +should work for most machines. For Unix: "./configure; make test; make install" +For MSDOS, use one of the special makefiles such as Makefile.msc. +For VMS, use Make_vms.com or descrip.mms. + +Questions about zlib should be sent to , or to +Gilles Vollant for the Windows DLL version. +The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ +Before reporting a problem, please check this site to verify that +you have the latest version of zlib; otherwise get the latest version and +check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html +before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.1.4 are documented in the file ChangeLog. +The only changes made since 1.1.3 are bug corrections: + +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +The beta version 1.1.5beta includes many more changes. A new official +version 1.1.5 will be released as soon as extensive testing has been +completed on it. + + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess +is in the CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling +is available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html + +An experimental package to read and write files in .zip format, +written on top of zlib by Gilles Vollant , is +available at http://www.winimage.com/zLibDll/unzip.html +and also in the contrib/minizip directory of zlib. + + +Notes for some targets: + +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL + The zlib DLL support was initially done by Alessandro Iacopetti and is + now maintained by Gilles Vollant . Check the zlib DLL + home page at http://www.winimage.com/zLibDll + + From Visual Basic, you can call the DLL functions which do not take + a structure as argument: compress, uncompress and all gz* functions. + See contrib/visual-basic.txt for more information, or get + http://www.tcfb.com/dowseware/cmp-z-it.zip + +- For 64-bit Irix, deflate.c must be compiled without any optimization. + With -O, one libpng test fails. The test works in 32 bit mode (with + the -n32 compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 + it works when compiled with cc. + +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 + is necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works + with other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For Turbo C the small model is supported only with reduced performance to + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 + +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html + Per Harald Myrvang + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/adler32.c b/contrib/vmap_extractor_v2/stormlib/zlib/adler32.c new file mode 100644 index 000000000..fae88b655 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/adler32.c @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt b/contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt new file mode 100644 index 000000000..cdc830b5d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt @@ -0,0 +1,213 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The real question is, given a Huffman tree, how to decode fast. The most +important realization is that shorter codes are much more common than +longer codes, so pay attention to decoding the short codes fast, and let +the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and set it +for the maximum speed. + +inflate() sends new trees relatively often, so it is possibly set for a +smaller first level table than an application that has only one tree for +all the data. For inflate, which has 286 possible codes for the +literal/length tree, the size of the first table is nine bits. Also the +distance trees have 30 possible values, and the size of the first table is +six bits. Note that for each of those cases, the table ended up one bit +longer than the ``average'' code length, i.e. the code length of an +approximately flat code which would be a little more than eight bits for +286 symbols and a little less than five bits for 30 symbols. It would be +interesting to see if optimizing the first level table for other +applications gave values within a bit or two of the flat code size. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode to and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +ftp://ds.internic.net/rfc/rfc1951.txt diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup b/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup new file mode 100644 index 000000000..6cfad1dc0 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup @@ -0,0 +1,66 @@ +# Amiga powerUP (TM) Makefile +# makefile for libpng and SAS C V6.58/7.00 PPC compiler +# Copyright (C) 1998 by Andreas R. Kleinert + +CC = scppc +CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \ + OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 +LIBNAME = libzip.a +AR = ppc-amigaos-ar +AR_FLAGS = cr +RANLIB = ppc-amigaos-ranlib +LDFLAGS = -r -o +LDLIBS = LIB:scppc.a +LN = ppc-amigaos-ld +RM = delete quiet + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example minigzip + +test: all + example + echo hello world | minigzip | minigzip -d + +$(LIBNAME): $(OBJS) + $(AR) $(AR_FLAGS) $@ $(OBJS) + $(RANLIB) $@ + +example: example.o $(LIBNAME) + $(LN) $(LDFLAGS) example LIB:c_ppc.o example.o $(LIBNAME) $(LDLIBS) LIB:end.o + +minigzip: minigzip.o $(LIBNAME) + $(LN) $(LDFLAGS) minigzip LIB:c_ppc.o minigzip.o $(LIBNAME) $(LDLIBS) LIB:end.o + +clean: + $(RM) *.o example minigzip $(LIBNAME) foo.gz + +zip: + zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ + descrip.mms *.[ch] + +tgz: + cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ + zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zutil.h zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas b/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas new file mode 100644 index 000000000..5323e8217 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas @@ -0,0 +1,64 @@ +# SMakefile for zlib +# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly +# Osma Ahvenlampi +# Amiga, SAS/C 6.56 & Smake + +CC=sc +CFLAGS=OPT +#CFLAGS=OPT CPU=68030 +#CFLAGS=DEBUG=LINE +LDFLAGS=LIB z.lib + +SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ + NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: SCOPTIONS example minigzip + +test: all + `cd`/example + echo hello world | minigzip | minigzip -d + +install: z.lib + copy zlib.h zconf.h INCLUDE: clone + copy z.lib LIB: clone + +z.lib: $(OBJS) + oml z.lib r $(OBJS) + +example: example.o z.lib + $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) + +minigzip: minigzip.o z.lib + $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) + +clean: + -delete force quiet *.o example minigzip z.lib foo.gz *.lnk SCOPTIONS + +SCOPTIONS: Smakefile + copy to $@ 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib new file mode 100644 index 000000000..7ad191cf5 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib @@ -0,0 +1,34 @@ +All files under this contrib directory are UNSUPPORTED. There were +provided by users of zlib and were not tested by the authors of zlib. +Use at your own risk. Please contact the authors of the contributions +for help about these, not the zlib authors. Thanks. + + +asm386/ by Gilles Vollant + 386 asm code replacing longest_match(), for Visual C++ 4.2 and ML 6.11c + +asm586/ and asm686/ by Brian Raiter + asm code for Pentium and Pentium Pro + See http://www.muppetlabs.com/~breadbox/software/assembly.html + +delphi/ by Bob Dellaca + Support for Delphi + +delphi2/ by Davide Moretti + Another support for C++Builder and Delphi + +minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + See http://www.winimage.com/zLibDll/unzip.html + +iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + +visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm new file mode 100644 index 000000000..28d527f47 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm @@ -0,0 +1,559 @@ +; +; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86 +; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. +; File written by Gilles Vollant, by modifiying the longest_match +; from Jean-loup Gailly in deflate.c +; It need wmask == 0x7fff +; (assembly code is faster with a fixed wmask) +; +; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK) +; I compile with : "ml /coff /Zi /c gvmat32.asm" +; + +;uInt longest_match_7fff(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ + + NbStack equ 76 + cur_match equ dword ptr[esp+NbStack-0] + str_s equ dword ptr[esp+NbStack-4] +; 5 dword on top (ret,ebp,esi,edi,ebx) + adrret equ dword ptr[esp+NbStack-8] + pushebp equ dword ptr[esp+NbStack-12] + pushedi equ dword ptr[esp+NbStack-16] + pushesi equ dword ptr[esp+NbStack-20] + pushebx equ dword ptr[esp+NbStack-24] + + chain_length equ dword ptr [esp+NbStack-28] + limit equ dword ptr [esp+NbStack-32] + best_len equ dword ptr [esp+NbStack-36] + window equ dword ptr [esp+NbStack-40] + prev equ dword ptr [esp+NbStack-44] + scan_start equ word ptr [esp+NbStack-48] + wmask equ dword ptr [esp+NbStack-52] + match_start_ptr equ dword ptr [esp+NbStack-56] + nice_match equ dword ptr [esp+NbStack-60] + scan equ dword ptr [esp+NbStack-64] + + windowlen equ dword ptr [esp+NbStack-68] + match_start equ dword ptr [esp+NbStack-72] + strend equ dword ptr [esp+NbStack-76] + NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure + dep_chain_length equ 70h+4 + dep_window equ 2ch+4 + dep_strstart equ 60h+4 + dep_prev_length equ 6ch+4 + dep_nice_match equ 84h+4 + dep_w_size equ 20h+4 + dep_prev equ 34h+4 + dep_w_mask equ 28h+4 + dep_good_match equ 80h+4 + dep_match_start equ 64h+4 + dep_lookahead equ 68h+4 + + +_TEXT segment + +IFDEF NOUNDERLINE + public longest_match_7fff +; public match_init +ELSE + public _longest_match_7fff +; public _match_init +ENDIF + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + +IFDEF NOUNDERLINE +;match_init proc near +; ret +;match_init endp +ELSE +;_match_init proc near +; ret +;_match_init endp +ENDIF + + +IFDEF NOUNDERLINE +longest_match_7fff proc near +ELSE +_longest_match_7fff proc near +ENDIF + + mov edx,[esp+4] + + + + push ebp + push edi + push esi + push ebx + + sub esp,NbStackAdd + +; initialize or check the variables used in match.asm. + mov ebp,edx + +; chain_length = s->max_chain_length +; if (prev_length>=good_match) chain_length >>= 2 + mov edx,[ebp+dep_chain_length] + mov ebx,[ebp+dep_prev_length] + cmp [ebp+dep_good_match],ebx + ja noshr + shr edx,2 +noshr: +; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop + inc edx + mov edi,[ebp+dep_nice_match] + mov chain_length,edx + mov eax,[ebp+dep_lookahead] + cmp eax,edi +; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + jae nolookaheadnicematch + mov edi,eax +nolookaheadnicematch: +; best_len = s->prev_length + mov best_len,ebx + +; window = s->window + mov esi,[ebp+dep_window] + mov ecx,[ebp+dep_strstart] + mov window,esi + + mov nice_match,edi +; scan = window + strstart + add esi,ecx + mov scan,esi +; dx = *window + mov dx,word ptr [esi] +; bx = *(window+best_len-1) + mov bx,word ptr [esi+ebx-1] + add esi,MAX_MATCH-1 +; scan_start = *scan + mov scan_start,dx +; strend = scan + MAX_MATCH-1 + mov strend,esi +; bx = scan_end = *(window+best_len-1) + +; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +; s->strstart - (IPos)MAX_DIST(s) : NIL; + + mov esi,[ebp+dep_w_size] + sub esi,MIN_LOOKAHEAD +; here esi = MAX_DIST(s) + sub ecx,esi + ja nodist + xor ecx,ecx +nodist: + mov limit,ecx + +; prev = s->prev + mov edx,[ebp+dep_prev] + mov prev,edx + +; + mov edx,dword ptr [ebp+dep_match_start] + mov bp,scan_start + mov eax,cur_match + mov match_start,edx + + mov edx,window + mov edi,edx + add edi,best_len + mov esi,prev + dec edi +; windowlen = window + best_len -1 + mov windowlen,edi + + jmp beginloop2 + align 4 + +; here, in the loop +; eax = ax = cur_match +; ecx = limit +; bx = scan_end +; bp = scan_start +; edi = windowlen (window + best_len -1) +; esi = prev + + +;// here; chain_length <=16 +normalbeg0add16: + add chain_length,16 + jz exitloop +normalbeg0: + cmp word ptr[edi+eax],bx + je normalbeg2noroll +rcontlabnoroll: +; cur_match = prev[cur_match & wmask] + and eax,7fffh + mov ax,word ptr[esi+eax*2] +; if cur_match > limit, go to exitloop + cmp ecx,eax + jnb exitloop +; if --chain_length != 0, go to exitloop + dec chain_length + jnz normalbeg0 + jmp exitloop + +normalbeg2noroll: +; if (scan_start==*(cur_match+window)) goto normalbeg2 + cmp bp,word ptr[edx+eax] + jne rcontlabnoroll + jmp normalbeg2 + +contloop3: + mov edi,windowlen + +; cur_match = prev[cur_match & wmask] + and eax,7fffh + mov ax,word ptr[esi+eax*2] +; if cur_match > limit, go to exitloop + cmp ecx,eax +jnbexitloopshort1: + jnb exitloop +; if --chain_length != 0, go to exitloop + + +; begin the main loop +beginloop2: + sub chain_length,16+1 +; if chain_length <=16, don't use the unrolled loop + jna normalbeg0add16 + +do16: + cmp word ptr[edi+eax],bx + je normalbeg2dc0 + +maccn MACRO lab + and eax,7fffh + mov ax,word ptr[esi+eax*2] + cmp ecx,eax + jnb exitloop + cmp word ptr[edi+eax],bx + je lab + ENDM + +rcontloop0: + maccn normalbeg2dc1 + +rcontloop1: + maccn normalbeg2dc2 + +rcontloop2: + maccn normalbeg2dc3 + +rcontloop3: + maccn normalbeg2dc4 + +rcontloop4: + maccn normalbeg2dc5 + +rcontloop5: + maccn normalbeg2dc6 + +rcontloop6: + maccn normalbeg2dc7 + +rcontloop7: + maccn normalbeg2dc8 + +rcontloop8: + maccn normalbeg2dc9 + +rcontloop9: + maccn normalbeg2dc10 + +rcontloop10: + maccn short normalbeg2dc11 + +rcontloop11: + maccn short normalbeg2dc12 + +rcontloop12: + maccn short normalbeg2dc13 + +rcontloop13: + maccn short normalbeg2dc14 + +rcontloop14: + maccn short normalbeg2dc15 + +rcontloop15: + and eax,7fffh + mov ax,word ptr[esi+eax*2] + cmp ecx,eax + jnb exitloop + + sub chain_length,16 + ja do16 + jmp normalbeg0add16 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +normbeg MACRO rcontlab,valsub +; if we are here, we know that *(match+best_len-1) == scan_end + cmp bp,word ptr[edx+eax] +; if (match != scan_start) goto rcontlab + jne rcontlab +; calculate the good chain_length, and we'll compare scan and match string + add chain_length,16-valsub + jmp iseq + ENDM + + +normalbeg2dc11: + normbeg rcontloop11,11 + +normalbeg2dc12: + normbeg short rcontloop12,12 + +normalbeg2dc13: + normbeg short rcontloop13,13 + +normalbeg2dc14: + normbeg short rcontloop14,14 + +normalbeg2dc15: + normbeg short rcontloop15,15 + +normalbeg2dc10: + normbeg rcontloop10,10 + +normalbeg2dc9: + normbeg rcontloop9,9 + +normalbeg2dc8: + normbeg rcontloop8,8 + +normalbeg2dc7: + normbeg rcontloop7,7 + +normalbeg2dc6: + normbeg rcontloop6,6 + +normalbeg2dc5: + normbeg rcontloop5,5 + +normalbeg2dc4: + normbeg rcontloop4,4 + +normalbeg2dc3: + normbeg rcontloop3,3 + +normalbeg2dc2: + normbeg rcontloop2,2 + +normalbeg2dc1: + normbeg rcontloop1,1 + +normalbeg2dc0: + normbeg rcontloop0,0 + + +; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end + +normalbeg2: + mov edi,window + + cmp bp,word ptr[edi+eax] + jne contloop3 ; if *(ushf*)match != scan_start, continue + +iseq: +; if we are here, we know that *(match+best_len-1) == scan_end +; and (match == scan_start) + + mov edi,edx + mov esi,scan ; esi = scan + add edi,eax ; edi = window + cur_match = match + + mov edx,[esi+3] ; compare manually dword at match+3 + xor edx,[edi+3] ; and scan +3 + + jz begincompare ; if equal, go to long compare + +; we will determine the unmatch byte and calculate len (in esi) + or dl,dl + je eq1rr + mov esi,3 + jmp trfinval +eq1rr: + or dx,dx + je eq1 + + mov esi,4 + jmp trfinval +eq1: + and edx,0ffffffh + jz eq11 + mov esi,5 + jmp trfinval +eq11: + mov esi,6 + jmp trfinval + +begincompare: + ; here we now scan and match begin same + add edi,6 + add esi,6 + mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes + repe cmpsd ; loop until mismatch + + je trfin ; go to trfin if not unmatch +; we determine the unmatch byte + sub esi,4 + mov edx,[edi-4] + xor edx,[esi] + + or dl,dl + jnz trfin + inc esi + + or dx,dx + jnz trfin + inc esi + + and edx,0ffffffh + jnz trfin + inc esi + +trfin: + sub esi,scan ; esi = len +trfinval: +; here we have finised compare, and esi contain len of equal string + cmp esi,best_len ; if len > best_len, go newbestlen + ja short newbestlen +; now we restore edx, ecx and esi, for the big loop + mov esi,prev + mov ecx,limit + mov edx,window + jmp contloop3 + +newbestlen: + mov best_len,esi ; len become best_len + + mov match_start,eax ; save new position as match_start + cmp esi,nice_match ; if best_len >= nice_match, exit + jae exitloop + mov ecx,scan + mov edx,window ; restore edx=window + add ecx,esi + add esi,edx + + dec esi + mov windowlen,esi ; windowlen = window + best_len-1 + mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end + +; now we restore ecx and esi, for the big loop : + mov esi,prev + mov ecx,limit + jmp contloop3 + +exitloop: +; exit : s->match_start=match_start + mov ebx,match_start + mov ebp,str_s + mov ecx,best_len + mov dword ptr [ebp+dep_match_start],ebx + mov eax,dword ptr [ebp+dep_lookahead] + cmp ecx,eax + ja minexlo + mov eax,ecx +minexlo: +; return min(best_len,s->lookahead) + +; restore stack and register ebx,esi,edi,ebp + add esp,NbStackAdd + + pop ebx + pop esi + pop edi + pop ebp + ret +InfoAuthor: +; please don't remove this string ! +; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary! + db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah + + + +IFDEF NOUNDERLINE +longest_match_7fff endp +ELSE +_longest_match_7fff endp +ENDIF + + +IFDEF NOUNDERLINE +cpudetect32 proc near +ELSE +_cpudetect32 proc near +ENDIF + + + pushfd ; push original EFLAGS + pop eax ; get original EFLAGS + mov ecx, eax ; save original EFLAGS + xor eax, 40000h ; flip AC bit in EFLAGS + push eax ; save new EFLAGS value on stack + popfd ; replace current EFLAGS value + pushfd ; get new EFLAGS + pop eax ; store new EFLAGS in EAX + xor eax, ecx ; can’t toggle AC bit, processor=80386 + jz end_cpu_is_386 ; jump if 80386 processor + push ecx + popfd ; restore AC bit in EFLAGS first + + pushfd + pushfd + pop ecx + + mov eax, ecx ; get original EFLAGS + xor eax, 200000h ; flip ID bit in EFLAGS + push eax ; save new EFLAGS value on stack + popfd ; replace current EFLAGS value + pushfd ; get new EFLAGS + pop eax ; store new EFLAGS in EAX + popfd ; restore original EFLAGS + xor eax, ecx ; can’t toggle ID bit, + je is_old_486 ; processor=old + + mov eax,1 + db 0fh,0a2h ;CPUID + +exitcpudetect: + ret + +end_cpu_is_386: + mov eax,0300h + jmp exitcpudetect + +is_old_486: + mov eax,0400h + jmp exitcpudetect + +IFDEF NOUNDERLINE +cpudetect32 endp +ELSE +_cpudetect32 endp +ENDIF + +_TEXT ends +end diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c new file mode 100644 index 000000000..d853bb7ce --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c @@ -0,0 +1,200 @@ +/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86 + * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. + * File written by Gilles Vollant, by modifiying the longest_match + * from Jean-loup Gailly in deflate.c + * it prepare all parameters and call the assembly longest_match_gvasm + * longest_match execute standard C code is wmask != 0x7fff + * (assembly code is faster with a fixed wmask) + * + */ + +#include "deflate.h" + +#undef FAR +#include + +#ifdef ASMV +#define NIL 0 + +#define UNALIGNED_OK + + +/* if your C compiler don't add underline before function name, + define ADD_UNDERLINE_ASMFUNC */ +#ifdef ADD_UNDERLINE_ASMFUNC +#define longest_match_7fff _longest_match_7fff +#endif + + + +void match_init() +{ +} + +unsigned long cpudetect32(); + +uInt longest_match_c( + deflate_state *s, + IPos cur_match); /* current match */ + + +uInt longest_match_7fff( + deflate_state *s, + IPos cur_match); /* current match */ + +uInt longest_match( + deflate_state *s, + IPos cur_match) /* current match */ +{ + static uInt iIsPPro=2; + + if ((s->w_mask == 0x7fff) && (iIsPPro==0)) + return longest_match_7fff(s,cur_match); + + if (iIsPPro==2) + iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0; + + return longest_match_c(s,cur_match); +} + + + +uInt longest_match_c(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#endif /* ASMV */ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat new file mode 100644 index 000000000..6c5ffd7a0 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat @@ -0,0 +1 @@ +c:\masm611\bin\ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def new file mode 100644 index 000000000..7e9d60d55 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def @@ -0,0 +1,74 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + + +VERSION 1.11 + + +HEAPSIZE 1048576,8192 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp new file mode 100644 index 000000000..a70d4d4a6 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 + +CFG=zlibvc - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ + "Win32 (ALPHA) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc__" +# PROP BASE Intermediate_Dir "zlibvc__" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc__" +# PROP Intermediate_Dir "zlibvc__" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_0" +# PROP BASE Intermediate_Dir "zlibvc_0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_0" +# PROP Intermediate_Dir "zlibvc_0" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_1" +# PROP BASE Intermediate_Dir "zlibvc_1" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_1" +# PROP Intermediate_Dir "zlibvc_1" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "zlibvc - Win32 Release" +# Name "zlibvc - Win32 Debug" +# Name "zlibvc - Win32 ReleaseAxp" +# Name "zlibvc - Win32 ReleaseWithoutAsm" +# Name "zlibvc - Win32 ReleaseWithoutCrtdll" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\adler32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ADLER=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\compress.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_COMPR=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\crc32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_CRC32=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\deflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_DEFLA=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gvmat32c.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gzio.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_GZIO_=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infblock.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFBL=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFCO=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inffast.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFFA=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFLA=\ + ".\infblock.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFTR=\ + ".\inftrees.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFUT=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\trees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_TREES=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_UNCOM=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\unzip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zlib.rc +# End Source File +# Begin Source File + +SOURCE=.\zlibvc.def +# End Source File +# Begin Source File + +SOURCE=.\zutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ZUTIL=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw new file mode 100644 index 000000000..493cd8703 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.586 b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.586 new file mode 100644 index 000000000..6bb78f320 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.586 @@ -0,0 +1,43 @@ +This is a patched version of zlib modified to use +Pentium-optimized assembly code in the deflation algorithm. The files +changed/added by this patch are: + +README.586 +match.S + +The effectiveness of these modifications is a bit marginal, as the the +program's bottleneck seems to be mostly L1-cache contention, for which +there is no real way to work around without rewriting the basic +algorithm. The speedup on average is around 5-10% (which is generally +less than the amount of variance between subsequent executions). +However, when used at level 9 compression, the cache contention can +drop enough for the assembly version to achieve 10-20% speedup (and +sometimes more, depending on the amount of overall redundancy in the +files). Even here, though, cache contention can still be the limiting +factor, depending on the nature of the program using the zlib library. +This may also mean that better improvements will be seen on a Pentium +with MMX, which suffers much less from L1-cache contention, but I have +not yet verified this. + +Note that this code has been tailored for the Pentium in particular, +and will not perform well on the Pentium Pro (due to the use of a +partial register in the inner loop). + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S new file mode 100644 index 000000000..8f1614078 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S @@ -0,0 +1,354 @@ +/* match.s -- Pentium-optimized version of longest_match() + * Written for zlib 1.1.2 + * Copyright (C) 1998 Brian Raiter + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define wmask 0 /* local copy of s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define chainlenscanend 12 /* high word: current chain len */ + /* low word: last bytes sought */ +#define scanstart 16 /* first two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* Offsets for fields in the deflate_state structure. These numbers + * are calculated from the definition of deflate_state, with the + * assumption that the compiler will dword-align the fields. (Thus, + * changing the definition of deflate_state could easily cause this + * program to crash horribly, without so much as a warning at + * compile time. Sigh.) + */ +#define dsWSize 36 +#define dsWMask 44 +#define dsWindow 48 +#define dsPrev 56 +#define dsMatchLen 88 +#define dsPrevMatch 92 +#define dsStrStart 100 +#define dsMatchStart 104 +#define dsLookahead 108 +#define dsPrevLen 112 +#define dsMaxChainLen 116 +#define dsGoodMatch 132 +#define dsNiceMatch 136 + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: + +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $LocalVarsSize, %esp + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the scanend */ +/* scanend value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ + + movw (%edi), %bx + movw %bx, scanstart(%esp) + movw -1(%edi,%eax), %bx + movl %ebx, chainlenscanend(%esp) + +/* Posf *prev = s->prev; */ +/* uInt wmask = s->w_mask; */ + + movl dsPrev(%edx), %edi + movl dsWMask(%edx), %edx + mov %edx, wmask(%esp) + +/* Jump into the main loop. */ + + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) + * %ecx = curmatch + * %edx = curmatch & wmask + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + * + * Two optimization notes on the choice of instructions: + * + * The first instruction uses a 16-bit address, which costs an extra, + * unpairable cycle. This is cheaper than doing a 32-bit access and + * zeroing the high word, due to the 3-cycle misalignment penalty which + * would occur half the time. This also turns out to be cheaper than + * doing two separate 8-bit accesses, as the memory is so rarely in the + * L1 cache. + * + * The window buffer, however, apparently spends a lot of time in the + * cache, and so it is faster to retrieve the word at the end of the + * match string with two 8-bit loads. The instructions that test the + * word at the beginning of the match string, however, are executed + * much less frequently, and there it was cheaper to use 16-bit + * instructions, which avoided the necessity of saving off and + * subsequently reloading one of the other registers. + */ +LookupLoop: + /* 1 U & V */ + movw (%edi,%edx,2), %cx /* 2 U pipe */ + movl wmask(%esp), %edx /* 2 V pipe */ + cmpl %ebp, %ecx /* 3 U pipe */ + jbe LeaveNow /* 3 V pipe */ + subl $0x00010000, %ebx /* 4 U pipe */ + js LeaveNow /* 4 V pipe */ +LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ + andl %ecx, %edx /* 5 V pipe */ + cmpb %bl, %al /* 6 U pipe */ + jnz LookupLoop /* 6 V pipe */ + movb (%esi,%ecx), %ah + cmpb %bh, %ah + jnz LookupLoop + movl window(%esp), %eax + movw (%eax,%ecx), %ax + cmpw scanstart(%esp), %ax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %ebx, chainlenscanend(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + movl (%edi,%edx), %ebx + xorl %ebx, %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + movl 4(%edi,%edx), %ebx + xorl %ebx, %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl chainlenscanend(%esp), %ebx + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl wmask(%esp), %edx + andl %ecx, %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movl chainlenscanend(%esp), %ebx + movw -1(%edi,%eax), %bx + movl dsPrev(%edx), %edi + movl %ebx, chainlenscanend(%esp) + movl wmask(%esp), %edx + andl %ecx, %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp +match_init: ret diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.686 b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.686 new file mode 100644 index 000000000..a593f23af --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.686 @@ -0,0 +1,34 @@ +This is a patched version of zlib, modified to use +Pentium-Pro-optimized assembly code in the deflation algorithm. The +files changed/added by this patch are: + +README.686 +match.S + +The speedup that this patch provides varies, depending on whether the +compiler used to build the original version of zlib falls afoul of the +PPro's speed traps. My own tests show a speedup of around 10-20% at +the default compression level, and 20-30% using -9, against a version +compiled using gcc 2.7.2.3. Your mileage may vary. + +Note that this code has been tailored for the PPro/PII in particular, +and will not perform particuarly well on a Pentium. + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S new file mode 100644 index 000000000..8e86c33c2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S @@ -0,0 +1,327 @@ +/* match.s -- Pentium-Pro-optimized version of longest_match() + * Written for zlib 1.1.2 + * Copyright (C) 1998 Brian Raiter + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define chainlenwmask 0 /* high word: current chain len */ + /* low word: s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define scanstart 16 /* first two bytes of string */ +#define scanend 12 /* last two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* Offsets for fields in the deflate_state structure. These numbers + * are calculated from the definition of deflate_state, with the + * assumption that the compiler will dword-align the fields. (Thus, + * changing the definition of deflate_state could easily cause this + * program to crash horribly, without so much as a warning at + * compile time. Sigh.) + */ +#define dsWSize 36 +#define dsWMask 44 +#define dsWindow 48 +#define dsPrev 56 +#define dsMatchLen 88 +#define dsPrevMatch 92 +#define dsStrStart 100 +#define dsMatchStart 104 +#define dsLookahead 108 +#define dsPrevLen 112 +#define dsMaxChainLen 116 +#define dsGoodMatch 132 +#define dsNiceMatch 136 + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: + +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $LocalVarsSize, %esp + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsWMask(%edx), %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + orl %eax, %ebx + movl %ebx, chainlenwmask(%esp) + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%edi), %ebx + movl %ebx, scanstart(%esp) + movzwl -1(%edi,%eax), %ebx + movl %ebx, scanend(%esp) + movl dsPrev(%edx), %edi + +/* Jump into the main loop. */ + + movl chainlenwmask(%esp), %edx + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = scanend + * %ecx = curmatch + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + */ +LookupLoop: + andl %edx, %ecx + movzwl (%edi,%ecx,2), %ecx + cmpl %ebp, %ecx + jbe LeaveNow + subl $0x00010000, %edx + js LeaveNow +LoopEntry: movzwl -1(%esi,%ecx), %eax + cmpl %ebx, %eax + jnz LookupLoop + movl window(%esp), %eax + movzwl (%eax,%ecx), %eax + cmpl scanstart(%esp), %eax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %edx, chainlenwmask(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + xorl (%edi,%edx), %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + xorl 4(%edi,%edx), %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl scanend(%esp), %ebx + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movzwl -1(%edi,%eax), %ebx + movl dsPrev(%edx), %edi + movl %ebx, scanend(%esp) + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp +match_init: ret diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak new file mode 100644 index 000000000..ba557e2b9 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak @@ -0,0 +1,36 @@ +# Makefile for zlib32bd.lib +# ------------- Borland C++ 4.5 ------------- + +# The (32-bit) zlib32bd.lib made with this makefile is intended for use +# in making the (32-bit) DLL, png32bd.dll. It uses the "stdcall" calling +# convention. + +CFLAGS= -ps -O2 -C -K -N- -k- -d -3 -r- -w-par -w-aus -WDE +CC=f:\bc45\bin\bcc32 +LIBFLAGS= /C +LIB=f:\bc45\bin\tlib +ZLIB=zlib32bd.lib + +.autodepend +.c.obj: + $(CC) -c $(CFLAGS) $< + +OBJ1=adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj +OBJ2=infcodes.obj inflate.obj inftrees.obj infutil.obj inffast.obj +OBJ3=trees.obj uncompr.obj zutil.obj +pOBJ1=+adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infblock.obj +pOBJ2=+infcodes.obj+inflate.obj+inftrees.obj+infutil.obj+inffast.obj +pOBJ3=+trees.obj+uncompr.obj+zutil.obj + +all: $(ZLIB) + +$(ZLIB): $(OBJ1) $(OBJ2) $(OBJ3) + @if exist $@ del $@ + $(LIB) @&&| +$@ $(LIBFLAGS) & +$(pOBJ1) & +$(pOBJ2) & +$(pOBJ3) +| + +# End of makefile for zlib32bd.lib diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas new file mode 100644 index 000000000..4f96b7d2c --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas @@ -0,0 +1,169 @@ +unit zlibdef; + +interface + +uses + Windows; + +const + ZLIB_VERSION = '1.1.3'; + +type + voidpf = Pointer; + int = Integer; + uInt = Cardinal; + pBytef = PChar; + uLong = Cardinal; + + alloc_func = function(opaque: voidpf; items, size: uInt): voidpf; + stdcall; + free_func = procedure(opaque, address: voidpf); + stdcall; + + internal_state = Pointer; + + z_streamp = ^z_stream; + z_stream = packed record + next_in: pBytef; // next input byte + avail_in: uInt; // number of bytes available at next_in + total_in: uLong; // total nb of input bytes read so far + + next_out: pBytef; // next output byte should be put there + avail_out: uInt; // remaining free space at next_out + total_out: uLong; // total nb of bytes output so far + + msg: PChar; // last error message, NULL if no error + state: internal_state; // not visible by applications + + zalloc: alloc_func; // used to allocate the internal state + zfree: free_func; // used to free the internal state + opaque: voidpf; // private data object passed to zalloc and zfree + + data_type: int; // best guess about the data type: ascii or binary + adler: uLong; // adler32 value of the uncompressed data + reserved: uLong; // reserved for future use + end; + +const + Z_NO_FLUSH = 0; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + + Z_OK = 0; + Z_STREAM_END = 1; + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = -1; + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + + MAX_MEM_LEVEL = 9; + +function adler32(adler: uLong; const buf: pBytef; len: uInt): uLong; + stdcall; +function crc32(crc: uLong; const buf: pBytef; len: uInt): uLong; + stdcall; +function deflate(strm: z_streamp; flush: int): int; + stdcall; +function deflateCopy(dest, source: z_streamp): int; + stdcall; +function deflateEnd(strm: z_streamp): int; + stdcall; +function deflateInit2_(strm: z_streamp; level, method, + windowBits, memLevel, strategy: int; + const version: PChar; stream_size: int): int; + stdcall; +function deflateInit_(strm: z_streamp; level: int; + const version: PChar; stream_size: int): int; + stdcall; +function deflateParams(strm: z_streamp; level, strategy: int): int; + stdcall; +function deflateReset(strm: z_streamp): int; + stdcall; +function deflateSetDictionary(strm: z_streamp; + const dictionary: pBytef; + dictLength: uInt): int; + stdcall; +function inflate(strm: z_streamp; flush: int): int; + stdcall; +function inflateEnd(strm: z_streamp): int; + stdcall; +function inflateInit2_(strm: z_streamp; windowBits: int; + const version: PChar; stream_size: int): int; + stdcall; +function inflateInit_(strm: z_streamp; const version: PChar; + stream_size: int): int; + stdcall; +function inflateReset(strm: z_streamp): int; + stdcall; +function inflateSetDictionary(strm: z_streamp; + const dictionary: pBytef; + dictLength: uInt): int; + stdcall; +function inflateSync(strm: z_streamp): int; + stdcall; + +function deflateInit(strm: z_streamp; level: int): int; +function deflateInit2(strm: z_streamp; level, method, windowBits, + memLevel, strategy: int): int; +function inflateInit(strm: z_streamp): int; +function inflateInit2(strm: z_streamp; windowBits: int): int; + +implementation + +function deflateInit(strm: z_streamp; level: int): int; +begin + Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(strm: z_streamp; level, method, windowBits, + memLevel, strategy: int): int; +begin + Result := deflateInit2_(strm, level, method, windowBits, memLevel, + strategy, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(strm: z_streamp): int; +begin + Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2(strm: z_streamp; windowBits: int): int; +begin + Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, + sizeof(z_stream)); +end; + +const + zlibDLL = 'png32bd.dll'; + +function adler32; external zlibDLL; +function crc32; external zlibDLL; +function deflate; external zlibDLL; +function deflateCopy; external zlibDLL; +function deflateEnd; external zlibDLL; +function deflateInit2_; external zlibDLL; +function deflateInit_; external zlibDLL; +function deflateParams; external zlibDLL; +function deflateReset; external zlibDLL; +function deflateSetDictionary; external zlibDLL; +function inflate; external zlibDLL; +function inflateEnd; external zlibDLL; +function inflateInit2_; external zlibDLL; +function inflateInit_; external zlibDLL; +function inflateReset; external zlibDLL; +function inflateSetDictionary; external zlibDLL; +function inflateSync; external zlibDLL; + +end. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr new file mode 100644 index 000000000..78bb25408 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr @@ -0,0 +1,224 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = d_zlib.lib +OBJFILES = d_zlib.obj adler32.obj deflate.obj infblock.obj infcodes.obj inffast.obj \ + inflate.obj inftrees.obj infutil.obj trees.obj +RESFILES = +RESDEPEN = $(RESFILES) +LIBFILES = +LIBRARIES = VCL35.lib +SPARELIBS = VCL35.lib +DEFFILE = +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \ + dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -O2 -Ve -d -k- -vi +CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm +CFLAG3 = -ff -pr -5 +PFLAGS = -U;$(DEBUGLIBPATH) -I$(BCB)\include;$(BCB)\include\vcl -H -W -$I- -v -JPHN -M +RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl +AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn +LFLAGS = +IFLAGS = -g -Gn +# --------------------------------------------------------------------------- +ALLOBJ = c0w32.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib +# --------------------------------------------------------------------------- +!!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include +Item1=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + + --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = TLib +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include;$(BCB)\include\vcl +Item1=$(BCB)\include + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) $(IFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp new file mode 100644 index 000000000..f5dea59b7 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp @@ -0,0 +1,17 @@ +#include +#pragma hdrstop +//--------------------------------------------------------------------------- +USEUNIT("adler32.c"); +USEUNIT("deflate.c"); +USEUNIT("infblock.c"); +USEUNIT("infcodes.c"); +USEUNIT("inffast.c"); +USEUNIT("inflate.c"); +USEUNIT("inftrees.c"); +USEUNIT("infutil.c"); +USEUNIT("trees.c"); +//--------------------------------------------------------------------------- +#define Library + +// To add a file to the library use the Project menu 'Add to Project'. + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt new file mode 100644 index 000000000..cbd31620d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt @@ -0,0 +1,17 @@ +These are files used to compile zlib under Borland C++ Builder 3. + +zlib.bpg is the main project group that can be loaded in the BCB IDE and +loads all other *.bpr projects + +zlib.bpr is a project used to create a static zlib.lib library with C calling +convention for functions. + +zlib32.bpr creates a zlib32.dll dynamic link library with Windows standard +calling convention. + +d_zlib.bpr creates a set of .obj files with register calling convention. +These files are used by zlib.pas to create a Delphi unit containing zlib. +The d_zlib.lib file generated isn't useful and can be deleted. + +zlib.cpp, zlib32.cpp and d_zlib.cpp are used by the above projects. + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg new file mode 100644 index 000000000..b6c9acdf8 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg @@ -0,0 +1,26 @@ +#------------------------------------------------------------------------------ +VERSION = BWS.01 +#------------------------------------------------------------------------------ +!ifndef ROOT +ROOT = $(MAKEDIR)\.. +!endif +#------------------------------------------------------------------------------ +MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$** +DCC = $(ROOT)\bin\dcc32.exe $** +BRCC = $(ROOT)\bin\brcc32.exe $** +#------------------------------------------------------------------------------ +PROJECTS = zlib zlib32 d_zlib +#------------------------------------------------------------------------------ +default: $(PROJECTS) +#------------------------------------------------------------------------------ + +zlib: zlib.bpr + $(MAKE) + +zlib32: zlib32.bpr + $(MAKE) + +d_zlib: d_zlib.bpr + $(MAKE) + + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr new file mode 100644 index 000000000..cf3945b25 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr @@ -0,0 +1,225 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = zlib.lib +OBJFILES = zlib.obj adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj \ + infcodes.obj inffast.obj inflate.obj inftrees.obj infutil.obj trees.obj \ + uncompr.obj zutil.obj +RESFILES = +RESDEPEN = $(RESFILES) +LIBFILES = +LIBRARIES = VCL35.lib +SPARELIBS = VCL35.lib +DEFFILE = +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \ + dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -O2 -Ve -d -k- -vi +CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm +CFLAG3 = -ff -5 +PFLAGS = -U;$(DEBUGLIBPATH) -I$(BCB)\include;$(BCB)\include\vcl -H -W -$I- -v -JPHN -M +RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl +AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn +LFLAGS = +IFLAGS = -g -Gn +# --------------------------------------------------------------------------- +ALLOBJ = c0w32.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib +# --------------------------------------------------------------------------- +!!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include +Item1=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + + --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = TLib +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include;$(BCB)\include\vcl +Item1=$(BCB)\include + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) $(IFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp new file mode 100644 index 000000000..bf6953ba1 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp @@ -0,0 +1,22 @@ +#include +#pragma hdrstop +//--------------------------------------------------------------------------- +USEUNIT("adler32.c"); +USEUNIT("compress.c"); +USEUNIT("crc32.c"); +USEUNIT("deflate.c"); +USEUNIT("gzio.c"); +USEUNIT("infblock.c"); +USEUNIT("infcodes.c"); +USEUNIT("inffast.c"); +USEUNIT("inflate.c"); +USEUNIT("inftrees.c"); +USEUNIT("infutil.c"); +USEUNIT("trees.c"); +USEUNIT("uncompr.c"); +USEUNIT("zutil.c"); +//--------------------------------------------------------------------------- +#define Library + +// To add a file to the library use the Project menu 'Add to Project'. + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas new file mode 100644 index 000000000..10ae4cae2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas @@ -0,0 +1,534 @@ +{*******************************************************} +{ } +{ Delphi Supplemental Components } +{ ZLIB Data Compression Interface Unit } +{ } +{ Copyright (c) 1997 Borland International } +{ } +{*******************************************************} + +{ Modified for zlib 1.1.3 by Davide Moretti Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, 256); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := 256; + end; + finally + CCheck(deflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; + BufInc: Integer; +begin + FillChar(strm, sizeof(strm), 0); + BufInc := (InBytes + 255) and not 255; + if OutEstimate = 0 then + OutBytes := BufInc + else + OutBytes := OutEstimate; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, BufInc); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := BufInc; + end; + finally + DCheck(inflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +// TCustomZlibStream + +constructor TCustomZLibStream.Create(Strm: TStream); +begin + inherited Create; + FStrm := Strm; + FStrmPos := Strm.Position; +end; + +procedure TCustomZLibStream.Progress(Sender: TObject); +begin + if Assigned(FOnProgress) then FOnProgress(Sender); +end; + + +// TCompressionStream + +constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; + Dest: TStream); +const + Levels: array [TCompressionLevel] of ShortInt = + (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); +begin + inherited Create(Dest); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec))); +end; + +destructor TCompressionStream.Destroy; +begin + FZRec.next_in := nil; + FZRec.avail_in := 0; + try + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) + and (FZRec.avail_out = 0) do + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + end; + if FZRec.avail_out < sizeof(FBuffer) then + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out); + finally + deflateEnd(FZRec); + end; + inherited Destroy; +end; + +function TCompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + raise ECompressionError.Create('Invalid stream operation'); +end; + +function TCompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + FZRec.next_in := @Buffer; + FZRec.avail_in := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_in > 0) do + begin + CCheck(deflate(FZRec, 0)); + if FZRec.avail_out = 0 then + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + FStrmPos := FStrm.Position; + Progress(Self); + end; + end; + Result := Count; +end; + +function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + if (Offset = 0) and (Origin = soFromCurrent) then + Result := FZRec.total_in + else + raise ECompressionError.Create('Invalid stream operation'); +end; + +function TCompressionStream.GetCompressionRate: Single; +begin + if FZRec.total_in = 0 then + Result := 0 + else + Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; +end; + + +// TDecompressionStream + +constructor TDecompressionStream.Create(Source: TStream); +begin + inherited Create(Source); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec))); +end; + +destructor TDecompressionStream.Destroy; +begin + inflateEnd(FZRec); + inherited Destroy; +end; + +function TDecompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + FZRec.next_out := @Buffer; + FZRec.avail_out := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_out > 0) do + begin + if FZRec.avail_in = 0 then + begin + FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); + if FZRec.avail_in = 0 then + begin + Result := Count - FZRec.avail_out; + Exit; + end; + FZRec.next_in := FBuffer; + FStrmPos := FStrm.Position; + Progress(Self); + end; + DCheck(inflate(FZRec, 0)); + end; + Result := Count; +end; + +function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + raise EDecompressionError.Create('Invalid stream operation'); +end; + +function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +var + I: Integer; + Buf: array [0..4095] of Char; +begin + if (Offset = 0) and (Origin = soFromBeginning) then + begin + DCheck(inflateReset(FZRec)); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + FStrm.Position := 0; + FStrmPos := 0; + end + else if ( (Offset >= 0) and (Origin = soFromCurrent)) or + ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then + begin + if Origin = soFromBeginning then Dec(Offset, FZRec.total_out); + if Offset > 0 then + begin + for I := 1 to Offset div sizeof(Buf) do + ReadBuffer(Buf, sizeof(Buf)); + ReadBuffer(Buf, Offset mod sizeof(Buf)); + end; + end + else + raise EDecompressionError.Create('Invalid stream operation'); + Result := FZRec.total_out; +end; + +end. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr new file mode 100644 index 000000000..cabcec449 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr @@ -0,0 +1,174 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = zlib32.dll +OBJFILES = zlib32.obj adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj \ + infcodes.obj inffast.obj inflate.obj inftrees.obj infutil.obj trees.obj \ + uncompr.obj zutil.obj +RESFILES = +RESDEPEN = $(RESFILES) +LIBFILES = +LIBRARIES = +SPARELIBS = +DEFFILE = +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \ + dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -WD -O2 -Ve -d -k- -vi -c -tWD +CFLAG2 = -D_NO_VCL;ZLIB_DLL -I$(BCB)\include +CFLAG3 = -ff -5 +PFLAGS = -D_NO_VCL;ZLIB_DLL -U$(BCB)\lib;$(RELEASELIBPATH) -I$(BCB)\include -$I- -v \ + -JPHN -M +RFLAGS = -D_NO_VCL;ZLIB_DLL -i$(BCB)\include +AFLAGS = /i$(BCB)\include /d_NO_VCL /dZLIB_DLL /mx /w2 /zn +LFLAGS = -L$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpd -x -Gi +IFLAGS = -Gn -g +# --------------------------------------------------------------------------- +ALLOBJ = c0d32.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) import32.lib cw32mt.lib +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=1 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription=DLL (GUI) +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=1 +Item0=$(BCB)\include + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib + +[HistoryLists\hlConditionals] +Count=1 +Item0=_NO_VCL;ZLIB_DLL + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + +# --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = ilink32 +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) $(IFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp new file mode 100644 index 000000000..7372f6b98 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp @@ -0,0 +1,42 @@ + +#include +#pragma hdrstop +#include + + +//--------------------------------------------------------------------------- +// Important note about DLL memory management in a VCL DLL: +// +// +// +// If your DLL uses VCL and exports any functions that pass VCL String objects +// (or structs/classes containing nested Strings) as parameter or function +// results, you will need to build both your DLL project and any EXE projects +// that use your DLL with the dynamic RTL (the RTL DLL). This will change your +// DLL and its calling EXE's to use BORLNDMM.DLL as their memory manager. In +// these cases, the file BORLNDMM.DLL should be deployed along with your DLL +// and the RTL DLL (CP3240MT.DLL). To avoid the requiring BORLNDMM.DLL in +// these situations, pass string information using "char *" or ShortString +// parameters and then link with the static RTL. +// +//--------------------------------------------------------------------------- +USEUNIT("adler32.c"); +USEUNIT("compress.c"); +USEUNIT("crc32.c"); +USEUNIT("deflate.c"); +USEUNIT("gzio.c"); +USEUNIT("infblock.c"); +USEUNIT("infcodes.c"); +USEUNIT("inffast.c"); +USEUNIT("inflate.c"); +USEUNIT("inftrees.c"); +USEUNIT("infutil.c"); +USEUNIT("trees.c"); +USEUNIT("uncompr.c"); +USEUNIT("zutil.c"); +//--------------------------------------------------------------------------- +#pragma argsused +int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) +{ + return 1; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp new file mode 100644 index 000000000..7d265b3b5 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp @@ -0,0 +1,24 @@ + +#include "zfstream.h" + +int main() { + + // Construct a stream object with this filebuffer. Anything sent + // to this stream will go to standard out. + gzofstream os( 1, ios::out ); + + // This text is getting compressed and sent to stdout. + // To prove this, run 'test | zcat'. + os << "Hello, Mommy" << endl; + + os << setcompressionlevel( Z_NO_COMPRESSION ); + os << "hello, hello, hi, ho!" << endl; + + setcompressionlevel( os, Z_DEFAULT_COMPRESSION ) + << "I'm compressing again" << endl; + + os.close(); + + return 0; + +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp new file mode 100644 index 000000000..a690bbefc --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp @@ -0,0 +1,329 @@ + +#include +#include "zfstream.h" + +gzfilebuf::gzfilebuf() : + file(NULL), + mode(0), + own_file_descriptor(0) +{ } + +gzfilebuf::~gzfilebuf() { + + sync(); + if ( own_file_descriptor ) + close(); + +} + +gzfilebuf *gzfilebuf::open( const char *name, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p; + memset(char_mode,'\0',10); + p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + if ( (file = gzopen(name, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 1; + + return this; + +} + +gzfilebuf *gzfilebuf::attach( int file_descriptor, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p; + memset(char_mode,'\0',10); + p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 0; + + return this; + +} + +gzfilebuf *gzfilebuf::close() { + + if ( is_open() ) { + + sync(); + gzclose( file ); + file = NULL; + + } + + return this; + +} + +int gzfilebuf::setcompressionlevel( short comp_level ) { + + return gzsetparams(file, comp_level, -2); + +} + +int gzfilebuf::setcompressionstrategy( short comp_strategy ) { + + return gzsetparams(file, -2, comp_strategy); + +} + + +streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { + + return streampos(EOF); + +} + +int gzfilebuf::underflow() { + + // If the file hasn't been opened for reading, error. + if ( !is_open() || !(mode & ios::in) ) + return EOF; + + // if a buffer doesn't exists, allocate one. + if ( !base() ) { + + if ( (allocate()) == EOF ) + return EOF; + setp(0,0); + + } else { + + if ( in_avail() ) + return (unsigned char) *gptr(); + + if ( out_waiting() ) { + if ( flushbuf() == EOF ) + return EOF; + } + + } + + // Attempt to fill the buffer. + + int result = fillbuf(); + if ( result == EOF ) { + // disable get area + setg(0,0,0); + return EOF; + } + + return (unsigned char) *gptr(); + +} + +int gzfilebuf::overflow( int c ) { + + if ( !is_open() || !(mode & ios::out) ) + return EOF; + + if ( !base() ) { + if ( allocate() == EOF ) + return EOF; + setg(0,0,0); + } else { + if (in_avail()) { + return EOF; + } + if (out_waiting()) { + if (flushbuf() == EOF) + return EOF; + } + } + + int bl = blen(); + setp( base(), base() + bl); + + if ( c != EOF ) { + + *pptr() = c; + pbump(1); + + } + + return 0; + +} + +int gzfilebuf::sync() { + + if ( !is_open() ) + return EOF; + + if ( out_waiting() ) + return flushbuf(); + + return 0; + +} + +int gzfilebuf::flushbuf() { + + int n; + char *q; + + q = pbase(); + n = pptr() - q; + + if ( gzwrite( file, q, n) < n ) + return EOF; + + setp(0,0); + + return 0; + +} + +int gzfilebuf::fillbuf() { + + int required; + char *p; + + p = base(); + + required = blen(); + + int t = gzread( file, p, required ); + + if ( t <= 0) return EOF; + + setg( base(), base(), base()+t); + + return t; + +} + +gzfilestream_common::gzfilestream_common() : + ios( gzfilestream_common::rdbuf() ) +{ } + +gzfilestream_common::~gzfilestream_common() +{ } + +void gzfilestream_common::attach( int fd, int io_mode ) { + + if ( !buffer.attach( fd, io_mode) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::open( const char *name, int io_mode ) { + + if ( !buffer.open( name, io_mode ) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::close() { + + if ( !buffer.close() ) + clear( ios::failbit | ios::badbit ); + +} + +gzfilebuf *gzfilestream_common::rdbuf() { + + return &buffer; + +} + +gzifstream::gzifstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzifstream::gzifstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzifstream::gzifstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzifstream::~gzifstream() { } + +gzofstream::gzofstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzofstream::gzofstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzofstream::gzofstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzofstream::~gzofstream() { } diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h new file mode 100644 index 000000000..c87fa08e9 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h @@ -0,0 +1,142 @@ + +#ifndef _zfstream_h +#define _zfstream_h + +#include +#include "zlib.h" + +class gzfilebuf : public streambuf { + +public: + + gzfilebuf( ); + virtual ~gzfilebuf(); + + gzfilebuf *open( const char *name, int io_mode ); + gzfilebuf *attach( int file_descriptor, int io_mode ); + gzfilebuf *close(); + + int setcompressionlevel( short comp_level ); + int setcompressionstrategy( short comp_strategy ); + + inline int is_open() const { return (file !=NULL); } + + virtual streampos seekoff( streamoff, ios::seek_dir, int ); + + virtual int sync(); + +protected: + + virtual int underflow(); + virtual int overflow( int = EOF ); + +private: + + gzFile file; + short mode; + short own_file_descriptor; + + int flushbuf(); + int fillbuf(); + +}; + +class gzfilestream_common : virtual public ios { + + friend class gzifstream; + friend class gzofstream; + friend gzofstream &setcompressionlevel( gzofstream &, int ); + friend gzofstream &setcompressionstrategy( gzofstream &, int ); + +public: + virtual ~gzfilestream_common(); + + void attach( int fd, int io_mode ); + void open( const char *name, int io_mode ); + void close(); + +protected: + gzfilestream_common(); + +private: + gzfilebuf *rdbuf(); + + gzfilebuf buffer; + +}; + +class gzifstream : public gzfilestream_common, public istream { + +public: + + gzifstream(); + gzifstream( const char *name, int io_mode = ios::in ); + gzifstream( int fd, int io_mode = ios::in ); + + virtual ~gzifstream(); + +}; + +class gzofstream : public gzfilestream_common, public ostream { + +public: + + gzofstream(); + gzofstream( const char *name, int io_mode = ios::out ); + gzofstream( int fd, int io_mode = ios::out ); + + virtual ~gzofstream(); + +}; + +template class gzomanip { + friend gzofstream &operator<<(gzofstream &, const gzomanip &); +public: + gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { } +private: + gzofstream &(*func)(gzofstream &, T); + T val; +}; + +template gzofstream &operator<<(gzofstream &s, + const gzomanip &m) { + return (*m.func)(s, m.val); + +} + +inline gzofstream &setcompressionlevel( gzofstream &s, int l ) { + (s.rdbuf())->setcompressionlevel(l); + return s; +} + +inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) { + (s.rdbuf())->setcompressionstrategy(l); + return s; +} + +inline gzomanip setcompressionlevel(int l) +{ + return gzomanip(&setcompressionlevel,l); +} + +inline gzomanip setcompressionstrategy(int l) +{ + return gzomanip(&setcompressionstrategy,l); +} + +#endif + + + + + + + + + + + + + + + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h new file mode 100644 index 000000000..43d2332b7 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h @@ -0,0 +1,307 @@ +/* + * + * Copyright (c) 1997 + * Christian Michelsen Research AS + * Advanced Computing + * Fantoftvegen 38, 5036 BERGEN, Norway + * http://www.cmr.no + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Christian Michelsen Research AS makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef ZSTREAM__H +#define ZSTREAM__H + +/* + * zstream.h - C++ interface to the 'zlib' general purpose compression library + * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $ + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(_WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +class zstringlen { +public: + zstringlen(class izstream&); + zstringlen(class ozstream&, const char*); + size_t value() const { return val.word; } +private: + struct Val { unsigned char byte; size_t word; } val; +}; + +// ----------------------------- izstream ----------------------------- + +class izstream +{ + public: + izstream() : m_fp(0) {} + izstream(FILE* fp) : m_fp(0) { open(fp); } + izstream(const char* name) : m_fp(0) { open(name); } + ~izstream() { close(); } + + /* Opens a gzip (.gz) file for reading. + * open() can be used to read a file which is not in gzip format; + * in this case read() will directly read from the file without + * decompression. errno can be checked to distinguish two error + * cases (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name) { + if (m_fp) close(); + m_fp = ::gzopen(name, "rb"); + } + + void open(FILE* fp) { + SET_BINARY_MODE(fp); + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), "rb"); + } + + /* Flushes all pending input if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + int r = ::gzclose(m_fp); + m_fp = 0; return r; + } + + /* Binary read the given number of bytes from the compressed file. + */ + int read(void* buf, size_t len) { + return ::gzread(m_fp, buf, len); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + private: + gzFile m_fp; +}; + +/* + * Binary read the given (array of) object(s) from the compressed file. + * If the input file was not in gzip format, read() copies the objects number + * of bytes into the buffer. + * returns the number of uncompressed bytes actually read + * (0 for end of file, -1 for error). + */ +template +inline int read(izstream& zs, T* x, Items items) { + return ::gzread(zs.fp(), x, items*sizeof(T)); +} + +/* + * Binary input with the '>' operator. + */ +template +inline izstream& operator>(izstream& zs, T& x) { + ::gzread(zs.fp(), &x, sizeof(T)); + return zs; +} + + +inline zstringlen::zstringlen(izstream& zs) { + zs > val.byte; + if (val.byte == 255) zs > val.word; + else val.word = val.byte; +} + +/* + * Read length of string + the string with the '>' operator. + */ +inline izstream& operator>(izstream& zs, char* x) { + zstringlen len(zs); + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return zs; +} + +inline char* read_string(izstream& zs) { + zstringlen len(zs); + char* x = new char[len.value()+1]; + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return x; +} + +// ----------------------------- ozstream ----------------------------- + +class ozstream +{ + public: + ozstream() : m_fp(0), m_os(0) { + } + ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(fp, level); + } + ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(name, level); + } + ~ozstream() { + close(); + } + + /* Opens a gzip (.gz) file for writing. + * The compression level parameter should be in 0..9 + * errno can be checked to distinguish two error cases + * (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name, int level = Z_DEFAULT_COMPRESSION) { + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzopen(name, mode); + } + + /* open from a FILE pointer. + */ + void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) { + SET_BINARY_MODE(fp); + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), mode); + } + + /* Flushes all pending output if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + if (m_os) { + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = 0; + } + int r = ::gzclose(m_fp); m_fp = 0; return r; + } + + /* Binary write the given number of bytes into the compressed file. + */ + int write(const void* buf, size_t len) { + return ::gzwrite(m_fp, (voidp) buf, len); + } + + /* Flushes all pending output into the compressed file. The parameter + * _flush is as in the deflate() function. The return value is the zlib + * error number (see function gzerror below). flush() returns Z_OK if + * the flush_ parameter is Z_FINISH and all output could be flushed. + * flush() should be called only when strictly necessary because it can + * degrade compression. + */ + int flush(int _flush) { + os_flush(); + return ::gzflush(m_fp, _flush); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + ostream& os() { + if (m_os == 0) m_os = new ostrstream; + return *m_os; + } + + void os_flush() { + if (m_os && m_os->pcount()>0) { + ostrstream* oss = new ostrstream; + oss->fill(m_os->fill()); + oss->flags(m_os->flags()); + oss->precision(m_os->precision()); + oss->width(m_os->width()); + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = oss; + } + } + + private: + gzFile m_fp; + ostrstream* m_os; +}; + +/* + * Binary write the given (array of) object(s) into the compressed file. + * returns the number of uncompressed bytes actually written + * (0 in case of error). + */ +template +inline int write(ozstream& zs, const T* x, Items items) { + return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T)); +} + +/* + * Binary output with the '<' operator. + */ +template +inline ozstream& operator<(ozstream& zs, const T& x) { + ::gzwrite(zs.fp(), (voidp) &x, sizeof(T)); + return zs; +} + +inline zstringlen::zstringlen(ozstream& zs, const char* x) { + val.byte = 255; val.word = ::strlen(x); + if (val.word < 255) zs < (val.byte = val.word); + else zs < val; +} + +/* + * Write length of string + the string with the '<' operator. + */ +inline ozstream& operator<(ozstream& zs, const char* x) { + zstringlen len(zs, x); + ::gzwrite(zs.fp(), (voidp) x, len.value()); + return zs; +} + +#ifdef _MSC_VER +inline ozstream& operator<(ozstream& zs, char* const& x) { + return zs < (const char*) x; +} +#endif + +/* + * Ascii write with the << operator; + */ +template +inline ostream& operator<<(ozstream& zs, const T& x) { + zs.os_flush(); + return zs.os() << x; +} + +#endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp new file mode 100644 index 000000000..5bbd56c3a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp @@ -0,0 +1,25 @@ +#include "zstream.h" +#include +#include +#include + +void main() { + char h[256] = "Hello"; + char* g = "Goodbye"; + ozstream out("temp.gz"); + out < "This works well" < h < g; + out.close(); + + izstream in("temp.gz"); // read it back + char *x = read_string(in), *y = new char[256], z[256]; + in > y > z; + in.close(); + cout << x << endl << y << endl << z << endl; + + out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results + out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl; + out << z << endl << y << endl << x << endl; + out << 1.1234567890123456789 << endl; + + delete[] x; delete[] y; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip new file mode 100644 index 000000000..9987c543c --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip @@ -0,0 +1,38 @@ +Change in 0.15: (19 Mar 98) +- fix memory leak in minizip.c + +Change in 0.14: (10 Mar 98) +- fix bugs in minizip.c sample for zipping big file +- fix problem in month in date handling +- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for + comment handling + +Change in 0.13: (6 Mar 98) +- fix bugs in zip.c +- add real minizip sample + +Change in 0.12: (4 Mar 98) +- add zip.c and zip.h for creates .zip file +- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly) +- fix miniunz.c for file without specific record for directory + +Change in 0.11: (3 Mar 98) +- fix bug in unzGetCurrentFileInfo for get extra field and comment +- enhance miniunz sample, remove the bad unztst.c sample + +Change in 0.10: (2 Mar 98) +- fix bug in unzReadCurrentFile +- rename unzip* to unz* function and structure +- remove Windows-like hungary notation variable name +- modify some structure in unzip.h +- add somes comment in source +- remove unzipGetcCurrentFile function +- replace ZUNZEXPORT by ZEXPORT +- add unzGetLocalExtrafield for get the local extrafield info +- add a new sample, miniunz.c + +Change in 0.4: (25 Feb 98) +- suppress the type unzipFileInZip. + Only on file in the zipfile can be open at the same time +- fix somes typo in code +- added tm_unz structure in unzip_file_info (date/time in readable format) diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c new file mode 100644 index 000000000..f3b783287 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c @@ -0,0 +1,508 @@ +#include +#include +#include +#include +#include +#include + +#ifdef unix +# include +# include +#else +# include +# include +#endif + +#include "unzip.h" + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) + +/* + mini unzip, demo of unzip package + + usage : + Usage : miniunz [-exvlo] file.zip [file_to_extract] + + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT + if it exists +*/ + + +/* change_file_date : change the date/time of a file + filename : the filename of the file where date/time must be modified + dosdate : the new date at the MSDos format (4 bytes) + tmu_date : the SAME new date at the tm_unz format */ +void change_file_date(filename,dosdate,tmu_date) + const char *filename; + uLong dosdate; + tm_unz tmu_date; +{ +#ifdef WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + + hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING,0,NULL); + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); + CloseHandle(hFile); +#else +#ifdef unix + struct utimbuf ut; + struct tm newdate; + newdate.tm_sec = tmu_date.tm_sec; + newdate.tm_min=tmu_date.tm_min; + newdate.tm_hour=tmu_date.tm_hour; + newdate.tm_mday=tmu_date.tm_mday; + newdate.tm_mon=tmu_date.tm_mon; + if (tmu_date.tm_year > 1900) + newdate.tm_year=tmu_date.tm_year - 1900; + else + newdate.tm_year=tmu_date.tm_year ; + newdate.tm_isdst=-1; + + ut.actime=ut.modtime=mktime(&newdate); + utime(filename,&ut); +#endif +#endif +} + + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#ifdef WIN32 + ret = mkdir(dirname); +#else +#ifdef unix + ret = mkdir (dirname,0775); +#endif +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +void do_banner() +{ + printf("MiniUnz 0.15, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n"); +} + +void do_help() +{ + printf("Usage : miniunz [-exvlo] file.zip [file_to_extract]\n\n") ; +} + + +int do_list(uf) + unzFile uf; +{ + uLong i; + unz_global_info gi; + int err; + + err = unzGetGlobalInfo (uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); + printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); + for (i=0;i0) + ratio = (file_info.compressed_size*100)/file_info.uncompressed_size; + + if (file_info.compression_method==0) + string_method="Stored"; + else + if (file_info.compression_method==Z_DEFLATED) + { + uInt iLevel=(uInt)((file_info.flag & 0x6)/2); + if (iLevel==0) + string_method="Defl:N"; + else if (iLevel==1) + string_method="Defl:X"; + else if ((iLevel==2) || (iLevel==3)) + string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ + } + else + string_method="Unkn. "; + + printf("%7lu %6s %7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", + file_info.uncompressed_size,string_method,file_info.compressed_size, + ratio, + (uLong)file_info.tmu_date.tm_mon + 1, + (uLong)file_info.tmu_date.tm_mday, + (uLong)file_info.tmu_date.tm_year % 100, + (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, + (uLong)file_info.crc,filename_inzip); + if ((i+1)='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + } + + if (rep == 'N') + skip = 1; + + if (rep == 'A') + *popt_overwrite=1; + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=fopen(write_filename,"wb"); + + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && ((*popt_extract_without_path)==0) && + (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + makedir(write_filename); + *(filename_withoutpath-1)=c; + fout=fopen(write_filename,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + printf(" extracting: %s\n",write_filename); + + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + fclose(fout); + if (err==0) + change_file_date(write_filename,file_info.dosDate, + file_info.tmu_date); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int do_extract(uf,opt_extract_without_path,opt_overwrite) + unzFile uf; + int opt_extract_without_path; + int opt_overwrite; +{ + uLong i; + unz_global_info gi; + int err; + FILE* fout=NULL; + + err = unzGetGlobalInfo (uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + + for (i=0;i +#include +#include +#include +#include +#include + +#ifdef unix +# include +# include +# include +# include +#else +# include +# include +#endif + +#include "zip.h" + + +#define WRITEBUFFERSIZE (16384) +#define MAXFILENAME (256) + +#ifdef WIN32 +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret = 0; + { + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATA ff32; + + hFind = FindFirstFile(f,&ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + ret = 1; + } + } + return ret; +} +#else +#ifdef unix +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret=0; + struct stat s; /* results of stat() */ + struct tm* filedate; + time_t tm_t=0; + + if (strcmp(f,"-")!=0) + { + char name[MAXFILENAME]; + int len = strlen(f); + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (stat(name,&s)==0) + { + tm_t = s.st_mtime; + ret = 1; + } + } + filedate = localtime(&tm_t); + + tmzip->tm_sec = filedate->tm_sec; + tmzip->tm_min = filedate->tm_min; + tmzip->tm_hour = filedate->tm_hour; + tmzip->tm_mday = filedate->tm_mday; + tmzip->tm_mon = filedate->tm_mon ; + tmzip->tm_year = filedate->tm_year; + + return ret; +} +#else +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + return 0; +} +#endif +#endif + + + + +int check_exist_file(filename) + const char* filename; +{ + FILE* ftestexist; + int ret = 1; + ftestexist = fopen(filename,"rb"); + if (ftestexist==NULL) + ret = 0; + else + fclose(ftestexist); + return ret; +} + +void do_banner() +{ + printf("MiniZip 0.15, demo of zLib + Zip package written by Gilles Vollant\n"); + printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n"); +} + +void do_help() +{ + printf("Usage : minizip [-o] file.zip [files_to_add]\n\n") ; +} + +int main(argc,argv) + int argc; + char *argv[]; +{ + int i; + int opt_overwrite=0; + int opt_compress_level=Z_DEFAULT_COMPRESSION; + int zipfilenamearg = 0; + char filename_try[MAXFILENAME]; + int zipok; + int err=0; + int size_buf=0; + void* buf=NULL, + + + do_banner(); + if (argc==1) + { + do_help(); + exit(0); + return 0; + } + else + { + for (i=1;i='0') && (c<='9')) + opt_compress_level = c-'0'; + } + } + else + if (zipfilenamearg == 0) + zipfilenamearg = i ; + } + } + + size_buf = WRITEBUFFERSIZE; + buf = (void*)malloc(size_buf); + if (buf==NULL) + { + printf("Error allocating memory\n"); + return ZIP_INTERNALERROR; + } + + if (zipfilenamearg==0) + zipok=0; + else + { + int i,len; + int dot_found=0; + + zipok = 1 ; + strcpy(filename_try,argv[zipfilenamearg]); + len=strlen(filename_try); + for (i=0;i='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N')); + if (rep=='N') + zipok = 0; + } + } + + if (zipok==1) + { + zipFile zf; + int errclose; + zf = zipOpen(filename_try,0); + if (zf == NULL) + { + printf("error opening %s\n",filename_try); + err= ZIP_ERRNO; + } + else + printf("creating %s\n",filename_try); + + for (i=zipfilenamearg+1;(i0) + { + err = zipWriteInFileInZip (zf,buf,size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + fclose(fin); + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } + } + } + errclose = zipClose(zf,NULL); + if (errclose != ZIP_OK) + printf("error in closing %s\n",filename_try); + } + + free(buf); + exit(0); + return 0; /* to avoid warning */ +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt new file mode 100644 index 000000000..1fc023c72 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt @@ -0,0 +1,37 @@ + +UnZip 0.15 additionnal library + + + This unzip package allow extract file from .ZIP file, compatible with +PKZip 2.04g, WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported, and old compression used by old +PKZip 1.x are not supported. + +See probdesc.zip from PKWare for specification of .ZIP format. + +What is Unzip + The Zlib library support the deflate compression and the creation of gzip (.gz) +file. Zlib is free and small. + The .Zip format, which can contain several compressed files (.gz can containt +only one file) is a very popular format. This is why I've written a package for reading file compressed in Zipfile. + +Using Unzip package + +You need source of Zlib (get zlib111.zip and read zlib.h). +Get unzlb015.zip and read unzip.h (whith documentation of unzip functions) + +The Unzip package is only two file : unzip.h and unzip.c. But it use the Zlib + files. +unztst.c is a simple sample program, which list file in a zipfile and display + README.TXT or FILE_ID.DIZ (if these files are found). +miniunz.c is a mini unzip program. + +I'm also currenlyt writing a zipping portion (zip.h, zip.c and test with minizip.c) + +Please email me for feedback. +I hope my source is compatible with Unix system, but I need your help for be sure + +Latest revision : Mar 04th, 1998 + +Check http://www.winimage.com/zLibDll/unzip.html for up to date info. diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c new file mode 100644 index 000000000..ff71a474d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c @@ -0,0 +1,1294 @@ +/* unzip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read unzip.h for more info +*/ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char unz_copyright[] = + " unzip 0.15 Copyright 1998 Gilles Vollant "; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + FILE* file; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + FILE* file; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ +} unz_s; + + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte(fin,pi) + FILE *fin; + int *pi; +{ + unsigned char c; + int err = fread(&c, 1, 1, fin); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ferror(fin)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir(fin) + FILE *fin; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) + return 0; + + + uSizeFile = ftell( fin ); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) + break; + + if (fread(buf,(uInt)uReadSize,1,fin)!=1) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen (path) + const char *path; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + FILE * fin ; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + fin=fopen(path,"rb"); + if (fin==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; + + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + fclose(s->file); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { + uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def new file mode 100644 index 000000000..f6ede89bc --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def @@ -0,0 +1,15 @@ + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h new file mode 100644 index 000000000..76692cb70 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h @@ -0,0 +1,275 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c new file mode 100644 index 000000000..0cae64ab7 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c @@ -0,0 +1,718 @@ +/* zip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read zip.h for more info +*/ + + +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char zip_copyright[] = + " zip 0.15 Copyright 1998 Gilles Vollant "; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + uLong pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralheader; /* size of the central header for cur file */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; +} curfile_info; + +typedef struct +{ + FILE * filezip; + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile_info ci; /* info on the file curretly writing */ + + uLong begin_pos; /* position of the beginning of the zipfile */ + uLong number_entry; +} zip_internal; + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(ldi) + linkedlist_datablock_internal* ldi; +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(ll) + linkedlist_data* ll; +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(ll) + linkedlist_data* ll; +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(ll,buf,len) + linkedlist_data* ll; + const void* buf; + uLong len; +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + +local int write_datablock(fout,ll) + FILE * fout; + linkedlist_data* ll; +{ + linkedlist_datablock_internal* ldi; + ldi = ll->first_block; + while (ldi!=NULL) + { + if (ldi->filled_in_this_block > 0) + if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1) + return ZIP_ERRNO; + ldi = ldi->next_datablock; + } + return ZIP_OK; +} + +/****************************************************************************/ + +/* =========================================================================== + Outputs a long in LSB order to the given file + nbByte == 1, 2 or 4 (byte, short or long) +*/ + +local int ziplocal_putValue OF((FILE *file, uLong x, int nbByte)); +local int ziplocal_putValue (file, x, nbByte) + FILE *file; + uLong x; + int nbByte; +{ + unsigned char buf[4]; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (fwrite(buf,nbByte,1,file)!=1) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); +local void ziplocal_putValue_inmemory (dest, x, nbByte) + void* dest; + uLong x; + int nbByte; +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } +} +/****************************************************************************/ + + +local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) + tm_zip* ptm; + uLong dosDate; +{ + uLong year = (uLong)ptm->tm_year; + if (year>1980) + year-=1980; + else if (year>80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +extern zipFile ZEXPORT zipOpen (pathname, append) + const char *pathname; + int append; +{ + zip_internal ziinit; + zip_internal* zi; + + ziinit.filezip = fopen(pathname,(append == 0) ? "wb" : "ab"); + if (ziinit.filezip == NULL) + return NULL; + ziinit.begin_pos = ftell(ziinit.filezip); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + init_linkedlist(&(ziinit.central_dir)); + + + zi = (zip_internal*)ALLOC(sizeof(zip_internal)); + if (zi==NULL) + { + fclose(ziinit.filezip); + return NULL; + } + + *zi = ziinit; + return (zipFile)zi; +} + +extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; +{ + zip_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; + + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = strlen(comment); + + size_filename = strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); + } + + zi->ci.flag = 0; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.pos_local_header = ftell(zi->filezip); + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + + size_extrafield_global + size_comment; + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); + + ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); + ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(filename+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + /* write the local header */ + err = ziplocal_putValue(zi->filezip,(uLong)LOCALHEADERMAGIC,4); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)20,2);/* version needed to extract */ + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.dosDate,4); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* compressed size, unknown */ + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* uncompressed size, unknown */ + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2); + + if ((err==ZIP_OK) && (size_filename>0)) + if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1) + err = ZIP_ERRNO; + + if ((err==ZIP_OK) && (size_extrafield_local>0)) + if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED)) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + err = deflateInit2(&zi->ci.stream, level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); + + if (err==Z_OK) + zi->ci.stream_initialised = 1; + } + + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (file, buf, len) + zipFile file; + const voidp buf; + unsigned len; +{ + zip_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.stream.next_in = buf; + zi->ci.stream.avail_in = len; + zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + zi->ci.pos_in_buffered_data = 0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + if (zi->ci.method == Z_DEFLATED) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + for (i=0;ici.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + } + + return 0; +} + +extern int ZEXPORT zipCloseFileInZip (file) + zipFile file; +{ + zip_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if (zi->ci.method == Z_DEFLATED) + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + zi->ci.pos_in_buffered_data = 0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + + if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK)) + { + err=deflateEnd(&zi->ci.stream); + zi->ci.stream_initialised = 0; + } + + ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)zi->ci.crc32,4); /*crc*/ + ziplocal_putValue_inmemory(zi->ci.central_header+20, + (uLong)zi->ci.stream.total_out,4); /*compr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+24, + (uLong)zi->ci.stream.total_in,4); /*uncompr size*/ + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, + (uLong)zi->ci.size_centralheader); + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + long cur_pos_inzip = ftell(zi->filezip); + if (fseek(zi->filezip, + zi->ci.pos_local_header + 14,SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.crc32,4); /* crc 32, unknown */ + + if (err==ZIP_OK) /* compressed size, unknown */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_out,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_in,4); + + if (fseek(zi->filezip, + cur_pos_inzip,SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipClose (file, global_comment) + zipFile file; + const char* global_comment; +{ + zip_internal* zi; + int err = 0; + uLong size_centraldir = 0; + uLong centraldir_pos_inzip ; + uInt size_global_comment; + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + + if (global_comment==NULL) + size_global_comment = 0; + else + size_global_comment = strlen(global_comment); + + + centraldir_pos_inzip = ftell(zi->filezip); + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block, + 1,zi->filezip) !=1 ) + err = ZIP_ERRNO; + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_datablock(zi->central_dir.first_block); + + if (err==ZIP_OK) /* Magic End */ + err = ziplocal_putValue(zi->filezip,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = ziplocal_putValue(zi->filezip,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = ziplocal_putValue(zi->filezip,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2); + + if (err==ZIP_OK) /* size of the central directory */ + err = ziplocal_putValue(zi->filezip,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the + starting disk number */ + err = ziplocal_putValue(zi->filezip,(uLong)centraldir_pos_inzip ,4); + + if (err==ZIP_OK) /* zipfile comment length */ + err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2); + + if ((err==ZIP_OK) && (size_global_comment>0)) + if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 ) + err = ZIP_ERRNO; + fclose(zi->filezip); + TRYFREE(zi); + + return err; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def new file mode 100644 index 000000000..5d5079fbc --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def @@ -0,0 +1,5 @@ + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h new file mode 100644 index 000000000..678260b33 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h @@ -0,0 +1,150 @@ +/* zip.h -- IO for compress .zip files using zlib + Version 0.15 alpha, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow creates .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + For uncompress .zip file, look at unzip.h + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/zip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _zip_H +#define _zip_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_INTERNALERROR (-104) + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows NT a filename like "c:\\zlib\\zlib111.zip" or on + an Unix computer "zlib/zlib111.zip". + if the file pathname exist and append=1, the zip will be created at the end + of the file. (useful if the file contain a self extractor code) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. + + +*/ + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) +*/ + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const voidp buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip_H */ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def new file mode 100644 index 000000000..7e9d60d55 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def @@ -0,0 +1,74 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + + +VERSION 1.11 + + +HEAPSIZE 1048576,8192 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp new file mode 100644 index 000000000..a70d4d4a6 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 + +CFG=zlibvc - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ + "Win32 (ALPHA) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc__" +# PROP BASE Intermediate_Dir "zlibvc__" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc__" +# PROP Intermediate_Dir "zlibvc__" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_0" +# PROP BASE Intermediate_Dir "zlibvc_0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_0" +# PROP Intermediate_Dir "zlibvc_0" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_1" +# PROP BASE Intermediate_Dir "zlibvc_1" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_1" +# PROP Intermediate_Dir "zlibvc_1" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "zlibvc - Win32 Release" +# Name "zlibvc - Win32 Debug" +# Name "zlibvc - Win32 ReleaseAxp" +# Name "zlibvc - Win32 ReleaseWithoutAsm" +# Name "zlibvc - Win32 ReleaseWithoutCrtdll" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\adler32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ADLER=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\compress.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_COMPR=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\crc32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_CRC32=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\deflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_DEFLA=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gvmat32c.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gzio.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_GZIO_=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infblock.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFBL=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFCO=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inffast.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFFA=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFLA=\ + ".\infblock.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFTR=\ + ".\inftrees.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFUT=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\trees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_TREES=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_UNCOM=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\unzip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zlib.rc +# End Source File +# Begin Source File + +SOURCE=.\zlibvc.def +# End Source File +# Begin Source File + +SOURCE=.\zutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ZUTIL=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw new file mode 100644 index 000000000..493cd8703 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w32 b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w32 new file mode 100644 index 000000000..c99dc28cf --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w32 @@ -0,0 +1,63 @@ +# Makefile for zlib. Modified for mingw32 +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, +# +# make -fmakefile.w32 +# + +CC=gcc + +# Generate dependencies (see end of the file) + +CPPFLAGS=-MMD + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is not found, replace with copy /Y . +CP=cp -f + +# The default value of RM is "rm -f." +# If "rm.exe" is not found, uncomment: +# RM=del + +LD=gcc +LDLIBS=-L. -lz +LDFLAGS=-s + + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o \ + inffast.o + +TEST_OBJS = minigzip.o untgz.o + +all: minigzip.exe untgz.exe + +rebuild: clean all + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $(LDFLAGS) -o $@ $< $(LDLIBS) + +.PHONY : clean + +clean: + $(RM) *.d *.o *.exe libz.a foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c new file mode 100644 index 000000000..4a431ff31 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c @@ -0,0 +1,522 @@ +/* + * untgz.c -- Display contents and/or extract file from + * a gzip'd TAR file + * written by "Pedro A. Aranda Guti\irrez" + * adaptation to Unix by Jean-loup Gailly + */ + +#include +#include +#include +#include +#include +#include +#ifdef unix +# include +#else +# include +# include +#endif + +#include "zlib.h" + +#ifdef WIN32 +# ifndef F_OK +# define F_OK (0) +# endif +# ifdef _MSC_VER +# define mkdir(dirname,mode) _mkdir(dirname) +# define strdup(str) _strdup(str) +# define unlink(fn) _unlink(fn) +# define access(path,mode) _access(path,mode) +# else +# define mkdir(dirname,mode) _mkdir(dirname) +# endif +#else +# include +#endif + + +/* Values used in typeflag field. */ + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define LNKTYPE '1' /* link */ +#define SYMTYPE '2' /* reserved */ +#define CHRTYPE '3' /* character special */ +#define BLKTYPE '4' /* block special */ +#define DIRTYPE '5' /* directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* reserved */ + +#define BLOCKSIZE 512 + +struct tar_header +{ /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; + +union tar_buffer { + char buffer[BLOCKSIZE]; + struct tar_header header; +}; + +enum { TGZ_EXTRACT = 0, TGZ_LIST }; + +static char *TGZfname OF((const char *)); +void TGZnotfound OF((const char *)); + +int getoct OF((char *, int)); +char *strtime OF((time_t *)); +int ExprMatch OF((char *,char *)); + +int makedir OF((char *)); +int matchname OF((int,int,char **,char *)); + +void error OF((const char *)); +int tar OF((gzFile, int, int, int, char **)); + +void help OF((int)); +int main OF((int, char **)); + +char *prog; + +/* This will give a benign warning */ + +static char *TGZprefix[] = { "\0", ".tgz", ".tar.gz", ".tar", NULL }; + +/* Return the real name of the TGZ archive */ +/* or NULL if it does not exist. */ + +static char *TGZfname OF((const char *fname)) +{ + static char buffer[1024]; + int origlen,i; + + strcpy(buffer,fname); + origlen = strlen(buffer); + + for (i=0; TGZprefix[i]; i++) + { + strcpy(buffer+origlen,TGZprefix[i]); + if (access(buffer,F_OK) == 0) + return buffer; + } + return NULL; +} + +/* error message for the filename */ + +void TGZnotfound OF((const char *fname)) +{ + int i; + + fprintf(stderr,"%s : couldn't find ",prog); + for (i=0;TGZprefix[i];i++) + fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n", + fname, + TGZprefix[i]); + exit(1); +} + + +/* help functions */ + +int getoct(char *p,int width) +{ + int result = 0; + char c; + + while (width --) + { + c = *p++; + if (c == ' ') + continue; + if (c == 0) + break; + result = result * 8 + (c - '0'); + } + return result; +} + +char *strtime (time_t *t) +{ + struct tm *local; + static char result[32]; + + local = localtime(t); + sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d", + local->tm_mday, local->tm_mon+1, local->tm_year+1900, + local->tm_hour, local->tm_min, local->tm_sec); + return result; +} + + +/* regular expression matching */ + +#define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) + +int ExprMatch(char *string,char *expr) +{ + while (1) + { + if (ISSPECIAL(*expr)) + { + if (*expr == '/') + { + if (*string != '\\' && *string != '/') + return 0; + string ++; expr++; + } + else if (*expr == '*') + { + if (*expr ++ == 0) + return 1; + while (*++string != *expr) + if (*string == 0) + return 0; + } + } + else + { + if (*string != *expr) + return 0; + if (*expr++ == 0) + return 1; + string++; + } + } +} + +/* recursive make directory */ +/* abort if you get an ENOENT errno somewhere in the middle */ +/* e.g. ignore error "mkdir on existing directory" */ +/* */ +/* return 1 if OK */ +/* 0 on error */ + +int makedir (char *newdir) +{ + char *buffer = strdup(newdir); + char *p; + int len = strlen(buffer); + + if (len <= 0) { + free(buffer); + return 0; + } + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mkdir(buffer, 0775) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT)) + { + fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +int matchname (int arg,int argc,char **argv,char *fname) +{ + if (arg == argc) /* no arguments given (untgz tgzarchive) */ + return 1; + + while (arg < argc) + if (ExprMatch(fname,argv[arg++])) + return 1; + + return 0; /* ignore this for the moment being */ +} + + +/* Tar file list or extract */ + +int tar (gzFile in,int action,int arg,int argc,char **argv) +{ + union tar_buffer buffer; + int len; + int err; + int getheader = 1; + int remaining = 0; + FILE *outfile = NULL; + char fname[BLOCKSIZE]; + time_t tartime; + + if (action == TGZ_LIST) + printf(" day time size file\n" + " ---------- -------- --------- -------------------------------------\n"); + while (1) + { + len = gzread(in, &buffer, BLOCKSIZE); + if (len < 0) + error (gzerror(in, &err)); + /* + * Always expect complete blocks to process + * the tar information. + */ + if (len != BLOCKSIZE) + error("gzread: incomplete block read"); + + /* + * If we have to get a tar header + */ + if (getheader == 1) + { + /* + * if we met the end of the tar + * or the end-of-tar block, + * we are done + */ + if ((len == 0) || (buffer.header.name[0]== 0)) break; + + tartime = (time_t)getoct(buffer.header.mtime,12); + strcpy(fname,buffer.header.name); + + switch (buffer.header.typeflag) + { + case DIRTYPE: + if (action == TGZ_LIST) + printf(" %s %s\n",strtime(&tartime),fname); + if (action == TGZ_EXTRACT) + makedir(fname); + break; + case REGTYPE: + case AREGTYPE: + remaining = getoct(buffer.header.size,12); + if (action == TGZ_LIST) + printf(" %s %9d %s\n",strtime(&tartime),remaining,fname); + if (action == TGZ_EXTRACT) + { + if ((remaining) && (matchname(arg,argc,argv,fname))) + { + outfile = fopen(fname,"wb"); + if (outfile == NULL) { + /* try creating directory */ + char *p = strrchr(fname, '/'); + if (p != NULL) { + *p = '\0'; + makedir(fname); + *p = '/'; + outfile = fopen(fname,"wb"); + } + } + fprintf(stderr, + "%s %s\n", + (outfile) ? "Extracting" : "Couldn't create", + fname); + } + else + outfile = NULL; + } + /* + * could have no contents + */ + getheader = (remaining) ? 0 : 1; + break; + default: + if (action == TGZ_LIST) + printf(" %s <---> %s\n",strtime(&tartime),fname); + break; + } + } + else + { + unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; + + if ((action == TGZ_EXTRACT) && (outfile != NULL)) + { + if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) + { + fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname); + fclose(outfile); + unlink(fname); + } + } + remaining -= bytes; + if (remaining == 0) + { + getheader = 1; + if ((action == TGZ_EXTRACT) && (outfile != NULL)) + { +#ifdef WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal; + SYSTEMTIME st; + struct tm localt; + + fclose(outfile); + + localt = *localtime(&tartime); + + hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + st.wYear = (WORD)localt.tm_year+1900; + st.wMonth = (WORD)localt.tm_mon; + st.wDayOfWeek = (WORD)localt.tm_wday; + st.wDay = (WORD)localt.tm_mday; + st.wHour = (WORD)localt.tm_hour; + st.wMinute = (WORD)localt.tm_min; + st.wSecond = (WORD)localt.tm_sec; + st.wMilliseconds = 0; + SystemTimeToFileTime(&st,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,NULL,&ftm); + CloseHandle(hFile); + + outfile = NULL; +#else + struct utimbuf settime; + + settime.actime = settime.modtime = tartime; + + fclose(outfile); + outfile = NULL; + utime(fname,&settime); +#endif + } + } + } + } + + if (gzclose(in) != Z_OK) + error("failed gzclose"); + + return 0; +} + + +/* =========================================================== */ + +void help(int exitval) +{ + fprintf(stderr, + "untgz v 0.1\n" + " an sample application of zlib 1.0.4\n\n" + "Usage : untgz TGZfile to extract all files\n" + " untgz TGZfile fname ... to extract selected files\n" + " untgz -l TGZfile to list archive contents\n" + " untgz -h to display this help\n\n"); + exit(exitval); +} + +void error(const char *msg) +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + + +/* ====================================================================== */ + +int _CRT_glob = 0; /* disable globbing of the arguments */ + +int main(int argc,char **argv) +{ + int action = TGZ_EXTRACT; + int arg = 1; + char *TGZfile; + gzFile *f; + + + prog = strrchr(argv[0],'\\'); + if (prog == NULL) + { + prog = strrchr(argv[0],'/'); + if (prog == NULL) + { + prog = strrchr(argv[0],':'); + if (prog == NULL) + prog = argv[0]; + else + prog++; + } + else + prog++; + } + else + prog++; + + if (argc == 1) + help(0); + + if (strcmp(argv[arg],"-l") == 0) + { + action = TGZ_LIST; + if (argc == ++arg) + help(0); + } + else if (strcmp(argv[arg],"-h") == 0) + { + help(0); + } + + if ((TGZfile = TGZfname(argv[arg])) == NULL) + TGZnotfound(argv[arg]); + + ++arg; + if ((action == TGZ_LIST) && (arg != argc)) + help(1); + +/* + * Process the TGZ file + */ + switch(action) + { + case TGZ_LIST: + case TGZ_EXTRACT: + f = gzopen(TGZfile,"rb"); + if (f == NULL) + { + fprintf(stderr,"%s: Couldn't gzopen %s\n", + prog, + TGZfile); + return 1; + } + exit(tar(f, action, arg, argc, argv)); + break; + + default: + error("Unknown option!"); + exit(1); + } + + return 0; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt new file mode 100644 index 000000000..10fb44bc5 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt @@ -0,0 +1,69 @@ +See below some functions declarations for Visual Basic. + +Frequently Asked Question: + +Q: Each time I use the compress function I get the -5 error (not enough + room in the output buffer). + +A: Make sure that the length of the compressed buffer is passed by + reference ("as any"), not by value ("as long"). Also check that + before the call of compress this length is equal to the total size of + the compressed buffer and not zero. + + +From: "Jon Caruana" +Subject: Re: How to port zlib declares to vb? +Date: Mon, 28 Oct 1996 18:33:03 -0600 + +Got the answer! (I haven't had time to check this but it's what I got, and +looks correct): + +He has the following routines working: + compress + uncompress + gzopen + gzwrite + gzread + gzclose + +Declares follow: (Quoted from Carlos Rios , in Vb4 form) + +#If Win16 Then 'Use Win16 calls. +Declare Function compress Lib "ZLIB.DLL" (ByVal compr As + String, comprLen As Any, ByVal buf As String, ByVal buflen + As Long) As Integer +Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr + As String, uncomprLen As Any, ByVal compr As String, ByVal + lcompr As Long) As Integer +Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As + String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As + Long) As Integer +#Else +Declare Function compress Lib "ZLIB32.DLL" + (ByVal compr As String, comprLen As Any, ByVal buf As + String, ByVal buflen As Long) As Integer +Declare Function uncompress Lib "ZLIB32.DLL" + (ByVal uncompr As String, uncomprLen As Any, ByVal compr As + String, ByVal lcompr As Long) As Long +Declare Function gzopen Lib "ZLIB32.DLL" + (ByVal file As String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzwrite Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzclose Lib "ZLIB32.DLL" + (ByVal file As Long) As Long +#End If + +-Jon Caruana +jon-net@usa.net +Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/crc32.c b/contrib/vmap_extractor_v2/stormlib/zlib/crc32.c new file mode 100644 index 000000000..60deca2dd --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/crc32.c @@ -0,0 +1,162 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +#define local static + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local const uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLongf * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLongf *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong ZEXPORT crc32(crc, buf, len) + uLong crc; + const Bytef *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/deflate.c b/contrib/vmap_extractor_v2/stormlib/zlib/deflate.c new file mode 100644 index 000000000..16ebdade3 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/deflate.c @@ -0,0 +1,1350 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in ftp://ds.internic.net/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + static const char* my_version = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == Z_NULL) strm->zfree = zcfree; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#ifdef FASTEST + level = 1; +#endif + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; + + s = strm->state; + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + *dest = *source; + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +#ifndef FASTEST +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return len <= s->lookahead ? len : s->lookahead; +} +#endif /* FASTEST */ +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/deflate.h b/contrib/vmap_extractor_v2/stormlib/zlib/deflate.h new file mode 100644 index 000000000..b99a48a52 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/deflate.h @@ -0,0 +1,318 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms b/contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms new file mode 100644 index 000000000..9d364598a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/example.c b/contrib/vmap_extractor_v2/stormlib/zlib/example.c new file mode 100644 index 000000000..e7e367333 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/example.c @@ -0,0 +1,556 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *out, const char *in, + Byte *uncompr, int uncomprLen)); +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(out, in, uncompr, uncomprLen) + const char *out; /* compressed output file */ + const char *in; /* compressed input file */ + Byte *uncompr; + int uncomprLen; +{ + int err; + int len = strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(out, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(in, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + } + strcpy((char*)uncompr, "garbage"); + + uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); + if (uncomprLen != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char *)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, uncomprLen); + uncomprLen = strlen((char*)uncompr); + if (uncomprLen != 6) { /* "hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello+7)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char *)uncompr); + } + + gzclose(file); +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + (argc > 2 ? argv[2] : TESTFILE), + uncompr, (int)uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + exit(0); + return 0; /* to avoid warning */ +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/gzio.c b/contrib/vmap_extractor_v2/stormlib/zlib/gzio.c new file mode 100644 index 000000000..09e0a20b8 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/gzio.c @@ -0,0 +1,875 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_DEFLATE to avoid the compression code. + */ + +/* @(#) $Id$ */ + +#include + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + long startpos; /* start of compressed data in file (header skipped) */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open return NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->startpos = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * startpos anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->startpos = (ftell(s->file) - s->stream.avail_in); + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[20]; + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + if (len != 0) s->stream.avail_in++, s->stream.next_in--; + if (c != EOF) { + s->stream.avail_in++, s->stream.next_in--; + s->transparent = 1; + } + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } + } + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_DEFLATE + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, + s->file); + } + len -= s->stream.avail_out; + s->stream.total_in += (uLong)len; + s->stream.total_out += (uLong)len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may + * be different from s->stream.total_out) in case of + * concatenated .gz files. Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + uLong total_in = s->stream.total_in; + uLong total_out = s->stream.total_out; + + inflateReset(&(s->stream)); + s->stream.total_in = total_in; + s->stream.total_out = total_out; + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_DEFLATE +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + const voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + va_start(va, format); +#ifdef HAS_vsnprintf + (void)vsnprintf(buf, sizeof(buf), format, va); +#else + (void)vsprintf(buf, format, va); +#endif + va_end(va); + len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ + if (len <= 0) return 0; + + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + +#ifdef HAS_snprintf + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#else + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#endif + len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ + if (len <= 0) return 0; + + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->z_err = deflate(&(s->stream), flush); + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_DEFLATE */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->stream.total_in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return (z_off_t)s->stream.total_in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->stream.total_out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->stream.total_in = s->stream.total_out = (uLong)offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if ((uLong)offset >= s->stream.total_out) { + offset -= s->stream.total_out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return (z_off_t)s->stream.total_out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + + if (s->startpos == 0) { /* not a compressed file */ + rewind(s->file); + return 0; + } + + (void) inflateReset(&s->stream); + return fseek(s->file, s->startpos, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + return Z_STREAM_ERROR; +#else + err = do_flush (file, Z_FINISH); + if (err != Z_OK) return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); +#endif + } + return destroy((gz_stream*)file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char* ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infblock.c b/contrib/vmap_extractor_v2/stormlib/zlib/infblock.c new file mode 100644 index 000000000..dd7a6d40a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/infblock.c @@ -0,0 +1,403 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + ZFREE(z, s->sub.trees.blens); + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z) +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * IN assertion: s != Z_NULL + */ +int inflate_blocks_sync_point(s) +inflate_blocks_statef *s; +{ + return s->mode == LENS; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infblock.h b/contrib/vmap_extractor_v2/stormlib/zlib/infblock.h new file mode 100644 index 000000000..173b2267a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/infblock.h @@ -0,0 +1,39 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c b/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c new file mode 100644 index 000000000..9abe5412b --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c @@ -0,0 +1,251 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = q - c->sub.copy.dist; + while (f < s->window) /* modulo window size-"while" instead */ + f += s->end - s->window; /* of "if" handles invalid distances */ + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h b/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h new file mode 100644 index 000000000..46821a02b --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h @@ -0,0 +1,27 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inffast.c b/contrib/vmap_extractor_v2/stormlib/zlib/inffast.c new file mode 100644 index 000000000..aa7f1d4d2 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/inffast.c @@ -0,0 +1,183 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + r = q - d; + if (r < s->window) /* wrap if needed */ + { + do { + r += s->end - s->window; /* force pointer in window */ + } while (r < s->window); /* covers invalid distances */ + e = s->end - r; + if (c > e) + { + c -= e; /* wrapped copy */ + do { + *q++ = *r++; + } while (--e); + r = s->window; + do { + *q++ = *r++; + } while (--c); + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inffast.h b/contrib/vmap_extractor_v2/stormlib/zlib/inffast.h new file mode 100644 index 000000000..a31a4bbb0 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/inffast.h @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h b/contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h new file mode 100644 index 000000000..77f7e7631 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inflate.c b/contrib/vmap_extractor_v2/stormlib/zlib/inflate.c new file mode 100644 index 000000000..dfb2e867d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/inflate.c @@ -0,0 +1,366 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int ZEXPORT inflateReset(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int ZEXPORT inflateEnd(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +int ZEXPORT inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int ZEXPORT inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int ZEXPORT inflate(z, f) +z_streamp z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + + +int ZEXPORT inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c b/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c new file mode 100644 index 000000000..4c32ca30d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c @@ -0,0 +1,454 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#if !defined(BUILDFIXED) && !defined(STDC) +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ +#endif + +const char inflate_copyright[] = + " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build(b, n, s, d, e, t, m, hp, hn, v) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= 288) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +const uIntf *d; /* list of base values for non-simple codes */ +const uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +inflate_huft *hp; /* space for trees */ +uInt *hn; /* hufts used in space */ +uIntf *v; /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), or Z_DATA_ERROR if the input is invalid. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_DATA_ERROR; /* overflow of MANY */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, hp, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#ifdef BUILDFIXED +local int fixed_built = 0; +#define FIXEDH 544 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; +#else +#include "inffixed.h" +#endif + + +int inflate_trees_fixed(bl, bd, tl, td, z) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for memory allocation */ +{ +#ifdef BUILDFIXED + /* build fixed tables if not already */ + if (!fixed_built) + { + int k; /* temporary variable */ + uInt f = 0; /* number of hufts used in fixed_mem */ + uIntf *c; /* length list for huft_build */ + uIntf *v; /* work area for huft_build */ + + /* allocate memory */ + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + { + ZFREE(z, c); + return Z_MEM_ERROR; + } + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 9; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, + fixed_mem, &f, v); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, + fixed_mem, &f, v); + + /* done */ + ZFREE(z, v); + ZFREE(z, c); + fixed_built = 1; + } +#endif + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h b/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h new file mode 100644 index 000000000..04b73b729 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h @@ -0,0 +1,58 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infutil.c b/contrib/vmap_extractor_v2/stormlib/zlib/infutil.c new file mode 100644 index 000000000..9a076221f --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/infutil.c @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infutil.h b/contrib/vmap_extractor_v2/stormlib/zlib/infutil.h new file mode 100644 index 000000000..4401df82f --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/infutil.h @@ -0,0 +1,98 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/maketree.c b/contrib/vmap_extractor_v2/stormlib/zlib/maketree.c new file mode 100644 index 000000000..a16d4b146 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/maketree.c @@ -0,0 +1,85 @@ +/* maketree.c -- make inffixed.h table for decoding fixed codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* This program is included in the distribution for completeness. + You do not need to compile or run this program since inffixed.h + is already included in the distribution. To use this program + you need to compile zlib with BUILDFIXED defined and then compile + and link this program with the zlib library. Then the output of + this program can be piped to inffixed.h. */ + +#include +#include +#include "zutil.h" +#include "inftrees.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* generate initialization table for an inflate_huft structure array */ +void maketree(uInt b, inflate_huft *t) +{ + int i, e; + + i = 0; + while (1) + { + e = t[i].exop; + if (e && (e & (16+64)) == 0) /* table pointer */ + { + fprintf(stderr, "maketree: cannot initialize sub-tables!\n"); + exit(1); + } + if (i % 4 == 0) + printf("\n "); + printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base); + if (++i == (1< +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + int len = strlen(file); + + strcpy(buf, file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, GZ_SUFFIX); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...] + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int uncompr = 0; + gzFile file; + char outmode[20]; + + strcpy(outmode, "wb6 "); + + prog = argv[0]; + argc--, argv++; + + while (argc > 0) { + if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + do { + if (uncompr) { + file_uncompress(*argv); + } else { + file_compress(*argv, outmode); + } + } while (argv++, --argc); + } + exit(0); + return 0; /* to avoid warning */ +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32 b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32 new file mode 100644 index 000000000..f476da916 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32 @@ -0,0 +1,104 @@ +# Makefile for zlib +# Borland C++ + +# This version of the zlib makefile was adapted by Chris Young for use +# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode +# flat memory model. It was created for use with POV-Ray ray tracer and +# you may choose to edit the CFLAGS to suit your needs but the +# switches -WX and -DMSDOS are required. +# -- Chris Young 76702.1655@compuserve.com + +# To use, do "make -fmakefile.b32" + +# See zconf.h for details about the memory requirements. + +# ------------- Borland C++ ------------- +MODEL=-WX +CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS +CC=bcc32 +LD=bcc32 +LIB=tlib +LDFLAGS= $(MODEL) +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + del zlib.lib + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor new file mode 100644 index 000000000..f5651b40f --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor @@ -0,0 +1,125 @@ +# Makefile for zlib +# Borland C++ ************ UNTESTED *********** + +# To use, do "make -fmakefile.bor" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C++, Borland C++ ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of s, m, c, l (small, medium, compact, large) +MODEL=l + +CC=bcc +# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version +LD=$(CC) +AR=tlib + +# compiler flags +CFLAGS=-O2 -Z -m$(MODEL) $(LOC) +# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0 + +LDFLAGS=-m$(MODEL) + +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +ZLIB_H = zlib.h zconf.h +ZUTIL_H = zutil.h $(ZLIB_H) + +ZLIB_LIB = zlib_$(MODEL).lib + +all: test + +# individual dependencies and action rules: +adler32.obj: adler32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c $(ZUTIL_H) infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) +$(OBJP1) + $(AR) $(ZLIB_LIB) +$(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2 b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2 new file mode 100644 index 000000000..0ab431c8a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2 @@ -0,0 +1,100 @@ +# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.dj2; make test -fmakefile.dj2 +# +# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: +# +# make install -fmakefile.dj2 +# +# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as +# in the sample below if the pattern of the DJGPP distribution is to +# be followed. Remember that, while 'es around <=> are ignored in +# makefiles, they are *not* in batch files or in djgpp.env. +# - - - - - +# [make] +# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include +# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib +# BUTT=-m486 +# - - - - - +# Alternately, these variables may be defined below, overriding the values +# in djgpp.env, as +# INCLUDE_PATH=c:\usr\include +# LIBRARY_PATH=c:\usr\lib + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx new file mode 100644 index 000000000..0e5e5cc43 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc new file mode 100644 index 000000000..562201d87 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc @@ -0,0 +1,121 @@ +# Makefile for zlib +# Microsoft C 5.1 or later + +# To use, do "make makefile.msc" +# To compile in small model, set below: MODEL=S + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of S, M, C, L (small, medium, compact, large) +MODEL=L + +CC=cl +CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC) +#-Ox generates bad code with MSC 5.1 +LIB_CFLAGS=-Zl $(CFLAGS) + +LD=link +LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode +# "/farcall/packcode" are only useful for `large code' memory models +# but should be a "no-op" for small code models. + +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +ZLIB_H = zlib.h zconf.h +ZUTIL_H = zutil.h $(ZLIB_H) + +ZLIB_LIB = zlib_$(MODEL).lib + +all: $(ZLIB_LIB) example.exe minigzip.exe + +# individual dependencies and action rules: +adler32.obj: adler32.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +compress.obj: compress.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +crc32.obj: crc32.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +gzio.obj: gzio.c $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h + $(CC) -c $(LIB_CFLAGS) $*.c + +infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h + $(CC) -c $(LIB_CFLAGS) $*.c + +inflate.obj: inflate.c $(ZUTIL_H) infblock.h + $(CC) -c $(LIB_CFLAGS) $*.c + +inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h + $(CC) -c $(LIB_CFLAGS) $*.c + +infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h + $(CC) -c $(LIB_CFLAGS) $*.c + +inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h + $(CC) -c $(LIB_CFLAGS) $*.c + +trees.obj: trees.c deflate.h $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +uncompr.obj: uncompr.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +zutil.obj: zutil.c $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +example.obj: example.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + if exist $(ZLIB_LIB) del $(ZLIB_LIB) + lib $(ZLIB_LIB) $(OBJ1); + lib $(ZLIB_LIB) $(OBJ2); + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB); + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB); + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc new file mode 100644 index 000000000..63e055035 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc @@ -0,0 +1,108 @@ +# Makefile for zlib +# TurboC 2.0 + +# To use, do "make -fmakefile.tc" +# To compile in small model, set below: MODEL=-ms + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C 2.0 ------------- +MODEL=l +# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +CFLAGS=-O2 -G -Z -m$(MODEL) +CC=tcc -I\tc\include +LD=tcc -L\tc\lib +AR=tlib +LDFLAGS=-m$(MODEL) -f- +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +ZLIB_H = zlib.h zconf.h +ZUTIL_H = zutil.h $(ZLIB_H) + +ZLIB_LIB = zlib_$(MODEL).lib + +all: test + +adler32.obj: adler32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c $(ZUTIL_H) infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) +$(OBJP1) + $(AR) $(ZLIB_LIB) +$(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) -eexample.exe example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) -eminigzip.exe minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w32 b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w32 new file mode 100644 index 000000000..0a05fa9a4 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w32 @@ -0,0 +1,97 @@ +# Makefile for zlib +# Microsoft 32-bit Visual C++ 4.0 or later (may work on earlier versions) + +# To use, do "nmake /f makefile.w32" + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft Visual C++ 4.0 and later ------------- +MODEL= +CFLAGS=-Ox -GA3s -nologo -W3 +CC=cl +LD=link +LDFLAGS= +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: zlib.lib example.exe minigzip.exe + +adler32.obj: adler32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zlib.lib: $(OBJ1) $(OBJ2) + if exist zlib.lib del zlib.lib + lib /OUT:zlib.lib $(OBJ1) $(OBJ2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib /OUT:example.exe /SUBSYSTEM:CONSOLE + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib /OUT:minigzip.exe /SUBSYSTEM:CONSOLE + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat new file mode 100644 index 000000000..44bf8607f --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat @@ -0,0 +1,103 @@ +# Makefile for zlib +# Watcom 10a + +# This version of the zlib makefile was adapted by Chris Young for use +# with Watcom 10a 32-bit protected mode flat memory model. It was created +# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to +# suit your needs but the -DMSDOS is required. +# -- Chris Young 76702.1655@compuserve.com + +# To use, do "wmake -f makefile.wat" + +# See zconf.h for details about the memory requirements. + +# ------------- Watcom 10a ------------- +MODEL=-mf +CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS +CC=wcc386 +LD=wcl386 +LIB=wlib -b -c +LDFLAGS= +O=.obj + +# variables +OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) +OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) +OBJ3=infutil$(O) inffast$(O) +OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O) +OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O) +OBJP3=infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +crc32.obj: crc32.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h & + infcodes.h infutil.h + $(CC) $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h & + infcodes.h inffast.h + $(CC) $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) $(OBJ3) + del zlib.lib + $(LIB) zlib.lib +$(OBJP1) + $(LIB) zlib.lib +$(OBJP2) + $(LIB) zlib.lib +$(OBJP3) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: minigzip.exe example.exe + example + echo hello world | minigzip | minigzip -d >test + type test + +#clean: +# del *.obj +# del *.exe diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def new file mode 100644 index 000000000..6c04412f9 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def @@ -0,0 +1,60 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + +EXETYPE NT + +SUBSYSTEM WINDOWS + +STUB 'WINSTUB.EXE' + +VERSION 1.13 + +CODE EXECUTE READ + +DATA READ WRITE + +HEAPSIZE 1048576,4096 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc new file mode 100644 index 000000000..556d4ff95 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,1,3,0 + PRODUCTVERSION 1,1,3,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", "1.1.3\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlib.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-1998 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx new file mode 100644 index 000000000..2d475b184 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx @@ -0,0 +1,138 @@ +# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc -Zwin32 + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc new file mode 100644 index 000000000..cdd652f23 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc @@ -0,0 +1,87 @@ +# Makefile for zlib. Modified for mingw32 by C. Spieler, 6/16/98. +# (This Makefile is directly derived from Makefile.dj2) +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.gcc; make test -fmakefile.gcc +# +# To install libz.a, zconf.h and zlib.h in the mingw32 directories, type: +# +# make install -fmakefile.gcc +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt new file mode 100644 index 000000000..b250f2ac7 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt @@ -0,0 +1,88 @@ +# Makefile for zlib + +!include + +CC=cl +LD=link +CFLAGS=-O -nologo +LDFLAGS= +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) + +all: zlib.dll example.exe minigzip.exe + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +zlib.dll: $(OBJ1) $(OBJ2) zlib.dnt + link $(dlllflags) -out:$@ -def:zlib.dnt $(OBJ1) $(OBJ2) $(guilibsdll) + +zlib.lib: zlib.dll + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + del *.obj + del *.exe + del *.dll + del *.lib diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt b/contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt new file mode 100644 index 000000000..7f9475cfb --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt @@ -0,0 +1,47 @@ +LIBRARY zlib.dll +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2 b/contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2 new file mode 100644 index 000000000..4f569471e --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2 @@ -0,0 +1,136 @@ +# Makefile for zlib under OS/2 using GCC (PGCC) +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# cp Makefile.os2 .. +# cd .. +# make -f Makefile.os2 test + +# This makefile will build a static library z.lib, a shared library +# z.dll and a import library zdll.lib. You can use either z.lib or +# zdll.lib by specifying either -lz or -lzdll on gcc's command line + +CC=gcc -Zomf -s + +CFLAGS=-O6 -Wall +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +#################### BUG WARNING: ##################### +## infcodes.c hits a bug in pgcc-1.0, so you have to use either +## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem) +## This bug is reportedly fixed in pgcc >1.0, but this was not tested +CFLAGS+=-fno-force-mem + +LDFLAGS=-s -L. -lzdll -Zcrtdll +LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll + +VER=1.1.0 +ZLIB=z.lib +SHAREDLIB=z.dll +SHAREDLIBIMP=zdll.lib +LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP) + +AR=emxomfar cr +IMPLIB=emximp +RANLIB=echo +TAR=tar +SHELL=bash + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \ + algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \ + contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 + +all: example.exe minigzip.exe + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +$(ZLIB): $(OBJS) + $(AR) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +$(SHAREDLIB): $(OBJS) os2/z.def + $(LDSHARED) -o $@ $^ + +$(SHAREDLIBIMP): os2/z.def + $(IMPLIB) -o $@ $^ + +example.exe: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip.exe: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def b/contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def new file mode 100644 index 000000000..4c753f1a3 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def @@ -0,0 +1,51 @@ +; +; Slightly modified version of ../nt/zlib.dnt :-) +; + +LIBRARY Z +DESCRIPTION "Zlib compression library for OS/2" +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 + compress + crc32 + deflate + deflateCopy + deflateEnd + deflateInit2_ + deflateInit_ + deflateParams + deflateReset + deflateSetDictionary + gzclose + gzdopen + gzerror + gzflush + gzopen + gzread + gzwrite + inflate + inflateEnd + inflateInit2_ + inflateInit_ + inflateReset + inflateSetDictionary + inflateSync + uncompress + zlibVersion + gzprintf + gzputc + gzgetc + gzseek + gzrewind + gztell + gzeof + gzsetparams + zError + inflateSyncPoint + get_crc_table + compress2 + gzputs + gzgets diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/trees.c b/contrib/vmap_extractor_v2/stormlib/zlib/trees.c new file mode 100644 index 000000000..0a9840567 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/trees.c @@ -0,0 +1,1214 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/trees.h b/contrib/vmap_extractor_v2/stormlib/zlib/trees.h new file mode 100644 index 000000000..72facf900 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c b/contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c new file mode 100644 index 000000000..a287714f5 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c @@ -0,0 +1,58 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zconf.h b/contrib/vmap_extractor_v2/stormlib/zlib/zconf.h new file mode 100644 index 000000000..eb0ae2e1a --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zconf.h @@ -0,0 +1,279 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT __declspec(dllexport) WINAPI +# define ZEXPORTRVA __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT _export +# define ZEXPORTVA _export +# endif +# endif +# endif +#endif + +#if defined (__BEOS__) +# if defined (ZLIB_DLL) +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.3 b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.3 new file mode 100644 index 000000000..3a6e45047 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.3 @@ -0,0 +1,107 @@ +.TH ZLIB 3 "11 March 2002" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.I gzip +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. The decoder checks +the consistency of the compressed data, so the library should never +crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h. +The distribution source includes examples of use of the library +the files +.I example.c +and +.IR minigzip.c . +.LP +A Java implementation of +.IR zlib +is available in the Java Development Kit 1.1 +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmarquess@bfsec.bt.co.uk) +is available at CPAN (Comprehensive Perl Archive Network) sites, +such as: +.IP +ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* +.LP +A Python interface to +.IR zlib +written by A.M. Kuchling +is available from the Python Software Association sites, such as: +.IP +ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz +.SH "SEE ALSO" +Questions about zlib should be sent to: +.IP +zlib@quest.jpl.nasa.gov +or, if this fails, to the author addresses given below. +The zlib home page is: +.IP +http://www.cdrom.com/pub/infozip/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +ftp://ds.internic.net/rfc/rfc1950.txt (zlib format) +.br +rfc1951.txt (deflate format) +.br +rfc1952.txt (gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.SH AUTHORS +Version 1.1.4 +Copyright (C) 1995-2002 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.h b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.h new file mode 100644 index 000000000..52cb529f6 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.h @@ -0,0 +1,893 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.html b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.html new file mode 100644 index 000000000..c34370386 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.html @@ -0,0 +1,971 @@ + + + + zlib general purpose compression library version 1.1.4 + + + + + +

zlib 1.1.4 Manual

+
+

Contents

+
    +
  1. Prologue +
  2. Introduction +
  3. Utility functions +
  4. Basic functions +
  5. Advanced functions +
  6. Constants +
  7. struct z_stream_s +
  8. Checksum functions +
  9. Misc +
+
+

Prologue

+ 'zlib' general purpose compression library version 1.1.4, March 11th, 2002 +

+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler +

+ This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. +

+ Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: +

    +
  1. The origin of this software must not be misrepresented ; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +
  2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +
  3. This notice may not be removed or altered from any source distribution. +
+ +
+
Jean-loup Gailly +
jloup@gzip.org +
Mark Adler +
madler@alumni.caltech.edu +
+ + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files + + ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), + + rfc1951.txt + (deflate format) and + + rfc1952.txt + (gzip format). +

+ This manual is converted from zlib.h by + piaip +

+ Visit + http://ftp.cdrom.com/pub/infozip/zlib/ + for the official zlib web page. +

+ +


+

Introduction

+ The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. +

+ + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +

+ + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. +

+ + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +

+ +


+

Utility functions

+ The following utility functions are implemented on top of the +
basic stream-oriented functions. + To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +

Function list

+
    +
  • int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
  • int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
  • int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
  • typedef voidp gzFile; +
  • gzFile gzopen (const char *path, const char *mode); +
  • gzFile gzdopen (int fd, const char *mode); +
  • int gzsetparams (gzFile file, int level, int strategy); +
  • int gzread (gzFile file, voidp buf, unsigned len); +
  • int gzwrite (gzFile file, const voidp buf, unsigned len); +
  • int VA gzprintf (gzFile file, const char *format, ...); +
  • int gzputs (gzFile file, const char *s); +
  • char * gzgets (gzFile file, char *buf, int len); +
  • int gzputc (gzFile file, int c); +
  • int gzgetc (gzFile file); +
  • int gzflush (gzFile file, int flush); +
  • z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
  • z_off_t gztell (gzFile file); +
  • int gzrewind (gzFile file); +
  • int gzeof (gzFile file); +
  • int gzclose (gzFile file); +
  • const char * gzerror (gzFile file, int *errnum); +
+

Function description

+
+
int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
+ Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer.

+ This function can be used to compress a whole file at once if the + input file is mmap'ed.

+ compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer.

+ +

int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
+ Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. +

+ + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +

+ +

int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
+ Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer.

+ This function can be used to decompress a whole file at once if the + input file is mmap'ed. +

+ + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +

+ +

typedef voidp gzFile; +

+ +

gzFile gzopen (const char *path, const char *mode); +
+ Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) +

+ + gzopen can be used to read a file which is not in gzip format ; in this + case gzread will directly read from the file without decompression. +

+ + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state ; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +

+ +

gzFile gzdopen (int fd, const char *mode); +
+ gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. +

+ The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). +

+ gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +

+ +

int gzsetparams (gzFile file, int level, int strategy); +
+ Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. +

+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +

+ +

int gzread (gzFile file, voidp buf, unsigned len); +
+ Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. +

+ gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). +

+ +

int gzwrite (gzFile file, const voidp buf, unsigned len); +
+ Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +

+ +

int VA gzprintf (gzFile file, const char *format, ...); +
+ Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +

+ +

int gzputs (gzFile file, const char *s); +
+ Writes the given null-terminated string to the compressed file, excluding + the terminating null character. +

+ gzputs returns the number of characters written, or -1 in case of error. +

+ +

char * gzgets (gzFile file, char *buf, int len); +
+ Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. +

+ gzgets returns buf, or Z_NULL in case of error. +

+ +

int gzputc (gzFile file, int c); +
+ Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +

+ +

int gzgetc (gzFile file); +
+ Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +

+ +

int gzflush (gzFile file, int flush); +
+ Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. +

+ gzflush should be called only when strictly necessary because it can + degrade compression. +

+ +

z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
+ Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. +

+ If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported ; gzseek then compresses a sequence of zeroes up to the new + starting position. +

+ gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +

+ +

int gzrewind (gzFile file); +
+ Rewinds the given file. This function is supported only for reading. +

+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +

+ +

z_off_t gztell (gzFile file); +
+ Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +

+ + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +

+ +

int gzeof (gzFile file); +
+ Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +

+ +

int gzclose (gzFile file); +
+ Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +

+ +

const char * gzerror (gzFile file, int *errnum); +
+ Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +

+

+
+

Basic functions

+

Function list

+
+ +

Function description

+
+
const char * zlibVersion (void); +
The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. +

+ +

int deflateInit (z_streamp strm, int level); +
+ Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. +

+ + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). +

+ + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). +

+ + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +

+ +

int deflate (z_streamp strm, int flush); +
+ deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush.

+ + The detailed semantics are as follows. deflate performs one or both of the + following actions: + +

    +
  • Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + +
  • + Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. +

+ + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly ; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. +

+ + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. +

+ + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. +

+ + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). +

+ + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space ; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. +

+ + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. +

+ + deflate() sets strm-> adler to the adler32 checksum of all input read + so far (that is, total_in bytes). +

+ + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. +

+ + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +

+ +

int deflateEnd (z_streamp strm); +
+ All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

+ + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +

+ +

int inflateInit (z_streamp strm); +
+ Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly ; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. +

+ + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +

+ +

int inflate (z_streamp strm, int flush); +
+ inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. +

+ + The detailed semantics are as follows. inflate performs one or both of the + following actions: + +

    +
  • Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + +
  • Provide more output starting at next_out and update next_out and + avail_out accordingly. inflate() provides as much output as possible, + until there is no more input data or no more space in the output buffer + (see below about the flush parameter). +

+ + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. +

+ + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. +

+ + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed ; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. +

+ + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT ; otherwise + it sets strm-> adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. +

+ + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +

+ +

int inflateEnd (z_streamp strm); +
+ All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

+ + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +

+
+

Advanced functions

+ The following functions are needed only in some special applications. +

Function list

+
+

Function description

+
+
int deflateInit2 (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); + +
This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller.

+ + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library.

+ + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead.

+ + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio ; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel.

+ + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching ; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately.

+ + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate().

+ +

int deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
+ Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary).

+ + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy ; the data can then be compressed better than + with the default empty dictionary.

+ + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front.

+ + Upon return of this function, strm-> adler is set to the Adler32 value + of the dictionary ; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.)

+ + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate().

+ +

int deflateCopy (z_streamp dest, z_streamp source); +
+ Sets the destination stream as a complete copy of the source stream.

+ + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory.

+ + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination.

+ +

int deflateReset (z_streamp strm); +
This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2.

+ + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL).

+ +

int deflateParams (z_streamp strm, int level, int strategy); +
+ Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate().

+ + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm-> avail_out must be + non-zero.

+ + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero.

+ +

int inflateInit2 (z_streamp strm, int windowBits); + +
This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller.

+ + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window.

+ + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.)

+ +

int inflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
+ Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary).

+ + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate().

+ +

int inflateSync (z_streamp strm); + +
Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided.

+ + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data.

+ +

int inflateReset (z_streamp strm); +
+ This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. +

+ + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +

+

+ +
+

Checksum functions

+ These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +

Function list

+
+

Function description

+
+
uLong adler32 (uLong adler, const Bytef *buf, uInt len); +
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. +

+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: +

+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+   
+ +
uLong crc32 (uLong crc, const Bytef *buf, uInt len); +
+ Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: +
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+   
+
+
+

struct z_stream_s

+ +
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream ;
+
+typedef z_stream FAR * z_streamp;  ÿ 
+
+
+ The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application.

+ + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value.

+ + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe.

+ + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). +

+ + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step).

+ +


+

Constants

+ +
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 
+	/* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+/* Allowed flush values ; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy ; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions less than 1.0.2 */
+
+
+ +
+

Misc

+
deflateInit and inflateInit are macros to allow checking the zlib version + and the compiler's view of z_stream. +

+ Other functions: +

+
const char * zError (int err); +
int inflateSyncPoint (z_streamp z); +
const uLongf * get_crc_table (void); +
+
+ + Last update: Wed Oct 13 20:42:34 1999
+ piapi@csie.ntu.edu.tw +
+ + + diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c b/contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c new file mode 100644 index 000000000..9a6ac61f5 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c @@ -0,0 +1,19 @@ +/* zmemory.c + Internal memory alloc and memory free functions + */ + +#include + +#include "zlib.h" + +const char *z_errmsg[10]; // Needed by zlib + +voidpf zcalloc(voidpf opaque, uInt items, uInt size) +{ + return (voidpf)calloc(items, size); +} + +void zcfree(voidpf opaque, voidpf address) +{ + free(address); +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zutil.c b/contrib/vmap_extractor_v2/stormlib/zlib/zutil.c new file mode 100644 index 000000000..9a076221f --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zutil.c @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zutil.h b/contrib/vmap_extractor_v2/stormlib/zlib/zutil.h new file mode 100644 index 000000000..718ebc15b --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlib/zlib/zutil.h @@ -0,0 +1,220 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, + uInt len)); +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ diff --git a/contrib/vmap_extractor_v2/stormlibdll/DllMain.c b/contrib/vmap_extractor_v2/stormlibdll/DllMain.c new file mode 100644 index 000000000..cbfa84a08 --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlibdll/DllMain.c @@ -0,0 +1,24 @@ +/*****************************************************************************/ +/* DllMain.c Copyright (c) Ladislav Zezula 2006 */ +/*---------------------------------------------------------------------------*/ +/* Description: DllMain for the StormLib.dll library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 23.11.06 1.00 Lad The first version of DllMain.c */ +/*****************************************************************************/ + +#define WIN32_LEAN_AND_MEAN +#include + +//----------------------------------------------------------------------------- +// DllMain + +DWORD WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) +{ + UNREFERENCED_PARAMETER(hInst); + UNREFERENCED_PARAMETER(dwReason); + UNREFERENCED_PARAMETER(lpReserved); + + return TRUE; +} diff --git a/contrib/vmap_extractor_v2/stormlibdll/StormLib.def b/contrib/vmap_extractor_v2/stormlibdll/StormLib.def new file mode 100644 index 000000000..8ec49053d --- /dev/null +++ b/contrib/vmap_extractor_v2/stormlibdll/StormLib.def @@ -0,0 +1,47 @@ +LIBRARY StormLib.dll + +EXPORTS + + SFileSetLocale + SFileGetLocale + SFileOpenArchive + SFileCloseArchive + + SFileOpenFileEx + SFileCloseFile + SFileGetFilePos + SFileGetFileSize + SFileSetFilePointer + SFileReadFile + SFileExtractFile + + SFileAddListFile + + SFileCreateArchiveEx + + SFileAddFile + SFileAddWave + SFileRemoveFile + SFileRenameFile + SFileSetFileLocale + + SFileHasFile + SFileGetFileName + SFileGetFileInfo + + SFileFindFirstFile + SFileFindNextFile + SFileFindClose + + SListFileFindFirstFile + SListFileFindNextFile + SListFileFindClose + + SFileSetCompactCallback + SFileCompactArchive + + SFileEnumLocales + + SCompCompress + SCompDecompress + SCompSetDataCompression diff --git a/contrib/vmap_extractor_v2/vmapExtractor_VC71.sln b/contrib/vmap_extractor_v2/vmapExtractor_VC71.sln new file mode 100644 index 000000000..13156cd66 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapExtractor_VC71.sln @@ -0,0 +1,23 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmapExtractor", "vmapExtractor_VC71.vcproj", "{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug Ansi Static = Debug Ansi Static + Release Ansi Static = Release Ansi Static + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Debug Ansi Static.ActiveCfg = Debug Ansi Static|Win32 + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Debug Ansi Static.Build.0 = Debug Ansi Static|Win32 + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Release Ansi Static.ActiveCfg = Release Ansi Static|Win32 + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Release Ansi Static.Build.0 = Release Ansi Static|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/contrib/vmap_extractor_v2/vmapExtractor_VC71.vcproj b/contrib/vmap_extractor_v2/vmapExtractor_VC71.vcproj new file mode 100644 index 000000000..c546fcc33 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapExtractor_VC71.vcproj @@ -0,0 +1,786 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/vmap_extractor_v2/vmapExtractor_VC80.sln b/contrib/vmap_extractor_v2/vmapExtractor_VC80.sln new file mode 100644 index 000000000..cc24730b1 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapExtractor_VC80.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmapExtractor", "vmapExtractor_VC80.vcproj", "{87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug Ansi Static|Win32 = Debug Ansi Static|Win32 + Release Ansi Static|Win32 = Release Ansi Static|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Debug Ansi Static|Win32.ActiveCfg = Debug Ansi Static|Win32 + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Debug Ansi Static|Win32.Build.0 = Debug Ansi Static|Win32 + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Release Ansi Static|Win32.ActiveCfg = Release Ansi Static|Win32 + {87335BBF-5DA8-4FEC-A51E-1FB948F2FFE9}.Release Ansi Static|Win32.Build.0 = Release Ansi Static|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/vmap_extractor_v2/vmapExtractor_VC80.vcproj b/contrib/vmap_extractor_v2/vmapExtractor_VC80.vcproj new file mode 100644 index 000000000..5d8cdea90 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapExtractor_VC80.vcproj @@ -0,0 +1,1000 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp b/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp new file mode 100644 index 000000000..b798263ca --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp @@ -0,0 +1,227 @@ +#include "adtfile.h" + + +char * GetPlainName(char * FileName) +{ + char * szTemp; + + if((szTemp = strrchr(FileName, '\\')) != NULL) + FileName = szTemp + 1; + return FileName; +} + +void fixnamen(char *name, size_t len) +{ + for (size_t i=0; i0 && name[i]>='A' && name[i]<='Z' && isalpha(name[i-1])) + { + name[i] |= 0x20; + } else if ((i==0 || !isalpha(name[i-1])) && name[i]>='a' && name[i]<='z') + { + name[i] &= ~0x20; + } + } +} +void fixname2(char *name, size_t len) +{ + for (size_t i=0; iopen()) + { + m2->ConvertToVMAPModel((char*)szLocalFile); + } + delete m2; + + } + else + fclose(output); + } + + delete[] buf; + } + + } + else if (!strcmp(fourcc,"MWMO")) + { + if (size) + { + + char *buf = new char[size]; + ADT.read(buf, size); + char *p=buf; + int q = 0; + WmoInstansName = new string[size]; + while (p= recordSize); + + data = new unsigned char[recordSize*recordCount+stringSize]; + stringTable = data + recordSize*recordCount; + f.read(data,recordSize*recordCount+stringSize); + f.close(); + return true; +} + +DBCFile::~DBCFile() +{ + delete [] data; +} + +DBCFile::Record DBCFile::getRecord(size_t id) +{ + assert(data); + return Record(*this, data + id*recordSize); +} + +DBCFile::Iterator DBCFile::begin() +{ + assert(data); + return Iterator(*this, data); +} +DBCFile::Iterator DBCFile::end() +{ + assert(data); + return Iterator(*this, stringTable); +} + diff --git a/contrib/vmap_extractor_v2/vmapextract/dbcfile.h b/contrib/vmap_extractor_v2/vmapextract/dbcfile.h new file mode 100644 index 000000000..bf6b8635a --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/dbcfile.h @@ -0,0 +1,139 @@ +#ifndef DBCFILE_H +#define DBCFILE_H +#define __STORMLIB_SELF__ + +#include +#include +#include "Stormlib.h" + +class DBCFile +{ +public: + DBCFile(const std::string &filename); + ~DBCFile(); + + // Open database. It must be openened before it can be used. + bool open(); + + // TODO: Add a close function? + + // Database exceptions + class Exception + { + public: + Exception(const std::string &message): message(message) + { } + virtual ~Exception() + { } + const std::string &getMessage() {return message;} + private: + std::string message; + }; + + // + class NotFound: public Exception + { + public: + NotFound(): Exception("Key was not found") + { } + }; + + // Iteration over database + class Iterator; + class Record + { + public: + Record& operator= (const Record& r) + { + file = r.file; + offset = r.offset; + return *this; + } + float getFloat(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+field*4); + } + unsigned int getUInt(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+(field*4)); + } + int getInt(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+field*4); + } + unsigned char getByte(size_t ofs) const + { + assert(ofs < file.recordSize); + return *reinterpret_cast(offset+ofs); + } + const char *getString(size_t field) const + { + assert(field < file.fieldCount); + size_t stringOffset = getUInt(field); + assert(stringOffset < file.stringSize); + //char * tmp = (char*)file.stringTable + stringOffset; + //unsigned char * tmp2 = file.stringTable + stringOffset; + return reinterpret_cast(file.stringTable + stringOffset); + } + private: + Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} + unsigned char *offset; + DBCFile &file; + + friend class DBCFile; + friend class Iterator; + }; + + /* Iterator that iterates over records */ + class Iterator + { + public: + Iterator(DBCFile &file, unsigned char *offset): + record(file, offset) {} + /// Advance (prefix only) + Iterator & operator++() { + record.offset += record.file.recordSize; + return *this; + } + /// Return address of current instance + Record const & operator*() const { return record; } + const Record* operator->() const { + return &record; + } + /// Comparison + bool operator==(const Iterator &b) const + { + return record.offset == b.record.offset; + } + bool operator!=(const Iterator &b) const + { + return record.offset != b.record.offset; + } + private: + Record record; + }; + + // Get record by id + Record getRecord(size_t id); + /// Get begin iterator over records + Iterator begin(); + /// Get begin iterator over records + Iterator end(); + /// Trivial + size_t getRecordCount() const { return recordCount;} + size_t getFieldCount() const { return fieldCount; } + +private: + std::string filename; + size_t recordSize; + size_t recordCount; + size_t fieldCount; + size_t stringSize; + unsigned char *data; + unsigned char *stringTable; +}; + +#endif diff --git a/contrib/vmap_extractor_v2/vmapextract/model.cpp b/contrib/vmap_extractor_v2/vmapextract/model.cpp new file mode 100644 index 000000000..7dca7841d --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/model.cpp @@ -0,0 +1,261 @@ +//#include "common.h" +#include "model.h" +//#include "world.h" +#include +#include + +//int globalTime = 0; + +Model::Model(std::string &filename) : filename(filename) +{ +} + +bool Model::open() +{ + MPQFile f(filename.c_str()); + + ok = !f.isEof(); + + if (!ok) + { + f.close(); + printf("Error loading model %s\n", filename.c_str()); + return false; + } + + memcpy(&header, f.getBuffer(), sizeof(ModelHeader)); + if(header.nBoundingTriangles > 0) { + +#if 0 + animated = isAnimated(f); + if(animated) + { + f.close(); + return false; + } +#endif + trans = 1.0f; + origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices); + + vertices = new Vec3D[header.nVertices]; + normals = new Vec3D[header.nVertices]; + + for (size_t i=0; iofsIndex); + uint16 *triangles = (uint16*)(f.getBuffer() + view->ofsTris); + + nIndices = view->nTris; + indices = new uint16[nIndices]; + for (size_t i = 0; i0) { + ModelBoneDef &bb = bo[verts[i].bones[b]]; + if (bb.translation.type || bb.rotation.type || bb.scaling.type || (bb.flags&8)) { + if (bb.flags&8) { + // if we have billboarding, the model will need per-instance animation + ind = true; + } + animGeometry = true; + break; + } + } + } + } + + if (animGeometry) animBones = true; + else { + for (size_t i=0; i 0; + + bool animMisc = header.nCameras>0 || // why waste time, pretty much all models with cameras need animation + header.nLights>0 || // same here + header.nParticleEmitters>0 || + header.nRibbonEmitters>0; + + if (animMisc) animBones = true; + + // animated colors + if (header.nColors) { + ModelColorDef *cols = (ModelColorDef*)(f.getBuffer() + header.ofsColors); + for (size_t i=0; i0) + { + fwrite(indices, sizeof(unsigned short), nIdexes, output); + } + fwrite("VERT",4, 1, output); + wsize = sizeof(int) + sizeof(float) * 3 * nVertices; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&nVertices, sizeof(int), 1, output); + if(nVertices >0) + { + for(int vpos=0; vpos + +class Model; +class WMOInstance; + +Vec3D fixCoordSystem(Vec3D v); + + + + +class Model +{ +public: + ModelHeader header; + ModelAnimation *anims; + int *globalSequences; + +public: + bool animGeometry,animTextures,animBones; + bool animated; + + bool isAnimated(MPQFile &f); + ModelVertex *origVertices; + Vec3D *vertices, *normals; + uint16 *indices; + size_t nIndices; + + bool open(); + bool ConvertToVMAPModel(char * outfilename); + +public: + + bool ok; + bool ind; + + float rad; + float trans; + bool animcalc; + int anim, animtime; + + Model(std::string &filename); + ~Model(); + +private: + std::string filename; + char outfilename; +}; + +class ModelInstance +{ +public: + Model *model; + + int id; + + Vec3D pos, rot; + unsigned int d1, scale; + + float frot,w,sc; + + int light; + Vec3D ldir; + Vec3D lcol; + + ModelInstance() {} + ModelInstance(MPQFile &f,const char* ModelInstName,const char*MapName, FILE *pDirfile); + +}; + +#endif diff --git a/contrib/vmap_extractor_v2/vmapextract/modelheaders.h b/contrib/vmap_extractor_v2/vmapextract/modelheaders.h new file mode 100644 index 000000000..7d5e800e7 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/modelheaders.h @@ -0,0 +1,304 @@ +#ifndef MODELHEADERS_H +#define MODELHEADERS_H + +typedef unsigned char uint8; +typedef char int8; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned int uint32; +typedef int int32; + +#pragma pack(push,1) + +struct ModelHeader { + char id[4]; + uint8 version[4]; + uint32 nameLength; + uint32 nameOfs; + uint32 type; + + uint32 nGlobalSequences; + uint32 ofsGlobalSequences; + uint32 nAnimations; + uint32 ofsAnimations; + uint32 nC; + uint32 ofsC; + uint32 nD; + uint32 ofsD; + uint32 nBones; + uint32 ofsBones; + uint32 nF; + uint32 ofsF; + + uint32 nVertices; + uint32 ofsVertices; + uint32 nViews; + uint32 ofsViews; + + uint32 nColors; + uint32 ofsColors; + + uint32 nTextures; + uint32 ofsTextures; + + uint32 nTransparency; // H + uint32 ofsTransparency; + uint32 nI; // always unused ? + uint32 ofsI; + uint32 nTexAnims; // J + uint32 ofsTexAnims; + uint32 nK; + uint32 ofsK; + + uint32 nTexFlags; + uint32 ofsTexFlags; + uint32 nY; + uint32 ofsY; + + uint32 nTexLookup; + uint32 ofsTexLookup; + + uint32 nTexUnitLookup; // L + uint32 ofsTexUnitLookup; + uint32 nTransparencyLookup; // M + uint32 ofsTransparencyLookup; + uint32 nTexAnimLookup; + uint32 ofsTexAnimLookup; + + float floats[14]; + + uint32 nBoundingTriangles; + uint32 ofsBoundingTriangles; + uint32 nBoundingVertices; + uint32 ofsBoundingVertices; + uint32 nBoundingNormals; + uint32 ofsBoundingNormals; + + uint32 nO; + uint32 ofsO; + uint32 nP; + uint32 ofsP; + uint32 nQ; + uint32 ofsQ; + uint32 nLights; // R + uint32 ofsLights; + uint32 nCameras; // S + uint32 ofsCameras; + uint32 nT; + uint32 ofsT; + uint32 nRibbonEmitters; // U + uint32 ofsRibbonEmitters; + uint32 nParticleEmitters; // V + uint32 ofsParticleEmitters; + +}; + +// block B - animations +struct ModelAnimation { + uint32 animID; + uint32 timeStart; + uint32 timeEnd; + + float moveSpeed; + + uint32 loopType; + uint32 flags; + uint32 d1; + uint32 d2; + uint32 playSpeed; // note: this can't be play speed because it's 0 for some models + + Vec3D boxA, boxB; + float rad; + + int16 s[2]; +}; + + +// sub-block in block E - animation data +struct AnimationBlock { + int16 type; // interpolation type (0=none, 1=linear, 2=hermite) + int16 seq; // global sequence id or -1 + uint32 nRanges; + uint32 ofsRanges; + uint32 nTimes; + uint32 ofsTimes; + uint32 nKeys; + uint32 ofsKeys; +}; + +// block E - bones +struct ModelBoneDef { + int32 animid; + int32 flags; + int16 parent; // parent bone index + int16 geoid; + // new int added to the bone definitions. Added in WoW 2.0 + int32 unknown; + AnimationBlock translation; + AnimationBlock rotation; + AnimationBlock scaling; + Vec3D pivot; +}; + +struct ModelTexAnimDef { + AnimationBlock trans, rot, scale; +}; + +struct ModelVertex { + Vec3D pos; + uint8 weights[4]; + uint8 bones[4]; + Vec3D normal; + Vec2D texcoords; + int unk1, unk2; // always 0,0 so this is probably unused +}; + +struct ModelView { + uint32 nIndex, ofsIndex; // Vertices in this model (index into vertices[]) + uint32 nTris, ofsTris; // indices + uint32 nProps, ofsProps; // additional vtx properties + uint32 nSub, ofsSub; // materials/renderops/submeshes + uint32 nTex, ofsTex; // material properties/textures + int32 lod; // LOD bias? +}; + + +/// One material + render operation +struct ModelGeoset { + uint16 d1; // mesh part id? + uint16 d2; // ? + uint16 vstart; // first vertex + uint16 vcount; // num vertices + uint16 istart; // first index + uint16 icount; // num indices + uint16 d3; // number of bone indices + uint16 d4; // offset into bone index list + uint16 d5; // ? + uint16 d6; // root bone? + Vec3D v; + float unknown[4]; // Added in WoW 2.0? +}; + +/// A texture unit (sub of material) +struct ModelTexUnit{ + // probably the texture units + // size always >=number of materials it seems + uint16 flags; // Flags + uint16 order; // ? + uint16 op; // Material this texture is part of (index into mat) + uint16 op2; // Always same as above? + int16 colorIndex; // color or -1 + uint16 flagsIndex; // more flags... + uint16 texunit; // Texture unit (0 or 1) + uint16 d4; // ? (seems to be always 1) + uint16 textureid; // Texture id (index into global texture list) + uint16 texunit2; // copy of texture unit value? + uint16 transid; // transparency id (index into transparency list) + uint16 texanimid; // texture animation id +}; + +// block X - render flags +struct ModelRenderFlags { + uint16 flags; + uint16 blend; +}; + +// block G - color defs +struct ModelColorDef { + AnimationBlock color; + AnimationBlock opacity; +}; + +// block H - transp defs +struct ModelTransDef { + AnimationBlock trans; +}; + +struct ModelTextureDef { + uint32 type; + uint32 flags; + uint32 nameLen; + uint32 nameOfs; +}; + +struct ModelLightDef { + int16 type; + int16 bone; + Vec3D pos; + AnimationBlock ambColor; + AnimationBlock ambIntensity; + AnimationBlock color; + AnimationBlock intensity; + AnimationBlock attStart; + AnimationBlock attEnd; + AnimationBlock unk1; +}; + +struct ModelCameraDef { + int32 id; + float fov, farclip, nearclip; + AnimationBlock transPos; + Vec3D pos; + AnimationBlock transTarget; + Vec3D target; + AnimationBlock rot; +}; + + +struct ModelParticleParams { + float mid; + uint32 colors[3]; + float sizes[3]; + int16 d[10]; + float unk[3]; + float scales[3]; + float slowdown; + float rotation; + float f2[16]; +}; + +struct ModelParticleEmitterDef { + int32 id; + int32 flags; + Vec3D pos; + int16 bone; + int16 texture; + int32 nZero1; + int32 ofsZero1; + int32 nZero2; + int32 ofsZero2; + int16 blend; + int16 type; + int16 s1; + int16 s2; + int16 cols; + int16 rows; + AnimationBlock params[10]; + ModelParticleParams p; + AnimationBlock unk; +}; + + +struct ModelRibbonEmitterDef { + int32 id; + int32 bone; + Vec3D pos; + int32 nTextures; + int32 ofsTextures; + int32 nUnknown; + int32 ofsUnknown; + AnimationBlock color; + AnimationBlock opacity; + AnimationBlock above; + AnimationBlock below; + float res, length, unk; + int16 s1, s2; + AnimationBlock unk1; + AnimationBlock unk2; +}; + + +#pragma pack(pop) + + +#endif \ No newline at end of file diff --git a/contrib/vmap_extractor_v2/vmapextract/mpq.cpp b/contrib/vmap_extractor_v2/vmapextract/mpq.cpp new file mode 100644 index 000000000..ae847d8be --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/mpq.cpp @@ -0,0 +1,136 @@ +#include "mpq.h" +//#include +#include "Stormlib.h" +#define __STORMLIB_SELF__ + +typedef std::vector ArchiveSet; +ArchiveSet gOpenArchives; +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +MPQArchive::MPQArchive(const char* filename) +{ + BOOL succ = SFileOpenArchive(filename, 0, 0,&hMPQ); + if (succ) + { + MPQArchive*ar = (MPQArchive*)(hMPQ); + printf("Opening %s\n", filename); + gOpenArchives.push_back(ar); + succ = true; + + } + else + { + printf("Error!!!Not open archive %s\n", filename); + } +} + +void MPQArchive::close() +{ + SFileCloseArchive(hMPQ); +} + +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +MPQFile::MPQFile(const char* filename): + eof(false), + buffer(0), + pointer(0), + size(0) +{ + for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) + { + + HANDLE hFile = ""; + MPQArchive*(hMPQ) = *i; + BOOL succ = SFileOpenFileEx(hMPQ,filename,0, &hFile); + if (succ) + { + DWORD s = SFileGetFileSize(hFile, 0); + if (!s) + { + eof = true; + buffer = 0; + return; + } + size = (size_t)s; + buffer = new char[s]; + SFileReadFile(hFile, buffer, s, 0, 0); + SFileCloseFile(hFile); + + eof = false; + return; + } + } + + eof = true; + buffer = 0; + +} + +MPQFile::~MPQFile() +{ + close(); +} + +size_t MPQFile::read(void* dest, size_t bytes) +{ + if (eof) + return 0; + + size_t rpos = pointer + bytes; + if (rpos > size) + { + bytes = size - pointer; + eof = true; + } + + memcpy(dest, &(buffer[pointer]), bytes); + + pointer = rpos; + + return bytes; +} + +bool MPQFile::isEof() +{ + return eof; +} + +void MPQFile::seek(int offset) +{ + pointer = offset; + eof = (pointer >= size); +} + +void MPQFile::seekRelative(int offset) +{ + pointer += offset; + eof = (pointer >= size); +} + +void MPQFile::close() +{ + if (buffer) + delete[] buffer; + buffer = 0; + eof = true; +} + +size_t MPQFile::getSize() +{ + return size; +} + +size_t MPQFile::getPos() +{ + return pointer; +} + +char* MPQFile::getBuffer() +{ + return buffer; +} + +char* MPQFile::getPointer() +{ + return buffer + pointer; +} + diff --git a/contrib/vmap_extractor_v2/vmapextract/mpq.h b/contrib/vmap_extractor_v2/vmapextract/mpq.h new file mode 100644 index 000000000..79f30afc7 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/mpq.h @@ -0,0 +1,69 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#ifndef MPQ_H +#define MPQ_H + +#define __STORMLIB_SELF__ + +#include +#include +#include +#include +#include "Stormlib.h" + +using namespace std; + +typedef unsigned int uint32; + + +class MPQArchive +{ + +public: + HANDLE hMPQ; + MPQArchive(const char* filename); + void close(); +}; + +class MPQFile +{ + HANDLE hFile; + HANDLE hMPQ; + bool eof; + char *buffer; + size_t pointer, + size; + + // disable copying + //MPQFile(const MPQFile &f) {} + //void operator=(const MPQFile &f) {} + +public: + MPQFile(const char* filename); + ~MPQFile(); + size_t read(void* dest, size_t bytes); + size_t getSize(); + size_t getPos(); + char* getBuffer(); + char* getPointer(); + bool isEof(); + void seek(int offset); + void seekRelative(int offset); + void close(); +}; + +inline void flipcc(char *fcc) +{ + char t; + t=fcc[0]; + fcc[0]=fcc[3]; + fcc[3]=t; + t=fcc[1]; + fcc[1]=fcc[2]; + fcc[2]=t; +} + + + +#endif + diff --git a/contrib/vmap_extractor_v2/vmapextract/vec3d.h b/contrib/vmap_extractor_v2/vmapextract/vec3d.h new file mode 100644 index 000000000..88b8e1c4f --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/vec3d.h @@ -0,0 +1,230 @@ +#ifndef VEC3D_H +#define VEC3D_H + +#include +#include + + + +class Vec3D { +public: + float x,y,z; + + Vec3D(float x0 = 0.0f, float y0 = 0.0f, float z0 = 0.0f) : x(x0), y(y0), z(z0) {} + + Vec3D(const Vec3D& v) : x(v.x), y(v.y), z(v.z) {} + + Vec3D& operator= (const Vec3D &v) { + x = v.x; + y = v.y; + z = v.z; + return *this; + } + + Vec3D operator+ (const Vec3D &v) const + { + Vec3D r(x+v.x,y+v.y,z+v.z); + return r; + } + + Vec3D operator- (const Vec3D &v) const + { + Vec3D r(x-v.x,y-v.y,z-v.z); + return r; + } + + float operator* (const Vec3D &v) const + { + return x*v.x + y*v.y + z*v.z; + } + + Vec3D operator* (float d) const + { + Vec3D r(x*d,y*d,z*d); + return r; + } + + friend Vec3D operator* (float d, const Vec3D& v) + { + return v * d; + } + + Vec3D operator% (const Vec3D &v) const + { + Vec3D r(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); + return r; + } + + Vec3D& operator+= (const Vec3D &v) + { + x += v.x; + y += v.y; + z += v.z; + return *this; + } + + Vec3D& operator-= (const Vec3D &v) + { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } + + Vec3D& operator*= (float d) + { + x *= d; + y *= d; + z *= d; + return *this; + } + + float lengthSquared() const + { + return x*x+y*y+z*z; + } + + float length() const + { + return sqrt(x*x+y*y+z*z); + } + + Vec3D& normalize() + { + this->operator*= (1.0f/length()); + return *this; + } + + Vec3D operator~ () const + { + Vec3D r(*this); + r.normalize(); + return r; + } + + friend std::istream& operator>>(std::istream& in, Vec3D& v) + { + in >> v.x >> v.y >> v.z; + return in; + } + + operator float*() + { + return (float*)this; + } + +}; + + +class Vec2D { +public: + float x,y; + + Vec2D(float x0 = 0.0f, float y0 = 0.0f) : x(x0), y(y0) {} + + Vec2D(const Vec2D& v) : x(v.x), y(v.y) {} + + Vec2D& operator= (const Vec2D &v) { + x = v.x; + y = v.y; + return *this; + } + + Vec2D operator+ (const Vec2D &v) const + { + Vec2D r(x+v.x,y+v.y); + return r; + } + + Vec2D operator- (const Vec2D &v) const + { + Vec2D r(x-v.x,y-v.y); + return r; + } + + float operator* (const Vec2D &v) const + { + return x*v.x + y*v.y; + } + + Vec2D operator* (float d) const + { + Vec2D r(x*d,y*d); + return r; + } + + friend Vec2D operator* (float d, const Vec2D& v) + { + return v * d; + } + + Vec2D& operator+= (const Vec2D &v) + { + x += v.x; + y += v.y; + return *this; + } + + Vec2D& operator-= (const Vec2D &v) + { + x -= v.x; + y -= v.y; + return *this; + } + + Vec2D& operator*= (float d) + { + x *= d; + y *= d; + return *this; + } + + float lengthSquared() const + { + return x*x+y*y; + } + + float length() const + { + return sqrt(x*x+y*y); + } + + Vec2D& normalize() + { + this->operator*= (1.0f/length()); + return *this; + } + + Vec2D operator~ () const + { + Vec2D r(*this); + r.normalize(); + return r; + } + + + friend std::istream& operator>>(std::istream& in, Vec2D& v) + { + in >> v.x >> v.y; + return in; + } + + operator float*() + { + return (float*)this; + } + +}; + + +inline void rotate(float x0, float y0, float *x, float *y, float angle) +{ + float xa = *x - x0, ya = *y - y0; + *x = xa*cosf(angle) - ya*sinf(angle) + x0; + *y = xa*sinf(angle) + ya*cosf(angle) + y0; +} + + + +#endif + diff --git a/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp b/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp new file mode 100644 index 000000000..dfc7cddcf --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp @@ -0,0 +1,566 @@ +/*****************************************************************************/ +/* StormLibTest.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This module uses very brutal test methods for StormLib. It extracts all */ +/* files from the archive with Storm.dll and with stormlib and compares them,*/ +/* then tries to build a copy of the entire archive, then removes a few files*/ +/* from the archive and adds them back, then compares the two archives, ... */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 25.03.03 1.00 Lad The first version of StormLibTest.cpp */ +/*****************************************************************************/ + +#define _CRT_SECURE_NO_DEPRECATE +#include +#include +#include +#include +#include +#include +#include + + +#define __STORMLIB_SELF__ // Don't use StormLib.lib +#include "StormLib.h" + +#pragma warning(disable : 4505) +#pragma comment(lib, "Winmm.lib") + +//From Extractor +#include "adtfile.h" +#include "wdtfile.h" +#include "dbcfile.h" +#include "mpq.h" +#include "wmo.h" + +//------------------------------------------------------------------------------ +// Defines + +#define MPQ_BLOCK_SIZE 0x1000 + +//----------------------------------------------------------------------------- +// from extractor +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef struct{ + char name[64]; + unsigned int id; +}map_id; + +map_id * map_ids; +uint16 * areas; +uint16 *areamax; +uint32 map_count; +char output_path[128]="."; +char input_path[1024]="."; +bool hasInputPathParam = false; +char tmp[512]; +bool preciseVectorData = false; +//char gamepath[1024]; + +//Convert function +//bool ConvertADT(char*,char*); + +// Constants + +//static const char * szWorkDirMaps = ".\\Maps"; +static const char * szWorkDirWmo = ".\\buildings"; + +//static LPBYTE pbBuffer1 = NULL; +//static LPBYTE pbBuffer2 = NULL; + +// Local testing functions + +static void clreol() +{ + printf("\r \r"); +} + +static const char * GetPlainName(const char * szFileName) +{ + const char * szTemp; + + if((szTemp = strrchr(szFileName, '\\')) != NULL) + szFileName = szTemp + 1; + return szFileName; +} +//------------------------------------------------------------------------------ +static void ShowProcessedFile(const char * szFileName) +{ + char szLine[80]; + size_t nLength = strlen(szFileName); + + memset(szLine, 0x20, sizeof(szLine)); + szLine[sizeof(szLine)-1] = 0; + + if(nLength > sizeof(szLine)-1) + nLength = sizeof(szLine)-1; + memcpy(szLine, szFileName, nLength); + printf("\r%s\n", szLine); +} + + +//---------------------------------------------------------------------------------------------------------------------------------------------------------------------- +int ExtractWmo(const std::vector& pArchiveNames) +{ + + char* szListFile = ""; + char szLocalFile[MAX_PATH] = ""; + HANDLE hMpq = ""; + BOOL bResult = FALSE; + + //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"}; + + int nError = ERROR_SUCCESS; + if(szListFile == NULL || *szListFile == 0) + szListFile = NULL; + //char tmp[1024]; + //for (size_t i=0; i<4; i++) + for (size_t i=0; iopen()) + { + printf("Not open RootWmo!!!\n"); + bResult = SFileFindNextFile(hFind, &wf); + continue; + } + FILE *output=fopen(szLocalFile,"wb"); + froot->ConvertToVMAPRootWmo(output); + int Wmo_nVertices = 0; + if(froot->nGroups !=0) + { + for (int i=0; inGroups; i++) + { + char temp[512]; + strcpy(temp, wf.cFileName); + temp[strlen(wf.cFileName)-4] = 0; + char groupFileName[512]; + sprintf(groupFileName,"%s_%03d.wmo",temp, i); + printf("%s\n",groupFileName); + //printf("GroupWmo!\n"); + string s = groupFileName; + WMOGroup * fgroup = new WMOGroup(s); + if(!fgroup->open()) + { + printf("Not all open Group file for: %s\n",GetPlainName(wf.cFileName)); + bResult = SFileFindNextFile(hFind, &wf); + break; + } + Wmo_nVertices += fgroup->ConvertToVMAPGroupWmo(output, preciseVectorData); + } + } + fseek(output, 8, SEEK_SET); // store the correct no of vertices + fwrite(&Wmo_nVertices,sizeof(int),1,output); + fclose(output); + } + } else { + fclose(n); + } + wf.dwFileFlags &= ~MPQ_FILE_HAS_EXTRA; + wf.dwFileFlags &= ~MPQ_FILE_EXISTS; + // Find the next file + bResult = SFileFindNextFile(hFind, &wf); + } + // Delete the extracted file in the case of an error + if(nError != ERROR_SUCCESS) + DeleteFile(szLocalFile); + // Close the search handle + if(hFind != NULL) + SFileFindClose(hFind); + + } + } + // Close both archives + if(hMpq != NULL) + //SFileCloseArchive(hMpq); + if(nError == ERROR_SUCCESS) + printf("\nExtract wmo complete (No errors)\n"); + + return nError; + +} + +void ExtractMapsFromMpq() +{ + +} +//----------------------------------------------------------------------------- +void ParsMapFiles() +{ + char fn[512]; + char id_filename[64]; + char id[10]; + for (unsigned int i=0; iinit(id_filename); + delete ADT; + } + + } + } + } + } +} +#if 0 +void ParsMapFiles() +{ + + char fn[512]; + for (unsigned int i=0; iinit(); + delete ADT; + } + + } + } + } + } +} +#endif +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +void getGamePath() +{ +#ifdef _WIN32 + HKEY key; + DWORD t,s; + LONG l; + s = sizeof(input_path); + memset(input_path,0,s); + l = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Blizzard Entertainment\\World of Warcraft",0,KEY_QUERY_VALUE,&key); + //l = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Blizzard Entertainment\\Burning Crusade Closed Beta",0,KEY_QUERY_VALUE,&key); + l = RegQueryValueEx(key,"InstallPath",0,&t,(LPBYTE)input_path,&s); + RegCloseKey(key); + if (strlen(input_path) > 0) + { + if (input_path[strlen(input_path) - 1] != '\\') strcat(input_path, "\\"); + } + strcat(input_path,"Data\\"); +#else + strcpy(input_path,"data/"); +#endif +} + +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +bool scan_patches(char* scanmatch, std::vector& pArchiveNames) +{ + int i; + char path[512]; + std::list matches; + + WIN32_FIND_DATA ffData; + HANDLE hFind; + + for (i = 1; i <= 99; i++) + { + if (i != 1) + { + sprintf(path, "%s-%d.mpq", scanmatch, i); + } + else + { + sprintf(path, "%s.mpq", scanmatch); + } + + hFind = INVALID_HANDLE_VALUE; + hFind = FindFirstFile(path, &ffData); + if (hFind == INVALID_HANDLE_VALUE) break; + FindClose(hFind); + + matches.push_back(path); + } + + matches.reverse(); + for (std::list::iterator i = matches.begin(); i != matches.end(); i++) + { + pArchiveNames.push_back(i->c_str()); + } + + printf("\n"); + + return(true); +} + +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +bool fillArchiveNameVector(std::vector& pArchiveNames) { + //srand((unsigned int)time(0)); + + if(!hasInputPathParam) + getGamePath(); + + printf("\nGame path: %s\n", input_path); + + char path[512]; + std::vector locales; + + // scan game directories + WIN32_FIND_DATA ffData; + HANDLE hFind; + DWORD dwError; + + // first, scan for locales (4-letter directories) + printf("Scanning for locales.\n"); + sprintf(path, "%s*.*", input_path); + hFind = INVALID_HANDLE_VALUE; + hFind = FindFirstFile(path, &ffData); + if (hFind == INVALID_HANDLE_VALUE) + { + printf("\nCould not open data directory for reading. Aborting.\n"); + return(false); + } + do + { + if (ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (ffData.cFileName[0] != '.') + { + if (strlen(ffData.cFileName) == 4) + { + printf("Found locale: %s\n", ffData.cFileName); + locales.push_back(ffData.cFileName); + } + } + } + } while (FindNextFile(hFind, &ffData) != 0); + dwError = GetLastError(); + FindClose(hFind); + if (dwError != ERROR_NO_MORE_FILES) + { + printf("\nError reading data directory while scanning locales. Aborting.\n"); + return(false); + } + printf("\n"); + + if (locales.size() == 0) + { + printf("Sorry, no locales found. Aborting.\n"); + return(false); + } + + // now, scan for the patch levels in the core dir + printf("Loading patch levels from data directory.\n"); + sprintf(path, "%spatch", input_path); + if (!scan_patches(path, pArchiveNames)) return(false); + + // now, scan for the patch levels in locale dirs + printf("Loading patch levels from locale directories.\n"); + for (std::vector::iterator i = locales.begin(); i != locales.end(); i++) + { + printf("Locale: %s\n", i->c_str()); + sprintf(path, "%s%s\\patch-%s", input_path, i->c_str(), i->c_str()); + if (!scan_patches(path, pArchiveNames)) return(false); + } + + // open expansion and common files + printf("Opening data files from data directory.\n"); + sprintf(path, "%sexpansion.mpq", input_path); + pArchiveNames.push_back(path); + sprintf(path, "%scommon.mpq", input_path); + pArchiveNames.push_back(path); + printf("\n"); + + // open locale expansion and common files + printf("Opening data files from locale directories.\n"); + for (std::vector::iterator i = locales.begin(); i != locales.end(); i++) + { + printf("Locale: %s\n", i->c_str()); + sprintf(path, "%s%s\\expansion-locale-%s.mpq", input_path, i->c_str(), i->c_str()); + pArchiveNames.push_back(path); + sprintf(path, "%s%s\\locale-%s.mpq", input_path, i->c_str(), i->c_str()); + pArchiveNames.push_back(path); + printf("\n"); + } + return true; +} +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// return false it normal processing can not proceed + +bool processArgv(int argc, char ** argv, char*versionString) +{ + bool result = true; + hasInputPathParam = false; + bool preciseVectorData = false; + + for(int i=1; i< argc; ++i) { + if(strcmp("-s",argv[i]) == 0) { + preciseVectorData = false; + } else if(strcmp("-d",argv[i]) == 0) { + if((i+1)]\n", argv[0]); + printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n"); + printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n"); + printf(" -d : Path to the vector data source folder.\n"); + printf(" -? : This message.\n"); + } + return result; +} + +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// Main +// +// The program must be run with two command line arguments +// +// Arg1 - The source MPQ name (for testing reading and file find) +// Arg2 - Listfile name +// + +int main(int argc, char ** argv) +{ + //char tmp[512]; +// FILE* pDatei; +// char tmp[512]; +// char tmp1[512]; + //char tmp2[512]; +// char tmp3[512]; +// char tmp4[512]; +// char szMpqName[MAX_PATH] = ""; +// char szListFile[MAX_PATH] = ""; + int nError = ERROR_SUCCESS; + char *versionString = "V2.4 2007_07_12"; + + // Use command line arguments, when some + if(!processArgv(argc, argv, versionString)) + return 1; + + printf("Extract %s. Beginning work ....\n",versionString); + // Set the lowest priority to allow running in the background + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + // Create the working directory + if(nError == ERROR_SUCCESS) + { + //if(!CreateDirectory(szWorkDirMaps, NULL)) + // nError = GetLastError(); + if(!CreateDirectory(szWorkDirWmo, NULL)) + nError = GetLastError(); + if(nError == ERROR_ALREADY_EXISTS) + nError = ERROR_SUCCESS; + } + //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + // patch goes first -> fake priority handling + std::vector archives; + + //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + std::vector archiveNames; + + fillArchiveNameVector(archiveNames); + for (size_t i=0; iopen(); + map_count=dbc->getRecordCount (); + map_ids=new map_id[map_count]; + for(unsigned int x=0;xgetRecord (x).getUInt(0); + strcpy(map_ids[x].name,dbc->getRecord(x).getString(1)); + printf("Map - %s\n",map_ids[x].name); + } + + delete dbc; + ParsMapFiles(); + delete [] map_ids; + nError = ERROR_SUCCESS; + } + + clreol(); + if(nError != ERROR_SUCCESS) { + printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData); + _getch(); + } + printf("Extract %s. Work complete. No errors.",versionString); +} diff --git a/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp b/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp new file mode 100644 index 000000000..831cdaae7 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp @@ -0,0 +1,120 @@ +#define __STORMLIB_SELF__ + +#include "wdtfile.h" +#include "adtfile.h" + + +char * wdtGetPlainName(char * FileName) +{ + char * szTemp; + + if((szTemp = strrchr(FileName, '\\')) != NULL) + FileName = szTemp + 1; + return FileName; +} + +WDTFile::WDTFile(char* file_name, char* file_name1):WDT(file_name) +{ + filename.append(file_name1,strlen(file_name1)); +} + +bool WDTFile::init(char *map_id) +{ + + if (WDT.isEof()) + { + //printf("Can't find WDT file.\n"); + return false; + } + + char fourcc[5]; + size_t size; + + + const char dirname[] = "buildings\\dir"; + FILE *dirfile; + dirfile = fopen(dirname, "ab"); + if(!dirfile) + { + printf("Can't open dirfile!'%s'\n"); + return false; + } + + + while (!WDT.isEof()) + { + WDT.read(fourcc,4); + WDT.read(&size, 4); + + flipcc(fourcc); + fourcc[4] = 0; + + size_t nextpos = WDT.getPos() + size; + + if (!strcmp(fourcc,"MAIN")) + { + } + if (!strcmp(fourcc,"MWMO")) + { + // global map objects + if (size) + { + char *buf = new char[size]; + WDT.read(buf, size); + char *p=buf; + int q = 0; + gWmoInstansName = new string[size]; + while (p=0 && z >= 0 && x<64 && z<64)) return NULL; + + char name[512]; + + sprintf(name,"World\\Maps\\%s\\%s_%d_%d.adt", filename.c_str(), filename.c_str(), x, z); + return new ADTFile(name); +} diff --git a/contrib/vmap_extractor_v2/vmapextract/wdtfile.h b/contrib/vmap_extractor_v2/vmapextract/wdtfile.h new file mode 100644 index 000000000..7a7002a2e --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/wdtfile.h @@ -0,0 +1,30 @@ +#ifndef WDTFILE_H +#define WDTFILE_H + +#define __STORMLIB_SELF__ + +#include "mpq.h" +#include "adtfile.h" +#include "wmo.h" +#include +#include "stdlib.h" + +class WDTFile +{ +public: + WDTFile(char* file_name, char* file_name1); + ~WDTFile(void); + bool init(char *map_id); + + string* gWmoInstansName; + int gnWMO, nMaps; + + ADTFile* GetMap(int x, int z); + +private: + MPQFile WDT; + bool maps[64][64]; + string filename; +}; + +#endif diff --git a/contrib/vmap_extractor_v2/vmapextract/wmo.cpp b/contrib/vmap_extractor_v2/vmapextract/wmo.cpp new file mode 100644 index 000000000..9dfda6f77 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/wmo.cpp @@ -0,0 +1,531 @@ +#define __STORMLIB_SELF__ + +#include "wmo.h" +#include "Stormlib.h" +#include "mpq.h" + +using namespace std; + + +WMORoot::WMORoot(std::string &filename) : filename(filename) +{ +} +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +bool WMORoot::open() +{ + + MPQFile f(filename.c_str()); + if(f.isEof ()) + { + printf("No such file.\n"); + return false; + } + + size_t size; + char fourcc[5]; + bbcorn1[3] = 0; + bbcorn2[3]= 0; + + while (!f.isEof ()) + { + f.read(fourcc,4); + f.read(&size, 4); + + flipcc(fourcc); + fourcc[4] = 0; + + size_t nextpos = f.getPos() + size; + + if (!strcmp(fourcc,"MOHD"))//header + { + + f.read(&nTextures, 4); + f.read(&nGroups, 4); + f.read(&nP, 4); + f.read(&nLights, 4); + f.read(&nModels, 4); + f.read(&nDoodads, 4); + f.read(&nDoodadSets, 4); + f.read(&col, 4); + f.read(&RootID, 4); + f.read(bbcorn1,12); + f.read(bbcorn2,12); + break; + } + /* + else if (!strcmp(fourcc,"MOTX")) + { + + } + else if (!strcmp(fourcc,"MOMT")) + { + + } + else if (!strcmp(fourcc,"MOGN")) + { + + } + else if (!strcmp(fourcc,"MOGI")) + { + + } + else if (!strcmp(fourcc,"MOLT")) + { + + } + else if (!strcmp(fourcc,"MODN")) + { + + } + else if (!strcmp(fourcc,"MODS")) + { + + } + else if (!strcmp(fourcc,"MODD")) + { + + } + else if (!strcmp(fourcc,"MOSB")) + { + + } + else if (!strcmp(fourcc,"MOPV")) + { + + } + else if (!strcmp(fourcc,"MOPT")) + { + + } + else if (!strcmp(fourcc,"MOPR")) + { + + } + else if (!strcmp(fourcc,"MFOG")) + { + + } + */ + f.seek((int)nextpos); + } + f.close (); + return true; +} +//--------------------------------------------------------------------------- + +bool WMORoot::ConvertToVMAPRootWmo(FILE *pOutfile) +{ + //printf("Convert RootWmo...\n"); + + fwrite("VMAP002",1,8,pOutfile); + unsigned int nVectors = 0; + fwrite(&nVectors,sizeof(nVectors),1,pOutfile); // will be filled later + fwrite(&nGroups,4,1,pOutfile); + return true; +} + +//---------------------------------------------------------------------------- +WMORoot::~WMORoot() +{ +} +//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +WMOGroup::WMOGroup(std::string &filename) : filename(filename) +{ +} +//--------------------------------------------------------------------------- +bool WMOGroup::open() +{ + MPQFile f(filename.c_str()); + if(f.isEof ()) + { + printf("No such file.\n"); + return false; + } + size_t size; + char fourcc[5]; + bbcorn1[3] = 0; + bbcorn2[3] = 0; + while (!f.isEof ()) + { + f.read(fourcc,4); + f.read(&size, 4); + flipcc(fourcc); + if (!strcmp(fourcc,"MOGP"))//Fix sizeoff = Data size. + { + size = 68; + } + fourcc[4] = 0; + size_t nextpos = f.getPos() + size; + LiquEx_size = 0; + liquflags = 0; + + if (!strcmp(fourcc,"MOGP"))//header + { + f.seekRelative(-4); + f.read(&offsize, 4); + f.read(&flag, 4); + f.read(&flag1, 4); + f.read(&Xid, 4); + f.read(bbcorn1, 12); + f.read(bbcorn2, 12); + f.read(&Xid2, 4); + f.read(&Xid3, 4); + f.read(&zero1, 4); + f.read(&Xflag, 4); + f.read(&nTexture,4); + f.read(&GroupID,4); + } + else if (!strcmp(fourcc,"MOPY")) + { + MOPY = new char[size]; + mopy_size = size; + nTriangles = (int)size / 2; + f.read(MOPY, size); + } + else if (!strcmp(fourcc,"MOVI")) + { + MOVI = new uint16[size/2]; + f.read(MOVI, size); + + } + else if (!strcmp(fourcc,"MOVT")) + { + MOVT = new float[size/4]; + f.read(MOVT, size); + nVertices = (int)size / 12; + } + else if (!strcmp(fourcc,"MONR")) + { + } + else if (!strcmp(fourcc,"MOTV")) + { + } + else if (!strcmp(fourcc,"MOBA")) + { + MOBA = new uint16[size/2]; + moba_size = size/2; + f.read(MOBA, size); + } + else if (!strcmp(fourcc,"MLIQ")) + { + liquflags |= 1; + WMOLiquidHeader hlq; + f.read(&hlq, 0x1E); + float ydir = -1.0f; + hlq_xverts = hlq.xverts; + hlq_yverts = hlq.yverts; + int noVer = hlq.xverts * hlq.yverts; + float tilesize = CHUNKSIZE / 8.0f; + LiquEx_size = sizeof(float) * 3 * noVer; + LiquEx = new float[sizeof(float) * 3 * noVer]; + int p = 0; + + for (int j=0; j0) { + if(fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes) { printf("Error while writing file indexarray"); exit(0); } + } + + if(fwrite("VERT",4, 1, output) != 1) { printf("Error while writing file nbraches ID"); exit(0); } + wsize = sizeof(int) + sizeof(float) * 3 * nVertices; + if(fwrite(&wsize, sizeof(int), 1, output) != 1) { printf("Error while writing file wsize"); } + if(fwrite(&nVertices, sizeof(int), 1, output) != 1) { printf("Error while writing file nVertices"); exit(0); } + if(nVertices >0) { + if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices) { printf("Error while writing file vectors"); exit(0); } + } + + if(LiquEx_size != 0) + { + int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU" + fwrite(LIQU_h,4,4,output); + fwrite(LiquEx,4,LiquEx_size/4,output); + delete [] LiquEx; + } + + return nTriangles; + } else { + //printf("Convert GroupWmo...\n"); + //-------GRP ------------------------------------- + fwrite(&liquflags,sizeof(uint32),1,output); + char GRP[] = "GRP "; + fwrite(GRP,1,4,output); + int k = 0; + int moba_batch = moba_size/12; + MobaEx = new int[moba_batch*4]; + for(int i=8; i MoviExSort[i+1]) + { + hold = MoviExSort[i]; + MoviExSort[i] = MoviExSort[i+1]; + MoviExSort[i+1] = hold; + } + //double = 65535 + else + if (MoviExSort[i] == MoviExSort[i+1]) + MoviExSort[i+1] = 65535; + } + } + // double delet + uint16 s = 0; + for (int i=0; i < IndexExTr_size*3; i++) + { + if (MoviExSort[i]!=65535) + { + MoviExSort[s] = MoviExSort[i]; + s++; + } + } + MovtExSort = new uint16[s]; + for (int i=0; i < s; i++) + { + MovtExSort[i] = MoviExSort[i]; + } + + for (int i=0; i < IndexExTr_size*3; i++) + { + uint16 b = MoviEx[i]; + for (uint16 x = 0; x < s; x++) + { + if(MoviExSort[x] == b) + { + + MoviEx[i] = x; + break; + } + } + + } + int INDX[] = {0x58444E49,IndexExTr_size*6+4,IndexExTr_size*3}; + fwrite(INDX,4,3,output); + fwrite(MoviEx,2,IndexExTr_size*3,output); + + delete [] MoviEx; + delete [] MoviExSort; + delete [] IndexExTr; + + //----------VERT--------- + //-----MOVT---------- + int d = 0; + MovtEx = new float[s*3]; + for (uint16 i=0; i> 16; + + int realx1 = (int) ((float) pos2.x / 533.333333f); + int realy1 = (int) ((float) pos2.z / 533.333333f); + int realx2 = (int) ((float) pos3.x / 533.333333f); + int realy2 = (int) ((float) pos3.z / 533.333333f); + + if(realx1 < 0) + { + realx1 +=20; realx2+=20; + } + if(realy1 < 0) + { + realy1 +=20; realy2+=20; + } // hack to prevent neg. values + + //-----------add_in _dir_file---------------- + + char tempname[512]; + // const char dirname[] = "buildings\\dir"; + + sprintf(tempname, "buildings\\%s", WmoInstName); + FILE *input; + input = fopen(tempname, "r+b"); + if(!input) + { + return; + } + fseek(input, 8, SEEK_SET); // get the correct no of vertices + int nVertices; + fread(&nVertices, sizeof (int), 1, input); + fclose(input); + if(nVertices == 0) + { + return; + } + + /* FILE *dirfile; + dirfile = fopen(dirname, "ab"); + if(!dirfile) + { + printf("Can't open dirfile!'%s'\n"); + return; + } + */ + float x,z; + x = pos.x; + z = pos.z; + if(x==0 && z == 0) + { x = 533.33333f*32; z = 533.33333f*32; } + fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n", + MapName, + WmoInstName, + (float) x, (float) pos.y, (float) z, + (float) rot.x, (float) rot.y, (float) rot.z, + nVertices, + realx1, realy1, + realx2, realy2 + ); + + // fclose(dirfile); +} + + + + diff --git a/contrib/vmap_extractor_v2/vmapextract/wmo.h b/contrib/vmap_extractor_v2/vmapextract/wmo.h new file mode 100644 index 000000000..b8f6439e3 --- /dev/null +++ b/contrib/vmap_extractor_v2/vmapextract/wmo.h @@ -0,0 +1,107 @@ +#ifndef WMO_H +#define WMO_H +#define __STORMLIB_SELF__ +#define TILESIZE (533.33333f) +#define CHUNKSIZE ((TILESIZE) / 16.0f) + +#include "Stormlib.h" +#include +#include "vec3d.h" +#include +#include "mpq.h" + + +class WMOInstance; +class WMOManager; + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; + + +class WMORoot +{ +public: + int nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootID; + unsigned int col; + int bbcorn1[3]; + int bbcorn2[3]; + + WMORoot(std::string &filename); + ~WMORoot(); + + bool open(); + bool ConvertToVMAPRootWmo(FILE *output); +private: + std::string filename; + char outfilename; + +}; + +class WMOGroup +{ +public: + + int offsize,flag,flag1,Xid,Xid2,Xid3,zero1,Xflag,nTexture,GroupID; + int mopy_size,moba_size,hlq_xverts,hlq_yverts; + int MopyEx_size,IndexExTr_size,LiquEx_size; + unsigned int nVertices; // number when loaded + int nTriangles; // number when loaded + int bbcorn1[3]; + int bbcorn2[3]; + int * IndexExTr; + char* MOPY; + char* MopyEx; + uint16* MOVI; + uint16* MoviEx; + uint16* MoviExSort; + float* MOVT; + float* MovtEx; + uint16* MovtExSort; + float* MONR; + float* MonrEx; + uint16* MOBA; + int* MobaEx; + float* LiquEx; + uint32 liquflags; + + WMOGroup(std::string &filename); + ~WMOGroup(); + + bool open(); + int ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData); + +private: + std::string filename; + char outfilename; + +}; + +struct WMOLiquidHeader +{ + int xverts, yverts, xtiles, ytiles; + float pos_x; + float pos_y; + float pos_z; + short type; +}; + +class WMOInstance +{ + static std::set ids; +public: + string MapName; + int currx; + int curry; + WMOGroup *wmo; + Vec3D pos; + Vec3D pos2, pos3, rot; + int indx,id, d2, d3; + int doodadset; + + WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile); + + static void reset(); +}; + +#endif \ No newline at end of file diff --git a/dep/ACE_wrappers/AUTHORS b/dep/ACE_wrappers/AUTHORS new file mode 100644 index 000000000..3e474e06c --- /dev/null +++ b/dep/ACE_wrappers/AUTHORS @@ -0,0 +1,13 @@ +Douglas C. Schmidt +d.schmidt@vanderbilt.edu + +Professor of Computer Science +Associate Chair of Computer Science and Engineering +Department of Electrical Engineering and Computer Science +Senior Researcher at the Institute for Software Integrated Systems (ISIS) +Vanderbilt University +Nashville, TN 37203 + +www.dre.vanderbilt.edu/~schmidt +TEL: (615) 343-8197 +FAX: (615) 343-7440 diff --git a/dep/ACE_wrappers/COPYING b/dep/ACE_wrappers/COPYING new file mode 100644 index 000000000..1d96c4905 --- /dev/null +++ b/dep/ACE_wrappers/COPYING @@ -0,0 +1,110 @@ + + _________________________________________________________________ + + Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM), and + CoSMIC(TM) + + [1]ACE(TM), [2]TAO(TM), [3]CIAO(TM), and [4]CoSMIC(TM) (henceforth + referred to as "DOC software") are copyrighted by [5]Douglas C. + Schmidt and his [6]research group at [7]Washington University, + [8]University of California, Irvine, and [9]Vanderbilt University, + Copyright (c) 1993-2008, all rights reserved. Since DOC software is + open-source, freely available software, you are free to use, modify, + copy, and distribute--perpetually and irrevocably--the DOC software + source code and object code produced from the source, as well as copy + and distribute modified versions of this software. You must, however, + include this copyright statement along with any code built using DOC + software that you release. No copyright statement needs to be provided + if you just ship binary executables of your software products. + + You can use DOC software in commercial and/or binary software releases + and are under no obligation to redistribute any of your source code + that is built using DOC software. Note, however, that you may not do + anything to the DOC software code, such as copyrighting it yourself or + claiming authorship of the DOC software code, that will prevent DOC + software from being distributed freely using an open-source + development model. You needn't inform anyone that you're using DOC + software in your software, though we encourage you to let [10]us know + so we can promote your project in the [11]DOC software success + stories. + + The [12]ACE, [13]TAO, [14]CIAO, and [15]CoSMIC web sites are + maintained by the [16]DOC Group at the [17]Institute for Software + Integrated Systems (ISIS) and the [18]Center for Distributed Object + Computing of Washington University, St. Louis for the development of + open-source software as part of the open-source software community. + Submissions are provided by the submitter ``as is'' with no warranties + whatsoever, including any warranty of merchantability, noninfringement + of third party intellectual property, or fitness for any particular + purpose. In no event shall the submitter be liable for any direct, + indirect, special, exemplary, punitive, or consequential damages, + including without limitation, lost profits, even if advised of the + possibility of such damages. Likewise, DOC software is provided as is + with no warranties of any kind, including the warranties of design, + merchantability, and fitness for a particular purpose, + noninfringement, or arising from a course of dealing, usage or trade + practice. Washington University, UC Irvine, Vanderbilt University, + their employees, and students shall have no liability with respect to + the infringement of copyrights, trade secrets or any patents by DOC + software or any part thereof. Moreover, in no event will Washington + University, UC Irvine, or Vanderbilt University, their employees, or + students be liable for any lost revenue or profits or other special, + indirect and consequential damages. + + DOC software is provided with no support and without any obligation on + the part of Washington University, UC Irvine, Vanderbilt University, + their employees, or students to assist in its use, correction, + modification, or enhancement. A [19]number of companies around the + world provide commercial support for DOC software, however. + + DOC software is Y2K-compliant, as long as the underlying OS platform + is Y2K-compliant. Likewise, DOC software is compliant with the new US + daylight savings rule passed by Congress as "The Energy Policy Act of + 2005," which established new daylight savings times (DST) rules for + the United States that expand DST as of March 2007. Since DOC software + obtains time/date and calendaring information from operating systems + users will not be affected by the new DST rules as long as they + upgrade their operating systems accordingly. + + The names ACE(TM), TAO(TM), CIAO(TM), CoSMIC(TM), Washington + University, UC Irvine, and Vanderbilt University, may not be used to + endorse or promote products or services derived from this source + without express written permission from Washington University, UC + Irvine, or Vanderbilt University. This license grants no permission to + call products or services derived from this source ACE(TM), TAO(TM), + CIAO(TM), or CoSMIC(TM), nor does it grant permission for the name + Washington University, UC Irvine, or Vanderbilt University to appear + in their names. + + If you have any suggestions, additions, comments, or questions, please + let [20]me know. + + [21]Douglas C. Schmidt + _________________________________________________________________ + + Back to the [22]ACE home page. + +References + + 1. http://www.cs.wustl.edu/~schmidt/ACE.html + 2. http://www.cs.wustl.edu/~schmidt/TAO.html + 3. http://www.dre.vanderbilt.edu/CIAO/ + 4. http://www.dre.vanderbilt.edu/cosmic/ + 5. http://www.dre.vanderbilt.edu/~schmidt/ + 6. http://www.cs.wustl.edu/~schmidt/ACE-members.html + 7. http://www.wustl.edu/ + 8. http://www.uci.edu/ + 9. http://www.vanderbilt.edu/ + 10. mailto:doc_group@cs.wustl.edu + 11. http://www.cs.wustl.edu/~schmidt/ACE-users.html + 12. http://www.cs.wustl.edu/~schmidt/ACE.html + 13. http://www.cs.wustl.edu/~schmidt/TAO.html + 14. http://www.dre.vanderbilt.edu/CIAO/ + 15. http://www.dre.vanderbilt.edu/cosmic/ + 16. http://www.dre.vanderbilt.edu/ + 17. http://www.isis.vanderbilt.edu/ + 18. http://www.cs.wustl.edu/~schmidt/doc-center.html + 19. http://www.cs.wustl.edu/~schmidt/commercial-support.html + 20. mailto:d.schmidt@vanderbilt.edu + 21. http://www.dre.vanderbilt.edu/~schmidt/ + 22. http://www.cs.wustl.edu/ACE.html diff --git a/dep/ACE_wrappers/ChangeLog b/dep/ACE_wrappers/ChangeLog new file mode 100644 index 000000000..6dc3c9d34 --- /dev/null +++ b/dep/ACE_wrappers/ChangeLog @@ -0,0 +1,6119 @@ +Mon Sep 15 06:08:04 CDT 2008 Simon Massey + + * ACE version 5.6.6 released. + +Fri Sep 12 21:13:04 UTC 2008 Adam Mitz + + * bin/MakeProjectCreator/config/MPC.cfg: + + Changed how DDS_ROOT is referenced (for OpenDDS support). + +Fri Sep 12 12:56:15 UTC 2008 Johnny Willemsen + + Reverted change below, brakes VMS support + + Tue Sep 9 18:46:15 UTC 2008 Johnny Willemsen + * bin/mwc.pl: + * bin/mpc.pl: + Use FindBin::RealScript to get the real script name, that also + works when we have a symbolic link with a different name to + one of these scripts. This fixes bugzilla 3407 + +Thu Sep 11 14:55:00 UTC 2008 Simon Massey + + * bin/diff-builds.pl + * bin/diff-builds-and-group-fixed-tests-only.sh + + Make revision number appending to new test failures optional. + +Tue Sep 9 18:46:15 UTC 2008 Johnny Willemsen + + * bin/mwc.pl: + * bin/mpc.pl: + Use FindBin::RealScript to get the real script name, that also + works when we have a symbolic link with a different name to + one of these scripts. This fixes bugzilla 3407 + +Tue Sep 9 14:05:00 UTC 2008 Simon Massey + + * bin/diff-builds-and-group-fixed-tests-only.sh + Change the sort to cater from revision numbers. + +Tue Sep 9 13:39:00 UTC 2008 Simon Massey + + * bin/diff-builds.pl + typo vi / non-vi edit + +Tue Sep 9 13:35:00 UTC 2008 Simon Massey + + * bin/diff-builds.pl + Adjust for revision numbers. + +Tue Sep 9 11:36:15 UTC 2008 Johnny Willemsen + + * ace/OS_NS_time.cpp (strptime_emulation): + Clear the struct tm before filling it. Without we get a random + value back if the user doesn't use a full date. + +Tue Sep 9 11:31:15 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/modules/VXTestProjectCreator.pm: + * bin/MakeProjectCreator/templates/vxtest.mpd: + Also generate a vxtest file for libraries + +Thu Sep 4 14:39:33 UTC 2008 Ciju John + + * bin/diff-builds-and-group-fixed-tests-only.sh: + '-P' isn't a valid option on Ubantu linux (Bug 15051). Replacing + with Perl alternate. + +Wed Sep 3 10:23:15 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Don't run OBV Typed events with micro and compact configurations + +Wed Sep 3 07:31:15 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Added support for ACE_RUN_VX_TGTSRV_WORKINGDIR. Before starting + the executable we will do a chdir to this directory when it + is specified + +Wed Sep 3 07:10:15 UTC 2008 Johnny Willemsen + + * tests/Bound_Ptr_Test.cpp: + Don't use ACE_ASSERT, it is disabled in release mode and this test + had some real functionality placed within an ACE_ASSERT. This fixes + bugzilla 3415 + +Tue Sep 2 14:11:15 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/config/acedefaults.mpb: + Don't use ACE_LIB_TEXT but ACE_TEXT, the former has been deprecated + a long time ago + +Thu Aug 28 21:18:11 UTC 2008 Adam Mitz + + * bin/tao_orb_tests.lst: + * bin/tao_other_tests.lst: + + Removed "Exceptions" and "NO_EXCEPTIONS" as -Config options. + +Thu Aug 28 18:33:15 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Improved prompt matching + +Thu Aug 28 13:04:15 UTC 2008 Johnny Willemsen + + * bin/auto_run_tests.pl: + The error when we can't chdir to a directory was confusing + + * bin/PerlACE/ProcessVX.pm: + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Reduced duplicate code and added support for ACE_RUN_VX_STARTUP_SCRIPT + and ACE_RUN_VX_STARTUP_SCRIPT_ROOT with which we can specify a + startup script that is executed before the real application is started + + * bin/PerlACE/TestTarget_VxWorks.pm: + A VxWorks target has to be rebooted between tests + +Mon Aug 25 11:15:15 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Added missing run_test.pl to the OBV/Typed_Events test + +Thu Aug 21 09:38:15 UTC 2008 Johnny Willemsen + + * docs/Download.html: + Added OpenSuSE build services as new rpm download location. + Removed ACE-install.sh reference, it is not part of the + archive anymore + +Thu Aug 21 06:54:15 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/templates/gnu.mpd: + Also check /usr/lib64 for the libs + + * bin/depgen.pl: + * bin/mpc.pl: + * bin/mwc.pl: + * bin/PerlACE/ConfigList.pm: + * bin/PerlACE/MSProject.pm: + * bin/PerlACE/Process.pm: + * bin/PerlACE/Process_Unix.pm: + * bin/PerlACE/Process_VMS.pm: + * bin/PerlACE/Process_Win32.pm: + * bin/PerlACE/ProcessLVRT.pm: + * bin/PerlACE/ProcessVX.pm: + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + * bin/PerlACE/Run_Test.pm: + * bin/PerlACE/TestTarget.pm: + * bin/PerlACE/TestTarget_LVRT.pm: + * bin/PerlACE/TestTarget_VxWorks.pm: + * bin/Uniqueid.pm: + Added missing shebang lines to fix rpm packaging warnings + +Wed Aug 20 09:38:15 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/modules/BorlandProjectCreator.pm: + * bin/MMakeProjectCreator/modules/BorlandWorkspaceCreator.pm: + Fixed bugzilla 3403. Migrated parts of the bmake type to this + generator, fixes issues when we need to go a directory up + in the workspace. As side effect the resulting Makefile.bor + is smaller in size which reduces the full size of the + distribution. In the near future I want to remove the borland + MPC generator and only use bmake. + +Wed Aug 20 09:08:15 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Fixed a bug with putenv with rtp mode + +Tue Aug 19 19:06:15 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Don't use cmd to send commands through telnet. The disadvantage + of the cmd method is that it only returns when the prompt + appears again. When this doesn't happen we don't get the output + of the last command into our build log or on the telnet client + +Tue Aug 19 14:01:15 UTC 2008 Johnny Willemsen + + * ace/config-win32-borland.h: + * ace/OS_NS_stdlib.inl: + * ace/config-win32-msvc.h: + CodeGear C++ Builder 2009 has wcstoull and strtoull + +Mon Aug 18 11:30:15 UTC 2008 Johnny Willemsen + + * ace/config-win32-borland.h: + CodeGear C++ Builder 2009 doesn't support inline assembly + +Mon Aug 18 10:17:15 UTC 2008 Johnny Willemsen + + * ACE-INSTALL.html: + Improved BCB instructions + +Sun Aug 17 18:04:15 UTC 2008 Johnny Willemsen + + * ACE-INSTALL.html: + * include/makeinclude/compiler.bor: + Added BCBVER 10/11/12 + +Sun Aug 17 07:30:15 UTC 2008 Johnny Willemsen + + * bin/mwc.pl: + * bin/mpc.pl: + Use RealBin to get the location of this script, that gives the + real location also in case we use a symbolic link to these + scripts. Thanks to Adam Mitz for pointing me to RealBin + +Fri Aug 15 11:07:00 UTC 2008 Simon Massey + + * make/makeinclude/platform_aix_ibm.GNU: + Added missing AIX compiler version 0800. + +Wed Aug 13 14:40:15 UTC 2008 Johnny Willemsen + + * ace/Truncate.h: + Added missing specializations for Borland C++. + +Wed Aug 13 14:18:15 UTC 2008 Johnny Willemsen + + * m4/ace_defines.m4: + * m4/ace_functions.m4: + * m4/ace_headers.m4: + Reverted change below, doesn't work on suse 11.1 yet + +Wed Aug 13 13:22:15 UTC 2008 Johnny Willemsen + + * m4/ace_defines.m4: + * m4/ace_functions.m4: + * m4/ace_headers.m4: + Updated these files to work with autoconf 2.62. Thanks to + Philipp Thomas for these patches. These + are needed to use autoconf on OpenSuSE Factory (11.1 beta). + This fixes bugzilla 3396. + +Wed Aug 13 11:55:15 UTC 2008 Johnny Willemsen + + * ace/Truncate.h: + Added missing specializations for Borland C++. + +Wed Aug 13 11:44:15 UTC 2008 Johnny Willemsen + + * rpmbuild/ace-tao-ciao.txt: + Made several improvements to this new spec file. Thanks to + Philipp Thomas for assisting with this + +Tue Aug 12 19:45:16 UTC 2008 Jeff Parsons + + * ace/Time_Value.inl: + * examples/OS/Process/process.cpp: + * examples/Misc/test_dump.h: + * examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp: + * examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp: + * examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp: + * examples/ASX/Message_Queue/buffer_stream.cpp: + * examples/ASX/Message_Queue/bounded_buffer.cpp: + * examples/ASX/Message_Queue/priority_buffer.cpp: + * examples/ASX/UPIPE_Event_Server/Supplier_Router.cpp: + * examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp: + * examples/ASX/UPIPE_Event_Server/event_server.cpp: + * examples/ASX/UPIPE_Event_Server/Consumer_Router.cpp: + * examples/Web_Crawler/Iterators.cpp: + * examples/Web_Crawler/URL_Visitor.cpp: + * examples/Web_Crawler/Mem_Map_Stream.cpp: + * examples/Shared_Malloc/test_malloc.cpp: + * examples/QOS/Simple/Sender_QoS_Event_Handler.cpp: + * examples/APG/ThreadPools/TP_Reactor.cpp: + * examples/IPC_SAP/FILE_SAP/client.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp: + * examples/IPC_SAP/SPIPE_SAP/NPClient.cpp: + * examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp: + * examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp: + * examples/IPC_SAP/SSL_SAP/SSL-client.cpp: + * examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp: + * examples/Logger/client/logging_app.cpp: + * examples/Service_Configurator/IPC-tests/client/remote_stream_client_test.cpp: + * examples/Threads/thread_pool.cpp: + * examples/Threads/thread_specific.cpp: + * examples/Threads/task_four.cpp: + * examples/Reactor/Multicast/Log_Wrapper.cpp: + * examples/Reactor/WFMO_Reactor/Window_Messages.cpp: + * examples/Reactor/Proactor/test_cancel.cpp: + * examples/Reactor/Proactor/test_proactor.cpp: + * examples/Reactor/Misc/notification.cpp: + * examples/Connection/blocking/SPIPE-connector.cpp: + * examples/Mem_Map/file-reverse/file-reverse.cpp: + * examples/C++NPv1/Logging_Handler.cpp: + * examples/C++NPv1/Logging_Client.cpp: + * examples/C++NPv2/AC_Client_Logging_Daemon.cpp: + * examples/C++NPv2/Reactor_Logging_Server_Adapter.cpp: + * examples/C++NPv2/Client_Logging_Daemon.cpp: + * examples/C++NPv2/Service_Reporter.cpp: + * examples/C++NPv2/Logging_Handler.cpp: + + More truncation warning fixes. + +Tue Aug 12 18:15:08 UTC 2008 James H. Hill + + * docs/ace_guidelines.vsmacros: + + Update the macros file to ingore .xsd files. + + * docs/svn/config: + * docs/svn/svn-prefs.reg: + + Added .aspx files to the configuration preferences. + +Tue Aug 12 08:00:15 UTC 2008 Johnny Willemsen + + * ace/Thread_Manager.cpp: + Revert changes of bugzilla 3391, Thread_Pool_Test does fail + with the change + +Mon Aug 11 18:18:15 UTC 2008 Johnny Willemsen + + * tests/Log_Msg_Test.cpp: + Fixed unicode compile error + +Mon Aug 11 16:09:20 UTC 2008 Adam Mitz + + * bin/tao_orb_tests.lst: + + Exclude TAO/tests/Bug_3068_Regression from single-threaded builds. + +Mon Aug 11 13:49:00 UTC 2008 Simon Massey + + * tests/tests.mpc: + There were still some tests that produce test libraries that were + not updated when acelib was devorced from ace_output project. Such + tests need to either add the dependancy (to place their output in + the standard lib directory) or have "libout = ." to specify the + library to be placed locally in the test directory. + +Mon Aug 11 13:37:15 UTC 2008 Johnny Willemsen + + * ace/Thread_Manager.{h,cpp,inl}: + Make sure we don't miss any already terminated threads when doing + a join. Also made some code more readable, removed ancient AIX + workarounds. This fixes bugzilla 3391. Thanks to + for reporting this + + * ace/Containers_T.{h,cpp}: + Changed dont_remove to a bool + +Mon Aug 11 12:45:15 UTC 2008 Johnny Willemsen + + * ace/OS_NS_stdio.cpp: + Simplified some methods + +Mon Aug 11 08:56:15 UTC 2008 Johnny Willemsen + + * tests/Log_Msg_Test.cpp: + Extending testing of ACE_Log_Msg by enabling the format specifiers + tests and add a test for %T. Also removed the check for vsnprintf + to see that VxWorks 5.5.x still has a problem with buffer overflows. + In that case we have to fix that in ACE_Log_Msg. + + * ace/Log_Msg.cpp: + Fixed some buffer size calculations when ACE_TCHAR != char. Fixed + %T when wchar is used, thanks to Nathalie D'Amours + for reporting this. This fixes + bugzilla 3388 + + * ace/ACE.{h,cpp} (timestamp): + Use bool and sizes of buffers should have size_t as type + + * ace/MEM_Stream_Test.cpp: + Removed incorrect comment + +Mon Aug 11 07:36:15 UTC 2008 Johnny Willemsen + + * ace/Makefile.am: + Added missing header files. Thanks to haibin zhang + for reporting this + +Sun Aug 10 23:02:15 UTC 2008 Adam Mitz + + * ace/SSL/SSL_SOCK_Stream.inl (set_handle): + + Reverted back to the C-style cast that was there before Jeff's commit + because many compilers didn't like a reinterpret_cast here. + +Sat Aug 9 17:42:10 UTC 2008 Adam Mitz + + * ace/SSL/SSL_SOCK_Acceptor.cpp: + * ace/SSL/SSL_SOCK_Connector.cpp: + * ace/SSL/SSL_SOCK_Stream.inl: + * ace/SSL/SSL_SOCK_Stream.cpp: + * examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.inl: + + Fixed compile errors in inline=0 and Win32-ssl builds. + ACE_Utils::truncate_cast can't cast ACE_HANDLE to int on Win32. + +Fri Aug 8 20:35:37 UTC 2008 Adam Mitz + + * ace/Stack_Trace.cpp: + + Glibc implementation: fixed whitespace + VxWorks (both kernel and RTP): VxWorks can return -1 for the number + of arguments when the actual number is unknown. + +Fri Aug 8 19:33:42 UTC 2008 Jeff Parsons + + * ace/Message_Queue_T.cpp: + * ace/SSL/SSL_Asynch_BIO.cpp: + * ace/SSL/SSL_SOCK_Acceptor.cpp: + * ace/SSL/SSL_Context.cpp: + * ace/SSL/SSL_Asynch_Stream.cpp: + * ace/SSL/SSL_SOCK_Connector.cpp: + * ace/SSL/SSL_SOCK_Stream.cpp: + * ace/SSL/SSL_SOCK_Stream.inl: + * Kokyu/DSRT_Sched_Queue_T.cpp: + * Kokyu/Default_Dispatcher_Impl.cpp: + * ACEXML/common/Transcode.cpp: + * ACEXML/common/HttpCharStream.cpp: + * ACEXML/common/Mem_Map_Stream.cpp: + * examples/Monitor/MC_Test_Utilities.cpp: + * examples/Service_Configurator/IPC-tests/server/Handle_Timeout.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp: + * examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.inl: + + Fixes for VC 7.1 warnings, mostly truncation. + +Fri Aug 8 17:58:28 UTC 2008 J.T. Conklin + + * configure.ac: + + Changed the ACE_NEW_THROWS_EXCEPTION feature test to use + setrlimit() (on systems that have it) to reduce the RLIMIT_DATA + limit so the test, which continuously allocates memory in order + to observe the behavior of out-of-memory conditions, will "fail" + quickly without unnecessarily consuming a lot of system + resources. Fixes bugzilla #3090. + +Fri Aug 8 14:42:11 UTC 2008 Johnny Willemsen + + * bin/fuzz.pl: + Also check cpp/inl files for RefCountServantBase + +Fri Aug 8 08:36:11 UTC 2008 Johnny Willemsen + + * ace/Truncate.h: + Added missing specializations for Borland C++. + +Fri Aug 8 08:17:11 UTC 2008 Johnny Willemsen + + * ace/Makefile.am: + Added missing Svc_Conf_Token_Table.h which was already in the MPC + file. Thanks to haibin zhang + for reporting this + +Thu Aug 7 21:59:58 UTC 2008 Adam Mitz + + * bin/tao_orb_tests.lst: + + Added the new test TAO/tests/Bug_3068_Regression. + +Thu Aug 7 20:21:29 UTC 2008 Jeff Parsons + + * ace/Process_Manager.cpp: + * ace/Asynch_IO.cpp: + * ace/Pagefile_Memory_Pool.cpp: + * ace/MEM_IO.cpp: + * ace/Time_Value.inl: + * ace/SV_Semaphore_Simple.cpp: + * ace/Thread_Manager.cpp: + * ace/MEM_IO.inl: + * ace/ETCL/ETCL_Interpreter.cpp: + * ace/UPIPE_Stream.cpp: + * ace/SOCK_Dgram.cpp: + * ace/FILE_IO.cpp: + * ace/OS_NS_unistd.cpp: + * ace/FIFO_Recv_Msg.inl: + * ace/CDR_Size.cpp: + * ace/ACE.cpp: + * ace/CDR_Stream.cpp: + + Added usage of ACE_Utils::truncate_cast<> + to get rid of conversion warnings, mostly from size_t + to ssize_t. + +Thu Aug 7 18:02:11 UTC 2008 Johnny Willemsen + + * NEWS: + ACE/TAO/CIAO now supports CodeGear C++ Builder 2009 + +Thu Aug 7 15:28:13 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Makefile.am: + + Added source file Null_Network_Interface_Monitor.cpp that + was overlooked until now. + +Wed Aug 6 18:45:11 UTC 2008 Johnny Willemsen + + * ace/ace.mpc: + Added a few missing header files + +Wed Aug 6 18:17:32 UTC 2008 Jeff Parsons + + * protocols/ace/HTBP/HTBP_Channel.cpp: + * ace/SSL/SSL_Asynch_Stream.cpp: + * performance-tests/TCP/tcp_test.cpp: + * performance-tests/UDP/udp_test.cpp: + * tests/Upgradable_RW_Test.cpp: + * tests/ARGV_Test.cpp: + * tests/OrdMultiSet_Test.cpp: + * apps/JAWS/server/HTTP_Server.cpp: + * apps/soreduce/Obj_Module.cpp: + * apps/soreduce/Library.cpp: + * apps/soreduce/soreduce.cpp: + * apps/soreduce/SO_Group.cpp: + * websvcs/lib/URL_Addr.cpp: + * examples/OS/Process/imore.cpp: + * examples/Connection/blocking/SPIPE-connector.cpp: + * examples/C++NPv2/AC_Client_Logging_Daemon.cpp: + * examples/C++NPv2/Client_Logging_Daemon.cpp: + + Cosmetic changes to eliminate warnings from + some Linux compilers. + +Wed Aug 6 13:40:00 UTC 2008 Simon Massey + + * docs/bczar/bczar.html: + Updated the "Bugzilla" section to match the current version + of bugzilla's interface. + +Wed Aug 6 13:01:11 UTC 2008 Johnny Willemsen + + * ace/SOCK_CODgram.cpp: + Fixed gcc 4.3 warnings + +Wed Aug 6 08:49:11 UTC 2008 Johnny Willemsen + + * examples/Connection/blocking/SPIPE-connector.cpp: + * examples/OS/Process/imore.cpp: + Fixed gcc 4.3 warnings + +Wed Aug 6 08:45:11 UTC 2008 Johnny Willemsen + + * examples/C++NPv2/AC_Client_Logging_Daemon.cpp: + * examples/C++NPv2/Client_Logging_Daemon.cpp: + Fixed gcc 4.3 warnings + +Wed Aug 6 08:12:11 UTC 2008 Johnny Willemsen + + * configure.ac: + * m4/ace.m4: + Use more cached values, improved detection of tcl. Add bzip2 + support + +Wed Aug 6 08:01:11 UTC 2008 Johnny Willemsen + + * ACEXML/common/ZipCharStream.cpp: + Fixed compile error in some builds + + * ACEXML/parser/parser/Parser.cpp: + Check for the dtd file using a / and \ path specifier. This + makes it possible to also use a / on windows to specify + the path. This fixes bugzilla 3352 + + * ACEXML/common/FileCharStream.h: + Doxygen fix + + * ACEXML/common/FileCharStream.cpp: + No need to check for a valid pointer before calling delete + +Tue Aug 5 19:33:26 2008 Steve Huston + + * ace/Log_Msg.cpp: Fixed tab characters. + + * ace/config-posix.h: Only set ACE_HAS_POSIX_SEM_TIMEOUT if the + _POSIX_TIMEOUTS feature test is not -1 (disabled). Fixes build + on HP-UX 11iv3. + + * examples/APG/ThreadPools/LF_ThreadPool.cpp (elect_new_leader): Log + the "Resiging and Electing" message at LM_DEBUG severity, not + LM_ERROR. This is on APG page 342. Thanks to Julien Vintrou for + pointing this out. + + * THANKS: Added Julien Vintrou. + +Tue Aug 5 20:19:28 UTC 2008 Steve Huston + + * ace/config-linux-common.h: Removed ACE_HAS_BROKEN_THREAD_KEYFREE. + Reverts change from + Thu Aug 9 13:39:12 UTC 2007 Johnny Willemsen + which is no longer needed. + +Tue Aug 5 18:51:02 UTC 2008 Jeff Parsons + + * ace/MMAP_Memory_Pool.cpp: + * ace/Service_Manager.cpp: + * ace/Stream.cpp: + * Kokyu/Dispatcher_Task.cpp: + * apps/gperf/src/List_Node.cpp: + * apps/gperf/src/Key_List.cpp: + * apps/gperf/src/Gen_Perf.cpp: + * apps/gperf/src/Iterator.cpp: + * apps/gperf/src/Hash_Table.cpp: + * ACEXML/common/ZipCharStream.cpp: + * ACEXML/common/HttpCharStream.cpp: + * ACEXML/parser/parser/Parser.inl: + * ASNMP/asnmp/asn1.cpp: + * ASNMP/asnmp/address.cpp: + + Cosmetic changes to eliminate warnings on + Fedora Rawhide. + +Tue Aug 5 18:37:11 UTC 2008 Johnny Willemsen + + * rpmbuild/ace-tao-init-fedora.tar.bz2: + * rpmbuild/ace-tao-init-suse.tar.bz2: + Seperated distribution specific files in two bz2 archives, + the rpm spec file will use one of them + +Tue Aug 5 16:41:03 UTC 2008 Steve Huston + + * ace/Log_Msg.h: Changed key_created_ from int to bool. + + * ace/Log_Msg.cpp (close): Two changes related to Bugzilla 2980: + - Remove the #if ACE_HAS_BROKEN_THREAD_KEYFREE - the code inside + that block was what should always be done - delete the ACE_Log_Msg + instance and reset the TSS value to 0 so it's not cleaned up again + later when the thread runs down. The whole idea of the + ACE_HAS_BROKEN_THREAD_KEYFREE seems dubious and should probably be + removed, but I haven't gone that far - there's one more use in + OS_NS_Thread which seems pertinent for LynxOS and I can't test + it, so it's still there - but should be reviewed and probably + removed. + - Free the TSS key - if setting key_created_ to 0, what's the point + of leaving the key? Any future attempt to get the per-thread value + would result in a new key being created. Again, freeing the key + has no affect on already-allocated instances. + This should resolve Bugzilla 2980 again. + +Tue Aug 5 14:33:11 UTC 2008 Johnny Willemsen + + * rpmbuild/ace-tao-ciao.txt: + Spec file that is work in progress. Didn't use spec as extension + because that gives problems with rpmbuild. + +Tue Aug 5 13:52:11 UTC 2008 Johnny Willemsen + + * ace/Guard_T.h: + * ace/Guard_T.inl: + * ace/TSS_T.cpp: + Changed block to a bool + + * ace/Guard_T.h: + Initialise owner_ to solve gcc 4.3 warnings + +Tue Aug 05 10:15:00 UTC 2008 Simon Massey + + * tests/Reactor_Remove_Resume_Test_Dev_Poll.cpp: + + I don't know why removing "TP_Reactor.h" stopped ACE.h from + being included; but is seems it was incidently included in + the previous (non-Dev_Poll) test. + +Tue Aug 5 08:02:11 UTC 2008 Johnny Willemsen + + * ACEXML/common/HttpCharStream.cpp: + Fixed gcc4.3 warning + +Tue Aug 5 07:53:11 UTC 2008 Johnny Willemsen + + * tests/Message_Queue_Test.cpp: + * tests/Message_Queue_Test_Ex.cpp: + Fixed gcc4.3 warning + +Tue Aug 5 07:11:11 UTC 2008 Johnny Willemsen + + * examples/IPC_SAP/SOCK_SAP/run_test + * examples/IPC_SAP/SOCK_SAP/summarize + * examples/IPC_SAP/SSL_SAP/summarize + * examples/IPC_SAP/SOCK_SAP/run_test.sh + * examples/IPC_SAP/SOCK_SAP/summarize.pl + * examples/IPC_SAP/SSL_SAP/summarize.pl + Renamed files to have an extension that matches the type of file + +Tue Aug 5 06:45:11 UTC 2008 Johnny Willemsen + + * bin/add_rel_link.sh: + Added missing path + +Mon Aug 4 19:58:20 UTC 2008 Steve Huston + + * ace/Process.cpp (inherit_environment): Re using Unicode from + Thu Jul 31 15:10:16 UTC 2008 Adam Mitz + only do it for systems that have ACE_HAS_WCHAR. Fixes a LabVIEW + Pharlap ETS build issue. + +Mon Aug 04 13:08:00 UTC 2008 Simon Massey + + * tests/Reactor_Remove_Resume_Test.cpp: + * tests/Reactor_Remove_Resume_Test_Dev_Poll.cpp: + * tests/run_test.lst: + * tests/tests.mpc: + + Split out the ACE_Dev_Poll_Reactor part of this test since + this is excersing a known problem with ACE_Dev_Poll_Reactor + (see Bugzilla 3178). + +Mon Aug 4 07:20:12 UTC 2008 Johnny Willemsen + + * ace/config-g++-common.h: + * ace/config-macros.h: + Moved definition of ACE_UNUSED_ARG for GC back to config-macros.h else + it isn't available when doing an autoconf build + +Fri Aug 1 10:59:55 UTC 2008 Adam Mitz + + * tests/Process_Env_Test.cpp: + + #ifdef-out the helper functions in the cases where the body of + run_main is also #ifdef'ed-out. + +Thu Jul 31 15:10:16 UTC 2008 Adam Mitz + + * ace/Process.cpp (inherit_environment): + + When "use_unicode_environment" is in effect, use the unicode env + block (GetEnvironmentStringsW) when copying the current environment + in order to inherit it (Win32 only). + + * tests/Process_Env_Test.cpp: + + Extended this test to verify that a large environment block is indeed + inherited by the spawned process. + +Thu Jul 31 13:16:00 UTC 2008 Simon Massey + + * bin/tao_orb_tests.lst: + + The QUICK test alternatives should have the same configs as + their non-quick alternative tests. This has been playing havok + with !Win32 tests on windows platforms that are using QUICK. + +Thu Jul 31 12:35:00 UTC 2008 Simon Massey + + * tests/run_test.lst: + * tests/tests.mpc: + * tests/Refcounted_Event_Handler_Test_DevPoll.cpp: + * tests/Reference_Counted_Event_Handler_Test_Dev_Poll.cpp: + + Test renamed (has to be less than 38 characters). + +Thu Jul 31 10:25:12 UTC 2008 Johnny Willemsen + + * ace/config-g++-common.h: + Use a different ACE_UNUSED_ARG macro for GCC 4.2 and newer. Moved + also the definition for gcc to this file instead of config-macros.h. + Thanks to Jules Colding , Jonathan Brannan + , and Ken Sedgwick + for providing the patches. This fixes bugzilla 3270 + + * ace/config-macros.h: + Don't define ACE_UNUSED_ARG for GCC + + * rpmbuild/ace-tao.spec: + Removed unused arg patch + + * rpmbuild/ace-tao-unusedarg.patch: + Removed, not needed anymore + +Thu Jul 31 10:20:00 UTC 2008 Simon Massey + + * tests/Reactor_Dispatch_Order_Test_Dev_Poll.cpp: + + To avoid warnings on platforms where: + #if defined (ACE_HAS_DEV_POLL) || defined (ACE_HAS_EVENT_POLL) + is false, this test has now been fully guarded and an alternate + main provided. + + * tests/Reference_Counted_Event_Handler_Test_Dev_Poll.cpp: + * tests/run_test.lst: + * tests/tests.mpc: + + Since the collated test scores are actually grouping both runs + of the original test together (they ignore parameters apparently), + a newly named test was needed. + +Thu Jul 31 10:05:12 UTC 2008 Johnny Willemsen + + * ace/config-macros.h: + Only define ACE_UNUSED_ARG when it is not defined yet. Makes it + easier to test how to resolve warnings with gcc 4.3 + +Wed Jul 30 14:03:12 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxworks6.2.GNU: + * include/makeinclude/platform_vxworks6.3.GNU: + Also convert slashes in HOST_ROOT + +Wed Jul 30 09:55:00 UTC 2008 Simon Massey + + * tests/tests.mpc: + + Missed adding the new Reactor_Dispatch_Order_Test_Dev_Poll + entry. + +Tue Jul 29 22:23:08 UTC 2008 J.T. Conklin + + * m4/ace.m4: + + Add ACE_PATH_BZIP2 feature test, sets ACE_BZIP2_CPPFLAGS, + ACE_BZIP2_LDFLAGS, and ACE_BZIP2_LIBS as needed when + --with-bzip2 is specified on the command line. + +Tue Jul 29 21:33:14 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/config/automake.features: + + Add bzip2=1 + +Tue Jul 29 21:29:43 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/config/ace_bzip2.mpb: + + New file, overrides definitions from MPC's bzip2.mpb for + automake build. + +Tue Jul 29 19:58:22 UTC 2008 Adam Mitz + + * bin/tao_orb_tests.lst: + + Reverted Tue Jul 29 14:21:32 UTC 2008 Adam Mitz + because the bug should now be fixed in TAO. + +Tue Jul 29 18:11:32 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + TAO/tests/Bug_3000_Regression fails because that issue remains + unresolved, added !FIXED_BUGS_ONLY. + +Tue Jul 29 14:21:32 UTC 2008 Adam Mitz + + * bin/tao_orb_tests.lst: + + TAO/tests/Bug_3163_Regression fails because that issue remains + unresolved, added !FIXED_BUGS_ONLY. + +Tue Jul 29 12:45:00 UTC 2008 Simon Massey + + * tests/run_test.lst: + * tests/Reference_Counted_Event_Handler_Test.cpp: + + Corrected the disabling of ACE_Dev_Poll_Reactor test and split + the test into two runs once with this reactor test disabled + and once with just this reactor test enabled (marked with + !FIXED_BUGS_ONLY) due to internal problems with + ACE_Dev_Poll_Reactor. + +Tue Jul 29 12:14:00 UTC 2008 Simon Massey + + * tests/run_test.lst: + * tests/Reactor_Dispatch_Order_Test.cpp: + * tests/Reactor_Dispatch_Order_Test_Dev_Poll.cpp: + + These tests now actually return a failure if the test failed + instead of always returning 0. I have also split out the + problematic part of this test re-enabled by: + Wed Jul 9 19:07:24 2008 Steve Huston which itself reversed: + Sat Mar 29 08:16:57 UTC 2008 Johnny Willemsen that originally + disabled testing for ACE_Dev_Poll_Reactor due to internal + problems with ACE_Dev_Poll_Reactor. + +Mon Jul 28 13:39:13 2008 Johnny Willemsen + + * ace/config-macros.h: + * ace/streams.h: + Removed workarounds for ancient Borland C++ versions + +Mon Jul 28 13:32:13 2008 Johnny Willemsen + + * ace/Asynch_Acceptor.cpp: + * ace/WIN32_Asynch_IO.cpp: + Removed compiler checks + + * ace/OS_NS_stdio.cpp: + Don't check for Borland C++ but for ACE_HAS_NONCONST_FDOPEN + + * ace/OS_NS_stdio.inl: + Removed workaround for Borland C++ + +Mon Jul 28 13:10:13 2008 Johnny Willemsen + + * ace/Global_Macros.h: + Removed obsolete workaround for Borland C++ + +Mon Jul 28 13:03:13 2008 Johnny Willemsen + + * ace/ace_wchar.h: + Removed obsolete workaround for Borland C++ + +Mon Jul 28 11:52:13 2008 Johnny Willemsen + + * ace/Registry.cpp: + Don't declare a static object within a method because that + could lead to race conditions in a multi threaded program + + * ace/ace_qt4reactor.mpc: + Fixed bug in this file + +Mon Jul 28 11:40:13 2008 Johnny Willemsen + + * ace/ETCL/ETCL_Interpreter.h: + Doxygen fixes and made destructor virtual, this is a base class + + * ace/INET_Addr.cpp: + Const change + +Fri Jul 25 14:21:13 2008 Johnny Willemsen + + * ace/ace_qtreactor.mpc: + * ace/ace_qt3reactor.mpc: + Renamed qt to qt3, this builds and links the qtreactor + with qt3 + + * ace/ace_qt4reactor.mpc: + New project for qt4 + + You can set qt=1 and qt3=1 together or set qt4=1, but not + both at the same time. Thanks to Kees van Marle + for testing qt4 + +Fri Jul 25 14:13:13 2008 Johnny Willemsen + + * ace/QtReactor/QtReactor.cpp: + * ace/QtReactor/QtReactor.h: + Improved qt4 support + +Fri Jul 25 14:09:13 2008 Johnny Willemsen + + * bin/MakeProjectCreator/config/ace_qt3.mpb + * bin/MakeProjectCreator/config/ace_qt4.mpb + * bin/MakeProjectCreator/config/global.features: + Set qt3 and qt4 default to 0. qt4 has different libs + that we need to link with but also the qglobal.h is + located on a different location, so added ACE_HAS_QT4 + which is then used to select which qglobal.h we include. + + * bin/MakeProjectCreator/config/ace_qtreactor.mpb: + This is for qt3 so derive from ace_qt3 + +Thu Jul 24 19:04:13 2008 Steve Huston + + * ace/Containers_T.h: Improved documentation for ACE_DLList, noting + especially that T pointers inserted into the list are not deleted + when removed. Thank you to Bob Fiske for this improvement and sample + code to illustrate. + + * THANKS: Added Bob Fiske. + +Thu Jul 24 12:50:00 UTC 2008 Simon Massey + + * bin/diff-builds-and-group-fixed-tests-only.sh: + This shell script runs the perl diff-builds.pl script between + the date given as the first parameter and the current utc date. + The output is tidied up and any !FIXED_BUGS_ONLY bugs are + removed before being grouped and the failed tests counted. + +Thu Jul 24 08:10:00 UTC 2008 Simon Massey + + * bin/tao_orb_tests.lst: + * bin/tao_other_tests.lst: + Added config item !FIXED_BUGS_ONLY to tests that highlight + problems that have not yet been fixed. Please remove this + config item once the bugs have actually been fixed, and + include this config item with any newly added tests in the + future that fall into this category. + +Wed Jul 23 13:30:28 UTC 2008 Simon Massey + + * bin/PerlACE/Process_Win32.pm: + Allow named .bat files for windows. + +Wed Jul 23 13:08:28 UTC 2008 Johnny Willemsen + + * bin/generate_doxygen.pl: + * etc/tao_ziop.doxygen: + * html/index.html: + Added TAO ZIOP to the documentation + +Wed Jul 23 10:51:28 UTC 2008 Johnny Willemsen + + * ace/Select_Reactor_Base.h: + Doxygen change + + * ace/Select_Reactor_T.cpp: + * ace/Select_Reactor_T.h: + * ace/TP_Reactor.cpp: + * ace/TP_Reactor.h: + mask_signals should be a bool like in the base class + +Wed Jul 23 08:11:28 UTC 2008 Johnny Willemsen + + * ace/SOCK_Dgram_Mcast.cpp: + Use reentrant get_host_addr. This fixes bugzilla 3368. Thanks to + Yongming Wang for reporting this + +Tue Jul 22 15:02:00 UTC 2008 Simon Massey + + * bin/group_test_stats.sh: + Reverse and sort numerically so that highest number of + failures are listed first. + +Tue Jul 22 13:09:28 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Added ZIOP test + +Tue Jul 22 11:52:28 UTC 2008 Johnny Willemsen + + * bin/make_release.py: + Don't convert line ending for pdf files + +Tue Jul 22 09:55:28 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/config/global.features: + bzip2 is default disabled + +Tue Jul 22 07:36:28 UTC 2008 Johnny Willemsen + + * ace/CDR_Stream.{h,cpp,inl}: + Added setting for alignment which is needed for ZIOP where we want + to place back the wr_ptr to a previous location. Few const and layout + changes + +Mon Jul 21 13:09:28 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Run nslist tests under vxworks + +Sat Jul 19 19:58:54 UTC 2008 Johnny Willemsen + + * ace/config-macosx-tiger.h: + Make sure we set the correct ACE_SIZEOF_LONG_DOUBLE value. Thanks + to Frank Förster for reporting this + +Thu Jul 17 20:24:11 UTC 2008 Steve Huston + + * ace/OS_NS_sys_socket.inl (recvfrom): For Pharlap ETS, correct for + a situation where recvfrom() returns a good address but an + unexpectedly short length. + +Tue Jul 15 17:29:22 UTC 2008 Jeff Parsons + + * examples/Monitor/Bytes_Sent/bytes_sent.cpp: + * examples/Monitor/Message_Queue_Size/message_queue_size.cpp: + * examples/Monitor/Constraint/constraint.cpp: + * examples/Monitor/CPU_Load/cpu_load.cpp: + * examples/Monitor/Num_Threads/num_threads.cpp: + * examples/Monitor/Group/group.cpp: + * examples/Monitor/Memory_Usage/memory_usage.cpp: + + Changes corresponding to the relocation in + + Tue Jul 15 17:19:14 UTC 2008 Jeff Parsons + +Tue Jul 15 17:19:14 UTC 2008 Jeff Parsons + + * ace/Monitor_Size.cpp: + * ace/Monitor_Control_Types.cpp: + * ace/Monitor_Control_Types.h: + * ace/Monitor_Base.cpp: + * ace/Monitor_Base.h: + * ace/Monitor_Base.inl: + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/CPU_Load_Monitor.cpp: + * ace/Monitor_Control/Monitor_Group.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.cpp: + * ace/Monitor_Control/Monitor_Query.cpp: + * ace/Monitor_Control/Num_Threads_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + Relocated the statistics-related values from + Monitor_Base to Monitor_Control_Types. Also + inlined the information type accessor, the + constraint list accessor and the refcounting + methods. + +Tue Jul 15 01:27:54 UTC 2008 Johnny Willemsen + + * ace/config-win32-common.h: + Added pragma comment for iphlpapi.lib. Thanks to Yongming Wang + for reporting this + +Mon Jul 14 12:50:34 UTC 2008 Chad Elliott + + * NEWS: + + Added an entry for my change from Mon Jun 30 12:41:00 UTC 2008. + +Mon Jul 14 12:05:00 UTC 2008 Simon Massey + + * ace/Message_Queue_T.cpp: + + Correct void function dump returns from previous commit of: + Fri Jul 11 08:06:40 UTC 2008 James H. Hill + +Sat Jul 12 12:59:19 UTC 2008 Johnny Willemsen + + * ace/config-borland-common.h: + Removed BCB4 support + + * ace/ACE.cpp: + Const/layout changes + + * ace/Configuration.h: + Doxygen changes + + * ace/Monitor_Base.cpp (retrieve_and_clear): + Use clear_i to prevent deadlocks + + * ace/SOCK_IO.cpp: + Const changes + + * ace/Strategies_T.cpp: + layout changes + +Fri Jul 11 23:48:19 UTC 2008 Johnny Willemsen + + * bin/make_release.py: + Don't exclude the mwc files for vc8. Thanks to Michael Guntli + for reporting + this. This fixes bugzilla 3364 + +Fri Jul 11 14:41:19 UTC 2008 James H. Hill + + * NEWS: + + Updated the NEW file to reflect previous ChangeLog entry. + +Fri Jul 11 08:06:40 UTC 2008 James H. Hill + + * ace/Message_Queue_T.h: + * ace/Message_Queue_T.cpp: + + Implemented the iterator and reverse iterator for the + ACE_Message_Queue_Ex class. + +Wed Jul 9 21:20:13 UTC 2008 Ken Sedgwick + + * rpmbuild/README: + Added basic rpmbuild instructions. + +Wed Jul 9 19:07:24 2008 Steve Huston + + * tests/Reactor_Dispatch_Order_Test.cpp: Reversed this change: + Sat Mar 29 08:16:57 UTC 2008 Johnny Willemsen + which disabled testing for ACE_Dev_Poll_Reactor. Let's see what the + issues are then address and/or disable as needed. + Also fixed a cut/paste error. + +Wed Jul 9 18:37:57 2008 Steve Huston + + * tests/Reference_Counted_Event_Handler_Test.cpp: Enabled test for + Winsock 2 systems; previously only ran the ACE_WFMO_Reactor-based + test for non-Winsock 2 systems, where it is not supported. + +Wed Jul 9 17:45:40 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for ACE_HAS_NON_BLOCKING_CONNECTS. + + * tests/MT_SOCK_Test.cpp: + + Remove use of ACE_HAS_NON_BLOCKING_CONNECTS feature test macro. + It was removed since ACE no longer supports any systems that + required it. + +Wed Jul 9 16:09:30 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + * configure.ac: + + Remove feature test and autoheader template for + ACE_LACKS_WILDCARD_BIND. + + * ace/Sock_Connect.cpp: + + Remove use of ACE_LACKS_WILDCARD_BIND feature test macro. + + * ace/README: + + Remove ACE_LACKS_WILDCARD_BIND from the list of feature test + macros. It was removed since ACE no longer supports any systems + that required it. + +Wed Jul 9 16:02:32 UTC 2008 J.T. Conklin + + * configure.ac: + + Changed ACE_HAS_SIGVAL_SIGVAL_INT and ACE_HAS_SIGVAL_SIGVAL_PTR + feature tests to use "union sigval" instead of "sigval_t". The + former is what ACE uses; while the latter is a common extension, + it is not in the XPG3 specification. Thanks to Olli Savia. + +Wed Jul 9 14:23:00 UTC 2008 J.T. Conklin + + * ace/README: + + Remove ACE_HAS_TEMPLATE_SPECIALIZATION from list of feature + test macros. + +Wed Jul 9 14:18:26 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + * configure.ac: + + Remove feature test and autoheader template for + ACE_HAS_DLFCN_H_BROKEN_EXTERN_C. + + * ace/os_include/os_dlfcn.h: + + Remove use of ACE_HAS_DLFCN_H_BROKEN_EXTERN_C feature test + macro. + + * ace/README: + + Remove ACE_HAS_DLFCN_H_BROKEN_EXTERN_C from the list of feature + test macros. It was removed since ACE no longer supports any + systems that required it. + +Wed Jul 9 09:20:03 UTC 2008 Olli Savia + + * ace/TTY_IO.h: + * ace/TTY_IO.cpp: + Removed deprecated 'parityenb' member from ACE_TTY_IO::Serial_Params + structure. + + * NEWS: + Added a note about change above. + +Tue Jul 8 21:53:31 UTC 2008 Douglas C. Schmidt + + * ace/Service_Manager.cpp (process_request): Ensure that requests + are processed using the global context, rather than the current + one. Thanks to Michael Doubez for suggesting this fix. + +Tue Jul 8 16:44:24 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for ACE_HAS_BROKEN_HPUX_TEMPLATES. + + * netsvcs/lib/Server_Logging_Handler_T.cpp: + * netsvcs/lib/Server_Logging_Handler_T.h: + + Remove use of ACE_HAS_BROKEN_HPUX_TEMPLATES feature test macro. + + * ace/README: + + Remove ACE_HAS_BROKEN_HPUX_TEMPLATES from the list of feature + test macros. It was removed since ACE no longer supports any + systems that required it. + +Tue Jul 8 16:41:26 2008 Steve Huston + + * ace/WIN32_Asynch_IO.cpp (ACE_WIN32_Asynch_Write_Stream::write): For + Winsock 2-capable platforms, use WSASend() instead of WriteFile(). + The former performs an order of magnitude faster. Thanks to + Namrata Gandhi for running the Win32 native performance tests. + +Tue Jul 8 16:35:57 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + * configure.ac: + + Remove feature test and autoheader template for + ACE_NEEDS_REGEXPR_H. It is no longer used by ACE. + + * ace/config-unixware-7.1.0.h: + * ace/config-unixware-7.1.0.udk.h: + + Remove the ACE_NEEDS_REGEXPR_H feature test macro definition. + It is no longer used by ACE. + +Tue Jul 8 16:06:46 UTC 2008 J.T. Conklin + + * NEWS: + + Document new --enable-rcsid option for autoconf build. + + * m4/ace.m4: + * m4/config_h.m4: + * m4/platform.m4: + + Add support of a new --enable-rcsid option for the autoconf + build. Previously, compiling RCS IDs into object files was + tightly coupled with the --enable-debug option and was always + disabled for certain operating systems. A separate option allows + the user to select this behavior independently. + +Tue Jul 8 14:41:08 2008 Steve Huston + + * tests/Reference_Counted_Event_Handler_Test.cpp: Fixed test cases + that I accidentally reversed in + Fri Jul 4 20:11:02 UTC 2008 Steve Huston + +Tue Jul 08 06:44:09 MST 2008 Trevor Fields + + * bin/PerlACE/Run_Test.pm: + + Added waitforfileoutput and waitforfileoutput_timed + methods that wait for output to appear in a file. + +Sun Jul 6 19:47:27 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + Added idl and pidl include files to tao-devel package. + +Sun Jul 6 18:28:58 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + * rpmbuild/ace-tao-orbsvcs-daemon.patch: + * rpmbuild/ace-tao-config.patch: + Updated for latest DOC Group release (x.6.6). + Tracked libACE_Monitor_Control name change. + Fixed broken patches. + +Fri Jul 4 20:11:02 UTC 2008 Steve Huston + + * ace/config-macros.h: Don't set ACE_HAS_PROCESS_SPAWN for + ACE_HAS_PHARLAP - there's only one process available. + + * ace/Recursive_Thread_Mutex.cpp (get_nesting_level): Add Pharlap ETS + to those platforms without access to the recursion count on a + recursive mutex. + + * tests/run_test.lst: Disable Sendfile_Test on LABVIEW_RT - it lacks + sendfile support. + + * tests/Reference_Counted_Event_Handler_Test.cpp: Replaced ACE_ASSERT + with ACE_ERROR; surrounded naked strings with ACE_TEXT; added a test + option for using ACE_Dev_Poll_Reactor where available. + + * tests/Service_Config_Test.cpp: Replaced ACE_ASSERT with ACE_ERROR. + + * tests/Thread_Pool_Reactor_Resume_Test.cpp: + * tests/Thread_Pool_Reactor_Test.cpp: Add ACE_HAS_PHARLAP to those + platforms that need to scale back the max number of connections + due to limited capacity. + +Thu Jul 3 21:42:54 UTC 2008 J.T. Conklin + + * configure.ac: + + Changed the feature test used for the existance of the sigval_t + type not to define ACE_LACKS_SIGVAL_T if it does not exist. + + However, it is still needed to set the ac_cv_type_sigval_t shell + variable, which is used to decide whether to perform the + ACE_HAS_SIGVAL_SIGVAL_INT and ACE_HAS_SIGVAL_SIGVAL_PTR feature + tests. + + This fixes (the newly reopened) bugzilla #2794. Thanks to Olli + Savi for suggesting taking another look. + +Thu Jul 3 16:38:35 UTC 2008 Chad Elliott + + * bin/MakeProjectCreator/templates/gnu.mpd: + + Added the use of 'postclean' to be used during the realclean + target. + +Wed Jul 2 18:30:15 UTC 2008 Jeff Parsons + + * ace/Monitor_Base.cpp (clear_i): + + Added resize of string array (if applicable) to 0. + + * ace/Monitor_Control/CPU_Load_Monitor.h: + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.h: + * ace/Monitor_Control/Num_Threads_Monitor.h: + * ace/Monitor_Control/CPU_Load_Monitor.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.cpp: + * ace/Monitor_Control/Num_Threads_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + Finished implementation of clear_i() method for all + platforms. + +Wed Jul 2 12:45:53 UTC 2008 Douglas C. Schmidt + + * Updated the COPYING file to make it consistent with what's on the website. + +Wed Jul 02 12:30:00 UTC 2008 Simon Massey + + * ace/Monitor_Control/Solaris_Network_Interface_Monitor.cpp: + + ACE_TEXT () and ACE_TEXT_ALWAYS_CHAR () required here. + +Wed Jul 02 12:05:00 UTC 2008 Simon Massey + + * ace/Framework_Component.cpp: + + Annoying text constant problem in a build. No need for ACE_TEXT() + here. + +Wed Jul 2 11:51:03 UTC 2008 Chad Elliott + + * tests/Makefile.am: + + Added the Process_Env_Test. + +Wed Jul 02 11:40:00 UTC 2008 Simon Massey + + * tests/Process_Env_Test.cpp: + + Annoyingly the ACE_RCSID() macro provides it's own ; + This fixes the "Process_Env_Test.cpp:23: error: extra ';'" error. + +Tue Jul 1 22:47:17 UTC 2008 Steve Huston + + * ace/Process.{h cpp}: Can't define or use the new convert_env_buffer() + method unless ACE_HAS_WCHAR is defined. This extra check is needed + for LabVIEW RT / Pharlap ETS because it purports to be Win32 but + does not have wide-char support. + +Tue Jul 1 14:20:00 UTC 2008 Simon Massey + + * bin/PythonACE/fuzz/check_no_tabs.py: + + Attempt to provide tabs check. + +Tue Jul 1 12:29:34 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + Cosmetic changes. + +Mon Jun 30 16:50:05 UTC 2008 Chad Elliott + + * ace/Process.h: + + Fixed a misplaced bit of code. + +Mon Jun 30 12:41:00 UTC 2008 Chad Elliott + + * ace/Process.h: + * ace/Process.cpp: + + Added an option to ACE_Process_Options to use a wchar_t environment + buffer instead of char. This is useful only on Windows with + ACE_USES_WCHAR undefined. The benefit of using a wchar_t + environment buffer is that it is not limited to 32kb as a char + environment buffer is. + + In ACE_Process::spawn(), convert the char environment buffer to a + wchar_t environment buffer if specified to do so in the process + options. + + * tests/Process_Env_Test.cpp: + * tests/run_test.lst: + * tests/tests.mpc: + + Added a test for the above feature. + +Fri Jun 27 18:04:52 UTC 2008 Steve Huston + + * include/makeinclude/rules.local.GNU: Removed the first setting of + CLEANUP_OBJS by itself - it was a duplicate of what's done in + CLEANUP_BIN's case, but with possibly an incorrect objext. Prevents + a main executable's object file from being deleted twice and ensures + only valid object file extension is used. Thanks to Howard Finer + for pointing this out. + +Fri Jun 27 16:08:27 UTC 2008 Steve Huston + + * include/makeinclude/rules.local.GNU: Add $(VOBJS) to CLEANUP_OBJS to + be sure all objects that go into a binary are cleaned up. + +Fri Jun 27 15:35:58 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/modules/AutomakeWorkspaceHelper.pm: + + Changed TAO_IDLFLAGS to Rename executable from gperf to + ace_gperf. + +Fri Jun 27 14:58:17 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Solaris_Network_Interface_Monitor.h: + + Changed ACE_CString member to ACE_TString, to accommodate + wchar builds. + +Thu Jun 26 20:41:20 UTC 2008 J.T. Conklin + + * ace/Profile_Timer.cpp: + + Explictly #include "ace/OS_NS_fcntl.h" and "ace/OS_NS_unistd.h" + if ACE_HAS_PRUSAGE_T is defined. These headers are implicitly + #included with inline builds, but are required for builds + where inline has been disabled. + +Thu Jun 26 13:13:16 UTC 2008 Jeff Parsons + + * ace/Monitor_Control_Types.h: + * ace/Monitor_Base.cpp: + * ace/Monitor_Base.h: + * ace/Monitor_Control/Monitor_Group.h: + * ace/Monitor_Control/Monitor_Group.cpp: + + Restored support for string data type in + monitor storage, by moving data types, + members and methods from their original + location in an earlier version of the + Notification Service monitor classes, + to the appropriate locations in ACE. + +Thu Jun 26 02:45:21 UTC 2008 Phil Mesnier + + * THANKS: added Ittehad Shaikh + +Wed Jun 25 15:05:29 UTC 2008 J.T. Conklin + + * apps/gperf/src/Makefile.am: + + Rename executable from gperf to ace_gperf. + +Wed Jun 25 14:59:13 UTC 2008 J.T. Conklin + + * apps/gperf/tests/Makefile.am: + + Re-tabify. + +Wed Jun 25 14:09:52 UTC 2008 Johnny Willemsen + + * rpmbuild/ace-tao-config.patch + Removed ACE_GPERF + + * rpmbuild/ace-tao.spec: + Document changes + + * rpmbuild/ace-tao-gperf-info.patch: + Removed, not needed anymore + +Wed Jun 25 13:29:13 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + * configure.ac: + + Remove feature test and autoheader template for + ACE_HAS_BROKEN_NETBSD_MSYNC. + + * ace/OS_NS_sys_mman.inl: + + Remove the use of the ACE_HAS_BROKEN_NETBSD_MSYNC feature test + macro. It was removed since ACE no longer supports the systems + that required it. + +Wed Jun 25 11:23:00 UTC 2008 Simon Massey + + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + + Tue Jun 24 11:46:41 UTC 2008 Jeff Parsons committed + Miss-cased ACE_TEXT. + +Wed Jun 25 10:00:00 UTC 2008 Simon Massey + + * bin/fuzz.pl: + + Enhance ACE_TMAIN and ORB_init checks for /* .. */ comments. + +Wed Jun 25 06:58:52 UTC 2008 Johnny Willemsen + + * apps/gperf/gperf.1: + * apps/gperf/gperf.info: + * apps/gperf/gperf.mpc: + * apps/gperf/gperf.texi: + * apps/gperf/ace_gperf.1: + * apps/gperf/ace_gperf.info: + * apps/gperf/ace_gperf.mpc: + * apps/gperf/ace_gperf.texi: + * apps/gperf/gperf/src/gperf.mpc: + * apps/gperf/gperf/tests/gperf_test.mpb: + * apps/gperf/gperf/tests/Makefile.am: + Renamed gperf to ace_gperf to make sure we always get the gperf + from ace, fedora also has a regular gperf package + + * include/makeinclude/platform_vxworks5.5.x.GNU: + * include/makeinclude/platform_vxworks6.2.GNU: + * include/makeinclude/platform_vxworks6.3.GNU: + Updated for gperf rename + + * rpmbuild/ace-tao.spec: + Removed gperf rename which only was done in the rpm package. + This fixes bugzilla 3342 + +Wed Jun 25 05:59:52 UTC 2008 J.T. Conklin + + * include/makeinclude/platform_netbsd.GNU: + + Conditionally set no_hidden_visibility to 1. + +Tue Jun 24 13:52:00 UTC 2008 Simon Massey + + * tests/Bug_2980_Regression_Test.cpp: + * tests/tests.mpc: + + Remove ACE_TMAIN from this test and stop it building on + wide systems (as per original test). The test can not use + ace directly. + +Tue Jun 24 13:30:31 2008 Steve Huston + + * ace/CDR_Stream.h: For ACE_OutputCDR, note that attempting to set a + specific byte order requires ACE_ENABLE_SWAP_ON_WRITE to have any + affect. Thanks to Howard Finer for pointing this out. + +Tue Jun 24 11:46:41 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + For Solaris and *BSD WChar builds, ACE_TEXT-ified the argument + in the call to the platform-specific base class + constructor. + +Tue Jun 24 11:02:00 UTC 2008 Simon Massey + + * ace/Svc_Conf_Token_Table.h: + + commit generated 3rd file. + Fix the dependancies for FC6_Compact_NoInline build. + +Tue Jun 24 09:45:00 UTC 2008 Simon Massey + + * tests/Bug_2980_Regression_Test.cpp: + * tests/tests.mpc: + + Manually add the ACE_TMAIN code to this test. + +Tue Jun 24 00:03:27 UTC 2008 J.T. Conklin + + * ace/Monitor_Control/BSD_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/BSD_Network_Interface_Monitor.h: + + Changed to fetch current value in constructor, and subtract + that from subsequent values in each update() call. + +Mon Jun 23 15:28:00 UTC 2008 Simon Massey + + * ace/Svc_Conf_y.cpp: + + Fix fuzz errors incorrect ACE_TMAIN/main use; commit generated 2nd. + +Mon Jun 23 15:27:00 UTC 2008 Simon Massey + + * ace/Svc_Conf.y: + + Fix fuzz errors incorrect ACE_TMAIN/main use; commit source 1st. + +Mon Jun 23 13:51:23 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Windows_Monitor.h: + + Changed class member type from ACE_CString to ACE_TString + to accomondate Unicode builds. + + * ace/Monitor_Control/Windows_Monitor.cpp: + + Removed incorrect use of ACE_TEXT wrapper on a non-literal. + +Mon Jun 23 12:34:35 UTC 2008 Chad Elliott + + * bin/tao_other_tests.lst: + + Added the new Notify Timeout test. + +Mon Jun 23 12:09:26 UTC 2008 Douglas C. Schmidt + + * examples/C++NPv2/display_logfile.cpp: Divided an ACE_TCHAR + string by sizeof (ACE_TCHAR) to get the appropriate size. + Thanks to J.T. for reporting + this. + +Mon Jun 23 11:12:00 UTC 2008 Simon Massey + + * ace/Svc_Conf_y.cpp: + * bin/LabVIEW_RT/labview_test_controller/test.cpp: + * ASNMP/examples/trap/trap.cpp: + * ASNMP/examples/get/get.cpp: + * ASNMP/examples/get/get_async.cpp: + * ASNMP/examples/set/set.cpp: + * ASNMP/examples/next/next.cpp: + * ASNMP/examples/walk/walk.cpp: + * netsvcs/clients/Tokens/mutex/test_mutex.cpp: + * performance-tests/RPC/client.cpp: + * tests/Bug_2980_Regression_Test.cpp: + + Fix fuzz errors incorrect ACE_TMAIN/main use. + +Sun Jun 22 17:23:08 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/CPU_Load_Monitor.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.cpp: + * ace/Monitor_Control/Num_Threads_Monitor.cpp: + + Fix to clear_i() implementation for these monitors that + compiled only on Windows. + +Fri Jun 20 20:40:50 UTC 2008 Jeff Parsons + + * ace/Monitor_Size.cpp: + * ace/Monitor_Base.cpp: + * ace/Monitor_Base.h: + + Moved stats features from the Notification Service monitor + class to the ACE base class. + + * ace/Monitor_Control/Windows_Multi_Instance_Monitor.cpp: + * ace/Monitor_Control/Linux_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/CPU_Load_Monitor.h: + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Windows_Monitor.h: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.h: + * ace/Monitor_Control/Monitor_Group.h: + * ace/Monitor_Control/Null_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/BSD_Network_Interface_Monitor.h: + * ace/Monitor_Control/Solaris_Network_Interface_Monitor.h: + * ace/Monitor_Control/Num_Threads_Monitor.h: + * ace/Monitor_Control/Bytes_Sent_Monitor.h: + * ace/Monitor_Control/CPU_Load_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.h: + * ace/Monitor_Control/Windows_Monitor.cpp: + * ace/Monitor_Control/Monitor_Group.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.cpp: + * ace/Monitor_Control/Linux_Network_Interface_Monitor.h: + * ace/Monitor_Control/Windows_Multi_Instance_Monitor.h: + * ace/Monitor_Control/BSD_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/Bytes_Received_Monitor.h: + * ace/Monitor_Control/Solaris_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.h: + * ace/Monitor_Control/Null_Network_Interface_Monitor.h: + * ace/Monitor_Control/Num_Threads_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + Implemented overrides of clear_i() for all the OS + monitors. + +Fri Jun 20 20:25:12 UTC 2008 Steve Huston + + * bin/PerlACE/README: Edited to reflect the change in process for + referring to test components. Components are now referred to with + numbers instead of names. + + * bin/PerlACE/TestTarget.pm: In create_target(), warn if the component + is not a number. + + * bin/PerlACE/ProcessLVRT.pm: Don't try to close an undefined Telnet. + + * bin/tao_orb_tests.lst: Removed the LabVIEW_RT disabling on + Bug_2702_Regression, Oneway_Send_Timeouts, and Abstract_Interface. + + * tests/run_test.pl: Changed the target component from "ace" to 1 per + new component referring convention. + +Fri Jun 20 18:40:10 UTC 2008 Chad Elliott + + * bin/PerlACE/Run_Test.pm: + + Removed references to HostProcess and TargetProcess. + + * bin/PerlACE/TestTarget.pm: + * bin/PerlACE/TestTarget_VxWorks.pm: + + Added a new test target for VxWorks. It currently has no reboot + related functionality. + + * bin/PerlACE/TestTarget_LVRT.pm: + + Added the ability to accept multiple files for the DeleteFile + method as unlink does. + + * bin/PerlACE/HostProcess.pm: + * bin/PerlACE/TargetProcess.pm: + + Removed these files. + +Fri Jun 20 15:15:00 UTC 2008 Simon Massey + + * bin/fuzz.pl: + + Small bug in white space compaction. + +Fri Jun 20 14:15:00 UTC 2008 Simon Massey + + * bin/fuzz.pl: + + Enhance ACE_TMAIN check for multi-line detection and remove + detection level for this check. + +Fri Jun 20 12:09:53 UTC 2008 Chad Elliott + + * examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp: + * examples/IPC_SAP/SSL_SAP/SSL-client.cpp: + + Added static_cast's to avoid warnings from vc8. + +Thu Jun 19 16:21:07 2008 Steve Huston + + * ace/CDR_Base.h: + * ace/CDR_Stream.h: Added a enum to ACE_CDR with the values for + byte ordering specifier. Moved the setting of ACE_CDR_BYTE_ORDER + from CDR_Stream.h to CDR_Base.h so it can be used in the enum. + These make it easier for users to figure out what to do when they + want to force a specific byte ordering. + Also did a little more doxygen cleanup. + +Thu Jun 19 15:11:00 UTC 2008 Simon Massey + + * bin/fuzz.pl: + + Enable ORB_init() 3rd parameter null string check. + +Thu Jun 19 14:11:04 UTC 2008 J.T. Conklin + + * ace/Monitor_Control/BSD_Network_Interface_Monitor.cpp: + + Explicitly #include and for non-inline + builds. + +Wed Jun 18 17:36:34 UTC 2008 Yan Dai + + * ace/Stack_Trace.cpp: + + Moved pragma disable warning directives from inside of function to + outside to take effect. + +Wed Jun 18 17:27:51 2008 Steve Huston + + * ace/CDR_Stream.h: Some doxygen improvements. + +Wed Jun 18 15:36:11 UTC 2008 Phil Mesnier + + * bin/tao_orb_tests.lst: + + Added new run_test scripts for the special variants of the TAO + POA EndpointPolicy test. + +Wed Jun 18 13:20:00 UTC 2008 Simon Massey + + * bin/fuzz.pl: + + Redo check for wide character incompatabilty ORB_init() miss-use. + Caters for multi-line ORB_init. + +Wed Jun 18 12:16:48 UTC 2008 Chad Elliott + + * bin/PerlACE/Run_Test.pm: + + Increase the process start wait time for QNX. + +Wed Jun 18 10:43:20 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_linux_icc.GNU: + Don't use deprecated options + +Wed Jun 18 09:50:20 UTC 2008 Johnny Willemsen + + * README: + * ACE-INSTALL.html: + Updated + +Tue Jun 17 22:43:20 2008 Steve Huston + + * ace/Reactor.h: Clarify that calling remove_handler() for a signal + handler does not invoke the handler's handle_close() callback. Also + note that this behavior is under debate in Bugzilla #2368. Thanks to + Bill Kendall for calling this to attention. + + * THANKS: Added Bill Kendall. + +Tue Jun 17 15:36:49 UTC 2008 Yan Dai + + * ace/Stack_Trace.cpp: + + Disabled warning C4706 in load_dbghelp_library_if_needed() + and enabled afterwards on windows. + +Tue Jun 17 13:55:00 UTC 2008 Simon Massey + + * bin/fuzz.pl: + + Add check for wide character incompatabilty ORB_init() miss-use. + +Tue Jun 17 12:40:03 UTC 2008 J.T. Conklin + + * ace/Monitor_Control/BSD_Network_Interface_Monitor.cpp: + + Explicitly #include for non-inline builds. + +Tue Jun 17 09:30:00 UTC 2008 Simon Massey + + * apps/JAWS/clients/WebSTONE/src/bench.c: + * apps/JAWS/clients/WebSTONE/src/errexit.c: + * apps/JAWS/clients/WebSTONE/src/genrand.c: + * apps/JAWS/clients/WebSTONE/src/timefunc.c: + * apps/JAWS/clients/WebSTONE/src/webclient.c: + * apps/JAWS/clients/WebSTONE/src/webmaster.c: + + Fuzz errors, Untabify. + +Tue Jun 17 08:13:00 UTC 2008 Simon Massey + + * include/make_include/platform_sunos5_common.GNU: + + Changed default "kstat ?= 1" at Johnny Willemsens request. + +Tue Jun 17 06:42:51 UTC 2008 Yan Dai + + * ace/Stack_Trace.cpp: + + Fixed declared method (determine_starting_frame) never referenced + warning on HP aCC build. + +Mon Jun 16 21:26:05 UTC 2008 Abdullah Sowayan + + * bin/fuzz.pl: + + Enable check_for_tab for all files in the repository. + +Mon Jun 16 21:22:03 UTC 2008 Abdullah Sowayan + + * apps/JAWS/clients/Caching/Local_Locator.cpp: + * apps/JAWS/clients/WebSTONE/src/bench.c: + * apps/JAWS/clients/WebSTONE/src/errexit.c: + * apps/JAWS/clients/WebSTONE/src/genrand.c: + * apps/JAWS/clients/WebSTONE/src/get.c: + * apps/JAWS/clients/WebSTONE/src/gettimeofday.c: + * apps/JAWS/clients/WebSTONE/src/parse_file_list.c: + * apps/JAWS/clients/WebSTONE/src/rexec.c: + * apps/JAWS/clients/WebSTONE/src/statistics.c: + * apps/JAWS/clients/WebSTONE/src/sysdep.c: + * apps/JAWS/clients/WebSTONE/src/timefunc.c: + * apps/drwho/Hash_Table.cpp: + + Untabify. + +Mon Jun 16 20:24:45 UTC 2008 Abdullah Sowayan + + * apps/Gateway/Gateway/Connection_Handler.cpp: + * apps/Gateway/Gateway/Event_Forwarding_Discriminator.cpp: + * apps/Gateway/Peer/Options.cpp: + * apps/JAWS/clients/Blobby/Options.cpp: + * apps/JAWS/clients/Blobby/blobby.cpp: + * apps/JAWS/clients/Caching/ID_Generator.cpp: + * apps/JAWS/clients/Caching/Local_Locator.cpp: + * apps/JAWS/clients/Caching/Locator_Request_Reply.cpp: + * apps/JAWS/clients/Caching/URL_Properties.inl: + * apps/JAWS/clients/WebSTONE/src/bench.c: + * apps/JAWS/clients/WebSTONE/src/cgi-send.c: + * apps/JAWS/clients/WebSTONE/src/get.c: + * apps/JAWS/clients/WebSTONE/src/getopt.c: + * apps/JAWS/clients/WebSTONE/src/nsapi-send.c: + * apps/JAWS/server/HTTP_Config.cpp: + * apps/JAWS/server/HTTP_Handler.cpp: + * apps/JAWS/server/HTTP_Helpers.cpp: + * apps/JAWS/server/HTTP_Response.cpp: + * apps/JAWS/server/HTTP_Server.h: + * apps/JAWS/server/HTTP_Server.cpp: + * apps/JAWS/stress_testing/benchd.cpp: + * apps/JAWS/stress_testing/connection.cpp: + * apps/JAWS/stress_testing/http_tester.cpp: + * apps/JAWS2/JAWS/Cache_Hash_T.h: + * apps/JAWS2/JAWS/Hash_Bucket_T.h: + * apps/drwho/File_Manager.cpp: + * apps/drwho/Hash_Table.cpp: + * apps/drwho/PMC_All.cpp: + * apps/drwho/PMC_Flo.cpp: + * apps/drwho/PMC_Ruser.cpp: + * apps/drwho/PMC_Usr.cpp: + * apps/drwho/PMS_Ruser.cpp: + * apps/drwho/PM_Client.cpp: + * apps/drwho/Rwho_DB_Manager.cpp: + * apps/gperf/src/Gen_Perf.cpp: + + Untabify. + +Mon Jun 16 19:06:38 UTC 2008 William R. Otte + + * ace/config-borland-common.h: + * ace/config-hpux-11.00.h: + * ace/config-mvs.h: + * ace/config-win32-dmc.h: + * ace/config-win32-ghs.h: + * ace/config-win32-msvc.h: + + Fixes for MCPP preprocessing on Windows. + +Mon Jun 16 19:06:44 UTC 2008 Chad Elliott + + * ace/Acceptor.cpp: + * ace/Connector.cpp: + * ace/Strategies_T.cpp: + + Use the NORMAL_CLOSE_OPERATION enum value when closing the service + handler during activation. + +Mon Jun 16 18:33:34 UTC 2008 Abdullah Sowayan + + * examples/ASX/UPIPE_Event_Server/Peer_Router.cpp: + * examples/OS/Process/imore.cpp: + * examples/Reactor/Proactor/test_proactor3.cpp: + * examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.cpp: + + Untabify. + +Mon Jun 16 18:00:26 UTC 2008 Abdullah Sowayan + + * ASNMP/examples/get/get.cpp: + * ASNMP/examples/get/get_async.cpp: + * ASNMP/examples/next/next.cpp: + * ASNMP/examples/set/set.cpp: + + Untabify. + +Mon Jun 16 17:53:00 UTC 2008 Abdullah Sowayan + + * examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp: + * examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp: + * examples/IPC_SAP/TLI_SAP/db-client.cpp: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFC.h: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFCDlg.h: + * examples/Log_Msg/Log_Msg_MFC/StdAfx.h: + * examples/Log_Msg/Log_Msg_MFC/StdAfx.cpp: + * examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.inl: + + Untabify. + +Mon Jun 16 17:27:36 UTC 2008 Chad Elliott + + * bin/PerlACE/TargetProcess.pm: + + Remove the "use" of PerlACE::ProcessVX. It is already used in + PerlACE::Process and using it in this module causes things to be + evaluated incorrectly with respect to @ARGV. + +Mon Jun 16 17:01:19 UTC 2008 Abdullah Sowayan + + * bin/fuzz.pl: + + Enable check_for_tab check for ACE_ROOT/examples + +Mon Jun 16 16:54:25 UTC 2008 Abdullah Sowayan + + * examples/APG/Logging/Callback-2.h: + * examples/APG/Logging/Callback-3.h: + * examples/APG/Logging/Use_Logger.cpp: + * examples/APG/Threads/Message_Queue.cpp: + * examples/APG/Timers/CB.h: + * examples/APG/Timers/PCB.cpp: + * examples/ASX/CCM_App/SC_Server.cpp: + * examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp: + * examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp: + * examples/ASX/Event_Server/Event_Server/Peer_Router.cpp: + * examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp: + * examples/ASX/Message_Queue/bounded_buffer.cpp: + * examples/ASX/Message_Queue/priority_buffer.cpp: + * examples/ASX/UPIPE_Event_Server/Peer_Router.cpp: + * examples/Bounded_Packet_Relay/BPR_Drivers.cpp: + * examples/Bounded_Packet_Relay/Thread_Bounded_Packet_Relay.cpp: + * examples/Bounded_Packet_Relay/bpr_thread.cpp: + * examples/C++NPv2/display_logfile.cpp: + * examples/Connection/misc/Connection_Handler.h: + * examples/IPC_SAP/ATM_SAP/CPP-client.cpp: + * examples/IPC_SAP/ATM_SAP/CPP-server.cpp: + * examples/IPC_SAP/DEV_SAP/writer/writer.cpp: + * examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp: + * examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp: + * examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp: + * examples/IPC_SAP/FILE_SAP/client.cpp: + * examples/IPC_SAP/SOCK_SAP/C-inclient.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp: + * examples/IPC_SAP/SPIPE_SAP/NPServer.cpp: + * examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp: + * examples/IPC_SAP/TLI_SAP/CPP-ATM-client.cpp: + * examples/IPC_SAP/TLI_SAP/CPP-ATM-server.cpp: + * examples/IPC_SAP/TLI_SAP/CPP-client.cpp: + * examples/IPC_SAP/TLI_SAP/CPP-server.cpp: + * examples/IPC_SAP/TLI_SAP/db-client.cpp: + * examples/IPC_SAP/TLI_SAP/ftp-client.cpp: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFC.h: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFC.cpp: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFCDlg.h: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFCDlg.cpp: + * examples/Logger/Acceptor-server/server_loggerd.h: + * examples/Logger/Acceptor-server/server_loggerd.cpp: + * examples/Logger/simple-server/Logging_Handler.cpp: + * examples/Logger/simple-server/server_loggerd.cpp: + * examples/Mem_Map/IO-tests/test_io.cpp: + * examples/Misc/test_get_opt.cpp: + * examples/Misc/test_profile_timer.cpp: + * examples/OS/Process/imore.cpp: + * examples/QOS/Change_Receiver_FlowSpec/Receiver_QoS_Event_Handler.cpp: + * examples/Reactor/FIFO/client.cpp: + * examples/Reactor/FIFO/server.cpp: + * examples/Reactor/Misc/notification.cpp: + * examples/Reactor/Misc/test_signals_1.cpp: + * examples/Reactor/Misc/test_signals_2.cpp: + * examples/Reactor/Ntalker/ntalker.cpp: + * examples/Reactor/Proactor/test_cancel.h: + * examples/Reactor/Proactor/test_cancel.cpp: + * examples/Reactor/Proactor/test_multiple_loops.cpp: + * examples/Reactor/Proactor/test_proactor3.cpp: + * examples/Reactor/Proactor/test_timeout.cpp: + * examples/Reactor/Proactor/test_timeout_st.cpp: + * examples/Registry/test_registry_update.cpp: + * examples/Service_Configurator/IPC-tests/client/broadcast_client_test.cpp: + * examples/Service_Configurator/IPC-tests/client/local_dgram_client_test.cpp: + * examples/Service_Configurator/IPC-tests/client/local_pipe_client_test.cpp: + * examples/Service_Configurator/IPC-tests/client/local_stream_client_test.cpp: + * examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.inl: + * examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp: + * examples/Service_Configurator/Misc/Timer_Service.cpp: + * examples/Shared_Memory/test_SV.cpp: + * examples/System_V_IPC/SV_Message_Queues/TMQ_Client.cpp: + * examples/Threads/recursive_mutex.cpp: + * examples/Threads/task_one.cpp: + * examples/Threads/thread_manager.cpp: + * examples/Threads/token.cpp: + + Untabify. + +Mon Jun 16 16:04:40 2008 Steve Huston + + * bin/PerlACE/TestTarget.pm: When getting the exe subdir for a + target, pick up the command line setting if the "default" target + is in use. This should fix the broken exesubdir TAO builds. + +Mon Jun 16 15:45:45 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Null_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/Null_Network_Interface_Monitor.h: + + New files, defining a base class for tne network interface OS + monitors when the monitor framework itself is enabled but no + platform-specific OS monitor flags are defined, whether because + the platform itself does not support native system-level + monitoring, or because the Linux, Windows or Solaris OS + monitor flags has been turned off for some reason. + + * ace/Monitor_Control/Monitor_Control.mpc: + * ace/Monitor_Control/Bytes_Sent_Monitor.h: + * ace/Monitor_Control/Packets_Sent_Monitor.h: + * ace/Monitor_Control/Linux_Network_Interface_Monitor.h: + * ace/Monitor_Control/Bytes_Received_Monitor.h: + * ace/Monitor_Control/Packets_Received_Monitor.h: + + Incorporated the new no-op network interface monitor base class + into the existing network interface monitor classes. If this + new base class is used, the monitor's value will always be 0, + and its update() method will be a no-op. + +Mon Jun 16 12:12:16 UTC 2008 Jeff Parsons + + * ace/config-sunos5.5.h: + + Reverted addition of ACE_HAS_KSTAT flag in + + Fri Jun 13 14:00:00 UTC 2008 Jeff Parsons + + Thanks to Johnny Willemsen , we now + know that the correct way to do this is to set kstat=1 + in platform_macros.GNU. + +Mon Jun 16 11:28:11 UTC 2008 Abdullah Sowayan + + * bin/fuzz.pl: + + Enable check_for_tab check for TAO/tests/examples and TAO/performance-tests + +Mon Jun 16 10:30:00 UTC 2008 Simon Massey + + * tests/Max_Default_Port_Test.cpp: + + Un-tabify. + +Mon Jun 16 10:20:00 UTC 2008 Simon Massey + + * ace/Monitor_Control/BSD_Network_Interface_Moinitor.cpp: + + Correct Fuzz errors (removed NULL). + +Mon Jun 16 01:01:27 UTC 2008 Abdullah Sowayan + + * bin/fuzz.pl: + + Enable check_for_tab check for TAO/tests + +Sun Jun 15 16:03:29 UTC 2008 Abdullah Sowayan + + * bin/fuzz.pl: + + Enable check_for_tab check for TAO/orbsvcs + +Sun Jun 15 13:23:13 UTC 2008 Johnny Willemsen + + * ace/config-linux-common.h: + Added ACE_LACKS_STRRECVFD when no streams are available (like fc9) + + * rpmbuild/ace-tao-strrecvfd.patch: + Deleted + + * rpmbuild/ace-tao.spec: + Patch 6 is not needed anymore + + * ace/Strategies_T.h: + Doxygen change + +Sun Jun 15 03:08:53 UTC 2008 J.T. Conklin + + * ace/Monitor_Control/Monitor_Control.mpc: + + Add BSD_Network_Interface_Monitor.cpp to Source_Files section. + +Fri Jun 13 14:50:28 UTC 2008 Simon Massey + + Add BSD_Network_Interface_Monitor.cpp and + + untab-ified to remove fuzz errors. + +Fri Jun 13 14:45:28 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Windows_Multi_Instance_Monitor.cpp: + + Removed unused local variable. + +Fri Jun 13 14:31:35 UTC 2008 Adam Mitz + + * ace/Stack_Trace.cpp (Solaris section): + + Yesterday's addition of support for 64-bit SPARC broke on x86. + +Fri Jun 13 14:00:00 UTC 2008 Jeff Parsons + + * ace/config-sunos5.5.h: + + Added #define of ACE_HAS_KSTAT, used by the OS monitors in + ace/Monitor_Control on Solaris platforms to guard the + visibility of Solaris-specific code and base classes. + +Fri Jun 13 13:40:39 UTC 2008 J.T. Conklin + + * ace/Monitor_Control/Makefile.am: + + Add BSD_Network_Interface_Monitor.cpp and + Solaris_Network_Interface_Monitor.cpp to Headers_File section. + + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Bytes_Received_Monitor.h: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.h: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.h: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.h: + + Inherit from BSD_Network_Interface_Monitor on FreeBSD, + NetBSD, and OpenBSD systems. + + * ace/Monitor_Control/BSD_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/BSD_Network_Interface_Monitor.h: + + New files, network interface monitor for systems with 4.4BSD + derived network stack. + +Fri Jun 13 13:24:11 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Linux_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.h: + * ace/Monitor_Control/Packets_Sent_Monitor.h: + * ace/Monitor_Control/Linux_Network_Interface_Monitor.h: + * ace/Monitor_Control/Bytes_Received_Monitor.h: + * ace/Monitor_Control/Packets_Received_Monitor.h: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + Added '|| defined (AIX)' to every occurrence of + '#if defined (linux)' to eliminate build errors on the + latter platform. + +Thu Jun 12 21:57:33 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + * configure.ac: + + Remove feature test for ACE_HAS_TEMPLATE_SPECIALIZATION. + + * ace/config-borland-common.h: + * ace/config-cray.h: + * ace/config-cxx-common.h: + * ace/config-g++-common.h: + * ace/config-hpux-11.00.h: + * ace/config-icc-common.h: + * ace/config-integritySCA.h: + * ace/config-irix6.x-sgic++.h: + * ace/config-mvs.h: + * ace/config-openvms.h: + * ace/config-suncc-common.h: + * ace/config-sunos5.4-sunc++-4.x.h: + * ace/config-sunos5.5.h: + * ace/config-sunos5.6.h: + * ace/config-tandem-nsk-mips-v2.h: + * ace/config-tandem-nsk-mips-v3.h: + * ace/config-tru64.h: + * ace/config-unixware-7.1.0.udk.h: + * ace/config-win32-dmc.h: + * ace/config-win32-ghs.h: + * ace/config-win32-msvc-8.h: + * ace/config-win32-msvc-9.h: + * ace/config-win32-msvc-7.h: + + Remove unused #define of ACE_HAS_TEMPLATE_SPECIALIZATION. This + feature test macro is no longer used. + +Thu Jun 12 18:47:54 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Solaris_Network_Interface_Monitor.h: + * ace/Monitor_Control/Solaris_Network_Interface_Monitor.cpp: + + New files, containing a base class used with + Bytes_Received_Monitor, Bytes_Sent_Monitor, + Packets_Received_Monitor and Packets_Sent_Monitor + when they are compiled on Solaris platforms. + + * ace/Monitor_Control/Windows_Multi_Instance_Monitor.cpp: + * ace/Monitor_Control/Linux_Network_Interface_Monitor.cpp: + * ace/Monitor_Control/CPU_Load_Monitor.h: + * ace/Monitor_Control/Bytes_Received_Monitor.cpp: + * ace/Monitor_Control/Windows_Monitor.h: + * ace/Monitor_Control/Packets_Received_Monitor.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.h: + * ace/Monitor_Control/Monitor_Control.mpc: + * ace/Monitor_Control/Num_Threads_Monitor.h: + * ace/Monitor_Control/Bytes_Sent_Monitor.h: + * ace/Monitor_Control/CPU_Load_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.h: + * ace/Monitor_Control/Windows_Monitor.cpp: + * ace/Monitor_Control/Memory_Usage_Monitor.cpp: + * ace/Monitor_Control/Linux_Network_Interface_Monitor.h: + * ace/Monitor_Control/Windows_Multi_Instance_Monitor.h: + * ace/Monitor_Control/Bytes_Received_Monitor.h: + * ace/Monitor_Control/Packets_Received_Monitor.h: + * ace/Monitor_Control/Num_Threads_Monitor.cpp: + * ace/Monitor_Control/Bytes_Sent_Monitor.cpp: + * ace/Monitor_Control/Packets_Sent_Monitor.cpp: + + - Changed required to complete the support of + network interface monitors on Solaris. + + - Changed guards for Windows-specific header file + inclusion to use the recently added ACE_HAS_PDH_H, + which in turn guards the definition of the + ACE_HAS_WIN32_PDH flag used in source code. + + - Changed the names of the platform-specific monitor + update methods to update_i(), from the distinct + names they had before. This changed allowed the + elimination of many #ifdef guards in source code. + +Thu Jun 12 17:42:47 UTC 2008 Steve Huston + + * bin/PerlACE/Process.pm: + * bin/PerlACE/Process_Win32.pm: Moved the Target sub from Process_Win32 + to Process so everybody can see it. Thanks to Chad Elliott for + finding and suggesting the correction for it. + +Thu Jun 12 16:04:33 UTC 2008 Steve Huston + + * bin/tao_orb_tests.lst: Disabled newly added tests on LabVIEW_RT. + + * bin/PerlACE/README: Describes how the ACE+TAO test procedures work. + Includes a description of how to drive the generalized ability to + redirect execution of tests off of the build host. + + * bin/PerlACE/TestTarget.pm: + * bin/PerlACE/TestTarget_LVRT.pm: + * bin/PerlACE/ProcessLVRT.pm: + * bin/PerlACE/Process_Win32.pm: Add the ability to configure various + aspects of ACE+TAO (+CIAO I guess, but haven't tried that) to run + on machines other than the build host and with alternate roots + (ACE_ROOT, TAO_ROOT). This is an effort to generalize the ability + to run off of the build host without adding more switches and options + and convoluted settings and platform-specific code in the main + scripts. The README file explains how to set up modules to extend + testing to other platforms. LabVIEW_RT is the only one there now; + VxWorks is an obvious addition and would allow a bunch of special-case + code to be removed from the main scripts. The test-driving script + does require some change to take advantage of this capability. ACE + tests in ACE_wrappers/tests have the change. A few TAO tests do + (see TAO ChangeLog). Without the changes to the test-driving script + everything behaves as it always did. + + * tests/run_test.pl: Uses the new TestTarget capability, naming the + test target "ace". Thus, to redirect these tests to another machine, + set the DOC_TEST_ACE environment variable with a configuration name + and set configuration variables accordingly. + +Thu Jun 12 14:38:19 UTC 2008 Adam Mitz + + * ace/Stack_Trace.h: + * ace/Stack_Trace.cpp: + + Added support for SPARCv9 (64-bit). + Reverted the Win32 assembly back to the simplest form, we had tried + to make it compatible with Borland but it still didn't work. As of + now ACE compiled by Borland will not generate stack traces. + +Thu Jun 12 12:17:52 UTC 2008 Chad Elliott + + * ace/Stack_Trace.cpp: + + Corrected Win32 assembler compilation error. + +Wed Jun 11 16:24:00 UTC 2008 Phil Mesnier + + * bin/tao_orb_tests.lst: + + Added new test case. + +Wed Jun 11 13:55:00 UTC 2008 Simon Massey + + * ace/Time_Value.inl: + * ace/Time_Value.h: + + Add extra inline void msec(int) that calls void msec(long) + to avoid amiguity between void msec(long) and void msec(_int64 &) + when natual sized integers are given (which seems to be + quite often). + +Wed Jun 11 13:02:22 UTC 2008 Chad Elliott + + * bin/PerlACE/Run_Test.pm: + + Replaced the "use PerlACE::Process". It is necessary to be loaded + inside this module to ensure that all of the command line options + can be processed. + +Wed Jun 11 04:17:42 UTC 2008 J.T. Conklin + + * m4/platform.m4: + + Remove ACE_HAS_AIX_BROKEN_SOCKET_HEADER definitions. + +Wed Jun 11 03:51:32 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_CHARPTR_SPRINTF. This feature test macro is no longer + used. + +Wed Jun 11 03:39:48 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_LACKS_FLOATING_POINT. This feature test macro is no longer + used. + +Wed Jun 11 03:33:31 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_TYPENAME_KEYWORD. This feature test macro is no longer + used. + +Wed Jun 11 03:31:02 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_SPARCWORKS_401_SIGNALS. This feature test macro is no + longer used. + +Wed Jun 11 02:57:12 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for ACE_HAS_AIX_BROKEN_SOCKET_HEADER. + This feature test macro is no longer used. + +Wed Jun 11 02:52:16 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_SELECT_USES_INT. This feature test macro is no longer used. + +Wed Jun 11 02:48:07 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for HAVE_RESTARTABLE_SYSCALLS. + This feature test macro is no longer used. + +Wed Jun 11 00:17:01 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_IRIX_53_SIGNALS. This feature test macro is no longer + used. + +Tue Jun 10 23:57:53 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature tests and autoheader templates for + ACE_HAS_STD_TEMPLATE_SPECIALIZATION and + ACE_HAS_STD_TEMPLATE_CLASS_MEMBER_SPECIALIZATION. + These feature test macros are no longer used. + +Tue Jun 10 23:52:19 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_BROKEN_SAP_ANY. This feature test macro is no longer + used. + +Tue Jun 10 23:49:46 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for ACE_HAS_BROKEN_NESTED_TEMPLATES. + This feature test macro is no longer used. + +Tue Jun 10 23:47:46 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for ACE_HAS_SUNOS4_SIGNAL_T. + This feature test macro is no longer used. + +Tue Jun 10 23:45:34 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_BROKEN_CONDITIONAL_STRING_CAST. This feature test macro + is no longer used. + +Tue Jun 10 23:43:19 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_BROKEN_CONVERSIONS. This feature test macro is no + longer used. + +Tue Jun 10 23:41:11 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_BROKEN_NAMESPACES. This feature test macro is no longer + used. + +Tue Jun 10 23:39:09 UTC 2008 J.T. Conklin + + * m4/config_h.m4: + + Remove autoheader template for ACE_HAS_SYSCALL_GETRUSAGE. This + feature test macro is no longer used. + +Tue Jun 10 23:16:31 UTC 2008 J.T. Conklin + + * configure.ac: + * m4/config_h.m4: + + Remove feature test and autoheader template for + ACE_HAS_BROKEN_TIMESPEC_MEMBERS. This feature test macro is no + longer used. + +Tue Jun 10 21:28:23 UTC 2008 J.T. Conklin + + * m4/platform.m4: + + Add ACE_CHECK_GETNAME_RETURNS_RANDOM_SIN_ZERO feature check, + which sets the ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO feature test + macro on Linux systems running kernels older than 2.5.47. This + is a compile time check, like was done in config-linux-common.h, + based on the value of LINUX_VERSION_CODE from . + This means ACE compiled on a newer Linux system but deployed on + an older one could result in run-time failures. + + Fixes Bugzilla #3132. + +Tue Jun 10 21:33:25 UTC 2008 Jeff Parsons + + * ace/CDR_Stream.h: + * ace/CDR_Stream.cpp: + + Replaced a Monitor class forward declaration with the full file + include, moved from the source file to the header file. This + move enables ACE monitor points to compile when inlining is + turned on. + +Tue Jun 10 18:46:24 UTC 2008 Yan Dai + + * ace/Stack_Trace.h: + + Updated comments to not exclude Borland from supported platforms. + + * ace/Stack_Trace.cpp: + + - Moved the label "x" from inside of asm to be outside. Some compiler + does not like it. + - Enabled LynxOS support and excluded support for gcc old versions before 3.3. + +Tue Jun 10 13:56:17 UTC 2008 Adam Mitz + + * ace/Stack_Trace.cpp: + + One more fix for Win32 wchar. + +Tue Jun 10 13:32:57 UTC 2008 Chad Elliott + + * tests/Bug_2980_Regression_Test.cpp: + + Avoid pointer-to-function and pointer-to-object warnings from g++. + +Tue Jun 10 12:53:05 UTC 2008 Chad Elliott + + * tests/SSL/SSL_Asynch_Stream_Test.cpp: + + Modified to avoid virtual method hiding. + +Tue Jun 10 11:37:09 UTC 2008 Chad Elliott + + * tests/Time_Value_Test.cpp: + + Added a static cast to avoid warnings on QNX. + +Tue Jun 10 10:57:00 UTC 2008 Simon Massey + + * ace/ACE.cpp: + + Correct presidence bug highlighted by FC9_GCC_430 build: + ACE.cpp:1429: warning: suggest parentheses around && within || + ACE.cpp:1665: warning: suggest parentheses around && within || + ACE.cpp:1853: warning: suggest parentheses around && within || + The default precidence is && before ||, but the way the || + statements were grouped, it was clear that was not the intended + resolution. + + Correct empty if statement bug highlighted by FC9_GCC_430 build: + ACE.cpp:2773: warning: suggest braces around empty body in an 'if' statement + + Also removed warnings by using empty braces: + ACE.cpp:3389: warning: suggest a space before ';' or explicit braces around empty body in 'while' statement + ACE.cpp:3414: warning: suggest a space before ';' or explicit braces around empty body in 'while' statement + + +Mon Jun 9 21:38:04 UTC 2008 Yan Dai + + * ace/Stack_Trace.cpp: + + Passed string literals instead of ACE_TEXT string to GetProcAddress as it + accepts LPCSTR which is defined as char*. This should fix wchar (Win32) + build errors. + +Mon Jun 9 20:52:52 2008 Steve Huston + + * ace/Asynch_IO.h: Doxygen improvements. + +Mon Jun 9 19:40:56 UTC 2008 Yan Dai + + * ace/Stack_Trace.h: + * ace/Stack_Trace.cpp: + + Excluded LynxOS, MinGW and Borland builds from stack trace supported + platforms. + +Mon Jun 09 14:46:00 UTC 2008 Simon Massey + + * ace/Stack_Trace.cpp: + * ace/Stack_Trace.h: + + Remove TEXT() and TCHAR Fuzz errors. + +Mon Jun 9 11:26:36 UTC 2008 Chad Elliott + + * ace/ace_for_tao.mpc: + + Added Stack_Trace.cpp since Log_Msg.cpp needs it. + +Mon Jun 09 10:42:00 UTC 2008 Simon Massey + + * ace/NT_Service.cpp: + + unambiguated call to time_value msec(long) at line 437 + caused by new uint64 non-const setter provided by: + Thu Jun 5 14:52:43 UTC 2008 Steve Huston + +Sun Jun 8 18:09:22 UTC 2008 J.T. Conklin + + * m4/platform.m4: + + Add ACE_CHECK_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE feature + check, which sets the ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE + feature test macro on Linux and OpenBSD systems (as is done in + the canned config-*.h files). Fixes Bugzilla #3141. + +Sat Jun 7 13:56:56 UTC 2008 Chad Elliott + + * ace/Log_Msg.cpp: + + Use ACE_TEXT instead of ACE_LIB_TEXT. + +Sat Jun 7 03:28:01 UTC 2008 Yan Dai + + Merged in stack_trace_branch that added stack trace support. + + * NEWS: + + Add an entry for stack trace support. + + * ace/Log_Msg.h: + + Added comments for "%?". + + * ace/Log_Msg.cpp: + + Added new conversion character, the question mark, which gets + replaced by a stack trace on supported platforms. + + * ace/Stack_Trace.h: + * ace/Stack_Trace.cpp: + + Added new class that, on supported platforms, will take a + snapshot of the current stack when instantiated. + + * ace/ace.mpc: + + Added Stack_Trace in as source. + + * ace/config-macosx-leopard.h: + + Added ACE_HAS_EXECINFO_H define. + + * ace/Makefile.am: + + Added Stack_Trace.h and Stack_Trace.cpp. + + * configure.ac: + + Added checks for execinfo.h header. + + * tests/Stack_Trace_Test.cpp: + + New test. + + * tests/run_test.lst: + * tests/tests.mpc: + + Added Stack_Trace_Test in. + +Fri Jun 6 19:05:14 UTC 2008 Chad Elliott + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + + Put an eval around the require of Net::Telnet so that these + modules can always be "used", but not necessarily employed. + + * bin/PerlACE/Run_Test.pm: + + Use PerlACE::TargetProcess and PerlACE::HostProcess so that all + test scripts may use them. + + * bin/PerlACE/TargetProcess.pm: + * bin/PerlACE/HostProcess.pm: + + Added modules to simplify the writing of test scripts so that + VxWorks testing can be transparent to the script itself. Having + two packages allows for role reversal (using the -reverse_roles + option to run_test.pl). For example, if you have a test that + consists of a server and a client, the script will look like this: + + $SV = new PerlACE::TargetProcess("server", "-o $iorfile"); + $CL = new PerlACE::HostProcess("client", "-k file://$iorfile"); + + If testing for VxWorks, the server process will be run on the + target and the client process will be run on the host. If the + -reverse_roles option is provided to run_test.pl, the server + process will run on the host and the client process will run on + the target. + +Fri Jun 06 13:00:00 UTC 2008 Simon Massey + + * ace/ACE.cpp: + + untabified. + +Fri Jun 06 11:10:00 UTC 2008 Simon Massey + + * ace/ACE.cpp: + + Added #include ace/OS_NS_fcntl.h to previous commit of + Thu Jun 5 23:46:14 UTC 2008 J.T. Conklin. + +Fri Jun 6 08:31:06 UTC 2008 Vladimir Zykov + + * ace/config-hpux-11.00.h: + According to Steve Huston HP-UX does provide strtoull and + wcstoull but they can be used not as straight forward as + in other compilers. I have no access to HP-UX so I added + corresponding TODO comment about ACE_LACKS_STRTOULL and + ACE_LACKS_WCSTOULL that I added previously. + + * ace/config-vxworks6.2.h: + * ace/config-vxworks6.4.h: + * ace/config-vxworks5.x.h: + * ace/config-vxworks6.3.h: + VxWorks doesn't provide wcstoull as well. + Added ACE_LACKS_WCSTOULL. + +Thu Jun 5 23:46:14 UTC 2008 J.T. Conklin + + * ace/ACE.cpp: + + Changed daemonize() to open /dev/null and duplicate the file + descriptor as descriptors 0, 1, and 2 if it is invoked with the + closed_all_handles flag set. This avoids problems with I/O + to/from stdin, stdout, and stderr; cin, cout, and cerr; + etc. being written to/read from whatever files/sockets/devices + associated with descriptors 0, 1, and 2 when they are reopened. + This fixes Bugzilla #3338. + +Thu Jun 5 16:30:58 2008 Steve Huston + + * NEWS: Added note concerning ACE_Time_Value changes from + Thu Jun 5 14:52:43 UTC 2008 Steve Huston + +Tue Jun 3 13:09:27 UTC 2008 Douglas C. Schmidt + + * ace/OS_main.h (wmain): Added + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + ACE_END_VERSIONED_NAMESPACE_DECL + + to the ace_wmain_i macro. Thanks to June Fang for reporting this. + +Thu Jun 5 14:52:43 UTC 2008 Steve Huston + + * ace/Time_Value.{h inl}: Added a non-const variant of + void msec(ACE_UINT64&) - this allows the msec(ACE_UINT64&) accessor + to be called on both const and non-const objects without error. + Fixes Bugzilla #3336. Thanks to Simon Massey for this idea. + + * tests/Time_Value_Test.cpp: Added a const-checking msec() call and + corrected the test case. + +Thu Jun 05 13:45:00 UTC 2008 Simon Massey + + * ace/Get_Opt.cpp: + * ace/Get_Opt.h: + * ace/Get_Opt.inl: + + As a conveniance in wide character builds allow the + options string to be specified as a standard narrow + string (that is converted internally). This type of + use is littered throughout the TAO code. + + * ace/OS_NS_stdio.cpp: + * ace/OS_NS_stdio.h: + * ace/OS_NS_stdio.inl: + + As a conveniance in wide character builds allow the + fopen() call to have parameters of mixed wide/narrow + type. This type of use is littered throughout the TAO + code. + + * ace/OS_NS_stdlib.inl: + + Correct the mkstemp facades, they were not returning + the modified template string under wide character builds, + this caused the tao_idl compiler to be unable to find + the pre-processed files to rename that it had just created. + + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_MFC.mpc: + * examples/Log_Msg/Log_Msg_MFC/Log_Msg_Unicode_MFC.mpc: + + Deleted the Unicode specific version, normal one suffices + after all. + + * bin/tao_orb_tests.lst: + + Disabled problematic LynxOS test. + +Wed Jun 4 22:45:20 2008 Steve Huston + + * ace/config-pharlap.h: Added ACE_LACKS_FILELLOCKS. My changes from + Mon Apr 28 21:53:23 UTC 2008 Steve Huston + exposed a call to LockFileEx, which is not present on Pharlap + (and, therefore, not present in LabVIEW RT). The alternate API, + LockFile, is present on Pharlap but documented as unsupported. + Since the OS doesn't do multiple processes, there are more effective + ways to synchronize that file locks anyway. + +Wed Jun 4 20:59:16 UTC 2008 Ciju John + + * ace/SSL/SSL_Context.cpp: + Fix for Bug 3337. ::SSL_add_dir_cert_subjects_to_stack() isn't + ready for Windows. + +Wed Jun 4 17:12:10 UTC 2008 J.T. Conklin + + * ace/ACE.cpp (timestamp): + + Make sure to divide sizeof timebuf by sizeof (ACE_TCHAR) to + avoid buffer overflow. This is another instance of the same + problem fixed in: + + Mon Jun 2 15:26:57 UTC 2008 Douglas C. Schmidt + +Wed Jun 4 16:05:54 UTC 2008 Steve Huston + + * tests/Time_Value_Test.cpp: Added a test case for Bugzilla #3336 + as reported by Aaron Scamehorn. + +Wed Jun 4 14:36:55 UTC 2008 Jeff Parsons + + * ace/Monitor_Point_Registry.cpp: + * ace/Monitor_Base.cpp: + + Disabled warning messages reporting an unsuccessful unbind + of a monitor from the monitor point registry. In some + cases, it appears that the default process reactor singleton + is destroyed before the monitor point registry. The reactor + has an associated ACE_Message_Queue, which in turn has an + associated monitor. Somehow in the destruction of the + singleton, the normal chain of destructor calls, which + would remove the monitor from the registry, is bypassed, + leaving the removal to happen when the registry's + destructor is called and the entry in question is no longer + valid. In any case, this happens only at process shutdown, + and there is no memory leak. Ways to make this happen in + a more friendly fashion are being looked into. + +Tue Jun 3 16:14:39 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + * rpmbuild/ace-tao-unusedarg.patch: + * rpmbuild/ace-tao-strrecvfd.patch: + + Added ace-tao-strrecvfd.patch (related to bug #3291). + Changed make loop construct to abort when subcomponent fails. + Removed PSS from TAO build list. + Added ace-tao-unusedarg.patch (related to bug #3270). + Made qt3 BuildRequires conditional on Fedora version. + +Mon Jun 2 15:26:57 UTC 2008 Douglas C. Schmidt + + * ace/Log_Record.cpp (format_msg): Make sure to divide sizeof ctp + by sizeof (ACE_TCHAR) to avoid buffer overflow. Thanks to June + Fang for reporting this. + +Sun Jun 1 02:01:38 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + * rpmbuild/ace-tao-etc.tar.gz: + * rpmbuild/ace-tao-orbsvcs-daemon.patch: + + Added ace-tao-orbsvcs-daemon.patch to workaround + daemonization problems in rpm installed services. + Fixed tao-cosconcurrency command line arguments. + +Fri May 30 13:57:06 UTC 2008 Vladimir Zykov + + * ace/config-vxworks6.2.h: + * ace/config-vxworks6.4.h: + * ace/config-vxworks5.x.h: + * ace/config-vxworks6.3.h: + VxWorks doesn't provide strtoull(). + +Fri May 30 13:48:48 UTC 2008 Vladimir Zykov + + * ace/config-openvms.h: + OpenVMS doesn't provide wcstoull() function. + +Fri May 30 13:37:13 UTC 2008 Vladimir Zykov + + * ace/OS_NS_stdlib.inl: + Fixed MinGW builds. + + * ace/config-cygwin32.h: + Disabled wcstoull() on cygwin since it doesn't provide + such function. + +Fri May 30 13:17:55 UTC 2008 Simon Massey + + * test/INET_Addr_Test_IPV6.cpp: + Resolve Conflict #define INTERFACE with MFC under VC8. + +Fri May 30 10:07:55 UTC 2008 Vladimir Zykov + + * ace/config-win32-borland.h: + Borland compilers doesn't provide strtoull() and wcstoull(). + + * ace/config-sunos5.5.h: + * ace/config-sunos5.10.h: + wcstoull() didn't exist on Solaris until version 10. + + * ace/config-hpux-11.00.h: + HP-UX doesn't provide strtoull() and wcstoull(). + +Thu May 29 16:08:01 UTC 2008 Vladimir Zykov + + * ace/OS_NS_stdlib.cpp: + * ace/OS_NS_stdlib.inl: + * ace/OS_NS_stdlib.h: + + Added strtoull() function to ACE_OS. + + * configure.ac: + + Added a check for presence of strtoull() and wcstoull() + in the build environment. + +Thu May 29 15:15:00 UTC 2008 Simon Massey + + * ace/INET_Addr.cpp: + + Remove tabs to avoid fuzz warning. + +Thu May 29 10:15:00 UTC 2008 Simon Massey + + * tests/Bug_3332_Regression_Test.cpp: + + Remove signed/unsigned comparison warnings. + +Wed May 28 18:13:15 UTC 2008 J.T. Conklin + + * ace/INET_Addr.cpp: + * ace/INET_Addr.h: + + Changed ACE_INET_Addr::get_host_addr(char *, int) to be thread + safe by calling ACE_OS::inet_ntop() instead of + ACE_OS::inet_ntoa(). + + Changed ACE_INET_Addr::get_host_addr(void) to call + INET_Addr::get_host_addr(char *, size) with a static buffer. + + Removed the special cases for VxWorks in both of the above + methods which called inet_ntoa_b() which, according to comments, + was for efficency and thread safety. These are are now as + efficent and thread safe (or not, in the case of ACE_INET_Addr:: + get_host_addr(void)) as any other target platform, but no longer + need a string buffer member in every ACE_INET_Addr instance. + +Wed May 28 13:46:00 UTC 2008 Simon Massey + + * ace/Malloc.h: + Eliminate a warning from some fanicaly builds. + +Wed May 28 08:10:00 UTC 2008 Simon Massey + + * tests/Bug_3332_Regression_Test.cpp: + * tests/Bug_3332_Regression_Test.txt: + * tests/run_test.lst: + * tests/tests.mpc: + + Regression test for the change of: + Fri May 23 12:45:00 UTC 2008 * ace/RB_Tree.cpp. + +Tue May 27 23:10:33 UTC 2008 J.T. Conklin + + * ace/Makefile.am: + + Adding missing template and header files. + +Tue May 27 12:11:07 UTC 2008 Chad Elliott + + * ace/ace.mpc: + + Added missing template and header files. + +Mon May 26 13:54:38 UTC 2008 Olli Savia + + * ace/config-lynxos.h: + Defined ACE_LACKS_POLL_H. + +Mon May 26 07:28:23 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + Clarified the tao-cosevent and tao-rtevent "Summary" tags. + +Mon May 26 00:31:51 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + Fixed rpm build error: bad tar extraction command. + +Sun May 25 17:18:20 UTC 2008 Adam Mitz + + * ace/ace.mwc: + + s/MonitorControl/Monitor_Control/ + +Sun May 25 04:11:37 UTC 2008 Ken Sedgwick + + * rpmbuild/ace-tao.spec: + * rpmbuild/ace-tao-rnq.patch: + * rpmbuild/ace-tao-config-tmplvis.patch: + * rpmbuild/ace-tao-hasicmp.patch: + * rpmbuild/ace-tao-obstack.patch: + * rpmbuild/ace-tao-config-ipv6.patch: + Removed ace-tao-obstack.patch, no longer needed. + Converted ace-tao-config-ipv6.patch into conditional rpm script. + Converted ace-tao-rnq.patch into conditional rpm script. + Converted ace-tao-config-tmplvis.patch and ace-tao-hasicmp.patch + into rpm script. + +Sat May 24 19:50:46 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/modules/AutomakeWorkspaceHelper.pm: + + Adjust libpaths now that ACE_MonitorControl library has been + renamed to just ACE_Monitor_Control. + +Fri May 23 14:20:48 UTC 2008 J.T. Conklin + + * m4/platform.m4: + + Added *mingw64* case in ACE_SET_PLATFORM_MACROS and + ACE_CHECK_FORMAT_SPECIFIERS feature test macros. + +Fri May 23 12:45:00 UTC 2008 Simon Massey + + * ace/RB_Tree.cpp: + + Enhancement to stop external pointers to retained items being + invalidated upon key deletion. + +Fri May 23 12:14:54 UTC 2008 Jeff Parsons + + * ace/Monitor_Control/Auto_Update_Starter.h: + + Updated filename (which was recently changed) in a comment. + Thanks to Simon Massey for + reporting the fuzz warning. + +Fri May 23 08:14:38 UTC 2008 Olli Savia + + * tests/run_test.lst: + + Run Bug_2980_Regression_Test on LynxOS. + +Fri May 23 00:18:24 UTC 2008 J.T. Conklin + + * ace/Makefile.am: + + Rename MonitorControl subdirectory to Monitor_Control, to + adapt to this change: + + Wed May 21 19:01:10 UTC 2008 Jeff Parsons + +Thu May 22 23:04:38 UTC 2008 J.T. Conklin + + * configure.ac: + + Rename MonitorControl subdirectory to Monitor_Control, to + adapt to this change: + + Wed May 21 19:01:10 UTC 2008 Jeff Parsons + +Thu May 22 19:29:35 UTC 2008 Jeff Parsons + + * ace/Monitor_Base.h (clear): + + Made the method virtual, since it's overridden in the + TAO Notification Service monitors and we are now using + the ACE monitor registry which stores everyhing as the + ACE base class monitor. + +Thu May 22 14:56:10 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Added support for ACE_RUN_VX_EXE_SUBDIR which can be used when + the vxworks executables are build in a subdirectory + +Thu May 22 09:47:10 UTC 2008 Johnny Willemsen + + * rpmbuild/ace-tao-codeset.patch: + * ace/Codeset_Registry_db.cpp: + Merged patch into the regular registry + + * ace/OS_NS_sys_uio.cpp: + Const change + + * ace/Service_Config.cpp: + Layout change + + * rpmbuild/ace-tao.spec: + Removed codeset patch + +Thu May 22 09:37:10 UTC 2008 Johnny Willemsen + + * rpmbuild/* + New directory with files needed to create rpm's for ACE/TAO. + These files will be improved and we will check whether the + rpm patches can be integrated into the real config files. + Thanks to Ken Sedgwick for + delivering these files. + +Wed May 21 19:01:10 UTC 2008 Jeff Parsons + + * ace/MonitorControl/*: + + Changed directory name to Monitor_Control and renamed all + contained files, classes, libs, MPC projects, ifdef guards, + and macros similarly, to better conform to the ACE style. + + * ace/Monitor_Point_Registry.cpp: + * ace/Monitor_Admin.h: + * ace/Monitor_Admin.cpp: + * bin/MakeProjectCreator/config/ace_mc.mpb: + * examples/Monitor/Bytes_Sent/bytes_sent.cpp: + * examples/Monitor/Bytes_Sent/Makefile.am: + * examples/Monitor/Message_Queue_Size/message_queue_size.cpp: + * examples/Monitor/Message_Queue_Size/Makefile.am: + * examples/Monitor/Constraint/constraint.cpp: + * examples/Monitor/Constraint/Makefile.am: + * examples/Monitor/CPU_Load/cpu_load.cpp: + * examples/Monitor/CPU_Load/Makefile.am: + * examples/Monitor/Num_Threads/Makefile.am: + * examples/Monitor/Num_Threads/num_threads.cpp: + * examples/Monitor/Group/Makefile.am: + * examples/Monitor/Group/group.cpp: + * examples/Monitor/Memory_Usage/Makefile.am: + * examples/Monitor/Memory_Usage/memory_usage.cpp: + + Changes corresponding to the renaming above. + +Wed May 21 14:06:13 UTC 2008 Jeff Parsons + + * ace/Monitor_Base.h: + * ace/Monitor_Base.cpp: + + Made the update() method non pure virtual. + +Tue May 20 19:33:29 UTC 2008 Jeff Parsons + + * ace/Message_Queue_T.cpp: + + Added the stringified process id to the construction of + the message queue size monitor's name, since some tests + were showing that message queues were being created with + the same hex address in different processes. + +Tue May 20 17:55:39 UTC 2008 Chad Elliott + + * ace/Svc_Handler.h: + + Added an enum to be used as flags parameter for close(). + + * ace/Acceptor.cpp: + * ace/Connector.cpp: + * ace/Strategies_T.cpp: + + Use the new enum during the call to close() on the service handler + to indicate the circumstances behind the closure. + + This is part of a set of commits for Bug 2935. + +Tue May 20 09:45:21 UTC 2008 Johnny Willemsen + + * ace/Ping_Socket.{h,cpp}: + Use bool + +Mon May 19 19:26:21 UTC 2008 Johnny Willemsen + + * tests/Log_Msg_Test.cpp: + On VxWorks/LynxOS we didn't test the buffer overflow, but we + shouldn't test this when ACE_LACKS_VSNPRINTF is defined + because it will then fail + +Mon May 19 19:13:21 UTC 2008 Johnny Willemsen + + * ace/Hash_Map_Manager_T.h: + Doxygen change + + * ace/Hash_Map_Manager_T.cpp (shared_find) + Set errno to ENOENT when the size is zero + +Mon May 19 19:08:21 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Added 2085 and 2243 + +Mon May 19 14:19:21 UTC 2008 Johnny Willemsen + + * docs/bczar/bczar.html: + Updated mailing lists + + * docs/Download.html: + * etc/index.html: + Updated for x.6.5 + + * ace/config-openvms.h: + Removed sock max of 64kb + +Mon May 19 02:53:21 CDT 2008 Johnny Willemsen + + * ACE version 5.6.5 released. + +Fri May 16 10:13:15 UTC 2008 Johnny Willemsen + + Reverted change below, causes problems in the builds + * include/makeinclude/platform_linux.GNU: + Only set DLD and LD when they are not set yet + +Fri May 16 07:50:15 UTC 2008 Johnny Willemsen + + * tests/Based_Pointer_Test.cpp: + Also define a public destructor to silence the gnu warning that + we only have private + +Fri May 16 07:49:15 UTC 2008 Johnny Willemsen + + * examples/Monitor/Num_Threads/num_threads.cpp: + Fixed compile errors when monitoring framework is disabled + +Fri May 16 07:41:15 UTC 2008 Johnny Willemsen + + * examples/APG/Streams/Answerer.cpp: + * examples/APG/Streams/EndTask.h: + Replaced EndTask with TheEndTask to resolve a name conflict + when using MinGW + +Fri May 16 07:18:15 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_linux.GNU: + * include/makeinclude/platform_linux_common.GNU: + Support lib64 paths to detect certain features. Thanks to Ken + Sedgwick for reporting this + + * include/makeinclude/platform_linux.GNU: + Only set DLD and LD when they are not set yet + +Thu May 15 14:00:15 UTC 2008 Johnny Willemsen + + * ace/Based_Pointer_T.{h,inl}: + * tests/Based_Pointer_Test.cpp: + Fixed bugzilla 3285, make it possible to use + ACE_Based_Pointer. Thanks to Thomas Brownridge + for reporting this. + +Thu May 15 12:36:42 UTC 2008 Phil Mesnier + + * ace/MMAP_Memory_Pool.cpp: + When using a default base address of 0x0 and otherwise wanting + a fixed address, a special flag was used to imply that after the + first address is selected the system in a call to ::mmap() + subsequent calls to ::mmap() reuse the selected base address + as a fixed address. This may cause problems with reloading + persistent data if the stored data contains pointers and the + system selected base address changes from run to run. + + * ace/config-linux-common.h: + The default base address for the x86-64 platform cannot be 0x0. + Doing so causes the system to choose an address which for some + unknown reason causes SEGV errors in Malloc_T. The linux-specific + mmap flag, MAP_32BIT, resolves those segv errors, but on x86-64 + using 0x0 as the default base address on subsequent runs cause + a different assigned base address to be selected. If the data + in the mapped memory contains pointers to mapped memory, those + are then wrong and cause SEGV crashs. By experimentation, it + seems the default base address for powerpc is appropriate for + x86-64. + +Thu May 15 10:19:15 UTC 2008 Johnny Willemsen + + * include/makeinclude/rules.lib.GNU: + Fixed OpenVMS specific part + +Thu May 15 10:17:15 UTC 2008 Johnny Willemsen + + * ace/Unbounded_Set_Ex.cpp: + Fixed bug in the insert method + + * ace/Unbounded_Set_Test.cpp: + Extended this test to reproduce the bug above and replaced all + ACE_ASSERTS with if checks + +Thu May 15 10:05:00 UTC 2008 Simon Massey + + * bin/msvc_mpc_auto_compile.pl: + Split orbsvcs out from ciao build. + +Thu May 15 07:09:15 UTC 2008 Johnny Willemsen + + * ace/ace.mpc: + Added config-win32-msvc9.h, thanks to for + reporting this + +Wed May 14 20:41:17 2008 Steve Huston + + * ace/Thread_Manager.h: Expanded the documentation, particularly for + spawn[_n]. + +Wed May 14 18:30:15 UTC 2008 Johnny Willemsen + + * ace/config-irix6.x-common.h: + * ace/config-linux-common.h: + * ace/config-sunos5.4-g++.h: + * ace/config-sunos5.4-sunc++-4.x.h: + * ace/config-sunos5.5.h: + * ace/config-tandem.h: + * ace/config-unixware-7.1.0.h: + * ace/config-unixware-7.1.0.udk.h: + * ace/MonitorControl/MemoryUsageMonitor.cpp: + * ace/MonitorControl/MemoryUsageMonitor.h: + * ace/OS.inl: + * ace/os_include/os_unistd.h: + * ace/os_include/sys/os_resource.h: + * ace/POSIX_Proactor.cpp: + * ace/configure.ac: + Seems we already had a ACE_HAS_SYSINFO but this is a different + method but with the same name as we use in the monitoring code. + Added ACE_HAS_SYS_SYSTEMINFO_H as new define, renamed the + linux define to ACE_HAS_LINUX_SYSINFO + +Wed May 14 18:14:15 UTC 2008 Johnny Willemsen + + * ace/ACE.cpp: + Layout changes + + * ace/config-vxworks5.x.h: + * ace/OS_NS_unistd.inl: + * ace/Sock_Connect.cpp: + Extended for VxWorks Medusa + + * ace/Logging_Strategy.cpp: + Initialise pointer with 0 + +Wed May 14 14:26:15 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxworks5.5.x.GNU: + Detect medusa pid/pcd/pne + +Wed May 14 12:34:15 UTC 2008 Johnny Willemsen + + * ace/os_include/os_pdhmsg.h: + New file + + * ace/config-win32-common.h: + Added ACE_HAS_PDHMSG_H + + * ace/config-win32-mingw.h: + * ace/config-WinCE.h: + Added ACE_LACKS_PDHMSG_H + + * ace/Makefile.am: + Added new file + + * ace/MonitorControl/WindowsMultiInstanceMonitor.cpp: + Use new os_pdhmsg.h + +Wed May 14 12:24:15 UTC 2008 Johnny Willemsen + + * ace/os_include/os_kstat.h: + * ace/os_include/sys/os_sysinfo.h: + New header files + + * ace/os_include/os_glob.h: + * ace/os_include/sys/os_statvfs.h: + Removed not needed includes + + * configure.ac: + Added check for sysinfo.h + + * ace/config-linux-common.h: + Added ACE_HAS_SYSINFO and ACE_HAS_SYSINFO_H + + * ace/Makefile.am: + Added new files + + * ace/MonitorControl/CPULoadMonitor.h: + * ace/MonitorControl/MemoryUsageMonitor.cpp: + * ace/MonitorControl/MemoryUsageMonitor.h: + Use the new defines and header files + +Wed May 14 10:41:15 UTC 2008 Johnny Willemsen + + * ace/*: + * examples/Monitor/*: + Renamed MonitorControl namespace to Monitor_Control to comply + to ACE coding guidelines + +Wed May 14 09:48:15 UTC 2008 Johnny Willemsen + + * tests/run_test.lst: + Enabled some more tests on vxworks + +Tue May 13 19:20:15 UTC 2008 Johnny Willemsen + + * bin/diff-builds.pl: + Updated for move of test stats + +Mon May 12 12:19:15 UTC 2008 Jeff Parsons + + * examples/Monitor/MC_Test_Utilities.h: + * examples/Monitor/Bytes_Sent/bytes_sent.cpp: + * examples/Monitor/Message_Queue_Size/message_queue_size.cpp: + * examples/Monitor/Constraint/constraint.cpp: + * examples/Monitor/CPU_Load/cpu_load.cpp: + * examples/Monitor/MC_Test_Utilities.cpp: + * examples/Monitor/Group/group.cpp: + * examples/Monitor/Memory_Usage/memory_usage.cpp: + + Added appropriate preprocessor guards to ensure a + successful build when ACE_HAS_MONITOR_FRAMEWORK is + defined as 0. + + * examples/Monitor/Message_Queue_Size/Message_Queue_Size.mpc: + + Removed outdated macro additions from project. + +Fri May 9 18:58:52 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Config.h: + * ace/Service_Config.inl: + * ace/Service_Config.cpp: + * ace/Service_Gestalt.cpp: + + Calling ACE_Service_Config::open() does not correctly initialize + the SC global state (process name, in particular but others + too). Fixing bug#3319. + +Fri May 9 17:58:21 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/modules/AutomakeWorkspaceHelper.pm: + + Revert changes of: + Thu May 8 22:13:24 UTC 2008 J.T. Conklin + + Now that ETCL Parser library has been renamed back to + ACE_ETCL_Parser. + +Fri May 9 17:55:39 UTC 2008 J.T. Conklin + + * examples/Monitor/Bytes_Sent/Makefile.am: + * examples/Monitor/Message_Queue_Size/Makefile.am: + * examples/Monitor/Constraint/Makefile.am: + * examples/Monitor/CPU_Load/Makefile.am: + * examples/Monitor/Num_Threads/Makefile.am: + * examples/Monitor/Group/Makefile.am: + * examples/Monitor/Memory_Usage/Makefile.am: + * ace/ETCL/Makefile.am: + * ace/MonitorControl/Makefile.am: + + Regenerated. + +Fri May 9 14:17:11 UTC 2008 William R. Otte + + * include/makeinclude/platform_macosx_icc.GNU: + + Support for ICC on Intel Macs. + +Fri May 9 12:04:15 UTC 2008 Johnny Willemsen + + * ace/config-all.h: + Added ACE_HAS_MONITOR_POINTS which currently is set to 0. We will + enable this in a few builds to test them in detail. This way the + user can decide to enable the monitor framework but not get the + ACE builtin monitor points + + * ace/CDR_Stream.cpp: + * ace/CDR_Stream.h: + * ace/CDR_Stream.inl: + * ace/Message_Queue_T.cpp: + * ace/Message_Queue_T.h: + Added monitor points + + * ace/Codeset_IBM1047.cpp: + Removed code to silence the hp compiler, this is not needed in other + files + +Fri May 9 11:44:59 UTC 2008 Jeff Parsons + + * bin/MakeProjectCreator/config/ace_etcl_parser.mpb: + + Changed the filename etcl_parser.mpb to the one + above, for consistency in the names of ACE-related + files. Also changed the corresponding library name + to ACE_ETCL_Parser. + + * ace/ETCL/ACE_ETCL_Parser.pc.in: + + Changed the name of ETCL_Parser.pc.in likewise. + Also changed the contents of this file accordingly. + + * ace/ETCL/ETCL.mpc: + * ace/MonitorControl/MonitorControl.mpc: + * bin/MakeProjectCreator/config/ace_mc.mpb: + + Changes corresponding to the name changes above. + +Thu May 8 23:03:15 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/config/ace_zlib.mpb: + + ACE-specific zlib base project that overrides library settings + in MPC's own zlib base project for the automake build. + +Thu May 8 22:13:24 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/modules/AutomakeWorkspaceHelper.pm: + + Adjust libpaths now that ACE_ETCL_Parser library has been + renamed to just ETCL_Parser. + +Thu May 8 22:07:40 UTC 2008 J.T. Conklin + + * ace/ETCL/Makefile.am: + + Regenerated. + + * ace/ETCL/ACE_ETCL.pc.in: + * ace/ETCL/ETCL_Parser.pc.in: + + New pkg-config template files. + + * ace/ETCL/ETCL.mpc: + + Add Pkgconfig_Files sections for ACE_ETCL and ETCL_Parser + projects. + +Thu May 8 21:06:29 UTC 2008 Jeff Parsons + + * ace/ETCL/ETCL_Constraint_Visitor.h: + * ace/ETCL/ETCL_Constraint_Visitor.cpp: + + Removed a no-op method mean to be overridden + in derived visitors, but then abandoned. + +Fri May 2 17:45:13 UTC 2008 Douglas C. Schmidt + + * docs/ACE-guidelines.html: Updated the style guide to discuss the + use of '_' vs intercaps. + +Thu May 8 10:51:29 UTC 2008 Steve Huston + + * include/makeinclude/platform_sunos5_g++.GNU: Ensure -pipe is not + inserted into CCFLAGS twice. Similar to earlier change from + Wed Jan 23 17:23:31 UTC 2008 Steve Huston + Fixes Bugzilla #3232. + +Thu May 8 08:06:10 UTC 2008 Johnny Willemsen + + * ace/ETCL/ETCL_l.cpp: + * ace/ETCL/ETCL_y.cpp: + Fixed casing of include + +Wed May 7 19:28:35 UTC 2008 Steve Huston + + * ace/Unbounded_Set.{h inl}: Replaced typedef BASE with base_type. + Avoids a BASE macro on AIX. + +Wed May 7 19:02:51 UTC 2008 Jeff Parsons + + * ace/ETCL/ETCL_include: + + Removed this directory. + + * ace/ETCL/etcl_parser_export.h: + + Relocated here from ace/ETCL/ETCL_include. + + * bin/MakeProjectCreator/config/etcl_parser.mpb: + + Renamed this file from ace_etcl_parser.mpb. + + * ace/ETCL/ETCL_l.cpp: + * ace/ETCL/ETCL.yy + * ace/ETCL/ETCL_Interpreter.cpp: + * ace/ETCL/ETCL.ll: + * ace/ETCL/ETCL_y.cpp: + * ace/ETCL/ETCL_Interpreter.h: + * ace/ETCL/ETCL.mpc: + * ace/MonitorControl/MonitorControl.mpc: + * bin/MakeProjectCreator/config/ace_mc.mpb: + + All changes in this checkin are to remove + unnecessary things as a result of making the + ETCL parser the only one used. The corresponding + parser in TAO is eliminated. + +Wed May 7 17:11:10 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_linux_icc.GNU: + Added ICC 11.0 + +Wed May 7 14:28:54 UTC 2008 Chad Elliott + + * bin/ChangeLogEditor/FileLocatorFactory.pm: + + Changed to detect Subversion before CVS. + +Wed May 7 14:12:10 UTC 2008 Johnny Willemsen + + * tests/Bug_3319_Regression_Test.cpp: + * tests/run_test.lst: + * tests/tests.mpc: + Added regression for bugzilla 3319 + +Wed May 7 10:52:10 UTC 2008 Johnny Willemsen + + * ace/Hash_Map_Manager_T.cpp: + Fixed GCC warning about maybe unitialised use and also + use prefix decrement and no need for some intermediate variables + +Wed May 7 08:42:10 UTC 2008 Johnny Willemsen + + * ace/config-vxworks5.x.h: + Added ACE_HAS_4_4BSD_SENDMSG_RECVMSG + +Wed May 7 07:03:29 UTC 2008 William R. Otte + + * ace/Unbounded_Set.h + + Fuzz fix. + +Wed May 7 06:33:30 UTC 2008 William R. Otte + + * ace/Unbounded_Set.inl + + Fix unused argument warning. + +Tue May 6 17:03:17 UTC 2008 William R. Otte + + * ace/Hash_Map_Manager_T.cpp: + Fixed segfault if shared_find is called on a map of size zero. + + * ace/Log_Msg.h: + + Comments for trace_active were swapped. + + * ace/Node.h: + * ace/Node.cpp: + * ace/Unbounded_Set.h: + * ace/Unbounded_Set.inl: + * ace/Unbounded_Set.cpp: + * ace/Unbounded_Set_Ex.h: + * ace/Unbounded_Set_Ex.inl: + * ace/Unbounded_Set_Ex.cpp: + + Extended the Unbounded_Set to include a comparator template parameter, + which must implement operator (), which returns true if the items are + equivalent. This class has been renamed Unbounded_Set_Ex. + + Unbounded_Set is now implemented in terms of Unbounded_Set_Ex with a + comparator that uses operator== to compare the items. + + * ace/Service_Gestalt.h: + * tests/Unbounded_Set_Test.cpp: + + Slight updates to conform with new implementation. + + * NEWS + + Added description for above. + +Tue May 6 12:37:43 UTC 2008 Jeff Parsons + + * ace/ETCL/ETCL_Constraint.h: + * ace/ETCL/ETCL_Constraint_Visitor.cpp: + * ace/ETCL/ETCL_Constraint_Visitor.h: + * ace/ETCL/ETCL_Constraint.inl: + * ace/ETCL/ETCL_Constraint.cpp: + + Moved code from the TAO ETCL classes to base classes + here. + +Tue May 6 08:27:10 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Added support for ACE_RUN_VX_TGT_TELNET_HOST and + ACE_RUN_VX_TGT_TELNET_PORT so that an explicit telnet server + can be configured. If not specified we use ACE_RUN_VX_TGTHOST + which also specifies the ip address that is used as endpoint + for the corba servers + +Mon May 5 17:09:10 UTC 2008 Johnny Willemsen + + * include/makeinclude/build_dll.bor: + * include/makeinclude/build_exe.bor: + * include/makeinclude/build_lib.bor: + Handle files with cxx extension just as we could handle cpp files + +Mon May 5 07:53:10 UTC 2008 Johnny Willemsen + + * ace/os_include/os_pdh.h: + New os_include file for pdh.h + + * ace/configure.ac: + Added check for pdh.h + + * ace/Makefile.am: + Added new file + + * ace/config-win32-common.h: + * ace/config-win32-mingw.h: + * ace/config-WinCE.h: + Windows has pdh.h, but not MinGW and not WinCE + + * ace/MonitorControl/BytesReceivedMonitor.cpp: + * ace/MonitorControl/BytesReceivedMonitor.h: + * ace/MonitorControl/BytesSentMonitor.cpp: + * ace/MonitorControl/BytesSentMonitor.h: + * ace/MonitorControl/CPULoadMonitor.cpp: + * ace/MonitorControl/CPULoadMonitor.h: + * ace/MonitorControl/MemoryUsageMonitor.cpp: + * ace/MonitorControl/MemoryUsageMonitor.h: + * ace/MonitorControl/NumThreadsMonitor.cpp: + * ace/MonitorControl/NumThreadsMonitor.h: + * ace/MonitorControl/PacketsReceivedMonitor.cpp: + * ace/MonitorControl/PacketsReceivedMonitor.h: + * ace/MonitorControl/PacketsSentMonitor.cpp: + * ace/MonitorControl/PacketsSentMonitor.h: + * ace/MonitorControl/WindowsMonitor.cpp: + * ace/MonitorControl/WindowsMonitor.h: + * ace/MonitorControl/WindowsMultiInstanceMonitor.cpp: + * ace/MonitorControl/WindowsMultiInstanceMonitor.h: + Use ACE_HAS_WIN32_PDH instead of ACE_WIN32 because with WinCE and + MinGW we don't have pdh on windows + +Mon May 5 07:37:10 UTC 2008 Johnny Willemsen + + * examples/Monitor/CPU_Load/cpu_load.cpp: + * examples/Monitor/Group/group.cpp: + Fixed C90 warnings + +Mon May 5 07:30:10 UTC 2008 Johnny Willemsen + + * examples/Monitor/MC_Test_Utilities.mpc: + Don't build with ace_for_tao enabled + +Sat May 3 17:00:07 UTC 2008 J.T. Conklin + + * bin/MakeProjectCreator/modules/AutomakeWorkspaceHelper.pm: + + Add relative libdirs for new ACE_ETCL, ACE_ETCL_Parser, and + ACE_MonitorControl libraries. + +Sat May 3 13:47:21 UTC 2008 J.T. Conklin + + * examples/Makefile.am: + + Regenerated. + +Fri May 2 23:58:38 UTC 2008 J.T. Conklin + + * configure.ac: + + Build new example directories. + + * examples/Monitor/Bytes_Sent/Makefile.am: + * examples/Monitor/Message_Queue_Size/Makefile.am: + * examples/Monitor/Constraint/Makefile.am: + * examples/Monitor/CPU_Load/Makefile.am: + * examples/Monitor/Num_Threads/Makefile.am: + * examples/Monitor/Group/Makefile.am: + * examples/Monitor/Memory_Usage/Makefile.am: + * examples/Monitor/Makefile.am: + * examples/Semaphores/Makefile.am: + + New Makefile.am's. + +Fri May 2 23:29:06 UTC 2008 J.T. Conklin + + * ace/ETCL/Makefile.am: + + Regenerated. + + * ace/ETCL/ETCL.mpc: + + Add automake specific rule for includes. + +Fri May 2 22:53:46 UTC 2008 J.T. Conklin + + * configure.ac: + + Build ace/ETCL and ace/MonitorControl. + +Fri May 2 21:54:40 UTC 2008 J.T. Conklin + + * ace/ETCL/Makefile.am: + * ace/MonitorControl/Makefile.am: + + New Makefile.am's. + + * ace/Makefile.am: + + Regenerated. + +Fri May 2 18:36:41 UTC 2008 Jeff Parsons + + * ace/ETCL/ETCL_Interpreter.h: + + Fix for build problems with versioned namespaces turned on. + +Fri May 2 17:50:10 UTC 2008 Johnny Willemsen + + * ace/config-vxworks6.2.h: + * ace/config-vxworks6.3.h: + * ace/config-vxworks6.4.h: + Only define _C99 when it is not defined yet + +Fri May 2 17:20:37 UTC 2008 Steve Huston + + * tests/Message_Queue_Test.cpp: Removed the delay sleep between loop + iterations - it causes the test to time out too often. Increased + the message count back to multiples of 100,000. + +Fri May 2 15:34:55 UTC 2008 Steve Huston + + * tests/RW_Process_Mutex_Test.cpp: Fixed compile warning about + redundant variable. + +Fri May 2 11:07:10 UTC 2008 Johnny Willemsen + + * ace/MMAP_Memory_Pool.{h,cpp}: + Doxygen improvements and moved the documentation about the + handle_signal method from the cpp to the header file so that + it appears in the doxygen documentation + +Fri May 2 09:36:10 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Added Bug_3315_Regression + +Fri May 2 08:25:10 UTC 2008 Johnny Willemsen + + * bin/msvc_static_order.lst: + Added new libs + +Fri May 2 08:15:10 UTC 2008 Johnny Willemsen + + * ace/ace_for_tao.mpc: + Added new monitor files + +Fri May 2 08:04:10 UTC 2008 Johnny Willemsen + + * ace/Monitor_Admin.cpp + * ace/Monitor_Admin.h + * ace/MonitorControl/AutoUpdateStarter.cpp + * ace/MonitorControl/AutoUpdateStarter.h + * ace/MonitorControl/MonitorControl_utils.h + Updated for naming conventions + +Fri May 2 07:47:10 UTC 2008 Johnny Willemsen + + * examples/Monitor/Bytes_Sent/bytes_sent.cpp + * examples/Monitor/Constraint/constraint.cpp + * examples/Monitor/CPU_Load/cpu_load.cpp + * examples/Monitor/Group/group.cpp + * examples/Monitor/Memory_Usage/memory_usage.cpp + * examples/Monitor/Message_Queue_Size/message_queue_size.cpp + * examples/Monitor/Num_Threads/num_threads.cpp + Updated include + + * examples/Monitor/Bytes_Sent/Bytes_Sent.mpc + * examples/Monitor/Constraint/Constraint.mpc + * examples/Monitor/Num_Threads/Num_Threads.mpc + * examples/Monitor/Group/Group.mpc + * examples/Monitor/CPU_Load/CPU_Load.mpc + * examples/Monitor/Message_Queue_Size/Message_Queue_Size.mpc + Don't build with ace_for_tao + +Thu May 1 22:35:17 UTC 2008 Steve Huston + + * ace/MonitorControl/MonitorControl.mpc: + * bin/MakeProjectCreator/config/ace_mc.mpb: + Avoid wince - it lacks the needed PDH capability. + +Thu May 1 18:27:10 UTC 2008 Johnny Willemsen + + * ace/MonitorControl/MonitorControl.mpc: + * bin/MakeProjectCreator/config/ace_mc.mpb: + Use ACE_MonitorControl as shared library name + +Thu May 1 17:31:01 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Config.cpp: Removed an assert guarding the case when + the current thread has no associated configuration context. Added + code that would initialize the thread's configuration context with + the global, instead. This addresses bug# 3315. + +Thu May 1 17:11:48 UTC 2008 Jeff Parsons + + * ace/ace.mwc: + + Added MonitorControl directory to the workspace. + +Thu May 1 17:05:37 UTC 2008 Jeff Parsons + + * ace/MonitorControl/PacketsSentMonitor.h: + * ace/MonitorControl/WindowsMultiInstanceMonitor.cpp: + * ace/MonitorControl/WindowsMonitor.cpp: + * ace/MonitorControl/PacketsReceivedMonitor.cpp: + * ace/MonitorControl/MonitorGroup.h: + * ace/MonitorControl/MonitorQuery.h: + * ace/MonitorControl/NumThreadsMonitor.cpp: + * ace/MonitorControl/PacketsSentMonitor.cpp: + * ace/MonitorControl/MonitorGroup.cpp: + * ace/MonitorControl/WindowsMultiInstanceMonitor.h: + * ace/MonitorControl/WindowsMonitor.h: + * ace/MonitorControl/MonitorControl_utils.h: + * ace/MonitorControl/MonitorQuery.cpp: + * ace/MonitorControl/PacketsReceivedMonitor.h: + * ace/MonitorControl/NumThreadsMonitor.h: + + Changed header includes to be consistently relative + to $ACE_ROOT. + +Thu May 1 16:11:12 UTC 2008 Jeff Parsons + + * MonitorControl/*: + + Moved this directory to $ACE_ROOT/ace. + +Thu May 1 15:56:58 UTC 2008 Steve Huston + + * tests/run_test.lst: Change Bug_2980_Regression_Test's !MSVC to + !Win32. The test won't run on Windows per its comments, but no + XML configs set MSVC - they set Win32. + +Thu May 1 15:27:25 UTC 2008 Steve Huston + + * tests/Message_Queue_Test.cpp: In the counting test, run multiples + of 50,000 instead of 100,000, blocks. The test is timing out on a + number of platforms. + + * tests/RW_Process_Mutex_Test.cpp: Fix signed/unsigned warnings and + wchar build error. Changed the default lock name to something other + than the program's name. Using the program name produces "text + file busy" when attempting a file lock on it... doh... + +Thu May 1 14:47:33 UTC 2008 Jeff Parsons + + * MonitorControl/examples/*: + + Removed this directory and moved its contents to + $ACE_ROOT/examples/Monitor. + + * bin/MakeProjectCreator/config/acelib.mpb: + + Cosmetic changes. + +Thu May 1 14:37:03 UTC 2008 Chad Elliott + + * bin/MakeProjectCreator/modules/VXTestProjectCreator.pm: + + Override the warn_useless_project() method so that we are no + longer warned about "no useful targets" for this project type. + +Wed Apr 30 22:01:10 UTC 2008 Steve Huston + + * tests/RW_Process_Mutex_Test.cpp: New test for proper functioning + of ACE_RW_Process_Mutex. + + * tests/tests.mpc: + * tests/run_test.lst: Add RW_Process_Mutex_Test. + +Wed Apr 30 21:14:45 UTC 2008 James H. Hill + + * ace/Hash_Map_Manager_T.h: + + Two of the backwards compatible iterators for + ACE_Hash_Map_Manager incorrectly defined the iterator_category + trait based on the container_type, which does not have an + iterator_category. Now the trait is defined in terms of its + base class. This resolved Bugzilla Bug #3314. + +Wed Apr 30 16:49:27 UTC 2008 Jeff Parsons + + * MonitorControl/PacketsSentMonitor.h: + * MonitorControl/BytesReceivedMonitor.h: + * MonitorControl/PacketsReceivedMonitor.h: + * MonitorControl/BytesSentMonitor.h: + + Added include of export header file, since it's not + pulled in indirectly on Solaris builds. + + * MonitorControl/WindowsMultiInstanceMonitor.cpp: + + Fixed signed/unsigned comparison warnings on wchar builds. + +Wed Apr 30 16:24:41 UTC 2008 Jeff Parsons + + * MonitorControl/CPULoadMonitor.cpp: + * MonitorControl/WindowsMonitor.cpp: + * MonitorControl/WindowsMultiInstanceMonitor.cpp: + * MonitorControl/MemoryUsageMonitor.cpp: + * MonitorControl/NumThreadsMonitor.cpp: + * MonitorControl/LinuxNetworkInterfaceMonitor.cpp: + + Fixed wchar build errors. + +Wed Apr 30 13:49:52 UTC 2008 Steve Huston + + * ace/UUID.cpp (get_timestamp_and_clocksequence): Case clock sequence + value using ACE_UINT16 instead of u_char to prevent duplicates + when many UUIDs are generated quickly. Thanks to Wim van den Boogaard + for this fix. Resolves Bugzilla #3313. + +Tue Apr 29 19:52:48 UTC 2008 Steve Huston + + * ace/Proactor.cpp: Simplify the timer_handler_ task spawn and + shutdown. Also, if close() sees an error from the implementation's + close, don't stop closing. Things are most likely already ripped + apart too far to recover from, and it's likely to cause a hang to + just try to stop closing now. + + * ace/POSIX_Asynch_IO.cpp: Correctly handle the ACE_Message_Block + pointers passed to operations and later updating when complete. + Thanks to Fernando C. Jeronymo for diagnosing this problem. + + * THANKS: Added Fernando C. Jeronymo to the Hall of Fame. + + * tests/Proactor_UDP_Test.cpp: Fix to close down correctly in + half-duplex mode. + +Tue Apr 29 19:12:53 UTC 2008 Jeff Parsons + + * bin/MakeProjectCreator/config/ace_etcl_parser.mpb: + + Changed the path of the 'includes' line to match + the new location of ETCL. + + * MonitorControl/Constraint_Interpreter.cpp: + * MonitorControl/Constraint_Visitor.h: + * MonitorControl/Constraint_Visitor.cpp: + * MonitorControl/Constraint_Interpreter.h: + + Updated #includes to match the new location of ETCL. + + * MonitorControl/AutoUpdateStarter.h: + + Moved location of enabled monitors check, it was + previous to any place it could see the #define in + an included file. + + * MonitorControl/examples/Constraint/constraint.cpp: + * MonitorControl/examples/CPU_Load/cpu_load.cpp: + * MonitorControl/examples/Group/group.cpp: + + Some compile warnings fixed. + +Tue Apr 29 18:37:10 UTC 2008 Johnny Willemsen + + * MonitorControl/AutoUpdateStarter.h: + * MonitorControl/Constraint_Interpreter.h: + * MonitorControl/Constraint_Visitor.h: + * MonitorControl/LinuxNetworkInterfaceMonitor.h: + * MonitorControl/MonitorControl.h: + * MonitorControl/MonitorQuery.h: + * MonitorControl/WindowsMonitor.h: + * MonitorControl/WindowsMultiInstanceMonitor.h: + Make sure we have at least one include before pragma once + +Tue Apr 29 18:27:10 UTC 2008 Johnny Willemsen + + * docs/bczar/bczar.html: + * etc/index.html: + Updated Beta to Micro + +Tue Apr 29 18:02:22 UTC 2008 Jeff Parsons + + * ETCL/*: + + Moved this directory and all its contents to $ACE_ROOT/ace. + Also changed #includes to be relative to $ACE_ROOT. + + * ace/ace.mwc: + + Added ETCL directory. + + * docs/svn/svn-prefs.reg: + + Added *.diff to list. + +Tue Apr 29 17:45:10 UTC 2008 Johnny Willemsen + + * MonitorControl/examples/Bytes_Sent/bytes_sent.cpp: + * MonitorControl/examples/Constraint/constraint.cpp: + * MonitorControl/examples/CPU_Load/cpu_load.cpp: + * MonitorControl/examples/Group/group.cpp: + * MonitorControl/examples/Memory_Usage/memory_usage.cpp: + * MonitorControl/examples/Message_Queue_Size/message_queue_size.cpp: + * MonitorControl/examples/Num_Threads/num_threads.cpp: + Updated main for unicode + +Tue Apr 29 13:14:10 UTC 2008 Johnny Willemsen + + * tests/Test_Output.cpp: + Check for ACE_VXWORKS + +Tue Apr 29 13:12:10 UTC 2008 Johnny Willemsen + + * MonitorControl/AutoUpdateStarter.cpp: + * MonitorControl/Constraint_Interpreter.cpp: + * MonitorControl/Constraint_Interpreter.h: + * MonitorControl/Constraint_Visitor.cpp: + * MonitorControl/Constraint_Visitor.h: + * MonitorControl/CPULoadMonitor.cpp: + * MonitorControl/LinuxNetworkInterfaceMonitor.cpp: + * MonitorControl/NumThreadsMonitor.cpp: + * MonitorControl/WindowsMonitor.cpp: + * MonitorControl/WindowsMultiInstanceMonitor.cpp: + Updated includes to fix errors and improve compile speed when + this lib is disabled + +Tue Apr 29 08:16:10 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/templates/vxtest.mpd: + Zap empty line + + * bin/PerlACE/ProcessVX.pm: + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Improved handling of vxtest file + +Tue Apr 29 07:23:10 UTC 2008 Johnny Willemsen + + * ace/MEM_Connector.cpp: + * ace/Service_Manager.cpp: + * ace/SOCK_Dgram_Mcast.cpp: + Reverted accidental commits from Doug + +Tue Apr 29 06:32:10 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/modules/VXTestProjectCreator.pm: + Generate exename.vxtest instead of project name + + * bin/MakeProjectCreator/templates/vxtest.mpd: + Don't generate ld < + +Mon Apr 28 22:34:10 UTC 2008 Steve Huston + + * tests/Proactor_UDP_Test.cpp: Fix compile errors on non-Windows. + +Mon Apr 28 21:53:23 UTC 2008 Steve Huston + + * docs/ACE-development-process.html: Fix a few remaining nits. + + * ace/OS_NS_stdio.inl: Removed all the pre-ACE_HAS_WINNT4 code in the + file locks methods. This was the only place left in ACE that + referred to ACE_HAS_WINNT4; all pre-NT4 support was removed last + year from the rest of ACE. This also corrects behavior of file + locks as well as ACE_RW_Process_Mutex. + + * ace/RW_Process_Mutex.h: Doxygen improvements. + + * ace/SOCK_CODgram.h: Doxygen improvements. + + * ace/SOCK_CODgram.cpp (open): If either of the local or remote + addresses is specified, use its address family rather than the + value of protocol_family. If both are specified, they must match. + + * tests/Message_Queue_Test.cpp: Added a counting test to validate the + queue's message counting. + + * tests/Proactor_UDP_Test.cpp: New test for UDP with ACE_Proactor. + + * tests/tests.mpc: + * tests/run_test.lst: Add Proactor_UDP_Test. + +Mon Apr 28 19:21:54 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX.pm: + * bin/PerlACE/ProcessVX_Unix.pm: + * bin/PerlACE/ProcessVX_Win32.pm: + Use the vxtest file when testing shared non rtp + +Mon Apr 28 19:06:10 UTC 2008 Jeff Parsons + + * MonitorControl/MonitorControl.h: + + Added ACE_HAS_MONITOR_FRAMEWORK guard to this file. + +Mon Apr 28 18:24:54 UTC 2008 Johnny Willemsen + + * ace/ace_wchar.h: + Added defines needed to build MonitorControl unicode + + * MonitorControl/WindowsMonitor.cpp: + * MonitorControl/WindowsMultiInstanceMonitor.cpp: + Make a correct difference between unicode and non unicode builds + + * ace/Strategies_T.{h,inl}: + Refcount from base is now a long + +Mon Apr 28 18:23:55 UTC 2008 Adam Mitz + + * bin/PerlACE/ProcessVX_Unix.pm: + + Fixed a bug in my previous commit of this file, + $cmdnr was not updated when the unload commands were added. + +Mon Apr 28 17:59:43 UTC 2008 Jeff Parsons + + * Constraint_Interpreter.cpp: + * Constraint_Visitor.h: + * MonitorGroup.h: + * MonitorQuery.h: + * AutoUpdateStarter.h: + * Constraint_Visitor.cpp: + * MonitorGroup.cpp: + * Constraint_Interpreter.h: + * MonitorQuery.cpp: + * AutoUpdateStarter.cpp: + * MonitorControl_utils.h: + + Added ACE_HAS_MONITOR_FRAMEWORK guards + similarly to the other files in the library. + +Mon Apr 28 17:54:54 UTC 2008 Johnny Willemsen + + * MonitorControl/BytesReceivedMonitor.cpp: + * MonitorControl/BytesSentMonitor.cpp: + * MonitorControl/CPULoadMonitor.cpp: + * MonitorControl/MemoryUsageMonitor.cpp: + * MonitorControl/NumThreadsMonitor.cpp: + * MonitorControl/PacketsReceivedMonitor.cpp: + * MonitorControl/PacketsSentMonitor.cpp: + * MonitorControl/WindowsMonitor.cpp: + * MonitorControl/WindowsMonitor.h: + * MonitorControl/WindowsMultiInstanceMonitor.cpp: + * MonitorControl/WindowsMultiInstanceMonitor.h: + Fixed unicode compile problems on windows + +Mon Apr 28 13:25:54 UTC 2008 Johnny Willemsen + + * examples/APG/Streams/streams.mpc: + * examples/C++NPv2/C++NPv2.mpc: + Use base projects + +Mon Apr 28 13:20:40 UTC 2008 Douglas C. Schmidt + + * ace/Vector_T.inl (ACE_Vector): Take another shot at fixing the + max_size() problem. + +Mon Apr 28 12:45:18 UTC 2008 Chad Elliott + + * bin/tao_orb_tests.lst: + + Added the new TAO HandleExhaustion test for all but Windows. + +Mon Apr 28 12:21:55 UTC 2008 Douglas C. Schmidt + + * ace/Vector_T.inl (ACE_Vector): Zapped the "this->" in "this->max_size()". + Thanks to Karl-Heinz for reporting this. + +Mon Apr 28 12:13:54 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_sunos5_common.GNU: + Added kstat support needed for monitoring lib on solaris + +Mon Apr 28 12:05:54 UTC 2008 Johnny Willemsen + + * MonitorControl/*: + Merge from MonitorControl branch. + +Mon Apr 28 11:37:54 UTC 2008 Johnny Willemsen + + * ace/config-all.h: + * ace/Global_Macros.h: + Moved set of define to config-all + + * ace/Truncate.h: + * ace/Condition_T.h: + Doxygen fix + +Mon Apr 28 11:36:46 UTC 2008 Chad Elliott + + * ace/Acceptor.h: + * ace/Acceptor.cpp: + + Added a virtual method to facilitate the configurable handling of + accept() errors. + +Mon Apr 28 11:30:54 UTC 2008 Johnny Willemsen + + * ETCL/*: + New ETCL library for ACE + + * bin/MakeProjectCreator/config/ace_etcl.mpb: + * bin/MakeProjectCreator/config/ace_etcl_parser.mpb: + * bin/MakeProjectCreator/config/ace_mc.mpb: + New base projects + + * bin/MakeProjectCreator/config/acenosubsets.mpb: + Layout changes + +Mon Apr 28 10:31:54 UTC 2008 Johnny Willemsen + + * ace/Monitor_Admin.cpp: + * ace/Monitor_Admin.h: + * ace/Monitor_Admin_Manager.cpp: + * ace/Monitor_Admin_Manager.h: + * ace/Monitor_Base.cpp: + * ace/Monitor_Base.h: + * ace/Monitor_Base.inl: + * ace/Monitor_Control_Action.cpp: + * ace/Monitor_Control_Action.h: + * ace/Monitor_Control_Types.cpp: + * ace/Monitor_Control_Types.h: + * ace/Monitor_Point_Registry.cpp: + * ace/Monitor_Point_Registry.h: + * ace/ace.mpc: + * ace/Global_Macros.h: + First commit coming from the Monitor branch. This will add a + monitoring framework to ACE with which size of queues, cpu load + and other resources can be monitored. + +Sun Apr 27 05:55:54 UTC 2008 Johnny Willemsen + + * ace/Service_Object.cpp: + Fixed big introduced by some cleanup I did + +Fri Apr 25 21:47:54 UTC 2008 Adam Mitz + + * bin/MakeProjectCreator/templates/vxtest.mpd: + * bin/PerlACE/ProcessVX_Unix.pm: + + Began integration of the foo.vxtest files into the actual testing + process. This needs to get enhanced in ProcessVX_Win32.pm too. + +Fri Apr 25 21:21:56 UTC 2008 Adam Mitz + + * ace/Object_Manager.cpp: + + Removed a comment that no longer applies. + + * bin/PerlACE/Process_Win32.pm: + + Changed the check for failure to spawn a process, in order to avoid + a race condition (the spawned process exits normally before we even + check its status). + + * bin/auto_run_tests.pl: + + With -s, account for different parameter formatting requirements in + the win32 and posix sandbox programs. + +Fri Apr 25 14:25:00 UTC 2008 Simon Massey + + * tests/Unload_libACE.cpp: + I've backed out this change due to lack of time to chase up + the lack of macro definitions. This will need to be revisited. + +Fri Apr 25 10:40:00 UTC 2008 Simon Massey + + * tests/Unload_libACE.cpp: + This test wasn't using ACE_TMAIN. + +Fri Apr 25 09:10:00 UTC 2008 Simon Massey + + * bin/MakeProjectCreator/config/global.features: + * examples/Log_Mgs/Log_Msg_MFC/Log_Mgs_MFC.mpc: + Feature name "uses_wchar" already used within ACE/TAO. Replaces + the "unicode" feature name. Template / project names within MPC + still named unicode. + +Thu Apr 24 18:45:32 UTC 2008 Johnny Willemsen + + * ace/config-linux-common.h: + When ACE_LACKS_STROPTS_H not is defined we assume we have + strbut so we set ACE_HAS_STRBUF_T + +Thu Apr 24 16:47:16 UTC 2008 Chad Elliott + + * bin/tao_orb_tests.lst: + + The DLL_ORB test requires threads. Disable it when the ST config + is used. + +Thu Apr 24 15:05:50 UTC 2008 Simon McQueen + + * bin/tao_orb_tests.lst: + + Scheduled new regression test for bug #3299. + +Thu Apr 24 09:55:00 UTC 2008 Simon Massey + + * bin/MakeProjectCreator/config/ace_unicode.mpb: + * bin/MakeProjectCreator/config/global.features: + Default unicode=0 feature. Unicode does not depend upon MFC, + may be used together as necessary. + + * examples/Log_Mgs/Log_Msg_MFC/Log_Mgs_MFC.mpc: + * examples/Log_Mgs/Log_Msg_MFC/Log_Mgs_Unicode_MFC.mpc: + Split out the unicode requirements. + +Thu Apr 24 05:58:32 UTC 2008 Johnny Willemsen + + * ace/Refcountable_T.{cpp,inl}: + Use ACE_INLINE + +Thu Apr 24 05:47:32 UTC 2008 Johnny Willemsen + + * ace/config-posix.h: + Reverted change below, already made a similar change which is less risky + + Thu Apr 17 19:27:23 UTC 2008 Douglas C. Schmidt + * ace/config-posix.h: Added a check for + + #if defined _XOPEN_STREAMS && _XOPEN_STREAMS == -1 + # define ACE_LACKS_STROPTS_H + #endif + + so that ACE will compile properly on Fedora 8. Thanks to + Jules Colding for this fix. + +Thu Apr 17 19:27:23 UTC 2008 Douglas C. Schmidt + + * ace/config-posix.h: Added a check for + + #if defined _XOPEN_STREAMS && _XOPEN_STREAMS == -1 + # define ACE_LACKS_STROPTS_H + #endif + + so that ACE will compile properly on Fedora 8. Thanks to + Jules Colding for this fix. + +Wed Apr 23 18:29:32 UTC 2008 Johnny Willemsen + + * ace/Refcountable.{h,cpp,inl}: + * ace/Refcountable_T.{h,cpp,inl}: + Changed ACE_Refcountable to ACE_Refcountable_T which has a + trait for the type of lock. ACE_Refcountable is now a typedef + of ACE_Refcountable_T. Also the refcount + type is now a long so that we can make use of the Atomic_Op + optimizations on some platforms + + * ace/ace.mpc: + * ace/Makefile.am: + Updated for the change above + +Wed Apr 23 14:49:32 UTC 2008 Johnny Willemsen + + * ace/config-linux-common.h: + When _XOPEN_STREAMS is defined to -1 we don't have stropts.h, + this fixes bugzilla 3291. Thanks to Jules Colding + for reporting this + +Wed Apr 23 14:10:32 UTC 2008 Johnny Willemsen + + * docs/ACE-development-process.html: + We are using svn as repository + +Wed Apr 23 14:01:32 UTC 2008 Johnny Willemsen + + * bin/generate_rel_manpages: + Corrected doxygen path + + * bin/group_test_stats.sh: + Helper script to analyze test stat diffs + + * ace/Sig_Handler.{h,cpp}: + Doxygen changes and changed third_party_sig_handler flag to a + bool + + * ace/Service_Repository.{h,cpp}: + Changed ignore_suspended to a bool + + * ace/Intrusive_Auto_Ptr.h: + Fixed typo in comment + + * ace/config-vxworks6.2.h: + * ace/config-vxworks6.3.h: + * ace/config-vxworks6.4.h: + Removed workaround that is only needed with VxWorks 5.5.1 + + * ace/Codeset_Registry_db.cpp: + Added UCS2 and correct short names. This fixes bugzilla 3295 + + * ace/Codeset_IBM1047.h: + Doxygen changes + + * ace/Cleanup_Strategies_T.h: + Layout changes + + * ace/Service_Gestalt.{h,inl}: + No need for virtual methods, use bool and doxygen changes + + * ace/Service_Manager.h: + Explicitly mark destructor as virtual + + * ace/Service_Object.{h,cpp,inl}: + Use bool + +Wed Apr 23 01:53:32 CDT 2008 Johnny Willemsen + + * ACE version 5.6.4 released. + +Wed Apr 16 13:06:05 UTC 2008 Iliyan Jeliazkov + + * ace/ARGV.cpp: + Don't quote quotes already quoted. + +Mon Apr 14 12:10:57 UTC 2008 Johnny Willemsen + + * tests/run_test.pl: + Don't run 2980 when WCHAR is set + +Mon Apr 14 11:08:57 UTC 2008 Johnny Willemsen + + * ace/Threading_Helper_T.cpp: + Removed + + * ace/Makefile.am: + Removed file above + + * ace/Service_Config.{h,cpp,inl}: + Changed the template instantiations like we have for Atomic_Op. + +Mon Apr 14 09:54:57 UTC 2008 Johnny Willemsen + + * tests/tests.mpc: + Don't build 2980 with wchar enabled and added empty resource + file section + +Mon Apr 14 08:59:57 UTC 2008 Johnny Willemsen + + * ace/Threading_Helper_T.cpp: + Added new file with the threading helper template code. This resolves + the strange link problems with BCB. This file is included in the + Service_Config.h file + + * ace/Makefile.am: + Added new files + + * ace/Service_Config.{h,cpp,inl}: + Include the new Threading_Helper_T.cpp and removed the implementation + from these files + + * tests/tests.mpc: + Added missing include for bug 2980 + + * ace/Codeset_Registry.h: + Fixed typo in comment + + * ace/Shared_Object.h: + Doxygen changes + +Mon Apr 14 01:56:06 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Config.h: + * ace/Service_Config.inl: + * ace/Service_Config.cpp: + + Moved ACE_Threading_Helper ctor and dtor implementaion + inline. This makes them available to code that indirectly + references the threadkey_ member (like, in examples/). This + should resolve link-time problems with borland compilers. + + * tests/Bug_2980_Regression_Test.cpp (unloadDll): + + Fixing warnings about missing extern "C" qualifier in call to + pthread_create. + +Sun Apr 13 07:27:57 UTC 2008 Johnny Willemsen + + * ace/OS_NS_Thread.cpp (_vx_call_entry): + Set the sc::current before calling main. This resolves the + sc asserts with vxworks kernel mode. Thanks to Iliyan + for suggesting this addition + +Fri Apr 11 17:36:34 UTC 2008 Douglas C. Schmidt + + * docs/Download.html: + * docs/ACE-development-process.html: + * docs/ACE-bug-process.html: Updated these files to use the major, + minor, and micro release terminology. + +Fri Apr 11 15:26:08 UTC 2008 Iliyan Jeliazkov + + * tests/Bug_2980_Regression_Test.cpp: + * tests/run_test.lst: + + Including config-lite.h: the driver is non-ACE but it still + needs to know platform-specific stuff, like threads usage, + etc. + +Fri Apr 11 01:51:13 UTC 2008 Iliyan Jeliazkov + + * ace/Svc_Conf_Tokens.h: + * ace/svcconf.mpb: + + Fixing a fuzz build warning of a missing $Id. Also, not all + make(1)'s have $(MV), so changing mpb to use just "mv" + +Thu Apr 10 22:32:58 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Config.h: + * ace/Service_Config.cpp: + + Fixing compile problems with single-thread-only builds - using + the compiler's abilities (partial specialization) to generate + appropriate code. + + * ace/Svc_Conf.h: + * ace/Svc_Conf_Token_Table.h: + * ace/Svc_Conf_Tokens.h: + * ace/Svc_Conf_y.cpp: + * ace/svcconf.mpb: + + Changes to fix compile problems related to versioned namespace + use. Eliminated custom token file post-processing - replaced + with a wrapper header file (yacc(1) is now producing + Token_Table.h, which gets included in Tokens.h) + +Thu Apr 10 14:42:04 UTC 2008 Iliyan Jeliazkov + + * ace/Svc_Conf.h: + + Adding YYSTYPE_IS_DECLARED to prevent yacc(1) from trying to use a + trivial definition of YYSTYPE. + + * ace/Svc_Conf.y: + + Fixing an unused variable warning. Adding an YYSTYPE guard. + + * ace/Svc_Conf_Tokens.h: + * ace/Svc_Conf_y.cpp: + * ace/svcconf.mpb: + + Undefining YYSTYPE_IS_DECLARED at the bottom of Svc_Conf_Tokens.h + prevents it from leaking and poluting the global namespace. This + allows other yacc(1) based parsers to be used in ACE + apps. Cleaning up and recording generated files. + +Thu Apr 10 13:27:13 UTC 2008 Chad Elliott + + * tests/Bug_2980_Regression_Test.cpp: + + Fixed compilation issues and reversed the CAN_RUN_TEST check to + get it to run on non-win32 and non-vxworks operating systems. + +Thu Apr 10 10:11:57 UTC 2008 Johnny Willemsen + + * ace/Dynamic_Service.inl: + Corrected method signatures + +Thu Apr 10 10:03:57 UTC 2008 Johnny Willemsen + + * tests/Bug_2980_Regression_Test.cpp: + Fixed BCB compile error + +Thu Apr 10 07:13:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_linux_pgi.GNU: + Removed deprecated linker flags + + * ace/Dev_Poll_Reactor.cpp: + * ace/Notification_Queue.cpp: + * ace/Service_Config.cpp: + * ace/Service_Object.cpp: + * ace/Sock_Connect.cpp: + Added missing includes + + * ace/Notification_Queue.cpp: + * ace/Notification_Queue.inl: + Added missing versioned namespace macros + +Thu Apr 10 06:41:57 UTC 2008 Johnny Willemsen + + * ace/Service_Gestalt.h: + Added include of Guard_T.h + + * include/makeinclude/platform_linux_pgi.GNU: + Updated for latest pgCC version + +Thu Apr 10 00:50:53 UTC 2008 Iliyan Jeliazkov + + * tests/Bug_2980_Regression_Test.cpp: + * tests/tests.mpc: + + Fixing a compile problem with no-threads builds. + +Wed Apr 9 22:05:30 UTC 2008 Iliyan Jeliazkov + + * ace/Svc_Conf.h: + * ace/Svc_Conf.y: + * ace/Svc_Conf_Lexer.h: + * ace/Svc_Conf_Lexer.cpp: + * ace/Svc_Conf_Param.h: + * ace/Svc_Conf_Tokens.h: + * ace/Svc_Conf_y.cpp: + * ace/svcconf.mpb: + + Simplified the build sequence reducing the number of additional + transformations needed for Bison's parser output. That includes + the elimination of the ACE_YY prefix, which was necessary only + because of these transformations. Added ACE_TEXT around naked + string literals. Fixed build warnings with unicode builds. + +Wed Apr 9 20:22:46 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Repository.cpp: + Fixing relocate_i to both account for empty slots _and_ provide + useful logging. + +Wed Apr 9 18:24:57 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Don't run 3171 with CORBA/e micro + +Wed Apr 9 11:50:27 UTC 2008 Chad Elliott + + * bin/MakeProjectCreator/modules/VXTestProjectCreator.pm: + + Added a need_to_write_project override method to only allow the + project file to be written if it is an executable project. + + * bin/MakeProjectCreator/modules/VXTestWorkspaceCreator.pm: + + Fixed a bug where an invalid base module was used in the @ISA. + +Wed Apr 9 11:41:57 UTC 2008 Johnny Willemsen + + * tests/Bug_2980_Regression_Test.cpp: + Check for ACE_VXWORKS + +Wed Apr 9 11:11:57 UTC 2008 Johnny Willemsen + + * ace/Svc_Conf_y.cpp: + Fixed unicode build problems + +Wed Apr 9 08:06:57 UTC 2008 Johnny Willemsen + + * ace/Svc_Conf.y: + * ace/Svc_Conf_y.cpp: + Fixed unicode build problems + +Wed Apr 9 07:18:57 UTC 2008 Johnny Willemsen + + * ace/Service_Config.h: + Export ACE_Threading_Helper, it is used as protected class + member + + * ace/Service_Gestalt.cpp: + Don't use ACE_LIB_TEXT + + * ace/High_Res_Timer.h: + * ace/Based_Pointer_T.h: + Doxygen changes + + * ace/Naming_Context.cpp: + Fixed gcc 4.3 warning + + * ace/OS_NS_errno.h (last_error): + Give the argument a name so that doxygen can do its work + + * ace/Select_Reactor_T.cpp: + Use scoping + + * ace/MMAP_Memory_Pool.{h,cpp}: + Add a bool flag to indicate whether the signal handler has to + be installed or not. Made some other flags bool and win32 there + is no need have a signal handler as member. This fixes bugzilla + 3290 + +Wed Apr 9 02:43:37 UTC 2008 Iliyan Jeliazkov + + * ace/Dynamic_Service.inl (instance): + Adjusting interface to take a smart pointer. + + * ace/OS_NS_unistd.cpp (argv_to_string): + Adding interpretation for tabs and new line characters as + characters to trigger quoting. + + * ace/Service_Config.h: + * ace/Service_Config.cpp: + * ace/Service_Gestalt.h: + * ace/Service_Gestalt.inl: + * ace/Service_Gestalt.cpp: + * ace/Service_Repository.cpp: + Reformatting, updating comments and logging. + +Wed Apr 9 01:21:42 UTC 2008 Douglas C. Schmidt + + * ace/Condition_T.cpp (wait): Fixed a bug where the mutex + parameter wasn't being used properly if abstime was 0. Thanks + to Andriy Gapon for reporting this. + +Mon Apr 7 18:49:57 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/docs/templates/gnu.txt: + Document linkflags + +Mon Apr 7 15:21:38 UTC 2008 Iliyan Jeliazkov + + This the second part of the SC refatoring. It builds on top of + the intrusive refcounting mechanism introduced earlier to improve + design and eliminate memory issues (leaks, SEGV on shutdown) + + * ace/Service_Config.cpp (open_i,ACE_Service_Config): + + Moved the implicit configuration file handling from open_i to + the SG instance. Eliminated close_svcs() by incorporating its + functionality in close(). + + * ace/Service_Config.inl: + * ace/Service_Config.h (ACE_Service_Config_Guard,ACE_Service_Config): + + Removing the inheritance relationship between Service Config and + Service Gestalt. To simplify the memory management, SC becomes an + interface to the actual configuration data managed by SG. Coupled + with the reference counting of SG instances, this ensures correct + memory management in multi-threaded environments where both the + TSS and the user code may trigger SG finalization. + + Introducing ACE_Threading_Helper to simplify TSS management + (RAII idiom). Changed ACE_Service_Config_Guard to use the new + smart pointer for SG. Doxygen comments cleanup. + + * ace/Svc_Conf.y: + * ace/Svc_Conf_y.cpp: + + Fixing unused function definition + + * tests/Bug_2980_Regression_Test.cpp: + + Updating the test to prevent it from breaking vxWorks builds + which appear to lack a declaration for dlopen() + +Sun Apr 6 01:53:13 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Gestalt.cpp: + + Fixing unused variable warning. + + * ace/Svc_Conf_y.cpp: + * ace/svcconf.mpb: + + Ensuring there are no TAB characters present in the generated + file. + + * tests/run_test.lst: + + Excluding Bug_2980_Regression as it is not runnable on vxWorks. + +Sat Apr 5 16:21:50 UTC 2008 Iliyan Jeliazkov + + * ace/Service_Config.inl: + * ace/Service_Config.cpp: + * ace/Service_Gestalt.cpp: + * ace/Service_Gestalt.h: + + Making SG intrusively refcountable by introducing + intrusive_{add,remove}_ref methods and a refcounter. Adding + skip_default_svc_conf_file parameter in process_directives. + + * ace/svcconf.mpb: + * tests/Object_Manager_Flipping_Test.cpp: + + Reformatting and cleanup. + +Sat Apr 5 13:42:57 UTC 2008 Johnny Willemsen + + * tests/Bug_2980_Regression_Test.cpp: + Fixed argument not used warnings + +Sat Apr 5 13:36:57 UTC 2008 Johnny Willemsen + + * ace/Parse_Node.cpp: + Moved include out of versioned namespace block + +Sat Apr 5 11:50:40 UTC 2008 Iliyan Jeliazkov + + * ace/Parse_Node.cpp: + * ace/Svc_Conf.y: + * ace/Svc_Conf_Tokens.h: + * ace/Svc_Conf_y.cpp: + + Replacing ACE_LIB_TEXT with ACE_TEXT + +Fri Apr 4 21:43:35 UTC 2008 Iliyan Jeliazkov + + * THANKS: + + Adding Michael Carter for reporting + and debugging bug 3007. + + * ace/Base_Thread_Adapter.h: + * ace/Base_Thread_Adapter.cpp: + + Storing a pointer to SG that was current in the parent thread, + which enables correct "inheritance" of the SG in the child thread. + + * ace/Parse_Node.h: + * ace/Parse_Node.cpp: + + Fixing ACE_Stream_Node::{apply,link} to ensure the modules are linked + together and initialized correctly - see bug# 2916. Moving the + initialization code out of the yacc parser, here. + + * ace/Service_Object.cpp: + * ace/Service_Types.cpp: + + Improving the log output in fini(). + + * ace/Service_Repository.h: + + Eliminating an unused parameter static_only from relocate_i() + + * ace/Service_Repository.cpp: + + Simplified relocate_i() and fixed an error that was causing it to + choose incorrect ranges of service indexes to relocate. + Eliminated the boolean static_only parameter as it was always + being set to true. Changed remove() to eliminate the "packing" + code and updated the few other methods, which assumed there are no + "gaps" in the service storage. + + * ace/Svc_Conf.h: + * ace/Svc_Conf.y: + * ace/Svc_Conf_Tokens.h: + * ace/Svc_Conf_y.cpp: + + Adding an overloaded yyerror that takes just a string to comply + with the changed bison template. Moving the module initialization + code out of the parser. See ACE_Stream_Node class and bug# 2916. + + * ace/Thread_Adapter.cpp: + + The invoke() method, which runs in the new thread, initializes the + thread-specific configuration context. This scheme ensures any + newly spawned thread would inherit the spawning thread's service + configuration context. + + * ace/ace.mpc: + + Adding Intrusive_Auto_Ptr to the list. + + * ace/svcconf.mpb: + + Updated for the grammar updates, see bug# 2916. + + * examples/ASX/CCM_App/ASX_CCM_App.mpc: + * examples/ASX/CCM_App/CCM_App.cpp: + + The DLL names are case-sensitive on *nix. Minor layout changes. + + * tests/Object_Manager_Flipping_Test.cpp: + + Updated to use the Intrusive_Auto_Ptr + + * tests/run_test.lst: + * tests/tests.mpc: + + Adding Bug_2980_Regression_Test + +Fri Apr 4 18:27:57 UTC 2008 Johnny Willemsen + + * configure.ac: + Fixed iostream detection. This fixes bugzilla 3288 + This to Thomas Girard + for reporting this. + +Thu Apr 3 14:13:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxworks5.5.x.GNU: + * include/makeinclude/platform_vxworks6.2.GNU: + * include/makeinclude/platform_vxworks6.3.GNU: + Changed the make variable from which we zap the -ansi and also support + this with the diab compiler + +Thu Apr 3 09:40:00 UTC 2008 Simon Massey + + * apps/JAWS/stress_testing/benchd.cpp: + + Using "interface" as the descriptive name of a parameter seems to + cause VC8 (when building with MFC) to assume you mean a struct type + and it raises an incorrect systax error. + +Thu Apr 3 07:05:57 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/templates/gnu.mpd: + Generate link_groups also when staticflags are not set + +Wed Apr 2 21:40:00 UTC 2008 J.T. Conklin + + * configure.ac: + + Fix typo in ACE_HAS_BSWAP_{16,32,64} feature tests. + This to Thomas Girard + for reporting this. + +Wed Apr 2 20:22:50 UTC 2008 Iliyan Jeliazkov + + * ace/Intrusive_Auto_Ptr.h: + * ace/Intrusive_Auto_Ptr.inl: + + Correcting a problem with VC71 + +Wed Apr 2 11:06:30 UTC 2008 Vladimir Zykov + + * bin/tao_orb_tests.lst: + + Enabled a TAO/tests/Collocated_Forwarding on vxworks and + vxworks_rtp. + +Wed Apr 2 09:05:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxworks5.5.x.GNU: + * include/makeinclude/platform_vxworks6.2.GNU: + * include/makeinclude/platform_vxworks6.3.GNU: + Add no_cflags_ansi and no_ccflags_ansi which if set do remove the + -ansi compiler flag + +Wed Apr 2 08:14:57 UTC 2008 Johnny Willemsen + + * ace/config-linux-common.h: + Replaced ACE_HAS_VOIDPTR_GETTIMEOFDAY with + ACE_HAS_TIMEZONE_GETTIMEOFDAY, this fixes bugzilla 3145 + This to Thomas Girard + for reporting this + +Wed Apr 2 07:51:57 UTC 2008 Johnny Willemsen + + * tests/run_test.lst: + Enabled a few tests on VxWorks again, in the past rebooting a + crashed target was problematic but that is not an issue anymore + +Tue Apr 1 14:20:34 UTC 2008 Vladimir Zykov + + * bin/tao_orb_tests.lst: + Added a new test for collocated forwarding case. + +Tue Apr 1 12:58:57 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Added OBV typed event test + +Tue Apr 1 12:52:57 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Add the DSI Gateway exception test, they should run, the scoreboard + will show if they run + +Tue Apr 1 08:33:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Set ACE_OPENVMS_IA64 on Itanium + + * include/makeinclude/rules.lib.GNU: + Only use a special AR rule on OpenVMS IA64 + +Tue Apr 1 07:38:57 UTC 2008 Johnny Willemsen + + * tests/Intrusive_Auto_Ptr_Test.cpp: + Fixed argument not used warning + +Tue Apr 1 07:34:57 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Enabled a few tests for vxworks + +Tue Apr 1 07:12:57 UTC 2008 Johnny Willemsen + + * tests/Reactor_Dispatch_Order_Test.cpp: + Only run the reactor once, this will lead to the failing of this test + when using the WFMO Reactor which seems to be a old issue that needs + to get addressed + +Tue Apr 1 06:54:57 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Disabled most tests for vxworks and vxworks_rtp, we first need to + convert a lot of scripts to support vxworks + +Mon Mar 31 21:48:58 UTC 2008 J.T. Conklin + + * configure.ac: + + Changed to avoid feature test for pthread_getaffinity_np() and + pthread_setaffinity_np() if system does not have cpu_set_t. In + that case, the pthread functions are amost certainly not + compatible. + + * ace/Makefile.am: + + Add Intrusive_Auto_Ptr.cpp, Intrusive_Auto_Ptr.h, and + Intrusive_Auto_ptr.inl to nobase_include_HEADERS. + +Mon Mar 31 18:56:40 UTC 2008 Iliyan Jeliazkov + + * ace/Refcounted_Auto_Ptr.h: + * ace/Refcounted_Auto_Ptr.inl: + * ace/Refcounted_Auto_Ptr.cpp: + + Reverting the changes because a) they are not really necessary + for the refactoring of the service config, and; b) the AIX + compiler appears to not deal well with implicit conversion + definitions, to template member types. + +Mon Mar 31 16:15:17 UTC 2008 Iliyan Jeliazkov + + * tests/tests.mpc: + + Adding Intrusive_Auto_Ptr_Test to the list + +Mon Mar 31 14:52:58 UTC 2008 Iliyan Jeliazkov + + * ace/Intrusive_Auto_Ptr.h: + * ace/Intrusive_Auto_Ptr.cpp: + * ace/Refcounted_Auto_Ptr.h: + * ace/Refcounted_Auto_Ptr.inl: + * ace/Refcounted_Auto_Ptr.cpp: + + Added preprocessor guards for proper inlining. Qualified + the type name in the implementation of opretator + unspecified_bool_type () to appease GCC 3.x + +Mon Mar 31 13:50:45 UTC 2008 Iliyan Jeliazkov + + * tests/run_test.lst: + + Adding Intrusive_Auto_Ptr_Test to the list + +Mon Mar 31 12:09:20 UTC 2008 Chad Elliott + + * bin/MakeProjectCreator/modules/AutomakeWorkspaceHelper.pm: + + Always reference Kokyu libraries from $(ACE_BUILDDIR) instead of + $(top_builddir) so that it will work from both ACE and TAO. + +Mon Mar 31 11:00:57 UTC 2008 Johnny Willemsen + + * tests/Bug_2980_Regression_Dll.cpp: + * tests/Bug_2980_Regression_Test.cpp: + Fixed fuzz errors + +Mon Mar 31 08:59:57 UTC 2008 Johnny Willemsen + + * tests/OS_Test.cpp: + Added test for ACE_OS::last_error() + +Sun Mar 30 19:54:23 UTC 2008 Iliyan Jeliazkov + + This is the first step of merging the changes from the gestalt + refactoring branch. It includes only changes that are merely + peripheral, without impacting the actual configuration mechanism + - yet. + + * ace/ARGV.h: + * ace/ARGV.cpp: + + Introducing a ctor that takes the number of parameters in argv, + thus eliminating the requirement to have argv 0-terminated. This + requirement can be a hard to satisfy in cases where the argv has + been "manualy constructed", i.e. not provided by the OS + environment. + + * ace/Intrusive_Auto_Ptr.h: + * ace/Intrusive_Auto_Ptr.inl: + * ace/Intrusive_Auto_Ptr.cpp: + + Added an intrusive auto pointer implementation. It is a reference + counted auto pointer that can be used for types with explicit + reference management implementations. + + * ace/OS_NS_unistd.h: + * ace/OS_NS_unistd.cpp: + + Introducing new argv_to_string which takes an explicit argc + argument and relaxes the requirement on argv (to be 0-terminated). + + * ace/Refcounted_Auto_Ptr.h: + * ace/Refcounted_Auto_Ptr.inl: + + Adding a mechanism that provides a correct conversion to boolean + for smart pointers, which preserves the smantics of "if (ap) ..." + without the unwanted side effects. Credit goes to Andrei + Alexandrescu's Modern C++ Design book. + + * ace/Service_Types.cpp: + + Cosmetics: adding this-> to member references. + + * examples/ASX/CCM_App/ASX_CCM_App.mpc: + * examples/ASX/CCM_App/CCM_App.cpp: + + Fixing a problem that precludes the test from running correctly + on *nix - the DLL names are not case-insensitive. Minor layout + changes. + + * tests/Intrusive_Auto_Ptr_Test.cpp: + + A test for the new auto ptr. + + * tests/Bug_2980_Regression_Dll.cpp: + * tests/Bug_2980_Regression_Test.cpp: + * tests/run_test.lst: + * tests/tests.mpc: + + Addded a test for bug 2980. Thanks to Lothar Werzinger for contributing the code. + +Sun Mar 30 18:54:57 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX_Win32.pm: + Handle single quotes in the executable arguments + +Sat Mar 29 08:16:57 UTC 2008 Johnny Willemsen + + * tests/Reactor_Dispatch_Order_Test.cpp: + Dev_Poll reactor displays other bugs, so disable this part of + the test + + * ace/Select_Reactor_Base.cpp: + Position the iterator on the first element that is none zero, fixes + crashing of the reactor_dispatch_order_test on non windows platforms + +Fri Mar 28 17:18:50 UTC 2008 Steve Huston + + * ace/CDR_Stream.cpp (write_long_placeholder, write_short_placeholder): + Be careful to adjust and grow the stream's block before taking + the pointer that's returned to the user. Thanks to Alain Kocelniak + for this fix. + + * ace/CDR_Stream.h: Note that the placeholder methods return 0 if + the method fails due to insufficient memory. + + * THANKS: Added Alain Kocelniak to the Hall of Fame. + +Fri Mar 28 15:40:03 UTC 2008 Chad Elliott + + * tests/unload_libace.mpb: + + Inhert from vc_warnings instead of duplicating part of it's + functionality. + +Fri Mar 28 09:24:25 UTC 2008 Vladimir Zykov + + * bin/tao_orb_tests.lst: + + Enabled a test to Bug_3276_Regression. + +Fri Mar 28 09:17:57 UTC 2008 Johnny Willemsen + + * tests/Reactor_Dispatch_Order_Test.cpp: + Extended this test to also test suspend/resume_handlers and the + dev_poll reactor. Thanks to Russell Morra for extending this test + + * ace/ACE.cpp: + * ace/High_Res_Timer.inl: + Layout changes + + * ace/Hash_Map_Manager_T.cpp: + Use prefix increment instead of postfix + + * ace/High_Res_Timer.h: + * ace/Reactor.h: + * ace/Select_Reactor_Base.h: + Doxygen changes + + * ace/Select_Reactor_Base.inl: + Fixed done implementation. This fixes bugzilla 3267 + + * ace/String_Base.cpp: + Initialise pointer with 0 + + * ace/WFMO_Reactor.{h,cpp,inl}: + Bool changes, fixed implementation of suspend_handlers/resume_handlers, + the to_be_added set modifications where not done correctly + +Thu Mar 27 19:09:57 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + * bin/tao_other_tests.lst: + Diabled 3251/3252 in a static build + +Thu Mar 27 16:27:44 UTC 2008 Adam Mitz + + * ace/Object_Manager.cpp: + + In Win32 debug builds with ACE_DISABLE_WIN32_ERROR_WINDOWS, also + redirect assert messages to stderr instead of GUI message boxes. + +Thu Mar 27 16:17:57 UTC 2008 Johnny Willemsen + + * docs/ACE-bug-process.html: + * docs/ACE-development-process.html: + * docs/ACE-guidelines.html: + * docs/usage-bugzilla.html: + Updated bugzilla location + +Thu Mar 27 15:52:57 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/modules/VXTestProjectCreator.pm: + * bin/MakeProjectCreator/modules/VXTestWorkspaceCreator.pm: + * bin/MakeProjectCreator/templates/vxtest.mpd: + New MPC generator called vxtest. This will generate the loading + of the downloadable kernel modules for an application. + +Thu Mar 27 14:07:27 UTC 2008 J.T. Conklin + + * configure.ac: + + #include in ACE_HAS_BSWAP_{16,32,64} feature tests. + Resolves bugzilla issue #3134. + +Thu Mar 27 12:54:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxworks6.3.GNU: + Small change to get the VxWorks shared library build further + +Thu Mar 27 12:46:48 UTC 2008 Chad Elliott + + * tests/SSL/Thread_Pool_Reactor_SSL_Test.cpp: + + Changed ACE_TMAIN to run_main for the non-threaded portion of the + #ifdef. ACE_TMAIN is defined in Main.cpp. + +Thu Mar 27 12:37:18 UTC 2008 Chad Elliott + + * ASNMP/asnmp/snmperrs.h: + + Added an unknown error code message to the pErrs array to avoid + getting a garbage pointer from Snmp::error_string() in the event + that the error code is outside the valid range. + +Thu Mar 27 11:11:57 UTC 2008 Johnny Willemsen + + * ace/Free_List.cpp: + Fixed ambiguous else with GCC 4.3. Thanks to Jules Colding + for reporting this + +Thu Mar 27 10:36:18 UTC 2008 Simon McQueen + + * include/makeinclude/wrapper_macros.GNU: + + Make it possible to specify an alternate name / location for + platform_macros.GNU. This fixes bug #3269. + +Wed Mar 26 15:32:01 UTC 2008 Adam Mitz + + * bin/MakeProjectCreator/templates/gnu.mpd: + + Corrected my change from yesterday so that it works properly for + executable projects that pull in source files from other directories. + +Tue Mar 25 18:02:52 UTC 2008 Chad Elliott + + * ASNMP/asnmp/wpdu.cpp: + + Added an intermediate integer to avoid type-punned pointer + dereferencing. + +Tue Mar 25 14:19:31 UTC 2008 Adam Mitz + + * bin/MakeProjectCreator/templates/gnu.mpd: + + When generating the linker command line for executable linked against + static libs, exclude the "libFoo.a" form of the libraries. They are + already accounted for by "-lFoo" arguments. This resolved Bugzilla + Bug #3266. + +Tue Mar 25 10:43:57 UTC 2008 Johnny Willemsen + + * netsvcs/lib/Server_Logging_Handler.cpp: + Corrected static template member instantiation to resolve compile + error on OpenVMS Alpha + +Tue Mar 25 10:12:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Disable warnings on IA64 without using GNV, that doesn't work + in all cases + +Tue Mar 25 09:08:57 UTC 2008 Johnny Willemsen + + * ace/INET_Addr.cpp: + Detect sockets that are bigger then ACE_MAX_DEFAULT_PORT. + Thanks to Patrick Rabau for + reporting this. This fixes bugzilla 3264 + + * tests/INET_Addr_Test.cpp: + Added a test for an overflow of the port number + + * ace/Hash_Map_Manager_T.{h,inl}: + Changed head argument of the iterators to a bool + + * ace/Reactor.h: + * ace/Reactor_Impl.h: + Doxygen changes + +Tue Mar 25 00:38:33 UTC 2008 J.T. Conklin + + * ace/Makefile.am: + + Add Configuration.inl to nobase_include_HEADERS. + +Mon Mar 24 16:21:30 UTC 2008 Douglas C. Schmidt + + * ace/OS_NS_Thread.cpp (event_timedwait): Fixed this code so that + it will treat 0 using "wait indefinitely" semantics for Windows + and all other OS platforms. Thanks to Paul Carter for contributing this. + +Mon Mar 24 16:13:51 UTC 2008 Douglas C. Schmidt + + * tests/Manual_Event_Test.cpp (worker): Added a test to ensure + that a null pointer works properly for the + ACE_Manual_Event::wait() method. Thanks to Paul Carter for contributing this. + +Mon Mar 24 15:43:28 UTC 2008 Abdullah Sowayan + + * bin/MakeProjectCreator/config/MPC.cfg: + + MPC can now be configured to recognize ACE_TMAIN as an executable + entry point. We no longer need to explicitly state that a project will + be an executable in the MPC file, MPC will automatically deduce that + the project is an executable given the presence of ACE_TMAIN. + + This change above relates to the following change in MPC: + Mon Mar 24 15:18:28 UTC 2008 Chad Elliott + +Mon Mar 24 02:25:58 UTC 2008 Douglas C. Schmidt + + * COPYING: Updated the license a bit based on feedback from Tom + Callaway" . These changes will + enable ACE+TAO to be shipped with Fedora. + +Fri Mar 21 16:12:53 UTC 2008 Steve Huston + + * ace/OS_NS_unistd.cpp (num_processors_online): Count the online + processors for Windows, not just the number present. + + * tests/OS_Test.cpp: Sanity-check the num_processors_online() value. + +Fri Mar 21 15:10:57 UTC 2008 Johnny Willemsen + + * ace/FoxReactor/FoxReactor.cpp: + Fix 64bit issues, this fixes bugzilla 3248 + This to Thomas Girard + for reporting this + +Fri Mar 21 10:46:57 UTC 2008 Johnny Willemsen + + * m4/ace.m4: + Changed gperf check + + * apps/Makefile.aml: + Updated gperf check. This fixes bugzilla 3249. + This to Thomas Girard + for reporting this + +Fri Mar 21 10:06:57 UTC 2008 Johnny Willemsen + + * ace/config-vxworks.h: + If ACE_VXWORKS is not defined try to figure out which vxworks + version we are using based on some vxworks version defines + + * ace/Select_Reactor_Base.h: + Doxygen changes and made the constructor of + ACE_Select_Reactor_Handler_Repository_Iterator explicit + + * ace/Process.{h,cpp}: + Layout change + +Thu Mar 20 15:34:18 UTC 2008 Chad Elliott + + * bin/MakeProjectCreator/config/acedefaults.mpb: + + Changed the ACE_LD_DECORATOR_STR macro to use $(LIBMODIFIER) + instead of $(ILIBMODIFIER) for the bmake project type. + +Thu Mar 20 12:42:57 UTC 2008 Johnny Willemsen + + * ace/Addr.h: + Layout change + + * ace/High_Res_Timer.cpp: + Changed supported flag to a bool + + * ace/INET_Addr.h: + Doxygen change + + * ace/Svc_Conf.h: + Moved regular include before pragma once + +Wed Mar 19 13:45:00 UTC 2008 Simon Massey + + * ace/tao_orb_tests.lst: + Remove TAO/tests/Bug_1482_Regression from LynxOS. + +Wed Mar 19 11:41:57 UTC 2008 Johnny Willemsen + + * ace/Process_Manager.h: + * ace/Semaphore.h: + * ace/SOCK.h: + * ace/SOCK_IO.h: + Doxygen changes + + * ace/Service_Gestalt.h: + Removed not needed forward declaration + + * ace/OS_NS_Thread.h: + Layout change + +Tue Mar 18 20:17:55 UTC 2008 Steve Huston + + * bin/PerlACE/ProcessLVRT.pm: + * bin/PerlACE/TestTarget_LVRT.pm: Handle timeouts to the target better + and smarten up the way it gets log files from a failed target. + + * bin/PerlACE/TestTarget.pm: + * bin/PerlACE/TestTarget_LVRT.pm: Add a GetFile() method to get a file + from the target to the local machine. By default, it does nothing. + It's meant for use by targets that don't necessarily have locally + accessible file systems, such as LabVIEW RT. + + * bin/Run_Test.pm: + * bin/PerlACE/Process_Win32.pm: Add support for running tests on + LabVIEW RT similarly to the way they're done on VxWorks; TAO tests + run the server on the target and the client on the host. + + * bin/LabVIEW_RT/labview_test_controller/labview_test_controller.cpp: + Catch exceptions and try to report it to stderr before the machine + locks up, dies, etc. + +Tue Mar 18 07:33:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Removed -Wc/DISTINGUISH_NESTED_ENUMS, only needed for one test + +Mon Mar 14 09:17:57 UTC 2008 Johnny Willemsen + + * bin/tao_other_tests.lst: + Added 3252 + +Mon Mar 14 09:07:57 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Added 3251 + +Fri Mar 14 19:57:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_aix_g++.GNU: + Improved support for buildbits=64 + +Fri Mar 14 19:09:57 UTC 2008 Johnny Willemsen + + * ace/INET_Addr.cpp: + Fixe warning with GCC 4.2 on AIX + +Fri Mar 14 19:07:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_aix_g++.GNU: + Disable visibility by default. With GCC 4.2 on AIX we get warnings + that visibility is not supported in that configuration + +Fri Mar 14 15:02:33 UTC 2008 Ciju John + + * bin/tao_other_tests.lst: + Turn on the Notify Persistent_POA test. + +Fri Mar 14 09:30:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_aix_g++.GNU: + Don't use -mcpu=common, that is an ancient default of AIX 5.1 + +Thu Mar 13 12:41:57 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_aix_g++.GNU: + Fixed support for buildbits=32/64 + +Wed Mar 12 19:49:57 UTC 2008 Johnny Willemsen + + Reverted the gperf change below, breaks all autoconf builds + + Wed Mar 12 06:55:57 UTC 2008 Johnny Willemsen + * m4/ace.m4: + Added enable-aio, enable-ipo and fixed gperf handling. + This to Thomas Girard + for reporting this + +Wed Mar 12 15:08:57 UTC 2008 Johnny Willemsen + + * bin/PerlACE/ProcessVX.pm: + Fix retry mechanism for the iBoot bar + +Wed Mar 12 12:59:57 UTC 2008 Johnny Willemsen + + * m4/ace.m4: + Added support for fox, thanks to Thomas Girard + for reporting this. + This fixes bugzilla 3147 + +Wed Mar 12 11:59:57 UTC 2008 Johnny Willemsen + + * ace/FoxReactor/FoxReactor.{h,cpp}: + Removed check for ACE_HAS_FOX + + * include/makeinclude/wrapper_macros.GNU: + Changed fox handling, matches the other reactors. Thanks to + Thomas Girard for + reporting this. This resolves bugzilla 3248 + + * include/makeinclude/platform_aix_ibm.GNU: + Added support for Visual Age 9 + +Wed Mar 12 11:53:57 UTC 2008 Johnny Willemsen + + * ace/FoxReactor/FoxReactor.h: + Added missing include, thanks to Thomas Girard + for reporting this + +Wed Mar 12 07:07:57 UTC 2008 Johnny Willemsen + + * ace/FoxReactor/FoxReactor.cpp: + Fixed compile errors, thanks to Thomas Girard + for reporting this + +Wed Mar 12 06:59:57 UTC 2008 Johnny Willemsen + + * ace/ace.mwc: + * bin/MakeProjectCreator/config/global.features: + Added fox reactor, thanks to Thomas Girard + for reporting this + +Wed Mar 12 06:55:57 UTC 2008 Johnny Willemsen + + * m4/ace.m4: + Added enable-aio, enable-ipo and fixed gperf handling. + This to Thomas Girard + for reporting this + +Tue Mar 11 12:24:43 UTC 2008 Steve Huston + + * ace/Svc_Conf.h: Add #include "ace/config.h" so a setting for + ACE_LACKS_PRAGMA_ONCE can be seen. Fixes compile warnings. + +Tue Mar 11 12:20:02 UTC 2008 Steve Huston + + * ace/Log_Msg.cpp (log): Fixed compile error. No need to use + ACE_TEXT_ALWAYS_CHAR for a char* literal. + +Mon Mar 10 22:27:09 UTC 2008 Nanbor Wang + + * ace/Svc_Conf.h: Removed redundant inclusion of Obstack.h. It is + included later in Svc_Conf_Param.h. Removing this extra + inclusion allows us to build on MacOS Leopard with optimization + enabled. + +Mon Mar 10 15:35:02 UTC 2008 Steve Huston + + * ace/Log_Msg.{h cpp} (log): For %C, clearly note that it always prints + a narrow-char string, and adjust the va_arg to match. Thanks to + Russell Morra for reporting this issue. + +Mon Mar 10 13:20:57 UTC 2008 Johnny Willemsen + + * tests/Multicast_Test.cpp: + When sending fails, print the ip address we are using in the error + message. + +Sat Mar 8 16:23:57 UTC 2008 Douglas C. Schmidt + + * ace/WIN32_Asynch_IO.cpp (send): Enhanced the code to allow sends + of 0-sized datagrams. Thanks to Andi Heusser for this fix. + +Thu Mar 6 16:49:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/rules.lib.GNU: + Rearranged some rules to make sure c/C files are compiled with the + C compiler on OpenVMS + +Thu Mar 6 13:10:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Improved this file + +Thu Mar 6 10:33:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Removed restriction that only a shared or static build can be done + +Wed Mar 5 07:54:18 UTC 2008 Johnny Willemsen + + * bin/tao_orb_tests.lst: + Don't run the parallel connect strategy test on VxWorks 5.5, the + command length of the shell is not long enough. + +Tue Mar 4 09:27:18 UTC 2008 Johnny Willemsen + + * bin/ProcessVX.pm: + Added a retry to the iPass protocol code, in a full test run + we sometimes see that the reboot has failed. With this retry + we hopefully get rid of those false test failures + +Tue Mar 4 05:54:22 UTC 2008 William Otte + + * bin/svn_props.py: + Automatically set default properties when svn complains. + +Mon Mar 3 11:22:18 UTC 2008 Johnny Willemsen + + * bin/MakeProjectCreator/templates/bor.mpd: + Just single line comments + + * bin/MakeProjectCreator/templates/gnu.mpd: + Check VXWORKSLINK for 1 + +Mon Mar 3 11:10:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxworks5.5.x.GNU: + * include/makeinclude/platform_vxworks6.2.GNU: + * include/makeinclude/platform_vxworks6.3.GNU: + * include/makeinclude/rules.bin.GNU: + * include/makeinclude/rules.lib.GNU: + Use 1 for VXWORKSLINK instead of true. Added footprint=1 + as flag to specify that you are doing a footprint build + +Mon Mar 3 10:49:28 UTC 2008 Abdullah Sowayan + + * apps/JAWS/clients/WebSTONE/src/cgi-send.c: + * apps/JAWS/clients/WebSTONE/src/genrand.c: + * apps/JAWS/clients/WebSTONE/src/webmaster.c: + * contrib/utility/Example/CommandLine/Foo/command.cpp: + * contrib/utility/Example/ExH/BadCast/bad_cast.cpp: + * contrib/utility/Example/ExH/Compound/compound.cpp: + * contrib/utility/Example/ExH/HelloWorld/hello_world.cpp: + * contrib/utility/Example/ExH/LogicToSystem/logic_to_system.cpp: + * contrib/utility/Example/Hetero/Container/container.cpp: + * contrib/utility/Example/Introspection/InheritanceTree/inheritance_tree.cpp: + * contrib/utility/Example/Introspection/Traversal/driver.cpp: + * contrib/utility/Test/ExH/Converter/converter.cpp: + * contrib/utility/Test/ExH/Inline/inline.cpp: + * contrib/utility/Test/ExH/Logic/DescriptiveException/descriptive_exception.cpp: + * contrib/utility/Test/ExH/System/DescriptiveException/descriptive_exception.cpp: + * contrib/utility/Test/Introspection/Inline/inline.cpp: + * contrib/utility/Test/Synch/Inline/inline.cpp: + * etc/xlc_dummy.cpp: + * examples/Reactor/Proactor/test_aiocb.cpp: + * examples/Reactor/Proactor/test_aiosig.cpp: + + Disable fuzz's check_for_improper_main_declaration check on these files. + These files don't use ACE. + + * examples/Reactor/WFMO_Reactor/Multithreading.cpp: + * examples/Reactor/WFMO_Reactor/Registration.cpp: + * examples/Reactor/WFMO_Reactor/Registry_Changes.cpp: + * examples/Threads/task_three.cpp: + + Use the proper form of ACE_TMAIN. Namely, the argv parameter + should be "ACE_TCHAR *argv[]" instead of "ACE_TCHAR **argv" + or "ACE_TCHAR *[]" instead of "ACE_TCHAR **" + + * apps/JAWS3/bench/average.cpp: + * netsvcs/clients/Tokens/invariant/invariant.cpp: + + Use ACE_TMAIN instead of main as the program entry point to comply + with ACE/TAO/CIAO coding standards. + +Mon Mar 3 08:58:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Improved this file + +Mon Mar 3 07:30:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Don't set INSLIB + +Mon Mar 3 07:00:18 UTC 2008 Johnny Willemsen + + * include/makeinclude/rules.local.GNU: + Rearranged some rules so that C files are compiled with the + C compiler on OpenVMS + +Mon Mar 3 06:57:18 UTC 2008 Johnny Willemsen + + * bin/ProcessVX.pm: + Added support to specify a custom password for the iBoot + +Sun Mar 2 20:04:18 UTC 2008 Johnny Willemsen + + * bin/ProcessVX.pm: + Integrated some OCI changes for the iBoot + +Sun Mar 2 19:32:18 UTC 2008 Johnny Willemsen + + * bin/auto_run_tests.pl: + Use ACE_ROOT as defailt root test directory instead of the current + directory + +Sun Mar 2 18:53:12 UTC 2008 Abdullah Sowayan + + * ASNMP/agent/main.cpp: + * ace/Svc_Conf_y.cpp: + * apps/JAWS3/jaws3/main.cpp: + * examples/Mem_Map/IO-tests/test_io.cpp: + * examples/Reactor/Multicast/client.cpp: + * examples/Reactor/Multicast/server.cpp: + * examples/Reactor/Proactor/test_aiocb_ace.cpp: + * examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.cpp: + * netsvcs/clients/Naming/Dump_Restore/createfile.cpp: + * netsvcs/clients/Tokens/collection/collection.cpp: + * netsvcs/clients/Tokens/collection/rw_locks.cpp: + * netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp: + * netsvcs/clients/Tokens/invariant/invariant.cpp: + * netsvcs/clients/Tokens/manual/manual.cpp: + * netsvcs/clients/Tokens/mutex/test_mutex.cpp: + * netsvcs/clients/Tokens/rw_lock/rw_locks.cpp: + * performance-tests/Misc/context_switch_time.cpp: + * performance-tests/Misc/test_guard.cpp: + * performance-tests/Server_Concurrency/Leader_Follower/RT_CORBA_Leader_Follower.cpp: + * performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.cpp: + * performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp: + + Use ACE_TMAIN instead of main as the program entry point to comply + with ACE/TAO/CIAO coding standards. + + * examples/Mem_Map/IO-tests/Mem_Map_IO_Tests.mpc: + + MPC doesn't recognize ACE_TMAIN as an entry point, as such, we need + to explicitly set exename in the MPC file. + + * apps/JAWS/clients/WebSTONE/src/webclient.c: + * contrib/utility/Example/CommandLine/Foo/foo.cpp: + * performance-tests/Synch-Benchmarks/context.c: + * performance-tests/TTCP/C/new-ttcp.cpp: + * tests/Unload_libACE.cpp: + + Disable fuzz's check_for_improper_main_declaration check on these files. + These files don't use ACE. + +Sat Mar 1 19:09:18 UTC 2008 Johnny Willemsen + + * bin/auto_run_tests.pl: + Added -r as option to specify an alternate root test directory + instead of the current directory. Combined this with -l we can + then run perl scripts for testing project code. + +Thu Feb 28 16:08:18 UTC 2008 Johnny Willemsen + + * bin/generate_compile_stats.sh: + Added --compiler as option so that we can specify a different + compiler then gcc + +Thu Feb 28 08:32:18 UTC 2008 Johnny Willemsen + + * docs/ACE-bug-process.html: + Removed cvs + +Wed Feb 27 19:28:18 UTC 2008 William Otte + + * bin/MakeProjectCreator/config/global.features: + disable mcpp by default. + +Tue Feb 26 15:52:37 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Added support for buildbits=64 + +Tue Feb 26 09:18:37 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + Added some compiler flags to reduce the number of warnings/errors + in the OpenVMS builds + +Mon Feb 25 19:44:37 UTC 2008 Johnny Willemsen + + * bin/PerlACE/Process_Unix.pm: + * bin/PerlACE/Process_Win32.pm: + Added IgnoreHostRoot which can be set from a test script. That way + when doing cross host testing we can make sure we don't get the + executable from the host root directory. This is for example usefull + when we want to spawn perl or another system utility + + * bin/PerlACE/Run_Test.pm: + Removed commented out line + +Mon Feb 25 14:30:37 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_vxwork6.2.GNU: + * include/makeinclude/platform_vxwork6.3.GNU: + Added LD_PARTIALFLAGS which can be set for footprint builds + +Mon Feb 25 08:13:37 UTC 2008 Johnny Willemsen + + * ace/config-macros.h: + Set ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN when + ACE_THR_FUNC_RETURN is an integral type + + * ace/Task.cpp: + Use ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN to determine whether + we can do a reinterpret_cast or static_cast. This is much easier + then checking all compilers + +Sun Feb 24 19:37:37 UTC 2008 Johnny Willemsen + + * ace/Configuration.cpp: + * ace/Configuration.h: + * ace/Configuration.inl: + Added new inline file + + * ace/Get_Opt.cpp: + Prefix increment + + * ace/Event_Handler.h: + Removed commented out code + +Sat Feb 23 06:56:37 UTC 2008 Johnny Willemsen + + * include/makeinclude/platform_openvms.GNU: + OpenVMS doesn't have rwho + +Fri Feb 22 18:55:37 UTC 2008 Johnny Willemsen + + * ace/Message_Queue_NT.h: + Fixed wrong include + +Fri Feb 22 14:20:37 UTC 2008 Johnny Willemsen + + * ace/Message_Queue.{h,cpp,inl}: + * ace/Message_Queue_NT.{h,cpp,inl}: + * tests/Message_Queue_Test.cpp: + * ace/ace.mpc: + * ace/Makefile.am: + Moved ACE_Message_Queue_NT to its own file + +Fri Feb 22 08:54:37 UTC 2008 Johnny Willemsen + + * bin/global.features: + Default optimize_collocated_invocations to 1 + +Fri Feb 22 00:34:17 UTC 2008 Steve Huston + + * bin/tao_orb_tests.lst: Added !LabVIEW_RT to all tests that haven't + been adapted to the non-local filesystem mechanism I invented to run + tests for LabVIEW RT targets (and can also be used for other target + types). Now I can enable TAO tests for the LabVIEW RT scoreboard + build. + +Thu Feb 21 15:25:37 UTC 2008 Johnny Willemsen + + * docs/Download.html: + Updated download links to point to x.6.3 + + * etc/index.html: + Updated for x.6.3 + +Thu Feb 21 02:34:37 CST 2008 Johnny Willemsen + + * ACE version 5.6.3 released. + +Local Variables: +mode: change-log +add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time)) +indent-tabs-mode: nil +End: diff --git a/dep/ACE_wrappers/FAQ b/dep/ACE_wrappers/FAQ new file mode 100644 index 000000000..c184fbde8 --- /dev/null +++ b/dep/ACE_wrappers/FAQ @@ -0,0 +1,1847 @@ +There are many changes and improvements in the new version of ACE. +The ChangeLog file contains complete details about all of them. + +I've tested ACE thoroughly on Solaris 2.3 and 2.4 with the SunC++ 4.x +compiler and Centerline 2.x. I've also tested it with the SunC++ 3.x +compiler on the SunOS 4.x platform. However, I've not been able to +test it on other platforms. If anyone has time to do that, and can +report the results back to me I'd appreciate that. + +Please let me know if you have any questions or comments. + + Doug + +---------------------------------------- + +1. SIGHUP + +> 1) Where the heck does the HUP signal get registered for the +> $ACE_ROOT/tests/Service_Configurator/server stuff? I looked there and +> in $ACE_ROOT/libsrc/Service_Configurator. No luck. I guess I am +> just blind from reading. + + Take a look in ./libsrc/Service_Configurator/Service_Config.h. +The constructor for Service_Config is where it happens: + + Service_Config (int ignore_defaults = 0, + size_t size = Service_Config::MAX_SERVICES, + int signum = SIGHUP); + +---------------------------------------- +2. Multi-threaded Signal_Handler support + +> It appears Signal_Handler is +> not setup for multi-threaded apps. How do you handle signals +> in different threads? Do I have to put in the hooks in my app or should +> it go in the Threads arena? + + Ah, good question... My design follows the approach espoused +by Sun. Basically, they suggest that you implement per-thread signal +handling atop of the basic UNIX signal handlers (or in the case of +ACE, the handle_signal() callbacks on Event_Handler subclasses) by +using the thread id returned by thr_self() to index into a search +structure containing the handlers. This should be pretty straight +forward to layer atop the existing ACE Signal_Handler mechanisms. +However, you might ask yourself whether you really want (1) separate +signal handler *functionality* in different threads or (2) different +threads that mask out certain signals. The latter might be easier to +implement and reason about! + +---------------------------------------- +3. Problems compiling ACE with G++ + +> I substituted -lg++ for -lC in macro_wrappers.GNU and ran make. +> +> Most stuff seemed to build. Continually got messages like the following: +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libASX.a: warning: archive has no table of c +> ontents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libThreads.a: warning: archive has no table +> of contents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libSPIPE.a: warning: archive has no table of +> contents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libASX.a: warning: archive has no table of c +> ontents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libThreads.a: warning: archive has no table +> of contents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libSPIPE.a: warning: archive has no table of +> contents; add one using ranlib(1) + +> no matter how many times I used ranlib or removed the libraries and re-compiled +> or whatever. Perhaps these are System V specific and will not work on 4.1.3? + + Yes, that's exactly right. If you look at the files, they all +contain ifdef's for features that aren't included in the +./include/makeinclude/wrapper_macros.GNU file. To make this more +obvious, I've enclosed the following message in the ACE-INSTALL.html file: + + * Sun OS 4.1.x + + Note that on SunOS 4.x you may get warnings from the + linker that "archive has no table of contents; add + one using ranlib(1)" for certain libraries (e.g., + libASX.a, libThreads.a, and libSPIPE.a). This + occurs since SunOS 4.x does not support these features. + +> never able to get .so -- assume these are shared libraries that gcc can not +> deal with. + + Yes, if you use the stock gcc/gas/gnu ld +compiler/assembler/linker, you won't get shared libraries to work. It +is possible to hack this by using the "collect" version of g++. +However, as usual, I strongly advise people to stay away from g++ if +you want to use shared libraries or templates. + +> got some linker errors as follows: +> +> g++ -g -DACE_NTRACE -DACE_HAS_MT_SAFE_SOCKETS -DACE_HAS_NO_T_ERRNO -DACE_HAS_ +> OLD_MALLOC -DACE_HAS_POLL -DACE_HAS_SEMUN -DACE_HAS_SETOWN -DACE_HAS_STRBUF_T - +> DACE_HAS_STREAMS -DACE_HAS_SVR4_DYNAMIC_LINKING -DACE_HAS_TIUSER_H -DACE_HAS_SY +> S_FILIO_H -DACE_PAGE_SIZE=4096 -DACE_HAS_ALLOCA -DACE_HAS_CPLUSPLUS_HEADERS -DA +> CE_HAS_SVR4_SIGNAL_T -DACE_HAS_STRERROR -DMALLOC_STATS -I/usr2/tss/jvm/ACE_wrap +> pers/include -I/usr2/tss/jvm/ACE_wrappers/libsrc/Shared_Malloc -o test_malloc +> .obj/test_malloc.o -L/usr2/tss/jvm/ACE_wrappers/lib -Bstatic -lSemaphores -lS +> hared_Malloc -lShared_Memory -lReactor -lThreads -lMem_Map -lLog_Msg -lFIFO -lI +> PC_SAP -lMisc -lnsl -lg++ +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libThreads.a: warning: archive has no table +> of contents; add one using ranlib(1) +> ld: Undefined symbol +> _free__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEXPv +> _free__t6Malloc2Z17Local_Memory_PoolZ10Null_MutexPv +> _malloc__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEXUl +> _malloc__t6Malloc2Z17Local_Memory_PoolZ10Null_MutexUl +> _remove__t6Malloc2Z17Local_Memory_PoolZ10Null_Mutex +> ___t6Malloc2Z17Local_Memory_PoolZ10Null_Mutex +> _print_stats__t6Malloc2Z17Local_Memory_PoolZ10Null_Mutex +> _remove__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEX +> ___t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEX +> _print_stats__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEX +> collect2: ld returned 2 exit status +> gcc: file path prefix `static' never used +> make[2]: *** [test_malloc] Error 1 +> make[2]: Leaving directory `/usr2/tss/jvm/ACE_wrappers/tests/Shared_Malloc' +> <======== End all: /usr2/tss/jvm/ACE_wrappers/tests/Shared_Malloc + + That looks like a problem that G++ has with templates. I +don't know of any reasonable solution to this problem using g++. + +> Finally decided there was enough stuff that it looked like I might have some +> thing so I tried to run some tests and could not find so much as one piece +> of documentation that might give me some clue about running tests. + +You should take a look at ./tests/Service_Configurator/server/README +file. That explains how to run the more complicated tests. As for +the other tests, it is pretty straight forward if you look at the +./tests/IPC_SAP/SOCK_SAP and ./tests/Reactor/* directory code to +figure out how to run the tests. I don't have a Q/A department, so +any documentation has to come from volunteers. + +---------------------------------------- +4. Is there any docs or man pages on the Log_Record class? + +There is a paper in the C++_wrappers_doc.tar.Z file on ics.uci.edu +called reactor2.ps that has some examples of using Log_Record. The +./apps/Logger directories show several examples using Log_Record. +Finally, the source code for Log_Record is pretty short (though it +clearly could be commented better ;-)). + +---------------------------------------- +5. Signal handling prototypes + +> According to the man page on sigaction on our system, that line +> should look something like the following: +> +> sa.sa_handler = SIG_DFL; + + The problem is that most versions of UNIX I've come across +don't have a correct prototype for this field of struct sigaction. +That's why I define two variants of signal handler typedefs: one that +is a typedef of the "correct version" (which I call SignalHandler) and +one of which is a typedef of the "incorrect version" (which I call +SignalHandlerV). You might check out the sysincludes.h file to see +how it is defining SignalHandlerV and make sure this matches what your +OS/Compiler defines in + +---------------------------------------- +6. Omitting shared libraries + +> Can anyone tell me a way to turn off the creation of the shared libraries +> in the ACE build. + +You can simply comment out the LIB target in the $ACE_ROOT/ace/Makefile +or change the BUILD target from + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) + +to + +BUILD = $(VSHLIB) $(SHLIBA) + +---------------------------------------- +7. DCE threading and signal handling + +>Reading the DCE docs leaves me confused as to how to make everyone +>work together in a happy hormonious whole. May basic need is to catch +>asynchronous signals so i can release some global resources before +>the process exits. + +You need to spawn a separate thread to handle signals. As part of +your init, do this: + pthread_create(&tid, thread_attr, signal_catcher, NULL); + pthread_detach(&tid); + +Where signal_catcher is like this: +static void * +signal_catcher(void *arg) +{ + static int catch_sigs[] = { + SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGCHLD + }; + sigset_t catch_these; + int i; + error_status_t st; + + for ( ; ; ) { + sigemptyset(&catch_these); + for (i = 0; i < sizeof catch_sigs / sizeof catch_sigs[0]; i++) + sigaddset(&catch_these, catch_sigs[i]); + i = sigwait(&catch_these); + /* Note continue below, to re-do the loop. */ + switch (i) { + default: + fprintf(stderr, "Caught signal %d. Exiting.\n", i); + CLEANUP_AND_EXIT(); + /* NOTREACHED */ +#if defined(SIGCHLD) + case SIGCHLD: + srvrexec__reap(); + continue; +#endif /* defined(SIGCHLD) */ + } + } + return NULL; +} +---------------------------------------- +8. + +> I have installed ACE2.15.5 on SunOS 4.1.3 with gcc2.6.0. I run the test program +> ---server_test. The static is OK, but error found when I commented out the first +> one and uncommented out the second one in the svc.conf file: +> +> #static Svc_Manager "-d -p 3912" +> dynamic Remote_Brdcast Service_Object * .shobj/Handle_Broadcast.so:remote_broad +> cast "-p 10001" +> +> The error goes like this: +> +> ----------- +> jupiter[12] %server_test -d +> starting up daemon server_test +> opening static service Svc_Manager +> did static on Svc_Manager, error = 0 +> signal signal 1 occurred +> beginning reconfiguration at Sat Feb 25 13:40:29 1995 +> Segmentation fault (core dumped) +> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +My guess is that the code generated by GCC on SunOS 4.x does not +correctly initialize static variables from shared libraries. The +SunC++ 4.0.x compiler does this correctly on Solaris 2.x (though I +believe that on SunOS 4.x it doesn't work without some extra coaxing). + +In general, I try to avoid using ACE's explicit dynamic linking +mechanisms on SunOS 4.x and GCC. You can write plenty of interesting +and useful code with ACE without using those features. Those tests +are mostly there to illustrate the "proof of concept." +---------------------------------------- +9. + +> a) I noticed the default constructor for the reactor does an open w/ defaults. +> Does this mean I need to close it if I wish to re-open it with different +> size and restart values? + + No. With the latest versions of ACE, you can now just call +open() with a new size and it will correctly resize the internal +tables to fit. + +> b) What is the usage difference between the normal FD_Set objects +> (rd/wr/ex_handle_mask_) and the ready FD_Set objects +> (rd/wr/ex_handle_mask_ready)? + + The normal FD_Sets (now called Handle_Set in ACE 3.0.5) holds +the "waitable" descriptors (these are the descriptors given to +select() or poll()). In contrast, the ready FD_Sets may be set by +Event_Handler subclasses (by called the set_ready() API) to indicate +to the Reactor that they want to be redispatched on the next go-round +*without* blocking. If you look at the Reactor code, you'll see that +the wait_for() method checks the ready sets first and doesn't block if +there are any bits set in those masks. This features makes it +possible for Event_Handlers to control subsequent dispatching policies +of the Reactor. + +> c) What does the positive return value do from an event handler callback: +> -1 detaches the event handler for that mask +> 0 does nothing - keeps the event handler registered for that mask +> >0 resets a bit in the current dispatching mask (I think) - does this mean +> this event will be called again before the current dispatch cycle is done? + +Almost... (it's tied in with my description of the ready sets above). +It means that once the Reactor finishes cycling through the set of +descriptors it got back from select() or poll(), it will redispatch +the ready set descriptors before sleeping. + +> Without direct access to the bit masks in X, I'm not sure I could emulate +> this activity - what do you think? + +I'm not sure. I'm not enough of an X guru. Maybe someone else on the +list knows the answer to this? + +> d) If I let X do the select blocking, will that have any affect on +> the Reactor performing signal handling? + + Yes, I think that will cause problems since the Reactor relies +on a "handshake" between its Signal_Handler component and its +handle_events loop to properly handle signals. + +> e) Is the Poll method preferred over Select if it is available - why? + +For systems that implement select() in terms of poll() (e.g., Solaris +2.x) then it may be somewhat faster. Otherwise, it doesn't really +matter since (1) they (should) do the same thing and (2) the end user +shouldn't notice any change in behavior. + +---------------------------------------- +10. + +> I would very much like to evaluate/use the ACE Toolkit, +> but am limited as to disk space on our system. +> What is the total disk space required for a compiled, +> usable toolkit? + +The source code itself is around 2 Meg, uncompressed. + +The compiled version of ACE is around 90 Meg compiled with the SunC++ +4.x compiler (naturally, this will differ with other compilers). +However, of this amount, about 40 meg are for the libraries, and +another 50 meg are for the test programs. Naturally, you don't need +to keep the test programs compiled. + +The postscript documentation is around 5 Meg, compressed. + +---------------------------------------- +11. + +> This is regarding the newer release of ACE and pertaining to the library +> archive file. My question is, if all the ".o" files are archived into one +> single "libACE.a", does it increase the size of the executable program? + +No. The use of a *.a file allows the linker to extract out only those +*.o files that are actually used by the program. + +> If it does, then does a large executable program mean possibility of it being +> slower? + + No. + +---------------------------------------- +12. + +> What happens if I have several reactors in a process (e.g. in different +> threads)? +> +> Programmer 1 decides to register at reactor 1 in his thread 1 a signal handler +> for SIGUSR. +> Programmer 2 decides to register at reactor 2 in his thread 2 a signal handler +> for SIGUSR. + + Naturally, the behavior of this all depends on the semantics +of the threads package... In Solaris 2.x, signal handlers are shared +by all threads. Moreover, the Reactor uses a static table to hold the +thread handlers. Thus, only one of the handler's would be registered +(i.e., whichever one was registered second). + +> Programmer 3 designs the process and decides to have thread 1 and thread 2 +> running in the same process and also makes use of a third party software library +> that internally has also registered a signal handler (not at the reactor) for +> SIGUSR. + + Now you've got big problems! This is an example of a +limitation with UNIX signal handlers... In general, it's a bad idea +to use signal handlers if you can avoid it. This is yet another +reason why. + +> When looking into Ace/ACE_wrappers/tests/Reactor/misc/signal_tester.C you +> have shown a way to do this by marking the dummy file_descriptor of the +> Sig_Handler object ready for reading asynchronously. The handle_input() +> routine of Sig_Handler object will then be dispatched synchronously. +> But what happens if I have several reactors. +> The asynchronously dispatched +> handle_signal() routine does not know via which reactor it has been registered +> so in which reactor to modify the dummy file_descriptor. +> Is your suggestion to have just one process global reactor in such a case? + + Yes, precisely. I would *strongly* recommend against using +several reactors within separate threads within the same process if +you are going to be having them handle signals. Can you use 1 +reactor and/or have one reactor handle signals within a process? + +> One thing we want to do is the priorization of Event_Handlers. I.e. in case +> of concurrent events the sequence in which the Event_Handler methods will be +> activated depends on their priority relative to each other. +> We have two choices: +> - complete priorization, which means a high priority Input Event_Handler may +> be activated prior to a lower prioritized Output Event_Handler (and doing +> so violating the 'hardcoded rule' that output must be done prior to input). +> - priorization only in categories, which means all Output Event_handler are +> ordered by their priority regardless of priorities for the category of Input +> Event_Handlers. The priority is fixed between the categories, i.e. first +> output then input then out-of-band. +> +> Right now I would think that we have to use the second choice if we want to +> use the feature of asynchronous output with automatical re-queueing. Am I right +> ? + + Hum, that's an interesting problem. It might be better to +subclass the Reactor to form a new class called Priority_Reactor. +This subclass would override the Reactor's dispatch method and +dispatch the event handlers in "priority" order. I've never done +that, but I don't think it would be all that difficult. + +---------------------------------------- +13. + +> Is the Orbix (aka CORBA) version still around? + +Nope, IONA does not support Orbix-2.X nor Orbix-3.0 anymore (the +versions of Orbix that the ACE code was based upon). Plus we didn't +maintain this code for ages, so it probably was broken too. + +---------------------------------------- +14. +> We are using your ACE software and ran into a problem which may or may not +> be related to the mutex locks. The question may have more to do with how +> mutex locks should be used. We had a class which was using your mutex +> lock wrapper. Each member function of the class acquired the lock before +> processing and released on exiting the function. Some member functions may +> call other member functions. The following is an example: +> +> class foo { +> +> void a() +> { +> MT( Mutex_Block m( this->lock_ )); +> +> if( cond ) +> b(); +> } +> +> void b() +> { +> MT( Mutex_Block m( this->lock_ )); +> +> if( cond ) +> a(); +> } +> +> }; +> +> Is this valid ? My assumtpion is that the mutex lock is recursive and +> the same thread can acquire the lock multiple times in different member +> functions. + + Ah, that's a great question since there are subtle and +pernicious problems lurking in the approach you are trying above. +Basically, Solaris mutex locks are *not* recursive (don't ask why...) +Thus, if you want to design an application like the one above you'll +need to use one or more of the following patterns: + +---------------------------------------- +A. Use recursive mutexes. Although these are not available in + Solaris directly they are supported in the later versions + of ACE. You might want to take a look at the latest + version (./gnu/ACE-3.1.9.tar.Z). It's got lots of new + support for threading and synchronization. In that case, + you simply do the following: + + class Foo + { + public: + void a() + { + MT( Guard > m( this->lock_ )); + b (); + } + + void b() + { + MT( Guard > m( this->lock_ )); + b_i (); + } + + }; + + The advantage with this is that it requires almost no + changes to existing code. The disadvantage is that + recursive locks are just slightly more expensive. + +B. Have two layers of methods (a) which are public and acquire + the Mutex and then call down to methods in layer (b), which + are private and do all the work. Methods in layer b assume + that the locks are held. This avoids the deadlock problem + caused by non-recursive mutexes. Here's what this approach + looks like (using the more recent ACE class names): + + class Foo + { + public: + void b() + { + MT( Guard m( this->lock_ )); + b_i (); + } + + void b_i() + { + if( cond ) + a_i(); + } + + void a_i() + { + if( cond ) + b_i(); + } + + void a() + { + MT( Guard m( this->lock_ )); + a_i (); + } + + }; + + The advantage here is that inline functions can basically + remove all performance overhead. The disadvantage is that + you need to maintain two sets of interfaces. + +C. Yet another approach is to release locks when calling + other methods, like this: + + class Foo + { + public: + void b() + { + MT( Guard m( this->lock_ )); + m.release (); + a (); + m.acquire (); + } + + void a() + { + MT( Guard m( this->lock_ )); + m.release (); + b (); + m.acquire (); + } + + }; + + The disadvantage with this, of course, is that you + greatly increase your locking overhead. In addition, + you need to be very careful about introducing race + conditions into the code. The primary reason for + using this approach is if you need to call back to + code that you don't have any control over (such as + OS I/O routines) and you don't want to hold the + lock for an indefinite period of time. +---------------------------------------- + + BTW, all three of these patterns are used in the ACE Reactor +class category. The Reactor has a number of fairly complex +concurrency control and callback issues it must deal with and I've +found it useful to use all three of these patterns jointly. + + I'd be interested to hear any comments on these approaches. + + Doug +---------------------------------------- +15. + +> I am working on Solaris 2.3 and trying to understand how to get around +> the problem of trying to open a Socket connection to a remote host that +> is "dead". Of course you get a nice long process block if the socket +> is in Blocking mode (TCP lets you know when you can continue - how polite). +> +> So how does a non-blocking connect work with respect to using +> the Reactor and a SOCK_Stream object to coordinate the opening +> of the connection? Do I wait on the OUTPUT event for the FD? +> How do I know if the connect worked or possibly timed-out? Is +> this a reliable approach (I read somewhere that this will only +> work if the STREAMS module is at the top of the protocol stack +> - MAN page I think)? + +An example of implementing this is in the Gateway sample application +in the new ACE. It's also encapsulated in the Connector<> pattern of +the Connection class category in ./libsrc/Connection. You may want to +take a look at those two things for concrete usage examples. + +However, the basics of getting non-blocking to work are: +- set socket to non-blocking +- initiate connect() request +- if connect() returned 0 you're connected +- if connect() returned -1 and errno is EWOULDBLOCK (or EAGAIN, depending +on where you are), then register an event handler for read and write events +on the socket +- any other errno value is fatal + +When an event is returned +- no matter which event you get back (read or write), you may have gotten +the event out of error. Thus, re-attempt the connect() and check to see if +errno is EISCONN (if it's not there's a problem!) +- if errno was EISCONN, the connection is ready to go, otherwise you must +handle an error condition + +If you want to "time out" after a certain period of time, consider +registering for a timer event with Reactor. If the timer goes off before +the connection succeeds, close down the appropriate socket. + +> Is using a separate thread to make the connection a better way to avoid +> the potentialy long block in the main thread during the connect call? + +You could do that, but it can all be accomplised in a single process using +the facilities available. +---------------------------------------- +16. + +> I was wondering, does the Reactor class have the ability to prioritize +> activity on the registered event handlers? + + The default strategy for the Reactor's dispatch routine +(Reactor::dispatch) does not prioritize dispatching other than to +dispatch callbacks in ascending order from 0 -> maxhandlep1. + +> We have a requirment to be able to process both real-time, as well as, stored +> telemetry and ERMs concurrently. Real-time needs to be processed at a higher +> priority than stored data. Our design is based on both real-time and stored +> data coming into our process via separate sockets. + + I can think of several ways to do this: + + 1. Use dup() or dup2() to organize your sockets such that the + higher priority sockets come first in the Handle_Sets that + the Reactor uses to dispatch sockets. This is pretty easy + if you don't want to muck with the Reactor code at all. + + 2. You could subclass Reactor::dispatch() and revise it so + that it dispatches according to some other criteria that + you define in order to ensure your prioritization of + sockets. + +BTW, I'm not sure what you mean by "real-time" but I assume that you +are aware that there is no true "real-time" scheduling for network I/O +in Solaris. However, if by "real-time" you mean "higher priority" +then either of the above strategies should work fine. +---------------------------------------- +17. + +> I compiled the new ACE 3.2.0 's apps/Gateway. The compiling went +> through without any errors. But I could not get it running, neither single +> threaded nor multi-threaded. The cc_config and rt_config files entries are given +> below. Also the machine configurations are given below. Does it need some more +> settings or some patch !!?? + + I believe you are seeing the effects of the dreaded Sun MP bug +with non-blocking connects. The easy work around for now is simply to +give the "-b" option to the Gateway::init() routine via the svc.conf +file: + +dynamic Gateway Service_Object *.shobj/Gateway.so:_alloc_gatewayd() active + "-b -d -c cc_config -f rt_config" + +If you check line 137 of the Gateway::parse_args() method you'll see +what this does. +---------------------------------------- +18. + +How to get ACE to work with GCC C++ templates. + +The first and foremost thing to do is to get the latest version of GCC +(2.7.2) and also get the template repository patches from + +ftp://ftp.cygnus.com/pub/g++/gcc-2.7.1-repo.gz + +This will get the ball rolling... + +Here is some more info on G++ templates courtesy of Medhi TABATABAI +: + +Where's the Template? +===================== + + C++ templates are the first language feature to require more +intelligence from the environment than one usually finds on a UNIX +system. Somehow the compiler and linker have to make sure that each +template instance occurs exactly once in the executable if it is +needed, and not at all otherwise. There are two basic approaches to +this problem, which I will refer to as the Borland model and the +Cfront model. + +Borland model + Borland C++ solved the template instantiation problem by adding + the code equivalent of common blocks to their linker; template + instances are emitted in each translation unit that uses them, and + they are collapsed together at run time. The advantage of this + model is that the linker only has to consider the object files + themselves; there is no external complexity to worry about. This + disadvantage is that compilation time is increased because the + template code is being compiled repeatedly. Code written for this + model tends to include definitions of all member templates in the + header file, since they must be seen to be compiled. + +Cfront model + The AT&T C++ translator, Cfront, solved the template instantiation + problem by creating the notion of a template repository, an + automatically maintained place where template instances are + stored. As individual object files are built, notes are placed in + the repository to record where templates and potential type + arguments were seen so that the subsequent instantiation step + knows where to find them. At link time, any needed instances are + generated and linked in. The advantages of this model are more + optimal compilation speed and the ability to use the system + linker; to implement the Borland model a compiler vendor also + needs to replace the linker. The disadvantages are vastly + increased complexity, and thus potential for error; theoretically, + this should be just as transparent, but in practice it has been + very difficult to build multiple programs in one directory and one + program in multiple directories using Cfront. Code written for + this model tends to separate definitions of non-inline member + templates into a separate file, which is magically found by the + link preprocessor when a template needs to be instantiated. + + Currently, g++ implements neither automatic model. The g++ team +hopes to have a repository working for 2.7.0. In the mean time, you +have three options for dealing with template instantiations: + + 1. Do nothing. Pretend g++ does implement automatic instantiation + management. Code written for the Borland model will work fine, but + each translation unit will contain instances of each of the + templates it uses. In a large program, this can lead to an + unacceptable amount of code duplication. + + 2. Add `#pragma interface' to all files containing template + definitions. For each of these files, add `#pragma implementation + "FILENAME"' to the top of some `.C' file which `#include's it. + Then compile everything with -fexternal-templates. The templates + will then only be expanded in the translation unit which + implements them (i.e. has a `#pragma implementation' line for the + file where they live); all other files will use external + references. If you're lucky, everything should work properly. If + you get undefined symbol errors, you need to make sure that each + template instance which is used in the program is used in the file + which implements that template. If you don't have any use for a + particular instance in that file, you can just instantiate it + explicitly, using the syntax from the latest C++ working paper: + + template class A; + template ostream& operator << (ostream&, const A&); + + This strategy will work with code written for either model. If + you are using code written for the Cfront model, the file + containing a class template and the file containing its member + templates should be implemented in the same translation unit. + + A slight variation on this approach is to use the flag + -falt-external-templates instead; this flag causes template + instances to be emitted in the translation unit that implements + the header where they are first instantiated, rather than the one + which implements the file where the templates are defined. This + header must be the same in all translation units, or things are + likely to break. + + *See Declarations and Definitions in One Header: C++ Interface, + for more discussion of these pragmas. + + 3. Explicitly instantiate all the template instances you use, and + compile with -fno-implicit-templates. This is probably your best + bet; it may require more knowledge of exactly which templates you + are using, but it's less mysterious than the previous approach, + and it doesn't require any `#pragma's or other g++-specific code. + You can scatter the instantiations throughout your program, you + can create one big file to do all the instantiations, or you can + create tiny files like + + #include "Foo.h" + #include "Foo.cc" + + template class Foo; + + for each instance you need, and create a template instantiation + library from those. I'm partial to the last, but your mileage may + vary. If you are using Cfront-model code, you can probably get + away with not using -fno-implicit-templates when compiling files + that don't `#include' the member template definitions. + +4. Placing a function that looks like this near the top of a .C file + that uses any inline template member functions permits proper inlining: + + // #ifdef __GNUG__ + // This function works around the g++ problem with inline template member + // calls not being inlined ONLY in the first block (in a compilation + // unit) from which they are called. + // This function is inline and is never called, so it does not produce + // any executable code. The "if" statements avoid compiler warnings about + // unused variables. + inline + void + gcc_inline_template_member_function_instantiator() + { + if ( (List *) 0 ); + } + // #endif // __GNUG__ + + other prerequisites: + -- All inline template member functions should be defined in + the template class header. Otherwise, g++ will not inline + nested inline template member function calls. + -- Template .h and .C files should NOT include iostream.h + (and therefore debugging.h). + This is because iostream.h indirectly includes other + GNU headers that have unprotected #pragma interface, + which is incompatible with -fno-implicit-templates and optimal + space savings. + -- inline virtual destructors will not be inlined, unless necessary, + if you want to save every last byte + -- be sure that -Winline is enabled + +---------------------------------------- +19. + +> 1. when are dynamically loaded objects removed from the Service_Config. + +The Service Configurator calls dlclose() when a "remove Service_Name" +directive is encountered in the svc.conf file (or programmatically +when the Service_Config::remove() method is invoked). Check out the +code in ./libsrc/Service_Config/Service_Repository.i and +./libsrc/Service_Config/Service_Config.i to see exactly what happens. + +> 2. In the Service Configurator, when an item is entered in the svc.conf +> how dow you know which items will be invoked as threads and +> which items are forked. I know that static items are executed +> internally. + + No! It's totally up to the subclass of Service_Object to +decide whetehr threading/forking/single-threading is used. Check out +the ./apps/Logger/Service_Configurator_Logger for examples of +single-threaded and multi-threaded configuration. +---------------------------------------- +20. + +> I have been reading the Service Configurator Logger. I was wondering about +> cleanup of new objects. In the handle_input method for the Acceptor a new +> svc_handler is allocated for each new input request and deleted in the +> handle_close. I was wondering how handle close was called when a client who +> has created a socket terminates the connection (i.e., when is handle_close +> called). + +handle_close() is automatically called by the Reactor when a +handle_input()/handle_output()/etc. method returns -1. This is the +"hook" that instructs the Reactor to call handle_**() and then remove +the Event_Handler object from its internal tables. + +---------------------------------------- +21. + +> How does the Logger know to remove the client socket and the svc_handler object. +> Does he recieve an exception. + + No. when the client terminates the underlying TCP/IP +implementation sends a RESET message to the logger host. This is +delivered to the logger process as a 0-sized read(). It then knows to +close down. + +> What I am worried about is a leak. Where by alot of clients connect and +> disconnect and the server does not cleanup correctly. Such as a core dump +> from the client where he cannot close correctly. + + That's handled by the underlying TCP (assuming it is +implemented correctly...). + +> What I am doing is attempting to convert the logger example into an alarm +> manager for remote nodes. In this application a node may be powered down +> there by terminating a Logger/Alarm server connection abnormally, this could +> leave the Logger with many dangling sockets and allocated svc_handler objects. + + If the TCP implementation doesn't handle this correctly then +the standard way of dealing with it is to have an Event_Handler use a +watchdog timer to periodically "poll" the client to make sure it is +still connected. BTW, PCs tend to have more problems with this than +UNIX boxes since when they are turned off the TCP implementation may +not be able to send a RESET... +---------------------------------------- +22. + +Using templates with Centerline. + +Centerline uses ptlink to process the C++ templates. ptlink expect the +template declarations and definitions (app.h and app.C) to reside in +the same directory. This works fine for the ACE hierarchy since +everything is a link to the appropriate src directory (include/*.[hi] +--> ../src/). When a users of the ACE distribution attempts to include +the ACE classes in an existing application hierarchy this problem will +arise if ptlink is used. + +The solution is to create a link to the declaration file from the +definition file directory and use the "-I" to point to the definition +directory. + +---------------------------------------- + +23. + +> When I try to compile $ACE_ROOT/src/Message_Queue.C on a Solaris +> 5.3 system using SUNPro CC 4.0, the compiler aborts with a Signal 10 +> (Bus Error). Our copy of CC 4.0 is over a year old and I do not +> know if any patches or upgrades exist for it. If they do, then we +> have not applied them to our compiler. + + Several other people have run across this as well. It turns +out that there is a bug in the Sun 4.0.0 C++ compiler that will get a +bus error when -g is used. If you compilg Message_Queue.C *without* +-g then it works fine. The later versions of SunC++ don't have this +bug. I'd recommend that you upgrade as soon as possible. + +---------------------------------------- + +24. + +> I have added a dynamic service to the Service Configurator. This new service +> fails on the load because it uses application libraries that are not shared +> object libraries (i.e., objects in libApp.a). I am assuming from the error +> message that the problem is the mix match of shared and non-shared objects. + + Right, exactly. + +> I was wondering if there is an easy way to add static services to the +> Service Configurator. The example directory listing static service is +> very tightly coupled with the Service_Config object. Is there another +> way of adding static services. + + Sure, that's easy. The best way to do this is to use the +interfaces of the Service_Respository class to configure static +services into the Service_Config. A good example of how to do this is +in Service_Config.[Chi]: + +int +Service_Config::load_defaults (void) +{ + for (Static_Svc_Descriptor *sl = Service_Config::service_list_; sl->name_ != 0; sl++) + { + Service_Type *stp = ace_create_service_type (sl->name_, sl->type_, + (const void *) (*sl->alloc_)(), + sl->flags_); + if (stp == 0) + continue; + + const Service_Record *sr = new Service_Record (sl->name_, stp, 0, sl->active_); + + if (Service_Config::svc_rep->insert (sr) == -1) + return -1; + } + return 0; +} + +---------------------------------------- +25. + +> 8. Do you have examples of the SYNC/ASYNC pattern? + + Yes. Check out the following: + + 1. The latest version of ./apps/Gateway/Gateway has + an example of this when you compile with the USE_OUTPUT_MT + flag. In this case, the Reactor performs the "Async" + processing, which multiplexes all incoming messages from peers + arriving on Input_Channels. These messages are then queued + up at the appropriate Output_Channels. Each Output_Channel + runs in a separate thread, performing the "Sync" + processing. + + 2. Also, the latest version of the OOCP-tutorial4.ps.gz + file available from wuarchive.wustl.edu in the + directory /languages/c++/ACE/ACE-documentation shows + an example of using the Half-Sync/Half-Async pattern + to build an Image Server. I'm using this as an + example in my tutorials these days. + +---------------------------------------- +26. + +> We had a discussion about something we saw in the new ACE code. +> I thing there was a member function of a class that was doing a +> "delete this". Is this safe? + +In general it is safe as long as (1) the object has been allocated +dynamically off the heap and (2) you don't try to access the object +after it has been deleted. You'll note that I tend to use this idiom +in places where an object is registered with the Reactor, which must +then must ensure the object cleans itself up when handle_close() is +called. Note that to ensure (1) I try to declare the destructor +"private" or "protected" so that the object must be allocated off the +heap (some compilers have a problem with this, so I may not be as +consistent as I ought to...). + +---------------------------------------- +27. + +> 5. What is the correct way for building a modified ACE library? +> Changing in "libsrc" or in "include" directory? +> When I make a complete new directory, how can I get introduced +> the dependencies within my new makefile, can you give a short hint? + +Sure, no problem. For instance, here's what I did tonight when I +added the new Thread_Specific.[hiC] files to ACE: + + 1. Created three new files Thread_Specific.[hiC] in + ./libsrc/Threads. + + 2. cd'd to ../../include/ace and did a + + % ln -s ../../libsrc/Threads/Thread_Specific.[hi] . + + 3. cd'd to ../../src and did a + + % ln -s ../../libsrc/Threads/Thread_Specific.C . + + 4. then I did + + % make depend + + on the ./src directory, which updated the dependencies. + +---------------------------------------- +28. The following is from Neil B. Cohen (nbc@metsci.com), who is + writing about how to work around problems he's found with HP/UX. + +I've been trying to compile the latest beta (3.2.9) on an HP running +HPUX9.05 for the past week or so. I've had problems with templates up +and down the line. I finally discovered (after some discussions with +the HP support people) that they have made numerous changes to their +C++ compiler recently to fix problems with templates and +exceptions. If you are trying to compile ACE under HPUX with anything +less than version 3.70 of the HP compiler, you may have serious +problems (we were using v3.50 which came with the machine when we +bought it a few months ago). + +Also, unlike earlier ACE versions, I was forced to add the following +line to the rules.lib.GNU file to "close" the library - ie. force the +various template files to be instantiated and linked to the ACE +library itself. I don't know if this is necessary, or the only way to +make things work, but it seems to do the job for my system. + +in rules.lib.GNU... + +$(VLIB): $(VOBJS) + - CC -pts -pth -ptb -ptv -I$(ACE_ROOT)/include $(VOBJS) + $(AR) $(ARFLAGS) $@ $? ./ptrepository/*.o + -$(RANLIB) $@ + -chmod a+r $@ + +I added the CC line, and added the "./ptrepository/*.o" to the $(AR) +cmd. Sun has an -xar option, I believe that does something similar to +this. Also - note that I'm not sure that the "-ptb" option is +necessary. I added that before we upgraded the compiler, so it may not +be needed now... + +---------------------------------------- +29. + +> I just ran my program with Purify, and it is telling me that there +> is at least one large (~4k) memory leak in +> ACE_Thread_Specific. This may or may not be serious, +> but it is probably worth looking into. + +Right, that's ok. This is data that's allocated on a "per-thread" +basis the first time a thread makes a call using the LM_ERROR or +LM_DEBUG macros. The data isn't freed-up until the thread exits. + +---------------------------------------- + +30. + +> In my trying to use the Reactor pattern for my application I +> noticed that I had to couple my eventHandler derived objects with a +> specific IPC_SAP mechanism. To use some of your own examples your +> Client_Stream object contains a TLI_Stream object to use in data +> transfer. My application calls for determining the communication +> mechanism at run time. To do this my eventHandler must be able to +> create the appropriate IPC_Stream object at run time and use its +> methods through a super class casting. The problem is that there is no +> super class with the virtual methods for send, recv, etc. To solve my +> problem I will create that super class and have the TLI ( as well as +> other wrapper objects) inherit from it instead of IPC_SAP. My question +> is I am suspicious of why ACE wasn't designed with that in mind? Is my +> application that unique ? or is there a better way to do this that I +> am not aware of ? Your help in this matter will be much appreciated. + +ACE was developed using static binding for IPC_SAP in order to +emphasize speed of execution over dynamic flexibility *in the core +infrastructure*. To do otherwise would have penalized the performance +of *all* applications in order to handle the relatively infrequent +case where you want to be able to swap mechanisms at run-time. + +Since it is straightforward to create an abstract class like the one +you describe above I decided to make this a "layered" service rather +than use this mechanism in the core of ACE. + +BTW, I would not modify TLI_SAP and SOCK_SAP to inherit from a new +class. Instead, I would use the Bridge and Adapter patterns from the +"Gang of Four" patterns catalog and do something like this: + +---------------------------------------- +// Abstract base class +class ACE_IPC_Stream +{ +public: + virtual ssize_t recv (void *buf, size_t bytes) = 0; + virtual ssize_t send (const void *buf, size_t bytes) = 0; + virtual ACE_HANDLE get_handle (void) const = 0; + // ... +}; +---------------------------------------- + +and then create new classes like + +---------------------------------------- +template +class ACE_IPC_Stream_T : public ACE_IPC_Stream +{ +public: + virtual ssize_t recv (void *buf, size_t bytes) + { + return this->ipc_.recv (buf, bytes); + } + + virtual ssize_t send (const void *buf, size_t bytes) + { + return this->ipc_.send (buf, bytes); + } + + virtual ACE_HANDLE get_handle (void) + { + return this->ipc_.get_handle (); + } + // ... + +private: + IPC ipc_; + // Target of delegation + // (e.g., ACE_SOCK_Stream or ACE_TLI_Stream). +} +---------------------------------------- + +Then you could write code that operated on ACE_SAP *'s to get a +generic interface, but that reused existing code like SOCK_SAP and +TLI_SAP, e.g., + +---------------------------------------- +class My_Event_Handler : public ACE_Event_Handler +{ +public: + My_Event_Handler (void) { + // Figure out which IPC mechanism to use somehow: + + if (use_tli) + this->my_ipc_ = new ACE_SAP_IPC; + else if (use_sockets) + this->my_ipc_ = new ACE_SAP_IPC; + else + ... + } + +private: + ACE_IPC_Stream *my_ipc_; +}; +---------------------------------------- + +There are obviously details left out here, but this is the general idea. + +---------------------------------------- +31. + +> I was trying to view your 'Writting example applications in CORBA' article +> /tutorial using ghostview but the .ps file seems to be corrupted ( I tried to +> ftp it more than once). Any help would be much appreciated. + +There are two solutions to this problem (which seems to be caused by a +weird interaction between ghostview and the "psnup" program I use to +generate the slides 4-up on a page): + + 1. If you want to print them or view them 1-up on a page you + can edit the postscript file and remove the first 551 + lines or so (which are generated by the psnup script). + This will cause the document to be printed 1-up rather than + 4-up. + + 2. You can try to print the 4-up file on a postscript printer. + Believe it or not, this typically works, even though ghostview + can't handle it! + +---------------------------------------- +32. + +> We would like to use the Reactor class as a static member on some of +> our classes (one per process) so that we can see and use the Reactor +> witnin each process on a global level. We are using it to set +> timers several levels down in our class trees and don't want to pass +> a pointer to it through all of our constructors. My question is: +> are there any static initialization dependencies that you know of +> when using the default "do nothing" constructor of the Reactor that +> could prevent use from using it as a static member variable? Thanks +> for any advice on this issue. + +The only problems you'll have are the typical ones about "order of +initialization" of statics in separate files. You'll also have to +live with the default size of the I/O handler table, which probably +isn't a problem since the max is something like 1024 or so. + +BTW, I solve this problem in ACE via the Service_Config::reactor, +which is a static *pointer* to a Reactor. If you really wanted to +make this work nicely, you could use the Singleton pattern from the +"Gang of Four" patterns catalog. That should solve your problem even +more elegantly! + +---------------------------------------- +33. +> I just got the ACE-3.3 version and am trying it on the HP-UX. +> I run into a small problem while cloning the directories that +> might be worth fixing. +> +> I made a directory called ACE_WRAPPERS/HP-UXA.09.05-g1, cd to it +> and run "make -f ../Makefile clone". when I look in src, I have: +> Acceptor.C@ -> ../libsrc/Connection/Acceptor.C +> +> However, ../libsrc does not exist. It is not one of the CLONE +> variables in ACE_WRAPPERS/Makefile. I don't think you'd want to +> clone libsrc too, since its files don't change. + +I think you can solve this problem as follows: + +% cd ACE_WRAPPERS +% setenv ACE_ROOT $cwd +% cd HP-UXA.09.05-g1 +% make -f ../Makefile clone +% setenv ACE_ROOT $cwd +% make + +That should build the links correctly since they'll point to the +absolute, rather than relative, pathnames! + +---------------------------------------- +34. + +> Our quality personal has asked me the following questions for which +> I think you are the right guy for answering that: + +> o How long is ACE used in industrial products? + +It was first used at Ericsson starting in the fall of 1992, so that +makes it about 3 years now. + +> o What are reference projects comparable to ours that use ACE? + +The ones I have directly worked with include: + +Motorola -- satellite communication control +Kodak Health Imaging Systems -- enterprise medical imaging +Siemens -- enterprise medical imaging +Ericsson/GE Mobile Communications -- telecommunication switch management +Bellcore -- ATM switch signal software + +In addition, there are probably about 100 or more other companies that +have used ACE in commercial products. The current mailing list has +about 300 people from about 230 different companies and universities. +If you'd like additional info, please let me know. + +> o How many persons have contributed on testing and writing error +> reports for ACE? + +Around 60 or so. All the contributors are listed by name and email +address at the end of the README file distributed with the ACE release. + +> o How many bug fixes have been made since ACE was public domain? + +All information related to bug fixes is available in the ChangeLog +file distributed with the ACE release (I could count these for you if +you need that level of detail). + +> o How many literature is there on ACE? + +All articles published about ACE are referenced in the BIBLIOGRAPHY +file in the top-level directory of ACE. + +---------------------------------------- + +35. + +> We are currently evaluating ACE for use on a new telecom switch. +> Many of us like ACE but are having trouble convincing some team +> members that wrappers are better than using the direct Unix +> system calls. + +> I have read your papers that came with ACE, but was wondering if there +> are other papers that address the benefits (or problems) of wrappers? + +This topic has been discussed in other places, most notably the book +by Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides +called "Design Patterns: Elements of Reusable Object-Oriented +Software" (Addison-Wesley, 1994), where it is described in terms of +the "Adapter" pattern. + +Very briefly, there are several key reasons why you should *not* use +UNIX system calls directly (regardless of whether you use ACE or not). + +1. Portability -- + + Unless you plan to develop code on only 1 UNIX platform (and + you never plan to upgrade from that platform as it goes + through new releases of the OS) you'll run across many, many + non-portable features. It's beyond the scope of this + FAQ to name them all, but just take a look at ACE sometime + and you'll see all the #ifdefs I've had to add to deal with + non-compatible OSs and compilers. Most of these are centralized + in one place in ACE (in the ace/OS.*files), but it took a lot + of work to factor this out. By using wrappers, you can avoid + most of this problem in the bulk of your application code + and avoid revisiting all of these issues yourself. + + In addition, ACE is now ported to other platforms (e.g., + Windows NT and Windows 95). If you want to write code that + is portable across platforms, wrappers are a good way to + accomplish this. + +2. Ease of programming -- + + I'd go as far as to say that anyone who wants to program + applications using C-level APIs like sockets or TLI is not + serious about developing industrial strength, robust, and easy + to maintain software. Sockets and TLI are *incredibly* + error-prone and tedious to use, in addition to being + non-portable. I've got a paper that discusses this in detail + at URL http://www.cs.wustl.edu/~schmidt/PDF/COOTS-95.pdf + +3. Incorporation with higher-level patterns and programming methods -- + + Here's where the Adapter pattern stuff really pays + off. For example, by making all the UNIX network + programming interfaces and synchronization mechanisms + have the same API I can write very powerful higher-level + patterns (e.g., Connector and Acceptor) that generalize + over these mechanisms. For proof of this, take a look + at the ./tests/Connection/non_blocking directory + in the latest ACE-beta.tar.gz at wuarchive.wustl.edu + in the /languages/c++/ACE directory. It implements + the same exact program that can be parameterized + with sockets, TLI, and STREAM pipes *without* + modifying any application source code. It is + literally impossible to do this without wrappers. + +---------------------------------------- +36. + +> How can I use a kind of "Reactor" in such a way that a reading +> thread can notice the arrival of new data on several shared memory +> areas ? + +Ah, that is a tricky issue! The underlying problem is that UNIX is +inconsistent with respect to the ability to "wait" on different +sources of events. In this case, Windows NT is much more consistent +(but it has its own set of problems...). + +> Poll, Select and Reactor (so far I read) assume that file +> descriptors are present, which is not the case with shared memory. + +That's correct (though to be more precise, the Reactor can also deal +with signals, as I discuss below). + +> Is there a common and efficient way to deal with that kind of +> situation, or do I have to insert extra ipc mechanisms (based on +> descriptors) ? + +There are several solutions: + +1. Use the Reactor's signal handling capability (see the + ./tests/Reactor/misc/signal_tester.C for an example) + and have the process/thread that writes to shared + data send a signal to the reader process(es). The + disadvantage of this is that your code needs to + be signal-safe now... + +2. Use a combination of SPIPE_Streams and the Reactor + to implement a simple "notification protocol," e.g., + the receiver process has an Event_Handler with a + SPIPE_Stream in it that can be notified when the + sender process writes data to shared memory. + The disadvantage here is that there's an extra + trip through the kernel, though the overhead + is very small since you only need to send 1 byte. + +3. Use threads and either bypass the Reactor altogether + or integrate the threads with the Reactor using its + Reactor::notify() mechanism (see the + ./tests/Reactor/misc/notification.C file for an + example of how Reactor::notify() works). The + disadvantage of this approach is that it won't + work for platforms that lack threads. + +---------------------------------------- +37. + +> What do you think about wrapping communication methodologies in C++ streams? +> What I mean is having defining a stream and extractor/insertor functions +> which the underlying implementation reads/writes on comm mechanisms instead of +> files. I would think this to be a very general interface for all comms +> implementations. All user code would look the same, but the underlying stream +> implementations would be different. Whether the stream functionality would +> be defined by the stream itself (eg tcpstream) or with manipulators +> (eg commstream cs; cs << tcp;) is up for grabs in my mind. +> +> Anyhow, I was wondering your input... + +That technique has been used for a long time. In fact, there are +several freely available versions of iostreams that do this and +RogueWave also sells a new product (Net.h++) that does this. I think +this approach is fine for simple applications. + +However, it doesn't really work well if you need to write +sophisticated distributed applications that must use features like +non-blocking I/O, concurrency, or that must be highly robust against +the types of errors that occur in a distributed system. + +For these kinds of systems you either need some type of ORB, or you +need to write the apps with lower-level C++ wrappers like the ones +provided by ACE. + +---------------------------------------- + +38. + +> What is the difference between cont() and next() in an ACE_Message_Block? + +Ah, good question. cont() gives you a pointer to the next +Message_Block in a chain of Message_Block fragments that all belong to +the same logical message. In contrast, next() (and prev()) return +pointers to the next (and previous) Message_Block in the doubly linked +list of Message_Blocks on a Message_Queue. + +BTW, this is *exactly* the same structure as in System V Streams... + +> Which would I use if I wanted to add a header and a trailer, each stored in +> ACE_Message_Blocks of their own, to another ACE_Message_Block? + +You should use cont() for that. Does that make sense? +---------------------------------------- + +39. + +> I think that your site is cool, but it's being a terrible tease in +> that I really want to read the contents, but don't know anything +> about x-gzip formatting. I'm running Netscape 2.0 under MS Windows +> NT. + +To view PostScript files under Win32 you will need a PostScript +viewer such as GSview. You can find GSview and Ghostscript (which is +needed to run GSview) at http://www.cs.wisc.edu/~ghost/. + +It seems that both Netscape and Internet Explorer mangles the names +of downloaded files to reflect their content type, so *.ps.gz files +are saved as *_ps.ps instead. Fortunately, GSview as of version 2.2 +supports gzip compressed postscript. When set up as a viewer for +Postscript files, files with mangled names can be viewed by GSview +without any preprocessing. + +---------------------------------------- + +40. + +> What I am doing is +> 1. Making an ACE_SOCK_Dgram and let it choose the next available port number. +> 2. Making a message that will be broadcasted to X number of servers. This +> message has a port number which the server will use to send its reply. +> 3. Broadcast the message to a fixed port number. +> 4. Wait for replies from the servers. +> +> +> It looks like I need "ACE::bind_port" to return the port number that +> it picked and "ACE_SOCK_Dgram::shared_open" will need it store the +> port number so I could call some function like +> ACE_SOCK_Dgram::get_port_number or it would need to return the port +> number instead of the handle(I could always call +> ACE_SOCK_Dgram::get_handle if I needed the handle). +> +> Is there I way to get the port number that I have missed? + +Sure, can't you just do this: + +// Defaults to all "zeros", so bind will pick port. +ACE_INET_Addr dg_addr; + +ACE_SOCK_Dgram dg; + +dg.open (dg_addr); + +dg.get_local_addr (dg_addr); + +dg_addr.get_port_number (); + +---------------------------------------- + +41. How can you rename a core file? + +new_disposition.sa_handler = &Handle_Coredump_Signal; +sigemptyset(&new_disposition.sa_mask); +sigaddset(&new_disposition.sa_mask,SIGCHLD); +new_disposition.sa_flags = 0; +sigaction(SIGSEGV,&new_disposition,&old_disposition); + +***************** + +void +Handle_Coredump_Signal(void) +{ + int status; + pid_t child; + char new_core_name[64]; + + if(0 == (child = fork())) + { + abort(); + } + else + { + if(-1 == waitpid(child,&status,NULL)) + { + exit(-1); + } + sprintf(new_core_name,"core_%d",getpid()); + rename("core",new_core_name); + exit(0); + } +} + +---------------------------------------- + +42. + +> I have seen 2 different inlining policies in ACE +> +> 1) The .i file is included unconditionally by both the .h and .C file +> and all functions in the .i file carry the "inline" keyword. + +Right. Those are for cases where I *always* want to inline those +methods. I do this mostly for very short wrapper methods (e.g., +read() or write()) that are likely to be on the "fast path" of an +application. + +> 2) The .i file is included by the .h file ONLY if __INLINE__ is defined +> for the compile. This causes the functions in the .i file to be +> compiled as inline functions (INLINE translates to inline in this case). +> If __INLINE__ is not defined, the .i file is only included by the .C +> file and the functions do NOT carry the "inline" keyword. + +I do this for cases where it's really not essential to have those +methods inline, but some users might want to compile ACE that was if +they want to eliminate all the wrapper function-call overhead. For +instance, I'll typically do this when I'm running benchmarks. + +---------------------------------------- + +43. Integrating ACE and CORBA + +> Our goal is to implement a CORBA-II compliant application. I am +> trying to conceptually visualize the applicability to ACE to this +> attempt (which we're pretty excited about), and I was hoping you'd +> offer any opinions / observations that you might have. + +We've successfully integrated ACE with several implementations of +CORBA (in particular Orbix 1.3 and 2.0) and used it in a number of +commercial applications. In these systems, we use ACE for a number of +tasks, including the following: + +1. Intra-application concurrency control, threading, and + synchronization via the ACE_Thread_Manager and Synch* classes. + +2. Dynamic linking of services via the ACE_Service_Config. + +3. Integration of event loops via the ACE_Reactor. + +4. Management of shared memory via ACE_Malloc. + +5. High-performance network I/O via the ACE_SOCK* wrappers. + +plus many more. + +You can find out more info about the ACE/CORBA integration and the +performance issues associated with it in the following paper: + +http://www.cs.wustl.edu/~schmidt/PDF/COOTS-96.pdf + +---------------------------------------- + +44. + +> Can the Reactor's event loop be called recursively? + +This is not advisable. The Reactor's dispatch() method is not +reentrant (though it is thread-safe) since it maintains state about +the active descriptors it is iterating over. Therefore, depending on +the descriptors you're selecting on, you could end up with spurious +handle_*() callbacks if you make nested calls to the +Reactor::handle_events() method. + +> For example, if I have a program that sets up some event handlers +> and then calls, in an infinite loop, ACE_Reactor::handle_events(). +> Can one of the event handlers call handle_events() again if it needs +> to block, while allowing other event handlers a chance to run? + +I'm not sure if this is really a good idea, even if the Reactor were +reentrant. In particular, what good does it do for one Event_Handler +to "block" by calling handle_events() again? The event the handler is +waiting for will likely be dispatched by the nested handle_events() +call! So when you returned back from the nested call to +handle_events() it will be tricky to know what state you were in and +how to proceed. + +Here's how I design my single-threaded systems that have to deal with +this: + + 1. I use a single event loop based on the Reactor, which acts + a cooperative multi-tasking scheduler/dispatcher. + + 2. I then program all Event_Handler's as non-blocking I/O + objects. This is straightforward to do for both input and + output using the ACE_Reactor::schedule_wakeup() and + ACE_Reactor::cancel_wakeup() methods (available with the + latest version of ACE). + + 3. Then, whenever an Event_Handler must block on I/O, it + queues up its state on an ACE_Message_Queue, calls + ACE_Reactor::schedule_wakeup(), and returns to the + main event loop so that other Event_Handlers can be + dispatched. When the I/O is ready, the Reactor will + call back to the appropriate handle_* method, which + can pick up the state it left in the Message_Queue and + continue. + +There are a number of places to find more information on this sort of +design: + + 1. $ACE_ROOT/apps/Gateway/Gateway/Channel.cpp -- + This Gateway application example shows the C++ code. + + 2. http://www.cs.wustl.edu/~schmidt/PDF/TAPOS-00.pdf -- + This paper describes the underlying patterns. + + 3. http://www.cs.wustl.edu/~schmidt/PDF/OONP-tutorial4.pdf + -- This tutorial explains the source code and + the patterns. + +BTW, I'll be describing patterns for this type of design challenge in +my tutorial at USENIX COOTS in June. Please check out +http://www.cs.wustl.edu/~schmidt/COOTS-96.html for more info. + +---------------------------------------- + +45. + +> In one of my programs, a process needs to receive input from +> multiple input sources. One of the input sources is a file +> descriptor while another is a message queue. Is there a clean way to +> integrate this a message queue source into the Reactor class so that +> both inputs are handled uniformly? + +Do you have multiple threads on your platform? If not, then life will +be *very* tough and you'll basically have to use multiple processes to +do what you're trying to do. There is *no* portable way to combine +System V message queues and file descriptors on UNIX, unfortunately. + +If you do have threads, the easiest thing to do is to have a thread +reading the message queue and redirecting the messages into the +Reactor via its notify() method. + +Please take a look at the program called + +examples/Reactor/Misc/notification.cpp + +for an example. + +---------------------------------------- + +46. + +> I'm writing a program to find out the address for a socket. The +> idea is that we open an ACE_Acceptor (and will eventually perform +> accept() on it.) Before we can do that we need to find out the +> address of the ACE_Acceptor so that we can publish it (for others to +> be able to connect to it.) The trouble is that the call +> ACE_INET_Addr::get_host_name () prints "localhost" as the host name +> while I would like to principal host name to be printed instead. + +All ACE_INET_Addr::get_host_name() is doing is calling +ACE_OS::gethostbyaddr(), which in turn will call the socket +gethostbyaddr() function. I suspect that what you should do is +something like the following: + +ACE_Acceptor listener (ACE_Addr::sap_any); + +ACE_INET_Addr addr; + +listener.get_local_addr (addr); + +char *host = addr.get_host_name (); + +if (::strcmp (host, "localhost") == 0) +{ + char name[MAXHOSTNAMELEN]; + ACE_OS::hostname (name, sizeof name); + cerr << name << endl; +} +else + cerr << host << endl; + +---------------------------------------- + +47. + +> Could you please point me to stuff dealing with asynchronous cross +> platform socket calls. I want to use non blocking socket calls on +> both UNIX and NT. + +Sure, no problem. Take a look at the + +./examples/Connection/non_blocking/ + +directory. There are a number of examples there. In addition, there +are examples of non-blocking connections in + +./examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp + +The code that actually enables the non-blocking socket I/O is in +ace/IPC_SAP.cpp + +---------------------------------------- + +48. + +> Is ACE exception-safe? If I throw an exception out of event +> handler, will the Reactor code clean itself? + +Yes, that should be ok. In general, the two things to watch out for +with exceptions are: + + 1. Memory leaks -- There shouldn't be any memory leaks internally + to the Reactor since it doesn't allocate any memory when + dispatching event handlers. + + 2. Locks -- In the MT_SAFE version of ACE, the Reactor acquires + an internal lock before dispatching Event_Handler callbacks. + However, this lock is controlled by an ACE_Guard, whose + destructor will release the lock if exceptions are thrown + from an Event_Handler. + +---------------------------------------- + +49. + +> I am building a Shared memory manager object using MMAP and MALLOC +> basically as: +> +> typedef ACE_Malloc SHMALLOC; +> +> I noticed that the ACE_MMAP_Memory_Pool class provides for the users +> to specify a Semaphore key. However, once I use it via the +> ACE_Malloc<..>::ACE_Malloc(const char* poolname) constructor, I lose +> this option. + +Yes, that is correct. That design decision was made to keep a clean +interface that will work for all the various types of memory pools. + +> Is there any recommended way to specialize ACE classes to allow this +> key to be overridden? + +Yes indeed, you just create a new subclass (e.g., class +My_Memory_Pool) that inherits from ACE_MMAP_Memory_Pool and then you +pass in the appropriate key to the constructor of ACE_MMAP_Memory_Pool +in the constructor of My_Memory_Pool. Then you just say: + +typedef ACE_Malloc SHMALLOC; + +Please check out the file: + +examples/Shared_Malloc/Malloc.cpp + +which illustrates more or less how to do this. + +---------------------------------------- + +50. + +> What is the best way to turn on TRACE output in ACE. I commented +> out the #define ACE_NTRACE 1 in config.h and rebuilt ACE and the +> examples. + +The best way to do this is to say + +#define ACE_NTRACE 0 + +in config.h. + +> When I run the CPP-inserver example in examples/IPC_SAP/SOCK_SAP, I +> get some trace output but not everything I would expect to see. + +Can you please let me know what you'd expect to see that you're not +seeing? Some of the ACE_TRACE macros for the lower-level ACE methods +are commented out to avoid problems with infinite recursion (i.e., +tracing the ACE_Trace calls...). I haven't had a chance to go over +all of these indepth, but I know that it should be possible to turn +many of them back on. + +> It would be nice to have a runtime option for turning trace on and +> off. + +There already is. In fact, there are two ways to do it. +If you want to control tracing for the entire process, please check +out ACE_Trace::start_tracing() and ACE_Trace::stop_tracing(). + +If you want to control tracing on a per-thread basis please take a +look at the ACE_Log_Msg class. There are methods called +stop_tracing() and start_tracing() that do what you want. + +---------------------------------------- + +51. + +> I've been using an acceptor and a connector in one (OS-) process. +> What does happen, if a signal is sent to this process? Is the signal +> processed by every ACE_Event_Handler (or its descendants) that is +> around? The manual page simply states that handle signal is called +> as soon as a signal is triggered by the OS. + +How this signal is handled depends on several factors: + +1. Whether your using ACE_Sig_Handler or ACE_Sig_Handlers to register + the signal handlers. + +2. If you're using ACE_Sig_Handler, then the ACE_Event_Handler * that + you've most recently registered to handle the signal will + have it's handle_signal() method called back by the Reactor. + +3. If you're using ACE_Sig_Handlers, then all of the ACE_Event_Handler * + that you've register will be called back. + +For examples of how this works, please check out + +$ACE_ROOT/examples/Reactor/Misc/test_signals.cpp + +This contains a long comment that explains precisely how everything +works! diff --git a/dep/ACE_wrappers/Makefile.am b/dep/ACE_wrappers/Makefile.am new file mode 100644 index 000000000..2d84dbdad --- /dev/null +++ b/dep/ACE_wrappers/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to create Makefile.in +## +## $Id: Makefile.am 80826 2008-03-04 14:51:23Z wotte $ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +SUBDIRS = \ + ace + +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = foreign diff --git a/dep/ACE_wrappers/NEWS b/dep/ACE_wrappers/NEWS new file mode 100644 index 000000000..1c0f15d2c --- /dev/null +++ b/dep/ACE_wrappers/NEWS @@ -0,0 +1,1345 @@ +PLANNED MAJOR CHANGES "SOMETIME IN THE FUTURE" (i.e., exact beta not known) +=========================================================================== + +. RPM packaging as part of the release process by the doc_group (Remedy and user community) + +. Remove BCB6, BCB2006, and the borland MPC template after the release of x.6.6 + +USER VISIBLE CHANGES BETWEEN ACE-5.6.5 and ACE-5.6.6 +==================================================== + +. Added an option to the ACE_Process_Options class to use a wchar_t + environment buffer on Windows. + +. A new configure option, --enable-rcsid, was added to the autoconf build. + This is used to embed RCS IDs in object files. + +. A new method was added: void ACE_Time_Value::msec (ACE_UINT64&) + This method, like the existing msec(ACE_UINT64&)const method, obtains the + time value in milliseconds and stores it in the passed ACE_UINT64 object. + This method was added so that msec(ACE_UINT64&) can be called on both + const and non-const ACE_Time_Value objects without triggering compile errors. + Fixes Bugzilla #3336. + +. Added ACE_Stack_Trace class to allow users to obtain a stack trace + within their application on supported platforms. A new conversion + character, the question mark, was added to ACE_Log_Msg for stack + trace logging. + +. Added iterator support to ACE_Message_Queue_Ex class. The resulted in + the addition of ACE_Message_Queue_Ex_Iterator class and + ACE_Message_Queue_Ex_Reverse_Iterator class. + +. Renamed gperf to ace_gperf to prevent clashes with the regular gperf + tool that is available in linux distributions + +. Added support for FC9 + +. Added support for OpenSuSE 11.0 + +. Improved support for GCC 4.2 and 4.3 + +. Added support for CodeGear C++ Builder 2009 + +USER VISIBLE CHANGES BETWEEN ACE-5.6.4 and ACE-5.6.5 +==================================================== + +. Added new Monitoring lib that can be used to store and retrieve + counters. This is disabled by default because it is not 100% + finished yet, with the next release it will be enabled by default + +. Fixed bug in ACE_Service_Config when it was used from a thread + not spawned by ACE + +. Add VxWorks 6.x kernel mode with shared library support to ACE + +. Extended the implementation of Unbounded_Set, which has been + renamed Unbounded_Set_Ex, to accept a second parameter which is + a comparator that implements operator() which returns true if + the items are equivalent. Unbounded_Set has been reimplemented + in terms of Unbounded_Set_Ex using a comparator that uses operator==, + which captures the previous behavior. + +. Added support for Intel C++ on MacOSX + +USER VISIBLE CHANGES BETWEEN ACE-5.6.3 and ACE-5.6.4 +==================================================== + +. Reworked the relationship between ACE_Service_Config and + ACE_Service_Gestalt + +. Improved autoconf support + +. Improved AIX with gcc support + +. Improved OpenVMS support + +. Improved VxWorks support + +USER VISIBLE CHANGES BETWEEN ACE-5.6.2 and ACE-5.6.3 +==================================================== + +. Deprecated Visual Age 5 and older + +. Closed a rare race condition hole whereby ACE_Atomic_Op<> function + pointers would not be fully initialized prior to use. See bugzilla + 3185 for details. + +. Tweaks to support MacOS X Leopard (10.5 and 10.5.1) on Intel + +. Fixed compile problems with MinGW with GCC 4.2. Do note that we do see + much more test failures then when using GCC 3.4. + +. Changed to use synchronous exception handling with msvc 8/9 which is the + default. Asynchrous exception handling does catch access violations but + it leads to lower performance and other problems. See also bugzilla 3169 + +. Make ace_main extern C with VxWorks so that it doesn't get mangled + +. Fixed compile errors and warnings for VxWorks 6.6 + +. Added an MPC generator for the WindRiver Workbench 2.6 which is shipped + with VxWorks 6.4 + +. Added support for CodeGear C++ Builder 2007 with December 2007 update + installed + +. Added support for VxWorks 5.5.1 + +. Implemented the const reverse iterator for ACE_Hash_Map_Manager_Ex + +. Increased support for using ACE_Hash_Map_Manager_Ex with STL + functions based on latest standard C++ draft + +USER VISIBLE CHANGES BETWEEN ACE-5.6.1 and ACE-5.6.2 +==================================================== + +. ACE-ified the UUID class, which will change user applications slightly. + +. Added support for Sun Studio 12 + +. Added support for Intel C++ 10.1 + +. Fixed runtime problems with VxWorks 6.x in kernel mode, several improvements + have been made to ACE, but also some problems in the VxWorks kernel have + been found for which WindRiver has made patches. + +. Added support for VxWorks 6.5 kernel mode + +. Added support for MacOS 10.5 + +. Support for MacOS 10.4 is now deprecated. + +. Added support for OpenSuSE 10.3 + +. Added support for RedHat 5.1 + +. Added support for Microsoft Visual Studio 2008 + +. Added support for Fedora Core 8 + +. Added support for Ubuntu 7.10 + +. With Ubuntu 7.04 and 7.10 we can't use visibility, that results in + unresolved externals when building some tests. With lsb_release we + now detect Ubuntu 7.04 and 7.10 automatically and then we disable + visibility + +. Removed deprecated (un)subscribe methods from ACE_SOCK_Dgram_Mcast + +. Added an additional replace() method to ACE_OuptutCDR for replacing a + ACE_CDR::Short value. Also added write_long_placeholder() and + write_short_placeholder() to properly align the stream's write pointer, + write a placeholder value and return the placeholder's pointer. The pointer + can later be used in a call to replace() to replace the placeholder with a + different value. + +. Initial support for VxWorks 6.6 + +. Removed support for pthread draft 4, 6, & 7. This makes the ACE threading + code much cleaner + +. Improved autoconf support + +. Fixed TSS emulation problems + +. Changed ACE_thread_t and ACE_hthread_t to int for VxWorks kernel mode. All + thread creation methods do have an additional const char* argument to + specify the task name, this now also works with pthread support enabled + +. Use bool in much more interfaces where this is possible + +. Added support for Debian Etch + +. Fixed ACE CDR LongDouble support on VxWorks 6.x + +. Added Microsoft Visual Studio 2008 project files to the release packages + +. Fixed a few bugs in the ACE_Vector template + +USER VISIBLE CHANGES BETWEEN ACE-5.6 and ACE-5.6.1 +==================================================== + +. Added support for CodeGear RAD Studio 2007 + +. Added support for CodeGear C++ Builder 2007 Update 3 + +. Modified the definiton of ACE_DEFAULT_THREAD_KEYS on Windows so it + is based on the version of the OS as defined by Microsoft in this web + page: http://tinyurl.com/2jqcmd + This fixes bugzilla #2753 + +USER VISIBLE CHANGES BETWEEN ACE-5.5.10 and ACE-5.6 +==================================================== + +. OpenVMS 8.3 on IA64 port + +. Added autoconf support for Intel C++ 10.0 + +. Improved autoconf support on Linux, Solaris, NetBSD and HPUX + +. CodeGear C++ Builder 2007 Update 2 support + +. The netsvcs's client logging daemon has a new configuration option, + -llocal-ip[:local-port], which can be used to specify the local IP + address and port number for the client logging daemon's connection to + the server logging daemon. If the -l option is specified with an IP + address but not a port number, an unused port number is selected. + +. A new ACE+TAO port to LabVIEW RT 8.2 with Pharlap ETS. The host build + environment is Windows with Microsoft Visual Studio .NET 2003 (VC7.1). + Please see the ACE-INSTALL.html file for build instructions. + +USER VISIBLE CHANGES BETWEEN ACE-5.5.9 and ACE-5.5.10 +==================================================== + +. The ACE_utsname struct, used in the ACE_OS::uname() function when the + platform doesn't provide the standard utsname struct, was changed. It + defines a number of text fields and their types were changed from + ACE_TCHAR[] to char[] in order to be consistent with all other platforms. + This removes the need to write different code for platforms where + ACE_LACKS_UTSNAME_T is set and that have wide characters (most probably + Windows). Fixes Bugzilla #2665. + +. The ACE::daemonize() "close_all_handles" parameter was changed from + an "int" to a "bool" to better reflect how it is used. + +. VxWorks 6.5 support. Compilation of the core libraries has been validated + but no runtime testing has been performed. + +. CodeGear C++ Builder 2007 support. + +. The FaCE utility was moved from the ACE_wrappers/apps directory to + ACE_wrappers/contrib. It is used for testing ACE+TAO apps on WinCE. + See the ACE_wrappers/contrib/FaCE/README file for more information. + +. ACE_INET_Addr::set (u_short port, char *host_name, ...) now favors IPv6 + addresses when compiled with ACE_HAS_IPV6 defined and the supplied address + family is AF_UNSPEC. This means that if host_name has an IPv6 address in + DNS or /etc/hosts, that will be used over an IPv4 address. If no IPv6 + address exists for host_name, then its IPv4 address will be used. + +. Intel C++ 10.0 support + +. Support for the version of vc8 for 64-bit (AMD64) shipped with the Microsoft + Platform SDK. + +. Fixed ACE_Vector::swap() (bugzilla #2951). + +. Make use of the Atomic_Op optimizations on Intel EM64T processors. The + Atomic_Op is now several times faster on EM64T then with previous versions + of ACE + +USER VISIBLE CHANGES BETWEEN ACE-5.5.8 and ACE-5.5.9 +==================================================== + +. Use Intel C++ specific optimizations for Linux on IA64 + +. Improved support for ACE_OS::fgetc. Added support for ACE_OS::fputc, + ACE_OS::getc, ACE_OS::putc and ACE_OS::ungetc. + +. Added support for ACE_OS::log2(double) and improved support for + ACE::log2(u_long). + +. Shared library builds on AIX now produce a libxxx.so file instead of the + previous practice of producing libxxx.a(shr.o). + +. GCC 4.1.2 that comes with Fedora 7 seems to have a fix for the visibility + attribute we use for the singletons. F7 users will therefore need to + define the following in your config.h file. + ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 1 + +. Fixed (rare) problem in TP_Reactor where incorrect event handler was + resumed. + +. Reduced footprint on some platforms, particularly those that use + g++ >= 3.3. + +USER VISIBLE CHANGES BETWEEN ACE-5.5.7 and ACE-5.5.8 +==================================================== + +. Extended ACE_Event constructor with optional LPSECURITY_ATTRIBUTES + argument + +. Added support for QT4 + +. Added support to integrate with the FOX Toolkit (www.fox-toolkit.org) + +. Added support for Microsoft Visual Studio Code Name "Orcas", which is + the msvc9 beta + +. Added ability to provide an optional priority when calling + ACE_Message_Queue_Ex::enqueue_prio(). There was previously no way + to specify a priority for queueing. + +. Removed support for Visual Age on Windows. + +. ACE will compile once again with ACE_LACKS_CDR_ALIGNMENT #defined. + +. ACE_Process_Manager::terminate() no longer removes the process from the + process descriptor table; the pid remains available in order to call + ACE_Process_Manager::wait(). + +USER VISIBLE CHANGES BETWEEN ACE-5.5.6 and ACE-5.5.7 +==================================================== + +. ACE 5.5 contained a set of pragmas which prevented Visual Studio 2005 (VC8) + from issuing warnings where C run-time functions are used but a more + secure alternative is available. For more information on the C run-time + issues and Microsoft's response, please see the following MSDN page: + http://msdn2.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx. + In this beta, the pragmas which prevented the warnings have been removed. + The ACE library has been reviewed and most of the use of "unsafe" functions + has been fixed where possible. Since not all of the warnings emanating from + ACE are situations that can or should be fixed, the ACE VC8 projects will + prevent the warnings while building the ACE kit and its contained examples, + tests, etc. The warnings are disabled by adding Microsoft-specified macros + to the compile line via MPC. If desired, the warnings can be re-enabled by + regenerating the project files with different MPC features. Note, however, + that while ACE without warnings caused by the new C run-time functions, your + application builds may trigger these warnings either by use of the "unsafe" + C run-time functions or via use of an inlined ACE_OS method which uses it. + If the warning is caused by an ACE_OS method, there is a more safe alternate + available, probably located by appending _r to the method name (e.g., + instead of using ACE_OS::ctime(), use ACE_OS::ctime_r()). + There are other cases where the compiler may have issued warnings and ACE + prevented this via a #pragma. These #pragmas have been removed as well. + This may cause your application builds to trigger more warnings from VC8 + than past ACE versions. You should review your code and either correct + the code or disable the warnings locally, as appropriate. + +. The "release" argument to a number of ACE_String_Base<> methods was changed + from int to bool to more accurately reflect its purpose. The following + methods were changed: + + ACE_String_Base (const CHAR *s, + ACE_Allocator *the_allocator = 0, + int release = 1); + to + ACE_String_Base (const CHAR *s, + ACE_Allocator *the_allocator = 0, + bool release = true); + + ACE_String_Base (const CHAR *s, + size_type len, + ACE_Allocator *the_allocator = 0, + int release = 1); + to + ACE_String_Base (const CHAR *s, + size_type len, + ACE_Allocator *the_allocator = 0, + bool release = true); + + void set (const CHAR * s, int release = 1); + to + void set (const CHAR * s, bool release = true); + + void set (const CHAR * s, size_type len, int release); + to + void set (const CHAR * s, size_type len, bool release); + + void clear (int release = 0); + to + void clear (bool release = false); + + Since ACE_String_Base forms the basis of the ACE_CString and ACE_TString + classes, this may ripple out to user application code. If you encounter + errors in this area while building your applications, replace the + int argument you are passing to the method now with either true or false. + +. Solutions for the eVC3/4 platform have been removed from this + release. Note that we package WinCE projects/workspaces for use + with VC8. + +. There were 3 new ACE_Log_Msg logging format specifiers added to make logging + easier for types that may change sizes across platforms. These all take one + argument, and the new formats are: + %b - format a ssize_t value + %B - format a size_t value + %: - format a time_t value + +. The ace/Time_Request_Reply.h and ace/Time_Request_Reply.cpp files were + moved from $ACE_ROOT/ace to $ACE_ROOT/netsvcs/lib. The time arguments in + the public API to ACE_Time_Request were changed from ACE_UINT32 to time_t + and the portions of the on-wire protocol that contains time was changed from + ACE_UINT32 to ACE_UINT64. Thus, code that uses the ACE_Time_Request class + to transfer time information will not interoperate properly with prior + ACE versions. This will affect uses of the netsvcs time clerk/server. + +. The portion of the ACE_Name_Request class that carries the on-wire seconds + portion of a timeout value was changed from ACE_UINT32 to ACE_UINT64. This + means that Name server/clients at ACE 5.5.7 and higher will not interoperate + properly with previous ACE versions' name servers/clients. + +. In the ACE_Log_Record (ACE_Log_Priority, long, long) constructor, the + second argument, long time_stamp, was changed to be of type time_t. This + aligns the type with the expected value, a time stamp such as that returned + from ACE_OS::time(). + +. Added support for VxWorks 6.x cross compilation using a Windows host + system + +. Added support for VxWorks 6.x using the diab compiler + +. The destructor of ACE_Event_Handler no longer calls + purge_pending_notifications(). Please see bugzilla #2845 for the full + rationale. + (http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=2845) + +USER VISIBLE CHANGES BETWEEN ACE-5.5.5 and ACE-5.5.6 +==================================================== + +. The ACE_TYPENAME macro has been added to those that are not + available when the ACE_LACKS_DEPRECATED_MACROS config option is set + (it is not set by default). You are encouraged to replace the use of + ACE_TYPENAME with the C++ typename keyword before the ACE_TYPENAME + macros is removed from ACE in the future. + +. A new script, rm_exception_macros.pl, has been added to help users + remove the use of the ACE exception macros from their own code. + +USER VISIBLE CHANGES BETWEEN ACE-5.5.4 and ACE-5.5.5 +==================================================== + +. The prebuild MPC keyword is now supported by the gnuace project type. + This fixes Bugzilla #2713. + +. Support for Windows earlier than NT 4 SP2 was removed. ACE will not build + for Windows 95, 98, Me, etc. out of the box any longer. + +. Reformat stringified IPv6 addresses to use [addr]:port when printing + addresses that contain ':' such as "::1". + +. Added method to ACE_INET_Addr to determine if address is IPv6 or + IPv4 multicast. + +. Fixed a bug in ACE_Async_Timer_Adapter_Timer_Queue_Adapter where the + gettimeofday function of the timer queue was ignored when setting the alarm. + +. Fixed a problem where, on Solaris 9 onwards, calling + ACE_OS::thr_create(THR_NEW_LWP) more than 2^15 (65535) times in a + process will fail. See changelog entry from "Wed Jan 3 22:31:05 UTC + 2007 Chris Cleeland " for more information. + +. Fixed a bug in ACE_QtReactor where the two select() calls in that function + might select on different handler sets. + +. ACE_SOCK_IO::recvv(iovec[], size_t, const ACE_Time_Value* = 0) and + ACE_SOCK_IO::sendv (const iovec[], size_t, const ACE_Time_Value* = 0) methods + were changed to specify the iovec count argument as int instead of size_t + since it gets reduced to int in the underlying OS calls (usually). + +. The following deprecated methods were removed: + + ssize_t ACE_SOCK_IO::recv (iovec iov[], + size_t n, + const ACE_Time_Value *timeout = 0) const; + + ssize_t ACE_SOCK_IO::recv (iovec *io_vec, + const ACE_Time_Value *timeout = 0) const; + + ssize_t ACE_SOCK_IO::send (const iovec iov[], + size_t n, + const ACE_Time_Value *timeout = 0) const; + + These were previously replaced with more specific recvv() and sendv() + methods. + +. The ACE_Service_Repository::find(const ACE_TCHAR name[], + const ACE_Service_Type **srp = 0, + int ignore_suspended = true) const + method's 'ignore_suspended' parameter was changed from int to bool to + reflect it's purpose as a yes/no indicator. + +. Added --enable-ace-reactor-notification-queue configure script + option to the autoconf build for enabling the Reactor's userspace + notification queue (defines ACE_HAS_REACTOR_NOTIFICATION_QUEUE in + config.h). + +. The int ACE_OutputCDR::consolidate(void) method was contributed by + Howard Finer at Sonus Networks. This method consolidates any continuation + blocks used by an ACE_OutputCDR object into a single block. It's useful for + situations which require access to a single memory area containing the + encoded stream, regardless of its length, when the length cannot be known + in advance. + +. There are a number of new methods defined on ACE_String_Base: + + size_t capacity (void) const: This method returns the number + of allocated CHAR units in the string object. + + void fast_resize (size_t): This method manage the sizing/reallocating + of the string, but doesn't do the memory setting of resize(). + + bool operator!= (const CHAR *) const + bool operator== (const CHAR *) const: These methods compare the + string with a nul-terminated CHAR* string. + + nonmember functions operator== and operator!= where also added + that compare const ACE_String_Base and const CHAR*; these make + it possible to switch ACE_String and CHAR* on either side of + the operator. + + Thank you to Kelly Hickel for these additions. + +. There are 2 new build options on the traditional make command: + dmalloc and mtrace. When specified at build time (e.g. make mtrace=1) + the PLATFORM_DMALLOC_CPPFLAGS and/or PLATFORM_MTRACE_CPPFLAGS values + are added to CPPFLAGS. For dmalloc, the PLATFORM_DMALLOC_LDFLAGS and + PLATFORM_DMALLOC_LIBS are added to LDFLAGS and LIBS, respectively. + Thank you to Howard Finer for supplying these additions. + +. Added the ability to specify additional purify and quantify command-line + options by setting PLATFORM_PURIFY_OPTIONS and PLATFORM_QUANTIFY_OPTIONS, + respectively. Thank you to Howard Finer for supplying these additions. + +. Added the ability to use trio (http://sourceforge.net/projects/ctrio/) + if platform lacks decent support for vsnprintf. trio support is + enabled by defining trio=1 in plaform_macros.GNU + +. Removed Irix 5, DGUX, and m88k support + +. Improved LynxOS 4.2 support + +. VxWorks 6.4 support + +. Added support for FC6. Because the GCC 4.1.1 version that gets shipped + has a fix for the visibility attribute we use for the singletons + you will need to define the following in your config.h file. This can't be + done automatically because SuSE 10.2 gets shipped with GCC 4.1.2 but + doesn't have the same fix + ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 1 + +. RTEMS port + +USER VISIBLE CHANGES BETWEEN ACE-5.5.3 and ACE-5.5.4 +==================================================== + +. Added appropriate intptr_t and uintptr_t typedefs on platforms that + don't provide them (i.e. when ACE_LACKS_INTPTR_T is defined). + +. Added ability to explicitly choose support for 32 bit or 64 bit file + offsets on all platforms. Define the _FILE_OFFSET_BITS preprocessor + symbol to either 32 or 64 to choose the desired number of file + offset bits. This preprocessor symbol is supported natively by most + UNIX and UNIX-like operating systems, and supported by ACE on + Windows. Use the new ACE_OFF_T typedef to refer to file offsets + across UNIX and Windows portably. + +. 64-bit file offsets are now enabled by default in Win64 + configurations. + +. Improved support for 64 bit platforms (64 bit addresses, etc). + +. Added STL-style traits, iterators and a swap() method to the + ACE_Array_Base<> class template. + +. Added STL-style traits and iterator accessors to the + ACE_Hash_Map_Manager_Ex<> class template, as well as new find() and + unbind() methods that return (as an "out" parameter) and accept + iterators, respectively. + +. Greatly improved event handler dispatch performance in + select()-based reactors (e.g. ACE_Select_Reactor and ACE_TP_Reactor) + for large handle sets on Windows. Previous event handler search + were linear, and are now constant on average. + +. Addressed a number of Coverity errors (CHECKED_RETURN, DEADCODE, + LOCK, USE_AFTER_FREE, RESOURCE_LEAK, FORWARD_NULL). + +. Added STL-style "element_type" trait to all ACE auto_ptr class + templates. + +. Removed support for LynxOS 3.x. + +. Resolved Bugzilla #2701 to ensure fini() is called for all + Service Objects upon calling ACE_Service_Config::close() + +. VxWorks 5.5.2 has been tested, for ACE the support is exactly + the same as for VxWorks 5.5.1. No specific defines or flags have + to be used. + +USER VISIBLE CHANGES BETWEEN ACE-5.5.2 and ACE-5.5.3 +==================================================== + +. Added the base projects for executionmanager_stub and plan_generator. + +. Added the ACE_Hash_MultiMap_Manager class and its test file. + +. Changed the ACE_Synch_Options::operator[] method to return bool rather than + int. The value returned is a yes/no indication of whether or not the + specified option(s) are set in the object. + +. Changed the prototype(s) for ACE::debug () to return (and take) a + bool. This is consistent with the original intent for this + feature. If you have been using it like 'ACE::debug () > 0' or + 'ACE::debug (1)', you may have to rebuild ACE. The value of the + ACE_DEBUG environment variable can be used to specify the initial + value for ACE::debug(), at the process start up. + +. An assembler (within a C source file) based implementation for SPARC + of atomic operations suitable for use with the + ACE_Atomic_Op and + ACE_Atomic_Op specializations has + been added. Currently, it can only be enabled by setting the + atomic_ops_sparc make macro to 1 when using the GNUACE build system with + the Solaris SunCC compiler. It should be noted that this requires the + -xarch=v8plus (or higher) be added to the CFLAGS make macro or the + assembler code will not compile. + +. The ACE_Message_Queue_Ex_N class + is new, contributed by Guy Peleg . + ACE_Message_Queue_Ex_N is + similar to ACE_Message_Queue_Ex in that the object queued is a + template parameter. However, ACE_Message_Queue_Ex_N allows the + enqueueing and dequeueing of multiple chained objects at once. This + wasn't added to ACE_Message_Queue_Ex because the chained object + functionality requires the ACE_MESSAGE_TYPE class to have a + ACE_MESSAGE_TYPE *next (void) const method, analogous to + ACE_Message_Block::next(), to follow the chain and this would + probably break existing applications using ACE_Message_Queue_Ex. + The ACE_wrappers/tests/Message_Queue_Test_Ex.cpp test has an example of + how to use the new class. + +. The selector and comparator function pointer arguments to ACE_OS::scandir() + and ACE_Dirent_Selector are now marked as extern "C" to enforce their + use with a C RTL function. User code that defines functions which are + passed as the selector or comparator arguments which are not declared + extern "C" may generate compile warnings. To resolve this, add extern "C" + to the function's signature. See ACE_wrappers/tests/Dirent_Test.cpp for + an example. + +. To address a problem in the ACE string interface that prevented + substring or character searches in very large strings (e.g. greater + than the maximum value of an ssize_t type) from being correctly + reported to the caller, the find(), rfind() and strstr() methods now + return an unsigned integer (size_t) instead of a signed one + (ssize_t). Affected classes include: + + * ACE_CString + * ACE_WString + * ACE_TString + * ACE_NS_WString + + Unless you have been explicitly using -1 instead of npos when + comparing the return value of find(), rfind() and strstr(), and/or + assigning the return value to ssize_t you should not see any + difference. A new size_type typedef has been added to the ACE string + class to aid developers. This typedef is analogous to the standard + C++ string::size_type typedef. + + The ACE_String_Base<>::strstr() documentation and the default + rfind() argument erroneously referred to -1 instead of npos. Those + instances have been corrected. + + To summarize, a "no position" condition is denoted using the npos + constant, not -1. It can be referred directly by scoping it with the + appropriate string class (e.g. ACE_CString::npos, ACE_WString::npos, + etc). + +. Changing the shared library extension for hpux ia64 to ".so". On + HP-UX 11i Version 1.5 the naming scheme is lib*.sl for PA and + lib*.so on IPF. + +. The ACE_Refcounted_Auto_Ptr reset() and release() methods were changed + per Bugzilla #1925. They will both now detach from the underlying + ACE_Refcounted_Auto_Ptr_Rep object; reset() will create a new one for + the new pointer specified as its argument. This change may cause referenced + objects to be deleted in cases where previous ACE versions would not have. + +. The return type of "ACE_Refcounted_Auto_Ptr::null (void) const" changed + from int to bool. It's possible values, true and false, have not changed. + +. TTY_IO now accepts "none" as a valid parity value. Due to this change + 'parityenb' member is now deprecated and will be removed in the future. + The users of TTY_IO class should change their code to use only 'paritymode' + member for parity control and leave 'parityenb' unchanged (it is + enabled by default in class constructor). + +. Support for Intel C++ 9.1 on Windows and Linux + +. VxWorks 6.3 support + +. Fixed Bugzilla #2648 to make sure ACE_Service_Object::fini() + is called iff ACE_Service_Object::init() succeeded, as per + C++NPv2. + +. Added preliminary support for Mac OS X 10.4 on Intel CPU's. + +. Fixed Bugzilla #2602 to re-enable XML Service Configurator + file support. + +USER VISIBLE CHANGES BETWEEN ACE-5.5.1 and ACE-5.5.2 +==================================================== + +. Added support for: + - VxWorks 6.2 for the rtp model using pthread support + - OpenVMS 8.2 for Alpha + +. Removed code and configurations that provided support for: + - Visual C++ 6.0 and 7.0 + - Chorus + - pSOS + - KAI C++ on all platforms + +. Explicit template instantiation support has been removed. This effectively + removes support for Sun Forte 6 and 7 which required explicit template + instantiation to build ACE reliably. + +. Added support for multiple independent Service Repositories through + configuration contexts called "Gestalt". Full backwards compatibility + is maintained through the existing ACE_Service_Config static methods, + while direct individual repository access is enabled through instances + of the new ACE_Service_Gestalt class. ACE_Service_Config has changed to + a specialization of ACE_Service_Gestalt and is only responsible for the + process-wide configuration. + +. To support dynamically-sized ACE_Log_Record messages, the netsvcs + logging components now use ACE CDR encoding and transfer mechanisms + inspired by the examples in Chapter 4 of the C++NPv1 book. + The client and server logging daemons in ACE 5.5.2 and forward will + not interoperate with those in previous ACE versions. + +. Added a wrapper for the sendfile API (ACE_OS::sendfile()). + +. Added support for netlink sockets on Linux. + +. Added a new method, ACE_Task::last_thread(). This method returns the thread + ID (ACE_thread_t) of the last thread to exit from the ACE_Task object. + Users checking to see if a thread is the last one out (for example, to know + when to perform cleanup operations) should compare the current thread ID to + the return value from last_thread(). This is a change from the previously + recommended practice (C++NPv2, page 189) of comparing the return value of + thr_count() with 0. + +. Changed the first argument to ACE_OS::strptime() to be 'const' which + matches its usual usage in POSIX strptime(). This change allows users to + pass const strings in - a common use case. + +. Made part of the file support in ACE 64bit but we have some places where + 32bit types are used, this could lead to some conversion warnings which + will be addressed in the near future, but getting everything 64bit + compliant is a lot of work. + +USER VISIBLE CHANGES BETWEEN ACE-5.5 and ACE-5.5.1 +==================================================== + +. Added support for the --enable-symbol-visibility configure option + to the autoconf build infrastructure instead of solely relying on + feature tests to enable/disable symbol visibility support. This + avoids build problems with icc, etc. + +. Added support for the --enable-fl-reactor configure option to the + autoconf build infrastructure to build the ACE_FlReactor library. + +. Added support for the --enable-qt-reactor configure option to the + autoconf build infrastructure to build the ACE_QtReactor library. + +. Added support for the --enable-xt-reactor configure option to the + autoconf build infrastructure to build the ACE_XtReactor library. + +. Fixed a bug that would cause timer IDs from ACE_Timer_Heap to be + improperly duplicated under certain conditions (Bugzilla #2447). + +. Fixed ACE_SSL_Context::private_key(), context(), and dh_params() methods + to allow retrying a file load after a failed call. + +. Fixed ACE_SSL_Asynch_Stream so it can be instantiated; also moved the + declarations for ACE_SSL_Asynch_Read_Stream_Result, + ACE_SSL_Asynch_Write_Stream_Result, and ACE_SSL_Asynch_Result classes + to the ace/SSL/SSL_Asynch_Stream.h file so applications can see them. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.10 and ACE-5.5 +==================================================== + +. Added a platform macros option "templates=manual", currently only + applies to AIX 5.3 with XL 7 compiler. It allows the user to tell the + compiler to set -qnotempinc and -qnotemplateregistry and works well + in static builds. + +. ACE and its tests compile error free with GCC 4.1 pre release. + +. ACE_Recursive_Thread_Mutex::get_nesting_level() fixed for 64-bit Windows + XP on amd64/EM64T hardware. + +. Many build-time fixes for Windows Mobile 5 and Windows PocketPC 2003 using + Visual Studio .NET 2005 (VC8). + +. Added support for the --enable-tk-reactor configure option to the + autoconf build infrastructure to build the ACE_TkReactor library. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.9 and ACE-5.4.10 +==================================================== + +. Fixed a bug in ACE_Timer_Heap_T::cancel(). + +. Improved ACE_Time_Value support for boundary conditions. + +. Fixed problems with operator placement delete on certain C++ compilers. + +. Fixed a bug with the ACE_SPIPE_Acceptor on Windows. + +. Correctly set sockaddr_in.sin_len and sockaddr_in6.sin6_len on + platforms that have these fields. + +. Avoided problems with namespace pollution for max() macros. + +. Many fixes for ACE_LACKS* and ACE_HAS* macros for autoconfig. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.8 and ACE-5.4.9 +==================================================== + +. Added dozens of new ACE_LACKS and ACE_HAS defines which are used to + simplify the ACE_OS layer + +. Constructors of ACE_Time_Value have been made explicit to prevent + implicit conversions. + +. Added a shutdown() method to ACE_Barrier. The new method aborts the + wait by all threads. + +. Changed the behavior of ACE_Message_Queue::enqueue_head() and + enqueue_tail(). If the enqueued message block has other blocks + chained to it via its next() pointer, the entire chain of blocks + will be enqueued at once. + +. Improved the support for high-resolution timers with + ACE_Timer_Queue_Adapter. + +. Make it possible to disable file caching in JAWS. + +. Improved ACE_Pipe implementation so that it uses localhost to avoid + firewall problems. + +. Added Unicode support to the Service Configurator. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.7 and ACE-5.4.8 +==================================================== + +. Improved IPv6 support + +. Improved 64bit portability + +. TTY_IO overhaul + - Improved documentation. + - It is now possible to request infinite timeout in portable manner. + This can be achieved by setting negative value to readtimeoutmsec. + - Various bugs fixed and portability issues resolved. + +. Subset ACE for TAO and TAO Services + +. Support for Intel C++ 9.0 on Windows and Linux + +. Support for Microsoft Visual Studio 2005 (aka VC8) for Win32 as well + as the Windows CE platforms Pocket PC 2003 and Windows Mobile 5. + Solution/project files are generated with an appended "_vc8" for + Win32 and "_WinCE" for the CE platforms. See + ACE_wrappers/docs/CE-status.txt for more information. + +. Completed implementation of ACE_Dev_Poll_Reactor using the Linux epoll + facility; tested on Red Hat Enterprise Linux 4. + +. The in-memory size of an ACE_RB_Tree will be smaller due to rearranged + placement of pointers. + +. Added an optimization to CDR stream to ignores alignment when marshaling + data. Use this new ACE_LACKS_CDR_ALIGNMENT compile-time option only + when the ACE_DISABLE_SWAP_ON_READ macro is enabled. This new option + requires ACE CDR engine to do both marshaling and demarshaling, and + when this option is enabled the encoded streams are no longer + compliant with the CORBA CDR specification. + +. Developed Feature Oriented Customizer (FOCUS) tool to enable + specialization of middleware frameworks such as Reactor and Protocol + framework. FOCUS provides an XML based transformation engine, where + the transformations to specialize the components are captured in XML + file and a weaver specializes the code. + +. Added support for unrolling ACE_OS::memcpy copy loop where + applicable to improve performance. Autoconf tests empirically + determine whether loop unrolling is at least 10% better than default + version. + +. Added support for an ACE "versioned" namespace. When enabled, ACE + library sources will be placed within a namespace of the user's + choice or a namespace of the form ACE_5_4_7 by default, where + "5_4_7" is the ACE major, minor and beta versions. The default may + be overridden by defining the ACE_VERSIONED_NAMESPACE_NAME + preprocessor symbol. Enable overall versioned namespace support by + adding "versioned_namespace=1" to your MPC default.features file. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.6 and ACE-5.4.7 +==================================================== + +. Support for shared libraries with VxWorks + +. Support for Solaris 10 on x86 with Sun Studio 10 (C++ 5.7). + +. Extended ACE_OS::event_xxx implementation to support platforms + having either PThread support with Process Shared condition + variables or POSIX semaphores with named (process shared) + semaphore support or using the new FIFO based semaphores. + +. ACE_OS::closesocket() no longer calls ACE_OS::shutdown() on any platform + while closing the socket. It previously called ACE_OS::shutdown() on + HP-UX. Removing this call fixes the fork-and-close programming paradigm + that's common to many networked applications. + +. RMCast + - Support for message fragmentation. This will allow + for messages larger than 64K. + - Support for flow control. + - Timed recv() in RMCast::Socket. + - Per-instance configurable protocol parameters (e.g., message + retention time, NAK timeout, etc). + +USER VISIBLE CHANGES BETWEEN ACE-5.4.5 and ACE-5.4.6 +==================================================== + +. Updated RMCast to include + - Reactor-compatible interface. + - Message unavailability reporting. + - Protocol documentation. + +. Added support for 64bit Visual Age on AIX + +. Improved g++ 4.0 support. A number of RTTI related problems have been + fixed. + +. Smaller footprint. + +. Fixed memory leaks ACE_DLL and ACE_Log_Msg classes. + +. The ACE::ICMP_Socket and ACE::Ping_Socket classes were moved out of + the ACE namespace and "flattened" to ACE_ICMP_Socket and + ACE_Ping_Socket to be consistent with the rest of ACE. + +. ACE_INET_Addr::set_address() - fixed a possible struct member + alignment issue when building an IPv4-mapped IPv6 address. + +. Added a new ACE::wild_match() function to match a string based on + wildcards. + +. Added efficient overloads for string concatenation to the + ACE_String_Base class. + +. Added support for the use of pthread_getschedparam on MacOS X. + +. Fixed an issue with static initialization of TSS related classes on + static builds for Windows. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.4 and ACE-5.4.5 +==================================================== + +. Remove special handling in the Thread Specific Storage(TSS) code + that released the TSS key for ACE_TSS. ACE_TSS has + been changed to explicitly free the TSS key when necessary. + +. On Win32 systems: detect thread termination via a hook in DLLMain + for ACE.dll. This allows cleanup of TSS objects for non-ACE threads + that use ACE functions. The most common case was threads that used + ACE logging. Formerly any TSS objects created by these threads would + be leaked. + +. Added support for GNU G++ 4.0. The x.4.5 beta takes advantage of + g++ 4.0's symbol visibility. This feature is conceptually similar + to MS Windows "__declspec(dllexport)" DLL functionality. Using this + new g++ feature results in substantially improved ACE/TAO/CIAO + shared library binaries. A subset of the improvements include the + following: + + * The number of unnecessarily exported DSO/DLL symbols is + greatly reduced, resulting in faster program start times. + * Smaller footprint. + * Improved performance since run-time indirection of internal + symbols is no longer needed. + + No changes to the ACE/TAO sources were necessary to support this + feature since the required visibility attributes were hidden behind + the various "*_Export" macros (formerly only useful for MS Windows + DLLs) used throughout ACE/TAO. + +. The ACE_Reactor destructor will now call close() on the referenced reactor + implementation. This assures that all handlers are notified before the + ACE_Reactor object that's most likely referenced in these handlers is + invalid. Although this should not be a user-visible change, it did catch + some ACE tests off guard destroying reactor implementations and ACE_Reactor + interfaces in the wrong order, so it may come up in the field as well. + When using dynamically allocated reactor implementations, do not destroy + the implementation object before the ACE_Reactor interface object. Use of + the ACE_Reactor constructor's delete_implementation argument (with a value + of 1) is recommended when dynamically allocating reactor implementations. + +. Improved performance of HTBP by not requiring a lookup of peer hostname. + +. Added new ACE_SizeCDR stream which allows one to calculate size of the + representation without writing anything. + +. Number of improvements in RMCast, reliable multicast implementation. + +USER VISIBLE CHANGES BETWEEN ACE-5.4.3 and ACE-5.4.4 +==================================================== + +. The ace-config script has been replaced by pkg-config metadata files + which are installed in ${prefix}/lib/pkgconfig by the automake build. + +. Remove ACE_OS::gets() implementation. While this ACE implementation + of gets() did not contain the security holes that all standard + gets() implementations have, keeping it around only serves to foster + confusion since (1) some may incorrectly assume that this + ACE-specific gets() implementation has the same holes as standard + ones, and (2) invoking it with a default size argument so that it + looks like a standard gets() call results in behavior that is + different from the standard. Use ACE_OS::fgets() instead. + +. Removed ACE_Unbounded_Set_Ex, this gave the false idea that it had + thread safe iterators. Use ACE_Unbounded_Set instead + +. Improved VxWorks support for static libraries. Shared libraries do cause + several known problems which will be fixed in the x.4.5 release. + +. Removed the usage of the ACE_x_cast macros, we are using the C++ casts + from now on. The ACE_x_cast macros are deprecated and will be removed + after the x.5.1 release + +. Some improvements in autoconf support; better detection of available + OS and compiler features. + +. Fixed bugs in ACE TSS emulation + +USER VISIBLE CHANGES BETWEEN ACE-5.4.2 and ACE-5.4.3 +==================================================== + +. Improved Cygwin 1.5.12 support, 90% of the tests now succeed + +. Improved OpenVMS support. + +. Added ability to use fltk with Cygwin/MinGW + +. Added ACE_INT64 that defines a native 64 bit type. + +. Added 'q' as usable specifier for ACE_Log_Msg to print out int64 bit number. + +. Added better support for Intel C++ compilers. + +. Improved HPUX support. + +. Added a new directory ("ACE_wrappers/protocols/ace") for new protocols + that are not directly components of ACE, but are relate to ACE and + defined a new protocol, HTBP (Hypertext Tunneling, Bidirectional + Protocol) providing ACE_Acceptor/Connector/Stream semantics over a + connection owned by an HTTP proxy. Test cases in + ACE_wrappers/tests/HTBP provide examples of use. + +. Performace enhancement in TP_Reactor's handle_timer_events method [Bug + 1971]. + +. Various changes to permit ACE to execute on HP NonStop platform (e.g + support for its pthreads version). + +. Updated HP NonStop configuration files (config-tandem-nsk). + +. The "ACE" pseudo-namespace is now a true C++ namespace. Transitional + pseudo-namespaces that were only meant to be used internally by ACE, + such as "ACE_Sock_Connect", no longer exist. + +. ACE_CDR::Boolean type is now a true C++ "bool" on all platforms except + MSVC++ 6. We plan to deprecate MSVC++ 6 support sometime after the + x.5 release of ACE+TAO+CIAO, so we recommend you start migrating to a + later version of MSVC++. + +. More GNU g++ 3.4.x fixes. + +. Added ICMP and "ping" socket support. + +. Added mkstemp() emulation. + +. Fixed problem on Linux < 2.5.47 platforms where equality comparison of + two logically equal sockaddr_in structure instances would incorrectly + fail. + +. Support for wide characters has been improved on non-Windows + platforms. + +. A number of Windows CE problems have been fixed. + +. ACE's loading of DLLs (for example, as a result of loading synamic + services) has been changed to use the native OS's facilities for + locating the DLL instead of searching LD_LIBRARY_PATH (or its + equivalent) then loading the DLL using a full pathname. This restores + enforcement of a platform's loading and security policy. To use the + old DLL locating method, add ACE_MUST_HELP_DLOPEN_SEARCH_PATH to your + config.h file before building ACE. + +. A number of errors in the APG example programs have been corrected. + +. Select_Reactor and Priority_Reactor performance improved. [Bug 1890] + +. Wide-char functionality on POSIX (Linux, etc.) + +. TSS memory leak fixes [Bug 1542] + +. Ported to HPUX 11i v2 on Itanium + +. Added code to ACE for platform RedHat AS 3.0 on Opteron. + +. Changed ACE::crc32() family of functions to NOT fold in the length of + the string/buffer/iovec into the CRC. + + +USER VISIBLE CHANGES BETWEEN ACE-5.4.1 and ACE-5.4.2 +==================================================== + +. Support for g++ 3.4.1. + +. All ACE Makefiles, project files, etc, are now generated by OCI's + "MakeProjectCreator" (MPC) tool. Makefiles and project files for + commonly used configurations have been pre-generated and distributed + with the beta(s). Please see: + + $ACE_ROOT/ACE-INSTALL.html + + for information on how to use MPC with ACE. + +. Improved Doxygen documentation. + +. Reduced header file dependencies, which should speedup compilation + and help minimize static footprint. + +. ACE now requires support for the following standard C++ features: + + - "bool" keyword + + - "mutable" keyword + + - "explicit" keyword + + - C++ casts (e.g. static_cast<>, reinterpret_cast<>, dynamic_cast<> + and const_cast<>) + + If you're using a compiler that does NOT support these features + please contact Steve Huston for support. + +. Changed the select()-based reactor implementations to scan for + broken handles to remove based on the registered handles, not on + event handlers. This allows for bad handles to be removed from the + reactor even if the event handler doesn't implement get_handle() the + way we expect. + +. Support for Pthreads native recursive mutexes was added. This + capability is specified to ACE_OS::mutex_init() as an optional + argument, lock_type. To fix confusion from an earlier attempt to add + this functionality, the meaning of the old 'type' argument to + ACE_OS::thread_mutex_init() is changed. It previously combined the + scope and type. Now it is just the type (e.g. recursive), as the + scope is inherent in the method used. For clarification on + ACE_HAS_RECURSIVE_MUTEXES, it means that the platform is capable of + them, not that they always are, as one would expect. However, before + Pthreads had recursion added, it was never optional. Now it is. + +. Initial support for new Linux sys_epoll() interface in + Dev_Poll_Reactor. The obsolete Linux /dev/epoll interface is no + longer supported. + +. Improved Cygwin support. + - Threading works without problems. + - Problems with shared memory, process shared mutexes, multicast and + some other small things still exist. + +. New OpenVMS port. + - This is for the latest version of OpenVMS with all available ECOs + applied. Basic stuff works without problems. Advanced features + still need some work. + +. Usage of ASYS_INLINE is deprecated in ACE. Use ACE_INLINE instead. + +. All inline source files now end in ".inl". The previous ".i" + extension is generally used for preprocessed C sources. + +. Autoconf support has been improved and fixed on a number of + platforms, including the BSD variants (e.g. FreeBSD). It is still + not the preferred way to configure most platforms, but it is ready + for wider testing. Please report any problems found to + ace-bugs@cs.wustl.edu. + +. A number of fixes were made to quiet compile errors and warnings on + 64-bit Windows. + +. For builds on AIX using Visual Age C++, the make rtti option default + was changed to 1, enabling RTTI by default. + +. ACE_Service_Repository::remove() has a new, optional argument that + can receive the service record pointer for the removed service. If + the pointer is returned to the caller, it is not deleted. If the + pointer is not returned to the caller (the default) it is deleted + (this is the historic behavior). + +. The tutorials in ACE_wrappers/docs have been removed. They were not + being maintained and caused confusion in a number of cases. Now that + there are complete examples that match the printed books (C++NPv1, + C++NPv2, APG), the older tutorials are no longer useful. Please see + + $ACE_ROOT/examples/C++NPv1/ + $ACE_ROOT/examples/C++NPv2/ + $ACE_ROOT/examples/APG/ + + for the source code of the examples in those books. + +. ACE_String_Base::fast_clear() is a new method which sets the string + length to 0. Doesn't release string-allocated memory, but if the + memory was externally supplied, it is no longer referenced from the + string object. + +. A true C++ "bool" is now used as the CDR stream boolean type, if + supported by the compiler. + +. Renamed AIX 5L configuration header from config-aix5.1.h to + config-aix-5.x.h. + +. All C++ equality, relational and logical operators now return bool + instead of int, as is the norm for modern C++. + +. Added new ACE_OS::realpath() implementation. Contributed by Olli + Savia + + +USER VISIBLE CHANGES BETWEEN ACE-5.4 and ACE-5.4.1 +==================================================== + +ACE +--- + +. Fixed "make install" support in ACE+autoconf configurations. + +. Fixed autoconf support on Solaris. + +. Corrected invalid `aux' directory (on MS Windows) found in ACE + distribution. + +. ACE/TAO build now without problems with MinGW and all ACE tests run + now without problems + +. Added some more support for the new CBuilderX Preview compiler, this + is not 100% ready yet because the compiler is still a preview and + has its own problems. + +. Added Visual SlickEdit 8.1 MPC template + +. Added workaround for compile problems in Borland Release builds + +. Cygwin 1.5.9 is now supported + +. Tests for IPV6 have been added + +. Implement lstat() so that it'll use stat() on platforms that don't + support lstat(). + +. Problems related to ACE_Event_Handler usage in WFMO_Reactor was + fixed. + +. A wrapper for rmdir () has been added. + +. Threads spawned in thread-per-connection mode never inherited the + priority. This problem was fixed and this fix is consistent with the + C++ NPV* books. + +. Fixed memory leaks with ACE_String_Base::resize () + +. Enable the usage of native recursive mutexes for the implementation + of ACE recursive mutexes on Linux. + +. The ACE Proactor framework can now be enabled for AIX 5.2. Since AIO + functionality is not run-time enabled by default on AIX 5.2, the ACE + Proactor code is not built by default on AIX. To enable it, the + config.h file must contain #define ACE_HAS_AIO_CALLS before + including the config-aix-5.1.h file. + +. The ACE_POSIX_CB_Proactor implementation is now built on all + platforms except LynxOS. + + +USER VISIBLE CHANGES BETWEEN ACE-5.3.6 and ACE-5.4 +================================================== + +ACE: +--- +. Added a new makefile commandline flag, static_link, that can be + used to force static linking when static_libs_only is turned on. It + uses the new STATIC_LINK_FLAG variable and is currently only + implemented for for GNU ld, i.e., it adds the "-static" option to + LDFLAGS. It's turned off by default since using it causes the + footprint to go up by almost 1 MB on Linux, since it links all the + system and compiler .a files, but can be turned on if users + want/need to use it, by enabling both static_libs_only and static_link. + + +. Added macros ACE_USES_GPROF which enables users to use gprof in a + multithreaded environment with ACE libs. + +. Added a new functor template class, ACE_Malloc_Lock_Adapter_T, + that's used by ACE_Malloc_T as a factory for the ACE_LOCK template + parameter, and allows the use of locking strategy classes, like + ACE_Process_Semaphore and ACE_Thread_Semaphore that don't have a + satisfactory ctor taking a single required ACE_TCHAR* parameter, to + be adapted to work with ACE_Malloc_T. + +. The source code examples from "The ACE Programmer's Guide" book by + Huston, Syyid, and Johnston, are now located in + $ACE_ROOT/examples/APG. + +. Support for GNU autoconf is now in ACE. Please see ACE-INSTALL.html + for details. + +. Fixed problems that prevented ACE from being compiled on LynxOS + 4.0.0. + +. Fixed compilation error which prevented ACE from being compiled when + ACE_COMPILE_TIMEPROBES was set to 1. + +. Preliminary support for Tandem NSK has been added. + +. Lots of bug fixes with TLI and XPG5. Please see $ACE_ROOT/ChangeLog + for details. + +. Fixed ACE_OS::event_timedwait() and ACE_OS::event_wait() so that + they use a while loop around the ACE_OS::cond_[timed]wait() calls to + avoid problems with spurious wakeups, etc. + +. ACE's wrapper around getipnodebyname() and getipnodebyaddr () has + been made go through the IPv4-only case on ACE_WIN32. Since Windows + IPv6 implementation doesn't offer support (at thistime) for + getipnodebyname() the code has been changed to use the IPV4 part of + the code. + +. Install with Borland C++ of ACE library fixed + +ACEXML: +------- + +. Fixed memory leak in ACEXML parser. + +. Fixed implementations of rewind() in all the CharStreams. They were + broken previously. + +. Fixed bugs in the parser associated with incorrect handling of PE + References for keywords. diff --git a/dep/ACE_wrappers/PROBLEM-REPORT-FORM b/dep/ACE_wrappers/PROBLEM-REPORT-FORM new file mode 100644 index 000000000..5382135f4 --- /dev/null +++ b/dep/ACE_wrappers/PROBLEM-REPORT-FORM @@ -0,0 +1,90 @@ +[Please use the PRF form below to submit bug reports, problem reports, + etc., to the ACE developers and interested users. Send to + ace-bugs@cs.wustl.edu. If you are using OCI, PrismTech, or + Riverace's versions of ACE do not send bugs to this mailing list, but + instead contact those companies for support. Please also send your + PRF as plain ASCII text, _not_ uuencoded or as an attachment. + + We prefer that all bug reports be submitted through our bug tracking + system. See $ACE_ROOT/docs/usage-bugzilla.html for more information + about how to do this. If you are unsure as to whether your problem + is a real bug or not then please submit your question to the mailing + list using the following form. Not using the problem report form + will make it harder or impossible to identify the problem, and in + many cases we will be unable to help at all. Also please try to + browse bugzilla and the ChangeLog files to find out if your problem + has been solved in a more recent version of ACE. + + To ensure that you see responses, please do one of the following: + + 1) Subscribe to the ace-bugs mail list, by sending email with + contents "subscribe ace-bugs" to majordomo@cs.wustl.edu. + + 2) Or, monitor the comp.soft-sys.ace newsgroup for responses. + + Replace/remove all the explanatory text in brackets before mailing. + + Please send this form as ASCII text only. Do _not_ send it as an + attachment, or as tar'ed, compressed and/or uuencoded text. And + limit line lengths to less than 80 characters. + + PLEASE make your Subject: line as descriptive as possible. + Subjects like "ACE bug" or "bug report" are not helpful! + Also, do _not_ include the word "help" in the Subject!] + + When including your config.h and platform_macros.GNU files as requested + below, only include the contents if you use the recommended method of + including the platform-specific file in your file. If you use a link + to the platform-specific file, simply state which one - DO NOT + include an entire platform-specific configuration file in the form. + +8<----------8<----------8<----------8<----------8<----------8<----------8<---- + +To: ace-bugs@cs.wustl.edu +Subject: [area]: [synopsis] + + ACE VERSION: 5.6.6 + + HOST MACHINE and OPERATING SYSTEM: + If on Windows based OS's, which version of WINSOCK do you + use?: + + TARGET MACHINE and OPERATING SYSTEM, if different from HOST: + COMPILER NAME AND VERSION (AND PATCHLEVEL): + + THE $ACE_ROOT/ace/config.h FILE [if you use a link to a platform- + specific file, simply state which one]: + + THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE [if you + use a link to a platform-specific file, simply state which one + (unless this isn't used in this case, e.g., with Microsoft Visual + C++)]: + + CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.features + (used by MPC when you generate your own makefiles): + + AREA/CLASS/EXAMPLE AFFECTED: +[What example failed? What module failed to compile?] + + DOES THE PROBLEM AFFECT: + COMPILATION? + LINKING? + On Unix systems, did you run make realclean first? + EXECUTION? + OTHER (please specify)? +[Please indicate whether ACE, your application, or both are affected.] + + SYNOPSIS: +[Brief description of the problem] + + DESCRIPTION: +[Detailed description of problem. Don't just say " +doesn't work, here's a fix," explain what your program does +to get to the state. ] + + REPEAT BY: +[What you did to get the error; include test program or session +transcript if at all possible. ] + + SAMPLE FIX/WORKAROUND: +[If available ] diff --git a/dep/ACE_wrappers/README b/dep/ACE_wrappers/README new file mode 100644 index 000000000..1b46d7fd6 --- /dev/null +++ b/dep/ACE_wrappers/README @@ -0,0 +1,222 @@ +This document is also available at the following URL: + +http://www.cs.wustl.edu/~schmidt/ACE.html + +All software and documentation is available via both anonymous ftp and +the World Wide Web.] + +THE ADAPTIVE COMMUNICATION ENVIRONMENT (ACE) + +An Object-Oriented Network Programming Toolkit + +---------------------------------------- + +Overview of ACE + +The ADAPTIVE Communication Environment (ACE) is an object-oriented +(OO) toolkit that implements fundamental design patterns for +communication software. ACE provides a rich set of reusable C++ +wrappers and frameworks that perform common communication software +tasks across a range of OS platforms, including Win32/Win64, most +versions of UNIX (e.g., SunOS, HP-UX , AIX, Linux, NetBSD, and FreeBSD), +real-time operating systems (e.g., VxWorks, Chorus, LynxOS, and QNX), +OpenVMS, and MVS OpenEdition. A single source tree is used for all +these platforms and porting ACE to other platforms is relatively easy. + +The communication software components provided by ACE include event +demultiplexing and event handler dispatching, service initialization, +interprocess communication, shared memory management, message routing, +dynamic (re)configuration of distributed services, multi-threading, +and concurrency control. There are both C++ and Java versions of ACE +available. + +ACE is targeted for developers of high-performance and real-time +communication services and applications on UNIX, POSIX, and Win32 +platforms. ACE simplifies the development of OO network applications +and services that utilize interprocess communication, event +demultiplexing, explicit dynamic linking, and concurrency. ACE +automates system configuration and reconfiguration by dynamically +linking services into applications at run-time and executing these +services in one or more processes or threads. + +ACE is currently used in commercial projects and products by dozens of +companies including Ericsson, Bellcore, Siemens, Motorola, Kodak, +Boeing, Lucent, DEC, Lockheed Martin, and SAIC. Commercial support +for ACE is available from several companies as listed at +http://www.cs.wustl.edu/~schmidt/commercial-support.html + +---------------------------------------- + +C++ Wrappers for OS Interfaces + +The lower-level portions of ACE provide a set of portable and +type-secure C++ wrappers that encapsulate the following C language OS +interfaces: + + . IPC mechanisms + -- e.g., Internet- and UNIX-domain sockets, TLI, Named + Pipes (for UNIX and Win32) and STREAM pipes; + + . Event demultiplexing + -- e.g., select(), poll(), and Win32 + WaitForMultipleObjects and I/O completion ports; + + . Multi-threading and synchronization + -- e.g., Solaris threads, POSIX Pthreads, and Win32 + threads; + + . Explicit dynamic linking + -- e.g., dlopen/dlsym on UNIX and LoadLibrary/GetProc + on Win32; + + . Memory-mapped files and shared memory management + -- e.g., BSD mmap(), SYSV shared memory, and Win32 + shared memory; + + . System V IPC + -- e.g., shared memory, semaphores, message queues. + +The OS Adaptation Layer shields the upper levels of ACE from platform +dependencies associated with the underlying OS interfaces. + +---------------------------------------- + +Frameworks and Class Categories + +ACE also contains a higher-level network programming framework that +integrates and enhances the lower-level C++ wrappers. This framework +supports the dynamic configuration of concurrent distributed services +into applications. The framework portion of ACE contains the +following class categories: + + . The Reactor + -- Supports both Reactive and Proactive I/O; + + . The Service Configurator + -- Support dynamic (re)configuration of objects; + + . The ADAPTIVE Service Executive + -- A user-level implementation of System V STREAMS, + that supports modular integration of + hierarchically-related communicaion services; + + . Concurrency + -- Various types of higher-level concurrency + control and synchronization patterns (such as + Polymorphic Futures and Active Objects); + + . Shared Malloc + -- Components for managing dynamically allocation + of shared and local memory; + +---------------------------------------- + +Distributed Services and Components + +Finally, ACE provides a standard library of distributed services that +are packaged as components. These service components play two roles +in ACE: + + 1. They provide reusable components for common distributed + system tasks such as logging, naming, locking, and time + synchronization. + + 2. They illustrate how to utilize ACE features such as the + Reactor, Service Configurator, Service Initialization, + Concurrency, and IPC components. + +---------------------------------------- + +Middleware Applications + +ACE has been used in research and development projects at many +universities and companies. For instance, it has been used to build +avionics systems at Boeing, telecommunication systems at Bellcore, +Ericsson, Motorola, and Lucent; medical imaging systems at Siemens and +Kodak; and many academic research projects. Two example middleware +applications provided with the ACE release include: + + 1. The ACE ORB (TAO) -- TAO is a real-time implementation of + CORBA built using the framework components and patterns + provided by ACE. + + 2. JAWS -- JAWS is a high-performance, adaptive Web server + built using the components in ACE. + +---------------------------------------- + +OBTAINING ACE + +The current ACE release is provided as a tar file that is around 3 Meg +compressed using GNU gzip. ACE may be obtained electronically from +http://www.cs.wustl.edu/~schmidt/ACE-obtain.html. This release +contains the source code, test drivers, and example applications +(including JAWS) for C++ wrapper libraries and the higher-level ACE +network programming framework developed as part of the ADAPTIVE +project at the University of California, Irvine and at Washington +University, St. Louis. + +You can get The ACE ORB (TAO) in a companion release at +http://www.cs.wustl.edu/~schmidt/TAO.html. + +---------------------------------------- + +ACE DOCUMENTATION AND TUTORIALS + +Many of the C++ wrappers and higher-level components have been +described in issues of the C++ Report, as well as in proceedings of +many journals, conferences, and workshops. + +A collection of white papers and tutorial handouts are included at +ftp://wuarchive.wustl.edu/languages/c++/ACE/ACE-documentation. This +directory contains postscript versions of various papers that describe +different aspects of ACE. + +I update these papers periodically to reflect changes to the ACE +architecture. Therefore, you might want to check the date on the +files to make sure that you have read the most recent versions of +these papers. + +This material is also available available via the WWW at URL: + +http://www.cs.wustl.edu/~schmidt/ACE.html + +---------------------------------------- + +ACE MAILING LIST AND NEWSGROUP + +A mailing list, ace-users@list.isis.vanderbilt.edu, is available for discussing +bug fixes, enhancements, and porting issues regarding ACE. Please +send mail to me at the ace-users-request@list.isis.vanderbilt.edu +if you'd like to join the mailing list. There is also a USENET newsgroup +called comp.soft-sys.ace. Please see +http://www.cs.wustl.edu/~schmidt/ACE-mail.html for details on how to +subscribe to the mailing list. + +---------------------------------------- + +BUILDING AND INSTALLING ACE + +Please refer to the http://www.cs.wustl.edu/~schmidt/ACE-install.html +file for information on how to build and test the ACE wrappers. The +BIBLIOGRAPHY file contains information on where to obtain articles +that describe the ACE wrappers and the ADAPTIVE system in more detail. + +The current release has been tested extensively, but if you find any +bugs, please report them to the ACE mailing list +ace-users@cs.wustl.edu using the $ACE_ROOT/PROBLEM-REPORT-FORM. +Please use the same form to submit questions, comments, etc. +To ensure that you see responses, please do one of the following: + + 1) Subscribe to the ace-users mail list, by sending email with + contents "subscribe ace-users" to + ace-users-request@list.isis.vanderbilt.edu. + + 2) Or, monitor the comp.soft-sys.ace newsgroup for responses. + +---------------------------------------- + +ACKNOWLEDGEMENTS + +Please see the file `$ACE_ROOT/THANKS' for a list of the thousands of +people who've contributed to ACE and TAO over the years. diff --git a/dep/ACE_wrappers/THANKS b/dep/ACE_wrappers/THANKS new file mode 100644 index 000000000..269b5fd7d --- /dev/null +++ b/dep/ACE_wrappers/THANKS @@ -0,0 +1,2289 @@ +ACKNOWLEDGEMENTS + +ACE and TAO have been deeply influenced and improved by the following +members of my research group at Washington University in St. Louis, the +University of California at Irvine, and Vanderbilt University in Nashville. + +Everett Anderson +Alexander Babu Arulanthu +Shawn Atkins +Jaiganesh Balasubramanian +Krishnakumar Balasubramanian +Matt Braun +Darrell Brunsch +Dante J. Cannarozzi +Sharath R. Cholleti +Chris Cleeland +Angelo Corsaro +Gan Deng +Mayur Deshpande +Eric Ding +George Edwards +Sergio Flores-Gaitan +Chris Gill +Andrew G. Gilpin +Aniruddha Gokhale +Priyanka Gontla +Pradeep Gore +Matthew P. Hampton +Tim Harrison +John Heitmann +James Hill +Shawn Hannan +Don Hinton +Joe Hoffert +James Hu +Huang-Ming Huang +Frank A. Hunleth +Prashant Jain +Shanshan Jiang +Vishal Kachroo +Michael Kircher +Boris Kolpackov +Arvind S. Krishna +Yamuna Krishnamurthy +Fred Kuhns +David Levine +Tao Lu +Mike Moran +Sumedh Mungee +Balachandran Natarajan +Will Otte +Kirthika Parameswaran +Krishnakumar Pathayapura +Stoyan Paunov +Carlos O'Ryan +Ossama Othman +Jeff Parsons +Irfan Pyarali +Nilabja Roy +Lucas Seibert +Diego Sevilla Ruiz +Nishanth Shankaran +Marina Spivak +Venkita Subramonian +Nagarajan Surendran +Cassia Tatibana +Sumant Tambe +Gabriele Trombetti +Emre Turkay +Nanbor Wang +Seth Widoff +Jules White +Friedhelm Wolf +Torben Worm +Ming Xiong + +I would also like to thank all the following people who have also +contributed to ACE and TAO over the years: + +Paul Stephenson +Olaf Kruger +Ed Brown +Lee Baker +Alex Ranous +Mark Patton +Steffen Winther Sorensen +Troy Warner +Stacy Mahlon +Charles Eads +Mark Frutig +Todd Hoff +George +Brad Needham +Leslee Xu +Detlef Becker +Bruce Worden +Chris Tarr +Bill Sears +Greg Lavender +Steve Warwick +Mats Sundvall +Andreas Ueltschi +Nigel Hooke +Medhi Tabatabai +Stuart Powell +Bin Mu +Andrew McGowan +Ken Konecki +John P. Hearn +Giang Hoang Nguyen +Carlos Garcia Braschi +Jam Hamidi +Eric Vaughan +Karlheinz Dorn +Gerhard Lenzer +Steve Ritter +Chandra Venkatapathy +Matt Stevens +Bob Vistica +David Trumble +George Reynolds +Hans Rohnert +Alex V. Maclinovsky +Todd Blanchard +Rob Clairmont +Christian Millour +Neil B. Cohen +Dieter Quehl +Reginald S. Perry +James Morris +Mark Seaborn +Phil Brooks +E. Jason Scheck +Daniel Proulx +Bill Tang +John Huchinson +Jack Erickson +Byron Walton +Bill Lear +Mark Zusman +Aurelio Nocerino +Walt Akers +Greg Baker +Alexandre Karev +Pramod Kumar Singh +Bryon Rigg +Brad Brown +Patty Genualdi +Eshel Liran +Mick Adams +Chris Eich +Mike Flinn +Audun Tornquist +Sandeep Joshi +Bernd Hofner +Craig Perras +Kirk Sinnard +Matthew Newhook +Gerolf Wendland +Phil Mesnier +Ross Dargahi +Richard Orr +Rich Ryan +Jan Rychter +Tom Marrs <0002104588 at mcimail dot com> +Bob Olson +Jean-Francois Ripouteau +Ajit Sagar +Ashish Singhai +David Sames +Gonzalo Diethelm +Raj +Darrin Edelman +Steve Weismuller +Eric C. Newton +Andres Kruse +Ramesh Nagabushnam +Antonio Tortorici +Nigel Lowe +Tom Leith +Michael Fortinsky +Marco Sommerau +Gary Salsbery +Eric Beser +Alfred Keller +John Lu +James Mansion +Jesper S. M|ller +Chris Lahey +Michael R"uger +Istvan Buki +Greg Wilson +Garrett Conaty +Brad Flood +Marius Kjeldahl +Steve Huston +Eugene K. Plaude +Joseph DeAngelis +Kim Gillies +Luca Priorelli +Alan Stewart +Hani Yakan +William L. Gerecke +Craig Johnston +Pierre-Yves Duval +Rochi Febo Dommarco +Jonathan Biggar +Scott Shupe +Chuck Gehr +Avi Nash +Padhu Ramalingam +Jay Denkberg +Ayman Farahat +Tilo Christ +rev +Hamutal Yanay +Vital Aza +Alex Villazon +David Artus +Todd Barkalow +Alexander Smundak +Thilo Kielmann +Matthias Kerkhoff +Fred LaBar +Hanan Herzog +Eric Parker +James Michael Dwyer +Arun Katkere +Bob Dunmire +Sandro Doro +Robert Lyng +Phil Logan +John Cosby +Wayne Vucenic +Harry Gunnarsson +James CE Johnson +Samuel_Bercovici +Per Andersson +Anthony McConnell +Mark Rabotnikov +John Bossom +Rino Simioni +Slawomir Kuzniar +Rob Jordan +Michael Maxie +John Cosby +Nigel Owen +Jorn Jensen +Paul Roman +Dave Mayerhoefer +Bert Craytor +Joey Zhu +Arthur J. Lewis +Michael R. MacFaden +Paul Han +Jeff Morgan +Arturo Montes +Elliot Lau +Mark Wright +Michael Newton +Kumar Neelakantan +Scott Halstead +Jean-Marc Strauss +Adam Porter +Hakan Kallberg +Eric Dean Russell +Daniel Montalibet +Norbert Rapp +Ganesh Pai +Berni Merkle +Tom Wright +Torbjorn Lindgren +Mike Bernat +Brian Mendel +Jeremy Buch +Kevin Boyle +Kevin Martindale +Luis Lopes +Adrian Salt +Hongbo Xu +Michael Hartman +Tom Dobridge +Rich Christy +Satoshi Ueno +Eugene R. Somdahl +Robert Head +Ivan Murphy +Jan Perman +Shankar Krishnamoorthy +Reza Roodsari +Jim Crossley +Johannes Gutleber +Yigong Liu +Erik Urdang +Mike Schweiger +Anthony Mutiso +Jeff R. Hayes +David Brackman +Dave Moore +Joseph Cross +Cherif Sleiman +Stefan Ericsson +Thanh Ma +Oleg Krivosheev +Stephen Coy +Bob Laferriere +Satheesh Kumar MG +Karen Amestoy +Jeff Richard +Samuel Melamed +Vladimir Schipunov +Felix Popp +Billy Quinn +Michael McKnight +Huiying Shen +Alex Chan +Aaron Valdivia +Edan Ayal +Jeffrey Peterson +Neil Lavelle +Steven Wohlever +Manojkumar Acharya +Evgeny Beskrovny +Kirill Rybaltchenko +Laura Paterno +Ben Eng +Mike Kamrad +Marios Zikos +Mark L Boriack +Mark Hyett +Valik Solrzano Barboza +John Connett +Tom Arbuckle +Stephen Henry +Dani Flexer +Michael Hoffman +John Lindal +Dustin Laurence +Ernie Makris +Timothy A. Brown +Pat McNerthney +Lori Anderson +Erik Margraf +Bryan Doerr +Adam Miller +Thomas Jordan +Keith Nicewarner +Frederic Andres +Achint Sandhu +Mitch Kuninsky +Alex Chan +Jeff Hellzen +Thomas Venturella +Philippe O'Reilly +Stan Leeson +Richard Keizer +Edgar Villanueva +Oliver Kellogg +Dave Meyer +Thomas Hampson +Jay Kistler +Scott Snyder +Mark Evans +Todd Pack +Mark Maris +Jason Katz +Jim Penny +Chris Ryan +J dot Russell Noseworthy +Carol Sanders +Jerry Bickle +Paul von Behren +Sudish Joseph +Loren Rittle +Alexander Ovsiankin +Ravi Nagabhyru +Tom Brusehaver +Dave Tallman +Monish Rajpal +Garry Brother +Andreas Schuelke +Ganapathi +James Garrison +Brad Walton +Paul Motuzenko +Kurt Sussman +Rob Thornton +Chanaka Liyanaarachchi +Saneyasu +Steve Kay +Greg White +Ki-hyun Yoon +Umar Syyid +Bill Fulton +Amancio Hasty +Zoran Ivanovic +Sree Oggu +James Risinger +Leo Modica +Bob Scott +Mark Kettner +Kent Watsen +Chris Healey +Philippe Klein +William S. Lear +John Geiss +Ernesto Guisado +Stuart Myles +Lothar Werzinger +Andrew Harbick +Pavel Motuzenko +Ross J. Lillie +Sam Hauer +Frank J. Hodum +David Miron +Anton van Straaten +Joe Covalesky +Bill Backstrom +Jeff Franks +John Mulhern <9107 at mn3 dot lawson dot lawson dot com> +Johan Lundin +Eric Powers +Gabriel Lima +Doug Anderson +Hongyin Quan +Maximilian Hoferer +Kevin Stanley +Jeff Greif +Jeff McDaniel +Andreas Geisler +Bob McWhirter +Daniel Winder +Zheng Han +Christa Schwanninger +Byron Harris +Barney Dalton +Peter Gorgia +Dirk Broer +Joseph E. LaPrade +Goran Lowkrantz +Susan Liebeskind +Dana Hackman +Margherita Vittone Wiersma +Priya Narasimhan +Jeff Hopper +Mats Nilsson +Dongwook Kim +Don Davis +Alberto Villarica +XuYifeng +Tom Shields +Krishna Padmasola +Andre Folkers +Paul Sexton +Marc Lehmann +Anne Blankert +Raja Ati +Clinton Carr +Peter Liqun Na +Frank Adcock +Xu Yifeng +Valery Arkhangorodsky +Alan Scheinine +Andrew G. Harvey +Dann Corbit +James +Jason Milley +Ulf Jaehrig +Peter Nordlund +Mark Weel +Tres Seaver +Erik Koerber +Eric R. Medley +David O'Farrell +Amir Bahmanyari +Ian Wright +David Janello +Rich Wellner +Fernando D. Mato Mira +Jonathan Reis +Seung-Lee Hoon +Russell L. Carter +Bill Hall +Brian Gilstrap +Balaji Srinivasan +Anders W. Tell +Larry Lachman +Terry Rosenbaum +Rainer Blome +Kirk Ellett +Sunil Kumar +T Stach +Ron Barack +Daniel Nieten +Paul K. Fisher +Jim Buck +Olivier Lau +Achim Stindt +Fredrik Lindahl +Joseph Weihs +Serge Kolgan +James Megquier +Martin Krumpolec +Michael Thomas +Vicentini Emanuele +Bob Price +Ramiro Penataro Blanco +Sigg Pascal +Ivan Leong +Virginie Amar +Tom Ziomek +Hamish Friedlander +Mark De Jong +Knut Johannessen +Leif Jakobsmeier +Jon Lindgren +Steve Vinoski +Christian Mueffling +Victor Yu +Jeff Donner +Joe Loyall +Stanislav Meduna +Christian Korn +Ron Barack +Steve Totten +Faron Dutton +Gary York +Patty Hair +Ivan Pascal +William A. Hoffman +Mark Lucovsky +Greg Holtmeyer +Jody Hagins +Patrice Bensoussan +Keith Brown +Barry Hoggard +Peter J. Mason +Jerry D. De Master +Greg Gallant +wym +Karel Zuiderveld +Mike Goldman +Peter Gross +Greg Ross +Stanford S. Guillory +Peter Weat +Magnus Karlsson +Andreas Tobler +John Aughey +Knut-Havard Aksnes +Eric Mitchell +Tommy Andreasen +Slava Galperin +Jeff Olszewski +Sudhanshu Garg +Mike Preradovic +Greg Harrison +Sangwoo Jin +Jacques Salerian +Steve Coleman +Diethard Ohrt +Jacob Jones +Phil Ruelle +Sush Bankapura +Eric Covington +Darren Whobrey +Mason Taube +Rod Joseph +Hans Horsmann +Kevin Royalty +Souhad Mcheik +Mark Little +Tim Stack +Marc Engel +Uma Markandu +Henrik Nordberg +Tad Jarosinski +Andy Marchewka +Neal Norwitz +Frederic Maria +David Hooker +Christian Destor +Andrew Hobson +Andre Folkers +Torsten Kuepper +Hao Ruan +Alexander Davidovich +Cristian Ferretti +N Becker +Yaolong Lan +Elias Sreih +Liang Chen +Mark Laffoon +Ti Z +Brian Dance +Alexey Gadzhiev +Francois Bernier +Bill Rizzi +Peter Windle +Jaepil Kim +Dmitry Goldshtain +Carl Grinstead +Henric Jungheim +Michael Preobrazhensky +Gregory D. Fee +Roland Gigler +Frank Buschmann +Eric Eide +Don Busch +Thomas Lockhart +David Hauck +Keith Rohrer +Tim Rose +Sam Rhine +Chris Schleicher +Margaret Reitz +Thomas Mehrkam +Erik Ivanenko +Sarmeesha Reddy +Steven Tine +Dave Steele +Simeon Simeonov +David H. Whittington +Ian MacDonald +Hans Ridder +Todd Mullanix +Hai Vu +Paul Francis +Kristopher Johnson +Dave Butenhof +Dominic Williams +Srikumar Kareti +Ian Pepper +Kevin Lyda +James D. Rucker +Brian Wallis +Sandeep Goyal +English Malc +Frank O'Dwyer +Long Hoang +Steven D. Chen +Alain Magloire +Jim Rogers +Nick Sawadsky +David Brownell +Richard Stallman +Casey Lucas +Brian C. Olson +Joseph A. Condlin +Serge Du +Mike Mazurek +Christian Schuderer +John R. Taylor +Bill Tovrea +Wallace Owen +Vyacheslav A. Batenin +Edwin D. Windes +Christopher Kohlhoff +Andreas Terstegge +Stefaan Kiebooms +Keith Nichol +Rebecca Sanford +Ram Vishnuvajjala +Tom Bradley +Shaun Ohagan +Dale Wood +Robert Flanders +Gul Onural +Stephen E Blake +Eric S Rosenthal +Sridevi Subramanian +Bruce Trask +Jake Hamby +Rick Weisner +Dennis C. De Mars +V dot Lakshmanan +Hata Yoshiaki +Vidya Narayanan +Sean Landis +Youzhong Liu +John Weald +Gilbert Roulot +Gildo Medeiros Junior +Brian Peterson +Fabrice Podlyski +Darren DeRidder +John Tucker +Oleg Orlov +Timothy Canham +Randy Heiland +Joyce Fu +Surender Kumar +Pradeep Avasthi +Guicheney Christophe +Madhu Konety +Isaac Stoddard +Alvarez +Peter Brandstrom +Eugene Surovegin +Thaddeus Olczyk +John Chludzinski +Pedro Alves Ferreira +Bruce Edge +Dan Butler +Ron MacKenzie +Craig Rodrigues +Phil Y. Wang +David Brock +John Morey +Dwayne Burns +Denis Ouellet +Stefan Ullrich +Brian Raven +Gheorghe Aprotosoaie +Carsten Zerbst +Paul Calabrese +Stephane Chatre +James Whitledge +Erik Johannes +Alex Hornby +Riaz Syed +Clarence M. Weaver +Roger Egbers +Ralf Kluthe +Ruud Diterwich +Bill Nesbitt +Will Skunk +David Digby +Timothy Schimke +Jim Robinson +Peter Mueller +Raghu Nambiath +Mike Gingell +David McCann +Ruediger Franke +Brian Jones +Michael Garvin +Mike Vitalo +Kirk Davies +Arno Pernozzoli +Trey Grubbs +Matthias Schumann +John Gathright +Alexander Villatora +Hoang Duong +Michael Roth +Craig Anderson +Mitsuhiko Hara +Weihai Yu +Tal Lev-Ami +Chris Zimman +Rick Wesson +Sridhara Rao Dasu +Walter Welzel +Anthony Shipman +Tobin Bergen-Hill +Toshio Hori +John Mink +Duane Binder +Randall Sharo +Dave Madden +Cliff_H_Campbell +Narendra Ravi +Krishnakumar B. +David Sunwall +Brian Wright +Yosi Sarusi +Robert Shewan +Skye Sweeney +Lars Immisch +Stefan Wendt +Herbert +Clarence Bishop +Giga Giguashvili +Philipp Slusallek +Matthew Davis +Janusz Stopa +Rusty Conover +Alex Mintz +Phillippe Merle +Mark Winrock +Boris Kaminer +Martin Botzler +Lorin Hochstein +Wenli Bai +Harry Forry +Jose Rubio +Joerg Pommnitz +Mogens Hansen +Shafiek Savahl +Pierre Grondin +John Masiyowski +Uwe Landrock +Klaus Banzer +Probal Bhattacharjya +Dmitri Katchalov +Alok Gupta +Chien Yueh +John K. Black +Kamen Penev +Gregory Yarmit +Jarek Tomaszewski +Siegurd Weber +Fabrizio Giannotti +Harald Finster +Fritz Bosch +Charles Frasch +Chris Hafey +Rick Hess +David Dunn +Jaymes Galvin +Marat +Sergey Nemanov +Vladimir Kondratiev +John Glynn +Raymond Wiker +Michael Pitman +Joseph Jefferson +Engelbert Staller +George Ball +Dennis Noll +Ronald Fischer +Marvin Allen Wolfthal +Dan Gilboa +Sean Boudreau +Shalini Yajnik +Matt Thompson +Peter C Chien +Bruce Alderson +Christoph Poggemann +Travis Shirk +Alain Sauron +David Delano +Boris Sukholitko +Brian Mason +Thomas Groth +Damien Dufour +Paulo Breda Vieira +Samuel Stickland +Bryan Van de Ven +Greg Siebers +Rob Gabbot +Paul Carreiro +Jovan Kilibarda +Derek Dominish +Devesh Kothari +Stephen Moon +Hani Mawlawi +Benedikt Eric Heinen +Jason Topaz +Alexander Dergatch +Airat A. Sadreev +Klaus Hofmann +Miroslav Koncar +Extern Chatterji +Zach Frey +Ruibiao Qiu +Marcelo Matus +R Seshardi +Stephan Kulow +Alexander Belopolsky +Ben Bourner +Lalitha Chinthamani +Thomas Huang +Sankaranarayanan K. V +Ephraim Vider +Reid Spencer +Kevin Dalley +Jan Nielsen +Jochen Linkohr +Mirko Brandner +Yuval Yosef +Chad Elliott +David X. Callaway +Soren Ilsoe +Eric Hopper +Martin Johnson +Pierre Oberson +Chris Uzdavinis +Ishay Green +Andrey Nechypurenko +Charlie Duke +Jonathan Luellen +Andrew Psaltis +Erik Jones +Ted Burghart +Mike Winter +Judy Ward +Ken Block +Jamshid Afshar +Jerry Jiang +Rob Ruff +Hugh Arnold +Hessel Idzenga +Mark C. Barnes +Suresh Kannan +Alex Scholte +Greg Jansen +Raj Narayanaswamy +Iain Melville +Daniel Lang
+Chris Leishman +Klemen Zagar +Rick Ohnemus +Adamo, Vince +Defang Zhou +Dave Zumbro +Ted Nolan +Jianfei Xu +Alvin C. Shih +J dot Scott Evans +Alex Luk +Kenneth Osenbroch +Jason Czavislak +Alex Chachanashvili +Gilbert Grosdidier +James Briggs +Herbert Wang +Anders Olsson +Sergey Gnilitsky +David Wicks +Girish Birajdar +Hajdukiewicz Markus +Gerwin Robert +Alia Atlas +David Hall +Todd Gruhn +John Hickin +Alex Brown +Rich Seibel +Jim Scheller +Bob Bouterse +Sandeep Adwankar +W Craig Trader +Bruce McIntosh +Natarajan Kalpathy +David O'Farrell +Bob Bouterse +Malcolm Spence +Dong-Yueh Liu +Craig Ball +Norbert Krain +Adrian Miranda +Cody Dean +Hans Scharkowitz +Charles Meier +Tim Sim +Shalabh Bhatnagar +Charles Scott +Espen Harlinn +mulder +Richard L. Johnson +Tam Nguyen +Jeff Graham +Ralph Loader +Ji Wuliu +Wada Hiroshi +Sal Amander +Torsten Pfuetzenreuter +John M. Mills +David McWeeny +Florian Lackerbauer +Manuel Benche +Steve Luoma +Roger Tragin +Alex Bangs +Yangfen Qiu +Johnny Chen +John Foresteire +Larry Peacock +Francisco Bravo +Antti Valtokari +John Smyder +Mathew Samuel +Conrad Hughes +John Rodgers +Charles Taurines +James Lacey +Nick Pratt +Xiaojun Wu +George Lafortune +Aoxiang Xu +Dima Skvortsov +Moore Y. Cao +Wai Keung Fung +Michael Laing +Benoit Viaud +Ken Weinert +Ferran Boladeres Salvad +Steve Vranyes +Jim Melton +Ron Klein +Anuj Singhal +Henrik Kai +Dominic Hughes +Lior Shalev +Charlie Duke +William Horn +Greg Hall +Aviad Eden +Vianney Lecroart +Russell Mora +Samir Shaikh +Eric Yee +Matt Emerson +Yiu L. Lee +Pedro Brandao +Hakon Innerdal +Sami Aario +Ingo Dahm +Vijay Aswadhati +Xiaowen Wang + +Warren Miller +Youngkwan Cho +Dorr H. Clark +Dave McNeely +Eric Malenfant +Roland Fischer +Alexander Libman +Roger Larsson +Martin Stack +Michael Ravits +Derek Viljoen +Hamed Azizadah +Keo Kelly +Joachim Achtzehnter +Tomer Amiaz +Sergey Osokin +Nick Logvinov +Viatcheslav Batenine +Shashi Bhushan +Javier Corrales +J dot Randy Pitz +Richard Reitmeyer +Xavier Montet +Letha Etzkorn +James Dabbs +Matej Sekoranja +Mattias Eriksson +Nicoletta Viale +George Reid +Kim Lester +Wilson Chan +William Rucklidge +Victor Krebss +Chander P. Thareja +John Mills +Haifeng Lee +Hans Utz +Askok Kumar Kalanithi +Chris Able +John Hiltenbrand +Steve Hespelt +Peter Fischer +Madhu Ramachandran +Caleb Epstein +Bruno Marconi +Ken Childress +Michael Kramer +Johnny Willemsen +Jonathan Astle +Javier Lopez Sanchez +Nir Drang +Albert Wijnja +Marcel Van Der Weert +Mervyn Quah +Giovanni Zito +Matthew Adams +Sameer Schabungbam +Jeff Butler +Roland Rüdenauer +John Buckman +Guy Rosen + +Bennett R. Stabile +Paul Caffrey +Low Aik long +Michael Rinne +Jaffar Shaikh +Roger Beck +Trueman Bill +Harold Bien +Mateu Batle +Philip Miller +Base V Paul +Evghenii Filippov +Mike Curtis +Jessie Ragsdale +Shourya Sarcar +Eric Crampton +Sandip Patel +ChenXu +Vsevolod Novikov +Brendan Corcoran +Steve Sivier +Rick Schneeman +Klaus H. Wolf +Jean-Christophe Dubois +Michael Hampel +Wei Zheng +Bernd Annamaier +Joachim Tremouroux +Momchil Velikov +Munagala Ramanath +Kevin Marshall +David Channon +Andy Guy +Oscar Rodriquez +Jonathan Cano +Alain Decamps +Paul Rubel +Jon Loeliger +Ricardo Chan +Sarabjeet Duhra +Michael Rushton +Arno Pernozzoli +Calum Mitchell +Jerry Odenwelder +Kent Stewart +Alexander Kogan +Michael Lindner +Arnaud Compan +Michael Searles +Bogdan Jeram +Sebastian Schubert +Li Zhou +Shivakumar Patil +Steve Olson +Allen Broadman +Yuriy Zaporozhets +Joe Guan +Attilio Dona +McGanahan Skjellifetti +Matthias Wittig +David Allen +Edwin McKay +Scott Bolin +Mike Anderson +David Singer +Nick Lin +Ron Hashimshony +Max Khon +Jonas Nordin +Jonathan Stockdale +Jean-Francois Daune +Wei Chiang +Rick Stille +Kirill Kuolechov +Edwin Wrench +Yung Trinh +Richard Eperjesi +Ben Strong +David Karr +Sathish Tiptur +Lu Yunhai +Christian Ewald +Samuel Qi Luo +Sergey Logvin +Orlando Ribeiro +Doug Warner +Kevin Regan +Andy Olson +Max Voronoy +Alexandr Gavrilov +Scott Gunn +Mason Deaver +Richard Huber +Glen Osterhout +YingLi +Haka +Sam Chong +Virgilijus Globis +Stefan Scherer +Pim Philipse +Michael Grove +John Mackenzie +Ricky Marek +Patrick Maassen +Christian Schuhegger +David L Smith +Rainer Doerntge +Tompa +Derek Horton +Shameek Basu +Dipti Jain +Eric Zuur +Jeffrey J. Persch +Rahul Shukla +Pierre Fayolle +Greg McCain +Matt Cheers +Benjamin Fry +Ram Ben-Yakir +Eric Desamore +John Ashmun +Przemyslaw Marciniak +Carsten Madsen +David Sperry +Ted Horst +Diana Arroyo +Benny Prijono +Roland Ziegler +Stelios Sfakianakis +Mike Letchworth +Brian Gilmer +James Dunham +Juergen Pfreundt +Joel Sherrill +Jules Colding +Stephane Pion +Raghu Narayan +Richard Goold +Nathalie D'Amours +Albert Pariante +Stephen Torri +Philippe Perrin +Gunnar Buason +David Hanvey +Jeff McNiel +Georg Lohrer +Rachel G Smith +Tom Lake +Logan Modahala +Jean Malenfant +Victor Poznyak +Juan Jose Comellas +James Dorsey +Benot Desmeules +Tom Moog +Stan Pinte +Dayisi +Peter Georgakakis +Richard Hardgrave +Mark Drijver +Guy Bolton King +Carlton Teel +Alexandre Cervieri +Darren Griffith +Sam Mok +Josh Curry +Norman Wilson +Itzhak Briskman +James Kanyok +Corey Trager +Kirat Singh +Oleg Pavliv +Frederick Niemi +Andrew Munro +Nicolas Huynh +Kevin Burge +Wayne Erchak +Yew Khong See +Greg Thompson +Mike Pyle +Kobi Cohen-Arazi +Israel Illescas Gomez +Brodie Thiesfield +Erik Toubro Nielsen +Masaoud T. Moonim +Steve Witten +Gil Rapaport +Boris Temkin +Steve Perkins +Jerry Thomas +cuma +Ron Heald +Andrew Finnell +Dan Levi +Rob Andzik +James Maynard +Francois Rioux +Ophir Bleiberg +Allen Kelly +Victor Pitchouc +Srikanth Vedire +J Shane Culpepper +Steffen Hieber +Craig L. Ching +Ben Howard +Rich Newman +Kelly F. Hickel +David Trusty +Burkhard Neppert +Crawford Lodge +Scott Gaa +Jenny Kowald +Oren Zeev-Ben-Mordehai +Holger P. Krekel +Glenn Popelka +Tibor Kiss +Robert Davidson +Peter Crowther +Mouna Seri +Vladimir Chovanec +Alexander Rieger +Glen Coakley +Scott Plant +Wilfried Reinoehl +Sangeetha Ramadurai +Victor Chernenko +Frank Wolf +Christophe Galerne +Scott Harris +Stefan Kluehspies +Egon Wuchner +Ugendreshwar Kudupudi +Ekkehard Hoffmann +Ted Krovetz +Grzegorz Sikora +Fabris +Christina Junru +Patrick Rabau +Hyman Rosen +Torbjorn Backstrom +Robert Burke +Olivier Brunet +Bret Clark +Steve Rahn +Bertrand Motuelle +Blair Zajac +Gary Duzan +Garry Shamis +Eamonn Saunders +Yev Omenzel +John E Hein +Tino Schwarze +Gergely Timar +Peter Phillips +Yury Kuznesov +Daniel Manfis +Massimo Pichini +Eyal Neuman +Dave Hale +Giulio Agostini +Werner Buchert +Kevin Cline +Mahesh Varadarajan +Olof Lindfors +Tom Wagner +Kyle Brost +Vincent Nicolas +Jonathan Wackley +Jan Kalin +Andreas Huggel +Alain Totouom +Tushar Nair +Sunny Leung +Bonifides Bautista +Brad Hoskins +Donald Acton +Hagen Ulrich +Adrian Mercieca +Lars Steubesand +Heping He +Leo Kov +Suresh N +David Arndt +Tad Hetke +Graeme Clark +Gu Song +Chris Hughes +Fikri Pribadi +Ioulia Passynkova +Steve Osselton +Doron Rajwan +Stuart Jones +Guillaume Renaud +Tommy Svensson +Jstwo +Hartmut Quast +Ulrich Voigt +Syed Wasim Ali +Bo Balder +Michael Sawczyn +Ildar Gabdulline +David Yongqiang Wang +Shahzad Aslam-Mir +Andrew Foster +C Chan +Alexey Chalimov +Andrea Bernicchia +Praphul Menon +Patrick N +Garth Watney +Jim Connelly +Eyal Lubetzky +Gaoyan Xie +Michael Brinkmann +Chatchai Khumboa +Andrey Shkinev +Michael Graf +Justin Michel +Robert Martin +Charles Meidinger +Petr Tuma +Greg Burley +Marvin Greenberg +Mike Connors +Ben Flight +Bob Jolliffe +Jesse +Robert Handl +Keith Snively +Ahmed Riza +Miljenko Norsic +David Robison +Preston Elder +Eric Peters +Edward A Thompson +Eugene Alterman +Patrick Cosmo +Ran Kohavi +Harvinder Sawhney +Sorin Iordachescu +Mahesh Vedantam +Brian Olson +Roy Sharon +Charlie Grames +Tom Howard +Michael Gillmann +Yaniv Ben Ari +Victor Terber +David Sanders +Yoram Zini +Sean McCauliff +Shmulik Regev +Andrew L. Shwaika +Gerhard Voss +Gregor Bruce +Ian Cahoon +Alexei I. Adamovich +Sohail Husain +Jerome Julius +William R Volz +Koushik Banerjee +Zoran Cetusic +Patrick Bennett +Felix Wyss +Tim Rydell +Petr Shelomovsky +Juliana Diniz +Yuval Cohen +Timothy Kilbourn +Marc Walrave +Petru Marginean +Paresh Raote +Donna Maskell +Steve Ige +Marco Kranawetter +Christian Veleba +Olli Savia +Bhaskara Rao G +M Schulze +John Michael Zorko +Ami Bar +David Smith +Peter van Merkerk +Bill Dyer +Rodney Morris +Mark Hoffmann +Markus Wild +Joe Hayes +Chip Jones +Patrick J Lardieri +Ken O'Brien +Daniel Troesser +Ivan Pazymenko +Dan Green +Cyrille Chepelov +Peter Heitman +Paxton Mason +Yan Dai +Sean I. Luzader +Renjie Tang +Max V. Zinal +Stan Sosnovsky +Ariel Peltz +Carsten Prescher +Raghuram Shetty +Val Dumiterscu +Oleg Kraynov +Stephan Gudmundson +Frank Kuhlman +Denis Otchenashko +Marc M Adkins +Jon Lambert +Rainer Lucas +Allan S Iverson +Jeffrey Shaffer +Oleg Burlachenko +Jian Chen +Jeff Paciga +Laurent Sabourin +Frank Rybak +Tim Iskander +Michele Amoretti +Ido Yellin +Eric Page +Kevin Heifner +James Haiar +Pavel Repin +Whitney Kew +Tom Phan +Andrew Guy +Bharathi Kangatharan +Jean Quinsat +Ma Ting Chong +Andrew Sutton +Ansgar Konermann +Amir Kunst +Daniel Garrido +Andy Alvarez +Soeren Gerlach +Vitaly Prapirny +Sasha Agranov +Ruwanganie Gunatilleke +Peter Kullmann

+Lyn Headley +Jeff Adams +Alexander Maack +Timothy Culp +Oleg Terletsky +Bill Tonseth +Frank Pilhofer +Eric Quere +Keith Thornton +Nathan Krasney +Marek Maleta +David Smith +Dimitrije Jankovic +Frank O. Flemisch +Cary Steinmetz +Ty Tenait +Nitin Mallya +Nick Cross +Christopher W. Midgley +Wanjia +Shanliang Cheng +Andy Ling +Stephen Howard +Carsten T. Nielsen +Adee Ran + +Davide Pasetto +Michael Hornok +Wim van den Boogaard +Carol Hunsicker +Joseph Sarbak +Ruslan Zasukhin +Colin Weaver +Kew Whitney +Sean Ogle +Tim Bradley +Kier Schmitt +George Varsamis +Alan Tanga +Bertin Colpron +Jeff Wilson +Dmitry Khrapov +Francois +Laxmikant Bopalkar +Steven Gardner +Ronald Berger +Jeremy Altavilla +Brian Appel +Lan Zhineng +Leen Van Kampen +James Beale +Mark Xu +Umberto Mascia +Marcel Loose +Christian Klutz +Ville Lehtiniemi +Chumsu Kim +Schone Mullerin +Cemal Yimaz +Newton Aird +Frederic Motte +Roger Weeks +Gautam Thaker +Christophe Juniet +Jeff W +Geir Berset +Ken Sedgwick +Vince Mounts +Vladislav Zverev +Erich Hochmuth +Nick S. Petrov +Dmitry Botcharnikov +Philippe Haussy

+K2 +Eric Frias +Antonio Saraiva +Sean M. Paus +Yuanfang Zhang +Jonathan Franklin +Cristian Ungureanu +Tommy Persson +Christian Barheine +Ole Husgaard +Victor Kirk +Sandeep Neema +Mike Curtis +Artashes Ghazaryan +Ashok Sadasivan +Andreas Koehler +Thomas Devanneaux +Paul Marquis +Ed Skees +Marc Alter +Martin Geliot +Simon McQueen +Jason Pasion +Philipp Leibfried +Erwin Rol +Dirk Moermans +Huseyin Calgin +Jaroslaw Nozderko +Sharon Caspi +Thomas Natterer +Wilbur Lang +Rick Marlborough +David-A O-Brien +Shelton Tang +Frederic Langlet +Antonio Leonforte +Pablo d'Angelo +Christophe Vedel +Uwe Jaeger +Viktor Ransmayr +Daniel Bell +Mathias Waack +Mike Nordell +Tufan Oruk +Tim Smith +Andy King +Eric Strennen +Abhay Kulkarni +Ron Muck +Ma Weida +Terry Lao +Volker Boerchers +Tim Pullen +Marc Tardif +Guan Joe +Petr Ferschmann +Greg Mulyar +Max F. Bilyk +Danile White +Andrew Marlow +Michael F"olsl +Vincent Chau +Theo Landman +Igor Pisarenko +Dima Scub +Volodymyr Orlenko +Grigory +Michael Soden +Dennis Sporcic +Emmanuel Thevenot Beaufort +Denis Parnaland +Matthias Blankenhaus +Wolfgang Schroeder +Mario Hofmann +Bruce MacDonald +Jeffrey Graham +Otis Nyandoro +Ray Limpus +Dmitri Belogaj +Will Christof +Ferran Boladeres Salvad +Juan Carlos Montes Costa +Edward Scott +Steve Spencer +Fukasawa Mitsuo +Martin Brown +Terry Mihm +Jeff Gray +Rob Eger +Leonid Kvetnyi +Rudolf Weber +Sergei Pimenov +David Kinder +Sebastien Lalonde +Jia Wan +Bertin Colpron +Weston Markham +Bryan Thrall +Subhabrata Biswas +Dave Ryan +Zsolt Zsoldos +Tongzhe Cui +Braden McDaniel +Richard Woodring +Andras Lang +Scott Gammil +Nick Lewycky +Ira Burton +Thomas Wiegert +Craig Watcham +Pit Linnartz +Peder Norgaard +David Ohlemacher +Ken Kane +Bill Church +Udo Berninger +Vincent Korkos +Martin Corino +Terry Lacy +Branko Mijic +Jeff Kelley +Daniel Hannum +Jason Cohen +Nick Kukuczka +Andrew Voumard +Anand +D.J. Dwyer +Douglas A Stuart +Victor N. +Francesco Baldi +Michael Rice +Jesse Greenwald +Raymond Hoofman +Jason Smith +Danta Cannarozzi +Valery Salamakha +Karim Fodil-Lemelin +Wenlong Tang +Manish Jain +Robin Farine +Roland Schimmack +Roy Pollock +Eric Held +Kees van Marle +Dieter Knueppel +Amol Tambe +Emiliano Berenbaum +Scott Clarke +Sunil Rottoo +Martin Habets +Todd Cooper +Serkan Unsal +Milan Cvetkovic +Didier Becu +Dan Halbert +Jerome Waibel +Stephan Frenzel +Bruce Jones +Tim Hawes +Philip Leishman +Alexander Jasper +Gerard Grant +Trevor Fields +Jeff Dugan +Jeff Mirwaisi +Alain Dupont +Stephan Bettermann +David McKen +Adam Fanello +Matthieu Vansteene +Sean Rooney +Enrico Detoma +Onopin V. Mikhail +Edward R. Mulholland +Brian Buesker +Vladimir Naylov +Ted Mules +Mike Hepburn +Dale Wilson +Thomas Girard +Malcolm McRoberts +Dror Tirosh +Chris Sontag +Moran Levi +UV Wildner +Alan l Batongbacal +Gary Maxey +Yoav Borer +Andre Kleibeuker +Andy Bellafaire +John Fletcher +Terry Ware +Pierre Pacchioni +Roger Beathard +Konstantinos Margaritis +Stephen Procter +Christoph Liebig +Andre Kostur +Markus Stenberg +Jonathan Pollack +Si Mong Park +Hakim Souami +Paul Morrison +John Poplett +Heiko Bachmann +Andrew Metcalfe +Simon Dutkowski +Mickael P. Golovin +Shannon Barber +Brad Orner +Michelangelo Nottoli +Peter Bekiesch +Martin Kaul +Lukas Gruetzmacher +Robert Schiele +Matthew Grosso +Akim Boyko +Nils Sandoy +Daniel Miranda +Hans-Peter Bock +Dmitri Hrapof +Denny Kolb +Daniel Buchs +Matt Murphy +Brian Nelson +Avi Ouziel +Matthew Gillen +Chris Reed +Andrew Reid +Praveen Sharma +Yi Zuo +Raphael Bossek +Richard G. Hash +Karl Tredwell +Norm Whitehead +Jiang Wei +Kevin Bryan +Zvika Ashani +Thomas Costa +Dom Monteiro +Jean-Marc Prud'homme +Yury Osadchy +Pavan Mandalkar +Scott Willey +David Calkins +Wu Yongwei +Karen L. Regner +Michel Drapeau +Hans Bos +Kevin Stacy +Liat +Andreas Wagner +Steven Xie +Kris Dekeyser +Matthew Harris +Abhijit Sachdev +Mikael Lundqvist +Peter Hercek +Jay Welch +Angel Roman +Jessica Pistole +Paolo Carlini +Eric Whorter +Vincent Seignole +Jingbin An +Roland Meub +Marek Brudka +Levente Torok +Panagiotis Issaris +Mehrdad Nazari +Pierre Bisaillon +Rob Boyer +Scott Gammill +Bayu Hendradjaya +Randy Hammon +Bill Cassanova +Matthew Corey +Vinod Kumar +Mirek Pabich +Christian Egeler +J.T. Conklin +Dale Hawkins +Bill Hopkins +David Fleeman +Merlin Ran +Kevin Christian +Trina Wisler +Bae-Sik Chon +Benjamin Bronk +Dave Craig +Ofira Shaer +Ciaran Moran +Thomas Rohner +Ken Descoteaux +Claas-Hinrich Dommreis +Yateen Joshi +Sergei Kuchin +Theckla Louchios +Randy Secrest +Patrice Marques +Stanislaw Trytek +Mattias Nilsson +Michael Hollins +Dave Knox +Lance Paine +Brian Waltersdorf +Johann Kandlbauer +Adam Rymarczuk +Heiko Nardmann +J. Abelardo Gutierrez +Roger Sala +Razi Ben-Yehuda +Geo Sebastian +Simon Massey +Rich Shapiro +Ramiro Morales +Andrew Athan +Sebastien Roy +Matthew Townsend +Rick Robinson +John D. Robertson +Paul Lew +Eider Oliveira +Jeff Jones +Jean-Christophe Cota +Paul +Vincent Newsum +Vasili Goutas +Iliyan Jeliazkov +Shlomi Yaakobovich +Todd Marshall +Ciju John +Yuk Ming Kwok +Honorato Saavedra +Domingos Monteiro +Bill Somerville +Bjorn Roald +Michi Henning +Xue Yong Zhi +Ertugrul Sorar +Simone Viani +Rohan Mars +Robert S. Iakobashvili +Chris Hammond +Vincent Spano +Nuno Silva +Greg Bostrum +Dipa Suri +Adam Howell +Steven Frare +Dave Dalapati +Arjun Thounaojam +Michael Altmann +Steven Patrick +Pete McCann +William Nagel +M. C. Gahan +Thia Chang Chao +Gao Xianchao +Huang Rui +Sam Abbe +Mike McGahan +David Michael +Steve D. Baker +Martina Yen +Kim ByeongSu +Doug McCorkle +YiQing Xiong +Peter Falsh +Don Sharp +Arto Jalkanen +Scott Zionic +Diana Ukleja +Shaun Cooley +Aapo Mäkinen +Matt Emerson +Sean Parker +Mark Wilson +Joerg Rockel +Phil Chen +Stefan Morrow +Bruce Elliot +Mitscher Dubreus +Brian O'Connor +Ron Wilson +Peter Grotrian +Alex Ott +D. J. Stachniak +Slava Gorelik +Wolfgang Fischer +Nicholas Todd +Arno Wilhelm +Andreas Schuler +Altaf Aali +Vemund Handeland +Mario Di Giacomo +Raoul Gough +Aaron +Rohini Madhavan +Alan Balasuar +Will Chai +Paul Koch +Dave Giovannini +Dave Varnell +Howard Finer +Mark Callaghan +Hanson Lu +Gavin Yu +Srikanth Gopal +Like Ma +Alvin Msg +Angela Ziegenhorn +Sam Mesh +Felix Perez Alamillo +Steven T. Hatton +Yevgen Galchenko +Timothy Wayne Gomez +Ventimiglia Chere +Frederick Heckel +Ian Zagorskih +Olivier Guérin +Abdel Rigumye +James Damour +Alan Anderson +Vito Bico +Aldo Texier +J H Choi +Mike Chartier +Nikolay Metchev +Anand Rathi +Vitaly Belekhov +Dorian Hileaga +Steve Williams +Paul Friberg

+Zachi Klopman +Jin Zhi Ye +David Carlton +Feng Li +Michael van der Westhuizen +Jan Zima +Francesco Salvestrini +Sandeep Deshpande +Hubert Talbot +Oh Yoon Sik +Anton Bakanovskiy +Toha Bakanovsky +David Faure +Robert Hancock +Peter Oslej +Yongming Wang +Vadim Iosevich +Mike Knight +Nathan Anderson +Eyal Car +Jonathan Sprinkle +Vladimir Panov +Volker Lukas +Bryan Cassell +Guy Peleg +Wallace Zhang +Richard Ward +Alan Stokes +Rick Taylor +Tobias Herzke +Paul Felix +Jan Ohlenburg +Eric Tiangang +David Hawkins +Michael Klein +Sandro Santos Andrade +Richard Spence +Thomas E Lackey +luxi78 at gmail dot com +John Lilley +Abdullah Sowayan +Nathan Bamford +Zoltan Molnar +William Byrne +Karl Schmitt +Ron DeAngelis +Alex Sheh +Daniel Wagner <__daniel___ at icg do tu-graz dot ac dot at> +Nemoy Michael +Marc Brown +Andrew Keane +Martin Kolleck +Tino Riethmueller +Adam Mitz +Frank Rehberger +Aaron Scamehorn +Alan Kierstead +Sven-Uwe Sieler-Hornke +Spencer Vanroekel +Dan Pozdol +Yauheni Akhotnikau +Axter +Roopa Pundaleeka +JR Andreassen +Mockey Chen +Vincent Joseph +Igor Mammedov +Yuan +Adrian Tulloch +Dmitriy Kuznetsov +Steve Orner +Bob Ronak +Aleksandar Vukajlovic +esIgnacio Alvarez +Sergey Zubarev +Qingbo Cai +David White +Jason Zhang +Mark Paulus +Willie Chen +Martin Cornelius +Mohit Kapoor +David Gibbs +Gary Fernandez +Jason Zhao +Keith Muzzioli +John Black +David Chu +Kevin Hu +Yasser Zabuair +Phlip +Michelle Zheng +Gerolf Reinwardt +Paul Robinson +Popeye Cai +David Highley +Sonicfly Zhou +Phil Billingham +David Giovannini +Paul Daugherty +Robert Schwebel +William Cote +Ben Creech +Michael Reed +Heesuk Shin +Hong Xing +Winston Zhang +Stefan Naewe +Graeme Bell +Eric Danielou +Wei Jiang +Dale Boan +Christoph Schmalhofer +Amnon Berger +Ephy Levy +Don Meek +Liu Qian +Nzer Zaidenberg +Birgit Platt +Andy Salnikov +Hieu Ngyuen +Andriy Gapon +Andy Wang +Zhamak Dehghani +Charles Calkins +Manuel Traut +Drew Reynaud +Artur DeEsperanto +Scott Mitchell +Thomas Vanier +N Johnson +Adam Nagel +Robert Neumann +Venkat +Juraj Ivancic +Daniel Black +Richard Ridgway +Vadym Ridosh +Viola Wang +Ray Lischner +Sergey Kosenko +Pavel Zaichenko +Paul Riley +Nelson Filipe Ferreira Gonçalves +Harry Goldschmitt +Sail Zeng +Markus Henschel +Asif Lodhi +Andrew Schnable +Grigoriy Zeleniy +Yves Alloyer +Waba +Scott Mark +Bjoern Rasmussen +Ian C White +Dennis Chernoivanov +Werner Burger +Andres Hurtis +Joe French +M. Arshad Khan +Hans van't Hag +Roland Sun +Vance Maverick +John McCabe +Andres Oportus +Olof Granered +Eric Hughes +Zhenghao Shi +Alexander Kornienko +Ben Mohlenhoff +Bill Bruns +Dmitriy Nikitinskiy +Ravi Kanth +Ian Roberts +Patrick Spiering +Duane Beck +Kanghee Yoon +Xu Liang +Leo Lei +Jules d'Entremont +Rajiv K. Shukla +Haibin Zhang +Vikram Karandikar +Kim J. Schmock +Venkat Forums +James Marsh +Shaolong Xiang +Christoph Hofmann +Vladimir Zykov +Daniel de Angelis Cordeiro +Hal Black +Peter Korf +Norbert Thoden +Premkumar P +David Beck +Hayim Shaul +Erman Balcik +Torsten Saliwada +Nathan Glasser +Grégor Boirie +Alex Solan +Venkat Sidhabathuni +Nathan Ernst +Kun Niu +Karl-Heinz Wind +Oliver Spang +Hu Yi +Joe Seward +Tom Callaway +Alick Nie +Douglas Atique +Nayeem Khan +Sorin Voicu-Comendant +Andi Heusser +Paul Carter +Michael Carter +Alain Kocelniak +Alvaro Vega Garcia +Fernando C. Jeronymo +Stephen Mouring +Tim +Thomas Brownridge +June Fang +Bill Kendall +Ittehad Shaikh +Michael Doubez +Namrata Gandhi <...> +Michael Guntli +Frank Förster +Roger Leblanc +Bob Fiske +Julien Vintrou +Jonathan Brannan +antred +Nathalie D'Amours +Mele Giovanni +Philipp Thomas + +I would particularly like to thank Paul Stephenson, who worked with me +at Ericsson in the early 1990's. Paul devised the recursive Makefile +scheme that underlies the ACE distribution and also spent countless +hours with me discussing object-oriented techniques for developing +distributed application frameworks. + +Finally, I'd also like to thank Todd L. Montgomery , +fellow heavy metal head, for fulfilling his quest to get ACE to +compile with GCC! + +In conclusion, our goal is to see ACE+TAO+CIAO continue to evolve and +become a more comprehensive, robust, and well-documented C++ class +library that is freely available to researchers and developers. If +you have any improvements, suggestions, and or comments, we'd like to +hear about it. Please see the instructions in + +$ACE_ROOT/PROBLEM-REPORT-FORM +$TAO_ROOT/PROBLEM-REPORT-FORM +$CIAO_ROOT/PROBLEM-REPORT-FORM + +for instructions on submitting suggestions or fixes. + + Thanks, + + Douglas C. Schmidt + d.schmidt at vanderbilt.edu diff --git a/dep/ACE_wrappers/VERSION b/dep/ACE_wrappers/VERSION new file mode 100644 index 000000000..0c1423ad0 --- /dev/null +++ b/dep/ACE_wrappers/VERSION @@ -0,0 +1,11 @@ +This is ACE version 5.6.6, released Mon Sep 15 06:08:04 CDT 2008 + +If you have any problems with or questions about ACE, please send +email to the ACE mailing list (ace-users@cs.wustl.edu), using the form +found in the file PROBLEM-REPORT-FORM. To ensure that you see responses, +please do one of the following: + + 1) Subscribe to the ace-users mail list, by sending email with + contents "subscribe ace-users" to majordomo@cs.wustl.edu. + + 2) Or, monitor the comp.soft-sys.ace newsgroup for responses. diff --git a/dep/ACE_wrappers/ace/ACE.bor b/dep/ACE_wrappers/ace/ACE.bor new file mode 100644 index 000000000..4eb982fcd --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE.bor @@ -0,0 +1,2312 @@ +# Makefile for building the ACE library with Borland C++ Make + +NAME = ACE + +NO_FULL_PATH=1 + +OBJFILES = \ + $(OBJDIR)\ACE.$(OBJ_EXT) \ + $(OBJDIR)\ACE_crc32.$(OBJ_EXT) \ + $(OBJDIR)\ACE_crc_ccitt.$(OBJ_EXT) \ + $(OBJDIR)\ace_wchar.$(OBJ_EXT) \ + $(OBJDIR)\Activation_Queue.$(OBJ_EXT) \ + $(OBJDIR)\Active_Map_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Addr.$(OBJ_EXT) \ + $(OBJDIR)\Argv_Type_Converter.$(OBJ_EXT) \ + $(OBJDIR)\Assert.$(OBJ_EXT) \ + $(OBJDIR)\Asynch_IO.$(OBJ_EXT) \ + $(OBJDIR)\Asynch_IO_Impl.$(OBJ_EXT) \ + $(OBJDIR)\Asynch_Pseudo_Task.$(OBJ_EXT) \ + $(OBJDIR)\ATM_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\ATM_Addr.$(OBJ_EXT) \ + $(OBJDIR)\ATM_Connector.$(OBJ_EXT) \ + $(OBJDIR)\ATM_Params.$(OBJ_EXT) \ + $(OBJDIR)\ATM_QoS.$(OBJ_EXT) \ + $(OBJDIR)\ATM_Stream.$(OBJ_EXT) \ + $(OBJDIR)\Atomic_Op.$(OBJ_EXT) \ + $(OBJDIR)\Atomic_Op_Sparc.$(OBJ_EXT) \ + $(OBJDIR)\Auto_Event.$(OBJ_EXT) \ + $(OBJDIR)\Barrier.$(OBJ_EXT) \ + $(OBJDIR)\Base_Thread_Adapter.$(OBJ_EXT) \ + $(OBJDIR)\Based_Pointer_Repository.$(OBJ_EXT) \ + $(OBJDIR)\Basic_Stats.$(OBJ_EXT) \ + $(OBJDIR)\Basic_Types.$(OBJ_EXT) \ + $(OBJDIR)\Capabilities.$(OBJ_EXT) \ + $(OBJDIR)\CDR_Base.$(OBJ_EXT) \ + $(OBJDIR)\CDR_Size.$(OBJ_EXT) \ + $(OBJDIR)\CDR_Stream.$(OBJ_EXT) \ + $(OBJDIR)\Cleanup.$(OBJ_EXT) \ + $(OBJDIR)\Codecs.$(OBJ_EXT) \ + $(OBJDIR)\Codeset_IBM1047.$(OBJ_EXT) \ + $(OBJDIR)\Codeset_Registry.$(OBJ_EXT) \ + $(OBJDIR)\Codeset_Registry_db.$(OBJ_EXT) \ + $(OBJDIR)\Condition_Recursive_Thread_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Condition_Thread_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Configuration.$(OBJ_EXT) \ + $(OBJDIR)\Configuration_Import_Export.$(OBJ_EXT) \ + $(OBJDIR)\Connection_Recycling_Strategy.$(OBJ_EXT) \ + $(OBJDIR)\Containers.$(OBJ_EXT) \ + $(OBJDIR)\Copy_Disabled.$(OBJ_EXT) \ + $(OBJDIR)\Countdown_Time.$(OBJ_EXT) \ + $(OBJDIR)\Date_Time.$(OBJ_EXT) \ + $(OBJDIR)\DEV.$(OBJ_EXT) \ + $(OBJDIR)\DEV_Addr.$(OBJ_EXT) \ + $(OBJDIR)\DEV_Connector.$(OBJ_EXT) \ + $(OBJDIR)\DEV_IO.$(OBJ_EXT) \ + $(OBJDIR)\Dev_Poll_Reactor.$(OBJ_EXT) \ + $(OBJDIR)\Dirent.$(OBJ_EXT) \ + $(OBJDIR)\Dirent_Selector.$(OBJ_EXT) \ + $(OBJDIR)\DLL.$(OBJ_EXT) \ + $(OBJDIR)\DLL_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Dump.$(OBJ_EXT) \ + $(OBJDIR)\Dynamic.$(OBJ_EXT) \ + $(OBJDIR)\Dynamic_Message_Strategy.$(OBJ_EXT) \ + $(OBJDIR)\Dynamic_Service_Base.$(OBJ_EXT) \ + $(OBJDIR)\Dynamic_Service_Dependency.$(OBJ_EXT) \ + $(OBJDIR)\Encoding_Converter.$(OBJ_EXT) \ + $(OBJDIR)\Encoding_Converter_Factory.$(OBJ_EXT) \ + $(OBJDIR)\Event.$(OBJ_EXT) \ + $(OBJDIR)\Event_Handler.$(OBJ_EXT) \ + $(OBJDIR)\FIFO.$(OBJ_EXT) \ + $(OBJDIR)\FIFO_Recv.$(OBJ_EXT) \ + $(OBJDIR)\FIFO_Recv_Msg.$(OBJ_EXT) \ + $(OBJDIR)\FIFO_Send.$(OBJ_EXT) \ + $(OBJDIR)\FIFO_Send_Msg.$(OBJ_EXT) \ + $(OBJDIR)\FILE.$(OBJ_EXT) \ + $(OBJDIR)\FILE_Addr.$(OBJ_EXT) \ + $(OBJDIR)\FILE_Connector.$(OBJ_EXT) \ + $(OBJDIR)\FILE_IO.$(OBJ_EXT) \ + $(OBJDIR)\File_Lock.$(OBJ_EXT) \ + $(OBJDIR)\Filecache.$(OBJ_EXT) \ + $(OBJDIR)\Flag_Manip.$(OBJ_EXT) \ + $(OBJDIR)\Framework_Component.$(OBJ_EXT) \ + $(OBJDIR)\Functor.$(OBJ_EXT) \ + $(OBJDIR)\Functor_String.$(OBJ_EXT) \ + $(OBJDIR)\Get_Opt.$(OBJ_EXT) \ + $(OBJDIR)\gethrtime.$(OBJ_EXT) \ + $(OBJDIR)\Handle_Ops.$(OBJ_EXT) \ + $(OBJDIR)\Handle_Set.$(OBJ_EXT) \ + $(OBJDIR)\Hashable.$(OBJ_EXT) \ + $(OBJDIR)\High_Res_Timer.$(OBJ_EXT) \ + $(OBJDIR)\ICMP_Socket.$(OBJ_EXT) \ + $(OBJDIR)\INET_Addr.$(OBJ_EXT) \ + $(OBJDIR)\Init_ACE.$(OBJ_EXT) \ + $(OBJDIR)\IO_Cntl_Msg.$(OBJ_EXT) \ + $(OBJDIR)\IO_SAP.$(OBJ_EXT) \ + $(OBJDIR)\IOStream.$(OBJ_EXT) \ + $(OBJDIR)\IPC_SAP.$(OBJ_EXT) \ + $(OBJDIR)\Lib_Find.$(OBJ_EXT) \ + $(OBJDIR)\Local_Memory_Pool.$(OBJ_EXT) \ + $(OBJDIR)\Local_Name_Space.$(OBJ_EXT) \ + $(OBJDIR)\Local_Tokens.$(OBJ_EXT) \ + $(OBJDIR)\Lock.$(OBJ_EXT) \ + $(OBJDIR)\Log_Msg.$(OBJ_EXT) \ + $(OBJDIR)\Log_Msg_Backend.$(OBJ_EXT) \ + $(OBJDIR)\Log_Msg_Callback.$(OBJ_EXT) \ + $(OBJDIR)\Log_Msg_IPC.$(OBJ_EXT) \ + $(OBJDIR)\Log_Msg_NT_Event_Log.$(OBJ_EXT) \ + $(OBJDIR)\Log_Msg_UNIX_Syslog.$(OBJ_EXT) \ + $(OBJDIR)\Log_Record.$(OBJ_EXT) \ + $(OBJDIR)\Logging_Strategy.$(OBJ_EXT) \ + $(OBJDIR)\LSOCK.$(OBJ_EXT) \ + $(OBJDIR)\LSOCK_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\LSOCK_CODgram.$(OBJ_EXT) \ + $(OBJDIR)\LSOCK_Connector.$(OBJ_EXT) \ + $(OBJDIR)\LSOCK_Dgram.$(OBJ_EXT) \ + $(OBJDIR)\LSOCK_Stream.$(OBJ_EXT) \ + $(OBJDIR)\Malloc.$(OBJ_EXT) \ + $(OBJDIR)\Malloc_Allocator.$(OBJ_EXT) \ + $(OBJDIR)\Manual_Event.$(OBJ_EXT) \ + $(OBJDIR)\MEM_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\MEM_Addr.$(OBJ_EXT) \ + $(OBJDIR)\MEM_Connector.$(OBJ_EXT) \ + $(OBJDIR)\MEM_IO.$(OBJ_EXT) \ + $(OBJDIR)\Mem_Map.$(OBJ_EXT) \ + $(OBJDIR)\MEM_SAP.$(OBJ_EXT) \ + $(OBJDIR)\MEM_Stream.$(OBJ_EXT) \ + $(OBJDIR)\Message_Block.$(OBJ_EXT) \ + $(OBJDIR)\Message_Queue.$(OBJ_EXT) \ + $(OBJDIR)\Message_Queue_NT.$(OBJ_EXT) \ + $(OBJDIR)\Message_Queue_Vx.$(OBJ_EXT) \ + $(OBJDIR)\Method_Request.$(OBJ_EXT) \ + $(OBJDIR)\MMAP_Memory_Pool.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Admin.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Admin_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Base.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Control_Action.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Control_Types.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Point_Registry.$(OBJ_EXT) \ + $(OBJDIR)\Monitor_Size.$(OBJ_EXT) \ + $(OBJDIR)\Msg_WFMO_Reactor.$(OBJ_EXT) \ + $(OBJDIR)\Multihomed_INET_Addr.$(OBJ_EXT) \ + $(OBJDIR)\Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Name_Proxy.$(OBJ_EXT) \ + $(OBJDIR)\Name_Request_Reply.$(OBJ_EXT) \ + $(OBJDIR)\Name_Space.$(OBJ_EXT) \ + $(OBJDIR)\Naming_Context.$(OBJ_EXT) \ + $(OBJDIR)\Netlink_Addr.$(OBJ_EXT) \ + $(OBJDIR)\Notification_Queue.$(OBJ_EXT) \ + $(OBJDIR)\Notification_Strategy.$(OBJ_EXT) \ + $(OBJDIR)\NT_Service.$(OBJ_EXT) \ + $(OBJDIR)\Obchunk.$(OBJ_EXT) \ + $(OBJDIR)\Object_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Object_Manager_Base.$(OBJ_EXT) \ + $(OBJDIR)\OS_Errno.$(OBJ_EXT) \ + $(OBJDIR)\OS_Log_Msg_Attributes.$(OBJ_EXT) \ + $(OBJDIR)\OS_main.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_arpa_inet.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_ctype.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_dirent.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_dlfcn.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_errno.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_fcntl.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_math.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_netdb.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_poll.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_pwd.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_regex.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_signal.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_stdio.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_stdlib.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_string.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_strings.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_stropts.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_mman.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_msg.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_resource.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_select.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_sendfile.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_shm.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_socket.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_stat.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_time.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_uio.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_utsname.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_sys_wait.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_Thread.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_time.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_unistd.$(OBJ_EXT) \ + $(OBJDIR)\OS_NS_wchar.$(OBJ_EXT) \ + $(OBJDIR)\OS_QoS.$(OBJ_EXT) \ + $(OBJDIR)\OS_Thread_Adapter.$(OBJ_EXT) \ + $(OBJDIR)\OS_TLI.$(OBJ_EXT) \ + $(OBJDIR)\Pagefile_Memory_Pool.$(OBJ_EXT) \ + $(OBJDIR)\Parse_Node.$(OBJ_EXT) \ + $(OBJDIR)\PI_Malloc.$(OBJ_EXT) \ + $(OBJDIR)\Ping_Socket.$(OBJ_EXT) \ + $(OBJDIR)\Pipe.$(OBJ_EXT) \ + $(OBJDIR)\POSIX_Asynch_IO.$(OBJ_EXT) \ + $(OBJDIR)\POSIX_CB_Proactor.$(OBJ_EXT) \ + $(OBJDIR)\POSIX_Proactor.$(OBJ_EXT) \ + $(OBJDIR)\Priority_Reactor.$(OBJ_EXT) \ + $(OBJDIR)\Proactor.$(OBJ_EXT) \ + $(OBJDIR)\Proactor_Impl.$(OBJ_EXT) \ + $(OBJDIR)\Process.$(OBJ_EXT) \ + $(OBJDIR)\Process_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Process_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Process_Semaphore.$(OBJ_EXT) \ + $(OBJDIR)\Profile_Timer.$(OBJ_EXT) \ + $(OBJDIR)\Reactor.$(OBJ_EXT) \ + $(OBJDIR)\Reactor_Impl.$(OBJ_EXT) \ + $(OBJDIR)\Reactor_Notification_Strategy.$(OBJ_EXT) \ + $(OBJDIR)\Reactor_Timer_Interface.$(OBJ_EXT) \ + $(OBJDIR)\Read_Buffer.$(OBJ_EXT) \ + $(OBJDIR)\Recursive_Thread_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Recyclable.$(OBJ_EXT) \ + $(OBJDIR)\Registry.$(OBJ_EXT) \ + $(OBJDIR)\Registry_Name_Space.$(OBJ_EXT) \ + $(OBJDIR)\Remote_Name_Space.$(OBJ_EXT) \ + $(OBJDIR)\Remote_Tokens.$(OBJ_EXT) \ + $(OBJDIR)\Rtems_init.$(OBJ_EXT) \ + $(OBJDIR)\RW_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\RW_Process_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\RW_Thread_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Sample_History.$(OBJ_EXT) \ + $(OBJDIR)\Sbrk_Memory_Pool.$(OBJ_EXT) \ + $(OBJDIR)\Sched_Params.$(OBJ_EXT) \ + $(OBJDIR)\Select_Reactor_Base.$(OBJ_EXT) \ + $(OBJDIR)\Semaphore.$(OBJ_EXT) \ + $(OBJDIR)\Service_Config.$(OBJ_EXT) \ + $(OBJDIR)\Service_Gestalt.$(OBJ_EXT) \ + $(OBJDIR)\Service_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Service_Object.$(OBJ_EXT) \ + $(OBJDIR)\Service_Repository.$(OBJ_EXT) \ + $(OBJDIR)\Service_Types.$(OBJ_EXT) \ + $(OBJDIR)\Shared_Memory.$(OBJ_EXT) \ + $(OBJDIR)\Shared_Memory_MM.$(OBJ_EXT) \ + $(OBJDIR)\Shared_Memory_Pool.$(OBJ_EXT) \ + $(OBJDIR)\Shared_Memory_SV.$(OBJ_EXT) \ + $(OBJDIR)\Shared_Object.$(OBJ_EXT) \ + $(OBJDIR)\Sig_Adapter.$(OBJ_EXT) \ + $(OBJDIR)\Sig_Handler.$(OBJ_EXT) \ + $(OBJDIR)\Signal.$(OBJ_EXT) \ + $(OBJDIR)\SOCK.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_CODgram.$(OBJ_EXT) \ + $(OBJDIR)\Sock_Connect.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Connector.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Dgram.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Dgram_Bcast.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Dgram_Mcast.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_IO.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Netlink.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_SEQPACK_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_SEQPACK_Association.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_SEQPACK_Connector.$(OBJ_EXT) \ + $(OBJDIR)\SOCK_Stream.$(OBJ_EXT) \ + $(OBJDIR)\SPIPE.$(OBJ_EXT) \ + $(OBJDIR)\SPIPE_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\SPIPE_Addr.$(OBJ_EXT) \ + $(OBJDIR)\SPIPE_Connector.$(OBJ_EXT) \ + $(OBJDIR)\SPIPE_Stream.$(OBJ_EXT) \ + $(OBJDIR)\SString.$(OBJ_EXT) \ + $(OBJDIR)\Stack_Trace.$(OBJ_EXT) \ + $(OBJDIR)\Stats.$(OBJ_EXT) \ + $(OBJDIR)\String_Base_Const.$(OBJ_EXT) \ + $(OBJDIR)\SUN_Proactor.$(OBJ_EXT) \ + $(OBJDIR)\SV_Message.$(OBJ_EXT) \ + $(OBJDIR)\SV_Message_Queue.$(OBJ_EXT) \ + $(OBJDIR)\SV_Semaphore_Complex.$(OBJ_EXT) \ + $(OBJDIR)\SV_Semaphore_Simple.$(OBJ_EXT) \ + $(OBJDIR)\SV_Shared_Memory.$(OBJ_EXT) \ + $(OBJDIR)\Svc_Conf_Lexer.$(OBJ_EXT) \ + $(OBJDIR)\Svc_Conf_y.$(OBJ_EXT) \ + $(OBJDIR)\Synch_Options.$(OBJ_EXT) \ + $(OBJDIR)\System_Time.$(OBJ_EXT) \ + $(OBJDIR)\Task.$(OBJ_EXT) \ + $(OBJDIR)\Thread.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Adapter.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Control.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Exit.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Hook.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Mutex.$(OBJ_EXT) \ + $(OBJDIR)\Thread_Semaphore.$(OBJ_EXT) \ + $(OBJDIR)\Throughput_Stats.$(OBJ_EXT) \ + $(OBJDIR)\Time_Value.$(OBJ_EXT) \ + $(OBJDIR)\Timeprobe.$(OBJ_EXT) \ + $(OBJDIR)\TLI.$(OBJ_EXT) \ + $(OBJDIR)\TLI_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\TLI_Connector.$(OBJ_EXT) \ + $(OBJDIR)\TLI_Stream.$(OBJ_EXT) \ + $(OBJDIR)\Token.$(OBJ_EXT) \ + $(OBJDIR)\Token_Collection.$(OBJ_EXT) \ + $(OBJDIR)\Token_Invariants.$(OBJ_EXT) \ + $(OBJDIR)\Token_Manager.$(OBJ_EXT) \ + $(OBJDIR)\Token_Request_Reply.$(OBJ_EXT) \ + $(OBJDIR)\TP_Reactor.$(OBJ_EXT) \ + $(OBJDIR)\Trace.$(OBJ_EXT) \ + $(OBJDIR)\TSS_Adapter.$(OBJ_EXT) \ + $(OBJDIR)\TTY_IO.$(OBJ_EXT) \ + $(OBJDIR)\UNIX_Addr.$(OBJ_EXT) \ + $(OBJDIR)\UPIPE_Acceptor.$(OBJ_EXT) \ + $(OBJDIR)\UPIPE_Connector.$(OBJ_EXT) \ + $(OBJDIR)\UPIPE_Stream.$(OBJ_EXT) \ + $(OBJDIR)\UTF16_Encoding_Converter.$(OBJ_EXT) \ + $(OBJDIR)\UTF32_Encoding_Converter.$(OBJ_EXT) \ + $(OBJDIR)\UTF8_Encoding_Converter.$(OBJ_EXT) \ + $(OBJDIR)\UUID.$(OBJ_EXT) \ + $(OBJDIR)\WFMO_Reactor.$(OBJ_EXT) \ + $(OBJDIR)\WIN32_Asynch_IO.$(OBJ_EXT) \ + $(OBJDIR)\WIN32_Proactor.$(OBJ_EXT) \ + $(OBJDIR)\XML_Svc_Conf.$(OBJ_EXT) \ + $(OBJDIR)\XTI_ATM_Mcast.$(OBJ_EXT) + +LFLAGS = \ + -L"." \ + -j"." \ + -L"..\lib" \ + -j"..\lib" + +RESDIR = . + +RESOURCE = $(OBJDIR)\ace.res + +RC_FLAGS = \ + -i".." + + +!ifdef STATIC +LIB_FLAGS = \ + -DACE_AS_STATIC_LIBS +!else +DLL_FLAGS = \ + -DACE_BUILD_DLL +!endif + +CFLAGS = \ + -I".." \ + $(LIB_FLAGS) \ + $(DLL_FLAGS) + +CPPDIR = . +CDIR = . + +INCDIR_NAME = stage-10168\ACE_wrappers\ace + +# build_files rules + + +# test_files rules + + +# pkgconfig_files rules + + +# Override defaults in outputdir.bor +INSTALL_THIS_TARGET = 1 + +INCLUDES_INSTALL=1 +BINDIR = ..\lib + +!include <$(ACE_ROOT)\include\makeinclude\build_library.bor> + +includes_install: $(INCLUDES) + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ACE.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ACE.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ACE_export.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ACE_export.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ace_wchar.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ace_wchar.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Activation_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Activation_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Active_Map_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Active_Map_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Active_Map_Manager_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Active_Map_Manager_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Arg_Shifter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Arg_Shifter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ARGV.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ARGV.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Argv_Type_Converter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Argv_Type_Converter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array_Map.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array_Map.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Assert.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Assert.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_IO_Impl.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_IO_Impl.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_Pseudo_Task.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_Pseudo_Task.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Params.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Params.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_QoS.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_QoS.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Atomic_Op.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Atomic_Op.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Atomic_Op_Sparc.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Atomic_Op_Sparc.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Atomic_Op_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Atomic_Op_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Event.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Event.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Functor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Functor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_IncDec_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_IncDec_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Ptr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Ptr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Barrier.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Barrier.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Base_Thread_Adapter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Base_Thread_Adapter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Based_Pointer_Repository.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Based_Pointer_Repository.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Based_Pointer_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Based_Pointer_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Basic_Stats.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Basic_Stats.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Basic_Types.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Basic_Types.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Bound_Ptr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Bound_Ptr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cache_Map_Manager_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cache_Map_Manager_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cached_Connect_Strategy_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cached_Connect_Strategy_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Caching_Strategies_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Caching_Strategies_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Caching_Utility_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Caching_Utility_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Capabilities.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Capabilities.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CDR_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\CDR_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CDR_Size.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\CDR_Size.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CDR_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\CDR_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CE_Screen_Output.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\CE_Screen_Output.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y checked_iterator.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\checked_iterator.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cleanup.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cleanup.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cleanup_Strategies_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cleanup_Strategies_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Codecs.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Codecs.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Codeset_IBM1047.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Codeset_IBM1047.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Codeset_Registry.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Codeset_Registry.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Codeset_Symbols.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Codeset_Symbols.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Condition_Recursive_Thread_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Condition_Recursive_Thread_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Condition_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Condition_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Condition_Thread_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Condition_Thread_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-aix-5.x.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-aix-5.x.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-all.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-all.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-borland-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-borland-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-cray.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-cray.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-cxx-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-cxx-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-cygwin32.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-cygwin32.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-doxygen.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-doxygen.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-freebsd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-freebsd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-g++-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-g++-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-ghs-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-ghs-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-hpux-11.00.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-hpux-11.00.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-icc-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-icc-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-integritySCA.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-integritySCA.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-irix6.5.x-sgic++.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-irix6.5.x-sgic++.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-irix6.x-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-irix6.x-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-irix6.x-g++.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-irix6.x-g++.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-irix6.x-sgic++.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-irix6.x-sgic++.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-linux-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-linux-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-linux.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-linux.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-lite.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-lite.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-lynxos.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-lynxos.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-macosx-leopard.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-macosx-leopard.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-macosx-panther.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-macosx-panther.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-macosx-tiger.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-macosx-tiger.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-macosx.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-macosx.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-macros.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-macros.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-minimal.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-minimal.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-mvs.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-mvs.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-netbsd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-netbsd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-openbsd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-openbsd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-openvms.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-openvms.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-pharlap.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-pharlap.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-posix-nonetworking.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-posix-nonetworking.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-posix.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-posix.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-qnx-neutrino.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-qnx-neutrino.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-qnx-rtp-62x.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-qnx-rtp-62x.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-qnx-rtp-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-qnx-rtp-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-qnx-rtp-pre62x.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-qnx-rtp-pre62x.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-qnx-rtp.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-qnx-rtp.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-rtems.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-rtems.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sco-5.0.0-nothread.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sco-5.0.0-nothread.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sco-5.0.0.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sco-5.0.0.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-suncc-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-suncc-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.10.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.10.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.11.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.11.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.4-g++.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.4-g++.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.4-sunc++-4.x.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.4-sunc++-4.x.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.5.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.5.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.6.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.6.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.7.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.7.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.8.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.8.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-sunos5.9.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-sunos5.9.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-tandem-nsk-mips-v2.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-tandem-nsk-mips-v2.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-tandem-nsk-mips-v3.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-tandem-nsk-mips-v3.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-tandem.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-tandem.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-tru64.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-tru64.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-unixware-7.1.0.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-unixware-7.1.0.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-unixware-7.1.0.udk.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-unixware-7.1.0.udk.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-visualage.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-visualage.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks5.x.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks5.x.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks6.2.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks6.2.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks6.3.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks6.3.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks6.4.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks6.4.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks6.5.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks6.5.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-vxworks6.6.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-vxworks6.6.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-borland.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-borland.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-common.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-common.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-dmc.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-dmc.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-ghs.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-ghs.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-interix.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-interix.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-mingw.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-mingw.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-msvc-7.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-msvc-7.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-msvc-8.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-msvc-8.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-msvc-9.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-msvc-9.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32-msvc.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32-msvc.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-win32.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-win32.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config-WinCE.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config-WinCE.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y config.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\config.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Configuration.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Configuration.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Configuration_Import_Export.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Configuration_Import_Export.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Connection_Recycling_Strategy.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Connection_Recycling_Strategy.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Containers.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Containers.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Containers_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Containers_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Copy_Disabled.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Copy_Disabled.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CORBA_macros.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\CORBA_macros.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Countdown_Time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Countdown_Time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Date_Time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Date_Time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Default_Constants.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Default_Constants.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dev_Poll_Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dev_Poll_Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dirent.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dirent.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dirent_Selector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dirent_Selector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DLL.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\DLL.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DLL_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\DLL_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dump.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dump.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dump_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dump_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Message_Strategy.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Message_Strategy.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Service.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Service.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Service_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Service_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Service_Dependency.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Service_Dependency.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Encoding_Converter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Encoding_Converter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Encoding_Converter_Factory.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Encoding_Converter_Factory.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Env_Value_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Env_Value_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event_Handler.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event_Handler.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event_Handler_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event_Handler_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Exception_Macros.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Exception_Macros.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Recv.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Recv.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Recv_Msg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Recv_Msg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Send.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Send.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Send_Msg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Send_Msg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y File_Lock.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\File_Lock.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Filecache.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Filecache.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Flag_Manip.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Flag_Manip.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Framework_Component.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Framework_Component.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Framework_Component_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Framework_Component_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Free_List.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Free_List.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor_String.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor_String.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Future.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Future.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Future_Set.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Future_Set.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Get_Opt.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Get_Opt.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Global_Macros.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Global_Macros.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Guard_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Guard_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Handle_Gobbler.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Handle_Gobbler.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Handle_Ops.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Handle_Ops.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Handle_Set.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Handle_Set.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Cache_Map_Manager_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Cache_Map_Manager_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_Manager_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_Manager_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_With_Allocator_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_With_Allocator_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Multi_Map_Manager_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Multi_Map_Manager_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hashable.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hashable.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y High_Res_Timer.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\High_Res_Timer.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ICMP_Socket.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\ICMP_Socket.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y If_Then_Else.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\If_Then_Else.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y INET_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\INET_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Init_ACE.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Init_ACE.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_Auto_Ptr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_Auto_Ptr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_List.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_List.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_List_Node.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_List_Node.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IO_Cntl_Msg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\IO_Cntl_Msg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IO_SAP.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\IO_SAP.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y iosfwd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\iosfwd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IOStream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\IOStream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IOStream_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\IOStream_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IPC_SAP.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\IPC_SAP.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Lib_Find.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Lib_Find.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Local_Memory_Pool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Local_Memory_Pool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Local_Name_Space.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Local_Name_Space.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Local_Name_Space_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Local_Name_Space_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Local_Tokens.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Local_Tokens.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Lock.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Lock.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Lock_Adapter_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Lock_Adapter_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LOCK_SOCK_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LOCK_SOCK_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg_Backend.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg_Backend.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg_Callback.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg_Callback.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg_IPC.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg_IPC.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg_NT_Event_Log.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg_NT_Event_Log.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg_UNIX_Syslog.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg_UNIX_Syslog.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Priority.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Priority.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Record.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Record.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Logging_Strategy.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Logging_Strategy.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_CODgram.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_CODgram.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Dgram.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Dgram.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc_Allocator.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc_Allocator.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Managed_Object.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Managed_Object.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Manual_Event.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Manual_Event.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Mem_Map.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Mem_Map.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_SAP.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_SAP.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Memory_Pool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Memory_Pool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Block.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Block.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Block_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Block_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue_NT.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue_NT.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue_Vx.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue_Vx.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Method_Object.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Method_Object.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Method_Request.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Method_Request.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Metrics_Cache.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Metrics_Cache.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Metrics_Cache_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Metrics_Cache_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Min_Max.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Min_Max.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MMAP_Memory_Pool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\MMAP_Memory_Pool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Module.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Module.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Admin.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Admin.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Admin_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Admin_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Control_Action.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Control_Action.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Control_Types.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Control_Types.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Point_Registry.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Point_Registry.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Size.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Size.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Msg_WFMO_Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Msg_WFMO_Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Multihomed_INET_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Multihomed_INET_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Name_Proxy.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Name_Proxy.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Name_Request_Reply.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Name_Request_Reply.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Name_Space.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Name_Space.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Naming_Context.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Naming_Context.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Netlink_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Netlink_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Node.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Node.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Notification_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Notification_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Notification_Strategy.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Notification_Strategy.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y NT_Service.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\NT_Service.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Null_Barrier.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Null_Barrier.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Null_Condition.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Null_Condition.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Null_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Null_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Null_Semaphore.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Null_Semaphore.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Numeric_Limits.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Numeric_Limits.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Obchunk.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Obchunk.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Object_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Object_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Object_Manager_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Object_Manager_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Obstack.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Obstack.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Obstack_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Obstack_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Dirent.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Dirent.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Errno.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Errno.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\arpa mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\arpa + -© /Y os_include\arpa\os_inet.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\arpa\os_inet.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\net mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\net + -© /Y os_include\net\os_if.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\net\os_if.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\netinet mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\netinet + -© /Y os_include\netinet\os_in.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\netinet\os_in.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\netinet mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\netinet + -© /Y os_include\netinet\os_tcp.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\netinet\os_tcp.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_aio.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_aio.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_assert.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_assert.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_byteswap.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_byteswap.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_complex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_complex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_cpio.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_cpio.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_ctype.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_ctype.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_dirent.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_dirent.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_dlfcn.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_dlfcn.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_errno.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_errno.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_fcntl.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_fcntl.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_fenv.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_fenv.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_float.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_float.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_fmtmsg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_fmtmsg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_fnmatch.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_fnmatch.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_ftw.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_ftw.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_glob.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_glob.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_grp.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_grp.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_iconv.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_iconv.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_intrin.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_intrin.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_inttypes.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_inttypes.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_iso646.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_iso646.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_kstat.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_kstat.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_langinfo.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_langinfo.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_libgen.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_libgen.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_limits.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_limits.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_local.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_local.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_math.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_math.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_monetary.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_monetary.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_mqueue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_mqueue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_ndbm.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_ndbm.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_netdb.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_netdb.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_nl_types.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_nl_types.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_pdh.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_pdh.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_pdhmsg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_pdhmsg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_poll.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_poll.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_pthread.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_pthread.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_pwd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_pwd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_regex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_regex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_sched.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_sched.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_search.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_search.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_semaphore.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_semaphore.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_setjmp.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_setjmp.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_signal.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_signal.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_spawn.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_spawn.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stdarg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stdarg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stdbool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stdbool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stddef.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stddef.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stdint.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stdint.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stdio.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stdio.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stdlib.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stdlib.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_string.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_string.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_strings.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_strings.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_stropts.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_stropts.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_syslog.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_syslog.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_tar.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_tar.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_termios.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_termios.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_tgmath.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_tgmath.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_trace.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_trace.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_ucontext.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_ucontext.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_ulimit.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_ulimit.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_unistd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_unistd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_utime.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_utime.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_utmpx.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_utmpx.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_wchar.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_wchar.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_wctype.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_wctype.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include + -© /Y os_include\os_wordexp.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\os_wordexp.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_ipc.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_ipc.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_loadavg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_loadavg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_mman.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_mman.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_msg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_msg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_pstat.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_pstat.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_resource.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_resource.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_select.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_select.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_sem.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_sem.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_shm.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_shm.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_socket.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_socket.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_stat.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_stat.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_statvfs.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_statvfs.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_sysctl.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_sysctl.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_sysinfo.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_sysinfo.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_timeb.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_timeb.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_times.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_times.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_types.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_types.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_uio.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_uio.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_un.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_un.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_utsname.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_utsname.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys + -© /Y os_include\sys\os_wait.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\os_include\sys\os_wait.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Log_Msg_Attributes.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Log_Msg_Attributes.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_main.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_main.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Memory.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Memory.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_arpa_inet.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_arpa_inet.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_ctype.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_ctype.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_dirent.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_dirent.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_dlfcn.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_dlfcn.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_errno.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_errno.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_fcntl.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_fcntl.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_macros.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_macros.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_math.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_math.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_netdb.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_netdb.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_poll.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_poll.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_pwd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_pwd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_regex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_regex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_signal.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_signal.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_stdio.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_stdio.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_stdlib.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_stdlib.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_string.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_string.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_strings.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_strings.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_stropts.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_stropts.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_mman.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_mman.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_msg.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_msg.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_resource.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_resource.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_select.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_select.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_sendfile.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_sendfile.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_shm.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_shm.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_socket.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_socket.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_stat.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_stat.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_uio.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_uio.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_utsname.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_utsname.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_wait.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_wait.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_Thread.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_Thread.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_unistd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_unistd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_wchar.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_wchar.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_QoS.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_QoS.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_String.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_String.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Thread_Adapter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Thread_Adapter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_TLI.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_TLI.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pagefile_Memory_Pool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pagefile_Memory_Pool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pair.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pair.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pair_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pair_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Parse_Node.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Parse_Node.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y PI_Malloc.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\PI_Malloc.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Ping_Socket.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Ping_Socket.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pipe.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pipe.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y POSIX_Asynch_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\POSIX_Asynch_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y POSIX_CB_Proactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\POSIX_CB_Proactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y POSIX_Proactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\POSIX_Proactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y post.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\post.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y pre.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\pre.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Priority_Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Priority_Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Proactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Proactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Proactor_Impl.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Proactor_Impl.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process_Semaphore.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process_Semaphore.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Profile_Timer.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Profile_Timer.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RB_Tree.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\RB_Tree.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor_Impl.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor_Impl.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor_Notification_Strategy.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor_Notification_Strategy.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor_Timer_Interface.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor_Timer_Interface.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor_Token_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor_Token_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Read_Buffer.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Read_Buffer.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Recursive_Thread_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Recursive_Thread_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Recyclable.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Recyclable.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcountable.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcountable.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcountable_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcountable_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcounted_Auto_Ptr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcounted_Auto_Ptr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Registry.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Registry.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Registry_Name_Space.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Registry_Name_Space.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Remote_Name_Space.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Remote_Name_Space.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Remote_Tokens.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Remote_Tokens.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reverse_Lock_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reverse_Lock_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RW_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\RW_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RW_Process_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\RW_Process_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RW_Thread_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\RW_Thread_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sample_History.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sample_History.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sbrk_Memory_Pool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sbrk_Memory_Pool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sched_Params.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sched_Params.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Select_Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Select_Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Select_Reactor_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Select_Reactor_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Select_Reactor_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Select_Reactor_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Semaphore.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Semaphore.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Config.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Config.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Gestalt.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Gestalt.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Object.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Object.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Repository.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Repository.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Templates.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Templates.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Types.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Types.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Memory.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Memory.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Memory_MM.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Memory_MM.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Memory_Pool.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Memory_Pool.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Memory_SV.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Memory_SV.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Object.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Object.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sig_Adapter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sig_Adapter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sig_Handler.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sig_Handler.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Signal.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Signal.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Singleton.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Singleton.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_CODgram.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_CODgram.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sock_Connect.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sock_Connect.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Dgram.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Dgram.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Dgram_Bcast.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Dgram_Bcast.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Dgram_Mcast.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Dgram_Mcast.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Netlink.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Netlink.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_SEQPACK_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_SEQPACK_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_SEQPACK_Association.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_SEQPACK_Association.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_SEQPACK_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_SEQPACK_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SString.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SString.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SStringfwd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SStringfwd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stack_Trace.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stack_Trace.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Static_Object_Lock.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Static_Object_Lock.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stats.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stats.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Strategies.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Strategies.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Strategies_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Strategies_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stream_Modules.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stream_Modules.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y streams.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\streams.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y String_Base.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\String_Base.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y String_Base_Const.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\String_Base_Const.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SUN_Proactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SUN_Proactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Message.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Message.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Message_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Message_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Semaphore_Complex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Semaphore_Complex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Semaphore_Simple.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Semaphore_Simple.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Shared_Memory.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Shared_Memory.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Conf.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Conf.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Conf_Lexer.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Conf_Lexer.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Conf_Param.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Conf_Param.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Conf_Token_Table.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Conf_Token_Table.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Conf_Tokens.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Conf_Tokens.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y svc_export.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\svc_export.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Handler.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Handler.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Synch.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Synch.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Synch_Options.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Synch_Options.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Synch_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Synch_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Synch_Traits.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Synch_Traits.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y System_Time.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\System_Time.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task_Ex_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task_Ex_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Test_and_Set.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Test_and_Set.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Adapter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Adapter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Control.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Control.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Exit.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Exit.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Hook.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Hook.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Mutex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Mutex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Semaphore.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Semaphore.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Throughput_Stats.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Throughput_Stats.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Time_Value.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Time_Value.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timeprobe.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timeprobe.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timeprobe_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timeprobe_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Hash.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Hash.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Hash_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Hash_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Heap.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Heap.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Heap_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Heap_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_List.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_List.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_List_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_List_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue_Adapters.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue_Adapters.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queuefwd.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queuefwd.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Wheel.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Wheel.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Wheel_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Wheel_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Collection.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Collection.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Invariants.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Invariants.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Manager.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Manager.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Request_Reply.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Request_Reply.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TP_Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TP_Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Trace.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Trace.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Truncate.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Truncate.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TSS_Adapter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TSS_Adapter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TSS_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TSS_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TTY_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\TTY_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Typed_SV_Message.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Typed_SV_Message.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Typed_SV_Message_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Typed_SV_Message_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Queue.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Queue.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Set.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Set.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Set_Ex.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Set_Ex.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UNIX_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UNIX_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Acceptor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Acceptor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Addr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Addr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Connector.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Connector.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Stream.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Stream.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UTF16_Encoding_Converter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UTF16_Encoding_Converter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UTF32_Encoding_Converter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UTF32_Encoding_Converter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UTF8_Encoding_Converter.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UTF8_Encoding_Converter.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UUID.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\UUID.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Value_Ptr.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Value_Ptr.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Vector_T.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Vector_T.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Version.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Version.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Versioned_Namespace.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\Versioned_Namespace.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y WFMO_Reactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\WFMO_Reactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y WIN32_Asynch_IO.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\WIN32_Asynch_IO.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y WIN32_Proactor.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\WIN32_Proactor.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y XML_Svc_Conf.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\XML_Svc_Conf.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y XTI_ATM_Mcast.h $(INSTALL_DIR)\include\$(INCDIR_NAME)\XTI_ATM_Mcast.h 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Acceptor.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Acceptor.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Active_Map_Manager_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Active_Map_Manager_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Arg_Shifter.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Arg_Shifter.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ARGV.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\ARGV.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array_Base.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array_Base.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array_Map.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array_Map.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_Acceptor.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_Acceptor.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_Connector.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_Connector.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Atomic_Op_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Atomic_Op_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Functor.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Functor.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_IncDec_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_IncDec_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Ptr.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Ptr.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Based_Pointer_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Based_Pointer_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cache_Map_Manager_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cache_Map_Manager_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cached_Connect_Strategy_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cached_Connect_Strategy_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Caching_Strategies_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Caching_Strategies_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Caching_Utility_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Caching_Utility_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cleanup_Strategies_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cleanup_Strategies_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Condition_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Condition_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Connector.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Connector.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Containers_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Containers_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dump_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dump_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Service.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Service.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Env_Value_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Env_Value_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event_Handler_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event_Handler_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Framework_Component_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Framework_Component_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Free_List.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Free_List.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Future.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Future.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Future_Set.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Future_Set.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Guard_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Guard_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Cache_Map_Manager_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Cache_Map_Manager_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_Manager_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_Manager_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_With_Allocator_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_With_Allocator_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Multi_Map_Manager_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Multi_Map_Manager_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_Auto_Ptr.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_Auto_Ptr.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_List.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_List.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_List_Node.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_List_Node.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IOStream_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\IOStream_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Local_Name_Space_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Local_Name_Space_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Lock_Adapter_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Lock_Adapter_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LOCK_SOCK_Acceptor.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\LOCK_SOCK_Acceptor.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Managed_Object.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Managed_Object.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map_Manager.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map_Manager.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Block_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Block_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Metrics_Cache_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Metrics_Cache_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Module.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Module.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Node.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Node.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Obstack_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Obstack_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pair_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pair_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RB_Tree.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\RB_Tree.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor_Token_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor_Token_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcountable_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcountable_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcounted_Auto_Ptr.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcounted_Auto_Ptr.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reverse_Lock_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reverse_Lock_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Select_Reactor_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Select_Reactor_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Singleton.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Singleton.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Strategies_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Strategies_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stream.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stream.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stream_Modules.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stream_Modules.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y String_Base.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\String_Base.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Svc_Handler.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Svc_Handler.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Synch_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Synch_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task_Ex_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task_Ex_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Test_and_Set.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Test_and_Set.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timeprobe_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timeprobe_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Hash_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Hash_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Heap_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Heap_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_List_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_List_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue_Adapters.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue_Adapters.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Wheel_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Wheel_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TSS_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\TSS_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Typed_SV_Message.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Typed_SV_Message.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Typed_SV_Message_Queue.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Typed_SV_Message_Queue.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Queue.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Queue.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Set.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Set.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Set_Ex.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Set_Ex.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Vector_T.cpp $(INSTALL_DIR)\include\$(INCDIR_NAME)\Vector_T.cpp 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ACE.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ACE.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ace_wchar.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ace_wchar.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Activation_Queue.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Activation_Queue.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Active_Map_Manager.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Active_Map_Manager.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Active_Map_Manager_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Active_Map_Manager_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ARGV.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ARGV.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Argv_Type_Converter.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Argv_Type_Converter.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array_Base.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array_Base.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Array_Map.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Array_Map.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Asynch_IO_Impl.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Asynch_IO_Impl.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Acceptor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Acceptor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Params.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Params.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_QoS.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_QoS.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y ATM_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\ATM_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Atomic_Op.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Atomic_Op.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Atomic_Op_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Atomic_Op_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Event.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Event.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Functor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Functor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_IncDec_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_IncDec_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Auto_Ptr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Auto_Ptr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Barrier.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Barrier.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Base_Thread_Adapter.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Base_Thread_Adapter.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Based_Pointer_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Based_Pointer_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Basic_Stats.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Basic_Stats.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Basic_Types.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Basic_Types.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Bound_Ptr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Bound_Ptr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cache_Map_Manager_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cache_Map_Manager_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Caching_Strategies_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Caching_Strategies_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Capabilities.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Capabilities.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CDR_Base.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\CDR_Base.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CDR_Size.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\CDR_Size.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y CDR_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\CDR_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Cleanup.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Cleanup.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Codeset_Registry.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Codeset_Registry.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Condition_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Condition_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Condition_Thread_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Condition_Thread_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Configuration.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Configuration.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Containers.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Containers.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Containers_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Containers_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Date_Time.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Date_Time.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y DEV_IO.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\DEV_IO.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dev_Poll_Reactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dev_Poll_Reactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dirent.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dirent.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dirent_Selector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dirent_Selector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Message_Strategy.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Message_Strategy.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Dynamic_Service.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Dynamic_Service.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Env_Value_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Env_Value_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event_Handler.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event_Handler.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Event_Handler_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Event_Handler_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Recv.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Recv.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Recv_Msg.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Recv_Msg.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Send.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Send.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FIFO_Send_Msg.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FIFO_Send_Msg.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y FILE_IO.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\FILE_IO.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y File_Lock.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\File_Lock.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Flag_Manip.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Flag_Manip.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Framework_Component.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Framework_Component.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor_String.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor_String.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Functor_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Functor_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Get_Opt.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Get_Opt.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Guard_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Guard_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Handle_Gobbler.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Handle_Gobbler.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Handle_Set.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Handle_Set.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Cache_Map_Manager_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Cache_Map_Manager_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_Manager_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_Manager_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Map_With_Allocator_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Map_With_Allocator_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hash_Multi_Map_Manager_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hash_Multi_Map_Manager_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Hashable.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Hashable.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y High_Res_Timer.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\High_Res_Timer.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y INET_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\INET_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_Auto_Ptr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_Auto_Ptr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_List.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_List.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Intrusive_List_Node.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Intrusive_List_Node.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IO_Cntl_Msg.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\IO_Cntl_Msg.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IO_SAP.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\IO_SAP.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IOStream_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\IOStream_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y IPC_SAP.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\IPC_SAP.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Local_Tokens.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Local_Tokens.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Lock.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Lock.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Lock_Adapter_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Lock_Adapter_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Msg.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Msg.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Log_Record.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Log_Record.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_CODgram.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_CODgram.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Dgram.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Dgram.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y LSOCK_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\LSOCK_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc_Allocator.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc_Allocator.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Malloc_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Malloc_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Managed_Object.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Managed_Object.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Manual_Event.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Manual_Event.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map_Manager.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map_Manager.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Map_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Map_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Acceptor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Acceptor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_IO.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_IO.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Mem_Map.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Mem_Map.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_SAP.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_SAP.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MEM_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MEM_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Block.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Block.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Block_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Block_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue_NT.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue_NT.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Message_Queue_Vx.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Message_Queue_Vx.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Metrics_Cache_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Metrics_Cache_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y MMAP_Memory_Pool.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\MMAP_Memory_Pool.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Module.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Module.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Monitor_Base.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Monitor_Base.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Msg_WFMO_Reactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Msg_WFMO_Reactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Multihomed_INET_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Multihomed_INET_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Naming_Context.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Naming_Context.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Netlink_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Netlink_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Notification_Queue.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Notification_Queue.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Notification_Strategy.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Notification_Strategy.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y NT_Service.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\NT_Service.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Obchunk.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Obchunk.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Object_Manager.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Object_Manager.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Obstack_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Obstack_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Errno.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Errno.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_Log_Msg_Attributes.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_Log_Msg_Attributes.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_arpa_inet.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_arpa_inet.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_ctype.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_ctype.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_dirent.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_dirent.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_dlfcn.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_dlfcn.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_errno.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_errno.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_fcntl.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_fcntl.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_math.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_math.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_netdb.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_netdb.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_poll.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_poll.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_pwd.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_pwd.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_regex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_regex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_signal.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_signal.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_stdio.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_stdio.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_stdlib.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_stdlib.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_string.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_string.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_strings.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_strings.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_stropts.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_stropts.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_mman.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_mman.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_msg.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_msg.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_resource.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_resource.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_select.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_select.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_sendfile.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_sendfile.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_shm.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_shm.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_socket.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_socket.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_stat.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_stat.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_time.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_time.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_uio.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_uio.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_sys_wait.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_sys_wait.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_Thread.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_Thread.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_time.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_time.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_unistd.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_unistd.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_NS_wchar.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_NS_wchar.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y OS_TLI.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\OS_TLI.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pagefile_Memory_Pool.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pagefile_Memory_Pool.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pair_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pair_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y PI_Malloc.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\PI_Malloc.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Ping_Socket.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Ping_Socket.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Pipe.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Pipe.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y POSIX_Proactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\POSIX_Proactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Proactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Proactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process_Manager.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process_Manager.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Process_Semaphore.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Process_Semaphore.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Profile_Timer.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Profile_Timer.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RB_Tree.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\RB_Tree.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reactor_Notification_Strategy.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reactor_Notification_Strategy.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Read_Buffer.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Read_Buffer.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Recursive_Thread_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Recursive_Thread_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Recyclable.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Recyclable.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcountable_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcountable_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Refcounted_Auto_Ptr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Refcounted_Auto_Ptr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Remote_Tokens.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Remote_Tokens.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Reverse_Lock_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Reverse_Lock_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RW_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\RW_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RW_Process_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\RW_Process_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y RW_Thread_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\RW_Thread_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sample_History.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sample_History.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sched_Params.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sched_Params.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Select_Reactor_Base.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Select_Reactor_Base.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Select_Reactor_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Select_Reactor_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Semaphore.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Semaphore.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Config.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Config.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Gestalt.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Gestalt.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Object.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Object.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Repository.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Repository.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Service_Types.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Service_Types.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Memory_MM.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Memory_MM.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Memory_SV.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Memory_SV.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Shared_Object.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Shared_Object.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Sig_Handler.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Sig_Handler.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Signal.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Signal.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Singleton.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Singleton.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Acceptor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Acceptor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_CODgram.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_CODgram.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Dgram.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Dgram.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Dgram_Bcast.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Dgram_Bcast.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Dgram_Mcast.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Dgram_Mcast.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_IO.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_IO.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Netlink.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Netlink.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_SEQPACK_Acceptor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_SEQPACK_Acceptor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_SEQPACK_Association.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_SEQPACK_Association.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_SEQPACK_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_SEQPACK_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SOCK_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SOCK_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SPIPE_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SPIPE_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SString.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SString.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stats.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stats.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Strategies_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Strategies_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y String_Base.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\String_Base.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Message.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Message.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Message_Queue.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Message_Queue.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Semaphore_Complex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Semaphore_Complex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Semaphore_Simple.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Semaphore_Simple.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y SV_Shared_Memory.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\SV_Shared_Memory.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task_Ex_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task_Ex_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Task_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Task_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Adapter.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Adapter.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Control.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Control.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Manager.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Manager.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Mutex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Mutex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Thread_Semaphore.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Thread_Semaphore.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Time_Value.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Time_Value.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timeprobe.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timeprobe.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue_Adapters.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue_Adapters.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Timer_Queue_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Timer_Queue_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TLI_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\TLI_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Collection.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Collection.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Manager.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Manager.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Token_Request_Reply.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Token_Request_Reply.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TP_Reactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\TP_Reactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y TSS_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\TSS_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Typed_SV_Message.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Typed_SV_Message.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Typed_SV_Message_Queue.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Typed_SV_Message_Queue.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Queue.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Queue.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Set.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Set.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Unbounded_Set_Ex.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Unbounded_Set_Ex.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UNIX_Addr.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\UNIX_Addr.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Acceptor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Acceptor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Connector.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Connector.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UPIPE_Stream.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\UPIPE_Stream.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UTF16_Encoding_Converter.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\UTF16_Encoding_Converter.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y UUID.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\UUID.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y Vector_T.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\Vector_T.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y WFMO_Reactor.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\WFMO_Reactor.inl 1> NUL + -@if not exist $(INSTALL_DIR)\include\$(INCDIR_NAME)\. mkdir $(INSTALL_DIR)\include\$(INCDIR_NAME)\. + -© /Y XTI_ATM_Mcast.inl $(INSTALL_DIR)\include\$(INCDIR_NAME)\XTI_ATM_Mcast.inl 1> NUL + +realclean: + @-rem + diff --git a/dep/ACE_wrappers/ace/ACE.cpp b/dep/ACE_wrappers/ace/ACE.cpp new file mode 100644 index 000000000..4980b2d73 --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE.cpp @@ -0,0 +1,3444 @@ +// $Id: ACE.cpp 82581 2008-08-11 08:58:24Z johnnyw $ + +#include "ace/ACE.h" + +#include "ace/Basic_Types.h" +#include "ace/Handle_Set.h" +#include "ace/Auto_Ptr.h" +#include "ace/SString.h" +#include "ace/Version.h" +#include "ace/Message_Block.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_sys_select.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_strings.h" +#include "ace/OS_NS_signal.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_sys_resource.h" +#include "ace/OS_NS_sys_wait.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_sys_uio.h" +#include "ace/OS_NS_sys_stat.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_TLI.h" +#include "ace/Truncate.h" + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) +extern "C" int maxFiles; +#endif /* ACE_VXWORKS */ + +#if !defined (__ACE_INLINE__) +#include "ace/ACE.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) +# include "ace/OS_NS_poll.h" +#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ + + +ACE_RCSID (ace, + ACE, + "$Id: ACE.cpp 82581 2008-08-11 08:58:24Z johnnyw $") + + +// Open versioned namespace, if enabled by the user. + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE +{ + // private: + // Used internally so not exported. + + // Size of allocation granularity. + size_t allocation_granularity_ = 0; + + // Size of a VM page. + size_t pagesize_ = 0; + + // Are we debugging ACE? + // Keeps track of whether we're in some global debug mode. + char debug_; +} + + +int +ACE::out_of_handles (int error) +{ + // EMFILE is common to all platforms. + if (error == EMFILE || +#if defined (ACE_WIN32) + // On Win32, we need to check for ENOBUFS also. + error == ENOBUFS || +#elif defined (HPUX) + // On HPUX, we need to check for EADDRNOTAVAIL also. + error == EADDRNOTAVAIL || +#elif defined (linux) + // On linux, we need to check for ENOENT also. + error == ENOENT || + // For RedHat5.2, need to check for EINVAL too. + error == EINVAL || + // Without threads check for EOPNOTSUPP + error == EOPNOTSUPP || +#elif defined (sun) + // On sun, we need to check for ENOSR also. + error == ENOSR || + // Without threads check for ENOTSUP + error == ENOTSUP || +#elif defined (__FreeBSD__) + // On FreeBSD we need to check for EOPNOTSUPP (LinuxThreads) or + // ENOSYS (libc_r threads) also. + error == EOPNOTSUPP || + error == ENOSYS || +#elif defined (__OpenBSD__) + // OpenBSD appears to return EBADF. + error == EBADF || +#elif defined (__sgi) // irix + error == ENOTSUP || +#elif defined (DIGITAL_UNIX) // osf1 + error == ENOTSUP || +#endif /* ACE_WIN32 */ + error == ENFILE) + return 1; + else + return 0; +} + +u_int +ACE::major_version (void) +{ + return ACE_MAJOR_VERSION; +} + +u_int +ACE::minor_version (void) +{ + return ACE_MINOR_VERSION; +} + +u_int +ACE::beta_version (void) +{ + return ACE_BETA_VERSION; +} + +const ACE_TCHAR * +ACE::compiler_name (void) +{ +#ifdef ACE_CC_NAME + return ACE_CC_NAME; +#else + return ACE_TEXT (""); +#endif +} + +u_int +ACE::compiler_major_version (void) +{ +#ifdef ACE_CC_MAJOR_VERSION + return ACE_CC_MAJOR_VERSION; +#else + return 0; +#endif +} + +u_int +ACE::compiler_minor_version (void) +{ +#ifdef ACE_CC_MINOR_VERSION + return ACE_CC_MINOR_VERSION; +#else + return 0; +#endif +} + +u_int +ACE::compiler_beta_version (void) +{ +#ifdef ACE_CC_BETA_VERSION + return ACE_CC_BETA_VERSION; +#else + return 0; +#endif +} + +bool +ACE::debug (void) +{ + static const char* debug = ACE_OS::getenv ("ACE_DEBUG"); + return (ACE::debug_ != 0) ? ACE::debug_ : (debug != 0 ? (*debug != '0'): false); +} + +void +ACE::debug (bool onoff) +{ + ACE::debug_ = onoff; +} + +int +ACE::select (int width, + ACE_Handle_Set *readfds, + ACE_Handle_Set *writefds, + ACE_Handle_Set *exceptfds, + const ACE_Time_Value *timeout) +{ + int result = ACE_OS::select (width, + readfds ? readfds->fdset () : 0, + writefds ? writefds->fdset () : 0, + exceptfds ? exceptfds->fdset () : 0, + timeout); + if (result > 0) + { +# if !defined (ACE_WIN32) + // This isn't needed for Windows... it's a no-op anyway. + if (readfds) + readfds->sync ((ACE_HANDLE) width); + if (writefds) + writefds->sync ((ACE_HANDLE) width); + if (exceptfds) + exceptfds->sync ((ACE_HANDLE) width); +#endif /* ACE_WIN32 */ + } + return result; +} + +int +ACE::select (int width, + ACE_Handle_Set &readfds, + const ACE_Time_Value *timeout) +{ + int result = ACE_OS::select (width, + readfds.fdset (), + 0, + 0, + timeout); + +#if !defined (ACE_WIN32) + if (result > 0) + readfds.sync ((ACE_HANDLE) width); +#endif /* ACE_WIN32 */ + return result; +} + +int +ACE::terminate_process (pid_t pid) +{ +#if defined (ACE_HAS_PHARLAP) + ACE_UNUSED_ARG (pid); + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_WIN32) + // Create a handle for the given process id. + ACE_HANDLE process_handle = + ::OpenProcess (PROCESS_TERMINATE, + FALSE, // New handle is not inheritable. + pid); + + if (process_handle == ACE_INVALID_HANDLE + || process_handle == 0) + return -1; + else + { + // Kill the process associated with process_handle. + BOOL terminate_result = + ::TerminateProcess (process_handle, 0); + // Free up the kernel resources. + ACE_OS::close (process_handle); + return terminate_result ? 0 : -1; + } +#else + return ACE_OS::kill (pid, 9); +#endif /* ACE_HAS_PHARLAP */ +} + +int +ACE::process_active (pid_t pid) +{ +#if !defined(ACE_WIN32) + if (ACE_OS::kill (pid, 0) == 0) + return 1; + else if (errno == ESRCH) + return 0; + else + return -1; +#else + // Create a handle for the given process id. + ACE_HANDLE process_handle = + ::OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid); + if (process_handle == ACE_INVALID_HANDLE || process_handle == 0) + return 0; + else + { + DWORD status; + int result = 1; + if (::GetExitCodeProcess (process_handle, + &status) == 0 + || status != STILL_ACTIVE) + result = 0; + + ::CloseHandle (process_handle); + return result; + } +#endif /* !ACE_WIN32 */ +} + +const ACE_TCHAR * +ACE::execname (const ACE_TCHAR *old_name) +{ +#if defined (ACE_WIN32) + const ACE_TCHAR *suffix = ACE_OS::strrchr (old_name, ACE_TEXT ('.')); + if (suffix == 0 || ACE_OS::strcasecmp (suffix, ACE_TEXT (".exe")) != 0) + { + ACE_TCHAR *new_name = 0; + + size_t size = + ACE_OS::strlen (old_name) + + ACE_OS::strlen (ACE_TEXT (".exe")) + + 1; + + ACE_NEW_RETURN (new_name, + ACE_TCHAR[size], + 0); + ACE_TCHAR *end = new_name; + + end = ACE_OS::strecpy (new_name, old_name); + + // Concatenate the .exe suffix onto the end of the executable. + // end points _after_ the terminating nul. + ACE_OS::strcpy (end - 1, ACE_TEXT (".exe")); + + return new_name; + } +#endif /* ACE_WIN32 */ + return old_name; +} + +u_long +ACE::hash_pjw (const char *str, size_t len) +{ + u_long hash = 0; + + for (size_t i = 0; i < len; i++) + { + const char temp = str[i]; + hash = (hash << 4) + (temp * 13); + + u_long g = hash & 0xf0000000; + + if (g) + { + hash ^= (g >> 24); + hash ^= g; + } + } + + return hash; +} + +u_long +ACE::hash_pjw (const char *str) +{ + return ACE::hash_pjw (str, ACE_OS::strlen (str)); +} + +#if defined (ACE_HAS_WCHAR) +u_long +ACE::hash_pjw (const wchar_t *str, size_t len) +{ + u_long hash = 0; + + for (size_t i = 0; i < len; i++) + { + // @@ UNICODE: Does this function do the correct thing with wchar's? + + const wchar_t temp = str[i]; + hash = (hash << 4) + (temp * 13); + + u_long g = hash & 0xf0000000; + + if (g) + { + hash ^= (g >> 24); + hash ^= g; + } + } + + return hash; +} + +u_long +ACE::hash_pjw (const wchar_t *str) +{ + return ACE::hash_pjw (str, ACE_OS::strlen (str)); +} +#endif /* ACE_HAS_WCHAR */ + +#if !defined (ACE_HAS_WINCE) +ACE_TCHAR * +ACE::strenvdup (const ACE_TCHAR *str) +{ + ACE_TRACE ("ACE::strenvdup"); + + return ACE_OS::strenvdup (str); +} +#endif /* ACE_HAS_WINCE */ + +/* + +Examples: + +Source NT UNIX +================================================================== +netsvc netsvc.dll libnetsvc.so +(PATH will be (LD_LIBRARY_PATH +evaluated) evaluated) + +libnetsvc.dll libnetsvc.dll libnetsvc.dll + warning +netsvc.so netsvc.so + warning libnetsvc.so + +..\../libs/netsvc ..\..\libs\netsvc.dll ../../libs/netsvc.so +(absolute path used) (absolute path used) + +*/ + +const ACE_TCHAR * +ACE::basename (const ACE_TCHAR *pathname, ACE_TCHAR delim) +{ + ACE_TRACE ("ACE::basename"); + const ACE_TCHAR *temp = ACE_OS::strrchr (pathname, delim); + + if (temp == 0) + return pathname; + else + return temp + 1; +} + +const ACE_TCHAR * +ACE::dirname (const ACE_TCHAR *pathname, ACE_TCHAR delim) +{ + ACE_TRACE ("ACE::dirname"); + static ACE_TCHAR return_dirname[MAXPATHLEN + 1]; + + const ACE_TCHAR *temp = ACE_OS::strrchr (pathname, delim); + + if (temp == 0) + { + return_dirname[0] = '.'; + return_dirname[1] = '\0'; + + return return_dirname; + } + else + { + // When the len is truncated, there are problems! This should + // not happen in normal circomstances + size_t len = temp - pathname + 1; + if (len > (sizeof return_dirname / sizeof (ACE_TCHAR))) + len = sizeof return_dirname / sizeof (ACE_TCHAR); + + ACE_OS::strsncpy (return_dirname, + pathname, + len); + return return_dirname; + } +} + +ssize_t +ACE::recv (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::recv (handle, (char *) buf, len, flags); + else + { + int val = 0; + if (ACE::enter_recv_timedwait (handle, timeout, val) ==-1) + return -1; + else + { + ssize_t bytes_transferred = + ACE_OS::recv (handle, (char *) buf, len, flags); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +#if defined (ACE_HAS_TLI) + +ssize_t +ACE::t_rcv (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::t_rcv (handle, (char *) buf, len, flags); + else + { + int val = 0; + if (ACE::enter_recv_timedwait (handle, timeout, val) ==-1) + return -1; + else + { + ssize_t bytes_transferred = + ACE_OS::t_rcv (handle, (char *) buf, len, flags); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +#endif /* ACE_HAS_TLI */ + +ssize_t +ACE::recv (ACE_HANDLE handle, + void *buf, + size_t n, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE::recv_i (handle, buf, n); + else + { + int val = 0; + if (ACE::enter_recv_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE::recv_i (handle, buf, n); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::recvmsg (ACE_HANDLE handle, + struct msghdr *msg, + int flags, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::recvmsg (handle, msg, flags); + else + { + int val = 0; + if (ACE::enter_recv_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE_OS::recvmsg (handle, msg, flags); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::recvfrom (ACE_HANDLE handle, + char *buf, + int len, + int flags, + struct sockaddr *addr, + int *addrlen, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::recvfrom (handle, buf, len, flags, addr, addrlen); + else + { + int val = 0; + if (ACE::enter_recv_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = + ACE_OS::recvfrom (handle, buf, len, flags, addr, addrlen); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + n = ACE_OS::recv (handle, + static_cast (buf) + bytes_transferred, + len - bytes_transferred, + flags); + // Check EOF. + if (n == 0) + return 0; + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK) + { + // Wait for the blocking to subside. + int const result = ACE::handle_read_ready (handle, 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + } + + return static_cast (bytes_transferred); +} + +ssize_t +ACE::recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + n = ACE_OS::recv (handle, + static_cast (buf) + bytes_transferred, + len - bytes_transferred, + flags); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + errno == EWOULDBLOCK) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_read_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + return result; + else + return static_cast (bytes_transferred); +} + +#if defined (ACE_HAS_TLI) + +ssize_t +ACE::t_rcv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + n = ACE_OS::t_rcv (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred, + flags); + // Check EOF. + if (n == 0) + return 0; + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK) + { + // Wait for the blocking to subside. + int result = ACE::handle_read_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + } + + return bytes_transferred; +} + +ssize_t +ACE::t_rcv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + n = ACE_OS::t_rcv (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred, + flags); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + errno == EWOULDBLOCK) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_read_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + return result; + else + return bytes_transferred; +} + +#endif /* ACE_HAS_TLI */ + +ssize_t +ACE::recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + n = ACE::recv_i (handle, + static_cast (buf) + bytes_transferred, + len - bytes_transferred); + // Check EOF. + if (n == 0) + { + return 0; + } + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK) + { + // Wait for the blocking to subside. + int result = ACE::handle_read_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + } + + return static_cast (bytes_transferred); +} + +ssize_t +ACE::recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + n = ACE::recv_i (handle, + static_cast (buf) + bytes_transferred, + len - bytes_transferred); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + errno == EWOULDBLOCK) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_read_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + return result; + else + return static_cast (bytes_transferred); +} + +// This is basically an interface to ACE_OS::readv, that doesn't use +// the struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE::recv (ACE_HANDLE handle, size_t n, ...) +{ + va_list argp; + int total_tuples = static_cast (n / 2); + iovec *iovp; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (int i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + ssize_t result = ACE_OS::recvv (handle, iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +ssize_t +ACE::recvv (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::recvv (handle, iov, iovcnt); + else + { + int val = 0; + if (ACE::enter_recv_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE_OS::recvv (handle, iov, iovcnt); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::recvv_n_i (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + for (int s = 0; + s < iovcnt; + ) + { + // Try to transfer as much of the remaining data as possible. + ssize_t n = ACE_OS::recvv (handle, + iov + s, + iovcnt - s); + // Check EOF. + if (n == 0) + return 0; + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK) + { + // Wait for the blocking to subside. + int result = ACE::handle_read_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + + for (bytes_transferred += n; + s < iovcnt + && n >= static_cast (iov[s].iov_len); + s++) + n -= iov[s].iov_len; + + if (n != 0) + { + char *base = static_cast (iov[s].iov_base); + iov[s].iov_base = base + n; + iov[s].iov_len = iov[s].iov_len - n; + } + } + + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::recvv_n_i (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (int s = 0; + s < iovcnt; + ) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + ssize_t n = ACE_OS::recvv (handle, + iov + s, + iovcnt - s); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + errno == EWOULDBLOCK) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_read_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + + for (bytes_transferred += n; + s < iovcnt + && n >= static_cast (iov[s].iov_len); + s++) + n -= iov[s].iov_len; + + if (n != 0) + { + char *base = reinterpret_cast (iov[s].iov_base); + iov[s].iov_base = base + n; + iov[s].iov_len = iov[s].iov_len - n; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + { + return result; + } + else + { + return ACE_Utils::truncate_cast (bytes_transferred); + } +} + +ssize_t +ACE::recv_n (ACE_HANDLE handle, + ACE_Message_Block *message_block, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + while (message_block != 0) + { + // Our current message block chain. + const ACE_Message_Block *current_message_block = message_block; + + while (current_message_block != 0) + { + size_t current_message_block_length = + current_message_block->length (); + char *this_rd_ptr = current_message_block->rd_ptr (); + + // Check if this block has any space for incoming data. + while (current_message_block_length > 0) + { + u_long const this_chunk_length = + ACE_Utils::truncate_cast ( + current_message_block_length); + + // Collect the data in the iovec. + iov[iovcnt].iov_base = this_rd_ptr; + iov[iovcnt].iov_len = this_chunk_length; + current_message_block_length -= this_chunk_length; + this_rd_ptr += this_chunk_length; + + // Increment iovec counter. + ++iovcnt; + + // The buffer is full make a OS call. @@ TODO find a way to + // find ACE_IOV_MAX for platforms that do not define it rather + // than simply setting ACE_IOV_MAX to some arbitrary value such + // as 16. + if (iovcnt == ACE_IOV_MAX) + { + size_t current_transfer = 0; + + ssize_t const result = ACE::recvv_n (handle, + iov, + iovcnt, + timeout, + ¤t_transfer); + + // Add to total bytes transferred. + bytes_transferred += current_transfer; + + // Errors. + if (result == -1 || result == 0) + return result; + + // Reset iovec counter. + iovcnt = 0; + } + } + + // Select the next message block in the chain. + current_message_block = current_message_block->cont (); + } + + // Selection of the next message block chain. + message_block = message_block->next (); + } + + // Check for remaining buffers to be sent. This will happen when + // ACE_IOV_MAX is not a multiple of the number of message blocks. + if (iovcnt != 0) + { + size_t current_transfer = 0; + + ssize_t const result = ACE::recvv_n (handle, + iov, + iovcnt, + timeout, + ¤t_transfer); + + // Add to total bytes transferred. + bytes_transferred += current_transfer; + + // Errors. + if (result == -1 || result == 0) + { + return result; + } + } + + // Return total bytes transferred. + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::send (ACE_HANDLE handle, + const void *buf, + size_t n, + int flags, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::send (handle, (const char *) buf, n, flags); + else + { + int val = 0; + if (ACE::enter_send_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE_OS::send (handle, (const char *) buf, n, flags); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +#if defined (ACE_HAS_TLI) + +ssize_t +ACE::t_snd (ACE_HANDLE handle, + const void *buf, + size_t n, + int flags, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::t_snd (handle, (const char *) buf, n, flags); + else + { + int val = 0; + if (ACE::enter_send_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE_OS::t_snd (handle, (const char *) buf, n, flags); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +#endif /* ACE_HAS_TLI */ + +ssize_t +ACE::send (ACE_HANDLE handle, + const void *buf, + size_t n, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE::send_i (handle, buf, n); + else + { + int val = 0; + if (ACE::enter_send_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE::send_i (handle, buf, n); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::sendmsg (ACE_HANDLE handle, + const struct msghdr *msg, + int flags, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::sendmsg (handle, msg, flags); + else + { + int val = 0; + if (ACE::enter_send_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE_OS::sendmsg (handle, msg, flags); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::sendto (ACE_HANDLE handle, + const char *buf, + int len, + int flags, + const struct sockaddr *addr, + int addrlen, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::sendto (handle, buf, len, flags, addr, addrlen); + else + { + int val = 0; + if (ACE::enter_send_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = + ACE_OS::sendto (handle, buf, len, flags, addr, addrlen); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + n = ACE_OS::send (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred, + flags); + // Check EOF. + if (n == 0) + return 0; + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. +#if defined (ACE_WIN32) + if (errno == EWOULDBLOCK) // If enobufs no need to loop +#else + if (errno == EWOULDBLOCK || errno == ENOBUFS) +#endif /* ACE_WIN32 */ + { + // Wait for the blocking to subside. + int result = ACE::handle_write_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + } + + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + n = ACE_OS::send (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred, + flags); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + (errno == EWOULDBLOCK || errno == ENOBUFS)) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_write_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + { + return result; + } + else + { + return ACE_Utils::truncate_cast (bytes_transferred); + } +} + +#if defined (ACE_HAS_TLI) + +ssize_t +ACE::t_snd_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + n = ACE_OS::t_snd (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred, + flags); + // Check EOF. + if (n == 0) + return 0; + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK || errno == ENOBUFS) + { + // Wait for the blocking to subside. + int result = ACE::handle_write_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + } + + return bytes_transferred; +} + +ssize_t +ACE::t_snd_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + n = ACE_OS::t_snd (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred, + flags); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + errno == EWOULDBLOCK || errno == ENOBUFS) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_write_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + return result; + else + return bytes_transferred; +} + +#endif /* ACE_HAS_TLI */ + +ssize_t +ACE::send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + n = ACE::send_i (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred); + // Check EOF. + if (n == 0) + { + return 0; + } + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK || errno == ENOBUFS) + { + // Wait for the blocking to subside. + int result = ACE::handle_write_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + } + + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + ssize_t n; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + for (bytes_transferred = 0; + bytes_transferred < len; + bytes_transferred += n) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + n = ACE::send_i (handle, + (char *) buf + bytes_transferred, + len - bytes_transferred); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + (errno == EWOULDBLOCK || errno == ENOBUFS)) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_write_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + { + return result; + } + else + { + return ACE_Utils::truncate_cast (bytes_transferred); + } +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE::send (ACE_HANDLE handle, size_t n, ...) +{ + va_list argp; + int total_tuples = static_cast (n / 2); + iovec *iovp; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (int i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + ssize_t result = ACE_OS::sendv (handle, iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +ssize_t +ACE::sendv (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout) +{ + if (timeout == 0) + return ACE_OS::sendv (handle, iov, iovcnt); + else + { + int val = 0; + if (ACE::enter_send_timedwait (handle, timeout, val) == -1) + return -1; + else + { + ssize_t bytes_transferred = ACE_OS::sendv (handle, iov, iovcnt); + ACE::restore_non_blocking_mode (handle, val); + return bytes_transferred; + } + } +} + +ssize_t +ACE::sendv_n_i (ACE_HANDLE handle, + const iovec *i, + int iovcnt, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + iovec *iov = const_cast (i); + + for (int s = 0; + s < iovcnt; + ) + { + // Try to transfer as much of the remaining data as possible. + ssize_t n = ACE_OS::sendv (handle, + iov + s, + iovcnt - s); + // Check EOF. + if (n == 0) + return 0; + + // Check for other errors. + if (n == -1) + { + // Check for possible blocking. + if (errno == EWOULDBLOCK || errno == ENOBUFS) + { + // Wait for the blocking to subside. + int result = ACE::handle_write_ready (handle, + 0); + + // Did select() succeed? + if (result != -1) + { + // Blocking subsided. Continue data transfer. + n = 0; + continue; + } + } + + // Other data transfer or select() failures. + return -1; + } + + for (bytes_transferred += n; + s < iovcnt + && n >= static_cast (iov[s].iov_len); + s++) + n -= iov[s].iov_len; + + if (n != 0) + { + char *base = reinterpret_cast (iov[s].iov_base); + iov[s].iov_base = base + n; + iov[s].iov_len = iov[s].iov_len - n; + } + } + + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::sendv_n_i (ACE_HANDLE handle, + const iovec *i, + int iovcnt, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + ssize_t result = 0; + int error = 0; + + int val = 0; + ACE::record_and_set_non_blocking_mode (handle, val); + + iovec *iov = const_cast (i); + + for (int s = 0; + s < iovcnt; + ) + { + // Try to transfer as much of the remaining data as possible. + // Since the socket is in non-blocking mode, this call will not + // block. + ssize_t n = ACE_OS::sendv (handle, + iov + s, + iovcnt - s); + + // Check for errors. + if (n == 0 || + n == -1) + { + // Check for possible blocking. + if (n == -1 && + (errno == EWOULDBLOCK || errno == ENOBUFS)) + { + // Wait upto for the blocking to subside. + int rtn = ACE::handle_write_ready (handle, + timeout); + + // Did select() succeed? + if (rtn != -1) + { + // Blocking subsided in period. Continue + // data transfer. + n = 0; + continue; + } + } + + // Wait in select() timed out or other data transfer or + // select() failures. + error = 1; + result = n; + break; + } + + for (bytes_transferred += n; + s < iovcnt + && n >= static_cast (iov[s].iov_len); + s++) + n -= iov[s].iov_len; + + if (n != 0) + { + char *base = reinterpret_cast (iov[s].iov_base); + iov[s].iov_base = base + n; + iov[s].iov_len = iov[s].iov_len - n; + } + } + + ACE::restore_non_blocking_mode (handle, val); + + if (error) + { + return result; + } + else + { + return ACE_Utils::truncate_cast (bytes_transferred); + } +} + +ssize_t +ACE::write_n (ACE_HANDLE handle, + const ACE_Message_Block *message_block, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + while (message_block != 0) + { + // Our current message block chain. + const ACE_Message_Block *current_message_block = message_block; + + while (current_message_block != 0) + { + size_t current_message_block_length = + current_message_block->length (); + char *this_block_ptr = current_message_block->rd_ptr (); + + // Check if this block has any data to be sent. + while (current_message_block_length > 0) + { + u_long const this_chunk_length = + ACE_Utils::truncate_cast ( + current_message_block_length); + + // Collect the data in the iovec. + iov[iovcnt].iov_base = this_block_ptr; + iov[iovcnt].iov_len = this_chunk_length; + current_message_block_length -= this_chunk_length; + this_block_ptr += this_chunk_length; + + // Increment iovec counter. + ++iovcnt; + + // The buffer is full make a OS call. @@ TODO find a way to + // find ACE_IOV_MAX for platforms that do not define it rather + // than simply setting ACE_IOV_MAX to some arbitrary value such + // as 16. + if (iovcnt == ACE_IOV_MAX) + { + size_t current_transfer = 0; + + ssize_t const result = ACE::writev_n (handle, + iov, + iovcnt, + ¤t_transfer); + + // Add to total bytes transferred. + bytes_transferred += current_transfer; + + // Errors. + if (result == -1 || result == 0) + return result; + + // Reset iovec counter. + iovcnt = 0; + } + } + + // Select the next message block in the chain. + current_message_block = current_message_block->cont (); + } + + // Selection of the next message block chain. + message_block = message_block->next (); + } + + // Check for remaining buffers to be sent. This will happen when + // ACE_IOV_MAX is not a multiple of the number of message blocks. + if (iovcnt != 0) + { + size_t current_transfer = 0; + + ssize_t const result = ACE::writev_n (handle, + iov, + iovcnt, + ¤t_transfer); + + // Add to total bytes transferred. + bytes_transferred += current_transfer; + + // Errors. + if (result == -1 || result == 0) + return result; + } + + // Return total bytes transferred. + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::send_n (ACE_HANDLE handle, + const ACE_Message_Block *message_block, + const ACE_Time_Value *timeout, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + while (message_block != 0) + { + // Our current message block chain. + const ACE_Message_Block *current_message_block = message_block; + + while (current_message_block != 0) + { + char *this_block_ptr = current_message_block->rd_ptr (); + size_t current_message_block_length = + current_message_block->length (); + + // Check if this block has any data to be sent. + while (current_message_block_length > 0) + { + u_long const this_chunk_length = + ACE_Utils::truncate_cast ( + current_message_block_length); + + // Collect the data in the iovec. + iov[iovcnt].iov_base = this_block_ptr; + iov[iovcnt].iov_len = this_chunk_length; + current_message_block_length -= this_chunk_length; + this_block_ptr += this_chunk_length; + + // Increment iovec counter. + ++iovcnt; + + // The buffer is full make a OS call. @@ TODO find a way to + // find ACE_IOV_MAX for platforms that do not define it rather + // than simply setting ACE_IOV_MAX to some arbitrary value such + // as 16. + if (iovcnt == ACE_IOV_MAX) + { + size_t current_transfer = 0; + + ssize_t const result = ACE::sendv_n (handle, + iov, + iovcnt, + timeout, + ¤t_transfer); + + // Add to total bytes transferred. + bytes_transferred += current_transfer; + + // Errors. + if (result == -1 || result == 0) + return result; + + // Reset iovec counter. + iovcnt = 0; + } + } + + // Select the next message block in the chain. + current_message_block = current_message_block->cont (); + } + + // Selection of the next message block chain. + message_block = message_block->next (); + } + + // Check for remaining buffers to be sent. This will happen when + // ACE_IOV_MAX is not a multiple of the number of message blocks. + if (iovcnt != 0) + { + size_t current_transfer = 0; + + ssize_t const result = ACE::sendv_n (handle, + iov, + iovcnt, + timeout, + ¤t_transfer); + + // Add to total bytes transferred. + bytes_transferred += current_transfer; + + // Errors. + if (result == -1 || result == 0) + { + return result; + } + } + + // Return total bytes transferred. + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::readv_n (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + for (int s = 0; + s < iovcnt; + ) + { + ssize_t n = ACE_OS::readv (handle, + iov + s, + iovcnt - s); + + if (n == -1 || n == 0) + return n; + + for (bytes_transferred += n; + s < iovcnt + && n >= static_cast (iov[s].iov_len); + s++) + n -= iov[s].iov_len; + + if (n != 0) + { + char *base = reinterpret_cast (iov[s].iov_base); + iov[s].iov_base = base + n; + iov[s].iov_len = iov[s].iov_len - n; + } + } + + return ACE_Utils::truncate_cast (bytes_transferred); +} + +ssize_t +ACE::writev_n (ACE_HANDLE handle, + const iovec *i, + int iovcnt, + size_t *bt) +{ + size_t temp; + size_t &bytes_transferred = bt == 0 ? temp : *bt; + bytes_transferred = 0; + + iovec *iov = const_cast (i); + + for (int s = 0; + s < iovcnt; + ) + { + ssize_t n = ACE_OS::writev (handle, + iov + s, + iovcnt - s); + + if (n == -1 || n == 0) + { + return n; + } + + for (bytes_transferred += n; + s < iovcnt + && n >= static_cast (iov[s].iov_len); + s++) + n -= iov[s].iov_len; + + if (n != 0) + { + char *base = reinterpret_cast (iov[s].iov_base); + iov[s].iov_base = base + n; + iov[s].iov_len = iov[s].iov_len - n; + } + } + + return ACE_Utils::truncate_cast (bytes_transferred); +} + +int +ACE::handle_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout, + int read_ready, + int write_ready, + int exception_ready) +{ +#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + ACE_UNUSED_ARG (write_ready); + ACE_UNUSED_ARG (exception_ready); + + struct pollfd fds; + + fds.fd = handle; + fds.events = read_ready ? POLLIN : POLLOUT; + fds.revents = 0; + + int result = ACE_OS::poll (&fds, 1, timeout); +#else + ACE_Handle_Set handle_set; + handle_set.set_bit (handle); + + // Wait for data or for the timeout to elapse. + int select_width; +# if defined (ACE_WIN32) + // This arg is ignored on Windows and causes pointer truncation + // warnings on 64-bit compiles. + select_width = 0; +# else + select_width = int (handle) + 1; +# endif /* ACE_WIN64 */ + int result = ACE_OS::select (select_width, + read_ready ? handle_set.fdset () : 0, // read_fds. + write_ready ? handle_set.fdset () : 0, // write_fds. + exception_ready ? handle_set.fdset () : 0, // exception_fds. + timeout); + +#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ + + switch (result) + { + case 0: // Timer expired. + errno = ETIME; + /* FALLTHRU */ + case -1: // we got here directly - select() returned -1. + return -1; + case 1: // Handle has data. + /* FALLTHRU */ + default: // default is case result > 0; return a + // ACE_ASSERT (result == 1); + return result; + } +} + +int +ACE::enter_recv_timedwait (ACE_HANDLE handle, + const ACE_Time_Value *timeout, + int &val) +{ + int result = ACE::handle_read_ready (handle, + timeout); + + if (result == -1) + return -1; + + ACE::record_and_set_non_blocking_mode (handle, + val); + + return result; +} + +int +ACE::enter_send_timedwait (ACE_HANDLE handle, + const ACE_Time_Value *timeout, + int &val) +{ + int result = ACE::handle_write_ready (handle, + timeout); + + if (result == -1) + return -1; + + ACE::record_and_set_non_blocking_mode (handle, + val); + + return result; +} + +void +ACE::record_and_set_non_blocking_mode (ACE_HANDLE handle, + int &val) +{ + // We need to record whether we are already *in* nonblocking mode, + // so that we can correctly reset the state when we're done. + val = ACE::get_flags (handle); + + if (ACE_BIT_DISABLED (val, ACE_NONBLOCK)) + // Set the handle into non-blocking mode if it's not already in + // it. + ACE::set_flags (handle, ACE_NONBLOCK); +} + +void +ACE::restore_non_blocking_mode (ACE_HANDLE handle, + int val) +{ + if (ACE_BIT_DISABLED (val, + ACE_NONBLOCK)) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + // Only disable ACE_NONBLOCK if we weren't in non-blocking mode + // originally. + ACE::clr_flags (handle, ACE_NONBLOCK); + } +} + + +// Format buffer into printable format. This is useful for debugging. +// Portions taken from mdump by J.P. Knight (J.P.Knight@lut.ac.uk) +// Modifications by Todd Montgomery. + +size_t +ACE::format_hexdump (const char *buffer, + size_t size, + ACE_TCHAR *obuf, + size_t obuf_sz) +{ + ACE_TRACE ("ACE::format_hexdump"); + + u_char c; + ACE_TCHAR textver[16 + 1]; + + // We can fit 16 bytes output in text mode per line, 4 chars per byte. + size_t maxlen = (obuf_sz / 68) * 16; + + if (size > maxlen) + size = maxlen; + + size_t i; + + size_t lines = size / 16; + for (i = 0; i < lines; i++) + { + size_t j; + + for (j = 0 ; j < 16; j++) + { + c = (u_char) buffer[(i << 4) + j]; // or, buffer[i*16+j] + ACE_OS::sprintf (obuf, + ACE_TEXT ("%02x "), + c); + obuf += 3; + if (j == 7) + { + ACE_OS::sprintf (obuf, + ACE_TEXT (" ")); + ++obuf; + } + textver[j] = ACE_OS::ace_isprint (c) ? c : '.'; + } + + textver[j] = 0; + + ACE_OS::sprintf (obuf, + ACE_TEXT (" %s\n"), + textver); + + while (*obuf != '\0') + ++obuf; + } + + if (size % 16) + { + for (i = 0 ; i < size % 16; i++) + { + c = (u_char) buffer[size - size % 16 + i]; + ACE_OS::sprintf (obuf, + ACE_TEXT ("%02x "), + c); + obuf += 3; + if (i == 7) + { + ACE_OS::sprintf (obuf, + ACE_TEXT (" ")); + ++obuf; + } + textver[i] = ACE_OS::ace_isprint (c) ? c : '.'; + } + + for (i = size % 16; i < 16; i++) + { + ACE_OS::sprintf (obuf, + ACE_TEXT (" ")); + obuf += 3; + if (i == 7) + { + ACE_OS::sprintf (obuf, + ACE_TEXT (" ")); + ++obuf; + } + textver[i] = ' '; + } + + textver[i] = 0; + ACE_OS::sprintf (obuf, + ACE_TEXT (" %s\n"), + textver); + } + return size; +} + +// Returns the current timestamp in the form +// "hour:minute:second:microsecond." The month, day, and year are +// also stored in the beginning of the date_and_time array. + +ACE_TCHAR * +ACE::timestamp (ACE_TCHAR date_and_time[], + size_t date_and_timelen, + bool return_pointer_to_first_digit) +{ + //ACE_TRACE ("ACE::timestamp"); + + if (date_and_timelen < 35) + { + errno = EINVAL; + return 0; + } + +#if defined (WIN32) + // Emulate Unix. Win32 does NOT support all the UNIX versions + // below, so DO we need this ifdef. + static const ACE_TCHAR *day_of_week_name[] = + { + ACE_TEXT ("Sun"), + ACE_TEXT ("Mon"), + ACE_TEXT ("Tue"), + ACE_TEXT ("Wed"), + ACE_TEXT ("Thu"), + ACE_TEXT ("Fri"), + ACE_TEXT ("Sat") + }; + + static const ACE_TCHAR *month_name[] = + { + ACE_TEXT ("Jan"), + ACE_TEXT ("Feb"), + ACE_TEXT ("Mar"), + ACE_TEXT ("Apr"), + ACE_TEXT ("May"), + ACE_TEXT ("Jun"), + ACE_TEXT ("Jul"), + ACE_TEXT ("Aug"), + ACE_TEXT ("Sep"), + ACE_TEXT ("Oct"), + ACE_TEXT ("Nov"), + ACE_TEXT ("Dec") + }; + + SYSTEMTIME local; + ::GetLocalTime (&local); + + ACE_OS::sprintf (date_and_time, + ACE_TEXT ("%3s %3s %2d %04d %02d:%02d:%02d.%06d"), + day_of_week_name[local.wDayOfWeek], + month_name[local.wMonth - 1], + (int) local.wDay, + (int) local.wYear, + (int) local.wHour, + (int) local.wMinute, + (int) local.wSecond, + (int) (local.wMilliseconds * 1000)); + return &date_and_time[15 + (return_pointer_to_first_digit != 0)]; +#else /* UNIX */ + ACE_TCHAR timebuf[26]; // This magic number is based on the ctime(3c) man page. + ACE_Time_Value cur_time = ACE_OS::gettimeofday (); + time_t secs = cur_time.sec (); + + ACE_OS::ctime_r (&secs, + timebuf, + sizeof timebuf / sizeof (ACE_TCHAR)); + // date_and_timelen > sizeof timebuf! + ACE_OS::strsncpy (date_and_time, + timebuf, + date_and_timelen); + ACE_TCHAR yeartmp[5]; + ACE_OS::strsncpy (yeartmp, + &date_and_time[20], + 5); + ACE_TCHAR timetmp[9]; + ACE_OS::strsncpy (timetmp, + &date_and_time[11], + 9); + ACE_OS::sprintf (&date_and_time[11], +# if defined (ACE_USES_WCHAR) + ACE_TEXT ("%ls %ls.%06ld"), +# else + ACE_TEXT ("%s %s.%06ld"), +# endif /* ACE_USES_WCHAR */ + yeartmp, + timetmp, + cur_time.usec ()); + date_and_time[33] = '\0'; + return &date_and_time[15 + (return_pointer_to_first_digit != 0)]; +#endif /* WIN32 */ +} + +// This function rounds the request to a multiple of the page size. + +size_t +ACE::round_to_pagesize (size_t len) +{ + ACE_TRACE ("ACE::round_to_pagesize"); + + if (ACE::pagesize_ == 0) + ACE::pagesize_ = ACE_OS::getpagesize (); + + return (len + (ACE::pagesize_ - 1)) & ~(ACE::pagesize_ - 1); +} + +size_t +ACE::round_to_allocation_granularity (size_t len) +{ + ACE_TRACE ("ACE::round_to_allocation_granularity"); + + if (ACE::allocation_granularity_ == 0) + ACE::allocation_granularity_ = ACE_OS::allocation_granularity (); + + return (len + (ACE::allocation_granularity_ - 1)) & ~(ACE::allocation_granularity_ - 1); +} + +ACE_HANDLE +ACE::handle_timed_complete (ACE_HANDLE h, + const ACE_Time_Value *timeout, + int is_tli) +{ + ACE_TRACE ("ACE::handle_timed_complete"); + +#if !defined (ACE_WIN32) && defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + + struct pollfd fds; + + fds.fd = h; + fds.events = POLLIN | POLLOUT; + fds.revents = 0; + +#else + ACE_Handle_Set rd_handles; + ACE_Handle_Set wr_handles; + + rd_handles.set_bit (h); + wr_handles.set_bit (h); +#endif /* !ACE_WIN32 && ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ + +#if defined (ACE_WIN32) + // Winsock is different - it sets the exception bit for failed connect, + // unlike other platforms, where the read bit is set. + ACE_Handle_Set ex_handles; + ex_handles.set_bit (h); +#endif /* ACE_WIN32 */ + + bool need_to_check = false; + bool known_failure = false; + +#if defined (ACE_WIN32) + int n = ACE_OS::select (0, // Ignored on Windows: int (h) + 1, + 0, + wr_handles, + ex_handles, + timeout); +#else +# if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + + int n = ACE_OS::poll (&fds, 1, timeout); + +# else + int n = ACE_OS::select (int (h) + 1, + rd_handles, + wr_handles, + 0, + timeout); +# endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ +#endif /* ACE_WIN32 */ + + // If we failed to connect within the time period allocated by the + // caller, then we fail (e.g., the remote host might have been too + // busy to accept our call). + if (n <= 0) + { + if (n == 0 && timeout != 0) + errno = ETIME; + return ACE_INVALID_HANDLE; + } + + // Usually, a ready-for-write handle is successfully connected, and + // ready-for-read (exception on Win32) is a failure. On fails, we + // need to grab the error code via getsockopt. On possible success for + // any platform where we can't tell just from select() (e.g. AIX), + // we also need to check for success/fail. +#if defined (ACE_WIN32) + ACE_UNUSED_ARG (is_tli); + + // On Win32, ex_handle set indicates a failure. We'll do the check + // to try and get an errno value, but the connect failed regardless of + // what getsockopt says about the error. + if (ex_handles.is_set (h)) + { + need_to_check = true; + known_failure = true; + } +#elif defined (ACE_VXWORKS) + ACE_UNUSED_ARG (is_tli); + + // Force the check on VxWorks. The read handle for "h" is not set, + // so "need_to_check" is false at this point. The write handle is + // set, for what it's worth. + need_to_check = true; +#else + if (is_tli) + +# if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + need_to_check = (fds.revents & POLLIN) && !(fds.revents & POLLOUT); +# else + need_to_check = rd_handles.is_set (h) && !wr_handles.is_set (h); +# endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ + + else +#if defined(AIX) + // AIX is broken... both success and failed connect will set the + // write handle only, so always check. + need_to_check = true; +#else +# if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + need_to_check = (fds.revents & POLLIN); +# else + need_to_check = rd_handles.is_set (h); +# endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ +#endif /* AIX */ +#endif /* ACE_WIN32 */ + + if (need_to_check) + { +#if defined (SOL_SOCKET) && defined (SO_ERROR) + int sock_err = 0; + int sock_err_len = sizeof (sock_err); + int sockopt_ret = ACE_OS::getsockopt (h, SOL_SOCKET, SO_ERROR, + (char *)&sock_err, &sock_err_len); + if (sockopt_ret < 0) + { + h = ACE_INVALID_HANDLE; + } + + if (sock_err != 0 || known_failure) + { + h = ACE_INVALID_HANDLE; + errno = sock_err; + } +#else + char dummy; + + // The following recv() won't block provided that the + // ACE_NONBLOCK flag has not been turned off . + n = ACE::recv (h, &dummy, 1, MSG_PEEK); + + // If no data was read/peeked at, check to see if it's because + // of a non-connected socket (and therefore an error) or there's + // just no data yet. + if (n <= 0) + { + if (n == 0) + { + errno = ECONNREFUSED; + h = ACE_INVALID_HANDLE; + } + else if (errno != EWOULDBLOCK && errno != EAGAIN) + h = ACE_INVALID_HANDLE; + } +#endif + } + + // 1. The HANDLE is ready for writing and doesn't need to be checked or + // 2. recv() returned an indication of the state of the socket - if there is + // either data present, or a recv is legit but there's no data yet, + // the connection was successfully established. + return h; +} + +// Wait up to amount of time to accept a connection. + +int +ACE::handle_timed_accept (ACE_HANDLE listener, + ACE_Time_Value *timeout, + int restart) +{ + ACE_TRACE ("ACE::handle_timed_accept"); + // Make sure we don't bomb out on erroneous values. + if (listener == ACE_INVALID_HANDLE) + return -1; + +#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + + struct pollfd fds; + + fds.fd = listener; + fds.events = POLLIN; + fds.revents = 0; + +#else + // Use the select() implementation rather than poll(). + ACE_Handle_Set rd_handle; + rd_handle.set_bit (listener); +#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ + + // We need a loop here if is enabled. + + for (;;) + { +#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT) + + int n = ACE_OS::poll (&fds, 1, timeout); + +#else + int select_width; +# if defined (ACE_WIN32) + // This arg is ignored on Windows and causes pointer truncation + // warnings on 64-bit compiles. + select_width = 0; +# else + select_width = int (listener) + 1; +# endif /* ACE_WIN32 */ + int n = ACE_OS::select (select_width, + rd_handle, 0, 0, + timeout); +#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */ + + switch (n) + { + case -1: + if (errno == EINTR && restart) + continue; + else + return -1; + /* NOTREACHED */ + case 0: + if (timeout != 0 + && timeout->sec () == 0 + && timeout->usec () == 0) + errno = EWOULDBLOCK; + else + errno = ETIMEDOUT; + return -1; + /* NOTREACHED */ + case 1: + return 0; + /* NOTREACHED */ + default: + errno = EINVAL; + return -1; + /* NOTREACHED */ + } + } +} + +// Make the current process a UNIX daemon. This is based on Stevens +// code from APUE. + +int +ACE::daemonize (const ACE_TCHAR pathname[], + bool close_all_handles, + const ACE_TCHAR program_name[]) +{ + ACE_TRACE ("ACE::daemonize"); +#if !defined (ACE_LACKS_FORK) + pid_t pid = ACE_OS::fork (); + + if (pid == -1) + return -1; + else if (pid != 0) + ACE_OS::exit (0); // Parent exits. + + // 1st child continues. + ACE_OS::setsid (); // Become session leader. + + ACE_OS::signal (SIGHUP, SIG_IGN); + + pid = ACE_OS::fork (program_name); + + if (pid != 0) + ACE_OS::exit (0); // First child terminates. + + // Second child continues. + + if (pathname != 0) + // change working directory. + ACE_OS::chdir (pathname); + + ACE_OS::umask (0); // clear our file mode creation mask. + + // Close down the I/O handles. + if (close_all_handles) + { + for (int i = ACE::max_handles () - 1; i >= 0; i--) + ACE_OS::close (i); + + int fd = ACE_OS::open ("/dev/null", O_RDWR, 0); + if (fd != -1) + { + ACE_OS::dup2 (fd, ACE_STDIN); + ACE_OS::dup2 (fd, ACE_STDOUT); + ACE_OS::dup2 (fd, ACE_STDERR); + + if (fd > ACE_STDERR) + ACE_OS::close (fd); + } + } + + return 0; +#else + ACE_UNUSED_ARG (pathname); + ACE_UNUSED_ARG (close_all_handles); + ACE_UNUSED_ARG (program_name); + + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_LACKS_FORK */ +} + +pid_t +ACE::fork (const ACE_TCHAR *program_name, + int avoid_zombies) +{ + if (avoid_zombies == 0) + return ACE_OS::fork (program_name); + else + { + // This algorithm is adapted from an example in the Stevens book + // "Advanced Programming in the Unix Environment" and an item in + // Andrew Gierth's Unix Programming FAQ. It creates an orphan + // process that's inherited by the init process; init cleans up + // when the orphan process terminates. + // + // Another way to avoid zombies is to ignore or catch the + // SIGCHLD signal; we don't use that approach here. + + pid_t pid = ACE_OS::fork (); + if (pid == 0) + { + // The child process forks again to create a grandchild. + switch (ACE_OS::fork (program_name)) + { + case 0: // grandchild returns 0. + return 0; + case -1: // assumes all errnos are < 256 + ACE_OS::_exit (errno); + default: // child terminates, orphaning grandchild + ACE_OS::_exit (0); + } + } + + // Parent process waits for child to terminate. + ACE_exitcode status; + if (pid < 0 || ACE_OS::waitpid (pid, &status, 0) < 0) + return -1; + + // child terminated by calling exit()? + if (WIFEXITED ((status))) + { + // child terminated normally? + if (WEXITSTATUS ((status)) == 0) + return 1; + else + errno = WEXITSTATUS ((status)); + } + else + // child didn't call exit(); perhaps it received a signal? + errno = EINTR; + + return -1; + } +} + +int +ACE::max_handles (void) +{ + ACE_TRACE ("ACE::max_handles"); +#if defined (RLIMIT_NOFILE) && !defined (ACE_LACKS_RLIMIT) + rlimit rl; + int const r = ACE_OS::getrlimit (RLIMIT_NOFILE, &rl); +# if !defined (RLIM_INFINITY) + if (r == 0) + return rl.rlim_cur; +# else + if (r == 0 && rl.rlim_cur != RLIM_INFINITY) + return rl.rlim_cur; + // If == RLIM_INFINITY, fall through to the ACE_LACKS_RLIMIT sections +# endif /* RLIM_INFINITY */ +#endif /* RLIMIT_NOFILE && !ACE_LACKS_RLIMIT */ + +#if defined (_SC_OPEN_MAX) + return ACE_OS::sysconf (_SC_OPEN_MAX); +#elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) + return maxFiles; +#elif defined (FD_SETSIZE) + return FD_SETSIZE; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* _SC_OPEN_MAX */ +} + +// Set the number of currently open handles in the process. +// +// If NEW_LIMIT == -1 set the limit to the maximum allowable. +// Otherwise, set it to be the value of NEW_LIMIT. + +int +ACE::set_handle_limit (int new_limit, + int increase_limit_only) +{ + ACE_TRACE ("ACE::set_handle_limit"); + int cur_limit = ACE::max_handles (); + int max_limit = cur_limit; + + if (cur_limit == -1) + return -1; + +#if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE) + struct rlimit rl; + + ACE_OS::memset ((void *) &rl, 0, sizeof rl); + int r = ACE_OS::getrlimit (RLIMIT_NOFILE, &rl); + if (r == 0) + max_limit = rl.rlim_max; +#endif /* ACE_LACKS_RLIMIT */ + + if (new_limit == -1) + new_limit = max_limit; + + if (new_limit < 0) + { + errno = EINVAL; + return -1; + } + else if (new_limit > cur_limit) + { + // Increase the limit. +#if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE) + rl.rlim_cur = new_limit; + return ACE_OS::setrlimit (RLIMIT_NOFILE, &rl); +#elif defined (ACE_LACKS_RLIMIT_NOFILE) + return 0; +#else + // Must return EINVAL errno. + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_LACKS_RLIMIT */ + } + else if (increase_limit_only == 0) + { + // Decrease the limit. +#if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE) + rl.rlim_cur = new_limit; + return ACE_OS::setrlimit (RLIMIT_NOFILE, &rl); +#else + // We give a chance to platforms without RLIMIT to work. + // Instead of ACE_NOTSUP_RETURN (0), just return 0 because + // new_limit is <= cur_limit, so it's a no-op. + return 0; +#endif /* ACE_LACKS_RLIMIT */ + } + + return 0; +} + +// Euclid's greatest common divisor algorithm. +u_long +ACE::gcd (u_long x, u_long y) +{ + while (y != 0) + { + u_long r = x % y; + x = y; + y = r; + } + + return x; +} + + +// Calculates the minimum enclosing frame size for the given values. +u_long +ACE::minimum_frame_size (u_long period1, u_long period2) +{ + // if one of the periods is zero, treat it as though it as + // uninitialized and return the other period as the frame size + if (0 == period1) + { + return period2; + } + if (0 == period2) + { + return period1; + } + + // if neither is zero, find the greatest common divisor of the two periods + u_long greatest_common_divisor = ACE::gcd (period1, period2); + + // explicitly consider cases to reduce risk of possible overflow errors + if (greatest_common_divisor == 1) + { + // periods are relative primes: just multiply them together + return period1 * period2; + } + else if (greatest_common_divisor == period1) + { + // the first period divides the second: return the second + return period2; + } + else if (greatest_common_divisor == period2) + { + // the second period divides the first: return the first + return period1; + } + else + { + // the current frame size and the entry's effective period + // have a non-trivial greatest common divisor: return the + // product of factors divided by those in their gcd. + return (period1 * period2) / greatest_common_divisor; + } +} + + +u_long +ACE::is_prime (const u_long n, + const u_long min_factor, + const u_long max_factor) +{ + if (n > 3) + for (u_long factor = min_factor; + factor <= max_factor; + ++factor) + if (n / factor * factor == n) + return factor; + + return 0; +} + +const ACE_TCHAR * +ACE::sock_error (int error) +{ +#if defined (ACE_WIN32) + static ACE_TCHAR unknown_msg[64]; + + switch (error) + { + case WSAVERNOTSUPPORTED: + return ACE_TEXT ("version of WinSock not supported"); + /* NOTREACHED */ + case WSASYSNOTREADY: + return ACE_TEXT ("WinSock not present or not responding"); + /* NOTREACHED */ + case WSAEINVAL: + return ACE_TEXT ("app version not supported by DLL"); + /* NOTREACHED */ + case WSAHOST_NOT_FOUND: + return ACE_TEXT ("Authoritive: Host not found"); + /* NOTREACHED */ + case WSATRY_AGAIN: + return ACE_TEXT ("Non-authoritive: host not found or server failure"); + /* NOTREACHED */ + case WSANO_RECOVERY: + return ACE_TEXT ("Non-recoverable: refused or not implemented"); + /* NOTREACHED */ + case WSANO_DATA: + return ACE_TEXT ("Valid name, no data record for type"); + /* NOTREACHED */ + /* + case WSANO_ADDRESS: + return "Valid name, no MX record"; + */ + case WSANOTINITIALISED: + return ACE_TEXT ("WSA Startup not initialized"); + /* NOTREACHED */ + case WSAENETDOWN: + return ACE_TEXT ("Network subsystem failed"); + /* NOTREACHED */ + case WSAEINPROGRESS: + return ACE_TEXT ("Blocking operation in progress"); + /* NOTREACHED */ + case WSAEINTR: + return ACE_TEXT ("Blocking call cancelled"); + /* NOTREACHED */ + case WSAEAFNOSUPPORT: + return ACE_TEXT ("address family not supported"); + /* NOTREACHED */ + case WSAEMFILE: + return ACE_TEXT ("no file handles available"); + /* NOTREACHED */ + case WSAENOBUFS: + return ACE_TEXT ("no buffer space available"); + /* NOTREACHED */ + case WSAEPROTONOSUPPORT: + return ACE_TEXT ("specified protocol not supported"); + /* NOTREACHED */ + case WSAEPROTOTYPE: + return ACE_TEXT ("protocol wrong type for this socket"); + /* NOTREACHED */ + case WSAESOCKTNOSUPPORT: + return ACE_TEXT ("socket type not supported for address family"); + /* NOTREACHED */ + case WSAENOTSOCK: + return ACE_TEXT ("handle is not a socket"); + /* NOTREACHED */ + case WSAEWOULDBLOCK: + return ACE_TEXT ("resource temporarily unavailable"); + /* NOTREACHED */ + case WSAEADDRINUSE: + return ACE_TEXT ("address already in use"); + /* NOTREACHED */ + case WSAECONNABORTED: + return ACE_TEXT ("connection aborted"); + /* NOTREACHED */ + case WSAECONNRESET: + return ACE_TEXT ("connection reset"); + /* NOTREACHED */ + case WSAENOTCONN: + return ACE_TEXT ("not connected"); + /* NOTREACHED */ + case WSAETIMEDOUT: + return ACE_TEXT ("connection timed out"); + /* NOTREACHED */ + case WSAECONNREFUSED: + return ACE_TEXT ("connection refused"); + /* NOTREACHED */ + case WSAEHOSTDOWN: + return ACE_TEXT ("host down"); + /* NOTREACHED */ + case WSAEHOSTUNREACH: + return ACE_TEXT ("host unreachable"); + /* NOTREACHED */ + case WSAEADDRNOTAVAIL: + return ACE_TEXT ("address not available"); + /* NOTREACHED */ + case WSAEISCONN: + return ACE_TEXT ("socket is already connected"); + /* NOTREACHED */ + case WSAENETRESET: + return ACE_TEXT ("network dropped connection on reset"); + /* NOTREACHED */ + case WSAEMSGSIZE: + return ACE_TEXT ("message too long"); + /* NOTREACHED */ + case WSAENETUNREACH: + return ACE_TEXT ("network is unreachable"); + /* NOTREACHED */ + case WSAEFAULT: + return ACE_TEXT ("bad address"); + /* NOTREACHED */ + case WSAEDISCON: + return ACE_TEXT ("graceful shutdown in progress"); + /* NOTREACHED */ + case WSAEACCES: + return ACE_TEXT ("permission denied"); + /* NOTREACHED */ + case WSAESHUTDOWN: + return ACE_TEXT ("cannot send after socket shutdown"); + /* NOTREACHED */ + case WSAEPROCLIM: + return ACE_TEXT ("too many processes"); + /* NOTREACHED */ + case WSAEALREADY: + return ACE_TEXT ("operation already in progress"); + /* NOTREACHED */ + case WSAEPFNOSUPPORT: + return ACE_TEXT ("protocol family not supported"); + /* NOTREACHED */ + case WSAENOPROTOOPT: + return ACE_TEXT ("bad protocol option"); + /* NOTREACHED */ + case WSATYPE_NOT_FOUND: + return ACE_TEXT ("class type not found"); + /* NOTREACHED */ + case WSAEOPNOTSUPP: + return ACE_TEXT ("operation not supported"); + /* NOTREACHED */ + case WSAEDESTADDRREQ: + return ACE_TEXT ("destination address required"); + /* NOTREACHED */ + default: + ACE_OS::sprintf (unknown_msg, ACE_TEXT ("unknown error: %d"), error); + return unknown_msg; + /* NOTREACHED */ + } +#else + ACE_UNUSED_ARG (error); + ACE_NOTSUP_RETURN (0); +#endif /* ACE_WIN32 */ +} + +bool +ACE::is_sock_error (int error) +{ +#if defined (ACE_WIN32) + switch (error) + { + case WSAVERNOTSUPPORTED: + case WSASYSNOTREADY: + case WSAEINVAL: + case WSAHOST_NOT_FOUND: + case WSATRY_AGAIN: + case WSANO_RECOVERY: + case WSANO_DATA: + /* + case WSANO_ADDRESS: + */ + case WSANOTINITIALISED: + case WSAENETDOWN: + case WSAEINPROGRESS: + case WSAEINTR: + case WSAEAFNOSUPPORT: + case WSAEMFILE: + case WSAENOBUFS: + case WSAEPROTONOSUPPORT: + case WSAEPROTOTYPE: + case WSAESOCKTNOSUPPORT: + case WSAENOTSOCK: + case WSAEWOULDBLOCK: + case WSAEADDRINUSE: + case WSAECONNABORTED: + case WSAECONNRESET: + case WSAENOTCONN: + case WSAETIMEDOUT: + case WSAECONNREFUSED: + case WSAEHOSTDOWN: + case WSAEHOSTUNREACH: + case WSAEADDRNOTAVAIL: + case WSAEISCONN: + case WSAENETRESET: + case WSAEMSGSIZE: + case WSAENETUNREACH: + case WSAEFAULT: + case WSAEDISCON: + case WSAEACCES: + case WSAESHUTDOWN: + case WSAEPROCLIM: + case WSAEALREADY: + case WSAEPFNOSUPPORT: + case WSAENOPROTOOPT: + case WSATYPE_NOT_FOUND: + case WSAEOPNOTSUPP: + return true; + } +#else + ACE_UNUSED_ARG (error); +#endif /* ACE_WIN32 */ + return false; +} + +char * +ACE::strndup (const char *str, size_t n) +{ + const char *t = str; + size_t len; + + // Figure out how long this string is (remember, it might not be + // NUL-terminated). + + for (len = 0; + len < n && *t++ != '\0'; + len++) + continue; + + char *s; + ACE_ALLOCATOR_RETURN (s, + (char *) ACE_OS::malloc (len + 1), + 0); + return ACE_OS::strsncpy (s, str, len + 1); +} + +#if defined (ACE_HAS_WCHAR) +wchar_t * +ACE::strndup (const wchar_t *str, size_t n) +{ + const wchar_t *t = str; + size_t len; + + // Figure out how long this string is (remember, it might not be + // NUL-terminated). + + for (len = 0; + len < n && *t++ != '\0'; + len++) + continue; + + wchar_t *s; + ACE_ALLOCATOR_RETURN (s, + static_cast ( + ACE_OS::malloc ((len + 1) * sizeof (wchar_t))), + 0); + return ACE_OS::strsncpy (s, str, len + 1); +} +#endif /* ACE_HAS_WCHAR */ + +char * +ACE::strnnew (const char *str, size_t n) +{ + const char *t = str; + size_t len; + + // Figure out how long this string is (remember, it might not be + // NUL-terminated). + + for (len = 0; + len < n && *t++ != L'\0'; + len++) + continue; + + char *s; + ACE_NEW_RETURN (s, + char[len + 1], + 0); + return ACE_OS::strsncpy (s, str, len + 1); +} + +#if defined (ACE_HAS_WCHAR) +wchar_t * +ACE::strnnew (const wchar_t *str, size_t n) +{ + const wchar_t *t = str; + size_t len; + + // Figure out how long this string is (remember, it might not be + // NUL-terminated). + + for (len = 0; + len < n && *t++ != ACE_TEXT_WIDE ('\0'); + len++) + continue; + + wchar_t *s; + ACE_NEW_RETURN (s, + wchar_t[len + 1], + 0); + return ACE_OS::strsncpy (s, str, len + 1); +} +#endif /* ACE_HAS_WCHAR */ + +const char * +ACE::strend (const char *s) +{ + while (*s++ != '\0') + continue; + + return s; +} + +#if defined ACE_HAS_WCHAR +const wchar_t * +ACE::strend (const wchar_t *s) +{ + while (*s++ != ACE_TEXT_WIDE ('\0')) + continue; + + return s; +} +#endif + +char * +ACE::strnew (const char *s) +{ + if (s == 0) + return 0; + char *t = 0; + ACE_NEW_RETURN (t, + char [ACE_OS::strlen (s) + 1], + 0); + if (t == 0) + return 0; + else + return ACE_OS::strcpy (t, s); +} + +#if defined (ACE_HAS_WCHAR) +wchar_t * +ACE::strnew (const wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *t = 0; + ACE_NEW_RETURN (t, + wchar_t[ACE_OS::strlen (s) + 1], + 0); + if (t == 0) + return 0; + else + return ACE_OS::strcpy (t, s); +} +#endif /* ACE_HAS_WCHAR */ + +inline static bool equal_char(char a, char b, bool case_sensitive) +{ + if (case_sensitive) + return a == b; + return ACE_OS::ace_tolower(a) == ACE_OS::ace_tolower(b); +} + +bool +ACE::wild_match(const char* str, const char* pat, bool case_sensitive) +{ + if (str == pat) + return true; + if (pat == 0 || str == 0) + return false; + + bool star = false; + const char* s = str; + const char* p = pat; + while (*s != '\0') + { + if (*p == '*') + { + star = true; + pat = p; + while (*++pat == '*') {} + + if (*pat == '\0') + return true; + p = pat; + } + else if (*p == '?') + { + ++s; + ++p; + } + else if (! equal_char(*s, *p, case_sensitive)) + { + if (!star) + return false; + s = ++str; + p = pat; + } + else + { + ++s; + ++p; + } + } + if (*p == '*') + while (*++p == '*') {} + + return *p == '\0'; +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ACE.h b/dep/ACE_wrappers/ace/ACE.h new file mode 100644 index 000000000..654bbb323 --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE.h @@ -0,0 +1,824 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file ACE.h + * + * $Id: ACE.h 82581 2008-08-11 08:58:24Z johnnyw $ + * + * This file contains value added ACE functions that extend the + * behavior of the UNIX and Win32 OS calls. + * + * All these ACE static functions are consolidated in a single place + * in order to manage the namespace better. These functions are put + * here rather than in @c ACE_OS in order to separate concerns. + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ACE_H +#define ACE_ACE_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_math.h" +#include "ace/Flag_Manip.h" +#include "ace/Handle_Ops.h" +#include "ace/Lib_Find.h" +#include "ace/Init_ACE.h" +#include "ace/Sock_Connect.h" +#include "ace/Default_Constants.h" + +#if defined (ACE_EXPORT_MACRO) +# undef ACE_EXPORT_MACRO +#endif +#define ACE_EXPORT_MACRO ACE_Export + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations. +class ACE_Time_Value; +class ACE_Message_Block; +class ACE_Handle_Set; + +/** + * @namespace ACE + * + * @brief The namespace containing the ACE framework itself. + * + * The ACE namespace contains all types (classes, structures, + * typedefs, etc), and global functions and variables in the ACE + * framework. + */ +namespace ACE +{ + // = ACE version information. + /// e.g., the "5" in ACE 5.1.12. + extern ACE_Export u_int major_version (void); + + /// e.g., the "1" in ACE 5.1.12. + extern ACE_Export u_int minor_version (void); + + /// e.g., the "12" in ACE 5.1.12. + /// Returns 0 for "stable" (non-beta) releases. + extern ACE_Export u_int beta_version (void); + + // = C++ compiler version information. + /// E.g., the "SunPro C++" in SunPro C++ 4.32.0 + extern ACE_Export const ACE_TCHAR * compiler_name (void); + + /// E.g., the "4" in SunPro C++ 4.32.0 + extern ACE_Export u_int compiler_major_version (void); + + /// E.g., the "32" in SunPro C++ 4.32.0 + extern ACE_Export u_int compiler_minor_version (void); + + /// E.g., the "0" in SunPro C++ 4.32.0 + extern ACE_Export u_int compiler_beta_version (void); + + /// Check if error indicates the process being out of handles (file + /// descriptors). + extern ACE_Export int out_of_handles (int error); + + /// Simple wildcard matching function supporting '*' and '?' + /// return true if string s matches pattern. + extern ACE_Export bool wild_match(const char* s, const char* pattern, bool case_sensitive = true); + + /** + * @name I/O operations + * + * Notes on common parameters: + * + * @a handle is the connected endpoint that will be used for I/O. + * + * @a buf is the buffer to write from or receive into. + * + * @a len is the number of bytes to transfer. + * + * The @a timeout parameter in the following methods indicates how + * long to blocking trying to transfer data. If @a timeout == 0, + * then the call behaves as a normal send/recv call, i.e., for + * blocking sockets, the call will block until action is possible; + * for non-blocking sockets, @c EWOULDBLOCK will be returned if no + * action is immediately possible. + * + * If @a timeout != 0, the call will wait until the relative time + * specified in @a *timeout elapses. + * + * The "_n()" I/O methods keep looping until all the data has been + * transferred. These methods also work for sockets in non-blocking + * mode i.e., they keep looping on @c EWOULDBLOCK. @a timeout is + * used to make sure we keep making progress, i.e., the same timeout + * value is used for every I/O operation in the loop and the timeout + * is not counted down. + * + * The return values for the "*_n()" methods match the return values + * from the non "_n()" methods and are specified as follows: + * + * - On complete transfer, the number of bytes transferred is returned. + * - On timeout, -1 is returned, @c errno == @c ETIME. + * - On error, -1 is returned, @c errno is set to appropriate error. + * - On @c EOF, 0 is returned, @c errno is irrelevant. + * + * On partial transfers, i.e., if any data is transferred before + * timeout / error / @c EOF, @a bytes_transferred> will contain the + * number of bytes transferred. + * + * Methods with @a iovec parameter are I/O vector variants of the + * I/O operations. + * + * Methods with the extra @a flags argument will always result in + * @c send getting called. Methods without the extra @a flags + * argument will result in @c send getting called on Win32 + * platforms, and @c write getting called on non-Win32 platforms. + */ + //@{ + extern ACE_Export ssize_t recv (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout = 0); + +#if defined (ACE_HAS_TLI) + + extern ACE_Export ssize_t t_rcv (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + const ACE_Time_Value *timeout = 0); + +#endif /* ACE_HAS_TLI */ + + extern ACE_Export ssize_t recv (ACE_HANDLE handle, + void *buf, + size_t len, + const ACE_Time_Value *timeout = 0); + + extern ACE_Export ssize_t recvmsg (ACE_HANDLE handle, + struct msghdr *msg, + int flags, + const ACE_Time_Value *timeout = 0); + + extern ACE_Export ssize_t recvfrom (ACE_HANDLE handle, + char *buf, + int len, + int flags, + struct sockaddr *addr, + int *addrlen, + const ACE_Time_Value *timeout = 0); + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t recv_n (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + +#if defined (ACE_HAS_TLI) + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t t_rcv_n (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + +#endif /* ACE_HAS_TLI */ + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t recv_n (ACE_HANDLE handle, + void *buf, + size_t len, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + /// Receive into a variable number of pieces. + /** + * Accepts a variable, caller-specified, number of pointer/length + * pairs. Arguments following @a n are char *, size_t pairs. + * + * @param handle The I/O handle to receive on + * @param n The total number of char *, size_t pairs following @a n. + * + * @return -1 on error, else total number of bytes received. + */ + extern ACE_Export ssize_t recv (ACE_HANDLE handle, size_t n, ...); + + extern ACE_Export ssize_t recvv (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout = 0); + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t recvv_n (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + extern ACE_Export ssize_t recv_n (ACE_HANDLE handle, + ACE_Message_Block *message_block, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + extern ACE_Export ssize_t send (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout = 0); + +#if defined (ACE_HAS_TLI) + + extern ACE_Export ssize_t t_snd (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout = 0); + +#endif /* ACE_HAS_TLI */ + + extern ACE_Export ssize_t send (ACE_HANDLE handle, + const void *buf, + size_t len, + const ACE_Time_Value *timeout = 0); + + extern ACE_Export ssize_t sendmsg (ACE_HANDLE handle, + const struct msghdr *msg, + int flags, + const ACE_Time_Value *timeout = 0); + + extern ACE_Export ssize_t sendto (ACE_HANDLE handle, + const char *buf, + int len, + int flags, + const struct sockaddr *addr, + int addrlen, + const ACE_Time_Value *timeout = 0); + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t send_n (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + +#if defined (ACE_HAS_TLI) + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t t_snd_n (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + +#endif /* ACE_HAS_TLI */ + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t send_n (ACE_HANDLE handle, + const void *buf, + size_t len, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + /// Varargs variant. + extern ACE_Export ssize_t send (ACE_HANDLE handle, size_t n, ...); + + extern ACE_Export ssize_t sendv (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout = 0); + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t sendv_n (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + /// Send all the @a message_blocks chained through their @c next and + /// @c cont pointers. This call uses the underlying OS gather-write + /// operation to reduce the domain-crossing penalty. + extern ACE_Export ssize_t send_n (ACE_HANDLE handle, + const ACE_Message_Block *message_block, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + // = File system I/O functions (these don't support timeouts). + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t read_n (ACE_HANDLE handle, + void *buf, + size_t len, + size_t *bytes_transferred = 0); + + ACE_NAMESPACE_INLINE_FUNCTION + ssize_t write_n (ACE_HANDLE handle, + const void *buf, + size_t len, + size_t *bytes_transferred = 0); + + /// Write all the @a message_blocks chained through their @c next + /// and @c cont pointers. This call uses the underlying OS + /// gather-write operation to reduce the domain-crossing penalty. + extern ACE_Export ssize_t write_n (ACE_HANDLE handle, + const ACE_Message_Block *message_block, + size_t *bytes_transferred = 0); + + extern ACE_Export ssize_t readv_n (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + size_t *bytes_transferred = 0); + + extern ACE_Export ssize_t writev_n (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + size_t *bytes_transferred = 0); + //@} + + /** + * Wait up to @a timeout amount of time to passively establish a + * connection. This method doesn't perform the @c accept, it just + * does the timed wait. + */ + extern ACE_Export int handle_timed_accept (ACE_HANDLE listener, + ACE_Time_Value *timeout, + int restart); + + /** + * Wait up to @a timeout amount of time to complete an actively + * established non-blocking connection. If @a is_tli is non-0 then + * we are being called by a TLI wrapper (which behaves slightly + * differently from a socket wrapper). + */ + extern ACE_Export ACE_HANDLE handle_timed_complete ( + ACE_HANDLE listener, + const ACE_Time_Value *timeout, + int is_tli = 0); + + /** + * Reset the limit on the number of open handles. If @a new_limit + * == -1 set the limit to the maximum allowable. Otherwise, set + * the limit value to @a new_limit. If @a increase_limit_only is + * non-0 then only allow increases to the limit. + */ + extern ACE_Export int set_handle_limit (int new_limit = -1, + int increase_limit_only = 0); + + /** + * Returns the maximum number of open handles currently permitted in + * this process. This maximum may be extended using + * @c ACE::set_handle_limit. + */ + extern ACE_Export int max_handles (void); + + // = String functions +#if !defined (ACE_HAS_WINCE) + /** + * Return a dynamically allocated duplicate of @a str, substituting + * the environment variable if @c str[0] @c == @c '$'. Note that + * the pointer is allocated with @c ACE_OS::malloc and must be freed + * by @c ACE_OS::free. + */ + extern ACE_Export ACE_TCHAR *strenvdup (const ACE_TCHAR *str); +#endif /* ACE_HAS_WINCE */ + + /// Returns a pointer to the "end" of the string, i.e., the character + /// past the '\0'. + extern ACE_Export const char *strend (const char *s); + + /// This method is just like @c strdup, except that it uses + /// @c operator @c new rather than @c malloc. If @a s is NULL + /// returns NULL rather than segfaulting. + extern ACE_Export char *strnew (const char *s); + + /// Delete the memory allocated by @c strnew. + ACE_NAMESPACE_INLINE_FUNCTION void strdelete (char *s); + + /// Create a fresh new copy of @a str, up to @a n chars long. Uses + /// @c ACE_OS::malloc to allocate the new string. + extern ACE_Export char *strndup (const char *str, size_t n); + + /// Create a fresh new copy of @a str, up to @a n chars long. Uses + /// @c ACE_OS::malloc to allocate the new string. + extern ACE_Export char *strnnew (const char *str, size_t n); + +#if defined (ACE_HAS_WCHAR) + extern ACE_Export const wchar_t *strend (const wchar_t *s); + + extern ACE_Export wchar_t *strnew (const wchar_t *s); + + ACE_NAMESPACE_INLINE_FUNCTION void strdelete (wchar_t *s); + + extern ACE_Export wchar_t *strndup (const wchar_t *str, size_t n); + + extern ACE_Export wchar_t *strnnew (const wchar_t *str, size_t n); + +#endif /* ACE_HAS_WCHAR */ + + /** + * On Windows, determines if a specified pathname ends with ".exe" + * (not case sensitive). If on Windows and there is no ".exe" suffix, + * a new ACE_TCHAR array is allocated and a copy of @c pathname with + * the ".exe" suffix is copied into it. In this case, the caller is + * responsible for calling delete [] on the returned pointer. + * + * @param pathname The name to check for a proper suffix. + * + * @retval @c pathname if there is a proper suffix for Windows. This is + * always the return value for non-Windows platforms. + * @retval If a suffix needs to be added, returns a pointer to new[] + * allocated memory containing the original @c pathname plus + * a ".exe" suffix. The caller is responsible for freeing the + * memory using delete []. + */ + extern ACE_Export const ACE_TCHAR *execname (const ACE_TCHAR *pathname); + + /** + * Returns the "basename" of a @a pathname separated by @a delim. + * For instance, the basename of "/tmp/foo.cpp" is "foo.cpp" when + * @a delim is @a '/'. + */ + extern ACE_Export const ACE_TCHAR *basename (const ACE_TCHAR *pathname, + ACE_TCHAR delim = + ACE_DIRECTORY_SEPARATOR_CHAR); + + /** + * Returns the "dirname" of a @a pathname. For instance, the + * dirname of "/tmp/foo.cpp" is "/tmp" when @a delim is @a '/'. If + * @a pathname has no @a delim ".\0" is returned. This method does + * not modify @a pathname and is not reentrant. + */ + extern ACE_Export const ACE_TCHAR *dirname (const ACE_TCHAR *pathname, + ACE_TCHAR delim = + ACE_DIRECTORY_SEPARATOR_CHAR); + + /** + * Returns the current timestamp in the form + * "hour:minute:second:microsecond." The month, day, and year are + * also stored in the beginning of the @a date_and_time array, which + * is a user-supplied array of size @a time_len> @c ACE_TCHARs. + * Returns 0 if unsuccessful, else returns pointer to beginning of the + * "time" portion of @a date_and_time. If @a + * return_pointer_to_first_digit is 0 then return a pointer to the + * space before the time, else return a pointer to the beginning of + * the time portion. + */ + extern ACE_Export ACE_TCHAR *timestamp (ACE_TCHAR date_and_time[], + size_t time_len, + bool return_pointer_to_first_digit = false); + + /** + * if @a avoid_zombies == 0 call @c ACE_OS::fork directly, else + * create an orphan process that's inherited by the init process; + * init cleans up when the orphan process terminates so we don't + * create zombies. Returns -1 on failure and either the child PID + * on success if @a avoid_zombies == 0 or 1 on success if @a + * avoid_zombies != 0 (this latter behavior is a known bug that + * needs to be fixed). + */ + extern ACE_Export pid_t fork ( + const ACE_TCHAR *program_name = ACE_TEXT (""), + int avoid_zombies = 0); + + /** + * Become a daemon process using the algorithm in Richard Stevens + * "Advanced Programming in the UNIX Environment." If + * @a close_all_handles is non-zero then all open file handles are + * closed. + */ + extern ACE_Export int daemonize ( + const ACE_TCHAR pathname[] = ACE_TEXT ("/"), + bool close_all_handles = ACE_DEFAULT_CLOSE_ALL_HANDLES, + const ACE_TCHAR program_name[] = ACE_TEXT ("")); + + // = Miscellaneous functions. + /// Rounds the request to a multiple of the page size. + extern ACE_Export size_t round_to_pagesize (size_t len); + + /// Rounds the request to a multiple of the allocation granularity. + extern ACE_Export size_t round_to_allocation_granularity (size_t len); + + // @@ UNICODE what about buffer? + /// Format buffer into printable format. This is useful for + /// debugging. + extern ACE_Export size_t format_hexdump (const char *buffer, size_t size, + ACE_TCHAR *obuf, size_t obuf_sz); + + /// Computes the hash value of {str} using the "Hash PJW" routine. + extern ACE_Export u_long hash_pjw (const char *str); + + /// Computes the hash value of {str} using the "Hash PJW" routine. + extern ACE_Export u_long hash_pjw (const char *str, size_t len); + +#if defined (ACE_HAS_WCHAR) + /// Computes the hash value of {str} using the "Hash PJW" routine. + extern ACE_Export u_long hash_pjw (const wchar_t *str); + + /// Computes the hash value of {str} using the "Hash PJW" routine. + extern ACE_Export u_long hash_pjw (const wchar_t *str, size_t len); +#endif /* ACE_HAS_WCHAR */ + + /// Computes CRC-CCITT for the string. + extern ACE_Export ACE_UINT16 crc_ccitt(const char *str); + + /// Computes CRC-CCITT for the buffer. + extern ACE_Export ACE_UINT16 crc_ccitt(const void *buf, size_t len, + ACE_UINT16 crc = 0); + + /// Computes CRC-CCITT for the @ len iovec buffers. + extern ACE_Export ACE_UINT16 crc_ccitt(const iovec *iov, int len, + ACE_UINT16 crc = 0); + + /// Computes the ISO 8802-3 standard 32 bits CRC for the string. + extern ACE_Export ACE_UINT32 crc32 (const char *str); + + /// Computes the ISO 8802-3 standard 32 bits CRC for the buffer. + extern ACE_Export ACE_UINT32 crc32 (const void *buf, size_t len, + ACE_UINT32 crc = 0); + + /// Computes the ISO 8802-3 standard 32 bits CRC for the + /// @ len iovec buffers. + extern ACE_Export ACE_UINT32 crc32 (const iovec *iov, int len, + ACE_UINT32 crc = 0); + + /// Euclid's greatest common divisor algorithm. + extern ACE_Export u_long gcd (u_long x, u_long y); + + /// Calculates the minimum enclosing frame size for the given values. + extern ACE_Export u_long minimum_frame_size (u_long period1, u_long period2); + + /** + * Function that can burn up noticeable CPU time: brute-force + * determination of whether number @a n is prime. Returns 0 if + * it is prime, or the smallest factor if it is not prime. + * @a min_factor and @a max_factor can be used to partition the work + * among threads. For just one thread, typical values are 2 and + * n/2. + */ + extern ACE_Export u_long is_prime (const u_long n, + const u_long min_factor, + const u_long max_factor); + + /// Map troublesome win32 errno values to values that standard C + /// strerr function understands. Thank you Microsoft. + extern ACE_Export int map_errno (int error); + + /// Returns a string containing the error message corresponding to a + /// WinSock error. This works around an omission in the Win32 API. + /// @internal + extern ACE_Export const ACE_TCHAR * sock_error (int error); + + /// Determins whether the given error code corresponds to to a + /// WinSock error. If so returns true, false otherwise. + /// @internal + extern ACE_Export bool is_sock_error (int error); + + /** + * Checks if process with {pid} is still alive. Returns 1 if it is + * still alive, 0 if it isn't alive, and -1 if something weird + * happened. + */ + extern ACE_Export int process_active (pid_t pid); + + /** + * Terminate the process abruptly with id @a pid. On Win32 platforms + * this uses {TerminateProcess} and on POSIX platforms is uses + * {kill} with the -9 (SIGKILL) signal, which cannot be caught or + * ignored. Note that this call is potentially dangerous to use + * since the process being terminated may not have a chance to + * cleanup before it shuts down. + */ + extern ACE_Export int terminate_process (pid_t pid); + + /** + * This method uses process id and object pointer to come up with a + * machine wide unique name. The process ID will provide uniqueness + * between processes on the same machine. The "this" pointer of the + * {object} will provide uniqueness between other "live" objects in + * the same process. The uniqueness of this name is therefore only + * valid for the life of {object}. + */ + ACE_NAMESPACE_INLINE_FUNCTION void unique_name (const void *object, + ACE_TCHAR *name, + size_t length); + + /// Computes the base 2 logarithm of {num}. + ACE_NAMESPACE_INLINE_FUNCTION u_long log2 (u_long num); + + /// Hex conversion utility. + ACE_NAMESPACE_INLINE_FUNCTION ACE_TCHAR nibble2hex (u_int n); + + /// Convert a hex character to its byte representation. + ACE_NAMESPACE_INLINE_FUNCTION u_char hex2byte (ACE_TCHAR c); + + // = Set/get the debug level. + extern ACE_Export bool debug (void); + extern ACE_Export void debug (bool onoff); + + /// Wrapper facade for @c select that uses @c ACE_Handle_Sets. + extern ACE_Export int select (int width, + ACE_Handle_Set *readfds, + ACE_Handle_Set *writefds = 0, + ACE_Handle_Set *exceptfds = 0, + const ACE_Time_Value *timeout = 0); + + /// Wrapper facade for the most common use of @c select that uses + /// @c ACE_Handle_Sets. + extern ACE_Export int select (int width, + ACE_Handle_Set &readfds, + const ACE_Time_Value *timeout = 0); + + /// Timed wait for handle to get read ready. + ACE_NAMESPACE_INLINE_FUNCTION + int handle_read_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout); + + /// Timed wait for handle to get write ready. + ACE_NAMESPACE_INLINE_FUNCTION + int handle_write_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout); + + /// Timed wait for handle to get exception ready. + ACE_NAMESPACE_INLINE_FUNCTION + int handle_exception_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout); + + /// Timed wait for handle to get read, write, or exception ready. + extern ACE_Export int handle_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout, + int read_ready, + int write_ready, + int exception_ready); + + /// Wait for @a timeout before proceeding to a @c recv operation. + /// @a val keeps track of whether we're in non-blocking mode or + /// not. + extern ACE_Export int enter_recv_timedwait (ACE_HANDLE handle, + const ACE_Time_Value *timeout, + int &val); + + /// Wait for @a timeout before proceeding to a @c send operation. + /// @a val keeps track of whether we're in non-blocking mode or + /// not. + extern ACE_Export int enter_send_timedwait (ACE_HANDLE handle, + const ACE_Time_Value* timeout, + int &val); + + /// This makes sure that @a handle is set into non-blocking mode. + /// @a val keeps track of whether were in non-blocking mode or not. + extern ACE_Export void record_and_set_non_blocking_mode (ACE_HANDLE handle, + int &val); + + /// Cleanup after a timed operation, restore the appropriate + /// non-blocking status of @a handle. + extern ACE_Export void restore_non_blocking_mode (ACE_HANDLE handle, + int val); + + // private: + // These functions aren't meant to be used internally, so they are + // not exported. + + // + // = Recv_n helpers + // + + ACE_NAMESPACE_INLINE_FUNCTION ssize_t recv_i (ACE_HANDLE handle, + void *buf, + size_t len); + + extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + size_t *bytes_transferred); + + extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + +#if defined (ACE_HAS_TLI) + + extern ACE_Export ssize_t t_rcv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + size_t *bytes_transferred); + + extern ACE_Export ssize_t t_rcv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + +#endif /* ACE_HAS_TLI */ + + extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + size_t *bytes_transferred); + + extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle, + void *buf, + size_t len, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + + extern ACE_Export ssize_t recvv_n_i (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + size_t *bytes_transferred); + + extern ACE_Export ssize_t recvv_n_i (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + + // + // = Send_n helpers + // + + ACE_NAMESPACE_INLINE_FUNCTION ssize_t send_i (ACE_HANDLE handle, + const void *buf, + size_t len); + + extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + size_t *bytes_transferred); + + extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + +#if defined (ACE_HAS_TLI) + + extern ACE_Export ssize_t t_snd_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + size_t *bytes_transferred); + + extern ACE_Export ssize_t t_snd_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + +#endif /* ACE_HAS_TLI */ + + extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + size_t *bytes_transferred); + + extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle, + const void *buf, + size_t len, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + + extern ACE_Export ssize_t sendv_n_i (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + size_t *bytes_transferred); + + extern ACE_Export ssize_t sendv_n_i (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout, + size_t *bytes_transferred); + +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/ACE.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ACE_H */ diff --git a/dep/ACE_wrappers/ace/ACE.inl b/dep/ACE_wrappers/ace/ACE.inl new file mode 100644 index 000000000..f800ac80a --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE.inl @@ -0,0 +1,350 @@ +// -*- C++ -*- +// +// $Id: ACE.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_Thread.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_NS_sys_socket.h" + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +// Wrappers for methods that have been moved to ACE_OS. + +ACE_INLINE ssize_t +ACE::read_n (ACE_HANDLE handle, + void *buf, + size_t len, + size_t *bytes_transferred) +{ + return ACE_OS::read_n (handle, + buf, + len, + bytes_transferred); +} + +ACE_INLINE ssize_t +ACE::write_n (ACE_HANDLE handle, + const void *buf, + size_t len, + size_t *bytes_transferred) +{ + return ACE_OS::write_n (handle, + buf, + len, + bytes_transferred); +} + +ACE_INLINE ssize_t +ACE::recv_n (ACE_HANDLE handle, + void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::recv_n_i (handle, + buf, + len, + flags, + bytes_transferred); + else + return ACE::recv_n_i (handle, + buf, + len, + flags, + timeout, + bytes_transferred); +} + +#if defined (ACE_HAS_TLI) + +ACE_INLINE ssize_t +ACE::t_rcv_n (ACE_HANDLE handle, + void *buf, + size_t len, + int *flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::t_rcv_n_i (handle, + buf, + len, + flags, + bytes_transferred); + else + return ACE::t_rcv_n_i (handle, + buf, + len, + flags, + timeout, + bytes_transferred); +} + +#endif /* ACE_HAS_TLI */ + +ACE_INLINE ssize_t +ACE::recv_n (ACE_HANDLE handle, + void *buf, + size_t len, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::recv_n_i (handle, + buf, + len, + bytes_transferred); + else + return ACE::recv_n_i (handle, + buf, + len, + timeout, + bytes_transferred); +} + +ACE_INLINE ssize_t +ACE::recvv_n (ACE_HANDLE handle, + iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::recvv_n_i (handle, + iov, + iovcnt, + bytes_transferred); + else + return ACE::recvv_n_i (handle, + iov, + iovcnt, + timeout, + bytes_transferred); +} + +ACE_INLINE ssize_t +ACE::send_n (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::send_n_i (handle, + buf, + len, + flags, + bytes_transferred); + else + return ACE::send_n_i (handle, + buf, + len, + flags, + timeout, + bytes_transferred); +} + +#if defined (ACE_HAS_TLI) + +ACE_INLINE ssize_t +ACE::t_snd_n (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::t_snd_n_i (handle, + buf, + len, + flags, + bytes_transferred); + else + return ACE::t_snd_n_i (handle, + buf, + len, + flags, + timeout, + bytes_transferred); +} + +#endif /* ACE_HAS_TLI */ + +ACE_INLINE ssize_t +ACE::send_n (ACE_HANDLE handle, + const void *buf, + size_t len, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::send_n_i (handle, + buf, + len, + bytes_transferred); + else + return ACE::send_n_i (handle, + buf, + len, + timeout, + bytes_transferred); +} + +ACE_INLINE ssize_t +ACE::sendv_n (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + if (timeout == 0) + return ACE::sendv_n_i (handle, + iov, + iovcnt, + bytes_transferred); + else + return ACE::sendv_n_i (handle, + iov, + iovcnt, + timeout, + bytes_transferred); +} + +ACE_INLINE ssize_t +ACE::send_i (ACE_HANDLE handle, const void *buf, size_t len) +{ +#if defined (ACE_WIN32) || defined (HPUX) + return ACE_OS::send (handle, (const char *) buf, len); +#else + return ACE_OS::write (handle, (const char *) buf, len); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE ssize_t +ACE::recv_i (ACE_HANDLE handle, void *buf, size_t len) +{ +#if defined (ACE_WIN32) || defined (ACE_OPENVMS) || defined (ACE_TANDEM_T1248_PTHREADS) + return ACE_OS::recv (handle, (char *) buf, len); +#else + return ACE_OS::read (handle, (char *) buf, len); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE::handle_read_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout) +{ + return ACE::handle_ready (handle, + timeout, + 1, + 0, + 0); +} + +ACE_INLINE int +ACE::handle_write_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout) +{ + return ACE::handle_ready (handle, + timeout, + 0, + 1, + 0); +} + +ACE_INLINE int +ACE::handle_exception_ready (ACE_HANDLE handle, + const ACE_Time_Value *timeout) +{ + return ACE::handle_ready (handle, + timeout, + 0, + 0, + 1); +} + +ACE_INLINE void +ACE::strdelete (char *s) +{ + delete [] s; +} + +#if defined (ACE_HAS_WCHAR) +ACE_INLINE void +ACE::strdelete (wchar_t *s) +{ + delete [] s; +} +#endif /* ACE_HAS_WCHAR */ + +ACE_INLINE void +ACE::unique_name (const void *object, + ACE_TCHAR *name, + size_t length) +{ + ACE_OS::unique_name (object, name, length); +} + +ACE_INLINE u_long +ACE::log2 (u_long num) +{ + u_long log = 0; + + for (; num > 1; ++log) + num >>= 1; + + return log; +} + +ACE_INLINE ACE_TCHAR +ACE::nibble2hex (u_int n) +{ + // Hexadecimal characters. +#if defined (ACE_VXWORKS) && !defined (__DCPLUSPLUS__) + // temporary solution to prevent Windriver GNU toolchains from spewing + // loads of warnings when inlining. + // problem (incorrect warning leftover from older GNU) has been reported as + // TSR to Windriver. + const ACE_TCHAR hex_chars[] = ACE_TEXT ("0123456789abcdef"); +#else + static const ACE_TCHAR hex_chars[] = ACE_TEXT ("0123456789abcdef"); +#endif + + // Yes, this works for UNICODE + return hex_chars[n & 0x0f]; +} + +ACE_INLINE int +ACE::map_errno (int error) +{ +#if defined (ACE_WIN32) + switch (error) + { + case WSAEWOULDBLOCK: + return EAGAIN; // Same as UNIX errno EWOULDBLOCK. + } +#endif /* ACE_WIN32 */ + + return error; +} + +ACE_INLINE u_char +ACE::hex2byte (ACE_TCHAR c) +{ + if (ACE_OS::ace_isdigit (c)) + return (u_char) (c - ACE_TEXT ('0')); + else if (ACE_OS::ace_islower (c)) + return (u_char) (10 + c - ACE_TEXT ('a')); + else + return (u_char) (10 + c - ACE_TEXT ('A')); +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ACE_crc32.cpp b/dep/ACE_wrappers/ace/ACE_crc32.cpp new file mode 100644 index 000000000..70d93e6b5 --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE_crc32.cpp @@ -0,0 +1,161 @@ +// $Id: ACE_crc32.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" + +ACE_RCSID (ace, + ACE_crc32, + "$Id: ACE_crc32.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +namespace +{ + /*****************************************************************/ + /* */ + /* CRC LOOKUP TABLE */ + /* ================ */ + /* The following CRC lookup table was generated automagically */ + /* by the Rocksoft^tm Model CRC Algorithm Table Generation */ + /* Program V1.0 using the following model parameters: */ + /* */ + /* Width : 4 bytes. */ + /* Poly : 0x04C11DB7L */ + /* Reverse : TRUE. */ + /* */ + /* For more information on the Rocksoft^tm Model CRC Algorithm, */ + /* see the document titled "A Painless Guide to CRC Error */ + /* Detection Algorithms" by Ross Williams */ + /* (ross@guest.adelaide.edu.au.). This document is likely to be */ + /* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ + /* */ + /*****************************************************************/ + + const ACE_UINT32 crc_table[] = + { + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL + }; + + /*****************************************************************/ + /* End of CRC Lookup Table */ + /*****************************************************************/ +} + +#define COMPUTE(var, ch) (var) = (crc_table[(var ^ ch) & 0xFF] ^ (var >> 8)) + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_UINT32 +ACE::crc32 (const char *string) +{ + ACE_UINT32 crc = 0xFFFFFFFF; + + for (const char *p = string; + *p != 0; + ++p) + { + COMPUTE (crc, *p); + } + + return ~crc; +} + +ACE_UINT32 +ACE::crc32 (const void *buffer, size_t len, ACE_UINT32 crc) +{ + crc = ~crc; + + for (const char *p = (const char *) buffer, + *e = (const char *) buffer + len; + p != e; + ++p) + { + COMPUTE (crc, *p); + } + + return ~crc; +} + +ACE_UINT32 +ACE::crc32 (const iovec *iov, int len, ACE_UINT32 crc) +{ + crc = ~crc; + + for (int i = 0; i < len; ++i) + { + for (const char *p = (const char *) iov[i].iov_base, + *e = (const char *) iov[i].iov_base + iov[i].iov_len; + p != e; + ++p) + COMPUTE (crc, *p); + } + + return ~crc; +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#undef COMPUTE diff --git a/dep/ACE_wrappers/ace/ACE_crc_ccitt.cpp b/dep/ACE_wrappers/ace/ACE_crc_ccitt.cpp new file mode 100644 index 000000000..ef7f5d65b --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE_crc_ccitt.cpp @@ -0,0 +1,128 @@ +// $Id: ACE_crc_ccitt.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" + +ACE_RCSID (ace, + ACE_crc_ccitt, + "$Id: ACE_crc_ccitt.cpp 80826 2008-03-04 14:51:23Z wotte $") + +namespace +{ + /*****************************************************************/ + /* */ + /* CRC LOOKUP TABLE */ + /* ================ */ + /* The following CRC lookup table was generated automagically */ + /* by the Rocksoft^tm Model CRC Algorithm Table Generation */ + /* Program V1.0 using the following model parameters: */ + /* */ + /* Width : 2 bytes. */ + /* Poly : 0x1021 */ + /* Reverse : TRUE. */ + /* */ + /* For more information on the Rocksoft^tm Model CRC Algorithm, */ + /* see the document titled "A Painless Guide to CRC Error */ + /* Detection Algorithms" by Ross Williams */ + /* (ross@guest.adelaide.edu.au.). This document is likely to be */ + /* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ + /* */ + /*****************************************************************/ + + const ACE_UINT16 crc_table[] = + { + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, + 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, + 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, + 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, + 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, + 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, + 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, + 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, + 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, + 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, + 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, + 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, + 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, + 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, + 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, + 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, + 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, + 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, + 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, + 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, + 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, + 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, + 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, + 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, + 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, + 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, + 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, + 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, + 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, + 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, + 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 + }; + + /*****************************************************************/ + /* End of CRC Lookup Table */ + /*****************************************************************/ +} + +#define COMPUTE(var, ch) (var) = (crc_table[(var ^ ch) & 0xFF] ^ (var >> 8)) + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_UINT16 +ACE::crc_ccitt (const char *string) +{ + ACE_UINT16 crc = 0xFFFF; + + for (const char *p = string; + *p != 0; + ++p) + { + COMPUTE (crc, *p); + } + + return ~crc; +} + +ACE_UINT16 +ACE::crc_ccitt (const void *buffer, size_t len, ACE_UINT16 crc) +{ + crc = ~crc; + + for (const char *p = (const char *) buffer, + *e = (const char *) buffer + len; + p != e; + ++p) + { + COMPUTE (crc, *p); + } + + return ~crc; +} + +ACE_UINT16 +ACE::crc_ccitt (const iovec *iov, int len, ACE_UINT16 crc) +{ + crc = ~crc; + + for (int i = 0; i < len; ++i) + { + for (const char *p = (const char *) iov[i].iov_base, + *e = (const char *) iov[i].iov_base + iov[i].iov_len; + p != e; + ++p) + COMPUTE (crc, *p); + } + + return ~crc; +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#undef COMPUTE diff --git a/dep/ACE_wrappers/ace/ACE_export.h b/dep/ACE_wrappers/ace/ACE_export.h new file mode 100644 index 000000000..8ad2a33eb --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE_export.h @@ -0,0 +1,76 @@ +// -*- C++ -*- +// $Id: ACE_export.h 80826 2008-03-04 14:51:23Z wotte $ +// Definition for Win32 Export directives. +// This file is generated automatically by +// generate_export_file.pl +// ------------------------------ + +#ifndef ACE_EXPORT_H +#define ACE_EXPORT_H + +#include "ace/config-lite.h" + +#if defined (ACE_AS_STATIC_LIBS) + +# if !defined (ACE_HAS_DLL) +# define ACE_HAS_DLL 0 +# endif /* ! ACE_HAS_DLL */ +#else +# if !defined (ACE_HAS_DLL) +# define ACE_HAS_DLL 1 +# endif /* ! ACE_HAS_DLL */ +#endif /* ACE_AS_STATIC_LIB */ + +#if defined (ACE_HAS_DLL) +# if (ACE_HAS_DLL == 1) +# if defined (ACE_BUILD_DLL) +# define ACE_Export ACE_Proper_Export_Flag +# define ACE_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else +# define ACE_Export ACE_Proper_Import_Flag +# define ACE_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* ACE_BUILD_DLL */ +# else +# define ACE_Export +# define ACE_SINGLETON_DECLARATION(T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* ! ACE_HAS_DLL == 1 */ +#else +# define ACE_Export +# define ACE_SINGLETON_DECLARATION(T) +# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* ACE_HAS_DLL */ + +// Added by hand to help with ACE_OS namespace +#if defined (__TANDEM) && defined (USE_EXPLICIT_EXPORT) +#define ACE_NAMESPACE_STORAGE_CLASS ACE_EXPORT_MACRO extern +#else +#define ACE_NAMESPACE_STORAGE_CLASS extern ACE_EXPORT_MACRO +#endif + +#if defined (__ACE_INLINE__) +# if defined (_MSC_VER) || defined (__MINGW32__) || defined (CYGWIN32) || \ + (defined (__SUNPRO_CC) && __SUNPRO_CC >= 0x560) || \ + (defined (__HP_aCC) && (__HP_aCC >= 60500)) || \ + (defined (__sgi) && \ + defined (_COMPILER_VERSION) && _COMPILER_VERSION <= 730) +# define ACE_NAMESPACE_INLINE_FUNCTION inline +# else +# define ACE_NAMESPACE_INLINE_FUNCTION ACE_NAMESPACE_STORAGE_CLASS inline +# endif +# define ACE_INLINE_TEMPLATE_FUNCTION inline +#else +# define ACE_NAMESPACE_INLINE_FUNCTION ACE_NAMESPACE_STORAGE_CLASS +// Microsoft Visual C++ will accept 'extern'; others refuse. +# if defined (_MSC_VER) || defined (__BORLANDC__) +# define ACE_INLINE_TEMPLATE_FUNCTION ACE_Export +# else +# define ACE_INLINE_TEMPLATE_FUNCTION +# endif +#endif + +#endif /* ACE_EXPORT_H */ + +// End of auto generated file. diff --git a/dep/ACE_wrappers/ace/ACE_vc71.vcproj b/dep/ACE_wrappers/ace/ACE_vc71.vcproj new file mode 100644 index 000000000..f308d6ec6 --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE_vc71.vcproj @@ -0,0 +1,5255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dep/ACE_wrappers/ace/ACE_vc8.vcproj b/dep/ACE_wrappers/ace/ACE_vc8.vcproj new file mode 100644 index 000000000..6b05ee9b2 --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE_vc8.vcproj @@ -0,0 +1,6640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dep/ACE_wrappers/ace/ACE_vc9.vcproj b/dep/ACE_wrappers/ace/ACE_vc9.vcproj new file mode 100644 index 000000000..0bef2b94a --- /dev/null +++ b/dep/ACE_wrappers/ace/ACE_vc9.vcproj @@ -0,0 +1,6640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dep/ACE_wrappers/ace/ARGV.cpp b/dep/ACE_wrappers/ace/ARGV.cpp new file mode 100644 index 000000000..edfd4efa7 --- /dev/null +++ b/dep/ACE_wrappers/ace/ARGV.cpp @@ -0,0 +1,383 @@ +// $Id: ARGV.cpp 81374 2008-04-16 13:07:47Z iliyan $ + +#ifndef ACE_ARGV_CPP +#define ACE_ARGV_CPP + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_Memory.h" + +#if !defined (__ACE_INLINE__) +#include "ace/ARGV.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, ARGV, "$Id: ARGV.cpp 81374 2008-04-16 13:07:47Z iliyan $") + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE (ACE_ARGV_Queue_Entry) +ACE_ALLOC_HOOK_DEFINE (ACE_ARGV) + +template +void +ACE_ARGV_Queue_Entry_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ARGV_Queue_Entry_T::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("arg_ = %s"), this->arg_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("quote_arg_ = %d"), (int)this->quote_arg_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +void +ACE_ARGV_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ARGV_T::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("argc_ = %d"), this->argc_)); + + ACE_ARGV *this_obj = const_cast (this); + + for (int i = 0; i < this->argc_; i++) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\nargv_[%i] = %s"), + i, + this_obj->argv ()[i])); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nbuf = %s\n"), this->buf_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Creates this->argv_ out of this->buf_. New memory is allocated for +// each element of the array. This is used by the array-to-string +// style constructor and for creating this->argv_ when in iterative +// mode. + +template +int +ACE_ARGV_T::string_to_argv (void) +{ + ACE_TRACE ("ACE_ARGV_T::string_to_argv"); + + return ACE_OS::string_to_argv (this->buf_, + this->argc_, + this->argv_, + this->substitute_env_args_); +} + +template +ACE_ARGV_T::ACE_ARGV_T (const CHAR_TYPE buf[], + bool substitute_env_args) + : substitute_env_args_ (substitute_env_args), + iterative_ (false), + argc_ (0), + argv_ (0), + buf_ (0), + length_ (0), + queue_ () +{ + ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE[] to CHAR_TYPE *[]"); + + if (buf == 0 || buf[0] == 0) + return; + + // Make an internal copy of the string. + ACE_NEW (this->buf_, + CHAR_TYPE[ACE_OS::strlen (buf) + 1]); + ACE_OS::strcpy (this->buf_, buf); + + // Create this->argv_. + if (this->string_to_argv () == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("string_to_argv"))); +} + +template +ACE_ARGV_T::ACE_ARGV_T (CHAR_TYPE *argv[], + bool substitute_env_args, + bool quote_arg) + : substitute_env_args_ (substitute_env_args), + iterative_ (false), + argc_ (0), + argv_ (0), + buf_ (0), + length_ (0), + queue_ () +{ + ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] to CHAR_TYPE[]"); + + if (argv == 0 || argv[0] == 0) + return; + + this->argc_ = ACE_OS::argv_to_string (argv, + this->buf_, + substitute_env_args, + quote_arg); +} + +template +ACE_ARGV_T::ACE_ARGV_T (int argc, + CHAR_TYPE *argv[], + bool substitute_env_args, + bool quote_arg) + : substitute_env_args_ (substitute_env_args), + iterative_ (false), + argc_ (0), + argv_ (0), + buf_ (0), + length_ (0), + queue_ () +{ + ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T int,CHAR_TYPE*[] to CHAR_TYPE[]"); + + this->argc_ = ACE_OS::argv_to_string (argc, + argv, + this->buf_, + substitute_env_args, + quote_arg); +} + + +template +ACE_ARGV_T::ACE_ARGV_T (CHAR_TYPE *first_argv[], + CHAR_TYPE *second_argv[], + bool substitute_env_args, + bool quote_args) + : substitute_env_args_ (substitute_env_args), + iterative_ (false), + argc_ (0), + argv_ (0), + buf_ (0), + length_ (0), + queue_ () +{ + ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] + CHAR_TYPE *[] to CHAR_TYPE[]"); + + int first_argc = 0; + int second_argc = 0; + + CHAR_TYPE *first_buf = 0; + CHAR_TYPE *second_buf = 0; + + // convert the first argv to a string + if (first_argv != 0 && first_argv[0] != 0) + { + first_argc = ACE_OS::argv_to_string (first_argv, + first_buf, + substitute_env_args, + quote_args); + } + + // convert the second argv to a string + if (second_argv != 0 && second_argv[0] != 0) + { + second_argc = ACE_OS::argv_to_string (second_argv, + second_buf, + substitute_env_args, + quote_args); + } + + // Add the number of arguments in both the argvs. + this->argc_ = first_argc + second_argc; + + size_t buf_len = + ACE_OS::strlen (first_buf) + ACE_OS::strlen (second_buf) + 1; + + // Allocate memory to the lenght of the combined argv string. + ACE_NEW (this->buf_, + CHAR_TYPE[buf_len + 1]); + + // copy the first argv string to the buffer + ACE_OS::strcpy (this->buf_, first_buf); + + // concatenate the second argv string to the buffer + ACE_OS::strcat (this->buf_, second_buf); + + // Delete the first and second buffers + delete [] first_buf; + delete [] second_buf; +} + +template +ACE_ARGV_T::ACE_ARGV_T (bool substitute_env_args) + : substitute_env_args_ (substitute_env_args), + iterative_ (true), + argc_ (0), + argv_ (0), + buf_ (0), + length_ (0), + queue_ () +{ + ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T Iterative"); + + // Nothing to do yet -- the user puts in arguments via add () +} + +template +int +ACE_ARGV_T::add (const CHAR_TYPE *next_arg, bool quote_arg) +{ + // Only allow this to work in the "iterative" verion -- the + // ACE_ARGVs created with the one argument constructor. + if (!this->iterative_) + { + errno = EINVAL; + return -1; + } + + this->length_ += ACE_OS::strlen (next_arg); + if (quote_arg && ACE_OS::strchr (next_arg, ' ') != 0) + { + this->length_ += 2; + if (ACE_OS::strchr (next_arg, '"') != 0) + for (const CHAR_TYPE * p = next_arg; *p != '\0'; ++p) + if (*p == '"') ++this->length_; + } + else + { + quote_arg = false; + } + + // Put the new argument at the end of the queue. + if (this->queue_.enqueue_tail (ACE_ARGV_Queue_Entry_T (next_arg, quote_arg)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Can't add more to ARGV queue")), + -1); + + ++this->argc_; + + // Wipe argv_ and buf_ away so that they will be recreated if the + // user calls argv () or buf (). + if (this->argv_ != 0) + { + for (int i = 0; this->argv_[i] != 0; i++) + ACE_OS::free ((void *) this->argv_[i]); + + delete [] this->argv_; + this->argv_ = 0; + } + + delete [] this->buf_; + this->buf_ = 0; + + return 0; +} + +template +int +ACE_ARGV_T::add (CHAR_TYPE *argv[], bool quote_args) +{ + for (int i = 0; argv[i] != 0; i++) + if (this->add (argv[i], quote_args) == -1) + return -1; + + return 0; +} + +// Free up argv_ and buf_ + +template +ACE_ARGV_T::~ACE_ARGV_T (void) +{ + ACE_TRACE ("ACE_ARGV_T::~ACE_ARGV_T"); + + if (this->argv_ != 0) + for (int i = 0; this->argv_[i] != 0; i++) + ACE_OS::free ((void *) this->argv_[i]); + + delete [] this->argv_; + delete [] this->buf_; +} + +// Create buf_ out of the queue_. This is only used in the +// "iterative" mode. + +template +int +ACE_ARGV_T::create_buf_from_queue (void) +{ + ACE_TRACE ("ACE_ARGV_T::create_buf_from_queue"); + + // If the are no arguments, don't do anything + if (this->argc_ <= 0) + return -1; + + delete [] this->buf_; + + ACE_NEW_RETURN (this->buf_, + CHAR_TYPE[this->length_ + this->argc_], + -1); + + // Get an iterator over the queue + ACE_Unbounded_Queue_Iterator > iter (this->queue_); + + ACE_ARGV_Queue_Entry_T *arg = 0; + CHAR_TYPE *ptr = this->buf_; + size_t len; + + while (!iter.done ()) + { + // Get next argument from the queue. + iter.next (arg); + iter.advance (); + + if (arg->quote_arg_) + { + *ptr++ = '"'; + if (ACE_OS::strchr (arg->arg_, '"') != 0) + { + CHAR_TYPE prev = 0; + for (const CHAR_TYPE * p = arg->arg_; *p != '\0'; ++p) + { + if (*p == '"' && prev != '\\') *ptr++ = '\\'; + prev = *ptr++ = *p; + } + } + else + { + len = ACE_OS::strlen (arg->arg_); + // Copy the argument into buf_ + ACE_OS::memcpy ((void *) ptr, + (const void *) (arg->arg_), + len * sizeof (CHAR_TYPE)); + // Move the pointer down. + ptr += len; + } + *ptr++ = '"'; + } + else + { + len = ACE_OS::strlen (arg->arg_); + // Copy the argument into buf_ + ACE_OS::memcpy ((void *) ptr, + (const void *) (arg->arg_), + len * sizeof (CHAR_TYPE)); + // Move the pointer down. + ptr += len; + } + + // Put in an argument separating space. + *ptr++ = ' '; + } + + // Put in the NUL terminator + ptr[-1] = '\0'; + + return 0; +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ARGV_CPP */ diff --git a/dep/ACE_wrappers/ace/ARGV.h b/dep/ACE_wrappers/ace/ARGV.h new file mode 100644 index 000000000..66e71810a --- /dev/null +++ b/dep/ACE_wrappers/ace/ARGV.h @@ -0,0 +1,333 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file ARGV.h + * + * $Id: ARGV.h 81156 2008-03-30 20:56:47Z iliyan $ + * + * @author Doug Schmidt + * @author Everett Anderson + */ +//========================================================================== + +#ifndef ACE_ARGUMENT_VECTOR_H +#define ACE_ARGUMENT_VECTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/Unbounded_Queue.h" + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_ARGV_Queue_Entry_T + * + * @brief An entry in the queue which keeps user supplied arguments. + */ +template +class ACE_ARGV_Queue_Entry_T +{ +public: + // = Initialization and termination. + /// Initialize a ACE_ARGV_Queue_Entry_T. + ACE_ARGV_Queue_Entry_T (void); + + /** + * Initialize a ACE_ARGV_Queue_Entry_T. + * + * @param arg Pointer to an argument + * + * @param quote_arg The argument @a arg need to be quoted + * while adding to the vector. + */ + ACE_ARGV_Queue_Entry_T (const CHAR_TYPE *arg, + bool quote_arg); + + /** + * Initialize a ACE_ARGV_Queue_Entry_T. + * + * @param entry Pointer to a queue entry + */ + ACE_ARGV_Queue_Entry_T (const ACE_ARGV_Queue_Entry_T &entry); + + /// We need this destructor to keep some compilers from complaining. + /// It's just a no-op, however. + ~ACE_ARGV_Queue_Entry_T (void); + + /// Dump the state of this object. + void dump (void) const; + + // Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Pointer to the argument. + const CHAR_TYPE * arg_; + + /// The argument need to be quoted while adding to the vector. + bool quote_arg_; +}; + +/** + * @class ACE_ARGV_T + * + * @brief Builds a counted argument vector (ala argc/argv) from either + * a string or a set of separate tokens. This class preserves whitespace + * within tokens only if the whitespace-containing token is enclosed in + * either single (') or double (") quotes. This is consistent with the + * expected behavior if an argument vector obtained using this class is + * passed to, for example, ACE_Get_Opt. + * + * This class can substitute environment variable values for tokens that + * are environment variable references (e.g., @c $VAR). This only works + * if the token is an environment variable reference and nothing else; it + * doesn't substitute environment variable references within a token. + * For example, @c $HOME/file will not substitute the value of the HOME + * environment variable. + */ +template +class ACE_ARGV_T +{ +public: + // = Initialization and termination. + /** + * Splits the specified string into an argument vector. Arguments in the + * string are delimited by whitespace. Whitespace-containing arguments + * must be enclosed in quotes, either single (') or double ("). + * + * @param buf A nul-terminated CHAR_TYPE array to split into arguments + * for the vector. + * + * @param substitute_env_args If non-zero, any token that is an + * environment variable reference (e.g., @c $VAR) will have + * its environment variable value in the resultant vector + * in place of the environment variable name. + */ + explicit ACE_ARGV_T (const CHAR_TYPE buf[], + bool substitute_env_args = true); + + /** + * Initializes the argument vector from a set of arguments. Any environment + * variable references are translated (if applicable) during execution of + * this method. In contrast with ACE_ARGV_T(CHAR_TYPE *[], bool, bool), this + * ctor does not require argv to be 0-terminated as the number of arguments + * is provided explicitely. + * + * @param argc The number of arguments in the argv array. + * + * @param argv An array of tokens to initialize the object with. All needed + * data is copied from @a argv during this call; the pointers + * in @a argv are not needed after this call, and the memory + * referred to by @a argv is not referenced by this object. + * + * @param substitute_env_args If non-zero, any element of @a argv that is + * an environment variable reference (e.g., @c $VAR) will have + * its environment variable value in the resultant vector + * in place of the environment variable name. + * + * @param quote_args If non-zero each argument @a argv[i] needs to + * be enclosed in double quotes ('"'). + */ + explicit ACE_ARGV_T (int argc, + CHAR_TYPE *argv[], + bool substitute_env_args = true, + bool quote_args = false); + + /** + * Initializes the argument vector from a set of arguments. Any environment + * variable references are translated (if applicable) during execution of + * this method. + * + * @param argv An array of tokens to initialize the object with. The + * array must be terminated with a 0 pointer. All needed + * data is copied from @a argv during this call; the pointers + * in @a argv are not needed after this call, and the memory + * referred to by @a argv is not referenced by this object. + * + * @param substitute_env_args If non-zero, any element of @a argv that is + * an environment variable reference (e.g., @c $VAR) will have + * its environment variable value in the resultant vector + * in place of the environment variable name. + * + * @param quote_args If non-zero each argument @a argv[i] needs to + * be enclosed in double quotes ('"'). + */ + explicit ACE_ARGV_T (CHAR_TYPE *argv[], + bool substitute_env_args = true, + bool quote_args = false); + + /** + * Initializes the argument vector from two combined argument vectors. + * + * @param first_argv An array of tokens to initialize the object with. + * The array must be terminated with a 0 pointer. + * @param second_argv An array of tokens that is concatenated with the + * the tokens in @a first_argv. The array must be + * terminated with a 0 pointer. + * @param substitute_env_args If non-zero, any element of @a first_argv + * or @a second_argv that is an environment variable + * reference (e.g., @c $VAR) will have its environment + * variable value in the resultant vector in place + * of the environment variable name. + * + * @param quote_args If non-zero each arguments @a first_argv[i] and + * @a second_argv[i] needs to be enclosed + * in double quotes ('"'). + */ + ACE_ARGV_T (CHAR_TYPE *first_argv[], + CHAR_TYPE *second_argv[], + bool substitute_env_args = true, + bool quote_args = false); + + /** + * Initialize this object so arguments can be added later using one + * of the add methods. This is referred to as the @i iterative method + * of adding arguments to this object. + */ + explicit ACE_ARGV_T (bool substitute_env_args = true); + + /// Destructor. + ~ACE_ARGV_T (void); + + /** @name Accessor methods + * + * These methods access the argument vector contained in this object. + */ + //@{ + /** + * Returns the specified element of the current argument vector. + * + * @param index Index to the desired element. + * + * @retval Pointer to the indexed string. + * @retval 0 if @a index is out of bounds. + */ + const CHAR_TYPE *operator[] (size_t index); + + /** + * Returns the current argument vector. The returned pointers are to data + * maintained internally to this class. Do not change or delete either the + * pointers or the memory to which they refer. + */ + CHAR_TYPE **argv (void); + + /// Returns the current number of arguments. + int argc (void) const; + + /** + * Returns a single string form of the current arguments. The returned + * pointer refers to memory maintained internally to this class. Do not + * change or delete it. + */ + const CHAR_TYPE *buf (void); + + //@} + + /// Dump the state of this object. + void dump (void) const; + + // Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /** + * Add another argument. This only works in the iterative mode. + * + * @note This method copies the specified pointer, but not the data + * contained in the referenced memory. Thus, if the content of + * the memory referred to by @a next_arg are changed after this + * method returns, the results are undefined. + * + * @param next_arg Pointer to the next argument to add to the vector. + * + * @param quote_arg The argument @a next_arg need to be quoted while + * adding to the vector. + * + * @retval 0 on success; -1 on failure. Most likely @c errno values are: + * - EINVAL: This object is not in iterative mode. + * - ENOMEM: Not enough memory available to save @a next_arg. + */ + int add (const CHAR_TYPE *next_arg, bool quote_arg = false); + + /** + * Add an array of arguments. This only works in the iterative mode. + * + * @note This method copies the specified pointers, but not the data + * contained in the referenced memory. Thus, if the content of + * the memory referred to by any of the @a argv elements is + * changed after this method returns, the results are undefined. + * + * @param argv Pointers to the arguments to add to the vector. + * @a argv must be terminated by a 0 pointer. + * + * @param quote_args If non-zero each argument @a argv[i] needs to + * be enclosed in double quotes ('"'). + * + * @retval 0 on success; -1 on failure. Most likely @c errno values are: + * - EINVAL: This object is not in iterative mode. + * - ENOMEM: Not enough memory available to save @a next_arg. + */ + int add (CHAR_TYPE *argv[], bool quote_args = false); + +private: + /// Copy constructor not implemented. + ACE_UNIMPLEMENTED_FUNC (ACE_ARGV_T (const ACE_ARGV_T&)) + + /// Assignment operator not implemented. + ACE_UNIMPLEMENTED_FUNC (ACE_ARGV_T operator= (const ACE_ARGV_T&)) + + /// Creates buf_ from the queue of added args, deletes previous buf_. + int create_buf_from_queue (void); + + /// Converts buf_ into the CHAR_TYPE *argv[] format. + int string_to_argv (void); + + /// Replace args with environment variable values? + bool substitute_env_args_; + + bool iterative_; + + /// Number of arguments in the ARGV array. + int argc_; + + /// The array of string arguments. + CHAR_TYPE **argv_; + + /// Buffer containing the contents. + CHAR_TYPE *buf_; + + /// Total length of the arguments in the queue, not counting + /// separating spaces + size_t length_; + + /// Queue which keeps user supplied arguments. This is only + /// active in the "iterative" mode. + ACE_Unbounded_Queue > queue_; +}; + +typedef ACE_ARGV_Queue_Entry_T ACE_ARGV_Queue_Entry; +typedef ACE_ARGV_T ACE_ARGV; + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/ARGV.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/ARGV.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("ARGV.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_ARGUMENT_VECTOR_H */ diff --git a/dep/ACE_wrappers/ace/ARGV.inl b/dep/ACE_wrappers/ace/ARGV.inl new file mode 100644 index 000000000..fdc5b13d7 --- /dev/null +++ b/dep/ACE_wrappers/ace/ARGV.inl @@ -0,0 +1,104 @@ +/* -*- C++ -*- */ +// $Id: ARGV.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Global_Macros.h" + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_ARGV_Queue_Entry_T::ACE_ARGV_Queue_Entry_T (void) + : arg_(0), + quote_arg_(false) +{ + // No-op +} + +template ACE_INLINE +ACE_ARGV_Queue_Entry_T::ACE_ARGV_Queue_Entry_T (const CHAR_TYPE *arg, + bool quote_arg) + : arg_(arg), + quote_arg_(quote_arg) +{ + // No-op +} + +template ACE_INLINE +ACE_ARGV_Queue_Entry_T::ACE_ARGV_Queue_Entry_T (const ACE_ARGV_Queue_Entry_T &entry) + : arg_(entry.arg_), + quote_arg_(entry.quote_arg_) +{ + // No-op +} + +template ACE_INLINE +ACE_ARGV_Queue_Entry_T::~ACE_ARGV_Queue_Entry_T (void) +{ + // No-op just to keep some compilers happy... +} + +// Return the number of args +template +ACE_INLINE int +ACE_ARGV_T::argc (void) const +{ + ACE_TRACE ("ACE_ARGV_T::argc"); + // Try to create the argv_ if it isn't there + ACE_ARGV_T *nonconst_this = + const_cast *> (this); + (void) nonconst_this->argv (); + return this->argc_; +} + +// Return the arguments in a space-separated string +template +ACE_INLINE const CHAR_TYPE * +ACE_ARGV_T::buf (void) +{ + ACE_TRACE ("ACE_ARGV_T::buf"); + + if (this->buf_ == 0 && this->iterative_) + this->create_buf_from_queue (); + + return (const CHAR_TYPE *) this->buf_; +} + +// Return the arguments in an entry-per-argument array + +template +ACE_INLINE CHAR_TYPE ** +ACE_ARGV_T::argv (void) +{ + ACE_TRACE ("ACE_ARGV_T::argv"); + + // Try to create the argv_ if it isn't there + if (this->argv_ == 0) + { + if (this->iterative_ && this->buf_ == 0) + this->create_buf_from_queue (); + + // Convert buf_ to argv_ + if (this->string_to_argv () == -1) + return (CHAR_TYPE **) 0; + } + + return (CHAR_TYPE **) this->argv_; +} + +// Subscript operator. + +template +ACE_INLINE const CHAR_TYPE * +ACE_ARGV_T::operator[] (size_t i) +{ + ACE_TRACE ("ACE_ARGV_T::operator[]"); + + // Don't go out of bounds. + if (i >= static_cast (this->argc_)) + return 0; + + return (const CHAR_TYPE *) this->argv ()[i]; +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ATM_Acceptor.cpp b/dep/ACE_wrappers/ace/ATM_Acceptor.cpp new file mode 100644 index 000000000..1aa6c6d70 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Acceptor.cpp @@ -0,0 +1,309 @@ +// $Id: ATM_Acceptor.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ATM_Acceptor.h" + +ACE_RCSID(ace, ATM_Acceptor, "$Id: ATM_Acceptor.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_ATM) + +#if defined (ACE_HAS_LINUX_ATM) +#include /**/ "linux/atmdev.h" +#endif /* ACE_HAS_LINUX_ATM */ + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_Acceptor.inl" +#endif /* __ACE_INLINE__ */ + + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Put the actual definitions of the ACE_ATM_Request and +// ACE_ATM_Request_Queue classes here to hide them from clients... + +ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Acceptor) + +ACE_ATM_Acceptor::ACE_ATM_Acceptor (void) +{ + ACE_TRACE ("ACE_ATM_Acceptor::ACE_ATM_Acceptor"); +} + +ACE_ATM_Acceptor::~ACE_ATM_Acceptor (void) +{ + ACE_TRACE ("ACE_ATM_Acceptor::~ACE_ATM_Acceptor"); +} + +int +ACE_ATM_Acceptor::get_local_addr (ACE_ATM_Addr &local_addr) +{ + ACE_TRACE ("ACE_ATM_Acceptor::get_local_addr"); + +#if defined (ACE_HAS_FORE_ATM_WS2) + unsigned long ret = 0; + DWORD deviceID = 0; + ATM_ADDRESS addr; + struct sockaddr_atm *laddr; + + if (::WSAIoctl ((int) ((ACE_SOCK_Acceptor *)this) -> get_handle (), + SIO_GET_ATM_ADDRESS, + (LPVOID) &deviceID, + sizeof (DWORD), + (LPVOID)&addr, + sizeof (ATM_ADDRESS), + &ret, + 0, + 0) == SOCKET_ERROR) { + ACE_OS::printf ("ATM_Acceptor (get_local_addr): WSIoctl: %d\n", + ::WSAGetLastError ()); + return -1; + } + + laddr = (struct sockaddr_atm *)local_addr.get_addr (); + ACE_OS::memcpy ((void *)& (laddr -> satm_number), + (void *)&addr, + ATM_ADDR_SIZE - 1); + + return 0; +#elif defined (ACE_HAS_FORE_ATM_XTI) + ACE_UNUSED_ARG (local_addr); + + return 0; +#elif defined (ACE_HAS_LINUX_ATM) + ATM_Addr *myaddr = (ATM_Addr *)local_addr.get_addr (); + int addrlen = sizeof (myaddr->sockaddratmsvc); + + if (ACE_OS::getsockname (acceptor_.get_handle (), + (struct sockaddr *) & (myaddr->sockaddratmsvc), + &addrlen) < 0) { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ATM_Acceptor (get_local_addr): ioctl: %d\n"), + errno)); + return -1; + } + + return (0); +#else + ACE_UNUSED_ARG (local_addr); + + return 0; +#endif /* ACE_HAS_FORE_ATM_WS2 && ACE_HAS_FORE_ATM_XTI */ +} + +ACE_HANDLE +ACE_ATM_Acceptor::open (const ACE_Addr &remote_sap, + int backlog, + ACE_ATM_Params params) +{ + ACE_TRACE ("ACE_ATM_Acceptor::open"); +#if defined (ACE_HAS_FORE_ATM_XTI) + ACE_HANDLE handle = acceptor_.open (remote_sap, + params.get_reuse_addr (), + params.get_oflag (), + params.get_info (), + backlog, + params.get_device ()); + return (handle == ACE_INVALID_HANDLE ? -1 : 0); +#elif defined (ACE_HAS_FORE_ATM_WS2) + struct sockaddr_atm local_atm_addr; + ACE_HANDLE ret; + DWORD flags = 0; + + /* Create a local endpoint of communication */ + + // Only leaves can listen. + flags = ACE_FLAG_MULTIPOINT_C_LEAF | ACE_FLAG_MULTIPOINT_D_LEAF; + + if ((ret = ACE_OS::socket (AF_ATM, + SOCK_RAW, + ATMPROTO_AAL5, + 0, + 0, + flags)) + == ACE_INVALID_HANDLE) { + ACE_OS::printf ("Acceptor (open): socket %d\n", + ::WSAGetLastError ()); + return (ret); + } + + ((ACE_SOCK_Acceptor *)this) -> set_handle (ret); + + /* Set up the address information to become a server */ + ACE_OS::memset ((void *) &local_atm_addr, 0, sizeof local_atm_addr); + local_atm_addr.satm_family = AF_ATM; + local_atm_addr.satm_number.AddressType = SAP_FIELD_ANY_AESA_REST; + local_atm_addr.satm_number.Addr[ ATM_ADDR_SIZE - 1 ] + = ((ACE_ATM_Addr *)&remote_sap) -> get_selector (); + local_atm_addr.satm_blli.Layer2Protocol = SAP_FIELD_ANY; + local_atm_addr.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT; + local_atm_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT; + + /* Associate address with endpoint */ + if (ACE_OS::bind (((ACE_SOCK_Acceptor *)this) -> get_handle (), + reinterpret_cast (&local_atm_addr), + sizeof local_atm_addr) == -1) { + ACE_OS::printf ("Acceptor (open): bind %d\n", ::WSAGetLastError ()); + return (ACE_INVALID_HANDLE); + } + + /* Make endpoint listen for service requests */ + if (ACE_OS::listen (( (ACE_SOCK_Acceptor *)this) -> get_handle (), + backlog) + == -1) { + ACE_OS::printf ("Acceptor (open): listen %d\n", ::WSAGetLastError ()); + return (ACE_INVALID_HANDLE); + } + + return 0; +#elif defined (ACE_HAS_LINUX_ATM) + //we need to set the qos before binding to the socket + //use remote_sap as local_sap + + ACE_ATM_Addr local_sap; + ATM_Addr *local_sap_addr = (ATM_Addr*)local_sap.get_addr (); + ACE_ATM_QoS def_qos; + ATM_QoS qos = def_qos.get_qos (); + + ACE_HANDLE handle; + if ((handle = ACE_OS::socket (params.get_protocol_family (), + params.get_type (), + params.get_protocol (), + params.get_protocol_info (), + params.get_sock_group (), + params.get_flags () + )) + == ACE_INVALID_HANDLE) { + ACE_DEBUG (LM_DEBUG, + ACE_TEXT ("Acceptor (socket): socket %d\n"), + errno); + return (ACE_INVALID_HANDLE); + } + + ((ACE_SOCK_Acceptor *)this) -> set_handle (handle); + if (ACE_OS::setsockopt (handle, + SOL_ATM, + SO_ATMQOS, + reinterpret_cast (&qos), + sizeof (qos)) < 0) { + ACE_OS::printf ("Acceptor (setsockopt): setsockopt:%d\n", + errno); + } + + struct atmif_sioc req; + struct sockaddr_atmsvc aux_addr[1024]; + + req.number = 0; + req.arg = aux_addr; + req.length = sizeof (aux_addr); + if (ACE_OS::ioctl (handle, + ATM_GETADDR, + &req) < 0) { + ACE_OS::perror ("Acceptor (setsockopt): ioctl:"); + } + else { + local_sap_addr->sockaddratmsvc = aux_addr[0]; + } + local_sap.set_selector (( (ACE_ATM_Addr*)&remote_sap)->get_selector ()); + + if (ACE_OS::bind (handle, + reinterpret_cast ( + &(local_sap_addr->sockaddratmsvc)), + sizeof (local_sap_addr->sockaddratmsvc) + ) == -1) { + ACE_DEBUG (LM_DEBUG, + ACE_TEXT ("Acceptor (open): bind %d\n"), + errno); + return -1; + } + // Make endpoint listen for service requests + if (ACE_OS::listen (handle, + backlog) + == -1) { + ACE_DEBUG (LM_DEBUG, + ACE_TEXT ("Acceptor (listen): listen %d\n"), + errno); + return -1; + } + + return 0; +#else + ACE_UNUSED_ARG (remote_sap); + ACE_UNUSED_ARG (backlog); + ACE_UNUSED_ARG (params); +#endif /* ACE_HAS_FORE_ATM_XTI/ACE_HAS_FORE_ATM_WS2/ACE_HAS_LINUX_ATM */ +} + +int +ACE_ATM_Acceptor::accept (ACE_ATM_Stream &new_sap, + ACE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle, + ACE_ATM_Params params, + ACE_ATM_QoS qos) +{ + ACE_TRACE ("ACE_ATM_Acceptor::accept"); +#if defined (ACE_HAS_FORE_ATM_XTI) + ATM_QoS optbuf = qos.get_qos (); + + return (acceptor_.accept (new_sap.get_stream (), + remote_addr, + timeout, + restart, + reset_new_handle, + params.get_rw_flag (), + params.get_user_data (), + &optbuf)); +#elif defined (ACE_HAS_FORE_ATM_WS2) + ACE_HANDLE n_handle; + ACE_HANDLE s_handle = ((ACE_SOCK_Acceptor *) this) -> get_handle (); + struct sockaddr_atm *cli_addr + = (struct sockaddr_atm *)remote_addr -> get_addr (); + int caddr_len = sizeof (struct sockaddr_atm); + + do { + n_handle = ACE_OS::accept (s_handle, + reinterpret_cast (cli_addr), + &caddr_len); + } while (n_handle == ACE_INVALID_HANDLE && errno == EINTR); + + ((ACE_ATM_Addr *)remote_addr) -> set (cli_addr, + ((ACE_ATM_Addr *)remote_addr) -> get_selector ()); + ((ACE_IPC_SAP *)&new_sap) -> set_handle (n_handle); + + return 0; +#elif defined (ACE_HAS_LINUX_ATM) + ACE_UNUSED_ARG (params); + + ACE_HANDLE s_handle = ((ACE_SOCK_Acceptor *) this) -> get_handle (); + struct atm_qos accept_qos = qos.get_qos (); + + if (ACE_OS::setsockopt (s_handle, + SOL_ATM, + SO_ATMQOS, + reinterpret_cast (&accept_qos), + sizeof (accept_qos)) < 0) { + ACE_OS::printf ("Acceptor (accept): error setting Qos"); + } + + return (acceptor_.accept (new_sap.get_stream (), + remote_addr, + timeout, + restart, + reset_new_handle)); +#else + ACE_UNUSED_ARG (new_sap); + ACE_UNUSED_ARG (remote_addr); + ACE_UNUSED_ARG (timeout); + ACE_UNUSED_ARG (restart); + ACE_UNUSED_ARG (reset_new_handle); + ACE_UNUSED_ARG (params); + ACE_UNUSED_ARG (qos); + return (0); +#endif /* ACE_HAS_FORE_ATM_XTI */ +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + + +#endif /* ACE_HAS_ATM */ diff --git a/dep/ACE_wrappers/ace/ATM_Acceptor.h b/dep/ACE_wrappers/ace/ATM_Acceptor.h new file mode 100644 index 000000000..c69e2f854 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Acceptor.h @@ -0,0 +1,123 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file ATM_Acceptor.h + * + * $Id: ATM_Acceptor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//============================================================================= + + +#ifndef ACE_ATM_ACCEPTOR_H +#define ACE_ATM_ACCEPTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_ATM) + +#include "ace/ATM_Stream.h" +#include "ace/ATM_Params.h" +#include "ace/ATM_QoS.h" + +#if defined (ACE_HAS_LINUX_ATM) +#include /**/ "atm.h" +#endif /* ACE_HAS_LINUX_ATM */ + +#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM) +#include "ace/SOCK_Acceptor.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ACE_SOCK_Acceptor ATM_Acceptor; +ACE_END_VERSIONED_NAMESPACE_DECL +#elif defined (ACE_HAS_FORE_ATM_XTI) +#include "ace/TLI_Acceptor.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ACE_TLI_Acceptor ATM_Acceptor; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif // ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations. +class ACE_Time_Value; + +/** + * @class ACE_ATM_Acceptor + * + * @brief Defines the member functions for ACE_ATM_Acceptor abstraction. + * + * This class wraps up the ACE_SOCK_Acceptor and ACE_TLI_Acceptor + * to make the mechanism for the ATM protocol transparent. + */ +class ACE_Export ACE_ATM_Acceptor +{ + +public: + // = Initialization and termination methods. + /// Default constructor. + ACE_ATM_Acceptor (void); + + ~ACE_ATM_Acceptor (); + + /// Initiate a passive mode connection. + ACE_ATM_Acceptor (const ACE_Addr &remote_sap, + int backlog = ACE_DEFAULT_BACKLOG, + ACE_ATM_Params params = ACE_ATM_Params()); + + /// Initiate a passive mode socket. + ACE_HANDLE open (const ACE_Addr &remote_sap, + int backlog = ACE_DEFAULT_BACKLOG, + ACE_ATM_Params params = ACE_ATM_Params()); + + /// Close down the acceptor and release resources. + int close (void); + + // = Passive connection acceptance method. + + /// Accept a new data transfer connection. A @a timeout of 0 means + /// block forever, a @a timeout of {0, 0} means poll. @a restart == 1 + /// means "restart if interrupted." + int accept (ACE_ATM_Stream &new_sap, + ACE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int reset_new_handle = 0, + ACE_ATM_Params params = ACE_ATM_Params(), + ACE_ATM_QoS qos = ACE_ATM_QoS()); + + /// Get the local address currently listening on + int get_local_addr( ACE_ATM_Addr &local_addr ); + + // = Meta-type info + typedef ACE_ATM_Addr PEER_ADDR; + typedef ACE_ATM_Stream PEER_STREAM; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + ATM_Acceptor acceptor_; +}; + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + + +#if defined (__ACE_INLINE__) +#include "ace/ATM_Acceptor.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_ATM */ +#include /**/ "ace/post.h" +#endif /* ACE_ATM_ACCEPTOR_H */ diff --git a/dep/ACE_wrappers/ace/ATM_Acceptor.inl b/dep/ACE_wrappers/ace/ATM_Acceptor.inl new file mode 100644 index 000000000..fa60c4ad8 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Acceptor.inl @@ -0,0 +1,43 @@ +// -*- C++ -*- +// +// $Id: ATM_Acceptor.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_ATM_Acceptor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ATM_Acceptor::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_INLINE +ACE_ATM_Acceptor::ACE_ATM_Acceptor (const ACE_Addr &remote_sap, + int backlog, + ACE_ATM_Params params) +{ + ACE_TRACE ("ACE_ATM_Acceptor::ACE_ATM_Acceptor"); + + //FUZZ: disable check_for_lack_ACE_OS + if (open (remote_sap, backlog, params) < 0) + //FUZZ: enable check_for_lack_ACE_OS + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_ATM_Acceptor::ACE_ATM_Acceptor"))); +} + +ACE_INLINE +int +ACE_ATM_Acceptor::close (void) +{ +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM) + return (acceptor_.close()); +#else + return 0; +#endif // ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ATM_Addr.cpp b/dep/ACE_wrappers/ace/ATM_Addr.cpp new file mode 100644 index 000000000..739a80763 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Addr.cpp @@ -0,0 +1,522 @@ +// $Id: ATM_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $ + +// Defines the Internet domain address family address format. + +#include "ace/ATM_Addr.h" +#if defined (ACE_HAS_ATM) + +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_FORE_ATM_WS2) +#include /**/ "forews2.h" +#endif /* ACE_HAS_FORE_ATM_WS2 */ + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_Addr.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, ATM_Addr, "$Id: ATM_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Addr) + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) +#define BHLI_MAGIC "FORE_ATM" +// This is line rate in cells/s for an OC-3 MM interface. +const long ACE_ATM_Addr::LINE_RATE = 353207; +const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0x1; +const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0x2; +const int ACE_ATM_Addr::DEFAULT_SELECTOR = 0x99; +#elif defined (ACE_HAS_LINUX_ATM) +//pbrandao:for Linux: +//pbrandao:for now stick with current definitions +//pbrandao:see if later need to change +const long ACE_ATM_Addr::LINE_RATE = 353207; +const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0; +const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0; +const int ACE_ATM_Addr::DEFAULT_SELECTOR = 0x99; +#else +const long ACE_ATM_Addr::LINE_RATE = 0L; +const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0; +const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0; +const int ACE_ATM_Addr::DEFAULT_SELECTOR = 0x0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + +// Default constructor + +ACE_ATM_Addr::ACE_ATM_Addr (u_char selector) +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + : ACE_Addr (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + : ACE_Addr (PF_ATMSVC, +#else + : ACE_Addr (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + sizeof this->atm_addr_) +{ + // ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + (void) ACE_OS::memset ((void *) &this->atm_addr_, + 0, + sizeof this->atm_addr_); + this->init (selector); +} + +// Copy constructor. + +ACE_ATM_Addr::ACE_ATM_Addr (const ACE_ATM_Addr &sap, + u_char selector) +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + : ACE_Addr (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + : ACE_Addr (PF_ATMSVC, +#else + : ACE_Addr (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + sizeof this->atm_addr_) +{ + ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + this->set (sap, selector); +#if defined (ACE_HAS_LINUX_ATM) + this->atm_addr_.sockaddratmsvc.sas_family = PF_ATMSVC; + this->atm_addr_.atmsap.blli[0].l3_proto = ATM_L3_NONE; + this->atm_addr_.atmsap.blli[0].l2_proto = ATM_L2_NONE; + this->atm_addr_.atmsap.bhli.hl_type = ATM_HL_NONE; +#endif /* ACE_HAS_LINUX_ATM */ +} + +ACE_ATM_Addr::ACE_ATM_Addr (const ATM_Addr *sap, + u_char selector) +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + : ACE_Addr (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + : ACE_Addr (PF_ATMSVC, +#else + : ACE_Addr (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + sizeof this->atm_addr_) +{ + ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + this->set (sap, selector); +} + + +ACE_ATM_Addr::ACE_ATM_Addr (const ACE_TCHAR sap[], + u_char selector) +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + : ACE_Addr (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + : ACE_Addr (PF_ATMSVC, +#else + : ACE_Addr (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + sizeof this->atm_addr_) +{ + ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr"); + this->set (sap, selector); +} + +ACE_ATM_Addr::~ACE_ATM_Addr (void) +{ +} + +// Return the address. + +void * +ACE_ATM_Addr::get_addr (void) const +{ + ACE_TRACE ("ACE_ATM_Addr::get_addr"); + return (void *) &this->atm_addr_; +} + +void +ACE_ATM_Addr::init (u_char selector) +{ +#if defined (ACE_HAS_FORE_ATM_XTI) + // Note: this approach may be FORE implementation-specific. When we + // bind with tag_addr ABSENT and tag_selector PRESENT, only the + // selector (i.e. address[19]) is used by the TP. The rest of the + // local address is filled in by the TP and can be obtained via the + // 'ret' parameter or with t_getname ()/t_getprotaddr (). + + atm_addr_.addressType = (u_int16_t) AF_ATM; + + atm_addr_.sap.t_atm_sap_addr.SVE_tag_addr = (int8_t) T_ATM_ABSENT; + atm_addr_.sap.t_atm_sap_addr.SVE_tag_selector = (int8_t) T_ATM_PRESENT; + + atm_addr_.sap.t_atm_sap_addr.address_format = (u_int8_t) T_ATM_ENDSYS_ADDR; + atm_addr_.sap.t_atm_sap_addr.address_length = ATMNSAP_ADDR_LEN; + atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1] = selector; + + atm_addr_.sap.t_atm_sap_layer2.SVE_tag = (int8_t) T_ATM_ABSENT; + atm_addr_.sap.t_atm_sap_layer3.SVE_tag = (int8_t) T_ATM_ABSENT; + + atm_addr_.sap.t_atm_sap_appl.SVE_tag = (int8_t) T_ATM_PRESENT; + atm_addr_.sap.t_atm_sap_appl.ID_type = (u_int8_t) T_ATM_USER_APP_ID; + + ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_appl.ID.user_defined_ID, + BHLI_MAGIC, + sizeof atm_addr_.sap.t_atm_sap_appl.ID); +#elif defined (ACE_HAS_FORE_ATM_WS2) + ACE_OS::memset ((void *)&atm_addr_, 0, sizeof atm_addr_); + atm_addr_.satm_number.Addr[ ATM_ADDR_SIZE - 1 ] = (char)selector; + atm_addr_.satm_family = AF_ATM; + atm_addr_.satm_number.AddressType = ATM_NSAP; + atm_addr_.satm_number.NumofDigits = ATM_ADDR_SIZE; + atm_addr_.satm_blli.Layer2Protocol = SAP_FIELD_ABSENT; + atm_addr_.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT; + atm_addr_.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT; + + // Need to know the correspondence. + //atm_addr_.sap.t_atm_sap_appl.SVE_tag = (int8_t) T_ATM_PRESENT; + //atm_addr_.sap.t_atm_sap_appl.ID_type = (u_int8_t) T_ATM_USER_APP_ID; + //ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_appl.ID.user_defined_ID, + // BHLI_MAGIC, + // sizeof atm_addr_.sap.t_atm_sap_appl.ID); +#elif defined (ACE_HAS_LINUX_ATM) + atm_addr_.sockaddratmsvc.sas_family = AF_ATMSVC; + atm_addr_.sockaddratmsvc.sas_addr.prv[ATM_ESA_LEN - 1] = (char)selector; + atm_addr_.atmsap.blli[0].l3_proto = ATM_L3_NONE; + atm_addr_.atmsap.blli[0].l2_proto = ATM_L2_NONE; + atm_addr_.atmsap.bhli.hl_type = ATM_HL_NONE; +#else + ACE_UNUSED_ARG (selector); +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +int +ACE_ATM_Addr::set (const ACE_ATM_Addr &sap, + u_char selector) +{ + ACE_TRACE ("ACE_ATM_Addr::set"); + + this->init (selector); + + this->ACE_Addr::base_set (sap.get_type (), + sap.get_size ()); + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + ACE_ASSERT (sap.get_type () == AF_ATM); +#elif defined (ACE_HAS_LINUX_ATM) + ACE_ASSERT (sap.get_type () == PF_ATMSVC); +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */ + + (void) ACE_OS::memcpy ((void *) &this->atm_addr_, + (void *) &sap.atm_addr_, + sizeof this->atm_addr_); + return 0; +} + +int +ACE_ATM_Addr::set (const ATM_Addr *sap, + u_char selector) +{ + ACE_TRACE ("ACE_ATM_Addr::set"); + + this->init (selector); + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + this->ACE_Addr::base_set (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + this->ACE_Addr::base_set (PF_ATMSVC, +#else + this->ACE_Addr::base_set (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */ + sizeof (*sap)); + + (void) ACE_OS::memcpy ((void *) &this->atm_addr_, + (void *) sap, + sizeof this->atm_addr_); + return 0; +} + +int +ACE_ATM_Addr::set (const ACE_TCHAR address[], + u_char selector) +{ + ACE_TRACE ("ACE_ATM_Addr::set"); + int ret; + + this->init (selector); + +#if defined (ACE_HAS_FORE_ATM_XTI) + atm_addr_.sap.t_atm_sap_addr.SVE_tag_addr = + (int8_t) T_ATM_PRESENT; +#endif /* ACE_HAS_FORE_ATM_XTI */ + + ret = this -> string_to_addr (address); + this -> set_selector (selector); + return ret; +} + +// Transform the string into the current addressing format. + +int +ACE_ATM_Addr::string_to_addr (const ACE_TCHAR sap[]) +{ + ACE_TRACE ("ACE_ATM_Addr::string_to_addr"); + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + this->ACE_Addr::base_set (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + this->ACE_Addr::base_set (PF_ATMSVC, +#else + this->ACE_Addr::base_set (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + sizeof this->atm_addr_); +#if defined (ACE_HAS_FORE_ATM_XTI) + struct hostent *entry; + struct atmnsap_addr *nsap; + + // Yow, someone gave us a NULL ATM address! + if (sap == 0) + { + errno = EINVAL; + return -1; + } + else if ((entry = gethostbyname_atmnsap ((ACE_TCHAR *)sap)) != 0) + { + ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_addr.address, + entry->h_addr_list[0], + ATMNSAP_ADDR_LEN - 1); + } + else if ((nsap = atmnsap_addr (sap)) != 0) + { + ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_addr.address, + nsap->atmnsap, + ATMNSAP_ADDR_LEN); + } + else { + errno = EINVAL; + return -1; + } +#elif defined (ACE_HAS_FORE_ATM_WS2) + DWORD dwValue; + HANDLE hLookup; + WSAQUERYSETW qsRestrictions; + CSADDR_INFO csaBuffer; + WCHAR tmpWStr[100]; + + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, sap, -1, tmpWStr, 100); + + csaBuffer.LocalAddr.iSockaddrLength = sizeof (struct sockaddr_atm); + csaBuffer.LocalAddr.lpSockaddr = (struct sockaddr *)&atm_addr_; + csaBuffer.RemoteAddr.iSockaddrLength = sizeof (struct sockaddr_atm); + csaBuffer.RemoteAddr.lpSockaddr = (struct sockaddr *)&atm_addr_; + + qsRestrictions.dwSize = sizeof (WSAQUERYSETW); + qsRestrictions.lpszServiceInstanceName = 0; + qsRestrictions.lpServiceClassId = &FORE_NAME_CLASS; + qsRestrictions.lpVersion = 0; + qsRestrictions.lpszComment = 0; + qsRestrictions.dwNameSpace = FORE_NAME_SPACE; + qsRestrictions.lpNSProviderId = 0; + qsRestrictions.lpszContext = L""; + qsRestrictions.dwNumberOfProtocols = 0; + qsRestrictions.lpafpProtocols = 0; + qsRestrictions.lpszQueryString = tmpWStr; + qsRestrictions.dwNumberOfCsAddrs = 1; + qsRestrictions.lpcsaBuffer = &csaBuffer; + qsRestrictions.lpBlob = 0; //&blob; + + if (::WSALookupServiceBeginW (&qsRestrictions, LUP_RETURN_ALL, &hLookup) + == SOCKET_ERROR) { + ACE_OS::printf ("Error: WSALookupServiceBeginW failed! %d\n", + ::WSAGetLastError ()); + return -1; + } + + dwValue = sizeof (WSAQUERYSETW); + + if (::WSALookupServiceNextW (hLookup, 0, &dwValue, &qsRestrictions) + == SOCKET_ERROR) { + if (WSAGetLastError () != WSA_E_NO_MORE) { + ACE_OS::printf ("Error: WSALookupServiceNextW failed! %d\n", + ::WSAGetLastError ()); + return -1; + } + } + + if (WSALookupServiceEnd (hLookup) == SOCKET_ERROR) { + ACE_OS::printf ("Error : WSALookupServiceEnd failed! %d \n", + ::WSAGetLastError ()); + errno = EINVAL; + return -1; + } +#elif defined (ACE_HAS_LINUX_ATM) + if (sap == 0 || !ACE_OS::strcmp (sap,"")) { + errno = EINVAL; + return -1; + } + + if (text2atm ((ACE_TCHAR *)sap, + (struct sockaddr *)& (atm_addr_.sockaddratmsvc), + sizeof (atm_addr_.sockaddratmsvc), + T2A_SVC | T2A_NAME) < 0) { + ACE_DEBUG (LM_DEBUG, + "Error : text2atm failed!\n"); + errno = EINVAL; + return -1; + } +#else + ACE_UNUSED_ARG (sap); + + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM) + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */ +} + +// Transform the current address into string format. + +int +ACE_ATM_Addr::addr_to_string (ACE_TCHAR addr[], + size_t addrlen) const +{ + ACE_TRACE ("ACE_ATM_Addr::addr_to_string"); + +#if defined (ACE_HAS_FORE_ATM_XTI) + ACE_TCHAR buffer[MAXNAMELEN + 1]; + struct atmnsap_addr nsap; + ACE_OS::memcpy (nsap.atmnsap, + atm_addr_.sap.t_atm_sap_addr.address, + ATMNSAP_ADDR_LEN); + ACE_OS::sprintf (buffer, + ACE_TEXT ("%s"), + atmnsap_ntoa (nsap)); + + size_t total_len = ACE_OS::strlen (buffer) + sizeof ('\0'); + + if (addrlen < total_len) + return -1; + else + ACE_OS::strcpy (addr, buffer); + + return 0; +#elif defined (ACE_HAS_FORE_ATM_WS2) + ACE_TCHAR buffer[MAXNAMELEN + 1]; + int i; + + if (addrlen < ATM_ADDR_SIZE + 1) + return -1; + + for (i = 0; i < ATM_ADDR_SIZE; i++) { + buffer[ i * 3 ] = '\0'; + ACE_OS::sprintf (buffer, ACE_TEXT ("%s%02x."), + buffer, + atm_addr_.satm_number.Addr[ i ]); + } + + buffer[ ATM_ADDR_SIZE * 3 - 1 ] = '\0'; + ACE_OS::strcpy (addr, buffer); + + return 0; +#elif defined (ACE_HAS_LINUX_ATM) + ACE_TCHAR buffer[MAX_ATM_ADDR_LEN + 1]; + int total_len; + if ((total_len = atm2text (buffer, + sizeof buffer, + (struct sockaddr *)& (atm_addr_.sockaddratmsvc), + A2T_PRETTY)) < 0) { + ACE_DEBUG ((LM_DEBUG,"ACE_ATM_Addr (addr_to_string): atm2text failed\n")); + return -1; + } + if (addrlen < (size_t)total_len) + return -1; + else + ACE_OS::strcpy (addr, + buffer); + + return 0; +#else + ACE_UNUSED_ARG (addr); + ACE_UNUSED_ARG (addrlen); + return -1; +#endif /* ACE_HAS_FORE_ATM_XTI && ACE_HAS_FORE_ATM_WS2 */ +} + +const ACE_TCHAR * +ACE_ATM_Addr::addr_to_string (void) const +{ + ACE_TRACE ("ACE_ATM_Addr::addr_to_string"); + + static ACE_TCHAR addr[MAXHOSTNAMELEN + 1]; + if (this->addr_to_string (addr, + MAXHOSTNAMELEN + 1) < 0) + return 0; + + return addr; +} + +// Set a pointer to the address. +void +ACE_ATM_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_ATM_Addr::set_addr"); + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + this->ACE_Addr::base_set (AF_ATM, +#elif defined (ACE_HAS_LINUX_ATM) + this->ACE_Addr::base_set (PF_ATMSVC, +#else + this->ACE_Addr::base_set (AF_UNSPEC, +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_WS2 */ + len); + ACE_OS::memcpy ((void *) &this->atm_addr_, + (void *) addr, len); +} + +// Compare two addresses for inequality. + +bool +ACE_ATM_Addr::operator != (const ACE_ATM_Addr &sap) const +{ + ACE_TRACE ("ACE_ATM_Addr::operator !="); + return ! ((*this) == sap); +} + +// Compare two addresses for equality. + +bool +ACE_ATM_Addr::operator == (const ACE_ATM_Addr &sap) const +{ + ACE_TRACE ("ACE_ATM_Addr::operator =="); + +#if defined (ACE_HAS_LINUX_ATM) + return (atm_equal ((const struct sockaddr *)& (this->atm_addr_.sockaddratmsvc), + (const struct sockaddr *)& (sap.atm_addr_.sockaddratmsvc), + 0, + 0) + && + sap_equal (& (this->atm_addr_.atmsap), + & (sap.atm_addr_.atmsap), + 0)); +#else + return ACE_OS::memcmp (&atm_addr_, + &sap.atm_addr_, + sizeof (ATM_Addr)) == 0; +#endif /* ACE_HAS_LINUX_ATM */ +} + +void +ACE_ATM_Addr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ATM_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_TCHAR s[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16]; + ACE_OS::sprintf (s, + ACE_TEXT ("%s"), + this->addr_to_string ()); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s"), s)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_ATM */ diff --git a/dep/ACE_wrappers/ace/ATM_Addr.h b/dep/ACE_wrappers/ace/ATM_Addr.h new file mode 100644 index 000000000..7fa93f149 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Addr.h @@ -0,0 +1,197 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file ATM_Addr.h + * + * $Id: ATM_Addr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//========================================================================== + +#ifndef ACE_ATM_ADDR_H +#define ACE_ATM_ADDR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_ATM) + +#include /**/ "ace/ACE_export.h" +#include "ace/Addr.h" + +#if defined (ACE_HAS_FORE_ATM_XTI) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ATMSAPAddress ATM_Addr; +ACE_END_VERSIONED_NAMESPACE_DECL +#elif defined (ACE_HAS_FORE_ATM_WS2) +#define FORE_NAME_SPACE NS_ALL +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef struct sockaddr_atm ATM_Addr; +ACE_END_VERSIONED_NAMESPACE_DECL +#elif defined (ACE_HAS_LINUX_ATM) + +#include /**/ "atm.h" + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +//pbrandao:as Linux has this 2 structs separeted we "link it" here +typedef struct _linux_atm_addr +{ + struct sockaddr_atmsvc sockaddratmsvc; + struct atm_sap atmsap; +} ATM_Addr; +#else +typedef int ATM_Addr; +#endif /* ACE_HAS_FORE_ATM_XTI/ACE_HAS_FORE_ATM_WS2/ACE_HAS_LINUX_ATM */ + +/** + * @class ACE_ATM_Addr + * + * @brief Defines the ATM domain address family address format. + */ +class ACE_Export ACE_ATM_Addr : public ACE_Addr +{ +public: + // Constants used for ATM options + static const long LINE_RATE; + static const int OPT_FLAGS_CPID; + static const int OPT_FLAGS_PMP; + static const int DEFAULT_SELECTOR; + + // = Initialization methods. + /// Default constructor. + ACE_ATM_Addr (u_char selector = DEFAULT_SELECTOR); + + /// Copy constructor. + ACE_ATM_Addr (const ACE_ATM_Addr &, + u_char selector = DEFAULT_SELECTOR); + + /** + * Creates an ACE_ATM_Addr from an ATMSAPAddress structure. This + * is vendor specific (FORE systems). May need to change when other + * vendors are supported. + */ + ACE_ATM_Addr (const ATM_Addr *, + u_char selector = DEFAULT_SELECTOR); + + /** + * Initializes an ACE_ATM_Addr from the which can be + * "atm-address" (e.g., + * "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname" + * (e.g., "frisbee.cs.wustl.edu"). + */ + ACE_ATM_Addr (const ACE_TCHAR sap[], + u_char selector = DEFAULT_SELECTOR); + + /// Default dtor. + ~ACE_ATM_Addr (void); + + // = Initialization methods (useful after object construction). + /// Default initialization for non-address values (e.g., + /// t_atm_sap_addr.SVE_tag_addr, t_atm_sap_addr.SVE_tag_selector) + void init (u_char selector = DEFAULT_SELECTOR); + + /// Initializes from another ACE_ATM_Addr. + int set (const ACE_ATM_Addr &, + u_char selector = DEFAULT_SELECTOR); + + /** + * Initializes an ACE_ATM_Addr from an ATMSAPAddress/sockaddr_atm + * structure. This is vendor specific (FORE systems). May need to + * change when other vendors are supported. + */ + int set (const ATM_Addr *, + u_char selector = DEFAULT_SELECTOR); + + /** + * Initializes an ACE_ATM_Addr from the which can be + * "atm-address" (e.g., + * "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname" + * (e.g., "frisbee.cs.wustl.edu"). + */ + int set (const ACE_TCHAR sap[], + u_char selector = DEFAULT_SELECTOR); + + /** + * Initializes an ACE_ATM_Addr from the which can be + * "atm-address" (e.g., + * "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname" + * (e.g., "frisbee.cs.wustl.edu"). + */ + virtual int string_to_addr (const ACE_TCHAR sap[]); + + /** + * Return the character representation of the ATM address (e.g., + * "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") storing it in + * the @a addr (which is assumed to be bytes long). This + * version is reentrant. Returns -1 if the of the @a addr + * is too small, else 0. + */ + virtual int addr_to_string (ACE_TCHAR addr[], + size_t addrlen) const; + + /** + * Return the character representation of the ATM address (e.g., + * "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00"). Returns -1 + * if the of the is too small, else 0.(This version + * is non-reentrant since it returns a pointer to a static data + * area.) + */ + const ACE_TCHAR *addr_to_string (void) const; + + /// Return a pointer to the underlying network address. + virtual void *get_addr (void) const; + + /// Set a pointer to the address. + virtual void set_addr (void *, int); + + /// Return the selector for network address. + u_char get_selector (void) const; + + /// Set the selector for the network address. + void set_selector (u_char selector); + + /** + * Compare two addresses for equality. The addresses are considered + * equal if they contain the same ATM address. Q: Is there any + * other check for equality needed for ATM? + */ + bool operator == (const ACE_ATM_Addr &SAP) const; + + /// Compare two addresses for inequality. + bool operator != (const ACE_ATM_Addr &SAP) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +// char *construct_options (ACE_HANDLE fd, +// int qos_kb, +// int flags, +// long *optsize); +// // Construct options for ATM connections + +private: + ATM_Addr atm_addr_; +}; + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + + +#if defined (__ACE_INLINE__) +#include "ace/ATM_Addr.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_ATM */ +#include /**/ "ace/post.h" +#endif /* ACE_ATM_ADDR_H */ diff --git a/dep/ACE_wrappers/ace/ATM_Addr.inl b/dep/ACE_wrappers/ace/ATM_Addr.inl new file mode 100644 index 000000000..55f43d661 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Addr.inl @@ -0,0 +1,37 @@ +// -*- C++ -*- +// +// $Id: ATM_Addr.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE u_char +ACE_ATM_Addr::get_selector (void) const +{ + ACE_TRACE ("ACE_ATM_Addr::get_selector"); +#if defined (ACE_HAS_FORE_ATM_XTI) + return atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1]; +#elif defined (ACE_HAS_FORE_ATM_WS2) + return atm_addr_.satm_number.Addr[ ATM_ADDR_SIZE - 1 ]; +#elif defined (ACE_HAS_LINUX_ATM) + return atm_addr_.sockaddratmsvc.sas_addr.prv[ATM_ESA_LEN - 1]; +#else + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +ACE_INLINE void +ACE_ATM_Addr::set_selector (u_char selector) +{ + ACE_TRACE ("ACE_ATM_Addr::set_selector"); +#if defined (ACE_HAS_FORE_ATM_XTI) + atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1] = selector; +#elif defined (ACE_HAS_FORE_ATM_WS2) + atm_addr_.satm_number.Addr[ ATM_ADDR_SIZE - 1 ] = selector; +#elif defined (ACE_HAS_LINUX_ATM) + atm_addr_.sockaddratmsvc.sas_addr.prv[ATM_ESA_LEN - 1] = selector; +#else + ACE_UNUSED_ARG (selector); +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ATM_Connector.cpp b/dep/ACE_wrappers/ace/ATM_Connector.cpp new file mode 100644 index 000000000..c1ce226ad --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Connector.cpp @@ -0,0 +1,138 @@ +// ATM_Connector.cpp +// $Id: ATM_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ATM_Connector.h" +#if defined (ACE_HAS_ATM) + +#include "ace/Handle_Set.h" + +ACE_RCSID(ace, ATM_Connector, "$Id: ATM_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_Connector.inl" +#endif /* __ACE_INLINE__ */ + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Connector) + +ACE_ATM_Connector::ACE_ATM_Connector (void) +{ + ACE_TRACE ("ACE_ATM_Connector::ACE_ATM_Connector"); +} + +// Actively connect and produce a new ACE_ATM_Stream if things go well... +// Connect the to the , waiting up to +// amount of time if necessary. + +int +ACE_ATM_Connector::connect (ACE_ATM_Stream &new_stream, + const ACE_ATM_Addr &remote_sap, + ACE_ATM_Params params, + ACE_ATM_QoS options, + ACE_Time_Value *timeout, + const ACE_ATM_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_ATM_Connector::connect"); +#if defined (ACE_HAS_FORE_ATM_XTI) + return connector_.connect(new_stream.get_stream(), + remote_sap, + timeout, + local_sap, + reuse_addr, + flags, + perms, + params.get_device(), + params.get_info(), + params.get_rw_flag(), + params.get_user_data(), + &options.get_qos()); +#elif defined (ACE_HAS_FORE_ATM_WS2) + ACE_DEBUG(LM_DEBUG, + ACE_TEXT ("ATM_Connector(connect): set QoS parameters\n" )); + + ACE_HANDLE s = new_stream.get_handle(); + struct sockaddr_atm *saddr = ( struct sockaddr_atm *)remote_sap.get_addr(); + ACE_QoS cqos = options.get_qos(); + + ACE_QoS_Params qos_params = ACE_QoS_Params(0, + 0, + &cqos, + 0, + 0); + + ACE_DEBUG(LM_DEBUG, + ACE_TEXT ("ATM_Connector(connect): connecting...\n")); + + int result = ACE_OS::connect( s, + ( struct sockaddr *)saddr, + sizeof( struct sockaddr_atm ), + qos_params ); + + if ( result != 0 ) + ACE_OS::printf( "ATM_Connector(connect): connection failed, %d\n", + ::WSAGetLastError()); + + return result; +#elif defined (ACE_HAS_LINUX_ATM) + ACE_UNUSED_ARG (params); + ACE_UNUSED_ARG (timeout); + ACE_UNUSED_ARG (reuse_addr); + ACE_UNUSED_ARG (perms); + ACE_UNUSED_ARG (flags); + + ACE_HANDLE handle = new_stream.get_handle(); + ATM_QoS qos =options.get_qos(); + ATM_Addr *local_addr=(ATM_Addr*)local_sap.get_addr(), + *remote_addr=(ATM_Addr*)remote_sap.get_addr(); + + if (ACE_OS::setsockopt(handle, + SOL_ATM, + SO_ATMSAP, + reinterpret_cast (&(local_addr->atmsap)), + sizeof(local_addr->atmsap)) < 0) { + ACE_OS::printf( "ATM_Connector(connect): unable to set atmsap %d\nContinuing...", + errno); + } + if (ACE_OS::setsockopt(handle, + SOL_ATM, + SO_ATMQOS, + reinterpret_cast (&qos), + sizeof(qos)) < 0) { + ACE_DEBUG((LM_DEBUG,ACE_TEXT ("ATM_Connector(connect): unable to set qos %d\n"), + errno)); + return -1; + } + + int result = ACE_OS::connect(handle, + (struct sockaddr *)&(remote_addr->sockaddratmsvc), + sizeof( remote_addr->sockaddratmsvc)); + + if ( result != 0 ) + ACE_DEBUG(LM_DEBUG, + ACE_TEXT ("ATM_Connector(connect): connection failed, %d\n"), + errno); + + return result; +#else + ACE_UNUSED_ARG (new_stream); + ACE_UNUSED_ARG (remote_sap); + ACE_UNUSED_ARG (params); + ACE_UNUSED_ARG (options); + ACE_UNUSED_ARG (timeout); + ACE_UNUSED_ARG (local_sap); + ACE_UNUSED_ARG (reuse_addr); + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (perms); + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_ATM */ diff --git a/dep/ACE_wrappers/ace/ATM_Connector.h b/dep/ACE_wrappers/ace/ATM_Connector.h new file mode 100644 index 000000000..cbeedeea7 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Connector.h @@ -0,0 +1,164 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file ATM_Connector.h + * + * $Id: ATM_Connector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//============================================================================= + +#ifndef ACE_ATM_CONNECTOR_H +#define ACE_ATM_CONNECTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_ATM) + +#include "ace/ATM_Stream.h" +#include "ace/ATM_Params.h" +#include "ace/ATM_QoS.h" + +#if defined (ACE_WIN32) || defined (ACE_HAS_LINUX_ATM) +#include "ace/SOCK_Connector.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ACE_SOCK_Connector ATM_Connector; +ACE_END_VERSIONED_NAMESPACE_DECL +#else +#include "ace/XTI_ATM_Mcast.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ACE_XTI_ATM_Mcast ATM_Connector; +// Open versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL +#endif + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_ATM_Connector + * + * @brief Defines an active connection factory for the ACE_ATM C++ + * wrappers. + */ +class ACE_Export ACE_ATM_Connector +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_ATM_Connector (void); + + /** + * Actively connect and produce a @a new_stream if things go well. + * The @a remote_sap is the address that we are trying to connect + * with. The are the parameters needed for either socket + * or XTI/ATM connections. The @a timeout is the amount of time to + * wait to connect. If it's 0 then we block indefinitely. If + * *timeout == {0, 0} then the connection is done using non-blocking + * mode. In this case, if the connection can't be made immediately + * the value of -1 is returned with @c errno == EWOULDBLOCK. If + * *timeout > {0, 0} then this is the maximum amount of time to wait before + * timing out. If the time expires before the connection is made + * @c errno == ETIME. The @a local_sap is the value of local address + * to bind to. If it's the default value of then + * the user is letting the OS do the binding. If @a reuse_addr == 1 + * then the is reused, even if it hasn't been cleanedup yet. + */ + ACE_ATM_Connector (ACE_ATM_Stream &new_stream, + const ACE_ATM_Addr &remote_sap, + ACE_ATM_Params params = ACE_ATM_Params(), + ACE_ATM_QoS options = ACE_ATM_QoS(), + ACE_Time_Value *timeout = 0, + const ACE_ATM_Addr &local_sap = ACE_ATM_Addr( "", 0 ), + int reuse_addr = 0, +#if defined (ACE_WIN32) + int flags = 0, +#else + int flags = O_RDWR, +#endif /* ACE_WIN32 */ + int perms = 0); + + /** + * Actively connect and produce a @a new_stream if things go well. + * The @a remote_sap is the address that we are trying to connect + * with. The are the parameters needed for either socket + * or XTI/ATM connections. The @a timeout is the amount of time to + * wait to connect. If it's 0 then we block indefinitely. If + * *timeout == {0, 0} then the connection is done using non-blocking + * mode. In this case, if the connection can't be made immediately + * the value of -1 is returned with @c errno == EWOULDBLOCK. If + * *timeout > {0, 0} then this is the maximum amount of time to wait before + * timing out. If the time expires before the connection is made + * @c errno == ETIME. The @a local_sap is the value of local address + * to bind to. If it's the default value of then + * the user is letting the OS do the binding. If @a reuse_addr == 1 + * then the is reused, even if it hasn't been cleanedup yet. + */ + int connect (ACE_ATM_Stream &new_stream, + const ACE_ATM_Addr &remote_sap, + ACE_ATM_Params params = ACE_ATM_Params(), + ACE_ATM_QoS options = ACE_ATM_QoS(), + ACE_Time_Value *timeout = 0, + const ACE_ATM_Addr &local_sap = ACE_ATM_Addr( "", + 0 ), + int reuse_addr = 0, +#if defined (ACE_WIN32) + int flags = 0, +#else + int flags = O_RDWR, +#endif /* ACE_WIN32 */ + int perms = 0); + + /** + * Try to complete a non-blocking connection. + * If connection completion is successful then @a new_stream contains + * the connected ACE_SOCK_Stream. If @a remote_sap is non-NULL then it + * will contain the address of the connected peer. + */ + int complete (ACE_ATM_Stream &new_stream, + ACE_ATM_Addr *remote_sap, + ACE_Time_Value *tv); + + /** + * Actively add a leaf to the root (i.e., point-to-multipoint). The + * @a remote_sap is the address of the leaf that we + * are trying to add. + */ + int add_leaf (ACE_ATM_Stream ¤t_stream, + const ACE_Addr &remote_sap, + ACE_ATM_QoS &qos); + + /// Resets any event associations on this handle + int reset_new_handle (ACE_HANDLE handle); + + // = Meta-type info + typedef ACE_ATM_Addr PEER_ADDR; + typedef ACE_ATM_Stream PEER_STREAM; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + ATM_Connector connector_; +}; + +// Open versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/ATM_Connector.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_ATM */ +#include /**/ "ace/post.h" +#endif /* ACE_ATM_CONNECTOR_H */ diff --git a/dep/ACE_wrappers/ace/ATM_Connector.inl b/dep/ACE_wrappers/ace/ATM_Connector.inl new file mode 100644 index 000000000..0b89cbf08 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Connector.inl @@ -0,0 +1,132 @@ +// -*- C++ -*- +// +// $Id: ATM_Connector.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_ATM_Connector::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ATM_Connector::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_INLINE +ACE_ATM_Connector::ACE_ATM_Connector (ACE_ATM_Stream &new_stream, + const ACE_ATM_Addr &remote_sap, + ACE_ATM_Params params, + ACE_ATM_QoS options, + ACE_Time_Value *timeout, + const ACE_ATM_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_ATM_Connector::ACE_ATM_Connector"); + if ((ACE_HANDLE)this->connect (new_stream, + remote_sap, + params, + options, + timeout, + local_sap, + reuse_addr, + flags, + perms) == ACE_INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME)) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_ATM_Stream::ACE_ATM_Stream"))); +} + +// Try to complete a non-blocking connection. + +ACE_INLINE +int +ACE_ATM_Connector::complete (ACE_ATM_Stream &new_stream, + ACE_ATM_Addr *remote_sap, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_ATM_Connector::complete"); +#if defined (ACE_HAS_ATM) + return connector_.complete(new_stream.get_stream(), + remote_sap, + tv); +#else + ACE_UNUSED_ARG(new_stream); + ACE_UNUSED_ARG(remote_sap); + ACE_UNUSED_ARG(tv); + return 0; +#endif +} + +ACE_INLINE +int +ACE_ATM_Connector::add_leaf (ACE_ATM_Stream ¤t_stream, + const ACE_Addr &remote_sap, + ACE_ATM_QoS &qos) +{ + ACE_TRACE ("ACE_ATM_Connector::add_leaf"); +#if defined (ACE_HAS_FORE_ATM_XTI) + return connector_.add_leaf(current_stream.get_stream(), + remote_sap, + leaf_id, + timeout); +#elif defined (ACE_HAS_FORE_ATM_WS2) + struct sockaddr_atm *saddr = (struct sockaddr_atm *)remote_sap.get_addr(); + ACE_QoS cqos = qos.get_qos(); + int addr_len = sizeof( struct sockaddr_atm ); + + ACE_QoS_Params qos_params(0, + 0, + &cqos, + 0, + (JL_SENDER_ONLY)); + + ACE_OS::printf( "ATM_Connector::add_leaf: connecting...\n" ); + + ACE_HANDLE result = ACE_OS::join_leaf(current_stream.get_handle(), + (struct sockaddr *)saddr, + addr_len, + qos_params); + + if ( result == ACE_INVALID_HANDLE ) + ACE_OS::printf( "ATM_Connector(add_leaf): connection failed, %d\n", + ::WSAGetLastError()); + + return (result != ACE_INVALID_HANDLE); +#elif defined (ACE_HAS_LINUX_ATM) + ACE_OS::printf("ATM_Connector(add_leaf): not yet implemented in Linux \n"); + + ACE_UNUSED_ARG(current_stream); + ACE_UNUSED_ARG(remote_sap); + ACE_UNUSED_ARG(leaf_id); + ACE_UNUSED_ARG(timeout); + + return 0; +#else + ACE_UNUSED_ARG(current_stream); + ACE_UNUSED_ARG(remote_sap); + ACE_UNUSED_ARG(leaf_id); + ACE_UNUSED_ARG(timeout); + return 0; +#endif +} + +ACE_INLINE +int +ACE_ATM_Connector::reset_new_handle (ACE_HANDLE handle) +{ +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) + // Reset the event association + return ::WSAEventSelect ((SOCKET) handle, + 0, + 0); +#else /* !defined ACE_HAS_WINSOCK2 */ + ACE_UNUSED_ARG (handle); + return 0; +#endif /* ACE_WIN32 */ +} + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ATM_Params.cpp b/dep/ACE_wrappers/ace/ATM_Params.cpp new file mode 100644 index 000000000..70a05f1d7 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Params.cpp @@ -0,0 +1,20 @@ +// $Id: ATM_Params.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ATM_Params.h" + +#if defined (ACE_HAS_ATM) + +ACE_RCSID(ace, ATM_Params, "$Id: ATM_Params.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_Params.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Params) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_ATM */ + diff --git a/dep/ACE_wrappers/ace/ATM_Params.h b/dep/ACE_wrappers/ace/ATM_Params.h new file mode 100644 index 000000000..d1e8c9231 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Params.h @@ -0,0 +1,214 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file ATM_Params.h + * + * $Id: ATM_Params.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//========================================================================== + + +#ifndef ACE_ATM_PARAMS_H +#define ACE_ATM_PARAMS_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_ATM) + +#include /**/ "ace/ACE_export.h" + +#if defined (ACE_HAS_FORE_ATM_XTI) +#include "ace/TLI.h" +#define ATM_PROTOCOL_DEFAULT 0 +typedef struct t_info Param_Info; +typedef struct netbuf Param_Udata; +#elif defined (ACE_HAS_FORE_ATM_WS2) +#include "ace/SOCK.h" +#define ATM_PROTOCOL_DEFAULT ATMPROTO_AAL5 +#define ACE_XTI_ATM_DEVICE "" +typedef int Param_Info; +typedef int Param_Udata; +#elif defined (ACE_HAS_LINUX_ATM) +#include /**/ "atm.h" +#define AF_ATM PF_ATMSVC +#define ACE_XTI_ATM_DEVICE "" +#define ATM_PROTOCOL_DEFAULT ATM_AAL5 +typedef int Param_Info; +typedef int Param_Udata; +#else +#define ACE_XTI_ATM_DEVICE "" +typedef int Param_Info; +typedef int Param_Udata; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_ATM_Params + * + * @brief Wrapper class that simplifies the information passed to the ATM + * enabled ACE_ATM_Connector class. + */ +class ACE_Export ACE_ATM_Params +{ +public: + /** + * Initialize the data members. This class combines options from + * ACE_SOCK_Connector (@a protocol_family, @a protocol, , + * @a protocol_info, , and @a flags) and + * ACE_TLI_Connector (, , , , and ) + * so that either mechanism can be used transparently for ATM. + */ + ACE_ATM_Params (int rw_flag = 1, + const char device[] = ACE_XTI_ATM_DEVICE, + Param_Info *info = 0, + Param_Udata *udata = 0, + int oflag = O_RDWR, + int protocol_family = AF_ATM, + int protocol = ATM_PROTOCOL_DEFAULT, + int type = +#if defined (ACE_HAS_LINUX_ATM) + SOCK_DGRAM, +#else + SOCK_RAW, +#endif /* ACE_HAS_LINUX_ATM */ + ACE_Protocol_Info *protocol_info = 0, + ACE_SOCK_GROUP g = 0, + u_long flags + = ACE_FLAG_MULTIPOINT_C_ROOT + | ACE_FLAG_MULTIPOINT_D_ROOT, // connector by default + int reuse_addr = 0); + + /// Destructor. + ~ACE_ATM_Params (); + + /// Get protocol family. + int get_protocol_family (void) const; + + /// Set protocol family. + void set_protocol_family (int); + + /// Get protocol. + int get_protocol (void) const; + + /// Set protocol. + void set_protocol (int); + + /// Get type. + int get_type (void) const; + + /// Set type. + void set_type (int); + + /// Get protocol info. + ACE_Protocol_Info *get_protocol_info( void ); + + /// Set protocol info. + void set_protocol_info( ACE_Protocol_Info *); + + /// Get socket group. + ACE_SOCK_GROUP get_sock_group( void ); + + /// Set socket group. + void set_sock_group( ACE_SOCK_GROUP ); + + /// Get socket flags. + u_long get_flags( void ); + + /// Set socket flags. + void set_flags( u_long ); + + /// Get reuse_addr flag. + int get_reuse_addr (void) const; + + /// Set reuse_addr flag. + void set_reuse_addr (int); + + /// Get device. + const char* get_device (void) const; + + /// Get info. + Param_Info* get_info (void) const; + + /// Set info. + void set_info (Param_Info *); + + /// Get r/w flag. + int get_rw_flag (void) const; + + /// Set r/w flag. + void set_rw_flag (int); + + /// Get user data. + Param_Udata* get_user_data (void) const; + + /// Set user data. + void set_user_data (Param_Udata*); + + /// Get open flag. + int get_oflag (void) const; + + /// Set open flag. + void set_oflag (int); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Protocol family for sockets connections. + int protocol_family_; + + /// Protocol for sockets connections. + int protocol_; + + /// Type for opening sockets. + int type_; + + /// Information about the protocol. + ACE_Protocol_Info *protocol_info_; + + /// Socket group used (for sockets only). + ACE_SOCK_GROUP group_; + + /// Flags for sockets (for sockets only). + u_long flags_; + + /// Flag for reusing address for opening sockets. + int reuse_addr_; + + /// Device name for XTI/ATM connections. + const char *device_; + + /// Info for XTI/ATM connections. + Param_Info *info_; + + /// R/W flag for XTI/ATM connections. + int rw_flag_; + + /// User data for XTI/ATM connections. + Param_Udata *udata_; + + /// Open flag for XTI/ATM connections. + int oflag_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/ATM_Params.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_ATM */ +#include /**/ "ace/post.h" +#endif /* ACE_ATM_PARAMS_H */ diff --git a/dep/ACE_wrappers/ace/ATM_Params.inl b/dep/ACE_wrappers/ace/ATM_Params.inl new file mode 100644 index 000000000..de2a4d451 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Params.inl @@ -0,0 +1,235 @@ +// -*- C++ -*- +// +// $Id: ATM_Params.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_ATM_Params::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ATM_Params::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_INLINE +ACE_ATM_Params::ACE_ATM_Params (int rw_flag, + const char device[], + Param_Info *info, + Param_Udata *udata, + int oflag, + int protocol_family, + int protocol, + int type, + ACE_Protocol_Info *protocol_info, + ACE_SOCK_GROUP g, + u_long flags, + int reuse_addr) + : protocol_family_(protocol_family), + protocol_(protocol), + type_(type), + protocol_info_(protocol_info), + group_(g), + flags_(flags), + reuse_addr_(reuse_addr), + device_(device), + info_(info), + rw_flag_(rw_flag), + udata_(udata), + oflag_(oflag) +{ + ACE_TRACE ("ACE_ATM_Params::ACE_ATM_Params"); +} + +// Default dtor. +ACE_INLINE +ACE_ATM_Params::~ACE_ATM_Params (void) +{ + ACE_TRACE ("ACE_ATM_Params::~ACE_ATM_Params"); +} + +ACE_INLINE +int +ACE_ATM_Params::get_protocol_family (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_protocol_family"); + return protocol_family_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_protocol_family (int family) +{ + ACE_TRACE ("ACE_ATM_Params::set_protocol_family"); + protocol_family_ = family; +} + +ACE_INLINE +int +ACE_ATM_Params::get_protocol (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_protocol"); + return protocol_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_protocol (int protocol) +{ + ACE_TRACE ("ACE_ATM_Params::set_protocol"); + protocol_ = protocol; +} + +ACE_INLINE +int +ACE_ATM_Params::get_type (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_type"); + return type_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_type (int type) +{ + ACE_TRACE ("ACE_ATM_Params::set_type"); + type_ = type; +} + +ACE_INLINE +ACE_Protocol_Info* +ACE_ATM_Params::get_protocol_info( void ) +{ + ACE_TRACE ("ACE_ATM_Params::get_protocol_info"); + return protocol_info_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_protocol_info( ACE_Protocol_Info *protocol_info ) +{ + ACE_TRACE ("ACE_ATM_Params::set_protocol_info"); + protocol_info_ = protocol_info; +} + +ACE_INLINE +ACE_SOCK_GROUP +ACE_ATM_Params::get_sock_group( void ) +{ + ACE_TRACE ("ACE_ATM_Params::get_sock_group"); + return group_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_sock_group( ACE_SOCK_GROUP g ) +{ + ACE_TRACE ("ACE_ATM_Params::set_sock_group"); + group_ = g; +} + +ACE_INLINE +u_long +ACE_ATM_Params::get_flags( void ) +{ + ACE_TRACE ("ACE_ATM_Params::get_flags"); + return flags_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_flags( u_long flags) +{ + ACE_TRACE ("ACE_ATM_Params::set_flags"); + flags_ = flags; +} + +ACE_INLINE +int +ACE_ATM_Params::get_reuse_addr (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_reuse_addr"); + return reuse_addr_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_reuse_addr (int reuse_addr) +{ + ACE_TRACE ("ACE_ATM_Params::set_reuse_addr"); + reuse_addr_ = reuse_addr; +} + +ACE_INLINE +const char* +ACE_ATM_Params::get_device (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_device"); + return device_; +} + +ACE_INLINE +Param_Info* +ACE_ATM_Params::get_info (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_info"); + return info_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_info (Param_Info* info) +{ + ACE_TRACE ("ACE_ATM_Params::set_info"); + info_ = info; +} + +ACE_INLINE +int +ACE_ATM_Params::get_rw_flag (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_rw_flag"); + return rw_flag_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_rw_flag (int rw_flag) +{ + ACE_TRACE ("ACE_ATM_Params::set_rw_flag"); + rw_flag_ = rw_flag; +} + +ACE_INLINE +Param_Udata* +ACE_ATM_Params::get_user_data (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_user_data"); + return udata_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_user_data (Param_Udata *udata) +{ + ACE_TRACE ("ACE_ATM_Params::set_user_data"); + udata_ = udata; +} + +ACE_INLINE +int +ACE_ATM_Params::get_oflag (void) const +{ + ACE_TRACE ("ACE_ATM_Params::get_oflag"); + return oflag_; +} + +ACE_INLINE +void +ACE_ATM_Params::set_oflag (int oflag) +{ + ACE_TRACE ("ACE_ATM_Params::set_oflag"); + oflag_ = oflag; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ATM_QoS.cpp b/dep/ACE_wrappers/ace/ATM_QoS.cpp new file mode 100644 index 000000000..d5405d042 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_QoS.cpp @@ -0,0 +1,631 @@ +// $Id: ATM_QoS.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ATM_QoS.h" + +ACE_RCSID(ace, ATM_QoS, "$Id: ATM_QoS.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_ATM) + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_QoS.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) +#define BHLI_MAGIC "FORE_ATM" +// This is line rate in cells/s for an OC-3 MM interface. +const long ACE_ATM_QoS::LINE_RATE = 353207; +const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1; +const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2; +const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99; +const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 8192; +#elif defined (ACE_HAS_LINUX_ATM) +//pbrandao:for Linux: +//pbrandao:for now stick with current definitions +//pbrandao:see if later need to change +const long ACE_ATM_QoS::LINE_RATE = 353207; +const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1; +const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2; +const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99; +const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 8192; +#else +const long ACE_ATM_QoS::LINE_RATE = 0L; +const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0; +const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0; +const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x0; +const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ + +ACE_ALLOC_HOOK_DEFINE(ACE_ATM_QoS) + +ACE_ATM_QoS::ACE_ATM_QoS (int pktSize) +{ + ACE_TRACE ("ACE_ATM_QoS::ACE_ATM_QoS"); +#if defined (ACE_HAS_LINUX_ATM) + ACE_OS::memset(&qos_, 0, sizeof(qos_)); + qos_.aal = ATM_PROTOCOL_DEFAULT; + qos_.rxtp.traffic_class = ATM_ANYCLASS; + qos_.rxtp.max_sdu = pktSize; + qos_.txtp.traffic_class = ATM_ANYCLASS; + qos_.txtp.max_sdu = pktSize; +#else + ACE_UNUSED_ARG (pktSize); +#endif /* ACE_HAS_LINUX_ATM */ +} + +ACE_ATM_QoS::ACE_ATM_QoS(int rate, + int pktSize) +{ + ACE_TRACE( "ACE_ATM_QoS::ACE_ATM_QoS" ); +#if defined (ACE_HAS_FORE_ATM_WS2) + AAL_PARAMETERS_IE ie_aalparams; + ATM_TRAFFIC_DESCRIPTOR_IE ie_td; + ATM_BROADBAND_BEARER_CAPABILITY_IE ie_bbc; + ATM_QOS_CLASS_IE ie_qos; + Q2931_IE *ie_ptr; + int size; + + // Setting up cbr parameters ... + ie_aalparams.AALType = AALTYPE_5; + ie_aalparams.AALSpecificParameters.AAL5Parameters.ForwardMaxCPCSSDUSize + = pktSize; // was 1516; + ie_aalparams.AALSpecificParameters.AAL5Parameters.BackwardMaxCPCSSDUSize + = pktSize; // was 1516; + ie_aalparams.AALSpecificParameters.AAL5Parameters.Mode = AAL5_MODE_MESSAGE; + ie_aalparams.AALSpecificParameters.AAL5Parameters.SSCSType = AAL5_SSCS_NULL; + + size = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(AAL_PARAMETERS_IE); + + ie_td.Forward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Forward.PeakCellRate_CLP01 = rate; + ie_td.Forward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Forward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT; + ie_td.Forward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT; + ie_td.Forward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT; + ie_td.Forward.Tagging = SAP_FIELD_ABSENT; + + ie_td.Backward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Backward.PeakCellRate_CLP01 = rate; + ie_td.Backward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Backward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT; + ie_td.Backward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT; + ie_td.Backward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT; + ie_td.Backward.Tagging = SAP_FIELD_ABSENT; + + ie_td.BestEffort = 0; // Note: this must be set to zero for CBR. + + size += sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_TRAFFIC_DESCRIPTOR_IE ); + + ie_bbc.BearerClass = BCOB_X; + ie_bbc.TrafficType = TT_CBR; + ie_bbc.TimingRequirements = TR_END_TO_END; + ie_bbc.ClippingSusceptability = CLIP_NOT; + ie_bbc.UserPlaneConnectionConfig = UP_P2P; + + size += sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE ); + + ie_qos.QOSClassForward = QOS_CLASS1; + ie_qos.QOSClassBackward = QOS_CLASS1; // This may not be really used + // since we do only simplex data xfer. + + size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE); + + qos_.ProviderSpecific.buf = (char *) ACE_OS::malloc(size); + if (qos_.ProviderSpecific.buf == 0) { + ACE_ERROR((LM_ERROR, + ACE_TEXT ("ACE_ATM_QoS::ACE_ATM_QoS: Unable to allocate %d bytes for qos_.ProviderSpecific.buf\n"), + size)); + return; + } + qos_.ProviderSpecific.len = size; + ACE_OS::memset(qos_.ProviderSpecific.buf, 0, size); + + ie_ptr = (Q2931_IE *) qos_.ProviderSpecific.buf; + ie_ptr->IEType = IE_AALParameters; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( AAL_PARAMETERS_IE ); + ACE_OS::memcpy(ie_ptr->IE, &ie_aalparams, sizeof(AAL_PARAMETERS_IE)); + + ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength); + ie_ptr->IEType = IE_TrafficDescriptor; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_TRAFFIC_DESCRIPTOR_IE ); + ACE_OS::memcpy(ie_ptr->IE, &ie_td, sizeof(ATM_TRAFFIC_DESCRIPTOR_IE)); + + ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength); + ie_ptr->IEType = IE_BroadbandBearerCapability; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE ); + ACE_OS::memcpy(ie_ptr->IE, + &ie_bbc, + sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE)); + + ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength); + ie_ptr->IEType = IE_QOSClass; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_QOS_CLASS_IE ); + ACE_OS::memcpy(ie_ptr->IE, &ie_qos, sizeof(ATM_QOS_CLASS_IE)); + + // qos_.SendingFlowspec.TokenRate = 0xffffffff; + // qos_.SendingFlowspec.TokenBucketSize = 0xffffffff; + // qos_.SendingFlowspec.PeakBandwidth = 0xffffffff; + // qos_.SendingFlowspec.Latency = 0xffffffff; + // qos_.SendingFlowspec.DelayVariation = 0xffffffff; + // qos_.SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; + // This will most probably be ignored by the service provider. + // qos_.SendingFlowspec.MaxSduSize = 0xffffffff; + // qos_.SendingFlowspec.MinimumPolicedSize = 0xffffffff; + + // qos_.ReceivingFlowspec.TokenRate = 0xffffffff; + // qos_.ReceivingFlowspec.TokenBucketSize = 0xffffffff; + // qos_.ReceivingFlowspec.PeakBandwidth = 0xffffffff; + // qos_.ReceivingFlowspec.Latency = 0xffffffff; + // qos_.ReceivingFlowspec.DelayVariation = 0xffffffff; + // qos_.ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; + // This will most probably be ignored by the service provider. + // qos_.ReceivingFlowspec.MaxSduSize = 0xffffffff; + // qos_.ReceivingFlowspec.MinimumPolicedSize = 0; + + ACE_Flow_Spec send_fspec( 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + SERVICETYPE_BESTEFFORT, + // This will most probably ignored by SP. + 0xffffffff, + 0xffffffff, + 15, + ACE_DEFAULT_THREAD_PRIORITY ), + recv_fspec( 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + SERVICETYPE_BESTEFFORT, + // This will most probably ignored by SP. + 0xffffffff, + 0, + 15, + ACE_DEFAULT_THREAD_PRIORITY ); + + qos_.sending_flowspec (send_fspec); + qos_.receiving_flowspec (recv_fspec); +#elif defined (ACE_HAS_FORE_ATM_XTI) + ACE_UNUSED_ARG (rate); + ACE_UNUSED_ARG (pktSize); +#elif defined (ACE_HAS_LINUX_ATM) + ACE_OS::memset(&qos_, + 0, + sizeof(qos_)); + qos_.aal = ATM_PROTOCOL_DEFAULT; + qos_.rxtp.max_sdu = pktSize; + + if (rate > 0) { + qos_.rxtp.pcr = rate; + qos_.rxtp.traffic_class = ATM_CBR; + qos_.txtp.traffic_class = ATM_CBR; + qos_.txtp.pcr = rate; + } + else { + qos_.rxtp.traffic_class = ATM_UBR; + qos_.txtp.traffic_class = ATM_UBR; + } + + qos_.txtp.max_sdu = pktSize; +#else + ACE_UNUSED_ARG (rate); +#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_FORE_ATM_XTI || ACE_HAS_LINUX_ATM */ +} + +void +ACE_ATM_QoS::set_cbr_rate (int rate, + int pktSize) +{ + ACE_TRACE ("ACE_ATM_QoS::set_cbr_rate"); +#if defined (ACE_HAS_FORE_ATM_WS2) + /* + AAL_PARAMETERS_IE ie_aalparams; + ATM_TRAFFIC_DESCRIPTOR_IE ie_td; + ATM_BROADBAND_BEARER_CAPABILITY_IE ie_bbc; + ATM_QOS_CLASS_IE ie_qos; + Q2931_IE *ie_ptr; + int size; + */ + + ACE_OS::printf( "ATM_QoS(set_cbr_rate): set rate to %d c/s\n", rate ); + + // Setting up cbr parameters ... + /* + FORE has changed this - we no longer specify QoS this way + ie_aalparams.AALType = AALTYPE_5; + ie_aalparams.AALSpecificParameters.AAL5Parameters.ForwardMaxCPCSSDUSize + = pktSize; // was 1516; + ie_aalparams.AALSpecificParameters.AAL5Parameters.BackwardMaxCPCSSDUSize + = pktSize; // was 1516; + ie_aalparams.AALSpecificParameters.AAL5Parameters.Mode = AAL5_MODE_MESSAGE; + ie_aalparams.AALSpecificParameters.AAL5Parameters.SSCSType = AAL5_SSCS_NULL; + + size = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(AAL_PARAMETERS_IE); + + ie_td.Forward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Forward.PeakCellRate_CLP01 = rate; + ie_td.Forward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Forward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT; + ie_td.Forward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT; + ie_td.Forward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT; + ie_td.Forward.Tagging = SAP_FIELD_ABSENT; + + ie_td.Backward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Backward.PeakCellRate_CLP01 = rate; + ie_td.Backward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT; + ie_td.Backward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT; + ie_td.Backward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT; + ie_td.Backward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT; + ie_td.Backward.Tagging = SAP_FIELD_ABSENT; + + ie_td.BestEffort = 0; // Note: this must be set to zero for CBR. + + size += sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_TRAFFIC_DESCRIPTOR_IE ); + + ie_bbc.BearerClass = BCOB_X; + ie_bbc.TrafficType = TT_CBR; + ie_bbc.TimingRequirements = TR_END_TO_END; + ie_bbc.ClippingSusceptability = CLIP_NOT; + ie_bbc.UserPlaneConnectionConfig = UP_P2P; + + size += sizeof(Q2931_IE_TYPE) + + sizeof(ULONG) + + sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE); + + ie_qos.QOSClassForward = QOS_CLASS1; + ie_qos.QOSClassBackward = QOS_CLASS1; // This may not be really used + // since we only simplex data xfer. + + size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE); + + qos_.ProviderSpecific.buf = (char *) ACE_OS::malloc(size); + if (qos_.ProviderSpecific.buf == 0) { + ACE_ERROR((LM_ERROR, + ACE_TEXT ("ACE_ATM_QoS::ACE_ATM_QoS: Unable to allocate %d bytes for qos_.ProviderSpecific.buf\n"), + size)); + return; + } + qos_.ProviderSpecific.len = size; + ACE_OS::memset(qos_.ProviderSpecific.buf, 0, size); + + ie_ptr = (Q2931_IE *) qos_.ProviderSpecific.buf; + ie_ptr->IEType = IE_AALParameters; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( AAL_PARAMETERS_IE ); + ACE_OS::memcpy(ie_ptr->IE, &ie_aalparams, sizeof(AAL_PARAMETERS_IE)); + + ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength); + ie_ptr->IEType = IE_TrafficDescriptor; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_TRAFFIC_DESCRIPTOR_IE ); + ACE_OS::memcpy(ie_ptr->IE, &ie_td, sizeof(ATM_TRAFFIC_DESCRIPTOR_IE)); + + ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength); + ie_ptr->IEType = IE_BroadbandBearerCapability; + ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) + + sizeof( ULONG ) + + sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE ); + ACE_OS::memcpy( ie_ptr->IE, + &ie_bbc, + sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE )); + + ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength); + ie_ptr->IEType = IE_QOSClass; + ie_ptr->IELength = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + + sizeof(ATM_QOS_CLASS_IE); + ACE_OS::memcpy(ie_ptr->IE, &ie_qos, sizeof(ATM_QOS_CLASS_IE)); + */ + + const int BYTES_PER_ATM_CELL = 53; + ACE_OS::memset(&qos_, 0, sizeof(ATM_QoS)); + // Setting the token rate sets the minimum rate. 3 Mbits/sec seems too high. + // Certainly for Vaudeville audio, we only need about 1000 c/s which is + // 424000 bits/sec which is 53000 bytes/sec. + //qos_.SendingFlowspec.TokenRate = 3*(1024*128); // 3Mbits/sec + qos_.SendingFlowspec.TokenRate = 53000; // 1000 cells/sec + qos_.SendingFlowspec.TokenBucketSize = 32*1024; // our block size + //ourQos.SendingFlowspec.PeakBandwidth = ourQos.SendingFlowspec.TokenRate; + qos_.SendingFlowspec.ServiceType = SERVICETYPE_GUARANTEED; + // Peak bandwidth is in bytes/sec. The rate is specified in cells/sec so + // we need to convert from cells/sec to bytes/sec (i.e., multiply by 53). + qos_.SendingFlowspec.PeakBandwidth = rate * BYTES_PER_ATM_CELL; + qos_.SendingFlowspec.Latency = -1; // we don't care too much + qos_.SendingFlowspec.DelayVariation = -1; // we don't care too much + // no provider-specific data allowed on ATM + qos_.ProviderSpecific.buf=0; + qos_.ProviderSpecific.len=0; + // unidirectional P2MP; we don't need to setup the Receiving flowspec + + //qos_.SendingFlowspec.TokenRate = 0xffffffff; + //qos_.SendingFlowspec.TokenBucketSize = 0xffffffff; + //qos_.SendingFlowspec.PeakBandwidth = 0xffffffff; + //qos_.SendingFlowspec.Latency = 0xffffffff; + //qos_.SendingFlowspec.DelayVariation = 0xffffffff; + //qos_.SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; + // This will most probably be ignored by the service provider. + //qos_.SendingFlowspec.MaxSduSize = 0xffffffff; + //qos_.SendingFlowspec.MinimumPolicedSize = 0xffffffff; + + //qos_.ReceivingFlowspec.TokenRate = 0xffffffff; + //qos_.ReceivingFlowspec.TokenBucketSize = 0xffffffff; + //qos_.ReceivingFlowspec.PeakBandwidth = 0xffffffff; + //qos_.ReceivingFlowspec.Latency = 0xffffffff; + //qos_.ReceivingFlowspec.DelayVariation = 0xffffffff; + //qos_.ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; + // This will most probably be ignored by the service provider. + //qos_.ReceivingFlowspec.MaxSduSize = 0xffffffff; + //qos_.ReceivingFlowspec.MinimumPolicedSize = 0; + + /* + ACE_Flow_Spec send_fspec( 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + SERVICETYPE_BESTEFFORT, + // This will most probably ignored by SP. + 0xffffffff, + 0xffffffff, + 15, + ACE_DEFAULT_THREAD_PRIORITY ), + recv_fspec( 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff, + SERVICETYPE_BESTEFFORT, + // This will most probably ignored by SP. + 0xffffffff, + 0, + 15, + ACE_DEFAULT_THREAD_PRIORITY ); + + qos_.sending_flowspec( send_fspec ); + qos_.receiving_flowspec( recv_fspec ); + */ +#elif defined (ACE_HAS_FORE_ATM_XTI) + ACE_UNUSED_ARG (rate); + ACE_UNUSED_ARG (pktSize); +#elif defined (ACE_HAS_LINUX_ATM) + ACE_UNUSED_ARG (pktSize); + + qos_.rxtp.traffic_class = ATM_CBR; + qos_.rxtp.pcr = rate; + qos_.txtp.traffic_class = ATM_CBR; + qos_.txtp.pcr = rate; +#else + ACE_UNUSED_ARG (rate); +#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_FORE_ATM_XTI || ACE_HAS_LINUX_ATM */ +} + +void +ACE_ATM_QoS::set_rate (ACE_HANDLE fd, + int rate, + int flags) +{ + ACE_TRACE ("ACE_ATM_QoS::set_rate"); +#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM) + set_cbr_rate( rate ); + + ACE_UNUSED_ARG( fd ); + ACE_UNUSED_ARG( flags ); +#elif defined (ACE_HAS_FORE_ATM_XTI) + long optlen = 0; + qos_.buf = construct_options(fd, + rate, + flags, + &optlen); + qos_.len = optlen; +#else + ACE_UNUSED_ARG (rate); +#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM || ACE_HAS_FORE_ATM_XTI */ +} + +char* +ACE_ATM_QoS::construct_options (ACE_HANDLE fd, + int rate, + int flags, + long *len) +{ +#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM) + ACE_UNUSED_ARG (fd); + ACE_UNUSED_ARG (rate); + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (len); + return (0); +#elif defined (ACE_HAS_FORE_ATM_XTI) + struct t_opthdr *popt; + char *buf; + int qos_cells; + struct t_info info; + + if (ACE_OS::t_getinfo (fd, &info) == -1) + { + ACE_OS::t_error ("t_getinfo"); + return 0; + } + + buf = (char *) ACE_OS::malloc (info.options); + + if (buf == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to allocate %d bytes for options\n"), + info.options), + 0); + + popt = (struct t_opthdr *) buf; + + if (flags & OPT_FLAGS_CPID) + { + // This constructs the T_ATM_ORIG_ADDR option, which is used to + // signal the UNI 3.1 Calling Party ID Information Element. + t_atm_addr *source_addr; + + popt->len = sizeof (struct t_opthdr) + sizeof (t_atm_addr); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_ORIG_ADDR; + popt->status = 0; + + source_addr = + (t_atm_addr *)((char *) popt + sizeof (struct t_opthdr)); + + source_addr->address_format = T_ATM_ENDSYS_ADDR; + source_addr->address_length = ATMNSAP_ADDR_LEN; + + ATMSAPAddress local_addr; + struct t_bind boundaddr; + + boundaddr.addr.maxlen = sizeof(local_addr); + boundaddr.addr.buf = (char *) &local_addr; + + //if (ACE_OS::t_getprotaddr(fd, &boundaddr, 0) < 0) { + if (ACE_OS::t_getname(fd, + &boundaddr.addr, + LOCALNAME) < 0) + { + ACE_OS::t_error("t_getname (local_address)"); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Can't get local address!\n"))); + ACE_OS::free (buf); + return 0; + } + + ACE_OS::memcpy(source_addr->address, + local_addr.sap.t_atm_sap_addr.address, + ATMNSAP_ADDR_LEN); + + popt = T_OPT_NEXTHDR (buf, info.options , popt); + } + + // This constructs all options necessary (bearer cap., QoS, and + // Traffic Descriptor) to signal for a CBR connection with the + // specified QoS in kbit/sec., and/or specify a PMP connection. + + // For FORE 200e cards, the adapter shapes traffic to CBR with rate + // equal to PCR CLP=0+1 (traffic.forward.PCR_all_traffic) + + qos_cells = (rate * 1000) / (48*8); + + if ((qos_cells > 0 && qos_cells < LINE_RATE) + || (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))) + { + struct t_atm_bearer *bearer; + struct t_atm_traffic *traffic; + + // T_ATM_BEARER_CAP: Broadband bearer capability + popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_bearer); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_BEARER_CAP; + popt->status = 0; + + bearer = (struct t_atm_bearer *)((char *) popt + + sizeof (struct t_opthdr)); + bearer->bearer_class = T_ATM_CLASS_X; + + if (qos_cells) + { + bearer->traffic_type = T_ATM_CBR; + bearer->timing_requirements = T_ATM_END_TO_END; + } + else + { + bearer->traffic_type = 0; // UBR + bearer->timing_requirements = 0; + } + bearer->clipping_susceptibility = T_ATM_NULL; + + if (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)) + bearer->connection_configuration = T_ATM_1_TO_MANY; + else + bearer->connection_configuration = T_ATM_1_TO_1; + + popt = T_OPT_NEXTHDR (buf, info.options, popt); + + // T_ATM_TRAFFIC: traffic descriptor + popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_traffic); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_TRAFFIC; + popt->status = 0; + + traffic = (struct t_atm_traffic *)((char *) popt + + sizeof (struct t_opthdr)); + + traffic->forward.PCR_high_priority = T_ATM_ABSENT; + traffic->forward.PCR_all_traffic = qos_cells ? qos_cells : LINE_RATE; + traffic->forward.SCR_high_priority = T_ATM_ABSENT; + traffic->forward.SCR_all_traffic = T_ATM_ABSENT; + traffic->forward.MBS_high_priority = T_ATM_ABSENT; + traffic->forward.MBS_all_traffic = T_ATM_ABSENT; + traffic->forward.tagging = T_NO; + + traffic->backward.PCR_high_priority = T_ATM_ABSENT; + traffic->backward.PCR_all_traffic = + (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)) + ? 0 : qos_cells ? qos_cells : LINE_RATE; + traffic->backward.SCR_high_priority = T_ATM_ABSENT; + traffic->backward.SCR_all_traffic = T_ATM_ABSENT; + traffic->backward.MBS_high_priority = T_ATM_ABSENT; + traffic->backward.MBS_all_traffic = T_ATM_ABSENT; + traffic->backward.tagging = T_NO; + + traffic->best_effort = qos_cells ? T_NO : T_YES; + + popt = T_OPT_NEXTHDR (buf, + info.options, + popt); + } + + if (qos_cells > 0 && qos_cells < LINE_RATE) + { + struct t_atm_qos *qos; + + // T_ATM_QOS: Quality of Service + popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_qos); + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_QOS; + popt->status = 0; + + qos = (struct t_atm_qos *)((char *) popt + sizeof (struct t_opthdr)); + qos->coding_standard = T_ATM_ITU_CODING; + qos->forward.qos_class = T_ATM_QOS_CLASS_1; + qos->backward.qos_class = T_ATM_QOS_CLASS_1; + + popt = T_OPT_NEXTHDR (buf, info.options, popt); + } + + // Return actual size of options and option buffer to user. + *len = (char *) popt - buf; + + return buf; +#else + ACE_UNUSED_ARG (fd); + ACE_UNUSED_ARG (rate); + ACE_UNUSED_ARG (flag); + ACE_UNUSED_ARG (len); + return (0); +#endif /* ACE_HAS_FORE_ATM_WS2 */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_ATM */ + diff --git a/dep/ACE_wrappers/ace/ATM_QoS.h b/dep/ACE_wrappers/ace/ATM_QoS.h new file mode 100644 index 000000000..4e35f3fdd --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_QoS.h @@ -0,0 +1,115 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file ATM_QoS.h + * + * $Id: ATM_QoS.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//========================================================================== + + +#ifndef ACE_ATM_QoS_H +#define ACE_ATM_QoS_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined(ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_ATM) + +#if defined (ACE_HAS_FORE_ATM_WS2) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +// just map to WS2 GQOS struct +typedef ACE_QoS ATM_QoS; +ACE_END_VERSIONED_NAMESPACE_DECL +#elif defined (ACE_HAS_FORE_ATM_XTI) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef struct netbuf ATM_QoS; +ACE_END_VERSIONED_NAMESPACE_DECL +#elif defined (ACE_HAS_LINUX_ATM) +#include /**/ "atm.h" +#include "ace/ATM_Params.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef struct atm_qos ATM_QoS; +ACE_END_VERSIONED_NAMESPACE_DECL +#else +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef int ATM_QoS; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_FORE_ATM_XTI || ACE_HAS_LINUX_ATM */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_ATM_QoS + * + * @brief Define the QoS parameters for ATM + * + * This class wraps up QoS parameters for both ATM/XTI and + * ATM/WinSock2 to make the mechanism for the ATM protocol + * transparent. + */ +class ACE_Export ACE_ATM_QoS +{ +public: + // Constants used for ATM options + static const long LINE_RATE; + static const int OPT_FLAGS_CPID; + static const int OPT_FLAGS_PMP; + static const int DEFAULT_SELECTOR; + static const int DEFAULT_PKT_SIZE; + + // = Initializattion and termination methods. + /// Default constructor. + ACE_ATM_QoS(int = DEFAULT_PKT_SIZE); + + /// Constructor with a CBR rate. + ACE_ATM_QoS(int, + int = DEFAULT_PKT_SIZE); + + ~ACE_ATM_QoS (); + + /// Set the rate. + void set_rate (ACE_HANDLE, + int, + int); + + /// Set CBR rate in cells per second. + void set_cbr_rate (int, + int = DEFAULT_PKT_SIZE); + + /// Get ATM_QoS struct. + ATM_QoS get_qos (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Construct QoS options. + char* construct_options(ACE_HANDLE, + int, + int, + long*); + +private: + ATM_QoS qos_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/ATM_QoS.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_ATM */ +#include /**/ "ace/post.h" +#endif /* ACE_ATM_QoS_H */ diff --git a/dep/ACE_wrappers/ace/ATM_QoS.inl b/dep/ACE_wrappers/ace/ATM_QoS.inl new file mode 100644 index 000000000..52b521119 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_QoS.inl @@ -0,0 +1,29 @@ +// -*- C++ -*- +// +// $Id: ATM_QoS.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_ATM_QoS::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ATM_QoS::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_INLINE +ACE_ATM_QoS::~ACE_ATM_QoS () +{ + ACE_TRACE ("ACE_ATM_QoS::~ACE_ATM_QoS"); +} + +ACE_INLINE +ATM_QoS +ACE_ATM_QoS::get_qos (void) +{ + ACE_TRACE ("ACE_ATM_QoS::get_qos"); + return qos_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ATM_Stream.cpp b/dep/ACE_wrappers/ace/ATM_Stream.cpp new file mode 100644 index 000000000..affb89147 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Stream.cpp @@ -0,0 +1,290 @@ +// $Id: ATM_Stream.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ATM_Stream.h" + +ACE_RCSID (ace, ATM_Stream, "$Id: ATM_Stream.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_ATM) + +#if !defined (__ACE_INLINE__) +#include "ace/ATM_Stream.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE (ACE_ATM_Stream) + +char* +ACE_ATM_Stream::get_peer_name (void) const +{ + ACE_TRACE ("ACE_ATM_Stream::get_peer_name"); +#if defined (ACE_HAS_FORE_ATM_XTI) + // // Use t_getprotaddr for XTI/ATM + // struct t_bind *localaddr + // = (struct t_bind *) ACE_OS::t_alloc (get_handle (), + // T_BIND, + // T_ADDR); + // struct t_bind *peeraddr + // = (struct t_bind *) ACE_OS::t_alloc (get_handle (), + // T_BIND, + // T_ADDR); + // ::t_getprotaddr (get_handle (), + // localaddr, + // peeraddr); + + // char* connected_name = (char*) ACE_OS::malloc (peeraddr->addr.len + 1); + // ACE_OS::strcpy (connected_name, + // peeraddr->addr.buf); + // ACE_OS::t_free ((char *) localaddr, + // T_BIND); + // ACE_OS::t_free ((char *) peeraddr, + // T_BIND); + // return (connected_name); + +#error "This doesn't seem to work. May need to jimmy-rig something with the" +#error "/etc/xti_hosts file - Ugh!" + + ACE_ATM_Addr sa; + struct netbuf name; + name.maxlen = sa.get_size (); + name.buf = (char *) sa.get_addr (); + ACE_OS::t_getname (this->get_handle (), &name, REMOTENAME); + // ACE_OS::ioctl (this->get_handle (), + // TI_GETPEERNAME, + // &name); + return (name.buf); + +#elif defined (ACE_HAS_FORE_ATM_WS2) + // Use getpeername for WinSock2. + struct sockaddr_atm name; + ACE_OS::memset (&name, 0, sizeof (name)); + int nameSize = sizeof (name); + + if (ACE_OS::getpeername (this->get_handle (), + (struct sockaddr *) &name, + &nameSize) != 0) { + return 0; + } + + char buffer[256]; + for (unsigned int index = 0; index < ATM_ADDR_SIZE - 1; index++) { + buffer[ index * 3 ] = '\0'; + ACE_OS::sprintf (buffer, "%s%02x.", buffer, name.satm_number.Addr[ index ]); + } + buffer[ (ATM_ADDR_SIZE - 1) * 3 ] = '\0'; + ACE_OS::sprintf (buffer, "%s%02x.", buffer, 0); + buffer[ ATM_ADDR_SIZE * 3 - 1 ] = '\0'; + for (index = 0; index < ACE_OS::strlen (buffer); ++index) + buffer[index] = ACE_OS::ace_tolower (buffer[index]); + + ifstream atm_hosts ("C:/WINNT/atmhosts"); + assert (atm_hosts.is_open ()); + + // Find the host address in the ATM hosts file and return the + // host name + char line[256]; + char *host_ptr, *host_name = 0; + ACE_NEW_RETURN (host_name, char[256], 0); + while (!atm_hosts.eof ()) { + atm_hosts.getline (line, 256); + // Convert the line to lower case to ease comparison + for (index = 0; index < ACE_OS::strlen (line); ++index) + line[index] = ACE_OS::ace_tolower (line[index]); + if (ACE_OS::strstr (line, buffer) != 0) + { + char *strtok_p; + // Grab the second token which is the host name + ACE_OS::strtok_r (line, " \t", &strtok_p); + host_ptr = ACE_OS::strtok (0, " \t", &strtok_p); + ACE_OS::strcpy (host_name, host_ptr); + break; + } + } + + return host_name; +#elif defined (ACE_HAS_LINUX_ATM) + ATM_Addr name; + int nameSize = sizeof (name.sockaddratmsvc); + + if (ACE_OS::getpeername (this->get_handle (), + (struct sockaddr *) & (name.sockaddratmsvc), + &nameSize) < 0) { + ACE_OS::perror ("ACE_ATM_Stream (get_peer_name) : "); + return 0; + } + + static ACE_TCHAR buffer[MAX_ATM_ADDR_LEN + 1]; + int total_len; + if ((total_len = atm2text (buffer,sizeof buffer, + (struct sockaddr *) & (name.sockaddratmsvc), + A2T_PRETTY|A2T_NAME)) < 0) { + ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("ACE_ATM_Stream (get_peer_name) :%d"),errno)); + return 0; + } + + return (char*) buffer; +#else + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +ACE_HANDLE +ACE_ATM_Stream::get_handle (void) const +{ + ACE_TRACE ("ACE_ATM_Stream::get_handle"); +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM) + return stream_.get_handle (); +#else + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +int +ACE_ATM_Stream::get_vpi_vci (ACE_UINT16 &vpi, + ACE_UINT16 &vci) const +{ + ACE_TRACE ("ACE_ATM_Stream::get_vpi_vci"); +#if defined (ACE_HAS_FORE_ATM_XTI) + struct t_atm_conn_prop conn_prop; + char* connect_opts = (char *) &conn_prop; + int opt_size = sizeof (t_atm_conn_prop); + struct t_info info; + struct t_optmgmt opt_req, opt_ret; + + if (ACE_OS::t_getinfo (stream_.get_handle (), + &info) < 0) + { + ACE_OS::t_error ("t_getinfo"); + return -1; + } + + char *buf_req = (char *) ACE_OS::malloc (info.options); + if (buf_req == 0) + { + ACE_OS::fprintf (stderr, + "Unable to allocate %ld bytes for options\n", + info.options); + return -1; + } + + char *buf_ret = (char *) ACE_OS::malloc (info.options); + if (buf_ret == 0) + { + ACE_OS::fprintf (stderr, + "Unable to allocate %ld bytes for options\n", + info.options); + return -1; + } + + ACE_OS::memset (&opt_req, 0, sizeof (opt_req)); + ACE_OS::memset (&opt_ret, 0, sizeof (opt_ret)); + + struct t_opthdr *popt = (struct t_opthdr *) buf_req; + struct t_opthdr *popt_ret = (struct t_opthdr *) buf_ret; + + popt->len= sizeof (struct t_opthdr) + opt_size; + + // We are only concerned with SVCs so no other check or values are needed + // here. + popt->level = T_ATM_SIGNALING; + popt->name = T_ATM_CONN_PROP; + popt->status = 0; + + opt_req.opt.len = popt->len; + opt_req.opt.buf = (char *) popt; + opt_req.flags = T_CURRENT; + + popt = T_OPT_NEXTHDR (buf_req, + info.options, + popt); + opt_ret.opt.maxlen = info.options; + opt_ret.opt.buf = (char *) popt_ret; + + if (ACE_OS::t_optmgmt (stream_.get_handle (), + &opt_req, + &opt_ret) < 0) { + ACE_OS::t_error ("t_optmgmt"); + return -1; + } + + ACE_OS::memcpy (connect_opts, + (char *) popt_ret + sizeof (struct t_opthdr), + opt_size); + + ACE_OS::free (buf_ret); + ACE_OS::free (buf_req); + + vpi = conn_prop.vpi; + vci = conn_prop.vci; + return (0); +#elif defined (ACE_HAS_FORE_ATM_WS2) + ATM_CONNECTION_ID connID; + DWORD bytes = 0; + + if (::WSAIoctl ((int) this -> get_handle (), + SIO_GET_ATM_CONNECTION_ID, + 0, + 0, + (LPVOID) &connID, + sizeof (ATM_CONNECTION_ID), + &bytes, + 0, + 0) + == SOCKET_ERROR) { + ACE_OS::printf ("Error: WSAIoctl %d\n", WSAGetLastError ()); + } + + vpi = (ACE_UINT16) connID.VPI; + vci = (ACE_UINT16) connID.VCI; + + return 0; +#elif defined (ACE_HAS_LINUX_ATM) +#if defined (SO_ATMPVC) /* atm version>=0.62 */ + struct sockaddr_atmpvc mypvcaddr; + int addrpvclen = sizeof (mypvcaddr); + if (ACE_OS::getsockopt (stream_.get_handle (), + SOL_ATM, + SO_ATMPVC, + reinterpret_cast (&mypvcaddr), + &addrpvclen) < 0) { + ACE_DEBUG (LM_DEBUG, + ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: getsockopt %d\n"), + errno); + return -1; + } + vpi = (ACE_UINT16) mypvcaddr.sap_addr.vpi; + vci = (ACE_UINT16) mypvcaddr.sap_addr.vci; + + return 0; +#elif defined (SO_VCID) /* patch for atm version 0.59 */ + struct atm_vcid mypvcid; + int pvcidlen = sizeof (mypvcid); + if (ACE_OS::getsockopt (stream_.get_handle (), + SOL_ATM,SO_VCID, + reinterpret_cast (&mypvcid), + &pvcidlen) < 0) { + ACE_DEBUG (LM_DEBUG, + ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: getsockopt %d\n"), + errno); + return -1; + } + vpi = (ACE_UINT16) mypvcid.vpi; + vci = (ACE_UINT16) mypvcid.vci; + + return 0; +#else + ACE_DEBUG (LM_DEBUG, + ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: Not implemented in this ATM version. Update to >= 0.62\n Or patch 0.59")); + ACE_UNUSED_ARG (vci); + ACE_UNUSED_ARG (vpi); + + return (-1); +#endif /* SO_ATMPVC || SO_VCID */ +#else + return (-1); +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_ATM */ diff --git a/dep/ACE_wrappers/ace/ATM_Stream.h b/dep/ACE_wrappers/ace/ATM_Stream.h new file mode 100644 index 000000000..41ffb0da3 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Stream.h @@ -0,0 +1,107 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file ATM_Stream.h + * + * $Id: ATM_Stream.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//============================================================================= + + +#ifndef ACE_ATM_STREAM_H +#define ACE_ATM_STREAM_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_ATM) + +#include "ace/ATM_Addr.h" +#include "ace/ATM_Params.h" + +#if defined (ACE_WIN32) +#include "ace/SOCK_Stream.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ACE_SOCK_Stream ATM_Stream; +ACE_END_VERSIONED_NAMESPACE_DECL +#else +#include "ace/TLI_Stream.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +typedef ACE_TLI_Stream ATM_Stream; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_ATM_Stream + * + * @brief Defines the member functions for ACE_ATM_Stream abstraction. + */ +class ACE_Export ACE_ATM_Stream +{ +public: + // = Initialization and termination methods. + /// Default constructor. + ACE_ATM_Stream (void); + + // = ATM-specific open and shutdown operations. + /// open the stream. + int open (ACE_ATM_Params params = ACE_ATM_Params()); + + /// Close down and release resources. + int close (void); + + /// Get the underlying handle. + ACE_HANDLE get_handle (void) const; + + /// Get the underlying stream. + ATM_Stream& get_stream (void); + + /// Get the name of the connected host. + char* get_peer_name (void) const; + + /// Get the VPI and VCI of the stream. + int get_vpi_vci (ACE_UINT16 &vpi, + ACE_UINT16 &vci) const; + + /// Recv an n byte buffer from the connected transport mechanism. + ssize_t recv (void *buf, + size_t n, + int *flags = 0) const; + + /// Send exactly n bytes to the connected transport mechanism. + ssize_t send_n (const void *buf, + size_t n, + int flags) const; + + // = Meta-type info + typedef ACE_ATM_Addr PEER_ADDR; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Typedef'd to the appropriate stream mechanism above. + ATM_Stream stream_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/ATM_Stream.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_ATM */ +#include /**/ "ace/post.h" +#endif /* ACE_ATM_STREAM_H */ diff --git a/dep/ACE_wrappers/ace/ATM_Stream.inl b/dep/ACE_wrappers/ace/ATM_Stream.inl new file mode 100644 index 000000000..087c1ed44 --- /dev/null +++ b/dep/ACE_wrappers/ace/ATM_Stream.inl @@ -0,0 +1,133 @@ +// -*- C++ -*- +// +// $Id: ATM_Stream.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_ATM_Stream::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_ATM_Stream::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_INLINE +ACE_ATM_Stream::ACE_ATM_Stream (void) +{ + ACE_TRACE ("ACE_ATM_Stream::ACE_ATM_Stream"); +} + +ACE_INLINE +int +ACE_ATM_Stream::open (ACE_ATM_Params params) +{ + ACE_TRACE ("ACE_ATM_Stream::open"); +#if defined (ACE_HAS_FORE_ATM_XTI) + ACE_HANDLE handle = stream_.open (params.get_device(), + params.get_oflag(), + params.get_info()); + return (handle == ACE_INVALID_HANDLE ? -1 : 0); +#elif defined (ACE_HAS_FORE_ATM_WS2) + params.set_flags( ACE_FLAG_MULTIPOINT_C_ROOT | ACE_FLAG_MULTIPOINT_D_ROOT ); + + int retval = stream_.open (params.get_type(), + params.get_protocol_family(), + params.get_protocol(), + params.get_protocol_info(), + params.get_sock_group(), + params.get_flags(), + params.get_reuse_addr()); + if (retval == -1) + return -1; + + struct sockaddr_atm sock_addr; + + ACE_OS::memset(&sock_addr, 0, sizeof(struct sockaddr_atm)); + sock_addr.satm_family = AF_ATM; + sock_addr.satm_number.AddressType=ADDR_ANY; + sock_addr.satm_number.NumofDigits = ATM_ADDR_SIZE; + sock_addr.satm_blli.Layer2Protocol = SAP_FIELD_ABSENT; + sock_addr.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT; + sock_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT; + if (ACE_OS::bind(get_handle(), + (struct sockaddr FAR *)&sock_addr, + sizeof(struct sockaddr_atm)) < 0) + { + ACE_OS::printf("Error binding local address: %d",WSAGetLastError()); + return -1; + } + + return 0; +#else + ACE_UNUSED_ARG(params); + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI */ +} + +ACE_INLINE +int +ACE_ATM_Stream::close (void) +{ + ACE_TRACE ("ACE_ATM_Stream::close"); +#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) + return stream_.close (); +#else + return 0; +#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */ +} + +ACE_INLINE +ATM_Stream& +ACE_ATM_Stream::get_stream (void) +{ + ACE_TRACE ("ACE_ATM_Stream::get_stream"); + return stream_; +} + +ACE_INLINE +ssize_t +ACE_ATM_Stream::recv (void *buf, + size_t n, + int *flags) const +{ + ACE_TRACE ("ACE_ATM_Stream::recv"); +#if defined (ACE_HAS_FORE_ATM_XTI) + return stream_.recv (buf, + n, + flags); +#elif defined (ACE_HAS_FORE_ATM_WS2) + return stream_.recv (buf, + n); +#else + ACE_UNUSED_ARG(buf); + ACE_UNUSED_ARG(n); + ACE_UNUSED_ARG(flags); + return (0); +#endif /* ACE_HAS_FORE_ATM_XTI */ +} + +ACE_INLINE +ssize_t +ACE_ATM_Stream::send_n (const void *buf, + size_t n, + int flags) const +{ + ACE_TRACE ("ACE_ATM_Stream::send_n"); +#if defined (ACE_HAS_FORE_ATM_XTI) + return stream_.send_n (buf, + n, + flags); +#elif defined (ACE_HAS_FORE_ATM_WS2) + return stream_.send_n (buf, + n, + flags); +#else + ACE_UNUSED_ARG(buf); + ACE_UNUSED_ARG(n); + ACE_UNUSED_ARG(flags); + return (0); +#endif /* ACE_HAS_FORE_ATM_XTI */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Acceptor.cpp b/dep/ACE_wrappers/ace/Acceptor.cpp new file mode 100644 index 000000000..1ba51af5e --- /dev/null +++ b/dep/ACE_wrappers/ace/Acceptor.cpp @@ -0,0 +1,1235 @@ +#ifndef ACE_ACCEPTOR_CPP +#define ACE_ACCEPTOR_CPP + +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Acceptor.h" +#include "ace/Handle_Set.h" +#include "ace/Svc_Handler.h" +#include "ace/WFMO_Reactor.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_select.h" + +ACE_RCSID (ace, + Acceptor, + "$Id: Acceptor.cpp 81991 2008-06-16 19:05:40Z elliott_c $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Acceptor) + +template void +ACE_Acceptor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Acceptor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->peer_acceptor_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Acceptor::operator ACE_PEER_ACCEPTOR & () const +{ + ACE_TRACE ("ACE_Acceptor::operator ACE_PEER_ACCEPTOR &"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template ACE_PEER_ACCEPTOR & +ACE_Acceptor::acceptor (void) const +{ + ACE_TRACE ("ACE_Acceptor::acceptor"); + return const_cast (this->peer_acceptor_); +} + +// Returns ACE_HANDLE of the underlying Acceptor_Strategy. + +template ACE_HANDLE +ACE_Acceptor::get_handle (void) const +{ + ACE_TRACE ("ACE_Acceptor::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +// Initialize the appropriate strategies for creation, passive +// connection acceptance, and concurrency, and then register +// with the Reactor and listen for connection requests at the +// designated . + +template int +ACE_Acceptor::open + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor, + int flags, + int use_select, + int reuse_addr) +{ + ACE_TRACE ("ACE_Acceptor::open"); + this->flags_ = flags; + this->use_select_ = use_select; + this->reuse_addr_ = reuse_addr; + this->peer_acceptor_addr_ = local_addr; + + // Must supply a valid Reactor to Acceptor::open()... + + if (reactor == 0) + { + errno = EINVAL; + return -1; + } + + if (this->peer_acceptor_.open (local_addr, reuse_addr) == -1) + return -1; + + // Set the peer acceptor's handle into non-blocking mode. This is a + // safe-guard against the race condition that can otherwise occur + // between the time when indicates that a passive-mode + // socket handle is "ready" and when we call . During this + // interval, the client can shutdown the connection, in which case, + // the call can hang! + if (this->accept_strategy_->acceptor ().enable (ACE_NONBLOCK) != 0) + return -1; + + // Initialize the concurrency strategy. + + if (con_s == 0) + { + ACE_NEW_RETURN (con_s, + CONCURRENCY_STRATEGY, + -1); + this->delete_concurrency_strategy_ = true; + } + this->concurrency_strategy_ = con_s; + + // Initialize the scheduling strategy. + + if (sch_s == 0) + { + ACE_NEW_RETURN (sch_s, + SCHEDULING_STRATEGY, + -1); + this->delete_scheduling_strategy_ = true; + } + this->scheduling_strategy_ = sch_s; + + this->use_select_ = use_select; + + return this->reactor ()->register_handler + (this, + ACE_Event_Handler::ACCEPT_MASK); +} + +// Simple constructor. + +template +ACE_Strategy_Acceptor::ACE_Strategy_Acceptor + (const ACE_TCHAR service_name[], + const ACE_TCHAR service_description[], + int use_select, + int reuse_addr) + : creation_strategy_ (0), + delete_creation_strategy_ (false), + accept_strategy_ (0), + delete_accept_strategy_ (false), + concurrency_strategy_ (0), + delete_concurrency_strategy_ (false), + scheduling_strategy_ (0), + delete_scheduling_strategy_ (false), + service_name_ (0), + service_description_ (0) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor"); + + if (service_name != 0) + ACE_ALLOCATOR (this->service_name_, + ACE_OS::strdup (service_name)); + if (service_description != 0) + ACE_ALLOCATOR (this->service_description_, + ACE_OS::strdup (service_description)); + this->use_select_ = use_select; + this->reuse_addr_ = reuse_addr; +} + +template +ACE_Strategy_Acceptor::ACE_Strategy_Acceptor + (const ACE_PEER_ACCEPTOR_ADDR &addr, + ACE_Reactor *reactor, + ACE_Creation_Strategy *cre_s, + ACE_Accept_Strategy *acc_s, + ACE_Concurrency_Strategy *con_s, + ACE_Scheduling_Strategy *sch_s, + const ACE_TCHAR service_name[], + const ACE_TCHAR service_description[], + int use_select, + int reuse_addr) + : creation_strategy_ (0), + delete_creation_strategy_ (false), + accept_strategy_ (0), + delete_accept_strategy_ (false), + concurrency_strategy_ (0), + delete_concurrency_strategy_ (false), + scheduling_strategy_ (0), + delete_scheduling_strategy_ (false), + service_name_ (0), + service_description_ (0) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor"); + + if (this->open (addr, + reactor, + cre_s, + acc_s, + con_s, + sch_s, + service_name, + service_description, + use_select, + reuse_addr) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor"))); +} + +// Perform termination activities when is removed from the +// . + +template int +ACE_Strategy_Acceptor::handle_close (ACE_HANDLE, + ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::handle_close"); + // Guard against multiple closes. + if (this->reactor () != 0) + { + ACE_HANDLE handle = this->get_handle (); + + if (this->delete_creation_strategy_) + delete this->creation_strategy_; + this->delete_creation_strategy_ = false; + this->creation_strategy_ = 0; + + if (this->delete_accept_strategy_) + delete this->accept_strategy_; + this->delete_accept_strategy_ = false; + this->accept_strategy_ = 0; + + if (this->delete_concurrency_strategy_) + delete this->concurrency_strategy_; + this->delete_concurrency_strategy_ = false; + this->concurrency_strategy_ = 0; + + if (this->delete_scheduling_strategy_) + delete this->scheduling_strategy_; + this->delete_scheduling_strategy_ = false; + this->scheduling_strategy_ = 0; + + // We must use the obtained *before* we deleted the + // accept_strategy_... + + this->reactor ()->remove_handler + (handle, + ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL); + + // Set the Reactor to 0 so that we don't try to close down + // again. + this->reactor (0); + } + return 0; +} + +// Bridge method for creating a . The strategy for +// creating a are configured into the Acceptor via it's +// . The default is to create a new +// . However, subclasses can override this strategy to +// perform creation in any way that they like (such as +// creating subclass instances of , using a singleton, +// dynamically linking the handler, etc.). + +template int +ACE_Strategy_Acceptor::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::make_svc_handler"); + return this->creation_strategy_->make_svc_handler (sh); +} + +// Bridge method for accepting the new connection into the +// . The default behavior delegates to the +// in the Acceptor_Strategy. + +template int +ACE_Strategy_Acceptor::accept_svc_handler + (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::accept_svc_handler"); + return this->accept_strategy_->accept_svc_handler (svc_handler); +} + +// Bridge method for activating a with the appropriate +// concurrency strategy. The default behavior of this method is to +// activate the SVC_HANDLER by calling its open() method (which allows +// the SVC_HANDLER to define its own concurrency strategy). However, +// subclasses can override this strategy to do more sophisticated +// concurrency activations (such as creating the SVC_HANDLER as an +// "active object" via multi-threading or multi-processing). + +template int +ACE_Strategy_Acceptor::activate_svc_handler + (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::activate_svc_handler"); + return this->concurrency_strategy_->activate_svc_handler + (svc_handler, + (void *) this); +} + +template +ACE_Strategy_Acceptor::~ACE_Strategy_Acceptor (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::~ACE_Strategy_Acceptor"); + ACE_OS::free ((void *) this->service_name_); + ACE_OS::free ((void *) this->service_description_); + this->handle_close (); +} + +// Signal the server to shutdown gracefully. + +template int +ACE_Strategy_Acceptor::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_Reactor::instance()->end_reactor_event_loop (); + return 0; +} + +template int +ACE_Strategy_Acceptor::info (ACE_TCHAR **strp, + size_t length) const +{ + ACE_TRACE ("ACE_Strategy_Acceptor::info"); + + ACE_TCHAR buf[BUFSIZ]; + ACE_TCHAR service_addr_str[BUFSIZ]; + ACE_PEER_ACCEPTOR_ADDR addr; + + if (this->acceptor ().get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (service_addr_str, + sizeof service_addr_str) == -1) + return -1; + + // @@ Should add the protocol in... + ACE_OS::sprintf (buf, + ACE_TEXT ("%s\t %s #%s\n"), + this->service_name_ == 0 + ? ACE_TEXT ("") + : this->service_name_, + service_addr_str, + this->service_description_ == 0 + ? ACE_TEXT ("") + : this->service_description_); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strsncpy (*strp, buf, length); + return static_cast (ACE_OS::strlen (buf)); +} + +template int +ACE_Strategy_Acceptor::fini (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::fini"); + return this->ACE_Strategy_Acceptor::handle_close (); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Oneshot_Acceptor) + +template void +ACE_Oneshot_Acceptor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Oneshot_Acceptor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsvc_handler_ = %x"), this->svc_handler_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nrestart_ = %d"), this->restart_)); + this->peer_acceptor_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_concurrency_strategy_ = %d"), + delete_concurrency_strategy_)); + this->concurrency_strategy_->dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template int +ACE_Oneshot_Acceptor::open + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor, + ACE_Concurrency_Strategy *con_s) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::open"); + this->reactor (reactor); + + // Initialize the concurrency strategy. + + if (con_s == 0) + { + ACE_NEW_RETURN (con_s, + ACE_Concurrency_Strategy, + -1); + this->delete_concurrency_strategy_ = true; + } + this->concurrency_strategy_ = con_s; + + // Reuse the addr, even if it is already in use...! + return this->peer_acceptor_.open (local_addr, 1); +} + +template +ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor (void) + : delete_concurrency_strategy_ (false) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor"); + this->reactor (0); +} + +template +ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor, + ACE_Concurrency_Strategy *cs) + : delete_concurrency_strategy_ (false) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor"); + if (this->open (local_addr, reactor, cs) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor"))); +} + +template +ACE_Oneshot_Acceptor::~ACE_Oneshot_Acceptor (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::~ACE_Oneshot_Acceptor"); + this->handle_close (); +} + +template int +ACE_Oneshot_Acceptor::close (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::close"); + return this->handle_close (); +} + +template int +ACE_Oneshot_Acceptor::handle_close (ACE_HANDLE, + ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::handle_close"); + + // Guard against multiple closes. + if (this->delete_concurrency_strategy_) + { + delete this->concurrency_strategy_; + this->delete_concurrency_strategy_ = false; + this->concurrency_strategy_ = 0; + } + // Note that if we aren't actually registered with the + // ACE_Reactor then it's ok for this call to fail... + + if (this->reactor ()) + this->reactor ()->remove_handler + (this, + ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL); + + if (this->peer_acceptor_.close () == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("close\n"))); + return 0; +} + +template int +ACE_Oneshot_Acceptor::handle_timeout + (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::handle_timeout"); + errno = ETIME; + + if (this->svc_handler_->handle_timeout (tv, arg) == -1) + this->svc_handler_->handle_close (this->svc_handler_->get_handle (), + ACE_Event_Handler::TIMER_MASK); + + // Since we aren't necessarily registered with the Reactor, don't + // bother to check the return value here... + if (this->reactor ()) + this->reactor ()->remove_handler (this, + ACE_Event_Handler::ACCEPT_MASK); + return 0; +} + +template int +ACE_Oneshot_Acceptor::cancel (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::cancel"); + return this->reactor () && this->reactor ()->cancel_timer (this); +} + +template int +ACE_Oneshot_Acceptor::register_handler + (SVC_HANDLER *svc_handler, + const ACE_Synch_Options &synch_options, + int restart) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::register_handler"); + // Can't do this if we don't have a Reactor. + if (this->reactor () == 0) + { + errno = EINVAL; + return -1; + } + else + { + this->svc_handler_ = svc_handler; + this->restart_ = restart; + ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value (); + + if (tv != 0 + && this->reactor ()->schedule_timer (this, + synch_options.arg (), + *tv) == 0) + return -1; + else + return this->reactor ()->register_handler + (this, + ACE_Event_Handler::ACCEPT_MASK); + } +} + +// Bridge method for activating a with the appropriate +// concurrency strategy. The default behavior of this method is to +// activate the SVC_HANDLER by calling its open() method (which allows +// the SVC_HANDLER to define its own concurrency strategy). However, +// subclasses can override this strategy to do more sophisticated +// concurrency activations (such as creating the SVC_HANDLER as an +// "active object" via multi-threading or multi-processing). + +template int +ACE_Oneshot_Acceptor::activate_svc_handler + (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::activate_svc_handler"); + return this->concurrency_strategy_->activate_svc_handler + (svc_handler, + (void *) this); +} + +// Factors out the code shared between the and +// methods. + +template int +ACE_Oneshot_Acceptor::shared_accept + (SVC_HANDLER *svc_handler, + ACE_PEER_ACCEPTOR_ADDR *remote_addr, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::shared_accept"); + if (svc_handler == 0) + return -1; + + // Accept connection into the Svc_Handler. + else if (this->peer_acceptor_.accept (svc_handler->peer (), // stream + remote_addr, // remote address + timeout, // timeout + restart, // restart + reset_new_handle // reset new handle + ) == -1) + { + // Check whether we just timed out or whether we failed... + if (!(errno == EWOULDBLOCK || errno == ETIME)) + // Close down handler to avoid memory leaks. + svc_handler->close (CLOSE_DURING_NEW_CONNECTION); + return -1; + } + // Activate the using the designated concurrency + // strategy (note that this method becomes responsible for handling + // errors and freeing up the memory if things go awry...) + else + return this->activate_svc_handler (svc_handler); +} + +// Make a SVC_HANDLER, accept the connection into the SVC_HANDLER, and +// then activate the SVC_HANDLER. Note that SVC_HANDLER::open() +// decides what type of concurrency strategy to use. + +template int +ACE_Oneshot_Acceptor::accept + (SVC_HANDLER *svc_handler, + ACE_PEER_ACCEPTOR_ADDR *remote_addr, + const ACE_Synch_Options &synch_options, + int restart, + int reset_new_handle) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::accept"); + // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y > + // 0) then this->connector_.connect() will block synchronously. If + // is set then we don't want this to happen (since we + // want the ACE_Reactor to do the timeout asynchronously). + // Therefore, we'll force this->connector_ to use ACE_Time_Value (0, + // 0) in this case... + + ACE_Time_Value *timeout; + int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR]; + + if (use_reactor) + timeout = (ACE_Time_Value *) &ACE_Time_Value::zero; + else + timeout = (ACE_Time_Value *) synch_options.time_value (); + + if (this->shared_accept (svc_handler, // stream + remote_addr, // remote address + timeout, // timeout + restart, // restart + reset_new_handle // reset new handler + ) == -1) + { + if (use_reactor && errno == EWOULDBLOCK) + // We couldn't accept right away, so let's wait in the + // . + this->register_handler (svc_handler, + synch_options, + restart); + return -1; + } + return 0; +} + +// Accepts one pending connection from a client (since we're the +// "oneshot" Acceptor). + +template int +ACE_Oneshot_Acceptor::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::handle_input"); + int result = 0; + + // Cancel any timer that might be pending. + this->cancel (); + + // Try to find out if the implementation of the reactor that we are + // using requires us to reset the event association for the newly + // created handle. This is because the newly created handle will + // inherit the properties of the listen handle, including its event + // associations. + int reset_new_handle = this->reactor ()->uses_event_associations (); + + // There is a use-case whereby this object will be gone upon return + // from shared_accept - if the Svc_Handler deletes this Oneshot_Acceptor + // during the shared_accept/activation steps. So, do whatever we need + // to do with this object before calling shared_accept. + if (this->reactor ()) + this->reactor ()->remove_handler + (this, + ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL); + + if (this->shared_accept (this->svc_handler_, // stream + 0, // remote address + 0, // timeout + this->restart_, // restart + reset_new_handle // reset new handle + ) == -1) + result = -1; + + return result; +} + +// Hook called by the explicit dynamic linking facility. + +template int +ACE_Oneshot_Acceptor::init (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::init"); + return -1; +} + +template int +ACE_Oneshot_Acceptor::fini (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::fini"); + return this->handle_close (); +} + +template int +ACE_Oneshot_Acceptor::info (ACE_TCHAR **strp, + size_t length) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::info"); + ACE_TCHAR buf[BUFSIZ]; + ACE_TCHAR addr_str[BUFSIZ]; + ACE_PEER_ACCEPTOR_ADDR addr; + + if (this->peer_acceptor_.get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1) + return -1; + + ACE_OS::sprintf (buf, + ACE_TEXT ("%s\t %s %s"), + ACE_TEXT ("ACE_Oneshot_Acceptor"), + addr_str, + ACE_TEXT ("#oneshot acceptor factory\n")); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strsncpy (*strp, buf, length); + return static_cast (ACE_OS::strlen (buf)); +} + +template int +ACE_Oneshot_Acceptor::suspend (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::suspend"); + return this->reactor () && this->reactor ()->suspend_handler (this); +} + +template int +ACE_Oneshot_Acceptor::resume (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::resume"); + return this->reactor () && this->reactor ()->resume_handler (this); +} + +// Returns ACE_HANDLE of the underlying peer_acceptor. + +template ACE_HANDLE +ACE_Oneshot_Acceptor::get_handle (void) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +template ACE_PEER_ACCEPTOR & +ACE_Oneshot_Acceptor::acceptor (void) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::acceptor"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template +ACE_Oneshot_Acceptor::operator ACE_PEER_ACCEPTOR & () const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::operator ACE_PEER_ACCEPTOR &"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ACCEPTOR_CPP */ diff --git a/dep/ACE_wrappers/ace/Acceptor.h b/dep/ACE_wrappers/ace/Acceptor.h new file mode 100644 index 000000000..88329be53 --- /dev/null +++ b/dep/ACE_wrappers/ace/Acceptor.h @@ -0,0 +1,688 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Acceptor.h + * + * $Id: Acceptor.h 81460 2008-04-28 11:34:23Z elliott_c $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ACCEPTOR_H +#define ACE_ACCEPTOR_H + +#include /**/ "ace/pre.h" + +#include "ace/Service_Object.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Strategies_T.h" +#include "ace/Synch_Options.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Acceptor + * + * @brief Abstract factory for creating a service handler + * (SVC_HANDLER), accepting into the SVC_HANDLER, and + * activating the SVC_HANDLER. + * + * Implements the basic strategy for passively establishing + * connections with clients. An ACE_Acceptor is parameterized + * by concrete types that conform to the interfaces of + * PEER_ACCEPTOR and SVC_HANDLER. The PEER_ACCEPTOR is + * instantiated with a transport mechanism that passively + * establishes connections. The SVC_HANDLER is instantiated + * with a concrete type that performs the application-specific + * service. An ACE_Acceptor inherits from ACE_Service_Object, + * which in turn inherits from ACE_Event_Handler. This enables + * the ACE_Reactor to dispatch the ACE_Acceptor's handle_input + * method when connection events occur. The handle_input method + * performs the ACE_Acceptor's default creation, connection + * establishment, and service activation strategies. These + * strategies can be overridden by subclasses individually or as + * a group. + */ +template +class ACE_Acceptor : public ACE_Service_Object +{ +public: + + // Useful STL-style traits. + typedef ACE_PEER_ACCEPTOR_ADDR addr_type; + typedef ACE_PEER_ACCEPTOR acceptor_type; + typedef SVC_HANDLER handler_type; + typedef typename SVC_HANDLER::stream_type stream_type; + + /// "Do-nothing" constructor. + ACE_Acceptor (ACE_Reactor * = 0, + int use_select = 1); + + /** + * Open the contained @c PEER_ACCEPTOR object to begin listening, and + * register with the specified reactor for accept events. An + * acceptor can only listen to one port at a time, so make sure to + * @c close() the acceptor before calling @c open() again. + * + * The @c PEER_ACCEPTOR handle is put into non-blocking mode as a + * safeguard against the race condition that can otherwise occur + * between the time when the passive-mode socket handle is "ready" + * and when the actual @c accept() call is made. During this + * interval, the client can shutdown the connection, in which case, + * the @c accept() call can hang. + * + * @param local_addr The address to listen at. + * @param reactor Pointer to the ACE_Reactor instance to register + * this object with. The default is the singleton. + * @param flags Flags to control what mode an accepted socket + * will be put into after it is accepted. The only + * legal value for this argument is @c ACE_NONBLOCK, + * which enables non-blocking mode on the accepted + * peer stream object in @c SVC_HANDLER. The default + * is 0. + * @param use_select Affects behavior when called back by the reactor + * when a connection can be accepted. If non-zero, + * this object will accept all pending connections, + * intead of just the one that triggered the reactor + * callback. Uses ACE_OS::select() internally to + * detect any remaining acceptable connections. + * The default is 1. + * @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with + * @p local_addr. Generally used to request that the + * OS allow reuse of the listen port. The default is 1. + */ + ACE_Acceptor (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor = ACE_Reactor::instance (), + int flags = 0, + int use_select = 1, + int reuse_addr = 1); + + /** + * Open the contained @c PEER_ACCEPTOR object to begin listening, and + * register with the specified reactor for accept events. An + * acceptor can only listen to one port at a time, so make sure to + * @c close() the acceptor before calling @c open() again. + * + * The @c PEER_ACCEPTOR handle is put into non-blocking mode as a + * safeguard against the race condition that can otherwise occur + * between the time when the passive-mode socket handle is "ready" + * and when the actual @c accept() call is made. During this + * interval, the client can shutdown the connection, in which case, + * the @c accept() call can hang. + * + * @param local_addr The address to listen at. + * @param reactor Pointer to the ACE_Reactor instance to register + * this object with. The default is the singleton. + * @param flags Flags to control what mode an accepted socket + * will be put into after it is accepted. The only + * legal value for this argument is @c ACE_NONBLOCK, + * which enables non-blocking mode on the accepted + * peer stream object in @c SVC_HANDLER. The default + * is 0. + * @param use_select Affects behavior when called back by the reactor + * when a connection can be accepted. If non-zero, + * this object will accept all pending connections, + * intead of just the one that triggered the reactor + * callback. Uses ACE_OS::select() internally to + * detect any remaining acceptable connections. + * The default is 1. + * @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with + * @p local_addr. Generally used to request that the + * OS allow reuse of the listen port. The default is 1. + * + * @retval 0 Success + * @retval -1 Failure, @c errno contains an error code. + */ + virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor = ACE_Reactor::instance (), + int flags = 0, + int use_select = 1, + int reuse_addr = 1); + + /// Close down the Acceptor's resources. + virtual ~ACE_Acceptor (void); + + /// Return the underlying PEER_ACCEPTOR object. + virtual operator ACE_PEER_ACCEPTOR &() const; + + /// Return the underlying PEER_ACCEPTOR object. + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + + /// Returns the listening acceptor's {ACE_HANDLE}. + virtual ACE_HANDLE get_handle (void) const; + + /// Close down the Acceptor + virtual int close (void); + + /// In the event that an accept fails, this method will be called and + /// the return value will be returned from handle_input(). + virtual int handle_accept_error (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = The following three methods define the Acceptor's strategies + // for creating, accepting, and activating SVC_HANDLER's, + // respectively. + + /** + * Bridge method for creating a SVC_HANDLER. The default is to + * create a new {SVC_HANDLER} if {sh} == 0, else {sh} is unchanged. + * However, subclasses can override this policy to perform + * SVC_HANDLER creation in any way that they like (such as creating + * subclass instances of SVC_HANDLER, using a singleton, dynamically + * linking the handler, etc.). Returns -1 on failure, else 0. + */ + virtual int make_svc_handler (SVC_HANDLER *&sh); + + /** + * Bridge method for accepting the new connection into the + * . The default behavior delegates to the + * PEER_ACCEPTOR::accept. + */ + virtual int accept_svc_handler (SVC_HANDLER *svc_handler); + + /** + * Bridge method for activating a {svc_handler} with the appropriate + * concurrency strategy. The default behavior of this method is to + * activate the SVC_HANDLER by calling its {open} method (which + * allows the SVC_HANDLER to define its own concurrency strategy). + * However, subclasses can override this strategy to do more + * sophisticated concurrency activations (such as making the + * SVC_HANDLER as an "active object" via multi-threading or + * multi-processing). + */ + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + + // = Demultiplexing hooks. + /// Perform termination activities when {this} is removed from the + /// {reactor}. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Accepts all pending connections from clients, and creates and + /// activates SVC_HANDLERs. + virtual int handle_input (ACE_HANDLE); + + // = Dynamic linking hooks. + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Calls {handle_close}. + virtual int fini (void); + + /// Default version returns address info in {buf}. + virtual int info (ACE_TCHAR **buf, size_t) const; + +public: + // = Service management hooks. + /// This method calls {Reactor::suspend}. + virtual int suspend (void); + + /// This method calls {Reactor::resume}. + virtual int resume (void); + +protected: + /// Concrete factory for accepting connections from clients... + ACE_PEER_ACCEPTOR peer_acceptor_; + + /// Needed to reopen the socket if {accept} fails. + ACE_PEER_ACCEPTOR_ADDR peer_acceptor_addr_; + + /** + * Flags that indicate how {SVC_HANDLER}'s should be initialized + * prior to being activated. Right now, the only flag that is + * processed is {ACE_NONBLOCK}, which enabled non-blocking I/O on + * the {SVC_HANDLER} when it is opened. + */ + int flags_; + + /// Flag that indicates whether it shall use {select} in the + /// {accept}-loop. + int use_select_; + + /// Needed to reopen the socket if {accept} fails. + int reuse_addr_; +}; + +/** + * @class ACE_Strategy_Acceptor + * + * @brief Abstract factory for creating a service handler + * (SVC_HANDLER), accepting into the SVC_HANDLER, and activating + * the SVC_HANDLER. + * + * Implements a flexible and extensible set of strategies for + * passively establishing connections with clients. There are + * three main strategies: (1) creating a SVC_HANDLER, (2) + * passively accepting a new connection from a client into the + * SVC_HANDLER, and (3) activating the SVC_HANDLER with a + * particular concurrency mechanism. + */ +template +class ACE_Strategy_Acceptor + : public ACE_Acceptor +{ +public: + + // Useful STL-style traits. + typedef ACE_Creation_Strategy + creation_strategy_type; + typedef ACE_Accept_Strategy + accept_strategy_type; + typedef ACE_Concurrency_Strategy + concurrency_strategy_type; + typedef ACE_Scheduling_Strategy scheduling_strategy_type; + typedef ACE_Acceptor + base_type; + + // = Define some useful (old style) traits. + typedef ACE_Creation_Strategy CREATION_STRATEGY; + typedef ACE_Accept_Strategy ACCEPT_STRATEGY; + typedef ACE_Concurrency_Strategy CONCURRENCY_STRATEGY; + typedef ACE_Scheduling_Strategy SCHEDULING_STRATEGY; + + + + /// Default constructor. + ACE_Strategy_Acceptor (const ACE_TCHAR service_name[] = 0, + const ACE_TCHAR service_description[] = 0, + int use_select = 1, + int reuse_addr = 1); + + /** + * Initialize the appropriate strategies for creation, passive + * connection acceptance, and concurrency, and then register {this} + * with the Reactor and listen for connection requests at the + * designated {local_addr}. + */ + ACE_Strategy_Acceptor (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor * = ACE_Reactor::instance (), + ACE_Creation_Strategy * = 0, + ACE_Accept_Strategy * = 0, + ACE_Concurrency_Strategy * = 0, + ACE_Scheduling_Strategy * = 0, + const ACE_TCHAR service_name[] = 0, + const ACE_TCHAR service_description[] = 0, + int use_select = 1, + int reuse_addr = 1); + + /** + * Open the contained @c PEER_ACCEPTOR object to begin listening, and + * register with the specified reactor for accept events. + * + * The @c PEER_ACCEPTOR handle is put into non-blocking mode as a + * safeguard against the race condition that can otherwise occur + * between the time when the passive-mode socket handle is "ready" + * and when the actual @c accept call is made. During this + * interval, the client can shutdown the connection, in which case, + * the {accept} call can hang. + * + * @param local_addr The address to listen at. + * @param reactor Pointer to the ACE_Reactor instance to register + * this object with. The default is the singleton. + * @param flags Flags to control what mode an accepted socket + * will be put into after it is accepted. The only + * legal value for this argument is @c ACE_NONBLOCK, + * which enables non-blocking mode on the accepted + * peer stream object in @c SVC_HANDLER. The default + * is 0. + * @param use_select Affects behavior when called back by the reactor + * when a connection can be accepted. If non-zero, + * this object will accept all pending connections, + * intead of just the one that triggered the reactor + * callback. Uses ACE_OS::select() internally to + * detect any remaining acceptable connections. + * The default is 1. + * @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with + * @p local_addr. Generally used to request that the + * OS allow reuse of the listen port. The default is 1. + * + * @retval 0 Success + * @retval -1 Failure, @c errno contains an error code. + */ + virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor, + int flags = 0, + int use_select = 1, + int reuse_addr = 1); + + /** + * Initialize the appropriate strategies for creation, passive + * connection acceptance, and concurrency, and then register {this} + * with the Reactor and listen for connection requests at the + * designated {local_addr}. + */ + virtual int open (const ACE_PEER_ACCEPTOR_ADDR &, + ACE_Reactor * = ACE_Reactor::instance (), + ACE_Creation_Strategy * = 0, + ACE_Accept_Strategy * =0, + ACE_Concurrency_Strategy * = 0, + ACE_Scheduling_Strategy * = 0, + const ACE_TCHAR *service_name = 0, + const ACE_TCHAR *service_description = 0, + int use_select = 1, + int reuse_addr = 1); + + /// Close down the Strategy_Acceptor's resources. + virtual ~ACE_Strategy_Acceptor (void); + + /// Return the underlying PEER_ACCEPTOR object. + virtual operator ACE_PEER_ACCEPTOR &() const; + + /// Return the underlying PEER_ACCEPTOR object. + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + + /// Returns the listening acceptor's {ACE_HANDLE}. + virtual ACE_HANDLE get_handle (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Service management hooks. + + /// This method delegates to the {Scheduling_Strategy}'s {suspend} + /// method. + virtual int suspend (void); + + /// This method delegates to the {Scheduling_Strategy}'s {resume} + /// method. + virtual int resume (void); + +protected: + + /// Calls {handle_close} when dynamically unlinked. + virtual int fini (void); + + /// Default version returns address info in {buf}. + virtual int info (ACE_TCHAR **buf, size_t) const; + + // = The following three methods define the {Acceptor}'s strategies + // for creating, accepting, and activating {SVC_HANDLER}'s, + // respectively. + + /** + * Bridge method for creating a {SVC_HANDLER}. The strategy for + * creating a {SVC_HANDLER} are configured into the Acceptor via + * it's {creation_strategy_}. The default is to create a new + * {SVC_HANDLER} if {sh} == 0, else {sh} is unchanged. However, + * subclasses can override this policy to perform {SVC_HANDLER} + * creation in any way that they like (such as creating subclass + * instances of {SVC_HANDLER}, using a singleton, dynamically + * linking the handler, etc.). Returns -1 on failure, else 0. + */ + virtual int make_svc_handler (SVC_HANDLER *&); + + /** + * Bridge method for accepting the new connection into the + * {SVC_HANDLER}. The default behavior delegates to the + * {PEER_ACCEPTOR::accept} in the {Acceptor_Strategy}. + */ + virtual int accept_svc_handler (SVC_HANDLER *svc_handler); + + /** + * Bridge method for activating a {SVC_HANDLER} with the appropriate + * concurrency strategy. The default behavior of this method is to + * activate the {SVC_HANDLER} by calling its {open} method (which + * allows the {SVC_HANDLER} to define its own concurrency strategy). + * However, subclasses can override this strategy to do more + * sophisticated concurrency activations (such as creating the + * {SVC_HANDLER} as an "active object" via multi-threading or + * multi-processing). + */ + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + + // = Demultiplexing hooks. + /// Perform termination activities when {this} is removed from the + /// {Reactor}. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Handle SIGINT. + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + // = These data members are "logically private" but are put in the + // protected part in case subclasses want to access them. + + // = Strategy objects. + + /// Creation strategy for an Acceptor. + CREATION_STRATEGY *creation_strategy_; + + /// true if {Acceptor} created the creation strategy and thus should + /// delete it, else false. + bool delete_creation_strategy_; + + /// Accept strategy for an {Acceptor}. + ACCEPT_STRATEGY *accept_strategy_; + + /// true if {Acceptor} created the accept strategy and thus should delete + /// it, else false. + bool delete_accept_strategy_; + + /// Concurrency strategy for an {Acceptor}. + CONCURRENCY_STRATEGY *concurrency_strategy_; + + /// true if {Acceptor} created the concurrency strategy and thus should + /// delete it, else false. + bool delete_concurrency_strategy_; + + /// Scheduling strategy for an {Acceptor}. + SCHEDULING_STRATEGY *scheduling_strategy_; + + /// true if {Acceptor} created the scheduling strategy and thus should + /// delete it, else false. + bool delete_scheduling_strategy_; + + // = Service information objects. + + /// Name of the service. + ACE_TCHAR *service_name_; + + /// Description of the service. + ACE_TCHAR *service_description_; + + /// Address that the {Strategy_Acceptor} uses to listen for + /// connections. + ACE_PEER_ACCEPTOR_ADDR service_addr_; +}; + +/** + * @class ACE_Oneshot_Acceptor + * + * @brief Generic factory for passively connecting clients and creating + * exactly one service handler (SVC_HANDLER). + * + * This class works similarly to the regular {ACE_Acceptor}, + * with the following differences: + * 1. This class doesn't automagically register {this} with the + * {ACE_Reactor} since it expects to have its {accept} method + * called directly. However, it stashes the {ACE_Reactor} + * pointer away in case it's needed later to finish accepting + * a connection asynchronously. + * 2. The class doesn't need an {ACE_Creation_Strategy} (since + * the user supplies the SVC_HANDLER) or an + * {ACE_Accept_Strategy} (since this class only accepts one + * connection and then removes all traces of itself from the + * {ACE_Reactor} if it was registered for asynchronous + * accepts). + */ +template +class ACE_Oneshot_Acceptor : public ACE_Service_Object +{ +public: + + // Useful STL-style traits. + typedef ACE_PEER_ACCEPTOR_ADDR addr_type; + typedef ACE_PEER_ACCEPTOR acceptor_type; + typedef SVC_HANDLER handler_type; + typedef typename SVC_HANDLER::stream_type stream_type; + + /// Constructor. + ACE_Oneshot_Acceptor (void); + + /** + * Initialize the appropriate strategies for concurrency and then + * open the {peer_acceptor} at the designated {local_addr}. Note + * that unlike the {ACE_Acceptor} and {ACE_Strategy_Acceptor}, this + * method does NOT register {this} acceptor with the {reactor} at + * this point -- it just stashes the {reactor} away in case it's + * needed later. + */ + ACE_Oneshot_Acceptor (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor *reactor = ACE_Reactor::instance (), + ACE_Concurrency_Strategy * = 0); + + /** + * Initialize the appropriate strategies for concurrency and then + * open the {peer_acceptor} at the designated {local_addr}. Note + * that unlike the {ACE_Acceptor} and {ACE_Strategy_Acceptor}, this + * method does NOT register {this} acceptor with the {reactor} at + * this point -- it just stashes the {reactor} away in case it's + * needed later. + */ + int open (const ACE_PEER_ACCEPTOR_ADDR &, + ACE_Reactor *reactor = ACE_Reactor::instance (), + ACE_Concurrency_Strategy * = 0); + + /// Close down the {Oneshot_Acceptor}. + virtual ~ACE_Oneshot_Acceptor (void); + + // = Explicit factory operation. + /// Create a {SVC_HANDLER}, accept the connection into the + /// {SVC_HANDLER}, and activate the {SVC_HANDLER}. + virtual int accept (SVC_HANDLER * = 0, + ACE_PEER_ACCEPTOR_ADDR *remote_addr = 0, + const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults, + int restart = 1, + int reset_new_handle = 0); + + /// Cancel a oneshot acceptor that was started asynchronously. + virtual int cancel (void); + + /// Return the underlying {PEER_ACCEPTOR} object. + virtual operator ACE_PEER_ACCEPTOR &() const; + + /// Return the underlying {PEER_ACCEPTOR} object. + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + + /// Close down the {Oneshot_Acceptor}. + virtual int close (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /** + * Bridge method for activating a {svc_handler} with the appropriate + * concurrency strategy. Default behavior is to activate the + * {SVC_HANDLER} as a "passive object." However, subclasses can + * override this strategy to do more sophisticated concurrency + * activations (such as creating the {SVC_HANDLER} as an "active + * object" via multi-threading or multi-processing). + */ + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + + /// Factors out the code shared between the {accept} and + /// {handle_input} methods. + int shared_accept (SVC_HANDLER *svc_handler, + ACE_PEER_ACCEPTOR_ADDR *remote_addr, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle); + + // = Demultiplexing hooks. + /// Returns the listening acceptor's {ACE_HANDLE}. + virtual ACE_HANDLE get_handle (void) const; + + /// Perform termination activities when {this} is removed from the + /// {reactor}. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Accept one connection from a client and activates the + /// SVC_HANDLER. + virtual int handle_input (ACE_HANDLE); + + /// Called when an acceptor times out... + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + + // = Dynamic linking hooks. + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int fini (void); + + /// Default version returns address info in {buf}. + virtual int info (ACE_TCHAR **, size_t) const; + + // = Service management hooks. + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int suspend (void); + + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int resume (void); + +private: + /** + * Insert ourselves into the {ACE_Reactor} so that we can continue + * accepting this connection asynchronously. This method should NOT + * be called by developers directly. + */ + int register_handler (SVC_HANDLER *svc_handler, + const ACE_Synch_Options &options, + int restart); + + /// Hold the svc_handler_ across asynchrony boundaries. + SVC_HANDLER *svc_handler_; + + /// Hold the restart flag across asynchrony boundaries. + int restart_; + + /// Factory that establishes connections passively. + ACE_PEER_ACCEPTOR peer_acceptor_; + + /// Concurrency strategy for an Acceptor. + ACE_Concurrency_Strategy *concurrency_strategy_; + + /// true if Acceptor created the concurrency strategy and thus should + /// delete it, else false. + bool delete_concurrency_strategy_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Acceptor.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Acceptor.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ACCEPTOR_H */ diff --git a/dep/ACE_wrappers/ace/Activation_Queue.cpp b/dep/ACE_wrappers/ace/Activation_Queue.cpp new file mode 100644 index 000000000..f18ada06e --- /dev/null +++ b/dep/ACE_wrappers/ace/Activation_Queue.cpp @@ -0,0 +1,138 @@ +#include "ace/Activation_Queue.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Activation_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/Method_Request.h" +#include "ace/Malloc_Base.h" +#include "ace/Time_Value.h" + +ACE_RCSID (ace, + Activation_Queue, + "$Id: Activation_Queue.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_Activation_Queue::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("delete_queue_ = %d\n"), + this->delete_queue_)); + ACE_DEBUG ((LM_INFO, ACE_TEXT ("queue_: \n"))); + if (this->queue_) + this->queue_->dump(); + else + //FUZZ: disable check_for_NULL + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(NULL)\n"))); + //FUZZ: enable check_for_NULL + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Activation_Queue::ACE_Activation_Queue (ACE_Message_Queue *new_queue, + ACE_Allocator *alloc, + ACE_Allocator *db_alloc) + : delete_queue_ (false) + , allocator_(alloc) + , data_block_allocator_(db_alloc) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + if (new_queue) + this->queue_ = new_queue; + else + { + ACE_NEW (this->queue_, + ACE_Message_Queue); + this->delete_queue_ = true; + } +} + +void +ACE_Activation_Queue::queue (ACE_Message_Queue *q) +{ + // Destroy the internal queue if one exist. + if (this->delete_queue_) + { + // Destroy the current queue. + delete this->queue_; + + // Set the flag to false. NOTE that the delete_queue_ flag is a + // flag used to only indicate whether or not if an internal + // ACE_Message_Queue has been created, therefore, it will not + // affect the user if the user decided to replace the queue with + // their own queue no matter how many time they call on this + // function. + this->delete_queue_ = false; + } + + queue_ = q; +} + +ACE_Activation_Queue::~ACE_Activation_Queue (void) +{ + if (this->delete_queue_) + delete this->queue_; +} + +ACE_Method_Request * +ACE_Activation_Queue::dequeue (ACE_Time_Value *tv) +{ + ACE_Message_Block *mb = 0; + + // Dequeue the message. + if (this->queue_->dequeue_head (mb, tv) != -1) + { + // Get the next . + ACE_Method_Request *mr = + reinterpret_cast (mb->base ()); + // Delete the message block. + mb->release (); + return mr; + } + else + return 0; +} + +int +ACE_Activation_Queue::enqueue (ACE_Method_Request *mr, + ACE_Time_Value *tv) +{ + ACE_Message_Block *mb = 0; + + // We pass sizeof (*mr) here so that flow control will work + // correctly. Since we also pass note that no unnecessary + // memory is actually allocated -- just the size field is set. + ACE_NEW_MALLOC_RETURN (mb, + static_cast (this->allocator_->malloc (sizeof (ACE_Message_Block))), + ACE_Message_Block (sizeof (*mr), // size + ACE_Message_Block::MB_DATA, // type + 0, // cont + (char *) mr, // data + 0, // allocator + 0, // locking strategy + mr->priority (), // priority + ACE_Time_Value::zero, // execution time + ACE_Time_Value::max_time, // absolute time of deadline + this->data_block_allocator_, // data_block allocator + this->allocator_), // message_block allocator + -1); + + // Enqueue in priority order. + int const result = this->queue_->enqueue_prio (mb, tv); + + // Free ACE_Message_Block if enqueue_prio failed. + if (result == -1) + ACE_DES_FREE (mb, this->allocator_->free, ACE_Message_Block); + + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Activation_Queue.h b/dep/ACE_wrappers/ace/Activation_Queue.h new file mode 100644 index 000000000..454640474 --- /dev/null +++ b/dep/ACE_wrappers/ace/Activation_Queue.h @@ -0,0 +1,173 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Activation_Queue.h + * + * $Id: Activation_Queue.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Andres Kruse + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ACTIVATION_QUEUE_H +#define ACE_ACTIVATION_QUEUE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Message_Queue.h" +#include "ace/Condition_Thread_Mutex.h" + +/// Define to be compatible with the terminology in the POSA2 book! +#define ACE_Activation_List ACE_Activation_Queue + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Method_Request; + +/** + * @class ACE_Activation_Queue + * + * @brief Reifies a method into a request. Subclasses typically + * represent necessary state and behavior. + * + * Maintains a priority-ordered queue of ACE_Method_Request objects. + * A scheduler class (often derived from ACE_Task) subsequently removes + * each method request and invokes its @c call() method. + * + * This class is discussed in depth in the Active Object chapter + * of POSA2. In that book, it is referred to as an Activation List. + * + * @sa ACE_Method_Request + */ +class ACE_Export ACE_Activation_Queue +{ +public: + // = Initialization and termination methods. + /// Constructor. + /** + * Initializes a new activation queue. + * + * @param new_queue The activation queue uses an ACE_Message_Queue to + * queue and order the method requests. If this argument + * is 0, a new ACE_Message_Queue is created for this + * object's use and will be deleted when this object is + * destroyed. If a non-zero pointer is supplied, the + * passed object will be used and will not be deleted when + * this object is destroyed. If an ACE_Task is being created + * to act as the scheduler, for instance, its + * ACE_Message_Queue pointer can be passed to this object. + * @param alloc Optional, the allocator to use when allocating + * ACE_Message_Block instances that wrap the method requests + * queued to this activation queue. Defaults to + * ACE_Allocator::instance(). + * @param db_alloc Optional, the allocator to use when allocating + * data blocks for the ACE_Message_Block instances that + * wrap the method requests queued to this activation queue. + * Defaults to ACE_Allocator::instance(). + */ + ACE_Activation_Queue (ACE_Message_Queue *new_queue = 0, + ACE_Allocator *alloc = 0, + ACE_Allocator *db_alloc = 0); + + /// Destructor. + virtual ~ACE_Activation_Queue (void); + + // = Activate Queue operations. + + /// Dequeue the next available ACE_Method_Request. + /** + * @param tv If 0, the method will block until a method request is + * available, else will wait until the absolute time specified + * in the referenced ACE_Time_Value. This method will return, + * earlier, however, if queue is closed, deactivated, or when + * a signal occurs. + * + * @retval Pointer to the dequeued ACE_Method_Request object. + * @retval 0 an error occurs; errno contains further information. If + * the specified timeout elapses, errno will be @c EWOULDBLOCK. + */ + ACE_Method_Request *dequeue (ACE_Time_Value *tv = 0); + + /// Enqueue the ACE_Method_Request in priority order. + /** + * The priority of the method request is obtained via the @c priority() + * method of the queued method request. Priority ordering is determined + * by the ACE_Message_Queue class; 0 is the lowest priority. + * + * @param new_method_request Pointer to the ACE_Method_Request object to + * queue. This object's @c priority() method is called to obtain + * the priority. + * @param tv If 0, the method will block until the method request can + * be queued, else will wait until the absolute time specified + * in the referenced ACE_Time_Value. This method will return, + * earlier, however, if queue is closed, deactivated, or when + * a signal occurs. + * + * @retval >0 The number of method requests on the queue after adding + * the specified request. + * @retval -1 if an error occurs; errno contains further information. If + * the specified timeout elapses, errno will be @c EWOULDBLOCK. + */ + int enqueue (ACE_Method_Request *new_method_request, ACE_Time_Value *tv = 0); + + /// Get the current number of method objects in the queue. + size_t method_count (void) const; + + /// Returns 1 if the queue is empty, 0 otherwise. + int is_empty (void) const; + + /// Returns 1 if the queue is full, 0 otherwise. + int is_full (void) const; + + /// Dump the state of an request. + void dump (void) const; + + /// Get a pointer to the underlying queue. + ACE_Message_Queue *queue (void) const; + + /// Set the pointer to the underlying queue. + void queue (ACE_Message_Queue *q); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + // = Prevent copying and assignment. + ACE_Activation_Queue (const ACE_Activation_Queue &); + void operator= (const ACE_Activation_Queue &); + +protected: + + /// Stores the Method_Requests. + ACE_Message_Queue *queue_; + + /// Keeps track of whether we need to delete the queue. + bool delete_queue_; + +private: + + /// Allocation strategy of the queue. + ACE_Allocator *allocator_; + + /// Allocation strategy of the message blocks. + ACE_Allocator *data_block_allocator_; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Activation_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_ACTIVATION_QUEUE_H */ diff --git a/dep/ACE_wrappers/ace/Activation_Queue.inl b/dep/ACE_wrappers/ace/Activation_Queue.inl new file mode 100644 index 000000000..4c0ffc049 --- /dev/null +++ b/dep/ACE_wrappers/ace/Activation_Queue.inl @@ -0,0 +1,31 @@ +// -*- C++ -*- +// +// $Id: Activation_Queue.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE size_t +ACE_Activation_Queue::method_count (void) const +{ + return queue_->message_count (); +} + +ACE_INLINE int +ACE_Activation_Queue::is_full (void) const +{ + return queue_->is_full (); +} + +ACE_INLINE int +ACE_Activation_Queue::is_empty (void) const +{ + return queue_->is_empty (); +} + +ACE_INLINE ACE_Message_Queue * +ACE_Activation_Queue::queue (void) const +{ + return queue_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Active_Map_Manager.cpp b/dep/ACE_wrappers/ace/Active_Map_Manager.cpp new file mode 100644 index 000000000..6ec891b5d --- /dev/null +++ b/dep/ACE_wrappers/ace/Active_Map_Manager.cpp @@ -0,0 +1,9 @@ +// $Id: Active_Map_Manager.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Active_Map_Manager.h" + +ACE_RCSID(ace, Active_Map_Manager, "$Id: Active_Map_Manager.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (__ACE_INLINE__) +#include "ace/Active_Map_Manager.inl" +#endif /* __ACE_INLINE__ */ diff --git a/dep/ACE_wrappers/ace/Active_Map_Manager.h b/dep/ACE_wrappers/ace/Active_Map_Manager.h new file mode 100644 index 000000000..d1558b146 --- /dev/null +++ b/dep/ACE_wrappers/ace/Active_Map_Manager.h @@ -0,0 +1,116 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Active_Map_Manager.h + * + * $Id: Active_Map_Manager.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali + */ +//============================================================================= + + +#ifndef ACE_ACTIVE_MAP_MANAGER_H +#define ACE_ACTIVE_MAP_MANAGER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Basic_Types.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Active_Map_Manager_Key + * + * @brief Key used in the Active Object Map. + * + * This key keeps information of the index and the generation + * count of the slot it represents. Since the index information + * is part of the key, lookups are super fast and predictable, + */ +class ACE_Export ACE_Active_Map_Manager_Key +{ +public: + /// Default constructor. + ACE_Active_Map_Manager_Key (void); + + /** + * Constructor given the @a slot_index and @a slot_generation number. + * This is useful once the user has somehow recovered the + * @a slot_index and @a slot_generation number from the client. + */ + ACE_Active_Map_Manager_Key (ACE_UINT32 slot_index, + ACE_UINT32 slot_generation); + + /// Get the slot_index. + ACE_UINT32 slot_index (void) const; + + /// Set the slot_index. + void slot_index (ACE_UINT32 i); + + /// Get the slot_generation number. + ACE_UINT32 slot_generation (void) const; + + /// Set the slot_generation number. + void slot_generation (ACE_UINT32 g); + + /// Size required to store information about active key. + static size_t size (void); + + /// Recover state of active key from @a data. User must make sure + /// that @a data encoded using the encode() method. + void decode (const void *data); + + /// Encode state of the active key into @a data. @a data must be as + /// big as the value returned from . + void encode (void *data) const; + + /// Compare keys. + bool operator== (const ACE_Active_Map_Manager_Key &rhs) const; + bool operator!= (const ACE_Active_Map_Manager_Key &rhs) const; + + // = This really should be protected but because of template + // friends, they are not. + + /// Increment the number. + void increment_slot_generation_count (void); + +private: + + /** + * @brief Data for the Active Object Map Key. + * + * This separate structure makes it easier to manage copying + * the index and the generation to and from the user buffer. + * + */ + struct key_data + { + /// Slot index in the active map. + ACE_UINT32 slot_index_; + + /// Slot generation number of slot in the active map. + ACE_UINT32 slot_generation_; + }; + + /// Data for the Active Object Map Key. + key_data key_data_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Active_Map_Manager.inl" +#endif /* __ACE_INLINE__ */ + +// Include the templates here. +#include "ace/Active_Map_Manager_T.h" + +#include /**/ "ace/post.h" +#endif /* ACE_ACTIVE_MAP_MANAGER_H */ diff --git a/dep/ACE_wrappers/ace/Active_Map_Manager.inl b/dep/ACE_wrappers/ace/Active_Map_Manager.inl new file mode 100644 index 000000000..df90ada6a --- /dev/null +++ b/dep/ACE_wrappers/ace/Active_Map_Manager.inl @@ -0,0 +1,95 @@ +// -*- C++ -*- +// +// $Id: Active_Map_Manager.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Active_Map_Manager_Key::ACE_Active_Map_Manager_Key (void) +{ + // If you change ~0, please change ACE_Map_Manager::free_list_id() + // accordingly. + this->key_data_.slot_index_ = (ACE_UINT32) ~0; + this->key_data_.slot_generation_ = 0; +} + +ACE_INLINE +ACE_Active_Map_Manager_Key::ACE_Active_Map_Manager_Key (ACE_UINT32 slot_index, + ACE_UINT32 slot_generation) +{ + this->key_data_.slot_index_ = slot_index; + this->key_data_.slot_generation_ = slot_generation; +} + +ACE_INLINE ACE_UINT32 +ACE_Active_Map_Manager_Key::slot_index (void) const +{ + return this->key_data_.slot_index_; +} + +ACE_INLINE ACE_UINT32 +ACE_Active_Map_Manager_Key::slot_generation (void) const +{ + return this->key_data_.slot_generation_; +} + +ACE_INLINE bool +ACE_Active_Map_Manager_Key::operator== (const ACE_Active_Map_Manager_Key &rhs) const +{ + return + this->key_data_.slot_index_ == rhs.key_data_.slot_index_ && + this->key_data_.slot_generation_ == rhs.key_data_.slot_generation_; +} + +ACE_INLINE bool +ACE_Active_Map_Manager_Key::operator!= (const ACE_Active_Map_Manager_Key &rhs) const +{ + return !this->operator== (rhs); +} + +ACE_INLINE void +ACE_Active_Map_Manager_Key::slot_index (ACE_UINT32 i) +{ + this->key_data_.slot_index_ = i; +} + +ACE_INLINE void +ACE_Active_Map_Manager_Key::slot_generation (ACE_UINT32 g) +{ + this->key_data_.slot_generation_ = g; +} + +ACE_INLINE void +ACE_Active_Map_Manager_Key::increment_slot_generation_count (void) +{ + ++this->key_data_.slot_generation_; +} + +/* static */ +ACE_INLINE size_t +ACE_Active_Map_Manager_Key::size (void) +{ + return sizeof (ACE_UINT32) + sizeof (ACE_UINT32); +} + +ACE_INLINE void +ACE_Active_Map_Manager_Key::decode (const void *data) +{ + // Copy the information from the user buffer into the key. + ACE_OS::memcpy (&this->key_data_, + data, + sizeof this->key_data_); +} + +ACE_INLINE void +ACE_Active_Map_Manager_Key::encode (void *data) const +{ + // Copy the key data to the user buffer. + ACE_OS::memcpy (data, + &this->key_data_, + sizeof this->key_data_); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Active_Map_Manager_T.cpp b/dep/ACE_wrappers/ace/Active_Map_Manager_T.cpp new file mode 100644 index 000000000..732cc2951 --- /dev/null +++ b/dep/ACE_wrappers/ace/Active_Map_Manager_T.cpp @@ -0,0 +1,22 @@ +// $Id: Active_Map_Manager_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_ACTIVE_MAP_MANAGER_T_CPP +#define ACE_ACTIVE_MAP_MANAGER_T_CPP + +#include "ace/Active_Map_Manager_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Active_Map_Manager_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Active_Map_Manager) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ACTIVE_MAP_MANAGER_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Active_Map_Manager_T.h b/dep/ACE_wrappers/ace/Active_Map_Manager_T.h new file mode 100644 index 000000000..f63d43537 --- /dev/null +++ b/dep/ACE_wrappers/ace/Active_Map_Manager_T.h @@ -0,0 +1,211 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Active_Map_Manager_T.h + * + * $Id: Active_Map_Manager_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali + */ +//============================================================================= + + +#ifndef ACE_ACTIVE_MAP_MANAGER_T_H +#define ACE_ACTIVE_MAP_MANAGER_T_H +#include /**/ "ace/pre.h" + +#include "ace/Map_Manager.h" +#include "ace/Active_Map_Manager.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Null_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Active_Map_Manager + * + * @brief Define a map abstraction that associates system generated + * keys with user specified values. + * + * Since the key is system generated, searches are very fast and + * take a constant amount of time. + */ +template +class ACE_Active_Map_Manager : public ACE_Map_Manager +{ +public: + + // = Traits. + typedef ACE_Active_Map_Manager_Key key_type; + typedef T mapped_type; + + typedef ACE_Map_Entry ENTRY; + typedef ACE_Map_Iterator ITERATOR; + typedef ACE_Map_Reverse_Iterator REVERSE_ITERATOR; + + typedef ENTRY entry; + typedef ITERATOR iterator; + typedef REVERSE_ITERATOR reverse_iterator; + + // = Initialization and termination methods. + /// Initialize a with the ACE_DEFAULT_MAP_SIZE. + ACE_Active_Map_Manager (ACE_Allocator *alloc = 0); + + /// Initialize a with @a size entries. + ACE_Active_Map_Manager (size_t size, + ACE_Allocator *alloc = 0); + + /// Close down a and release dynamically + /// allocated resources. + ~ACE_Active_Map_Manager (void); + + /// Initialize a with size @a length. + int open (size_t length = ACE_DEFAULT_MAP_SIZE, + ACE_Allocator *alloc = 0); + + /// Close down a and release dynamically + /// allocated resources. + int close (void); + + /// Add @a value to the map, and the corresponding key produced by the + /// Active_Map_Manager is returned through @a key. + int bind (const T &value, + ACE_Active_Map_Manager_Key &key); + + /// Add @a value to the map. The user does not care about the + /// corresponding key produced by the Active_Map_Manager. + int bind (const T &value); + + /** + * Reserves a slot in the internal structure and returns the key and + * a pointer to the value. User should place their @a value into + * <*internal_value>. This method is useful in reducing the number + * of copies required in some cases. Note that is + * only a temporary pointer and will change when the map resizes. + * Therefore, the user should use the pointer immediately and not + * hold on to it. + */ + int bind (ACE_Active_Map_Manager_Key &key, + T *&internal_value); + + /// Reassociate @a key with @a value. The function fails if @a key is + /// not in the map. + int rebind (const ACE_Active_Map_Manager_Key &key, + const T &value); + + /** + * Reassociate @a key with @a value, storing the old value into the + * "out" parameter @a old_value. The function fails if @a key is not + * in the map. + */ + int rebind (const ACE_Active_Map_Manager_Key &key, + const T &value, + T &old_value); + + /** + * Reassociate @a key with @a value, storing the old key and value + * into the "out" parameter @a old_key and @a old_value. The function + * fails if @a key is not in the map. + */ + int rebind (const ACE_Active_Map_Manager_Key &key, + const T &value, + ACE_Active_Map_Manager_Key &old_key, + T &old_value); + + /// Locate @a value associated with @a key. + int find (const ACE_Active_Map_Manager_Key &key, + T &value) const; + + /// Is @a key in the map? + int find (const ACE_Active_Map_Manager_Key &key) const; + + /** + * Locate @a value associated with @a key. The value is returned via + * and hence a copy is saved. Note that + * is only a temporary pointer and will change when + * the map resizes. Therefore, the user should use the pointer + * immediately and not hold on to it. + */ + int find (const ACE_Active_Map_Manager_Key &key, + T *&internal_value) const; + + // Creates a key. User should place their @a value into + // <*internal_value>. This method is useful in reducing the number + // of copies required in some cases. + + /// Remove @a key from the map. + int unbind (const ACE_Active_Map_Manager_Key &key); + + /// Remove @a key from the map, and return the @a value associated with + /// @a key. + int unbind (const ACE_Active_Map_Manager_Key &key, + T &value); + + /** + * Locate @a value associated with @a key. The value is returned via + * and hence a copy is saved. Note that + * is only a temporary pointer and will change when + * the map resizes or when this slot is reused. Therefore, the user + * should use the pointer immediately and not hold on to it. + */ + int unbind (const ACE_Active_Map_Manager_Key &key, + T *&internal_value); + + /// Return the current size of the map. + size_t current_size (void) const; + + /// Return the total size of the map. + size_t total_size (void) const; + + /// Returns a key that cannot be found in the map. + static const ACE_Active_Map_Manager_Key npos (void); + + /// Dump the state of an object. + void dump (void) const; + + // = STL styled iterator factory functions. + + /// Return forward iterator. + ACE_Map_Iterator begin (void); + ACE_Map_Iterator end (void); + + /// Return reverse iterator. + ACE_Map_Reverse_Iterator rbegin (void); + ACE_Map_Reverse_Iterator rend (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + + /// Private base class + typedef ACE_Map_Manager ACE_AMM_BASE; + +private: + + // = Disallow these operations. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Active_Map_Manager &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Active_Map_Manager (const ACE_Active_Map_Manager &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Active_Map_Manager_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Active_Map_Manager_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Active_Map_Manager_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_ACTIVE_MAP_MANAGER_T_H */ diff --git a/dep/ACE_wrappers/ace/Active_Map_Manager_T.inl b/dep/ACE_wrappers/ace/Active_Map_Manager_T.inl new file mode 100644 index 000000000..647b55ebd --- /dev/null +++ b/dep/ACE_wrappers/ace/Active_Map_Manager_T.inl @@ -0,0 +1,311 @@ +// -*- C++ -*- +// +// $Id: Active_Map_Manager_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE int +ACE_Active_Map_Manager::bind (ACE_Active_Map_Manager_Key &key, + T *&internal_value) +{ + ACE_UINT32 slot_index; + int result = this->next_free (slot_index); + + if (result == 0) + { + // Move from free list to occupied list + this->move_from_free_list_to_occupied_list (slot_index); + + // Reset the key. + this->search_structure_[slot_index].ext_id_.increment_slot_generation_count (); + this->search_structure_[slot_index].ext_id_.slot_index (slot_index); + + // Copy the key for the user. + key = this->search_structure_[slot_index].ext_id_; + + // This is where the user should place the value. + internal_value = &this->search_structure_[slot_index].int_id_; + + // Update the current size. + ++this->cur_size_; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::bind (const T &value, + ACE_Active_Map_Manager_Key &key) +{ + T *internal_value = 0; + int result = this->bind (key, + internal_value); + + if (result == 0) + { + // Store new value. + *internal_value = value; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::bind (const T &value) +{ + ACE_Active_Map_Manager_Key key; + return this->bind (value, key); +} + +template ACE_INLINE int +ACE_Active_Map_Manager::find (const ACE_Active_Map_Manager_Key &key, + T *&internal_value) const +{ + ACE_UINT32 slot_index = key.slot_index (); + ACE_UINT32 slot_generation = key.slot_generation (); + + if (slot_index > this->total_size_ || +#if defined (ACE_HAS_LAZY_MAP_MANAGER) + this->search_structure_[slot_index].free_ || +#endif /* ACE_HAS_LAZY_MAP_MANAGER */ + this->search_structure_[slot_index].ext_id_.slot_generation () != slot_generation || + this->search_structure_[slot_index].ext_id_.slot_index () == + (ACE_UINT32)this->free_list_id ()) + { + return -1; + } + else + { + // This is where the user value is. + internal_value = &this->search_structure_[slot_index].int_id_; + } + + return 0; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::find (const ACE_Active_Map_Manager_Key &key) const +{ + T *internal_value = 0; + return this->find (key, + internal_value); +} + +template ACE_INLINE int +ACE_Active_Map_Manager::find (const ACE_Active_Map_Manager_Key &key, + T &value) const +{ + T *internal_value = 0; + int result = this->find (key, + internal_value); + + if (result == 0) + value = *internal_value; + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::rebind (const ACE_Active_Map_Manager_Key &key, + const T &value) +{ + int result = this->find (key); + + if (result == 0) + { + // Store new value. + this->search_structure_[key.slot_index ()].int_id_ = value; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::rebind (const ACE_Active_Map_Manager_Key &key, + const T &value, + T &old_value) +{ + int result = this->find (key); + + if (result == 0) + { + // Copy old value. + old_value = this->search_structure_[key.slot_index ()].int_id_; + + // Store new value. + this->search_structure_[key.slot_index ()].int_id_ = value; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::rebind (const ACE_Active_Map_Manager_Key &key, + const T &value, + ACE_Active_Map_Manager_Key &old_key, + T &old_value) +{ + int result = this->find (key); + + if (result == 0) + { + // Copy old key. + old_key = this->search_structure_[key.slot_index ()].ext_id_; + + // Copy old value. + old_value = this->search_structure_[key.slot_index ()].int_id_; + + // Store new value. + this->search_structure_[key.slot_index ()].int_id_ = value; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::unbind (const ACE_Active_Map_Manager_Key &key, + T *&internal_value) +{ + int result = this->find (key, + internal_value); + + if (result == 0) + { + ACE_UINT32 slot_index = key.slot_index (); + +#if defined (ACE_HAS_LAZY_MAP_MANAGER) + + // + // In the case of lazy map managers, the movement of free slots + // from the occupied list to the free list is delayed until we + // run out of free slots in the free list. + // + + this->search_structure_[slot_index].free_ = 1; + +#else + + // Move from occupied list to free list. + this->move_from_occupied_list_to_free_list (slot_index); + +#endif /* ACE_HAS_LAZY_MAP_MANAGER */ + + // Reset the slot_index. This will tell us that this entry is free. + this->search_structure_[slot_index].ext_id_.slot_index (this->free_list_id ()); + + // Update the current size. + --this->cur_size_; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::unbind (const ACE_Active_Map_Manager_Key &key, + T &value) +{ + T *internal_value; + int result = this->unbind (key, + internal_value); + + if (result == 0) + { + // Copy old value. + value = *internal_value; + } + + return result; +} + +template ACE_INLINE int +ACE_Active_Map_Manager::unbind (const ACE_Active_Map_Manager_Key &key) +{ + T *internal_value; + return this->unbind (key, + internal_value); +} + +template ACE_INLINE +ACE_Active_Map_Manager::ACE_Active_Map_Manager (ACE_Allocator *alloc) + : ACE_AMM_BASE (alloc) +{ +} + +template ACE_INLINE +ACE_Active_Map_Manager::ACE_Active_Map_Manager (size_t size, + ACE_Allocator *alloc) + : ACE_AMM_BASE (size, + alloc) +{ +} + +template ACE_INLINE +ACE_Active_Map_Manager::~ACE_Active_Map_Manager (void) +{ +} + +template ACE_INLINE int +ACE_Active_Map_Manager::open (size_t length, + ACE_Allocator *alloc) +{ + return ACE_AMM_BASE::open (length, alloc); +} + +template ACE_INLINE int +ACE_Active_Map_Manager::close (void) +{ + return ACE_AMM_BASE::close (); +} + +template ACE_INLINE size_t +ACE_Active_Map_Manager::current_size (void) const +{ + return ACE_AMM_BASE::current_size (); +} + +template ACE_INLINE size_t +ACE_Active_Map_Manager::total_size (void) const +{ + return ACE_AMM_BASE::total_size (); +} + +/* static */ +template ACE_INLINE const ACE_Active_Map_Manager_Key +ACE_Active_Map_Manager::npos (void) +{ + return ACE_Active_Map_Manager_Key (~0, ~0); +} + +template ACE_INLINE void +ACE_Active_Map_Manager::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_AMM_BASE::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_Map_Iterator +ACE_Active_Map_Manager::begin (void) +{ + return ACE_AMM_BASE::begin (); +} + +template ACE_INLINE ACE_Map_Iterator +ACE_Active_Map_Manager::end (void) +{ + return ACE_AMM_BASE::end (); +} + +template ACE_INLINE ACE_Map_Reverse_Iterator +ACE_Active_Map_Manager::rbegin (void) +{ + return ACE_AMM_BASE::rbegin (); +} + +template ACE_INLINE ACE_Map_Reverse_Iterator +ACE_Active_Map_Manager::rend (void) +{ + return ACE_AMM_BASE::rend (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Addr.cpp b/dep/ACE_wrappers/ace/Addr.cpp new file mode 100644 index 000000000..fb338f9ac --- /dev/null +++ b/dep/ACE_wrappers/ace/Addr.cpp @@ -0,0 +1,73 @@ +// $Id: Addr.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Addr.h" + + +ACE_RCSID (ace, + Addr, + "$Id: Addr.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +#if !defined (__ACE_INLINE__) +#include "ace/Addr.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/os_include/sys/os_socket.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Note: this object requires static construction and destruction. +/* static */ +const ACE_Addr ACE_Addr::sap_any (AF_ANY, -1); + +ACE_ALLOC_HOOK_DEFINE(ACE_Addr) + + +// Initializes instance variables. Note that 0 is an unspecified +// protocol family type... + +ACE_Addr::ACE_Addr (int type, int size) : + addr_type_ (type), + addr_size_ (size) +{ +} + +ACE_Addr::~ACE_Addr (void) +{ +} + +void * +ACE_Addr::get_addr (void) const +{ + return 0; +} + +void +ACE_Addr::set_addr (void *, int) +{ +} + +// Initializes instance variables. + +void +ACE_Addr::base_set (int type, int size) +{ + this->addr_type_ = type; + this->addr_size_ = size; +} + +void +ACE_Addr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("addr_type_ = %d"), this->addr_type_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\naddr_size_ = %d"), this->addr_size_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Addr.h b/dep/ACE_wrappers/ace/Addr.h new file mode 100644 index 000000000..e58ffe2c0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Addr.h @@ -0,0 +1,103 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Addr.h + * + * $Id: Addr.h 81030 2008-03-20 12:43:29Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ADDR_H +#define ACE_ADDR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Addr + * + * @brief Defines the base class for the "address family independent" + * address format. + */ +class ACE_Export ACE_Addr +{ +public: + // = Initialization and termination methods. + /// Initializes instance variables. + ACE_Addr (int type = -1, int size = -1); + + /// Destructor. + virtual ~ACE_Addr (void); + + // = Get/set the size of the address. + + /// Return the size of the address. + int get_size (void) const; + + /// Sets the size of the address. + void set_size (int size); + + // = Get/set the type of the address. + + /// Get the type of the address. + int get_type (void) const; + + /// Set the type of the address. + void set_type (int type); + + /// Return a pointer to the address. + virtual void *get_addr (void) const; + + /// Set a pointer to the address. + virtual void set_addr (void *, int len); + + // = Equality/inequality tests + /// Check for address equality. + bool operator == (const ACE_Addr &sap) const; + + /// Check for address inequality. + bool operator != (const ACE_Addr &sap) const; + + /// Initializes instance variables. + void base_set (int type, int size); + + /// Wild-card address. + static const ACE_Addr sap_any; + + /// Returns a hash value. This should be overwritten by a subclass + /// that can produce a better hash value. + virtual unsigned long hash (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// e.g., AF_UNIX, AF_INET, AF_SPIPE, etc. + int addr_type_; + + /// Number of bytes in the address. + int addr_size_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Addr.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ADDR_H */ diff --git a/dep/ACE_wrappers/ace/Addr.inl b/dep/ACE_wrappers/ace/Addr.inl new file mode 100644 index 000000000..44fd495a6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Addr.inl @@ -0,0 +1,61 @@ +// -*- C++ -*- +// +// $Id: Addr.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Return the address of the address. + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE bool +ACE_Addr::operator == (const ACE_Addr &sap) const +{ + return (sap.addr_type_ == this->addr_type_ && + sap.addr_size_ == this->addr_size_ ); +} + +ACE_INLINE bool +ACE_Addr::operator != (const ACE_Addr &sap) const +{ + return (sap.addr_type_ != this->addr_type_ || + sap.addr_size_ != this->addr_size_ ); +} + +// Return the size of the address. + +ACE_INLINE int +ACE_Addr::get_size (void) const +{ + return this->addr_size_; +} + +// Sets the size of the address. + +ACE_INLINE void +ACE_Addr::set_size (int size) +{ + this->addr_size_ = size; +} + +// Return the type of the address. + +ACE_INLINE int +ACE_Addr::get_type (void) const +{ + return this->addr_type_; +} + +// Set the type of the address. + +ACE_INLINE void +ACE_Addr::set_type (int type) +{ + this->addr_type_ = type; +} + +ACE_INLINE unsigned long +ACE_Addr::hash (void) const +{ + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Arg_Shifter.cpp b/dep/ACE_wrappers/ace/Arg_Shifter.cpp new file mode 100644 index 000000000..43d5074db --- /dev/null +++ b/dep/ACE_wrappers/ace/Arg_Shifter.cpp @@ -0,0 +1,230 @@ +#ifndef ACE_ARG_SHIFTER_T_CPP +#define ACE_ARG_SHIFTER_T_CPP + +#include "ace/Arg_Shifter.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_strings.h" +#include "ace/OS_Errno.h" +#include "ace/OS_Memory.h" + +ACE_RCSID (ace, + Arg_Shifter, + "$Id: Arg_Shifter.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Arg_Shifter_T::ACE_Arg_Shifter_T (int& argc, + const CHAR_TYPE** argv, + const CHAR_TYPE** temp) + : argc_ (argc), + total_size_ (argc), + temp_ (temp), + argv_ (argv), + current_index_ (0), + back_ (argc - 1), + front_ (0) +{ + this->init (); +} + +template +ACE_Arg_Shifter_T::ACE_Arg_Shifter_T (int& argc, + CHAR_TYPE** argv, + CHAR_TYPE** temp) + : argc_ (argc), + total_size_ (argc), + temp_ ((const CHAR_TYPE **) temp), + argv_ ((const CHAR_TYPE **) argv), + current_index_ (0), + back_ (argc - 1), + front_ (0) +{ + this->init (); +} + +template +void +ACE_Arg_Shifter_T::init (void) +{ + // If not provided with one, allocate a temporary array. + if (this->temp_ == 0) + ACE_NEW (this->temp_, + const CHAR_TYPE *[this->total_size_]); + + if (this->temp_ != 0) + { + // Fill the temporary array. + this->argc_ = 0; + for (int i = 0; i < this->total_size_; i++) + { + this->temp_[i] = this->argv_[i]; + this->argv_[i] = 0; + } + } + else + { + // Allocation failed, prohibit iteration. + this->current_index_ = this->argc_; + this->front_ = this->argc_; + } +} + +template +ACE_Arg_Shifter_T::~ACE_Arg_Shifter_T (void) +{ + // Delete the temporary vector. + delete [] temp_; +} + +template +const CHAR_TYPE * +ACE_Arg_Shifter_T::get_current (void) const +{ + const CHAR_TYPE * retval = 0; + + if (this->is_anything_left ()) + retval = this->temp_[current_index_]; + + return retval; +} + +template +const CHAR_TYPE * +ACE_Arg_Shifter_T::get_the_parameter (const CHAR_TYPE *flag) +{ + // the return 0's abound because this method + // would otherwise be a deep if { } else { } + + // check to see if any arguments still exist + if (!this->is_anything_left()) + return 0; + + // check to see if the flag is the argument + int const offset = this->cur_arg_strncasecmp (flag); + if (offset == -1) + return 0; + + if (offset == 0) + { + this->consume_arg (); + + if (!this->is_parameter_next()) + { + return 0; + } + } + // the parameter is in the middle somewhere... + return this->temp_[current_index_] + offset; +} + +template +int +ACE_Arg_Shifter_T::cur_arg_strncasecmp (const CHAR_TYPE *flag) +{ + // Check for a current argument + if (this->is_anything_left()) + { + size_t const flag_length = ACE_OS::strlen (flag); + + // Check for presence of the flag + if (ACE_OS::strncasecmp(this->temp_[current_index_], + flag, + flag_length) == 0) + { + if (ACE_OS::strlen(temp_[current_index_]) == + flag_length) + { + // match and lengths are equal + return 0; + } + else + { + // matches, with more info to boot! + size_t const remaining = ACE_OS::strspn + (this->temp_[current_index_] + flag_length, + ACE_TEXT (" ")) + flag_length; + return static_cast (remaining); + } + } + } + // failure + return -1; +} + +template +int +ACE_Arg_Shifter_T::consume_arg (int number) +{ + int retval = 0; + + // Stick knowns at the end of the vector (consumed). + if (this->is_anything_left() >= number) + { + for (int i = 0, j = this->back_ - (number - 1); + i < number; + ++i, ++j, ++this->current_index_) + this->argv_[j] = this->temp_[this->current_index_]; + + this->back_ -= number; + retval = 1; + } + + return retval; +} + +template +int +ACE_Arg_Shifter_T::ignore_arg (int number) +{ + int retval = 0; + + // Keep unknowns at the head of the vector. + if (this->is_anything_left () >= number) + { + for (int i = 0; + i < number; + i++, this->current_index_++, this->front_++) + this->argv_[this->front_] = this->temp_[this->current_index_]; + + retval = 1; + this->argc_ += number; + } + + return retval; +} + +template +int +ACE_Arg_Shifter_T::is_anything_left (void) const +{ + return this->total_size_ - this->current_index_; +} + +template +int +ACE_Arg_Shifter_T::is_option_next (void) const +{ + return this->is_anything_left () && + this->temp_[this->current_index_][0] == '-'; +} + +template +int +ACE_Arg_Shifter_T::is_parameter_next (void) const +{ + return this->is_anything_left () + && this->temp_[this->current_index_][0] != '-'; +} + +template +int +ACE_Arg_Shifter_T::num_ignored_args (void) const +{ + return this->front_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ATOMIC_OP_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Arg_Shifter.h b/dep/ACE_wrappers/ace/Arg_Shifter.h new file mode 100644 index 000000000..e143e57d1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Arg_Shifter.h @@ -0,0 +1,221 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Arg_Shifter.h + * + * $Id: Arg_Shifter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Seth Widoff + */ +//============================================================================= + +#ifndef ACE_ARG_SHIFTER_H +#define ACE_ARG_SHIFTER_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Arg_Shifter_T + * + * @brief This ADT operates on a specified set of arguments (@a argv). + * As known arguments are scanned, they are shifted to the back of the + * @a argv vector, so deeper levels of argument parsing can locate the yet + * unprocessed arguments at the beginning of the vector. + * + * The @c ACE_Arg_Shifter copies the pointers of the @a argv vector + * into a temporary array. As the @c ACE_Arg_Shifter iterates over + * the copied vector, it places known arguments in the rear of the + * vector, leaving the unknown ones in the beginning. So, after having + * visited all the arguments in the temporary vector, @c ACE_Arg_Shifter + * has placed all the unknown arguments in their original order at + * the front of original @a argv. + */ +template +class ACE_Arg_Shifter_T +{ +public: + // = Initialization and termination methods. + /** + * Initialize the ACE_Arg_Shifter to the vector over which to + * iterate. Optionally, also provide the temporary array for + * use in shifting the arguments. If ACE_Arg_Shifter must allocate + * the temporary vector internally and dynamic allocation fails, the + * ACE_Arg_Shifter will set all indicators to end of the vector, + * forbidding iteration. Following iteration over @a argv, the + * @a argc value will be updated to contain the number of + * unconsumed arguments. + * @param argc The number of strings in @a argv. @a argc will be + * updated to reflect the number of unconsumed arguments. + * @param argv The argument vector to shift. The string pointers in + * the vector will be reordered to place the @a argc unconsumed + * arguments at the front of the vector. + * @param temp A vector of @c CHAR_TYPE pointers at least @a argc + * elements long. The vector will be used for argument shifting as + * the specified @a argv vector is consumed. The vector must not + * be modified while this object exists. If this argument is 0 + * (the default) the object will allocate and free the temporary + * vector transparently. + */ + ACE_Arg_Shifter_T (int& argc, + const CHAR_TYPE **argv, + const CHAR_TYPE **temp = 0); + + /// Same behavior as the preceding constructor, but without the + /// "const" qualifier. + ACE_Arg_Shifter_T (int& argc, + CHAR_TYPE **argv, + CHAR_TYPE **temp = 0); + + /// Destructor. + ~ACE_Arg_Shifter_T (void); + + /// Get the current head of the vector. + const CHAR_TYPE *get_current (void) const; + + /** + * If the @a flag matches the current_arg of arg shifter + * this method will attempt to return the associated + * parameter value + * + * Safe to call without checking that a current arg exists + * + * In the following examples, a pointer to the char* "value" is ret + * + * eg: main -foobar value, main -FooBar value + * main -FOOBARvalue + * + * all of the above will all match the @a flag == -FooBar + * and will return a char* to "value" + * + * main -foobar 4 would succeed and return a char* to "4" + * main -foobar -4 does not succeed (-4 is not a parameter) + * but instead, would return 0 + * + * 0 is returned: + * If the current argument does not match flag + * If there is no parameter found after a 'matched' flag + * + * If the flag is matched and the flag and paramter DO NOT RUN + * together, the flag is consumed, the parameter is returned, + * and the new current argument is the parameter value. + * ie '-foobarflag VALUE' leaves the new cur arg == "VALUE" + * + * If the flag is matched and the flag and parameter RUN + * together '-foobarflagVALUE', the flag is NOT consumed + * and the cur arg is left pointing to the entire flag/value pair + */ + const CHAR_TYPE *get_the_parameter (const CHAR_TYPE* flag); + + /** + * Check if the current argument matches (case insensitive) + * + * ------------------------------------------------------------ + * + * Case A: Perfect Match (case insensitive) + * 0 is returned. + * + * ie: when current_arg = "-foobar" or "-FOOBAR" or "-fooBAR" + * this->cur_arg_strncasecmp ("-FooBar); + * will return 0 + * + * ------------------------------------------------------------ + * + * Case B: Perfect Match (case insensitive) but the current_arg + * is longer than the flag. Returns a number equal to the index + * in the char* indicating the start of the extra characters + * + * ie: when current_arg = "-foobar98023" + * this->cur_arg_strncasecmp ("-FooBar); + * will return 7 + * + * Notice: this number will always be > 0 + * + * ------------------------------------------------------------ + * + * Case C: If neither of Case A or B is met (no match) + * then -1 is returned + */ + int cur_arg_strncasecmp (const CHAR_TYPE *flag); + + /// Consume @a number argument(s) by sticking them/it on the end of + /// the vector. + int consume_arg (int number = 1); + + /// Place @a number arguments in the same relative order ahead of the + /// known arguments in the vector. + int ignore_arg (int number = 1); + + /// Returns the number of args left to see in the vector. + int is_anything_left (void) const; + + /// Returns 1 if there's a next item in the vector and it begins with + /// '-'. + int is_option_next (void) const; + + /// Returns 1 if there's a next item in the vector and it doesn't + /// begin with '-'. + int is_parameter_next (void) const; + + /// Returns the number of irrelevant args seen. + int num_ignored_args (void) const; + +private: + /// Copy Constructor should not be used. + ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T (const ACE_Arg_Shifter_T&)) + + /// Assignment '=' operator should not be used. + ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T operator= (const ACE_Arg_Shifter_T&)) + + /// Refactor the constructor logic. + void init (void); + + /// The size of the argument vector. + int& argc_; + + /// The size of argv_. + int total_size_; + + /// The temporary array over which we traverse. + const CHAR_TYPE **temp_; + + /// The array in which the arguments are reordered. + const CHAR_TYPE **argv_; + + /// The element in we're currently examining. + int current_index_; + + /// The index of in which we'll stick the next unknown + /// argument. + int back_; + + /// The index of in which we'll stick the next known + /// argument. + int front_; +}; + +typedef ACE_Arg_Shifter_T ACE_Arg_Shifter; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Arg_Shifter.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Arg_Shifter.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ARG_SHIFTER_H */ diff --git a/dep/ACE_wrappers/ace/Argv_Type_Converter.cpp b/dep/ACE_wrappers/ace/Argv_Type_Converter.cpp new file mode 100644 index 000000000..d594e6545 --- /dev/null +++ b/dep/ACE_wrappers/ace/Argv_Type_Converter.cpp @@ -0,0 +1,204 @@ +// $Id: Argv_Type_Converter.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Argv_Type_Converter.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Argv_Type_Converter.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Argv_Type_Converter, + "$Id: Argv_Type_Converter.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#include "ace/OS_NS_string.h" +#include "ace/OS_Errno.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_USES_WCHAR) +ACE_Argv_Type_Converter::ACE_Argv_Type_Converter (int &argc, wchar_t** argv) + : saved_argc_ (argc), + char_argv_ (0), + wchar_argv_ (argv), + before_pass_argc_ (argc), + original_type_ (true), + wchar_passed_ (false), + char_passed_ (false) +{ + this->initialize (); + + for (int i = 0; i < argc; ++i) + this->char_argv_[i] = ACE_OS::strdup (ACE_TEXT_ALWAYS_CHAR (argv[i])); +} +#endif // ACE_USES_WCHAR + + +ACE_Argv_Type_Converter::ACE_Argv_Type_Converter (int &argc, char **argv) + : saved_argc_(argc), + char_argv_(argv) +#if defined (ACE_USES_WCHAR) + , wchar_argv_(0), + before_pass_argc_(argc), + original_type_(false), + wchar_passed_(false), + char_passed_(false) +{ + this->initialize(); + + for (int i = 0; i < argc; ++i) + this->wchar_argv_[i] = ACE_OS::strdup (ACE_TEXT_ANTI_TO_TCHAR (argv[i])); +} +#else +{ +} +#endif // ACE_USES_WCHAR + +ACE_Argv_Type_Converter::~ACE_Argv_Type_Converter (void) +{ +#if defined (ACE_USES_WCHAR) + // selectively delete the 'copy' of argv + if (this->original_type_) + { + // if original type is wchar_t + if (this->char_passed_) + this->align_wchar_with_char (); + + for (int i = 0; i < this->before_pass_argc_; ++i) + ACE_OS::free (this->char_argv_[i]); + + delete [] this->char_argv_; + } + else + { + // if original type is char + if (this->wchar_passed_) + this->align_char_with_wchar (); + + for (int i = 0; i < this->before_pass_argc_; ++i) + ACE_OS::free (this->wchar_argv_[i]); + + delete [] this->wchar_argv_; + } +#endif // ACE_USES_WCHAR +} + +#if defined (ACE_USES_WCHAR) +void +ACE_Argv_Type_Converter::initialize (void) +{ + if (this->original_type_) + { + // Make a copy of argv in 'char'. type Create one more argv entry + // than original argc for the NULL. + ACE_NEW (char_argv_, + char *[this->saved_argc_ + 1]); + this->char_argv_[saved_argc_] = 0; // last entry of argv is + // always a NULL + } + else + { + // make a copy of argv in 'wchar_t' type + ACE_NEW (this->wchar_argv_, + wchar_t*[this->saved_argc_ + 1]); + this->wchar_argv_[saved_argc_] = 0; + } +} + + +void +ACE_Argv_Type_Converter::align_char_with_wchar (void) +{ + int wchar_argv_index = 0; + wchar_t* match_argv = this->wchar_argv_[0]; // pick the initial entry + + while (wchar_argv_index < this->saved_argc_) + { + // if n'th entries of both argv lists are different + if (ACE_OS::strcmp (this->char_argv_[wchar_argv_index], + ACE_TEXT_ALWAYS_CHAR (match_argv)) != 0) + { + // loop through the wchar argv list entries that are after + // wchar_argv_index + for (int i = wchar_argv_index + 1; i < before_pass_argc_; ++i) + { + if (ACE_OS::strcmp (this->char_argv_[i], + ACE_TEXT_ALWAYS_CHAR (match_argv)) == 0) + { + // swap the pointers in the char argv list + char *temp = this->char_argv_[wchar_argv_index]; + this->char_argv_[wchar_argv_index] = this->char_argv_[i]; + this->char_argv_[i] = temp; + break; + } + } + } + + // move to the next wchar argv list entry + match_argv = this->wchar_argv_[++wchar_argv_index]; + } + + this->cleanup (); +} + +void +ACE_Argv_Type_Converter::align_wchar_with_char (void) +{ + int char_argv_index = 0; + char* match_argv = this->char_argv_[0]; // pick the initial entry + + while (char_argv_index < saved_argc_) + { + // if n'th entries of both argv lists are different + if (ACE_OS::strcmp ( + ACE_TEXT_ALWAYS_CHAR (this->wchar_argv_[char_argv_index]), + match_argv) != 0) + { + // loop through the wchar argv list entries that are after + // wchar_argv_index + for (int i = char_argv_index + 1; i < this->before_pass_argc_; ++i) + { + if (ACE_OS::strcmp ( + ACE_TEXT_ALWAYS_CHAR(this->wchar_argv_[i]), + match_argv) == 0) { + // swap the pointers in the char argv list + wchar_t* temp = this->wchar_argv_[char_argv_index]; + this->wchar_argv_[char_argv_index] = this->wchar_argv_[i]; + this->wchar_argv_[i] = temp; + break; + } + } + } + + // move to the next wchar argv list entry + match_argv = this->char_argv_[++char_argv_index]; + } + + this->cleanup(); +} + +void +ACE_Argv_Type_Converter::cleanup (void) +{ + for (int i = this->saved_argc_; i < this->before_pass_argc_; ++i) + { + // Check whether it's ours to delete. + if (original_type_) + { + ACE_OS::free (this->char_argv_[i]); + this->char_argv_[i] = 0; + } + else + { + ACE_OS::free (this->wchar_argv_[i]); + this->wchar_argv_[i] = 0; + } + } + + this->before_pass_argc_ = this->saved_argc_; + + this->wchar_passed_ = false; + this->char_passed_ = false; +} +#endif // ACE_USES_WCHAR + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Argv_Type_Converter.h b/dep/ACE_wrappers/ace/Argv_Type_Converter.h new file mode 100644 index 000000000..ee2c541ed --- /dev/null +++ b/dep/ACE_wrappers/ace/Argv_Type_Converter.h @@ -0,0 +1,119 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Argv_Type_Converter.h + * + * $Id: Argv_Type_Converter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Si Mong Park + */ +//============================================================================= + +#ifndef ACE_ARGV_TYPE_CONVERTER_H +#define ACE_ARGV_TYPE_CONVERTER_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" +#include "ace/OS_Memory.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Argv_Type_Converter + * + * @brief To convert 'char' input/command line parameter to 'wchar_t'. + * + * This class is to convert 'char' type command line paramter to + * wide-character (wchar_t) format and stores the copy of it. + * This is useful for all classes that use 'char**' argv but cannot + * be converted into 'ACE_TCHAR**' version. + * Note that the converted data will be lost upon destruction, so + * classes should use this class as their data member. + */ +class ACE_Export ACE_Argv_Type_Converter +{ +public: + + ACE_Argv_Type_Converter (int &argc, char** argv); + +#if defined (ACE_USES_WCHAR) + ACE_Argv_Type_Converter (int &argc, wchar_t** argv); +#endif // ACE_USES_WCHAR + + ~ACE_Argv_Type_Converter (void); + + /// Returns the pointer of converted command line. + ACE_TCHAR** get_TCHAR_argv (void); + + /// Returns the pointer of ASCII (char) command line. + char** get_ASCII_argv (void); + + /// Returns the number of sub paramters (argc). + int& get_argc (void); + +private: + + /// Copy Constructor should not be used. + ACE_Argv_Type_Converter (const ACE_Argv_Type_Converter&); + + /// Assignment '=' operator should not be used. + ACE_Argv_Type_Converter operator= (const ACE_Argv_Type_Converter&); + +#if defined (ACE_USES_WCHAR) + + /// Perform common initialization for two Ctor's. + void initialize (void); + + /// Align all entries in the char type argv list with wchar_t type + /// argv list. + void align_char_with_wchar (void); + + /// Align all entries in the wchar_t type argv list with char type + /// argv list. + void align_wchar_with_char (void); + + /// Clean up removed (comsumed) argv entries and reset the pass flags. + void cleanup (void); +#endif // ACE_USES_WCHAR + +private: + /// Original number of input paramter, same as 'argc'. + int &saved_argc_; + + /// Data member pointer that contains converted argv in ACE_ANTI_TCHAR. + char** char_argv_; + +#if defined (ACE_USES_WCHAR) + /// Data member pointer that contains converted argv in ACE_TCHAR. + wchar_t** wchar_argv_; + + /// argc value before any argv has been passed. + int before_pass_argc_; + + /// false represents original argv passed in is char, and true + /// represents wchar_t. + bool const original_type_; + + /// true indicates wchar_t type argv has been passed. + bool wchar_passed_; + + /// true indicates char type argv has been passed. + bool char_passed_; +#endif /* ACE_USES_WCHAR */ +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Argv_Type_Converter.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ARGV_TYPE_CONVERTER_H */ diff --git a/dep/ACE_wrappers/ace/Argv_Type_Converter.inl b/dep/ACE_wrappers/ace/Argv_Type_Converter.inl new file mode 100644 index 000000000..e4b0ed5a0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Argv_Type_Converter.inl @@ -0,0 +1,44 @@ +// -*- C++ -*- +// +// $Id: Argv_Type_Converter.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ACE_TCHAR** +ACE_Argv_Type_Converter::get_TCHAR_argv (void) +{ +#if defined (ACE_USES_WCHAR) + if (this->char_passed_) + { + this->align_wchar_with_char (); + } + + this->wchar_passed_ = true; + return this->wchar_argv_; +#else + return this->char_argv_; +#endif // ACE_USES_WCHAR +} + +ACE_INLINE char** +ACE_Argv_Type_Converter::get_ASCII_argv (void) +{ +#if defined (ACE_USES_WCHAR) + if (this->wchar_passed_) + { + this->align_char_with_wchar (); + } + + this->char_passed_ = true; +#endif // ACE_USES_WCHAR + + return this->char_argv_; +} + +ACE_INLINE int& +ACE_Argv_Type_Converter::get_argc (void) +{ + return this->saved_argc_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Array.h b/dep/ACE_wrappers/ace/Array.h new file mode 100644 index 000000000..3caaa7b71 --- /dev/null +++ b/dep/ACE_wrappers/ace/Array.h @@ -0,0 +1,29 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Array.h + * + * $Id: Array.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @deprecated + * + * @note This file has been deprecated and will soon go away. You + * should directly include "Containers_T.h" instead. + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ARRAY_H +#define ACE_ARRAY_H +#include /**/ "ace/pre.h" + +#include "ace/Containers_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/post.h" +#endif /* ACE_ARRAY_H */ diff --git a/dep/ACE_wrappers/ace/Array_Base.cpp b/dep/ACE_wrappers/ace/Array_Base.cpp new file mode 100644 index 000000000..49e42e1ad --- /dev/null +++ b/dep/ACE_wrappers/ace/Array_Base.cpp @@ -0,0 +1,235 @@ +// $Id: Array_Base.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_ARRAY_BASE_CPP +#define ACE_ARRAY_BASE_CPP + +#include "ace/Array_Base.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Array_Base.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Malloc_Base.h" +#include "ace/os_include/os_errno.h" + +#include + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Dynamically initialize an array. +template +ACE_Array_Base::ACE_Array_Base (typename ACE_Array_Base::size_type size, + ACE_Allocator *alloc) + : max_size_ (size), + cur_size_ (size), + allocator_ (alloc) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + if (size != 0) + { + ACE_ALLOCATOR (this->array_, + (T *) this->allocator_->malloc (size * sizeof (T))); + for (size_type i = 0; i < size; ++i) + new (&array_[i]) T; + } + else + this->array_ = 0; +} + +template +ACE_Array_Base::ACE_Array_Base (typename ACE_Array_Base::size_type size, + const T &default_value, + ACE_Allocator *alloc) + : max_size_ (size), + cur_size_ (size), + allocator_ (alloc) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + if (size != 0) + { + ACE_ALLOCATOR (this->array_, + (T *) this->allocator_->malloc (size * sizeof (T))); + for (size_type i = 0; i < size; ++i) + new (&array_[i]) T (default_value); + } + else + this->array_ = 0; +} + +// The copy constructor (performs initialization). + +template +ACE_Array_Base::ACE_Array_Base (const ACE_Array_Base &s) + : max_size_ (s.size ()), + cur_size_ (s.size ()), + allocator_ (s.allocator_) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_ALLOCATOR (this->array_, + (T *) this->allocator_->malloc (s.size () * sizeof (T))); + for (size_type i = 0; i < this->size (); ++i) + new (&this->array_[i]) T (s.array_[i]); +} + +// Assignment operator (performs assignment). + +template void +ACE_Array_Base::operator= (const ACE_Array_Base &s) +{ + // Check for "self-assignment". + + if (this != &s) + { + if (this->max_size_ < s.size ()) + { + // Need to reallocate memory. + + // Strongly exception-safe assignment. + // + // Note that we're swapping the allocators here, too. + // Should we? Probably. "*this" should be a duplicate of + // the "right hand side". + ACE_Array_Base tmp (s); + this->swap (tmp); + } + else + { + // Underlying array is large enough. No need to reallocate + // memory. + // + // "*this" still owns the memory for the underlying array. + // Do not swap out the allocator. + // + // @@ Why don't we just drop the explicit destructor and + // placement operator new() calls with a straight + // element-by-element assignment? Is the existing + // approach more efficient? + // -Ossama + + ACE_DES_ARRAY_NOFREE (this->array_, + s.size (), + T); + + this->cur_size_ = s.size (); + + for (size_type i = 0; i < this->size (); ++i) + new (&this->array_[i]) T (s.array_[i]); + } + } +} + +// Set an item in the array at location slot. + +template int +ACE_Array_Base::set (const T &new_item, + typename ACE_Array_Base::size_type slot) +{ + if (this->in_range (slot)) + { + this->array_[slot] = new_item; + return 0; + } + else + return -1; +} + +// Get an item in the array at location slot. + +template int +ACE_Array_Base::get (T &item, + typename ACE_Array_Base::size_type slot) const +{ + if (this->in_range (slot)) + { + // Copies the item. If you don't want to copy, use operator [] + // instead (but then you'll be responsible for range checking). + item = this->array_[slot]; + return 0; + } + else + return -1; +} + +template int +ACE_Array_Base::max_size (typename ACE_Array_Base::size_type new_size) +{ + if (new_size > this->max_size_) + { + T *tmp = 0; + + ACE_ALLOCATOR_RETURN (tmp, + (T *) this->allocator_->malloc (new_size * sizeof (T)), + -1); + for (size_type i = 0; i < this->cur_size_; ++i) + new (&tmp[i]) T (this->array_[i]); + + // Initialize the new portion of the array that exceeds the + // previously allocated section. + for (size_type j = this->cur_size_; j < new_size; ++j) + new (&tmp[j]) T; + + ACE_DES_ARRAY_FREE (this->array_, + this->max_size_, + this->allocator_->free, + T); + this->array_ = tmp; + this->max_size_ = new_size; + this->cur_size_ = new_size; + } + + return 0; +} + +template int +ACE_Array_Base::size (typename ACE_Array_Base::size_type new_size) +{ + int const r = this->max_size (new_size); + + if (r == 0) + this->cur_size_ = new_size; + + return r; +} + +template +void +ACE_Array_Base::swap (ACE_Array_Base & rhs) +{ + std::swap (this->max_size_ , rhs.max_size_); + std::swap (this->cur_size_ , rhs.cur_size_); + std::swap (this->array_ , rhs.array_); + std::swap (this->allocator_, rhs.allocator_); +} + +// **************************************************************** + +template int +ACE_Array_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Array_Iterator::next"); + + if (this->done ()) + { + item = 0; + return 0; + } + else + { + item = &array_[current_]; + return 1; + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ARRAY_BASE_CPP */ diff --git a/dep/ACE_wrappers/ace/Array_Base.h b/dep/ACE_wrappers/ace/Array_Base.h new file mode 100644 index 000000000..44e281255 --- /dev/null +++ b/dep/ACE_wrappers/ace/Array_Base.h @@ -0,0 +1,256 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Array_Base.h + * + * $Id: Array_Base.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ARRAY_BASE_H +#define ACE_ARRAY_BASE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/Malloc_Base.h" +#include /* For reverse_iterator adapters */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration. +template class ACE_Array_Iterator; + +/** + * @class ACE_Array_Base + * + * @brief Implement a simple dynamic array + * + * This parametric class implements a simple dynamic array; + * resizing must be controlled by the user. No comparison or find + * operations are implemented. + */ +template +class ACE_Array_Base +{ +public: + + // Old/ACE-style traits. + typedef T TYPE; + typedef ACE_Array_Iterator ITERATOR; + + // STL-style typedefs/traits. + typedef T value_type; + typedef value_type * iterator; + typedef value_type const * const_iterator; + typedef value_type & reference; + typedef value_type const & const_reference; + typedef value_type * pointer; + typedef value_type const * const_pointer; + typedef ptrdiff_t difference_type; + typedef ACE_Allocator::size_type size_type; + + ACE_DECLARE_STL_REVERSE_ITERATORS + + // = Initialization and termination methods. + + /// Dynamically create an uninitialized array. + ACE_Array_Base (size_type size = 0, + ACE_Allocator * the_allocator = 0); + + /// Dynamically initialize the entire array to the . + ACE_Array_Base (size_type size, + T const & default_value, + ACE_Allocator * the_allocator = 0); + + /** + * The copy constructor performs initialization by making an exact + * copy of the contents of parameter , i.e., *this == s will + * return true. + */ + ACE_Array_Base (ACE_Array_Base const & s); + + /** + * Assignment operator performs an assignment by making an exact + * copy of the contents of parameter , i.e., *this == s will + * return true. Note that if the of is >= than + * we can copy it without reallocating. However, if + * is < we must delete the , + * reallocate a new , and then copy the contents of . + */ + void operator= (ACE_Array_Base const & s); + + /// Clean up the array (e.g., delete dynamically allocated memory). + ~ACE_Array_Base (void); + + // = Set/get methods. + + /// Set item in the array at location @a slot. Doesn't + /// perform range checking. + T & operator[] (size_type slot); + + /// Get item in the array at location @a slot. Doesn't + /// perform range checking. + T const & operator[] (size_type slot) const; + + /// Set an item in the array at location @a slot. Returns + /// -1 if @a slot is not in range, else returns 0. + int set (T const & new_item, size_type slot); + + /** + * Get an item in the array at location @a slot. Returns -1 if + * @a slot is not in range, else returns 0. Note that this function + * copies the item. If you want to avoid the copy, you can use + * the const operator [], but then you'll be responsible for range checking. + */ + int get (T & item, size_type slot) const; + + /// Returns the of the array. + size_type size (void) const; + + /** + * Changes the size of the array to match . + * It copies the old contents into the new array. + * Return -1 on failure. + */ + int size (size_type new_size); + + /// Returns the of the array. + size_type max_size (void) const; + + /** + * Changes the size of the array to match . + * It copies the old contents into the new array. + * Return -1 on failure. + * It does not affect new_size + */ + int max_size (size_type new_size); + + /** + * @name Forward Iterator Accessors + * + * Forward iterator accessors. + */ + //@{ + iterator begin (void); + iterator end (void); + const_iterator begin (void) const; + const_iterator end (void) const; + //@} + + /** + * @name Reverse Iterator Accessors + * + * Reverse iterator accessors. + */ + //@{ + reverse_iterator rbegin (void); + reverse_iterator rend (void); + const_reverse_iterator rbegin (void) const; + const_reverse_iterator rend (void) const; + //@} + + /// Swap the contents of this array with the given @a array in + /// an exception-safe manner. + void swap (ACE_Array_Base & array); + +protected: + + /// Returns 1 if @a slot is within range, i.e., 0 >= @a slot < + /// , else returns 0. + bool in_range (size_type slot) const; + + /// Maximum size of the array, i.e., the total number of elements + /// in . + size_type max_size_; + + /** + * Current size of the array. This starts out being == to + * . However, if we are assigned a smaller array, then + * will become less than . The purpose of + * keeping track of both sizes is to avoid reallocating memory if we + * don't have to. + */ + size_type cur_size_; + + /// Pointer to the array's storage buffer. + value_type * array_; + + /// Allocation strategy of the ACE_Array_Base. + ACE_Allocator * allocator_; + + friend class ACE_Array_Iterator; +}; + +// **************************************************************** + +/** + * @class ACE_Array_Iterator + * + * @brief Implement an iterator over an ACE_Array. + * + * This iterator is safe in the face of array element deletions. + * But it is NOT safe if the array is resized (via the ACE_Array + * assignment operator) during iteration. That would be very + * odd, and dangerous. + */ +template +class ACE_Array_Iterator +{ +public: + // = Initialization method. + ACE_Array_Iterator (ACE_Array_Base &); + + // = Iteration methods. + + /// Pass back the that hasn't been seen in the Array. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the Array. Returns 0 when all the + /// items in the Array have been seen, else 1. + int advance (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the current item in the iteration. + size_t current_; + + /// Pointer to the Array we're iterating over. + ACE_Array_Base &array_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Array_Base.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Array_Base.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Array_Base.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ARRAY_BASE_H */ diff --git a/dep/ACE_wrappers/ace/Array_Base.inl b/dep/ACE_wrappers/ace/Array_Base.inl new file mode 100644 index 000000000..046c1bffc --- /dev/null +++ b/dep/ACE_wrappers/ace/Array_Base.inl @@ -0,0 +1,146 @@ +// -*- C++ -*- +// +// $Id: Array_Base.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Clean up the array (e.g., delete dynamically allocated memory). +template ACE_INLINE +ACE_Array_Base::~ACE_Array_Base (void) +{ + ACE_DES_ARRAY_FREE (this->array_, + this->max_size_, + this->allocator_->free, + T); +} + +template +ACE_INLINE typename ACE_Array_Base::iterator +ACE_Array_Base::begin (void) +{ + return this->array_; +} + +template +ACE_INLINE typename ACE_Array_Base::iterator +ACE_Array_Base::end (void) +{ + return this->array_ + this->cur_size_; +} + +template +ACE_INLINE typename ACE_Array_Base::const_iterator +ACE_Array_Base::begin (void) const +{ + return this->array_; +} + +template +ACE_INLINE typename ACE_Array_Base::const_iterator +ACE_Array_Base::end (void) const +{ + return this->array_ + this->cur_size_; +} + +template +ACE_INLINE typename ACE_Array_Base::reverse_iterator +ACE_Array_Base::rbegin (void) +{ + return reverse_iterator (this->end ()); +} + +template +ACE_INLINE typename ACE_Array_Base::reverse_iterator +ACE_Array_Base::rend (void) +{ + return reverse_iterator (this->begin ()); +} + +template +ACE_INLINE typename ACE_Array_Base::const_reverse_iterator +ACE_Array_Base::rbegin (void) const +{ + return const_reverse_iterator (this->end ()); +} + +template +ACE_INLINE typename ACE_Array_Base::const_reverse_iterator +ACE_Array_Base::rend (void) const +{ + return const_reverse_iterator (this->begin ()); +} + +template ACE_INLINE typename ACE_Array_Base::size_type +ACE_Array_Base::size (void) const +{ + return this->cur_size_; +} + +template ACE_INLINE typename ACE_Array_Base::size_type +ACE_Array_Base::max_size (void) const +{ + return this->max_size_; +} + +template ACE_INLINE bool +ACE_Array_Base::in_range (typename ACE_Array_Base::size_type index) const +{ + return index < this->cur_size_; +} + +template ACE_INLINE T & +ACE_Array_Base::operator[] (typename ACE_Array_Base::size_type index) +{ + return this->array_[index]; +} + +template ACE_INLINE const T & +ACE_Array_Base::operator[] (typename ACE_Array_Base::size_type index) const +{ + return this->array_[index]; +} + +// **************************************************************** + +template ACE_INLINE void +ACE_Array_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Array_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_INLINE +ACE_Array_Iterator::ACE_Array_Iterator (ACE_Array_Base &a) + : current_ (0), + array_ (a) +{ + // ACE_TRACE ("ACE_Array_Iterator::ACE_Array_Iterator"); +} + +template ACE_INLINE int +ACE_Array_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Array_Iterator::advance"); + + if (this->current_ < array_.size ()) + { + ++this->current_; + return 1; + } + else + { + // Already finished iterating. + return 0; + } +} + +template ACE_INLINE int +ACE_Array_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Array_Iterator::done"); + + return this->current_ >= array_.size (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Array_Map.cpp b/dep/ACE_wrappers/ace/Array_Map.cpp new file mode 100644 index 000000000..5530a8b54 --- /dev/null +++ b/dep/ACE_wrappers/ace/Array_Map.cpp @@ -0,0 +1,299 @@ +// $Id: Array_Map.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_ARRAY_MAP_CPP +#define ACE_ARRAY_MAP_CPP + +#include "ace/Array_Map.h" + +#ifndef __ACE_INLINE__ +# include "ace/Array_Map.inl" +#endif /* !__ACE_INLINE__ */ + +#include "ace/checked_iterator.h" + +#include + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#ifndef ACE_LACKS_MEMBER_TEMPLATES +template +template +ACE_Array_Map::ACE_Array_Map (InputIterator f, + InputIterator l) + : size_ (l - f) + , capacity_ (size_) + , nodes_ (size_ == 0 ? 0 : new value_type[size_]) +{ + (void) std::copy (f, + l, + ACE_make_checked_array_iterator (this->begin (), + this->size_)); + +// iterator n = this->begin (); + +// for (InputIterator i = f; i != l; ++i, ++n) +// *n = *i; +} +#else +template +ACE_Array_Map::ACE_Array_Map ( + typename ACE_Array_Map::const_iterator f, + typename ACE_Array_Map::const_iterator l) + : size_ (l - f) + , capacity_ (size_) + , nodes_ (size_ == 0 ? 0 : new value_type[size_]) +{ + (void) std::copy (f, + l, + ACE_make_checked_array_iterator (this->begin (), + this->size_)); + +// iterator n = this->begin (); + +// for (const_iterator i = f; i != l; ++i, ++n) +// *n = *i; +} +#endif /* !ACE_LACKS_MEMBER_TEMPLATES */ + +template +ACE_Array_Map::ACE_Array_Map ( + ACE_Array_Map const & map) + : size_ (map.size_) + , capacity_ (map.size_) + , nodes_ (size_ == 0 ? 0 : new value_type[size_]) +{ + std::copy (map.begin (), + map.end (), + ACE_make_checked_array_iterator (this->begin (), + this->size_)); + +// iterator f = map.begin (); +// iterator l = map.end (); +// iterator n = this->begin (); + +// for (iterator i = f; i != l; ++i, ++n) +// *n = *i; +} + +template +ACE_Array_Map::~ACE_Array_Map (void) +{ + delete[] this->nodes_; +} + +template +void +ACE_Array_Map::swap ( + ACE_Array_Map & map) +{ + std::swap (this->size_, map.size_); + std::swap (this->capacity_, map.capacity_); + std::swap (this->nodes_, map.nodes_); +} + +template +std::pair::iterator, bool> +ACE_Array_Map::insert ( + typename ACE_Array_Map::value_type const & x) +{ + // Linear insertion due to linear duplicate key search. + + bool inserted = false; + iterator i = this->find (x.first); + + if (i == this->end ()) + { + // Add the element to the array. + + size_type const old_size = this->size (); + this->grow (1); // Increase size by at least one. + + i = this->begin () + old_size; + *i = x; + + ++this->size_; + + inserted = true; + } + + return std::make_pair (i, inserted); +} + +#ifndef ACE_LACKS_MEMBER_TEMPLATES +template +template +void +ACE_Array_Map::insert (InputIterator f, InputIterator l) +{ + this->grow (l - f); // Preallocate storage. + + for (InputIterator i = f; i != l; ++i) + { + (void) this->insert (*i); + } +} +#else +template +void +ACE_Array_Map::insert ( + typename ACE_Array_Map::const_iterator f, + typename ACE_Array_Map::const_iterator l) +{ + this->grow (l - f); // Preallocate storage. + + for (const_iterator i = f; i != l; ++i) + { + (void) this->insert (*i); + } +} +#endif /* ACE_LACKS_MEMBER_TEMPLATES */ + +template +void +ACE_Array_Map::erase ( + typename ACE_Array_Map::iterator pos) +{ + iterator const first = this->begin (); + iterator const last = this->end (); + + if (pos >= first && pos < last) + { + if (pos != last - 1) + { + // Relocate the tail element to the location of the erased + // element to prevent introduction of "holes" in the + // underlying array. + *pos = *(last - 1); + } + + // Explicitly destroy the tail element by assigning a default + // constructed instance to it. Note that this also works for + // the case of a map of size 1. + *(last - 1) = value_type (); + + --this->size_; + } +} + +template +typename ACE_Array_Map::size_type +ACE_Array_Map::erase ( + typename ACE_Array_Map::key_type const & k) +{ + iterator pos = this->find (k); + + size_type const old_size = this->size_; + + this->erase (pos); + + return old_size - this->size_; +} + +template +void +ACE_Array_Map::erase ( + typename ACE_Array_Map::iterator first, + typename ACE_Array_Map::iterator last) +{ + if (this->begin () <= first && first < last && last < this->end ()) + for (iterator i = first; i != last; ++i) + this->erase (i); +} + +template +void +ACE_Array_Map::clear (void) +{ + this->size_ = 0; // No need to deallocate array nor destroy elements. +} + +template +typename ACE_Array_Map::iterator +ACE_Array_Map::find ( + typename ACE_Array_Map::key_type const & k) +{ + iterator const the_end = this->end (); + + EqualTo eq; + + for (iterator i = this->begin (); i != the_end; ++i) + if (eq (k, i->first)) + return i; + + return this->end (); +} + +template +typename ACE_Array_Map::const_iterator +ACE_Array_Map::find ( + typename ACE_Array_Map::key_type const & k) const +{ + const_iterator const the_end = this->end (); + + EqualTo eq; + + for (const_iterator i = this->begin (); i != the_end; ++i) + if (eq (k, i->first)) + return i; + + return this->end (); +} + +template +void +ACE_Array_Map::grow ( + typename ACE_Array_Map::size_type s) +{ + if (this->size () + s > this->capacity_) + { + // This implementation focuses more on static footprint than + // speed. + + // Strongly exception safe. + + ACE_Array_Map temp (this->size () + s); + + std::copy (this->begin (), + this->end (), + ACE_make_checked_array_iterator (temp.begin (), + temp.capacity_)); + + size_type const n = this->size (); // Do not swap out the size + // since we bypassed the + // temporary map's element + // counting code. + this->swap (temp); + + this->size_ = n; + } +} + +// --------------------------------------------------------------- + +template +bool +operator== (ACE_Array_Map const & lhs, + ACE_Array_Map const & rhs) +{ + // Do not include Array_Map capacity in comparison. It isn't useful + // in this case. + + return (lhs.size () == rhs.size () + && std::equal (lhs.begin (), + lhs.end (), + ACE_make_checked_array_iterator (rhs.begin (), + rhs.size ()))); +} + +template +bool +operator< (ACE_Array_Map const & lhs, + ACE_Array_Map const & rhs) +{ + return std::lexicographical_compare (lhs.begin (), lhs.end (), + rhs.begin (), rhs.end ()); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ARRAY_MAP_CPP */ diff --git a/dep/ACE_wrappers/ace/Array_Map.h b/dep/ACE_wrappers/ace/Array_Map.h new file mode 100644 index 000000000..67aa8d94b --- /dev/null +++ b/dep/ACE_wrappers/ace/Array_Map.h @@ -0,0 +1,300 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Array_Map.h + * + * $Id: Array_Map.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Light weight array-based map with fast iteration but linear + * (i.e. O(n)) search times. STL-style interface is exposed. + * + * @note This class requires the STL generic algorithms and + * reverse_iterator adapter. + * + * @author Ossama Othman + */ +//============================================================================= + + +#ifndef ACE_ARRAY_MAP_H +#define ACE_ARRAY_MAP_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include +#include +#include + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Array_Map + * + * @brief Light weight array-based map with fast iteration, but linear + * (i.e. O(n)) search times. + * + * Map implementation that focuses on small footprint and fast + * iteration. Search times are, however, linear (O(n)) meaning that + * this map isn't suitable for large data sets that will be searched + * in performance critical areas of code. Iteration over large data + * sets, however, is faster than linked list-based maps, for example, + * since spatial locality is maximized through the use of contiguous + * arrays as the underlying storage. + * @par + * An @c ACE_Array_Map is a unique associative container, meaning that + * duplicate values may not be added to the map. It is also pair + * associative (value_type is a std::pair<>). It is not a sorted + * container. + * @par + * An STL @c std::map -like interface is exposed by this class + * portability. Furthermore, this map's iterators are compatible with + * STL algorithms. + * @par + * Requirements and Performance Characteristics + * - Internal Structure + * Array + * - Duplicates allowed? + * No + * - Random access allowed? + * Yes + * - Search speed + * O(n) + * - Insert/replace speed + * O(n), can be longer if the map has to resize + * - Iterator still valid after change to container? + * No + * - Frees memory for removed elements? + * Yes + * - Items inserted by + * Value + * - Requirements for key type + * -# Default constructor + * -# Copy constructor + * -# operator= + * -# operator== + * - Requirements for object type + * -# Default constructor + * -# Copy constructor + * -# operator= + */ +template > +class ACE_Array_Map +{ +public: + + // STL-style typedefs/traits. + typedef Key key_type; + typedef Value data_type; + typedef std::pair value_type; + typedef value_type * iterator; + typedef value_type const * const_iterator; + typedef value_type & reference; + typedef value_type const & const_reference; + typedef value_type * pointer; + typedef value_type const * const_pointer; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + + ACE_DECLARE_STL_REVERSE_ITERATORS + + /// Default Constructor. + /** + * Create an empty map with a preallocated buffer of size @a s. + */ + ACE_Array_Map (size_type s = 0); + +#ifndef ACE_LACKS_MEMBER_TEMPLATES + template + ACE_Array_Map (InputIterator f, InputIterator l); +#else + ACE_Array_Map (const_iterator f, const_iterator l); +#endif /* !ACE_LACKS_MEMBER_TEMPLATES */ + + ACE_Array_Map (ACE_Array_Map const & map); + ACE_Array_Map & operator= (ACE_Array_Map const & map); + + /// Destructor. + ~ACE_Array_Map (void); + + /** + * @name Forward Iterator Accessors + * + * Forward iterator accessors. + */ + //@{ + iterator begin (void); + iterator end (void); + const_iterator begin (void) const; + const_iterator end (void) const; + //@} + + /** + * @name Reverse Iterator Accessors + * + * Reverse iterator accessors. + */ + //@{ + reverse_iterator rbegin (void); + reverse_iterator rend (void); + const_reverse_iterator rbegin (void) const; + const_reverse_iterator rend (void) const; + //@} + + /// Return current size of map. + /** + * @return The number of elements in the map. + */ + size_type size (void) const; + + /// Maximum number of elements the map can hold. + size_type max_size (void) const; + + /// Return @c true if the map is empty, else @c false. + bool is_empty (void) const; // ACE style + + /** + * Return @c true if the map is empty, else @c false. We recommend + * using @c is_empty() instead since it's more consistent with the + * ACE container naming conventions. + */ + bool empty (void) const; // STL style + + /// Swap the contents of this map with the given @a map in an + /// exception-safe manner. + void swap (ACE_Array_Map & map); + + /// Insert the value @a x into the map. + /** + * STL-style map insertion method. + * + * @param x @c std::pair containing key and datum. + * + * @return @c std::pair::second will be @c false if the map already + * contains a value with the same key as @a x. + */ + std::pair insert (value_type const & x); + +#ifndef ACE_LACKS_MEMBER_TEMPLATES + /// Insert range of elements into map. + template + void insert (InputIterator f, InputIterator l); +#else + /// Insert range of elements into map. + void insert (const_iterator f, const_iterator l); +#endif /* ACE_LACKS_MEMBER_TEMPLATES */ + + /// Remove element at position @a pos from the map. + void erase (iterator pos); + + /// Remove element corresponding to key @a k from the map. + /** + * @return Number of elements that were erased. + */ + size_type erase (key_type const & k); + + /// Remove range of elements [@a first, @a last) from the map. + /** + * @note [@a first, @a last) must be valid range within the map. + */ + void erase (iterator first, iterator last); + + /// Clear contents of map. + /** + * @note This a constant time (O(1)) operation. + */ + void clear (void); + + /** + * @name Search Operations + * + * Search the map for data corresponding to key @a k. + */ + //@{ + /** + * @return @c end() if data corresponding to key @a k is not in the + * map. + */ + iterator find (key_type const & k); + + /** + * @return @c end() if data corresponding to key @a k is not in the + * map. + */ + const_iterator find (key_type const & k) const; + //@} + + /// Count the number of elements corresponding to key @a k. + /** + * @return In the case of this map, the count will always be one if + * such exists in the map. + */ + size_type count (key_type const & k); + + /// Convenience array index operator. + /** + * Array index operator that allows insertion and retrieval of + * elements using an array index syntax, such as: + * @par + * map["Foo"] = 12; + */ + data_type & operator[] (key_type const & k); + +private: + + /// Increase size of underlying buffer by @a s. + void grow (size_type s); + +private: + + /// Number of elements in the map. + size_type size_; + + /// Current size of underlying array. + /** + * @note @c capacity_ is always greater than or equal to @c size_; + */ + size_type capacity_; + + /// Underlying array containing keys and data. + value_type * nodes_; + +}; + +// -------------------------------------------------------------- + +/// @c ACE_Array_Map equality operator. +template +bool operator== (ACE_Array_Map const & lhs, + ACE_Array_Map const & rhs); + +/// @c ACE_Array_Map lexicographical comparison operator. +template +bool operator< (ACE_Array_Map const & lhs, + ACE_Array_Map const & rhs); + +// -------------------------------------------------------------- + +ACE_END_VERSIONED_NAMESPACE_DECL + +#ifdef __ACE_INLINE__ +# include "ace/Array_Map.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +# include "ace/Array_Map.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Array_Map.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ARRAY_MAP_H */ diff --git a/dep/ACE_wrappers/ace/Array_Map.inl b/dep/ACE_wrappers/ace/Array_Map.inl new file mode 100644 index 000000000..b053dc0a4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Array_Map.inl @@ -0,0 +1,133 @@ +// -*- C++ -*- +// +// $Id: Array_Map.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_INLINE +ACE_Array_Map::ACE_Array_Map ( + typename ACE_Array_Map::size_type s) + : size_ (0) + , capacity_ (s) + , nodes_ (s == 0 ? 0 : new value_type[s]) +{ +} + +template +ACE_INLINE ACE_Array_Map & +ACE_Array_Map::operator= ( + ACE_Array_Map const & map) +{ + // Strongly exception-safe assignment. + + ACE_Array_Map temp (map); + this->swap (temp); + return *this; +} + +template +ACE_INLINE typename ACE_Array_Map::iterator +ACE_Array_Map::begin (void) +{ + return this->nodes_; +} + +template +ACE_INLINE typename ACE_Array_Map::iterator +ACE_Array_Map::end (void) +{ + return this->nodes_ + this->size_; +} + +template +ACE_INLINE typename ACE_Array_Map::const_iterator +ACE_Array_Map::begin (void) const +{ + return this->nodes_; +} + +template +ACE_INLINE typename ACE_Array_Map::const_iterator +ACE_Array_Map::end (void) const +{ + return this->nodes_ + this->size_; +} + +template +ACE_INLINE typename ACE_Array_Map::reverse_iterator +ACE_Array_Map::rbegin (void) +{ + return reverse_iterator (this->end ()); +} + +template +ACE_INLINE typename ACE_Array_Map::reverse_iterator +ACE_Array_Map::rend (void) +{ + return reverse_iterator (this->begin ()); +} + +template +ACE_INLINE typename ACE_Array_Map::const_reverse_iterator +ACE_Array_Map::rbegin (void) const +{ + return const_reverse_iterator (this->end ()); +} + +template +ACE_INLINE typename ACE_Array_Map::const_reverse_iterator +ACE_Array_Map::rend (void) const +{ + return const_reverse_iterator (this->begin ()); +} + +template +ACE_INLINE typename ACE_Array_Map::size_type +ACE_Array_Map::size (void) const +{ + return this->size_; +} + +template +ACE_INLINE typename ACE_Array_Map::size_type +ACE_Array_Map::max_size (void) const +{ + return size_type (-1) / sizeof (value_type); +} + +template +ACE_INLINE bool +ACE_Array_Map::is_empty (void) const +{ + return this->size_ == 0; +} + +// The following method is deprecated. + +template +ACE_INLINE bool +ACE_Array_Map::empty (void) const +{ + return this->is_empty (); +} + +template +ACE_INLINE typename ACE_Array_Map::size_type +ACE_Array_Map::count ( + typename ACE_Array_Map::key_type const & k) +{ + return + (this->find (k) == this->end () ? 0 : 1); // Only one datum per key. +} + +template +ACE_INLINE typename ACE_Array_Map::data_type & +ACE_Array_Map::operator[] ( + typename ACE_Array_Map::key_type const & k) +{ + iterator i = (this->insert (value_type (k, data_type ()))).first; + return (*i).second; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Assert.cpp b/dep/ACE_wrappers/ace/Assert.cpp new file mode 100644 index 000000000..4a71c9e5a --- /dev/null +++ b/dep/ACE_wrappers/ace/Assert.cpp @@ -0,0 +1,24 @@ +// $Id: Assert.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Assert.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, Assert, "$Id: Assert.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The following ASSERT macro is courtesy of Alexandre Karev +// . +void +__ace_assert(const char *file, int line, const ACE_TCHAR *expression) +{ + int error = ACE_Log_Msg::last_error_adapter (); + ACE_Log_Msg *log = ACE_Log_Msg::instance (); + + log->set (file, line, -1, error, log->restart (), + log->msg_ostream (), log->msg_callback ()); + + log->log (LM_ERROR, ACE_TEXT ("ACE_ASSERT: file %N, line %l assertion failed for '%s'.%a\n"), expression, -1); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Assert.h b/dep/ACE_wrappers/ace/Assert.h new file mode 100644 index 000000000..cf28a4a89 --- /dev/null +++ b/dep/ACE_wrappers/ace/Assert.h @@ -0,0 +1,38 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Assert.h + * + * $Id: Assert.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ASSERT_H +#define ACE_ASSERT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#include /**/ "ace/config-all.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +ACE_Export void __ace_assert(const char *file, int line, const ACE_TCHAR *expression); +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_NDEBUG) +#define ACE_ASSERT(x) \ + (static_cast(0)) +#else +#define ACE_ASSERT(X) \ + ((X) \ + ? static_cast(0) \ + : ACE_VERSIONED_NAMESPACE_NAME::__ace_assert(__FILE__, __LINE__, ACE_TEXT_CHAR_TO_TCHAR (#X))) +#endif /* ACE_NDEBUG */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ASSERT */ diff --git a/dep/ACE_wrappers/ace/Asynch_Acceptor.cpp b/dep/ACE_wrappers/ace/Asynch_Acceptor.cpp new file mode 100644 index 000000000..12aeebe0d --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_Acceptor.cpp @@ -0,0 +1,514 @@ +/* -*- C++ -*- */ +// $Id: Asynch_Acceptor.cpp 82444 2008-07-28 13:33:07Z johnnyw $ + +#ifndef ACE_ASYNCH_ACCEPTOR_C +#define ACE_ASYNCH_ACCEPTOR_C + +#include "ace/Asynch_Acceptor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, Asynch_Acceptor, "$Id: Asynch_Acceptor.cpp 82444 2008-07-28 13:33:07Z johnnyw $") + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) +// This only works on platforms that support async i/o. + +#include "ace/OS_Errno.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/Log_Msg.h" +#include "ace/Message_Block.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" +#include "ace/Sock_Connect.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Asynch_Acceptor::ACE_Asynch_Acceptor (void) + : listen_handle_ (ACE_INVALID_HANDLE), + pass_addresses_ (false), + validate_new_connection_ (false), + reissue_accept_ (1), + bytes_to_read_ (0) +{ +} + +template +ACE_Asynch_Acceptor::~ACE_Asynch_Acceptor (void) +{ + // Close down the listen socket + if (this->listen_handle_ != ACE_INVALID_HANDLE) + { + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + } +} + +template int +ACE_Asynch_Acceptor::open (const ACE_INET_Addr &address, + size_t bytes_to_read, + bool pass_addresses, + int backlog, + int reuse_addr, + ACE_Proactor *proactor, + bool validate_new_connection, + int reissue_accept, + int number_of_initial_accepts) +{ + ACE_TRACE ("ACE_Asynch_Acceptor<>::open"); + + this->proactor (proactor); + this->pass_addresses_ = pass_addresses; + this->bytes_to_read_ = bytes_to_read; + this->validate_new_connection_ = validate_new_connection; + this->reissue_accept_ = reissue_accept; + this->addr_family_ = address.get_type (); + + // Create the listener socket + this->listen_handle_ = ACE_OS::socket (address.get_type (), SOCK_STREAM, 0); + if (this->listen_handle_ == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_OS::socket")), + -1); + // Initialize the ACE_Asynch_Accept + if (this->asynch_accept_.open (*this, + this->listen_handle_, + 0, + this->proactor ()) == -1) + { + ACE_Errno_Guard g (errno); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Accept::open"))); + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + return -1; + } + + if (reuse_addr) + { + // Reuse the address + int one = 1; + if (ACE_OS::setsockopt (this->listen_handle_, + SOL_SOCKET, + SO_REUSEADDR, + (const char*) &one, + sizeof one) == -1) + { + ACE_Errno_Guard g (errno); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_OS::setsockopt"))); + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + return -1; + } + } + + // If port is not specified, bind to any port. + static ACE_INET_Addr sa (ACE_sap_any_cast (const ACE_INET_Addr &)); + + if (address == sa && + ACE::bind_port (this->listen_handle_, + INADDR_ANY, + address.get_type()) == -1) + { + ACE_Errno_Guard g (errno); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::bind_port"))); + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + return -1; + } + + // Bind to the specified port. + if (ACE_OS::bind (this->listen_handle_, + reinterpret_cast (address.get_addr ()), + address.get_size ()) == -1) + { + ACE_Errno_Guard g (errno); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_OS::bind"))); + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + return -1; + } + + // Start listening. + if (ACE_OS::listen (this->listen_handle_, backlog) == -1) + { + ACE_Errno_Guard g (errno); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_OS::listen"))); + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + return -1; + } + + // For the number of . + if (number_of_initial_accepts == -1) + number_of_initial_accepts = backlog; + + for (int i = 0; i < number_of_initial_accepts; i++) + { + // Initiate accepts. + if (this->accept (bytes_to_read) == -1) + { + ACE_Errno_Guard g (errno); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Acceptor::accept"))); + ACE_OS::closesocket (this->listen_handle_); + this->listen_handle_ = ACE_INVALID_HANDLE; + return -1; + } + } + + return 0; +} + +template int +ACE_Asynch_Acceptor::set_handle (ACE_HANDLE listen_handle) +{ + ACE_TRACE ("ACE_Asynch_Acceptor<>::set_handle"); + + // Take ownership of the + this->listen_handle_ = listen_handle; + + // Reinitialize the ACE_Asynch_Accept + if (this->asynch_accept_.open (*this, + this->listen_handle_, + 0, + this->proactor ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Accept::open")), + -1); + return 0; +} + +template ACE_HANDLE +ACE_Asynch_Acceptor::get_handle (void) const +{ + return this->listen_handle_; +} + +template int +ACE_Asynch_Acceptor::accept (size_t bytes_to_read, const void *act) +{ + ACE_TRACE ("ACE_Asynch_Acceptor<>::accept"); + + ACE_Message_Block *message_block = 0; + // The space_needed calculation is drive by needs of Windows. POSIX doesn't + // need to extra 16 bytes, but it doesn't hurt. + size_t space_needed = sizeof (sockaddr_in) + 16; +#if defined (ACE_HAS_IPV6) + if (PF_INET6 == this->addr_family_) + space_needed = sizeof (sockaddr_in6) + 16; +#endif /* ACE_HAS_IPV6 */ + space_needed = (2 * space_needed) + bytes_to_read; + + // Create a new message block big enough for the addresses and data + ACE_NEW_RETURN (message_block, + ACE_Message_Block (space_needed), + -1); + + // Initiate asynchronous accepts + if (this->asynch_accept_.accept (*message_block, + bytes_to_read, + ACE_INVALID_HANDLE, + act, + 0, + ACE_SIGRTMIN, + this->addr_family_) == -1) + { + // Cleanup on error + message_block->release (); + return -1; + } + return 0; +} + +template void +ACE_Asynch_Acceptor::handle_accept (const ACE_Asynch_Accept::Result &result) +{ + ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept"); + + // Variable for error tracking + int error = 0; + + // If the asynchronous accept fails. + if (!result.success () || result.accept_handle () == ACE_INVALID_HANDLE) + { + error = 1; + } + +#if defined (ACE_WIN32) + // In order to use accept handle with other Window Sockets 1.1 + // functions, we call the setsockopt function with the + // SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the + // socket so that other Windows Sockets routines to access the + // socket correctly. + if (!error && + ACE_OS::setsockopt (result.accept_handle (), + SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, + (char *) &this->listen_handle_, + sizeof (this->listen_handle_)) == -1) + { + error = 1; + } +#endif /* ACE_WIN32 */ + + // Parse address. + ACE_INET_Addr local_address; + ACE_INET_Addr remote_address; + if (!error && + (this->validate_new_connection_ || this->pass_addresses_)) + // Parse the addresses. + this->parse_address (result, + remote_address, + local_address); + + // Validate remote address + if (!error && + this->validate_new_connection_ && + (this->validate_connection (result, remote_address, local_address) == -1)) + { + error = 1; + } + + HANDLER *new_handler = 0; + if (!error) + { + // The Template method + new_handler = this->make_handler (); + if (new_handler == 0) + { + error = 1; + } + } + + // If no errors + if (!error) + { + // Update the Proactor. + new_handler->proactor (this->proactor ()); + + // Pass the addresses + if (this->pass_addresses_) + new_handler->addresses (remote_address, + local_address); + + // Pass the ACT + if (result.act () != 0) + new_handler->act (result.act ()); + + // Set up the handler's new handle value + new_handler->handle (result.accept_handle ()); + + // Initiate the handler + new_handler->open (result.accept_handle (), + result.message_block ()); + } + + // On failure, no choice but to close the socket + if (error && + result.accept_handle() != ACE_INVALID_HANDLE ) + ACE_OS::closesocket (result.accept_handle ()); + + // Delete the dynamically allocated message_block + result.message_block ().release (); + + // Start off another asynchronous accept to keep the backlog going, + // unless we closed the listen socket already (from the destructor), + // or this callback is the result of a canceled/aborted accept. + if (this->should_reissue_accept () && + this->listen_handle_ != ACE_INVALID_HANDLE +#if defined (ACE_WIN32) + && result.error () != ERROR_OPERATION_ABORTED +#else + && result.error () != ECANCELED +#endif + ) + this->accept (this->bytes_to_read_); +} + +template int +ACE_Asynch_Acceptor::validate_connection + (const ACE_Asynch_Accept::Result& /* result */, + const ACE_INET_Addr& /* remote */, + const ACE_INET_Addr& /* local */) +{ + // Default implementation always validates the remote address. + return 0; +} + +template int +ACE_Asynch_Acceptor::cancel (void) +{ + ACE_TRACE ("ACE_Asynch_Acceptor<>::cancel"); + + // All I/O operations that are canceled will complete with the error + // ERROR_OPERATION_ABORTED. All completion notifications for the I/O + // operations will occur normally. +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + return (int) ::CancelIo (this->listen_handle_); +#else + // Supported now + return this->asynch_accept_.cancel(); +#endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) */ +} + +template void +ACE_Asynch_Acceptor::parse_address (const + ACE_Asynch_Accept::Result &result, + ACE_INET_Addr &remote_address, + ACE_INET_Addr &local_address) +{ + ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address"); + +#if defined (ACE_HAS_AIO_CALLS) + + // Use an ACE_SOCK to get the addresses - it knows how to deal with + // ACE_INET_Addr objects and get IPv4/v6 addresses. + ACE_SOCK_Stream str (result.accept_handle ()); + str.get_local_addr (local_address); + str.get_remote_addr (remote_address); + +#elif defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) + + ACE_Message_Block &message_block = result.message_block (); + + sockaddr *local_addr = 0; + sockaddr *remote_addr = 0; + int local_size = 0; + int remote_size = 0; + // This matches setup in accept(). + size_t addr_size = sizeof (sockaddr_in) + 16; +#if defined (ACE_HAS_IPV6) + if (this->addr_family_ == PF_INET6) + addr_size = sizeof (sockaddr_in6) + 16; +#endif /* ACE_HAS_IPV6 */ + + ::GetAcceptExSockaddrs (message_block.rd_ptr (), + static_cast (this->bytes_to_read_), + static_cast (addr_size), + static_cast (addr_size), + &local_addr, + &local_size, + &remote_addr, + &remote_size); + + local_address.set (reinterpret_cast (local_addr), + local_size); + remote_address.set (reinterpret_cast (remote_addr), + remote_size); +#else + // just in case + errno = ENOTSUP; +#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */ + return; +} + +template ACE_HANDLE +ACE_Asynch_Acceptor::handle (void) const +{ + return this->listen_handle_; +} + +template void +ACE_Asynch_Acceptor::handle (ACE_HANDLE h) +{ + ACE_Handler::handle (h); +} + +template ACE_Asynch_Accept & +ACE_Asynch_Acceptor::asynch_accept (void) +{ + return this->asynch_accept_; +} + +template HANDLER * +ACE_Asynch_Acceptor::make_handler (void) +{ + // Default behavior + HANDLER *handler = 0; + ACE_NEW_RETURN (handler, + HANDLER, + 0); + return handler; +} + +/* static */ +template size_t +ACE_Asynch_Acceptor::address_size (void) +{ + return sizeof (sockaddr) + sizeof (sockaddr_in); +} + +template bool +ACE_Asynch_Acceptor::pass_addresses (void) const +{ + return this->pass_addresses_; +} + +template void +ACE_Asynch_Acceptor::pass_addresses (bool new_value) +{ + this->pass_addresses_ = new_value; +} + +template bool +ACE_Asynch_Acceptor::validate_new_connection (void) const +{ + return this->validate_new_connection_; +} + +template void +ACE_Asynch_Acceptor::validate_new_connection (bool new_value) +{ + this->validate_new_connection_ = new_value; +} + +template int +ACE_Asynch_Acceptor::reissue_accept (void) const +{ + return this->reissue_accept_; +} + +template void +ACE_Asynch_Acceptor::reissue_accept (int new_value) +{ + this->reissue_accept_ = new_value; +} + +template size_t +ACE_Asynch_Acceptor::bytes_to_read (void) const +{ + return this->bytes_to_read_; +} + +template void +ACE_Asynch_Acceptor::bytes_to_read (size_t new_value) +{ + this->bytes_to_read_ = new_value; +} + +template int +ACE_Asynch_Acceptor::should_reissue_accept (void) +{ + return this->reissue_accept_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */ +#endif /* ACE_ASYNCH_ACCEPTOR_C */ diff --git a/dep/ACE_wrappers/ace/Asynch_Acceptor.h b/dep/ACE_wrappers/ace/Asynch_Acceptor.h new file mode 100644 index 000000000..29872d594 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_Acceptor.h @@ -0,0 +1,281 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Asynch_Acceptor.h + * + * $Id: Asynch_Acceptor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali (irfan@cs.wustl.edu) + */ +//============================================================================= + +#ifndef ACE_ASYNCH_ACCEPTOR_H +#define ACE_ASYNCH_ACCEPTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) +// This only works on platforms that support async i/o. + +#include "ace/Default_Constants.h" +#include "ace/Asynch_IO.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations +class ACE_Message_Block; +class ACE_INET_Addr; + +/** + * @class ACE_Asynch_Acceptor + * + * @brief This class is an example of the Acceptor Pattern. This class + * will accept new connections and create new HANDLER to handle + * the new connections. + * + * Unlike the ACE_Acceptor, however, this class is designed to + * be used asynchronously. + */ +template +class ACE_Asynch_Acceptor : public ACE_Handler +{ +public: + /// A do nothing constructor. + ACE_Asynch_Acceptor (void); + + /// Virtual destruction + virtual ~ACE_Asynch_Acceptor (void); + + /** + * @c open starts one or more asynchronous accept requests on a + * @a address. Each accept operation may optionally read an + * initial buffer from the new connection when accepted. + * + * @param address The address to listen/accept connections on. + * If the address does not specify a port, a random + * port is selected and bound. + * @param bytes_to_read Optional, specifies the maximum number of bytes + * to read with the accept. The buffer for the initial + * data is allocated internally and passed to the + * @c ACE_Service_Handler::open() hook method. It is + * legitimate only during the @c open() method and must + * be copied if required after @c open() returns. + * This pre-read function works only on Windows. + * @param pass_addresses Optional, a non-zero value indicates that + * the local and peer addresses should be passed to the + * associated @c ACE_Service_Handler::addresses() method + * after any call to @c validate_new_connection() and prior + * to the @c open() hook method call. + * @param backlog Optional, defaulting to @c ACE_DEFAULT_ASYNCH_BACKLOG (which + * can be adjusted in your platform's @c config.h file). + * Specifies the listening backlog for the listening socket. + * @param reuse_addr Optional, indicates whether the @c SO_REUSEADDR + * option is set on the listening socket or not. + * @param proactor Optional, pointer to the @c ACE_Proactor to use for + * demultiplexing asynchronous accepts. If 0, the + * process's singleton @c ACE_Proactor is used. + * @param validate_new_connection Optional, if true, this object's + * @c validate_connection() method is called after + * the accept completes, but before the service handler's + * @c open() hook method is called. If @c + * validate_connection() returns -1, the newly-accepted + * socket is immediately closed, and the @c addresses() + * method is not called. + * @param reissue_accept Optional, if non-zero (the default), a new + * asynchronous accept operation is started after each + * completion, whether the completion is for success or + * failure, and whether or not a successfully-accepted + * connection is subsequently refused. + * @param number_of_initial_accepts Optional, the number of asynchronous + * accepts that are started immediately. If -1 (the + * default), the value of @a backlog is used. + * + * @note On Windows, the peer address is only available at the time + * the connection is accepted. Therefore, if you require the peer + * address on Windows, do not rely on the + * @c ACE_SOCK::get_remote_addr() method - it won't work. You must + * supply a non-zero value for @a pass_addresses and obtain the + * peer address in the @c ACE_Service_Handler::addresses() method. + * + * @see ACE_INET_Addr + * @see ACE_Service_Handler + */ + virtual int open (const ACE_INET_Addr &address, + size_t bytes_to_read = 0, + bool pass_addresses = false, + int backlog = ACE_DEFAULT_ASYNCH_BACKLOG, + int reuse_addr = 1, + ACE_Proactor *proactor = 0, + bool validate_new_connection = false, + int reissue_accept = 1, + int number_of_initial_accepts = -1); + + /// Get the underlying handle. + virtual ACE_HANDLE get_handle (void) const; + + /** + * Set the underlying listen handle. It is the user's responsibility + * to make sure that the old listen handle has been appropriately + * closed and the all outstanding asynchronous operations have + * either completed or have been canceled on the old listen handle. + */ + virtual int set_handle (ACE_HANDLE handle); + + /// This initiates a new asynchronous accept operation. + /** + * You need only call this method if the @a reissue_accept argument + * passed to @c open() was 0. + */ + virtual int accept (size_t bytes_to_read = 0, const void *act = 0); + + /** + * Cancels all pending accepts operations issued by this object. + * + * @note On Windows, only accept operations initiated by the calling thread + * are canceled. + */ + virtual int cancel (void); + + /** + * Template method to validate peer before service is opened. + * This method is called after a new connection is accepted if the + * @a validate_connection argument to @c open() was non-zero or + * the @c validate_new_connection() method is called to turn this + * feature on. The default implementation returns 0. Users can + * reimplement this method to perform validation of the peer + * using it's address, running an authentication procedure (such as + * SSL) or anything else necessary or desireable. The return value + * from this method determines whether or not ACE will continue + * opening the service or abort the connection. + * + * @param result Result of the connection acceptance. + * @param remote Peer's address. + * @param local Local address connection was accepted at. + * + * @retval -1 ACE_Asynch_Acceptor will close the connection, and + * the service will not be opened. + * @retval 0 Service opening will proceeed. + */ + virtual int validate_connection (const ACE_Asynch_Accept::Result& result, + const ACE_INET_Addr &remote, + const ACE_INET_Addr& local); + + /** + * Template method for deciding whether to reissue accept. + * + * This hook method is called after each accept completes to decide if + * another accept should be initiated. If the method returns a non-zero + * value, another accept is initiated. + * + * The default implemenation always returns the value passed as the + * @c open() method's @a reissue_accept argument. That value can also + * be changed using the @c reissue_accept() method. + */ + virtual int should_reissue_accept (void); + + // + // These are low level tweaking methods + // + + /// Get flag that indicates if parsing and passing of addresses to + /// the service_handler is necessary. + virtual bool pass_addresses (void) const; + + /// Set flag that indicates if parsing and passing of addresses to + /// the service_handler is necessary. + virtual void pass_addresses (bool new_value); + + /// Get flag that indicates if address validation is required. + virtual bool validate_new_connection (void) const; + + /// Set flag that indicates if address validation is required. + virtual void validate_new_connection (bool new_value); + + /// Get flag that indicates if a new accept should be reissued when a accept + /// completes. + virtual int reissue_accept (void) const; + + /// Set flag that indicates if a new accept should be reissued when a accept + /// completes. + virtual void reissue_accept (int new_value); + + /// Get bytes to be read with the call. + virtual size_t bytes_to_read (void) const; + + /// Set bytes to be read with the call. + virtual void bytes_to_read (size_t new_value); + + /// @deprecated address_size() assumes IPv4 use, so is not always valid. + /// This method will be removed after ACE 5.5. Internal uses have been + /// changes to base needed sizes on the addr_family_ member. + static size_t address_size (void); + +protected: + + /// This is called when an outstanding accept completes. + virtual void handle_accept (const ACE_Asynch_Accept::Result &result); + + /// Return the listen handle. + ACE_HANDLE handle (void) const; + /// Set the listen handle. + void handle (ACE_HANDLE h); + + /// This parses the address from read buffer. + void parse_address (const ACE_Asynch_Accept::Result &result, + ACE_INET_Addr &remote_address, + ACE_INET_Addr &local_address); + + /// Return the asynch accept object. + ACE_Asynch_Accept &asynch_accept (void); + + /** + * This is the template method used to create new handler. + * Subclasses must overwrite this method if a new handler creation + * strategy is required. + */ + virtual HANDLER *make_handler (void); + +private: + /// Handle used to listen for new connections. + ACE_HANDLE listen_handle_; + + /// Asynch_Accept used to make life easier :-) + ACE_Asynch_Accept asynch_accept_; + + /// Flag that indicates if parsing of addresses is necessary. + bool pass_addresses_; + + /// Flag that indicates if address validation is required. + bool validate_new_connection_; + + /// Flag that indicates if a new accept should be reissued when a + /// accept completes. + int reissue_accept_; + + /// Bytes to be read with the call. + size_t bytes_to_read_; + + /// Address family used to open this object. Obtained from @a address passed + /// to @c open(). + int addr_family_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Asynch_Acceptor.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Asynch_Acceptor.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */ +#include /**/ "ace/post.h" +#endif /* ACE_ASYNCH_ACCEPTOR_H */ diff --git a/dep/ACE_wrappers/ace/Asynch_Connector.cpp b/dep/ACE_wrappers/ace/Asynch_Connector.cpp new file mode 100644 index 000000000..3d493069f --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_Connector.cpp @@ -0,0 +1,296 @@ +// $Id: Asynch_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_ASYNCH_CONNECTOR_CPP +#define ACE_ASYNCH_CONNECTOR_CPP + +#include "ace/Asynch_Connector.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE) +// This only works on platforms that support async I/O. + +#include "ace/OS_NS_sys_socket.h" +#include "ace/OS_Memory.h" +#include "ace/Flag_Manip.h" +#include "ace/Log_Msg.h" +#include "ace/Message_Block.h" +#include "ace/INET_Addr.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Asynch_Connector::ACE_Asynch_Connector (void) + : pass_addresses_ (false), + validate_new_connection_ (false) +{ +} + +template +ACE_Asynch_Connector::~ACE_Asynch_Connector (void) +{ + //this->asynch_connect_.close (); +} + +template int +ACE_Asynch_Connector::open (bool pass_addresses, + ACE_Proactor *proactor, + bool validate_new_connection) +{ + this->proactor (proactor); + this->pass_addresses_ = pass_addresses; + this->validate_new_connection_ = validate_new_connection; + + // Initialize the ACE_Asynch_Connect + if (this->asynch_connect_.open (*this, + ACE_INVALID_HANDLE, + 0, + this->proactor ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Connect::open")), + -1); + return 0; +} + +template int +ACE_Asynch_Connector::connect (const ACE_INET_Addr & remote_sap, + const ACE_INET_Addr & local_sap, + int reuse_addr, + const void *act) +{ + // Initiate asynchronous connect + if (this->asynch_connect_.connect (ACE_INVALID_HANDLE, + remote_sap, + local_sap, + reuse_addr, + act) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Connect::connect")), + -1); + return 0; +} + +template void +ACE_Asynch_Connector::handle_connect (const ACE_Asynch_Connect::Result &result) +{ + // Variable for error tracking + int error = 0; + + // If the asynchronous connect fails. + if (!result.success () || + result.connect_handle () == ACE_INVALID_HANDLE) + { + error = 1; + } + + if (result.error () != 0) + { + error = 1; + } + + // set blocking mode + if (!error && + ACE::clr_flags + (result.connect_handle (), ACE_NONBLOCK) != 0) + { + error = 1; + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode"))); + } + + // Parse the addresses. + ACE_INET_Addr local_address; + ACE_INET_Addr remote_address; + if (!error && + (this->validate_new_connection_ || this->pass_addresses_)) + this->parse_address (result, + remote_address, + local_address); + + // Call validate_connection even if there was an error - it's the only + // way the application can learn the connect disposition. + if (this->validate_new_connection_ && + this->validate_connection (result, remote_address, local_address) == -1) + { + error = 1; + } + + HANDLER *new_handler = 0; + if (!error) + { + // The Template method + new_handler = this->make_handler (); + if (new_handler == 0) + { + error = 1; + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed"))); + } + } + + // If no errors + if (!error) + { + // Update the Proactor. + new_handler->proactor (this->proactor ()); + + // Pass the addresses + if (this->pass_addresses_) + new_handler->addresses (remote_address, + local_address); + + // Pass the ACT + if (result.act () != 0) + new_handler->act (result.act ()); + + // Set up the handler's new handle value + new_handler->handle (result.connect_handle ()); + + ACE_Message_Block mb; + + // Initiate the handler with empty message block; + new_handler->open (result.connect_handle (), mb); + } + + // On failure, no choice but to close the socket + if (error && + result.connect_handle() != ACE_INVALID_HANDLE) + ACE_OS::closesocket (result.connect_handle ()); +} + +template int +ACE_Asynch_Connector::validate_connection + (const ACE_Asynch_Connect::Result &, + const ACE_INET_Addr & /* remote_address */, + const ACE_INET_Addr & /* local_address */) +{ + // Default implementation always validates the remote address. + return 0; +} + +template int +ACE_Asynch_Connector::cancel (void) +{ + return this->asynch_connect_.cancel (); +} + +template void +ACE_Asynch_Connector::parse_address (const ACE_Asynch_Connect::Result &result, + ACE_INET_Addr &remote_address, + ACE_INET_Addr &local_address) +{ +#if defined (ACE_HAS_IPV6) + // Getting the addresses. + sockaddr_in6 local_addr; + sockaddr_in6 remote_addr; +#else + // Getting the addresses. + sockaddr_in local_addr; + sockaddr_in remote_addr; +#endif /* ACE_HAS_IPV6 */ + + // Get the length. + int local_size = sizeof (local_addr); + int remote_size = sizeof (remote_addr); + + // Get the local address. + if (ACE_OS::getsockname (result.connect_handle (), + reinterpret_cast (&local_addr), + &local_size) < 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT("%p\n"), + ACE_TEXT("ACE_Asynch_Connector:: failed"))); + + // Get the remote address. + if (ACE_OS::getpeername (result.connect_handle (), + reinterpret_cast (&remote_addr), + &remote_size) < 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT("%p\n"), + ACE_TEXT("ACE_Asynch_Connector:: failed"))); + + // Set the addresses. + local_address.set (reinterpret_cast (&local_addr), + local_size); + remote_address.set (reinterpret_cast (&remote_addr), + remote_size); + +#if 0 + // @@ Just debugging. + char local_address_buf [BUFSIZ]; + char remote_address_buf [BUFSIZ]; + + if (local_address.addr_to_string (local_address_buf, + sizeof local_address_buf) == -1) + ACE_ERROR ((LM_ERROR, + "Error:%m:can't obtain local_address's address string")); + + ACE_DEBUG ((LM_DEBUG, + "ACE_Asynch_Connector::parse_address : " + "Local address %s\n", + local_address_buf)); + + if (remote_address.addr_to_string (remote_address_buf, + sizeof remote_address_buf) == -1) + ACE_ERROR ((LM_ERROR, + "Error:%m:can't obtain remote_address's address string")); + + ACE_DEBUG ((LM_DEBUG, + "ACE_Asynch_Connector::parse_address : " + "Remote address %s\n", + remote_address_buf)); +#endif /* 0 */ + + return; +} + + +template ACE_Asynch_Connect & +ACE_Asynch_Connector::asynch_connect (void) +{ + return this->asynch_connect_; +} + +template HANDLER * +ACE_Asynch_Connector::make_handler (void) +{ + // Default behavior + HANDLER *handler = 0; + ACE_NEW_RETURN (handler, HANDLER, 0); + return handler; +} + +template bool +ACE_Asynch_Connector::pass_addresses (void) const +{ + return this->pass_addresses_; +} + +template void +ACE_Asynch_Connector::pass_addresses (bool new_value) +{ + this->pass_addresses_ = new_value; +} + +template bool +ACE_Asynch_Connector::validate_new_connection (void) const +{ + return this->validate_new_connection_; +} + +template void +ACE_Asynch_Connector::validate_new_connection (bool new_value) +{ + this->validate_new_connection_ = new_value; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */ +#endif /* ACE_ASYNCH_CONNECTOR_CPP */ diff --git a/dep/ACE_wrappers/ace/Asynch_Connector.h b/dep/ACE_wrappers/ace/Asynch_Connector.h new file mode 100644 index 000000000..7c7969cc2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_Connector.h @@ -0,0 +1,171 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Asynch_Connector.h + * + * $Id: Asynch_Connector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Alexander Libman + */ +//============================================================================= + +#ifndef ACE_ASYNCH_CONNECTOR_H +#define ACE_ASYNCH_CONNECTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE) +// This only works on platforms that support async i/o. + +#include "ace/Asynch_IO.h" +#include "ace/INET_Addr.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations +class ACE_Message_Block; + +/** + * @class ACE_Asynch_Connector + * + * @brief This class is an example of the Connector pattern. This class + * will establish new connections and create new HANDLER objects to handle + * the new connections. + * + * Unlike the ACE_Connector, however, this class is designed to + * be used asynchronously with the ACE Proactor framework. + */ + +template +class ACE_Asynch_Connector : public ACE_Handler +{ +public: + /// A do nothing constructor. + ACE_Asynch_Connector (void); + + /// Virtual destruction + virtual ~ACE_Asynch_Connector (void); + + /** + * This opens asynch connector + */ + virtual int open (bool pass_addresses = false, + ACE_Proactor *proactor = 0, + bool validate_new_connection = true); + + /// This initiates a new asynchronous connect + virtual int connect (const ACE_INET_Addr &remote_sap, + const ACE_INET_Addr &local_sap = + (const ACE_INET_Addr &)ACE_Addr::sap_any, + int reuse_addr = 1, + const void *act = 0); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. + * + * @note On Windows, this method does not cancel connect operations + * issued by other threads. + * + * @note On POSIX, delegates cancelation to ACE_POSIX_Asynch_Connect. + */ + virtual int cancel (void); + + + /** + * Template method to validate peer before service is opened. + * This method is called when the connection attempt completes, + * whether it succeeded or failed, if the @a validate_connection + * argument to @c open() was non-zero or the @c validate_new_connection() + * method is called to turn this feature on. The default implementation + * returns 0. Users can (and probably should) reimplement this method + * to learn about the success or failure of the connection attempt. + * If the connection completed successfully, this method can be used to + * perform validation of the peer using it's address, running an + * authentication procedure (such as SSL) or anything else necessary or + * desireable. The return value from this method determines whether or + * not ACE will continue opening the service or abort the connection. + * + * @param result Result of the connection acceptance. Use + * result.success() to determine success or failure of + * the connection attempt. + * @param remote Peer's address. If the connection failed, this object + * is undefined. + * @param local Local address connection was completed from. If the + * connection failed, this object is undefined. + * + * @retval -1 ACE_Asynch_Connector will close the connection, and + * the service will not be opened. + * @retval 0 Service opening will proceeed. + * @return Return value is ignored if the connection attempt failed. + */ + virtual int validate_connection (const ACE_Asynch_Connect::Result& result, + const ACE_INET_Addr &remote, + const ACE_INET_Addr& local); + + // + // These are low level tweaking methods + // + + /// Set and get flag that indicates if parsing and passing of + /// addresses to the service_handler is necessary. + virtual bool pass_addresses (void) const; + virtual void pass_addresses (bool new_value); + + /// Set and get flag that indicates if address validation is + /// required. + virtual bool validate_new_connection (void) const; + virtual void validate_new_connection (bool new_value); + +protected: + + /// This is called when an outstanding accept completes. + virtual void handle_connect (const ACE_Asynch_Connect::Result &result); + + + /// This parses the address from read buffer. + void parse_address (const ACE_Asynch_Connect::Result &result, + ACE_INET_Addr &remote_address, + ACE_INET_Addr &local_address); + + /// Return the asynch Connect object. + ACE_Asynch_Connect & asynch_connect (void); + + /** + * This is the template method used to create new handler. + * Subclasses must overwrite this method if a new handler creation + * strategy is required. + */ + virtual HANDLER *make_handler (void); + +private: + + /// Asynch_Connect used to make life easier :-) + ACE_Asynch_Connect asynch_connect_; + + /// Flag that indicates if parsing of addresses is necessary. + bool pass_addresses_; + + /// Flag that indicates if address validation is required. + bool validate_new_connection_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Asynch_Connector.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Asynch_Connector.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */ +#include /**/ "ace/post.h" +#endif /* ACE_ASYNCH_CONNECTOR_H */ diff --git a/dep/ACE_wrappers/ace/Asynch_IO.cpp b/dep/ACE_wrappers/ace/Asynch_IO.cpp new file mode 100644 index 000000000..26bba31a3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_IO.cpp @@ -0,0 +1,1414 @@ +// $Id: Asynch_IO.cpp 82559 2008-08-07 20:23:07Z parsons $ + +#include "ace/Asynch_IO.h" + +ACE_RCSID(ace, Asynch_IO, "$Id: Asynch_IO.cpp 82559 2008-08-07 20:23:07Z parsons $") + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) +// This only works on platforms with Asynchronous IO + +#include "ace/Proactor.h" +#include "ace/Message_Block.h" +#include "ace/INET_Addr.h" +#include "ace/Asynch_IO_Impl.h" +#include "ace/os_include/os_errno.h" +#include "ace/Truncate.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +size_t +ACE_Asynch_Result::bytes_transferred (void) const +{ + return this->implementation ()->bytes_transferred (); +} + +const void * +ACE_Asynch_Result::act (void) const +{ + return this->implementation ()->act (); +} + +int +ACE_Asynch_Result::success (void) const +{ + return this->implementation ()->success (); +} + +const void * +ACE_Asynch_Result::completion_key (void) const +{ + return this->implementation ()->completion_key (); +} + +unsigned long +ACE_Asynch_Result::error (void) const +{ + return this->implementation ()->error (); +} + +ACE_HANDLE +ACE_Asynch_Result::event (void) const +{ + return this->implementation ()->event (); +} + +unsigned long +ACE_Asynch_Result::offset (void) const +{ + return this->implementation ()->offset (); +} + +unsigned long +ACE_Asynch_Result::offset_high (void) const +{ + return this->implementation ()->offset_high (); +} + +int +ACE_Asynch_Result::priority (void) const +{ + return this->implementation ()->priority (); +} + +int +ACE_Asynch_Result::signal_number (void) const +{ + return this->implementation ()->signal_number (); +} + +ACE_Asynch_Result::ACE_Asynch_Result (ACE_Asynch_Result_Impl *implementation) + : implementation_ (implementation) +{ +} + +ACE_Asynch_Result::~ACE_Asynch_Result (void) +{ + // Proactor deletes the implementation when the finishes. +} + +ACE_Asynch_Result_Impl * +ACE_Asynch_Result::implementation (void) const +{ + return this->implementation_; +} + +// ********************************************************************* + +int +ACE_Asynch_Operation::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return this->implementation ()->open (handler.proxy (), + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Operation::cancel (void) +{ + if (0 == this->implementation ()) + { + errno = EFAULT; + return -1; + } + return this->implementation ()->cancel (); +} + +ACE_Proactor * +ACE_Asynch_Operation::proactor (void) const +{ + if (0 == this->implementation ()) + { + errno = EFAULT; + return 0; + } + return this->implementation ()->proactor (); +} + +ACE_Asynch_Operation::ACE_Asynch_Operation (void) +{ +} + +ACE_Asynch_Operation::~ACE_Asynch_Operation (void) +{ +} + +ACE_Proactor * +ACE_Asynch_Operation::get_proactor (ACE_Proactor *user_proactor, + ACE_Handler &handler) const +{ + if (user_proactor == 0) + { + // Grab the singleton proactor if proactor> is zero + user_proactor = handler.proactor (); + if (user_proactor == 0) + user_proactor = ACE_Proactor::instance (); + } + + return user_proactor; +} + +// ************************************************************ + +ACE_Asynch_Read_Stream::ACE_Asynch_Read_Stream (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Read_Stream::~ACE_Asynch_Read_Stream (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Read_Stream::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_read_stream ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Read_Stream::read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->read (message_block, + bytes_to_read, + act, + priority, + signal_number); +} + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) +int +ACE_Asynch_Read_Stream::readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->readv (message_block, + bytes_to_read, + act, + priority, + signal_number); +} +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Read_Stream::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +size_t +ACE_Asynch_Read_Stream::Result::bytes_to_read (void) const +{ + return this->implementation ()->bytes_to_read (); +} + +ACE_Message_Block & +ACE_Asynch_Read_Stream::Result::message_block (void) const +{ + return this->implementation ()->message_block (); +} + +ACE_HANDLE +ACE_Asynch_Read_Stream::Result::handle (void) const +{ + return this->implementation ()->handle (); +} + +ACE_Asynch_Read_Stream::Result::Result (ACE_Asynch_Read_Stream_Result_Impl *implementation) + : ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Read_Stream::Result::~Result (void) +{ + // Proactor will delete the implementation after is + // finished. +} + +ACE_Asynch_Read_Stream_Result_Impl * +ACE_Asynch_Read_Stream::Result::implementation (void) const +{ + return this->implementation_; +} + +// *************************************************** + +ACE_Asynch_Write_Stream::ACE_Asynch_Write_Stream (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Write_Stream::~ACE_Asynch_Write_Stream (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Write_Stream::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_write_stream ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Write_Stream::write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->write (message_block, + bytes_to_write, + act, + priority, + signal_number); +} + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) +int +ACE_Asynch_Write_Stream::writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->writev (message_block, + bytes_to_write, + act, + priority, + signal_number); +} +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Write_Stream::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +size_t +ACE_Asynch_Write_Stream::Result::bytes_to_write (void) const +{ + return this->implementation ()->bytes_to_write (); +} + +ACE_Message_Block & +ACE_Asynch_Write_Stream::Result::message_block (void) const +{ + return this->implementation ()->message_block (); +} + +ACE_HANDLE +ACE_Asynch_Write_Stream::Result::handle (void) const +{ + return this->implementation ()->handle (); +} + +ACE_Asynch_Write_Stream::Result::Result (ACE_Asynch_Write_Stream_Result_Impl *implementation) + : ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Write_Stream::Result::~Result (void) +{ + // Proactor will delte the implementation when the call + // finishes. +} + +ACE_Asynch_Write_Stream_Result_Impl * +ACE_Asynch_Write_Stream::Result::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Read_File::ACE_Asynch_Read_File (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Read_File::~ACE_Asynch_Read_File (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Read_File::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_read_file ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Read_File::read (ACE_Message_Block &message_block, + size_t bytes_to_read, + unsigned long offset, + unsigned long offset_high, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->read (message_block, + bytes_to_read, + offset, + offset_high, + act, + priority, + signal_number); +} + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) +int +ACE_Asynch_Read_File::readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + unsigned long offset, + unsigned long offset_high, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->readv (message_block, + bytes_to_read, + offset, + offset_high, + act, + priority, + signal_number); +} +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Read_File::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Read_File::Result::Result (ACE_Asynch_Read_File_Result_Impl *implementation) + : ACE_Asynch_Read_Stream::Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Read_File::Result::~Result (void) +{ + // Proactor will delete the implementation when call + // completes. +} + +ACE_Asynch_Read_File_Result_Impl * +ACE_Asynch_Read_File::Result::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Write_File::ACE_Asynch_Write_File (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Write_File::~ACE_Asynch_Write_File (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Write_File::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_write_file ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Write_File::write (ACE_Message_Block &message_block, + size_t bytes_to_write, + unsigned long offset, + unsigned long offset_high, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->write (message_block, + bytes_to_write, + offset, + offset_high, + act, + priority, + signal_number); +} + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) +int +ACE_Asynch_Write_File::writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + unsigned long offset, + unsigned long offset_high, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->writev (message_block, + bytes_to_write, + offset, + offset_high, + act, + priority, + signal_number); +} +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Write_File::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Write_File::Result::Result (ACE_Asynch_Write_File_Result_Impl *implementation) + : ACE_Asynch_Write_Stream::Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Write_File::Result::~Result (void) +{ + // Proactor will delete the implementation when the call + // completes. +} + +ACE_Asynch_Write_File_Result_Impl * +ACE_Asynch_Write_File::Result::implementation (void) const +{ + return this->implementation_; +} + +// ********************************************************************* + +ACE_Asynch_Accept::ACE_Asynch_Accept (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Accept::~ACE_Asynch_Accept (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Accept::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_accept ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Accept::accept (ACE_Message_Block &message_block, + size_t bytes_to_read, + ACE_HANDLE accept_handle, + const void *act, + int priority, + int signal_number, + int addr_family) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->accept (message_block, + bytes_to_read, + accept_handle, + act, + priority, + signal_number, + addr_family); +} + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Accept::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +size_t +ACE_Asynch_Accept::Result::bytes_to_read (void) const +{ + return this->implementation ()->bytes_to_read (); +} + +ACE_Message_Block & +ACE_Asynch_Accept::Result::message_block (void) const +{ + return this->implementation ()->message_block (); +} + +ACE_HANDLE +ACE_Asynch_Accept::Result::listen_handle (void) const +{ + return this->implementation ()->listen_handle (); +} + +ACE_HANDLE +ACE_Asynch_Accept::Result::accept_handle (void) const +{ + return this->implementation ()->accept_handle (); +} + +ACE_Asynch_Accept::Result::Result (ACE_Asynch_Accept_Result_Impl *implementation) + : ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Accept::Result::~Result (void) +{ + // Proactor will delete the implementation when the call + // completes. +} + +ACE_Asynch_Accept_Result_Impl * +ACE_Asynch_Accept::Result::implementation (void) const +{ + return this->implementation_; +} + + + +// ********************************************************************* + +ACE_Asynch_Connect::ACE_Asynch_Connect (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Connect::~ACE_Asynch_Connect (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Connect::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_connect ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Connect::connect (ACE_HANDLE connect_handle, + const ACE_Addr & remote_sap, + const ACE_Addr & local_sap, + int reuse_addr, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->connect (connect_handle, + remote_sap, + local_sap, + reuse_addr, + act, + priority, + signal_number); +} + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Connect::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Connect::Result::Result (ACE_Asynch_Connect_Result_Impl *implementation) + : ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Connect::Result::~Result (void) +{ + // Proactor will delete the implementation when the call + // completes. +} + +ACE_HANDLE +ACE_Asynch_Connect::Result::connect_handle (void) const +{ + return this->implementation ()->connect_handle (); +} + + +ACE_Asynch_Connect_Result_Impl * +ACE_Asynch_Connect::Result::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Transmit_File::ACE_Asynch_Transmit_File (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Transmit_File::~ACE_Asynch_Transmit_File (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Transmit_File::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_transmit_file ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +int +ACE_Asynch_Transmit_File::transmit_file (ACE_HANDLE file, + Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + unsigned long offset, + unsigned long offset_high, + size_t bytes_per_send, + unsigned long flags, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->transmit_file (file, + header_and_trailer, + bytes_to_write, + offset, + offset_high, + bytes_per_send, + flags, + act, + priority, + signal_number); +} + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Transmit_File::implementation (void) const +{ + return this->implementation_; +} + +// **************************************************************************** + +ACE_HANDLE +ACE_Asynch_Transmit_File::Result::socket (void) const +{ + return this->implementation ()->socket (); +} + +ACE_HANDLE +ACE_Asynch_Transmit_File::Result::file (void) const +{ + return this->implementation ()->file (); +} + +ACE_Asynch_Transmit_File::Header_And_Trailer * +ACE_Asynch_Transmit_File::Result::header_and_trailer (void) const +{ + return this->implementation ()->header_and_trailer (); +} + +size_t +ACE_Asynch_Transmit_File::Result::bytes_to_write (void) const +{ + return this->implementation ()->bytes_to_write (); +} + +size_t +ACE_Asynch_Transmit_File::Result::bytes_per_send (void) const +{ + return this->implementation ()->bytes_per_send (); +} + +unsigned long +ACE_Asynch_Transmit_File::Result::flags (void) const +{ + return this->implementation ()->flags (); +} + +ACE_Asynch_Transmit_File::Result::Result (ACE_Asynch_Transmit_File_Result_Impl *implementation) + : ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Transmit_File::Result::~Result (void) +{ +} + +ACE_Asynch_Transmit_File_Result_Impl * +ACE_Asynch_Transmit_File::Result::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +ACE_Asynch_Transmit_File::Header_And_Trailer::Header_And_Trailer (ACE_Message_Block *header, + size_t header_bytes, + ACE_Message_Block *trailer, + size_t trailer_bytes) + : header_ (header), + header_bytes_ (header_bytes), + trailer_ (trailer), + trailer_bytes_ (trailer_bytes) +{ +} + +ACE_Asynch_Transmit_File::Header_And_Trailer::~Header_And_Trailer (void) +{ +} + +void +ACE_Asynch_Transmit_File::Header_And_Trailer::header_and_trailer (ACE_Message_Block *header, + size_t header_bytes, + ACE_Message_Block *trailer, + size_t trailer_bytes) +{ + this->header (header); + this->header_bytes (header_bytes); + this->trailer (trailer); + this->trailer_bytes (trailer_bytes); +} + +ACE_Message_Block * +ACE_Asynch_Transmit_File::Header_And_Trailer::header (void) const +{ + return this->header_; +} + +void +ACE_Asynch_Transmit_File::Header_And_Trailer::header (ACE_Message_Block *message_block) +{ + this->header_ = message_block; +} + +size_t +ACE_Asynch_Transmit_File::Header_And_Trailer::header_bytes (void) const +{ + return this->header_bytes_; +} + +void +ACE_Asynch_Transmit_File::Header_And_Trailer::header_bytes (size_t bytes) +{ + this->header_bytes_ = bytes; +} + +ACE_Message_Block * +ACE_Asynch_Transmit_File::Header_And_Trailer::trailer (void) const +{ + return this->trailer_; +} + +void +ACE_Asynch_Transmit_File::Header_And_Trailer::trailer (ACE_Message_Block *message_block) +{ + this->trailer_ = message_block; +} + +size_t +ACE_Asynch_Transmit_File::Header_And_Trailer::trailer_bytes (void) const +{ + return this->trailer_bytes_; +} + +void +ACE_Asynch_Transmit_File::Header_And_Trailer::trailer_bytes (size_t bytes) +{ + this->trailer_bytes_ = bytes; +} + +ACE_LPTRANSMIT_FILE_BUFFERS +ACE_Asynch_Transmit_File::Header_And_Trailer::transmit_buffers (void) +{ + // If both are zero, return zero + if (this->header_ == 0 && this->trailer_ == 0) + { + return 0; + } + else + { + // Something is valid + + // If header is valid, set the fields + if (this->header_ != 0) + { + this->transmit_buffers_.Head = this->header_->rd_ptr (); +#if defined (ACE_WIN64) || defined (ACE_WIN32) + this->transmit_buffers_.HeadLength = + ACE_Utils::truncate_cast (this->header_bytes_); +#else + this->transmit_buffers_.HeadLength = this->header_bytes_; +#endif /* ACE_WIN64 || ACE_WIN32 */ + } + else + { + this->transmit_buffers_.Head = 0; + this->transmit_buffers_.HeadLength = 0; + } + + // If trailer is valid, set the fields + if (this->trailer_ != 0) + { + this->transmit_buffers_.Tail = this->trailer_->rd_ptr (); +#if defined(ACE_WIN64) || defined (ACE_WIN32) + this->transmit_buffers_.TailLength = + ACE_Utils::truncate_cast (this->trailer_bytes_); +#else + this->transmit_buffers_.TailLength = this->trailer_bytes_; +#endif /* ACE_WIN64 || ACE_WIN32 */ + } + else + { + this->transmit_buffers_.Tail = 0; + this->transmit_buffers_.TailLength = 0; + } + + // Return the transmit buffers + return &this->transmit_buffers_; + } +} + +// ********************************************************************* + +ACE_Handler::ACE_Handler (void) + : proactor_ (0), handle_ (ACE_INVALID_HANDLE) +{ + ACE_Handler::Proxy *p; + ACE_NEW (p, ACE_Handler::Proxy (this)); + this->proxy_.reset (p); +} + +ACE_Handler::ACE_Handler (ACE_Proactor *d) + : proactor_ (d), handle_ (ACE_INVALID_HANDLE) +{ + ACE_Handler::Proxy *p; + ACE_NEW (p, ACE_Handler::Proxy (this)); + this->proxy_.reset (p); +} + +ACE_Handler::~ACE_Handler (void) +{ + ACE_Handler::Proxy *p = this->proxy_.get (); + if (p) + p->reset (); +} + +void +ACE_Handler::handle_read_stream (const ACE_Asynch_Read_Stream::Result & /* result */) +{ +} + +void +ACE_Handler::handle_write_stream (const ACE_Asynch_Write_Stream::Result & /* result */) +{ +} + +void +ACE_Handler::handle_write_dgram (const ACE_Asynch_Write_Dgram::Result & /* result */) +{ +} + +void +ACE_Handler::handle_read_dgram (const ACE_Asynch_Read_Dgram::Result & /* result */) +{ +} + +void +ACE_Handler::handle_accept (const ACE_Asynch_Accept::Result & /* result */) +{ +} + +void +ACE_Handler::handle_connect (const ACE_Asynch_Connect::Result & /* result */) +{ +} + +void +ACE_Handler::handle_transmit_file (const ACE_Asynch_Transmit_File::Result & /* result */) +{ +} + +void +ACE_Handler::handle_read_file (const ACE_Asynch_Read_File::Result & /* result */) +{ +} + +void +ACE_Handler::handle_write_file (const ACE_Asynch_Write_File::Result & /* result */) +{ +} + +void +ACE_Handler::handle_time_out (const ACE_Time_Value & /* tv */, + const void * /* act */) +{ +} + +void +ACE_Handler::handle_wakeup (void) +{ +} + +ACE_Proactor * +ACE_Handler::proactor (void) +{ + return this->proactor_; +} + +void +ACE_Handler::proactor (ACE_Proactor *p) +{ + this->proactor_ = p; +} + +ACE_HANDLE +ACE_Handler::handle (void) const +{ + return this->handle_; +} + +void +ACE_Handler::handle (ACE_HANDLE h) +{ + this->handle_ = h; +} + +ACE_Refcounted_Auto_Ptr & +ACE_Handler::proxy (void) +{ + return this->proxy_; +} + +// ************************************************************ + +ACE_Service_Handler::ACE_Service_Handler (void) +{ +} + +ACE_Service_Handler::~ACE_Service_Handler (void) +{ +} + +void +ACE_Service_Handler::addresses (const ACE_INET_Addr & /* remote_address */, + const ACE_INET_Addr & /* local_address */ ) +{ +} + +void +ACE_Service_Handler::act (const void *) +{ +} + +void +ACE_Service_Handler::open (ACE_HANDLE, + ACE_Message_Block &) +{ +} + + +// ************************************************************ + +ACE_Asynch_Read_Dgram::ACE_Asynch_Read_Dgram (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Read_Dgram::~ACE_Asynch_Read_Dgram (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Read_Dgram::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_read_dgram ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +ssize_t +ACE_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block, + size_t &number_of_bytes_recvd, + int flags, + int protocol_family, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->recv (message_block, + number_of_bytes_recvd, + flags, + protocol_family, + act, + priority, + signal_number); +} + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Read_Dgram::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +int +ACE_Asynch_Read_Dgram::Result::remote_address (ACE_Addr& addr) const +{ + return this->implementation ()->remote_address (addr); +} + +ACE_Message_Block* +ACE_Asynch_Read_Dgram::Result::message_block (void) const +{ + return this->implementation ()->message_block (); +} + +int +ACE_Asynch_Read_Dgram::Result::flags (void) const +{ + return this->implementation ()->flags (); +} + +size_t +ACE_Asynch_Read_Dgram::Result::bytes_to_read (void) const +{ + return this->implementation ()->bytes_to_read (); +} + +ACE_HANDLE +ACE_Asynch_Read_Dgram::Result::handle (void) const +{ + return this->implementation ()->handle(); +} + +ACE_Asynch_Read_Dgram::Result::Result (ACE_Asynch_Read_Dgram_Result_Impl *implementation) +: ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Read_Dgram::Result::~Result (void) +{ +} + +ACE_Asynch_Read_Dgram_Result_Impl * +ACE_Asynch_Read_Dgram::Result::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + + +ACE_Asynch_Write_Dgram::ACE_Asynch_Write_Dgram (void) + : implementation_ (0) +{ +} + +ACE_Asynch_Write_Dgram::~ACE_Asynch_Write_Dgram (void) +{ + // Delete the implementation. + delete this->implementation_; + this->implementation_ = 0; +} + +int +ACE_Asynch_Write_Dgram::open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + // Get a proactor for/from the user. + proactor = this->get_proactor (proactor, handler); + + // Now let us get the implementation initialized. + if ((this->implementation_ = proactor->create_asynch_write_dgram ()) == 0) + return -1; + + // Call the method of the base class. + return ACE_Asynch_Operation::open (handler, + handle, + completion_key, + proactor); +} + +ssize_t +ACE_Asynch_Write_Dgram::send (ACE_Message_Block *message_block, + size_t &number_of_bytes_sent, + int flags, + const ACE_Addr& remote_addr, + const void *act, + int priority, + int signal_number) +{ + if (0 == this->implementation_) + { + errno = EFAULT; + return -1; + } + return this->implementation_->send (message_block, + number_of_bytes_sent, + flags, + remote_addr, + act, + priority, + signal_number); +} + +ACE_Asynch_Operation_Impl * +ACE_Asynch_Write_Dgram::implementation (void) const +{ + return this->implementation_; +} + +// ************************************************************ + +size_t +ACE_Asynch_Write_Dgram::Result::bytes_to_write (void) const +{ + return this->implementation ()->bytes_to_write (); +} + +ACE_Message_Block* +ACE_Asynch_Write_Dgram::Result::message_block () const +{ + return this->implementation ()->message_block (); +} + +int +ACE_Asynch_Write_Dgram::Result::flags (void) const +{ + return this->implementation ()->flags (); +} + +ACE_HANDLE +ACE_Asynch_Write_Dgram::Result::handle (void) const +{ + return this->implementation ()->handle (); +} + +ACE_Asynch_Write_Dgram_Result_Impl * +ACE_Asynch_Write_Dgram::Result::implementation (void) const +{ + return this->implementation_; +} + +ACE_Asynch_Write_Dgram::Result::Result (ACE_Asynch_Write_Dgram_Result_Impl *implementation) +: ACE_Asynch_Result (implementation), + implementation_ (implementation) +{ +} + +ACE_Asynch_Write_Dgram::Result::~Result (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */ diff --git a/dep/ACE_wrappers/ace/Asynch_IO.h b/dep/ACE_wrappers/ace/Asynch_IO.h new file mode 100644 index 000000000..6aeb21fe5 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_IO.h @@ -0,0 +1,1734 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Asynch_IO.h + * + * $Id: Asynch_IO.h 81870 2008-06-09 20:53:53Z shuston $ + * + * This works on Win32 (defined (ACE_WIN32) && !defined + * (ACE_HAS_WINCE)) platforms and on POSIX4 platforms with {aio_*} + * routines (defined (ACE_HAS_AIO_CALLS)) + * + * On Win32 platforms, the implementation of + * {ACE_Asynch_Transmit_File} and {ACE_Asynch_Accept} are only + * supported if ACE_HAS_WINSOCK2 is defined or you are on WinNT 4.0 + * or higher. + * + * @author Irfan Pyarali + * @author Tim Harrison + * @author Alexander Babu Arulanthu + * @author Roger Tragin + * @author Alexander Libman + */ +//============================================================================= + +#ifndef ACE_ASYNCH_IO_H +#define ACE_ASYNCH_IO_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) + +#include "ace/Synch_Traits.h" +#if defined (ACE_HAS_THREADS) +# include "ace/Thread_Mutex.h" +#else +# include "ace/Null_Mutex.h" +#endif /* ACE_HAS_THREADS */ +#include "ace/Refcounted_Auto_Ptr.h" + +#include "ace/os_include/os_signal.h" +#include "ace/os_include/sys/os_socket.h" +#include "ace/os_include/sys/os_types.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_HAS_WIN32_OVERLAPPED_IO) +typedef TRANSMIT_FILE_BUFFERS ACE_TRANSMIT_FILE_BUFFERS; +typedef LPTRANSMIT_FILE_BUFFERS ACE_LPTRANSMIT_FILE_BUFFERS; +typedef PTRANSMIT_FILE_BUFFERS ACE_PTRANSMIT_FILE_BUFFERS; + +# define ACE_INFINITE INFINITE +# define ACE_STATUS_TIMEOUT STATUS_TIMEOUT +# define ACE_WAIT_FAILED WAIT_FAILED +# define ACE_WAIT_TIMEOUT WAIT_TIMEOUT +# else /* ACE_HAS_WIN32_OVERLAPPED_IO */ +struct ACE_TRANSMIT_FILE_BUFFERS +{ + void *Head; + size_t HeadLength; + void *Tail; + size_t TailLength; +}; +typedef ACE_TRANSMIT_FILE_BUFFERS* ACE_PTRANSMIT_FILE_BUFFERS; +typedef ACE_TRANSMIT_FILE_BUFFERS* ACE_LPTRANSMIT_FILE_BUFFERS; + +# if !defined (ACE_INFINITE) +# define ACE_INFINITE LONG_MAX +# endif /* ACE_INFINITE */ +# define ACE_STATUS_TIMEOUT LONG_MAX +# define ACE_WAIT_FAILED LONG_MAX +# define ACE_WAIT_TIMEOUT LONG_MAX +# endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + +// Forward declarations +class ACE_Proactor; +class ACE_Handler; +class ACE_Message_Block; +class ACE_INET_Addr; +class ACE_Addr; + +// Forward declarations +class ACE_Asynch_Result_Impl; +class ACE_Time_Value; + +/** + * @class ACE_Asynch_Result + * + * @brief An interface base class which allows users access to common + * information related to an asynchronous operation. + * + * An interface base class from which you can obtain some basic + * information like the number of bytes transferred, the ACT + * associated with the asynchronous operation, indication of + * success or failure, etc. Subclasses may want to store more + * information that is particular to the asynchronous operation + * it represents. + */ +class ACE_Export ACE_Asynch_Result +{ + +public: + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This is the ACT associated with the handle on which the + * Asynch_Operation takes place. + * + * On WIN32, this returns the ACT associated with the handle when it + * was registered with the I/O completion port. + * + * @@ This is not implemented for POSIX4 platforms. Returns 0. + */ + const void *completion_key (void) const; + + /// Error value if the operation fails. + unsigned long error (void) const; + + /** + * On WIN32, this returns the event associated with the OVERLAPPED + * structure. + * + * This returns ACE_INVALID_HANDLE on POSIX4-Unix platforms. + */ + ACE_HANDLE event (void) const; + + /** + * This really makes sense only when doing file I/O. + * + * On WIN32, these are represented in the OVERLAPPED datastructure. + * + * @@ On POSIX4-Unix, offset_high should be supported using + * aiocb64. + */ + unsigned long offset (void) const; + unsigned long offset_high (void) const; + + /** + * Priority of the operation. + * + * On POSIX4-Unix, this is supported. Priority works like {nice} in + * Unix. Negative values are not allowed. 0 means priority of the + * operation same as the process priority. 1 means priority of the + * operation is one less than process. And so forth. + * + * On Win32, this is a no-op. + */ + int priority (void) const; + + /** + * POSIX4 real-time signal number to be used for the + * operation. {signal_number} ranges from ACE_SIGRTMIN to ACE_SIGRTMAX. By + * default, ACE_SIGRTMIN is used to issue {aio_} calls. This is a no-op + * on non-POSIX4 systems and returns 0. + */ + int signal_number (void) const; + + + /// Destructor. + virtual ~ACE_Asynch_Result (void); + +protected: + /// Constructor. This implementation will not be deleted. The + /// implementation will be deleted by the Proactor. + ACE_Asynch_Result (ACE_Asynch_Result_Impl *implementation); + + /// Get the implementation class. + ACE_Asynch_Result_Impl *implementation (void) const; + + /// Implementation class. + ACE_Asynch_Result_Impl *implementation_; +}; + +// Forward declarations +class ACE_Asynch_Operation_Impl; + +/** + * @class ACE_Asynch_Operation + * + * @brief This is an interface base class for all asynch + * operations. The resposiblility of this class is to forward + * all methods to its delegation/implementation class, e.g., + * ACE_WIN32_Asynch_Operation or ACE_POSIX_Asynch_Operation. + * + * There are some attributes and functionality which is common + * to all asychronous operations. The delegation classes of this + * class will factor out this code. + */ +class ACE_Export ACE_Asynch_Operation +{ + +public: + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ({handle} == ACE_INVALID_HANDLE), + * {ACE_Handler::handle} will be called on the {handler} to get the + * correct handle. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * (Attempts to) cancel the asynchronous operation pending against + * the {handle} registered with this Operation. + * + * All completion notifications for the I/O operations will occur + * normally. + * + * = Return Values: + * + * -1 : Operation failed. (can get only in POSIX). + * 0 : All the operations were cancelled. + * 1 : All the operations were already finished in this + * handle. Unable to cancel them. + * 2 : Atleast one of the requested operations cannot be + * cancelled. + * + * There is slight difference in the semantics between NT and POSIX + * platforms which is given below. + * + * = Win32 : + * + * cancels all pending accepts operations that were issued by the + * calling thread. The function does not cancel asynchronous + * operations issued by other threads. + * All I/O operations that are canceled will complete with the + * error ERROR_OPERATION_ABORTED. + * + * = POSIX: + * + * Attempts to cancel one or more asynchronous I/O requests + * currently outstanding against the {handle} registered in this + * operation. + * For requested operations that are successfully canceled, the + * associated error status is set to ECANCELED. + */ + int cancel (void); + + + // = Access methods. + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + + /// Destructor. + virtual ~ACE_Asynch_Operation (void); + +protected: + /// Constructor. + ACE_Asynch_Operation (void); + + /// Return the underlying implementation class. + virtual ACE_Asynch_Operation_Impl *implementation (void) const = 0; + + /// Get a proactor for/from the user + ACE_Proactor *get_proactor (ACE_Proactor *user_proactor, + ACE_Handler &handler) const; +}; + +// Forward declarations +class ACE_Asynch_Read_Stream_Result_Impl; +class ACE_Asynch_Read_Stream_Impl; + +/** + * @class ACE_Asynch_Read_Stream + * + * @brief This class is a factory for starting off asynchronous reads + * on a stream. This class forwards all methods to its + * implementation class. + * + * Once {open} is called, multiple asynchronous {read}s can + * started using this class. An ACE_Asynch_Read_Stream::Result + * will be passed back to the {handler} when the asynchronous + * reads completes through the {ACE_Handler::handle_read_stream} + * callback. + */ +class ACE_Export ACE_Asynch_Read_Stream : public ACE_Asynch_Operation +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Read_Stream (void); + + /// Destructor + virtual ~ACE_Asynch_Read_Stream (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. + * + * @param handler The ACE_Handler that will be called to handle completions + * for operations initiated using this factory. + * @param handle The handle that future read operations will use. + * If handle == @c ACE_INVALID_HANDLE, + * ACE_Handler::handle() will be called on @ handler + * to get the correct handle. + * + * @retval 0 for success. + * @retval -1 for failure; consult @c errno for further information. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * Initiate an asynchronous read operation. + * + * @param message_block The ACE_Message_Block to receive the data. + * Received bytes will be placed in the block + * beginning at its current write pointer. + * If data is read, the message block's write + * pointer will be advanced by the number of + * bytes read. + * @param num_bytes_to_read The maximum number of bytes to read. + * @param act Asynchronous Completion Token; passed through to + * the completion handler in the Result object. + * @param priority Priority of the operation. On POSIX4-Unix, + * this is supported. Works like @c nice in Unix. + * Negative values are not allowed. 0 means + * priority of the operation same as the process + * priority. 1 means priority of the operation is + * one less than process priority, etc. + * Ignored on Windows. + * @param signal_number The POSIX4 real-time signal number to be used + * to signal completion of the operation. Values + * range from ACE_SIGRTMIN to ACE_SIGRTMAX. + * This argument is ignored on non-POSIX4 systems. + */ + int read (ACE_Message_Block &message_block, + size_t num_bytes_to_read, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + */ + int readv (ACE_Message_Block &message_block, + size_t num_bytes_to_read, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); +#endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) */ + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Implementation class that all methods will be forwarded to. + ACE_Asynch_Read_Stream_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is the class which will be passed back to the + * ACE_Handler::handle_read_stream when the asynchronous read completes. + * This class forwards all the methods to the implementation classes. + * + * This class has all the information necessary for the + * handler to uniquiely identify the completion of the + * asynchronous read. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Read_Stream_Result; + friend class ACE_WIN32_Asynch_Read_Stream_Result; + + public: + /// The number of bytes which were requested at the start of the + /// asynchronous read. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for reading. + ACE_HANDLE handle (void) const; + + /// Get the implementation class. + ACE_Asynch_Read_Stream_Result_Impl *implementation (void) const; + + protected: + /// Constructor. + Result (ACE_Asynch_Read_Stream_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// The implementation class. + ACE_Asynch_Read_Stream_Result_Impl *implementation_; + }; +}; + +// Forward declarations +class ACE_Asynch_Write_Stream_Impl; +class ACE_Asynch_Write_Stream_Result_Impl; + +/** + * @class ACE_Asynch_Write_Stream + * + * @brief This class is a factory for initiating asynchronous writes + * on a connected TCP/IP stream. This class forwards all methods to its + * implementation class. + * + * Once open() is called, multiple asynchronous writes can be + * started using this class. An ACE_Asynch_Write_Stream::Result + * will be passed to the ACE_Handler::handle_write_stream() method on the + * opened ACE_Handler object when the asynchronous write completes. + */ +class ACE_Export ACE_Asynch_Write_Stream : public ACE_Asynch_Operation +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Write_Stream (void); + + /// Destructor. + virtual ~ACE_Asynch_Write_Stream (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous operation. + * + * @param handler ACE_Handler to be notified when operations initiated + * via this factory complete. The handle_write_stream() + * method will be called on this object. + * @param handle The socket handle to initiate write operations on. + * If handle is @c ACE_INVALID_HANDLE, + * ACE_Handler::handle() will be called on handler to + * get the handle value. + * @param completion_key A token that is passed to the completion handler. + * @param proactor The ACE_Proactor object which will control operation + * completion and dispatching the results to handler. + * If this is 0, the process's singleton ACE_Proactor + * will be used. + * + * @retval 0 for success. + * @retval -1 for failure; consult @c errno for further information. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * Initiates an asynchronous write on a socket. If the operation completes + * the ACE_Handler object registered in open() will receive a completion + * callback via its handle_write_stream() method. + * + * @param bytes_to_write The number of bytes to write. + * @param message_block The ACE_Message_Block containing data to write. + * Data is written to the socket beginning at the + * block's rd_ptr. Upon successful completion + * of the write operation, the message_block rd_ptr + * is updated to reflect the data that was written. + * @param act Token that is passed through to the completion + * handler. + * @param priority Priority of the operation. This argument only has + * an affect on POSIX4-Unix. Works like @c nice in + * Unix; negative values are not allowed. 0 means + * priority of the operation same as the process + * priority. 1 means priority of the operation is one + * less than the process, and so forth. + * @param signal_number The POSIX4 real-time signal number to be used + * for the operation. signal_number ranges from + * ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is + * not used on other platforms. + * + * @retval 0 for success, and the handle_write_stream associated + * with the opened ACE_Handler will be called. An + * instance of ACE_Asynch_Write_Stream::Result will be + * passed to the completion handler. + * @retval -1 for failure; consult @c errno for further information. + */ + int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + */ + int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); +#endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) */ + + /// Return the underlying implementation class. + /// @todo (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Implementation class that all methods will be forwarded to. + ACE_Asynch_Write_Stream_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * ACE_Handler when the asynchronous write completes. This class + * forwards all the methods to the implementation class. + * + * This class has all the information necessary for the + * handler to uniquiely identify the completion of the + * asynchronous write. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Write_Stream_Result; + friend class ACE_WIN32_Asynch_Write_Stream_Result; + + public: + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write (void) const; + + /// Message block that contains the data to be written. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for writing. + ACE_HANDLE handle (void) const; + + /// Get the implementation class. + ACE_Asynch_Write_Stream_Result_Impl *implementation (void) const; + + protected: + /// Constructor. + Result (ACE_Asynch_Write_Stream_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// Implementation class. + ACE_Asynch_Write_Stream_Result_Impl *implementation_; + }; +}; + +// Forward declarations +class ACE_Asynch_Read_File_Impl; +class ACE_Asynch_Read_File_Result_Impl; + +/** + * @class ACE_Asynch_Read_File + * + * @brief This class is a factory for starting off asynchronous reads + * on a file. This class forwards all methods to its + * implementation class. + * + * Once open() is called, multiple asynchronous reads can + * started using this class. An ACE_Asynch_Read_File::Result + * will be passed back to the completion handler's + * ACE_Handler::handle_read_file() method when each asynchronous + * read completes. + * This class differs slightly from ACE_Asynch_Read_Stream as it + * allows the user to specify an offset for the read. + */ +class ACE_Export ACE_Asynch_Read_File : public ACE_Asynch_Read_Stream +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Read_File (void); + + /// Destructor. + virtual ~ACE_Asynch_Read_File (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous operation. + * + * @param handler ACE_Handler to be notified when operations initiated + * via this factory complete. The + * ACE_Handler::handle_read_file() method will be + * called on this object. + * @param handle The file handle to initiate read operations on. + * If handle is @c ACE_INVALID_HANDLE, + * ACE_Handler::handle() will be called on handler to + * get the handle value. + * @param completion_key A token that is passed to the completion handler. + * @param proactor The ACE_Proactor object which will control operation + * completion and dispatching the results to handler. + * If this is 0, the process's singleton ACE_Proactor + * will be used. + * + * @retval 0 for success. + * @retval -1 for failure; consult @c errno for further information. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * This starts off an asynchronous read. Upto {bytes_to_read} will + * be read and stored in the {message_block}. The read will start + * at {offset} from the beginning of the file. Priority of the + * operation is specified by {priority}. On POSIX4-Unix, this is + * supported. Works like {nice} in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, this argument is a no-op. + * {signal_number} is the POSIX4 real-time signal number to be used + * for the operation. {signal_number} ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + unsigned long offset = 0, + unsigned long offset_high = 0, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + * @note In win32 Each data block payload must be at least the size of a system + * memory page and must be aligned on a system memory page size boundary + */ + int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + unsigned long offset = 0, + unsigned long offset_high = 0, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Delegation/implementation class that all methods will be + /// forwarded to. + ACE_Asynch_Read_File_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * {handler} when the asynchronous read completes. This class + * forwards all the methods to the implementation class. + * + * This class has all the information necessary for the + * {handler} to uniquiely identify the completion of the + * asynchronous read. + * This class differs slightly from + * ACE_Asynch_Read_Stream::Result as it calls back + * {ACE_Handler::handle_read_file} on the {handler} instead of + * {ACE_Handler::handle_read_stream}. No additional state is + * required by this class as ACE_Asynch_Result can store the + * {offset}. + */ + class ACE_Export Result : public ACE_Asynch_Read_Stream::Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Read_File_Result; + friend class ACE_WIN32_Asynch_Read_File_Result; + + public: + /// Get the implementation class. + ACE_Asynch_Read_File_Result_Impl *implementation (void) const; + + protected: + /// Constructor. This implementation will not be deleted. + Result (ACE_Asynch_Read_File_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// The implementation class. + ACE_Asynch_Read_File_Result_Impl *implementation_; + + private: + /// Here just to provide an dummpy implementation, since the + /// one auto generated by MSVC is flagged as infinitely recursive + void operator= (Result &) {} + }; +}; + +// Forward declarations +class ACE_Asynch_Write_File_Impl; +class ACE_Asynch_Write_File_Result_Impl; + +/** + * @class ACE_Asynch_Write_File + * + * @brief This class is a factory for starting off asynchronous writes + * on a file. This class forwards all methods to its + * implementation class. + * + * Once {open} is called, multiple asynchronous {write}s can be + * started using this class. A ACE_Asynch_Write_File::Result + * will be passed back to the {handler} when the asynchronous + * writes completes through the {ACE_Handler::handle_write_file} + * callback. + * This class differs slightly from ACE_Asynch_Write_Stream as + * it allows the user to specify an offset for the write. + */ +class ACE_Export ACE_Asynch_Write_File : public ACE_Asynch_Write_Stream +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Write_File (void); + + /// Destructor. + virtual ~ACE_Asynch_Write_File (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ({handle} == ACE_INVALID_HANDLE), + * {ACE_Handler::handle} will be called on the {handler} to get the + * correct handle. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * This starts off an asynchronous write. Upto {bytes_to_write} + * will be written from the {message_block}, starting at the + * block's {rd_ptr}. The write will go to the file, starting + * {offset} bytes from the beginning of the file. Priority of the + * operation is specified by {priority}. On POSIX4-Unix, this is + * supported. Works like {nice} in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, this is a no-op. + * {signal_number} is the POSIX4 real-time signal number to be used + * for the operation. {signal_number} ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + unsigned long offset = 0, + unsigned long offset_high = 0, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + * @note In win32 Each data block payload must be at least the size of a system + * memory page and must be aligned on a system memory page size boundary + */ + int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + unsigned long offset = 0, + unsigned long offset_high = 0, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Implementation object. + ACE_Asynch_Write_File_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * {handler} when the asynchronous write completes. This class + * forwards all the methods to the implementation class. + * + * This class has all the information necessary for the + * {handler} to uniquiely identify the completion of the + * asynchronous write. + * This class differs slightly from + * ACE_Asynch_Write_Stream::Result as it calls back + * {ACE_Handler::handle_write_file} on the {handler} instead + * of {ACE_Handler::handle_write_stream}. No additional state + * is required by this class as ACE_Asynch_Result can store + * the {offset}. + */ + class ACE_Export Result : public ACE_Asynch_Write_Stream::Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Write_File_Result; + friend class ACE_WIN32_Asynch_Write_File_Result; + + public: + /// Get the implementation class. + ACE_Asynch_Write_File_Result_Impl *implementation (void) const; + + protected: + /// Constructor. This implementation will not be deleted. + Result (ACE_Asynch_Write_File_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// The implementation class. + ACE_Asynch_Write_File_Result_Impl *implementation_; + + private: + /// Here just to provide an dummpy implementation, since the + /// one auto generated by MSVC is flagged as infinitely recursive + void operator= (Result &) {}; + }; +}; + +// Forward declarations +class ACE_Asynch_Accept_Result_Impl; +class ACE_Asynch_Accept_Impl; + +/** + * @class ACE_Asynch_Accept + * + * @brief This class is a factory for starting off asynchronous accepts + * on a listen handle. This class forwards all methods to its + * implementation class. + * + * Once {open} is called, multiple asynchronous {accept}s can + * started using this class. A ACE_Asynch_Accept::Result will + * be passed back to the {handler} when the asynchronous accept + * completes through the {ACE_Handler::handle_accept} + * callback. + */ +class ACE_Export ACE_Asynch_Accept : public ACE_Asynch_Operation +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Accept (void); + + /// Destructor. + virtual ~ACE_Asynch_Accept (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ({handle} == ACE_INVALID_HANDLE), + * {ACE_Handler::handle} will be called on the {handler} to get the + * correct handle. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * This starts off an asynchronous accept. The asynchronous accept + * call also allows any initial data to be returned to the + * handler specified to @c open(). + * @param message_block A message block to receive initial data, as well + * as the local and remote addresses when the + * connection is made. Since the block receives + * the addresses regardless of whether or not + * initial data is available or requested, the + * message block size must be at least + * @a bytes_to_read plus two times the size of + * the addresses used (IPv4 or IPv6). + * @param bytes_to_read The maximum number of bytes of initial data + * to read into @a message_block. + * @param accept_handle The handle that the new connection will be + * accepted on. If @c INVALID_HANDLE, a new + * handle will be created using @a addr_family. + * @param act Value to be passed in result when operation + * completes. + * @param priority Priority of the operation. On POSIX4-Unix, this + * is supported. Works like @c nice in Unix. + * Negative values are not allowed. 0 means + * priority of the operation same as the process + * priority. 1 means priority of the operation is + * one less than process. And so forth. + * On Win32, this argument is ignored. + * @param signal_number The POSIX4 real-time signal number to be used + * for the operation. Value range is from + * @c ACE_SIGRTMIN to @c ACE_SIGRTMAX. + * This argument is ignored on non-POSIX4 systems. + * @param addr_family The address family to use if @a accept_handle + * is @c ACE_INVALID_HANDLE and a new handle must + * be opened. Values are @c AF_INET and @c PF_INET6. + */ + int accept (ACE_Message_Block &message_block, + size_t bytes_to_read, + ACE_HANDLE accept_handle = ACE_INVALID_HANDLE, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN, + int addr_family = AF_INET); + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Delegation/implementation class that all methods will be + /// forwarded to. + ACE_Asynch_Accept_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * {handler} when the asynchronous accept completes. + * + * This class has all the information necessary for the + * {handler} to uniquiely identify the completion of the + * asynchronous accept. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Accept_Result; + friend class ACE_WIN32_Asynch_Accept_Result; + + public: + /// The number of bytes which were requested at the start of the + /// asynchronous accept. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for accepting new connections. + ACE_HANDLE listen_handle (void) const; + + /// I/O handle for the new connection. + ACE_HANDLE accept_handle (void) const; + + /// Get the implementation. + ACE_Asynch_Accept_Result_Impl *implementation (void) const; + + protected: + /// Contructor. Implementation will not be deleted. + Result (ACE_Asynch_Accept_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// Impelmentation class. + ACE_Asynch_Accept_Result_Impl *implementation_; + }; +}; +// Forward declarations +class ACE_Asynch_Connect_Result_Impl; +class ACE_Asynch_Connect_Impl; + +/** + * @class ACE_Asynch_Connect + * + * @brief This class is a factory for starting off asynchronous connects + * This class forwards all methods to its implementation class. + * + * Once @c open is called, multiple asynchronous connect operationss can + * started using this class. A ACE_Asynch_Connect::Result will + * be passed back to the associated ACE_Handler when the asynchronous connect + * completes through the ACE_Handler::handle_connect() callback. + */ +class ACE_Export ACE_Asynch_Connect : public ACE_Asynch_Operation +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Connect (void); + + /// Destructor. + virtual ~ACE_Asynch_Connect (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. + * + * @note @arg handle is ignored and should be @c ACE_INVALID_HANDLE. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * This starts off an asynchronous Connect. + */ + int connect (ACE_HANDLE connect_handle, + const ACE_Addr & remote_sap, + const ACE_Addr & local_sap, + int reuse_addr, + const void *act=0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Delegation/implementation class that all methods will be + /// forwarded to. + ACE_Asynch_Connect_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * handler when the asynchronous connect completes. + * + * This class has all the information necessary for the + * handler to uniquely identify the completion of the + * asynchronous connect. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Connect_Result; + friend class ACE_WIN32_Asynch_Connect_Result; + + public: + + /// I/O handle for the connection. + ACE_HANDLE connect_handle (void) const; + + /// Get the implementation. + ACE_Asynch_Connect_Result_Impl *implementation (void) const; + + protected: + /// Contructor. Implementation will not be deleted. + Result (ACE_Asynch_Connect_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// Impelmentation class. + ACE_Asynch_Connect_Result_Impl *implementation_; + }; +}; + +// Forward declarations +class ACE_Asynch_Transmit_File_Result_Impl; +class ACE_Asynch_Transmit_File_Impl; + +/** + * @class ACE_Asynch_Transmit_File + * + * @brief This class is a factory for starting off asynchronous + * transmit files on a stream. + * + * Once {open} is called, multiple asynchronous {transmit_file}s + * can started using this class. A + * ACE_Asynch_Transmit_File::Result will be passed back to the + * {handler} when the asynchronous transmit file completes + * through the {ACE_Handler::handle_transmit_file} callback. + * The transmit_file function transmits file data over a + * connected network connection. The function uses the operating + * system's cache manager to retrieve the file data. This + * function provides high-performance file data transfer over + * network connections. This function would be of great use in + * a Web Server, Image Server, etc. + */ +class ACE_Export ACE_Asynch_Transmit_File : public ACE_Asynch_Operation +{ + +public: + // Forward declarations + class Header_And_Trailer; + + /// A do nothing constructor. + ACE_Asynch_Transmit_File (void); + + /// Destructor. + virtual ~ACE_Asynch_Transmit_File (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ({handle} == ACE_INVALID_HANDLE), + * {ACE_Handler::handle} will be called on the {handler} to get the + * correct handle. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** + * This starts off an asynchronous transmit file. The {file} is a + * handle to an open file. {header_and_trailer} is a pointer to a + * data structure that contains pointers to data to send before and + * after the file data is sent. Set this parameter to 0 if you only + * want to transmit the file data. Upto {bytes_to_write} will be + * written to the {socket}. If you want to send the entire file, + * let {bytes_to_write} = 0. {bytes_per_send} is the size of each + * block of data sent per send operation. Please read the Win32 + * documentation on what the flags should be. Priority of the + * operation is specified by {priority}. On POSIX4-Unix, this is + * supported. Works like {nice} in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, this is a no-op. + * {signal_number} is the POSIX4 real-time signal number to be used + * for the operation. {signal_number} ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + int transmit_file (ACE_HANDLE file, + Header_And_Trailer *header_and_trailer = 0, + size_t bytes_to_write = 0, + unsigned long offset = 0, + unsigned long offset_high = 0, + size_t bytes_per_send = 0, + unsigned long flags = 0, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// The implementation class. + ACE_Asynch_Transmit_File_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * {handler} when the asynchronous transmit file completes. + * + * This class has all the information necessary for the + * {handler} to uniquiely identify the completion of the + * asynchronous transmit file. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Transmit_File_Result; + friend class ACE_WIN32_Asynch_Transmit_File_Result; + + public: + /// Socket used for transmitting the file. + ACE_HANDLE socket (void) const; + + /// File from which the data is read. + ACE_HANDLE file (void) const; + + /// Header and trailer data associated with this transmit file. + Header_And_Trailer *header_and_trailer (void) const; + + /// The number of bytes which were requested at the start of the + /// asynchronous transmit file. + size_t bytes_to_write (void) const; + + /// Number of bytes per send requested at the start of the transmit + /// file. + size_t bytes_per_send (void) const; + + /// Flags which were passed into transmit file. + unsigned long flags (void) const; + + /// Get the implementation class. + ACE_Asynch_Transmit_File_Result_Impl *implementation (void) const; + + protected: + /// Constructor. + Result (ACE_Asynch_Transmit_File_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// The implementation class. + ACE_Asynch_Transmit_File_Result_Impl *implementation_; + }; + +/** + * @class Header_And_Trailer + * + * @brief The class defines a data structure that contains pointers + * to data to send before and after the file data is sent. + * + * This class provides a wrapper over TRANSMIT_FILE_BUFFERS + * and provided a consistent use of ACE_Message_Blocks. + */ + class ACE_Export Header_And_Trailer + { + + public: + /// Constructor. + Header_And_Trailer (ACE_Message_Block *header = 0, + size_t header_bytes = 0, + ACE_Message_Block *trailer = 0, + size_t trailer_bytes = 0); + + /// Destructor + virtual ~Header_And_Trailer (void); + + /// This method allows all the member to be set in one fell swoop. + void header_and_trailer (ACE_Message_Block *header = 0, + size_t header_bytes = 0, + ACE_Message_Block *trailer = 0, + size_t trailer_bytes = 0); + + /// Get header which goes before the file data. + ACE_Message_Block *header (void) const; + + /// Set header which goes before the file data. + void header (ACE_Message_Block *message_block); + + /// Get size of the header data. + size_t header_bytes (void) const; + + /// Set size of the header data. + void header_bytes (size_t bytes); + + /// Get trailer which goes after the file data. + ACE_Message_Block *trailer (void) const; + + /// Set trailer which goes after the file data. + void trailer (ACE_Message_Block *message_block); + + /// Get size of the trailer data. + size_t trailer_bytes (void) const; + + /// Set size of the trailer data. + void trailer_bytes (size_t bytes); + + /// Conversion routine. + ACE_LPTRANSMIT_FILE_BUFFERS transmit_buffers (void); + + protected: + /// Header data. + ACE_Message_Block *header_; + + /// Size of header data. + size_t header_bytes_; + + /// Trailer data. + ACE_Message_Block *trailer_; + + /// Size of trailer data. + size_t trailer_bytes_; + + /// Target data structure. + ACE_TRANSMIT_FILE_BUFFERS transmit_buffers_; + }; +}; + + +// Forward declarations +class ACE_Asynch_Read_Dgram_Result_Impl; +class ACE_Asynch_Read_Dgram_Impl; +class ACE_Addr; + +/** + * @class ACE_Asynch_Read_Dgram + * + * @brief This class is a factory for starting off asynchronous reads + * on a UDP socket. This class forwards all methods to its + * implementation class. + * + * Once {open} is called, multiple asynchronous {read}s can be + * started using this class. An ACE_Asynch_Read_Dgram::Result + * will be passed back to the {handler} when the asynchronous + * reads completes through the {ACE_Handler::handle_read_dgram} + * callback. + */ +class ACE_Export ACE_Asynch_Read_Dgram : public ACE_Asynch_Operation +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Read_Dgram (void); + + /// Destructor + virtual ~ACE_Asynch_Read_Dgram (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ({handle} == ACE_INVALID_HANDLE), + * {ACE_Handler::handle} will be called on the {handler} to get the + * correct handle. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** This starts off an asynchronous read. Upto + * {message_block->total_size()} will be read and stored in the + * {message_block}. {message_block}'s {wr_ptr} will be updated to reflect + * the added bytes if the read operation is successfully completed. + * Return code of 1 means immediate success and {number_of_bytes_recvd} + * will contain number of bytes read. The {ACE_Handler::handle_read_dgram} + * method will still be called. Return code of 0 means the IO will + * complete proactively. Return code of -1 means there was an error, use + * errno to get the error code. + * + * Scatter/gather is supported on WIN32 by using the {message_block->cont()} + * method. Up to ACE_IOV_MAX {message_block}'s are supported. Upto + * {message_block->size()} bytes will be read into each {message block} for + * a total of {message_block->total_size()} bytes. All {message_block}'s + * {wr_ptr}'s will be updated to reflect the added bytes for each + * {message_block} + * + * Priority of the operation is specified by {priority}. On POSIX4-Unix, + * this is supported. Works like {nice} in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, {priority} is a no-op. + * {signal_number} is the POSIX4 real-time signal number to be used + * for the operation. {signal_number} ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + ssize_t recv (ACE_Message_Block *message_block, + size_t &number_of_bytes_recvd, + int flags, + int protocol_family = PF_INET, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Implementation class that all methods will be forwarded to. + ACE_Asynch_Read_Dgram_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is the class which will be passed back to the + * {handler} when the asynchronous read completes. This class + * forwards all the methods to the implementation classes. + * + * This class has all the information necessary for the + * {handler} to uniquiely identify the completion of the + * asynchronous read. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Read_Dgram_Result; + friend class ACE_WIN32_Asynch_Read_Dgram_Result; + + public: + + /// The number of bytes which were requested at the start of the + /// asynchronous read. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data + ACE_Message_Block *message_block (void) const; + + /// The flags used in the read + int flags (void) const; + + /// The address of where the packet came from + int remote_address (ACE_Addr& addr) const; + + /// I/O handle used for reading. + ACE_HANDLE handle (void) const; + + /// Get the implementation class. + ACE_Asynch_Read_Dgram_Result_Impl *implementation (void) const; + + protected: + /// Constructor. + Result (ACE_Asynch_Read_Dgram_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// The implementation class. + ACE_Asynch_Read_Dgram_Result_Impl *implementation_; + }; +}; + +// Forward declarations +class ACE_Asynch_Write_Dgram_Impl; +class ACE_Asynch_Write_Dgram_Result_Impl; + +/** + * @class ACE_Asynch_Write_Dgram + * + * @brief This class is a factory for starting off asynchronous writes + * on a UDP socket. This class forwards all methods to its + * implementation class. + * + * Once {open} is called, multiple asynchronous {writes}s can + * started using this class. An ACE_Asynch_Write_Dgram::Result + * will be passed back to the {handler} when the asynchronous + * write completes through the + * {ACE_Handler::handle_write_dgram} callback. + */ +class ACE_Export ACE_Asynch_Write_Dgram : public ACE_Asynch_Operation +{ + +public: + /// A do nothing constructor. + ACE_Asynch_Write_Dgram (void); + + /// Destructor. + virtual ~ACE_Asynch_Write_Dgram (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ({handle} == ACE_INVALID_HANDLE), + * {ACE_Handler::handle} will be called on the {handler} to get the + * correct handle. + */ + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + /** This starts off an asynchronous send. Upto + * {message_block->total_length()} will be sent. {message_block}'s + * {rd_ptr} will be updated to reflect the sent bytes if the send operation + * is successfully completed. + * Return code of 1 means immediate success and {number_of_bytes_sent} + * is updated to number of bytes sent. The {ACE_Handler::handle_write_dgram} + * method will still be called. Return code of 0 means the IO will + * complete proactively. Return code of -1 means there was an error, use + * errno to get the error code. + * + * Scatter/gather is supported on WIN32 by using the {message_block->cont()} + * method. Up to ACE_IOV_MAX {message_block}'s are supported. Upto + * {message_block->length()} bytes will be sent from each {message block} + * for a total of {message_block->total_length()} bytes. All + * {message_block}'s {rd_ptr}'s will be updated to reflect the bytes sent + * from each {message_block}. + * + * Priority of the operation is specified by {priority}. On POSIX4-Unix, + * this is supported. Works like {nice} in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, this argument is a no-op. + * {signal_number} is the POSIX4 real-time signal number to be used + * for the operation. {signal_number} ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + ssize_t send (ACE_Message_Block *message_block, + size_t &number_of_bytes_sent, + int flags, + const ACE_Addr& remote_addr, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + + /// Return the underlying implementation class. + // (this should be protected...) + virtual ACE_Asynch_Operation_Impl *implementation (void) const; + +protected: + /// Implementation class that all methods will be forwarded to. + ACE_Asynch_Write_Dgram_Impl *implementation_; + +public: +/** + * @class Result + * + * @brief This is that class which will be passed back to the + * {handler} when the asynchronous write completes. This class + * forwards all the methods to the implementation class. + * + * This class has all the information necessary for the + * {handler} to uniquiely identify the completion of the + * asynchronous write. + */ + class ACE_Export Result : public ACE_Asynch_Result + { + + /// The concrete implementation result classes only construct this + /// class. + friend class ACE_POSIX_Asynch_Write_Dgram_Result; + friend class ACE_WIN32_Asynch_Write_Dgram_Result; + + public: + + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write (void) const; + + /// Message block which contains the sent data + ACE_Message_Block *message_block (void) const; + + /// The flags using in the write + int flags (void) const; + + /// I/O handle used for writing. + ACE_HANDLE handle (void) const; + + /// Get the implementation class. + ACE_Asynch_Write_Dgram_Result_Impl *implementation (void) const; + + protected: + /// Constructor. + Result (ACE_Asynch_Write_Dgram_Result_Impl *implementation); + + /// Destructor. + virtual ~Result (void); + + /// Implementation class. + ACE_Asynch_Write_Dgram_Result_Impl *implementation_; + }; +}; + + +/** + * @class ACE_Handler + * + * @brief This base class defines the interface for receiving the + * results of asynchronous operations. + * + * Subclasses of this class will fill in appropriate methods. + */ +class ACE_Export ACE_Handler +{ +public: + /// A do nothing constructor. + ACE_Handler (void); + + /// A do nothing constructor which allows proactor to be set to \. + ACE_Handler (ACE_Proactor *p); + + /// Virtual destruction. + virtual ~ACE_Handler (void); + + /// This method will be called when an asynchronous read completes on + /// a stream. + virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result); + + /// This method will be called when an asynchronous write completes + /// on a UDP socket. + virtual void handle_write_dgram (const ACE_Asynch_Write_Dgram::Result &result); + + /// This method will be called when an asynchronous read completes on + /// a UDP socket. + virtual void handle_read_dgram (const ACE_Asynch_Read_Dgram::Result &result); + + /// This method will be called when an asynchronous write completes + /// on a stream. + virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result); + + /// This method will be called when an asynchronous read completes on + /// a file. + virtual void handle_read_file (const ACE_Asynch_Read_File::Result &result); + + /// This method will be called when an asynchronous write completes + /// on a file. + virtual void handle_write_file (const ACE_Asynch_Write_File::Result &result); + + /// This method will be called when an asynchronous accept completes. + virtual void handle_accept (const ACE_Asynch_Accept::Result &result); + + /// This method will be called when an asynchronous connect completes. + virtual void handle_connect (const ACE_Asynch_Connect::Result &result); + + /// This method will be called when an asynchronous transmit file + /// completes. + virtual void handle_transmit_file (const ACE_Asynch_Transmit_File::Result &result); + + /// Called when timer expires. {tv} was the requested time value and + /// {act} is the ACT passed when scheduling the timer. + virtual void handle_time_out (const ACE_Time_Value &tv, + const void *act = 0); + + /** + * This is method works with the {run_event_loop} of the + * ACE_Proactor. A special {Wake_Up_Completion} is used to wake up + * all the threads that are blocking for completions. + */ + virtual void handle_wakeup (void); + + /// Get the proactor associated with this handler. + ACE_Proactor *proactor (void); + + /// Set the proactor. + void proactor (ACE_Proactor *p); + + /** + * Get the I/O handle used by this {handler}. This method will be + * called by the ACE_Asynch_* classes when an ACE_INVALID_HANDLE is + * passed to {open}. + */ + virtual ACE_HANDLE handle (void) const; + + /// Set the ACE_HANDLE value for this Handler. + virtual void handle (ACE_HANDLE); + + /** + * @class Proxy + * + * @brief The Proxy class acts as a proxy for dispatch of completions + * to operations issued for the associated handler. It allows the handler + * to be deleted while operations are outstanding. The proxy must be used + * to get the ACE_Handler pointer for dispatching, and if it's 0, the + * handler is no longer valid and the result should not be dispatched. + */ + class ACE_Export Proxy + { + public: + Proxy (ACE_Handler *handler) : handler_ (handler) {}; + void reset (void) { this->handler_ = 0; }; + ACE_Handler *handler (void) { return this->handler_; }; + private: + ACE_Handler *handler_; + }; + typedef ACE_Refcounted_Auto_Ptr + Proxy_Ptr; + + Proxy_Ptr &proxy (void); + +protected: + /// The proactor associated with this handler. + ACE_Proactor *proactor_; + + /// The ACE_HANDLE in use with this handler. + ACE_HANDLE handle_; + + /// Refers to proxy for this handler. + ACE_Refcounted_Auto_Ptr proxy_; + + ACE_UNIMPLEMENTED_FUNC (ACE_Handler (const ACE_Handler &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Handler operator= (const ACE_Handler &)) +}; + +// Forward declarations +class ACE_INET_Addr; + +// Forward declarations +template +class ACE_Asynch_Acceptor; + +/** + * @class ACE_Service_Handler + * + * @brief This base class defines the interface for the + * ACE_Asynch_Acceptor to call into when new connection are + * accepted. + * + * Subclasses of this class will fill in appropriate methods to + * define application specific behavior. + */ +class ACE_Export ACE_Service_Handler : public ACE_Handler +{ + + /// The Acceptor is the factory and therefore should have special + /// privileges. + friend class ACE_Asynch_Acceptor; + +public: + /// A do nothing constructor. + ACE_Service_Handler (void); + + /// Virtual destruction. + virtual ~ACE_Service_Handler (void); + + /** + * {open} is called by ACE_Asynch_Acceptor to initialize a new + * instance of ACE_Service_Handler that has been created after the + * new connection is accepted. The handle for the new connection is + * passed along with the initial data that may have shown up. + */ + virtual void open (ACE_HANDLE new_handle, + ACE_Message_Block &message_block); + + // protected: + // This should be corrected after the correct semantics of the + // friend has been figured out. + + /// Called by ACE_Asynch_Acceptor to pass the addresses of the new + /// connections. + virtual void addresses (const ACE_INET_Addr &remote_address, + const ACE_INET_Addr &local_address); + + /// Called by ACE_Asynch_Acceptor to pass the act. + virtual void act (const void *); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS*/ +#include /**/ "ace/post.h" +#endif /* ACE_ASYNCH_IO_H */ diff --git a/dep/ACE_wrappers/ace/Asynch_IO_Impl.cpp b/dep/ACE_wrappers/ace/Asynch_IO_Impl.cpp new file mode 100644 index 000000000..b4b47eda5 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_IO_Impl.cpp @@ -0,0 +1,117 @@ +// $Id: Asynch_IO_Impl.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Asynch_IO_Impl.h" + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) +// This only works on Win32 platforms and on Unix platforms supporting +// aio calls. + +#if !defined (__ACE_INLINE__) +#include "ace/Asynch_IO_Impl.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Asynch_Result_Impl::~ACE_Asynch_Result_Impl (void) +{ +} + +ACE_Asynch_Operation_Impl::~ACE_Asynch_Operation_Impl (void) +{ +} + +ACE_Asynch_Read_Stream_Impl::~ACE_Asynch_Read_Stream_Impl (void) +{ +} + +ACE_Asynch_Read_Stream_Result_Impl::~ACE_Asynch_Read_Stream_Result_Impl (void) +{ +} + +ACE_Asynch_Write_Stream_Impl::~ACE_Asynch_Write_Stream_Impl (void) +{ +} + +ACE_Asynch_Write_Stream_Result_Impl::~ACE_Asynch_Write_Stream_Result_Impl (void) +{ +} + +ACE_Asynch_Read_File_Impl::~ACE_Asynch_Read_File_Impl (void) +{ +} + +ACE_Asynch_Write_File_Impl::~ACE_Asynch_Write_File_Impl (void) +{ +} + +ACE_Asynch_Read_File_Result_Impl::~ACE_Asynch_Read_File_Result_Impl (void) +{ +} + +ACE_Asynch_Write_File_Result_Impl::~ACE_Asynch_Write_File_Result_Impl (void) +{ +} + +ACE_Asynch_Accept_Result_Impl::~ACE_Asynch_Accept_Result_Impl (void) +{ +} + +ACE_Asynch_Connect_Result_Impl::~ACE_Asynch_Connect_Result_Impl (void) +{ +} + +ACE_Asynch_Accept_Impl::~ACE_Asynch_Accept_Impl (void) +{ +} + +ACE_Asynch_Connect_Impl::~ACE_Asynch_Connect_Impl (void) +{ +} + +ACE_Asynch_Transmit_File_Impl::~ACE_Asynch_Transmit_File_Impl (void) +{ +} + +ACE_Asynch_Transmit_File_Result_Impl::~ACE_Asynch_Transmit_File_Result_Impl (void) +{ +} + +ACE_Asynch_Read_Dgram_Impl::~ACE_Asynch_Read_Dgram_Impl (void) +{ +} + +ACE_Asynch_Read_Dgram_Impl::ACE_Asynch_Read_Dgram_Impl (void) +{ +} + +ACE_Asynch_Write_Dgram_Impl::~ACE_Asynch_Write_Dgram_Impl (void) +{ +} + +ACE_Asynch_Write_Dgram_Impl::ACE_Asynch_Write_Dgram_Impl (void) +{ +} + +//*********************************************** + +ACE_Asynch_Read_Dgram_Result_Impl::~ACE_Asynch_Read_Dgram_Result_Impl (void) +{ +} + +ACE_Asynch_Read_Dgram_Result_Impl::ACE_Asynch_Read_Dgram_Result_Impl (void) +{ +} + +//*********************************************** + +ACE_Asynch_Write_Dgram_Result_Impl::~ACE_Asynch_Write_Dgram_Result_Impl (void) +{ +} + +ACE_Asynch_Write_Dgram_Result_Impl::ACE_Asynch_Write_Dgram_Result_Impl (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */ diff --git a/dep/ACE_wrappers/ace/Asynch_IO_Impl.h b/dep/ACE_wrappers/ace/Asynch_IO_Impl.h new file mode 100644 index 000000000..06eb5c10a --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_IO_Impl.h @@ -0,0 +1,816 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Asynch_IO_Impl.h + * + * $Id: Asynch_IO_Impl.h 80826 2008-03-04 14:51:23Z wotte $ + * + * + * This class contains asbtract base classes for all the concrete + * implementation classes for the various asynchronous operations + * that are used with the Praoctor. + * + * + * @author Irfan Pyarali (irfan@cs.wustl.edu) + * @author Tim Harrison (harrison@cs.wustl.edu) + * @author Alexander Babu Arulanthu + * @author Roger Tragin + * @author Alexander Libman + */ +//============================================================================= + +#ifndef ACE_ASYNCH_IO_IMPL_H +#define ACE_ASYNCH_IO_IMPL_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) +// This only works on Win32 platforms and on Unix platforms supporting +// aio calls. + +#include "ace/Asynch_IO.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration. +class ACE_Proactor_Impl; + +/** + * @class ACE_Asynch_Result_Impl + * + * @brief Abstract base class for the all the classes that provide + * concrete implementations for ACE_Asynch_Result. + * + */ +class ACE_Export ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Result_Impl (void); + + /// Number of bytes transferred by the operation. + virtual size_t bytes_transferred (void) const = 0; + + /// ACT associated with the operation. + virtual const void *act (void) const = 0; + + /// Did the operation succeed? + virtual int success (void) const = 0; + + /// This ACT is not the same as the ACT associated with the + /// asynchronous operation. + virtual const void *completion_key (void) const = 0; + + /// Error value if the operation fail. + virtual u_long error (void) const = 0; + + /// Event associated with the OVERLAPPED structure. + virtual ACE_HANDLE event (void) const = 0; + + /// This really make sense only when doing file I/O. + virtual u_long offset (void) const = 0; + virtual u_long offset_high (void) const = 0; + + /// Priority of the operation. + virtual int priority (void) const = 0; + + /** + * POSIX4 real-time signal number to be used for the + * operation. ranges from SIGRTMIN to SIGRTMAX. By + * default, SIGRTMIN is used to issue calls. This is a no-op + * on non-POSIX4 systems and returns 0. + */ + virtual int signal_number (void) const = 0; + + // protected: + // + // These two should really be protected. But sometimes it + // simplifies code to be able to "fake" a result. Use carefully. + /// This is called when the asynchronous operation completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error = 0) = 0; + + /// Post @c this to the Proactor's completion port. + virtual int post_completion (ACE_Proactor_Impl *proactor) = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Result_Impl (void); +}; + +/** + * @class ACE_Asynch_Operation_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Operation. + */ +class ACE_Export ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Operation_Impl (void); + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If @a handle == ACE_INVALID_HANDLE, + * ACE_Handler::handle() will be called on the proxied handler to get the + * correct handle. + */ + virtual int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) = 0; + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + virtual int cancel (void) = 0; + + // = Access methods. + + /// Return the underlying proactor. + virtual ACE_Proactor* proactor (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Operation_Impl (void); +}; + +/** + * @class ACE_Asynch_Read_Stream_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Read_Stream + * + */ +class ACE_Export ACE_Asynch_Read_Stream_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Read_Stream_Impl (void); + + /// This starts off an asynchronous read. Upto @a bytes_to_read will + /// be read and stored in the @a message_block. + virtual int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) = 0; + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + */ + virtual int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) = 0; +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + +protected: + /// Do-nothing constructor. + ACE_Asynch_Read_Stream_Impl (void); +}; + +/** + * @class ACE_Asynch_Read_Stream_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Read_Stream::Result class. + * + */ +class ACE_Export ACE_Asynch_Read_Stream_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Read_Stream_Result_Impl (void); + + /// The number of bytes which were requested at the start of the + /// asynchronous read. + virtual size_t bytes_to_read (void) const = 0; + + /// Message block which contains the read data. + virtual ACE_Message_Block &message_block (void) const = 0; + + /// I/O handle used for reading. + virtual ACE_HANDLE handle (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Read_Stream_Result_Impl (void); +}; + +/** + * @class ACE_Asynch_Write_Stream_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Write_Stream class. + * + */ +class ACE_Export ACE_Asynch_Write_Stream_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Write_Stream_Impl (void); + + /// This starts off an asynchronous write. Upto @a bytes_to_write + /// will be written from the @a message_block. + virtual int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) = 0; + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + */ + virtual int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) = 0; +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + +protected: + /// Do-nothing constructor. + ACE_Asynch_Write_Stream_Impl (void); +}; + +/** + * @class ACE_Asynch_Write_Stream_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Write_Stream::Result. + * + */ +class ACE_Export ACE_Asynch_Write_Stream_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Write_Stream_Result_Impl (void); + + /// The number of bytes which were requested at the start of the + /// asynchronous write. + virtual size_t bytes_to_write (void) const = 0; + + /// Message block that contains the data to be written. + virtual ACE_Message_Block &message_block (void) const = 0; + + /// I/O handle used for writing. + virtual ACE_HANDLE handle (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Write_Stream_Result_Impl (void); +}; + +/** + * @class ACE_Asynch_Read_File_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Read_File::Result. + * + */ +class ACE_Export ACE_Asynch_Read_File_Impl : public virtual ACE_Asynch_Read_Stream_Impl +{ +public: + virtual ~ACE_Asynch_Read_File_Impl (void); + + /** + * This starts off an asynchronous read. Upto @a bytes_to_read will + * be read and stored in the @a message_block. The read will start + * at @a offset from the beginning of the file. + */ + virtual int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) = 0; + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + * @note In win32 Each data block payload must be at least the size of a system + * memory page and must be aligned on a system memory page size boundary + */ + virtual int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) = 0; +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + + /// This starts off an asynchronous read. Upto @a bytes_to_read will + /// be read and stored in the @a message_block. + virtual int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) = 0; + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + */ + virtual int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) = 0; +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + +protected: + /// Do-nothing constructor. + ACE_Asynch_Read_File_Impl (void); +}; + +/** + * @class ACE_Asynch_Read_File_Result_Impl + * + * @brief This is the abstract base class for all the concrete + * implementation classes for ACE_Asynch_Read_File::Result. + * + */ +class ACE_Export ACE_Asynch_Read_File_Result_Impl : public virtual ACE_Asynch_Read_Stream_Result_Impl +{ +public: + /// Destructor. + virtual ~ACE_Asynch_Read_File_Result_Impl (void); + +protected: + /// Do-nothing constructor. + ACE_Asynch_Read_File_Result_Impl (void); +}; + +/** + * @class ACE_Asynch_Write_File_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Write_File. + * + */ +class ACE_Export ACE_Asynch_Write_File_Impl : public virtual ACE_Asynch_Write_Stream_Impl +{ +public: + virtual ~ACE_Asynch_Write_File_Impl (void); + + /** + * This starts off an asynchronous write. Upto @a bytes_to_write + * will be write and stored in the @a message_block. The write will + * start at @a offset from the beginning of the file. + */ + virtual int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) = 0; + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + * @note In win32 Each data block payload must be at least the size of a system + * memory page and must be aligned on a system memory page size boundary + */ + virtual int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) = 0; +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + + /// This starts off an asynchronous write. Upto @a bytes_to_write + /// will be written from the @a message_block. + virtual int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) = 0; + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + */ + virtual int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) = 0; +#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */ + +protected: + /// Do-nothing constructor. + ACE_Asynch_Write_File_Impl (void); +}; + +/** + * @class ACE_Asynch_Write_File_Result_Impl + * + * @brief This is the abstract base class for all the concrete + * implementation classes that provide different implementations + * for the ACE_Asynch_Write_File::Result. + * + */ +class ACE_Export ACE_Asynch_Write_File_Result_Impl : public virtual ACE_Asynch_Write_Stream_Result_Impl +{ +public: + virtual ~ACE_Asynch_Write_File_Result_Impl (void); + +protected: + /// Do-nothing constructor. + ACE_Asynch_Write_File_Result_Impl (void); +}; + +/** + * @class ACE_Asynch_Accept_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Accept. + * + */ +class ACE_Export ACE_Asynch_Accept_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Accept_Impl (void); + + /** + * This starts off an asynchronous accept. The asynchronous accept + * call also allows any initial data to be returned to the + * . Upto @a bytes_to_read will be read and stored in the + * @a message_block. The @a accept_handle will be used for the + * call. If (@a accept_handle == INVALID_HANDLE), a new + * handle will be created. + * + * @a message_block must be specified. This is because the address of + * the new connection is placed at the end of this buffer. + */ + virtual int accept (ACE_Message_Block &message_block, + size_t bytes_to_read, + ACE_HANDLE accept_handle, + const void *act, + int priority, + int signal_number, + int addr_family) = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Accept_Impl (void); +}; + +/** + * @class ACE_Asynch_Accept_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Accept. + * + */ +class ACE_Export ACE_Asynch_Accept_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Accept_Result_Impl (void); + + /// The number of bytes which were requested at the start of the + /// asynchronous accept. + virtual size_t bytes_to_read (void) const = 0; + + /// Message block which contains the read data. + virtual ACE_Message_Block &message_block (void) const = 0; + + /// I/O handle used for accepting new connections. + virtual ACE_HANDLE listen_handle (void) const = 0; + + /// I/O handle for the new connection. + virtual ACE_HANDLE accept_handle (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Accept_Result_Impl (void); +}; + + +/** + * @class ACE_Asynch_Connect_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Connect. + * + */ +class ACE_Export ACE_Asynch_Connect_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Connect_Impl (void); + + /** + * This starts off an asynchronous connect + */ + virtual int connect (ACE_HANDLE connect_handle, + const ACE_Addr & remote_sap, + const ACE_Addr & local_sap, + int reuse_addr, + const void *act, + int priority, + int signal_number) = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Connect_Impl (void); +}; + +/** + * @class ACE_Asynch_Connect_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Connect. + * + */ +class ACE_Export ACE_Asynch_Connect_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Connect_Result_Impl (void); + + /// I/O handle for the connection. + virtual ACE_HANDLE connect_handle (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Connect_Result_Impl (void); +}; + + +/** + * @class ACE_Asynch_Transmit_File_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Transmit_File. + * + */ +class ACE_Asynch_Transmit_File_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Transmit_File_Impl (void); + + /// This starts off an asynchronous transmit file. + virtual int transmit_file (ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + int priority, + int signal_number) = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Transmit_File_Impl (void); +}; + +/** + * @class ACE_Asynch_Transmit_File_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Transmit_File::Result. + * + */ +class ACE_Export ACE_Asynch_Transmit_File_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Transmit_File_Result_Impl (void); + + /// Socket used for transmitting the file. + virtual ACE_HANDLE socket (void) const = 0; + + /// File from which the data is read. + virtual ACE_HANDLE file (void) const = 0; + + /// Header and trailer data associated with this transmit file. + virtual ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer (void) const = 0; + + /// The number of bytes which were requested at the start of the + /// asynchronous transmit file. + virtual size_t bytes_to_write (void) const = 0; + + /// Number of bytes per send requested at the start of the transmit + /// file. + virtual size_t bytes_per_send (void) const = 0; + + /// Flags which were passed into transmit file. + virtual u_long flags (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Transmit_File_Result_Impl (void); +}; + + +/** + * @class ACE_Asynch_Read_Dgram_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Read_Dgram + * + */ +class ACE_Export ACE_Asynch_Read_Dgram_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Read_Dgram_Impl (void); + + /** This starts off an asynchronous read. Upto + * total_size()> will be read and stored in the + * @a message_block. @a message_block's will be updated to reflect + * the added bytes if the read operation is successful completed. + * Return code of 1 means immediate success and + * will contain number of bytes read. The + * method will still be called. Return code of 0 means the IO will + * complete proactively. Return code of -1 means there was an error, use + * errno to get the error code. + * + * Scatter/gather is supported on WIN32 by using the cont()> + * method. Up to ACE_IOV_MAX @a message_block's are supported. Upto + * size()> bytes will be read into each for + * a total of total_size()> bytes. All @a message_block's + * 's will be updated to reflect the added bytes for each + * @a message_block + * + * Priority of the operation is specified by @a priority. On POSIX4-Unix, + * this is supported. Works like in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, @a priority is a no-op. + * @a signal_number is the POSIX4 real-time signal number to be used + * for the operation. @a signal_number ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + virtual ssize_t recv (ACE_Message_Block *message_block, + size_t &number_of_bytes_recvd, + int flags, + int protocol_family, + const void *act, + int priority, + int signal_number) = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Read_Dgram_Impl (void); +}; + +/** + * @class ACE_Asynch_Read_Dgram_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Read_Dgram::Result class. + * + */ +class ACE_Export ACE_Asynch_Read_Dgram_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Read_Dgram_Result_Impl (void); + + /// Message block which contains the read data + virtual ACE_Message_Block *message_block (void) const = 0; + + /// The number of bytes which were requested at the start of the + /// asynchronous read. + virtual size_t bytes_to_read (void) const = 0; + + /// The address of where the packet came from + virtual int remote_address (ACE_Addr& addr) const = 0; + + /// The flags used in the read + virtual int flags (void) const = 0; + + /// I/O handle used for reading. + virtual ACE_HANDLE handle (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Read_Dgram_Result_Impl (void); +}; + +/** + * @class ACE_Asynch_Write_Dgram_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Write_Dgram class. + * + */ +class ACE_Export ACE_Asynch_Write_Dgram_Impl : public virtual ACE_Asynch_Operation_Impl +{ +public: + virtual ~ACE_Asynch_Write_Dgram_Impl (void); + + /** This starts off an asynchronous send. Upto + * total_length()> will be sent. @a message_block's + * will be updated to reflect the sent bytes if the send operation + * is successful completed. + * Return code of 1 means immediate success and + * is updated to number of bytes sent. The + * method will still be called. Return code of 0 means the IO will + * complete proactively. Return code of -1 means there was an error, use + * errno to get the error code. + * + * Scatter/gather is supported on WIN32 by using the cont()> + * method. Up to ACE_IOV_MAX @a message_block's are supported. Upto + * length()> bytes will be sent from each + * for a total of total_length()> bytes. All + * @a message_block's 's will be updated to reflect the bytes sent + * from each @a message_block. + * + * Priority of the operation is specified by @a priority. On POSIX4-Unix, + * this is supported. Works like in Unix. Negative values are not + * allowed. 0 means priority of the operation same as the process + * priority. 1 means priority of the operation is one less than + * process. And so forth. On Win32, this argument is a no-op. + * @a signal_number is the POSIX4 real-time signal number to be used + * for the operation. @a signal_number ranges from ACE_SIGRTMIN to + * ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems. + */ + virtual ssize_t send (ACE_Message_Block *message_block, + size_t &number_of_bytes_sent, + int flags, + const ACE_Addr &addr, + const void *act, + int priority, + int signal_number) = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Write_Dgram_Impl (void); +}; + +/** + * @class ACE_Asynch_Write_Dgram_Result_Impl + * + * @brief Abstract base class for all the concrete implementation + * classes that provide different implementations for the + * ACE_Asynch_Write_Dgram::Result class. + * + */ +class ACE_Export ACE_Asynch_Write_Dgram_Result_Impl : public virtual ACE_Asynch_Result_Impl +{ +public: + virtual ~ACE_Asynch_Write_Dgram_Result_Impl (void); + + /// The number of bytes which were requested at the start of the + /// asynchronous write. + virtual size_t bytes_to_write (void) const = 0; + + /// Message block which contains the sent data + virtual ACE_Message_Block *message_block (void) const = 0; + + /// The flags using in the write + virtual int flags (void) const = 0; + + /// I/O handle used for writing. + virtual ACE_HANDLE handle (void) const = 0; + +protected: + /// Do-nothing constructor. + ACE_Asynch_Write_Dgram_Result_Impl (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Asynch_IO_Impl.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */ +#include /**/ "ace/post.h" +#endif /* ACE_ASYNCH_IO_IMPL_H */ diff --git a/dep/ACE_wrappers/ace/Asynch_IO_Impl.inl b/dep/ACE_wrappers/ace/Asynch_IO_Impl.inl new file mode 100644 index 000000000..60dc69dfb --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_IO_Impl.inl @@ -0,0 +1,106 @@ +// -*- C++ -*- +// +// $Id: Asynch_IO_Impl.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Asynch_Result_Impl::ACE_Asynch_Result_Impl (void) +{ +} + +ACE_INLINE +ACE_Asynch_Operation_Impl::ACE_Asynch_Operation_Impl (void) +{ +} + +ACE_INLINE +ACE_Asynch_Read_Stream_Impl::ACE_Asynch_Read_Stream_Impl (void) + : ACE_Asynch_Operation_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Read_Stream_Result_Impl::ACE_Asynch_Read_Stream_Result_Impl (void) + : ACE_Asynch_Result_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Write_Stream_Impl::ACE_Asynch_Write_Stream_Impl (void) + : ACE_Asynch_Operation_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Write_Stream_Result_Impl::ACE_Asynch_Write_Stream_Result_Impl (void) + : ACE_Asynch_Result_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Read_File_Impl::ACE_Asynch_Read_File_Impl (void) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Read_Stream_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Read_File_Result_Impl::ACE_Asynch_Read_File_Result_Impl (void) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Read_Stream_Result_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Write_File_Impl::ACE_Asynch_Write_File_Impl (void) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Write_Stream_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Write_File_Result_Impl::ACE_Asynch_Write_File_Result_Impl (void) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Write_Stream_Result_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Accept_Impl::ACE_Asynch_Accept_Impl (void) + : ACE_Asynch_Operation_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Accept_Result_Impl::ACE_Asynch_Accept_Result_Impl (void) + : ACE_Asynch_Result_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Connect_Impl::ACE_Asynch_Connect_Impl (void) + : ACE_Asynch_Operation_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Connect_Result_Impl::ACE_Asynch_Connect_Result_Impl (void) + : ACE_Asynch_Result_Impl () +{ +} + + +ACE_INLINE +ACE_Asynch_Transmit_File_Impl::ACE_Asynch_Transmit_File_Impl (void) + : ACE_Asynch_Operation_Impl () +{ +} + +ACE_INLINE +ACE_Asynch_Transmit_File_Result_Impl::ACE_Asynch_Transmit_File_Result_Impl (void) + : ACE_Asynch_Result_Impl () +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Asynch_Pseudo_Task.cpp b/dep/ACE_wrappers/ace/Asynch_Pseudo_Task.cpp new file mode 100644 index 000000000..94f0d6980 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_Pseudo_Task.cpp @@ -0,0 +1,130 @@ +// $Id: Asynch_Pseudo_Task.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Asynch_Pseudo_Task.h" + +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_signal.h" + +ACE_RCSID(ace, Asynch_Pseudo_Task, "$Id: Asynch_Pseudo_Task.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Asynch_Pseudo_Task::ACE_Asynch_Pseudo_Task () + : select_reactor_ (), // should be initialized before reactor_ + reactor_ (&select_reactor_, 0) // don't delete implementation +{ +} + +ACE_Asynch_Pseudo_Task::~ACE_Asynch_Pseudo_Task () +{ + this->stop (); +} + +int +ACE_Asynch_Pseudo_Task::start (void) +{ + if (this->reactor_.initialized () == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%N:%l:%p\n"), + ACE_TEXT ("start reactor is not initialized")), + -1); + + return this->activate () == -1 ? -1 : 0; // If started, return 0 +} + +int +ACE_Asynch_Pseudo_Task::stop (void) +{ + if (this->thr_count () == 0) // already stopped + return 0; + + if (this->reactor_.end_reactor_event_loop () == -1) + return -1; + + this->wait (); + this->reactor_.close (); + return 0; +} + +int +ACE_Asynch_Pseudo_Task::svc (void) +{ +#if !defined (ACE_WIN32) + + sigset_t RT_signals; + + sigemptyset (&RT_signals); + for (int si = ACE_SIGRTMIN; si <= ACE_SIGRTMAX; si++) + sigaddset (&RT_signals, si); + + if (ACE_OS::pthread_sigmask (SIG_BLOCK, &RT_signals, 0) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Error:(%P | %t):%p\n"), + ACE_TEXT ("pthread_sigmask"))); +#endif + + reactor_.owner (ACE_Thread::self ()); + reactor_.run_reactor_event_loop (); + + return 0; +} + + + +int +ACE_Asynch_Pseudo_Task::register_io_handler (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + int flg_suspend) +{ + // Register the handler with the reactor. + if (-1 == this->reactor_.register_handler (handle, handler, mask)) + return -1; + + if (flg_suspend == 0) + return 0; + + // Suspend the handle now. Enable only when the accept is issued + // by the application. + if (this->reactor_.suspend_handler (handle) == -1) + { + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%N:%l:%p\n"), + ACE_TEXT ("register_io_handler (suspended)"))); + this->reactor_.remove_handler (handle, ACE_Event_Handler::ALL_EVENTS_MASK + | ACE_Event_Handler::DONT_CALL); + return -1; + } + + return 0; +} + +int +ACE_Asynch_Pseudo_Task::remove_io_handler (ACE_HANDLE handle) +{ + return this->reactor_.remove_handler (handle, + ACE_Event_Handler::ALL_EVENTS_MASK + | ACE_Event_Handler::DONT_CALL); +} + +int +ACE_Asynch_Pseudo_Task::remove_io_handler (ACE_Handle_Set &set) +{ + return this->reactor_.remove_handler (set, ACE_Event_Handler::ALL_EVENTS_MASK + | ACE_Event_Handler::DONT_CALL); +} + +int +ACE_Asynch_Pseudo_Task::suspend_io_handler (ACE_HANDLE handle) +{ + return this->reactor_.suspend_handler (handle); +} + +int +ACE_Asynch_Pseudo_Task::resume_io_handler (ACE_HANDLE handle) +{ + return this->reactor_.resume_handler (handle); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Asynch_Pseudo_Task.h b/dep/ACE_wrappers/ace/Asynch_Pseudo_Task.h new file mode 100644 index 000000000..6e2c3a1d4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Asynch_Pseudo_Task.h @@ -0,0 +1,73 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Asynch_Pseudo_Task.h + * + * $Id: Asynch_Pseudo_Task.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Alexander Libman + */ +//============================================================================= + +#ifndef ACE_ASYNCH_PSEUDO_TASK_H +#define ACE_ASYNCH_PSEUDO_TASK_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Reactor.h" +#include "ace/Select_Reactor.h" +#include "ace/Task.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/* + * Specialization hook to replace the Reactor with the + * concrete Reactor implementation, e.g., select_st, + * select_mt etc. + */ +//@@ REACTOR_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK + +/** + * @class ACE_Asynch_Pseudo_Task + * + */ +class ACE_Export ACE_Asynch_Pseudo_Task : public ACE_Task +{ +public: + ACE_Asynch_Pseudo_Task(); + virtual ~ACE_Asynch_Pseudo_Task(); + + int start (void); + int stop (void); + + int register_io_handler (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + int flg_suspend); + + int remove_io_handler (ACE_HANDLE handle); + int remove_io_handler (ACE_Handle_Set &set); + int resume_io_handler (ACE_HANDLE handle); + int suspend_io_handler (ACE_HANDLE handle); + +protected: + virtual int svc (void); + + /// Should be initialized before reactor_ + ACE_Select_Reactor select_reactor_; + + ACE_Reactor reactor_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_ASYNCH_PSEUDO_TASK_H */ diff --git a/dep/ACE_wrappers/ace/Atomic_Op.cpp b/dep/ACE_wrappers/ace/Atomic_Op.cpp new file mode 100644 index 000000000..57139ac85 --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op.cpp @@ -0,0 +1,310 @@ +// $Id: Atomic_Op.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Atomic_Op.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (ace, + Atomic_Op, + "$Id: Atomic_Op.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (__ACE_INLINE__) +#include "ace/Atomic_Op.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_HAS_BUILTIN_ATOMIC_OP) + +#if defined (ACE_INCLUDE_ATOMIC_OP_SPARC) +# include "ace/Atomic_Op_Sparc.h" +#endif /* ACE_INCLUDE_ATOMIC_OP_SPARC */ + +namespace { + +#if defined (_MSC_VER) +// Disable "no return value" warning, as we will be putting +// the return values directly into the EAX register. +#pragma warning (push) +#pragma warning (disable: 4035) +#endif /* _MSC_VER */ + +long +single_cpu_increment (volatile long *value) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + long tmp = 1; + unsigned long addr = reinterpret_cast (value); + asm( "xadd %0, (%1)" : "+r"(tmp) : "r"(addr) ); + return tmp + 1; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_add_long ( + reinterpret_cast (value), 1); +#elif defined(__GNUC__) && defined(PPC) + long tmp; + asm("lwz %0,%1" : "=r" (tmp) : "m" (*value) ); + asm("addi %0,%0,1" : "+r" (tmp) ); + asm("stw %0,%1" : "+r" (tmp), "=m" (*value) ); + return tmp; +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +single_cpu_decrement (volatile long *value) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + long tmp = -1; + unsigned long addr = reinterpret_cast (value); + asm( "xadd %0, (%1)" : "+r"(tmp) : "r"(addr) ); + return tmp - 1; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_add_long ( + reinterpret_cast (value), -1); +#elif defined(__GNUC__) && defined(PPC) + long tmp; + asm("lwz %0,%1" : "=r" (tmp) : "m" (*value) ); + asm("addi %0,%0,-1" : "+r" (tmp) ); + asm("stw %0,%1" : "+r" (tmp), "=m" (*value) ); + return tmp; +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +single_cpu_exchange (volatile long *value, long rhs) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + unsigned long addr = reinterpret_cast (value); + asm( "xchg %0, (%1)" : "+r"(rhs) : "r"(addr) ); + return rhs; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_swap_long ( + reinterpret_cast (value), rhs); +#elif defined(__GNUC__) && defined(PPC) + long tmp; + asm("lwz %0,%1" : "=r" (tmp) : "m" (rhs) ); + asm("stw %0,%1" : "+r" (tmp), "=m" (*value) ); + return tmp; +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_UNUSED_ARG (rhs); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +single_cpu_exchange_add (volatile long *value, long rhs) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + unsigned long addr = reinterpret_cast (value); + asm( "xadd %0, (%1)" : "+r"(rhs) : "r"(addr) ); + return rhs; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_swap_add_long ( + reinterpret_cast (value), rhs); +#elif defined(__GNUC__) && defined(PPC) + long tmp; + asm("add %0,%1,%2" : "=r" (tmp) : "r" (*value), "r" (rhs) ); + asm("stw %0,%1" : "+r" (tmp), "=m" (*value) ); + return tmp; +#elif defined (WIN32) && !defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) +# if defined (_MSC_VER) + __asm + { + mov eax, rhs + mov edx, value + xadd [edx], eax + } + // Return value is already in EAX register. +# elif defined (__BORLANDC__) + _EAX = rhs; + _EDX = reinterpret_cast (value); + __emit__(0x0F, 0xC1, 0x02); // xadd [edx], eax + // Return value is already in EAX register. +# else /* _MSC_VER */ + ACE_UNUSED_ARG (value); + ACE_UNUSED_ARG (rhs); + ACE_NOTSUP_RETURN (-1); +# endif /* _MSC_VER */ +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_UNUSED_ARG (rhs); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +multi_cpu_increment (volatile long *value) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + long tmp = 1; + unsigned long addr = reinterpret_cast (value); + asm( "lock ; xadd %0, (%1)" : "+r"(tmp) : "r"(addr) ); + return tmp + 1; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_add_long ( + reinterpret_cast (value), 1); +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +multi_cpu_decrement (volatile long *value) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + long tmp = -1; + unsigned long addr = reinterpret_cast (value); + asm( "lock ; xadd %0, (%1)" : "+r"(tmp) : "r"(addr) ); + return tmp - 1; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_add_long ( + reinterpret_cast (value), -1); +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +multi_cpu_exchange (volatile long *value, long rhs) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + unsigned long addr = reinterpret_cast (value); + // The XCHG instruction automatically follows LOCK semantics + asm( "xchg %0, (%1)" : "+r"(rhs) : "r"(addr) ); + return rhs; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_swap_long ( + reinterpret_cast (value), rhs); +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_UNUSED_ARG (rhs); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +long +multi_cpu_exchange_add (volatile long *value, long rhs) +{ +#if defined (ACE_HAS_INTEL_ASSEMBLY) + unsigned long addr = reinterpret_cast (value); + asm( "lock ; xadd %0, (%1)" : "+r"(rhs) : "r"(addr) ); + return rhs; +#elif defined (sun) || \ + (defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))) + return ace_atomic_swap_add_long ( + reinterpret_cast (value), rhs); +#elif defined (WIN32) && !defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) +# if defined (_MSC_VER) + __asm + { + mov eax, rhs + mov edx, value + lock xadd [edx], eax + } + // Return value is already in EAX register. +# elif defined (__BORLANDC__) + _EAX = rhs; + _EDX = reinterpret_cast (value); + __emit__(0xF0, 0x0F, 0xC1, 0x02); // lock xadd [edx], eax + // Return value is already in EAX register. +# else /* _MSC_VER */ + ACE_UNUSED_ARG (value); + ACE_UNUSED_ARG (rhs); + ACE_NOTSUP_RETURN (-1); +# endif /* _MSC_VER */ +#else /* ACE_HAS_INTEL_ASSEMBLY*/ + ACE_UNUSED_ARG (value); + ACE_UNUSED_ARG (rhs); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_INTEL_ASSEMBLY*/ +} + +#if defined (_MSC_VER) +#pragma warning (pop) +#endif /* _MSC_VER */ + +} // end namespace + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +long (*ACE_Atomic_Op::increment_fn_) (volatile long *) = multi_cpu_increment; +long (*ACE_Atomic_Op::decrement_fn_) (volatile long *) = multi_cpu_decrement; +long (*ACE_Atomic_Op::exchange_fn_) (volatile long *, long) = multi_cpu_exchange; +long (*ACE_Atomic_Op::exchange_add_fn_) (volatile long *, long) = multi_cpu_exchange_add; + +void +ACE_Atomic_Op::init_functions (void) +{ + if (ACE_OS::num_processors () == 1) + { + increment_fn_ = single_cpu_increment; + decrement_fn_ = single_cpu_decrement; + exchange_fn_ = single_cpu_exchange; + exchange_add_fn_ = single_cpu_exchange_add; + } + else + { + increment_fn_ = multi_cpu_increment; + decrement_fn_ = multi_cpu_decrement; + exchange_fn_ = multi_cpu_exchange; + exchange_add_fn_ = multi_cpu_exchange_add; + } +} + +void +ACE_Atomic_Op::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +long (*ACE_Atomic_Op::increment_fn_) (volatile long *) = multi_cpu_increment; +long (*ACE_Atomic_Op::decrement_fn_) (volatile long *) = multi_cpu_decrement; +long (*ACE_Atomic_Op::exchange_fn_) (volatile long *, long) = multi_cpu_exchange; +long (*ACE_Atomic_Op::exchange_add_fn_) (volatile long *, long) = multi_cpu_exchange_add; + +void +ACE_Atomic_Op::init_functions (void) +{ + if (ACE_OS::num_processors () == 1) + { + increment_fn_ = single_cpu_increment; + decrement_fn_ = single_cpu_decrement; + exchange_fn_ = single_cpu_exchange; + exchange_add_fn_ = single_cpu_exchange_add; + } + else + { + increment_fn_ = multi_cpu_increment; + decrement_fn_ = multi_cpu_decrement; + exchange_fn_ = multi_cpu_exchange; + exchange_add_fn_ = multi_cpu_exchange_add; + } +} + +void +ACE_Atomic_Op::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */ diff --git a/dep/ACE_wrappers/ace/Atomic_Op.h b/dep/ACE_wrappers/ace/Atomic_Op.h new file mode 100644 index 000000000..196b9208f --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op.h @@ -0,0 +1,260 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Atomic_Op.h + * + * $Id: Atomic_Op.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ATOMIC_OP_H +#define ACE_ATOMIC_OP_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Thread_Mutex.h" + +// Include the templates here. +#include "ace/Atomic_Op_T.h" + +// Determine whether builtin atomic op support is +// available on this platform. +#if defined (ACE_HAS_THREADS) +# if defined (WIN32) +# if defined (ACE_HAS_INTRINSIC_INTERLOCKED) +# define ACE_HAS_BUILTIN_ATOMIC_OP +# endif /* ACE_HAS_INTRINSIC_INTERLOCKED */ +# if defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) +# define ACE_HAS_BUILTIN_ATOMIC_OP +# else /* ACE_HAS_INTERLOCKED_EXCHANGEADD */ + // Inline assembly emulation of InterlockedExchangeAdd + // is currently only implemented for MSVC (x86 only) and Borland. +# if (defined (_MSC_VER) && defined (_M_IX86)) || defined (__BORLANDC__) +# define ACE_HAS_BUILTIN_ATOMIC_OP +# endif /* _MSC_VER || __BORLANDC__ */ +# endif /* ACE_HAS_INTERLOCKED_EXCHANGEADD */ +# elif defined (ACE_HAS_INTEL_ASSEMBLY) +# define ACE_HAS_BUILTIN_ATOMIC_OP +# endif /* WIN32 */ +#endif /* ACE_HAS_THREADS */ + +#if defined (ACE_HAS_BUILTIN_ATOMIC_OP) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Atomic_Op + * + * @brief Specialization of ACE_Atomic_Op for platforms that + * support atomic integer operations. + * + * Specialization of ACE_Atomic_Op for platforms that support atomic + * integer operations. + */ +template<> +class ACE_Export ACE_Atomic_Op +{ +public: + /// Initialize to 0. + ACE_Atomic_Op (void); + + /// Initialize to c. + ACE_Atomic_Op (long c); + + /// Manage copying... + ACE_Atomic_Op (const ACE_Atomic_Op &c); + + /// Atomically pre-increment . + long operator++ (void); + + /// Atomically post-increment . + long operator++ (int); + + /// Atomically increment by rhs. + long operator+= (long rhs); + + /// Atomically pre-decrement . + long operator-- (void); + + /// Atomically post-decrement . + long operator-- (int); + + /// Atomically decrement by rhs. + long operator-= (long rhs); + + /// Atomically compare with rhs. + bool operator== (long rhs) const; + + /// Atomically compare with rhs. + bool operator!= (long rhs) const; + + /// Atomically check if greater than or equal to rhs. + bool operator>= (long rhs) const; + + /// Atomically check if greater than rhs. + bool operator> (long rhs) const; + + /// Atomically check if less than or equal to rhs. + bool operator<= (long rhs) const; + + /// Atomically check if less than rhs. + bool operator< (long rhs) const; + + /// Atomically assign rhs to . + ACE_Atomic_Op &operator= (long rhs); + + /// Atomically assign to . + ACE_Atomic_Op &operator= (const ACE_Atomic_Op &rhs); + + /// Explicitly return . + long value (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Explicitly return (by reference). + volatile long &value_i (void); + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + /// Used during ACE object manager initialization to optimize the fast + /// atomic op implementation according to the number of CPUs. + static void init_functions (void); + +private: + + // This function cannot be supported by this template specialization. + // If you need access to an underlying lock, use the ACE_Atomic_Op_Ex + // template instead. + ACE_Thread_Mutex &mutex (void); + +private: + + /// Current object decorated by the atomic op. + volatile long value_; + + // Pointers to selected atomic op implementations. + static long (*increment_fn_) (volatile long *); + static long (*decrement_fn_) (volatile long *); + static long (*exchange_fn_) (volatile long *, long); + static long (*exchange_add_fn_) (volatile long *, long); +}; + +/** + * @class ACE_Atomic_Op + * + * @brief Specialization of ACE_Atomic_Op for platforms that + * support atomic integer operations. + * + * Specialization of ACE_Atomic_Op for platforms that support atomic + * integer operations. + */ +template<> +class ACE_Export ACE_Atomic_Op +{ +public: + /// Initialize to 0. + ACE_Atomic_Op (void); + + /// Initialize to c. + ACE_Atomic_Op (unsigned long c); + + /// Manage copying... + ACE_Atomic_Op (const ACE_Atomic_Op &c); + + /// Atomically pre-increment . + unsigned long operator++ (void); + + /// Atomically post-increment . + unsigned long operator++ (int); + + /// Atomically increment by rhs. + unsigned long operator+= (unsigned long rhs); + + /// Atomically pre-decrement . + unsigned long operator-- (void); + + /// Atomically post-decrement . + unsigned long operator-- (int); + + /// Atomically decrement by rhs. + unsigned long operator-= (unsigned long rhs); + + /// Atomically compare with rhs. + bool operator== (unsigned long rhs) const; + + /// Atomically compare with rhs. + bool operator!= (unsigned long rhs) const; + + /// Atomically check if greater than or equal to rhs. + bool operator>= (unsigned long rhs) const; + + /// Atomically check if greater than rhs. + bool operator> (unsigned long rhs) const; + + /// Atomically check if less than or equal to rhs. + bool operator<= (unsigned long rhs) const; + + /// Atomically check if less than rhs. + bool operator< (unsigned long rhs) const; + + /// Atomically assign rhs to . + ACE_Atomic_Op &operator= (unsigned long rhs); + + /// Atomically assign to . + ACE_Atomic_Op &operator= (const ACE_Atomic_Op &rhs); + + /// Explicitly return . + unsigned long value (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Explicitly return (by reference). + volatile unsigned long &value_i (void); + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + /// Used during ACE object manager initialization to optimize the fast + /// atomic op implementation according to the number of CPUs. + static void init_functions (void); + +private: + + // This function cannot be supported by this template specialization. + // If you need access to an underlying lock, use the ACE_Atomic_Op_Ex + // template instead. + ACE_Thread_Mutex &mutex (void); + +private: + + /// Current object decorated by the atomic op. + volatile unsigned long value_; + + // Pointers to selected atomic op implementations. + static long (*increment_fn_) (volatile long *); + static long (*decrement_fn_) (volatile long *); + static long (*exchange_fn_) (volatile long *, long); + static long (*exchange_add_fn_) (volatile long *, long); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */ + +#if defined (__ACE_INLINE__) +#include "ace/Atomic_Op.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /*ACE_ATOMIC_OP_H*/ diff --git a/dep/ACE_wrappers/ace/Atomic_Op.inl b/dep/ACE_wrappers/ace/Atomic_Op.inl new file mode 100644 index 000000000..ed6bfbdbc --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op.inl @@ -0,0 +1,335 @@ +// -*- C++ -*- +// +// $Id: Atomic_Op.inl 80826 2008-03-04 14:51:23Z wotte $ + +#if defined (ACE_HAS_BUILTIN_ATOMIC_OP) + +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) +# include "ace/os_include/os_intrin.h" + +#pragma intrinsic (_InterlockedExchange, _InterlockedExchangeAdd, _InterlockedIncrement, _InterlockedDecrement) +#endif /* ACE_HAS_INTRINSIC_INTERLOCKED */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op (void) + : value_ (0) +{ +} + +ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op (long c) + : value_ (c) +{ +} + +ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op ( + const ACE_Atomic_Op &rhs) + : value_ (rhs.value_) +{ +} + +ACE_INLINE long +ACE_Atomic_Op::operator++ (void) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return ::_InterlockedIncrement (const_cast (&this->value_)); +#elif defined (WIN32) + return ::InterlockedIncrement (const_cast (&this->value_)); +#else /* WIN32 */ + return (*increment_fn_) (&this->value_); +#endif /* WIN32 */ +} + +ACE_INLINE long +ACE_Atomic_Op::operator++ (int) +{ + return ++*this - 1; +} + +ACE_INLINE long +ACE_Atomic_Op::operator-- (void) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return ::_InterlockedDecrement (const_cast (&this->value_)); +#elif defined (WIN32) + return ::InterlockedDecrement (const_cast (&this->value_)); +#else /* WIN32 */ + return (*decrement_fn_) (&this->value_); +#endif /* WIN32 */ +} + +ACE_INLINE long +ACE_Atomic_Op::operator-- (int) +{ + return --*this + 1; +} + +ACE_INLINE long +ACE_Atomic_Op::operator+= (long rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return ::_InterlockedExchangeAdd (const_cast (&this->value_), + rhs) + rhs; +#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) + return ::InterlockedExchangeAdd (const_cast (&this->value_), + rhs) + rhs; +#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ + return (*exchange_add_fn_) (&this->value_, rhs) + rhs; +#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ +} + +ACE_INLINE long +ACE_Atomic_Op::operator-= (long rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return ::_InterlockedExchangeAdd (const_cast (&this->value_), + -rhs) - rhs; +#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) + return ::InterlockedExchangeAdd (const_cast (&this->value_), + -rhs) - rhs; +#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ + return (*exchange_add_fn_) (&this->value_, -rhs) - rhs; +#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ +} + +ACE_INLINE bool +ACE_Atomic_Op::operator== (long rhs) const +{ + return (this->value_ == rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator!= (long rhs) const +{ + return (this->value_ != rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator>= (long rhs) const +{ + return (this->value_ >= rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator> (long rhs) const +{ + return (this->value_ > rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator<= (long rhs) const +{ + return (this->value_ <= rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator< (long rhs) const +{ + return (this->value_ < rhs); +} + +ACE_INLINE ACE_Atomic_Op & +ACE_Atomic_Op::operator= (long rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + ::_InterlockedExchange (const_cast (&this->value_), rhs); +#elif defined (WIN32) + ::InterlockedExchange (const_cast (&this->value_), rhs); +#else /* WIN32 */ + (*exchange_fn_) (&this->value_, rhs); +#endif /* WIN32 */ + return *this; +} + +ACE_INLINE ACE_Atomic_Op & +ACE_Atomic_Op::operator= ( + const ACE_Atomic_Op &rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + ::_InterlockedExchange (const_cast (&this->value_), rhs.value_); +#elif defined (WIN32) + ::InterlockedExchange (const_cast (&this->value_), rhs.value_); +#else /* WIN32 */ + (*exchange_fn_) (&this->value_, rhs.value_); +#endif /* WIN32 */ + return *this; +} + +ACE_INLINE long +ACE_Atomic_Op::value (void) const +{ + return this->value_; +} + +ACE_INLINE volatile long & +ACE_Atomic_Op::value_i (void) +{ + return this->value_; +} + + +ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op (void) + : value_ (0) +{ +} + +ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op (unsigned long c) + : value_ (c) +{ +} + +ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op ( + const ACE_Atomic_Op &rhs) + : value_ (rhs.value_) +{ +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::operator++ (void) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return static_cast (::_InterlockedIncrement (const_cast (reinterpret_cast(&this->value_)))); +#elif defined (WIN32) + return static_cast (::InterlockedIncrement (const_cast (reinterpret_cast(&this->value_)))); +#else /* WIN32 */ + return static_cast ((*increment_fn_) (reinterpret_cast (&this->value_))); +#endif /* WIN32 */ +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::operator++ (int) +{ + return ++*this - 1; +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::operator-- (void) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return static_cast (::_InterlockedDecrement (const_cast (reinterpret_cast(&this->value_)))); +#elif defined (WIN32) + return static_cast (::InterlockedDecrement (const_cast (reinterpret_cast(&this->value_)))); +#else /* WIN32 */ + return static_cast ((*decrement_fn_) (reinterpret_cast (&this->value_))); +#endif /* WIN32 */ +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::operator-- (int) +{ + return --*this + 1; +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::operator+= (unsigned long rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return static_cast (::_InterlockedExchangeAdd (const_cast (reinterpret_cast (&this->value_)), + rhs)) + rhs; +#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) + return static_cast (::InterlockedExchangeAdd (const_cast (reinterpret_cast (&this->value_)), + rhs)) + rhs; +#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ + return static_cast ((*exchange_add_fn_) (reinterpret_cast (&this->value_), rhs)) + rhs; +#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::operator-= (unsigned long rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + return static_cast (::_InterlockedExchangeAdd (const_cast (reinterpret_cast(&this->value_)), + -static_cast(rhs))) - rhs; +#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) + return static_cast (::InterlockedExchangeAdd (const_cast (reinterpret_cast(&this->value_)), + -static_cast(rhs))) - rhs; +#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ + long l_rhs = static_cast (rhs); + return static_cast ((*exchange_add_fn_) (reinterpret_cast (&this->value_), -l_rhs)) - rhs; +#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */ +} + +ACE_INLINE bool +ACE_Atomic_Op::operator== (unsigned long rhs) const +{ + return (this->value_ == rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator!= (unsigned long rhs) const +{ + return (this->value_ != rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator>= (unsigned long rhs) const +{ + return (this->value_ >= rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator> (unsigned long rhs) const +{ + return (this->value_ > rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator<= (unsigned long rhs) const +{ + return (this->value_ <= rhs); +} + +ACE_INLINE bool +ACE_Atomic_Op::operator< (unsigned long rhs) const +{ + return (this->value_ < rhs); +} + +ACE_INLINE ACE_Atomic_Op & +ACE_Atomic_Op::operator= (unsigned long rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + ::_InterlockedExchange (const_cast (reinterpret_cast (&this->value_)), rhs); +#elif defined (WIN32) + ::InterlockedExchange (const_cast (reinterpret_cast (&this->value_)), rhs); +#else /* WIN32 */ + (*exchange_fn_) (reinterpret_cast (&this->value_), rhs); +#endif /* WIN32 */ + return *this; +} + +ACE_INLINE ACE_Atomic_Op & +ACE_Atomic_Op::operator= ( + const ACE_Atomic_Op &rhs) +{ +#if defined (ACE_HAS_INTRINSIC_INTERLOCKED) + ::_InterlockedExchange (const_cast (reinterpret_cast (&this->value_)), rhs.value_); +#elif defined (WIN32) + ::InterlockedExchange (const_cast (reinterpret_cast (&this->value_)), rhs.value_); +#else /* WIN32 */ + (*exchange_fn_) (reinterpret_cast (&this->value_), rhs.value_); +#endif /* WIN32 */ + return *this; +} + +ACE_INLINE unsigned long +ACE_Atomic_Op::value (void) const +{ + return this->value_; +} + +ACE_INLINE volatile unsigned long & +ACE_Atomic_Op::value_i (void) +{ + return this->value_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */ diff --git a/dep/ACE_wrappers/ace/Atomic_Op_Sparc.c b/dep/ACE_wrappers/ace/Atomic_Op_Sparc.c new file mode 100644 index 000000000..842673e58 --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op_Sparc.c @@ -0,0 +1,187 @@ +/* $Id: Atomic_Op_Sparc.c 80826 2008-03-04 14:51:23Z wotte $ + * + * This is a C file for a reason. The Sun C++ compiler does not accept + * inline assembler. + * + * Portions of this code are based on atomic operations found in the + * linux kernel source code. + */ + +#if defined (ACE_INCLUDE_ATOMIC_OP_SPARC) + +#if defined(__i386) && defined(__SUNPRO_C) +static void +__sunpro_asm_code() { + __asm("\n\ + .globl ace_atomic_add_long \n\ + .type ace_atomic_add_long,@function \n\ + .align 4 \n\ +ace_atomic_add_long: \n\ + movl 0x00000004(%esp), %edx \n\ + movl 0x00000008(%esp), %eax \n\ + lock; xadd %eax, (%edx) \n\ + addl 0x00000008(%esp), %eax \n\ + ret \n\ + "); + + __asm("\n\ + .globl ace_atomic_swap_long \n\ + .type ace_atomic_swap_long,@function \n\ + .align 4 \n\ +ace_atomic_swap_long: \n\ + movl 0x00000004(%esp), %edx \n\ + movl 0x00000008(%esp), %eax \n\ + xchg %eax, (%edx) \n\ + ret \n\ + "); + + __asm("\n\ + .globl ace_atomic_swap_add_long \n\ + .type ace_atomic_swap_add_long,@function \n\ + .align 4 \n\ +ace_atomic_swap_add_long: \n\ + movl 0x00000004(%esp), %edx \n\ + movl 0x00000008(%esp), %eax \n\ + lock; xadd %eax, (%edx) \n\ + ret \n\ + "); +} + +#elif defined(__x86_64) && defined(__SUNPRO_C) + +static void +__sunpro_asm_code() { + __asm("\n\ + .globl ace_atomic_add_long \n\ + .type ace_atomic_add_long,@function \n\ + .align 16 \n\ +ace_atomic_add_long: \n\ + movq %rsi, %rax \n\ + lock; xaddq %rax, (%rdi) \n\ + addq %rsi, %rax \n\ + ret \n\ + "); + + __asm("\n\ + .globl ace_atomic_swap_long \n\ + .type ace_atomic_swap_long,@function \n\ + .align 16 \n\ +ace_atomic_swap_long: \n\ + xchgq %rsi, (%rdi) \n\ + movq %rsi, %rax \n\ + ret \n\ + "); + + __asm("\n\ + .globl ace_atomic_swap_add_long \n\ + .type ace_atomic_swap_add_long,@function \n\ + .align 16 \n\ +ace_atomic_swap_add_long: \n\ + lock; xaddq %rsi, (%rdi) \n\ + movq %rsi, %rax \n\ + ret \n\ + "); +} + +#elif defined (__sparcv9) + +unsigned long +ace_atomic_add_long (volatile unsigned long *dest, long rhs) +{ + __asm ("restore\n" + "ldx [%o0], %o2\n" + ".again_add:\n" + "add %o2, %o1, %o3\n" + "casx [%o0], %o2, %o3\n" + "cmp %o2, %o3\n" + "bne,pn %xcc, .again_add\n" + "mov %o3, %o2\n" + "retl\n" + "add %o2, %o1, %o0\n"); +} + +unsigned long +ace_atomic_swap_long (volatile unsigned long *dest, unsigned long rhs) +{ + __asm ("restore\n" + "ldx [%o0], %o2\n" + ".again_swap:\n" + "mov %o1, %o3\n" + "casx [%o0], %o2, %o3\n" + "cmp %o2, %o3\n" + "bne,pn %xcc, .again_swap\n" + "mov %o3, %o2\n" + "retl\n" + "mov %o3, %o0\n"); +} + +unsigned long +ace_atomic_swap_add_long (volatile unsigned long *dest, long rhs) +{ + __asm ("restore\n" + "ldx [%o0], %o2\n" + ".again_swap_add:\n" + "mov %o2, %o4\n" + "add %o2, %o1, %o3\n" + "casx [%o0], %o2, %o3\n" + "cmp %o2, %o3\n" + "bne,pn %xcc, .again_swap_add\n" + "mov %o3, %o2\n" + "retl\n" + "mov %o4, %o0\n"); +} + +#else + +unsigned long +ace_atomic_add_long (volatile unsigned long *dest, long rhs) +{ + __asm ("restore\n" + "ld [%o0], %o2\n" + ".again_add:\n" + "add %o2, %o1, %o3\n" + "cas [%o0], %o2, %o3\n" + "cmp %o2, %o3\n" + "bne,pn %icc, .again_add\n" + "mov %o3, %o2\n" + "retl\n" + "add %o2, %o1, %o0\n"); +} + +unsigned long +ace_atomic_swap_long (volatile unsigned long *dest, unsigned long rhs) +{ + __asm ("restore\n" + "ld [%o0], %o2\n" + ".again_swap:\n" + "mov %o1, %o3\n" + "cas [%o0], %o2, %o3\n" + "cmp %o2, %o3\n" + "bne,pn %icc, .again_swap\n" + "mov %o3, %o2\n" + "retl\n" + "mov %o3, %o0\n"); +} + +unsigned long +ace_atomic_swap_add_long (volatile unsigned long *dest, long rhs) +{ + __asm ("restore\n" + "ld [%o0], %o2\n" + ".again_swap_add:\n" + "mov %o2, %o4\n" + "add %o2, %o1, %o3\n" + "cas [%o0], %o2, %o3\n" + "cmp %o2, %o3\n" + "bne,pn %icc, .again_swap_add\n" + "mov %o3, %o2\n" + "retl\n" + "mov %o4, %o0\n"); +} + +# endif /* __sparcv9 */ + +#elif !defined (__GNUC__) && !defined (__INTEL_COMPILER) +/* Make compilers stop complaining about an empty translation unit */ +static int shut_up_compiler = 0; +#endif /* ACE_INCLUDE_ATOMIC_OP_SPARC */ diff --git a/dep/ACE_wrappers/ace/Atomic_Op_Sparc.h b/dep/ACE_wrappers/ace/Atomic_Op_Sparc.h new file mode 100644 index 000000000..75b9ad6ea --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op_Sparc.h @@ -0,0 +1,14 @@ +/* -*- C++ -*- */ +// $Id: Atomic_Op_Sparc.h 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_ATOMIC_OP_SPARC_H +#define ACE_ATOMIC_OP_SPARC_H + +extern "C" +{ + unsigned long ace_atomic_add_long (volatile unsigned long *dest, long rhs); + unsigned long ace_atomic_swap_long (volatile unsigned long *dest, unsigned long rhs); + unsigned long ace_atomic_swap_add_long (volatile unsigned long *dest, long rhs); +} + +#endif /* ACE_ATOMIC_OP_SPARC_H */ diff --git a/dep/ACE_wrappers/ace/Atomic_Op_T.cpp b/dep/ACE_wrappers/ace/Atomic_Op_T.cpp new file mode 100644 index 000000000..7f14370c6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op_T.cpp @@ -0,0 +1,82 @@ +#ifndef ACE_ATOMIC_OP_T_CPP +#define ACE_ATOMIC_OP_T_CPP + +#include "ace/Atomic_Op_T.h" + +#ifdef ACE_HAS_DUMP +# include "ace/Log_Msg.h" +#endif /* ACE_HAS_DUMP */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Atomic_Op_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Atomic_Op_Ex) +ACE_ALLOC_HOOK_DEFINE(ACE_Atomic_Op) + +ACE_RCSID(ace, Atomic_Op_T, "$Id: Atomic_Op_T.cpp 80826 2008-03-04 14:51:23Z wotte $") + +// ************************************************* +template ACE_LOCK & +ACE_Atomic_Op_Ex::mutex (void) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::mutex"); + return this->mutex_; +} + +template +void +ACE_Atomic_Op_Ex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Atomic_Op_Ex::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Atomic_Op_Ex::ACE_Atomic_Op_Ex (ACE_LOCK & mtx) + : mutex_ (mtx) + , value_ (0) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::ACE_Atomic_Op_Ex"); +} + +template +ACE_Atomic_Op_Ex::ACE_Atomic_Op_Ex ( + ACE_LOCK & mtx, + typename ACE_Atomic_Op_Ex::arg_type c) + : mutex_ (mtx) + , value_ (c) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::ACE_Atomic_Op_Ex"); +} + +// **************************************************************** + +template +ACE_Atomic_Op::ACE_Atomic_Op (void) + : impl_ (this->own_mutex_) +{ + // ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); +} + +template +ACE_Atomic_Op::ACE_Atomic_Op ( + typename ACE_Atomic_Op::arg_type c) + : impl_ (own_mutex_, c) +{ + // ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_ATOMIC_OP_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Atomic_Op_T.h b/dep/ACE_wrappers/ace/Atomic_Op_T.h new file mode 100644 index 000000000..13bd7dbbf --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op_T.h @@ -0,0 +1,369 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Atomic_Op_T.h + * + * $Id: Atomic_Op_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_ATOMIC_OP_T_H +#define ACE_ATOMIC_OP_T_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +struct ACE_Type_Traits +{ + typedef TYPE const & parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef bool parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef char parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef signed char parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef unsigned char parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef short parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef unsigned short parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef int parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef unsigned int parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef long parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef unsigned long parameter_type; +}; + +#ifndef ACE_LACKS_LONGLONG_T +template<> +struct ACE_Type_Traits +{ + typedef long long parameter_type; +}; +#endif /* !ACE_LACKS_LONGLONG_T */ + +#if !defined (ACE_LACKS_LONGLONG_T) \ + && !defined (ACE_LACKS_UNSIGNEDLONGLONG_T) +template<> +struct ACE_Type_Traits +{ + typedef unsigned long long parameter_type; +}; +#endif /* !ACE_LACKS_LONGLONG_T && !ACE_LACKS_UNSIGNEDLONGLONG_T */ + +template<> +struct ACE_Type_Traits +{ + typedef float parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef double parameter_type; +}; + +template<> +struct ACE_Type_Traits +{ + typedef long double parameter_type; +}; + +template +struct ACE_Type_Traits +{ + typedef TYPE* parameter_type; +}; + +/** + * @class ACE_Atomic_Op_Ex + * + * @brief Transparently parameterizes synchronization into basic + * arithmetic operations. + * + * This class is described in an article in the July/August 1994 + * issue of the C++ Report magazine. It implements a + * templatized version of the Decorator pattern from the GoF book. + * + * ACE_Atomic_Op_Ex objects must be constructed with a reference + * to an existing lock. A single lock can be shared between + * multiple ACE_Atomic_Op_Ex objects. If you do not require this + * ability consider using the ACE_Atomic_Op class instead, which + * may be able to take advantage of platform-specific + * optimisations to provide atomic operations without requiring a + * lock. + */ +template +class ACE_Atomic_Op_Ex +{ +public: + + typedef typename ACE_Type_Traits::parameter_type arg_type; + + // = Initialization methods. + + /// Initialize @c value_ to 0. + ACE_Atomic_Op_Ex (ACE_LOCK & mtx); + + /// Initialize @c value_ to c. + ACE_Atomic_Op_Ex (ACE_LOCK & mtx, arg_type c); + + // = Accessors. + + /// Atomically pre-increment @c value_. + TYPE operator++ (void); + + /// Atomically post-increment @c value_. + TYPE operator++ (int); + + /// Atomically increment @c value_ by rhs. + TYPE operator+= (arg_type rhs); + + /// Atomically pre-decrement @c value_. + TYPE operator-- (void); + + /// Atomically post-decrement @c value_. + TYPE operator-- (int); + + /// Atomically decrement @c value_ by rhs. + TYPE operator-= (arg_type rhs); + + /// Atomically compare @c value_ with rhs. + bool operator== (arg_type rhs) const; + + /// Atomically compare @c value_ with rhs. + bool operator!= (arg_type rhs) const; + + /// Atomically check if @c value_ greater than or equal to rhs. + bool operator>= (arg_type rhs) const; + + /// Atomically check if @c value_ greater than rhs. + bool operator> (arg_type rhs) const; + + /// Atomically check if @c value_ less than or equal to rhs. + bool operator<= (arg_type rhs) const; + + /// Atomically check if @c value_ less than rhs. + bool operator< (arg_type rhs) const; + + /// Atomically assign rhs to @c value_. + ACE_Atomic_Op_Ex &operator= (arg_type rhs); + + /// Atomically assign to @c value_. + ACE_Atomic_Op_Ex &operator= ( + ACE_Atomic_Op_Ex const & rhs); + + /// Explicitly return @c value_. + TYPE value (void) const; + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + /// Manage copying... + ACE_Atomic_Op_Ex (ACE_Atomic_Op_Ex const &); + + /** + * Returns a reference to the underlying . This makes it + * possible to acquire the lock explicitly, which can be useful in + * some cases if you instantiate the with an + * ACE_Recursive_Mutex or ACE_Process_Mutex. @note the right + * name would be lock_, but HP/C++ will choke on that! + */ + ACE_LOCK & mutex (void); + + /** + * Explicitly return @c value_ (by reference). This gives the user + * full, unrestricted access to the underlying value. This method + * will usually be used in conjunction with explicit access to the + * lock. Use with care ;-) + */ + TYPE & value_i (void); + +private: + /// Type of synchronization mechanism. + ACE_LOCK & mutex_; + + /// Current object decorated by the atomic op. + TYPE value_; +}; + +/** + * @class ACE_Atomic_Op + * + * @brief Transparently parameterizes synchronization into basic + * arithmetic operations. + * + * This class is described in an article in the July/August 1994 + * issue of the C++ Report magazine. It implements a + * templatized version of the Decorator pattern from the GoF book. + * + * Certain platforms may provide a template specialization for + * ACE_Atomic_Op that provides optimized + * atomic integer operations without actually requiring a mutex. + */ +template +class ACE_Atomic_Op +{ +public: + + typedef typename ACE_Type_Traits::parameter_type arg_type; + + /// Initialize @c value_ to 0. + ACE_Atomic_Op (void); + + /// Initialize @c value_ to c. + ACE_Atomic_Op (arg_type c); + + /// Manage copying... + ACE_Atomic_Op (ACE_Atomic_Op const & c); + + /// Atomically assign rhs to @c value_. + ACE_Atomic_Op & operator= (arg_type rhs); + + /// Atomically assign to @c value_. + ACE_Atomic_Op & operator= ( + ACE_Atomic_Op const & rhs); + + /// Atomically pre-increment @c value_. + TYPE operator++ (void); + + /// Atomically post-increment @c value_. + TYPE operator++ (int); + + /// Atomically increment @c value_ by rhs. + TYPE operator+= (arg_type rhs); + + /// Atomically pre-decrement @c value_. + TYPE operator-- (void); + + /// Atomically post-decrement @c value_. + TYPE operator-- (int); + + /// Atomically decrement @c value_ by rhs. + TYPE operator-= (arg_type rhs); + + /// Atomically compare @c value_ with rhs. + bool operator== (arg_type rhs) const; + + /// Atomically compare @c value_ with rhs. + bool operator!= (arg_type rhs) const; + + /// Atomically check if @c value_ greater than or equal to rhs. + bool operator>= (arg_type rhs) const; + + /// Atomically check if @c value_ greater than rhs. + bool operator> (arg_type rhs) const; + + /// Atomically check if @c value_ less than or equal to rhs. + bool operator<= (arg_type rhs) const; + + /// Atomically check if @c value_ less than rhs. + bool operator< (arg_type rhs) const; + + /// Explicitly return @c value_. + TYPE value (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /** + * Returns a reference to the underlying . This makes it + * possible to acquire the lock explicitly, which can be useful in + * some cases if you instantiate the ACE_Atomic_Op with an + * ACE_Recursive_Mutex or ACE_Process_Mutex. + * + * @deprecated This member function is deprecated and so may go away in + * the future. If you need access to the underlying mutex, consider + * using the ACE_Atomic_Op_Ex template instead. + */ + ACE_LOCK & mutex (void); + + /** + * Explicitly return @c value_ (by reference). This gives the user + * full, unrestricted access to the underlying value. This method + * will usually be used in conjunction with explicit access to the + * lock. Use with care ;-) + */ + TYPE & value_i (void); + +private: + /// Type of synchronization mechanism. + ACE_LOCK own_mutex_; + + /// Underlying atomic op implementation. + ACE_Atomic_Op_Ex impl_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Atomic_Op_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Atomic_Op_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Atomic_Op_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /*ACE_ATOMIC_OP_T_H*/ diff --git a/dep/ACE_wrappers/ace/Atomic_Op_T.inl b/dep/ACE_wrappers/ace/Atomic_Op_T.inl new file mode 100644 index 000000000..ff051b0cb --- /dev/null +++ b/dep/ACE_wrappers/ace/Atomic_Op_T.inl @@ -0,0 +1,340 @@ +// -*- C++ -*- +// +// $Id: Atomic_Op_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Guard_T.h" + +#include + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// +// ACE_Atomic_Op_Ex inline functions +// + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::operator++ (void) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator++"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return ++this->value_; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::operator+= ( + typename ACE_Atomic_Op_Ex::arg_type rhs) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator+="); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return this->value_ += rhs; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::operator-- (void) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator--"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return --this->value_; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::operator-= ( + typename ACE_Atomic_Op_Ex::arg_type rhs) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator-="); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return this->value_ -= rhs; +} + +template +ACE_INLINE +ACE_Atomic_Op_Ex::ACE_Atomic_Op_Ex ( + ACE_Atomic_Op_Ex const & rhs) + : mutex_ (rhs.mutex_) + , value_ (rhs.value ()) // rhs.value() returns atomically +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::ACE_Atomic_Op_Ex"); +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::operator++ (int) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator++"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return this->value_++; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::operator-- (int) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator--"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return this->value_--; +} + +template +ACE_INLINE bool +ACE_Atomic_Op_Ex::operator== ( + typename ACE_Atomic_Op_Ex::arg_type rhs) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator=="); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false); + return this->value_ == rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op_Ex::operator!= ( + typename ACE_Atomic_Op_Ex::arg_type rhs) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator!="); + return !(*this == rhs); +} + +template +ACE_INLINE bool +ACE_Atomic_Op_Ex::operator>= ( + typename ACE_Atomic_Op_Ex::arg_type rhs) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator>="); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false); + return this->value_ >= rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op_Ex::operator> ( + typename ACE_Atomic_Op_Ex::arg_type rhs) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator>"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false); + return this->value_ > rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op_Ex::operator<= ( + typename ACE_Atomic_Op_Ex::arg_type rhs) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator<="); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false); + return this->value_ <= rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op_Ex::operator< ( + typename ACE_Atomic_Op_Ex::arg_type rhs) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator<"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false); + return this->value_ < rhs; +} + +template +ACE_INLINE ACE_Atomic_Op_Ex & +ACE_Atomic_Op_Ex::operator= ( + ACE_Atomic_Op_Ex const & rhs) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator="); + + ACE_Atomic_Op_Ex tmp (rhs); + + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, *this); + std::swap (this->value_, tmp.value_); + + return *this; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op_Ex::value (void) const +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::value"); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); + return this->value_; +} + +template +ACE_INLINE TYPE & +ACE_Atomic_Op_Ex::value_i (void) +{ + // Explicitly return (by reference). This gives the user + // full, unrestricted access to the underlying value. This method + // will usually be used in conjunction with explicit access to the + // lock. Use with care ;-) + return this->value_; +} + +template +ACE_INLINE ACE_Atomic_Op_Ex & +ACE_Atomic_Op_Ex::operator= ( + typename ACE_Atomic_Op_Ex::arg_type rhs) +{ + // ACE_TRACE ("ACE_Atomic_Op_Ex::operator="); + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, *this); + this->value_ = rhs; + return *this; +} + +// +// ACE_Atomic_Op inline functions +// + +template ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op ( + ACE_Atomic_Op const & rhs) + : impl_ (own_mutex_, rhs.value ()) +{ + // ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); +} + + +template +ACE_INLINE ACE_Atomic_Op & +ACE_Atomic_Op::operator= ( + typename ACE_Atomic_Op::arg_type i) +{ + this->impl_ = i; + return *this; +} + +template +ACE_INLINE ACE_Atomic_Op & +ACE_Atomic_Op::operator= ( + ACE_Atomic_Op const & rhs) +{ + this->impl_ = rhs.impl_; + return *this; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::operator++ (void) +{ + return ++this->impl_; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::operator++ (int) +{ + return this->impl_++; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::operator+= ( + typename ACE_Atomic_Op::arg_type rhs) +{ + return this->impl_ += rhs; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::operator-- (void) +{ + return --this->impl_; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::operator-- (int) +{ + return this->impl_--; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::operator-= ( + typename ACE_Atomic_Op::arg_type rhs) +{ + return this->impl_ -= rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op::operator== ( + typename ACE_Atomic_Op::arg_type rhs) const +{ + return this->impl_ == rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op::operator!= ( + typename ACE_Atomic_Op::arg_type rhs) const +{ + return this->impl_ != rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op::operator>= ( + typename ACE_Atomic_Op::arg_type rhs) const +{ + return this->impl_ >= rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op::operator> ( + typename ACE_Atomic_Op::arg_type rhs) const +{ + return this->impl_ > rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op::operator<= ( + typename ACE_Atomic_Op::arg_type rhs) const +{ + return this->impl_ <= rhs; +} + +template +ACE_INLINE bool +ACE_Atomic_Op::operator< ( + typename ACE_Atomic_Op::arg_type rhs) const +{ + return this->impl_ < rhs; +} + +template +ACE_INLINE TYPE +ACE_Atomic_Op::value (void) const +{ + return this->impl_.value (); +} + +template +ACE_INLINE void +ACE_Atomic_Op::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->impl_.dump (); +#endif /* ACE_HAS_DUMP */ + return; +} + +template +ACE_INLINE ACE_LOCK & +ACE_Atomic_Op::mutex (void) +{ + return this->own_mutex_; +} + +template +ACE_INLINE TYPE & +ACE_Atomic_Op::value_i (void) +{ + return this->impl_.value_i (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Auto_Event.cpp b/dep/ACE_wrappers/ace/Auto_Event.cpp new file mode 100644 index 000000000..51efcf760 --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Event.cpp @@ -0,0 +1,49 @@ +// $Id: Auto_Event.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Auto_Event.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Auto_Event.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Auto_Event, + "$Id: Auto_Event.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Auto_Event::ACE_Auto_Event (int initial_state, + int type, + const char *name, + void *arg) + : ACE_Event (0, + initial_state, + type, + ACE_TEXT_CHAR_TO_TCHAR (name), + arg) +{ +} + +#if defined (ACE_HAS_WCHAR) +ACE_Auto_Event::ACE_Auto_Event (int initial_state, + int type, + const wchar_t *name, + void *arg) + : ACE_Event (0, + initial_state, + type, + ACE_TEXT_WCHAR_TO_TCHAR (name), + arg) +{ +} +#endif /* ACE_HAS_WCHAR */ + +void +ACE_Auto_Event::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_Event::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Auto_Event.h b/dep/ACE_wrappers/ace/Auto_Event.h new file mode 100644 index 000000000..042f82ed2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Event.h @@ -0,0 +1,73 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Auto_Event.h + * + * $Id: Auto_Event.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_AUTO_EVENT_H +#define ACE_AUTO_EVENT_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Auto_Event + * + * @brief Auto Events. + * + * Specialization of Event mechanism which wakes up one waiting + * thread on . All platforms support process-scope locking + * support. However, only Win32 platforms support global naming and + * system-scope locking support. + */ +class ACE_Export ACE_Auto_Event : public ACE_Event +{ +public: + /// Constructor which will create auto event + ACE_Auto_Event (int initial_state = 0, + int type = USYNC_THREAD, + const char *name = 0, + void *arg = 0); + +#if defined (ACE_HAS_WCHAR) + /// Constructor which will create auto event (wchar_t version) + ACE_Auto_Event (int initial_state, + int type, + const wchar_t *name, + void *arg = 0); +#endif /* ACE_HAS_WCHAR */ + + /// Default dtor. + ~ACE_Auto_Event (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Auto_Event.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_AUTO_EVENT_H */ diff --git a/dep/ACE_wrappers/ace/Auto_Event.inl b/dep/ACE_wrappers/ace/Auto_Event.inl new file mode 100644 index 000000000..b614e0b0d --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Event.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id: Auto_Event.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Auto_Event::~ACE_Auto_Event (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Auto_Functor.cpp b/dep/ACE_wrappers/ace/Auto_Functor.cpp new file mode 100644 index 000000000..9d0dc79aa --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Functor.cpp @@ -0,0 +1,39 @@ +// $Id: Auto_Functor.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_AUTO_FUNCTOR_CPP +#define ACE_AUTO_FUNCTOR_CPP + +#include "ace/Auto_Functor.h" + +#if !defined(__ACE_INLINE__) +# include "ace/Auto_Functor.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Utils::Auto_Functor::~Auto_Functor() +{ + reset(0); +} + +template void +ACE_Utils::Auto_Functor::reset(X * p) +{ + if(p_ != 0) + { + f_(p_); + } + p_ = p; +} + +templatevoid +ACE_Utils::Auto_Functor::reset(X * p, Functor f) +{ + reset(p); + f_ = f; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /*ACE_AUTO_FUNCTOR_CPP*/ diff --git a/dep/ACE_wrappers/ace/Auto_Functor.h b/dep/ACE_wrappers/ace/Auto_Functor.h new file mode 100644 index 000000000..2c2b81eb2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Functor.h @@ -0,0 +1,127 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file Auto_Functor.h + * + * $Id: Auto_Functor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//============================================================================= +#ifndef ACE_AUTO_FUNCTOR_H +#define ACE_AUTO_FUNCTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE_Utils +{ +/** + * @class Auto_Functor_Ref + * + * @brief Helper class to implement assignment and copy-construction + * as expected + */ +template +struct Auto_Functor_Ref +{ + X * p_; + Functor f_; + + Auto_Functor_Ref(X * p, Functor f); +}; + +/** + * @class Auto_Functor + * + * @brief Helper template to implement auto_ptr<>-like classes, but + * executing a functor in the destructor, instead of always + * deleting things. + * + * The functor is called in the destructor, and it must implement: + * + * Functor() throw();
+ * Functor(Functor const &) throw();
+ * Functor & operator=(Functor const &) throw();
+ * void operator()(X * p) throw();
+ * + */ +template +class Auto_Functor +{ +public: + typedef X element_type; + typedef Functor functor_type; + + /// Constructor + explicit Auto_Functor (X * p = 0, + Functor functor = Functor()); // throw() + + Auto_Functor (Auto_Functor & rhs); // throw() + + Auto_Functor& operator= (Auto_Functor & rhs); // throw() + +#if !defined(ACE_LACKS_MEMBER_TEMPLATES) + template + Auto_Functor(Auto_Functor& rhs); // throw() + + template + Auto_Functor& operator= (Auto_Functor& rhs); // throw() +#endif /* ACE_LACKS_MEMBER_TEMPLATES */ + + ~Auto_Functor(); // throw() + + X & operator*() const; // throw() + + X * operator->() const; // throw() + + X * get(); // throw() + + X * release(); // throw() + + void reset (X * p = 0); // throw() + + void reset (X * p, Functor f); // throw() + + Functor const & functor() const; // throw() + + Auto_Functor(Auto_Functor_Ref rhs); // throw() + + Auto_Functor & operator=(Auto_Functor_Ref rhs); // throw() + +#if !defined(ACE_LACKS_MEMBER_TEMPLATES) + template operator Auto_Functor_Ref(); // throw() + + template operator Auto_Functor(); // throw() +#else + operator Auto_Functor_Ref(); // throw() +#endif /* ACE_LACKS_MEMBER_TEMPLATES */ + +private: + X * p_; + + Functor f_; +}; + +} // namespace ACE_Utils + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined(__ACE_INLINE__) +# include "ace/Auto_Functor.inl" +#endif /* __ACE_INLINE__ */ + +#if defined(ACE_TEMPLATES_REQUIRE_SOURCE) +# include "ace/Auto_Functor.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#include /**/ "ace/post.h" +#endif /* ACE_AUTO_FUNCTOR_H*/ diff --git a/dep/ACE_wrappers/ace/Auto_Functor.inl b/dep/ACE_wrappers/ace/Auto_Functor.inl new file mode 100644 index 000000000..d4cb2cc04 --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Functor.inl @@ -0,0 +1,134 @@ +// -*- C++ -*- +// +// $Id: Auto_Functor.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_Utils::Auto_Functor_Ref:: +Auto_Functor_Ref(X * p, Functor f) + : p_(p) + , f_(f) +{ +} + +template ACE_INLINE +ACE_Utils::Auto_Functor::Auto_Functor(X * p, Functor f) + : p_(p) + , f_(f) +{ +} + +template ACE_INLINE +ACE_Utils::Auto_Functor::Auto_Functor(Auto_Functor & rhs) + : p_(rhs.release()) + , f_(rhs.f_) +{ +} + +template +ACE_INLINE ACE_Utils::Auto_Functor& +ACE_Utils::Auto_Functor:: operator=(Auto_Functor & rhs) +{ + reset(rhs.release()); + f_ = rhs.f_; + return *this; +} + +#if !defined(ACE_LACKS_MEMBER_TEMPLATES) +template template ACE_INLINE +ACE_Utils::Auto_Functor::Auto_Functor(Auto_Functor& rhs) + : p_(rhs.release()) + , f_(rhs.f_) +{ +} + +template template +ACE_INLINE ACE_Utils::Auto_Functor& +ACE_Utils::Auto_Functor::operator=(Auto_Functor& rhs) +{ + reset(rhs.release()); + return *this; +} +#endif /* ACE_LACKS_MEMBER_TEMPLATES */ + +template ACE_INLINE X & +ACE_Utils::Auto_Functor::operator*() const +{ + return *p_; +} + +template +ACE_INLINE X * +ACE_Utils::Auto_Functor::operator->() const +{ + return p_; +} + +template +ACE_INLINE X * +ACE_Utils::Auto_Functor::get() +{ + return p_; +} + +template +ACE_INLINE X * +ACE_Utils::Auto_Functor::release() +{ + X * tmp = p_; + p_ = 0; + return tmp; +} + +template +ACE_INLINE Functor const & +ACE_Utils::Auto_Functor::functor() const +{ + return f_; +} + +template ACE_INLINE +ACE_Utils::Auto_Functor::Auto_Functor(Auto_Functor_Ref rhs) + : p_(rhs.p_) + , f_(rhs.f_) +{ +} + +template +ACE_INLINE ACE_Utils::Auto_Functor & +ACE_Utils::Auto_Functor::operator=(Auto_Functor_Ref rhs) +{ + if(rhs.p_ != p_) + { + reset(rhs.p_); + f_ = rhs.f_; + } + return *this; +} + +#if !defined(ACE_LACKS_MEMBER_TEMPLATES) + +template template ACE_INLINE +ACE_Utils::Auto_Functor::operator ACE_Utils::Auto_Functor_Ref() +{ + return ACE_Utils::Auto_Functor_Ref(release(), f_); +} + +template template ACE_INLINE +ACE_Utils::Auto_Functor::operator ACE_Utils::Auto_Functor() +{ + return ACE_Utils::Auto_Functor(release(), f_); +} + +#else + +templateACE_INLINE +ACE_Utils::Auto_Functor::operator ACE_Utils::Auto_Functor_Ref() +{ + return ACE_Utils::Auto_Functor_Ref(release(), f_); +} + +#endif /* ACE_LACKS_MEMBER_TEMPLATES */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Auto_IncDec_T.cpp b/dep/ACE_wrappers/ace/Auto_IncDec_T.cpp new file mode 100644 index 000000000..ccef122ed --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_IncDec_T.cpp @@ -0,0 +1,34 @@ +// $Id: Auto_IncDec_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_AUTO_INCDEC_T_CPP +#define ACE_AUTO_INCDEC_T_CPP + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Auto_IncDec_T.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Auto_IncDec_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Auto_IncDec) + +template void +ACE_Auto_IncDec::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Auto_IncDec::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_AUTO_INCDEC_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Auto_IncDec_T.h b/dep/ACE_wrappers/ace/Auto_IncDec_T.h new file mode 100644 index 000000000..01677101d --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_IncDec_T.h @@ -0,0 +1,91 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Auto_IncDec_T.h + * + * $Id: Auto_IncDec_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Edan Ayal + */ +//============================================================================= + + +#ifndef ACE_AUTO_INCDEC_T_H +#define ACE_AUTO_INCDEC_T_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Auto_IncDec + * + * @brief This class automatically increments and decrements a + * parameterized counter. + * + * This data structure is meant to be used within a method, + * function, or scope. The actual parameter given for the + * template parameter + * must provide at least operators ++ and --. + */ +template +class ACE_Auto_IncDec +{ +public: + + /// Implicitly increment the counter. + ACE_Auto_IncDec (ACE_SAFELY_INCREMENTABLE_DECREMENTABLE &counter); + + /// Implicitly decrement the counter. + ~ACE_Auto_IncDec (void); + + /// Dump the state of an object. + void dump (void) const; + +protected: + /// Reference to the counter + /// we're incrementing/decrementing. + ACE_SAFELY_INCREMENTABLE_DECREMENTABLE &counter_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const + ACE_Auto_IncDec &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Auto_IncDec (const + ACE_Auto_IncDec &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Auto_IncDec_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Auto_IncDec_T.cpp" +// On Win32 platforms, this code will be included as template source +// code and will not be inlined. Therefore, we first turn off +// ACE_INLINE, set it to be nothing, include the code, and then turn +// ACE_INLINE back to its original setting. All this nonsense is +// necessary, since the generic template code that needs to be +// specialized cannot be inlined, else the compiler will ignore the +// specialization code. Also, the specialization code *must* be +// inlined or the compiler will ignore the specializations. +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Auto_IncDec_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_AUTO_INCDEC_T_H */ diff --git a/dep/ACE_wrappers/ace/Auto_IncDec_T.inl b/dep/ACE_wrappers/ace/Auto_IncDec_T.inl new file mode 100644 index 000000000..e61980e71 --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_IncDec_T.inl @@ -0,0 +1,25 @@ +// -*- C++ -*- +// +// $Id: Auto_IncDec_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Implicitly and automatically increment the counter. + +template ACE_INLINE +ACE_Auto_IncDec::ACE_Auto_IncDec + (ACE_SAFELY_INCREMENTABLE_DECREMENTABLE &counter) + : counter_ (counter) +{ + ++this->counter_; +} + +// Implicitly and automatically decrement the counter. + +template ACE_INLINE +ACE_Auto_IncDec::~ACE_Auto_IncDec (void) +{ + --this->counter_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Auto_Ptr.cpp b/dep/ACE_wrappers/ace/Auto_Ptr.cpp new file mode 100644 index 000000000..791bd482a --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Ptr.cpp @@ -0,0 +1,21 @@ +// $Id: Auto_Ptr.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_AUTO_PTR_CPP +#define ACE_AUTO_PTR_CPP + +#include "ace/Auto_Ptr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Auto_Ptr.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Auto_Ptr, "$Id: Auto_Ptr.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Auto_Basic_Ptr) +ACE_ALLOC_HOOK_DEFINE(ACE_Auto_Basic_Array_Ptr) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_AUTO_PTR_CPP */ diff --git a/dep/ACE_wrappers/ace/Auto_Ptr.h b/dep/ACE_wrappers/ace/Auto_Ptr.h new file mode 100644 index 000000000..3183019ac --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Ptr.h @@ -0,0 +1,242 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Auto_Ptr.h + * + * $Id: Auto_Ptr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + * @author Irfan Pyarali + * @author Jack Reeves + * @author Dr. Harald M. Mueller + */ +//============================================================================= + +#ifndef ACE_AUTO_PTR_H +#define ACE_AUTO_PTR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (_MSC_VER) +// Suppress warning e.g. "return type for +// 'ACE_Auto_Array_Pointer::operator ->' is 'type *' (i.e., not a UDT +// or reference to a UDT. Will produce errors if applied using infix +// notation)" +# pragma warning(push) +# pragma warning(disable: 4284) +#endif /* _MSC_VER */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Auto_Basic_Ptr + * + * @brief Implements the draft C++ standard auto_ptr abstraction. + * This class allows one to work on non-object (basic) types + */ +template +class ACE_Auto_Basic_Ptr +{ +public: + typedef X element_type; + + // = Initialization and termination methods + explicit ACE_Auto_Basic_Ptr (X * p = 0) : p_ (p) {} + + ACE_Auto_Basic_Ptr (ACE_Auto_Basic_Ptr & ap); + ACE_Auto_Basic_Ptr &operator= (ACE_Auto_Basic_Ptr & rhs); + ~ACE_Auto_Basic_Ptr (void); + + // = Accessor methods. + X &operator *() const; + X *get (void) const; + X *release (void); + void reset (X * p = 0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + X *p_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if !defined (ACE_LACKS_AUTO_PTR) && \ + defined (ACE_HAS_STANDARD_CPP_LIBRARY) && \ + (ACE_HAS_STANDARD_CPP_LIBRARY != 0) +#include +#if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) && \ + (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB != 0) +using std::auto_ptr; +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ +#else /* ACE_HAS_STANDARD_CPP_LIBRARY */ + +/** + * @class auto_ptr + * + * @brief Implements the draft C++ standard auto_ptr abstraction. + */ +template +class auto_ptr : public ACE_Auto_Basic_Ptr +{ +public: + typedef X element_type; + + // = Initialization and termination methods + explicit auto_ptr (X * p = 0) : ACE_Auto_Basic_Ptr (p) {} + auto_ptr (auto_ptr & ap) : ACE_Auto_Basic_Ptr (ap.release ()) {} + + X *operator-> () const; +}; + +#endif /* ACE_HAS_STANDARD_CPP_LIBRARY */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @brief Implements the draft C++ standard auto_ptr abstraction. + * This version can be used instead of auto_ptr, and obviates + * the need for the ACE_AUTO_PTR_RESET macro on platforms like + * VC6 where the auto_ptr is broken. + */ +template +class ACE_Auto_Ptr : public ACE_Auto_Basic_Ptr +{ +public: + typedef X element_type; + + // = Initialization and termination methods + explicit ACE_Auto_Ptr (X * p = 0) : ACE_Auto_Basic_Ptr (p) {} + + X *operator-> () const; +}; + +/** + * @class ACE_Auto_Basic_Array_Ptr + * + * @brief Implements an extension to the draft C++ standard auto_ptr + * abstraction. This class allows one to work on non-object + * (basic) types that must be treated as an array, e.g., + * deallocated via "delete [] foo". + */ +template +class ACE_Auto_Basic_Array_Ptr +{ +public: + typedef X element_type; + + // = Initialization and termination methods. + explicit ACE_Auto_Basic_Array_Ptr (X * p = 0) : p_ (p) {} + + ACE_Auto_Basic_Array_Ptr (ACE_Auto_Basic_Array_Ptr & ap); + ACE_Auto_Basic_Array_Ptr &operator= (ACE_Auto_Basic_Array_Ptr & rhs); + ~ACE_Auto_Basic_Array_Ptr (void); + + // = Accessor methods. + X & operator* () const; + X & operator[] (int i) const; + X * get (void) const; + X * release (void); + void reset (X * p = 0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + X * p_; +}; + +/** + * @class ACE_Auto_Array_Ptr + * + * @brief Implements an extension to the draft C++ standard auto_ptr + * abstraction. + */ +template +class ACE_Auto_Array_Ptr : public ACE_Auto_Basic_Array_Ptr +{ +public: + typedef X element_type; + + // = Initialization and termination methods. + explicit ACE_Auto_Array_Ptr (X *p = 0) + : ACE_Auto_Basic_Array_Ptr (p) {} + + X *operator-> () const; +}; + + +/** + * @brief Reset given @c auto_ptr element to new element. + * + * Some platforms have an older version of auto_ptr support, which + * lacks reset, and cannot be disabled easily. Portability to these + * platforms requires use of this function template. This function + * template also works for the @c ACE_Auto_{Basic_}Array_Ptr class + * template, as well. + */ +template +inline void +ACE_auto_ptr_reset (AUTO_PTR_TYPE & ap, + PTR_TYPE * p) +{ +#if defined (ACE_AUTO_PTR_LACKS_RESET) + // Allow compiler to adjust pointer to potential base class pointer + // of element type found in auto_ptr. + typename AUTO_PTR_TYPE::element_type * const tp = p; + if (tp != ap.get ()) + { + ap = AUTO_PTR_TYPE (tp); + } +#else + ap.reset (p); +#endif /* ACE_AUTO_PTR_LACKS_RESET */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Some platforms have an older version of auto_ptr +// support, which lacks reset, and cannot be disabled +// easily. Portability to these platforms requires +// use of the following ACE_AUTO_PTR_RESET macro. +// +// The TYPE macro parameter is no longer necessary but we leave it +// around for backward compatibility. This is also the reason why the +// ACE_auto_ptr_reset function template is not called +// ACE_AUTO_PTR_RESET. +# define ACE_AUTO_PTR_RESET(AUTOPTR,NEWPTR,TYPE) \ + ACE_auto_ptr_reset (AUTOPTR, NEWPTR); + +#if defined (__ACE_INLINE__) +#include "ace/Auto_Ptr.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Auto_Ptr.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Auto_Ptr.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#if defined (_MSC_VER) +// Restore the warning state to what it was before entry. +# pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" +#endif /* ACE_AUTO_PTR_H */ diff --git a/dep/ACE_wrappers/ace/Auto_Ptr.inl b/dep/ACE_wrappers/ace/Auto_Ptr.inl new file mode 100644 index 000000000..9ea47c3f2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Auto_Ptr.inl @@ -0,0 +1,171 @@ +// -*- C++ -*- +// +// $Id: Auto_Ptr.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE void +ACE_Auto_Basic_Ptr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Auto_Basic_Ptr::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_INLINE void +ACE_Auto_Basic_Array_Ptr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_INLINE +ACE_Auto_Basic_Ptr::ACE_Auto_Basic_Ptr (ACE_Auto_Basic_Ptr &rhs) + : p_ (rhs.release ()) +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::ACE_Auto_Basic_Ptr"); +} + +template ACE_INLINE X * +ACE_Auto_Basic_Ptr::get (void) const +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::get"); + return this->p_; +} + +template ACE_INLINE X * +ACE_Auto_Basic_Ptr::release (void) +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::release"); + X *old = this->p_; + this->p_ = 0; + return old; +} + +template ACE_INLINE void +ACE_Auto_Basic_Ptr::reset (X *p) +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::reset"); + if (this->get () != p) + delete this->get (); + this->p_ = p; +} + +template ACE_INLINE ACE_Auto_Basic_Ptr & +ACE_Auto_Basic_Ptr::operator= (ACE_Auto_Basic_Ptr &rhs) +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::operator="); + if (this != &rhs) + { + this->reset (rhs.release ()); + } + return *this; +} + +template ACE_INLINE +ACE_Auto_Basic_Ptr::~ACE_Auto_Basic_Ptr (void) +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::~ACE_Auto_Basic_Ptr"); + delete this->get (); +} + +template ACE_INLINE X & +ACE_Auto_Basic_Ptr::operator *() const +{ + ACE_TRACE ("ACE_Auto_Basic_Ptr::operator *()"); + return *this->get (); +} + +#if defined (ACE_LACKS_AUTO_PTR) || \ + !defined (ACE_HAS_STANDARD_CPP_LIBRARY) || \ + (ACE_HAS_STANDARD_CPP_LIBRARY == 0) + +template ACE_INLINE X * +auto_ptr::operator-> () const +{ + ACE_TRACE ("auto_ptr::operator->"); + return this->get (); +} + +#endif /* ACE_HAS_STANDARD_CPP_LIBRARY */ + +template ACE_INLINE X * +ACE_Auto_Ptr::operator-> () const +{ + ACE_TRACE ("ACE_Auto_Ptr::operator->"); + return this->get (); +} + +template ACE_INLINE X * +ACE_Auto_Basic_Array_Ptr::get (void) const +{ + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::get"); + return this->p_; +} + +template ACE_INLINE X * +ACE_Auto_Basic_Array_Ptr::release (void) +{ + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::release"); + X *old = this->p_; + this->p_ = 0; + return old; +} + +template ACE_INLINE void +ACE_Auto_Basic_Array_Ptr::reset (X *p) +{ + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::reset"); + if (this->get () != p) + delete [] this->get (); + this->p_ = p; +} + +template ACE_INLINE +ACE_Auto_Basic_Array_Ptr::ACE_Auto_Basic_Array_Ptr (ACE_Auto_Basic_Array_Ptr &rhs) + : p_ (rhs.release ()) +{ + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::ACE_Auto_Basic_Array_Ptr"); +} + +template ACE_INLINE ACE_Auto_Basic_Array_Ptr & +ACE_Auto_Basic_Array_Ptr::operator= (ACE_Auto_Basic_Array_Ptr &rhs) +{ + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::operator="); + if (this != &rhs) + { + this->reset (rhs.release ()); + } + return *this; +} + +template ACE_INLINE +ACE_Auto_Basic_Array_Ptr::~ACE_Auto_Basic_Array_Ptr (void) +{ + ACE_TRACE ("ACE_Auto_Basic_Array_Ptr::~ACE_Auto_Basic_Array_Ptr"); + delete [] this->get (); +} + +template ACE_INLINE X & +ACE_Auto_Basic_Array_Ptr::operator *() const +{ + return *this->get (); +} + +template ACE_INLINE X & +ACE_Auto_Basic_Array_Ptr::operator[](int i) const +{ + X *array = this->get (); + return array[i]; +} + +template ACE_INLINE X * +ACE_Auto_Array_Ptr::operator->() const +{ + return this->get (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Barrier.cpp b/dep/ACE_wrappers/ace/Barrier.cpp new file mode 100644 index 000000000..f3f4454b7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Barrier.cpp @@ -0,0 +1,197 @@ +// $Id: Barrier.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Barrier.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Barrier.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Guard_T.h" +#include "ace/OS_NS_errno.h" + +#if defined (ACE_HAS_DUMP) +# include "ace/Log_Msg.h" +#endif /* ACE_HAS_DUMP */ + +ACE_RCSID (ace, + Barrier, + "$Id: Barrier.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Sub_Barrier) + +void +ACE_Sub_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Sub_Barrier::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->barrier_finished_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("running_threads_ = %d"), this->running_threads_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Sub_Barrier::ACE_Sub_Barrier (unsigned int count, + ACE_Thread_Mutex &lock, + const ACE_TCHAR *name, + void *arg) + : barrier_finished_ (lock, name, arg), + running_threads_ (count) +{ +// ACE_TRACE ("ACE_Sub_Barrier::ACE_Sub_Barrier"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Barrier) + +void +ACE_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Barrier::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("current_generation_ = %d"), this->current_generation_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncount_ = %d"), this->count_)); + this->sub_barrier_1_.dump (); + this->sub_barrier_2_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Barrier::ACE_Barrier (unsigned int count, + const ACE_TCHAR *name, + void *arg) + : lock_ (name, (ACE_mutexattr_t *) arg), + current_generation_ (0), + count_ (count), + sub_barrier_1_ (count, lock_, name, arg), + sub_barrier_2_ (count, lock_, name, arg) +{ + ACE_TRACE ("ACE_Barrier::ACE_Barrier"); + this->sub_barrier_[0] = &this->sub_barrier_1_; + this->sub_barrier_[1] = &this->sub_barrier_2_; +} + +int +ACE_Barrier::wait (void) +{ + ACE_TRACE ("ACE_Barrier::wait"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_Sub_Barrier *sbp = + this->sub_barrier_[this->current_generation_]; + + // Check for shutdown... + if (sbp == 0) + { + errno = ESHUTDOWN; + return -1; + } + + int retval = 0; + + if (sbp->running_threads_ == 1) + { + // We're the last running thread, so swap generations and tell + // all the threads waiting on the barrier to continue on their + // way. + sbp->running_threads_ = this->count_; + // Swap generations. + this->current_generation_ = 1 - this->current_generation_; + sbp->barrier_finished_.broadcast (); + } + else + { + --sbp->running_threads_; + + // Block until all the other threads wait(). + while (sbp->running_threads_ != this->count_) + sbp->barrier_finished_.wait (); + + // We're awake and the count has completed. See if it completed + // because all threads hit the barrier, or because the barrier + // was shut down. + if (this->sub_barrier_[this->current_generation_] == 0) + { + errno = ESHUTDOWN; + retval = -1; + } + } + + return retval; +} + +int +ACE_Barrier::shutdown (void) +{ + ACE_TRACE ("ACE_Barrier::shutdown"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_Sub_Barrier *sbp = + this->sub_barrier_[this->current_generation_]; + + // Check for shutdown... + if (sbp == 0) + { + errno = ESHUTDOWN; + return -1; + } + + // Flag the shutdown + this->sub_barrier_[0] = 0; + this->sub_barrier_[1] = 0; + // Tell all the threads waiting on the barrier to continue on their way. + sbp->running_threads_ = this->count_; + sbp->barrier_finished_.broadcast (); + + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Barrier) + +ACE_Thread_Barrier::ACE_Thread_Barrier (unsigned int count, + const ACE_TCHAR *name) + : ACE_Barrier (count, name) +{ +// ACE_TRACE ("ACE_Thread_Barrier::ACE_Thread_Barrier"); +} + +void +ACE_Thread_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Barrier::dump"); + ACE_Barrier::dump (); +#endif /* ACE_HAS_DUMP */ +} + +#if 0 +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Barrier) + +ACE_Process_Barrier::ACE_Process_Barrier (u_int count, + const ACE_TCHAR *name) + : ACE_Barrier (count, USYNC_PROCESS, name) +{ +// ACE_TRACE ("ACE_Process_Barrier::ACE_Process_Barrier"); +} + +void +ACE_Process_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Process_Barrier::dump"); + ACE_Barrier::dump (); +#endif /* ACE_HAS_DUMP */ +} +#endif /* 0 */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Barrier.h b/dep/ACE_wrappers/ace/Barrier.h new file mode 100644 index 000000000..189ff07e4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Barrier.h @@ -0,0 +1,215 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Barrier.h + * + * $Id: Barrier.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_BARRIER_H +#define ACE_BARRIER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/config-all.h" + +// ACE platform supports some form of threading. +#if !defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_errno.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Barrier + * + * @brief This is a no-op to make ACE "syntactically consistent." + */ +class ACE_Export ACE_Barrier +{ +public: + ACE_Barrier (unsigned int, const ACE_TCHAR * = 0, void * = 0) {} + ~ACE_Barrier (void) {} + int wait (void) { ACE_NOTSUP_RETURN (-1); } + void dump (void) const {} +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#else /* ACE_HAS_THREADS */ + +#include "ace/Condition_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +struct ACE_Export ACE_Sub_Barrier +{ + // = Initialization. + ACE_Sub_Barrier (unsigned int count, + ACE_Thread_Mutex &lock, + const ACE_TCHAR *name = 0, + void *arg = 0); + + ~ACE_Sub_Barrier (void); + + /// True if this generation of the barrier is done. + ACE_Condition_Thread_Mutex barrier_finished_; + + /// Number of threads that are still running. + int running_threads_; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +/** + * @class ACE_Barrier + * + * @brief Implements "barrier synchronization". + * + * This class allows number of threads to synchronize + * their completion of (one round of) a task, which is known as + * "barrier synchronization". After all the threads call + * on the barrier they are all atomically released and can begin a new + * round. + * + * This implementation uses a "sub-barrier generation numbering" + * scheme to avoid overhead and to ensure that all threads wait to + * leave the barrier correct. This code is based on an article from + * SunOpsis Vol. 4, No. 1 by Richard Marejka + * (Richard.Marejka@canada.sun.com). + */ +class ACE_Export ACE_Barrier +{ +public: + /// Initialize the barrier to synchronize @a count threads. + ACE_Barrier (unsigned int count, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Default dtor. + ~ACE_Barrier (void); + + /// Block the caller until all @c count threads have called @c wait and + /// then allow all the caller threads to continue in parallel. + /// + /// @retval 0 after successfully waiting for all threads to wait. + /// @retval -1 if an error occurs or the barrier is shut + /// down (@sa shutdown ()). + int wait (void); + + /// Shut the barrier down, aborting the wait of all waiting threads. + /// Any threads waiting on the barrier when it is shut down will return with + /// value -1, errno ESHUTDOWN. + /// + /// @retval 0 for success, -1 if already shut down. + /// + /// @since ACE beta 5.4.9. + int shutdown (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Serialize access to the barrier state. + ACE_Thread_Mutex lock_; + + /// Either 0 or 1, depending on whether we are the first generation + /// of waiters or the next generation of waiters. + int current_generation_; + + /// Total number of threads that can be waiting at any one time. + int count_; + + /** + * We keep two @c sub_barriers, one for the first "generation" of + * waiters, and one for the next "generation" of waiters. This + * efficiently solves the problem of what to do if all the first + * generation waiters don't leave the barrier before one of the + * threads calls wait() again (i.e., starts up the next generation + * barrier). + */ + ACE_Sub_Barrier sub_barrier_1_; + ACE_Sub_Barrier sub_barrier_2_; + ACE_Sub_Barrier *sub_barrier_[2]; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Barrier &); + ACE_Barrier (const ACE_Barrier &); +}; + +#if 0 +/** + * @class ACE_Process_Barrier + * + * @brief Implements "barrier synchronization" using ACE_Process_Mutexes! + * + * This class is just a simple wrapper for ACE_Barrier that + * selects the USYNC_PROCESS variant for the locks. + */ +class ACE_Export ACE_Process_Barrier : public ACE_Barrier +{ +public: + /// Create a Process_Barrier, passing in the optional @a name. + ACE_Process_Barrier (unsigned int count, const ACE_TCHAR *name = 0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; +#endif /* 0 */ + +/** + * @class ACE_Thread_Barrier + * + * @brief Implements "barrier synchronization" using ACE_Thread_Mutexes! + * + * This class is just a simple wrapper for ACE_Barrier that + * selects the USYNC_THREAD variant for the locks. + */ +class ACE_Export ACE_Thread_Barrier : public ACE_Barrier +{ +public: + /// Create a Thread_Barrier, passing in the optional @a name. + ACE_Thread_Barrier (unsigned int count, const ACE_TCHAR *name = 0); + + /// Default dtor. + ~ACE_Thread_Barrier (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Barrier.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_BARRIER_H */ diff --git a/dep/ACE_wrappers/ace/Barrier.inl b/dep/ACE_wrappers/ace/Barrier.inl new file mode 100644 index 000000000..10430d917 --- /dev/null +++ b/dep/ACE_wrappers/ace/Barrier.inl @@ -0,0 +1,22 @@ +// -*- C++ -*- +// +// $Id: Barrier.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Sub_Barrier::~ACE_Sub_Barrier (void) +{ +} + +ACE_INLINE +ACE_Barrier::~ACE_Barrier (void) +{ +} + +ACE_INLINE +ACE_Thread_Barrier::~ACE_Thread_Barrier (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Base_Thread_Adapter.cpp b/dep/ACE_wrappers/ace/Base_Thread_Adapter.cpp new file mode 100644 index 000000000..94386ee1d --- /dev/null +++ b/dep/ACE_wrappers/ace/Base_Thread_Adapter.cpp @@ -0,0 +1,128 @@ +// $Id: Base_Thread_Adapter.cpp 81239 2008-04-04 22:28:48Z iliyan $ + +#include "ace/Base_Thread_Adapter.h" + +ACE_RCSID (ace, + Base_Thread_Adapter, + "$Id: Base_Thread_Adapter.cpp 81239 2008-04-04 22:28:48Z iliyan $") + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "ace/Base_Thread_Adapter.inl" +#endif /* ACE_HAS_INLINED_OSCALLS */ + +#if defined (ACE_HAS_TSS_EMULATION) +# include "ace/OS_NS_Thread.h" +#endif /* ACE_HAS_TSS_EMULATION */ + +#include "ace/Service_Config.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INIT_LOG_MSG_HOOK ACE_Base_Thread_Adapter::init_log_msg_hook_ = 0; +ACE_INHERIT_LOG_MSG_HOOK ACE_Base_Thread_Adapter::inherit_log_msg_hook_ = 0; +ACE_CLOSE_LOG_MSG_HOOK ACE_Base_Thread_Adapter::close_log_msg_hook_ = 0; +ACE_SYNC_LOG_MSG_HOOK ACE_Base_Thread_Adapter::sync_log_msg_hook_ = 0; +ACE_THR_DESC_LOG_MSG_HOOK ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_ = 0; + +ACE_Base_Thread_Adapter::ACE_Base_Thread_Adapter ( + ACE_THR_FUNC user_func, + void *arg, + ACE_THR_C_FUNC entry_point, + ACE_OS_Thread_Descriptor *td +#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , ACE_SEH_EXCEPT_HANDLER selector + , ACE_SEH_EXCEPT_HANDLER handler +#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ) + : user_func_ (user_func) + , arg_ (arg) + , entry_point_ (entry_point) + , thr_desc_ (td) + , ctx_ (ACE_Service_Config::current()) +{ + ACE_OS_TRACE ("ACE_Base_Thread_Adapter::ACE_Base_Thread_Adapter"); + + if (ACE_Base_Thread_Adapter::init_log_msg_hook_ != 0) + (*ACE_Base_Thread_Adapter::init_log_msg_hook_) ( + this->log_msg_attributes_ +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , selector + , handler +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ); +#ifdef ACE_USES_GPROF + getitimer (ITIMER_PROF, &itimer_); +#endif // ACE_USES_GPROF +} + +ACE_Base_Thread_Adapter::~ACE_Base_Thread_Adapter (void) +{ +} + +void +ACE_Base_Thread_Adapter::inherit_log_msg (void) +{ + if (ACE_Base_Thread_Adapter::inherit_log_msg_hook_ != 0) + (*ACE_Base_Thread_Adapter::inherit_log_msg_hook_)( + this->thr_desc_, + this->log_msg_attributes_); + + // Initialize the proper configuration context for the new thread + // Placed here since inherit_log_msg() gets called from any of our + // descendants (before self-destructing) + ACE_Service_Config::current (this->ctx_); +} + +void +ACE_Base_Thread_Adapter::close_log_msg (void) +{ + if (ACE_Base_Thread_Adapter::close_log_msg_hook_ != 0) + (*ACE_Base_Thread_Adapter::close_log_msg_hook_) (); +} + +void +ACE_Base_Thread_Adapter::sync_log_msg (const ACE_TCHAR *prg) +{ + if (ACE_Base_Thread_Adapter::sync_log_msg_hook_ != 0) + (*ACE_Base_Thread_Adapter::sync_log_msg_hook_) (prg); +} + +ACE_OS_Thread_Descriptor * +ACE_Base_Thread_Adapter::thr_desc_log_msg (void) +{ + if (ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_ != 0) + return (*ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_) (); + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Run the thread entry point for the . This must +// be an extern "C" to make certain compilers happy... + +extern "C" ACE_THR_FUNC_RETURN +ACE_THREAD_ADAPTER_NAME (void *args) +{ + ACE_OS_TRACE ("ACE_THREAD_ADAPTER_NAME"); + +#if defined (ACE_HAS_TSS_EMULATION) + // As early as we can in the execution of the new thread, allocate + // its local TS storage. Allocate it on the stack, to save dynamic + // allocation/dealloction. + void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]; + ACE_TSS_Emulation::tss_open (ts_storage); +#endif /* ACE_HAS_TSS_EMULATION */ + + ACE_Base_Thread_Adapter * const thread_args = + static_cast (args); + +#ifdef ACE_USES_GPROF + setitimer (ITIMER_PROF, thread_args->timerval (), 0); +#endif // ACE_USES_GPROF + + // Invoke the user-supplied function with the args. + ACE_THR_FUNC_RETURN status = thread_args->invoke (); + + return status; +} + diff --git a/dep/ACE_wrappers/ace/Base_Thread_Adapter.h b/dep/ACE_wrappers/ace/Base_Thread_Adapter.h new file mode 100644 index 000000000..b36d18e4f --- /dev/null +++ b/dep/ACE_wrappers/ace/Base_Thread_Adapter.h @@ -0,0 +1,195 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Base_Thread_Adapter.h + * + * $Id: Base_Thread_Adapter.h 81239 2008-04-04 22:28:48Z iliyan $ + * + * @author Nanbor Wang + */ +//============================================================================= + +#ifndef ACE_BASE_THREAD_ADAPTER_H +#define ACE_BASE_THREAD_ADAPTER_H +#include /**/ "ace/pre.h" + +#include "ace/OS_Log_Msg_Attributes.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/ACE_export.h" +#include "ace/OS_Log_Msg_Attributes.h" + +#ifdef ACE_USES_GPROF +#include "os_include/sys/os_time.h" +#endif // ACE_USES_GPROF + +#if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1) +# define ACE_THREAD_ADAPTER_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ace_thread_adapter) +#else +# define ACE_THREAD_ADAPTER_NAME ace_thread_adapter +#endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */ + +// Run the thread entry point for the ACE_Thread_Adapter. This must +// be an extern "C" to make certain compilers happy... + +extern "C" ACE_Export ACE_THR_FUNC_RETURN ACE_THREAD_ADAPTER_NAME (void *args); + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_OS_Thread_Descriptor + * + * @brief Parent class of all ACE_Thread_Descriptor classes. + * = + * Container for ACE_Thread_Descriptor members that are + * used in ACE_OS. + */ +class ACE_Export ACE_OS_Thread_Descriptor +{ +public: + /// Get the thread creation flags. + long flags (void) const; + +protected: + /// For use by ACE_Thread_Descriptor. + ACE_OS_Thread_Descriptor (long flags = 0); + + /** + * Keeps track of whether this thread was created "detached" or not. + * If a thread is *not* created detached then if someone calls + * , we need to join with that thread (and + * close down the handle). + */ + long flags_; +}; + + + +class ACE_Service_Gestalt; + + +/** + * @class ACE_Base_Thread_Adapter + * + * @brief Base class for all the Thread_Adapters. + * + * Converts a C++ function into a function that can be + * called from a thread creation routine + * (e.g., pthread_create() or _beginthreadex()) that expects an + * extern "C" entry point. This class also makes it possible to + * transparently provide hooks to register a thread with an + * ACE_Thread_Manager. + * This class is used in ACE_OS::thr_create(). In general, the + * thread that creates an object of this class is different from + * the thread that calls @c invoke() on this object. Therefore, + * the @c invoke() method is responsible for deleting itself. + */ +class ACE_Export ACE_Base_Thread_Adapter +{ +public: + + virtual ~ACE_Base_Thread_Adapter (void); + + /// Virtual method invoked by the thread entry point. + virtual ACE_THR_FUNC_RETURN invoke (void) = 0; + + /// Accessor for the C entry point function to the OS thread creation + /// routine. + ACE_THR_C_FUNC entry_point (void); + +#ifdef ACE_USES_GPROF + /// Accessor to the itimer_ + /// followed http://sam.zoy.org/writings/programming/gprof.html + struct itimerval* timerval (void); +#endif // ACE_USES_PROF + + /// Invoke the close_log_msg_hook, if it is present + static void close_log_msg (void); + + /// Invoke the sync_log_msg_hook, if it is present + static void sync_log_msg (const ACE_TCHAR *prog_name); + + /// Invoke the thr_desc_log_msg_hook, if it is present + static ACE_OS_Thread_Descriptor *thr_desc_log_msg (void); + +protected: + /// Constructor. + ACE_Base_Thread_Adapter (ACE_THR_FUNC user_func, + void *arg, + ACE_THR_C_FUNC entry_point = (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, + ACE_OS_Thread_Descriptor *td = 0 +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , ACE_SEH_EXCEPT_HANDLER selector = 0 + , ACE_SEH_EXCEPT_HANDLER handler = 0 +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ); + /// Inherit the logging features if the parent thread has an + /// ACE_Log_Msg. + void inherit_log_msg (void); + +private: + /// The hooks to inherit and cleanup the Log_Msg attributes + static ACE_INIT_LOG_MSG_HOOK init_log_msg_hook_; + static ACE_INHERIT_LOG_MSG_HOOK inherit_log_msg_hook_; + static ACE_CLOSE_LOG_MSG_HOOK close_log_msg_hook_; + static ACE_SYNC_LOG_MSG_HOOK sync_log_msg_hook_; + static ACE_THR_DESC_LOG_MSG_HOOK thr_desc_log_msg_hook_; + + /// Set the Log_Msg hooks + static void set_log_msg_hooks (ACE_INIT_LOG_MSG_HOOK init_hook, + ACE_INHERIT_LOG_MSG_HOOK inherit_hook, + ACE_CLOSE_LOG_MSG_HOOK close_hook, + ACE_SYNC_LOG_MSG_HOOK sync_hook, + ACE_THR_DESC_LOG_MSG_HOOK thr_desc); + + /// Allow the ACE_Log_Msg class to set its hooks. + friend class ACE_Log_Msg; + +protected: + /// Thread startup function passed in by the user (C++ linkage). + ACE_THR_FUNC user_func_; + + /// Argument to thread startup function. + void *arg_; + + /// Entry point to the underlying OS thread creation call (C + /// linkage). + ACE_THR_C_FUNC entry_point_; + + /** + * Optional thread descriptor. Passing this pointer in will force + * the spawned thread to cache this location in and wait + * until fills in all information in thread + * descriptor. + */ + ACE_OS_Thread_Descriptor *thr_desc_; + + /// The ACE_Log_Msg attributes. + ACE_OS_Log_Msg_Attributes log_msg_attributes_; + + /// That is usefull for gprof, define itimerval +#ifdef ACE_USES_GPROF + struct itimerval itimer_; +#endif // ACE_USES_GPROF + + /// Keep a reference to the configuration context that spawns the + /// thread so the child can inherit it. + ACE_Service_Gestalt * const ctx_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "ace/Base_Thread_Adapter.inl" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#include /**/ "ace/post.h" +#endif /* ACE_BASE_THREAD_ADAPTER_H */ diff --git a/dep/ACE_wrappers/ace/Base_Thread_Adapter.inl b/dep/ACE_wrappers/ace/Base_Thread_Adapter.inl new file mode 100644 index 000000000..3bac80246 --- /dev/null +++ b/dep/ACE_wrappers/ace/Base_Thread_Adapter.inl @@ -0,0 +1,48 @@ +// -*- C++ -*- +// +// $Id: Base_Thread_Adapter.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE long +ACE_OS_Thread_Descriptor::flags (void) const +{ + return flags_; +} + +ACE_INLINE +ACE_OS_Thread_Descriptor::ACE_OS_Thread_Descriptor (long flags) + : flags_ (flags) +{ +} + +ACE_INLINE void +ACE_Base_Thread_Adapter::set_log_msg_hooks ( + ACE_INIT_LOG_MSG_HOOK init_hook, + ACE_INHERIT_LOG_MSG_HOOK inherit_hook, + ACE_CLOSE_LOG_MSG_HOOK close_hook, + ACE_SYNC_LOG_MSG_HOOK sync_hook, + ACE_THR_DESC_LOG_MSG_HOOK thr_desc_hook) +{ + ACE_Base_Thread_Adapter::init_log_msg_hook_ = init_hook; + ACE_Base_Thread_Adapter::inherit_log_msg_hook_ = inherit_hook; + ACE_Base_Thread_Adapter::close_log_msg_hook_ = close_hook; + ACE_Base_Thread_Adapter::sync_log_msg_hook_ = sync_hook; + ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_ = thr_desc_hook; +} + +ACE_INLINE ACE_THR_C_FUNC +ACE_Base_Thread_Adapter::entry_point (void) +{ + return this->entry_point_; +} + +#ifdef ACE_USES_GPROF +ACE_INLINE itimerval* +ACE_Base_Thread_Adapter::timerval (void) +{ + return &(this->itimer_); +} +#endif // ACE_USES_GPROF + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Based_Pointer_Repository.cpp b/dep/ACE_wrappers/ace/Based_Pointer_Repository.cpp new file mode 100644 index 000000000..4ebe8b82c --- /dev/null +++ b/dep/ACE_wrappers/ace/Based_Pointer_Repository.cpp @@ -0,0 +1,119 @@ +// $Id: Based_Pointer_Repository.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Map_Manager.h" +#include "ace/Based_Pointer_Repository.h" +#include "ace/Guard_T.h" +#include "ace/Null_Mutex.h" +#include "ace/Synch_Traits.h" +#include "ace/RW_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Based_Pointer_Repository_Rep + * + * @brief Implementation for the ACE_Based_Pointer_Repository. + * + * Every memory pool in ACE binds it's mapping base address and + * the mapped size to this repository every time it maps/remaps a + * new chunk of memory successfully. + */ +class ACE_Based_Pointer_Repository_Rep +{ +public: + // Useful typedefs. + typedef ACE_Map_Manager MAP_MANAGER; + typedef ACE_Map_Iterator MAP_ITERATOR; + typedef ACE_Map_Entry MAP_ENTRY; + + /// Keeps track of the mapping between addresses and their associated + /// values. + MAP_MANAGER addr_map_; + + /// Synchronize concurrent access to the map. + ACE_SYNCH_MUTEX lock_; +}; + +ACE_Based_Pointer_Repository::ACE_Based_Pointer_Repository (void) +{ + ACE_TRACE ("ACE_Based_Pointer_Repository::ACE_Based_Pointer_Repository"); + ACE_NEW (this->rep_, + ACE_Based_Pointer_Repository_Rep); +} + +ACE_Based_Pointer_Repository::~ACE_Based_Pointer_Repository (void) +{ + ACE_TRACE ("ACE_Based_Pointer_Repository::~ACE_Based_Pointer_Repository"); + delete this->rep_; +} + +// Search for appropriate base address in repository + +int +ACE_Based_Pointer_Repository::find (void *addr, void *&base_addr) +{ + ACE_TRACE ("ACE_Based_Pointer_Repository::find"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->rep_->lock_, -1); + ACE_Based_Pointer_Repository_Rep::MAP_ENTRY *ce = 0; + + for (ACE_Based_Pointer_Repository_Rep::MAP_ITERATOR iter (this->rep_->addr_map_); + iter.next (ce) != 0; + iter.advance ()) + // Check to see if is within any of the regions. + if (addr >= ce->ext_id_ + && addr < ((char *)ce->ext_id_ + ce->int_id_)) + { + // Assign the base address. + base_addr = ce->ext_id_; + return 1; + } + + // Assume base address 0 (e.g., if new'ed). + base_addr = 0; + return 0; +} + +// Bind a new entry to the repository or update the size of an +// existing entry. + +int +ACE_Based_Pointer_Repository::bind (void *addr, size_t size) +{ + ACE_TRACE ("ACE_Based_Pointer_Repository::bind"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->rep_->lock_, -1); + + return this->rep_->addr_map_.rebind (addr, size); +} + +// Unbind a base from the repository. + +int +ACE_Based_Pointer_Repository::unbind (void *addr) +{ + ACE_TRACE ("ACE_Based_Pointer_Repository::unbind"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->rep_->lock_, -1); + ACE_Based_Pointer_Repository_Rep::MAP_ENTRY *ce = 0; + + // Search for service handlers that requested notification. + + for (ACE_Based_Pointer_Repository_Rep::MAP_ITERATOR iter (this->rep_->addr_map_); + iter.next (ce) != 0; + iter.advance ()) + { + // Check to see if is within any of the regions and if + // so, unbind the key from the map. + if (addr >= ce->ext_id_ + && addr < ((char *)ce->ext_id_ + ce->int_id_)) + // Unbind base address. + return this->rep_->addr_map_.unbind (ce->ext_id_); + } + + return 0; +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton * + ACE_Singleton::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Based_Pointer_Repository.h b/dep/ACE_wrappers/ace/Based_Pointer_Repository.h new file mode 100644 index 000000000..f674a8de7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Based_Pointer_Repository.h @@ -0,0 +1,91 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Based_Pointer_Repository.h + * + * $Id: Based_Pointer_Repository.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Dietrich Quehl + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_BASED_POINTER_REPOSITORY_H +#define ACE_BASED_POINTER_REPOSITORY_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Singleton.h" +#include "ace/Synch_Traits.h" +#include "ace/os_include/os_stddef.h" + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl., using the "Cheshire Cat" technique. +class ACE_Based_Pointer_Repository_Rep; + +/** + * @class ACE_Based_Pointer_Repository + * + * @brief Maps pointers to the base address of the region to which each + * pointer belongs. + */ +class ACE_Export ACE_Based_Pointer_Repository +{ +public: + // = Use ACE_Null_Mutex to allow locking while iterating. + + // = Initialization and termination methods. + ACE_Based_Pointer_Repository (void); + ~ACE_Based_Pointer_Repository (void); + + // = Search structure methods. + /** + * Return the appropriate @a base_addr region that contains @a addr. + * Returns 1 on success and 0 if the @a addr isn't contained in any + * @a base_addr region. + */ + int find (void *addr, + void *&base_addr); + + /// Bind a new entry to the repository or update the size of an + /// existing entry. Returns 0 on success and -1 on failure. + int bind (void *addr, + size_t size); + + /// Unbind from the repository the that @a addr is + /// contained within. + int unbind (void *addr); + +private: + + /// Use the "Cheshire-Cat" technique to hide the implementation in + /// order to avoid circular #include dependencies. + ACE_Based_Pointer_Repository_Rep *rep_; + +}; + +// ---------------------------------- + +/// Declare a process wide singleton +ACE_SINGLETON_DECLARE (ACE_Singleton, + ACE_Based_Pointer_Repository, + ACE_SYNCH_RW_MUTEX) + +/// Provide a Singleton access point to the based pointer repository. +typedef ACE_Singleton + ACE_BASED_POINTER_REPOSITORY; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_BASED_POINTER_REPOSITORY_H */ diff --git a/dep/ACE_wrappers/ace/Based_Pointer_T.cpp b/dep/ACE_wrappers/ace/Based_Pointer_T.cpp new file mode 100644 index 000000000..b85774db4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Based_Pointer_T.cpp @@ -0,0 +1,121 @@ +// $Id: Based_Pointer_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_BASED_POINTER_T_CPP +#define ACE_BASED_POINTER_T_CPP + +#include "ace/Based_Pointer_T.h" +#include "ace/Based_Pointer_Repository.h" +#include "ace/Log_Msg.h" + +# define ACE_TRACEX(X) ACE_Trace ____ (ACE_TEXT (X), __LINE__, ACE_TEXT (__FILE__)) + +#if !defined (__ACE_INLINE__) +#include "ace/Based_Pointer_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Based_Pointer::ACE_Based_Pointer (void) +{ + ACE_TRACE ("ACE_Based_Pointer::ACE_Based_Pointer"); +} + +template void +ACE_Based_Pointer_Basic::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Based_Pointer_Basic::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntarget_ = %d\n"), this->target_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("base_offset_ = %d\n"), this->base_offset_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("computed pointer = %x\n"), + (CONCRETE *)(ACE_COMPUTE_BASED_POINTER (this)))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Based_Pointer::ACE_Based_Pointer (CONCRETE *initial) + : ACE_Based_Pointer_Basic (initial) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic"); +} + +template +ACE_Based_Pointer::ACE_Based_Pointer (const void* base_addr, int) + : ACE_Based_Pointer_Basic (base_addr, 0) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic"); +} + +template +ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic (void) + : target_ (0), + base_offset_ (0) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic"); + void *base_addr = 0; + + // Find the base address associated with our pointer. Note + // that it's ok for to return 0, which simply indicates that + // the address is not in memory-mapped virtual address space. + ACE_BASED_POINTER_REPOSITORY::instance ()->find (this, + base_addr); + this->base_offset_ = (char *) this - (char *) base_addr; +} + +template +ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic (const void *base_addr, int) + : target_ (0), + base_offset_ (0) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic"); + this->base_offset_ = (char *) this - (char *) base_addr; +} + +template +ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic (CONCRETE *rhs) + : target_ (0), + base_offset_ (0) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic"); + + if (rhs == 0) + // Store a value of that indicate "NULL" pointer. + this->target_ = -1; + else + { + void *base_addr = 0; + + // Find the base address associated with the pointer. + // Note that it's ok for to return 0, which simply + // indicates that the address is not in memory-mapped virtual + // address space. + ACE_BASED_POINTER_REPOSITORY::instance ()->find (this, + base_addr); + this->base_offset_ = (char *) this - (char *) base_addr; + this->target_ = ((char *) rhs - (char *) base_addr); + } +} + +template +ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic (const ACE_Based_Pointer_Basic &) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::ACE_Based_Pointer_Basic"); + + ACE_ASSERT (0); // not implemented. +} + +template +ACE_Based_Pointer::ACE_Based_Pointer (const ACE_Based_Pointer &rhs) + : ACE_Based_Pointer_Basic (rhs) +{ + ACE_TRACE ("ACE_Based_Pointer::ACE_Based_Pointer"); + ACE_ASSERT (0); // not implemented. +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_BASED_POINTER_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Based_Pointer_T.h b/dep/ACE_wrappers/ace/Based_Pointer_T.h new file mode 100644 index 000000000..802e73ca0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Based_Pointer_T.h @@ -0,0 +1,205 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Based_Pointer_T.h + * + * $Id: Based_Pointer_T.h 81705 2008-05-15 14:02:02Z johnnyw $ + * + * @author Dietrich Quehl + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_BASED_POINTER_T_H +#define ACE_BASED_POINTER_T_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Basic_Types.h" + +#if defined (_MSC_VER) +// Suppress warning e.g. "return type for +// 'ACE_Based_Pointer::operator ->' is 'long *' (i.e., not a UDT +// or reference to a UDT. Will produce errors if applied using infix +// notation)" +#pragma warning(disable: 4284) +#endif /* _MSC_VER */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Based_Pointer_Basic + * + * @brief A proxy that keeps track of the relative offset of a "pointer" + * from its base address. + * This class makes it possible to transparently use "pointers" in + * shared memory as easily as programming with pointers to local + * memory. In particular, we don't need to ensure that the base + * addresses of all the pointers are mapped into separate + * processes at the same absolute memory base address. + */ +template +class ACE_Based_Pointer_Basic +{ +public: + /** + * This constructor initializes the by asking the + * Singleton for the base address of + * the memory region within which it is instantiated. Two results + * are possible: + * + * 1. An has stored a base address/size pair and the + * new based-pointer instance is located between the base address and + * the base address + size - 1. In this case, the repository + * returns the base address. + * + * 2. No suitable address/size pair was found. The repository + * assumes an address in the regular (not mapped) virtual address + * space of the process and returns 0. In this case, the + * based-pointer uses its address as an offset to it's base + * address 0. + */ + ACE_Based_Pointer_Basic (void); + + /** + * Initialize this object using the @a initial pointer. This + * constructor initializes the by asking the + * Singleton for the base address of + * the memory region within which it is instantiated. Three results + * are possible: + * + * 1. An has stored a base address/size pair and the + * new based-pointer instance is located between the base address and + * the base address + size - 1. In this case, the repository + * returns the base address. + * + * 2. No suitable address/size pair was found. The repository + * assumes an address in the regular (not mapped) virtual address + * space of the process and returns 0. In this case, the + * based-pointer uses its address as an offset to its base + * address 0. + * + * 3. If @a initial is 0 then set the value of to -1, which + * indicates a "NULL" pointer. + */ + ACE_Based_Pointer_Basic (CONCRETE *initial); + + /// Copy constructor. + ACE_Based_Pointer_Basic (const ACE_Based_Pointer_Basic &); + + /// Constructor for know base address. @a o is only used to + /// resolve overload ambiguity. + ACE_Based_Pointer_Basic (const void *base_addr, int o); + + /// Pseudo-assignment operator. + void operator = (CONCRETE *from); + + /// Pseudo-assignment operator. + void operator = (const ACE_Based_Pointer_Basic &); + + /// Dereference operator. + CONCRETE operator * (void) const; + + /// Less than operator. + bool operator < (const ACE_Based_Pointer_Basic &) const; + + /// Less than or equal operator. + bool operator <= (const ACE_Based_Pointer_Basic &) const; + + /// Greater than operator. + bool operator > (const ACE_Based_Pointer_Basic &) const; + + /// Greater than or equal operator. + bool operator >= (const ACE_Based_Pointer_Basic &) const; + + /// Equality operator. + bool operator == (const ACE_Based_Pointer_Basic &) const; + + /// Inequality operator. + bool operator != (const ACE_Based_Pointer_Basic &) const; + + /// Subscript operator. + CONCRETE operator [](int index) const; + + /// Increment operator. + void operator+= (int index); + + /// Returns the underlying memory address of the smart pointer. + operator CONCRETE *() const; + + /// Returns the underlying memory address of the smart pointer. + CONCRETE *addr (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Dump the state of the object. + void dump (void) const; + +protected: + ptrdiff_t target_; + + /// Keep track of our offset from the base pointer. + ptrdiff_t base_offset_; +}; + +/** + * @class ACE_Based_Pointer + * + * @brief A smart proxy that keeps track of the relative offset of a + * "pointer" from its base address. + * + * This class makes it possible to transparently use "pointers" in + * shared memory as easily as programming with pointers to local + * memory by overloading the C++ delegation operator ->(). + */ +template +class ACE_Based_Pointer : public ACE_Based_Pointer_Basic +{ +public: + // = Initialization method. + /// Constructor. See constructor for ACE_Based_Pointer_Basic for + /// details. + ACE_Based_Pointer (void); + + /// Initialize this object using the pointer. See + /// constructor for ACE_Based_Pointer_Basic for details. + ACE_Based_Pointer (CONCRETE *initial); + + /// Initialize this object with known @a base_addr. @a dummy is + /// a dummy value used to resolve overload ambiguity and it + /// otherwise ignored. + ACE_Based_Pointer (const void *base_addr, int dummy); + + /// Copy constructor (not implemented yet). + ACE_Based_Pointer (const ACE_Based_Pointer &); + + /// Assignment operator. + void operator = (const ACE_Based_Pointer &); + + /// Pseudo-assignment operator. + void operator = (CONCRETE *from); + + /// The C++ "delegation operator". + CONCRETE *operator-> (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Based_Pointer_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Based_Pointer_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Based_Pointer_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_BASED_POINTER_T_H */ diff --git a/dep/ACE_wrappers/ace/Based_Pointer_T.inl b/dep/ACE_wrappers/ace/Based_Pointer_T.inl new file mode 100644 index 000000000..ba6a5aa51 --- /dev/null +++ b/dep/ACE_wrappers/ace/Based_Pointer_T.inl @@ -0,0 +1,139 @@ +// -*- C++ -*- +// +// $Id: Based_Pointer_T.inl 81705 2008-05-15 14:02:02Z johnnyw $ + +#define ACE_COMPUTE_BASED_POINTER(P) (((char *) (P) - (P)->base_offset_) + (P)->target_) +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE CONCRETE * +ACE_Based_Pointer::operator->(void) +{ + ACE_TRACE ("ACE_Based_Pointer::operator->"); + return reinterpret_cast (ACE_COMPUTE_BASED_POINTER (this)); +} + +template ACE_INLINE void +ACE_Based_Pointer_Basic::operator = (CONCRETE *rhs) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator ="); + if (rhs == 0) + // Store a value of that indicate "NULL" pointer. + this->target_ = -1; + else + this->target_ = ((char *) rhs + - ((char *) this - this->base_offset_)); +} + +template ACE_INLINE void +ACE_Based_Pointer::operator = (CONCRETE *rhs) +{ + ACE_TRACE ("ACE_Based_Pointer::operator ="); + if (rhs == 0) + // Store a value of that indicate "NULL" pointer. + this->target_ = -1; + else + this->target_ = ((char *) rhs + - ((char *) this - this->base_offset_)); +} + +template ACE_INLINE CONCRETE +ACE_Based_Pointer_Basic::operator *(void) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator *"); + return *reinterpret_cast (ACE_COMPUTE_BASED_POINTER (this)); +} + +template ACE_INLINE CONCRETE * +ACE_Based_Pointer_Basic::addr (void) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::addr"); + + if (this->target_ == -1) + return 0; + else + return reinterpret_cast (ACE_COMPUTE_BASED_POINTER (this)); +} + +template ACE_INLINE +ACE_Based_Pointer_Basic::operator CONCRETE *() const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator CONCRETE *()"); + + return this->addr (); +} + +template ACE_INLINE CONCRETE +ACE_Based_Pointer_Basic::operator [] (int index) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator []"); + CONCRETE *c = + reinterpret_cast (ACE_COMPUTE_BASED_POINTER (this)); + return c[index]; +} + +template ACE_INLINE void +ACE_Based_Pointer_Basic::operator += (int index) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator +="); + this->base_offset_ += (index * sizeof (CONCRETE)); +} + +template ACE_INLINE bool +ACE_Based_Pointer_Basic::operator == (const ACE_Based_Pointer_Basic &rhs) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator =="); + return ACE_COMPUTE_BASED_POINTER (this) == ACE_COMPUTE_BASED_POINTER (&rhs); +} + +template ACE_INLINE bool +ACE_Based_Pointer_Basic::operator != (const ACE_Based_Pointer_Basic &rhs) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator !="); + return !(*this == rhs); +} + +template ACE_INLINE bool +ACE_Based_Pointer_Basic::operator < (const ACE_Based_Pointer_Basic &rhs) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator <"); + return ACE_COMPUTE_BASED_POINTER (this) < ACE_COMPUTE_BASED_POINTER (&rhs); +} + +template ACE_INLINE bool +ACE_Based_Pointer_Basic::operator <= (const ACE_Based_Pointer_Basic &rhs) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator <="); + return ACE_COMPUTE_BASED_POINTER (this) <= ACE_COMPUTE_BASED_POINTER (&rhs); +} + +template ACE_INLINE bool +ACE_Based_Pointer_Basic::operator > (const ACE_Based_Pointer_Basic &rhs) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator >"); + return ACE_COMPUTE_BASED_POINTER (this) > ACE_COMPUTE_BASED_POINTER (&rhs); +} + +template ACE_INLINE bool +ACE_Based_Pointer_Basic::operator >= (const ACE_Based_Pointer_Basic &rhs) const +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator >="); + return ACE_COMPUTE_BASED_POINTER (this) >= ACE_COMPUTE_BASED_POINTER (&rhs); +} + +template ACE_INLINE void +ACE_Based_Pointer_Basic::operator= (const ACE_Based_Pointer_Basic &rhs) +{ + ACE_TRACE ("ACE_Based_Pointer_Basic::operator="); + *this = rhs.addr (); +} + +template ACE_INLINE void +ACE_Based_Pointer::operator= (const ACE_Based_Pointer &rhs) +{ + ACE_TRACE ("ACE_Based_Pointer::operator="); + *this = rhs.addr (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Basic_Stats.cpp b/dep/ACE_wrappers/ace/Basic_Stats.cpp new file mode 100644 index 000000000..fe678333d --- /dev/null +++ b/dep/ACE_wrappers/ace/Basic_Stats.cpp @@ -0,0 +1,78 @@ +// $Id: Basic_Stats.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Basic_Stats.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Basic_Stats.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, + Basic_Stats, + "$Id: Basic_Stats.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_Basic_Stats::accumulate (const ACE_Basic_Stats &rhs) +{ + if (rhs.samples_count_ == 0) + return; + + if (this->samples_count_ == 0) + { + this->min_ = rhs.min_; + this->min_at_ = rhs.min_at_; + + this->max_ = rhs.max_; + this->max_at_ = rhs.max_at_; + } + else + { + if (this->min_ > rhs.min_) + { + this->min_ = rhs.min_; + this->min_at_ = rhs.min_at_; + } + if (this->max_ < rhs.max_) + { + this->max_ = rhs.max_; + this->max_at_ = rhs.max_at_; + } + } + + this->samples_count_ += rhs.samples_count_; + this->sum_ += rhs.sum_; +} + +void +ACE_Basic_Stats::dump_results (const ACE_TCHAR *msg, ACE_UINT32 sf) const +{ +#ifndef ACE_NLOGGING + if (this->samples_count () == 0u) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s : no data collected\n"), msg)); + return; + } + + ACE_UINT64 avg = this->sum_ / this->samples_count_; + + ACE_UINT64 l_min = this->min_ / sf; + ACE_UINT64 l_max = this->max_ / sf; + ACE_UINT64 l_avg = avg / sf; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s latency : %Q[%d]/%Q/%Q[%d] (min/avg/max)\n"), + msg, + l_min, this->min_at_, + l_avg, + l_max, this->max_at_)); + +#else + ACE_UNUSED_ARG (msg); + ACE_UNUSED_ARG (sf); +#endif /* ACE_NLOGGING */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Basic_Stats.h b/dep/ACE_wrappers/ace/Basic_Stats.h new file mode 100644 index 000000000..bff1ff29f --- /dev/null +++ b/dep/ACE_wrappers/ace/Basic_Stats.h @@ -0,0 +1,87 @@ + +//============================================================================= +/** + * @file Basic_Stats.h + * + * $Id: Basic_Stats.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//============================================================================= + + +#ifndef ACE_BASIC_STATS_H +#define ACE_BASIC_STATS_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Basic_Types.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/// Collect basic stats about a series of samples +/** + * Compute the average and standard deviation (aka jitter) for an + * arbitrary number of samples, using constant space. + * Normally used for latency statistics. + */ +class ACE_Export ACE_Basic_Stats +{ +public: + /// Constructor + /** + * The number of samples is pre-allocated, and cannot changes once + * the class is initialized. + */ + ACE_Basic_Stats (void); + + /// The number of samples received so far + ACE_UINT32 samples_count (void) const; + + /// Record one sample. + void sample (ACE_UINT64 value); + + /// Update the values to reflect the stats in @a rhs. + void accumulate (const ACE_Basic_Stats &rhs); + + /// Dump all the samples + /** + * Prints out the results, using @a msg as a prefix for each message and + * scaling all the numbers by @a scale_factor. The latter is useful because + * high resolution timer samples are acquired in clock ticks, but often + * presented in microseconds. + */ + void dump_results (const ACE_TCHAR *msg, + ACE_UINT32 scale_factor) const; + + /// The number of samples + ACE_UINT32 samples_count_; + + /// The minimum value + ACE_UINT64 min_; + + /// The number of the sample that had the minimum value + ACE_UINT32 min_at_; + + /// The maximum value + ACE_UINT64 max_; + + /// The number of the sample that had the maximum value + ACE_UINT32 max_at_; + + /// The sum of all the values + ACE_UINT64 sum_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Basic_Stats.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_BASIC_STATS_H */ diff --git a/dep/ACE_wrappers/ace/Basic_Stats.inl b/dep/ACE_wrappers/ace/Basic_Stats.inl new file mode 100644 index 000000000..e2f153884 --- /dev/null +++ b/dep/ACE_wrappers/ace/Basic_Stats.inl @@ -0,0 +1,53 @@ +// -*- C++ -*- +// +// $Id: Basic_Stats.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Basic_Stats::ACE_Basic_Stats (void) + : samples_count_ (0) + , min_ (0) + , min_at_ (0) + , max_ (0) + , max_at_ (0) + , sum_ (0) +{ +} + +ACE_INLINE ACE_UINT32 +ACE_Basic_Stats::samples_count (void) const +{ + return this->samples_count_; +} + +ACE_INLINE void +ACE_Basic_Stats::sample (ACE_UINT64 value) +{ + ++this->samples_count_; + + if (this->samples_count_ == 1u) + { + this->min_ = value; + this->min_at_ = this->samples_count_; + this->max_ = value; + this->max_at_ = this->samples_count_; + } + else + { + if (this->min_ > value) + { + this->min_ = value; + this->min_at_ = this->samples_count_; + } + if (this->max_ < value) + { + this->max_ = value; + this->max_at_ = this->samples_count_; + } + } + + this->sum_ += value; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Basic_Types.cpp b/dep/ACE_wrappers/ace/Basic_Types.cpp new file mode 100644 index 000000000..42ae83c0b --- /dev/null +++ b/dep/ACE_wrappers/ace/Basic_Types.cpp @@ -0,0 +1,139 @@ +#include "ace/Basic_Types.h" + +#if !defined (__ACE_INLINE__) +# include "ace/Basic_Types.inl" +#endif /* ! __ACE_INLINE__ */ + + +ACE_RCSID (ace, + Basic_Types, + "$Id: Basic_Types.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +#if defined (ACE_LACKS_LONGLONG_T) && !defined (ACE_LACKS_UNSIGNEDLONGLONG_T) +# include "ace/Log_Msg.h" +# include "ace/OS_NS_stdio.h" +# include "ace/OS_NS_string.h" +# if !defined (ACE_LACKS_IOSTREAM_TOTALLY) +// FUZZ: disable check_for_streams_include +# include "ace/streams.h" +# endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_U_LongLong::output (FILE *file) const +{ + if (h_ () > 0) + ACE_OS::fprintf (file, "0x%lx%0*lx", h_ (), 2 * sizeof l_ (), l_ ()); + else + ACE_OS::fprintf (file, "0x%lx", l_ ()); +} + + +ACE_TCHAR * +ACE_U_LongLong::as_string (ACE_TCHAR *output, + unsigned int base, + unsigned int uppercase) const +{ + if (*this == 0) + { + ACE_OS::strcpy(output, "0"); + } + else + { + switch(base) + { + case 8: + { + unsigned int index = 0; + int bshift = 31; + while(bshift >= 1) + { + unsigned int sval = (this->h_ () >> bshift) & 7; + if (sval > 0 || index != 0) + { + output[index] = sval + '0'; + ++index; + } + bshift -= 3; + } + bshift = 30; + while(bshift >= 0) + { + unsigned int sval = (this->l_ () >> bshift) & 7; + // Combine the last bit of hi with the first 3-bit digit + if (bshift == 30) + { + sval |= (this->h_ () & 1) << 2; + } + if (sval > 0 || index != 0) + { + output[index] = sval + '0'; + ++index; + } + bshift -= 3; + } + output[index] = '\0'; + break; + } + case 10: + { + ACE_OS::sprintf(output, "%.0f", *this / 1.0); + break; + } + case 16: + { + if (this->h_ () != 0) + { + ACE_OS::sprintf(output, + (uppercase ? "%lX%0*lX" : "%lx%0*lx"), + this->h_ (), 2 * sizeof this->l_ (), + this->l_ ()); + } + else + { + ACE_OS::sprintf(output, + (uppercase ? "%lX" : "%lx"), this->l_ ()); + + } + break; + } + default: + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Unsupported base = %u\n"), base)); + output[0] = '\0'; + } + } + } + + return output; +} + + +# if !defined (ACE_LACKS_IOSTREAM_TOTALLY) +ostream& +operator<< (ostream& os, const ACE_U_LongLong& ll) +{ +#ifdef __TANDEM && (__CPLUSPLUS_VERSION >= 3) + unsigned long flags = os.flags(); +#else + unsigned long flags = os.setf(0); +#endif + char buffer[32]; + + if ((flags & ios::oct) != 0) + os << ll.as_string (buffer, 8); + else if ((flags & ios::hex) != 0) + os << ll.as_string (buffer, 16, (flags & ios::uppercase)); + else + os << ll.as_string (buffer); + return os; +} +# endif + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_LACKS_LONGLONG_T */ + diff --git a/dep/ACE_wrappers/ace/Basic_Types.h b/dep/ACE_wrappers/ace/Basic_Types.h new file mode 100644 index 000000000..8e46abf30 --- /dev/null +++ b/dep/ACE_wrappers/ace/Basic_Types.h @@ -0,0 +1,890 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Basic_Types.h + * + * $Id: Basic_Types.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author David L. Levine + * + * #defines the list of preprocessor macros below. The config.h file can + * pre-define any of these to short-cut the definitions. This is usually + * only necessary if the preprocessor does all of its math using integers. + * + * Sizes of built-in types: + * - ACE_SIZEOF_CHAR + * - ACE_SIZEOF_WCHAR + * - ACE_SIZEOF_SHORT + * - ACE_SIZEOF_INT + * - ACE_SIZEOF_LONG + * - ACE_SIZEOF_LONG_LONG + * - ACE_SIZEOF_VOID_P + * - ACE_SIZEOF_FLOAT + * - ACE_SIZEOF_DOUBLE + * - ACE_SIZEOF_LONG_DOUBLE + * + * Wrappers for built-in types of specific sizes: + * - ACE_USHORT16 (For backward compatibility. Use ACE_UINT16 instead.) + * - ACE_INT8 + * - ACE_UINT8 + * - ACE_INT16 + * - ACE_UINT16 + * - ACE_INT32 + * - ACE_UINT32 + * - ACE_UINT64 + * (@note ACE_INT64 is partly defined, there is no ACE_LongLong for + * platforms that don't have a native 8-byte integer type.) + * + * Byte-order (endian-ness) determination: + * ACE_BYTE_ORDER, to either ACE_BIG_ENDIAN or ACE_LITTLE_ENDIAN + * + * + */ +//============================================================================= + +#include "ace/config-lite.h" + +#ifndef ACE_BASIC_TYPES_H +# define ACE_BASIC_TYPES_H + +# include /**/ "ace/pre.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Pull in definitions +# include "ace/os_include/os_limits.h" // Integer limits +# include "ace/os_include/os_float.h" // Floating point limits +# include "ace/os_include/os_stdlib.h" // Other types +# include "ace/os_include/os_stddef.h" // Get ptrdiff_t - see further comments below + +# if defined(ACE_LACKS_LONGLONG_T) +# include "ace/os_include/os_stdio.h" // For long long emulation +# endif /* ACE_LACKS_LONGLONG_T */ + +# include "ace/os_include/sys/os_types.h" + +# if !defined (ACE_LACKS_SYS_PARAM_H) +# include /**/ +# endif /* ACE_LACKS_SYS_PARAM_H */ + +# include "ace/ACE_export.h" + +# if !defined (ACE_LACKS_STDINT_H) +# include +# endif +# if !defined (ACE_LACKS_INTTYPES_H) +# include +# endif + +#ifdef ACE_LACKS_INTPTR_T +# include "ace/If_Then_Else.h" + +// This intptr_t typedef is here instead of +// since it depends on the template +// metaprogramming in . + +// We could compare ACE_SIZEOF_VOID_P against ACE_SIZEOF_LONG, etc. +// However, that depends on the ACE preprocessor symbol definitions in +// the platform-specific configuration header being correct. +// The template meta-programming approach we take below, +// i.e. determining the type at compile-time rather than at +// preprocessing-time, will work for all platforms, and does not +// depend on ACE developer-defined configuration parameters. + +typedef ACE::If_Then_Else< + (sizeof (void*) == sizeof (signed int)), + signed int, + ACE::If_Then_Else< + (sizeof (void*) == sizeof (signed long)), + signed long, +#ifdef ACE_LACKS_LONGLONG_T + void /* Unknown. Force an invalid type */ +#else + ACE::If_Then_Else< + (sizeof (void*) == sizeof (signed long long)), + signed long long, + void /* Unknown. Force an invalid type */ + >::result_type +#endif /* ACE_LACKS_LONGLONG_T */ + >::result_type + >::result_type intptr_t; + +typedef ACE::If_Then_Else< + (sizeof (void*) == sizeof (unsigned int)), + unsigned int, + ACE::If_Then_Else< + (sizeof (void*) == sizeof (unsigned long)), + unsigned long, +#ifdef ACE_LACKS_UNSIGNEDLONGLONG_T + void /* Unknown. Force an invalid type */ +#else + ACE::If_Then_Else< + (sizeof (void*) == sizeof (unsigned long long)), + unsigned long long, + void /* Unknown. Force an invalid type */ + >::result_type +#endif /* ACE_LACKS_UNSIGNEDLONGLONG_T */ + >::result_type + >::result_type uintptr_t; + +#endif /* ACE_LACKS_INTPTR_T */ + +// A char always has 1 byte, by definition. +# define ACE_SIZEOF_CHAR 1 + +// Unfortunately, there isn't a portable way to determine the size of a wchar. +// So we just define them on a platform basis. If the platform doesn't +// define it and it's an XPG4 system, assume wchar_t is 4 bytes. Some code +// uses ACE_SIZEOF_WCHAR in preprocessor statements, so sizeof() isn't valid. +// If the platform config doesn't set this, and this guess is wrong, +// Basic_Types_Test should catch the inconsistency. +# if defined (ACE_HAS_WCHAR) +# if !defined (ACE_SIZEOF_WCHAR) +# if defined (ACE_HAS_XPG4_MULTIBYTE_CHAR) +# define ACE_SIZEOF_WCHAR 4 +# else +// 0 so the Basic_Types test will catch this. +# define ACE_SIZEOF_WCHAR 0 +# endif /* ACE_HAS_XPG4_MULTIBYTE_CHAR */ +# endif /* !ACE_SIZEOF_WCHAR */ +# endif /* ACE_HAS_WCHAR */ + +// The number of bytes in a short. +# if !defined (ACE_SIZEOF_SHORT) +# if (USHRT_MAX) == 255U +# define ACE_SIZEOF_SHORT 1 +# elif (USHRT_MAX) == 65535U +# define ACE_SIZEOF_SHORT 2 +# elif (USHRT_MAX) == 4294967295U +# define ACE_SIZEOF_SHORT 4 +# elif (USHRT_MAX) == 18446744073709551615U +# define ACE_SIZEOF_SHORT 8 +# else +# error: unsupported short size, must be updated for this platform! +# endif /* USHRT_MAX */ +# endif /* !defined (ACE_SIZEOF_SHORT) */ + +// The number of bytes in an int. +# if !defined (ACE_SIZEOF_INT) +# if (UINT_MAX) == 65535U +# define ACE_SIZEOF_INT 2 +# elif (UINT_MAX) == 4294967295U +# define ACE_SIZEOF_INT 4 +# elif (UINT_MAX) == 18446744073709551615U +# define ACE_SIZEOF_INT 8 +# else +# error: unsupported int size, must be updated for this platform! +# endif /* UINT_MAX */ +# endif /* !defined (ACE_SIZEOF_INT) */ + +// The number of bytes in a long. +# if !defined (ACE_SIZEOF_LONG) +# if (ULONG_MAX) == 65535UL +# define ACE_SIZEOF_LONG 2 +# elif ((ULONG_MAX) == 4294967295UL) +# define ACE_SIZEOF_LONG 4 +# elif ((ULONG_MAX) == 18446744073709551615UL) +# define ACE_SIZEOF_LONG 8 +# else +# error: unsupported long size, must be updated for this platform! +# endif /* ULONG_MAX */ +# endif /* !defined (ACE_SIZEOF_LONG) */ + +// The number of bytes in a long long. +# if !defined (ACE_SIZEOF_LONG_LONG) +# if defined (ACE_LACKS_LONGLONG_T) +# define ACE_SIZEOF_LONG_LONG 8 +# elif defined (ULLONG_MAX) +# if ((ULLONG_MAX) == 4294967295ULL) +# define ACE_SIZEOF_LONG_LONG 4 +# elif ((ULLONG_MAX) == 18446744073709551615ULL) +# define ACE_SIZEOF_LONG_LONG 8 +# endif +# elif defined (ULONGLONG_MAX) +# if ((ULONGLONG_MAX) == 4294967295ULL) +# define ACE_SIZEOF_LONG_LONG 4 +# elif ((ULONGLONG_MAX) == 18446744073709551615ULL) +# define ACE_SIZEOF_LONG_LONG 8 +# endif +# endif +# // If we can't determine the size of long long, assume it is 8 +# // instead of erroring out. (Either ULLONG_MAX and ULONGLONG_MAX +# // may not be supported; or an extended C/C++ dialect may need to +# // be selected. If this assumption is wrong, it can be addressed +# // in the platform-specific config header. +# if !defined (ACE_SIZEOF_LONG_LONG) +# define ACE_SIZEOF_LONG_LONG 8 +# endif +# endif /* !defined (ACE_SIZEOF_LONG_LONG) */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The sizes of the commonly implemented types are now known. Set up +// typedefs for whatever we can. Some of these are needed for certain +// cases of ACE_UINT64, so do them before the 64-bit stuff. + +#if defined (ACE_INT8_TYPE) + typedef ACE_INT8_TYPE ACE_INT8; +#elif defined (ACE_HAS_INT8_T) + typedef int8_t ACE_INT8; +#elif !defined (ACE_LACKS_SIGNED_CHAR) + typedef signed char ACE_INT8; +#else + typedef char ACE_INT8; +#endif /* defined (ACE_INT8_TYPE) */ + +#if defined (ACE_UINT8_TYPE) + typedef ACE_UINT8_TYPE ACE_UINT8; +#elif defined (ACE_HAS_UINT8_T) + typedef uint8_t ACE_UINT8; +#else + typedef unsigned char ACE_UINT8; +#endif /* defined (ACE_UINT8_TYPE) */ + +#if defined (ACE_INT16_TYPE) + typedef ACE_INT16_TYPE ACE_INT16; +#elif defined (ACE_HAS_INT16_T) + typedef int16_t ACE_INT16; +#elif ACE_SIZEOF_SHORT == 2 + typedef short ACE_INT16; +#elif ACE_SIZEOF_INT == 2 + typedef int ACE_INT16; +#else +# error Have to add to the ACE_INT16 type setting +#endif /* defined (ACE_INT16_TYPE) */ + +#if defined (ACE_UINT16_TYPE) + typedef ACE_UINT16_TYPE ACE_UINT16; +#elif defined (ACE_HAS_UINT16_T) + typedef uint16_t ACE_UINT16; +#elif ACE_SIZEOF_SHORT == 2 + typedef unsigned short ACE_UINT16; +#elif ACE_SIZEOF_INT == 2 + typedef unsigned int ACE_UINT16; +#else +# error Have to add to the ACE_UINT16 type setting +#endif /* defined (ACE_UINT16_TYPE) */ + +#if defined (ACE_INT32_TYPE) + typedef ACE_INT32_TYPE ACE_INT32; +#elif defined (ACE_HAS_INT32_T) + typedef int32_t ACE_INT32; +#elif ACE_SIZEOF_INT == 4 + typedef int ACE_INT32; +#elif ACE_SIZEOF_LONG == 4 + typedef long ACE_INT32; +#else +# error Have to add to the ACE_INT32 type setting +#endif /* defined (ACE_INT32_TYPE) */ + +#if defined (ACE_UINT32_TYPE) + typedef ACE_UINT32_TYPE ACE_UINT32; +#elif defined (ACE_HAS_UINT32_T) + typedef uint32_t ACE_UINT32; +#elif ACE_SIZEOF_INT == 4 + typedef unsigned int ACE_UINT32; +#elif ACE_SIZEOF_LONG == 4 + typedef unsigned long ACE_UINT32; +#else +# error Have to add to the ACE_UINT32 type setting +#endif /* defined (ACE_UINT32_TYPE) */ + +#if defined (ACE_INT64_TYPE) + typedef ACE_INT64_TYPE ACE_INT64; +#elif defined (ACE_HAS_INT64_T) + typedef int64_t ACE_INT64; +#elif ACE_SIZEOF_LONG == 8 + typedef long ACE_INT64; +#elif !defined (ACE_LACKS_LONGLONG_T) && ACE_SIZEOF_LONG_LONG == 8 +# ifdef __GNUC__ + // Silence g++ "-pedantic" warnings regarding use of "long long" + // type. + __extension__ +# endif /* __GNUC__ */ + typedef long long ACE_INT64; +#endif /* defined (ACE_INT64_TYPE) */ + +#if !(defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T)) +/* See matching #if around ACE_U_LongLong class declaration below */ + +# if defined (ACE_UINT64_TYPE) + typedef ACE_UINT64_TYPE ACE_UINT64; +# elif defined (ACE_HAS_UINT64_T) + typedef uint64_t ACE_UINT64; +# elif ACE_SIZEOF_LONG == 8 + typedef unsigned long ACE_UINT64; +# elif ACE_SIZEOF_LONG_LONG == 8 +# ifdef __GNUC__ + // Silence g++ "-pedantic" warnings regarding use of "long long" + // type. + __extension__ +# endif /* __GNUC__ */ + typedef unsigned long long ACE_UINT64; +# endif /* defined (ACE_UINT64_TYPE) */ +#endif /* !(ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T) */ + + +typedef ACE_UINT16 ACE_USHORT16; // @@ Backward compatibility. + +// Define a generic byte for use in codecs +typedef unsigned char ACE_Byte; + +// Define a pseudo wide character type when wchar is not supported so we +// can support basic wide character string operations. + +# if defined (ACE_HAS_WCHAR) || defined (ACE_HAS_XPG4_MULTIBYTE_CHAR) +# define ACE_WINT_T wint_t +# define ACE_WCHAR_T wchar_t +# else +# define ACE_WINT_T ACE_UINT16 +# define ACE_WCHAR_T ACE_UINT16 +# endif /* ACE_HAS_WCHAR */ + +// The number of bytes in a void *. +# ifndef ACE_SIZEOF_VOID_P +# define ACE_SIZEOF_VOID_P ACE_SIZEOF_LONG +# endif /* ACE_SIZEOF_VOID_P */ + +// Type for doing arithmetic on pointers ... as elsewhere, we assume +// that unsigned versions of a type are the same size as the signed +// version of the same type. +# if defined (ACE_HAS_WINCE) && (_WIN32_WCE < 400) +typedef unsigned long ptrdiff_t; // evc3, PocketPC don't defined ptrdiff_t +# endif + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Byte-order (endian-ness) determination. +# if defined (BYTE_ORDER) +# if (BYTE_ORDER == LITTLE_ENDIAN) +# define ACE_LITTLE_ENDIAN 0x0123 +# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN +# elif (BYTE_ORDER == BIG_ENDIAN) +# define ACE_BIG_ENDIAN 0x3210 +# define ACE_BYTE_ORDER ACE_BIG_ENDIAN +# else +# error: unknown BYTE_ORDER! +# endif /* BYTE_ORDER */ +# elif defined (_BYTE_ORDER) +# if (_BYTE_ORDER == _LITTLE_ENDIAN) +# define ACE_LITTLE_ENDIAN 0x0123 +# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN +# elif (_BYTE_ORDER == _BIG_ENDIAN) +# define ACE_BIG_ENDIAN 0x3210 +# define ACE_BYTE_ORDER ACE_BIG_ENDIAN +# else +# error: unknown _BYTE_ORDER! +# endif /* _BYTE_ORDER */ +# elif defined (__BYTE_ORDER) +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define ACE_LITTLE_ENDIAN 0x0123 +# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define ACE_BIG_ENDIAN 0x3210 +# define ACE_BYTE_ORDER ACE_BIG_ENDIAN +# else +# error: unknown __BYTE_ORDER! +# endif /* __BYTE_ORDER */ +# else /* ! BYTE_ORDER && ! __BYTE_ORDER */ + // We weren't explicitly told, so we have to figure it out . . . +# if defined (i386) || defined (__i386__) || defined (_M_IX86) || \ + defined (vax) || defined (__alpha) || defined (__LITTLE_ENDIAN__) || \ + defined (ARM) || defined (_M_IA64) || defined (__ia64__) || \ + defined (_M_AMD64) || defined (__amd64) + // We know these are little endian. +# define ACE_LITTLE_ENDIAN 0x0123 +# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN +# else + // Otherwise, we assume big endian. +# define ACE_BIG_ENDIAN 0x3210 +# define ACE_BYTE_ORDER ACE_BIG_ENDIAN +# endif +# endif /* ! BYTE_ORDER && ! __BYTE_ORDER */ + +// Byte swapping macros to deal with differences between little endian +// and big endian machines. Note that "long" here refers to 32 bit +// quantities. +# define ACE_SWAP_LONG(L) ((ACE_SWAP_WORD ((L) & 0xFFFF) << 16) \ + | ACE_SWAP_WORD(((L) >> 16) & 0xFFFF)) +# define ACE_SWAP_WORD(L) ((((L) & 0x00FF) << 8) | (((L) & 0xFF00) >> 8)) + +# if defined (ACE_LITTLE_ENDIAN) +# define ACE_HTONL(X) ACE_SWAP_LONG (X) +# define ACE_NTOHL(X) ACE_SWAP_LONG (X) +# define ACE_IDL_NCTOHL(X) (X) +# define ACE_IDL_NSTOHL(X) (X) +# else +# define ACE_HTONL(X) X +# define ACE_NTOHL(X) X +# define ACE_IDL_NCTOHL(X) (X << 24) +# define ACE_IDL_NSTOHL(X) ((X) << 16) +# endif /* ACE_LITTLE_ENDIAN */ + +# if defined (ACE_LITTLE_ENDIAN) +# define ACE_HTONS(x) ACE_SWAP_WORD(x) +# define ACE_NTOHS(x) ACE_SWAP_WORD(x) +# else +# define ACE_HTONS(x) x +# define ACE_NTOHS(x) x +# endif /* ACE_LITTLE_ENDIAN */ + +#if defined (ACE_LACKS_LONGLONG_T) + // This throws away the high 32 bits. It's very unlikely that a + // pointer will be more than 32 bits wide if the platform does not + // support 64-bit integers. +# define ACE_LONGLONG_TO_PTR(PTR_TYPE, L) \ + reinterpret_cast (L.lo ()) +#elif defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64)) +# define ACE_LONGLONG_TO_PTR(PTR_TYPE, L) \ + reinterpret_cast (static_cast (L)) +#else /* ! ACE_LACKS_LONGLONG_T */ +# define ACE_LONGLONG_TO_PTR(PTR_TYPE, L) \ + reinterpret_cast (static_cast (L)) +#endif /* ! ACE_LACKS_LONGLONG_T */ + +// If the platform lacks an unsigned long long, define one. +#if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T) +// Forward declaration for streams +# include "ace/iosfwd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_U_LongLong + * + * @brief Unsigned long long for platforms that don't have one. + * + * Provide our own unsigned long long. This is intended to be + * use with ACE_High_Res_Timer, so the division operator assumes + * that the quotient fits into a u_long. + * Please note that the constructor takes (optionally) two values. + * The high one contributes 0x100000000 times its value. So, + * for example, (0, 2) is _not_ 20000000000, but instead + * 0x200000000. To emphasize this, the default values are expressed + * in hex, and output () dumps the value in hex. + */ + class ACE_Export ACE_U_LongLong + { + public: + // = Initialization and termination methods. +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + ACE_U_LongLong (const long long value = 0x0); +#else + ACE_U_LongLong (const ACE_UINT32 lo = 0x0, const ACE_UINT32 hi = 0x0); +#endif + ACE_U_LongLong (const ACE_U_LongLong &); + ACE_U_LongLong &operator= (const ACE_U_LongLong &); + ACE_U_LongLong &operator= (const ACE_INT32 &); + ACE_U_LongLong &operator= (const ACE_UINT32 &); + ~ACE_U_LongLong (void); + + // = Overloaded relation operators. + bool operator== (const ACE_U_LongLong &) const; + bool operator== (const ACE_UINT32) const; + bool operator!= (const ACE_U_LongLong &) const; + bool operator!= (const ACE_UINT32) const; + bool operator< (const ACE_U_LongLong &) const; + bool operator< (const ACE_UINT32) const; + bool operator<= (const ACE_U_LongLong &) const; + bool operator<= (const ACE_UINT32) const; + bool operator> (const ACE_U_LongLong &) const; + bool operator> (const ACE_UINT32) const; + bool operator>= (const ACE_U_LongLong &) const; + bool operator>= (const ACE_UINT32) const; + + ACE_U_LongLong operator+ (const ACE_U_LongLong &) const; + ACE_U_LongLong operator+ (const ACE_UINT32) const; + ACE_U_LongLong operator- (const ACE_U_LongLong &) const; + ACE_U_LongLong operator- (const ACE_UINT32) const; + ACE_U_LongLong operator* (const ACE_UINT32) const; + ACE_U_LongLong &operator*= (const ACE_UINT32); + + ACE_U_LongLong operator<< (const unsigned int) const; + ACE_U_LongLong &operator<<= (const unsigned int); + ACE_U_LongLong operator>> (const unsigned int) const; + ACE_U_LongLong &operator>>= (const unsigned int); + + double operator/ (const double) const; + + ACE_U_LongLong &operator+= (const ACE_U_LongLong &); + ACE_U_LongLong &operator+= (const ACE_UINT32); + ACE_U_LongLong &operator-= (const ACE_U_LongLong &); + ACE_U_LongLong &operator-= (const ACE_UINT32); + ACE_U_LongLong &operator++ (); + ACE_U_LongLong &operator-- (); + const ACE_U_LongLong operator++ (int); + const ACE_U_LongLong operator-- (int); + ACE_U_LongLong &operator|= (const ACE_U_LongLong); + ACE_U_LongLong &operator|= (const ACE_UINT32); + ACE_U_LongLong &operator&= (const ACE_U_LongLong); + ACE_U_LongLong &operator&= (const ACE_UINT32); + + // Note that the following take ACE_UINT32 arguments. These are + // typical use cases, and easy to implement. But, they limit the + // return values to 32 bits as well. There are no checks for + // overflow. + ACE_UINT32 operator/ (const ACE_UINT32) const; + ACE_UINT32 operator% (const ACE_UINT32) const; + + // The following only operate on the lower 32 bits (they take only + // 32 bit arguments). + ACE_UINT32 operator| (const ACE_INT32) const; + ACE_UINT32 operator& (const ACE_INT32) const; + + // The following operators convert their arguments to + // ACE_UINT32. So, there may be information loss if they are + // used. + ACE_U_LongLong operator* (const ACE_INT32) const; + ACE_U_LongLong &operator*= (const ACE_INT32); + ACE_UINT32 operator/ (const ACE_INT32) const; +# if ACE_SIZEOF_INT == 4 + ACE_UINT32 operator/ (const unsigned long) const; + ACE_UINT32 operator/ (const long) const; +# else /* ACE_SIZEOF_INT != 4 */ + ACE_UINT32 operator/ (const unsigned int) const; + ACE_UINT32 operator/ (const int) const; +# endif /* ACE_SIZEOF_INT != 4 */ + + // = Helper methods. + /// Outputs the value to the FILE, in hex. + void output (FILE * = stdout) const; + + ACE_TCHAR *as_string (ACE_TCHAR *string, + unsigned int base = 10, + unsigned int uppercase = 0) const; + + ACE_UINT32 hi (void) const; + ACE_UINT32 lo (void) const; + + void hi (const ACE_UINT32 hi); + void lo (const ACE_UINT32 lo); + +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + long long to_int64 (void) const; +# endif + + private: + +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + long long data_; +#else + public: + struct ace_hi_lo_correct_endian + { +# if defined (ACE_BIG_ENDIAN) + /// High 32 bits. + ACE_UINT32 hi_; + /// Low 32 bits. + ACE_UINT32 lo_; + +# else + + /// Low 32 bits. + ACE_UINT32 lo_; + /// High 32 bits. + ACE_UINT32 hi_; +# endif /* ! ACE_BIG_ENDIAN */ + }; + private: + union + { + struct ace_hi_lo_correct_endian data_; + + /// To ensure alignment on 8-byte boundary. + double for_alignment_; + }; + + // @note the following four accessors are inlined here in + // order to minimize the extent of the data_ struct. It's + // only used here; the .i and .cpp files use the accessors. + + /// Internal utility function to hide access through struct. + const ACE_UINT32 &h_ () const { return data_.hi_; } + + /// Internal utility function to hide access through struct. + ACE_UINT32 &h_ () { return data_.hi_; } + + /// Internal utility function to hide access through struct. + const ACE_UINT32 &l_ () const { return data_.lo_; } + + /// Internal utility function to hide access through struct. + ACE_UINT32 &l_ () { return data_.lo_; } + + // @note the above four accessors are inlined here in + // order to minimize the extent of the data_ struct. It's + // only used here; the .inl and .cpp files use the accessors. + + /// These functions are used to implement multiplication. + ACE_UINT32 ul_shift (ACE_UINT32 a, + ACE_UINT32 c_in, + ACE_UINT32 *c_out) const; + ACE_U_LongLong ull_shift (ACE_U_LongLong a, + ACE_UINT32 c_in, + ACE_UINT32 *c_out) const; + ACE_U_LongLong ull_add (ACE_U_LongLong a, + ACE_U_LongLong b, + ACE_UINT32 *carry) const; + ACE_U_LongLong ull_mult (ACE_U_LongLong a, + ACE_UINT32 b, + ACE_UINT32 *carry) const; +#endif // ACE_LACKS_UNSIGNEDLONGLONG_T + }; + + typedef ACE_U_LongLong ACE_UINT64; + +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + ostream &operator<< (ostream &, const ACE_U_LongLong &); +#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +# endif /* ACE_LACKS_LONGLONG_T */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Conversions from ACE_UINT64 to ACE_UINT32. ACE_CU64_TO_CU32 should +// be used on const ACE_UINT64's. +# if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T) +inline ACE_UINT32 +ACE_U64_TO_U32 (ACE_U_LongLong const & n) +{ + /** + * @note We could add a cast operator to ACE_U_LongLong but that may + * cause more problems than it solves. Force users to perform + * an explicit cast via ACE_{C}U64_TO_{C}U32. + */ + return n.lo (); +} + +inline ACE_UINT32 +ACE_CU64_TO_CU32 (ACE_U_LongLong const & n) +{ + return ACE_U64_TO_U32 (n); +} +# else /* ! ACE_LACKS_LONGLONG_T */ +inline ACE_UINT32 +ACE_U64_TO_U32 (ACE_UINT64 n) +{ + return static_cast (n); +} + +inline ACE_UINT32 +ACE_CU64_TO_CU32 (ACE_UINT64 n) +{ + return static_cast (n); +} +# endif /* ! ACE_LACKS_LONGLONG_T */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +// 64-bit literals require special marking on some platforms. +# if defined (ACE_LACKS_LONGLONG_T) + // Can only specify 32-bit arguments. +# define ACE_UINT64_LITERAL(n) n ## UL + // This one won't really work, but it'll keep + // some compilers happy until we have better support +# define ACE_INT64_LITERAL(n) n ## L +# elif defined (ACE_WIN32) +# if defined (__MINGW32__) +# define ACE_UINT64_LITERAL(n) n ## ull +# define ACE_INT64_LITERAL(n) n ## ll +# else +# define ACE_UINT64_LITERAL(n) n ## ui64 +# define ACE_INT64_LITERAL(n) n ## i64 +# endif /* defined (__MINGW32__) */ +# elif defined (__TANDEM) +# define ACE_UINT64_LITERAL(n) n ## LL +# define ACE_INT64_LITERAL(n) n ## LL +# else /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */ +# define ACE_UINT64_LITERAL(n) n ## ull +# define ACE_INT64_LITERAL(n) n ## ll +# endif /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */ + +#if !defined (ACE_INT8_FORMAT_SPECIFIER) +# if defined (PRId8) +# define ACE_INT8_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRId8) +# else +# define ACE_INT8_FORMAT_SPECIFIER ACE_TEXT ("%d") +# endif /* defined (PRId8) */ +#endif /* ACE_INT8_FORMAT_SPECIFIER */ + +#if !defined (ACE_UINT8_FORMAT_SPECIFIER) +# if defined (PRIu8) +# define ACE_UINT8_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRIu8) +# else +# define ACE_UINT8_FORMAT_SPECIFIER ACE_TEXT ("%u") +# endif /* defined (PRIu8) */ +#endif /* ACE_UINT8_FORMAT_SPECIFIER */ + +#if !defined (ACE_INT16_FORMAT_SPECIFIER) +# if defined (PRId16) +# define ACE_INT16_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRId16) +# else +# define ACE_INT16_FORMAT_SPECIFIER ACE_TEXT ("%d") +# endif /* defined (PRId16) */ +#endif /* ACE_INT16_FORMAT_SPECIFIER */ + +#if !defined (ACE_UINT16_FORMAT_SPECIFIER) +# if defined (PRIu16) +# define ACE_UINT16_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRIu16) +# else +# define ACE_UINT16_FORMAT_SPECIFIER ACE_TEXT ("%u") +# endif /* defined (PRIu16) */ +#endif /* ACE_UINT16_FORMAT_SPECIFIER */ + +#if !defined (ACE_INT32_FORMAT_SPECIFIER) +# if defined (PRId32) +# define ACE_INT32_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRId32) +# elif ACE_SIZEOF_INT == 4 +# define ACE_INT32_FORMAT_SPECIFIER ACE_TEXT ("%d") +# else +# define ACE_INT32_FORMAT_SPECIFIER ACE_TEXT ("%ld") +# endif /* defined (PRId32) */ +#endif /* ACE_INT32_FORMAT_SPECIFIER */ + +#if !defined (ACE_UINT32_FORMAT_SPECIFIER) +# if defined (PRIu32) +# define ACE_UINT32_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRIu32) +# elif ACE_SIZEOF_INT == 4 +# define ACE_UINT32_FORMAT_SPECIFIER ACE_TEXT ("%u") +# else +# define ACE_UINT32_FORMAT_SPECIFIER ACE_TEXT ("%lu") +# endif /* defined (PRIu32) */ +#endif /* ACE_UINT32_FORMAT_SPECIFIER */ + +#if !defined (ACE_INT64_FORMAT_SPECIFIER) +# if defined (PRId64) +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRId64) +# elif ACE_SIZEOF_LONG == 8 +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%ld") +# else +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%lld") +# endif /* defined (PRId64) */ +#endif /* ACE_INT64_FORMAT_SPECIFIER */ + +#if !defined (ACE_UINT64_FORMAT_SPECIFIER) +# if defined (PRIu64) +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%") ACE_TEXT (PRIu64) +# elif ACE_SIZEOF_LONG == 8 +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%lu") +# else +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%llu") +# endif /* defined (PRIu64) */ +#endif /* ACE_UINT64_FORMAT_SPECIFIER */ + +#if !defined (ACE_SSIZE_T_FORMAT_SPECIFIER) +# if defined (ACE_WIN64) +# define ACE_SSIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%I64d") +# else +# define ACE_SSIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%d") +# endif /* ACE_WIN64 */ +#endif /* ACE_SSIZE_T_FORMAT_SPECIFIER */ + +#if !defined (ACE_SIZE_T_FORMAT_SPECIFIER) +# if defined (ACE_WIN64) +# define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%I64u") +# else +# define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%u") +# endif /* ACE_WIN64 */ +#endif /* ACE_SIZE_T_FORMAT_SPECIFIER */ + +// Cast from UINT64 to a double requires an intermediate cast to INT64 +// on some platforms. +# if defined (ACE_LACKS_LONGLONG_T) + // Only use the low 32 bits. +# define ACE_UINT64_DBLCAST_ADAPTER(n) ACE_U64_TO_U32 (n) +# elif defined (ACE_LACKS_UNSIGNEDLONGLONG_T) +# define ACE_UINT64_DBLCAST_ADAPTER(n) ((n).to_int64 ()) +# elif defined (ACE_WIN32) +# define ACE_UINT64_DBLCAST_ADAPTER(n) static_cast<__int64> (n) +# else /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */ +# define ACE_UINT64_DBLCAST_ADAPTER(n) (n) +# endif /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */ + + +// The number of bytes in a float. +# ifndef ACE_SIZEOF_FLOAT +# if FLT_MAX_EXP == 128 +# define ACE_SIZEOF_FLOAT 4 +# elif FLT_MAX_EXP == 1024 +# define ACE_SIZEOF_FLOAT 8 +# else +# error: unsupported float size, must be updated for this platform! +# endif /* FLT_MAX_EXP */ +# endif /* ACE_SIZEOF_FLOAT */ + +// The number of bytes in a double. +# ifndef ACE_SIZEOF_DOUBLE +# if DBL_MAX_EXP == 128 +# define ACE_SIZEOF_DOUBLE 4 +# elif DBL_MAX_EXP == 1024 +# define ACE_SIZEOF_DOUBLE 8 +# else +# error: unsupported double size, must be updated for this platform! +# endif /* DBL_MAX_EXP */ +# endif /* ACE_SIZEOF_DOUBLE */ + +// The number of bytes in a long double. +# ifndef ACE_SIZEOF_LONG_DOUBLE +# if LDBL_MAX_EXP == 128 +# define ACE_SIZEOF_LONG_DOUBLE 4 +# elif LDBL_MAX_EXP == 1024 +# define ACE_SIZEOF_LONG_DOUBLE 8 +# elif LDBL_MAX_EXP == 16384 +# if defined (LDBL_DIG) && LDBL_DIG == 18 +# if defined (__ia64) || defined (__x86_64) +# define ACE_SIZEOF_LONG_DOUBLE 16 +# else /* ! __ia64 */ +# define ACE_SIZEOF_LONG_DOUBLE 12 +# endif /* __ia64 */ +# else /* ! LDBL_DIG || LDBL_DIG != 18 */ +# define ACE_SIZEOF_LONG_DOUBLE 16 +# endif /* ! LDBL_DIG || LDBL_DIG != 18 */ +# else +# error: unsupported double size, must be updated for this platform! +# endif /* LDBL_MAX_EXP */ +# endif /* ACE_SIZEOF_LONG_DOUBLE */ + +// Max and min sizes for the ACE integer types. +#define ACE_CHAR_MAX 0x7F +#define ACE_CHAR_MIN -(ACE_CHAR_MAX)-1 +#define ACE_OCTET_MAX 0xFF +#define ACE_INT16_MAX 0x7FFF +#define ACE_INT16_MIN -(ACE_INT16_MAX)-1 +#define ACE_UINT16_MAX 0xFFFF +#define ACE_WCHAR_MAX ACE_UINT16_MAX +#define ACE_INT32_MAX 0x7FFFFFFF +#define ACE_INT32_MIN -(ACE_INT32_MAX)-1 +#define ACE_UINT32_MAX 0xFFFFFFFF +#define ACE_INT64_MAX ACE_INT64_LITERAL(0x7FFFFFFFFFFFFFFF) +#define ACE_INT64_MIN -(ACE_INT64_MAX)-1 + +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) +// ACE_U_LongLong's constructor accepts a "long long" in this +// case. Set it to ACE_U_LongLong (-1) since the bit pattern for long +// long (-1) is the same as the maximum unsigned long long value. +# define ACE_UINT64_MAX ACE_U_LongLong (ACE_INT64_LITERAL (0xFFFFFFFFFFFFFFFF)) +#elif defined (ACE_LACKS_LONGLONG_T) +// ACE_U_LongLong's constructor accepts an ACE_UINT32 low and high +// pair of parameters. +# define ACE_UINT64_MAX ACE_U_LongLong (0xFFFFFFFFu, 0xFFFFFFFFu) +#else +# define ACE_UINT64_MAX ACE_UINT64_LITERAL (0xFFFFFFFFFFFFFFFF) +#endif /* ACE_LACKS_UNSIGNEDLONGLONG_T */ + +// These use ANSI/IEEE format. +#define ACE_FLT_MAX 3.402823466e+38F +#define ACE_FLT_MIN 1.175494351e-38F +#define ACE_DBL_MAX 1.7976931348623158e+308 +#define ACE_DBL_MIN 2.2250738585072014e-308 + +# if defined (__ACE_INLINE__) +# include "ace/Basic_Types.inl" +# endif /* __ACE_INLINE__ */ + +# include /**/ "ace/post.h" +#endif /* ACE_BASIC_TYPES_H */ diff --git a/dep/ACE_wrappers/ace/Basic_Types.inl b/dep/ACE_wrappers/ace/Basic_Types.inl new file mode 100644 index 000000000..c6f0013d4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Basic_Types.inl @@ -0,0 +1,954 @@ +// -*- C++ -*- +// +// $Id: Basic_Types.inl 80826 2008-03-04 14:51:23Z wotte $ + +# if !defined (ACE_LACKS_LONGLONG_T) && defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Implementation for ACE_U_LongLong when we have signed long long +// but no unsigned long long. + +ACE_INLINE +ACE_U_LongLong::ACE_U_LongLong (const long long value) + : data_ (value) +{ +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::hi (void) const +{ + return (data_ >> 32) & 0xFFFFFFFF; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::lo (void) const +{ + return data_ & 0xFFFFFFFF; +} + +ACE_INLINE void +ACE_U_LongLong::hi (const ACE_UINT32 hi) +{ + data_ = hi; + data_ <<= 32; +} + +ACE_INLINE void +ACE_U_LongLong::lo (const ACE_UINT32 lo) +{ + data_ = lo; +} + +ACE_INLINE long long +ACE_U_LongLong::to_int64 (void) const +{ + return data_; +} + +ACE_INLINE +ACE_U_LongLong::~ACE_U_LongLong (void) +{ +} + +ACE_INLINE bool +ACE_U_LongLong::operator== (const ACE_U_LongLong &n) const +{ + return data_ == n.data_; +} + +ACE_INLINE bool +ACE_U_LongLong::operator== (const ACE_UINT32 n) const +{ + return data_ == n; +} + +ACE_INLINE bool +ACE_U_LongLong::operator!= (const ACE_U_LongLong &n) const +{ + return ! (*this == n); +} + +ACE_INLINE bool +ACE_U_LongLong::operator!= (const ACE_UINT32 n) const +{ + return ! (*this == n); +} + +ACE_INLINE bool +ACE_U_LongLong::operator< (const ACE_U_LongLong &n) const +{ + if (data_ > 0) + if (n.data_ > 0) + return data_ < n.data_; + else + return true; + else + if (n.data_ > 0) + return false; + else + return data_ < n.data_; +} + +ACE_INLINE bool +ACE_U_LongLong::operator< (const ACE_UINT32 n) const +{ + return operator< (static_cast (n)); +} + +ACE_INLINE bool +ACE_U_LongLong::operator<= (const ACE_U_LongLong &n) const +{ + if (data_ == n.data_) return true; + + return data_ < n.data_; +} + +ACE_INLINE bool +ACE_U_LongLong::operator<= (const ACE_UINT32 n) const +{ + return operator<= (static_cast (n)); +} + +ACE_INLINE bool +ACE_U_LongLong::operator> (const ACE_U_LongLong &n) const +{ + if (data_ > 0) + if (n.data_ > 0) + return data_ > n.data_; + else + return false; + else + if (n.data_ > 0) + return true; + else + return data_ > n.data_; +} + +ACE_INLINE bool +ACE_U_LongLong::operator> (const ACE_UINT32 n) const +{ + return operator> (static_cast (n)); +} + +ACE_INLINE bool +ACE_U_LongLong::operator>= (const ACE_U_LongLong &n) const +{ + if (data_ == n.data_) return true; + + return data_ > n.data_; +} + +ACE_INLINE bool +ACE_U_LongLong::operator>= (const ACE_UINT32 n) const +{ + return operator>= (static_cast (n)); +} + +ACE_INLINE +ACE_U_LongLong::ACE_U_LongLong (const ACE_U_LongLong &n) + : data_ (n.data_) +{ +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator= (const ACE_U_LongLong &n) +{ + data_ = n.data_; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator= (const ACE_INT32 &rhs) +{ + if (rhs >= 0) + { + data_ = rhs; + data_ &= 0xFFFFFFFF; + } + else + { + // We do not handle the case where a negative 32 bit integer is + // assigned to this representation of a 64 bit unsigned integer. + // The "undefined behavior" behavior performed by this + // implementation is to simply set all bits to zero. + data_ = 0; + } + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator= (const ACE_UINT32 &rhs) +{ + data_ = rhs; + + return *this; +} + + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator+ (const ACE_U_LongLong &n) const +{ + return data_ + n.data_; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator+ (const ACE_UINT32 n) const +{ + return operator+ (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator- (const ACE_U_LongLong &n) const +{ + return data_ - n.data_; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator- (const ACE_UINT32 n) const +{ + return operator- (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator<< (const u_int n) const +{ + return data_ << n; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator<<= (const u_int n) +{ + data_ <<= n; + + return *this; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator>> (const u_int n) const +{ + return data_ >> n; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator>>= (const u_int n) +{ + data_ >>= n; + + return *this; +} + +ACE_INLINE double +ACE_U_LongLong::operator/ (const double n) const +{ + return data_ / n; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator+= (const ACE_U_LongLong &n) +{ + data_ += n.data_; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator+= (const ACE_UINT32 n) +{ + return operator+= (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator* (const ACE_UINT32 n) const +{ + return data_ * n; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator*= (const ACE_UINT32 n) +{ + data_ *= n; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator-= (const ACE_U_LongLong &n) +{ + data_ -= n.data_; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator-= (const ACE_UINT32 n) +{ + return operator-= (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator++ () +{ + ++data_; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator-- () +{ + --data_; + + return *this; +} + +ACE_INLINE const ACE_U_LongLong +ACE_U_LongLong::operator++ (int) +{ + // Post-increment operator should always be implemented in terms of + // the pre-increment operator to enforce consistent semantics. + ACE_U_LongLong temp (*this); + ++*this; + return temp; +} + +ACE_INLINE const ACE_U_LongLong +ACE_U_LongLong::operator-- (int) +{ + // Post-decrement operator should always be implemented in terms of + // the pre-decrement operator to enforce consistent semantics. + ACE_U_LongLong temp (*this); + --*this; + return temp; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator|= (const ACE_U_LongLong n) +{ + data_ |= n.data_; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator|= (const ACE_UINT32 n) +{ + return operator|= (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator&= (const ACE_U_LongLong n) +{ + data_ &= n.data_; + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator&= (const ACE_UINT32 n) +{ + return operator&= (static_cast (n)); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const ACE_UINT32 n) const +{ + return data_ / n; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator% (const ACE_UINT32 n) const +{ + return data_ % n; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator| (const ACE_INT32 n) const +{ + return data_ | n; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator& (const ACE_INT32 n) const +{ + return data_ & n; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator* (const ACE_INT32 n) const +{ + return operator* ((ACE_UINT32) n); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator*= (const ACE_INT32 n) +{ + return operator*= ((ACE_UINT32) n); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const ACE_INT32 n) const +{ + return operator/ ((ACE_UINT32) n); +} + +#if ACE_SIZEOF_INT == 4 +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const u_long n) const +{ + return operator/ ((ACE_UINT32) n); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const long n) const +{ + return operator/ ((ACE_UINT32) n); +} + +#else /* ACE_SIZEOF_INT != 4 */ +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const u_int n) const +{ + return operator/ ((ACE_UINT32) n); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const int n) const +{ + return operator/ ((ACE_UINT32) n); +} +#endif + +ACE_END_VERSIONED_NAMESPACE_DECL + +#elif defined (ACE_LACKS_LONGLONG_T) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_U_LongLong::ACE_U_LongLong (const ACE_UINT32 lo, const ACE_UINT32 hi) +{ + h_ () = hi; + l_ () = lo; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::hi (void) const +{ + return h_ (); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::lo (void) const +{ + return l_ (); +} + +ACE_INLINE void +ACE_U_LongLong::hi (const ACE_UINT32 hi) +{ + h_ () = hi; +} + +ACE_INLINE void +ACE_U_LongLong::lo (const ACE_UINT32 lo) +{ + l_ () = lo; +} + +ACE_INLINE +ACE_U_LongLong::~ACE_U_LongLong (void) +{ +} + +ACE_INLINE bool +ACE_U_LongLong::operator== (const ACE_U_LongLong &n) const +{ + return h_ () == n.h_ () && l_ () == n.l_ (); +} + +ACE_INLINE bool +ACE_U_LongLong::operator== (const ACE_UINT32 n) const +{ + return h_ () == 0 && l_ () == n; +} + +ACE_INLINE bool +ACE_U_LongLong::operator!= (const ACE_U_LongLong &n) const +{ + return ! (*this == n); +} + +ACE_INLINE bool +ACE_U_LongLong::operator!= (const ACE_UINT32 n) const +{ + return ! (*this == n); +} + +ACE_INLINE bool +ACE_U_LongLong::operator< (const ACE_U_LongLong &n) const +{ + return h_ () < n.h_ () ? 1 + : h_ () > n.h_ () ? 0 + : l_ () < n.l_ (); +} + +ACE_INLINE bool +ACE_U_LongLong::operator< (const ACE_UINT32 n) const +{ + return operator< (static_cast (n)); +} + +ACE_INLINE bool +ACE_U_LongLong::operator<= (const ACE_U_LongLong &n) const +{ + return h_ () < n.h_ () ? 1 + : h_ () > n.h_ () ? 0 + : l_ () <= n.l_ (); +} + +ACE_INLINE bool +ACE_U_LongLong::operator<= (const ACE_UINT32 n) const +{ + return operator<= (static_cast (n)); +} + +ACE_INLINE bool +ACE_U_LongLong::operator> (const ACE_U_LongLong &n) const +{ + return h_ () > n.h_ () ? 1 + : h_ () < n.h_ () ? 0 + : l_ () > n.l_ (); +} + +ACE_INLINE bool +ACE_U_LongLong::operator> (const ACE_UINT32 n) const +{ + return operator> (static_cast (n)); +} + +ACE_INLINE bool +ACE_U_LongLong::operator>= (const ACE_U_LongLong &n) const +{ + return h_ () > n.h_ () ? 1 + : h_ () < n.h_ () ? 0 + : l_ () >= n.l_ (); +} + +ACE_INLINE bool +ACE_U_LongLong::operator>= (const ACE_UINT32 n) const +{ + return operator>= (static_cast (n)); +} + +ACE_INLINE +ACE_U_LongLong::ACE_U_LongLong (const ACE_U_LongLong &n) +{ + h_ () = n.h_ (); + l_ () = n.l_ (); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator= (const ACE_U_LongLong &n) +{ + h_ () = n.h_ (); + l_ () = n.l_ (); + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator= (const ACE_INT32 &rhs) +{ + if (rhs >= 0) + { + l_ () = static_cast (rhs); + h_ () = 0; + } + else + { + // We do not handle the case where a negative 32 bit integer is + // assigned to this representation of a 64 bit unsigned integer. + // The "undefined behavior" behavior performed by this + // implementation is to simply set all bits to zero. + l_ () = 0; + h_ () = 0; + } + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator= (const ACE_UINT32 &rhs) +{ + l_ () = rhs; + h_ () = 0; + + return *this; +} + + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator+ (const ACE_U_LongLong &n) const +{ + ACE_U_LongLong ret (l_ () + n.l_ (), h_ () + n.h_ ()); + if (ret.l_ () < n.l_ ()) /* carry */ ++ret.h_ (); + + return ret; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator+ (const ACE_UINT32 n) const +{ + return operator+ (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator- (const ACE_U_LongLong &n) const +{ + ACE_U_LongLong ret (l_ () - n.l_ (), h_ () - n.h_ ()); + if (l_ () < n.l_ ()) /* borrow */ --ret.h_ (); + + return ret; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator- (const ACE_UINT32 n) const +{ + return operator- (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator<< (const u_int n) const +{ + const ACE_UINT32 carry_mask = l_ () >> (32 - n); + ACE_U_LongLong ret (n < 32 ? l_ () << n : 0, + n < 32 ? (h_ () << n) | carry_mask : carry_mask); + + return ret; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator<<= (const u_int n) +{ + const ACE_UINT32 carry_mask = l_ () >> (32 - n); + h_ () = n < 32 ? (h_ () << n) | carry_mask : carry_mask; + + // g++ 2.7.2.3/Solaris 2.5.1 doesn't modify l_ () if shifted by 32. + l_ () = n < 32 ? l_ () << n : 0; + + return *this; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator>> (const u_int n) const +{ + const ACE_UINT32 carry_mask = h_ () << (32 - n); + ACE_U_LongLong ret (n < 32 ? (l_ () >> n) | carry_mask : 0, + n < 32 ? h_ () >> n : 0); + + return ret; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator>>= (const u_int n) +{ + const ACE_UINT32 carry_mask = h_ () << (32 - n); + l_ () = n < 32 ? (l_ () >> n) | carry_mask : carry_mask; + h_ () = n < 32 ? h_ () >> n : 0; + + return *this; +} + +ACE_INLINE double +ACE_U_LongLong::operator/ (const double n) const +{ + // See the derivation above in operator/ (const ACE_UINT32). + + return ((double) 0xffffffffu - n + 1.0) / n * h_ () + + (double) h_ () + (double) l_ () / n; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator+= (const ACE_U_LongLong &n) +{ + h_ () += n.h_ (); + l_ () += n.l_ (); + if (l_ () < n.l_ ()) /* carry */ ++h_ (); + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator+= (const ACE_UINT32 n) +{ + return operator+= (static_cast (n)); +} + +#define ACE_HIGHBIT (~(~0UL >> 1)) + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::ul_shift (ACE_UINT32 a, ACE_UINT32 c_in, ACE_UINT32 *c_out) const +{ + const ACE_UINT32 b = (a << 1) | c_in; + *c_out = (*c_out << 1) + ((a & ACE_HIGHBIT) > 0); + + return b; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::ull_shift (ACE_U_LongLong a, + ACE_UINT32 c_in, + ACE_UINT32 *c_out) const +{ + ACE_U_LongLong b; + + b.l_ () = (a.l_ () << 1) | c_in; + c_in = ((a.l_ () & ACE_HIGHBIT) > 0); + b.h_ () = (a.h_ () << 1) | c_in; + *c_out = (*c_out << 1) + ((a.h_ () & ACE_HIGHBIT) > 0); + + return b; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::ull_add (ACE_U_LongLong a, ACE_U_LongLong b, ACE_UINT32 *carry) const +{ + ACE_U_LongLong r (0, 0); + ACE_UINT32 c1, c2, c3, c4; + + c1 = a.l_ () % 2; + c2 = b.l_ () % 2; + c3 = 0; + + r.l_ () = a.l_ ()/2 + b.l_ ()/2 + (c1+c2)/2; + r.l_ () = ul_shift (r.l_ (), (c1+c2)%2, &c3); + + c1 = a.h_ () % 2; + c2 = b.h_ () % 2; + c4 = 0; + + r.h_ () = a.h_ ()/2 + b.h_ ()/2 + (c1+c2+c3)/2; + r.h_ () = ul_shift (r.h_ (), (c1+c2+c3)%2, &c4); + + *carry = c4; + + return r; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::ull_mult (ACE_U_LongLong a, ACE_UINT32 b, ACE_UINT32 *carry) const +{ + register ACE_UINT32 mask = ACE_HIGHBIT; + const ACE_U_LongLong zero (0, 0); + ACE_U_LongLong accum (0, 0); + ACE_UINT32 c; + + *carry = 0; + if (b > 0) + do + { + accum = ull_shift (accum, 0U, carry); + if (b & mask) + accum = ull_add (accum, a, &c); + else + accum = ull_add (accum, zero, &c); + *carry += c; + mask >>= 1; + } + while (mask > 0); + + return accum; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator* (const ACE_UINT32 n) const +{ + ACE_UINT32 carry; // will throw the carry away + + return ull_mult (*this, n, &carry); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator*= (const ACE_UINT32 n) +{ + ACE_UINT32 carry; // will throw the carry away + + return *this = ull_mult (*this, n, &carry); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator-= (const ACE_U_LongLong &n) +{ + h_ () -= n.h_ (); + if (l_ () < n.l_ ()) /* borrow */ --h_ (); + l_ () -= n.l_ (); + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator-= (const ACE_UINT32 n) +{ + return operator-= (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator++ () +{ + ++l_ (); + if (l_ () == 0) /* carry */ ++h_ (); + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator-- () +{ + if (l_ () == 0) /* borrow */ --h_ (); + --l_ (); + + return *this; +} + +ACE_INLINE const ACE_U_LongLong +ACE_U_LongLong::operator++ (int) +{ + // Post-increment operator should always be implemented in terms of + // the pre-increment operator to enforce consistent semantics. + ACE_U_LongLong temp (*this); + ++*this; + return temp; +} + +ACE_INLINE const ACE_U_LongLong +ACE_U_LongLong::operator-- (int) +{ + // Post-decrement operator should always be implemented in terms of + // the pre-decrement operator to enforce consistent semantics. + ACE_U_LongLong temp (*this); + --*this; + return temp; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator|= (const ACE_U_LongLong n) +{ + l_ () |= n.l_ (); + h_ () |= n.h_ (); + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator|= (const ACE_UINT32 n) +{ + return operator|= (static_cast (n)); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator&= (const ACE_U_LongLong n) +{ + l_ () &= n.l_ (); + h_ () &= n.h_ (); + + return *this; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator&= (const ACE_UINT32 n) +{ + return operator&= (static_cast (n)); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const ACE_UINT32 n) const +{ + // This takes advantage of the fact that the return type has only 32 + // bits. Replace 0x100000000 with 0xffffffff + 1 because the former + // has 33 bits. + // Quotient = (0x100000000u * hi_ + lo_) / n + // = ((0x100000000u - n + n) * hi_ + lo_) / n + // = ((0x100000000u - n) / n * hi_ + hi_ * n / n + lo_ / n + // = (0x100000000u - n) / n * hi_ + hi_ + lo_ / n + // = (0xffffffffu - n + 1) / n * hi_ + hi_ + lo_ / n + + return (0xffffffffu - n + 1) / n * h_ () + h_ () + l_ () / n; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator% (const ACE_UINT32 n) const +{ + // Because the argument is an ACE_UINT32, the result can never be + // bigger than 32 bits. Replace 0x100000000 with 0xffffffff + 1 + // because the former has 33 bits. + // Mod = (0x100000000u * hi_ + lo_) % n + // = (0x100000000u % n * hi_ + lo_ % n) % n + // = ((0x100000000u - n) % n * hi_ + lo_ % n) % n + // = ((0xffffffffu - n + 1) % n * hi_ + lo_ % n) % n + + return ((0xffffffff - n + 1) % n * h_ () + l_ () % n) % n; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator| (const ACE_INT32 n) const +{ + return l_ () | n; +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator& (const ACE_INT32 n) const +{ + return l_ () & n; +} + +ACE_INLINE ACE_U_LongLong +ACE_U_LongLong::operator* (const ACE_INT32 n) const +{ + return operator* ((ACE_UINT32) n); +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator*= (const ACE_INT32 n) +{ + return operator*= ((ACE_UINT32) n); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const ACE_INT32 n) const +{ + return operator/ ((ACE_UINT32) n); +} + +#if ACE_SIZEOF_INT == 4 +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const u_long n) const +{ + return operator/ ((ACE_UINT32) n); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const long n) const +{ + return operator/ ((ACE_UINT32) n); +} + +#else /* ACE_SIZEOF_INT != 4 */ +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const u_int n) const +{ + return operator/ ((ACE_UINT32) n); +} + +ACE_INLINE ACE_UINT32 +ACE_U_LongLong::operator/ (const int n) const +{ + return operator/ ((ACE_UINT32) n); +} +#endif /* ACE_SIZEOF_INT != 4 */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */ diff --git a/dep/ACE_wrappers/ace/Bound_Ptr.h b/dep/ACE_wrappers/ace/Bound_Ptr.h new file mode 100644 index 000000000..ec7384e0d --- /dev/null +++ b/dep/ACE_wrappers/ace/Bound_Ptr.h @@ -0,0 +1,388 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Bound_Ptr.h + * + * $Id: Bound_Ptr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Christopher Kohlhoff + * @author Boris Kolpackov + */ +//============================================================================= + +#ifndef ACE_BOUND_PTR_H +#define ACE_BOUND_PTR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Auto_Ptr.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Bound_Ptr_Counter + * + * @brief An ACE_Bound_Ptr_Counter object encapsulates an + * object reference count. + * + * Do not use this class directly, use ACE_Strong_Bound_Ptr or + * ACE_Weak_Bound_Ptr instead. + */ +template +class ACE_Bound_Ptr_Counter +{ +public: + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + ACE_Bound_Ptr_Counter (long init_obj_ref_count = 0); + ~ACE_Bound_Ptr_Counter (void); + + /// Create a ACE_Bound_Ptr_Counter and initialize the + /// reference count to indicate ownership by a strong pointer. + static ACE_Bound_Ptr_Counter *create_strong (void); + + /// Increase both the object and counter reference counts and return + /// the new object reference count. A return value of -1 indicates + /// that the object has already been destroyed. + static long attach_strong (ACE_Bound_Ptr_Counter *counter); + + /// Decreases both the object and counter reference counts and + /// deletes whichever has no more references. Returns the new object + /// reference count. + static long detach_strong (ACE_Bound_Ptr_Counter *counter); + + /// Create a ACE_Bound_Ptr_Counter and initialize the + /// reference count to indicate no ownership. + static ACE_Bound_Ptr_Counter *create_weak (void); + + /// Increase the counter reference count and return argument. + static void attach_weak (ACE_Bound_Ptr_Counter *counter); + + /// Decreases the counter reference count and deletes the counter if + /// it has no more references. + static void detach_weak (ACE_Bound_Ptr_Counter *counter); + + /// Determine whether the object has been deleted. + static bool object_was_deleted (ACE_Bound_Ptr_Counter *counter); + +private: + + /// Allocate a new ACE_Bound_Ptr_Counter instance, + /// returning NULL if it cannot be created. + static ACE_Bound_Ptr_Counter *internal_create (long init_obj_ref_count); + +private: + + /// Reference count of underlying object. Is set to -1 once the + /// object has been destroyed to indicate to all weak pointers that + /// it is no longer valid. + long obj_ref_count_; + + /// Reference count of this counter. + long self_ref_count_; + + /// Mutex variable to synchronize access to the reference counts. + ACE_LOCK lock_; +}; + +// Forward decl. +template class ACE_Weak_Bound_Ptr; + +/** + * @class ACE_Strong_Bound_Ptr + * + * @brief This class implements support for a reference counted + * pointer. + * + * Assigning or copying instances of an ACE_Strong_Bound_Ptr will + * automatically increment the reference count of the underlying object. + * When the last instance of an ACE_Strong_Bound_Ptr that references a + * particular object is destroyed or overwritten, it will invoke delete + * on its underlying pointer. + */ +template +class ACE_Strong_Bound_Ptr +{ +public: + /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the + /// object \ immediately. + explicit ACE_Strong_Bound_Ptr (X *p = 0); + + /// Constructor that initializes an ACE_Strong_Bound_Ptr by stealing + /// ownership of an object from an auto_ptr. + explicit ACE_Strong_Bound_Ptr (auto_ptr p); + + /// Copy constructor binds @c this and @a r to the same object. + ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr &r); + + /// Constructor binds @c this and @a r to the same object. + ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr &r); + + /// Copy constructor binds @c this and @a r to the same object if + /// Y* can be implicitly converted to X*. + template + ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr &r) + : counter_ (r.counter_), + ptr_ (dynamic_cast(r.ptr_)) + { + // This ctor is temporarily defined here to increase our chances + // of being accepted by broken compilers. + // + COUNTER::attach_strong (this->counter_); + } + + /// Destructor. + ~ACE_Strong_Bound_Ptr (void); + + /// Assignment operator that binds @c this and @a r to the same object. + void operator = (const ACE_Strong_Bound_Ptr &r); + + /// Assignment operator that binds @c this and @a r to the same object. + void operator = (const ACE_Weak_Bound_Ptr &r); + + /// Assignment operator that binds @c this and @a r to the same object + /// if Y* can be implicitly converted to X*. + template + ACE_Weak_Bound_Ptr& + operator= (const ACE_Strong_Bound_Ptr &r) + { + // This operator is temporarily defined here to increase our chances + // of being accepted by broken compilers. + // + + // This will work if &r == this, by first increasing the ref count + + COUNTER *new_counter = r.counter_; + X* new_ptr = dynamic_cast (r.ptr_); + COUNTER::attach_strong (new_counter); + if (COUNTER::detach_strong (this->counter_) == 0) + delete this->ptr_; + this->counter_ = new_counter; + this->ptr_ = new_ptr; + + return *this; + } + + /// Equality operator that returns @c true if both + /// ACE_Strong_Bound_Ptr instances point to the same underlying + /// object. + /** + * @note It also returns @c true if both objects have just been + * instantiated and not used yet. + */ + bool operator == (const ACE_Strong_Bound_Ptr &r) const; + + /// Equality operator that returns true if the ACE_Strong_Bound_Ptr + /// and ACE_Weak_Bound_Ptr objects point to the same underlying + /// object. + /** + * @note It also returns @c true if both objects have just been + * instantiated and not used yet. + */ + bool operator == (const ACE_Weak_Bound_Ptr &r) const; + + /// Equality operator that returns @c true if the + /// ACE_Strong_Bound_Ptr and the raw pointer point to the same + /// underlying object. + bool operator == (X *p) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (const ACE_Strong_Bound_Ptr &r) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (const ACE_Weak_Bound_Ptr &r) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (X *p) const; + + /// Redirection operator + X *operator-> (void) const; + + /// Dereference operator + X &operator * (void) const; + + /// Get the pointer value. + X *get (void) const; + + /// Resets the ACE_Strong_Bound_Ptr to refer to a different + /// underlying object. + void reset (X *p = 0); + + /// Resets the ACE_Strong_Bound_Ptr to refer to a different + /// underlying object, ownership of which is stolen from the + /// auto_ptr. + void reset (auto_ptr p); + + /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr + /// objects. + int null (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + typedef X X_t; // This indirection is for Borland C++. + + friend class ACE_Weak_Bound_Ptr; + + template + friend class ACE_Strong_Bound_Ptr; + + /// The ACE_Bound_Ptr_Counter type. + typedef ACE_Bound_Ptr_Counter COUNTER; + + /// The reference counter. + COUNTER *counter_; + + /// The underlying object. + X *ptr_; +}; + +/** + * @class ACE_Weak_Bound_Ptr + * + * @brief This class implements support for a weak pointer that complements + * ACE_Strong_Bound_Ptr. + * + * Unlike ACE_Strong_Bound_Ptr, assigning or copying instances of an + * ACE_Weak_Bound_Ptr will not automatically increment the reference + * count of the underlying object. What ACE_Weak_Bound_Ptr does is + * preserve the knowledge that the object is in fact reference + * counted, and thus provides an alternative to raw pointers where + * non-ownership associations must be maintained. When the last + * instance of an ACE_Strong_Bound_Ptr that references a particular + * object is destroyed or overwritten, the corresponding + * ACE_Weak_Bound_Ptr instances are set to NULL. + */ +template +class ACE_Weak_Bound_Ptr +{ +public: + /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to + /// the object \ immediately. + explicit ACE_Weak_Bound_Ptr (X *p = 0); + + /// Copy constructor binds @c this and @a r to the same object. + ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr &r); + + /// Constructor binds @c this and @a r to the same object. + ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr &r); + + /// Destructor. + ~ACE_Weak_Bound_Ptr (void); + + /// Assignment operator that binds @c this and @a r to the same object. + void operator = (const ACE_Weak_Bound_Ptr &r); + + /// Assignment operator that binds @c this and @a r to the same object. + void operator = (const ACE_Strong_Bound_Ptr &r); + + /// Equality operator that returns @c true if both + /// ACE_Weak_Bound_Ptr objects point to the same underlying object. + /** + * @note It also returns @c true if both objects have just been + * instantiated and not used yet. + */ + bool operator == (const ACE_Weak_Bound_Ptr &r) const; + + /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr + /// and ACE_Strong_Bound_Ptr objects point to the same underlying + /// object. + /** + * @note It also returns @c true if both objects have just been + * instantiated and not used yet. + */ + bool operator == (const ACE_Strong_Bound_Ptr &r) const; + + /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr + /// and the raw pointer point to the same underlying object. + bool operator == (X *p) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (const ACE_Weak_Bound_Ptr &r) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (const ACE_Strong_Bound_Ptr &r) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (X *p) const; + + /// Redirection operator. + /** + * It returns a temporary strong pointer and makes use of the + * chaining properties of operator-> to ensure that the underlying + * object does not disappear while you are using it. If you are + * certain of the lifetimes of the object, and do not want to incur + * the locking overhead, then use the unsafe_get method instead. + */ + ACE_Strong_Bound_Ptr operator-> (void) const; + + /// Obtain a strong pointer corresponding to this weak pointer. This + /// function is useful to create a temporary strong pointer for + /// conversion to a reference. + ACE_Strong_Bound_Ptr strong (void) const; + + /// Get the pointer value. Warning: this does not affect the + /// reference count of the underlying object, so it may disappear on + /// you while you are using it if you are not careful. + X *unsafe_get (void) const; + + /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying + /// object. + void reset (X *p = 0); + + /// Increment the reference count on the underlying object. + /** + * Returns the new reference count on the object. This function may + * be used to integrate the bound pointers into an external + * reference counting mechanism such as those used by COM or CORBA + * servants. + */ + long add_ref (void); + + /// Decrement the reference count on the underlying object, which is deleted + /// if the count has reached zero. + /** + * Returns the new reference count on the object. This function may + * be used to integrate the bound pointers into an external + * reference counting mechanism such as those used by COM or CORBA + * servants. + */ + long remove_ref (void); + + /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects. + int null (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + typedef X X_t; // This indirection is for Borland C++. + + friend class ACE_Strong_Bound_Ptr; + + /// The ACE_Bound_Ptr_Counter type. + typedef ACE_Bound_Ptr_Counter COUNTER; + + /// The reference counter. + COUNTER *counter_; + + /// The underlying object. + X *ptr_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include "ace/Bound_Ptr.inl" + +#include /**/ "ace/post.h" + +#endif /* ACE_BOUND_PTR_H */ diff --git a/dep/ACE_wrappers/ace/Bound_Ptr.inl b/dep/ACE_wrappers/ace/Bound_Ptr.inl new file mode 100644 index 000000000..540a5516e --- /dev/null +++ b/dep/ACE_wrappers/ace/Bound_Ptr.inl @@ -0,0 +1,494 @@ +/* -*- C++ -*- */ +// $Id: Bound_Ptr.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Bound_Ptr.i + +#include "ace/Guard_T.h" +#if !defined (ACE_NEW_THROWS_EXCEPTIONS) +# include "ace/Log_Msg.h" +#endif /* ACE_NEW_THROWS_EXCEPTIONS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template inline ACE_Bound_Ptr_Counter * +ACE_Bound_Ptr_Counter::internal_create (long init_obj_ref_count) +{ + ACE_Bound_Ptr_Counter *temp = 0; + ACE_NEW_RETURN (temp, + ACE_Bound_Ptr_Counter (init_obj_ref_count), + 0); + return temp; +} + +template inline ACE_Bound_Ptr_Counter * +ACE_Bound_Ptr_Counter::create_strong (void) +{ + // Set initial object reference count to 1. + ACE_Bound_Ptr_Counter *temp = internal_create (1); +#if defined (ACE_NEW_THROWS_EXCEPTIONS) + if (temp == 0) + ACE_throw_bad_alloc; +#else + ACE_ASSERT (temp != 0); +#endif /* ACE_NEW_THROWS_EXCEPTIONS */ + return temp; +} + + + +template inline long +ACE_Bound_Ptr_Counter::attach_strong (ACE_Bound_Ptr_Counter* counter) +{ + ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1); + + // Can't attach a strong pointer to an object that has already been deleted. + if (counter->obj_ref_count_ == -1) + return -1; + + long new_obj_ref_count = ++counter->obj_ref_count_; + ++counter->self_ref_count_; + + return new_obj_ref_count; +} + +template inline long +ACE_Bound_Ptr_Counter::detach_strong (ACE_Bound_Ptr_Counter* counter) +{ + ACE_Bound_Ptr_Counter *counter_del = 0; + long new_obj_ref_count; + + { + ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1); + + if ((new_obj_ref_count = --counter->obj_ref_count_) == 0) + // Change the object reference count to -1 to indicate that the + // object has been deleted, as opposed to a weak pointer that + // simply hasn't had any strong pointers created from it yet. + counter->obj_ref_count_ = -1; + + if (--counter->self_ref_count_ == 0) + // Since counter contains the lock held by the ACE_Guard, the + // guard needs to be released before freeing the memory holding + // the lock. So save the pointer to free, then release, then + // free. + counter_del = counter; + + } // Release the lock + + delete counter_del; + + return new_obj_ref_count; +} + +template inline ACE_Bound_Ptr_Counter * +ACE_Bound_Ptr_Counter::create_weak (void) +{ + // Set initial object reference count to 0. + + ACE_Bound_Ptr_Counter *temp = internal_create (0); +#if defined (ACE_NEW_THROWS_EXCEPTIONS) + if (temp == 0) + ACE_throw_bad_alloc; +#else + ACE_ASSERT (temp != 0); +#endif /* ACE_NEW_THROWS_EXCEPTIONS */ + return temp; +} + +template inline void +ACE_Bound_Ptr_Counter::attach_weak (ACE_Bound_Ptr_Counter* counter) +{ + ACE_GUARD (ACE_LOCK, guard, counter->lock_); + + ++counter->self_ref_count_; +} + +template inline void +ACE_Bound_Ptr_Counter::detach_weak (ACE_Bound_Ptr_Counter* counter) +{ + ACE_Bound_Ptr_Counter *counter_del = 0; + + { + ACE_GUARD (ACE_LOCK, guard, counter->lock_); + + if (--counter->self_ref_count_ == 0) + // Since counter contains the lock held by the ACE_Guard, the + // guard needs to be released before freeing the memory holding + // the lock. So save the pointer to free, then release, then + // free. + counter_del = counter; + + } // Release the lock + + delete counter_del; +} + +template inline bool +ACE_Bound_Ptr_Counter::object_was_deleted (ACE_Bound_Ptr_Counter *counter) +{ + ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0); + + return counter->obj_ref_count_ == -1; +} + +template inline +ACE_Bound_Ptr_Counter::ACE_Bound_Ptr_Counter (long init_obj_ref_count) + : obj_ref_count_ (init_obj_ref_count), + self_ref_count_ (1) +{ +} + +template inline +ACE_Bound_Ptr_Counter::~ACE_Bound_Ptr_Counter (void) +{ +} + +template inline +ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (X *p) + : counter_ (COUNTER::create_strong ()), + ptr_ (p) +{ +} + +template inline +ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (auto_ptr p) + : counter_ (COUNTER::create_strong ()), + ptr_ (p.release()) +{ +} + +template inline +ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr &r) + : counter_ (r.counter_), + ptr_ (r.ptr_) +{ + COUNTER::attach_strong (this->counter_); +} + +template inline +ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr &r) + : counter_ (r.counter_), + ptr_ (r.ptr_) +{ + // When creating a strong pointer from a weak one we can't assume that the + // underlying object still exists. Therefore we must check for a return value + // of -1, which indicates that the object has been destroyed. + if (COUNTER::attach_strong (this->counter_) == -1) + { + // Underlying object has already been deleted, so set this pointer to null. + this->counter_ = COUNTER::create_strong (); + this->ptr_ = 0; + } +} + +template inline +ACE_Strong_Bound_Ptr::~ACE_Strong_Bound_Ptr (void) +{ + if (COUNTER::detach_strong (this->counter_) == 0) + delete this->ptr_; +} + +template inline void +ACE_Strong_Bound_Ptr::operator = (const ACE_Strong_Bound_Ptr &rhs) +{ + // This will work if &r == this, by first increasing the ref count, but + // why go through all that? + if (&rhs == this) + return; + + COUNTER *new_counter = rhs.counter_; + X_t *new_ptr = rhs.ptr_; + COUNTER::attach_strong (new_counter); + if (COUNTER::detach_strong (this->counter_) == 0) + delete this->ptr_; + this->counter_ = new_counter; + this->ptr_ = new_ptr; +} + +template inline void +ACE_Strong_Bound_Ptr::operator = (const ACE_Weak_Bound_Ptr &rhs) +{ + // This will work if &r == this, by first increasing the ref count, but + // why go through all that? + if (&rhs == this) + return; + + COUNTER *new_counter = rhs.counter_; + X_t *new_ptr = rhs.ptr_; + + // When creating a strong pointer from a weak one we can't assume that the + // underlying object still exists. Therefore we must check for a return value + // of -1, which indicates that the object has been destroyed. + if (COUNTER::attach_strong (new_counter) == -1) + { + // Underlying object has already been deleted, so set this pointer to null. + new_counter = COUNTER::create_strong (); + new_ptr = 0; + } + + if (COUNTER::detach_strong (this->counter_) == 0) + delete this->ptr_; + this->counter_ = new_counter; + this->ptr_ = new_ptr; +} + +template inline bool +ACE_Strong_Bound_Ptr::operator== (const ACE_Strong_Bound_Ptr &r) const +{ + return this->ptr_ == r.ptr_; +} + +template inline bool +ACE_Strong_Bound_Ptr::operator== (const ACE_Weak_Bound_Ptr &r) const +{ + // Use the weak pointer's operator== since it will check for null. + return r == *this; +} + +template inline bool +ACE_Strong_Bound_Ptr::operator== (X *p) const +{ + return this->ptr_ == p; +} + +template inline bool +ACE_Strong_Bound_Ptr::operator!= (const ACE_Strong_Bound_Ptr &r) const +{ + return this->ptr_ != r.ptr_; +} + +template inline bool +ACE_Strong_Bound_Ptr::operator!= (const ACE_Weak_Bound_Ptr &r) const +{ + // Use the weak pointer's operator!= since it will check for null. + return r != *this; +} + +template inline bool +ACE_Strong_Bound_Ptr::operator!= (X *p) const +{ + return this->ptr_ != p; +} + +template inline X * +ACE_Strong_Bound_Ptr::operator-> (void) const +{ + return this->ptr_; +} + +template inline X & +ACE_Strong_Bound_Ptr::operator *() const +{ + return *this->ptr_; +} + +template inline X* +ACE_Strong_Bound_Ptr::get (void) const +{ + return this->ptr_; +} + +template inline int +ACE_Strong_Bound_Ptr::null (void) const +{ + return this->ptr_ == 0; +} + +template inline void +ACE_Strong_Bound_Ptr::reset (X *p) +{ + COUNTER *old_counter = this->counter_; + X_t *old_ptr = this->ptr_; + this->counter_ = COUNTER::create_strong (); + this->ptr_ = p; + if (COUNTER::detach_strong (old_counter) == 0) + delete old_ptr; +} + +template inline void +ACE_Strong_Bound_Ptr::reset (auto_ptr p) +{ + COUNTER *old_counter = this->counter_; + X_t *old_ptr = this->ptr_; + this->counter_ = COUNTER::create_strong (); + this->ptr_ = p.release (); + if (COUNTER::detach_strong (old_counter) == 0) + delete old_ptr; +} + +template inline +ACE_Weak_Bound_Ptr::ACE_Weak_Bound_Ptr (X *p) + : counter_ (COUNTER::create_weak ()), + ptr_ (p) +{ +} + +template inline +ACE_Weak_Bound_Ptr::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr &r) + : counter_ (r.counter_), + ptr_ (r.ptr_) +{ + COUNTER::attach_weak (this->counter_); +} + +template inline +ACE_Weak_Bound_Ptr::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr &r) + : counter_ (r.counter_), + ptr_ (r.ptr_) +{ + COUNTER::attach_weak (this->counter_); +} + +template inline +ACE_Weak_Bound_Ptr::~ACE_Weak_Bound_Ptr (void) +{ + COUNTER::detach_weak (this->counter_); +} + +template inline void +ACE_Weak_Bound_Ptr::operator = (const ACE_Weak_Bound_Ptr &rhs) +{ + // This will work if &rhs == this, by first increasing the ref count + COUNTER *new_counter = rhs.counter_; + COUNTER::attach_weak (new_counter); + COUNTER::detach_weak (this->counter_); + this->counter_ = new_counter; + this->ptr_ = rhs.ptr_; +} + +template inline void +ACE_Weak_Bound_Ptr::operator = (const ACE_Strong_Bound_Ptr &rhs) +{ + // This will work if &rhs == this, by first increasing the ref count + COUNTER *new_counter = rhs.counter_; + COUNTER::attach_weak (new_counter); + COUNTER::detach_weak (this->counter_); + this->counter_ = new_counter; + this->ptr_ = rhs.ptr_; +} + +template inline bool +ACE_Weak_Bound_Ptr::operator== (const ACE_Weak_Bound_Ptr &r) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return r.ptr_ == 0; + + return this->ptr_ == r.ptr_; +} + +template inline bool +ACE_Weak_Bound_Ptr::operator== (const ACE_Strong_Bound_Ptr &r) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return r.ptr_ == 0; + + return this->ptr_ == r.ptr_; +} + +template inline bool +ACE_Weak_Bound_Ptr::operator== (X *p) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return p == 0; + + return this->ptr_ == p; +} + +template inline bool +ACE_Weak_Bound_Ptr::operator!= (const ACE_Weak_Bound_Ptr &r) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return r.ptr_ != 0; + + return this->ptr_ != r.ptr_; +} + +template inline bool +ACE_Weak_Bound_Ptr::operator!= (const ACE_Strong_Bound_Ptr &r) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return r.ptr_ != 0; + + return this->ptr_ != r.ptr_; +} + +template inline bool +ACE_Weak_Bound_Ptr::operator!= (X *p) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return p != 0; + + return this->ptr_ != p; +} + +template inline ACE_Strong_Bound_Ptr +ACE_Weak_Bound_Ptr::operator-> (void) const +{ + return ACE_Strong_Bound_Ptr (*this); +} + +template inline ACE_Strong_Bound_Ptr +ACE_Weak_Bound_Ptr::strong (void) const +{ + return ACE_Strong_Bound_Ptr (*this); +} + +template inline X* +ACE_Weak_Bound_Ptr::unsafe_get (void) const +{ + // We do not check if the object has been deleted, since this operation + // is defined to be unsafe! + return this->ptr_; +} + +template inline int +ACE_Weak_Bound_Ptr::null (void) const +{ + // A weak pointer must behave as though it is automatically set to null + // if the underlying object has been deleted. + if (COUNTER::object_was_deleted (this->counter_)) + return 1; + + return this->ptr_ == 0; +} + +template inline void +ACE_Weak_Bound_Ptr::reset (X *p) +{ + COUNTER *old_counter = this->counter_; + this->counter_ = COUNTER::create_weak (); + this->ptr_ = p; + COUNTER::detach_weak (old_counter); +} + +template inline long +ACE_Weak_Bound_Ptr::add_ref () +{ + return COUNTER::attach_strong (counter_); +} + +template inline long +ACE_Weak_Bound_Ptr::remove_ref () +{ + long new_obj_ref_count = COUNTER::detach_strong (counter_); + if (new_obj_ref_count == 0) + { + delete this->ptr_; + this->ptr_ = 0; + } + return new_obj_ref_count; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/CDR_Base.cpp b/dep/ACE_wrappers/ace/CDR_Base.cpp new file mode 100644 index 000000000..dab8978fd --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Base.cpp @@ -0,0 +1,799 @@ +#include "ace/CDR_Base.h" + +#if !defined (__ACE_INLINE__) +# include "ace/CDR_Base.inl" +#endif /* ! __ACE_INLINE__ */ + +#include "ace/Message_Block.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ace, + CDR_Base, + "$Id: CDR_Base.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined (NONNATIVE_LONGDOUBLE) +static const ACE_INT16 max_eleven_bit = 0x3ff; +static const ACE_INT16 max_fifteen_bit = 0x3fff; +#endif /* NONNATIVE_LONGDOUBLE */ + +// +// See comments in CDR_Base.inl about optimization cases for swap_XX_array. +// + +void +ACE_CDR::swap_2_array (char const * orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + + // We pretend that AMD64/GNU G++ systems have a Pentium CPU to + // take advantage of the inline assembly implementation. + + // Later, we try to read in 32 or 64 bit chunks, + // so make sure we don't do that for unaligned addresses. +#if ACE_SIZEOF_LONG == 8 && \ + !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__)) + char const * const o8 = ACE_ptr_align_binary (orig, 8); + while (orig < o8 && n > 0) + { + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + --n; + } +#else + char const * const o4 = ACE_ptr_align_binary (orig, 4); + // this is an _if_, not a _while_. The mistmatch can only be by 2. + if (orig != o4) + { + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + --n; + } +#endif + if (n == 0) + return; + + // + // Loop unrolling. Here be dragons. + // + + // (n & (~3)) is the greatest multiple of 4 not bigger than n. + // In the while loop ahead, orig will move over the array by 8 byte + // increments (4 elements of 2 bytes). + // end marks our barrier for not falling outside. + char const * const end = orig + 2 * (n & (~3)); + + // See if we're aligned for writting in 64 or 32 bit chunks... +#if ACE_SIZEOF_LONG == 8 && \ + !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__)) + if (target == ACE_ptr_align_binary (target, 8)) +#else + if (target == ACE_ptr_align_binary (target, 4)) +#endif + { + while (orig < end) + { +#if defined (ACE_HAS_INTEL_ASSEMBLY) + unsigned int a = + * reinterpret_cast (orig); + unsigned int b = + * reinterpret_cast (orig + 4); + asm ( "bswap %1" : "=r" (a) : "0" (a) ); + asm ( "bswap %1" : "=r" (b) : "0" (b) ); + asm ( "rol $16, %1" : "=r" (a) : "0" (a) ); + asm ( "rol $16, %1" : "=r" (b) : "0" (b) ); + * reinterpret_cast (target) = a; + * reinterpret_cast (target + 4) = b; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ecx, orig; + __asm mov edx, target; + __asm mov eax, [ecx]; + __asm mov ebx, 4[ecx]; + __asm bswap eax; + __asm bswap ebx; + __asm rol eax, 16; + __asm rol ebx, 16; + __asm mov [edx], eax; + __asm mov 4[edx], ebx; +#elif ACE_SIZEOF_LONG == 8 + // 64 bit architecture. + register unsigned long a = + * reinterpret_cast (orig); + + register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; + register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; + + a = (a1 | a2); + + * reinterpret_cast (target) = a; +#else + register ACE_UINT32 a = + * reinterpret_cast (orig); + register ACE_UINT32 b = + * reinterpret_cast (orig + 4); + + register ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8; + register ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8; + register ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8; + register ACE_UINT32 b2 = (b & 0xff00ff00U) >> 8; + + a = (a1 | a2); + b = (b1 | b2); + + * reinterpret_cast (target) = a; + * reinterpret_cast (target + 4) = b; +#endif + orig += 8; + target += 8; + } + } + else + { + // We're out of luck. We have to write in 2 byte chunks. + while (orig < end) + { +#if defined (ACE_HAS_INTEL_ASSEMBLY) + unsigned int a = + * reinterpret_cast (orig); + unsigned int b = + * reinterpret_cast (orig + 4); + asm ( "bswap %1" : "=r" (a) : "0" (a) ); + asm ( "bswap %1" : "=r" (b) : "0" (b) ); + // We're little endian. + * reinterpret_cast (target + 2) + = (unsigned short) (a & 0xffff); + * reinterpret_cast (target + 6) + = (unsigned short) (b & 0xffff); + asm ( "shrl $16, %1" : "=r" (a) : "0" (a) ); + asm ( "shrl $16, %1" : "=r" (b) : "0" (b) ); + * reinterpret_cast (target + 0) + = (unsigned short) (a & 0xffff); + * reinterpret_cast (target + 4) + = (unsigned short) (b & 0xffff); +#elif defined (ACE_HAS_PENTIUM) \ + && (defined (_MSC_VER) || defined (__BORLANDC__)) \ + && !defined (ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ecx, orig; + __asm mov edx, target; + __asm mov eax, [ecx]; + __asm mov ebx, 4[ecx]; + __asm bswap eax; + __asm bswap ebx; + // We're little endian. + __asm mov 2[edx], ax; + __asm mov 6[edx], bx; + __asm shr eax, 16; + __asm shr ebx, 16; + __asm mov 0[edx], ax; + __asm mov 4[edx], bx; +#elif ACE_SIZEOF_LONG == 8 + // 64 bit architecture. + register unsigned long a = + * reinterpret_cast (orig); + + register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; + register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; + + a = (a1 | a2); + + ACE_UINT16 b1 = static_cast (a >> 48); + ACE_UINT16 b2 = static_cast ((a >> 32) & 0xffff); + ACE_UINT16 b3 = static_cast ((a >> 16) & 0xffff); + ACE_UINT16 b4 = static_cast (a & 0xffff); + +#if defined(ACE_LITTLE_ENDIAN) + * reinterpret_cast (target) = b4; + * reinterpret_cast (target + 2) = b3; + * reinterpret_cast (target + 4) = b2; + * reinterpret_cast (target + 6) = b1; +#else + * reinterpret_cast (target) = b1; + * reinterpret_cast (target + 2) = b2; + * reinterpret_cast (target + 4) = b3; + * reinterpret_cast (target + 6) = b4; +#endif +#else + register ACE_UINT32 a = + * reinterpret_cast (orig); + register ACE_UINT32 b = + * reinterpret_cast (orig + 4); + + register ACE_UINT32 a1 = (a & 0x00ff00ff) << 8; + register ACE_UINT32 b1 = (b & 0x00ff00ff) << 8; + register ACE_UINT32 a2 = (a & 0xff00ff00) >> 8; + register ACE_UINT32 b2 = (b & 0xff00ff00) >> 8; + + a = (a1 | a2); + b = (b1 | b2); + + ACE_UINT32 c1 = static_cast (a >> 16); + ACE_UINT32 c2 = static_cast (a & 0xffff); + ACE_UINT32 c3 = static_cast (b >> 16); + ACE_UINT32 c4 = static_cast (b & 0xffff); + +#if defined(ACE_LITTLE_ENDIAN) + * reinterpret_cast (target) = c2; + * reinterpret_cast (target + 2) = c1; + * reinterpret_cast (target + 4) = c4; + * reinterpret_cast (target + 6) = c3; +#else + * reinterpret_cast (target) = c1; + * reinterpret_cast (target + 2) = c2; + * reinterpret_cast (target + 4) = c3; + * reinterpret_cast (target + 6) = c4; +#endif +#endif + + orig += 8; + target += 8; + } + } + + // (n & 3) == (n % 4). + switch (n&3) { + case 3: + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + case 2: + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + case 1: + ACE_CDR::swap_2 (orig, target); + } +} + +void +ACE_CDR::swap_4_array (char const * orig, char* target, size_t n) +{ + // ACE_ASSERT (n > 0); The caller checks that n > 0 + +#if ACE_SIZEOF_LONG == 8 + // Later, we read from *orig in 64 bit chunks, + // so make sure we don't generate unaligned readings. + char const * const o8 = ACE_ptr_align_binary (orig, 8); + // The mismatch can only be by 4. + if (orig != o8) + { + ACE_CDR::swap_4 (orig, target); + orig += 4; + target += 4; + --n; + } +#endif /* ACE_SIZEOF_LONG == 8 */ + + if (n == 0) + return; + + // + // Loop unrolling. Here be dragons. + // + + // (n & (~3)) is the greatest multiple of 4 not bigger than n. + // In the while loop, orig will move over the array by 16 byte + // increments (4 elements of 4 bytes). + // ends marks our barrier for not falling outside. + char const * const end = orig + 4 * (n & (~3)); + +#if ACE_SIZEOF_LONG == 8 + // 64 bits architecture. + // See if we can write in 8 byte chunks. + if (target == ACE_ptr_align_binary (target, 8)) + { + while (orig < end) + { + register unsigned long a = + * reinterpret_cast (orig); + register unsigned long b = + * reinterpret_cast (orig + 8); + +#if defined(ACE_HAS_INTEL_ASSEMBLY) + asm ("bswapq %1" : "=r" (a) : "0" (a)); + asm ("bswapq %1" : "=r" (b) : "0" (b)); + asm ("rol $32, %1" : "=r" (a) : "0" (a)); + asm ("rol $32, %1" : "=r" (b) : "0" (b)); +#else + register unsigned long a84 = (a & 0x000000ff000000ffL) << 24; + register unsigned long b84 = (b & 0x000000ff000000ffL) << 24; + register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8; + register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8; + register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8; + register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8; + register unsigned long a51 = (a & 0xff000000ff000000L) >> 24; + register unsigned long b51 = (b & 0xff000000ff000000L) >> 24; + + a = (a84 | a73 | a62 | a51); + b = (b84 | b73 | b62 | b51); +#endif + + * reinterpret_cast (target) = a; + * reinterpret_cast (target + 8) = b; + + orig += 16; + target += 16; + } + } + else + { + // We are out of luck, we have to write in 4 byte chunks. + while (orig < end) + { + register unsigned long a = + * reinterpret_cast (orig); + register unsigned long b = + * reinterpret_cast (orig + 8); + +#if defined(ACE_HAS_INTEL_ASSEMBLY) + asm ("bswapq %1" : "=r" (a) : "0" (a)); + asm ("bswapq %1" : "=r" (b) : "0" (b)); + asm ("rol $32, %1" : "=r" (a) : "0" (a)); + asm ("rol $32, %1" : "=r" (b) : "0" (b)); +#else + register unsigned long a84 = (a & 0x000000ff000000ffL) << 24; + register unsigned long b84 = (b & 0x000000ff000000ffL) << 24; + register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8; + register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8; + register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8; + register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8; + register unsigned long a51 = (a & 0xff000000ff000000L) >> 24; + register unsigned long b51 = (b & 0xff000000ff000000L) >> 24; + + a = (a84 | a73 | a62 | a51); + b = (b84 | b73 | b62 | b51); +#endif + + ACE_UINT32 c1 = static_cast (a >> 32); + ACE_UINT32 c2 = static_cast (a & 0xffffffff); + ACE_UINT32 c3 = static_cast (b >> 32); + ACE_UINT32 c4 = static_cast (b & 0xffffffff); + +#if defined (ACE_LITTLE_ENDIAN) + * reinterpret_cast (target + 0) = c2; + * reinterpret_cast (target + 4) = c1; + * reinterpret_cast (target + 8) = c4; + * reinterpret_cast (target + 12) = c3; +#else + * reinterpret_cast (target + 0) = c1; + * reinterpret_cast (target + 4) = c2; + * reinterpret_cast (target + 8) = c3; + * reinterpret_cast (target + 12) = c4; +#endif + orig += 16; + target += 16; + } + } + +#else /* ACE_SIZEOF_LONG != 8 */ + + while (orig < end) + { +#if defined (ACE_HAS_PENTIUM) && defined (__GNUG__) + register unsigned int a = + *reinterpret_cast (orig); + register unsigned int b = + *reinterpret_cast (orig + 4); + register unsigned int c = + *reinterpret_cast (orig + 8); + register unsigned int d = + *reinterpret_cast (orig + 12); + + asm ("bswap %1" : "=r" (a) : "0" (a)); + asm ("bswap %1" : "=r" (b) : "0" (b)); + asm ("bswap %1" : "=r" (c) : "0" (c)); + asm ("bswap %1" : "=r" (d) : "0" (d)); + + *reinterpret_cast (target) = a; + *reinterpret_cast (target + 4) = b; + *reinterpret_cast (target + 8) = c; + *reinterpret_cast (target + 12) = d; +#elif defined (ACE_HAS_PENTIUM) \ + && (defined (_MSC_VER) || defined (__BORLANDC__)) \ + && !defined (ACE_LACKS_INLINE_ASSEMBLY) + __asm mov eax, orig + __asm mov esi, target + __asm mov edx, [eax] + __asm mov ecx, 4[eax] + __asm mov ebx, 8[eax] + __asm mov eax, 12[eax] + __asm bswap edx + __asm bswap ecx + __asm bswap ebx + __asm bswap eax + __asm mov [esi], edx + __asm mov 4[esi], ecx + __asm mov 8[esi], ebx + __asm mov 12[esi], eax +#else + register ACE_UINT32 a = + * reinterpret_cast (orig); + register ACE_UINT32 b = + * reinterpret_cast (orig + 4); + register ACE_UINT32 c = + * reinterpret_cast (orig + 8); + register ACE_UINT32 d = + * reinterpret_cast (orig + 12); + + // Expect the optimizer reordering this A LOT. + // We leave it this way for clarity. + a = (a << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) | (a >> 24); + b = (b << 24) | ((b & 0xff00) << 8) | ((b & 0xff0000) >> 8) | (b >> 24); + c = (c << 24) | ((c & 0xff00) << 8) | ((c & 0xff0000) >> 8) | (c >> 24); + d = (d << 24) | ((d & 0xff00) << 8) | ((d & 0xff0000) >> 8) | (d >> 24); + + * reinterpret_cast (target) = a; + * reinterpret_cast (target + 4) = b; + * reinterpret_cast (target + 8) = c; + * reinterpret_cast (target + 12) = d; +#endif + + orig += 16; + target += 16; + } + +#endif /* ACE_SIZEOF_LONG == 8 */ + + // (n & 3) == (n % 4). + switch (n & 3) { + case 3: + ACE_CDR::swap_4 (orig, target); + orig += 4; + target += 4; + case 2: + ACE_CDR::swap_4 (orig, target); + orig += 4; + target += 4; + case 1: + ACE_CDR::swap_4 (orig, target); + } +} + +// +// We don't benefit from unrolling in swap_8_array and swap_16_array +// (swap_8 and swap_16 are big enough). +// +void +ACE_CDR::swap_8_array (char const * orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + + char const * const end = orig + 8*n; + while (orig < end) + { + swap_8 (orig, target); + orig += 8; + target += 8; + } +} + +void +ACE_CDR::swap_16_array (char const * orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + + char const * const end = orig + 16*n; + while (orig < end) + { + swap_16 (orig, target); + orig += 16; + target += 16; + } +} + +void +ACE_CDR::mb_align (ACE_Message_Block *mb) +{ +#if !defined (ACE_CDR_IGNORE_ALIGNMENT) + char * const start = ACE_ptr_align_binary (mb->base (), + ACE_CDR::MAX_ALIGNMENT); +#else + char * const start = mb->base (); +#endif /* ACE_CDR_IGNORE_ALIGNMENT */ + mb->rd_ptr (start); + mb->wr_ptr (start); +} + +int +ACE_CDR::grow (ACE_Message_Block *mb, size_t minsize) +{ + size_t newsize = + ACE_CDR::first_size (minsize + ACE_CDR::MAX_ALIGNMENT); + + if (newsize <= mb->size ()) + return 0; + + ACE_Data_Block *db = + mb->data_block ()->clone_nocopy (0, newsize); + + if (db == 0) + return -1; + + // Do the equivalent of ACE_CDR::mb_align() here to avoid having + // to allocate an ACE_Message_Block on the stack thereby avoiding + // the manipulation of the data blocks reference count + size_t mb_len = mb->length (); + char *start = ACE_ptr_align_binary (db->base (), + ACE_CDR::MAX_ALIGNMENT); + + ACE_OS::memcpy (start, mb->rd_ptr (), mb_len); + mb->data_block (db); + + // Setting the data block on the mb resets the read and write + // pointers back to the beginning. We must set the rd_ptr to the + // aligned start and adjust the write pointer to the end + mb->rd_ptr (start); + mb->wr_ptr (start + mb_len); + + // Remove the DONT_DELETE flags from mb + mb->clr_self_flags (ACE_Message_Block::DONT_DELETE); + + return 0; +} + +size_t +ACE_CDR::total_length (const ACE_Message_Block* begin, + const ACE_Message_Block* end) +{ + size_t l = 0; + // Compute the total size. + for (const ACE_Message_Block *i = begin; + i != end; + i = i->cont ()) + l += i->length (); + return l; +} + +void +ACE_CDR::consolidate (ACE_Message_Block *dst, + const ACE_Message_Block *src) +{ + if (src == 0) + return; + + size_t newsize = + ACE_CDR::first_size (ACE_CDR::total_length (src, 0) + + ACE_CDR::MAX_ALIGNMENT); + dst->size (newsize); + +#if !defined (ACE_CDR_IGNORE_ALIGNMENT) + // We must copy the contents of into the new buffer, but + // respecting the alignment. + ptrdiff_t srcalign = + ptrdiff_t(src->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT; + ptrdiff_t dstalign = + ptrdiff_t(dst->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT; + ptrdiff_t offset = srcalign - dstalign; + if (offset < 0) + offset += ACE_CDR::MAX_ALIGNMENT; + dst->rd_ptr (static_cast (offset)); + dst->wr_ptr (dst->rd_ptr ()); +#endif /* ACE_CDR_IGNORE_ALIGNMENT */ + + for (const ACE_Message_Block* i = src; + i != 0; + i = i->cont ()) + { + // If the destination and source are the same, do not + // attempt to copy the data. Just update the write pointer. + if (dst->wr_ptr () != i->rd_ptr ()) + dst->copy (i->rd_ptr (), i->length ()); + else + dst->wr_ptr (i->length ()); + } +} + +#if defined (NONNATIVE_LONGLONG) +bool +ACE_CDR::LongLong::operator== (const ACE_CDR::LongLong &rhs) const +{ + return this->h == rhs.h && this->l == rhs.l; +} + +bool +ACE_CDR::LongLong::operator!= (const ACE_CDR::LongLong &rhs) const +{ + return this->l != rhs.l || this->h != rhs.h; +} + +#endif /* NONNATIVE_LONGLONG */ + +#if defined (NONNATIVE_LONGDOUBLE) +ACE_CDR::LongDouble& +ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble::NativeImpl& rhs) +{ + ACE_OS::memset (this->ld, 0, sizeof (this->ld)); + + if (sizeof (rhs) == 8) + { +#if defined (ACE_LITTLE_ENDIAN) + static const size_t byte_zero = 1; + static const size_t byte_one = 0; + char rhs_ptr[16]; + ACE_CDR::swap_8 (reinterpret_cast (&rhs), rhs_ptr); +#else + static const size_t byte_zero = 0; + static const size_t byte_one = 1; + const char* rhs_ptr = reinterpret_cast (&rhs); +#endif + ACE_INT16 sign = static_cast ( + static_cast (rhs_ptr[0])) & 0x8000; + ACE_INT16 exponent = ((rhs_ptr[0] & 0x7f) << 4) | + ((rhs_ptr[1] >> 4) & 0xf); + const char* exp_ptr = reinterpret_cast (&exponent); + + // Infinity and NaN have an exponent of 0x7ff in 64-bit IEEE + if (exponent == 0x7ff) + { + exponent = 0x7fff; + } + else + { + exponent = (exponent - max_eleven_bit) + max_fifteen_bit; + } + exponent |= sign; + + // Store the sign bit and exponent + this->ld[0] = exp_ptr[byte_zero]; + this->ld[1] = exp_ptr[byte_one]; + + // Store the mantissa. In an 8 byte double, it is split by + // 4 bits (because of the 12 bits for sign and exponent), so + // we have to shift and or the rhs to get the right bytes. + size_t li = 2; + bool direction = true; + for (size_t ri = 1; ri < sizeof (rhs);) + { + if (direction) + { + this->ld[li] |= ((rhs_ptr[ri] << 4) & 0xf0); + direction = false; + ++ri; + } + else + { + this->ld[li] |= ((rhs_ptr[ri] >> 4) & 0xf); + direction = true; + ++li; + } + } +#if defined (ACE_LITTLE_ENDIAN) + ACE_OS::memcpy (rhs_ptr, this->ld, sizeof (this->ld)); + ACE_CDR::swap_16 (rhs_ptr, this->ld); +#endif + } + else + { + ACE_OS::memcpy(this->ld, + reinterpret_cast (&rhs), sizeof (rhs)); + } + return *this; +} + +ACE_CDR::LongDouble& +ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble& rhs) +{ + if (this != &rhs) + *this = rhs; + return *this; +} + +bool +ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble &rhs) const +{ + return ACE_OS::memcmp (this->ld, rhs.ld, 16) == 0; +} + +bool +ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble &rhs) const +{ + return ACE_OS::memcmp (this->ld, rhs.ld, 16) != 0; +} + +ACE_CDR::LongDouble::operator ACE_CDR::LongDouble::NativeImpl () const +{ + ACE_CDR::LongDouble::NativeImpl ret = 0.0; + char* lhs_ptr = reinterpret_cast (&ret); + + if (sizeof (ret) == 8) + { +#if defined (ACE_LITTLE_ENDIAN) + static const size_t byte_zero = 1; + static const size_t byte_one = 0; + char copy[16]; + ACE_CDR::swap_16 (this->ld, copy); +#else + static const size_t byte_zero = 0; + static const size_t byte_one = 1; + const char* copy = this->ld; +#endif + ACE_INT16 exponent = 0; + char* exp_ptr = reinterpret_cast (&exponent); + exp_ptr[byte_zero] = copy[0]; + exp_ptr[byte_one] = copy[1]; + + ACE_INT16 sign = (exponent & 0x8000); + exponent &= 0x7fff; + + // Infinity and NaN have an exponent of 0x7fff in 128-bit IEEE + if (exponent == 0x7fff) + { + exponent = 0x7ff; + } + else + { + exponent = (exponent - max_fifteen_bit) + max_eleven_bit; + } + exponent = (exponent << 4) | sign; + + // Store the sign and exponent + lhs_ptr[0] = exp_ptr[byte_zero]; + lhs_ptr[1] = exp_ptr[byte_one]; + + // Store the mantissa. In an 8 byte double, it is split by + // 4 bits (because of the 12 bits for sign and exponent), so + // we have to shift and or the rhs to get the right bytes. + size_t li = 1; + bool direction = true; + for (size_t ri = 2; li < sizeof (ret);) { + if (direction) + { + lhs_ptr[li] |= ((copy[ri] >> 4) & 0xf); + direction = false; + ++li; + } + else + { + lhs_ptr[li] |= ((copy[ri] & 0xf) << 4); + direction = true; + ++ri; + } + } + +#if defined (ACE_LITTLE_ENDIAN) + ACE_CDR::swap_8 (lhs_ptr, lhs_ptr); +#endif + } + else + { + ACE_OS::memcpy(lhs_ptr, this->ld, sizeof (ret)); + } + + // This bit of code is unnecessary. However, this code is + // necessary to work around a bug in the gcc 4.1.1 optimizer. + ACE_CDR::LongDouble tmp; + tmp.assign (ret); + + return ret; +} +#endif /* NONNATIVE_LONGDOUBLE */ + +#if defined(_UNICOS) && !defined(_CRAYMPP) +// placeholders to get things compiling +ACE_CDR::Float::Float (void) +{ +} + +ACE_CDR::Float::Float (const float & /* init */) +{ +} + +ACE_CDR::Float & +ACE_CDR::Float::operator= (const float & /* rhs */) +{ + return *this; +} + +bool +ACE_CDR::Float::operator!= (const ACE_CDR::Float & /* rhs */) const +{ + return false; +} +#endif /* _UNICOS */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/CDR_Base.h b/dep/ACE_wrappers/ace/CDR_Base.h new file mode 100644 index 000000000..9c5851b22 --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Base.h @@ -0,0 +1,379 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CDR_Base.h + * + * $Id: CDR_Base.h 82088 2008-06-19 16:22:16Z shuston $ + * + * ACE Common Data Representation (CDR) basic types. + * + * The current implementation assumes that the host has 1-byte, + * 2-byte and 4-byte integral types, and that it has single + * precision and double precision IEEE floats. + * Those assumptions are pretty good these days, with Crays being + * the only known exception. + * + * + * @author TAO version by + * @author Aniruddha Gokhale + * @author Carlos O'Ryan + * @author ACE version by + * @author Jeff Parsons + * @author Istvan Buki + */ +//============================================================================= + + +#ifndef ACE_CDR_BASE_H +#define ACE_CDR_BASE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Basic_Types.h" +#include "ace/Default_Constants.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Stuff used by the ACE CDR classes. Watch these values... they're also used +// in the ACE_CDR Byte_Order enum below. +#if defined ACE_LITTLE_ENDIAN +# define ACE_CDR_BYTE_ORDER 1 +// little endian encapsulation byte order has value = 1 +#else /* ! ACE_LITTLE_ENDIAN */ +# define ACE_CDR_BYTE_ORDER 0 +// big endian encapsulation byte order has value = 0 +#endif /* ! ACE_LITTLE_ENDIAN */ + +class ACE_Message_Block; + +/** + * @class ACE_CDR + * + * @brief Keep constants and some routines common to both Output and + * Input CDR streams. + */ +class ACE_Export ACE_CDR +{ +public: + // = Constants defined by the CDR protocol. + // By defining as many of these constants as possible as enums we + // ensure they get inlined and avoid pointless static memory + // allocations. + + enum + { + // Note that some of these get reused as part of the standard + // binary format: unsigned is the same size as its signed cousin, + // float is LONG_SIZE, and double is LONGLONG_SIZE. + + OCTET_SIZE = 1, + SHORT_SIZE = 2, + LONG_SIZE = 4, + LONGLONG_SIZE = 8, + LONGDOUBLE_SIZE = 16, + + OCTET_ALIGN = 1, + SHORT_ALIGN = 2, + LONG_ALIGN = 4, + LONGLONG_ALIGN = 8, + /// @note the CORBA LongDouble alignment requirements do not + /// match its size... + LONGDOUBLE_ALIGN = 8, + + /// Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long + /// double", size as above). + MAX_ALIGNMENT = 8, + + /// The default buffer size. + /** + * @todo We want to add options to control this + * default value, so this constant should be read as the default + * default value ;-) + */ + DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE, + + /// The buffer size grows exponentially until it reaches this size; + /// afterwards it grows linearly using the next constant + EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX, + + /// Once exponential growth is ruled out the buffer size increases + /// in chunks of this size, note that this constants have the same + /// value right now, but it does not need to be so. + LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK + }; + + /** + * @enum Byte_Order + * + * Defines values for the byte_order argument to ACE_OutputCDR and + * ACE_InputCDR. + */ + enum Byte_Order + { + /// Use big-endian order (also known as network byte order). + BYTE_ORDER_BIG_ENDIAN = 0, + /// Use little-endian order. + BYTE_ORDER_LITTLE_ENDIAN = 1, + /// Use whichever byte order is native to this machine. + BYTE_ORDER_NATIVE = ACE_CDR_BYTE_ORDER + }; + + /** + * Do byte swapping for each basic IDL type size. There exist only + * routines to put byte, halfword (2 bytes), word (4 bytes), + * doubleword (8 bytes) and quadword (16 byte); because those are + * the IDL basic type sizes. + */ + static void swap_2 (char const *orig, char *target); + static void swap_4 (char const *orig, char *target); + static void swap_8 (char const *orig, char *target); + static void swap_16 (char const *orig, char *target); + static void swap_2_array (char const *orig, + char *target, + size_t length); + static void swap_4_array (char const *orig, + char *target, + size_t length); + static void swap_8_array (char const *orig, + char *target, + size_t length); + static void swap_16_array (char const *orig, + char *target, + size_t length); + + /// Align the message block to ACE_CDR::MAX_ALIGNMENT, + /// set by the CORBA spec at 8 bytes. + static void mb_align (ACE_Message_Block *mb); + + /** + * Compute the size of the smallest buffer that can contain at least + * @a minsize bytes. + * To understand how a "best fit" is computed look at the + * algorithm in the code. + * Basically the buffers grow exponentially, up to a certain point, + * then the buffer size grows linearly. + * The advantage of this algorithm is that is rapidly grows to a + * large value, but does not explode at the end. + */ + static size_t first_size (size_t minsize); + + /// Compute not the smallest, but the second smallest buffer that + /// will fir @a minsize bytes. + static size_t next_size (size_t minsize); + + /** + * Increase the capacity of mb to contain at least @a minsize bytes. + * If @a minsize is zero the size is increased by an amount at least + * large enough to contain any of the basic IDL types. + * @retval -1 Failure + * @retval 0 Success. + */ + static int grow (ACE_Message_Block *mb, size_t minsize); + + /// Copy a message block chain into a single message block, + /// preserving the alignment of the first message block of the + /// original stream, not the following message blocks. + static void consolidate (ACE_Message_Block *dst, + const ACE_Message_Block *src); + + static size_t total_length (const ACE_Message_Block *begin, + const ACE_Message_Block *end); + + /** + * @name Basic OMG IDL Types + * + * These types are for use in the CDR classes. The cleanest way to + * avoid complaints from all compilers is to define them all. + */ + //@{ + typedef bool Boolean; + typedef unsigned char Octet; + typedef char Char; + typedef ACE_WCHAR_T WChar; + typedef ACE_INT16 Short; + typedef ACE_UINT16 UShort; + typedef ACE_INT32 Long; + typedef ACE_UINT32 ULong; + typedef ACE_UINT64 ULongLong; + +# if (defined (_MSC_VER)) || (defined (__BORLANDC__)) + typedef __int64 LongLong; +# elif ACE_SIZEOF_LONG == 8 && !defined(_CRAYMPP) + typedef long LongLong; +# elif defined(__TANDEM) + typedef long long LongLong; +# elif ACE_SIZEOF_LONG_LONG == 8 && !defined (ACE_LACKS_LONGLONG_T) +# if defined (sun) && !defined (ACE_LACKS_U_LONGLONG_T) + // sun #defines u_longlong_t, maybe other platforms do also. + // Use it, at least with g++, so that its -pedantic doesn't + // complain about no ANSI C++ long long. + typedef longlong_t LongLong; +# else + // LynxOS 2.5.0 and Linux don't have u_longlong_t. + typedef long long LongLong; +# endif /* sun */ +# else /* no native 64 bit integer type */ +# define NONNATIVE_LONGLONG + struct ACE_Export LongLong + { +# if defined (ACE_BIG_ENDIAN) + ACE_CDR::Long h; + ACE_CDR::Long l; +# else + ACE_CDR::Long l; + ACE_CDR::Long h; +# endif /* ! ACE_BIG_ENDIAN */ + + /** + * @name Overloaded Relation Operators. + * + * The canonical comparison operators. + */ + //@{ + bool operator== (const LongLong &rhs) const; + bool operator!= (const LongLong &rhs) const; + //@} + }; +# endif /* no native 64 bit integer type */ + +# if defined (NONNATIVE_LONGLONG) +# define ACE_CDR_LONGLONG_INITIALIZER {0,0} +# else +# define ACE_CDR_LONGLONG_INITIALIZER 0 +# endif /* NONNATIVE_LONGLONG */ + +# if ACE_SIZEOF_FLOAT == 4 + typedef float Float; +# else /* ACE_SIZEOF_FLOAT != 4 */ + struct Float + { +# if ACE_SIZEOF_INT == 4 + // Use unsigned int to get word alignment. + unsigned int f; +# else /* ACE_SIZEOF_INT != 4 */ + // Applications will probably have trouble with this. + char f[4]; +# if defined(_UNICOS) && !defined(_CRAYMPP) + Float (void); + Float (const float &init); + Float & operator= (const float &rhs); + bool operator!= (const Float &rhs) const; +# endif /* _UNICOS */ +# endif /* ACE_SIZEOF_INT != 4 */ + }; +# endif /* ACE_SIZEOF_FLOAT != 4 */ + +# if ACE_SIZEOF_DOUBLE == 8 + typedef double Double; +# else /* ACE_SIZEOF_DOUBLE != 8 */ + struct Double + { +# if ACE_SIZEOF_LONG == 8 + // Use u long to get word alignment. + unsigned long f; +# else /* ACE_SIZEOF_INT != 8 */ + // Applications will probably have trouble with this. + char f[8]; +# endif /* ACE_SIZEOF_INT != 8 */ + }; +# endif /* ACE_SIZEOF_DOUBLE != 8 */ + + // 94-9-32 Appendix A defines a 128 bit floating point "long + // double" data type, with greatly extended precision and four + // more bits of exponent (compared to "double"). This is an IDL + // extension, not yet standard. + +# if ACE_SIZEOF_LONG_DOUBLE == 16 + typedef long double LongDouble; +# define ACE_CDR_LONG_DOUBLE_INITIALIZER 0 +# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS = RHS +# else +# define NONNATIVE_LONGDOUBLE +# define ACE_CDR_LONG_DOUBLE_INITIALIZER {{0}} +# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS.assign (RHS) + struct ACE_Export LongDouble + { + // VxWorks' compiler (gcc 2.96) gets confused by the operator long + // double, so we avoid using long double as the NativeImpl. + // Linux's x86 long double format (12 or 16 bytes) is incompatible + // with Windows, Solaris, AIX, MacOS X and HP-UX (and probably others) + // long double format (8 or 16 bytes). If you need 32-bit Linux to + // inter-operate with 64-bit Linux you will want to define this + // macro to 0 so that "long double" is used. Otherwise, do not define + // this macro. +# if defined (ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE) && \ + (ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE == 1) + typedef double NativeImpl; +# else + typedef long double NativeImpl; +# endif /* ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE==1 */ + + char ld[16]; + + LongDouble& assign (const NativeImpl& rhs); + LongDouble& assign (const LongDouble& rhs); + + bool operator== (const LongDouble &rhs) const; + bool operator!= (const LongDouble &rhs) const; + + LongDouble& operator*= (const NativeImpl rhs) { + return this->assign (static_cast (*this) * rhs); + } + LongDouble& operator/= (const NativeImpl rhs) { + return this->assign (static_cast (*this) / rhs); + } + LongDouble& operator+= (const NativeImpl rhs) { + return this->assign (static_cast (*this) + rhs); + } + LongDouble& operator-= (const NativeImpl rhs) { + return this->assign (static_cast (*this) - rhs); + } + LongDouble& operator++ () { + return this->assign (static_cast (*this) + 1); + } + LongDouble& operator-- () { + return this->assign (static_cast (*this) - 1); + } + LongDouble operator++ (int) { + LongDouble ldv = *this; + this->assign (static_cast (*this) + 1); + return ldv; + } + LongDouble operator-- (int) { + LongDouble ldv = *this; + this->assign (static_cast (*this) - 1); + return ldv; + } + + operator NativeImpl () const; + }; +# endif /* ACE_SIZEOF_LONG_DOUBLE != 16 */ + + //@} + +#if !defined (ACE_CDR_GIOP_MAJOR_VERSION) +# define ACE_CDR_GIOP_MAJOR_VERSION 1 +#endif /*ACE_CDR_GIOP_MAJOR_VERSION */ + +#if !defined (ACE_CDR_GIOP_MINOR_VERSION) +# define ACE_CDR_GIOP_MINOR_VERSION 2 +#endif /* ACE_CDR_GIOP_MINOR_VERSION */ +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/CDR_Base.inl" +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" + +#endif /* ACE_CDR_BASE_H */ diff --git a/dep/ACE_wrappers/ace/CDR_Base.inl b/dep/ACE_wrappers/ace/CDR_Base.inl new file mode 100644 index 000000000..85373170a --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Base.inl @@ -0,0 +1,255 @@ +// -*- C++ -*- +// +// $Id: CDR_Base.inl 80826 2008-03-04 14:51:23Z wotte $ + +#if defined (ACE_HAS_INTRINSIC_BYTESWAP) +// Take advantage of MSVC++ byte swapping compiler intrinsics (found +// in ). +# pragma intrinsic (_byteswap_ushort, _byteswap_ulong, _byteswap_uint64) +#endif /* ACE_HAS_INTRINSIC_BYTESWAP */ + +#if defined (ACE_HAS_BSWAP_16) || defined (ACE_HAS_BSWAP_32) || defined (ACE_HAS_BSWAP_64) +# include "ace/os_include/os_byteswap.h" +#endif + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// +// The ACE_CDR::swap_X and ACE_CDR::swap_X_array routines are broken +// in 5 cases for optimization: +// +// * MSVC++ 7.1 or better +// => Compiler intrinsics +// +// * AMD64 CPU + gnu g++ +// => gcc amd64 inline assembly. +// +// * x86 Pentium CPU + gnu g++ +// (ACE_HAS_PENTIUM && __GNUG__) +// => gcc x86 inline assembly. +// +// * x86 Pentium CPU and (_MSC_VER) or BORLAND C++) +// (ACE_HAS_PENTIUM && ( _MSC_VER || __BORLANDC__ ) +// => MSC x86 inline assembly. +// +// * 64 bit architecture +// (ACE_SIZEOF_LONG == 8) +// => shift/masks using 64bit words. +// +// * default +// (none of the above) +// => shift/masks using 32bit words. +// +// +// Some things you could find useful to know if you intend to mess +// with this optimizations for swaps: +// +// * MSVC++ don't assume register values are conserved between +// statements. So you can clobber any register you want, +// whenever you want (well not *anyone* really, see manual). +// The MSVC++ optimizer will try to pick different registers +// for the C++ statements sorrounding your asm block, and if +// it's not possible will use the stack. +// +// * If you clobber registers with asm statements in gcc, you +// better do it in an asm-only function, or save/restore them +// before/after in the stack. If not, sorrounding C statements +// could end using the same registers and big-badda-bum (been +// there, done that...). The big-badda-bum could happen *even +// if you specify the clobbered register in your asm's*. +// Even better, use gcc asm syntax for detecting the register +// asigned to a certain variable so you don't have to clobber any +// register directly. +// + +ACE_INLINE void +ACE_CDR::swap_2 (const char *orig, char* target) +{ +#if defined (ACE_HAS_INTRINSIC_BYTESWAP) + // Take advantage of MSVC++ compiler intrinsic byte swapping + // function. + *reinterpret_cast (target) = + _byteswap_ushort (*reinterpret_cast (orig)); +#elif defined (ACE_HAS_BSWAP16) + *reinterpret_cast (target) = + bswap16 (*reinterpret_cast (orig)); +#elif defined (ACE_HAS_BSWAP_16) + *reinterpret_cast (target) = + bswap_16 (*reinterpret_cast (orig)); +#elif defined(ACE_HAS_INTEL_ASSEMBLY) + unsigned short a = + *reinterpret_cast (orig); + asm( "rolw $8, %0" : "=r" (a) : "0" (a) ); + *reinterpret_cast (target) = a; +#elif defined (ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ebx, orig; + __asm mov ecx, target; + __asm mov ax, [ebx]; + __asm rol ax, 8; + __asm mov [ecx], ax; +#else + register ACE_UINT16 usrc = * reinterpret_cast (orig); + register ACE_UINT16* udst = reinterpret_cast (target); + *udst = (usrc << 8) | (usrc >> 8); +#endif /* ACE_HAS_PENTIUM */ +} + +ACE_INLINE void +ACE_CDR::swap_4 (const char* orig, char* target) +{ +#if defined (ACE_HAS_INTRINSIC_BYTESWAP) + // Take advantage of MSVC++ compiler intrinsic byte swapping + // function. + *reinterpret_cast (target) = + _byteswap_ulong (*reinterpret_cast (orig)); +#elif defined (ACE_HAS_BSWAP32) + *reinterpret_cast (target) = + bswap32 (*reinterpret_cast (orig)); +#elif defined (ACE_HAS_BSWAP_32) + *reinterpret_cast (target) = + bswap_32 (*reinterpret_cast (orig)); +#elif defined(ACE_HAS_INTEL_ASSEMBLY) + // We have ACE_HAS_PENTIUM, so we know the sizeof's. + register unsigned int j = + *reinterpret_cast (orig); + asm ("bswap %1" : "=r" (j) : "0" (j)); + *reinterpret_cast (target) = j; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ebx, orig; + __asm mov ecx, target; + __asm mov eax, [ebx]; + __asm bswap eax; + __asm mov [ecx], eax; +#else + register ACE_UINT32 x = * reinterpret_cast (orig); + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); + * reinterpret_cast (target) = x; +#endif /* ACE_HAS_INTRINSIC_BYTESWAP */ +} + +ACE_INLINE void +ACE_CDR::swap_8 (const char* orig, char* target) +{ +#if defined (ACE_HAS_INTRINSIC_BYTESWAP) + // Take advantage of MSVC++ compiler intrinsic byte swapping + // function. + *reinterpret_cast (target) = + _byteswap_uint64 (*reinterpret_cast (orig)); +#elif defined (ACE_HAS_BSWAP64) + *reinterpret_cast (target) = + bswap64 (*reinterpret_cast (orig)); +#elif defined (ACE_HAS_BSWAP_64) + *reinterpret_cast (target) = + bswap_64 (*reinterpret_cast (orig)); +#elif (defined (__amd64__) || defined (__x86_64__)) && defined(__GNUG__) + register unsigned long x = + * reinterpret_cast (orig); + asm ("bswapq %1" : "=r" (x) : "0" (x)); + *reinterpret_cast (target) = x; +#elif defined(ACE_HAS_PENTIUM) && defined(__GNUG__) + register unsigned int i = + *reinterpret_cast (orig); + register unsigned int j = + *reinterpret_cast (orig + 4); + asm ("bswap %1" : "=r" (i) : "0" (i)); + asm ("bswap %1" : "=r" (j) : "0" (j)); + *reinterpret_cast (target + 4) = i; + *reinterpret_cast (target) = j; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ecx, orig; + __asm mov edx, target; + __asm mov eax, [ecx]; + __asm mov ebx, 4[ecx]; + __asm bswap eax; + __asm bswap ebx; + __asm mov 4[edx], eax; + __asm mov [edx], ebx; +#elif ACE_SIZEOF_LONG == 8 + // 64 bit architecture. + register unsigned long x = + * reinterpret_cast (orig); + register unsigned long x84 = (x & 0x000000ff000000ffUL) << 24; + register unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8; + register unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8; + register unsigned long x51 = (x & 0xff000000ff000000UL) >> 24; + x = (x84 | x73 | x62 | x51); + x = (x << 32) | (x >> 32); + *reinterpret_cast (target) = x; +#else + register ACE_UINT32 x = + * reinterpret_cast (orig); + register ACE_UINT32 y = + * reinterpret_cast (orig + 4); + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); + y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24); + * reinterpret_cast (target) = y; + * reinterpret_cast (target + 4) = x; +#endif /* ACE_HAS_INTRINSIC_BYTESWAP */ +} + +ACE_INLINE void +ACE_CDR::swap_16 (const char* orig, char* target) +{ + swap_8 (orig + 8, target); + swap_8 (orig, target + 8); +} + +ACE_INLINE size_t +ACE_CDR::first_size (size_t minsize) +{ + if (minsize == 0) + return ACE_CDR::DEFAULT_BUFSIZE; + + size_t newsize = ACE_CDR::DEFAULT_BUFSIZE; + while (newsize < minsize) + { + if (newsize < ACE_CDR::EXP_GROWTH_MAX) + { + // We grow exponentially at the beginning, this is fast and + // reduces the number of allocations. + + // Quickly multiply by two using a bit shift. This is + // guaranteed to work since the variable is an unsigned + // integer. + newsize <<= 1; + } + else + { + // but continuing with exponential growth can result in over + // allocations and easily yield an allocation failure. + // So we grow linearly when the buffer is too big. + newsize += ACE_CDR::LINEAR_GROWTH_CHUNK; + } + } + return newsize; +} + +ACE_INLINE size_t +ACE_CDR::next_size (size_t minsize) +{ + size_t newsize = ACE_CDR::first_size (minsize); + + if (newsize == minsize) + { + // If necessary increment the size + if (newsize < ACE_CDR::EXP_GROWTH_MAX) + // Quickly multiply by two using a bit shift. This is + // guaranteed to work since the variable is an unsigned + // integer. + newsize <<= 1; + else + newsize += ACE_CDR::LINEAR_GROWTH_CHUNK; + } + + return newsize; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +// **************************************************************** diff --git a/dep/ACE_wrappers/ace/CDR_Size.cpp b/dep/ACE_wrappers/ace/CDR_Size.cpp new file mode 100644 index 000000000..969709270 --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Size.cpp @@ -0,0 +1,262 @@ +#include "ace/CDR_Size.h" +#include "ace/SString.h" +#include "ace/OS_Memory.h" +#include "ace/Truncate.h" + +#if !defined (__ACE_INLINE__) +# include "ace/CDR_Size.inl" +#endif /* ! __ACE_INLINE__ */ + +ACE_RCSID (ace, + CDR_Size, + "$Id: CDR_Size.cpp 82559 2008-08-07 20:23:07Z parsons $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_CDR::Boolean +ACE_SizeCDR::write_wchar (ACE_CDR::WChar x) +{ + // Note: translator framework is not supported. + // + if (ACE_OutputCDR::wchar_maxbytes () == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + if (static_cast (major_version_) == 1 + && static_cast (minor_version_) == 2) + { + ACE_CDR::Octet len = + static_cast (ACE_OutputCDR::wchar_maxbytes ()); + + if (this->write_1 (&len)) + { + if (ACE_OutputCDR::wchar_maxbytes () == sizeof(ACE_CDR::WChar)) + { + return + this->write_octet_array ( + reinterpret_cast (&x), + static_cast (len)); + } + else + { + if (ACE_OutputCDR::wchar_maxbytes () == 2) + { + ACE_CDR::Short sx = static_cast (x); + return + this->write_octet_array ( + reinterpret_cast (&sx), + static_cast (len)); + } + else + { + ACE_CDR::Octet ox = static_cast (x); + return + this->write_octet_array ( + reinterpret_cast (&ox), + static_cast (len)); + } + } + } + } + else if (static_cast (minor_version_) == 0) + { // wchar is not allowed with GIOP 1.0. + errno = EINVAL; + return (this->good_bit_ = false); + } + + if (ACE_OutputCDR::wchar_maxbytes () == sizeof (ACE_CDR::WChar)) + { + const void *temp = &x; + return this->write_4 (reinterpret_cast (temp)); + } + else if (ACE_OutputCDR::wchar_maxbytes () == 2) + { + ACE_CDR::Short sx = static_cast (x); + return this->write_2 (reinterpret_cast (&sx)); + } + + ACE_CDR::Octet ox = static_cast (x); + return this->write_1 (reinterpret_cast (&ox)); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_string (ACE_CDR::ULong len, + const ACE_CDR::Char *x) +{ + // Note: translator framework is not supported. + // + if (len != 0) + { + if (this->write_ulong (len + 1)) + return this->write_char_array (x, len + 1); + } + else + { + // Be nice to programmers: treat nulls as empty strings not + // errors. (OMG-IDL supports languages that don't use the C/C++ + // notion of null v. empty strings; nulls aren't part of the OMG-IDL + // string model.) + if (this->write_ulong (1)) + return this->write_char (0); + } + + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_string (const ACE_CString &x) +{ + // @@ Leave this method in here, not the `.i' file so that we don't + // have to unnecessarily pull in the `ace/SString.h' header. + return this->write_string (static_cast (x.length ()), + x.c_str()); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_wstring (ACE_CDR::ULong len, + const ACE_CDR::WChar *x) +{ + // Note: translator framework is not supported. + // + if (ACE_OutputCDR::wchar_maxbytes () == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + if (static_cast (this->major_version_) == 1 + && static_cast (this->minor_version_) == 2) + { + if (x != 0) + { + //In GIOP 1.2 the length field contains the number of bytes + //the wstring occupies rather than number of wchars + //Taking sizeof might not be a good way! This is a temporary fix. + ACE_CDR::Boolean good_ulong = + this->write_ulong ( + ACE_Utils::truncate_cast ( + ACE_OutputCDR::wchar_maxbytes () * len)); + + if (good_ulong) + { + return this->write_wchar_array (x, len); + } + } + else + { + //In GIOP 1.2 zero length wstrings are legal + return this->write_ulong (0); + } + } + + else + if (x != 0) + { + if (this->write_ulong (len + 1)) + return this->write_wchar_array (x, len + 1); + } + else if (this->write_ulong (1)) + return this->write_wchar (0); + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_1 (const ACE_CDR::Octet *) +{ + this->adjust (1); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_2 (const ACE_CDR::UShort *) +{ + this->adjust (ACE_CDR::SHORT_SIZE); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_4 (const ACE_CDR::ULong *) +{ + this->adjust (ACE_CDR::LONG_SIZE); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_8 (const ACE_CDR::ULongLong *) +{ + this->adjust (ACE_CDR::LONGLONG_SIZE); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_16 (const ACE_CDR::LongDouble *) +{ + this->adjust (ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_wchar_array_i (const ACE_CDR::WChar *, + ACE_CDR::ULong length) +{ + if (length == 0) + return true; + + size_t const align = (ACE_OutputCDR::wchar_maxbytes () == 2) ? + ACE_CDR::SHORT_ALIGN : + ACE_CDR::OCTET_ALIGN; + + this->adjust (ACE_OutputCDR::wchar_maxbytes () * length, align); + return true; +} + + +ACE_CDR::Boolean +ACE_SizeCDR::write_array (const void *, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + if (length == 0) + return true; + + this->adjust (size * length, align); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_boolean_array (const ACE_CDR::Boolean*, + ACE_CDR::ULong length) +{ + this->adjust (length, 1); + return true; +} + +void +ACE_SizeCDR::adjust (size_t size) +{ + adjust (size, size); +} + +void +ACE_SizeCDR::adjust (size_t size, + size_t align) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + const size_t offset = ACE_align_binary (size_, align) - size_; + size_ += offset; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + size_ += size; +} + +ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const ACE_CString &x) +{ + ss.write_string (x); + return ss.good_bit (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/CDR_Size.h b/dep/ACE_wrappers/ace/CDR_Size.h new file mode 100644 index 000000000..a0b3c462c --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Size.h @@ -0,0 +1,241 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CDR_Size.h + * + * $Id: CDR_Size.h 80826 2008-03-04 14:51:23Z wotte $ + * + * + * ACE Common Data Representation (CDR) size-calculating stream. + * + * + * The current implementation assumes that the host has 1-byte, + * 2-byte and 4-byte integral types, and that it has single + * precision and double precision IEEE floats. + * Those assumptions are pretty good these days, with Crays beign + * the only known exception. + * + * + * @author Boris Kolpackov + * + */ +//============================================================================= + +#ifndef ACE_CDR_SIZE_H +#define ACE_CDR_SIZE_H + +#include /**/ "ace/pre.h" + +#include "ace/CDR_Base.h" +#include "ace/CDR_Stream.h" // for ACE_OutputCDR::from_* + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SStringfwd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_SizeCDR + * + * @brief A CDR stream for calculating size of the representation. + * + */ +class ACE_Export ACE_SizeCDR +{ +public: + /// Default constructor. + ACE_SizeCDR (ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Returns @c false if an error has ocurred. + bool good_bit (void) const; + + + /// Reset current size. + void reset (void); + + + /// Return current size. + size_t total_length (void) const; + + + // Return 0 on failure and 1 on success. + //@{ @name Size-calculating pseudo-write operations + ACE_CDR::Boolean write_boolean (ACE_CDR::Boolean x); + ACE_CDR::Boolean write_char (ACE_CDR::Char x); + ACE_CDR::Boolean write_wchar (ACE_CDR::WChar x); + ACE_CDR::Boolean write_octet (ACE_CDR::Octet x); + ACE_CDR::Boolean write_short (ACE_CDR::Short x); + ACE_CDR::Boolean write_ushort (ACE_CDR::UShort x); + ACE_CDR::Boolean write_long (ACE_CDR::Long x); + ACE_CDR::Boolean write_ulong (ACE_CDR::ULong x); + ACE_CDR::Boolean write_longlong (const ACE_CDR::LongLong &x); + ACE_CDR::Boolean write_ulonglong (const ACE_CDR::ULongLong &x); + ACE_CDR::Boolean write_float (ACE_CDR::Float x); + ACE_CDR::Boolean write_double (const ACE_CDR::Double &x); + ACE_CDR::Boolean write_longdouble (const ACE_CDR::LongDouble &x); + + /// For string we offer methods that accept a precomputed length. + ACE_CDR::Boolean write_string (const ACE_CDR::Char *x); + ACE_CDR::Boolean write_string (ACE_CDR::ULong len, + const ACE_CDR::Char *x); + ACE_CDR::Boolean write_string (const ACE_CString &x); + ACE_CDR::Boolean write_wstring (const ACE_CDR::WChar *x); + ACE_CDR::Boolean write_wstring (ACE_CDR::ULong length, + const ACE_CDR::WChar *x); + //@} + + /// @note the portion written starts at and ends + /// at . + /// The length is *NOT* stored into the CDR stream. + //@{ @name Array write operations + ACE_CDR::Boolean write_boolean_array (const ACE_CDR::Boolean *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_char_array (const ACE_CDR::Char *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_wchar_array (const ACE_CDR::WChar* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_octet_array (const ACE_CDR::Octet* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_short_array (const ACE_CDR::Short *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ushort_array (const ACE_CDR::UShort *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_long_array (const ACE_CDR::Long *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ulong_array (const ACE_CDR::ULong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_longlong_array (const ACE_CDR::LongLong* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ulonglong_array (const ACE_CDR::ULongLong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_float_array (const ACE_CDR::Float *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_double_array (const ACE_CDR::Double *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_longdouble_array (const ACE_CDR::LongDouble* x, + ACE_CDR::ULong length); + + /// + /// Adjust to @a size and count octets. + void adjust (size_t size); + + /// As above, but now the size and alignment requirements may be + /// different. + void adjust (size_t size, + size_t align); + +private: + /// disallow copying... + ACE_SizeCDR (const ACE_SizeCDR& rhs); + ACE_SizeCDR& operator= (const ACE_SizeCDR& rhs); + + ACE_CDR::Boolean write_1 (const ACE_CDR::Octet *x); + ACE_CDR::Boolean write_2 (const ACE_CDR::UShort *x); + ACE_CDR::Boolean write_4 (const ACE_CDR::ULong *x); + ACE_CDR::Boolean write_8 (const ACE_CDR::ULongLong *x); + ACE_CDR::Boolean write_16 (const ACE_CDR::LongDouble *x); + + /** + * write an array of @a length elements, each of @a size bytes and the + * start aligned at a multiple of . The elements are assumed + * to be packed with the right alignment restrictions. It is mostly + * designed for buffers of the basic types. + * + * This operation uses ; as explained above it is expected + * that using assignment is faster that for one element, + * but for several elements should be more efficient, it + * could be interesting to find the break even point and optimize + * for that case, but that would be too platform dependent. + */ + ACE_CDR::Boolean write_array (const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + + ACE_CDR::Boolean write_wchar_array_i (const ACE_CDR::WChar* x, + ACE_CDR::ULong length); + +private: + /// Set to false when an error ocurrs. + bool good_bit_; + + /// Current size. + size_t size_; + +protected: + /// GIOP version information + ACE_CDR::Octet major_version_; + ACE_CDR::Octet minor_version_; +}; + +// @@ This operator should not be inlined since they force SString.h +// to be included in this header. +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + const ACE_CString &x); + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/CDR_Size.inl" +#else /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Not used by CORBA or TAO +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Char x); + +// CDR size-calculating output operators for primitive types + +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Short x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::UShort x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Long x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::ULong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::LongLong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::ULongLong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR& ss, + ACE_CDR::LongDouble x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Float x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Double x); + +// CDR size-calculating output operator from helper classes + +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_boolean x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_char x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_wchar x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_octet x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_string x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_wstring x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + const ACE_CDR::Char* x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + const ACE_CDR::WChar* x); + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" + +#endif /* ACE_CDR_SIZE_H */ diff --git a/dep/ACE_wrappers/ace/CDR_Size.inl b/dep/ACE_wrappers/ace/CDR_Size.inl new file mode 100644 index 000000000..4ea81523f --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Size.inl @@ -0,0 +1,424 @@ +// -*- C++ -*- +// +// $Id: CDR_Size.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_SizeCDR::ACE_SizeCDR (ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : good_bit_ (true), + size_ (0), + major_version_ (major_version), + minor_version_ (minor_version) +{ +} + +ACE_INLINE bool +ACE_SizeCDR::good_bit (void) const +{ + return this->good_bit_; +} + +ACE_INLINE void +ACE_SizeCDR::reset (void) +{ + this->size_ = 0; +} + +ACE_INLINE size_t +ACE_SizeCDR::total_length (void) const +{ + return this->size_; +} + + +// Encode the CDR stream. + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_octet (ACE_CDR::Octet x) +{ + return this->write_1 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_boolean (ACE_CDR::Boolean x) +{ + return (ACE_CDR::Boolean) this->write_octet (x ? (ACE_CDR::Octet) 1 : (ACE_CDR::Octet) 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_char (ACE_CDR::Char x) +{ + // Note: translator framework is not supported. + // + return this->write_1 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_short (ACE_CDR::Short x) +{ + return this->write_2 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ushort (ACE_CDR::UShort x) +{ + return this->write_2 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_long (ACE_CDR::Long x) +{ + return this->write_4 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulong (ACE_CDR::ULong x) +{ + return this->write_4 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longlong (const ACE_CDR::LongLong &x) +{ + return this->write_8 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulonglong (const ACE_CDR::ULongLong &x) +{ + const void *temp = &x; + return this->write_8 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_float (ACE_CDR::Float x) +{ + const void *temp = &x; + return this->write_4 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_double (const ACE_CDR::Double &x) +{ + const void *temp = &x; + return this->write_8 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longdouble (const ACE_CDR::LongDouble &x) +{ + const void *temp = &x; + return this->write_16 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_string (const ACE_CDR::Char *x) +{ + if (x != 0) + { + const ACE_CDR::ULong len = + static_cast (ACE_OS::strlen (x)); + return this->write_string (len, x); + } + return this->write_string (0, 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_wstring (const ACE_CDR::WChar *x) +{ + if (x != 0) + { + ACE_CDR::ULong len = + static_cast (ACE_OS::strlen (x)); + return this->write_wstring (len, x); + } + return this->write_wstring (0, 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_char_array (const ACE_CDR::Char *x, + ACE_CDR::ULong length) +{ + // Note: translator framework is not supported. + // + return this->write_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_wchar_array (const ACE_CDR::WChar* x, + ACE_CDR::ULong length) +{ + // Note: translator framework is not supported. + // + if (ACE_OutputCDR::wchar_maxbytes () == 0) + { + errno = EACCES; + return (ACE_CDR::Boolean) (this->good_bit_ = false); + } + if (ACE_OutputCDR::wchar_maxbytes () == sizeof (ACE_CDR::WChar)) + return this->write_array (x, + sizeof (ACE_CDR::WChar), + sizeof (ACE_CDR::WChar) == 2 + ? ACE_CDR::SHORT_ALIGN + : ACE_CDR::LONG_ALIGN, + length); + return this->write_wchar_array_i (x,length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_octet_array (const ACE_CDR::Octet* x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_short_array (const ACE_CDR::Short *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ushort_array (const ACE_CDR::UShort *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_long_array (const ACE_CDR::Long *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulong_array (const ACE_CDR::ULong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longlong_array (const ACE_CDR::LongLong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulonglong_array (const ACE_CDR::ULongLong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_float_array (const ACE_CDR::Float *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_double_array (const ACE_CDR::Double *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longdouble_array (const ACE_CDR::LongDouble* x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN, + length); +} + + +// **************************************************************** + + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Char x) +{ + ss.write_char (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Short x) +{ + ss.write_short (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::UShort x) +{ + ss.write_ushort (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Long x) +{ + ss.write_long (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::ULong x) +{ + ss.write_ulong (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::LongLong x) +{ + ss.write_longlong (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::ULongLong x) +{ + ss.write_ulonglong (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::LongDouble x) +{ + ss.write_longdouble (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Float x) +{ + ss.write_float (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Double x) +{ + ss.write_double (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const ACE_CDR::Char *x) +{ + ss.write_string (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const ACE_CDR::WChar *x) +{ + ss.write_wstring (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +// The following use the helper classes +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_boolean x) +{ + ss.write_boolean (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_char x) +{ + ss.write_char (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_wchar x) +{ + ss.write_wchar (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_octet x) +{ + ss.write_octet (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_string x) +{ + ACE_CDR::ULong len = 0; + + if (x.val_ != 0) + { + len = static_cast (ACE_OS::strlen (x.val_)); + } + + ss.write_string (len, x.val_); + return + (ACE_CDR::Boolean) (ss.good_bit () && (!x.bound_ || len <= x.bound_)); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_wstring x) +{ + ACE_CDR::ULong len = 0; + + if (x.val_ != 0) + { + len = static_cast (ACE_OS::strlen (x.val_)); + } + + ss.write_wstring (len, x.val_); + return + (ACE_CDR::Boolean) (ss.good_bit () && (!x.bound_ || len <= x.bound_)); +} + + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/CDR_Stream.cpp b/dep/ACE_wrappers/ace/CDR_Stream.cpp new file mode 100644 index 000000000..80b405467 --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Stream.cpp @@ -0,0 +1,2068 @@ +#include "ace/CDR_Stream.h" +#include "ace/SString.h" +#include "ace/Auto_Ptr.h" +#include "ace/Truncate.h" + +#if !defined (__ACE_INLINE__) +# include "ace/CDR_Stream.inl" +#endif /* ! __ACE_INLINE__ */ + +ACE_RCSID (ace, + CDR_Stream, + "$Id: CDR_Stream.cpp 82559 2008-08-07 20:23:07Z parsons $") + +// **************************************************************** + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +size_t ACE_OutputCDR::wchar_maxbytes_ = sizeof (ACE_CDR::WChar); + +ACE_OutputCDR::ACE_OutputCDR (size_t size, + int byte_order, + ACE_Allocator *buffer_allocator, + ACE_Allocator *data_block_allocator, + ACE_Allocator *message_block_allocator, + size_t memcpy_tradeoff, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ ((size ? size : (size_t) ACE_CDR::DEFAULT_BUFSIZE) + ACE_CDR::MAX_ALIGNMENT, + ACE_Message_Block::MB_DATA, + 0, + 0, + buffer_allocator, + 0, + 0, + ACE_Time_Value::zero, + ACE_Time_Value::max_time, + data_block_allocator, + message_block_allocator), +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + current_alignment_ (0), +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + current_is_writable_ (true), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + memcpy_tradeoff_ (memcpy_tradeoff), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) + +{ + ACE_CDR::mb_align (&this->start_); + this->current_ = &this->start_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->total_length ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_OutputCDR::ACE_OutputCDR (char *data, + size_t size, + int byte_order, + ACE_Allocator *buffer_allocator, + ACE_Allocator *data_block_allocator, + ACE_Allocator *message_block_allocator, + size_t memcpy_tradeoff, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (size, + ACE_Message_Block::MB_DATA, + 0, + data, + buffer_allocator, + 0, + 0, + ACE_Time_Value::zero, + ACE_Time_Value::max_time, + data_block_allocator, + message_block_allocator), +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + current_alignment_ (0), +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + current_is_writable_ (true), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + memcpy_tradeoff_ (memcpy_tradeoff), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ + // We cannot trust the buffer to be properly aligned + ACE_CDR::mb_align (&this->start_); + this->current_ = &this->start_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->total_length ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_OutputCDR::ACE_OutputCDR (ACE_Data_Block *data_block, + int byte_order, + ACE_Allocator *message_block_allocator, + size_t memcpy_tradeoff, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (data_block, + ACE_Message_Block::DONT_DELETE, + message_block_allocator), +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + current_alignment_ (0), +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + current_is_writable_ (true), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + memcpy_tradeoff_ (memcpy_tradeoff), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ + // We cannot trust the buffer to be properly aligned + ACE_CDR::mb_align (&this->start_); + this->current_ = &this->start_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->total_length ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_OutputCDR::ACE_OutputCDR (ACE_Message_Block *data, + int byte_order, + size_t memcpy_tradeoff, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (data->data_block ()->duplicate ()), +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + current_alignment_ (0), +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + current_is_writable_ (true), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + memcpy_tradeoff_ (memcpy_tradeoff), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ + // We cannot trust the buffer to be properly aligned + ACE_CDR::mb_align (&this->start_); + this->current_ = &this->start_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->total_length ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +/*static*/ void +ACE_OutputCDR::wchar_maxbytes (size_t maxbytes) +{ + ACE_OutputCDR::wchar_maxbytes_ = maxbytes; +} + +/*static*/ size_t +ACE_OutputCDR::wchar_maxbytes () +{ + return ACE_OutputCDR::wchar_maxbytes_; +} + +int +ACE_OutputCDR::grow_and_adjust (size_t size, + size_t align, + char*& buf) +{ + if (!this->current_is_writable_ + || this->current_->cont () == 0 + || this->current_->cont ()->size () < size + ACE_CDR::MAX_ALIGNMENT) + { + // Calculate the new buffer's length; if growing for encode, we + // don't grow in "small" chunks because of the cost. + size_t cursize = this->current_->size (); + if (this->current_->cont () != 0) + cursize = this->current_->cont ()->size (); + size_t minsize = size; + +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + minsize += ACE_CDR::MAX_ALIGNMENT; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + // Make sure that there is enough room for bytes, but + // also make it bigger than whatever our current size is. + if (minsize < cursize) + minsize = cursize; + + size_t const newsize = ACE_CDR::next_size (minsize); + + this->good_bit_ = false; + ACE_Message_Block* tmp = 0; + ACE_NEW_RETURN (tmp, + ACE_Message_Block (newsize, + ACE_Message_Block::MB_DATA, + 0, + 0, + this->current_->data_block ()->allocator_strategy (), + 0, + 0, + ACE_Time_Value::zero, + ACE_Time_Value::max_time, + this->current_->data_block ()->data_block_allocator ()), + -1); + + // Message block initialization may fail while the construction + // succeds. Since as a matter of policy, ACE may throw no + // exceptions, we have to do a separate check like this. + if (tmp != 0 && tmp->size () < newsize) + { + delete tmp; + errno = ENOMEM; + return -1; + } + + this->good_bit_ = true; + +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + // The new block must start with the same alignment as the + // previous block finished. + ptrdiff_t const tmpalign = + reinterpret_cast (tmp->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT; + ptrdiff_t const curalign = + static_cast (this->current_alignment_) % ACE_CDR::MAX_ALIGNMENT; + ptrdiff_t offset = curalign - tmpalign; + if (offset < 0) + offset += ACE_CDR::MAX_ALIGNMENT; + tmp->rd_ptr (static_cast (offset)); + tmp->wr_ptr (tmp->rd_ptr ()); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + // grow the chain and set the current block. + tmp->cont (this->current_->cont ()); + this->current_->cont (tmp); + } + this->current_ = this->current_->cont (); + this->current_is_writable_ = true; + + return this->adjust (size, align, buf); +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_wchar (ACE_CDR::WChar x) +{ + if (this->wchar_translator_ != 0) + return (this->good_bit_ = this->wchar_translator_->write_wchar (*this, x)); + if (ACE_OutputCDR::wchar_maxbytes_ == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + if (static_cast (major_version_) == 1 + && static_cast (minor_version_) == 2) + { + ACE_CDR::Octet len = + static_cast (ACE_OutputCDR::wchar_maxbytes_); + if (this->write_1 (&len)) + { + if (ACE_OutputCDR::wchar_maxbytes_ == sizeof(ACE_CDR::WChar)) + return + this->write_octet_array ( + reinterpret_cast (&x), + static_cast (len)); + else + if (ACE_OutputCDR::wchar_maxbytes_ == 2) + { + ACE_CDR::Short sx = static_cast (x); + return + this->write_octet_array ( + reinterpret_cast (&sx), + static_cast (len)); + } + else + { + ACE_CDR::Octet ox = static_cast (x); + return + this->write_octet_array ( + reinterpret_cast (&ox), + static_cast (len)); + } + } + } + else if (static_cast (minor_version_) == 0) + { // wchar is not allowed with GIOP 1.0. + errno = EINVAL; + return (this->good_bit_ = false); + } + if (ACE_OutputCDR::wchar_maxbytes_ == sizeof (ACE_CDR::WChar)) + { + void const * const temp = &x; + return + this->write_4 (reinterpret_cast (temp)); + } + else if (ACE_OutputCDR::wchar_maxbytes_ == 2) + { + ACE_CDR::Short sx = static_cast (x); + return this->write_2 (reinterpret_cast (&sx)); + } + ACE_CDR::Octet ox = static_cast (x); + return this->write_1 (reinterpret_cast (&ox)); +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_string (ACE_CDR::ULong len, + const ACE_CDR::Char *x) +{ + // @@ This is a slight violation of "Optimize for the common case", + // i.e. normally the translator will be 0, but OTOH the code is + // smaller and should be better for the cache ;-) ;-) + if (this->char_translator_ != 0) + return this->char_translator_->write_string (*this, len, x); + + if (len != 0) + { + if (this->write_ulong (len + 1)) + return this->write_char_array (x, len + 1); + } + else + { + // Be nice to programmers: treat nulls as empty strings not + // errors. (OMG-IDL supports languages that don't use the C/C++ + // notion of null v. empty strings; nulls aren't part of the OMG-IDL + // string model.) + if (this->write_ulong (1)) + return this->write_char (0); + } + + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_string (const ACE_CString &x) +{ + // @@ Leave this method in here, not the `.i' file so that we don't + // have to unnecessarily pull in the `ace/SString.h' header. + return this->write_string (static_cast (x.length ()), + x.c_str()); +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_wstring (ACE_CDR::ULong len, + const ACE_CDR::WChar *x) +{ + // @@ This is a slight violation of "Optimize for the common case", + // i.e. normally the translator will be 0, but OTOH the code is + // smaller and should be better for the cache ;-) ;-) + // What do we do for GIOP 1.2??? + if (this->wchar_translator_ != 0) + return this->wchar_translator_->write_wstring (*this, len, x); + if (ACE_OutputCDR::wchar_maxbytes_ == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + if (static_cast (this->major_version_) == 1 + && static_cast (this->minor_version_) == 2) + { + if (x != 0) + { + //In GIOP 1.2 the length field contains the number of bytes + //the wstring occupies rather than number of wchars + //Taking sizeof might not be a good way! This is a temporary fix. + ACE_CDR::Boolean good_ulong = + this->write_ulong ( + ACE_Utils::truncate_cast ( + ACE_OutputCDR::wchar_maxbytes_ * len)); + + if (good_ulong) + { + return this->write_wchar_array (x, len); + } + } + else + { + //In GIOP 1.2 zero length wstrings are legal + return this->write_ulong (0); + } + } + + else + if (x != 0) + { + if (this->write_ulong (len + 1)) + return this->write_wchar_array (x, len + 1); + } + else if (this->write_ulong (1)) + return this->write_wchar (0); + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_octet_array_mb (const ACE_Message_Block* mb) +{ + // If the buffer is small and it fits in the current message + // block it is be cheaper just to copy the buffer. + for (const ACE_Message_Block* i = mb; + i != 0; + i = i->cont ()) + { + size_t const length = i->length (); + + // If the mb does not own its data we are forced to make a copy. + if (ACE_BIT_ENABLED (i->flags (), + ACE_Message_Block::DONT_DELETE)) + { + if (! this->write_array (i->rd_ptr (), + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + static_cast (length))) + return (this->good_bit_ = false); + continue; + } + + if (length < this->memcpy_tradeoff_ + && this->current_->wr_ptr () + length < this->current_->end ()) + { + if (! this->write_array (i->rd_ptr (), + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + static_cast (length))) + return (this->good_bit_ = false); + continue; + } + + ACE_Message_Block* cont = 0; + this->good_bit_ = false; + ACE_NEW_RETURN (cont, + ACE_Message_Block (i->data_block ()->duplicate ()), + false); + this->good_bit_ = true; + + if (this->current_->cont () != 0) + ACE_Message_Block::release (this->current_->cont ()); + cont->rd_ptr (i->rd_ptr ()); + cont->wr_ptr (i->wr_ptr ()); + + this->current_->cont (cont); + this->current_ = cont; + this->current_is_writable_ = false; +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + this->current_alignment_ = + (this->current_alignment_ + cont->length ()) % ACE_CDR::MAX_ALIGNMENT; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + } + + return true; +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_1 (const ACE_CDR::Octet *x) +{ + char *buf = 0; + if (this->adjust (1, buf) == 0) + { + *reinterpret_cast (buf) = *x; + return true; + } + + return false; +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_2 (const ACE_CDR::UShort *x) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::SHORT_SIZE, buf) == 0) + { +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *reinterpret_cast (buf) = *x; + return true; +#else + if (!this->do_byte_swap_) + { + *reinterpret_cast (buf) = *x; + return true; + } + else + { + ACE_CDR::swap_2 (reinterpret_cast (x), buf); + return true; + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + } + + return false; +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_4 (const ACE_CDR::ULong *x) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::LONG_SIZE, buf) == 0) + { +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *reinterpret_cast (buf) = *x; + return true; +#else + if (!this->do_byte_swap_) + { + *reinterpret_cast (buf) = *x; + return true; + } + else + { + ACE_CDR::swap_4 (reinterpret_cast (x), buf); + return true; + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + } + + return false; +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_8 (const ACE_CDR::ULongLong *x) +{ + char *buf = 0; + + if (this->adjust (ACE_CDR::LONGLONG_SIZE, buf) == 0) + { +#if defined (__arm__) + // Convert to Intel format (12345678 => 56781234) + const char *orig = reinterpret_cast (x); + char *target = buf; + register ACE_UINT32 x = + *reinterpret_cast (orig); + register ACE_UINT32 y = + *reinterpret_cast (orig + 4); + *reinterpret_cast (target) = y; + *reinterpret_cast (target + 4) = x; + return true; +#else +# if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *reinterpret_cast (buf) = *x; + return true; +# else + if (!this->do_byte_swap_) + { + *reinterpret_cast (buf) = *x; + return true; + } + else + { + ACE_CDR::swap_8 (reinterpret_cast (x), buf); + return true; + } +# endif /* ACE_ENABLE_SWAP_ON_WRITE */ +#endif /* !__arm__ */ + } + + return false; +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_16 (const ACE_CDR::LongDouble *x) +{ + char* buf = 0; + if (this->adjust (ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN, + buf) == 0) + { +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *reinterpret_cast (buf) = *x; + return 1; +#else + if (!this->do_byte_swap_) + { + *reinterpret_cast (buf) = *x; + return true; + } + else + { + ACE_CDR::swap_16 (reinterpret_cast (x), buf); + return true; + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + } + + return false; +} + +ACE_CDR::Boolean +ACE_OutputCDR::write_wchar_array_i (const ACE_CDR::WChar *x, + ACE_CDR::ULong length) +{ + if (length == 0) + return true; + char* buf = 0; + size_t const align = (ACE_OutputCDR::wchar_maxbytes_ == 2) ? + ACE_CDR::SHORT_ALIGN : + ACE_CDR::OCTET_ALIGN; + + if (this->adjust (ACE_OutputCDR::wchar_maxbytes_ * length, align, buf) == 0) + { + if (ACE_OutputCDR::wchar_maxbytes_ == 2) + { + ACE_CDR::UShort *sb = reinterpret_cast (buf); + for (size_t i = 0; i < length; ++i) +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + sb[i] = static_cast (x[i]); +#else + if (!this->do_byte_swap_) + sb[i] = static_cast (x[i]); + else + { + ACE_CDR::UShort sx = static_cast (x[i]); + ACE_CDR::swap_2 (reinterpret_cast (&sx), &buf[i * 2]); + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + } + else + { + for (size_t i = 0; i < length; ++i) + buf[i] = static_cast (x[i]); + } + return this->good_bit_; + } + return false; +} + + +ACE_CDR::Boolean +ACE_OutputCDR::write_array (const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + if (length == 0) + return true; + char *buf = 0; + if (this->adjust (size * length, align, buf) == 0) + { +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + ACE_OS::memcpy (buf, x, size*length); + return true; +#else + if (!this->do_byte_swap_ || size == 1) + { + ACE_OS::memcpy (buf, x, size*length); + return true; + } + else + { + const char *source = reinterpret_cast (x); + switch (size) + { + case 2: + ACE_CDR::swap_2_array (source, buf, length); + return true; + case 4: + ACE_CDR::swap_4_array (source, buf, length); + return true; + case 8: + ACE_CDR::swap_8_array (source, buf, length); + return true; + case 16: + ACE_CDR::swap_16_array (source, buf, length); + return true; + default: + // TODO: print something? + this->good_bit_ = false; + return false; + } + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + } + this->good_bit_ = false; + return false; +} + + +ACE_CDR::Boolean +ACE_OutputCDR::write_boolean_array (const ACE_CDR::Boolean* x, + ACE_CDR::ULong length) +{ + // It is hard to optimize this, the spec requires that on the wire + // booleans be represented as a byte with value 0 or 1, but in + // memory it is possible (though very unlikely) that a boolean has + // a non-zero value (different from 1). + // We resort to a simple loop. + ACE_CDR::Boolean const * const end = x + length; + + for (ACE_CDR::Boolean const * i = x; + i != end && this->good_bit (); + ++i) + (void) this->write_boolean (*i); + + return this->good_bit (); +} + + +char * +ACE_OutputCDR::write_long_placeholder (void) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::LONG_SIZE, buf) == 0) + *reinterpret_cast (buf) = 0; + else + buf = 0; + return buf; +} + + +char * +ACE_OutputCDR::write_short_placeholder (void) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::SHORT_SIZE, buf) == 0) + *reinterpret_cast (buf) = 0; + else + buf = 0; + return buf; +} + + +ACE_CDR::Boolean +ACE_OutputCDR::replace (ACE_CDR::Long x, char* loc) +{ + if (this->find (loc) == 0) + return false; + +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *reinterpret_cast (loc) = x; +#else + if (!this->do_byte_swap_) + { + *reinterpret_cast (loc) = x; + } + else + { + ACE_CDR::swap_4 (reinterpret_cast (&x), loc); + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + + return true; +} + + +ACE_CDR::Boolean +ACE_OutputCDR::replace (ACE_CDR::Short x, char* loc) +{ + if (this->find (loc) == 0) + return false; + +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *reinterpret_cast (loc) = x; +#else + if (!this->do_byte_swap_) + { + *reinterpret_cast (loc) = x; + } + else + { + ACE_CDR::swap_2 (reinterpret_cast (&x), loc); + } +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + + return true; +} + + +int +ACE_OutputCDR::consolidate (void) +{ + // Optimize by only doing something if we need to + if (this->current_ != &this->start_) + { + // Set the number of bytes in the top-level block, reallocating + // if necessary. The rd_ptr and wr_ptr remain at the original offsets + // into the buffer, even if it is reallocated. + // Return an error if the allocation failed. + size_t const newsize = + ACE_CDR::first_size (this->total_length () + + ACE_CDR::MAX_ALIGNMENT); + if (this->start_.size (newsize) < 0) + { + return -1; + } + + // Consolidate the chain into the first block. NOTE that + // ACE_CDR::consolidate can not be used since we don't want to + // overwrite what is already in the first block. We just append it since + // the read and write pointers weren't affected by the resizing above. + // We also don't have to worry about alignment since the start block is + // already aligned. + // NOTE also we know there is a continuation since we checked for it + // above. There is therefore no reason to check for a 0 continuation + // field here. + ACE_Message_Block *cont = this->start_.cont (); + for (const ACE_Message_Block* i = cont; i != 0; i = i->cont ()) + { + this->start_.copy (i->rd_ptr (), i->length ()); + } + + // Release the old blocks that were consolidated and reset the + // current_ and current_is_writable_ to reflect the single used block. + ACE_Message_Block::release (cont); + this->start_.cont (0); + this->current_ = &this->start_; + this->current_is_writable_ = true; + } + + return 0; +} + + +ACE_Message_Block* +ACE_OutputCDR::find (char* loc) +{ + ACE_Message_Block* mb = 0; + for (mb = &this->start_; mb != 0; mb = mb->cont ()) + { + if (loc <= mb->wr_ptr () && loc >= mb->rd_ptr ()) + { + break; + } + } + + return mb; +} + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + +void +ACE_OutputCDR::register_monitor (const char *id) +{ + this->monitor_->name (id); + this->monitor_->add_to_registry (); +} + +void +ACE_OutputCDR::unregister_monitor (void) +{ + this->monitor_->remove_from_registry (); +} + +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + +// **************************************************************** + +ACE_InputCDR::ACE_InputCDR (const char *buf, + size_t bufsiz, + int byte_order, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (buf, bufsiz), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ + this->start_.wr_ptr (bufsiz); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (bufsiz); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (size_t bufsiz, + int byte_order, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (bufsiz), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (bufsiz); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (const ACE_Message_Block *data, + int byte_order, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version, + ACE_Lock* lock) + : start_ (0, ACE_Message_Block::MB_DATA, 0, 0, 0, lock), + good_bit_ (true), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + this->reset (data, byte_order); +} + +ACE_InputCDR::ACE_InputCDR (ACE_Data_Block *data, + ACE_Message_Block::Message_Flags flag, + int byte_order, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (data, flag), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (data->size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (ACE_Data_Block *data, + ACE_Message_Block::Message_Flags flag, + size_t rd_pos, + size_t wr_pos, + int byte_order, + ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : start_ (data, flag), + do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER), + good_bit_ (true), + major_version_ (major_version), + minor_version_ (minor_version), + char_translator_ (0), + wchar_translator_ (0) +{ + // Set the read pointer + this->start_.rd_ptr (rd_pos); + + // Set the write pointer after doing a sanity check. + char* wrpos = this->start_.base () + wr_pos; + + if (this->start_.end () >= wrpos) + { + this->start_.wr_ptr (wr_pos); + } + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (data->size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (const ACE_InputCDR& rhs, + size_t size, + ACE_CDR::Long offset) + : start_ (rhs.start_, + ACE_CDR::MAX_ALIGNMENT), + do_byte_swap_ (rhs.do_byte_swap_), + good_bit_ (true), + major_version_ (rhs.major_version_), + minor_version_ (rhs.minor_version_), + char_translator_ (rhs.char_translator_), + wchar_translator_ (rhs.wchar_translator_) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + // Align the base pointer assuming that the incoming stream is also + // aligned the way we are aligned + char *incoming_start = ACE_ptr_align_binary (rhs.start_.base (), + ACE_CDR::MAX_ALIGNMENT); +#else + char *incoming_start = rhs.start_.base (); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + const size_t newpos = + (rhs.start_.rd_ptr() - incoming_start) + offset; + + if (newpos <= this->start_.space () + && newpos + size <= this->start_.space ()) + { + this->start_.rd_ptr (newpos); + this->start_.wr_ptr (newpos + size); + } + else + { + this->good_bit_ = false; + } + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (const ACE_InputCDR& rhs, + size_t size) + : start_ (rhs.start_, + ACE_CDR::MAX_ALIGNMENT), + do_byte_swap_ (rhs.do_byte_swap_), + good_bit_ (true), + major_version_ (rhs.major_version_), + minor_version_ (rhs.minor_version_), + char_translator_ (rhs.char_translator_), + wchar_translator_ (rhs.wchar_translator_) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + // Align the base pointer assuming that the incoming stream is also + // aligned the way we are aligned + char *incoming_start = ACE_ptr_align_binary (rhs.start_.base (), + ACE_CDR::MAX_ALIGNMENT); +#else + char *incoming_start = rhs.start_.base (); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + const size_t newpos = + rhs.start_.rd_ptr() - incoming_start; + + if (newpos <= this->start_.space () + && newpos + size <= this->start_.space ()) + { + // Notice that ACE_Message_Block::duplicate may leave the + // wr_ptr() with a higher value than what we actually want. + this->start_.rd_ptr (newpos); + this->start_.wr_ptr (newpos + size); + + ACE_CDR::Octet byte_order = 0; + (void) this->read_octet (byte_order); + this->do_byte_swap_ = (byte_order != ACE_CDR_BYTE_ORDER); + } + else + { + this->good_bit_ = false; + } + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (const ACE_InputCDR& rhs) + : start_ (rhs.start_, + ACE_CDR::MAX_ALIGNMENT), + do_byte_swap_ (rhs.do_byte_swap_), + good_bit_ (true), + major_version_ (rhs.major_version_), + minor_version_ (rhs.minor_version_), + char_translator_ (rhs.char_translator_), + wchar_translator_ (rhs.wchar_translator_) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + char *buf = ACE_ptr_align_binary (rhs.start_.base (), + ACE_CDR::MAX_ALIGNMENT); +#else + char *buf = rhs.start_.base (); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + size_t rd_offset = rhs.start_.rd_ptr () - buf; + size_t wr_offset = rhs.start_.wr_ptr () - buf; + this->start_.rd_ptr (rd_offset); + this->start_.wr_ptr (wr_offset); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR::ACE_InputCDR (ACE_InputCDR::Transfer_Contents x) + : start_ (x.rhs_.start_.data_block ()), + do_byte_swap_ (x.rhs_.do_byte_swap_), + good_bit_ (true), + major_version_ (x.rhs_.major_version_), + minor_version_ (x.rhs_.minor_version_), + char_translator_ (x.rhs_.char_translator_), + wchar_translator_ (x.rhs_.wchar_translator_) +{ + this->start_.rd_ptr (x.rhs_.start_.rd_ptr ()); + this->start_.wr_ptr (x.rhs_.start_.wr_ptr ()); + + ACE_Data_Block* db = this->start_.data_block ()->clone_nocopy (); + (void) x.rhs_.start_.replace_data_block (db); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_InputCDR& +ACE_InputCDR::operator= (const ACE_InputCDR& rhs) +{ + if (this != &rhs) + { + this->start_.data_block (rhs.start_.data_block ()->duplicate ()); + this->start_.rd_ptr (rhs.start_.rd_ptr ()); + this->start_.wr_ptr (rhs.start_.wr_ptr ()); + this->do_byte_swap_ = rhs.do_byte_swap_; + this->good_bit_ = true; + this->char_translator_ = rhs.char_translator_; + this->major_version_ = rhs.major_version_; + this->minor_version_ = rhs.minor_version_; + } + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + return *this; +} + +ACE_InputCDR::ACE_InputCDR (const ACE_OutputCDR& rhs, + ACE_Allocator* buffer_allocator, + ACE_Allocator* data_block_allocator, + ACE_Allocator* message_block_allocator) + : start_ (rhs.total_length () + ACE_CDR::MAX_ALIGNMENT, + ACE_Message_Block::MB_DATA, + 0, + 0, + buffer_allocator, + 0, + 0, + ACE_Time_Value::zero, + ACE_Time_Value::max_time, + data_block_allocator, + message_block_allocator), + do_byte_swap_ (rhs.do_byte_swap_), + good_bit_ (true), + major_version_ (rhs.major_version_), + minor_version_ (rhs.minor_version_), + char_translator_ (rhs.char_translator_), + wchar_translator_ (rhs.wchar_translator_) +{ + ACE_CDR::mb_align (&this->start_); + for (const ACE_Message_Block *i = rhs.begin (); + i != rhs.end (); + i = i->cont ()) + { + this->start_.copy (i->rd_ptr (), i->length ()); + } + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE_NEW (this->monitor_, + ACE::Monitor_Control::Size_Monitor); + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_CDR::Boolean +ACE_InputCDR::skip_wchar (void) +{ + if (static_cast (major_version_) == 1 + && static_cast (minor_version_) == 2) + { + ACE_CDR::Octet len; + if (this->read_1 (&len)) + return this->skip_bytes (static_cast (len)); + } + else + { + ACE_CDR::WChar x; + void * const temp = &x; + if (ACE_OutputCDR::wchar_maxbytes_ == 2) + return this->read_2 (reinterpret_cast (temp)); + else + return this->read_4 (reinterpret_cast (temp)); + } + + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_InputCDR::read_wchar (ACE_CDR::WChar& x) +{ + if (this->wchar_translator_ != 0) + { + this->good_bit_ = this->wchar_translator_->read_wchar (*this,x); + return this->good_bit_; + } + if (ACE_OutputCDR::wchar_maxbytes_ == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + if (ACE_OutputCDR::wchar_maxbytes_ == sizeof (ACE_CDR::WChar)) + { + if (static_cast (major_version_) == 1 + && static_cast (minor_version_) == 2) + { + ACE_CDR::Octet len; + + if (this->read_1 (&len)) + return this->read_array + (reinterpret_cast (&x), + static_cast (len), + ACE_CDR::OCTET_ALIGN, + 1); + + else + return (this->good_bit_ = false); + } + + void * const temp = &x; + if (sizeof (ACE_CDR::WChar) == 2) + return this->read_2 (reinterpret_cast (temp)); + else + return this->read_4 (reinterpret_cast (temp)); + } + + if (static_cast (major_version_) == 1 + && static_cast (minor_version_) == 2) + { + ACE_CDR::Octet len; + + if (this->read_1 (&len)) + { + if (len == 2) + { + ACE_CDR::Short sx; + if (this->read_array + (reinterpret_cast (&sx), + static_cast (len), + ACE_CDR::OCTET_ALIGN, + 1)) + { + x = static_cast (sx); + return true; + } + } + else + { + ACE_CDR::Octet ox; + if (this->read_array + (reinterpret_cast (&ox), + static_cast (len), + ACE_CDR::OCTET_ALIGN, + 1)) + { + x = static_cast (ox); + return true; + } + } + } + } + else + { + if (ACE_OutputCDR::wchar_maxbytes_ == 2) + { + ACE_CDR::UShort sx; + if (this->read_2 (reinterpret_cast (&sx))) + { + x = static_cast (sx); + return true; + } + } + else + { + ACE_CDR::Octet ox; + if (this->read_1 (&ox)) + { + x = static_cast (ox); + return true; + } + + } + } + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_InputCDR::read_string (ACE_CDR::Char *&x) +{ + // @@ This is a slight violation of "Optimize for the common case", + // i.e. normally the translator will be 0, but OTOH the code is + // smaller and should be better for the cache ;-) ;-) + if (this->char_translator_ != 0) + { + this->good_bit_ = this->char_translator_->read_string (*this, x); + return this->good_bit_; + } + + ACE_CDR::ULong len = 0; + + if (!this->read_ulong (len)) + return false; + + // A check for the length being too great is done later in the + // call to read_char_array but we want to have it done before + // the memory is allocated. + if (len > 0 && len <= this->length()) + { + ACE_NEW_RETURN (x, + ACE_CDR::Char[len], + 0); + + ACE_Auto_Basic_Array_Ptr safe_data (x); + + if (this->read_char_array (x, len)) + { + (void) safe_data.release (); + return true; + } + } + else if (len == 0) + { + // Convert any null strings to empty strings since empty + // strings can cause crashes. (See bug 58.) + ACE_NEW_RETURN (x, + ACE_CDR::Char[1], + 0); + ACE_OS::strcpy (const_cast (x), ""); + return true; + } + + x = 0; + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_InputCDR::read_string (ACE_CString &x) +{ + ACE_CDR::Char * data = 0; + if (this->read_string (data)) + { + ACE_Auto_Basic_Array_Ptr safe_data (data); + x = data; + return true; + } + + x = ""; + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_InputCDR::read_wstring (ACE_CDR::WChar*& x) +{ + // @@ This is a slight violation of "Optimize for the common case", + // i.e. normally the translator will be 0, but OTOH the code is + // smaller and should be better for the cache ;-) ;-) + if (this->wchar_translator_ != 0) + { + this->good_bit_ = this->wchar_translator_->read_wstring (*this, x); + return this->good_bit_; + } + if (ACE_OutputCDR::wchar_maxbytes_ == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + ACE_CDR::ULong len = 0; + + if (!this->read_ulong (len)) + { + return false; + } + + // A check for the length being too great is done later in the + // call to read_char_array but we want to have it done before + // the memory is allocated. + if (len > 0 && len <= this->length ()) + { + ACE_Auto_Basic_Array_Ptr safe_data; + + if (static_cast (this->major_version_) == 1 + && static_cast (this->minor_version_) == 2) + { + len /= + ACE_Utils::truncate_cast ( + ACE_OutputCDR::wchar_maxbytes_); + + //allocating one extra for the null character needed by applications + ACE_NEW_RETURN (x, + ACE_CDR::WChar [len + 1], + false); + + ACE_auto_ptr_reset (safe_data, x); + + if (this->read_wchar_array (x, len)) + { + + //Null character used by applications to find the end of + //the wstring + //Is this okay with the GIOP 1.2 spec?? + x[len] = '\x00'; + + (void) safe_data.release (); + + return true; + } + } + else + { + ACE_NEW_RETURN (x, + ACE_CDR::WChar [len], + false); + + ACE_auto_ptr_reset (safe_data, x); + + if (this->read_wchar_array (x, len)) + { + (void) safe_data.release (); + + return true; + } + } + } + else if (len == 0) + { + // Convert any null strings to empty strings since empty + // strings can cause crashes. (See bug 58.) + ACE_NEW_RETURN (x, + ACE_CDR::WChar[1], + false); + x[0] = '\x00'; + return true; + } + + this->good_bit_ = false; + x = 0; + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_array (void* x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + if (length == 0) + return true; + char* buf = 0; + + if (this->adjust (size * length, align, buf) == 0) + { +#if defined (ACE_DISABLE_SWAP_ON_READ) + ACE_OS::memcpy (x, buf, size*length); +#else + if (!this->do_byte_swap_ || size == 1) + ACE_OS::memcpy (x, buf, size*length); + else + { + char *target = reinterpret_cast (x); + switch (size) + { + case 2: + ACE_CDR::swap_2_array (buf, target, length); + break; + case 4: + ACE_CDR::swap_4_array (buf, target, length); + break; + case 8: + ACE_CDR::swap_8_array (buf, target, length); + break; + case 16: + ACE_CDR::swap_16_array (buf, target, length); + break; + default: + // TODO: print something? + this->good_bit_ = false; + return false; + } + } +#endif /* ACE_DISABLE_SWAP_ON_READ */ + return this->good_bit_; + } + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_wchar_array_i (ACE_CDR::WChar* x, + ACE_CDR::ULong length) +{ + if (length == 0) + return true; + char* buf = 0; + size_t const align = (ACE_OutputCDR::wchar_maxbytes_ == 2) ? + ACE_CDR::SHORT_ALIGN : + ACE_CDR::OCTET_ALIGN; + + if (this->adjust (ACE_OutputCDR::wchar_maxbytes_ * length, align, buf) == 0) + { + if (ACE_OutputCDR::wchar_maxbytes_ == 2) + { + ACE_CDR::UShort *sb = reinterpret_cast (buf); + for (size_t i = 0; i < length; ++i) +#if defined (ACE_DISABLE_SWAP_ON_READ) + x[i] = static_cast (sb[i]); +#else + if (!this->do_byte_swap_) + x[i] = static_cast (sb[i]); + else + { + ACE_CDR::UShort sx; + ACE_CDR::swap_2 (&buf[i * 2], reinterpret_cast (&sx)); + x[i] = static_cast (sx); + } +#endif /* ACE_DISABLE_SWAP_ON_READ */ + } + else + { + for (size_t i = 0; i < length; ++i) + x[i] = static_cast (buf[i]); + } + return this->good_bit_; + } + return false; +} + + +ACE_CDR::Boolean +ACE_InputCDR::read_boolean_array (ACE_CDR::Boolean *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length > this->length ()) + { + this->good_bit_ = false; + return false; + } + + // It is hard to optimize this, the spec requires that on the wire + // booleans be represented as a byte with value 0 or 1, but in + // memory it is possible (though very unlikely) that a boolean has + // a non-zero value (different from 1). + // We resort to a simple loop. + for (ACE_CDR::ULong i = 0; i != length && this->good_bit_; ++i) + (void) this->read_boolean (x[i]); + + return this->good_bit_; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_1 (ACE_CDR::Octet *x) +{ + if (this->rd_ptr () < this->wr_ptr ()) + { + *x = *reinterpret_cast (this->rd_ptr ()); + this->start_.rd_ptr (1); + return true; + } + + this->good_bit_ = false; + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_2 (ACE_CDR::UShort *x) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::SHORT_SIZE, buf) == 0) + { +#if !defined (ACE_DISABLE_SWAP_ON_READ) + if (!this->do_byte_swap_) + *x = *reinterpret_cast (buf); + else + ACE_CDR::swap_2 (buf, reinterpret_cast (x)); +#else + *x = *reinterpret_cast (buf); +#endif /* ACE_DISABLE_SWAP_ON_READ */ + return true; + } + this->good_bit_ = false; + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_4 (ACE_CDR::ULong *x) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::LONG_SIZE, buf) == 0) + { +#if !defined (ACE_DISABLE_SWAP_ON_READ) + if (!this->do_byte_swap_) + *x = *reinterpret_cast (buf); + else + ACE_CDR::swap_4 (buf, reinterpret_cast (x)); +#else + *x = *reinterpret_cast (buf); +#endif /* ACE_DISABLE_SWAP_ON_READ */ + return true; + } + this->good_bit_ = false; + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_8 (ACE_CDR::ULongLong *x) +{ + char *buf = 0; + + if (this->adjust (ACE_CDR::LONGLONG_SIZE, buf) == 0) + { +#if !defined (ACE_DISABLE_SWAP_ON_READ) +# if defined (__arm__) + if (!this->do_byte_swap_) + { + // Convert from Intel format (12345678 => 56781234) + const char *orig = buf; + char *target = reinterpret_cast (x); + register ACE_UINT32 x = + *reinterpret_cast (orig); + register ACE_UINT32 y = + *reinterpret_cast (orig + 4); + *reinterpret_cast (target) = y; + *reinterpret_cast (target + 4) = x; + } + else + { + // Convert from Sparc format (12345678 => 43218765) + const char *orig = buf; + char *target = reinterpret_cast (x); + register ACE_UINT32 x = + *reinterpret_cast (orig); + register ACE_UINT32 y = + *reinterpret_cast (orig + 4); + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); + y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24); + *reinterpret_cast (target) = x; + *reinterpret_cast (target + 4) = y; + } +# else + if (!this->do_byte_swap_) + *x = *reinterpret_cast (buf); + else + ACE_CDR::swap_8 (buf, reinterpret_cast (x)); +# endif /* !__arm__ */ +#else + *x = *reinterpret_cast (buf); +#endif /* ACE_DISABLE_SWAP_ON_READ */ + return true; + } + + this->good_bit_ = false; + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::read_16 (ACE_CDR::LongDouble *x) +{ + char *buf = 0; + if (this->adjust (ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN, + buf) == 0) + { +#if !defined (ACE_DISABLE_SWAP_ON_READ) + if (!this->do_byte_swap_) + *x = *reinterpret_cast (buf); + else + ACE_CDR::swap_16 (buf, reinterpret_cast (x)); +#else + *x = *reinterpret_cast (buf); +#endif /* ACE_DISABLE_SWAP_ON_READ */ + return true; + } + + this->good_bit_ = false; + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::skip_string (void) +{ + ACE_CDR::ULong len = 0; + if (this->read_ulong (len)) + { + if (this->rd_ptr () + len <= this->wr_ptr ()) + { + this->rd_ptr (len); + return true; + } + this->good_bit_ = false; + } + return false; +} + +ACE_CDR::Boolean +ACE_InputCDR::skip_wstring (void) +{ + ACE_CDR::ULong len = 0; + ACE_CDR::Boolean continue_skipping = read_ulong (len); + + if (continue_skipping && len != 0) + { + if (static_cast (this->major_version_) == 1 + && static_cast (this->minor_version_) == 2) + continue_skipping = this->skip_bytes ((size_t)len); + else + while (continue_skipping && len--) + continue_skipping = this->skip_wchar (); + } + return continue_skipping; +} + +ACE_CDR::Boolean +ACE_InputCDR::skip_bytes (size_t len) +{ + if (this->rd_ptr () + len <= this->wr_ptr ()) + { + this->rd_ptr (len); + return true; + } + this->good_bit_ = false; + return false; +} + +int +ACE_InputCDR::grow (size_t newsize) +{ + if (ACE_CDR::grow (&this->start_, newsize) == -1) + return -1; + + ACE_CDR::mb_align (&this->start_); + this->start_.wr_ptr (newsize); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + if (newsize > this->start_.total_size ()) + { + this->monitor_->receive (newsize); + } +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + return 0; +} + +void +ACE_InputCDR::reset (const ACE_Message_Block* data, + int byte_order) +{ + this->reset_byte_order (byte_order); + ACE_CDR::consolidate (&this->start_, data); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +void +ACE_InputCDR::steal_from (ACE_InputCDR &cdr) +{ + this->do_byte_swap_ = cdr.do_byte_swap_; + this->start_.data_block (cdr.start_.data_block ()->duplicate ()); + + // If the message block had a DONT_DELETE flags, just clear it off.. + this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE); + this->start_.rd_ptr (cdr.start_.rd_ptr ()); + + this->start_.wr_ptr (cdr.start_.wr_ptr ()); + this->major_version_ = cdr.major_version_; + this->minor_version_ = cdr.minor_version_; + cdr.reset_contents (); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +void +ACE_InputCDR::exchange_data_blocks (ACE_InputCDR &cdr) +{ + // Exchange byte orders + int const byte_order = cdr.do_byte_swap_; + cdr.do_byte_swap_ = this->do_byte_swap_; + this->do_byte_swap_ = byte_order; + + // Get the destination read and write pointers + size_t const drd_pos = + cdr.start_.rd_ptr () - cdr.start_.base (); + size_t const dwr_pos = + cdr.start_.wr_ptr () - cdr.start_.base (); + + // Get the source read & write pointers + size_t const srd_pos = + this->start_.rd_ptr () - this->start_.base (); + size_t const swr_pos = + this->start_.wr_ptr () - this->start_.base (); + + // Exchange data_blocks. Dont release any of the data blocks. + ACE_Data_Block *dnb = + this->start_.replace_data_block (cdr.start_.data_block ()); + cdr.start_.replace_data_block (dnb); + + // Exchange the flags information.. + ACE_Message_Block::Message_Flags df = cdr.start_.self_flags (); + ACE_Message_Block::Message_Flags sf = this->start_.self_flags (); + + cdr.start_.clr_self_flags (df); + this->start_.clr_self_flags (sf); + + cdr.start_.set_self_flags (sf); + this->start_.set_self_flags (df); + + // Reset the pointers to zero before it is set again. + cdr.start_.reset (); + this->start_.reset (); + + // Set the read and write pointers. + if (cdr.start_.size () >= srd_pos) + { + cdr.start_.rd_ptr (srd_pos); + } + + if (cdr.start_.size () >= swr_pos) + { + cdr.start_.wr_ptr (swr_pos); + } + + if (this->start_.size () >= drd_pos) + { + this->start_.rd_ptr (drd_pos); + } + + if (this->start_.size () >= dwr_pos) + { + this->start_.wr_ptr (dwr_pos); + } + + ACE_CDR::Octet const dmajor = cdr.major_version_; + ACE_CDR::Octet const dminor = cdr.minor_version_; + + // Exchange the GIOP version info + cdr.major_version_ = this->major_version_; + cdr.minor_version_ = this->minor_version_; + + this->major_version_ = dmajor; + this->minor_version_ = dminor; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_Data_Block * +ACE_InputCDR::clone_from (ACE_InputCDR &cdr) +{ + this->do_byte_swap_ = cdr.do_byte_swap_; + + // Get the read & write pointer positions in the incoming CDR + // streams + char *rd_ptr = cdr.start_.rd_ptr (); + char *wr_ptr = cdr.start_.wr_ptr (); + + // Now reset the incoming CDR stream + cdr.start_.reset (); + + // As we have reset the stream, try to align the underlying message + // block in the incoming stream + ACE_CDR::mb_align (&cdr.start_); + + // Get the read & write pointer positions again + char *nrd_ptr = cdr.start_.rd_ptr (); + char *nwr_ptr = cdr.start_.wr_ptr (); + + // Actual length of the stream is.. + // @todo: This will look idiotic, but we dont seem to have much of a + // choice. How do we calculate the length of the incoming stream? + // Calling the method before calling reset () would give us the + // wrong length of the stream that needs copying. So we do the + // calulation like this + // (1) We get the and positions of the incoming + // stream. + // (2) Then we reset the stream and then align it. + // (3) We get the and positions again. (Points #1 + // thru #3 has been done already) + // (4) The difference in the and positions gives + // us the following, the actual bytes traversed by the and + // . + // (5) The bytes traversed by the is the actual length of + // the stream. + + // Actual bytes traversed + size_t rd_bytes = rd_ptr - nrd_ptr; + size_t wr_bytes = wr_ptr - nwr_ptr; + + ACE_CDR::mb_align (&this->start_); + + ACE_Data_Block *db = + this->start_.data_block (); + + // If the size of the data that needs to be copied are higher than + // what is available, then do a reallocation. + if (wr_bytes > (this->start_.size () - ACE_CDR::MAX_ALIGNMENT)) + { + // @@NOTE: We need to probably add another method to the message + // block interface to simplify this + db = + cdr.start_.data_block ()->clone_nocopy (); + + if (db == 0 || db->size ((wr_bytes) + + ACE_CDR::MAX_ALIGNMENT) == -1) + return 0; + + // Replace our data block by using the incoming CDR stream. + db = this->start_.replace_data_block (db); + + // Align the start_ message block. + ACE_CDR::mb_align (&this->start_); + + // Clear the DONT_DELETE flag if it has been set + this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE); + } + + // Now do the copy + (void) ACE_OS::memcpy (this->start_.wr_ptr (), + cdr.start_.rd_ptr (), + wr_bytes); + + // Set the read pointer position to the same point as that was in + // cdr. + this->start_.rd_ptr (rd_bytes); + this->start_.wr_ptr (wr_bytes); + + // We have changed the read & write pointers for the incoming + // stream. Set them back to the positions that they were before.. + cdr.start_.rd_ptr (rd_bytes); + cdr.start_.wr_ptr (wr_bytes); + + this->major_version_ = cdr.major_version_; + this->minor_version_ = cdr.minor_version_; + + // Copy the char/wchar translators + this->char_translator_ = cdr.char_translator_; + this->wchar_translator_ = cdr.wchar_translator_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + return db; +} + +ACE_Message_Block* +ACE_InputCDR::steal_contents (void) +{ + ACE_Message_Block* block = this->start_.clone (); + this->start_.data_block (block->data_block ()->clone ()); + + // If at all our message had a DONT_DELETE flag set, just clear it + // off. + this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE); + + ACE_CDR::mb_align (&this->start_); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + return block; +} + +void +ACE_InputCDR::reset_contents (void) +{ + this->start_.data_block (this->start_.data_block ()->clone_nocopy ()); + + // Reset the flags... + this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + +void +ACE_InputCDR::register_monitor (const char *id) +{ + this->monitor_->name (id); + this->monitor_->add_to_registry (); +} + +void +ACE_InputCDR::unregister_monitor (void) +{ + this->monitor_->remove_from_registry (); +} + +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + +// -------------------------------------------------------------- + +ACE_Char_Codeset_Translator::~ACE_Char_Codeset_Translator (void) +{ +} + +// -------------------------------------------------------------- + +ACE_WChar_Codeset_Translator::~ACE_WChar_Codeset_Translator (void) +{ +} + +// -------------------------------------------------------------- + +ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, const ACE_CString &x) +{ + os.write_string (x); + return os.good_bit (); +} + +ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CString &x) +{ + is.read_string (x); + return is.good_bit (); +} + +#if defined (GEN_OSTREAM_OPS) + +std::ostream& +operator<< (std::ostream &os, ACE_OutputCDR::from_boolean x) +{ + return (x.val_ ? os << "true" : os << "false"); +} + +std::ostream& +operator<< (std::ostream &os, ACE_OutputCDR::from_char x) +{ + return os << '\'' << x.val_ << '\''; +} + +std::ostream& +operator<< (std::ostream &os, ACE_OutputCDR::from_wchar x) +{ + os.setf (ios_base::showbase); + os.setf (ios_base::hex, ios_base::basefield); + os << x.val_; + os.unsetf (ios_base::showbase); + os.setf (ios_base::dec, ios_base::basefield); + return os; +} + +std::ostream& +operator<< (std::ostream &os, ACE_OutputCDR::from_octet x) +{ + // Same format (hex) and no risk of overflow. + ACE_CDR::WChar w = static_cast (x.val_); + ACE_OutputCDR::from_wchar tmp (w); + return os << tmp; +} + +#endif /* GEN_OSTREAM_OPS */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/CDR_Stream.h b/dep/ACE_wrappers/ace/CDR_Stream.h new file mode 100644 index 000000000..a9c789f41 --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Stream.h @@ -0,0 +1,1402 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CDR_Stream.h + * + * $Id: CDR_Stream.h 82350 2008-07-22 07:36:47Z johnnyw $ + * + * ACE Common Data Representation (CDR) marshaling and demarshaling + * classes. + * + * This implementation was inspired in the CDR class in SunSoft's + * IIOP engine, but has a completely different implementation and a + * different interface too. + * + * The current implementation assumes that the host has 1-byte, + * 2-byte and 4-byte integral types, and that it has single + * precision and double precision IEEE floats. + * Those assumptions are pretty good these days, with Crays being + * the only known exception. + * + * Optimizations + * ------------- + * ACE_LACKS_CDR_ALIGNMENT + * @author Arvind S. Krishna + * + * CDR stream ignores alignment when marshaling data. Use this option + * only when ACE_DISABLE_SWAP_ON_READ can be enabled. This option requires + * ACE CDR engine to do both marshaling and demarshaling. + * + * + * @author TAO version by Aniruddha Gokhale + * @author Carlos O'Ryan + * @author ACE version by Jeff Parsons + * @author Istvan Buki + * @author Codeset translation by Jim Rogers + */ +//============================================================================= + +#ifndef ACE_CDR_STREAM_H +#define ACE_CDR_STREAM_H + +#include /**/ "ace/pre.h" + +#include "ace/CDR_Base.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SStringfwd.h" +#include "ace/Message_Block.h" + +#if defined (GEN_OSTREAM_OPS) +#include "ace/streams.h" +#endif /* GEN_OSTREAM_OPS */ + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) +#include "Monitor_Size.h" +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Char_Codeset_Translator; +class ACE_WChar_Codeset_Translator; + +class ACE_InputCDR; + +/** + * @class ACE_OutputCDR + * + * @brief A CDR stream for marshalling data, most often for transmission to + * another system which may or may not have the same byte order. + * + * This class is based on the the CORBA spec for Java (98-02-29), + * java class omg.org.CORBA.portable.OutputStream. It diverts in + * a few ways: + * @li Operations taking arrays don't have offsets, because in C++ + * it is easier to describe an array starting from x+offset. + * @li Operations return an error status, because exceptions are + * not widely available in C++ (yet). + */ +class ACE_Export ACE_OutputCDR +{ +public: + /** + * The Codeset translators need access to some private members to + * efficiently marshal arrays + * For reading from an output CDR stream. + */ + friend class ACE_Char_Codeset_Translator; + friend class ACE_WChar_Codeset_Translator; + friend class ACE_InputCDR; + + /** + * Default constructor; allows one to set byte ordering, allocators, and + * tuning information. + * + * @param size Causes constructor to preallocate @a size bytes; if + * @a size is 0 it allocates the default size. + * + * @param byte_order The byte order that data will have within this + * object. Unless otherwise specified, the byte order + * will be the order native to the hardware this is + * executed on. To force the marshalled data to have + * a specific order, specify one of the values defined + * in ACE_CDR::Byte_Order. + * @note The @c ACE_ENABLE_SWAP_ON_WRITE config macro + * must be set for any local byte swapping to occur + * as data is inserted into an ACE_OutputCDR object. + */ + ACE_OutputCDR (size_t size = 0, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_Allocator* buffer_allocator = 0, + ACE_Allocator* data_block_allocator = 0, + ACE_Allocator* message_block_allocator = 0, + size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF, + ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Build a CDR stream with an initial buffer, it will *not* remove + /// , since it did not allocated it. It's important to be careful + /// with the alignment of . + /** + * Create an output stream from an arbitrary buffer, care must be + * exercised with alignment, because this contructor will align if + * needed. In this case @a data will not point to the start of the + * output stream. @c begin()->rd_ptr() points to the start of the + * output stream. See @c ACE_ptr_align_binary() to properly align a + * pointer and use ACE_CDR::MAX_ALIGNMENT for the correct alignment. + */ + ACE_OutputCDR (char *data, + size_t size, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_Allocator* buffer_allocator = 0, + ACE_Allocator* data_block_allocator = 0, + ACE_Allocator* message_block_allocator = 0, + size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF, + ACE_CDR::Octet giop_major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet giop_minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Build a CDR stream with an initial data block, it will *not* remove + /// , since it did not allocated it. It's important to be + // careful with the alignment of . + /** + * Create an output stream from an arbitrary data block, care must be + * exercised with alignment, because this contructor will align if + * needed. In this case @a data_block will not point to the + * start of the output stream. begin()->rd_ptr() points to the start + * off the output stream. See ACE_ptr_align_binary() to properly align a + * pointer and use ACE_CDR::MAX_ALIGNMENT for the correct alignment. + */ + ACE_OutputCDR (ACE_Data_Block *data_block, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_Allocator* message_block_allocator = 0, + size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF, + ACE_CDR::Octet giop_major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet giop_minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Build a CDR stream with an initial Message_Block chain, it will + /// *not* remove @a data, since it did not allocate it. + ACE_OutputCDR (ACE_Message_Block *data, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF, + ACE_CDR::Octet giop_major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet giop_minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// destructor + ~ACE_OutputCDR (void); + + /** + * Disambiguate overload when inserting booleans, octets, chars, and + * bounded strings. + */ + //@{ @name Helper classes + + struct ACE_Export from_boolean + { + explicit from_boolean (ACE_CDR::Boolean b); + ACE_CDR::Boolean val_; + }; + + struct ACE_Export from_octet + { + explicit from_octet (ACE_CDR::Octet o); + ACE_CDR::Octet val_; + }; + + struct ACE_Export from_char + { + explicit from_char (ACE_CDR::Char c); + ACE_CDR::Char val_; + }; + + struct ACE_Export from_wchar + { + explicit from_wchar (ACE_CDR::WChar wc); + ACE_CDR::WChar val_; + }; + + struct ACE_Export from_string + { + from_string (ACE_CDR::Char* s, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy = 0); + from_string (const ACE_CDR::Char* s, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy = 0); + ACE_CDR::Char *val_; + ACE_CDR::ULong bound_; + ACE_CDR::Boolean nocopy_; + }; + + struct ACE_Export from_wstring + { + from_wstring (ACE_CDR::WChar* ws, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy = 0); + from_wstring (const ACE_CDR::WChar* ws, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy = 0); + ACE_CDR::WChar *val_; + ACE_CDR::ULong bound_; + ACE_CDR::Boolean nocopy_; + }; + //@} + + /** + * @{ @name Write operations + * Return 0 on failure and 1 on success. + */ + ACE_CDR::Boolean write_boolean (ACE_CDR::Boolean x); + ACE_CDR::Boolean write_char (ACE_CDR::Char x); + ACE_CDR::Boolean write_wchar (ACE_CDR::WChar x); + ACE_CDR::Boolean write_octet (ACE_CDR::Octet x); + ACE_CDR::Boolean write_short (ACE_CDR::Short x); + ACE_CDR::Boolean write_ushort (ACE_CDR::UShort x); + ACE_CDR::Boolean write_long (ACE_CDR::Long x); + ACE_CDR::Boolean write_ulong (ACE_CDR::ULong x); + ACE_CDR::Boolean write_longlong (const ACE_CDR::LongLong &x); + ACE_CDR::Boolean write_ulonglong (const ACE_CDR::ULongLong &x); + ACE_CDR::Boolean write_float (ACE_CDR::Float x); + ACE_CDR::Boolean write_double (const ACE_CDR::Double &x); + ACE_CDR::Boolean write_longdouble (const ACE_CDR::LongDouble &x); + + /// For string we offer methods that accept a precomputed length. + ACE_CDR::Boolean write_string (const ACE_CDR::Char *x); + ACE_CDR::Boolean write_string (ACE_CDR::ULong len, + const ACE_CDR::Char *x); + ACE_CDR::Boolean write_string (const ACE_CString &x); + ACE_CDR::Boolean write_wstring (const ACE_CDR::WChar *x); + ACE_CDR::Boolean write_wstring (ACE_CDR::ULong length, + const ACE_CDR::WChar *x); + //@} + + /// @note the portion written starts at and ends + /// at . + /// The length is *NOT* stored into the CDR stream. + //@{ @name Array write operations + ACE_CDR::Boolean write_boolean_array (const ACE_CDR::Boolean *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_char_array (const ACE_CDR::Char *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_wchar_array (const ACE_CDR::WChar* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_octet_array (const ACE_CDR::Octet* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_short_array (const ACE_CDR::Short *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ushort_array (const ACE_CDR::UShort *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_long_array (const ACE_CDR::Long *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ulong_array (const ACE_CDR::ULong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_longlong_array (const ACE_CDR::LongLong* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ulonglong_array (const ACE_CDR::ULongLong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_float_array (const ACE_CDR::Float *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_double_array (const ACE_CDR::Double *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_longdouble_array (const ACE_CDR::LongDouble* x, + ACE_CDR::ULong length); + + /// Write an octet array contained inside a MB, this can be optimized + /// to minimize copies. + ACE_CDR::Boolean write_octet_array_mb (const ACE_Message_Block* mb); + //@} + + /** + * @{ @name Placeholder/replace operations + * Facilitates writing a placeholder into a CDR stream to be replaced + * later with a different value. + * + * @note An example use for this facility is: + * @code + ACE_OutputCDR strm; + ... // insert values... + char *pos = strm.write_long_placeholder (); + ... // insert more values + ACE_CDR::Long real_val; // Somehow assign the "correct" value + strm.replace (real_val, pos); // Replace earlier placeholder + @endcode + */ + + /** + * Write a placeholder into the stream. The placeholder's pointer + * is returned so it may later be passed as the @a loc argument to + * replace (). + * These methods align the stream's write pointer properly prior to + * writing the placeholder. + * + * @retval Pointer to the placeholder; 0 if there is not enough space + * in the stream and memory could not be allocated. + */ + char* write_long_placeholder (void); + char* write_short_placeholder (void); + + /** + * Writes a new value into a specific location. This is commonly + * used to update a prior "placeholder" location in the stream. + * The specified location is assumed to have proper CDR alignment for the + * type to insert. This requirement is satisfied by using one of the + * placeholder-writing methods to align the stream for the anticipated + * value and obtain the correct location. + * Treatment of @a x with repect to byte swapping is the same as for when + * any value is inserted. + * + * @param x The value to insert into the specified location. + * @param loc The location at which to insert @a x. @a loc must be a valid + * position within the stream's current set of message blocks. + * + * @sa write_long_placeholder(), write_short_placeholder () + */ + ACE_CDR::Boolean replace (ACE_CDR::Long x, char* loc); + ACE_CDR::Boolean replace (ACE_CDR::Short x, char* loc); + //@} + + /** + * Return 0 on failure and 1 on success. + */ + //@{ @name Append contents of own CDR stream to another + ACE_CDR::Boolean append_boolean (ACE_InputCDR &); + ACE_CDR::Boolean append_char (ACE_InputCDR &); + ACE_CDR::Boolean append_wchar (ACE_InputCDR &); + ACE_CDR::Boolean append_octet (ACE_InputCDR &); + ACE_CDR::Boolean append_short (ACE_InputCDR &); + ACE_CDR::Boolean append_ushort (ACE_InputCDR &); + ACE_CDR::Boolean append_long (ACE_InputCDR &); + ACE_CDR::Boolean append_ulong (ACE_InputCDR &); + ACE_CDR::Boolean append_longlong (ACE_InputCDR &); + ACE_CDR::Boolean append_ulonglong (ACE_InputCDR &); + ACE_CDR::Boolean append_float (ACE_InputCDR &); + ACE_CDR::Boolean append_double (ACE_InputCDR &); + ACE_CDR::Boolean append_longdouble (ACE_InputCDR &); + + ACE_CDR::Boolean append_wstring (ACE_InputCDR &); + ACE_CDR::Boolean append_string (ACE_InputCDR &); + //@} + + /// Returns @c false if an error has ocurred. + /** + * @note The only expected error is to run out of memory. + */ + bool good_bit (void) const; + + /// Reuse the CDR stream to write on the old buffer. + void reset (void); + + /// Add the length of each message block in the chain. + size_t total_length (void) const; + + /** + * Return the start of the message block chain for this CDR stream. + * @note The complete CDR stream is represented by a chain of + * message blocks. + */ + const ACE_Message_Block *begin (void) const; + + /// Return the last message in the chain that is is use. + const ACE_Message_Block *end (void) const; + + /// Return the message block in chain. + const ACE_Message_Block *current (void) const; + + /// Replace the message block chain with a single message block. + /** + * Upon successful completion, there will be a single message block + * containing the data from the complete message block chain. + * + * @note The only expected error is to run out of memory. + */ + int consolidate (void); + + /** + * Access the underlying buffer (read only). @note This + * method only returns a pointer to the first block in the + * chain. + */ + const char *buffer (void) const; + + /** + * Return the size of first message block in the block chain. @note This + * method only returns information about the first block in the + * chain. + */ + size_t length (void) const; + + /** + * Utility function to allow the user more flexibility. + * Pads the stream up to the nearest -byte boundary. + * Argument MUST be a power of 2. + * Returns 0 on success and -1 on failure. + */ + int align_write_ptr (size_t alignment); + + /// Access the codeset translators. They can be null! + ACE_Char_Codeset_Translator *char_translator (void) const; + ACE_WChar_Codeset_Translator *wchar_translator (void) const; + + /// Set the char codeset translator. + void char_translator (ACE_Char_Codeset_Translator *); + /// Set the wchar codeset translator. + void wchar_translator (ACE_WChar_Codeset_Translator *); + + /// set the global size of serialized wchars. This may be different + /// than the size of a wchar_t. + static void wchar_maxbytes (size_t max_bytes); + + /// access the serialized size of wchars. + static size_t wchar_maxbytes (void); + + /** + * Return alignment of the wr_ptr(), with respect to the start of + * the CDR stream. This is not the same as the alignment of + * current->wr_ptr()! + */ + size_t current_alignment (void) const; + + void current_alignment (size_t current_alignment); + + /** + * Returns (in @a buf) the next position in the buffer aligned to + * @a size, it advances the Message_Block wr_ptr past the data + * (i.e., @a buf + @a size). If necessary it grows the Message_Block + * buffer. Sets the good_bit to false and returns a -1 on failure. + */ + int adjust (size_t size, + char *&buf); + + /// As above, but now the size and alignment requirements may be + /// different. + int adjust (size_t size, + size_t align, + char *&buf); + + /// Returns true if this stream is writing in non-native byte order + /// and false otherwise. For example, it would be true if either + /// ACE_ENABLE_SWAP_ON_WRITE is defined or a specific byte order was + /// specified for this stream. + bool do_byte_swap (void) const; + + /// Returns the byte order this stream is marshaling data in. Will be one + /// of the values in ACE_CDR::Byte_Order. + int byte_order (void) const; + + /// For use by a gateway, which creates the output stream for the + /// reply to the client in its native byte order, but which must + /// send the reply in the byte order of the target's reply to the + /// gateway. + void reset_byte_order (int byte_order); + + /// set GIOP version info + void set_version (ACE_CDR::Octet major, ACE_CDR::Octet minor); + + /// Set the underlying GIOP version.. + void get_version (ACE_CDR::Octet &major, ACE_CDR::Octet &minor); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + /// Register and unregister our buffer size monitor. + void register_monitor (const char* id); + void unregister_monitor (void); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + +private: + + // Find the message block in the chain of message blocks + // that the provide location locates. + ACE_Message_Block* find (char* loc); + + /// disallow copying... + ACE_OutputCDR (const ACE_OutputCDR& rhs); + ACE_OutputCDR& operator= (const ACE_OutputCDR& rhs); + + ACE_CDR::Boolean write_1 (const ACE_CDR::Octet *x); + ACE_CDR::Boolean write_2 (const ACE_CDR::UShort *x); + ACE_CDR::Boolean write_4 (const ACE_CDR::ULong *x); + ACE_CDR::Boolean write_8 (const ACE_CDR::ULongLong *x); + ACE_CDR::Boolean write_16 (const ACE_CDR::LongDouble *x); + + /** + * write an array of @a length elements, each of @a size bytes and the + * start aligned at a multiple of . The elements are assumed + * to be packed with the right alignment restrictions. It is mostly + * designed for buffers of the basic types. + * + * This operation uses ; as explained above it is expected + * that using assignment is faster that for one element, + * but for several elements should be more efficient, it + * could be interesting to find the break even point and optimize + * for that case, but that would be too platform dependent. + */ + ACE_CDR::Boolean write_array (const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + + ACE_CDR::Boolean write_wchar_array_i (const ACE_CDR::WChar* x, + ACE_CDR::ULong length); + + + /** + * Grow the CDR stream. When it returns @a buf contains a pointer to + * memory in the CDR stream, with at least @a size bytes ahead of it + * and aligned to an boundary. It moved the to . + */ + int grow_and_adjust (size_t size, + size_t align, + char *&buf); + +private: + /// The start of the chain of message blocks. + ACE_Message_Block start_; + + /// The current block in the chain where we are writing. + ACE_Message_Block *current_; + +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + /** + * The current alignment as measured from the start of the buffer. + * Usually this coincides with the alignment of the buffer in + * memory, but, when we chain another buffer this "quasi invariant" + * is broken. + * The current_alignment is used to readjust the buffer following + * the stolen message block. + */ + size_t current_alignment_; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + /** + * Is the current block writable. When we steal a buffer from the + * user and just chain it into the message block we are not supposed + * to write on it, even if it is past the start and end of the + * buffer. + */ + bool current_is_writable_; + + /** + * If not zero swap bytes at writing so the created CDR stream byte + * order does *not* match the machine byte order. The motivation + * for such a beast is that in some setting a few (fast) machines + * can be serving hundreds of slow machines with the opposite byte + * order, so it makes sense (as a load balancing device) to put the + * responsibility in the writers. THIS IS NOT A STANDARD IN CORBA, + * USE AT YOUR OWN RISK + */ + bool do_byte_swap_; + + /// Set to false when an error ocurrs. + bool good_bit_; + + /// Break-even point for copying. + size_t const memcpy_tradeoff_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE::Monitor_Control::Size_Monitor *monitor_; +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + +protected: + /// GIOP version information + ACE_CDR::Octet major_version_; + ACE_CDR::Octet minor_version_; + + /// If not nil, invoke for translation of character and string data. + ACE_Char_Codeset_Translator *char_translator_; + ACE_WChar_Codeset_Translator *wchar_translator_; + + /** + * Some wide char codesets may be defined with a maximum number + * of bytes that is smaller than the size of a wchar_t. This means + * that the CDR cannot simply memcpy a block of wchars to and from + * the stream, but must instead realign the bytes appropriately. + * In cases when wchar i/o is not allowed, such as with GIOP 1.0, + * or not having a native wchar codeset defined, the maxbytes is + * set to zero, indicating no wchar data is allowed. + */ + static size_t wchar_maxbytes_; +}; + + +// **************************************************************** + +/** + * @class ACE_InputCDR + * + * @brief A CDR stream for demarshalling CDR-encoded data. + * + * This class is based on the the CORBA spec for Java (98-02-29), + * java class omg.org.CORBA.portable.InputStream. It diverts in a + * few ways: + * @li Operations to retrieve basic types take parameters by + * reference. + * @li Operations taking arrays don't have offsets, because in C++ + * it is easier to describe an array starting from x+offset. + * @li Operations return an error status, because exceptions are + * not widely available in C++ (yet). + */ +class ACE_Export ACE_InputCDR +{ +public: + // The translators need privileged access to efficiently demarshal + // arrays and such. + friend class ACE_Char_Codeset_Translator; + friend class ACE_WChar_Codeset_Translator; + + /** + * Create an input stream from an arbitrary buffer. The buffer must + * be properly aligned because this contructor will *not* work if + * the buffer is aligned unproperly.See ACE_ptr_align_binary() for + * instructions on how to align a pointer properly and use + * ACE_CDR::MAX_ALIGNMENT for the correct alignment. + */ + ACE_InputCDR (const char *buf, + size_t bufsiz, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Create an empty input stream. The caller is responsible for + /// putting the right data and providing the right alignment. + ACE_InputCDR (size_t bufsiz, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Create an input stream from an ACE_Message_Block + /** + * The alignment of the @a data block is carried into the new + * ACE_InputCDR object. This constructor either increments the + * @a data reference count, or copies the data (if it's a compound + * message block) so the caller can release the block immediately + * upon return. + */ + ACE_InputCDR (const ACE_Message_Block *data, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION, + ACE_Lock* lock = 0); + + /// Create an input stream from an ACE_Data_Block. The + /// indicates whether the can be deleted by the CDR stream + /// or not + ACE_InputCDR (ACE_Data_Block *data, + ACE_Message_Block::Message_Flags flag = 0, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Create an input stream from an ACE_Data_Block. It also sets the + /// read and write pointers at the desired positions. This would be + /// helpful if the applications desires to create a new CDR stream + /// from a semi-processed datablock. + ACE_InputCDR (ACE_Data_Block *data, + ACE_Message_Block::Message_Flags flag, + size_t read_pointer_position, + size_t write_pointer_position, + int byte_order = ACE_CDR::BYTE_ORDER_NATIVE, + ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /** + * These make a copy of the current stream state, but do not copy + * the internal buffer, so the same stream can be read multiple + * times efficiently. + */ + ACE_InputCDR (const ACE_InputCDR& rhs); + + ACE_InputCDR& operator= (const ACE_InputCDR& rhs); + + /// When interpreting indirected TypeCodes it is useful to make a + /// "copy" of the stream starting in the new position. + ACE_InputCDR (const ACE_InputCDR& rhs, + size_t size, + ACE_CDR::Long offset); + + /// This creates an encapsulated stream, the first byte must be (per + /// the spec) the byte order of the encapsulation. + ACE_InputCDR (const ACE_InputCDR& rhs, + size_t size); + + /// Create an input CDR from an output CDR. + ACE_InputCDR (const ACE_OutputCDR& rhs, + ACE_Allocator* buffer_allocator = 0, + ACE_Allocator* data_block_allocator = 0, + ACE_Allocator* message_block_allocator = 0); + + /// Helper class to transfer the contents from one input CDR to + /// another without requiring any extra memory allocations, data + /// copies or too many temporaries. + struct ACE_Export Transfer_Contents + { + Transfer_Contents (ACE_InputCDR &rhs); + + ACE_InputCDR &rhs_; + }; + /// Transfer the contents from to a new CDR + ACE_InputCDR (Transfer_Contents rhs); + + /// Destructor + ~ACE_InputCDR (void); + + /// Disambiguate overloading when extracting octets, chars, + /// booleans, and bounded strings + //@{ @name Helper classes + + struct ACE_Export to_boolean + { + explicit to_boolean (ACE_CDR::Boolean &b); + ACE_CDR::Boolean &ref_; + }; + + struct ACE_Export to_char + { + explicit to_char (ACE_CDR::Char &c); + ACE_CDR::Char &ref_; + }; + + struct ACE_Export to_wchar + { + explicit to_wchar (ACE_CDR::WChar &wc); + ACE_CDR::WChar &ref_; + }; + + struct ACE_Export to_octet + { + explicit to_octet (ACE_CDR::Octet &o); + ACE_CDR::Octet &ref_; + }; + + struct ACE_Export to_string + { + /** + * @deprecated The constructor taking a non-const string is now + * deprecated (C++ mapping 00-01-02), but we keep it + * around for backward compatibility. + */ + to_string (ACE_CDR::Char *&s, + ACE_CDR::ULong b); + to_string (const ACE_CDR::Char *&s, + ACE_CDR::ULong b); + const ACE_CDR::Char *&val_; + ACE_CDR::ULong bound_; + }; + + struct ACE_Export to_wstring + { + /// The constructor taking a non-const wstring is + /// now deprecated (C++ mapping 00-01-02), but we + /// keep it around for backward compatibility. + to_wstring (ACE_CDR::WChar *&ws, + ACE_CDR::ULong b); + to_wstring (const ACE_CDR::WChar *&ws, + ACE_CDR::ULong b); + const ACE_CDR::WChar *&val_; + ACE_CDR::ULong bound_; + }; + //@} + + /** + * Return @c false on failure and @c true on success. + */ + //@{ @name Read basic IDL types + ACE_CDR::Boolean read_boolean (ACE_CDR::Boolean& x); + ACE_CDR::Boolean read_char (ACE_CDR::Char &x); + ACE_CDR::Boolean read_wchar (ACE_CDR::WChar& x); + ACE_CDR::Boolean read_octet (ACE_CDR::Octet& x); + ACE_CDR::Boolean read_short (ACE_CDR::Short &x); + ACE_CDR::Boolean read_ushort (ACE_CDR::UShort &x); + ACE_CDR::Boolean read_long (ACE_CDR::Long &x); + ACE_CDR::Boolean read_ulong (ACE_CDR::ULong &x); + ACE_CDR::Boolean read_longlong (ACE_CDR::LongLong& x); + ACE_CDR::Boolean read_ulonglong (ACE_CDR::ULongLong& x); + ACE_CDR::Boolean read_float (ACE_CDR::Float &x); + ACE_CDR::Boolean read_double (ACE_CDR::Double &x); + ACE_CDR::Boolean read_longdouble (ACE_CDR::LongDouble &x); + + ACE_CDR::Boolean read_string (ACE_CDR::Char *&x); + ACE_CDR::Boolean read_string (ACE_CString &x); + ACE_CDR::Boolean read_wstring (ACE_CDR::WChar*& x); + //@} + + /** + * The buffer @a x must be large enough to contain @a length + * elements. + * Return @c false on failure and @c true on success. + */ + //@{ @name Read basic IDL types arrays + ACE_CDR::Boolean read_boolean_array (ACE_CDR::Boolean* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_char_array (ACE_CDR::Char *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_wchar_array (ACE_CDR::WChar* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_octet_array (ACE_CDR::Octet* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_short_array (ACE_CDR::Short *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_ushort_array (ACE_CDR::UShort *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_long_array (ACE_CDR::Long *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_ulong_array (ACE_CDR::ULong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_longlong_array (ACE_CDR::LongLong* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_ulonglong_array (ACE_CDR::ULongLong* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_float_array (ACE_CDR::Float *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_double_array (ACE_CDR::Double *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean read_longdouble_array (ACE_CDR::LongDouble* x, + ACE_CDR::ULong length); + //@} + + /** + * Return @c false on failure and @c true on success. + */ + //@{ @name Skip elements + ACE_CDR::Boolean skip_boolean (void); + ACE_CDR::Boolean skip_char (void); + ACE_CDR::Boolean skip_wchar (void); + ACE_CDR::Boolean skip_octet (void); + ACE_CDR::Boolean skip_short (void); + ACE_CDR::Boolean skip_ushort (void); + ACE_CDR::Boolean skip_long (void); + ACE_CDR::Boolean skip_ulong (void); + ACE_CDR::Boolean skip_longlong (void); + ACE_CDR::Boolean skip_ulonglong (void); + ACE_CDR::Boolean skip_float (void); + ACE_CDR::Boolean skip_double (void); + ACE_CDR::Boolean skip_longdouble (void); + //@} + + /** + * The next field must be a string, this method skips it. It is + * useful in parsing a TypeCode. + * @return @c false on failure and @c true on success. + */ + ACE_CDR::Boolean skip_wstring (void); + ACE_CDR::Boolean skip_string (void); + + /// Skip @a n bytes in the CDR stream. + /** + * @return @c false on failure and @c true on success. + */ + ACE_CDR::Boolean skip_bytes (size_t n); + + /// returns @c false if a problem has been detected. + bool good_bit (void) const; + + /** + * @return The start of the message block chain for this CDR + * stream. + * + * @note In the current implementation the chain has length 1, but + * we are planning to change that. + */ + const ACE_Message_Block* start (void) const; + + // = The following functions are useful to read the contents of the + // CDR stream from a socket or file. + + /** + * Grow the internal buffer, reset @c rd_ptr to the first byte in + * the new buffer that is properly aligned, and set @c wr_ptr to @c + * rd_ptr @c + @c newsize + */ + int grow (size_t newsize); + + /** + * After reading and partially parsing the contents the user can + * detect a change in the byte order, this method will let him/her + * change it. + */ + void reset_byte_order (int byte_order); + + /// Re-initialize the CDR stream, copying the contents of the chain + /// of message_blocks starting from @a data. + void reset (const ACE_Message_Block *data, + int byte_order); + + /// Steal the contents from the current CDR. + ACE_Message_Block *steal_contents (void); + + /// Steal the contents of @a cdr and make a shallow copy into this + /// stream. + void steal_from (ACE_InputCDR &cdr); + + /// Exchange data blocks with the caller of this method. The read + /// and write pointers are also exchanged. + /** + * @note We now do only with the start_ message block. + */ + void exchange_data_blocks (ACE_InputCDR &cdr); + + /// Copy the data portion from the @c cdr to this cdr and return the + /// data content (ie. the ACE_Data_Block) from this CDR to the + /// caller. + /** + * @note The caller is responsible for managing the memory of the + * returned ACE_Data_Block. + */ + ACE_Data_Block* clone_from (ACE_InputCDR &cdr); + + /// Re-initialize the CDR stream, forgetting about the old contents + /// of the stream and allocating a new buffer (from the allocators). + void reset_contents (void); + + /// Returns the current position for the @c rd_ptr. + char* rd_ptr (void); + + /// Returns the current position for the @c wr_ptr. + char* wr_ptr (void); + + /// Return how many bytes are left in the stream. + size_t length (void) const; + + /** + * Utility function to allow the user more flexibility. + * Skips up to the nearest @a alignment-byte boundary. + * Argument MUST be a power of 2. + * + * @return 0 on success and -1 on failure. + */ + int align_read_ptr (size_t alignment); + + /// If @c true then this stream is writing in non-native byte order. + /// This is only meaningful if ACE_ENABLE_SWAP_ON_WRITE is defined. + bool do_byte_swap (void) const; + + /// If @c do_byte_swap() returns @c false, this returns + /// ACE_CDR_BYTE_ORDER else it returns !ACE_CDR_BYTE_ORDER. + int byte_order (void) const; + + /// Access the codeset translators. They can be nil! + ACE_Char_Codeset_Translator *char_translator (void) const; + ACE_WChar_Codeset_Translator *wchar_translator (void) const; + + /// Set the codeset translators. + void char_translator (ACE_Char_Codeset_Translator *); + void wchar_translator (ACE_WChar_Codeset_Translator *); + + /** + * Returns (in @a buf) the next position in the buffer aligned to + * @a size. It advances the Message_Block @c rd_ptr past the data + * (i.e., @c buf @c + @c size). Sets the good_bit to @c false and + * returns a -1 on failure. + */ + int adjust (size_t size, + char *&buf); + + /// As above, but now the size and alignment requirements may be + /// different. + int adjust (size_t size, + size_t align, + char *&buf); + + /// Set the underlying GIOP version.. + void set_version (ACE_CDR::Octet major, ACE_CDR::Octet minor); + + /// Set the underlying GIOP version.. + void get_version (ACE_CDR::Octet &major, ACE_CDR::Octet &minor); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + /// Register and unregister our buffer size monitor. + void register_monitor (const char* id); + void unregister_monitor (void); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + +protected: + + /// The start of the chain of message blocks, even though in the + /// current version the chain always has length 1. + ACE_Message_Block start_; + + /// The CDR stream byte order does not match the one on the machine, + /// swapping is needed while reading. + bool do_byte_swap_; + + /// set to @c false when an error occurs. + bool good_bit_; + + /// The GIOP versions for this stream + ACE_CDR::Octet major_version_; + ACE_CDR::Octet minor_version_; + + /// If not nil, invoke for translation of character and string data. + ACE_Char_Codeset_Translator *char_translator_; + ACE_WChar_Codeset_Translator *wchar_translator_; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + ACE::Monitor_Control::Size_Monitor *monitor_; +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + +private: + + ACE_CDR::Boolean read_1 (ACE_CDR::Octet *x); + ACE_CDR::Boolean read_2 (ACE_CDR::UShort *x); + ACE_CDR::Boolean read_4 (ACE_CDR::ULong *x); + ACE_CDR::Boolean read_8 (ACE_CDR::ULongLong *x); + ACE_CDR::Boolean read_16 (ACE_CDR::LongDouble *x); + + // Several types can be read using the same routines, since TAO + // tries to use native types with known size for each CORBA type. + // We could use void* or char* to make the interface more + // consistent, but using native types let us exploit the strict + // alignment requirements of CDR streams and implement the + // operations using asignment. + + /** + * Read an array of @a length elements, each of @a size bytes and the + * start aligned at a multiple of . The elements are assumed + * to be packed with the right alignment restrictions. It is mostly + * designed for buffers of the basic types. + * + * This operation uses ; as explained above it is expected + * that using assignment is faster that for one element, + * but for several elements should be more efficient, it + * could be interesting to find the break even point and optimize + * for that case, but that would be too platform dependent. + */ + ACE_CDR::Boolean read_array (void* x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + /** + * On those occasions when the native codeset for wchar is smaller than + * the size of a wchar_t, such as using UTF-16 with a 4-byte wchar_t, a + * special form of reading the array is needed. Actually, this should be + * a default translator. + */ + ACE_CDR::Boolean read_wchar_array_i (ACE_CDR::WChar * x, + ACE_CDR::ULong length); + + /// Move the rd_ptr ahead by @a offset bytes. + void rd_ptr (size_t offset); + + /// Points to the continuation field of the current message block. + char* end (void); +}; + +// **************************************************************** + +/** + * @class ACE_Char_Codeset_Translator + * + * @brief Codeset translation routines common to both Output and Input + * CDR streams. + * + * This class is a base class for defining codeset translation + * routines to handle the character set translations required by + * both CDR Input streams and CDR Output streams. + * + * Translators are reference counted. This allows for stateful as well + * as stateless translators. Stateless translators will be allocated + * once whereas CDR Streams own their own copy of a stateful translator. + */ +class ACE_Export ACE_Char_Codeset_Translator +{ +public: + virtual ~ACE_Char_Codeset_Translator (); + + /// Read a single character from the stream, converting from the + /// stream codeset to the native codeset + virtual ACE_CDR::Boolean read_char (ACE_InputCDR&, + ACE_CDR::Char&) = 0; + + /// Read a string from the stream, including the length, converting + /// the characters from the stream codeset to the native codeset + virtual ACE_CDR::Boolean read_string (ACE_InputCDR&, + ACE_CDR::Char *&) = 0; + + /// Read an array of characters from the stream, converting the + /// characters from the stream codeset to the native codeset. + virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR&, + ACE_CDR::Char*, + ACE_CDR::ULong) = 0; + + /// Write a single character to the stream, converting from the + /// native codeset to the stream codeset + virtual ACE_CDR::Boolean write_char (ACE_OutputCDR&, + ACE_CDR::Char) = 0; + + /// Write a string to the stream, including the length, converting + /// from the native codeset to the stream codeset + virtual ACE_CDR::Boolean write_string (ACE_OutputCDR&, + ACE_CDR::ULong, + const ACE_CDR::Char*) = 0; + + /// Write an array of characters to the stream, converting from the + /// native codeset to the stream codeset + virtual ACE_CDR::Boolean write_char_array (ACE_OutputCDR&, + const ACE_CDR::Char*, + ACE_CDR::ULong) = 0; + + virtual ACE_CDR::ULong ncs () = 0; + virtual ACE_CDR::ULong tcs () = 0; +protected: + /// Children have access to low-level routines because they cannot + /// use read_char or something similar (it would recurse). + ACE_CDR::Boolean read_1 (ACE_InputCDR& input, + ACE_CDR::Octet *x); + ACE_CDR::Boolean write_1 (ACE_OutputCDR& output, + const ACE_CDR::Octet *x); + + /// Efficiently read @a length elements of size @a size each from + /// into ; the data must be aligned to . + ACE_CDR::Boolean read_array (ACE_InputCDR& input, + void* x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + /** + * Efficiently write @a length elements of size @a size from into + * . Before inserting the elements enough padding is added + * to ensure that the elements will be aligned to in the + * stream. + */ + ACE_CDR::Boolean write_array (ACE_OutputCDR& output, + const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + /** + * Exposes the stream implementation of , this is useful in + * many cases to minimize memory allocations during marshaling. + * On success @a buf will contain a contiguous area in the CDR stream + * that can hold @a size bytes aligned to . + * Results + */ + int adjust (ACE_OutputCDR& out, + size_t size, + size_t align, + char *&buf); + + /// Used by derived classes to set errors in the CDR stream. + void good_bit (ACE_OutputCDR& out, bool bit); + + /// Obtain the CDR Stream's major & minor version values. + ACE_CDR::Octet major_version (ACE_InputCDR& input); + ACE_CDR::Octet minor_version (ACE_InputCDR& input); + ACE_CDR::Octet major_version (ACE_OutputCDR& output); + ACE_CDR::Octet minor_version (ACE_OutputCDR& output); +}; + +// **************************************************************** + +/** + * @class ACE_WChar_Codeset_Translator + * + * @brief Codeset translation routines common to both Output and Input + * CDR streams. + * + * This class is a base class for defining codeset translation + * routines to handle the character set translations required by + * both CDR Input streams and CDR Output streams. + */ +class ACE_Export ACE_WChar_Codeset_Translator +{ +public: + virtual ~ACE_WChar_Codeset_Translator (); + + virtual ACE_CDR::Boolean read_wchar (ACE_InputCDR&, + ACE_CDR::WChar&) = 0; + virtual ACE_CDR::Boolean read_wstring (ACE_InputCDR&, + ACE_CDR::WChar *&) = 0; + virtual ACE_CDR::Boolean read_wchar_array (ACE_InputCDR&, + ACE_CDR::WChar*, + ACE_CDR::ULong) = 0; + virtual ACE_CDR::Boolean write_wchar (ACE_OutputCDR&, + ACE_CDR::WChar) = 0; + virtual ACE_CDR::Boolean write_wstring (ACE_OutputCDR&, + ACE_CDR::ULong, + const ACE_CDR::WChar*) = 0; + virtual ACE_CDR::Boolean write_wchar_array (ACE_OutputCDR&, + const ACE_CDR::WChar*, + ACE_CDR::ULong) = 0; + + virtual ACE_CDR::ULong ncs () = 0; + virtual ACE_CDR::ULong tcs () = 0; +protected: + /// Children have access to low-level routines because they cannot + /// use read_char or something similar (it would recurse). + ACE_CDR::Boolean read_1 (ACE_InputCDR& input, + ACE_CDR::Octet *x); + ACE_CDR::Boolean read_2 (ACE_InputCDR& input, + ACE_CDR::UShort *x); + ACE_CDR::Boolean read_4 (ACE_InputCDR& input, + ACE_CDR::ULong *x); + ACE_CDR::Boolean write_1 (ACE_OutputCDR& output, + const ACE_CDR::Octet *x); + ACE_CDR::Boolean write_2 (ACE_OutputCDR& output, + const ACE_CDR::UShort *x); + ACE_CDR::Boolean write_4 (ACE_OutputCDR& output, + const ACE_CDR::ULong *x); + + /// Efficiently read @a length elements of size @a size each from + /// into ; the data must be aligned to . + ACE_CDR::Boolean read_array (ACE_InputCDR& input, + void* x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + /** + * Efficiently write @a length elements of size @a size from into + * . Before inserting the elements enough padding is added + * to ensure that the elements will be aligned to in the + * stream. + */ + ACE_CDR::Boolean write_array (ACE_OutputCDR& output, + const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + /** + * Exposes the stream implementation of , this is useful in + * many cases to minimize memory allocations during marshaling. + * On success @a buf will contain a contiguous area in the CDR stream + * that can hold @a size bytes aligned to . + * Results + */ + int adjust (ACE_OutputCDR& out, + size_t size, + size_t align, + char *&buf); + + /// Used by derived classes to set errors in the CDR stream. + void good_bit (ACE_OutputCDR& out, bool bit); + + /// Obtain the CDR Stream's major & minor version values. + ACE_CDR::Octet major_version (ACE_InputCDR& input); + ACE_CDR::Octet minor_version (ACE_InputCDR& input); + ACE_CDR::Octet major_version (ACE_OutputCDR& output); + ACE_CDR::Octet minor_version (ACE_OutputCDR& output); + +}; + +// @@ These operators should not be inlined since they force SString.h +// to be included in this header. +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + const ACE_CString &x); + +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CString &x); + + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/CDR_Stream.inl" +#else /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Not used by CORBA or TAO +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::Char x); +// CDR output operators for primitive types + +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::Short x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::UShort x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::Long x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::ULong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::LongLong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::ULongLong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR& os, + ACE_CDR::LongDouble x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::Float x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_CDR::Double x); + +// CDR output operator from helper classes + +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_boolean x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_char x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_wchar x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_octet x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_string x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_wstring x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + const ACE_CDR::Char* x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + const ACE_CDR::WChar* x); + +// Not used by CORBA or TAO +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::Char &x); +// CDR input operators for primitive types + +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::Short &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::UShort &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::Long &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::ULong &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::LongLong &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::ULongLong &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::LongDouble &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::Float &x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::Double &x); + +// CDR input operator from helper classes + +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_InputCDR::to_boolean x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_InputCDR::to_char x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_InputCDR::to_wchar x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_InputCDR::to_octet x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_InputCDR::to_string x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_InputCDR::to_wstring x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::Char*& x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + ACE_CDR::WChar*& x); + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* __ACE_INLINE__ */ + +#if defined (GEN_OSTREAM_OPS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// ostream insertion operators for debugging code generated from IDL. All +// but these below are either in generated code itself or are unambiguous +// primitive types. + +ACE_Export std::ostream& operator<< (std::ostream &os, + ACE_OutputCDR::from_boolean x); + +ACE_Export std::ostream& operator<< (std::ostream &os, + ACE_OutputCDR::from_char x); + +ACE_Export std::ostream& operator<< (std::ostream &os, + ACE_OutputCDR::from_wchar x); + +ACE_Export std::ostream& operator<< (std::ostream &os, + ACE_OutputCDR::from_octet x); + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* GEN_OSTREAM_OPS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CDR_STREAM_H */ diff --git a/dep/ACE_wrappers/ace/CDR_Stream.inl b/dep/ACE_wrappers/ace/CDR_Stream.inl new file mode 100644 index 000000000..9fef2d8fa --- /dev/null +++ b/dep/ACE_wrappers/ace/CDR_Stream.inl @@ -0,0 +1,1728 @@ +// -*- C++ -*- +// +// $Id: CDR_Stream.inl 82350 2008-07-22 07:36:47Z johnnyw $ + +#include "ace/OS_NS_string.h" +#include "ace/OS_Memory.h" + +// **************************************************************** + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// implementing the special types +ACE_INLINE +ACE_OutputCDR::from_boolean::from_boolean (ACE_CDR::Boolean b) + : val_ (b) +{ +} + +ACE_INLINE +ACE_InputCDR::to_boolean::to_boolean (ACE_CDR::Boolean &b) + : ref_ (b) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_octet::from_octet (ACE_CDR::Octet o) + : val_ (o) +{ +} + +ACE_INLINE +ACE_InputCDR::to_octet::to_octet (ACE_CDR::Octet &o) + : ref_ (o) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_char::from_char (ACE_CDR::Char c) + : val_ (c) +{ +} + +ACE_INLINE +ACE_InputCDR::to_char::to_char (ACE_CDR::Char &c) + : ref_ (c) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_wchar::from_wchar (ACE_CDR::WChar wc) + : val_ (wc) +{ +} + +ACE_INLINE +ACE_InputCDR::to_wchar::to_wchar (ACE_CDR::WChar &wc) + : ref_ (wc) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_string::from_string (ACE_CDR::Char *s, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy) + : val_ (s), + bound_ (b), + nocopy_ (nocopy) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_string::from_string (const ACE_CDR::Char *s, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy) + : val_ (const_cast (s)), + bound_ (b), + nocopy_ (nocopy) +{ +} + +ACE_INLINE +ACE_InputCDR::to_string::to_string (ACE_CDR::Char *&s, + ACE_CDR::ULong b) + : val_ (const_cast (s)), + bound_ (b) +{ +} + +ACE_INLINE +ACE_InputCDR::to_string::to_string (const ACE_CDR::Char *&s, + ACE_CDR::ULong b) + : val_ (s), + bound_ (b) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_wstring::from_wstring (ACE_CDR::WChar *ws, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy) + : val_ (ws), + bound_ (b), + nocopy_ (nocopy) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_wstring::from_wstring (const ACE_CDR::WChar *ws, + ACE_CDR::ULong b, + ACE_CDR::Boolean nocopy) + : val_ (const_cast (ws)), + bound_ (b), + nocopy_ (nocopy) +{ +} + +ACE_INLINE +ACE_InputCDR::to_wstring::to_wstring (ACE_CDR::WChar *&ws, + ACE_CDR::ULong b) + : val_ (const_cast (ws)), + bound_ (b) +{ +} + +ACE_INLINE +ACE_InputCDR::to_wstring::to_wstring (const ACE_CDR::WChar *&ws, + ACE_CDR::ULong b) + : val_ (ws), + bound_ (b) +{ +} + +ACE_INLINE +ACE_InputCDR::Transfer_Contents::Transfer_Contents (ACE_InputCDR &rhs) + : rhs_ (rhs) +{ +} + +// **************************************************************** + +ACE_INLINE +ACE_OutputCDR::~ACE_OutputCDR (void) +{ + if (this->start_.cont () != 0) + { + ACE_Message_Block::release (this->start_.cont ()); + this->start_.cont (0); + } + + this->current_ = 0; + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->remove_ref (); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_INLINE void +ACE_OutputCDR::reset (void) +{ + this->current_ = &this->start_; + this->current_is_writable_ = true; + ACE_CDR::mb_align (&this->start_); + +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + this->current_alignment_ = 0; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + // It is tempting not to remove the memory, but we need to do so to + // release any potential user buffers chained in the continuation + // field. + + ACE_Message_Block * const cont = this->start_.cont (); + if (cont) + { + ACE_Message_Block::release (cont); + this->start_.cont (0); + } + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->start_.total_size ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +// Encode the CDR stream. + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_octet (ACE_CDR::Octet x) +{ + return this->write_1 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_boolean (ACE_CDR::Boolean x) +{ + return + static_cast ( + this->write_octet ( + x + ? static_cast (1) + : static_cast (0))); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_char (ACE_CDR::Char x) +{ + if (this->char_translator_ == 0) + { + ACE_CDR::Octet temp = static_cast (x); + return this->write_1 (&temp); + } + return this->char_translator_->write_char (*this, x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_short (ACE_CDR::Short x) +{ + ACE_CDR::UShort temp = static_cast (x); + return this->write_2 (&temp); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_ushort (ACE_CDR::UShort x) +{ + return this->write_2 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_long (ACE_CDR::Long x) +{ + ACE_CDR::ULong temp = static_cast (x); + return this->write_4 (&temp); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_ulong (ACE_CDR::ULong x) +{ + return this->write_4 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_longlong (const ACE_CDR::LongLong &x) +{ + void const * const temp = &x; + return this->write_8 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_ulonglong (const ACE_CDR::ULongLong &x) +{ + return this->write_8 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_float (ACE_CDR::Float x) +{ + void const * const temp = &x; + return this->write_4 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_double (const ACE_CDR::Double &x) +{ + void const * const temp = &x; + return this->write_8 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_longdouble (const ACE_CDR::LongDouble &x) +{ + return this->write_16 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_string (const ACE_CDR::Char *x) +{ + if (x) + { + ACE_CDR::ULong const len = + static_cast (ACE_OS::strlen (x)); + return this->write_string (len, x); + } + + return this->write_string (0, 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_wstring (const ACE_CDR::WChar *x) +{ + if (x) + { + ACE_CDR::ULong const len = + static_cast (ACE_OS::strlen (x)); + return this->write_wstring (len, x); + } + + return this->write_wstring (0, 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_char_array (const ACE_CDR::Char *x, + ACE_CDR::ULong length) +{ + if (this->char_translator_ == 0) + return this->write_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); + return this->char_translator_->write_char_array (*this, x, length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_wchar_array (const ACE_CDR::WChar* x, + ACE_CDR::ULong length) +{ + if (this->wchar_translator_) + return this->wchar_translator_->write_wchar_array (*this, x, length); + + if (ACE_OutputCDR::wchar_maxbytes_ == 0) + { + errno = EACCES; + return (ACE_CDR::Boolean) (this->good_bit_ = false); + } + + if (ACE_OutputCDR::wchar_maxbytes_ == sizeof (ACE_CDR::WChar)) + return this->write_array (x, + sizeof (ACE_CDR::WChar), + sizeof (ACE_CDR::WChar) == 2 + ? ACE_CDR::SHORT_ALIGN + : ACE_CDR::LONG_ALIGN, + length); + return this->write_wchar_array_i (x,length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_octet_array (const ACE_CDR::Octet* x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_short_array (const ACE_CDR::Short *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_ushort_array (const ACE_CDR::UShort *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_long_array (const ACE_CDR::Long *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_ulong_array (const ACE_CDR::ULong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_longlong_array (const ACE_CDR::LongLong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_ulonglong_array (const ACE_CDR::ULongLong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_float_array (const ACE_CDR::Float *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_double_array (const ACE_CDR::Double *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_longdouble_array (const ACE_CDR::LongDouble* x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN, + length); +} + +ACE_INLINE bool +ACE_OutputCDR::good_bit (void) const +{ + return this->good_bit_; +} + +ACE_INLINE int +ACE_OutputCDR::adjust (size_t size, + size_t align, + char*& buf) +{ + if (!this->current_is_writable_) + return this->grow_and_adjust (size, align, buf); + +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + size_t const offset = + ACE_align_binary (this->current_alignment_, align) + - this->current_alignment_; + + buf = this->current_->wr_ptr () + offset; +#else + buf = this->current_->wr_ptr (); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + char * const end = buf + size; + + if (end <= this->current_->end () && + end >= buf) + { +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + this->current_alignment_ += offset + size; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + this->current_->wr_ptr (end); + +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->receive (this->total_length ()); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ + + return 0; + } + + return this->grow_and_adjust (size, align, buf); +} + +ACE_INLINE int +ACE_OutputCDR::adjust (size_t size, char*& buf) +{ + return this->adjust (size, size, buf); +} + +ACE_INLINE void +ACE_OutputCDR::set_version (ACE_CDR::Octet major, ACE_CDR::Octet minor) +{ + this->major_version_ = major; + this->minor_version_ = minor; +} + +ACE_INLINE void +ACE_OutputCDR::get_version (ACE_CDR::Octet &major, ACE_CDR::Octet &minor) +{ + major = this->major_version_; + minor = this->minor_version_; +} + + +ACE_INLINE const ACE_Message_Block* +ACE_OutputCDR::begin (void) const +{ + return &this->start_; +} + +ACE_INLINE const ACE_Message_Block* +ACE_OutputCDR::end (void) const +{ + return this->current_->cont (); +} + +ACE_INLINE const ACE_Message_Block* +ACE_OutputCDR::current (void) const +{ + return this->current_; +} + +ACE_INLINE size_t +ACE_OutputCDR::total_length (void) const +{ + return ACE_CDR::total_length (this->begin (), this->end ()); +} + +ACE_INLINE const char* +ACE_OutputCDR::buffer (void) const +{ + return this->start_.rd_ptr (); +} + +ACE_INLINE size_t +ACE_OutputCDR::length (void) const +{ + return this->start_.length (); +} + +ACE_INLINE bool +ACE_OutputCDR::do_byte_swap (void) const +{ + return this->do_byte_swap_; +} + +ACE_INLINE int +ACE_OutputCDR::byte_order (void) const +{ + if (this->do_byte_swap ()) + return !ACE_CDR_BYTE_ORDER; + else + return ACE_CDR_BYTE_ORDER; +} + +ACE_INLINE void +ACE_OutputCDR::reset_byte_order (int byte_order) +{ + this->do_byte_swap_ = (byte_order != ACE_CDR_BYTE_ORDER); +} + +ACE_INLINE size_t +ACE_OutputCDR::current_alignment (void) const +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + return this->current_alignment_; +#else + // Default value set to 0 + return 0; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ +} + +ACE_INLINE void +ACE_OutputCDR::current_alignment (size_t current_alignment) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + this->current_alignment_ = current_alignment; +#else + ACE_UNUSED_ARG (current_alignment); + return 0; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ +} + +ACE_INLINE int +ACE_OutputCDR::align_write_ptr (size_t alignment) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + char *dummy; + return this->adjust (0, alignment, dummy); +#else + ACE_UNUSED_ARG (alignment); + // A return value of -1 from this function is used + // to indicate failure, returning 0 + return 0; +#endif /* ACE_LACKS_CDR_ALIGNMENT */ +} + +ACE_INLINE ACE_Char_Codeset_Translator * +ACE_OutputCDR::char_translator (void) const +{ + return this->char_translator_; +} + +ACE_INLINE ACE_WChar_Codeset_Translator * +ACE_OutputCDR::wchar_translator (void) const +{ + return this->wchar_translator_; +} + +ACE_INLINE void +ACE_OutputCDR::char_translator (ACE_Char_Codeset_Translator * ctran) +{ + this->char_translator_ = ctran; +} + +ACE_INLINE void +ACE_OutputCDR::wchar_translator (ACE_WChar_Codeset_Translator * wctran) +{ + this->wchar_translator_ = wctran; +} + +// **************************************************************** + +ACE_INLINE +ACE_InputCDR::~ACE_InputCDR (void) +{ +#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1) + this->monitor_->remove_ref (); +#endif /* ACE_HAS_MONITOR_POINTS==1 */ +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_octet (ACE_CDR::Octet& x) +{ + return this->read_1 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_boolean (ACE_CDR::Boolean& x) +{ + ACE_CDR::Octet tmp = 0; + (void) this->read_octet (tmp); + x = tmp ? true : false; + return (ACE_CDR::Boolean) this->good_bit_; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_char (ACE_CDR::Char &x) +{ + if (this->char_translator_ == 0) + { + void *temp = &x; + return this->read_1 (reinterpret_cast (temp)); + } + return this->char_translator_->read_char (*this, x); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_short (ACE_CDR::Short &x) +{ + void *temp = &x; + return this->read_2 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_ushort (ACE_CDR::UShort &x) +{ + return this->read_2 (&x); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_long (ACE_CDR::Long &x) +{ + void *temp = &x; + return this->read_4 (reinterpret_cast (temp)); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_ulong (ACE_CDR::ULong &x) +{ + return this->read_4 (&x); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_longlong (ACE_CDR::LongLong &x) +{ + void *temp = &x; + return this->read_8 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_ulonglong (ACE_CDR::ULongLong &x) +{ + return this->read_8 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_float (ACE_CDR::Float &x) +{ + void *temp = &x; + return this->read_4 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_double (ACE_CDR::Double &x) +{ + void *temp = &x; + return this->read_8 (reinterpret_cast (temp)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_longdouble (ACE_CDR::LongDouble &x) +{ + return this->read_16 (&x); +} + +ACE_INLINE size_t +ACE_InputCDR::length (void) const +{ + return this->start_.length (); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_char_array (ACE_CDR::Char* x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length > this->length ()) + { + this->good_bit_ = false; + return false; + } + + if (this->char_translator_ == 0) + return this->read_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); + return this->char_translator_->read_char_array (*this, x, length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_wchar_array (ACE_CDR::WChar* x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_OutputCDR::wchar_maxbytes_ > this->length ()) + { + this->good_bit_ = false; + return false; + } + + if (this->wchar_translator_ != 0) + return this->wchar_translator_->read_wchar_array (*this, x, length); + if (ACE_OutputCDR::wchar_maxbytes_ != sizeof (ACE_CDR::WChar)) + return this->read_wchar_array_i (x, length); + return this->read_array (x, + sizeof (ACE_CDR::WChar), + sizeof (ACE_CDR::WChar) == 2 + ? ACE_CDR::SHORT_ALIGN + : ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_octet_array (ACE_CDR::Octet* x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::OCTET_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_short_array (ACE_CDR::Short *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::SHORT_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_ushort_array (ACE_CDR::UShort *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::SHORT_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_long_array (ACE_CDR::Long *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONG_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_ulong_array (ACE_CDR::ULong *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONG_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_longlong_array (ACE_CDR::LongLong *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONGLONG_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_ulonglong_array (ACE_CDR::ULongLong *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONGLONG_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_float_array (ACE_CDR::Float *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONG_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_double_array (ACE_CDR::Double *x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONGLONG_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + + return this->read_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::read_longdouble_array (ACE_CDR::LongDouble* x, + ACE_CDR::ULong length) +{ + // Make sure the length of the array isn't greater than the length of + // the stream. + if (length * ACE_CDR::LONGDOUBLE_SIZE > this->length ()) + { + this->good_bit_ = false; + return false; + } + return this->read_array (x, + ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_octet (void) +{ + ACE_CDR::Octet x; + return this->read_1 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_char (void) +{ + return this->skip_octet (); // sizeof (Char) == sizeof (Octet) +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_boolean (void) +{ + return this->skip_octet () && this->good_bit_; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_ushort (void) +{ + ACE_CDR::UShort x; + return this->read_2 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_short (void) +{ + return this->skip_ushort (); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_ulong (void) +{ + ACE_CDR::ULong x; + return this->read_4 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_long (void) +{ + return this->skip_ulong (); // sizeof (Long) == sizeof (ULong) +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_ulonglong (void) +{ + ACE_CDR::ULongLong x; + return this->read_8 (&x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_longlong (void) +{ + return this->skip_ulonglong (); // sizeof (LongLong) == sizeof (ULongLong) +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_float (void) +{ + return this->skip_ulong (); // sizeof(Float) == sizeof (ULong) +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_double (void) +{ + return this->skip_ulonglong (); // sizeof(Double) == sizeof (ULongLong) +} + +ACE_INLINE ACE_CDR::Boolean +ACE_InputCDR::skip_longdouble (void) +{ + ACE_CDR::LongDouble x; + return this->read_16 (&x); +} + +ACE_INLINE char* +ACE_InputCDR::end (void) +{ + return this->start_.end (); +} + +ACE_INLINE void +ACE_InputCDR::rd_ptr (size_t offset) +{ + this->start_.rd_ptr (offset); +} + +ACE_INLINE char* +ACE_InputCDR::rd_ptr (void) +{ + return this->start_.rd_ptr (); +} + +ACE_INLINE char* +ACE_InputCDR::wr_ptr (void) +{ + return this->start_.wr_ptr (); +} + +ACE_INLINE int +ACE_InputCDR::adjust (size_t size, + size_t align, + char*& buf) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + buf = ACE_ptr_align_binary (this->rd_ptr (), align); +#else + buf = this->rd_ptr (); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + char * const end = buf + size; + if (end <= this->wr_ptr ()) + { + this->start_.rd_ptr (end); + return 0; + } + + this->good_bit_ = false; + return -1; +#if defined (ACE_LACKS_CDR_ALIGNMENT) + ACE_UNUSED_ARG (align); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ +} + +ACE_INLINE int +ACE_InputCDR::adjust (size_t size, + char*& buf) +{ + return this->adjust (size, size, buf); +} + +ACE_INLINE const ACE_Message_Block* +ACE_InputCDR::start (void) const +{ + return &this->start_; +} + +ACE_INLINE bool +ACE_InputCDR::good_bit (void) const +{ + return this->good_bit_; +} + +// **************************************************************** + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::Char x) +{ + os.write_char (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::Short x) +{ + os.write_short (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::UShort x) +{ + os.write_ushort (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::Long x) +{ + os.write_long (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::ULong x) +{ + os.write_ulong (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::LongLong x) +{ + os.write_longlong (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::ULongLong x) +{ + os.write_ulonglong (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::LongDouble x) +{ + os.write_longdouble (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::Float x) +{ + os.write_float (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_CDR::Double x) +{ + os.write_double (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, const ACE_CDR::Char *x) +{ + os.write_string (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, const ACE_CDR::WChar *x) +{ + os.write_wstring (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +// The following use the helper classes +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_boolean x) +{ + (void) os.write_boolean (x.val_); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_char x) +{ + os.write_char (x.val_); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_wchar x) +{ + os.write_wchar (x.val_); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_octet x) +{ + os.write_octet (x.val_); + return (ACE_CDR::Boolean) os.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_string x) +{ + ACE_CDR::ULong len = 0; + + if (x.val_ != 0) + { + len = static_cast (ACE_OS::strlen (x.val_)); + } + + os.write_string (len, x.val_); + return + (ACE_CDR::Boolean) (os.good_bit () && (!x.bound_ || len <= x.bound_)); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_wstring x) +{ + ACE_CDR::ULong len = 0; + + if (x.val_ != 0) + { + len = static_cast (ACE_OS::strlen (x.val_)); + } + + os.write_wstring (len, x.val_); + return + (ACE_CDR::Boolean) (os.good_bit () && (!x.bound_ || len <= x.bound_)); +} + +// **************************************************************** + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::Char &x) +{ + return is.read_char (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::Short &x) +{ + return is.read_short (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::UShort &x) +{ + return is.read_ushort (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>>(ACE_InputCDR &is, ACE_CDR::Long &x) +{ + return is.read_long (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::ULong &x) +{ + return is.read_ulong (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR& is, ACE_CDR::LongLong &x) +{ + return is.read_longlong (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR& is, ACE_CDR::ULongLong &x) +{ + return is.read_ulonglong (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR& is, ACE_CDR::LongDouble &x) +{ + return is.read_longdouble (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::Float &x) +{ + return is.read_float (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::Double &x) +{ + return is.read_double (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::Char *&x) +{ + return is.read_string (x) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_CDR::WChar *&x) +{ + return is.read_wstring (x) && is.good_bit (); +} + +// The following use the helper classes +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_boolean x) +{ + return is.read_boolean (x.ref_); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_char x) +{ + return is.read_char (x.ref_) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_wchar x) +{ + return is.read_wchar (x.ref_) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_octet x) +{ + return is.read_octet (x.ref_) && is.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_string x) +{ + // check if the bounds are satisfied + return + (is.read_string (const_cast (x.val_)) + && is.good_bit () + && (!x.bound_ + || ACE_OS::strlen (x.val_) <= x.bound_)); +} + +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_wstring x) +{ + // check if the bounds are satisfied + return + (is.read_wstring (const_cast (x.val_)) + && is.good_bit () + && (!x.bound_ + || ACE_OS::strlen (x.val_) <= x.bound_)); +} + +// *************************************************************************** +// We must define these methods here because they use the "read_*" inlined +// methods of the ACE_InputCDR class +// *************************************************************************** + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_boolean (ACE_InputCDR &stream) +{ + ACE_CDR::Boolean x; + return stream.read_boolean (x) ? this->write_boolean (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_char (ACE_InputCDR &stream) +{ + ACE_CDR::Char x; + return stream.read_char (x) ? this->write_char (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_wchar (ACE_InputCDR &stream) +{ + ACE_CDR::WChar x; + return stream.read_wchar (x) ? this->write_wchar (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_octet (ACE_InputCDR &stream) +{ + ACE_CDR::Octet x; + return stream.read_octet (x) ? this->write_octet (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_short (ACE_InputCDR &stream) +{ + ACE_CDR::Short x; + return stream.read_short (x) ? this->write_short (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_ushort (ACE_InputCDR &stream) +{ + ACE_CDR::UShort x; + return stream.read_ushort (x) ? this->write_ushort (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_long (ACE_InputCDR &stream) +{ + ACE_CDR::Long x; + return stream.read_long (x) ? this->write_long (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_ulong (ACE_InputCDR &stream) +{ + ACE_CDR::ULong x; + return stream.read_ulong (x) ? this->write_ulong (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_longlong (ACE_InputCDR &stream) +{ + ACE_CDR::LongLong x; + return stream.read_longlong (x) ? this->write_longlong (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_ulonglong (ACE_InputCDR &stream) +{ + ACE_CDR::ULongLong x; + return stream.read_ulonglong (x) ? this->write_ulonglong (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_float (ACE_InputCDR &stream) +{ + ACE_CDR::Float x; + return stream.read_float (x) ? this->write_float (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_double (ACE_InputCDR &stream) +{ + ACE_CDR::Double x; + return stream.read_double (x) ? this->write_double (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_longdouble (ACE_InputCDR &stream) +{ + ACE_CDR::LongDouble x; + return stream.read_longdouble (x) ? this->write_longdouble (x) : false; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_string (ACE_InputCDR &stream) +{ + ACE_CDR::Char *x = 0; + ACE_CDR::Boolean const flag = + (stream.read_string (x) ? this->write_string (x) : false); + delete [] x; + return flag; +} + +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::append_wstring (ACE_InputCDR &stream) +{ + ACE_CDR::WChar *x = 0; + ACE_CDR::Boolean const flag = + (stream.read_wstring (x) ? this->write_wstring (x) : false); + delete [] x; + return flag; +} + +ACE_INLINE void +ACE_InputCDR::reset_byte_order (int byte_order) +{ + this->do_byte_swap_ = (byte_order != ACE_CDR_BYTE_ORDER); +} + +ACE_INLINE bool +ACE_InputCDR::do_byte_swap (void) const +{ + return this->do_byte_swap_; +} + +ACE_INLINE int +ACE_InputCDR::byte_order (void) const +{ + return this->do_byte_swap () ? !ACE_CDR_BYTE_ORDER : ACE_CDR_BYTE_ORDER; +} + +ACE_INLINE int +ACE_InputCDR::align_read_ptr (size_t alignment) +{ +#if !defined (ACE_LACKS_CDR_ALIGNMENT) + char *buf = ACE_ptr_align_binary (this->rd_ptr (), + alignment); +#else + char *buf = this->rd_ptr (); +#endif /* ACE_LACKS_CDR_ALIGNMENT */ + + if (buf <= this->wr_ptr ()) + { + this->start_.rd_ptr (buf); + return 0; + } + + this->good_bit_ = false; + return -1; +} + +ACE_INLINE void +ACE_InputCDR::set_version (ACE_CDR::Octet major, ACE_CDR::Octet minor) +{ + this->major_version_ = major; + this->minor_version_ = minor; +} + +ACE_INLINE void +ACE_InputCDR::get_version (ACE_CDR::Octet &major, ACE_CDR::Octet &minor) +{ + major = this->major_version_; + minor = this->minor_version_; +} + +ACE_INLINE ACE_Char_Codeset_Translator * +ACE_InputCDR::char_translator (void) const +{ + return this->char_translator_; +} + +ACE_INLINE ACE_WChar_Codeset_Translator * +ACE_InputCDR::wchar_translator (void) const +{ + return this->wchar_translator_; +} + + +ACE_INLINE void +ACE_InputCDR::char_translator (ACE_Char_Codeset_Translator * ctran) +{ + this->char_translator_ = ctran; +} + +ACE_INLINE void +ACE_InputCDR::wchar_translator (ACE_WChar_Codeset_Translator * wctran) +{ + this->wchar_translator_ = wctran; +} + +// **************************************************************** + +ACE_INLINE ACE_CDR::Boolean +ACE_Char_Codeset_Translator::read_1 (ACE_InputCDR& input, + ACE_CDR::Octet *x) +{ + return input.read_1 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_Char_Codeset_Translator::write_1 (ACE_OutputCDR& output, + const ACE_CDR::Octet *x) +{ + return output.write_1 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_Char_Codeset_Translator::read_array (ACE_InputCDR& in, + void* x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + return in.read_array (x, size, align, length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_Char_Codeset_Translator::write_array (ACE_OutputCDR& out, + const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + return out.write_array(x, size, align, length); +} + +ACE_INLINE int +ACE_Char_Codeset_Translator::adjust (ACE_OutputCDR& out, + size_t size, + size_t align, + char *&buf) +{ + return out.adjust(size, align, buf); +} + +ACE_INLINE void +ACE_Char_Codeset_Translator::good_bit (ACE_OutputCDR& out, bool bit) +{ + out.good_bit_ = bit; +} + +ACE_INLINE ACE_CDR::Octet +ACE_Char_Codeset_Translator::major_version (ACE_InputCDR& input) +{ + return input.major_version_; +} + +ACE_INLINE ACE_CDR::Octet +ACE_Char_Codeset_Translator::minor_version (ACE_InputCDR& input) +{ + return input.minor_version_; +} + +ACE_INLINE ACE_CDR::Octet +ACE_Char_Codeset_Translator::major_version (ACE_OutputCDR& output) +{ + return output.major_version_; +} + +ACE_INLINE ACE_CDR::Octet +ACE_Char_Codeset_Translator::minor_version (ACE_OutputCDR& output) +{ + return output.minor_version_; +} + +// **************************************************************** + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::read_1 (ACE_InputCDR& input, + ACE_CDR::Octet *x) +{ + return input.read_1 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::read_2 (ACE_InputCDR& input, + ACE_CDR::UShort *x) +{ + return input.read_2 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::read_4 (ACE_InputCDR& input, + ACE_CDR::ULong *x) +{ + return input.read_4 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::write_1 (ACE_OutputCDR& output, + const ACE_CDR::Octet *x) +{ + return output.write_1 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::write_2 (ACE_OutputCDR& output, + const ACE_CDR::UShort *x) +{ + return output.write_2 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::write_4 (ACE_OutputCDR& output, + const ACE_CDR::ULong *x) +{ + return output.write_4 (x); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::read_array (ACE_InputCDR& in, + void* x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + return in.read_array (x, size, align, length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::write_array (ACE_OutputCDR& out, + const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + return out.write_array(x, size, align, length); +} + +ACE_INLINE int +ACE_WChar_Codeset_Translator::adjust (ACE_OutputCDR& out, + size_t size, + size_t align, + char *&buf) +{ + return out.adjust(size, align, buf); +} + +ACE_INLINE void +ACE_WChar_Codeset_Translator::good_bit (ACE_OutputCDR& out, bool bit) +{ + out.good_bit_ = bit; +} + +ACE_INLINE ACE_CDR::Octet +ACE_WChar_Codeset_Translator::major_version (ACE_InputCDR& input) +{ + return input.major_version_; +} + +ACE_INLINE ACE_CDR::Octet +ACE_WChar_Codeset_Translator::minor_version (ACE_InputCDR& input) +{ + return input.minor_version_; +} + +ACE_INLINE ACE_CDR::Octet +ACE_WChar_Codeset_Translator::major_version (ACE_OutputCDR& output) +{ + return output.major_version_; +} + +ACE_INLINE ACE_CDR::Octet +ACE_WChar_Codeset_Translator::minor_version (ACE_OutputCDR& output) +{ + return output.minor_version_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/CE_Screen_Output.cpp b/dep/ACE_wrappers/ace/CE_Screen_Output.cpp new file mode 100644 index 000000000..dfd3d717a --- /dev/null +++ b/dep/ACE_wrappers/ace/CE_Screen_Output.cpp @@ -0,0 +1,158 @@ +// $Id: CE_Screen_Output.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/CE_Screen_Output.h" +#if defined (ACE_HAS_WINCE) + +#include "ace/Log_Msg.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_CE_Screen_Output::ACE_CE_Screen_Output(HWND hEdit) +: handler_(hEdit) +, pFile_(0) +{ +} + +ACE_CE_Screen_Output::ACE_CE_Screen_Output() +: handler_(0) +, pFile_(0) +{ +} + +ACE_CE_Screen_Output::~ACE_CE_Screen_Output() +{ + if (pFile_ != 0) { + fclose(pFile_); + } +} + +void ACE_CE_Screen_Output::log(ACE_Log_Record &log_record) +{ + ACE_TCHAR verbose_msg[ACE_Log_Record::MAXVERBOSELOGMSGLEN]; + int result = log_record.format_msg (ACE_TEXT("WindozeCE"), // host name + 0, // verbose flag + verbose_msg); + + if (result == 0) + { + verbose_msg[ ACE_OS::strlen(verbose_msg) - 1 ] = 0; // CE does not like '\n' by itself. + *this << verbose_msg << endl; + } +} + +void ACE_CE_Screen_Output::SetOutputWindow(HWND hEdit) +{ + handler_ = hEdit; +} + +void ACE_CE_Screen_Output::clear() +{ + SetWindowText(handler_, 0); +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (ACE_TCHAR* output) +{ + int length = GetWindowTextLength(handler_); + SendMessage(handler_, EM_SETSEL, length, length); + SendMessage(handler_, EM_REPLACESEL, 0, (LPARAM)output); + + if (pFile_ != 0) + { + fwprintf(pFile_, L"%s", output); + } + + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (const ACE_TCHAR* output) +{ + ACE_TCHAR* buffer = ACE_OS::strdup(output); + if (buffer != 0) + { + *this << buffer; + delete buffer; + } + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (ACE_ANTI_TCHAR* output) +{ + *this << ACE_TEXT_CHAR_TO_TCHAR(output); + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (const ACE_ANTI_TCHAR* output) +{ + *this << ACE_TEXT_CHAR_TO_TCHAR(output); + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (char output) +{ + *this << (int)output; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (unsigned char output) +{ + *this << (int)output; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (unsigned short output) +{ + ACE_TCHAR buffer[20]; + wsprintf(buffer, ACE_TEXT("%u"), output); + *this << buffer; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (int output) +{ + ACE_TCHAR buffer[20]; + wsprintf(buffer, ACE_TEXT("%d"), output); + *this << buffer; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (unsigned int output) +{ + ACE_TCHAR buffer[20]; + wsprintf(buffer, ACE_TEXT("%du"), output); + *this << buffer; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (float output) +{ + ACE_TCHAR buffer[20]; + swprintf(buffer, ACE_TEXT("%f"), output); + *this << buffer; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (long output) +{ + ACE_TCHAR buffer[20]; + wsprintf(buffer, ACE_TEXT("%l"), output); + *this << buffer; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (unsigned long output) +{ + ACE_TCHAR buffer[20]; + wsprintf(buffer, ACE_TEXT("%lu"), output); + *this << buffer; + return *this; +} + +ACE_CE_Screen_Output& ACE_CE_Screen_Output::operator << (FILE* pFile) +{ + pFile_ = pFile; + return *this; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif // ACE_HAS_WINCE diff --git a/dep/ACE_wrappers/ace/CE_Screen_Output.h b/dep/ACE_wrappers/ace/CE_Screen_Output.h new file mode 100644 index 000000000..ba2bc7c02 --- /dev/null +++ b/dep/ACE_wrappers/ace/CE_Screen_Output.h @@ -0,0 +1,109 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CE_Screen_Output.h + * + * $Id: CE_Screen_Output.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Si Mong Park + */ +//============================================================================= + +#ifndef ACE_CE_SCREEN_OUTPUT_H +#define ACE_CE_SCREEN_OUTPUT_H + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_WINCE) + +#include "ace/Log_Msg_Callback.h" +#include "ace/Log_Record.h" + +namespace +{ + const ACE_TCHAR endl[] = ACE_TEXT("\r\n"); + const ACE_TCHAR tab[] = ACE_TEXT("\t"); +} + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_CE_Screen_Output + * + * @brief Replacement of text output for Windows CE. + * + * This class allows standard text output to be displayed on + * text window for Windows CE. Generally, all ACE output will + * go through under CE if and only if user uses WindozeCE + * implementation by using main_ce instead of main. + * Also, for the easier debugging purpose, object pointer of + * this class can be gotten from ACE_Log_Msg::msg_callback() + * and then can be used directly by user just like cout stream. + */ +class ACE_Export ACE_CE_Screen_Output : public ACE_Log_Msg_Callback +{ +public: + + ACE_CE_Screen_Output (HWND hEdit); + + ACE_CE_Screen_Output (void); + + virtual ~ACE_CE_Screen_Output(); + + /// Implementation of pure virtual function from ACE_Log_Msg_Callback. + virtual void log (ACE_Log_Record &log_record); + + /// Interface to specify active window handle. + void SetOutputWindow (HWND hWnd); + + void clear (void); + + /// Stream insertion operator that performs actual print out. + /** + * @note This is the only one operator that performs output. All + * other perators convert the type and use this operator + * underneath. + */ + ACE_CE_Screen_Output& operator << (ACE_TCHAR*); + ACE_CE_Screen_Output& operator << (const ACE_TCHAR*); + + ACE_CE_Screen_Output& operator << (ACE_ANTI_TCHAR* output); + ACE_CE_Screen_Output& operator << (const ACE_ANTI_TCHAR* output); + + ACE_CE_Screen_Output& operator << (char output); + ACE_CE_Screen_Output& operator << (unsigned char output); + + ACE_CE_Screen_Output& operator << (unsigned short output); + + ACE_CE_Screen_Output& operator << (int output); + ACE_CE_Screen_Output& operator << (unsigned int output); + + ACE_CE_Screen_Output& operator << (float output); + + ACE_CE_Screen_Output& operator << (long output); + ACE_CE_Screen_Output& operator << (unsigned long output); + + ACE_CE_Screen_Output& operator << (FILE* pFile); + +private: + + ACE_CE_Screen_Output (ACE_CE_Screen_Output&); + +private: + + HWND handler_; + + /// FILE pointer that used to save output to file. This class does + /// not own the file handler pointer. + FILE* pFile_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif // ACE_HAS_WINCE +#endif // ACE_CE_SCREEN_OUTPUT_H diff --git a/dep/ACE_wrappers/ace/CORBA_macros.h b/dep/ACE_wrappers/ace/CORBA_macros.h new file mode 100644 index 000000000..beab26b7f --- /dev/null +++ b/dep/ACE_wrappers/ace/CORBA_macros.h @@ -0,0 +1,575 @@ +// -*- C++ -*- + +// ============================================================================ +/** + * @file CORBA_macros.h + * + * $Id: CORBA_macros.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Writing code that is portable between platforms with or without + * native C++ exceptions is hard. The following macros offer some + * help on this task, mostly oriented to making the ORB code and the + * IDL generated code portable. + * + * @author Nanbor Wang + * @author Aniruddha Gokhale + * @author Carlos O'Ryan , et al. + */ +// ============================================================================ + +// Macros for handling CORBA exceptions. + +#ifndef ACE_CORBA_MACROS_H +#define ACE_CORBA_MACROS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#define ACE_ENV_POLLUTE_NAMES + +#include "ace/Exception_Macros.h" + +// The Windows MFC exception mechanism requires that a caught CException +// (including the CMemoryException in use here) be freed using its Delete() +// method. Thus, when MFC is in use and we're catching exceptions as a result +// of new(), the exception's Delete() method has to be called. No other +// platform imposes this sort of restriction/requirement. The Windows +// config stuff (at least for MSVC/MFC) defines a ACE_del_bad_alloc macro +// that works with its ACE_bad_alloc macro to implement this cleanup +// requirement. Since no other platform requires this, define it as +// empty here. +#if !defined (ACE_del_bad_alloc) +# define ACE_del_bad_alloc +#endif + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + +// If you wish to you use these macros for emulating exceptions on +// platforms which lack native exception support, you need to do the +// following: +// 1. Define a class Exception. You can name it as you please. This class +// should be at the root of the inheritance hierarchy of all the +// exceptions used in your application. It should define at a minimum +// the following pure virtual methods: +// a) _downcast () - Which allows narrowing of the base exception type to a +// derived type. +// b) _raise() - Which throws an exception of type Exception. +// +// Classes which derive from these should implement these operations. +// +// 2. Define a class Environment. You can name it as you please. This class +// is an exception holder. This class is always on the stack. It should +// support at a minimum the following methods: +// a) exception() - Which returns the Exception held in the current +// Environment. +// b) exception (Exception* foo) - Which replaces/sets the Exception +// held in the current Environment with foo. +// b) clear() - Which resets a particular instance of Environment. +// c) A copy constructor and an assignment operator. +// +// Note that the above description assumes that you use the following +// macros only within a particular domain. For example, if your +// application has to interoperate across domains, then you need to define +// an exception adapter to translate exceptions from one domain to +// exceptions in the other. Please refer to Stroustrup's book on how to do +// this. If your use case is this complex, you would be better off with +// going with native exceptions rather than emulated exceptions, though +// the macros should still work if you defined your adapter class as +// ACE_EXCEPTION_TYPE. + + +// The following macros assume that an environment variable is passed +// in/out of each function that can throw an exception. The type of the +// environment variable is defined by ACE_ENV_TYPE. + +#if !defined (ACE_ENV_TYPE) +# define ACE_ENV_TYPE CORBA::Environment +#endif /* ACE_ENV_TYPE */ + +// The name of the variable is defined by ACE_TRY_ENV. Below is the name +// that we use by default. If you wish to change it you can redefine +// ACE_TRY_ENV to change the default name. Also ACE_ADOPT_ENV allows the +// use of non-standard name within a scope. + +#if !defined (ACE_TRY_ENV) +# define ACE_TRY_ENV _ACE_CORBA_Environment_variable +#endif /* ACE_TRY_ENV */ + +// The base type of Exception from which all the other exception types are +// derived. You can set this to any type as you please. By default, it is +// set to CORBA::Exception. + +#if !defined (ACE_EXCEPTION_TYPE) +# define ACE_EXCEPTION_TYPE CORBA::Exception +#endif /* ACE_EXCEPTION_TYPE */ + +// This method is used to get the default value of the Environment +// variable. In the case of TAO, this variable is part of the TSS ORB +// resources and the method TAO_default_environment() returns the +// Environment variable. + +#if !defined (ACE_DEFAULT_GET_ENV_METHOD) +# define ACE_DEFAULT_GET_ENV_METHOD TAO_default_environment +#endif /* ACE_DEFAULT_GET_ENV_METHOD */ + +// This is the exception caught by ACE_CATCHANY. +#if !defined (ACE_ANY_EXCEPTION) +# define ACE_ANY_EXCEPTION ex +#endif /* ACE_ANY_EXCEPTION */ + +// Declare a new environment variable on the stack. The type of the +// environment variable is determined by ACE_ENV_TYPE. +#if defined (ACE_USES_NATIVE_EXCEPTIONS) +// Don't instantiate an emulated exception environment at all when +// using native C++ exception support. It won't be used. +# define ACE_DECLARE_NEW_ENV +#else +# define ACE_DECLARE_NEW_ENV \ + ACE_ENV_TYPE ACE_TRY_ENV +#endif /* ACE_USES_NATIVE_EXCEPTIONS */ + +// Provided for backward compatibility purposes. Don't use it in new code. +// Use the definition above along with defining ACE_ENV_TYPE. + +#if defined (ACE_ENV_POLLUTE_NAMES) +# define ACE_DECLARE_NEW_CORBA_ENV ACE_DECLARE_NEW_ENV +#endif /* ACE_ENV_POLLUTE_NAMES */ + +#if defined (ACE_USES_NATIVE_EXCEPTIONS) +// ----------------------------------------------------------------- + +// Provided for backward compatibility purposes. Don't use it in new code. +#if defined (ACE_ENV_POLLUTE_NAMES) +# define ACE_ADOPT_CORBA_ENV(ENV) +#endif /* ACE_ENV_POLLUTE_NAMES */ + +#define ACE_ADOPT_ENV (ENV) + +// No need to check. Native exceptions handle the control flow +// automatically when an exception occurs. +# define ACE_CHECK + +// Used when the function requires a return value. +# define ACE_CHECK_RETURN(RETV) + +// ACE_THROW_INT should not be used by the user. +# define ACE_THROW_INT(EXCEPTION) \ + throw EXCEPTION + +// Throwing an exception is easy. These two macros should _NOT_ be +// used within try blocks. +# define ACE_THROW(EXCEPTION) \ + throw EXCEPTION + +// Throwing an exception when the function requires a return value. +# define ACE_THROW_RETURN(EXCEPTION,RETV) \ + throw EXCEPTION + +// For compilers with native exceptions, we can simply use try to try. ;-) +// do {} while (0) is required to avoid compilation warnings. +# define ACE_TRY \ + do \ + { \ + try \ + { +# define ACE_TRY_NEW_ENV \ + do \ + { \ + try \ + { +# define ACE_TRY_EX(LABEL) \ + do \ + { \ + try \ + { + +// No need to check for exceptions within try block for compilers with +// native exceptions. +# define ACE_TRY_CHECK +# define ACE_TRY_CHECK_EX(LABEL) + +// Likewise, throwing exceptions within try blocks is easy. +# define ACE_TRY_THROW(EXCEPTION) throw EXCEPTION +# define ACE_TRY_THROW_EX(EXCEPTION,LABEL) throw EXCEPTION + +// Same thing for catch. +# define ACE_CATCH(EXCEPTION,VAR) \ + } \ + catch (EXCEPTION & VAR) \ + { \ + ACE_UNUSED_ARG (VAR); + +# define ACE_CATCHANY \ + ACE_CATCH(ACE_EXCEPTION_TYPE, ACE_ANY_EXCEPTION) + +# define ACE_CATCHALL \ + } \ + catch (...) \ + { + +# if defined (ACE_HAS_DEPRECATED_ACE_RETHROW) +# define ACE_RETHROW throw +# endif /* ACE_HAS_DEPRECATED_ACE_RETHROW */ + +// Rethrowing the exception from catch blocks. +# define ACE_RE_THROW throw +# define ACE_RE_THROW_EX(LABEL) throw + +// Close the catch block. +# define ACE_ENDTRY \ + } \ + } while (0) + +#else /* ! ACE_USES_NATIVE_EXCEPTIONS */ +// ----------------------------------------------------------------- + +// When handling compilers without native exceptions, things get a bit +// hairy. Exceptions are simulated using ACE_ENV_TYPE. The trick here is to +// make sure the flow-of-control can simulate the case when native +// exceptions occur... + +#if defined (ACE_ENV_POLLUTE_NAMES) +# define ACE_ADOPT_CORBA_ENV(ENV) ACE_ENV_TYPE &ACE_TRY_ENV = ENV +#endif /* ACE_ENV_POLLUTE_NAMES */ + +# define ACE_ADOPT_ENV(ENV) ACE_ENV_TYPE &ACE_TRY_ENV = ENV + +// Follow every statement that could throw exceptions with ACE_CHECK or +// ACE_CHECK_RETURN. These two macros should _NOT_ be used within try +// blocks. Use ACE_TRY_CHECK or ACE_TRY_CHECK_EX instead. +# define ACE_CHECK \ + if (ACE_TRY_ENV . exception () != 0) \ + return +// When function requires a return value +# define ACE_CHECK_RETURN(RETV) \ + if (ACE_TRY_ENV . exception () != 0) \ + return RETV + +// ACE_THROW_INT should not be used by the user. +# define ACE_THROW_INT(EXCEPTION) ACE_TRY_ENV.exception (new EXCEPTION) + +// Throwing exceptions will inevitably cause a return from the current +// function. These two macros should _NOT_ be used within try blocks. Use +// ACE_TRY_THROW or ACE_TRY_THROW_EX instead. +# define ACE_THROW(EXCEPTION) \ + do \ + { \ + ACE_TRY_ENV.exception (new EXCEPTION); \ + return; \ + } while (0) + +# define ACE_THROW_RETURN(EXCEPTION,RETV) \ + do \ + { \ + ACE_TRY_ENV.exception (new EXCEPTION); \ + return RETV; \ + } while (0) + +// ACE_TRY sets up flags to control program flow. ACE_TRY_FLAG acts like a +// one-shot flip-flop. When an exception occurs (detected using +// ACE_TRY_CHECK,) ACE_TRY_FLAG will be reset and the control goes back +// into ACE_TRY_LABEL. Since ACE_TRY_FLAG is reset, the try block won't get +// executed again and the control proceeds to the following catch blocks. +// ACE_EXCEPTION_NOT_CAUGHT flag is used to prevent catching an exception +// twice. This macro assumes there's already an ACE_ENV_TYPE variable +// ACE_TRY_ENV defined (which should be the case normally) +# define ACE_TRY \ + do { \ + int ACE_TRY_FLAG = 1; \ + int ACE_EXCEPTION_NOT_CAUGHT = 1; \ + ACE_TRY_LABEL: \ + if (ACE_TRY_FLAG) \ + do { + +// ACE_TRY_NEW_ENV functions like the macro ACE_TRY but defines a new +// ACE_ENV_TYPE variable ACE_TRY_ENV. It is most often used in the outer +// most function where no ACE_TRY_ENV is available. +# define ACE_TRY_NEW_ENV \ + do { \ + ACE_DECLARE_NEW_ENV;\ + int ACE_TRY_FLAG = 1; \ + int ACE_EXCEPTION_NOT_CAUGHT = 1; \ + ACE_TRY_LABEL: \ + if (ACE_TRY_FLAG) \ + do { + +// ACE_TRY_EX works exactly like ACE_TRY macro except the label used in the +// try block is customizable to avoid name clashing. It should be used when +// nested try blocks or multiple try blocks are required, in the same +// function. +# define ACE_TRY_EX(LABEL) \ + do { \ + int ACE_TRY_FLAG = 1; \ + int ACE_EXCEPTION_NOT_CAUGHT = 1; \ + ACE_TRY_LABEL ## LABEL: \ + if (ACE_TRY_FLAG) \ + do { + +// Check for exceptions within try blocks. +# define ACE_TRY_CHECK \ + { \ + if (ACE_TRY_ENV.exception () != 0) \ + { \ + ACE_TRY_FLAG = 0; \ + goto ACE_TRY_LABEL; \ + } \ + } + +// Checking exception within EX try blocks. +# define ACE_TRY_CHECK_EX(LABEL) \ + { \ + if (ACE_TRY_ENV.exception () != 0) \ + { \ + ACE_TRY_FLAG = 0; \ + goto ACE_TRY_LABEL ## LABEL; \ + } \ + } + +// Throwing exception within TRY blocks. +# define ACE_TRY_THROW(EXCEPTION) \ + { \ + ACE_TRY_ENV.exception (new EXCEPTION); \ + ACE_TRY_FLAG = 0; \ + goto ACE_TRY_LABEL; \ + } + +# define ACE_TRY_THROW_EX(EXCEPTION,LABEL) \ + { \ + ACE_TRY_ENV.exception (new EXCEPTION); \ + ACE_TRY_FLAG = 0; \ + goto ACE_TRY_LABEL ## LABEL; \ + } + +// When exceptions occur or try block finishes execution without exception, +// control will continue in the catch block. This macro first checks if +// there's any uncaught exception left. If all the conditions are met, we +// have caught an exception. It then resets ACE_EXCEPTION_NOT_CAUGHT to +// prevent subsequent catch blocks from catching the same exception again, +// and extracts out the underlying exception in ACE_TRY_ENV. We also make a +// copy of ACE_TRY_ENV in ACE_CAUGHT_ENV, in case we want to rethrow the +// exception. ACE_TRY_ENV is cleared out after the exception is caught so +// you should not use ACE_TRY_ENV within the catch block(You should use the +// exception directly). +# define ACE_CATCH(TYPE,VAR) \ + } while (0); \ + do \ + if (ACE_TRY_ENV.exception () != 0 && ACE_EXCEPTION_NOT_CAUGHT && \ + TYPE::_downcast(ACE_TRY_ENV.exception ()) != 0) \ + { \ + ACE_ENV_TYPE ACE_CAUGHT_ENV = ACE_TRY_ENV;\ + ACE_EXCEPTION_NOT_CAUGHT = 0; \ + TYPE &VAR = *TYPE::_downcast (ACE_CAUGHT_ENV.exception ()); \ + ACE_UNUSED_ARG (VAR); \ + ACE_TRY_ENV.clear (); + +// ACE_CATCHANY uses ACE_CATCH to catch all exceptions derived from +// ACE_EXCEPTION_TYPE +# define ACE_CATCHANY ACE_CATCH (ACE_EXCEPTION_TYPE, ACE_ANY_EXCEPTION) + +// Since there's no other exception for compilers without exception +// support, we simply catch all ACE_EXCEPTION_TYPE exceptions for +// ACE_CATCHALL. +# define ACE_CATCHALL ACE_CATCHANY + +# if defined (ACE_HAS_DEPRECATED_ACE_RETHROW) +# define ACE_RETHROW \ + do \ + ACE_TRY_ENV = ACE_CAUGHT_ENV; \ + while (0) +# endif /* ACE_HAS_DEPRECATED_ACE_RETHROW */ + +// Rethrowing exception within catch blocks. Notice that we depend on the +// ACE_CHECK/ACE_CHECK_RETURN following the ACE_ENDTRY, or ACE_TRY_CHECK/ +// ACE_TRY_CHECK_EX following the ACE_ENDTRY when the catch block is within +// another try block, to do the "Right Thing[TM]." +# define ACE_RE_THROW \ + do {\ + ACE_TRY_ENV = ACE_CAUGHT_ENV; \ + goto ACE_TRY_LABEL; \ + } while (0) +# define ACE_RE_THROW_EX(LABEL) \ + do {\ + ACE_TRY_ENV = ACE_CAUGHT_ENV; \ + goto ACE_TRY_LABEL ## LABEL; \ + } while (0) + +// Close the try block. Since exceptions may not get caught, and exceptions +// can also be rethrown from the catch block, it's always a good idea to +// follow ACE_ENDTRY with ACE_CHECK or ACE_TRY_CHECK (depending on the +// context.) +# define ACE_ENDTRY \ + } while (0); \ + } while (0) + +#endif /* ! ACE_USES_NATIVE_EXCEPTIONS */ + +#endif /* !ACE_LACKS_DEPRECATED_MACROS */ + +// ACE_HAS_EXCEPTIONS is not the same as ACE_NEW_THROWS_EXCEPTIONS. +#if defined(ACE_NEW_THROWS_EXCEPTIONS) + +# if defined (ACE_HAS_NEW_NOTHROW) + +# define ACE_NEW_THROW_EX(POINTER,CONSTRUCTOR,EXCEPTION) \ + do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \ + if (POINTER == 0) { throw EXCEPTION; } \ + } while (0) + +# else + +# define ACE_NEW_THROW_EX(POINTER,CONSTRUCTOR,EXCEPTION) \ + do { try { POINTER = new CONSTRUCTOR; } \ + catch (ACE_bad_alloc) { ACE_del_bad_alloc throw EXCEPTION; } \ + } while (0) + +# endif /* ACE_HAS_NEW_NOTHROW */ + +#else /* ! ACE_NEW_THROWS_EXCEPTIONS */ + +# define ACE_NEW_THROW_EX(POINTER,CONSTRUCTOR,EXCEPTION) \ + do { POINTER = new CONSTRUCTOR; \ + if (POINTER == 0) { throw EXCEPTION; } \ + } while (0) + +#endif /* ACE_NEW_THROWS_EXCEPTIONS */ + +# define ACE_GUARD_THROW_EX(MUTEX,OBJ,LOCK,EXCEPTION) \ + ACE_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) throw EXCEPTION; + +# define ACE_READ_GUARD_THROW_EX(MUTEX,OBJ,LOCK,EXCEPTION) \ + ACE_Read_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) throw EXCEPTION; + +# define ACE_WRITE_GUARD_THROW_EX(MUTEX,OBJ,LOCK,EXCEPTION) \ + ACE_Write_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) throw EXCEPTION; + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + +//@{ +/** + * @name Native C++ exceptions portability macros. + * + * The following macros are used to write code portable between platforms + * with and without native C++ exception support. Their main goal is to + * hide the presence of the ACE_ENV_TYPE argument, but they collaborate + * with the ACE_TRY_* macros to emulate the try/catch blocks. + */ + +/// Define a macro to emit code only when ACE_ENV_TYPE is used +#if !defined (ACE_USES_NATIVE_EXCEPTIONS) || defined (ACE_ENV_BKWD_COMPAT) +# define ACE_ENV_EMIT_CODE(X) X +#else +# define ACE_ENV_EMIT_CODE(X) +#endif /* ACE_USES_NATIVE_EXCEPTIONS && ! ACE_ENV_BKWD_COMPAT */ + +/// Another macro to emit code only when ACE_ENV_TYPE is used +#if !defined (ACE_USES_NATIVE_EXCEPTIONS) || defined (ACE_ENV_BKWD_COMPAT) +# define ACE_ENV_EMIT_CODE2(X,Y) X,Y +#else +# define ACE_ENV_EMIT_CODE2(X,Y) +#endif /* ACE_USES_NATIVE_EXCEPTIONS && ! ACE_ENV_BKWD_COMPAT */ + +/// Helper macro +#define ACE_ENV_EMIT_DUMMY + +/// Declare a ACE_ENV_TYPE argument as the last argument of a +/// function +/** + * Normally this macro is used as follows: + * + * void my_funct (int x, int y ACE_ENV_ARG_DECL); + * + * Its purpose is to provide developers (and users) with a mechanism to + * write code that is portable to platforms with and without native C++ + * exceptions. + */ +#define ACE_ENV_ARG_DECL \ + ACE_ENV_EMIT_CODE2(ACE_ENV_EMIT_DUMMY, \ + ACE_ENV_TYPE &ACE_TRY_ENV) + +/// Declare a ACE_ENV_TYPE argument with the default value obtained from +/// the ORB/application. +/** + * It is similar to ACE_ENV_ARG_DECL. The name of the default environment + * getter method needs to be changed when switching ORBs or when used with + * another application. + */ +#define ACE_ENV_ARG_DECL_WITH_DEFAULTS \ + ACE_ENV_EMIT_CODE2(ACE_ENV_EMIT_DUMMY, \ + ACE_ENV_TYPE &ACE_TRY_ENV = \ + ACE_DEFAULT_GET_ENV_METHOD ()) + +/// Declare a ACE_ENV_TYPE argument that is not used by the +/// function definition. +/** + * Similar to ACE_ENV_ARG_DECL, but the formal parameter name is dropped to + * avoid warnings about unused parameters + */ +#define ACE_ENV_ARG_DECL_NOT_USED \ + ACE_ENV_EMIT_CODE2(ACE_ENV_EMIT_DUMMY, \ + ACE_ENV_TYPE &) + +/// Declare a ACE_ENV_TYPE argument for methods that do not take any other +/// parameters +#define ACE_ENV_SINGLE_ARG_DECL \ + ACE_ENV_EMIT_CODE(ACE_ENV_TYPE &ACE_TRY_ENV) + +/// Declare a ACE_ENV_TYPE argument with a default value for methods that +/// do not take any other parameters. The name of the default environment +/// getter method needs to be changed when switching ORBs or when used in +/// another application. +#define ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS \ + ACE_ENV_EMIT_CODE(ACE_ENV_TYPE &ACE_TRY_ENV = \ + ACE_DEFAULT_GET_ENV_METHOD ()) + +/// Declare a ACE_ENV_TYPE argument for methods which don't use it. +#define ACE_ENV_SINGLE_ARG_DECL_NOT_USED \ + ACE_ENV_EMIT_CODE(ACE_ENV_TYPE &) + +/// Use the ACE_ENV_TYPE argument in a nested call +#define ACE_ENV_ARG_PARAMETER \ + ACE_ENV_EMIT_CODE2(ACE_ENV_EMIT_DUMMY, \ + ACE_TRY_ENV) + +/// Use the ACE_ENV_TYPE argument in a nested call, assuming that the +/// called function takes only the ACE_TRY_ENV argument. +#define ACE_ENV_SINGLE_ARG_PARAMETER \ + ACE_ENV_EMIT_CODE(ACE_TRY_ENV) + +/// Eliminate unused argument warnings about ACE_TRY_ENV +#define ACE_ENV_ARG_NOT_USED \ + ACE_ENV_EMIT_CODE(ACE_UNUSED_ARG(ACE_TRY_ENV)) +//@} + +#if !defined (ACE_USES_NATIVE_EXCEPTIONS) +// This thing can be moved above when we drop ACE_ENV_BKWD_COMPAT. +# define ACE_ENV_RAISE(ex) ACE_TRY_ENV.exception (ex) +#else +# define ACE_ENV_RAISE(ex) (ex)->_raise () +#endif /* ACE_USES_NATIVE_EXCEPTIONS */ + +// ============================================================ + +// Print out a TAO exception. This is not CORBA compliant. +# define ACE_PRINT_TAO_EXCEPTION(EX,INFO) \ + EX._tao_print_exception (INFO) + +// Print out a CORBA exception. There is not portable way to +// dump a CORBA exception. If you are using other ORB implementation, +// redefine the macro to get what you want. +# if !defined ACE_PRINT_EXCEPTION +# define ACE_PRINT_EXCEPTION(EX,INFO) ACE_PRINT_TAO_EXCEPTION(EX,INFO) +# endif /* ACE_PRINT_EXCEPTION */ + +#endif /* !ACE_LACKS_DEPRECATED_MACROS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CORBA_MACROS_H */ diff --git a/dep/ACE_wrappers/ace/Cache_Map_Manager_T.cpp b/dep/ACE_wrappers/ace/Cache_Map_Manager_T.cpp new file mode 100644 index 000000000..f87031eb0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Cache_Map_Manager_T.cpp @@ -0,0 +1,420 @@ +// $Id: Cache_Map_Manager_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CACHE_MAP_MANAGER_T_CPP +#define ACE_CACHE_MAP_MANAGER_T_CPP + +#include "ace/Cache_Map_Manager_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Log_Msg.h" +#include "ace/Malloc_Base.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Cache_Map_Manager_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Cache_Map_Manager) + +ACE_ALLOC_HOOK_DEFINE(ACE_Cache_Map_Iterator) + +ACE_ALLOC_HOOK_DEFINE(ACE_Cache_Map_Reverse_Iterator) + +#define ACE_T1 class KEY, class VALUE, class CMAP_TYPE, class ITERATOR_IMPL, class REVERSE_ITERATOR_IMPL, class CACHING_STRATEGY, class ATTRIBUTES +#define ACE_T2 KEY, VALUE, CMAP_TYPE, ITERATOR_IMPL, REVERSE_ITERATOR_IMPL, CACHING_STRATEGY, ATTRIBUTES + +template +ACE_Cache_Map_Manager::ACE_Cache_Map_Manager (CACHING_STRATEGY &caching_s, + size_t size, + ACE_Allocator *alloc) + : caching_strategy_ (caching_s) +{ + if (this->open (size, alloc) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Cache_Map_Manager::ACE_Cache_Map_Manager"))); + +} + +template +ACE_Cache_Map_Manager::~ACE_Cache_Map_Manager (void) +{ + this->close (); +} + +template int +ACE_Cache_Map_Manager::open (size_t length, + ACE_Allocator *alloc) +{ + return this->map_.open (length, + alloc); +} + +template int +ACE_Cache_Map_Manager::close (void) +{ + return this->map_.close (); +} + +template int +ACE_Cache_Map_Manager::bind (const KEY &key, + const VALUE &value) +{ + // Insert an entry which has the and the which + // is the combination of the and the attributes of the + // caching strategy. + CACHE_VALUE cache_value (value, + this->caching_strategy_.attributes ()); + + int bind_result = this->map_.bind (key, + cache_value); + + if (bind_result != -1) + { + + int result = this->caching_strategy_.notify_bind (bind_result, + cache_value.second ()); + + if (result == -1) + { + + this->map_.unbind (key); + + // Unless the notification goes thru the bind operation is + // not complete. + bind_result = -1; + + } + + } + + return bind_result; +} + + +template int +ACE_Cache_Map_Manager::rebind (const KEY &key, + const VALUE &value) +{ + CACHE_VALUE cache_value (value, + this->caching_strategy_.attributes ()); + + int rebind_result = this->map_.rebind (key, + cache_value); + + if (rebind_result != -1) + { + + int result = this->caching_strategy_.notify_rebind (rebind_result, + cache_value.second ()); + + if (result == -1) + { + + // Make sure the unbind operation is done only when the + // notification fails after a bind which is denoted by + // rebind_result = 0 + if (rebind_result == 0) + this->map_.unbind (key); + + // Unless the notification goes thru the rebind operation is + // not complete. + rebind_result = -1; + + } + + } + + return rebind_result; +} + + +template int +ACE_Cache_Map_Manager::rebind (const KEY &key, + const VALUE &value, + VALUE &old_value) +{ + CACHE_VALUE cache_value (value, + this->caching_strategy_.attributes ()); + + CACHE_VALUE old_cache_value (old_value, + this->caching_strategy_.attributes ()); + + int rebind_result = this->map_.rebind (key, + cache_value, + old_cache_value); + + if (rebind_result != -1) + { + + int result = this->caching_strategy_.notify_rebind (rebind_result, + cache_value.second ()); + + if (result == -1) + { + + // Make sure the unbind operation is done only when the + // notification fails after a bind which is denoted by + // rebind_result = 0 + if (rebind_result == 0) + this->map_.unbind (key); + + // Unless the notification goes thru the rebind operation is + // not complete. + rebind_result = -1; + + } + else + { + + old_value = old_cache_value.first (); + + } + + } + + return rebind_result; +} + +template int +ACE_Cache_Map_Manager::rebind (const KEY &key, + const VALUE &value, + KEY &old_key, + VALUE &old_value) +{ + CACHE_VALUE cache_value (value, + this->caching_strategy_.attributes ()); + + CACHE_VALUE old_cache_value (old_value, + this->caching_strategy_.attributes ()); + + int rebind_result = this->map_.rebind (key, + cache_value, + old_key, + old_cache_value); + + if (rebind_result != -1) + { + + int result = this->caching_strategy_.notify_rebind (rebind_result, + cache_value.second ()); + + if (result == -1) + { + + // Make sure the unbind operation is done only when the + // notification fails after a bind which is denoted by + // rebind_result = 0 + if (rebind_result == 0) + this->map_.unbind (key); + + // Unless the notification goes thru the rebind operation is + // not complete. + rebind_result = -1; + + } + else + { + + old_value = old_cache_value.first (); + + } + + } + + return rebind_result; +} + +template int +ACE_Cache_Map_Manager::trybind (const KEY &key, + VALUE &value) +{ + CACHE_VALUE cache_value (value, + this->caching_strategy_.attributes ()); + + int trybind_result = this->map_.trybind (key, + cache_value); + + if (trybind_result != -1) + { + + int result = this->caching_strategy_.notify_trybind (trybind_result, + cache_value.second ()); + + if (result == -1) + { + + // If the entry has got inserted into the map, it is removed + // due to failure. + if (trybind_result == 0) + this->map_.unbind (key); + + trybind_result = -1; + + } + else + { + + // If an attempt is made to bind an existing entry the value + // is overwritten with the value from the map. + if (trybind_result == 1) + value = cache_value.first (); + + } + + } + + return trybind_result; +} + +template int +ACE_Cache_Map_Manager::find (const KEY &key, + VALUE &value) +{ + // Lookup the key and populate the . + CACHE_VALUE cache_value; + + int find_result = this->map_.find (key, + cache_value); + + if (find_result != -1) + { + + int result = this->caching_strategy_.notify_find (find_result, + cache_value.second ()); + + // Unless the find and notification operations go thru, this + // method is not successful. + if (result == -1) + find_result = -1; + else + { + + // Since the has now changed after the + // notification, we need to bind to the map again. + int rebind_result = this->map_.rebind (key, + cache_value); + if (rebind_result == -1) + find_result = -1; + else + value = cache_value.first (); + + } + + } + + return find_result; +} + +template int +ACE_Cache_Map_Manager::find (const KEY &key) +{ + // Lookup the key and populate the . + CACHE_VALUE cache_value; + + int find_result = this->map_.find (key, + cache_value); + + if (find_result != -1) + { + + int result = this->caching_strategy_.notify_find (find_result, + cache_value.second ()); + + // Unless the find and notification operations go thru, this + // method is not successful. + if (result == -1) + find_result = -1; + else + { + + // Since the has now changed after the + // notification, we need to bind to the map again. + int rebind_result = this->map_.rebind (key, + cache_value); + + if (rebind_result == -1) + find_result = -1; + + } + + } + + return find_result; +} + + +template int +ACE_Cache_Map_Manager::unbind (const KEY &key) +{ + // Remove the entry from the cache. + CACHE_VALUE cache_value; + + int unbind_result = this->map_.unbind (key, + cache_value); + + if (unbind_result != -1) + { + + int result = this->caching_strategy_.notify_unbind (unbind_result, + cache_value.second ()); + + if (result == -1) + unbind_result = -1; + + } + + return unbind_result; +} + +template int +ACE_Cache_Map_Manager::unbind (const KEY &key, + VALUE &value) +{ + // Remove the entry from the cache. + CACHE_VALUE cache_value; + + int unbind_result = this->map_.unbind (key, + cache_value); + + if (unbind_result != -1) + { + + int result = this->caching_strategy_.notify_unbind (unbind_result, + cache_value.second ()); + + if (result == -1) + unbind_result = -1; + else + value = cache_value.first (); + + } + + return unbind_result; +} + +template void +ACE_Cache_Map_Manager::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->map_.dump (); + + this->caching_strategy_.dump (); +#endif /* ACE_HAS_DUMP */ +} + +#undef ACE_T1 +#undef ACE_T2 + +template +ACE_Cache_Map_Iterator::~ACE_Cache_Map_Iterator (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_CACHE_MAP_MANAGER_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Cache_Map_Manager_T.h b/dep/ACE_wrappers/ace/Cache_Map_Manager_T.h new file mode 100644 index 000000000..060a8b38a --- /dev/null +++ b/dep/ACE_wrappers/ace/Cache_Map_Manager_T.h @@ -0,0 +1,405 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Cache_Map_Manager_T.h + * + * $Id: Cache_Map_Manager_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kirthika Parameswaran + */ +//============================================================================= + +#ifndef ACE_CACHE_MAP_MANAGER_T_H +#define ACE_CACHE_MAP_MANAGER_T_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Default_Constants.h" +#include "ace/Global_Macros.h" +#include "ace/Pair_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration. +class ACE_Allocator; + +#define ACE_Cache_Map_Iterator ACMI +#define ACE_Cache_Map_Reverse_Iterator ACMRI + +template +class ACE_Cache_Map_Iterator; + +template +class ACE_Cache_Map_Reverse_Iterator; + +// For linkers that cant grok long names. +#define ACE_Cache_Map_Manager ACMM + +/** + * @class ACE_Cache_Map_Manager + * + * @brief Defines a abstraction that will purge entries from a map. + * + * The will manage the map it contains + * and provide purging on demand from the map. The strategy for + * caching is decided by the user and provided to the Cache + * Manager. The Cache Manager acts as a agent and communicates + * between the Map and the Strategy for purging entries from the + * map. + * No locking mechanism provided since locking at this level + * isn't efficient. Locking has to be provided by the + * application. + */ +template +class ACE_Cache_Map_Manager +{ +public: + + // = Traits. + typedef KEY key_type; + typedef VALUE mapped_type; + typedef CMAP_TYPE map_type; + typedef CACHING_STRATEGY caching_strategy_type; + + typedef ITERATOR_IMPL ITERATOR_IMPLEMENTATION; + typedef REVERSE_ITERATOR_IMPL REVERSE_ITERATOR_IMPLEMENTATION; + + friend class ACE_Cache_Map_Iterator; + friend class ACE_Cache_Map_Reverse_Iterator; + + // = ACE-style iterator typedefs. + typedef ACE_Cache_Map_Iterator + ITERATOR; + typedef ACE_Cache_Map_Reverse_Iterator + REVERSE_ITERATOR; + + // = STL-style iterator typedefs. + typedef ITERATOR + iterator; + typedef REVERSE_ITERATOR + reverse_iterator; + + /** + * The actual value mapped to the key in the map. The + * are used by the strategy and is transparent to the user of this + * class. + */ + typedef ACE_Pair CACHE_VALUE; + + // = Initialization and termination methods. + + /// Initialize a with and + /// @a size entries. + ACE_Cache_Map_Manager (CACHING_STRATEGY &caching_strategy, + size_t size = ACE_DEFAULT_MAP_SIZE, + ACE_Allocator *alloc = 0); + + /// Close down a and release dynamically allocated + /// resources. + virtual ~ACE_Cache_Map_Manager (void); + + /// Initialize a cache with size @a length. + int open (size_t length = ACE_DEFAULT_MAP_SIZE, + ACE_Allocator *alloc = 0); + + /// Close down a cache and release dynamically allocated resources. + int close (void); + + /** + * Associate @a key with @a value. If @a key is already in the CMAP_TYPE + * then the ENTRY is not changed. Returns 0 if a new entry is bound + * successfully, returns 1 if an attempt is made to bind an existing + * entry, and returns -1 if failures occur. + */ + int bind (const KEY &key, + const VALUE &value); + + /** + * Lookup entry in the cache. If it is not found, returns -1. + * If the @a key is located in the CMAP_TYPE object, the CACHING_STRATEGY is + * notified of it via notify_find (int result, ATTRIBUTES &attribute). + * If notify_find also returns 0 (success), then this function returns + * 0 (success) and sets the cached value in @a value. + */ + int find (const KEY &key, + VALUE &value); + + /** + * Lookup entry in the cache. If it is not found, returns -1. + * If the @a key is located in the CMAP_TYPE object, the CACHING_STRATEGY is + * notified of it via notify_find (int result, ATTRIBUTES &attribute). + * If notify_find also returns 0 (success), then this function returns + * 0 (success). + */ + int find (const KEY &key); + + /** + * Reassociate the @a key with @a value. If the @a key already exists + * in the cache then returns 1, on a new bind returns 0 and returns + * -1 in case of any failures. + */ + int rebind (const KEY &key, + const VALUE &value); + + /** + * Reassociate @a key with @a value, storing the old value into the + * "out" parameter @a old_value. The function fails if @a key is not + * in the cache for caches that do not allow user specified keys. + * However, for caches that allow user specified keys, if the key is + * not in the cache, a new @a key / @a value association is created. + */ + int rebind (const KEY &key, + const VALUE &value, + VALUE &old_value); + + /** + * Reassociate @a key with @a value, storing the old key and value + * into the "out" parameters @a old_key and @a old_value. The + * function fails if @a key is not in the cache for caches that do + * not allow user specified keys. However, for caches that allow + * user specified keys, if the key is not in the cache, a new + * @a key / @a value association is created. + */ + int rebind (const KEY &key, + const VALUE &value, + KEY &old_key, + VALUE &old_value); + + /** + * Associate @a key with @a value if and only if @a key is not in the + * cache. If @a key is already in the cache, then the @a value + * parameter is overwritten with the existing value in the + * cache. Returns 0 if a new @a key / @a value association is created. + * Returns 1 if an attempt is made to bind an existing entry. This + * function fails for maps that do not allow user specified keys. + */ + int trybind (const KEY &key, + VALUE &value); + + /// Remove @a key from the cache. + int unbind (const KEY &key); + + /// Remove @a key from the cache, and return the @a value associated with + /// @a key. + int unbind (const KEY &key, + VALUE &value); + + /// Remove entries from the cache depending upon the strategy. + int purge (void); + + /// Return the current size of the cache. + size_t current_size (void) const; + + /// Return the total size of the cache. + size_t total_size (void) const; + + /// Dumps the state of the object. + void dump (void) const; + + // = STL styled iterator factory functions. + + /// Return forward iterator. + ITERATOR begin (void); + ITERATOR end (void); + + /// Return reverse iterator. + REVERSE_ITERATOR rbegin (void); + REVERSE_ITERATOR rend (void); + + /// The map managed by the Cache_Map_Manager. + CMAP_TYPE &map (void); + + /// The caching strategy used on the cache. + CACHING_STRATEGY &caching_strategy (void); + +protected: + + /// The underlying map which needs to be cached. + CMAP_TYPE map_; + + /// The strategy to be followed for caching entries in the map. + CACHING_STRATEGY &caching_strategy_; + +private: + + // = Disallow these operations. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Cache_Map_Manager &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Cache_Map_Manager (const ACE_Cache_Map_Manager &)) + +}; + +/** + * @class ACE_Cache_Map_Iterator + * + * @brief Defines a iterator for the Cache_Map_Manager. + * + * Implementation to be provided by the iterator of the map + * managed by the ACE_Cache_Map_Manager. + */ +template +class ACE_Cache_Map_Iterator +{ + +public: + + // = Traits. + /// The actual value mapped to the key in the cache. The + /// are used by the strategy and is transperant to the cache user. + typedef ACE_Reference_Pair + value_type; + typedef ACE_Pair + CACHE_VALUE; + + // = Initialisation and termination methods. + + ACE_Cache_Map_Iterator (const IMPLEMENTATION &iterator_impl); + + /// Copy constructor. + ACE_Cache_Map_Iterator (const ACE_Cache_Map_Iterator &rhs); + + virtual ~ACE_Cache_Map_Iterator (void); + + // = Iteration methods. + + /// assignment operator. + ACE_Cache_Map_Iterator &operator= + (const ACE_Cache_Map_Iterator &rhs); + + /// Comparision operators. + bool operator== (const ACE_Cache_Map_Iterator &rhs) const; + bool operator!= (const ACE_Cache_Map_Iterator &rhs) const; + + /// Returns a reference to the internal element @c this is pointing + /// to. + ACE_Reference_Pair operator* (void) const; + + // = STL styled iteration, compare, and reference functions. + + /// Prefix advance + ACE_Cache_Map_Iterator &operator++ (void); + + /// Postfix advance. + ACE_Cache_Map_Iterator operator++ (int); + + /// Prefix reverse. + ACE_Cache_Map_Iterator &operator-- (void); + + /// Postfix reverse. + ACE_Cache_Map_Iterator operator-- (int); + + /// Returns the iterator of the internal map in the custody of the + /// Cache_Map_Manager. + IMPLEMENTATION &iterator_implementation (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// The actual iterator which iterates internally on the map + /// belonging to the Cache_Map_Manager. + IMPLEMENTATION iterator_implementation_; +}; + +/** + * @class ACE_Cache_Map_Reverse_Iterator + * + * @brief Defines a reverse iterator for the Cache_Map_Manager. + * + * Implementation to be provided by the reverse iterator of the map + * managed by thr Cache_Map_manager. + */ +template +class ACE_Cache_Map_Reverse_Iterator +{ +public: + + // = Traits. + /// The actual value mapped to the key in the cache. The + /// are used by the strategy and is transperant to the cache user. + typedef ACE_Reference_Pair value_type; + typedef ACE_Pair CACHE_VALUE; + + // = Initialisation and termination methods. + + ACE_Cache_Map_Reverse_Iterator (const REVERSE_IMPLEMENTATION &iterator_impl); + + /// Copy constructor. + ACE_Cache_Map_Reverse_Iterator (const ACE_Cache_Map_Reverse_Iterator &rhs); + + ~ACE_Cache_Map_Reverse_Iterator (void); + + // = Iteration methods. + + /// Assignment operator. + ACE_Cache_Map_Reverse_Iterator &operator= + (const ACE_Cache_Map_Reverse_Iterator &rhs); + + /// Comparision operators. + bool operator== (const ACE_Cache_Map_Reverse_Iterator &rhs) const; + bool operator!= (const ACE_Cache_Map_Reverse_Iterator &rhs) const; + + /// Returns a reference to the internal element @c this is pointing + /// to. + ACE_Reference_Pair operator* (void) const; + + // = STL styled iteration, compare, and reference functions. + + /// Prefix advance + ACE_Cache_Map_Reverse_Iterator &operator++ (void); + + /// Postfix advance. + ACE_Cache_Map_Reverse_Iterator operator++ (int); + + /// Prefix reverse. + ACE_Cache_Map_Reverse_Iterator &operator-- (void); + + /// Postfix reverse. + ACE_Cache_Map_Reverse_Iterator operator-- (int); + + /// Returns the iterator of the internal map in the custody of the + /// Cache_Map_Manager. + REVERSE_IMPLEMENTATION &iterator_implementation (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// The actual iterator which iterates internally on the map + /// belonging to the Cache_Map_Manager. + REVERSE_IMPLEMENTATION reverse_iterator_implementation_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Cache_Map_Manager_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Cache_Map_Manager_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Cache_Map_Manager_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CACHE_MAP_MANAGER_T_H */ diff --git a/dep/ACE_wrappers/ace/Cache_Map_Manager_T.inl b/dep/ACE_wrappers/ace/Cache_Map_Manager_T.inl new file mode 100644 index 000000000..bcd48bd33 --- /dev/null +++ b/dep/ACE_wrappers/ace/Cache_Map_Manager_T.inl @@ -0,0 +1,245 @@ +// -*- C++ -*- +// +//$Id: Cache_Map_Manager_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE int +ACE_Cache_Map_Manager::purge (void) +{ + return this->caching_strategy ().caching_utility ().clear_cache (this->map_, + this->caching_strategy ().purge_percent ()); +} + +template ACE_INLINE size_t +ACE_Cache_Map_Manager::current_size (void) const +{ + return this->map_.current_size (); +} + +template ACE_INLINE size_t +ACE_Cache_Map_Manager::total_size (void) const +{ + return this->map_.total_size (); +} + +template ACE_INLINE CMAP_TYPE & +ACE_Cache_Map_Manager::map (void) +{ + return this->map_; +} + +template ACE_INLINE CACHING_STRATEGY & +ACE_Cache_Map_Manager::caching_strategy (void) +{ + return this->caching_strategy_; +} + +template ACE_INLINE ACE_Cache_Map_Iterator +ACE_Cache_Map_Manager::begin (void) +{ + return ITERATOR (this->map_.begin ()); +} + +template ACE_INLINE ACE_Cache_Map_Iterator +ACE_Cache_Map_Manager::end (void) +{ + return ITERATOR (this->map_.end ()); +} + +template ACE_INLINE ACE_Cache_Map_Reverse_Iterator +ACE_Cache_Map_Manager::rbegin (void) +{ + return REVERSE_ITERATOR (this->map_.rbegin ()); +} +template ACE_INLINE ACE_Cache_Map_Reverse_Iterator +ACE_Cache_Map_Manager::rend (void) +{ + return REVERSE_ITERATOR (this->map_.rend ()); +} + +//////////////////////////////////////////////////////////////////////////////// + +template ACE_INLINE +ACE_Cache_Map_Iterator::ACE_Cache_Map_Iterator (const ACE_Cache_Map_Iterator &rhs) + : iterator_implementation_ (rhs.iterator_implementation_) +{ +} + +template ACE_INLINE ACE_Cache_Map_Iterator & +ACE_Cache_Map_Iterator::operator= (const ACE_Cache_Map_Iterator &rhs) +{ + this->iterator_implementation_ = rhs.iterator_implementation_; + return *this; +} + +template ACE_INLINE bool +ACE_Cache_Map_Iterator::operator== (const ACE_Cache_Map_Iterator &rhs) const +{ + return this->iterator_implementation_ == rhs.iterator_implementation_; +} + +template ACE_INLINE bool +ACE_Cache_Map_Iterator::operator!= (const ACE_Cache_Map_Iterator &rhs) const +{ + return this->iterator_implementation_ != rhs.iterator_implementation_; +} + +template ACE_INLINE ACE_Reference_Pair +ACE_Cache_Map_Iterator::operator* (void) const +{ + value_type retn ((*this->iterator_implementation_).ext_id_, + (*this->iterator_implementation_).int_id_.first ()); + return retn; +} + +template ACE_INLINE +ACE_Cache_Map_Iterator & +ACE_Cache_Map_Iterator::operator++ (void) +{ + ++this->iterator_implementation_; + return *this; +} + +template ACE_INLINE +ACE_Cache_Map_Iterator +ACE_Cache_Map_Iterator::operator++ (int) +{ + ACE_Cache_Map_Iterator retn = *this; + ++this->iterator_implementation_; + return retn; +} + +template ACE_INLINE +ACE_Cache_Map_Iterator & +ACE_Cache_Map_Iterator::operator-- (void) +{ + --this->iterator_implementation_; + return *this; +} + +template ACE_INLINE +ACE_Cache_Map_Iterator +ACE_Cache_Map_Iterator::operator-- (int) +{ + ACE_Cache_Map_Iterator retn = *this; + --this->iterator_implementation_; + return retn; +} + +template ACE_INLINE void +ACE_Cache_Map_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->iterator_implementation_.dump (); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_INLINE +ACE_Cache_Map_Iterator::ACE_Cache_Map_Iterator (const IMPLEMENTATION &iterator_impl) + : iterator_implementation_ (iterator_impl) +{ +} + +template ACE_INLINE IMPLEMENTATION & +ACE_Cache_Map_Iterator::iterator_implementation (void) +{ + return this->iterator_implementation_; +} + +//////////////////////////////////////////////////////////////////////////////// + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator::ACE_Cache_Map_Reverse_Iterator (const ACE_Cache_Map_Reverse_Iterator &rhs) + : reverse_iterator_implementation_ (rhs.reverse_iterator_implementation_) +{ +} + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator::~ACE_Cache_Map_Reverse_Iterator (void) +{ +} + +template ACE_INLINE ACE_Cache_Map_Reverse_Iterator & +ACE_Cache_Map_Reverse_Iterator::operator= (const ACE_Cache_Map_Reverse_Iterator &rhs) +{ + this->reverse_iterator_implementation_ = rhs.reverse_iterator_implementation_; + return *this; +} + +template ACE_INLINE bool +ACE_Cache_Map_Reverse_Iterator::operator== (const ACE_Cache_Map_Reverse_Iterator &rhs) const +{ + return this->reverse_iterator_implementation_ == rhs.reverse_iterator_implementation_; +} + +template ACE_INLINE bool +ACE_Cache_Map_Reverse_Iterator::operator!= (const ACE_Cache_Map_Reverse_Iterator &rhs) const +{ + return this->reverse_iterator_implementation_ != rhs.reverse_iterator_implementation_; +} + +template ACE_INLINE ACE_Reference_Pair +ACE_Cache_Map_Reverse_Iterator::operator* (void) const +{ + value_type retv ((*this->reverse_iterator_implementation_).ext_id_, + (*this->reverse_iterator_implementation_).int_id_.first ()); + return retv; +} + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator & +ACE_Cache_Map_Reverse_Iterator::operator++ (void) +{ + ++this->reverse_iterator_implementation_; + return *this; +} + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator +ACE_Cache_Map_Reverse_Iterator::operator++ (int) +{ + ACE_Cache_Map_Reverse_Iterator retn = *this; + ++this->reverse_iterator_implementation_; + return retn; +} + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator & +ACE_Cache_Map_Reverse_Iterator::operator-- (void) +{ + --this->reverse_iterator_implementation_; + return *this; +} + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator +ACE_Cache_Map_Reverse_Iterator::operator-- (int) +{ + ACE_Cache_Map_Reverse_Iterator retn = *this; + --this->reverse_iterator_implementation_; + return retn; +} + + +template ACE_INLINE void +ACE_Cache_Map_Reverse_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->reverse_iterator_implementation_.dump (); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_INLINE +ACE_Cache_Map_Reverse_Iterator::ACE_Cache_Map_Reverse_Iterator (const REVERSE_IMPLEMENTATION &iterator_impl) + : reverse_iterator_implementation_(iterator_impl) +{ +} + +template ACE_INLINE REVERSE_IMPLEMENTATION & +ACE_Cache_Map_Reverse_Iterator::iterator_implementation (void) +{ + return this->reverse_iterator_implementation_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Cached_Connect_Strategy_T.cpp b/dep/ACE_wrappers/ace/Cached_Connect_Strategy_T.cpp new file mode 100644 index 000000000..1f9ad0abd --- /dev/null +++ b/dep/ACE_wrappers/ace/Cached_Connect_Strategy_T.cpp @@ -0,0 +1,734 @@ +//$Id: Cached_Connect_Strategy_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CACHED_CONNECT_STRATEGY_T_CPP +#define ACE_CACHED_CONNECT_STRATEGY_T_CPP + +#include "ace/Cached_Connect_Strategy_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/ACE.h" +#include "ace/Service_Repository.h" +#include "ace/Service_Types.h" +#include "ace/Thread_Manager.h" +#include "ace/WFMO_Reactor.h" +#include "ace/Pair_T.h" + +#define ACE_T1 class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX +#define ACE_T2 SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Cached_Connect_Strategy_Ex::ACE_Cached_Connect_Strategy_Ex +(CACHING_STRATEGY &caching_s, + ACE_Creation_Strategy *cre_s, + ACE_Concurrency_Strategy *con_s, + ACE_Recycling_Strategy *rec_s, + MUTEX *lock, + int delete_lock) + : CCSBASE (cre_s, con_s, rec_s, lock, delete_lock), + connection_cache_ (caching_s) +{ + if (this->open (cre_s, con_s, rec_s) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Cached_Connect_Strategy_Ex\n"))); +} + +template +ACE_Cached_Connect_Strategy_Ex::~ACE_Cached_Connect_Strategy_Ex (void) +{ + cleanup (); +} + + +template int +ACE_Cached_Connect_Strategy_Ex::check_hint_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + ACE_Hash_Map_Entry, ACE_Pair > *&entry, + int &found) +{ + ACE_UNUSED_ARG (remote_addr); + ACE_UNUSED_ARG (timeout); + ACE_UNUSED_ARG (local_addr); + ACE_UNUSED_ARG (reuse_addr); + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (perms); + + found = 0; + + // Get the recycling act for the svc_handler + CONNECTION_CACHE_ENTRY *possible_entry = + (CONNECTION_CACHE_ENTRY *) sh->recycling_act (); + + // Check to see if the hint svc_handler has been closed down + if (possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED) + { + // If close, decrement refcount + if (possible_entry->ext_id_.decrement () == 0) + { + // If refcount goes to zero, close down the svc_handler + possible_entry->int_id_.first ()->recycler (0, 0); + possible_entry->int_id_.first ()->close (); + this->purge_i (possible_entry); + } + + // Hint not successful + found = 0; + + // Reset hint + sh = 0; + } + + // If hint is not closed, see if it is connected to the correct + // address and is recyclable + else if ((possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE || + possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE) && + possible_entry->ext_id_.subject () == remote_addr) + { + // Hint successful + found = 1; + + // Tell the that it should prepare itself for + // being recycled. + this->prepare_for_recycling (sh); + + // + // Update the caching attributes directly since we don't do a + // find() on the cache map. + // + + // Indicates successful find. + int find_result = 0; + + int result = this->caching_strategy ().notify_find (find_result, + possible_entry->int_id_.second ()); + + if (result == -1) + return result; + } + else + { + // This hint will not be used. + possible_entry->ext_id_.decrement (); + + // Hint not successful + found = 0; + + // If is not connected to the correct address or is busy, + // we will not use it. + sh = 0; + } + + if (found) + entry = possible_entry; + + return 0; +} + +template int +ACE_Cached_Connect_Strategy_Ex::find_or_create_svc_handler_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + ACE_Hash_Map_Entry, ACE_Pair > *&entry, + int &found) +{ + REFCOUNTED_HASH_RECYCLABLE_ADDRESS search_addr (remote_addr); + + // Try to find the address in the cache. Only if we don't find it + // do we create a new and connect it with the server. + while (this->find (search_addr, entry) != -1) + { + // We found a cached svc_handler. + // Get the cached + sh = entry->int_id_.first (); + + // Is the connection clean? + int state_result = + ACE::handle_ready (sh->peer ().get_handle (), + &ACE_Time_Value::zero, + 1, // read ready + 0, // write ready + 1);// exception ready + + if (state_result == 1) + { + + if (sh->close () == -1) + return -1; + + sh = 0; + + // Cycle it once again.. + } + else if ((state_result == -1) && (errno == ETIME)) + { + // Found!!! + // Set the flag + found = 1; + + // Tell the that it should prepare itself for + // being recycled. + if (this->prepare_for_recycling (sh) == -1) + return -1; + + return 0; + } + else + { + return -1; + } + } + + // Not found... + + // Set the flag + found = 0; + + // We need to use a temporary variable here since we are not + // allowed to change because other threads may use this + // when we let go of the lock during the OS level connect. + // + // Note that making a new svc_handler, connecting remotely, + // binding to the map, and assigning of the hint and recycler + // should be atomic to the outside world. + SVC_HANDLER *potential_handler = 0; + + // Create a new svc_handler + if (this->make_svc_handler (potential_handler) == -1) + return -1; + + // Connect using the svc_handler. + if (this->cached_connect (potential_handler, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms) == -1) + { + // Close the svc handler. + potential_handler->close (0); + + return -1; + } + else + { + // Insert the new SVC_HANDLER instance into the cache. + if (this->connection_cache_.bind (search_addr, + potential_handler, + entry) == -1) + { + // Close the svc handler and reset . + potential_handler->close (0); + + return -1; + } + + // Everything succeeded as planned. Assign to + // . + sh = potential_handler; + + // Set the recycler and the recycling act + + this->assign_recycler (sh, this, entry); + } + + return 0; +} + +template int +ACE_Cached_Connect_Strategy_Ex::cached_connect (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + // Actively establish the connection. This is a timed blocking + // connect. + if (this->new_connection (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms) == -1) + { + // If connect() failed because of timeouts, we have to reject + // the connection entirely. This is necessary since currently + // there is no way for the non-blocking connects to complete and + // for the to notify the cache of the completion of + // connect(). + + if (errno == EWOULDBLOCK || errno == ETIMEDOUT) + errno = ENOTSUP; + else if (ACE::out_of_handles (errno) || errno == EADDRINUSE) + { + // If the connect failed due to the process running out of + // file descriptors then, auto_purging of some connections + // are done from the CONNECTION_CACHE. This frees the + // descriptors which get used in the connect process and + // hence the same method is called again! + if (this->purge_connections () == -1) + return -1; + + // Try connecting again. + if (this->new_connection (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms) == -1) + { + if (errno == EWOULDBLOCK || errno == ETIMEDOUT) + errno = ENOTSUP; + return -1; + } + } + else + { + return -1; + } + } + + return 0; + +} + + +template int +ACE_Cached_Connect_Strategy_Ex::connect_svc_handler_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + int& found) +{ + CONNECTION_CACHE_ENTRY *entry = 0; + + // Check if the user passed a hint svc_handler + if (sh != 0) + { + int result = this->check_hint_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + entry, + found); + if (result != 0) + return result; + } + + // If not found + if (!found) + { + int result = this->find_or_create_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + entry, + found); + + if (result != 0) + return result; + + // Increment the refcount + entry->ext_id_.increment (); + } + + // For all successful cases: mark the in the cache + // as being . Therefore recyclable is BUSY. + entry->ext_id_.recycle_state (ACE_RECYCLABLE_BUSY); + + return 0; +} + + +template int +ACE_Cached_Connect_Strategy_Ex::cache_i (const void *recycling_act) +{ + // The wonders and perils of ACT + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act; + + // Mark the in the cache as not being . + // Therefore recyclable is IDLE. + entry->ext_id_.recycle_state (ACE_RECYCLABLE_IDLE_AND_PURGABLE); + + return 0; +} + +template int +ACE_Cached_Connect_Strategy_Ex::recycle_state_i (const void *recycling_act, + ACE_Recyclable_State new_state) +{ + // The wonders and perils of ACT + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act; + + // Mark the in the cache as not being . + // Therefore recyclable is IDLE. + entry->ext_id_.recycle_state (new_state); + + return 0; +} + +template ACE_Recyclable_State +ACE_Cached_Connect_Strategy_Ex::recycle_state_i (const void *recycling_act) const +{ + // The wonders and perils of ACT + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act; + + // Mark the in the cache as not being . + // Therefore recyclable is IDLE. + return entry->ext_id_.recycle_state (); +} + +template int +ACE_Cached_Connect_Strategy_Ex::purge_i (const void *recycling_act) +{ + // The wonders and perils of ACT + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act; + + return this->connection_cache_.unbind (entry); +} + + +template int +ACE_Cached_Connect_Strategy_Ex::mark_as_closed_i (const void *recycling_act) +{ + // The wonders and perils of ACT + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act; + + // Mark the in the cache as CLOSED. + entry->ext_id_.recycle_state (ACE_RECYCLABLE_CLOSED); + + return 0; +} + +template int +ACE_Cached_Connect_Strategy_Ex::cleanup_hint_i (const void *recycling_act, + void **act_holder) +{ + // Reset the <*act_holder> in the confines and protection of the + // lock. + if (act_holder) + *act_holder = 0; + + // The wonders and perils of ACT + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act; + + // Decrement the refcount on the . + int refcount = entry->ext_id_.decrement (); + + // If the svc_handler state is closed and the refcount == 0, call + // close() on svc_handler. + if (entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED && + refcount == 0) + { + entry->int_id_.first ()->recycler (0, 0); + entry->int_id_.first ()->close (); + this->purge_i (entry); + } + + return 0; +} + +template int +ACE_Cached_Connect_Strategy_Ex::purge_connections (void) +{ + return this->connection_cache_.purge (); +} + +template CACHING_STRATEGY & +ACE_Cached_Connect_Strategy_Ex::caching_strategy (void) +{ + return this->connection_cache_.caching_strategy (); +} + +template int +ACE_Cached_Connect_Strategy_Ex::find (ACE_Refcounted_Hash_Recyclable &search_addr, + ACE_Hash_Map_Entry, ACE_Pair > *&entry) +{ + typedef ACE_Hash_Map_Bucket_Iterator, + ACE_Hash, + ACE_Equal_To, + ACE_Null_Mutex> + CONNECTION_CACHE_BUCKET_ITERATOR; + + CONNECTION_CACHE_BUCKET_ITERATOR iterator (this->connection_cache_.map (), + search_addr); + + CONNECTION_CACHE_BUCKET_ITERATOR end (this->connection_cache_.map (), + search_addr, + 1); + + for (; + iterator != end; + ++iterator) + { + REFCOUNTED_HASH_RECYCLABLE_ADDRESS &addr = (*iterator).ext_id_; + + if (addr.recycle_state () != ACE_RECYCLABLE_IDLE_AND_PURGABLE && + addr.recycle_state () != ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE) + continue; + + if (addr.subject () != search_addr.subject ()) + continue; + + entry = &(*iterator); + + // + // Update the caching attributes directly since we don't do a + // find() on the cache map. + // + + // Indicates successful find. + int find_result = 0; + + int result = this->caching_strategy ().notify_find (find_result, + entry->int_id_.second ()); + + if (result == -1) + return result; + + return 0; + } + + return -1; +} + +template void +ACE_Cached_Connect_Strategy_Ex::cleanup (void) +{ + // Excluded other threads from changing the cache while we cleanup + ACE_GUARD (MUTEX, ace_mon, *this->lock_); + + // Close down all cached service handlers. + typename CONNECTION_CACHE::ITERATOR iter = this->connection_cache_.begin (); + while (iter != this->connection_cache_.end ()) + { + if ((*iter).second () != 0) + { + // save entry for future use + CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) + (*iter).second ()->recycling_act (); + + // close handler + (*iter).second ()->recycler (0, 0); + (*iter).second ()->close (); + + // remember next iter + typename CONNECTION_CACHE::ITERATOR next_iter = iter; + ++next_iter; + + // purge the item from the hash + this->purge_i (entry); + + // assign next iter + iter = next_iter; + } + else + ++iter; + } +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Cached_Connect_Strategy_Ex) +///////////////////////////////////////////////////////////////////////// + +template +ACE_Bounded_Cached_Connect_Strategy::ACE_Bounded_Cached_Connect_Strategy +(size_t max_size, + CACHING_STRATEGY &caching_s, + ACE_Creation_Strategy *cre_s, + ACE_Concurrency_Strategy *con_s, + ACE_Recycling_Strategy *rec_s, + MUTEX *lock, + int delete_lock) + : CCSEBASE (caching_s, cre_s, con_s, rec_s, lock, delete_lock), + max_size_ (max_size) +{ +} + +template +ACE_Bounded_Cached_Connect_Strategy::~ACE_Bounded_Cached_Connect_Strategy(void) +{ +} + +template +int +ACE_Bounded_Cached_Connect_Strategy::find_or_create_svc_handler_i +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + ACE_Hash_Map_Entry, + ACE_Pair > *&entry, + int &found) +{ + + REFCOUNTED_HASH_RECYCLABLE_ADDRESS search_addr (remote_addr); + + // Try to find the address in the cache. Only if we don't find it + // do we create a new and connect it with the server. + while (this->find (search_addr, entry) != -1) + { + // We found a cached svc_handler. + // Get the cached + sh = entry->int_id_.first (); + + // Is the connection clean? + int state_result= ACE::handle_ready (sh->peer ().get_handle (), + &ACE_Time_Value::zero, + 1, // read ready + 0, // write ready + 1);// exception ready + + if (state_result == 1) + { + // The connection was disconnected during idle. + // close the svc_handler down. + if (sh->close () == -1) + { + ACE_ASSERT (0); + return -1; + } + sh = 0; + // and rotate once more... + } + else if ((state_result == -1) && (errno == ETIME)) + { + // Found!!! + // Set the flag + found = 1; + + // Tell the that it should prepare itself for + // being recycled. + if (this->prepare_for_recycling (sh) == -1) + { + ACE_ASSERT (0); + return -1; + } + + return 0; + } + else // some other return value or error... + { + ACE_ASSERT (0); // just to see it coming + + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%t)ACE_Bounded_Cached_Connect_Strategy<>::") + ACE_TEXT ("find_or_create_svc_handler_i - ") + ACE_TEXT ("error polling server socket state.\n"))); + + return -1; + } + } + + // Not found... + + // Set the flag + found = 0; + + // Check the limit of handlers... + if ((this->max_size_ > 0) && + (this->connection_cache_.current_size () >= this->max_size_)) + { + // Try to purge idle connections + if (this->purge_connections () == -1) + return -1; + + // Check limit again. + if (this->connection_cache_.current_size () >= this->max_size_) + // still too much! + return -1; + + // OK, we have room now... + } + + // We need to use a temporary variable here since we are not + // allowed to change because other threads may use this + // when we let go of the lock during the OS level connect. + // + // Note that making a new svc_handler, connecting remotely, + // binding to the map, and assigning of the hint and recycler + // should be atomic to the outside world. + SVC_HANDLER *potential_handler = 0; + + // Create a new svc_handler + if (this->make_svc_handler (potential_handler) == -1) + return -1; + + // Connect using the svc_handler. + if (this->cached_connect (potential_handler, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms) == -1) + { + // Close the svc handler. + potential_handler->close (0); + return -1; + } + else + { + // Insert the new SVC_HANDLER instance into the cache. + if (this->connection_cache_.bind (search_addr, + potential_handler, + entry) == -1) + { + // Close the svc handler and reset . + potential_handler->close (0); + + return -1; + } + + // Everything succeeded as planned. Assign to + // . + sh = potential_handler; + + // Set the recycler and the recycling act + this->assign_recycler (sh, this, entry); + } + + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Cached_Connect_Strategy) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#undef ACE_T1 +#undef ACE_T2 + +#endif /* ACE_CACHED_CONNECT_STRATEGY_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Cached_Connect_Strategy_T.h b/dep/ACE_wrappers/ace/Cached_Connect_Strategy_T.h new file mode 100644 index 000000000..15517ddc3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Cached_Connect_Strategy_T.h @@ -0,0 +1,262 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Cached_Connect_Strategy_T.h + * + * $Id: Cached_Connect_Strategy_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kirthika Parameswaran + */ +//============================================================================= + +#ifndef CACHED_CONNECT_STRATEGY_T_H +#define CACHED_CONNECT_STRATEGY_T_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Strategies_T.h" +#include "ace/Hash_Cache_Map_Manager_T.h" +#include "ace/Caching_Strategies_T.h" +#include "ace/Functor_T.h" +#include "ace/Pair_T.h" + +// For linkers which cant grok long names... +#define ACE_Cached_Connect_Strategy_Ex ACCSE + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Cached_Connect_Strategy_Ex + * + * @brief A connection strategy which caches connections to peers + * (represented by SVC_HANDLER instances), thereby allowing + * subsequent re-use of unused, but available, connections. + * + * is intended to be used as a + * plug-in connection strategy for ACE_Strategy_Connector. + * It's added value is re-use of established connections and + * tweaking the role of the cache as per the caching strategy. + */ +template +class ACE_Cached_Connect_Strategy_Ex + : public ACE_Cached_Connect_Strategy +{ +public: + /// Constructor + ACE_Cached_Connect_Strategy_Ex ( + CACHING_STRATEGY &caching_s, + ACE_Creation_Strategy *cre_s = 0, + ACE_Concurrency_Strategy *con_s = 0, + ACE_Recycling_Strategy *rec_s = 0, + MUTEX *lock = 0, + int delete_lock = 0); + + /// Destructor + virtual ~ACE_Cached_Connect_Strategy_Ex (void); + + /// Explicit purging of connection entries from the connection cache. + virtual int purge_connections (void); + + /// Mark as closed (non-locking version). This is used during the cleanup of the + /// connections purged. + virtual int mark_as_closed_i (const void *recycling_act); + + /** + * Since g++ version < 2.8 arent happy with templates, this special + * method had to be devised to avoid memory leaks and perform + * cleanup of the . + */ + void cleanup (void); + + // = Typedefs for managing the map + typedef ACE_Refcounted_Hash_Recyclable + REFCOUNTED_HASH_RECYCLABLE_ADDRESS; + typedef ACE_Hash_Cache_Map_Manager, + ACE_Equal_To, + CACHING_STRATEGY, + ATTRIBUTES> + CONNECTION_CACHE; + typedef typename CONNECTION_CACHE::CACHE_ENTRY CONNECTION_CACHE_ENTRY; + typedef typename CONNECTION_CACHE::key_type KEY; + typedef typename CONNECTION_CACHE::mapped_type VALUE; + + typedef ACE_Recyclable_Handler_Cleanup_Strategy, + ACE_Hash_Map_Manager_Ex, + ACE_Hash, + ACE_Equal_To, + MUTEX> > + CLEANUP_STRATEGY; + + typedef ACE_Cached_Connect_Strategy + CCSBASE; + + // = Accessor. + CACHING_STRATEGY &caching_strategy (void); + +protected: + + /// Find an idle handle. + int find (ACE_Refcounted_Hash_Recyclable &search_addr, + ACE_Hash_Map_Entry, ACE_Pair > *&entry); + + /// Remove from cache (non-locking version). + virtual int purge_i (const void *recycling_act); + + /// Add to cache (non-locking version). + virtual int cache_i (const void *recycling_act); + + /// Get/Set (non-locking version). + virtual int recycle_state_i (const void *recycling_act, + ACE_Recyclable_State new_state); + virtual ACE_Recyclable_State recycle_state_i (const void *recycling_act) const; + + /// Cleanup hint and reset <*act_holder> to zero if . + virtual int cleanup_hint_i (const void *recycling_act, + void **act_holder); + + // = Helpers + int check_hint_i (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + ACE_Hash_Map_Entry, ACE_Pair > *&entry, + int &found); + + virtual int find_or_create_svc_handler_i (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + ACE_Hash_Map_Entry, ACE_Pair > *&entry, + int &found); + + virtual int connect_svc_handler_i (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + int &found); + + /** + * Connection of the svc_handler with the remote host. This method + * also encapsulates the connection done with auto_purging under the + * hood. If the connect failed due to the process running out of + * file descriptors then, auto_purging of some connections are done + * from the CONNECTION_CACHE. This frees the descriptors which get + * used in the connect process and hence the connect operation can + * succeed. + */ + virtual int cached_connect (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + + /// Table that maintains the cache of connected SVC_HANDLERs. + CONNECTION_CACHE connection_cache_; +}; + +///////////////////////////////////////////////////////////////////////////// + +// For linkers which cant grok long names... +#define ACE_Bounded_Cached_Connect_Strategy ABCCS + +/** + * @class ACE_Bounded_Cached_Connect_Strategy + * + * @brief A connection strategy which caches connections to peers + * (represented by SVC_HANDLER instances), thereby allowing + * subsequent re-use of unused, but available, connections. + * This strategy should be used when the cache is bounded by + * maximum size. + * + * is intended to be used as a + * plug-in connection strategy for ACE_Strategy_Connector. + * It's added value is re-use of established connections and + * tweaking the role of the cache as per the caching strategy. + * Thanks to Edan Ayal for contributing this + * class and Susan Liebeskind for + * brainstorming about it. + */ +template +class ACE_Bounded_Cached_Connect_Strategy + : public ACE_Cached_Connect_Strategy_Ex +{ + + typedef ACE_Cached_Connect_Strategy_Ex + CCSEBASE; + + // = Typedefs for managing the map + typedef ACE_Refcounted_Hash_Recyclable + REFCOUNTED_HASH_RECYCLABLE_ADDRESS; + +public: + + /// Constructor + ACE_Bounded_Cached_Connect_Strategy (size_t max_size, + CACHING_STRATEGY &caching_s, + ACE_Creation_Strategy *cre_s = 0, + ACE_Concurrency_Strategy *con_s = 0, + ACE_Recycling_Strategy *rec_s = 0, + MUTEX *lock = 0, + int delete_lock = 0); + + /// Destructor + virtual ~ACE_Bounded_Cached_Connect_Strategy (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + + virtual int find_or_create_svc_handler_i (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + ACE_Hash_Map_Entry, + ACE_Pair > *&entry, + int &found); + +protected: + + /// max items in the cache, used as a bound for the creation of svc_handlers. + size_t max_size_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Cached_Connect_Strategy_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Cached_Connect_Strategy_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* CACHED_CONNECT_STRATEGY_T_H */ diff --git a/dep/ACE_wrappers/ace/Caching_Strategies_T.cpp b/dep/ACE_wrappers/ace/Caching_Strategies_T.cpp new file mode 100644 index 000000000..2b0fd4e76 --- /dev/null +++ b/dep/ACE_wrappers/ace/Caching_Strategies_T.cpp @@ -0,0 +1,59 @@ +//$Id: Caching_Strategies_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CACHING_STRATEGIES_T_CPP +#define ACECACHING_STRATEGIES_T_CPP + +#include "ace/Caching_Strategies_T.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Caching_Strategies_T.inl" +#endif /* __ACE_INLINE__ */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Caching_Strategy::~ACE_Caching_Strategy (void) +{ +} + +////////////////////////////////////////////////////////////////////////////////// + +template +ACE_LRU_Caching_Strategy::ACE_LRU_Caching_Strategy (void) + : timer_ (0), + purge_percent_ (10) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////// + +template +ACE_LFU_Caching_Strategy::ACE_LFU_Caching_Strategy (void) + : purge_percent_ (10) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////// + +template +ACE_FIFO_Caching_Strategy::ACE_FIFO_Caching_Strategy (void) + : order_ (0), + purge_percent_ (10) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////// + +ACE_ALLOC_HOOK_DEFINE(ACE_LRU_Caching_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_LFU_Caching_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Caching_Strategy) +ACE_ALLOC_HOOK_DEFINE(ACE_Null_Caching_Strategy) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_CACHING_STRATEGIES_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Caching_Strategies_T.h b/dep/ACE_wrappers/ace/Caching_Strategies_T.h new file mode 100644 index 000000000..e4b0817aa --- /dev/null +++ b/dep/ACE_wrappers/ace/Caching_Strategies_T.h @@ -0,0 +1,552 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Caching_Strategies_T.h + * + * $Id: Caching_Strategies_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kirthika Parameswaran + */ +//============================================================================= + +#ifndef ACE_CACHING_STRATEGIES_H +#define ACE_CACHING_STRATEGIES_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Caching_Utility_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined(_MSC_VER) +#pragma warning(disable:4503) +#endif /* _MSC_VER */ + +// For linkers that cant grok long names. +#define ACE_Caching_Strategy ACS + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Caching_Strategy + * + * @brief This class is an abstract base class for a caching strategy. + * + * This class consists of all the interfaces a caching strategy should + * have and is used in association with the + * ACE_Caching_Strategy_Adaptor. + */ +template +class ACE_Caching_Strategy +{ +public: + /// Destructor. + virtual ~ACE_Caching_Strategy (void); + + /// Accessor method for the timer attributes. + virtual ATTRIBUTES attributes (void) = 0; + + /// Get the percentage of entries to purge. + virtual double purge_percent (void) = 0; + + /// Set the percentage of entries to purge. + virtual void purge_percent (double percentage) = 0; + + // = Strategy related Operations + + /// This method acts as a notification about the CONTAINERs bind + /// method call. + virtual int notify_bind (int result, + const ATTRIBUTES &attr) = 0; + + /// This method acts as a notification about the CONTAINERs find + /// method call + virtual int notify_find (int result, + ATTRIBUTES &attr) = 0; + + /// This method acts as a notification about the CONTAINERs unbind + /// method call + virtual int notify_unbind (int result, + const ATTRIBUTES &attr) = 0; + + /// This method acts as a notification about the CONTAINERs trybind + /// method call + virtual int notify_trybind (int result, + ATTRIBUTES &attr) = 0; + + /// This method acts as a notification about the CONTAINERs rebind + /// method call + virtual int notify_rebind (int result, + const ATTRIBUTES &attr) = 0; + + /// Purge the cache. + virtual CACHING_UTILITY &caching_utility (void) = 0; + + /// Dumps the state of the object. + virtual void dump (void) const = 0; +}; + +////////////////////////////////////////////////////////////////////////// + +#define ACE_Caching_Strategy_Adapter ACSA + +/** + * @class ACE_Caching_Strategy_Adapter + * + * @brief This class follows the Adaptor pattern and is used to provide + * External Polymorphism by deriving from ACE_Caching_Strategy. + * + * This class simply delegates all requests to the + * IMPLEMNETATION object within. This class should be passed in + * place of the the abstract base ACE_Caching_Strategy class as + * part of the External Polymorphism pattern. + */ +template +class ACE_Caching_Strategy_Adapter + : public ACE_Caching_Strategy +{ + +public: + + /// Constructor. + ACE_Caching_Strategy_Adapter (IMPLEMENTATION *implementation = 0, + bool delete_implementation = false); + + /// Destructor. + ~ACE_Caching_Strategy_Adapter (void); + + /// Accessor method for the timer attributes. + ATTRIBUTES attributes (void); + + /// Get the percentage of entries to purge. + double purge_percent (void); + + /// Set the percentage of entries to purge. + void purge_percent (double percentage); + + // = Strategy related Operations + + /// This method acts as a notification about the CONTAINERs bind + /// method call. + int notify_bind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs find + /// method call + int notify_find (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs unbind + /// method call + int notify_unbind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs trybind + /// method call + int notify_trybind (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs rebind + /// method call + int notify_rebind (int result, + const ATTRIBUTES &attr); + + /// Accessor to the implementation. + IMPLEMENTATION &implementation (void); + + /// Purge the cache. + CACHING_UTILITY &caching_utility (void); + + /// Dumps the state of the object. + void dump (void) const; + +private: + + /// Implementation class. + IMPLEMENTATION *implementation_; + + /// Do we need to delete the implementation? + bool delete_implementation_; +}; + +////////////////////////////////////////////////////////////////////////// +#define ACE_LRU_Caching_Strategy ALRU + +/** + * @class ACE_LRU_Caching_Strategy + * + * @brief Defines a Least Recently Used strategy which will decide on + * the item to be removed from the cache. + * + * This is a strategy which makes use of a virtual timer which + * is updated whenever an item is inserted or looked up in the + * container. When the need of purging entries arises, the items + * with the lowest timer values are removed. + * Explanation of the template parameter list: + * CONTAINER is any map with entries of type . + * The ATTRIBUTES are the deciding factor for purging of entries + * and should logically be included with the VALUE. Some ways of + * doing this are: As being a member of the VALUE or VALUE being + * ACE_Pair. The CACHING_UTILITY is the + * class which can be plugged in and which decides the entries + * to purge. + */ +template +class ACE_LRU_Caching_Strategy +{ +public: + + // Traits. + typedef ATTRIBUTES CACHING_ATTRIBUTES; + + // = Initialisation and termination. + + /** + * The is the map in which the entries reside. The + * timer attribute is initialed to zero in this constructor. And + * the field denotes the percentage of the entries + * in the cache which can be purged automagically and by default is + * set to 10%. + */ + ACE_LRU_Caching_Strategy (void); + + // = Operations of the strategy. + + /// Accessor method for the timer attributes. + ATTRIBUTES attributes (void); + + /// Get the percentage of entries to purge. + double purge_percent (void); + + /// Set the percentage of entries to purge. + void purge_percent (double percentage); + + // = Strategy related Operations + + /// This method acts as a notification about the CONTAINERs bind + /// method call. + int notify_bind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs find + /// method call + int notify_find (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs unbind + /// method call + int notify_unbind (int result, + const ATTRIBUTES &attr); + + + /// This method acts as a notification about the CONTAINERs trybind + /// method call + int notify_trybind (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs rebind + /// method call + int notify_rebind (int result, + const ATTRIBUTES &attr); + + /// Purge the cache. + CACHING_UTILITY &caching_utility (void); + + /// Dumps the state of the object. + void dump (void) const; + +private: + + /// This element is the one which is the deciding factor for purging + /// of an ITEM. + ATTRIBUTES timer_; + + /// The level about which the purging will happen automagically. + double purge_percent_; + + /// This is the helper class which will decide and expunge entries + /// from the cache. + CACHING_UTILITY caching_utility_; +}; + +////////////////////////////////////////////////////////////////////////// +#define ACE_LFU_Caching_Strategy ALFU + +/** + * @class ACE_LFU_Caching_Strategy + * + * @brief Defines a Least Frequently Used strategy for which will decide on + * the item to be removed from the cache. + * + * A attribute is tagged to each item which increments whenever + * the item is bound or looked up in the cache. Thus it denotes + * the frequency of use. According to the value of the attribute + * the item is removed from the CONTAINER i.e cache. + * Explanation of the template parameter list: + * CONTAINER is any map with entries of type . + * The ATTRIBUTES are the deciding factor for purging of entries + * and should logically be included with the VALUE. Some ways of + * doing this are: As being a member of the VALUE or VALUE being + * ACE_Pair. The CACHING_UTILITY is the + * class which can be plugged in and which decides the entries + * to purge. + */ +template +class ACE_LFU_Caching_Strategy +{ + +public: + + // Traits. + typedef ATTRIBUTES CACHING_ATTRIBUTES; + + // = Initialisation and termination methods. + + /** + * The is the map in which the entries reside. The + * timer attribute is initialed to zero in this constructor. And + * the field denotes the percentage of the entries + * in the cache which can be purged automagically and by default is + * set to 10%. + */ + ACE_LFU_Caching_Strategy (void); + + // = Strategy methods. + + /// Access the attributes. + ATTRIBUTES attributes (void); + + /// Get the percentage of entries to purge. + double purge_percent (void); + + /// Set the percentage of entries to purge. + void purge_percent (double percentage); + + // = Strategy related Operations + + /// This method acts as a notification about the CONTAINERs bind + /// method call. + int notify_bind (int result, + const ATTRIBUTES &attr); + + /// Lookup notification. + int notify_find (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs unbind + /// method call + int notify_unbind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs trybind + /// method call + int notify_trybind (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs rebind + /// method call + int notify_rebind (int result, + const ATTRIBUTES &attr); + + /// Purge the cache. + CACHING_UTILITY &caching_utility (void); + + /// Dumps the state of the object. + void dump (void) const; + +private: + + /// The level about which the purging will happen automagically. + double purge_percent_; + + /// This is the helper class which will decide and expunge entries + /// from the cache. + CACHING_UTILITY caching_utility_; +}; + +///////////////////////////////////////////////////////////// +#define ACE_FIFO_Caching_Strategy AFIFO + +/** + * @class ACE_FIFO_Caching_Strategy + * + * @brief The First In First Out strategy is implemented wherein each + * item is ordered. + * + * The order tag of each item is used to decide the item to be + * removed from the cache. The items with least order are removed. + * Explanation of the template parameter list: + * CONTAINER is any map with entries of type . + * The ATTRIBUTES are the deciding factor for purging of entries + * and should logically be included with the VALUE. Some ways of + * doing this are: As being a member of the VALUE or VALUE being + * ACE_Pair. The CACHING_UTILITY is the + * class which can be plugged in and which decides the entries + * to purge. + */ +template +class ACE_FIFO_Caching_Strategy +{ + +public: + + typedef ATTRIBUTES CACHING_ATTRIBUTES; + + // = Initialisation and termination. + + /** + * The is the map in which the entries reside. The + * timer attribute is initialed to zero in this constructor. And + * the field denotes the percentage of the entries + * in the cache which can be purged automagically and by default is + * set to 10%. + */ + ACE_FIFO_Caching_Strategy (void); + + // = Strategy methods. + + /// Accessor method. + ATTRIBUTES attributes (void); + + /// Get the percentage of entries to purge. + double purge_percent (void); + + /// Set the percentage of entries to purge. + void purge_percent (double percentage); + + // = Strategy related Operations + + /// Notification for an item getting bound into the cache. + int notify_bind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs find + /// method call + int notify_find (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs unbind + /// method call + int notify_unbind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs trybind + /// method call + int notify_trybind (int result, + ATTRIBUTES &attr); + + /// Notification for an item getting bound again into the cache. + int notify_rebind (int result, + const ATTRIBUTES &attr); + + /// Purge the cache. + CACHING_UTILITY &caching_utility (void); + + /// Dumps the state of the object. + void dump (void) const; + +private: + + /// The order is the deciding factor for the item to be removed from + /// the cache. + ATTRIBUTES order_; + + /// The level about which the purging will happen automagically. + double purge_percent_; + + /// This is the helper class which will decide and expunge entries + /// from the cache. + CACHING_UTILITY caching_utility_; +}; + +////////////////////////////////////////////////////////////////////// +#define ACE_Null_Caching_Strategy ANULL + +/** + * @class ACE_Null_Caching_Strategy + * + * @brief The is a special caching strategy which doesnt have the purging + * feature. + * + * No purging provided. To be used when purging might be too expensive + * an operation. + */ +template +class ACE_Null_Caching_Strategy +{ + +public: + + // = Traits. + typedef ATTRIBUTES CACHING_ATTRIBUTES; + + // = Strategy methods. All are NO_OP methods!!! + + /// Accessor method. + ATTRIBUTES attributes (void); + + /// Get the percentage of entries to purge. + double purge_percent (void); + + /// Set the percentage of entries to purge. + void purge_percent (double percentage); + + // = Strategy related Operations + + /// Notification for an item getting bound into the cache. + int notify_bind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs find + /// method call + int notify_find (int result, + ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs unbind + /// method call + int notify_unbind (int result, + const ATTRIBUTES &attr); + + /// This method acts as a notification about the CONTAINERs trybind + /// method call + int notify_trybind (int result, + ATTRIBUTES &attr); + + /// Notification for an item getting bound again into the cache. + int notify_rebind (int result, + const ATTRIBUTES &attr); + + /// Purge the cache. + CACHING_UTILITY &caching_utility (void); + + /// Dumps the state of the object. + void dump (void) const; + +private: + + /// This is the helper class which will decide and expunge entries + /// from the cache. + CACHING_UTILITY caching_utility_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Caching_Strategies_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Caching_Strategies_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Caching_Strategies_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CACHING_STRATEGIES_H */ diff --git a/dep/ACE_wrappers/ace/Caching_Strategies_T.inl b/dep/ACE_wrappers/ace/Caching_Strategies_T.inl new file mode 100644 index 000000000..41fa2d303 --- /dev/null +++ b/dep/ACE_wrappers/ace/Caching_Strategies_T.inl @@ -0,0 +1,456 @@ +// -*-C++-*- +// +//$Id: Caching_Strategies_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +////////////////////////////////////////////////////////////////////////////////// + +#include "ace/OS_Memory.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_Caching_Strategy_Adapter::ACE_Caching_Strategy_Adapter (IMPLEMENTATION *implementation, + bool delete_implementation) + : implementation_ (implementation), + delete_implementation_ (delete_implementation) +{ + if (this->implementation_ == 0) + { + ACE_NEW (this->implementation_, + IMPLEMENTATION); + this->delete_implementation_ = true; + } +} + +template ACE_INLINE +ACE_Caching_Strategy_Adapter::~ACE_Caching_Strategy_Adapter (void) +{ + if (this->delete_implementation_) + { + delete this->implementation_; + this->delete_implementation_ = false; + this->implementation_ = 0; + } +} + +template ACE_INLINE ATTRIBUTES +ACE_Caching_Strategy_Adapter::attributes (void) +{ + return this->implementation_->attributes (); +} + +template ACE_INLINE double +ACE_Caching_Strategy_Adapter::purge_percent (void) +{ + return this->implementation_->purge_percent (); +} + +template ACE_INLINE void +ACE_Caching_Strategy_Adapter::purge_percent (double percentage) +{ + this->implementation_->purge_percent (percentage); +} + +template ACE_INLINE int +ACE_Caching_Strategy_Adapter::notify_bind (int result, + const ATTRIBUTES &attr) +{ + return this->implementation_->notify_bind (result, + attr); +} + +template ACE_INLINE int +ACE_Caching_Strategy_Adapter::notify_find (int result, + ATTRIBUTES &attr) +{ + return this->implementation_->notify_find (result, + attr); +} + +template ACE_INLINE int +ACE_Caching_Strategy_Adapter::notify_unbind (int result, + const ATTRIBUTES &attr) +{ + return this->implementation_->notify_unbind (result, + attr); +} + +template ACE_INLINE int +ACE_Caching_Strategy_Adapter::notify_trybind (int result, + ATTRIBUTES &attr) +{ + return this->implementation_->notify_trybind (result, + attr); +} + +template ACE_INLINE int +ACE_Caching_Strategy_Adapter::notify_rebind (int result, + const ATTRIBUTES &attr) +{ + return this->implementation_->notify_rebind (result, + attr); +} + +template ACE_INLINE IMPLEMENTATION & +ACE_Caching_Strategy_Adapter::implementation (void) +{ + return *this->implementation_; +} + +template ACE_INLINE CACHING_UTILITY & +ACE_Caching_Strategy_Adapter::caching_utility (void) +{ + return this->implementation_->caching_utility (); +} + +template ACE_INLINE void +ACE_Caching_Strategy_Adapter::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Caching_Strategy_Adapter::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +////////////////////////////////////////////////////////////////////////////////// + +template ACE_INLINE ATTRIBUTES +ACE_LRU_Caching_Strategy::attributes (void) +{ + return this->timer_; +} + +template ACE_INLINE double +ACE_LRU_Caching_Strategy::purge_percent (void) +{ + return this->purge_percent_; +} + +template ACE_INLINE void +ACE_LRU_Caching_Strategy::purge_percent (double percentage) +{ + this->purge_percent_ = percentage; +} + +template ACE_INLINE int +ACE_LRU_Caching_Strategy::notify_bind ( + int result, + const ATTRIBUTES & /* attr */) +{ + if (result == 0) + ++this->timer_; + + return result; +} + +template ACE_INLINE int +ACE_LRU_Caching_Strategy::notify_find ( + int result, + ATTRIBUTES &attr) +{ + if (result == 0) + { + attr = this->timer_; + ++this->timer_; + } + + return result; +} + +template ACE_INLINE int +ACE_LRU_Caching_Strategy::notify_unbind ( + int result, + const ATTRIBUTES & /* attr */) +{ + return result; +} + +template ACE_INLINE int +ACE_LRU_Caching_Strategy::notify_trybind ( + int result, + ATTRIBUTES & /* attr */) +{ + return result; +} + +template ACE_INLINE int +ACE_LRU_Caching_Strategy::notify_rebind ( + int result, + const ATTRIBUTES & /* attr */) +{ + if (result == 0) + ++this->timer_; + + return result; +} + +template ACE_INLINE CACHING_UTILITY & +ACE_LRU_Caching_Strategy::caching_utility (void) +{ + return this->caching_utility_; +} + +template ACE_INLINE void +ACE_LRU_Caching_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_LRU_Caching_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("timer_ = %d "), this->timer_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +////////////////////////////////////////////////////////////////////////////////// + +template ACE_INLINE ATTRIBUTES +ACE_LFU_Caching_Strategy::attributes (void) +{ + return 0; +} + +template ACE_INLINE double +ACE_LFU_Caching_Strategy::purge_percent (void) +{ + return this->purge_percent_; +} + +template ACE_INLINE void +ACE_LFU_Caching_Strategy::purge_percent (double percentage) +{ + this->purge_percent_ = percentage; +} + +template ACE_INLINE int +ACE_LFU_Caching_Strategy::notify_bind (int result, + const ATTRIBUTES & /* attr */) +{ + + return result; +} + +template ACE_INLINE int +ACE_LFU_Caching_Strategy::notify_find (int result, + ATTRIBUTES &attr) +{ + if (result == 0) + ++attr; + + return result; +} + +template ACE_INLINE int +ACE_LFU_Caching_Strategy::notify_trybind (int result, + ATTRIBUTES & /* attr */) +{ + return result; +} + +template ACE_INLINE int +ACE_LFU_Caching_Strategy::notify_rebind (int result, + const ATTRIBUTES & /* attr */) +{ + return result; +} + +template ACE_INLINE int +ACE_LFU_Caching_Strategy::notify_unbind (int result, + const ATTRIBUTES & /* attr */) +{ + return result; +} + +template ACE_INLINE CACHING_UTILITY & +ACE_LFU_Caching_Strategy::caching_utility (void) +{ + return this->caching_utility_; +} + +template ACE_INLINE void +ACE_LFU_Caching_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_LFU_Caching_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +////////////////////////////////////////////////////////////////////////////////////// + +template ACE_INLINE ATTRIBUTES +ACE_FIFO_Caching_Strategy::attributes (void) +{ + return this->order_; +} + +template ACE_INLINE double +ACE_FIFO_Caching_Strategy::purge_percent (void) +{ + return this->purge_percent_; +} + +template ACE_INLINE void +ACE_FIFO_Caching_Strategy::purge_percent (double percentage) +{ + this->purge_percent_ = percentage; +} + +template ACE_INLINE int +ACE_FIFO_Caching_Strategy::notify_bind (int result, + const ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + if (result == 0) + ++this->order_; + + return result; +} + +template ACE_INLINE int +ACE_FIFO_Caching_Strategy::notify_find (int result, + ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_FIFO_Caching_Strategy::notify_unbind (int result, + const ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_FIFO_Caching_Strategy::notify_trybind (int result, + ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_FIFO_Caching_Strategy::notify_rebind (int result, + const ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + if (result == 0) + ++this->order_; + + return result; +} + +template ACE_INLINE CACHING_UTILITY & +ACE_FIFO_Caching_Strategy::caching_utility (void) +{ + return this->caching_utility_; +} + +template ACE_INLINE void +ACE_FIFO_Caching_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FIFO_Caching_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("order_ = %d "), this->order_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +////////////////////////////////////////////////////////////////////////////////// + +template ACE_INLINE ATTRIBUTES +ACE_Null_Caching_Strategy::attributes (void) +{ + return 0; +} + +template ACE_INLINE double +ACE_Null_Caching_Strategy::purge_percent (void) +{ + return 0; +} + +template ACE_INLINE void +ACE_Null_Caching_Strategy::purge_percent (double percentage) +{ + ACE_UNUSED_ARG (percentage); +} + +template ACE_INLINE int +ACE_Null_Caching_Strategy::notify_bind (int result, + const ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_Null_Caching_Strategy::notify_find (int result, + ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_Null_Caching_Strategy::notify_unbind (int result, + const ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_Null_Caching_Strategy::notify_trybind (int result, + ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE int +ACE_Null_Caching_Strategy::notify_rebind (int result, + const ATTRIBUTES &attr) +{ + ACE_UNUSED_ARG (attr); + + return result; +} + +template ACE_INLINE CACHING_UTILITY & +ACE_Null_Caching_Strategy::caching_utility (void) +{ + return this->caching_utility_; +} + +template ACE_INLINE void +ACE_Null_Caching_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Null_Caching_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +////////////////////////////////////////////////////////////////////////////////// diff --git a/dep/ACE_wrappers/ace/Caching_Utility_T.cpp b/dep/ACE_wrappers/ace/Caching_Utility_T.cpp new file mode 100644 index 000000000..a03a45758 --- /dev/null +++ b/dep/ACE_wrappers/ace/Caching_Utility_T.cpp @@ -0,0 +1,499 @@ +// $Id: Caching_Utility_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CACHING_UTILITY_T_CPP +#define ACE_CACHING_UTILITY_T_CPP + +#include "ace/Caching_Utility_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Min_Max.h" +#include "ace/OS_Memory.h" +#include "ace/Recyclable.h" + +////////////////////////////////////////////////////////////////////////////// + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Pair_Caching_Utility::ACE_Pair_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy, + int delete_cleanup_strategy) + : cleanup_strategy_ (cleanup_strategy), + delete_cleanup_strategy_ (delete_cleanup_strategy) +{ + if (cleanup_strategy == 0) + { + ACE_NEW (this->cleanup_strategy_, + CLEANUP_STRATEGY); + this->delete_cleanup_strategy_ = 1; + } +} + +template +ACE_Pair_Caching_Utility::~ACE_Pair_Caching_Utility (void) +{ + if (this->delete_cleanup_strategy_) + delete this->cleanup_strategy_; +} + +template int +ACE_Pair_Caching_Utility::clear_cache (CONTAINER &container, + double purge_percent) +{ + // Check that the purge_percent is non-zero. + if (purge_percent == 0) + return 0; + + // Get the number of entries in the container. + size_t current_map_size = container.current_size (); + + // Also whether the number of entries in the cache! + // Oops! then there is no way out but exiting. So return an error. + if (current_map_size == 0) + return 0; + + // Calculate the no of entries to remove from the cache depending + // upon the . + size_t const entries_to_remove + = ACE_MAX (static_cast (1), + static_cast (static_cast (purge_percent) + / 100 * current_map_size)); + KEY *key_to_remove = 0; + VALUE *value_to_remove = 0; + + for (size_t i = 0; i < entries_to_remove ; ++i) + { + this->minimum (container, + key_to_remove, + value_to_remove); + + // Simply verifying that the key is non-zero. + // This is important for strategies where the minimum + // entry cant be found due to constraints on the type of entry + // to remove. + if (key_to_remove == 0) + return 0; + + if (this->cleanup_strategy_->cleanup (container, + key_to_remove, + value_to_remove) == -1) + return -1; + + } + + return 0; +} + +template void +ACE_Pair_Caching_Utility::minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove) +{ + // Starting values. + ITERATOR iter = container.begin (); + ITERATOR end = container.end (); + ATTRIBUTES min = (*iter).int_id_.second (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + + // The iterator moves thru the container searching for the entry + // with the lowest ATTRIBUTES. + for (++iter; + iter != end; + ++iter) + { + if (min > (*iter).int_id_.second ()) + { + // Ah! an item with lower ATTTRIBUTES... + min = (*iter).int_id_.second (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +template +ACE_Recyclable_Handler_Caching_Utility::ACE_Recyclable_Handler_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy, + int delete_cleanup_strategy) + : cleanup_strategy_ (cleanup_strategy), + delete_cleanup_strategy_ (delete_cleanup_strategy) +{ + if (cleanup_strategy == 0) + { + ACE_NEW (this->cleanup_strategy_, + CLEANUP_STRATEGY); + this->delete_cleanup_strategy_ = 1; + } +} + +template +ACE_Recyclable_Handler_Caching_Utility::~ACE_Recyclable_Handler_Caching_Utility (void) +{ + if (this->delete_cleanup_strategy_) + delete this->cleanup_strategy_; +} + +template int +ACE_Recyclable_Handler_Caching_Utility::clear_cache (CONTAINER &container, + double purge_percent) +{ + // Check that the purge_percent is non-zero. + if (purge_percent == 0) + return 0; + + // Get the number of entries in the container. + size_t current_map_size = container.current_size (); + + // Also whether the number of entries in the cache is just one! + // Oops! then there is no way out but exiting. So return an error. + // if (current_map_size <= 1) + if (current_map_size == 0) + return 0; + + // Calculate the no of entries to remove from the cache depending + // upon the . + size_t const entries_to_remove + = ACE_MAX (static_cast (1), + static_cast (static_cast (purge_percent) + / 100 * current_map_size)); + + KEY *key_to_remove = 0; + VALUE *value_to_remove = 0; + + for (size_t i = 0; i < entries_to_remove ; ++i) + { + this->minimum (container, + key_to_remove, + value_to_remove); + + // Simply verifying that the key is non-zero. + // This is important for strategies where the minimum + // entry cant be found due to constraints on the type of entry + // to remove. + if (key_to_remove == 0) + return 0; + + if (this->cleanup_strategy_->cleanup (container, + key_to_remove, + value_to_remove) == -1) + return -1; + } + + return 0; +} + +template void +ACE_Recyclable_Handler_Caching_Utility::minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove) +{ + // Starting values. + ITERATOR end = container.end (); + ITERATOR iter = container.begin (); + ATTRIBUTES min = (*iter).int_id_.second (); + key_to_remove = 0; + value_to_remove = 0; + // Found the minimum entry to be purged? + int found = 0; + + // The iterator moves thru the container searching for the entry + // with the lowest ATTRIBUTES. + for (; + iter != end; + ++iter) + { + // If the entry isnt IDLE_AND_PURGABLE continue until you reach + // the first entry which can be purged. This is the minimum with + // which you will compare the rest of the purgable entries. + if ((*iter).ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE || + (*iter).ext_id_.recycle_state () == ACE_RECYCLABLE_PURGABLE_BUT_NOT_IDLE) + { + if (found == 0) + { + min = (*iter).int_id_.second (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + found = 1; + } + else + { + // Ah! an entry with lower ATTTRIBUTES... + if (min > (*iter).int_id_.second ()) + { + min = (*iter).int_id_.second (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + } + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +template +ACE_Refcounted_Recyclable_Handler_Caching_Utility::ACE_Refcounted_Recyclable_Handler_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy, + int delete_cleanup_strategy) + : cleanup_strategy_ (cleanup_strategy), + delete_cleanup_strategy_ (delete_cleanup_strategy), + marked_as_closed_entries_ (0) +{ + if (cleanup_strategy == 0) + { + ACE_NEW (this->cleanup_strategy_, + CLEANUP_STRATEGY); + this->delete_cleanup_strategy_ = 1; + } +} + +template +ACE_Refcounted_Recyclable_Handler_Caching_Utility::~ACE_Refcounted_Recyclable_Handler_Caching_Utility (void) +{ + if (this->delete_cleanup_strategy_) + delete this->cleanup_strategy_; +} + +template int +ACE_Refcounted_Recyclable_Handler_Caching_Utility::clear_cache (CONTAINER &container, + double purge_percent) +{ + // Check that the purge_percent is non-zero. + if (purge_percent == 0) + return 0; + + // Get the number of entries in the container which can be considered for purging. + size_t const available_entries = + container.current_size () - this->marked_as_closed_entries_; + + // Also whether the number of entries in the cache zero. + // Oops! then there is no way out but exiting. + if (available_entries <= 0) + return 0; + + // Calculate the no of entries to remove from the cache depending + // upon the . + size_t entries_to_remove + = ACE_MAX (static_cast (1), + static_cast (static_cast (purge_percent) + / 100 * available_entries)); + + if (entries_to_remove >= available_entries || entries_to_remove == 0) + entries_to_remove = available_entries - 1; + + KEY *key_to_remove = 0; + VALUE *value_to_remove = 0; + + for (size_t i = 0; i < entries_to_remove ; ++i) + { + this->minimum (container, + key_to_remove, + value_to_remove); + + // Simply verifying that the key is non-zero. + // This is important for strategies where the minimum + // entry cant be found due to constraints on the type of entry + // to remove. + if (key_to_remove == 0) + return 0; + + if (this->cleanup_strategy_->cleanup (container, + key_to_remove, + value_to_remove) == -1) + return -1; + + ++this->marked_as_closed_entries_; + } + + return 0; +} + +template void +ACE_Refcounted_Recyclable_Handler_Caching_Utility::minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove) +{ + // Starting values. + ITERATOR end = container.end (); + ITERATOR iter = container.begin (); + ATTRIBUTES min = (*iter).int_id_.second (); + key_to_remove = 0; + value_to_remove = 0; + // Found the minimum entry to be purged? + int found = 0; + + // The iterator moves thru the container searching for the entry + // with the lowest ATTRIBUTES. + for (; + iter != end; + ++iter) + { + // If the entry isnt IDLE_AND_PURGABLE continue until you reach + // the first entry which can be purged. This is the minimum with + // which you will compare the rest of the purgable entries. + if ((*iter).ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE || + (*iter).ext_id_.recycle_state () == ACE_RECYCLABLE_PURGABLE_BUT_NOT_IDLE) + { + if (found == 0) + { + min = (*iter).int_id_.second (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + found = 1; + } + else + { + // Ah! an entry with lower ATTTRIBUTES... + if (min > (*iter).int_id_.second ()) + { + min = (*iter).int_id_.second (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + } + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +template +ACE_Handler_Caching_Utility::ACE_Handler_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy, + int delete_cleanup_strategy) + : cleanup_strategy_ (cleanup_strategy), + delete_cleanup_strategy_ (delete_cleanup_strategy) +{ + if (cleanup_strategy == 0) + { + ACE_NEW (this->cleanup_strategy_, + CLEANUP_STRATEGY); + this->delete_cleanup_strategy_ = 1; + } +} + +template +ACE_Handler_Caching_Utility::~ACE_Handler_Caching_Utility (void) +{ + if (this->delete_cleanup_strategy_) + delete this->cleanup_strategy_; +} + +template int +ACE_Handler_Caching_Utility::clear_cache (CONTAINER &container, + double purge_percent) +{ + // Check that the purge_percent is non-zero. + if (purge_percent == 0) + return 0; + + // Get the number of entries in the container. + size_t current_map_size = container.current_size (); + + // Also whether the number of entries in the cache is just one! + // Oops! then there is no way out but exiting. So return an error. + if (current_map_size == 0) + return 0; + + // Calculate the no of entries to remove from the cache depending + // upon the . + size_t entries_to_remove + = ACE_MAX (static_cast (1), + static_cast (static_cast (purge_percent) + / 100 * current_map_size)); + + KEY *key_to_remove = 0; + VALUE *value_to_remove = 0; + + for (size_t i = 0; i < entries_to_remove ; ++i) + { + this->minimum (container, + key_to_remove, + value_to_remove); + + if (this->cleanup_strategy_->cleanup (container, + key_to_remove, + value_to_remove) == -1) + return -1; + } + + return 0; +} + +template void +ACE_Handler_Caching_Utility::minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove) +{ + // Starting values. + ITERATOR iter = container.begin (); + ITERATOR end = container.end (); + ATTRIBUTES min = (*iter).int_id_->caching_attributes (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + + // The iterator moves thru the container searching for the entry + // with the lowest ATTRIBUTES. + for (++iter; + iter != end; + ++iter) + { + if (min > (*iter).int_id_->caching_attributes () && + (*iter).int_id_->active () != 1) + { + // Ah! an item with lower ATTTRIBUTES... + min = (*iter).int_id_->caching_attributes (); + key_to_remove = &(*iter).ext_id_; + value_to_remove = &(*iter).int_id_; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +template +ACE_Null_Caching_Utility::ACE_Null_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy, + int delete_cleanup_strategy) + : cleanup_strategy_ (cleanup_strategy), + delete_cleanup_strategy_ (delete_cleanup_strategy) +{ + if (cleanup_strategy == 0) + { + ACE_NEW (this->cleanup_strategy_, + CLEANUP_STRATEGY); + this->delete_cleanup_strategy_ = 1; + } +} + +template +ACE_Null_Caching_Utility::~ACE_Null_Caching_Utility (void) +{ + if (this->delete_cleanup_strategy_) + delete this->cleanup_strategy_; +} + +template int +ACE_Null_Caching_Utility::clear_cache (CONTAINER &container, + double purge_percent) +{ + ACE_UNUSED_ARG (container); + ACE_UNUSED_ARG (purge_percent); + + return 0; +} + +template void +ACE_Null_Caching_Utility::minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove) +{ + ACE_UNUSED_ARG (container); + ACE_UNUSED_ARG (key_to_remove); + ACE_UNUSED_ARG (value_to_remove); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_CACHING_UTILITY_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Caching_Utility_T.h b/dep/ACE_wrappers/ace/Caching_Utility_T.h new file mode 100644 index 000000000..5428682d0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Caching_Utility_T.h @@ -0,0 +1,347 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Caching_Utility_T.h + * + * $Id: Caching_Utility_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kirthika Parameswaran + */ +//============================================================================= + +#ifndef ACE_CACHING_UTILITY_H +#define ACE_CACHING_UTILITY_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/Cleanup_Strategies_T.h" + +// For linkers that cant grok long names. +#define ACE_Pair_Caching_Utility APUTIL + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Pair_Caching_Utility + * + * @brief Defines a helper class for the Caching Strategies. + * + * This class defines the methods commonly used by the different + * caching strategies. For instance: method which + * decides and purges the entry from the container. @note This + * class helps in the caching_strategies using a container + * containing entries of > + * kind. The attributes helps in deciding the entries to be + * purged. The Cleanup_Strategy is the callback class to which the + * entries to be cleaned up will be delegated. + */ +template +class ACE_Pair_Caching_Utility +{ +public: + + typedef ACE_Cleanup_Strategy CLEANUP_STRATEGY; + + /// Constructor. + ACE_Pair_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy = 0, + int delete_cleanup_strategy = 0); + + /// Destructor. + ~ACE_Pair_Caching_Utility (void); + + /** + * Purge entries from the @a container. The Cleanup_Strategy will do the + * actual job of cleanup once the entries to be cleaned up are decided. + */ + int clear_cache (CONTAINER &container, + double purge_percent); + +protected: + + /// Find the entry with minimum caching attributes. + void minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove); + + /// The cleanup strategy which can be used to destroy the entries of + /// the container. + CLEANUP_STRATEGY *cleanup_strategy_; + + /// Whether the cleanup_strategy should be destroyed or not. + int delete_cleanup_strategy_; + + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Pair_Caching_Utility &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Pair_Caching_Utility (const ACE_Pair_Caching_Utility &)) +}; + +//////////////////////////////////////////////////////////////////////////////// +#define ACE_Recyclable_Handler_Caching_Utility ARHUTIL + +/** + * @class ACE_Recyclable_Handler_Caching_Utility + * + * @brief Defines a helper class for the Caching Strategies. + * + * This class defines the methods commonly used by the different + * caching strategies. For instance: method which + * decides and purges the entry from the container. @note This + * class helps in the caching_strategies using a container + * containing entries of kind. The attributes + * helps in deciding the entries to be purged. The + * Cleanup_Strategy is the callback class to which the entries to + * be cleaned up will be delegated. + */ +template +class ACE_Recyclable_Handler_Caching_Utility +{ + +public: + + typedef ACE_Recyclable_Handler_Cleanup_Strategy CLEANUP_STRATEGY; + typedef ACE_Cleanup_Strategy CLEANUP_STRATEGY_BASE; + + /// Constructor. + ACE_Recyclable_Handler_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy = 0, + int delete_cleanup_strategy = 0); + + /// Destructor. + ~ACE_Recyclable_Handler_Caching_Utility (void); + + /** + * Purge entries from the . The Cleanup_Strategy will do + * the actual job of cleanup once the entries to be cleaned up are + * decided. + */ + int clear_cache (CONTAINER &container, + double purge_percent); + +protected: + + /// Find the entry with minimum caching attributes. + void minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove); + + /// This is the default Cleanup Strategy for this utility. + CLEANUP_STRATEGY_BASE *cleanup_strategy_; + + /// Whether the cleanup_strategy should be destroyed or not. + int delete_cleanup_strategy_; + +private: + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Recyclable_Handler_Caching_Utility &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Recyclable_Handler_Caching_Utility (const ACE_Recyclable_Handler_Caching_Utility &)) +}; + +/////////////////////////////////////////////////////////////////////////// +#define ACE_Refcounted_Recyclable_Handler_Caching_Utility ARRHUTIL + +/** + * @class ACE_Refcounted_Recyclable_Handler_Caching_Utility + * + * @brief Defines a helper class for the Caching Strategies. + * + * This class defines the methods commonly used by the different + * caching strategies. For instance: clear_cache () method which + * decides and purges the entry from the container. @note This + * class helps in the caching_strategies using a container + * containing entries of kind. The attributes helps in + * deciding the entries to be purged. The Cleanup_Strategy is the + * callback class to which the entries to be cleaned up will be + * delegated. + */ +template +class ACE_Refcounted_Recyclable_Handler_Caching_Utility +{ + +public: + + typedef ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy CLEANUP_STRATEGY; + typedef ACE_Cleanup_Strategy CLEANUP_STRATEGY_BASE; + + /// Constructor. + ACE_Refcounted_Recyclable_Handler_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy = 0, + int delete_cleanup_strategy = 0); + + /// Destructor. + ~ACE_Refcounted_Recyclable_Handler_Caching_Utility (void); + + /** + * Purge entries from the . The Cleanup_Strategy will do + * the actual job of cleanup once the entries to be cleaned up are + * decided. + */ + int clear_cache (CONTAINER &container, + double purge_percent); + +protected: + + /// Find the entry with minimum caching attributes. + void minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove); + + /// This is the default Cleanup Strategy for this utility. + CLEANUP_STRATEGY_BASE *cleanup_strategy_; + + /// Whether the cleanup_strategy should be destroyed or not. + int delete_cleanup_strategy_; + + /** + * This figure denotes the number of entries are there in the + * container which have been marked as closed already but might + * not have been unbound from the container. + */ + size_t marked_as_closed_entries_; + +private: + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Refcounted_Recyclable_Handler_Caching_Utility &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Refcounted_Recyclable_Handler_Caching_Utility (const ACE_Refcounted_Recyclable_Handler_Caching_Utility &)) +}; + +//////////////////////////////////////////////////////////////////////////////////////// + +/** + * @class ACE_Handler_Caching_Utility + * + * @brief Defines a helper class for the Caching Strategies. + * + * This class defines the methods commonly used by the different + * caching strategies. For instance: method which + * decides and purges the entry from the container. @note This + * class helps in the caching_strategies using a container + * containing entries of kind where the HANDLER + * contains the caching attributes which help in deciding the + * entries to be purged. The Cleanup_Strategy is the callback + * class to which the entries to be cleaned up will be delegated. + */ +template +class ACE_Handler_Caching_Utility +{ +public: + + typedef ACE_Handler_Cleanup_Strategy CLEANUP_STRATEGY; + typedef ACE_Cleanup_Strategy CLEANUP_STRATEGY_BASE; + + /// Constructor. + ACE_Handler_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy = 0, + int delete_cleanup_strategy = 0); + + /// Destructor. + ~ACE_Handler_Caching_Utility (void); + + /** + * Purge entries from the . The Cleanup_Strategy will do + * the actual job of cleanup once the entries to be cleaned up are + * decided. + */ + int clear_cache (CONTAINER &container, + double purge_percent); + +protected: + + /** + * Find the entry with minimum caching attributes. This is handler + * specific since this utility is to be used very specifically for + * handler who have caching_attributes for server side acched + * connection management. + */ + void minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove); + + /// The cleanup strategy which can be used to destroy the entries of + /// the container. + CLEANUP_STRATEGY_BASE *cleanup_strategy_; + + /// Whether the cleanup_strategy should be destroyed or not. + int delete_cleanup_strategy_; + +private: + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Handler_Caching_Utility &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Handler_Caching_Utility (const ACE_Handler_Caching_Utility &)) +}; + +/////////////////////////////////////////////////////////////////////////// +#define ACE_Null_Caching_Utility ANUTIL +/** + * @class ACE_Null_Caching_Utility + * + * @brief Defines a dummy helper class for the Caching Strategies. + * + * This class defines the methods commonly used by the different + * caching strategies. For instance: method which + * decides and purges the entry from the container. @note This + * class is be used with the Null_Caching_Strategy. The + * Cleanup_Strategy is the callback class to which the entries to + * be cleaned up will be delegated. + */ +template +class ACE_Null_Caching_Utility +{ +public: + + typedef ACE_Null_Cleanup_Strategy CLEANUP_STRATEGY; + typedef ACE_Cleanup_Strategy CLEANUP_STRATEGY_BASE; + + /// Constructor. + ACE_Null_Caching_Utility (ACE_Cleanup_Strategy *cleanup_strategy = 0, + int delete_cleanup_strategy = 0); + + /// Destructor. + ~ACE_Null_Caching_Utility (void); + + /** + * Purge entries from the . The Cleanup_Strategy will do + * the actual job of cleanup once the entries to be cleaned up are + * decided. @note Here it is a no-op. + */ + int clear_cache (CONTAINER &container, + double purge_percent); + +protected: + + /** + * Find the entry with minimum caching attributes. This is handler + * specific since this utility is to be used very specifically for + * handler who have caching_attributes for server side acched + * connection management.@note Here it is a no-op. + */ + void minimum (CONTAINER &container, + KEY *&key_to_remove, + VALUE *&value_to_remove); + + /// The cleanup strategy which can be used to destroy the entries of + /// the container. + CLEANUP_STRATEGY_BASE *cleanup_strategy_; + + /// Whether the cleanup_strategy should be destroyed or not. + int delete_cleanup_strategy_; + +private: + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Null_Caching_Utility &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Null_Caching_Utility (const ACE_Null_Caching_Utility &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Caching_Utility_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Caching_Utility_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CACHING_UTILITY_H */ diff --git a/dep/ACE_wrappers/ace/Capabilities.cpp b/dep/ACE_wrappers/ace/Capabilities.cpp new file mode 100644 index 000000000..5d46e7547 --- /dev/null +++ b/dep/ACE_wrappers/ace/Capabilities.cpp @@ -0,0 +1,355 @@ +#include "ace/Capabilities.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Capabilities.inl" +#endif /* !__ACE_INLINE__ */ + +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (ace, + Capabilities, + "$Id: Capabilities.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +#define ACE_ESC ((ACE_TCHAR)0x1b) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_CapEntry::~ACE_CapEntry (void) +{ +} + +ACE_Capabilities::ACE_Capabilities (void) + : caps_ () +{ +} + +ACE_Capabilities::~ACE_Capabilities (void) +{ + this->resetcaps (); +} + +const ACE_TCHAR * +ACE_Capabilities::parse (const ACE_TCHAR *buf, ACE_TString &cap) +{ + while (*buf != ACE_TEXT ('\0') && *buf != ACE_TEXT (',')) + { + if (*buf == ACE_TEXT ('\\')) + { + ++buf; + if (*buf == ACE_TEXT ('E') || *buf == ACE_TEXT ('e')) + { + cap += ACE_ESC; + ++buf; + continue; + } + else if (*buf == ACE_TEXT ('r')) + { + cap += ACE_TEXT ('\r'); + ++buf; + continue; + } + else if (*buf == ACE_TEXT ('n')) + { + cap += ACE_TEXT ('\n'); + ++buf; + continue; + } + else if (*buf == ACE_TEXT ('t')) + { + cap += ACE_TEXT ('\t'); + ++buf; + continue; + } + else if (*buf == ACE_TEXT ('\\')) + { + cap += *buf++; + continue; + } + if (ACE_OS::ace_isdigit(*buf)) + { + // @@ UNICODE Does this work with unicode? + int oc = 0; + for (int i = 0; + i < 3 && *buf && ACE_OS::ace_isdigit (*buf); + i++) + oc = oc * 8 + (*buf++ - ACE_TEXT ('0')); + + cap += (ACE_TCHAR) oc; + continue; + } + } + cap += *buf++; + } + return buf; +} + +const ACE_TCHAR * +ACE_Capabilities::parse (const ACE_TCHAR *buf, int &cap) +{ + int n = 0; + + while (*buf && ACE_OS::ace_isdigit (*buf)) + n = n * 10 + (*buf++ - ACE_TEXT ('0')); + + cap = n; + + return buf; +} + +void +ACE_Capabilities::resetcaps (void) +{ + for (CAPABILITIES_MAP::ITERATOR iter (this->caps_); + !iter.done (); + iter.advance ()) + { + CAPABILITIES_MAP::ENTRY *entry = 0; + iter.next (entry); + delete entry->int_id_; + } + + this->caps_.close (); + this->caps_.open (); +} + +int +ACE_Capabilities::fillent (const ACE_TCHAR *buf) +{ + this->resetcaps (); + while (*buf) + { + ACE_TString s; + int n; + ACE_TString name; + ACE_CapEntry *ce; + + // Skip blanks + while (*buf && ACE_OS::ace_isspace(*buf)) buf++; + // If we get end of line return + + if (*buf == ACE_TEXT ('\0')) + break; + + if (*buf == ACE_TEXT ('#')) + { + while (*buf && *buf != ACE_TEXT ('\n')) + buf++; + if (*buf == ACE_TEXT ('\n')) + buf++; + continue; + } + while(*buf && *buf != ACE_TEXT ('=') + && *buf!= ACE_TEXT ('#') + && *buf != ACE_TEXT (',')) + name += *buf++; + + // If name is null. + switch (*buf) + { + case ACE_TEXT ('='): + // String property + buf = this->parse (buf + 1, s); + ACE_NEW_RETURN (ce, + ACE_StringCapEntry (s), + -1); + if (this->caps_.bind (name, ce) == -1) + { + delete ce; + return -1; + } + break; + case ACE_TEXT ('#'): + // Integer property + buf = this->parse (buf + 1, n); + ACE_NEW_RETURN (ce, + ACE_IntCapEntry (n), + -1); + if (this->caps_.bind (name, ce) == -1) + { + delete ce; + return -1; + } + break; + case ACE_TEXT (','): + // Boolean + ACE_NEW_RETURN (ce, + ACE_BoolCapEntry (1), + -1); + if (this->caps_.bind (name, ce) == -1) + { + delete ce; + return -1; + } + break; + default: + return 0; + } + + if (*buf++ != ACE_TEXT (',')) + return -1; + } + + return 0; +} + +int +ACE_Capabilities::is_entry (const ACE_TCHAR *name, const ACE_TCHAR *line) +{ + for (;;) + { + // Skip blanks or irrelevant characters + while (*line && ACE_OS::ace_isspace(*line)) + ++line; + + // End of line reached + if (*line == ACE_TEXT ('\0')) + break; + + // Build the entry name + ACE_TString nextname; + while (*line && *line != ACE_TEXT ('|') && *line != ACE_TEXT (',')) + nextname += *line++; + + // We have found the required entry? + if (ACE_OS::strcmp (nextname.c_str (), name) == 0) + return 1; + + // Skip puntuaction char if neccesary. + if (*line == ACE_TEXT ('|') || *line == ACE_TEXT (',')) + ++line; + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Invalid entry\n"))); + break; + } + } + return 0; +} + +int +ACE_Capabilities::getline (FILE *fp, ACE_TString &line) +{ + int ch; + + line.set (0, 0); + + while ((ch = ACE_OS::fgetc (fp)) != EOF && ch != ACE_TEXT ('\n')) + line += (ACE_TCHAR) ch; + + if (ch == EOF && line.length () == 0) + return -1; + else + return 0; +} + +int +ACE_Capabilities::getval (const ACE_TCHAR *keyname, ACE_TString &val) +{ + ACE_CapEntry* cap = 0; + if (this->caps_.find (keyname, cap) == -1) + return -1; + + ACE_StringCapEntry *scap = + dynamic_cast (cap); + if (scap == 0) + return -1; + + val = scap->getval (); + return 0; +} + +int +ACE_Capabilities::getval (const ACE_TCHAR *keyname, int &val) +{ + ACE_CapEntry *cap = 0; + if (this->caps_.find (keyname, cap) == -1) + return -1; + + ACE_IntCapEntry *icap = + dynamic_cast (cap); + if (icap != 0) + { + val = icap->getval (); + return 0; + } + + ACE_BoolCapEntry *bcap = + dynamic_cast (cap); + + if (bcap == 0) + return -1; + + val = bcap->getval (); + return 0; +} + +#if !defined (ACE_IS_SPLITTING) +static int +is_empty (const ACE_TCHAR *line) +{ + while (*line && ACE_OS::ace_isspace (*line)) + ++line; + + return *line == ACE_TEXT ('\0') || *line == ACE_TEXT ('#'); +} + +static int +is_line (const ACE_TCHAR *line) +{ + while (*line && ACE_OS::ace_isspace (*line)) + ++line; + + return *line != ACE_TEXT ('\0'); +} +#endif /* !ACE_IS_SPLITTING */ + +int +ACE_Capabilities::getent (const ACE_TCHAR *fname, const ACE_TCHAR *name) +{ + FILE *fp = ACE_OS::fopen (fname, ACE_TEXT ("r")); + + if (fp == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Can't open %s file\n"), + fname), + -1); + + int done; + ACE_TString line; + + while (0 == (done = (this->getline (fp, line) == -1)) + && is_empty (line.c_str ())) + continue; + + while (!done) + { + ACE_TString newline; + ACE_TString description; + + while (0 == (done = (this->getline (fp, newline) == -1))) + if (is_line (newline.c_str ())) + description += newline; + else + break; + + if (this->is_entry (name, line.c_str())) + { + ACE_OS::fclose (fp); + return this->fillent (description.c_str ()); + } + + line = newline; + while (!done && is_empty (line.c_str ())) + done = this->getline (fp, line) == -1; + } + + ACE_OS::fclose (fp); + return -1; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Capabilities.h b/dep/ACE_wrappers/ace/Capabilities.h new file mode 100644 index 000000000..e893d987c --- /dev/null +++ b/dep/ACE_wrappers/ace/Capabilities.h @@ -0,0 +1,221 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Capabilities.h + * + * $Id: Capabilities.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Arturo Montes + */ +//============================================================================= + + +#ifndef ACE_CAPABILITIES_H +#define ACE_CAPABILITIES_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Null_Mutex.h" +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Containers.h" +#include "ace/SString.h" +#include "ace/Functor_String.h" + +#if defined (ACE_IS_SPLITTING) +# include "ace/OS_NS_ctype.h" +#endif /* ACE_IS_SPLITTING */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_CapEntry + * + * @brief This class is the base class for all ACE Capabilities entry + * subclasses. + * + * This class is not instantiable and does not provide accessors + * or methods. If you want to add a new kind of attribute subclass + * this class and dynamic_cast to proper subclass. + */ +class ACE_Export ACE_CapEntry +{ +public: + + virtual ~ACE_CapEntry (void); + +protected: + + enum + { + ACE_INTCAP = 0, + ACE_STRINGCAP = 1, + ACE_BOOLCAP = 2 + }; + + ACE_CapEntry (int captype); + +protected: + + int captype_; + +}; + +/** + * @class ACE_IntCapEntry + * + * @brief This class implement the ACE Integer Capability subclass. + * + * This is a container class for ACE Capabilities integer container + * values. + */ +class ACE_Export ACE_IntCapEntry : public ACE_CapEntry +{ +public: + ACE_IntCapEntry (int val); + int getval (void) const; + +protected: + int val_; +}; + +/** + * @class ACE_StringCapEntry + * + * @brief This class implement the ACE String Capability subclass. + * + * This is a container class for ACE Capabilities String container + * values. + */ +class ACE_Export ACE_StringCapEntry : public ACE_CapEntry +{ +public: + ACE_StringCapEntry (const ACE_TString &val); + ACE_TString getval (void) const; + +protected: + ACE_TString val_; +}; + +/** + * @class ACE_BoolCapEntry + * + * @brief This class implement the ACE Bool Capability subclass. + * + * This is a container class for ACE Capabilities bool container + * values. + */ +class ACE_Export ACE_BoolCapEntry : public ACE_CapEntry +{ +public: + ACE_BoolCapEntry (int val); + int getval (void) const; + +protected: + int val_; +}; + +/** + * @class ACE_Capabilities + * + * @brief This class implement the ACE Capabilities. + * + * This is a container class for ACE Capabilities + * values. Currently exist three different capability values: + * (integer), (bool) and + * (String). An ACE_Capabilities is a + * unordered set of pair = (, *). Where + * the first component is the name of capability and the second + * component is a pointer to the capability value container. A + * is a container for ACE_Capabilities, the + * ACE_Capabilities has a name in the file, as a termcap file. + */ +class ACE_Export ACE_Capabilities +{ +public: + + typedef ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> CAPABILITIES_MAP; + + /// The Constructor + ACE_Capabilities (void); + + /// The Destructor + ~ACE_Capabilities(void); + +public: + + /// Get a string entry. + int getval (const ACE_TCHAR *ent, ACE_TString &val); + + /// Get an integer entry. + int getval (const ACE_TCHAR *ent, int &val); + + /// Get the ACE_Capabilities name from FILE fname and load the + /// associated capabitily entries in map. + int getent (const ACE_TCHAR *fname, const ACE_TCHAR *name); + +protected: + + /// Parse an integer property + const ACE_TCHAR *parse (const ACE_TCHAR *buf, int &cap); + + /// Parse a string property + const ACE_TCHAR *parse (const ACE_TCHAR *buf, ACE_TString &cap); + + /// Fill the ACE_Capabilities with description in ent. + int fillent(const ACE_TCHAR *ent); + + /// Parse a cap entry + int parseent (const ACE_TCHAR *name, ACE_TCHAR *line); + + /// Get a line from FILE input stream + int getline (FILE* fp, + ACE_TString &line); + + /// Is a valid entry + int is_entry (const ACE_TCHAR *name, const ACE_TCHAR *line); + + /// Reset the set of capabilities + void resetcaps (void); + +private: + + /// This is the set of ACE_CapEntry. + CAPABILITIES_MAP caps_; + +}; + +#if defined (ACE_IS_SPLITTING) +int +is_empty (const ACE_TCHAR *line) +{ + while (*line && ACE_OS::ace_isspace (*line)) + ++line; + + return *line == ACE_TEXT ('\0') || *line == ACE_TEXT ('#'); +} + +int +is_line (const ACE_TCHAR *line) +{ + while (*line && ACE_OS::ace_isspace (*line)) + ++line; + + return *line != ACE_TEXT ('\0'); +} +#endif /* ACE_IS_SPLITTING */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Capabilities.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* __ACE_CAPABILITIES_H__ */ diff --git a/dep/ACE_wrappers/ace/Capabilities.inl b/dep/ACE_wrappers/ace/Capabilities.inl new file mode 100644 index 000000000..37284b286 --- /dev/null +++ b/dep/ACE_wrappers/ace/Capabilities.inl @@ -0,0 +1,52 @@ +// -*- C++ -*- +// +// $Id: Capabilities.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_CapEntry::ACE_CapEntry (int captype) + : captype_ (captype) +{ +} + +ACE_INLINE +ACE_IntCapEntry::ACE_IntCapEntry (int val) + : ACE_CapEntry (ACE_INTCAP), + val_ (val) +{ +} + +ACE_INLINE int +ACE_IntCapEntry::getval (void) const +{ + return val_; +} + +ACE_INLINE +ACE_StringCapEntry::ACE_StringCapEntry (const ACE_TString &val) + : ACE_CapEntry (ACE_STRINGCAP), + val_ (val) +{ +} + +ACE_INLINE ACE_TString +ACE_StringCapEntry::getval (void) const +{ + return val_; +} + +ACE_INLINE +ACE_BoolCapEntry::ACE_BoolCapEntry (int val) + : ACE_CapEntry (ACE_BOOLCAP), + val_(val) +{ +} + +ACE_INLINE int +ACE_BoolCapEntry::getval (void) const +{ + return val_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Cleanup.cpp b/dep/ACE_wrappers/ace/Cleanup.cpp new file mode 100644 index 000000000..752ffb40b --- /dev/null +++ b/dep/ACE_wrappers/ace/Cleanup.cpp @@ -0,0 +1,192 @@ +// $Id: Cleanup.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Cleanup.h" + +ACE_RCSID (ace, + Cleanup, + "$Id: Cleanup.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "ace/Cleanup.inl" +#endif /* ACE_HAS_INLINED_OSCALLS */ + +#include "ace/OS_Memory.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_Cleanup::cleanup (void *) +{ + delete this; +} + + +ACE_Cleanup::~ACE_Cleanup (void) +{ +} + +/*****************************************************************************/ + +extern "C" void +ACE_CLEANUP_DESTROYER_NAME (ACE_Cleanup *object, void *param) +{ + object->cleanup (param); +} + +/*****************************************************************************/ + +ACE_Cleanup_Info::ACE_Cleanup_Info (void) + : object_ (0), + cleanup_hook_ (0), + param_ (0) +{ +} + +bool +ACE_Cleanup_Info::operator== (const ACE_Cleanup_Info &o) const +{ + return o.object_ == this->object_ + && o.cleanup_hook_ == this->cleanup_hook_ + && o.param_ == this->param_; +} + +bool +ACE_Cleanup_Info::operator!= (const ACE_Cleanup_Info &o) const +{ + return !(*this == o); +} + +/*****************************************************************************/ + +/** + * @class ACE_Cleanup_Info_Node + * + * @brief For maintaining a list of ACE_Cleanup_Info items. + * + * For internal use by ACE_Object_Manager. + */ +class ACE_Cleanup_Info_Node +{ +public: + ACE_Cleanup_Info_Node (void); + ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info, + ACE_Cleanup_Info_Node *next); + ~ACE_Cleanup_Info_Node (void); + ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &); +private: + ACE_Cleanup_Info cleanup_info_; + ACE_Cleanup_Info_Node *next_; + + friend class ACE_OS_Exit_Info; +}; + +ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void) + : cleanup_info_ (), + next_ (0) +{ +} + +ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info, + ACE_Cleanup_Info_Node *next) + : cleanup_info_ (new_info), + next_ (next) +{ +} + +ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void) +{ + delete next_; +} + +ACE_Cleanup_Info_Node * +ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info) +{ + ACE_Cleanup_Info_Node *new_node = 0; + + ACE_NEW_RETURN (new_node, + ACE_Cleanup_Info_Node (new_info, this), + 0); + + return new_node; +} + +/*****************************************************************************/ + +ACE_OS_Exit_Info::ACE_OS_Exit_Info (void) +{ + ACE_NEW (registered_objects_, ACE_Cleanup_Info_Node); +} + +ACE_OS_Exit_Info::~ACE_OS_Exit_Info (void) +{ + delete registered_objects_; + registered_objects_ = 0; +} + +int +ACE_OS_Exit_Info::at_exit_i (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param) +{ + ACE_Cleanup_Info new_info; + new_info.object_ = object; + new_info.cleanup_hook_ = cleanup_hook; + new_info.param_ = param; + + // Return -1 and sets errno if unable to allocate storage. Enqueue + // at the head and dequeue from the head to get LIFO ordering. + + ACE_Cleanup_Info_Node *new_node = 0; + + if ((new_node = registered_objects_->insert (new_info)) == 0) + return -1; + else + { + registered_objects_ = new_node; + return 0; + } +} + +int +ACE_OS_Exit_Info::find (void *object) +{ + // Check for already in queue, and return 1 if so. + for (ACE_Cleanup_Info_Node *iter = registered_objects_; + iter && iter->next_ != 0; + iter = iter->next_) + { + if (iter->cleanup_info_.object_ == object) + { + // The object has already been registered. + return 1; + } + } + + return 0; +} + +void +ACE_OS_Exit_Info::call_hooks (void) +{ + // Call all registered cleanup hooks, in reverse order of + // registration. + for (ACE_Cleanup_Info_Node *iter = registered_objects_; + iter && iter->next_ != 0; + iter = iter->next_) + { + ACE_Cleanup_Info &info = iter->cleanup_info_; + if (info.cleanup_hook_ == reinterpret_cast ( + ACE_CLEANUP_DESTROYER_NAME)) + // The object is an ACE_Cleanup. + ACE_CLEANUP_DESTROYER_NAME ( + reinterpret_cast (info.object_), + info.param_); + else if (info.object_ == &ace_exit_hook_marker) + // The hook is an ACE_EXIT_HOOK. + (* reinterpret_cast (info.cleanup_hook_)) (); + else + (*info.cleanup_hook_) (info.object_, info.param_); + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Cleanup.h b/dep/ACE_wrappers/ace/Cleanup.h new file mode 100644 index 000000000..8ea036058 --- /dev/null +++ b/dep/ACE_wrappers/ace/Cleanup.h @@ -0,0 +1,137 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Cleanup.h + * + * $Id: Cleanup.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + * @author Jesper S. M|ller + * @author and a cast of thousands... + * + * Originally in OS.h. + */ +//============================================================================= + +#ifndef ACE_CLEANUP_H +# define ACE_CLEANUP_H + +# include /**/ "ace/pre.h" + +# include "ace/config-lite.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/ACE_export.h" + +#if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1) +# include "ace/Global_Macros.h" +# define ACE_CLEANUP_DESTROYER_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ace_cleanup_destroyer) +#else +# define ACE_CLEANUP_DESTROYER_NAME ace_cleanup_destroyer +#endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Cleanup + * + * @brief Base class for objects that are cleaned by ACE_Object_Manager. + */ +class ACE_Export ACE_Cleanup +{ +public: + /// No-op constructor. + ACE_Cleanup (void); + + /// Destructor. + virtual ~ACE_Cleanup (void); + + /// Cleanup method that, by default, simply deletes itself. + virtual void cleanup (void *param = 0); +}; + +// Adapter for cleanup, used by ACE_Object_Manager. +extern "C" ACE_Export +void ACE_CLEANUP_DESTROYER_NAME (ACE_Cleanup *, void *param = 0); + +/** + * @class ACE_Cleanup_Info + * + * @brief Hold cleanup information for thread/process + */ +class ACE_Export ACE_Cleanup_Info +{ +public: + /// Default constructor. + ACE_Cleanup_Info (void); + + /// Equality operator. + bool operator== (const ACE_Cleanup_Info &o) const; + + /// Inequality operator. + bool operator!= (const ACE_Cleanup_Info &o) const; + + /// Point to object that gets passed into the . + void *object_; + + /// Cleanup hook that gets called back. + ACE_CLEANUP_FUNC cleanup_hook_; + + /// Parameter passed to the . + void *param_; +}; + +class ACE_Cleanup_Info_Node; + +/** + * @class ACE_OS_Exit_Info + * + * @brief Hold Object Manager cleanup (exit) information. + * + * For internal use by the ACE library, only. + */ +class ACE_Export ACE_OS_Exit_Info +{ +public: + /// Default constructor. + ACE_OS_Exit_Info (void); + + /// Destructor. + ~ACE_OS_Exit_Info (void); + + /// Use to register a cleanup hook. + int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); + + /// Look for a registered cleanup hook object. Returns 1 if already + /// registered, 0 if not. + int find (void *object); + + /// Call all registered cleanup hooks, in reverse order of + /// registration. + void call_hooks (); + +private: + /** + * Keeps track of all registered objects. The last node is only + * used to terminate the list (it doesn't contain a valid + * ACE_Cleanup_Info). + */ + ACE_Cleanup_Info_Node *registered_objects_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "ace/Cleanup.inl" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +# include /**/ "ace/post.h" +#endif /* ACE_CLEANUP_H */ diff --git a/dep/ACE_wrappers/ace/Cleanup.inl b/dep/ACE_wrappers/ace/Cleanup.inl new file mode 100644 index 000000000..9c36d6b1f --- /dev/null +++ b/dep/ACE_wrappers/ace/Cleanup.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id: Cleanup.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Cleanup::ACE_Cleanup (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Cleanup_Strategies_T.cpp b/dep/ACE_wrappers/ace/Cleanup_Strategies_T.cpp new file mode 100644 index 000000000..329659937 --- /dev/null +++ b/dep/ACE_wrappers/ace/Cleanup_Strategies_T.cpp @@ -0,0 +1,95 @@ +//$Id: Cleanup_Strategies_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CLEANUP_STRATEGIES_T_CPP +#define ACE_CLEANUP_STRATEGIES_T_CPP + +#include "ace/Cleanup_Strategies_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +//////////////////////////////////////////////////////////////////////////// + +template +ACE_Cleanup_Strategy::~ACE_Cleanup_Strategy (void) +{ +} + +template int +ACE_Cleanup_Strategy::cleanup (CONTAINER &container, + KEY *key, + VALUE *) +{ + return container.unbind (*key); +} + +//////////////////////////////////////////////////////////////////////////// + +template int +ACE_Recyclable_Handler_Cleanup_Strategy::cleanup ( + CONTAINER &container, + KEY *key, + VALUE *) +{ + VALUE value; + + if (container.unbind (*key, value) == -1) + return -1; + + value.first ()->recycler (0, 0); + + value.first ()->close (); + + return 0; +} + +///////////////////////////////////////////////////////////////////////////// + +template int +ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy::cleanup ( + CONTAINER &, + KEY *, + VALUE *value) +{ + return value->first ()->handle_close_i (); +} + +//////////////////////////////////////////////////////////////////////////// + +template int +ACE_Handler_Cleanup_Strategy::cleanup ( + CONTAINER &container, + KEY *key, + VALUE *value) +{ + // Remove the item from cache only if the handler isnt in use. + if ((*value)->active () == 0) + { + (*value)->close (); + + if (container.unbind (*key) == -1) + return -1; + + } + + return 0; +} + +//////////////////////////////////////////////////////////////////////////// + +template int +ACE_Null_Cleanup_Strategy::cleanup (CONTAINER &, + KEY *, + VALUE *) +{ + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_CLEANUP_STRATEGIES_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Cleanup_Strategies_T.h b/dep/ACE_wrappers/ace/Cleanup_Strategies_T.h new file mode 100644 index 000000000..ca51b47b1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Cleanup_Strategies_T.h @@ -0,0 +1,149 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Cleanup_Strategies_T.h + * + * $Id: Cleanup_Strategies_T.h 81388 2008-04-23 14:02:05Z johnnyw $ + * + * @author Kirthika Parameswaran + */ +//============================================================================= + + +#ifndef CLEANUP_STRATEGIES_H +#define CLEANUP_STRATEGIES_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// For linkers that cant grok long names. +#define ACE_Cleanup_Strategy ACLE + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Cleanup_Strategy + * + * @brief Defines a default strategy to be followed for cleaning up + * entries from a map which is the container. + * + * By default the entry to be cleaned up is removed from the + * container. + */ +template +class ACE_Cleanup_Strategy +{ + +public: + + /// Destructor. + virtual ~ACE_Cleanup_Strategy (void); + + /// The method which will do the cleanup of the entry in the container. + virtual int cleanup (CONTAINER &container, KEY *key, VALUE *value); +}; + +////////////////////////////////////////////////////////////////////// +#define ACE_Recyclable_Handler_Cleanup_Strategy ARHCLE + +/** + * @class ACE_Recyclable_Handler_Cleanup_Strategy + * + * @brief Defines a strategy to be followed for cleaning up + * entries which are svc_handlers from a container. + * + * The entry to be cleaned up is removed from the container. + * Here, since we are dealing with svc_handlers specifically, we + * perform a couple of extra operations. @note To be used when + * the handler is recyclable. + */ +template +class ACE_Recyclable_Handler_Cleanup_Strategy : public ACE_Cleanup_Strategy +{ + +public: + + /// The method which will do the cleanup of the entry in the container. + virtual int cleanup (CONTAINER &container, KEY *key, VALUE *value); +}; + +////////////////////////////////////////////////////////////////////// +#define ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy ARRHCLE + +/** + * @class ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy + * + * @brief Defines a strategy to be followed for cleaning up + * entries which are svc_handlers from a container. + * + * The entry to be cleaned up is removed from the container. + * Here, since we are dealing with recyclable svc_handlers with + * addresses which are refcountable specifically, we perform a + * couple of extra operations and do so without any locking. + */ +template +class ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy : public ACE_Cleanup_Strategy +{ +public: + /// The method which will do the cleanup of the entry in the container. + virtual int cleanup (CONTAINER &container, KEY *key, VALUE *value); +}; + +////////////////////////////////////////////////////////////////////// + +/** + * @class ACE_Handler_Cleanup_Strategy + * + * @brief Defines a strategy to be followed for cleaning up + * entries which are svc_handlers from a container. + * + * The entry to be cleaned up is removed from the container. + * Here, since we are dealing with svc_handlers specifically, we + * perform a couple of extra operations. @note This cleanup strategy + * should be used in the case when the handler has the caching + * attributes. + */ +template +class ACE_Handler_Cleanup_Strategy : public ACE_Cleanup_Strategy +{ +public: + /// The method which will do the cleanup of the entry in the container. + virtual int cleanup (CONTAINER &container, KEY *key, VALUE *value); +}; + +////////////////////////////////////////////////////////////////////// +#define ACE_Null_Cleanup_Strategy ANCLE + +/** + * @class ACE_Null_Cleanup_Strategy + * + * @brief Defines a do-nothing implementation of the cleanup strategy. + * + * This class simply does nothing at all! Can be used to nullify + * the effect of the Cleanup Strategy. + */ +template +class ACE_Null_Cleanup_Strategy : public ACE_Cleanup_Strategy +{ +public: + /// The dummy cleanup method. + virtual int cleanup (CONTAINER &container, KEY *key, VALUE *value); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Cleanup_Strategies_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Cleanup_Strategies_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* CLEANUP_STRATEGIES_H */ diff --git a/dep/ACE_wrappers/ace/Codecs.cpp b/dep/ACE_wrappers/ace/Codecs.cpp new file mode 100644 index 000000000..71491fe1c --- /dev/null +++ b/dep/ACE_wrappers/ace/Codecs.cpp @@ -0,0 +1,234 @@ +#include "ace/Codecs.h" +#include "ace/Log_Msg.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_ctype.h" + +ACE_RCSID (ace, + Codecs, + "$Id: Codecs.cpp 80826 2008-03-04 14:51:23Z wotte $") + +namespace +{ + // Just in case ... +#undef alphabet +#undef pad +#undef max_columns + + // Symbols which form the Base64 alphabet (Defined as per RFC 2045) + ACE_Byte const alphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + // The padding character used in the encoding + ACE_Byte const pad = '='; + + // Number of columns per line of encoded output (Can have a maximum + // value of 76). + int const max_columns = 72; +} + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +bool ACE_Base64::init_ = false; + +ACE_Byte ACE_Base64::decoder_[256]; + +ACE_Byte ACE_Base64::member_[256]; + +ACE_Byte* +ACE_Base64::encode (const ACE_Byte* input, + const size_t input_len, + size_t* output_len, + bool is_chunked) +{ + if (!ACE_Base64::init_) + ACE_Base64::init(); + + if (!input) + return 0; + + ACE_Byte* result = 0; + + size_t length = ((input_len + 2) / 3) * 4; + size_t num_lines = length / max_columns + 1; + length += num_lines + 1; + ACE_NEW_RETURN (result, ACE_Byte[length], 0); + + int char_count = 0; + int bits = 0; + size_t pos = 0; + int cols = 0; + + for (size_t i = 0; i < input_len; ++i) + { + bits += input[i]; + ++char_count; + + if (char_count == 3) + { + result[pos++] = alphabet[bits >> 18]; + result[pos++] = alphabet[(bits >> 12) & 0x3f]; + result[pos++] = alphabet[(bits >> 6) & 0x3f]; + result[pos++] = alphabet[bits & 0x3f]; + cols += 4; + if (cols == max_columns) { + if (is_chunked) + result[pos++] = '\n'; + cols = 0; + } + bits = 0; + char_count = 0; + } + else + { + bits <<= 8; + } + } + + if (char_count != 0) + { + bits <<= (16 - (8 * char_count)); + result[pos++] = alphabet[bits >> 18]; + result[pos++] = alphabet[(bits >> 12) & 0x3f]; + cols += 2; + if (char_count == 1) + { + result[pos++] = pad; + result[pos++] = pad; + cols += 2; + } + else + { + result[pos++] = alphabet[(bits >> 6) & 0x3f]; + result[pos++] = pad; + cols += 2; + } + } + + if (cols > 0 && is_chunked) + result[pos++] = '\n'; + + result[pos] = 0; + *output_len = pos; + return result; +} + +size_t +ACE_Base64::length (const ACE_Byte* input) +{ + if (!ACE_Base64::init_) + ACE_Base64::init(); + + ACE_Byte* ptr = const_cast (input); + while (*ptr != 0 && + (member_[*(ptr)] == 1 || *ptr == pad + || ACE_OS::ace_isspace (*ptr))) + ++ptr; + size_t len = ptr - input; + len = ((len + 3) / 4) * 3 + 1 ; + return len; +} + +ACE_Byte* +ACE_Base64::decode (const ACE_Byte* input, size_t* output_len) +{ + if (!ACE_Base64::init_) + ACE_Base64::init(); + + if (!input) + return 0; + + size_t result_len = ACE_Base64::length (input); + ACE_Byte* result = 0; + ACE_NEW_RETURN (result, ACE_Byte[result_len], 0); + + ACE_Byte* ptr = const_cast (input); + while (*ptr != 0 && + (member_[*(ptr)] == 1 || *ptr == pad + || ACE_OS::ace_isspace (*ptr))) + ++ptr; + size_t input_len = ptr - input; + + int char_count = 0; + int bits = 0; + size_t pos = 0; + + size_t i = 0; + for (; i < input_len; ++i) + { + if (input[i] == pad) + break; + if (!ACE_Base64::member_[input[i]]) + continue; + bits += decoder_[input[i]]; + ++char_count; + + if (char_count == 4) + { + result[pos++] = static_cast (bits >> 16); + result[pos++] = static_cast ((bits >> 8) & 0xff); + result[pos++] = static_cast (bits & 0xff); + bits = 0; + char_count = 0; + } + else + { + bits <<= 6; + } + } + + int errors = 0; + if ( i == input_len) + { + if (char_count) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Decoding incomplete: atleast %d bits truncated\n"), + (4 - char_count) * 6)); + ++errors; + } + } + else + { + switch (char_count) + { + case 1: + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Decoding incomplete: atleast 2 bits missing\n"))); + ++errors; + break; + case 2: + result[pos++] = static_cast (bits >> 10); + break; + case 3: + result[pos++] = static_cast (bits >> 16); + result[pos++] = static_cast ((bits >> 8) & 0xff); + break; + } + } + + if (errors) + { + delete[] result; + return 0; + } + result[pos] = 0; + *output_len = pos; + return result; +} + +void +ACE_Base64::init () +{ + if (!ACE_Base64::init_) + { + for (ACE_Byte i = 0; i < sizeof (alphabet); ++i) + { + ACE_Base64::decoder_[alphabet[i]] = i; + ACE_Base64::member_ [alphabet[i]] = 1; + } + ACE_Base64::init_ = true; + } + return; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Codecs.h b/dep/ACE_wrappers/ace/Codecs.h new file mode 100644 index 000000000..2c4227dd0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Codecs.h @@ -0,0 +1,121 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Codecs.h + * + * $Id: Codecs.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Krishnakumar B + * + * Codecs is a generic wrapper for various encoding and decoding + * mechanisms. Currently it includes Base64 content transfer-encoding as + * specified by RFC 2045, Multipurpose Internet Mail Extensions (MIME) Part + * One: Format of Internet Message Bodies. + * + */ +//============================================================================= + +#ifndef ACE_CODECS_H +#define ACE_CODECS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Basic_Types.h" +#include "ace/Global_Macros.h" + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Base64 + * + * @brief Encode/Decode a stream of bytes according to Base64 encoding. + * + * This class provides methods to encode or decode a stream of bytes + * to/from Base64 encoding. It doesn't convert the input stream to a + * canonical form before encoding. + * + */ +class ACE_Export ACE_Base64 +{ +public: + + //@{ + + /** + * Encodes a stream of bytes to Base64 data + * + * @param input Binary data in byte stream. + * @param input_len Length of the byte stream. + * @param output_len Length of the encoded Base64 byte stream. + * @param is_chunked If true, terminate 72 character blocks with newline + * @return Encoded Base64 data in byte stream or NULL if input data cannot + * be encoded. + */ + + static ACE_Byte* encode (const ACE_Byte* input, + const size_t input_len, + size_t* output_len, + bool is_chunked = true); + /** + * Decodes a stream of Base64 to bytes data + * + * @param input Encoded Base64 data in byte stream. + * @param output_len Length of the binary byte stream. + * @return Binary data in byte stream or NULL if input data cannot + * be encoded. + */ + static ACE_Byte* decode (const ACE_Byte* input, + size_t* output_len); + + /** + * Return the length of the encoded input data + * + * @param input Encoded Base64 data in byte stream. + * @return Length of the encoded Base64 data. + * + */ + static size_t length (const ACE_Byte* input); + + //@} + +protected: + + // Prevent default construction. + ACE_Base64 (void) {} + +private: + + // Preventing copying and assignment. + ACE_Base64 (ACE_Base64 const &); + ACE_Base64 & operator= (ACE_Base64 const &); + + /// Initialize the tables for encoding/decoding. + static void init (void); + +private: + + /// Alphabet used for decoding i.e decoder_[alphabet_[i = 0..63]] = i + static ACE_Byte decoder_[]; + + /// Alphabet used to check valid range of encoded input i.e + /// member_[alphabet_[0..63]] = 1 + static ACE_Byte member_[]; + + /// Boolean to denote whether initialization is complete + static bool init_; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_CODECS_H */ diff --git a/dep/ACE_wrappers/ace/Codeset_IBM1047.cpp b/dep/ACE_wrappers/ace/Codeset_IBM1047.cpp new file mode 100644 index 000000000..91582cf4e --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_IBM1047.cpp @@ -0,0 +1,309 @@ + +//============================================================================= +/** + * @file Codeset_IBM1047.cpp + * + * $Id: Codeset_IBM1047.cpp 81661 2008-05-09 12:05:34Z johnnyw $ + * + * Defines the arrays required to convert between ISO8859 (aka + * Latin/1) and IBM1047 (aka EBCDIC). + * + * + * @author Jim Rogers (jrogers@viasoft.com) + */ +//============================================================================= + + +#include "ace/Codeset_IBM1047.h" + +#if defined (ACE_HAS_EBCDIC) + +ACE_RCSID (ace, + Codeset_IBM1047, + "$Id: Codeset_IBM1047.cpp 81661 2008-05-09 12:05:34Z johnnyw $") + +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" + +namespace +{ + char const to_IBM1047[] = + { + "\x00\x01\x02\x03\x37\x2D\x2E\x2F\x16\x05\x25\x0B\x0C\x0D\x0E\x0F" // 00-0F + "\x10\x11\x12\x13\x3C\x3D\x32\x26\x18\x19\x3F\x27\x22\x1D\x35\x1F" // 10-1F + "\x40\x5A\x7F\x7B\x5B\x6C\x50\x7D\x4D\x5D\x5C\x4E\x6B\x60\x4B\x61" // 20-2F + "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\x7A\x5E\x4C\x7E\x6E\x6F" // 30-3F + "\x7C\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xD1\xD2\xD3\xD4\xD5\xD6" // 40-4F + "\xD7\xD8\xD9\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xAD\xE0\xBD\x5F\x6D" // 50-5F + "\x79\x81\x82\x83\x84\x85\x86\x87\x88\x89\x91\x92\x93\x94\x95\x96" // 60-6F + "\x97\x98\x99\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xC0\x4F\xD0\xA1\x07" // 70-7F + "\x43\x20\x21\x1C\x23\xEB\x24\x9B\x71\x28\x38\x49\x90\xBA\xEC\xDF" // 80-8F + "\x45\x29\x2A\x9D\x72\x2B\x8A\x9A\x67\x56\x64\x4A\x53\x68\x59\x46" // 90-9F + "\xEA\xDA\x2C\xDE\x8B\x55\x41\xFE\x58\x51\x52\x48\x69\xDB\x8E\x8D" // A0-AF + "\x73\x74\x75\xFA\x15\xB0\xB1\xB3\xB4\xB5\x6A\xB7\xB8\xB9\xCC\xBC" // B0-BF + "\xAB\x3E\x3B\x0A\xBF\x8F\x3A\x14\xA0\x17\xCB\xCA\x1A\x1B\x9C\x04" // C0-CF + "\x34\xEF\x1E\x06\x08\x09\x77\x70\xBE\xBB\xAC\x54\x63\x65\x66\x62" // D0-DF + "\x30\x42\x47\x57\xEE\x33\xB6\xE1\xCD\xED\x36\x44\xCE\xCF\x31\xAA" // E0-EF + "\xFC\x9E\xAE\x8C\xDD\xDC\x39\xFB\x80\xAF\xFD\x78\x76\xB2\x9F\xFF" // F0-FF +}; + + char const from_IBM1047[] = + { + "\x00\x01\x02\x03\xCF\x09\xD3\x7F\xD4\xD5\xC3\x0B\x0C\x0D\x0E\x0F" // 00-0F + "\x10\x11\x12\x13\xC7\xB4\x08\xC9\x18\x19\xCC\xCD\x83\x1D\xD2\x1F" // 10-1F + "\x81\x82\x1C\x84\x86\x0A\x17\x1B\x89\x91\x92\x95\xA2\x05\x06\x07" // 20-2F + "\x20\xEE\x16\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xC1\x1A" // 30-3F + "\x20\xA6\xE1\x80\xEB\x90\x9F\xE2\xAB\x8B\x9B\x2E\x3C\x28\x2B\x7C" // 40-4F + "\x26\xA9\xAA\x9C\xDB\xA5\x99\xE3\xA8\x9E\x21\x24\x2A\x29\x3B\x5E" // 50-5F + "\x2D\x2F\xDF\xDC\x9A\xDD\xDE\x98\x9D\xAC\xBA\x2C\x25\x5F\x3E\x3F" // 60-6F + "\xD7\x88\x94\xB0\xB1\xB2\xFC\xD6\xFB\x60\x3A\x23\x40\x27\x3D\x22" // 70-7F + "\xF8\x61\x62\x63\x64\x65\x66\x67\x68\x69\x96\xA4\xF3\xAF\xAE\xC5" // 80-8F + "\x8C\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x97\x87\xCE\x93\xF1\xFE" // 90-9F + "\xC8\x7E\x73\x74\x75\x76\x77\x78\x79\x7A\xEF\xC0\xDA\x5B\xF2\xF9" // A0-AF + "\xB5\xB6\xFD\xB7\xB8\xB9\xE6\xBB\xBC\xBD\x8D\xD9\xBF\x5D\xD8\xC4" // B0-BF + "\x7B\x41\x42\x43\x44\x45\x46\x47\x48\x49\xCB\xCA\xBE\xE8\xEC\xED" // C0-CF + "\x7D\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\xA1\xAD\xF5\xF4\xA3\x8F" // D0-DF + "\x5C\xE7\x53\x54\x55\x56\x57\x58\x59\x5A\xA0\x85\x8E\xE9\xE4\xD1" // E0-EF + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\xB3\xF7\xF0\xFA\xA7\xFF" // F0-FF + }; +} + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_IBM1047_ISO8859::ACE_IBM1047_ISO8859 (void) +{ +} + +ACE_IBM1047_ISO8859::~ACE_IBM1047_ISO8859 (void) +{ +} + +ACE_CDR::ULong +ACE_IBM1047_ISO8859::ncs () +{ + return 0x10020417; +} + +ACE_CDR::ULong +ACE_IBM1047_ISO8859::tcs () +{ + return 0x00010001; +} + +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::read_char (ACE_InputCDR &in, + ACE_CDR::Char &x) +{ + if (this->read_1 (in, reinterpret_cast (&x))) + { + x = to_IBM1047[x]; + return 1; + } + return 0; +} + +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::read_string (ACE_InputCDR& in, + ACE_CDR::Char *& x) +{ + ACE_CDR::ULong len; + + in.read_ulong (len); + + if (len > 0) + { + ACE_NEW_RETURN (x, + ACE_CDR::Char[len], + 0); + + if (this->read_char_array (in, x, len)) + return 1; + + delete [] x; + } + + x = 0; + return 0; +} + +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::read_char_array (ACE_InputCDR& in, + ACE_CDR::Char* x, + ACE_CDR::ULong len) +{ + if (this->read_array (in, + x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + len)) + { + for (ACE_CDR::ULong i = 0; i != len; ++i) + x[i] = to_IBM1047[x[i]]; + + return 1; + } + + return 0; +} + +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::write_char (ACE_OutputCDR& out, + ACE_CDR::Char x) +{ + return + this->write_1 (out, + reinterpret_cast (&from_IBM1047[x])); +} + +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::write_string (ACE_OutputCDR& out, + ACE_CDR::ULong len, + const ACE_CDR::Char* x) +{ + if (out.write_ulong (len + 1)) + return this->write_char_array (out, x, len + 1); + return 0; +} + +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::write_char_array (ACE_OutputCDR& out, + const ACE_CDR::Char* x, + ACE_CDR::ULong len) +{ + char *buf = 0; + if (this->adjust (out, len, 1, buf) == 0) + { + ACE_OS::memcpy (buf, x, len); + + for (ACE_CDR::ULong i = 0; i != len; ++i) + buf[i] = from_IBM1047[buf[i]]; + + return 1; + } + + this->good_bit(out, 0); + return 0; +} + +// **************************************************************** + +ACE_ISO8859_IBM1047::ACE_ISO8859_IBM1047 (void) +{ +} + +ACE_ISO8859_IBM1047::~ACE_ISO8859_IBM1047 (void) +{ +} + +ACE_CDR::ULong +ACE_ISO8859_IBM1047::ncs () +{ + return 0x00010001; +} + +ACE_CDR::ULong +ACE_ISO8859_IBM1047::tcs () +{ + return 0x10020417; +} + +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::read_char (ACE_InputCDR& in, + ACE_CDR::Char& x) +{ + if (this->read_1 (in, reinterpret_cast (&x))) + { + x = from_IBM1047[x]; + return 1; + } + return 0; +} + +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::read_string (ACE_InputCDR &in, + ACE_CDR::Char *&x) +{ + ACE_CDR::ULong len; + + in.read_ulong (len); + + if (len > 0) + { + ACE_NEW_RETURN (x, + ACE_CDR::Char[len], + 0); + + if (this->read_char_array (in, x, len)) + return 1; + + delete [] x; + } + + x = 0; + return 0; +} + +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::read_char_array (ACE_InputCDR &in, + ACE_CDR::Char *x, + ACE_CDR::ULong len) +{ + if (this->read_array (in, + x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + len)) + { + for (ACE_CDR::ULong i = 0; i != len; ++i) + x[i] = from_IBM1047[x[i]]; + + return 1; + } + + return 0; +} + +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::write_char (ACE_OutputCDR &out, + ACE_CDR::Char x) +{ + return + this->write_1 (out, + reinterpret_cast (&to_IBM1047[x])); +} + +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::write_string (ACE_OutputCDR& out, + ACE_CDR::ULong len, + const ACE_CDR::Char* x) +{ + if (out.write_ulong (len + 1)) + return this->write_char_array (out, x, len + 1); + else + return 0; +} + +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::write_char_array (ACE_OutputCDR &out, + const ACE_CDR::Char *x, + ACE_CDR::ULong len) +{ + char *buf = 0; + + if (this->adjust (out, len, 1, buf) == 0) + { + ACE_OS::memcpy (buf, x, len); + + for (ACE_CDR::ULong i = 0; i != len; ++i) + buf[i] = to_IBM1047[buf[i]]; + + return 1; + } + + this->good_bit (out, 0); + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_EBCDIC */ diff --git a/dep/ACE_wrappers/ace/Codeset_IBM1047.h b/dep/ACE_wrappers/ace/Codeset_IBM1047.h new file mode 100644 index 000000000..3caa8881f --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_IBM1047.h @@ -0,0 +1,127 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Codeset_IBM1047.h + * + * $Id: Codeset_IBM1047.h 81388 2008-04-23 14:02:05Z johnnyw $ + * + * Declares the arrays required to convert between ISO8859 (aka + * Latin/1) and IBM1047 (aka EBCDIC). + * + * @author Jim Rogers (jrogers@viasoft.com) + */ +//============================================================================= + + +#ifndef ACE_CODESET_IMB1047_H +#define ACE_CODESET_IMB1047_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_EBCDIC) + +#include "ace/CDR_Stream.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// **************************************************************** + +/** + * @class ACE_IBM1047_ISO8859 + * + * @brief Codeset translation specialization. + * + * This class performs the codeset translation: + * - Native: IBM_1047 (i.e. EBCDIC) + * - Stream: ISO-8859 (i.e. Latin/1) + */ +class ACE_Export ACE_IBM1047_ISO8859 : public ACE_Char_Codeset_Translator +{ +public: + /// A do nothing constructor. + ACE_IBM1047_ISO8859 (void); + + /// Virtual destruction + virtual ~ACE_IBM1047_ISO8859 (void); + + // = Documented in $ACE_ROOT/ace/CDR_Stream.h + virtual ACE_CDR::Boolean read_char (ACE_InputCDR &, + ACE_CDR::Char &); + virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, + ACE_CDR::Char *&); + virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR &, + ACE_CDR::Char *, + ACE_CDR::ULong); + virtual ACE_CDR::Boolean write_char (ACE_OutputCDR &, + ACE_CDR::Char); + virtual ACE_CDR::Boolean write_string (ACE_OutputCDR &, + ACE_CDR::ULong, + const ACE_CDR::Char *); + virtual ACE_CDR::Boolean write_char_array (ACE_OutputCDR &, + const ACE_CDR::Char *, + ACE_CDR::ULong); + + /// Return the native codeset ID as defined in the OSF code and character + /// set registry, 0x10020417 + virtual ACE_CDR::ULong ncs (); + /// Return the translated codeset ID as defined in the OSF code and character + /// set registry, 0x00010001 + virtual ACE_CDR::ULong tcs (); +}; + +/** + * @class ACE_ISO8859_IBM1047 + * + * @brief Codeset translation specialization. + * + * This class performs the codeset translation: + * - Native: ISO-8859 (i.e. Latin/1) + * - Stream: IBM-1047 (i.e. EBCDIC) + */ +class ACE_Export ACE_ISO8859_IBM1047 : public ACE_Char_Codeset_Translator +{ +public: + /// A do nothing constructor. + ACE_ISO8859_IBM1047 (void); + + /// Virtual destruction + virtual ~ACE_ISO8859_IBM1047 (void); + + // = Documented in $ACE_ROOT/ace/CDR_Stream.h + virtual ACE_CDR::Boolean read_char (ACE_InputCDR &, + ACE_CDR::Char &); + virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, + ACE_CDR::Char *&); + virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR &, + ACE_CDR::Char *, + ACE_CDR::ULong); + virtual ACE_CDR::Boolean write_char (ACE_OutputCDR &, + ACE_CDR::Char); + virtual ACE_CDR::Boolean write_string (ACE_OutputCDR &, + ACE_CDR::ULong, + const ACE_CDR::Char *); + virtual ACE_CDR::Boolean write_char_array (ACE_OutputCDR &, + const ACE_CDR::Char *, + ACE_CDR::ULong); + + /// Return the native codeset ID as defined in the OSF code and character + /// set registry, 0x00010001 + virtual ACE_CDR::ULong ncs (); + /// Return the translated codeset ID as defined in the OSF code and character + /// set registry, 0x10020417 + virtual ACE_CDR::ULong tcs (); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_EBCDIC */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CODESET_IMB1047_H */ diff --git a/dep/ACE_wrappers/ace/Codeset_Registry.cpp b/dep/ACE_wrappers/ace/Codeset_Registry.cpp new file mode 100644 index 000000000..c23ef3723 --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_Registry.cpp @@ -0,0 +1,111 @@ +//============================================================================= +/** + * @file Codeset_Registry.cpp + * + * $Id: Codeset_Registry.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * emulated codset regstry functions + * + * + * @author Phil Mesnier + */ +//============================================================================= + +#include "ace/Codeset_Registry.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" + +// $Id: Codeset_Registry.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#if !defined (__ACE_INLINE__) +#include "ace/Codeset_Registry.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Codeset_Registry, + "$Id: Codeset_Registry.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +int +ACE_Codeset_Registry::locale_to_registry_i (const ACE_CString &locale, + ACE_CDR::ULong &codeset_id, + ACE_CDR::UShort *num_sets, + ACE_CDR::UShort **char_sets) +{ + registry_entry const *element = 0; + for (size_t i = 0; element == 0 && i < num_registry_entries_; i++) + if (ACE_OS::strcmp (registry_db_[i].loc_name_, locale.c_str ()) == 0) + element = ®istry_db_[i]; + if (element == 0) + return 0; + codeset_id = element->codeset_id_; + if (num_sets != 0) + *num_sets = element->num_sets_; + if (char_sets != 0) + { + ACE_NEW_RETURN (*char_sets,ACE_CDR::UShort[element->num_sets_],0); + ACE_OS::memcpy (*char_sets, element->char_sets_, + element->num_sets_ * sizeof (ACE_CDR::UShort)); + } + return 1; +} + +int +ACE_Codeset_Registry::registry_to_locale_i (ACE_CDR::ULong codeset_id, + ACE_CString &locale, + ACE_CDR::UShort *num_sets, + ACE_CDR::UShort **char_sets) +{ + registry_entry const *element = 0; + for (size_t i = 0; element == 0 && i < num_registry_entries_; i++) + if (codeset_id == registry_db_[i].codeset_id_) + element = ®istry_db_[i]; + if (element == 0) + return 0; + locale.set (element->loc_name_); + if (num_sets != 0) + *num_sets = element->num_sets_; + if (char_sets != 0) + { + ACE_NEW_RETURN (*char_sets,ACE_CDR::UShort[element->num_sets_],0); + ACE_OS::memcpy (*char_sets, element->char_sets_, + element->num_sets_ * sizeof (ACE_CDR::UShort)); + } + return 1; +} + +int +ACE_Codeset_Registry::is_compatible_i (ACE_CDR::ULong codeset_id, + ACE_CDR::ULong other) +{ + registry_entry const *lhs = 0; + registry_entry const *rhs = 0; + for (size_t i = 0; (lhs == 0 || rhs == 0) && i < num_registry_entries_; i++) + { + if (codeset_id == registry_db_[i].codeset_id_) + lhs = ®istry_db_[i]; + if (other == registry_db_[i].codeset_id_) + rhs = ®istry_db_[i]; + } + + if (lhs == 0 || rhs == 0) + return 0; + + for (ACE_CDR::UShort l = 0; l < lhs->num_sets_; l++) + for (ACE_CDR::UShort r = 0; r < rhs->num_sets_; r++) + if (rhs->char_sets_[r] == lhs->char_sets_[l]) + return 1; + return 0; +} + +ACE_CDR::Short +ACE_Codeset_Registry::get_max_bytes_i (ACE_CDR::ULong codeset_id) +{ + for (size_t i = 0; i < num_registry_entries_; i++) + if (codeset_id == registry_db_[i].codeset_id_) + return registry_db_[i].max_bytes_; + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Codeset_Registry.h b/dep/ACE_wrappers/ace/Codeset_Registry.h new file mode 100644 index 000000000..e72c435f8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_Registry.h @@ -0,0 +1,104 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file Codeset_Registry.h + * + * $Id: Codeset_Registry.h 81348 2008-04-14 09:00:32Z johnnyw $ + * + * ACE wrapper around access functions for the OSF's DCE codeset registry + * access functions + * + * For environments that intrinsicly support the DCE defined access functions, + * the methods in this class are simply wrappers. On other platforms, emulation + * is provided. The motivation for this class is to support interoperability + * via translators and the CDR streams, primarily in TAO, but this capability + * is not restricted to CORBA. + * + * The emulated functionality supports Open Group RFC #40, currently RFC 40.2, + * www.opengroup.org/tech/rfc/rfc40.2.html + * + * @author Phil Mesnier + */ +//============================================================================= + +#ifndef ACE_CODESET_REGISTRY_H +#define ACE_CODESET_REGISTRY_H + +#include /**/ "ace/pre.h" +#include "ace/SString.h" +#include "ace/CDR_Base.h" +#include "ace/Codeset_Symbols.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_DCE_CODESET_REGISTRY) +#include /**/ +#endif /* ACE_HAS_DCE_CODESET_REGISTRY */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Export ACE_Codeset_Registry +{ +public: + + /// Based on a locale string, find the registry value and optional codeset + /// collection. This wraps the dce_cs_loc_to_rgy function, or emulates it. + static int locale_to_registry (const ACE_CString &locale, + ACE_CDR::ULong &codeset_id, + ACE_CDR::UShort * = 0, + ACE_CDR::UShort ** = 0); + + /// Based on a registry value, find the locale string and optional codeset + /// collection. This wraps the dce_cs_rgy_to_loc function, or emulates it. + static int registry_to_locale (ACE_CDR::ULong codeset_id, + ACE_CString &locale, + ACE_CDR::UShort * = 0, + ACE_CDR::UShort ** = 0); + + /// Tell if two codesets are compatible. This wraps the + /// rpc_cs_char_set_compat_check function. + static int is_compatible (ACE_CDR::ULong codeset_id, + ACE_CDR::ULong other); + + /// Return the max number of bytes required to represent a single character. + /// This wraps the rpc_rgy_get_max_bytes function. + static ACE_CDR::Short get_max_bytes (ACE_CDR::ULong codeset_id); + + enum {max_charsets_ = 5}; +protected: + typedef struct { + const char * desc_; + const char * loc_name_; + ACE_CDR::ULong codeset_id_; + ACE_CDR::UShort num_sets_; + ACE_CDR::UShort char_sets_[max_charsets_]; + ACE_CDR::UShort max_bytes_; + } registry_entry; + +private: + static size_t const num_registry_entries_; + static registry_entry const registry_db_[]; + + static int locale_to_registry_i (const ACE_CString &locale, + ACE_CDR::ULong &codeset_id, + ACE_CDR::UShort * = 0, + ACE_CDR::UShort ** = 0); + static int registry_to_locale_i (ACE_CDR::ULong codeset_id, + ACE_CString &locale, + ACE_CDR::UShort * = 0, + ACE_CDR::UShort ** = 0); + static int is_compatible_i (ACE_CDR::ULong codeset_id, + ACE_CDR::ULong other); + static ACE_CDR::Short get_max_bytes_i (ACE_CDR::ULong codeset_id); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Codeset_Registry.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_CODESET_REGISTRY_H */ diff --git a/dep/ACE_wrappers/ace/Codeset_Registry.inl b/dep/ACE_wrappers/ace/Codeset_Registry.inl new file mode 100644 index 000000000..4419cf5e7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_Registry.inl @@ -0,0 +1,102 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file Codeset_Registry.inl + * + * $Id: Codeset_Registry.inl 80826 2008-03-04 14:51:23Z wotte $ + * + * ACE wrapper around access functions for the OSF's DCE codeset registry + * access functions - the inline functions either call the system supplied + * DCE based codeset regsitry function, or calls the emulation + * + * + * @author Phil Mesnier + */ +//============================================================================= + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +int +ACE_Codeset_Registry::locale_to_registry(const ACE_CString &locale, + ACE_CDR::ULong &codeset_id, + ACE_CDR::UShort *num_sets, + ACE_CDR::UShort **char_sets) +{ +#if defined (ACE_HAS_DCE_CODESET_REGISTRY) + error_status_t result; + dce_cs_loc_to_rgy (locale.c_str(), + &codeset_id, + num_sets, + char_sets, + &result); + return (result == dce_cs_c_ok) ? 1 : 0; +#else + return ACE_Codeset_Registry::locale_to_registry_i (locale, + codeset_id, + num_sets, + char_sets); +#endif /* ACE_HAS_DCE_CODESET_REGISTRY */ +} + +// based on a registry value, find the locale string and optional codeset +// collection. This wraps the dce_cs_rgy_to_loc function, or emulates it. +ACE_INLINE +int +ACE_Codeset_Registry::registry_to_locale(ACE_CDR::ULong codeset_id, + ACE_CString &locale, + ACE_CDR::UShort *num_sets, + ACE_CDR::UShort **char_sets) +{ +#if defined (ACE_HAS_DCE_CODESET_REGISTRY) + error_status_t result; + char *buffer; + dce_cs_rgy_to_loc (codeset_id, + &buffer, + num_sets, + char_sets, + &result); + locale.set(buffer); // does a copy :-( + free (buffer); + return (result == dce_cs_c_ok) ? 1 : 0; +#else + return ACE_Codeset_Registry::registry_to_locale_i (codeset_id, + locale, + num_sets, + char_sets); +#endif /* ACE_HAS_DCE_CODESET_REGISTRY */ +} + +// Tell if two codesets are compatible. This wraps the +// rpc_cs_char_set_compat_check function. +ACE_INLINE +int +ACE_Codeset_Registry::is_compatible (ACE_CDR::ULong codeset_id, + ACE_CDR::ULong other) +{ +#if defined (ACE_HAS_DCE_CODESET_REGISTRY) + error_status_t result; + rpc_cs_char_set_compat_check(codeset_id,other,&result); + return (result == rpc_s_ok) ? 1 : 0; +#else + return ACE_Codeset_Registry::is_compatible_i (codeset_id,other); +#endif /* ACE_HAS_DCE_CODESET_REGISTRY */ +} + +// Return the max number of bytes required to represent a single character. +// This wraps the rpc_rgy_get_max_bytes function. +ACE_INLINE +ACE_CDR::Short +ACE_Codeset_Registry::get_max_bytes (ACE_CDR::ULong codeset_id) +{ +#if defined (ACE_HAS_DCE_CODESET_REGISTRY) + error_status_t result; + short max_bytes; + rpc_rgy_get_max_bytes(codeset_id,&max_bytes,&result); + return (result == rpc_s_ok) ? (short)max_bytes : 0; +#else + return ACE_Codeset_Registry::get_max_bytes_i (codeset_id); +#endif /* ACE_HAS_DCE_CODESET_REGISTRY */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Codeset_Registry_db.cpp b/dep/ACE_wrappers/ace/Codeset_Registry_db.cpp new file mode 100644 index 000000000..32b38631c --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_Registry_db.cpp @@ -0,0 +1,33 @@ +/* $Id: Codeset_Registry_db.cpp 81756 2008-05-22 09:47:33Z johnnyw $ + * Codeset registry DB, generated Fri Feb 28 21:01:30 2003 + * source: code_set_registry1.2g.txt + * + * To populate the registry_db, construct a codeset registry text file based + * on the OSF's Character and Code Set Registry. See DCE RFC 40.1 for details + * on obtaining the full text for the current registry. Once you have composed + * a text file containing all the desired codeset information, build and run + * mkcsregdb. The source is in $ACE_ROOT/apps/mkcsregdb. It will generate a new + * copy of this file, with the registry_db_ array properly initialized. + */ + +#include "ace/Codeset_Registry.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Codeset_Registry::registry_entry const +ACE_Codeset_Registry::registry_db_[] = +{ + {"ISO/IEC 10646-1:1993; UCS-2, Level 1","UCS-2",0x00010100,1,{0x1000},2}, + {"ISO 8859-1:1987; Latin Alphabet No. 1","ISO8859_1",0x00010001,1,{0x0011},1}, + {"IBM-1047 (CCSID 01047); Latin-1 Open System","EBCDIC",0x10020417,1,{0x0011},1}, + {"ISO/IEC 10646-1:1993; UCS-4, Level 1","UCS-4",0x00010104,1,{0x1000},4}, + {"ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form","UTF-16",0x00010109,1,{0x1000},2}, + {"X/Open UTF-8; UCS Transformation Format 8 (UTF-8)","UTF-8",0x05010001,1,{0x1000},6}, + {"ISO/IEC 8859-5:1988; Latin-Cyrillic Alphabet","ISO-8859-5",0x00010005,1,{0x0015},1}, + {"IBM-1251 (CCSID 01251); MS Windows Cyrillic","CP1251",0x100204e3,1,{0x0015},1}, + {"IBM-855 (CCSID 04951); Cyrillic Personal Computer","CP855",0x10021357,1,{0x0015},1} +}; + +size_t const ACE_Codeset_Registry::num_registry_entries_ = 9; + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Codeset_Symbols.h b/dep/ACE_wrappers/ace/Codeset_Symbols.h new file mode 100644 index 000000000..6ffe198c1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Codeset_Symbols.h @@ -0,0 +1,220 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Codeset_Symbols.h + * + * $Id: Codeset_Symbols.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Symbolic names for codeset ids. + * + * @author Dale Wilson (wilson_d@ociweb.com) + */ +//============================================================================= +#ifndef CODESET_SYMBOLS_H +#define CODESET_SYMBOLS_H + +// These numbers are assigned by the OpenGroup, a database is +// available at +// +// ftp://ftp.opengroup.org/pub/code_set_registry/ +// +// Alas, the database is in a semi-regular text file -- difficult to use. +// The following C/C++-friendly version of the codeset ids was captured +// from Version 1.2g of the registry. +// +#define ACE_CODESET_ID_ISO_8859_1 0x00010001U +#define ACE_CODESET_ID_ISO_8859_2 0x00010002U +#define ACE_CODESET_ID_ISO_8859_3 0x00010003U +#define ACE_CODESET_ID_ISO_8859_4 0x00010004U +#define ACE_CODESET_ID_ISO_8859_5 0x00010005U +#define ACE_CODESET_ID_ISO_8859_6 0x00010006U +#define ACE_CODESET_ID_ISO_8859_7 0x00010007U +#define ACE_CODESET_ID_ISO_8859_8 0x00010008U +#define ACE_CODESET_ID_ISO_8859_9 0x00010009U +#define ACE_CODESET_ID_ISO_8859_10 0x0001000AU +#define ACE_CODESET_ID_ISO_8859_15 0x0001000FU +#define ACE_CODESET_ID_ISO_646 0x00010020U +#define ACE_CODESET_ID_ISO_UCS_2_LEVEL_1 0x00010100U +#define ACE_CODESET_ID_ISO_UCS_2_LEVEL_2 0x00010101U +#define ACE_CODESET_ID_ISO_UCS_2_LEVEL_3 0x00010102U +#define ACE_CODESET_ID_ISO_UCS_4_LEVEL_1 0x00010104U +#define ACE_CODESET_ID_ISO_UCS_4_LEVEL_2 0x00010105U +#define ACE_CODESET_ID_ISO_UCS_4_LEVEL_3 0x00010106U +#define ACE_CODESET_ID_ISO_UTF_8 0x00010108U +#define ACE_CODESET_ID_ISO_UTF_16 0x00010109U +#define ACE_CODESET_ID_JIS_X0201 0x00030001U +#define ACE_CODESET_ID_JIS_X0208_1978 0x00030004U +#define ACE_CODESET_ID_JIS_X0208_1983 0x00030005U +#define ACE_CODESET_ID_JIS_X0208_1990 0x00030006U +#define ACE_CODESET_ID_JIS_X0212 0x0003000AU +#define ACE_CODESET_ID_JIS_EUCJP 0x00030010U +#define ACE_CODESET_ID_KS_C5601 0x00040001U +#define ACE_CODESET_ID_KS_C5657 0x00040002U +#define ACE_CODESET_ID_KS_EUCKR 0x0004000AU +#define ACE_CODESET_ID_CNS_11643_1986 0x00050001U +#define ACE_CODESET_ID_CNS_11643_1992 0x00050002U +#define ACE_CODESET_ID_CNS_EUCTW_1991 0x0005000AU +#define ACE_CODESET_ID_CNS_EUCTW_1993 0x00050010U +#define ACE_CODESET_ID_TIS_620_25290X000B0001U +#define ACE_CODESET_ID_TTB_CCDC 0x000D0001U +#define ACE_CODESET_ID_OSF_JAPANESE_UJIS 0x05000010U +#define ACE_CODESET_ID_OSF_JAPANESE_SJIS_1 0x05000011U +#define ACE_CODESET_ID_OSF_JAPANESE_SJIS_2 0x05000012U +#define ACE_CODESET_ID_XOPEN_UTF_8 0x05010001U +#define ACE_CODESET_ID_JVC_EUCJP 0x05020001U +#define ACE_CODESET_ID_JVC_SJIS 0x05020002U +#define ACE_CODESET_ID_DEC_KANJI 0x10000001U +#define ACE_CODESET_ID_SUPER_DEC_KANJI 0x10000002U +#define ACE_CODESET_ID_DEC_SHIFT_JIS 0x10000003U +#define ACE_CODESET_ID_HP_ROMAN8 0x10010001U +#define ACE_CODESET_ID_HP_KANA8 0x10010002U +#define ACE_CODESET_ID_HP_ARABIC8 0x10010003U +#define ACE_CODESET_ID_HP_GREEK8 0x10010004U +#define ACE_CODESET_ID_HP_HEBREW8 0x10010005U +#define ACE_CODESET_ID_HP_TURKISH8 0x10010006U +#define ACE_CODESET_ID_HP15CN 0x10010007U +#define ACE_CODESET_ID_HP_BIG5 0x10010008U +#define ACE_CODESET_ID_HP_JAPANESE15__SJIS_ 0x10010009U +#define ACE_CODESET_ID_HP_SJISHI 0x1001000AU +#define ACE_CODESET_ID_HP_SJISPC 0x1001000BU +#define ACE_CODESET_ID_HP_UJIS 0x1001000CU +#define ACE_CODESET_ID_IBM_037 0x10020025U +#define ACE_CODESET_ID_IBM_273 0x10020111U +#define ACE_CODESET_ID_IBM_277 0x10020115U +#define ACE_CODESET_ID_IBM_278 0x10020116U +#define ACE_CODESET_ID_IBM_280 0x10020118U +#define ACE_CODESET_ID_IBM_282 0x1002011AU +#define ACE_CODESET_ID_IBM_284 0x1002011CU +#define ACE_CODESET_ID_IBM_285 0x1002011DU +#define ACE_CODESET_ID_IBM_290 0x10020122U +#define ACE_CODESET_ID_IBM_297 0x10020129U +#define ACE_CODESET_ID_IBM_300 0x1002012CU +#define ACE_CODESET_ID_IBM_301 0x1002012DU +#define ACE_CODESET_ID_IBM_420 0x100201A4U +#define ACE_CODESET_ID_IBM_424 0x100201A8U +#define ACE_CODESET_ID_IBM_437 0x100201B5U +#define ACE_CODESET_ID_IBM_500 0x100201F4U +#define ACE_CODESET_ID_IBM_833 0x10020341U +#define ACE_CODESET_ID_IBM_834 0x10020342U +#define ACE_CODESET_ID_IBM_835 0x10020343U +#define ACE_CODESET_ID_IBM_836 0x10020344U +#define ACE_CODESET_ID_IBM_837 0x10020345U +#define ACE_CODESET_ID_IBM_838 0x10020346U +#define ACE_CODESET_ID_IBM_839 0x10020347U +#define ACE_CODESET_ID_IBM_850 0x10020352U +#define ACE_CODESET_ID_IBM_852 0x10020354U +#define ACE_CODESET_ID_IBM_855 0x10020357U +#define ACE_CODESET_ID_IBM_856 0x10020358U +#define ACE_CODESET_ID_IBM_857 0x10020359U +#define ACE_CODESET_ID_IBM_861 0x1002035DU +#define ACE_CODESET_ID_IBM_862 0x1002035EU +#define ACE_CODESET_ID_IBM_863 0x1002035FU +#define ACE_CODESET_ID_IBM_864 0x10020360U +#define ACE_CODESET_ID_IBM_866 0x10020362U +#define ACE_CODESET_ID_IBM_868 0x10020364U +#define ACE_CODESET_ID_IBM_869 0x10020365U +#define ACE_CODESET_ID_IBM_870 0x10020366U +#define ACE_CODESET_ID_IBM_871 0x10020367U +#define ACE_CODESET_ID_IBM_874 0x1002036AU +#define ACE_CODESET_ID_IBM_875 0x1002036BU +#define ACE_CODESET_ID_IBM_880 0x10020370U +#define ACE_CODESET_ID_IBM_891 0x1002037BU +#define ACE_CODESET_ID_IBM_896 0x10020380U +#define ACE_CODESET_ID_IBM_897 0x10020381U +#define ACE_CODESET_ID_IBM_903 0x10020387U +#define ACE_CODESET_ID_IBM_904 0x10020388U +#define ACE_CODESET_ID_IBM_918 0x10020396U +#define ACE_CODESET_ID_IBM_921 0x10020399U +#define ACE_CODESET_ID_IBM_922 0x1002039AU +#define ACE_CODESET_ID_IBM_926 0x1002039EU +#define ACE_CODESET_ID_IBM_927 0x1002039FU +#define ACE_CODESET_ID_IBM_928 0x100203A0U +#define ACE_CODESET_ID_IBM_929 0x100203A1U +#define ACE_CODESET_ID_IBM_930 0x100203A2U +#define ACE_CODESET_ID_IBM_932 0x100203A4U +#define ACE_CODESET_ID_IBM_933 0x100203A5U +#define ACE_CODESET_ID_IBM_934 0x100203A6U +#define ACE_CODESET_ID_IBM_935 0x100203A7U +#define ACE_CODESET_ID_IBM_936 0x100203A8U +#define ACE_CODESET_ID_IBM_937 0x100203A9U +#define ACE_CODESET_ID_IBM_938 0x100203AAU +#define ACE_CODESET_ID_IBM_939 0x100203ABU +#define ACE_CODESET_ID_IBM_941 0x100203ADU +#define ACE_CODESET_ID_IBM_942 0x100203AEU +#define ACE_CODESET_ID_IBM_943 0x100203AFU +#define ACE_CODESET_ID_IBM_946 0x100203B2U +#define ACE_CODESET_ID_IBM_947 0x100203B3U +#define ACE_CODESET_ID_IBM_948 0x100203B4U +#define ACE_CODESET_ID_IBM_949 0x100203B5U +#define ACE_CODESET_ID_IBM_950 0x100203B6U +#define ACE_CODESET_ID_IBM_951 0x100203B7U +#define ACE_CODESET_ID_IBM_955 0x100203BBU +#define ACE_CODESET_ID_IBM_964 0x100203C4U +#define ACE_CODESET_ID_IBM_970 0x100203CAU +#define ACE_CODESET_ID_IBM_1006 0x100203EEU +#define ACE_CODESET_ID_IBM_1025 0x10020401U +#define ACE_CODESET_ID_IBM_1026 0x10020402U +#define ACE_CODESET_ID_IBM_1027 0x10020403U +#define ACE_CODESET_ID_IBM_1040 0x10020410U +#define ACE_CODESET_ID_IBM_1041 0x10020411U +#define ACE_CODESET_ID_IBM_1043 0x10020413U +#define ACE_CODESET_ID_IBM_1046 0x10020416U +#define ACE_CODESET_ID_IBM_1047 0x10020417U +#define ACE_CODESET_ID_IBM_1088 0x10020440U +#define ACE_CODESET_ID_IBM_1097 0x10020449U +#define ACE_CODESET_ID_IBM_1098 0x1002044AU +#define ACE_CODESET_ID_IBM_1112 0x10020458U +#define ACE_CODESET_ID_IBM_1114 0x1002045AU +#define ACE_CODESET_ID_IBM_1115 0x1002045BU +#define ACE_CODESET_ID_IBM_1122 0x10020462U +#define ACE_CODESET_ID_IBM_1250 0x100204E2U +#define ACE_CODESET_ID_IBM_1251 0x100204E3U +#define ACE_CODESET_ID_IBM_1252 0x100204E4U +#define ACE_CODESET_ID_IBM_1253 0x100204E5U +#define ACE_CODESET_ID_IBM_1254 0x100204E6U +#define ACE_CODESET_ID_IBM_1255 0x100204E7U +#define ACE_CODESET_ID_IBM_1256 0x100204E8U +#define ACE_CODESET_ID_IBM_1257 0x100204E9U +#define ACE_CODESET_ID_IBM_1380 0x10020564U +#define ACE_CODESET_ID_IBM_1381 0x10020565U +#define ACE_CODESET_ID_IBM_1383 0x10020567U +#define ACE_CODESET_ID_IBM_4396 0x1002112CU +#define ACE_CODESET_ID_IBM_4946 0x10021352U +#define ACE_CODESET_ID_IBM_4948 0x10021354U +#define ACE_CODESET_ID_IBM_4951 0x10021357U +#define ACE_CODESET_ID_IBM_4952 0x10021358U +#define ACE_CODESET_ID_IBM_4953 0x10021359U +#define ACE_CODESET_ID_IBM_4960 0x10021360U +#define ACE_CODESET_ID_IBM_4964 0x10021364U +#define ACE_CODESET_ID_IBM_4965 0x10021365U +#define ACE_CODESET_ID_IBM_5026 0x100213A2U +#define ACE_CODESET_ID_IBM_5031 0x100213A7U +#define ACE_CODESET_ID_IBM_5035 0x100213ABU +#define ACE_CODESET_ID_IBM_5048 0x100213B8U +#define ACE_CODESET_ID_IBM_5049 0x100213B9U +#define ACE_CODESET_ID_IBM_5067 0x100213CBU +#define ACE_CODESET_ID_IBM_8612 0x100221A4U +#define ACE_CODESET_ID_IBM_9025 0x10022341U +#define ACE_CODESET_ID_IBM_9026 0x10022342U +#define ACE_CODESET_ID_IBM_9030 0x10022346U +#define ACE_CODESET_ID_IBM_9056 0x10022360U +#define ACE_CODESET_ID_IBM_9066 0x1002236AU +#define ACE_CODESET_ID_IBM_9125 0x100223A5U +#define ACE_CODESET_ID_IBM_25426 0x10026352U +#define ACE_CODESET_ID_IBM_25432 0x10026358U +#define ACE_CODESET_ID_IBM_1042 0x10026412U +#define ACE_CODESET_ID_IBM_28709 0x10027025U +#define ACE_CODESET_ID_IBM_33624 0x10028358U +#define ACE_CODESET_ID_IBM_33722 0x100283BAU +#define ACE_CODESET_ID_HTCSJIS 0x10030001U +#define ACE_CODESET_ID_HTCUJIS 0x10030002U +#define ACE_CODESET_ID_FUJITSU_U90 0x10040001U +#define ACE_CODESET_ID_FUJITSU_S90 0x10040002U +#define ACE_CODESET_ID_FUJITSU_R90 0x10040003U +#define ACE_CODESET_ID_EBCDIC_ASCII_AND_JEF 0x10040004U +#define ACE_CODESET_ID_EBCDIC_KATAKANA_AND_JEF 0x10040005U +#define ACE_CODESET_ID_EBCDIC_JAPANESE_ENGLISH_AND_JEF 0x10040006U + +#define ACE_CODESET_ID_TAO_BACKWARD_COMPATIBLE 0xf54414F0U +#endif // CODESET_SYMBOLS_H diff --git a/dep/ACE_wrappers/ace/Condition_Recursive_Thread_Mutex.cpp b/dep/ACE_wrappers/ace/Condition_Recursive_Thread_Mutex.cpp new file mode 100644 index 000000000..2a12b132f --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_Recursive_Thread_Mutex.cpp @@ -0,0 +1,129 @@ +// -*- C++ -*- + +/** + * @file Condition_Recursive_Thread_Mutex.cpp + * + * $Id: Condition_Recursive_Thread_Mutex.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt + */ + +#include "ace/Condition_Recursive_Thread_Mutex.h" + +#if defined (ACE_HAS_THREADS) + +#if defined (ACE_HAS_DUMP) +# include "ace/Log_Msg.h" +#endif /* ACE_HAS_DUMP */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +int +ACE_Condition::remove (void) +{ + return ACE_OS::cond_destroy (&this->cond_); +} + +void +ACE_Condition::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Condition::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + // No dump method for ACE_cond_t even in emulated mode. + // cond_.dump (); + this->mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Condition::~ACE_Condition (void) +{ + this->remove (); +} + +ACE_Condition::ACE_Condition (ACE_Recursive_Thread_Mutex &m) + : mutex_ (m) +{ + ACE_OS::cond_init (&this->cond_); +} + +int +ACE_Condition::wait (const ACE_Time_Value *abstime) +{ + return this->wait (this->mutex_, abstime); +} + +int +ACE_Condition::wait (ACE_Recursive_Thread_Mutex &mutex, + const ACE_Time_Value *abstime) +{ + ACE_recursive_mutex_state mutex_state_holder; + ACE_recursive_thread_mutex_t &recursive_mutex = mutex.mutex (); + + if (ACE_OS::recursive_mutex_cond_unlock (&recursive_mutex, + mutex_state_holder) == -1) + return -1; + + // We wait on the condition, specifying the nesting mutex. For platforms + // with ACE_HAS_RECURSIVE_MUTEXES, this is the recursive mutex itself, + // and is the same as recursive_mutex, above. The caller should have been + // holding the lock on entry to this method, and it is still held. + // For other platforms, this is the nesting mutex that guards the + // ACE_recursive_mutex_t internals, and recursive_mutex_cond_unlock() + // returned with the lock held, but waiters primed and waiting to be + // released. At cond_wait below, the mutex will be released. + // On return, it will be reacquired. + const int result = abstime == 0 + ? ACE_OS::cond_wait (&this->cond_, + &mutex.get_nesting_mutex ()) + : ACE_OS::cond_timedwait (&this->cond_, + &mutex.get_nesting_mutex (), + const_cast (abstime)); + // We are holding the mutex, whether the wait succeeded or failed. + // Stash errno (in case it failed) and then we need to reset the + // recursive mutex state to what it was on entry to this method. + // Resetting it may require a wait for another thread to release + // the ACE_recursive_thread_mutex_t if this is a platform without + // ACE_HAS_RECURSIVE_MUTEXES, and recursive_mutex_cond_relock() takes + // care of that. + { + ACE_Errno_Guard error (errno); + ACE_OS::recursive_mutex_cond_relock (&recursive_mutex, + mutex_state_holder); + } + + return result; +} + +int +ACE_Condition::signal (void) +{ + return ACE_OS::cond_signal (&this->cond_); +} + +int +ACE_Condition::broadcast (void) +{ + return ACE_OS::cond_broadcast (&this->cond_); +} + +ACE_Recursive_Thread_Mutex & +ACE_Condition::mutex (void) +{ + return this->mutex_; +} + +ACE_Condition_Recursive_Thread_Mutex::ACE_Condition_Recursive_Thread_Mutex ( + ACE_Recursive_Thread_Mutex &m) : + ACE_Condition (m) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Condition_Recursive_Thread_Mutex.h b/dep/ACE_wrappers/ace/Condition_Recursive_Thread_Mutex.h new file mode 100644 index 000000000..f3c4b5257 --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_Recursive_Thread_Mutex.h @@ -0,0 +1,118 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Condition_Recursive_Thread_Mutex.h + * + * $Id: Condition_Recursive_Thread_Mutex.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_CONDITION_RECURSIVE_THREAD_MUTEX_H +#define ACE_CONDITION_RECURSIVE_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Condition.h" +#else /* ACE_HAS_THREADS */ +#include "ace/Recursive_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template class ACE_Condition; + +/** + * @class ACE_Condition + * + * @brief ACE_Condition template specialization written using + * @a ACE_Recursive_Thread_Mutex. This allows threads to block until + * shared data changes state using recursive mutexes. + */ +template<> +class ACE_Export ACE_Condition +{ +public: + /// Initialize the condition variable with a recursive mutex. + ACE_Condition (ACE_Recursive_Thread_Mutex &m); + + /// Implicitly destroy the condition variable. + ~ACE_Condition (void); + + /** + * Explicitly destroy the condition variable. Note that only one + * thread should call this method since it doesn't protect against + * race conditions. + */ + int remove (void); + + /** + * Block on condition, or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" semantics. Else, if + * != 0 and the call times out before the condition is signaled + * returns -1 and sets errno to ETIME. + */ + int wait (const ACE_Time_Value *abstime = 0); + + /** + * Block on condition or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" wait() semantics on the recursive @a mutex + * passed as a parameter (this is useful if you need to store the + * in shared memory). Else, if != 0 and the + * call times out before the condition is signaled returns -1 + * and sets errno to ETIME. + */ + int wait (ACE_Recursive_Thread_Mutex &mutex, + const ACE_Time_Value *abstime = 0); + + /// Signal one waiting thread. + int signal (void); + + /// Signal *all* waiting threads. + int broadcast (void); + + /// Returns a reference to the underlying mutex; + ACE_Recursive_Thread_Mutex &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + +private: + + // = Prevent assignment and copying. + void operator= (const ACE_Condition &); + ACE_Condition (const ACE_Condition &); + +private: + + /// A normal (i.e., non-recursive) condition variable. + ACE_cond_t cond_; + + /// Reference to the recursive mutex. + ACE_Recursive_Thread_Mutex &mutex_; + +}; + +class ACE_Export ACE_Condition_Recursive_Thread_Mutex + : public ACE_Condition +{ +public: + /// Initialize the condition variable with a recursive mutex. + ACE_Condition_Recursive_Thread_Mutex (ACE_Recursive_Thread_Mutex &m); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONDITION_RECURSIVE_THREAD_MUTEX_H */ diff --git a/dep/ACE_wrappers/ace/Condition_T.cpp b/dep/ACE_wrappers/ace/Condition_T.cpp new file mode 100644 index 000000000..a2ebff153 --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_T.cpp @@ -0,0 +1,122 @@ +// $Id: Condition_T.cpp 81283 2008-04-09 01:28:18Z schmidt $ + +#ifndef ACE_CONDITION_T_CPP +#define ACE_CONDITION_T_CPP + +#include "ace/Condition_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Condition_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Condition) + +template void +ACE_Condition::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Condition::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Thread_Condition::ACE_Thread_Condition (MUTEX &m, + const ACE_TCHAR *name, + void *arg) + : ACE_Condition (m, USYNC_THREAD, name, arg) +{ +// ACE_TRACE ("ACE_Thread_Condition::ACE_Thread_Condition"); +} + +template void +ACE_Thread_Condition::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Condition::dump"); + + ACE_Condition::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Condition::ACE_Condition (MUTEX &m, + int type, + const ACE_TCHAR *name, + void *arg) + : + mutex_ (m) +{ + // ACE_TRACE ("ACE_Condition::ACE_Condition"); + + if (ACE_OS::cond_init (&this->cond_, + (short) type, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Condition::ACE_Condition"))); +} + +template +ACE_Condition::~ACE_Condition (void) +{ + // ACE_TRACE ("ACE_Condition::~ACE_Condition"); + + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Condition::~ACE_Condition"))); +} + +template int +ACE_Condition::wait (void) +{ + // ACE_TRACE ("ACE_Condition::wait"); + return ACE_OS::cond_wait (&this->cond_, + &this->mutex_.lock_); +} + +template int +ACE_Condition::wait (MUTEX &mutex, + const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition::wait"); + if (abstime == 0) + return ACE_OS::cond_wait (&this->cond_, + &mutex.lock_); + else + return ACE_OS::cond_timedwait (&this->cond_, + &mutex.lock_, + (ACE_Time_Value *) abstime); +} + +// Peform an "alertable" timed wait. If the argument ABSTIME == 0 +// then we do a regular cond_wait(), else we do a timed wait for up to +// ABSTIME using the Solaris cond_timedwait() function. + +template int +ACE_Condition::wait (const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition::wait"); + return this->wait (this->mutex_, abstime); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ + +#endif /* ACE_CONDITION_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Condition_T.h b/dep/ACE_wrappers/ace/Condition_T.h new file mode 100644 index 000000000..936ce8217 --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_T.h @@ -0,0 +1,167 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Condition_T.h + * + * $Id: Condition_T.h 81462 2008-04-28 11:39:40Z johnnyw $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_CONDITION_T_H +#define ACE_CONDITION_T_H + +#include /**/ "ace/pre.h" + +#include "ace/OS_NS_Thread.h" +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +/** + * @class ACE_Condition + * + * @brief ACE_Condition variable wrapper, which allows threads to block + * until shared data changes state. + * + * A condition variable enables threads to atomically block and + * test the condition under the protection of a mutual exclu- + * sion lock (mutex) until the condition is satisfied. That is, + * the mutex must have been held by the thread before calling + * wait or signal on the condition. If the condition is false, + * a thread blocks on a condition variable and atomically + * releases the mutex that is waiting for the condition to + * change. If another thread changes the condition, it may wake + * up waiting threads by signaling the associated condition + * variable. The waiting threads, upon awakening, reacquire the + * mutex and re-evaluate the condition. + * Note, you can only parameterize with + * @a ACE_Thread_Mutex, @a ACE_Recursive_Thread_Mutex, or @a ACE_Null_Mutex. + */ +template +class ACE_Condition +{ +public: + // = Initialiation and termination methods. + /// Initialize the condition variable. + ACE_Condition (MUTEX &m, int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, void *arg = 0); + + /// Implicitly destroy the condition variable. + ~ACE_Condition (void); + + // = Lock accessors. + /** + * Block on condition, or until absolute time-of-day has passed. If + * @a abstime == 0 use "blocking" semantics. Else, if @a abstime + * != 0 and the call times out before the condition is signaled + * returns -1 and sets errno to ETIME. + */ + int wait (const ACE_Time_Value *abstime); + + /// Block on condition. + int wait (void); + + /** + * Block on condition or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" wait() semantics on the + * passed as a parameter (this is useful if you need to store the + * in shared memory). Else, if != 0 and the + * call times out before the condition is signaled returns -1 + * and sets errno to ETIME. + */ + int wait (MUTEX &mutex, const ACE_Time_Value *abstime = 0); + + /// Signal one waiting thread. + int signal (void); + + /// Signal *all* waiting threads. + int broadcast (void); + + // = Utility methods. + /// Explicitly destroy the condition variable. + int remove (void); + + /// Returns a reference to the underlying mutex_; + MUTEX &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + /// Condition variable. + ACE_cond_t cond_; + + /// Reference to mutex lock. + MUTEX &mutex_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Condition &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Condition (const ACE_Condition &)) +}; + +/** + * @class ACE_Thread_Condition + * + * @brief ACE_Condition variable wrapper that works within processes. + * + * A condition variable enables threads to atomically block and + * test the condition under the protection of a mutual exclu- + * sion lock (mutex) until the condition is satisfied. That is, + * the mutex must have been held by the thread before calling + * wait or signal on the condition. If the condition is false, + * a thread blocks on a condition variable and atomically + * releases the mutex that is waiting for the condition to + * change. If another thread changes the condition, it may wake + * up waiting threads by signaling the associated condition + * variable. The waiting threads, upon awakening, reacquire the + * mutex and re-evaluate the condition. + */ +template +class ACE_Thread_Condition : public ACE_Condition +{ +public: + // = Initialization method. + ACE_Thread_Condition (MUTEX &m, const ACE_TCHAR *name = 0, void *arg = 0); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Condition_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Condition_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Condition_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONDITION_T_H */ diff --git a/dep/ACE_wrappers/ace/Condition_T.inl b/dep/ACE_wrappers/ace/Condition_T.inl new file mode 100644 index 000000000..e3b452734 --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_T.inl @@ -0,0 +1,51 @@ +// -*- C++ -*- +// +// $Id: Condition_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE int +ACE_Condition::remove (void) +{ + // ACE_TRACE ("ACE_Condition::remove"); + + // cond_destroy() is called in a loop if the condition variable is + // BUSY. This avoids a condition where a condition is signaled and + // because of some timing problem, the thread that is to be signaled + // has called the cond_wait routine after the signal call. Since + // the condition signal is not queued in any way, deadlock occurs. + + int result = 0; + + while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (&this->cond_); + ACE_OS::thr_yield (); + } + + return result; +} + +template ACE_INLINE MUTEX & +ACE_Condition::mutex (void) +{ + // ACE_TRACE ("ACE_Condition::mutex"); + return this->mutex_; +} + +template ACE_INLINE int +ACE_Condition::signal (void) +{ +// ACE_TRACE ("ACE_Condition::signal"); + return ACE_OS::cond_signal (&this->cond_); +} + +template ACE_INLINE int +ACE_Condition::broadcast (void) +{ +// ACE_TRACE ("ACE_Condition::broadcast"); + return ACE_OS::cond_broadcast (&this->cond_); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Condition_Thread_Mutex.cpp b/dep/ACE_wrappers/ace/Condition_Thread_Mutex.cpp new file mode 100644 index 000000000..c9f2620e4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_Thread_Mutex.cpp @@ -0,0 +1,126 @@ +/* -*- C++ -*- */ +/** + * @file Condition_Thread_Mutex.cpp + * + * $Id: Condition_Thread_Mutex.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt + */ + +#include "ace/Condition_Thread_Mutex.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Condition_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, Condition_Thread_Mutex, "$Id: Condition_Thread_Mutex.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Condition_Thread_Mutex) + +void +ACE_Condition_Thread_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Condition_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); +#if defined (ACE_WIN32) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("waiters = %d\n"), + this->cond_.waiters ())); +#endif /* ACE_WIN32 */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex (ACE_Thread_Mutex &m, + const ACE_TCHAR *name, + void *arg) + : mutex_ (m), + removed_ (false) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); + if (ACE_OS::cond_init (&this->cond_, + (short) USYNC_THREAD, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); +} + +ACE_Condition_Thread_Mutex:: +ACE_Condition_Thread_Mutex (ACE_Thread_Mutex &m, + ACE_Condition_Attributes &attributes, + const ACE_TCHAR *name, + void *arg) + : mutex_ (m), + removed_ (false) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); + if (ACE_OS::cond_init (&this->cond_, attributes.attributes_, + name, arg) != 0) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); +} + +ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex"); + this->remove (); +} + +// Peform an "alertable" timed wait. If the argument == 0 +// then we do a regular , else we do a timed wait for up to +// using the function. + +int +ACE_Condition_Thread_Mutex::wait (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + return ACE_OS::cond_wait (&this->cond_, &this->mutex_.lock_); +} + +int +ACE_Condition_Thread_Mutex::wait (ACE_Thread_Mutex &mutex, + const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + return ACE_OS::cond_timedwait (&this->cond_, + &mutex.lock_, + const_cast (abstime)); +} + +int +ACE_Condition_Thread_Mutex::wait (const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + return this->wait (this->mutex_, abstime); +} + +int +ACE_Condition_Thread_Mutex::signal (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::signal"); + return ACE_OS::cond_signal (&this->cond_); +} + +int +ACE_Condition_Thread_Mutex::broadcast (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::broadcast"); + return ACE_OS::cond_broadcast (&this->cond_); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Condition_Thread_Mutex.h b/dep/ACE_wrappers/ace/Condition_Thread_Mutex.h new file mode 100644 index 000000000..693ff0820 --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_Thread_Mutex.h @@ -0,0 +1,190 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Condition_Thread_Mutex.h + * + * $Id: Condition_Thread_Mutex.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_CONDITION_THREAD_MUTEX_H +#define ACE_CONDITION_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Condition.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include "ace/Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +class ACE_Export ACE_Condition_Attributes +{ +public: + /// Constructor + ACE_Condition_Attributes (int type = ACE_DEFAULT_SYNCH_TYPE); + + /// Destructor + ~ACE_Condition_Attributes (void); + +private: + friend class ACE_Condition_Thread_Mutex; + + /// The attributes + ACE_condattr_t attributes_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Condition_Attributes &); + ACE_Condition_Attributes (const ACE_Condition_Attributes &); +}; + +/** + * @class ACE_Condition_Thread_Mutex + * + * @brief ACE_Condition variable wrapper written using ACE_Mutexes This + * allows threads to block until shared data changes state. + * A condition variable enables threads to atomically block and + * test the condition under the protection of a mutual exclu- + * sion lock (mutex) until the condition is satisfied. That is, + * the mutex must have been held by the thread before calling + * wait or signal on the condition. If the condition is false, + * a thread blocks on a condition variable and atomically + * releases the mutex that is waiting for the condition to + * change. If another thread changes the condition, it may wake + * up waiting threads by signaling the associated condition + * variable. The waiting threads, upon awakening, reacquire the + * mutex and re-evaluate the condition. + * + * This should be an instantiation of ACE_Condition but problems + * with compilers precludes this... + */ +class ACE_Export ACE_Condition_Thread_Mutex +{ +public: + /// Initialize the condition variable. + ACE_Condition_Thread_Mutex (ACE_Thread_Mutex &m, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Initialize the condition variable. + ACE_Condition_Thread_Mutex (ACE_Thread_Mutex &m, + ACE_Condition_Attributes &attributes, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Implicitly destroy the condition variable. + ~ACE_Condition_Thread_Mutex (void); + + /** + * Explicitly destroy the condition variable. Note that only one + * thread should call this method since it doesn't protect against + * race conditions. + */ + int remove (void); + + /** + * Block on condition, or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" semantics. Else, if @a abstime + * != 0 and the call times out before the condition is signaled + * returns -1 and sets errno to ETIME. + */ + int wait (const ACE_Time_Value *abstime); + + /// Block on condition. + int wait (void); + + /** + * Block on condition or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" wait() semantics on the + * passed as a parameter (this is useful if you need to store the + * in shared memory). Else, if @a abstime != 0 and the + * call times out before the condition is signaled returns -1 + * and sets errno to ETIME. + */ + int wait (ACE_Thread_Mutex &mutex, const ACE_Time_Value *abstime = 0); + + /// Signal one waiting thread. + int signal (void); + + /// Signal *all* waiting threads. + int broadcast (void); + + /// Returns a reference to the underlying mutex; + ACE_Thread_Mutex &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Condition variable. + ACE_cond_t cond_; + + /// Reference to mutex lock. + ACE_Thread_Mutex &mutex_; + + /// Keeps track of whether has been called yet to avoid + /// multiple calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// on the same object, which is a bad idea anyway... + bool removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Condition_Thread_Mutex &); + ACE_Condition_Thread_Mutex (const ACE_Condition_Thread_Mutex &); +}; + +#if 0 +// The following class is commented out since there doesn't +// appear to be a portable and robust means of implementing this +// functionality across platforms. If you know of a portable and +// robust way to implement this functionality please let us know. + +/** + * @class ACE_Process_Condition + * + * @brief ACE_Condition variable wrapper that works across processes. + */ +class ACE_Export ACE_Process_Condition +{ +public: + ACE_Process_Condition (MUTEX &m, const ACE_TCHAR *name = 0, void *arg = 0); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; +#endif /* 0 */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Condition_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONDITION_THREAD_MUTEX_H */ diff --git a/dep/ACE_wrappers/ace/Condition_Thread_Mutex.inl b/dep/ACE_wrappers/ace/Condition_Thread_Mutex.inl new file mode 100644 index 000000000..851269e4a --- /dev/null +++ b/dep/ACE_wrappers/ace/Condition_Thread_Mutex.inl @@ -0,0 +1,74 @@ +// -*- C++ -*- +// +// $Id: Condition_Thread_Mutex.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Condition_Attributes::ACE_Condition_Attributes (int type) +{ + (void) ACE_OS::condattr_init (this->attributes_, type); +} + +ACE_INLINE +ACE_Condition_Attributes::~ACE_Condition_Attributes (void) +{ + ACE_OS::condattr_destroy (this->attributes_); +} + +ACE_INLINE int +ACE_Condition_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::remove"); + + // is called in a loop if the condition variable is + // BUSY. This avoids a condition where a condition is signaled and + // because of some timing problem, the thread that is to be signaled + // has called the cond_wait routine after the signal call. Since + // the condition signal is not queued in any way, deadlock occurs. + + int result = 0; + + if (!this->removed_) + { + this->removed_ = true; + + while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (&this->cond_); + ACE_OS::thr_yield (); + } + } + return result; +} + +ACE_INLINE ACE_Thread_Mutex & +ACE_Condition_Thread_Mutex::mutex (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::mutex"); + return this->mutex_; +} + +#if 0 +template void +ACE_Process_Condition::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Process_Condition::dump"); + + ACE_Condition::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Process_Condition::ACE_Process_Condition (MUTEX &m, + const ACE_TCHAR *name, + void *arg) + : ACE_Condition (m, USYNC_PROCESS, name, arg) +{ +// ACE_TRACE ("ACE_Process_Condition::ACE_Process_Condition"); +} +#endif /* 0 */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Configuration.cpp b/dep/ACE_wrappers/ace/Configuration.cpp new file mode 100644 index 000000000..734482f0e --- /dev/null +++ b/dep/ACE_wrappers/ace/Configuration.cpp @@ -0,0 +1,2148 @@ +// $Id: Configuration.cpp 80826 2008-03-04 14:51:23Z wotte $ +#include "ace/Configuration.h" +#include "ace/Auto_Ptr.h" +#include "ace/SString.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_strings.h" + +// Can remove this when import_config and export_config are removed from +// ACE_Configuration. They're deprecated at ACE 5.2. +#include "ace/Configuration_Import_Export.h" + +#if !defined (ACE_LACKS_ACCESS) +# include "ace/OS_NS_unistd.h" +#endif /* ACE_LACKS_ACCESS */ + +#if !defined (__ACE_INLINE__) +#include "ace/Configuration.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Section_Key_Internal::ACE_Section_Key_Internal (void) + : ref_count_ (0) +{ +} + +ACE_Section_Key_Internal::~ACE_Section_Key_Internal (void) +{ +} + +int +ACE_Section_Key_Internal::add_ref (void) +{ + ++ref_count_; + return 0; +} + +int +ACE_Section_Key_Internal::dec_ref (void) +{ + if (!--ref_count_) + delete this; + return 0; +} + +ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (void) + : key_ (0) +{ +} + +ACE_Configuration_Section_Key::~ACE_Configuration_Section_Key (void) +{ + if (key_) + key_->dec_ref (); +} + +ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (ACE_Section_Key_Internal* key) + : key_ (key) +{ + if (key_) + key_->add_ref (); +} + +ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (const ACE_Configuration_Section_Key& rhs) + : key_ (rhs.key_) +{ + if (key_) + key_->add_ref (); +} + +ACE_Configuration_Section_Key& +ACE_Configuration_Section_Key::operator= (const ACE_Configuration_Section_Key& rhs) +{ + if (this != &rhs) + { + if (key_) + key_->dec_ref (); + + key_ = rhs.key_; + + if (key_) + key_->add_ref (); + } + return *this; +} + +////////////////////////////////////////////////////////////////////////////// + +ACE_TCHAR ACE_Configuration::NULL_String_ = '\0'; + +ACE_Configuration::ACE_Configuration (void) + : root_ () +{ +} + +ACE_Configuration::~ACE_Configuration (void) +{ +} + +ACE_Section_Key_Internal* +ACE_Configuration::get_internal_key (const ACE_Configuration_Section_Key& key) +{ + return key.key_; +} + +int +ACE_Configuration::expand_path (const ACE_Configuration_Section_Key& key, + const ACE_TString& path_in, + ACE_Configuration_Section_Key& key_out, + int create) +{ + // Make a copy of key + ACE_Configuration_Section_Key current_section = key; + ACE_Auto_Basic_Array_Ptr pData (path_in.rep ()); + ACE_Tokenizer parser (pData.get ()); + parser.delimiter_replace ('\\', '\0'); + parser.delimiter_replace ('/', '\0'); + + for (ACE_TCHAR *temp = parser.next (); + temp != 0; + temp = parser.next ()) + { + // Open the section + if (open_section (current_section, + temp, + create, + key_out)) + return -1; + + current_section = key_out; + } + + return 0; + +} + +// import_config and export_config are here for backward compatibility, +// and have been deprecated. +int +ACE_Configuration::export_config (const ACE_TCHAR* filename) +{ + ACE_Registry_ImpExp exporter (*this); + return exporter.export_config (filename); +} + +int +ACE_Configuration::import_config (const ACE_TCHAR* filename) +{ + ACE_Registry_ImpExp importer (*this); + return importer.import_config (filename); +} + +int +ACE_Configuration::validate_name (const ACE_TCHAR* name, int allow_path) +{ + // Invalid character set + const ACE_TCHAR* reject = + allow_path ? ACE_TEXT ("][") : ACE_TEXT ("\\]["); + + // Position of the first invalid character or terminating null. + size_t const pos = ACE_OS::strcspn (name, reject); + + // Check if it is an invalid character. + if (name[pos] != ACE_TEXT ('\0')) + { + errno = EINVAL; + return -1; + } + + // The first character can never be a path separator. + if (name[0] == ACE_TEXT ('\\')) + { + errno = EINVAL; + return -1; + } + + // Validate length. + if (pos == 0 || pos > 255) + { + errno = ENAMETOOLONG; + return -1; + } + + return 0; +} + +int +ACE_Configuration::validate_value_name (const ACE_TCHAR* name) +{ + if (name == 0 || *name == this->NULL_String_) + return 0; + + return this->validate_name (name); +} + +const ACE_Configuration_Section_Key& +ACE_Configuration::root_section (void) const +{ + return root_; +} + +/** + * Determine if the contents of this object is the same as the + * contents of the object on the right hand side. + * Returns 1 (True) if they are equal and 0 (False) if they are not equal + */ +bool +ACE_Configuration::operator== (const ACE_Configuration& rhs) const +{ + bool rc = true; + int sectionIndex = 0; + ACE_TString sectionName; + ACE_Configuration *nonconst_this = const_cast (this); + ACE_Configuration &nonconst_rhs = const_cast (rhs); + + const ACE_Configuration_Section_Key& rhsRoot = rhs.root_section (); + ACE_Configuration_Section_Key rhsSection; + ACE_Configuration_Section_Key thisSection; + + // loop through each section in this object + while ((rc) && (nonconst_this->enumerate_sections (this->root_, + sectionIndex, + sectionName) == 0)) + { + // find that section in the rhs object + if (nonconst_rhs.open_section (rhsRoot, + sectionName.c_str (), + 0, + rhsSection) != 0) + { + // If the rhs object does not contain the section then we are + // not equal. + rc = false; + } + else if (nonconst_this->open_section (this->root_, + sectionName.c_str (), + 0, + thisSection) != 0) + { + // if there is some error opening the section in this object + rc = false; + } + else + { + // Well the sections match + int valueIndex = 0; + ACE_TString valueName; + VALUETYPE valueType; + VALUETYPE rhsType; + + // Enumerate each value in this section + while ((rc) && nonconst_this->enumerate_values (thisSection, + valueIndex, + valueName, + valueType) == 0) + { + // look for the same value in the rhs section + if (nonconst_rhs.find_value (rhsSection, + valueName.c_str (), + rhsType) != 0) + { + // We're not equal if the same value cannot + // be found in the rhs object. + rc = false; + } + else if (valueType != rhsType) + { + // we're not equal if the types do not match. + rc = false; + } + else + { + // finally compare values. + if (valueType == STRING) + { + ACE_TString thisString, rhsString; + if (nonconst_this->get_string_value (thisSection, + valueName.c_str (), + thisString) != 0) + { + // we're not equal if we cannot get this string + rc = false; + } + else if (nonconst_rhs.get_string_value ( + rhsSection, + valueName.c_str (), + rhsString) != 0) + { + // we're not equal if we cannot get rhs string + rc = false; + } + rc = (thisString == rhsString); + } + else if (valueType == INTEGER) + { + u_int thisInt = 0; + u_int rhsInt = 0; + if (nonconst_this->get_integer_value ( + thisSection, + valueName.c_str (), + thisInt) != 0) + { + // we're not equal if we cannot get this int + rc = false; + } + else if (nonconst_rhs.get_integer_value ( + rhsSection, + valueName.c_str (), + rhsInt) != 0) + { + // we're not equal if we cannot get rhs int + rc = false; + } + rc = (thisInt == rhsInt); + } + else if (valueType == BINARY) + { + void* thisData = 0; + void* rhsData = 0; + size_t thisLength = 0; + size_t rhsLength = 0; + if (nonconst_this->get_binary_value (thisSection, + valueName.c_str (), + thisData, + thisLength) != 0) + { + // we're not equal if we cannot get this data + rc = false; + } + else if (nonconst_rhs.get_binary_value ( + rhsSection, + valueName.c_str (), + rhsData, + rhsLength) != 0) + { + // we're not equal if we cannot get this data + rc = false; + } + + rc = (thisLength == rhsLength); + // are the length's the same? + + if (rc) + { + unsigned char* thisCharData = + (unsigned char*)thisData; + unsigned char* rhsCharData = (unsigned char*)rhsData; + // yes, then check each element + for (size_t count = 0; + (rc) && (count < thisLength); + count++) + { + rc = (* (thisCharData + count) == * (rhsCharData + count)); + } + + delete [] thisCharData; + delete [] rhsCharData; + }// end if the length's match + } + // We should never have valueTypes of INVALID, therefore + // we're not comparing them. How would we since we have + // no get operation for invalid types. + // So, if we have them, we guess they are equal. + + }// end else if values match. + + ++valueIndex; + + }// end value while loop + + // look in the rhs for values not in this + valueIndex = 0; + while ((rc) && (nonconst_rhs.enumerate_values (rhsSection, + valueIndex, + valueName, + rhsType) == 0)) + { + // look for the same value in this section + if (nonconst_this->find_value (thisSection, + valueName.c_str (), + valueType) != 0) + { + // We're not equal if the same value cannot + // be found in the rhs object. + rc = false; + } + ++valueIndex; + }// end while for rhs values not in this. + + }// end else if sections match. + + ++sectionIndex; + + }// end section while loop + + // Finally, make sure that there are no sections in rhs that do not + // exist in this + sectionIndex = 0; + while ((rc) + && (nonconst_rhs.enumerate_sections (rhsRoot, + sectionIndex, + sectionName) == 0)) + { + // find the section in this + if (nonconst_this->open_section (this->root_, + sectionName.c_str (), + 0, + thisSection) != 0) + { + // if there is some error opening the section in this object + rc = false; + } + else if (nonconst_rhs.open_section (rhsRoot, + sectionName.c_str (), + 0, + rhsSection) != 0) + { + // If the rhs object does not contain the section then we + // are not equal. + rc = false; + } + ++sectionIndex; + } + return rc; +} + +bool +ACE_Configuration::operator!= (const ACE_Configuration& rhs) const +{ + return !(*this == rhs); +} + +////////////////////////////////////////////////////////////////////////////// + +#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY) + +static const int ACE_DEFAULT_BUFSIZE = 256; + +static const ACE_TCHAR *temp_name (const ACE_TCHAR *name) +{ + if (name && *name == ACE_Configuration::NULL_String_) + return 0; + return name; +} + +ACE_Section_Key_Win32::ACE_Section_Key_Win32 (HKEY hKey) + : hKey_ (hKey) +{ +} + +ACE_Section_Key_Win32::~ACE_Section_Key_Win32 (void) +{ + ::RegCloseKey (hKey_); +} + +////////////////////////////////////////////////////////////////////////////// + +bool +ACE_Configuration_Win32Registry::operator== (const ACE_Configuration_Win32Registry &rhs) const +{ + ACE_UNUSED_ARG (rhs); + return true; +} + +bool +ACE_Configuration_Win32Registry::operator!= (const ACE_Configuration_Win32Registry &rhs) const +{ + ACE_UNUSED_ARG (rhs); + return true; +} + +ACE_Configuration_Win32Registry::ACE_Configuration_Win32Registry (HKEY hKey) +{ + ACE_Section_Key_Win32 *temp = 0; + + ACE_NEW (temp, ACE_Section_Key_Win32 (hKey)); + + root_ = ACE_Configuration_Section_Key (temp); +} + + +ACE_Configuration_Win32Registry::~ACE_Configuration_Win32Registry (void) +{ +} + +int +ACE_Configuration_Win32Registry::open_section (const ACE_Configuration_Section_Key& base, + const ACE_TCHAR* sub_section, + int create, + ACE_Configuration_Section_Key& result) +{ + if (validate_name (sub_section, 1)) + return -1; + + HKEY base_key; + if (load_key (base, base_key)) + return -1; + + int errnum; + HKEY result_key; + if ((errnum = ACE_TEXT_RegOpenKeyEx (base_key, + sub_section, + 0, + KEY_ALL_ACCESS, + &result_key)) != ERROR_SUCCESS) + { + if (!create) + { + errno = errnum; + return -1; + } + + if ((errnum = ACE_TEXT_RegCreateKeyEx (base_key, + sub_section, + 0, + 0, + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &result_key, +#if defined (__MINGW32__) + (PDWORD) 0 +#else + 0 +#endif /* __MINGW32__ */ + )) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + } + + ACE_Section_Key_Win32 *temp; + + ACE_NEW_RETURN (temp, ACE_Section_Key_Win32 (result_key), -1); + result = ACE_Configuration_Section_Key (temp); + return 0; +} + +int +ACE_Configuration_Win32Registry::remove_section (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* sub_section, + int recursive) +{ + if (validate_name (sub_section)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + if (recursive) + { + ACE_Configuration_Section_Key section; + if (open_section (key, sub_section, 0, section)) + return -1; + + HKEY sub_key; + if (load_key (section, sub_key)) + return -1; + + ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE]; + DWORD buffer_size = ACE_DEFAULT_BUFSIZE; + // Note we don't increment the index because the + // enumeration becomes invalid if we change the + // subkey, which we do when we delete it. By leaving + // it 0, we always delete the top entry + while (ACE_TEXT_RegEnumKeyEx (sub_key, + 0, + name_buffer, + &buffer_size, + 0, + 0, + 0, + 0) == ERROR_SUCCESS) + { + remove_section (section, name_buffer, 1); + buffer_size = ACE_DEFAULT_BUFSIZE; + } + } + + int errnum; + errnum = ACE_TEXT_RegDeleteKey (base_key, sub_section); + if (errnum != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::enumerate_values (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name, + VALUETYPE& type) +{ + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE]; + DWORD buffer_size = ACE_DEFAULT_BUFSIZE; + DWORD value_type; + + int rc = ACE_TEXT_RegEnumValue (base_key, + index, + name_buffer, + &buffer_size, + 0, + &value_type, + 0, + 0); + if (rc == ERROR_NO_MORE_ITEMS) + return 1; + else if (rc != ERROR_SUCCESS) + { + errno = rc; + return -1; + } + + name = name_buffer; + + switch (value_type) + { + case REG_BINARY: + type = BINARY; + break; + case REG_SZ: + type = STRING; + break; + case REG_DWORD: + type = INTEGER; + break; + default: + type = INVALID; + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::enumerate_sections (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name) +{ + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE]; + DWORD buffer_size = ACE_DEFAULT_BUFSIZE; + int rc = ACE_TEXT_RegEnumKeyEx (base_key, + index, + name_buffer, + &buffer_size, + 0, + 0, + 0, + 0); + if (rc == ERROR_NO_MORE_ITEMS) + return 1; + else if (rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS) + { + errno = rc; + return -1; + } + + name = name_buffer; + + return 0; +} + +int +ACE_Configuration_Win32Registry::set_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const ACE_TString& value) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + int errnum; + DWORD len = static_cast (value.length () + 1); + len *= sizeof (ACE_TCHAR); + if ((errnum = ACE_TEXT_RegSetValueEx (base_key, + t_name, + 0, + REG_SZ, + (BYTE *) value.fast_rep (), + len)) + != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::set_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int value) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + int errnum; + if ((errnum = ACE_TEXT_RegSetValueEx (base_key, + t_name, + 0, + REG_DWORD, + (BYTE *) &value, + sizeof (value))) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::set_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const void* data, + size_t length) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + int errnum; + if ((errnum = ACE_TEXT_RegSetValueEx (base_key, + t_name, + 0, + REG_BINARY, + (BYTE *) data, + static_cast (length))) + != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::get_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + ACE_TString& value) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + // Get the size of the binary data from windows + int errnum; + DWORD buffer_length = 0; + DWORD type; + if ((errnum = ACE_TEXT_RegQueryValueEx (base_key, + t_name, + 0, + &type, + (BYTE *) 0, + &buffer_length)) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + if (type != REG_SZ) + { + errno = ERROR_INVALID_DATATYPE; + return -1; + } + + ACE_TCHAR *temp = 0; + ACE_NEW_RETURN (temp, + ACE_TCHAR[buffer_length], + -1); + + ACE_Auto_Basic_Array_Ptr buffer (temp); + + if ((errnum = ACE_TEXT_RegQueryValueEx (base_key, + t_name, + 0, + &type, + (BYTE *) buffer.get (), + &buffer_length)) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + value = buffer.get (); + return 0; +} + +int +ACE_Configuration_Win32Registry::get_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int& value) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + int errnum; + DWORD length = sizeof (value); + DWORD type; + if ((errnum = ACE_TEXT_RegQueryValueEx (base_key, + t_name, + 0, + &type, + (BYTE *) &value, + &length)) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + if (type != REG_DWORD) + { + errno = ERROR_INVALID_DATATYPE; + return -1; + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::get_binary_value ( + const ACE_Configuration_Section_Key &key, + const ACE_TCHAR *name, + void *&data, + size_t &length) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + // Get the size of the binary data from windows + int errnum; + DWORD buffer_length = 0; + DWORD type; + if ((errnum = ACE_TEXT_RegQueryValueEx (base_key, + t_name, + 0, + &type, + (BYTE *) 0, + &buffer_length)) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + if (type != REG_BINARY) + { + errno = ERROR_INVALID_DATATYPE; + return -1; + } + + length = buffer_length; + + BYTE * the_data = 0; + ACE_NEW_RETURN (the_data, BYTE[length], -1); + ACE_Auto_Basic_Array_Ptr safe_data (the_data); + + if ((errnum = ACE_TEXT_RegQueryValueEx (base_key, + t_name, + 0, + &type, + the_data, + &buffer_length)) != ERROR_SUCCESS) + { + data = 0; + errno = errnum; + return -1; + } + + data = safe_data.release (); + + return 0; +} + +int +ACE_Configuration_Win32Registry::find_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + VALUETYPE& type_out) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + DWORD buffer_length=0; + DWORD type; + int result=ACE_TEXT_RegQueryValueEx (base_key, + t_name, + 0, + &type, + 0, + &buffer_length); + if (result != ERROR_SUCCESS) + { + errno = result; + return -1; + } + + switch (type) + { + case REG_SZ: + type_out = STRING; + break; + case REG_DWORD: + type_out = INTEGER; + break; + case REG_BINARY: + type_out = BINARY; + break; + default: + return -1; // unknown type + } + + return 0; +} + +int +ACE_Configuration_Win32Registry::remove_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name) +{ + const ACE_TCHAR *t_name = temp_name (name); + if (validate_value_name (t_name)) + return -1; + + HKEY base_key; + if (load_key (key, base_key)) + return -1; + + int errnum; + if ((errnum = ACE_TEXT_RegDeleteValue (base_key, t_name)) != ERROR_SUCCESS) + { + errno = errnum; + return -1; + } + + return 0; +} + + +int +ACE_Configuration_Win32Registry::load_key (const ACE_Configuration_Section_Key& key, + HKEY& hKey) +{ + ACE_Section_Key_Win32* pKey = dynamic_cast (get_internal_key (key)); + if (!pKey) + return -1; + + hKey = pKey->hKey_; + return 0; +} + +HKEY +ACE_Configuration_Win32Registry::resolve_key (HKEY hKey, + const ACE_TCHAR* path, + int create) +{ + HKEY result = 0; + // Make a copy of hKey + int errnum; +#if defined (ACE_HAS_WINCE) + if ((errnum = RegOpenKeyEx (hKey, 0, 0, 0, &result)) != ERROR_SUCCESS) +#else + if ((errnum = RegOpenKey (hKey, 0, &result)) != ERROR_SUCCESS) +#endif // ACE_HAS_WINCE + { + errno = errnum; + return 0; + } + + // recurse through the path + ACE_TCHAR *temp_path = 0; + ACE_NEW_RETURN (temp_path, + ACE_TCHAR[ACE_OS::strlen (path) + 1], + 0); + ACE_Auto_Basic_Array_Ptr pData (temp_path); + ACE_OS::strcpy (pData.get (), path); + ACE_Tokenizer parser (pData.get ()); + parser.delimiter_replace ('\\', '\0'); + parser.delimiter_replace ('/', '\0'); + + for (ACE_TCHAR *temp = parser.next (); + temp != 0; + temp = parser.next ()) + { + // Open the key + HKEY subkey; + +#if defined (ACE_HAS_WINCE) + if ((errnum = ACE_TEXT_RegOpenKeyEx (result, + temp, + 0, + 0, + &subkey)) != ERROR_SUCCESS) +#else + if ((errnum = ACE_TEXT_RegOpenKey (result, + temp, + &subkey)) != ERROR_SUCCESS) +#endif // ACE_HAS_WINCE + { + // try creating it + if (!create || (errnum = ACE_TEXT_RegCreateKeyEx (result, + temp, + 0, + 0, + 0, + KEY_ALL_ACCESS, + 0, + &subkey, +#if defined (__MINGW32__) + (PDWORD) 0 +#else + 0 +#endif /* __MINGW32__ */ + )) !=ERROR_SUCCESS) + { + errno = errnum; + // error + ::RegCloseKey (result); + return 0; + } + } + // release our open key handle + ::RegCloseKey (result); + result = subkey; + } + + return result; +} + +#endif /* ACE_WIN32 && !ACE_LACKS_WIN32_REGISTRY */ + +/////////////////////////////////////////////////////////////// + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void) + : type_ (ACE_Configuration::INVALID), + length_ (0) +{ + this->data_.ptr_ = 0; +} + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (ACE_TCHAR* string) + : type_ (ACE_Configuration::STRING), + length_ (0) +{ + this->data_.ptr_ = string; +} + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (u_int integer) + : type_ (ACE_Configuration::INTEGER), + length_ (0) +{ + this->data_.int_ = integer; +} + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void* data, size_t length) + : type_ (ACE_Configuration::BINARY), + length_ (length) +{ + this->data_.ptr_ = data; +} + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (const ACE_Configuration_Value_IntId& rhs) + : type_ (rhs.type_), + data_ (rhs.data_), + length_ (rhs.length_) +{ +} + +ACE_Configuration_Value_IntId::~ACE_Configuration_Value_IntId (void) +{ +} + +ACE_Configuration_Value_IntId& ACE_Configuration_Value_IntId::operator= (const ACE_Configuration_Value_IntId& rhs) +{ + if (this != &rhs) + { + type_ = rhs.type_; + data_ = rhs.data_; + length_ = rhs.length_; + } + return *this; +} + +void +ACE_Configuration_Value_IntId::free (ACE_Allocator *alloc) +{ + if (this->type_ == ACE_Configuration::STRING + || this->type_ == ACE_Configuration::BINARY) + alloc->free (data_.ptr_); + // Do nothing in other cases... +} + +ACE_Configuration_ExtId::ACE_Configuration_ExtId (void) + : name_ (0) +{ +} + +ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_TCHAR* name) + : name_ (name) +{ +} + +ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_Configuration_ExtId& rhs) + : name_ (rhs.name_) +{ +} + +ACE_Configuration_ExtId::~ACE_Configuration_ExtId (void) +{ +} + +ACE_Configuration_ExtId& ACE_Configuration_ExtId::operator= (const ACE_Configuration_ExtId& rhs) +{ + if (this != &rhs) + name_ = rhs.name_; + + return *this; +} + +bool +ACE_Configuration_ExtId::operator== (const ACE_Configuration_ExtId& rhs) const +{ + return (ACE_OS::strcasecmp (name_, rhs.name_) == 0); +} + +bool +ACE_Configuration_ExtId::operator!= (const ACE_Configuration_ExtId& rhs) const +{ + return !this->operator== (rhs); +} + +u_long +ACE_Configuration_ExtId::hash (void) const +{ + ACE_TString temp (name_, 0, false); + return temp.hash (); +} + +void +ACE_Configuration_ExtId::free (ACE_Allocator *alloc) +{ + alloc->free ((void *) (name_)); +} + +/////////////////////////////////////////////////////////////////////// + +ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (void) + : value_hash_map_ (0), + section_hash_map_ (0) +{ +} + +ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (VALUE_MAP* value_hash_map, SUBSECTION_MAP* section_hash_map) + : value_hash_map_ (value_hash_map), + section_hash_map_ (section_hash_map) +{ +} + +ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (const ACE_Configuration_Section_IntId& rhs) + : value_hash_map_ (rhs.value_hash_map_), + section_hash_map_ (rhs.section_hash_map_) +{ + +} + +ACE_Configuration_Section_IntId::~ACE_Configuration_Section_IntId () +{ +} + +ACE_Configuration_Section_IntId& +ACE_Configuration_Section_IntId::operator= (const ACE_Configuration_Section_IntId& rhs) +{ + if (this != &rhs) + { + value_hash_map_ = rhs.value_hash_map_; + section_hash_map_ = rhs.section_hash_map_; + } + return *this; +} + +void +ACE_Configuration_Section_IntId::free (ACE_Allocator *alloc) +{ + alloc->free ((void *) (value_hash_map_)); + alloc->free ((void *) (section_hash_map_)); +} + +ACE_Configuration_Section_Key_Heap::ACE_Configuration_Section_Key_Heap (const ACE_TCHAR* path) + : path_ (0), + value_iter_ (0), + section_iter_ (0) +{ + path_ = ACE_OS::strdup (path); +} + +ACE_Configuration_Section_Key_Heap::~ACE_Configuration_Section_Key_Heap () +{ + delete value_iter_; + delete section_iter_; + ACE_OS::free (path_); +} + +////////////////////////////////////////////////////////////////////////////// + +ACE_Configuration_Heap::ACE_Configuration_Heap (void) + : allocator_ (0), + index_ (0), + default_map_size_ (0) +{ + ACE_Configuration_Section_Key_Heap *temp = 0; + + ACE_NEW (temp, ACE_Configuration_Section_Key_Heap (ACE_TEXT (""))); + root_ = ACE_Configuration_Section_Key (temp); +} + +ACE_Configuration_Heap::~ACE_Configuration_Heap (void) +{ + if (allocator_) + allocator_->sync (); + + delete allocator_; +} + +int +ACE_Configuration_Heap::open (size_t default_map_size) +{ + default_map_size_ = default_map_size; + // Create the allocator with the appropriate options. + // The name used for the lock is the same as one used + // for the file. + ACE_NEW_RETURN (this->allocator_, + HEAP_ALLOCATOR (), + -1); + return create_index (); +} + + +int +ACE_Configuration_Heap::open (const ACE_TCHAR* file_name, + void* base_address, + size_t default_map_size) +{ + default_map_size_ = default_map_size; + + // Make sure that the file name is of the legal length. + if (ACE_OS::strlen (file_name) >= MAXNAMELEN + MAXPATHLEN) + { + errno = ENAMETOOLONG; + return -1; + } + + ACE_MMAP_Memory_Pool::OPTIONS options (base_address); + + // Create the allocator with the appropriate options. The name used + // for the lock is the same as one used for the file. + ACE_NEW_RETURN (this->allocator_, + PERSISTENT_ALLOCATOR (file_name, + file_name, + &options), + -1); + +#if !defined (ACE_LACKS_ACCESS) + // Now check if the backing store has been created successfully. + if (ACE_OS::access (file_name, F_OK) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("create_index\n")), + -1); +#endif /* ACE_LACKS_ACCESS */ + + return create_index (); +} + +int +ACE_Configuration_Heap::create_index (void) +{ + void *section_index = 0; + + // This is the easy case since if we find hash table in the + // memory-mapped file we know it's already initialized. + if (this->allocator_->find (ACE_CONFIG_SECTION_INDEX, section_index) == 0) + this->index_ = (SECTION_MAP *) section_index; + + // Create a new (because we've just created a new + // memory-mapped file). + else + { + size_t index_size = sizeof (SECTION_MAP); + section_index = this->allocator_->malloc (index_size); + + if (section_index == 0 + || create_index_helper (section_index) == -1 + || this->allocator_->bind (ACE_CONFIG_SECTION_INDEX, + section_index) == -1) + { + // Attempt to clean up. + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("create_index failed\n"))); + this->allocator_->remove (); + return -1; + } + // Add the root section + return new_section (ACE_TEXT (""), root_); + } + return 0; +} + +int +ACE_Configuration_Heap::create_index_helper (void *buffer) +{ + ACE_ASSERT (this->allocator_); + this->index_ = new (buffer) SECTION_MAP (this->allocator_); + return 0; +} + +int +ACE_Configuration_Heap::load_key (const ACE_Configuration_Section_Key& key, + ACE_TString& name) +{ + ACE_ASSERT (this->allocator_); + ACE_Configuration_Section_Key_Heap* pKey = + dynamic_cast (get_internal_key (key)); + + if (!pKey) + { + return -1; + } + + ACE_TString temp (pKey->path_, 0, false); + name.assign_nocopy (temp); + return 0; +} + + +int +ACE_Configuration_Heap::add_section (const ACE_Configuration_Section_Key& base, + const ACE_TCHAR* sub_section, + ACE_Configuration_Section_Key& result) +{ + ACE_ASSERT (this->allocator_); + ACE_TString section; + if (load_key (base, section)) + return -1; + + // Find the base section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; + + // See if this section already exists + ACE_Configuration_ExtId SubSectionExtId (sub_section); + int ignored = 0; + + if (!IntId.section_hash_map_->find (SubSectionExtId, ignored, allocator_)) + { + // already exists! + errno = EEXIST; + return -1; + } + + // Create the new section name + // only prepend a separater if were not at the root + if (section.length ()) + section += ACE_TEXT ("\\"); + + section += sub_section; + + // Add it to the base section + ACE_TCHAR* pers_name = (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (sub_section) + 1) * sizeof (ACE_TCHAR)); + ACE_OS::strcpy (pers_name, sub_section); + ACE_Configuration_ExtId SSExtId (pers_name); + if (IntId.section_hash_map_->bind (SSExtId, ignored, allocator_)) + { + allocator_->free (pers_name); + return -1; + } + return (new_section (section, result)); +} + +int +ACE_Configuration_Heap::new_section (const ACE_TString& section, + ACE_Configuration_Section_Key& result) +{ + ACE_ASSERT (this->allocator_); + // Create a new section and add it to the global list + + // Allocate memory for items to be stored in the table. + size_t section_len = section.length () + 1; + ACE_TCHAR *ptr = (ACE_TCHAR*) this->allocator_->malloc (section_len * sizeof (ACE_TCHAR)); + + int return_value = -1; + + if (ptr == 0) + return -1; + else + { + // Populate memory with data. + ACE_OS::strcpy (ptr, section.fast_rep ()); + + void *value_hash_map = 0; + size_t map_size = sizeof (VALUE_MAP); + value_hash_map = this->allocator_->malloc (map_size); + + // If allocation failed ... + if (value_hash_map == 0) + return -1; + + // Initialize allocated hash map through placement new. + if (value_open_helper (default_map_size_, value_hash_map ) == -1) + { + this->allocator_->free (value_hash_map ); + return -1; + } + + // create the section map + void* section_hash_map = 0; + map_size = sizeof (SUBSECTION_MAP); + section_hash_map = this->allocator_->malloc (map_size); + + // If allocation failed + if (section_hash_map == 0) + return -1; + + // initialize allocated hash map through placement new + if (section_open_helper (default_map_size_, section_hash_map) == -1) + { + this->allocator_->free (value_hash_map ); + this->allocator_->free (section_hash_map); + return -1; + } + + ACE_Configuration_ExtId name (ptr); + ACE_Configuration_Section_IntId entry ((VALUE_MAP*) value_hash_map, + (SUBSECTION_MAP*) section_hash_map); + + // Do a normal bind. This will fail if there's already an + // entry with the same name. + return_value = this->index_->bind (name, entry, this->allocator_); + + if (return_value == 1 /* Entry already existed so bind failed. */ + || return_value == -1 /* Unable to bind for other reasons. */) + { + // Free our dynamically allocated memory. + this->allocator_->free (static_cast (ptr)); + return return_value; + } + + // If bind () succeed, it will automatically sync + // up the map manager entry. However, we must sync up our + // name/value memory. + this->allocator_->sync (ptr, section_len); + } + + // set the result + ACE_Configuration_Section_Key_Heap *temp; + ACE_NEW_RETURN (temp, + ACE_Configuration_Section_Key_Heap (ptr), + -1); + result = ACE_Configuration_Section_Key (temp); + return return_value; +} + +int +ACE_Configuration_Heap::value_open_helper (size_t hash_table_size, + void *buffer) +{ + ACE_ASSERT (this->allocator_); + new (buffer) VALUE_MAP (hash_table_size, this->allocator_); + return 0; +} + +int +ACE_Configuration_Heap::section_open_helper (size_t hash_table_size, + void *buffer) +{ + ACE_ASSERT (this->allocator_); + new (buffer) SUBSECTION_MAP (hash_table_size, this->allocator_); + return 0; +} + +int +ACE_Configuration_Heap::open_section (const ACE_Configuration_Section_Key& base, + const ACE_TCHAR* sub_section, + int create, + ACE_Configuration_Section_Key& result) +{ + ACE_ASSERT (this->allocator_); + if (validate_name (sub_section, 1)) // 1 == allow_path + return -1; + + result = base; + + for (const ACE_TCHAR* separator; + (separator = ACE_OS::strchr (sub_section, ACE_TEXT ('\\'))) != 0; + ) + { + ACE_TString simple_section (sub_section, separator - sub_section); + int ret_val = + open_simple_section (result, simple_section.c_str (), create, result); + if (ret_val) + return ret_val; + sub_section = separator + 1; + } + + return open_simple_section (result, sub_section, create, result); +} + +int +ACE_Configuration_Heap::open_simple_section (const ACE_Configuration_Section_Key& base, + const ACE_TCHAR* sub_section, + int create, + ACE_Configuration_Section_Key& result) +{ + ACE_TString section (0, 0, false); + + if (load_key (base, section)) + { + return -1; + } + + // Only add the \\ if were not at the root + if (section.length ()) + { + section += ACE_TEXT ("\\"); + } + + section += sub_section; + + // resolve the section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + + if (index_->find (ExtId, IntId, allocator_)) + { + if (!create) + { + errno = ENOENT; + return -1; + } + + return add_section (base, sub_section, result); + } + + ACE_Configuration_Section_Key_Heap *temp; + ACE_NEW_RETURN (temp, + ACE_Configuration_Section_Key_Heap (section.fast_rep ()), + -1); + result = ACE_Configuration_Section_Key (temp); + return 0; +} + +int +ACE_Configuration_Heap::remove_section (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* sub_section, + int recursive) +{ + ACE_ASSERT (this->allocator_); + if (validate_name (sub_section)) + return -1; + + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this key + ACE_Configuration_ExtId ParentExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId ParentIntId; + if (index_->find (ParentExtId, ParentIntId, allocator_)) + return -1;// no parent key + + // Find this subkey + if (section.length ()) + section += ACE_TEXT ("\\"); + + section += sub_section; + ACE_Configuration_ExtId SectionExtId (section.fast_rep ()); + SECTION_HASH::ENTRY* section_entry; + SECTION_HASH* hashmap = index_; + if (hashmap->find (SectionExtId, section_entry)) + return -1; + + if (recursive) + { + ACE_Configuration_Section_Key section; + if (open_section (key, sub_section, 0, section)) + return -1; + + int index = 0; + ACE_TString name; + while (!enumerate_sections (section, index, name)) + { + if (remove_section (section, name.fast_rep (), 1)) + return -1; + + ++index; + } + } + + // Now make sure we dont have any subkeys + if (section_entry->int_id_.section_hash_map_->current_size ()) + { + errno = ENOTEMPTY; + return -1; + } + + // Now remove subkey from parent key + ACE_Configuration_ExtId SubSExtId (sub_section); + SUBSECTION_HASH::ENTRY* subsection_entry; + if (((SUBSECTION_HASH*)ParentIntId.section_hash_map_)-> + find (SubSExtId, subsection_entry)) + return -1; + + if (ParentIntId.section_hash_map_->unbind (SubSExtId, allocator_)) + return -1; + + subsection_entry->ext_id_.free (allocator_); + + // Remember the pointers so we can free them after we unbind + ACE_Configuration_ExtId ExtIdToFree (section_entry->ext_id_); + ACE_Configuration_Section_IntId IntIdToFree (section_entry->int_id_); + + // iterate over all values and free memory + VALUE_HASH* value_hash_map = section_entry->int_id_.value_hash_map_; + VALUE_HASH::ITERATOR value_iter = value_hash_map->begin (); + while (!value_iter.done ()) + { + VALUE_HASH::ENTRY* value_entry = 0; + if (!value_iter.next (value_entry)) + return 1; + + value_entry->ext_id_.free (allocator_); + value_entry->int_id_.free (allocator_); + + value_iter.advance (); + } + + // remove it + if (index_->unbind (SectionExtId, allocator_)) + return -1; + + value_hash_map->close (); + section_entry->int_id_.section_hash_map_->close (allocator_); + + // Free the memory + ExtIdToFree.free (allocator_); + IntIdToFree.free (allocator_); + + return 0; +} + +int +ACE_Configuration_Heap::enumerate_values (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name, + VALUETYPE& type) +{ + ACE_ASSERT (this->allocator_); + ACE_Configuration_Section_Key_Heap* pKey = + dynamic_cast (get_internal_key (key)); + if (!pKey) + return -1; + + name = pKey->path_; + + // resolve the section + ACE_Configuration_ExtId ExtId (pKey->path_); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; + + // Handle iterator resets + if (index == 0) + { + ACE_Hash_Map_Manager_Ex, + ACE_Equal_To, + ACE_Null_Mutex>* hash_map = IntId.value_hash_map_; + delete pKey->value_iter_; + + ACE_NEW_RETURN (pKey->value_iter_, + VALUE_HASH::ITERATOR (hash_map->begin ()), + -1); + } + + // Get the next entry + ACE_Hash_Map_Entry* entry = 0; + + if (!pKey->value_iter_->next (entry)) + return 1; + + // Return the value of the iterator and advance it + name = entry->ext_id_.name_; + type = entry->int_id_.type_; + pKey->value_iter_->advance (); + + return 0; +} + +int +ACE_Configuration_Heap::enumerate_sections (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name) +{ + ACE_ASSERT (this->allocator_); + // cast to a heap section key + ACE_Configuration_Section_Key_Heap* pKey = + dynamic_cast (get_internal_key (key)); + if (!pKey) + return -1; // not a heap key! + + // resolve the section + ACE_Configuration_ExtId ExtId (pKey->path_); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; // unknown section + + // Handle iterator resets + if (index == 0) + { + if (pKey->section_iter_) + delete pKey->section_iter_; + + ACE_NEW_RETURN (pKey->section_iter_, + SUBSECTION_HASH::ITERATOR (IntId.section_hash_map_->begin ()), + -1); + } + + // Get the next entry + ACE_Hash_Map_Entry* entry = 0; + if (!pKey->section_iter_->next (entry)) + return 1; + + // Return the value of the iterator and advance it + pKey->section_iter_->advance (); + name = entry->ext_id_.name_; + + return 0; +} + +int +ACE_Configuration_Heap::set_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const ACE_TString& value) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + ACE_TString section; + if (load_key (key, section)) + return -1; + + ACE_Configuration_ExtId section_ext (section.fast_rep ()); + ACE_Configuration_Section_IntId section_int; + if (index_->find (section_ext, section_int, allocator_)) + return -1; + + // Get the entry for this item (if it exists) + VALUE_HASH::ENTRY* entry; + ACE_Configuration_ExtId item_name (t_name); + if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0) + { + // found item, replace it + // Free the old value + entry->int_id_.free (allocator_); + // Allocate the new value in this heap + ACE_TCHAR* pers_value = + (ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR)); + ACE_OS::strcpy (pers_value, value.fast_rep ()); + ACE_Configuration_Value_IntId new_value_int (pers_value); + entry->int_id_ = new_value_int; + } + else + { + // it doesn't exist, bind it + ACE_TCHAR* pers_name = + (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR)); + ACE_OS::strcpy (pers_name, t_name); + ACE_TCHAR* pers_value = + (ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR)); + ACE_OS::strcpy (pers_value, value.fast_rep ()); + ACE_Configuration_ExtId item_name (pers_name); + ACE_Configuration_Value_IntId item_value (pers_value); + if (section_int.value_hash_map_->bind (item_name, item_value, allocator_)) + { + allocator_->free (pers_value); + allocator_->free (pers_name); + return -1; + } + return 0; + } + + return 0; +} + +int +ACE_Configuration_Heap::set_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int value) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this section + ACE_Configuration_ExtId section_ext (section.fast_rep ()); + ACE_Configuration_Section_IntId section_int; + if (index_->find (section_ext, section_int, allocator_)) + return -1; // section does not exist + + // Get the entry for this item (if it exists) + VALUE_HASH::ENTRY* entry; + ACE_Configuration_ExtId item_name (t_name); + if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0) + { + // found item, replace it + ACE_Configuration_Value_IntId new_value_int (value); + entry->int_id_ = new_value_int; + } + else + { + // it doesn't exist, bind it + ACE_TCHAR* pers_name = + (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR)); + ACE_OS::strcpy (pers_name, t_name); + ACE_Configuration_ExtId item_name (pers_name); + ACE_Configuration_Value_IntId item_value (value); + if (section_int.value_hash_map_->bind (item_name, item_value, allocator_)) + { + allocator_->free (pers_name); + return -1; + } + return 0; + } + + return 0; +} + +int +ACE_Configuration_Heap::set_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const void* data, + size_t length) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this section + ACE_Configuration_ExtId section_ext (section.fast_rep ()); + ACE_Configuration_Section_IntId section_int; + if (index_->find (section_ext, section_int, allocator_)) + return -1; // section does not exist + + // Get the entry for this item (if it exists) + VALUE_HASH::ENTRY* entry; + ACE_Configuration_ExtId item_name (t_name); + if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0) + { + // found item, replace it + // Free the old value + entry->int_id_.free (allocator_); + // Allocate the new value in this heap + ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length); + ACE_OS::memcpy (pers_value, data, length); + ACE_Configuration_Value_IntId new_value_int (pers_value, length); + entry->int_id_ = new_value_int; + } + else + { + // it doesn't exist, bind it + ACE_TCHAR* pers_name = + (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR)); + ACE_OS::strcpy (pers_name, t_name); + ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length); + ACE_OS::memcpy (pers_value, data, length); + ACE_Configuration_ExtId item_name (pers_name); + ACE_Configuration_Value_IntId item_value (pers_value, length); + if (section_int.value_hash_map_->bind (item_name, item_value, allocator_)) + { + allocator_->free (pers_value); + allocator_->free (pers_name); + return -1; + } + return 0; + } + + return 0; +} + +int +ACE_Configuration_Heap::get_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + ACE_TString& value) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; // section does not exist + + // See if it exists first + ACE_Configuration_ExtId VExtId (t_name); + ACE_Configuration_Value_IntId VIntId; + if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_)) + return -1; // unknown value + + // Check type + if (VIntId.type_ != ACE_Configuration::STRING) + { + errno = ENOENT; + return -1; + } + + // everythings ok, return the data + value = static_cast (VIntId.data_.ptr_); + return 0; +} + +int +ACE_Configuration_Heap::get_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int& value) +{ + ACE_ASSERT (this->allocator_); + + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section (0, 0, false); + + if (this->load_key (key, section) != 0) + { + return -1; + } + + // Find this section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + + if (index_->find (ExtId, IntId, allocator_) != 0) + { + return -1; // section does not exist + } + + + // See if it exists first + ACE_Configuration_ExtId VExtId (t_name); + ACE_Configuration_Value_IntId VIntId; + + if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_) != 0) + { + return -1; // unknown value + } + + // Check type + if (VIntId.type_ != ACE_Configuration::INTEGER) + { + errno = ENOENT; + return -1; + } + + // Everythings ok, return the data + value = VIntId.data_.int_; + return 0; +} + +int +ACE_Configuration_Heap::get_binary_value ( + const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + void*& data, + size_t& length) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; // section does not exist + + ACE_Configuration_ExtId VExtId (t_name); + ACE_Configuration_Value_IntId VIntId; + // See if it exists first + if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_)) + return -1; // unknown value + + // Check type + if (VIntId.type_ != ACE_Configuration::BINARY) + { + errno = ENOENT; + return -1; + } + + // Make a copy + ACE_NEW_RETURN (data, char[VIntId.length_], -1); + ACE_OS::memcpy (data, VIntId.data_.ptr_, VIntId.length_); + length = VIntId.length_; + return 0; +} + +int +ACE_Configuration_Heap::find_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + VALUETYPE& type_out) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; // section does not exist + + // Find it + ACE_Configuration_ExtId ValueExtId (t_name); + VALUE_HASH::ENTRY* value_entry; + if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry)) + return -1; // value does not exist + + type_out = value_entry->int_id_.type_; + return 0; +} + +int +ACE_Configuration_Heap::remove_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name) +{ + ACE_ASSERT (this->allocator_); + const ACE_TCHAR *t_name = name ? name : &this->NULL_String_; + if (validate_value_name (t_name)) + return -1; + + // Get the section name from the key + ACE_TString section; + if (load_key (key, section)) + return -1; + + // Find this section + ACE_Configuration_ExtId ExtId (section.fast_rep ()); + ACE_Configuration_Section_IntId IntId; + if (index_->find (ExtId, IntId, allocator_)) + return -1; // section does not exist + + // Find it + ACE_Configuration_ExtId ValueExtId (t_name); + VALUE_HASH::ENTRY* value_entry; + if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry)) + return -1; + + // free it + value_entry->ext_id_.free (allocator_); + value_entry->int_id_.free (allocator_); + + // Unbind it + if (IntId.value_hash_map_->unbind (ValueExtId, allocator_)) + return -1; + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Configuration.h b/dep/ACE_wrappers/ace/Configuration.h new file mode 100644 index 000000000..a0098c8ec --- /dev/null +++ b/dep/ACE_wrappers/ace/Configuration.h @@ -0,0 +1,894 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Configuration.h + * + * $Id: Configuration.h 82294 2008-07-12 13:03:37Z johnnyw $ + * + * @author Chris Hafey + * + * The ACE configuration API provides a portable abstraction for + * program configuration similar to the Microsoft Windows registry. + * The API supports a tree based hierarchy of configuration sections. Each + * section contains other sections or values. Values may contain string, + * unsigned integer and binary data. + * + * @note These classes are not thread safe, if multiple threads use these + * classes, you are responsible for serializing access. + * + * For examples of using this class, see: + * -# The test code in ACE_wrappers/test + * -# wxConfigViewer, a Windows like Registry Editor for ACE_Configuration + * -# TAO's IFR, it makes extensive use of ACE_Configuration + * + * @todo Templatize this class with an ACE_LOCK to provide thread safety + */ +//============================================================================= + +#ifndef ACE_CONFIGURATION_H +#define ACE_CONFIGURATION_H +#include /**/ "ace/pre.h" + +#include "ace/SStringfwd.h" +#include "ace/Hash_Map_With_Allocator_T.h" +#include "ace/Malloc_T.h" +#include "ace/MMAP_Memory_Pool.h" +#include "ace/Local_Memory_Pool.h" +#include "ace/Synch_Traits.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// configurable parameters + +#if !defined (ACE_CONFIG_SECTION_INDEX) +# define ACE_CONFIG_SECTION_INDEX "Config_Section_Index" +#endif /* ! ACE_CONFIG_SECTION_INDEX */ + +#if !defined (ACE_DEFAULT_CONFIG_SECTION_SIZE) +#define ACE_DEFAULT_CONFIG_SECTION_SIZE 16 +#endif /* ACE_DEFAULT_CONFIG_SECTION_SIZE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Section_Key_Internal + * + * @internal + * + * @brief A base class for internal handles to section keys for + * configuration implementations + * + * Implementations subclass this base class to represent a + * section key. + */ +class ACE_Export ACE_Section_Key_Internal +{ +public: + /// Virtual destructor, make sure descendants are virtual! + virtual ~ACE_Section_Key_Internal (void); + + /// Increment reference count + virtual int add_ref (void); + + /// Decrement reference count. Will delete this if count gets to 0 + virtual int dec_ref (void); +protected: + ACE_Section_Key_Internal (void); + ACE_Section_Key_Internal (const ACE_Section_Key_Internal& rhs); + ACE_Section_Key_Internal& operator= (ACE_Section_Key_Internal& rhs); + + u_int ref_count_; +}; + +/** + * @class ACE_Configuration_Section_Key + * + * @brief Reference counted wrapper for ACE_Section_Key_Internal. + * + * Reference counted wrapper class for the abstract internal + * section key. A user gets one of these to represent a section + * in the configuration database. + */ +class ACE_Export ACE_Configuration_Section_Key +{ + friend class ACE_Configuration; +public: + /// Default constructor. + ACE_Configuration_Section_Key (void); + + /// Constructor that initializes to a pointer to a concrete internal key. + /** + * @param key The section key to reference. Calls add_ref() with @a key. + */ + explicit ACE_Configuration_Section_Key (ACE_Section_Key_Internal *key); + + /// Copy constructor, increments the reference count on the key. + ACE_Configuration_Section_Key (const ACE_Configuration_Section_Key &rhs); + + /// Destructor, decrements reference count on the referenced key. + ~ACE_Configuration_Section_Key (void); + + /// Assignment operator, increments reference count for this object + /// and decrements it on @a rhs. + ACE_Configuration_Section_Key & + operator= (const ACE_Configuration_Section_Key &rhs); +private: + ACE_Section_Key_Internal *key_; +}; + +/** + * @class ACE_Configuration + * + * @internal + * + * @brief Base class for configuration databases + * + * This class provides an interface for configuration databases. A concrete + * class is required that implements the interface. + * + * @sa ACE_Configuration_Heap + * @sa ACE_Configuration_Win32Registry + */ +class ACE_Export ACE_Configuration +{ +public: + /// Enumeration for the various types of values we can store. + enum VALUETYPE + { + STRING, + INTEGER, + BINARY, + INVALID + }; + + /// Destructor + virtual ~ACE_Configuration (void); + + /// Obtain a reference to the root section of this configuration. + /* + * @return Reference to the configuration's root section. Note that + * it is a const reference. + */ + virtual const ACE_Configuration_Section_Key& root_section (void) const; + + /** + * Opens a named section in an existing section. + * + * @param base Existing section in which to open the named section. + * @param sub_section Name of the section to open. + * @param create If zero, the named section must exist. If non-zero, + * the named section will be created if it does not exist. + * @param result Reference; receives the section key for the new + * section. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int open_section (const ACE_Configuration_Section_Key &base, + const ACE_TCHAR *sub_section, + int create, + ACE_Configuration_Section_Key& result) = 0; + + /// Removes a named section. + /** + * @param key Section key to remove the named section from. + * @param sub_section Name of the section to remove. + * @param recursive If non zero, any subkeys below @a sub_section are + * removed as well. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int remove_section (const ACE_Configuration_Section_Key &key, + const ACE_TCHAR *sub_section, + int recursive) = 0; + + /** + * Enumerates through the values in a section. + * + * @param key Section key to iterate through. + * @param index Iteration position. Must be zero on the first call to + * iterate through @a key. Increment @a index by one on each + * successive call to this method. + * @param name Receives the value's name. + * @param type Receives the value's data type. + * + * @note You may not delete or add values while enumerating. If the + * section is modified during enumeration, results are undefined; + * you must restart the enumeration from index 0. + * + * @retval 0 for success, @a name and @a type are valid. + * @retval 1 there are no more values in the section. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int enumerate_values (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name, + VALUETYPE& type) = 0; + + /** + * Enumerates through the subsections in a section. + * + * @param key Section key to iterate through. + * @param index Iteration position. Must be zero on the first call to + * iterate through @a key. Increment @a index by one on each + * successive call to this method. + * @param name Receives the subsection's name. + * + * @note You may not modify the @a key section while enumerating. If the + * section is modified during enumeration, results are undefined; + * you must restart the enumeration from index 0. + * + * @retval 0 for success, @a name has a valid name. + * @retval 1 there are no more subsections in the section. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int enumerate_sections (const ACE_Configuration_Section_Key& key, + int index, ACE_TString& name) = 0; + + /// Sets a string-typed value. + /** + * @param key Configuration section to set the value in. + * @param name Name of the configuration value to set. If a value with + * the specified name exists, it is replaced. + * @param value The string to set the configuration value to. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int set_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const ACE_TString& value) = 0; + + /// Sets a integer-typed value. + /** + * @param key Configuration section to set the value in. + * @param name Name of the configuration value to set. If a value with + * the specified name exists, it is replaced. + * @param value The integer to set the configuration value to. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int set_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int value) = 0; + + /// Sets a binary-typed value. + /** + * @param key Configuration section to set the value in. + * @param name Name of the configuration value to set. If a value with + * the specified name exists, it is replaced. + * @param data Pointer to the binary data for the value. + * @param length Number of bytes for the new value. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int set_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const void* data, + size_t length) = 0; + + /// Gets a string-typed value. + /** + * @param key Configuration section to get the value from. + * @param name Name of the configuration value to get. + * @param value Receives the configuration value if it exists and + * has type STRING. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int get_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + ACE_TString& value) = 0; + + /// Gets an integer-typed value. + /** + * @param key Configuration section to get the value from. + * @param name Name of the configuration value to get. + * @param value Receives the configuration value if it exists and + * has type INTEGER. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int get_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int& value) = 0; + + /// Gets a binary-typed value. + /** + * @param key Configuration section to get the value from. + * @param name Name of the configuration value to get. + * @param data Receives a pointer to memory holding the binary data + * for the value. This method allocates the memory pointed + * to using operator new[]. The caller is responsible for + * freeing the memory using operator delete[]. + * @param length Receives the number of bytes in the value. + * + * @retval 0 for success; caller is responsible for freeing the + * returned memory. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int get_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + void*& data, + size_t& length) = 0; + + /** + * Retrieves the type of a named configuration value. + * + * @param key Configuration section to look up the name in. + * @param name Name of the configuration value to get the type of. + * @param type Receives the data type of the named value, if it exists. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int find_value(const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + VALUETYPE& type) = 0; + + /// Removes a named value. + /** + * @param key Configuration section to remove the named value from. + * @param name Name of the configuration value to remove. + * + * @retval 0 for success. + * @retval -1 for error; ACE_OS::last_error() retrieves error code. + */ + virtual int remove_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name) = 0; + + /** + * Expands @a path_in to @a key_out from @a key. If create is true, + * the subsections are created. Returns 0 on success, non zero on + * error The path consists of sections separated by the backslash + * '\' or forward slash '/'. + * Returns 0 on success, -1 if + virtual ~ACE_Section_Key_Win32 (void); + + // Not used + ACE_Section_Key_Win32 (const ACE_Section_Key_Win32& rhs); + ACE_Section_Key_Win32& operator= (const ACE_Section_Key_Win32& rhs); +}; + +/** + * @class ACE_Configuration_Win32Registry + * + * @brief The win32 registry implementation of a configuration database + * + * The win32 implementation basically makes calls through to the + * registry functions. The API is very similar so very little + * work must be done + */ +class ACE_Export ACE_Configuration_Win32Registry : public ACE_Configuration +{ +public: + + /** + * Constructor for registry configuration database. hKey is the + * base registry key to attach to. This class takes ownership of + * hKey, it will invoke on it upon destruction. + */ + explicit ACE_Configuration_Win32Registry (HKEY hKey); + + /// Destructor + virtual ~ACE_Configuration_Win32Registry (void); + + virtual int open_section (const ACE_Configuration_Section_Key& base, + const ACE_TCHAR* sub_section, + int create, + ACE_Configuration_Section_Key& result); + + virtual int remove_section (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* sub_section, + int recursive); + + virtual int enumerate_values (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name, + VALUETYPE& type); + + virtual int enumerate_sections (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name); + + virtual int set_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const ACE_TString& value); + + virtual int set_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int value); + + virtual int set_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const void* data, + size_t length); + + virtual int get_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + ACE_TString& value); + + virtual int get_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int& value); + + virtual int get_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + void*& data, + size_t& length); + + virtual int find_value(const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + VALUETYPE& type); + + /// Removes the the value @a name from @a key. returns non zero on error + virtual int remove_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name); + + /** + * This method traverses through . It is useful when + * you want the HKEY for a specific registry key, especially when + * initializing this implementation. Caller is responsible for + * closeing this key when it is no longer used. If create is 1 + * (default) the keys are create if they don't already exist. + * Returns 0 on error + */ + static HKEY resolve_key (HKEY hKey, + const ACE_TCHAR* path, + int create = 1); + virtual bool operator== (const ACE_Configuration_Win32Registry &rhs) const; + virtual bool operator!= (const ACE_Configuration_Win32Registry &rhs) const; + +protected: + + /// Gets the HKEY for a configuration section + int load_key (const ACE_Configuration_Section_Key& key, HKEY& hKey); + + // Not used + ACE_Configuration_Win32Registry (void); + ACE_Configuration_Win32Registry (const ACE_Configuration_Win32Registry& rhs); + ACE_Configuration_Win32Registry& operator= (const ACE_Configuration_Win32Registry& rhs); +}; +#endif /* ACE_WIN32 && !ACE_LACKS_WIN32_REGISTRY */ + +// ACE_Allocator version + +typedef ACE_Allocator_Adapter > + PERSISTENT_ALLOCATOR; +typedef ACE_Allocator_Adapter > + HEAP_ALLOCATOR; + +/** + * @class ACE_Configuration_ExtId + * + * @brief External ID for the section and value hash + * + * Contains a pointer to the section or value name. + */ +class ACE_Export ACE_Configuration_ExtId +{ +public: + /// Defeault ctor + ACE_Configuration_ExtId (void); + + /// Named constructor + explicit ACE_Configuration_ExtId (const ACE_TCHAR* name); + + /// Copy ctor + ACE_Configuration_ExtId (const ACE_Configuration_ExtId& rhs); + + /// destructor + ~ACE_Configuration_ExtId (void); + + /// Assignment operator + ACE_Configuration_ExtId& operator= (const ACE_Configuration_ExtId& rhs); + + /// Equality comparison operator (must match name_). + bool operator== (const ACE_Configuration_ExtId &rhs) const; + + /// Inequality comparison operator. + bool operator!= (const ACE_Configuration_ExtId &rhs) const; + + /// Frees the name of the value. needed since we don't know the + /// allocator name_ was created in + void free (ACE_Allocator *alloc); + + /// function is required in order for this class to be usable by + /// ACE_Hash_Map_Manager. + u_long hash (void) const; + + // = Data members. + + const ACE_TCHAR * name_; + + // Accessors + const ACE_TCHAR *name (void); +}; + +typedef ACE_Hash_Map_With_Allocator + SUBSECTION_MAP; +typedef ACE_Hash_Map_Manager_Ex, + ACE_Equal_To, + ACE_Null_Mutex> + SUBSECTION_HASH; + +/// @deprecated Deprecated typedef. Use the SUBSECTION_HASH::ENTRY trait instead. +typedef SUBSECTION_HASH::ENTRY SUBSECTION_ENTRY; + +/** + * @class ACE_Configuration_Value_IntId + * + * @brief The section hash table internal value class + * + * This class is present as the internal portion of a section's + * value hash table It may store string, integer or binary data. + */ +class ACE_Export ACE_Configuration_Value_IntId +{ +public: + /// Default constructor + ACE_Configuration_Value_IntId (void); + + /// String constructor, takes ownership of string + explicit ACE_Configuration_Value_IntId (ACE_TCHAR* string); + + /// Integer constructor + explicit ACE_Configuration_Value_IntId (u_int integer); + + /// Binary constructor, takes ownership of data + ACE_Configuration_Value_IntId (void* data, size_t length); + + /// Copy ctor + ACE_Configuration_Value_IntId (const ACE_Configuration_Value_IntId& rhs); + + /// Destructor + ~ACE_Configuration_Value_IntId (void); + + /// Assignment operator + ACE_Configuration_Value_IntId& operator= ( + const ACE_Configuration_Value_IntId& rhs); + + void free (ACE_Allocator *alloc); + + // = Data members. + + /** + * Points to the string value or binary data or IS the integer + * Length is only used when type_ == BINARY + */ + ACE_Configuration::VALUETYPE type_; + union { + void * ptr_; + u_int int_; + } data_; + size_t length_; +}; + +typedef ACE_Hash_Map_With_Allocator + VALUE_MAP; +typedef ACE_Hash_Map_Manager_Ex, + ACE_Equal_To, + ACE_Null_Mutex> + VALUE_HASH; + +// Deprecated typedef. Use the VALUE_HASH::ENTRY trait instead. +typedef VALUE_HASH::ENTRY VALUE_ENTRY; + +/** + * @class ACE_Configuration_Section_IntId + * + * @brief The internal ID for a section hash table + * + * Contains a hash table containing value name/values + */ +class ACE_Export ACE_Configuration_Section_IntId +{ +public: + /// Default ctor + ACE_Configuration_Section_IntId (void); + + /// Named ctor + ACE_Configuration_Section_IntId (VALUE_MAP* value_hash_map, + SUBSECTION_MAP* section_hash_map); + + /// Copy ctor + ACE_Configuration_Section_IntId (const ACE_Configuration_Section_IntId& rhs); + + /// Destructor + ~ACE_Configuration_Section_IntId (void); + + /// Assignment operator + ACE_Configuration_Section_IntId& operator= ( + const ACE_Configuration_Section_IntId& rhs); + + /// Frees the hash table and all its values + void free (ACE_Allocator *alloc); + + // = Data Members. + VALUE_MAP* value_hash_map_; + + SUBSECTION_MAP* section_hash_map_; +}; + +typedef ACE_Hash_Map_With_Allocator + SECTION_MAP; +typedef ACE_Hash_Map_Manager_Ex, + ACE_Equal_To, + ACE_Null_Mutex> + SECTION_HASH; + +// Deprecated typedef. Use the SECTION_HASH::ENTRY trait instead. +typedef SECTION_HASH::ENTRY SECTION_ENTRY; + +/** + * @class ACE_Configuration_Section_Key_Heap + * + * @brief Internal section key class for heap based configuration + * database. + * + * Contains a value iterator and full path name of section. + */ +class ACE_Export ACE_Configuration_Section_Key_Heap + : public ACE_Section_Key_Internal +{ +public: + /// Constructor based on the full path of the section + ACE_Configuration_Section_Key_Heap (const ACE_TCHAR* path); + + /// The path itself + ACE_TCHAR* path_; + + /// The value iterator + VALUE_HASH::ITERATOR* value_iter_; + + /// The sub section iterator + SUBSECTION_HASH::ITERATOR* section_iter_; +protected: + /// Destructor - will delete the iterators + virtual ~ACE_Configuration_Section_Key_Heap (void); + + // Not used + ACE_Configuration_Section_Key_Heap (const ACE_Configuration_Section_Key_Heap& rhs); + ACE_Configuration_Section_Key_Heap& operator= (const ACE_Configuration_Section_Key_Heap& rhs); +}; + +/** + * @class ACE_Configuration_Heap + * + * @brief The concrete implementation of a allocator based + * configuration database + * + * This class uses ACE's Allocators to manage a memory + * representation of a configuration database. A persistent heap + * may be used to store configurations persistently + * + * @note Before using this class you must call one of the open methods. + * + * @todo + * - Need to investigate what happens if memory mapped file gets mapped to + * a location different than it was created with. + */ +class ACE_Export ACE_Configuration_Heap : public ACE_Configuration +{ +public: + + /// Default ctor + ACE_Configuration_Heap (void); + + /// Destructor + virtual ~ACE_Configuration_Heap (void); + + /// Opens a configuration based on a file name + int open (const ACE_TCHAR* file_name, + void* base_address = ACE_DEFAULT_BASE_ADDR, + size_t default_map_size = ACE_DEFAULT_CONFIG_SECTION_SIZE); + + /// Opens a heap based configuration + int open (size_t default_map_size = ACE_DEFAULT_CONFIG_SECTION_SIZE); + + virtual int open_section (const ACE_Configuration_Section_Key& base, + const ACE_TCHAR* sub_section, + int create, ACE_Configuration_Section_Key& result); + + virtual int remove_section (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* sub_section, + int recursive); + + virtual int enumerate_values (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name, + VALUETYPE& type); + + virtual int enumerate_sections (const ACE_Configuration_Section_Key& key, + int index, + ACE_TString& name); + + virtual int set_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const ACE_TString& value); + + virtual int set_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int value); + + virtual int set_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + const void* data, + size_t length); + + virtual int get_string_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + ACE_TString& value); + + virtual int get_integer_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + u_int& value); + + virtual int get_binary_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + void* &data, + size_t &length); + + virtual int find_value(const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name, + VALUETYPE& type); + + /// Removes the the value @a name from @a key. returns non zero on error + virtual int remove_value (const ACE_Configuration_Section_Key& key, + const ACE_TCHAR* name); + +private: + /// @a sub_section may not contain path separators + int open_simple_section (const ACE_Configuration_Section_Key &base, + const ACE_TCHAR *sub_section, + int create, ACE_Configuration_Section_Key &result); + /// Adds a new section + int add_section (const ACE_Configuration_Section_Key &base, + const ACE_TCHAR *sub_section, + ACE_Configuration_Section_Key &result); + + /// Helper for the method. + int create_index (void); + + /// Helper for create_index() method: places hash table into an + /// allocated space. + int create_index_helper (void *buffer); + + int value_open_helper (size_t hash_table_size, void *buffer); + + int section_open_helper (size_t hash_table_size, void *buffer); + + int load_key (const ACE_Configuration_Section_Key& key, ACE_TString& name); + + int new_section (const ACE_TString& section, + ACE_Configuration_Section_Key& result); + + ACE_Configuration_Heap (const ACE_Configuration_Heap& rhs); + ACE_Configuration_Heap& operator= (const ACE_Configuration_Heap& rhs); + + ACE_Allocator *allocator_; + SECTION_MAP *index_; + size_t default_map_size_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Configuration.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIGURATION_H */ diff --git a/dep/ACE_wrappers/ace/Configuration.inl b/dep/ACE_wrappers/ace/Configuration.inl new file mode 100644 index 000000000..19c2c591b --- /dev/null +++ b/dep/ACE_wrappers/ace/Configuration.inl @@ -0,0 +1,13 @@ +// -*- C++ -*- +// +// $Id: Configuration.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE const ACE_TCHAR* +ACE_Configuration_ExtId::name (void) +{ + return name_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Configuration_Import_Export.cpp b/dep/ACE_wrappers/ace/Configuration_Import_Export.cpp new file mode 100644 index 000000000..88e6d66f2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Configuration_Import_Export.cpp @@ -0,0 +1,670 @@ +// $Id: Configuration_Import_Export.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Configuration_Import_Export.h" +#include "ace/OS_Errno.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Config_ImpExp_Base::ACE_Config_ImpExp_Base (ACE_Configuration& config) + : config_ (config) +{ +} + +ACE_Config_ImpExp_Base::~ACE_Config_ImpExp_Base (void) +{ +} + +ACE_Registry_ImpExp::ACE_Registry_ImpExp (ACE_Configuration& config) + : ACE_Config_ImpExp_Base (config) +{ +} + +ACE_Registry_ImpExp::~ACE_Registry_ImpExp (void) +{ +} + +// Imports the configuration database from filename. +// No existing data is removed. +int +ACE_Registry_ImpExp::import_config (const ACE_TCHAR* filename) +{ + if (0 == filename) + { + errno = EINVAL; + return -1; + } + FILE* in = ACE_OS::fopen (filename, ACE_TEXT ("r")); + if (!in) + return -1; + + u_int buffer_size = 4096; + u_int read_pos = 0; + ACE_TCHAR *buffer = 0; + ACE_NEW_NORETURN (buffer, ACE_TCHAR[buffer_size]); + if (!buffer) + { + ACE_Errno_Guard guard (errno); + (void) ACE_OS::fclose (in); + return -1; + } + ACE_Configuration_Section_Key section; + ACE_TCHAR *end = 0; + + while (ACE_OS::fgets (buffer+read_pos, buffer_size - read_pos, in)) + { + // Check if we got all the line. + end = ACE_OS::strrchr (buffer + read_pos, + ACE_TEXT ('\n')); // look for end of line + if (!end) // we havn't reach the end of the line yet + { + // allocate a new buffer - double size the previous one + ACE_TCHAR *temp_buffer; + ACE_NEW_NORETURN (temp_buffer, ACE_TCHAR[buffer_size * 2]); + if (!temp_buffer) + { + ACE_Errno_Guard guard (errno); + delete [] buffer; + (void) ACE_OS::fclose (in); + return -1; + } + + // copy the beginnning of the line + ACE_OS::memcpy (temp_buffer, buffer, buffer_size); + read_pos = buffer_size - 1; + buffer_size *= 2; + delete [] buffer; + buffer = temp_buffer; + continue; + } + read_pos = 0; + + // Check for a comment + if (buffer[0] == ACE_TEXT (';') || buffer[0] == ACE_TEXT ('#')) + continue; + + if (buffer[0] == ACE_TEXT ('[')) + { + // We have a new section here, strip out the section name + end = ACE_OS::strrchr (buffer, ACE_TEXT (']')); + if (!end) + { + ACE_OS::fclose (in); + delete [] buffer; + return -3; + } + *end = 0; + + if (config_.expand_path (config_.root_section (), buffer + 1, section, 1)) + { + ACE_OS::fclose (in); + delete [] buffer; + return -3; + } + continue; + } // end if firs char is a [ + + if (buffer[0] == ACE_TEXT ('"')) + { + // we have a value + end = ACE_OS::strchr (buffer+1, '"'); + if (!end) // no closing quote, not a value so just skip it + continue; + + // null terminate the name + *end = 0; + ACE_TCHAR* name = buffer + 1; + end+=2; + // determine the type + if (*end == '\"') + { + // string type + // truncate trailing " + ++end; + ACE_TCHAR* trailing = ACE_OS::strrchr (end, '"'); + if (trailing) + *trailing = 0; + if (config_.set_string_value (section, name, end)) + { + ACE_OS::fclose (in); + delete [] buffer; + return -4; + } + } + else if (ACE_OS::strncmp (end, ACE_TEXT ("dword:"), 6) == 0) + { + // number type + ACE_TCHAR* endptr = 0; + unsigned long value = ACE_OS::strtoul (end + 6, &endptr, 16); + if (config_.set_integer_value (section, name, value)) + { + ACE_OS::fclose (in); + delete [] buffer; + return -4; + } + } + else if (ACE_OS::strncmp (end, ACE_TEXT ("hex:"), 4) == 0) + { + // binary type + size_t string_length = ACE_OS::strlen (end + 4); + // divide by 3 to get the actual buffer length + size_t length = string_length / 3; + size_t remaining = length; + u_char* data = 0; + ACE_NEW_RETURN (data, + u_char[length], + -1); + u_char* out = data; + ACE_TCHAR* inb = end + 4; + ACE_TCHAR* endptr = 0; + while (remaining) + { + u_char charin = (u_char) ACE_OS::strtoul (inb, &endptr, 16); + *out = charin; + ++out; + --remaining; + inb += 3; + } + if (config_.set_binary_value (section, name, data, length)) + { + ACE_OS::fclose (in); + delete [] data; + delete [] buffer; + return -4; + } + else + delete [] data; + } + else + { + // invalid type, ignore + continue; + } + }// end if first char is a " + else + { + // if the first character is not a ", [, ;, or # we may be + // processing a file in the old format. + // Try and process the line as such and if it fails, + // return an error + int rc = process_previous_line_format (buffer, section); + if (rc != 0) + { + ACE_OS::fclose (in); + delete [] buffer; + return rc; + } + } // end if maybe old format + } // end while fgets + + if (ferror (in)) + { + ACE_OS::fclose (in); + delete [] buffer; + return -1; + } + + ACE_OS::fclose (in); + delete [] buffer; + return 0; +} + +// This method exports the entire configuration database to . +// Once the file is opened this method calls 'export_section' passing +// the root section. +int +ACE_Registry_ImpExp::export_config (const ACE_TCHAR* filename) +{ + if (0 == filename) + { + errno = EINVAL; + return -1; + } + int result = -1; + + FILE* out = ACE_OS::fopen (filename, ACE_TEXT ("w")); + if (out) + { + result = this->export_section (config_.root_section (), + ACE_TEXT (""), + out); + // The data may have been buffered and will be flush on close, + // so we need to check that the close succeeds. + if (ACE_OS::fclose (out) < 0) + result = -7; + } + return result; +} + +// Method provided by derived classes in order to write one section +// to the file specified. Called by export_config when exporting +// the entire configuration object. + +int +ACE_Registry_ImpExp::export_section (const ACE_Configuration_Section_Key& section, + const ACE_TString& path, + FILE* out) +{ + // don't export the root + if (path.length ()) + { + // Write out the section header + ACE_TString header = ACE_TEXT ("["); + header += path; + header += ACE_TEXT ("]"); + header += ACE_TEXT (" \n"); + if (ACE_OS::fputs (header.fast_rep (), out) < 0) + return -1; + // Write out each value + int index = 0; + ACE_TString name; + ACE_Configuration::VALUETYPE type; + ACE_TString line; + ACE_TCHAR int_value[32]; + ACE_TCHAR bin_value[3]; + void* binary_data; + size_t binary_length; + ACE_TString string_value; + while (!config_.enumerate_values (section, index, name, type)) + { + line = ACE_TEXT ("\"") + name + ACE_TEXT ("\"="); + switch (type) + { + case ACE_Configuration::INTEGER: + { + u_int value; + if (config_.get_integer_value (section, name.fast_rep (), value)) + return -2; + ACE_OS::sprintf (int_value, ACE_TEXT ("%08x"), value); + line += ACE_TEXT ("dword:"); + line += int_value; + break; + } + case ACE_Configuration::STRING: + { + if (config_.get_string_value (section, + name.fast_rep (), + string_value)) + return -2; + line += ACE_TEXT ("\""); + line += string_value + ACE_TEXT ("\""); + break; + } +#ifdef _WIN32 + case ACE_Configuration::INVALID: + break; // JDO added break. Otherwise INVALID is processed + // like BINARY. If that's correct, please remove the + // break and these comments +#endif + case ACE_Configuration::BINARY: + { + // not supported yet - maybe use BASE64 codeing? + if (config_.get_binary_value (section, + name.fast_rep (), + binary_data, + binary_length)) + return -2; + line += ACE_TEXT ("hex:"); + unsigned char* ptr = (unsigned char*)binary_data; + while (binary_length) + { + if (ptr != binary_data) + { + line += ACE_TEXT (","); + } + ACE_OS::sprintf (bin_value, ACE_TEXT ("%02x"), *ptr); + line += bin_value; + --binary_length; + ++ptr; + } + delete [] (char*) binary_data; + break; + } + default: + return -3; + } + line += ACE_TEXT ("\n"); + if (ACE_OS::fputs (line.fast_rep (), out) < 0) + return -4; + ++index; + } + } + // Export all sub sections + int index = 0; + ACE_TString name; + ACE_Configuration_Section_Key sub_key; + ACE_TString sub_section; + while (!config_.enumerate_sections (section, index, name)) + { + ACE_TString sub_section (path); + if (path.length ()) + sub_section += ACE_TEXT ("\\"); + sub_section += name; + if (config_.open_section (section, name.fast_rep (), 0, sub_key)) + return -5; + if (export_section (sub_key, sub_section.fast_rep (), out)) + return -6; + ++index; + } + return 0; +} + +// +// This method read the line format origionally used in ACE 5.1 +// +int +ACE_Registry_ImpExp::process_previous_line_format (ACE_TCHAR* buffer, + ACE_Configuration_Section_Key& section) +{ + // Chop any cr/lf at the end of the line. + ACE_TCHAR *endp = ACE_OS::strpbrk (buffer, ACE_TEXT ("\r\n")); + if (endp != 0) + *endp = '\0'; + + // assume this is a value, read in the value name + ACE_TCHAR* end = ACE_OS::strchr (buffer, '='); + if (end) // no =, not a value so just skip it + { + // null terminate the name + *end = 0; + ++end; + // determine the type + if (*end == '\"') + { + // string type + if(config_.set_string_value (section, buffer, end + 1)) + return -4; + } + else if (*end == '#') + { + // number type + u_int value = ACE_OS::atoi (end + 1); + if (config_.set_integer_value (section, buffer, value)) + return -4; + } + } + return 0; +} // end read_previous_line_format + + +ACE_Ini_ImpExp::ACE_Ini_ImpExp (ACE_Configuration& config) + : ACE_Config_ImpExp_Base (config) +{ +} + +ACE_Ini_ImpExp::~ACE_Ini_ImpExp (void) +{ +} + +// Method to read file and populate object. +int +ACE_Ini_ImpExp::import_config (const ACE_TCHAR* filename) +{ + if (0 == filename) + { + errno = EINVAL; + return -1; + } + FILE* in = ACE_OS::fopen (filename, ACE_TEXT ("r")); + if (!in) + return -1; + + // @@ Make this a dynamic size! + ACE_TCHAR buffer[4096]; + ACE_Configuration_Section_Key section; + while (ACE_OS::fgets (buffer, sizeof buffer, in)) + { + ACE_TCHAR *line = this->squish (buffer); + // Check for a comment and blank line + if (line[0] == ACE_TEXT (';') || + line[0] == ACE_TEXT ('#') || + line[0] == '\0') + continue; + + if (line[0] == ACE_TEXT ('[')) + { + // We have a new section here, strip out the section name + ACE_TCHAR* end = ACE_OS::strrchr (line, ACE_TEXT (']')); + if (!end) + { + ACE_OS::fclose (in); + return -3; + } + *end = 0; + + if (config_.expand_path (config_.root_section (), + line + 1, + section, + 1)) + { + ACE_OS::fclose (in); + return -3; + } + + continue; + } + + // We have a line; name ends at equal sign. + ACE_TCHAR *end = ACE_OS::strchr (line, ACE_TEXT ('=')); + if (end == 0) // No '=' + { + ACE_OS::fclose (in); + return -3; + } + *end++ = '\0'; + ACE_TCHAR *name = this->squish (line); +#if 0 + if (ACE_OS::strlen (name) == 0) // No name; just an '=' + { + ACE_OS::fclose (in); + return -3; + } +#endif + // Now find the start of the value + ACE_TCHAR *value = this->squish (end); + size_t value_len = ACE_OS::strlen (value); + if (value_len > 0) + { + // ACE 5.2 (and maybe earlier) exported strings may be enclosed + // in quotes. If string is quote-delimited, strip the quotes. + // Newer exported files don't have quote delimiters. + if (value[0] == ACE_TEXT ('"') && + value[value_len - 1] == ACE_TEXT ('"')) + { + // Strip quotes off both ends. + value[value_len - 1] = '\0'; + ++value; + } + } + + if (config_.set_string_value (section, name, value)) + { + ACE_OS::fclose (in); + return -4; + } + } // end while fgets + + if (ferror (in)) + { + ACE_OS::fclose (in); + return -1; + } + + ACE_OS::fclose (in); + return 0; +} + +// This method exports the entire configuration database to . +// Once the file is opened this method calls 'export_section' passing +// the root section. +int +ACE_Ini_ImpExp::export_config (const ACE_TCHAR* filename) +{ + if (0 == filename) + { + errno = EINVAL; + return -1; + } + int result = -1; + + FILE* out = ACE_OS::fopen (filename, ACE_TEXT ("w")); + if (out) + { + result = this->export_section (config_.root_section (), + ACE_TEXT (""), + out); + // The data may have been buffered and will be flush on close, + // so we need to check that the close succeeds. + if (ACE_OS::fclose (out) < 0) + result = -7; + } + return result; +} + +// Method provided by derived classes in order to write one section to the +// file specified. Called by export_config when exporting the entire +// configuration objet + +int +ACE_Ini_ImpExp::export_section (const ACE_Configuration_Section_Key& section, + const ACE_TString& path, + FILE* out) +{ + // don't export the root + if (path.length ()) + { + // Write out the section header + ACE_TString header = ACE_TEXT ("["); + header += path; + header += ACE_TEXT ("]\n"); + if (ACE_OS::fputs (header.fast_rep (), out) < 0) + return -1; + // Write out each value + int index = 0; + ACE_TString name; + ACE_Configuration::VALUETYPE type; + ACE_TString line; + ACE_TCHAR int_value[32]; + ACE_TCHAR bin_value[3]; + void* binary_data; + size_t binary_length; + ACE_TString string_value; + while (!config_.enumerate_values (section, index, name, type)) + { + line = name + ACE_TEXT ("="); + switch (type) + { + case ACE_Configuration::INTEGER: + { + u_int value; + if (config_.get_integer_value (section, name.fast_rep (), value)) + return -2; + ACE_OS::sprintf (int_value, ACE_TEXT ("%08x"), value); + line += int_value; + break; + } + case ACE_Configuration::STRING: + { + if (config_.get_string_value (section, + name.fast_rep (), + string_value)) + return -2; + line += string_value; + break; + } +#ifdef _WIN32 + case ACE_Configuration::INVALID: + break; // JDO added break. Otherwise INVALID is processed + // like BINARY. If that's correct, please remove the + // break and these comments +#endif + case ACE_Configuration::BINARY: + { + // not supported yet - maybe use BASE64 codeing? + if (config_.get_binary_value (section, + name.fast_rep (), + binary_data, + binary_length)) + return -2; + line += ACE_TEXT ("\""); + unsigned char* ptr = (unsigned char*)binary_data; + while (binary_length) + { + if (ptr != binary_data) + { + line += ACE_TEXT (","); + } + ACE_OS::sprintf (bin_value, ACE_TEXT ("%02x"), *ptr); + line += bin_value; + --binary_length; + ++ptr; + } + line += ACE_TEXT ("\""); + delete [] (char *) binary_data; + break; + } + default: + return -3; + + }// end switch on type + + line += ACE_TEXT ("\n"); + if (ACE_OS::fputs (line.fast_rep (), out) < 0) + return -4; + ++index; + }// end while enumerating values + } + // Export all sub sections + int index = 0; + ACE_TString name; + ACE_Configuration_Section_Key sub_key; + ACE_TString sub_section; + while (!config_.enumerate_sections (section, index, name)) + { + ACE_TString sub_section (path); + if (path.length ()) + sub_section += ACE_TEXT ("\\"); + sub_section += name; + if (config_.open_section (section, name.fast_rep (), 0, sub_key)) + return -5; + if (export_section (sub_key, sub_section.fast_rep (), out)) + return -6; + ++index; + } + return 0; + +} + +// Method to squish leading and trailing whitespaces from a string. +// Whitespace is defined as: spaces (' '), tabs ('\t') or end-of-line +// (cr/lf). The terminating nul is moved up to expunge trailing +// whitespace and the returned pointer points at the first +// non-whitespace character in the string, which may be the nul +// terminator if the string is all whitespace. + +ACE_TCHAR * +ACE_Ini_ImpExp::squish (ACE_TCHAR *src) +{ + ACE_TCHAR *cp = 0; + + if (src == 0) + return 0; + + // Start at the end and work backwards over all whitespace. + for (cp = src + ACE_OS::strlen (src) - 1; + cp != src; + --cp) + if (!ACE_OS::ace_isspace (*cp)) + break; + cp[1] = '\0'; // Chop trailing whitespace + + // Now start at the beginning and move over all whitespace. + for (cp = src; ACE_OS::ace_isspace (*cp); ++cp) + continue; + + return cp; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Configuration_Import_Export.h b/dep/ACE_wrappers/ace/Configuration_Import_Export.h new file mode 100644 index 000000000..e93544bee --- /dev/null +++ b/dep/ACE_wrappers/ace/Configuration_Import_Export.h @@ -0,0 +1,215 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Configuration_Import_Export.h + * + * $Id: Configuration_Import_Export.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Jerry D. Odenwelder Jr. + * Chris Hafey + * + * Classes defined in this file provide the ability to import and export + * ACE Configuration objects to/from disk files. The base class + * ACE_Config_ImpExp_Base provides the common functionality and the derived + * classes implement the import/export functionality for the specific format. + * + * @todo + * - Add locking for thread safety. + * - Provide ability to read file in one format and write in another. + * - See todo's in each class + */ +//============================================================================= + +#ifndef ACE_CONFIGURATION_IMPORT_EXPORT_H +#define ACE_CONFIGURATION_IMPORT_EXPORT_H +#include /**/ "ace/pre.h" + +#include "ace/Configuration.h" +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Config_ImpExp_Base + * + * @brief Base class for file import/export configuration. + * + * This class provides base functionality for configuration objects + * that are persisted in files. It takes an ACE_Configuration + * object that it populates with the data read. + * + */ +class ACE_Export ACE_Config_ImpExp_Base +{ +public: + /// Constructor taking the ACE_Configuration to import/export to + ACE_Config_ImpExp_Base (ACE_Configuration& config); + + /** + * Destructor + */ + virtual ~ACE_Config_ImpExp_Base (void); + + /** + * Imports the configuration database from @a filename. + * No existing data is removed. + */ + virtual int import_config (const ACE_TCHAR* filename) = 0; + + /** + * This method exports the entire configuration database to @a filename. + * Once the file is opened this method calls 'export_section' passing + * the root section. + */ + virtual int export_config (const ACE_TCHAR* filename) = 0; + +protected: + ACE_Configuration &config_; + +private: + ACE_Config_ImpExp_Base (const ACE_Config_ImpExp_Base&); + ACE_Config_ImpExp_Base& operator= (const ACE_Config_ImpExp_Base&); +}; + +/** + * @class ACE_Registry_ImpExp + * + * @brief Configuration object that imports/exports data to a file formatted + * using the Win32 Registry file export format. This format looks like + * [Section] + * "key"="String Data" + * "key"=dword: numeric data in hexidecimal format + * "key"=hex: binary data + * + * @todo + * - Add dynamic buffer when importing. currently it will not allow + * importing of values greater than a fixed ammount (4096 bytes) + * + */ +class ACE_Export ACE_Registry_ImpExp : public ACE_Config_ImpExp_Base +{ +public: + /// Construction + ACE_Registry_ImpExp (ACE_Configuration&); + + /// Destruction. + virtual ~ACE_Registry_ImpExp (void); + + /** + * Imports the configuration database from filename. + * No existing data is removed. + */ + virtual int import_config (const ACE_TCHAR* filename); + + /** + * This method exports the entire configuration database to @a filename. + * Once the file is opened this method calls export_section() passing + * the root section. + */ + virtual int export_config (const ACE_TCHAR* filename); + +private: + int export_section (const ACE_Configuration_Section_Key& section, + const ACE_TString& path, + FILE* out); + + int process_previous_line_format (ACE_TCHAR* buffer, + ACE_Configuration_Section_Key& section); + + ACE_Registry_ImpExp ( const ACE_Registry_ImpExp&); + ACE_Registry_ImpExp& operator= ( const ACE_Registry_ImpExp&); +}; + +/** + * @class ACE_Ini_ImpExp + * + * @brief Imports the configuration database from filename as strings. + * Allows non-typed values. (no #, dword: hex:, etc. prefixes) and + * skips whitespace (tabs and spaces) as in standard .ini and .conf + * files. Values (to right of equal sign) can be double quote + * delimited to embed tabs and spaces in the string. + * Caller must convert string to type. + * + * This method allows for lines in the .ini or .conf file like this: + * + * TimeToLive = 100 + * Delay = FALSE + * Flags = FF34 + * Heading = "ACE - Adaptive Communication Environment" + * + * (note leading whitespace (tabs) in examples below) + * + * SeekIndex = 14 + * TraceLevel = 6 # Can comment lines like this + * Justification = left_justified + * + * The caller can then retrieve the string with the regular + * function and convert the string to the + * desired data type. + * + * @todo + * - Strings with embedded newlines cause the import to fail + * - Strings with embedded quotes " cause the import to fail + * - Importing/exporting for values in the root section does not work + * - Add dynamic buffer when importing. currently it will not allow + * importing of values greater than a fixed ammount (4096 bytes) +*/ +class ACE_Export ACE_Ini_ImpExp : public ACE_Config_ImpExp_Base +{ +public: + /** + * Construction + */ + ACE_Ini_ImpExp (ACE_Configuration&); + + /** + * Destructor + */ + virtual ~ACE_Ini_ImpExp (void); + + /** + * Imports the configuration database from filename. + * No existing data is removed. + */ + virtual int import_config (const ACE_TCHAR* filename); + + /** + * This method exports the entire configuration database to @a filename. + * Once the file is opened this method calls export_section() passing + * the root section. + */ + virtual int export_config (const ACE_TCHAR* filename); + +private: + /** + * Method provided by derived classes in order to write one section + * to the file specified. Called by export_config() when exporting + * the entire configuration object. + */ + int export_section (const ACE_Configuration_Section_Key& section, + const ACE_TString& path, + FILE* out); + + /** + * Method to squish leading and trailing whitespaces in a string. + * Whitespace is defined as: spaces (' '), tabs ('\\t') or cr/lf. + * Returns a pointer to the first non-whitespace character in the + * buffer provided, or a pointer to the terminating null if the string + * is all whitespace. The terminating null is moved forward to the + * first character past the last non-whitespace. + */ + ACE_TCHAR *squish (ACE_TCHAR *src); + + ACE_Ini_ImpExp (const ACE_Ini_ImpExp&); + ACE_Ini_ImpExp& operator= (const ACE_Ini_ImpExp&); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIGURATION_IMPORT_EXPORT_H */ diff --git a/dep/ACE_wrappers/ace/Connection_Recycling_Strategy.cpp b/dep/ACE_wrappers/ace/Connection_Recycling_Strategy.cpp new file mode 100644 index 000000000..78b088843 --- /dev/null +++ b/dep/ACE_wrappers/ace/Connection_Recycling_Strategy.cpp @@ -0,0 +1,13 @@ +#include "ace/Connection_Recycling_Strategy.h" + + +ACE_RCSID(ace, Connection_Recycling_Strategy, "$Id: Connection_Recycling_Strategy.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Connection_Recycling_Strategy::~ACE_Connection_Recycling_Strategy (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Connection_Recycling_Strategy.h b/dep/ACE_wrappers/ace/Connection_Recycling_Strategy.h new file mode 100644 index 000000000..75169638d --- /dev/null +++ b/dep/ACE_wrappers/ace/Connection_Recycling_Strategy.h @@ -0,0 +1,63 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Connection_Recycling_Strategy.h + * + * $Id: Connection_Recycling_Strategy.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= +#ifndef ACE_CONNECTION_RECYCLING_STRATEGY_H +#define ACE_CONNECTION_RECYCLING_STRATEGY_H +#include /**/ "ace/pre.h" + +#include "ace/Recyclable.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Connection_Recycling_Strategy + * + * @brief Defines the interface for a connection recycler. + */ +class ACE_Export ACE_Connection_Recycling_Strategy +{ +public: + /// Virtual Destructor + virtual ~ACE_Connection_Recycling_Strategy (void); + + /// Remove from cache. + virtual int purge (const void *recycling_act) = 0; + + /// Add to cache. + virtual int cache (const void *recycling_act) = 0; + + virtual int recycle_state (const void *recycling_act, + ACE_Recyclable_State new_state) = 0; + + /// Get/Set recycle_state. + virtual ACE_Recyclable_State recycle_state (const void *recycling_act) const = 0; + + /// Mark as closed. + virtual int mark_as_closed (const void *recycling_act) = 0; + + /// Mark as closed.(non-locking version) + virtual int mark_as_closed_i (const void *recycling_act) = 0; + + /// Cleanup hint and reset @a act_holder to zero if @a act_holder != 0. + virtual int cleanup_hint (const void *recycling_act, + void **act_holder = 0) = 0; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /*ACE_CONNECTION_RECYCLING_STRATEGY*/ diff --git a/dep/ACE_wrappers/ace/Connector.cpp b/dep/ACE_wrappers/ace/Connector.cpp new file mode 100644 index 000000000..3e68abc09 --- /dev/null +++ b/dep/ACE_wrappers/ace/Connector.cpp @@ -0,0 +1,966 @@ +// $Id: Connector.cpp 81991 2008-06-16 19:05:40Z elliott_c $ + +#ifndef ACE_CONNECTOR_CPP +#define ACE_CONNECTOR_CPP + +#include "ace/Connector.h" +#include "ace/ACE.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/os_include/os_fcntl.h" /* Has ACE_NONBLOCK */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Connector) + +template +ACE_NonBlocking_Connect_Handler::ACE_NonBlocking_Connect_Handler +(ACE_Connector_Base &connector, + SVC_HANDLER *sh, + long id) + : connector_ (connector) + , svc_handler_ (sh) + , timer_id_ (id) +{ + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::ACE_NonBlocking_Connect_Handler"); + + this->reference_counting_policy ().value + (ACE_Event_Handler::Reference_Counting_Policy::ENABLED); +} + +template SVC_HANDLER * +ACE_NonBlocking_Connect_Handler::svc_handler (void) +{ + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::svc_handler"); + return this->svc_handler_; +} + +template long +ACE_NonBlocking_Connect_Handler::timer_id (void) +{ + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::timer_id"); + return this->timer_id_; +} + +template void +ACE_NonBlocking_Connect_Handler::timer_id (long id) +{ + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::timer_id"); + this->timer_id_ = id; +} + +template void +ACE_NonBlocking_Connect_Handler::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("svc_handler_ = %x"), this->svc_handler_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_id_ = %d"), this->timer_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template bool +ACE_NonBlocking_Connect_Handler::close (SVC_HANDLER *&sh) +{ + // Make sure that we haven't already initialized the Svc_Handler. + if (!this->svc_handler_) + return false; + + { + // Exclusive access to the Reactor. + ACE_GUARD_RETURN (ACE_Lock, + ace_mon, + this->reactor ()->lock (), + 0); + + // Double check. + if (!this->svc_handler_) + return false; + + // Remember the Svc_Handler. + sh = this->svc_handler_; + ACE_HANDLE h = sh->get_handle (); + this->svc_handler_ = 0; + + // Remove this handle from the set of non-blocking handles + // in the Connector. + this->connector_.non_blocking_handles ().remove (h); + + // Cancel timer. + if (this->reactor ()->cancel_timer (this->timer_id (), + 0, + 0) == -1) + return false; + + // Remove from Reactor. + if (this->reactor ()->remove_handler ( + h, + ACE_Event_Handler::ALL_EVENTS_MASK) == -1) + return false; + } + + return true; +} + + +template int +ACE_NonBlocking_Connect_Handler::handle_timeout +(const ACE_Time_Value &tv, + const void *arg) +{ + // This method is called if a connection times out before completing. + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::handle_timeout"); + + SVC_HANDLER *svc_handler = 0; + int retval = this->close (svc_handler) ? 0 : -1; + + // Forward to the SVC_HANDLER the that was passed in as a + // magic cookie during ACE_Connector::connect(). This gives the + // SVC_HANDLER an opportunity to take corrective action (e.g., wait + // a few milliseconds and try to reconnect again. + if (svc_handler != 0 && svc_handler->handle_timeout (tv, arg) == -1) + svc_handler->handle_close (svc_handler->get_handle (), + ACE_Event_Handler::TIMER_MASK); + + return retval; +} + + +template int +ACE_NonBlocking_Connect_Handler::handle_input (ACE_HANDLE) +{ + // Called when a failure occurs during asynchronous connection + // establishment. + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::handle_input"); + + SVC_HANDLER *svc_handler = 0; + int const retval = this->close (svc_handler) ? 0 : -1; + + // Close Svc_Handler. + if (svc_handler != 0) + svc_handler->close (NORMAL_CLOSE_OPERATION); + + return retval; +} + +template int +ACE_NonBlocking_Connect_Handler::handle_output (ACE_HANDLE handle) +{ + // Called when a connection is establishment asynchronous. + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::handle_output"); + + // Grab the connector ref before smashing ourselves in close(). + ACE_Connector_Base &connector = this->connector_; + SVC_HANDLER *svc_handler = 0; + int const retval = this->close (svc_handler) ? 0 : -1; + + if (svc_handler != 0) + connector.initialize_svc_handler (handle, svc_handler); + + return retval; +} + +template int +ACE_NonBlocking_Connect_Handler::handle_exception (ACE_HANDLE h) +{ + // On Win32, the except mask must also be set for asynchronous + // connects. + ACE_TRACE ("ACE_NonBlocking_Connect_Handler::handle_exception"); + return this->handle_output (h); +} + +template int +ACE_NonBlocking_Connect_Handler::resume_handler (void) +{ + return ACE_Event_Handler::ACE_EVENT_HANDLER_NOT_RESUMED; +} + +template void +ACE_Connector::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Connector::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = %d"), this->flags_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template int +ACE_Connector::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_Connector::make_svc_handler"); + + if (sh == 0) + ACE_NEW_RETURN (sh, + SVC_HANDLER, + -1); + + // Set the reactor of the newly created to the same + // reactor that this is using. + sh->reactor (this->reactor ()); + return 0; +} + +template int +ACE_Connector::activate_svc_handler (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Connector::activate_svc_handler"); + // No errors initially + int error = 0; + + // See if we should enable non-blocking I/O on the 's + // peer. + if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0) + { + if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1) + error = 1; + } + // Otherwise, make sure it's disabled by default. + else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1) + error = 1; + + // We are connected now, so try to open things up. + if (error || svc_handler->open ((void *) this) == -1) + { + // Make sure to close down the to avoid descriptor + // leaks. + // The connection was already made; so this close is a "normal" + // close operation. + svc_handler->close (NORMAL_CLOSE_OPERATION); + return -1; + } + else + return 0; +} + +template ACE_PEER_CONNECTOR & +ACE_Connector::connector (void) const +{ + return const_cast (this->connector_); +} + +template int +ACE_Connector::connect_svc_handler +(SVC_HANDLER *&svc_handler, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connector::connect_svc_handler"); + + return this->connector_.connect (svc_handler->peer (), + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template int +ACE_Connector::connect_svc_handler +(SVC_HANDLER *&svc_handler, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connector::connect_svc_handler"); + + sh_copy = svc_handler; + return this->connector_.connect (svc_handler->peer (), + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template int +ACE_Connector::open (ACE_Reactor *r, int flags) +{ + ACE_TRACE ("ACE_Connector::open"); + this->reactor (r); + this->flags_ = flags; + return 0; +} + +template +ACE_Connector::ACE_Connector (ACE_Reactor *r, + int flags) +{ + ACE_TRACE ("ACE_Connector::ACE_Connector"); + (void) this->open (r, flags); +} + +template int +ACE_Connector::connect +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + // Initiate connection to peer. + return this->connect_i (sh, + 0, + remote_addr, + synch_options, + local_addr, + reuse_addr, + flags, + perms); +} + +template int +ACE_Connector::connect +(SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + // Initiate connection to peer. + return this->connect_i (sh, + &sh_copy, + remote_addr, + synch_options, + local_addr, + reuse_addr, + flags, + perms); +} + +template int +ACE_Connector::connect_i +(SVC_HANDLER *&sh, + SVC_HANDLER **sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connector::connect_i"); + + // If the user hasn't supplied us with a we'll use the + // factory method to create one. Otherwise, things will remain as + // they are... + if (this->make_svc_handler (sh) == -1) + return -1; + + ACE_Time_Value *timeout = 0; + int const use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR]; + + if (use_reactor) + timeout = const_cast (&ACE_Time_Value::zero); + else + timeout = const_cast (synch_options.time_value ()); + + int result; + if (sh_copy == 0) + result = this->connect_svc_handler (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); + else + result = this->connect_svc_handler (sh, + *sh_copy, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); + + // Activate immediately if we are connected. + if (result != -1) + return this->activate_svc_handler (sh); + + // Delegate to connection strategy. + if (use_reactor && ACE_OS::last_error () == EWOULDBLOCK) + { + // If the connection hasn't completed and we are using + // non-blocking semantics then register + // ACE_NonBlocking_Connect_Handler with the ACE_Reactor so that + // it will call us back when the connection is complete or we + // timeout, whichever comes first... + int result; + + if (sh_copy == 0) + result = this->nonblocking_connect (sh, synch_options); + else + result = this->nonblocking_connect (*sh_copy, synch_options); + + // If for some reason the call failed, then + // will be set to the new error. If the call succeeds, however, + // we need to make sure that remains set to + // . + if (result == 0) + errno = EWOULDBLOCK; + } + else + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + // Make sure to close down the service handler to avoid handle + // leaks. + if (sh_copy == 0) + { + if (sh) + sh->close (CLOSE_DURING_NEW_CONNECTION); + } + else if (*sh_copy) + (*sh_copy)->close (CLOSE_DURING_NEW_CONNECTION); + } + + return -1; +} + +template int +ACE_Connector::connect_n +(size_t n, + SVC_HANDLER *sh[], + ACE_PEER_CONNECTOR_ADDR remote_addrs[], + ACE_TCHAR *failed_svc_handlers, + const ACE_Synch_Options &synch_options) +{ + int result = 0; + + for (size_t i = 0; i < n; i++) + { + if (this->connect (sh[i], remote_addrs[i], synch_options) == -1 + && !(synch_options[ACE_Synch_Options::USE_REACTOR] + && errno == EWOULDBLOCK)) + { + result = -1; + if (failed_svc_handlers != 0) + // Mark this entry as having failed. + failed_svc_handlers[i] = 1; + } + else if (failed_svc_handlers != 0) + // Mark this entry as having succeeded. + failed_svc_handlers[i] = 0; + } + + return result; +} + +// Cancel a that was started asynchronously. +template int +ACE_Connector::cancel (SVC_HANDLER *sh) +{ + ACE_TRACE ("ACE_Connector::cancel"); + + ACE_Event_Handler *handler = + this->reactor ()->find_handler (sh->get_handle ()); + + if (handler == 0) + return -1; + + // find_handler() increments handler's refcount; ensure we decrement it. + ACE_Event_Handler_var safe_handler (handler); + + NBCH *nbch = + dynamic_cast (handler); + + if (nbch == 0) + return -1; + + SVC_HANDLER *tmp_sh = 0; + + if (nbch->close (tmp_sh) == false) + return -1; + + return 0; +} + +template int +ACE_Connector::nonblocking_connect +(SVC_HANDLER *sh, + const ACE_Synch_Options &synch_options) +{ + ACE_TRACE ("ACE_Connector::nonblocking_connect"); + + // Must have a valid Reactor for non-blocking connects to work. + if (this->reactor () == 0) + return -1; + + // Register the pending SVC_HANDLER so that it can be activated + // later on when the connection completes. + + ACE_HANDLE handle = sh->get_handle (); + long timer_id = -1; + ACE_Time_Value *tv = 0; + NBCH *nbch = 0; + + ACE_NEW_RETURN (nbch, + NBCH (*this, + sh, + -1), + -1); + + ACE_Event_Handler_var safe_nbch (nbch); + + // Exclusive access to the Reactor. + ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1); + + // Register handle with the reactor for connection events. + ACE_Reactor_Mask mask = ACE_Event_Handler::CONNECT_MASK; + if (this->reactor ()->register_handler (handle, + nbch, + mask) == -1) + goto reactor_registration_failure; + + // Add handle to non-blocking handle set. + this->non_blocking_handles ().insert (handle); + + // If we're starting connection under timer control then we need to + // schedule a timeout with the ACE_Reactor. + tv = const_cast (synch_options.time_value ()); + if (tv != 0) + { + timer_id = + this->reactor ()->schedule_timer (nbch, + synch_options.arg (), + *tv); + if (timer_id == -1) + goto timer_registration_failure; + + // Remember timer id. + nbch->timer_id (timer_id); + } + + return 0; + + // Undo previous actions using the ol' "goto label and fallthru" + // trick... + timer_registration_failure: + + // Remove from Reactor. + this->reactor ()->remove_handler (handle, mask); + + // Remove handle from the set of non-blocking handles. + this->non_blocking_handles ().remove (handle); + + /* FALLTHRU */ + + reactor_registration_failure: + // Close the svc_handler + + sh->close (CLOSE_DURING_NEW_CONNECTION); + + return -1; +} + +template +ACE_Connector::~ACE_Connector (void) +{ + ACE_TRACE ("ACE_Connector::~ACE_Connector"); + + this->close (); +} + +template void +ACE_Connector::initialize_svc_handler +(ACE_HANDLE handle, + SVC_HANDLER *svc_handler) +{ + // Try to find out if the reactor uses event associations for the + // handles it waits on. If so we need to reset it. + int reset_new_handle = + this->reactor ()->uses_event_associations (); + + if (reset_new_handle) + this->connector_.reset_new_handle (handle); + + // Transfer ownership of the ACE_HANDLE to the SVC_HANDLER. + svc_handler->set_handle (handle); + + ACE_PEER_CONNECTOR_ADDR raddr; + + // Check to see if we're connected. + if (svc_handler->peer ().get_remote_addr (raddr) != -1) + this->activate_svc_handler (svc_handler); + else // Somethings gone wrong, so close down... + { +#if defined (ACE_WIN32) + // Win32 (at least prior to Windows 2000) has a timing problem. + // If you check to see if the connection has completed too fast, + // it will fail - so wait 35 milliseconds to let it catch up. + ACE_Time_Value tv (0, ACE_NON_BLOCKING_BUG_DELAY); + ACE_OS::sleep (tv); + if (svc_handler->peer ().get_remote_addr (raddr) != -1) + this->activate_svc_handler (svc_handler); + else // do the svc handler close below... +#endif /* ACE_WIN32 */ + svc_handler->close (NORMAL_CLOSE_OPERATION); + } +} + +template void +ACE_Connector::reactor (ACE_Reactor *reactor) +{ + this->reactor_ = reactor; +} + +template ACE_Reactor * +ACE_Connector::reactor (void) const +{ + return this->reactor_; +} + +template ACE_Unbounded_Set & +ACE_Connector::non_blocking_handles (void) +{ + return this->non_blocking_handles_; +} + +template int +ACE_Connector::close (void) +{ + // If there are no non-blocking handle pending, return immediately. + if (this->non_blocking_handles ().size () == 0) + return 0; + + // Exclusive access to the Reactor. + ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1); + + // Go through all the non-blocking handles. It is necessary to + // create a new iterator each time because we remove from the handle + // set when we cancel the Svc_Handler. + ACE_HANDLE *handle = 0; + while (1) + { + ACE_Unbounded_Set_Iterator + iterator (this->non_blocking_handles ()); + if (!iterator.next (handle)) + break; + + ACE_Event_Handler *handler = + this->reactor ()->find_handler (*handle); + if (handler == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%t: Connector::close h %d, no handler\n"), + *handle)); + // Remove handle from the set of non-blocking handles. + this->non_blocking_handles ().remove (*handle); + continue; + } + + // find_handler() incremented handler's refcount; ensure it's decremented + ACE_Event_Handler_var safe_handler (handler); + NBCH *nbch = dynamic_cast (handler); + if (nbch == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%t: Connector::close h %d handler %@ ") + ACE_TEXT ("not a legit handler\n"), + *handle, + handler)); + // Remove handle from the set of non-blocking handles. + this->non_blocking_handles ().remove (*handle); + continue; + } + SVC_HANDLER *svc_handler = nbch->svc_handler (); + + // Cancel the non-blocking connection. + this->cancel (svc_handler); + + // Close the associated Svc_Handler. + svc_handler->close (NORMAL_CLOSE_OPERATION); + } + + return 0; +} + +template int +ACE_Connector::fini (void) +{ + ACE_TRACE ("ACE_Connector::fini"); + + return this->close (); +} + +// Hook called by the explicit dynamic linking facility. + +template int +ACE_Connector::init (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("ACE_Connector::init"); + return -1; +} + +template int +ACE_Connector::suspend (void) +{ + ACE_TRACE ("ACE_Connector::suspend"); + return -1; +} + +template int +ACE_Connector::resume (void) +{ + ACE_TRACE ("ACE_Connector::resume"); + return -1; +} + +template int +ACE_Connector::info (ACE_TCHAR **strp, size_t length) const +{ + ACE_TRACE ("ACE_Connector::info"); + ACE_TCHAR buf[BUFSIZ]; + + ACE_OS::sprintf (buf, + ACE_TEXT ("%s\t %s"), + ACE_TEXT ("ACE_Connector"), + ACE_TEXT ("# connector factory\n")); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strsncpy (*strp, buf, length); + return static_cast (ACE_OS::strlen (buf)); +} + +template int +ACE_Strategy_Connector::open (ACE_Reactor *r, + int flags) +{ + ACE_TRACE ("ACE_Strategy_Connector::open"); + return this->open (r, 0, 0, 0, flags); +} + +template int +ACE_Strategy_Connector::open +(ACE_Reactor *r, + ACE_Creation_Strategy *cre_s, + ACE_Connect_Strategy *conn_s, + ACE_Concurrency_Strategy *con_s, + int flags) +{ + ACE_TRACE ("ACE_Strategy_Connector::open"); + + this->reactor (r); + + // @@ Not implemented yet. + // this->flags_ = flags; + ACE_UNUSED_ARG (flags); + + // Initialize the creation strategy. + + // First we decide if we need to clean up. + if (this->creation_strategy_ != 0 && + this->delete_creation_strategy_ && + cre_s != 0) + { + delete this->creation_strategy_; + this->creation_strategy_ = 0; + this->delete_creation_strategy_ = false; + } + + if (cre_s != 0) + this->creation_strategy_ = cre_s; + else if (this->creation_strategy_ == 0) + { + ACE_NEW_RETURN (this->creation_strategy_, + CREATION_STRATEGY, + -1); + this->delete_creation_strategy_ = true; + } + + + // Initialize the accept strategy. + + if (this->connect_strategy_ != 0 && + this->delete_connect_strategy_ && + conn_s != 0) + { + delete this->connect_strategy_; + this->connect_strategy_ = 0; + this->delete_connect_strategy_ = false; + } + + if (conn_s != 0) + this->connect_strategy_ = conn_s; + else if (this->connect_strategy_ == 0) + { + ACE_NEW_RETURN (this->connect_strategy_, + CONNECT_STRATEGY, + -1); + this->delete_connect_strategy_ = true; + } + + // Initialize the concurrency strategy. + + if (this->concurrency_strategy_ != 0 && + this->delete_concurrency_strategy_ && + con_s != 0) + { + delete this->concurrency_strategy_; + this->concurrency_strategy_ = 0; + this->delete_concurrency_strategy_ = false; + } + + if (con_s != 0) + this->concurrency_strategy_ = con_s; + else if (this->concurrency_strategy_ == 0) + { + ACE_NEW_RETURN (this->concurrency_strategy_, + CONCURRENCY_STRATEGY, + -1); + this->delete_concurrency_strategy_ = true; + } + + return 0; +} + +template +ACE_Strategy_Connector::ACE_Strategy_Connector +(ACE_Reactor *reactor, + ACE_Creation_Strategy *cre_s, + ACE_Connect_Strategy *conn_s, + ACE_Concurrency_Strategy *con_s, + int flags) + : creation_strategy_ (0), + delete_creation_strategy_ (false), + connect_strategy_ (0), + delete_connect_strategy_ (false), + concurrency_strategy_ (0), + delete_concurrency_strategy_ (false) +{ + ACE_TRACE ("ACE_Connector::ACE_Strategy_Connector"); + + if (this->open (reactor, cre_s, conn_s, con_s, flags) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_Strategy_Connector::ACE_Strategy_Connector"))); +} + +template +ACE_Strategy_Connector::~ACE_Strategy_Connector (void) +{ + ACE_TRACE ("ACE_Strategy_Connector::~ACE_Strategy_Connector"); + + // Close down + this->close (); +} + +template int +ACE_Strategy_Connector::close (void) +{ + if (this->delete_creation_strategy_) + delete this->creation_strategy_; + this->delete_creation_strategy_ = false; + this->creation_strategy_ = 0; + + if (this->delete_connect_strategy_) + delete this->connect_strategy_; + this->delete_connect_strategy_ = false; + this->connect_strategy_ = 0; + + if (this->delete_concurrency_strategy_) + delete this->concurrency_strategy_; + this->delete_concurrency_strategy_ = false; + this->concurrency_strategy_ = 0; + + return SUPER::close (); +} + +template int +ACE_Strategy_Connector::make_svc_handler (SVC_HANDLER *&sh) +{ + return this->creation_strategy_->make_svc_handler (sh); +} + +template int +ACE_Strategy_Connector::connect_svc_handler +(SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + return this->connect_strategy_->connect_svc_handler (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template int +ACE_Strategy_Connector::connect_svc_handler +(SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + return this->connect_strategy_->connect_svc_handler (sh, + sh_copy, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template int +ACE_Strategy_Connector::activate_svc_handler (SVC_HANDLER *svc_handler) +{ + return this->concurrency_strategy_->activate_svc_handler (svc_handler, this); +} + +template ACE_Creation_Strategy * +ACE_Strategy_Connector::creation_strategy (void) const +{ + return this->creation_strategy_; +} + +template ACE_Connect_Strategy * +ACE_Strategy_Connector::connect_strategy (void) const +{ + return this->connect_strategy_; +} + +template ACE_Concurrency_Strategy * +ACE_Strategy_Connector::concurrency_strategy (void) const +{ + return this->concurrency_strategy_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_CONNECTOR_C */ diff --git a/dep/ACE_wrappers/ace/Connector.h b/dep/ACE_wrappers/ace/Connector.h new file mode 100644 index 000000000..b13fc56c1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Connector.h @@ -0,0 +1,563 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Connector.h + * + * $Id: Connector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_CONNECTOR_H +#define ACE_CONNECTOR_H + +#include /**/ "ace/pre.h" + +#include "ace/Service_Object.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Strategies_T.h" +#include "ace/Synch_Options.h" +#include "ace/Unbounded_Set.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Connector_Base + * + * @brief This base interface allows ACE_NonBlocking_Connect_Handler + * to only care about the SVC_HANDLER template parameter of the + * ACE_Connector. Otherwise, ACE_NonBlocking_Connect_Handler would + * have to be configured with all the template parameters that + * ACE_Connector is configured with. + */ +template +class ACE_Connector_Base +{ +public: + + virtual ~ACE_Connector_Base (void) {} + + /// Initialize the Svc_Handler. + virtual void initialize_svc_handler (ACE_HANDLE handle, + SVC_HANDLER *svc_handler) = 0; + + /// Return the handle set representing the non-blocking connects in + /// progress. + virtual ACE_Unbounded_Set &non_blocking_handles (void) = 0; +}; + +/** + * @class ACE_NonBlocking_Connect_Handler + * + * @brief Performs non-blocking connects on behalf of the Connector. + */ +template +class ACE_NonBlocking_Connect_Handler : public ACE_Event_Handler +{ +public: + + /// Constructor. + ACE_NonBlocking_Connect_Handler (ACE_Connector_Base &connector, + SVC_HANDLER *, + long timer_id); + + /// Close up and return underlying SVC_HANDLER through @c sh. + /** + * If the return value is true the close was performed succesfully, + * implying that this object was removed from the reactor and thereby + * (by means of reference counting decremented to 0) deleted. + * If the return value is false, the close was not successful. + * The @c sh does not have any connection to the return + * value. The argument will return a valid svc_handler object if a + * valid one exists within the object. Returning a valid svc_handler + * pointer also invalidates the svc_handler contained in this + * object. + */ + bool close (SVC_HANDLER *&sh); + + /// Get SVC_HANDLER. + SVC_HANDLER *svc_handler (void); + + /// Get handle. + ACE_HANDLE handle (void); + + /// Set handle. + void handle (ACE_HANDLE); + + /// Get timer id. + long timer_id (void); + + /// Set timer id. + void timer_id (long timer_id); + + /// Called by ACE_Reactor when asynchronous connections fail. + virtual int handle_input (ACE_HANDLE); + + /// Called by ACE_Reactor when asynchronous connections succeed. + virtual int handle_output (ACE_HANDLE); + + /// Called by ACE_Reactor when asynchronous connections suceeds (on + /// some platforms only). + virtual int handle_exception (ACE_HANDLE fd); + + /// This method is called if a connection times out before + /// completing. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + + /// Should Reactor resume us if we have been suspended before the upcall? + virtual int resume_handler (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /// Connector base. + ACE_Connector_Base &connector_; + + /// Associated SVC_HANDLER. + SVC_HANDLER *svc_handler_; + + /// Associated timer id. + long timer_id_; +}; + +/** + * @class ACE_Connector + * + * @brief Generic factory for actively connecting clients and creating + * service handlers (SVC_HANDLERs). + * + * Implements the strategy for actively establishing connections with + * clients. An ACE_Connector is parameterized by concrete types that + * conform to the interfaces of PEER_CONNECTOR and SVC_HANDLER. The + * PEER_CONNECTOR is instantiated with a transport mechanism that + * actively establishes connections. The SVC_HANDLER is instantiated + * with a concrete type that performs the application-specific + * service. Both blocking and non-blocking connects are supported. + * Further, non-blocking connects support timeouts. + */ +template +class ACE_Connector : public ACE_Connector_Base, public ACE_Service_Object +{ +public: + + // Useful STL-style traits. + typedef typename SVC_HANDLER::addr_type addr_type; + typedef ACE_PEER_CONNECTOR connector_type; + typedef SVC_HANDLER handler_type; + typedef typename SVC_HANDLER::stream_type stream_type; + typedef typename ACE_PEER_CONNECTOR::PEER_ADDR peer_addr_type; + typedef ACE_PEER_CONNECTOR_ADDR ACE_PEER_ADDR_TYPEDEF; + + /** + * Initialize a connector. @a flags indicates how SVC_HANDLER's + * should be initialized prior to being activated. Right now, the + * only flag that is processed is ACE_NONBLOCK, which enabled + * non-blocking I/O on the SVC_HANDLER when it is opened. + */ + ACE_Connector (ACE_Reactor *r = ACE_Reactor::instance (), + int flags = 0); + + /** + * Initialize a connector. @a flags indicates how SVC_HANDLER's + * should be initialized prior to being activated. Right now, the + * only flag that is processed is ACE_NONBLOCK, which enabled + * non-blocking I/O on the SVC_HANDLER when it is opened. + */ + virtual int open (ACE_Reactor *r = ACE_Reactor::instance (), + int flags = 0); + + /// Shutdown a connector and release resources. + virtual ~ACE_Connector (void); + + // = Connection establishment methods. + + /** + * Initiate connection of @a svc_handler to peer at @a remote_addr + * using @a synch_options. If the caller wants to designate the + * selected @a local_addr they can (and can also insist that the + * @a local_addr be reused by passing a value @a reuse_addr == + * 1). @a flags and @a perms can be used to pass any flags that are + * needed to perform specific operations such as opening a file + * within connect with certain permissions. If the connection fails + * the hook on the will be called + * automatically to prevent resource leaks. + */ + virtual int connect (SVC_HANDLER *&svc_handler, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults, + const ACE_PEER_CONNECTOR_ADDR &local_addr + = (peer_addr_type &) ACE_PEER_CONNECTOR_ADDR_ANY, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + + /** + * This is a variation on the previous method. On cached + * connectors the @a svc_handler_hint variable can be used as a hint + * for future lookups. Since this variable is modified in the + * context of the internal cache its use is thread-safe. But the + * actual svc_handler for the current connection is returned in the + * second parameter @a svc_handler. If the connection fails the + * hook on the will be called automatically to + * prevent resource leaks. + */ + virtual int connect (SVC_HANDLER *&svc_handler_hint, + SVC_HANDLER *&svc_handler, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults, + const ACE_PEER_CONNECTOR_ADDR &local_addr + = (peer_addr_type &) ACE_PEER_CONNECTOR_ADDR_ANY, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + + /** + * Initiate connection of @a n @a svc_handlers to peers at + * @a remote_addrs using @a synch_options. Returns -1 if failure + * occurs and 0 otherwise. If @a failed_svc_handlers is non-NULL, a + * 1 is placed in the corresponding index of @a failed_svc_handlers + * for each that failed to connect, else a 0 is + * placed in that index. + */ + virtual int connect_n (size_t n, + SVC_HANDLER *svc_handlers[], + ACE_PEER_CONNECTOR_ADDR remote_addrs[], + ACE_TCHAR *failed_svc_handlers = 0, + const ACE_Synch_Options &synch_options = + ACE_Synch_Options::defaults); + + /** + * Cancel the @a svc_handler that was started asynchronously. Note that + * this is the only case when the Connector does not actively close + * the @a svc_handler. It is left up to the caller of to + * decide the fate of the @a svc_handler. + */ + virtual int cancel (SVC_HANDLER *svc_handler); + + /// Close down the Connector. All pending non-blocking connects are + /// canceled and the corresponding svc_handler is closed. + virtual int close (void); + + /// Return the underlying PEER_CONNECTOR object. + virtual ACE_PEER_CONNECTOR &connector (void) const; + + /// Initialize Svc_Handler. + virtual void initialize_svc_handler (ACE_HANDLE handle, + SVC_HANDLER *svc_handler); + + /// Set Reactor. + virtual void reactor (ACE_Reactor *reactor); + + /// Get Reactor. + virtual ACE_Reactor *reactor (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Helpful typedefs. + typedef ACE_NonBlocking_Connect_Handler NBCH; + + // = The following two methods define the Connector's strategies for + // creating, connecting, and activating SVC_HANDLER's, respectively. + + /** + * Bridge method for creating a SVC_HANDLER. The default is to + * create a new SVC_HANDLER only if @a sh == 0, else @a sh is + * unchanged. However, subclasses can override this policy to + * perform SVC_HANDLER creation in any way that they like (such as + * creating subclass instances of SVC_HANDLER, using a singleton, + * dynamically linking the handler, etc.). Returns -1 if failure, + * else 0. + */ + virtual int make_svc_handler (SVC_HANDLER *&sh); + + /** + * Bridge method for connecting the @a svc_handler to the + * @a remote_addr. The default behavior delegates to the + * . + */ + virtual int connect_svc_handler (SVC_HANDLER *&svc_handler, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + virtual int connect_svc_handler (SVC_HANDLER *&svc_handler, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + + /** + * Bridge method for activating a @a svc_handler with the appropriate + * concurrency strategy. The default behavior of this method is to + * activate the SVC_HANDLER by calling its method (which + * allows the SVC_HANDLER to define its own concurrency strategy). + * However, subclasses can override this strategy to do more + * sophisticated concurrency activations (such as creating the + * SVC_HANDLER as an "active object" via multi-threading or + * multi-processing). + */ + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + + /// Creates and registers ACE_NonBlocking_Connect_Handler. + int nonblocking_connect (SVC_HANDLER *, + const ACE_Synch_Options &); + + /// Implementation of the connect methods. + virtual int connect_i (SVC_HANDLER *&svc_handler, + SVC_HANDLER **sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + + /// Return the handle set representing the non-blocking connects in + /// progress. + ACE_Unbounded_Set &non_blocking_handles (void); + + // = Dynamic linking hooks. + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Calls handle_close() to shutdown the Connector gracefully. + virtual int fini (void); + + /// Default version returns address info in @a buf. + virtual int info (ACE_TCHAR **strp, size_t length) const; + + // = Service management hooks. + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int suspend (void); + + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int resume (void); + +private: + /// This is the peer connector factory. + ACE_PEER_CONNECTOR connector_; + + /** + * Flags that indicate how SVC_HANDLER's should be initialized + * prior to being activated. Right now, the only flag that is + * processed is ACE_NONBLOCK, which enabled non-blocking I/O on + * the SVC_HANDLER when it is opened. + */ + int flags_; + + /// Pointer to the Reactor. + ACE_Reactor *reactor_; + + /// Handle set representing the non-blocking connects in progress. + ACE_Unbounded_Set non_blocking_handles_; + +}; + +/** + * @class ACE_Strategy_Connector + * + * @brief Abstract factory for creating a service handler + * (SVC_HANDLER), connecting the SVC_HANDLER, and activating the + * SVC_HANDLER. + * + * Implements a flexible and extensible set of strategies for + * actively establishing connections with clients. There are + * three main strategies: (1) creating a SVC_HANDLER, (2) + * actively initiating a new connection from the client, + * and (3) activating the SVC_HANDLER with a + * particular concurrency mechanism after the connection is established. + */ +template +class ACE_Strategy_Connector + : public ACE_Connector +{ +public: + + // Useful STL-style traits. + typedef ACE_Creation_Strategy + creation_strategy_type; + typedef ACE_Connect_Strategy + connect_strategy_type; + typedef ACE_Concurrency_Strategy + concurrency_strategy_type; + typedef ACE_Connector + base_type; + + // = Define some useful (old style) traits. + typedef ACE_Creation_Strategy + CREATION_STRATEGY; + typedef ACE_Connect_Strategy + CONNECT_STRATEGY; + typedef ACE_Concurrency_Strategy + CONCURRENCY_STRATEGY; + typedef ACE_Connector + SUPER; + + /** + * Initialize a connector. @a flags indicates how 's + * should be initialized prior to being activated. Right now, the + * only flag that is processed is ACE_NONBLOCK, which enabled + * non-blocking I/O on the SVC_HANDLER when it is opened. + */ + ACE_Strategy_Connector (ACE_Reactor *r = ACE_Reactor::instance (), + ACE_Creation_Strategy * = 0, + ACE_Connect_Strategy * = 0, + ACE_Concurrency_Strategy * = 0, + int flags = 0); + + /** + * Initialize a connector. @a flags indicates how SVC_HANDLER's + * should be initialized prior to being activated. Right now, the + * only flag that is processed is ACE_NONBLOCK, which enabled + * non-blocking I/O on the SVC_HANDLER when it is opened. + * Default strategies would be created and used. + */ + virtual int open (ACE_Reactor *r, + int flags); + + /** + * Initialize a connector. @a flags indicates how SVC_HANDLER's + * should be initialized prior to being activated. Right now, the + * only flag that is processed is ACE_NONBLOCK, which enabled + * non-blocking I/O on the SVC_HANDLER when it is opened. + */ + virtual int open (ACE_Reactor *r = ACE_Reactor::instance (), + ACE_Creation_Strategy * = 0, + ACE_Connect_Strategy * = 0, + ACE_Concurrency_Strategy * = 0, + int flags = 0); + + /// Shutdown a connector and release resources. + virtual ~ACE_Strategy_Connector (void); + + /// Close down the Connector + virtual int close (void); + + // = Strategies accessors + virtual ACE_Creation_Strategy *creation_strategy (void) const; + virtual ACE_Connect_Strategy *connect_strategy (void) const; + virtual ACE_Concurrency_Strategy *concurrency_strategy (void) const; + +protected: + // = The following three methods define the 's strategies + // for creating, connecting, and activating SVC_HANDLER's, + // respectively. + + /** + * Bridge method for creating a SVC_HANDLER. The strategy for + * creating a SVC_HANDLER are configured into the Connector via + * it's . The default is to create a new + * SVC_HANDLER only if @a sh == 0, else @a sh is unchanged. + * However, subclasses can override this policy to perform + * SVC_HANDLER creation in any way that they like (such as + * creating subclass instances of SVC_HANDLER, using a singleton, + * dynamically linking the handler, etc.). Returns -1 if failure, + * else 0. + */ + virtual int make_svc_handler (SVC_HANDLER *&sh); + + /** + * Bridge method for connecting the new connection into the + * SVC_HANDLER. The default behavior delegates to the + * in the . + */ + virtual int connect_svc_handler (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + + /** + * Bridge method for connecting the new connection into the + * SVC_HANDLER. The default behavior delegates to the + * in the . + * @a sh_copy is used to obtain a copy of the @a sh pointer, but that + * can be kept in the stack; the motivation is a bit too long to + * include here, but basically we want to modify @a sh safely, using + * the internal locks in the Connect_Strategy, while saving a TSS + * copy in @a sh_copy, usually located in the stack. + */ + virtual int connect_svc_handler (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + + /** + * Bridge method for activating a SVC_HANDLER with the appropriate + * concurrency strategy. The default behavior of this method is to + * activate the SVC_HANDLER by calling its method (which + * allows the SVC_HANDLER to define its own concurrency strategy). + * However, subclasses can override this strategy to do more + * sophisticated concurrency activations (such as creating the + * SVC_HANDLER as an "active object" via multi-threading or + * multi-processing). + */ + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + + // = Strategy objects. + + /// Creation strategy for an Connector. + CREATION_STRATEGY *creation_strategy_; + + /// true if Connector created the creation strategy and thus should + /// delete it, else false. + bool delete_creation_strategy_; + + /// Connect strategy for a Connector. + CONNECT_STRATEGY *connect_strategy_; + + /// true if Connector created the connect strategy and thus should + /// delete it, else false. + bool delete_connect_strategy_; + + /// Concurrency strategy for an . + CONCURRENCY_STRATEGY *concurrency_strategy_; + + /// true if Connector created the concurrency strategy and thus should + /// delete it, else false. + bool delete_concurrency_strategy_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Connector.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Connector.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CONNECTOR_H */ diff --git a/dep/ACE_wrappers/ace/Containers.cpp b/dep/ACE_wrappers/ace/Containers.cpp new file mode 100644 index 000000000..244a9ad4b --- /dev/null +++ b/dep/ACE_wrappers/ace/Containers.cpp @@ -0,0 +1,12 @@ +// $Id: Containers.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Containers.h" + +ACE_RCSID (ace, + Containers, + "$Id: Containers.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (__ACE_INLINE__) +#include "ace/Containers.inl" +#endif /* __ACE_INLINE__ */ + diff --git a/dep/ACE_wrappers/ace/Containers.h b/dep/ACE_wrappers/ace/Containers.h new file mode 100644 index 000000000..ecff8e368 --- /dev/null +++ b/dep/ACE_wrappers/ace/Containers.h @@ -0,0 +1,71 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Containers.h + * + * $Id: Containers.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_CONTAINERS_H +#define ACE_CONTAINERS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template class ACE_Double_Linked_List; +template class ACE_Double_Linked_List_Iterator_Base; +template class ACE_Double_Linked_List_Iterator; +template class ACE_Double_Linked_List_Reverse_Iterator; + +/** + * @class ACE_DLList_Node + * + * @brief Base implementation of element in a DL list. Needed for + * ACE_Double_Linked_List. + */ +class ACE_Export ACE_DLList_Node +{ +public: + friend class ACE_Double_Linked_List; + friend class ACE_Double_Linked_List_Iterator_Base; + friend class ACE_Double_Linked_List_Iterator; + friend class ACE_Double_Linked_List_Reverse_Iterator; + + ACE_DLList_Node (void *i, + ACE_DLList_Node *n = 0, + ACE_DLList_Node *p = 0); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + void *item_; + + ACE_DLList_Node *next_; + ACE_DLList_Node *prev_; + +protected: + ACE_DLList_Node (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Containers.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Containers_T.h" + +#include /**/ "ace/post.h" + +#endif /* ACE_CONTAINERS_H */ diff --git a/dep/ACE_wrappers/ace/Containers.inl b/dep/ACE_wrappers/ace/Containers.inl new file mode 100644 index 000000000..8094672a8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Containers.inl @@ -0,0 +1,25 @@ +// -*- C++ -*- +// +// $Id: Containers.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_DLList_Node::ACE_DLList_Node (void) + : item_ (0), + next_ (0), + prev_ (0) +{ +} + +ACE_INLINE +ACE_DLList_Node::ACE_DLList_Node (void *i, + ACE_DLList_Node *n, + ACE_DLList_Node *p) + : item_ (i), + next_ (n), + prev_ (p) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Containers_T.cpp b/dep/ACE_wrappers/ace/Containers_T.cpp new file mode 100644 index 000000000..f4b6bd8a7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Containers_T.cpp @@ -0,0 +1,1932 @@ +// $Id: Containers_T.cpp 82588 2008-08-11 13:37:41Z johnnyw $ + +#ifndef ACE_CONTAINERS_T_CPP +#define ACE_CONTAINERS_T_CPP + +#include "ace/Log_Msg.h" +#include "ace/Malloc_Base.h" +#include "ace/OS_Memory.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Containers.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Containers_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Stack) + +template void +ACE_Bounded_Stack::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Bounded_Stack::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Bounded_Stack::ACE_Bounded_Stack (size_t size) + : size_ (size), + top_ (0) +{ + ACE_NEW (this->stack_, + T[size]); + ACE_TRACE ("ACE_Bounded_Stack::ACE_Bounded_Stack"); +} + +template +ACE_Bounded_Stack::ACE_Bounded_Stack (const ACE_Bounded_Stack &s) + : size_ (s.size_), + top_ (s.top_) +{ + ACE_NEW (this->stack_, + T[s.size_]); + + ACE_TRACE ("ACE_Bounded_Stack::ACE_Bounded_Stack"); + + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; +} + +template void +ACE_Bounded_Stack::operator= (const ACE_Bounded_Stack &s) +{ + ACE_TRACE ("ACE_Bounded_Stack::operator="); + + if (&s != this) + { + if (this->size_ < s.size_) + { + delete [] this->stack_; + ACE_NEW (this->stack_, + T[s.size_]); + this->size_ = s.size_; + } + this->top_ = s.top_; + + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; + } +} + +template +ACE_Bounded_Stack::~ACE_Bounded_Stack (void) +{ + ACE_TRACE ("ACE_Bounded_Stack::~ACE_Bounded_Stack"); + delete [] this->stack_; +} + +// ---------------------------------------- + +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Stack) + +template void +ACE_Fixed_Stack::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Fixed_Stack::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Fixed_Stack::ACE_Fixed_Stack (void) + : size_ (ACE_SIZE), + top_ (0) +{ + ACE_TRACE ("ACE_Fixed_Stack::ACE_Fixed_Stack"); +} + +template +ACE_Fixed_Stack::ACE_Fixed_Stack (const ACE_Fixed_Stack &s) + : size_ (s.size_), + top_ (s.top_) +{ + ACE_TRACE ("ACE_Fixed_Stack::ACE_Fixed_Stack"); + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; +} + +template void +ACE_Fixed_Stack::operator= (const ACE_Fixed_Stack &s) +{ + ACE_TRACE ("ACE_Fixed_Stack::operator="); + + if (&s != this) + { + this->top_ = s.top_; + + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; + } +} + +template +ACE_Fixed_Stack::~ACE_Fixed_Stack (void) +{ + ACE_TRACE ("ACE_Fixed_Stack::~ACE_Fixed_Stack"); +} + +//---------------------------------------- + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Stack) + +template void +ACE_Unbounded_Stack::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Stack::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unbounded_Stack::ACE_Unbounded_Stack (ACE_Allocator *alloc) + : head_ (0), + cur_size_ (0), + allocator_ (alloc) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::ACE_Unbounded_Stack"); + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (ACE_Node *) this->allocator_->malloc (sizeof (ACE_Node)), + ACE_Node); + this->head_->next_ = this->head_; +} + +template void +ACE_Unbounded_Stack::delete_all_nodes (void) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::delete_all_nodes"); + + while (this->is_empty () == 0) + { + ACE_Node *temp = this->head_->next_; + this->head_->next_ = temp->next_; + ACE_DES_FREE_TEMPLATE (temp, this->allocator_->free, + ACE_Node, ); + } + + this->cur_size_ = 0; + + ACE_ASSERT (this->head_ == this->head_->next_ + && this->is_empty ()); +} + +template void +ACE_Unbounded_Stack::copy_all_nodes (const ACE_Unbounded_Stack &s) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::copy_all_nodes"); + + ACE_ASSERT (this->head_ == this->head_->next_); + + ACE_Node *temp = this->head_; + + for (ACE_Node *s_temp = s.head_->next_; + s_temp != s.head_; + s_temp = s_temp->next_) + { + ACE_Node *nptr = temp->next_; + ACE_NEW_MALLOC (temp->next_, + (ACE_Node *) this->allocator_->malloc (sizeof (ACE_Node)), + ACE_Node (s_temp->item_, nptr)); + temp = temp->next_; + } + this->cur_size_ = s.cur_size_; +} + +template +ACE_Unbounded_Stack::ACE_Unbounded_Stack (const ACE_Unbounded_Stack &s) + : head_ (0), + cur_size_ (0), + allocator_ (s.allocator_) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (ACE_Node *) this->allocator_->malloc (sizeof (ACE_Node)), + ACE_Node); + this->head_->next_ = this->head_; + + // ACE_TRACE ("ACE_Unbounded_Stack::ACE_Unbounded_Stack"); + this->copy_all_nodes (s); +} + +template void +ACE_Unbounded_Stack::operator= (const ACE_Unbounded_Stack &s) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::operator="); + + if (this != &s) + { + this->delete_all_nodes (); + this->copy_all_nodes (s); + } +} + +template +ACE_Unbounded_Stack::~ACE_Unbounded_Stack (void) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::~ACE_Unbounded_Stack"); + + this->delete_all_nodes (); + ACE_DES_FREE_TEMPLATE (head_, + this->allocator_->free, + ACE_Node, + ); +} + +template int +ACE_Unbounded_Stack::push (const T &new_item) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::push"); + + ACE_Node *temp = 0; + + ACE_NEW_MALLOC_RETURN (temp, + static_cast *> (this->allocator_->malloc (sizeof (ACE_Node))), + ACE_Node (new_item, this->head_->next_), + -1); + this->head_->next_ = temp; + ++this->cur_size_; + return 0; +} + +template int +ACE_Unbounded_Stack::pop (T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::pop"); + + if (this->is_empty ()) + return -1; + else + { + ACE_Node *temp = this->head_->next_; + item = temp->item_; + this->head_->next_ = temp->next_; + + ACE_DES_FREE_TEMPLATE (temp, + this->allocator_->free, + ACE_Node, + ); + --this->cur_size_; + return 0; + } +} + +template int +ACE_Unbounded_Stack::find (const T &item) const +{ + // ACE_TRACE ("ACE_Unbounded_Stack::find"); + // Set into the dummy node. + this->head_->item_ = item; + + ACE_Node *temp = this->head_->next_; + + // Keep looping until we find the item. + while (!(temp->item_ == item)) + temp = temp->next_; + + // If we found the dummy node then it's not really there, otherwise, + // it is there. + return temp == this->head_ ? -1 : 0; +} + +template int +ACE_Unbounded_Stack::insert (const T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::insert"); + + if (this->find (item) == 0) + return 1; + else + return this->push (item); +} + +template int +ACE_Unbounded_Stack::remove (const T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Stack::remove"); + + // Insert the item to be founded into the dummy node. + this->head_->item_ = item; + + ACE_Node *curr = this->head_; + + while (!(curr->next_->item_ == item)) + curr = curr->next_; + + if (curr->next_ == this->head_) + return -1; // Item was not found. + else + { + ACE_Node *temp = curr->next_; + // Skip over the node that we're deleting. + curr->next_ = temp->next_; + --this->cur_size_; + ACE_DES_FREE_TEMPLATE (temp, + this->allocator_->free, + ACE_Node, + ); + return 0; + } +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Double_Linked_List_Iterator_Base) + +template +ACE_Double_Linked_List_Iterator_Base::ACE_Double_Linked_List_Iterator_Base (const ACE_Double_Linked_List &dll) + : current_ (0), dllist_ (&dll) +{ + // Do nothing +} + +template +ACE_Double_Linked_List_Iterator_Base::ACE_Double_Linked_List_Iterator_Base (const ACE_Double_Linked_List_Iterator_Base &iter) + : current_ (iter.current_), + dllist_ (iter.dllist_) +{ + // Do nothing +} + + +template T * +ACE_Double_Linked_List_Iterator_Base::next (void) const +{ + return this->not_done (); +} + +template int +ACE_Double_Linked_List_Iterator_Base::next (T *&ptr) const +{ + ptr = this->not_done (); + return ptr ? 1 : 0; +} + + +template int +ACE_Double_Linked_List_Iterator_Base::done (void) const +{ + return this->not_done () ? 0 : 1; +} + +template T & +ACE_Double_Linked_List_Iterator_Base::operator* (void) const +{ + return *(this->not_done ()); +} + +// @@ Is this a valid retasking? Make sure to check with Purify and +// whatnot that we're not leaking memory or doing any other screwing things. +template void +ACE_Double_Linked_List_Iterator_Base::reset (ACE_Double_Linked_List &dll) +{ + current_ = 0; + dllist_ = &dll; +} + + template int +ACE_Double_Linked_List_Iterator_Base::go_head (void) +{ + this->current_ = static_cast (dllist_->head_->next_); + return this->current_ ? 1 : 0; +} + +template int +ACE_Double_Linked_List_Iterator_Base::go_tail (void) +{ + this->current_ = static_cast (dllist_->head_->prev_); + return this->current_ ? 1 : 0; +} + +template T * +ACE_Double_Linked_List_Iterator_Base::not_done (void) const +{ + if (this->current_ != this->dllist_->head_) + return this->current_; + else + return 0; +} + +template T * +ACE_Double_Linked_List_Iterator_Base::do_advance (void) +{ + if (this->not_done ()) + { + this->current_ = static_cast (this->current_->next_); + return this->not_done (); + } + else + return 0; +} + +template T * +ACE_Double_Linked_List_Iterator_Base::do_retreat (void) +{ + if (this->not_done ()) + { + this->current_ = static_cast (this->current_->prev_); + return this->not_done (); + } + else + return 0; +} + +template void +ACE_Double_Linked_List_Iterator_Base::dump_i (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("current_ = %x"), this->current_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Double_Linked_List_Iterator) + +template +ACE_Double_Linked_List_Iterator::ACE_Double_Linked_List_Iterator (const ACE_Double_Linked_List &dll) + : ACE_Double_Linked_List_Iterator_Base (dll) +{ + this->current_ = static_cast (dll.head_->next_); + // Advance current_ out of the null area and onto the first item in + // the list +} + +template void +ACE_Double_Linked_List_Iterator::reset (ACE_Double_Linked_List &dll) +{ + this->ACE_Double_Linked_List_Iterator_Base ::reset (dll); + this->current_ = static_cast (dll.head_->next_); + // Advance current_ out of the null area and onto the first item in + // the list +} + +template int +ACE_Double_Linked_List_Iterator::first (void) +{ + return this->go_head (); +} + +template int +ACE_Double_Linked_List_Iterator::advance (void) +{ + return this->do_advance () ? 1 : 0; +} + +template T* +ACE_Double_Linked_List_Iterator::advance_and_remove (bool dont_remove) +{ + T* item = 0; + if (dont_remove) + this->do_advance (); + else + { + item = this->next (); + this->do_advance (); + // It seems dangerous to remove nodes in an iterator, but so it goes... + ACE_Double_Linked_List *dllist = + const_cast *> (this->dllist_); + dllist->remove (item); + } + return item; +} + +template void +ACE_Double_Linked_List_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->dump_i (); +#endif /* ACE_HAS_DUMP */ +} + +// Prefix advance. + +template +ACE_Double_Linked_List_Iterator & +ACE_Double_Linked_List_Iterator::operator++ (void) +{ + this->do_advance (); + return *this; +} + + +// Postfix advance. + +template +ACE_Double_Linked_List_Iterator +ACE_Double_Linked_List_Iterator::operator++ (int) +{ + ACE_Double_Linked_List_Iterator retv (*this); + this->do_advance (); + return retv; +} + + +// Prefix reverse. + +template +ACE_Double_Linked_List_Iterator & +ACE_Double_Linked_List_Iterator::operator-- (void) +{ + this->do_retreat (); + return *this; +} + + +// Postfix reverse. + +template +ACE_Double_Linked_List_Iterator +ACE_Double_Linked_List_Iterator::operator-- (int) +{ + ACE_Double_Linked_List_Iterator retv (*this); + this->do_retreat (); + return retv; +} + + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Double_Linked_List_Reverse_Iterator) + + template +ACE_Double_Linked_List_Reverse_Iterator::ACE_Double_Linked_List_Reverse_Iterator (ACE_Double_Linked_List &dll) + : ACE_Double_Linked_List_Iterator_Base (dll) +{ + this->current_ = static_cast (dll.head_->prev_); + // Advance current_ out of the null area and onto the last item in + // the list +} + +template void +ACE_Double_Linked_List_Reverse_Iterator::reset (ACE_Double_Linked_List &dll) +{ + this->ACE_Double_Linked_List_Iterator_Base ::reset (dll); + this->current_ = static_cast (dll.head_->prev_); + // Advance current_ out of the null area and onto the last item in + // the list +} + +template int +ACE_Double_Linked_List_Reverse_Iterator::first (void) +{ + return this->go_tail (); +} + +template int +ACE_Double_Linked_List_Reverse_Iterator::advance (void) +{ + return this->do_retreat () ? 1 : 0; +} + +template T* +ACE_Double_Linked_List_Reverse_Iterator::advance_and_remove (bool dont_remove) +{ + T* item = 0; + if (dont_remove) + { + this->do_retreat (); + } + else + { + item = this->next (); + this->do_retreat (); + // It seems dangerous to remove nodes in an iterator, but so it goes... + ACE_Double_Linked_List *dllist = + const_cast *> (this->dllist_); + dllist->remove (item); + } + return item; +} + +template void +ACE_Double_Linked_List_Reverse_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->dump_i (); +#endif /* ACE_HAS_DUMP */ +} + +// Prefix advance. + +template +ACE_Double_Linked_List_Reverse_Iterator & +ACE_Double_Linked_List_Reverse_Iterator::operator++ (void) +{ + this->do_retreat (); + return *this; +} + + +// Postfix advance. + +template +ACE_Double_Linked_List_Reverse_Iterator +ACE_Double_Linked_List_Reverse_Iterator::operator++ (int) +{ + ACE_Double_Linked_List_Reverse_Iterator retv (*this); + this->do_retreat (); + return retv; +} + + +// Prefix reverse. + +template +ACE_Double_Linked_List_Reverse_Iterator & +ACE_Double_Linked_List_Reverse_Iterator::operator-- (void) +{ + this->do_advance (); + return *this; +} + + +// Postfix reverse. + +template +ACE_Double_Linked_List_Reverse_Iterator +ACE_Double_Linked_List_Reverse_Iterator::operator-- (int) +{ + ACE_Double_Linked_List_Reverse_Iterator retv (*this); + this->do_advance (); + return retv; +} + + +ACE_ALLOC_HOOK_DEFINE(ACE_Double_Linked_List) + + template +ACE_Double_Linked_List:: ACE_Double_Linked_List (ACE_Allocator *alloc) + : size_ (0), allocator_ (alloc) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (T *) this->allocator_->malloc (sizeof (T)), + T); + this->init_head (); +} + +template +ACE_Double_Linked_List::ACE_Double_Linked_List (const ACE_Double_Linked_List &cx) + : allocator_ (cx.allocator_) +{ + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (T *) this->allocator_->malloc (sizeof (T)), + T); + this->init_head (); + this->copy_nodes (cx); + this->size_ = cx.size_; +} + +template void +ACE_Double_Linked_List::operator= (const ACE_Double_Linked_List &cx) +{ + if (this != &cx) + { + this->delete_nodes (); + this->copy_nodes (cx); + } +} + +template +ACE_Double_Linked_List::~ACE_Double_Linked_List (void) +{ + this->delete_nodes (); + + ACE_DES_FREE (head_, + this->allocator_->free, + T); + + this->head_ = 0; +} + +template int +ACE_Double_Linked_List::is_empty (void) const +{ + return this->size () ? 0 : 1; +} + +template int +ACE_Double_Linked_List::is_full (void) const +{ + return 0; // We have no bound. +} + +template T * +ACE_Double_Linked_List::insert_tail (T *new_item) +{ + // Insert it before , i.e., at tail. + this->insert_element (new_item, 1); + return new_item; +} + +template T * +ACE_Double_Linked_List::insert_head (T *new_item) +{ + this->insert_element (new_item); // Insert it after , i.e., at head. + return new_item; +} + +template T * +ACE_Double_Linked_List::delete_head (void) +{ + if (this->is_empty ()) + return 0; + + T *temp = static_cast (this->head_->next_); + // Detach it from the list. + this->remove_element (temp); + return temp; +} + +template T * +ACE_Double_Linked_List::delete_tail (void) +{ + if (this->is_empty ()) + return 0; + + T *temp = static_cast (this->head_->prev_); + // Detach it from the list. + this->remove_element (temp); + return temp; +} + +template void +ACE_Double_Linked_List::reset (void) +{ + this->delete_nodes (); +} + +template int +ACE_Double_Linked_List::get (T *&item, size_t slot) +{ + ACE_Double_Linked_List_Iterator iter (*this); + + for (size_t i = 0; + i < slot && !iter.done (); + i++) + iter.advance (); + + item = iter.next (); + return item ? 0 : -1; +} + +template size_t +ACE_Double_Linked_List::size (void) const +{ + return this->size_; +} + +template void +ACE_Double_Linked_List::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // Dump the state of an object. +#endif /* ACE_HAS_DUMP */ +} + +#if 0 +template T * +ACE_Double_Linked_List::find (const T &item) +{ + for (ACE_Double_Linked_List_Iterator iter (*this); + !iter.done (); + iter.advance ()) + { + T *temp = iter.next (); + + if (*temp == item) + return temp; + } + + return 0; +} + +template int +ACE_Double_Linked_List::remove (const T &item) +{ + T *temp = this->find (item); + + if (temp != 0) + return this->remove (temp); + else + return -1; +} +#endif /* 0 */ + +template int +ACE_Double_Linked_List::remove (T *n) +{ + return this->remove_element (n); +} + +template void +ACE_Double_Linked_List::delete_nodes (void) +{ + while (! this->is_empty ()) + { + T * temp = static_cast (this->head_->next_); + this->remove_element (temp); + ACE_DES_FREE (temp, + this->allocator_->free, + T); + } +} + +template void +ACE_Double_Linked_List::copy_nodes (const ACE_Double_Linked_List &c) +{ + for (ACE_Double_Linked_List_Iterator iter (c); + !iter.done (); + iter.advance ()) + { + T* temp = 0; + ACE_NEW_MALLOC (temp, + (T *)this->allocator_->malloc (sizeof (T)), + T (*iter.next ())); + this->insert_tail (temp); + } +} + +template void +ACE_Double_Linked_List::init_head (void) +{ + this->head_->next_ = this->head_; + this->head_->prev_ = this->head_; +} + +template int +ACE_Double_Linked_List::insert_element (T *new_item, + int before, + T *old_item) +{ + if (old_item == 0) + old_item = this->head_; + + if (before) + old_item = static_cast (old_item->prev_); + + new_item->next_ = old_item->next_; + new_item->next_->prev_ = new_item; + new_item->prev_ = old_item; + old_item->next_ = new_item; + ++this->size_; + return 0; // Well, what will cause errors here? +} + +template int +ACE_Double_Linked_List::remove_element (T *item) +{ + // Notice that you have to ensure that item is an element of this + // list. We can't do much checking here. + + if (item == this->head_ || item->next_ == 0 + || item->prev_ == 0 || this->size () == 0) // Can't remove head + return -1; + + item->prev_->next_ = item->next_; + item->next_->prev_ = item->prev_; + item->next_ = item->prev_ = 0; // reset pointers to prevent double removal. + --this->size_; + return 0; +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set) + +template size_t +ACE_Fixed_Set::size (void) const +{ + ACE_TRACE ("ACE_Fixed_Set::size"); + return this->cur_size_; +} + +template void +ACE_Fixed_Set::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Fixed_Set::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Fixed_Set::~ACE_Fixed_Set (void) +{ + ACE_TRACE ("ACE_Fixed_Set::~ACE_Fixed_Set"); + this->cur_size_ = 0; +} + +template +ACE_Fixed_Set::ACE_Fixed_Set (const ACE_Fixed_Set &fs) + : cur_size_ (fs.cur_size_) +{ + ACE_TRACE ("ACE_Fixed_Set::ACE_Fixed_Set"); + + for (size_t i = 0, j = 0; i < fs.max_size_ && j < this->cur_size_; ++i) + if (fs.search_structure_[i].is_free_ == 0) + this->search_structure_[j++] = fs.search_structure_[i]; +} + +template void +ACE_Fixed_Set::operator= (const ACE_Fixed_Set &fs) +{ + ACE_TRACE ("ACE_Fixed_Set::operator="); + + if (this != &fs) + { + this->cur_size_ = fs.cur_size_; + + for (size_t i = 0, j = 0; i < fs.max_size_ && j < this->cur_size_; ++i) + if (fs.search_structure_[i].is_free_ == 0) + this->search_structure_[j++] = fs.search_structure_[i]; + } +} + +template +ACE_Fixed_Set::ACE_Fixed_Set (void) + : cur_size_ (0), + max_size_ (ACE_SIZE) +{ + ACE_TRACE ("ACE_Fixed_Set::ACE_Fixed_Set"); + for (size_t i = 0; i < this->max_size_; i++) + this->search_structure_[i].is_free_ = 1; +} + +template int +ACE_Fixed_Set::find (const T &item) const +{ + ACE_TRACE ("ACE_Fixed_Set::find"); + + for (size_t i = 0, j = 0; i < this->max_size_ && j < this->cur_size_; ++i) + if (this->search_structure_[i].is_free_ == 0) + { + if (this->search_structure_[i].item_ == item) + return 0; + ++j; + } + + return -1; +} + +template int +ACE_Fixed_Set::insert (const T &item) +{ + ACE_TRACE ("ACE_Fixed_Set::insert"); + ssize_t first_free = -1; // Keep track of first free slot. + size_t i; + + for (i = 0; + i < this->max_size_ && first_free == -1; + ++i) + + // First, make sure we don't allow duplicates. + + if (this->search_structure_[i].is_free_ == 0) + { + if (this->search_structure_[i].item_ == item) + return 1; + } + else + first_free = static_cast (i); + + // If we found a free spot let's reuse it. + + if (first_free > -1) + { + this->search_structure_[first_free].item_ = item; + this->search_structure_[first_free].is_free_ = 0; + this->cur_size_++; + return 0; + } + else /* No more room! */ + { + errno = ENOMEM; + return -1; + } +} + +template int +ACE_Fixed_Set::remove (const T &item) +{ + ACE_TRACE ("ACE_Fixed_Set::remove"); + + for (size_t i = 0, j = 0; + i < this->max_size_ && j < this->cur_size_; + ++i) + if (this->search_structure_[i].is_free_ == 0) + { + if (this->search_structure_[i].item_ == item) + { + // Mark this entry as being free. + this->search_structure_[i].is_free_ = 1; + + --this->cur_size_; + return 0; + } + else + ++j; + } + + return -1; +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set_Iterator_Base) + +template void +ACE_Fixed_Set_Iterator_Base::dump_i (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Fixed_Set_Iterator_Base::dump_i"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Fixed_Set_Iterator_Base::ACE_Fixed_Set_Iterator_Base (ACE_Fixed_Set &s) + : s_ (s), + next_ (-1), + iterated_items_ (0) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator_Base::ACE_Fixed_Set_Iterator_Base"); + this->advance (); +} + +template int +ACE_Fixed_Set_Iterator_Base::advance (void) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator_Base::advance"); + + if (this->iterated_items_ < this->s_.cur_size_) + { + for (++this->next_; + static_cast (this->next_) < this->s_.max_size_; + ++this->next_) + if (this->s_.search_structure_[this->next_].is_free_ == 0) + { + ++this->iterated_items_; + return 1; + } + } + else + ++this->next_; + + return 0; +} + +template int +ACE_Fixed_Set_Iterator_Base::first (void) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator_Base::first"); + + next_ = -1; + iterated_items_ = 0; + return this->advance (); +} + +template int +ACE_Fixed_Set_Iterator_Base::done (void) const +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator_Base::done"); + + return ! (this->iterated_items_ < this->s_.cur_size_); +} + +template int +ACE_Fixed_Set_Iterator_Base::next_i (T *&item) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator_Base::next_i"); + + if (static_cast (this->next_) < this->s_.max_size_) + do + { + if (this->s_.search_structure_[this->next_].is_free_ == 0) + { + item = &this->s_.search_structure_[this->next_].item_; + this->advance (); + return 1; + } + } + while (this->advance () == 1); + + return 0; +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set_Iterator) + +template void +ACE_Fixed_Set_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->dump_i (); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Fixed_Set_Iterator::ACE_Fixed_Set_Iterator (ACE_Fixed_Set &s) + : ACE_Fixed_Set_Iterator_Base (s) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::ACE_Fixed_Set_Iterator"); +} + +template int +ACE_Fixed_Set_Iterator::next (T *&item) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::next"); + return this->next_i (item); +} + +template int +ACE_Fixed_Set_Iterator::remove (T *&item) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::remove"); + + if (this->s_.search_structure_[this->next_].is_free_ == 0) + { + item = &this->s_.search_structure_[this->next_].item_; + this->s_.remove (*item); + --(this->iterated_items_); + return 1; + } + + return 0; +} + +template T& +ACE_Fixed_Set_Iterator::operator* (void) +{ + T *retv = 0; + + if (this->s_.search_structure_[this->next_].is_free_ == 0) + retv = &this->s_.search_structure_[this->next_].item_; + + ACE_ASSERT (retv != 0); + + return *retv; +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set_Const_Iterator) + +template void +ACE_Fixed_Set_Const_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + this->dump_i (); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Fixed_Set_Const_Iterator::ACE_Fixed_Set_Const_Iterator (const ACE_Fixed_Set &s) + : ACE_Fixed_Set_Iterator_Base (s) +{ + ACE_TRACE ("ACE_Fixed_Set_Const_Iterator::ACE_Fixed_Set_Const_Iterator"); +} + +template int +ACE_Fixed_Set_Const_Iterator::next (const T *&item) +{ + ACE_TRACE ("ACE_Fixed_Set_Const_Iterator::next"); + + return this->next_i (item); +} + +template const T& +ACE_Fixed_Set_Const_Iterator::operator* (void) const +{ + const T *retv = 0; + + if (this->s_.search_structure_[this->next_].is_free_ == 0) + retv = &this->s_.search_structure_[this->next_].item_; + + ACE_ASSERT (retv != 0); + + return *retv; +} + +//-------------------------------------------------- +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Set) + +template void +ACE_Bounded_Set::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Bounded_Set::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Bounded_Set::~ACE_Bounded_Set (void) +{ + ACE_TRACE ("ACE_Bounded_Set::~ACE_Bounded_Set"); + delete [] this->search_structure_; +} + +template +ACE_Bounded_Set::ACE_Bounded_Set (void) + : cur_size_ (0), + max_size_ (static_cast (ACE_Bounded_Set::DEFAULT_SIZE)) +{ + ACE_TRACE ("ACE_Bounded_Set::ACE_Bounded_Set"); + + ACE_NEW (this->search_structure_, + typename ACE_Bounded_Set::Search_Structure[this->max_size_]); + + for (size_t i = 0; i < this->max_size_; ++i) + this->search_structure_[i].is_free_ = 1; +} + +template size_t +ACE_Bounded_Set::size (void) const +{ + ACE_TRACE ("ACE_Bounded_Set::size"); + return this->cur_size_; +} + +template +ACE_Bounded_Set::ACE_Bounded_Set (const ACE_Bounded_Set &bs) + : cur_size_ (bs.cur_size_), + max_size_ (bs.max_size_) +{ + ACE_TRACE ("ACE_Bounded_Set::ACE_Bounded_Set"); + + ACE_NEW (this->search_structure_, + typename ACE_Bounded_Set::Search_Structure[this->max_size_]); + + for (size_t i = 0; i < this->cur_size_; i++) + this->search_structure_[i] = bs.search_structure_[i]; +} + +template void +ACE_Bounded_Set::operator= (const ACE_Bounded_Set &bs) +{ + ACE_TRACE ("ACE_Bounded_Set::operator="); + + if (this != &bs) + { + if (this->max_size_ < bs.cur_size_) + { + delete [] this->search_structure_; + ACE_NEW (this->search_structure_, + typename ACE_Bounded_Set::Search_Structure[bs.cur_size_]); + this->max_size_ = bs.cur_size_; + } + + this->cur_size_ = bs.cur_size_; + + for (size_t i = 0; i < this->cur_size_; i++) + this->search_structure_[i] = bs.search_structure_[i]; + } +} + +template +ACE_Bounded_Set::ACE_Bounded_Set (size_t size) + : cur_size_ (0), + max_size_ (size) +{ + ACE_TRACE ("ACE_Bounded_Set::ACE_Bounded_Set"); + ACE_NEW (this->search_structure_, + typename ACE_Bounded_Set::Search_Structure[size]); + + for (size_t i = 0; i < this->max_size_; i++) + this->search_structure_[i].is_free_ = 1; +} + +template int +ACE_Bounded_Set::find (const T &item) const +{ + ACE_TRACE ("ACE_Bounded_Set::find"); + + for (size_t i = 0; i < this->cur_size_; i++) + if (this->search_structure_[i].item_ == item + && this->search_structure_[i].is_free_ == 0) + return 0; + + return -1; +} + +template int +ACE_Bounded_Set::insert (const T &item) +{ + ACE_TRACE ("ACE_Bounded_Set::insert"); + int first_free = -1; // Keep track of first free slot. + size_t i; + + for (i = 0; i < this->cur_size_; i++) + // First, make sure we don't allow duplicates. + + if (this->search_structure_[i].item_ == item + && this->search_structure_[i].is_free_ == 0) + return 1; + else if (this->search_structure_[i].is_free_ && first_free == -1) + first_free = static_cast (i); + + if (first_free > -1) // If we found a free spot let's reuse it. + { + this->search_structure_[first_free].item_ = item; + this->search_structure_[first_free].is_free_ = 0; + return 0; + } + else if (i < this->max_size_) // Insert at the end of the active portion. + { + this->search_structure_[i].item_ = item; + this->search_structure_[i].is_free_ = 0; + this->cur_size_++; + return 0; + } + else /* No more room! */ + { + errno = ENOMEM; + return -1; + } +} + +template int +ACE_Bounded_Set::remove (const T &item) +{ + ACE_TRACE ("ACE_Bounded_Set::remove"); + for (size_t i = 0; i < this->cur_size_; i++) + if (this->search_structure_[i].item_ == item) + { + // Mark this entry as being free. + this->search_structure_[i].is_free_ = 1; + + // If we just unbound the highest entry, then we need to + // figure out where the next highest active entry is. + if (i + 1 == this->cur_size_) + { + while (i > 0 && this->search_structure_[--i].is_free_) + continue; + + if (i == 0 && this->search_structure_[i].is_free_) + this->cur_size_ = 0; + else + this->cur_size_ = i + 1; + } + return 0; + } + + return -1; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Set_Iterator) + + template void +ACE_Bounded_Set_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Bounded_Set_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Bounded_Set_Iterator::ACE_Bounded_Set_Iterator (ACE_Bounded_Set &s) + : s_ (s), + next_ (-1) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::ACE_Bounded_Set_Iterator"); + this->advance (); +} + +template int +ACE_Bounded_Set_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::advance"); + + for (++this->next_; + static_cast (this->next_) < this->s_.cur_size_ + && this->s_.search_structure_[this->next_].is_free_; + ++this->next_) + continue; + + return static_cast (this->next_) < this->s_.cur_size_; +} + +template int +ACE_Bounded_Set_Iterator::first (void) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::first"); + + next_ = -1; + return this->advance (); +} + +template int +ACE_Bounded_Set_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::done"); + + return static_cast (this->next_) >= + this->s_.cur_size_; +} + +template int +ACE_Bounded_Set_Iterator::next (T *&item) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::next"); + if (static_cast (this->next_) < this->s_.cur_size_) + { + item = &this->s_.search_structure_[this->next_].item_; + return 1; + } + else + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_DNode) + + template +ACE_DNode::ACE_DNode (const T &i, ACE_DNode *n, ACE_DNode *p) + : next_ (n), prev_ (p), item_ (i) +{ +} + +template +ACE_DNode::~ACE_DNode (void) +{ +} + +// **************************************************************** + +template void +ACE_Unbounded_Stack_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Stack_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unbounded_Stack_Iterator::ACE_Unbounded_Stack_Iterator (ACE_Unbounded_Stack &q) + : current_ (q.head_->next_), + stack_ (q) +{ + // ACE_TRACE ("ACE_Unbounded_Stack_Iterator::ACE_Unbounded_Stack_Iterator"); +} + +template int +ACE_Unbounded_Stack_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Unbounded_Stack_Iterator::advance"); + this->current_ = this->current_->next_; + return this->current_ != this->stack_.head_; +} + +template int +ACE_Unbounded_Stack_Iterator::first (void) +{ + // ACE_TRACE ("ACE_Unbounded_Stack_Iterator::first"); + this->current_ = this->stack_.head_->next_; + return this->current_ != this->stack_.head_; +} + +template int +ACE_Unbounded_Stack_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Unbounded_Stack_Iterator::done"); + + return this->current_ == this->stack_.head_; +} + +template int +ACE_Unbounded_Stack_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Unbounded_Stack_Iterator::next"); + if (this->current_ == this->stack_.head_) + return 0; + else + { + item = &this->current_->item_; + return 1; + } +} + + +ACE_ALLOC_HOOK_DEFINE(ACE_Ordered_MultiSet) + + + template +ACE_Ordered_MultiSet::ACE_Ordered_MultiSet (ACE_Allocator *alloc) + : head_ (0) + , tail_ (0) + , cur_size_ (0) + , allocator_ (alloc) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet::ACE_Ordered_MultiSet"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); +} + +template +ACE_Ordered_MultiSet::ACE_Ordered_MultiSet (const ACE_Ordered_MultiSet &us) + : head_ (0) + , tail_ (0) + , cur_size_ (0) + , allocator_ (us.allocator_) +{ + ACE_TRACE ("ACE_Ordered_MultiSet::ACE_Ordered_MultiSet"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + this->copy_nodes (us); +} + +template +ACE_Ordered_MultiSet::~ACE_Ordered_MultiSet (void) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet::~ACE_Ordered_MultiSet"); + + this->delete_nodes (); +} + + +template void +ACE_Ordered_MultiSet::operator= (const ACE_Ordered_MultiSet &us) +{ + ACE_TRACE ("ACE_Ordered_MultiSet::operator="); + + if (this != &us) + { + this->delete_nodes (); + this->copy_nodes (us); + } +} + + +template int +ACE_Ordered_MultiSet::insert (const T &item) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet::insert"); + + return this->insert_from (item, this->head_, 0); +} + +template int +ACE_Ordered_MultiSet::insert (const T &new_item, + ITERATOR &iter) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet::insert using iterator"); + + return this->insert_from (new_item, iter.current_, &iter.current_); +} + +template int +ACE_Ordered_MultiSet::remove (const T &item) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet::remove"); + + ACE_DNode *node = 0; + + int result = locate (item, 0, node); + + // if we found the node, remove from list and free it + if (node && (result == 0)) + { + if (node->prev_) + node->prev_->next_ = node->next_; + else + head_ = node->next_; + + if (node->next_) + node->next_->prev_ = node->prev_; + else + tail_ = node->prev_; + + --this->cur_size_; + + ACE_DES_FREE_TEMPLATE (node, + this->allocator_->free, + ACE_DNode, + ); + return 0; + } + + return -1; +} + +template int +ACE_Ordered_MultiSet::find (const T &item, + ITERATOR &iter) const +{ + // search an occurance of item, using iterator's current position as a hint + ACE_DNode *node = iter.current_; + int const result = locate (item, node, node); + + // if we found the node, update the iterator and indicate success + if (node && (result == 0)) + { + iter.current_ = node; + return 0; + } + + return -1; +} + + + +template void +ACE_Ordered_MultiSet::reset (void) +{ + ACE_TRACE ("reset"); + + this->delete_nodes (); +} + +template void +ACE_Ordered_MultiSet::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Ordered_MultiSet::dump"); + // + // ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhead_ = %u"), this->head_)); + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhead_->next_ = %u"), this->head_->next_)); + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d\n"), this->cur_size_)); + // + // T *item = 0; + // size_t count = 1; + // + // for (ACE_Ordered_MultiSet_Iterator iter (*(ACE_Ordered_MultiSet *) this); + // iter.next (item) != 0; + // iter.advance ()) + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("count = %d\n"), count++)); + // + // ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template int +ACE_Ordered_MultiSet::insert_from (const T &item, ACE_DNode *position, + ACE_DNode **new_position) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet::insert_from"); + + // create a new node + ACE_DNode *temp = 0; + ACE_NEW_MALLOC_RETURN (temp, + static_cast*> (this->allocator_->malloc (sizeof (ACE_DNode))), + ACE_DNode (item), + -1); + // obtain approximate location of the node + int result = locate (item, position, position); + + // if there are nodes in the multiset + if (position) + { + switch (result) + { + // insert after the approximate position + case -1: + + // if there is a following node + if (position->next_) + { + // link up with the following node + position->next_->prev_ = temp; + temp->next_ = position->next_; + } + else + // appending to the end of the set + tail_ = temp; + + // link up with the preceeding node + temp->prev_ = position; + position->next_ = temp; + + break; + + // insert before the position + case 0: + case 1: + + // if there is a preceeding node + if (position->prev_) + { + // link up with the preceeding node + position->prev_->next_ = temp; + temp->prev_ = position->prev_; + } + else + // prepending to the start of the set + head_ = temp; + + // link up with the preceeding node + temp->next_ = position; + position->prev_ = temp; + + break; + + default: + return -1; + } + } + else + { + // point the head and tail to the new node. + this->head_ = temp; + this->tail_ = temp; + } + + ++this->cur_size_; + if (new_position) + *new_position = temp; + + return 0; +} + +template int +ACE_Ordered_MultiSet::locate (const T &item, ACE_DNode *start_position, + ACE_DNode *&new_position) const +{ + if (! start_position) + start_position = this->head_; + + // If starting before the item, move forward until at or just before + // item. + while (start_position && start_position->item_ < item && + start_position->next_) + start_position = start_position->next_; + + // If starting after the item, move back until at or just after item + while (start_position && item < start_position->item_ && + start_position->prev_) + start_position = start_position->prev_; + + // Save the (approximate) location in the passed pointer. + new_position = start_position; + + // Show the location is after (1), before (-1) , or at (0) the item + if (!new_position) + return 1; + else if (item < new_position->item_) + return 1; + else if (new_position->item_ < item) + return -1; + else + return 0; +} + +// Looks for first occurance of in the ordered set, using the +// passed starting position as a hint: if there is such an instance, +// it updates the new_position pointer to point to one such node and +// returns 0; if there is no such node, then if there is a node before +// where the item would have been, it updates the new_position pointer +// to point to this node and returns -1; if there is no such node, +// then if there is a node after where the item would have been, it +// updates the new_position pointer to point to this node (or 0 if +// there is no such node) and returns 1; + +template void +ACE_Ordered_MultiSet::copy_nodes (const ACE_Ordered_MultiSet &us) +{ + ACE_DNode *insertion_point = this->head_; + + for (ACE_DNode *curr = us.head_; + curr != 0; + curr = curr->next_) + this->insert_from (curr->item_, insertion_point, &insertion_point); +} + +template void +ACE_Ordered_MultiSet::delete_nodes (void) +{ + // iterate through list, deleting nodes + for (ACE_DNode *curr = this->head_; + curr != 0; + ) + { + ACE_DNode *temp = curr; + curr = curr->next_; + ACE_DES_FREE_TEMPLATE (temp, + this->allocator_->free, + ACE_DNode, + ); + } + + this->head_ = 0; + this->tail_ = 0; + this->cur_size_ = 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Ordered_MultiSet_Iterator) + +template +ACE_Ordered_MultiSet_Iterator::ACE_Ordered_MultiSet_Iterator (ACE_Ordered_MultiSet &s) + : current_ (s.head_), + set_ (s) +{ + // ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::ACE_Ordered_MultiSet_Iterator"); +} + +template int +ACE_Ordered_MultiSet_Iterator::next (T *&item) const +{ + // ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::next"); + if (this->current_) + { + item = &this->current_->item_; + return 1; + } + + return 0; +} + +template T& +ACE_Ordered_MultiSet_Iterator::operator* (void) +{ + //ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::operator*"); + T *retv = 0; + + int const result = this->next (retv); + ACE_ASSERT (result != 0); + ACE_UNUSED_ARG (result); + + return *retv; +} + +ACE_ALLOC_HOOK_DEFINE (ACE_DLList_Node) + +template T * +ACE_DLList::insert_tail (T *new_item) +{ + ACE_DLList_Node *temp1 = 0; + ACE_NEW_MALLOC_RETURN (temp1, + static_cast (this->allocator_->malloc (sizeof (ACE_DLList_Node))), + ACE_DLList_Node (new_item), + 0); + ACE_DLList_Node *temp2 = ACE_DLList_Base::insert_tail (temp1); + return (T *) (temp2 ? temp2->item_ : 0); +} + +template T * +ACE_DLList::insert_head (T *new_item) +{ + ACE_DLList_Node *temp1 = 0; + ACE_NEW_MALLOC_RETURN (temp1, + (ACE_DLList_Node *) this->allocator_->malloc (sizeof (ACE_DLList_Node)), + ACE_DLList_Node (new_item), 0); + ACE_DLList_Node *temp2 = ACE_DLList_Base::insert_head (temp1); + return (T *) (temp2 ? temp2->item_ : 0); +} + +template T * +ACE_DLList::delete_head (void) +{ + ACE_DLList_Node *temp1 = ACE_DLList_Base::delete_head (); + T *temp2 = (T *) (temp1 ? temp1->item_ : 0); + ACE_DES_FREE (temp1, + this->allocator_->free, + ACE_DLList_Node); + + return temp2; +} + +template T * +ACE_DLList::delete_tail (void) +{ + ACE_DLList_Node *temp1 = ACE_DLList_Base::delete_tail (); + T *temp2 = (T *) (temp1 ? temp1->item_ : 0); + ACE_DES_FREE (temp1, + this->allocator_->free, + ACE_DLList_Node); + return temp2; +} + +// **************************************************************** + +// Compare this array with for equality. + +template bool +ACE_Array::operator== (const ACE_Array &s) const +{ + if (this == &s) + return true; + else if (this->size () != s.size ()) + return false; + + const size_t len = s.size (); + for (size_t slot = 0; slot < len; ++slot) + if ((*this)[slot] != s[slot]) + return false; + + return true; +} + +// **************************************************************** + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_CONTAINERS_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Containers_T.h b/dep/ACE_wrappers/ace/Containers_T.h new file mode 100644 index 000000000..7245b51b6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Containers_T.h @@ -0,0 +1,2073 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Containers_T.h + * + * $Id: Containers_T.h 82588 2008-08-11 13:37:41Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_CONTAINERS_T_H +#define ACE_CONTAINERS_T_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Need by ACE_DLList_Node. +#include "ace/Containers.h" + +// Shared with "ace/Unbounded_Set.h" +#include "ace/Node.h" + +// Backwards compatibility, please include "ace/Array_Base.h" directly. +#include "ace/Array_Base.h" + +// Backwards compatibility, please include "ace/Unbounded_Set.h" directly. +#include "ace/Unbounded_Set.h" + +// Backwards compatibility, please include "ace/Unbounded_Queue.h" directly. +#include "ace/Unbounded_Queue.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Allocator; + + +/** + * @class ACE_Bounded_Stack + * + * @brief Implement a generic LIFO abstract data type. + * + * This implementation of a Stack uses a bounded array + * that is allocated dynamically. The Stack interface + * provides the standard constant time push, pop, and top + * operations. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Dynamic array + * - Duplicates allowed? + * Yes + * - Random access allowed? + * No + * - Search speed + * N/A + * - Insert/replace speed + * N/A + * - Iterator still valid after change to container? + * N/A + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * + */ +template +class ACE_Bounded_Stack +{ +public: + // = Initialization, assignment, and termination methods. + + /// Initialize a new empty stack with the provided size.. + /** + * Initialize and allocate space for a new Bounded_Stack with the provided + * size. + */ + ACE_Bounded_Stack (size_t size); + + /// Initialize the stack to be a copy of the stack provided. + /** + * Initialize the stack to be an exact copy of the Bounded_Stack provided + * as a parameter. + */ + ACE_Bounded_Stack (const ACE_Bounded_Stack &s); + + /// Assignment operator + /** + * Perform a deep copy operation using the Bounded_Stack parameter. If the + * capacity of the lhs isn't sufficient for the rhs, then the underlying data + * structure will be reallocated to accomadate the larger number of elements. + */ + void operator= (const ACE_Bounded_Stack &s); + + /// Perform actions needed when stack goes out of scope. + /** + * Deallocate the memory used by the Bounded_Stack. + */ + ~ACE_Bounded_Stack (void); + + // = Classic Stack operations. + + ///Add an element to the top of the stack. + /** + * Place a new item on top of the stack. Returns -1 if the stack + * is already full, 0 if the stack is not already full, and -1 if + * failure occurs. + */ + int push (const T &new_item); + + ///Remove an item from the top of stack. + /** + * Remove and return the top stack item. Returns -1 if the stack is + * already empty, 0 if the stack is not already empty, and -1 if + * failure occurs. + */ + int pop (T &item); + + ///Examine the contents of the top of stack. + /** + * Return top stack item without removing it. Returns -1 if the + * stack is already empty, 0 if the stack is not already empty, and + * -1 if failure occurs. + */ + int top (T &item) const; + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * Performs constant time check to determine if the stack is empty. + */ + int is_empty (void) const; + + /// Returns 1 if the container is full, otherwise returns 0. + /** + * Performs constant time check to determine if the stack is at capacity. + */ + int is_full (void) const; + + /// The number of items in the stack. + /** + * Return the number of items currently in the stack. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Size of the dynamically allocated data. + size_t size_; + + /// Keeps track of the current top of stack. + size_t top_; + + /// Holds the stack's contents. + T *stack_; +}; + +//---------------------------------------- + + +/** + * @class ACE_Fixed_Stack + * + * @brief Implement a generic LIFO abstract data type. + * + * This implementation of a Stack uses a fixed array + * with the size fixed at instantiation time. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Fixed array + * - Duplicates allowed? + * Yes + * - Random access allowed? + * No + * - Search speed + * N/A + * - Insert/replace speed + * N/A + * - Iterator still valid after change to container? + * N/A + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * + */ +template +class ACE_Fixed_Stack +{ +public: + // = Initialization, assignment, and termination methods. + /// Initialize a new stack so that it is empty. + /** + * Initialize an empty stack. + */ + ACE_Fixed_Stack (void); + + /// The copy constructor (performs initialization). + /** + * Initialize the stack and copy the provided stack into the current stack. + */ + ACE_Fixed_Stack (const ACE_Fixed_Stack &s); + + /// Assignment operator (performs assignment). + /** + * Perform a deep copy of the provided stack. + */ + void operator= (const ACE_Fixed_Stack &s); + + /// Perform actions needed when stack goes out of scope. + /** + * Destroy the stack. + */ + ~ACE_Fixed_Stack (void); + + // = Classic Stack operations. + + ///Constant time placement of element on top of stack. + /** + * Place a new item on top of the stack. Returns -1 if the stack + * is already full, 0 if the stack is not already full, and -1 if + * failure occurs. + */ + int push (const T &new_item); + + ///Constant time removal of top of stack. + /** + * Remove and return the top stack item. Returns -1 if the stack is + * already empty, 0 if the stack is not already empty, and -1 if + * failure occurs. + */ + int pop (T &item); + + ///Constant time examination of top of stack. + /** + * Return top stack item without removing it. Returns -1 if the + * stack is already empty, 0 if the stack is not already empty, and + * -1 if failure occurs. + */ + int top (T &item) const; + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * Performs constant time check to see if stack is empty. + */ + int is_empty (void) const; + + /// Returns 1 if the container is full, otherwise returns 0. + /** + * Performs constant time check to see if stack is full. + */ + int is_full (void) const; + + /// The number of items in the stack. + /** + * Constant time access to the current size of the stack. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Size of the allocated data. + size_t size_; + + /// Keeps track of the current top of stack. + size_t top_; + + /// Holds the stack's contents. + T stack_[ACE_SIZE]; +}; + +//---------------------------------------- + +template class ACE_Ordered_MultiSet; +template class ACE_Ordered_MultiSet_Iterator; + +/** + * @class ACE_DNode + * + * @brief Implementation element in a bilinked list. + */ +template +class ACE_DNode +{ + friend class ACE_Ordered_MultiSet; + friend class ACE_Ordered_MultiSet_Iterator; + +public: + + /// This isn't necessary, but it keeps some compilers happy. + ~ACE_DNode (void); + +private: + + // = Initialization methods + ACE_DNode (const T &i, ACE_DNode *n = 0, ACE_DNode *p = 0); + + /// Pointer to next element in the list of {ACE_DNode}s. + ACE_DNode *next_; + + /// Pointer to previous element in the list of {ACE_DNode}s. + ACE_DNode *prev_; + + /// Current value of the item in this node. + T item_; +}; + + + +/** + * @class ACE_Unbounded_Stack + * + * @brief Implement a generic LIFO abstract data type. + * + * This implementation of an unbounded Stack uses a linked list. + * If you use the {insert} or {remove} methods you should keep + * in mind that duplicate entries aren't allowed. In general, + * therefore, you should avoid the use of these methods since + * they aren't really part of the ADT stack. The stack is implemented + * as a doubly linked list. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Double linked list + * - Duplicates allowed? + * No + * - Random access allowed? + * No + * - Search speed + * Linear + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * Yes + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * + */ +template +class ACE_Unbounded_Stack +{ +public: + friend class ACE_Unbounded_Stack_Iterator; + + // Trait definition. + typedef ACE_Unbounded_Stack_Iterator ITERATOR; + + // = Initialization, assignment, and termination methods. + /// Initialize a new stack so that it is empty. Use user defined + /// allocation strategy if specified. + /** + * Initialize an empty stack using the user specified allocation strategy + * if provided. + */ + ACE_Unbounded_Stack (ACE_Allocator *the_allocator = 0); + + /// The copy constructor (performs initialization). + /** + * Initialize this stack to be an exact copy of {s}. + */ + ACE_Unbounded_Stack (const ACE_Unbounded_Stack &s); + + /// Assignment operator (performs assignment). + /** + * Perform a deep copy of the rhs into the lhs. + */ + void operator= (const ACE_Unbounded_Stack &s); + + /// Perform actions needed when stack goes out of scope. + /** + * Destroy the underlying list for the stack. + */ + ~ACE_Unbounded_Stack (void); + + // = Classic Stack operations. + + + ///Push an element onto the top of stack. + /** + * Place a new item on top of the stack. Returns -1 if the stack + * is already full, 0 if the stack is not already full, and -1 if + * failure occurs. + */ + int push (const T &new_item); + + ///Pop the top element of the stack. + /** + * Remove and return the top stack item. Returns -1 if the stack is + * already empty, 0 if the stack is not already empty, and -1 if + * failure occurs. + */ + int pop (T &item); + + ///Examine the top of the stack. + /** + * Return top stack item without removing it. Returns -1 if the + * stack is already empty, 0 if the stack is not already empty, and + * -1 if failure occurs. + */ + int top (T &item) const; + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * Constant time check to see if the stack is empty. + */ + int is_empty (void) const; + + /// Returns 1 if the container is full, otherwise returns 0. + /** + * Always resturns 0 since the stack is unbounded. + */ + int is_full (void) const; + + // = Auxiliary methods (not strictly part of the Stack ADT). + + ///Linear Insert of an item. + /** + * Insert {new_item} into the Stack at the head (but doesn't allow + * duplicates). Returns -1 if failures occur, 1 if item is already + * present (i.e., no duplicates are allowed), else 0. + */ + int insert (const T &new_item); + + /// Remove @a item from the Stack. Returns 0 if it removes the item, + /// -1 if it can't find the item, and -1 if a failure occurs. + /** + * Linear remove operation. + */ + int remove (const T &item); + + /// Finds if @a item occurs the set. Returns 0 if finds, else -1. + /** + * Linear find operation. + */ + int find (const T &item) const; + + /// The number of items in the stack. + /** + * Constant time access to the current stack size. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Delete all the nodes in the stack. + void delete_all_nodes (void); + + /// Copy all nodes from {s} to {this}. + void copy_all_nodes (const ACE_Unbounded_Stack &s); + + /// Head of the linked list of Nodes. + ACE_Node *head_; + + /// Current size of the stack. + size_t cur_size_; + + /// Allocation strategy of the stack. + ACE_Allocator *allocator_; +}; + +/** + * @class ACE_Unbounded_Stack_Iterator + * + * @brief Implement an iterator over an unbounded Stack. + */ +template +class ACE_Unbounded_Stack_Iterator +{ +public: + // = Initialization method. + /// Move to the first element in the {stack}. + ACE_Unbounded_Stack_Iterator (ACE_Unbounded_Stack &stack); + + // = Iteration methods. + + /// Pass back the @a next_item that hasn't been seen in the Stack. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the Stack. Returns 0 when all the + /// items in the Stack have been seen, else 1. + int advance (void); + + /// Move to the first element in the Stack. Returns 0 if the + /// Stack is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the current node in the iteration. + ACE_Node *current_; + + /// Pointer to the Stack we're iterating over. + ACE_Unbounded_Stack &stack_; +}; + +template +class ACE_Double_Linked_List; + +/** + * @class ACE_Double_Linked_List_Iterator_Base + * + * @brief Implements a common base class for iterators for a double + * linked list ADT + */ +template +class ACE_Double_Linked_List_Iterator_Base +{ +public: + // = Iteration methods. + + /// Passes back the {entry} under the iterator. Returns 0 if the + /// iteration has completed, otherwise 1 + int next (T *&) const; + + /** + * @deprecated Return the address of next (current) unvisited item in + * the list. 0 if there is no more element available. + */ + T *next (void) const; + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// STL-like iterator dereference operator: returns a reference + /// to the node underneath the iterator. + T & operator* (void) const ; + + /** + * Retasks the iterator to iterate over a new + * Double_Linked_List. This allows clients to reuse an iterator + * without incurring the constructor overhead. If you do use this, + * be aware that if there are more than one reference to this + * iterator, the other "clients" may be very bothered when their + * iterator changes. @@ Here be dragons. Comments? + */ + void reset (ACE_Double_Linked_List &); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Initialization methods. + + /// Constructor + ACE_Double_Linked_List_Iterator_Base (const ACE_Double_Linked_List &); + + /// Copy constructor. + ACE_Double_Linked_List_Iterator_Base (const + ACE_Double_Linked_List_Iterator_Base + &iter); + + // = Iteration methods. + /** + * Move to the first element of the list. Returns 0 if the list is + * empty, else 1. + * @note the head of the ACE_DLList is actually a null entry, so the + * first element is actually the 2n'd entry + */ + int go_head (void); + + /// Move to the last element of the list. Returns 0 if the list is + /// empty, else 1. + int go_tail (void); + + /** + * Check if we reach the end of the list. Can also be used to get + * the *current* element in the list. Return the address of the + * current item if there are still elements left , 0 if we run out + * of element. + */ + T *not_done (void) const ; + + /// Advance to the next element in the list. Return the address of the + /// next element if there are more, 0 otherwise. + T *do_advance (void); + + /// Retreat to the previous element in the list. Return the address + /// of the previous element if there are more, 0 otherwise. + T *do_retreat (void); + + /// Dump the state of an object. + void dump_i (void) const; + + /// Remember where we are. + T *current_; + + const ACE_Double_Linked_List *dllist_; +}; + +/** + * @class ACE_Double_Linked_List_Iterator + * + * @brief Implements an iterator for a double linked list ADT + * + * Iterate thru the double-linked list. This class provides + * an interface that let users access the internal element + * addresses directly. Notice {class T} must declare + * ACE_Double_Linked_List<T>, + * ACE_Double_Linked_List_Iterator_Base <T> and + * ACE_Double_Linked_List_Iterator as friend classes and class T + * should also have data members T* next_ and T* prev_. + */ +template +class ACE_Double_Linked_List_Iterator : public ACE_Double_Linked_List_Iterator_Base +{ +public: + // = Initialization method. + ACE_Double_Linked_List_Iterator (const ACE_Double_Linked_List &); + + /** + * Retasks the iterator to iterate over a new + * Double_Linked_List. This allows clients to reuse an iterator + * without incurring the constructor overhead. If you do use this, + * be aware that if there are more than one reference to this + * iterator, the other "clients" may be very bothered when their + * iterator changes. + * @@ Here be dragons. Comments? + */ + void reset (ACE_Double_Linked_List &); + + /// Move to the first element in the list. Returns 0 if the + /// list is empty, else 1. + int first (void); + + /// Move forward by one element in the list. Returns 0 when all the + /// items in the list have been seen, else 1. + int advance (void); + + /** + * Advance the iterator while removing the original item from the + * list. Return a pointer points to the original (removed) item. + * If @a dont_remove equals false, this function behaves like {advance} + * but return 0 (NULL) instead. + */ + T* advance_and_remove (bool dont_remove); + + // = STL-style iteration methods + + /// Prefix advance. + ACE_Double_Linked_List_Iterator & operator++ (void); + + /// Postfix advance. + ACE_Double_Linked_List_Iterator operator++ (int); + + /// Prefix reverse. + ACE_Double_Linked_List_Iterator & operator-- (void); + + /// Postfix reverse. + ACE_Double_Linked_List_Iterator operator-- (int); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +/** + * @class ACE_Double_Linked_List_Reverse_Iterator + * + * @brief Implements a reverse iterator for a double linked list ADT + * + * Iterate backwards over the double-linked list. This class + * provide an interface that let users access the internal + * element addresses directly, which seems to break the + * encapsulation. Notice {class T} must declare + * ACE_Double_Linked_List<T>, + * ACE_Double_Linked_List_Iterator_Base <T> and + * ACE_Double_Linked_List_Iterator as friend classes and class T + * should also have data members T* next_ and T* prev_. + */ +template +class ACE_Double_Linked_List_Reverse_Iterator : public ACE_Double_Linked_List_Iterator_Base +{ +public: + // = Initialization method. + ACE_Double_Linked_List_Reverse_Iterator (ACE_Double_Linked_List &); + + /** + * Retasks the iterator to iterate over a new + * Double_Linked_List. This allows clients to reuse an iterator + * without incurring the constructor overhead. If you do use this, + * be aware that if there are more than one reference to this + * iterator, the other "clients" may be very bothered when their + * iterator changes. + * @@ Here be dragons. Comments? + */ + void reset (ACE_Double_Linked_List &); + + /// Move to the first element in the list. Returns 0 if the + /// list is empty, else 1. + int first (void); + + /// Move forward by one element in the list. Returns 0 when all the + /// items in the list have been seen, else 1. + int advance (void); + + /** + * Advance the iterator while removing the original item from the + * list. Return a pointer points to the original (removed) item. + * If @a dont_remove equals false, this function behaves like {advance} + * but return 0 (NULL) instead. + */ + T* advance_and_remove (bool dont_remove); + + // = STL-style iteration methods + + /// Prefix advance. + ACE_Double_Linked_List_Reverse_Iterator & operator++ (void); + + /// Postfix advance. + ACE_Double_Linked_List_Reverse_Iterator operator++ (int); + + /// Prefix reverse. + ACE_Double_Linked_List_Reverse_Iterator & operator-- (void); + + /// Postfix reverse. + ACE_Double_Linked_List_Reverse_Iterator operator-- (int); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + + +/** + * @class ACE_Double_Linked_List + * + * @brief A double-linked list implementation. + * + * This implementation of an unbounded double-linked list uses a + * circular linked list with a dummy node. It is pretty much + * like the {ACE_Unbounded_Queue} except that it allows removing + * of a specific element from a specific location. + * Notice that this class is an implementation of a very simple + * data structure. This is *NOT* a container class. You can use the + * class to implement other contains classes but it is *NOT* a + * general purpose container class. + * The parameter class *MUST* have members T* prev and T* next + * and users of this class are responsible to follow the general + * rules of using double-linked lists to maintaining the list + * integrity. + * If you need a double linked container class, use the DLList + * class which is a container but delegates to the Double_Linked_List + * class. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Double Linked List + * - Duplicates allowed? + * Yes + * - Random access allowed? + * No + * - Search speed + * N/A + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * + */ +template +class ACE_Double_Linked_List +{ +public: + friend class ACE_Double_Linked_List_Iterator_Base; + friend class ACE_Double_Linked_List_Iterator; + friend class ACE_Double_Linked_List_Reverse_Iterator; + + // Trait definition. + typedef ACE_Double_Linked_List_Iterator ITERATOR; + typedef ACE_Double_Linked_List_Reverse_Iterator REVERSE_ITERATOR; + + // = Initialization and termination methods. + /// construction. Use user specified allocation strategy + /// if specified. + /** + * Initialize an empy list using the allocation strategy specified by the user. + * If none is specified, then use default allocation strategy. + */ + ACE_Double_Linked_List (ACE_Allocator *the_allocator = 0); + + /// Copy constructor. + /** + * Create a double linked list that is a copy of the provided + * parameter. + */ + ACE_Double_Linked_List (const ACE_Double_Linked_List &); + + /// Assignment operator. + /** + * Perform a deep copy of the provided list by first deleting the nodes of the + * lhs and then copying the nodes of the rhs. + */ + void operator= (const ACE_Double_Linked_List &); + + /// Destructor. + /** + * Clean up the memory allocated for the nodes of the list. + */ + ~ACE_Double_Linked_List (void); + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, 0 otherwise. + /** + * Performs constant time check to determine if the list is empty. + */ + int is_empty (void) const; + + /// The list is unbounded, so this always returns 0. + /** + * Since the list is unbounded, the method simply returns 0. + */ + int is_full (void) const; + + // = Classic queue operations. + + /// Adds @a new_item to the tail of the list. Returns the new item + /// that was inserted. + /** + * Provides constant time insertion at the end of the list structure. + */ + T *insert_tail (T *new_item); + + /// Adds @a new_item to the head of the list.Returns the new item that + /// was inserted. + /** + * Provides constant time insertion at the head of the list. + */ + T *insert_head (T *new_item); + + /// Removes the head of the list and returns a pointer to that item. + /** + * Removes and returns the first {item} in the list. Returns + * internal node's address on success, 0 if the queue was empty. + * This method will *not* free the internal node. + */ + T* delete_head (void); + + /// Removes the tail of the list and returns a pointer to that item. + /** + * Removes and returns the last {item} in the list. Returns + * internal nodes's address on success, 0 if the queue was + * empty. This method will *not* free the internal node. + */ + T *delete_tail (void); + + // = Additional utility methods. + + ///Empty the list. + /** + * Reset the {ACE_Double_Linked_List} to be empty. + * Notice that since no one is interested in the items within, + * This operation will delete all items. + */ + void reset (void); + + /// Get the {slot}th element in the set. Returns -1 if the element + /// isn't in the range {0..{size} - 1}, else 0. + /** + * Iterates through the list to the desired index and assigns the provides pointer + * with the address of the node occupying that index. + */ + int get (T *&item, size_t slot = 0); + + /// The number of items in the queue. + /** + * Constant time call to return the current size of the list. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Use DNode address directly. + /** + * Constant time removal of an item from the list using it's address. + */ + int remove (T *n); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Delete all the nodes in the list. + /** + * Removes and deallocates memory for all of the list nodes. + */ + void delete_nodes (void); + + /// Copy nodes from {rhs} into this list. + /** + * Copy the elements of the provided list by allocated new nodes and assigning + * them with the proper data. + */ + void copy_nodes (const ACE_Double_Linked_List &rhs); + + /// Setup header pointer. Called after we create the head node in ctor. + /** + * Initialize the head pointer so that the list has a dummy node. + */ + void init_head (void); + + ///Constant time insert a new item into the list structure. + /** + * Insert a @a new_item into the list. It will be added before + * or after @a old_item. Default is to insert the new item *after* + * {head_}. Return 0 if succeed, -1 if error occured. + */ + int insert_element (T *new_item, + int before = 0, + T *old_item = 0); + + ///Constant time delete an item from the list structure. + /** + * Remove @a item from the list. Return 0 if succeed, -1 otherwise. + * Notice that this function checks if item is {head_} and either its + * {next_} or {prev_} is NULL. The function resets item's {next_} and + * {prev_} to 0 to prevent clobbering the double-linked list if a user + * tries to remove the same node again. + */ + int remove_element (T *item); + + /// Head of the circular double-linked list. + T *head_; + + /// Size of this list. + size_t size_; + + /// Allocation Strategy of the queue. + ACE_Allocator *allocator_; +}; + + +template class ACE_DLList; +template class ACE_DLList_Iterator; +template class ACE_DLList_Reverse_Iterator; + +typedef ACE_Double_Linked_List ACE_DLList_Base; + +//typedef ACE_Double_Linked_List_Iterator +// ACE_DLList_Iterator_Base; +//typedef ACE_Double_Linked_List_Reverse_Iterator +// ACE_DLList_Reverse_Iterator_Base; +//@@ These two typedefs (inherited from James Hu's original design) +// have been removed because Sun CC 4.2 had problems with it. I guess +// having the DLList_Iterators inheriting from a class which is +// actually a typedef leads to problems. #define'ing rather than +// typedef'ing worked, but as per Carlos's reccomendation, I'm just +// replacing all references to the base classes with their actual +// type. Matt Braun (6/15/99) + +/** + * @class ACE_DLList + * + * @brief A double-linked list container class. + * + * ACE_DLList is a simple, unbounded container implemented using a + * double-linked list. It is critical to remember that ACE_DLList inherits + * from ACE_Double_Linked_List, wrapping each T pointer in a ACE_DLList_Node + * object which satisfies the next/prev pointer requirements imposed by + * ACE_Double_Linked_List. + * + * Each item inserted to an ACE_DLList is a pointer to a T object. The + * caller is responsible for lifetime of the T object. ACE_DLList takes no + * action on the T object; it is not copied on insertion and it is not + * deleted on removal from the ACE_DLList. + */ +template +class ACE_DLList : public ACE_DLList_Base +{ + friend class ACE_DLList_Node; + friend class ACE_Double_Linked_List_Iterator; + friend class ACE_DLList_Iterator; + friend class ACE_DLList_Reverse_Iterator; + +public: + + /// Delegates to ACE_Double_Linked_List. + void operator= (const ACE_DLList &l); + + /** + * @name Queue-like insert and delete methods + */ + //@{ + + /** + * Insert pointer for a new item at the tail of the list. + * + * @return Pointer to item inserted; 0 on error. + */ + T *insert_tail (T *new_item); + + /** + * Insert pointer for a new item at the head of the list. + * + * @return Pointer to item inserted; 0 on error. + */ + T *insert_head (T *new_item); + + /** + * Removes the item at the head of the list and returns its pointer. + * + * @return Pointer to previously inserted item; 0 if the list is empty, + * an error occurred, or the original pointer inserted was 0. + */ + T *delete_head (void); + + /** + * Removes the item at the tail of the list and returns its pointer. + * + * @return Pointer to previously inserted item; 0 if the list is empty, + * an error occurred, or the original pointer inserted was 0. + */ + T *delete_tail (void); + //@} + + /** + * Provide random access to any item in the list. + * + * @param item Receives a pointer to the T object pointer held at the + * specified position in the list. + * @param slot Position in the list to access. The first position is 0. + * + * @retval 0 Success; T pointer returned in item. + * @retval -1 Error, most likely slot is outside the range of the list. + */ + int get (T *&item, size_t slot = 0); + + /// Delegates to ACE_Double_Linked_List. + void dump (void) const; + + /// Delegates to ACE_Double_Linked_List. + int remove (ACE_DLList_Node *n); + + /** + * Constructor. + * + * @param the_allocator Allocator to use for allocating ACE_DLList_Node + * objects that wrap T objects for inclusion in the + * list. If 0, ACE_Allocator::instance() is used. + */ + ACE_DLList (ACE_Allocator *the_allocator = 0); + + /// Delegates to ACE_Double_Linked_List. + ACE_DLList (const ACE_DLList &l); + + /** + * Deletes all ACE_DLList_Node objects in the list starting from the head. + * No T objects referred to by the deleted ACE_DLList_Node objects are + * modified or freed. If you desire all of the T objects in the list to + * be deleted as well, code such as this should be used prior to destroying + * the ACE_DLList: + * @code + ACE_DLList list; + ... // insert dynamically allocated Items... + Item *p; + while ((p = list.delete_head()) != 0) + delete *p; + @endcode + */ + ~ACE_DLList (void); +}; + +/** + * @class ACE_DLList_Iterator + * + * @brief A double-linked list container class iterator. + * + * This implementation uses ACE_Double_Linked_List_Iterator to + * perform the logic behind this container class. It delegates + * all of its calls to ACE_Double_Linked_List_Iterator. + */ +template +class ACE_DLList_Iterator : public ACE_Double_Linked_List_Iterator +{ + + friend class ACE_DLList; + friend class ACE_DLList_Node; + +public: + + // = Initialization method. + ACE_DLList_Iterator (ACE_DLList &l); + + /** + * Retasks the iterator to iterate over a new + * Double_Linked_List. This allows clients to reuse an iterator + * without incurring the constructor overhead. If you do use this, + * be aware that if there are more than one reference to this + * iterator, the other "clients" may be very bothered when their + * iterator changes. + * @@ Here be dragons. Comments? + */ + void reset (ACE_DLList &l); + + // = Iteration methods. + /// Move forward by one element in the list. Returns 0 when all the + /// items in the list have been seen, else 1. + int advance (void); + + /// Pass back the {next_item} that hasn't been seen in the list. + /// Returns 0 when all items have been seen, else 1. + int next (T *&); + + /** + * @deprecated Delegates to ACE_Double_Linked_List_Iterator, except that + * whereas the Double_Linked_List version of next returns the node, this next + * returns the contents of the node + */ + T *next (void) const; + + /** + * Removes the current item (i.e., {next}) from the list. + * Note that DLList iterators do not support {advance_and_remove} + * directly (defined in its base class) and you will need to + * release the element returned by it. + */ + int remove (void); + + /// Delegates to ACE_Double_Linked_List_Iterator. + void dump (void) const; + +private: + ACE_DLList *list_; +}; + +/** + * @class ACE_DLList_Reverse_Iterator + * + * @brief A double-linked list container class iterator. + * + * This implementation uses ACE_Double_Linked_List_Iterator to + * perform the logic behind this container class. It delegates + * all of its calls to ACE_Double_Linked_List_Iterator. + */ +template +class ACE_DLList_Reverse_Iterator : public ACE_Double_Linked_List_Reverse_Iterator +{ + + friend class ACE_DLList; + friend class ACE_DLList_Node; + +public: + + // = Initialization method. + ACE_DLList_Reverse_Iterator (ACE_DLList &l); + + /** + * Retasks the iterator to iterate over a new + * Double_Linked_List. This allows clients to reuse an iterator + * without incurring the constructor overhead. If you do use this, + * be aware that if there are more than one reference to this + * iterator, the other "clients" may be very bothered when their + * iterator changes. + * @@ Here be dragons. Comments? + */ + void reset (ACE_DLList &l); + + // = Iteration methods. + /// Move forward by one element in the list. Returns 0 when all the + /// items in the list have been seen, else 1. + int advance (void); + + /// Pass back the {next_item} that hasn't been seen in the list. + /// Returns 0 when all items have been seen, else 1. + int next (T *&); + + /// @deprecated Delegates to ACE_Double_Linked_List_Iterator. + T *next (void) const; + + /// Removes the current item (i.e., {next}) from the list. + /// Note that DLList iterators do not support {advance_and_remove} + /// directly (defined in its base class) and you will need to + /// release the element returned by it. + int remove (void); + + /// Delegates to ACE_Double_Linked_List_Iterator. + void dump (void) const; + +private: + ACE_DLList *list_; +}; + +// Forward declaration. +template +class ACE_Fixed_Set; + +/** + * @class ACE_Fixed_Set_Iterator_Base + * + * @brief Implements a common base class for iterators for a unordered set. + */ +template +class ACE_Fixed_Set_Iterator_Base +{ +public: + // = Iteration methods. + + /// Pass back the {next_item} that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Move to the first element in the set. Returns 0 if the + /// set is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Initialization method. + ACE_Fixed_Set_Iterator_Base (ACE_Fixed_Set &s); + + /// Set we are iterating over. + ACE_Fixed_Set &s_; + + /// How far we've advanced over the set. + ssize_t next_; + + /// The number of non free items that the iterator had pointed at. + size_t iterated_items_; + + /// Dump the state of an object. + void dump_i (void) const; + + /// Pass back the {next_item} that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next_i (T *&next_item); +}; + +/** + * @class ACE_Fixed_Set_Iterator + * + * @brief Iterates through an unordered set. + * + * This implementation of an unordered set uses a fixed array. + * Allows deletions while iteration is occurring. + */ +template +class ACE_Fixed_Set_Iterator : public ACE_Fixed_Set_Iterator_Base +{ +public: + // = Initialization method. + ACE_Fixed_Set_Iterator (ACE_Fixed_Set &s); + + // = Iteration methods. + + /// Pass back the {next_item} that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Dump the state of an object. + void dump (void) const; + + /// Remove the item where the itearetor is located at. + /// Returns 1 if it removes a item, else 0. + /// Pass back the removed {item}. + int remove (T *&item); + + /// STL-like iterator dereference operator: returns a reference + /// to the node underneath the iterator. + T & operator* (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +/** + * @class ACE_Fixed_Set_Const_Iterator + * + * @brief Iterates through a const unordered set. + * + * This implementation of an unordered set uses a fixed array. + */ +template +class ACE_Fixed_Set_Const_Iterator : public ACE_Fixed_Set_Iterator_Base +{ +public: + // = Initialization method. + ACE_Fixed_Set_Const_Iterator (const ACE_Fixed_Set &s); + + // = Iteration methods. + + /// Pass back the {next_item} that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next (const T *&next_item); + + /// Dump the state of an object. + void dump (void) const; + + /// STL-like iterator dereference operator: returns a reference + /// to the node underneath the iterator. + const T & operator* (void) const ; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +/** + * @class ACE_Fixed_Set + * + * @brief Implement a simple unordered set of {T} with maximum {ACE_SIZE}. + * + * This implementation of an unordered set uses a fixed array. + * It does not allow duplicate members. The set provides linear insertion/deletion + * operations. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Fixed array + * - Duplicates allowed? + * No + * - Random access allowed? + * No + * - Search speed + * Linear + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * -# operator== + * + */ +template +class ACE_Fixed_Set +{ +public: + friend class ACE_Fixed_Set_Iterator_Base; + friend class ACE_Fixed_Set_Iterator; + friend class ACE_Fixed_Set_Const_Iterator; + + // Trait definitions. + typedef ACE_Fixed_Set_Iterator ITERATOR; + typedef ACE_Fixed_Set_Const_Iterator CONST_ITERATOR; + + // = Initialization and termination methods. + /// Default Constructor. + /** + * Creates an empy set + */ + ACE_Fixed_Set (void); + + /// Copy constructor. + /** + * Initializes a set to be a copy of the set parameter. + */ + ACE_Fixed_Set (const ACE_Fixed_Set &); + + /// Assignment operator. + /** + * Deep copy of one set to another. + */ + void operator= (const ACE_Fixed_Set &); + + /// Destructor. + /** + * Destroys a set. + */ + ~ACE_Fixed_Set (void); + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * Performs constant time check to determine if a set is empty. + */ + int is_empty (void) const; + + /// Returns 1 if the container is full, otherwise returns 0. + /** + * Performs a constant time check to see if the set is full. + */ + int is_full (void) const; + + // = Classic unordered set operations. + + ///Linear time insertion of an item unique to the set. + /** + * Insert @a new_item into the set (doesn't allow duplicates). + * Returns -1 if failures occur, 1 if item is already present, else + * 0. + */ + int insert (const T &new_item); + + ///Linear time removal operation of an item. + /** + * Remove first occurrence of {item} from the set. Returns 0 if + * it removes the item, -1 if it can't find the item, and -1 if a + * failure occurs. Removal doesn't reclaim memory for the @a item. + */ + int remove (const T &item); + + /// Finds if @a item occurs in the set. Returns 0 if finds, else -1. + /** + * Performs a linear find operation for the specified @a item. + */ + int find (const T &item) const; + + /// Size of the set. + /** + * Returns the current size of the set. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Holds the contents of the set. + struct + { + /// Item in the set. + T item_; + + /// Keeps track of whether this item is in use or not. + int is_free_; + } search_structure_[ACE_SIZE]; + + /// Current size of the set. + size_t cur_size_; + + /// Maximum size of the set. + size_t max_size_; +}; + +// Forward declaration. +template +class ACE_Bounded_Set; + +/** + * @class ACE_Bounded_Set_Iterator + * + * @brief Iterates through an unordered set. + * + * This implementation of an unordered set uses a Bounded array. + * Allows deletions while iteration is occurring. + */ +template +class ACE_Bounded_Set_Iterator +{ +public: + // = Initialization method. + ACE_Bounded_Set_Iterator (ACE_Bounded_Set &s); + + // = Iteration methods. + + /// Pass back the {next_item} that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Move to the first element in the set. Returns 0 if the + /// set is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Set we are iterating over. + ACE_Bounded_Set &s_; + + /// How far we've advanced over the set. + ssize_t next_; +}; + + +/** + * @class ACE_Bounded_Set + * + * @brief Implement a simple unordered set of {T} with maximum + * set at creation time. + * + * This implementation of an unordered set uses a Bounded array. + * This implementation does not allow duplicates. It provides + * linear insert/remove/find operations. Insertion/removal does not + * invalidate iterators, but caution should be taken to ensure + * expected behavior. Once initialized, the object has a maximum size + * which can only be increased by the assignment of another larger Bounded_Set. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Bounded array which can grow via assignment + * - Duplicates allowed? + * No + * - Random access allowed? + * No + * - Search speed + * Linear + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * -# operator== + * + */ +template +class ACE_Bounded_Set +{ +public: + friend class ACE_Bounded_Set_Iterator; + + // Trait definition. + typedef ACE_Bounded_Set_Iterator ITERATOR; + + enum + { + DEFAULT_SIZE = 10 + }; + + // = Initialization and termination methods. + /// Construct a Bounded_Set using the default size. + /** + * The default constructor initializes the Bounded_Set to a maximum size + * specified by the DEFAULT_SIZE. + */ + ACE_Bounded_Set (void); + + /// Construct a Bounded_Set with the provided sizeB. + /** + * Initialize the Bounded_Set to have a maximum size equal to the size + * parameter specified. + */ + ACE_Bounded_Set (size_t size); + + /// Construct a Bounded_Set that is a copy of the provides Bounded_Set. + /** + * Initialize the Bounded_Set to be a copy of the Bounded_Set parameter. + */ + ACE_Bounded_Set (const ACE_Bounded_Set &); + + /// Assignment operator. + /** + * The assignment will make a deep copy of the Bounded_Set provided. If the + * rhs has more elements than the capacity of the lhs, then the lhs will be + * deleted and reallocated to accomadate the larger number of elements. + */ + void operator= (const ACE_Bounded_Set &); + + /// Destructor + /** + * Clean up the underlying dynamically allocated memory that is used by + * the Bounded_Set. + */ + ~ACE_Bounded_Set (void); + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * A constant time check is performed to determine if the Bounded_Set is + * empty. + */ + int is_empty (void) const; + + /// Returns 1 if the container is full, otherwise returns 0. + /** + * Performs a constant time check to determine if the Bounded_Set is at + * capacity. + */ + int is_full (void) const; + + // = Classic unordered set operations. + + ///Inserts a new element unique to the set. + /** + * Insert @a new_item into the set (doesn't allow duplicates) in linear + * time. + * Returns -1 if failures occur, 1 if item is already present, else + * 0. + */ + int insert (const T &new_item); + + ///Finds the specified element and removes it from the set. + /** + * Remove first occurrence of @a item from the set. Returns 0 if it + * removes the item, -1 if it can't find the item, and -1 if a + * failure occurs. The linear remove operation does not reclaim the + * memory associated with the removed item. + */ + int remove (const T &item); + + /// Finds if @a item occurs in the set. Returns 0 if finds, else -1. + /** + * find preforms a linear search for {item} and returns 0 on successful + * find and -1 otherwise. + */ + int find (const T &item) const; + + /// Size of the set. + /** + * Returns a size_t representing the current size of the set. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + struct Search_Structure + { + /// Item in the set. + T item_; + + /// Keeps track of whether this item is in use or not. + int is_free_; + }; + + /// Holds the contents of the set. + Search_Structure *search_structure_; + + /// Current size of the set. + size_t cur_size_; + + /// Maximum size of the set. + size_t max_size_; +}; + +/** + * @class ACE_Ordered_MultiSet_Iterator + * + * @brief Implement a bidirectional iterator over an ordered multiset. + * This class template requires that < operator semantics be + * defined for the parameterized type {T}, but does not impose + * any restriction on how that ordering operator is implemented. + */ +template +class ACE_Ordered_MultiSet_Iterator +{ +public: + friend class ACE_Ordered_MultiSet; + + // = Initialization method. + ACE_Ordered_MultiSet_Iterator (ACE_Ordered_MultiSet &s); + + // = Iteration methods. + + /// Pass back the {next_item} that hasn't been seen in the ordered multiset. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item) const; + + /// Repositions the iterator at the first item in the ordered multiset + /// Returns 0 if the list is empty else 1. + int first (void); + + /// Repositions the iterator at the last item in the ordered multiset + /// Returns 0 if the list is empty else 1. + int last (void); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Move backward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int retreat (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Returns a reference to the internal element {this} is pointing to. + T& operator* (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /// Pointer to the current node in the iteration. + ACE_DNode *current_; + + /// Pointer to the set we're iterating over. + ACE_Ordered_MultiSet &set_; +}; + + +/** + * @class ACE_Ordered_MultiSet + * + * @brief Implement a simple ordered multiset of {T} of unbounded size + * that allows duplicates. This class template requires that < + * operator semantics be defined for the parameterized type {T}, but + * does not impose any restriction on how that ordering operator is + * implemented. The set is implemented as a linked list. + * + * + * Requirements and Performance Characteristics + * - Internal Structure + * Double linked list + * - Duplicates allowed? + * Yes + * - Random access allowed? + * No + * - Search speed + * Linear + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * Yes + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * -# operator== + * -# operator< + * + * + */ +template +class ACE_Ordered_MultiSet +{ +public: + friend class ACE_Ordered_MultiSet_Iterator; + + // Trait definition. + typedef ACE_Ordered_MultiSet_Iterator ITERATOR; + + // = Initialization and termination methods. + /// Constructor. Use user specified allocation strategy + /// if specified. + /** + * Initialize the set using the allocation strategy specified. If none, use the + * default strategy. + */ + ACE_Ordered_MultiSet (ACE_Allocator *the_allocator = 0); + + /// Copy constructor. + /** + * Initialize the set to be a copy of the provided set. + */ + ACE_Ordered_MultiSet (const ACE_Ordered_MultiSet &); + + /// Destructor. + /** + * Delete the nodes of the set. + */ + ~ACE_Ordered_MultiSet (void); + + /// Assignment operator. + /** + * Delete the nodes in lhs, and copy the nodes from the rhs. + */ + void operator= (const ACE_Ordered_MultiSet &); + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * Constant time check to determine if the set is empty. + */ + int is_empty (void) const; + + /// Size of the set. + /** + * Constant time check to determine the size of the set. + */ + size_t size (void) const; + + // = Classic unordered set operations. + + /// Insert @a new_item into the ordered multiset. + /// Returns -1 if failures occur, else 0. + /** + * Linear time, order preserving insert into the set beginning at the head. + */ + int insert (const T &new_item); + + ///Linear time insert beginning at the point specified by the provided iterator. + /** + * Insert @a new_item into the ordered multiset, starting its search at + * the node pointed to by the iterator, and if insertion was successful, + * updates the iterator to point to the newly inserted node. + * Returns -1 if failures occur, else 0. + */ + int insert (const T &new_item, ITERATOR &iter); + + /// Remove first occurrence of @a item from the set. Returns 0 if + /// it removes the item, -1 if it can't find the item. + /** + * Linear time search operation which removes the item from the set if found . + */ + int remove (const T &item); + + ///Linear find operation. + /** + * Finds first occurrence of @a item in the multiset, using the iterator's + * current position as a hint to improve performance. If find succeeds, + * it positions the iterator at that node and returns 0, or if it cannot + * locate the node, it leaves the iterator alone and just returns -1. + */ + int find (const T &item, ITERATOR &iter) const; + + /// Reset the ACE_Ordered_MultiSet to be empty. + /** + * Delete the nodes inside the set. + */ + void reset (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /** + * Insert @a item, starting its search at the position given, + * and if successful updates the passed pointer to point to + * the newly inserted item's node. + */ + int insert_from (const T &item, ACE_DNode *start_position, + ACE_DNode **new_position); + + /** + * Looks for first occurance of @a item in the ordered set, using the + * passed starting position as a hint: if there is such an instance, it + * updates the new_position pointer to point to this node and returns 0; + * if there is no such node, then if there is a node before where the + * item would have been, it updates the new_position pointer to point + * to this node and returns -1; if there is no such node, then if there + * is a node after where the item would have been, it updates the + * new_position pointer to point to this node (or 0 if there is no such + * node) and returns 1; + */ + int locate (const T &item, ACE_DNode *start_position, + ACE_DNode *&new_position) const; + + /// Delete all the nodes in the Set. + void delete_nodes (void); + + /// Copy nodes into this set. + void copy_nodes (const ACE_Ordered_MultiSet &); + + /// Head of the bilinked list of Nodes. + ACE_DNode *head_; + + /// Head of the bilinked list of Nodes. + ACE_DNode *tail_; + + /// Current size of the set. + size_t cur_size_; + + /// Allocation strategy of the set. + ACE_Allocator *allocator_; +}; + +// **************************************************************** + +/** + * @class ACE_Array + * + * @brief A dynamic array class. + * + * This class extends ACE_Array_Base, adding comparison operators. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Dynamic array + * - Duplicates allowed? + * Yes + * - Random access allowed? + * Yes + * - Search speed + * N/A + * - Insert/replace speed + * O(1) + * - Iterator still valid after change to container? + * - In general, yes. + * - If array size is changed during iteration, no. + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * -# operator!= + * + * @sa ACE_Array_Base. This class inherits its operations and requirements. + */ +template +class ACE_Array : public ACE_Array_Base +{ +public: + // Define a "trait" + typedef T TYPE; + + typedef ACE_Array_Iterator ITERATOR; + + // = Exceptions. + + // = Initialization and termination methods. + + /// Dynamically create an uninitialized array. + /** + * Initialize an empty array of the specified size using the provided + * allocation strategy. + */ + ACE_Array (size_t size = 0, + ACE_Allocator* alloc = 0); + + /// Dynamically initialize the entire array to the {default_value}. + /** + * Initialize an array the given size placing the default_value in each index. + */ + ACE_Array (size_t size, + const T &default_value, + ACE_Allocator* alloc = 0); + + ///Copy constructor. + /** + * The copy constructor performs initialization by making an exact + * copy of the contents of parameter {s}, i.e., *this == s will + * return true. + */ + ACE_Array (const ACE_Array &s); + + ///Assignment operator + /** + * Assignment operator performs an assignment by making an exact + * copy of the contents of parameter {s}, i.e., *this == s will + * return true. Note that if the {max_size_} of {array_} is >= than + * {s.max_size_} we can copy it without reallocating. However, if + * {max_size_} is < {s.max_size_} we must delete the {array_}, + * reallocate a new {array_}, and then copy the contents of {s}. + */ + void operator= (const ACE_Array &s); + + // = Compare operators + + ///Equality comparison operator. + /** + * Compare this array with {s} for equality. Two arrays are equal + * if their {size}'s are equal and all the elements from 0 .. {size} + * are equal. + */ + bool operator== (const ACE_Array &s) const; + + ///Inequality comparison operator. + /** + * Compare this array with {s} for inequality such that {*this} != + * {s} is always the complement of the boolean return value of + * {*this} == {s}. + */ + bool operator!= (const ACE_Array &s) const; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Containers_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Containers_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Containers_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CONTAINERS_T_H */ diff --git a/dep/ACE_wrappers/ace/Containers_T.inl b/dep/ACE_wrappers/ace/Containers_T.inl new file mode 100644 index 000000000..912c9df8b --- /dev/null +++ b/dep/ACE_wrappers/ace/Containers_T.inl @@ -0,0 +1,479 @@ +// -*- C++ -*- +// +// $Id: Containers_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE int +ACE_Bounded_Stack::is_empty (void) const +{ + ACE_TRACE ("ACE_Bounded_Stack::is_empty"); + return this->top_ == 0; +} + +template ACE_INLINE int +ACE_Bounded_Stack::is_full (void) const +{ + ACE_TRACE ("ACE_Bounded_Stack::is_full"); + return this->top_ >= this->size_; +} + +template ACE_INLINE int +ACE_Bounded_Stack::push (const T &new_item) +{ + ACE_TRACE ("ACE_Bounded_Stack::push"); + if (this->is_full () == 0) + { + this->stack_[this->top_++] = new_item; + return 0; + } + else + return -1; +} + +template ACE_INLINE int +ACE_Bounded_Stack::pop (T &item) +{ + ACE_TRACE ("ACE_Bounded_Stack::pop"); + if (this->is_empty () == 0) + { + item = this->stack_[--this->top_]; + return 0; + } + else + return -1; +} + +template ACE_INLINE int +ACE_Bounded_Stack::top (T &item) const +{ + ACE_TRACE ("ACE_Bounded_Stack::top"); + if (this->is_empty () == 0) + { + item = this->stack_[this->top_ - 1]; + return 0; + } + else + return -1; +} + +template ACE_INLINE size_t +ACE_Bounded_Stack::size (void) const +{ + return this->size_; +} + +//---------------------------------------- + +template ACE_INLINE int +ACE_Fixed_Stack::is_empty (void) const +{ + ACE_TRACE ("ACE_Fixed_Stack::is_empty"); + return this->top_ == 0; +} + +template ACE_INLINE int +ACE_Fixed_Stack::is_full (void) const +{ + ACE_TRACE ("ACE_Fixed_Stack::is_full"); + return this->top_ >= this->size_; +} + +template ACE_INLINE int +ACE_Fixed_Stack::push (const T &new_item) +{ + ACE_TRACE ("ACE_Fixed_Stack::push"); + if (this->is_full () == 0) + { + this->stack_[this->top_++] = new_item; + return 0; + } + else + return -1; +} + +template ACE_INLINE int +ACE_Fixed_Stack::pop (T &item) +{ + ACE_TRACE ("ACE_Fixed_Stack::pop"); + if (this->is_empty () == 0) + { + item = this->stack_[--this->top_]; + return 0; + } + else + return -1; +} + +template ACE_INLINE int +ACE_Fixed_Stack::top (T &item) const +{ + ACE_TRACE ("ACE_Fixed_Stack::top"); + if (this->is_empty () == 0) + { + item = this->stack_[this->top_ - 1]; + return 0; + } + else + return -1; +} + +template ACE_INLINE size_t +ACE_Fixed_Stack::size (void) const +{ + return this->size_; +} + +template ACE_INLINE int +ACE_Unbounded_Stack::is_empty (void) const +{ + // ACE_TRACE ("ACE_Unbounded_Stack::is_empty"); + return this->head_ == this->head_->next_; +} + +template ACE_INLINE int +ACE_Unbounded_Stack::top (T &item) const +{ + ACE_TRACE ("ACE_Unbounded_Stack::top"); + if (this->is_empty () == 0) + { + item = this->head_->next_->item_; + return 0; + } + else + return -1; +} + +template ACE_INLINE int +ACE_Unbounded_Stack::is_full (void) const +{ + ACE_TRACE ("ACE_Unbounded_Stack::is_full"); + return 0; // ??? +} + +template ACE_INLINE size_t +ACE_Unbounded_Stack::size (void) const +{ + return this->cur_size_; +} + +// --- + + +// --- + +template ACE_INLINE int +ACE_Fixed_Set::is_empty (void) const +{ + ACE_TRACE ("ACE_Fixed_Set::is_empty"); + return this->cur_size_ == 0; +} + +template ACE_INLINE int +ACE_Fixed_Set::is_full (void) const +{ + ACE_TRACE ("ACE_Fixed_Set::is_full"); + return this->cur_size_ == this->max_size_; +} + +// --- + +template ACE_INLINE int +ACE_Bounded_Set::is_empty (void) const +{ + ACE_TRACE ("ACE_Bounded_Set::is_empty"); + return this->cur_size_ == 0; +} + +template ACE_INLINE int +ACE_Bounded_Set::is_full (void) const +{ + ACE_TRACE ("ACE_Bounded_Set::is_full"); + return this->cur_size_ == this->max_size_; +} + +// -- + +template ACE_INLINE int +ACE_Ordered_MultiSet_Iterator::first (void) +{ + ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::first"); + current_ = set_.head_; + + return (current_ ? 1 : 0); +} + +template ACE_INLINE int +ACE_Ordered_MultiSet_Iterator::last (void) +{ + ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::last"); + current_ = set_.tail_; + + return (current_ ? 1 : 0); +} + +template ACE_INLINE int +ACE_Ordered_MultiSet_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::advance"); + + current_ = current_ ? current_->next_ : 0; + + return (current_ ? 1 : 0); +} + +template ACE_INLINE int +ACE_Ordered_MultiSet_Iterator::retreat (void) +{ + ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::retreat"); + + current_ = current_ ? current_->prev_ : 0; + + return (current_ ? 1 : 0); +} + +template ACE_INLINE int +ACE_Ordered_MultiSet_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::done"); + + return (current_ ? 0 : 1); +} + +template ACE_INLINE void +ACE_Ordered_MultiSet_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Ordered_MultiSet_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + + + +// -- + +template ACE_INLINE int +ACE_Ordered_MultiSet::is_empty (void) const +{ + ACE_TRACE ("ACE_Ordered_MultiSet::is_empty"); + return this->cur_size_ > 0 ? 0 : 1; +} + +template ACE_INLINE size_t +ACE_Ordered_MultiSet::size (void) const +{ +// ACE_TRACE ("ACE_Ordered_MultiSet::size"); + return this->cur_size_; +} + +// **************************************************************** + +template ACE_INLINE +ACE_Array::ACE_Array (size_t size, + ACE_Allocator *alloc) + : ACE_Array_Base (size, alloc) +{ +} + +template ACE_INLINE +ACE_Array::ACE_Array (size_t size, + const T &default_value, + ACE_Allocator *alloc) + : ACE_Array_Base (size, default_value, alloc) +{ +} + +// The copy constructor (performs initialization). + +template ACE_INLINE +ACE_Array::ACE_Array (const ACE_Array &s) + : ACE_Array_Base (s) +{ +} + +// Assignment operator (performs assignment). + +template ACE_INLINE void +ACE_Array::operator= (const ACE_Array &s) +{ + // Check for "self-assignment". + + if (this != &s) + this->ACE_Array_Base::operator= (s); +} + +// Compare this array with for inequality. + +template ACE_INLINE bool +ACE_Array::operator!= (const ACE_Array &s) const +{ + return !(*this == s); +} + +// **************************************************************** + + +// **************************************************************** + +template ACE_INLINE void +ACE_DLList::operator= (const ACE_DLList &l) +{ + *(ACE_DLList_Base *) this = l; +} + +template ACE_INLINE int +ACE_DLList::get (T *&item, size_t index) +{ + ACE_DLList_Node *node; + int result = ACE_DLList_Base::get (node, index); + if (result != -1) + item = (T *) node->item_; + return result; +} + +template ACE_INLINE void +ACE_DLList::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DLList_Base::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_INLINE int +ACE_DLList::remove (ACE_DLList_Node *n) +{ + int result = ACE_DLList_Base::remove (n); + ACE_DES_FREE (n, + this->allocator_->free, + ACE_DLList_Node); + return result; +} + +template ACE_INLINE +ACE_DLList::ACE_DLList (ACE_Allocator *alloc) + : ACE_DLList_Base (alloc) +{ +} + +template ACE_INLINE +ACE_DLList::ACE_DLList (const ACE_DLList &l) + : ACE_DLList_Base ((ACE_DLList &) l) +{ +} + +template ACE_INLINE +ACE_DLList::~ACE_DLList (void) +{ + while (this->delete_head ()) ; +} + +template ACE_INLINE int +ACE_DLList_Iterator::remove (void) +{ + ACE_DLList_Node *temp = this->ACE_Double_Linked_List_Iterator ::next (); + this->ACE_Double_Linked_List_Iterator ::advance (); + return list_->remove (temp); +} + +template ACE_INLINE +ACE_DLList_Iterator::ACE_DLList_Iterator (ACE_DLList &l) + : ACE_Double_Linked_List_Iterator ((ACE_DLList_Base &)l), + list_ (&l) +{ +} + +template ACE_INLINE void +ACE_DLList_Iterator::reset (ACE_DLList &l) +{ + list_ = &l; + this->ACE_Double_Linked_List_Iterator ::reset ((ACE_DLList_Base &)l); +} + +template ACE_INLINE int +ACE_DLList_Iterator::next (T *&ptr) +{ + ACE_DLList_Node *temp = + ACE_Double_Linked_List_Iterator ::next (); + if (temp) + ptr = (T *) temp->item_; + return temp ? 1 : 0; +} + +template ACE_INLINE T * +ACE_DLList_Iterator::next (void) const +{ + ACE_DLList_Node *temp = ACE_Double_Linked_List_Iterator ::next (); + return (T *) (temp ? temp->item_ : 0); +} + +template ACE_INLINE int +ACE_DLList_Iterator::advance (void) +{ + return this->ACE_Double_Linked_List_Iterator ::advance (); +} + +template ACE_INLINE void +ACE_DLList_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_Double_Linked_List_Iterator ::dump (); +#endif /* ACE_HAS_DUMP */ +} + + +template ACE_INLINE int +ACE_DLList_Reverse_Iterator::remove (void) +{ + ACE_DLList_Node *temp = ACE_Double_Linked_List_Reverse_Iterator ::next (); + this->ACE_Double_Linked_List_Reverse_Iterator ::advance (); + return list_->remove (temp); +} + +template ACE_INLINE +ACE_DLList_Reverse_Iterator::ACE_DLList_Reverse_Iterator (ACE_DLList &l) + : ACE_Double_Linked_List_Reverse_Iterator ((ACE_DLList_Base &)l), + list_ (&l) +{ +} + +template ACE_INLINE void +ACE_DLList_Reverse_Iterator::reset (ACE_DLList &l) +{ + list_ = &l; + this->ACE_Double_Linked_List_Reverse_Iterator ::reset ((ACE_DLList_Base &)l); +} + +template ACE_INLINE int +ACE_DLList_Reverse_Iterator::advance (void) +{ + return ACE_Double_Linked_List_Reverse_Iterator ::advance (); +} + +template ACE_INLINE int +ACE_DLList_Reverse_Iterator::next (T *&ptr) +{ + ACE_DLList_Node *temp = + ACE_Double_Linked_List_Reverse_Iterator ::next (); + if (temp == 0) + return 0; + ptr = (T *) temp->item_; + return 1; +} + +template ACE_INLINE T * +ACE_DLList_Reverse_Iterator::next (void) const +{ + ACE_DLList_Node *temp = ACE_Double_Linked_List_Reverse_Iterator ::next (); + return (T *) (temp ? temp->item_ : 0); +} + + +template ACE_INLINE void +ACE_DLList_Reverse_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_Double_Linked_List_Reverse_Iterator ::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Copy_Disabled.cpp b/dep/ACE_wrappers/ace/Copy_Disabled.cpp new file mode 100644 index 000000000..687831119 --- /dev/null +++ b/dep/ACE_wrappers/ace/Copy_Disabled.cpp @@ -0,0 +1,23 @@ +/** + * @file Copy_Disabled.cpp + * + * $Id: Copy_Disabled.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ + +#include "ace/Copy_Disabled.h" + + +ACE_RCSID (ace, + Copy_Disabled, + "$Id: Copy_Disabled.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Copy_Disabled::ACE_Copy_Disabled (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Copy_Disabled.h b/dep/ACE_wrappers/ace/Copy_Disabled.h new file mode 100644 index 000000000..f7b40e264 --- /dev/null +++ b/dep/ACE_wrappers/ace/Copy_Disabled.h @@ -0,0 +1,65 @@ +// -*- C++ -*- + +//=========================================================================== +/** + * @file Copy_Disabled.h + * + * $Id: Copy_Disabled.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//=========================================================================== + +#ifndef ACE_COPY_DISABLED_H +#define ACE_COPY_DISABLED_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Copy_Disabled + * + * @brief Helper class to disable copy construction and assignment + * + * Classes used to control OS and other resources are not "canonical", + * i.e. they have their copy constructor and assignment operators + * disabled. + * This is often done by making the copy constructor and assignment + * operators private, effectively disallowing copying by clients of + * the class (including derived classes). If the copy constructor and + * assingment operators are left unimplemented then the class itself + * cannot make any copies of its instances, because it would result in + * link errors. + * + * To use this class simply use private inheritance: + * + * class Foo : private ACE_Copy_Disabled + * { + * // code here + * }; + * + */ +class ACE_Export ACE_Copy_Disabled +{ +public: + + /// Default constructor + ACE_Copy_Disabled (void); + +private: + ACE_Copy_Disabled (const ACE_Copy_Disabled &); + ACE_Copy_Disabled &operator= (const ACE_Copy_Disabled &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_COPY_DISABLED_H */ diff --git a/dep/ACE_wrappers/ace/Countdown_Time.cpp b/dep/ACE_wrappers/ace/Countdown_Time.cpp new file mode 100644 index 000000000..dbb2ca55a --- /dev/null +++ b/dep/ACE_wrappers/ace/Countdown_Time.cpp @@ -0,0 +1,66 @@ +#include "ace/Countdown_Time.h" +#include "ace/OS_NS_sys_time.h" + +ACE_RCSID (ace, + Countdown_Time, + "$Id: Countdown_Time.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Countdown_Time::ACE_Countdown_Time (ACE_Time_Value *max_wait_time) + : max_wait_time_ (max_wait_time), + stopped_ (false) +{ + this->start (); +} + +ACE_Countdown_Time::~ACE_Countdown_Time (void) +{ + this->stop (); +} + +void +ACE_Countdown_Time::start (void) +{ + if (this->max_wait_time_ != 0) + { + this->start_time_ = ACE_OS::gettimeofday (); + this->stopped_ = false; + } +} + +bool +ACE_Countdown_Time::stopped (void) const +{ + return stopped_; +} + +void +ACE_Countdown_Time::stop (void) +{ + if (this->max_wait_time_ != 0 && this->stopped_ == false) + { + ACE_Time_Value elapsed_time = ACE_OS::gettimeofday () - this->start_time_; + + if (*this->max_wait_time_ > elapsed_time) + { + *this->max_wait_time_ -= elapsed_time; + } + else + { + // Used all of timeout. + *this->max_wait_time_ = ACE_Time_Value::zero; + // errno = ETIME; + } + this->stopped_ = true; + } +} + +void +ACE_Countdown_Time::update (void) +{ + this->stop (); + this->start (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Countdown_Time.h b/dep/ACE_wrappers/ace/Countdown_Time.h new file mode 100644 index 000000000..c12cfb108 --- /dev/null +++ b/dep/ACE_wrappers/ace/Countdown_Time.h @@ -0,0 +1,80 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Countdown_Time.h + * + * $Id: Countdown_Time.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_COUNTDOWN_TIME_H +#define ACE_COUNTDOWN_TIME_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Time_Value.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Countdown_Time + * + * @brief Keeps track of the amount of elapsed time. + * + * This class has a side-effect on the @c max_wait_time -- every + * time the stop() method is called the @c max_wait_time is + * updated. + */ +class ACE_Export ACE_Countdown_Time +{ +public: + /// Cache the @a max_wait_time and call @c start(). + ACE_Countdown_Time (ACE_Time_Value *max_wait_time); + + /// Destructor, makes sure the max_wait_time that got passed as pointer + /// to the constructor is updated with the time elapsed. + ~ACE_Countdown_Time (void); + + /// Cache the current time and enter a start state. + void start (void); + + /// Subtract the elapsed time from max_wait_time_ and enter a stopped + /// state. + void stop (void); + + /// Calls stop and then start. max_wait_time_ is modified by the + /// call to stop. + void update (void); + + /// Returns true if we've already been stopped, else false. + bool stopped (void) const; + +private: + /// Maximum time we were willing to wait. + ACE_Time_Value *max_wait_time_; + + /// Beginning of the start time. + ACE_Time_Value start_time_; + + /// Keeps track of whether we've already been stopped. + bool stopped_; + + // Prevent copying + ACE_Countdown_Time (const ACE_Countdown_Time &); + ACE_Countdown_Time &operator= (const ACE_Countdown_Time &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_COUNTDOWN_TIME_H */ diff --git a/dep/ACE_wrappers/ace/DEV.cpp b/dep/ACE_wrappers/ace/DEV.cpp new file mode 100644 index 000000000..42178a68e --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV.cpp @@ -0,0 +1,43 @@ +// $Id: DEV.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/DEV.h" + +#include "ace/OS_NS_unistd.h" + +#if !defined (__ACE_INLINE__) +#include "ace/DEV.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, DEV, "$Id: DEV.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV) + +void +ACE_DEV::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_DEV::dump"); +#endif /* ACE_HAS_DUMP */ +} + +// This is the do-nothing constructor. + +ACE_DEV::ACE_DEV (void) +{ + ACE_TRACE ("ACE_DEV::ACE_DEV"); +} + +// Close the device + +int +ACE_DEV::close (void) +{ + ACE_TRACE ("ACE_DEV::close"); + int result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV.h b/dep/ACE_wrappers/ace/DEV.h new file mode 100644 index 000000000..86f8d5dc8 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV.h @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file DEV.h + * + * $Id: DEV.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer + */ +//============================================================================= + + +#ifndef ACE_DEV_H +#define ACE_DEV_H +#include /**/ "ace/pre.h" + +#include "ace/IO_SAP.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/DEV_Addr.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_DEV_CONNECTOR ACE_DEV_Connector +#define ACE_DEV_STREAM ACE_DEV_IO +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_DEV_CONNECTOR ACE_DEV_Connector, ACE_DEV_Addr +#define ACE_DEV_STREAM ACE_DEV_IO, ACE_DEV_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_DEV + * + * @brief Defines the member functions for the base class of the + * ACE_DEV abstraction. + */ +class ACE_Export ACE_DEV : public ACE_IO_SAP +{ +public: + /// Close down the DEVICE + int close (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /** + * Disable signal @a signum + * This is here to prevent Win32 from + * disabling SPIPE using socket calls + */ + int disable (int signum) const ; + +protected: + /// Ensure that this class is an abstract base class + ACE_DEV (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/DEV.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DEV_H */ diff --git a/dep/ACE_wrappers/ace/DEV.inl b/dep/ACE_wrappers/ace/DEV.inl new file mode 100644 index 000000000..4d97a73d8 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV.inl @@ -0,0 +1,18 @@ +// -*- C++ -*- +// +// $Id: DEV.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_DEV::disable (int signum) const +{ +#if defined (ACE_WIN32) + ACE_UNUSED_ARG (signum) ; + return 0 ; +#else /* ACE_WIN32 */ + return ACE_IO_SAP::disable (signum) ; +#endif /* ACE_WIN32 */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV_Addr.cpp b/dep/ACE_wrappers/ace/DEV_Addr.cpp new file mode 100644 index 000000000..64bbb5087 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_Addr.cpp @@ -0,0 +1,108 @@ +// $Id: DEV_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/DEV_Addr.h" +#if !defined (__ACE_INLINE__) +#include "ace/DEV_Addr.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ace, + DEV_Addr, + "$Id: DEV_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV_Addr) + +// Transform the current address into string format. + +int +ACE_DEV_Addr::addr_to_string (ACE_TCHAR *s, size_t len) const +{ + ACE_TRACE ("ACE_DEV_Addr::addr_to_string"); + + ACE_OS::strsncpy (s, this->devname_, len); + return 0; +} + +// Return a pointer to the address. + +void * +ACE_DEV_Addr::get_addr (void) const +{ + ACE_TRACE ("ACE_DEV_Addr::get_addr"); + + return (void *) &this->devname_; +} + +void +ACE_DEV_Addr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_DEV_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("devname_ = %s"), this->devname_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Do nothing constructor. + +ACE_DEV_Addr::ACE_DEV_Addr (void) + : ACE_Addr (AF_DEV, sizeof this->devname_) +{ + ACE_TRACE ("ACE_DEV_Addr::ACE_DEV_Addr"); + + (void) ACE_OS::memset ((void *) &this->devname_, + 0, sizeof this->devname_); +} + +int +ACE_DEV_Addr::set (const ACE_DEV_Addr &sa) +{ + this->base_set (sa.get_type (), sa.get_size ()); + + if (sa.get_type () == AF_ANY) + (void) ACE_OS::memset ((void *) &this->devname_, + 0, + sizeof this->devname_); + else + (void) ACE_OS::strsncpy (this->devname_, + sa.devname_, + ACE_DEV_Addr::DEVNAME_LENGTH); + return 0; +} + +// Copy constructor. + +ACE_DEV_Addr::ACE_DEV_Addr (const ACE_DEV_Addr &sa) + : ACE_Addr (AF_DEV, sizeof this->devname_) +{ + ACE_TRACE ("ACE_DEV_Addr::ACE_DEV_Addr"); + + this->set (sa); +} + +ACE_DEV_Addr::ACE_DEV_Addr (const ACE_TCHAR *devname) + : ACE_Addr (AF_DEV, sizeof this->devname_) +{ + ACE_TRACE ("ACE_DEV_Addr::ACE_DEV_Addr"); + + this->set (devname); +} + +ACE_DEV_Addr & +ACE_DEV_Addr::operator= (const ACE_DEV_Addr &sa) +{ + ACE_TRACE ("ACE_DEV_Addr::operator="); + + if (this != &sa) + this->set (sa); + + return *this; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV_Addr.h b/dep/ACE_wrappers/ace/DEV_Addr.h new file mode 100644 index 000000000..49ec5023a --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_Addr.h @@ -0,0 +1,90 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file DEV_Addr.h + * + * $Id: DEV_Addr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer and Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_DEV_ADDR_H +#define ACE_DEV_ADDR_H + +#include /**/ "ace/pre.h" + +#include "ace/Addr.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_dirent.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_DEV_Addr + * + * @brief Defines device address family address format. + */ +class ACE_Export ACE_DEV_Addr : public ACE_Addr +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_DEV_Addr (void); + + /// Copy constructor. + ACE_DEV_Addr (const ACE_DEV_Addr &sa); + + /// Acts like a copy constructor. + int set (const ACE_DEV_Addr &sa); + + /// Create a ACE_DEV_Addr from a device name. + explicit ACE_DEV_Addr (const ACE_TCHAR *devname); + + /// Create a ACE_Addr from a ACE_DEV pathname. + void set (const ACE_TCHAR *devname); + + /// Assignment operator. + ACE_DEV_Addr &operator= (const ACE_DEV_Addr &); + + /// Return a pointer to the address. + virtual void *get_addr (void) const; + + /// Transform the current address into string format. + virtual int addr_to_string (ACE_TCHAR *addr, size_t) const; + + /// Compare two addresses for equality. + bool operator == (const ACE_DEV_Addr &SAP) const; + + /// Compare two addresses for inequality. + bool operator != (const ACE_DEV_Addr &SAP) const; + + /// Return the path name used for the rendezvous point. + const ACE_TCHAR *get_path_name (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + enum { DEVNAME_LENGTH = MAXPATHLEN + 1 }; + /// Name of the device. + ACE_TCHAR devname_[DEVNAME_LENGTH]; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/DEV_Addr.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_DEV_ADDR_H */ diff --git a/dep/ACE_wrappers/ace/DEV_Addr.inl b/dep/ACE_wrappers/ace/DEV_Addr.inl new file mode 100644 index 000000000..5c1da68d7 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_Addr.inl @@ -0,0 +1,51 @@ +// -*- C++ -*- +// +// $Id: DEV_Addr.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_string.h" +#include "ace/Global_Macros.h" +#include "ace/os_include/sys/os_socket.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_DEV_Addr::set (const ACE_TCHAR *devname) +{ + ACE_TRACE ("ACE_DEV_Addr::set"); + + this->ACE_Addr::base_set + (AF_DEV, static_cast (ACE_OS::strlen (devname))); + ACE_OS::strsncpy (this->devname_, devname, ACE_DEV_Addr::DEVNAME_LENGTH); +} + +// Compare two addresses for equality. + +ACE_INLINE bool +ACE_DEV_Addr::operator == (const ACE_DEV_Addr &sap) const +{ + ACE_TRACE ("ACE_DEV_Addr::operator =="); + + return ACE_OS::strcmp (this->devname_, sap.devname_) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE bool +ACE_DEV_Addr::operator != (const ACE_DEV_Addr &sap) const +{ + ACE_TRACE ("ACE_DEV_Addr::operator !="); + + return !((*this) == sap); // This is lazy, of course... ;-). +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE const ACE_TCHAR * +ACE_DEV_Addr::get_path_name (void) const +{ + ACE_TRACE ("ACE_DEV_Addr::get_path_name"); + + return this->devname_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV_Connector.cpp b/dep/ACE_wrappers/ace/DEV_Connector.cpp new file mode 100644 index 000000000..bdc2530ac --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_Connector.cpp @@ -0,0 +1,53 @@ +// $Id: DEV_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/DEV_Connector.h" + +#include "ace/Handle_Ops.h" + +#if !defined (__ACE_INLINE__) +#include "ace/DEV_Connector.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID (ace, + DEV_Connector, + "$Id: DEV_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV_Connector) + +void +ACE_DEV_Connector::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_DEV_Connector::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_DEV_Connector::ACE_DEV_Connector (void) +{ + ACE_TRACE ("ACE_DEV_Connector::ACE_DEV_Connector"); +} + +int +ACE_DEV_Connector::connect (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &, + int, + int flags, + int perms) +{ + ACE_TRACE ("ACE_DEV_Connector::connect"); + + ACE_HANDLE handle = ACE::handle_timed_open (timeout, + remote_sap.get_path_name (), + flags, perms); + new_io.set_handle (handle); + new_io.addr_ = remote_sap; // class copy. + return handle == ACE_INVALID_HANDLE ? -1 : 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV_Connector.h b/dep/ACE_wrappers/ace/DEV_Connector.h new file mode 100644 index 000000000..32a7223f4 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_Connector.h @@ -0,0 +1,110 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file DEV_Connector.h + * + * $Id: DEV_Connector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer and Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_DEV_CONNECTOR_H +#define ACE_DEV_CONNECTOR_H +#include /**/ "ace/pre.h" + +#include "ace/DEV_IO.h" +#include "ace/Log_Msg.h" +#include "ace/os_include/os_fcntl.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_DEV_Connector + * + * @brief Defines an active connection factory for the ACE_DEV wrappers. + */ +class ACE_Export ACE_DEV_Connector +{ +public: + /// Default constructor. + ACE_DEV_Connector (void); + + /** + * Actively connect and produce a @a new_io if things go well. + * The @a remote_sap is the address that we are trying to connect + * with. The @a timeout is the amount of time to wait to connect. + * If it's 0 then we block indefinitely. If *timeout == {0, 0} then + * the connection is done using non-blocking mode. In this case, if + * the connection can't be made immediately the value of -1 is + * returned with @c errno == EWOULDBLOCK. If *timeout > {0, 0} then + * this is the maximum amount of time to wait before timing out. If the + * time expires before the connection is made @c errno == ETIME. The + * @a local_sap is the value of local address to bind to. If it's + * the default value of ACE_Addr::sap_any then the user is letting + * the OS do the binding. If @a reuse_addr == 1 then the + * is reused, even if it hasn't been cleanedup yet. + * The @a flags and @a perms arguments are passed down to the + * method. + */ + ACE_DEV_Connector (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + + /** + * Actively connect and produce a @a new_io if things go well. + * The @a remote_sap is the address that we are trying to connect + * with. The @a timeout is the amount of time to wait to connect. + * If it's 0 then we block indefinitely. If *timeout == {0, 0} then + * the connection is done using non-blocking mode. In this case, if + * the connection can't be made immediately the value of -1 is + * returned with @c errno == EWOULDBLOCK. If *timeout > {0, 0} then + * this is the maximum amount of time to wait before timing out. If the + * time expires before the connection is made @c errno == ETIME. The + * @a local_sap is the value of local address to bind to. If it's + * the default value of ACE_Addr::sap_any then the user is letting + * the OS do the binding. If @a reuse_addr == 1 then the + * is reused, even if it hasn't been cleanedup yet. + * The @a flags and @a perms arguments are passed down to the + * method. + */ + int connect (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + + /// Resets any event associations on this handle + int reset_new_handle (ACE_HANDLE handle); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Meta-type info + typedef ACE_DEV_Addr PEER_ADDR; + typedef ACE_DEV_IO PEER_STREAM; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/DEV_Connector.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DEV_CONNECTOR_H */ diff --git a/dep/ACE_wrappers/ace/DEV_Connector.inl b/dep/ACE_wrappers/ace/DEV_Connector.inl new file mode 100644 index 000000000..924a42547 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_Connector.inl @@ -0,0 +1,34 @@ +// -*- C++ -*- +// +// $Id: DEV_Connector.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Creates a Local ACE_DEV. + +ACE_INLINE +ACE_DEV_Connector::ACE_DEV_Connector (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_DEV_Connector::ACE_DEV_Connector"); + if (this->connect (new_io, remote_sap, timeout, local_sap, + reuse_addr, flags, perms) == ACE_IO_SAP::INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME)) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("address %s, %p\n"), + remote_sap.get_path_name (), ACE_TEXT ("ACE_DEV_IO"))); +} + +ACE_INLINE int +ACE_DEV_Connector::reset_new_handle (ACE_HANDLE handle) +{ + ACE_UNUSED_ARG (handle); + // Nothing to do here since the handle is not a socket + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV_IO.cpp b/dep/ACE_wrappers/ace/DEV_IO.cpp new file mode 100644 index 000000000..b9a8e1f46 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_IO.cpp @@ -0,0 +1,131 @@ +// $Id: DEV_IO.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/DEV_IO.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/DEV_IO.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, DEV_IO, "$Id: DEV_IO.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV_IO) + +// Return the local endpoint address. + +int +ACE_DEV_IO::get_local_addr (ACE_DEV_Addr &addr) const +{ + ACE_TRACE ("ACE_DEV_IO::get_local_addr"); + + addr = this->addr_; + return 0; +} + +// Return the address of the remotely connected peer (if there is +// one). + +int +ACE_DEV_IO::get_remote_addr (ACE_DEV_Addr &addr) const +{ + ACE_TRACE ("ACE_DEV_IO::get_remote_addr"); + addr = this->addr_; + return 0; +} + +void +ACE_DEV_IO::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_DEV_IO::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->addr_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Simple-minded do nothing constructor. + +ACE_DEV_IO::ACE_DEV_IO (void) +{ + ACE_TRACE ("ACE_DEV_IO::ACE_DEV_IO"); +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_DEV_IO::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + va_list argp; + int total_tuples = static_cast (n / 2); + iovec *iovp; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (int i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + ssize_t result = ACE_OS::writev (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use the +// struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_DEV_IO::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + va_list argp; + int total_tuples = static_cast (n / 2); + iovec *iovp; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (int i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + ssize_t result = ACE_OS::readv (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DEV_IO.h b/dep/ACE_wrappers/ace/DEV_IO.h new file mode 100644 index 000000000..3b1c3deb3 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_IO.h @@ -0,0 +1,185 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file DEV_IO.h + * + * $Id: DEV_IO.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_DEV_IO_H +#define ACE_DEV_IO_H +#include /**/ "ace/pre.h" + +#include "ace/DEV.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_STREAM_PIPES) +# include "ace/OS_NS_stropts.h" +#endif /* ACE_HAS_STREAM_PIPES */ + +#include "ace/os_include/os_stdio.h" +#include "ace/os_include/sys/os_uio.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +/** + * @class ACE_DEV_IO + * + * @brief Read/Write operations on Devices. + */ +class ACE_Export ACE_DEV_IO : public ACE_DEV +{ +public: + friend class ACE_DEV_Connector; + + /// Default constructor. + ACE_DEV_IO (void); + + // = Various send operations. + /// send upto @a n bytes in @a buf. + ssize_t send (const void *buf, size_t n) const; + + /// Recv upto @a n bytes in @a buf. + ssize_t recv (void *buf, size_t n) const; + + /// Send n bytes, keep trying until n are sent. + ssize_t send_n (const void *buf, + size_t n) const; + + /** + * @name I/O operations + * + * Notes on common parameters: + * + * @a buf is the buffer to write from or receive into. + * + * @a len is the number of bytes to transfer. + * + * The @a timeout parameter in the following methods indicates how + * long to blocking trying to transfer data. If @a timeout == 0, + * then the call behaves as a normal send/recv call, i.e., for + * blocking sockets, the call will block until action is possible; + * for non-blocking sockets, EWOULDBLOCK will be returned if no + * action is immediately possible. + * + * If @a timeout != 0, the call will wait until the relative time + * specified in *@a timeout elapses. + * + * The "_n()" I/O methods keep looping until all the data has been + * transferred. These methods also work for sockets in non-blocking + * mode i.e., they keep looping on EWOULDBLOCK. @a timeout is used + * to make sure we keep making progress, i.e., the same timeout + * value is used for every I/O operation in the loop and the timeout + * is not counted down. + * + * The return values for the "*_n()" methods match the return values + * from the non "_n()" methods and are specified as follows: + * + * - On complete transfer, the number of bytes transferred is returned. + * - On timeout, -1 is returned, errno == ETIME. + * - On error, -1 is returned, errno is set to appropriate error. + * - On EOF, 0 is returned, errno is irrelevant. + * + * On partial transfers, i.e., if any data is transferred before + * timeout/error/EOF, @a bytes_transferred will contain the number of + * bytes transferred. + */ + ssize_t recv_n (void *buf, + size_t n, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0) const; + +#if defined (ACE_HAS_STREAM_PIPES) + /// Recv bytes via STREAM pipes using "band" mode. + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *band, + int *flags) const; + + /// Send bytes via STREAM pipes using "band" mode. + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int band, + int flags) const; + + /// Recv @a cntl and @a data via STREAM pipes. + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *flags) const; + + /// Send @a cntl and @a data via STREAM pipes. + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int flags = 0) const; +#endif /* ACE_HAS_STREAM_PIPES */ + + /// Send iovecs via <::writev>. + ssize_t send (const iovec iov[], size_t n) const; + + /// Recv iovecs via <::readv>. + ssize_t recv (iovec iov[], size_t n) const; + + /** + * Send N char *ptrs and int lengths. Note that the char *'s + * precede the ints (basically, an varargs version of writev). The + * count N is the *total* number of trailing arguments, *not* a + * couple of the number of tuple pairs! + */ + ssize_t send (size_t n, ...) const; + + /** + * This is an interface to ::readv, that doesn't use the struct + * iovec explicitly. The ... can be passed as an arbitrary number + * of (char *ptr, int len) tuples. However, the count N is the + * *total* number of trailing arguments, *not* a couple of the + * number of tuple pairs! + */ + ssize_t recv (size_t n, ...) const; + + /// Send @a n bytes via Win32 WriteFile using overlapped I/O. + ssize_t send (const void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + + /// Recv @a n bytes via Win32 ReadFile using overlapped I/O. + ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + + /// Dump the state of an object. + void dump (void) const; + + // = The following two methods are no-ops to keep the + // ACE_Connector happy. + /// Return the local endpoint address. + int get_local_addr (ACE_DEV_Addr &) const; + + /// Return the address of the remotely connected peer (if there is + /// one). + int get_remote_addr (ACE_DEV_Addr &) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Meta-type info + typedef ACE_DEV_Addr PEER_ADDR; + +private: + /// Address of device we are connected to. + ACE_DEV_Addr addr_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/DEV_IO.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DEV_IO_H */ diff --git a/dep/ACE_wrappers/ace/DEV_IO.inl b/dep/ACE_wrappers/ace/DEV_IO.inl new file mode 100644 index 000000000..796d24e11 --- /dev/null +++ b/dep/ACE_wrappers/ace/DEV_IO.inl @@ -0,0 +1,126 @@ +// -*- C++ -*- +// +// $Id: DEV_IO.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_sys_uio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_Memory.h" + +#include "ace/ACE.h" + +// Send exactly N bytes from BUF to this device. Keeping trying until +// this many bytes are sent. + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ssize_t +ACE_DEV_IO::send_n (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::send_n"); + return ACE::write_n (this->get_handle (), buf, n); +} + +// Receive exactly N bytes from this file into BUF. Keep trying until +// this many bytes are received. + +ACE_INLINE ssize_t +ACE_DEV_IO::recv_n (void *buf, + size_t n, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) const +{ + ACE_TRACE ("ACE_DEV_IO::recv_n"); +#if defined (ACE_WIN32) + ACE_UNUSED_ARG (timeout); + + return ACE::read_n (this->get_handle (), + buf, + n, + bytes_transferred); +#else + return ACE::recv_n (this->get_handle (), + buf, + n, + timeout, + bytes_transferred); +#endif /*ACE_WIN32*/ +} + +ACE_INLINE ssize_t +ACE_DEV_IO::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, n); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::send (const iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::writev (this->get_handle (), iov, static_cast (n)); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::recv (iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::readv (this->get_handle (), iov, static_cast (n)); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::send (const void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::write (this->get_handle (), + (const char *) buf, n, + overlapped); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::recv (void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n, + overlapped); +} + +#if defined (ACE_HAS_STREAM_PIPES) +ACE_INLINE ssize_t +ACE_DEV_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *band, int *flags) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::getpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int band, int flags) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::putpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *flags) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::getmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +ACE_INLINE ssize_t +ACE_DEV_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int flags) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::putmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} +#endif /* ACE_HAS_STREAM_PIPES */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DLL.cpp b/dep/ACE_wrappers/ace/DLL.cpp new file mode 100644 index 000000000..cad251100 --- /dev/null +++ b/dep/ACE_wrappers/ace/DLL.cpp @@ -0,0 +1,267 @@ +// $Id: DLL.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/DLL.h" + +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/DLL_Manager.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_dlfcn.h" +#include "ace/OS_NS_Thread.h" + +#include + +ACE_RCSID(ace, DLL, "$Id: DLL.cpp 80826 2008-03-04 14:51:23Z wotte $") + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Default constructor. Also, by default, the object will be closed +// before it is destroyed. + +ACE_DLL::ACE_DLL (bool close_handle_on_destruction) + : open_mode_ (0), + dll_name_ (0), + close_handle_on_destruction_ (close_handle_on_destruction), + dll_handle_ (0), + error_ (0) +{ + ACE_TRACE ("ACE_DLL::ACE_DLL (int)"); +} + +ACE_DLL::ACE_DLL (const ACE_DLL &rhs) + : open_mode_ (0), + dll_name_ (0), + close_handle_on_destruction_ (false), + dll_handle_ (0), + error_ (0) +{ + ACE_TRACE ("ACE_DLL::ACE_DLL (const ACE_DLL &)"); + + if (rhs.dll_name_ + // This will automatically up the refcount. + && this->open (rhs.dll_name_, + rhs.open_mode_, + rhs.close_handle_on_destruction_) != 0 + && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL::copy_ctor: error: %s\n"), + this->error ())); +} + +// Assignment operator + +ACE_DLL & +ACE_DLL::operator= (const ACE_DLL &rhs) +{ + ACE_TRACE ("ACE_DLL::operator= (const ACE_DLL &)"); + + ACE_DLL tmp (rhs); + + std::swap (this->open_mode_, tmp.open_mode_); + std::swap (this->dll_name_, tmp.dll_name_); + std::swap (this->close_handle_on_destruction_, + tmp.close_handle_on_destruction_); + std::swap (this->dll_handle_, tmp.dll_handle_); + std::swap (this->error_, tmp.error_); + + return *this; +} + + +// If the library name and the opening mode are specified than on +// object creation the library is implicitly opened. + +ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name, + int open_mode, + bool close_handle_on_destruction) + : open_mode_ (open_mode), + dll_name_ (0), + close_handle_on_destruction_ (close_handle_on_destruction), + dll_handle_ (0), + error_ (0) +{ + ACE_TRACE ("ACE_DLL::ACE_DLL"); + + if (this->open (dll_name, this->open_mode_, close_handle_on_destruction) != 0 + && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL::open: error calling open: %s\n"), + this->error ())); +} + +// The library is closed before the class gets destroyed depending on +// the close_handle_on_destruction value specified which is stored in +// close_handle_on_destruction_. + +ACE_DLL::~ACE_DLL (void) +{ + ACE_TRACE ("ACE_DLL::~ACE_DLL"); + + this->close (); + + // Normally delete()d in ACE_DLL::close(). However, that may not + // occur if full ACE_DLL initialization is interrupted due to errors + // (e.g. attempting to open a DSO/DLL that does not exist). Make + // sure this->dll_name_ is deallocated. + delete [] this->dll_name_; +} + +// This method opens the library based on the mode specified using the +// ACE_SHLIB_HANDLE which is obtained on making the ACE_OS::dlopen call. +// The default mode is: +// RTLD_LAZY Only references to data symbols are relocate when the +// object is first loaded. +// The other modes include: +// RTLD_NOW All necessary relocations are performed when the +// object is first loaded. +// RTLD_GLOBAL The object symbols are made available for the +// relocation processing of any other object. + +int +ACE_DLL::open (const ACE_TCHAR *dll_filename, + int open_mode, + bool close_handle_on_destruction) +{ + ACE_TRACE ("ACE_DLL::open"); + + return open_i (dll_filename, open_mode, close_handle_on_destruction); +} + +int +ACE_DLL::open_i (const ACE_TCHAR *dll_filename, + int open_mode, + bool close_handle_on_destruction, + ACE_SHLIB_HANDLE handle) +{ + ACE_TRACE ("ACE_DLL::open_i"); + + this->error_ = 0; + + if (!dll_filename) + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL::open_i: dll_name is %s\n"), + this->dll_name_ == 0 ? ACE_TEXT ("(null)") + : this->dll_name_)); + return -1; + } + + if (this->dll_handle_) + { + // If we have a good handle and its the same name, just return. + if (ACE_OS::strcmp (this->dll_name_, dll_filename) == 0) + return 0; + else + this->close (); + } + + if (!this->dll_name_) + this->dll_name_ = ACE::strnew (dll_filename); + + this->open_mode_ = open_mode; + this->close_handle_on_destruction_ = close_handle_on_destruction; + + this->dll_handle_ = ACE_DLL_Manager::instance()->open_dll (this->dll_name_, + this->open_mode_, + handle); + + if (!this->dll_handle_) + this->error_ = 1; + + return this->error_ ? -1 : 0; +} + +// The symbol refernce of the name specified is obtained. + +void * +ACE_DLL::symbol (const ACE_TCHAR *sym_name, int ignore_errors) +{ + ACE_TRACE ("ACE_DLL::symbol"); + + this->error_ = 0; + + void *sym = 0; + if (this->dll_handle_) + sym = this->dll_handle_->symbol (sym_name, ignore_errors); + + if (!sym) + this->error_ = 1; + + return sym; +} + +// The library is closed using the ACE_SHLIB_HANDLE object, i.e., the +// shared object is now disassociated form the current process. + +int +ACE_DLL::close (void) +{ + ACE_TRACE ("ACE_DLL::close"); + + int retval = 0; + + if (this->dll_handle_ + && this->close_handle_on_destruction_ + && this->dll_name_ + && (retval = ACE_DLL_Manager::instance ()->close_dll (this->dll_name_)) != 0) + this->error_ = 1; + + // Even if close_dll() failed, go ahead and cleanup. + this->dll_handle_ = 0; + delete [] this->dll_name_; + this->dll_name_ = 0; + this->close_handle_on_destruction_ = false; + + return retval; +} + +// This method is used return the last error of a library operation. + +ACE_TCHAR * +ACE_DLL::error (void) const +{ + ACE_TRACE ("ACE_DLL::error"); + if (this->error_) + { + return ACE_OS::dlerror (); + } + + return 0; +} + +// Return the handle to the user either temporarily or forever, thus +// orphaning it. If 0 means the user wants the handle forever and if 1 +// means the user temporarily wants to take the handle. + +ACE_SHLIB_HANDLE +ACE_DLL::get_handle (int become_owner) const +{ + ACE_TRACE ("ACE_DLL::get_handle"); + + ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE; + + if (this->dll_handle_) + handle = this->dll_handle_->get_handle (become_owner); + + return handle; +} + +// Set the handle for the DLL. By default, the object will be closed +// before it is destroyed. + +int +ACE_DLL::set_handle (ACE_SHLIB_HANDLE handle, + bool close_handle_on_destruction) +{ + ACE_TRACE ("ACE_DLL::set_handle"); + + // Create a unique name. Note that this name is only quaranteed + // to be unique for the life of this object. + ACE_TCHAR temp[ACE_UNIQUE_NAME_LEN]; + ACE_OS::unique_name (this, temp, ACE_UNIQUE_NAME_LEN); + + return this->open_i (temp, 1, close_handle_on_destruction, handle); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DLL.h b/dep/ACE_wrappers/ace/DLL.h new file mode 100644 index 000000000..fa748e8d9 --- /dev/null +++ b/dep/ACE_wrappers/ace/DLL.h @@ -0,0 +1,196 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file DLL.h + * + * $Id: DLL.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kirthika Parameswaran + */ +//============================================================================= + +#ifndef ACE_DLL_H +#define ACE_DLL_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/os_include/os_dlfcn.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_DLL_Handle; + +/** + * @class ACE_DLL + * + * @brief Provides an abstract interface for handling various DLL + * operations. + * + * This class is a wrapper over the various methods for utilizing + * a dynamically linked library (DLL), which is called a shared + * library on some platforms. Operations @c open(), @c close(), and + * @c symbol() have been implemented to help opening/closing and + * extracting symbol information from a DLL, respectively. + */ +class ACE_Export ACE_DLL +{ +public: + // = Initialization and termination methods. + + /** + * Default constructor. By default, the close() operation on the + * object will be invoked before it is destroyed. + * @param close_handle_on_destruction Indicates whether or not the + * close() method will be called to close an open DLL when this + * object is destroyed. By default, close() will be called. + * Set this parameter to 0 for situations where the DLL's lifetime + * is controlled in a scope other than that of this ACE_DLL object. + * For example, termination by ACE_DLL_Manager via ACE::fini(). + */ + explicit ACE_DLL (bool close_handle_on_destruction = true); + + /// Allow assignment + ACE_DLL& operator= (const ACE_DLL &rhs); + + + /** + * This constructor performs the actions of open() during construction. + * @param dll_name The name or path of the DLL to load. + * @param open_mode Flags to alter the actions taken when loading the DLL. + * The possible values are: + * @li @c RTLD_LAZY (this the default): loads identifier symbols but + * not the symbols for functions, which are loaded dynamically + * on-demand. + * @li @c RTLD_NOW: performs all necessary relocations when + * @a dll_name is first loaded + * @li RTLD_GLOBAL: makes symbols available for relocation + * processing of any other DLLs. + * @param close_handle_on_destruction Indicates whether or not the + * close() method will be called to close an open DLL when this + * object is destroyed. By default, close() will be called. + * Set this parameter to 0 for situations where the DLL's lifetime + * is controlled in a scope other than that of this ACE_DLL object. + * For example, termination by ACE_DLL_Manager via ACE::fini(). + */ + explicit ACE_DLL (const ACE_TCHAR *dll_name, + int open_mode = ACE_DEFAULT_SHLIB_MODE, + bool close_handle_on_destruction = true); + + /// Copy constructor. + ACE_DLL (const ACE_DLL &); + + /** + * This method opens and dynamically links a specified DLL. + * @param dll_name The filename or path of the DLL to load. + * If a filename is given to @c open(), the @c ACE::ldfind() is used + * to locate DLLs via the following algorithms: (1) DLL filename + * expansion: @c ACE::ldfind() determines the name of the DLL by + * adding the appropriate prefix and suffix, e.g., it adds the @c lib + * prefix and @c .so suffix for Solaris and the @c .dll suffix for + * Windows and (2) DLL search path: @c ACE::ldfind() will also search + * for the designated DLL using the platform's DLL search path + * environment variable, e.g., it searches for DLLs using @c + * LD_LIBRARY_PATH on many UNIX systems and @c PATH on Windows. + * @param open_mode Flags to alter the actions taken when loading the DLL. + * The possible values are: + * @li @c RTLD_LAZY (this the default): loads identifier symbols but + * not the symbols for functions, which are loaded dynamically + * on-demand. + * @li @c RTLD_NOW: performs all necessary relocations when + * @a dll_name is first loaded + * @li RTLD_GLOBAL: makes symbols available for relocation + * processing of any other DLLs. + * @param close_handle_on_destruction Indicates whether or not the + * close() method will be called to close an open DLL when this + * object is destroyed. By default, close() will be called. + * Set this parameter to 0 for situations where the DLL's lifetime + * is controlled in a scope other than that of this ACE_DLL object. + * For example, termination by ACE_DLL_Manager via ACE::fini(). + * @retval -1 On failure + * @retval 0 On success. + */ + int open (const ACE_TCHAR *dll_name, + int open_mode = ACE_DEFAULT_SHLIB_MODE, + bool close_handle_on_destruction = true); + + /// Call to close the DLL object. + int close (void); + + /** + * Called when the DLL object is destroyed -- invokes close() if the + * @a close_handle_on_destruction flag was set to non-zero in the + * constructor or open() method. + */ + ~ACE_DLL (void); + + /** + * Look up a named symbol in the DLL. DLL must be successfully opened + * before calling symbol(). + * @param symbol_name The symbol name to look up. + * @param ignore_errors If set to 1, allows you to probe a dll without + * generating error messages in the log. Handy for determining + * the capabilities of a library. + * @return Returns the value of @a symbol_name if it is a valid symbol + * in the DLL. Otherwise, returns 0. + */ + void *symbol (const ACE_TCHAR *symbol_name, int ignore_errors = 0); + + /// Returns a pointer to a string explaining that an error occured. You + /// will need to consult the error log for the actual error string + /// returned by the OS. + ACE_TCHAR *error (void) const; + + /** + * Return the handle to the caller. If @a become_owner is non-0 then + * caller assumes ownership of the handle and the ACE_DLL object + * won't call close() when it goes out of scope, even if + * is set. + */ + ACE_SHLIB_HANDLE get_handle (int become_owner = 0) const; + + /// Set the handle for the DLL object. By default, the close() + //operation on / the object will be invoked before it is destroyed. + int set_handle (ACE_SHLIB_HANDLE handle, + bool close_handle_on_destruction = true); + +private: + + int open_i (const ACE_TCHAR *dll_name, + int open_mode = ACE_DEFAULT_SHLIB_MODE, + bool close_handle_on_destruction = true, + ACE_SHLIB_HANDLE handle = 0); + + + //private: +public: + + /// Open mode. + int open_mode_; + + /// Keep track of the name of the loaded dll, so it can be used + /// to remove framework components, singletons that live in the dll, + /// prior to unloading the dll in the close() method. + ACE_TCHAR *dll_name_; + + /// This flag keeps track of whether we should close the handle + /// automatically when the object is destroyed. + bool close_handle_on_destruction_; + + ACE_DLL_Handle *dll_handle_; + + /// Flag to record if the last operation had an error. + bool error_; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_DLL_H */ diff --git a/dep/ACE_wrappers/ace/DLL_Manager.cpp b/dep/ACE_wrappers/ace/DLL_Manager.cpp new file mode 100644 index 000000000..90049a042 --- /dev/null +++ b/dep/ACE_wrappers/ace/DLL_Manager.cpp @@ -0,0 +1,787 @@ +// $Id: DLL_Manager.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/DLL_Manager.h" + +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/Framework_Component.h" + +#include "ace/Lib_Find.h" +#include "ace/Object_Manager.h" +#include "ace/SString.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Guard_T.h" +#include "ace/OS_NS_dlfcn.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ace, + DLL_Manager, + "DLL_Manager.cpp,v 4.23 2003/11/05 23:30:46 shuston Exp") + +/******************************************************************/ + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +sig_atomic_t ACE_DLL_Handle::open_called_ = 0; + +ACE_DLL_Handle::ACE_DLL_Handle (void) + : refcount_ (0), + dll_name_ (0), + handle_ (ACE_SHLIB_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_DLL_Handle::ACE_DLL_Handle"); +} + +ACE_DLL_Handle::~ACE_DLL_Handle (void) +{ + ACE_TRACE ("ACE_DLL_Handle::~ACE_DLL_Handle"); + this->close (1); + delete[] this->dll_name_; +} + +const ACE_TCHAR * +ACE_DLL_Handle::dll_name (void) const +{ + ACE_TRACE ("ACE_DLL_Handle::dll_name"); + return this->dll_name_; +} + +int +ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, + int open_mode, + ACE_SHLIB_HANDLE handle) +{ + ACE_TRACE ("ACE_DLL_Handle::open"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + if (this->dll_name_) + { + // Once dll_name_ has been set, it can't be changed.. + if (ACE_OS::strcmp (this->dll_name_, dll_name) != 0) + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) DLL_Handle::open: error, ") + ACE_TEXT ("tried to reopen %s with name %s\n"), + this->dll_name_, + dll_name)); + + return -1; + } + } + else + this->dll_name_ = ACE::strnew (dll_name); + + if (!this->open_called_) + this->open_called_ = 1; + + // If it hasn't been loaded yet, go ahead and do that now. + if (this->handle_ == ACE_SHLIB_INVALID_HANDLE) + { + if (handle) + this->handle_ = handle; + else + { + /* + ** Get the set of names to try loading. We need to do this to + ** properly support the ability for a user to specify a simple, + ** unadorned name (for example, "ACE") that will work across + ** platforms. We apply platform specifics to get a name that will + ** work (e.g. libACE, ACEd.dll, ACE.dll, etc.) We rely on the + ** underlying dlopen() implementation to "Do The Right Thing" in + ** terms of using relative paths, LD_LIBRARY_PATH, system security + ** rules, etc. except when ACE_MUST_HELP_DLOPEN_SEARCH_PATH is set. + ** If it is set, then ACE::ldfind() scans the configured path + ** looking for a match on the name and prefix/suffix applications. + ** NOTE: having ACE scan for a file and then pass a fully-qualified + ** pathname to dlopen() is a potential security hole; therefore, + ** do not use ACE_MUST_HELP_DLOPEN_SEARCH_PATH unless necessary + ** and only after considering the risks. + */ + ACE_Array dll_names; + dll_names.max_size (10); // Decent guess to avoid realloc later + +#if defined (ACE_MUST_HELP_DLOPEN_SEARCH_PATH) + // Find out where the library is + ACE_TCHAR dll_pathname[MAXPATHLEN + 1]; + + // Transform the pathname into the appropriate dynamic link library + // by searching the ACE_LD_SEARCH_PATH. + ACE::ldfind (dll_name, + dll_pathname, + (sizeof dll_pathname / sizeof (ACE_TCHAR))); + ACE_TString dll_str (dll_pathname); + dll_names.size (1); + dll_names.set (dll_str, 0); +#else + this->get_dll_names (dll_name, dll_names); +#endif + + ACE_Array_Iterator name_iter (dll_names); + ACE_TString *name = 0; + while (name_iter.next (name)) + { + // The ACE_SHLIB_HANDLE object is obtained. + this->handle_ = ACE_OS::dlopen (name->c_str (), + open_mode); + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ") + ACE_TEXT ("(\"%s\", 0x%x) -> %s: %s\n"), + name->c_str (), + open_mode, + ((this->handle_ != ACE_SHLIB_INVALID_HANDLE) + ? ACE_TEXT ("succeeded") + : ACE_TEXT ("failed")), + this->error()->c_str())); + } + + if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) // Good one? + break; + + // If errno is ENOENT we just skip over this one, + // anything else - like an undefined symbol, for + // instance must be flagged here or the next error will + // mask it. + // @TODO: If we've found our DLL _and_ it's + // broken, should we continue at all? + if ((errno != 0) && (errno != ENOENT) && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ") + ACE_TEXT ("(\'%s\') failed, errno=") + ACE_TEXT ("%d: %s\n"), + name->c_str (), + errno, + this->error ()->c_str ())); + +#if defined (AIX) + // AIX often puts the shared library file (most often named + // shr.o) inside an archive library. If this is an archive + // library name, then try appending [shr.o] and retry. + if (ACE_TString::npos != name->strstr (ACE_TEXT (".a"))) + { + ACE_TCHAR aix_pathname[MAXPATHLEN + 1]; + ACE_OS::strncpy (aix_pathname, + name->c_str (), + name->length ()); + aix_pathname[name->length ()] = '\0'; + ACE_OS::strcat (aix_pathname, ACE_TEXT ("(shr.o)")); + open_mode |= RTLD_MEMBER; + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ") + ACE_TEXT ("(\"%s\", 0x%x) -> %s: %s\n"), + aix_pathname, + open_mode, + ACE_TEXT ((this->handle_ != ACE_SHLIB_INVALID_HANDLE) + ? "succeeded" + : "failed"), + this->error()->c_str())); + } + + this->handle_ = ACE_OS::dlopen (aix_pathname, open_mode); + if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) + break; + + // If errno is ENOENT we just skip over this one, anything + // else - like an undefined symbol, for instance + // must be flagged here or the next error will mask it. + // + // @TODO: If we've found our DLL _and_ it's broken, + // should we continue at all? + if (ACE::debug () && (errno != 0) && (errno != ENOENT)) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ") + ACE_TEXT ("(\'%s\') failed, errno=") + ACE_TEXT ("%d: %s\n"), + name->c_str (), + errno, + this->error ()->c_str ())); + + } +#endif /* AIX */ + + name_iter.advance (); + } + + if (this->handle_ == ACE_SHLIB_INVALID_HANDLE) + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::open (\"%s\"): ") + ACE_TEXT ("Invalid handle error: %s\n"), + this->dll_name_, + this->error ()->c_str ())); + + return -1; + } + } + } + + ++this->refcount_; + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::open - %s (%d), refcount=%d\n"), + this->dll_name_, + this->handle_, + this->refcount_)); + return 0; +} + + +int +ACE_DLL_Handle::close (int unload) +{ + ACE_TRACE ("ACE_DLL_Handle::close"); + + int retval = 0; + ACE_SHLIB_HANDLE h = ACE_SHLIB_INVALID_HANDLE; + + // Only hold the lock until it comes time to dlclose() the DLL. Closing + // the DLL can cause further shutdowns as DLLs and their dependents are + // unloaded. + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + // Since we don't actually unload the dll as soon as the refcount + // reaches zero, we need to make sure we don't decrement it below + // zero. + if (this->refcount_ > 0) + --this->refcount_; + else + this->refcount_ = 0; + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::close - ") + ACE_TEXT ("%s (handle=%d, refcount=%d)\n"), + this->dll_name_, + this->handle_, + this->refcount_)); + + if (this->refcount_ == 0 && + this->handle_ != ACE_SHLIB_INVALID_HANDLE && + unload == 1) + { + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::close: ") + ACE_TEXT ("Unloading %s (handle=%d)\n"), + this->dll_name_, + this->handle_)); + + // First remove any associated Framework Components. + ACE_Framework_Repository *frPtr= ACE_Framework_Repository::instance (); + if (frPtr) + { + frPtr->remove_dll_components (this->dll_name_); + } + + h = this->handle_; + this->handle_ = ACE_SHLIB_INVALID_HANDLE; + } + } // Release lock_ here + + if (h != ACE_SHLIB_INVALID_HANDLE) + { + retval = ACE_OS::dlclose (h); + + if (retval != 0 && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::close - ") + ACE_TEXT ("Failed with: \"%s\".\n"), + this->error ()->c_str ())); + } + + return retval; +} + +sig_atomic_t +ACE_DLL_Handle::refcount (void) const +{ + return this->refcount_; +} + +void * +ACE_DLL_Handle::symbol (const ACE_TCHAR *sym_name, int ignore_errors) +{ + ACE_TRACE ("ACE_DLL_Handle::symbol"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + ACE_Auto_Array_Ptr auto_name (ACE::ldname (sym_name)); + // handle_ can be invalid especially when ACE_DLL_Handle resigned ownership + // BTW. Handle lifecycle management is a little crazy in ACE + if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) + { +#if defined (ACE_OPENVMS) + void *sym = ACE::ldsymbol (this->handle_, auto_name.get ()); +#else + void *sym = ACE_OS::dlsym (this->handle_, auto_name.get ()); +#endif + + // Linux says that the symbol could be null and that it isn't an + // error. So you should check the error message also, but since + // null symbols won't do us much good anyway, let's still report + // an error. + if (!sym && ignore_errors != 1) + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::symbol (\"%s\") ") + ACE_TEXT (" failed with \"%s\".\n"), + auto_name.get (), + this->error ()->c_str ())); + + return 0; + } + return sym; + } + return 0; +} + +ACE_SHLIB_HANDLE +ACE_DLL_Handle::get_handle (int become_owner) +{ + ACE_TRACE ("ACE_DLL_Handle::get_handle"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + if (this->refcount_ == 0 && become_owner != 0) + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) DLL_Handle::get_handle: ") + ACE_TEXT ("cannot become owner, refcount == 0.\n"))); + + return ACE_SHLIB_INVALID_HANDLE; + } + + ACE_SHLIB_HANDLE handle = this->handle_; + + if (become_owner != 0) + { + if (--this->refcount_ == 0) + this->handle_ = ACE_SHLIB_INVALID_HANDLE; + } + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) ACE_DLL_Handle::get_handle: ") + ACE_TEXT ("post call: handle %s, refcount %d\n"), + this->handle_ == ACE_SHLIB_INVALID_HANDLE ? + ACE_TEXT ("invalid") : ACE_TEXT ("valid"), + this->refcount_)); + + return handle; +} + +// This method is used return the last error of a library operation. + +auto_ptr +ACE_DLL_Handle::error (void) +{ + ACE_TRACE ("ACE_DLL_Handle::error"); + const ACE_TCHAR *error = ACE_OS::dlerror (); + auto_ptr str + (new ACE_TString (error ? error : ACE_TEXT ("no error"))); + return str; +} + +void +ACE_DLL_Handle::get_dll_names (const ACE_TCHAR *dll_name, + ACE_Array &try_names) +{ + // Build the array of DLL names to try on this platform by applying the + // proper prefixes and/or suffixes to the specified dll_name. + ACE_TString base (dll_name); + ACE_TString base_dir, base_file, base_suffix; + + // 1. Separate the dll_name into the dir part and the file part. We + // only decorate the file part to determine the names to try loading. + ACE_TString::size_type pos = base.rfind (ACE_DIRECTORY_SEPARATOR_CHAR); + if (pos != ACE_TString::npos) + { + base_dir = base.substr (0, pos + 1); + base_file = base.substr (pos + 1); + } + else + base_file = base; + + // 2. Locate the file suffix, if there is one. Move the '.' and the + // suffix to base_suffix. + if ((pos = base_file.rfind (ACE_TEXT ('.'))) != ACE_TString::npos) + { + base_suffix = base_file.substr (pos); + base_file = base_file.substr (0, pos); + } + + // 3. Build the combinations to try for this platform. + // Try these combinations: + // - name with decorator and platform's suffix appended (if not supplied) + // - name with platform's suffix appended (if not supplied) + // - name with platform's dll prefix (if it has one) and suffix + // - name with platform's dll prefix, decorator, and suffix. + // - name as originally given + // We first try to find the file using the decorator so that when a + // filename with and without decorator is used, we get the file with + // the same decorator as the ACE dll has and then as last resort + // the one without. For example with msvc, the debug build has a "d" + // decorator, but the release build has none and we really want to get + // the debug version of the library in a debug application instead + // of the release one. + // So we need room for 5 entries in try_names. + try_names.size (0); + if ((try_names.max_size () - try_names.size ()) < 5) + try_names.max_size (try_names.max_size () + 5); +#if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK) + ACE_TString decorator (ACE_LD_DECORATOR_STR); +#endif + ACE_TString suffix (ACE_DLL_SUFFIX); + ACE_TString prefix (ACE_DLL_PREFIX); + + for (size_t i = 0; i < 5 && try_names.size () < try_names.max_size (); ++i) + { + ACE_TString try_this; + size_t j = try_names.size (); + switch (i) + { + case 0: // Name + decorator + suffix + case 1: // Name + suffix + case 2: // Prefix + name + decorator + suffix + case 3: // Prefix + name + suffix + if ( + base_suffix.length () > 0 +#if !(defined(ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)) + || (i == 1 || i == 3) // No decorator desired; skip +#endif + ) + break; + try_this = base_dir; + if (i > 1) + try_this += prefix; + try_this += base_file; + if (base_suffix.length () > 0) + try_this += base_suffix; + else + { +#if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK) + try_this += decorator; +#endif + try_this += suffix; + } + break; + case 4: + try_this = dll_name; + break; + } + + if (try_this.length ()) + { + try_names.size (j + 1); + try_names.set (try_this, j); + } + } + return; +} + +/******************************************************************/ + +// Pointer to the Singleton instance. +ACE_DLL_Manager *ACE_DLL_Manager::instance_ = 0; + + +ACE_DLL_Manager * +ACE_DLL_Manager::instance (int size) +{ + ACE_TRACE ("ACE_DLL_Manager::instance"); + + if (ACE_DLL_Manager::instance_ == 0) + { + // Perform Double-Checked Locking Optimization. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + if (ACE_DLL_Manager::instance_ == 0) + { + ACE_NEW_RETURN (ACE_DLL_Manager::instance_, + ACE_DLL_Manager (size), + 0); + } + } + + return ACE_DLL_Manager::instance_; +} + +void +ACE_DLL_Manager::close_singleton (void) +{ + ACE_TRACE ("ACE_DLL_Manager::close_singleton"); + + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance ())); + + delete ACE_DLL_Manager::instance_; + ACE_DLL_Manager::instance_ = 0; +} + +ACE_DLL_Manager::ACE_DLL_Manager (int size) + : handle_vector_ (0), + current_size_ (0), + total_size_ (0), + unload_policy_ (ACE_DLL_UNLOAD_POLICY_PER_DLL) +{ + ACE_TRACE ("ACE_DLL_Manager::ACE_DLL_Manager"); + + if (this->open (size) != 0 && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL_Manager ctor failed to allocate ") + ACE_TEXT ("handle_vector_.\n"))); +} + +ACE_DLL_Manager::~ACE_DLL_Manager (void) +{ + ACE_TRACE ("ACE_DLL_Manager::~ACE_DLL_Manager"); + + if (this->close () != 0 && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL_Manager dtor failed to close ") + ACE_TEXT ("properly.\n"))); +} + +ACE_DLL_Handle * +ACE_DLL_Manager::open_dll (const ACE_TCHAR *dll_name, + int open_mode, + ACE_SHLIB_HANDLE handle) +{ + ACE_TRACE ("ACE_DLL_Manager::open_dll"); + + ACE_DLL_Handle *temp_handle = 0; + ACE_DLL_Handle *dll_handle = 0; + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + dll_handle = this->find_dll (dll_name); + if (!dll_handle) + { + if (this->current_size_ < this->total_size_) + { + ACE_NEW_RETURN (temp_handle, + ACE_DLL_Handle, + 0); + + dll_handle = temp_handle; + } + } + } + + if (dll_handle) + { + if (dll_handle->open (dll_name, open_mode, handle) != 0) + { + // Error while opening dll. Free temp handle + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL_Manager::open_dll: Could not ") + ACE_TEXT ("open dll %s.\n"), + dll_name)); + + delete temp_handle; + return 0; + } + + // Add the handle to the vector only if the dll is successfully + // opened. + if (temp_handle != 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + this->handle_vector_[this->current_size_] = dll_handle; + ++this->current_size_; + } + } + + return dll_handle; +} + +int +ACE_DLL_Manager::close_dll (const ACE_TCHAR *dll_name) +{ + ACE_TRACE ("ACE_DLL_Manager::close_dll"); + ACE_DLL_Handle *handle = 0; + + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + handle = this->find_dll (dll_name); + } + + if (handle) + { + return this->unload_dll (handle, 0); + } + + return -1; +} + +u_long +ACE_DLL_Manager::unload_policy (void) const +{ + ACE_TRACE ("ACE_DLL_Manager::unload_policy"); + return this->unload_policy_; +} + +void +ACE_DLL_Manager::unload_policy (u_long unload_policy) +{ + ACE_TRACE ("ACE_DLL_Manager::unload_policy"); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); + + u_long old_policy = this->unload_policy_; + this->unload_policy_ = unload_policy; + + // If going from LAZY to EAGER or from PER_DLL to PER_PROCESS|EAGER, + // call close(1) on all the ACE_DLL_Handle objects with refcount == 0 + // which will force those that are still loaded to be unloaded. + if (this->handle_vector_) + if (( ACE_BIT_ENABLED (old_policy, ACE_DLL_UNLOAD_POLICY_LAZY) && + ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_LAZY) ) || + ( ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_LAZY) && + ACE_BIT_ENABLED (old_policy, ACE_DLL_UNLOAD_POLICY_PER_DLL) && + ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_PER_DLL) )) + { + for (int i = this->current_size_ - 1; i >= 0; i--) + { + if (this->handle_vector_[i] && + this->handle_vector_[i]->refcount () == 0) + this->handle_vector_[i]->close (1); + } + } +} + +int +ACE_DLL_Manager::open (int size) +{ + ACE_TRACE ("ACE_DLL_Manager::open"); + + ACE_DLL_Handle **temp = 0; + + ACE_NEW_RETURN (temp, + ACE_DLL_Handle *[size], + -1); + + this->handle_vector_ = temp; + this->total_size_ = size; + return 0; +} + +int +ACE_DLL_Manager::close (void) +{ + ACE_TRACE ("ACE_DLL_Manager::close"); + + int force_close = 1; + + if (this->handle_vector_ != 0) + { + // Delete components in reverse order. + for (int i = this->current_size_ - 1; i >= 0; i--) + { + if (this->handle_vector_[i]) + { + ACE_DLL_Handle *s = + const_cast (this->handle_vector_[i]); + this->handle_vector_[i] = 0; + this->unload_dll (s, force_close); + delete s; + } + } + + delete [] this->handle_vector_; + this->handle_vector_ = 0; + this->current_size_ = 0; + } + return 0; +} + +ACE_DLL_Handle * +ACE_DLL_Manager::find_dll (const ACE_TCHAR *dll_name) const +{ + ACE_TRACE ("ACE_DLL_Manager::find_dll"); + + for (int i = 0; i < this->current_size_; i++) + if (this->handle_vector_[i] && + ACE_OS::strcmp (this->handle_vector_[i]->dll_name (), dll_name) == 0) + { + return this->handle_vector_[i]; + } + + return 0; +} + +int +ACE_DLL_Manager::unload_dll (ACE_DLL_Handle *dll_handle, int force_unload) +{ + ACE_TRACE ("ACE_DLL_Manager::unload_dll"); + + if (dll_handle) + { + int unload = force_unload; + if (unload == 0) + { + // apply strategy + if (ACE_BIT_DISABLED (this->unload_policy_, + ACE_DLL_UNLOAD_POLICY_PER_DLL)) + { + unload = ACE_BIT_DISABLED (this->unload_policy_, + ACE_DLL_UNLOAD_POLICY_LAZY); + } + else + { + // Declare the type of the symbol: + typedef int (*dll_unload_policy)(void); + + void * const unload_policy_ptr = + dll_handle->symbol (ACE_TEXT ("_get_dll_unload_policy"), 1); +#if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64)) + int const temp_p = + reinterpret_cast (unload_policy_ptr); +#else + intptr_t const temp_p = + reinterpret_cast (unload_policy_ptr); +#endif + + dll_unload_policy const the_policy = + reinterpret_cast (temp_p); + + if (the_policy != 0) + unload = ACE_BIT_DISABLED (the_policy (), + ACE_DLL_UNLOAD_POLICY_LAZY); + else + unload = ACE_BIT_DISABLED (this->unload_policy_, + ACE_DLL_UNLOAD_POLICY_LAZY); + } + } + + if (dll_handle->close (unload) != 0) + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL_Manager::unload error.\n"))); + + return -1; + } + } + else + { + if (ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_DLL_Manager::unload_dll called with ") + ACE_TEXT ("null pointer.\n"))); + + return -1; + } + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/DLL_Manager.h b/dep/ACE_wrappers/ace/DLL_Manager.h new file mode 100644 index 000000000..63b9ee04a --- /dev/null +++ b/dep/ACE_wrappers/ace/DLL_Manager.h @@ -0,0 +1,269 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file DLL_Manager.h + * + * $Id: DLL_Manager.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + */ +//============================================================================= + +#ifndef ACE_DLL_MANAGER_H +#define ACE_DLL_MANAGER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Auto_Ptr.h" +#include "ace/Containers_T.h" +#include "ace/SStringfwd.h" +#include "ace/os_include/os_dlfcn.h" + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +# include "ace/Thread_Mutex.h" +#endif /* ACE_MT_SAFE */ + +#define ACE_DEFAULT_DLL_MANAGER_SIZE 1024 + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_DLL_Handle + * + * @brief Provides an abstract interface for handling various DLL + * operations. + * + * This class is an wrapper over the various methods for utilizing a + * dynamically linked library (DLL), which is called a shared library + * on some platforms. It is refcounted and managed by + * ACE_DLL_Manager, so there will only be a single instance of this + * class for each dll loaded, no matter how many instances of ACE_DLL + * an application has open. Operations , , and + * have been implemented to help opening/closing and extracting symbol + * information from a DLL, respectively. + * + * Most of this class came from the original ACE_DLL class. ACE_DLL + * is now just an interface that passed all it's calls either directly + * or via ACE_DLL_Manager to this class for execution. + * + */ +class ACE_Export ACE_DLL_Handle +{ +public: + + /// Default construtor. + ACE_DLL_Handle (void); + + /// Destructor. + ~ACE_DLL_Handle (void); + + /// Returns the name of the shared library (without prefixes or suffixes). + const ACE_TCHAR *dll_name () const; + + /** + * This method opens and dynamically links @a dll_name. The default + * mode is , which loads identifier symbols but not the + * symbols for functions, which are loaded dynamically on-demand. + * Other supported modes include: , which performs all + * necessary relocations when @a dll_name is first loaded and + * , which makes symbols available for relocation + * processing of any other DLLs. Returns -1 on failure and 0 on + * success. + */ + int open (const ACE_TCHAR *dll_name, + int open_mode, + ACE_SHLIB_HANDLE handle); + + /// Call to close the DLL object. If unload = 0, it only decrements + /// the refcount, but if unload = 1, then it will actually unload + /// the library when the refcount == 0; + int close (int unload = 0); + + /// Return the current refcount. + sig_atomic_t refcount (void) const; + + /// If @a symbol_name is in the symbol table of the DLL a pointer to + /// the @a symbol_name is returned. Otherwise, returns 0. Set the + /// ignore_errors flag to supress logging errors if symbol_name isn't + /// found. This is nice if you just want to probe a dll to see what's + /// available, since missing functions in that case aren't really errors. + void *symbol (const ACE_TCHAR *symbol_name, int ignore_errors = 0); + + /** + * Return the handle to the caller. If @a become_owner is non-0 then + * caller assumes ownership of the handle so we decrement the retcount. + */ + ACE_SHLIB_HANDLE get_handle (int become_owner = 0); + +private: + + /// Returns a pointer to a string explaining why or + /// failed. This is used internal to print out the error to the log, + /// but since this object is shared, we can't store or return the error + /// to the caller. + auto_ptr error (void); + + // Builds array of DLL names to try to dlopen, based on platform + // and configured DLL prefixes/suffixes. + // Returns the array of names to try in try_names. + void get_dll_names (const ACE_TCHAR *dll_name, + ACE_Array &try_names); + + // Disallow copying and assignment since we don't handle them. + ACE_DLL_Handle (const ACE_DLL_Handle &); + void operator= (const ACE_DLL_Handle &); + +private: + + // Keep track of how many ACE_DLL objects have a reference to this + // dll. + sig_atomic_t refcount_; + + /// Name of the shared library. + ACE_TCHAR *dll_name_; + + /// Handle to the actual library loaded by the OS. + ACE_SHLIB_HANDLE handle_; + + /// Keeps track of whether or not open() has ever been called. This + /// helps get around problem on Linux, and perhaps other OS's, that + /// seg-fault if dlerror() is called before the ld library has been + /// initialized by a call to dlopen(). + static sig_atomic_t open_called_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Synchronization variable for the MT_SAFE Repository + ACE_Thread_Mutex lock_; +#endif /* ACE_MT_SAFE */ +}; + +class ACE_Framework_Repository; + +/** + * @class ACE_DLL_Manager + * + * @brief This class is a singleton and serves as a factory and + * repository for instances of ACE_DLL_Handle. + * + * This class is a singleton whose lifetime is managed by the + * ACE_Framework_Repository. Although it is normally meant to be + * used directly only by ACE_DLL, applications can call the unload_policy() + * methods in order get/set the the dll unload policy. Unload policies include + * per_process/per-dll and eager/lazy. Dlls can export set their own policy + * by using the ACE_DLL_UNLOAD_POLICY macro found in config-all.h. If a dll + * choses to set an unload policy, it will be used when the per-dll policy + * (the default) is in effect. If the per-dll policy is in effect and a dll + * has not chosen to set a policy, the current per-process policy will be + * used. + * + * The following policy macros are provided in config-all.h: + * + * ACE_DLL_UNLOAD_POLICY_PER_PROCESS - Per-process policy that unloads dlls + * eagerly. + * + * ACE_DLL_UNLOAD_POLICY_PER_DLL - Apply policy on a per-dll basis. If the + * dll doesn't use one of the macros below, the current per-process policy + * will be used. + * + * ACE_DLL_UNLOAD_POLICY_LAZY - Don't unload dll when refcount reaches + * zero, i.e., wait for either an explicit unload request or program exit. + * + * ACE_DLL_UNLOAD_POLICY_DEFAULT - Default policy allows dlls to control + * their own destinies, but will unload those that don't make a choice eagerly. + * + */ +class ACE_Export ACE_DLL_Manager +{ +public: + friend class ACE_Framework_Repository; + friend class ACE_Object_Manager; + + enum + { + DEFAULT_SIZE = ACE_DEFAULT_DLL_MANAGER_SIZE + }; + + /// Return a unique instance + static ACE_DLL_Manager *instance (int size = ACE_DLL_Manager::DEFAULT_SIZE); + + /// Factory for ACE_DLL_Handle objects. If one already exits, + /// its refcount is incremented. + ACE_DLL_Handle *open_dll (const ACE_TCHAR *dll_name, + int openmode, + ACE_SHLIB_HANDLE handle); + + /// Close the underlying dll. Decrements the refcount. + int close_dll (const ACE_TCHAR *dll_name); + + /// Returns the current per-process UNLOAD_POLICY. + u_long unload_policy (void) const; + + /// Set the per-process UNLOAD_POLICY. If the policy is changed from + /// LAZY to EAGER, then it will also unload any dlls with zero + /// refcounts. + void unload_policy (u_long unload_policy); + +protected: + + /// Default constructor. + ACE_DLL_Manager (int size = ACE_DLL_Manager::DEFAULT_SIZE); + + /// Destructor. + ~ACE_DLL_Manager (void); + + // Allocate handle_vector_. + int open (int size); + + // Close all open dlls and deallocate memory. + int close (void); + + // Find dll in handle_vector_. + ACE_DLL_Handle *find_dll (const ACE_TCHAR *dll_name) const; + + // Applies strategy for unloading dll. + int unload_dll (ACE_DLL_Handle *dll_handle, int force_unload = 0); + +private: + + /// Close the singleton instance. + static void close_singleton (void); + + // Disallow copying and assignment since we don't handle these. + ACE_DLL_Manager (const ACE_DLL_Manager &); + void operator= (const ACE_DLL_Manager &); + +private: + + /// Vector containing all loaded handle objects. + ACE_DLL_Handle **handle_vector_; + + /// Current number of handles. + int current_size_; + + /// Maximum number of handles. + int total_size_; + + /// Unload strategy. + u_long unload_policy_; + + /// Pointer to a process-wide ACE_DLL_Manager. + static ACE_DLL_Manager *instance_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Synchronization variable for the MT_SAFE Repository + ACE_Thread_Mutex lock_; +#endif /* ACE_MT_SAFE */ + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_DLL_MANAGER_H */ diff --git a/dep/ACE_wrappers/ace/Date_Time.cpp b/dep/ACE_wrappers/ace/Date_Time.cpp new file mode 100644 index 000000000..eff0f273f --- /dev/null +++ b/dep/ACE_wrappers/ace/Date_Time.cpp @@ -0,0 +1,10 @@ +// Date_Time.cpp +// $Id: Date_Time.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Date_Time.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Date_Time.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Date_Time, "$Id: Date_Time.cpp 80826 2008-03-04 14:51:23Z wotte $") diff --git a/dep/ACE_wrappers/ace/Date_Time.h b/dep/ACE_wrappers/ace/Date_Time.h new file mode 100644 index 000000000..a15d435ee --- /dev/null +++ b/dep/ACE_wrappers/ace/Date_Time.h @@ -0,0 +1,125 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Date_Time.h + * + * $Id: Date_Time.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Tim Harrison (harrison@cs.wustl.edu) (and he's darn proud of this ;-)) + * + */ +//========================================================================== + +#ifndef ACE_DATE_TIME_H +#define ACE_DATE_TIME_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +/** + * @class ACE_Date_Time + * + * @brief System independent representation of date and time. + */ +class ACE_Export ACE_Date_Time +{ +public: + /// Constructor initializes current time/date info. + ACE_Date_Time (void); + + /// Constructor initializes with the given ACE_Time_Value + explicit ACE_Date_Time (const ACE_Time_Value& timevalue); + + /// Constructor with init values, no check for validy + /// Set/get portions of ACE_Date_Time, no check for validity. + ACE_Date_Time (long day, + long month = 0, + long year = 0, + long hour = 0, + long minute = 0, + long second = 0, + long microsec = 0, + long wday = 0); + + /// Update to the current time/date. + void update (void); + + /// Update to the given ACE_Time_Value + void update (const ACE_Time_Value& timevalue); + + /// Get day. + long day (void) const; + + /// Set day. + void day (long day); + + /// Get month. + long month (void) const; + + /// Set month. + void month (long month); + + /// Get year. + long year (void) const; + + /// Set year. + void year (long year); + + /// Get hour. + long hour (void) const; + + /// Set hour. + void hour (long hour); + + /// Get minute. + long minute (void) const; + + /// Set minute. + void minute (long minute); + + /// Get second. + long second (void) const; + + /// Set second. + void second (long second); + + /// Get microsec. + long microsec (void) const; + + /// Set microsec. + void microsec (long microsec); + + /// Get weekday. + long weekday (void) const; + + /// Set weekday. + void weekday (long wday); + +private: + long day_; + long month_; + long year_; + long hour_; + long minute_; + long second_; + long microsec_; + long wday_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Date_Time.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DATE_TIME_H */ diff --git a/dep/ACE_wrappers/ace/Date_Time.inl b/dep/ACE_wrappers/ace/Date_Time.inl new file mode 100644 index 000000000..d34807d83 --- /dev/null +++ b/dep/ACE_wrappers/ace/Date_Time.inl @@ -0,0 +1,219 @@ +// -*- C++ -*- +// +// $Id: Date_Time.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Global_Macros.h" +#include "ace/Time_Value.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/OS_NS_time.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void +ACE_Date_Time::update (const ACE_Time_Value& timevalue) +{ +#if defined (ACE_HAS_WINCE) + // CE doesn't do localtime(). + FILETIME file_time = timevalue; + FILETIME local_file_time; + SYSTEMTIME sys_time; + ::FileTimeToLocalFileTime (&file_time, &local_file_time); + ::FileTimeToSystemTime (&local_file_time, &sys_time); + this->day_ = sys_time.wDay; + this->month_ = sys_time.wMonth; + this->year_ = sys_time.wYear; + this->hour_ = sys_time.wHour; + this->minute_ = sys_time.wMinute; + this->second_ = sys_time.wSecond; + this->microsec_ = sys_time.wMilliseconds * 1000; + this->wday_ = sys_time.wDayOfWeek; +#else + time_t time = timevalue.sec (); + struct tm tm_time; + ACE_OS::localtime_r (&time, &tm_time); + this->day_ = tm_time.tm_mday; + this->month_ = tm_time.tm_mon + 1; // localtime's months are 0-11 + this->year_ = tm_time.tm_year + 1900; // localtime reports years since 1900 + this->hour_ = tm_time.tm_hour; + this->minute_ = tm_time.tm_min; + this->second_ = tm_time.tm_sec; + this->microsec_ = timevalue.usec (); + this->wday_ = tm_time.tm_wday; +#endif /* ACE_HAS_WINCE */ +} + +ACE_INLINE void +ACE_Date_Time::update (void) +{ + ACE_TRACE ("ACE_Date_Time::update"); + + update(ACE_OS::gettimeofday ()); +} + +ACE_INLINE +ACE_Date_Time::ACE_Date_Time (void) +{ + ACE_TRACE ("ACE_Date_Time::ACE_Date_Time"); + this->update (); +} + +ACE_INLINE +ACE_Date_Time::ACE_Date_Time (const ACE_Time_Value& timevalue) +{ + ACE_TRACE ("ACE_Date_Time::ACE_Date_Time: timevalue"); + this->update (timevalue); +} + +// Constructor with init values, no check for validy +ACE_INLINE +ACE_Date_Time::ACE_Date_Time (long day, + long month, + long year, + long hour, + long minute, + long second, + long microsec, + long wday) + : day_ (day), + month_ (month), + year_ (year), + hour_ (hour), + minute_ (minute), + second_ (second), + microsec_ (microsec), + wday_ (wday) +{ + ACE_TRACE ("ACE_Date_Time::ACE_Date_Time"); +} + +// set/get portions of ACE_Date_Time, no check for validy + +// get day +ACE_INLINE long +ACE_Date_Time::day (void) const +{ + ACE_TRACE ("ACE_Date_Time::day"); + return day_; +} + +// set day +ACE_INLINE void +ACE_Date_Time::day (long day) +{ + ACE_TRACE ("ACE_Date_Time::day"); + day_ = day; +} + +// get month +ACE_INLINE long +ACE_Date_Time::month (void) const +{ + ACE_TRACE ("ACE_Date_Time::month"); + return month_; +} + +// set month +ACE_INLINE void +ACE_Date_Time::month (long month) +{ + ACE_TRACE ("ACE_Date_Time::month"); + month_ = month; +} + +// get year +ACE_INLINE long +ACE_Date_Time::year (void) const +{ + ACE_TRACE ("ACE_Date_Time::year"); + return year_; +} + +// set year +ACE_INLINE void +ACE_Date_Time::year (long year) +{ + ACE_TRACE ("ACE_Date_Time::year"); + year_ = year; +} + +// get hour +ACE_INLINE long +ACE_Date_Time::hour (void) const +{ + ACE_TRACE ("ACE_Date_Time::hour"); + return hour_; +} + +// set hour +ACE_INLINE void +ACE_Date_Time::hour (long hour) +{ + ACE_TRACE ("ACE_Date_Time::hour"); + hour_ = hour; +} + +// get minute +ACE_INLINE long +ACE_Date_Time::minute (void) const +{ + ACE_TRACE ("ACE_Date_Time::minute"); + return minute_; +} + +// set minute +ACE_INLINE void +ACE_Date_Time::minute (long minute) +{ + ACE_TRACE ("ACE_Date_Time::minute"); + minute_ = minute; +} + +// get second +ACE_INLINE long +ACE_Date_Time::second (void) const +{ + ACE_TRACE ("ACE_Date_Time::second"); + return second_; +} + +// set second +ACE_INLINE void +ACE_Date_Time::second (long second) +{ + ACE_TRACE ("ACE_Date_Time::second"); + second_ = second; +} + +// get microsec +ACE_INLINE long +ACE_Date_Time::microsec (void) const +{ + ACE_TRACE ("ACE_Date_Time::microsec"); + return microsec_; +} + +// set microsec +ACE_INLINE void +ACE_Date_Time::microsec (long microsec) +{ + ACE_TRACE ("ACE_Date_Time::microsec"); + microsec_ = microsec; +} + +// get wday +ACE_INLINE long +ACE_Date_Time::weekday (void) const +{ + ACE_TRACE ("ACE_Date_Time::weekday"); + return wday_; +} + +// set wday +ACE_INLINE void +ACE_Date_Time::weekday (long wday) +{ + ACE_TRACE ("ACE_Date_Time::weekday"); + wday_ = wday; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Default_Constants.h b/dep/ACE_wrappers/ace/Default_Constants.h new file mode 100644 index 000000000..13e99e917 --- /dev/null +++ b/dep/ACE_wrappers/ace/Default_Constants.h @@ -0,0 +1,573 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Default_Constants.h + * + * $Id: Default_Constants.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + * @author Jesper S. M|ller + * @author and a cast of thousands... + * + * This one is split from the famous OS.h + */ +//============================================================================= + +#ifndef ACE_DEFAULT_CONSTANTS_H +#define ACE_DEFAULT_CONSTANTS_H +#include /**/ "ace/pre.h" + +// Included just keep compilers that see #pragma dierctive first +// happy. +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Define the default constants for ACE. Many of these are used for +// the ACE tests and applications. You can change these values by +// defining the macros in your config.h file. +# if !defined (ACE_DEFAULT_CLOSE_ALL_HANDLES) +# define ACE_DEFAULT_CLOSE_ALL_HANDLES true +# endif /* ACE_DEFAULT_CLOSE_ALL_HANDLES */ + +// The maximum length for a fully qualified Internet name. +# if !defined(ACE_MAX_FULLY_QUALIFIED_NAME_LEN) +# define ACE_MAX_FULLY_QUALIFIED_NAME_LEN 256 +# endif /* ACE_MAX_FULLY_QUALIFIED_NAME_LEN */ + +#if !defined (ACE_DEFAULT_PAGEFILE_POOL_BASE) +#define ACE_DEFAULT_PAGEFILE_POOL_BASE (void *) 0 +#endif /* ACE_DEFAULT_PAGEFILE_POOL_BASE */ + +#if !defined (ACE_DEFAULT_PAGEFILE_POOL_SIZE) +#define ACE_DEFAULT_PAGEFILE_POOL_SIZE (size_t) 0x01000000 +#endif /* ACE_DEFAULT_PAGEFILE_POOL_SIZE */ + +#if !defined (ACE_DEFAULT_PAGEFILE_POOL_CHUNK) +#define ACE_DEFAULT_PAGEFILE_POOL_CHUNK (size_t) 0x00010000 +#endif /* ACE_DEFAULT_PAGEFILE_POOL_CHUNK */ + +#if !defined (ACE_DEFAULT_PAGEFILE_POOL_NAME) +#define ACE_DEFAULT_PAGEFILE_POOL_NAME ACE_TEXT ("Default_ACE_Pagefile_Memory_Pool") +#endif /* ACE_DEFAULT_PAGEFILE_POOL_NAME */ + +#if !defined (ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY) +#define ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY 0 +#endif /* ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY */ + +#if !defined (ACE_DEFAULT_SERVICE_REPOSITORY_SIZE) +#define ACE_DEFAULT_SERVICE_REPOSITORY_SIZE 1024 +#endif /* ACE_DEFAULT_SERVICE_REPOSITORY_SIZE */ + +#if !defined (ACE_REACTOR_NOTIFICATION_ARRAY_SIZE) +#define ACE_REACTOR_NOTIFICATION_ARRAY_SIZE 1024 +#endif /* ACE_REACTOR_NOTIFICATION_ARRAY_SIZE */ + +# if !defined (ACE_DEFAULT_TIMEOUT) +# define ACE_DEFAULT_TIMEOUT 5 +# endif /* ACE_DEFAULT_TIMEOUT */ + +# if !defined (ACE_DEFAULT_BACKLOG) +# define ACE_DEFAULT_BACKLOG 5 +# endif /* ACE_DEFAULT_BACKLOG */ + +# if !defined (ACE_DEFAULT_ASYNCH_BACKLOG) +# define ACE_DEFAULT_ASYNCH_BACKLOG 5 +# endif /* ACE_DEFAULT_ASYNCH_BACKLOG */ + +# if !defined (ACE_DEFAULT_THREADS) +# define ACE_DEFAULT_THREADS 1 +# endif /* ACE_DEFAULT_THREADS */ + +// The following 3 defines are used in the IP multicast and broadcast tests. +# if !defined (ACE_DEFAULT_BROADCAST_PORT) +# define ACE_DEFAULT_BROADCAST_PORT 20000 +# endif /* ACE_DEFAULT_BROADCAST_PORT */ + +# if !defined (ACE_DEFAULT_MULTICAST_PORT) +# define ACE_DEFAULT_MULTICAST_PORT 20001 +# endif /* ACE_DEFAULT_MULTICAST_PORT */ + +# if !defined (ACE_DEFAULT_MULTICAST_ADDR) +// This address MUST be within the range for host group addresses: +// 224.0.0.0 to 239.255.255.255. +# define ACE_DEFAULT_MULTICAST_ADDR "224.9.9.2" +# endif /* ACE_DEFAULT_MULTICAST_ADDR */ + +# if defined (ACE_HAS_IPV6) +# if !defined (ACE_DEFAULT_MULTICASTV6_ADDR) +// This address should be within the range for site-local addresses: +// ff05::0/16 . +# define ACE_DEFAULT_MULTICASTV6_ADDR "ff05:0::ff01:1" +# endif /* ACE_DEFAULT_MULTICASTV6_ADDR */ +# endif + +// Default port number for HTTP. +# if !defined (ACE_DEFAULT_HTTP_SERVER_PORT) +# define ACE_DEFAULT_HTTP_SERVER_PORT 80 +# endif /* ACE_DEFAULT_HTTP_SERVER_PORT */ + +// Used in many IPC_SAP tests +# if !defined (ACE_DEFAULT_SERVER_PORT) +# define ACE_DEFAULT_SERVER_PORT 20002 +# endif /* ACE_DEFAULT_SERVER_PORT */ + +# if !defined (ACE_DEFAULT_HTTP_PORT) +# define ACE_DEFAULT_HTTP_PORT 80 +# endif /* ACE_DEFAULT_HTTP_PORT */ + +# if !defined (ACE_DEFAULT_MAX_SOCKET_BUFSIZ) +# define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 65536 +# endif /* ACE_DEFAULT_MAX_SOCKET_BUFSIZ */ + +# if !defined (ACE_DEFAULT_SERVER_PORT_STR) +# define ACE_DEFAULT_SERVER_PORT_STR ACE_TEXT("20002") +# endif /* ACE_DEFAULT_SERVER_PORT_STR */ + +// Used for the Service_Directory test +# if !defined (ACE_DEFAULT_SERVICE_PORT) +# define ACE_DEFAULT_SERVICE_PORT 20003 +# endif /* ACE_DEFAULT_SERVICE_PORT */ + +// Used for the ACE_Thread_Spawn test +# if !defined (ACE_DEFAULT_THR_PORT ) +# define ACE_DEFAULT_THR_PORT 20004 +# endif /* ACE_DEFAULT_THR_PORT */ + +// Used for tests +# if !defined (ACE_DEFAULT_LOCAL_PORT) +# define ACE_DEFAULT_LOCAL_PORT 20005 +# endif /* ACE_DEFAULT_LOCAL_PORT */ + +// Used for Connector tests +# if !defined (ACE_DEFAULT_LOCAL_PORT_STR) +# define ACE_DEFAULT_LOCAL_PORT_STR "20005" +# endif /* ACE_DEFAULT_LOCAL_PORT_STR */ + +// Used for the name server. +# if !defined (ACE_DEFAULT_NAME_SERVER_PORT) +# define ACE_DEFAULT_NAME_SERVER_PORT 20006 +# endif /* ACE_DEFAULT_NAME_SERVER_PORT */ + +# if !defined (ACE_DEFAULT_NAME_SERVER_PORT_STR) +# define ACE_DEFAULT_NAME_SERVER_PORT_STR "20006" +# endif /* ACE_DEFAULT_NAME_SERVER_PORT_STR */ + +// Used for the token server. +# if !defined (ACE_DEFAULT_TOKEN_SERVER_PORT) +# define ACE_DEFAULT_TOKEN_SERVER_PORT 20007 +# endif /* ACE_DEFAULT_TOKEN_SERVER_PORT */ + +# if !defined (ACE_DEFAULT_TOKEN_SERVER_PORT_STR) +# define ACE_DEFAULT_TOKEN_SERVER_PORT_STR "20007" +# endif /* ACE_DEFAULT_TOKEN_SERVER_PORT_STR */ + +// Used for the logging server. +# if !defined (ACE_DEFAULT_LOGGING_SERVER_PORT) +# define ACE_DEFAULT_LOGGING_SERVER_PORT 20008 +# endif /* ACE_DEFAULT_LOGGING_SERVER_PORT */ + +# if !defined (ACE_DEFAULT_LOGGING_SERVER_PORT_STR) +# define ACE_DEFAULT_LOGGING_SERVER_PORT_STR "20008" +# endif /* ACE_DEFAULT_LOGGING_SERVER_PORT_STR */ + +// Used for the logging server. +# if !defined (ACE_DEFAULT_THR_LOGGING_SERVER_PORT) +# define ACE_DEFAULT_THR_LOGGING_SERVER_PORT 20008 +# endif /* ACE_DEFAULT_THR_LOGGING_SERVER_PORT */ + +# if !defined (ACE_DEFAULT_THR_LOGGING_SERVER_PORT_STR) +# define ACE_DEFAULT_THR_LOGGING_SERVER_PORT_STR "20008" +# endif /* ACE_DEFAULT_THR_LOGGING_SERVER_PORT_STR */ + +// Used for the time server. +# if !defined (ACE_DEFAULT_TIME_SERVER_PORT) +# define ACE_DEFAULT_TIME_SERVER_PORT 20009 +# endif /* ACE_DEFAULT_TIME_SERVER_PORT */ + +# if !defined (ACE_DEFAULT_TIME_SERVER_PORT_STR) +# define ACE_DEFAULT_TIME_SERVER_PORT_STR "20009" +# endif /* ACE_DEFAULT_TIME_SERVER_PORT_STR */ + +# if !defined (ACE_DEFAULT_TIME_SERVER_STR) +# define ACE_DEFAULT_TIME_SERVER_STR "ACE_TS_TIME" +# endif /* ACE_DEFAULT_TIME_SERVER_STR */ + +// Used by the FIFO tests and the Client_Logging_Handler netsvc. +# if !defined (ACE_DEFAULT_RENDEZVOUS) +# if defined (ACE_HAS_STREAM_PIPES) +# define ACE_DEFAULT_RENDEZVOUS ACE_TEXT("/tmp/fifo.ace") +# else +# define ACE_DEFAULT_RENDEZVOUS ACE_TEXT("localhost:20010") +# endif /* ACE_HAS_STREAM_PIPES */ +# endif /* ACE_DEFAULT_RENDEZVOUS */ + +// Used for the UNIX syslog logging interface to ACE_Log_Msg. +# ifndef ACE_DEFAULT_SYSLOG_FACILITY +# define ACE_DEFAULT_SYSLOG_FACILITY LOG_USER +# endif /* ACE_DEFAULT_SYSLOG_FACILITY */ + +# if !defined (ACE_DEFAULT_LOGGER_KEY) + +# if defined (ACE_HAS_STREAM_PIPES) +# define ACE_DEFAULT_LOGGER_KEY ACE_TEXT ("/tmp/server_daemon") +# else +# define ACE_DEFAULT_LOGGER_KEY ACE_TEXT ("localhost:20012") +# endif /* ACE_HAS_STREAM_PIPES */ +# endif /* ACE_DEFAULT_LOGGER_KEY */ + +// The way to specify the local host for loopback IP. This is usually +// "localhost" but it may need changing on some platforms. +# if !defined (ACE_LOCALHOST) +# define ACE_LOCALHOST ACE_TEXT ("localhost") +# endif + +// This specification for an IPv6 localhost should work on all platforms +// supporting IPv6 +# if defined (ACE_HAS_IPV6) +# if !defined (ACE_IPV6_LOCALHOST) +# define ACE_IPV6_LOCALHOST ACE_TEXT ("::1") +# endif /* ACE_IPV6_LOCALHOST*/ +#endif /* ACE_HAS_IPV6 */ + +// This specification for an IPv6 ANY address should work on all platforms +// supporting IPv6 +# if defined (ACE_HAS_IPV6) +# if !defined (ACE_IPV6_ANY) +# define ACE_IPV6_ANY ACE_TEXT ("::") +# endif /* ACE_IPV6_ANY*/ +#endif /* ACE_HAS_IPV6 */ + +# if !defined (ACE_DEFAULT_SERVER_HOST) +# if defined (ACE_HAS_IPV6) +# define ACE_DEFAULT_SERVER_HOST ACE_IPV6_LOCALHOST +# else /*ACE_HAS_IPV6*/ +# define ACE_DEFAULT_SERVER_HOST ACE_LOCALHOST +# endif /*ACE_HAS_IPV6*/ +# endif /* ACE_DEFAULT_SERVER_HOST */ + +// Default shared memory key +# if !defined (ACE_DEFAULT_SHM_KEY) +# define ACE_DEFAULT_SHM_KEY 1234 +# endif /* ACE_DEFAULT_SHM_KEY */ + +// Default address for shared memory mapped files and SYSV shared memory +// (defaults to 64 M). +# if !defined (ACE_DEFAULT_BASE_ADDR) +# define ACE_DEFAULT_BASE_ADDR ((char *) (64 * 1024 * 1024)) +# endif /* ACE_DEFAULT_BASE_ADDR */ + +// Default segment size used by SYSV shared memory (128 K) +# if !defined (ACE_DEFAULT_SEGMENT_SIZE) +# define ACE_DEFAULT_SEGMENT_SIZE 1024 * 128 +# endif /* ACE_DEFAULT_SEGMENT_SIZE */ + +// Maximum number of SYSV shared memory segments +// (does anyone know how to figure out the right values?!) +# if !defined (ACE_DEFAULT_MAX_SEGMENTS) +# define ACE_DEFAULT_MAX_SEGMENTS 6 +# endif /* ACE_DEFAULT_MAX_SEGMENTS */ + +// Name of the map that's stored in shared memory. +# if !defined (ACE_NAME_SERVER_MAP) +# define ACE_NAME_SERVER_MAP "Name Server Map" +# endif /* ACE_NAME_SERVER_MAP */ + +// Default file permissions. +# if !defined (ACE_DEFAULT_FILE_PERMS) +# if defined (ACE_VXWORKS) +# define ACE_DEFAULT_FILE_PERMS (S_IRUSR | S_IWUSR| S_IRGRP| S_IROTH) +# else +# define ACE_DEFAULT_FILE_PERMS 0644 +# endif /* ACE_VXWORKS */ +# endif /* ACE_DEFAULT_FILE_PERMS */ + +// Default directory permissions. +# if !defined (ACE_DEFAULT_DIR_PERMS) +# define ACE_DEFAULT_DIR_PERMS 0755 +# endif /* ACE_DEFAULT_DIR_PERMS */ + +# if !defined (ACE_DEFAULT_TIMEPROBE_TABLE_SIZE) +# define ACE_DEFAULT_TIMEPROBE_TABLE_SIZE 8 * 1024 +# endif /* ACE_DEFAULT_TIMEPROBE_TABLE_SIZE */ + +// Default size of the ACE Map_Manager. +# if !defined (ACE_DEFAULT_MAP_SIZE) +# define ACE_DEFAULT_MAP_SIZE 1024 +# endif /* ACE_DEFAULT_MAP_SIZE */ + +// Defaults for ACE Timer Wheel +# if !defined (ACE_DEFAULT_TIMER_WHEEL_SIZE) +# define ACE_DEFAULT_TIMER_WHEEL_SIZE 1024 +# endif /* ACE_DEFAULT_TIMER_WHEEL_SIZE */ + +# if !defined (ACE_DEFAULT_TIMER_WHEEL_RESOLUTION) +# define ACE_DEFAULT_TIMER_WHEEL_RESOLUTION 100 +# endif /* ACE_DEFAULT_TIMER_WHEEL_RESOLUTION */ + +// Default size for ACE Timer Hash table +# if !defined (ACE_DEFAULT_TIMER_HASH_TABLE_SIZE) +# define ACE_DEFAULT_TIMER_HASH_TABLE_SIZE 1024 +# endif /* ACE_DEFAULT_TIMER_HASH_TABLE_SIZE */ + +// Defaults for the ACE Free List +# if !defined (ACE_DEFAULT_FREE_LIST_PREALLOC) +# define ACE_DEFAULT_FREE_LIST_PREALLOC 0 +# endif /* ACE_DEFAULT_FREE_LIST_PREALLOC */ + +# if !defined (ACE_DEFAULT_FREE_LIST_LWM) +# define ACE_DEFAULT_FREE_LIST_LWM 0 +# endif /* ACE_DEFAULT_FREE_LIST_LWM */ + +# if !defined (ACE_DEFAULT_FREE_LIST_HWM) +# define ACE_DEFAULT_FREE_LIST_HWM 25000 +# endif /* ACE_DEFAULT_FREE_LIST_HWM */ + +# if !defined (ACE_DEFAULT_FREE_LIST_INC) +# define ACE_DEFAULT_FREE_LIST_INC 100 +# endif /* ACE_DEFAULT_FREE_LIST_INC */ + +# if !defined (ACE_UNIQUE_NAME_LEN) +# define ACE_UNIQUE_NAME_LEN 100 +# endif /* ACE_UNIQUE_NAME_LEN */ + +# if !defined (ACE_MAX_DGRAM_SIZE) + // This is just a guess. 8k is the normal limit on + // most machines because that's what NFS expects. +# define ACE_MAX_DGRAM_SIZE 8192 +# endif /* ACE_MAX_DGRAM_SIZE */ + +# if !defined (ACE_DEFAULT_ARGV_BUFSIZ) +# define ACE_DEFAULT_ARGV_BUFSIZ 1024 * 4 +# endif /* ACE_DEFAULT_ARGV_BUFSIZ */ + +// A free list which create more elements when there aren't enough +// elements. +# define ACE_FREE_LIST_WITH_POOL 1 + +// A simple free list which doen't allocate/deallocate elements. +# define ACE_PURE_FREE_LIST 2 + +# if defined (ACE_WIN32) + +// This is necessary to work around bugs with Win32 non-blocking +// connects... +# if !defined (ACE_NON_BLOCKING_BUG_DELAY) +# define ACE_NON_BLOCKING_BUG_DELAY 35000 +# endif /* ACE_NON_BLOCKING_BUG_DELAY */ +# endif /*ACE_WIN32*/ + +// Max size of an ACE Log Record data buffer. This can be reset in +// the config.h file if you'd like to increase or decrease the size. +# if !defined (ACE_MAXLOGMSGLEN) +# define ACE_MAXLOGMSGLEN 4 * 1024 +# endif /* ACE_MAXLOGMSGLEN */ + +// Max size of an ACE Token. +# define ACE_MAXTOKENNAMELEN 40 + +// Max size of an ACE Token client ID. +# define ACE_MAXCLIENTIDLEN MAXHOSTNAMELEN + 20 + +/// Max udp packet size +#if !defined (ACE_MAX_UDP_PACKET_SIZE) +#define ACE_MAX_UDP_PACKET_SIZE 65536 +#endif + +/** + * @name Default values to control CDR classes memory allocation strategies + */ +//@{ + +/// Control the initial size of all CDR buffers, application +/// developers may want to optimize this value to fit their request +/// size +#if !defined (ACE_DEFAULT_CDR_BUFSIZE) +# define ACE_DEFAULT_CDR_BUFSIZE 512 +#endif /* ACE_DEFAULT_CDR_BUFSIZE */ + +#if (ACE_DEFAULT_CDR_BUFSIZE == 0) +# error: ACE_DEFAULT_CDR_BUFSIZE should be bigger then 0 +#endif + +/// Stop exponential growth of CDR buffers to avoid overallocation +#if !defined (ACE_DEFAULT_CDR_EXP_GROWTH_MAX) +# define ACE_DEFAULT_CDR_EXP_GROWTH_MAX 65536 +#endif /* ACE_DEFAULT_CDR_EXP_GROWTH_MAX */ + +/// Control CDR buffer growth after maximum exponential growth is +/// reached +#if !defined (ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK) +# define ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK 65536 +#endif /* ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK */ +//@} + +/// Control the zero-copy optimizations for octet sequences +/** + * Large octet sequences can be sent without any copies by chaining + * them in the list of message blocks that represent a single CDR + * stream. However, if the octet sequence is too small the zero copy + * optimizations actually hurt performance. Octet sequences smaller + * than this value will be copied. + */ +#if !defined (ACE_DEFAULT_CDR_MEMCPY_TRADEOFF) +#define ACE_DEFAULT_CDR_MEMCPY_TRADEOFF 256 +#endif /* ACE_DEFAULT_CDR_MEMCPY_TRADEOFF */ + +#if defined (ACE_WIN32) + // Define the pathname separator characters for Win32 (ugh). +# define ACE_DIRECTORY_SEPARATOR_STR_A "\\" +# define ACE_DIRECTORY_SEPARATOR_CHAR_A '\\' +#else + // Define the pathname separator characters for UNIX. +# define ACE_DIRECTORY_SEPARATOR_STR_A "/" +# define ACE_DIRECTORY_SEPARATOR_CHAR_A '/' +#endif /* ACE_WIN32 */ + +// Define the Wide character and normal versions of some of the string macros +#if defined (ACE_HAS_WCHAR) +# define ACE_DIRECTORY_SEPARATOR_STR_W ACE_TEXT_WIDE(ACE_DIRECTORY_SEPARATOR_STR_A) +# define ACE_DIRECTORY_SEPARATOR_CHAR_W ACE_TEXT_WIDE(ACE_DIRECTORY_SEPARATOR_CHAR_A) +#endif /* ACE_HAS_WCHAR */ + +#define ACE_DIRECTORY_SEPARATOR_STR ACE_TEXT (ACE_DIRECTORY_SEPARATOR_STR_A) +#define ACE_DIRECTORY_SEPARATOR_CHAR ACE_TEXT (ACE_DIRECTORY_SEPARATOR_CHAR_A) + +#if !defined (ACE_DEFAULT_THREAD_PRIORITY) +# define ACE_DEFAULT_THREAD_PRIORITY (-0x7fffffffL - 1L) +#endif /* ACE_DEFAULT_THREAD_PRIORITY */ + +#if !defined (ACE_DEFAULT_THREAD_STACKSIZE) +# define ACE_DEFAULT_THREAD_STACKSIZE 0 +#endif /* ACE_DEFAULT_THREAD_STACKSIZE */ + +#if !defined (ACE_MAX_DEFAULT_PORT) +# define ACE_MAX_DEFAULT_PORT 65535 +#endif /* ACE_MAX_DEFAULT_PORT */ + +// Default number of ACE_Event_Handlers supported by +// ACE_Timer_Heap. +# if !defined (ACE_DEFAULT_TIMERS) +# define ACE_DEFAULT_TIMERS _POSIX_TIMER_MAX +# endif /* ACE_DEFAULT_TIMERS */ + +#if defined (ACE_WIN32) +# define ACE_PLATFORM_A "Win32" +# define ACE_PLATFORM_EXE_SUFFIX_A ".exe" +#elif defined (ACE_VXWORKS) +# define ACE_PLATFORM_A "VxWorks" +# if defined (__RTP__) +# define ACE_PLATFORM_EXE_SUFFIX_A ".vxe" +# else +# define ACE_PLATFORM_EXE_SUFFIX_A ".out" +# endif +#else /* !ACE_WIN32 && !ACE_VXWORKS */ +# define ACE_PLATFORM_A "UNIX" +# define ACE_PLATFORM_EXE_SUFFIX_A "" +#endif /* ACE_WIN32 */ + +// Define the Wide character and normal versions of some of the string macros +#if defined (ACE_HAS_WCHAR) +# define ACE_PLATFORM_W ACE_TEXT_WIDE(ACE_PLATFORM_A) +# define ACE_PLATFORM_EXE_SUFFIX_W ACE_TEXT_WIDE(ACE_PLATFORM_EXE_SUFFIX_A) +#endif /* ACE_HAS_WCHAR */ + +#define ACE_PLATFORM ACE_TEXT (ACE_PLATFORM_A) +#define ACE_PLATFORM_EXE_SUFFIX ACE_TEXT (ACE_PLATFORM_EXE_SUFFIX_A) + +#if defined (ACE_WIN32) +# define ACE_LD_SEARCH_PATH ACE_TEXT ("PATH") +# define ACE_LD_SEARCH_PATH_SEPARATOR_STR ACE_TEXT (";") +# define ACE_DLL_SUFFIX ACE_TEXT (".dll") +# if defined (__MINGW32__) +# define ACE_DLL_PREFIX ACE_TEXT ("lib") +# else /* __MINGW32__ */ +# define ACE_DLL_PREFIX ACE_TEXT ("") +# endif /* __MINGW32__ */ +#else /* !ACE_WIN32 */ +# if !defined (ACE_LD_SEARCH_PATH) +# define ACE_LD_SEARCH_PATH ACE_TEXT ("LD_LIBRARY_PATH") +# endif /* ACE_LD_SEARCH_PATH */ +# if !defined (ACE_LD_SEARCH_PATH_SEPARATOR_STR) +# define ACE_LD_SEARCH_PATH_SEPARATOR_STR ACE_TEXT (":") +# endif /* ACE_LD_SEARCH_PATH_SEPARATOR_STR */ +#endif /* ACE_WIN32 */ + +#if !defined (ACE_DLL_SUFFIX) +# define ACE_DLL_SUFFIX ACE_TEXT (".so") +#endif /* ACE_DLL_SUFFIX */ + +#if !defined (ACE_DLL_PREFIX) +# define ACE_DLL_PREFIX ACE_TEXT ("lib") +#endif /* ACE_DLL_PREFIX */ + +#if defined (ACE_WIN32) +// Used for dynamic linking +# if !defined (ACE_DEFAULT_SVC_CONF) +# if (ACE_USES_CLASSIC_SVC_CONF == 1) +# define ACE_DEFAULT_SVC_CONF ACE_TEXT (".\\svc.conf") +# else +# define ACE_DEFAULT_SVC_CONF ACE_TEXT (".\\svc.conf.xml") +# endif /* ACE_USES_CLASSIC_SVC_CONF ==1 */ +# endif /* ACE_DEFAULT_SVC_CONF */ +#endif /* ACE_WIN32 */ + + // Used for dynamic linking. +#if !defined (ACE_DEFAULT_SVC_CONF) +# if (ACE_USES_CLASSIC_SVC_CONF == 1) +# define ACE_DEFAULT_SVC_CONF ACE_TEXT ("./svc.conf") +# else +# define ACE_DEFAULT_SVC_CONF ACE_TEXT ("./svc.conf.xml") +# endif /* ACE_USES_CLASSIC_SVC_CONF ==1 */ +#endif /* ACE_DEFAULT_SVC_CONF */ + +#if !defined (ACE_LOGGER_KEY) +# define ACE_LOGGER_KEY ACE_TEXT ("/tmp/server_daemon") +#endif /* ACE_LOGGER_KEY */ + +// Theses defines are used by the ACE Name Server. +#if !defined (ACE_DEFAULT_LOCALNAME_A) +# define ACE_DEFAULT_LOCALNAME_A "localnames" +#endif /* ACE_DEFAULT_LOCALNAME_A */ +#if !defined (ACE_DEFAULT_GLOBALNAME_A) +# define ACE_DEFAULT_GLOBALNAME_A "globalnames" +#endif /* ACE_DEFAULT_GLOBALNAME_A */ + +// ACE_DEFAULT_NAMESPACE_DIR is for legacy mode apps. A better +// way of doing this is something like ACE_Lib_Find::get_temp_dir, since +// this directory may not exist +#if defined (ACE_LEGACY_MODE) +# if defined (ACE_WIN32) +# define ACE_DEFAULT_NAMESPACE_DIR_A "C:\\temp" +# else /* ACE_WIN32 */ +# define ACE_DEFAULT_NAMESPACE_DIR_A "/tmp" +# endif /* ACE_WIN32 */ +# if defined (ACE_HAS_WCHAR) +# define ACE_DEFAULT_NAMESPACE_DIR_W ACE_TEXT_WIDE(ACE_DEFAULT_NAMESPACE_DIR_A) +# endif /* ACE_HAS_WCHAR */ +# define ACE_DEFAULT_NAMESPACE_DIR ACE_TEXT(ACE_DEFAULT_NAMESPACE_DIR_A) +#endif /* ACE_LEGACY_MODE */ + +#if defined (ACE_HAS_WCHAR) +# define ACE_DEFAULT_LOCALNAME_W ACE_TEXT_WIDE(ACE_DEFAULT_LOCALNAME_A) +# define ACE_DEFAULT_GLOBALNAME_W ACE_TEXT_WIDE(ACE_DEFAULT_GLOBALNAME_A) +#endif /* ACE_HAS_WCHAR */ + +#define ACE_DEFAULT_LOCALNAME ACE_TEXT (ACE_DEFAULT_LOCALNAME_A) +#define ACE_DEFAULT_GLOBALNAME ACE_TEXT (ACE_DEFAULT_GLOBALNAME_A) + +# if defined (ACE_WIN32) + // The "null" device on Win32. +# define ACE_DEV_NULL "nul" +# define ACE_SYSCALL_FAILED 0xFFFFFFFF +# else /* !ACE_WIN32 */ + // The "null" device on UNIX. +# define ACE_DEV_NULL "/dev/null" +# define ACE_SYSCALL_FAILED -1 +# endif /* ACE_WIN32 */ + +#include /**/ "ace/post.h" +#endif /*ACE_DEFAULT_CONSTANTS_H*/ diff --git a/dep/ACE_wrappers/ace/Dev_Poll_Reactor.cpp b/dep/ACE_wrappers/ace/Dev_Poll_Reactor.cpp new file mode 100644 index 000000000..60a71d299 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dev_Poll_Reactor.cpp @@ -0,0 +1,2516 @@ +// $Id: Dev_Poll_Reactor.cpp 81315 2008-04-10 07:14:15Z johnnyw $ + +#include "ace/OS_NS_errno.h" +#include "ace/Dev_Poll_Reactor.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +ACE_RCSID (ace, + Dev_Poll_Reactor, + "$Id: Dev_Poll_Reactor.cpp 81315 2008-04-10 07:14:15Z johnnyw $") + +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + +# include "ace/OS_NS_unistd.h" +# include "ace/OS_NS_fcntl.h" +# include "ace/OS_NS_stropts.h" + +# if defined (ACE_HAS_EVENT_POLL) && defined (linux) +# include /**/ +# elif defined (ACE_HAS_DEV_POLL) +# if defined (linux) +# include /**/ +# elif defined (HPUX_VERS) && HPUX_VERS < 1123 +# include /**/ +# else +# include /**/ +# endif /* linux */ +# endif /* ACE_HAS_DEV_POLL */ + +#if !defined (__ACE_INLINE__) +# include "ace/Dev_Poll_Reactor.inl" +#endif /* __ACE_INLINE__ */ + + +#include "ace/Handle_Set.h" +#include "ace/Reactor.h" +#include "ace/Timer_Heap.h" +#include "ace/Timer_Queue.h" +#include "ace/ACE.h" +#include "ace/Reverse_Lock_T.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Null_Mutex.h" +#include "ace/os_include/os_poll.h" +#include "ace/OS_NS_sys_mman.h" +#include "ace/Guard_T.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_time.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Dev_Poll_Reactor_Notify::ACE_Dev_Poll_Reactor_Notify (void) + : dp_reactor_ (0) + , notification_pipe_ () + , max_notify_iterations_ (-1) +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + , notification_queue_ () +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ +{ +} + +int +ACE_Dev_Poll_Reactor_Notify::open (ACE_Reactor_Impl *r, + ACE_Timer_Queue * /* timer_queue */, + int disable_notify_pipe) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::open"); + + if (disable_notify_pipe == 0) + { + this->dp_reactor_ = dynamic_cast (r); + + if (this->dp_reactor_ == 0) + { + errno = EINVAL; + return -1; + } + + if (this->notification_pipe_.open () == -1) + return -1; + +#if defined (F_SETFD) + // close-on-exec + ACE_OS::fcntl (this->notification_pipe_.read_handle (), F_SETFD, 1); + ACE_OS::fcntl (this->notification_pipe_.write_handle (), F_SETFD, 1); +#endif /* F_SETFD */ + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + if (notification_queue_.open () == -1) + { + return -1; + } + + if (ACE::set_flags (this->notification_pipe_.write_handle (), + ACE_NONBLOCK) == -1) + return -1; +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ + + // Set the read handle into non-blocking mode since we need to + // perform a "speculative" read when determining if there are + // notifications to dispatch. + if (ACE::set_flags (this->notification_pipe_.read_handle (), + ACE_NONBLOCK) == -1) + return -1; + } + + return 0; +} + +int +ACE_Dev_Poll_Reactor_Notify::close (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::close"); + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + notification_queue_.reset (); +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ + + return this->notification_pipe_.close (); +} + +int +ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify"); + + // Just consider this method a "no-op" if there's no + // ACE_Dev_Poll_Reactor configured. + if (this->dp_reactor_ == 0) + return 0; + + ACE_Notification_Buffer buffer (eh, mask); + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + ACE_UNUSED_ARG (timeout); + ACE_Dev_Poll_Handler_Guard eh_guard (eh); + + int notification_required = + notification_queue_.push_new_notification (buffer); + + if (notification_required == -1) + return -1; // Also decrement eh's reference count + + // The notification has been queued, so it will be delivered at some + // point (and may have been already); release the refcnt guard. + eh_guard.release (); + + if (notification_required == 0) + return 0; + + // Now pop the pipe to force the callback for dispatching when ready. If + // the send fails due to a full pipe, don't fail - assume the already-sent + // pipe bytes will cause the entire notification queue to be processed. + ssize_t n = ACE::send (this->notification_pipe_.write_handle (), + (char *) &buffer, + 1, // Only need one byte to pop the pipe + &ACE_Time_Value::zero); + if (n == -1 && (errno != ETIME && errno != EAGAIN)) + return -1; + + return 0; +#else + + ACE_Dev_Poll_Handler_Guard eh_guard (eh); + + ssize_t n = ACE::send (this->notification_pipe_.write_handle (), + (char *) &buffer, + sizeof buffer, + timeout); + if (n == -1) + return -1; + + eh_guard.release (); + + return 0; +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ +} + +int +ACE_Dev_Poll_Reactor_Notify::dispatch_notifications ( + int & /* number_of_active_handles */, + ACE_Handle_Set & /* rd_mask */) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notifications"); + + // This method is unimplemented in the ACE_Dev_Poll_Reactor. + // Instead, the notification handler is invoked as part of the IO + // event set. Doing so alters the some documented semantics that + // state that the notifications are handled before IO events. + // Enforcing such semantics does not appear to be beneficial, and + // also serves to slow down event dispatching particularly with this + // ACE_Dev_Poll_Reactor. + + ACE_NOTSUP_RETURN (-1); +} + +int +ACE_Dev_Poll_Reactor_Notify::read_notify_pipe (ACE_HANDLE handle, + ACE_Notification_Buffer &buffer) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::read_notify_pipe"); + + // This is a (non-blocking) "speculative" read, i.e., we attempt to + // read even if no event was polled on the read handle. A + // speculative read is necessary since notifications must be + // dispatched before IO events. We can avoid the speculative read + // by "walking" the array of pollfd structures returned from + // `/dev/poll' or `/dev/epoll' but that is potentially much more + // expensive than simply checking for an EWOULDBLOCK. + size_t to_read; + char *read_p; + bool have_one = false; + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + // For the queued case, we'll try to read one byte (since that's what + // the notify () tried to put in) but we don't need it - notifications can + // be queued even if the pipe fills, so there may be more notifications + // queued than there are bytes in the pipe. + char b; + read_p = &b; + to_read = 1; + + // Before reading the byte, pop a message from the queue and queue a + // new message unless the queue is now empty. The protocol is to + // keep a byte in the pipe as long as the queue is not empty. + bool more_messages_queued = false; + ACE_Notification_Buffer next; + + int result = notification_queue_.pop_next_notification (buffer, + more_messages_queued, + next); + + if (result == 0) + { + // remove the notification byte from the pipe, avoiding notification loop + ACE::recv (handle, read_p, to_read); + return 0; + } + + if (result == -1) + return -1; + + if (more_messages_queued) + (void) ACE::send (this->notification_pipe_.write_handle (), + (char *)&next, + 1 /* one byte is enough */, + &ACE_Time_Value::zero); +#else + to_read = sizeof buffer; + read_p = (char *)&buffer; +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ + + ssize_t n = ACE::recv (handle, read_p, to_read); + + if (n > 0) + { + // Check to see if we've got a short read. + if (static_cast (n) != to_read) + { + size_t remainder = to_read - n; + + // If so, try to recover by reading the remainder. If this + // doesn't work we're in big trouble since the input stream + // won't be aligned correctly. I'm not sure quite what to + // do at this point. It's probably best just to return -1. + if (ACE::recv (handle, &read_p[n], remainder) <= 0) + return -1; + } + + return 1; + } + + // Return -1 if things have gone seriously wrong. + if (n <= 0 && (errno != EWOULDBLOCK && errno != EAGAIN)) + return -1; + + return have_one ? 1 : 0; +} + + +int +ACE_Dev_Poll_Reactor_Notify::handle_input (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::handle_input"); + + // @@ We may end up dispatching this event handler twice: once when + // performing the speculative read on the notification pipe + // handle, and once more when dispatching the IO events. + + // Precondition: this->select_reactor_.token_.current_owner () == + // ACE_Thread::self (); + + int number_dispatched = 0; + int result = 0; + ACE_Notification_Buffer buffer; + + while ((result = this->read_notify_pipe (handle, buffer)) > 0) + { + // Dispatch the buffer + // NOTE: We count only if we made any dispatches ie. upcalls. + if (this->dispatch_notify (buffer) > 0) + ++number_dispatched; + + // Bail out if we've reached the . Note that + // by default is -1, so we'll loop until all + // the available notifications have been dispatched. + if (number_dispatched == this->max_notify_iterations_) + break; + } + + if (result == -1) + { + // Reassign number_dispatched to -1 if things have gone + // seriously wrong. + number_dispatched = -1; + } + + // Enqueue ourselves into the list of waiting threads. When we + // reacquire the token we'll be off and running again with ownership + // of the token. The postcondition of this call is that + // == . + //this->select_reactor_->renew (); + + return number_dispatched; +} + +ACE_HANDLE +ACE_Dev_Poll_Reactor_Notify::notify_handle (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify_handle"); + + return this->notification_pipe_.read_handle (); +} + +int +ACE_Dev_Poll_Reactor_Notify::is_dispatchable (ACE_Notification_Buffer &) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::is_dispatchable"); + + ACE_NOTSUP_RETURN (-1); +} + +int +ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer &buffer) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notify"); + + // If eh == 0 then another thread is unblocking the + // ACE_Dev_Poll_Reactor to update the ACE_Dev_Poll_Reactor's + // internal structures. Otherwise, we need to dispatch the + // appropriate handle_* method on the ACE_Event_Handler + // pointer we've been passed. + if (buffer.eh_ != 0) + { + int result = 0; + + // Guard the handler's refcount. Recall that when the notify + // was queued, the refcount was incremented, so it need not be + // now. The guard insures that it is decremented properly. + ACE_Dev_Poll_Handler_Guard eh_guard (buffer.eh_, false); + + switch (buffer.mask_) + { + case ACE_Event_Handler::READ_MASK: + case ACE_Event_Handler::ACCEPT_MASK: + result = buffer.eh_->handle_input (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::WRITE_MASK: + result = buffer.eh_->handle_output (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::EXCEPT_MASK: + result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE); + break; + default: + // Should we bail out if we get an invalid mask? + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("dispatch_notify invalid mask = %d\n"), + buffer.mask_)); + } + if (result == -1) + buffer.eh_->handle_close (ACE_INVALID_HANDLE, buffer.mask_); + } + + return 1; +} + +void +ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (int iterations) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations"); + + // Must always be > 0 or < 0 to optimize the loop exit condition. + if (iterations == 0) + iterations = 1; + + this->max_notify_iterations_ = iterations; +} + +int +ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations"); + + return this->max_notify_iterations_; +} + +int +ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications ( + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications"); + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + + return notification_queue_.purge_pending_notifications (eh, mask); + +#else /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */ + ACE_UNUSED_ARG (eh); + ACE_UNUSED_ARG (mask); + ACE_NOTSUP_RETURN (-1); +#endif /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */ +} + +void +ACE_Dev_Poll_Reactor_Notify::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("dp_reactor_ = %@"), + this->dp_reactor_)); + this->notification_pipe_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// ----------------------------------------------------------------- + +ACE_Dev_Poll_Reactor_Handler_Repository:: +ACE_Dev_Poll_Reactor_Handler_Repository (void) + : max_size_ (0), + handlers_ (0) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::ACE_Dev_Poll_Reactor_Handler_Repository"); +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::invalid_handle ( + ACE_HANDLE handle) const +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::invalid_handle"); + + if (handle < 0 || handle >= this->max_size_) + { + errno = EINVAL; + return 1; + } + else + return 0; +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::handle_in_range ( + ACE_HANDLE handle) const +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::handle_in_range"); + + if (handle >= 0 && handle < this->max_size_) + return 1; + else + { + errno = EINVAL; + return 0; + } +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::open (size_t size) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::open"); + + this->max_size_ = size; + + // Try to allocate the memory. + ACE_NEW_RETURN (this->handlers_, + ACE_Dev_Poll_Event_Tuple[size], + -1); + + // Try to increase the number of handles if is greater than + // the current limit. + return ACE::set_handle_limit (size); +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::unbind_all (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::unbind_all"); + + // Unbind all of the event handlers. + for (int handle = 0; + handle < this->max_size_; + ++handle) + this->unbind (handle); + + return 0; +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::close (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::close"); + + if (this->handlers_ != 0) + { + this->unbind_all (); + + delete [] this->handlers_; + this->handlers_ = 0; + } + + return 0; +} + +ACE_Event_Handler * +ACE_Dev_Poll_Reactor_Handler_Repository::find (ACE_HANDLE handle, + size_t *index_p) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::find"); + + ACE_Event_Handler *eh = 0; + + // Only bother to search for the if it's in range. + if (this->handle_in_range (handle)) + { + eh = this->handlers_[handle].event_handler; + if (eh != 0) + { + if (index_p != 0) + *index_p = handle; + } + else + errno = ENOENT; + } + + return eh; +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::bind ( + ACE_HANDLE handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::bind"); + + if (event_handler == 0) + return -1; + + if (handle == ACE_INVALID_HANDLE) + handle = event_handler->get_handle (); + + if (this->invalid_handle (handle)) + return -1; + + this->handlers_[handle].event_handler = event_handler; + this->handlers_[handle].mask = mask; + event_handler->add_reference (); + + return 0; +} + +int +ACE_Dev_Poll_Reactor_Handler_Repository::unbind (ACE_HANDLE handle, + bool decr_refcnt) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::unbind"); + + if (this->find (handle) == 0) + return -1; + + if (decr_refcnt) + this->handlers_[handle].event_handler->remove_reference (); + this->handlers_[handle].event_handler = 0; + this->handlers_[handle].mask = ACE_Event_Handler::NULL_MASK; + this->handlers_[handle].suspended = 0; + + return 0; +} + +// ----------------------------------------------------------------- + +ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq, + int disable_notify_pipe, + ACE_Reactor_Notify *notify, + int mask_signals, + int s_queue) + : initialized_ (false) + , poll_fd_ (ACE_INVALID_HANDLE) + , size_ (0) + // , ready_set_ () +#if defined (ACE_HAS_EVENT_POLL) + , events_ (0) + , start_pevents_ (0) + , end_pevents_ (0) +#else + , dp_fds_ (0) + , start_pfds_ (0) + , end_pfds_ (0) +#endif /* ACE_HAS_EVENT_POLL */ + , deactivated_ (0) + , token_ (*this, s_queue) + , lock_adapter_ (token_) + , timer_queue_ (0) + , delete_timer_queue_ (false) + , signal_handler_ (0) + , delete_signal_handler_ (false) + , notify_handler_ (0) + , delete_notify_handler_ (false) + , mask_signals_ (mask_signals) + , restart_ (0) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor"); + + if (this->open (ACE::max_handles (), + 0, + sh, + tq, + disable_notify_pipe, + notify) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Dev_Poll_Reactor::open ") + ACE_TEXT ("failed inside ") + ACE_TEXT ("ACE_Dev_Poll_Reactor::CTOR"))); +} + +ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (size_t size, + int rs, + ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq, + int disable_notify_pipe, + ACE_Reactor_Notify *notify, + int mask_signals, + int s_queue) + : initialized_ (false) + , poll_fd_ (ACE_INVALID_HANDLE) + , size_ (0) + // , ready_set_ () +#if defined (ACE_HAS_EVENT_POLL) + , events_ (0) + , start_pevents_ (0) + , end_pevents_ (0) +#else + , dp_fds_ (0) + , start_pfds_ (0) + , end_pfds_ (0) +#endif /* ACE_HAS_EVENT_POLL */ + , deactivated_ (0) + , token_ (*this, s_queue) + , lock_adapter_ (token_) + , timer_queue_ (0) + , delete_timer_queue_ (false) + , signal_handler_ (0) + , delete_signal_handler_ (false) + , notify_handler_ (0) + , delete_notify_handler_ (false) + , mask_signals_ (mask_signals) + , restart_ (0) +{ + if (this->open (size, + rs, + sh, + tq, + disable_notify_pipe, + notify) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Dev_Poll_Reactor::open ") + ACE_TEXT ("failed inside ACE_Dev_Poll_Reactor::CTOR"))); +} + +ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor"); + + (void) this->close (); +} + +int +ACE_Dev_Poll_Reactor::open (size_t size, + int restart, + ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq, + int disable_notify_pipe, + ACE_Reactor_Notify *notify) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::open"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + // Can't initialize ourselves more than once. + if (this->initialized_) + return -1; + + this->restart_ = restart; + this->signal_handler_ = sh; + this->timer_queue_ = tq; + this->notify_handler_ = notify; + + int result = 0; + + // Allows the signal handler to be overridden. + if (this->signal_handler_ == 0) + { + ACE_NEW_RETURN (this->signal_handler_, + ACE_Sig_Handler, + -1); + + if (this->signal_handler_ == 0) + result = -1; + else + this->delete_signal_handler_ = true; + } + + // Allows the timer queue to be overridden. + if (result != -1 && this->timer_queue_ == 0) + { + ACE_NEW_RETURN (this->timer_queue_, + ACE_Timer_Heap, + -1); + + if (this->timer_queue_ == 0) + result = -1; + else + this->delete_timer_queue_ = true; + } + + // Allows the Notify_Handler to be overridden. + if (result != -1 && this->notify_handler_ == 0) + { + ACE_NEW_RETURN (this->notify_handler_, + ACE_Dev_Poll_Reactor_Notify, + -1); + + if (this->notify_handler_ == 0) + result = -1; + else + this->delete_notify_handler_ = true; + } + +#if defined (ACE_HAS_EVENT_POLL) + + // Allocating event table: + ACE_NEW_RETURN (this->events_, epoll_event[size], -1); + + // Initializing epoll: + this->poll_fd_ = ::epoll_create (size); + if (this->poll_fd_ == -1) + result = -1; + +#else + + // Allocate the array before opening the device to avoid a potential + // resource leak if allocation fails. + ACE_NEW_RETURN (this->dp_fds_, + pollfd[size], + -1); + + // Open the `/dev/poll' character device. + this->poll_fd_ = ACE_OS::open ("/dev/poll", O_RDWR); + if (this->poll_fd_ == ACE_INVALID_HANDLE) + result = -1; + +#endif /* ACE_HAS_EVENT_POLL */ + + if (result != -1 && this->handler_rep_.open (size) == -1) + result = -1; + + // Registration of the notification handler must be done after the + // /dev/poll device has been fully initialized. + else if (this->notify_handler_->open (this, + 0, + disable_notify_pipe) == -1 + || (disable_notify_pipe == 0 + && this->register_handler_i ( + this->notify_handler_->notify_handle (), + this->notify_handler_, + ACE_Event_Handler::READ_MASK) == -1)) + result = -1; + + this->size_ = size; + + if (result != -1) + // We're all set to go. + this->initialized_ = true; + else + // This will close down all the allocated resources properly. + (void) this->close (); + + return result; +} + +int +ACE_Dev_Poll_Reactor::current_info (ACE_HANDLE, size_t & /* size */) +{ + ACE_NOTSUP_RETURN (-1); +} + + +int +ACE_Dev_Poll_Reactor::set_sig_handler (ACE_Sig_Handler *signal_handler) +{ + if (this->delete_signal_handler_) + delete this->signal_handler_; + + this->signal_handler_ = signal_handler; + this->delete_signal_handler_ = false; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::timer_queue (ACE_Timer_Queue *tq) +{ + if (this->delete_timer_queue_) + delete this->timer_queue_; + + this->timer_queue_ = tq; + this->delete_timer_queue_ = false; + + return 0; + +} + +ACE_Timer_Queue * +ACE_Dev_Poll_Reactor::timer_queue (void) const +{ + return this->timer_queue_; +} + +int +ACE_Dev_Poll_Reactor::close (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::close"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + int result = 0; + + if (this->poll_fd_ != ACE_INVALID_HANDLE) + { + result = ACE_OS::close (this->poll_fd_); + } + +#if defined (ACE_HAS_EVENT_POLL) + + delete [] this->events_; + this->events_ = 0; + +#else + + delete [] this->dp_fds_; + this->dp_fds_ = 0; + +#endif /* ACE_HAS_EVENT_POLL */ + + if (this->delete_signal_handler_) + { + delete this->signal_handler_; + this->signal_handler_ = 0; + this->delete_signal_handler_ = false; + } + + (void) this->handler_rep_.close (); + + if (this->delete_timer_queue_) + { + delete this->timer_queue_; + this->timer_queue_ = 0; + this->delete_timer_queue_ = false; + } + + if (this->notify_handler_ != 0) + this->notify_handler_->close (); + + if (this->delete_notify_handler_) + { + delete this->notify_handler_; + this->notify_handler_ = 0; + this->delete_notify_handler_ = false; + } + + this->poll_fd_ = ACE_INVALID_HANDLE; + +#if defined (ACE_HAS_EVENT_POLL) + this->start_pevents_ = 0; + this->end_pevents_ = 0; +#else + this->start_pfds_ = 0; + this->end_pfds_ = 0; +#endif /* ACE_HAS_EVENT_POLL */ + + this->initialized_ = false; + + return result; +} + +int +ACE_Dev_Poll_Reactor::work_pending (const ACE_Time_Value & max_wait_time) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending"); + + // Stash the current time + // + // The destructor of this object will automatically compute how much + // time elapsed since this method was called. + ACE_Time_Value mwt (max_wait_time); + ACE_MT (ACE_Countdown_Time countdown (&mwt)); + + Token_Guard guard (this->token_); + int const result = guard.acquire_quietly (&mwt); + + // If the guard is NOT the owner just return the retval + if (!guard.is_owner ()) + return result; + + // Update the countdown to reflect time waiting for the mutex. + ACE_MT (countdown.update ()); + + return this->work_pending_i (&mwt); +} + +int +ACE_Dev_Poll_Reactor::work_pending_i (ACE_Time_Value * max_wait_time) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending_i"); + + if (this->deactivated_) + return 0; + +#if defined (ACE_HAS_EVENT_POLL) + if (this->start_pevents_ != this->end_pevents_) +#else + if (this->start_pfds_ != this->end_pfds_) +#endif /* ACE_HAS_EVENT_POLL */ + return 1; // We still have work_pending (). Do not poll for + // additional events. + + ACE_Time_Value timer_buf (0); + ACE_Time_Value *this_timeout = + this->timer_queue_->calculate_timeout (max_wait_time, &timer_buf); + + // Check if we have timers to fire. + int const timers_pending = + ((this_timeout != 0 && max_wait_time == 0) + || (this_timeout != 0 && max_wait_time != 0 + && *this_timeout != *max_wait_time) ? 1 : 0); + + long const timeout = + (this_timeout == 0 + ? -1 /* Infinity */ + : static_cast (this_timeout->msec ())); + +#if defined (ACE_HAS_EVENT_POLL) + + // Wait for events. + int const nfds = ::epoll_wait (this->poll_fd_, + this->events_, + this->size_, + static_cast (timeout)); + + if (nfds > 0) + { + this->start_pevents_ = this->events_; + this->end_pevents_ = this->start_pevents_ + nfds; + } + +#else + + struct dvpoll dvp; + + dvp.dp_fds = this->dp_fds_; + dvp.dp_nfds = this->size_; + dvp.dp_timeout = timeout; // Milliseconds + + // Poll for events + int const nfds = ACE_OS::ioctl (this->poll_fd_, DP_POLL, &dvp); + + // Retrieve the results from the pollfd array. + this->start_pfds_ = dvp.dp_fds; + + // If nfds == 0 then end_pfds_ == start_pfds_ meaning that there is + // no work pending. If nfds > 0 then there is work pending. + // Otherwise an error occurred. + if (nfds > -1) + this->end_pfds_ = this->start_pfds_ + nfds; +#endif /* ACE_HAS_EVENT_POLL */ + + // If timers are pending, override any timeout from the poll. + return (nfds == 0 && timers_pending != 0 ? 1 : nfds); +} + + +int +ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events"); + + // Stash the current time + // + // The destructor of this object will automatically compute how much + // time elapsed since this method was called. + ACE_MT (ACE_Countdown_Time countdown (max_wait_time)); + + Token_Guard guard (this->token_); + int const result = guard.acquire_quietly (max_wait_time); + + // If the guard is NOT the owner just return the retval + if (!guard.is_owner ()) + return result; + + if (this->deactivated_) + return -1; + + // Update the countdown to reflect time waiting for the mutex. + ACE_MT (countdown.update ()); + + return this->handle_events_i (max_wait_time, guard); +} + +int +ACE_Dev_Poll_Reactor::handle_events_i (ACE_Time_Value *max_wait_time, + Token_Guard &guard) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events_i"); + + int result = 0; + // int active_handle_count = 0; + + // Poll for events + // + // If the underlying ioctl () call was interrupted via the interrupt + // signal (i.e. returned -1 with errno == EINTR) then the loop will + // be restarted if so desired. + do + { + result = this->work_pending_i (max_wait_time); + if (result == -1) + ACE_ERROR ((LM_ERROR, "%t: %p\n", "work_pending_i")); + } + while (result == -1 && this->restart_ != 0 && errno == EINTR); + + if (result == 0 || (result == -1 && errno == ETIME)) + return 0; + else if (result == -1) + { + if (errno != EINTR) + return -1; + + // Bail out -- we got here since the poll was interrupted. + // If it was due to a signal registered through our ACE_Sig_Handler, + // then it was dispatched, so we count it in the number of events + // handled rather than cause an error return. + if (ACE_Sig_Handler::sig_pending () != 0) + { + ACE_Sig_Handler::sig_pending (0); + return 1; + } + return -1; + } + + // Dispatch an event. + return this->dispatch (guard); +} + +// Dispatch an event. On entry, the token is held by the caller. If an +// event is found to dispatch, the token is released before dispatching it. +int +ACE_Dev_Poll_Reactor::dispatch (Token_Guard &guard) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::dispatch"); + + // Perform the Template Method for dispatching the first located event. + // We dispatch only one to effectively dispatch events concurrently. + // As soon as an event is located, the token is released, allowing the + // next waiter to begin getting an event while we dispatch one here. + int result = 0; + + // Handle timers early since they may have higher latency + // constraints than I/O handlers. Ideally, the order of + // dispatching should be a strategy... + if ((result = this->dispatch_timer_handler (guard)) != 0) + return result; + + // Check to see if there are no more I/O handles left to + // dispatch AFTER we've handled the timers. + + // Finally, dispatch the I/O handlers. + result = this->dispatch_io_event (guard); + + return result; +} + +int +ACE_Dev_Poll_Reactor::dispatch_timer_handler (Token_Guard &guard) +{ + if (this->timer_queue_->is_empty ()) + return 0; // Empty timer queue so cannot have any expired timers. + + // Get the current time + ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () + + this->timer_queue_->timer_skew ()); + + // Look for a node in the timer queue whose timer <= the present + // time. + ACE_Timer_Node_Dispatch_Info info; + if (this->timer_queue_->dispatch_info (cur_time, info)) + { + const void *upcall_act = 0; + + // Preinvoke (handles refcount if needed, etc.) + this->timer_queue_->preinvoke (info, cur_time, upcall_act); + + // Release the token before expiration upcall. + guard.release_token (); + + // call the functor + this->timer_queue_->upcall (info, cur_time); + + // Postinvoke (undo refcount if needed, etc.) + this->timer_queue_->postinvoke (info, cur_time, upcall_act); + + // We have dispatched a timer + return 1; + } + + return 0; +} + +#if 0 +int +ACE_Dev_Poll_Reactor::dispatch_notification_handlers ( + ACE_Select_Reactor_Handle_Set &dispatch_set, + int &number_of_active_handles, + int &number_of_handlers_dispatched) +{ + // Check to see if the ACE_HANDLE associated with the + // Dev_Poll_Reactor's notify hook is enabled. If so, it means that + // one or more other threads are trying to update the + // ACE_Dev_Poll_Reactor's internal tables or the notify pipe is + // enabled. We'll handle all these threads and notifications, and + // then break out to continue the event loop. + + const int n = + this->notify_handler_->dispatch_notifications (number_of_active_handles, + dispatch_set.rd_mask_); + + if (n == -1) + return -1; + else + number_of_handlers_dispatched += n; + + return /* this->state_changed_ ? -1 : */ 0; +} +#endif /* 0 */ + +int +ACE_Dev_Poll_Reactor::dispatch_io_event (Token_Guard &guard) +{ + + // Define bits to check for while dispatching. +#if defined (ACE_HAS_EVENT_POLL) + const __uint32_t out_event = EPOLLOUT; + const __uint32_t exc_event = EPOLLPRI; + const __uint32_t in_event = EPOLLIN; + const __uint32_t err_event = EPOLLHUP | EPOLLERR; +#else + const short out_event = POLLOUT; + const short exc_event = POLLPRI; + const short in_event = POLLIN; + const short err_event = 0; // No known bits for this +#endif /* ACE_HAS_EVENT_POLL */ + + // Since the underlying event demultiplexing mechansim (`/dev/poll' + // or '/dev/epoll') is stateful, and since only one result buffer is + // used, all pending events (i.e. those retrieved from a previous + // poll) must be dispatched before any additional event can be + // polled. As such, the Dev_Poll_Reactor keeps track of the + // progress of events that have been dispatched. + + // Dispatch the events. + // + // Select the first available handle with event (s) pending. Check for + // event type in defined order of dispatch: output, exception, input. + // When an event is located, clear its bit in the dispatch set. If there + // are no more events for the handle, also increment the pfds pointer + // to move to the next handle ready. + // + // Notice that pfds only contains file descriptors that have + // received events. +#if defined (ACE_HAS_EVENT_POLL) + struct epoll_event *& pfds = this->start_pevents_; + if (pfds < this->end_pevents_) +#else + struct pollfd *& pfds = this->start_pfds_; + if (pfds < this->end_pfds_) +#endif /* ACE_HAS_EVENT_POLL */ + { +#if defined (ACE_HAS_EVENT_POLL) + const ACE_HANDLE handle = pfds->data.fd; + __uint32_t &revents = pfds->events; +#else + const ACE_HANDLE handle = pfds->fd; + short &revents = pfds->revents; +#endif /* ACE_HAS_EVENT_POLL */ + + // Figure out what to do first in order to make it easier to manage + // the bit twiddling and possible pfds increment before releasing + // the token for dispatch. + // Note that if there's an error (such as the handle was closed + // without being removed from the event set) the EPOLLHUP and/or + // EPOLLERR bits will be set in revents. + bool disp_out = false; + bool disp_exc = false; + bool disp_in = false; + if (ACE_BIT_ENABLED (revents, out_event)) + { + disp_out = true; + ACE_CLR_BITS (revents, out_event); + } + else if (ACE_BIT_ENABLED (revents, exc_event)) + { + disp_exc = true; + ACE_CLR_BITS (revents, exc_event); + } + else if (ACE_BIT_ENABLED (revents, in_event)) + { + disp_in = true; + ACE_CLR_BITS (revents, in_event); + } + else if (ACE_BIT_ENABLED (revents, err_event)) + { + this->remove_handler_i (handle, ACE_Event_Handler::ALL_EVENTS_MASK); + ++pfds; + return 1; + } + else + { + ACE_ERROR ((LM_ERROR, ACE_TEXT (" (%t) dispatch_io h %d unknown events 0x%x\n"), handle, revents)); + // ACE_ASSERT (0); + } + + // Increment the pointer to the next element before we + // release the token. Otherwise event handlers end up being + // dispatched multiple times for the same poll. + if (revents == 0) + ++pfds; + + /* When using sys_epoll, we can attach arbitrary user + data to the descriptor, so it can be delivered when + activity is detected. Perhaps we should store event + handler together with descriptor, instead of looking + it up in a repository ? Could it boost performance ? + */ + ACE_Event_Handler *eh = this->handler_rep_.find (handle); + + if (eh) + { + // Modify the reference count in an exception-safe way. + // Note that eh could be the notify handler. It's not strictly + // necessary to manage its refcount, but since we don't enable + // the counting policy, it won't do much. Management of the + // notified handlers themselves is done in the notify handler. + ACE_Dev_Poll_Handler_Guard eh_guard (eh); + + // Release the reactor token before upcall. + guard.release_token (); + + // Dispatch the detected event + if (disp_out) + { + const int status = + this->upcall (eh, &ACE_Event_Handler::handle_output, handle); + + if (status < 0) + // Note that the token is reacquired in remove_handler (). + this->remove_handler (handle, ACE_Event_Handler::WRITE_MASK); + return 1; + } + + if (disp_exc) + { + const int status = + this->upcall (eh, &ACE_Event_Handler::handle_exception, handle); + + if (status < 0) + // Note that the token is reacquired in remove_handler (). + this->remove_handler (handle, ACE_Event_Handler::EXCEPT_MASK); + return 1; + } + + if (disp_in) + { + const int status = + this->upcall (eh, &ACE_Event_Handler::handle_input, handle); + + if (status < 0) + // Note that the token is reacquired in remove_handler (). + this->remove_handler (handle, ACE_Event_Handler::READ_MASK); + return 1; + } + } // The reactor token is reacquired upon leaving this scope. + } + + return 0; +} + +int +ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events"); + + return this->handle_events (max_wait_time); +} + +int +ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value &max_wait_time) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events"); + + return this->handle_events (&max_wait_time); +} + +int +ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value &max_wait_time) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events"); + + return this->handle_events (max_wait_time); +} + +int +ACE_Dev_Poll_Reactor::deactivated (void) +{ + return this->deactivated_; +} + +void +ACE_Dev_Poll_Reactor::deactivate (int do_stop) +{ + this->deactivated_ = do_stop; + this->wakeup_all_threads (); +} + +int +ACE_Dev_Poll_Reactor::register_handler (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->register_handler_i (handler->get_handle (), + handler, + mask); +} + +int +ACE_Dev_Poll_Reactor::register_handler (ACE_HANDLE handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->register_handler_i (handle, + event_handler, + mask); +} + +int +ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler_i"); + + if (handle == ACE_INVALID_HANDLE + || mask == ACE_Event_Handler::NULL_MASK) + { + errno = EINVAL; + return -1; + } + + if (this->handler_rep_.find (handle) == 0) + { + // Handler not present in the repository. Bind it. + if (this->handler_rep_.bind (handle, event_handler, mask) != 0) + return -1; + +#if defined (ACE_HAS_EVENT_POLL) + + struct epoll_event epev; + ACE_OS::memset (&epev, 0, sizeof (epev)); + static const int op = EPOLL_CTL_ADD; + + epev.events = this->reactor_mask_to_poll_event (mask); + epev.data.fd = handle; + + if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "epoll_ctl")); + (void) this->handler_rep_.unbind (handle); + return -1; + } + +#endif /* ACE_HAS_EVENT_POLL */ + } + else + { + // Handler is already present in the repository, so register it + // again, possibly for different event. Add new mask to the + // current one. + if (this->mask_ops_i (handle, mask, ACE_Reactor::ADD_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mask_ops_i"), -1); + } + +#ifndef ACE_HAS_EVENT_POLL + + struct pollfd pfd; + + pfd.fd = handle; + pfd.events = this->reactor_mask_to_poll_event (mask); + pfd.revents = 0; + + // Add file descriptor to the "interest set." + if (ACE_OS::write (this->poll_fd_, &pfd, sizeof (pfd)) != sizeof (pfd)) + { + (void) this->handler_rep_.unbind (handle); + return -1; + } +#endif /*ACE_HAS_EVENT_POLL*/ + + // Note the fact that we've changed the state of the wait_set_, + // which is used by the dispatching loop to determine whether it can + // keep going or if it needs to reconsult select (). + // this->state_changed_ = 1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::register_handler ( + ACE_HANDLE /* event_handle */, + ACE_HANDLE /* io_handle */, + ACE_Event_Handler * /* event_handler */, + ACE_Reactor_Mask /* mask */) +{ + ACE_NOTSUP_RETURN (-1); +} + +int +ACE_Dev_Poll_Reactor::register_handler (const ACE_Handle_Set &handle_set, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler"); + + ACE_Handle_Set_Iterator handle_iter (handle_set); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + // @@ It might be more efficient to construct a pollfd array and + // pass it to the write () call in register_handler_i () only once, + // instead of calling write () (a system call) once for each file + // descriptor. + + for (ACE_HANDLE h = handle_iter (); + h != ACE_INVALID_HANDLE; + h = handle_iter ()) + if (this->register_handler_i (h, event_handler, mask) == -1) + return -1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler"); + + return this->signal_handler_->register_handler (signum, + new_sh, + new_disp, + old_sh, + old_disp); +} + +int +ACE_Dev_Poll_Reactor::register_handler (const ACE_Sig_Set &sigset, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler"); + + int result = 0; + +#if (ACE_NSIG > 0) + + for (int s = 1; s < ACE_NSIG; ++s) + if ((sigset.is_member (s) == 1) + && this->signal_handler_->register_handler (s, + new_sh, + new_disp) == -1) + result = -1; + +#else /* ACE_NSIG <= 0 */ + + ACE_UNUSED_ARG (sigset); + ACE_UNUSED_ARG (new_sh); + ACE_UNUSED_ARG (new_disp); + +#endif /* ACE_NSIG <= 0 */ + + return result; +} + +int +ACE_Dev_Poll_Reactor::remove_handler (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->remove_handler_i (handler->get_handle (), mask); +} + +int +ACE_Dev_Poll_Reactor::remove_handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->remove_handler_i (handle, mask); +} + +int +ACE_Dev_Poll_Reactor::remove_handler_i (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler_i"); + + ACE_Event_Handler *eh = this->handler_rep_.find (handle); + + if (eh == 0 || + this->mask_ops_i (handle, mask, ACE_Reactor::CLR_MASK) == -1) + return -1; + + // Check for ref counting now - handle_close () may delete eh. + bool const requires_reference_counting = + eh->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + if (ACE_BIT_DISABLED (mask, ACE_Event_Handler::DONT_CALL)) + (void) eh->handle_close (handle, mask); + + // If there are no longer any outstanding events on the given handle + // then remove it from the handler repository. + if (this->handler_rep_.mask (handle) == ACE_Event_Handler::NULL_MASK) + this->handler_rep_.unbind (handle, requires_reference_counting); + + // Note the fact that we've changed the state of the wait_set, + // i.e. the "interest set," which is used by the dispatching loop to + // determine whether it can keep going or if it needs to reconsult + // /dev/poll or /dev/epoll. + // this->state_changed_ = 1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::remove_handler (const ACE_Handle_Set &handle_set, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler"); + + ACE_Handle_Set_Iterator handle_iter (handle_set); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + // @@ It might be more efficient to construct a pollfd array and + // pass it to the write () call in register_handler_i () only once, + // instead of calling write () (a system call) once for each file + // descriptor. + + for (ACE_HANDLE h = handle_iter (); + h != ACE_INVALID_HANDLE; + h = handle_iter ()) + if (this->remove_handler_i (h, mask) == -1) + return -1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler"); + + return this->signal_handler_->remove_handler (signum, + new_disp, + old_disp, + sigkey); +} + +int +ACE_Dev_Poll_Reactor::remove_handler (const ACE_Sig_Set &sigset) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler"); + + int result = 0; + +#if (ACE_NSIG > 0) + + for (int s = 1; s < ACE_NSIG; ++s) + if ((sigset.is_member (s) == 1) + && this->signal_handler_->remove_handler (s) == -1) + result = -1; + +#else /* ACE_NSIG <= 0 */ + + ACE_UNUSED_ARG (sigset); + +#endif /* ACE_NSIG <= 0 */ + + return result; +} + +int +ACE_Dev_Poll_Reactor::suspend_handler (ACE_Event_Handler *event_handler) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler"); + + if (event_handler == 0) + { + errno = EINVAL; + return -1; + } + + ACE_HANDLE handle = event_handler->get_handle (); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->suspend_handler_i (handle); +} + +int +ACE_Dev_Poll_Reactor::suspend_handler (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->suspend_handler_i (handle); +} + +int +ACE_Dev_Poll_Reactor::suspend_handler (const ACE_Handle_Set &handles) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler"); + + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->suspend_handler_i (h) == -1) + return -1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::suspend_handlers (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handlers"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + size_t const len = this->handler_rep_.size (); + + for (size_t i = 0; i < len; ++i) + if (this->handler_rep_.suspended (i) == 0 + && this->suspend_handler_i (i) != 0) + return -1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::suspend_handler_i (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler_i"); + + if (this->handler_rep_.find (handle) == 0) + return -1; + + if (this->handler_rep_.suspended (handle)) + return 0; // Already suspended. @@ Should this be an error? + + // Remove the handle from the "interest set." + // + // Note that the associated event handler is still in the handler + // repository, but no events will be polled on the given handle thus + // no event will be dispatched to the event handler. + +#if defined (ACE_HAS_EVENT_POLL) + + struct epoll_event epev; + ACE_OS::memset (&epev, 0, sizeof (epev)); + static const int op = EPOLL_CTL_DEL; + + epev.events = 0; + epev.data.fd = handle; + + if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1) + return -1; + +#else + + struct pollfd pfd[1]; + + pfd[0].fd = handle; + pfd[0].events = POLLREMOVE; + pfd[0].revents = 0; + + if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd)) + return -1; + +#endif /* ACE_HAS_EVENT_POLL */ + + this->handler_rep_.suspend (handle); + + return 0; +} + +int +ACE_Dev_Poll_Reactor::resume_handler (ACE_Event_Handler *event_handler) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler"); + + if (event_handler == 0) + { + errno = EINVAL; + return -1; + } + + ACE_HANDLE handle = event_handler->get_handle (); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->resume_handler_i (handle); +} + +int +ACE_Dev_Poll_Reactor::resume_handler (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->resume_handler_i (handle); +} + +int +ACE_Dev_Poll_Reactor::resume_handler (const ACE_Handle_Set &handles) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler"); + + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->resume_handler_i (h) == -1) + return -1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::resume_handlers (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handlers"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + size_t const len = this->handler_rep_.size (); + + for (size_t i = 0; i < len; ++i) + if (this->handler_rep_.suspended (i) + && this->resume_handler_i (i) != 0) + return -1; + + return 0; +} + +int +ACE_Dev_Poll_Reactor::resume_handler_i (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler_i"); + + if (this->handler_rep_.find (handle) == 0 + && this->handler_rep_.suspended (handle) == 0) + return -1; + + ACE_Reactor_Mask mask = this->handler_rep_.mask (handle); + + if (mask == ACE_Event_Handler::NULL_MASK) + return -1; + + // Place the handle back in to the "interest set." + // + // Events for the given handle will once again be polled. + +#if defined (ACE_HAS_EVENT_POLL) + + struct epoll_event epev; + ACE_OS::memset (&epev, 0, sizeof (epev)); + static const int op = EPOLL_CTL_ADD; + + epev.events = this->reactor_mask_to_poll_event (mask); + epev.data.fd = handle; + + if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1) + return -1; + +#else + + struct pollfd pfd[1]; + + pfd[0].fd = handle; + pfd[0].events = this->reactor_mask_to_poll_event (mask); + pfd[0].revents = 0; + + if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd)) + return -1; + +#endif /* ACE_HAS_EVENT_POLL */ + + this->handler_rep_.resume (handle); + + return 0; +} + +int +ACE_Dev_Poll_Reactor::resumable_handler (void) +{ + // @@ Is this correct? + + return 0; +} + +int +ACE_Dev_Poll_Reactor::uses_event_associations (void) +{ + // Since the Dev_Poll_Reactor does not do any event associations, + // this method always return zero. + return 0; +} + +long +ACE_Dev_Poll_Reactor::schedule_timer (ACE_Event_Handler *event_handler, + const void *arg, + const ACE_Time_Value &delay, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_timer"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + if (0 != this->timer_queue_) + return this->timer_queue_->schedule + (event_handler, + arg, + this->timer_queue_->gettimeofday () + delay, + interval); + + errno = ESHUTDOWN; + return -1; +} + +int +ACE_Dev_Poll_Reactor::reset_timer_interval (long timer_id, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::reset_timer_interval"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + if (0 != this->timer_queue_) + return this->timer_queue_->reset_interval (timer_id, interval); + + errno = ESHUTDOWN; + return -1; +} + +int +ACE_Dev_Poll_Reactor::cancel_timer (ACE_Event_Handler *event_handler, + int dont_call_handle_close) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return (this->timer_queue_ == 0 + ? 0 + : this->timer_queue_->cancel (event_handler, + dont_call_handle_close)); +} + +int +ACE_Dev_Poll_Reactor::cancel_timer (long timer_id, + const void **arg, + int dont_call_handle_close) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return (this->timer_queue_ == 0 + ? 0 + : this->timer_queue_->cancel (timer_id, + arg, + dont_call_handle_close)); +} + +int +ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup"); + + return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK); +} + +int +ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup"); + + return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK); +} + +int +ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup"); + + return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK); +} + +int +ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup"); + + return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK); +} + +int +ACE_Dev_Poll_Reactor::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::notify"); + + ssize_t n = 0; + + // Pass over both the Event_Handler *and* the mask to allow the + // caller to dictate which Event_Handler method the receiver + // invokes. Note that this call can timeout. + + n = this->notify_handler_->notify (eh, mask, timeout); + + return n == -1 ? -1 : 0; +} + +void +ACE_Dev_Poll_Reactor::max_notify_iterations (int iterations) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations"); + + ACE_MT (ACE_GUARD (ACE_Dev_Poll_Reactor_Token, mon, this->token_)); + + this->notify_handler_->max_notify_iterations (iterations); +} + +int +ACE_Dev_Poll_Reactor::max_notify_iterations (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->notify_handler_->max_notify_iterations (); +} + +int +ACE_Dev_Poll_Reactor::purge_pending_notifications (ACE_Event_Handler * eh, + ACE_Reactor_Mask mask) +{ + if (this->notify_handler_ == 0) + return 0; + + return this->notify_handler_->purge_pending_notifications (eh, mask); +} + +ACE_Event_Handler * +ACE_Dev_Poll_Reactor::find_handler (ACE_HANDLE handle) +{ + ACE_MT (ACE_READ_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, 0)); + + ACE_Event_Handler *event_handler = this->handler_rep_.find (handle); + if (event_handler) + event_handler->add_reference (); + return event_handler; +} + +int +ACE_Dev_Poll_Reactor::handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **event_handler) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::handler"); + + ACE_MT (ACE_READ_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + ACE_Event_Handler *h = this->handler_rep_.find (handle); + + if (h != 0 + && ACE_BIT_CMP_MASK (this->handler_rep_.mask (handle), + mask, // Compare all bits in the mask + mask)) + { + if (event_handler != 0) + *event_handler = h; + + return 0; + } + + return -1; +} + +int +ACE_Dev_Poll_Reactor::handler (int signum, + ACE_Event_Handler **eh) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::handler"); + + ACE_Event_Handler *handler = this->signal_handler_->handler (signum); + + if (handler == 0) + return -1; + else if (eh != 0) + *eh = handler; + + return 0; +} + +bool +ACE_Dev_Poll_Reactor::initialized (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::initialized"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, false)); + + return this->initialized_; +} + +size_t +ACE_Dev_Poll_Reactor::size (void) const +{ + return this->size_; +} + +ACE_Lock & +ACE_Dev_Poll_Reactor::lock (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::lock"); + + return this->lock_adapter_; +} + +void +ACE_Dev_Poll_Reactor::wakeup_all_threads (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::wakeup_all_threads"); + + // Send a notification, but don't block if there's no one to receive + // it. + this->notify (0, + ACE_Event_Handler::NULL_MASK, + (ACE_Time_Value *) &ACE_Time_Value::zero); +} + +int +ACE_Dev_Poll_Reactor::owner (ACE_thread_t /* new_owner */, + ACE_thread_t * /* old_owner */) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::owner"); + + // There is no need to set the owner of the event loop. Multiple + // threads may invoke the event loop simulataneously. + + return 0; +} + +int +ACE_Dev_Poll_Reactor::owner (ACE_thread_t * /* owner */) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::owner"); + + // There is no need to set the owner of the event loop. Multiple + // threads may invoke the event loop simulataneously. + + return 0; +} + +int +ACE_Dev_Poll_Reactor::restart (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::restart"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->restart_; +} + +int +ACE_Dev_Poll_Reactor::restart (int r) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::restart"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + int current_value = this->restart_; + this->restart_ = r; + return current_value; +} + +void +ACE_Dev_Poll_Reactor::requeue_position (int) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position"); +} + +int +ACE_Dev_Poll_Reactor::requeue_position (void) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position"); + + ACE_NOTSUP_RETURN (-1); +} + +int +ACE_Dev_Poll_Reactor::mask_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->mask_ops_i (event_handler->get_handle (), mask, ops); +} + +int +ACE_Dev_Poll_Reactor::mask_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1)); + + return this->mask_ops_i (handle, mask, ops); +} + +int +ACE_Dev_Poll_Reactor::mask_ops_i (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops_i"); + + if (this->handler_rep_.handle_in_range (handle) == 0) + return -1; + + // Block out all signals until method returns. + ACE_Sig_Guard sb; + + ACE_Reactor_Mask const old_mask = this->handler_rep_.mask (handle); + ACE_Reactor_Mask new_mask = old_mask; + + // Perform GET, CLR, SET, and ADD operations on the interest/wait + // set and the suspend set (if necessary). + // + // GET = 1, Retrieve current value + // SET = 2, Set value of bits to new mask (changes the entire mask) + // ADD = 3, Bitwise "or" the value into the mask (only changes + // enabled bits) + // CLR = 4 Bitwise "and" the negation of the value out of the mask + // (only changes enabled bits) + // + // Returns the original mask. + + switch (ops) + { + case ACE_Reactor::GET_MASK: + // The work for this operation is done in all cases at the + // begining of the function. + return old_mask; + + case ACE_Reactor::CLR_MASK: + ACE_CLR_BITS (new_mask, mask); + break; + + case ACE_Reactor::SET_MASK: + new_mask = mask; + break; + + case ACE_Reactor::ADD_MASK: + ACE_SET_BITS (new_mask, mask); + break; + + default: + return -1; + } + + /// Reset the mask for the given handle. + this->handler_rep_.mask (handle, new_mask); + + if (this->handler_rep_.suspended (handle) == 0) + { + // Only attempt to alter events for the handle from the + // "interest set" if it hasn't been suspended. + + short const events = this->reactor_mask_to_poll_event (new_mask); + +#if defined (sun) + // Apparently events cannot be updated on-the-fly on Solaris so + // remove the existing events, and then add the new ones. + struct pollfd pfd[2]; + + pfd[0].fd = handle; + pfd[0].events = POLLREMOVE; + pfd[0].revents = 0; + pfd[1].fd = (events == POLLREMOVE ? ACE_INVALID_HANDLE : handle); + pfd[1].events = events; + pfd[1].revents = 0; + + // Change the events associated with the given file descriptor. + if (ACE_OS::write (this->poll_fd_, + pfd, + sizeof (pfd)) != sizeof (pfd)) + return -1; +#elif defined (ACE_HAS_EVENT_POLL) + + struct epoll_event epev; + ACE_OS::memset (&epev, 0, sizeof (epev)); + int op; + + // ACE_Event_Handler::NULL_MASK ??? + if (new_mask == 0) + { + op = EPOLL_CTL_DEL; + epev.events = 0; + } + else + { + op = EPOLL_CTL_MOD; + epev.events = events; + } + + epev.data.fd = handle; + + if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1) + { + // If a handle is closed, epoll removes it from the poll set + // automatically - we may not know about it yet. If that's the + // case, a mod operation will fail with ENOENT. Retry it as + // an add. + if (op == EPOLL_CTL_MOD && errno == ENOENT && + ::epoll_ctl (this->poll_fd_, EPOLL_CTL_ADD, handle, &epev) == -1) + return -1; + } + +#else + pollfd pfd[1]; + + pfd[0].fd = handle; + pfd[0].events = events; + pfd[0].revents = 0; + + // Change the events associated with the given file descriptor. + if (ACE_OS::write (this->poll_fd_, + pfd, + sizeof (pfd)) != sizeof (pfd)) + return -1; +#endif /*ACE_HAS_EVENT_POLL */ + } + + return old_mask; +} + +int +ACE_Dev_Poll_Reactor::ready_ops (ACE_Event_Handler * /* event_handler */, + ACE_Reactor_Mask /* mask */, + int /* ops */) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops"); + + // Since the Dev_Poll_Reactor uses the poll result buffer, the + // ready_set cannot be directly manipulated outside of the event + // loop. + ACE_NOTSUP_RETURN (-1); +} + +int +ACE_Dev_Poll_Reactor::ready_ops (ACE_HANDLE /* handle */, + ACE_Reactor_Mask /* mask */, + int /* ops */) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops"); + + // Since the Dev_Poll_Reactor uses the poll result buffer, the + // ready_set cannot be directly manipulated outside of the event + // loop. + ACE_NOTSUP_RETURN (-1); +} + +void +ACE_Dev_Poll_Reactor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Dev_Poll_Reactor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("restart_ = %d\n"), this->restart_)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("initialized_ = %d"), + this->initialized_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("poll_fd_ = %d"), this->poll_fd_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("size_ = %u"), this->size_)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("deactivated_ = %d"), + this->deactivated_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +short +ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event (ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event"); + + if (mask == ACE_Event_Handler::NULL_MASK) + // No event. Remove from interest set. +#if defined (ACE_HAS_EVENT_POLL) + return EPOLL_CTL_DEL; +#else + return POLLREMOVE; +#endif /* ACE_HAS_EVENT_POLL */ + + short events = 0; + + // READ, ACCEPT, and CONNECT flag will place the handle in the + // read set. + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK) + || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK) + || ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK)) + { +#if defined (ACE_HAS_EVENT_POLL) + ACE_SET_BITS (events, EPOLLIN); +#else + ACE_SET_BITS (events, POLLIN); +#endif /*ACE_HAS_EVENT_POLL*/ + } + + // WRITE and CONNECT flag will place the handle in the write set. + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK) + || ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK)) + { +#if defined (ACE_HAS_EVENT_POLL) + ACE_SET_BITS (events, EPOLLOUT); +#else + ACE_SET_BITS (events, POLLOUT); +#endif /*ACE_HAS_EVENT_POLL*/ + } + + // EXCEPT flag will place the handle in the except set. + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK)) + { +#if defined (ACE_HAS_EVENT_POLL) + ACE_SET_BITS (events, EPOLLPRI); +#else + ACE_SET_BITS (events, POLLPRI); +#endif /*ACE_HAS_EVENT_POLL*/ + } + + return events; +} + +namespace { + void polite_sleep_hook (void *) { } +} + +int +ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly (ACE_Time_Value *max_wait) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly"); + + // Acquire the token but don't ping any waiters; just queue up politely. + int result = 0; + if (max_wait) + { + ACE_Time_Value tv = ACE_OS::gettimeofday (); + tv += *max_wait; + + ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook, + 0, + &tv)); + } + else + { + ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook)); + } + + // Check for timeouts and errors. + if (result == -1) + { + if (errno == ETIME) + return 0; + else + { + ACE_ERROR ((LM_ERROR, "%t: %p\n", "token acquire_read")); + return -1; + } + } + + // We got the token and so let us mark ourselves as owner + this->owner_ = 1; + + return result; +} + +int +ACE_Dev_Poll_Reactor::Token_Guard::acquire (ACE_Time_Value *max_wait) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire"); + + // Try to grab the token. If someone if already there, don't wake + // them up, just queue up in the thread pool. + int result = 0; + if (max_wait) + { + ACE_Time_Value tv = ACE_OS::gettimeofday (); + tv += *max_wait; + + ACE_MT (result = this->token_.acquire (0, 0, &tv)); + } + else + { + ACE_MT (result = this->token_.acquire ()); + } + + // Check for timeouts and errors. + if (result == -1) + { + if (errno == ETIME) + return 0; + else + return -1; + } + + // We got the token and so let us mark ourseleves as owner + this->owner_ = 1; + + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */ diff --git a/dep/ACE_wrappers/ace/Dev_Poll_Reactor.h b/dep/ACE_wrappers/ace/Dev_Poll_Reactor.h new file mode 100644 index 000000000..38d9c013a --- /dev/null +++ b/dep/ACE_wrappers/ace/Dev_Poll_Reactor.h @@ -0,0 +1,1252 @@ +// -*- C++ -*- + +// ========================================================================= +/** + * @file Dev_Poll_Reactor.h + * + * $Id: Dev_Poll_Reactor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @c /dev/poll (or Linux @c sys_epoll) based Reactor implementation. + * + * @author Ossama Othman + */ +// ========================================================================= + + +#ifndef ACE_DEV_POLL_REACTOR_H +#define ACE_DEV_POLL_REACTOR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_EVENT_POLL) && defined (ACE_HAS_DEV_POLL) +# error ACE_HAS_EVENT_POLL and ACE_HAS_DEV_POLL are mutually exclusive. +#endif /* ACE_HAS_EVENT_POLL && defined ACE_HAS_DEV_POLL */ + +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + +#include "ace/Pipe.h" +#include "ace/Lock_Adapter_T.h" +#include "ace/Reactor_Impl.h" +#include "ace/Reactor_Token_T.h" +#include "ace/Token.h" + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) +# include "ace/Notification_Queue.h" +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ + +#if defined (ACE_HAS_DEV_POLL) +struct pollfd; +#elif defined (ACE_HAS_EVENT_POLL) +struct epoll_event; +#endif + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations +class ACE_Sig_Handler; +class ACE_Dev_Poll_Reactor; + +/** + * @class ACE_Dev_Poll_Event_Tuple + * + * @brief Class that associates specific event mask with a given event + * handler. + * + * This class merely provides a means to associate an event mask + * with an event handler. Such an association is needed since it is + * not possible to retrieve the event mask from the "interest set" + * stored in the `/dev/poll' or `/dev/epoll' driver. Without this + * external association, it would not be possible keep track of the + * event mask for a given event handler when suspending it or resuming + * it. + * + * @note An ACE_Handle_Set is not used since the number of handles may + * exceed its capacity (ACE_DEFAULT_SELECT_REACTOR_SIZE). + */ +class ACE_Dev_Poll_Event_Tuple +{ +public: + + /// Constructor. + ACE_Dev_Poll_Event_Tuple (void); + +public: + + /// The event handler. + ACE_Event_Handler *event_handler; + + /// The event mask for the above event handler. + ACE_Reactor_Mask mask; + + /// Flag that states whether or not the event handler is suspended. + char suspended; +}; + +// --------------------------------------------------------------------- + +#if 0 +/** + * @class ACE_Dev_Poll_Ready_Set + * + * @brief Class that contains the list of "ready" file descriptors. + * + * This class points to an array of pollfd structures corresponding to + * "ready" file descriptors, such as those corresponding to event + * handlers that request an additional callback after being initially + * dispatched (i.e. return a value greater than zero). + * @par + * The idea is to store the "ready" set in an existing area of memory + * that already contains pollfd instances. Doing so is safe since the + * "ready" set is dispatched before polling for additional events, + * thus avoiding being potentially overwritten during the event poll. + * @par + * When the "ready" set is dispatched, all that needs to be done is to + * iterate over the contents of the array. There is no need to "walk" + * the array in search of ready file descriptors since the array by + * design only contains ready file descriptors. As such, this + * implementation of a ready set is much more efficient in the + * presence of a large number of file descriptors in terms of both + * time and space than the one used in the Select_Reactor, for + * example. + */ +class ACE_Dev_Poll_Ready_Set +{ +public: + + /// Constructor. + ACE_Dev_Poll_Ready_Set (void); + +public: + + /// The array containing the pollfd structures corresponding to the + /// "ready" file descriptors. + struct pollfd *pfds; + + /// The number of "ready" file descriptors in the above array. + int nfds; + +}; +#endif /* 0 */ + +// --------------------------------------------------------------------- + +/** + * @class ACE_Dev_Poll_Reactor_Notify + * + * @brief Event handler used for unblocking the ACE_Dev_Poll_Reactor + * from its event loop. + * + * This event handler is used internally by the ACE_Dev_Poll_Reactor + * as a means to allow a thread other then the one running the event + * loop to unblock the event loop. + */ +class ACE_Dev_Poll_Reactor_Notify : public ACE_Reactor_Notify +{ +public: + + /// Constructor + ACE_Dev_Poll_Reactor_Notify (void); + + /** + * @name Initialization and Termination Methods + * + * Methods called when initializing and terminating this event + * handler. + */ + virtual int open (ACE_Reactor_Impl *, + ACE_Timer_Queue *timer_queue = 0, + int disable_notify = 0); + virtual int close (void); + + /** + * Called by a thread when it wants to unblock the Reactor_Impl. + * This wakes up the Reactor_Impl if currently blocked. Pass over + * both the Event_Handler and the mask to allow the caller to + * dictate which Event_Handler method the Reactor_Impl will + * invoke. The ACE_Time_Value indicates how long to block + * trying to notify the Reactor_Impl. If timeout == 0, the + * caller will block until action is possible, else will wait until + * the relative time specified in *timeout elapses). + */ + virtual int notify (ACE_Event_Handler *eh = 0, + ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK, + ACE_Time_Value *timeout = 0); + + /// Unimplemented method required by pure virtual method in abstract + /// base class. + /** + * This method's interface is not very compatibile with this + * Reactor's design. It's not clear why this method is pure virtual + * either. + */ + virtual int dispatch_notifications (int &number_of_active_handles, + ACE_Handle_Set &rd_mask); + + /// Returns the ACE_HANDLE of the notify pipe on which the reactor + /// is listening for notifications so that other threads can unblock + /// the Reactor_Impl. + virtual ACE_HANDLE notify_handle (void); + + /// Verify whether the buffer has dispatchable info or not. + virtual int is_dispatchable (ACE_Notification_Buffer &buffer); + + /// Handle one notify call represented in @a buffer. This could be + /// because of a thread trying to unblock the Reactor_Impl. + virtual int dispatch_notify (ACE_Notification_Buffer &buffer); + + /// Read one notify call on the handle into @a buffer. + /// This could be because of a thread trying to unblock the Reactor_Impl. + virtual int read_notify_pipe (ACE_HANDLE handle, + ACE_Notification_Buffer &buffer); + + /// Called back by the ACE_Dev_Poll_Reactor when a thread wants to + /// unblock us. + virtual int handle_input (ACE_HANDLE handle); + + /** + * Set the maximum number of times that the handle_input method + * will iterate and dispatch the ACE_Event_Handlers that are + * passed in via the notify queue before breaking out of the event + * loop. By default, this is set to -1, which means "iterate until + * the queue is empty." Setting this to a value like "1 or 2" will + * increase "fairness" (and thus prevent starvation) at the expense + * of slightly higher dispatching overhead. + */ + virtual void max_notify_iterations (int); + + /** + * Get the maximum number of times that the handle_input method + * will iterate and dispatch the ACE_Event_Handlers that are + * passed in via the notify queue before breaking out of its event + * loop. + */ + virtual int max_notify_iterations (void); + + /** + * Purge any notifications pending in this reactor for the specified + * ACE_Event_Handler object. Returns the number of notifications + * purged. Returns -1 on error. + */ + virtual int purge_pending_notifications ( + ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Dump the state of an object. + virtual void dump (void) const; + +protected: + + /** + * Keep a back pointer to the ACE_Dev_Poll_Reactor. If this value + * if NULL then the ACE_Dev_Poll_Reactor has been initialized with + * disable_notify_pipe. + */ + ACE_Dev_Poll_Reactor *dp_reactor_; + + /** + * Contains the ACE_HANDLE the ACE_Dev_Poll_Reactor is listening + * on, as well as the ACE_HANDLE that threads wanting the attention + * of the ACE_Dev_Poll_Reactor will write to. + */ + ACE_Pipe notification_pipe_; + + /** + * Keeps track of the maximum number of times that the + * ACE_Dev_Poll_Reactor_Notify::handle_input method will iterate and + * dispatch the ACE_Event_Handlers that are passed in via the + * notify pipe before breaking out of its recv loop. By default, + * this is set to -1, which means "iterate until the pipe is empty." + */ + int max_notify_iterations_; + +#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) + /** + * @brief A user-space queue to store the notifications. + * + * The notification pipe has OS-specific size restrictions. That + * is, no more than a certain number of bytes may be stored in the + * pipe without blocking. This limit may be too small for certain + * applications. In this case, ACE can be configured to store all + * the events in user-space. The pipe is still needed to wake up + * the reactor thread, but only one event is sent through the pipe + * at a time. + */ + ACE_Notification_Queue notification_queue_; +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ + +}; + +// --------------------------------------------------------------------- + +/** + * @class ACE_Dev_Poll_Reactor_Handler_Repository + * + * @internal + + * @brief Used to map ACE_HANDLEs onto the appropriate + * ACE_Event_Handler *. + * + * + * This class is simply a container that maps a handle to its + * corresponding event handler. It is not meant for use outside of + * the Dev_Poll_Reactor. + */ +class ACE_Dev_Poll_Reactor_Handler_Repository +{ +public: + + /// Constructor. + ACE_Dev_Poll_Reactor_Handler_Repository (void); + + /// Initialize a repository of the appropriate @a size. + int open (size_t size); + + /// Close down the repository. + int close (void); + + /** + * @name Repository Manipulation Operations + * + * Methods used to search and modify the handler repository. + */ + //@{ + + /** + * Return the @c ACE_Event_Handler associated with @c ACE_HANDLE. If + * @a index_p is non-zero, then return the index location of the + * handle, if found. + */ + ACE_Event_Handler *find (ACE_HANDLE handle, size_t *index_p = 0); + + /// Set the event mask for event handler associated with the given + /// handle. + void mask (ACE_HANDLE handle, ACE_Reactor_Mask mask); + + /// Retrieve the event mask for the event handler associated with + /// the given handle. + ACE_Reactor_Mask mask (ACE_HANDLE handle); + + /// Mark the event handler associated with the given handle as + /// "suspended." + void suspend (ACE_HANDLE handle); + + /// Mark the event handler associated with the given handle as + /// "resumed." + void resume (ACE_HANDLE handle); + + /// Is the event handler for the given handle suspended? + int suspended (ACE_HANDLE handle) const; + + /// Bind the ACE_Event_Handler to the @c ACE_HANDLE with the + /// appropriate ACE_Reactor_Mask settings. + int bind (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask); + + /// Remove the binding for @c ACE_HANDLE; optionally decrement the associated + /// handler's reference count. + int unbind (ACE_HANDLE handle, bool decr_refcnt = true); + + /// Remove all the (@c ACE_HANDLE, @c ACE_Event_Handler) tuples. + int unbind_all (void); + + /** + * @name Sanity Checking + * + * Methods used to prevent "out-of-range" errors when indexing the + * underlying handler array. + */ + //@{ + + // Check the @a handle to make sure it's a valid @c ACE_HANDLE that + // within the range of legal handles (i.e., greater than or equal to + // zero and less than @c max_size_). + int invalid_handle (ACE_HANDLE handle) const; + + // Check the handle to make sure it's a valid @c ACE_HANDLE that is + // within the range of currently registered handles (i.e., greater + // than or equal to zero and less than @c max_handlep1_). + int handle_in_range (ACE_HANDLE handle) const; + + //@} + + /// Returns the current table size. + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /// Maximum number of handles. + int max_size_; + + /// The underlying array of event handlers. + /** + * The array of event handlers is directly indexed directly using + * an @c ACE_HANDLE value. This is Unix-specific. + */ + ACE_Dev_Poll_Event_Tuple *handlers_; + +}; + +// --------------------------------------------------------------------- + +/** + * @class ACE_Dev_Poll_Reactor + * + * @brief A `/dev/poll' or `/dev/epoll' based Reactor implemenatation. + * + * @attention The Linux epoll implementation works quite well and is + * fully supported; however, the /dev/poll implementation is @em experimental. + * + * The ACE_Dev_Poll_Reactor uses the `/dev/poll' or '/dev/epoll' + * character devices to demultiplex events on a given set of file + * descriptors. Unlike @c select(), `/dev/poll' and `/dev/epoll' have + * no hard-coded limit on the number of file descriptors that may be + * handled at any given time. As such, the ACE_Dev_Poll_Reactor can + * generally handle a much larger number of file descriptors than + * @c select() -based reactors. Furthermore, since `/dev/poll' and + * `/dev/epoll' both return a set of file descriptors that are active, + * there is no need to "walk" the set of file descriptors to determine + * which ones are active, such as what is done with the @c select() and + * @c poll() system calls. All returned file descriptors are active. + * This makes event dispatching very efficient. + * + * @note In general, this reactor may only be used to demultiplex + * events on sockets. Demultiplexing events on pipes, for + * example may not work. This is due to a limitation in the + * underlying `/dev/poll' device driver. + * + * @note It is only possible to achieve millisecond timeout + * resolutions with the @c ACE_Dev_Poll_Reactor. However, the + * timeout resolution for timers is independent of the reactors + * timeout resolution. As such, it may be possible to achieve + * sub-millisecond timeout resolutions for timers but that is + * entirely platform dependent. + */ + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +typedef ACE_Token ACE_DEV_POLL_TOKEN; +#else +typedef ACE_Noop_Token ACE_DEV_POLL_TOKEN; +#endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */ +typedef ACE_Reactor_Token_T ACE_Dev_Poll_Reactor_Token; + +class ACE_Export ACE_Dev_Poll_Reactor : public ACE_Reactor_Impl +{ +public: + + /// Initialize @c ACE_Dev_Poll_Reactor with the default size. + /** + * The default size for the @c ACE_Dev_Poll_Reactor is the maximum + * number of open file descriptors for the process. + */ + ACE_Dev_Poll_Reactor (ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + int disable_notify_pipe = 0, + ACE_Reactor_Notify *notify = 0, + int mask_signals = 1, + int s_queue = ACE_DEV_POLL_TOKEN::FIFO); + + /// Initialize ACE_Dev_Poll_Reactor with size @a size. + /** + * @note On Unix platforms, the @a size parameter should be as large + * as the maximum number of file descriptors allowed for a + * given process. This is necessary since a file descriptor + * is used to directly index the array of event handlers + * maintained by the Reactor's handler repository. Direct + * indexing is used for efficiency reasons. If the size + * parameter is less than the process maximum, the process + * maximum will be decreased in order to prevent potential + * access violations. + */ + ACE_Dev_Poll_Reactor (size_t size, + int restart = 0, + ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + int disable_notify_pipe = 0, + ACE_Reactor_Notify *notify = 0, + int mask_signals = 1, + int s_queue = ACE_DEV_POLL_TOKEN::FIFO); + + /// Close down and release all resources. + virtual ~ACE_Dev_Poll_Reactor (void); + + /// Initialization. + virtual int open (size_t size, + int restart = 0, + ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + int disable_notify_pipe = 0, + ACE_Reactor_Notify * = 0); + + /** + * @param handle allows the reactor to check if the caller is + * valid. + * + * @return 0 if the size of the current message has been put in + * size. -1 if not. + */ + virtual int current_info (ACE_HANDLE handle, size_t & /* size */); + + /// Use a user specified signal handler instead. + virtual int set_sig_handler (ACE_Sig_Handler *signal_handler); + + /// Set a user-specified timer queue. + virtual int timer_queue (ACE_Timer_Queue *tq); + + /// Get the timer queue + /// @return The current @c ACE_Timer_Queue. + virtual ACE_Timer_Queue *timer_queue (void) const; + + /// Close down and release all resources. + virtual int close (void); + + // = Event loop drivers. + /** + * Returns non-zero if there are I/O events "ready" for dispatching, + * but does not actually dispatch the event handlers. By default, + * don't block while checking this, i.e., "poll". + * + * @note It is only possible to achieve millisecond timeout + * resolutions with the @c ACE_Dev_Poll_Reactor. + */ + virtual int work_pending ( + const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero); + + /** + * This event loop driver blocks for up to @a max_wait_time before + * returning. It will return earlier if events occur. Note that + * @a max_wait_time can be 0, in which case this method blocks + * indefinitely until events occur. + * @par + * @a max_wait_time is decremented to reflect how much time this + * call took. For instance, if a time value of 3 seconds is passed + * to @c handle_events() and an event occurs after 2 seconds, + * @a max_wait_time will equal 1 second. This can be used if an + * application wishes to handle events for some fixed amount of + * time. + * @par + * The only difference between @c alertable_handle_events() and + * handle_events() is that in the alertable case, the event loop + * will return when the system queues an I/O completion routine or + * an Asynchronous Procedure Call. + * + * @return The total number of @c ACE_Event_Handlers that were + * dispatched, 0 if the @a max_wait_time elapsed without + * dispatching any handlers, or -1 if an error occurs. + + * @note It is only possible to achieve millisecond timeout + * resolutions with the @c ACE_Dev_Poll_Reactor. + */ + virtual int handle_events (ACE_Time_Value *max_wait_time = 0); + virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0); + + /** + * This method is just like the one above, except the + * @a max_wait_time value is a reference and can therefore never be + * @c NULL. + * + * @note It is only possible to achieve millisecond timeout + * resolutions with the @c ACE_Dev_Poll_Reactor. + */ + virtual int handle_events (ACE_Time_Value &max_wait_time); + virtual int alertable_handle_events (ACE_Time_Value &max_wait_time); + + // = Event handling control. + + /** + * @return The status of Reactor. If this function returns 0, the + * reactor is actively handling events. If it returns + * non-zero, @c handle_events() and + * @c handle_alertable_events() return -1 immediately. + */ + virtual int deactivated (void); + + /** + * Control whether the Reactor will handle any more incoming events + * or not. If @a do_stop == 1, the Reactor will be disabled. By + * default, a reactor is in active state and can be + * deactivated/reactived as desired. + */ + virtual void deactivate (int do_stop); + + // = Register and remove Handlers. + + /// Register @a event_handler with @a mask. The I/O handle will + /// always come from get_handle on the event_handler. + virtual int register_handler (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /// Register @a event_handler with @a mask. The I/O handle is + /// provided through the @a io_handle parameter. + virtual int register_handler (ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * Register an @a event_handler that will be notified when + * @a event_handle is signaled. @a mask specifies the network + * events that the @a event_handler is interested in. + */ + virtual int register_handler (ACE_HANDLE event_handle, + ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /// Register @a event_handler> with all the @a handles> in the @c + /// Handle_Set. + virtual int register_handler (const ACE_Handle_Set &handles, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * Register @a new_sh to handle the signal @a signum using the + * @a new_disp. Returns the @a old_sh that was previously + * registered (if any), along with the @a old_disp of the signal + * handler. + */ + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + + /// Registers to handle a set of signals using the + /// . + virtual int register_handler (const ACE_Sig_Set &sigset, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0); + + /// Removes @a event_handler. + /** + * @note The I/O handle will be obtained using @c get_handle() + * method of @a event_handler . If @a mask == + * @c ACE_Event_Handler::DONT_CALL then the @c handle_close() + * method of the @a event_handler is not invoked. + */ + virtual int remove_handler (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * Removes @a handle. If @a mask == ACE_Event_Handler::DONT_CALL + * then the method of the associated + * is not invoked. + */ + virtual int remove_handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask); + + /** + * Removes all handles in . If @a mask == + * ACE_Event_Handler::DONT_CALL then the method of + * the associated s is not invoked. + */ + virtual int remove_handler (const ACE_Handle_Set &handle_set, + ACE_Reactor_Mask mask); + + /** + * Remove the ACE_Event_Handler currently associated with @a signum. + * Install the new disposition (if given) and return the previous + * disposition (if desired by the caller). Returns 0 on success and + * -1 if @a signum is invalid. + */ + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + + /// Calls for every signal in . + virtual int remove_handler (const ACE_Sig_Set &sigset); + + // = Suspend and resume Handlers. + + /// Suspend event_handler temporarily. Use + /// ACE_Event_Handler::get_handle() to get the handle. + virtual int suspend_handler (ACE_Event_Handler *event_handler); + + /// Suspend handle temporarily. + virtual int suspend_handler (ACE_HANDLE handle); + + /// Suspend all handles in handle set temporarily. + virtual int suspend_handler (const ACE_Handle_Set &handles); + + /// Suspend all handles temporarily. + virtual int suspend_handlers (void); + + /// Resume event_handler. Use ACE_Event_Handler::get_handle() to + /// get the handle. + virtual int resume_handler (ACE_Event_Handler *event_handler); + + /// Resume handle. + virtual int resume_handler (ACE_HANDLE handle); + + /// Resume all handles in handle set. + virtual int resume_handler (const ACE_Handle_Set &handles); + + /// Resume all handles. + virtual int resume_handlers (void); + + /// Does the reactor allow the application to resume the handle on + /// its own, i.e., can it pass on the control of handle resumption to + /// the application. + virtual int resumable_handler (void); + + /// Return 1 if we any event associations were made by the reactor + /// for the handles that it waits on, 0 otherwise. + virtual int uses_event_associations (void); + + // = Timer management. + + /** + * Schedule an ACE_Event_Handler that will expire after an amount + * of time. The return value of this method, a timer_id value, + * uniquely identifies the event_handler in the ACE_Reactor's + * internal list of timers. + * This timer_id value can be used to cancel the timer + * with the cancel_timer() call. + * + * @see cancel_timer() + * @see reset_timer_interval() + * + * @param event_handler event handler to schedule on reactor + * @param arg argument passed to the handle_timeout() method of + * event_handler. + * @param delay time interval after which the timer will expire. + * @param interval time interval for which the timer will be + * automatically rescheduled. + * @return -1 on failure, a timer_id value on success + */ + virtual long schedule_timer (ACE_Event_Handler *event_handler, + const void *arg, + const ACE_Time_Value &delay, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /** + * Resets the interval of the timer represented by @a timer_id to + * @a interval, which is specified in relative time to the current + * . If @a interval is equal to + * ACE_Time_Value::zero, the timer will become a non-rescheduling + * timer. Returns 0 if successful, -1 if not. + */ + virtual int reset_timer_interval (long timer_id, + const ACE_Time_Value &interval); + + /// Cancel all Event_Handlers that match the address of + /// @a event_handler. Returns number of handlers cancelled. + virtual int cancel_timer (ACE_Event_Handler *event_handler, + int dont_call_handle_close = 1); + + /** + * Cancel the single event handler that matches the @a timer_id value + * (which was returned from the schedule method). If @a arg is + * non-NULL then it will be set to point to the ``magic cookie'' + * argument passed in when the event handler was registered. This + * makes it possible to free up the memory and avoid memory leaks. + * Returns 1 if cancellation succeeded and 0 if the @a timer_id + * wasn't found. + */ + virtual int cancel_timer (long timer_id, + const void **arg = 0, + int dont_call_handle_close = 1); + + // = High-level event handler scheduling operations + + /// Add @a masks_to_be_added to the @a event_handler's entry. + /// @a event_handler must already have been registered. + virtual int schedule_wakeup (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks_to_be_added); + + /// Add @a masks_to_be_added to the @a handle's entry. + /// associated with @a handle must already have been registered. + virtual int schedule_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask masks_to_be_added); + + /// Clear @a masks_to_be_cleared from the @a event_handler's entry. + virtual int cancel_wakeup (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks_to_be_cleared); + + /// Clear @a masks_to_be_cleared from the @a handle's entry. + virtual int cancel_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask masks_to_be_cleared); + + // = Notification methods. + + /** + * Notify @a event_handler of @a mask event. The ACE_Time_Value + * indicates how long to blocking trying to notify. If @a timeout == + * 0, the caller will block until action is possible, else will wait + * until the relative time specified in @a timeout elapses). + */ + virtual int notify (ACE_Event_Handler *event_handler = 0, + ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK, + ACE_Time_Value * = 0); + + /** + * Set the maximum number of times that ACE_Reactor_Impl will + * iterate and dispatch the that are passed in + * via the notify queue before breaking out of its + * loop. By default, this is set to + * -1, which means "iterate until the queue is empty." Setting this + * to a value like "1 or 2" will increase "fairness" (and thus + * prevent starvation) at the expense of slightly higher dispatching + * overhead. + */ + virtual void max_notify_iterations (int); + + /** + * Get the maximum number of times that the ACE_Reactor_Impl will + * iterate and dispatch the that are passed in + * via the notify queue before breaking out of its + * loop. + */ + virtual int max_notify_iterations (void); + + /** + * Purge any notifications pending in this reactor for the specified + * ACE_Event_Handler object. Returns the number of notifications + * purged. Returns -1 on error. + */ + virtual int purge_pending_notifications (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /** + * Return the Event_Handler associated with @a handle. Return 0 if + * @a handle is not registered. + */ + virtual ACE_Event_Handler *find_handler (ACE_HANDLE handle); + + /** + * Check to see if @a handle is associated with a valid Event_Handler + * bound to @a mask. Return the @a event_handler associated with this + * @c handler if @a event_handler != 0. + */ + virtual int handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **event_handler = 0); + + /** + * Check to see if @a signum is associated with a valid Event_Handler + * bound to a signal. Return the @a event_handler associated with + * this @c handler if @a event_handler != 0. + */ + virtual int handler (int signum, + ACE_Event_Handler ** = 0); + + /// Returns true if Reactor has been successfully initialized, else + /// false. + virtual bool initialized (void); + + /// Returns the current size of the Reactor's internal descriptor + /// table. + virtual size_t size (void) const; + + /// Returns a reference to the Reactor's internal lock. + virtual ACE_Lock &lock (void); + + /// Wake up all threads waiting in the event loop. + virtual void wakeup_all_threads (void); + + /// Transfers ownership of Reactor_Impl to the new_owner. + /** + * @note There is no need to set the owner of the event loop for the + * ACE_Dev_Poll_Reactor. Multiple threads may invoke the + * event loop simulataneously. As such, this method is a + * no-op. + */ + virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0); + + /// Return the ID of the "owner" thread. + /** + * @note There is no need to set the owner of the event loop for the + * ACE_Dev_Poll_Reactor. Multiple threads may invoke the + * event loop simulataneously. As such, this method is a + * no-op. + */ + virtual int owner (ACE_thread_t *owner); + + /// Get the existing restart value. + virtual int restart (void); + + /// Set a new value for restart and return the original value. + /** + * @param r If zero, then the event loop will not be automatically + * restarted if the underlying poll is interrupted via the + * INTR (interrupt) signal. + * + * @return Returns the previous "restart" value. + */ + virtual int restart (int r); + + /// Set position of the owner thread. + /** + * @note This is currently a no-op. + */ + virtual void requeue_position (int); + + /// Get position of the owner thread. + /** + * @note This is currently a no-op. + */ + virtual int requeue_position (void); + + /** + * @name Low-level wait_set mask manipulation methods + * + * Low-level methods to manipulate the event/reactor mask associated + * with a handle and event handler when polling for events. + * @par + * The "interest set," i.e. the wait set, can be directly + * manipulated with these methods. + */ + //@{ + + /// GET/SET/ADD/CLR the dispatch mask "bit" bound with the + /// event_handler and mask. + /** + * @return Old mask on success, -1 on error. + */ + virtual int mask_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + int ops); + + /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle + /// and mask. + /** + * @return Old mask on success, -1 on error. + */ + virtual int mask_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops); + + //@} + + /** + * @name Low-level ready_set mask manipulation methods + * + * These methods are unimplemented. + */ + //@{ + + /// GET/SET/ADD/CLR the ready "bit" bound with the event_handler + /// and mask. + virtual int ready_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + int ops); + + /// GET/SET/ADD/CLR the ready "bit" bound with the handle and mask. + virtual int ready_ops (ACE_HANDLE handle, + ACE_Reactor_Mask, + int ops); + + //@} + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + + class Token_Guard; + + /// Non-locking version of wait_pending(). + /** + * Returns non-zero if there are I/O events "ready" for dispatching, + * but does not actually dispatch the event handlers. By default, + * don't block while checking this, i.e., "poll". + * + * @note It is only possible to achieve millisecond timeout + * resolutions with the ACE_Dev_Poll_Reactor. + */ + int work_pending_i (ACE_Time_Value *max_wait_time); + + /// Poll for events and return the number of event handlers that + /// were dispatched. + /** + * This is a helper method called by all handle_events() methods. + */ + int handle_events_i (ACE_Time_Value *max_wait_time, Token_Guard &guard); + + /// Perform the upcall with the given event handler method. + int upcall (ACE_Event_Handler *event_handler, + int (ACE_Event_Handler::*callback)(ACE_HANDLE), + ACE_HANDLE handle); + + /** + * Dispatch ACE_Event_Handlers for time events, I/O events, and + * signal events. Returns the total number of ACE_Event_Handlers + * that were dispatched or -1 if something goes wrong. + */ + int dispatch (Token_Guard &guard); + + /// Dispatch a single timer, if ready. + /// Returns: 0 if no timers ready (token still held), + /// 1 if a timer was expired (token released), + /// -1 on error (token still held). + int dispatch_timer_handler (Token_Guard &guard); + + /// Dispatch an IO event to the corresponding event handler. Returns + /// Returns: 0 if no events ready (token still held), + /// 1 if an event was expired (token released), + /// -1 on error (token still held). + int dispatch_io_event (Token_Guard &guard); + + /// Register the given event handler with the reactor. + int register_handler_i (ACE_HANDLE handle, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + + /// Remove the event handler associated with the given handle and + /// event mask from the "interest set." + int remove_handler_i (ACE_HANDLE handle, ACE_Reactor_Mask mask); + + /// Temporarily remove the given handle from the "interest set." + int suspend_handler_i (ACE_HANDLE handle); + + /// Place the given handle that was temporarily removed from the + /// "interest set," i.e that was suspended, back in to the interest + /// set. The given handle will once again be polled for events. + int resume_handler_i (ACE_HANDLE handle); + + /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle + /// and mask. This internal helper method acquires no lock. + /** + * @return Old mask on success, -1 on error. + */ + int mask_ops_i (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops); + + /// Convert a reactor mask to its corresponding poll() event mask. + short reactor_mask_to_poll_event (ACE_Reactor_Mask mask); + +protected: + + /// Has the reactor been initialized. + bool initialized_; + + /// The file descriptor associated with the open `/dev/poll' or + /// `/dev/epoll' device. + /** + * All interactions with the `/dev/poll' or `/dev/epoll' device are + * done through this file descriptor. + */ + ACE_HANDLE poll_fd_; + + /// The maximum number of file descriptors over which demultiplexing + /// will occur. + size_t size_; + + /// Track HANDLES we are interested in for various events that must + /// be dispatched *without* polling. + /// ACE_Dev_Poll_Ready_Set ready_set_; + +#if defined (ACE_HAS_EVENT_POLL) + /// Table of event structures to be filled by epoll_wait: + struct epoll_event *events_; + + /// Pointer to the next epoll_event array element that contains the next + /// event to be dispatched. + struct epoll_event *start_pevents_; + + /// The last element in the event array plus one. + /** + * The loop that dispatches IO events stops when this->start_pevents_ == + * this->end_pevents_. + */ + struct epoll_event *end_pevents_; + +#else + /// The pollfd array that `/dev/poll' will feed its results to. + struct pollfd *dp_fds_; + + + /// Pointer to the next pollfd array element that contains the next + /// event to be dispatched. + struct pollfd *start_pfds_; + + /// The last element in the pollfd array plus one. + /** + * The loop that dispatches IO events stops when this->start_pfds == + * this->end_pfds_. + */ + struct pollfd *end_pfds_; +#endif /* ACE_HAS_EVENT_POLL */ + + /// This flag is used to keep track of whether we are actively handling + /// events or not. + sig_atomic_t deactivated_; + + /// Lock used for synchronization of reactor state. + ACE_Dev_Poll_Reactor_Token token_; + + /// Adapter used to return internal lock to outside world. + ACE_Lock_Adapter lock_adapter_; + + /// The repository that contains all registered event handlers. + ACE_Dev_Poll_Reactor_Handler_Repository handler_rep_; + + /// Defined as a pointer to allow overriding by derived classes... + ACE_Timer_Queue *timer_queue_; + + /// Keeps track of whether we should delete the timer queue (if we + /// didn't create it, then we don't delete it). + bool delete_timer_queue_; + + /// Handle signals without requiring global/static variables. + ACE_Sig_Handler *signal_handler_; + + /// Keeps track of whether we should delete the signal handler (if we + /// didn't create it, then we don't delete it). + bool delete_signal_handler_; + + /// Callback object that unblocks the if it's + /// sleeping. + ACE_Reactor_Notify *notify_handler_; + + /// Keeps track of whether we need to delete the notify handler (if + /// we didn't create it, then we don't delete it). + bool delete_notify_handler_; + + /// Flag that determines if signals are masked during event + /// dispatching. + /** + * If 0 then the Reactor will not mask the signals during the event + * dispatching. This is useful for applications that do not + * register any signal handlers and want to reduce the overhead + * introduce by the kernel level locks required to change the mask. + */ + int mask_signals_; + + /// Restart the handle_events event loop method automatically when + /// polling function in use (ioctl() in this case) is interrupted + /// via an EINTR signal. + int restart_; + +protected: + + /** + * @class Token_Guard + * + * @brief A helper class that helps grabbing, releasing and waiting + * on tokens for a thread that needs access to the reactor's token. + */ + class ACE_Export Token_Guard + { + public: + + /// Constructor that will grab the token for us + Token_Guard (ACE_Dev_Poll_Reactor_Token &token); + + /// Destructor. This will release the token if it hasn't been + /// released till this point + ~Token_Guard (void); + + /// Release the token .. + void release_token (void); + + /// Returns whether the thread that created this object owns the + /// token or not. + int is_owner (void); + + /// A helper method that acquires the token 1) at a low priority, and + /// 2) wait quietly for the token, not waking another thread. This + /// is appropriate for cases where a thread wants to wait for and + /// dispatch an event, not causing an existing waiter to relinquish the + /// token, and also queueing up behind other threads waiting to modify + /// event records. + int acquire_quietly (ACE_Time_Value *max_wait = 0); + + /// A helper method that acquires the token at a high priority, and + /// does wake the current token holder. + int acquire (ACE_Time_Value *max_wait = 0); + + private: + + Token_Guard (void); + + private: + + /// The Reactor token. + ACE_Dev_Poll_Reactor_Token &token_; + + /// Flag that indicate whether the thread that created this object + /// owns the token or not. A value of 0 indicates that this class + /// hasn't got the token (and hence the thread) and a value of 1 + /// vice-versa. + int owner_; + + }; + +}; + + +/** + * @class ACE_Dev_Poll_Handler_Guard + * + * @brief Class used to make event handler reference count + * manipulation exception-safe. + * + * This class makes the reference count manipulation that occurs + * during an upcall exception-safe. Prior to dispatching the event + * handler, the reference count is increased. Once the upcall for the + * given event handler is complete, its reference count will be decreased. + */ +class ACE_Dev_Poll_Handler_Guard +{ +public: + + /// Constructor + /** + * The constructor checks to see if @a eh is a reference-counted handler and + * remember that for later. If @a eh is reference counted, its reference + * count is incremented unless @a do_incr is false. + * @a do_incr should be false if the reference count was incremented + * independently of this guard, for example, on a notify handler since + * the reference count is incremented when the notify is queued. + */ + ACE_Dev_Poll_Handler_Guard (ACE_Event_Handler *eh, bool do_incr = true); + + /// Destructor + /** + * The destructor decrements the reference count on the event + * handler corresponding to the given handle. + */ + ~ACE_Dev_Poll_Handler_Guard (void); + + /// Release the event handler from this guard; when the destructor is + /// called, the handler's reference count will not be decremented. + void release (void); + +private: + + /// The event handler being managed. + ACE_Event_Handler *eh_; + + /// true if eh_ is a reference-counted handler. + bool refcounted_; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/Dev_Poll_Reactor.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */ + +#include /**/ "ace/post.h" + +#endif /* ACE_DEV_POLL_REACTOR_H */ diff --git a/dep/ACE_wrappers/ace/Dev_Poll_Reactor.inl b/dep/ACE_wrappers/ace/Dev_Poll_Reactor.inl new file mode 100644 index 000000000..96e71f2de --- /dev/null +++ b/dep/ACE_wrappers/ace/Dev_Poll_Reactor.inl @@ -0,0 +1,228 @@ +// -*- C++ -*- +// +// $Id: Dev_Poll_Reactor.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Log_Msg.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Dev_Poll_Event_Tuple::ACE_Dev_Poll_Event_Tuple (void) + : event_handler (0), + mask (ACE_Event_Handler::NULL_MASK), + suspended (0) +{ +} + +// --------------------------------------------------------------------- + +#if 0 +ACE_INLINE +ACE_Dev_Poll_Ready_Set::ACE_Dev_Poll_Ready_Set (void) + : pfds (0), + nfds (0) +{ +} +#endif /* 0 */ + +// --------------------------------------------------------------------- + +ACE_INLINE void +ACE_Dev_Poll_Reactor_Handler_Repository::mask (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::mask"); + + // Only bother to search for the handle if it's in range. + if (this->handle_in_range (handle)) + this->handlers_[handle].mask = mask; +} + +ACE_INLINE ACE_Reactor_Mask +ACE_Dev_Poll_Reactor_Handler_Repository::mask (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::mask"); + + ACE_Reactor_Mask mask = ACE_Event_Handler::NULL_MASK; + + // Only bother to search for the handle if it's in range. + if (this->handle_in_range (handle)) + mask = this->handlers_[handle].mask; + + if (mask == ACE_Event_Handler::NULL_MASK) + errno = ENOENT; + + return mask; +} + +ACE_INLINE void +ACE_Dev_Poll_Reactor_Handler_Repository::suspend (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::suspend"); + + // Only bother to search for the handle if it's in range. + if (this->handle_in_range (handle)) + this->handlers_[handle].suspended = 1; +} + +ACE_INLINE void +ACE_Dev_Poll_Reactor_Handler_Repository::resume (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::resume"); + + // Only bother to search for the handle if it's in range. + if (this->handle_in_range (handle)) + this->handlers_[handle].suspended = 0; +} + +ACE_INLINE int +ACE_Dev_Poll_Reactor_Handler_Repository::suspended (ACE_HANDLE handle) const +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::suspended"); + + if (this->handle_in_range (handle)) + return this->handlers_[handle].suspended; + + return -1; +} + +ACE_INLINE size_t +ACE_Dev_Poll_Reactor_Handler_Repository::size (void) const +{ + ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::size"); + + return this->max_size_; +} + +// ----------------------------------------------------------------- + +ACE_INLINE +ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard + (ACE_Event_Handler *eh, + bool do_incr) + : eh_ (eh), + refcounted_ (false) +{ + if (eh == 0) + return; + + this->refcounted_ = + eh->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + if (do_incr && this->refcounted_) + eh->add_reference (); + + /** + * The below comments were here when I replaced the old refcount + * scheme was replaced. They may still need addressing. -Steve Huston + */ + + /** + * @todo Suspend the handler so that other threads will not cause + * an event that is already in an upcall from being dispatched + * again. + * + * @note The naive approach would be to simply call + * suspend_handler_i() on the reactor. However, that would + * cause a system call (write()) to occur. Obviously this + * can potentially have an adverse affect on performance. + * Ideally, the handler would only be marked as "suspended" in + * the handler repository. If an event arrives for a + * suspended handler that event can be "queued" in a + * "handle readiness queue." "Queued" is quoted since a real + * queue need not be used since duplicate events can be + * coalesced, thus avoiding unbounded queue growth. Event + * coalescing is already done by Linux's event poll driver + * (/dev/epoll) so Solaris' poll driver (/dev/poll) is the + * main concern here. The largest the queue can be is the + * same size as the number of handlers stored in the handler + * repository. + */ +} + +ACE_INLINE +ACE_Dev_Poll_Handler_Guard::~ACE_Dev_Poll_Handler_Guard (void) +{ + if (this->refcounted_ && this->eh_ != 0) + this->eh_->remove_reference (); + + /** + * The below comments were here when I replaced the old refcount + * scheme was replaced. They may still need addressing. -Steve Huston + */ + /** + * @todo Resume the handler so that other threads will be allowed to + * dispatch the handler. + */ +} + +ACE_INLINE void +ACE_Dev_Poll_Handler_Guard::release (void) +{ + this->eh_ = 0; +} + +// --------------------------------------------------------------------- + +ACE_INLINE int +ACE_Dev_Poll_Reactor::upcall (ACE_Event_Handler *event_handler, + int (ACE_Event_Handler::*callback)(ACE_HANDLE), + ACE_HANDLE handle) +{ + // If the handler returns positive value (requesting a reactor + // callback) just call back as many times as the handler requests + // it. Other threads are off handling other things. + int status = 0; + + do + { + status = (event_handler->*callback) (handle); + } + while (status > 0); + + return status; +} + + +/************************************************************************/ +// Methods for ACE_Dev_Poll_Reactor::Token_Guard +/************************************************************************/ + +ACE_INLINE +ACE_Dev_Poll_Reactor::Token_Guard::Token_Guard (ACE_Dev_Poll_Reactor_Token &token) + + : token_ (token), + owner_ (0) +{ +} + +ACE_INLINE +ACE_Dev_Poll_Reactor::Token_Guard::~Token_Guard (void) +{ + if (this->owner_ == 1) + { + ACE_MT (this->token_.release ()); + this->owner_ = 0; + } +} + +ACE_INLINE void +ACE_Dev_Poll_Reactor::Token_Guard::release_token (void) +{ + if (this->owner_) + { + ACE_MT (this->token_.release ()); + + // We are not the owner anymore.. + this->owner_ = 0; + } +} + +ACE_INLINE int +ACE_Dev_Poll_Reactor::Token_Guard::is_owner (void) +{ + return this->owner_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dirent.cpp b/dep/ACE_wrappers/ace/Dirent.cpp new file mode 100644 index 000000000..df1290e1e --- /dev/null +++ b/dep/ACE_wrappers/ace/Dirent.cpp @@ -0,0 +1,7 @@ +// $Id: Dirent.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Dirent.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Dirent.inl" +#endif /* __ACE_INLINE__ */ diff --git a/dep/ACE_wrappers/ace/Dirent.h b/dep/ACE_wrappers/ace/Dirent.h new file mode 100644 index 000000000..2dd5d0a19 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dirent.h @@ -0,0 +1,122 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dirent.h + * + * $Id: Dirent.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Define a portable C++ interface to ACE_OS_Dirent directory-entry + * manipulation. + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_DIRENT_H +#define ACE_DIRENT_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_dirent.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dirent + * + * @brief Define a portable C++ directory-entry iterator based on the POSIX API. + */ +class ACE_Export ACE_Dirent +{ +public: + // = Initialization and termination methods. + /// Default constructor. + ACE_Dirent (void); + + /// Constructor calls + explicit ACE_Dirent (const ACE_TCHAR *dirname); + + /// Opens the directory named by filename and associates a directory + /// stream with it. + int open (const ACE_TCHAR *filename); + + /// Destructor calls . + ~ACE_Dirent (void); + + /// Closes the directory stream and frees the structure. + void close (void); + + // = Iterator methods. + /** + * Returns a pointer to a structure representing the directory entry + * at the current position in the directory stream to which dirp + * refers, and positions the directory stream at the next entry, + * except on read-only filesystems. It returns a NULL pointer upon + * reaching the end of the directory stream, or upon detecting an + * invalid location in the directory. shall not return + * directory entries containing empty names. It is unspecified + * whether entries are returned for dot or dot-dot. The pointer + * returned by points to data that may be overwritten by + * another call to on the same directory stream. This + * data shall not be overwritten by another call to on a + * different directory stream. may buffer several + * directory entries per actual read operation; marks for + * update the st_atime field of the directory each time the + * directory is actually read. + */ + ACE_DIRENT *read (void); + + /** + * Has the equivalent functionality as except that an + * @a entry and @a result buffer must be supplied by the caller to + * store the result. + */ + int read (struct ACE_DIRENT *entry, + struct ACE_DIRENT **result); + + // = Manipulators. + /// Returns the current location associated with the directory + /// stream. + long tell (void); + + /** + * Sets the position of the next operation on the + * directory stream. The new position reverts to the position + * associated with the directory stream at the time the + * operation that provides loc was performed. Values returned by + * are good only for the lifetime of the pointer from + * which they are derived. If the directory is closed and then + * reopened, the value may be invalidated due to + * undetected directory compaction. It is safe to use a previous + * value immediately after a call to and before + * any calls to readdir. + */ + void seek (long loc); + + /** + * Resets the position of the directory stream to the beginning of + * the directory. It also causes the directory stream to refer to + * the current state of the corresponding directory, as a call to + * would. + */ + void rewind (void); + +private: + /// Pointer to the directory stream. + ACE_DIR *dirp_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Dirent.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DIRENT_H */ diff --git a/dep/ACE_wrappers/ace/Dirent.inl b/dep/ACE_wrappers/ace/Dirent.inl new file mode 100644 index 000000000..01ce3a96c --- /dev/null +++ b/dep/ACE_wrappers/ace/Dirent.inl @@ -0,0 +1,99 @@ +// -*- C++ -*- +// +// $Id: Dirent.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Log_Msg.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_Dirent::open (const ACE_TCHAR *dirname) +{ + // If the directory stream is already open, close it to prevent + // possible resource leaks. + + if (this->dirp_ != 0) + { + ACE_OS::closedir (this->dirp_); + this->dirp_ = 0; + } + + this->dirp_ = ACE_OS::opendir (dirname); + + if (this->dirp_ == 0) + return -1; + else + return 0; +} + +ACE_INLINE +ACE_Dirent::ACE_Dirent (void) + : dirp_ (0) +{ +} + +ACE_INLINE +ACE_Dirent::ACE_Dirent (const ACE_TCHAR *dirname) + : dirp_ (0) +{ + if (this->open (dirname) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Dirent::ACE_Dirent"))); +} + +ACE_INLINE +ACE_Dirent::~ACE_Dirent (void) +{ + if (this->dirp_ != 0) + ACE_OS::closedir (this->dirp_); +} + +ACE_INLINE ACE_DIRENT * +ACE_Dirent::read (void) +{ + return this->dirp_ ? ACE_OS::readdir (this->dirp_) : 0; +} + +ACE_INLINE int +ACE_Dirent::read (struct ACE_DIRENT *entry, + struct ACE_DIRENT **result) +{ + return this->dirp_ + ? ACE_OS::readdir_r (this->dirp_, entry, result) + : 0; +} + +ACE_INLINE void +ACE_Dirent::close (void) +{ + if (this->dirp_ != 0) + { + ACE_OS::closedir (this->dirp_); + + // Prevent double closure + this->dirp_ = 0; + } +} + +ACE_INLINE void +ACE_Dirent::rewind (void) +{ + if (this->dirp_) + ACE_OS::rewinddir (this->dirp_); +} + +ACE_INLINE void +ACE_Dirent::seek (long loc) +{ + if (this->dirp_) + ACE_OS::seekdir (this->dirp_, loc); +} + +ACE_INLINE long +ACE_Dirent::tell (void) +{ + return this->dirp_ ? ACE_OS::telldir (this->dirp_) : 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dirent_Selector.cpp b/dep/ACE_wrappers/ace/Dirent_Selector.cpp new file mode 100644 index 000000000..8fcb5775b --- /dev/null +++ b/dep/ACE_wrappers/ace/Dirent_Selector.cpp @@ -0,0 +1,59 @@ +// $Id: Dirent_Selector.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Dirent_Selector.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Dirent_Selector.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/OS_NS_dirent.h" +#include "ace/OS_NS_stdlib.h" + +ACE_RCSID (ace, + Dirent_Selector, + "$Id: Dirent_Selector.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Construction/Destruction + +ACE_Dirent_Selector::ACE_Dirent_Selector (void) + : namelist_ (0), + n_ (0) +{ +} + +ACE_Dirent_Selector::~ACE_Dirent_Selector (void) +{ + // Free up any allocated resources. + this->close(); +} + +int +ACE_Dirent_Selector::open (const ACE_TCHAR *dir, + ACE_SCANDIR_SELECTOR sel, + ACE_SCANDIR_COMPARATOR cmp) +{ + n_ = ACE_OS::scandir (dir, &this->namelist_, sel, cmp); + return n_; +} + +int +ACE_Dirent_Selector::close (void) +{ + for (--n_; n_ >= 0; --n_) + { +#if defined (ACE_LACKS_STRUCT_DIR) + // Only the lacking-struct-dir emulation allocates this. Native + // scandir includes d_name in the dirent struct itself. + ACE_OS::free (this->namelist_[n_]->d_name); +#endif + ACE_OS::free (this->namelist_[n_]); + } + + ACE_OS::free (this->namelist_); + this->namelist_ = 0; + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dirent_Selector.h b/dep/ACE_wrappers/ace/Dirent_Selector.h new file mode 100644 index 000000000..20673c473 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dirent_Selector.h @@ -0,0 +1,75 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dirent_Selector.h + * + * $Id: Dirent_Selector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Define a portable C++ interface to the method. + * + * @author Rich Newman + */ +//============================================================================= + +#ifndef ACE_DIRENT_SELECTOR_H +#define ACE_DIRENT_SELECTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_dirent.h" /* Need ACE_SCANDIR_SELECTOR, COMPARATOR */ +#include "ace/os_include/os_dirent.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dirent_Selector + * + * @brief Define a portable C++ directory-entry iterator based on the + * POSIX scandir API. + */ +class ACE_Export ACE_Dirent_Selector +{ +public: + /// Constructor + ACE_Dirent_Selector (void); + + /// Destructor. + virtual ~ACE_Dirent_Selector (void); + + /// Return the length of the list of matching directory entries. + int length (void) const; + + /// Return the entry at @a index. + ACE_DIRENT *operator[] (const int index) const; + + /// Free up resources. + int close (void); + + /// Open the directory @a dir and populate the current list of names with + /// directory entries that match the @a selector and @a comparator. + int open (const ACE_TCHAR *dir, + ACE_SCANDIR_SELECTOR selector = 0, + ACE_SCANDIR_COMPARATOR comparator = 0); + +protected: + /// Ptr to the namelist array. + ACE_DIRENT **namelist_; + + /// Number of entries in the array. + int n_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Dirent_Selector.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DIRENT_SELECTOR_H */ diff --git a/dep/ACE_wrappers/ace/Dirent_Selector.inl b/dep/ACE_wrappers/ace/Dirent_Selector.inl new file mode 100644 index 000000000..15f804704 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dirent_Selector.inl @@ -0,0 +1,19 @@ +// -*- C++ -*- +// +// $Id: Dirent_Selector.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_Dirent_Selector::length (void) const +{ + return n_; +} + +ACE_INLINE ACE_DIRENT * +ACE_Dirent_Selector::operator[] (const int n) const +{ + return this->namelist_[n]; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dump.cpp b/dep/ACE_wrappers/ace/Dump.cpp new file mode 100644 index 000000000..6e5c2d0c3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dump.cpp @@ -0,0 +1,141 @@ +// $Id: Dump.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Dump.h" +#include "ace/Guard_T.h" +#include "ace/Thread_Mutex.h" +#include "ace/Object_Manager.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, Dump, "$Id: Dump.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Implementations (very simple for now...) + +ACE_Dumpable::~ACE_Dumpable (void) +{ + ACE_TRACE ("ACE_Dumpable::~ACE_Dumpable"); +} + +ACE_Dumpable::ACE_Dumpable (const void *this_ptr) + : this_ (this_ptr) +{ + ACE_TRACE ("ACE_Dumpable::ACE_Dumpable"); +} + +ACE_Dumpable_Ptr::ACE_Dumpable_Ptr (const ACE_Dumpable *dumper) + : dumper_ (dumper) +{ + ACE_TRACE ("ACE_Dumpable_Ptr::ACE_Dumpable_Ptr"); +} + +const ACE_Dumpable * +ACE_Dumpable_Ptr::operator->() const +{ + ACE_TRACE ("ACE_Dumpable_Ptr::operator->"); + return this->dumper_; +} + +void +ACE_Dumpable_Ptr::operator= (const ACE_Dumpable *dumper) const +{ + ACE_TRACE ("ACE_Dumpable_Ptr::operator="); + if (this->dumper_ != dumper) + { + delete const_cast (this->dumper_); + (const_cast (this))->dumper_ = dumper; + } +} + +ACE_ODB::ACE_ODB (void) + // Let the Tuple default constructor initialize object_table_ + : current_size_ (0) +{ + ACE_TRACE ("ACE_ODB::ACE_ODB"); +} + +ACE_ODB * +ACE_ODB::instance (void) +{ + ACE_TRACE ("ACE_ODB::instance"); + + if (ACE_ODB::instance_ == 0) + { + ACE_MT (ACE_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_DUMP_LOCK); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0)); + + if (ACE_ODB::instance_ == 0) + ACE_NEW_RETURN (ACE_ODB::instance_, + ACE_ODB, + 0); + } + + return ACE_ODB::instance_; +} + +void +ACE_ODB::dump_objects (void) +{ + ACE_TRACE ("ACE_ODB::dump_objects"); + for (int i = 0; i < this->current_size_; i++) + { + if (this->object_table_[i].this_ != 0) + // Dump the state of the object. + this->object_table_[i].dumper_->dump (); + } +} + +// This method registers a new . It detects +// duplicates and simply overwrites them. + +void +ACE_ODB::register_object (const ACE_Dumpable *dumper) +{ + ACE_TRACE ("ACE_ODB::register_object"); + int i; + int slot = 0; + + for (i = 0; i < this->current_size_; i++) + { + if (this->object_table_[i].this_ == 0) + slot = i; + else if (this->object_table_[i].this_ == dumper->this_) + { + slot = i; + break; + } + } + + if (i == this->current_size_) + { + slot = this->current_size_++; + ACE_ASSERT (this->current_size_ < ACE_ODB::MAX_TABLE_SIZE); + } + this->object_table_[slot].this_ = dumper->this_; + this->object_table_[slot].dumper_ = dumper; +} + +void +ACE_ODB::remove_object (const void *this_ptr) +{ + ACE_TRACE ("ACE_ODB::remove_object"); + int i; + + for (i = 0; i < this->current_size_; i++) + { + if (this->object_table_[i].this_ == this_ptr) + break; + } + + if (i < this->current_size_) + { + this->object_table_[i].this_ = 0; + this->object_table_[i].dumper_ = 0; + } +} + +ACE_ODB *ACE_ODB::instance_ = 0; + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dump.h b/dep/ACE_wrappers/ace/Dump.h new file mode 100644 index 000000000..4ccd64adb --- /dev/null +++ b/dep/ACE_wrappers/ace/Dump.h @@ -0,0 +1,172 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Dump.h + * + * $Id: Dump.h 80826 2008-03-04 14:51:23Z wotte $ + * + * + * A prototype mechanism that allow all ACE objects to be registered + * with a central in-memory "database" that can dump the state of all + * live ACE objects (e.g., from within a debugger). + * + * The macros which allow easy registration and removal of objects to be + * dumped (ACE_REGISTER_OBJECT and ACE_REMOVE_OBJECT) are turned into + * no-ops by compiling with the ACE_NDEBUG macro defined. This allows + * usage to be removed in "release mode" builds without changing code. + * + * There are several interesting aspects to this design: + * + * 1. It uses the External Polymorphism pattern to avoid having to + * derive all ACE classes from a common base class that has virtual + * methods (this is crucial to avoid unnecessary overhead). In + * addition, there is no additional space added to ACE objects + * (this is crucial to maintain binary layout compatibility). + * + * 2. This mechanism can be conditionally compiled in order to + * completely disable this feature entirely. Moreover, by + * using macros there are relatively few changes to ACE code. + * + * 3. This mechanism copes with single-inheritance hierarchies of + * dumpable classes. In such cases we typically want only one + * dump, corresponding to the most derived instance. Thanks to + * Christian Millour (chris@etca.fr) for illustrating how to do + * this. Note, however, that this scheme doesn't generalize to + * work with multiple-inheritance or virtual base classes. + * + * Future work includes: + * + * 1. Using a dynamic object table rather than a static table + * + * 2. Adding support to allow particular classes of objects to + * be selectively dumped. + * + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_DUMP_H +#define ACE_DUMP_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dumpable + * + * @brief Base class that defines a uniform interface for all object + * dumping. + */ +class ACE_Export ACE_Dumpable +{ +public: + friend class ACE_ODB; + friend class ACE_Dumpable_Ptr; + + /// Constructor. + ACE_Dumpable (const void *); + + /// This pure virtual method must be filled in by a subclass. + virtual void dump (void) const = 0; + +protected: + virtual ~ACE_Dumpable (void); + +private: + /// Pointer to the object that is being stored. + const void *this_; +}; + +/** + * @class ACE_Dumpable_Ptr + * + * @brief A smart pointer stored in the in-memory object database + * ACE_ODB. The pointee (if any) is deleted when reassigned. + */ +class ACE_Export ACE_Dumpable_Ptr +{ +public: + ACE_Dumpable_Ptr (const ACE_Dumpable *dumper = 0); + const ACE_Dumpable *operator->() const; + void operator= (const ACE_Dumpable *dumper) const; + +private: + /// "Real" pointer to the underlying abstract base class + /// pointer that does the real work. + const ACE_Dumpable *dumper_; +}; + +/** + * @class ACE_ODB + * + * @brief This is the object database (ODB) that keeps track of all + * live ACE objects. + */ +class ACE_Export ACE_ODB +{ +public: + /// @todo This is clearly inadequate and should be dynamic... + enum {MAX_TABLE_SIZE = 100000}; + + /// Iterates through the entire set of registered objects and + /// dumps their state. + void dump_objects (void); + + /// Add the tuple to the list of registered ACE objects. + void register_object (const ACE_Dumpable *dumper); + + /// Use to locate and remove the associated from the + /// list of registered ACE objects. + void remove_object (const void *this_); + + /// Interface to the Singleton instance of the object database. + static ACE_ODB *instance (void); + +private: + ACE_ODB (void); // Ensure we have a Singleton... + + struct Tuple + { + /// Pointer to the object that is registered. + const void *this_; + + /// Smart pointer to the ACE_Dumpable object associated with this_. + /// This uses an ACE_Dumpable_Ptr, instead of a bare pointer, to + /// cope with hierarchies of dumpable classes. In such cases we + /// typically want only one dump, corresponding to the most derived + /// instance. To achieve this, the handle registered for the + /// subobject corresponding to the base class is destroyed (hence + /// on destruction of the subobject its handle won't exist anymore + /// and we'll have to check for that). + const ACE_Dumpable_Ptr dumper_; + + Tuple (void) : dumper_(0) {} + }; + + /// Singleton instance of this class. + static ACE_ODB *instance_; + + /// The current implementation is very simple-minded and will be + /// changed to be dynamic. + Tuple object_table_[ACE_ODB::MAX_TABLE_SIZE]; + + /// Current size of . + int current_size_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Include the templates classes at this point. +#include "ace/Dump_T.h" + +#include /**/ "ace/post.h" +#endif /* ACE_DUMP_H */ diff --git a/dep/ACE_wrappers/ace/Dump_T.cpp b/dep/ACE_wrappers/ace/Dump_T.cpp new file mode 100644 index 000000000..da2b62a6f --- /dev/null +++ b/dep/ACE_wrappers/ace/Dump_T.cpp @@ -0,0 +1,48 @@ +// Dump_T.cpp +// +// $Id: Dump_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_DUMP_T_CPP +#define ACE_DUMP_T_CPP + +#include "ace/Dump_T.h" +#include "ace/Global_Macros.h" +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Dumpable_Adapter::~ACE_Dumpable_Adapter (void) +{ + ACE_TRACE ("ACE_Dumpable_Adapter::~ACE_Dumpable_Adapter"); +} + +template +ACE_Dumpable_Adapter::ACE_Dumpable_Adapter (const Concrete *t) + : ACE_Dumpable ((const void *) t), this_ (t) +{ + ACE_TRACE ("ACE_Dumpable_Adapter::ACE_Dumpable_Adapter"); +} + +template Concrete * +ACE_Dumpable_Adapter::operator->() const +{ + return (Concrete *) this->this_; +} + +template void +ACE_Dumpable_Adapter::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Dumpable_Adapter::dump"); + this->this_->dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_DUMP_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Dump_T.h b/dep/ACE_wrappers/ace/Dump_T.h new file mode 100644 index 000000000..92b57addc --- /dev/null +++ b/dep/ACE_wrappers/ace/Dump_T.h @@ -0,0 +1,82 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dump_T.h + * + * $Id: Dump_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_DUMP_T_H +#define ACE_DUMP_T_H +#include /**/ "ace/pre.h" + +#include "ace/Dump.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dumpable_Adapter + * + * @brief This class inherits the interface of the abstract ACE_Dumpable + * class and is instantiated with the implementation of the + * concrete component class . + * + * This design is similar to the Adapter and Decorator patterns + * from the ``Gang of Four'' book. Note that + * need not inherit from a common class since ACE_Dumpable + * provides the uniform virtual interface! + */ +template +class ACE_Dumpable_Adapter : public ACE_Dumpable +{ +public: + // = Initialization and termination methods. + ACE_Dumpable_Adapter (const Concrete *t); + ~ACE_Dumpable_Adapter (void); + + /// Concrete dump method (simply delegates to the method of + /// ). + virtual void dump (void) const; + + /// Delegate to methods in the Concrete class. + Concrete *operator->() const; + +private: + /// Pointer to @c this of . + const Concrete *this_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +// Some useful macros for conditionally compiling this feature... +#if defined (ACE_NDEBUG) +#define ACE_REGISTER_OBJECT(CLASS) +#define ACE_REMOVE_OBJECT +#else +#define ACE_REGISTER_OBJECT(CLASS) \ + ACE_ODB::instance ()->register_object \ + (new ACE_Dumpable_Adapter (this)); +#define ACE_REMOVE_OBJECT \ + ACE_ODB::instance ()->remove_object \ + ((void *) this); +#endif /* ACE_NDEBUG */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Dump_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Dump_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_DUMP_T_H */ diff --git a/dep/ACE_wrappers/ace/Dynamic.cpp b/dep/ACE_wrappers/ace/Dynamic.cpp new file mode 100644 index 000000000..4eaedad0c --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic.cpp @@ -0,0 +1,34 @@ +// $Id: Dynamic.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Dynamic.h" +#include "ace/Singleton.h" +#include "ace/TSS_T.h" +#include "ace/Synch_Traits.h" +#include "ace/Null_Mutex.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Dynamic.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Dynamic, "$Id: Dynamic.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Dynamic::ACE_Dynamic (void) + : is_dynamic_ (false) +{ + ACE_TRACE ("ACE_Dynamic::ACE_Dynamic"); +} + +/* static */ ACE_Dynamic * +ACE_Dynamic::instance (void) +{ + return ACE_TSS_Singleton::instance (); +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_TSS_Singleton * + ACE_TSS_Singleton::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic.h b/dep/ACE_wrappers/ace/Dynamic.h new file mode 100644 index 000000000..70dfcd8d9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic.h @@ -0,0 +1,75 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Dynamic.h + * + * $Id: Dynamic.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + * @author Irfan Pyarali. + */ +//========================================================================== + +#ifndef ACE_DYNAMIC_H +#define ACE_DYNAMIC_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dynamic + * + * @brief Checks to see if an object was dynamically allocated. + * + * This class holds the pointer in a thread-safe manner between + * the call to operator new and the call to the constructor. + */ +class ACE_Export ACE_Dynamic +{ +public: + // = Initialization and termination method. + /// Constructor. + ACE_Dynamic (void); + + /// Destructor. + ~ACE_Dynamic (void); + + /** + * Sets a flag that indicates that the object was dynamically + * created. This method is usually called in operator new and then + * checked and reset in the constructor. + */ + void set (void); + + /// @c true if we were allocated dynamically, else @c false. + bool is_dynamic (void); + + /// Resets state flag. + void reset (void); + + static ACE_Dynamic *instance (void); + +private: + /** + * Flag that indicates that the object was dynamically created. This + * method is usually called in operator new and then checked and + * reset in the constructor. + */ + bool is_dynamic_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Dynamic.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_DYNAMIC_H */ diff --git a/dep/ACE_wrappers/ace/Dynamic.inl b/dep/ACE_wrappers/ace/Dynamic.inl new file mode 100644 index 000000000..1e8e968f8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic.inl @@ -0,0 +1,34 @@ +// -*- C++ -*- +// +// $Id: Dynamic.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Dynamic::~ACE_Dynamic (void) +{ + // ACE_TRACE ("ACE_Dynamic::~ACE_Dynamic"); +} + +ACE_INLINE void +ACE_Dynamic::set (void) +{ + // ACE_TRACE ("ACE_Dynamic::set"); + this->is_dynamic_ = true; +} + +ACE_INLINE bool +ACE_Dynamic::is_dynamic (void) +{ + // ACE_TRACE ("ACE_Dynamic::is_dynamic"); + return this->is_dynamic_; +} + +ACE_INLINE void +ACE_Dynamic::reset (void) +{ + // ACE_TRACE ("ACE_Dynamic::reset"); + this->is_dynamic_ = false; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.cpp b/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.cpp new file mode 100644 index 000000000..9211f3313 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.cpp @@ -0,0 +1,205 @@ +#include "ace/Dynamic_Message_Strategy.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Dynamic_Message_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Guard_T.h" +#include "ace/Log_Msg.h" +#include "ace/Malloc_Base.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ace, + Dynamic_Message_Strategy, + "$Id: Dynamic_Message_Strategy.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// ctor + +ACE_Dynamic_Message_Strategy::ACE_Dynamic_Message_Strategy (unsigned long static_bit_field_mask, + unsigned long static_bit_field_shift, + unsigned long dynamic_priority_max, + unsigned long dynamic_priority_offset) + : static_bit_field_mask_ (static_bit_field_mask), + static_bit_field_shift_ (static_bit_field_shift), + dynamic_priority_max_ (dynamic_priority_max), + dynamic_priority_offset_ (dynamic_priority_offset), + max_late_ (0, dynamic_priority_offset - 1), + min_pending_ (0, dynamic_priority_offset), + pending_shift_ (0, dynamic_priority_max) +{ +} + +// dtor + +ACE_Dynamic_Message_Strategy::~ACE_Dynamic_Message_Strategy (void) +{ +} + +ACE_Dynamic_Message_Strategy::Priority_Status +ACE_Dynamic_Message_Strategy::priority_status (ACE_Message_Block & mb, + const ACE_Time_Value & tv) +{ + // default the message to have pending priority status + Priority_Status status = ACE_Dynamic_Message_Strategy::PENDING; + + // start with the passed absolute time as the message's priority, then + // call the polymorphic hook method to (at least partially) convert + // the absolute time and message attributes into the message's priority + ACE_Time_Value priority (tv); + convert_priority (priority, mb); + + // if the priority is negative, the message is pending + if (priority < ACE_Time_Value::zero) + { + // priority for pending messages must be shifted + // upward above the late priority range + priority += pending_shift_; + if (priority < min_pending_) + priority = min_pending_; + } + // otherwise, if the priority is greater than the maximum late + // priority value that can be represented, it is beyond late + else if (priority > max_late_) + { + // all messages that are beyond late are assigned lowest priority (zero) + mb.msg_priority (0); + return ACE_Dynamic_Message_Strategy::BEYOND_LATE; + } + // otherwise, the message is late, but its priority is correct + else + status = ACE_Dynamic_Message_Strategy::LATE; + + // use (fast) bitwise operators to isolate and replace + // the dynamic portion of the message's priority + mb.msg_priority((mb.msg_priority() & static_bit_field_mask_) | + ((priority.usec () + + ACE_ONE_SECOND_IN_USECS * (suseconds_t)(priority.sec())) << + static_bit_field_shift_)); + + // returns the priority status of the message + return status; +} + + +// Dump the state of the strategy. + +void +ACE_Dynamic_Message_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Dynamic_Message_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("static_bit_field_mask_ = %u\n") + ACE_TEXT ("static_bit_field_shift_ = %u\n") + ACE_TEXT ("dynamic_priority_max_ = %u\n") + ACE_TEXT ("dynamic_priority_offset_ = %u\n") + ACE_TEXT ("max_late_ = [%d sec, %d usec]\n") + ACE_TEXT ("min_pending_ = [%d sec, %d usec]\n") + ACE_TEXT ("pending_shift_ = [%d sec, %d usec]\n"), + this->static_bit_field_mask_, + this->static_bit_field_shift_, + this->dynamic_priority_max_, + this->dynamic_priority_offset_, + this->max_late_.sec (), + this->max_late_.usec (), + this->min_pending_.sec (), + this->min_pending_.usec (), + this->pending_shift_.sec (), + this->pending_shift_.usec ())); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Deadline_Message_Strategy::ACE_Deadline_Message_Strategy (unsigned long static_bit_field_mask, + unsigned long static_bit_field_shift, + unsigned long dynamic_priority_max, + unsigned long dynamic_priority_offset) + : ACE_Dynamic_Message_Strategy (static_bit_field_mask, + static_bit_field_shift, + dynamic_priority_max, + dynamic_priority_offset) +{ +} + +ACE_Deadline_Message_Strategy::~ACE_Deadline_Message_Strategy (void) +{ +} + +void +ACE_Deadline_Message_Strategy::convert_priority (ACE_Time_Value & priority, + const ACE_Message_Block & mb) +{ + // Convert absolute time passed in tv to negative time + // to deadline of mb with respect to that absolute time. + priority -= mb.msg_deadline_time (); +} + // dynamic priority conversion function based on time to deadline + +void +ACE_Deadline_Message_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Deadline_Message_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Dynamic_Message_Strategy base class: \n"))); + this->ACE_Dynamic_Message_Strategy::dump (); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nderived class: ACE_Deadline_Message_Strategy\n"))); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Laxity_Message_Strategy::ACE_Laxity_Message_Strategy (unsigned long static_bit_field_mask, + unsigned long static_bit_field_shift, + unsigned long dynamic_priority_max, + unsigned long dynamic_priority_offset) + : ACE_Dynamic_Message_Strategy (static_bit_field_mask, + static_bit_field_shift, + dynamic_priority_max, + dynamic_priority_offset) +{ +} + +ACE_Laxity_Message_Strategy::~ACE_Laxity_Message_Strategy (void) +{ +} + +void +ACE_Laxity_Message_Strategy::convert_priority (ACE_Time_Value & priority, + const ACE_Message_Block & mb) +{ + // Convert absolute time passed in tv to negative + // laxity of mb with respect to that absolute time. + priority += mb.msg_execution_time (); + priority -= mb.msg_deadline_time (); +} + // dynamic priority conversion function based on laxity + +void +ACE_Laxity_Message_Strategy::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Laxity_Message_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Dynamic_Message_Strategy base class: \n"))); + this->ACE_Dynamic_Message_Strategy::dump (); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nderived class: ACE_Laxity_Message_Strategy\n"))); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + // Dump the state of the strategy. + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.h b/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.h new file mode 100644 index 000000000..090ad3a8f --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.h @@ -0,0 +1,217 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Dynamic_Message_Strategy.h + * + * $Id: Dynamic_Message_Strategy.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_DYNAMIC_MESSAGE_STRATEGY_H +#define ACE_DYNAMIC_MESSAGE_STRATEGY_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Message_Block.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dynamic_Message_Strategy + * + * @brief An abstract base class which provides dynamic priority + * evaluation methods for use by the ACE_Dynamic_Message_Queue + * class or any other class which needs to manage the priorities + * of a collection of ACE_Message_Blocks dynamically. + * + * Methods for deadline and laxity based priority evaluation are + * provided. These methods assume a specific partitioning of + * the message priority number into a higher order dynamic bit + * field and a lower order static priority bit field. The + * default partitioning assumes an unsigned dynamic message + * priority field of 22 bits and an unsigned static message + * priority field of 10 bits. This corresponds to the initial + * values of the static class members. To provide a different + * partitioning, assign a different set of values to the static + * class memebers before using the static member functions. + */ +class ACE_Export ACE_Dynamic_Message_Strategy +{ +public: + + // = Message priority status + + // Values are defined as bit flags so that status combinations may + // be specified easily. + + enum Priority_Status + { + /// Message can still make its deadline + PENDING = 0x01, + /// Message cannot make its deadline + LATE = 0x02, + /// Message is so late its priority is undefined + BEYOND_LATE = 0x04, + /// Mask to match any priority status + ANY_STATUS = 0x07 + }; + + /// Constructor. + ACE_Dynamic_Message_Strategy (unsigned long static_bit_field_mask, + unsigned long static_bit_field_shift, + unsigned long dynamic_priority_max, + unsigned long dynamic_priority_offset); + + /// Virtual destructor. + virtual ~ACE_Dynamic_Message_Strategy (void); + + /// Updates the message's priority and returns its priority status. + Priority_Status priority_status (ACE_Message_Block &mb, + const ACE_Time_Value &tv); + + /// Get static bit field mask. + unsigned long static_bit_field_mask (void) const; + + /// Set static bit field mask. + void static_bit_field_mask (unsigned long); + + /// Get left shift value to make room for static bit field. + unsigned long static_bit_field_shift (void) const; + + /// Set left shift value to make room for static bit field. + void static_bit_field_shift (unsigned long); + + /// Get maximum supported priority value. + unsigned long dynamic_priority_max (void) const; + + /// Set maximum supported priority value. + void dynamic_priority_max (unsigned long); + + /// Get offset to boundary between signed range and unsigned range. + unsigned long dynamic_priority_offset (void) const; + + /// Set offset to boundary between signed range and unsigned range. + void dynamic_priority_offset (unsigned long); + + /// Dump the state of the strategy. + virtual void dump (void) const; + +protected: + /// Hook method for dynamic priority conversion. + virtual void convert_priority (ACE_Time_Value &priority, + const ACE_Message_Block &mb) = 0; + + /// This is a bit mask with all ones in the static bit field. + unsigned long static_bit_field_mask_; + + /** + * This is a left shift value to make room for static bit field: + * this value should be the logarithm base 2 of + * (static_bit_field_mask_ + 1). + */ + unsigned long static_bit_field_shift_; + + /// Maximum supported priority value. + unsigned long dynamic_priority_max_; + + /// Offset to boundary between signed range and unsigned range. + unsigned long dynamic_priority_offset_; + + /// Maximum late time value that can be represented. + ACE_Time_Value max_late_; + + /// Minimum pending time value that can be represented. + ACE_Time_Value min_pending_; + + /// Time value by which to shift pending priority. + ACE_Time_Value pending_shift_; +}; + +/** + * @class ACE_Deadline_Message_Strategy + * + * @brief Deadline based message priority strategy. + * + * Assigns dynamic message priority according to time to deadline. The + * message priority is divided into high and low order bit fields. The + * high order bit field is used for dynamic message priority, which is + * updated whenever the convert_priority() method is called. The + * low order bit field is used for static message priority and is left + * unchanged. The partitioning of the priority value into high and low + * order bit fields is done according to the arguments passed to the + * strategy object's constructor. + */ +class ACE_Export ACE_Deadline_Message_Strategy : public ACE_Dynamic_Message_Strategy +{ +public: + /// Ctor, with all arguments defaulted. + ACE_Deadline_Message_Strategy (unsigned long static_bit_field_mask = 0x3FFUL, // 2^(10) - 1 + unsigned long static_bit_field_shift = 10, // 10 low order bits + unsigned long dynamic_priority_max = 0x3FFFFFUL, // 2^(22)-1 + unsigned long dynamic_priority_offset = 0x200000UL); // 2^(22-1) + + /// Virtual dtor. + virtual ~ACE_Deadline_Message_Strategy (void); + + /// Dynamic priority conversion function based on time to deadline. + virtual void convert_priority (ACE_Time_Value &priority, + const ACE_Message_Block &mb); + + /// Dump the state of the strategy. + virtual void dump (void) const; +}; + +/** + * @class ACE_Laxity_Message_Strategy + * + * @brief Laxity based message priority strategy. + * + * Assigns dynamic message priority according to laxity (time to + * deadline minus worst case execution time). The message priority is + * divided into high and low order bit fields. The high order + * bit field is used for dynamic message priority, which is + * updated whenever the convert_priority() method is called. The + * low order bit field is used for static message priority and is left + * unchanged. The partitioning of the priority value into high and low + * order bit fields is done according to the arguments passed to the + * strategy object's constructor. + */ +class ACE_Export ACE_Laxity_Message_Strategy : public ACE_Dynamic_Message_Strategy +{ +public: + /// Ctor, with all arguments defaulted. + ACE_Laxity_Message_Strategy (unsigned long static_bit_field_mask = 0x3FFUL, // 2^(10) - 1 + unsigned long static_bit_field_shift = 10, // 10 low order bits + unsigned long dynamic_priority_max = 0x3FFFFFUL, // 2^(22)-1 + unsigned long dynamic_priority_offset = 0x200000UL); // 2^(22-1) + + /// virtual dtor. + virtual ~ACE_Laxity_Message_Strategy (void); + + /// Dynamic priority conversion function based on laxity. + virtual void convert_priority (ACE_Time_Value &priority, + const ACE_Message_Block &mb); + + /// Dump the state of the strategy. + virtual void dump (void) const; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Dynamic_Message_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_DYNAMIC_MESSAGE_STRATEGY_H */ diff --git a/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.inl b/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.inl new file mode 100644 index 000000000..9742a07fd --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Message_Strategy.inl @@ -0,0 +1,75 @@ +// -*- C++ -*- +// +// $Id: Dynamic_Message_Strategy.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE unsigned long +ACE_Dynamic_Message_Strategy::static_bit_field_mask (void) const +{ + return static_bit_field_mask_; +} + // get static bit field mask + +ACE_INLINE void +ACE_Dynamic_Message_Strategy::static_bit_field_mask (unsigned long ul) +{ + static_bit_field_mask_ = ul; +} + // set static bit field mask + +ACE_INLINE unsigned long +ACE_Dynamic_Message_Strategy::static_bit_field_shift (void) const +{ + return static_bit_field_shift_; +} + // get left shift value to make room for static bit field + +ACE_INLINE void +ACE_Dynamic_Message_Strategy::static_bit_field_shift (unsigned long ul) +{ + static_bit_field_shift_ = ul; +} + // set left shift value to make room for static bit field + +ACE_INLINE unsigned long +ACE_Dynamic_Message_Strategy::dynamic_priority_max (void) const +{ + return dynamic_priority_max_; +} + // get maximum supported priority value + +ACE_INLINE void +ACE_Dynamic_Message_Strategy::dynamic_priority_max (unsigned long ul) +{ + // pending_shift_ depends on dynamic_priority_max_: for performance + // reasons, the value in pending_shift_ is (re)calculated only when + // dynamic_priority_max_ is initialized or changes, and is stored + // as a class member rather than being a derived value. + dynamic_priority_max_ = ul; + pending_shift_ = ACE_Time_Value (0, ul); +} + // set maximum supported priority value + +ACE_INLINE unsigned long +ACE_Dynamic_Message_Strategy::dynamic_priority_offset (void) const +{ + return dynamic_priority_offset_; +} + // get offset for boundary between signed range and unsigned range + +ACE_INLINE void +ACE_Dynamic_Message_Strategy::dynamic_priority_offset (unsigned long ul) +{ + // max_late_ and min_pending_ depend on dynamic_priority_offset_: + // for performance reasons, the values in max_late_ and min_pending_ + // are (re)calculated only when dynamic_priority_offset_ is + // initialized or changes, and are stored as a class member rather + // than being derived each time one of their values is needed. + dynamic_priority_offset_ = ul; + max_late_ = ACE_Time_Value (0, ul - 1); + min_pending_ = ACE_Time_Value (0, ul); +} + // set offset for boundary between signed range and unsigned range + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic_Service.cpp b/dep/ACE_wrappers/ace/Dynamic_Service.cpp new file mode 100644 index 000000000..28d6e4526 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service.cpp @@ -0,0 +1,63 @@ +// $Id: Dynamic_Service.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_DYNAMIC_SERVICE_CPP +#define ACE_DYNAMIC_SERVICE_CPP + +#include "ace/Dynamic_Service.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Service_Object.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Dynamic_Service.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +template TYPE * +ACE_Dynamic_Service::instance (const ACE_TCHAR *name) +{ + ACE_Service_Object * svc_obj = + static_cast + (ACE_Dynamic_Service_Base::instance (name,false)); + return dynamic_cast (svc_obj); +} + +template TYPE * +ACE_Dynamic_Service::instance (const ACE_TCHAR *name, + bool no_global) +{ + ACE_Service_Object * svc_obj = + static_cast + (ACE_Dynamic_Service_Base::instance (name, no_global)); + return dynamic_cast (svc_obj); +} + +template TYPE * +ACE_Dynamic_Service::instance (const ACE_Service_Gestalt* conf, + const ACE_TCHAR *name) +{ + ACE_Service_Object * svc_obj = + static_cast + (ACE_Dynamic_Service_Base::instance (conf, name, false)); + return dynamic_cast (svc_obj); +} + +template TYPE * +ACE_Dynamic_Service::instance (const ACE_Service_Gestalt* conf, + const ACE_TCHAR *name, + bool no_global) +{ + ACE_Service_Object * svc_obj = + static_cast + (ACE_Dynamic_Service_Base::instance (conf, name, no_global)); + return dynamic_cast (svc_obj); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_DYNAMIC_SERVICE_CPP */ diff --git a/dep/ACE_wrappers/ace/Dynamic_Service.h b/dep/ACE_wrappers/ace/Dynamic_Service.h new file mode 100644 index 000000000..b90095c76 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service.h @@ -0,0 +1,89 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dynamic_Service.h + * + * $Id: Dynamic_Service.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Prashant Jain + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_DYNAMIC_SERVICE_H +#define ACE_DYNAMIC_SERVICE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Global_Macros.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Dynamic_Service_Base.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Service_Object; + +/** + * @class ACE_Dynamic_Service + * + * @brief Provides a general interface to retrieve arbitrary objects + * from the ACE service repository. + * + * Uses "name" for lookup in the ACE service repository. Obtains + * the object and returns it as the appropriate type. + */ +template +class ACE_Dynamic_Service : public ACE_Dynamic_Service_Base +{ +public: + /// Return instance using @a name to search the Service_Repository. + static TYPE* instance (const ACE_TCHAR *name); + static TYPE* instance (const ACE_TCHAR *name, bool no_global); + + static TYPE* instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name); + static TYPE* instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name, bool no_global); + +#if defined (ACE_USES_WCHAR) + + /// Return instance using @a name to search the Service_Repository. + static TYPE* instance (const ACE_ANTI_TCHAR *name); + + static TYPE* instance (const ACE_ANTI_TCHAR *name, bool no_global); + + static TYPE* instance (const ACE_Service_Gestalt* repo, + const ACE_ANTI_TCHAR *name); + static TYPE* instance (const ACE_Service_Gestalt* repo, + const ACE_ANTI_TCHAR *name, bool no_global); +#endif // ACE_USES_WCHAR + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Dynamic_Service ()) + ACE_UNIMPLEMENTED_FUNC (ACE_Dynamic_Service (const ACE_Dynamic_Service&)) + ACE_UNIMPLEMENTED_FUNC (ACE_Dynamic_Service& operator= (const ACE_Dynamic_Service&)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Dynamic_Service.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +# include "ace/Dynamic_Service.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +# pragma implementation ("Dynamic_Service.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_DYNAMIC_SERVICE_H */ diff --git a/dep/ACE_wrappers/ace/Dynamic_Service.inl b/dep/ACE_wrappers/ace/Dynamic_Service.inl new file mode 100644 index 000000000..31324bf53 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service.inl @@ -0,0 +1,39 @@ +// -*- C++ -*- +// +// $Id: Dynamic_Service.inl 81318 2008-04-10 10:12:05Z johnnyw $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_USES_WCHAR) + +template ACE_INLINE TYPE * +ACE_Dynamic_Service::instance (const ACE_ANTI_TCHAR *name) +{ + return instance (ACE_TEXT_CHAR_TO_TCHAR (name),false); +} + +template ACE_INLINE TYPE * +ACE_Dynamic_Service::instance (const ACE_ANTI_TCHAR *name, + bool no_global) +{ + return instance (ACE_TEXT_CHAR_TO_TCHAR (name),no_global); +} + +template ACE_INLINE TYPE * +ACE_Dynamic_Service::instance (const ACE_Service_Gestalt* repo, + const ACE_ANTI_TCHAR *name) +{ + return instance (repo, ACE_TEXT_CHAR_TO_TCHAR (name),false); +} + +template ACE_INLINE TYPE * +ACE_Dynamic_Service::instance (const ACE_Service_Gestalt* repo, + const ACE_ANTI_TCHAR *name, + bool no_global) +{ + return instance (repo, ACE_TEXT_CHAR_TO_TCHAR (name),no_global); +} + +#endif // ACE_USES_WCHAR + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic_Service_Base.cpp b/dep/ACE_wrappers/ace/Dynamic_Service_Base.cpp new file mode 100644 index 000000000..91eec162c --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service_Base.cpp @@ -0,0 +1,101 @@ +#include "ace/Dynamic_Service_Base.h" +#include "ace/ACE.h" +#include "ace/Service_Config.h" +#include "ace/Service_Repository.h" +#include "ace/Service_Types.h" +#include "ace/Log_Msg.h" + + +ACE_RCSID (ace, + Dynamic_Service_Base, + "$Id: Dynamic_Service_Base.cpp 80826 2008-03-04 14:51:23Z wotte $") + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +void +ACE_Dynamic_Service_Base::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Dynamic_Service_Base::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Get the instance using for the current global +// service configuration repository. + +void * +ACE_Dynamic_Service_Base::instance (const ACE_TCHAR *name, bool no_global) +{ + ACE_TRACE ("ACE_Dynamic_Service_Base::instance"); + return instance (ACE_Service_Config::current (), name, no_global); +} + +// Find a service registration + +const ACE_Service_Type * +ACE_Dynamic_Service_Base::find_i (const ACE_Service_Gestalt* &repo, + const ACE_TCHAR *name, + bool no_global) +{ + ACE_TRACE ("ACE_Dynamic_Service_Base::find_i"); + const ACE_Service_Type *svc_rec = 0; + + ACE_Service_Gestalt* global = ACE_Service_Config::global (); + + for ( ; (repo->find (name, &svc_rec) == -1) && !no_global; repo = global) + { + // Check the static repo, too if different + if (repo == global) + break; + } + + return svc_rec; +} + + +// Get the instance using for specific configuration repository. +void * +ACE_Dynamic_Service_Base::instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name, + bool no_global) +{ + ACE_TRACE ("ACE_Dynamic_Service_Base::instance"); + + void *obj = 0; + const ACE_Service_Type_Impl *type = 0; + + const ACE_Service_Gestalt* repo_found = repo; + const ACE_Service_Type *svc_rec = find_i (repo_found, name, no_global); + if (svc_rec != 0) + { + type = svc_rec->type (); + if (type != 0) + obj = type->object (); + } + + if (ACE::debug ()) + { + ACE_Guard log_guard (*ACE_Log_Msg::instance ()); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) DSB::instance, repo=%@, name=%s") + ACE_TEXT (" type=%@ => %@"), + repo->repo_, name, type, obj)); + + if (repo->repo_ != repo_found->repo_) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" [in repo=%@]\n"), + repo_found->repo_)); + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + } + + return obj; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic_Service_Base.h b/dep/ACE_wrappers/ace/Dynamic_Service_Base.h new file mode 100644 index 000000000..095e883a8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service_Base.h @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Dynamic_Service_Base.h + * + * $Id: Dynamic_Service_Base.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Prashant Jain + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_DYNAMIC_SERVICE_BASE_H +#define ACE_DYNAMIC_SERVICE_BASE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Service_Gestalt; +class ACE_Service_Type; + +/** + * @class ACE_Dynamic_Service_Base + * + * @brief Base class for all ACE_Dynamic_Service instantiations. + * + * Factors out common code shared by all ACE_Dynamic_Service + * instantiations, this avoid code bloat. + */ +class ACE_Export ACE_Dynamic_Service_Base +{ + +public: + /// Dump the current static of the object + void dump (void) const; + +protected: + /// Perform the default repo search, but optionally skip searching the global + /// repo. + static void* instance (const ACE_TCHAR *name, bool no_global = false); + + static void* instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name, + bool no_global = false); + + /// No need to create, or assign instances of this class + ACE_Dynamic_Service_Base (void); + ~ACE_Dynamic_Service_Base (void); + const ACE_Dynamic_Service_Base& operator= (const ACE_Dynamic_Service_Base&); + +private: + /// Implement the service search policy, i.e. "look for the service first + /// locally and then globally" + static const ACE_Service_Type *find_i (const ACE_Service_Gestalt* &repo, + const ACE_TCHAR *name, + bool no_global); + + /// The dependency declaration class needs access to the service search + /// policy, implemented by find_i() + friend class ACE_Dynamic_Service_Dependency; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_DYNAMIC_SERVICE_BASE_H */ diff --git a/dep/ACE_wrappers/ace/Dynamic_Service_Dependency.cpp b/dep/ACE_wrappers/ace/Dynamic_Service_Dependency.cpp new file mode 100644 index 000000000..df7cd0f5d --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service_Dependency.cpp @@ -0,0 +1,51 @@ +#include "ace/ACE.h" +#include "ace/DLL_Manager.h" +#include "ace/Dynamic_Service_Dependency.h" +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" + +ACE_RCSID (ace, + Dynamic_Service_Dependency, + "$Id: Dynamic_Service_Dependency.cpp 80826 2008-03-04 14:51:23Z wotte $") + + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +ACE_Dynamic_Service_Dependency::ACE_Dynamic_Service_Dependency (const ACE_TCHAR *principal) +{ + this->init (ACE_Service_Config::current (), principal); +} + +ACE_Dynamic_Service_Dependency::ACE_Dynamic_Service_Dependency (const ACE_Service_Gestalt *cfg, + const ACE_TCHAR *principal) +{ + this->init (cfg, principal); +} + + +ACE_Dynamic_Service_Dependency::~ACE_Dynamic_Service_Dependency (void) +{ + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) DSD, this=%@ - destroying\n"), + this)); +} + +void +ACE_Dynamic_Service_Dependency::init (const ACE_Service_Gestalt *cfg, + const ACE_TCHAR *principal) +{ + const ACE_Service_Type* st = + ACE_Dynamic_Service_Base::find_i (cfg, principal,false); + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) DSD, this=%@ - creating dependency on "), this)); + st->dump (); + } + this->tracker_ = st->dll (); +} + + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Dynamic_Service_Dependency.h b/dep/ACE_wrappers/ace/Dynamic_Service_Dependency.h new file mode 100644 index 000000000..0f187d003 --- /dev/null +++ b/dep/ACE_wrappers/ace/Dynamic_Service_Dependency.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dynamic_Service_Dependency.h + * + * $Id: Dynamic_Service_Dependency.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Iliyan Jeliazkov + */ +//============================================================================= + +#ifndef ACE_DYNAMIC_SERVICE_DEPENDENCY_H +#define ACE_DYNAMIC_SERVICE_DEPENDENCY_H + +#include /**/ "ace/pre.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Dynamic_Service_Base.h" +#include "ace/Service_Object.h" +#include "ace/DLL.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dynamic_Service_Dependency + * + * @brief Provides a way to declare dependency on specific service, + * thus helping to avoid order of initialization issues with instances + * of an objects whose implementation code resides in dynamically loaded + * services. + * + * It is disastrous to have dynamically loadable services create and give away + * ownership of objects and then ending up being unloaded before all those + * instances have been deleted. Normally the code for such objects classes + * resides within the TEXT segment of the DLL, which implements the service. + * If a service gets removed, its DLL may be unmapped from memory and then + * any attempt to invoke a method on the said objects will cause SEGV. + * + * Such instances must contain a member of ACE_Dynamic_Service_Dependency + * initialized with the service they depend on. + * ACE_Dynamic_Service_Dependency's constructor and destructor are + * "magical" - they work by maintaining the underlying dynamic service's + * DLL reference count. + */ +class ACE_Export ACE_Dynamic_Service_Dependency +{ +public: + ACE_Dynamic_Service_Dependency (const ACE_Service_Gestalt *cfg, + const ACE_TCHAR *principal); + ACE_Dynamic_Service_Dependency (const ACE_TCHAR *principal); + ~ACE_Dynamic_Service_Dependency (void); + +private: + void init (const ACE_Service_Gestalt *cfg, const ACE_TCHAR *principal); + +private: + ACE_DLL tracker_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + + +#include /**/ "ace/post.h" + +#endif /* ACE_DYNAMIC_SERVICE_DEPENDENCY_H */ diff --git a/dep/ACE_wrappers/ace/Encoding_Converter.cpp b/dep/ACE_wrappers/ace/Encoding_Converter.cpp new file mode 100644 index 000000000..b5fd2b354 --- /dev/null +++ b/dep/ACE_wrappers/ace/Encoding_Converter.cpp @@ -0,0 +1,12 @@ +// $Id: Encoding_Converter.cpp 80826 2008-03-04 14:51:23Z wotte $ +#include "ace/Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Encoding_Converter::~ACE_Encoding_Converter (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ diff --git a/dep/ACE_wrappers/ace/Encoding_Converter.h b/dep/ACE_wrappers/ace/Encoding_Converter.h new file mode 100644 index 000000000..34d22fa29 --- /dev/null +++ b/dep/ACE_wrappers/ace/Encoding_Converter.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//========================================================================= +/** + * @file Encoding_Converter.h + * + * $Id: Encoding_Converter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * This class is the base class for all encoding converters that convert + * to and from UTF-8. + * + * @author Chad Elliott + */ +//========================================================================= + +#ifndef ACE_ENCODING_CONVERTER_H +#define ACE_ENCODING_CONVERTER_H + +#include /**/ "ace/pre.h" + +#include "ace/Basic_Types.h" + +#if defined (ACE_USES_WCHAR) +#include /**/ "ace/ACE_export.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** The base class for all ACE UTF Encoding Converters. + * This class provides a generic interface that is used to implement + * various UTF encoding conversion classes. + */ +class ACE_Export ACE_Encoding_Converter +{ +public: + /// This enum describes the various states that can be returned + /// from the to_utf8() and from_utf8() methods which depends on + /// both the source buffer and the size of the target buffer. + enum Result {CONVERSION_OK, + SOURCE_EXHAUSTED, + TARGET_EXHAUSTED, + SOURCE_ILLEGAL + }; + + /// This destructor is here (and virtual) because we have virtual + /// functions. + virtual ~ACE_Encoding_Converter (void); + + /// Convert the source (which can be in any encoding) to UTF-8 and + /// store it in the provided target buffer. + virtual Result to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool strict = true) = 0; + + /// Convert the UTF-8 source into an alternate encoding and store it + /// in the provided target buffer. + virtual Result from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict = true) = 0; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ENCODING_CONVERTER_H */ diff --git a/dep/ACE_wrappers/ace/Encoding_Converter_Factory.cpp b/dep/ACE_wrappers/ace/Encoding_Converter_Factory.cpp new file mode 100644 index 000000000..f603ae3e8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Encoding_Converter_Factory.cpp @@ -0,0 +1,74 @@ +// $Id: Encoding_Converter_Factory.cpp 80826 2008-03-04 14:51:23Z wotte $ +#include "ace/Encoding_Converter_Factory.h" + +#if defined (ACE_USES_WCHAR) +#include "ace/UTF32_Encoding_Converter.h" +#include "ace/UTF16_Encoding_Converter.h" +#include "ace/UTF8_Encoding_Converter.h" +#include "ace/OS_Memory.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Encoding_Converter* +ACE_Encoding_Converter_Factory::create ( + const ACE_Byte* source, + size_t source_size, + ACE_Encoding_Converter_Factory::Encoding_Hint hint) +{ +#if defined (ACE_BIG_ENDIAN) + bool const convert_for_bigendian = true; +#else + bool const convert_for_bigendian = false; +#endif /* ACE_BIG_ENDIAN */ + ACE_Encoding_Converter* converter = 0; + + switch (hint) + { + case ACE_UTF_32BE: + ACE_NEW_RETURN (converter, + ACE_UTF32_Encoding_Converter (!convert_for_bigendian), + 0); + break; + case ACE_UTF_32LE: + ACE_NEW_RETURN (converter, + ACE_UTF32_Encoding_Converter (convert_for_bigendian), + 0); + break; + case ACE_UTF_16BE: + ACE_NEW_RETURN (converter, + ACE_UTF16_Encoding_Converter (!convert_for_bigendian), + 0); + break; + case ACE_UTF_16LE: + ACE_NEW_RETURN (converter, + ACE_UTF16_Encoding_Converter (convert_for_bigendian), + 0); + break; + case ACE_UTF_8: + ACE_NEW_RETURN (converter, + ACE_UTF8_Encoding_Converter, + 0); + break; + default: + // First check for ASCII since much of ASCII text will appear to + // convert from UTF-16 to UTF-8. + converter = ACE_UTF8_Encoding_Converter::encoded (source, source_size); + if (converter != 0) + return converter; + + // Check for UTF-32 + converter = ACE_UTF32_Encoding_Converter::encoded (source, source_size); + if (converter != 0) + return converter; + + // Check for UTF-16 + converter = ACE_UTF16_Encoding_Converter::encoded (source, source_size); + if (converter != 0) + return converter; + } + + return converter; +} + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ diff --git a/dep/ACE_wrappers/ace/Encoding_Converter_Factory.h b/dep/ACE_wrappers/ace/Encoding_Converter_Factory.h new file mode 100644 index 000000000..1441c690b --- /dev/null +++ b/dep/ACE_wrappers/ace/Encoding_Converter_Factory.h @@ -0,0 +1,54 @@ +// -*- C++ -*- + +//========================================================================= +/** + * @file Encoding_Converter_Factory.h + * + * $Id: Encoding_Converter_Factory.h 80826 2008-03-04 14:51:23Z wotte $ + * + * This class can be used to create encoding converters of various types. + * + * @author Chad Elliott + */ +//========================================================================= + +#ifndef ACE_ENCODING_CONVERTER_FACTORY_H +#define ACE_ENCODING_CONVERTER_FACTORY_H + +#include /**/ "ace/pre.h" + +#include "ace/Basic_Types.h" + +#if defined (ACE_USES_WCHAR) +#include /**/ "ace/ACE_export.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Encoding_Converter; + +/** Create an encoding converter based on the source or hint. + * This class allows users to avoid knowing any concrete converter types. + */ +class ACE_Export ACE_Encoding_Converter_Factory +{ +public: + /// This enum is used to tell what type of converter to create. + enum Encoding_Hint { ACE_UTF_32BE, ACE_UTF_32LE, + ACE_UTF_16BE, ACE_UTF_16LE, + ACE_UTF_8, ACE_NONE + }; + + /// Create an encoding converter based on the source. If a hint is + /// given, it just creates the specified type of converter without looking + /// at the source. + static ACE_Encoding_Converter* create (const ACE_Byte* source, + size_t source_size, + Encoding_Hint hint = ACE_NONE); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ + +#include /**/ "ace/post.h" + +#endif /* ACE_ENCODING_CONVERTER_FACTORY_H */ diff --git a/dep/ACE_wrappers/ace/Env_Value_T.cpp b/dep/ACE_wrappers/ace/Env_Value_T.cpp new file mode 100644 index 000000000..1997bbea4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Env_Value_T.cpp @@ -0,0 +1,12 @@ +// $Id: Env_Value_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_ENV_VALUE_T_CPP +#define ACE_ENV_VALUE_T_CPP + +#include "ace/Env_Value_T.h" + +#if ! defined (__ACE_INLINE__) +#include "ace/Env_Value_T.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_ENV_VALUE_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Env_Value_T.h b/dep/ACE_wrappers/ace/Env_Value_T.h new file mode 100644 index 000000000..df2178a0f --- /dev/null +++ b/dep/ACE_wrappers/ace/Env_Value_T.h @@ -0,0 +1,166 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Env_Value_T.h + * + * $Id: Env_Value_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Template to encapsulate getting a value from an environment variable + * and using a supplied default value if not in the environment. + * + * + * @author Chris Cleeland (derived from work by Carlos O'Ryan) + */ +//============================================================================= + +#ifndef ACE_ENV_VALUE_T_H +#define ACE_ENV_VALUE_T_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Global_Macros.h" +#include "ace/OS_NS_stdlib.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Env_Value + * + * @brief Environment Variable Value + * + * Reads a variable from the user environment, providing a default + * value. + */ +template +class ACE_Env_Value +{ +public: + /** + * Default constructor which isn't bound to a specific environment + * variable name or a default value. Before being useful it must + * 'd. + */ + ACE_Env_Value (void); + + /// Constructor that calls . + ACE_Env_Value (const ACE_TCHAR *varname, + const T &vardefault); + + /// Destroy the value. + ~ACE_Env_Value (void); + + /// Returns the value as type T. + operator T (void); + + /// The constructor, read @a varname from the environment, using + /// @a defval as its value if it is not defined. + void open (const ACE_TCHAR *varname, const T &defval); + + /// Returns the name of the variable being tracked. + const ACE_TCHAR *varname (void) const; + +private: + /// Disallow copying and assignment. + ACE_UNIMPLEMENTED_FUNC (ACE_Env_Value(const ACE_Env_Value &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Env_Value operator=(const ACE_Env_Value &)) + + void fetch_value (void); + + const ACE_TCHAR *varname_; + T value_; +}; + +/// Function to convert a string @a s into type @c T. +template void ACE_Convert (const ACE_TCHAR *s, T &t); + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Env_Value_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Env_Value_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, ACE_TCHAR *&v) +{ + v = (ACE_TCHAR *) s; +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, const ACE_TCHAR *&v) +{ + v = (const ACE_TCHAR *) s; +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, short &si) +{ + si = static_cast (ACE_OS::strtol (s, 0, 10)); +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, u_short &us) +{ + us = static_cast (ACE_OS::strtol (s, 0, 10)); +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, u_int &i) +{ + i = static_cast (ACE_OS::strtol (s, 0, 10)); +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, long &l) +{ + l = ACE_OS::strtol (s, 0, 10); +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, int &i) +{ + i = static_cast (ACE_OS::strtol (s, 0, 10)); +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, u_long &ul) +{ + ul = ACE_OS::strtoul (s, 0, 10); +} + +template <> inline void +ACE_Convert (const ACE_TCHAR *s, double &d) +{ + d = ACE_OS::strtod (s, 0); +} + +// Default calls a CTOR on type T of the form 'T::T(const char*)', but +// users can feel free to create their own specialized conversion +// functions if necessary, as shown above. Note that for 'char*' the +// default is used because a simple cast will be performed and no +// conversion will be necessary. +template inline void +ACE_Convert (const ACE_TCHAR *s, T &t) +{ + t = T (s); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Env_Value_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_ENV_VALUE_T_H */ diff --git a/dep/ACE_wrappers/ace/Env_Value_T.inl b/dep/ACE_wrappers/ace/Env_Value_T.inl new file mode 100644 index 000000000..d9af1b031 --- /dev/null +++ b/dep/ACE_wrappers/ace/Env_Value_T.inl @@ -0,0 +1,60 @@ +// $Id: Env_Value_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_Env_Value::operator T (void) +{ + return value_; +} + +template ACE_INLINE +ACE_Env_Value::ACE_Env_Value (void) + : varname_ (0) +{ +} + +template ACE_INLINE +ACE_Env_Value::ACE_Env_Value (const ACE_TCHAR *varname, + const T &defval) + : varname_ (varname), + value_(defval) +{ + this->fetch_value (); +} + +template ACE_INLINE void +ACE_Env_Value::open (const ACE_TCHAR *varname, + const T &defval) +{ + this->varname_ = varname; + this->value_ = defval; + this->fetch_value (); +} + +template ACE_INLINE void +ACE_Env_Value::fetch_value (void) +{ +#if defined (ACE_WIN32) + const ACE_TCHAR *env = ACE_OS::getenv (this->varname_); + if (env != 0) + ACE_Convert (env, value_); +#else + char *nenv = ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (this->varname_)); + if (nenv != 0) + ACE_Convert (ACE_TEXT_CHAR_TO_TCHAR (nenv), this->value_); +#endif +} + +template ACE_INLINE const ACE_TCHAR* +ACE_Env_Value::varname (void) const +{ + return this->varname_; +} + +template ACE_INLINE +ACE_Env_Value::~ACE_Env_Value (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Event.cpp b/dep/ACE_wrappers/ace/Event.cpp new file mode 100644 index 000000000..ea5f86d99 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event.cpp @@ -0,0 +1,93 @@ +// $Id: Event.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Event.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Event.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, Event, "$Id: Event.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Event::ACE_Event (int manual_reset, + int initial_state, + int type, + const ACE_TCHAR *name, + void *arg, + LPSECURITY_ATTRIBUTES sa) + : removed_ (false) +{ + if (ACE_OS::event_init (&this->handle_, + manual_reset, + initial_state, + type, + name, + arg, + sa) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Event::ACE_Event"))); +} + +ACE_Event::~ACE_Event (void) +{ + this->remove (); +} + +int +ACE_Event::remove (void) +{ + int result = 0; + if (!this->removed_) + { + this->removed_ = true; + result = ACE_OS::event_destroy (&this->handle_); + } + return result; +} + +int +ACE_Event::wait (void) +{ + return ACE_OS::event_wait (&this->handle_); +} + +int +ACE_Event::wait (const ACE_Time_Value *abstime, int use_absolute_time) +{ + return ACE_OS::event_timedwait (&this->handle_, + const_cast (abstime), + use_absolute_time); +} + +int +ACE_Event::signal (void) +{ + return ACE_OS::event_signal (&this->handle_); +} + +int +ACE_Event::pulse (void) +{ + return ACE_OS::event_pulse (&this->handle_); +} + +int +ACE_Event::reset (void) +{ + return ACE_OS::event_reset (&this->handle_); +} + +void +ACE_Event::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Event.h b/dep/ACE_wrappers/ace/Event.h new file mode 100644 index 000000000..887b504d8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event.h @@ -0,0 +1,143 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Event.h + * + * $Id: Event.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_EVENT_H +#define ACE_EVENT_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_Thread.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Event + * + * @brief A wrapper around the Win32 event locking mechanism. + * + * Portable implementation of an Event mechanism, which is native to + * Win32, but must be emulated on UNIX. All platforms support + * process-scope locking support. However, only Win32 platforms + * support global naming and system-scope locking support. + */ +class ACE_Export ACE_Event +{ +public: + /// Constructor that creates event. + ACE_Event (int manual_reset = 0, + int initial_state = 0, + int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, + void *arg = 0, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Implicitly destroy the event variable. + ~ACE_Event (void); + + /** + * Explicitly destroy the event variable. Note that only one thread + * should call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Underlying handle to event. + ACE_event_t handle (void) const; + + /** + * Set the underlying handle to event. Note that this method assumes + * ownership of the and will close it down in . If + * you want the to stay open when is called make + * sure to call on the before closing it. You are + * responsible for the closing the existing before + * overwriting it. + */ + void handle (ACE_event_t new_handle); + + /** + * if MANUAL reset + * sleep till the event becomes signaled + * event remains signaled after wait() completes. + * else AUTO reset + * sleep till the event becomes signaled + * event resets wait() completes. + */ + int wait (void); + + /// Same as wait() above, but this one can be timed + /// @a abstime is absolute time-of-day if if @a use_absolute_time + /// is non-0, else it is relative time. + int wait (const ACE_Time_Value *abstime, + int use_absolute_time = 1); + + /** + * if MANUAL reset + * wake up all waiting threads + * set to signaled state + * else AUTO reset + * if no thread is waiting, set to signaled state + * if thread(s) are waiting, wake up one waiting thread and + * reset event + */ + int signal (void); + + /** + * if MANUAL reset + * wakeup all waiting threads and + * reset event + * else AUTO reset + * wakeup one waiting thread (if present) and + * reset event + */ + int pulse (void); + + /// Set to nonsignaled state. + int reset (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// The underlying handle. + ACE_event_t handle_; + + /// Keeps track of whether has been called yet to avoid + /// multiple calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// on the same object, which is a bad idea anyway... + bool removed_; + +private: + // = Prevent copying. + ACE_Event (const ACE_Event& event); + const ACE_Event &operator= (const ACE_Event &rhs); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Event.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_EVENT_H */ diff --git a/dep/ACE_wrappers/ace/Event.inl b/dep/ACE_wrappers/ace/Event.inl new file mode 100644 index 000000000..ae0805c95 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event.inl @@ -0,0 +1,18 @@ +// -*- C++ -*- +// $Id: Event.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ACE_event_t +ACE_Event::handle (void) const +{ + return this->handle_; +} + +ACE_INLINE void +ACE_Event::handle (ACE_event_t new_handle) +{ + this->handle_ = new_handle; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Event_Handler.cpp b/dep/ACE_wrappers/ace/Event_Handler.cpp new file mode 100644 index 000000000..9e0a10e6a --- /dev/null +++ b/dep/ACE_wrappers/ace/Event_Handler.cpp @@ -0,0 +1,396 @@ +// Event_Handler.cpp +// $Id: Event_Handler.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Event_Handler.h" +#include "ace/OS_Errno.h" +#include "ace/Reactor.h" +#include "ace/Thread_Manager.h" +/* Need to see if ACE_HAS_BUILTIN_ATOMIC_OP defined */ +#include "ace/Atomic_Op.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Event_Handler.inl" +#endif /* __ACE_INLINE__ */ + +#include + +ACE_RCSID(ace, Event_Handler, "$Id: Event_Handler.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Implement conceptually abstract virtual functions in the base class +// so derived classes don't have to implement unused ones. + +ACE_Event_Handler::ACE_Event_Handler (ACE_Reactor *r, + int p) + : reference_count_ (1), + priority_ (p), + reactor_ (r), + reference_counting_policy_ (Reference_Counting_Policy::DISABLED) +{ + // ACE_TRACE ("ACE_Event_Handler::ACE_Event_Handler"); +} + +ACE_Event_Handler::~ACE_Event_Handler (void) +{ + // ACE_TRACE ("ACE_Event_Handler::~ACE_Event_Handler"); +} + +// Gets the file descriptor associated with this I/O device. + +ACE_HANDLE +ACE_Event_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_Event_Handler::get_handle"); + return ACE_INVALID_HANDLE; +} + +// Sets the file descriptor associated with this I/O device. + +void +ACE_Event_Handler::set_handle (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::set_handle"); +} + +// Gets the priority of this handler. + +int +ACE_Event_Handler::priority (void) const +{ + ACE_TRACE ("ACE_Event_Handler::priority"); + return this->priority_; +} + +// Sets the priority + +void +ACE_Event_Handler::priority (int priority) +{ + ACE_TRACE ("ACE_Event_Handler::priority"); + this->priority_ = priority; +} + +// Called when the object is about to be removed from the Dispatcher +// tables. + +int +ACE_Event_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Event_Handler::handle_close"); + return -1; +} + +// Called when input becomes available on fd. + +int +ACE_Event_Handler::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_input"); + return -1; +} + +// Called when output is possible on fd. + +int +ACE_Event_Handler::handle_output (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_output"); + return -1; +} + +// Called when urgent data is available on fd. + +int +ACE_Event_Handler::handle_exception (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_exception"); + return -1; +} + +// Called when timer expires, TV stores the current time. + +int +ACE_Event_Handler::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_TRACE ("ACE_Event_Handler::handle_timeout"); + return -1; +} + +// Called when a monitored Process exits + +int +ACE_Event_Handler::handle_exit (ACE_Process *) +{ + ACE_TRACE ("ACE_Event_Handler::handle_exit"); + return -1; +} + +// Called when a registered signal occurs. + +int +ACE_Event_Handler::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Event_Handler::handle_signal"); + return -1; +} + +int +ACE_Event_Handler::resume_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler::resume_handler"); + + // Return a default value and allow the reactor to take care of + // resuming the handler + return ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER; +} + + +int +ACE_Event_Handler::handle_qos (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_qos"); + return -1; +} + +int +ACE_Event_Handler::handle_group_qos (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_group_qos"); + return -1; +} + +void +ACE_Event_Handler::reactor (ACE_Reactor *reactor) +{ + ACE_TRACE ("ACE_Event_Handler::reactor"); + this->reactor_ = reactor; +} + +ACE_Reactor * +ACE_Event_Handler::reactor (void) const +{ + ACE_TRACE ("ACE_Event_Handler::reactor"); + return this->reactor_; +} + +ACE_Reactor_Timer_Interface * +ACE_Event_Handler::reactor_timer_interface (void) const +{ + ACE_TRACE ("ACE_Event_Handler::reactor_timer_interface"); + return this->reactor_; +} + +ACE_Event_Handler::Reference_Count +ACE_Event_Handler::add_reference (void) +{ + bool const reference_counting_required = + this->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + if (reference_counting_required) + return ++this->reference_count_; + else + return 1; +} + +ACE_Event_Handler::Reference_Count +ACE_Event_Handler::remove_reference (void) +{ + bool const reference_counting_required = + this->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + if (reference_counting_required) + { + Reference_Count result = + --this->reference_count_; + + if (result == 0) + delete this; + + return result; + } + else + { + return 1; + } +} + +ACE_Event_Handler::Policy::~Policy (void) +{ +} + +ACE_Event_Handler::Reference_Counting_Policy::Reference_Counting_Policy (Reference_Counting_Policy::Value value) + : value_ (value) +{ +} + +ACE_Event_Handler::Reference_Counting_Policy::Value +ACE_Event_Handler::Reference_Counting_Policy::value (void) const +{ + return this->value_; +} + +void +ACE_Event_Handler::Reference_Counting_Policy::value (ACE_Event_Handler::Reference_Counting_Policy::Value value) +{ + this->value_ = value; +} + +ACE_Event_Handler::Reference_Counting_Policy & +ACE_Event_Handler::reference_counting_policy (void) +{ + return this->reference_counting_policy_; +} + +//#if !defined (ACE_HAS_WINCE) + +ACE_THR_FUNC_RETURN +ACE_Event_Handler::read_adapter (void *args) +{ + ACE_Event_Handler *this_ptr = static_cast (args); + ACE_Reactor *r = this_ptr->reactor (); + + while (this_ptr->handle_input (ACE_STDIN) != -1) + continue; + + this_ptr->handle_close (ACE_STDIN, ACE_Event_Handler::READ_MASK); + // It's possible for handle_close() to "delete this" so we need to + // cache the reactor pointer and use it here. + r->notify (); + + return 0; +} + +int +ACE_Event_Handler::register_stdin_handler (ACE_Event_Handler *eh, + ACE_Reactor *reactor, + ACE_Thread_Manager *thr_mgr, + int flags) +{ +#if defined (ACE_WIN32) + ACE_UNUSED_ARG (reactor); + + eh->reactor (reactor); + return thr_mgr->spawn (&read_adapter, static_cast (eh), flags); +#else + // Keep compilers happy. + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (thr_mgr); + return reactor->register_handler (ACE_STDIN, + eh, + ACE_Event_Handler::READ_MASK); +#endif /* ACE_WIN32 */ +} + +int +ACE_Event_Handler::remove_stdin_handler (ACE_Reactor *reactor, + ACE_Thread_Manager * /* thr_mgr */) +{ +#if defined (ACE_WIN32) + ACE_UNUSED_ARG (reactor); + + // What should we do here? + ACE_NOTSUP_RETURN (-1); +#else + return reactor->remove_handler (ACE_STDIN, + ACE_Event_Handler::READ_MASK); +#endif /* ACE_WIN32 */ +} + +//#endif /* ACE_HAS_WINCE */ + +// --------------------------------------------------------------------- + +ACE_Event_Handler_var::ACE_Event_Handler_var (void) + : ptr_ (0) +{ +} + +ACE_Event_Handler_var::ACE_Event_Handler_var (ACE_Event_Handler *p) + : ptr_ (p) +{ +} + +ACE_Event_Handler_var::ACE_Event_Handler_var (const ACE_Event_Handler_var &b) + : ptr_ (b.ptr_) +{ + if (this->ptr_ != 0) + { + this->ptr_->add_reference (); + } +} + +ACE_Event_Handler_var::~ACE_Event_Handler_var (void) +{ + if (this->ptr_ != 0) + { + ACE_Errno_Guard eguard (errno); + this->ptr_->remove_reference (); + } +} + +ACE_Event_Handler_var & +ACE_Event_Handler_var::operator= (ACE_Event_Handler *p) +{ + if (this->ptr_ != p) + { + ACE_Event_Handler_var tmp (p); + std::swap (this->ptr_, tmp.ptr_); + } + + return *this; +} + +ACE_Event_Handler_var & +ACE_Event_Handler_var::operator= (const ACE_Event_Handler_var &b) +{ + ACE_Event_Handler_var tmp (b); + std::swap (this->ptr_, tmp.ptr_); + + return *this; +} + +ACE_Event_Handler * +ACE_Event_Handler_var::operator->() const +{ + return this->ptr_; +} + +ACE_Event_Handler * +ACE_Event_Handler_var::handler (void) const +{ + return this->ptr_; +} + +ACE_Event_Handler * +ACE_Event_Handler_var::release (void) +{ + ACE_Event_Handler * const old = this->ptr_; + this->ptr_ = 0; + return old; +} + +void +ACE_Event_Handler_var::reset (ACE_Event_Handler *p) +{ + *this = p; +} + +// --------------------------------------------------------------------- + +ACE_Notification_Buffer::ACE_Notification_Buffer (void) +{ + ACE_TRACE ("ACE_Notification_Buffer::ACE_Notification_Buffer"); +} + +ACE_Notification_Buffer::ACE_Notification_Buffer (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) + : eh_ (eh), + mask_ (mask) +{ + ACE_TRACE ("ACE_Notification_Buffer::ACE_Notification_Buffer"); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Event_Handler.h b/dep/ACE_wrappers/ace/Event_Handler.h new file mode 100644 index 000000000..28a762892 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event_Handler.h @@ -0,0 +1,388 @@ +/* -*- C++ -*- */ + +//========================================================================== +/** + * @file Event_Handler.h + * + * $Id: Event_Handler.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_EVENT_HANDLER_H +#define ACE_EVENT_HANDLER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_signal.h" +#include "ace/Atomic_Op.h" +#include "ace/Synch_Traits.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration. +class ACE_Message_Block; +class ACE_Reactor; +class ACE_Reactor_Timer_Interface; +class ACE_Thread_Manager; +class ACE_Process; + +typedef unsigned long ACE_Reactor_Mask; + +/** + * @class ACE_Event_Handler + * + * @brief Provides an abstract interface for handling various types of + * I/O, timer, and signal events. + * + * Subclasses read/write input/output on an I/O descriptor, + * handle an exception raised on an I/O descriptor, handle a + * timer's expiration, or handle a signal. + */ +class ACE_Export ACE_Event_Handler +{ +public: + enum + { + LO_PRIORITY = 0, + HI_PRIORITY = 10, + NULL_MASK = 0, +#if defined (ACE_USE_POLL) + READ_MASK = POLLIN, + WRITE_MASK = POLLOUT, + EXCEPT_MASK = POLLPRI, +#else /* USE SELECT */ + READ_MASK = (1 << 0), + WRITE_MASK = (1 << 1), + EXCEPT_MASK = (1 << 2), +#endif /* ACE_USE_POLL */ + ACCEPT_MASK = (1 << 3), + CONNECT_MASK = (1 << 4), + TIMER_MASK = (1 << 5), + QOS_MASK = (1 << 6), + GROUP_QOS_MASK = (1 << 7), + SIGNAL_MASK = (1 << 8), + ALL_EVENTS_MASK = READ_MASK | + WRITE_MASK | + EXCEPT_MASK | + ACCEPT_MASK | + CONNECT_MASK | + TIMER_MASK | + QOS_MASK | + GROUP_QOS_MASK | + SIGNAL_MASK, + RWE_MASK = READ_MASK | + WRITE_MASK | + EXCEPT_MASK, + DONT_CALL = (1 << 9) + }; + + /// Destructor is virtual to enable proper cleanup. + virtual ~ACE_Event_Handler (void); + + /// Get the I/O handle. + virtual ACE_HANDLE get_handle (void) const; + + /// Set the I/O handle. + virtual void set_handle (ACE_HANDLE); + + // = Get/set priority + + // Priorities run from MIN_PRIORITY (which is the "lowest priority") + // to MAX_PRIORITY (which is the "highest priority"). + /// Get the priority of the Event_Handler. + virtual int priority (void) const; + + /// Set the priority of the Event_Handler. + virtual void priority (int priority); + + /// Called when input events occur (e.g., connection or data). + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + /// Called when output events are possible (e.g., when flow control + /// abates or non-blocking connection completes). + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + /// Called when an exceptional events occur (e.g., SIGURG). + virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE); + + /** + * Called when timer expires. @a current_time represents the current + * time that the was selected for timeout + * dispatching and @a act is the asynchronous completion token that + * was passed in when was invoked. + */ + virtual int handle_timeout (const ACE_Time_Value ¤t_time, + const void *act = 0); + + /// Called when a process exits. + virtual int handle_exit (ACE_Process *); + + /// Called when a method returns -1 or when the + /// method is called on an ACE_Reactor. The + /// @a close_mask indicates which event has triggered the + /// method callback on a particular @a handle. + virtual int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask); + + /// Called when object is signaled by OS (either via UNIX signals or + /// when a Win32 object becomes signaled). + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + enum + { + /// The handler is not resumed at all. Could lead to deadlock.. + ACE_EVENT_HANDLER_NOT_RESUMED = -1, + /// The reactor takes responsibility of resuming the handler and + /// is the default + ACE_REACTOR_RESUMES_HANDLER = 0, + /// The application takes responsibility of resuming the handler + ACE_APPLICATION_RESUMES_HANDLER + }; + /** + * Called to figure out whether the handler needs to resumed by the + * reactor or the application can take care of it. The default + * value of 0 would be returned which would allow the reactor to + * take care of resumption of the handler. The application can + * return a value more than zero and decide to resume the handler + * themseleves. + * + * @note This method is only useful for the ACE_TP_Reactor. Sad + * that we have to have this method in a class that is supposed to + * be used across different components in ACE. + */ + virtual int resume_handler (void); + + virtual int handle_qos (ACE_HANDLE = ACE_INVALID_HANDLE); + virtual int handle_group_qos (ACE_HANDLE = ACE_INVALID_HANDLE); + + // = Accessors to set/get the various event demultiplexors. + /// Set the event demultiplexors. + virtual void reactor (ACE_Reactor *reactor); + + /// Get the event demultiplexors. + virtual ACE_Reactor *reactor (void) const; + + /// Get only the reactor's timer related interface. + virtual ACE_Reactor_Timer_Interface *reactor_timer_interface (void) const; + + /** + * Used to read from non-socket ACE_HANDLEs in our own thread to + * work around Win32 limitations that don't allow us to 'able on + * Win32. + */ + static int register_stdin_handler (ACE_Event_Handler *eh, + ACE_Reactor *reactor, + ACE_Thread_Manager *thr_mgr, + int flags = THR_DETACHED); + + /// Performs the inverse of the method. + static int remove_stdin_handler (ACE_Reactor *reactor, + ACE_Thread_Manager *thr_mgr); + + /// Reference count type. + typedef long Reference_Count; + + /// Increment reference count on the handler. + /** + * This method is called when the handler is registered with the + * Reactor and when the Reactor makes an upcall on the handler. + * Reference count is 1 when the handler is created. + * + * @return Current reference count. + */ + virtual Reference_Count add_reference (void); + + /// Decrement reference count on the handler. + /** + * This method is called when the handler is removed from the + * Reactor and when an upcall made on the handler by the Reactor + * completes. Handler is deleted when the reference count reaches + * 0. + * + * @return Current reference count. + */ + virtual Reference_Count remove_reference (void); + + /** + * @class Policy + * + * @brief Base class for all handler policies. + */ + class ACE_Export Policy + { + + public: + + /// Virtual destructor. + virtual ~Policy (void); + }; + + /** + * @class Reference_Counting_Policy + * + * @brief This policy dictates the reference counting requirements + * for the handler. + * + * This policy allows applications to configure whether it wants the + * Reactor to call add_reference() and remove_reference() during + * registrations, removals, and upcalls. + * + * Default: DISABLED. + */ + class ACE_Export Reference_Counting_Policy : public Policy + { + /// This policy can only be created by the handler. + friend class ACE_Event_Handler; + + public: + + enum Value + { + /// Perform reference counting. + ENABLED, + /// Don't perform reference counting. + DISABLED + }; + + /// Current Reference_Counting_Policy. + Value value (void) const; + + /// Update Reference_Counting_Policy. + void value (Value value); + + private: + + /// Private constructor. + Reference_Counting_Policy (Value value); + + /// The value of the policy. + Value value_; + }; + + /// Current Reference_Counting_Policy. + Reference_Counting_Policy &reference_counting_policy (void); + +protected: + /// Force ACE_Event_Handler to be an abstract base class. + ACE_Event_Handler (ACE_Reactor * = 0, + int priority = ACE_Event_Handler::LO_PRIORITY); + + /// Typedef for implementation of reference counting. + typedef ACE_Atomic_Op Atomic_Reference_Count; + + /// Reference count. + Atomic_Reference_Count reference_count_; + +private: + + /// Priority of this Event_Handler. + int priority_; + + /// Pointer to the various event demultiplexors. + ACE_Reactor *reactor_; + + /// Reference counting requirements. + Reference_Counting_Policy reference_counting_policy_; +}; + +/** + * @class ACE_Event_Handler_var + * + * @brief Auto pointer like class for Event Handlers. + * + * Used to manage lifecycle of handlers. This class calls + * ACE_Event_Handler::remove_reference() in its destructor. + */ +class ACE_Export ACE_Event_Handler_var +{ + +public: + + /// Default constructor. + ACE_Event_Handler_var (void); + + /// Construct with a handler. + ACE_Event_Handler_var (ACE_Event_Handler *p); + + /// Copy constructor. + ACE_Event_Handler_var (const ACE_Event_Handler_var &b); + + /// Destructor. + ~ACE_Event_Handler_var (void); + + /// Assignment to a handler. + ACE_Event_Handler_var &operator= (ACE_Event_Handler *p); + + /// Assignment to a ACE_Event_Handler_var. + ACE_Event_Handler_var &operator= (const ACE_Event_Handler_var &b); + + /// Overloaded "->". + ACE_Event_Handler *operator-> () const; + + /// Access the handler. + ACE_Event_Handler *handler (void) const; + + /// Release the handler. + ACE_Event_Handler *release (void); + + /// Reset the handler. + void reset (ACE_Event_Handler *p = 0); + +private: + + /// Handler. + ACE_Event_Handler *ptr_; +}; + +/** + * @class ACE_Notification_Buffer + * + * @brief Simple wrapper for passing s and + * ACE_Reactor_Masks between threads. + */ +class ACE_Export ACE_Notification_Buffer +{ +public: + ACE_Notification_Buffer (void); + + ACE_Notification_Buffer (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + + /// Default dtor. + ~ACE_Notification_Buffer (void); + + /// Pointer to the Event_Handler that will be dispatched + /// by the main event loop. + ACE_Event_Handler *eh_; + + /// Mask that indicates which method to call. + ACE_Reactor_Mask mask_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Event_Handler.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_EVENT_HANDLER_H */ diff --git a/dep/ACE_wrappers/ace/Event_Handler.inl b/dep/ACE_wrappers/ace/Event_Handler.inl new file mode 100644 index 000000000..d97c45466 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event_Handler.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id: Event_Handler.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Notification_Buffer::~ACE_Notification_Buffer (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Event_Handler_T.cpp b/dep/ACE_wrappers/ace/Event_Handler_T.cpp new file mode 100644 index 000000000..45d9d4e27 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event_Handler_T.cpp @@ -0,0 +1,125 @@ +// Event_Handler_T.cpp +// +// $Id: Event_Handler_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_EVENT_HANDLER_T_CPP +#define ACE_EVENT_HANDLER_T_CPP + +#include "ace/Event_Handler_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +#if !defined (__ACE_INLINE__) +#include "ace/Event_Handler_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Event_Handler_T) + +template void +ACE_Event_Handler_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Event_Handler_T::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Event_Handler_T::~ACE_Event_Handler_T (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::~ACE_Event_Handler_T"); + if (this->delete_handler_) + delete this->op_handler_; +} + +template +ACE_Event_Handler_T::ACE_Event_Handler_T (T *op_handler, int delete_handler, + GET_HANDLE get_handle, + IO_HANDLER input_h, + CL_HANDLER close_h, + SIG_HANDLER sig_h, + TO_HANDLER timeout_h, + IO_HANDLER output_h, + SET_HANDLE set_handle, + IO_HANDLER except_h) + : op_handler_ (op_handler), + input_handler_ (input_h), + output_handler_ (output_h), + except_handler_ (except_h), + to_handler_ (timeout_h), + cl_handler_ (close_h), + sig_handler_ (sig_h), + delete_handler_ (delete_handler), + set_handle_ (set_handle), + get_handle_ (get_handle) +{ + ACE_TRACE ("ACE_Event_Handler_T::ACE_Event_Handler_T"); +} + +template ACE_HANDLE +ACE_Event_Handler_T::get_handle (void) const +{ + ACE_TRACE ("ACE_Event_Handler_T::get_handle"); + return this->get_handle_ == 0 ? ACE_INVALID_HANDLE : (this->op_handler_->*get_handle_) (); +} + +template void +ACE_Event_Handler_T::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_Event_Handler_T::set_handle"); + if (this->set_handle_ != 0) + (this->op_handler_->*set_handle_) (h); +} + +template int +ACE_Event_Handler_T::handle_input (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_input"); + return this->input_handler_ == 0 ? 0 : (this->op_handler_->*input_handler_) (fd); +} + +template int +ACE_Event_Handler_T::handle_output (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_output"); + return this->output_handler_ == 0 ? 0 : (this->op_handler_->*output_handler_) (fd); +} + +template int +ACE_Event_Handler_T::handle_exception (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_exception"); + return this->except_handler_ == 0 ? 0 : (this->op_handler_->*except_handler_) (fd); +} + +template int +ACE_Event_Handler_T::handle_timeout (const ACE_Time_Value &tv, const void *arg) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_timeout"); + return this->to_handler_ == 0 ? 0 : (this->op_handler_->*to_handler_) (tv, arg); +} + +template int +ACE_Event_Handler_T::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_close"); + return this->cl_handler_ == 0 ? 0 : (this->op_handler_->*cl_handler_) (fd, close_mask); +} + +template int +ACE_Event_Handler_T::handle_signal (int signum, siginfo_t *s, ucontext_t *u) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_signal"); + return this->sig_handler_ == 0 ? 0 : (this->op_handler_->*sig_handler_) (signum, s, u); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + +#endif /* ACE_EVENT_HANDLER_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Event_Handler_T.h b/dep/ACE_wrappers/ace/Event_Handler_T.h new file mode 100644 index 000000000..7f81b3474 --- /dev/null +++ b/dep/ACE_wrappers/ace/Event_Handler_T.h @@ -0,0 +1,191 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Handler_T.h + * + * $Id: Event_Handler_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_EVENT_HANDLER_T_H +#define ACE_EVENT_HANDLER_T_H +#include /**/ "ace/pre.h" + +#include "ace/Event_Handler.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Event_Handler_T + * + * @brief Enable a class that doesn't inherit from the + * ACE_Event_Handler to be incorporated into the ACE_Reactor + * framework. Thanks to Greg Lavender (g.lavender@isode.com) + * for sharing this idea. + * + * It is sometimes the case that an application has a hierarchy + * of operation dispatcher classes that have their own + * inheritance hierarchy but also would like to integrate with + * the ACE_Reactor. Rather than adopt a "mixin" approach, it is + * often cleaner to define a template as a subclass of + * ACE_Event_Handler and paramterize it with an operation + * dispatcher type. + * When constructing an instantiation of the ACE_Event_Handler_T + * object, a set of pointers to member functions must be + * provided so that when one of the handle_* methods is called + * by the ACE_Reactor, the appropriate method is called on the + * underlying operations object. This is done since in some + * cases it is useful to map any event that happens to the same + * method on an object. + * The ACE_Event_Handler_T template is instantiated by an + * operations object and registered with the ACE_Reactor, and it + * then calls the appropriate op_handler. So, it's basically + * just another level of indirection in event dispatching. The + * coupling betweent the ultimate handler of the event and the + * ACE_Event_Handler class is relaxed a bit by have this + * intermediate object of type around. The + * client object can then dynamically change the bindings for + * the various handlers so that during the life of one of the + * operation objects, it can change how it wants events to be + * handled. It just instantiates a new instance of the template + * with different bindings and reregisters this new object with + * the ACE_Reactor. + */ +template +class ACE_Event_Handler_T : public ACE_Event_Handler +{ +public: + // = Typedefs to simplify pointer-to-member-function registration. + + // Get/set the underlying handle. + typedef ACE_HANDLE (T::*GET_HANDLE) (void) const; + typedef void (T::*SET_HANDLE) (ACE_HANDLE); + + /// Handle I/O events. + typedef int (T::*IO_HANDLER) (ACE_HANDLE); + + /// Handle timeout events. + typedef int (T::*TO_HANDLER) (const ACE_Time_Value &, const void *); + + /// Handle close events. + typedef int (T::*CL_HANDLER) (ACE_HANDLE, ACE_Reactor_Mask); + + /// = Initialization and termination methods. + typedef int (T::*SIG_HANDLER) (int, siginfo_t*, ucontext_t*); + + /// Initialize the op_handler. + ACE_Event_Handler_T (T *op_handler, + int delete_handler, + GET_HANDLE get_handle = 0, + IO_HANDLER input = 0, + CL_HANDLER close = 0, + SIG_HANDLER sig = 0, + TO_HANDLER timeout = 0, + IO_HANDLER output = 0, + SET_HANDLE set_handle = 0, + IO_HANDLER except = 0); + + /// Close down and delete the + ~ACE_Event_Handler_T (void); + + // = Override all the ACE_Event_Handler methods. + + // These methods all delegate down to the operations handler. + virtual ACE_HANDLE get_handle (void) const; + virtual void set_handle (ACE_HANDLE); + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE); + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask); + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + // = Get/set the operations handler. + T *op_handler (void); + void op_handler (T *); + + // = Get/set the target pointer-to-method used for dispatching. + + GET_HANDLE handle_get (void); + void handle_get (GET_HANDLE); + + SET_HANDLE handle_set (void); + void handle_set (SET_HANDLE); + + IO_HANDLER input_handler (void); + void input_handler (IO_HANDLER); + + IO_HANDLER output_handler (void); + void output_handler (IO_HANDLER); + + IO_HANDLER except_handler (void); + void except_handler (IO_HANDLER); + + TO_HANDLER to_handler (void); + void to_handler (TO_HANDLER); + + CL_HANDLER cl_handler (void); + void cl_handler (CL_HANDLER); + + SIG_HANDLER sig_handler (void); + void sig_handler (SIG_HANDLER); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Pointer to the object that handles all the delegated operations. + T *op_handler_; + + // = Handle input, output, and exception events. + IO_HANDLER input_handler_; + IO_HANDLER output_handler_; + IO_HANDLER except_handler_; + + /// Handle timeout events. + TO_HANDLER to_handler_; + + /// Handle close events. + CL_HANDLER cl_handler_; + + /// Handle signal events. + SIG_HANDLER sig_handler_; + + /// Keeps track of whether we need to delete the handler in the + /// destructor. + int delete_handler_; + + // = Get/set underlying handle. + SET_HANDLE set_handle_; + GET_HANDLE get_handle_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Event_Handler_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Event_Handler_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Event_Handler_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ +#include /**/ "ace/post.h" +#endif /* ACE_EVENT_HANDLER_H */ diff --git a/dep/ACE_wrappers/ace/Event_Handler_T.inl b/dep/ACE_wrappers/ace/Event_Handler_T.inl new file mode 100644 index 000000000..40db43e8e --- /dev/null +++ b/dep/ACE_wrappers/ace/Event_Handler_T.inl @@ -0,0 +1,135 @@ +// -*- C++ -*- +// +// $Id: Event_Handler_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE void +ACE_Event_Handler_T::op_handler (T *op) +{ + ACE_TRACE ("ACE_Event_Handler_T::op_handler"); + this->op_handler_ = op; +} + +template ACE_INLINE T * +ACE_Event_Handler_T::op_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::op_handler"); + return this->op_handler_; +} + +template ACE_INLINE typename ACE_Event_Handler_T::GET_HANDLE +ACE_Event_Handler_T::handle_get (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_get"); + return this->get_handle_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::handle_get (typename ACE_Event_Handler_T::GET_HANDLE h) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_get"); + this->get_handle_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::SET_HANDLE +ACE_Event_Handler_T::handle_set (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_set"); + return this->set_handle_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::handle_set (typename ACE_Event_Handler_T::SET_HANDLE h) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_set"); + this->set_handle_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::IO_HANDLER +ACE_Event_Handler_T::input_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::input_handler"); + return this->input_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::input_handler (typename ACE_Event_Handler_T::IO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::input_handler"); + this->input_handler_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::IO_HANDLER +ACE_Event_Handler_T::output_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::output_handler"); + return this->output_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::output_handler (typename ACE_Event_Handler_T::IO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::output_handler"); + this->output_handler_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::IO_HANDLER +ACE_Event_Handler_T::except_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::except_handler"); + return this->except_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::except_handler (typename ACE_Event_Handler_T::IO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::except_handler"); + this->except_handler_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::TO_HANDLER +ACE_Event_Handler_T::to_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::to_handler"); + return this->to_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::to_handler (typename ACE_Event_Handler_T::TO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::to_handler"); + this->to_handler_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::CL_HANDLER +ACE_Event_Handler_T::cl_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::cl_handler"); + return this->cl_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::cl_handler (typename ACE_Event_Handler_T::CL_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::cl_handler"); + this->cl_handler_ = h; +} + +template ACE_INLINE typename ACE_Event_Handler_T::SIG_HANDLER +ACE_Event_Handler_T::sig_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::sig_handler"); + return this->sig_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::sig_handler (typename ACE_Event_Handler_T::SIG_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::sig_handler"); + this->sig_handler_ = h; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Exception_Macros.h b/dep/ACE_wrappers/ace/Exception_Macros.h new file mode 100644 index 000000000..bb74b1a21 --- /dev/null +++ b/dep/ACE_wrappers/ace/Exception_Macros.h @@ -0,0 +1,55 @@ +// -*- C++ -*- + +// ============================================================================ +/** + * @file Exception_Macros.h + * + * $Id: Exception_Macros.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Writing code that is portable between platforms with or without + * native C++ exceptions is hard. The following macros offer some + * help on this task. + * + * @author Nanbor Wang + * @author Aniruddha Gokhale + * @author Carlos O'Ryan + * @author Krishnakumar B , et al. + */ +// ============================================================================ + +// Macros for handling exceptions. + +#ifndef ACE_EXCEPTION_MACROS_H +#define ACE_EXCEPTION_MACROS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +// By default, if the compiler supports native exception handling, assume +// CORBA also support native exception handling. But it can be disabled by +// defining ACE_CORBA_HAS_EXCEPTIONS=0. If the compiler does not support +// exceptions handling, make sure native exception handling is disabled. +#if defined (ACE_HAS_EXCEPTIONS) +# if defined (ACE_CORBA_HAS_EXCEPTIONS) +# if (ACE_CORBA_HAS_EXCEPTIONS == 0) +# undef ACE_USES_NATIVE_EXCEPTIONS +# else /* ACE_CORBA_HAS_EXCEPTIONS != 0 */ +# define ACE_USES_NATIVE_EXCEPTIONS +# endif /* ACE_CORBA_HAS_EXCEPTIONS == 0 */ +# else +# define ACE_USES_NATIVE_EXCEPTIONS +# define ACE_CORBA_HAS_EXCEPTIONS +# endif /* ACE_CORBA_HAS_EXCEPTIONS */ +#else /* ! ACE_HAS_EXCEPTIONS */ +# undef ACE_CORBA_HAS_EXCEPTIONS +# undef ACE_USES_NATIVE_EXCEPTIONS +#endif /* ACE_HAS_EXCEPTIONS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_EXCEPTION_MACROS_H */ diff --git a/dep/ACE_wrappers/ace/FIFO.cpp b/dep/ACE_wrappers/ace/FIFO.cpp new file mode 100644 index 000000000..e3970015c --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO.cpp @@ -0,0 +1,78 @@ +// $Id: FIFO.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FIFO.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FIFO.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_sys_stat.h" +#include "ace/OS_NS_fcntl.h" + +ACE_RCSID(ace, FIFO, "$Id: FIFO.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO) + +void +ACE_FIFO::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FIFO::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("rendezvous_ = %s"), this->rendezvous_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_FIFO::open (const ACE_TCHAR *r, int flags, mode_t perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO::open"); + ACE_OS::strsncpy (this->rendezvous_, r, MAXPATHLEN); + + if ((flags & O_CREAT) != 0 + && ACE_OS::mkfifo (this->rendezvous_, perms) == -1 + && !(errno == EEXIST)) + return -1; + + this->set_handle (ACE_OS::open (this->rendezvous_, flags, 0, sa)); + return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0; +} + +ACE_FIFO::ACE_FIFO (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO::ACE_FIFO"); + if (this->open (fifo_name, flags, perms, sa) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_FIFO"))); +} + +ACE_FIFO::ACE_FIFO (void) +{ +// ACE_TRACE ("ACE_FIFO::ACE_FIFO"); +} + +int +ACE_FIFO::close (void) +{ + ACE_TRACE ("ACE_FIFO::close"); + int result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO.h b/dep/ACE_wrappers/ace/FIFO.h new file mode 100644 index 000000000..2d590563a --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO.h @@ -0,0 +1,85 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file FIFO.h + * + * $Id: FIFO.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//========================================================================== + + +#ifndef ACE_FIFO_H +#define ACE_FIFO_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/IPC_SAP.h" +#include "ace/os_include/os_limits.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_FIFO + * + * @brief Abstract base class for UNIX FIFOs + * + * UNIX FIFOs are also known Named Pipes, which are totally + * unrelated to Win32 Named Pipes. If you want to use a local + * IPC mechanism that will be portable to both UNIX and Win32, + * take a look at the classes. + */ +class ACE_Export ACE_FIFO : public ACE_IPC_SAP +{ +public: + /// Open up the named pipe on the in accordance with the + /// flags. + int open (const ACE_TCHAR *rendezvous, int flags, mode_t perms, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Close down the ACE_FIFO without removing the rendezvous point. + int close (void); + + /// Close down the ACE_FIFO and remove the rendezvous point from the + /// file system. + int remove (void); + + /// Return the local address of this endpoint. + int get_local_addr (const ACE_TCHAR *&rendezvous) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Make these protected to ensure that the class is "abstract." + /// Default constructor. + ACE_FIFO (void); + + /// Open up the named pipe on the in accordance with the + /// flags. + ACE_FIFO (const ACE_TCHAR *rendezvous, int flags, mode_t perms, + LPSECURITY_ATTRIBUTES sa = 0); + +private: + /// Rendezvous point in the file system. + ACE_TCHAR rendezvous_[MAXPATHLEN + 1]; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FIFO.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FIFO_H */ diff --git a/dep/ACE_wrappers/ace/FIFO.inl b/dep/ACE_wrappers/ace/FIFO.inl new file mode 100644 index 000000000..05cc030a9 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO.inl @@ -0,0 +1,25 @@ +// -*- C++ -*- +// +// $Id: FIFO.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_unistd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_FIFO::get_local_addr (const ACE_TCHAR *&r) const +{ + ACE_TRACE ("ACE_FIFO::get_local_addr"); + r = this->rendezvous_; + return 0; +} + +ACE_INLINE int +ACE_FIFO::remove (void) +{ + ACE_TRACE ("ACE_FIFO::remove"); + int const result = this->close (); + return ACE_OS::unlink (this->rendezvous_) == -1 || result == -1 ? -1 : 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Recv.cpp b/dep/ACE_wrappers/ace/FIFO_Recv.cpp new file mode 100644 index 000000000..254e30f21 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Recv.cpp @@ -0,0 +1,88 @@ +// $Id: FIFO_Recv.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FIFO_Recv.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_fcntl.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FIFO_Recv.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FIFO_Recv, "$Id: FIFO_Recv.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Recv) + +void +ACE_FIFO_Recv::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FIFO_Recv::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_FIFO::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("aux_handle_ = %d"), this->aux_handle_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_FIFO_Recv::close (void) +{ + ACE_TRACE ("ACE_FIFO_Recv::close"); + int result = ACE_FIFO::close (); + + if (this->aux_handle_ != ACE_INVALID_HANDLE) + return ACE_OS::close (this->aux_handle_); + else + return result; +} + +// Note that persistent means "open fifo for writing, as well as +// reading." This ensures that the fifo never gets EOF, even if there +// aren't any writers at the moment! + +int +ACE_FIFO_Recv::open (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + int persistent, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Recv::open"); + + if (ACE_FIFO::open (fifo_name, ACE_NONBLOCK | flags, perms, sa) == -1) + return -1; + else if (this->disable (ACE_NONBLOCK) == -1) + return -1; + else if (persistent + && (this->aux_handle_ = ACE_OS::open (fifo_name, O_WRONLY, 0, sa)) == ACE_INVALID_HANDLE) + return -1; + else + return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0; +} + +ACE_FIFO_Recv::ACE_FIFO_Recv (void) + : aux_handle_ (ACE_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_FIFO_Recv::ACE_FIFO_Recv"); +} + +ACE_FIFO_Recv::ACE_FIFO_Recv (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + int persistent, + LPSECURITY_ATTRIBUTES sa) + : aux_handle_ (ACE_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_FIFO_Recv::ACE_FIFO_Recv"); + + if (this->ACE_FIFO_Recv::open (fifo_name, + flags, + perms, + persistent, + sa) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_FIFO_Recv"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Recv.h b/dep/ACE_wrappers/ace/FIFO_Recv.h new file mode 100644 index 000000000..c19d102c8 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Recv.h @@ -0,0 +1,85 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file FIFO_Recv.h + * + * $Id: FIFO_Recv.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//========================================================================== + + +#ifndef ACE_FIFO_RECV_H +#define ACE_FIFO_RECV_H + +#include /**/ "ace/pre.h" + +#include "ace/FIFO.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_fcntl.h" +#include "ace/Default_Constants.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_FIFO_Recv + * + * @brief Receiver side of the bytestream C++ wrapper for UNIX + * FIFOs. + */ +class ACE_Export ACE_FIFO_Recv : public ACE_FIFO +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_FIFO_Recv (void); + + /// Open up a bytestream named pipe for reading. + ACE_FIFO_Recv (const ACE_TCHAR *rendezvous, + int flags = O_CREAT | O_RDONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + int persistent = 1, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Open up a bytestream named pipe for reading. + int open (const ACE_TCHAR *rendezvous, + int flags = O_CREAT | O_RDONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + int persistent = 1, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Close down the named pipe. + int close (void); + + /// Recv @a buf of up to @a len bytes. + ssize_t recv (void *buf, size_t len); + + /// Recv @a buf of exactly @a len bytes (block until done). + ssize_t recv_n (void *buf, size_t len); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Auxiliary handle that is used to implement persistent FIFOs. + ACE_HANDLE aux_handle_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FIFO_Recv.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_FIFO_RECV_H */ diff --git a/dep/ACE_wrappers/ace/FIFO_Recv.inl b/dep/ACE_wrappers/ace/FIFO_Recv.inl new file mode 100644 index 000000000..d4c3fee43 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Recv.inl @@ -0,0 +1,24 @@ +// -*- C++ -*- +// +// $Id: FIFO_Recv.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" +#include "ace/OS_NS_unistd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ssize_t +ACE_FIFO_Recv::recv (void *buf, size_t len) +{ + ACE_TRACE ("ACE_FIFO_Recv::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, len); +} + +ACE_INLINE ssize_t +ACE_FIFO_Recv::recv_n (void *buf, size_t n) +{ + ACE_TRACE ("ACE_FIFO_Recv::recv_n"); + return ACE::recv_n (this->get_handle (), buf, n); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Recv_Msg.cpp b/dep/ACE_wrappers/ace/FIFO_Recv_Msg.cpp new file mode 100644 index 000000000..f389d03d2 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Recv_Msg.cpp @@ -0,0 +1,67 @@ +// $Id: FIFO_Recv_Msg.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FIFO_Recv_Msg.h" + +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FIFO_Recv_Msg.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FIFO_Recv_Msg, "$Id: FIFO_Recv_Msg.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Recv_Msg) + +void +ACE_FIFO_Recv_Msg::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FIFO_Recv_Msg::dump"); + ACE_FIFO_Recv::dump (); +#endif /* ACE_HAS_DUMP */ +} + +// Note that persistent means "open FIFO for writing, as well as +// reading." This ensures that the FIFO never gets EOF, even if there +// aren't any writers at the moment! + +int +ACE_FIFO_Recv_Msg::open (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + int persistent, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::open"); + + return ACE_FIFO_Recv::open (fifo_name, + flags, + perms, + persistent, + sa); +} + +ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg (void) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg"); +} + +ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + int persistent, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg"); + + if (this->ACE_FIFO_Recv_Msg::open (fifo_name, + flags, + perms, + persistent, + sa) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_FIFO_Recv_Msg"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Recv_Msg.h b/dep/ACE_wrappers/ace/FIFO_Recv_Msg.h new file mode 100644 index 000000000..80b7bdda9 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Recv_Msg.h @@ -0,0 +1,138 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file FIFO_Recv_Msg.h + * + * $Id: FIFO_Recv_Msg.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_FIFO_RECV_MSG_H +#define ACE_FIFO_RECV_MSG_H +#include /**/ "ace/pre.h" + +#include "ace/FIFO_Recv.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decls +class ACE_Str_Buf; + +/** + * @class ACE_FIFO_Recv_Msg + * + * @brief Receiver side for the record oriented C++ wrapper for UNIX FIFOs. + * + * This method works slightly differently on platforms with the + * @c ACE_HAS_STREAM_PIPES configuration setting than those without. + * With ACE_HAS_STREAM_PIPES, the @c getmsg() system function is used + * and it preserves message boundaries internally. Without + * @c ACE_HAS_STREAM_PIPES, the message boundaries are emulated by + * this class and ACE_FIFO_Send_Msg cooperating. The sending class + * first writes an integer number of bytes in the message, then the + * message. ACE_FIFO_Recv_Msg reads the count, then the data. + * The operational differences occur primarily when a message is larger + * than what a caller of this class requests. See recv() for details. + */ +class ACE_Export ACE_FIFO_Recv_Msg : public ACE_FIFO_Recv +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_FIFO_Recv_Msg (void); + + /// Open up a record-oriented named pipe for reading. + ACE_FIFO_Recv_Msg (const ACE_TCHAR *rendezvous, + int flags = O_CREAT | O_RDONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + int persistent = 1, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Open up a record-oriented named pipe for reading. + int open (const ACE_TCHAR *rendezvous, + int flags = O_CREAT | O_RDONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + int persistent = 1, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Receive a message based on attributes in an ACE_Str_Buf. + /** + * @param msg Reference to an ACE_Str_Buf whose @c buf member points + * to the memory to receive the data and @c maxlen member + * contains the maximum number of bytes to receive. + * On return after successfully reading data, the + * @c len member contains the number of bytes received and + * placed in the buffer pointed to by @c msg.buf. + * + * @retval -1 Error; consult @c errno for specific error number. + * @return If the @c ACE_HAS_STREAM_PIPES configuration setting is + * defined, the return value is the number of bytes received + * in the message and will be the same as @c buf.len. + * The return value from the @c getmsg() system function + * is discarded. + * If @c ACE_HAS_STREAM_PIPES is not defined, the number + * of bytes in the message read from the FIFO is returned. + * If the message is larger than the maximum length + * requested in @c msg.maxlen, the return value reflects + * the entire message length, and the @c msg.len member + * reflects how many bytes were actually placed in the + * caller's buffer. Any part of the message longer than + * @c msg.maxlen is discarded. + */ + ssize_t recv (ACE_Str_Buf &msg); + + /// Receive a message based on buffer pointer and maximum size. + /** + * @param buf Pointer to the memory to receive the data. + * @param len The maximum number of bytes to receive. + * + * @retval -1 Error; consult @c errno for specific error number. + * @return The number of bytes received in the message. For messages + * that are larger than the requested maximum size, the + * behavior is different depending on the @c ACE_HAS_STREAM_PIPES + * configuration setting. With @c ACE_HAS_STREAM_PIPES, + * the return value will be the same as @arg len (this is + * also possible if the message is exactly the same length + * as @arg len, and the two cases are indistinguishable). + * Without @c ACE_HAS_STREAM_PIPES, the return value is + * the total length of the message, including bytes in + * excess of @arg len. The excess bytes are discarded. + */ + ssize_t recv (void *buf, size_t len); + +#if defined (ACE_HAS_STREAM_PIPES) + /// Recv and message via Stream pipes. + ssize_t recv (ACE_Str_Buf *data, + ACE_Str_Buf *cntl, + int *flags); + + /// Recv and message via Stream pipes in "band" mode. + ssize_t recv (int *band, + ACE_Str_Buf *data, + ACE_Str_Buf *cntl, + int *flags); +#endif /* ACE_HAS_STREAM_PIPES */ + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FIFO_Recv_Msg.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FIFO_RECV_MSG_H */ diff --git a/dep/ACE_wrappers/ace/FIFO_Recv_Msg.inl b/dep/ACE_wrappers/ace/FIFO_Recv_Msg.inl new file mode 100644 index 000000000..0a0b0673d --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Recv_Msg.inl @@ -0,0 +1,137 @@ +// -*- C++ -*- +// +// $Id: FIFO_Recv_Msg.inl 82559 2008-08-07 20:23:07Z parsons $ + +#include "ace/Min_Max.h" +#include "ace/OS_NS_stropts.h" +#include "ace/Truncate.h" + +#if !defined (ACE_HAS_STREAM_PIPES) +#include "ace/OS_NS_unistd.h" +#endif + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ssize_t +ACE_FIFO_Recv_Msg::recv (ACE_Str_Buf &recv_msg) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); +#if defined (ACE_HAS_STREAM_PIPES) + int i = 0; + if (ACE_OS::getmsg (this->get_handle (), + (strbuf *) 0, + (strbuf *) &recv_msg, + &i) == -1) + { + return -1; + } + else + { + return recv_msg.len; + } +#else /* Do the ol' 2-read trick... */ + if (ACE_OS::read (this->get_handle (), + (char *) &recv_msg.len, + sizeof recv_msg.len) != sizeof recv_msg.len) + { + return -1; + } + else + { + size_t remaining = static_cast (recv_msg.len); + size_t requested = static_cast (recv_msg.maxlen); + ssize_t recv_len = ACE_OS::read (this->get_handle (), + (char *) recv_msg.buf, + ACE_MIN (remaining, requested)); + + if (recv_len == -1) + { + return -1; + } + + // Tell caller what's really in the buffer. + recv_msg.len = static_cast (recv_len); + + // If there are more bytes remaining in the message, read them and + // throw them away. Leaving them in the FIFO would make it difficult + // to find the start of the next message in the fifo. + // Since the ACE_HAS_STREAM_PIPES version of this method doesn't + // return getmsg()'s indication of "data remaining", don't worry about + // saving the indication here either to read the remainder later. + size_t total_msg_size = remaining; + remaining -= recv_len; + + while (remaining > 0) + { + const size_t throw_away = 1024; + char dev_null[throw_away]; + recv_len = ACE_OS::read (this->get_handle (), + dev_null, + ACE_MIN (remaining, throw_away)); + + if (recv_len == -1) + { + break; + } + + remaining -= recv_len; + } + + return ACE_Utils::truncate_cast (total_msg_size); + } +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE ssize_t +ACE_FIFO_Recv_Msg::recv (void *buf, size_t max_len) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); + ACE_Str_Buf recv_msg ((char *) buf, 0, static_cast (max_len)); + + return this->recv (recv_msg); +} + +#if defined (ACE_HAS_STREAM_PIPES) +ACE_INLINE ssize_t +ACE_FIFO_Recv_Msg::recv (ACE_Str_Buf *data, + ACE_Str_Buf *cntl, + int *flags) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); + if (ACE_OS::getmsg (this->get_handle (), + (strbuf *) cntl, + (strbuf *) data, + flags) == -1) + { + return -1; + } + else + { + return (cntl == 0 ? 0 : cntl->len) + (data == 0 ? 0 : data->len); + } +} + +ACE_INLINE ssize_t +ACE_FIFO_Recv_Msg::recv (int *band, + ACE_Str_Buf *data, + ACE_Str_Buf *cntl, + int *flags) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); + + if (ACE_OS::getpmsg (this->get_handle (), + (strbuf *) cntl, + (strbuf *) data, + band, + flags) == -1) + { + return -1; + } + else + { + return (cntl == 0 ? 0 : cntl->len) + (data == 0 ? 0 : data->len); + } +} +#endif /* ACE_HAS_STREAM_PIPES */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Send.cpp b/dep/ACE_wrappers/ace/FIFO_Send.cpp new file mode 100644 index 000000000..720e63c54 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Send.cpp @@ -0,0 +1,58 @@ +// $Id: FIFO_Send.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FIFO_Send.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FIFO_Send.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FIFO_Send, "$Id: FIFO_Send.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Send) + +void +ACE_FIFO_Send::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FIFO_Send::dump"); + ACE_FIFO::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_FIFO_Send::ACE_FIFO_Send (void) +{ +// ACE_TRACE ("ACE_FIFO_Send::ACE_FIFO_Send"); +} + +int +ACE_FIFO_Send::open (const ACE_TCHAR *rendezvous_name, + int flags, + mode_t perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Send::open"); + return ACE_FIFO::open (rendezvous_name, + flags | O_WRONLY, + perms, + sa); +} + +ACE_FIFO_Send::ACE_FIFO_Send (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Send::ACE_FIFO_Send"); + if (this->ACE_FIFO_Send::open (fifo_name, + flags, + perms, + sa) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_FIFO_Send::ACE_FIFO_Send"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Send.h b/dep/ACE_wrappers/ace/FIFO_Send.h new file mode 100644 index 000000000..cc0fc282f --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Send.h @@ -0,0 +1,75 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file FIFO_Send.h + * + * $Id: FIFO_Send.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//========================================================================== + + +#ifndef ACE_FIFO_SEND_H +#define ACE_FIFO_SEND_H + +#include /**/ "ace/pre.h" + +#include "ace/FIFO.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_fcntl.h" +#include "ace/Default_Constants.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_FIFO_Send + * + * @brief Sender side for the bytestream C++ wrapper for UNIX FIFOs + */ +class ACE_Export ACE_FIFO_Send : public ACE_FIFO +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_FIFO_Send (void); + + /// Open up a bytestream named pipe for writing. + ACE_FIFO_Send (const ACE_TCHAR *rendezvous, + int flags = O_WRONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Open up a bytestream named pipe for writing. + int open (const ACE_TCHAR *rendezvous, + int flags = O_WRONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Send @a buf of up to @a len bytes. + ssize_t send (const void *buf, size_t len); + + /// Send @a buf of exactly @a len bytes (block until done). + ssize_t send_n (const void *buf, size_t len); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FIFO_Send.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_FIFO_SEND_H */ diff --git a/dep/ACE_wrappers/ace/FIFO_Send.inl b/dep/ACE_wrappers/ace/FIFO_Send.inl new file mode 100644 index 000000000..a01facd61 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Send.inl @@ -0,0 +1,24 @@ +// -*- C++ -*- +// +// $Id: FIFO_Send.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" +#include "ace/OS_NS_unistd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ssize_t +ACE_FIFO_Send::send (const void *buf, size_t len) +{ + ACE_TRACE ("ACE_FIFO_Send::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, len); +} + +ACE_INLINE ssize_t +ACE_FIFO_Send::send_n (const void *buf, size_t n) +{ + ACE_TRACE ("ACE_FIFO_Send::send_n"); + return ACE::send_n (this->get_handle (), buf, n); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Send_Msg.cpp b/dep/ACE_wrappers/ace/FIFO_Send_Msg.cpp new file mode 100644 index 000000000..b3bbae00a --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Send_Msg.cpp @@ -0,0 +1,80 @@ +// $Id: FIFO_Send_Msg.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FIFO_Send_Msg.h" + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_sys_uio.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FIFO_Send_Msg.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FIFO_Send_Msg, "$Id: FIFO_Send_Msg.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Send_Msg) + +void +ACE_FIFO_Send_Msg::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FIFO_Send_Msg::dump"); + ACE_FIFO_Send::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ssize_t +ACE_FIFO_Send_Msg::send (const ACE_Str_Buf &send_msg) +{ + // ACE_TRACE ("ACE_FIFO_Send_Msg::send"); +#if defined (ACE_HAS_STREAM_PIPES) + if (ACE_OS::putmsg (this->get_handle (), + (strbuf *) 0, + (strbuf *) &send_msg, + 0) == -1) + return -1; + else + return send_msg.len; +#else + iovec iov[2]; + + iov[0].iov_base = (char *) &send_msg.len; + iov[0].iov_len = sizeof send_msg.len; + + iov[1].iov_base = (char *) send_msg.buf; + iov[1].iov_len = static_cast (send_msg.len); + + ssize_t sent = ACE_OS::writev (this->get_handle (), iov, 2); + if (sent > 0) + sent -= iov[0].iov_len; // Don't count the length we added. + return sent; +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg (void) +{ +// ACE_TRACE ("ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg"); +} + +int +ACE_FIFO_Send_Msg::open (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::open"); + return ACE_FIFO_Send::open (fifo_name, flags | O_WRONLY, perms, sa); +} + +ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg (const ACE_TCHAR *fifo_name, + int flags, + mode_t perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg"); + if (this->ACE_FIFO_Send_Msg::open (fifo_name, flags, perms, sa) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_FIFO_Send_Msg"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FIFO_Send_Msg.h b/dep/ACE_wrappers/ace/FIFO_Send_Msg.h new file mode 100644 index 000000000..504d89721 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Send_Msg.h @@ -0,0 +1,91 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file FIFO_Send_Msg.h + * + * $Id: FIFO_Send_Msg.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_FIFO_SEND_MSG_H +#define ACE_FIFO_SEND_MSG_H +#include /**/ "ace/pre.h" + +#include "ace/FIFO_Send.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_STREAM_PIPES) +# include "ace/OS_NS_stropts.h" +#endif /* ACE_HAS_STREAM_PIPES */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward Decls +class ACE_Str_Buf; + +/** + * @class ACE_FIFO_Send_Msg + * + * @brief Sender side for the Record oriented C++ wrapper for UNIX + * FIFOs. + */ +class ACE_Export ACE_FIFO_Send_Msg : public ACE_FIFO_Send +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_FIFO_Send_Msg (void); + + /// Open up a record-oriented named pipe for writing. + ACE_FIFO_Send_Msg (const ACE_TCHAR *rendezvous, + int flags = O_WRONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Open up a record-oriented named pipe for writing. + int open (const ACE_TCHAR *rendezvous, + int flags = O_WRONLY, + mode_t perms = ACE_DEFAULT_FILE_PERMS, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Send @a buf of up to @a len bytes. + ssize_t send (const ACE_Str_Buf &msg); + + /// Send @a buf of exactly @a len bytes (block until done). + ssize_t send (const void *buf, size_t len); + +#if defined (ACE_HAS_STREAM_PIPES) + /// Send and message via Stream pipes. + ssize_t send (const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl = 0, + int flags = 0); + + /// Send and message via Stream pipes in "band" mode. + ssize_t send (int band, + const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl = 0, + int flags = MSG_BAND); +#endif /* ACE_HAS_STREAM_PIPES */ + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FIFO_Send_Msg.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FIFO_SEND_MSG_H */ diff --git a/dep/ACE_wrappers/ace/FIFO_Send_Msg.inl b/dep/ACE_wrappers/ace/FIFO_Send_Msg.inl new file mode 100644 index 000000000..0a34e64e3 --- /dev/null +++ b/dep/ACE_wrappers/ace/FIFO_Send_Msg.inl @@ -0,0 +1,53 @@ +// -*- C++ -*- +// +// $Id: FIFO_Send_Msg.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_stropts.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ssize_t +ACE_FIFO_Send_Msg::send (const void *buf, size_t len) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); + ACE_Str_Buf send_msg ((char *) buf, static_cast (len)); + + return this->send (send_msg); +} + +#if defined (ACE_HAS_STREAM_PIPES) +ACE_INLINE ssize_t +ACE_FIFO_Send_Msg::send (const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl, + int flags) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); + if (ACE_OS::putmsg (this->get_handle (), + (strbuf *) cntl, + (strbuf *) data, + flags) == -1) + return-1; + else + return (cntl == 0 ? 0 : cntl->len) + (data == 0 ? 0 : data->len); +} + +ACE_INLINE ssize_t +ACE_FIFO_Send_Msg::send (int band, + const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl, + int flags) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); + + if (ACE_OS::putpmsg (this->get_handle (), + (strbuf *) cntl, + (strbuf *) data, + band, + flags) == -1) + return -1; + else + return (cntl == 0 ? 0 : cntl->len) + (data == 0 ? 0 : data->len); +} +#endif /* ACE_HAS_STREAM_PIPES */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE.cpp b/dep/ACE_wrappers/ace/FILE.cpp new file mode 100644 index 000000000..8fe88d1b0 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE.cpp @@ -0,0 +1,147 @@ +// $Id: FILE.cpp 80826 2008-03-04 14:51:23Z wotte $ + +/* Defines the member functions for the base class of the ACE_IO_SAP + ACE_FILE abstraction. */ + +#include "ace/FILE.h" + +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_stat.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FILE.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FILE, "$Id: FILE.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE) + +void +ACE_FILE::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FILE::dump"); + ACE_IO_SAP::dump (); +#endif /* ACE_HAS_DUMP */ +} + +// This is the do-nothing constructor. + +ACE_FILE::ACE_FILE (void) +{ + ACE_TRACE ("ACE_FILE::ACE_FILE"); +} + +// Close the file + +int +ACE_FILE::close (void) +{ + ACE_TRACE ("ACE_FILE::close"); + int result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + return result; +} + +int +ACE_FILE::get_info (ACE_FILE_Info *finfo) +{ + ACE_TRACE ("ACE_FILE::get_info"); + ACE_stat filestatus; + + int const result = ACE_OS::fstat (this->get_handle (), &filestatus); + + if (result == 0) + { + finfo->mode_ = filestatus.st_mode; + finfo->nlink_ = filestatus.st_nlink; + finfo->size_ = filestatus.st_size; + } + + return result; +} + +int +ACE_FILE::get_info (ACE_FILE_Info &finfo) +{ + ACE_TRACE ("ACE_FILE::get_info"); + + return this->get_info (&finfo); +} + +int +ACE_FILE::truncate (ACE_OFF_T length) +{ + ACE_TRACE ("ACE_FILE::truncate"); + return ACE_OS::ftruncate (this->get_handle (), length); +} + +ACE_OFF_T +ACE_FILE::seek (ACE_OFF_T offset, int startpos) +{ + return ACE_OS::lseek (this->get_handle (), offset, startpos); +} + +ACE_OFF_T +ACE_FILE::tell (void) +{ + ACE_TRACE ("ACE_FILE::tell"); + return ACE_OS::lseek (this->get_handle (), 0, SEEK_CUR); +} + +// Return the local endpoint address. + +int +ACE_FILE::get_local_addr (ACE_Addr &addr) const +{ + ACE_TRACE ("ACE_FILE::get_local_addr"); + + // Perform the downcast since had better be an + // . + ACE_FILE_Addr *file_addr = + dynamic_cast (&addr); + + if (file_addr == 0) + return -1; + else + { + *file_addr = this->addr_; + return 0; + } +} + +// Return the same result as . + +int +ACE_FILE::get_remote_addr (ACE_Addr &addr) const +{ + ACE_TRACE ("ACE_FILE::get_remote_addr"); + + return this->get_local_addr (addr); +} + +int +ACE_FILE::remove (void) +{ + ACE_TRACE ("ACE_FILE::remove"); + + this->close (); + return ACE_OS::unlink (this->addr_.get_path_name ()); +} + +int +ACE_FILE::unlink (void) +{ + ACE_TRACE ("ACE_FILE::unlink"); + + return ACE_OS::unlink (this->addr_.get_path_name ()); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE.h b/dep/ACE_wrappers/ace/FILE.h new file mode 100644 index 000000000..407a03379 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE.h @@ -0,0 +1,139 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file FILE.h + * + * $Id: FILE.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer + */ +//============================================================================= + +#ifndef ACE_FILE_H +#define ACE_FILE_H +#include /**/ "ace/pre.h" + +#include "ace/IO_SAP.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/FILE_Addr.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_FILE_CONNECTOR ACE_FILE_Connector +#define ACE_FILE_STREAM ACE_FILE_IO +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_FILE_CONNECTOR ACE_FILE_Connector, ACE_FILE_Addr +#define ACE_FILE_STREAM ACE_FILE_IO, ACE_FILE_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_FILE_Info + * + * @brief Abstracts basic OS FILE information. + */ +class ACE_Export ACE_FILE_Info +{ +public: + /// Mode of file + mode_t mode_; + + /// No of links + nlink_t nlink_; + + /// Size of file + ACE_OFF_T size_; +}; + +/** + * @class ACE_FILE + * + * @brief Defines the core methods of the ACE_FILE abstraction. + */ +class ACE_Export ACE_FILE : public ACE_IO_SAP +{ +public: + /// Close the ACE_FILE handle without removing the ACE_FILE from + /// the file system. + int close (void); + + /// Close and remove the ACE_FILE from the file system. + int remove (void); + + /// Remove the ACE_FILE from the file system without closing the + /// ACE_FILE handle. + int unlink (void); + + /// Get information on this ACE_FILE. + int get_info (ACE_FILE_Info *finfo); + + /// Get information on this ACE_FILE. + int get_info (ACE_FILE_Info &finfo); + + /// Set filesize to length byte. + int truncate (ACE_OFF_T length); + + /** + * Sets the file pointer as follows: + * o If is , the pointer is set to @a offset + * bytes. + * + * o If is , the pointer is set to its + * current location plus @a offset. + * + * o If is , the pointer is set to the size + * of the file plus offset. + */ + ACE_OFF_T seek (ACE_OFF_T offset, + int whence = SEEK_CUR); + + /// Return an offset for the file handle. + ACE_OFF_T tell (void); + + /** + * Disable signal @a signum + * This is here to prevent Win32 from + * disabling SPIPE using socket calls + */ + int disable (int signum) const ; + + /// Return the local endpoint address in the referenced ACE_Addr. + /// Returns 0 if successful, else -1. + int get_local_addr (ACE_Addr &) const; + + /// Return the same thing as get_local_addr(). + int get_remote_addr (ACE_Addr &) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Ensure that this class is only created by the + /// ACE_FILE_Connector. + ACE_FILE (void); + + /// File we are "connected" with... + ACE_FILE_Addr addr_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FILE.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FILE_H */ diff --git a/dep/ACE_wrappers/ace/FILE.inl b/dep/ACE_wrappers/ace/FILE.inl new file mode 100644 index 000000000..288374afc --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE.inl @@ -0,0 +1,18 @@ +// -*- C++ -*- +// +// $Id: FILE.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_FILE::disable (int signum) const +{ +#if defined (ACE_WIN32) + ACE_UNUSED_ARG (signum) ; + return 0 ; +#else /* ACE_WIN32 */ + return ACE_IO_SAP::disable (signum) ; +#endif /* ACE_WIN32 */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE_Addr.cpp b/dep/ACE_wrappers/ace/FILE_Addr.cpp new file mode 100644 index 000000000..6d8fbeb77 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_Addr.cpp @@ -0,0 +1,124 @@ +// $Id: FILE_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FILE_Addr.h" +#include "ace/Lib_Find.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" +#include "ace/os_include/sys/os_socket.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FILE_Addr.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FILE_Addr, "$Id: FILE_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE_Addr) + +ACE_FILE_Addr::ACE_FILE_Addr (void) + : ACE_Addr (AF_FILE, sizeof this->filename_ / sizeof (ACE_TCHAR)) +{ + this->filename_[0] = '\0'; +} + +int +ACE_FILE_Addr::set (const ACE_FILE_Addr &sa) +{ + if (sa.get_type () == AF_ANY) + { +#if defined (ACE_DEFAULT_TEMP_FILE) + // Create a temporary file. + ACE_OS::strcpy (this->filename_, + ACE_DEFAULT_TEMP_FILE); +#else /* ACE_DEFAULT_TEMP_FILE */ + if (ACE::get_temp_dir (this->filename_, MAXPATHLEN - 15) == -1) + // -15 for ace-file-XXXXXX + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Temporary path too long, ") + ACE_TEXT ("defaulting to current directory\n"))); + this->filename_[0] = 0; + } + + // Add the filename to the end + ACE_OS::strcat (this->filename_, ACE_TEXT ("ace-fileXXXXXX")); + +#endif /* ACE_DEFAULT_TEMP_FILE */ + + if (ACE_OS::mktemp (this->filename_) == 0) + return -1; + this->base_set (AF_FILE, + static_cast (ACE_OS::strlen (this->filename_) + 1)); + } + else + { + (void)ACE_OS::strsncpy (this->filename_, sa.filename_, sa.get_size ()); + + this->base_set (sa.get_type (), sa.get_size ()); + } + return 0; +} + +// Copy constructor. + +ACE_FILE_Addr::ACE_FILE_Addr (const ACE_FILE_Addr &sa) + : ACE_Addr (AF_FILE, sizeof this->filename_) +{ + this->set (sa); +} + +int +ACE_FILE_Addr::set (const ACE_TCHAR *filename) +{ + this->ACE_Addr::base_set (AF_FILE, + static_cast (ACE_OS::strlen (filename) + 1)); + (void) ACE_OS::strsncpy (this->filename_, + filename, + sizeof this->filename_ / sizeof (ACE_TCHAR)); + return 0; +} + +ACE_FILE_Addr & +ACE_FILE_Addr::operator= (const ACE_FILE_Addr &sa) +{ + if (this != &sa) + this->set (sa); + return *this; +} + +// Create a ACE_Addr from a ACE_FILE pathname. + +ACE_FILE_Addr::ACE_FILE_Addr (const ACE_TCHAR *filename) +{ + this->set (filename); +} + +int +ACE_FILE_Addr::addr_to_string (ACE_TCHAR *s, size_t len) const +{ + ACE_OS::strsncpy (s, this->filename_, len); + return 0; +} + +// Return the address. + +void * +ACE_FILE_Addr::get_addr (void) const +{ + return (void *)&this->filename_; +} + +void +ACE_FILE_Addr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FILE_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("filename_ = %s"), this->filename_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE_Addr.h b/dep/ACE_wrappers/ace/FILE_Addr.h new file mode 100644 index 000000000..432275b96 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_Addr.h @@ -0,0 +1,89 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file FILE_Addr.h + * + * $Id: FILE_Addr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_FILE_ADDR_H +#define ACE_FILE_ADDR_H +#include /**/ "ace/pre.h" + +#include "ace/Addr.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Flag_Manip.h" +#include "ace/os_include/os_dirent.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_FILE_Addr + * + * @brief Defines the FILE address family address format. + */ +class ACE_Export ACE_FILE_Addr : public ACE_Addr +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_FILE_Addr (void); + + /// Copy constructor. + ACE_FILE_Addr (const ACE_FILE_Addr &sa); + + /// Acts like a copy constructor. If @a sa == ACE_Addr::sap_any then + /// create a temporary filename using ACE_OS::mktemp. + int set (const ACE_FILE_Addr &sa); + + /// Create a ACE_FILE_Addr from a pathname. + explicit ACE_FILE_Addr (const ACE_TCHAR *filename); + + /// Create a ACE_FILE_Addr from a pathname. + int set (const ACE_TCHAR *filename); + + /// Assignment operator. + ACE_FILE_Addr &operator= (const ACE_FILE_Addr &); + + /// Return a pointer to the address. + virtual void *get_addr (void) const; + + /// Transform the current address into string format. + virtual int addr_to_string (ACE_TCHAR *addr, size_t) const; + + /// Compare two addresses for equality. + bool operator == (const ACE_FILE_Addr &SAP) const; + + /// Compare two addresses for inequality. + bool operator != (const ACE_FILE_Addr &SAP) const; + + /// Return the path name used for the rendezvous point. + const ACE_TCHAR *get_path_name (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Name of the file. + ACE_TCHAR filename_[MAXPATHLEN + 1]; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FILE_Addr.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FILE_ADDR_H */ diff --git a/dep/ACE_wrappers/ace/FILE_Addr.inl b/dep/ACE_wrappers/ace/FILE_Addr.inl new file mode 100644 index 000000000..0ae7d31d2 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_Addr.inl @@ -0,0 +1,34 @@ +// -*- C++ -*- +// +// $Id: FILE_Addr.inl 80826 2008-03-04 14:51:23Z wotte $ + + +#include "ace/SString.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Compare two addresses for equality. + +ACE_INLINE bool +ACE_FILE_Addr::operator == (const ACE_FILE_Addr &sap) const +{ + return ACE_OS::strcmp (this->filename_, sap.filename_) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE bool +ACE_FILE_Addr::operator != (const ACE_FILE_Addr &sap) const +{ + return !((*this) == sap); // This is lazy, of course... ;-) +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE const ACE_TCHAR * +ACE_FILE_Addr::get_path_name (void) const +{ + return this->filename_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE_Connector.cpp b/dep/ACE_wrappers/ace/FILE_Connector.cpp new file mode 100644 index 000000000..b59b1e891 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_Connector.cpp @@ -0,0 +1,84 @@ +// $Id: FILE_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/FILE_Connector.h" +#include "ace/Handle_Ops.h" +#include "ace/OS_NS_stdlib.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FILE_Connector.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FILE_Connector, "$Id: FILE_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE_Connector) + +void +ACE_FILE_Connector::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FILE_Connector::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_FILE_Connector::ACE_FILE_Connector (void) +{ + ACE_TRACE ("ACE_FILE_Connector::ACE_FILE_Connector"); +} + +int +ACE_FILE_Connector::connect (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &, + int, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FILE_Connector::connect"); + ACE_ASSERT (new_io.get_handle () == ACE_INVALID_HANDLE); + + ACE_HANDLE handle = ACE_INVALID_HANDLE; + + // Check to see if caller has requested that we create the filename. + if (reinterpret_cast ( + const_cast (remote_sap)) == ACE_Addr::sap_any) + { + // Create a new temporary file. + // Use ACE_OS::mkstemp() if it is available since it avoids a + // race condition, and subsequently a security hole due to that + // race condition (specifically, a denial-of-service attack). + // + // However, using mkstemp() prevents us from doing a timed open + // since it opens the file for us. Better to avoid the race + // condition. + char filename[] = "ace-file-XXXXXX"; + + handle = ACE_OS::mkstemp (filename); // mkstemp() replaces "XXXXXX" + + if (handle == ACE_INVALID_HANDLE + || new_io.addr_.set (ACE_TEXT_CHAR_TO_TCHAR (filename)) != 0) + return -1; + + new_io.set_handle (handle); + + return 0; + } + else + new_io.addr_ = remote_sap; // class copy. + + handle = ACE::handle_timed_open (timeout, + new_io.addr_.get_path_name (), + flags, + perms); + + new_io.set_handle (handle); + return handle == ACE_INVALID_HANDLE ? -1 : 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE_Connector.h b/dep/ACE_wrappers/ace/FILE_Connector.h new file mode 100644 index 000000000..c6d396373 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_Connector.h @@ -0,0 +1,113 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file FILE_Connector.h + * + * $Id: FILE_Connector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + +#ifndef ACE_FILE_CONNECTOR_H +#define ACE_FILE_CONNECTOR_H +#include /**/ "ace/pre.h" + +#include "ace/FILE_IO.h" +#include "ace/Log_Msg.h" +#include "ace/os_include/os_fcntl.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_FILE_Connector + * + * @brief Defines an active connection factory for the ACE_FILE wrappers. + * + * Note that the O_APPEND flag is only partly supported on Win32. If + * you specify O_APPEND, then the file pointer will be positioned at + * the end of the file initially during open, but it is not + * re-positioned at the end prior to each write, as specified by + * POSIX. This is generally good enough for typical situations, but + * it is ``not quite right'' in its semantics. + */ +class ACE_Export ACE_FILE_Connector +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_FILE_Connector (void); + + /** + * Actively ``connect'' and produce a @a new_io ACE_FILE_IO object + * if things go well. The @a remote_sap is the file that we are + * trying to create/open. If it's the default value of + * ACE_Addr::sap_any then the user is letting the OS create the + * filename (via ). The @a timeout is the amount of + * time to wait to create/open the file. If it's 0 then we block + * indefinitely. If *timeout == {0, 0} then the file is created + * using non-blocking mode. If *timeout > {0, 0} then this is the + * maximum amount of time to wait before timing out. The + * @a local_sap and @a reuse_addr parameters are ignored. The @a flags + * and @a perms arguments are passed down to the + * method. + */ + ACE_FILE_Connector (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR | O_CREAT, + int perms = ACE_DEFAULT_FILE_PERMS); + + /** + * Actively ``connect'' and produce a @a new_io object + * if things go well. The @a remote_sap is the file that we are + * trying to create/open. If it's the default value of + * ACE_Addr::sap_any then the user is letting the OS create the + * filename (via ). The @a timeout is the amount of + * time to wait to create/open the file. If it's 0 then we block + * indefinitely. If *timeout == {0, 0} then the file is created + * using non-blocking mode. In this case, if the create/open can't + * be done immediately the value of -1 is returned with . If *timeout > {0, 0} then this is the maximum amount of + * time to wait before timing out. If the time expires before the + * connection is made @c errno == ETIME. The @a local_sap and + * @a reuse_addr parameters are ignored. The @a flags and @a perms + * arguments are passed down to the method. + */ + int connect (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR | O_CREAT, + int perms = ACE_DEFAULT_FILE_PERMS); + + /// Resets any event associations on this handle + int reset_new_handle (ACE_HANDLE handle); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Meta-type "trait" information. + typedef ACE_FILE_Addr PEER_ADDR; + typedef ACE_FILE_IO PEER_STREAM; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FILE_Connector.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FILE_CONNECTOR_H */ diff --git a/dep/ACE_wrappers/ace/FILE_Connector.inl b/dep/ACE_wrappers/ace/FILE_Connector.inl new file mode 100644 index 000000000..deab94e00 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_Connector.inl @@ -0,0 +1,36 @@ +// -*- C++ -*- +// +// $Id: FILE_Connector.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Creates a Local ACE_FILE. + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_FILE_Connector::ACE_FILE_Connector (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FILE_Connector::ACE_FILE_Connector"); + if (this->connect (new_io, remote_sap, timeout, local_sap, + reuse_addr, flags, perms) == ACE_IO_SAP::INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME)) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("address %s, %p\n"), + remote_sap.get_path_name (), + ACE_TEXT ("ACE_FILE_IO"))); +} + +ACE_INLINE int +ACE_FILE_Connector::reset_new_handle (ACE_HANDLE handle) +{ + ACE_UNUSED_ARG (handle); + // Nothing to do here since the handle is not a socket + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE_IO.cpp b/dep/ACE_wrappers/ace/FILE_IO.cpp new file mode 100644 index 000000000..d6bf084df --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_IO.cpp @@ -0,0 +1,145 @@ +// $Id: FILE_IO.cpp 82559 2008-08-07 20:23:07Z parsons $ + +#include "ace/FILE_IO.h" + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_sys_stat.h" +#include "ace/OS_Memory.h" +#include "ace/Truncate.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FILE_IO.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, FILE_IO, "$Id: FILE_IO.cpp 82559 2008-08-07 20:23:07Z parsons $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE_IO) + +void +ACE_FILE_IO::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_FILE_IO::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->addr_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Simple-minded do nothing constructor. + +ACE_FILE_IO::ACE_FILE_IO (void) +{ + ACE_TRACE ("ACE_FILE_IO::ACE_FILE_IO"); +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_FILE_IO::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + va_list argp; + int total_tuples = ACE_Utils::truncate_cast (n / 2); + iovec *iovp = 0; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (int i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + ssize_t result = ACE_OS::writev (this->get_handle (), + iovp, + total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use +// the struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_FILE_IO::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + va_list argp; + int total_tuples = ACE_Utils::truncate_cast (n / 2); + iovec *iovp = 0; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (int i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + ssize_t const result = ACE_OS::readv (this->get_handle (), + iovp, + total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// Allows a client to read from a file without having to provide a +// buffer to read. This method determines how much data is in the +// file, allocates a buffer of this size, reads in the data, and +// returns the number of bytes read. + +ssize_t +ACE_FILE_IO::recvv (iovec *io_vec) +{ + ACE_TRACE ("ACE_FILE_IO::recvv"); + + io_vec->iov_base = 0; + size_t const length = + static_cast (ACE_OS::filesize (this->get_handle ())); + + if (length > 0) + { + ACE_NEW_RETURN (io_vec->iov_base, + char[length], + -1); + io_vec->iov_len = this->recv_n (io_vec->iov_base, + length); + return io_vec->iov_len; + } + else + { + return ACE_Utils::truncate_cast (length); + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/FILE_IO.h b/dep/ACE_wrappers/ace/FILE_IO.h new file mode 100644 index 000000000..951069e36 --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_IO.h @@ -0,0 +1,170 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file FILE_IO.h + * + * $Id: FILE_IO.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_FILE_IO_H +#define ACE_FILE_IO_H +#include /**/ "ace/pre.h" + +#include "ace/FILE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/FILE_Addr.h" + +// Used in the FILE_IO.h file... +#include "ace/os_include/os_stdio.h" +#include "ace/os_include/sys/os_uio.h" + +#if defined (ACE_HAS_STREAM_PIPES) +# include "ace/OS_NS_stropts.h" +#endif /* ACE_HAS_STREAM_PIPES */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl. +class ACE_Message_Block; +class ACE_Time_Value; + +/** + * @class ACE_FILE_IO + * + * @brief Read/Write operations on Files + */ +class ACE_Export ACE_FILE_IO : public ACE_FILE +{ +public: + friend class ACE_FILE_Connector; + + // = Initialization method. + /// Default constructor. + ACE_FILE_IO (void); + + /// send upto @a n bytes in @a buf. + ssize_t send (const void *buf, size_t n) const; + + /// Recv upto @a n bytes in @a buf. + ssize_t recv (void *buf, size_t n) const; + + /// Send n bytes, keep trying until n are sent. + ssize_t send_n (const void *buf, size_t n) const; + + /// Send all the @a message_blocks chained through their and + /// pointers. This call uses the underlying OS gather-write + /// operation to reduce the domain-crossing penalty. + ssize_t send_n (const ACE_Message_Block *message_block, + const ACE_Time_Value *timeout = 0, + size_t *bytes_transferred = 0); + + /// Recv n bytes, keep trying until n are received. + ssize_t recv_n (void *buf, size_t n) const; + +#if defined (ACE_HAS_STREAM_PIPES) + /// Send bytes via STREAM pipes. + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int flags = 0) const; + + /// Recv bytes via STREAM pipes. + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *flags) const; + + /// Send bytes via STREAM pipes using "band" mode. + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int band, + int flags) const; + + /// Recv bytes via STREAM pipes using "band" mode. + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *band, + int *flags) const; + +#endif /* ACE_HAS_STREAM_PIPES */ + + /// Send iovecs via <::writev>. + ssize_t send (const iovec iov[], int n) const; + + /// Recv iovecs via <::readv>. + ssize_t recv (iovec iov[], int n) const; + + /** + * Send N char *ptrs and int lengths. Note that the char *'s + * precede the ints (basically, an varargs version of writev). The + * count N is the *total* number of trailing arguments, *not* a + * couple of the number of tuple pairs! + */ + ssize_t send (size_t n, ...) const; + + /** + * This is an interface to ::readv, that doesn't use the struct + * iovec explicitly. The ... can be passed as an arbitrary number + * of (char *ptr, int len) tuples. However, the count N is the + * *total* number of trailing arguments, *not* a couple of the + * number of tuple pairs! + */ + ssize_t recv (size_t n, ...) const; + + /// Send @a n bytes via Win32 WriteFile using overlapped I/O. + ssize_t send (const void *buf, + size_t n, + ACE_OVERLAPPED *overlapped) const; + + /// Recv @a n bytes via Win32 ReadFile using overlapped I/O. + ssize_t recv (void *buf, + size_t n, + ACE_OVERLAPPED *overlapped) const; + + /// Send an @c iovec of size @a n to the file. + ssize_t sendv (const iovec iov[], + int n) const; + + /** + * Allows a client to read from a file without having to provide a + * buffer to read. This method determines how much data is in the + * file, allocates a buffer of this size, reads in the data, and + * returns the number of bytes read. The caller is responsible for + * deleting the member in the field of using + * delete [] io_vec->iov_base. + */ + ssize_t recvv (iovec *io_vec); + + /// Send an of size @a n to the file. Will block until all + /// bytes are sent or an error occurs. + ssize_t sendv_n (const iovec iov[], + int n) const; + + /// Receive an of size @a n to the file. + ssize_t recvv_n (iovec iov[], + int n) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Meta-type info + typedef ACE_FILE_Addr PEER_ADDR; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/FILE_IO.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FILE_IO_H */ diff --git a/dep/ACE_wrappers/ace/FILE_IO.inl b/dep/ACE_wrappers/ace/FILE_IO.inl new file mode 100644 index 000000000..d2e4f756c --- /dev/null +++ b/dep/ACE_wrappers/ace/FILE_IO.inl @@ -0,0 +1,152 @@ +// -*- C++ -*- +// +// $Id: FILE_IO.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" +#include "ace/OS_NS_sys_uio.h" +#include "ace/OS_NS_unistd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ssize_t +ACE_FILE_IO::sendv_n (const iovec iov[], int n) const +{ + ACE_TRACE ("ACE_FILE_IO::sendv_n"); + return ACE::writev_n (this->get_handle (), + iov, + n); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::send_n (const ACE_Message_Block *message_block, + const ACE_Time_Value *timeout, + size_t *bytes_transferred) +{ + ACE_TRACE ("ACE_FILE_IO::send_n"); + ACE_UNUSED_ARG (timeout); + return ACE::write_n (this->get_handle (), + message_block, + bytes_transferred); +} + +// Recv an n byte message from the file. + +ACE_INLINE ssize_t +ACE_FILE_IO::recvv_n (iovec iov[], int n) const +{ + ACE_TRACE ("ACE_FILE_IO::recvv_n"); + // @@ Carlos, can you please update this to call the + // new ACE::recvv_n() method that you write? + return ACE_OS::readv (this->get_handle (), + iov, + n); +} + +// Send an of size to the file. + +ACE_INLINE ssize_t +ACE_FILE_IO::sendv (const iovec iov[], int n) const +{ + ACE_TRACE ("ACE_FILE_IO::sendv"); + return ACE_OS::writev (this->get_handle (), iov, n); +} + +// Send exactly N bytes from BUF to this file. Keeping trying until +// this many bytes are sent. + +ACE_INLINE ssize_t +ACE_FILE_IO::send_n (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::send_n"); + return ACE::write_n (this->get_handle (), buf, n); +} + +// Receive exactly N bytes from this file into BUF. Keep trying until +// this many bytes are received. + +ACE_INLINE ssize_t +ACE_FILE_IO::recv_n (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::recv_n"); + return ACE::read_n (this->get_handle (), buf, n); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::write (this->get_handle (), buf, n); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::read (this->get_handle (), buf, n); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::send (const iovec iov[], int n) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::writev (this->get_handle (), iov, n); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::recv (iovec iov[], int n) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::readv (this->get_handle (), iov, n); +} + +#if defined (ACE_HAS_STREAM_PIPES) +ACE_INLINE ssize_t +ACE_FILE_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *band, int *flags) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::getpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int band, int flags) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::putpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *flags) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::getmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int flags) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::putmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::send (const void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::write (this->get_handle (), + buf, n, + overlapped); +} + +ACE_INLINE ssize_t +ACE_FILE_IO::recv (void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::read (this->get_handle (), buf, n, + overlapped); +} + +#endif /* ACE_HAS_STREAM_PIPES */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/File_Lock.cpp b/dep/ACE_wrappers/ace/File_Lock.cpp new file mode 100644 index 000000000..eeba6f614 --- /dev/null +++ b/dep/ACE_wrappers/ace/File_Lock.cpp @@ -0,0 +1,72 @@ +// $Id: File_Lock.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/File_Lock.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/File_Lock.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, File_Lock, "$Id: File_Lock.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_File_Lock) + +void +ACE_File_Lock::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_File_Lock::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_File_Lock::ACE_File_Lock (ACE_HANDLE h, + int unlink_in_destructor) + : removed_ (0), + unlink_in_destructor_ (unlink_in_destructor) +{ +// ACE_TRACE ("ACE_File_Lock::ACE_File_Lock"); + if (ACE_OS::flock_init (&this->lock_) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_File_Lock::ACE_File_Lock"))); + this->set_handle (h); +} + +ACE_File_Lock::ACE_File_Lock (const ACE_TCHAR *name, + int flags, + mode_t perms, + int unlink_in_destructor) + : unlink_in_destructor_ (unlink_in_destructor) +{ +// ACE_TRACE ("ACE_File_Lock::ACE_File_Lock"); + + if (this->open (name, flags, perms) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p %s\n"), + ACE_TEXT ("ACE_File_Lock::ACE_File_Lock"), + name)); +} + +int +ACE_File_Lock::open (const ACE_TCHAR *name, + int flags, + mode_t perms) +{ +// ACE_TRACE ("ACE_File_Lock::open"); + this->removed_ = 0; + return ACE_OS::flock_init (&this->lock_, flags, name, perms); +} + +ACE_File_Lock::~ACE_File_Lock (void) +{ +// ACE_TRACE ("ACE_File_Lock::~ACE_File_Lock"); + this->remove (this->unlink_in_destructor_); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/File_Lock.h b/dep/ACE_wrappers/ace/File_Lock.h new file mode 100644 index 000000000..12f8ed64f --- /dev/null +++ b/dep/ACE_wrappers/ace/File_Lock.h @@ -0,0 +1,170 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file File_Lock.h + * + * $Id: File_Lock.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_FILE_LOCK_H +#define ACE_FILE_LOCK_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_stdio.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_File_Lock + * + * @brief A wrapper around the UNIX file locking mechanism. + * + * Allows us to "adapt" the UNIX file locking mechanisms to work + * with all of our Guard stuff... + */ +class ACE_Export ACE_File_Lock +{ +public: + /** + * Set the of the File_Lock to @a handle. Note that this + * constructor assumes ownership of the @a handle and will close it + * down in . If you want the @a handle to stay open when + * is called make sure to call on the @a handle. + * If you don't want the file unlinked in the destructor pass a + * zero value for . + */ + ACE_File_Lock (ACE_HANDLE handle = ACE_INVALID_HANDLE, + int unlink_in_destructor = 1); + + /// Open the @a filename with @a flags and @a mode and set the result + /// to . If you don't want the file unlinked in the + /// destructor pass a zero value for . + ACE_File_Lock (const ACE_TCHAR *filename, + int flags, + mode_t mode = 0, + int unlink_in_destructor = 1); + + /// Open the @a filename with @a flags and @a mode and set the result to + /// . + int open (const ACE_TCHAR *filename, + int flags, + mode_t mode = 0); + + /// Remove a File lock by releasing it and closing down the . + ~ACE_File_Lock (void); + + /// Remove a File lock by releasing it and closing down the + /// . If is non-0 then we unlink the file. + int remove (int unlink_file = 1); + + /** + * Note, for interface uniformity with other synchronization + * wrappers we include the method. This is implemented as + * a write-lock to be on the safe-side... + */ + int acquire (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /** + * Note, for interface uniformity with other synchronization + * wrappers we include the method. This is implemented + * as a write-lock to be on the safe-side... Returns -1 on failure. + * If we "failed" because someone else already had the lock, @c errno + * is set to @c EBUSY. + */ + int tryacquire (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /// Unlock a readers/writer lock. + int release (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /// Acquire a write lock, but block if any readers or a + /// writer hold the lock. + int acquire_write (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /** + * Conditionally acquire a write lock (i.e., won't block). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_write (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /** + * Conditionally upgrade to a write lock (i.e., won't block). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_write_upgrade (short whence = 0, + ACE_OFF_T start = 0, + ACE_OFF_T len = 1); + + /** + * Acquire a read lock, but block if a writer hold the lock. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, @c errno is set to @c EBUSY. + */ + int acquire_read (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /** + * Conditionally acquire a read lock (i.e., won't block). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_read (short whence = 0, ACE_OFF_T start = 0, ACE_OFF_T len = 1); + + /// Get underlying ACE_HANDLE for the file. + ACE_HANDLE get_handle (void) const; + + /** + * Set underlying ACE_HANDLE. Note that this method assumes + * ownership of the and will close it down in . If + * you want the to stay open when is called make + * sure to call on the before closing it. You are + * responsible for the closing the existing before + * overwriting it. + */ + void set_handle (ACE_HANDLE); + + /// Dump state of the object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Locking structure for OS record locks. + ACE_OS::ace_flock_t lock_; + + /// Keeps track of whether has been called yet to avoid + /// multiple calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// on the same object, which is a bad idea anyway... + int removed_; + + /// Keeps track of whether to unlink the underlying file in the + /// destructor. + int unlink_in_destructor_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_File_Lock &); + ACE_File_Lock (const ACE_File_Lock &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/File_Lock.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FILE_LOCK_H */ diff --git a/dep/ACE_wrappers/ace/File_Lock.inl b/dep/ACE_wrappers/ace/File_Lock.inl new file mode 100644 index 000000000..20b000392 --- /dev/null +++ b/dep/ACE_wrappers/ace/File_Lock.inl @@ -0,0 +1,96 @@ +// -*- C++ -*- +// +// $Id: File_Lock.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_File_Lock::acquire_read (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::acquire_read"); + return ACE_OS::flock_rdlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire_read (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire_read"); + return ACE_OS::flock_tryrdlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire_write (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire_write"); + return ACE_OS::flock_trywrlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire_write_upgrade (short whence, + ACE_OFF_T start, + ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire_write_upgrade"); + return ACE_OS::flock_trywrlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire"); + return this->tryacquire_write (whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::acquire_write (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::acquire_write"); + return ACE_OS::flock_wrlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::acquire (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::acquire"); + return this->acquire_write (whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::release (short whence, ACE_OFF_T start, ACE_OFF_T len) +{ +// ACE_TRACE ("ACE_File_Lock::release"); + return ACE_OS::flock_unlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::remove (int unlink_file) +{ +// ACE_TRACE ("ACE_File_Lock::remove"); + + int result = 0; + + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::flock_destroy (&this->lock_, + unlink_file); + } + return result; +} + +ACE_INLINE ACE_HANDLE +ACE_File_Lock::get_handle (void) const +{ +// ACE_TRACE ("ACE_File_Lock::get_handle"); + return this->lock_.handle_; +} + +ACE_INLINE void +ACE_File_Lock::set_handle (ACE_HANDLE h) +{ +// ACE_TRACE ("ACE_File_Lock::set_handle"); + this->lock_.handle_ = h; + this->removed_ = 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Filecache.cpp b/dep/ACE_wrappers/ace/Filecache.cpp new file mode 100644 index 000000000..3a7e3da0a --- /dev/null +++ b/dep/ACE_wrappers/ace/Filecache.cpp @@ -0,0 +1,754 @@ +// $Id: Filecache.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Filecache.h" +#include "ace/Object_Manager.h" +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/Guard_T.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/Truncate.h" + +ACE_RCSID (ace, + Filecache, + "$Id: Filecache.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_WIN32) +// Specifies no sharing flags. +#define R_MASK ACE_DEFAULT_OPEN_PERMS +#define W_MASK 0 +#else +#define R_MASK S_IRUSR|S_IRGRP|S_IROTH +#define W_MASK S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH +#endif /* ACE_WIN32 */ + +#if defined (ACE_WIN32) +// See if you can get rid of some of these. +#define READ_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \ + FILE_FLAG_OVERLAPPED | \ + O_RDONLY) +// static const int RCOPY_FLAGS = (FILE_FLAG_SEQUENTIAL_SCAN | +// O_RDONLY); +#define WRITE_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \ + FILE_FLAG_OVERLAPPED | \ + O_RDWR | O_CREAT | O_TRUNC) +// static const int WCOPY_FLAGS = (FILE_FLAG_SEQUENTIAL_SCAN | +// O_RDWR | O_CREAT | O_TRUNC); +#else +#define READ_FLAGS O_RDONLY +// static const int RCOPY_FLAGS = O_RDONLY; +#define WRITE_FLAGS (O_RDWR | O_CREAT | O_TRUNC) +// static const int WCOPY_FLAGS = O_RDWR | O_CREAT | O_TRUNC; +#endif /* ACE_WIN32 */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// static data members +ACE_Filecache *ACE_Filecache::cvf_ = 0; + +void +ACE_Filecache_Handle::init (void) +{ + this->file_ = 0; + this->handle_ = ACE_INVALID_HANDLE; +} + +ACE_Filecache_Handle::ACE_Filecache_Handle (void) + : file_ (0), handle_ (0), mapit_ (0) +{ + this->init (); +} + +ACE_Filecache_Handle::ACE_Filecache_Handle (const ACE_TCHAR *filename, + ACE_Filecache_Flag mapit) + : file_ (0), handle_ (0), mapit_ (mapit) +{ + this->init (); + // Fetch the file from the Virtual_Filesystem let the + // Virtual_Filesystem do the work of cache coherency. + + // Filecache will also do the acquire, since it holds the lock at + // that time. + this->file_ = ACE_Filecache::instance ()->fetch (filename, mapit); +} + +ACE_Filecache_Handle::ACE_Filecache_Handle (const ACE_TCHAR *filename, + int size, + ACE_Filecache_Flag mapit) + : file_ (0), handle_ (0), mapit_ (mapit) +{ + this->init (); + + if (size == 0) + ACE_Filecache::instance ()->remove (filename); + else + { + // Since this is being opened for a write, simply create a new + // ACE_Filecache_Object now, and let the destructor add it into CVF + // later + + // Filecache will also do the acquire, since it holds the lock at + // that time. + this->file_ = ACE_Filecache::instance ()->create (filename, size); + } +} + +ACE_Filecache_Handle::~ACE_Filecache_Handle (void) +{ + if (this->handle_ != ACE_INVALID_HANDLE) + // this was dup ()'d + ACE_OS::close (this->handle_); + + ACE_Filecache::instance ()->finish (this->file_); +} + +void * +ACE_Filecache_Handle::address (void) const +{ + return this->file_ == 0 ? 0 : this->file_->address (); +} + +ACE_HANDLE +ACE_Filecache_Handle::handle (void) const +{ + if (this->handle_ == ACE_INVALID_HANDLE && this->file_ != 0) + { + ACE_Filecache_Handle *mutable_this = + const_cast (this); + mutable_this->handle_ = ACE_OS::dup (this->file_->handle ()); + } + return this->handle_; +} + +int +ACE_Filecache_Handle::error (void) const +{ + if (this->file_ == 0) + return -1; + else + return this->file_->error (); +} + +ACE_OFF_T +ACE_Filecache_Handle::size (void) const +{ + if (this->file_ == 0) + return -1; + else + return this->file_->size (); +} + +// ------------------ +// ACE_Filecache_Hash +// ------------------ + +#define ACE_Filecache_Hash \ + ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> +#define ACE_Filecache_Hash_Entry \ + ACE_Hash_Map_Entry + +template <> +ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry ( + const ACE_TCHAR *const &ext_id, + ACE_Filecache_Object *const &int_id, + ACE_Filecache_Hash_Entry *next, + ACE_Filecache_Hash_Entry *prev) + : ext_id_ (ext_id + ? ACE_OS::strdup (ext_id) + : ACE_OS::strdup (ACE_TEXT (""))), + int_id_ (int_id), + next_ (next), + prev_ (prev) +{ +} + +template <> +ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (ACE_Filecache_Hash_Entry *next, + ACE_Filecache_Hash_Entry *prev) + : ext_id_ (0), + next_ (next), + prev_ (prev) +{ +} + +template <> +ACE_Filecache_Hash_Entry::~ACE_Hash_Map_Entry (void) +{ + ACE_OS::free ((void *) ext_id_); +} + +// We need these template specializations since KEY is defined as a +// ACE_TCHAR*, which doesn't have a hash() or equal() method defined on it. + +template <> +unsigned long +ACE_Filecache_Hash::hash (const ACE_TCHAR *const &ext_id) +{ + return ACE::hash_pjw (ext_id); +} + +template <> +int +ACE_Filecache_Hash::equal (const ACE_TCHAR *const &id1, + const ACE_TCHAR *const &id2) +{ + return ACE_OS::strcmp (id1, id2) == 0; +} + +#undef ACE_Filecache_Hash +#undef ACE_Filecache_Hash_Entry + + +// ------------- +// ACE_Filecache +// ------------- + +ACE_Filecache * +ACE_Filecache::instance (void) +{ + // Double check locking pattern. + if (ACE_Filecache::cvf_ == 0) + { + ACE_SYNCH_RW_MUTEX &lock = + *ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_FILECACHE_LOCK); + ACE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, ace_mon, lock, 0); + + // @@ James, please check each of the ACE_NEW_RETURN calls to + // make sure that it is safe to return if allocation fails. + if (ACE_Filecache::cvf_ == 0) + ACE_NEW_RETURN (ACE_Filecache::cvf_, + ACE_Filecache, + 0); + } + + return ACE_Filecache::cvf_; +} + +ACE_Filecache::ACE_Filecache (void) + : size_ (ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE), + hash_ (size_) +{ +} + +ACE_Filecache::~ACE_Filecache (void) +{ +} + +ACE_Filecache_Object * +ACE_Filecache::insert_i (const ACE_TCHAR *filename, + ACE_SYNCH_RW_MUTEX &filelock, + int mapit) +{ + ACE_Filecache_Object *handle = 0; + + if (this->hash_.find (filename, handle) == -1) + { + ACE_NEW_RETURN (handle, + ACE_Filecache_Object (filename, filelock, 0, mapit), + 0); + + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%t) CVF: creating %s\n"), filename)); + + if (this->hash_.bind (filename, handle) == -1) + { + delete handle; + handle = 0; + } + } + else + handle = 0; + + return handle; +} + +ACE_Filecache_Object * +ACE_Filecache::remove_i (const ACE_TCHAR *filename) +{ + ACE_Filecache_Object *handle = 0; + + // Disassociate file from the cache. + if (this->hash_.unbind (filename, handle) == 0) + { + handle->stale_ = 1; + + // Try a lock. If it succeeds, we can delete it now. + // Otherwise, it will clean itself up later. + if (handle->lock_.tryacquire_write () == 0) + { + delete handle; + handle = 0; + } + } + else + handle = 0; + + return handle; +} + +ACE_Filecache_Object * +ACE_Filecache::update_i (const ACE_TCHAR *filename, + ACE_SYNCH_RW_MUTEX &filelock, + int mapit) +{ + ACE_Filecache_Object *handle = 0; + + handle = this->remove_i (filename); + handle = this->insert_i (filename, filelock, mapit); + + return handle; +} + +int +ACE_Filecache::find (const ACE_TCHAR *filename) +{ + return this->hash_.find (filename); +} + + +ACE_Filecache_Object * +ACE_Filecache::remove (const ACE_TCHAR *filename) +{ + ACE_Filecache_Object *handle = 0; + + ACE_OFF_T loc = ACE::hash_pjw (filename) % this->size_; + ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc]; + // ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc]; + + if (this->hash_.find (filename, handle) != -1) + { + ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, + ace_mon, + hashlock, + 0); + + return this->remove_i (filename); + } + + return 0; +} + + +ACE_Filecache_Object * +ACE_Filecache::fetch (const ACE_TCHAR *filename, int mapit) +{ + ACE_Filecache_Object *handle = 0; + + ACE_OFF_T loc = ACE::hash_pjw (filename) % this->size_; + ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc]; + ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc]; + + filelock.acquire_read (); + + if (this->hash_.find (filename, handle) == -1) + { + ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, + ace_mon, + hashlock, + 0); + + // Second check in the method call + handle = this->insert_i (filename, filelock, mapit); + + if (handle == 0) + filelock.release (); + } + else + { + if (handle->update ()) + { + { + // Double check locking pattern + ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, + ace_mon, + hashlock, + 0); + + // Second check in the method call + handle = this->update_i (filename, filelock, mapit); + + if (handle == 0) + filelock.release (); + } + } + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%t) CVF: found %s\n"), filename)); + } + + return handle; +} + +ACE_Filecache_Object * +ACE_Filecache::create (const ACE_TCHAR *filename, int size) +{ + ACE_Filecache_Object *handle = 0; + + ACE_OFF_T loc = ACE::hash_pjw (filename) % this->size_; + ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc]; + + ACE_NEW_RETURN (handle, + ACE_Filecache_Object (filename, size, filelock), + 0); + handle->acquire (); + + return handle; +} + +ACE_Filecache_Object * +ACE_Filecache::finish (ACE_Filecache_Object *&file) +{ + if (file == 0) + return file; + + ACE_OFF_T loc = ACE::hash_pjw (file->filename_) % this->size_; + ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc]; + + if (file != 0) + switch (file->action_) + { + case ACE_Filecache_Object::ACE_WRITING: + { + ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, + ace_mon, + hashlock, + 0); + + file->release (); + + this->remove_i (file->filename_); +#if 0 + int result = this->hash_.bind (file->filename (), file); + + if (result == 0) + file->acquire (); +#else + // Last one using a stale file is resposible for deleting it. + if (file->stale_) + { + // Try a lock. If it succeds, we can delete it now. + // Otherwise, it will clean itself up later. + if (file->lock_.tryacquire_write () == 0) + { + delete file; + file = 0; + } + } +#endif + } + + break; + default: + file->release (); + + // Last one using a stale file is resposible for deleting it. + if (file->stale_) + { + // Try a lock. If it succeds, we can delete it now. + // Otherwise, it will clean itself up later. + if (file->lock_.tryacquire_write () == 0) + { + delete file; + file = 0; + } + } + + break; + } + + return file; +} + +void +ACE_Filecache_Object::init (void) +{ + this->filename_[0] = '\0'; + this->handle_ = ACE_INVALID_HANDLE; + this->error_ = ACE_SUCCESS; + this->tempname_ = 0; + this->size_ = 0; + + ACE_OS::memset (&(this->stat_), 0, sizeof (this->stat_)); +} + +ACE_Filecache_Object::ACE_Filecache_Object (void) + : tempname_ (0), + mmap_ (), + handle_ (0), + // stat_ (), + size_ (0), + action_ (0), + error_ (0), + stale_ (0), + // sa_ (), + junklock_ (), + lock_ (junklock_) +{ + this->init (); +} + +ACE_Filecache_Object::ACE_Filecache_Object (const ACE_TCHAR *filename, + ACE_SYNCH_RW_MUTEX &lock, + LPSECURITY_ATTRIBUTES sa, + int mapit) + : tempname_ (0), + mmap_ (), + handle_ (0), + // stat_ (), + size_ (0), + action_ (0), + error_ (0), + stale_ (0), + sa_ (sa), + junklock_ (), + lock_ (lock) +{ + this->init (); + + // ASSERT strlen(filename) < sizeof (this->filename_) + ACE_OS::strcpy (this->filename_, filename); + this->action_ = ACE_Filecache_Object::ACE_READING; + // place ourselves into the READING state + + // Can we access the file? + if (ACE_OS::access (this->filename_, R_OK) == -1) + { + this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED); + return; + } + + // Can we stat the file? + if (ACE_OS::stat (this->filename_, &this->stat_) == -1) + { + this->error_i (ACE_Filecache_Object::ACE_STAT_FAILED); + return; + } + + this->size_ = ACE_Utils::truncate_cast (this->stat_.st_size); + this->tempname_ = this->filename_; + + // Can we open the file? + this->handle_ = ACE_OS::open (this->tempname_, + READ_FLAGS, R_MASK, this->sa_); + if (this->handle_ == ACE_INVALID_HANDLE) + { + this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED, + ACE_TEXT ("ACE_Filecache_Object::ctor: open")); + return; + } + + if (mapit) + { + // Can we map the file? + if (this->mmap_.map (this->handle_, static_cast (-1), + PROT_READ, ACE_MAP_PRIVATE, 0, 0, this->sa_) != 0) + { + this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED, + ACE_TEXT ("ACE_Filecache_Object::ctor: map")); + ACE_OS::close (this->handle_); + this->handle_ = ACE_INVALID_HANDLE; + return; + } + } + + // Ok, finished! + this->action_ = ACE_Filecache_Object::ACE_READING; +} + +ACE_Filecache_Object::ACE_Filecache_Object (const ACE_TCHAR *filename, + ACE_OFF_T size, + ACE_SYNCH_RW_MUTEX &lock, + LPSECURITY_ATTRIBUTES sa) + : stale_ (0), + sa_ (sa), + lock_ (lock) +{ + this->init (); + + this->size_ = size; + ACE_OS::strcpy (this->filename_, filename); + this->action_ = ACE_Filecache_Object::ACE_WRITING; + + // Can we access the file? + if (ACE_OS::access (this->filename_, R_OK|W_OK) == -1 + // Does it exist? + && ACE_OS::access (this->filename_, F_OK) != -1) + { + // File exists, but we cannot access it. + this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED); + return; + } + + this->tempname_ = this->filename_; + + // Can we open the file? + this->handle_ = ACE_OS::open (this->tempname_, WRITE_FLAGS, W_MASK, this->sa_); + if (this->handle_ == ACE_INVALID_HANDLE) + { + this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED, + ACE_TEXT ("ACE_Filecache_Object::acquire: open")); + return; + } + + // Can we write? + if (ACE_OS::pwrite (this->handle_, "", 1, this->size_ - 1) != 1) + { + this->error_i (ACE_Filecache_Object::ACE_WRITE_FAILED, + ACE_TEXT ("ACE_Filecache_Object::acquire: write")); + ACE_OS::close (this->handle_); + return; + } + + // Can we map? + if (this->mmap_.map (this->handle_, this->size_, PROT_RDWR, MAP_SHARED, + 0, 0, this->sa_) != 0) + { + this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED, + ACE_TEXT ("ACE_Filecache_Object::acquire: map")); + ACE_OS::close (this->handle_); + } + + // Ok, done! +} + +ACE_Filecache_Object::~ACE_Filecache_Object (void) +{ + if (this->error_ == ACE_SUCCESS) + { + this->mmap_.unmap (); + ACE_OS::close (this->handle_); + this->handle_ = ACE_INVALID_HANDLE; + } + + this->lock_.release (); +} + +int +ACE_Filecache_Object::acquire (void) +{ + return this->lock_.tryacquire_read (); +} + +int +ACE_Filecache_Object::release (void) +{ + if (this->action_ == ACE_WRITING) + { + // We are safe since only one thread has a writable Filecache_Object + +#if 0 + ACE_HANDLE original = ACE_OS::open (this->filename_, WRITE_FLAGS, W_MASK, + this->sa_); + if (original == ACE_INVALID_HANDLE) + this->error_ = ACE_Filecache_Object::ACE_OPEN_FAILED; + else if (ACE_OS::write (original, this->mmap_.addr (), + this->size_) == -1) + { + this->error_ = ACE_Filecache_Object::ACE_WRITE_FAILED; + ACE_OS::close (original); + ACE_OS::unlink (this->filename_); + } + else if (ACE_OS::stat (this->filename_, &this->stat_) == -1) + this->error_ = ACE_Filecache_Object::ACE_STAT_FAILED; +#endif + + this->mmap_.unmap (); + ACE_OS::close (this->handle_); + this->handle_ = ACE_INVALID_HANDLE; + +#if 0 + // Leave the file in an acquirable state. + this->handle_ = ACE_OS::open (this->tempname_, READ_FLAGS, R_MASK); + if (this->handle_ == ACE_INVALID_HANDLE) + { + this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED, + "ACE_Filecache_Object::acquire: open"); + } + else if (this->mmap_.map (this->handle_, -1, + PROT_READ, + ACE_MAP_PRIVATE, + 0, + 0, + this->sa_) != 0) + { + this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED, + "ACE_Filecache_Object::acquire: map"); + ACE_OS::close (this->handle_); + this->handle_ = ACE_INVALID_HANDLE; + } + + this->action_ = ACE_Filecache_Object::ACE_READING; +#endif + } + + return this->lock_.release (); +} + +int +ACE_Filecache_Object::error (void) const +{ + // The existence of the object means a read lock is being held. + return this->error_; +} + +int +ACE_Filecache_Object::error_i (int error_value, const ACE_TCHAR *s) +{ + s = s; + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p.\n"), s)); + this->error_ = error_value; + return error_value; +} + +const ACE_TCHAR * +ACE_Filecache_Object::filename (void) const +{ + // The existence of the object means a read lock is being held. + return this->filename_; +} + +ACE_OFF_T +ACE_Filecache_Object::size (void) const +{ + // The existence of the object means a read lock is being held. + return this->size_; +} + +ACE_HANDLE +ACE_Filecache_Object::handle (void) const +{ + // The existence of the object means a read lock is being held. + return this->handle_; +} + +void * +ACE_Filecache_Object::address (void) const +{ + // The existence of the object means a read lock is being held. + return this->mmap_.addr (); +} + +int +ACE_Filecache_Object::update (void) const +{ + // The existence of the object means a read lock is being held. + int result; + ACE_stat statbuf; + + if (ACE_OS::stat (this->filename_, &statbuf) == -1) + result = 1; + else + // non-portable code may follow +#if defined (ACE_HAS_WINCE) + // Yup, non-portable... there's probably a way to safely implement + // difftime() on WinCE, but for now, this will have to do. It flags + // every file as having changed since cached. + result = 1; +#else + result = ACE_OS::difftime (this->stat_.st_mtime, statbuf.st_mtime) < 0; +#endif /* ACE_HAS_WINCE */ + + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Filecache.h b/dep/ACE_wrappers/ace/Filecache.h new file mode 100644 index 000000000..60b8a90f6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Filecache.h @@ -0,0 +1,353 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Filecache.h + * + * $Id: Filecache.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef ACE_FILECACHE_H +#define ACE_FILECACHE_H + +#include /**/ "ace/pre.h" + +#include "ace/Mem_Map.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Null_Mutex.h" +#include "ace/Synch_Traits.h" +#include "ace/RW_Thread_Mutex.h" +#include "ace/OS_NS_sys_stat.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +enum ACE_Filecache_Flag +{ + ACE_NOMAP = 0, + ACE_MAPIT = 1 +}; + +class ACE_Filecache_Object; + +/** + * @class ACE_Filecache_Handle + * + * @brief Abstraction over a real file. This is meant to be the entry + * point into the Cached Virtual Filesystem. + * + * This is a cached filesystem implementation based loosely on the + * implementation of JAWS_File. The interfaces will be nearly the + * same. The under-the-hood implementation should hopefully be a + * much faster thing. + * These will be given their own implementations later. For now, we + * borrow the implementation provided by JAWS. + * On creation, the cache is checked, and reference count is + * incremented. On destruction, reference count is decremented. If + * the reference count is 0, the file is removed from the cache. + * E.g. 1, + * { + * ACE_Filecache_Handle foo("foo.html"); + * this->peer ().send (foo.address (), foo.size ()); + * } + * E.g. 2, + * { + * ACE_Filecache_Handle foo("foo.html"); + * io->transmitfile (foo.handle (), this->peer ().handle ()); + * } + * E.g. 3, + * { + * ACE_Filecache_Handle foo("foo.html", content_length); + * this->peer ().recv (foo.address (), content_length); + * } + * TODO: + */ +class ACE_Export ACE_Filecache_Handle +{ + // (1) Get rid of the useless copying of files when reading. + // Although it does make sure the file you send isn't being changed, + // it doesn't make sure the file is in a sensible state before + // sending it. + // + // Alternative: if the file get's trashed while it is being shipped, + // let the client request the file again. The cache should have an + // updated copy by that point. + // + // (2) Use hashing for locating files. This means I need a hastable + // implementation with buckets. + // + // (3) Only lock when absolutely necessary. JAWS_Virtual_Filesystem was + // rather conservative, but for some reason it still ran into problems. + // Since this design should be simpler, problems should be easier to spot. + // +public: + + /// Query cache for file, and acquire it. Assumes the file is being + /// opened for reading. + ACE_Filecache_Handle (const ACE_TCHAR *filename, + ACE_Filecache_Flag mapit = ACE_MAPIT); + + /** + * Create new entry, and acquire it. Presence of SIZE assumes the + * file is being opened for writing. If SIZE is zero, assumes the + * file is to be removed from the cache. + */ + ACE_Filecache_Handle (const ACE_TCHAR *filename, + int size, + ACE_Filecache_Flag mapit = ACE_MAPIT); + + /// Closes any open handles, release acquired file. + ~ACE_Filecache_Handle (void); + + /// Base address of memory mapped file. + void *address (void) const; + + /// A handle (e.g., UNIX file descriptor, or NT file handle). + ACE_HANDLE handle (void) const; + + /// Any associated error in handle creation and acquisition. + int error (void) const; + + /// The size of the file. + ACE_OFF_T size (void) const; + +protected: + /// Default do nothing constructor. Prevent it from being called. + ACE_Filecache_Handle (void); + + /// Common initializations for constructors. + void init (void); + +public: + /// These come from ACE_Filecache_Object, which is an internal class. + enum + { + ACE_SUCCESS = 0, + ACE_ACCESS_FAILED, + ACE_OPEN_FAILED, + ACE_COPY_FAILED, + ACE_STAT_FAILED, + ACE_MEMMAP_FAILED, + ACE_WRITE_FAILED + }; + +private: + /// A reference to the low level instance. + ACE_Filecache_Object *file_; + + /// A 'd version of the one from . + ACE_HANDLE handle_; + + int mapit_; +}; + +typedef ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> + ACE_Filecache_Hash; + +typedef ACE_Hash_Map_Entry ACE_Filecache_Hash_Entry; + +/** + * @class ACE_Filecache + * + * @brief A hash table holding the information about entry point into + * the Cached Virtual Filesystem. On insertion, the reference + * count is incremented. On destruction, reference count is + * decremented. + */ +class ACE_Export ACE_Filecache +{ +public: + /// Singleton pattern. + static ACE_Filecache *instance (void); + + ~ACE_Filecache (void); + + /// Returns 0 if the file associated with ``filename'' is in the cache, + /// or -1 if not. + int find (const ACE_TCHAR *filename); + + /// Return the file associated with ``filename'' if it is in the cache, + /// or create if not. + ACE_Filecache_Object *fetch (const ACE_TCHAR *filename, int mapit = 1); + + /// Remove the file associated with ``filename'' from the cache. + ACE_Filecache_Object *remove (const ACE_TCHAR *filename); + + /// Create a new Filecache_Object, returns it. + ACE_Filecache_Object *create (const ACE_TCHAR *filename, int size); + + /// Release an acquired Filecache_Object, returns it again or NULL if it + /// was deleted. + ACE_Filecache_Object *finish (ACE_Filecache_Object *&new_file); + +protected: + ACE_Filecache_Object *insert_i (const ACE_TCHAR *filename, + ACE_SYNCH_RW_MUTEX &filelock, + int mapit); + ACE_Filecache_Object *remove_i (const ACE_TCHAR *filename); + ACE_Filecache_Object *update_i (const ACE_TCHAR *filename, + ACE_SYNCH_RW_MUTEX &filelock, + int mapit); + +public: + + enum + { + /// For this stupid implementation, use an array. Someday, use a + /// balanced search tree, or real hash table. + ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE = 512, + + /// This determines the highwater mark in megabytes for the cache. + /// This will be ignored for now. + ACE_DEFAULT_VIRTUAL_FILESYSTEM_CACHE_SIZE = 20 + }; + +protected: + /// Prevent it from being called. + ACE_Filecache (void); + +private: + ACE_OFF_T size_; + + /// The hash table + ACE_Filecache_Hash hash_; + + /// The reference to the instance + static ACE_Filecache *cvf_; + + // = Synchronization variables. + ACE_SYNCH_RW_MUTEX hash_lock_[ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE]; + ACE_SYNCH_RW_MUTEX file_lock_[ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE]; +}; + +/** + * @class ACE_Filecache_Object + * + * @brief Abstraction over a real file. This is what the Virtual + * Filesystem contains. This class is not intended for general + * consumption. Please consult a physician before attempting to + * use this class. + */ +class ACE_Export ACE_Filecache_Object +{ +public: + friend class ACE_Filecache; + + /// Creates a file for reading. + ACE_Filecache_Object (const ACE_TCHAR *filename, + ACE_SYNCH_RW_MUTEX &lock, + LPSECURITY_ATTRIBUTES sa = 0, + int mapit = 1); + + /// Creates a file for writing. + ACE_Filecache_Object (const ACE_TCHAR *filename, + ACE_OFF_T size, + ACE_SYNCH_RW_MUTEX &lock, + LPSECURITY_ATTRIBUTES sa = 0); + + /// Only if reference count is zero should this be called. + ~ACE_Filecache_Object (void); + + /// Increment the reference_count_. + int acquire (void); + + /// Decrement the reference_count_. + int release (void); + + // = error_ accessors + int error (void) const; + int error (int error_value, + const ACE_TCHAR *s = ACE_TEXT ("ACE_Filecache_Object")); + + /// filename_ accessor + const ACE_TCHAR *filename (void) const; + + /// handle_ accessor. + ACE_HANDLE handle (void) const; + + /// Base memory address for memory mapped file. + void *address (void) const; + + /// size_ accessor. + ACE_OFF_T size (void) const; + + /// True if file on disk is newer than cached file. + int update (void) const; + +protected: + /// Prevent from being called. + ACE_Filecache_Object (void); + + /// Common initialization code, + void init (void); + +private: + /// Internal error logging method, no locking. + int error_i (int error_value, + const ACE_TCHAR *s = ACE_TEXT ("ACE_Filecache_Object")); + +public: + + enum Creation_States + { + ACE_READING = 1, + ACE_WRITING = 2 + }; + + enum Error_Conditions + { + ACE_SUCCESS = 0, + ACE_ACCESS_FAILED, + ACE_OPEN_FAILED, + ACE_COPY_FAILED, + ACE_STAT_FAILED, + ACE_MEMMAP_FAILED, + ACE_WRITE_FAILED + }; + +private: + /// The temporary file name and the real file name. The real file is + /// copied into the temporary file for safety reasons. + ACE_TCHAR *tempname_; + ACE_TCHAR filename_[MAXPATHLEN + 1]; + + /// Holds the memory mapped version of the temporary file. + ACE_Mem_Map mmap_; + + /// The descriptor to the temporary file. + ACE_HANDLE handle_; + + /// Used to compare against the real file to test if an update is needed. + ACE_stat stat_; + ACE_OFF_T size_; + + /// Status indicators. + int action_; + int error_; + + /// If set to 1, means the object is flagged for removal. + int stale_; + + /// Security attribute object. + LPSECURITY_ATTRIBUTES sa_; + + /// The default initializer + ACE_SYNCH_RW_MUTEX junklock_; + + /// Provides a bookkeeping mechanism for users of this object. + ACE_SYNCH_RW_MUTEX &lock_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_FILECACHE_H */ diff --git a/dep/ACE_wrappers/ace/Flag_Manip.cpp b/dep/ACE_wrappers/ace/Flag_Manip.cpp new file mode 100644 index 000000000..f9ac4083f --- /dev/null +++ b/dep/ACE_wrappers/ace/Flag_Manip.cpp @@ -0,0 +1,95 @@ +// $Id: Flag_Manip.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Flag_Manip.h" + +#if defined (ACE_LACKS_FCNTL) +# include "ace/OS_NS_stropts.h" +# include "ace/OS_NS_errno.h" +#endif /* ACE_LACKS_FCNTL */ + +#if !defined (__ACE_INLINE__) +#include "ace/Flag_Manip.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (CYGWIN32) +# include "ace/os_include/os_termios.h" +#endif /* CYGWIN32 */ + +ACE_RCSID (ace, + Flag_Manip, + "$Id: Flag_Manip.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Flags are file status flags to turn on. + +int +ACE::set_flags (ACE_HANDLE handle, int flags) +{ + ACE_TRACE ("ACE::set_flags"); +#if defined (ACE_LACKS_FCNTL) + switch (flags) + { + case ACE_NONBLOCK: + // nonblocking argument (1) + // blocking: (0) + { + int nonblock = 1; + return ACE_OS::ioctl (handle, FIONBIO, &nonblock); + } + default: + ACE_NOTSUP_RETURN (-1); + } +#else + int val = ACE_OS::fcntl (handle, F_GETFL, 0); + + if (val == -1) + return -1; + + // Turn on flags. + ACE_SET_BITS (val, flags); + + if (ACE_OS::fcntl (handle, F_SETFL, val) == -1) + return -1; + else + return 0; +#endif /* ACE_LACKS_FCNTL */ +} + +// Flags are the file status flags to turn off. + +int +ACE::clr_flags (ACE_HANDLE handle, int flags) +{ + ACE_TRACE ("ACE::clr_flags"); + +#if defined (ACE_LACKS_FCNTL) + switch (flags) + { + case ACE_NONBLOCK: + // nonblocking argument (1) + // blocking: (0) + { + int nonblock = 0; + return ACE_OS::ioctl (handle, FIONBIO, &nonblock); + } + default: + ACE_NOTSUP_RETURN (-1); + } +#else + int val = ACE_OS::fcntl (handle, F_GETFL, 0); + + if (val == -1) + return -1; + + // Turn flags off. + ACE_CLR_BITS (val, flags); + + if (ACE_OS::fcntl (handle, F_SETFL, val) == -1) + return -1; + else + return 0; +#endif /* ACE_LACKS_FCNTL */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Flag_Manip.h b/dep/ACE_wrappers/ace/Flag_Manip.h new file mode 100644 index 000000000..0457dcb4d --- /dev/null +++ b/dep/ACE_wrappers/ace/Flag_Manip.h @@ -0,0 +1,58 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Flag_Manip.h + * + * $Id: Flag_Manip.h 80826 2008-03-04 14:51:23Z wotte $ + * + * This class includes the functions used for the Flag Manipulation. + * + * @author Priyanka Gontla + */ +//============================================================================= + +#ifndef ACE_FLAG_MANIP_H +#define ACE_FLAG_MANIP_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/os_include/os_fcntl.h" /* For values passed to these methods */ + +#if defined (ACE_EXPORT_MACRO) +# undef ACE_EXPORT_MACRO +#endif +#define ACE_EXPORT_MACRO ACE_Export + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE +{ + // = Set/get/clear various flags related to I/O HANDLE. + /// Set flags associated with @a handle. + extern ACE_Export int set_flags (ACE_HANDLE handle, + int flags); + + /// Clear flags associated with @a handle. + extern ACE_Export int clr_flags (ACE_HANDLE handle, + int flags); + + /// Return the current setting of flags associated with @a handle. + ACE_NAMESPACE_INLINE_FUNCTION int get_flags (ACE_HANDLE handle); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Flag_Manip.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FLAG_MANIP_H */ diff --git a/dep/ACE_wrappers/ace/Flag_Manip.inl b/dep/ACE_wrappers/ace/Flag_Manip.inl new file mode 100644 index 000000000..229a4ee59 --- /dev/null +++ b/dep/ACE_wrappers/ace/Flag_Manip.inl @@ -0,0 +1,26 @@ +// -*- C++ -*- +// +// $Id: Flag_Manip.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_fcntl.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Return flags currently associated with handle. +ACE_INLINE int +ACE::get_flags (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE::get_flags"); + +#if defined (ACE_LACKS_FCNTL) + // ACE_OS::fcntl is not supported. It + // would be better to store ACE's notion of the flags + // associated with the handle, but this works for now. + ACE_UNUSED_ARG (handle); + return 0; +#else + return ACE_OS::fcntl (handle, F_GETFL, 0); +#endif /* ACE_LACKS_FCNTL */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Framework_Component.cpp b/dep/ACE_wrappers/ace/Framework_Component.cpp new file mode 100644 index 000000000..48d304359 --- /dev/null +++ b/dep/ACE_wrappers/ace/Framework_Component.cpp @@ -0,0 +1,279 @@ +// Framework_Component.cpp +// $Id: Framework_Component.cpp 82238 2008-07-02 12:05:46Z sma $ + +#include "ace/Framework_Component.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Framework_Component.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Object_Manager.h" +#include "ace/Log_Msg.h" +#include "ace/DLL_Manager.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(ace, Framework_Component, "$Id: Framework_Component.cpp 82238 2008-07-02 12:05:46Z sma $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Framework_Component::~ACE_Framework_Component (void) +{ + ACE_TRACE ("ACE_Framework_Component::~ACE_Framework_Component"); + + ACE::strdelete (const_cast (this->dll_name_)); + ACE::strdelete (const_cast (this->name_)); +} + +/***************************************************************/ + +ACE_ALLOC_HOOK_DEFINE(ACE_Framework_Repository) + +sig_atomic_t ACE_Framework_Repository::shutting_down_ = 0; + +// Pointer to the Singleton instance. +ACE_Framework_Repository *ACE_Framework_Repository::repository_ = 0; + +ACE_Framework_Repository::~ACE_Framework_Repository (void) +{ + ACE_TRACE ("ACE_Framework_Repository::~ACE_Framework_Repository"); + this->close (); +} + +int +ACE_Framework_Repository::open (int size) +{ + ACE_TRACE ("ACE_Framework_Repository::open"); + + ACE_Framework_Component **temp = 0; + + ACE_NEW_RETURN (temp, + ACE_Framework_Component *[size], + -1); + + this->component_vector_ = temp; + this->total_size_ = size; + return 0; +} + +int +ACE_Framework_Repository::close (void) +{ + ACE_TRACE ("ACE_Framework_Repository::close"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + this->shutting_down_ = 1; + + if (this->component_vector_ != 0) + { + // Delete components in reverse order. + for (int i = this->current_size_ - 1; i >= 0; i--) + if (this->component_vector_[i]) + { + ACE_Framework_Component *s = + const_cast ( + this->component_vector_[i]); + + this->component_vector_[i] = 0; + delete s; + } + + delete [] this->component_vector_; + this->component_vector_ = 0; + this->current_size_ = 0; + } + + ACE_DLL_Manager::close_singleton (); + return 0; +} + +ACE_Framework_Repository * +ACE_Framework_Repository::instance (int size) +{ + ACE_TRACE ("ACE_Framework_Repository::instance"); + + if (ACE_Framework_Repository::repository_ == 0) + { + // Perform Double-Checked Locking Optimization. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + if (ACE_Framework_Repository::repository_ == 0) + { + if (ACE_Object_Manager::starting_up () || + !ACE_Object_Manager::shutting_down ()) + { + ACE_NEW_RETURN (ACE_Framework_Repository::repository_, + ACE_Framework_Repository (size), + 0); + } + } + } + + return ACE_Framework_Repository::repository_; +} + +void +ACE_Framework_Repository::close_singleton (void) +{ + ACE_TRACE ("ACE_Framework_Repository::close_singleton"); + + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance ())); + + delete ACE_Framework_Repository::repository_; + ACE_Framework_Repository::repository_ = 0; +} + +int +ACE_Framework_Repository::register_component (ACE_Framework_Component *fc) +{ + ACE_TRACE ("ACE_Framework_Repository::register_component"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + int i; + + // Check to see if it's already registered + for (i = 0; i < this->current_size_; i++) + if (this->component_vector_[i] && + fc->this_ == this->component_vector_[i]->this_) + { + ACE_ERROR_RETURN ((LM_ERROR, + "AFR::register_component: error, compenent already registered\n"), + -1); + } + + if (i < this->total_size_) + { + this->component_vector_[i] = fc; + this->current_size_++; + return 0; + } + + return -1; +} + +int +ACE_Framework_Repository::remove_component (const ACE_TCHAR *name) +{ + ACE_TRACE ("ACE_Framework_Repository::remove_component"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + int i; + + for (i = 0; i < this->current_size_; i++) + if (this->component_vector_[i] && + ACE_OS::strcmp (this->component_vector_[i]->name_, name) == 0) + { + delete this->component_vector_[i]; + this->component_vector_[i] = 0; + this->compact (); + return 0; + } + + return -1; +} + +int +ACE_Framework_Repository::remove_dll_components (const ACE_TCHAR *dll_name) +{ + ACE_TRACE ("ACE_Framework_Repository::remove_dll_components"); + + if (this->shutting_down_) + return this->remove_dll_components_i (dll_name); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + return this->remove_dll_components_i (dll_name); +} + +int +ACE_Framework_Repository::remove_dll_components_i (const ACE_TCHAR *dll_name) +{ + ACE_TRACE ("ACE_Framework_Repository::remove_dll_components_i"); + + int i; + int retval = -1; + + for (i = 0; i < this->current_size_; i++) + if (this->component_vector_[i] && + ACE_OS::strcmp (this->component_vector_[i]->dll_name_, dll_name) == 0) + { + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("AFR::remove_dll_components_i (%s) ") + ACE_TEXT ("component \"%s\"\n"), + dll_name, this->component_vector_[i]->name_)); + delete this->component_vector_[i]; + this->component_vector_[i] = 0; + ++retval; + } + + this->compact (); + + return retval == -1 ? -1 : 0; +} + +void +ACE_Framework_Repository::compact (void) +{ + ACE_TRACE ("ACE_Framework_Repository::compact"); + + int i; + int start_hole; + int end_hole; + + do + { + start_hole = this->current_size_; + end_hole = this->current_size_; + + // Find hole + for (i = 0; i < this->current_size_; ++i) + { + if (this->component_vector_[i] == 0) + { + if (start_hole == this->current_size_) + { + start_hole = i; + end_hole = i; + } + else + end_hole = i; + } + else if (end_hole != this->current_size_) + break; + } + + if (start_hole != this->current_size_) + { + // move the contents and reset current_size_ + while (end_hole + 1 < this->current_size_) + { + this->component_vector_[start_hole++] = + this->component_vector_[++end_hole]; + } + // Since start_hole is now one past the last + // active slot. + this->current_size_ = start_hole; + } + + } while (start_hole != this->current_size_); +} + +void +ACE_Framework_Repository::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Framework_Repository::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Framework_Repository::ACE_Framework_Repository (int size) + : current_size_ (0) +{ + ACE_TRACE ("ACE_Framework_Repository::ACE_Framework_Repository"); + + if (this->open (size) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Framework_Repository"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Framework_Component.h b/dep/ACE_wrappers/ace/Framework_Component.h new file mode 100644 index 000000000..941960bf0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Framework_Component.h @@ -0,0 +1,210 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Framework_Component.h + * + * $Id: Framework_Component.h 80826 2008-03-04 14:51:23Z wotte $ + * + * A prototype mechanism that allows framework components, singletons + * such as ACE_Reactor, ACE_Proactor, etc, to be registered with a + * central repository managed by the ACE_Object_Manager or + * ACE_Service_Config that will handle destruction. + * + * This technique obviates changing ACE_Object_Manager and + * ACE_Service_Config everytime a new framework is added. Which also + * means that unused framework components don't need to linked into + * the final application which is important for applications with + * stringent footprint requirements. + * + * Framework components need only provide a static method, + * close_singleton() and add the ACE_REGISTER_FRAMEWORK_COMPONENT macro + * call to their instance() methods in order to participate. Components + * that don't have a close_singleton() method can also participate via + * template specialization of ACE_Framework_Component_T. + * + * This design uses the External Polymorphism pattern to avoid having + * to derive all framework components from a common base class that + * has virtual methods (this is crucial to avoid unnecessary overhead), + * and is based on the dump debugging implementation found in + * . + * + * @author Don Hinton . + */ +//============================================================================= + +#ifndef ACE_FRAMEWORK_COMPONENT_H +#define ACE_FRAMEWORK_COMPONENT_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_signal.h" +#include "ace/Thread_Mutex.h" + +#define ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE 1024 + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Framework_Component + * + * @brief Base class that defines a uniform interface for all managed + * framework components. + */ +class ACE_Export ACE_Framework_Component +{ +public: + friend class ACE_Framework_Repository; + + /// Constructor. + ACE_Framework_Component (void *_this, + const ACE_TCHAR *dll_name = 0, + const ACE_TCHAR *name = 0); + + /// Close the contained singleton. + virtual void close_singleton (void) = 0; + +protected: + /// Destructor. + virtual ~ACE_Framework_Component (void); + +private: + // No copy possible + ACE_Framework_Component (const ACE_Framework_Component &); + void operator= (const ACE_Framework_Component &); + +private: + /// Pointer to the actual component. + const void *this_; + + /// Library associated with this component + const ACE_TCHAR *dll_name_; + + /// Component name + const ACE_TCHAR *name_; +}; + +/** + * @class ACE_Framework_Repository + * + * @brief Contains all framework components used by an application. + * + * This class contains a vector of ACE_Framework_Component *'s. On + * destruction, framework components are destroyed in the reverse order + * that they were added originally. + */ +class ACE_Export ACE_Framework_Repository +{ +public: + // This is just to silence a compiler warning about no public ctors + friend class ACE_Framework_Component; + + enum + { + DEFAULT_SIZE = ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE + }; + + /// Close down the repository and free up dynamically allocated + /// resources. + ~ACE_Framework_Repository (void); + + /// Initialize the repository. + int open (int size = DEFAULT_SIZE); + + /// Close down the repository and free up dynamically allocated + /// resources, also called by dtor. + int close (void); + + /// Get pointer to a process-wide ACE_Framework_Repository. + static ACE_Framework_Repository *instance + (int size = ACE_Framework_Repository::DEFAULT_SIZE); + + /// Delete the dynamically allocated Singleton. + static void close_singleton (void); + + // = Search structure operations (all acquire locks as necessary). + + /// Insert a new component. Returns -1 when the repository is full + /// and 0 on success. + int register_component (ACE_Framework_Component *fc); + + /// Remove a component. Returns -1 on error or if component not found + /// and 0 on success. + int remove_component (const ACE_TCHAR *name); + + /// Remove all components associated with a particular dll. + int remove_dll_components (const ACE_TCHAR *dll_name); + + /// Return the current size of the repository. + int current_size (void) const; + + /// Return the total size of the repository. + int total_size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + + /// Initialize the repository. + ACE_Framework_Repository (int size = ACE_Framework_Repository::DEFAULT_SIZE); + +private: + + /// Actually removes the dll components, must be called with locks held. + int remove_dll_components_i (const ACE_TCHAR *dll_name); + + /// Compact component_vector_ after components have been removed__maintains + /// order. + void compact (void); + + /// Disallow copying and assignment. + ACE_Framework_Repository (const ACE_Framework_Repository &); + ACE_Framework_Repository &operator= (const ACE_Framework_Repository &); + +private: + + /// Contains all the framework components. + ACE_Framework_Component **component_vector_; + + /// Current number of components. + int current_size_; + + /// Maximum number of components. + int total_size_; + + /// Pointer to a process-wide ACE_Framework_Repository. + static ACE_Framework_Repository *repository_; + + /// Flag set when repository is the process of shutting down. This + /// is necessary to keep from self-deadlocking since some of + /// the components might make calls back to the repository to + /// unload their components, e.g., ACE_DLL_Manager. + static sig_atomic_t shutting_down_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Synchronization variable for the MT_SAFE Repository + ACE_Thread_Mutex lock_; +#endif /* ACE_MT_SAFE */ + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Framework_Component.inl" +#endif /* __ACE_INLINE__ */ + +// Include the templates classes at this point. +#include "ace/Framework_Component_T.h" + +#include /**/ "ace/post.h" +#endif /* ACE_FRAMEWORK_COMPONENT_H */ diff --git a/dep/ACE_wrappers/ace/Framework_Component.inl b/dep/ACE_wrappers/ace/Framework_Component.inl new file mode 100644 index 000000000..1fb2de38b --- /dev/null +++ b/dep/ACE_wrappers/ace/Framework_Component.inl @@ -0,0 +1,39 @@ +// -*- C++ -*- +// +// $Id: Framework_Component.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" +#include "ace/Guard_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Framework_Component::ACE_Framework_Component (void *_this, + const ACE_TCHAR *dll_name, + const ACE_TCHAR *name) + : this_ (_this), + dll_name_ (ACE::strnew (dll_name ? dll_name : ACE_TEXT (""))), + name_ (ACE::strnew (name ? name : ACE_TEXT (""))) +{ + ACE_TRACE ("ACE_Framework_Component::ctor"); +} + +/***************************************************************/ + +ACE_INLINE int +ACE_Framework_Repository::current_size (void) const +{ + ACE_TRACE ("ACE_Framework_Repository::current_size"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->lock_, -1)); + return this->current_size_; +} + +ACE_INLINE int +ACE_Framework_Repository::total_size (void) const +{ + ACE_TRACE ("ACE_Framework_Repository::total_size"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->lock_, -1)); + return this->total_size_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Framework_Component_T.cpp b/dep/ACE_wrappers/ace/Framework_Component_T.cpp new file mode 100644 index 000000000..6f0be7b5e --- /dev/null +++ b/dep/ACE_wrappers/ace/Framework_Component_T.cpp @@ -0,0 +1,33 @@ +// $Id: Framework_Component_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_FRAMEWORK_COMPONENT_T_CPP +#define ACE_FRAMEWORK_COMPONENT_T_CPP + +#include "ace/Framework_Component_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Framework_Component_T::ACE_Framework_Component_T (Concrete *concrete) + : ACE_Framework_Component ((void *) concrete, concrete->dll_name (), concrete->name ()) +{ + ACE_TRACE ("ACE_Framework_Component_T::ctor"); +} + +template +ACE_Framework_Component_T::~ACE_Framework_Component_T (void) +{ + ACE_TRACE ("ACE_Framework_Component_T::~ACE_Framework_Component_T"); + Concrete::close_singleton (); +} + +template void +ACE_Framework_Component_T::close_singleton (void) +{ + ACE_TRACE ("ACE_Framework_Component_T::close_singleton"); + Concrete::close_singleton (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_FRAMEWORK_COMPONENT_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Framework_Component_T.h b/dep/ACE_wrappers/ace/Framework_Component_T.h new file mode 100644 index 000000000..2dcef43e3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Framework_Component_T.h @@ -0,0 +1,71 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Framework_Component_T.h + * + * $Id: Framework_Component_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + */ +//============================================================================= + +#ifndef ACE_FRAMEWORK_COMPONENT_T_H +#define ACE_FRAMEWORK_COMPONENT_T_H +#include /**/ "ace/pre.h" +#include "ace/Framework_Component.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Framework_Component_T + * + * @brief This class inherits the interface of the abstract + * ACE_Framework_Component class and is instantiated with the + * implementation of the concrete component class @c class Concrete. + * + * This design is similar to the Adapter and Decorator patterns + * from the ``Gang of Four'' book. Note that @c class Concrete + * need not inherit from a common class since ACE_Framework_Component + * provides the uniform virtual interface! (implementation based on + * ACE_Dumpable_Adapter in . + */ +template +class ACE_Framework_Component_T : public ACE_Framework_Component +{ +public: + // = Initialization and termination methods. + + /// Constructor. + ACE_Framework_Component_T (Concrete *concrete); + + /// Destructor. + ~ACE_Framework_Component_T (void); + + /// Close the contained singleton. + void close_singleton (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +// This macro should be called in the instance() method +// of the Concrete class that will be managed. Along +// with the appropriate template instantiation. +#define ACE_REGISTER_FRAMEWORK_COMPONENT(CLASS, INSTANCE) \ + ACE_Framework_Repository::instance ()->register_component \ + (new ACE_Framework_Component_T (INSTANCE)); + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Framework_Component_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Framework_Component_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_FRAMEWORK_COMPONENT_T_H */ diff --git a/dep/ACE_wrappers/ace/Free_List.cpp b/dep/ACE_wrappers/ace/Free_List.cpp new file mode 100644 index 000000000..4da723f48 --- /dev/null +++ b/dep/ACE_wrappers/ace/Free_List.cpp @@ -0,0 +1,163 @@ +// $Id: Free_List.cpp 81107 2008-03-27 11:12:42Z johnnyw $ + +#ifndef ACE_FREE_LIST_CPP +#define ACE_FREE_LIST_CPP + +#include "ace/Free_List.h" +#include "ace/Guard_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Free_List::~ACE_Free_List (void) +{ +} + +// Default constructor that takes in a preallocation number +// (), a low and high water mark ( and ) and an +// increment value () + +template +ACE_Locked_Free_List::ACE_Locked_Free_List (int mode, + size_t prealloc, + size_t lwm, + size_t hwm, + size_t inc) + : mode_ (mode), + free_list_ (0), + lwm_ (lwm), + hwm_ (hwm), + inc_ (inc), + size_ (0) +{ + this->alloc (prealloc); +} + +// Destructor - removes all the elements from the free_list + +template +ACE_Locked_Free_List::~ACE_Locked_Free_List (void) +{ + if (this->mode_ != ACE_PURE_FREE_LIST) + while (this->free_list_ != 0) + { + T *temp = this->free_list_; + this->free_list_ = this->free_list_->get_next (); + delete temp; + } +} + +// Inserts an element onto the free list (if we are allowed to manage +// elements withing and it pasts the high water mark, delete the +// element) + +template void +ACE_Locked_Free_List::add (T *element) +{ + ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_)); + + // Check to see that we not at the high water mark. + if (this->mode_ == ACE_PURE_FREE_LIST + || this->size_ < this->hwm_) + { + element->set_next (this->free_list_); + this->free_list_ = element; + this->size_++; + } + else + delete element; +} + +// Takes a element off the freelist and returns it. It creates +// new elements if we are allowed to do it and the size is at the low +// water mark. + +template T * +ACE_Locked_Free_List::remove (void) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, 0)); + + // If we are at the low water mark, add some nodes + if (this->mode_ != ACE_PURE_FREE_LIST && this->size_ <= this->lwm_) + this->alloc (this->inc_); + + // Remove a node + T *temp = this->free_list_; + + if (temp != 0) + { + this->free_list_ = this->free_list_->get_next (); + this->size_--; + } + + return temp; +} + + +// Returns the current size of the free list + +template size_t +ACE_Locked_Free_List::size (void) +{ + return this->size_; +} + +// Resizes the free list to + +template void +ACE_Locked_Free_List::resize (size_t newsize) +{ + ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_)); + + // Check if we are allowed to resize + if (this->mode_ != ACE_PURE_FREE_LIST) + { + // Check to see if we grow or shrink + if (newsize < this->size_) + { + this->dealloc (this->size_ - newsize); + } + else + { + this->alloc (newsize - this->size_); + } + } +} + +// Allocates extra nodes for the freelist + +template void +ACE_Locked_Free_List::alloc (size_t n) +{ + for (; n > 0; n--) + { + T *temp = 0; + ACE_NEW (temp, T); + temp->set_next (this->free_list_); + this->free_list_ = temp; + this->size_++; + } +} + +// Removes and frees nodes from the freelist. + +template void +ACE_Locked_Free_List::dealloc (size_t n) +{ + for (; this->free_list_ != 0 && n > 0; + n--) + { + T *temp = this->free_list_; + this->free_list_ = this->free_list_->get_next (); + delete temp; + this->size_--; + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_FREE_LIST_CPP */ diff --git a/dep/ACE_wrappers/ace/Free_List.h b/dep/ACE_wrappers/ace/Free_List.h new file mode 100644 index 000000000..3d429dcaf --- /dev/null +++ b/dep/ACE_wrappers/ace/Free_List.h @@ -0,0 +1,150 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Free_List.h + * + * $Id: Free_List.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Darrell Brunsch (brunsch@cs.wustl.edu) + */ +//============================================================================= + +#ifndef ACE_FREE_LIST_H +#define ACE_FREE_LIST_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/Default_Constants.h" +#include "ace/os_include/os_stddef.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Free_List + * + * @brief Implements a free list. + * + * This class maintains a free list of nodes of type T. + */ +template +class ACE_Free_List +{ +public: + /// Destructor - removes all the elements from the free_list. + virtual ~ACE_Free_List (void); + + /// Inserts an element onto the free list (if it isn't past the high + /// water mark). + virtual void add (T *element) = 0; + + /// Takes a element off the freelist and returns it. It creates + /// new elements if the size is at or below the low water mark. + virtual T *remove (void) = 0; + + /// Returns the current size of the free list. + virtual size_t size (void) = 0; + + /// Resizes the free list to @a newsize. + virtual void resize (size_t newsize) = 0; +}; + +/** + * @class ACE_Locked_Free_List + * + * @brief Implements a free list. + * + * This class maintains a free list of nodes of type T. It + * depends on the type T having a and + * method. It maintains a mutex so the freelist can be used in + * a multithreaded program . + */ +template +class ACE_Locked_Free_List : public ACE_Free_List +{ +public: + // = Initialization and termination. + /** + * Constructor takes a @a mode (i.e., ACE_FREE_LIST_WITH_POOL or + * ACE_PURE_FREE_LIST), a count of the number of nodes to + * , a low and high water mark ( and ) that + * indicate when to allocate more nodes, an increment value () + * that indicates how many nodes to allocate when the list must + * grow. + */ + ACE_Locked_Free_List (int mode = ACE_FREE_LIST_WITH_POOL, + size_t prealloc = ACE_DEFAULT_FREE_LIST_PREALLOC, + size_t lwm = ACE_DEFAULT_FREE_LIST_LWM, + size_t hwm = ACE_DEFAULT_FREE_LIST_HWM, + size_t inc = ACE_DEFAULT_FREE_LIST_INC); + + /// Destructor - removes all the elements from the free_list. + virtual ~ACE_Locked_Free_List (void); + + /// Inserts an element onto the free list (if it isn't past the high + /// water mark). + virtual void add (T *element); + + /// Takes a element off the freelist and returns it. It creates + /// new elements if the size is at or below the low water mark. + virtual T *remove (void); + + /// Returns the current size of the free list. + virtual size_t size (void); + + /// Resizes the free list to @a newsize. + virtual void resize (size_t newsize); + +protected: + /// Allocates @a n extra nodes for the freelist. + virtual void alloc (size_t n); + + /// Removes and frees @a n nodes from the freelist. + virtual void dealloc (size_t n); + + /// Free list operation mode, either ACE_FREE_LIST_WITH_POOL or + /// ACE_PURE_FREE_LIST. + int mode_; + + /// Pointer to the first node in the freelist. + T *free_list_; + + /// Low water mark. + size_t lwm_; + + /// High water mark. + size_t hwm_; + + /// Increment value. + size_t inc_; + + /// Keeps track of the size of the list. + size_t size_; + + /// Synchronization variable for ACE_Timer_Queue. + ACE_LOCK mutex_; + +private: + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Locked_Free_List (const ACE_Locked_Free_List &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Locked_Free_List &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Free_List.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Free_List.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_FREE_LIST_H */ diff --git a/dep/ACE_wrappers/ace/Functor.cpp b/dep/ACE_wrappers/ace/Functor.cpp new file mode 100644 index 000000000..429aaac9f --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor.cpp @@ -0,0 +1,43 @@ + +//============================================================================= +/** + * @file Functor.cpp + * + * $Id: Functor.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * Non-inlinable method definitions for non-templatized classes + * and template specializations implementing the GOF Command Pattern, + * and STL-style functors. + * + * + * @author Chris Gill + * + * Based on Command Pattern implementations originally done by + * + * Carlos O'Ryan + * Douglas C. Schmidt + * Sergio Flores-Gaitan + * + * and on STL-style functor implementations originally done by + * + * Irfan Pyarali + */ +//============================================================================= + + +#include "ace/Functor_T.h" +#include "ace/Functor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Functor.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Functor, "$Id: Functor.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Command_Base::~ACE_Command_Base (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Functor.h b/dep/ACE_wrappers/ace/Functor.h new file mode 100644 index 000000000..8504cf076 --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor.h @@ -0,0 +1,593 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Functor.h + * + * $Id: Functor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Non-templatized classes and class template specializations for + * implementing function objects that are used in various places + * in ACE. There are currently two major categories of function + * objects in ACE: GoF Command Pattern objects, and STL-style + * functors for comparison of container elements. The command objects + * are invoked via an execute () method, while the STL-style functors are + * invoked via an operator() () method. + * Non-templatized classes for implementing the GoF Command Pattern, + * also known as functors or function objects. + * + * + * @author Chris Gill + * @author Based on Command Pattern implementations originally done by + * @author Carlos O'Ryan + * @author Douglas C. Schmidt + * @author Sergio Flores-Gaitan + * @author and on STL-style functor implementations originally done by + * @author Irfan Pyarali + */ +//========================================================================== + + +#ifndef ACE_FUNCTOR_H +#define ACE_FUNCTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/ACE_export.h" +#include "ace/Basic_Types.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +////////////////////////////////////////////////////////////// +// GOF Command Pattern Classes and Template Specializations // +////////////////////////////////////////////////////////////// + +/** + * @class ACE_Command_Base + * + * @brief Defines an abstract class that allows us to invoke commands + * without knowing anything about the implementation. + * + * This class declares an interface to execute a command + * independent of the effect of the command, or the objects used + * to implement it. + */ +class ACE_Export ACE_Command_Base +{ +public: + // = Initialization and termination methods. + /// Default constructor. + ACE_Command_Base (void); + + /// Virtual destructor. + virtual ~ACE_Command_Base (void); + + /** + * Invokes the method encapsulated by the command, passing along the + * passed argument (if any). Users of classes derived from this + * class must ensure that the resulting invocation can tolerate a + * null void pointer being passed, or otherwise ensure that this + * will never occur. + */ + virtual int execute (void *arg = 0) = 0; +}; + +//////////////////////////////////////////////////////////// +// STL-style Functor Classes and Template Specializations // +//////////////////////////////////////////////////////////// + +// Forward declaration since we are going to specialize that template +// here. The template itself requires this file so every user of the +// template should also see the specialization. +template class ACE_Hash; +template class ACE_Equal_To; +template class ACE_Less_Than; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a char + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (char t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a signed char + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (signed char t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing an unsigned char + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (unsigned char t) const; +}; + +#if 0 +// @@ ADD HASHES FOR ACE TYPES + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a 16-bit signed number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (ACE_INT16 t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a 16-bit unsigned number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (ACE_UINT16 t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a 32-bit signed number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (ACE_INT32 t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a 32-bit unsigned number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (ACE_UINT32 t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a 64-bit unsigned number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (ACE_UINT64 t) const; +}; + +// @@ DONE ADDING HASHES FOR ACE TYPES +#endif + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a short number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (short t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing an unsigned short number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (unsigned short t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing an int number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (int t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing an unsigned int number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (unsigned int t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a long number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (long t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing an unsigned long number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (unsigned long t) const; +}; + +#if !defined (ACE_LACKS_LONGLONG_T) && (ACE_SIZEOF_LONG < 8) +/** + * @class ACE_Hash + * + * @brief Function object for hashing a signed 64-bit number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (ACE_INT64 t) const; +}; +#endif /* !ACE_LACKS_LONGLONG_T && ACE_SIZEOF_LONG < 8 */ + +// We can do this even if ACE_LACKS_UNSIGNEDLONGLONG_T because there's an +// emulation for it in ACE_U_LongLong. +#if (ACE_SIZEOF_LONG < 8) +/** + * @class ACE_Hash + * + * @brief Function object for hashing an unsigned 64-bit number + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (const ACE_UINT64 &t) const; +}; +#endif /* ACE_SIZEOF_LONG < 8 */ + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a const string + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Calls ACE::hash_pjw + unsigned long operator () (const char *t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a string + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Calls ACE::hash_pjw + unsigned long operator () (const char *t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a void * + */ +template<> +class ACE_Export ACE_Hash +{ +public: + unsigned long operator () (const void *) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two const strings are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const char *lhs, + const char *rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two non-const + * strings are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const char *lhs, + const char *rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two unsigned + * 16 bit ints are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls built-in operators + int operator () (const ACE_UINT16 lhs, + const ACE_UINT16 rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two + * 16 bit ints are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls built-in operators + int operator () (const ACE_INT16 lhs, + const ACE_INT16 rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two unsigned + * 32 bit ints are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls built-in operators + int operator () (const ACE_UINT32 lhs, + const ACE_UINT32 rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two + * 32 bit ints are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls built-in operators + int operator () (const ACE_INT32 lhs, + const ACE_INT32 rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two unsigned + * 64 bit ints are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls built-in operators + int operator () (const ACE_UINT64 lhs, + const ACE_UINT64 rhs) const; +}; + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first const string + * is less than the second const string. + */ +template<> +class ACE_Export ACE_Less_Than +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const char *lhs, + const char *rhs) const; +}; + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first string + * is less than the second string. + */ +template<> +class ACE_Export ACE_Less_Than +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const char *lhs, + const char *rhs) const; +}; + +#if defined (ACE_HAS_WCHAR) + +# if ! defined (ACE_LACKS_NATIVE_WCHAR_T) +/** + * @class ACE_Hash + * + * @brief Function object for hashing a wchar_t + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Simply returns t + unsigned long operator () (wchar_t t) const; +}; +# endif /* ACE_LACKS_NATIVE_WCHAR_T */ +/** + * @class ACE_Hash + * + * @brief Function object for hashing a const string + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Calls ACE::hash_pjw + unsigned long operator () (const wchar_t *t) const; +}; + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a string + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Calls ACE::hash_pjw + unsigned long operator () (const wchar_t *t) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two const strings are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const wchar_t *lhs, + const wchar_t *rhs) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two non-const + * strings are equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const wchar_t *lhs, + const wchar_t *rhs) const; +}; + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first const string + * is less than the second const string. + */ +template<> +class ACE_Export ACE_Less_Than +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const wchar_t *lhs, + const wchar_t *rhs) const; +}; + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first string + * is less than the second string. + */ +template<> +class ACE_Export ACE_Less_Than +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const wchar_t *lhs, + const wchar_t *rhs) const; +}; + +#endif // ACE_HAS_WCHAR + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Functor.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_FUNCTOR_H */ diff --git a/dep/ACE_wrappers/ace/Functor.inl b/dep/ACE_wrappers/ace/Functor.inl new file mode 100644 index 000000000..30e539459 --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor.inl @@ -0,0 +1,284 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Functor.inl + * + * $Id: Functor.inl 80826 2008-03-04 14:51:23Z wotte $ + * + * Inlinable method definitions for non-templatized classes + * and template specializations implementing the GOF Command Pattern, + * and STL-style functors. + * + * + * @author Chris Gill + * + * Based on Command Pattern implementations originally done by + * + * Carlos O'Ryan + * Douglas C. Schmidt + * Sergio Flores-Gaitan + * + * and on STL-style functor implementations originally done by + * Irfan Pyarali + */ +//============================================================================= + + +#include "ace/ACE.h" +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +////////////////////////////////////////////////////////////// +// GOF Command Pattern Classes and Template Specializations // +////////////////////////////////////////////////////////////// + +// Default constructor. + +ACE_INLINE +ACE_Command_Base::ACE_Command_Base (void) +{ +} + +//////////////////////////////////////////////////////////// +// STL-style Functor Classes and Template Specializations // +//////////////////////////////////////////////////////////// + +ACE_INLINE unsigned long +ACE_Hash::operator () (char t) const +{ + return t; +} + +#if defined (ACE_HAS_WCHAR) && ! defined (ACE_LACKS_NATIVE_WCHAR_T) +ACE_INLINE unsigned long +ACE_Hash::operator () (wchar_t t) const +{ + return t; +} +#endif /* ACE_HAS_WCHAR && ! ACE_LACKS_NATIVE_WCHAR_T */ + +ACE_INLINE unsigned long +ACE_Hash::operator () (signed char t) const +{ + return t; +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (unsigned char t) const +{ + return t; +} + +#if 0 +ACE_INLINE unsigned long +ACE_Hash::operator () (ACE_INT16 t) const +{ + return t; +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (ACE_UINT16 t) const +{ + return t; +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (ACE_INT32 t) const +{ + return static_cast (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (ACE_UINT32 t) const +{ + return t; +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (ACE_UINT64 t) const +{ +#if (ACE_SIZEOF_LONG == 4) + return ACE_U64_TO_U32 (t); +#else + return static_cast (t); +#endif /* ACE_SIZEOF_LONG */ +} +#endif + +ACE_INLINE unsigned long +ACE_Hash::operator () (short t) const +{ + return static_cast (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (unsigned short t) const +{ + return static_cast (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (int t) const +{ + return static_cast (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (unsigned int t) const +{ + return static_cast (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (long t) const +{ + return static_cast (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (unsigned long t) const +{ + return t; +} + +// This #if needs to match the one in Functor.h +#if !defined (ACE_LACKS_LONGLONG_T) && (ACE_SIZEOF_LONG < 8) +ACE_INLINE unsigned long +ACE_Hash::operator () (ACE_INT64 t) const +{ + return static_cast (t); +} +#endif /* !ACE_LACKS_LONGLONG_T && ACE_SIZEOF_LONG < 8 */ + +#if (ACE_SIZEOF_LONG < 8) +ACE_INLINE unsigned long +ACE_Hash::operator () (const ACE_UINT64 &t) const +{ +#if (ACE_SIZEOF_LONG == 4) + return ACE_U64_TO_U32 (t); +#else + return static_cast (t); +#endif /* ACE_SIZEOF_LONG */ +} +#endif /* !ACE_LACKS_UNSIGNEDLONGLONG_T */ + +ACE_INLINE unsigned long +ACE_Hash::operator () (const char *t) const +{ + return ACE::hash_pjw (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (const char *t) const +{ + return ACE::hash_pjw (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (const void *t) const +{ + return static_cast (reinterpret_cast (t)); +} + +/***********************************************************************/ +ACE_INLINE int +ACE_Equal_To::operator () (const char *lhs, const char *rhs) const +{ + return !ACE_OS::strcmp (lhs, rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const char *lhs, const char *rhs) const +{ + return !ACE_OS::strcmp (lhs, rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_UINT16 lhs, const ACE_UINT16 rhs) const +{ + return (lhs == rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_INT16 lhs, const ACE_INT16 rhs) const +{ + return (lhs == rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_UINT32 lhs, const ACE_UINT32 rhs) const +{ + return (lhs == rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_INT32 lhs, const ACE_INT32 rhs) const +{ + return (lhs == rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_UINT64 lhs, const ACE_UINT64 rhs) const +{ + return (lhs == rhs); +} + +/****************************************************************************/ +ACE_INLINE int +ACE_Less_Than::operator () (const char *lhs, const char *rhs) const +{ + return (ACE_OS::strcmp (lhs, rhs) < 0) ? 1 : 0; +} + +ACE_INLINE int +ACE_Less_Than::operator () (const char *lhs, const char *rhs) const +{ + return (ACE_OS::strcmp (lhs, rhs) < 0) ? 1 : 0; +} + + +#if defined (ACE_HAS_WCHAR) + +ACE_INLINE unsigned long +ACE_Hash::operator () (const wchar_t *t) const +{ + return ACE::hash_pjw (t); +} + +ACE_INLINE unsigned long +ACE_Hash::operator () (const wchar_t *t) const +{ + return ACE::hash_pjw (t); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const wchar_t *lhs, + const wchar_t *rhs) const +{ + return !ACE_OS::strcmp (lhs, rhs); +} + +ACE_INLINE int +ACE_Equal_To::operator () (const wchar_t *lhs, + const wchar_t *rhs) const +{ + return !ACE_OS::strcmp (lhs, rhs); +} + +ACE_INLINE int +ACE_Less_Than::operator () (const wchar_t *lhs, const wchar_t *rhs) const +{ + return (ACE_OS::strcmp (lhs, rhs) < 0) ? 1 : 0; +} + +ACE_INLINE int +ACE_Less_Than::operator () (const wchar_t *lhs, const wchar_t *rhs) const +{ + return (ACE_OS::strcmp (lhs, rhs) < 0) ? 1 : 0; +} + +#endif // ACE_HAS_WCHAR + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Functor_String.cpp b/dep/ACE_wrappers/ace/Functor_String.cpp new file mode 100644 index 000000000..c113f5cdf --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor_String.cpp @@ -0,0 +1,7 @@ +#include "ace/Functor_String.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Functor_String.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Functor, "$Id: Functor_String.cpp 80826 2008-03-04 14:51:23Z wotte $") diff --git a/dep/ACE_wrappers/ace/Functor_String.h b/dep/ACE_wrappers/ace/Functor_String.h new file mode 100644 index 000000000..6070fcf1b --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor_String.h @@ -0,0 +1,141 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Functor_String.h + * + * $Id: Functor_String.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Class template specializations for ACE_*String types implementing + * function objects that are used in various places in ATC. They + * could be placed in Functor.h. But we don't want to couple string + * types to the rest of ACE+TAO. Hence they are placed in a seperate + * file. + */ +//========================================================================== +#ifndef ACE_FUNCTOR_STRING_H +#define ACE_FUNCTOR_STRING_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/ACE_export.h" +#include "ace/SStringfwd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +//////////////////////////////////////////////////////////// +// STL-style Functor Classes and Template Specializations // +//////////////////////////////////////////////////////////// + +// Forward declaration since we are going to specialize that template +// here. The template itself requires this file so every user of the +// template should also see the specialization. +template class ACE_Hash; +template class ACE_Equal_To; +template class ACE_Less_Than; + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two ACE_CStrings are + * equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + int operator () (const ACE_CString &lhs, + const ACE_CString &rhs) const; +}; + + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a ACE_CString + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Calls ACE::hash_pjw + unsigned long operator () (const ACE_CString &lhs) const; +}; + + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first const string + * is less than the second const string. + */ +template<> +class ACE_Export ACE_Less_Than +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const ACE_CString &lhs, + const ACE_CString &rhs) const; +}; + + +#if defined (ACE_USES_WCHAR) + +/** + * @class ACE_Equal_To + * + * @brief Function object for determining whether two ACE_CStrings are + * equal. + */ +template<> +class ACE_Export ACE_Equal_To +{ +public: + int operator () (const ACE_WString &lhs, + const ACE_WString &rhs) const; +}; + + +/** + * @class ACE_Hash + * + * @brief Function object for hashing a ACE_WString + */ +template<> +class ACE_Export ACE_Hash +{ +public: + /// Calls ACE::hash_pjw + unsigned long operator () (const ACE_WString &lhs) const; +}; + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first const string + * is less than the second const string. + */ +template<> +class ACE_Export ACE_Less_Than +{ +public: + /// Simply calls ACE_OS::strcmp + int operator () (const ACE_WString &lhs, + const ACE_WString &rhs) const; +}; + +#endif /*ACE_USES_WCHAR*/ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Functor_String.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /*ACE_FUNCTOR_STRING_H*/ diff --git a/dep/ACE_wrappers/ace/Functor_String.inl b/dep/ACE_wrappers/ace/Functor_String.inl new file mode 100644 index 000000000..bdac96386 --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor_String.inl @@ -0,0 +1,56 @@ +// -*- C++ -*- +// +// $Id: Functor_String.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" +#include "ace/String_Base.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE unsigned long +ACE_Hash::operator () (const ACE_CString &t) const +{ + return t.hash (); +} + + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_CString &lhs, + const ACE_CString &rhs) const +{ + return lhs == rhs; +} + +ACE_INLINE int +ACE_Less_Than::operator () (const ACE_CString &lhs, + const ACE_CString &rhs) const +{ + return (lhs < rhs); +} + + +#if defined (ACE_USES_WCHAR) +ACE_INLINE unsigned long +ACE_Hash::operator () (const ACE_WString &t) const +{ + return t.hash (); +} + + +ACE_INLINE int +ACE_Equal_To::operator () (const ACE_WString &lhs, + const ACE_WString &rhs) const +{ + return lhs == rhs; +} + +ACE_INLINE int +ACE_Less_Than::operator () (const ACE_WString &lhs, + const ACE_WString &rhs) const +{ + return (lhs < rhs); +} + +#endif /*ACE_USES_WCHAR*/ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Functor_T.cpp b/dep/ACE_wrappers/ace/Functor_T.cpp new file mode 100644 index 000000000..213b501aa --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor_T.cpp @@ -0,0 +1,49 @@ +// $Id: Functor_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_FUNCTOR_T_CPP +#define ACE_FUNCTOR_T_CPP + +#include "ace/Functor_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Functor_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Command_Callback) + +/////////////////////////////////// +// GOF Command Pattern Templates // +/////////////////////////////////// + +// Constructor. + +template +ACE_Command_Callback::ACE_Command_Callback (RECEIVER &recvr, + ACTION action) + : receiver_ (recvr), + action_ (action) +{ +} + +template +ACE_Command_Callback::~ACE_Command_Callback (void) +{ +} + +// Invokes an operation. + +template int +ACE_Command_Callback::execute (void *arg) +{ + return (receiver_.*action_) (arg); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_FUNCTOR_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Functor_T.h b/dep/ACE_wrappers/ace/Functor_T.h new file mode 100644 index 000000000..f055c3c88 --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor_T.h @@ -0,0 +1,158 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Functor_T.h + * + * $Id: Functor_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Templatized classes for implementing function objects that are + * used in various places in ACE. There are currently two major + * categories of function objects in ACE: GOF Command Pattern + * objects, and STL-style functors for comparison of container + * elements. The command objects are invoked via an + * method, while the STL-style functors are invoked via an + * method. + * + * + * @author Chris Gill + * @author Based on Command Pattern implementations originally done by + * @author Carlos O'Ryan + * @author Douglas C. Schmidt + * @author Sergio Flores-Gaitan + * @author and on STL-style functor implementations originally done by + * @author Irfan Pyarali + */ +//============================================================================= + + +#ifndef ACE_FUNCTOR_T_H +#define ACE_FUNCTOR_T_H +#include /**/ "ace/pre.h" + +#include "ace/Functor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Functor_String.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/////////////////////////////////// +// GOF Command Pattern Templates // +/////////////////////////////////// + +/** + * @class ACE_Command_Callback + * + * @brief Defines a class template that allows us to invoke a GOF + * command style callback to an object without knowing anything + * about the object except its type. + * + * This class declares an interface to execute operations, + * binding a RECEIVER object with an ACTION. The RECEIVER knows + * how to implement the operation. A class can invoke operations + * without knowing anything about it, or how it was implemented. + */ +template +class ACE_Command_Callback : public ACE_Command_Base +{ +public: + /// Constructor: sets the of the Command to recvr, and the + /// of the Command to . + ACE_Command_Callback (RECEIVER &recvr, ACTION action); + + /// Virtual destructor. + virtual ~ACE_Command_Callback (void); + + /// Invokes the method from the object . + virtual int execute (void *arg = 0); + +private: + /// Object where the method resides. + RECEIVER &receiver_; + + /// Method that is going to be invoked. + ACTION action_; +}; + +///////////////////////////////// +// STL-style Functor Templates // +///////////////////////////////// + +/** + * @class ACE_Hash + * + * @brief Function object for hashing + */ +template +class ACE_Hash +{ +public: + /// Simply calls t.hash () + unsigned long operator () (const TYPE &t) const; +}; + +/** + * @class ACE_Pointer_Hash + * + * @brief Function object for hashing pointers + */ +template +class ACE_Pointer_Hash +{ +public: + /// Simply returns t. + unsigned long operator () (TYPE t) const; +}; + +/** + * @class ACE_Equal_To + * + * @brief Function object for comparing two objects of + * the given type for equality. + */ +template +class ACE_Equal_To +{ +public: + /// Simply calls operator== + bool operator () (const TYPE &lhs, + const TYPE &rhs) const; +}; + +/** + * @class ACE_Less_Than + * + * @brief Function object for determining whether the first object of + * the given type is less than the second object of the same + * type. + */ +template +class ACE_Less_Than +{ +public: + /// Simply calls operator< + bool operator () (const TYPE &lhs, + const TYPE &rhs) const; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Functor_T.inl" +#endif /* __ACE_INLINE__ */ + + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Functor_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Functor_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_FUNCTOR_T_H */ diff --git a/dep/ACE_wrappers/ace/Functor_T.inl b/dep/ACE_wrappers/ace/Functor_T.inl new file mode 100644 index 000000000..35cfed5b7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Functor_T.inl @@ -0,0 +1,42 @@ +// -*- C++ -*- +// +// $Id: Functor_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE unsigned long +ACE_Hash::operator () (const TYPE &t) const +{ + return t.hash (); +} + +template ACE_INLINE unsigned long +ACE_Pointer_Hash::operator () (TYPE t) const +{ +#if defined (ACE_WIN64) + // The cast below is legit... we only want a hash, and need not convert + // the hash back to a pointer. +# pragma warning(push) +# pragma warning(disable : 4311) /* Truncate pointer to unsigned long */ +#endif /* ACE_WIN64 */ + return reinterpret_cast (t); +#if defined (ACE_WIN64) +# pragma warning(pop) +#endif /* ACE_WIN64 */ +} + +template ACE_INLINE bool +ACE_Equal_To::operator () (const TYPE &lhs, + const TYPE &rhs) const +{ + return lhs == rhs; +} + +template ACE_INLINE bool +ACE_Less_Than::operator () (const TYPE &lhs, + const TYPE &rhs) const +{ + return lhs < rhs; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Future.cpp b/dep/ACE_wrappers/ace/Future.cpp new file mode 100644 index 000000000..e3693bd29 --- /dev/null +++ b/dep/ACE_wrappers/ace/Future.cpp @@ -0,0 +1,436 @@ + // $Id: Future.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_FUTURE_CPP +#define ACE_FUTURE_CPP + +#include "ace/Future.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID (ace, Future, "$Id: Future.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_THREADS) + +# include "ace/Guard_T.h" +# include "ace/Recursive_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Future_Holder::ACE_Future_Holder (void) +{ +} + +template +ACE_Future_Holder::ACE_Future_Holder (const ACE_Future &item) + : item_ (item) +{ +} + +template +ACE_Future_Holder::~ACE_Future_Holder (void) +{ +} + +template +ACE_Future_Observer::ACE_Future_Observer (void) +{ +} + +template +ACE_Future_Observer::~ACE_Future_Observer (void) +{ +} + +// Dump the state of an object. + +template void +ACE_Future_Rep::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + "ref_count_ = %d\n", + (int) this->ref_count_)); + ACE_DEBUG ((LM_INFO,"value_: \n")); + if (this->value_) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NON-NULL)\n"))); + else + //FUZZ: disable check_for_NULL + ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NULL)\n"))); + //FUZZ: enable check_for_NULL + + ACE_DEBUG ((LM_INFO,"value_ready_: \n")); + this->value_ready_.dump (); + ACE_DEBUG ((LM_INFO,"value_ready_mutex_: \n")); + this->value_ready_mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_Future_Rep * +ACE_Future_Rep::internal_create (void) +{ + ACE_Future_Rep *temp = 0; + ACE_NEW_RETURN (temp, + ACE_Future_Rep (), + 0); + return temp; +} + +template ACE_Future_Rep * +ACE_Future_Rep::create (void) +{ + // Yes set ref count to zero. + ACE_Future_Rep *temp = internal_create (); +#if defined (ACE_NEW_THROWS_EXCEPTIONS) + if (temp == 0) + ACE_throw_bad_alloc; +#else + ACE_ASSERT (temp != 0); +#endif /* ACE_NEW_THROWS_EXCEPTIONS */ + return temp; + } + + +template ACE_Future_Rep * +ACE_Future_Rep::attach (ACE_Future_Rep*& rep) +{ + ACE_ASSERT (rep != 0); + // Use value_ready_mutex_ for both condition and ref count management + ACE_MT (ACE_Guard r_mon (rep->value_ready_mutex_)); + ++rep->ref_count_; + return rep; +} + +template void +ACE_Future_Rep::detach (ACE_Future_Rep*& rep) +{ + ACE_ASSERT (rep != 0); + // Use value_ready_mutex_ for both condition and ref count management + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, r_mon, rep->value_ready_mutex_)); + + if (rep->ref_count_-- == 0) + { + ACE_MT (r_mon.release ()); + // We do not need the lock when deleting the representation. + // There should be no side effects from deleting rep and we don + // not want to release a deleted mutex. + delete rep; + } +} + +template void +ACE_Future_Rep::assign (ACE_Future_Rep*& rep, ACE_Future_Rep* new_rep) +{ + ACE_ASSERT (rep != 0); + ACE_ASSERT (new_rep != 0); + // Use value_ready_mutex_ for both condition and ref count management + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, r_mon, rep->value_ready_mutex_)); + + ACE_Future_Rep* old = rep; + rep = new_rep; + + // detached old last for exception safety + if (old->ref_count_-- == 0) + { + ACE_MT (r_mon.release ()); + // We do not need the lock when deleting the representation. + // There should be no side effects from deleting rep and we don + // not want to release a deleted mutex. + delete old; + } +} + +template +ACE_Future_Rep::ACE_Future_Rep (void) + : value_ (0), + ref_count_ (0), + value_ready_ (value_ready_mutex_) +{ +} + +template +ACE_Future_Rep::~ACE_Future_Rep (void) +{ + delete this->value_; +} + +template int +ACE_Future_Rep::ready (void) const +{ + return this->value_ != 0; +} + +template int +ACE_Future_Rep::set (const T &r, + ACE_Future &caller) +{ + // If the value is already produced, ignore it... + if (this->value_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, + ace_mon, + this->value_ready_mutex_, + -1)); + // Otherwise, create a new result value. Note the use of the + // Double-checked locking pattern to avoid multiple allocations. + + if (this->value_ == 0) // Still no value, so proceed + { + ACE_NEW_RETURN (this->value_, + T (r), + -1); + + // Remove and notify all subscribed observers. + typename OBSERVER_COLLECTION::iterator iterator = + this->observer_collection_.begin (); + + typename OBSERVER_COLLECTION::iterator end = + this->observer_collection_.end (); + + while (iterator != end) + { + OBSERVER *observer = *iterator++; + observer->update (caller); + } + + // Signal all the waiting threads. + return this->value_ready_.broadcast (); + } + // Destructor releases the lock. + } + return 0; +} + +template int +ACE_Future_Rep::get (T &value, + ACE_Time_Value *tv) const +{ + // If the value is already produced, return it. + if (this->value_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + this->value_ready_mutex_, + -1)); + // If the value is not yet defined we must block until the + // producer writes to it. + + while (this->value_ == 0) + // Perform a timed wait. + if (this->value_ready_.wait (tv) == -1) + return -1; + + // Destructor releases the lock. + } + + value = *this->value_; + return 0; +} + +template int +ACE_Future_Rep::attach (ACE_Future_Observer *observer, + ACE_Future &caller) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); + + // Otherwise, create a new result value. Note the use of the + // Double-checked locking pattern to avoid corrupting the list. + + int result = 1; + + // If the value is already produced, then notify observer + if (this->value_ == 0) + result = this->observer_collection_.insert (observer); + else + observer->update (caller); + + return result; +} + +template int +ACE_Future_Rep::detach (ACE_Future_Observer *observer) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); + + // Remove all occurrences of the specified observer from this + // objects hash map. + return this->observer_collection_.remove (observer); +} + +template +ACE_Future_Rep::operator T () +{ + // If the value is already produced, return it. + if (this->value_ == 0) + { + // Constructor of ace_mon acquires the mutex. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0)); + + // If the value is not yet defined we must block until the + // producer writes to it. + + // Wait ``forever.'' + + while (this->value_ == 0) + if (this->value_ready_.wait () == -1) + // What to do in this case since we've got to indicate + // failure somehow? Exceptions would be nice, but they're + // not portable... + return 0; + + // Destructor releases the mutex + } + + return *this->value_; +} + +template +ACE_Future::ACE_Future (void) + : future_rep_ (FUTURE_REP::create ()) +{ +} + +template +ACE_Future::ACE_Future (const ACE_Future &r) + : future_rep_ (FUTURE_REP::attach (((ACE_Future &) r).future_rep_)) +{ +} + +template +ACE_Future::ACE_Future (const T &r) + : future_rep_ (FUTURE_REP::create ()) +{ + this->future_rep_->set (r, *this); +} + +template +ACE_Future::~ACE_Future (void) +{ + FUTURE_REP::detach (future_rep_); +} + +template bool +ACE_Future::operator== (const ACE_Future &r) const +{ + return r.future_rep_ == this->future_rep_; +} + +template bool +ACE_Future::operator!= (const ACE_Future &r) const +{ + return r.future_rep_ != this->future_rep_; +} + +template int +ACE_Future::cancel (const T &r) +{ + this->cancel (); + return this->future_rep_->set (r, + *this); +} + +template int +ACE_Future::cancel (void) +{ + // If this ACE_Future is already attached to a ACE_Future_Rep, + // detach it (maybe delete the ACE_Future_Rep). + FUTURE_REP::assign (this->future_rep_, + FUTURE_REP::create ()); + return 0; +} + +template int +ACE_Future::set (const T &r) +{ + // Give the pointer to the result to the ACE_Future_Rep. + return this->future_rep_->set (r, + *this); +} + +template int +ACE_Future::ready (void) const +{ + // We're ready if the ACE_Future_rep is ready... + return this->future_rep_->ready (); +} + +template int +ACE_Future::get (T &value, + ACE_Time_Value *tv) const +{ + // We return the ACE_Future_rep. + return this->future_rep_->get (value, tv); +} + +template int +ACE_Future::attach (ACE_Future_Observer *observer) +{ + return this->future_rep_->attach (observer, *this); +} + +template int +ACE_Future::detach (ACE_Future_Observer *observer) +{ + return this->future_rep_->detach (observer); +} + +template +ACE_Future::operator T () +{ + // note that this will fail (and COREDUMP!) + // if future_rep_ == 0 ! + // + // but... + // this is impossible unless somebody is so stupid to + // try something like this: + // + // Future futT; + // T t; + // t = futT; + + // perform type conversion on Future_Rep. + return *future_rep_; +} + +template void +ACE_Future::operator = (const ACE_Future &rhs) +{ + // assignment: + // + // bind to the same as . + + // This will work if &r == this, by first increasing the ref count + ACE_Future &r = (ACE_Future &) rhs; + FUTURE_REP::assign (this->future_rep_, + FUTURE_REP::attach (r.future_rep_)); +} + +template void +ACE_Future::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, + ACE_BEGIN_DUMP, this)); + + if (this->future_rep_) + this->future_rep_->dump (); + + ACE_DEBUG ((LM_DEBUG, + ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template ACE_Future_Rep * +ACE_Future::get_rep () +{ + return this->future_rep_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ + +#endif /* ACE_FUTURE_CPP */ diff --git a/dep/ACE_wrappers/ace/Future.h b/dep/ACE_wrappers/ace/Future.h new file mode 100644 index 000000000..e30159eaf --- /dev/null +++ b/dep/ACE_wrappers/ace/Future.h @@ -0,0 +1,387 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Future.h + * + * $Id: Future.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Andres Kruse + * @author Douglas C. Schmidt + * @author Per Andersson and + * @author John Tucker + */ +//============================================================================= + +#ifndef ACE_FUTURE_H +#define ACE_FUTURE_H + +#include /**/ "ace/pre.h" + +#include "ace/Unbounded_Set.h" +#include "ace/Strategies_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl. +template class ACE_Future_Holder; +template class ACE_Future_Observer; +template class ACE_Future_Rep; +template class ACE_Future; + +/** + * @class ACE_Future_Holder + * + * @brief Implementation of object that holds an ACE_Future. + */ +template +class ACE_Future_Holder +{ +public: + ACE_Future_Holder (const ACE_Future &future); + ~ACE_Future_Holder (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + ACE_Future item_; + +protected: + ACE_Future_Holder (void); +}; + +/** + * @class ACE_Future_Observer + * + * @brief ACE_Future_Observer + * + * An ACE_Future_Observer object implements an object that is + * subscribed with an ACE_Future object so that it may be notified + * when the value of the ACE_Future object is written to by a writer + * thread. It uses the Observer pattern. + */ +template +class ACE_Future_Observer +{ +public: + /// Destructor + virtual ~ACE_Future_Observer (void); + + /// Called by the ACE_Future in which we are subscribed to when + /// its value is written to. + virtual void update (const ACE_Future &future) = 0; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +protected: + + /// Constructor + ACE_Future_Observer (void); +}; + +/** + * @class ACE_Future_Rep + * + * @internal + * + * @brief ACE_Future_Rep + * + * An ACE_Future_Rep object encapsules a pointer to an object + * of class T which is the result of an asynchronous method + * invocation. It is pointed to by ACE_Future object[s] and + * only accessible through them. + */ +template +class ACE_Future_Rep +{ +private: + friend class ACE_Future; + + /** + * Set the result value. The specified represents the + * future that invoked this method, which is used to notify + * the list of future observers. Returns 0 for success, -1 on error. + * This function only has an effect the first time it is called for + * the object. Subsequent calls return 0 (success) but have no effect. + */ + int set (const T &r, + ACE_Future &caller); + + /// Wait up to @a tv time to get the @a value. Note that @a tv must be + /// specified in absolute time rather than relative time. + int get (T &value, + ACE_Time_Value *tv) const; + + /** + * Attaches the specified observer to a subject (i.e., the ACE_Future_Rep). + * The update method of the specified subject will be invoked with a copy of + * the written-to ACE_Future as input when the result gets set. + * + * Returns 0 if the observer is successfully attached, 1 if the + * observer is already attached, and -1 if failures occur. + */ + int attach (ACE_Future_Observer *observer, + ACE_Future &caller); + + /** + * Detaches the specified observer from a subject (i.e., the ACE_Future_Rep). + * The update method of the specified subject will not be invoked when the + * ACE_Future_Reps result gets set. Returns 1 if the specified observer was + * actually attached to the subject prior to this call and 0 if was not. + * + * Returns 0 if the observer was successfully detached, and -1 if the + * observer was not attached in the first place. + */ + int detach (ACE_Future_Observer *observer); + + /** + * Type conversion. will block forever until the result is + * available. Note that this method is going away in a subsequent + * release since it doesn't distinguish between failure results and + * success results (exceptions should be used, but they aren't + * portable...). The method should be used instead since it + * separates the error value from the result, and also permits + * timeouts. + */ + operator T (); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Encapsulate reference count and object lifetime of instances. + + // These methods must go after the others to work around a bug with + // Borland's C++ Builder... + + /// Allocate a new ACE_Future_Rep instance, returning NULL if it + /// cannot be created. + static ACE_Future_Rep *internal_create (void); + + /// Create a ACE_Future_Rep and initialize the reference count. + static ACE_Future_Rep *create (void); + + /** + * Increase the reference count and return argument. Uses the + * attribute "value_ready_mutex_" to synchronize reference count + * updating. + * + * Precondition (rep != 0). + */ + static ACE_Future_Rep *attach (ACE_Future_Rep *&rep); + + /** + * Decreases the reference count and deletes rep if there are no + * more references to rep. + * + * Precondition (rep != 0) + */ + static void detach (ACE_Future_Rep *&rep); + + /** + * Decreases the rep's reference count and deletes rep if there + * are no more references to rep. Then assigns new_rep to rep. + * + * Precondition (rep != 0 && new_rep != 0) + */ + static void assign (ACE_Future_Rep *&rep, ACE_Future_Rep *new_rep); + + /// Is result available? + int ready (void) const; + + /// Pointer to the result. + T *value_; + + /// Reference count. + int ref_count_; + + typedef ACE_Future_Observer OBSERVER; + + typedef ACE_Unbounded_Set OBSERVER_COLLECTION; + + /// Keep a list of ACE_Future_Observers unread by client's reader thread. + OBSERVER_COLLECTION observer_collection_; + + // = Condition variable and mutex that protect the . + mutable ACE_Recursive_Thread_Mutex value_ready_mutex_; + mutable ACE_Condition_Recursive_Thread_Mutex value_ready_; + +private: + + ACE_Future_Rep (void); + +protected: + + ~ACE_Future_Rep (void); + +}; + +/** + * @class ACE_Future + * + * @brief This class implements a ``single write, multiple read'' + * pattern that can be used to return results from asynchronous + * method invocations. + */ +template +class ACE_Future +{ +public: + // = Initialization and termination methods. + /// Constructor. + ACE_Future (void); + + /// Copy constructor binds @a this and @a r to the same + /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary. + ACE_Future (const ACE_Future &r); + + /// Constructor that initialises an ACE_Future to point to the + /// result @a r immediately. + ACE_Future (const T &r); + + /// Destructor. + ~ACE_Future (void); + + /// Assignment operator that binds @a this and @a r to the same + /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary. + void operator = (const ACE_Future &r); + + /// Cancel an ACE_Future and assign the value @a r. It is used if a + /// client does not want to wait for the value to be produced. + int cancel (const T &r); + + /** + * Cancel an ACE_Future. Put the future into its initial + * state. Returns 0 on succes and -1 on failure. It is now possible + * to reuse the ACE_Future. But remember, the ACE_Future + * is now bound to a new ACE_Future_Rep. + */ + int cancel (void); + + /** + * Equality operator that returns @c true if both ACE_Future objects + * point to the same ACE_Future_Rep object. + * + * @note It also returns @c true if both objects have just been + * instantiated and not used yet. + */ + bool operator == (const ACE_Future &r) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (const ACE_Future &r) const; + + /** + * Make the result available. Is used by the server thread to give + * the result to all waiting clients. Returns 0 for success, -1 on failure. + * This function only has an effect the first time it is called for + * the object (actually, the first time the underlying ACE_Future_Rep has a + * value assigned to it). Subsequent calls return 0 (success) but have no + * effect. + */ + int set (const T &r); + + /** + * Wait to get the object's value. + * + * @param value Receives the value of this ACE_Future when it is set. + * @param tv Pointer to an ACE_Time_Value containing the absolute + * time to wait until for the value to be set. If @a tv + * is 0, the call waits indefinitely for the value to be + * set, unless an error occurs. + * + * @retval 0 Success; @a value contains the value of the ACE_Future. + * @retval -1 Error; check ACE_OS::last_error() for an error code. + */ + int get (T &value, + ACE_Time_Value *tv = 0) const; + + /** + * @deprecated Note that this method is going away in a subsequent + * release since it doesn't distinguish between failure + * results and success results (exceptions should be + * used, but they aren't portable...). + * Type conversion, which obtains the result of the asynchronous + * method invocation. Will block forever. The get() method should be + * used instead since it separates the error value from the result, + * and also permits timeouts. + */ + operator T (); + + /// Check if the result is available. + int ready (void) const; + + /** + * Attaches the specified observer to a subject (this ACE_Future). + * The update method of the specified subject will be invoked with a copy of + * the associated ACE_Future as input when the result gets set. If the + * result is already set when this method gets invoked, then the update + * method of the specified subject will be invoked immediately. + * + * @param observer The observer to attach to the subject. + * + * @retval 0 Success. + * @retval 1 The observer was already attached. + * @retval -1 Error; check ACE_OS::last_error() for an error code. + */ + int attach (ACE_Future_Observer *observer); + + /** + * Detaches the specified observer from a subject (this ACE_Future). + * The update method of the specified subject will not be invoked when the + * ACE_Future_Rep result gets set. + * + * @param observer The observer to attach to the subject. + * + * @retval 0 The observer was successfully detached. + * @retval -1 Error, including the observer not attached prior + * to calling this method. + */ + int detach (ACE_Future_Observer *observer); + + /// Dump the state of an object. + void dump (void) const; + + /** + * Get the underlying ACE_Future_Rep pointer. Note that this method should + * rarely, if ever, be used and that modifying the underlying + * ACE_Future_Rep should be done with extreme caution. + */ + ACE_Future_Rep *get_rep (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + // the ACE_Future_Rep + /// Protect operations on the . + typedef ACE_Future_Rep FUTURE_REP; + FUTURE_REP *future_rep_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Future.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Future.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_FUTURE_H */ diff --git a/dep/ACE_wrappers/ace/Future_Set.cpp b/dep/ACE_wrappers/ace/Future_Set.cpp new file mode 100644 index 000000000..fceca83dd --- /dev/null +++ b/dep/ACE_wrappers/ace/Future_Set.cpp @@ -0,0 +1,136 @@ +// $Id: Future_Set.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_FUTURE_SET_CPP +#define ACE_FUTURE_SET_CPP + +#include "ace/Future_Set.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Future_Set::ACE_Future_Set (ACE_Message_Queue *new_queue) + : delete_queue_ (false) +{ + if (new_queue) + this->future_notification_queue_ = new_queue; + else + { + ACE_NEW (this->future_notification_queue_, + ACE_Message_Queue); + this->delete_queue_ = true; + } +} + +template +ACE_Future_Set::~ACE_Future_Set (void) +{ + // Detach ourselves from all remaining futures, if any, in our map. + typename FUTURE_HASH_MAP::iterator iterator = + this->future_map_.begin (); + + typename FUTURE_HASH_MAP::iterator end = + this->future_map_.end (); + + for (; + iterator != end; + ++iterator) + { + FUTURE_HOLDER *future_holder = (*iterator).int_id_; + future_holder->item_.detach (this); + delete future_holder; + } + + if (this->delete_queue_) + delete this->future_notification_queue_; +} + +template int +ACE_Future_Set::is_empty () const +{ + return (((ACE_Future_Set*)this)->future_map_.current_size () == 0 ); +} + +template int +ACE_Future_Set::insert (ACE_Future &future) +{ + FUTURE_HOLDER *future_holder; + ACE_NEW_RETURN (future_holder, + FUTURE_HOLDER (future), + -1); + + FUTURE_REP *future_rep = future.get_rep (); + int result = this->future_map_.bind (future_rep, + future_holder); + + // If a new map entry was created, then attach to the future, + // otherwise we were already attached to the future or some error + // occurred so just delete the future holder. + if ( result == 0 ) + // Attach ourself to the ACE_Futures list of observer + future.attach (this); + else + delete future_holder; + + return result; +} + +template void +ACE_Future_Set::update (const ACE_Future &future) +{ + ACE_Message_Block *mb; + FUTURE &local_future = const_cast &> (future); + + ACE_NEW (mb, + ACE_Message_Block ((char *) local_future.get_rep (), 0)); + + // Enqueue in priority order. + this->future_notification_queue_->enqueue (mb, 0); +} + +template int +ACE_Future_Set::next_readable (ACE_Future &future, + ACE_Time_Value *tv) +{ + if (this->is_empty ()) + return 0; + + ACE_Message_Block *mb = 0; + FUTURE_REP *future_rep = 0; + + // Wait for a "readable future" signal from the message queue. + if (this->future_notification_queue_->dequeue_head (mb, + tv) != -1) + { + // Extract future rep from the message block. + future_rep = reinterpret_cast (mb->base ()); + + // Delete the message block. + mb->release (); + } + else + return 0; + + // Remove the hash map entry with the specified future rep from our map. + FUTURE_HOLDER *future_holder; + if (this->future_map_.find (future_rep, + future_holder) != -1) + { + future = future_holder->item_; + this->future_map_.unbind (future_rep); + delete future_holder; + return 1; + } + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_FUTURE_SET_CPP */ diff --git a/dep/ACE_wrappers/ace/Future_Set.h b/dep/ACE_wrappers/ace/Future_Set.h new file mode 100644 index 000000000..a954d2997 --- /dev/null +++ b/dep/ACE_wrappers/ace/Future_Set.h @@ -0,0 +1,146 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Future_Set.h + * + * $Id: Future_Set.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author John Tucker + */ +//============================================================================= + +#ifndef ACE_FUTURE_SET_H +#define ACE_FUTURE_SET_H +#include /**/ "ace/pre.h" + +#include "ace/Thread.h" +#include "ace/Message_Queue.h" +#include "ace/Future.h" +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Null_Mutex.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Future_Set + * + * @brief This class implements a mechanism which allows the values of + * a collection of ACE_Future objects to be accessed by reader threads + * as they become available. The caller(s) provide the ACE_Future_Set + * (i.e. the observer...) with the collection of ACE_Future objects + * (i.e. the subjects...) that are to be observed using the + * the ACE_Future_Set::insert() method. The caller(s) may then iterate + * over the collection in the order in which they become readable using + * the ACE_Future_Set::next_readable() method. + */ +template +class ACE_Future_Set : public ACE_Future_Observer +{ +public: + // = Initialization and termination methods. + + /// Constructor. + ACE_Future_Set (ACE_Message_Queue *future_notification_queue_ = 0); + + /// Destructor. + ~ACE_Future_Set (void); + + /** + * Return 1 if their are no ACE_Future objects left on its queue and + * 0 otherwise. + * + * When an ACE_Future_Set has no ACE_Future>subjects to observe it is + * empty. The ACE_Future_Set is in the empty state when either the caller(s) + * have retrieved every readable ACE_Future subject assigned the + * ACE_Future_Set via the ACE_Future_Set::next_readable() method, + * or when the ACE_Future_Set has not been assigned any subjects. + */ + int is_empty (void) const; + + /** + * Enqueus the given ACE_Future into this objects queue when it is + * readable. + * + * Returns 0 if the future is successfully inserted, 1 if the + * future is already inserted, and -1 if failures occur. + */ + int insert (ACE_Future &future); + + /** + * Wait up to @a tv time to get the @a value. Note that @a tv must be + * specified in absolute time rather than relative time.); get the + * next ACE_Future that is readable. If @a tv = 0, the will block + * forever. + * + * If a readable future becomes available, then the input + * ACE_Future object param will be assigned with it and 1 will + * be returned. If the ACE_Future_Set is empty (i.e. see definition + * of ACE_Future_Set::is_empty()), then 0 is returned. + * + * When a readable ACE_Future object is retrieved via the + * ACE_Future_Set::next_readable() method, the ACE_Future_Set will + * remove that ACE_Future object from its list of subjects. + */ + int next_readable (ACE_Future &result, + ACE_Time_Value *tv = 0); + + /// Called by the ACE_Future subject in which we are subscribed to + /// when its value is written to. + virtual void update (const ACE_Future &future); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + // = Disallow these operations. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Future_Set &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Future_Set (const ACE_Future_Set &)) + + typedef ACE_Future FUTURE; + + typedef ACE_Future_Rep FUTURE_REP; + + typedef ACE_Future_Holder FUTURE_HOLDER; + + typedef ACE_Pointer_Hash FUTURE_REP_HASH; + + typedef ACE_Equal_To FUTURE_REP_COMPARE; + + typedef ACE_Hash_Map_Manager_Ex FUTURE_HASH_MAP; + + /// Map of , subjects, which have not been written to by + /// client's writer thread. + FUTURE_HASH_MAP future_map_; + + /// Message queue for notifying the reader thread of which + /// have been written to by client's writer thread. + ACE_Message_Queue *future_notification_queue_; + + /// Keeps track of whether we need to delete the message queue. + bool delete_queue_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Future_Set.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Future_Set.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_THREADS */ +#include /**/ "ace/post.h" +#endif /* ACE_FUTURE_SET_H */ diff --git a/dep/ACE_wrappers/ace/GNUmakefile b/dep/ACE_wrappers/ace/GNUmakefile new file mode 100644 index 000000000..138ff5e47 --- /dev/null +++ b/dep/ACE_wrappers/ace/GNUmakefile @@ -0,0 +1,83 @@ +# -*- makefile -*- +#---------------------------------------------------------------------------- +# GNU ACE Workspace +# +# $Id: GNUACEWorkspaceCreator.pm 80826 2008-03-04 14:51:23Z wotte $ +# +# This file was generated by MPC. Any changes made directly to +# this file will be lost the next time it is generated. +# +# MPC Command: +# /export/anduriltmp/bczar/DOC_ROOT/stage-10168/ACE_wrappers/bin/mwc.pl -type gnuace -exclude "TAO/TAO_*.mwc,TAO/CIAO/CIAO_*.mwc" -recurse -hierarchy -relative ACE_ROOT=/export/anduriltmp/bczar/DOC_ROOT/stage-10168/ACE_wrappers -relative TAO_ROOT=/export/anduriltmp/bczar/DOC_ROOT/stage-10168/ACE_wrappers/TAO -relative CIAO_ROOT=/export/anduriltmp/bczar/DOC_ROOT/stage-10168/ACE_wrappers/TAO/CIAO +# +#---------------------------------------------------------------------------- + +MAKEFILE = GNUmakefile + +ifeq ($(findstring k,$(MAKEFLAGS)),k) + KEEP_GOING = - +endif + +include $(ACE_ROOT)/include/makeinclude/macros.GNU + +all: ACE ACE_FlReactor ACE_Qt3Reactor ACE_TkReactor ACE_XtReactor ACE_ETCL ACE_ETCL_Parser Monitor_Control-target SSL-target + +REMAINING_TARGETS := $(subst all, , $(TARGETS_NESTED:.nested=)) $(CUSTOM_TARGETS) + +$(REMAINING_TARGETS): + @$(MAKE) -f GNUmakefile.ACE $(@) + @$(MAKE) -f GNUmakefile.ACE_FlReactor $(@) + @$(MAKE) -f GNUmakefile.ACE_Qt3Reactor $(@) + @$(MAKE) -f GNUmakefile.ACE_TkReactor $(@) + @$(MAKE) -f GNUmakefile.ACE_XtReactor $(@) + @cd ETCL && $(MAKE) -f GNUmakefile.ACE_ETCL $(@) + @cd ETCL && $(MAKE) -f GNUmakefile.ACE_ETCL_Parser $(@) + @cd Monitor_Control && $(MAKE) -f GNUmakefile.Monitor_Control $(@) + @cd SSL && $(MAKE) -f GNUmakefile.SSL $(@) + +.PHONY: ACE +ACE: + @$(MAKE) -f GNUmakefile.ACE all + +.PHONY: ACE_FlReactor +ACE_FlReactor: ACE + @$(MAKE) -f GNUmakefile.ACE_FlReactor all + +.PHONY: ACE_Qt3Reactor +ACE_Qt3Reactor: ACE + @$(MAKE) -f GNUmakefile.ACE_Qt3Reactor all + +.PHONY: ACE_TkReactor +ACE_TkReactor: ACE + @$(MAKE) -f GNUmakefile.ACE_TkReactor all + +.PHONY: ACE_XtReactor +ACE_XtReactor: ACE + @$(MAKE) -f GNUmakefile.ACE_XtReactor all + +.PHONY: ACE_ETCL +ACE_ETCL: ACE + @cd ETCL && $(MAKE) -f GNUmakefile.ACE_ETCL all + +.PHONY: ACE_ETCL_Parser +ACE_ETCL_Parser: ACE ACE_ETCL + @cd ETCL && $(MAKE) -f GNUmakefile.ACE_ETCL_Parser all + +.PHONY: Monitor_Control-target +Monitor_Control-target: ACE ACE_ETCL ACE_ETCL_Parser + @cd Monitor_Control && $(MAKE) -f GNUmakefile.Monitor_Control all + +.PHONY: SSL-target +SSL-target: ACE + @cd SSL && $(MAKE) -f GNUmakefile.SSL all + +project_name_list: + @echo ACE_ETCL + @echo ACE_ETCL_Parser + @echo ACE + @echo ACE_FlReactor + @echo ACE_Qt3Reactor + @echo ACE_TkReactor + @echo ACE_XtReactor + @echo Monitor_Control-target + @echo SSL-target diff --git a/dep/ACE_wrappers/ace/GNUmakefile.ACE b/dep/ACE_wrappers/ace/GNUmakefile.ACE new file mode 100644 index 000000000..b559137be --- /dev/null +++ b/dep/ACE_wrappers/ace/GNUmakefile.ACE @@ -0,0 +1,485 @@ +# -*- Makefile -*- +#---------------------------------------------------------------------------- +# GNU Makefile +# +# @file GNUmakefile.ACE +# +# $Id: gnu.mpd 82648 2008-08-21 06:55:54Z johnnyw $ +# +# This file was automatically generated by MPC. Any changes made directly to +# this file will be lost the next time it is generated. +# +#---------------------------------------------------------------------------- +MAKEFILE = GNUmakefile.ACE +DEPENDENCY_FILE = .depend.ACE + +## LIB may be set to empty later on in this file +LIB_UNCHECKED = libACE.a +LIB = $(LIB_UNCHECKED) +LIB_NAME = libACE + +## SHLIB may be set to empty later on in this file +SHLIB_UNCHECKED = libACE.$(SOEXT) +SHLIB = $(SHLIB_UNCHECKED) + +FILES = \ + Local_Name_Space.cpp \ + Name_Proxy.cpp \ + Name_Request_Reply.cpp \ + Name_Space.cpp \ + Naming_Context.cpp \ + Registry_Name_Space.cpp \ + Remote_Name_Space.cpp \ + NT_Service.cpp \ + Codecs.cpp \ + Local_Tokens.cpp \ + Remote_Tokens.cpp \ + Token_Collection.cpp \ + Token_Invariants.cpp \ + Token_Manager.cpp \ + Token_Request_Reply.cpp \ + DLL.cpp \ + Dynamic_Service_Base.cpp \ + Dynamic_Service_Dependency.cpp \ + Parse_Node.cpp \ + Service_Config.cpp \ + Service_Gestalt.cpp \ + Service_Manager.cpp \ + Service_Object.cpp \ + Service_Repository.cpp \ + Service_Types.cpp \ + Shared_Object.cpp \ + Svc_Conf_Lexer.cpp \ + Svc_Conf_y.cpp \ + Encoding_Converter.cpp \ + Encoding_Converter_Factory.cpp \ + UTF8_Encoding_Converter.cpp \ + UTF16_Encoding_Converter.cpp \ + UTF32_Encoding_Converter.cpp \ + XML_Svc_Conf.cpp \ + UUID.cpp \ + Filecache.cpp \ + ACE.cpp \ + ACE_crc_ccitt.cpp \ + ACE_crc32.cpp \ + ace_wchar.cpp \ + Activation_Queue.cpp \ + Active_Map_Manager.cpp \ + Addr.cpp \ + Argv_Type_Converter.cpp \ + Assert.cpp \ + Asynch_IO.cpp \ + Asynch_IO_Impl.cpp \ + Asynch_Pseudo_Task.cpp \ + ATM_Acceptor.cpp \ + ATM_Addr.cpp \ + ATM_Connector.cpp \ + ATM_Params.cpp \ + ATM_QoS.cpp \ + ATM_Stream.cpp \ + Atomic_Op.cpp \ + Atomic_Op_Sparc.c \ + Auto_Event.cpp \ + Barrier.cpp \ + Base_Thread_Adapter.cpp \ + Based_Pointer_Repository.cpp \ + Basic_Stats.cpp \ + Basic_Types.cpp \ + Capabilities.cpp \ + CDR_Base.cpp \ + CDR_Stream.cpp \ + CDR_Size.cpp \ + Cleanup.cpp \ + Codeset_IBM1047.cpp \ + Codeset_Registry.cpp \ + Codeset_Registry_db.cpp \ + Condition_Recursive_Thread_Mutex.cpp \ + Condition_Thread_Mutex.cpp \ + Configuration.cpp \ + Configuration_Import_Export.cpp \ + Connection_Recycling_Strategy.cpp \ + Containers.cpp \ + Copy_Disabled.cpp \ + Countdown_Time.cpp \ + Date_Time.cpp \ + DEV.cpp \ + DEV_Addr.cpp \ + DEV_Connector.cpp \ + DEV_IO.cpp \ + DLL_Manager.cpp \ + Dev_Poll_Reactor.cpp \ + Dirent.cpp \ + Dirent_Selector.cpp \ + Dump.cpp \ + Dynamic.cpp \ + Dynamic_Message_Strategy.cpp \ + Event.cpp \ + Event_Handler.cpp \ + FIFO.cpp \ + FIFO_Recv.cpp \ + FIFO_Recv_Msg.cpp \ + FIFO_Send.cpp \ + FIFO_Send_Msg.cpp \ + FILE.cpp \ + FILE_Addr.cpp \ + FILE_Connector.cpp \ + FILE_IO.cpp \ + File_Lock.cpp \ + Flag_Manip.cpp \ + Framework_Component.cpp \ + Functor.cpp \ + Functor_String.cpp \ + Get_Opt.cpp \ + gethrtime.cpp \ + Handle_Ops.cpp \ + Handle_Set.cpp \ + Hashable.cpp \ + High_Res_Timer.cpp \ + ICMP_Socket.cpp \ + INET_Addr.cpp \ + Init_ACE.cpp \ + IO_SAP.cpp \ + IO_Cntl_Msg.cpp \ + IOStream.cpp \ + IPC_SAP.cpp \ + Lib_Find.cpp \ + Local_Memory_Pool.cpp \ + Lock.cpp \ + Log_Msg.cpp \ + Log_Msg_Backend.cpp \ + Log_Msg_Callback.cpp \ + Log_Msg_IPC.cpp \ + Log_Msg_NT_Event_Log.cpp \ + Log_Msg_UNIX_Syslog.cpp \ + Log_Record.cpp \ + Logging_Strategy.cpp \ + LSOCK.cpp \ + LSOCK_Acceptor.cpp \ + LSOCK_CODgram.cpp \ + LSOCK_Connector.cpp \ + LSOCK_Dgram.cpp \ + LSOCK_Stream.cpp \ + Malloc.cpp \ + Malloc_Allocator.cpp \ + Manual_Event.cpp \ + MEM_Acceptor.cpp \ + MEM_Addr.cpp \ + MEM_Connector.cpp \ + MEM_IO.cpp \ + Mem_Map.cpp \ + MEM_SAP.cpp \ + MEM_Stream.cpp \ + Message_Block.cpp \ + Message_Queue.cpp \ + Message_Queue_NT.cpp \ + Message_Queue_Vx.cpp \ + Method_Request.cpp \ + MMAP_Memory_Pool.cpp \ + Msg_WFMO_Reactor.cpp \ + Monitor_Admin.cpp \ + Monitor_Admin_Manager.cpp \ + Monitor_Base.cpp \ + Monitor_Point_Registry.cpp \ + Monitor_Size.cpp \ + Monitor_Control_Types.cpp \ + Monitor_Control_Action.cpp \ + Multihomed_INET_Addr.cpp \ + Mutex.cpp \ + Netlink_Addr.cpp \ + Notification_Strategy.cpp \ + Notification_Queue.cpp \ + Obchunk.cpp \ + Object_Manager.cpp \ + Object_Manager_Base.cpp \ + OS_Errno.cpp \ + OS_Log_Msg_Attributes.cpp \ + OS_main.cpp \ + OS_NS_arpa_inet.cpp \ + OS_NS_ctype.cpp \ + OS_NS_dirent.cpp \ + OS_NS_dlfcn.cpp \ + OS_NS_errno.cpp \ + OS_NS_fcntl.cpp \ + OS_NS_math.cpp \ + OS_NS_netdb.cpp \ + OS_NS_poll.cpp \ + OS_NS_pwd.cpp \ + OS_NS_regex.cpp \ + OS_NS_signal.cpp \ + OS_NS_stdio.cpp \ + OS_NS_stdlib.cpp \ + OS_NS_string.cpp \ + OS_NS_strings.cpp \ + OS_NS_stropts.cpp \ + OS_NS_sys_mman.cpp \ + OS_NS_sys_msg.cpp \ + OS_NS_sys_resource.cpp \ + OS_NS_sys_select.cpp \ + OS_NS_sys_sendfile.cpp \ + OS_NS_sys_shm.cpp \ + OS_NS_sys_socket.cpp \ + OS_NS_sys_stat.cpp \ + OS_NS_sys_time.cpp \ + OS_NS_sys_uio.cpp \ + OS_NS_sys_utsname.cpp \ + OS_NS_sys_wait.cpp \ + OS_NS_Thread.cpp \ + OS_NS_time.cpp \ + OS_NS_unistd.cpp \ + OS_NS_wchar.cpp \ + OS_QoS.cpp \ + OS_Thread_Adapter.cpp \ + OS_TLI.cpp \ + Pagefile_Memory_Pool.cpp \ + PI_Malloc.cpp \ + Ping_Socket.cpp \ + Pipe.cpp \ + POSIX_Asynch_IO.cpp \ + POSIX_CB_Proactor.cpp \ + POSIX_Proactor.cpp \ + Priority_Reactor.cpp \ + Proactor.cpp \ + Proactor_Impl.cpp \ + Process.cpp \ + Process_Manager.cpp \ + Process_Mutex.cpp \ + Process_Semaphore.cpp \ + Profile_Timer.cpp \ + Reactor.cpp \ + Reactor_Impl.cpp \ + Reactor_Notification_Strategy.cpp \ + Reactor_Timer_Interface.cpp \ + Read_Buffer.cpp \ + Recursive_Thread_Mutex.cpp \ + Recyclable.cpp \ + Registry.cpp \ + Rtems_init.c \ + RW_Mutex.cpp \ + RW_Process_Mutex.cpp \ + RW_Thread_Mutex.cpp \ + Sample_History.cpp \ + Sbrk_Memory_Pool.cpp \ + Sched_Params.cpp \ + Select_Reactor_Base.cpp \ + Semaphore.cpp \ + Shared_Memory.cpp \ + Shared_Memory_MM.cpp \ + Shared_Memory_Pool.cpp \ + Shared_Memory_SV.cpp \ + Sig_Adapter.cpp \ + Sig_Handler.cpp \ + Signal.cpp \ + SOCK.cpp \ + SOCK_Acceptor.cpp \ + SOCK_CODgram.cpp \ + Sock_Connect.cpp \ + SOCK_Connector.cpp \ + SOCK_Dgram.cpp \ + SOCK_Dgram_Bcast.cpp \ + SOCK_Dgram_Mcast.cpp \ + SOCK_IO.cpp \ + SOCK_Netlink.cpp \ + SOCK_SEQPACK_Acceptor.cpp \ + SOCK_SEQPACK_Association.cpp \ + SOCK_SEQPACK_Connector.cpp \ + SOCK_Stream.cpp \ + SPIPE.cpp \ + SPIPE_Acceptor.cpp \ + SPIPE_Addr.cpp \ + SPIPE_Connector.cpp \ + SPIPE_Stream.cpp \ + SString.cpp \ + Stack_Trace.cpp \ + Stats.cpp \ + String_Base_Const.cpp \ + SUN_Proactor.cpp \ + SV_Message.cpp \ + SV_Message_Queue.cpp \ + SV_Semaphore_Complex.cpp \ + SV_Semaphore_Simple.cpp \ + SV_Shared_Memory.cpp \ + Synch_Options.cpp \ + System_Time.cpp \ + Task.cpp \ + Thread.cpp \ + Thread_Adapter.cpp \ + Thread_Control.cpp \ + Thread_Exit.cpp \ + Thread_Hook.cpp \ + Thread_Manager.cpp \ + Thread_Mutex.cpp \ + Thread_Semaphore.cpp \ + Throughput_Stats.cpp \ + Time_Value.cpp \ + Timeprobe.cpp \ + TLI.cpp \ + TLI_Acceptor.cpp \ + TLI_Connector.cpp \ + TLI_Stream.cpp \ + Token.cpp \ + TP_Reactor.cpp \ + Trace.cpp \ + TSS_Adapter.cpp \ + TTY_IO.cpp \ + UNIX_Addr.cpp \ + UPIPE_Acceptor.cpp \ + UPIPE_Connector.cpp \ + UPIPE_Stream.cpp \ + WFMO_Reactor.cpp \ + WIN32_Asynch_IO.cpp \ + WIN32_Proactor.cpp \ + XTI_ATM_Mcast.cpp + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- +ACE_SHLIBS = + +PRJ_TYPE = library + +INSLIB ?= ../lib +ifeq ($(INSLIB),.) + ifeq ($(PWD),) + PWD=$(shell pwd) + endif + INSLIB = $(PWD) +endif +OUTPUT_DIRECTORY = $(INSLIB) + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU + +ifneq (,$(RC)) +RESOURCES += \ + ace.rc + +RCFLAGS = \ + --include-dir=.. +endif + +# To build multiple targets in the same directory on AIX, it works +# best to have a template directory per project. +# The compiler/linker isn't too smart about instantiating templates... +ifdef TEMPINCDIR +TEMPINCDIR := $(TEMPINCDIR)/ACE +all: $(TEMPINCDIR) +endif + +ifneq ($(OUTPUT_DIRECTORY),) +all: $(OUTPUT_DIRECTORY) +$(OUTPUT_DIRECTORY): + -@$(MKDIR) "$(OUTPUT_DIRECTORY)" +endif + +LIBCHECK = 1 +ifneq ($(ace_for_tao),1) +ifneq ($(LIBCHECK), 1) + LIB = + SHLIB = + all: lib_warning +endif +else + LIB = + SHLIB = + all: avoid_warning +endif + +ifneq ($(ace_for_tao),1) +else + LIB = + SHLIB = + all: avoid_warning +endif +LSRC = $(FILES) + +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU +ifeq ($(VXWORKSLINK),1) +include $(TGT_DIR)/h/make/rules.$(PRJ_TYPE) +endif + +ifeq ($(VXWORKSLINK),1) +LDLIBPATH = -L. -L../lib +else +LDFLAGS += -L. -L../lib +endif +CPPFLAGS += -I.. +ifeq ($(shared_libs),1) + ifneq ($(SHLIB),) + CPPFLAGS += -DACE_BUILD_DLL + endif +endif +ifeq ($(static_libs),1) + CPPFLAGS += -DACE_AS_STATIC_LIBS +endif + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- +Svc_Conf_y.cpp: Svc_Conf.y +ifeq ($(notdir $(YACC)), bison) + $(YACC) -l -d Svc_Conf.y + sed -e 's/fprintf/ACE_OS::fprintf/g' \ + -e 's/\t/ /g' \ + -e 's/yy/ace_yy/g' \ + -e 's/->ace_yyerrno/->yyerrno/g' \ + -e 's/->ace_yylineno/->yylineno/g' \ + -e 's/ NULL/ 0/g' \ + -e 's/ace_yyerror[ ]*([ ]*"/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "/g' \ + -e 's/ace_yyerror[ ]*([ ]*ace_yymsg/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, ace_yymsg/g' \ + -e 's/ace_yyerror[ ]*([ ]*YY_/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, YY_/g' \ + -e 's@#include @@' \ + -e 's/Svc_Conf\.tab\.c/Svc_Conf_y.cpp/g' $@ + $(RM) -f Svc_Conf.tab.c Svc_Conf_y.cpp.orig +else + @echo 'ERROR: You must use bison 1.35 or higher to process this file' + @/bin/false +endif + +Svc_Conf_Token_Table.h: Svc_Conf.y Svc_Conf_y.cpp +ifeq ($(notdir $(YACC)), bison) + mv Svc_Conf.tab.h Svc_Conf_Token_Table.h +else + @echo 'ERROR: You must use bison 1.35 or higher to process this file' + @/bin/false +endif + +lib_warning: + @echo ACE will not be built due to the following missing library: + @echo $(LIBCHECK) + +avoid_warning: + @echo ACE will not be built due to one of the following enabled make macros: + @echo ace_for_tao + +## Some OS's have /bin/test others only have /usr/bin/test +ifeq ($(wildcard /bin/test), /bin/test) + TEST_EXE = /bin/test +else +ifeq ($(wildcard /usr/bin/test), /usr/bin/test) + TEST_EXE = /usr/bin/test +endif +endif + +ifneq ($(GENERATED_DIRTY),) +.PRECIOUS: $(GENERATED_DIRTY) +## If the generated files are anything but source files, we need to +## ensure that those files are generated before we attempt to build anything +## else. +ifeq ($(OBJS_DEPEND_ON_GENERATED),1) +$(VDIR)$(ACE_PCH_FILE) $(addprefix $(VDIR), $(OBJS)): $(GENERATED_DIRTY) +$(VSHDIR)$(ACE_PCH_FILE) $(VSHOBJS): $(GENERATED_DIRTY) +endif +endif + + +realclean: clean +ifneq ($(GENERATED_DIRTY),) + -$(RM) -r $(GENERATED_DIRTY) +endif + +__prebuild__: + @-: + diff --git a/dep/ACE_wrappers/ace/GNUmakefile.ACE_FlReactor b/dep/ACE_wrappers/ace/GNUmakefile.ACE_FlReactor new file mode 100644 index 000000000..2a9d9908c --- /dev/null +++ b/dep/ACE_wrappers/ace/GNUmakefile.ACE_FlReactor @@ -0,0 +1,189 @@ +# -*- Makefile -*- +#---------------------------------------------------------------------------- +# GNU Makefile +# +# @file GNUmakefile.ACE_FlReactor +# +# $Id: gnu.mpd 82648 2008-08-21 06:55:54Z johnnyw $ +# +# This file was automatically generated by MPC. Any changes made directly to +# this file will be lost the next time it is generated. +# +#---------------------------------------------------------------------------- +MAKEFILE = GNUmakefile.ACE_FlReactor +DEPENDENCY_FILE = .depend.ACE_FlReactor + +## LIB may be set to empty later on in this file +LIB_UNCHECKED = libACE_FlReactor.a +LIB = $(LIB_UNCHECKED) +LIB_NAME = libACE_FlReactor + +## SHLIB may be set to empty later on in this file +SHLIB_UNCHECKED = libACE_FlReactor.$(SOEXT) +SHLIB = $(SHLIB_UNCHECKED) + +FILES = \ + FlReactor/FlReactor.cpp + +VPATH = .:FlReactor + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- +ACE_SHLIBS = -lACE + +PRJ_TYPE = library + +INSLIB ?= ../lib +ifeq ($(INSLIB),.) + ifeq ($(PWD),) + PWD=$(shell pwd) + endif + INSLIB = $(PWD) +endif +OUTPUT_DIRECTORY = $(INSLIB) + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU + +# To build multiple targets in the same directory on AIX, it works +# best to have a template directory per project. +# The compiler/linker isn't too smart about instantiating templates... +ifdef TEMPINCDIR +TEMPINCDIR := $(TEMPINCDIR)/ACE_FlReactor +all: $(TEMPINCDIR) +endif + +ifneq ($(OUTPUT_DIRECTORY),) +all: $(OUTPUT_DIRECTORY) +$(OUTPUT_DIRECTORY): + -@$(MKDIR) "$(OUTPUT_DIRECTORY)" +endif + +# turn off libcheck if doing a dry run +ifeq ($(findstring n, $(MAKEFLAGS)),n) + LIBCHECK = 1 +else + # turn off libcheck if keep going was passed too + ifeq ($(findstring k, $(MAKEFLAGS)),k) + LIBCHECK = 1 + else + LIBCHECK ?= $(filter-out $(foreach lib,ACE,$(findstring $(lib),$(foreach libpath,. ../lib /usr/lib /usr/lib64 $(INSLIB),$(wildcard $(libpath)/lib$(lib).* $(libpath)/$(lib).lib)))),ACE) + ifeq ($(LIBCHECK),) + LIBCHECK = 1 + endif + endif +endif +ifeq ($(x11),1) +ifeq ($(gl),1) +ifeq ($(fl),1) +ifneq ($(LIBCHECK), 1) + LIB = + SHLIB = + all: lib_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif + +ifeq ($(x11),1) +ifeq ($(gl),1) +ifeq ($(fl),1) +else + LIB = + SHLIB = + all: require_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif +LSRC = $(FILES) + +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU +ifeq ($(VXWORKSLINK),1) +include $(TGT_DIR)/h/make/rules.$(PRJ_TYPE) +endif + +ifeq ($(VXWORKSLINK),1) +LDLIBPATH = -L. -L../lib +else +LDFLAGS += -L. -L../lib +endif +CPPFLAGS += -I.. +ifeq ($(shared_libs),1) + ifneq ($(SHLIB),) + CPPFLAGS += -DACE_FLREACTOR_BUILD_DLL + endif +endif +ifeq ($(static_libs),1) + CPPFLAGS += -DACE_AS_STATIC_LIBS +endif + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- +CPPFLAGS += $(PLATFORM_FL_CPPFLAGS) +CPPFLAGS += $(PLATFORM_GL_CPPFLAGS) $(PLATFORM_X11_CPPFLAGS) +LIBS += $(PLATFORM_FL_LIBS) $(PLATFORM_GL_LIBS) $(PLATFORM_X11_LIBS) +LDFLAGS += $(PLATFORM_FL_LDFLAGS) $(PLATFORM_GL_LDFLAGS) +LDFLAGS += $(PLATFORM_GL_LDFLAGS) + +lib_warning: + @echo ACE_FlReactor will not be built due to the following missing library: + @echo $(LIBCHECK) + +require_warning: + @echo ACE_FlReactor will not be built due to one of the following disabled make macros: + @echo x11 gl fl + +## Some OS's have /bin/test others only have /usr/bin/test +ifeq ($(wildcard /bin/test), /bin/test) + TEST_EXE = /bin/test +else +ifeq ($(wildcard /usr/bin/test), /usr/bin/test) + TEST_EXE = /usr/bin/test +endif +endif + +ifneq ($(GENERATED_DIRTY),) +.PRECIOUS: $(GENERATED_DIRTY) +## If the generated files are anything but source files, we need to +## ensure that those files are generated before we attempt to build anything +## else. +ifeq ($(OBJS_DEPEND_ON_GENERATED),1) +$(VDIR)$(ACE_PCH_FILE) $(addprefix $(VDIR), $(OBJS)): $(GENERATED_DIRTY) +$(VSHDIR)$(ACE_PCH_FILE) $(VSHOBJS): $(GENERATED_DIRTY) +endif +endif + + +realclean: clean +ifneq ($(GENERATED_DIRTY),) + -$(RM) -r $(GENERATED_DIRTY) +endif + +__prebuild__: + @-: + diff --git a/dep/ACE_wrappers/ace/GNUmakefile.ACE_Qt3Reactor b/dep/ACE_wrappers/ace/GNUmakefile.ACE_Qt3Reactor new file mode 100644 index 000000000..ea7f38d17 --- /dev/null +++ b/dep/ACE_wrappers/ace/GNUmakefile.ACE_Qt3Reactor @@ -0,0 +1,169 @@ +# -*- Makefile -*- +#---------------------------------------------------------------------------- +# GNU Makefile +# +# @file GNUmakefile.ACE_Qt3Reactor +# +# $Id: gnu.mpd 82648 2008-08-21 06:55:54Z johnnyw $ +# +# This file was automatically generated by MPC. Any changes made directly to +# this file will be lost the next time it is generated. +# +#---------------------------------------------------------------------------- +MAKEFILE = GNUmakefile.ACE_Qt3Reactor +DEPENDENCY_FILE = .depend.ACE_Qt3Reactor + +## LIB may be set to empty later on in this file +LIB_UNCHECKED = libACE_QtReactor.a +LIB = $(LIB_UNCHECKED) +LIB_NAME = libACE_QtReactor + +## SHLIB may be set to empty later on in this file +SHLIB_UNCHECKED = libACE_QtReactor.$(SOEXT) +SHLIB = $(SHLIB_UNCHECKED) + +FILES = \ + QtReactor/QtReactor_moc.cpp \ + QtReactor/QtReactor.cpp + +VPATH = .:QtReactor + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- +ACE_SHLIBS = -lACE -lqt-mt$(QT_VERSION) + +PRJ_TYPE = library + +INSLIB ?= ../lib +ifeq ($(INSLIB),.) + ifeq ($(PWD),) + PWD=$(shell pwd) + endif + INSLIB = $(PWD) +endif +OUTPUT_DIRECTORY = $(INSLIB) + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU + +# To build multiple targets in the same directory on AIX, it works +# best to have a template directory per project. +# The compiler/linker isn't too smart about instantiating templates... +ifdef TEMPINCDIR +TEMPINCDIR := $(TEMPINCDIR)/ACE_Qt3Reactor +all: $(TEMPINCDIR) +endif + +ifneq ($(OUTPUT_DIRECTORY),) +all: $(OUTPUT_DIRECTORY) +$(OUTPUT_DIRECTORY): + -@$(MKDIR) "$(OUTPUT_DIRECTORY)" +endif + +# turn off libcheck if doing a dry run +ifeq ($(findstring n, $(MAKEFLAGS)),n) + LIBCHECK = 1 +else + # turn off libcheck if keep going was passed too + ifeq ($(findstring k, $(MAKEFLAGS)),k) + LIBCHECK = 1 + else + LIBCHECK ?= $(filter-out $(foreach lib,ACE,$(findstring $(lib),$(foreach libpath,. ../lib $(QTDIR)/lib /usr/lib /usr/lib64 $(INSLIB),$(wildcard $(libpath)/lib$(lib).* $(libpath)/$(lib).lib)))),ACE) + ifeq ($(LIBCHECK),) + LIBCHECK = 1 + endif + endif +endif +ifeq ($(qt),1) +ifneq ($(LIBCHECK), 1) + LIB = + SHLIB = + all: lib_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif + +ifeq ($(qt),1) +else + LIB = + SHLIB = + all: require_warning +endif +LSRC = $(FILES) + +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU +ifeq ($(VXWORKSLINK),1) +include $(TGT_DIR)/h/make/rules.$(PRJ_TYPE) +endif + +ifeq ($(VXWORKSLINK),1) +LDLIBPATH = -L. -L../lib -L$(QTDIR)/lib +else +LDFLAGS += -L. -L../lib -L$(QTDIR)/lib +endif +CPPFLAGS += -I.. -I$(QTDIR)/include +CPPFLAGS += -DQT_THREAD_SUPPORT +ifeq ($(shared_libs),1) + ifneq ($(SHLIB),) + CPPFLAGS += -DACE_QTREACTOR_BUILD_DLL + endif +endif +ifeq ($(static_libs),1) + CPPFLAGS += -DACE_AS_STATIC_LIBS +endif + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- +CPPFLAGS += $(PLATFORM_QT_CPPFLAGS) +LIBS += $(PLATFORM_QT_LIBS) +LDFLAGS += $(PLATFORM_QT_LDFLAGS) + +lib_warning: + @echo ACE_Qt3Reactor will not be built due to the following missing library: + @echo $(LIBCHECK) + +require_warning: + @echo ACE_Qt3Reactor will not be built due to one of the following disabled make macros: + @echo qt + +## Some OS's have /bin/test others only have /usr/bin/test +ifeq ($(wildcard /bin/test), /bin/test) + TEST_EXE = /bin/test +else +ifeq ($(wildcard /usr/bin/test), /usr/bin/test) + TEST_EXE = /usr/bin/test +endif +endif + +GENERATED_DIRTY += QtReactor/QtReactor_moc.cpp +QtReactor/QtReactor_moc.cpp: QtReactor/QtReactor.h + $(QTDIR)/bin/moc QtReactor/QtReactor.h -o $@ + +ifneq ($(GENERATED_DIRTY),) +.PRECIOUS: $(GENERATED_DIRTY) +## If the generated files are anything but source files, we need to +## ensure that those files are generated before we attempt to build anything +## else. +ifeq ($(OBJS_DEPEND_ON_GENERATED),1) +$(VDIR)$(ACE_PCH_FILE) $(addprefix $(VDIR), $(OBJS)): $(GENERATED_DIRTY) +$(VSHDIR)$(ACE_PCH_FILE) $(VSHOBJS): $(GENERATED_DIRTY) +endif +endif + + +realclean: clean +ifneq ($(GENERATED_DIRTY),) + -$(RM) -r $(GENERATED_DIRTY) +endif + +__prebuild__: + @-: + diff --git a/dep/ACE_wrappers/ace/GNUmakefile.ACE_TkReactor b/dep/ACE_wrappers/ace/GNUmakefile.ACE_TkReactor new file mode 100644 index 000000000..efd388ced --- /dev/null +++ b/dep/ACE_wrappers/ace/GNUmakefile.ACE_TkReactor @@ -0,0 +1,163 @@ +# -*- Makefile -*- +#---------------------------------------------------------------------------- +# GNU Makefile +# +# @file GNUmakefile.ACE_TkReactor +# +# $Id: gnu.mpd 82648 2008-08-21 06:55:54Z johnnyw $ +# +# This file was automatically generated by MPC. Any changes made directly to +# this file will be lost the next time it is generated. +# +#---------------------------------------------------------------------------- +MAKEFILE = GNUmakefile.ACE_TkReactor +DEPENDENCY_FILE = .depend.ACE_TkReactor + +## LIB may be set to empty later on in this file +LIB_UNCHECKED = libACE_TkReactor.a +LIB = $(LIB_UNCHECKED) +LIB_NAME = libACE_TkReactor + +## SHLIB may be set to empty later on in this file +SHLIB_UNCHECKED = libACE_TkReactor.$(SOEXT) +SHLIB = $(SHLIB_UNCHECKED) + +FILES = \ + TkReactor/TkReactor.cpp + +VPATH = .:TkReactor + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- +ACE_SHLIBS = -lACE + +PRJ_TYPE = library + +INSLIB ?= ../lib +ifeq ($(INSLIB),.) + ifeq ($(PWD),) + PWD=$(shell pwd) + endif + INSLIB = $(PWD) +endif +OUTPUT_DIRECTORY = $(INSLIB) + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU + +# To build multiple targets in the same directory on AIX, it works +# best to have a template directory per project. +# The compiler/linker isn't too smart about instantiating templates... +ifdef TEMPINCDIR +TEMPINCDIR := $(TEMPINCDIR)/ACE_TkReactor +all: $(TEMPINCDIR) +endif + +ifneq ($(OUTPUT_DIRECTORY),) +all: $(OUTPUT_DIRECTORY) +$(OUTPUT_DIRECTORY): + -@$(MKDIR) "$(OUTPUT_DIRECTORY)" +endif + +# turn off libcheck if doing a dry run +ifeq ($(findstring n, $(MAKEFLAGS)),n) + LIBCHECK = 1 +else + # turn off libcheck if keep going was passed too + ifeq ($(findstring k, $(MAKEFLAGS)),k) + LIBCHECK = 1 + else + LIBCHECK ?= $(filter-out $(foreach lib,ACE,$(findstring $(lib),$(foreach libpath,. ../lib /usr/lib /usr/lib64 $(INSLIB),$(wildcard $(libpath)/lib$(lib).* $(libpath)/$(lib).lib)))),ACE) + ifeq ($(LIBCHECK),) + LIBCHECK = 1 + endif + endif +endif +ifeq ($(tk),1) +ifneq ($(LIBCHECK), 1) + LIB = + SHLIB = + all: lib_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif + +ifeq ($(tk),1) +else + LIB = + SHLIB = + all: require_warning +endif +LSRC = $(FILES) + +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU +ifeq ($(VXWORKSLINK),1) +include $(TGT_DIR)/h/make/rules.$(PRJ_TYPE) +endif + +ifeq ($(VXWORKSLINK),1) +LDLIBPATH = -L. -L../lib +else +LDFLAGS += -L. -L../lib +endif +CPPFLAGS += -I.. +ifeq ($(shared_libs),1) + ifneq ($(SHLIB),) + CPPFLAGS += -DACE_TKREACTOR_BUILD_DLL + endif +endif +ifeq ($(static_libs),1) + CPPFLAGS += -DACE_AS_STATIC_LIBS +endif + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- +CPPFLAGS += $(PLATFORM_TCL_CPPFLAGS) $(PLATFORM_TK_CPPFLAGS) +LIBS += $(PLATFORM_TCL_LIBS) $(PLATFORM_TK_LIBS) +LDFLAGS += $(PLATFORM_TCL_LDFLAGS) $(PLATFORM_TK_LDFLAGS) + +lib_warning: + @echo ACE_TkReactor will not be built due to the following missing library: + @echo $(LIBCHECK) + +require_warning: + @echo ACE_TkReactor will not be built due to one of the following disabled make macros: + @echo tk + +## Some OS's have /bin/test others only have /usr/bin/test +ifeq ($(wildcard /bin/test), /bin/test) + TEST_EXE = /bin/test +else +ifeq ($(wildcard /usr/bin/test), /usr/bin/test) + TEST_EXE = /usr/bin/test +endif +endif + +ifneq ($(GENERATED_DIRTY),) +.PRECIOUS: $(GENERATED_DIRTY) +## If the generated files are anything but source files, we need to +## ensure that those files are generated before we attempt to build anything +## else. +ifeq ($(OBJS_DEPEND_ON_GENERATED),1) +$(VDIR)$(ACE_PCH_FILE) $(addprefix $(VDIR), $(OBJS)): $(GENERATED_DIRTY) +$(VSHDIR)$(ACE_PCH_FILE) $(VSHOBJS): $(GENERATED_DIRTY) +endif +endif + + +realclean: clean +ifneq ($(GENERATED_DIRTY),) + -$(RM) -r $(GENERATED_DIRTY) +endif + +__prebuild__: + @-: + diff --git a/dep/ACE_wrappers/ace/GNUmakefile.ACE_XtReactor b/dep/ACE_wrappers/ace/GNUmakefile.ACE_XtReactor new file mode 100644 index 000000000..823e7f439 --- /dev/null +++ b/dep/ACE_wrappers/ace/GNUmakefile.ACE_XtReactor @@ -0,0 +1,175 @@ +# -*- Makefile -*- +#---------------------------------------------------------------------------- +# GNU Makefile +# +# @file GNUmakefile.ACE_XtReactor +# +# $Id: gnu.mpd 82648 2008-08-21 06:55:54Z johnnyw $ +# +# This file was automatically generated by MPC. Any changes made directly to +# this file will be lost the next time it is generated. +# +#---------------------------------------------------------------------------- +MAKEFILE = GNUmakefile.ACE_XtReactor +DEPENDENCY_FILE = .depend.ACE_XtReactor + +## LIB may be set to empty later on in this file +LIB_UNCHECKED = libACE_XtReactor.a +LIB = $(LIB_UNCHECKED) +LIB_NAME = libACE_XtReactor + +## SHLIB may be set to empty later on in this file +SHLIB_UNCHECKED = libACE_XtReactor.$(SOEXT) +SHLIB = $(SHLIB_UNCHECKED) + +FILES = \ + XtReactor/XtReactor.cpp + +VPATH = .:XtReactor + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- +ACE_SHLIBS = -lACE + +PRJ_TYPE = library + +INSLIB ?= ../lib +ifeq ($(INSLIB),.) + ifeq ($(PWD),) + PWD=$(shell pwd) + endif + INSLIB = $(PWD) +endif +OUTPUT_DIRECTORY = $(INSLIB) + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU + +# To build multiple targets in the same directory on AIX, it works +# best to have a template directory per project. +# The compiler/linker isn't too smart about instantiating templates... +ifdef TEMPINCDIR +TEMPINCDIR := $(TEMPINCDIR)/ACE_XtReactor +all: $(TEMPINCDIR) +endif + +ifneq ($(OUTPUT_DIRECTORY),) +all: $(OUTPUT_DIRECTORY) +$(OUTPUT_DIRECTORY): + -@$(MKDIR) "$(OUTPUT_DIRECTORY)" +endif + +# turn off libcheck if doing a dry run +ifeq ($(findstring n, $(MAKEFLAGS)),n) + LIBCHECK = 1 +else + # turn off libcheck if keep going was passed too + ifeq ($(findstring k, $(MAKEFLAGS)),k) + LIBCHECK = 1 + else + LIBCHECK ?= $(filter-out $(foreach lib,ACE,$(findstring $(lib),$(foreach libpath,. ../lib /usr/lib /usr/lib64 $(INSLIB),$(wildcard $(libpath)/lib$(lib).* $(libpath)/$(lib).lib)))),ACE) + ifeq ($(LIBCHECK),) + LIBCHECK = 1 + endif + endif +endif +ifeq ($(x11),1) +ifeq ($(xt),1) +ifneq ($(LIBCHECK), 1) + LIB = + SHLIB = + all: lib_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif + +ifeq ($(x11),1) +ifeq ($(xt),1) +else + LIB = + SHLIB = + all: require_warning +endif +else + LIB = + SHLIB = + all: require_warning +endif +LSRC = $(FILES) + +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU +ifeq ($(VXWORKSLINK),1) +include $(TGT_DIR)/h/make/rules.$(PRJ_TYPE) +endif + +ifeq ($(VXWORKSLINK),1) +LDLIBPATH = -L. -L../lib +else +LDFLAGS += -L. -L../lib +endif +CPPFLAGS += -I.. +ifeq ($(shared_libs),1) + ifneq ($(SHLIB),) + CPPFLAGS += -DACE_XTREACTOR_BUILD_DLL + endif +endif +ifeq ($(static_libs),1) + CPPFLAGS += -DACE_AS_STATIC_LIBS +endif + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- +CPPFLAGS += $(PLATFORM_XT_CPPFLAGS) $(PLATFORM_X11_CPPFLAGS) +LIBS += $(PLATFORM_XT_LIBS) $(PLATFORM_X11_LIBS) +LDFLAGS += $(PLATFORM_XT_LDFLAGS) $(PLATFORM_X11_LDFLAGS) + +lib_warning: + @echo ACE_XtReactor will not be built due to the following missing library: + @echo $(LIBCHECK) + +require_warning: + @echo ACE_XtReactor will not be built due to one of the following disabled make macros: + @echo x11 xt + +## Some OS's have /bin/test others only have /usr/bin/test +ifeq ($(wildcard /bin/test), /bin/test) + TEST_EXE = /bin/test +else +ifeq ($(wildcard /usr/bin/test), /usr/bin/test) + TEST_EXE = /usr/bin/test +endif +endif + +ifneq ($(GENERATED_DIRTY),) +.PRECIOUS: $(GENERATED_DIRTY) +## If the generated files are anything but source files, we need to +## ensure that those files are generated before we attempt to build anything +## else. +ifeq ($(OBJS_DEPEND_ON_GENERATED),1) +$(VDIR)$(ACE_PCH_FILE) $(addprefix $(VDIR), $(OBJS)): $(GENERATED_DIRTY) +$(VSHDIR)$(ACE_PCH_FILE) $(VSHOBJS): $(GENERATED_DIRTY) +endif +endif + + +realclean: clean +ifneq ($(GENERATED_DIRTY),) + -$(RM) -r $(GENERATED_DIRTY) +endif + +__prebuild__: + @-: + diff --git a/dep/ACE_wrappers/ace/Get_Opt.cpp b/dep/ACE_wrappers/ace/Get_Opt.cpp new file mode 100644 index 000000000..915ff8a87 --- /dev/null +++ b/dep/ACE_wrappers/ace/Get_Opt.cpp @@ -0,0 +1,734 @@ +// $Id: Get_Opt.cpp 81840 2008-06-05 13:46:45Z sma $ + +#include "ace/Get_Opt.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Get_Opt.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/ACE.h" +#include "ace/Log_Msg.h" +#include "ace/SString.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_NS_stdlib.h" + +ACE_RCSID (ace, + Get_Opt, + "$Id: Get_Opt.cpp 81840 2008-06-05 13:46:45Z sma $") + +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Get_Opt) + +#ifdef ACE_USES_WCHAR +void ACE_Get_Opt::ACE_Get_Opt_Init (const ACE_TCHAR *optstring) +#else +ACE_Get_Opt::ACE_Get_Opt (int argc, + ACE_TCHAR **argv, + const ACE_TCHAR *optstring, + int skip, + int report_errors, + int ordering, + int long_only) + : argc_ (argc), + argv_ (argv), + optind (skip), + opterr (report_errors), + optarg (0), + optstring_ (0), + long_only_ (long_only), + has_colon_ (0), + last_option_ (0), + nextchar_ (0), + optopt_ (0), + ordering_ (ordering), + nonopt_start_ (optind), + nonopt_end_ (optind), + long_option_ (0) +#endif +{ + ACE_TRACE ("ACE_Get_Opt::ACE_Get_Opt"); + + ACE_NEW (this->optstring_, ACE_TString (optstring)); + ACE_NEW (this->last_option_, ACE_TString (ACE_TEXT (""))); + + // First check to see if POSIXLY_CORRECT was set. + // Win32 is the only platform capable of wide-char env var. +#if defined (ACE_WIN32) + const ACE_TCHAR *env_check = ACE_TEXT ("POSIXLY_CORRECT"); +#else + const char *env_check = "POSIXLY_CORRECT"; +#endif + if (ACE_OS::getenv (env_check) != 0) + this->ordering_ = REQUIRE_ORDER; + + // Now, check to see if any or the following were passed at + // the begining of optstring: '+' same as POSIXLY_CORRECT; + // '-' turns off POSIXLY_CORRECT; or ':' which signifies we + // should return ':' if a parameter is missing for an option. + // We use a loop here, since a combination of "{+|-}:" in any + // order should be legal. + int done = 0; + int offset = 0; + while (!done) + { + switch (optstring[offset++]) + { + case '+': + this->ordering_ = REQUIRE_ORDER; + break; + case '-': + this->ordering_ = RETURN_IN_ORDER; + break; + case ':': + this->has_colon_ = 1; + break; + default: + // Quit as soon as we see something else... + done = 1; + break; + } + } +} + +ACE_Get_Opt::~ACE_Get_Opt (void) +{ + ACE_TRACE ("ACE_Get_Opt::~ACE_Get_Opt"); + + size_t i = 0; + size_t size = this->long_opts_.size (); + ACE_Get_Opt_Long_Option *option = 0; + for (i = 0; i < size; ++i) + { + int retval = this->long_opts_.get (option, i); + if (retval != 0) + { + // Should never happen. + retval = 0; + continue; + } + if (option) + { + delete option; + option = 0; + } + } + delete this->optstring_; + delete this->last_option_; +} + +int +ACE_Get_Opt::nextchar_i (void) +{ + ACE_TRACE ("ACE_Get_Opt::nextchar_i"); + + if (this->ordering_ == PERMUTE_ARGS) + if (this->permute () == EOF) + return EOF; + + // Update scanning pointer. + if (this->optind >= this->argc_) + { + // We're done... + this->nextchar_ = 0; + return EOF; + } + else if (*(this->nextchar_ = this->argv_[this->optind]) != '-' + || this->nextchar_[1] == '\0') + { + // We didn't get an option. + + if (this->ordering_ == REQUIRE_ORDER + || this->ordering_ == PERMUTE_ARGS) + // If we permuted or require the options to be in order, we're done. + return EOF; + + // It must be RETURN_IN_ORDER... + this->optarg = this->argv_[this->optind++]; + this->nextchar_ = 0; + return 1; + } + else if (this->nextchar_[1] != 0 + && *++this->nextchar_ == '-' + && this->nextchar_[1] == 0) + { + // Found "--" so we're done... + ++this->optind; + this->nextchar_ = 0; + return EOF; + } + + // If it's a long option, and we allow long options advance nextchar_. + if (*this->nextchar_ == '-' && this->long_opts_.size () != 0) + this->nextchar_++; + + return 0; +} + +int +ACE_Get_Opt::long_option_i (void) +{ + ACE_TRACE ("ACE_Get_Opt::long_option_i"); + + ACE_Get_Opt_Long_Option *p; + ACE_TCHAR *s = this->nextchar_; + int hits = 0; + int exact = 0; + ACE_Get_Opt_Long_Option *pfound = 0; + int indfound = 0; + + // Advance to the end of the long option name so we can use + // it to get the length for a string compare. + while (*s && *s != '=') + s++; + + size_t len = s - this->nextchar_; + // set last_option_ to nextchar_, up to the '='. + this->last_option (ACE_TString (this->nextchar_, len)); + + size_t size = this->long_opts_.size (); + u_int option_index = 0; + for (option_index = 0; option_index < size ; option_index++) + { + p = this->long_opts_[option_index]; + ACE_ASSERT (p); + + if (!ACE_OS::strncmp (p->name_, this->nextchar_, len)) + { + // Got at least a partial match. + pfound = p; + indfound = option_index; + hits += 1; + if (len == ACE_OS::strlen(p->name_)) + { + // And in fact, it's an exact match, so let's use it. + exact = 1; + break; + } + } + } + + if ((hits > 1) && !exact) + { + // Great, we found a match, but unfortunately we found more than + // one and it wasn't exact. + if (this->opterr) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%s: option `%s' is ambiguous\n"), + this->argv_[0], this->argv_[this->optind])); + this->nextchar_ = 0; + this->optind++; + return '?'; + } + + if (pfound != 0) + { + // Okay, we found a good one (either a single hit or an exact match). + option_index = indfound; + this->optind++; + if (*s) + { + // s must point to '=' which means there's an argument (well + // close enough). + if (pfound->has_arg_ != NO_ARG) + // Good, we want an argument and here it is. + this->optarg = ++s; + else + { + // Whoops, we've got what looks like an argument, but we + // don't want one. + if (this->opterr) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%s: long option `--%s' doesn't allow ") + ACE_TEXT ("an argument\n"), + this->argv_[0], pfound->name_)); + // The spec doesn't cover this, so we keep going and the program + // doesn't know we ignored an argument if opt_err is off!!! + } + } + else if (pfound->has_arg_ == ARG_REQUIRED) + { + // s didn't help us, but we need an argument. Note that + // optional arguments for long options must use the "=" syntax, + // so we won't get here in that case. + if (this->optind < this->argc_) + // We still have some elements left, so use the next one. + this->optarg = this->argv_[this->optind++]; + else + { + // All out of elements, so we have to punt... + if (this->opterr) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%s: long option '--%s' requires ") + ACE_TEXT ("an argument\n"), + this->argv_[0], pfound->name_)); + this->nextchar_ = 0; + this->optopt_ = pfound->val_; // Remember matching short equiv + return this->has_colon_ ? ':' : '?'; + } + } + this->nextchar_ = 0; + this->long_option_ = pfound; + // Since val_ has to be either a valid short option or 0, this works + // great. If the user really wants to know if a long option was passed. + this->optopt_ = pfound->val_; + return pfound->val_; + } + if (!this->long_only_ || this->argv_[this->optind][1] == '-' + || this->optstring_->find (*this->nextchar_) == ACE_TString::npos) + { + // Okay, we couldn't find a long option. If it isn't long_only (which + // means try the long first, and if not found try the short) or a long + // signature was passed, e.g. "--", or it's not a short (not sure when + // this could happen) it's an error. + if (this->opterr) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%s: illegal long option '--%s'\n"), + this->argv_[0], this->nextchar_)); + this->nextchar_ = 0; + this->optind++; + return '?'; + } + return this->short_option_i (); +} + +int +ACE_Get_Opt::short_option_i (void) +{ + ACE_TRACE ("ACE_Get_Opt::short_option_i"); + + /* Look at and handle the next option-character. */ + ACE_TCHAR opt = *this->nextchar_++; + // Set last_option_ to opt + this->last_option (opt); + + ACE_TCHAR *oli = 0; + oli = + const_cast (ACE_OS::strchr (this->optstring_->c_str (), opt)); + + /* Increment `optind' when we start to process its last character. */ + if (*this->nextchar_ == '\0') + ++this->optind; + + if (oli == 0 || opt == ':') + { + if (this->opterr) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%s: illegal short option -- %c\n"), + this->argv_[0], opt)); + return '?'; + } + if (opt == 'W' && oli[1] == ';') + { + if (this->nextchar_[0] == 0) + this->nextchar_ = this->argv_[this->optind]; + return long_option_i (); + } + this->optopt_ = oli[0]; // Remember the option that matched + if (oli[1] == ':') + { + if (oli[2] == ':') + { + // Takes an optional argument, and since short option args must + // must follow directly in the same argument, a NULL nextchar_ + // means we didn't get one. + if (*this->nextchar_ != '\0') + { + this->optarg = this->nextchar_; + this->optind++; + } + else + this->optarg = 0; + this->nextchar_ = 0; + } + else + { + // Takes a required argument. + if (*this->nextchar_ != '\0') + { + // Found argument in same argv-element. + this->optarg = this->nextchar_; + this->optind++; + } + else if (this->optind == this->argc_) + { + // Ran out of arguments before finding required argument. + if (this->opterr) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%s: short option requires ") + ACE_TEXT ("an argument -- %c\n"), + this->argv_[0], opt)); + opt = this->has_colon_ ? ':' : '?'; + } + else + // Use the next argv-element as the argument. + this->optarg = this->argv_[this->optind++]; + this->nextchar_ = 0; + } + } + return opt; +} + +int +ACE_Get_Opt::operator () (void) +{ + ACE_TRACE ("ACE_Get_Opt_Long::operator"); + + // First of all, make sure we reinitialize any pointers.. + this->optarg = 0; + this->long_option_ = 0; + + if (this->argv_ == 0) + { + // It can happen, e.g., on VxWorks. + this->optind = 0; + return -1; + } + + // We check this because we can string short options together if the + // preceding one doesn't take an argument. + if (this->nextchar_ == 0 || *this->nextchar_ == '\0') + { + int retval = this->nextchar_i (); + if (retval != 0) + return retval; + } + + if (((this->argv_[this->optind][0] == '-') + && (this->argv_[this->optind][1] == '-')) || this->long_only_) + return this->long_option_i (); + + return this->short_option_i (); +} + +int +ACE_Get_Opt::long_option (const ACE_TCHAR *name, + OPTION_ARG_MODE has_arg) +{ + ACE_TRACE ("ACE_Get_Opt::long_option (const ACE_TCHAR *name, OPTION_ARG_MODE has_arg)"); + return this->long_option (name, 0, has_arg); +} + +int +ACE_Get_Opt::long_option (const ACE_TCHAR *name, + int short_option, + OPTION_ARG_MODE has_arg) +{ + ACE_TRACE ("ACE_Get_Opt::long_option (const ACE_TCHAR *name, int short_option, OPTION_ARG_MODE has_arg)"); + + // We only allow valid alpha-numeric characters as short options. + // If short_options is not a valid alpha-numeric, we can still return it + // when the long option is found, but won't allow the caller to pass it on + // the command line (how could they?). The special case is 0, but since + // we always return it, we let the caller worry about that. + if (ACE_OS::ace_isalnum (short_option) != 0) + { + // If the short_option already exists, make sure it matches, otherwise + // add it. + ACE_TCHAR *s = 0; + if ((s = const_cast ( + ACE_OS::strchr (this->optstring_->c_str (), + short_option))) != 0) + { + // Short option exists, so verify the argument options + if (s[1] == ':') + { + if (s[2] == ':') + { + if (has_arg != ARG_OPTIONAL) + { + if (this->opterr) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("Existing short option '%c' takes ") + ACE_TEXT ("optional argument; adding %s ") + ACE_TEXT ("requires ARG_OPTIONAL\n"), + short_option, name)); + return -1; + } + } + else + if (has_arg != ARG_REQUIRED) + { + if (this->opterr) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("Existing short option '%c' requires ") + ACE_TEXT ("an argument; adding %s ") + ACE_TEXT ("requires ARG_REQUIRED\n"), + short_option, name)); + return -1; + } + } + else if (has_arg != NO_ARG) + { + if (this->opterr) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("Existing short option '%c' does not ") + ACE_TEXT ("accept an argument; adding %s ") + ACE_TEXT ("requires NO_ARG\n"), + short_option, name)); + return -1; + } + } + else + { + // Didn't find short option, so add it... + *this->optstring_ += (ACE_TCHAR) short_option; + if (has_arg == ARG_REQUIRED) + *this->optstring_ += ACE_TEXT (":"); + else if (has_arg == ARG_OPTIONAL) + *this->optstring_ += ACE_TEXT ("::"); + } + } + + ACE_Get_Opt_Long_Option *option = + new ACE_Get_Opt_Long_Option (name, has_arg, short_option); + + if (!option) + return -1; + + // Add to array + size_t size = this->long_opts_.size (); + if (this->long_opts_.size (size + 1) != 0 + || this->long_opts_.set (option, size) != 0) + { + delete option; + ACE_ERROR_RETURN + ((LM_ERROR, ACE_TEXT ("Could not add long option to array.\n")), + -1); + } + return 0; +} + +const ACE_TCHAR* +ACE_Get_Opt::long_option (void) const +{ + ACE_TRACE ("ACE_Get_Opt::long_option (void)"); + if (this->long_option_) + return this->long_option_->name_; + return 0; +} + +const ACE_TCHAR* +ACE_Get_Opt::last_option (void) const +{ + return this->last_option_->c_str (); +} + +void +ACE_Get_Opt::last_option (const ACE_TString &last_option) +{ + *this->last_option_ = last_option; +} + +void +ACE_Get_Opt::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Get_Opt::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n") + ACE_TEXT ("opstring_ = %s\n") + ACE_TEXT ("long_only_ = %d\n") + ACE_TEXT ("has_colon_ = %d\n") + ACE_TEXT ("last_option_ = %s\n") + ACE_TEXT ("nextchar_ = %s\n") + ACE_TEXT ("optopt_ = %c\n") + ACE_TEXT ("ordering_ = %d\n"), + this->optstring_->c_str (), + this->long_only_, + this->has_colon_, + this->last_option_->c_str (), + this->nextchar_, + this->optopt_, + this->ordering_)); + + // now loop through the + size_t size = this->long_opts_.size (); + for (u_int i = 0; i < size ; ++i) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n") + ACE_TEXT ("long_option name_ = %s\n") + ACE_TEXT ("has_arg_ = %d\n") + ACE_TEXT ("val_ = %d\n"), + this->long_opts_[i]->name_, + this->long_opts_[i]->has_arg_, + this->long_opts_[i]->val_)); + } + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +void +ACE_Get_Opt::permute_args (void) +{ + ACE_TRACE ("ACE_Get_Opt::permute_args"); + + u_long cyclelen, i, j, ncycle, nnonopts, nopts; + u_long opt_end = this->optind; + int cstart, pos = 0; + ACE_TCHAR *swap = 0; + + nnonopts = this->nonopt_end_ - this->nonopt_start_; + nopts = opt_end - this->nonopt_end_; + ncycle = ACE::gcd (nnonopts, nopts); + cyclelen = (opt_end - this->nonopt_start_) / ncycle; + + this->optind = this->optind - nnonopts; + + for (i = 0; i < ncycle; i++) + { + cstart = this->nonopt_end_ + i; + pos = cstart; + for (j = 0; j < cyclelen; j++) + { + if (pos >= this->nonopt_end_) + pos -= nnonopts; + else + pos += nopts; + swap = this->argv_[pos]; + + ((ACE_TCHAR **)this->argv_)[pos] = argv_[cstart]; + + ((ACE_TCHAR **)this->argv_)[cstart] = swap; + } + } +} + +int +ACE_Get_Opt::permute (void) +{ + ACE_TRACE ("ACE_Get_Opt::permute"); + + if (this->nonopt_start_ != this->nonopt_end_ + && this->nonopt_start_ != this->optind) + this->permute_args (); + + this->nonopt_start_ = this->optind; + + // Skip over args untill we find the next option. + while (this->optind < this->argc_ + && (this->argv_[this->optind][0] != '-' + || this->argv_[this->optind][1] == '\0')) + this->optind++; + + // Got an option, so mark this as the end of the non options. + this->nonopt_end_ = this->optind; + + if (this->optind != this->argc_ + && ACE_OS::strcmp (this->argv_[this->optind], + ACE_TEXT ("--")) == 0) + { + // We found the marker for the end of the options. + ++this->optind; + + if (this->nonopt_start_ != this->nonopt_end_ + && this->nonopt_end_ != this->optind) + this->permute_args (); + } + + if (this->optind == this->argc_) + { + if (this->nonopt_start_ != this->nonopt_end_) + this->optind = this->nonopt_start_; + return EOF; + } + return 0; +} + +const ACE_TCHAR * +ACE_Get_Opt::optstring (void) const +{ + return this->optstring_->c_str (); +} + +ACE_Get_Opt::ACE_Get_Opt_Long_Option::ACE_Get_Opt_Long_Option ( + const ACE_TCHAR *name, + int has_arg, + int val) + : name_ (ACE::strnew (name)), + has_arg_ (has_arg), + val_ (val) +{} + +ACE_Get_Opt::ACE_Get_Opt_Long_Option::~ACE_Get_Opt_Long_Option (void) +{ + delete [] this->name_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Get_Opt.h b/dep/ACE_wrappers/ace/Get_Opt.h new file mode 100644 index 000000000..3b4a420d9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Get_Opt.h @@ -0,0 +1,494 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Get_Opt.h + * + * $Id: Get_Opt.h 81840 2008-06-05 13:46:45Z sma $ + * + * @author Douglas C. Schmidt + * @author Don Hinton (added long option support) + */ +//========================================================================== + +#ifndef ACE_GET_OPT_H +#define ACE_GET_OPT_H +#include /**/ "ace/pre.h" + +#include "ace/SStringfwd.h" +#include "ace/Containers.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#undef optind +#undef optarg +#undef opterr + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/* + * These definitions are for backward compatibility with previous versions. + * of ACE_Get_Opt. + */ + +/** + * @class ACE_Get_Opt + * + * @brief Iterator for parsing command-line arguments. + * + * This is a C++ wrapper for getopt(3c) and getopt_long(3c). + */ + +class ACE_Export ACE_Get_Opt +{ +public: + /// Mutually exclusive ordering values. + enum + { + /** + * REQUIRE_ORDER means that processing stops and @c EOF is + * returned as soon as a non-option argument is found. @c opt_ind() + * will return the index of the next @a argv element so the program + * can continue processing the rest of the @a argv elements. + */ + REQUIRE_ORDER = 1, + + /** + * PERMUTE_ARGS means the @a argv elements are reordered dynamically + * (permuted) so that all options appear first. When the elements are + * permuted, the order of the options and the following arguments are + * maintained. When the last option has been processed, @c EOF is + * returned and @c opt_ind() returns the index into the next non-option + * element. + */ + PERMUTE_ARGS = 2, + + /** + * RETURN_IN_ORDER means each @a argv element is processed in the + * order is it seen. If the element is not recognized as an option, '1' + * is returned and @c opt_arg() refers to the @a argv element found. + */ + RETURN_IN_ORDER = 3 + }; + + /// Mutually exclusive option argument mode used by long options. + enum OPTION_ARG_MODE + { + /// Doesn't take an argument. + NO_ARG = 0, + + /// Requires an argument, same as passing ":" after a short option + /// character in @a optstring. + ARG_REQUIRED = 1, + + /// Argument is optional, same as passing "::" after a short + /// option character in @a optstring. + ARG_OPTIONAL = 2 + }; + + /** + * Constructor initializes the command line to be parsed. All information + * for parsing must be supplied to this constructor. + * + * @param argc The number of @a argv elements to parse. + * @param argv Command line tokens, such as would be passed + * to @c main(). + * @param optstring Nul-terminated string containing the legitimate + * short option characters. A single colon ":" + * following an option character means the option + * requires an argument. A double colon "::" following + * an option character means the argument is optional. + * The argument is taken from the rest of the current + * @a argv element, or from the following @a argv + * element (only valid for required arguments; + * optional arguments must always reside in the same + * @a argv element). The argument value, if any is + * returned by the @c opt_arg() method. + * @a optstring can be extended by adding long options + * with corresponding short options via the + * @c long_option() method. If the short option + * already appears in @a optstring, the argument + * characteristics must match, otherwise it is added. + * See @c long_option() for more information. + * If 'W', followed by a semi-colon ';' appears in + * @a optstring, then any time a 'W' appears on the + * command line, the following argument is treated as + * a long option. For example, if the command line + * contains "program -W foo", "foo" is treated as a + * long option, that is, as if "program --foo" had + * been passed. + * The following characters can appear in @a optstring + * before any option characters, with the described + * effect: + * - '+' changes the @a ordering to @a REQUIRE_ORDER. + * - '-' changes the @a ordering to @a RETURN_IN_ORDER. + * - ':' changes the return value from @c operator() + * and get_opt() from '?' to ':' when an option + * requires an argument but none is specified. + * + * @param skip_args Optional (default 1). The specified number of + * initial elements in @a argv are skipped before + * parsing begins. Thus, the default prevents + * @a argv[0] (usually the command name) from being + * parsed. @a argc includes all @a argv elements, + * including any skipped elements. + * @param report_errors Optional, if non-zero then parsing errors cause + * an error message to be displayed from the + * @c operator() method before it returns. The + * error message is suppressed if this argument is 0. + * This setting also controls whether or not an error + * message is displayed in @c long_option() encounters + * an error. + * @param ordering Optional (default is @c PERMUTE_ARGS); determines + * how the @a argv elements are processed. This argument + * is overridden by two factors: + * -# The @c POSIXLY_CORRECT environment variable. If + * this environment variable is set, the ordering + * is changed to @c REQUIRE_ORDER. + * -# Leading characters in @a optstring (see above). + * Any leading ordering characters override both + * the @a ordering argument and any effect of the + * @c POSIXLY_CORRECT environment variable. + * @param long_only Optional. If non-zero, then long options can be + * specified using a single '-' on the command line. + * If the token is not a long option, it is processed + * as usual, that is, as a short option or set of + * short options. + * + * Multiple short options can be combined as long as only the last + * one can takes an argument. For example, if @a optstring is defined as + * @c "abc:" or @c "abc::" then the command line @e "program -abcxxx" short + * options @e a, @e b, and @e c are found with @e "xxx" as the argument for + * @e c. + * However, if the command line is specified as @e "program -acb" only + * options @e a and @e c are found with @e "b" as the argument for @e c. + * Also, for options with optional arguments, that is, those followed by + * "::", the argument must be in the same @a argv element, so "program -abc + * xxx" will only find "xxx" as the argument for @e c if @a optstring is + * specified as @c "abc:" not @c "abc::". + */ +#ifndef ACE_USES_WCHAR + ACE_Get_Opt (int argc, + ACE_TCHAR **argv, + const ACE_TCHAR *optstring = ACE_TEXT (""), + int skip_args = 1, + int report_errors = 0, + int ordering = PERMUTE_ARGS, + int long_only = 0); + +#else +private: + void ACE_Get_Opt_Init (const ACE_TCHAR *optstring); +public: + ACE_INLINE ACE_Get_Opt (int argc, + ACE_TCHAR **argv, + const ACE_TCHAR *optstring = ACE_TEXT (""), + int skip_args = 1, + int report_errors = 0, + int ordering = PERMUTE_ARGS, + int long_only = 0); + ACE_INLINE ACE_Get_Opt (int argc, + ACE_TCHAR **argv, + const char *optstring, + int skip_args = 1, + int report_errors = 0, + int ordering = PERMUTE_ARGS, + int long_only = 0); +#endif + /// Default dtor. + ~ACE_Get_Opt (void); + + /** + * Scan elements of @a argv (whose length is @a argc) for short option + * characters given in @a optstring or long options (with no short + * option equivalents). + * + * If an element of @a argv starts with '-', and is not exactly "-" + * or "--", then it is a short option element. The characters of this + * element (aside from the initial '-') are option characters. If + * it starts with "--" followed by other characters it is treated as + * a long option. If @c operator() is called repeatedly, it returns + * each of the option characters from each of the option elements. + * + * @return The parsed option character. The following characters have + * special significance. + * @retval 0 A long option was found + * @retval '\?' Either an unknown option character was found, or the + * option is known but requires an argument, none was + * specified, and @a optstring did not contain a leading + * colon. + * @retval ':' A known option character was found but it requires an + * argument and none was supplied, and the first character + * of @a optstring was a colon. @c opt_opt() indicates + * which option was specified. + * @retval '1' @c RETURN_IN_ORDER was specified and a non-option argument + * was found. + * @retval EOF No more option characters were found. @c opt_ind() will + * return the index in @a argv of the first @a argv element + * that is not an option. If @c PERMUTE_ARGS was + * specified, the @a argv elements have been permuted so that + * those that are not options now come last. + * + * @note The standards are unclear with respect to the conditions under + * which '?' and ':' are returned, so we scan the initial characters of + * @a optstring up unto the first short option character for '+', '-', + * and ':' in order to determine ordering and missing argument behavior. + */ + int operator () (void); + + /** + * For communication from @c operator() to the caller. When + * @c operator() finds an option that takes an argument, the argument + * value is returned from this method, otherwise it returns 0. + */ + ACE_TCHAR *opt_arg (void) const; + + /** + * Returns the most recently matched option character. Especially + * useful when operator() returns ':' for an unspecified argument + * that's required, since this allows the caller to learn what option + * was specified without its required argument. + */ + int opt_opt (void); + + /** + * Index in @a argv of the next element to be scanned. This is used + * for communication to and from the caller and for communication + * between successive calls to @c operator(). On entry to + * @c operator(), zero means this is the first call; initialize. + * + * When @c operator() returns @c EOF, this is the index of the first of + * the non-option elements that the caller should itself scan. + * + * Otherwise, @c opt_ind() communicates from one call to the next how + * much of @a argv has been scanned so far. + */ + int &opt_ind (void); + + /// Adds a long option with no corresponding short option. + /** + * If the @a name option is seen, @c operator() returns 0. + * + * @param name The long option to add. + * @param has_arg Defines the argument requirements for + * the new option. + * + * @retval 0 Success + * @retval -1 The long option can not be added. + */ + int long_option (const ACE_TCHAR *name, + OPTION_ARG_MODE has_arg = NO_ARG); + + /// Adds a long option with a corresponding short option. + /** + * @param name The long option to add. + * @param short_option A character, the short option that corresponds + * to @a name. + * @param has_arg Defines the argument requirements for + * the new option. If the short option has already + * been supplied in the @a optstring, @a has_arg + * must match or an error is returned; otherwise, the + * new short option is added to the @a optstring. + * + * @retval 0 Success + * @retval -1 The long option can not be added. + */ + int long_option (const ACE_TCHAR *name, + int short_option, + OPTION_ARG_MODE has_arg = NO_ARG); + + /// Returns the name of the long option found on the last call to + /// @c operator() or 0 if none was found. + const ACE_TCHAR *long_option (void) const; + + /// The number of arguments in the internal @c argv_. + int argc (void) const; + + /// Accessor for the internal @c argv_ pointer. + ACE_TCHAR **argv (void) const; + + /// Accessor for the @c last_option that was processed. This allows + /// applications to know if the found option was a short or long + /// option, and is especially useful in cases where it was invalid + /// and the caller wants to print out the invalid value. + const ACE_TCHAR *last_option (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Return the @a optstring. This is handy to verify that calls to + /// long_option added short options as expected. + const ACE_TCHAR *optstring (void) const; + +public: + /* + * The following five data members should be private, but that + * would break backwards compatibility. However, we recommend not + * writing code that uses these fields directly. + */ + + /// Holds the @a argc count. + /** + * @deprecated This is public for backwards compatibility only. + * It will be made private in a release of ACE past 5.3. Do not + * write code that relies on this member being public; use the + * @c argc() accessor method instead. + */ + int argc_; + + /// Holds the @a argv pointer. + /** + * @deprecated This is public for backwards compatibility only. + * It will be made private in a release of ACE past 5.3. Do not + * write code that relies on this member being public; use the + * @c argv() accessor method instead. + */ + ACE_TCHAR **argv_; + + /// Index in @c argv_ of the next element to be scanned. + /** + * @deprecated This is public for backwards compatibility only. + * It will be made private in a release of ACE past 5.3. Do not + * write code that relies on this member being public; use the + * @c opt_ind() accessor method instead. + */ + int optind; + + /// Callers store zero here to inhibit the error message for + /// unrecognized options. + /** + * @deprecated This is public for backwards compatibility only. + * It will be made private in a release of ACE past 5.3. Do not + * write code that relies on this member being public; use the + * @a report_errors argument to this class's constructor instead. + */ + int opterr; + + /// Points to the option argument when one is found on last call to + /// @c operator(). + /** + * @deprecated This is public for backwards compatibility only. + * It will be made private in a release of ACE past 5.3. Do not + * write code that relies on this member being public; use the + * @c opt_arg() accessor method instead. + */ + ACE_TCHAR *optarg; + +private: + /** + * @class ACE_Get_Opt_Long_Option This class is for internal use + * in the ACE_Get_Opt class, and is inaccessible to users. + */ + class ACE_Get_Opt_Long_Option + { + public: + /// ctor + ACE_Get_Opt_Long_Option (const ACE_TCHAR *name, + int has_arg, + int val = 0); + + /// Dtor. + ~ACE_Get_Opt_Long_Option (void); + + bool operator < (const ACE_Get_Opt_Long_Option &rhs); + + /// Long option name. + const ACE_TCHAR *name_; + + /// Contains value for . + int has_arg_; + + /// Contains a valid short option character or zero if it doesn't + /// have a corresponding short option. It can also contain a + /// non-printable value that cannot be passed to but + /// will be returned by . This is handy for + /// simplifying long option handling, see tests/Get_Opt_Test.cpp + /// for an example of this technique. + int val_; + }; + + /// Updates nextchar_. + int nextchar_i (void); + + /// Handles long options. + int long_option_i (void); + + /// Handles short options. + int short_option_i (void); + + /// If permuting args, this functions manages the nonopt_start_ and + /// nonopt_end_ indexes and makes calls to permute to actually + /// reorder the -elements. + void permute_args (void); + + /// Handles reordering -elements. + int permute (void); + + /// Set last_option. + void last_option (const ACE_TString &s); + + // Disallow copying and assignment. + ACE_Get_Opt (const ACE_Get_Opt &); + ACE_Get_Opt &operator= (const ACE_Get_Opt &); + +private: + + /// Holds the option string. + ACE_TString *optstring_; + + /// Treat all options as long options. + int long_only_; + + /// Keeps track of whether or not a colon was passed in . + /// This is used to determine the return value when required + /// arguments are missing. + int has_colon_; + + /// This is the last option, short or long, that was processed. This + /// is handy to have in cases where the option passed was invalid. + ACE_TString *last_option_; + + /** + * The next char to be scanned in the option-element in which the + * last option character we returned was found. This allows us to + * pick up the scan where we left off * + * If this is zero, or a null string, it means resume the scan + * by advancing to the next -element. + */ + ACE_TCHAR *nextchar_; + + /// Most recently matched short option character. + int optopt_; + + /// Keeps track of ordering mode (default ). + int ordering_; + + /// Index of the first non-option -element found (only valid + /// when permuting). + int nonopt_start_; + + /// Index of the -element following the last non-option element + /// (only valid when permuting). + int nonopt_end_; + + /// Points to the long_option found on last call to . + ACE_Get_Opt_Long_Option *long_option_; + + /// Array of long options. + ACE_Array long_opts_; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Get_Opt.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_GET_OPT_H */ diff --git a/dep/ACE_wrappers/ace/Get_Opt.inl b/dep/ACE_wrappers/ace/Get_Opt.inl new file mode 100644 index 000000000..e307fb5e4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Get_Opt.inl @@ -0,0 +1,97 @@ +// -*- C++ -*- +// +// $Id: Get_Opt.inl 81840 2008-06-05 13:46:45Z sma $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE bool +ACE_Get_Opt::ACE_Get_Opt_Long_Option::operator < (const ACE_Get_Opt_Long_Option &rhs) +{ + return this->name_ < rhs.name_; +} + +ACE_INLINE int +ACE_Get_Opt::argc (void) const +{ + return this->argc_; +} + +ACE_INLINE ACE_TCHAR ** +ACE_Get_Opt::argv (void) const +{ + return this->argv_; +} + +ACE_INLINE ACE_TCHAR* +ACE_Get_Opt::opt_arg (void) const +{ + return this->optarg; +} + +ACE_INLINE int +ACE_Get_Opt::opt_opt (void) +{ + return this->optopt_; +} + +ACE_INLINE int & +ACE_Get_Opt::opt_ind (void) +{ + return this->optind; +} + +#ifdef ACE_USES_WCHAR +ACE_INLINE ACE_Get_Opt::ACE_Get_Opt (int argc, + ACE_TCHAR **argv, + const ACE_TCHAR *optstring, + int skip_args, + int report_errors, + int ordering, + int long_only) + : argc_ (argc), + argv_ (argv), + optind (skip_args), + opterr (report_errors), + optarg (0), + optstring_ (0), + long_only_ (long_only), + has_colon_ (0), + last_option_ (0), + nextchar_ (0), + optopt_ (0), + ordering_ (ordering), + nonopt_start_ (optind), + nonopt_end_ (optind), + long_option_ (0) +{ + ACE_Get_Opt_Init (optstring); +} + +ACE_INLINE ACE_Get_Opt::ACE_Get_Opt (int argc, + ACE_TCHAR **argv, + const char *optstring, + int skip_args, + int report_errors, + int ordering, + int long_only) + : argc_ (argc), + argv_ (argv), + optind (skip_args), + opterr (report_errors), + optarg (0), + optstring_ (), + long_only_ (long_only), + has_colon_ (0), + last_option_ (0), + nextchar_ (0), + optopt_ (0), + ordering_ (ordering), + nonopt_start_ (optind), + nonopt_end_ (optind), + long_option_ (0) +{ + ACE_Get_Opt_Init (ACE_TEXT_CHAR_TO_TCHAR (optstring)); +} +#endif + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Global_Macros.h b/dep/ACE_wrappers/ace/Global_Macros.h new file mode 100644 index 000000000..d1bf6420b --- /dev/null +++ b/dep/ACE_wrappers/ace/Global_Macros.h @@ -0,0 +1,1121 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Global_Macros.h + * + * $Id: Global_Macros.h 82442 2008-07-28 13:11:29Z johnnyw $ + * + * @author Douglas C. Schmidt + * @author Jesper S. M|ller + * @author and a cast of thousands... + * + * This one is split from the famous OS.h + */ +//============================================================================= + +#ifndef ACE_GLOBAL_MACROS_H +#define ACE_GLOBAL_MACROS_H + +#include /**/ "ace/pre.h" + +// Included just keep compilers that see #pragma dierctive first +// happy. +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/config-lite.h" +#include "ace/Assert.h" // For ACE_ASSERT + +// Start Global Macros +# define ACE_BEGIN_DUMP ACE_TEXT ("\n====\n(%P|%t|%x)\n") +# define ACE_END_DUMP ACE_TEXT ("====\n") + +# if defined (ACE_NDEBUG) +# define ACE_DB(X) +# else +# define ACE_DB(X) X +# endif /* ACE_NDEBUG */ + +// ACE_NO_HEAP_CHECK macro can be used to suppress false report of +// memory leaks. It turns off the built-in heap checking until the +// block is left. The old state will then be restored Only used for +// Win32 (in the moment). +# if defined (ACE_WIN32) + +# if defined (_DEBUG) && !defined (ACE_HAS_WINCE) && !defined (__BORLANDC__) +# include /**/ + +// Open versioned namespace, if enabled by the user. +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Export ACE_No_Heap_Check +{ +public: + ACE_No_Heap_Check (void) + : old_state (_CrtSetDbgFlag (_CRTDBG_REPORT_FLAG)) + { _CrtSetDbgFlag (old_state & ~_CRTDBG_ALLOC_MEM_DF);} + ~ACE_No_Heap_Check (void) { _CrtSetDbgFlag (old_state);} +private: + int old_state; +}; + +// Close versioned namespace, if enabled by the user. +ACE_END_VERSIONED_NAMESPACE_DECL + +# define ACE_NO_HEAP_CHECK ACE_No_Heap_Check ____no_heap; +# else /* !_DEBUG */ +# define ACE_NO_HEAP_CHECK +# endif /* _DEBUG */ +# else /* !ACE_WIN32 */ +# define ACE_NO_HEAP_CHECK +# endif /* ACE_WIN32 */ + +// Turn a number into a string. +# define ACE_ITOA(X) #X + +// Create a string of a server address with a "host:port" format. +# define ACE_SERVER_ADDRESS(H,P) H ACE_TEXT(":") P + +// A couple useful inline functions for checking whether bits are +// enabled or disabled. + +// Efficiently returns the least power of two >= X... +# define ACE_POW(X) (((X) == 0)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X))) +# define ACE_EVEN(NUM) (((NUM) & 1) == 0) +# define ACE_ODD(NUM) (((NUM) & 1) == 1) +# define ACE_BIT_ENABLED(WORD, BIT) (((WORD) & (BIT)) != 0) +# define ACE_BIT_DISABLED(WORD, BIT) (((WORD) & (BIT)) == 0) +# define ACE_BIT_CMP_MASK(WORD, BIT, MASK) (((WORD) & (BIT)) == MASK) +# define ACE_SET_BITS(WORD, BITS) (WORD |= (BITS)) +# define ACE_CLR_BITS(WORD, BITS) (WORD &= ~(BITS)) + +# if !defined (ACE_ENDLESS_LOOP) +# define ACE_ENDLESS_LOOP +# endif /* ! ACE_ENDLESS_LOOP */ + +# if defined (ACE_NEEDS_FUNC_DEFINITIONS) + // It just evaporated ;-) Not pleasant. +# define ACE_UNIMPLEMENTED_FUNC(f) +# else +# define ACE_UNIMPLEMENTED_FUNC(f) f; +# endif /* ACE_NEEDS_FUNC_DEFINITIONS */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + // Easy way to designate that a class is used as a pseudo-namespace. + // Insures that g++ "friendship" anamolies are properly handled. + # define ACE_CLASS_IS_NAMESPACE(CLASSNAME) \ + private: \ + CLASSNAME (void); \ + CLASSNAME (const CLASSNAME&); \ + friend class ace_dewarn_gplusplus +#endif /* ACE_LACKS_DEPRECATED_MACROS */ + +// ---------------------------------------------------------------- + +//FUZZ: disable check_for_exception_sepc +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + #if defined (ACE_HAS_NO_THROW_SPEC) + # define ACE_THROW_SPEC(X) + #else + # if defined (ACE_HAS_EXCEPTIONS) + # if defined (ACE_WIN32) && defined (_MSC_VER) && \ + (_MSC_VER >= 1400) && (_MSC_VER <= 1500) + # define ACE_THROW_SPEC(X) throw(...) + # else + # define ACE_THROW_SPEC(X) throw X + # endif /* ACE_WIN32 && VC8 */ + # else /* ! ACE_HAS_EXCEPTIONS */ + # define ACE_THROW_SPEC(X) + # endif /* ! ACE_HAS_EXCEPTIONS */ + #endif /*ACE_HAS_NO_THROW_SPEC*/ +#endif /* ACE_LACKS_DEPRECATED_MACROS */ +//FUZZ: enable check_for_exception_sepc + +// ---------------------------------------------------------------- + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + /** + * This macro is deprecated + */ + #define ACE_NESTED_CLASS(TYPE, NAME) TYPE::NAME +#endif /* ACE_LACKS_DEPRECATED_MACROS */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + /** + * @name CORBA namespace macros. + * + * CORBA namespace macros. + * + * @deprecated These macros were formerly used by TAO but are now + * deprecated, and only remain to retain some backward + * compatibility. They will be removed in a future ACE + * release. + */ + //@{ + #define ACE_CORBA_1(NAME) CORBA::NAME + #define ACE_CORBA_2(TYPE, NAME) CORBA::TYPE::NAME + #define ACE_CORBA_3(TYPE, NAME) CORBA::TYPE::NAME + //@} +#endif /* ACE_LACKS_DEPRECATED_MACROS */ + +// ---------------------------------------------------------------- + +// Convenient macro for testing for deadlock, as well as for detecting +// when mutexes fail. +#define ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ACTION, REACTION) \ + ACE_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () != 0) { ACTION; } \ + else { REACTION; } +#define ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, REACTION) \ + ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ;, REACTION) +#define ACE_GUARD(MUTEX, OBJ, LOCK) \ + ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return) +#define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN) \ + ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return RETURN) +# define ACE_WRITE_GUARD(MUTEX,OBJ,LOCK) \ + ACE_Write_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) return; +# define ACE_WRITE_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \ + ACE_Write_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) return RETURN; +# define ACE_READ_GUARD(MUTEX,OBJ,LOCK) \ + ACE_Read_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) return; +# define ACE_READ_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \ + ACE_Read_Guard< MUTEX > OBJ (LOCK); \ + if (OBJ.locked () == 0) return RETURN; + +// ---------------------------------------------------------------- + +# define ACE_DES_NOFREE(POINTER,CLASS) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~CLASS (); \ + } \ + } \ + while (0) + +# define ACE_DES_ARRAY_NOFREE(POINTER,SIZE,CLASS) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + (&(POINTER)[i])->~CLASS (); \ + } \ + } \ + } \ + while (0) + +# define ACE_DES_FREE(POINTER,DEALLOCATOR,CLASS) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) + +# define ACE_DES_ARRAY_FREE(POINTER,SIZE,DEALLOCATOR,CLASS) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + (&(POINTER)[i])->~CLASS (); \ + } \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) + +# if defined (ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR) +# define ACE_DES_NOFREE_TEMPLATE(POINTER,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + } \ + } \ + while (0) +# define ACE_DES_ARRAY_NOFREE_TEMPLATE(POINTER,SIZE,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + (&(POINTER)[i])->~T_CLASS (); \ + } \ + } \ + } \ + while (0) + +#if defined (ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) +# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS T_PARAMETER (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#else +# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#endif /* defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) */ +# define ACE_DES_ARRAY_FREE_TEMPLATE(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + (&(POINTER)[i])->~T_CLASS (); \ + } \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#if defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) +# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#else +# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#endif /* defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) */ +#if defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) +# define ACE_DES_FREE_TEMPLATE3(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#else +# define ACE_DES_FREE_TEMPLATE3(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#endif /* defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) */ +#if defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) +# define ACE_DES_FREE_TEMPLATE4(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3, T_PARAM4) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#else +# define ACE_DES_FREE_TEMPLATE4(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3, T_PARAM4) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +#endif /* defined(ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS) */ +# define ACE_DES_ARRAY_FREE_TEMPLATE2(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + (&(POINTER)[i])->~T_CLASS (); \ + } \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# else /* ! ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR */ +# define ACE_DES_NOFREE_TEMPLATE(POINTER,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + (POINTER)->T_CLASS T_PARAMETER::~T_CLASS (); \ + } \ + } \ + while (0) +# define ACE_DES_ARRAY_NOFREE_TEMPLATE(POINTER,SIZE,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + (POINTER)[i].T_CLASS T_PARAMETER::~T_CLASS (); \ + } \ + } \ + } \ + while (0) +# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + POINTER->T_CLASS T_PARAMETER::~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# define ACE_DES_ARRAY_FREE_TEMPLATE(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAMETER) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + POINTER[i].T_CLASS T_PARAMETER::~T_CLASS (); \ + } \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \ + do { \ + if (POINTER) \ + { \ + POINTER->T_CLASS ::~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# define ACE_DES_FREE_TEMPLATE3(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3) \ + do { \ + if (POINTER) \ + { \ + POINTER->T_CLASS ::~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# define ACE_DES_FREE_TEMPLATE4(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3,T_PARAM4) \ + do { \ + if (POINTER) \ + { \ + POINTER->T_CLASS ::~T_CLASS (); \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# define ACE_DES_ARRAY_FREE_TEMPLATE2(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \ + do { \ + if (POINTER) \ + { \ + for (size_t i = 0; \ + i < SIZE; \ + ++i) \ + { \ + POINTER[i].T_CLASS ::~T_CLASS (); \ + } \ + DEALLOCATOR (POINTER); \ + } \ + } \ + while (0) +# endif /* defined ! ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR */ + + +/*******************************************************************/ + +/// Service Objects, i.e., objects dynamically loaded via the service +/// configurator, must provide a destructor function with the +/// following prototype to perform object cleanup. +typedef void (*ACE_Service_Object_Exterminator)(void *); + +/** @name Service Configurator macros + * + * The following macros are used to define helper objects used in + * ACE's Service Configurator framework, which is described in + * Chapter 5 of C++NPv2 . This + * framework implements the Component Configurator pattern, which is + * described in Chapter 2 of POSA2 . + * The intent of this pattern is to allow developers to dynamically + * load and configure services into a system. With a little help from + * this macros statically linked services can also be dynamically + * configured. + * + * More details about this component are available in the documentation + * of the ACE_Service_Configurator class and also + * ACE_Dynamic_Service. + * + * Notice that in all the macros the SERVICE_CLASS parameter must be + * the name of a class derived from ACE_Service_Object. + */ +//@{ +/// Declare a the data structure required to register a statically +/// linked service into the service configurator. +/** + * The macro should be used in the header file where the service is + * declared, its only argument is usually the name of the class that + * implements the service. + * + * @param SERVICE_CLASS The name of the class implementing the + * service. + */ +# define ACE_STATIC_SVC_DECLARE(SERVICE_CLASS) \ +extern ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS ; + +/// As ACE_STATIC_SVC_DECLARE, but using an export macro for NT +/// compilers. +/** + * NT compilers require the use of explicit directives to export and + * import symbols from a DLL. If you need to define a service in a + * dynamic library you should use this version instead. + * Normally ACE uses a macro to inject the correct export/import + * directives on NT. Naturally it also the macro expands to a blank + * on platforms that do not require such directives. + * The first argument (EXPORT_NAME) is the prefix for this export + * macro, the full name is formed by appending _Export. + * ACE provides tools to generate header files that define the macro + * correctly on all platforms, please see + * $ACE_ROOT/bin/generate_export_file.pl + * + * @param EXPORT_NAME The export macro name prefix. + * @param SERVICE_CLASS The name of the class implementing the service. + */ +#define ACE_STATIC_SVC_DECLARE_EXPORT(EXPORT_NAME,SERVICE_CLASS) \ +extern EXPORT_NAME##_Export ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS; + +/// Define the data structure used to register a statically linked +/// service into the Service Configurator. +/** + * The service configurator requires several arguments to build and + * control an statically linked service, including its name, the + * factory function used to construct the service, and some flags. + * All those parameters are configured in a single structure, an + * instance of this structure is statically initialized using the + * following macro. + * + * @param SERVICE_CLASS The name of the class that implements the + * service, must be derived (directly or indirectly) from + * ACE_Service_Object. + * @param NAME The name for this service, this name is used by the + * service configurator to match configuration options provided in + * the svc.conf file. + * @param TYPE The type of object. Objects can be streams or service + * objects. Please read the ACE_Service_Configurator and ASX + * documentation for more details. + * @param FN The name of the factory function, usually the + * ACE_SVC_NAME macro can be used to generate the name. The + * factory function is often defined using ACE_FACTORY_DECLARE and + * ACE_FACTORY_DEFINE. + * @param FLAGS Flags to control the ownership and lifecycle of the + * object. Please read the ACE_Service_Configurator documentation + * for more details. + * @param ACTIVE If not zero then a thread will be dedicate to the + * service. Please read the ACE_Service_Configurator documentation + * for more details. + */ +# define ACE_STATIC_SVC_DEFINE(SERVICE_CLASS, NAME, TYPE, FN, FLAGS, ACTIVE) \ +ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS = { NAME, TYPE, FN, FLAGS, ACTIVE }; + +/// Automatically register a service with the service configurator +/** + * In some applications the services must be automatically registered + * with the service configurator, before main() starts. + * The ACE_STATIC_SVC_REQUIRE macro defines a class whose constructor + * register the service, it also defines a static instance of that + * class to ensure that the service is registered before main. + * + * On platforms that lack adequate support for static C++ objects the + * macro ACE_STATIC_SVC_REGISTER can be used to explicitly register + * the service. + * + * @todo One class per-Service_Object seems wasteful. It should be + * possible to define a single class and re-use it for all the + * service objects, just by passing the Service_Descriptor as an + * argument to the constructor. + */ +#if defined(ACE_LACKS_STATIC_CONSTRUCTORS) +# define ACE_STATIC_SVC_REQUIRE(SERVICE_CLASS)\ +class ACE_Static_Svc_##SERVICE_CLASS {\ +public:\ + ACE_Static_Svc_##SERVICE_CLASS() { \ + ACE_Service_Config::insert (\ + &ace_svc_desc_##SERVICE_CLASS); \ + } \ +}; +#define ACE_STATIC_SVC_REGISTER(SERVICE_CLASS)\ +ACE_Static_Svc_##SERVICE_CLASS ace_static_svc_##SERVICE_CLASS + +#else /* !ACE_LACKS_STATIC_CONSTRUCTORS */ + +# define ACE_STATIC_SVC_REQUIRE(SERVICE_CLASS)\ +class ACE_Static_Svc_##SERVICE_CLASS {\ +public:\ + ACE_Static_Svc_##SERVICE_CLASS() { \ + ACE_Service_Config::insert (\ + &ace_svc_desc_##SERVICE_CLASS); \ + } \ +};\ +static ACE_Static_Svc_##SERVICE_CLASS ace_static_svc_##SERVICE_CLASS; +#define ACE_STATIC_SVC_REGISTER(SERVICE_CLASS) do {} while (0) + +#endif /* !ACE_LACKS_STATIC_CONSTRUCTORS */ + +// Preprocessor symbols will not be expanded if they are +// concatenated. Force the preprocessor to expand them during the +// argument prescan by calling a macro that itself calls another that +// performs the actual concatenation. +#define ACE_PREPROC_CONCATENATE_IMPL(A,B) A ## B +#define ACE_PREPROC_CONCATENATE(A,B) ACE_PREPROC_CONCATENATE_IMPL(A,B) + +#if defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1 +// Preprocessor symbols will not be expanded if they are +// concatenated. Force the preprocessor to expand them during the +// argument prescan by calling a macro that itself calls another that +// performs the actual concatenation. +# define ACE_MAKE_SVC_CONFIG_FUNCTION_NAME(PREFIX,VERSIONED_NAMESPACE,SERVICE_CLASS) PREFIX ## _ ## VERSIONED_NAMESPACE ## _ ## SERVICE_CLASS +#else +# define ACE_MAKE_SVC_CONFIG_FUNCTION_NAME(PREFIX,VERSIONED_NAMESPACE,SERVICE_CLASS) PREFIX ## _ ## SERVICE_CLASS +#endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */ + +#define ACE_MAKE_SVC_CONFIG_FACTORY_NAME(VERSIONED_NAMESPACE,SERVICE_CLASS) ACE_MAKE_SVC_CONFIG_FUNCTION_NAME(_make,VERSIONED_NAMESPACE,SERVICE_CLASS) +#define ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(VERSIONED_NAMESPACE,SERVICE_CLASS) ACE_MAKE_SVC_CONFIG_FUNCTION_NAME(_gobble,VERSIONED_NAMESPACE,SERVICE_CLASS) + + +/// Declare the factory method used to create dynamically loadable +/// services. +/** + * Once the service implementation is dynamically loaded the Service + * Configurator uses a factory method to create the object. + * This macro declares such a factory function with the proper + * interface and export macros. + * Normally used in the header file that declares the service + * implementation. + * + * @param CLS must match the prefix of the export macro used for this + * service. + * @param SERVICE_CLASS must match the name of the class that + * implements the service. + * + */ +# define ACE_FACTORY_DECLARE(CLS,SERVICE_CLASS) \ +extern "C" CLS##_Export ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object * \ +ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (ACE_Service_Object_Exterminator *); + +/// Define the factory method (and destructor) for a dynamically +/// loadable service. +/** + * Use with arguments matching ACE_FACTORY_DECLARE. + * Normally used in the .cpp file that defines the service + * implementation. + * + * This macro defines both the factory method and the function used to + * cleanup the service object. + * + * If this macro is used to define a factory function that need not be + * exported (for example, in a static service situation), CLS can be + * specified as ACE_Local_Service. + */ +# define ACE_Local_Service_Export + +#if defined (ACE_OPENVMS) +# define ACE_PREPROC_STRINGIFY(A) #A +# define ACE_MAKE_SVC_REGISTRAR_ARG(A) ACE_PREPROC_STRINGIFY(A), (void*)&A +# define ACE_FACTORY_DEFINE(CLS,SERVICE_CLASS) \ +void ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (void *p) { \ + ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object * _p = \ + static_cast< ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *> (p); \ + ACE_ASSERT (_p != 0); \ + delete _p; } \ +extern "C" CLS##_Export ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *\ +ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (ACE_Service_Object_Exterminator *gobbler) \ +{ \ + ACE_TRACE (#SERVICE_CLASS); \ + if (gobbler != 0) \ + *gobbler = (ACE_Service_Object_Exterminator) ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS); \ + return new SERVICE_CLASS; \ +} \ +ACE_Dynamic_Svc_Registrar ace_svc_reg_##SERVICE_CLASS \ + (ACE_MAKE_SVC_REGISTRAR_ARG(ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS))); +#else +# define ACE_FACTORY_DEFINE(CLS,SERVICE_CLASS) \ +void ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (void *p) { \ + ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object * _p = \ + static_cast< ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *> (p); \ + ACE_ASSERT (_p != 0); \ + delete _p; } \ +extern "C" CLS##_Export ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *\ +ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (ACE_Service_Object_Exterminator *gobbler) \ +{ \ + ACE_TRACE (#SERVICE_CLASS); \ + if (gobbler != 0) \ + *gobbler = (ACE_Service_Object_Exterminator) ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS); \ + return new SERVICE_CLASS; \ +} +#endif + +/** + * For service classes scoped within namespaces, use this macro in + * place of ACE_FACTORY_DEFINE. The third argument in this case is + * the fully scoped name of the class as it is to be + * instantiated. For example, given: + * namespace ACE + * { + * namespace Foo + * { + * class Bar : public ACE_Service_Object + * {}; + * }; + * }; + * + * ACE_FACTORY_DECLARE(ACE,ACE_Foo_Bar) + * + * you would then use: + * + * ACE_FACTORY_NAMESPACE_DEFINE(ACE,ACE_Foo_Bar,ACE::Foo::Bar) + * + * Note that in this example, the ACE_FACTORY_DECLARE is done outside + * the namespace scope. Then, the SERVICE_CLASS name is the same as + * the fully scoped class name, but with '::' replaced with '_'. Doing + * this will ensure unique generated signatures for the various C + * style functions. + */ +#if defined (ACE_OPENVMS) +# define ACE_PREPROC_STRINGIFY(A) #A +# define ACE_MAKE_SVC_REGISTRAR_ARG(A) ACE_PREPROC_STRINGIFY(A), (void*)&A +# define ACE_FACTORY_NAMESPACE_DEFINE(CLS,SERVICE_CLASS,NAMESPACE_CLASS) \ +void ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (void *p) { \ + ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object * _p = \ + static_cast< ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *> (p); \ + ACE_ASSERT (_p != 0); \ + delete _p; } \ +extern "C" CLS##_Export ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *\ +ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (ACE_Service_Object_Exterminator *gobbler) \ +{ \ + ACE_TRACE (#SERVICE_CLASS); \ + if (gobbler != 0) \ + *gobbler = (ACE_Service_Object_Exterminator) ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS); \ + return new NAMESPACE_CLASS; \ +} \ +ACE_Dynamic_Svc_Registrar ace_svc_reg_##SERVICE_CLASS \ + (ACE_MAKE_SVC_REGISTRAR_ARG(ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS))); +#else +# define ACE_FACTORY_NAMESPACE_DEFINE(CLS,SERVICE_CLASS,NAMESPACE_CLASS) \ +void ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (void *p) { \ + ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object * _p = \ + static_cast< ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *> (p); \ + ACE_ASSERT (_p != 0); \ + delete _p; } \ +extern "C" CLS##_Export ACE_VERSIONED_NAMESPACE_NAME::ACE_Service_Object *\ +ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) (ACE_Service_Object_Exterminator *gobbler) \ +{ \ + ACE_TRACE (#SERVICE_CLASS); \ + if (gobbler != 0) \ + *gobbler = (ACE_Service_Object_Exterminator) ACE_MAKE_SVC_CONFIG_GOBBLER_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS); \ + return new NAMESPACE_CLASS; \ +} +#endif + +/// The canonical name for a service factory method +# define ACE_SVC_NAME(SERVICE_CLASS) ACE_MAKE_SVC_CONFIG_FACTORY_NAME(ACE_VERSIONED_NAMESPACE_NAME,SERVICE_CLASS) + +/// The canonical way to invoke (i.e. construct) a service factory +/// method. +#define ACE_SVC_INVOKE(SERVICE_CLASS) ACE_SVC_NAME(SERVICE_CLASS) (0) + +//@} + +/** @name Helper macros for services defined in the netsvcs library. + * + * The ACE services defined in netsvcs use this helper macros for + * simplicity. + * + */ +//@{ +# define ACE_SVC_FACTORY_DECLARE(X) ACE_FACTORY_DECLARE (ACE_Svc, X) +# define ACE_SVC_FACTORY_DEFINE(X) ACE_FACTORY_DEFINE (ACE_Svc, X) +//@} + +#if defined (ACE_WIN32) +// These are used in SPIPE_Acceptor/Connector, but are ignored at runtime. +# if defined (ACE_HAS_WINCE) +# if !defined (PIPE_TYPE_MESSAGE) +# define PIPE_TYPE_MESSAGE 0 +# endif +# if !defined (PIPE_READMODE_MESSAGE) +# define PIPE_READMODE_MESSAGE 0 +# endif +# if !defined (PIPE_WAIT) +# define PIPE_WAIT 0 +# endif +# endif /* ACE_HAS_WINCE */ +#else /* !ACE_WIN32 */ +// Add some typedefs and macros to enhance Win32 conformance... +# if !defined (LPSECURITY_ATTRIBUTES) +# define LPSECURITY_ATTRIBUTES int +# endif /* !defined LPSECURITY_ATTRIBUTES */ +# if !defined (GENERIC_READ) +# define GENERIC_READ 0 +# endif /* !defined GENERIC_READ */ +# if !defined (FILE_SHARE_READ) +# define FILE_SHARE_READ 0 +# endif /* !defined FILE_SHARE_READ */ +# if !defined (OPEN_EXISTING) +# define OPEN_EXISTING 0 +# endif /* !defined OPEN_EXISTING */ +# if !defined (FILE_ATTRIBUTE_NORMAL) +# define FILE_ATTRIBUTE_NORMAL 0 +# endif /* !defined FILE_ATTRIBUTE_NORMAL */ +# if !defined (MAXIMUM_WAIT_OBJECTS) +# define MAXIMUM_WAIT_OBJECTS 0 +# endif /* !defined MAXIMUM_WAIT_OBJECTS */ +# if !defined (FILE_FLAG_OVERLAPPED) +# define FILE_FLAG_OVERLAPPED 0 +# endif /* !defined FILE_FLAG_OVERLAPPED */ +# if !defined (FILE_FLAG_SEQUENTIAL_SCAN) +# define FILE_FLAG_SEQUENTIAL_SCAN 0 +# endif /* FILE_FLAG_SEQUENTIAL_SCAN */ +# if !defined(FILE_FLAG_WRITE_THROUGH) +# define FILE_FLAG_WRITE_THROUGH 0 +# endif /* !defined FILE_FLAG_WRITE_THROUGH */ +# if !defined(PIPE_WAIT) +# define PIPE_WAIT 0 +# endif /* !defined PIPE_WAIT */ +# if !defined(PIPE_NOWAIT) +# define PIPE_NOWAIT 0 +# endif /* !defined PIPE_WAIT */ +# if !defined(PIPE_READMODE_BYTE) +# define PIPE_READMODE_BYTE 0 +# endif /* !defined PIPE_READMODE_BYTE */ +# if !defined(PIPE_READMODE_MESSAGE) +# define PIPE_READMODE_MESSAGE 0 +# endif /* !defined PIPE_READMODE_MESSAGE */ +# if !defined(PIPE_TYPE_BYTE) +# define PIPE_TYPE_BYTE 0 +# endif /* !defined PIPE_TYPE_BYTE */ +# if !defined(PIPE_TYPE_MESSAGE) +# define PIPE_TYPE_MESSAGE 0 +# endif /* !defined PIPE_TYPE_MESSAGE */ +#endif /* ACE_WIN32 */ + + +// Some useful abstrations for expressions involving +// ACE_Allocator.malloc (). The difference between ACE_NEW_MALLOC* +// with ACE_ALLOCATOR* is that they call constructors also. + +#include "ace/OS_Errno.h" /* Need errno and ENOMEM */ + +# define ACE_ALLOCATOR_RETURN(POINTER,ALLOCATOR,RET_VAL) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \ + } while (0) +# define ACE_ALLOCATOR(POINTER,ALLOCATOR) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return; } \ + } while (0) +# define ACE_ALLOCATOR_NORETURN(POINTER,ALLOCATOR) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; } \ + } while (0) + +# define ACE_NEW_MALLOC_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,RET_VAL) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \ + else { (void) new (POINTER) CONSTRUCTOR; } \ + } while (0) +# define ACE_NEW_MALLOC(POINTER,ALLOCATOR,CONSTRUCTOR) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return;} \ + else { (void) new (POINTER) CONSTRUCTOR; } \ + } while (0) +# define ACE_NEW_MALLOC_NORETURN(POINTER,ALLOCATOR,CONSTRUCTOR) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM;} \ + else { (void) new (POINTER) CONSTRUCTOR; } \ + } while (0) + +/* ACE_Metrics */ +#if defined ACE_LACKS_ARRAY_PLACEMENT_NEW +# define ACE_NEW_MALLOC_ARRAY_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT,RET_VAL) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \ + else { for (u_int i = 0; i < COUNT; ++i) \ + {(void) new (POINTER) CONSTRUCTOR; ++POINTER;} \ + POINTER -= COUNT;} \ + } while (0) +# define ACE_NEW_MALLOC_ARRAY(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return;} \ + else { for (u_int i = 0; i < COUNT; ++i) \ + {(void) new (POINTER) CONSTRUCTOR; ++POINTER;} \ + POINTER -= COUNT;} \ + } while (0) +#else /* ! defined ACE_LACKS_ARRAY_PLACEMENT_NEW */ +# define ACE_NEW_MALLOC_ARRAY_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT,RET_VAL) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \ + else { (void) new (POINTER) CONSTRUCTOR [COUNT]; } \ + } while (0) +# define ACE_NEW_MALLOC_ARRAY(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT) \ + do { POINTER = ALLOCATOR; \ + if (POINTER == 0) { errno = ENOMEM; return;} \ + else { (void) new (POINTER) CONSTRUCTOR [COUNT]; } \ + } while (0) +#endif /* defined ACE_LACKS_ARRAY_PLACEMENT_NEW */ + +// This is being placed here temporarily to help stablelize the builds, but will +// be moved out along with the above macros as part of the subsetting. dhinton +#if !defined (ACE_LACKS_NEW_H) +# if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +# include /**/ +# else +# include /**/ +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ +#endif /* ! ACE_LACKS_NEW_H */ + +# define ACE_NOOP(x) + +#if defined (ACE_WIN32) && defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) +# define ACE_SEH_TRY __try +# define ACE_SEH_EXCEPT(X) __except(X) +# define ACE_SEH_FINALLY __finally +#else /* !ACE_WIN32 */ +# define ACE_SEH_TRY if (1) +# define ACE_SEH_EXCEPT(X) while (0) +# define ACE_SEH_FINALLY if (1) +#endif /* ACE_WIN32 */ + +// These should probably be put into a seperate header. + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +# if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +// Handle ACE_Message_Queue. +# define ACE_SYNCH_DECL class _ACE_SYNCH +# define ACE_SYNCH_USE _ACE_SYNCH +# define ACE_SYNCH_MUTEX_T typename _ACE_SYNCH::MUTEX +# define ACE_SYNCH_CONDITION_T typename _ACE_SYNCH::CONDITION +# define ACE_SYNCH_SEMAPHORE_T typename _ACE_SYNCH::SEMAPHORE + +// Handle ACE_Malloc* +# define ACE_MEM_POOL_1 class _ACE_MEM_POOL +# define ACE_MEM_POOL_2 _ACE_MEM_POOL +# define ACE_MEM_POOL _ACE_MEM_POOL +# define ACE_MEM_POOL_OPTIONS typename _ACE_MEM_POOL::OPTIONS + +// Handle ACE_Svc_Handler +# define ACE_PEER_STREAM_1 class _ACE_PEER_STREAM +# define ACE_PEER_STREAM_2 _ACE_PEER_STREAM +# define ACE_PEER_STREAM _ACE_PEER_STREAM +# define ACE_PEER_STREAM_ADDR typename _ACE_PEER_STREAM::PEER_ADDR + +// Handle ACE_Acceptor +# define ACE_PEER_ACCEPTOR_1 class _ACE_PEER_ACCEPTOR +# define ACE_PEER_ACCEPTOR_2 _ACE_PEER_ACCEPTOR +# define ACE_PEER_ACCEPTOR _ACE_PEER_ACCEPTOR +# define ACE_PEER_ACCEPTOR_ADDR typename _ACE_PEER_ACCEPTOR::PEER_ADDR + +// Handle ACE_Connector +# define ACE_PEER_CONNECTOR_1 class _ACE_PEER_CONNECTOR +# define ACE_PEER_CONNECTOR_2 _ACE_PEER_CONNECTOR +# define ACE_PEER_CONNECTOR _ACE_PEER_CONNECTOR +# define ACE_PEER_CONNECTOR_ADDR typename ACE_PEER_CONNECTOR::PEER_ADDR +# define ACE_PEER_CONNECTOR_ADDR_ANY ACE_PEER_ADDR_TYPEDEF::sap_any + +// Handle ACE_SOCK_* +# define ACE_SOCK_ACCEPTOR ACE_SOCK_Acceptor +# define ACE_SOCK_CONNECTOR ACE_SOCK_Connector +# define ACE_SOCK_STREAM ACE_SOCK_Stream +# define ACE_SOCK_DGRAM ACE_SOCK_Dgram +# define ACE_SOCK_DGRAM_BCAST ACE_SOCK_Dgram_Bcast +# define ACE_SOCK_DGRAM_MCAST ACE_SOCK_Dgram_Mcast + +// Handle ACE_SOCK_SEQPACK_* +# define ACE_SOCK_SEQPACK_ACCEPTOR ACE_SOCK_SEQPACK_Acceptor +# define ACE_SOCK_SEQPACK_CONNECTOR ACE_SOCK_SEQPACK_Connector +# define ACE_SOCK_SEQPACK_ASSOCIATION ACE_SOCK_SEQPACK_Association + +// Handle ACE_MEM_* +# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor +# define ACE_MEM_CONNECTOR ACE_MEM_Connector +# define ACE_MEM_STREAM ACE_MEM_Stream + +// Handle ACE_LSOCK_* +# define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor +# define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector +# define ACE_LSOCK_STREAM ACE_LSOCK_Stream + +// Handle ACE_TLI_* +# define ACE_TLI_ACCEPTOR ACE_TLI_Acceptor +# define ACE_TLI_CONNECTOR ACE_TLI_Connector +# define ACE_TLI_STREAM ACE_TLI_Stream + +// Handle ACE_SPIPE_* +# define ACE_SPIPE_ACCEPTOR ACE_SPIPE_Acceptor +# define ACE_SPIPE_CONNECTOR ACE_SPIPE_Connector +# define ACE_SPIPE_STREAM ACE_SPIPE_Stream + +// Handle ACE_UPIPE_* +# define ACE_UPIPE_ACCEPTOR ACE_UPIPE_Acceptor +# define ACE_UPIPE_CONNECTOR ACE_UPIPE_Connector +# define ACE_UPIPE_STREAM ACE_UPIPE_Stream + +// Handle ACE_FILE_* +# define ACE_FILE_CONNECTOR ACE_FILE_Connector +# define ACE_FILE_STREAM ACE_FILE_IO + +// Handle ACE_*_Memory_Pool. +# define ACE_MMAP_MEMORY_POOL ACE_MMAP_Memory_Pool +# define ACE_LITE_MMAP_MEMORY_POOL ACE_Lite_MMAP_Memory_Pool +# define ACE_SBRK_MEMORY_POOL ACE_Sbrk_Memory_Pool +# define ACE_SHARED_MEMORY_POOL ACE_Shared_Memory_Pool +# define ACE_LOCAL_MEMORY_POOL ACE_Local_Memory_Pool +# define ACE_PAGEFILE_MEMORY_POOL ACE_Pagefile_Memory_Pool + +# else /* TEMPLATES are broken in some form or another (i.e., most C++ compilers) */ + +// Handle ACE_Message_Queue. +# if defined (ACE_HAS_OPTIMIZED_MESSAGE_QUEUE) +# define ACE_SYNCH_DECL class _ACE_SYNCH_MUTEX_T, class _ACE_SYNCH_CONDITION_T, class _ACE_SYNCH_SEMAPHORE_T +# define ACE_SYNCH_USE _ACE_SYNCH_MUTEX_T, _ACE_SYNCH_CONDITION_T, _ACE_SYNCH_SEMAPHORE_T +# else +# define ACE_SYNCH_DECL class _ACE_SYNCH_MUTEX_T, class _ACE_SYNCH_CONDITION_T +# define ACE_SYNCH_USE _ACE_SYNCH_MUTEX_T, _ACE_SYNCH_CONDITION_T +# endif /* ACE_HAS_OPTIMIZED_MESSAGE_QUEUE */ +# define ACE_SYNCH_MUTEX_T _ACE_SYNCH_MUTEX_T +# define ACE_SYNCH_CONDITION_T _ACE_SYNCH_CONDITION_T +# define ACE_SYNCH_SEMAPHORE_T _ACE_SYNCH_SEMAPHORE_T + +// Handle ACE_Malloc* +# define ACE_MEM_POOL_1 class _ACE_MEM_POOL, class _ACE_MEM_POOL_OPTIONS +# define ACE_MEM_POOL_2 _ACE_MEM_POOL, _ACE_MEM_POOL_OPTIONS +# define ACE_MEM_POOL _ACE_MEM_POOL +# define ACE_MEM_POOL_OPTIONS _ACE_MEM_POOL_OPTIONS + +// Handle ACE_Svc_Handler +# define ACE_PEER_STREAM_1 class _ACE_PEER_STREAM, class _ACE_PEER_ADDR +# define ACE_PEER_STREAM_2 _ACE_PEER_STREAM, _ACE_PEER_ADDR +# define ACE_PEER_STREAM _ACE_PEER_STREAM +# define ACE_PEER_STREAM_ADDR _ACE_PEER_ADDR + +// Handle ACE_Acceptor +# define ACE_PEER_ACCEPTOR_1 class _ACE_PEER_ACCEPTOR, class _ACE_PEER_ADDR +# define ACE_PEER_ACCEPTOR_2 _ACE_PEER_ACCEPTOR, _ACE_PEER_ADDR +# define ACE_PEER_ACCEPTOR _ACE_PEER_ACCEPTOR +# define ACE_PEER_ACCEPTOR_ADDR _ACE_PEER_ADDR + +// Handle ACE_Connector +# define ACE_PEER_CONNECTOR_1 class _ACE_PEER_CONNECTOR, class _ACE_PEER_ADDR +# define ACE_PEER_CONNECTOR_2 _ACE_PEER_CONNECTOR, _ACE_PEER_ADDR +# define ACE_PEER_CONNECTOR _ACE_PEER_CONNECTOR +# define ACE_PEER_CONNECTOR_ADDR _ACE_PEER_ADDR +# define ACE_PEER_CONNECTOR_ADDR_ANY ACE_PEER_CONNECTOR_ADDR::sap_any + +// Handle ACE_SOCK_* +# define ACE_SOCK_ACCEPTOR ACE_SOCK_Acceptor, ACE_INET_Addr +# define ACE_SOCK_CONNECTOR ACE_SOCK_Connector, ACE_INET_Addr +# define ACE_SOCK_STREAM ACE_SOCK_Stream, ACE_INET_Addr +# define ACE_SOCK_DGRAM ACE_SOCK_Dgram, ACE_INET_Addr +# define ACE_SOCK_DGRAM_BCAST ACE_SOCK_Dgram_Bcast, ACE_INET_Addr +# define ACE_SOCK_DGRAM_MCAST ACE_SOCK_Dgram_Mcast, ACE_INET_Addr + +// Handle ACE_SOCK_SEQPACK_* +# define ACE_SOCK_SEQPACK_ACCEPTOR ACE_SOCK_SEQPACK_Acceptor, ACE_Multihomed_INET_Addr +# define ACE_SOCK_SEQPACK_CONNECTOR ACE_SOCK_SEQPACK_Connector, ACE_Multihomed_INET_Addr +# define ACE_SOCK_SEQPACK_ASSOCIATION ACE_SOCK_SEQPACK_Association, ACE_Multihomed_INET_Addr + +// Handle ACE_MEM_* +# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor, ACE_MEM_Addr +# define ACE_MEM_CONNECTOR ACE_MEM_Connector, ACE_INET_Addr +# define ACE_MEM_STREAM ACE_MEM_Stream, ACE_INET_Addr + +// Handle ACE_LSOCK_* +# define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor, ACE_UNIX_Addr +# define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector, ACE_UNIX_Addr +# define ACE_LSOCK_STREAM ACE_LSOCK_Stream, ACE_UNIX_Addr + +// Handle ACE_TLI_* +# define ACE_TLI_ACCEPTOR ACE_TLI_Acceptor, ACE_INET_Addr +# define ACE_TLI_CONNECTOR ACE_TLI_Connector, ACE_INET_Addr +# define ACE_TLI_STREAM ACE_TLI_Stream, ACE_INET_Addr + +// Handle ACE_SPIPE_* +# define ACE_SPIPE_ACCEPTOR ACE_SPIPE_Acceptor, ACE_SPIPE_Addr +# define ACE_SPIPE_CONNECTOR ACE_SPIPE_Connector, ACE_SPIPE_Addr +# define ACE_SPIPE_STREAM ACE_SPIPE_Stream, ACE_SPIPE_Addr + +// Handle ACE_UPIPE_* +# define ACE_UPIPE_ACCEPTOR ACE_UPIPE_Acceptor, ACE_SPIPE_Addr +# define ACE_UPIPE_CONNECTOR ACE_UPIPE_Connector, ACE_SPIPE_Addr +# define ACE_UPIPE_STREAM ACE_UPIPE_Stream, ACE_SPIPE_Addr + +// Handle ACE_FILE_* +# define ACE_FILE_CONNECTOR ACE_FILE_Connector, ACE_FILE_Addr +# define ACE_FILE_STREAM ACE_FILE_IO, ACE_FILE_Addr + +// Handle ACE_*_Memory_Pool. +# define ACE_MMAP_MEMORY_POOL ACE_MMAP_Memory_Pool, ACE_MMAP_Memory_Pool_Options +# define ACE_LITE_MMAP_MEMORY_POOL ACE_Lite_MMAP_Memory_Pool, ACE_MMAP_Memory_Pool_Options +# define ACE_SBRK_MEMORY_POOL ACE_Sbrk_Memory_Pool, ACE_Sbrk_Memory_Pool_Options +# define ACE_SHARED_MEMORY_POOL ACE_Shared_Memory_Pool, ACE_Shared_Memory_Pool_Options +# define ACE_LOCAL_MEMORY_POOL ACE_Local_Memory_Pool, ACE_Local_Memory_Pool_Options +# define ACE_PAGEFILE_MEMORY_POOL ACE_Pagefile_Memory_Pool, ACE_Pagefile_Memory_Pool_Options +# endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + +// Work around compilers that don't like in-class static integral +// constants. Constants in this case are meant to be compile-time +// constants so that they may be used as template arguments, for +// example. BOOST provides a similar macro. +#ifndef ACE_LACKS_STATIC_IN_CLASS_CONSTANTS +# define ACE_STATIC_CONSTANT(TYPE, ASSIGNMENT) static TYPE const ASSIGNMENT +#else +# define ACE_STATIC_CONSTANT(TYPE, ASSIGNMENT) enum { ASSIGNMENT } +#endif /* !ACE_LACKS_STATIC_IN_CLASS_CONSTANTS */ + +#include /**/ "ace/post.h" + +#endif /*ACE_GLOBAL_MACROS_H*/ diff --git a/dep/ACE_wrappers/ace/Guard_T.cpp b/dep/ACE_wrappers/ace/Guard_T.cpp new file mode 100644 index 000000000..a21fc2e2f --- /dev/null +++ b/dep/ACE_wrappers/ace/Guard_T.cpp @@ -0,0 +1,61 @@ +// $Id: Guard_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_GUARD_T_CPP +#define ACE_GUARD_T_CPP + +#include "ace/Guard_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Guard_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_HAS_DUMP) +# include "ace/Log_Msg.h" +#endif /* ACE_HAS_DUMP */ + +// **************************************************************** + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// ACE_ALLOC_HOOK_DEFINE(ACE_Guard) + +template void +ACE_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Guard::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("mutex_ = %x\n"), this->lock_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("owner_ = %d\n"), this->owner_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// ACE_ALLOC_HOOK_DEFINE(ACE_Write_Guard) + +template void +ACE_Write_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Write_Guard::dump"); + ACE_Guard::dump (); +#endif /* ACE_HAS_DUMP */ +} + +// ACE_ALLOC_HOOK_DEFINE(ACE_Read_Guard) + +template void +ACE_Read_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_Read_Guard::dump"); + ACE_Guard::dump (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_GUARD_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Guard_T.h b/dep/ACE_wrappers/ace/Guard_T.h new file mode 100644 index 000000000..46d555505 --- /dev/null +++ b/dep/ACE_wrappers/ace/Guard_T.h @@ -0,0 +1,365 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Guard_T.h + * + * $Id: Guard_T.h 82508 2008-08-05 13:52:48Z johnnyw $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_GUARD_T_H +#define ACE_GUARD_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/OS_NS_Thread.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Guard + * + * @brief This data structure is meant to be used within a method or + * function... It performs automatic aquisition and release of + * a parameterized synchronization object . + * + * The class given as an actual parameter must provide at + * the very least the , , , and + * methods. + */ +template +class ACE_Guard +{ +public: + + // = Initialization and termination methods. + ACE_Guard (ACE_LOCK &l); + + /// Implicitly and automatically acquire (or try to acquire) the + /// lock. If @a block is non-0 then the , else + /// it. + ACE_Guard (ACE_LOCK &l, bool block); + + /// Initialise the guard without implicitly acquiring the lock. The + /// parameter indicates whether the guard should release + /// the lock implicitly on destruction. The parameter is + /// ignored and is used here to disambiguate with the preceding + /// constructor. + ACE_Guard (ACE_LOCK &l, bool block, int become_owner); + + /// Implicitly release the lock. + ~ACE_Guard (void); + + // = Lock accessors. + + /// Explicitly acquire the lock. + int acquire (void); + + /// Conditionally acquire the lock (i.e., won't block). + int tryacquire (void); + + /// Explicitly release the lock, but only if it is held! + int release (void); + + /// Relinquish ownership of the lock so that it is not released + /// implicitly in the destructor. + void disown (void); + + // = Utility methods. + /// 1 if locked, 0 if couldn't acquire the lock + /// (errno will contain the reason for this). + int locked (void) const; + + /// Explicitly remove the lock. + int remove (void); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + + /// Helper, meant for subclass only. + ACE_Guard (ACE_LOCK *lock): lock_ (lock), owner_ (0) {} + + /// Pointer to the ACE_LOCK we're guarding. + ACE_LOCK *lock_; + + /// Keeps track of whether we acquired the lock or failed. + int owner_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Guard &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Guard (const ACE_Guard &)) +}; + +/** + * @class ACE_Write_Guard + * + * @brief This class is similar to class ACE_Guard, though it + * acquires/releases a write lock automatically (naturally, the + * it is instantiated with must support the appropriate + * API). + */ +template +class ACE_Write_Guard : public ACE_Guard +{ +public: + // = Initialization method. + + /// Implicitly and automatically acquire a write lock. + ACE_Write_Guard (ACE_LOCK &m); + + /// Implicitly and automatically acquire (or try to acquire) a write + /// lock. + ACE_Write_Guard (ACE_LOCK &m, bool block); + + // = Lock accessors. + + /// Explicitly acquire the write lock. + int acquire_write (void); + + /// Explicitly acquire the write lock. + int acquire (void); + + /// Conditionally acquire the write lock (i.e., won't block). + int tryacquire_write (void); + + /// Conditionally acquire the write lock (i.e., won't block). + int tryacquire (void); + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +/** + * @class ACE_Read_Guard + * + * @brief This class is similar to class ACE_Guard, though it + * acquires/releases a read lock automatically (naturally, the + * it is instantiated with must support the appropriate + * API). + */ +template +class ACE_Read_Guard : public ACE_Guard +{ +public: + // = Initialization methods. + + /// Implicitly and automatically acquire a read lock. + ACE_Read_Guard (ACE_LOCK& m); + + /// Implicitly and automatically acquire (or try to acquire) a read + /// lock. + ACE_Read_Guard (ACE_LOCK &m, bool block); + + // = Lock accessors. + + /// Explicitly acquire the read lock. + int acquire_read (void); + + /// Explicitly acquire the read lock. + int acquire (void); + + /// Conditionally acquire the read lock (i.e., won't block). + int tryacquire_read (void); + + /// Conditionally acquire the read lock (i.e., won't block). + int tryacquire (void); + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) + +#define ACE_TSS_Guard ACE_Guard +#define ACE_TSS_Write_GUARD ACE_Write_Guard +#define ACE_TSS_Read_GUARD ACE_Read_Guard + +#else + /* ACE platform supports some form of threading and + thread-specific storage. */ + +/** + * @class ACE_TSS_Guard + * + * @brief This data structure is meant to be used within a method or + * function... It performs automatic aquisition and release of + * a synchronization object. Moreover, it ensures that the lock + * is released even if a thread exits via ! + */ +template +class ACE_TSS_Guard +{ +public: + // = Initialization and termination methods. + + /// Implicitly and automatically acquire the thread-specific lock. + ACE_TSS_Guard (ACE_LOCK &lock, bool block = true); + + /// Implicitly release the thread-specific lock. + ~ACE_TSS_Guard (void); + + // = Lock accessors. + + /// Explicitly acquire the thread-specific lock. + int acquire (void); + + /// Conditionally acquire the thread-specific lock (i.e., won't + /// block). + int tryacquire (void); + + /// Explicitly release the thread-specific lock. + int release (void); + + // = Utility methods. + /// Explicitly release the thread-specific lock. + int remove (void); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + /// Helper, meant for subclass only. + ACE_TSS_Guard (void); + + /// Initialize the key. + void init_key (void); + + /// Called when thread exits to clean up the lock. + static void cleanup (void *ptr); + + /// Thread-specific key... + ACE_thread_key_t key_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Guard &)) + ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Guard (const ACE_TSS_Guard &)) +}; + +/** + * @class ACE_TSS_Write_Guard + * + * @brief This class is similar to class ACE_TSS_Guard, though it + * acquires/releases a write-lock automatically (naturally, the + * ACE_LOCK it is instantiated with must support the appropriate + * API). + */ +template +class ACE_TSS_Write_Guard : public ACE_TSS_Guard +{ +public: + // = Initialization method. + + /// Implicitly and automatically acquire the thread-specific write lock. + ACE_TSS_Write_Guard (ACE_LOCK &lock, bool block = true); + + // = Lock accessors. + + /// Explicitly acquire the thread-specific write lock. + int acquire_write (void); + + /// Explicitly acquire the thread-specific write lock. + int acquire (void); + + /// Conditionally acquire the thread-specific write lock (i.e., won't block). + int tryacquire_write (void); + + /// Conditionally acquire the thread-specific write lock (i.e., won't block). + int tryacquire (void); + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +/** + * @class ACE_TSS_Read_Guard + * + * @brief This class is similar to class , though it + * acquires/releases a read lock automatically (naturally, the + * it is instantiated with must support the + * appropriate API). + */ +template +class ACE_TSS_Read_Guard : public ACE_TSS_Guard +{ +public: + // = Initialization method. + /// Implicitly and automatically acquire the thread-specific read lock. + ACE_TSS_Read_Guard (ACE_LOCK &lock, bool block = true); + + // = Lock accessors. + /// Explicitly acquire the thread-specific read lock. + int acquire_read (void); + + /// Explicitly acquire the thread-specific read lock. + int acquire (void); + + /// Conditionally acquire the thread-specific read lock (i.e., won't + /// block). + int tryacquire_read (void); + + /// Conditionally acquire the thread-specific read lock (i.e., won't + /// block). + int tryacquire (void); + + // = Utility methods. + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#endif /* !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Guard_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Guard_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Guard_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_GUARD_T_H */ diff --git a/dep/ACE_wrappers/ace/Guard_T.inl b/dep/ACE_wrappers/ace/Guard_T.inl new file mode 100644 index 000000000..5fb22b3ba --- /dev/null +++ b/dep/ACE_wrappers/ace/Guard_T.inl @@ -0,0 +1,170 @@ +// -*- C++ -*- +// +// $Id: Guard_T.inl 82508 2008-08-05 13:52:48Z johnnyw $ + +#include "ace/RW_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE int +ACE_Guard::acquire (void) +{ + return this->owner_ = this->lock_->acquire (); +} + +template ACE_INLINE int +ACE_Guard::tryacquire (void) +{ + return this->owner_ = this->lock_->tryacquire (); +} + +template ACE_INLINE int +ACE_Guard::release (void) +{ + if (this->owner_ == -1) + return -1; + else + { + this->owner_ = -1; + return this->lock_->release (); + } +} + +template ACE_INLINE +ACE_Guard::ACE_Guard (ACE_LOCK &l) + : lock_ (&l), + owner_ (0) +{ + this->acquire (); +} + +template ACE_INLINE +ACE_Guard::ACE_Guard (ACE_LOCK &l, bool block) + : lock_ (&l), + owner_ (0) +{ + if (block) + this->acquire (); + else + this->tryacquire (); +} + +template ACE_INLINE +ACE_Guard::ACE_Guard (ACE_LOCK &l, bool /* block */, int become_owner) + : lock_ (&l), + owner_ (become_owner == 0 ? -1 : 0) +{ +} + +// Implicitly and automatically acquire (or try to acquire) the +// lock. + +template ACE_INLINE +ACE_Guard::~ACE_Guard (void) +{ + this->release (); +} + +template ACE_INLINE int +ACE_Guard::locked (void) const +{ + return this->owner_ != -1; +} + +template ACE_INLINE int +ACE_Guard::remove (void) +{ + return this->lock_->remove (); +} + +template ACE_INLINE void +ACE_Guard::disown (void) +{ + this->owner_ = -1; +} + +template ACE_INLINE +ACE_Write_Guard::ACE_Write_Guard (ACE_LOCK &m) + : ACE_Guard (&m) +{ + this->acquire_write (); +} + +template ACE_INLINE int +ACE_Write_Guard::acquire_write (void) +{ + return this->owner_ = this->lock_->acquire_write (); +} + +template ACE_INLINE int +ACE_Write_Guard::acquire (void) +{ + return this->owner_ = this->lock_->acquire_write (); +} + +template ACE_INLINE int +ACE_Write_Guard::tryacquire_write (void) +{ + return this->owner_ = this->lock_->tryacquire_write (); +} + +template ACE_INLINE int +ACE_Write_Guard::tryacquire (void) +{ + return this->owner_ = this->lock_->tryacquire_write (); +} + +template ACE_INLINE +ACE_Write_Guard::ACE_Write_Guard (ACE_LOCK &m, + bool block) + : ACE_Guard (&m) +{ + if (block) + this->acquire_write (); + else + this->tryacquire_write (); +} + +template ACE_INLINE int +ACE_Read_Guard::acquire_read (void) +{ + return this->owner_ = this->lock_->acquire_read (); +} + +template ACE_INLINE int +ACE_Read_Guard::acquire (void) +{ + return this->owner_ = this->lock_->acquire_read (); +} + +template ACE_INLINE int +ACE_Read_Guard::tryacquire_read (void) +{ + return this->owner_ = this->lock_->tryacquire_read (); +} + +template ACE_INLINE int +ACE_Read_Guard::tryacquire (void) +{ + return this->owner_ = this->lock_->tryacquire_read (); +} + +template ACE_INLINE +ACE_Read_Guard::ACE_Read_Guard (ACE_LOCK &m) + : ACE_Guard (&m) +{ + this->acquire_read (); +} + +template ACE_INLINE +ACE_Read_Guard::ACE_Read_Guard (ACE_LOCK &m, + bool block) + : ACE_Guard (&m) +{ + if (block) + this->acquire_read (); + else + this->tryacquire_read (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Handle_Gobbler.h b/dep/ACE_wrappers/ace/Handle_Gobbler.h new file mode 100644 index 000000000..9d6890a03 --- /dev/null +++ b/dep/ACE_wrappers/ace/Handle_Gobbler.h @@ -0,0 +1,68 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Handle_Gobbler.h + * + * $Id: Handle_Gobbler.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kirthika Parameswaran + * @author Irfan Pyarali + */ +//============================================================================= + + +#ifndef ACE_HANDLE_GOBBLER_H +#define ACE_HANDLE_GOBBLER_H +#include /**/ "ace/pre.h" + +#include "ace/Handle_Set.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Handle_Gobbler + * + * @brief This class gobbles up handles. + * + * This is useful when we need to control the number of handles + * available for a process. This class is mostly used for + * testing purposes. + */ +class ACE_Handle_Gobbler +{ +public: + + /// Destructor. Cleans up any remaining handles. + inline ~ACE_Handle_Gobbler (void); + + /** + * Handles are opened continously until the process runs out of + * them, and then handles are closed + * (freed) thereby making them usable in the future. + */ + inline int consume_handles (size_t n_handles_to_keep_available); + + /// Free up @a n_handles. + inline int free_handles (size_t n_handles); + + /// All remaining handles are closed. + inline void close_remaining_handles (void); + +private: + typedef ACE_Handle_Set HANDLE_SET; + + /// The container which holds the open descriptors. + HANDLE_SET handle_set_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include "ace/Handle_Gobbler.inl" + +#include /**/ "ace/post.h" +#endif /* ACE_HANDLE_GOBBLER_H */ diff --git a/dep/ACE_wrappers/ace/Handle_Gobbler.inl b/dep/ACE_wrappers/ace/Handle_Gobbler.inl new file mode 100644 index 000000000..4b81218e6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Handle_Gobbler.inl @@ -0,0 +1,78 @@ +// -*- C++ -*- +// +// $Id: Handle_Gobbler.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Since this is only included in Handle_Gobbler.h, these should be +// inline, not ACE_INLINE. +// FUZZ: disable check_for_inline + +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_fcntl.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +inline void +ACE_Handle_Gobbler::close_remaining_handles (void) +{ + ACE_Handle_Set_Iterator iter (this->handle_set_); + for (ACE_HANDLE h = iter (); h != ACE_INVALID_HANDLE; h = iter ()) + ACE_OS::close (h); +} + +inline +ACE_Handle_Gobbler::~ACE_Handle_Gobbler (void) +{ + this->close_remaining_handles (); +} + +inline int +ACE_Handle_Gobbler::free_handles (size_t n_handles) +{ + ACE_Handle_Set_Iterator iter (this->handle_set_); + for (ACE_HANDLE h = iter (); + h != ACE_INVALID_HANDLE && n_handles > 0; + --n_handles, h = iter ()) + ACE_OS::close (h); + + return 0; +} + +inline int +ACE_Handle_Gobbler::consume_handles (size_t n_handles_to_keep_available) +{ + int result = 0; + +#if defined(ACE_WIN32) + // On Win32, this style of gobbling doesn't seem to work. + ACE_UNUSED_ARG(n_handles_to_keep_available); + +#else + + while (1) + { + ACE_HANDLE handle = ACE_OS::open (ACE_DEV_NULL, O_WRONLY); + + if (handle == ACE_INVALID_HANDLE) + { + if (ACE::out_of_handles (errno)) + { + result = this->free_handles (n_handles_to_keep_available); + break; + } + else + { + result = -1; + break; + } + } + if (handle >= FD_SETSIZE) + break; + this->handle_set_.set_bit (handle); + } + +#endif /* ACE_WIN32 */ + + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Handle_Ops.cpp b/dep/ACE_wrappers/ace/Handle_Ops.cpp new file mode 100644 index 000000000..0ec856cf1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Handle_Ops.cpp @@ -0,0 +1,48 @@ +// $Id: Handle_Ops.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Handle_Ops.h" + +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/Time_Value.h" + +ACE_RCSID (ace, + Handle_Ops, + "$Id: Handle_Ops.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_HANDLE +ACE::handle_timed_open (ACE_Time_Value *timeout, + const ACE_TCHAR *name, + int flags, + int perms, + LPSECURITY_ATTRIBUTES sa) +{ + ACE_TRACE ("ACE::handle_timed_open"); + + if (timeout != 0) + { +#if !defined (ACE_WIN32) + // On Win32, ACE_NONBLOCK gets recognized as O_WRONLY so we + // don't use it there + flags |= ACE_NONBLOCK; +#endif /* ACE_WIN32 */ + + // Open the named pipe or file using non-blocking mode... + ACE_HANDLE const handle = ACE_OS::open (name, flags, perms, sa); + + if (handle == ACE_INVALID_HANDLE + && (errno == EWOULDBLOCK + && (timeout->sec () > 0 || timeout->usec () > 0))) + // This expression checks if we were polling. + errno = ETIMEDOUT; + + return handle; + } + else + return ACE_OS::open (name, flags, perms, sa); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Handle_Ops.h b/dep/ACE_wrappers/ace/Handle_Ops.h new file mode 100644 index 000000000..c615380f8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Handle_Ops.h @@ -0,0 +1,50 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Handle_Ops.h + * + * $Id: Handle_Ops.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Handle operations. + */ +//============================================================================= + +#ifndef ACE_HANDLE_OPS_H +#define ACE_HANDLE_OPS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +// = Operations on HANDLEs. +namespace ACE +{ + /** + * Wait up to @a timeout amount of time to actively open a device. + * This method doesn't perform the @c connect, it just does the + * timed wait. + */ + extern ACE_Export ACE_HANDLE handle_timed_open ( + ACE_Time_Value *timeout, + const ACE_TCHAR *name, + int flags, + int perms, + LPSECURITY_ATTRIBUTES sa = 0); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_HANDLE_OPS_H */ diff --git a/dep/ACE_wrappers/ace/Handle_Set.cpp b/dep/ACE_wrappers/ace/Handle_Set.cpp new file mode 100644 index 000000000..8eb5186cc --- /dev/null +++ b/dep/ACE_wrappers/ace/Handle_Set.cpp @@ -0,0 +1,570 @@ +// Handle_Set.cpp +// $Id: Handle_Set.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Handle_Set.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Handle_Set.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/OS_NS_string.h" + +ACE_RCSID(ace, Handle_Set, "$Id: Handle_Set.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set) + + // ACE_MSB_MASK is only used here. + // This needs to go here to avoid overflow problems on some compilers. +#if defined (ACE_WIN32) + // Does ACE_WIN32 have an fd_mask? +# define ACE_MSB_MASK (~(1 << (NFDBITS - 1))) +#else /* ! ACE_WIN32 */ +# define ACE_MSB_MASK (~((fd_mask) 1 << (NFDBITS - 1))) +#endif /* ! ACE_WIN32 */ + +#if defined (__BORLANDC__) && !defined (ACE_WIN32) +// The Borland C++ compiler on Linux also doesn't have fds_bits, but has __fds_bits. +#define fds_bits __fds_bits +#endif + +#if defined (linux) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !defined (_XOPEN_SOURCE) + // XPG4.2 requires the fds_bits member name, so it is not enabled by + // default on Linux/glibc-2.1.x systems. Instead use "__fds_bits." + // Ugly, but "what are you going to do?" 8-) +#define fds_bits __fds_bits +#endif /* linux && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !_XOPEN_SOURCE */ + +void +ACE_Handle_Set::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Handle_Set::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsize_ = %d"), this->size_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmax_handle_ = %d"), this->max_handle_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n[ "))); + +#if defined (ACE_WIN32) + for (size_t i = 0; i < (size_t) this->mask_.fd_count + 1; i++) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" %x "), this->mask_.fd_array[i])); +#else /* !ACE_WIN32 */ + for (ACE_HANDLE i = 0; i < this->max_handle_ + 1; i++) + if (this->is_set (i)) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" %d "), i)); +#endif /* ACE_WIN32 */ + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" ]\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Table that maps bytes to counts of the enabled bits in each value +// from 0 to 255, +// +// nbits_[0] == 0 +// +// because there are no bits enabled for the value 0. +// +// nbits_[5] == 2 +// +// because there are 2 bits enabled in the value 5, i.e., it's +// 101 in binary. + +const char ACE_Handle_Set::nbits_[256] = +{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; + +// Constructor, initializes the bitmask to all 0s. + +ACE_Handle_Set::ACE_Handle_Set (void) +{ + ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set"); + this->reset (); +} + +ACE_Handle_Set::ACE_Handle_Set (const fd_set &fd_mask) +{ + ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set"); + this->reset (); + ACE_OS::memcpy ((void *) &this->mask_, + (void *) &fd_mask, + sizeof this->mask_); +#if !defined (ACE_WIN32) + this->sync (ACE_Handle_Set::MAXSIZE); +#if defined (ACE_HAS_BIG_FD_SET) + this->min_handle_ = 0; +#endif /* ACE_HAS_BIG_FD_SET */ +#endif /* !ACE_WIN32 */ +} + +// Counts the number of bits enabled in N. Uses a table lookup to +// speed up the count. + +int +ACE_Handle_Set::count_bits (u_long n) +{ + + ACE_TRACE ("ACE_Handle_Set::count_bits"); +#if defined (ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT) + register int rval = 0; + + // Count the number of enabled bits in . This algorithm is very + // fast, i.e., O(enabled bits in n). + + for (register u_long m = n; + m != 0; + m &= m - 1) + rval++; + + return rval; +#else + return (ACE_Handle_Set::nbits_[n & 0xff] + + ACE_Handle_Set::nbits_[(n >> 8) & 0xff] + + ACE_Handle_Set::nbits_[(n >> 16) & 0xff] + + ACE_Handle_Set::nbits_[(n >> 24) & 0xff]); +#endif /* ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT */ +} + +#if defined (ACE_HAS_BIG_FD_SET) +// Find the bit position counting from right to left worst case +// (1<<31) is 8. + +int +ACE_Handle_Set::bitpos (u_long bit) +{ + register int l = 0; + register u_long n = bit - 1; + + // This is a fast count method when have the most significative bit. + + while (n >> 8) + { + n >>= 8; + l += 8; + } + + // Is greater than 15? + if (n & 16) + { + n >>= 4; + l += 4; + } + + // Count number remaining bits. + while (n != 0) + { + n &= n - 1; + l++; + } + return l; +} +#endif /* ACE_HAS_BIG_FD_SET */ + +// Synchronize the underlying FD_SET with the MAX_FD and the SIZE. + +#if defined (ACE_USE_SHIFT_FOR_EFFICIENCY) +// These don't work because shifting right 3 bits is not the same as +// dividing by 3, e.g., dividing by 8 requires shifting right 3 bits. +// In order to do the shift, we need to calculate the number of bits +// at some point. +#define ACE_DIV_BY_WORDSIZE(x) ((x) >> ((int) ACE_Handle_Set::WORDSIZE)) +#define ACE_MULT_BY_WORDSIZE(x) ((x) << ((int) ACE_Handle_Set::WORDSIZE)) +#else +#define ACE_DIV_BY_WORDSIZE(x) ((x) / ((int) ACE_Handle_Set::WORDSIZE)) +#define ACE_MULT_BY_WORDSIZE(x) ((x) * ((int) ACE_Handle_Set::WORDSIZE)) +#endif /* ACE_USE_SHIFT_FOR_EFFICIENCY */ + +void +ACE_Handle_Set::sync (ACE_HANDLE max) +{ + ACE_TRACE ("ACE_Handle_Set::sync"); +#if !defined (ACE_WIN32) + fd_mask *maskp = (fd_mask *)(this->mask_.fds_bits); + this->size_ = 0; + + for (int i = ACE_DIV_BY_WORDSIZE (max - 1); + i >= 0; + i--) + this->size_ += ACE_Handle_Set::count_bits (maskp[i]); + + this->set_max (max); +#else + ACE_UNUSED_ARG (max); +#endif /* !ACE_WIN32 */ +} + +// Resets the MAX_FD after a clear of the original MAX_FD. + +void +ACE_Handle_Set::set_max (ACE_HANDLE current_max) +{ + ACE_TRACE ("ACE_Handle_Set::set_max"); +#if !defined(ACE_WIN32) + fd_mask * maskp = (fd_mask *)(this->mask_.fds_bits); + + if (this->size_ == 0) + this->max_handle_ = ACE_INVALID_HANDLE; + else + { + int i; + + for (i = ACE_DIV_BY_WORDSIZE (current_max - 1); + maskp[i] == 0; + i--) + continue; +#if defined (ACE_TANDEM_NSK_BIT_ORDER) + // bits are in reverse order, MSB (sign bit) = bit 0. + this->max_handle_ = ACE_MULT_BY_WORDSIZE (i); + for (fd_mask val = maskp[i]; + (val & ACE_MSB_MASK) != 0; + val = (val << 1)) + ++this->max_handle_; +#elif 1 /* !defined(ACE_HAS_BIG_FD_SET) */ + this->max_handle_ = ACE_MULT_BY_WORDSIZE (i); + for (fd_mask val = maskp[i]; + (val & ~1) != 0; // This obscure code is needed since "bit 0" is in location 1... + val = (val >> 1) & ACE_MSB_MASK) + ++this->max_handle_; +#else + register u_long val = this->mask_.fds_bits[i]; + this->max_handle_ = ACE_MULT_BY_WORDSIZE (i) + + ACE_Handle_Set::bitpos(val & ~(val - 1)); +#endif /* 1 */ + } + + // Do some sanity checking... + if (this->max_handle_ >= ACE_Handle_Set::MAXSIZE) + this->max_handle_ = ACE_Handle_Set::MAXSIZE - 1; +#else + ACE_UNUSED_ARG (current_max); +#endif /* !ACE_WIN32 */ +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set_Iterator) + +void +ACE_Handle_Set_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Handle_Set_Iterator::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); +#if defined(ACE_WIN32) || !defined(ACE_HAS_BIG_FD_SET) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhandle_index_ = %d"), this->handle_index_)); +#elif defined(ACE_HAS_BIG_FD_SET) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_max_ = %d"), this->word_max_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_val_ = %d"), this->word_val_)); +#endif + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nword_num_ = %d"), this->word_num_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_HANDLE +ACE_Handle_Set_Iterator::operator () (void) +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::operator"); +#if defined (ACE_WIN32) + if (this->handle_index_ < this->handles_.mask_.fd_count) + // Return the handle and advance the iterator. + return (ACE_HANDLE) this->handles_.mask_.fd_array[this->handle_index_++]; + else + return ACE_INVALID_HANDLE; + +#elif !defined (ACE_HAS_BIG_FD_SET) /* !ACE_WIN32 */ + // No sense searching further than the max_handle_ + 1; + ACE_HANDLE maxhandlep1 = this->handles_.max_handle_ + 1; + + // HP-UX 11 plays some games with the fd_mask type - fd_mask is + // defined as an int_32t, but the fds_bits is an array of longs. + // This makes plainly indexing through the array by hand tricky, + // since the FD_* macros treat the array as int32_t. So the bits + // are in the right place for int32_t, even though the array is + // long. This, they say, is to preserve the same in-memory layout + // for 32-bit and 64-bit processes. So, we play the same game as + // the FD_* macros to get the bits right. On all other systems, + // this amounts to practically a NOP, since this is what would have + // been done anyway, without all this type jazz. + fd_mask * maskp = (fd_mask *)(this->handles_.mask_.fds_bits); + + if (this->handle_index_ >= maxhandlep1) + // We've seen all the handles we're interested in seeing for this + // iterator. + return ACE_INVALID_HANDLE; + else + { + ACE_HANDLE result = this->handle_index_; + + // Increment the iterator and advance to the next bit in this + // word. + this->handle_index_++; +#if defined (ACE_TANDEM_NSK_BIT_ORDER) + // bits are in reverse order, MSB (sign bit) = bit 0. + this->word_val_ = (this->word_val_ << 1); +# else + this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK; +# endif /* ACE_TANDEM_NSK_BIT_ORDER */ + + // If we've examined all the bits in this word, we'll go onto + // the next word. + + if (this->word_val_ == 0) + { + // Start the handle_index_ at the beginning of the next word + // and then loop until we've found the first non-zero bit or + // we run past the of the bitset. + + for (this->handle_index_ = ACE_MULT_BY_WORDSIZE(++this->word_num_); + this->handle_index_ < maxhandlep1 + && maskp[this->word_num_] == 0; + this->word_num_++) + this->handle_index_ += ACE_Handle_Set::WORDSIZE; + + // If the bit index becomes >= the maxhandlep1 that means + // there weren't any more bits set that we want to consider. + // Therefore, we'll just store the maxhandlep1, which will + // cause to return + // immediately next time it's called. + if (this->handle_index_ >= maxhandlep1) + { + this->handle_index_ = maxhandlep1; + return result; + } + else + // Load the bits of the next word. + this->word_val_ = maskp[this->word_num_]; + } + + // Loop until we get to have its least significant + // bit enabled, keeping track of which this + // represents (this information is used by subsequent calls to + // ). + +#if defined (ACE_TANDEM_NSK_BIT_ORDER) + // bits are in reverse order, MSB (sign bit) = bit 0. + for (; + this->word_val_ > 0; + this->word_val_ = (this->word_val_ << 1)) + this->handle_index_++; +# else + for (; + ACE_BIT_DISABLED (this->word_val_, 1); + this->handle_index_++) + this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK; +# endif /* ACE_TANDEM_NSK_BIT_ORDER */ + + return result; + } +#else /* !ACE_HAS_BIG_FD_SET */ + // Find the first word in fds_bits with bit on + register u_long lsb = this->word_val_; + + if (lsb == 0) + { + do + { + // We have exceeded the word count in Handle_Set? + if (++this->word_num_ >= this->word_max_) + return ACE_INVALID_HANDLE; + + lsb = this->handles_.mask_.fds_bits[this->word_num_]; + } + while (lsb == 0); + + // Set index to word boundary. + this->handle_index_ = ACE_MULT_BY_WORDSIZE (this->word_num_); + + // Put new word_val. + this->word_val_ = lsb; + + // Find the least significative bit. + lsb &= ~(lsb - 1); + + // Remove least significative bit. + this->word_val_ ^= lsb; + + // Save to calculate bit distance. + this->oldlsb_ = lsb; + + // Move index to least significative bit. + while (lsb >>= 1) + this->handle_index_++; + } + else + { + // Find the least significative bit. + lsb &= ~(lsb - 1); + + // Remove least significative bit. + this->word_val_ ^= lsb; + + register u_long n = lsb - this->oldlsb_; + + // Move index to bit distance between new lsb and old lsb. + do + { + this->handle_index_++; + n &= n >> 1; + } + while (n != 0); + + this->oldlsb_ = lsb; + } + + return this->handle_index_; +#endif /* ACE_WIN32 */ +} + +ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator (const ACE_Handle_Set &hs) + : handles_ (hs), +#if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32) + handle_index_ (0), + word_num_ (-1) +#elif defined (ACE_HAS_BIG_FD_SET) + oldlsb_ (0), + word_max_ (hs.max_handle_ == ACE_INVALID_HANDLE + ? 0 + : ((ACE_DIV_BY_WORDSIZE (hs.max_handle_)) + 1)) +#endif /* ACE_HAS_BIG_FD_SET */ +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator"); +#if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET) + // No sense searching further than the max_handle_ + 1; + ACE_HANDLE maxhandlep1 = + this->handles_.max_handle_ + 1; + + fd_mask *maskp = + (fd_mask *)(this->handles_.mask_.fds_bits); + + // Loop until we've found the first non-zero bit or we run past the + // of the bitset. + while (this->handle_index_ < maxhandlep1 + && maskp[++this->word_num_] == 0) + this->handle_index_ += ACE_Handle_Set::WORDSIZE; + + // If the bit index becomes >= the maxhandlep1 that means there + // weren't any bits set. Therefore, we'll just store the + // maxhandlep1, which will cause to return + // immediately. + if (this->handle_index_ >= maxhandlep1) + this->handle_index_ = maxhandlep1; + else + // Loop until we get to have its least significant bit + // enabled, keeping track of which this represents + // (this information is used by ). +#if defined (ACE_TANDEM_NSK_BIT_ORDER) + // bits are in reverse order, MSB (sign bit) = bit 0. + for (this->word_val_ = maskp[this->word_num_]; + this->word_val_ > 0; + this->word_val_ = (this->word_val_ << 1)) + this->handle_index_++; +# else + for (this->word_val_ = maskp[this->word_num_]; + ACE_BIT_DISABLED (this->word_val_, 1) + && this->handle_index_ < maxhandlep1; + this->handle_index_++) + this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK; +# endif /* ACE_TANDEM_NSK_BIT_ORDER */ +#elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET) + if (this->word_max_==0) + { + this->word_num_ = -1; + this->word_val_ = 0; + } + else + { + this->word_num_ = + ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1; + this->word_val_ = 0; + } +#endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */ +} + + +void +ACE_Handle_Set_Iterator::reset_state (void) +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::reset_state"); + +#if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32) + this->handle_index_ = 0; + this->word_num_ = -1; +#elif defined (ACE_HAS_BIG_FD_SET) + this->oldlsb_ = 0; + this->word_max_ = + this->handles_.max_handle_ == ACE_INVALID_HANDLE ? 0 + : ((ACE_DIV_BY_WORDSIZE (this->handles_.max_handle_)) + 1); +#endif /* ACE_HAS_BIG_FD_SET */ + +#if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET) + // No sense searching further than the max_handle_ + 1; + ACE_HANDLE maxhandlep1 = + this->handles_.max_handle_ + 1; + + fd_mask *maskp = + (fd_mask *)(this->handles_.mask_.fds_bits); + + // Loop until we've found the first non-zero bit or we run past the + // of the bitset. + while (this->handle_index_ < maxhandlep1 + && maskp[++this->word_num_] == 0) + this->handle_index_ += ACE_Handle_Set::WORDSIZE; + + // If the bit index becomes >= the maxhandlep1 that means there + // weren't any bits set. Therefore, we'll just store the + // maxhandlep1, which will cause to return + // immediately. + if (this->handle_index_ >= maxhandlep1) + this->handle_index_ = maxhandlep1; + else + // Loop until we get to have its least significant bit + // enabled, keeping track of which this represents + // (this information is used by ). +#if defined (ACE_TANDEM_NSK_BIT_ORDER) + // bits are in reverse order, MSB (sign bit) = bit 0. + for (this->word_val_ = maskp[this->word_num_]; + this->word_val_ > 0; + this->word_val_ = (this->word_val_ << 1)) + this->handle_index_++; +# else + for (this->word_val_ = maskp[this->word_num_]; + ACE_BIT_DISABLED (this->word_val_, 1) + && this->handle_index_ < maxhandlep1; + this->handle_index_++) + this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK; +# endif /* ACE_TANDEM_NSK_BIT_ORDER */ +#elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET) + if (this->word_max_==0) + { + this->word_num_ = -1; + this->word_val_ = 0; + } + else + { + this->word_num_ = + ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1; + this->word_val_ = 0; + } +#endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Handle_Set.h b/dep/ACE_wrappers/ace/Handle_Set.h new file mode 100644 index 000000000..a29672221 --- /dev/null +++ b/dep/ACE_wrappers/ace/Handle_Set.h @@ -0,0 +1,240 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Handle_Set.h + * + * $Id: Handle_Set.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_HANDLE_SET_H +#define ACE_HANDLE_SET_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_select.h" +#include "ace/os_include/os_limits.h" + +#if defined (__QNX__) + typedef long fd_mask; +#endif /* __QNX__ */ + +// Default size of the ACE Reactor. +#if defined (FD_SETSIZE) + int const ACE_FD_SETSIZE = FD_SETSIZE; +#else /* !FD_SETSIZE */ +# define ACE_FD_SETSIZE FD_SETSIZE +#endif /* ACE_FD_SETSIZE */ + +#if !defined (ACE_DEFAULT_SELECT_REACTOR_SIZE) +# define ACE_DEFAULT_SELECT_REACTOR_SIZE ACE_FD_SETSIZE +#endif /* ACE_DEFAULT_SELECT_REACTOR_SIZE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Handle_Set + * + * @brief C++ wrapper facade for the socket @c fd_set abstraction. + * + * This abstraction is a very efficient wrapper facade over + * @c fd_set. In particular, no range checking is performed, so + * it's important not to set or clear bits that are outside the + * @c ACE_DEFAULT_SELECT_REACTOR_SIZE. + */ +class ACE_Export ACE_Handle_Set +{ +public: + friend class ACE_Handle_Set_Iterator; + + // = Initialization and termination. + + enum + { + MAXSIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE + }; + + // = Initialization methods. + /// Constructor, initializes the bitmask to all 0s. + ACE_Handle_Set (void); + + /** + * Constructor, initializes the handle set from a given mask. + */ + ACE_Handle_Set (const fd_set &mask); + + // = Methods for manipulating bitsets. + /// Initialize the bitmask to all 0s and reset the associated fields. + void reset (void); + + /** + * Checks whether @a handle is enabled. No range checking is + * performed so @a handle must be less than + * @c ACE_DEFAULT_SELECT_REACTOR_SIZE. + */ + int is_set (ACE_HANDLE handle) const; + + /// Enables the @a handle. No range checking is performed so @a handle + /// must be less than @c ACE_DEFAULT_SELECT_REACTOR_SIZE. + void set_bit (ACE_HANDLE handle); + + /// Disables the @a handle. No range checking is performed so + /// @a handle must be less than @c ACE_DEFAULT_SELECT_REACTOR_SIZE. + void clr_bit (ACE_HANDLE handle); + + /// Returns a count of the number of enabled bits. + int num_set (void) const; + + /// Returns the number of the large bit. + ACE_HANDLE max_set (void) const; + + /** + * Rescan the underlying @c fd_set up to handle @a max to find the new + * (highest bit set) and (how many bits set) values. + * This is useful for evaluating the changes after the handle set has + * been manipulated in some way other than member functions; for example, + * after + ACE_Select_Reactor_Handle_Set dispatch_set_; + + /// Tracks handles that are waited for by . + ACE_Select_Reactor_Handle_Set ready_set_; + + /// Defined as a pointer to allow overriding by derived classes... + ACE_Timer_Queue *timer_queue_; + + /// Handle signals without requiring global/static variables. + ACE_Sig_Handler *signal_handler_; + + /// Callback object that unblocks the ACE_Select_Reactor if it's + /// sleeping. + ACE_Reactor_Notify *notify_handler_; + + /// Keeps track of whether we should delete the timer queue (if we + /// didn't create it, then we don't delete it). + bool delete_timer_queue_; + + /// Keeps track of whether we should delete the signal handler (if we + /// didn't create it, then we don't delete it). + bool delete_signal_handler_; + + /// Keeps track of whether we need to delete the notify handler (if + /// we didn't create it, then we don't delete it). + bool delete_notify_handler_; + + /// True if we've been initialized yet... + bool initialized_; + + /// Restart the event-loop method automatically when + /// . + + if (number_of_active_handles == 0) + { + do + { + if (this->timer_queue_ == 0) + return 0; + + this_timeout = + this->timer_queue_->calculate_timeout (max_wait_time, + &timer_buf); +#ifdef ACE_WIN32 + // This arg is ignored on Windows and causes pointer + // truncation warnings on 64-bit compiles. + int const width = 0; +#else + int const width = this->handler_rep_.max_handlep1 (); +#endif /* ACE_WIN32 */ + + dispatch_set.rd_mask_ = this->wait_set_.rd_mask_; + dispatch_set.wr_mask_ = this->wait_set_.wr_mask_; + dispatch_set.ex_mask_ = this->wait_set_.ex_mask_; + number_of_active_handles = ACE_OS::select (width, + dispatch_set.rd_mask_, + dispatch_set.wr_mask_, + dispatch_set.ex_mask_, + this_timeout); + } + while (number_of_active_handles == -1 && this->handle_error () > 0); + + if (number_of_active_handles > 0) + { +#if !defined (ACE_WIN32) + // Resynchronize the fd_sets so their "max" is set properly. + dispatch_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ()); + dispatch_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ()); + dispatch_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ()); +#endif /* ACE_WIN32 */ + } + else if (number_of_active_handles == -1) + { + // Normally, select() will reset the bits in dispatch_set + // so that only those filed descriptors that are ready will + // have bits set. However, when an error occurs, the bit + // set remains as it was when the select call was first made. + // Thus, we now have a dispatch_set that has every file + // descriptor that was originally waited for, which is not + // correct. We must clear all the bit sets because we + // have no idea if any of the file descriptors is ready. + // + // NOTE: We dont have a test case to reproduce this + // problem. But pleae dont ignore this and remove it off. + dispatch_set.rd_mask_.reset (); + dispatch_set.wr_mask_.reset (); + dispatch_set.ex_mask_.reset (); + } + } + + // Return the number of events to dispatch. + return number_of_active_handles; +} + +template int +ACE_Select_Reactor_T::dispatch_timer_handlers + (int &number_of_handlers_dispatched) +{ + number_of_handlers_dispatched += this->timer_queue_->expire (); + + return 0; +} + +template int +ACE_Select_Reactor_T::dispatch_notification_handlers + (ACE_Select_Reactor_Handle_Set &dispatch_set, + int &number_of_active_handles, + int &number_of_handlers_dispatched) +{ + // Check to see if the ACE_HANDLE associated with the + // Select_Reactor's notify hook is enabled. If so, it means that + // one or more other threads are trying to update the + // ACE_Select_Reactor_T's internal tables or the notify pipe is + // enabled. We'll handle all these threads and notifications, and + // then break out to continue the event loop. + int const n = + this->notify_handler_->dispatch_notifications (number_of_active_handles, + dispatch_set.rd_mask_); + + if (n == -1) + return -1; + else + { + number_of_handlers_dispatched += n; + number_of_active_handles -= n; + } + + // Same as dispatch_timer_handlers + // No need to do anything with the state changed. That is because + // unbind already handles the case where someone unregister some + // kind of handle and unbind it. (::unbind calls the function + // state_changed () to reflect ant change with that) + // return this->state_changed_ ? -1 : 0; + return 0; +} + +template int +ACE_Select_Reactor_T::dispatch_io_set + (int number_of_active_handles, + int &number_of_handlers_dispatched, + int mask, + ACE_Handle_Set &dispatch_mask, + ACE_Handle_Set &ready_mask, + ACE_EH_PTMF callback) +{ + ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_set"); + ACE_HANDLE handle; + + ACE_Handle_Set_Iterator handle_iter (dispatch_mask); + + while ((handle = handle_iter ()) != ACE_INVALID_HANDLE && + number_of_handlers_dispatched < number_of_active_handles) + { + ++number_of_handlers_dispatched; + + this->notify_handle (handle, + mask, + ready_mask, + this->handler_rep_.find (handle), + callback); + + // clear the bit from that dispatch mask, + // so when we need to restart the iteration (rebuilding the iterator...) + // we will not dispatch the already dispatched handlers + this->clear_dispatch_mask (handle, mask); + + if (this->state_changed_) + { + + handle_iter.reset_state (); + this->state_changed_ = false; + } + } + + return 0; +} + +template int +ACE_Select_Reactor_T::dispatch_io_handlers + (ACE_Select_Reactor_Handle_Set &dispatch_set, + int &number_of_active_handles, + int &number_of_handlers_dispatched) +{ + ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_handlers"); + + // Handle output events (this code needs to come first to handle the + // obscure case of piggy-backed data coming along with the final + // handshake message of a nonblocking connection). + + if (this->dispatch_io_set (number_of_active_handles, + number_of_handlers_dispatched, + ACE_Event_Handler::WRITE_MASK, + dispatch_set.wr_mask_, + this->ready_set_.wr_mask_, + &ACE_Event_Handler::handle_output) == -1) + { + number_of_active_handles -= number_of_handlers_dispatched; + return -1; + } + + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - EXCEPT\n"))); + if (this->dispatch_io_set (number_of_active_handles, + number_of_handlers_dispatched, + ACE_Event_Handler::EXCEPT_MASK, + dispatch_set.ex_mask_, + this->ready_set_.ex_mask_, + &ACE_Event_Handler::handle_exception) == -1) + { + number_of_active_handles -= number_of_handlers_dispatched; + return -1; + } + + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - READ\n"))); + if (this->dispatch_io_set (number_of_active_handles, + number_of_handlers_dispatched, + ACE_Event_Handler::READ_MASK, + dispatch_set.rd_mask_, + this->ready_set_.rd_mask_, + &ACE_Event_Handler::handle_input) == -1) + { + number_of_active_handles -= number_of_handlers_dispatched; + return -1; + } + + number_of_active_handles -= number_of_handlers_dispatched; + return 0; +} + +template int +ACE_Select_Reactor_T::dispatch + (int active_handle_count, + ACE_Select_Reactor_Handle_Set &dispatch_set) +{ + ACE_TRACE ("ACE_Select_Reactor_T::dispatch"); + + int io_handlers_dispatched = 0; + int other_handlers_dispatched = 0; + int signal_occurred = 0; + // The following do/while loop keeps dispatching as long as there + // are still active handles. Note that the only way we should ever + // iterate more than once through this loop is if signals occur + // while we're dispatching other handlers. + + do + { + // We expect that the loop will decrease the number of active + // handles in each iteration. If it does not, then something is + // inconsistent in the state of the Reactor and we should avoid + // the loop. Please read the comments on bug 2540 for more + // details. + int initial_handle_count = active_handle_count; + + // Note that we keep track of changes to our state. If any of + // the dispatch_*() methods below return -1 it means that the + // state has changed as the result of an + // being dispatched. This means that we + // need to bail out and rerun the select() loop since our + // existing notion of handles in may no longer be + // correct. + // + // In the beginning, our state starts out unchanged. After + // every iteration (i.e., due to signals), our state starts out + // unchanged again. + + this->state_changed_ = false; + + // Perform the Template Method for dispatching all the handlers. + + // First check for interrupts. + if (active_handle_count == -1) + { + // Bail out -- we got here since /. Pass over both the *and* the + * @a mask to allow the caller to dictate which + * method the will invoke. The ACE_Time_Value + * indicates how long to blocking trying to notify the + * . If @a timeout == 0, the caller will block until + * action is possible, else will wait until the relative time + * specified in *@a timeout elapses). + */ + virtual int notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, + ACE_Time_Value * = 0); + + /** + * Set the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify pipe before breaking out of its loop. By default, + * this is set to -1, which means "iterate until the pipe is empty." + * Setting this to a value like "1 or 2" will increase "fairness" + * (and thus prevent starvation) at the expense of slightly higher + * dispatching overhead. + */ + virtual void max_notify_iterations (int); + + /** + * Get the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify pipe before breaking out of its loop. + */ + virtual int max_notify_iterations (void); + + /// Get the existing restart value. + virtual int restart (void); + + /// Set a new value for restart and return the original value. + virtual int restart (int r); + + /// Set position that the main ACE_Select_Reactor thread is requeued in the + /// list of waiters during a callback. + virtual void requeue_position (int); + + /// Get position that the main ACE_Select_Reactor thread is requeued in the + /// list of waiters during a callback. + virtual int requeue_position (void); + + // = Low-level wait_set mask manipulation methods. + /// GET/SET/ADD/CLR the dispatch mask "bit" bound with the and + /// @a mask. + virtual int mask_ops (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + int ops); + + /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the + /// and @a mask. + virtual int mask_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops); + + // = Low-level ready_set mask manipulation methods. + /// GET/SET/ADD/CLR the ready "bit" bound with the and @a mask. + virtual int ready_ops (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + int ops); + + /// GET/SET/ADD/CLR the ready "bit" bound with the and @a mask. + virtual int ready_ops (ACE_HANDLE handle, + ACE_Reactor_Mask, + int ops); + + /// Wake up all threads in waiting in the event loop + virtual void wakeup_all_threads (void); + + // = Only the owner thread can perform a . + + /// Set the new owner of the thread and return the old owner. + virtual int owner (ACE_thread_t n_id, ACE_thread_t *o_id = 0); + + /// Return the current owner of the thread. + virtual int owner (ACE_thread_t *); + + // = Miscellaneous Handler operations. + + /** + * Return the Event_Handler associated with . Return 0 if + * is not registered. + */ + virtual ACE_Event_Handler *find_handler (ACE_HANDLE handle); + + /** + * Check to see if is associated with a valid Event_Handler + * bound to @a mask. Return the @a eh associated with this @a handler + * if != 0. + */ + virtual int handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **eh = 0); + + /** + * Check to see if @a signum is associated with a valid Event_Handler + * bound to a signal. Return the associated with this + * handler if != 0. + */ + virtual int handler (int signum, + ACE_Event_Handler ** = 0); + + /// Returns true if we've been successfully initialized, else false. + virtual bool initialized (void); + + /// Returns the current size of the Reactor's internal descriptor + /// table. + virtual size_t size (void) const; + + /** + * Returns a reference to the ACE_Reactor_Token that is + * used to serialize the internal processing logic. + * This can be useful for situations where you need to avoid + * deadlock efficiently when ACE_Event_Handlers are used in + * multiple threads. + */ + virtual ACE_Lock &lock (void); + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Internal methods that do the actual work. + + // All of these methods assume that the token + // lock is held by the public methods that call down to them. + + /// Do the work of actually binding the and with the + /// @a mask. + virtual int register_handler_i (ACE_HANDLE handle, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + + /// Register a set of . + virtual int register_handler_i (const ACE_Handle_Set &handles, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask); + + /// Do the work of actually unbinding the and with the + /// @a mask. + virtual int remove_handler_i (ACE_HANDLE handle, + ACE_Reactor_Mask); + + /// Remove a set of . + virtual int remove_handler_i (const ACE_Handle_Set &handles, + ACE_Reactor_Mask); + + /// Suspend the associated with + virtual int suspend_i (ACE_HANDLE handle); + + /// Check to see if the associated with is + /// suspended. Returns 0 if not, 1 if so. + virtual int is_suspended_i (ACE_HANDLE handle); + + /// Resume the associated with + virtual int resume_i (ACE_HANDLE handle); + + /// Implement the public handler method. + virtual ACE_Event_Handler *find_handler_i (ACE_HANDLE handle); + + /// Implement the public handler method. + virtual int handler_i (ACE_HANDLE handle, + ACE_Reactor_Mask, + ACE_Event_Handler ** = 0); + + /// Implement the public handler method. + virtual int handler_i (int signum, ACE_Event_Handler ** = 0); + + /** + * Check if there are any HANDLEs enabled in the , and + * if so, update the and return the number ready. If + * there aren't any HANDLEs enabled return 0. + */ + virtual int any_ready (ACE_Select_Reactor_Handle_Set &handle_set); + + /// Implement the method, assuming that the Sig_Guard is + /// beign held + virtual int any_ready_i (ACE_Select_Reactor_Handle_Set &handle_set); + + /// Take corrective action when errors occur. + virtual int handle_error (void); + + /// Make sure the handles are all valid. + virtual int check_handles (void); + + /// Wait for events to occur. + virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &, + ACE_Time_Value *); + + // = Dispatching methods. + + /** + * Template Method that dispatches ACE_Event_Handlers for time + * events, I/O events, and signal events. Returns the total number + * of ACE_Event_Handlers that were dispatched or -1 if something + * goes wrong. + */ + virtual int dispatch (int nfound, + ACE_Select_Reactor_Handle_Set &); + + /** + * Dispatch all timer handlers that have expired. Returns -1 if the + * state of the has changed, else 0. + * is set to the number of timer handlers + * dispatched. + */ + virtual int dispatch_timer_handlers (int &number_dispatched); + + /** + * Dispatch any notification handlers. Returns -1 if the state of + * the has changed, else returns number of handlers + * notified. + */ + virtual int dispatch_notification_handlers (ACE_Select_Reactor_Handle_Set &dispatch_set, + int &number_of_active_handles, + int &number_of_handlers_dispatched); + + /** + * Dispatch all the input/output/except handlers that are enabled in + * the . Updates and + * according to the behavior of the + * number Returns -1 if the state of the has changed, + * else 0. + */ + virtual int dispatch_io_handlers (ACE_Select_Reactor_Handle_Set &dispatch_set, + int &number_of_active_handles, + int &number_of_handlers_dispatched); + + /** + * Factors the dispatching of an io handle set (each WRITE, EXCEPT + * or READ set of handles). It updates the + * and invokes this->notify_handle + * for all the handles in using the @a mask, + * and parameters. Must return -1 if + * this->state_changed otherwise it must return 0. + */ + virtual int dispatch_io_set (int number_of_active_handles, + int &number_of_handlers_dispatched, + int mask, + ACE_Handle_Set& dispatch_mask, + ACE_Handle_Set& ready_mask, + ACE_EH_PTMF callback); + + /// Notify the appropriate in the context of the + /// associated with that a particular event has occurred. + virtual void notify_handle (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Handle_Set &, + ACE_Event_Handler *eh, + ACE_EH_PTMF callback); + + /// Enqueue ourselves into the list of waiting threads at the + /// appropriate point specified by . + virtual void renew (void); + + /// Synchronization token for the MT_SAFE ACE_Select_Reactor. + ACE_SELECT_REACTOR_TOKEN token_; + + /// Adapter used to return internal lock to outside world. + ACE_Lock_Adapter lock_adapter_; + + /// Release the token lock when a Win32 structured exception occurs. + int release_token (void); + + /// Stops the VC++ compiler from bitching about exceptions and destructors + int handle_events_i (ACE_Time_Value *max_wait_time = 0); + + /// This flag is used to keep track of whether we are actively handling + /// events or not. + sig_atomic_t deactivated_; + +private: + /// Deny access since member-wise won't work... + ACE_UNIMPLEMENTED_FUNC (ACE_Select_Reactor_T (const ACE_Select_Reactor_T &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Select_Reactor_T &operator= (const ACE_Select_Reactor_T &) ) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Select_Reactor_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Select_Reactor_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Select_Reactor_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_SELECT_REACTOR_T_H */ diff --git a/dep/ACE_wrappers/ace/Select_Reactor_T.inl b/dep/ACE_wrappers/ace/Select_Reactor_T.inl new file mode 100644 index 000000000..05405a5b1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Select_Reactor_T.inl @@ -0,0 +1,236 @@ +// -*- C++ -*- +// +// $Id: Select_Reactor_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Reactor.h" +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_INLINE int +ACE_Select_Reactor_T::resume_handler (ACE_Event_Handler *h) +{ + ACE_TRACE ("ACE_Select_Reactor_T::resume_handler"); + return this->resume_handler (h->get_handle ()); +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::resume_handler (const ACE_Handle_Set &handles) +{ + ACE_TRACE ("ACE_Select_Reactor_T::resume_handler"); + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + + ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1)); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->resume_i (h) == -1) + return -1; + + return 0; +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::suspend_handler (ACE_Event_Handler *h) +{ + ACE_TRACE ("ACE_Select_Reactor_T::suspend_handler"); + return this->suspend_handler (h->get_handle ()); +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::suspend_handler (const ACE_Handle_Set &handles) +{ + ACE_TRACE ("ACE_Select_Reactor_T::suspend_handler"); + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + + ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1)); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->suspend_i (h) == -1) + return -1; + + return 0; +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Select_Reactor_T::register_handler"); + return this->signal_handler_->register_handler (signum, + new_sh, new_disp, + old_sh, old_disp); +} + +#if defined (ACE_WIN32) + +template +ACE_INLINE int +ACE_Select_Reactor_T::register_handler (ACE_Event_Handler *, + ACE_HANDLE ) +{ + // Don't have an implementation for this yet... + ACE_NOTSUP_RETURN (-1); +} + +#endif /* ACE_WIN32 */ + +template +ACE_INLINE int +ACE_Select_Reactor_T::register_handler (ACE_HANDLE , + ACE_HANDLE , + ACE_Event_Handler *, + ACE_Reactor_Mask ) +{ + // Don't have an implementation for this yet... + ACE_NOTSUP_RETURN (-1); +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::handler (int signum, ACE_Event_Handler **handler) +{ + ACE_TRACE ("ACE_Select_Reactor_T::handler"); + return this->handler_i (signum, handler); +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + ACE_TRACE ("ACE_Select_Reactor_T::remove_handler"); + return this->signal_handler_->remove_handler (signum, new_disp, old_disp, sigkey); +} + +template +ACE_INLINE int +ACE_Select_Reactor_T::uses_event_associations (void) +{ + // Since the Select_Reactor does not do any event associations, this + // function always return 0. + return 0; +} + +// = The remaining methods in this file must be called with locks +// held. + +// Performs operations on the "ready" bits. + +template ACE_INLINE int +ACE_Select_Reactor_T::ready_ops (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Select_Reactor_T::ready_ops"); + return this->ready_ops (handler->get_handle (), mask, ops); +} + +// Performs operations on the "dispatch" masks. + +template ACE_INLINE int +ACE_Select_Reactor_T::mask_ops (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Select_Reactor_T::mask_ops"); + return this->mask_ops (handler->get_handle (), mask, ops); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::schedule_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Select_Reactor_T::schedule_wakeup"); + return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::cancel_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Select_Reactor_T::cancel_wakeup"); + return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::schedule_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Select_Reactor_T::schedule_wakeup"); + return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::cancel_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Select_Reactor_T::cancel_wakeup"); + return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK); +} + +template ACE_INLINE ACE_Lock & +ACE_Select_Reactor_T::lock (void) +{ + ACE_TRACE ("ACE_Select_Reactor_T::lock"); + return this->lock_adapter_; +} + +template ACE_INLINE void +ACE_Select_Reactor_T::wakeup_all_threads (void) +{ + // Send a notification, but don't block if there's no one to receive + // it. + this->notify (0, ACE_Event_Handler::NULL_MASK, (ACE_Time_Value *) &ACE_Time_Value::zero); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::alertable_handle_events (ACE_Time_Value *max_wait_time) +{ + return this->handle_events (max_wait_time); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::alertable_handle_events (ACE_Time_Value &max_wait_time) +{ + return this->handle_events (max_wait_time); +} + +template ACE_INLINE int +ACE_Select_Reactor_T::deactivated (void) +{ + return this->deactivated_; +} + +template ACE_INLINE void +ACE_Select_Reactor_T::deactivate (int do_stop) +{ + { + ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN, + ace_mon, + this->token_)); + this->deactivated_ = do_stop; + } + + this->wakeup_all_threads (); +} + +template ACE_INLINE size_t +ACE_Select_Reactor_T::size (void) const +{ + return this->handler_rep_.size (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Semaphore.cpp b/dep/ACE_wrappers/ace/Semaphore.cpp new file mode 100644 index 000000000..b3d6c6638 --- /dev/null +++ b/dep/ACE_wrappers/ace/Semaphore.cpp @@ -0,0 +1,62 @@ +// $Id: Semaphore.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Semaphore.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/ACE.h" + +ACE_RCSID (ace, + Semaphore, + "$Id: Semaphore.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Semaphore) + +void +ACE_Semaphore::dump (void) const +{ +// ACE_TRACE ("ACE_Semaphore::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Semaphore::ACE_Semaphore (unsigned int count, + int type, + const ACE_TCHAR *name, + void *arg, + int max) + : removed_ (false) +{ +// ACE_TRACE ("ACE_Semaphore::ACE_Semaphore"); +#if defined(ACE_LACKS_UNNAMED_SEMAPHORE) +// if the user does not provide a name, we generate a unique name here + ACE_TCHAR iname[ACE_UNIQUE_NAME_LEN]; + if (name == 0) + ACE::unique_name (this, iname, ACE_UNIQUE_NAME_LEN); + if (ACE_OS::sema_init (&this->semaphore_, count, type, + name ? name : iname, + arg, max) != 0) +#else + if (ACE_OS::sema_init (&this->semaphore_, count, type, + name, arg, max) != 0) +#endif + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Semaphore::ACE_Semaphore"))); +} + +ACE_Semaphore::~ACE_Semaphore (void) +{ +// ACE_TRACE ("ACE_Semaphore::~ACE_Semaphore"); + + this->remove (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Semaphore.h b/dep/ACE_wrappers/ace/Semaphore.h new file mode 100644 index 000000000..7c4936abf --- /dev/null +++ b/dep/ACE_wrappers/ace/Semaphore.h @@ -0,0 +1,183 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Semaphore.h + * + * $Id: Semaphore.h 81014 2008-03-19 11:41:31Z johnnyw $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_SEMAPHORE_H +#define ACE_SEMAPHORE_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_Thread.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +/** + * @class ACE_Semaphore + * + * @brief Wrapper for Dijkstra style general semaphores. + */ +class ACE_Export ACE_Semaphore +{ +public: + // = Initialization and termination. + /// Initialize the semaphore, with initial value of "count". + ACE_Semaphore (unsigned int count = 1, // By default make this unlocked. + int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, + void * = 0, + int max = 0x7fffffff); + + /// Implicitly destroy the semaphore. + ~ACE_Semaphore (void); + + /** + * Explicitly destroy the semaphore. Note that only one thread + * should call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Block the thread until the semaphore count becomes + /// greater than 0, then decrement it. + int acquire (void); + + /** + * Block the thread until the semaphore count becomes greater than 0 + * (at which point it is decremented) or until @a tv times out (in + * which case -1 is returned and @c errno == @c ETIME). Note that @a tv + * is assumed to be in "absolute" rather than "relative" time. The + * value of @a tv is updated upon return to show the actual + * (absolute) acquisition time. + * + * @note Solaris threads do not support timed semaphores. + * Therefore, if you're running on Solaris you might want to + * consider using the ACE POSIX pthreads implementation instead, + * which can be enabled by compiling ACE with + * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or + * -DACE_HAS_POSIX_SEM. + */ + int acquire (ACE_Time_Value &tv); + + /** + * If @a tv == 0 then call directly. Otherwise, Block + * the thread until the semaphore count becomes greater than 0 + * (at which point it is decremented) or until @a tv times out (in + * which case -1 is returned and @c errno == @c ETIME). Note that + * <*tv> is assumed to be in "absolute" rather than "relative" time. + * The value of <*tv> is updated upon return to show the actual + * (absolute) acquisition time. + * + * @note Solaris threads do not support timed semaphores. + * Therefore, if you're running on Solaris you might want to + * consider using the ACE POSIX pthreads implementation instead, + * which can be enabled by compiling ACE with + * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or + * -DACE_HAS_POSIX_SEM. */ + int acquire (ACE_Time_Value *tv); + + /** + * Conditionally decrement the semaphore if count is greater than 0 + * (i.e., won't block). Returns -1 on failure. If we "failed" + * because someone else already had the lock, @c errno is set to + * @c EBUSY. + */ + int tryacquire (void); + + /// Increment the semaphore by 1, potentially unblocking a waiting + /// thread. + int release (void); + + /// Increment the semaphore by @a release_count, potentially + /// unblocking waiting threads. + int release (unsigned int release_count); + + /** + * Acquire semaphore ownership. This calls and is only + * here to make the ACE_Semaphore interface consistent with the + * other synchronization APIs. + */ + int acquire_read (void); + + /** + * Acquire semaphore ownership. This calls and is only + * here to make the ACE_Semaphore interface consistent with the + * other synchronization APIs. + */ + int acquire_write (void); + + /** + * Conditionally acquire semaphore (i.e., won't block). This calls + * and is only here to make the ACE_Semaphore + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_read (void); + + /** + * Conditionally acquire semaphore (i.e., won't block). This calls + * and is only here to make the ACE_Semaphore + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_write (void); + + /** + * This is only here to make the ACE_Semaphore + * interface consistent with the other synchronization APIs. + * Assumes the caller has already acquired the semaphore using one of + * the above calls, and returns 0 (success) always. + */ + int tryacquire_write_upgrade (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Return the underlying lock. + const ACE_sema_t &lock (void) const; + +protected: + ACE_sema_t semaphore_; + + /// Keeps track of whether remove() has been called yet to avoid + /// multiple remove() calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// remove () on the same object, which is a bad idea anyway... + bool removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Semaphore &); + ACE_Semaphore (const ACE_Semaphore &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SEMAPHORE_H */ diff --git a/dep/ACE_wrappers/ace/Semaphore.inl b/dep/ACE_wrappers/ace/Semaphore.inl new file mode 100644 index 000000000..e0162dc24 --- /dev/null +++ b/dep/ACE_wrappers/ace/Semaphore.inl @@ -0,0 +1,119 @@ +// -*- C++ -*- +// +// $Id: Semaphore.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE const ACE_sema_t & +ACE_Semaphore::lock (void) const +{ +// ACE_TRACE ("ACE_Semaphore::lock"); + return this->semaphore_; +} + +ACE_INLINE int +ACE_Semaphore::remove (void) +{ +// ACE_TRACE ("ACE_Semaphore::remove"); + int result = 0; + if (!this->removed_) + { + this->removed_ = true; + result = ACE_OS::sema_destroy (&this->semaphore_); + } + return result; +} + +ACE_INLINE int +ACE_Semaphore::acquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::acquire (ACE_Time_Value &tv) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_, tv); +} + +ACE_INLINE int +ACE_Semaphore::acquire (ACE_Time_Value *tv) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_, tv); +} + +ACE_INLINE int +ACE_Semaphore::tryacquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::tryacquire"); + return ACE_OS::sema_trywait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::release (void) +{ +// ACE_TRACE ("ACE_Semaphore::release"); + return ACE_OS::sema_post (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::release (unsigned int release_count) +{ +// ACE_TRACE ("ACE_Semaphore::release"); + return ACE_OS::sema_post (&this->semaphore_, release_count); +} + +// Acquire semaphore ownership. This calls and is only +// here to make the interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::acquire_read (void) +{ + return this->acquire (); +} + +// Acquire semaphore ownership. This calls and is only +// here to make the interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::acquire_write (void) +{ + return this->acquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// and is only here to make the +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::tryacquire_read (void) +{ + return this->tryacquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// and is only here to make the +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::tryacquire_write (void) +{ + return this->tryacquire (); +} + +// This is only here to make the interface consistent +// with the other synchronization APIs. Assumes the caller has +// already acquired the semaphore using one of the above calls, and +// returns 0 (success) always. +ACE_INLINE int +ACE_Semaphore::tryacquire_write_upgrade (void) +{ + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Config.cpp b/dep/ACE_wrappers/ace/Service_Config.cpp new file mode 100644 index 000000000..f0f352ced --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Config.cpp @@ -0,0 +1,619 @@ +// $Id: Service_Config.cpp 81756 2008-05-22 09:47:33Z johnnyw $ + +#include "ace/Service_Config.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Config.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Service_Types.h" +#include "ace/Reactor.h" +#include "ace/Singleton.h" +#include "ace/Service_Repository.h" + +#ifndef ACE_LACKS_UNIX_SIGNALS +# include "ace/Sig_Adapter.h" +#endif /* !ACE_LACKS_UNIX_SIGNALS */ + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Thread.h" +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/Log_Msg.h" +#include "ace/ACE.h" + +ACE_RCSID (ace, + Service_Config, + "$Id: Service_Config.cpp 81756 2008-05-22 09:47:33Z johnnyw $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Threading_Helper::~ACE_Threading_Helper () +{ + ACE_OS::thr_key_detach (this->key_, 0); + ACE_OS::thr_keyfree (this->key_); +} + +ACE_Threading_Helper::ACE_Threading_Helper () + : key_ (ACE_OS::NULL_key) +{ +# if defined (ACE_HAS_TSS_EMULATION) + ACE_Object_Manager::init_tss (); +# endif + + if (ACE_Thread::keycreate (&key_, 0, 0) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Failed to create thread key: %p\n"), + "")); + } +} + +void +ACE_Threading_Helper::set (void* p) +{ + if (ACE_Thread::setspecific (key_, p) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Service Config failed to set thread key value: %p\n"), + "")); +} + +void* +ACE_Threading_Helper::get (void) +{ + void* temp = 0; + if (ACE_Thread::getspecific (key_, &temp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Service Config failed to get thread key value: %p\n"), + ""), + 0); + return temp; +} + +ACE_Threading_Helper::~ACE_Threading_Helper () +{ +} + +ACE_Threading_Helper::ACE_Threading_Helper () +{ +} + +void +ACE_Threading_Helper::set (void*) +{ +} + +void* +ACE_Threading_Helper::get (void) +{ + return ACE_Service_Config::singleton()->instance_.get (); +} + +/** + * @c ACE_Service_Config is supposed to be a Singleton. This is the + * only Configuration Gestalt available for access from static + * initializers at proces start-up time. Using Unmanaged Singleton + * is safer because (a) the Object Manager may not yet be fully initialized + * in the context of a static initializer that uses SC, and (b) because we + * know that upon process exit the SC will still be automaticaly and explicitly + * closed by @c ACE_Object_Manager::fini(). + */ +typedef ACE_Unmanaged_Singleton ACE_SERVICE_CONFIG_SINGLETON; + + +/// ctor +ACE_Service_Config_Guard::ACE_Service_Config_Guard (ACE_Service_Gestalt * psg) + : saved_ (ACE_Service_Config::current ()) +{ + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SCG:") + ACE_TEXT (" - config=%@ repo=%@ superceded by repo=%@\n"), + this, + this->saved_.get (), + this->saved_->repo_, + psg->repo_)); + + // Modify the TSS if the repo has changed + ACE_Service_Config::current (psg); +} + +ACE_Service_Config_Guard::~ACE_Service_Config_Guard (void) +{ + ACE_Service_Gestalt* s = this->saved_.get (); + ACE_ASSERT (s != 0); + + ACE_Service_Config::current (s); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SCG:") + ACE_TEXT (" - new repo=%@\n"), + this, + this->saved_->repo_)); +} + + +ACE_ALLOC_HOOK_DEFINE (ACE_Service_Config) + +// Set the signal handler to point to the handle_signal() function. +ACE_Sig_Adapter *ACE_Service_Config::signal_handler_ = 0; + +// Trigger a reconfiguration. +sig_atomic_t ACE_Service_Config::reconfig_occurred_ = 0; + +// = Set by command-line options. + +/// Pathname of file to write process id. +ACE_TCHAR *ACE_Service_Config::pid_file_name_ = 0; + +/// Shall we become a daemon process? +bool ACE_Service_Config::be_a_daemon_ = false; + +/// Number of the signal used to trigger reconfiguration. +int ACE_Service_Config::signum_ = SIGHUP; + +void +ACE_Service_Config::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Config::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_Service_Config::parse_args_i (int argc, ACE_TCHAR *argv[]) +{ + ACE_TRACE ("ACE_Service_Config::parse_args_i"); + + // Using PERMUTE_ARGS (default) in order to have all + // unrecognized options and their value arguments moved + // to the end of the argument vector. We'll pick them up + // after processing our options and pass them on to the + // base class for further parsing. + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, + argv, + ACE_TEXT ("bs:p:"), + 1 , // Start at argv[1]. + 0, // Do not report errors + ACE_Get_Opt::RETURN_IN_ORDER); + //FUZZ: enable check_for_lack_ACE_OS + + // Keep a list of all unknown arguments, begin with the + // executable's name + ACE_ARGV superargv; + superargv.add (argv[0]); + + //FUZZ: disable check_for_lack_ACE_OS + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case 'p': + ACE_Service_Config::pid_file_name_ = getopt.opt_arg (); + break; + case 'b': + ACE_Service_Config::be_a_daemon_ = true; + break; + case 's': + { + // There's no point in dealing with this on NT since it + // doesn't really support signals very well... +#if !defined (ACE_LACKS_UNIX_SIGNALS) + ACE_Service_Config::signum_ = + ACE_OS::atoi (getopt.opt_arg ()); + + if (ACE_Reactor::instance ()->register_handler + (ACE_Service_Config::signum_, + ACE_Service_Config::signal_handler_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("cannot obtain signal handler\n")), + -1); +#endif /* ACE_LACKS_UNIX_SIGNALS */ + break; + } + default: + superargv.add (argv[getopt.opt_ind () - 1], true); + } + + // Collect any argumets that were left + for (int c = getopt.opt_ind (); c < argc; ++c) + superargv.add (argv[c-1], true); + + bool ignore_default_svc_conf_file = false; + return instance_->parse_args_i (superargv.argc (), + superargv.argv (), + ignore_default_svc_conf_file); + +} /* parse_args_i () */ + + +int +ACE_Service_Config::open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool , + bool , + bool ) +{ + ACE_TRACE ("ACE_Service_Config::open_i"); + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1)); + + ACE_Log_Msg *log_msg = ACE_LOG_MSG; + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SC::open_i - this=%@, opened=%d\n"), + this, this->is_opened_)); + + // Guard against reentrant processing. + if (this->is_opened_) + return 0; + + this->is_opened_ = true; + + // Check for things we need to do on a per-process basis and which + // may not be safe, or wise to do an a per instance basis + + // Become a daemon before doing anything else. + if (ACE_Service_Config::be_a_daemon_) + ACE::daemonize (); + + // Write process id to file. + if (this->pid_file_name_ != 0) + { + FILE* pidf = ACE_OS::fopen (this->pid_file_name_, + ACE_TEXT("w")); + + if (pidf != 0) + { + ACE_OS::fprintf (pidf, + "%ld\n", + static_cast (ACE_OS::getpid())); + ACE_OS::fclose (pidf); + } + } + + u_long flags = log_msg->flags (); + + // Only use STDERR if the caller hasn't already set the flags. + if (flags == 0) + flags = (u_long) ACE_Log_Msg::STDERR; + + const ACE_TCHAR *key = logger_key; + + if (key == 0 || ACE_OS::strcmp (key, ACE_DEFAULT_LOGGER_KEY) == 0) + // Only use the static if the caller doesn't + // override it in the parameter list or if the key supplied is + // equal to the default static logger key. + key = ACE_Service_Config::current()->logger_key_; + else + ACE_SET_BITS (flags, ACE_Log_Msg::LOGGER); + + if (log_msg->open (program_name, + flags, + key) == -1) + return -1; + + if (ACE::debug ()) + ACE_DEBUG ((LM_STARTUP, + ACE_TEXT ("starting up daemon %n\n"))); + + // Initialize the Service Repository (this will still work if + // user forgets to define an object of type ACE_Service_Config). + ACE_Service_Repository::instance (ACE_Service_Gestalt::MAX_SERVICES); + + // Initialize the ACE_Reactor (the ACE_Reactor should be the + // same size as the ACE_Service_Repository). + ACE_Reactor::instance (); + + // There's no point in dealing with this on NT since it doesn't + // really support signals very well... +#if !defined (ACE_LACKS_UNIX_SIGNALS) + // Only attempt to register a signal handler for positive + // signal numbers. + if (ACE_Service_Config::signum_ > 0) + { + ACE_Sig_Set ss; + ss.sig_add (ACE_Service_Config::signum_); + if ((ACE_Reactor::instance () != 0) && + (ACE_Reactor::instance ()->register_handler + (ss, ACE_Service_Config::signal_handler_) == -1)) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("can't register signal handler\n"))); + } +#endif /* ACE_LACKS_UNIX_SIGNALS */ + + return 0; +} + +/// Return the global configuration instance. Always returns the same +/// instance +ACE_Service_Config * +ACE_Service_Config::singleton (void) +{ + return ACE_SERVICE_CONFIG_SINGLETON::instance (); +} + +int +ACE_Service_Config::insert (ACE_Static_Svc_Descriptor* stsd) +{ + return ACE_Service_Config::instance ()->insert (stsd); +} + + +// Totally remove from the daemon by removing it from the +// ACE_Reactor, and unlinking it if necessary. +int +ACE_Service_Config::remove (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Config::remove"); + return ACE_Service_Repository::instance ()->remove (svc_name); +} + +// Suspend . Note that this will not unlink the service +// from the daemon if it was dynamically linked, it will mark it as +// being suspended in the Service Repository and call the +// member function on the appropriate . A service +// can be resumed later on by calling the method... + +int +ACE_Service_Config::suspend (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Config::suspend"); + return ACE_Service_Repository::instance ()->suspend (svc_name); +} + +// Resume a SVC_NAME that was previously suspended or has not yet +// been resumed (e.g., a static service). + +int +ACE_Service_Config::resume (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Config::resume"); + return ACE_Service_Repository::instance ()->resume (svc_name); +} + + +ACE_Service_Config::ACE_Service_Config (bool ignore_static_svcs, + size_t size, + int signum) +{ + ACE_TRACE ("ACE_Service_Config::ACE_Service_Config"); + + // TODO: Need to find a more customizable way of instantiating the + // gestalt but perhaps we should leave this out untill such + // customizations are identified. + ACE_Service_Gestalt* tmp = 0; + ACE_NEW_NORETURN (tmp, + ACE_Service_Gestalt (size, false, ignore_static_svcs)); + + this->is_opened_ = false; + this->instance_ = tmp; + this->threadkey_.set (tmp); + + ACE_Service_Config::signum_ = signum; +} + +ACE_Service_Config::ACE_Service_Config (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key) +{ + ACE_TRACE ("ACE_Service_Config::ACE_Service_Config"); + + // TODO: Need to find a more customizable way of instantiating the + // gestalt but perhaps we should leave this out untill such + // customizations are identified. + ACE_Service_Gestalt* tmp = 0; + ACE_NEW_NORETURN (tmp, + ACE_Service_Gestalt (ACE_Service_Repository::DEFAULT_SIZE, false)); + + this->is_opened_ = false; + this->instance_ = tmp; + this->threadkey_.set (tmp); + + if (this->open (program_name, + logger_key) == -1 && errno != ENOENT) + { + // Only print out an error if it wasn't the svc.conf file that was + // missing. + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) SC failed to open: %p\n"), + program_name)); + } +} + +/// Return the "global" configuration instance, for the current +/// thread. This may be the same as instance(), but on some occasions, +/// it may be a different one. For example, ACE_Service_Config_Guard +/// provides a way of temporarily replacing the "current" +/// configuration instance in the context of a thread. +ACE_Service_Gestalt* +ACE_Service_Config::current (void) +{ + void* temp = ACE_Service_Config::singleton()->threadkey_.get (); + if (temp == 0) { + + // The most likely reason is that the current thread was spawned + // by some native primitive, like pthreads or Windows API - not + // from ACE. This is perfectly legal for callers who are not, or + // do not need to be ACE-aware. Such callers must have no + // expectation that the pluggable, multi-context configuration + // support will work - they would always get the global context, + // because at this point there is no information what the "parent" + // thread's configuration context was. + + temp = global(); + singleton()->threadkey_.set (temp); + } + + return static_cast (temp); +} + +/// A mutator to set the "current" (TSS) gestalt instance. +void +ACE_Service_Config::current (ACE_Service_Gestalt* newcurrent) +{ + ACE_Service_Config::singleton()->threadkey_.set (newcurrent); +} + + + +#if (ACE_USES_CLASSIC_SVC_CONF == 0) +ACE_Service_Type * +ACE_Service_Config::create_service_type (const ACE_TCHAR *n, + ACE_Service_Type_Impl *o, + ACE_DLL &dll, + int active) +{ + ACE_Service_Type *sp = 0; + ACE_NEW_RETURN (sp, + ACE_Service_Type (n, o, dll, active), + 0); + return sp; +} +#endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ + +ACE_Service_Type_Impl * +ACE_Service_Config::create_service_type_impl (const ACE_TCHAR *name, + int type, + void *symbol, + u_int flags, + ACE_Service_Object_Exterminator gobbler) +{ + ACE_Service_Type_Impl *stp = 0; + + // Note, the only place we need to put a case statement. This is + // also the place where we'd put the RTTI tests, if the compiler + // actually supported them! + + switch (type) + { + case ACE_Service_Type::SERVICE_OBJECT: + ACE_NEW_RETURN (stp, + ACE_Service_Object_Type ((ACE_Service_Object *) symbol, + name, flags, + gobbler), + 0); + break; + case ACE_Service_Type::MODULE: + ACE_NEW_RETURN (stp, + ACE_Module_Type (symbol, name, flags), + 0); + break; + case ACE_Service_Type::STREAM: + ACE_NEW_RETURN (stp, + ACE_Stream_Type (symbol, name, flags), + 0); + break; + default: + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("unknown case\n"))); + break; + } + return stp; + +} + + +// Signal handling API to trigger dynamic reconfiguration. +void +ACE_Service_Config::handle_signal (int sig, + siginfo_t *, + ucontext_t *) +{ +#if defined (ACE_NDEBUG) + ACE_UNUSED_ARG (sig); +#else /* ! ACE_NDEBUG */ + ACE_ASSERT (ACE_Service_Config::signum_ == sig); +#endif /* ! ACE_NDEBUG */ + + ACE_Service_Config::reconfig_occurred_ = 1; +} + +// Trigger reconfiguration to re-read configuration files. +void +ACE_Service_Config::reconfigure (void) +{ + ACE_TRACE ("ACE_Service_Config::reconfigure"); + + ACE_Service_Config::reconfig_occurred_ = 0; + + if (ACE::debug ()) + { +#if !defined (ACE_NLOGGING) + time_t t = ACE_OS::time (0); +#endif /* ! ACE_NLOGGING */ + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("beginning reconfiguration at %s"), + ACE_OS::ctime (&t))); + } + if (ACE_Service_Config::process_directives () == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("process_directives"))); +} + +// Tidy up and perform last rites on a terminating ACE_Service_Config. +int +ACE_Service_Config::close (void) +{ + ACE_Service_Config::singleton ()->instance_->close (); + + // Delete the service repository. All the objects inside the + // service repository should already have been finalized. + ACE_Service_Repository::close_singleton (); + + // Do away with the singleton ACE_Service_Config (calls dtor) + ACE_SERVICE_CONFIG_SINGLETON::close (); + + return 0; +} + + +int +ACE_Service_Config::fini_svcs (void) +{ + ACE_TRACE ("ACE_Service_Config::fini_svcs"); + + // Clear the LM_DEBUG bit from log messages if appropriate + if (ACE::debug ()) + ACE_Log_Msg::disable_debug_messages (); + + int result = 0; + if (ACE_Service_Repository::instance () != 0) + result = ACE_Service_Repository::instance ()->fini (); + + if (ACE::debug ()) + ACE_Log_Msg::enable_debug_messages (); + + return result; +} + +/// Perform user-specified close activities and remove dynamic memory. +ACE_Service_Config::~ACE_Service_Config (void) +{ + ACE_TRACE ("ACE_Service_Config::~ACE_Service_Config"); +} + +// ************************************************************ + +/* static */ +int +ACE_Service_Config::reconfig_occurred (void) +{ + ACE_TRACE ("ACE_Service_Config::reconfig_occurred"); + return ACE_Service_Config::reconfig_occurred_ != 0; +} + +void +ACE_Service_Config::reconfig_occurred (int config_occurred) +{ + ACE_TRACE ("ACE_Service_Config::reconfig_occurred"); + ACE_Service_Config::reconfig_occurred_ = config_occurred; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Config.h b/dep/ACE_wrappers/ace/Service_Config.h new file mode 100644 index 000000000..61d9fd4d0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Config.h @@ -0,0 +1,684 @@ +// -*- C++ -*- + +//==================================================================== +/** + * @file Service_Config.h + * + * $Id: Service_Config.h 81673 2008-05-09 19:09:43Z iliyan $ + * + * @author Douglas C. Schmidt + */ +//==================================================================== + +#ifndef ACE_SERVICE_CONFIG_H +#define ACE_SERVICE_CONFIG_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Default_Constants.h" +#include "ace/Intrusive_Auto_Ptr.h" +#include "ace/Service_Gestalt.h" +#include "ace/Synch_Traits.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_signal.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl. +class ACE_Service_Object; +class ACE_Service_Type; +class ACE_Service_Type_Impl; +class ACE_Service_Repository; +class ACE_Sig_Adapter; +class ACE_Allocator; +class ACE_Reactor; +class ACE_Thread_Manager; +class ACE_DLL; + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) +#define ACE_STATIC_SERVICE_DIRECTIVE(ident, parameters) \ + ACE_TEXT ("static ") \ + ACE_TEXT (ident) \ + ACE_TEXT (" \"") \ + ACE_TEXT (parameters) \ + ACE_TEXT ("\"") +#define ACE_DYNAMIC_SERVICE_DIRECTIVE(ident, libpathname, objectclass, parameters) \ + ACE_TEXT ("dynamic ") \ + ACE_TEXT (ident) \ + ACE_TEXT (" Service_Object * ") \ + ACE_TEXT (libpathname) \ + ACE_TEXT (":") \ + ACE_TEXT (objectclass) \ + ACE_TEXT ("() \"") \ + ACE_TEXT (parameters) \ + ACE_TEXT ("\"") +#define ACE_REMOVE_SERVICE_DIRECTIVE(ident) \ + ACE_TEXT ("remove ") \ + ACE_TEXT (ident) +class ACE_Svc_Conf_Param; +#else +#define ACE_STATIC_SERVICE_DIRECTIVE(ident, parameters) \ + ACE_TEXT ("") +#define ACE_DYNAMIC_SERVICE_DIRECTIVE(ident, libpathname, objectclass, parameters) \ + ACE_TEXT ("") \ + ACE_TEXT ("") +#define ACE_REMOVE_SERVICE_DIRECTIVE(ident) \ + ACE_TEXT ("") +class ACE_XML_Svc_Conf; +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +extern "C" +{ + typedef ACE_Service_Object *(*ACE_SERVICE_ALLOCATOR) (ACE_Service_Object_Exterminator *); +} + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Static_Svc_Descriptor + * + * @brief Holds the information necessary to describe a statically linked + * Svc. + */ +class ACE_Static_Svc_Descriptor +{ +public: + /// Name of the service. + const ACE_TCHAR *name_; + + /// Type of service. + int type_; + + /// Factory function that allocates the service. + ACE_SERVICE_ALLOCATOR alloc_; + + /// Bitmask flags indicating how the framework should delete memory. + u_int flags_; + + /// Flag indicating whether the service starts out active. + int active_; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +public: + /// Compare two service descriptors for equality. + bool operator== (ACE_Static_Svc_Descriptor &) const; + + /// Compare two service descriptors for inequality. + bool operator!= (ACE_Static_Svc_Descriptor &) const; +}; + + +/** + * @class ACE_Threading_Helper + * + * @brief Encapsulates responsibility for allocating, destroying and + * manipulating the value, associated with a thread-specific + * key. Relates to the ability of the created thread to inherit the + * parent thread's gestalt. Designed to be used as an instance member + * of @c ACE_Service_Config. + * + * Partial specialization over ACE_SYNCH_MUTEX is used to implement + * specific behavior in both multi- and single-threaded builds. + */ +template +class ACE_Threading_Helper +{ +}; + +/* + * Specialization for a multi threaded program + */ +template<> +class ACE_Export ACE_Threading_Helper +{ +public: + ACE_Threading_Helper (); + ~ACE_Threading_Helper (); + + void set (void*); + void* get (void); + +private: + /// Key for the thread-specific data, which is a simple pointer to + /// the thread's (currently-) global configuration context. + ACE_thread_key_t key_; +}; + +/* + * Specialization for a single threaded program + */ +template<> +class ACE_Export ACE_Threading_Helper +{ +public: + ACE_Threading_Helper (); + ~ACE_Threading_Helper (); + + void set (void*); + void* get (void); +}; + +#define ACE_Component_Config ACE_Service_Config + +/** + * @class ACE_Service_Config + * + * @brief Supplies common server operations for dynamic and static + * configuration of service. + * + * The ACE_Service_Config uses the Monostate pattern. Therefore, + * you can only have one of these instantiated per-process. It + * represents the process-wide collection of services, which is + * typicaly shared among all other configurable entities. The only + * ACE_Service_Config instance is registered with and owned by the + * ACE_Object_Manager. + * + * By contrast, the ACE_Service_Gestalt represents the collection + * of services, pertaining to a configurable entity. Typicaly, a + * "configurable entity" is an instance, which owns an instance of + * ACE_Service_Gestalt in order to ensure full controll over the + * services it needs. + * + * Another facet of ACE_Service_Config is that for a given thread, + * it provides access to its current, process-global + * ACE_Service_Gestalt instance through its curent() method. + * + * @note The signal_handler_ static member is allocated by the + * ACE_Object_Manager. The ACE_Service_Config constructor + * uses signal_handler_. Therefore, if the program has any + * static ACE_Service_Config objects, there might be + * initialization order problems. They can be minimized, but + * not eliminated, by _not_ #defining + * ACE_HAS_NONSTATIC_OBJECT_MANAGER. + */ +class ACE_Export ACE_Service_Config +{ + + /// The Instance, or the global (default) configuration context. + /// The monostate would forward the calls to that instance. The TSS + /// will point here + ACE_Intrusive_Auto_Ptr instance_; + + /// A helper instance to manage thread-specific key creation. + /// Dependent on the syncronization mutex ACE uses, the corresponding + /// partial template instantiation will perform the right services + /// that have to do with managing thread-specific storage. Note that, + /// for single-threaded builds they would do (next to) nothing. + ACE_Threading_Helper threadkey_; + +public: + + // = Initialization and termination methods. + + /** + * Initialize the Service Repository. Note that initialising @a + * signum to a negative number will prevent a signal handler being + * registered when the repository is opened. + */ + ACE_Service_Config (bool ignore_static_svcs = true, + size_t size = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE, + int signum = SIGHUP); + + /** + * Performs an open without parsing command-line arguments. The + * @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. + */ + ACE_Service_Config (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY); + + /// Perform user-specified close activities and remove dynamic + /// memory. + virtual ~ACE_Service_Config (void); + +private: + + /** + * Performs an open without parsing command-line arguments. + * Implements whats different in the opening sequence + * for this class, as opposed to the base class. + * + * The @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. If + * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file + * will be ignored. If @a ignore_debug_flag is non-0 then the + * application is responsible for setting the + * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of + * errors that occurred on failure and 0 otherwise. + */ + virtual int open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf_file, + bool ignore_debug_flag); + + /** + * Implements whats different in the command line parameter processing + * for this class, as opposed to the base class. + */ + virtual int parse_args_i (int argc, ACE_TCHAR *argv[]); + + /// = Static interfaces + + public: + /** + * Returns the process-wide global singleton instance. It would + * have been created and will be managed by the Object Manager. + */ + static ACE_Service_Config* singleton (void); + + /** + * Mutator for the currently active configuration context instance + * (gestalt). Intended for use by helper classes like @see + * ACE_Service_Config_Guard. Stack-based instances can be used to + * temporarily change which gestalt is seen as global by static + * initializers (especially those in DLLs loaded at run-time). + */ + static void current (ACE_Service_Gestalt*); + + /** + * Accessor for the "current" service gestalt + */ + static ACE_Service_Gestalt* current (void); + + /** + * This is what the static service initializators are hard-wired to + * use, so in order to avoid interface changes this method merely + * forwards to @c ACE_Service_Config::current. This enables us to + * enforce which Service Gestalt is used for services registering + * through static initializers. Especially important for DLL-based + * dynamic services, which can contain their own static services and + * static initializers. + * + * @deprecated Use current() instead. + */ + static ACE_Service_Gestalt* instance (void); + + /** + * Returns a process-wide global singleton instance in contrast with + * current (), which may return a different instance at different + * times, dependent on the context. Modifying this method's return + * value is strongly discouraged as it will circumvent the mechanism + * for dynamically loading services. If you must, use with extreme + * caution! + */ + static ACE_Service_Gestalt* global (void); + + /** + * Performs an open without parsing command-line arguments. The + * @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. If + * @a ignore_static_svcs is true then static services are not loaded, + * otherwise, they are loaded. If @a ignore_default_svc_conf_file is + * non-0 then the configuration file will be ignored. + * Returns zero upon success, -1 if the file is not found or cannot + * be opened (errno is set accordingly), otherwise returns the + * number of errors encountered loading the services in the + * specified svc.conf configuration file. If @a ignore_debug_flag is + * non-0 then the application is responsible for setting the + * @c ACE_Log_Msg::priority_mask appropriately. + */ + static int open (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + bool ignore_static_svcs = true, + bool ignore_default_svc_conf_file = false, + bool ignore_debug_flag = false); + + /** + * This is the primary entry point into the ACE_Service_Config (the + * constructor just handles simple initializations). It parses + * arguments passed in from @a argc and @a argv parameters. The + * arguments that are valid in a call to this method include: + * + * - '-b' Option to indicate that we should be a daemon. Note that when + * this option is used, the process will be daemonized before the + * service configuration file(s) are read. During daemonization, + * (on POSIX systems) the current directory will be changed to "/" + * so the caller should either fully specify the file names, or + * execute a @c chroot() to the appropriate directory. + * @sa ACE::daemonize(). + * - '-d' Turn on debugging mode + * - '-f' Specifies a configuration file name other than the default + * svc.conf. Can be specified multiple times to use multiple files. + * - '-k' Specifies the rendezvous point to use for the ACE distributed + * logger. + * - '-y' Explicitly enables the use of static services. This flag + * overrides the @a ignore_static_svcs parameter value. + * - '-n' Explicitly disables the use of static services. This flag + * overrides the @a ignore_static_svcs parameter value. + * - '-p' Specifies a pathname which is used to store the process id. + * - '-s' Specifies a signal number other than SIGHUP to trigger reprocessing + * of the configuration file(s). Ignored for platforms that do not + * have POSIX signals, such as Windows. + * - '-S' Specifies a service directive string. Enclose the string in quotes + * and escape any embedded quotes with a backslash. This option + * specifies service directives without the need for a configuration + * file. + * + * @param argc The number of commandline arguments. + * @param argv The array with commandline arguments + * @param logger_key Indicates where to write the logging output, + * which is typically either a STREAM pipe or a + * socket address. + * @param ignore_static_svcs If true then static services are not loaded, + * otherwise, they are loaded. + * @param ignore_default_svc_conf_file If non-0 then the @c svc.conf + * configuration file will be ignored. + * @param ignore_debug_flag If true then the application is responsible + * for setting the @c ACE_Log_Msg::priority_mask + * appropriately. + * + * @retval -1 The configuration file is not found or cannot + * be opened (errno is set accordingly). + * @retval 0 Success. + * @retval >0 The number of errors encountered while processing + * the service configuration file(s). + */ + static int open (int argc, + ACE_TCHAR *argv[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + bool ignore_static_svcs = true, + bool ignore_default_svc_conf_file = false, + bool ignore_debug_flag = false); + + /// Tidy up and perform last rites when ACE_Service_Config is shut + /// down. This method calls close_svcs(). Returns 0. + static int close (void); + + /// Perform user-specified close hooks and possibly delete all of the + /// configured services in the . + static int fini_svcs (void); + + /// True if reconfiguration occurred. + static int reconfig_occurred (void); + + /// Indicate that reconfiguration occurred. + static void reconfig_occurred (int); + + /// Perform the reconfiguration process. + static void reconfigure (void); + + // = The following methods are static in order to enforce Singleton + // semantics for the Reactor, Service_Repository, Thread_Manager, + // and Acceptor/Connector Strategy factory. Other portions of the + // system may need to access them at some point or another... + + // = This is not strictly needed, anymore since the service configurator + // has been refactored to allow multiple service configuration + // instances (called gestalts). The interfaces, however were retained in for + // the sake of maintaining source-code compatibility. + + + // = Accessors and mutators for process-wide Singletons. + + /// Returns a pointer to the list of statically linked services. + /// + /// @deprecated - Same as instance(), but still useful in legacy code, + /// (notably, one that can not be easily modified) which uses the following + /// idiom for registering static services: + /// + /// ACE_Service_Config::static_svcs ()->insert (...); + static ACE_Service_Gestalt* static_svcs (void); + + /// Insert a static service descriptor for processing on open_i(). The + /// corresponding ACE_STATIC_SVC_* macros were chaged to use this method + /// instead of obtaining a ptr to a container. See the note on static_svcs(). + /// Added to prevent exposing the internal storage representation of the + /// services repository and provide a better way of debugging service + /// loading and registration problems. + static int insert (ACE_Static_Svc_Descriptor *svc); + + // = Utility methods. + /// Dynamically link the shared object file and retrieve a pointer to + /// the designated shared object in this file. + static int initialize (const ACE_Service_Type *, + const ACE_TCHAR *parameters); + + /// Initialize and activate a statically @a svc_name service. + static int initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters); + + /// Resume a @a svc_name that was previously suspended or has not yet + /// been resumed (e.g., a static service). + static int resume (const ACE_TCHAR svc_name[]); + + /** + * Suspend @a svc_name. Note that this will not unlink the service + * from the daemon if it was dynamically linked, it will mark it as + * being suspended in the Service Repository and call the + * member function on the appropriate ACE_Service_Object. A + * service can be resumed later on by calling the member + * function... + */ + static int suspend (const ACE_TCHAR svc_name[]); + + /// Totally remove @a svc_name from the daemon by removing it + /// from the ACE_Reactor, and unlinking it if necessary. + static int remove (const ACE_TCHAR svc_name[]); + +#if defined (ACE_HAS_WINCE) && defined (ACE_USES_WCHAR) + // We must provide these function to bridge the Svc_Conf parser + // with ACE. + static int initialize (const ACE_Service_Type *, ACE_ANTI_TCHAR []); + static int initialize (const char svc_name[], ACE_ANTI_TCHAR parameters[]); + static int resume (const ACE_ANTI_TCHAR svc_name[]); + static int suspend (const ACE_ANTI_TCHAR svc_name[]); + static int remove (const ACE_ANTI_TCHAR svc_name[]); +#endif /* ACE_HAS_WINCE */ + + /// Dump the state of an object. + void dump (void) const; + + /// Set the signal_handler;for internal use by ACE_Object_Manager only. + static ACE_INLINE void signal_handler (ACE_Sig_Adapter *); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Process a file containing a list of service configuration + /// directives. + static int process_file (const ACE_TCHAR file[]); + + /// Process one service configuration @a directive, which is passed as + /// a string. Returns the number of errors that occurred. + static int process_directive (const ACE_TCHAR directive[]); + + /** + * Process one static service definition. Load a new static service + * into the ACE_Service_Repository. + * + * @param ssd Service descriptor, see the document of + * ACE_Static_Svc_Descriptor for more details. + * + * @param force_replace If set the new service descriptor replaces + * any previous instance in the ACE_Service_Repository. + * + * @return Returns -1 if the service cannot be 'loaded'. + */ + static int process_directive (const ACE_Static_Svc_Descriptor &ssd, + bool force_replace = false); + + /** + * Process (or re-process) service configuration requests that are + * provided in the svc.conf file(s). Returns the number of errors + * that occurred. + */ + static int process_directives (void); + + /// Handles signals to trigger reconfigurations. + static void handle_signal (int sig, siginfo_t *, ucontext_t *); + + /** + * Handle the command-line options intended for the + * ACE_Service_Config. Note that @c argv[0] is assumed to be the + * program name. + * The arguments that are valid in a call to this method are + * - '-b' Option to indicate that we should be a daemon + * - '-d' Turn on debugging mode + * - '-f' Option to read in the list of svc.conf file names + * - '-k' Option to read a wide string where in the logger output can + * be written + * - '-y' Turn on the flag for a repository of statically + * linked services + * - '-n' Need not have a repository of statically linked services + * - '-S' Option to read in the list of services on the command-line + * Please observe the difference between options '-f' that looks + * for a list of files and here a list of services. + */ + static int parse_args (int, ACE_TCHAR *argv[]); + +#if (ACE_USES_CLASSIC_SVC_CONF == 0) + static ACE_Service_Type *create_service_type (const ACE_TCHAR *n, + ACE_Service_Type_Impl *o, + ACE_DLL &dll, + int active); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ + + static ACE_Service_Type_Impl * + create_service_type_impl (const ACE_TCHAR *name, + int type, + void *symbol, + u_int flags, + ACE_Service_Object_Exterminator gobbler); + + /// @deprecated + /// Process service configuration requests that were provided on the + /// command-line. Returns the number of errors that occurred. + static int process_commandline_directives (void); + + /// Become a daemon. + static int start_daemon (void); + + // @deprecated + // Add the default statically-linked services to the + // ACE_Service_Repository. + static int load_static_svcs (void); + +protected: + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + /// @deprecated + /// This is the implementation function that process_directives() + /// and process_directive() both call. Returns the number of errors + /// that occurred. + static int process_directives_i (ACE_Svc_Conf_Param *param); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + + + // = Process-wide state. + +private: + + /// Have we called ACE_Service_Config::open() yet? + bool is_opened_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Synchronization variable for open, etc. + mutable ACE_SYNCH_MUTEX lock_; +#endif /* ACE_MT_SAFE */ + + /// True if reconfiguration occurred. + static sig_atomic_t reconfig_occurred_; + + // = Set by command-line options. + /// Shall we become a daemon process? + static bool be_a_daemon_; + + /// Pathname of file to write process id. + static ACE_TCHAR *pid_file_name_; + + /// Number of the signal used to trigger reconfiguration. + static int signum_; + + /// Handles the reconfiguration signals. + static ACE_Sig_Adapter *signal_handler_; + + /// Pointer to the Singleton (ACE_Cleanup) Gestalt instance. + /// There is thread-specific global instance pointer, which is used to + /// temporarily change which Gestalt instance is used for static service + /// registrations. + /// + /// A specific use case is a thread, which loads a _dynamic_ service from + /// a DLL. If the said DLL also contains additional _static_ services, + /// those *must* be registered with the same configuration repository as + /// the dynamic service. Otherwise, the DLL's static services would be + /// registered with the global Gestalt and may outlive the DLL that + /// contains their code and perhaps the memory in which they are in. + /// This is a problem because if the DLL gets unloaded (as it will, if + /// it was loaded in an instance of Gestalt), the DLL's memory will be + /// deallocated, but the global service repository will still "think" + /// it must finalize the (DLL's) static services - with disastrous + /// consequences, occurring in the post-main code (at_exit()). + + /// This class needs the intimate access to be able to swap the + /// current TSS pointer for the global Gestalt. + friend class ACE_Service_Config_Guard; + + /// The helper needs intimate access (when building with no threads) + friend class ACE_Threading_Helper ; + friend class ACE_Threading_Helper ; +}; + +/** + * @class ACE_Service_Config_Guard + * + * @brief A guard class, designed to be instantiated on the stack. + * + * Instantiating it with a specific configuration ensures any references to + * ACE_Service_Config::instance(), even when occuring in static constructors, + * will allways access the designated configuration instance. + * This comes very handy when a dynamic service also registers any static + * services of its own and their static factories. + */ +class ACE_Export ACE_Service_Config_Guard +{ +public: + ACE_Service_Config_Guard (ACE_Service_Gestalt* psg); + ~ACE_Service_Config_Guard (void); + +private: + // Private AND not implemented to disable copying + ACE_Service_Config_Guard(const ACE_Service_Config_Guard&); + ACE_Service_Config_Guard& operator= (const ACE_Service_Config_Guard&); + +private: + ACE_Intrusive_Auto_Ptr saved_; +}; + + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Service_Config.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_SERVICE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/Service_Config.inl b/dep/ACE_wrappers/ace/Service_Config.inl new file mode 100644 index 000000000..a03e7124e --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Config.inl @@ -0,0 +1,204 @@ +// -*- C++ -*- +// +// $Id: Service_Config.inl 81673 2008-05-09 19:09:43Z iliyan $ + +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// This is the primary entry point into the ACE_Service_Config (the +// constructor just handles simple initializations). +ACE_INLINE int +ACE_Service_Config::open (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf, + bool ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Config::open"); + if (singleton()->open_i (program_name, + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag) == -1) + return -1; + + return current()->open (program_name, + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag); +} + + +ACE_INLINE int +ACE_Service_Config::open (int argc, + ACE_TCHAR *argv[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf, + bool ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Config::open"); + if (singleton()->open_i (argv[0], + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag) == -1) + return -1; + + return current()->open (argc, + argv, + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag); +} + +// Handle the command-line options intended for the +// ACE_Service_Config. +ACE_INLINE int +ACE_Service_Config::parse_args (int argc, ACE_TCHAR *argv[]) +{ + return ACE_Service_Config::current ()->parse_args (argc, argv); +} + +/// Return the global configuration instance. Allways returns the same +/// instance +ACE_INLINE ACE_Service_Gestalt * +ACE_Service_Config::global (void) +{ + return ACE_Service_Config::singleton()->instance_.get (); +} + +/// Return the configuration instance, considered "global" in the +/// current thread. This may be the same as instance(), but on some +/// occasions, it may be a different one. For example, +/// ACE_Service_Config_Guard provides a way of temporarily replacing +/// the "current" configuration instance in the context of a thread. +ACE_INLINE ACE_Service_Gestalt * +ACE_Service_Config::instance (void) +{ + return ACE_Service_Config::current (); +} + +// This method has changed to return the gestalt instead of the +// container, underlying the service repository and defined +// ACE_Service_Gestalt::insert (ACE_Static_Svc_Descriptor*). This way +// the existing source code can keep using +// ACE_Service_Config::static_svcs(), however now it is not necessary +// to expose the repository storage *and* it is much easier to debug +// service registration problems. + +ACE_INLINE ACE_Service_Gestalt* +ACE_Service_Config::static_svcs (void) +{ + return ACE_Service_Config::current (); +} + +/// Compare two service descriptors for equality. +ACE_INLINE bool +ACE_Static_Svc_Descriptor::operator== (ACE_Static_Svc_Descriptor &d) const +{ + return ACE_OS::strcmp (name_, d.name_) == 0; +} + +/// Compare two service descriptors for inequality. +ACE_INLINE bool +ACE_Static_Svc_Descriptor::operator!= (ACE_Static_Svc_Descriptor &d) const +{ + return !(*this == d); +} + +ACE_INLINE void +ACE_Service_Config::signal_handler (ACE_Sig_Adapter *signal_handler) +{ + signal_handler_ = signal_handler; +} + +/// Initialize and activate a statically linked service. +ACE_INLINE int +ACE_Service_Config::initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Config::initialize"); + return ACE_Service_Config::current ()->initialize (svc_name, + parameters); +} + +/// Dynamically link the shared object file and retrieve a pointer to +/// the designated shared object in this file. +ACE_INLINE int +ACE_Service_Config::initialize (const ACE_Service_Type *sr, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Config::initialize"); + return ACE_Service_Config::current ()->initialize (sr, parameters); +} + +/// Process a file containing a list of service configuration +/// directives. +ACE_INLINE int ACE_Service_Config::process_file (const ACE_TCHAR file[]) +{ + return ACE_Service_Config::current ()->process_file (file); +} + +/// +ACE_INLINE int +ACE_Service_Config::process_directive (const ACE_TCHAR directive[]) +{ + return ACE_Service_Config::current ()->process_directive (directive); +} + +/// Process service configuration requests as indicated in the queue of +/// svc.conf files. +ACE_INLINE int +ACE_Service_Config::process_directives (void) +{ + return ACE_Service_Config::current ()->process_directives (false); +} + +ACE_INLINE int +ACE_Service_Config::process_directive (const ACE_Static_Svc_Descriptor &ssd, + bool force_replace) +{ + return ACE_Service_Config::current ()->process_directive (ssd, force_replace); +} + + +#if defined (ACE_HAS_WINCE) && defined (ACE_USES_WCHAR) +// We must provide these function to bridge Svc_Conf parser with ACE. + +ACE_INLINE int +ACE_Service_Config::initialize (const ACE_Service_Type *sp, ACE_ANTI_TCHAR parameters[]) +{ + return ACE_Service_Config::initialize (sp, ACE_TEXT_ANTI_TO_TCHAR (parameters)); +} + +ACE_INLINE int +ACE_Service_Config::initialize (const ACE_ANTI_TCHAR svc_name[], ACE_ANTI_TCHAR parameters[]) +{ + return ACE_Service_Config::initialize (ACE_TEXT_ANTI_TO_TCHAR (svc_name), + ACE_TEXT_ANTI_TO_TCHAR (parameters)); +} + +ACE_INLINE int +ACE_Service_Config::resume (const ACE_ANTI_TCHAR svc_name[]) +{ + return ACE_Service_Config::resume (ACE_TEXT_ANTI_TO_TCHAR (svc_name)); +} + +ACE_INLINE int +ACE_Service_Config::suspend (const ACE_ANTI_TCHAR svc_name[]) +{ + return ACE_Service_Config::suspend (ACE_TEXT_ANTI_TO_TCHAR (svc_name)); +} + +ACE_INLINE int +ACE_Service_Config::remove (const ACE_ANTI_TCHAR svc_name[]) +{ + return ACE_Service_Config::remove (ACE_TEXT_ANTI_TO_TCHAR (svc_name)); +} +#endif /* ACE_HAS_WINCE && !ACE_USES_WCHAR */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Gestalt.cpp b/dep/ACE_wrappers/ace/Service_Gestalt.cpp new file mode 100644 index 000000000..6ceeb1526 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Gestalt.cpp @@ -0,0 +1,1296 @@ +// $Id: Service_Gestalt.cpp 81673 2008-05-09 19:09:43Z iliyan $ + +#include "ace/Svc_Conf.h" +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/Malloc.h" +#include "ace/Service_Manager.h" +#include "ace/Service_Types.h" +#include "ace/Containers.h" +#include "ace/Auto_Ptr.h" +#include "ace/Reactor.h" +#include "ace/Thread_Manager.h" +#include "ace/DLL.h" +#include "ace/XML_Svc_Conf.h" +#include "ace/SString.h" + +#ifndef ACE_LACKS_UNIX_SIGNALS +# include "ace/Signal.h" +#endif /* !ACE_LACKS_UNIX_SIGNALS */ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_stat.h" + +#include "ace/TSS_T.h" +#include "ace/Service_Gestalt.h" + +#include "ace/Svc_Conf_Param.h" + +ACE_RCSID (ace, + Service_Gestalt, + "$Id: Service_Gestalt.cpp 81673 2008-05-09 19:09:43Z iliyan $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Service_Type_Dynamic_Guard::ACE_Service_Type_Dynamic_Guard + (ACE_Service_Repository &r, const ACE_TCHAR *name) + : repo_ (r) + // Relocation starts where the next service will be inserted (if any) + , repo_begin_ (r.current_size ()) + , name_ (name) +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + // On this thread (for the duration of the initialize() method), + // we're about to do two things that require locking: (1) fiddle + // with the repository and (2) load a DLL and hence lock the + // DLL_Manager. + // + // Now if we don't lock the repo here, it is possible that two + // threads may deadlock on initialization because they can acquire + // locks (1) and (2) in different order, for instance: + // + // T1: loads a DLL (2) and registers a service (1); + // + // T2: may be relocating a service (1), which could lead to a + // (re)opening or uping the ref count on a DLL (2); + // + // To prevent this, we lock the repo here, using the repo_monitor_ + // member guard. + , repo_monitor_ (r.lock_) +#endif +{ + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) STDG::, repo=%@") + ACE_TEXT(", name=%s - begining at [%d]\n"), + &this->repo_, + this->name_, + this->repo_begin_)); + + ACE_ASSERT (this->name_ != 0); // No name? +} + + +/// Destructor + +ACE_Service_Type_Dynamic_Guard::~ACE_Service_Type_Dynamic_Guard (void) +{ + const ACE_Service_Type *tmp = 0; + + // Lookup without ignoring suspended services. Making sure + // not to ignore any inactive services, since those may be forward + // declarations + size_t slot = 0; + int const ret = this->repo_.find_i (this->name_, slot, &tmp, false); + + // We inserted it (as inactive), so we expect to find it, right? + if ((ret < 0 && ret != -2) || tmp == 0) + { + if (ACE::debug ()) + ACE_ERROR ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) STDG:: - Failed (%d) to find %s -> %@\n"), + ret, this->name_, tmp)); + return; + } + + if (tmp->type () != 0) + { + // Something has registered a proper (non-forward-decl) service with + // the same name as our dummy. + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) STDG::, repo=%@ [%d], ") + ACE_TEXT ("name=%s - updating dependents [%d - %d)\n"), + &this->repo_, + slot, + this->name_, + this->repo_begin_, + this->repo_.current_size ())); + + // Relocate any services inserted since we were created. + // Any (static, i.e. DLL = 0) services registered in + // the context of this guard aren't really static because + // their code belongs in the DLL's code segment + this->repo_.relocate_i (this->repo_begin_, this->repo_.current_size (), tmp->dll()); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) STDG::, repo=%@ [%d], ") + ACE_TEXT ("name=%s - loaded (type=%@, impl=%@, object=%@, active=%d)\n"), + &this->repo_, + slot, + this->name_, + tmp, + tmp->type (), + tmp->type ()->object (), + tmp->active ())); + } +} + + + +// ---------------------------------------- + +ACE_Service_Gestalt::Processed_Static_Svc:: +Processed_Static_Svc (const ACE_Static_Svc_Descriptor *assd) + :name_(0), + assd_(assd) +{ + ACE_NEW_NORETURN (name_, ACE_TCHAR[ACE_OS::strlen(assd->name_)+1]); + ACE_OS::strcpy(name_,assd->name_); +} + +ACE_Service_Gestalt::Processed_Static_Svc::~Processed_Static_Svc (void) +{ + delete [] name_; +} + +void +ACE_Service_Gestalt::intrusive_add_ref (ACE_Service_Gestalt* g) +{ + if (g != 0) + { + ++g->refcnt_; + ACE_ASSERT (g->refcnt_ > 0); + } +} + +void +ACE_Service_Gestalt::intrusive_remove_ref (ACE_Service_Gestalt* g) +{ + if (g != 0) + { + long tmp = --g->refcnt_; + if (tmp <= 0) delete g; + ACE_ASSERT (tmp >= 0); + } +} + + +ACE_Service_Gestalt::~ACE_Service_Gestalt (void) +{ + + if (this->svc_repo_is_owned_) + delete this->repo_; + + this->repo_ =0; + + delete this->static_svcs_; + this->static_svcs_ = 0; + + // Delete the dynamically allocated static_svcs instance. +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::~SG - this=%@, pss = %@\n"), + this, this->processed_static_svcs_)); +#endif + + if (this->processed_static_svcs_ && + !this->processed_static_svcs_->is_empty()) + { + Processed_Static_Svc **pss = 0; + for (ACE_PROCESSED_STATIC_SVCS_ITERATOR iter (*this->processed_static_svcs_); + iter.next (pss) != 0; + iter.advance ()) + { + delete *pss; + } + } + + delete this->processed_static_svcs_; + this->processed_static_svcs_ = 0; + + delete this->svc_conf_file_queue_; + this->svc_conf_file_queue_ = 0; +} + +ACE_Service_Gestalt::ACE_Service_Gestalt (size_t size, + bool svc_repo_is_owned, + bool no_static_svcs) + : svc_repo_is_owned_ (svc_repo_is_owned) + , svc_repo_size_ (size) + , is_opened_ (0) + , logger_key_ (ACE_DEFAULT_LOGGER_KEY) + , no_static_svcs_ (no_static_svcs) + , svc_queue_ (0) + , svc_conf_file_queue_ (0) + , repo_ (0) + , static_svcs_ (0) + , processed_static_svcs_ (0) + , refcnt_ (0) +{ + (void)this->init_i (); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::ctor - this = %@, pss = %@\n"), + this, this->processed_static_svcs_)); +#endif +} + +/// Performs the common initialization tasks for a new or previously +/// closed instance. Must not be virtual, as it is also called from +/// the constructor. +int +ACE_Service_Gestalt::init_i (void) +{ + // Only initialize the repo_ if (a) we are being constructed, or; + // (b) we're being open()-ed, perhaps after previously having been + // close()-ed. In both cases: repo_ == 0 and we need a repository. + if (this->repo_ == 0) + { + if (this->svc_repo_is_owned_) + { + ACE_NEW_RETURN (this->repo_, + ACE_Service_Repository (this->svc_repo_size_), + -1); + } + else + { + this->repo_ = + ACE_Service_Repository::instance (this->svc_repo_size_); + } + } + + if (init_svc_conf_file_queue () == -1) + return -1; + + if ( svc_conf_file_queue_->is_empty ()) + { + // Check if the default file exists before attempting to queue it + // for processing + FILE *fp = ACE_OS::fopen (ACE_DEFAULT_SVC_CONF, + ACE_TEXT ("r")); + bool skip_static_svcs = (fp == 0); + if (fp != 0) + ACE_OS::fclose (fp); + + if (!skip_static_svcs) { + // Load the default "svc.conf" entry here if there weren't + // overriding -f arguments in . + if (svc_conf_file_queue_->enqueue_tail + (ACE_TString (ACE_DEFAULT_SVC_CONF)) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("enqueuing ") + ACE_DEFAULT_SVC_CONF + ACE_TEXT(" file")), + -1); + } + } + } + + return 0; +} + + +// Add the default statically-linked services to the Service +// Repository. + +int +ACE_Service_Gestalt::load_static_svcs (void) +{ + ACE_TRACE ("ACE_Service_Gestalt::load_static_svcs"); + + if (this->static_svcs_ == 0) + return 0; // Nothing to do + + ACE_Static_Svc_Descriptor **ssdp = 0; + for (ACE_STATIC_SVCS_ITERATOR iter (*this->static_svcs_); + iter.next (ssdp) != 0; + iter.advance ()) + { + ACE_Static_Svc_Descriptor *ssd = *ssdp; + + if (this->process_directive (*ssd, 1) == -1) + return -1; + } + return 0; + +} /* load_static_svcs () */ + + + +/// Find a static service descriptor by name + +int +ACE_Service_Gestalt::find_static_svc_descriptor (const ACE_TCHAR* name, + ACE_Static_Svc_Descriptor **ssd) const +{ + ACE_TRACE ("ACE_Service_Gestalt::find_static_svc_descriptor"); + + if (this->static_svcs_ == 0) + return -1; + + ACE_Static_Svc_Descriptor **ssdp = 0; + for (ACE_STATIC_SVCS_ITERATOR iter ( *this->static_svcs_); + iter.next (ssdp) != 0; + iter.advance ()) + { + if (ACE_OS::strcmp ((*ssdp)->name_, name) == 0) + { + if (ssd != 0) + *ssd = *ssdp; + + return 0; + } + } + + return -1; +} + +/// @brief + +const ACE_Static_Svc_Descriptor* +ACE_Service_Gestalt::find_processed_static_svc (const ACE_TCHAR* name) +{ + if (this->processed_static_svcs_ == 0 || name == 0) + return 0; + + Processed_Static_Svc **pss = 0; + for (ACE_PROCESSED_STATIC_SVCS_ITERATOR iter (*this->processed_static_svcs_); + iter.next (pss) != 0; + iter.advance ()) + { + if (ACE_OS::strcmp ((*pss)->name_, name) == 0) + return (*pss)->assd_; + } + return 0; +} + + + +/// @brief Captures a list of the direcives processed (explicitely) for this +/// Gestalt so that services can be replicated in other repositories +/// upon their first initialization. +/// +/// This is part of the mechanism ensuring distinct local instances +/// for static service objects, loaded in another repository. + +void +ACE_Service_Gestalt::add_processed_static_svc + (const ACE_Static_Svc_Descriptor *assd) +{ + + /// When process_directive(Static_Svc_Descriptor&) is called, it + /// associates a service object with the Gestalt and makes the + /// resource (a Service Object) local to the repository. This is but + /// the first step in using such SO. The next is the + /// "initialization" step. It is typicaly done through a "static" + /// service configuration directive. + /// + /// In contrast a "dynamic" directive, when processed through the + /// overloaded process_directives(string) both creates the SO + /// locally and initializes it, where the statics directive must + /// first locate the SO and then calls the init() method. This means + /// that durig the "static" initialization there's no specific + /// information about the hosting repository and the gestalt must + /// employ some lookup strategy to find it elsewhere. + + if (this->processed_static_svcs_ == 0) + ACE_NEW (this->processed_static_svcs_, + ACE_PROCESSED_STATIC_SVCS); + + Processed_Static_Svc **pss = 0; + for (ACE_PROCESSED_STATIC_SVCS_ITERATOR iter (*this->processed_static_svcs_); + iter.next (pss) != 0; + iter.advance ()) + { + if (ACE_OS::strcmp ((*pss)->name_, assd->name_) == 0) + { + (*pss)->assd_ = assd; + return; + } + } + Processed_Static_Svc *tmp = 0; + ACE_NEW (tmp,Processed_Static_Svc(assd)); + this->processed_static_svcs_->insert(tmp); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::add_processed_static_svc, ") + ACE_TEXT ("repo=%@ - %s\n"), + this->repo_, + assd->name_)); +} + + +/// Queues a static service object descriptor which, during open() +/// will be given to process_directive() to create the Service +/// Object. Normally, only called from static initializers, prior to +/// calling open() but loading a service from a DLL can cause it too. + +int +ACE_Service_Gestalt::insert (ACE_Static_Svc_Descriptor *stsd) +{ + if (this->static_svcs_ == 0) + ACE_NEW_RETURN (this->static_svcs_, + ACE_STATIC_SVCS, + -1); + + return this->static_svcs_->insert (stsd); +} + + +ACE_ALLOC_HOOK_DEFINE (ACE_Service_Gestalt) + + +void +ACE_Service_Gestalt::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Gestalt::dump"); +#endif /* ACE_HAS_DUMP */ +} + + + +/// + +int +ACE_Service_Gestalt::initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt_Base::initialize (repo)"); + ACE_ARGV args (parameters); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::initialize - () repo=%@, ") + ACE_TEXT ("looking up static ") + ACE_TEXT ("service \'%s\' to initialize\n"), + this->repo_, + svc_name)); + } +#endif + + const ACE_Service_Type *srp = 0; + for (int i = 0; this->find (svc_name, &srp) == -1 && i < 2; i++) + // if (this->repo_->find (svc_name, &srp) == -1) + { + const ACE_Static_Svc_Descriptor *assd = + ACE_Service_Config::global()->find_processed_static_svc(svc_name); + if (assd != 0) + { + this->process_directive_i(*assd, 0); + } + else + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) ERROR: SG::initialize - service \'%s\'") + ACE_TEXT (" was not located.\n"), + svc_name), + -1); + } + } + if (srp == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) ERROR: SG::initialize - service \'%s\'") + ACE_TEXT (" was not located.\n"), + svc_name), + -1); + + /// If initialization fails ... + if (srp->type ()->init (args.argc (), + args.argv ()) == -1) + { + // ... report and remove this entry. + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) ERROR: SG::initialize - static init of \'%s\'") + ACE_TEXT (" failed (%p)\n"), + svc_name, ACE_TEXT ("error"))); + this->repo_->remove (svc_name); + return -1; + } + + // If everything is ok, activate it + const_cast(srp)->active (1); + return 0; +} + + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) +int +ACE_Service_Gestalt::initialize (const ACE_Service_Type_Factory *stf, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt::initialize"); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@, name=%s") + ACE_TEXT (" - looking up in the repo\n"), + this->repo_, + stf->name ())); +#endif + + ACE_Service_Type *srp = 0; + int const retv = this->repo_->find (stf->name (), + (const ACE_Service_Type **) &srp); + + // If there is an active service already, remove it first + // before it can be re-installed. + if (retv >= 0) + { +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@,") + ACE_TEXT (" name=%s - removing a pre-existing namesake.\n"), + this->repo_, + stf->name ())); +#endif + this->repo_->remove (stf->name ()); + } + + // If there is an inactive service by that name it may have been + // either inactivated, or just a forward declaration for a service, + // that is in the process of being initialized. If it is the latter, + // then we have detected an attempt to initialize the same dynamic + // service while still processing previous attempt. This can lock up + // the process, because the ACE_DLL_Manager::open () is not + // re-entrant - it uses a Singleton lock to serialize concurent + // invocations. This use case must be handled here, because if the + // DLL_Manager was re-entrant we would have entered an infinite + // recursion here. + if (retv == -2 && srp->type () == 0) + ACE_ERROR_RETURN ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@,") + ACE_TEXT (" name=%s - forward-declared; ") + ACE_TEXT (" recursive initialization requests are") + ACE_TEXT (" ignored.\n"), + this->repo_, + stf->name ()), + -1); + + // Reserve a spot for the dynamic service by inserting an incomplete + // service declaration, i.e. one that can not produce a service + // object if asked (a forward declaration). This declaration + // ensures maintaining the proper partial ordering of the services + // with respect to their finalization. For example, dependent static + // services must be registered *after* the dynamic service that + // loads them, so that their finalization is complete *before* + // finalizing the dynamic service. + ACE_Service_Type_Dynamic_Guard dummy (*this->repo_, + stf->name ()); + + // make_service_type() is doing the dynamic loading and also runs + // any static initializers + ACE_Auto_Ptr tmp (stf->make_service_type (this)); + + if (tmp.get () != 0 && + this->initialize_i (tmp.get (), parameters) == 0) + { + // All good. Tthe ACE_Service_Type instance is now owned by the + // repository and we should make sure it is not destroyed upon + // exit from this method. + tmp.release (); + return 0; + } + + return -1; +} +#endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */ + + +// Dynamically link the shared object file and retrieve a pointer to +// the designated shared object in this file. +// @note This is obsolete (and error-prone) in the presense of dynamic +// services with their own static services. This method will allow those +// static services to register *before* the dynamic service that owns them. +// Upon finalization of the static services the process may crash, because +// the dynamic service's DLL may have been already released, together with +// the memory in which the static services reside. +// It may not crash, for instance, when the first static service to register +// is the same as the dynamic service being loaded. You should be so lucky! .. + +int +ACE_Service_Gestalt::initialize (const ACE_Service_Type *sr, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt::initialize"); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@, name=%s") + ACE_TEXT (" - looking up in the repo\n"), + this->repo_, + sr->name ())); + + ACE_Service_Type *srp = 0; + if (this->repo_->find (sr->name (), + (const ACE_Service_Type **) &srp) >= 0) + { +#ifndef ACE_NLOGGING + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@, name=%s") + ACE_TEXT (" - removing a pre-existing namesake.\n"), + this->repo_, + sr->name ())); +#endif + this->repo_->remove (sr->name ()); + } + + return this->initialize_i (sr, parameters); + +} + +// Dynamically link the shared object file and retrieve a pointer to +// the designated shared object in this file. +int +ACE_Service_Gestalt::initialize_i (const ACE_Service_Type *sr, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt::initialize_i"); + ACE_ARGV args (parameters); + if (sr->type ()->init (args.argc (), + args.argv ()) == -1) + { + // We just get ps to avoid having remove() delete it. + ACE_Service_Type *ps = 0; + this->repo_->remove (sr->name (), &ps); + +#ifndef ACE_NLOGGING + // Not using LM_ERROR here to avoid confusing the test harness + if (ACE::debug ()) + ACE_ERROR_RETURN ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) SG::initialize_i -") + ACE_TEXT (" repo=%@, name=%s - remove failed: %m\n"), + this->repo_, + sr->name ()), + -1); +#endif + return -1; + } + + if (this->repo_->insert (sr) == -1) + { +#ifndef ACE_NLOGGING + // Not using LM_ERROR here to avoid confusing the test harness + if (ACE::debug ()) + ACE_ERROR_RETURN ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) SG::initialize_i -") + ACE_TEXT (" repo=%@, name=%s - insert failed: %m\n"), + this->repo_, + sr->name ()), + -1); +#endif + return -1; + } + + return 0; +} + +// Totally remove from the daemon by removing it from the +// ACE_Reactor, and unlinking it if necessary. + +int +ACE_Service_Gestalt::remove (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::remove"); + if (this->repo_ == 0) + return -1; + + return this->repo_->remove (svc_name); +} + +// Suspend . Note that this will not unlink the service +// from the daemon if it was dynamically linked, it will mark it as +// being suspended in the Service Repository and call the +// member function on the appropriate . A service +// can be resumed later on by calling the method... + +int +ACE_Service_Gestalt::suspend (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::suspend"); + if (this->repo_ == 0) + return -1; + + return this->repo_->suspend (svc_name); +} + +// Resume a SVC_NAME that was previously suspended or has not yet +// been resumed (e.g., a static service). + +int +ACE_Service_Gestalt::resume (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::resume"); + if (this->repo_ == 0) + return -1; + + return this->repo_->resume (svc_name); +} + + +int +ACE_Service_Gestalt::process_directive (const ACE_Static_Svc_Descriptor &ssd, + bool force_replace) +{ + int const result = process_directive_i (ssd, force_replace); + if (result == 0) + { + this->add_processed_static_svc(&ssd); + } + return result; +} + +int +ACE_Service_Gestalt::process_directive_i (const ACE_Static_Svc_Descriptor &ssd, + bool force_replace) +{ + if (this->repo_ == 0) + return -1; + + if (!force_replace) + { + if (this->repo_->find (ssd.name_, 0, 0) >= 0) + { + // The service is already there, just return + return 0; + } + } + + + ACE_Service_Object_Exterminator gobbler; + void *sym = (ssd.alloc_)(&gobbler); + + ACE_Service_Type_Impl *stp = + ACE_Service_Config::create_service_type_impl (ssd.name_, + ssd.type_, + sym, + ssd.flags_, + gobbler); + if (stp == 0) + return 0; + + ACE_Service_Type *service_type = 0; + + // This is just a temporary to force the compiler to use the right + // constructor in ACE_Service_Type. Note that, in cases where we are + // called from a static initializer which is part of a DLL, there is + // not enough information about the actuall DLL in this context. + ACE_DLL tmp_dll; + + ACE_NEW_RETURN (service_type, + ACE_Service_Type (ssd.name_, + stp, + tmp_dll, + ssd.active_), + -1); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::process_directive_i, ") + ACE_TEXT ("repo=%@ - %s, dll=%s, force=%d\n"), + this->repo_, + ssd.name_, + (tmp_dll.dll_name_ == 0) ? ACE_TEXT ("") : tmp_dll.dll_name_, + force_replace)); +#endif + + return this->repo_->insert (service_type); +} + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + +int +ACE_Service_Gestalt::process_directives_i (ACE_Svc_Conf_Param *param) +{ +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::process_directives_i, ") + ACE_TEXT ("repo=%@ - %s\n"), + this->repo_, + (param->type == ACE_Svc_Conf_Param::SVC_CONF_FILE) + ? ACE_TEXT ("") + : param->source.directive)); +#endif + + // AC 970827 Skip the heap check because yacc allocates a buffer + // here which will be reported as a memory leak for some reason. + ACE_NO_HEAP_CHECK + + // Were we called in the context of the current instance? + ACE_ASSERT (this == param->config); + + // Temporarily (for the duration of this call) make sure that *any* + // static service registrations will happen with this instance. Such + // registrations are possible as a side-effect of dynamically + // loading a DLL, which has other static services registered. Thus + // this instance will own both the DLL and those static services, + // which implies that their finalization will be performed in the + // correct order, i.e. prior to finalizing the DLL + ACE_Service_Config_Guard guard (this); + + ::ace_yyparse (param); + + // This is a hack, better errors should be provided... + if (param->yyerrno > 0) + { + // Always set the last error if ace_yyparse() fails. + // Other code may use errno to determine the type + // of problem that occurred from processing directives. + ACE_OS::last_error (EINVAL); + return param->yyerrno; + } + else + return 0; +} + +#else + +ACE_XML_Svc_Conf * +ACE_Service_Gestalt::get_xml_svc_conf (ACE_DLL &xmldll) +{ + if (xmldll.open (ACE_TEXT ("ACEXML_XML_Svc_Conf_Parser")) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) Failure to open ACEXML_XML_Svc_Conf_Parser: %p\n"), + "ACE_Service_Config::get_xml_svc_conf"), + 0); + + void * foo = + xmldll.symbol (ACE_TEXT ("_ACEXML_create_XML_Svc_Conf_Object")); + + ACE_XML_Svc_Conf::Factory factory = + reinterpret_cast (foo); + if (factory == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) Unable to resolve factory: %p\n"), + xmldll.error ()), + 0); + + return factory (); +} +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + +int +ACE_Service_Gestalt::process_file (const ACE_TCHAR file[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::process_file"); + + // To avoid recursive processing of the same file and the same repository + // we maintain an implicit stack of dummy "services" named after the file + // being processed. Anytime we have to open a new file, we then can check + // to see if it is not already being processed by searching for a dummy + // service with a matching name. + if (this->repo_->find (file, 0, 0) >=0) + { + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("ACE (%P|%t) Configuration file %s is currently") + ACE_TEXT (" being processed. Ignoring recursive process_file().\n"), + file)); + return 0; + } + + // Register a dummy service as a forward decl, using the file name as name. + // The entry will be automaticaly removed once the thread exits this block. + ACE_Service_Type_Dynamic_Guard recursion_guard (*this->repo_, + file); + + /* + * @TODO: Test with ACE_USES_CLASSIC_SVC_CONF turned off! + */ +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + int result = 0; + + FILE *fp = ACE_OS::fopen (file, + ACE_TEXT ("r")); + + if (fp == 0) + { + // Invalid svc.conf file. We'll report it here and break out of + // the method. + if (ACE::debug ()) + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t): %p\n"), + file)); + + // Use stat to find out if the file exists. I didn't use access() + // because stat is better supported on most non-unix platforms. + ACE_stat exists; + if (ACE_OS::stat (file, &exists) == 0) + // If it exists, but we couldn't open it for reading then we + // must not have permission to read it. + errno = EPERM; + else + errno = ENOENT; + result = -1; + } + else + { + ACE_Svc_Conf_Param f (this, fp); + + // Keep track of the number of errors. + result = this->process_directives_i (&f); + + (void) ACE_OS::fclose (fp); + } + return result; +#else + ACE_DLL dll; + + auto_ptr + xml_svc_conf (this->get_xml_svc_conf (dll)); + + if (xml_svc_conf.get () == 0) + return -1; + + return xml_svc_conf->parse_file (file); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ +} + +int +ACE_Service_Gestalt::process_directive (const ACE_TCHAR directive[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::process_directive"); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::process_directive, repo=%@ - %s\n"), + this->repo_, + directive)); +#endif + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + ACE_UNUSED_ARG (directive); + + ACE_Svc_Conf_Param d (this, directive); + + return this->process_directives_i (&d); +#else + ACE_DLL dll; + + auto_ptr + xml_svc_conf (this->get_xml_svc_conf (dll)); + + if (xml_svc_conf.get () == 0) + return -1; + + // Temporarily (for the duration of this call) make sure that *any* static + // service registrations will happen with this instance. Such registrations + // are possible as a side-effect of dynamically loading a DLL, which has + // other static services registered. Thus this instance will own both the + // DLL and those static services, which implies that their finalization + // will be performed in the correct order, i.e. prior to finalizing the DLL + ACE_Service_Config_Guard guard (this); + + return xml_svc_conf->parse_string (directive); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + +} /* process_directive () */ + + +int +ACE_Service_Gestalt::init_svc_conf_file_queue (void) +{ + if (this->svc_conf_file_queue_ == 0) + { + ACE_SVC_QUEUE *tmp = 0; + ACE_NEW_RETURN (tmp, + ACE_SVC_QUEUE, + -1); + this->svc_conf_file_queue_ = tmp; + } + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::init_svc_conf_file_queue ") + ACE_TEXT ("- this=%@, repo=%@\n"), + this, this->repo_)); +#endif + + return 0; + +} /* init_svc_conf_file_queue () */ + + +int +ACE_Service_Gestalt::open_i (const ACE_TCHAR /*program_name*/[], + const ACE_TCHAR* /*logger_key*/, + bool ignore_static_svcs, + bool ignore_default_svc_conf_file, + bool ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Gestalt::open_i"); + int result = 0; + ACE_Log_Msg *log_msg = ACE_LOG_MSG; + + no_static_svcs_ = ignore_static_svcs; + + // Record the current log setting upon entering this thread. + u_long old_process_mask = log_msg->priority_mask + (ACE_Log_Msg::PROCESS); + + u_long old_thread_mask = log_msg->priority_mask + (ACE_Log_Msg::THREAD); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::open_i - this=%@, ") + ACE_TEXT ("opened=%d, loadstatics=%d\n"), + this, this->is_opened_, this->no_static_svcs_)); +#endif + + // Guard against reentrant processing. For example, + // if the singleton gestalt (ubergestalt) was already open, + // do not open it again... + if (this->is_opened_++ != 0) + return 0; + + if (this->init_i () != 0) + return -1; + + if (!ignore_debug_flag) + { + // If -d was included as a startup parameter, the user wants debug + // information printed during service initialization. + if (ACE::debug ()) + ACE_Log_Msg::enable_debug_messages (); + else + // The user has requested no debugging info. + ACE_Log_Msg::disable_debug_messages (); + } + + // See if we need to load the static services. + if (this->no_static_svcs_ == 0 + && this->load_static_svcs () == -1) + result = -1; + else + { + if (this->process_commandline_directives () == -1) + result = -1; + else + result = this->process_directives (ignore_default_svc_conf_file); + } + + + // Reset debugging back to the way it was when we came into + // into . + { + // Make sure to save/restore errno properly. + ACE_Errno_Guard error (errno); + + if (!ignore_debug_flag) + { + log_msg->priority_mask (old_process_mask, ACE_Log_Msg::PROCESS); + log_msg->priority_mask (old_thread_mask, ACE_Log_Msg::THREAD); + } + } + + return result; +} /* open_i () */ + + +int +ACE_Service_Gestalt::is_opened (void) +{ + return this->is_opened_; +} + +int +ACE_Service_Gestalt::process_commandline_directives (void) +{ + int result = 0; + if (this->svc_queue_ != 0) + { + ACE_TString *sptr = 0; + for (ACE_SVC_QUEUE_ITERATOR iter (*this->svc_queue_); + iter.next (sptr) != 0; + iter.advance ()) + { + // Process just a single directive. + if (this->process_directive ((sptr->fast_rep ())) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE (%P|%t) %p\n"), + ACE_TEXT ("process_directive"))); + result = -1; + } + } + + delete this->svc_queue_; + this->svc_queue_ = 0; + } + + return result; + +} /* process_commandline_directives () */ + + +int +ACE_Service_Gestalt::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::parse_args"); + bool unused_ignore_default_svc_conf = true; + return parse_args_i (argc, argv, unused_ignore_default_svc_conf); +} + +int +ACE_Service_Gestalt::parse_args_i (int argc, + ACE_TCHAR *argv[], + bool &ignore_default_svc_conf_file) +{ + ACE_TRACE ("ACE_Service_Gestalt::parse_args_i"); + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, + argv, + ACE_TEXT ("df:k:nyS:"), + 1); // Start at argv[1]. + //FUZZ: enable check_for_lack_ACE_OS + + if (this->init_svc_conf_file_queue () == -1) + return -1; + + //FUZZ: disable check_for_lack_ACE_OS + for (int c; (argc != 0) && ((c = getopt ()) != -1); ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case 'd': + ACE::debug (1); + break; + case 'f': + if (this->svc_conf_file_queue_->enqueue_tail (ACE_TString (getopt.opt_arg ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("enqueue_tail")), + -1); + ignore_default_svc_conf_file = true; + break; + case 'k': + /* + * @TODO: Is this always a static storage? Shouldn't we copy + * & gain ownership of the value? + */ + this->logger_key_ = getopt.opt_arg (); + break; + case 'n': + this->no_static_svcs_ = 1; + break; + case 'y': + this->no_static_svcs_ = 0; + break; + case 'S': + if (this->svc_queue_ == 0) + { + ACE_NEW_RETURN (this->svc_queue_, + ACE_SVC_QUEUE, + -1); + } + + if (this->svc_queue_->enqueue_tail (ACE_TString (getopt.opt_arg ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("enqueue_tail")), + -1); + break; + default: + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) %c is not a ACE_Service_Config option\n"), + c)); + } + + return 0; +} /* parse_args_i () */ + + + +// Process service configuration directives from the files queued for +// processing +int +ACE_Service_Gestalt::process_directives (bool ignore_default_svc_conf_file) +{ + ACE_TRACE ("ACE_Service_Gestalt::process_directives"); + + if (this->svc_conf_file_queue_ == 0 + || this->svc_conf_file_queue_->is_empty ()) + return 0; + + ACE_TString *sptr = 0; + ACE_TString default_svc_conf (ACE_DEFAULT_SVC_CONF); + + // Iterate through all the svc.conf files. + for (ACE_SVC_QUEUE_ITERATOR iter (*this->svc_conf_file_queue_); + iter.next (sptr) != 0; + iter.advance ()) + { + if (*sptr == default_svc_conf && ignore_default_svc_conf_file) + continue; + + int result = this->process_file (sptr->fast_rep ()); + if (result < 0) + return result; + } + + return 0; + +} /* process_directives () */ + +// Tidy up and perform last rites on a terminating ACE_Service_Gestalt. +int +ACE_Service_Gestalt::close (void) +{ + ACE_TRACE ("ACE_Service_Gestalt::close"); + + if (!this->is_opened_ || --this->is_opened_ != 0) + return 0; + + // Delete the list fo svc.conf files + delete this->svc_conf_file_queue_; + this->svc_conf_file_queue_ = 0; + + if (this->processed_static_svcs_ && + !this->processed_static_svcs_->is_empty()) + { + Processed_Static_Svc **pss = 0; + for (ACE_PROCESSED_STATIC_SVCS_ITERATOR iter (*this->processed_static_svcs_); + iter.next (pss) != 0; + iter.advance ()) + { + delete *pss; + } + } + delete this->processed_static_svcs_; + this->processed_static_svcs_ = 0; + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SG::close - complete this=%@, repo=%@, owned=%d\n"), + this, this->repo_, this->svc_repo_is_owned_)); +#endif + + if (this->svc_repo_is_owned_) + delete this->repo_; + + this->repo_ = 0; + + return 0; +} /* close () */ + + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Gestalt.inl" +#endif /* __ACE_INLINE__ */ + +// Allocate a Service Manager. +ACE_FACTORY_DEFINE (ACE, ACE_Service_Manager) diff --git a/dep/ACE_wrappers/ace/Service_Gestalt.h b/dep/ACE_wrappers/ace/Service_Gestalt.h new file mode 100644 index 000000000..51d3b9b27 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Gestalt.h @@ -0,0 +1,510 @@ +// -*- C++ -*- + +//==================================================================== +/** + * @file Service_Gestalt.h + * + * $Id: Service_Gestalt.h 81624 2008-05-06 17:14:57Z wotte $ + * + * @author Iliyan Jeliazkov + */ +//==================================================================== + +#ifndef ACE_SERVICE_GESTALT_H +#define ACE_SERVICE_GESTALT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/Default_Constants.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Auto_Ptr.h" +#include "ace/SString.h" +#include "ace/Unbounded_Queue.h" +#include "ace/Unbounded_Set.h" +#include "ace/Service_Repository.h" +#include "ace/Singleton.h" +#include "ace/OS_NS_signal.h" +#include "ace/Synch_Traits.h" +#include "ace/Atomic_Op.h" +#include "ace/Guard_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) +class ACE_Service_Type_Factory; +class ACE_Location_Node; +#else +class ACE_XML_Svc_Conf; +class ACE_DLL; +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + +class ACE_Static_Svc_Descriptor; +class ACE_Svc_Conf_Param; + +/** + * @class ACE_Service_Gestalt + * + * @brief Supplies common server operations for dynamic and static + * configuration of services. + * + * The Gestalt embodies the concept of configuration context. On one + * hand, it is a flat namespace, where names correspond to a Service + * Object instance. A Gestalt owns the Service Repository instance, + * which in turn owns the Service Object instances. + * + * Another aspect of a Gestalt is its responsibility for + * record-keeping and accounting for the meta-data, necessary for + * locating, removing or instantiating a service. + * + * A repository underlies an instance of a gestalt and its lifetime + * may or may not be bounded by the lifetime of the gestalt, that owns + * it. This feature is important for the derived classes and the + * Service Config in particular. + * + */ +class ACE_Export ACE_Service_Gestalt +{ +private: + /// + /// Not implemented to enforce no copying + // + ACE_UNIMPLEMENTED_FUNC (ACE_Service_Gestalt(const ACE_Service_Gestalt&)) + ACE_UNIMPLEMENTED_FUNC (ACE_Service_Gestalt& operator=(const ACE_Service_Gestalt&)) + +public: + enum + { + MAX_SERVICES = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE + }; + + /// Constructor either associates the instance with the process-wide + /// singleton instance of ACE_Service_Repository, or creates and + /// manages its own instance of the specified size. + ACE_Service_Gestalt (size_t size = 1024, + bool svc_repo_is_owned = true, + bool no_static_svcs = true); + + /// Perform user-specified close activities and remove dynamic + /// memory. + ~ACE_Service_Gestalt (void); + + /// Dump the state of an object. + void dump (void) const; + + /** + * Performs an open without parsing command-line arguments. The + * @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. If + * @a ignore_static_svcs is true then static services are not loaded, + * otherwise, they are loaded. If @a ignore_default_svc_conf_file is + * true then the configuration file will be ignored. + * Returns zero upon success, -1 if the file is not found or cannot + * be opened (errno is set accordingly), otherwise returns the + * number of errors encountered loading the services in the + * specified svc.conf configuration file. If @a ignore_debug_flag is + * true then the application is responsible for setting the + * appropriately. + */ + int open (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + bool ignore_static_svcs = true, + bool ignore_default_svc_conf_file = false, + bool ignore_debug_flag = false); + + /** + * This is the primary entry point into the ACE_Service_Config (the + * constructor just handles simple initializations). It parses + * arguments passed in from @a argc and @a argv parameters. The + * arguments that are valid in a call to this method include: + * + * - '-b' Option to indicate that we should be a daemon. Note that when + * this option is used, the process will be daemonized before the + * service configuration file(s) are read. During daemonization, + * (on POSIX systems) the current directory will be changed to "/" + * so the caller should either fully specify the file names, or + * execute a @c chroot() to the appropriate directory. + * @sa ACE::daemonize(). + * - '-d' Turn on debugging mode + * - '-f' Specifies a configuration file name other than the default + * svc.conf. Can be specified multiple times to use multiple files. + * - '-k' Specifies the rendezvous point to use for the ACE distributed + * logger. + * - '-y' Explicitly enables the use of static services. This flag + * overrides the @a ignore_static_svcs parameter value. + * - '-n' Explicitly disables the use of static services. This flag + * overrides the @a ignore_static_svcs parameter value. + * - '-p' Specifies a pathname which is used to store the process id. + * - '-s' Specifies a signal number other than SIGHUP to trigger reprocessing + * of the configuration file(s). Ignored for platforms that do not + * have POSIX signals, such as Windows. + * - '-S' Specifies a service directive string. Enclose the string in quotes + * and escape any embedded quotes with a backslash. This option + * specifies service directives without the need for a configuration + * file. + * + * @param argc The number of commandline arguments. + * @param argv The array with commandline arguments + * @param logger_key Indicates where to write the logging output, + * which is typically either a STREAM pipe or a + * socket address. + * @param ignore_static_svcs If true then static services are not loaded, + * otherwise, they are loaded. + * @param ignore_default_svc_conf_file If false then the @c svc.conf + * configuration file will be ignored. + * @param ignore_debug_flag If false then the application is responsible + * for setting the @c ACE_Log_Msg::priority_mask + * appropriately. + * + * @retval -1 The configuration file is not found or cannot + * be opened (errno is set accordingly). + * @retval 0 Success. + * @retval >0 The number of errors encountered while processing + * the service configuration file(s). + */ + int open (int argc, + ACE_TCHAR *argv[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + bool ignore_static_svcs = true, + bool ignore_default_svc_conf_file = false, + bool ignore_debug_flag = false); + + /// Has it been opened? Returns the difference between the times + /// open and close have been called on this instance + int is_opened (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Process one service configuration @a directive, which is passed as + /// a string. Returns the number of errors that occurred. + int process_directive (const ACE_TCHAR directive[]); + + /// Process one static service definition. + /** + * Load a new static service. + * + * @param ssd Service descriptor, see the document of + * ACE_Static_Svc_Descriptor for more details. + * + * @param force_replace If set the new service descriptor replaces + * any previous instance in the repository. + * + * @return Returns -1 if the service cannot be 'loaded'. + */ + int process_directive (const ACE_Static_Svc_Descriptor &ssd, + bool force_replace = false); + + /// Process a file containing a list of service configuration + /// directives. + int process_file (const ACE_TCHAR file[]); + + /** + * Locate an entry with @a name in the table. If @a ignore_suspended + * is set then only consider services marked as resumed. If the + * caller wants the located entry, pass back a pointer to the + * located entry via @a srp. If @a name is not found, -1 is returned. + * If @a name is found, but it is suspended and the caller wants to + * ignore suspended services a -2 is returned. + */ + int find (const ACE_TCHAR name[], + const ACE_Service_Type **srp = 0, + bool ignore_suspended = true) const; + + /** + * Handle the command-line options intended for the + * ACE_Service_Gestalt. Note that is assumed to be the + * program name. + * + * The arguments that are valid in a call to this method are + * - '-d' Turn on debugging mode + * - '-f' Option to read in the list of svc.conf file names + * - '-k' Option to read a wide string where in the logger output can + * be written + * - '-y' Turn on the flag for a repository of statically + * linked services + * - '-n' Need not have a repository of statically linked services + * - '-S' Option to read in the list of services on the command-line + * Please observe the difference between options '-f' that looks + * for a list of files and here a list of services. + */ + int parse_args (int, ACE_TCHAR *argv[]); + + /** + * Process (or re-process) service configuration requests that are + * provided in the svc.conf file(s). Returns the number of errors + * that occurred. + */ + int process_directives (bool ignore_default_svc_conf_file); + + /// Tidy up and perform last rites when ACE_Service_Config is shut + /// down. This method calls . Returns 0. + int close (void); + + + // Registers a service descriptor for a static service object + int insert (ACE_Static_Svc_Descriptor *stsd); + + // = Utility methods. + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + /// Dynamically link the shared object file and retrieve a pointer to + /// the designated shared object in this file. Also account for the + /// possiblity to have static services registered when loading the DLL, by + /// ensuring that the dynamic sevice is registered before any of its + /// subordibnate static services. Thus avoiding any finalization order + /// problems. + int initialize (const ACE_Service_Type_Factory *, + const ACE_TCHAR *parameters); +#endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */ + + /// Dynamically link the shared object file and retrieve a pointer to + /// the designated shared object in this file. + /// @deprecated + /// @note This is error-prone in the presense of dynamic services, + /// which in turn initialize their own static services. This method + /// will allow those static services to register *before* the dynamic + /// service that owns them. Upon finalization of the static services + /// the process will typically crash, because the dynamic service's + /// DLL may have been already released, together with the memory in + /// which the static services reside. It may not crash, for + /// instance, when the first static service to register is the same + /// as the dynamic service being loaded. You should be so lucky! + int initialize (const ACE_Service_Type *, + const ACE_TCHAR *parameters); + + /// Initialize and activate a statically @a svc_name service. + int initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters); + + /// Resume a @a svc_name that was previously suspended or has not yet + /// been resumed (e.g., a static service). + int resume (const ACE_TCHAR svc_name[]); + + /** + * Suspend @a svc_name. Note that this will not unlink the service + * from the daemon if it was dynamically linked, it will mark it as + * being suspended in the Service Repository and call the + * member function on the appropriate ACE_Service_Object. A + * service can be resumed later on by calling the member + * function... + */ + int suspend (const ACE_TCHAR svc_name[]); + + /// Totally remove @a svc_name from the daemon by removing it + /// from the ACE_Reactor, and unlinking it if necessary. + int remove (const ACE_TCHAR svc_name[]); + + /** + * Using the supplied name, finds and (if needed) returns a pointer to a + * static service descriptor. Returns 0 for success and -1 for failure + */ + int find_static_svc_descriptor (const ACE_TCHAR* name, + ACE_Static_Svc_Descriptor **ssd = 0) const; + + struct Processed_Static_Svc + { + Processed_Static_Svc (const ACE_Static_Svc_Descriptor *); + ~Processed_Static_Svc (void); + ACE_TCHAR * name_; + const ACE_Static_Svc_Descriptor *assd_; + }; + + /// Get the current ACE_Service_Repository held by this object. + ACE_Service_Repository* current_service_repository (void); + +protected: + + int parse_args_i (int, ACE_TCHAR *argv[], + bool& ignore_default_svc_conf_file); + + /** + * Performs an open without parsing command-line arguments. The + * @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. If + * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file + * will be ignored. If @a ignore_debug_flag is non-0 then the + * application is responsible for setting the + * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of + * errors that occurred on failure and 0 otherwise. + */ + int open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + bool ignore_static_svcs = true, + bool ignore_default_svc_conf_file = false, + bool ignore_debug_flag = false); + + /// Initialize the if necessary. + int init_svc_conf_file_queue (void); + + /// Add the default statically-linked services to the + /// ACE_Service_Repository. + int load_static_svcs (void); + + /// Process service configuration requests that were provided on the + /// command-line. Returns the number of errors that occurred. + int process_commandline_directives (void); + + /// Process a static directive without also inserting its descriptor + /// the global table. This avoids multiple additions when processing + /// directives in non-global gestalts. + int process_directive_i (const ACE_Static_Svc_Descriptor &ssd, + bool force_replace = false); + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + /// This is the implementation function that process_directives() + /// and process_directive() both call. Returns the number of errors + /// that occurred. + int process_directives_i (ACE_Svc_Conf_Param *param); +#else + /// Helper function to dynamically link in the XML Service Configurator + /// parser. + ACE_XML_Svc_Conf* get_xml_svc_conf (ACE_DLL &d); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + + /// Dynamically link the shared object file and retrieve a pointer to + /// the designated shared object in this file. + int initialize_i (const ACE_Service_Type *sr, const ACE_TCHAR *parameters); + + const ACE_Static_Svc_Descriptor* find_processed_static_svc (const ACE_TCHAR*); + void add_processed_static_svc (const ACE_Static_Svc_Descriptor *); + + /// Performs the common initialization tasks for a new or previously + /// closed instance. Must not be virtual, as it is called from the + /// constructor. + int init_i (void); + +protected: + + // Maintain a queue of services to be configured from the + // command-line. + typedef ACE_Unbounded_Queue ACE_SVC_QUEUE; + typedef ACE_Unbounded_Queue_Iterator ACE_SVC_QUEUE_ITERATOR; + + // Maintain a set of the statically linked service descriptors. + typedef ACE_Unbounded_Set + ACE_STATIC_SVCS; + + typedef ACE_Unbounded_Set_Iterator + ACE_STATIC_SVCS_ITERATOR; + + typedef ACE_Unbounded_Set + ACE_PROCESSED_STATIC_SVCS; + + typedef ACE_Unbounded_Set_Iterator + ACE_PROCESSED_STATIC_SVCS_ITERATOR; + + friend class ACE_Dynamic_Service_Base; + friend class ACE_Service_Object; + friend class ACE_Service_Config; + friend class ACE_Service_Config_Guard; + +protected: + + /// Do we own the service repository instance, or have only been + /// given a ptr to the singleton? + bool svc_repo_is_owned_; + + /// Repository size is necessary, so that we can close (which may + /// destroy the repository instance), and then re-open again. + size_t svc_repo_size_; + + /// Keep track of the number of times the instance has been + /// initialized (opened). "If so, we can't allow to be called since + /// it's not reentrant" is the original motivation, but that does not seem + /// to be the case anymore. This variable is incremented by the + /// method and decremented by the + /// method. + int is_opened_; + + /// Indicates where to write the logging output. This is typically + /// either a STREAM pipe or a socket + const ACE_TCHAR *logger_key_; + + /// Should we avoid loading the static services? + bool no_static_svcs_; + + /// Queue of services specified on the command-line. + ACE_SVC_QUEUE* svc_queue_; + + /** Queue of svc.conf files specified on the command-line. + * @@ This should probably be made to handle unicode filenames... + */ + ACE_SVC_QUEUE* svc_conf_file_queue_; + + /// The service repository to hold the services. + ACE_Service_Repository* repo_; + + /// Repository of statically linked services. + ACE_STATIC_SVCS* static_svcs_; + + /// Repository of statically linked services for which process + /// directive was called, but the service is not already a member of + /// the static_svcs_ list. + ACE_PROCESSED_STATIC_SVCS* processed_static_svcs_; + + /// Support for intrusive reference counting + ACE_Atomic_Op refcnt_; + + public: + static void intrusive_add_ref (ACE_Service_Gestalt*); + static void intrusive_remove_ref (ACE_Service_Gestalt*); + +}; /* class ACE_Service_Gestalt */ + + +/** + * @class ACE_Service_Type_Dynamic_Guard + * + * @brief A forward service declaration guard. + * + * Helps to resolve an issue with hybrid services, i.e. dynamic + * services, accompanied by static services in the same DLL. Only + * automatic instances of this class are supposed to exist. Those are + * created during (dynamic) service initialization and serve to: + * + * (a) Ensure the service we are loading is ordered last in the + * repository, following any other services it may cause to register, + * as part of its own registration. This is a common case when + * loading dynamic services from DLLs - there are often static + * initializers, which register static services. + * + * (b) The SDG instance destructor detects if the dynamic service + * initialized successfully and "fixes-up" all the newly registered + * static services to hold a reference to the DLL, from which they + * have originated. + */ +class ACE_Export ACE_Service_Type_Dynamic_Guard +{ +public: + ACE_Service_Type_Dynamic_Guard (ACE_Service_Repository &r, + ACE_TCHAR const *name); + + ~ACE_Service_Type_Dynamic_Guard (void); + +private: + ACE_Service_Repository & repo_; + size_t repo_begin_; + ACE_TCHAR const * const name_; + + +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_Guard< ACE_Recursive_Thread_Mutex > repo_monitor_; +#endif +}; + + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Service_Gestalt.inl" +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" + +#endif /* ACE_SERVICE_GESTALT_H */ diff --git a/dep/ACE_wrappers/ace/Service_Gestalt.inl b/dep/ACE_wrappers/ace/Service_Gestalt.inl new file mode 100644 index 000000000..d7de81361 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Gestalt.inl @@ -0,0 +1,76 @@ +// -*- C++ -*- +// +// $Id: Service_Gestalt.inl 81388 2008-04-23 14:02:05Z johnnyw $ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +// This is the primary entry point into the ACE_Service_Config (the +// constructor just handles simple initializations). + +ACE_INLINE int +ACE_Service_Gestalt::open (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf, + bool ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Gestalt::open"); + this->no_static_svcs_ = ignore_static_svcs; + + return this->open_i (program_name, + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag); +} + +ACE_INLINE int +ACE_Service_Gestalt::open (int argc, + ACE_TCHAR *argv[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf, + bool ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Gestalt::open"); + + this->no_static_svcs_ = ignore_static_svcs; + + if (this->parse_args_i (argc, + argv, + ignore_default_svc_conf) == -1) + return -1; + + return this->open_i (argv == 0 ? 0 : argv[0], + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag); +} + +/// Searches for a service object declaration in the local repo, only + +ACE_INLINE int +ACE_Service_Gestalt::find (const ACE_TCHAR name[], + const ACE_Service_Type **srp, + bool ignore_suspended) const +{ + // Closing the gestalt will have disassociated it from the + // repository. If the repository used to be owned by the gestalt, it + // will also have been destroyed - so just check for repo_ before + // doing anything with it. + if (this->repo_ != 0) + return this->repo_->find (name, srp, ignore_suspended); + + return 0; +} + +ACE_INLINE ACE_Service_Repository* +ACE_Service_Gestalt::current_service_repository (void) +{ + return this->repo_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Manager.cpp b/dep/ACE_wrappers/ace/Service_Manager.cpp new file mode 100644 index 000000000..54ceb67f6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Manager.cpp @@ -0,0 +1,437 @@ +// $Id: Service_Manager.cpp 82513 2008-08-05 18:52:53Z parsons $ + +#include "ace/Service_Manager.h" + +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "ace/Service_Repository.h" +#include "ace/Service_Config.h" +#include "ace/Service_Types.h" +#include "ace/Reactor.h" +#include "ace/WFMO_Reactor.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ace, + Service_Manager, + "$Id: Service_Manager.cpp 82513 2008-08-05 18:52:53Z parsons $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE (ACE_Service_Manager) + +void +ACE_Service_Manager::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Manager::dump"); +#endif /* ACE_HAS_DUMP */ +} + +// Static variables. + +u_short ACE_Service_Manager::DEFAULT_PORT_ = 10000; + +ACE_Service_Manager::ACE_Service_Manager (void) + : debug_ (false), + signum_ (SIGHUP) +{ + ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager"); +} + +ACE_Service_Manager::~ACE_Service_Manager (void) +{ + ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager"); +} + +int +ACE_Service_Manager::suspend (void) +{ + ACE_TRACE ("ACE_Service_Manager::suspend"); + return ACE_Reactor::instance ()->suspend_handler (this); +} + +int +ACE_Service_Manager::resume (void) +{ + ACE_TRACE ("ACE_Service_Manager::resume"); + return ACE_Reactor::instance ()->resume_handler (this); +} + +int +ACE_Service_Manager::open (const ACE_INET_Addr &sia) +{ + ACE_TRACE ("ACE_Service_Manager::open"); + + // Reuse the listening address, even if it's already in use! + if (this->acceptor_.open (sia, 1) == -1) + { + return -1; + } + + return 0; +} + +int +ACE_Service_Manager::info (ACE_TCHAR **strp, size_t length) const +{ + ACE_TRACE ("ACE_Service_Manager::info"); + ACE_INET_Addr sa; + ACE_TCHAR buf[BUFSIZ]; + + if (this->acceptor_.get_local_addr (sa) == -1) + { + return -1; + } + + ACE_OS::sprintf (buf, + ACE_TEXT ("%d/%s %s"), + sa.get_port_number (), + ACE_TEXT ("tcp"), + ACE_TEXT ("# lists all services in the daemon\n")); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + { + return -1; + } + else + { + ACE_OS::strsncpy (*strp, buf, length); + } + + return static_cast (ACE_OS::strlen (buf)); +} + +int +ACE_Service_Manager::init (int argc, ACE_TCHAR *argv[]) +{ + ACE_TRACE ("ACE_Service_Manager::init"); + ACE_INET_Addr local_addr (ACE_Service_Manager::DEFAULT_PORT_); + + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("dp:s:"), 0); // Start at argv[0] + + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case 'd': + this->debug_ = true; + break; + case 'p': + local_addr.set ((u_short) ACE_OS::atoi (getopt.opt_arg ())); + break; + case 's': + this->signum_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + default: + break; + } + + if (this->get_handle () == ACE_INVALID_HANDLE && + this->open (local_addr) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open")), -1); + } + else if (ACE_Reactor::instance ()->register_handler + (this, + ACE_Event_Handler::ACCEPT_MASK) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("registering service with ACE_Reactor\n")), + -1); + } + + return 0; +} + +int +ACE_Service_Manager::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Service_Manager::handle_close"); + return this->acceptor_.close (); +} + +int +ACE_Service_Manager::fini (void) +{ + ACE_TRACE ("ACE_Service_Manager::fini"); + + int retv = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + retv = + ACE_Reactor::instance ()->remove_handler ( + this, + ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL); + + this->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::NULL_MASK); + } + + return retv; +} + +ACE_HANDLE +ACE_Service_Manager::get_handle (void) const +{ + ACE_TRACE ("ACE_Service_Manager::get_handle"); + return this->acceptor_.get_handle (); +} + +int +ACE_Service_Manager::handle_signal (int, siginfo_t *, ucontext_t *) +{ + return 0; +} + +// Determine all the services offered by this daemon and return the +// information back to the client. + +int +ACE_Service_Manager::list_services (void) +{ + ACE_TRACE ("ACE_Service_Manager::list_services"); + ACE_Service_Repository_Iterator sri (*ACE_Service_Repository::instance (), 0); + + for (const ACE_Service_Type *sr; + sri.next (sr) != 0; + sri.advance ()) + { + ssize_t len = static_cast (ACE_OS::strlen (sr->name ())) + 11; + ACE_TCHAR buf[BUFSIZ]; + ACE_TCHAR *p = buf + len; + + ACE_OS::strcpy (buf, sr->name ()); + ACE_OS::strcat (buf, (sr->active ()) ? + ACE_TEXT (" (active) ") : + ACE_TEXT (" (paused) ")); + + p[-1] = ' '; + p[0] = '\0'; + + len += sr->type ()->info (&p, sizeof buf - len); + + if (this->debug_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("len = %d, info = %s%s"), + len, + buf, + buf[len - 1] == '\n' ? ACE_TEXT ("") : ACE_TEXT ("\n"))); + } + + if (len > 0) + { + ssize_t n = this->client_stream_.send_n (buf, len); + + if (n <= 0 && errno != EPIPE) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send_n"))); + } + } + } + + return 0; +} + +// Trigger a reconfiguration of the Service Configurator via its +// svc.conf file. + +int +ACE_Service_Manager::reconfigure_services (void) +{ + ACE_TRACE ("ACE_Service_Manager::reconfigure_services"); + +#if 0 +// Send ourselves a signal! ACE_OS::kill (ACE_OS::getpid (), +// this->signum_); +#endif /* 0 */ + + // Flag the main event loop that a reconfiguration should occur. + // The next trip through the should + // pick this up and cause a reconfiguration. Note that we can't + // trigger the reconfiguration automatically since that might "pull + // the rug" out from underneath the existing services in a + // problematic way. + ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1); + return static_cast (this->client_stream_.send_n ("done\n", + sizeof ("done\n"))); +} + +// isolate the request-processing code +void +ACE_Service_Manager::process_request (ACE_TCHAR *request) +{ + ACE_TRACE("ACE_Service_Manager::process_request"); + ACE_TCHAR *p; + + // Kill trailing newlines. + for (p = request; + (*p != '\0') && (*p != '\r') && (*p != '\n'); + p++) + { + continue; + } + + *p = '\0'; + + if (ACE_OS::strcmp (request, ACE_TEXT ("help")) == 0) + { + // Return a list of the configured services. + this->list_services (); + } + else if (ACE_OS::strcmp (request, ACE_TEXT ("reconfigure") )== 0) + { + // Trigger a reconfiguration by re-reading the local file. + this->reconfigure_services (); + } + else + { + // Just process a single request passed in via the socket + // remotely. + ACE_Service_Config_Guard guard (ACE_Service_Config::global ()); + ACE_Service_Config::process_directive (request); + } + + // Additional management services may be handled here... +} + +// Accept new connection from client and carry out the service they +// request. + +int +ACE_Service_Manager::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Service_Manager::handle_input"); + + // Try to find out if the implementation of the reactor that we are + // using requires us to reset the event association for the newly + // created handle. This is because the newly created handle will + // inherit the properties of the listen handle, including its event + // associations. + int reset_new_handle = + ACE_Reactor::instance ()->uses_event_associations (); + + if (this->acceptor_.accept (this->client_stream_, // stream + 0, // remote address + 0, // timeout + 1, // restart + reset_new_handle // reset new handler + ) == -1) + { + return -1; + } + + if (this->debug_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("client_stream fd = %d\n"), + this->client_stream_.get_handle ())); + ACE_INET_Addr sa; + + if (this->client_stream_.get_remote_addr (sa) == -1) + { + return -1; + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("accepted from host %C at port %d\n"), + sa.get_host_name (), + sa.get_port_number ())); + } + + ACE_TCHAR request[BUFSIZ]; + ACE_TCHAR* offset = request; + ssize_t remaining = sizeof (request); + + // Read service request from client. + + ssize_t result; + + // Keep looping until we actually get the request. Note that Win32 + // sets the socket into non-blocking mode, so we may need to loop if + // the system is heavily loaded. Read bytes into the buffer until a + // '\n' or '\r' is found in the buffer, otherwise the buffer + // contains an incomplete string. + + int error; + + do + { + result = client_stream_.recv (offset, remaining); + error = errno; + + if (result == 0 && error != EWOULDBLOCK) + { + remaining = 0; + } + + if (result >= 0) + { + if ((remaining -= result) <= 0) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("Request buffer overflow.\n"))); + result = 0; + break; + } + + offset += result; + *offset = 0; + + if (ACE_OS::strchr (request, '\r') != 0 + || ACE_OS::strchr (request, '\n') != 0) + { + remaining = 0; + } + } + } + while ((result == -1 && error == EWOULDBLOCK) || remaining > 0); + + switch (result) + { + case -1: + if (this->debug_) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("recv"))); + } + + break; + case 0: + return 0; + /* NOTREACHED */ + default: + { + ACE_Event_Handler *old_signal_handler = 0; + ACE_Reactor::instance ()->register_handler (SIGPIPE, + this, + 0, + &old_signal_handler); + + this->process_request (request); + + // Restore existing SIGPIPE handler + ACE_Reactor::instance ()->register_handler (SIGPIPE, + old_signal_handler); + } + } + + if (this->client_stream_.close () == -1 && this->debug_) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close"))); + } + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Manager.h b/dep/ACE_wrappers/ace/Service_Manager.h new file mode 100644 index 000000000..13ce60405 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Manager.h @@ -0,0 +1,120 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Service_Manager.h + * + * $Id: Service_Manager.h 81388 2008-04-23 14:02:05Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_SERVICE_MANAGER_H +#define ACE_SERVICE_MANAGER_H +#include /**/ "ace/pre.h" + +#include "ace/SOCK_Stream.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Acceptor.h" +#include "ace/INET_Addr.h" +#include "ace/Service_Object.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Service_Manager + * + * @brief Provide a standard ACE service for managing all the services + * configured in an ACE_Service_Repository. + * + * This implementation is simple and just handles each client + * request one at a time. There are currently 3 types of requests: + * - List services: If the string "help" is sent, return a list of all + * the services supported by the Service Configurator. + * - Reconfigure: If the string "reconfigure" is sent trigger a + * reconfiguration, which will re-read the local file. + * - Process directive: If neither "help" nor "reconfigure" is sent, + * simply treat the incoming string as a process directive and pass + * it along to . This allows + * remote configuration via command-line instructions like + * % echo suspend My_Remote_Service | telnet hostname 3911 + * + * Each request is associated with a new connection, which is closed + * when the request is processed. In addition, you must be using the + * singleton in order to trigger + * reconfigurations. + */ +class ACE_Export ACE_Service_Manager : public ACE_Service_Object +{ +public: + // = Initialization and termination hooks. + /// Constructor. + ACE_Service_Manager (void); + + /// Destructor. + virtual ~ACE_Service_Manager (void); + +protected: + // = Perform the various meta-services. + + /// Trigger a reconfiguration of the Service Configurator by + /// re-reading its local file. + virtual int reconfigure_services (void); + + /// Determine all the services offered by this daemon and return the + /// information back to the client. + virtual int list_services (void); + + // = Dynamic linking hooks. + virtual int init (int argc, ACE_TCHAR *argv[]); + virtual int info (ACE_TCHAR **info_string, size_t length) const; + virtual int fini (void); + + // = Scheduling hooks. + virtual int suspend (void); + virtual int resume (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + int open (const ACE_INET_Addr &sia); + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE fd); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask); + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + /// Handle one request. + virtual void process_request (ACE_TCHAR *request); + + /// Connection to the client (we only support one client connection + /// at a time). + ACE_SOCK_Stream client_stream_; + + /// Acceptor instance. + ACE_SOCK_Acceptor acceptor_; + + /// Keep track whether we debug or not. + bool debug_; + + /// The signal used to trigger reconfiguration. + int signum_; + + /// Default port for the Acceptor to listen on. + static u_short DEFAULT_PORT_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* _SERVICE_MANAGER_H */ diff --git a/dep/ACE_wrappers/ace/Service_Object.cpp b/dep/ACE_wrappers/ace/Service_Object.cpp new file mode 100644 index 000000000..33e27eb35 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Object.cpp @@ -0,0 +1,180 @@ +// $Id: Service_Object.cpp 81826 2008-06-02 15:29:53Z schmidt $ + +#include "ace/config-all.h" + +#include "ace/Service_Object.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Object.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/OS_NS_stdio.h" +#include "ace/Service_Types.h" +#include "ace/DLL.h" +#include "ace/ACE.h" +#include "ace/Log_Msg.h" +#if defined (ACE_OPENVMS) +# include "ace/Lib_Find.h" +#endif + +ACE_RCSID (ace, + Service_Object, + "$Id: Service_Object.cpp 81826 2008-06-02 15:29:53Z schmidt $") + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Object) + ACE_ALLOC_HOOK_DEFINE(ACE_Service_Type) + + void +ACE_Service_Type::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Type::dump"); +#endif /* ACE_HAS_DUMP */ + + + // Using printf, since the log facility may not have been + // initialized yet. Using a "//" prefix, in case the executable + // happens to be a code generator and the output gets embedded in + // the generated C++ code. + ACE_OS::fprintf(stderr, + "// [ST] dump, this=%p, name=%s, type=%p, so=%p, active=%d\n", + this, + this->name_, + this->type_, + (this->type_ != 0) ? this->type_->object () : 0, + this->active_); + +} + +ACE_Service_Type::ACE_Service_Type (const ACE_TCHAR *n, + ACE_Service_Type_Impl *t, + const ACE_DLL &dll, + bool active) + : name_ (0), + type_ (t), + dll_ (dll), + active_ (active), + fini_already_called_ (false) +{ + ACE_TRACE ("ACE_Service_Type::ACE_Service_Type"); + this->name (n); +} + +ACE_Service_Type::ACE_Service_Type (const ACE_TCHAR *n, + ACE_Service_Type_Impl *t, + ACE_SHLIB_HANDLE handle, + bool active) + : name_ (0), + type_ (t), + active_ (active), + fini_already_called_ (false) +{ + ACE_TRACE ("ACE_Service_Type::ACE_Service_Type"); + this->dll_.set_handle (handle); + this->name (n); +} + +ACE_Service_Type::~ACE_Service_Type (void) +{ + ACE_TRACE ("ACE_Service_Type::~ACE_Service_Type"); + this->fini (); + + delete [] const_cast (this->name_); +} + +int +ACE_Service_Type::fini (void) +{ + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) ST::fini - destroying name=%s, dll=%s\n"), + this->name_, + this->dll_.dll_name_)); + + if (this->fini_already_called_) + return 0; + + this->fini_already_called_ = true; + + if (this->type_ == 0) + { + // Returning 1 currently only makes sense for dummy instances, used + // to "reserve" a spot (kind of like forward-declarations) for a + // dynamic service. This is necessary to help enforce the correct + // finalization order, when such service also has any (dependent) + // static services + + return 1; // No implementation was found. + } + + int ret = this->type_->fini (); + + // Ensure that closing the DLL is done after type_->fini() as it may + // require access to the code for the service object destructor, + // which resides in the DLL + + return (ret | this->dll_.close ()); +} + +int +ACE_Service_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Service_Type::suspend"); + (const_cast (this))->active_ = false; + return this->type_->suspend (); +} + +int +ACE_Service_Type::resume (void) const +{ + ACE_TRACE ("ACE_Service_Type::resume"); + (const_cast (this))->active_ = true; + return this->type_->resume (); +} + +ACE_Service_Object::ACE_Service_Object (ACE_Reactor *r) + : ACE_Event_Handler (r) +{ + ACE_TRACE ("ACE_Service_Object::ACE_Service_Object"); +} + +ACE_Service_Object::~ACE_Service_Object (void) +{ + ACE_TRACE ("ACE_Service_Object::~ACE_Service_Object"); +} + +int +ACE_Service_Object::suspend (void) +{ + ACE_TRACE ("ACE_Service_Object::suspend"); + return 0; +} + +int +ACE_Service_Object::resume (void) +{ + ACE_TRACE ("ACE_Service_Object::resume"); + return 0; +} + +void +ACE_Service_Type::name (const ACE_TCHAR *n) +{ + ACE_TRACE ("ACE_Service_Type::name"); + + delete [] const_cast (this->name_); + this->name_ = ACE::strnew (n); +} + +#if defined (ACE_OPENVMS) +ACE_Dynamic_Svc_Registrar::ACE_Dynamic_Svc_Registrar (const ACE_TCHAR* alloc_name, + void* svc_allocator) +{ + // register service allocator function by full name in ACE singleton registry + ACE::ldregister (alloc_name, svc_allocator); +} +#endif + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Object.h b/dep/ACE_wrappers/ace/Service_Object.h new file mode 100644 index 000000000..d64cebba6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Object.h @@ -0,0 +1,207 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Service_Object.h + * + * $Id: Service_Object.h 81388 2008-04-23 14:02:05Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_SERVICE_OBJECT_H +#define ACE_SERVICE_OBJECT_H +#include /**/ "ace/pre.h" + +#include "ace/Shared_Object.h" +#include "ace/Svc_Conf_Tokens.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event_Handler.h" +#include "ace/DLL.h" + +#include "ace/Service_Gestalt.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#define ACE_Component ACE_Service_Object + +/** + * @class ACE_Service_Object + * + * @brief Provide the abstract base class common to all service + * implementations. + * + * Classes that inherit from ACE_Service_Objects are capable + * of being registered with the ACE_Reactor (due to the + * ACE_Event_Handler, as well as being dynamically linked by + * the ACE_Service_Config (due to the ACE_Shared_Object). + */ +class ACE_Export ACE_Service_Object + : public ACE_Event_Handler, + public ACE_Shared_Object +{ +public: + // = Initialization and termination methods. + /// Constructor. + ACE_Service_Object (ACE_Reactor * = 0); + + /// Destructor. + virtual ~ACE_Service_Object (void); + + /// Temporarily disable a service without removing it completely. + virtual int suspend (void); + + /// Re-enable a previously suspended service. + virtual int resume (void); +}; + +// Forward decl. +class ACE_Service_Type_Impl; + +/** + * @class ACE_Service_Type + * + * @brief Keeps track of information related to the various + * ACE_Service_Type_Impl subclasses. + * + * This class acts as the interface of the "Bridge" pattern. + */ +class ACE_Export ACE_Service_Type +{ +public: + enum + { + /// Delete the payload object. + DELETE_OBJ = 1, + + /// Delete the enclosing object. + DELETE_THIS = 2 + }; + + enum + { + SERVICE_OBJECT = ACE_SVC_OBJ_T, + MODULE = ACE_MODULE_T, + STREAM = ACE_STREAM_T, + INVALID_TYPE = -1 + }; + + // = Initialization and termination methods. + ACE_Service_Type (const ACE_TCHAR *n, + ACE_Service_Type_Impl *o, + const ACE_DLL &dll, + bool active); + ACE_Service_Type (const ACE_TCHAR *n, + ACE_Service_Type_Impl *o, + ACE_SHLIB_HANDLE handle, + bool active); + ~ACE_Service_Type (void); + + const ACE_TCHAR *name (void) const; + void name (const ACE_TCHAR *); + + const ACE_Service_Type_Impl *type (void) const; + void type (const ACE_Service_Type_Impl *, bool active = true); + + /// Is this just a stub for the real thing? + bool is_forward_declaration (void) const; + + int suspend (void) const; + int resume (void) const; + bool active (void) const; + void active (bool turnon); + + /// Calls on + int fini (void); + + /// Check if the service has been fini'ed. + bool fini_called (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Get to the DLL's implentation + const ACE_DLL & dll (void) const; + + /// Sets the DLL + void dll (const ACE_DLL&); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Humanly readible name of svc. + const ACE_TCHAR *name_; + + /// Pointer to C++ object that implements the svc. + const ACE_Service_Type_Impl *type_; + + /// ACE_DLL representing the shared object file (non-zero if + /// dynamically linked). + mutable ACE_DLL dll_; + + /// true if svc is currently active, otherwise false. + bool active_; + + /// true if on has already been called, otherwise false. + bool fini_already_called_; +}; + +/** + * @class ACE_Service_Object_Ptr + * + * @brief This is a smart pointer that holds onto the associated + * ACE_Service_Object * until the current scope is left, at + * which point the object's hook is called and the + * service_object_ gets deleted. + * + * This class is similar to the Standard C++ Library class + * . It is used in conjunction with statically linked + * , as shown in the + * ./netsvcs/server/main.cpp example. + */ +class ACE_Export ACE_Service_Object_Ptr +{ +public: + // = Initialization and termination methods. + /// Acquire ownership of the @a so. + ACE_Service_Object_Ptr (ACE_Service_Object *so); + + /// Release the held ACE_Service_Object by calling its hook. + ~ACE_Service_Object_Ptr (void); + + /// Smart pointer to access the underlying ACE_Service_Object. + ACE_Service_Object *operator-> (); + +private: + /// Holds the service object until we're done. + ACE_Service_Object *service_object_; +}; + +#if defined (ACE_OPENVMS) +/** + * @class ACE_Dynamic_Svc_Registrar + * + * @brief Used to register Service allocator function by its full name. + */ +class ACE_Dynamic_Svc_Registrar +{ +public: + ACE_Dynamic_Svc_Registrar (const ACE_TCHAR* alloc_name, + void* svc_allocator); +}; +#endif + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Service_Object.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SERVICE_OBJECT_H */ diff --git a/dep/ACE_wrappers/ace/Service_Object.inl b/dep/ACE_wrappers/ace/Service_Object.inl new file mode 100644 index 000000000..6283f3e99 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Object.inl @@ -0,0 +1,79 @@ +// -*- C++ -*- +// $Id: Service_Object.inl 81388 2008-04-23 14:02:05Z johnnyw $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ACE_Service_Object_Ptr::ACE_Service_Object_Ptr (ACE_Service_Object *so) + : service_object_ (so) +{ +} + +ACE_INLINE ACE_Service_Object_Ptr::~ACE_Service_Object_Ptr (void) +{ + this->service_object_->fini (); + delete this->service_object_; +} + +ACE_INLINE ACE_Service_Object * +ACE_Service_Object_Ptr::operator-> () +{ + return this->service_object_; +} + +ACE_INLINE const ACE_TCHAR * +ACE_Service_Type::name (void) const +{ + ACE_TRACE ("ACE_Service_Type::name"); + return this->name_; +} + +ACE_INLINE const ACE_Service_Type_Impl * +ACE_Service_Type::type (void) const +{ + ACE_TRACE ("ACE_Service_Type::type"); + return this->type_; +} + +ACE_INLINE void +ACE_Service_Type::type (const ACE_Service_Type_Impl *o, bool enabled) +{ + ACE_TRACE ("ACE_Service_Type::type"); + this->type_ = o; + ((ACE_Service_Type *) this)->active_ = enabled; +} + +ACE_INLINE bool +ACE_Service_Type::active (void) const +{ + ACE_TRACE ("ACE_Service_Type::active"); + return this->active_; +} + +ACE_INLINE void +ACE_Service_Type::active (bool turnon) +{ + ACE_TRACE ("ACE_Service_Type::active"); + this->active_ = turnon; +} + +ACE_INLINE bool +ACE_Service_Type::fini_called (void) const +{ + ACE_TRACE ("ACE_Service_Type::fini_called"); + return this->fini_already_called_; +} + +ACE_INLINE const ACE_DLL & ACE_Service_Type::dll () const +{ + ACE_TRACE ("ACE_Service_Type::dll"); + return this->dll_; +} + +ACE_INLINE void ACE_Service_Type::dll (const ACE_DLL &adll) +{ + ACE_TRACE ("ACE_Service_Type::dll"); + this->dll_ = adll; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + diff --git a/dep/ACE_wrappers/ace/Service_Repository.cpp b/dep/ACE_wrappers/ace/Service_Repository.cpp new file mode 100644 index 000000000..18fafe05b --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Repository.cpp @@ -0,0 +1,637 @@ +// $Id: Service_Repository.cpp 81388 2008-04-23 14:02:05Z johnnyw $ + +#include "ace/Service_Repository.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Repository.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Service_Types.h" +#include "ace/Object_Manager.h" +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ace, + Service_Repository, + "$Id: Service_Repository.cpp 81388 2008-04-23 14:02:05Z johnnyw $") + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository) + +// Process-wide Service Repository. +ACE_Service_Repository *ACE_Service_Repository::svc_rep_ = 0; + +// Controls whether the Service_Repository is deleted when we shut +// down (we can only delete it safely if we created it)! +bool ACE_Service_Repository::delete_svc_rep_ = false; + +void +ACE_Service_Repository::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Repository::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Service_Repository::ACE_Service_Repository (void) + : service_vector_ (0), + current_size_ (0), + total_size_ (0) +{ + ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository"); +} + +ACE_Service_Repository * +ACE_Service_Repository::instance (size_t size /* = ACE_Service_Repository::DEFAULT_SIZE */) +{ + ACE_TRACE ("ACE_Service_Repository::instance"); + + if (ACE_Service_Repository::svc_rep_ == 0) + { + // Perform Double-Checked Locking Optimization. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + if (ACE_Service_Repository::svc_rep_ == 0) + { + if (ACE_Object_Manager::starting_up () || + !ACE_Object_Manager::shutting_down ()) + { + ACE_NEW_RETURN (ACE_Service_Repository::svc_rep_, + ACE_Service_Repository (size), + 0); + ACE_Service_Repository::delete_svc_rep_ = true; + } + } + } + + return ACE_Service_Repository::svc_rep_; +} + +ACE_Service_Repository * +ACE_Service_Repository::instance (ACE_Service_Repository *s) +{ + ACE_TRACE ("ACE_Service_Repository::instance"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + + ACE_Service_Repository *t = ACE_Service_Repository::svc_rep_; + // We can't safely delete it since we don't know who created it! + ACE_Service_Repository::delete_svc_rep_ = false; + + ACE_Service_Repository::svc_rep_ = s; + return t; +} + +void +ACE_Service_Repository::close_singleton (void) +{ + ACE_TRACE ("ACE_Service_Repository::close_singleton"); + + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance ())); + + if (ACE_Service_Repository::delete_svc_rep_) + { + delete ACE_Service_Repository::svc_rep_; + ACE_Service_Repository::svc_rep_ = 0; + ACE_Service_Repository::delete_svc_rep_ = false; + } +} + +// Initialize the Repository to a clean slate. + +int +ACE_Service_Repository::open (size_t size) +{ + ACE_TRACE ("ACE_Service_Repository::open"); + + ACE_Service_Type **temp = 0; + + ACE_NEW_RETURN (temp, + ACE_Service_Type *[size], + -1); + + this->service_vector_ = const_cast (temp); + this->total_size_ = size; + return 0; +} + +ACE_Service_Repository::ACE_Service_Repository (size_t size) + : current_size_ (0) +{ + ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository"); + + if (this->open (size) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Service_Repository"))); +} + +// Finalize (call and possibly delete) all the services. + +int +ACE_Service_Repository::fini (void) +{ + ACE_TRACE ("ACE_Service_Repository::fini"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (this->service_vector_ == 0) + return 0; + + int retval = 0; + + // Do not be tempted to use the prefix decrement operator. Use + // postfix decrement operator since the index is unsigned and may + // wrap around the 0 + for (size_t i = this->current_size_; i-- != 0; ) + { + // the services in reverse order. + ACE_Service_Type *s = + const_cast (this->service_vector_[i]); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + { + if (s != 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ") + ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), + this, + i, + this->total_size_, + s->name(), + s->type (), + (s->type () != 0) ? s->type ()->object () : 0, + s->active ())); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d) -> 0\n"), + this, + i, + this->total_size_)); + } +#endif + + // Collect any errors. + if (s != 0) + retval += s->fini (); + } + + return (retval == 0) ? 0 : -1; +} + +// Close down all the services. + +int +ACE_Service_Repository::close (void) +{ + ACE_TRACE ("ACE_Service_Repository::close"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (this->service_vector_ == 0) + return 0; + +#ifndef ACE_NLOGGING + if(ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) SR::close - repo=%@, size=%d\n"), + this, + this->current_size_)); +#endif + + // Do not use the prefix decrement operator since the index is + // unsigned and may wrap around the 0. + for (size_t i = this->current_size_; i-- != 0; ) + { + // Delete services in reverse order. + ACE_Service_Type *s = + const_cast (this->service_vector_[i]); + +#ifndef ACE_NLOGGING + if(ACE::debug ()) + { + if (s == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) SR::close - repo=%@ [%d] -> 0\n"), + this, + i)); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) SR::close - repo=%@ [%d], name=%s, object=%@\n"), + this, + i, + s->name (), + s)); + } +#endif + --this->current_size_; + delete s; + } + + delete [] this->service_vector_; + this->service_vector_ = 0; + this->current_size_ = 0; + + return 0; +} + +ACE_Service_Repository::~ACE_Service_Repository (void) +{ + ACE_TRACE ("ACE_Service_Repository::~ACE_Service_Repository"); +#ifndef ACE_NLOGGING + if(ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) SR::, this=%@\n", this)); +#endif + this->close (); +} + +// Locate an entry with in the table. If is +// set then only consider services marked as resumed. If the caller +// wants the located entry, pass back a pointer to the located entry +// via . If is not found -1 is returned. If is +// found, but it is suspended and the caller wants to ignore suspended +// services a -2 is returned. Must be called with locks held. + +int +ACE_Service_Repository::find_i (const ACE_TCHAR name[], + size_t &slot, + const ACE_Service_Type **srp, + bool ignore_suspended) const +{ + ACE_TRACE ("ACE_Service_Repository::find_i"); + size_t i; + + for (i = 0; i < this->current_size_; i++) + { + if (this->service_vector_[i] != 0 // skip any empty slots + && ACE_OS::strcmp (name, + this->service_vector_[i]->name ()) == 0) + break; + } + + if (i < this->current_size_) + { + slot = i; + if (this->service_vector_[i]->fini_called ()) + { + if (srp != 0) + *srp = 0; + return -1; + } + + if (srp != 0) + *srp = this->service_vector_[i]; + + if (ignore_suspended + && this->service_vector_[i]->active () == 0) + return -2; + + return 0; + } + + return -1; +} + + +/// @brief Relocate (a static) service to another DLL. +/// +/// Works by having the service type keep a reference to a specific +/// DLL. No locking, caller makes sure calling it is safe. You can +/// forcefully relocate any DLLs in the given range, not only the +/// static ones - but that will cause Very Bad Things (tm) to happen. + +int +ACE_Service_Repository::relocate_i (size_t begin, + size_t end, + const ACE_DLL& adll) +{ + ACE_SHLIB_HANDLE new_handle = adll.get_handle (0); + + for (size_t i = begin; i < end; i++) + { + ACE_Service_Type *type = + const_cast (this->service_vector_[i]); + + ACE_SHLIB_HANDLE old_handle = (type == 0) ? ACE_SHLIB_INVALID_HANDLE + : type->dll ().get_handle (0); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + { + if (type == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)") + ACE_TEXT (": skipping empty slot\n"), + this, + i, + this->total_size_)); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)") + ACE_TEXT (": trying name=%s, handle: %d -> %d\n"), + this, + i, + this->total_size_, + type->name (), + old_handle, + new_handle)); + } +#endif + + if (type != 0 // skip any gaps + && old_handle == ACE_SHLIB_INVALID_HANDLE + && new_handle != old_handle) + { +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)") + ACE_TEXT (": relocating name=%s, handle: %d -> %d\n"), + this, + i, + this->total_size_, + type->name (), + old_handle, + new_handle)); +#endif + type->dll (adll); // ups the refcount on adll + } + } + + return 0; +} + +int +ACE_Service_Repository::find (const ACE_TCHAR name[], + const ACE_Service_Type **srp, + bool ignore_suspended) const +{ + ACE_TRACE ("ACE_Service_Repository::find"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + size_t ignore_location = 0; + return this->find_i (name, ignore_location, srp, ignore_suspended); +} + + +// Insert the ACE_Service_Type SR into the repository. Note that +// services may be inserted either resumed or suspended. Using same +// name as in an existing service causes the delete () to be called +// for the old one, i.e. make sure @code sr is allocated on the heap! +int +ACE_Service_Repository::insert (const ACE_Service_Type *sr) +{ + ACE_TRACE ("ACE_Service_Repository::insert"); + + size_t i = 0; + int return_value = -1; + ACE_Service_Type const *s = 0; + + // Establish scope for locking while manipulating the service + // storage + { + // @TODO: Do we need a recursive mutex here? + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, + ace_mon, + this->lock_, + -1)); + + return_value = find_i (sr->name (), i, &s, false); + + // Adding an entry. + if (s != 0) + { + this->service_vector_[i] = sr; + } + else + { + // New services are always added where current_size_ points, + // because if any DLL relocation needs to happen, it will be + // performed on services with indexes between some old + // current_size_ and the new current_size_ value. See + // ACE_Service_Type_Dynamic_Guard ctor and dtor for details. + + if (i < this->current_size_) + i = this->current_size_; + + if (i < this->total_size_) + { + this->service_vector_[i] = sr; + this->current_size_++; + return_value = 0; + } + else + { + return_value = -1; // no space left + } + + // Since there may be "holes" left by removed services one + // could consider wrapping current_size_ modulo + // total_size_. This is going to impact + // ACE_Service_Type_Dynamic_Guard, too and is tricky. Perhaps + // a new directive, like "reload" would be better as it can + // combine the removal and insertion in an atomic step and + // avoid creating too many "holes". + } + } +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::insert - repo=%@ [%d] (%d),") + ACE_TEXT (" name=%s (%s) (type=%@, object=%@, active=%d)\n"), + this, + i, + this->total_size_, + sr->name(), + (return_value == 0 ? ((s==0) ? "new" : "replacing") : "failed"), + sr->type (), + (sr->type () != 0) ? sr->type ()->object () : 0, + sr->active ())); +#endif + + // If necessary, delete but outside the lock. (s may be 0, but + // that's okay, too) + delete s; + + if (return_value == -1) + ACE_OS::last_error (ENOSPC); + + return return_value; +} + +// Resume a service that was previously suspended. +int +ACE_Service_Repository::resume (const ACE_TCHAR name[], + const ACE_Service_Type **srp) +{ + ACE_TRACE ("ACE_Service_Repository::resume"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t i = 0; + if (-1 == this->find_i (name, i, srp, 0)) + return -1; + + return this->service_vector_[i]->resume (); +} + +// Suspend a service so that it will not be considered active under +// most circumstances by other portions of the ACE_Service_Repository. + +int +ACE_Service_Repository::suspend (const ACE_TCHAR name[], + const ACE_Service_Type **srp) +{ + ACE_TRACE ("ACE_Service_Repository::suspend"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + size_t i = 0; + if (-1 == this->find_i (name, i, srp, 0)) + return -1; + + return this->service_vector_[i]->suspend (); +} + + +/** + * @brief Completely remove a entry from the Repository and + * dynamically unlink it if it was originally dynamically linked. + */ + +int +ACE_Service_Repository::remove (const ACE_TCHAR name[], ACE_Service_Type **ps) +{ + ACE_TRACE ("ACE_Service_Repository::remove"); + ACE_Service_Type *s = 0; + { + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + // Not found!? + if (this->remove_i (name, &s) == -1) + return -1; + } + + if (ps != 0) + *ps = s; + else + delete s; + return 0; +} + +/** + * @brief Completely remove a entry from the Repository and + * dynamically unlink it if it was originally dynamically linked. + * + * Return a ptr to the entry in @code ps. There is no locking so make + * sure you hold the repo lock when calling. + * + * Since the order of services in the Respository matters, we can't + * simply overwrite the entry being deleted with the last and + * decrement the by 1. A good example of why the order + * matters is a dynamic service, in whose DLL there is at least one + * static service. In order to prevent SEGV during finalization, those + * static services must be finalized _before_the dynamic service that + * owns them. Otherwice the TEXT segment, containing the code for the + * static service's desructor may be unloaded with the DLL. + * + * Neither can we "pack" the array because this may happen inside the + * scope of a Service_Dynamic_Guard, which caches an index where + * loading of a DLL started in order to relocate dependent services. + */ +int +ACE_Service_Repository::remove_i (const ACE_TCHAR name[], ACE_Service_Type **ps) +{ + size_t i = 0; + if (-1 == this->find_i (name, i, 0, false)) + return -1; // Not found + + // We may need the old ptr - to be delete outside the lock! + *ps = const_cast (this->service_vector_[i]); + +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::remove_i - repo=%@ [%d] (%d),") + ACE_TEXT (" name=%s (removed) (type=%@, active=%d)\n"), + this, + i, + this->total_size_, + name, + *ps, + (*ps)->active ())); +#endif + + this->service_vector_[i] = 0; // simply leave a gap + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository_Iterator) + +void +ACE_Service_Repository_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Repository_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + + +// Initializes the iterator and skips over any suspended entries at +// the beginning of the table, if necessary. Note, you must not +// perform destructive operations on elements during this iteration... + +ACE_Service_Repository_Iterator::ACE_Service_Repository_Iterator + (ACE_Service_Repository &sr, int ignr_suspended) + : svc_rep_ (sr), + next_ (0), + ignore_suspended_ (ignr_suspended) +{ + while (!(done() || valid())) + this->next_++; +} + +// Obtains a pointer to the next valid service in the table. If there +// are no more entries, returns 0, else 1. + +int +ACE_Service_Repository_Iterator::next (const ACE_Service_Type *&sr) +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::next"); + + if (done ()) + return 0; + + sr = this->svc_rep_.service_vector_[this->next_]; + return 1; +} + +// Advance the iterator by the proper amount. If we are ignoring +// suspended entries and the current entry is suspended, then we must +// skip over this entry. Otherwise, we must advance the NEXT index to +// reference the next valid service entry. + +int +ACE_Service_Repository_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::advance"); + + if (done()) return 0; + + do this->next_++; while (!(done () || valid ())); + + return !done(); +} + +bool +ACE_Service_Repository_Iterator::valid (void) const +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::valid"); + if (!this->ignore_suspended_) + return (this->svc_rep_.service_vector_[this->next_] != 0); // skip over gaps + + return (this->svc_rep_.service_vector_[this->next_] != 0 + && this->svc_rep_.service_vector_[this->next_]->active ()); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Repository.h b/dep/ACE_wrappers/ace/Service_Repository.h new file mode 100644 index 000000000..30c11ce6c --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Repository.h @@ -0,0 +1,280 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Service_Repository.h + * + * $Id: Service_Repository.h 81388 2008-04-23 14:02:05Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_SERVICE_REPOSITORY_H +#define ACE_SERVICE_REPOSITORY_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Default_Constants.h" +#include "ace/Recursive_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Service_Type; +class ACE_DLL; + +#define ACE_Component_Repository ACE_Service_Repository +/** + * @class ACE_Service_Repository + * + * @brief Contains all the services offered by a Service + * Configurator-based application. + * + * This class contains a vector of *'s and + * allows an administrative entity to centrally manage and + * control the behavior of application services. Note that if + * services are removed from the middle of the repository the + * order won't necessarily be maintained since the + * method performs compaction. However, the common case is not + * to remove services, so typically they are deleted in the + * reverse order that they were added originally. + */ +class ACE_Export ACE_Service_Repository +{ +public: + friend class ACE_Service_Repository_Iterator; + + enum + { + DEFAULT_SIZE = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE + }; + + // = Initialization and termination methods. + /// Initialize the repository. + ACE_Service_Repository (void); + + /// Initialize the repository. + ACE_Service_Repository (size_t size); + + /// Initialize the repository. + int open (size_t size = DEFAULT_SIZE); + + /// Close down the repository and free up dynamically allocated + /// resources. + ~ACE_Service_Repository (void); + + /// Close down the repository and free up dynamically allocated + /// resources. + int close (void); + + /// Finalize all the services by calling and deleting + /// dynamically allocated services. + int fini (void); + + /// Get pointer to a process-wide ACE_Service_Repository. + static ACE_Service_Repository * instance + (size_t size = ACE_Service_Repository::DEFAULT_SIZE); + + /// Set pointer to a process-wide ACE_Service_Repository and return + /// existing pointer. + static ACE_Service_Repository *instance (ACE_Service_Repository *); + + /// Delete the dynamically allocated Singleton. + static void close_singleton (void); + + // = Search structure operations (all acquire locks as necessary). + + /// Insert a new service record. Returns -1 when the service repository + /// is full and 0 on success. + int insert (const ACE_Service_Type *); + + /** + * Locate a named entry in the service table, optionally ignoring + * suspended entries. + * + * @param service_name The name of the service to search for. + * @param srp Optional; if not 0, it is a pointer to a location + * to receive the ACE_Service_Type pointer for the + * located service. Meaningless if this method + * returns -1. + * @param ignore_suspended If true, the search ignores suspended services. + * + * @retval 0 Named service was located. + * @retval -1 Named service was not found. + * @retval -2 Named service was found, but is suspended and + * @a ignore_suspended is true. + */ + int find (const ACE_TCHAR name[], + const ACE_Service_Type **srp = 0, + bool ignore_suspended = true) const; + + /// Remove an existing service record. If @a sr == 0, the service record + /// is deleted before control is returned to the caller. If @a sr != 0, + /// the service's record is removed from the repository, but not deleted; + /// *sr receives the service record pointer and the caller is responsible + /// for properly disposing of it. + int remove (const ACE_TCHAR[], ACE_Service_Type **sr = 0); + + // = Liveness control + /// Resume a service record. + int resume (const ACE_TCHAR[], const ACE_Service_Type ** = 0); + + /// Suspend a service record. + int suspend (const ACE_TCHAR[], const ACE_Service_Type ** = 0); + + /// Return the current size of the repository. + size_t current_size (void) const; + + /// Return the total size of the repository. + size_t total_size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + friend class ACE_Service_Type_Dynamic_Guard; + + /// Remove an existing service record. It requires @a sr != 0, which + /// receives the service record pointer and the caller is + /// responsible for properly disposing of it. + int remove_i (const ACE_TCHAR[], ACE_Service_Type **sr); + + /** + * Locate a named entry in the service table, optionally ignoring + * suspended entries. + * + * @param service_name The name of the service to search for. + * @param slot Receives the position index of the service if it + * is found. Contents are meaningless if this method + * returns -1. + * @param srp Optional; if not 0, it is a pointer to a location + * to receive the ACE_Service_Type pointer for the + * located service. Meaningless if this method + * returns -1. + * @param ignore_suspended If true, the search ignores suspended services. + * + * @retval 0 Named service was located; index in the table is set in + * @a slot. + * @retval -1 Named service was not found. + * @retval -2 Named service was found, but is suspended and + * @a ignore_suspended is true. + */ + int find_i (const ACE_TCHAR service_name[], + size_t &slot, + const ACE_Service_Type **srp = 0, + bool ignore_suspended = true) const; + + /// @brief Relocate (static) services to another DLL. + /// + /// If any have been registered in the context of a "forward + /// declaration" guard, those really aren't static services. Their + /// code is in the DLL's code segment, or in one of the dependent + /// DLLs. Therefore, such services need to be associated with the + /// proper DLL in order to prevent failures upon finalization. The + /// method locks the repo. + /// + /// Works by having the service type keep a reference to a specific + /// DLL. No locking, caller makes sure calling it is safe. You can + /// forcefully relocate any DLLs in the given range, not only the + /// static ones - but that will cause Very Bad Things (tm) to happen. + + int relocate_i (size_t begin, + size_t end, + const ACE_DLL &adll); + + /// Contains all the configured services. + const ACE_Service_Type **service_vector_; + + /// Current number of services. + size_t current_size_; + + /// Maximum number of services. + size_t total_size_; + + /// Pointer to a process-wide ACE_Service_Repository. + static ACE_Service_Repository *svc_rep_; + + /// Must delete the if true. + static bool delete_svc_rep_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Synchronization variable for the MT_SAFE Repository + mutable ACE_Recursive_Thread_Mutex lock_; +#endif /* ACE_MT_SAFE */ +}; + +/** + * @class ACE_Service_Repository_Iterator + * + * @brief Iterate through the ACE_Service_Repository. + * + * Make sure not to delete entries as the iteration is going on + * since this class is not designed as a robust iterator. + */ +class ACE_Export ACE_Service_Repository_Iterator +{ +public: + // = Initialization and termination methods. + /// Constructor initializes the iterator. + ACE_Service_Repository_Iterator (ACE_Service_Repository &sr, + int ignored_suspended = 1); + + /// Destructor. + ~ACE_Service_Repository_Iterator (void); + + +public: + // = Iteration methods. + + /// Pass back the that hasn't been seen in the repository. + /// Returns 0 when all items have been seen, else 1. + int next (const ACE_Service_Type *&next_item); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Move forward by one element in the repository. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + bool valid (void) const; + +private: + ACE_Service_Repository_Iterator (const ACE_Service_Repository_Iterator&); + + /// Reference to the Service Repository we are iterating over. + ACE_Service_Repository &svc_rep_; + + /// Next index location that we haven't yet seen. + size_t next_; + + /// Are we ignoring suspended services? + bool ignore_suspended_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Service_Repository.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* _SERVICE_REPOSITORY_H */ diff --git a/dep/ACE_wrappers/ace/Service_Repository.inl b/dep/ACE_wrappers/ace/Service_Repository.inl new file mode 100644 index 000000000..621c837ef --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Repository.inl @@ -0,0 +1,51 @@ +// -*- C++ -*- +// +// $Id: Service_Repository.inl 80826 2008-03-04 14:51:23Z wotte $ + +// Returns a count of the number of currently valid entries (counting +// both resumed and suspended entries). + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +#include "ace/Guard_T.h" +#include "ace/Thread_Mutex.h" +#endif /* ACE_MT_SAFE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE size_t +ACE_Service_Repository::current_size (void) const +{ + ACE_TRACE ("ACE_Service_Repository::current_size"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, + ace_mon, + (ACE_Recursive_Thread_Mutex &) this->lock_, 0)); + return this->current_size_; +} + +// Returns a count of the total number of possible entries in the +// table. + +ACE_INLINE size_t +ACE_Service_Repository::total_size (void) const +{ + ACE_TRACE ("ACE_Service_Repository::total_size"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, + ace_mon, + (ACE_Recursive_Thread_Mutex &) this->lock_, 0)); + return this->total_size_; +} + +ACE_INLINE int +ACE_Service_Repository_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::done"); + + return this->next_ >= this->svc_rep_.current_size_; +} + +ACE_INLINE +ACE_Service_Repository_Iterator::~ACE_Service_Repository_Iterator (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Templates.h b/dep/ACE_wrappers/ace/Service_Templates.h new file mode 100644 index 000000000..d05d0d611 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Templates.h @@ -0,0 +1,29 @@ + +//============================================================================= +/** + * @file Service_Templates.h + * + * $Id: Service_Templates.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Priyanka Gontla + */ +//============================================================================= + + +#ifndef ACE_SERVICE_TEMPLATES_H +#define ACE_SERVICE_TEMPLATES_H +#include /**/ "ace/pre.h" + +#include "ace/Svc_Conf.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Auto_Ptr.h" +#include "ace/Thread_Manager.h" +#include "ace/Stream_Modules.h" +#include "ace/Stream.h" + +#include /**/ "ace/post.h" +#endif /* ACE_SERVICE_TEMPLATES_H */ diff --git a/dep/ACE_wrappers/ace/Service_Types.cpp b/dep/ACE_wrappers/ace/Service_Types.cpp new file mode 100644 index 000000000..46c671beb --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Types.cpp @@ -0,0 +1,453 @@ +// $Id: Service_Types.cpp 81826 2008-06-02 15:29:53Z schmidt $ + +#include "ace/Service_Types.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Types.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Stream_Modules.h" +#include "ace/Stream.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + + +ACE_RCSID (ace, + Service_Types, + "$Id: Service_Types.cpp 81826 2008-06-02 15:29:53Z schmidt $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; +typedef ACE_Task MT_Task; + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Type_Impl) + +void +ACE_Service_Type_Impl::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Type_Impl::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Service_Type_Impl::ACE_Service_Type_Impl (void *so, + const ACE_TCHAR *s_name, + u_int f, + ACE_Service_Object_Exterminator gobbler) + : name_ (0), + obj_ (so), + gobbler_ (gobbler), + flags_ (f) +{ + ACE_TRACE ("ACE_Service_Type_Impl::ACE_Service_Type_Impl"); + this->name (s_name); +} + +ACE_Service_Type_Impl::~ACE_Service_Type_Impl (void) +{ + ACE_TRACE ("ACE_Service_Type_Impl::~ACE_Service_Type_Impl"); + + // It's ok to call this, even though we may have already deleted it + // in the fini() method since it would then be NULL. + delete [] const_cast (this->name_); +} + +int +ACE_Service_Type_Impl::fini (void) const +{ + ACE_TRACE ("ACE_Service_Type_Impl::fini"); + + delete [] const_cast (this->name_); + (const_cast (this))->name_ = 0; + + if (ACE_BIT_ENABLED (this->flags_, + ACE_Service_Type::DELETE_OBJ)) + { + if (gobbler_ != 0) + gobbler_ (this->object ()); + else + // Cast to remove const-ness. + operator delete ((void *) this->object ()); + } + + if (ACE_BIT_ENABLED (this->flags_, + ACE_Service_Type::DELETE_THIS)) + delete const_cast (this); + + return 0; +} + +ACE_Service_Object_Type::ACE_Service_Object_Type (void *so, + const ACE_TCHAR *s_name, + u_int f, + ACE_Service_Object_Exterminator gobbler) + : ACE_Service_Type_Impl (so, s_name, f, gobbler) + , initialized_ (-1) +{ + ACE_TRACE ("ACE_Service_Object_Type::ACE_Service_Object_Type"); +} + +int +ACE_Service_Object_Type::init (int argc, ACE_TCHAR *argv[]) const +{ + ACE_TRACE ("ACE_Service_Object_Type::init"); + + void * const obj = this->object (); + + ACE_Service_Object * const so = + static_cast (obj); + + if (so == 0) + return -1; + + this->initialized_ = so->init (argc, argv); + + return this->initialized_; +} + +int +ACE_Service_Object_Type::fini (void) const +{ + ACE_TRACE ("ACE_Service_Object_Type::fini"); + + void * const obj = this->object (); + + ACE_Service_Object * const so = + static_cast (obj); + + // Call fini() if an only if, the object was successfuly + // initialized, i.e. init() returned 0. This is necessary to + // maintain the ctor/dtor-like semantics for init/fini. + if (so != 0 && this->initialized_ == 0) + so->fini (); + + return ACE_Service_Type_Impl::fini (); +} + +ACE_Service_Object_Type::~ACE_Service_Object_Type (void) +{ + ACE_TRACE ("ACE_Service_Object_Type::~ACE_Service_Object_Type"); +} + +int +ACE_Service_Object_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Service_Object_Type::suspend"); + return static_cast (this->object ())->suspend (); +} + +int +ACE_Service_Object_Type::resume (void) const +{ + ACE_TRACE ("ACE_Service_Object_Type::resume"); + return static_cast (this->object ())->resume (); +} + +int +ACE_Service_Object_Type::info (ACE_TCHAR **str, size_t len) const +{ + ACE_TRACE ("ACE_Service_Object_Type::info"); + return static_cast (this->object ())->info (str, len); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Module_Type) + +void +ACE_Module_Type::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Module_Type::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Module_Type::ACE_Module_Type (void *m, + const ACE_TCHAR *m_name, + u_int f) + : ACE_Service_Type_Impl (m, m_name, f) +{ + ACE_TRACE ("ACE_Module_Type::ACE_Module_Type"); +} + +ACE_Module_Type::~ACE_Module_Type (void) +{ + ACE_TRACE ("ACE_Module_Type::~ACE_Module_Type"); +} + +int +ACE_Module_Type::init (int argc, ACE_TCHAR *argv[]) const +{ + ACE_TRACE ("ACE_Module_Type::init"); + void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader->init (argc, argv) == -1 + || writer->init (argc, argv) == -1) + return -1; + else + return 0; +} + +int +ACE_Module_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Module_Type::suspend"); + void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader->suspend () == -1 + || writer->suspend () == -1) + return -1; + else + return 0; +} + +int +ACE_Module_Type::resume (void) const +{ + ACE_TRACE ("ACE_Module_Type::resume"); + void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader->resume () == -1 + || writer->resume () == -1) + return -1; + else + return 0; +} + +// Note, these operations are somewhat too familiar with the +// implementation of ACE_Module and ACE_Module::close... + +int +ACE_Module_Type::fini (void) const +{ + ACE_TRACE ("ACE_Module_Type::fini"); + + void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader != 0) + reader->fini (); + + if (writer != 0) + writer->fini (); + + // Close the module and delete the memory. + mod->close (MT_Module::M_DELETE); + return ACE_Service_Type_Impl::fini (); +} + +int +ACE_Module_Type::info (ACE_TCHAR **str, size_t len) const +{ + ACE_TRACE ("ACE_Module_Type::info"); + ACE_TCHAR buf[BUFSIZ]; + + ACE_OS::sprintf (buf, + ACE_TEXT ("%s\t %s"), + this->name (), + ACE_TEXT ("# ACE_Module\n")); + + if (*str == 0 && (*str = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strsncpy (*str, buf, len); + return static_cast (ACE_OS::strlen (buf)); +} + +void +ACE_Module_Type::link (ACE_Module_Type *n) +{ + ACE_TRACE ("ACE_Module_Type::link"); + this->link_ = n; +} + +ACE_Module_Type * +ACE_Module_Type::link (void) const +{ + ACE_TRACE ("ACE_Module_Type::link"); + return this->link_; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Stream_Type) + +void +ACE_Stream_Type::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Stream_Type::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_Stream_Type::init (int, ACE_TCHAR *[]) const +{ + ACE_TRACE ("ACE_Stream_Type::init"); + return 0; +} + +int +ACE_Stream_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Stream_Type::suspend"); + + for (ACE_Module_Type *m = this->head_; + m != 0; + m = m->link ()) + m->suspend (); + + return 0; +} + +int +ACE_Stream_Type::resume (void) const +{ + ACE_TRACE ("ACE_Stream_Type::resume"); + + for (ACE_Module_Type *m = this->head_; + m != 0; + m = m->link ()) + m->resume (); + + return 0; +} + +ACE_Stream_Type::ACE_Stream_Type (void *s, + const ACE_TCHAR *s_name, + u_int f) + : ACE_Service_Type_Impl (s, s_name, f), + head_ (0) +{ + ACE_TRACE ("ACE_Stream_Type::ACE_Stream_Type"); +} + +ACE_Stream_Type::~ACE_Stream_Type (void) +{ + ACE_TRACE ("ACE_Stream_Type::~ACE_Stream_Type"); +} + +int +ACE_Stream_Type::info (ACE_TCHAR **str, size_t len) const +{ + ACE_TRACE ("ACE_Stream_Type::info"); + ACE_TCHAR buf[BUFSIZ]; + + ACE_OS::sprintf (buf, + ACE_TEXT ("%s\t %s"), + this->name (), + ACE_TEXT ("# STREAM\n")); + + if (*str == 0 && (*str = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strsncpy (*str, buf, len); + return static_cast (ACE_OS::strlen (buf)); +} + +int +ACE_Stream_Type::fini (void) const +{ + ACE_TRACE ("ACE_Stream_Type::fini"); + void *obj = this->object (); + MT_Stream *str = (MT_Stream *) obj; + + for (ACE_Module_Type *m = this->head_; m != 0; ) + { + ACE_Module_Type *t = m->link (); + + // Final arg is an indication to *not* delete the Module. + str->remove (m->name (), + MT_Module::M_DELETE_NONE); + + // Finalize the Module (this may delete it, but we don't really + // care since we don't access it again). + m->fini (); + m = t; + } + str->close (); + + return ACE_Service_Type_Impl::fini (); +} + +// Locate and remove from the ACE_Stream. + +int +ACE_Stream_Type::remove (ACE_Module_Type *mod) +{ + ACE_TRACE ("ACE_Stream_Type::remove"); + + ACE_Module_Type *prev = 0; + void *obj = this->object (); + MT_Stream *str = (MT_Stream *) obj; + int result = 0; + + for (ACE_Module_Type *m = this->head_; m != 0; ) + { + // We need to do this first so we don't bomb out if we delete m! + ACE_Module_Type *link = m->link (); + + if (m == mod) + { + if (prev == 0) + this->head_ = link; + else + prev->link (link); + + // Final arg is an indication to *not* delete the Module. + if (str->remove (m->name (), + MT_Module::M_DELETE_NONE) == -1) + result = -1; + + // This call may end up deleting m, which is ok since we + // don't access it again! + m->fini (); + } + else + prev = m; + + m = link; + } + + return result; +} + +int +ACE_Stream_Type::push (ACE_Module_Type *new_module) +{ + ACE_TRACE ("ACE_Stream_Type::push"); + void *obj = this->object (); + MT_Stream *str = (MT_Stream *) obj; + + new_module->link (this->head_); + this->head_ = new_module; + obj = new_module->object (); + return str->push ((MT_Module *) obj); +} + +ACE_Module_Type * +ACE_Stream_Type::find (const ACE_TCHAR *mod_name) const +{ + ACE_TRACE ("ACE_Stream_Type::find"); + + for (ACE_Module_Type *m = this->head_; + m != 0; + m = m->link ()) + if (ACE_OS::strcmp (m->name (), mod_name) == 0) + return m; + + return 0; +} + +// @@@ Eliminated ommented out explicit template instantiation code + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Service_Types.h b/dep/ACE_wrappers/ace/Service_Types.h new file mode 100644 index 000000000..b9450d2c5 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Types.h @@ -0,0 +1,206 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Service_Types.h + * + * $Id: Service_Types.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_SERVICE_TYPE_H +#define ACE_SERVICE_TYPE_H + +#include /**/ "ace/pre.h" + +#include "ace/Service_Object.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Service_Type_Impl + * + * @brief The abstract base class of the hierarchy that defines the + * contents of the ACE_Service_Repository. The subclasses of + * this class allow the configuration of ACE_Service_Objects, + * ACE_Modules, and ACE_Streams. + * + * This class provides the root of the implementation hierarchy + * of the "Bridge" pattern. It maintains a pointer to the + * appropriate type of service implementation, i.e., + * ACE_Service_Object, ACE_Module, or ACE_Stream. + */ +class ACE_Export ACE_Service_Type_Impl +{ +public: + // = Initialization and termination methods. + ACE_Service_Type_Impl (void *object, + const ACE_TCHAR *s_name, + u_int flags = 0, + ACE_Service_Object_Exterminator gobbler = 0); + virtual ~ACE_Service_Type_Impl (void); + + // = Pure virtual interface (must be defined by the subclass). + virtual int suspend (void) const = 0; + virtual int resume (void) const = 0; + virtual int init (int argc, ACE_TCHAR *argv[]) const = 0; + virtual int fini (void) const; + virtual int info (ACE_TCHAR **str, size_t len) const = 0; + + /// The pointer to the service. + void *object (void) const; + + /// Get the name of the service. + const ACE_TCHAR *name (void) const; + + /// Set the name of the service. + void name (const ACE_TCHAR *); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Name of the service. + const ACE_TCHAR *name_; + + /// Pointer to object that implements the service. This actually + /// points to an ACE_Service_Object, ACE_Module, or ACE_Stream. + void *obj_; + + /// Destroy function to deallocate obj_. + ACE_Service_Object_Exterminator gobbler_; + + /// Flags that control serivce behavior (particularly deletion). + u_int flags_; +}; + +/** + * @class ACE_Service_Object_Type + * + * @brief Define the methods for handling the configuration of + * ACE_Service_Objects. + */ +class ACE_Export ACE_Service_Object_Type : public ACE_Service_Type_Impl +{ +public: + // = Initialization method. + ACE_Service_Object_Type (void *so, + const ACE_TCHAR *name, + u_int flags = 0, + ACE_Service_Object_Exterminator gobbler = 0); + + ~ACE_Service_Object_Type (void); + + // = Implement the hooks for . + virtual int suspend (void) const; + virtual int resume (void) const; + virtual int init (int argc, ACE_TCHAR *argv[]) const; + virtual int fini (void) const; + virtual int info (ACE_TCHAR **str, size_t len) const; + +private: + /// Holds the initialization status (result of object->init()) + mutable int initialized_; +}; + +/** + * @class ACE_Module_Type + * + * @brief Define the methods for handling the configuration of + * ACE_Modules. + */ +class ACE_Export ACE_Module_Type : public ACE_Service_Type_Impl +{ +public: + // = Initialization method. + ACE_Module_Type (void *m, // Really an ACE_Module *. + const ACE_TCHAR *identifier, + u_int flags = 0); + + ~ACE_Module_Type (void); + + // = Implement the hooks for . + virtual int suspend (void) const; + virtual int resume (void) const; + virtual int init (int argc, ACE_TCHAR *argv[]) const; + virtual int fini (void) const; + virtual int info (ACE_TCHAR **str, size_t len) const; + + /// Get the link pointer. + ACE_Module_Type *link (void) const; + + /// Set the link pointer. + void link (ACE_Module_Type *); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the next ACE_Module_Type in an ACE_Stream_Type. + ACE_Module_Type *link_; +}; + +/** + * @class ACE_Stream_Type + * + * @brief Define the methods for handling the configuration of + * ACE_Streams. + */ +class ACE_Export ACE_Stream_Type : public ACE_Service_Type_Impl +{ +public: + // = Initialization method. + ACE_Stream_Type (void *s, // Really an ACE_Stream *. + const ACE_TCHAR *identifier, + u_int flags = 0); + + ~ACE_Stream_Type (void); + + // = Implement the hooks for . + virtual int suspend (void) const; + virtual int resume (void) const; + virtual int init (int argc, ACE_TCHAR *argv[]) const; + virtual int fini (void) const; + virtual int info (ACE_TCHAR **str, size_t len) const; + + /// Add a new ACE_Module to the top of the ACE_Stream. + int push (ACE_Module_Type *new_module); + + /// Search for @a module and remove it from the ACE_Stream. + int remove (ACE_Module_Type *module); + + /// Locate the ACE_Module with @a mod_name. + ACE_Module_Type *find (const ACE_TCHAR *mod_name) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the head of the ACE_Module list. + ACE_Module_Type *head_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Service_Types.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* _SERVICE_TYPE_H */ diff --git a/dep/ACE_wrappers/ace/Service_Types.inl b/dep/ACE_wrappers/ace/Service_Types.inl new file mode 100644 index 000000000..f7f935915 --- /dev/null +++ b/dep/ACE_wrappers/ace/Service_Types.inl @@ -0,0 +1,32 @@ +// -*- C++ -*- +// +// $Id: Service_Types.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/ACE.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE void * +ACE_Service_Type_Impl::object (void) const +{ + ACE_TRACE ("ACE_Service_Type_Impl::object"); + return this->obj_; +} + +ACE_INLINE const ACE_TCHAR * +ACE_Service_Type_Impl::name (void) const +{ + ACE_TRACE ("ACE_Service_Type_Impl::name"); + return this->name_; +} + +ACE_INLINE void +ACE_Service_Type_Impl::name (const ACE_TCHAR *n) +{ + ACE_TRACE ("ACE_Service_Type_Impl::name"); + + ACE::strdelete (const_cast (this->name_)); + this->name_ = ACE::strnew (n); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Memory.cpp b/dep/ACE_wrappers/ace/Shared_Memory.cpp new file mode 100644 index 000000000..ccb1f26c4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory.cpp @@ -0,0 +1,13 @@ +// $Id: Shared_Memory.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Shared_Memory.h" + +ACE_RCSID(ace, Shared_Memory, "$Id: Shared_Memory.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Shared_Memory::~ACE_Shared_Memory (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Memory.h b/dep/ACE_wrappers/ace/Shared_Memory.h new file mode 100644 index 000000000..6dbd17ff4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory.h @@ -0,0 +1,58 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Shared_Memory.h + * + * $Id: Shared_Memory.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//========================================================================== + + +#ifndef ACE_SHARED_MEMORY_H +#define ACE_SHARED_MEMORY_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#include "ace/os_include/os_stddef.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Shared_Memory + * + * @brief This base class adapts both System V shared memory and "BSD" + * mmap to a common API. + * + * This is a very simple-minded wrapper, i.e., it really is only + * useful for allocating large contiguous chunks of shared + * memory. For a much more sophisticated version, please check + * out the class. + */ +class ACE_Export ACE_Shared_Memory +{ +public: + virtual ~ACE_Shared_Memory (void); + + // = Note that all the following methods are pure virtual. + virtual int close (void) = 0; + virtual int remove (void) = 0; + virtual void *malloc (size_t = 0) = 0; + virtual int free (void *p) = 0; + virtual size_t get_segment_size (void) const = 0; + virtual ACE_HANDLE get_id (void) const = 0; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_SHARED_MEMORY_H */ diff --git a/dep/ACE_wrappers/ace/Shared_Memory_MM.cpp b/dep/ACE_wrappers/ace/Shared_Memory_MM.cpp new file mode 100644 index 000000000..d6d1ed90c --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_MM.cpp @@ -0,0 +1,111 @@ +// $Id: Shared_Memory_MM.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Shared_Memory_MM.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Shared_Memory_MM.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID (ace, + Shared_Memory_MM, + "$Id: Shared_Memory_MM.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_MM) + +void +ACE_Shared_Memory_MM::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Shared_Memory_MM::dump"); +#endif /* ACE_HAS_DUMP */ +} + +// Creates a shared memory segment of SIZE bytes. + +ACE_Shared_Memory_MM::ACE_Shared_Memory_MM (ACE_HANDLE handle, + size_t length, + int prot, + int share, + char *addr, + ACE_OFF_T pos) + : shared_memory_ (handle, length, prot, share, addr, pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::ACE_Shared_Memory_MM"); +} + +ACE_Shared_Memory_MM::ACE_Shared_Memory_MM (const ACE_TCHAR *file_name, + size_t len, + int flags, + int mode, + int prot, + int share, + char *addr, + ACE_OFF_T pos) + : shared_memory_ (file_name, len, flags, mode, + prot, share, addr, pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::ACE_Shared_Memory_MM"); +} + +// The "do-nothing" constructor. + +ACE_Shared_Memory_MM::ACE_Shared_Memory_MM (void) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::ACE_Shared_Memory_MM"); +} + +// The overall size of the segment. + +size_t +ACE_Shared_Memory_MM::get_segment_size (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_MM::get_segment_size"); + // This cast is legit since the original length in open() is an int. + return this->shared_memory_.size (); +} + +// Unmaps the shared memory segment. + +int +ACE_Shared_Memory_MM::remove (void) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::remove"); + return shared_memory_.remove (); +} + +// Closes (unmaps) the shared memory segment. + +int +ACE_Shared_Memory_MM::close (void) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::close"); + return shared_memory_.unmap (); +} + +void * +ACE_Shared_Memory_MM::malloc (size_t) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::malloc"); + void *addr = 0; + + return this->shared_memory_ (addr) == -1 ? 0 : addr; +} + +ACE_HANDLE +ACE_Shared_Memory_MM::get_id (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_MM::get_id"); + return this->shared_memory_.handle (); +} + +int +ACE_Shared_Memory_MM::free (void *p) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::free"); + return p != 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Memory_MM.h b/dep/ACE_wrappers/ace/Shared_Memory_MM.h new file mode 100644 index 000000000..e02b21249 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_MM.h @@ -0,0 +1,120 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Shared_Memory_MM.h + * + * $Id: Shared_Memory_MM.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + + +#ifndef ACE_SHARED_MALLOC_MM_H +#define ACE_SHARED_MALLOC_MM_H +#include /**/ "ace/pre.h" + +#include "ace/Shared_Memory.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Mem_Map.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Shared_Memory_MM + * + * @brief Shared memory wrapper based on MMAP. + * + * This class provides a very simple-minded shared memory manager. We + * strongly recommend that you do NOT use this class. Instead, please + * use @c ACE_Malloc, which has much more powerful capabilities. + */ +class ACE_Export ACE_Shared_Memory_MM : public ACE_Shared_Memory +{ +public: + // = Initialization and termination methods. + /// Default constructor. + ACE_Shared_Memory_MM (void); + + /// Constructor. + ACE_Shared_Memory_MM (ACE_HANDLE handle, + size_t length = static_cast (-1), + int prot = PROT_RDWR, + int share = ACE_MAP_PRIVATE, + char *addr = 0, + ACE_OFF_T pos = 0); + + /// Constructor. + ACE_Shared_Memory_MM (const ACE_TCHAR *file_name, + size_t length = static_cast (-1), + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_FILE_PERMS, + int prot = PROT_RDWR, + int share = ACE_MAP_SHARED, + char *addr = 0, ACE_OFF_T pos = 0); + + /// Open method. + int open (ACE_HANDLE handle, + size_t length = static_cast (-1), + int prot = PROT_RDWR, + int share = ACE_MAP_PRIVATE, + char *addr = 0, + ACE_OFF_T pos = 0); + + /// Open method. + int open (const ACE_TCHAR *file_name, + size_t length = static_cast (-1), + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_FILE_PERMS, + int prot = PROT_RDWR, + int share = ACE_MAP_SHARED, + char *addr = 0, + ACE_OFF_T pos = 0); + + /// Return the name of file that is mapped (if any). + const ACE_TCHAR *filename (void) const; + + /// Close down the shared memory segment. + virtual int close (void); + + /// Remove the shared memory segment and the underlying file. + virtual int remove (void); + + // = Allocation and deallocation methods. + /// Create a new chuck of memory containing @a size bytes. + virtual void *malloc (size_t size = 0); + + /// Free a chuck of memory allocated by + /// . + virtual int free (void *p); + + /// Return the size of the shared memory segment. + virtual size_t get_segment_size (void) const; + + /// Return the ID of the shared memory segment (i.e., an ACE_HANDLE). + virtual ACE_HANDLE get_id (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// This version is implemented with memory-mapped files. + ACE_Mem_Map shared_memory_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Shared_Memory_MM.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SHARED_MALLOC_MM_H */ diff --git a/dep/ACE_wrappers/ace/Shared_Memory_MM.inl b/dep/ACE_wrappers/ace/Shared_Memory_MM.inl new file mode 100644 index 000000000..6e1f4b766 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_MM.inl @@ -0,0 +1,42 @@ +// -*- C++ -*- +// +// $Id: Shared_Memory_MM.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Return the name of file that is mapped (if any). + +ACE_INLINE const ACE_TCHAR * +ACE_Shared_Memory_MM::filename (void) const +{ + return this->shared_memory_.filename (); +} + +ACE_INLINE int +ACE_Shared_Memory_MM::open (ACE_HANDLE handle, + size_t length, + int prot, + int share, + char *addr, + ACE_OFF_T pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::open"); + return shared_memory_.map (handle, length, prot, share, addr, pos); +} + +ACE_INLINE int +ACE_Shared_Memory_MM::open (const ACE_TCHAR *file_name, + size_t len, + int flags, + int mode, + int prot, + int share, + char *addr, + ACE_OFF_T pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::open"); + return shared_memory_.map (file_name, len, flags, mode, + prot, share, addr, pos); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Memory_Pool.cpp b/dep/ACE_wrappers/ace/Shared_Memory_Pool.cpp new file mode 100644 index 000000000..b61febc31 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_Pool.cpp @@ -0,0 +1,461 @@ +// $Id: Shared_Memory_Pool.cpp 80826 2008-03-04 14:51:23Z wotte $ + +// Shared_Memory_Pool.cpp +#include "ace/Shared_Memory_Pool.h" +#include "ace/OS_NS_sys_shm.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, Shared_Memory_Pool, "$Id: Shared_Memory_Pool.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (ACE_LACKS_SYSV_SHMEM) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_Pool) + +ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options ( + const char *base_addr, + size_t max_segments, + size_t file_perms, + ACE_OFF_T minimum_bytes, + size_t segment_size) + : base_addr_ (base_addr), + max_segments_ (max_segments), + minimum_bytes_ (minimum_bytes), + file_perms_ (file_perms), + segment_size_ (segment_size) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options"); +} + +void +ACE_Shared_Memory_Pool::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Shared_Memory_Pool::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_Shared_Memory_Pool::in_use (ACE_OFF_T &offset, + size_t &counter) +{ + offset = 0; + SHM_TABLE *st = reinterpret_cast (this->base_addr_); + shmid_ds buf; + + for (counter = 0; + counter < this->max_segments_ && st[counter].used_ == 1; + counter++) + { + if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("shmctl")), + -1); + offset += buf.shm_segsz; + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset)); + } + + return 0; +} + +int +ACE_Shared_Memory_Pool::find_seg (const void* const searchPtr, + ACE_OFF_T &offset, + size_t &counter) +{ + offset = 0; + SHM_TABLE *st = reinterpret_cast (this->base_addr_); + shmid_ds buf; + + for (counter = 0; + counter < this->max_segments_ + && st[counter].used_ == 1; + counter++) + { + if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("shmctl")), + -1); + offset += buf.shm_segsz; + + // If segment 'counter' starts at a location greater than the + // place we are searching for. We then decrement the offset to + // the start of counter-1. (flabar@vais.net) + if (((ptrdiff_t) offset + (ptrdiff_t) (this->base_addr_)) > (ptrdiff_t) searchPtr) + { + --counter; + offset -= buf.shm_segsz; + return 0; + } + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset)); + } + + return 0; +} + +int +ACE_Shared_Memory_Pool::commit_backing_store_name (size_t rounded_bytes, + ACE_OFF_T &offset) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::commit_backing_store_name"); + + size_t counter; + SHM_TABLE *st = reinterpret_cast (this->base_addr_); + + if (this->in_use (offset, counter) == -1) + return -1; + + if (counter == this->max_segments_) + ACE_ERROR_RETURN ((LM_ERROR, + "exceeded max number of segments = %d, base = %u, offset = %u\n", + counter, + this->base_addr_, + offset), + -1); + else + { + int shmid = ACE_OS::shmget (st[counter].key_, + rounded_bytes, + this->file_perms_ | IPC_CREAT | IPC_EXCL); + if (shmid == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("shmget")), + -1); + st[counter].shmid_ = shmid; + st[counter].used_ = 1; + + void *address = (void *) (((char *) this->base_addr_) + offset); + void *shmem = ACE_OS::shmat (st[counter].shmid_, + (char *) address, + 0); + + if (shmem != address) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p, shmem = %u, address = %u\n", + "shmat", + shmem, + address), + -1); + } + return 0; +} + +// Handle SIGSEGV and SIGBUS signals to remap shared memory properly. + +int +ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::handle_signal"); + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("signal %S occurred\n"), signum)); + + // While FreeBSD 5.X has a siginfo_t struct with a si_addr field, + // it does not define SEGV_MAPERR. +#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR) && \ + (defined (SEGV_MAPERR) || defined (SEGV_MEMERR)) + ACE_OFF_T offset; + // Make sure that the pointer causing the problem is within the + // range of the backing store. + + if (siginfo != 0) + { + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) si_signo = %d, si_code = %d, addr = %u\n"), siginfo->si_signo, siginfo->si_code, siginfo->si_addr)); + size_t counter; + if (this->in_use (offset, counter) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("in_use"))); +#if !defined(_UNICOS) + else if (!(siginfo->si_code == SEGV_MAPERR + && siginfo->si_addr < (((char *) this->base_addr_) + offset) + && siginfo->si_addr >= ((char *) this->base_addr_))) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) address %u out of range\n", + siginfo->si_addr), + -1); +#else /* ! _UNICOS */ + else if (!(siginfo->si_code == SEGV_MEMERR + && siginfo->si_addr < (((unsigned long) this->base_addr_) + offset) + && siginfo->si_addr >= ((unsigned long) this->base_addr_))) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) address %u out of range\n", + siginfo->si_addr), + -1); +#endif /* ! _UNICOS */ + } + + // The above if case will check to see that the address is in the + // proper range. Therefore there is a segment out there that the + // pointer wants to point into. Find the segment that someone else + // has used and attach to it (flabar@vais.net) + + size_t counter; // ret value to get shmid from the st table. + +#if !defined(_UNICOS) + if (this->find_seg (siginfo->si_addr, offset, counter) == -1) +#else /* ! _UNICOS */ + if (this->find_seg ((const void *)siginfo->si_addr, offset, counter) == -1) +#endif /* ! _UNICOS */ + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("in_use")), + -1); + + void *address = (void *) (((char *) this->base_addr_) + offset); + SHM_TABLE *st = reinterpret_cast (this->base_addr_); + + void *shmem = ACE_OS::shmat (st[counter].shmid_, (char *) address, 0); + + if (shmem != address) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p, shmem = %u, address = %u\n", + "shmat", + shmem, + address), + -1); + + // NOTE: this won't work if we dont have SIGINFO_T or SI_ADDR +#else + ACE_UNUSED_ARG (siginfo); +#endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */ + + return 0; +} + +ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool ( + const ACE_TCHAR *backing_store_name, + const OPTIONS *options) + : base_addr_ (0), + file_perms_ (ACE_DEFAULT_FILE_PERMS), + max_segments_ (ACE_DEFAULT_MAX_SEGMENTS), + minimum_bytes_ (0), + segment_size_ (ACE_DEFAULT_SEGMENT_SIZE) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool"); + + // Only change the defaults if != 0. + if (options) + { + this->base_addr_ = + reinterpret_cast (const_cast (options->base_addr_)); + this->max_segments_ = options->max_segments_; + this->file_perms_ = options->file_perms_; + this->minimum_bytes_ = options->minimum_bytes_; + this->segment_size_ = options->segment_size_; + } + + if (backing_store_name) + { + // Convert the string into a number that is used as the segment + // key. + + int segment_key; + int result = ::sscanf (ACE_TEXT_ALWAYS_CHAR (backing_store_name), + "%d", + &segment_key); + + if (result == 0 || result == EOF) + // The conversion to a number failed so hash with crc32 + // ACE::crc32 is also used in . + this->base_shm_key_ = + (key_t) ACE::crc32 (ACE_TEXT_ALWAYS_CHAR (backing_store_name)); + else + this->base_shm_key_ = segment_key; + + if (this->base_shm_key_ == IPC_PRIVATE) + // Make sure that the segment can be shared between unrelated + // processes. + this->base_shm_key_ = ACE_DEFAULT_SHM_KEY; + } + else + this->base_shm_key_ = ACE_DEFAULT_SHM_KEY; + + if (this->signal_handler_.register_handler (SIGSEGV, this) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Sig_Handler::register_handler"))); +} + +ACE_Shared_Memory_Pool::~ACE_Shared_Memory_Pool (void) +{ +} + +// Ask system for more shared memory. + +void * +ACE_Shared_Memory_Pool::acquire (size_t nbytes, + size_t &rounded_bytes) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::acquire"); + + rounded_bytes = this->round_up (nbytes); + + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes)); + + ACE_OFF_T offset; + + if (this->commit_backing_store_name (rounded_bytes, offset) == -1) + return 0; + + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes)); + return ((char *) this->base_addr_) + offset; +} + +// Ask system for initial chunk of shared memory. + +void * +ACE_Shared_Memory_Pool::init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire"); + + ACE_OFF_T shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE)); + rounded_bytes = this->round_up (nbytes > (size_t) this->minimum_bytes_ + ? nbytes + : (size_t) this->minimum_bytes_); + + // Acquire the semaphore to serialize initialization and prevent + // race conditions. + + int shmid = ACE_OS::shmget (this->base_shm_key_, + rounded_bytes + shm_table_offset, + this->file_perms_ | IPC_CREAT | IPC_EXCL); + if (shmid == -1) + { + if (errno != EEXIST) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("shmget")), + 0); + first_time = 0; + + shmid = ACE_OS::shmget (this->base_shm_key_, 0, 0); + + if (shmid == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("shmget")), + 0); + + // This implementation doesn't care if we don't get the key we + // want... + this->base_addr_ = + ACE_OS::shmat (shmid, + reinterpret_cast (this->base_addr_), + 0); + if (this->base_addr_ == reinterpret_cast (-1)) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p, base_addr = %u\n", + "shmat", + this->base_addr_), + 0); + } + else + { + first_time = 1; + + // This implementation doesn't care if we don't get the key we + // want... + this->base_addr_ = + ACE_OS::shmat (shmid, + reinterpret_cast (this->base_addr_), + 0); + if (this->base_addr_ == reinterpret_cast (-1)) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p, base_addr = %u\n", + "shmat", + this->base_addr_), 0); + + SHM_TABLE *st = reinterpret_cast (this->base_addr_); + st[0].key_ = this->base_shm_key_; + st[0].shmid_ = shmid; + + st[0].used_ = 1; + + for (size_t counter = 1; // Skip over the first entry... + counter < this->max_segments_; + counter++) + { + st[counter].key_ = this->base_shm_key_ + counter; + st[counter].shmid_ = 0; + st[counter].used_ = 0; + } + } + + return (void *) (((char *) this->base_addr_) + shm_table_offset); +} + +// Instruct the memory pool to release all of its resources. + +int +ACE_Shared_Memory_Pool::release (int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::release"); + + int result = 0; + SHM_TABLE *st = reinterpret_cast (this->base_addr_); + + for (size_t counter = 0; + counter < this->max_segments_ && st[counter].used_ == 1; + counter++) + if (ACE_OS::shmctl (st[counter].shmid_, IPC_RMID, 0) == -1) + result = -1; + + return result; +} + +int +ACE_Shared_Memory_Pool::sync (ssize_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::sync"); + return 0; +} + +int +ACE_Shared_Memory_Pool::sync (void *, size_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::sync"); + return 0; +} + +int +ACE_Shared_Memory_Pool::protect (ssize_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::protect"); + return 0; +} + +int +ACE_Shared_Memory_Pool::protect (void *, size_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::protect"); + return 0; +} + +void * +ACE_Shared_Memory_Pool::base_addr (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::base_addr"); + return this->base_addr_; +} + +// Implement the algorithm for rounding up the request to an +// appropriate chunksize. + +size_t +ACE_Shared_Memory_Pool::round_up (size_t nbytes) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::round_up"); + if (nbytes < this->segment_size_) + nbytes = this->segment_size_; + + return ACE::round_to_pagesize (nbytes); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* !ACE_LACKS_SYSV_SHMEM */ diff --git a/dep/ACE_wrappers/ace/Shared_Memory_Pool.h b/dep/ACE_wrappers/ace/Shared_Memory_Pool.h new file mode 100644 index 000000000..79cb970e7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_Pool.h @@ -0,0 +1,210 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Shared_Memory_Pool.h + * + * $Id: Shared_Memory_Pool.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Dougls C. Schmidt + * @author Prashant Jain + */ +//============================================================================= + +#ifndef ACE_SHARED_MEMORY_POOL_H +#define ACE_SHARED_MEMORY_POOL_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_SYSV_SHMEM) + +#include "ace/ACE.h" +#include "ace/Event_Handler.h" +#include "ace/Sig_Handler.h" +#include "ace/os_include/sys/os_mman.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Shared_Memory_Pool_Options + * + * @brief Helper class for Shared Memory Pool constructor options. + * + * This should be a nested class, but that breaks too many + * compilers. + */ +class ACE_Export ACE_Shared_Memory_Pool_Options +{ +public: + /// Initialization method. + ACE_Shared_Memory_Pool_Options ( + const char *base_addr = ACE_DEFAULT_BASE_ADDR, + size_t max_segments = ACE_DEFAULT_MAX_SEGMENTS, + size_t file_perms = ACE_DEFAULT_FILE_PERMS, + ACE_OFF_T minimum_bytes = 0, + size_t segment_size = ACE_DEFAULT_SEGMENT_SIZE); + + /// Base address of the memory-mapped backing store. + const char *base_addr_; + + /// Number of shared memory segments to allocate. + size_t max_segments_; + + /// What the minimum bytes of the initial segment should be. + ACE_OFF_T minimum_bytes_; + + /// File permissions to use when creating/opening a segment. + size_t file_perms_; + + /// Shared memory segment size. + size_t segment_size_; +}; + +/** + * @class ACE_Shared_Memory_Pool + * + * @brief Make a memory pool that is based on System V shared memory + * (shmget(2) etc.). This implementation allows memory to be + * shared between processes. If your platform doesn't support + * System V shared memory (e.g., Win32 and many RTOS platforms + * do not) then you should use ACE_MMAP_Memory_Pool instead of this + * class. In fact, you should probably use ACE_MMAP_Memory_Pool on + * platforms that *do* support System V shared memory since it + * provides more powerful features, such as persistent backing store + * and greatly scalability. + */ +class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler +{ +public: + typedef ACE_Shared_Memory_Pool_Options OPTIONS; + + /// Initialize the pool. + ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, + const OPTIONS *options = 0); + + virtual ~ACE_Shared_Memory_Pool (void); + + /// Ask system for initial chunk of local memory. + virtual void *init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time); + + /** + * Acquire at least @a nbytes from the memory pool. @a rounded_byes is + * the actual number of bytes allocated. Also acquires an internal + * semaphore that ensures proper serialization of Memory_Pool + * initialization across processes. + */ + virtual void *acquire (size_t nbytes, + size_t &rounded_bytes); + + /// Instruct the memory pool to release all of its resources. + virtual int release (int destroy = 1); + + /// Sync the memory region to the backing store starting at + /// @c this->base_addr_. + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + + /// Sync the memory region to the backing store starting at @a addr. + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + + /** + * Change the protection of the pages of the mapped region to @a prot + * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 + * then change protection of all pages in the mapped region. + */ + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + + /// Change the protection of the pages of the mapped region to @a prot + /// starting at @a addr up to @a len bytes. + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + + /// Return the base address of this memory pool, 0 if base_addr + /// never changes. + virtual void *base_addr (void) const; + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Implement the algorithm for rounding up the request to an + /// appropriate chunksize. + virtual size_t round_up (size_t nbytes); + + /** + * Commits a new shared memory segment if necessary after an + * or a signal. @a offset is set to the new offset into + * the backing store. + */ + virtual int commit_backing_store_name (size_t rounded_bytes, + ACE_OFF_T &offset); + + /// Keeps track of all the segments being used. + struct SHM_TABLE + { + /// Shared memory segment key. + key_t key_; + + /// Shared memory segment internal id. + int shmid_; + + /// Is the segment currently used.; + int used_; + }; + + /** + * Base address of the shared memory segment. If this has the value + * of 0 then the OS is free to select any address, otherwise this + * value is what the OS must try to use to map the shared memory + * segment. + */ + void *base_addr_; + + /// File permissions to use when creating/opening a segment. + size_t file_perms_; + + /// Number of shared memory segments in the table. + size_t max_segments_; + + /// What the minimim bytes of the initial segment should be. + ACE_OFF_T minimum_bytes_; + + /// Shared memory segment size. + size_t segment_size_; + + /// Base shared memory key for the segment. + key_t base_shm_key_; + + /// Find the segment that contains the @a searchPtr + virtual int find_seg (const void *const searchPtr, + ACE_OFF_T &offset, + size_t &counter); + + /// Determine how much memory is currently in use. + virtual int in_use (ACE_OFF_T &offset, + size_t &counter); + + /// Handles SIGSEGV. + ACE_Sig_Handler signal_handler_; + + /// Handle SIGSEGV and SIGBUS signals to remap shared memory + /// properly. + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* !ACE_LACKS_SYSV_SHMEM */ + +#include /**/ "ace/post.h" + +#endif /* ACE_SHARED_MEMORY_POOL_H */ diff --git a/dep/ACE_wrappers/ace/Shared_Memory_SV.cpp b/dep/ACE_wrappers/ace/Shared_Memory_SV.cpp new file mode 100644 index 000000000..fe26688b0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_SV.cpp @@ -0,0 +1,88 @@ +// $Id: Shared_Memory_SV.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Shared_Memory_SV.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Shared_Memory_SV.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID (ace, + Shared_Memory_SV, + "$Id: Shared_Memory_SV.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_SV) + +void +ACE_Shared_Memory_SV::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Shared_Memory_SV::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Shared_Memory_SV::ACE_Shared_Memory_SV (key_t id, + size_t length, + int create, + int perms, + void *addr, + int flags) + : shared_memory_ (id, length, create, perms, addr, flags) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::ACE_Shared_Memory_SV"); +} + +// The overall size of the segment. + +size_t +ACE_Shared_Memory_SV::get_segment_size (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_SV::get_segment_size"); + // This cast is ok since the 'open' method for this class allows only + // an 'int' size. Therefore, this case should not lose information. + return this->shared_memory_.get_segment_size (); +} + +// Removes the shared memory segment. + +int +ACE_Shared_Memory_SV::remove (void) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::remove"); + return shared_memory_.remove (); +} + +// Closes (detaches) the shared memory segment. + +int +ACE_Shared_Memory_SV::close (void) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::close"); + return shared_memory_.detach (); +} + +void * +ACE_Shared_Memory_SV::malloc (size_t) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::malloc"); + return this->shared_memory_.get_segment_ptr (); +} + +ACE_HANDLE +ACE_Shared_Memory_SV::get_id (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_SV::get_id"); + return this->shared_memory_.get_id (); +} + +int +ACE_Shared_Memory_SV::free (void *p) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::free"); + return p != 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Memory_SV.h b/dep/ACE_wrappers/ace/Shared_Memory_SV.h new file mode 100644 index 000000000..7ae62a332 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_SV.h @@ -0,0 +1,101 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Shared_Memory_SV.h + * + * $Id: Shared_Memory_SV.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + + +#ifndef ACE_SHARED_MALLOC_SV_H +#define ACE_SHARED_MALLOC_SV_H +#include /**/ "ace/pre.h" + +#include "ace/Shared_Memory.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SV_Shared_Memory.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Shared_Memory_SV + * + * @brief Shared memory wrapper based on System V shared memory. + * + * This class provides a very simple-minded shared memory manager. We + * strongly recommend that you do NOT use this class. Instead, please + * use @c ACE_Malloc, which has much more powerful capabilities. + */ +class ACE_Export ACE_Shared_Memory_SV : public ACE_Shared_Memory +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0 + }; + + // = Initialization and termination methods. + ACE_Shared_Memory_SV (void); + ACE_Shared_Memory_SV (key_t id, + size_t length, + int create = ACE_Shared_Memory_SV::ACE_OPEN, + int perms = ACE_DEFAULT_FILE_PERMS, + void *addr = 0, + int flags = 0); + + int open (key_t id, + size_t length, + int create = ACE_Shared_Memory_SV::ACE_OPEN, + int perms = ACE_DEFAULT_FILE_PERMS, + void *addr = 0, + int flags = 0); + + /// Close down the shared memory segment. + virtual int close (void); + + /// Remove the underlying shared memory segment. + virtual int remove (void); + + // = Allocation and deallocation methods. + /// Create a new chuck of memory containing @a size bytes. + virtual void *malloc (size_t = 0); + + /// Free a chuck of memory allocated by . + virtual int free (void *p); + + /// Return the size of the shared memory segment. + virtual size_t get_segment_size (void) const; + + /// Return the ID of the shared memory segment (i.e., a System V + /// shared memory internal id). + virtual ACE_HANDLE get_id (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// This version is implemented with System V shared memory + /// segments. + ACE_SV_Shared_Memory shared_memory_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Shared_Memory_SV.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SHARED_MALLOC_SV_H */ diff --git a/dep/ACE_wrappers/ace/Shared_Memory_SV.inl b/dep/ACE_wrappers/ace/Shared_Memory_SV.inl new file mode 100644 index 000000000..1a586701c --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Memory_SV.inl @@ -0,0 +1,30 @@ +// -*- C++ -*- +// +// $Id: Shared_Memory_SV.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_Shared_Memory_SV::open (key_t id, + size_t length, + int create, + int perms, + void *addr, + int flags) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::open"); + return shared_memory_.open_and_attach (id, length, create, + perms, addr, flags); +} + +// The "do-nothing" constructor. + +ACE_INLINE +ACE_Shared_Memory_SV::ACE_Shared_Memory_SV (void) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::ACE_Shared_Memory_SV"); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Object.cpp b/dep/ACE_wrappers/ace/Shared_Object.cpp new file mode 100644 index 000000000..76c27df1c --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Object.cpp @@ -0,0 +1,54 @@ +// $Id: Shared_Object.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Shared_Object.h" +#include "ace/Global_Macros.h" +#include "ace/config-all.h" + +/* Provide the abstract base class used to access dynamic linking + facilities */ + +#if !defined (__ACE_INLINE__) +#include "ace/Shared_Object.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Shared_Object, + "$Id: Shared_Object.cpp 80826 2008-03-04 14:51:23Z wotte $") + + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Initializes object when dynamic linking occurs. + +int +ACE_Shared_Object::init (int, ACE_TCHAR *[]) +{ + ACE_TRACE ("ACE_Shared_Object::init"); + return 0; +} + +// Terminates object when dynamic unlinking occurs. + +int +ACE_Shared_Object::fini (void) +{ + ACE_TRACE ("ACE_Shared_Object::fini"); + return 0; +} + +// Returns information on active object. + +int +ACE_Shared_Object::info (ACE_TCHAR **, size_t) const +{ + ACE_TRACE ("ACE_Shared_Object::info"); + return 0; +} + +// Need to give a default implementation. + +ACE_Shared_Object::~ACE_Shared_Object (void) +{ + ACE_TRACE ("ACE_Shared_Object::~ACE_Shared_Object"); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Shared_Object.h b/dep/ACE_wrappers/ace/Shared_Object.h new file mode 100644 index 000000000..fedf051ba --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Object.h @@ -0,0 +1,62 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Shared_Object.h + * + * $Id: Shared_Object.h 81348 2008-04-14 09:00:32Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_SHARED_OBJECT_H +#define ACE_SHARED_OBJECT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Shared_Object + * + * @brief Provide the abstract base class used to access dynamic + * linking facilities. + */ +class ACE_Export ACE_Shared_Object +{ +public: + /// Constructor + ACE_Shared_Object (void); + + /// Destructor + virtual ~ACE_Shared_Object (void); + + /// Initializes object when dynamic linking occurs. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Terminates object when dynamic unlinking occurs. + virtual int fini (void); + + /// Returns information on a service object. + virtual int info (ACE_TCHAR **info_string, size_t length = 0) const; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Shared_Object.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_SHARED_OBJECT_H */ diff --git a/dep/ACE_wrappers/ace/Shared_Object.inl b/dep/ACE_wrappers/ace/Shared_Object.inl new file mode 100644 index 000000000..4f5f00206 --- /dev/null +++ b/dep/ACE_wrappers/ace/Shared_Object.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id: Shared_Object.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Shared_Object::ACE_Shared_Object (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Sig_Adapter.cpp b/dep/ACE_wrappers/ace/Sig_Adapter.cpp new file mode 100644 index 000000000..d1af40f12 --- /dev/null +++ b/dep/ACE_wrappers/ace/Sig_Adapter.cpp @@ -0,0 +1,80 @@ +// $Id: Sig_Adapter.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Sig_Adapter.h" + +ACE_RCSID(ace, Sig_Adapter, "$Id: Sig_Adapter.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Sig_Action &sa, int sigkey) + : sigkey_ (sigkey), + type_ (SIG_ACTION), + sa_ (sa) +{ + // ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter"); +} + +ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Event_Handler *eh, + int sigkey) + : sigkey_ (sigkey), + type_ (ACE_HANDLER), + eh_ (eh) +{ + // ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter"); +} + +ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Sig_Handler_Ex sig_func, + int sigkey) + : sigkey_ (sigkey), + type_ (C_FUNCTION), + sig_func_ (sig_func) +{ + // ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter"); +} + +ACE_Sig_Adapter::~ACE_Sig_Adapter () +{ +} + +int +ACE_Sig_Adapter::sigkey (void) +{ + ACE_TRACE ("ACE_Sig_Adapter::sigkey"); + return this->sigkey_; +} + +int +ACE_Sig_Adapter::handle_signal (int signum, + siginfo_t *siginfo, + ucontext_t *ucontext) +{ + ACE_TRACE ("ACE_Sig_Adapter::handle_signal"); + + switch (this->type_) + { + case SIG_ACTION: + { + // We have to dispatch a handler that was registered by a + // third-party library. + + ACE_Sig_Action old_disp; + + // Make sure this handler executes in the context it was + // expecting... + this->sa_.register_action (signum, &old_disp); + + ACE_Sig_Handler_Ex sig_func = ACE_Sig_Handler_Ex (this->sa_.handler ()); + + (*sig_func) (signum, siginfo, ucontext); + // Restore the original disposition. + old_disp.register_action (signum); + break; + } + case ACE_HANDLER: + this->eh_->handle_signal (signum, siginfo, ucontext); + break; + case C_FUNCTION: + (*this->sig_func_) (signum, siginfo, ucontext); + break; + } + return 0; +} diff --git a/dep/ACE_wrappers/ace/Sig_Adapter.h b/dep/ACE_wrappers/ace/Sig_Adapter.h new file mode 100644 index 000000000..cbd6b3998 --- /dev/null +++ b/dep/ACE_wrappers/ace/Sig_Adapter.h @@ -0,0 +1,81 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Sig_Adapter.h + * + * $Id: Sig_Adapter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_SIG_ADAPTER_H +#define ACE_SIG_ADAPTER_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event_Handler.h" +#include "ace/Signal.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Sig_Adapter + * + * @brief Provide an adapter that transforms various types of signal + * handlers into the scheme used by the ACE_Reactor. + */ +class ACE_Export ACE_Sig_Adapter : public ACE_Event_Handler +{ +public: + ACE_Sig_Adapter (ACE_Sig_Action &, int sigkey); + ACE_Sig_Adapter (ACE_Event_Handler *, int sigkey); + ACE_Sig_Adapter (ACE_Sig_Handler_Ex, int sigkey = 0); + ~ACE_Sig_Adapter (void); + + /// Returns this signal key that's used to remove this from the + /// ACE_Reactor's internal table. + int sigkey (void); + + /// Called by the to dispatch the signal handler. + virtual int handle_signal (int, siginfo_t *, ucontext_t *); + +private: + /// Key for this signal handler (used to remove it). + int sigkey_; + + /// Is this an external handler or an ACE handler? + enum + { + /// We're just wrapping an ACE_Event_Handler. + ACE_HANDLER, + /// An ACE_Sig_Action. + SIG_ACTION, + /// A normal C function. + C_FUNCTION + } type_; + + // = This should be a union, but C++ won't allow that because the + // has a constructor. + /// This is an external handler (ugh). + ACE_Sig_Action sa_; + + /// This is an ACE hander. + ACE_Event_Handler *eh_; + + /// This is a normal C function. + ACE_Sig_Handler_Ex sig_func_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_SIG_ADAPTER_H */ diff --git a/dep/ACE_wrappers/ace/Sig_Handler.cpp b/dep/ACE_wrappers/ace/Sig_Handler.cpp new file mode 100644 index 000000000..33bbb638b --- /dev/null +++ b/dep/ACE_wrappers/ace/Sig_Handler.cpp @@ -0,0 +1,614 @@ +// $Id: Sig_Handler.cpp 81388 2008-04-23 14:02:05Z johnnyw $ + +#include "ace/Sig_Handler.h" +#include "ace/Sig_Adapter.h" +#include "ace/Signal.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Managed_Object.h" +#include "ace/Containers.h" +#include "ace/Guard_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Sig_Handler.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Sig_Handler, "$Id: Sig_Handler.cpp 81388 2008-04-23 14:02:05Z johnnyw $") + +#if defined (ACE_HAS_SIG_C_FUNC) + +extern "C" void +ace_sig_handler_dispatch (int signum, siginfo_t *info, ucontext_t *context) +{ + ACE_TRACE ("ace_sig_handler_dispatch"); + ACE_Sig_Handler::dispatch (signum, info, context); +} + +#define ace_signal_handler_dispatcher ACE_SignalHandler(ace_sig_handler_dispatch) + +extern "C" void +ace_sig_handlers_dispatch (int signum, siginfo_t *info, ucontext_t *context) +{ + ACE_TRACE ("ace_sig_handlers_dispatch"); + ACE_Sig_Handlers::dispatch (signum, info, context); +} + +#define ace_signal_handlers_dispatcher ACE_SignalHandler(ace_sig_handlers_dispatch) + +#else +#define ace_signal_handler_dispatcher ACE_SignalHandler(ACE_Sig_Handler::dispatch) + +#define ace_signal_handlers_dispatcher ACE_SignalHandler(ACE_Sig_Handlers::dispatch) +#endif /* ACE_HAS_SIG_C_FUNC */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Array of Event_Handlers that will handle the signals. +ACE_Event_Handler *ACE_Sig_Handler::signal_handlers_[ACE_NSIG]; + +// Remembers if a signal has occurred. +sig_atomic_t ACE_Sig_Handler::sig_pending_ = 0; + + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handler) + +ACE_Sig_Handler::~ACE_Sig_Handler (void) +{ +} + +void +ACE_Sig_Handler::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Sig_Handler::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_Sig_Handler::sig_pending (void) +{ + ACE_TRACE ("ACE_Sig_Handler::sig_pending"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + return ACE_Sig_Handler::sig_pending_ != 0; +} + +void +ACE_Sig_Handler::sig_pending (int pending) +{ + ACE_TRACE ("ACE_Sig_Handler::sig_pending"); + + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + ACE_Sig_Handler::sig_pending_ = pending; +} + +ACE_Event_Handler * +ACE_Sig_Handler::handler (int signum) +{ + ACE_TRACE ("ACE_Sig_Handler::handler"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + + if (ACE_Sig_Handler::in_range (signum)) + return ACE_Sig_Handler::signal_handlers_[signum]; + else + return 0; +} + +ACE_Event_Handler * +ACE_Sig_Handler::handler_i (int signum, + ACE_Event_Handler *new_sh) +{ + ACE_TRACE ("ACE_Sig_Handler::handler_i"); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Event_Handler *sh = ACE_Sig_Handler::signal_handlers_[signum]; + + ACE_Sig_Handler::signal_handlers_[signum] = new_sh; + return sh; + } + else + return 0; +} + +ACE_Event_Handler * +ACE_Sig_Handler::handler (int signum, + ACE_Event_Handler *new_sh) +{ + ACE_TRACE ("ACE_Sig_Handler::handler"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + + return ACE_Sig_Handler::handler_i (signum, new_sh); +} + +// Register an ACE_Event_Handler along with the corresponding SIGNUM. +// This method does NOT acquire any locks, so it can be called from a +// signal handler. + +int +ACE_Sig_Handler::register_handler_i (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Sig_Handler::register_handler_i"); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Sig_Action sa; // Define a "null" action. + ACE_Event_Handler *sh = ACE_Sig_Handler::handler_i (signum, + new_sh); + + // Return a pointer to the old if the user + // asks for this. + if (old_sh != 0) + *old_sh = sh; + + // Make sure that points to a valid location if the + // user doesn't care... + if (new_disp == 0) + new_disp = &sa; + + new_disp->handler (ace_signal_handler_dispatcher); +#if !defined (ACE_HAS_LYNXOS_SIGNALS) + new_disp->flags (new_disp->flags () | SA_SIGINFO); +#endif /* ACE_HAS_LYNXOS_SIGNALS */ + return new_disp->register_action (signum, old_disp); + } + else + return -1; +} + +// Register an ACE_Event_Handler along with the corresponding SIGNUM. +// This method acquires a lock, so it can't be called from a signal +// handler, e.g., . + +int +ACE_Sig_Handler::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Sig_Handler::register_handler"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + + return ACE_Sig_Handler::register_handler_i (signum, + new_sh, + new_disp, + old_sh, + old_disp); +} + +// Remove an ACE_Event_Handler. + +int +ACE_Sig_Handler::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int) +{ + ACE_TRACE ("ACE_Sig_Handler::remove_handler"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0); // Define the default disposition. + + if (new_disp == 0) + new_disp = &sa; + + ACE_Sig_Handler::signal_handlers_[signum] = 0; + + // Register either the new disposition or restore the default. + return new_disp->register_action (signum, old_disp); + } + + return -1; +} + +// Master dispatcher function that gets called by a signal handler and +// dispatches one handler... + +void +ACE_Sig_Handler::dispatch (int signum, + siginfo_t *siginfo, + ucontext_t *ucontext) +{ + ACE_TRACE ("ACE_Sig_Handler::dispatch"); + + // Save/restore errno. + ACE_Errno_Guard error (errno); + + // We can't use the call here because that acquires + // the lock, which is non-portable... + ACE_Sig_Handler::sig_pending_ = 1; + + // Darn well better be in range since the OS dispatched this... + ACE_ASSERT (ACE_Sig_Handler::in_range (signum)); + + ACE_Event_Handler *eh = ACE_Sig_Handler::signal_handlers_[signum]; + + if (eh != 0) + { + if (eh->handle_signal (signum, siginfo, ucontext) == -1) + { + // Define the default disposition. + ACE_Sig_Action sa ((ACE_SignalHandler) SIG_DFL, (sigset_t *) 0); + + ACE_Sig_Handler::signal_handlers_[signum] = 0; + + // Remove the current disposition by registering the default + // disposition. + sa.register_action (signum); + + // Allow the event handler to close down if necessary. + eh->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::SIGNAL_MASK); + } +#if defined (ACE_WIN32) + else + // Win32 is weird in the sense that it resets the signal + // disposition to SIG_DFL after a signal handler is + // dispatched. Therefore, to workaround this "feature" we + // must re-register the with + // explicitly. + ACE_Sig_Handler::register_handler_i (signum, + eh); +#endif /* ACE_WIN32*/ + } +} + +// ---------------------------------------- +// The following classes are local to this file. + +// There are bugs with HP/UX's C++ compiler that prevents this stuff +// from compiling... +#define ACE_MAX_SIGNAL_HANDLERS ((size_t) 20) + +// Keeps track of the id that uniquely identifies each registered +// signal handler. This id can be used to cancel a timer via the +// method. +int ACE_Sig_Handlers::sigkey_ = 0; + +// If this is true then a 3rd party library has registered a +// handler... +bool ACE_Sig_Handlers::third_party_sig_handler_ = false; + +// Make life easier by defining typedefs... +typedef ACE_Fixed_Set ACE_SIG_HANDLERS_SET; +typedef ACE_Fixed_Set_Iterator ACE_SIG_HANDLERS_ITERATOR; + +class ACE_Sig_Handlers_Set +{ +public: + static ACE_SIG_HANDLERS_SET *instance (int signum); + +private: + static ACE_SIG_HANDLERS_SET *sig_handlers_[ACE_NSIG]; +}; + +/* static */ +ACE_SIG_HANDLERS_SET *ACE_Sig_Handlers_Set::sig_handlers_[ACE_NSIG]; + +/* static */ +ACE_SIG_HANDLERS_SET * +ACE_Sig_Handlers_Set::instance (int signum) +{ + if (signum <= 0 || signum >= ACE_NSIG) + return 0; // This will cause problems... + else if (ACE_Sig_Handlers_Set::sig_handlers_[signum] == 0) + ACE_NEW_RETURN (ACE_Sig_Handlers_Set::sig_handlers_[signum], + ACE_SIG_HANDLERS_SET, + 0); + return ACE_Sig_Handlers_Set::sig_handlers_[signum]; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handlers) + +void +ACE_Sig_Handlers::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Sig_Handlers::dump"); +#endif /* ACE_HAS_DUMP */ +} + +// This is the method that does all the dirty work... The basic +// structure of this method was devised by Detlef Becker. + +int +ACE_Sig_Handlers::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Sig_Handlers::register_handler"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Sig_Adapter *ace_sig_adapter = 0; // Our signal handler. + ACE_Sig_Adapter *extern_sh = 0; // An external signal handler. + ACE_Sig_Action sa; + + // Get current signal disposition. + sa.retrieve_action (signum); + + // Check whether we are already in control of the signal + // handling disposition... + + if (!(sa.handler () == ace_signal_handlers_dispatcher + || sa.handler () == ACE_SignalHandler (SIG_IGN) + || sa.handler () == ACE_SignalHandler (SIG_DFL))) + { + // Drat, a 3rd party library has already installed a signal ;-( + + // Upto here we never disabled RESTART_MODE. Thus, + // RESTART_MODE can only be changed by 3rd party libraries. + + if (ACE_BIT_DISABLED (sa.flags (), SA_RESTART) + && ACE_Sig_Handlers::third_party_sig_handler_) + // Toggling is disallowed since we might break 3rd party + // code. + return -1; + + // Note that we've seen a 3rd party handler... + ACE_Sig_Handlers::third_party_sig_handler_ = true; + + // Create a new 3rd party disposition, remembering its + // preferred signal blocking etc...; + ACE_NEW_RETURN (extern_sh, + ACE_Sig_Adapter (sa, + ++ACE_Sig_Handlers::sigkey_), + -1); + // Add the external signal handler to the set of handlers + // for this signal. + if (ACE_Sig_Handlers_Set::instance (signum)->insert (extern_sh) == -1) + { + delete extern_sh; + return -1; + } + } + // Add our new handler at this point. + ACE_NEW_RETURN (ace_sig_adapter, + ACE_Sig_Adapter (new_sh, + ++ACE_Sig_Handlers::sigkey_), + -1); + // Add the ACE signal handler to the set of handlers for this + // signal (make sure it goes before the external one if there is + // one of these). + if (ACE_Sig_Handlers_Set::instance (signum)->insert (ace_sig_adapter) == -1) + { + // We couldn't reinstall our handler, so let's pretend like + // none of this happened... + if (extern_sh) + { + ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh); + delete extern_sh; + } + delete ace_sig_adapter; + return -1; + } + // If ACE_Sig_Handlers::dispatch() was set we're done. + else if (sa.handler () == ace_signal_handlers_dispatcher) + return ace_sig_adapter->sigkey (); + + // Otherwise, we need to register our handler function so that + // all signals will be dispatched through ACE. + else + { + // Make sure that new_disp points to a valid location if the + // user doesn't care... + if (new_disp == 0) + new_disp = &sa; + + new_disp->handler (ace_signal_handlers_dispatcher); + + // Default is to restart signal handlers. + new_disp->flags (new_disp->flags () | SA_RESTART); + new_disp->flags (new_disp->flags () | SA_SIGINFO); + + // Finally install (possibly reinstall) the ACE signal + // handler disposition with the SA_RESTART mode enabled. + if (new_disp->register_action (signum, old_disp) == -1) + { + // Yikes, lots of roll back at this point... + ACE_Sig_Handlers_Set::instance (signum)->remove (ace_sig_adapter); + delete ace_sig_adapter; + + if (extern_sh) + { + ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh); + delete extern_sh; + } + return -1; + } + else // Return the signal key so that programs can cancel this + // handler if they want! + return ace_sig_adapter->sigkey (); + } + } + + return -1; +} + +// Remove the ACE_Event_Handler currently associated with . +// Install the new disposition (if given) and return the previous +// disposition (if desired by the caller). Returns 0 on success and +// -1 if is invalid. + +int +ACE_Sig_Handlers::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + ACE_TRACE ("ACE_Sig_Handlers::remove_handler"); + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_Guard m (*lock)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + + // Iterate through the set of handlers for this signal. + + for (ACE_Event_Handler **eh; + handler_iterator.next (eh) != 0; + handler_iterator.advance ()) + { + // Type-safe downcast would be nice here... + ACE_Sig_Adapter *sh = (ACE_Sig_Adapter *) *eh; + + // Remove the handler if (1) its key matches the key we've + // been told to remove or (2) if we've been told to remove + // *all* handlers (i.e., == -1). + + if (sh->sigkey () == sigkey || sigkey == -1) + { + handler_set->remove (*eh); + delete *eh; + } + } + + if (handler_set->size () == 0) + { + // If there are no more handlers left for a signal then + // register the new disposition or restore the default + // disposition. + + ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0); + + if (new_disp == 0) + new_disp = &sa; + + return new_disp->register_action (signum, old_disp); + } + return 0; + } + else + return -1; +} + +// Master dispatcher function that gets called by a signal handler and +// dispatches *all* the handlers... + +void +ACE_Sig_Handlers::dispatch (int signum, + siginfo_t *siginfo, + ucontext_t *ucontext) +{ + ACE_TRACE ("ACE_Sig_Handlers::dispatch"); + // The following is #ifdef'd out because it's entirely non-portable + // to acquire a mutex in a signal handler... +#if 0 + ACE_MT (ACE_Recursive_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK); + ACE_TSS_Guard m (*lock)); +#endif /* 0 */ + + // Save/restore errno. + ACE_Errno_Guard error (errno); + + ACE_Sig_Handler::sig_pending_ = 1; + + // Darn well better be in range since the OS dispatched this... + ACE_ASSERT (ACE_Sig_Handler::in_range (signum)); + + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + + for (ACE_Event_Handler **eh = 0; + handler_iterator.next (eh) != 0; + handler_iterator.advance ()) + { + if ((*eh)->handle_signal (signum, siginfo, ucontext) == -1) + { + handler_set->remove (*eh); + delete *eh; + } + } +} + +// Return the first item in the list of handlers. Note that this will +// trivially provide the same behavior as the ACE_Sig_Handler +// version if there is only 1 handler registered! + +ACE_Event_Handler * +ACE_Sig_Handlers::handler (int signum) +{ + ACE_TRACE ("ACE_Sig_Handlers::handler"); + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + ACE_Event_Handler **eh = 0; + handler_iterator.next (eh); + return *eh; +} + +// The following is a strange bit of logic that tries to give the same +// semantics as what happens in ACE_Sig_Handler when we replace the +// current signal handler with a new one. Note that if there is only +// one signal handler the behavior will be identical. If there is +// more than one handler then things get weird... + +ACE_Event_Handler * +ACE_Sig_Handlers::handler (int signum, ACE_Event_Handler *new_sh) +{ + ACE_TRACE ("ACE_Sig_Handlers::handler"); + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + ACE_Event_Handler **eh = 0; + + // Find the first handler... + handler_iterator.next (eh); + + // ... then remove it from the set ... + handler_set->remove (*eh); + + // ... and then insert the new signal handler into the beginning of + // the set (note, this is a bit too tied up in the implementation of + // ACE_Unbounded_Set...). + ACE_Sig_Adapter *temp = 0; + + ACE_NEW_RETURN (temp, + ACE_Sig_Adapter (new_sh, + ++ACE_Sig_Handlers::sigkey_), + 0); + handler_set->insert (temp); + return *eh; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Sig_Handler.h b/dep/ACE_wrappers/ace/Sig_Handler.h new file mode 100644 index 000000000..53d30d4f0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Sig_Handler.h @@ -0,0 +1,237 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Sig_Handler.h + * + * $Id: Sig_Handler.h 81388 2008-04-23 14:02:05Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_SIGNAL_HANDLER_H +#define ACE_SIGNAL_HANDLER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event_Handler.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Sig_Action; + +/** + * @class ACE_Sig_Handler + * + * @brief This is the main dispatcher of signals for ACE. It improves + * the existing UNIX signal handling mechanism by allowing C++ + * objects to handle signals in a way that avoids the use of + * global/static variables and functions. + * + * Using this class a program can register an ACE_Event_Handler + * with the ACE_Sig_Handler in order to handle a designated + * @a signum. When a signal occurs that corresponds to this + * @a signum, the @c handle_signal method of the registered + * ACE_Event_Handler is invoked automatically. + */ +class ACE_Export ACE_Sig_Handler +{ +public: + /// Default constructor. + ACE_Sig_Handler (void); + + /// Destructor + virtual ~ACE_Sig_Handler (void); + + // = Registration and removal methods. + /** + * Add a new ACE_Event_Handler and a new sigaction associated with + * @a signum. Passes back the existing ACE_Event_Handler and its + * sigaction if pointers are non-zero. Returns -1 on failure and >= + * 0 on success. + */ + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + + /** + * Remove the ACE_Event_Handler currently associated with + * @a signum. @a sigkey is ignored in this implementation since there + * is only one instance of a signal handler. Install the new + * disposition (if given) and return the previous disposition (if + * desired by the caller). Returns 0 on success and -1 if @a signum + * is invalid. + */ + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp = 0, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + + // Set/get signal status. + /// True if there is a pending signal. + static int sig_pending (void); + + /// Reset the value of so that no signal is pending. + static void sig_pending (int); + + // = Set/get the handler associated with a particular signal. + + /// Return the ACE_Sig_Handler associated with @a signum. + virtual ACE_Event_Handler *handler (int signum); + + /// Set a new ACE_Event_Handler that is associated with @a signum. + /// Return the existing handler. + virtual ACE_Event_Handler *handler (int signum, ACE_Event_Handler *); + + /** + * Callback routine registered with sigaction(2) that dispatches the + * method of the appropriate pre-registered + * ACE_Event_Handler. + */ + static void dispatch (int, siginfo_t *, + ucontext_t *); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = These methods and data members are shared by derived classes. + + /** + * Set a new ACE_Event_Handler that is associated with @a signum. + * Return the existing handler. Does not acquire any locks so that + * it can be called from a signal handler, such as . + */ + static ACE_Event_Handler *handler_i (int signum, + ACE_Event_Handler *); + + /** + * This implementation method is called by and + * @c dispatch. It doesn't do any locking so that it can be called + * within a signal handler, such as @c dispatch. It adds a new + * ACE_Event_Handler and a new sigaction associated with @a signum. + * Passes back the existing ACE_Event_Handler and its sigaction if + * pointers are non-zero. Returns -1 on failure and >= 0 on + * success. + */ + static int register_handler_i (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + + /// Check whether the SIGNUM is within the legal range of signals. + static int in_range (int signum); + + /// Keeps track of whether a signal is pending. + static sig_atomic_t sig_pending_; + +private: + /// Array used to store one user-defined Event_Handler for every + /// signal. + static ACE_Event_Handler *signal_handlers_[ACE_NSIG]; +}; + +/** + * @class ACE_Sig_Handlers + * + * @brief This is an alternative signal handling dispatcher for ACE. It + * allows a list of signal handlers to be registered for each + * signal. It also makes SA_RESTART the default mode. + * + * Using this class a program can register one or more + * ACE_Event_Handler with the ACE_Sig_Handler in order to + * handle a designated @a signum. When a signal occurs that + * corresponds to this @a signum, the methods of + * all the registered ACE_Event_Handlers are invoked + * automatically. + */ +class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler +{ +public: + // = Registration and removal methods. + /** + * Add a new ACE_Event_Handler and a new sigaction associated with + * @a signum. Passes back the existing ACE_Event_Handler and its + * sigaction if pointers are non-zero. Returns -1 on failure and + * a that is >= 0 on success. + */ + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + + /** + * Remove an ACE_Event_Handler currently associated with @a signum. + * We remove the handler if (1) its sigkey> matches the @a sigkey + * passed as a parameter or (2) if we've been told to remove all the + * handlers, i.e., == -1. If a new disposition is given it + * is installed and the previous disposition is returned (if desired + * by the caller). Returns 0 on success and -1 if @a signum is + * invalid. + */ + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp = 0, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + + // = Set/get the handler associated with a particular signal. + + /// Return the head of the list of s associated with + /// SIGNUM. + virtual ACE_Event_Handler *handler (int signum); + + /** + * Set a new ACE_Event_Handler that is associated with SIGNUM at + * the head of the list of signals. Return the existing handler + * that was at the head. + */ + virtual ACE_Event_Handler *handler (int signum, + ACE_Event_Handler *); + + /** + * Callback routine registered with sigaction(2) that dispatches the + * method of all the pre-registered + * ACE_Event_Handlers for @a signum + */ + static void dispatch (int signum, siginfo_t *, ucontext_t *); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /** + * Keeps track of the id that uniquely identifies each registered + * signal handler. This id can be used to cancel a timer via the + * method. + */ + static int sigkey_; + + /// If this is true then a 3rd party library has registered a + /// handler... + static bool third_party_sig_handler_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Sig_Handler.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SIG_HANDLER_H */ diff --git a/dep/ACE_wrappers/ace/Sig_Handler.inl b/dep/ACE_wrappers/ace/Sig_Handler.inl new file mode 100644 index 000000000..de02c09ab --- /dev/null +++ b/dep/ACE_wrappers/ace/Sig_Handler.inl @@ -0,0 +1,15 @@ +// -*- C++ -*- +// +// $Id: Sig_Handler.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_INLINE +ACE_Sig_Handler::ACE_Sig_Handler (void) +{ +} + +ACE_INLINE int +ACE_Sig_Handler::in_range (int signum) +{ + ACE_TRACE ("ACE_Sig_Handler::in_range"); + return signum > 0 && signum < ACE_NSIG; +} diff --git a/dep/ACE_wrappers/ace/Signal.cpp b/dep/ACE_wrappers/ace/Signal.cpp new file mode 100644 index 000000000..5f1745550 --- /dev/null +++ b/dep/ACE_wrappers/ace/Signal.cpp @@ -0,0 +1,221 @@ +// $Id: Signal.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Signal.h" +// #include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Signal.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Signal, "$Id: Signal.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Action) + +void +ACE_Sig_Action::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Sig_Action::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Set) + +ACE_Sig_Set::~ACE_Sig_Set (void) +{ + ACE_TRACE ("ACE_Sig_Set::~ACE_Sig_Set"); + ACE_OS::sigemptyset (&this->sigset_); +} + +ACE_Sig_Action::~ACE_Sig_Action (void) +{ + ACE_TRACE ("ACE_Sig_Action::~ACE_Sig_Action"); +} + +// Restore the signal mask. + +ACE_Sig_Guard::~ACE_Sig_Guard (void) +{ + //ACE_TRACE ("ACE_Sig_Guard::~ACE_Sig_Guard"); + if (!this->condition_) + return; + +#if !defined (ACE_LACKS_UNIX_SIGNALS) +#if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK) + ACE_OS::sigprocmask (SIG_SETMASK, + (sigset_t *) this->omask_, + 0); +#else + ACE_OS::thr_sigsetmask (SIG_SETMASK, + (sigset_t *) this->omask_, + 0); +#endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */ +#endif /* !ACE_LACKS_UNIX_SIGNALS */ +} + +void +ACE_Sig_Set::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Sig_Set::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Guard) + +void +ACE_Sig_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Sig_Guard::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Sig_Action::ACE_Sig_Action (void) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = 0; + + // Since Service_Config::signal_handler_ is static and has an + // ACE_Sig_Action instance, Win32 will get errno set unless this is + // commented out. +#if !defined (ACE_WIN32) + ACE_OS::sigemptyset (&this->sa_.sa_mask); +#endif /* ACE_WIN32 */ + this->sa_.sa_handler = 0; +} + +ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler, + sigset_t *sig_mask, + int sig_flags) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + if (sig_mask == 0) + ACE_OS::sigemptyset (&this->sa_.sa_mask); + else + this->sa_.sa_mask = *sig_mask; // Structure assignment... + +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ +} + +ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler, + const ACE_Sig_Set &sig_mask, + int sig_flags) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + // Structure assignment... + this->sa_.sa_mask = sig_mask.sigset (); + +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ +} + +ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler, + int signum, + sigset_t *sig_mask, + int sig_flags) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + if (sig_mask == 0) + ACE_OS::sigemptyset (&this->sa_.sa_mask); + else + this->sa_.sa_mask = *sig_mask; // Structure assignment... + +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ + ACE_OS::sigaction (signum, &this->sa_, 0); +} + +ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler, + int signum, + const ACE_Sig_Set &sig_mask, + int sig_flags) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + // Structure assignment... + this->sa_.sa_mask = sig_mask.sigset (); + +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ + ACE_OS::sigaction (signum, &this->sa_, 0); +} + +ACE_Sig_Action::ACE_Sig_Action (const ACE_Sig_Set &signals, + ACE_SignalHandler sig_handler, + const ACE_Sig_Set &sig_mask, + int sig_flags) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + // Structure assignment... + this->sa_.sa_mask = sig_mask.sigset (); + +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ + +#if (ACE_NSIG > 0) + for (int s = 1; s < ACE_NSIG; s++) + if ((signals.is_member (s)) == 1) + ACE_OS::sigaction (s, &this->sa_, 0); +#else /* ACE_NSIG <= 0 */ + ACE_UNUSED_ARG (signals); +#endif /* ACE_NSIG <= 0 */ +} + +ACE_Sig_Action::ACE_Sig_Action (const ACE_Sig_Set &signals, + ACE_SignalHandler sig_handler, + sigset_t *sig_mask, + int sig_flags) +{ + // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + if (sig_mask == 0) + ACE_OS::sigemptyset (&this->sa_.sa_mask); + else + this->sa_.sa_mask = *sig_mask; // Structure assignment... + +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ + +#if (ACE_NSIG > 0) + for (int s = 1; s < ACE_NSIG; s++) + if ((signals.is_member (s)) == 1) + ACE_OS::sigaction (s, &this->sa_, 0); +#else /* ACE_NSIG <= 0 */ + ACE_UNUSED_ARG (signals); +#endif /* ACE_NSIG <= 0 */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Signal.h b/dep/ACE_wrappers/ace/Signal.h new file mode 100644 index 000000000..736d62e5c --- /dev/null +++ b/dep/ACE_wrappers/ace/Signal.h @@ -0,0 +1,267 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Signal.h + * + * $Id: Signal.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_SIGNAL_H +#define ACE_SIGNAL_H +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if defined (ACE_DONT_INCLUDE_ACE_SIGNAL_H) +# error ace/Signal.h was #included instead of signal.h by ace/OS_NS_signal.h: fix!!!! +#endif /* ACE_DONT_INCLUDE_ACE_SIGNAL_H */ + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_signal.h" + +// Type of the extended signal handler. +typedef void (*ACE_Sig_Handler_Ex) (int, siginfo_t *siginfo, ucontext_t *ucontext); + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Sig_Set + * + * @brief Provide a C++ wrapper for the C sigset_t interface. + * + * Handle signals via a more elegant C++ interface (e.g., + * doesn't require the use of global variables or global + * functions in an application). + */ +class ACE_Export ACE_Sig_Set +{ +public: + // = Initialization and termination methods. + /// Initialize with @a sigset. If @a sigset == 0 then fill + /// the set. + ACE_Sig_Set (sigset_t *sigset); + + /// Initialize with @a sigset. If @a sigset == 0 then fill + /// the set. + ACE_Sig_Set (ACE_Sig_Set *sigset); + + /// If @a fill == 0 then initialize the to be empty, else + /// full. + ACE_Sig_Set (int fill = 0); + + ~ACE_Sig_Set (void); + + /// Create a set that excludes all signals defined by the system. + int empty_set (void); + + /// Create a set that includes all signals defined by the system. + int fill_set (void); + + /// Adds the individual signal specified by @a signo to the set. + int sig_add (int signo); + + /// Deletes the individual signal specified by @a signo from the set. + int sig_del (int signo); + + /// Checks whether the signal specified by @a signo is in the set. + int is_member (int signo) const; + + /// Returns a pointer to the underlying @c sigset_t. + operator sigset_t *(); + + /// Returns a copy of the underlying @c sigset_t. + sigset_t sigset (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Set of signals. + sigset_t sigset_; +}; + +/** + * @class ACE_Sig_Action + * + * @brief C++ wrapper facade for the @c sigaction struct. + */ +class ACE_Export ACE_Sig_Action +{ +public: + // = Initialization methods. + /// Default constructor. Initializes everything to 0. + ACE_Sig_Action (void); + + /// Assigns the various fields of a @c sigaction struct but doesn't + /// register for signal handling via the @c sigaction function. + ACE_Sig_Action (ACE_SignalHandler handler, + sigset_t *sigmask = 0, + int flags = 0); + + /// Assigns the various fields of a @c sigaction struct but doesn't + /// register for signal handling via the @c sigaction function. + ACE_Sig_Action (ACE_SignalHandler handler, + const ACE_Sig_Set &sigmask, + int flags = 0); + + /** + * Assigns the various fields of a @c sigaction struct and registers + * the @a handler to process signal @a signum via the @c sigaction + * function. + */ + ACE_Sig_Action (ACE_SignalHandler handler, + int signum, + sigset_t *sigmask = 0, + int flags = 0); + + /** + * Assigns the various fields of a @c sigaction struct and registers + * the @a handler to process signal @a signum via the @c sigaction + * function. + */ + ACE_Sig_Action (ACE_SignalHandler handler, + int signum, + const ACE_Sig_Set &sigmask, + int flags = 0); + + + // @@ The next two methods have a parameter as "signalss". Please do + // not change the argument name as "signals". This causes the + // following problem as reported by + // . + + // In the file Signal.h two of the functions have and argument name + // of signals. signals is a Qt macro (to do with their meta object + // stuff. + // We could as well have it as "signal", but I am nost sure whether + // that would cause a problem with something else - Bala + + /** + * Assigns the various fields of a @c sigaction struct and registers + * the @a handler to process all @a signalss via the @c sigaction + * function. + */ + ACE_Sig_Action (const ACE_Sig_Set &signalss, + ACE_SignalHandler handler, + const ACE_Sig_Set &sigmask, + int flags = 0); + + /** + * Assigns the various fields of a @c sigaction struct and registers + * the @a handler to process all @a signalss via the @c sigaction + * function. + */ + ACE_Sig_Action (const ACE_Sig_Set &signalss, + ACE_SignalHandler handler, + sigset_t *sigmask = 0, + int flags = 0); + + /// Copy constructor. + ACE_Sig_Action (const ACE_Sig_Action &s); + + /// Default dtor. + ~ACE_Sig_Action (void); + + // = Signal action management. + /// Register @c this as the current disposition and store old + /// disposition into @a oaction if it is non-NULL. + int register_action (int signum, + ACE_Sig_Action *oaction = 0); + + /// Assign the value of @a oaction to @c this and make it become the + /// new signal disposition. + int restore_action (int signum, + ACE_Sig_Action &oaction); + + /// Retrieve the current disposition into @c this. + int retrieve_action (int signum); + + /// Set current signal action. + void set (struct sigaction *); + + /// Get current signal action. + struct sigaction *get (void); + operator struct sigaction *(); + + /// Set current signal flags. + void flags (int); + + /// Get current signal flags. + int flags (void); + + /// Set current signal mask. + void mask (sigset_t *); + void mask (ACE_Sig_Set &); + + /// Get current signal mask. + sigset_t *mask (void); + + /// Set current signal handler (pointer to function). + void handler (ACE_SignalHandler); + + /// Get current signal handler (pointer to function). + ACE_SignalHandler handler (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Controls signal behavior. + struct sigaction sa_; +}; + +/** + * @class ACE_Sig_Guard + * + * @brief Hold signals in MASK for duration of a C++ statement block. + * Note that a "0" for mask causes all signals to be held. + */ +class ACE_Export ACE_Sig_Guard +{ +public: + // = Initialization and termination methods. + /// This is kind of conditional Guard, needed when guard should be + /// activated only when a spcific condition met. When condition == + /// true (default), Guard is activated + ACE_Sig_Guard (ACE_Sig_Set *mask = 0, bool condition = true); + + /// Restore blocked signals. + ~ACE_Sig_Guard (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Original signal mask. + ACE_Sig_Set omask_; + + /// Guard Condition + bool condition_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Signal.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SIGNAL_HANDLER_H */ diff --git a/dep/ACE_wrappers/ace/Signal.inl b/dep/ACE_wrappers/ace/Signal.inl new file mode 100644 index 000000000..858c33c26 --- /dev/null +++ b/dep/ACE_wrappers/ace/Signal.inl @@ -0,0 +1,265 @@ +// -*- C++ -*- +// +// $Id: Signal.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_signal.h" +#include "ace/config-all.h" +#include "ace/Trace.h" +#include "ace/Object_Manager_Base.h" +#include "ace/OS_NS_Thread.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Sig_Set::ACE_Sig_Set (sigset_t *ss) + // : sigset_ () +{ + ACE_TRACE ("ACE_Sig_Set::ACE_Sig_Set"); + + if (ss == 0) + ACE_OS::sigfillset (&this->sigset_); + else + // Structure assignment. + this->sigset_ = *ss; +} + +ACE_INLINE +ACE_Sig_Set::ACE_Sig_Set (int fill) + // : sigset_ () +{ + ACE_TRACE ("ACE_Sig_Set::ACE_Sig_Set"); + + if (fill) + ACE_OS::sigfillset (&this->sigset_); + else + ACE_OS::sigemptyset (&this->sigset_); +} + +ACE_INLINE +ACE_Sig_Set::ACE_Sig_Set (ACE_Sig_Set *ss) + // : sigset_ () +{ + ACE_TRACE ("ACE_Sig_Set::ACE_Sig_Set"); + + if (ss == 0) + ACE_OS::sigfillset (&this->sigset_); + else + this->sigset_ = ss->sigset_; +} + +ACE_INLINE int +ACE_Sig_Set::empty_set (void) +{ + ACE_TRACE ("ACE_Sig_Set::empty_set"); + return ACE_OS::sigemptyset (&this->sigset_); +} + +ACE_INLINE int +ACE_Sig_Set::fill_set (void) +{ + ACE_TRACE ("ACE_Sig_Set::fill_set"); + return ACE_OS::sigfillset (&this->sigset_); +} + +ACE_INLINE int +ACE_Sig_Set::sig_add (int signo) +{ + ACE_TRACE ("ACE_Sig_Set::sig_add"); + return ACE_OS::sigaddset (&this->sigset_, signo); +} + +ACE_INLINE int +ACE_Sig_Set::sig_del (int signo) +{ + ACE_TRACE ("ACE_Sig_Set::sig_del"); + return ACE_OS::sigdelset (&this->sigset_, signo); +} + +ACE_INLINE int +ACE_Sig_Set::is_member (int signo) const +{ + ACE_TRACE ("ACE_Sig_Set::is_member"); + return ACE_OS::sigismember (const_cast (&this->sigset_), signo); +} + +ACE_INLINE +ACE_Sig_Set::operator sigset_t *(void) +{ + ACE_TRACE ("ACE_Sig_Set::operator sigset_t *"); + return &this->sigset_; +} + +ACE_INLINE sigset_t +ACE_Sig_Set::sigset (void) const +{ + ACE_TRACE ("ACE_Sig_Set::sigset"); + return this->sigset_; +} + +ACE_INLINE int +ACE_Sig_Action::flags (void) +{ + ACE_TRACE ("ACE_Sig_Action::flags"); + return this->sa_.sa_flags; +} + +ACE_INLINE void +ACE_Sig_Action::flags (int flags) +{ + ACE_TRACE ("ACE_Sig_Action::flags"); + this->sa_.sa_flags = flags; +} + +ACE_INLINE sigset_t * +ACE_Sig_Action::mask (void) +{ + ACE_TRACE ("ACE_Sig_Action::mask"); + return &this->sa_.sa_mask; +} + +ACE_INLINE void +ACE_Sig_Action::mask (sigset_t *ss) +{ + ACE_TRACE ("ACE_Sig_Action::mask"); + if (ss != 0) + this->sa_.sa_mask = *ss; // Structure assignment +} + +ACE_INLINE void +ACE_Sig_Action::mask (ACE_Sig_Set &ss) +{ + ACE_TRACE ("ACE_Sig_Action::mask"); + this->sa_.sa_mask = ss.sigset (); // Structure assignment +} + +ACE_INLINE ACE_SignalHandler +ACE_Sig_Action::handler (void) +{ + ACE_TRACE ("ACE_Sig_Action::handler"); + return ACE_SignalHandler (this->sa_.sa_handler); +} + +ACE_INLINE void +ACE_Sig_Action::handler (ACE_SignalHandler handler) +{ + ACE_TRACE ("ACE_Sig_Action::handler"); +#if !defined(ACE_HAS_TANDEM_SIGNALS) + this->sa_.sa_handler = ACE_SignalHandlerV (handler); +#else + this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (handler); +#endif /* !ACE_HAS_TANDEM_SIGNALS */ +} + +#if 0 +ACE_INLINE ACE_SignalHandler +ACE_Sig_Action::sigaction (void) +{ + ACE_TRACE ("ACE_Sig_Action::sigaction"); + return ACE_SignalHandler (this->sa_.sa_sigaction); +} + +ACE_INLINE void +ACE_Sig_Action::sigaction (ACE_SignalHandler handler) +{ + ACE_TRACE ("ACE_Sig_Action::sigaction"); + this->sa_.sa_sigaction = (void (*)()) ACE_SignalHandlerV (handler); +} +#endif /* 0 */ + +ACE_INLINE void +ACE_Sig_Action::set (struct sigaction *sa) +{ + ACE_TRACE ("ACE_Sig_Action::set"); + this->sa_ = *sa; // Structure assignment. +} + +ACE_INLINE struct sigaction * +ACE_Sig_Action::get (void) +{ + ACE_TRACE ("ACE_Sig_Action::get"); + return &this->sa_; +} + +ACE_INLINE +ACE_Sig_Action::operator struct sigaction * () +{ + ACE_TRACE ("ACE_Sig_Action::operator struct sigaction *"); + return &this->sa_; +} + +ACE_INLINE +ACE_Sig_Action::ACE_Sig_Action (const ACE_Sig_Action &s) + // : sa_ () +{ + ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + *this = s; // structure copy. +} + +ACE_INLINE int +ACE_Sig_Action::register_action (int signum, ACE_Sig_Action *oaction) +{ + ACE_TRACE ("ACE_Sig_Action::register_action"); + struct sigaction *sa = oaction == 0 ? 0 : oaction->get (); + + return ACE_OS::sigaction (signum, &this->sa_, sa); +} + +ACE_INLINE int +ACE_Sig_Action::retrieve_action (int signum) +{ + ACE_TRACE ("ACE_Sig_Action::retrieve_action"); + return ACE_OS::sigaction (signum, 0, &this->sa_); +} + +ACE_INLINE int +ACE_Sig_Action::restore_action (int signum, ACE_Sig_Action &oaction) +{ + ACE_TRACE ("ACE_Sig_Action::restore_action"); + this->sa_ = *oaction.get (); // Structure assignment + return ACE_OS::sigaction (signum, &this->sa_, 0); +} + +// Block out the signal MASK until the destructor is called. + +ACE_INLINE +ACE_Sig_Guard::ACE_Sig_Guard (ACE_Sig_Set *mask, + bool condition) + : omask_ () + , condition_ (condition) +{ + //ACE_TRACE ("ACE_Sig_Guard::ACE_Sig_Guard"); + if (!this->condition_) + return; + +#if defined (ACE_LACKS_UNIX_SIGNALS) + ACE_UNUSED_ARG (mask); +#else + // If MASK is 0 then block all signals! + if (mask == 0) + { +# if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK) + ACE_OS::sigprocmask (SIG_BLOCK, + ACE_OS_Object_Manager::default_mask (), + (sigset_t *) this->omask_); +# else + ACE_OS::thr_sigsetmask (SIG_BLOCK, + ACE_OS_Object_Manager::default_mask (), + (sigset_t *) this->omask_); +# endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */ + } + else +# if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK) + ACE_OS::sigprocmask (SIG_BLOCK, + (sigset_t *) *mask, + (sigset_t *) + this->omask_); +# else + ACE_OS::thr_sigsetmask (SIG_BLOCK, + (sigset_t *) *mask, + (sigset_t *) + this->omask_); +# endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */ +#endif /* ACE_LACKS_UNIX_SIGNALS */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Singleton.cpp b/dep/ACE_wrappers/ace/Singleton.cpp new file mode 100644 index 000000000..41c9cc194 --- /dev/null +++ b/dep/ACE_wrappers/ace/Singleton.cpp @@ -0,0 +1,534 @@ +// $Id: Singleton.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_SINGLETON_CPP +#define ACE_SINGLETON_CPP + +#include "ace/Singleton.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Singleton.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Object_Manager.h" +#include "ace/Log_Msg.h" +#include "ace/Framework_Component.h" +#include "ace/Guard_T.h" + +ACE_RCSID (ace, + Singleton, + "$Id: Singleton.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template void +ACE_Singleton::dump (void) +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Singleton::dump"); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), + ACE_Singleton::instance_i ())); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +#endif /* ACE_HAS_DUMP */ +} + +template ACE_Singleton *& +ACE_Singleton::instance_i (void) +{ +#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Pointer to the Singleton instance. This works around a bug with + // G++ and it's (mis-)handling of templates and statics... + static ACE_Singleton *singleton_ = 0; + + return singleton_; +#else + return ACE_Singleton::singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template TYPE * +ACE_Singleton::instance (void) +{ + ACE_TRACE ("ACE_Singleton::instance"); + + ACE_Singleton *&singleton = + ACE_Singleton::instance_i (); + + // Perform the Double-Check pattern... + if (singleton == 0) + { + if (ACE_Object_Manager::starting_up () || + ACE_Object_Manager::shutting_down ()) + { + // The program is still starting up, and therefore assumed + // to be single threaded. There's no need to double-check. + // Or, the ACE_Object_Manager instance has been destroyed, + // so the preallocated lock is not available. Either way, + // don't register for destruction with the + // ACE_Object_Manager: we'll have to leak this instance. + + ACE_NEW_RETURN (singleton, (ACE_Singleton), 0); + } + else + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + // Obtain a lock from the ACE_Object_Manager. The pointer + // is static, so we only obtain one per ACE_Singleton + // instantiation. + static ACE_LOCK *lock = 0; + if (ACE_Object_Manager::get_singleton_lock (lock) != 0) + // Failed to acquire the lock! + return 0; + + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); + + if (singleton == 0) + { +#endif /* ACE_MT_SAFE */ + ACE_NEW_RETURN (singleton, (ACE_Singleton), 0); + + // Register for destruction with ACE_Object_Manager. + ACE_Object_Manager::at_exit (singleton); +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + } +#endif /* ACE_MT_SAFE */ + } + } + + return &singleton->instance_; +} + +template void +ACE_Singleton::cleanup (void *) +{ + delete this; + ACE_Singleton::instance_i () = 0; +} + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Pointer to the Singleton instance. +template ACE_Singleton * +ACE_Singleton::singleton_ = 0; + +template ACE_Unmanaged_Singleton * +ACE_Unmanaged_Singleton::singleton_ = 0; +#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +template void +ACE_Unmanaged_Singleton::dump (void) +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Unmanaged_Singleton::dump"); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), + ACE_Unmanaged_Singleton::instance_i ())); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unmanaged_Singleton *& +ACE_Unmanaged_Singleton::instance_i (void) +{ +#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Pointer to the Singleton instance. This works around a bug with + // G++ and it's (mis-)handling of templates and statics... + static ACE_Unmanaged_Singleton *singleton_ = 0; + + return singleton_; +#else + return ACE_Unmanaged_Singleton::singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template TYPE * +ACE_Unmanaged_Singleton::instance (void) +{ + ACE_TRACE ("ACE_Unmanaged_Singleton::instance"); + + ACE_Unmanaged_Singleton *&singleton = + ACE_Unmanaged_Singleton::instance_i (); + + // Perform the Double-Check pattern... + if (singleton == 0) + { + if (ACE_Object_Manager::starting_up () || + ACE_Object_Manager::shutting_down ()) + { + // The program is still starting up, and therefore assumed + // to be single threaded. There's no need to double-check. + // Or, the ACE_Object_Manager instance has been destroyed, + // so the preallocated lock is not available. Either way, + // don't register for destruction with the + // ACE_Object_Manager: we'll have to leak this instance. + + ACE_NEW_RETURN (singleton, (ACE_Unmanaged_Singleton), + 0); + } + else + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + // Obtain a lock from the ACE_Object_Manager. The pointer + // is static, so we only obtain one per + // ACE_Unmanaged_Singleton instantiation. + static ACE_LOCK *lock = 0; + if (ACE_Object_Manager::get_singleton_lock (lock) != 0) + // Failed to acquire the lock! + return 0; + + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); +#endif /* ACE_MT_SAFE */ + + if (singleton == 0) + ACE_NEW_RETURN (singleton, + (ACE_Unmanaged_Singleton), + 0); + } + } + + return &singleton->instance_; +} + +template void +ACE_Unmanaged_Singleton::close (void) +{ + ACE_Unmanaged_Singleton *&singleton = + ACE_Unmanaged_Singleton::instance_i (); + + if (singleton) + { + singleton->cleanup (); + ACE_Unmanaged_Singleton::instance_i () = 0; + } +} + +template void +ACE_TSS_Singleton::dump (void) +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_TSS_Singleton::dump"); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), + ACE_TSS_Singleton::instance_i ())); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +#endif /* ACE_HAS_DUMP */ +} + +template ACE_TSS_Singleton *& +ACE_TSS_Singleton::instance_i (void) +{ +#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Pointer to the Singleton instance. This works around a bug with + // G++ and it's (mis-)handling of templates and statics... + static ACE_TSS_Singleton *singleton_ = 0; + + return singleton_; +#else + return ACE_TSS_Singleton::singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template TYPE * +ACE_TSS_Singleton::instance (void) +{ + ACE_TRACE ("ACE_TSS_Singleton::instance"); + + ACE_TSS_Singleton *&singleton = + ACE_TSS_Singleton::instance_i (); + + // Perform the Double-Check pattern... + if (singleton == 0) + { + if (ACE_Object_Manager::starting_up () || + ACE_Object_Manager::shutting_down ()) + { + // The program is still starting up, and therefore assumed + // to be single threaded. There's no need to double-check. + // Or, the ACE_Object_Manager instance has been destroyed, + // so the preallocated lock is not available. Either way, + // don't register for destruction with the + // ACE_Object_Manager: we'll have to leak this instance. + + ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton), 0); + } + else + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + + // Obtain a lock from the ACE_Object_Manager. The pointer + // is static, so we only obtain one per ACE_Singleton instantiation. + static ACE_LOCK *lock = 0; + if (ACE_Object_Manager::get_singleton_lock (lock) != 0) + // Failed to acquire the lock! + return 0; + + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); + + if (singleton == 0) + { +#endif /* ACE_MT_SAFE */ + ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton), + 0); + + // Register for destruction with ACE_Object_Manager. + ACE_Object_Manager::at_exit (singleton); +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + } +#endif /* ACE_MT_SAFE */ + } + } + + return ACE_TSS_GET (&singleton->instance_, TYPE); +} + +template void +ACE_TSS_Singleton::cleanup (void *) +{ + delete this; + ACE_TSS_Singleton::instance_i () = 0; +} + +template void +ACE_Unmanaged_TSS_Singleton::dump (void) +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Unmanaged_TSS_Singleton::dump"); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), + ACE_Unmanaged_TSS_Singleton::instance_i ())); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unmanaged_TSS_Singleton *& +ACE_Unmanaged_TSS_Singleton::instance_i (void) +{ +#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Pointer to the Singleton instance. This works around a bug with + // G++ and it's (mis-)handling of templates and statics... + static ACE_Unmanaged_TSS_Singleton *singleton_ = 0; + + return singleton_; +#else + return ACE_Unmanaged_TSS_Singleton::singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template TYPE * +ACE_Unmanaged_TSS_Singleton::instance (void) +{ + ACE_TRACE ("ACE_Unmanaged_TSS_Singleton::instance"); + + ACE_Unmanaged_TSS_Singleton *&singleton = + ACE_Unmanaged_TSS_Singleton::instance_i (); + + // Perform the Double-Check pattern... + if (singleton == 0) + { + if (ACE_Object_Manager::starting_up () || + ACE_Object_Manager::shutting_down ()) + { + // The program is still starting up, and therefore assumed + // to be single threaded. There's no need to double-check. + // Or, the ACE_Object_Manager instance has been destroyed, + // so the preallocated lock is not available. Either way, + // don't register for destruction with the + // ACE_Object_Manager: we'll have to leak this instance. + + ACE_NEW_RETURN (singleton, + (ACE_Unmanaged_TSS_Singleton), + 0); + } + else + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + // Obtain a lock from the ACE_Object_Manager. The pointer + // is static, so we only obtain one per + // ACE_Unmanaged_Singleton instantiation. + static ACE_LOCK *lock = 0; + if (ACE_Object_Manager::get_singleton_lock (lock) != 0) + // Failed to acquire the lock! + return 0; + + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); +#endif /* ACE_MT_SAFE */ + + if (singleton == 0) + ACE_NEW_RETURN (singleton, + (ACE_Unmanaged_TSS_Singleton), + 0); + } + } + + return ACE_TSS_GET (&singleton->instance_, TYPE); +} + +template void +ACE_Unmanaged_TSS_Singleton::close (void) +{ + ACE_Unmanaged_TSS_Singleton *&singleton = + ACE_Unmanaged_TSS_Singleton::instance_i (); + + if (singleton) + singleton->cleanup (); +} + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Pointer to the Singleton instance. +template ACE_TSS_Singleton * +ACE_TSS_Singleton::singleton_ = 0; + +template +ACE_Unmanaged_TSS_Singleton * +ACE_Unmanaged_TSS_Singleton::singleton_ = 0; +#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +/*************************************************************************/ + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Pointer to the Singleton instance. +template ACE_DLL_Singleton_T * +ACE_DLL_Singleton_T::singleton_ = 0; +#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +template void +ACE_DLL_Singleton_T::dump (void) +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_DLL_Singleton_T::dump"); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), + ACE_DLL_Singleton_T::instance_i ())); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_DLL_Singleton_T *& +ACE_DLL_Singleton_T::instance_i (void) +{ + ACE_TRACE ("ACE_DLL_Singleton_T::instance_i"); + +#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Pointer to the Singleton instance. This works around a bug with + // G++ and it's (mis-)handling of templates and statics... + static ACE_DLL_Singleton_T *singleton_ = 0; + + return singleton_; +#else + return ACE_DLL_Singleton_T::singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template TYPE * +ACE_DLL_Singleton_T::instance (void) +{ + ACE_TRACE ("ACE_DLL_Singleton_T::instance"); + + ACE_DLL_Singleton_T *&singleton = + ACE_DLL_Singleton_T::instance_i (); + + // Perform the Double-Check pattern... + if (singleton == 0) + { + if (ACE_Object_Manager::starting_up () || + ACE_Object_Manager::shutting_down ()) + { + // The program is still starting up, and therefore assumed + // to be single threaded. There's no need to double-check. + // Or, the ACE_Object_Manager instance has been destroyed, + // so the preallocated lock is not available. Either way, + // don't register for destruction with the + // ACE_Object_Manager: we'll have to leak this instance. + + ACE_NEW_RETURN (singleton, (ACE_DLL_Singleton_T), + 0); + } + else + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + // Obtain a lock from the ACE_Object_Manager. The pointer + // is static, so we only obtain one per + // ACE_Unmanaged_Singleton instantiation. + static ACE_LOCK *lock = 0; + if (ACE_Object_Manager::get_singleton_lock (lock) != 0) + // Failed to acquire the lock! + return 0; + + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); +#endif /* ACE_MT_SAFE */ + + if (singleton == 0) + ACE_NEW_RETURN (singleton, + (ACE_DLL_Singleton_T), + 0); + } + //ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_DLL_Singleton, singleton); + ACE_Framework_Repository::instance ()->register_component + (new ACE_Framework_Component_T > (singleton)); + } + + return &singleton->instance_; +} + +template void +ACE_DLL_Singleton_T::close (void) +{ + ACE_TRACE ("ACE_DLL_Singleton_T::close"); + + ACE_DLL_Singleton_T *&singleton = + ACE_DLL_Singleton_T::instance_i (); + + delete singleton; + singleton = 0; +} + +template void +ACE_DLL_Singleton_T::close_singleton (void) +{ + ACE_TRACE ("ACE_DLL_Singleton_T::close_singleton"); + ACE_DLL_Singleton_T::close (); +} + +template const ACE_TCHAR * +ACE_DLL_Singleton_T::dll_name (void) +{ + return this->instance ()->dll_name (); +} + +template const ACE_TCHAR * +ACE_DLL_Singleton_T::name (void) +{ + return this->instance ()->name (); +} + + +/**********************************************************************/ + +template const ACE_TCHAR* +ACE_DLL_Singleton_Adapter_T::dll_name (void) +{ + // @todo make this a constant somewhere (or it there already is one + // then use it. + return ACE_TEXT("ACE"); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_SINGLETON_CPP */ diff --git a/dep/ACE_wrappers/ace/Singleton.h b/dep/ACE_wrappers/ace/Singleton.h new file mode 100644 index 000000000..e9c8498ff --- /dev/null +++ b/dep/ACE_wrappers/ace/Singleton.h @@ -0,0 +1,327 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Singleton.h + * + * $Id: Singleton.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @brief + * + * @author Tim Harrison + * @author Douglas C. Schmidt + * @author Chris Lahey + * @author Rich Christy + * @author David Levine + */ +//============================================================================= + +#ifndef ACE_SINGLETON_H +#define ACE_SINGLETON_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" +#include "ace/TSS_T.h" +#include "ace/Cleanup.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Singleton + * + * @brief A Singleton Adapter uses the Adapter pattern to turn ordinary + * classes into Singletons optimized with the Double-Checked + * Locking optimization pattern. + * + * This implementation is a slight variation on the GoF + * Singleton pattern. In particular, a single + * > instance is allocated here, + * not a instance. The reason for this is to allow + * registration with the ACE_Object_Manager, so that the + * Singleton can be cleaned up when the process exits. For this + * scheme to work, a (static) cleanup() function must be + * provided. ACE_Singleton provides one so that TYPE doesn't + * need to. + * If you want to make sure that only the singleton instance of + * is created, and that users cannot create their own + * instances of , do the following to class : + * (a) Make the constructor of private (or protected) + * (b) Make Singleton a friend of + * Here is an example: + * @verbatim + * class foo + * { + * friend class ACE_Singleton; + * private: + * foo () { cout << "foo constructed" << endl; } + * ~foo () { cout << "foo destroyed" << endl; } + * }; + * typedef ACE_Singleton FOO; + * @endverbatim + * + * @note The best types to use for ACE_LOCK are + * ACE_Recursive_Thread_Mutex and ACE_Null_Mutex. + * ACE_Recursive_Thread_Mutex should be used in multi-threaded + * programs in which it is possible for more than one thread to + * access the > instance. + * ACE_Null_Mutex can be used otherwise. The reason that these + * types of locks are best has to do with their allocation by + * the ACE_Object_Manager. Single ACE_Recursive_Thread_Mutex + * and ACE_Null_Mutex instances are used for all ACE_Singleton + * instantiations. However, other types of locks are allocated + * per ACE_Singleton instantiation. + */ +template +class ACE_Singleton : public ACE_Cleanup +{ +public: + /// Global access point to the Singleton. + static TYPE *instance (void); + + /// Cleanup method, used by to destroy the + /// ACE_Singleton. + virtual void cleanup (void *param = 0); + + /// Dump the state of the object. + static void dump (void); + +protected: + /// Default constructor. + ACE_Singleton (void); + + /// Contained instance. + TYPE instance_; + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + /// Pointer to the Singleton (ACE_Cleanup) instance. + static ACE_Singleton *singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + /// Get pointer to the Singleton instance. + static ACE_Singleton *&instance_i (void); +}; + +/** + * @class ACE_Unmanaged_Singleton + * + * @brief Same as ACE_Singleton, except does _not_ register with + * ACE_Object_Manager for destruction. + * + * This version of ACE_Singleton can be used if, for example, + * its DLL will be unloaded before the ACE_Object_Manager + * destroys the instance. Unlike with ACE_Singleton, the + * application is responsible for explicitly destroying the + * instance after it is no longer needed (if it wants to avoid + * memory leaks, at least). The close() static member function + * must be used to explicitly destroy the Singleton. + * Usage is the same as for ACE_Singleton, but note that if you + * you declare a friend, the friend class must still be an + * *ACE_Singleton*, not an ACE_Unmanaged_Singleton. + */ +template +class ACE_Unmanaged_Singleton : public ACE_Singleton +{ +public: + /// Global access point to the Singleton. + static TYPE *instance (void); + + /// Explicitly delete the Singleton instance. + static void close (void); + + /// Dump the state of the object. + static void dump (void); + +protected: + /// Default constructor. + ACE_Unmanaged_Singleton (void); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + /// Pointer to the Singleton (ACE_Cleanup) instance. + static ACE_Unmanaged_Singleton *singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + /// Get pointer to the Singleton instance. + static ACE_Unmanaged_Singleton *&instance_i (void); +}; + +/** + * @class ACE_TSS_Singleton + * + * @brief This class uses the Adapter pattern to turn ordinary classes + * into Thread-specific Singletons optimized with the + * Double-Checked Locking optimization pattern. + * + * This implementation is another variation on the GoF Singleton + * pattern. In this case, a single > instance is allocated here, not a instance. + * Each call to the static method returns a Singleton + * whose pointer resides in thread-specific storage. As with + * ACE_Singleton, we use the ACE_Object_Manager so that the + * Singleton can be cleaned up when the process exits. For this + * scheme to work, a (static) cleanup() function must be + * provided. ACE_Singleton provides one so that TYPE doesn't + * need to. + */ +template +class ACE_TSS_Singleton : public ACE_Cleanup +{ +public: + /// Global access point to the singleton. + static TYPE *instance (void); + + /// Cleanup method, used by to destroy the + /// singleton. + virtual void cleanup (void *param = 0); + + /// Dump the state of the object. + static void dump (void); + +protected: + /// Default constructor. + ACE_TSS_Singleton (void); + + /// Contained instance. + ACE_TSS_TYPE (TYPE) instance_; + + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Singleton &)) + ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Singleton (const ACE_TSS_Singleton &)) + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + /// Pointer to the Singleton (ACE_Cleanup) instance. + static ACE_TSS_Singleton *singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + /// Get pointer to the TSS Singleton instance. + static ACE_TSS_Singleton *&instance_i (void); +}; + +/** + * @class ACE_Unmanaged_TSS_Singleton + * + * @brief Same as ACE_TSS_Singleton, except does _not_ register with + * ACE_Object_Manager for destruction. + * + * This version of ACE_TSS_Singleton can be used if, for example, its DLL will + * be unloaded before the ACE_Object_Manager destroys the instance. Unlike with + * ACE_Singleton, the application is responsible for explicitly destroying the + * instance after it is no longer needed (if it wants to avoid memory leaks, + * at least). The close() static member function must be used to explicitly + * destroy the Singleton. + */ +template +class ACE_Unmanaged_TSS_Singleton : public ACE_TSS_Singleton +{ +public: + /// Global access point to the singleton. + static TYPE *instance (void); + + /// Explicitly delete the singleton instance. + static void close (void); + + /// Dump the state of the object. + static void dump (void); + +protected: + /// Default constructor. + ACE_Unmanaged_TSS_Singleton (void); + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + /// Pointer to the Singleton (ACE_Cleanup) instance. + static ACE_Unmanaged_TSS_Singleton *singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + /// Get pointer to the Singleton instance. + static ACE_Unmanaged_TSS_Singleton *&instance_i (void); +}; + +/** + * @class ACE_DLL_Singleton_T + * + * @brief Same as ACE_Singleton, except that it registers for + * destruction with the ACE_Framework_Repository instead of + * with the ACE_Object_Manager directly. + * + * This version of ACE_Singleton should be used for singletons + * that live in a dll loaded either directly by ACE_DLL or indirectly + * by the ACE Service Configuration framework. Whenever ACE_DLL is ready + * to actually unload the dll, ACE_DLL_Singleton based dlls associated + * with that dll will be destroyed first. In fact, any singleton can + * safely use ACE_DLL_Singleton, even those that don't live in dlls. In + * that case, the singleton will be destroyed at normal program shutdown. + * + * The only additional requirement is that the contained class + * export name() and dll_name() methods. See ACE_DLL_Singleton_Adapter_T + * below for a convenient example of how to satisfy this + * requirement for the dll_name(). + * + * Usage is the same as for ACE_Singleton, but note that if you + * you declare a friend, the friend class must still be an + * *ACE_Singleton*, not an ACE_Unmanaged_Singleton. + */ +template +class ACE_DLL_Singleton_T +{ +public: + //void cleanup (void *param = 0); + + /// Global access point to the Singleton. + static TYPE *instance (void); + + /// Explicitly delete the Singleton instance. + static void close (void); + + static void close_singleton (void); + + /// Dump the state of the object. + static void dump (void); + + const ACE_TCHAR *dll_name (void); + + const ACE_TCHAR *name (void); + +protected: + /// Default constructor. + ACE_DLL_Singleton_T (void); + + /// Destructor. + ~ACE_DLL_Singleton_T (void); + + /// Contained instance. + TYPE instance_; + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + /// Pointer to the Singleton instance. + static ACE_DLL_Singleton_T *singleton_; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + /// Get pointer to the singleton instance. + static ACE_DLL_Singleton_T *&instance_i (void); +}; + +template +class ACE_DLL_Singleton_Adapter_T : public TYPE +{ +public: + const ACE_TCHAR *dll_name (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Singleton.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Singleton.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Singleton.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_SINGLETON_H */ diff --git a/dep/ACE_wrappers/ace/Singleton.inl b/dep/ACE_wrappers/ace/Singleton.inl new file mode 100644 index 000000000..107a8b78c --- /dev/null +++ b/dep/ACE_wrappers/ace/Singleton.inl @@ -0,0 +1,42 @@ +// -*- C++ -*- +// +// $Id: Singleton.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Default constructors. +// +// Note: don't explicitly initialize "instance_", because TYPE may not +// have a default constructor. Let the compiler figure it out . . . + +template ACE_INLINE +ACE_Singleton::ACE_Singleton (void) +{ +} + +template ACE_INLINE +ACE_Unmanaged_Singleton::ACE_Unmanaged_Singleton (void) +{ +} + +template ACE_INLINE +ACE_TSS_Singleton::ACE_TSS_Singleton (void) +{ +} + +template ACE_INLINE +ACE_Unmanaged_TSS_Singleton::ACE_Unmanaged_TSS_Singleton (void) +{ +} + +template ACE_INLINE +ACE_DLL_Singleton_T::ACE_DLL_Singleton_T (void) +{ +} + +template +ACE_DLL_Singleton_T::~ACE_DLL_Singleton_T (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Sock_Connect.cpp b/dep/ACE_wrappers/ace/Sock_Connect.cpp new file mode 100644 index 000000000..99815ce79 --- /dev/null +++ b/dep/ACE_wrappers/ace/Sock_Connect.cpp @@ -0,0 +1,1603 @@ +// $Id: Sock_Connect.cpp 82276 2008-07-09 17:35:49Z jtc $ + +#include "ace/Sock_Connect.h" +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Handle_Set.h" +#include "ace/Auto_Ptr.h" +#include "ace/SString.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_stdio.h" +#include "ace/ACE.h" + +#if defined (sparc) +# include "ace/OS_NS_fcntl.h" +#endif // sparc + +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/OS_NS_netdb.h" +#include "ace/OS_NS_unistd.h" +#include "ace/os_include/net/os_if.h" + +#if defined (ACE_HAS_IPV6) +# include "ace/Guard_T.h" +# include "ace/Recursive_Thread_Mutex.h" +# if defined (_AIX) +# include /**/ +# endif /* _AIX */ +#endif /* ACE_HAS_IPV6 */ + +# if defined (ACE_HAS_GETIFADDRS) +# if defined (ACE_VXWORKS) +# include /**/ +# else +# include /**/ +# endif /*ACE_VXWORKS */ +# endif /* ACE_HAS_GETIFADDRS */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) +#include /**/ +#include /**/ +#if defined (ACE_HAS_IPV6) +#include /**/ +extern "C" { + extern struct in_ifaddr* in_ifaddr; + extern LIST_HEAD(in_ifaddrhashhead, in_ifaddr) *in_ifaddrhashtbl; +} +#endif /* ACE_HAS_IPV6 */ +#include "ace/OS_NS_stdio.h" +#endif /* ACE_VXWORKS < 0x600 */ + +#if defined (ACE_VXWORKS) && ((ACE_VXWORKS == 0x630) || (ACE_VXWORKS == 0x640)) && defined (__RTP__) && defined (ACE_HAS_IPV6) +const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; +const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT; +const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; +const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; +#endif /* ACE_VXWORKS == 0x630 && __RTP__ && ACE_HAS_IPV6 */ + +#if defined (ACE_HAS_WINCE) +#include /**/ +// The following code is suggested by microsoft as a workaround to the fact +// that on Windows CE, these constants are exported as function addresses +// rather than simply values. +# include /**/ +const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; +const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; +#endif // ACE_HAS_WINCE + +#if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP) +# include "ace/OS_NS_stdio.h" +#endif + +#if defined (ACE_HAS_IPV6) + +// These defines support a generic usage based on +// the various SIGCF*IF ioctl implementations + +# if defined (SIOCGLIFCONF) +# define SIOCGIFCONF_CMD SIOCGLIFCONF +# if defined (__hpux) +# define IFREQ if_laddrreq +# define IFCONF if_laddrconf +# define IFC_REQ iflc_req +# define IFC_LEN iflc_len +# define IFC_BUF iflc_buf +# define IFR_ADDR iflr_addr +# define IFR_NAME iflr_name +# define IFR_FLAGS iflr_flags +# undef SETFAMILY +# define SA_FAMILY sa_family +# else +# define IFREQ lifreq +# define IFCONF lifconf +# define IFC_REQ lifc_req +# define IFC_LEN lifc_len +# define IFC_BUF lifc_buf +# define IFR_ADDR lifr_addr +# define IFR_NAME lifr_name +# define IFR_FLAGS lifr_flags +# define SETFAMILY +# define IFC_FAMILY lifc_family +# define IFC_FLAGS lifc_flags +# define SA_FAMILY ss_family +# endif +# else +# define SIOCGIFCONF_CMD SIOCGIFCONF +# define IFREQ ifreq +# define IFCONF ifconf +# define IFC_REQ ifc_req +# define IFC_LEN ifc_len +# define IFC_BUF ifc_buf +# define IFR_ADDR ifr_addr +# define IFR_NAME ifr_name +# define IFR_FLAGS ifr_flags +# undef SETFAMILY +# define SA_FAMILY sa_family +# endif /* SIOCGLIFCONF */ + +# if defined (ACE_HAS_THREADS) +# include "ace/Object_Manager.h" +# endif /* ACE_HAS_THREADS */ + +namespace +{ + // private: + // Used internally so not exported. + + // Does this box have ipv4 turned on? + int ace_ipv4_enabled = -1; + + // Does this box have ipv6 turned on? + int ace_ipv6_enabled = -1; + +} +#else /* ACE_HAS_IPV6 */ +# define SIOCGIFCONF_CMD SIOCGIFCONF +# define IFREQ ifreq +# define IFCONF ifconf +# define IFC_REQ ifc_req +# define IFC_LEN ifc_len +# define IFC_BUF ifc_buf +# define IFR_ADDR ifr_addr +# define IFR_NAME ifr_name +# define IFR_FLAGS ifr_flags +# undef SETFAMILY +# define SA_FAMILY sa_family +#endif /* ACE_HAS_IPV6 */ + +// This is a hack to work around a problem with Visual Age C++ 5 and 6 on AIX. +// Without this, the compiler auto-instantiates the ACE_Auto_Array_Ptr for +// ifreq (contained in this module) but only adds the #include for +// and not the one for which is also needed. Although we +// don't need the template defined here, it makes the compiler pull in +// and the build runs clean. +#if defined (AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 500) && (__IBMCPP__ < 700) +static ACE_Auto_Array_Ptr force_compiler_to_include_socket_h; +#endif /* AIX && __IBMCPP__ >= 500 */ + + +ACE_RCSID (ace, + Sock_Connect, + "$Id: Sock_Connect.cpp 82276 2008-07-09 17:35:49Z jtc $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Bind socket to an unused port. + +int +ACE::bind_port (ACE_HANDLE handle, ACE_UINT32 ip_addr, int address_family) +{ + ACE_TRACE ("ACE::bind_port"); + + ACE_INET_Addr addr; + +#if defined (ACE_HAS_IPV6) + if (address_family != PF_INET6) + // What do we do if it is PF_"INET6? Since it's 4 bytes, it must be an + // IPV4 address. Is there a difference? Why is this test done? dhinton +#else /* ACE_HAS_IPV6 */ + ACE_UNUSED_ARG (address_family); +#endif /* !ACE_HAS_IPV6 */ + addr = ACE_INET_Addr ((u_short)0, ip_addr); +#if defined (ACE_HAS_IPV6) + else if (ip_addr != INADDR_ANY) + // address_family == PF_INET6 and a non default IP address means to bind + // to the IPv4-mapped IPv6 address + addr.set ((u_short)0, ip_addr, 1, 1); +#endif /* ACE_HAS_IPV6 */ + + // The OS kernel should select a free port for us. + return ACE_OS::bind (handle, + (sockaddr*)addr.get_addr(), + addr.get_size()); +} + +int +ACE::get_bcast_addr (ACE_UINT32 &bcast_addr, + const ACE_TCHAR *host_name, + ACE_UINT32 host_addr, + ACE_HANDLE handle) +{ + ACE_TRACE ("ACE::get_bcast_addr"); + +#if defined (ACE_LACKS_GET_BCAST_ADDR) + ACE_UNUSED_ARG (bcast_addr); + ACE_UNUSED_ARG (host_name); + ACE_UNUSED_ARG (host_addr); + ACE_UNUSED_ARG (handle); + ACE_NOTSUP_RETURN (-1); +#elif !defined(ACE_WIN32) && !defined(__INTERIX) + ACE_HANDLE s = handle; + + if (s == ACE_INVALID_HANDLE) + s = ACE_OS::socket (AF_INET, SOCK_STREAM, 0); + + if (s == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_OS::socket")), + -1); + + struct ifconf ifc; + char buf[BUFSIZ]; + + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = buf; + + // Get interface structure and initialize the addresses using UNIX + // techniques + if (ACE_OS::ioctl (s, SIOCGIFCONF_CMD, (char *) &ifc) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_bcast_addr:") + ACE_TEXT ("ioctl (get interface configuration)")), + -1); + + struct ifreq *ifr = ifc.ifc_req; + + struct sockaddr_in ip_addr; + + // Get host ip address if necessary. + if (host_name) + { + hostent *hp = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name)); + + if (hp == 0) + return -1; + else +#if !defined(_UNICOS) + ACE_OS::memcpy ((char *) &ip_addr.sin_addr.s_addr, + (char *) hp->h_addr, + hp->h_length); +#else /* _UNICOS */ + { + ACE_UINT64 haddr; // a place to put the address + char * haddrp = (char *) &haddr; // convert to char pointer + ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length); + ip_addr.sin_addr.s_addr = haddr; + } +#endif /* ! _UNICOS */ + } + else + { + ACE_OS::memset ((void *) &ip_addr, 0, sizeof ip_addr); +#if !defined(_UNICOS) + ACE_OS::memcpy ((void *) &ip_addr.sin_addr, + (void*) &host_addr, + sizeof ip_addr.sin_addr); +#else /* _UNICOS */ + ip_addr.sin_addr.s_addr = host_addr; // just copy to the bitfield +#endif /* ! _UNICOS */ + } + +#if !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) + for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0; + n--, ifr++) +#else + // see mk_broadcast@SOCK_Dgram_Bcast.cpp + for (int nbytes = ifc.ifc_len; nbytes >= (int) sizeof (struct ifreq) && + ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ? + (nbytes >= (int) sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len) : 1); + ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ? + (nbytes -= sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len, + ifr = (struct ifreq *) + ((caddr_t) &ifr->ifr_addr + ifr->ifr_addr.sa_len)) : + (nbytes -= sizeof (struct ifreq), ifr++))) +#endif /* !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */ + { + struct sockaddr_in if_addr; + + // Compare host ip address with interface ip address. + ACE_OS::memcpy (&if_addr, + &ifr->ifr_addr, + sizeof if_addr); + + if (ip_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr) + continue; + + if (ifr->ifr_addr.sa_family != AF_INET) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_bcast_addr:") + ACE_TEXT ("Not AF_INET"))); + continue; + } + + struct ifreq flags = *ifr; + struct ifreq if_req = *ifr; + + if (ACE_OS::ioctl (s, SIOCGIFFLAGS, (char *) &flags) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_bcast_addr:") + ACE_TEXT (" ioctl (get interface flags)"))); + continue; + } + + if (ACE_BIT_DISABLED (flags.ifr_flags, IFF_UP)) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_bcast_addr:") + ACE_TEXT ("Network interface is not up"))); + continue; + } + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_LOOPBACK)) + continue; + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_BROADCAST)) + { + if (ACE_OS::ioctl (s, + SIOCGIFBRDADDR, + (char *) &if_req) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_bcast_addr:") + ACE_TEXT ("ioctl (get broadaddr)"))); + else + { + ACE_OS::memcpy (&ip_addr, + &if_req.ifr_broadaddr, + sizeof if_req.ifr_broadaddr); + + ACE_OS::memcpy ((void *) &host_addr, + (void *) &ip_addr.sin_addr, + sizeof host_addr); + + if (handle == ACE_INVALID_HANDLE) + ACE_OS::close (s); + + bcast_addr = host_addr; + return 0; + } + } + else + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_bcast_addr:") + ACE_TEXT ("Broadcast is not enable for this interface."))); + + if (handle == ACE_INVALID_HANDLE) + ACE_OS::close (s); + + bcast_addr = host_addr; + return 0; + } + + return 0; +#else + ACE_UNUSED_ARG (handle); + ACE_UNUSED_ARG (host_addr); + ACE_UNUSED_ARG (host_name); + bcast_addr = (ACE_UINT32 (INADDR_BROADCAST)); + return 0; +#endif /* !ACE_WIN32 && !__INTERIX */ +} + +int +ACE::get_fqdn (ACE_INET_Addr const & addr, + char hostname[], + size_t len) +{ + int h_error; // Not the same as errno! + hostent hentry; + ACE_HOSTENT_DATA buf; + + char * ip_addr = 0; + int ip_addr_size = 0; + if (addr.get_type () == AF_INET) + { + sockaddr_in * const sock_addr = + reinterpret_cast (addr.get_addr ()); + ip_addr_size = sizeof sock_addr->sin_addr; + ip_addr = (char*) &sock_addr->sin_addr; + } +#ifdef ACE_HAS_IPV6 + else + { + sockaddr_in6 * sock_addr = + reinterpret_cast (addr.get_addr ()); + + ip_addr_size = sizeof sock_addr->sin6_addr; + ip_addr = (char*) &sock_addr->sin6_addr; + } +#endif /* ACE_HAS_IPV6 */ + + // get the host entry for the address in question + hostent * const hp = ACE_OS::gethostbyaddr_r (ip_addr, + ip_addr_size, + addr.get_type (), + &hentry, + buf, + &h_error); + + // if it's not found in the host file or the DNS datase, there is nothing + // much we can do. embed the IP address + if (hp == 0 || hp->h_name == 0) + return -1; + + if (ACE::debug()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ") + ACE_TEXT ("canonical host name is %s\n"), + ACE_TEXT_CHAR_TO_TCHAR (hp->h_name))); + + // check if the canonical name is the FQDN + if (!ACE_OS::strchr(hp->h_name, '.')) + { + // list of address + char** p; + // list of aliases + char** q; + + // for every address and for every alias within the address, check and + // see if we can locate a FQDN + for (p = hp->h_addr_list; *p != 0; ++p) + { + for (q = hp->h_aliases; *q != 0; ++q) + { + if (ACE_OS::strchr(*q, '.')) + { + // we got an FQDN from an alias. use this + if (ACE_OS::strlen (*q) >= len) + // the hostname is too huge to fit into a + // buffer of size MAXHOSTNAMELEN + // should we check other aliases as well + // before bailing out prematurely? + // for right now, let's do it. this (short name) + // is atleast better than embedding the IP + // address in the profile + continue; + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ") + ACE_TEXT ("found fqdn within alias as %s\n"), + ACE_TEXT_CHAR_TO_TCHAR(*q))); + ACE_OS::strcpy (hostname, *q); + + return 0; + } + } + } + } + + // The canonical name may be an FQDN when we reach here. + // Alternatively, the canonical name (a non FQDN) may be the best + // we can do. + if (ACE_OS::strlen (hp->h_name) >= len) + { + // The hostname is too large to fit into a buffer of size + // MAXHOSTNAMELEN. + return -2; + } + else + { + ACE_OS::strcpy (hostname, hp->h_name); + } + + return 0; +} + +#if defined (ACE_WIN32) + +static int +get_ip_interfaces_win32 (size_t &count, + ACE_INET_Addr *&addrs) +{ +# if defined (ACE_HAS_WINCE) + // moved the ACE_HAS_WINCE impl ahaid of ACE_HAS_WINSOCK2 because + // WINCE in fact has winsock2, but doesn't properly support the + // WSAIoctl for obtaining IPv6 address info. + PIP_ADAPTER_ADDRESSES AdapterAddresses = 0; + ULONG OutBufferLength = 0; + ULONG RetVal = 0; + unsigned char *octet_buffer = 0; + + RetVal = + GetAdaptersAddresses(AF_UNSPEC, + 0, + 0, + AdapterAddresses, + &OutBufferLength); + + if (RetVal != ERROR_BUFFER_OVERFLOW) + { + return -1; + } + + ACE_NEW_RETURN (octet_buffer, unsigned char[OutBufferLength],-1); + AdapterAddresses = (IP_ADAPTER_ADDRESSES *)octet_buffer; + + RetVal = + GetAdaptersAddresses(AF_UNSPEC, + 0, + 0, + AdapterAddresses, + &OutBufferLength); + + if (RetVal != NO_ERROR) + { + delete [] octet_buffer; + return -1; + } + + // If successful, output some information from the data we received + PIP_ADAPTER_ADDRESSES AdapterList = AdapterAddresses; + while (AdapterList) + { + if (AdapterList->OperStatus == IfOperStatusUp) + { + if (AdapterList->IfIndex != 0) + ++count; + if (AdapterList->Ipv6IfIndex != 0) + ++count; + } + AdapterList = AdapterList->Next; + } + + AdapterList = AdapterAddresses; + + ACE_NEW_RETURN (addrs, ACE_INET_Addr[count],-1); + count = 0; + for (AdapterList = AdapterAddresses; + AdapterList != 0; + AdapterList = AdapterList->Next) + { + if (AdapterList->OperStatus != IfOperStatusUp) + continue; + + IP_ADAPTER_UNICAST_ADDRESS *uni = 0; + if (AdapterList->IfIndex != 0) + for (uni = AdapterList->FirstUnicastAddress; + uni != 0; + uni = uni->Next) + { + SOCKET_ADDRESS *sa_addr = &uni->Address; + if (sa_addr->lpSockaddr->sa_family == AF_INET) + { + sockaddr_in *sin = (sockaddr_in*)sa_addr->lpSockaddr; + addrs[count].set(sin,sa_addr->iSockaddrLength); + ++count; + break; + } + } + if (AdapterList->Ipv6IfIndex != 0) + { + for (uni = AdapterList->FirstUnicastAddress; + uni != 0; + uni = uni->Next) + { + SOCKET_ADDRESS *sa_addr = &uni->Address; + if (sa_addr->lpSockaddr->sa_family == AF_INET6) + { + sockaddr_in *sin = (sockaddr_in*)sa_addr->lpSockaddr; + addrs[count].set(sin,sa_addr->iSockaddrLength); + ++count; + break; + } + } + } + } + + delete [] octet_buffer; + return 0; + +# elif defined (ACE_HAS_PHARLAP) + // PharLap ETS has its own kernel routines to rummage through the device + // configs and extract the interface info, but only for Pharlap RT. +# if !defined (ACE_HAS_PHARLAP_RT) + ACE_NOTSUP_RETURN (-1); +# endif /* ACE_HAS_PHARLAP_RT */ + + // Locate all of the IP devices in the system, saving a DEVHANDLE + // for each. Then allocate the ACE_INET_Addrs needed and fetch all + // the IP addresses. To locate the devices, try the available + // device name roots and increment the device number until the + // kernel says there are no more of that type. + const size_t ACE_MAX_ETS_DEVICES = 64; // Arbitrary, but should be enough. + DEVHANDLE ip_dev[ACE_MAX_ETS_DEVICES]; + EK_TCPIPCFG *devp; + size_t i, j; + ACE_TCHAR dev_name[16]; + + count = 0; + for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count) + { + // Ethernet. + ACE_OS::sprintf (dev_name, + "ether%d", + i); + ip_dev[count] = EtsTCPGetDeviceHandle (dev_name); + if (ip_dev[count] == 0) + break; + } + for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count) + { + // SLIP. + ACE_OS::sprintf (dev_name, + "sl%d", + i); + ip_dev[count] = EtsTCPGetDeviceHandle (dev_name); + if (ip_dev[count] == 0) + break; + } + for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count) + { + // PPP. + ACE_OS::sprintf (dev_name, + "ppp%d", + i); + ip_dev[count] = EtsTCPGetDeviceHandle (dev_name); + if (ip_dev[count] == 0) + break; + } + + if (count > 0) + ACE_NEW_RETURN (addrs, + ACE_INET_Addr[count], + -1); + else + addrs = 0; + + for (i = 0, j = 0; i < count; i++) + { + devp = EtsTCPGetDeviceCfg (ip_dev[i]); + if (devp != 0) + { + addrs[j].set (0, + devp->nwIPAddress, + 0); // Already in net order. + ++j; + } + // There's no call to close the DEVHANDLE. + } + + count = j; + if (count == 0 && addrs != 0) + { + delete [] addrs; + addrs = 0; + } + + return 0; + + +# else + // All non-CE, non-Pharlap Windows. Must support Winsock2. + + int i, n_interfaces, status; + + INTERFACE_INFO info[64]; + SOCKET sock; + + // Get an (overlapped) DGRAM socket to test with + sock = socket (AF_INET, SOCK_DGRAM, 0); + if (sock == INVALID_SOCKET) + return -1; + + DWORD bytes; + status = WSAIoctl(sock, + SIO_GET_INTERFACE_LIST, + 0, + 0, + info, + sizeof(info), + &bytes, + 0, + 0); + closesocket (sock); + if (status == SOCKET_ERROR) + return -1; + + n_interfaces = bytes / sizeof(INTERFACE_INFO); + + // SIO_GET_INTERFACE_LIST does not work for IPv6 + // Instead recent versions of Winsock2 add the new opcode + // SIO_ADDRESS_LIST_QUERY. + // If this is not available forget about IPv6 local interfaces:-/ + int n_v6_interfaces = 0; + +# if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY) + + LPSOCKET_ADDRESS_LIST v6info; + char *buffer; + DWORD buflen = sizeof (SOCKET_ADDRESS_LIST) + (63 * sizeof (SOCKET_ADDRESS)); + ACE_NEW_RETURN (buffer, + char[buflen], + -1); + v6info = reinterpret_cast (buffer); + + // Get an (overlapped) DGRAM socket to test with. + // If it fails only return IPv4 interfaces. + sock = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (sock != INVALID_SOCKET) + { + status = WSAIoctl(sock, + SIO_ADDRESS_LIST_QUERY, + 0, + 0, + v6info, + buflen, + &bytes, + 0, + 0); + closesocket (sock); + if (status != SOCKET_ERROR) + n_v6_interfaces = v6info->iAddressCount; + } +# endif /* ACE_HAS_IPV6 */ + + ACE_NEW_RETURN (addrs, + ACE_INET_Addr[n_interfaces + n_v6_interfaces], + -1); + + // Now go through the list and transfer the good ones to the list of + // because they're down or don't have an IP address. + for (count = 0, i = 0; i < n_interfaces; ++i) + { + LPINTERFACE_INFO lpii; + struct sockaddr_in *addrp = 0; + + lpii = &info[i]; + if (!(lpii->iiFlags & IFF_UP)) + continue; + + // We assume IPv4 addresses here + addrp = reinterpret_cast (&lpii->iiAddress.AddressIn); + if (addrp->sin_addr.s_addr == INADDR_ANY) + continue; + + // Set the address for the caller. + addrs[count].set(addrp, sizeof(sockaddr_in)); + ++count; + } + +# if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY) + // Now go through the list and transfer the good ones to the list of + // because they're down or don't have an IP address. + for (i = 0; i < n_v6_interfaces; i++) + { + struct sockaddr_in6 *addr6p; + + if (v6info->Address[i].lpSockaddr->sa_family != AF_INET6) + continue; + + addr6p = reinterpret_cast (v6info->Address[i].lpSockaddr); + if (IN6_IS_ADDR_UNSPECIFIED(&addr6p->sin6_addr)) // IN6ADDR_ANY? + continue; + + // Set the address for the caller. + addrs[count].set(reinterpret_cast (addr6p), sizeof(sockaddr_in6)); + ++count; + } + + delete [] buffer; // Clean up +# endif /* ACE_HAS_IPV6 */ + + if (count == 0) + { + delete [] addrs; + addrs = 0; + } + + return 0; + +# endif /* ACE_HAS_WINCE */ +} +#elif defined (ACE_HAS_GETIFADDRS) +static int +get_ip_interfaces_getifaddrs (size_t &count, + ACE_INET_Addr *&addrs) +{ + // Take advantage of the BSD getifaddrs function that simplifies + // access to connected interfaces. + struct ifaddrs *ifap = 0; + struct ifaddrs *p_if = 0; + + if (::getifaddrs (&ifap) != 0) + return -1; + + // Count number of interfaces. + size_t num_ifs = 0; + for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next) + ++num_ifs; + + // Now create and initialize output array. + ACE_NEW_RETURN (addrs, + ACE_INET_Addr[num_ifs], + -1); // caller must free + + // Pull the address out of each INET interface. Not every interface + // is for IP, so be careful to count properly. When setting the + // INET_Addr, note that the 3rd arg (0) says to leave the byte order + // (already in net byte order from the interface structure) as is. + count = 0; + + for (p_if = ifap; + p_if != 0; + p_if = p_if->ifa_next) + { + if (p_if->ifa_addr && + p_if->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in *addr = + reinterpret_cast (p_if->ifa_addr); + + // Sometimes the kernel returns 0.0.0.0 as the interface + // address, skip those... + if (addr->sin_addr.s_addr != INADDR_ANY) + { + addrs[count].set ((u_short) 0, + addr->sin_addr.s_addr, + 0); + ++count; + } + } +# if defined (ACE_HAS_IPV6) + else if (p_if->ifa_addr && + p_if->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6 *addr = + reinterpret_cast (p_if->ifa_addr); + + // Skip the ANY address + if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr)) + { + addrs[count].set(reinterpret_cast (addr), + sizeof(sockaddr_in6)); + ++count; + } + } +# endif /* ACE_HAS_IPV6 */ + } + + ::freeifaddrs (ifap); + + return 0; +} +#elif defined (__hpux) +static int +get_ip_interfaces_hpux (size_t &count, + ACE_INET_Addr *&addrs) +{ + size_t num_ifs = 0; + size_t num_ifs_found = 0; + + // Call specific routine as necessary. + ACE_HANDLE handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0); + ACE_HANDLE handle_ipv6 = ACE_INVALID_HANDLE; + + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_ip_interfaces:open")), + -1); + + int result = 0; + int tmp_how_many = 0; + + result = ACE_OS::ioctl (handle, + SIOCGIFNUM, + (caddr_t) &tmp_how_many); + if (result != -1) + num_ifs = (size_t)tmp_how_many; + +# if defined (ACE_HAS_IPV6) + tmp_how_many = 0; + handle_ipv6 = ACE_OS::socket (PF_INET6, SOCK_DGRAM, 0); + result = ACE_OS::ioctl (handle_ipv6, + SIOCGLIFNUM, + (caddr_t) &tmp_how_many); + if (result != -1) + num_ifs += (size_t)tmp_how_many; +# endif + + if (num_ifs == 0) + { + ACE_OS::close (handle); + ACE_OS::close (handle_ipv6); + return -1; + } + + // ioctl likes to have an extra IFREQ structure to mark the end of + // what it returned, so increase the num_ifs by one. + ++num_ifs; + + //HPUX requires two passes, First for IPv4, then for IPv6 + + struct ifreq *ifs = 0; + ACE_NEW_RETURN (ifs, + struct ifreq[num_ifs], + -1); + ACE_OS::memset (ifs, 0, num_ifs * sizeof (struct ifreq)); + + ACE_Auto_Array_Ptr p_ifs (ifs); + + if (p_ifs.get() == 0) + { + ACE_OS::close (handle); + ACE_OS::close (handle_ipv6); + errno = ENOMEM; + return -1; + } + + struct ifconf ifcfg; + ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf)); + + ifcfg.ifc_req = p_ifs.get (); + ifcfg.ifc_len = num_ifs * sizeof (struct ifreq); + + if (ACE_OS::ioctl (handle, + SIOCGIFCONF, + (char *) &ifcfg) == -1) + { + ACE_OS::close (handle); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_ip_interfaces:") + ACE_TEXT ("ioctl - SIOCGIFCONF failed")), + -1); + } + + ACE_OS::close (handle); + + // Now create and initialize output array. + + ACE_NEW_RETURN (addrs, + ACE_INET_Addr[num_ifs], + -1); // caller must free + + struct ifreq *pcur = p_ifs.get (); + num_ifs_found = ifcfg.ifc_len / sizeof (struct ifreq); // get the number of returned ifs + + for (size_t i = 0; + i < num_ifs_found; + i++) + { + struct sockaddr_in *addr = + reinterpret_cast (&pcur->ifr_addr); + if (addr->sin_addr.s_addr != 0) + { + addrs[count].set ((u_short) 0, + addr->sin_addr.s_addr, + 0); + ++count; + } + ++pcur; + } + +# if defined (ACE_HAS_IPV6) + + if (handle_ipv6 != ACE_INVALID_HANDLE) + { + struct if_laddrreq *lifs = 0; + ACE_NEW_RETURN (lifs, + struct if_laddrreq[num_ifs], + -1); + ACE_OS::memset (lifs, 0, num_ifs * sizeof (struct if_laddrreq)); + + ACE_Auto_Array_Ptr p_lifs (lifs); + + if (p_lifs.get() == 0) + { + ACE_OS::close (handle); + ACE_OS::close (handle_ipv6); + errno = ENOMEM; + return -1; + } + + struct if_laddrconf lifcfg; + ACE_OS::memset (&lifcfg, 0, sizeof (struct if_laddrconf)); + + lifcfg.iflc_req = p_lifs.get (); + lifcfg.iflc_len = num_ifs * sizeof (struct if_laddrreq); + + if (ACE_OS::ioctl (handle_ipv6, + SIOCGLIFCONF, + (char *) &lifcfg) == -1) + { + ACE_OS::close (handle); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_ip_interfaces:") + ACE_TEXT ("ioctl - SIOCGLIFCONF failed")), + -1); + } + + ACE_OS::close (handle_ipv6); + + struct if_laddrreq *plcur = p_lifs.get (); + num_ifs_found = lifcfg.iflc_len / sizeof (struct if_laddrreq); + + for (size_t i = 0; + i < num_ifs_found; + i++) + { + struct sockaddr_in *addr = + reinterpret_cast (&plcur->iflr_addr); + if (!IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast(addr)->sin6_addr)) + { + addrs[count].set(addr, sizeof(struct sockaddr_in6)); + ++count; + } + ++plcur; + } + } +# endif /* ACE_HAS_IPV6 */ + return 0; +} +#elif defined (_AIX) +static int +get_ip_interfaces_aix (size_t &count, + ACE_INET_Addr *&addrs) +{ + ACE_HANDLE handle = ACE::get_handle(); + size_t num_ifs = 0; + struct ifconf ifc; + + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_ip_interfaces_aix:")), + -1); + + if (ACE_OS::ioctl (handle, + SIOCGSIZIFCONF, + (caddr_t)&ifc.ifc_len) == -1) + { + ACE_OS::close (handle); + ACE_ERROR_RETURN((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("get ifconf size")), + -1); + } + + ACE_NEW_RETURN (ifc.ifc_buf,char [ifc.ifc_len], -1); + + ACE_Auto_Array_Ptr safe_buf (ifc.ifc_buf); + ACE_OS::memset (safe_buf.get(), 0, ifc.ifc_len); + + if (ACE_OS::ioctl(handle, SIOCGIFCONF, (caddr_t)&ifc) == -1) + { + ACE_OS::close (handle); + ACE_ERROR_RETURN((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("get ifconf")), + -1); + } + + ACE_OS::close (handle); + + char *buf_start = safe_buf.get(); + char *buf_end = buf_start + ifc.ifc_len; + + num_ifs = 0; + for (char *ptr = buf_start; ptr < buf_end; ) + { + struct ifreq *req = reinterpret_cast(ptr); + ptr += IFNAMSIZ; + ptr += req->ifr_addr.sa_len; + if (req->ifr_addr.sa_family == AF_INET +# if defined (ACE_HAS_IPV6) + || req->ifr_addr.sa_family == AF_INET6 +# endif + ) + ++num_ifs; + } + ACE_NEW_RETURN (addrs,ACE_INET_Addr[num_ifs], -1); + + for (char * ptr = buf_start; ptr < buf_end; ) + { + struct ifreq *req = reinterpret_cast(ptr); + // skip the interface name + ptr += IFNAMSIZ; + if (req->ifr_addr.sa_family == AF_INET +# if defined (ACE_HAS_IPV6) + || req->ifr_addr.sa_family == AF_INET6 +# endif + ) + { + sockaddr_in *addr = (sockaddr_in*)&req->ifr_addr; + addrs[count++].set(addr, addr->sin_len); + } + ptr += req->ifr_addr.sa_len; + } + + return 0; +} + +#elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) && !defined (ACE_HAS_VXWORKS551_MEDUSA) +int +get_ip_interfaces_vxworks_lt600 (size_t &count, + ACE_INET_Addr *&addrs) +{ + count = 0; + // Loop through each address structure + +# if defined (ACE_HAS_IPV6) && defined (TAILQ_ENTRY) +# define ia_next ia_link.tqe_next +# endif /* TAILQ_ENTRY */ + + for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next) + { + ++count; + } + + // Now create and initialize output array. + ACE_NEW_RETURN (addrs, + ACE_INET_Addr[count], + -1); // caller must free + count = 0; + for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next) + { + struct ifnet* ifp = ia->ia_ifa.ifa_ifp; + if (ifp != 0) + { + // Get the current interface name + char interface[64]; + ACE_OS::sprintf(interface, "%s%d", ifp->if_name, ifp->if_unit); + + // Get the address for the current interface + char address [INET_ADDR_LEN]; + STATUS status = ifAddrGet(interface, address); + + if (status == OK) + { + // Concatenate a ':' at the end. This is because in + // ACE_INET_Addr::string_to_addr, the ip_address is + // obtained using ':' as the delimiter. Since, using + // ifAddrGet(), we just get the IP address, I am adding + // a ":" to get with the general case. + ACE_OS::strcat (address, ":"); + addrs[count].set (address); + } + else + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE::get_ip_interface failed\n") + ACE_TEXT ("Couldnt get the IP Address\n")), + -1); + } + ++count; + } + } + return 0; +} +#endif // ACE_WIN32 || ACE_HAS_GETIFADDRS || __hpux || _AIX || ACE_VXWORKS < 0x600 + + +// return an array of all configured IP interfaces on this host, count +// rc = 0 on success (count == number of interfaces else -1 caller is +// responsible for calling delete [] on parray + +int +ACE::get_ip_interfaces (size_t &count, + ACE_INET_Addr *&addrs) +{ + ACE_TRACE ("ACE::get_ip_interfaces"); + + count = 0; + addrs = 0; + +#if defined (ACE_WIN32) + return get_ip_interfaces_win32 (count, addrs); +#elif defined (ACE_HAS_GETIFADDRS) + return get_ip_interfaces_getifaddrs (count, addrs); +#elif defined (__hpux) + return get_ip_interfaces_hpux (count, addrs); +#elif defined (_AIX) + return get_ip_interfaces_aix (count, addrs); +#elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) && !defined (ACE_HAS_VXWORKS551_MEDUSA) + return get_ip_interfaces_vxworks_lt600 (count, addrs); +#elif (defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (ACE_OPENVMS) || (defined (ACE_VXWORKS) && (ACE_VXWORKS == 0x650)) || defined (ACE_HAS_RTEMS)) && !defined (ACE_LACKS_NETWORKING) + // COMMON (SVR4 and BSD) UNIX CODE + + // Call specific routine as necessary. + ACE_HANDLE handle = ACE::get_handle(); + + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_ip_interfaces:open")), + -1); + + size_t num_ifs, num_ifs_found; + + if (ACE::count_interfaces (handle, num_ifs)) + { + ACE_OS::close (handle); + return -1; + } + + // ioctl likes to have an extra ifreq structure to mark the end of + // what it returned, so increase the num_ifs by one. + ++num_ifs; + + struct IFREQ *ifs = 0; + ACE_NEW_RETURN (ifs, + struct IFREQ[num_ifs], + -1); + ACE_OS::memset (ifs, 0, num_ifs * sizeof (struct IFREQ)); + + ACE_Auto_Array_Ptr p_ifs (ifs); + + if (p_ifs.get() == 0) + { + ACE_OS::close (handle); + errno = ENOMEM; + return -1; + } + + struct IFCONF ifcfg; + ACE_OS::memset (&ifcfg, 0, sizeof (struct IFCONF)); + +# ifdef SETFAMILY + ifcfg.IFC_FAMILY = AF_UNSPEC; // request all families be returned + ifcfg.IFC_FLAGS = 0; +# endif + + ifcfg.IFC_REQ = p_ifs.get (); + ifcfg.IFC_LEN = num_ifs * sizeof (struct IFREQ); + + if (ACE_OS::ioctl (handle, + SIOCGIFCONF_CMD, + (caddr_t) &ifcfg) == -1) + { + ACE_OS::close (handle); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::get_ip_interfaces:") + ACE_TEXT ("ioctl - SIOCGIFCONF failed")), + -1); + } + + ACE_OS::close (handle); + + // Now create and initialize output array. + + ACE_NEW_RETURN (addrs, + ACE_INET_Addr[num_ifs], + -1); // caller must free + + struct IFREQ *pcur = p_ifs.get (); + num_ifs_found = ifcfg.IFC_LEN / sizeof (struct IFREQ); // get the number of returned ifs + + // Pull the address out of each INET interface. Not every interface + // is for IP, so be careful to count properly. When setting the + // INET_Addr, note that the 3rd arg (0) says to leave the byte order + // (already in net byte order from the interface structure) as is. + count = 0; + + for (size_t i = 0; + i < num_ifs_found; + i++) + { + if (pcur->IFR_ADDR.SA_FAMILY == AF_INET +# if defined (ACE_HAS_IPV6) + || pcur->IFR_ADDR.SA_FAMILY == AF_INET6 +# endif + ) + + { +# if !defined(_UNICOS) + struct sockaddr_in *addr = + reinterpret_cast (&pcur->IFR_ADDR); + + // Sometimes the kernel returns 0.0.0.0 as an IPv4 interface + // address; skip those... + if (addr->sin_addr.s_addr != 0 +# if defined (ACE_HAS_IPV6) + || (addr->sin_family == AF_INET6 && + !IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast(addr)->sin6_addr)) +# endif + ) + { + int addrlen = static_cast (sizeof (struct sockaddr_in)); +# if defined (ACE_HAS_IPV6) + if (addr->sin_family == AF_INET6) + addrlen = static_cast (sizeof (struct sockaddr_in6)); +# endif + addrs[count].set (addr, addrlen); + ++count; + } +# else /* ! _UNICOS */ + // need to explicitly copy on the Cray, since the bitfields kinda + // screw things up here + struct sockaddr_in inAddr; + + inAddr.sin_len = pcur->IFR_ADDR.sa_len; + inAddr.sin_family = pcur->IFR_ADDR.sa_family; + memcpy((void *)&(inAddr.sin_addr), + (const void *)&(pcur->IFR_ADDR.sa_data[8]), + sizeof(struct in_addr)); + + if (inAddr.sin_addr.s_addr != 0) + { + addrs[count].set(&inAddr, sizeof(struct sockaddr_in)); + ++count; + } +# endif /* ! _UNICOS */ + } + +#if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) + ++pcur; +#else + if (pcur->ifr_addr.sa_len <= sizeof (struct sockaddr)) + { + ++pcur; + } + else + { + pcur = (struct ifreq *) + (pcur->ifr_addr.sa_len + (caddr_t) &pcur->ifr_addr); + } +#endif /* !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */ + } + +# if defined (ACE_HAS_IPV6) + // Retrieve IPv6 local interfaces by scanning /proc/net/if_inet6 if + // it exists. If we cannot open it then ignore possible IPv6 + // interfaces, we did our best;-) + FILE* fp; + char addr_p[8][5]; + char s_ipaddr[64]; + int scopeid; + struct addrinfo hints, *res0; + int error; + + ACE_OS::memset (&hints, 0, sizeof (hints)); + hints.ai_flags = AI_NUMERICHOST; + hints.ai_family = AF_INET6; + + if ((fp = ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0) + { + while (fscanf (fp, + "%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*8s\n", + addr_p[0], addr_p[1], addr_p[2], addr_p[3], + addr_p[4], addr_p[5], addr_p[6], addr_p[7], &scopeid) != EOF) + { + // Format the address intoa proper IPv6 decimal address specification and + // resolve the resulting text using getaddrinfo(). + + const char* ip_fmt = "%s:%s:%s:%s:%s:%s:%s:%s%%%d"; + ACE_OS::sprintf (s_ipaddr, + ip_fmt, + addr_p[0], addr_p[1], addr_p[2], addr_p[3], + addr_p[4], addr_p[5], addr_p[6], addr_p[7], scopeid); + + error = getaddrinfo (s_ipaddr, 0, &hints, &res0); + if (error) + continue; + + if (res0->ai_family == AF_INET6 && + !IN6_IS_ADDR_UNSPECIFIED (&reinterpret_cast (res0->ai_addr)->sin6_addr)) + { + addrs[count].set(reinterpret_cast (res0->ai_addr), res0->ai_addrlen); + ++count; + } + freeaddrinfo (res0); + + } + ACE_OS::fclose (fp); + } +# endif /* ACE_HAS_IPV6 */ + + return 0; +#else + ACE_UNUSED_ARG (count); + ACE_UNUSED_ARG (addrs); + ACE_NOTSUP_RETURN (-1); // no implementation +#endif /* ACE_WIN32 */ +} + +// Helper routine for get_ip_interfaces, differs by UNIX platform so +// put into own subroutine. perform some ioctls to retrieve ifconf +// list of ifreq structs. + +int +ACE::count_interfaces (ACE_HANDLE handle, + size_t &how_many) +{ +#if defined (ACE_WIN32) || defined (ACE_HAS_GETIFADDRS) || defined (__hpux) || defined (_AIX) || (defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600)) + // none of these platforms make use of count_interfaces + ACE_UNUSED_ARG (handle); + ACE_UNUSED_ARG (how_many); + ACE_NOTSUP_RETURN (-1); // no implementation + +#elif defined (SIOCGIFNUM) +# if defined (SIOCGLIFNUM) + int cmd = SIOCGLIFNUM; + struct lifnum if_num = {AF_UNSPEC,0,0}; +# else + int cmd = SIOCGIFNUM; + int if_num = 0; +# endif /* SIOCGLIFNUM */ + if (ACE_OS::ioctl (handle, cmd, (caddr_t)&if_num) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::count_interfaces:") + ACE_TEXT ("ioctl - SIOCGLIFNUM failed")), + -1); +# if defined (SIOCGLIFNUM) + how_many = if_num.lifn_count; +# else + how_many = if_num; +# endif /* SIOCGLIFNUM */ +return 0; + +#elif (defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS)) && !defined (ACE_LACKS_NETWORKING) + // Note: DEC CXX doesn't define "unix". BSD compatible OS: HP UX, + // AIX, SunOS 4.x perform some ioctls to retrieve ifconf list of + // ifreq structs no SIOCGIFNUM on SunOS 4.x, so use guess and scan + // algorithm + + // Probably hard to put this many ifs in a unix box.. + const int MAX_IF = 50; + + // HACK - set to an unreasonable number + int num_ifs = MAX_IF; + + struct ifconf ifcfg; + size_t ifreq_size = num_ifs * sizeof (struct ifreq); + struct ifreq *p_ifs = + (struct ifreq *) ACE_OS::malloc (ifreq_size); + + if (!p_ifs) + { + errno = ENOMEM; + return -1; + } + + ACE_OS::memset (p_ifs, 0, ifreq_size); + ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf)); + + ifcfg.ifc_req = p_ifs; + ifcfg.ifc_len = ifreq_size; + + if (ACE_OS::ioctl (handle, + SIOCGIFCONF_CMD, + (caddr_t) &ifcfg) == -1) + { + ACE_OS::free (ifcfg.ifc_req); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::count_interfaces:") + ACE_TEXT ("ioctl - SIOCGIFCONF failed")), + -1); + } + + int if_count = 0, i; + + // get if address out of ifreq buffers. ioctl puts a blank-named + // interface to mark the end of the returned interfaces. + for (i = 0; + i < num_ifs; + i++) + { + /* In OpenBSD, the length of the list is returned. */ + ifcfg.ifc_len -= sizeof (struct ifreq); + if (ifcfg.ifc_len < 0) + break; + + ++if_count; +#if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) + ++p_ifs; +#else + if (p_ifs->ifr_addr.sa_len <= sizeof (struct sockaddr)) + { + ++p_ifs; + } + else + { + p_ifs = (struct ifreq *) + (p_ifs->ifr_addr.sa_len + (caddr_t) &p_ifs->ifr_addr); + } +#endif /* !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */ + } + + ACE_OS::free (ifcfg.ifc_req); + +# if defined (ACE_HAS_IPV6) + FILE* fp = 0; + + if ((fp = ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0) + { + // Scan the lines according to the expected format but don't really read any input + while (fscanf (fp, "%*32s %*02x %*02x %*02x %*02x %*8s\n") != EOF) + { + ++if_count; + } + ACE_OS::fclose (fp); + } +# endif /* ACE_HAS_IPV6 */ + + how_many = if_count; + return 0; +#else + ACE_UNUSED_ARG (handle); + ACE_UNUSED_ARG (how_many); + ACE_NOTSUP_RETURN (-1); // no implementation +#endif /* sparc && SIOCGIFNUM */ +} + +// Routine to return a handle from which ioctl() requests can be made. + +ACE_HANDLE +ACE::get_handle (void) +{ + // Solaris 2.x + ACE_HANDLE handle = ACE_INVALID_HANDLE; +#if defined (sparc) + handle = ACE_OS::open ("/dev/udp", O_RDONLY); +#elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX) || defined (__hpux) || (defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600)) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS) + // Note: DEC CXX doesn't define "unix" BSD compatible OS: HP UX, + // AIX, SunOS 4.x + + handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0); +#endif /* sparc */ + return handle; +} + + +#if defined (ACE_HAS_IPV6) +static int +ip_check (int &ipvn_enabled, int pf) +{ + // We only get to this point if ipvn_enabled was -1 in the caller. + // Perform Double-Checked Locking Optimization. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + + if (ipvn_enabled == -1) + { + // Determine if the kernel has IPv6 support by attempting to + // create a PF_INET socket and see if it fails. + ACE_HANDLE const s = ACE_OS::socket (pf, SOCK_DGRAM, 0); + if (s == ACE_INVALID_HANDLE) + { + ipvn_enabled = 0; + } + else + { + ipvn_enabled = 1; + ACE_OS::closesocket (s); + } + } + return ipvn_enabled; +} +#endif /* ACE_HAS_IPV6 */ + +bool +ACE::ipv4_enabled (void) +{ +#if defined (ACE_HAS_IPV6) + return static_cast (ace_ipv4_enabled == -1 ? + ::ip_check (ace_ipv4_enabled, PF_INET) : + ace_ipv4_enabled); +#else + // Assume it's always enabled since ACE requires some version of + // TCP/IP to exist. + return true; +#endif /* ACE_HAS_IPV6*/ +} + +int +ACE::ipv6_enabled (void) +{ +#if defined (ACE_HAS_IPV6) + return ace_ipv6_enabled == -1 ? + ::ip_check (ace_ipv6_enabled, PF_INET6) : + ace_ipv6_enabled; +#else /* ACE_HAS_IPV6 */ + return 0; +#endif /* !ACE_HAS_IPV6 */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Sock_Connect.h b/dep/ACE_wrappers/ace/Sock_Connect.h new file mode 100644 index 000000000..d6a72c718 --- /dev/null +++ b/dep/ACE_wrappers/ace/Sock_Connect.h @@ -0,0 +1,107 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Sock_Connect.h + * + * $Id: Sock_Connect.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Priyanka Gontla + * @author Based on code that existed formerly in ACE.h. + */ +//========================================================================== + +#ifndef ACE_SOCK_CONNECT_H +#define ACE_SOCK_CONNECT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Basic_Types.h" +#include "ace/os_include/netinet/os_in.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward Declarations +class ACE_INET_Addr; + +namespace ACE +{ + // = Socket connection establishment calls. + + /// Bind a new unused port to @a handle. + extern ACE_Export int bind_port (ACE_HANDLE handle, + ACE_UINT32 ip_addr = INADDR_ANY, + int address_family = AF_UNSPEC); + + /** + * Get our broadcast address based on our @a host_addr. If + * @a hostname is non-0 we'll use it to determine our IP address. If + * @a handle is not ACE_INVALID_HANDLE then we'll use this to + * determine our broadcast address, otherwise we'll have to create a + * socket internally (and free it). Returns -1 on failure and 0 on + * success. + */ + extern ACE_Export int get_bcast_addr ( + ACE_UINT32 &bcast_addr, + const ACE_TCHAR *hostname = 0, + ACE_UINT32 host_addr = 0, + ACE_HANDLE handle = ACE_INVALID_HANDLE); + + /// Get fully qualified host/domain name. + extern ACE_Export int get_fqdn (ACE_INET_Addr const & addr, + char hostname[], + size_t len); + + /** + * Return count and array of all configured IP interfaces on this + * host, rc = 0 on success (count == number of interfaces else -1). + * Caller is responsible for calling delete [] on @a addr_array. + */ + extern ACE_Export int get_ip_interfaces (size_t &count, + ACE_INET_Addr *&addr_array); + + /** + * Helper routine for get_ip_interfaces, differs by UNIX platform so + * put into own subroutine. perform some ioctls to retrieve ifconf + * list of ifreq structs. + */ + extern ACE_Export int count_interfaces (ACE_HANDLE handle, + size_t &how_many); + + /// Routine to return a handle from which @c ioctl requests can be + /// made. Caller must close the handle. + extern ACE_Export ACE_HANDLE get_handle (void); + + /// Returns @c true if IPv4 is enabled on the current host; @c false + /// if not. + /** + * This is an execution-time check. If ACE has not been compiled + * with @c ACE_HAS_IPV6, it always returns @c true. This function + * tries to create a @c PF_INET socket, returning @c true if it + * succeeds, and @c false if it fails. Caches the result so it only + gets checked once. + */ + extern ACE_Export bool ipv4_enabled (void); + + /** + * Returns 1 if IPv6 is enabled on the current host; 0 if not. + * This is an execution-time check. If ACE has not been compiled + * with ACE_HAS_IPV6, it always returns 0. If ACE_HAS_IPV6 is + * enabled, this function tries to create a PF_INET6 socket, + * returning 1 if it succeeds, and 0 if it fails. Caches the result + * so it only gets checked once. + */ + extern ACE_Export int ipv6_enabled (void); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_SOCK_CONNECT_H */ diff --git a/dep/ACE_wrappers/ace/Stack_Trace.cpp b/dep/ACE_wrappers/ace/Stack_Trace.cpp new file mode 100644 index 000000000..082cca8a8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Stack_Trace.cpp @@ -0,0 +1,696 @@ +//============================================================================= +/** + * @file Stack_Trace.cpp + * + * $Id: Stack_Trace.cpp 82575 2008-08-08 20:36:10Z mitza $ + * + * @brief Encapsulate string representation of stack trace. + * + * Portions of the platform-specific code have been based on + * code found in various places on the internet e.g., google groups, + * VxWorks FAQ, etc., and adapted for use here. + */ +//============================================================================= + +#include "ace/Stack_Trace.h" +#include "ace/Min_Max.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (ace, Stack_Trace, "$Id: Stack_Trace.cpp 82575 2008-08-08 20:36:10Z mitza $") + +/* + This is ugly, simply because it's very platform-specific. +*/ + +const char ACE_Stack_Trace::UNSUPPORTED[] = ""; +const char ACE_Stack_Trace::UNABLE_TO_GET_TRACE[] = ""; + +ACE_Stack_Trace::ACE_Stack_Trace (ssize_t starting_frame_offset, size_t num_frames) + : buflen_(0) +{ + // cannot initialize arrays, so we must assign. + this->buf_[0] = '\0'; + this->generate_trace (starting_frame_offset, num_frames); +} + +const char* +ACE_Stack_Trace::c_str () const +{ + return &this->buf_[0]; +} + +static inline size_t +determine_starting_frame (ssize_t initial_frame, ssize_t offset) +{ + return ACE_MAX( initial_frame + offset, static_cast(0)); +} + +#if (defined(__GLIBC__) || defined(ACE_HAS_EXECINFO_H)) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) +// This is the code for glibc +# include + +void +ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset, size_t num_frames) +{ + const size_t MAX_FRAMES = 128; + const ssize_t INITIAL_FRAME = 3; + + void* stack[MAX_FRAMES]; + size_t stack_size = 0; + char** stack_syms; + + if (num_frames == 0) + num_frames = MAX_FRAMES; + + size_t starting_frame = + determine_starting_frame (INITIAL_FRAME, starting_frame_offset); + + stack_size = ::backtrace (&stack[0], sizeof(stack)/sizeof(stack[0])); + if (stack_size != 0) + { + stack_syms = ::backtrace_symbols (stack, stack_size); + + for (size_t i = starting_frame; + i < stack_size && num_frames > 0; + i++, num_frames--) + { + // this could be more efficient by remembering where we left off in buf_ + char *symp = &stack_syms[i][0]; + while (this->buflen_ < SYMBUFSIZ && *symp != '\0') + { + this->buf_[this->buflen_++] = *symp++; + } + this->buf_[this->buflen_++] = '\n'; // put a newline at the end + } + this->buf_[this->buflen_+1] = '\0'; // zero terminate the string + + ::free (stack_syms); + } + else + { + ACE_OS::strcpy (&this->buf_[0], UNABLE_TO_GET_TRACE); + } +} +#elif defined(VXWORKS) && !defined(__RTP__) +# include +# include // hopefully this is enough to get all the necessary #defines. + +struct ACE_Stack_Trace_stackstate +{ + ACE_Stack_Trace_stackstate (char* b, size_t& bl, size_t nf, size_t sf) + : buf(b), buflen(bl), num_frames(nf), starting_frame(sf) + { } + + char* buf; + size_t& buflen; + size_t num_frames; + size_t starting_frame; +}; + +//@TODO: Replace with a TSS-based pointer to avoid problems in multithreaded environs, +// or use a mutex to serialize access to this. +static ACE_Stack_Trace_stackstate* ACE_Stack_Trace_stateptr = 0; + +static void +ACE_Stack_Trace_Add_Frame_To_Buf (INSTR *caller, + unsigned int func, + unsigned int nargs, + unsigned int *args) +{ + if (ACE_Stack_Trace_stateptr == 0) + return; + + ACE_Stack_Trace_stackstate *stackstate = ACE_Stack_Trace_stateptr; + + // Decrement the num_frames and starting_frame elements, + // then see if we're ready to start or ready to finish. + --stackstate->num_frames; + --stackstate->starting_frame; + + if (stackstate->num_frames == 0 || stackstate->starting_frame > 0) + return; + + // These are references so that the structure gets updated + // in the code below. + char*& buf = stackstate->buf; + unsigned int& len = stackstate->buflen; + + // At some point try using symFindByValue() to lookup func (and caller?) + // to print out symbols rather than simply addresses. + + // VxWorks can pass -1 for "nargs" if there was an error + if (nargs == static_cast (-1)) nargs = 0; + + len += ACE_OS::sprintf (&buf[len], "%#10x: %#10x (", (int)caller, func); + for (unsigned int i = 0; i < nargs; ++i) + { + if (i != 0) + len += ACE_OS::sprintf (&buf[len], ", "); + len += ACE_OS::sprintf(&buf [len], "%#x", args [i]); + } + + len += ACE_OS::sprintf(&buf[len], ")\n"); +} + +void +ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset, + size_t num_frames) +{ + const size_t MAX_FRAMES = 128; + const ssize_t INITIAL_FRAME = 3; + + if (num_frames == 0) + num_frames = MAX_FRAMES; + + size_t starting_frame = + determine_starting_frame (INITIAL_FRAME, starting_frame_offset); + + ACE_Stack_Trace_stackstate state (&this->buf_[0], this->buflen_, + num_frames, starting_frame); + + REG_SET regs; + + taskRegsGet ((int)taskIdSelf(), ®s); + // Maybe we should take a lock here to guard stateptr? + ACE_Stack_Trace_stateptr = &state; + trcStack (®s, (FUNCPTR)ACE_Stack_Trace_Add_Frame_To_Buf, taskIdSelf ()); +} + + +#elif defined(VXWORKS) && defined(__RTP__) +# include +# include +# include + +// See memEdrLib.c in VxWorks RTP sources for an example of stack tracing. + +static STATUS ace_vx_rtp_pc_validate (INSTR *pc, TRC_OS_CTX *pOsCtx) +{ + return ALIGNED (pc, sizeof (INSTR)) ? OK : ERROR; +} + +void +ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset, + size_t num_frames) +{ + const size_t MAX_FRAMES = 128; + const ssize_t INITIAL_FRAME = 2; + + if (num_frames == 0) num_frames = MAX_FRAMES; + size_t starting_frame = + determine_starting_frame (INITIAL_FRAME, starting_frame_offset); + + jmp_buf regs; + setjmp (regs); + + TASK_DESC desc; + if (taskInfoGet (taskIdSelf (), &desc) == ERROR) return; + + TRC_OS_CTX osCtx; + osCtx.stackBase = desc.td_pStackBase; + osCtx.stackEnd = desc.td_pStackEnd; + osCtx.pcValidateRtn = reinterpret_cast (ace_vx_rtp_pc_validate); + + char *fp = _WRS_FRAMEP_FROM_JMP_BUF (regs); + INSTR *pc = _WRS_RET_PC_FROM_JMP_BUF (regs); + + for (size_t depth = 0; depth < num_frames + starting_frame; ++depth) + { + char *prevFp; + INSTR *prevPc; + INSTR *prevFn; + + if (trcLibFuncs.lvlInfoGet (fp, pc, &osCtx, &prevFp, &prevPc, &prevFn) + == ERROR) + { + ACE_OS::strcpy (this->buf_, UNABLE_TO_GET_TRACE); + return; + } + + if(prevPc == 0 || prevFp == 0) break; + + if (depth >= starting_frame) + { + //Hopefully a future version of VxWorks will have a system call + //for an RTP to query its own symbols, but this is not possible now. + //An enhancement request has been filed under WIND00123307. + const char *fnName = "(no symbols)"; + + static const int N_ARGS = 12; + int buf[N_ARGS]; + int *pArgs = 0; + int numArgs = + trcLibFuncs.lvlArgsGet (prevPc, prevFn, prevFp, + buf, N_ARGS, &pArgs); + + // VxWorks can return -1 for "numArgs" if there was an error + if (numArgs == -1) numArgs = 0; + + size_t len = ACE_OS::strlen (this->buf_); + size_t space = SYMBUFSIZ - len - 1; + char *cursor = this->buf_ + len; + size_t written = ACE_OS::snprintf (cursor, space, "%x %s", + prevFn, fnName); + cursor += written; + space -= written; + + if (space < 1) return; //no point in logging when we're out of buffer + for (int arg = 0; numArgs != -1 && pArgs && arg < numArgs; ++arg) + { + if (arg == 0) *cursor++ = '(', --space; + written = ACE_OS::snprintf (cursor, space, + (arg < numArgs - 1) ? "%x, " : "%x", + pArgs[arg]); + cursor += written; + space -= written; + if (space && arg == numArgs - 1) *cursor++ = ')', --space; + } + if (space) *cursor++ = '\n', --space; + *cursor++ = 0; //we saved space for the null terminator + } + + fp = prevFp; + pc = prevPc; + } +} + +#elif defined(sun) +/* + * walks up call stack, printing library:routine+offset for each routine + */ + +# include +# include +# include +# include +# include +# define ACE_STACK_TRACE_BIAS 0 + +# if defined(sparc) || defined(__sparc) +# define ACE_STACK_TRACE_FLUSHWIN() asm("ta 3"); +# define ACE_STACK_TRACE_FRAME_PTR_INDEX 1 +# define ACE_STACK_TRACE_SKIP_FRAMES 0 +# if defined(__sparcv9) +# undef ACE_STACK_TRACE_BIAS +# define ACE_STACK_TRACE_BIAS 2047 +# endif +# endif + +# if defined(i386) || defined(__i386) +# define ACE_STACK_TRACE_FLUSHWIN() +# define ACE_STACK_TRACE_FRAME_PTR_INDEX 3 +# define ACE_STACK_TRACE_SKIP_FRAMES 0 +# endif + +# if defined(__amd64) || defined(__x86_64) +# define ACE_STACK_TRACE_FLUSHWIN() +# define ACE_STACK_TRACE_FRAME_PTR_INDEX 5 +# define ACE_STACK_TRACE_SKIP_FRAMES 0 +# endif + +# if defined(ppc) || defined(__ppc) +# define ACE_STACK_TRACE_FLUSHWIN() +# define ACE_STACK_TRACE_FRAME_PTR_INDEX 0 +# define ACE_STACK_TRACE_SKIP_FRAMES 2 +# endif + +static frame* +cs_frame_adjust(frame* sp) +{ + unsigned char* sp_byte = (unsigned char*)sp; + sp_byte += ACE_STACK_TRACE_BIAS; + return (frame*) sp_byte; +} + +/* + this function walks up call stack, calling user-supplied + function once for each stack frame, passing the pc and the user-supplied + usrarg as the argument. + */ + +static int +cs_operate(int (*func)(void *, void *), void * usrarg, + size_t starting_frame, size_t num_frames_arg) +{ + ACE_STACK_TRACE_FLUSHWIN(); + + jmp_buf env; + setjmp(env); + frame* sp = cs_frame_adjust((frame*) env[ACE_STACK_TRACE_FRAME_PTR_INDEX]); + + // make a copy of num_frames_arg to eliminate the following warning on some + // solaris platforms: + // Stack_Trace.cpp:318: warning: argument `size_t num_frames' might be clobbered by `longjmp' or `vfork' + size_t num_frames = num_frames_arg; + + // I would like to use ACE_MAX below rather than ?:, but + // I get linker relocation errors such as the following when + // I use it: + // ld: fatal: relocation error: file: .shobj/Stack_Trace.o section: + // .rela.debug_line symbol: : relocation against a discarded symbol, + // symbol is part of discarded section: + // .text%const __type_0&ace_max(const __type_0&,const __type_0&) + // + const size_t starting_skip = starting_frame - 1; +#if ACE_STACK_TRACE_SKIP_FRAMES == 0 + size_t skip_frames = starting_skip; +#else + size_t skip_frames = + ACE_STACK_TRACE_SKIP_FRAMES > starting_skip ? + ACE_STACK_TRACE_SKIP_FRAMES : starting_skip; +#endif /* ACE_STACK_TRACE_SKIP_FRAMES == 0 */ + size_t i; + for (i = 0; i < skip_frames && sp; ++i) + { + sp = cs_frame_adjust((frame*) sp->fr_savfp); + } + + i = 0; + + while ( sp + && sp->fr_savpc + && ++i + && --num_frames + && (*func)((void*)sp->fr_savpc, usrarg)) + { + sp = cs_frame_adjust((frame*) sp->fr_savfp); + } + + return(i); +} + +static int +add_frame_to_buf (void* pc, void* usrarg) +{ + char* buf = (char*)usrarg; + Dl_info info; + const char* func = "??"; + const char* lib = "??"; + + if(dladdr(pc, & info) != 0) + { + lib = (const char *) info.dli_fname; + func = (const char *) info.dli_sname; + } + + (void) ACE_OS::snprintf(buf, + ACE_Stack_Trace::SYMBUFSIZ, + "%s%s:%s+0x%x\n", + buf, + lib, + func, + //@@ Should the arithmetic on the following + //line be done with two void* ptrs? The result + //would be ptrdiff_t, and what is the correct + //sprintf() conversion character for that? + (size_t)pc - (size_t)info.dli_saddr); + + return(1); +} + +void +ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset, + size_t num_frames) +{ + const size_t MAX_FRAMES = 128; + const ssize_t INITIAL_FRAME = 3; + + if (num_frames == 0) + num_frames = MAX_FRAMES; + + size_t starting_frame = + determine_starting_frame (INITIAL_FRAME, starting_frame_offset); + + cs_operate (&add_frame_to_buf, &this->buf_[0], starting_frame, num_frames); +} + +#elif defined(ACE_WIN64) && (_WIN32_WINNT <= _WIN32_WINNT_WIN2K) +# if defined(_MSC_VER) +# define STRING2(X) #X +# define STRING(X) STRING2(X) +# pragma message (__FILE__ "(" STRING(__LINE__) ") : warning: stack traces"\ + " can't be generated on 64-bit Windows when _WIN32_WINNT is less than "\ + "0x501.") +# undef STRING +# undef STRING2 +# endif /*_MSC_VER*/ +void +ACE_Stack_Trace::generate_trace (ssize_t, size_t) +{ + ACE_OS::strcpy (&this->buf_[0], ""); +} + +#elif defined(ACE_WIN32) && !defined(ACE_HAS_WINCE) && !defined (__MINGW32__) \ + && !defined(__BORLANDC__) +# include +# include + +# define MAXTEXT 5000 +# define SYMSIZE 100 + +//@TODO: Test with WCHAR +//@TODO: Need a common CriticalSection since dbghelp is not thread-safe + +typedef struct _dbghelp_functions +{ + HMODULE hMod; //our handle to dbghelp.dll + + //these already have typedefs in DbgHelp.h + DWORD64 (WINAPI *SymGetModuleBase64) (HANDLE hProc, DWORD64 dwAddr); + PVOID (WINAPI *SymFunctionTableAccess64) (HANDLE hProc, DWORD64 AddrBase); + + typedef BOOL (WINAPI *SymFromAddr_t) + (HANDLE hProc, DWORD64 Addr, PDWORD64 Disp, PSYMBOL_INFO Symbol); + SymFromAddr_t SymFromAddr; + + typedef BOOL (WINAPI *SymGetLineFromAddr64_t) (HANDLE hProc, DWORD64 dwAddr, + PDWORD pdwDisplacement, + PIMAGEHLP_LINE64 Line); + SymGetLineFromAddr64_t SymGetLineFromAddr64; + + typedef DWORD (WINAPI *SymSetOptions_t) (DWORD SymOptions); + SymSetOptions_t SymSetOptions; + + typedef DWORD (WINAPI *SymGetOptions_t) (); + SymGetOptions_t SymGetOptions; + + typedef BOOL (WINAPI *SymInitialize_t) (HANDLE hProc, PCTSTR UserSearchPath, + BOOL invasive); + SymInitialize_t SymInitialize; + + typedef BOOL + (WINAPI *StackWalk64_t) (DWORD MachineType, HANDLE hPRoc, HANDLE hThr, + LPSTACKFRAME64 StackFrame, PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 RMRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FTARoutine, + PGET_MODULE_BASE_ROUTINE64 GMBRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); + StackWalk64_t StackWalk64; + + typedef BOOL (WINAPI *SymCleanup_t) (HANDLE hProc); + SymCleanup_t SymCleanup; +} dbghelp_functions; + + +# pragma warning (push) +# pragma warning (disable:4706) +static bool load_dbghelp_library_if_needed (dbghelp_functions *pDbg) +{ + //@TODO: See codeproject's StackWalker.cpp for the list of locations to + //search so we get the "enhanced" dbghelp if the user has it but it is not + //first on the path. + if (!(pDbg->hMod = ACE_TEXT_LoadLibrary (ACE_TEXT ("Dbghelp")))) + return false; + + //@TODO: Cache this so we don't have to re-link every time. When to unload? + +# define LINK(TYPE, NAME) (pDbg->NAME = \ + (TYPE) GetProcAddress (pDbg->hMod, #NAME)) +# define LINK_T(NAME) LINK (dbghelp_functions::NAME##_t, NAME) + return LINK (PGET_MODULE_BASE_ROUTINE64, SymGetModuleBase64) + && LINK (PFUNCTION_TABLE_ACCESS_ROUTINE64, SymFunctionTableAccess64) + && LINK_T (SymFromAddr) && LINK_T (SymGetLineFromAddr64) + && LINK_T (SymSetOptions)&& LINK_T (SymGetOptions) + && LINK_T (SymInitialize) && LINK_T (StackWalk64) && LINK_T (SymCleanup); +# undef LINK +# undef LINK_T +} +# pragma warning (pop) + + +struct frame_state { + STACKFRAME64 sf; + PSYMBOL_INFO pSym; + dbghelp_functions *pDbg; +}; + +static int +add_frame_to_buf (struct frame_state const *fs, void *usrarg) +{ + if (fs == 0 || usrarg == 0) + return -1; + + char *buf = static_cast (usrarg); + + DWORD64 disp; + DWORD64 dwModBase = fs->pDbg->SymGetModuleBase64 (GetCurrentProcess (), + fs->sf.AddrPC.Offset); + if (fs->pDbg->SymFromAddr (GetCurrentProcess (), + fs->sf.AddrPC.Offset, &disp, fs->pSym)) + { + IMAGEHLP_LINE64 line = {sizeof (IMAGEHLP_LINE64)}; + DWORD lineDisp; + if (fs->pDbg->SymGetLineFromAddr64 (GetCurrentProcess (), + fs->sf.AddrPC.Offset, + &lineDisp, &line)) + { + (void) ACE_OS::snprintf (buf, ACE_Stack_Trace::SYMBUFSIZ, + "%s%s() %s: %d + 0x%x\n", + buf, fs->pSym->Name, line.FileName, + line.LineNumber, lineDisp); + } + else + { + (void) ACE_OS::snprintf (buf, ACE_Stack_Trace::SYMBUFSIZ, + "%s%s()+0x%x [0x%x]\n", + buf, fs->pSym->Name, disp, + fs->sf.AddrPC.Offset - dwModBase); + } + } + else + { + (void) ACE_OS::snprintf (buf, ACE_Stack_Trace::SYMBUFSIZ, + "%s[0x%x]\n", + buf, fs->sf.AddrPC.Offset - dwModBase); + } + return 0; +} + +static void emptyStack () { } + +static int +cs_operate(int (*func)(struct frame_state const *, void *), void *usrarg, + size_t starting_frame, size_t num_frames) +{ + dbghelp_functions dbg; + if (!load_dbghelp_library_if_needed (&dbg)) + { + ACE_OS::strcpy (static_cast (usrarg), + ""); + if (dbg.hMod) FreeLibrary (dbg.hMod); + return 1; + } + + frame_state fs; + ZeroMemory (&fs.sf, sizeof (fs.sf)); + fs.pDbg = &dbg; + emptyStack (); //Not sure what this should do, Chad? + + CONTEXT c; + ZeroMemory (&c, sizeof (CONTEXT)); + c.ContextFlags = CONTEXT_FULL; + +# if defined (_M_IX86) + DWORD machine = IMAGE_FILE_MACHINE_I386; + __asm { + call x + x: pop eax + mov c.Eip, eax + mov c.Ebp, ebp + mov c.Esp, esp + } + fs.sf.AddrPC.Offset = c.Eip; + fs.sf.AddrStack.Offset = c.Esp; + fs.sf.AddrFrame.Offset = c.Ebp; + fs.sf.AddrPC.Mode = AddrModeFlat; + fs.sf.AddrStack.Mode = AddrModeFlat; + fs.sf.AddrFrame.Mode = AddrModeFlat; +# elif defined (_M_X64) + DWORD machine = IMAGE_FILE_MACHINE_AMD64; + RtlCaptureContext (&c); + fs.sf.AddrPC.Offset = c.Rip; + fs.sf.AddrFrame.Offset = c.Rsp; //should be Rbp or Rdi instead? + fs.sf.AddrStack.Offset = c.Rsp; + fs.sf.AddrPC.Mode = AddrModeFlat; + fs.sf.AddrFrame.Mode = AddrModeFlat; + fs.sf.AddrStack.Mode = AddrModeFlat; +# elif defined (_M_IA64) + DWORD machine = IMAGE_FILE_MACHINE_IA64; + RtlCaptureContext (&c); + fs.sf.AddrPC.Offset = c.StIIP; + fs.sf.AddrFrame.Offset = c.RsBSP; + fs.sf.AddrBStore.Offset = c.RsBSP; + fs.sf.AddrStack.Offset = c.IntSp; + fs.sf.AddrPC.Mode = AddrModeFlat; + fs.sf.AddrFrame.Mode = AddrModeFlat; + fs.sf.AddrBStore.Mode = AddrModeFlat; + fs.sf.AddrStack.Mode = AddrModeFlat; +# endif + + fs.pSym = (PSYMBOL_INFO) GlobalAlloc (GMEM_FIXED, + sizeof (SYMBOL_INFO) + + sizeof (ACE_TCHAR) * (SYMSIZE - 1)); + fs.pSym->SizeOfStruct = sizeof (SYMBOL_INFO); + fs.pSym->MaxNameLen = SYMSIZE * sizeof (ACE_TCHAR); + dbg.SymSetOptions (SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES + | SYMOPT_FAIL_CRITICAL_ERRORS | dbg.SymGetOptions ()); + dbg.SymInitialize (GetCurrentProcess (), 0, true); + //What does the "true" parameter mean when tracing the current process? + + for (size_t current_frame = 0; current_frame < num_frames + starting_frame; + ++current_frame) + { + BOOL ok = dbg.StackWalk64 (machine, + GetCurrentProcess (), + GetCurrentThread (), + &fs.sf, &c, 0, + dbg.SymFunctionTableAccess64, + dbg.SymGetModuleBase64, 0); + if (!ok || fs.sf.AddrFrame.Offset == 0) + break; + + if (current_frame < starting_frame) + continue; + + func (&fs, usrarg); + } + + dbg.SymCleanup (GetCurrentProcess ()); + GlobalFree (fs.pSym); + FreeLibrary (dbg.hMod); + + return 0; +} + +void +ACE_Stack_Trace::generate_trace (ssize_t starting_frame_offset, + size_t num_frames) +{ + const size_t MAX_FRAMES = 128; + const ssize_t INITIAL_FRAME = 3; + + if (num_frames == 0) + num_frames = MAX_FRAMES; + + size_t starting_frame = + determine_starting_frame (INITIAL_FRAME, starting_frame_offset); + + cs_operate (&add_frame_to_buf, &this->buf_[0], starting_frame, num_frames); +} + +#else // Unsupported platform +void +ACE_Stack_Trace::generate_trace (ssize_t, size_t) +{ +// Call determine_starting_frame() on HP aCC build to resolve declared +// method never referenced warning. +#if defined (__HP_aCC) + size_t starting_frame = determine_starting_frame (0, 0); +#endif + + ACE_OS::strcpy (&this->buf_[0], UNSUPPORTED); +} +#endif + diff --git a/dep/ACE_wrappers/ace/Stack_Trace.h b/dep/ACE_wrappers/ace/Stack_Trace.h new file mode 100644 index 000000000..56cf8a092 --- /dev/null +++ b/dep/ACE_wrappers/ace/Stack_Trace.h @@ -0,0 +1,107 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file Stack_Trace.h + * + * $Id: Stack_Trace.h 81926 2008-06-12 14:43:09Z mitza $ + * + * @author Chris Cleeland (cleeland.ociweb.com) + */ +//============================================================================= + +#ifndef ACE_STACK_TRACE_H +#define ACE_STACK_TRACE_H + +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" +#include "ace/Basic_Types.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +# ifndef ACE_STACK_TRACE_SYMBUFSIZ +# define ACE_STACK_TRACE_SYMBUFSIZ 4096 +# endif + +/** + * @class ACE_Stack_Trace + * + * @brief Encapsulate a string representation of a stack trace on supported platforms. + * Stack traces for code built with optimize=1 (or "Release" configs on Visual + * Studio) may be misleading (missng frames) due to inlining performed by the + * compiler, which is indepenent of the inline=0 / inline=1 build option and + * the __ACE_INLINE__ / ACE_NO_INLINE macros. + * + * A new conversion character, the question mark, was added to ACE_Log_Msg for stack + * trace logging. The %? conversion character was added as a convenience so that users + * need not instantiate an ACE_Stack_Trace instance solely for the purpose of printing + * it in an ACE logging message. The following are functionally equivalent: + * + * \code + * ACE_DEBUG((LM_DEBUG, "%?")); + * + * ACE_Stack_Trace st; + * ACE_DEBUG ((LM_DEBUG, "%s", st.c_str() )); + * \endcode + * + * These usage examples were shown in $ACE_ROOT/tests/Stack_Trace_Test.cpp. + * + * @note The stack trace functionality was currently supported on platforms: + * - Any platform using glibc as its runtime library, or where ACE_HAS_EXECINFO_H is defined + * (this covers Linux and Mac) and gcc version >= 3.3. + * - VxWorks, both kernel and RTP + * - Solaris + * - Windows 32 and 64 bit (Visual C++, excluding WinCE/mobile) + * + * @note Since stack trace buffer size has limitation(@c ACE_STACK_TRACE_SYMBUFSIZ), you will not + * get a complete stack trace if @c ACE_STACK_TRACE_SYMBUFSIZ value is less than actual stack + * trace data length. To get a complete stack trace, you need set @c ACE_STACK_TRACE_SYMBUFSIZ + * with a larger value that is enough for the stack trace data in your @c config.h file + * and rebuild ACE. + * + * @note Using ACE logging mechanism (%?) to log the stack trace also has ACE_MAXLOGMSGLEN size limitation. + * To get a complete stack trace, you could use different output method. Following is an example. + * + * \code + * ACE_Stack_Trace st; + * ACE_OS::printf("at [%s]\n", st.c_str()); + * \endcode + */ +class ACE_Export ACE_Stack_Trace +{ +public: + /** + * @brief Grab a snapshot of the current stack trace and hold it for later use. + * + * @param starting_frame_offset offset into the array of frames to start printing; 0 is the + * platform-specific offset for the first frame, positive numbers give less frames, negative give + * more frames + * @param num_frames the number of stack frames to include (0 indicates platform-specific maximum) + * + */ + explicit ACE_Stack_Trace (ssize_t starting_frame_offset = 0, size_t num_frames = 0); + + /** + * @brief Return buffer as a C-style string. + * @return C-style string with string representation of stack trace. + * @note Lifecycle of string follows lifecycle of ACE_Stack_Trace instance. + */ + const char* c_str() const; + + static const size_t SYMBUFSIZ = ACE_STACK_TRACE_SYMBUFSIZ; + +private: + char buf_[SYMBUFSIZ]; + size_t buflen_; + + static const char UNSUPPORTED[]; + static const char UNABLE_TO_GET_TRACE[]; + + void generate_trace (ssize_t starting_frame_offset, size_t num_frames); +}; + +#include /**/ "ace/post.h" +#endif /* ACE_STACK_TRACE_H */ + diff --git a/dep/ACE_wrappers/ace/Static_Object_Lock.h b/dep/ACE_wrappers/ace/Static_Object_Lock.h new file mode 100644 index 000000000..ad780258e --- /dev/null +++ b/dep/ACE_wrappers/ace/Static_Object_Lock.h @@ -0,0 +1,78 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Static_Object_Lock.h + * + * $Id: Static_Object_Lock.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author David L. Levine + * @author Matthias Kerkhoff + * @author Per Andersson + */ +//============================================================================= + +#ifndef ACE_STATIC_OBJECT_LOCK_H +#define ACE_STATIC_OBJECT_LOCK_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Recursive_Thread_Mutex; + +/** + * @class ACE_Static_Object_Lock + * + * @brief Provide an interface to access a global lock. + * + * This class is used to serialize the creation of static + * singleton objects. It really isn't needed any more, because + * anyone can access ACE_STATIC_OBJECT_LOCK directly. But, it + * is retained for backward compatibility. + */ +class ACE_Export ACE_Static_Object_Lock +{ +public: + /// Static lock access point. + static ACE_Recursive_Thread_Mutex *instance (void); + + /// For use only by ACE_Object_Manager to clean up lock if it + /// what dynamically allocated. + static void cleanup_lock (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ + +// hack to get around errors while compiling using split-cpp +#if defined (ACE_HAS_THREADS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_IS_SPLITTING) +typedef ACE_Cleanup_Adapter ACE_Static_Object_Lock_Type; + +# if defined (__GNUC__) +// With g++, suppress the warning that this is unused. +static ACE_Static_Object_Lock_Type *ACE_Static_Object_Lock_lock __attribute__ ((unused)) = 0; +# else +static ACE_Static_Object_Lock_Type *ACE_Static_Object_Lock_lock = 0; +# endif /* __GNUC__ */ + +# endif /* ACE_IS_SPLITTING */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_STATIC_OBJECT_LOCK_H */ diff --git a/dep/ACE_wrappers/ace/Stats.cpp b/dep/ACE_wrappers/ace/Stats.cpp new file mode 100644 index 000000000..bb6dcf0a6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Stats.cpp @@ -0,0 +1,426 @@ +// $Id: Stats.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Stats.h" + +#if !defined (__ACE_INLINE__) +# include "ace/Stats.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(ace, Stats, "$Id: Stats.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_UINT32 +ACE_Stats_Value::fractional_field (void) const +{ + if (precision () == 0) + { + return 1; + } + else + { + ACE_UINT32 field = 10; + for (u_int i = 0; i < precision () - 1; ++i) + { + field *= 10; + } + + return field; + } +} + +int +ACE_Stats::sample (const ACE_INT32 value) +{ + if (samples_.enqueue_tail (value) == 0) + { + ++number_of_samples_; + if (number_of_samples_ == 0) + { + // That's a lot of samples :-) + overflow_ = EFAULT; + return -1; + } + + if (value < min_) + min_ = value; + + if (value > max_) + max_ = value; + + return 0; + } + else + { + // Probably failed due to running out of memory when trying to + // enqueue the new value. + overflow_ = errno; + return -1; + } +} + +void +ACE_Stats::mean (ACE_Stats_Value &m, + const ACE_UINT32 scale_factor) +{ + if (number_of_samples_ > 0) + { +#if defined ACE_LACKS_LONGLONG_T + // If ACE_LACKS_LONGLONG_T, then ACE_UINT64 is a user-defined class. + // To prevent having to construct a static of that class, declare it + // on the stack, and construct it, in each function that needs it. + const ACE_U_LongLong ACE_STATS_INTERNAL_OFFSET (0, 8); +#else /* ! ACE_LACKS_LONGLONG_T */ + const ACE_UINT64 ACE_STATS_INTERNAL_OFFSET = + ACE_UINT64_LITERAL (0x100000000); +#endif /* ! ACE_LACKS_LONGLONG_T */ + + ACE_UINT64 sum = ACE_STATS_INTERNAL_OFFSET; + ACE_Unbounded_Queue_Iterator i (samples_); + while (! i.done ()) + { + ACE_INT32 *sample; + if (i.next (sample)) + { + sum += *sample; + i.advance (); + } + } + + // sum_ was initialized with ACE_STATS_INTERNAL_OFFSET, so + // subtract that off here. + quotient (sum - ACE_STATS_INTERNAL_OFFSET, + number_of_samples_ * scale_factor, + m); + } + else + { + m.whole (0); + m.fractional (0); + } +} + +int +ACE_Stats::std_dev (ACE_Stats_Value &std_dev, + const ACE_UINT32 scale_factor) +{ + if (number_of_samples_ <= 1) + { + std_dev.whole (0); + std_dev.fractional (0); + } + else + { + const ACE_UINT32 field = std_dev.fractional_field (); + + // The sample standard deviation is: + // + // sqrt (sum (sample_i - mean)^2 / (number_of_samples_ - 1)) + + ACE_UINT64 mean_scaled; + // Calculate the mean, scaled, so that we don't lose its + // precision. + ACE_Stats_Value avg (std_dev.precision ()); + mean (avg, 1u); + avg.scaled_value (mean_scaled); + + // Calculate the summation term, of squared differences from the + // mean. + ACE_UINT64 sum_of_squares = 0; + ACE_Unbounded_Queue_Iterator i (samples_); + while (! i.done ()) + { + ACE_INT32 *sample; + if (i.next (sample)) + { + const ACE_UINT64 original_sum_of_squares = sum_of_squares; + + // Scale up by field width so that we don't lose the + // precision of the mean. Carefully . . . + const ACE_UINT64 product (*sample * field); + + ACE_UINT64 difference; + // NOTE: please do not reformat this code! It // + // works with the Diab compiler the way it is! // + if (product >= mean_scaled) // + { // + difference = product - mean_scaled; // + } // + else // + { // + difference = mean_scaled - product; // + } // + // NOTE: please do not reformat this code! It // + // works with the Diab compiler the way it is! // + + // Square using 64-bit arithmetic. + sum_of_squares += difference * ACE_U64_TO_U32 (difference); + i.advance (); + + if (sum_of_squares < original_sum_of_squares) + { + overflow_ = ENOSPC; + return -1; + } + } + } + + // Divide the summation by (number_of_samples_ - 1), to get the + // variance. In addition, scale the variance down to undo the + // mean scaling above. Otherwise, it can get too big. + ACE_Stats_Value variance (std_dev.precision ()); + quotient (sum_of_squares, + (number_of_samples_ - 1) * field * field, + variance); + + // Take the square root of the variance to get the standard + // deviation. First, scale up . . . + ACE_UINT64 scaled_variance; + variance.scaled_value (scaled_variance); + + // And scale up, once more, because we'll be taking the square + // root. + scaled_variance *= field; + ACE_Stats_Value unscaled_standard_deviation (std_dev.precision ()); + square_root (scaled_variance, + unscaled_standard_deviation); + + // Unscale. + quotient (unscaled_standard_deviation, + scale_factor * field, + std_dev); + } + + return 0; +} + + +void +ACE_Stats::reset (void) +{ + overflow_ = 0u; + number_of_samples_ = 0u; + min_ = 0x7FFFFFFF; + max_ = -0x8000 * 0x10000; + samples_.reset (); +} + +int +ACE_Stats::print_summary (const u_int precision, + const ACE_UINT32 scale_factor, + FILE *file) const +{ + ACE_TCHAR mean_string [128]; + ACE_TCHAR std_dev_string [128]; + ACE_TCHAR min_string [128]; + ACE_TCHAR max_string [128]; + int success = 0; + + for (int tmp_precision = precision; + ! overflow_ && ! success && tmp_precision >= 0; + --tmp_precision) + { + // Build a format string, in case the C library doesn't support %*u. + ACE_TCHAR format[32]; + if (tmp_precision == 0) + ACE_OS::sprintf (format, ACE_TEXT ("%%%d"), tmp_precision); + else + ACE_OS::sprintf (format, ACE_TEXT ("%%d.%%0%du"), tmp_precision); + + ACE_Stats_Value u (tmp_precision); + ((ACE_Stats *) this)->mean (u, scale_factor); + ACE_OS::sprintf (mean_string, format, u.whole (), u.fractional ()); + + ACE_Stats_Value sd (tmp_precision); + if (((ACE_Stats *) this)->std_dev (sd, scale_factor)) + { + success = 0; + continue; + } + else + { + success = 1; + } + ACE_OS::sprintf (std_dev_string, format, sd.whole (), sd.fractional ()); + + ACE_Stats_Value minimum (tmp_precision), maximum (tmp_precision); + if (min_ != 0) + { + const ACE_UINT64 m (min_); + quotient (m, scale_factor, minimum); + } + if (max_ != 0) + { + const ACE_UINT64 m (max_); + quotient (m, scale_factor, maximum); + } + ACE_OS::sprintf (min_string, format, + minimum.whole (), minimum.fractional ()); + ACE_OS::sprintf (max_string, format, + maximum.whole (), maximum.fractional ()); + } + + if (success == 1) + { + ACE_OS::fprintf (file, ACE_TEXT ("samples: %u (%s - %s); mean: ") + ACE_TEXT ("%s; std dev: %s\n"), + samples (), min_string, max_string, + mean_string, std_dev_string); + return 0; + } + else + { +#if !defined (ACE_HAS_WINCE) + ACE_OS::fprintf (file, + ACE_TEXT ("ACE_Stats::print_summary: OVERFLOW: %s\n"), + ACE_OS::strerror (overflow_)); +#else + // WinCE doesn't have strerror ;( + ACE_OS::fprintf (file, + ACE_TEXT ("ACE_Stats::print_summary: OVERFLOW\n")); +#endif /* ACE_HAS_WINCE */ + return -1; + } +} + +void +ACE_Stats::quotient (const ACE_UINT64 dividend, + const ACE_UINT32 divisor, + ACE_Stats_Value "ient) +{ + // The whole part of the division comes from simple integer division. + quotient.whole (static_cast (divisor == 0 + ? 0 : dividend / divisor)); + + if (quotient.precision () > 0 || divisor == 0) + { + const ACE_UINT32 field = quotient.fractional_field (); + + // Fractional = (dividend % divisor) * 10^precision / divisor + + // It would be nice to add round-up term: + // Fractional = (dividend % divisor) * 10^precision / divisor + + // 10^precision/2 / 10^precision + // = ((dividend % divisor) * 10^precision + divisor) / + // divisor + quotient.fractional (static_cast ( + dividend % divisor * field / divisor)); + } + else + { + // No fractional portion is requested, so don't bother + // calculating it. + quotient.fractional (0); + } +} + +void +ACE_Stats::quotient (const ACE_Stats_Value ÷nd, + const ACE_UINT32 divisor, + ACE_Stats_Value "ient) +{ + // The whole part of the division comes from simple integer division. + quotient.whole (divisor == 0 ? 0 : dividend.whole () / divisor); + + if (quotient.precision () > 0 || divisor == 0) + { + const ACE_UINT32 field = quotient.fractional_field (); + + // Fractional = (dividend % divisor) * 10^precision / divisor. + quotient.fractional (dividend.whole () % divisor * field / divisor + + dividend.fractional () / divisor); + } + else + { + // No fractional portion is requested, so don't bother + // calculating it. + quotient.fractional (0); + } +} + +void +ACE_Stats::square_root (const ACE_UINT64 n, + ACE_Stats_Value &square_root) +{ + ACE_UINT32 floor = 0; + ACE_UINT32 ceiling = 0xFFFFFFFFu; + ACE_UINT32 mid = 0; + u_int i; + + // The maximum number of iterations is log_2 (2^64) == 64. + for (i = 0; i < 64; ++i) + { + mid = (ceiling - floor) / 2 + floor; + if (floor == mid) + // Can't divide the interval any further. + break; + else + { + // Multiply carefully to avoid overflow. + ACE_UINT64 mid_squared = mid; mid_squared *= mid; + if (mid_squared == n) + break; + else if (mid_squared < n) + floor = mid; + else + ceiling = mid; + } + } + + square_root.whole (mid); + ACE_UINT64 mid_squared = mid; mid_squared *= mid; + + if (square_root.precision () && mid_squared < n) + { + // (mid * 10^precision + fractional)^2 == + // n^2 * 10^(precision * 2) + + const ACE_UINT32 field = square_root.fractional_field (); + + floor = 0; + ceiling = field; + mid = 0; + + // Do the 64-bit arithmetic carefully to avoid overflow. + ACE_UINT64 target = n; + target *= field; + target *= field; + + ACE_UINT64 difference = 0; + + for (i = 0; i < square_root.precision (); ++i) + { + mid = (ceiling - floor) / 2 + floor; + + ACE_UINT64 current = square_root.whole () * field + mid; + current *= square_root.whole () * field + mid; + + if (floor == mid) + { + difference = target - current; + break; + } + else if (current <= target) + floor = mid; + else + ceiling = mid; + } + + // Check to see if the fractional part should be one greater. + ACE_UINT64 next = square_root.whole () * field + mid + 1; + next *= square_root.whole () * field + mid + 1; + + square_root.fractional (next - target < difference ? mid + 1 : mid); + } + else + { + // No fractional portion is requested, so don't bother + // calculating it. + square_root.fractional (0); + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Stats.h b/dep/ACE_wrappers/ace/Stats.h new file mode 100644 index 000000000..2590ec95c --- /dev/null +++ b/dep/ACE_wrappers/ace/Stats.h @@ -0,0 +1,222 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Stats.h + * + * $Id: Stats.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author David L. Levine + */ +//========================================================================== + + +#ifndef ACE_STATS_H +#define ACE_STATS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Unbounded_Queue.h" +#include "ace/Log_Msg.h" +#include "ace/Basic_Stats.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Stats_Value + * + * @brief Helper class for ACE_Stats. + * + * Container struct for 64-bit signed quantity and its + * precision. It would be nicer to use a fixed-point class, but + * this is sufficient. Users typically don't need to use this + * class directly; see ACE_Stats below. + */ +class ACE_Export ACE_Stats_Value +{ +public: + /** + * Constructor, which requires precision in terms of number of + * decimal digits. The more variation in the data, and the greater + * the data values, the smaller the precision must be to avoid + * overflow in the standard deviation calculation. 3 might be a + * good value, or maybe 4. 5 will probably be too large for + * non-trivial data sets. + */ + ACE_Stats_Value (const u_int precision); + + /// Accessor for precision. + u_int precision (void) const; + + /// Set the whole_ field. + void whole (const ACE_UINT32); + + /// Accessor for the whole_ field. + ACE_UINT32 whole (void) const; + + /// Set the fractional_ field. + void fractional (const ACE_UINT32); + + /// Accessor for the fractional_ field. + ACE_UINT32 fractional (void) const; + + /// Calculates the maximum value of the fractional portion, given its + /// precision. + ACE_UINT32 fractional_field (void) const; + + /** + * Access the value as an _unsigned_ 64 bit quantity. It scales the + * value up by {precision} decimal digits, so that no precision will + * be lost. It assumes that {whole_} is >= 0. + */ + void scaled_value (ACE_UINT64 &) const; + + /// Print to stdout. + void dump (void) const; + +private: + + ACE_Stats_Value (void) {} + +private: + /// The integer portion of the value. + ACE_UINT32 whole_; + + /// The fractional portion of the value. + ACE_UINT32 fractional_; + + /** + * The number of decimal digits of precision represented by + * {fractional_}. Not declared const, so the only way to change it + * is via the assignment operator. + */ + u_int precision_; + +}; + +/** + * @class ACE_Stats + * + * @brief Provides simple statistical analysis. + * + * Simple statistical analysis package. Prominent features are: + * -# It does not use any floating point arithmetic. + * -# It handles positive and/or negative sample values. The + * sample value type is ACE_INT32. + * -# It uses 64 bit unsigned, but not 64 bit signed, quantities + * internally. + * -# It checks for overflow of internal state. + * -# It has no static variables of other than built-in types. + * + * Example usage: + * + * @verbatim + * ACE_Stats stats; + * for (u_int i = 0; i < n; ++i) + * { + * const ACE_UINT32 sample = ...; + * stats.sample (sample); + * } + * stats.print_summary (3); + * @endverbatim + */ +class ACE_Export ACE_Stats +{ +public: + /// Default constructor. + ACE_Stats (void); + + /// Provide a new sample. Returns 0 on success, -1 if it fails due + /// to running out of memory, or to rolling over of the sample count. + int sample (const ACE_INT32 value); + + /// Access the number of samples provided so far. + ACE_UINT32 samples (void) const; + + /// Value of the minimum sample provided so far. + ACE_INT32 min_value (void) const; + + /// Value of the maximum sample provided so far. + ACE_INT32 max_value (void) const; + + /** + * Access the mean of all samples provided so far. The fractional + * part is to the specified number of digits. E.g., 3 fractional + * digits specifies that the fractional part is in thousandths. + */ + void mean (ACE_Stats_Value &mean, + const ACE_UINT32 scale_factor = 1); + + /// Access the standard deviation, whole and fractional parts. See + /// description of {mean} method for argument descriptions. + int std_dev (ACE_Stats_Value &std_dev, + const ACE_UINT32 scale_factor = 1); + + /** + * Print summary statistics. If scale_factor is not 1, then the + * results are divided by it, i.e., each of the samples is scaled + * down by it. If internal overflow is reached with the specified + * scale factor, it successively tries to reduce it. Returns -1 if + * there is overflow even with a 0 scale factor. + */ + int print_summary (const u_int precision, + const ACE_UINT32 scale_factor = 1, + FILE * = stdout) const; + + /// Initialize internal state. + void reset (void); + + /// Utility division function, for ACE_UINT64 dividend. + static void quotient (const ACE_UINT64 dividend, + const ACE_UINT32 divisor, + ACE_Stats_Value "ient); + + /// Utility division function, for ACE_Stats_Value dividend. + static void quotient (const ACE_Stats_Value ÷nd, + const ACE_UINT32 divisor, + ACE_Stats_Value "ient); + + /** + * Sqrt function, which uses an oversimplified version of Newton's + * method. It's not fast, but it doesn't require floating point + * support. + */ + static void square_root (const ACE_UINT64 n, + ACE_Stats_Value &square_root); + + /// Print summary statistics to stdout. + void dump (void) const; + +protected: + /// Internal indication of whether there has been overflow. Contains + /// the errno corresponding to the cause of overflow. + u_int overflow_; + + /// Number of samples. + ACE_UINT32 number_of_samples_; + + /// Minimum sample value. + ACE_INT32 min_; + + /// Maximum sample value. + ACE_INT32 max_; + + /// The samples. + ACE_Unbounded_Queue samples_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/Stats.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ! ACE_STATS_H */ diff --git a/dep/ACE_wrappers/ace/Stats.inl b/dep/ACE_wrappers/ace/Stats.inl new file mode 100644 index 000000000..4c76838c2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Stats.inl @@ -0,0 +1,104 @@ +// -*- C++ -*- +// +// $Id: Stats.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Stats_Value::ACE_Stats_Value (const u_int precision) + : whole_ (0), + fractional_ (0), + precision_ (precision) +{ +} + +ACE_INLINE +u_int +ACE_Stats_Value::precision (void) const +{ + return precision_; +} + +ACE_INLINE +void +ACE_Stats_Value::whole (const ACE_UINT32 value) +{ + whole_ = value; +} + +ACE_INLINE +ACE_UINT32 +ACE_Stats_Value::whole (void) const +{ + return whole_; +} + +ACE_INLINE +void +ACE_Stats_Value::fractional (const ACE_UINT32 value) +{ + fractional_ = value; +} + +ACE_INLINE +ACE_UINT32 +ACE_Stats_Value::fractional (void) const +{ + return fractional_; +} + +ACE_INLINE +void +ACE_Stats_Value::scaled_value (ACE_UINT64 &sv) const +{ + sv = whole () * fractional_field () + fractional (); +} + +ACE_INLINE +void +ACE_Stats_Value::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("precision: %u digits; whole: %u, fractional: %u\n"), + precision_, whole_, fractional_)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_INLINE +ACE_Stats::ACE_Stats (void) +{ + reset (); +} + +ACE_INLINE +ACE_UINT32 +ACE_Stats::samples (void) const +{ + return number_of_samples_; +} + +ACE_INLINE +ACE_INT32 +ACE_Stats::min_value (void) const +{ + return min_; +} + +ACE_INLINE +ACE_INT32 +ACE_Stats::max_value (void) const +{ + return max_; +} + +ACE_INLINE +void +ACE_Stats::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + print_summary (3u); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Strategies.h b/dep/ACE_wrappers/ace/Strategies.h new file mode 100644 index 000000000..484ffa9a5 --- /dev/null +++ b/dep/ACE_wrappers/ace/Strategies.h @@ -0,0 +1,33 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Strategies.h + * + * $Id: Strategies.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_STRATEGIES_H +#define ACE_STRATEGIES_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/// Place holder for backward compatibility.. +#include "ace/Connection_Recycling_Strategy.h" +#include "ace/Hashable.h" +#include "ace/Notification_Strategy.h" +#include "ace/Reactor_Notification_Strategy.h" +#include "ace/Recyclable.h" +#include "ace/Refcountable.h" + + +#include /**/ "ace/post.h" +#endif /*ACE_STRATEGIES_H*/ diff --git a/dep/ACE_wrappers/ace/Strategies_T.cpp b/dep/ACE_wrappers/ace/Strategies_T.cpp new file mode 100644 index 000000000..cd2935aad --- /dev/null +++ b/dep/ACE_wrappers/ace/Strategies_T.cpp @@ -0,0 +1,1502 @@ +// $Id: Strategies_T.cpp 82294 2008-07-12 13:03:37Z johnnyw $ + +#ifndef ACE_STRATEGIES_T_CPP +#define ACE_STRATEGIES_T_CPP + +#include "ace/Strategies_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Service_Repository.h" +#include "ace/Service_Types.h" +#include "ace/Thread_Manager.h" +#include "ace/WFMO_Reactor.h" +#include "ace/ACE.h" +#include "ace/OS_NS_dlfcn.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_Errno.h" +#include "ace/Svc_Handler.h" +#if defined (ACE_OPENVMS) +# include "ace/Lib_Find.h" +#endif + +#if !defined (__ACE_INLINE__) +#include "ace/Strategies_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Recycling_Strategy::~ACE_Recycling_Strategy (void) +{ +} + +template int +ACE_Recycling_Strategy::assign_recycler (SVC_HANDLER *svc_handler, + ACE_Connection_Recycling_Strategy *recycler, + const void *recycling_act) +{ + svc_handler->recycler (recycler, recycling_act); + return 0; +} + +template int +ACE_Recycling_Strategy::prepare_for_recycling (SVC_HANDLER *svc_handler) +{ + return svc_handler->recycle (); +} + +template +ACE_Singleton_Strategy::~ACE_Singleton_Strategy (void) +{ + ACE_TRACE ("ACE_Singleton_Strategy::~ACE_Singleton_Strategy"); + if (this->delete_svc_handler_) + delete this->svc_handler_; +} + +// Create a Singleton SVC_HANDLER by always returning the same +// SVC_HANDLER. + +template int +ACE_Singleton_Strategy::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_Singleton_Strategy::make_svc_handler"); + sh = this->svc_handler_; + return 0; +} + +template int +ACE_Singleton_Strategy::open (SVC_HANDLER *sh, + ACE_Thread_Manager *) +{ + ACE_TRACE ("ACE_Singleton_Strategy::open"); + + if (this->delete_svc_handler_) + delete this->svc_handler_; + + // If is NULL then create a new . + if (sh == 0) + { + ACE_NEW_RETURN (this->svc_handler_, + SVC_HANDLER, + -1); + this->delete_svc_handler_ = true; + } + else + { + this->svc_handler_ = sh; + this->delete_svc_handler_ = false; + } + + return 0; +} + +template int +ACE_DLL_Strategy::open (const ACE_TCHAR dll_name[], + const ACE_TCHAR factory_function[], + const ACE_TCHAR svc_name[], + ACE_Service_Repository *svc_rep, + ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_DLL_Strategy::open"); + this->inherited::open (thr_mgr); + ACE_OS::strcpy (this->dll_name_, dll_name); + ACE_OS::strcpy (this->factory_function_, factory_function); + ACE_OS::strcpy (this->svc_name_, svc_name); + this->svc_rep_ = svc_rep; + return 0; +} + +// Create a SVC_HANDLER by dynamically linking it from a DLL. + +template int +ACE_DLL_Strategy::make_svc_handler (SVC_HANDLER *&sh) +{ + ACE_TRACE ("ACE_DLL_Strategy::make_svc_handler"); + + // Open the shared library. + ACE_SHLIB_HANDLE handle = ACE_OS::dlopen (this->dll_name_); + + // Extract the factory function. +#if defined (ACE_OPENVMS) + SVC_HANDLER *(*factory)(void) = + (SVC_HANDLER *(*)(void)) ACE::ldsymbol (handle, + this->factory_function_); +#else + SVC_HANDLER *(*factory)(void) = + (SVC_HANDLER *(*)(void)) ACE_OS::dlsym (handle, + this->factory_function_); +#endif + + // Call the factory function to obtain the new SVC_Handler (should + // use RTTI here when it becomes available...) + SVC_HANDLER *svc_handler = 0; + + ACE_ALLOCATOR_RETURN (svc_handler, (*factory)(), -1); + + if (svc_handler != 0) + { + // Create an ACE_Service_Type containing the SVC_Handler and + // insert into this->svc_rep_; + + ACE_Service_Type_Impl *stp = 0; + ACE_NEW_RETURN (stp, + ACE_Service_Object_Type (svc_handler, + this->svc_name_), + -1); + + ACE_Service_Type *srp = 0; + + ACE_NEW_RETURN (srp, + ACE_Service_Type (this->svc_name_, + stp, + handle, + 1), + -1); + if (srp == 0) + { + delete stp; + errno = ENOMEM; + return -1; + } + + if (this->svc_rep_->insert (srp) == -1) + return -1; + // @@ Somehow, we need to deal with this->thr_mgr_... + } + + sh = svc_handler; + return 0; +} + +// Default behavior is to activate the SVC_HANDLER by calling it's +// open() method, which allows the SVC_HANDLER to determine its own +// concurrency strategy. + +template int +ACE_Concurrency_Strategy::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Concurrency_Strategy::activate_svc_handler"); + + int result = 0; + + // See if we should enable non-blocking I/O on the 's + // peer. + if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0) + { + if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1) + result = -1; + } + // Otherwise, make sure it's disabled by default. + else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1) + result = -1; + + if (result == 0 && svc_handler->open (arg) == -1) + result = -1; + + if (result == -1) + // The connection was already made; so this close is a "normal" close + // operation. + svc_handler->close (NORMAL_CLOSE_OPERATION); + + return result; +} + +template int +ACE_Reactive_Strategy::open (ACE_Reactor *reactor, + ACE_Reactor_Mask mask, + int flags) +{ + ACE_TRACE ("ACE_Reactive_Strategy::open"); + this->reactor_ = reactor; + this->mask_ = mask; + this->flags_ = flags; + + // Must have a + if (this->reactor_ == 0) + return -1; + else + return 0; +} + +template int +ACE_Reactive_Strategy::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Reactive_Strategy::activate_svc_handler"); + + int result = 0; + + if (this->reactor_ == 0) + result = -1; + + // Register with the Reactor with the appropriate . + else if (this->reactor_->register_handler (svc_handler, this->mask_) == -1) + result = -1; + + // If the implementation of the reactor uses event associations + else if (this->reactor_->uses_event_associations ()) + { + // If we don't have non-block on, it won't work with + // WFMO_Reactor + // This maybe too harsh + // if (!ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK)) + // goto failure; + if (svc_handler->open (arg) != -1) + return 0; + else + result = -1; + } + else + // Call up to our parent to do the SVC_HANDLER initialization. + return this->inherited::activate_svc_handler (svc_handler, arg); + + if (result == -1) + // The connection was already made; so this close is a "normal" close + // operation. + svc_handler->close (NORMAL_CLOSE_OPERATION); + + return result; +} + +template int +ACE_Thread_Strategy::open (ACE_Thread_Manager *thr_mgr, + long thr_flags, + int n_threads, + int flags) +{ + ACE_TRACE ("ACE_Thread_Strategy::open"); + this->thr_mgr_ = thr_mgr; + this->n_threads_ = n_threads; + this->thr_flags_ = thr_flags; + this->flags_ = flags; + + // Must have a thread manager! + if (this->thr_mgr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("error: must have a non-NULL thread manager\n")), + -1); + else + return 0; +} + +template int +ACE_Thread_Strategy::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Thread_Strategy::activate_svc_handler"); + // Call up to our parent to do the SVC_HANDLER initialization. + if (this->inherited::activate_svc_handler (svc_handler, + arg) == -1) + return -1; + else + // Turn the into an active object (if it isn't + // already one as a result of the first activation...) + return svc_handler->activate (this->thr_flags_, + this->n_threads_); +} + +template int +ACE_Accept_Strategy::open + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int reuse_addr) +{ + this->reuse_addr_ = reuse_addr; + this->peer_acceptor_addr_ = local_addr; + if (this->peer_acceptor_.open (local_addr, reuse_addr) == -1) + return -1; + + // Set the peer acceptor's handle into non-blocking mode. This is a + // safe-guard against the race condition that can otherwise occur + // between the time when was interrupted. + if (ACE_Sig_Handler::sig_pending () != 0) + { + ACE_Sig_Handler::sig_pending (0); + + // This piece of code comes from the old TP_Reactor. We did not + // handle signals at all then. If we happen to handle signals + // in the TP_Reactor, we should then start worryiung about this + // - Bala 21-Aug- 01 +if 0 + // Not sure if this should be done in the TP_Reactor + // case... leave it out for now. -Steve Huston 22-Aug-00 + + // If any HANDLES in the are activated as a + // result of signals they should be dispatched since + // they may be time critical... + active_handle_count = this->any_ready (dispatch_set); +else + // active_handle_count = 0; +endif + + // Record the fact that the Reactor has dispatched a + // handle_signal() method. We need this to return the + // appropriate count. + return 1; + } + + return -1; +} +#endif // #if 0 + + +int +ACE_TP_Reactor::handle_timer_events (int & /*event_count*/, + ACE_TP_Token_Guard &guard) +{ + if (this->timer_queue_ == 0 || this->timer_queue_->is_empty()) + { // Empty timer queue so cannot have any expired timers. + return 0; + } + + // Get the current time + ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () + + this->timer_queue_->timer_skew ()); + + // Look for a node in the timer queue whose timer <= the present + // time. + ACE_Timer_Node_Dispatch_Info info; + + if (this->timer_queue_->dispatch_info (cur_time, info)) + { + const void *upcall_act = 0; + + // Preinvoke. + this->timer_queue_->preinvoke (info, cur_time, upcall_act); + + // Release the token before dispatching notifies... + guard.release_token (); + + // call the functor + this->timer_queue_->upcall (info, cur_time); + + // Postinvoke + this->timer_queue_->postinvoke (info, cur_time, upcall_act); + + // We have dispatched a timer + return 1; + } + + return 0; +} + +int +ACE_TP_Reactor::handle_notify_events (int & /*event_count*/, + ACE_TP_Token_Guard &guard) +{ + // Get the handle on which notify calls could have occured + ACE_HANDLE notify_handle = this->get_notify_handle (); + + int result = 0; + + // The notify was not in the list returned by + // wait_for_multiple_events (). + if (notify_handle == ACE_INVALID_HANDLE) + return result; + + // Now just do a read on the pipe.. + ACE_Notification_Buffer buffer; + + // Clear the handle of the read_mask of our + this->ready_set_.rd_mask_.clr_bit (notify_handle); + + // Keep reading notifies till we empty it or till we have a + // dispatchable buffer + while (this->notify_handler_->read_notify_pipe (notify_handle, buffer) > 0) + { + // Just figure out whether we can read any buffer that has + // dispatchable info. If not we have just been unblocked by + // another thread trying to update the reactor. If we get any + // buffer that needs dispatching we will dispatch that after + // releasing the lock + if (this->notify_handler_->is_dispatchable (buffer) > 0) + { + // Release the token before dispatching notifies... + guard.release_token (); + + // Dispatch the upcall for the notify + this->notify_handler_->dispatch_notify (buffer); + + // We had a successful dispatch. + result = 1; + + // break out of the while loop + break; + } + } + + // If we did some work, then we just return 1 which will allow us + // to get out of here. If we return 0, then we will be asked to do + // some work ie. dispacth socket events + return result; +} + +int +ACE_TP_Reactor::handle_socket_events (int &event_count, + ACE_TP_Token_Guard &guard) +{ + + // We got the lock, lets handle some I/O events. + ACE_EH_Dispatch_Info dispatch_info; + + this->get_socket_event_info (dispatch_info); + + // If there is any event handler that is ready to be dispatched, the + // dispatch information is recorded in dispatch_info. + if (!dispatch_info.dispatch ()) + { + // Check for removed handlers. + if (dispatch_info.event_handler_ == 0) + { + this->handler_rep_.unbind(dispatch_info.handle_, + dispatch_info.mask_); + } + + + return 0; + } + + // Suspend the handler so that other threads don't start dispatching + // it, if we can't suspend then return directly + // + // NOTE: This check was performed in older versions of the + // TP_Reactor. Looks like it is a waste.. + if (dispatch_info.event_handler_ != this->notify_handler_) + if (this->suspend_i (dispatch_info.handle_) == -1) + return 0; + + // Call add_reference() if needed. + if (dispatch_info.reference_counting_required_) + dispatch_info.event_handler_->add_reference (); + + // Release the lock. Others threads can start waiting. + guard.release_token (); + + int result = 0; + + // If there was an event handler ready, dispatch it. + // Decrement the event left + --event_count; + + // Dispatched an event + if (this->dispatch_socket_event (dispatch_info) == 0) + ++result; + + return result; +} + +int +ACE_TP_Reactor::get_event_for_dispatching (ACE_Time_Value *max_wait_time) +{ + // If the reactor handler state has changed, clear any remembered + // ready bits and re-scan from the master wait_set. + if (this->state_changed_) + { + this->ready_set_.rd_mask_.reset (); + this->ready_set_.wr_mask_.reset (); + this->ready_set_.ex_mask_.reset (); + + this->state_changed_ = false; + } + else + { + // This is a hack... somewhere, under certain conditions (which + // I don't understand...) the mask will have all of its bits clear, + // yet have a size_ > 0. This is an attempt to remedy the affect, + // without knowing why it happens. + + this->ready_set_.rd_mask_.sync (this->ready_set_.rd_mask_.max_set ()); + this->ready_set_.wr_mask_.sync (this->ready_set_.wr_mask_.max_set ()); + this->ready_set_.ex_mask_.sync (this->ready_set_.ex_mask_.max_set ()); + } + + return this->wait_for_multiple_events (this->ready_set_, max_wait_time); +} + +int +ACE_TP_Reactor::get_socket_event_info (ACE_EH_Dispatch_Info &event) +{ + // Check for dispatch in write, except, read. Only catch one, but if + // one is caught, be sure to clear the handle from each mask in case + // there is more than one mask set for it. This would cause problems + // if the handler is suspended for dispatching, but its set bit in + // another part of ready_set_ kept it from being dispatched. + int found_io = 0; + ACE_HANDLE handle; + + // @@todo: We can do quite a bit of code reduction here. Let me get + // it to work before I do this. + { + ACE_Handle_Set_Iterator handle_iter (this->ready_set_.wr_mask_); + + while (!found_io && (handle = handle_iter ()) != ACE_INVALID_HANDLE) + { + if (this->is_suspended_i (handle)) + continue; + + // Remember this info + event.set (handle, + this->handler_rep_.find (handle), + ACE_Event_Handler::WRITE_MASK, + &ACE_Event_Handler::handle_output); + + this->clear_handle_read_set (handle); + found_io = 1; + } + } + + if (!found_io) + { + ACE_Handle_Set_Iterator handle_iter (this->ready_set_.ex_mask_); + + while (!found_io && (handle = handle_iter ()) != ACE_INVALID_HANDLE) + { + if (this->is_suspended_i (handle)) + continue; + + // Remember this info + event.set (handle, + this->handler_rep_.find (handle), + ACE_Event_Handler::EXCEPT_MASK, + &ACE_Event_Handler::handle_exception); + + this->clear_handle_read_set (handle); + + found_io = 1; + } + } + + if (!found_io) + { + ACE_Handle_Set_Iterator handle_iter (this->ready_set_.rd_mask_); + + while (!found_io && (handle = handle_iter ()) != ACE_INVALID_HANDLE) + { + if (this->is_suspended_i (handle)) + continue; + + // Remember this info + event.set (handle, + this->handler_rep_.find (handle), + ACE_Event_Handler::READ_MASK, + &ACE_Event_Handler::handle_input); + + this->clear_handle_read_set (handle); + found_io = 1; + } + } + + return found_io; +} + +// Dispatches a single event handler +int +ACE_TP_Reactor::dispatch_socket_event (ACE_EH_Dispatch_Info &dispatch_info) +{ + ACE_TRACE ("ACE_TP_Reactor::dispatch_socket_event"); + + ACE_Event_Handler * const event_handler = dispatch_info.event_handler_; + ACE_EH_PTMF const callback = dispatch_info.callback_; + + // Check for removed handlers. + if (event_handler == 0) + return -1; + + // Upcall. If the handler returns positive value (requesting a + // reactor callback) don't set the ready-bit because it will be + // ignored if the reactor state has changed. Just call back + // as many times as the handler requests it. Other threads are off + // handling other things. + int status = 1; + while (status > 0) + status = (event_handler->*callback) (dispatch_info.handle_); + + // Post process socket event + return this->post_process_socket_event (dispatch_info, status); +} + +int +ACE_TP_Reactor::post_process_socket_event (ACE_EH_Dispatch_Info &dispatch_info, + int status) +{ + int result = 0; + + // First check if we really have to post process something, if not, then + // we don't acquire the token which saves us a lot of time. + if (status < 0 || + (dispatch_info.event_handler_ != this->notify_handler_ && + dispatch_info.resume_flag_ == + ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER)) + { + // Get the reactor token and with this token acquired remove first the + // handler and resume it at the same time. This must be atomic, see also + // bugzilla 2395. When this is not atomic it can be that we resume the + // handle after it is reused by the OS. + ACE_TP_Token_Guard guard (this->token_); + + result = guard.acquire_token (); + + // If the guard is NOT the owner just return the retval + if (!guard.is_owner ()) + return result; + + // A different event handler may have been registered during the + // upcall if the handle was closed and then reopened, for + // example. Make sure we're removing and/or resuming the event + // handler used during the upcall. + ACE_Event_Handler const * const eh = + this->handler_rep_.find (dispatch_info.handle_); + + // Only remove or resume the event handler used during the + // upcall. + if (eh == dispatch_info.event_handler_) + { + if (status < 0) + { + result = + this->remove_handler_i (dispatch_info.handle_, + dispatch_info.mask_); + } + + // Resume handler if required. + if (dispatch_info.event_handler_ != this->notify_handler_ && + dispatch_info.resume_flag_ == + ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER) + this->resume_i (dispatch_info.handle_); + } + } + + // Call remove_reference() if needed. + if (dispatch_info.reference_counting_required_) + dispatch_info.event_handler_->remove_reference (); + + return result; +} + +int +ACE_TP_Reactor::resumable_handler (void) +{ + return 1; +} + +int +ACE_TP_Reactor::handle_events (ACE_Time_Value &max_wait_time) +{ + return this->handle_events (&max_wait_time); +} + +void +ACE_TP_Reactor::notify_handle (ACE_HANDLE, + ACE_Reactor_Mask, + ACE_Handle_Set &, + ACE_Event_Handler *eh, + ACE_EH_PTMF) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_TP_Reactor::notify_handle: ") + ACE_TEXT ("Wrong version of notify_handle() got called \n"))); + + ACE_ASSERT (eh == 0); + ACE_UNUSED_ARG (eh); +} + +ACE_HANDLE +ACE_TP_Reactor::get_notify_handle (void) +{ + // Call the notify handler to get a handle on which we would have a + // notify waiting + ACE_HANDLE const read_handle = + this->notify_handler_->notify_handle (); + + // Check whether the rd_mask has been set on that handle. If so + // return the handle. + if (read_handle != ACE_INVALID_HANDLE && + this->ready_set_.rd_mask_.is_set (read_handle)) + { + return read_handle; + } + + // None found.. + return ACE_INVALID_HANDLE; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/TP_Reactor.h b/dep/ACE_wrappers/ace/TP_Reactor.h new file mode 100644 index 000000000..a5994017e --- /dev/null +++ b/dep/ACE_wrappers/ace/TP_Reactor.h @@ -0,0 +1,320 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TP_Reactor.h + * + * $Id: TP_Reactor.h 82393 2008-07-23 10:52:34Z johnnyw $ + * + * The ACE_TP_Reactor (aka, Thread Pool Reactor) uses the + * Leader/Followers pattern to demultiplex events among a pool of + * threads. When using a thread pool reactor, an application + * pre-spawns a fixed number of threads. When these threads + * invoke the ACE_TP_Reactor's handle_events() method, one thread + * will become the leader and wait for an event. The other + * follower threads will queue up waiting for their turn to become + * the leader. When an event occurs, the leader will pick a + * follower to become the leader and go on to handle the event. + * The consequence of using ACE_TP_Reactor is the amortization of + * the costs used to create threads. The context switching cost + * will also reduce. Moreover, the total resources used by + * threads are bounded because there are a fixed number of threads. + * + * @author Irfan Pyarali + * @author Nanbor Wang + */ +//============================================================================= + + +#ifndef ACE_TP_REACTOR_H +#define ACE_TP_REACTOR_H + +#include /**/ "ace/pre.h" + +#include "ace/Select_Reactor.h" +#include "ace/Timer_Queue.h" /* Simple forward decl won't work... */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_EH_Dispatch_Info + * + * @brief This structure contains information of the activated event + * handler. + */ +class ACE_EH_Dispatch_Info +{ +public: + ACE_EH_Dispatch_Info (void); + + void set (ACE_HANDLE handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + ACE_EH_PTMF callback); + + bool dispatch (void) const; + + ACE_HANDLE handle_; + ACE_Event_Handler *event_handler_; + ACE_Reactor_Mask mask_; + ACE_EH_PTMF callback_; + int resume_flag_; + bool reference_counting_required_; + +private: + bool dispatch_; + + // Disallow copying and assignment. + ACE_EH_Dispatch_Info (const ACE_EH_Dispatch_Info &); + ACE_EH_Dispatch_Info &operator= (const ACE_EH_Dispatch_Info &); +}; + + +/** + * @class ACE_TP_Token_Guard + * + * @brief A helper class that helps grabbing, releasing and waiting + * on tokens for a thread that tries calling handle_events (). + * + * In short, this class will be owned by one thread by creating on the + * stack. This class gives the status of the ownership of the token + * and manages the ownership + */ + +class ACE_TP_Token_Guard +{ +public: + + /// Constructor that will grab the token for us + ACE_TP_Token_Guard (ACE_Select_Reactor_Token &token); + + /// Destructor. This will release the token if it hasnt been + /// released till this point + ~ACE_TP_Token_Guard (void); + + /// Release the token .. + void release_token (void); + + /// Returns whether the thread that created this object ownes the + /// token or not. + bool is_owner (void); + + /// A helper method that grabs the token for us, after which the + /// thread that owns that can do some actual work. + int acquire_read_token (ACE_Time_Value *max_wait_time = 0); + + /** + * A helper method that grabs the token for us, after which the + * thread that owns that can do some actual work. This differs from + * acquire_read_token() as it uses acquire () to get the token instead of + * acquire_read () + */ + int acquire_token (ACE_Time_Value *max_wait_time = 0); + +private: + + // Disallow default construction. + ACE_TP_Token_Guard (void); + + // Disallow copying and assignment. + ACE_TP_Token_Guard (const ACE_TP_Token_Guard &); + ACE_TP_Token_Guard &operator= (const ACE_TP_Token_Guard &); + +private: + + /// The Select Reactor token. + ACE_Select_Reactor_Token &token_; + + /// Flag that indicate whether the thread that created this object + /// owns the token or not. A value of false indicates that this class + /// hasnt got the token (and hence the thread) and a value of true + /// vice-versa. + bool owner_; + +}; + +/** + * @class ACE_TP_Reactor + * + * @brief Specialization of ACE_Select_Reactor to support thread-pool + * based event dispatching. + * + * One of the shortcomings of the ACE_Select_Reactor is that it + * does not support a thread pool-based event dispatching model, + * similar to the one in ACE_WFMO_Reactor. In ACE_Select_Reactor, only + * thread can call handle_events() at any given time. ACE_TP_Reactor + * removes this short-coming. + * + * ACE_TP_Reactor is a specialization of ACE_Select_Reactor to support + * thread pool-based event dispatching. This reactor takes advantage + * of the fact that events reported by @c select() are persistent if not + * acted upon immediately. It works by remembering the event handler + * which was just activated, suspending it for further I/O activities, + * releasing the internal lock (so that another thread can start waiting + * in the event loop) and then dispatching the event's handler outside the + * scope of the reactor lock. After the event handler has been dispatched + * the event handler is resumed for further I/O activity. + * + * This reactor implementation is best suited for situations when the + * callbacks to event handlers can take arbitrarily long and/or a number + * of threads are available to run the event loop. Note that I/O-processing + * callback code in event handlers (e.g. handle_input()) does not have to + * be modified or made thread-safe for this reactor. This is because + * before an I/O event is dispatched to an event handler, the handler is + * suspended; it is resumed by the reactor after the upcall completes. + * Therefore, multiple I/O events will not be made to one event handler + * multiple threads simultaneously. This suspend/resume protection does not + * apply to either timers scheduled with the reactor or to notifications + * requested via the reactor. When using timers and/or notifications you + * must provide proper protection for your class in the context of multiple + * threads. + */ +class ACE_Export ACE_TP_Reactor : public ACE_Select_Reactor +{ +public: + + /// Initialize ACE_TP_Reactor with the default size. + ACE_TP_Reactor (ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + bool mask_signals = true, + int s_queue = ACE_Select_Reactor_Token::FIFO); + + /** + * Initialize the ACE_TP_Reactor to manage + * @a max_number_of_handles. If @a restart is non-0 then the + * ACE_Reactor's @c handle_events() method will be restarted + * automatically when @c EINTR occurs. If @a sh or + * @a tq are non-0 they are used as the signal handler and + * timer queue, respectively. + */ + ACE_TP_Reactor (size_t max_number_of_handles, + int restart = 0, + ACE_Sig_Handler *sh = 0, + ACE_Timer_Queue *tq = 0, + bool mask_signals = true, + int s_queue = ACE_Select_Reactor_Token::FIFO); + + /** + * This event loop driver that blocks for @a max_wait_time before + * returning. It will return earlier if timer events, I/O events, + * or signal events occur. Note that @a max_wait_time can be 0, in + * which case this method blocks indefinitely until events occur. + * + * @a max_wait_time is decremented to reflect how much time this call + * took. For instance, if a time value of 3 seconds is passed to + * handle_events and an event occurs after 2 seconds, + * @a max_wait_time will equal 1 second. This can be used if an + * application wishes to handle events for some fixed amount of + * time. + * + * @return The total number of events that were dispatched; 0 if the + * @a max_wait_time elapsed without dispatching any handlers, or -1 + * if an error occurs (check @c errno for more information). + */ + virtual int handle_events (ACE_Time_Value *max_wait_time = 0); + + virtual int handle_events (ACE_Time_Value &max_wait_time); + + /// Does the reactor allow the application to resume the handle on + /// its own ie. can it pass on the control of handle resumption to + /// the application. The TP reactor has can allow applications to + /// resume handles. So return a positive value. + virtual int resumable_handler (void); + + /// Called from handle events + static void no_op_sleep_hook (void *); + + /// The ACE_TP_Reactor implementation does not have a single owner thread. + /// Attempts to set the owner explicitly are ignored. The reported owner + /// thread is the current Leader in the pattern. + virtual int owner (ACE_thread_t n_id, ACE_thread_t *o_id = 0); + + /// Return the thread ID of the current Leader. + virtual int owner (ACE_thread_t *t_id); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Internal methods that do the actual work. + + /// Template method from the base class. + virtual void clear_dispatch_mask (ACE_HANDLE handle, + ACE_Reactor_Mask mask); + + /// Dispatch just 1 signal, timer, notification handlers + int dispatch_i (ACE_Time_Value *max_wait_time, + ACE_TP_Token_Guard &guard); + + /// Get the event that needs dispatching. It could be either a + /// signal, timer, notification handlers or return possibly 1 I/O + /// handler for dispatching. In the most common use case, this would + /// return 1 I/O handler for dispatching + int get_event_for_dispatching (ACE_Time_Value *max_wait_time); + +#if 0 + // @Ciju + // signal handling isn't in a production state yet. + // Commenting it out for now. + + /// Method to handle signals + /// @note It is just busted at this point in time. + int handle_signals (int &event_count, + ACE_TP_Token_Guard &g); +#endif // #if 0 + + /// Handle timer events + int handle_timer_events (int &event_count, + ACE_TP_Token_Guard &g); + + /// Handle notify events + int handle_notify_events (int &event_count, + ACE_TP_Token_Guard &g); + + /// handle socket events + int handle_socket_events (int &event_count, + ACE_TP_Token_Guard &g); + + /// This method shouldn't get called. + virtual void notify_handle (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Handle_Set &, + ACE_Event_Handler *eh, + ACE_EH_PTMF callback); +private: + + /// Get the handle of the notify pipe from the ready set if there is + /// an event in the notify pipe. + ACE_HANDLE get_notify_handle (void); + + /// Get socket event dispatch information. + int get_socket_event_info (ACE_EH_Dispatch_Info &info); + + /// Notify the appropriate in the context of the + /// associated with that a particular event has occurred. + int dispatch_socket_event (ACE_EH_Dispatch_Info &dispatch_info); + + /// Clear the @a handle from the read_set + void clear_handle_read_set (ACE_HANDLE handle); + + int post_process_socket_event (ACE_EH_Dispatch_Info &dispatch_info,int status); + +private: + /// Deny access since member-wise won't work... + ACE_TP_Reactor (const ACE_TP_Reactor &); + ACE_TP_Reactor &operator = (const ACE_TP_Reactor &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/TP_Reactor.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_TP_REACTOR_H */ diff --git a/dep/ACE_wrappers/ace/TP_Reactor.inl b/dep/ACE_wrappers/ace/TP_Reactor.inl new file mode 100644 index 000000000..2b14a8c9b --- /dev/null +++ b/dep/ACE_wrappers/ace/TP_Reactor.inl @@ -0,0 +1,119 @@ +// -*- C++ -*- +// +// $Id: TP_Reactor.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/************************************************************************/ +// Methods for ACE_EH_Dispatch_Info +/************************************************************************/ + +ACE_INLINE +ACE_EH_Dispatch_Info::ACE_EH_Dispatch_Info (void) : + handle_ (ACE_INVALID_HANDLE), + event_handler_ (0), + mask_ (ACE_Event_Handler::NULL_MASK), + callback_ (0), + resume_flag_ (ACE_Event_Handler::ACE_REACTOR_RESUMES_HANDLER), + reference_counting_required_ (false), + dispatch_ (false) +{ +} + +ACE_INLINE void +ACE_EH_Dispatch_Info::set (ACE_HANDLE handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + ACE_EH_PTMF callback) +{ + this->dispatch_ = true; + + this->handle_ = handle; + this->event_handler_ = event_handler; + this->mask_ = mask; + this->callback_ = callback; + if (event_handler_) + { + this->resume_flag_ = event_handler->resume_handler (); + this->reference_counting_required_ = + (event_handler_->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED); + } + else + this->dispatch_ = false; +} + +ACE_INLINE bool +ACE_EH_Dispatch_Info::dispatch (void) const +{ + return this->dispatch_; +} + +/************************************************************************/ +// Methods for ACE_TP_Token_Guard +/************************************************************************/ + +ACE_INLINE +ACE_TP_Token_Guard::ACE_TP_Token_Guard (ACE_Select_Reactor_Token &token) + + : token_ (token), + owner_ (false) +{ +} + +ACE_INLINE +ACE_TP_Token_Guard::~ACE_TP_Token_Guard (void) +{ + if (this->owner_) + { + ACE_MT (this->token_.release ()); + this->owner_ = false; + } +} + +ACE_INLINE void +ACE_TP_Token_Guard::release_token (void) +{ + if (this->owner_) + { + ACE_MT (this->token_.release ()); + + // We are not the owner anymore.. + this->owner_ = false; + } +} + +ACE_INLINE bool +ACE_TP_Token_Guard::is_owner (void) +{ + return this->owner_; +} + + +/************************************************************************/ +// Methods for ACE_TP_Reactor +/************************************************************************/ + +ACE_INLINE void +ACE_TP_Reactor::no_op_sleep_hook (void *) +{ +} + +ACE_INLINE void +ACE_TP_Reactor::clear_handle_read_set (ACE_HANDLE handle) +{ + this->ready_set_.wr_mask_.clr_bit (handle); + this->ready_set_.ex_mask_.clr_bit (handle); + this->ready_set_.rd_mask_.clr_bit (handle); +} + +ACE_INLINE void +ACE_TP_Reactor::clear_dispatch_mask (ACE_HANDLE , + ACE_Reactor_Mask ) +{ + this->ready_set_.rd_mask_.reset (); + this->ready_set_.wr_mask_.reset (); + this->ready_set_.ex_mask_.reset (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/TSS_Adapter.cpp b/dep/ACE_wrappers/ace/TSS_Adapter.cpp new file mode 100644 index 000000000..da6218ddd --- /dev/null +++ b/dep/ACE_wrappers/ace/TSS_Adapter.cpp @@ -0,0 +1,45 @@ +/** + * @file TSS_Adapter.cpp + * + * $Id: TSS_Adapter.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt + */ + +#include "ace/TSS_Adapter.h" + +ACE_RCSID(ace, TSS_Adapter, "$Id: TSS_Adapter.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_TSS_Adapter::ACE_TSS_Adapter (void *object, ACE_THR_DEST f) + : ts_obj_ (object), + func_ (f) +{ + // ACE_TRACE ("ACE_TSS_Adapter::ACE_TSS_Adapter"); +} + +void +ACE_TSS_Adapter::cleanup (void) +{ + // ACE_TRACE ("ACE_TSS_Adapter::cleanup"); + (*this->func_)(this->ts_obj_); // call cleanup routine for ts_obj_ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +extern "C" void +ACE_TSS_C_cleanup (void *object) +{ + // ACE_TRACE ("ACE_TSS_C_cleanup"); + if (object != 0) + { + ACE_TSS_Adapter * const tss_adapter = (ACE_TSS_Adapter *) object; + // Perform cleanup on the real TS object. + tss_adapter->cleanup (); + // Delete the adapter object. + delete tss_adapter; + } +} diff --git a/dep/ACE_wrappers/ace/TSS_Adapter.h b/dep/ACE_wrappers/ace/TSS_Adapter.h new file mode 100644 index 000000000..b8ff85e32 --- /dev/null +++ b/dep/ACE_wrappers/ace/TSS_Adapter.h @@ -0,0 +1,61 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file TSS_Adapter.h + * + * $Id: TSS_Adapter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Originally in Synch.h + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_TSS_ADAPTER_H +#define ACE_TSS_ADAPTER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_TSS_Adapter + * + * @brief This class encapsulates a TSS object and its associated + * C++ destructor function. It is used by the ACE_TSS... + * methods (in Synch_T.cpp) in order to allow an extern + * "C" cleanup routine to be used. Needed by the "frigging" + * MVS C++ compiler. + * + * Objects of this class are stored in thread specific + * storage. ts_obj_ points to the "real" object and + * func_ is a pointer to the C++ cleanup function for ts_obj_. + */ +class ACE_Export ACE_TSS_Adapter +{ +public: + /// Initialize the adapter. + ACE_TSS_Adapter (void *object, ACE_THR_DEST f); + + /// Perform the cleanup operation. + void cleanup (void); + +//private: + + /// The real TS object. + void * const ts_obj_; + + /// The real cleanup routine for ts_obj; + ACE_THR_DEST func_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_TSS_ADAPTER_H */ diff --git a/dep/ACE_wrappers/ace/TSS_T.cpp b/dep/ACE_wrappers/ace/TSS_T.cpp new file mode 100644 index 000000000..7ef74538a --- /dev/null +++ b/dep/ACE_wrappers/ace/TSS_T.cpp @@ -0,0 +1,725 @@ +// $Id: TSS_T.cpp 82508 2008-08-05 13:52:48Z johnnyw $ + +#ifndef ACE_TSS_T_CPP +#define ACE_TSS_T_CPP + +#include "ace/TSS_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/TSS_T.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Thread.h" +#include "ace/Log_Msg.h" +#include "ace/Guard_T.h" +#include "ace/OS_NS_stdio.h" + +#if defined (ACE_HAS_THR_C_DEST) +# include "ace/TSS_Adapter.h" +#endif /* ACE_HAS_THR_C_DEST */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_TSS) + +template +ACE_TSS::~ACE_TSS (void) +{ +#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) + if (this->once_) + { + ACE_OS::thr_key_detach (this->key_, this); + ACE_OS::thr_keyfree (this->key_); + } +#else // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) + // We own it, we need to delete it. + delete type_; +#endif // defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) +} + +template TYPE * +ACE_TSS::operator-> () const +{ + return this->ts_get (); +} + +template +ACE_TSS::operator TYPE *(void) const +{ + return this->ts_get (); +} + +template TYPE * +ACE_TSS::make_TSS_TYPE (void) const +{ + TYPE *temp = 0; + ACE_NEW_RETURN (temp, + TYPE, + 0); + return temp; +} + +template void +ACE_TSS::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS::dump"); +#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->keylock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("key_ = %d\n"), this->key_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nonce_ = %d"), this->once_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ +#endif /* ACE_HAS_DUMP */ +} + +#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) +#if defined (ACE_HAS_THR_C_DEST) +extern "C" void ACE_TSS_C_cleanup (void *); // defined in Synch.cpp +#endif /* ACE_HAS_THR_C_DEST */ + +template void +ACE_TSS::cleanup (void *ptr) +{ + // Cast this to the concrete TYPE * so the destructor gets called. + delete (TYPE *) ptr; +} + +template int +ACE_TSS::ts_init (void) +{ + // Ensure that we are serialized! + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0); + + // Use the Double-Check pattern to make sure we only create the key + // once! + if (!this->once_) + { + if (ACE_Thread::keycreate (&this->key_, +#if defined (ACE_HAS_THR_C_DEST) + &ACE_TSS_C_cleanup, +#else + &ACE_TSS::cleanup, +#endif /* ACE_HAS_THR_C_DEST */ + (void *) this) != 0) + return -1; // Major problems, this should *never* happen! + else + { + // This *must* come last to avoid race conditions! + this->once_ = true; + return 0; + } + } + + return 0; +} + +template +ACE_TSS::ACE_TSS (TYPE *ts_obj) + : once_ (false), + key_ (ACE_OS::NULL_key) +{ + // If caller has passed us a non-NULL TYPE *, then we'll just use + // this to initialize the thread-specific value. Thus, subsequent + // calls to operator->() will return this value. This is useful + // since it enables us to assign objects to thread-specific data + // that have arbitrarily complex constructors! + + if (ts_obj != 0) + { + if (this->ts_init () == -1) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + // What should we do if this call fails?! +#if defined (ACE_HAS_WINCE) + ::MessageBox (0, + ACE_TEXT ("ACE_Thread::keycreate() failed!"), + ACE_TEXT ("ACE_TSS::ACE_TSS"), + MB_OK); +#else + ACE_OS::fprintf (stderr, + "ACE_Thread::keycreate() failed!"); +#endif /* ACE_HAS_WINCE */ + return; + } + +#if defined (ACE_HAS_THR_C_DEST) + // Encapsulate a ts_obj and it's destructor in an + // ACE_TSS_Adapter. + ACE_TSS_Adapter *tss_adapter = 0; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *) ts_obj, + ACE_TSS::cleanup)); + + // Put the adapter in thread specific storage + if (ACE_Thread::setspecific (this->key_, + (void *) tss_adapter) != 0) + { + delete tss_adapter; + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Thread::setspecific() failed!"))); + } +#else + if (ACE_Thread::setspecific (this->key_, + (void *) ts_obj) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Thread::setspecific() failed!"))); +#endif /* ACE_HAS_THR_C_DEST */ + } +} + +template TYPE * +ACE_TSS::ts_get (void) const +{ + if (!this->once_) + { + // Create and initialize thread-specific ts_obj. + if (const_cast< ACE_TSS < TYPE > * >(this)->ts_init () == -1) + // Seriously wrong.. + return 0; + } + + TYPE *ts_obj = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + + // Get the adapter from thread-specific storage + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + if (ACE_Thread::getspecific (this->key_, &temp) == -1) + return 0; // This should not happen! + tss_adapter = static_cast (temp); + + // Check to see if this is the first time in for this thread. + if (tss_adapter == 0) +#else + // Get the ts_obj from thread-specific storage. Note that no locks + // are required here... + void *temp = ts_obj; // Need this temp to keep G++ from complaining. + if (ACE_Thread::getspecific (this->key_, &temp) == -1) + return 0; // This should not happen! + ts_obj = static_cast (temp); + + // Check to see if this is the first time in for this thread. + if (ts_obj == 0) +#endif /* ACE_HAS_THR_C_DEST */ + { + // Allocate memory off the heap and store it in a pointer in + // thread-specific storage (on the stack...). + + ts_obj = this->make_TSS_TYPE (); + + if (ts_obj == 0) + return 0; + +#if defined (ACE_HAS_THR_C_DEST) + // Encapsulate a ts_obj and it's destructor in an + // ACE_TSS_Adapter. + ACE_NEW_RETURN (tss_adapter, + ACE_TSS_Adapter (ts_obj, + ACE_TSS::cleanup), 0); + + // Put the adapter in thread specific storage + if (ACE_Thread::setspecific (this->key_, + (void *) tss_adapter) != 0) + { + delete tss_adapter; + delete ts_obj; + return 0; // Major problems, this should *never* happen! + } +#else + // Store the dynamically allocated pointer in thread-specific + // storage. + if (ACE_Thread::setspecific (this->key_, + (void *) ts_obj) != 0) + { + delete ts_obj; + return 0; // Major problems, this should *never* happen! + } +#endif /* ACE_HAS_THR_C_DEST */ + } + +#if defined (ACE_HAS_THR_C_DEST) + // Return the underlying ts object. + return static_cast (tss_adapter->ts_obj_); +#else + return ts_obj; +#endif /* ACE_HAS_THR_C_DEST */ +} + +// Get the thread-specific object for the key associated with this +// object. Returns 0 if the ts_obj has never been initialized, +// otherwise returns a pointer to the ts_obj. + +template TYPE * +ACE_TSS::ts_object (void) const +{ + if (!this->once_) // Return 0 if we've never been initialized. + return 0; + + TYPE *ts_obj = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + + // Get the tss adapter from thread-specific storage + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + if (ACE_Thread::getspecific (this->key_, &temp) == -1) + { + return 0; // This should not happen! + } + else + { + tss_adapter = static_cast (temp); + { + if (tss_adapter != 0) + // Extract the real TS object. + ts_obj = static_cast (tss_adapter->ts_obj_); + } + } +#else + void *temp = ts_obj; // Need this temp to keep G++ from complaining. + if (ACE_Thread::getspecific (this->key_, &temp) == -1) + return 0; // This should not happen! + ts_obj = static_cast (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return ts_obj; +} + +template TYPE * +ACE_TSS::ts_object (TYPE *new_ts_obj) +{ + // Note, we shouldn't hold the keylock at this point because + // does it for us and we'll end up with deadlock + // otherwise... + if (!this->once_) + { + // Create and initialize thread-specific ts_obj. + if (this->ts_init () == -1) + return 0; + } + + TYPE *ts_obj = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + if (ACE_Thread::getspecific (this->key_, &temp) == -1) + return 0; // This should not happen! + tss_adapter = static_cast (temp); + + if (tss_adapter != 0) + { + ts_obj = static_cast (tss_adapter->ts_obj_); + delete tss_adapter; // don't need this anymore + } + + ACE_NEW_RETURN (tss_adapter, + ACE_TSS_Adapter ((void *) new_ts_obj, + ACE_TSS::cleanup), + 0); + + if (ACE_Thread::setspecific (this->key_, + (void *) tss_adapter) == -1) + { + delete tss_adapter; + return ts_obj; // This should not happen! + } +#else + void *temp = ts_obj; // Need this temp to keep G++ from complaining. + if (ACE_Thread::getspecific (this->key_, &temp) == -1) + return 0; // This should not happen! + ts_obj = static_cast (temp); + if (ACE_Thread::setspecific (this->key_, (void *) new_ts_obj) == -1) + return ts_obj; // This should not happen! +#endif /* ACE_HAS_THR_C_DEST */ + + return ts_obj; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard) + +template void +ACE_TSS_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS_Guard::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("key_ = %d"), this->key_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template void +ACE_TSS_Guard::init_key (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::init_key"); + + this->key_ = ACE_OS::NULL_key; + ACE_Thread::keycreate (&this->key_, +#if defined (ACE_HAS_THR_C_DEST) + &ACE_TSS_C_cleanup, +#else + &ACE_TSS_Guard::cleanup, +#endif /* ACE_HAS_THR_C_DEST */ + (void *) this); +} + +template +ACE_TSS_Guard::ACE_TSS_Guard (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::ACE_TSS_Guard"); + this->init_key (); +} + +template int +ACE_TSS_Guard::release (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::release"); + + ACE_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->release (); +} + +template int +ACE_TSS_Guard::remove (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::remove"); + + ACE_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->remove (); +} + +template +ACE_TSS_Guard::~ACE_TSS_Guard (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::~ACE_TSS_Guard"); + + ACE_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + // Make sure that this pointer is NULL when we shut down... + ACE_Thread::setspecific (this->key_, 0); + ACE_Thread::keyfree (this->key_); + // Destructor releases lock. + delete guard; +} + +template void +ACE_TSS_Guard::cleanup (void *ptr) +{ +// ACE_TRACE ("ACE_TSS_Guard::cleanup"); + + // Destructor releases lock. + delete (ACE_Guard *) ptr; +} + +template +ACE_TSS_Guard::ACE_TSS_Guard (ACE_LOCK &lock, bool block) +{ +// ACE_TRACE ("ACE_TSS_Guard::ACE_TSS_Guard"); + + this->init_key (); + ACE_Guard *guard = 0; + ACE_NEW (guard, + ACE_Guard (lock, + block)); + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *) guard, + ACE_TSS_Guard::cleanup)); + ACE_Thread::setspecific (this->key_, + (void *) tss_adapter); +#else + ACE_Thread::setspecific (this->key_, + (void *) guard); +#endif /* ACE_HAS_THR_C_DEST */ +} + +template int +ACE_TSS_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::acquire"); + + ACE_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->acquire (); +} + +template int +ACE_TSS_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::tryacquire"); + + ACE_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->tryacquire (); +} + +template +ACE_TSS_Write_Guard::ACE_TSS_Write_Guard (ACE_LOCK &lock, + bool block) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::ACE_TSS_Write_Guard"); + + this->init_key (); + ACE_Guard *guard = 0; + ACE_NEW (guard, + ACE_Write_Guard (lock, + block)); + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *) guard, + ACE_TSS_Guard::cleanup)); + ACE_Thread::setspecific (this->key_, + (void *) tss_adapter); +#else + ACE_Thread::setspecific (this->key_, + (void *) guard); +#endif /* ACE_HAS_THR_C_DEST */ +} + +template int +ACE_TSS_Write_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::acquire"); + + ACE_Write_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->acquire_write (); +} + +template int +ACE_TSS_Write_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::tryacquire"); + + ACE_Write_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->tryacquire_write (); +} + +template int +ACE_TSS_Write_Guard::acquire_write (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::acquire_write"); + + return this->acquire (); +} + +template int +ACE_TSS_Write_Guard::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::tryacquire_write"); + + return this->tryacquire (); +} + +template void +ACE_TSS_Write_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS_Write_Guard::dump"); + ACE_TSS_Guard::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_TSS_Read_Guard::ACE_TSS_Read_Guard (ACE_LOCK &lock, bool block) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::ACE_TSS_Read_Guard"); + + this->init_key (); + ACE_Guard *guard = 0; + ACE_NEW (guard, + ACE_Read_Guard (lock, + block)); +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *)guard, + ACE_TSS_Guard::cleanup)); + ACE_Thread::setspecific (this->key_, + (void *) tss_adapter); +#else + ACE_Thread::setspecific (this->key_, + (void *) guard); +#endif /* ACE_HAS_THR_C_DEST */ +} + +template int +ACE_TSS_Read_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::acquire"); + + ACE_Read_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->acquire_read (); +} + +template int +ACE_TSS_Read_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::tryacquire"); + + ACE_Read_Guard *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + void *temp = tss_adapter; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + tss_adapter = static_cast (temp); + guard = static_cast *> (tss_adapter->ts_obj_); +#else + void *temp = guard; // Need this temp to keep G++ from complaining. + ACE_Thread::getspecific (this->key_, &temp); + guard = static_cast *> (temp); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->tryacquire_read (); +} + +template int +ACE_TSS_Read_Guard::acquire_read (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::acquire_read"); + + return this->acquire (); +} + +template int +ACE_TSS_Read_Guard::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::tryacquire_read"); + + return this->tryacquire (); +} + +template void +ACE_TSS_Read_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS_Read_Guard::dump"); + ACE_TSS_Guard::dump (); +#endif /* ACE_HAS_DUMP */ +} + +#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TSS_T_CPP */ diff --git a/dep/ACE_wrappers/ace/TSS_T.h b/dep/ACE_wrappers/ace/TSS_T.h new file mode 100644 index 000000000..f9ffaa92f --- /dev/null +++ b/dep/ACE_wrappers/ace/TSS_T.h @@ -0,0 +1,253 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file TSS_T.h + * + * $Id: TSS_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_TSS_T_H +#define ACE_TSS_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// This should probably go somewhere else, but it's only used here and +// in Thread_Manager. +// Note there is no ACE_TSS_SET because one would typicaly do +// 'ACE_TSS_GET()->xyz_ = value', so the macro would have been too +// complicated. +# if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) +# define ACE_TSS_TYPE(T) ACE_TSS< T > +# define ACE_TSS_GET(I, T) ((I)->operator T * ()) +# else +# define ACE_TSS_TYPE(T) T +# define ACE_TSS_GET(I, T) (I) +# endif /* ACE_HAS_THREADS && (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) */ + +#include "ace/Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_TSS + * + * @brief Allows objects that are "physically" in thread specific + * storage (i.e., private to a thread) to be accessed as though + * they were "logically" global to a program. + * + * This class helps to maintain a separate copy of an object for each thread + * that needs access to it. All threads access a single instance of ACE_TSS + * to obtain a pointer to a thread-specific copy of a TYPE object. Using + * a pointer to TYPE in TSS instead of TYPE itself is useful because, + * in addition to avoiding copies on what may be a complex class, it allows + * assignment of objects to thread-specific data that have arbitrarily + * complex constructors. + * + * When the ACE_TSS object is destroyed, all threads's instances of the + * data are deleted. + * + * Modern compilers have no problem using a built-in type for @c TYPE. + * However, if you must use an older compiler that won't work with a built-in + * type, the ACE_TSS_Type_Adapter class template, below, can be used for + * adapting built-in types to work with ACE_TSS. + * + * @note Beware when creating static instances of this type + * (as with any other, btw). The unpredictable order of initialization + * across different platforms may cause a situation where one uses + * the instance before it is fully initialized. That's why typically + * instances of this type are dynamicaly allocated. On the stack it is + * typically allocated inside the ACE_Thread::svc() method which + * limits its lifetime appropriately. + * + */ +template +class ACE_TSS +{ +public: + /** + * Default constructor. Can also initialize this ACE_TSS instance, + * readying it for use by the calling thread as well as all other + * threads in the process. If the constructor does not initialize this + * object, the first access to it will perform the initialization, which + * could possibly (under odd error conditions) fail. + * + * @param ts_obj If non-zero, this object is initialized for use by + * all threads and @a ts_obj is used to set the + * thread-specific value for the calling thread. Other + * threads use the ts_object (TYPE *) method to set + * a specific value. + */ + ACE_TSS (TYPE *ts_obj = 0); + + /// Deregister this object from thread-specific storage administration. + /// Will cause all threads' copies of TYPE to be destroyed. + virtual ~ACE_TSS (void); + + /** + * Set the thread-specific object for the calling thread. + * If this object has not been initialized yet, this method performs the + * initialization. + * + * @param new_ts_obj The new value for the calling thread's copy of + * this object. + * + * @return The previous value of the calling thread's copy of this + * object; 0 if there was no previous value. This method also + * returns 0 on errors. To tell the difference between an error + * and a returned 0 pointer, it's recommended that one set errno + * to 0 prior to calling ts_object() and check for a new errno + * value if ts_object() returns 0. + */ + TYPE *ts_object (TYPE *new_ts_obj); + + /** @name Accessors + * + * All accessors return a pointer to the calling thread's copy of the + * TYPE data. The pointer may be 0 on error conditions or if the calling + * thread's copy of the data has not yet been set. See specific method + * descriptions for complete details. + */ + //@{ + /** + * Get the thread-specific object for this object. + * + * @return 0 if the object has never been initialized, otherwise returns + * the calling thread's copy of the data. The returned pointer + * may be 0 under odd error conditions; check errno for further + * information. + */ + TYPE *ts_object (void) const; + + /** + * Use a "smart pointer" to get the thread-specific data associated + * with this object. + * If this ACE_TSS object hasn't been initialized, this method + * will initialize it as a side-affect. If the calling thread has not + * set a value, a default-constructed instance of TYPE is allocated and it + * becomes the thread's instance. + * + * @return The calling thread's copy of the data. The returned pointer + * may be 0 under odd error conditions; check errno for further + * information. + */ + TYPE *operator-> () const; + + /** + * Obtain a pointer to the calling thread's TYPE object. + * If this ACE_TSS object hasn't been initialized, this method + * will initialize it as a side-affect. If the calling thread has not + * set a value, a default-constructed instance of TYPE is allocated and it + * becomes the thread's instance. + * + * @return The calling thread's copy of the data. The returned pointer + * may be 0 under odd error conditions; check errno for further + * information. + */ + operator TYPE *(void) const; + + //@} + + /// Hook for construction parameters. + virtual TYPE *make_TSS_TYPE (void) const; + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + /// Actually implements the code that retrieves the object from + /// thread-specific storage. + TYPE *ts_get (void) const; + + /// Factors out common code for initializing TSS. This must NOT be + /// called with the lock held... + int ts_init (void); + +#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) + /// This implementation only works for non-threading systems... + TYPE *type_; +#else + /// Avoid race conditions during initialization. + ACE_Thread_Mutex keylock_; + + /// "First time in" flag. + volatile bool once_; + + /// Key for the thread-specific error data. + ACE_thread_key_t key_; + + /// "Destructor" that deletes internal TYPE * when thread exits. + static void cleanup (void *ptr); +#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ + // = Disallow copying... + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS &)) + ACE_UNIMPLEMENTED_FUNC (ACE_TSS (const ACE_TSS &)) +}; + +/** + * @class ACE_TSS_Type_Adapter + * + * @brief Adapter that allows built-in types to be used with ACE_TSS. + * + * Wraps a value of a built-in type, providing conversions to + * and from the type. Example use with ACE_TSS: + * ACE_TSS > i; + * *i = 37; + * ACE_OS::fprintf (stderr, "%d\n", *i); + * Unfortunately, though, some compilers have trouble with the + * implicit type conversions. This seems to work better: + * ACE_TSS > i; + * i->operator int & () = 37; + * ACE_OS::fprintf (stderr, "%d\n", i->operator int ()); + */ +template +class ACE_TSS_Type_Adapter +{ +public: + /// Constructor. Inlined here so that it should _always_ be inlined. + ACE_TSS_Type_Adapter (const TYPE value = 0): value_ (value) {} + + /// TYPE conversion. Inlined here so that it should _always_ be + /// inlined. + operator TYPE () const { return value_; }; + + /// TYPE & conversion. Inlined here so that it should _always_ be + /// inlined. + operator TYPE &() { return value_; }; + +private: + /// The wrapped value. + TYPE value_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/TSS_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/TSS_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("TSS_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TSS_T_H */ diff --git a/dep/ACE_wrappers/ace/TSS_T.inl b/dep/ACE_wrappers/ace/TSS_T.inl new file mode 100644 index 000000000..9959a2edd --- /dev/null +++ b/dep/ACE_wrappers/ace/TSS_T.inl @@ -0,0 +1,42 @@ +// -*- C++ -*- +// +// $Id: TSS_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_TSS::ACE_TSS (TYPE *type) + : type_ (type) +{ +} + +template ACE_INLINE int +ACE_TSS::ts_init (void) +{ + return 0; +} + +template ACE_INLINE TYPE * +ACE_TSS::ts_object (void) const +{ + return this->type_; +} + +template ACE_INLINE TYPE * +ACE_TSS::ts_object (TYPE *type) +{ + this->type_ = type; + return this->type_; +} + +template ACE_INLINE TYPE * +ACE_TSS::ts_get (void) const +{ + return this->type_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ! (defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ diff --git a/dep/ACE_wrappers/ace/TTY_IO.cpp b/dep/ACE_wrappers/ace/TTY_IO.cpp new file mode 100644 index 000000000..9918ec0dc --- /dev/null +++ b/dep/ACE_wrappers/ace/TTY_IO.cpp @@ -0,0 +1,582 @@ +// $Id: TTY_IO.cpp 82271 2008-07-09 09:23:03Z olli $ + +#include "ace/TTY_IO.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_strings.h" + +#if defined (ACE_HAS_TERMIOS) +# include "ace/os_include/os_termios.h" +#elif defined (ACE_HAS_TERMIO) +# include +#endif + +ACE_RCSID (ace, + TTY_IO, + "$Id: TTY_IO.cpp 82271 2008-07-09 09:23:03Z olli $") + +namespace +{ + const char ACE_TTY_IO_NONE[] = "none"; +#if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO) || defined (ACE_WIN32) + const char ACE_TTY_IO_ODD[] = "odd"; + const char ACE_TTY_IO_EVEN[] = "even"; +#endif +#if defined (ACE_WIN32) + const char ACE_TTY_IO_MARK[] = "mark"; + const char ACE_TTY_IO_SPACE[] = "space"; +#endif /* ACE_WIN32 */ +} + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_TTY_IO::Serial_Params::Serial_Params (void) +{ + baudrate = 9600; + xonlim = 0; + xofflim = 0; + readmincharacters = 0; + readtimeoutmsec = 10000; + paritymode = ACE_TTY_IO_NONE; + ctsenb = false; + rtsenb = 0; + xinenb = false; + xoutenb = false; + modem = false; + rcvenb = true; + dsrenb = false; + dtrdisable = false; + databits = 8; + stopbits = 1; +} + +// Interface for reading/writing serial device parameters + +int ACE_TTY_IO::control (Control_Mode cmd, Serial_Params *arg) const +{ +#if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO) + +#if defined (ACE_HAS_TERMIOS) + struct termios devpar; + speed_t newbaudrate = 0; + if (tcgetattr (get_handle () , &devpar) == -1) +#elif defined (TCGETS) + struct termios devpar; + unsigned int newbaudrate = 0; + if (this->ACE_IO_SAP::control (TCGETS, static_cast(&devpar)) == -1) +#elif defined (TCGETA) + struct termio devpar; + unsigned int newbaudrate = 0; + if (this->ACE_IO_SAP::control (TCGETA, static_cast(&devpar)) == -1) +#else + errno = ENOSYS; +#endif /* ACE_HAS_TERMIOS */ + return -1; + + switch (cmd) + { + case SETPARAMS: + switch (arg->baudrate) + { +#if defined (B0) + case 0: newbaudrate = B0; break; +#endif /* B0 */ +#if defined (B50) + case 50: newbaudrate = B50; break; +#endif /* B50 */ +#if defined (B75) + case 75: newbaudrate = B75; break; +#endif /* B75 */ +#if defined (B110) + case 110: newbaudrate = B110; break; +#endif /* B110 */ +#if defined (B134) + case 134: newbaudrate = B134; break; +#endif /* B134 */ +#if defined (B150) + case 150: newbaudrate = B150; break; +#endif /* B150 */ +#if defined (B200) + case 200: newbaudrate = B200; break; +#endif /* B200 */ +#if defined (B300) + case 300: newbaudrate = B300; break; +#endif /* B300 */ +#if defined (B600) + case 600: newbaudrate = B600; break; +#endif /* B600 */ +#if defined (B1200) + case 1200: newbaudrate = B1200; break; +#endif /* B1200 */ +#if defined (B1800) + case 1800: newbaudrate = B1800; break; +#endif /* B1800 */ +#if defined (B2400) + case 2400: newbaudrate = B2400; break; +#endif /* B2400 */ +#if defined (B4800) + case 4800: newbaudrate = B4800; break; +#endif /* B4800 */ +#if defined (B9600) + case 9600: newbaudrate = B9600; break; +#endif /* B9600 */ +#if defined (B19200) + case 19200: newbaudrate = B19200; break; +#endif /* B19200 */ +#if defined (B38400) + case 38400: newbaudrate = B38400; break; +#endif /* B38400 */ +#if defined (B56000) + case 56000: newbaudrate = B56000; break; +#endif /* B56000 */ +#if defined (B57600) + case 57600: newbaudrate = B57600; break; +#endif /* B57600 */ +#if defined (B76800) + case 76800: newbaudrate = B76800; break; +#endif /* B76800 */ +#if defined (B115200) + case 115200: newbaudrate = B115200; break; +#endif /* B115200 */ +#if defined (B128000) + case 128000: newbaudrate = B128000; break; +#endif /* B128000 */ +#if defined (B153600) + case 153600: newbaudrate = B153600; break; +#endif /* B153600 */ +#if defined (B230400) + case 230400: newbaudrate = B230400; break; +#endif /* B230400 */ +#if defined (B307200) + case 307200: newbaudrate = B307200; break; +#endif /* B307200 */ +#if defined (B256000) + case 256000: newbaudrate = B256000; break; +#endif /* B256000 */ +#if defined (B460800) + case 460800: newbaudrate = B460800; break; +#endif /* B460800 */ +#if defined (B500000) + case 500000: newbaudrate = B500000; break; +#endif /* B500000 */ +#if defined (B576000) + case 576000: newbaudrate = B576000; break; +#endif /* B576000 */ +#if defined (B921600) + case 921600: newbaudrate = B921600; break; +#endif /* B921600 */ +#if defined (B1000000) + case 1000000: newbaudrate = B1000000; break; +#endif /* B1000000 */ +#if defined (B1152000) + case 1152000: newbaudrate = B1152000; break; +#endif /* B1152000 */ +#if defined (B1500000) + case 1500000: newbaudrate = B1500000; break; +#endif /* B1500000 */ +#if defined (B2000000) + case 2000000: newbaudrate = B2000000; break; +#endif /* B2000000 */ +#if defined (B2500000) + case 2500000: newbaudrate = B2500000; break; +#endif /* B2500000 */ +#if defined (B3000000) + case 3000000: newbaudrate = B3000000; break; +#endif /* B3000000 */ +#if defined (B3500000) + case 3500000: newbaudrate = B3500000; break; +#endif /* B3500000 */ +#if defined (B4000000) + case 4000000: newbaudrate = B4000000; break; +#endif /* B4000000 */ + default: + return -1; + } + +#if defined (ACE_HAS_TERMIOS) + // Can you really have different input and output baud rates?! + if (cfsetospeed (&devpar, newbaudrate) == -1) + return -1; + if (cfsetispeed (&devpar, newbaudrate) == -1) + return -1; +#else + devpar.c_cflag &= ~CBAUD; +# if defined (CBAUDEX) + devpar.c_cflag &= ~CBAUDEX; +# endif /* CBAUDEX */ + devpar.c_cflag |= newbaudrate; +#endif /* ACE_HAS_TERMIOS */ + + devpar.c_cflag &= ~CSIZE; + switch (arg->databits) + { + case 5: + devpar.c_cflag |= CS5; + break; + case 6: + devpar.c_cflag |= CS6; + break; + case 7: + devpar.c_cflag |= CS7; + break; + case 8: + devpar.c_cflag |= CS8; + break; + default: + return -1; + } + + switch (arg->stopbits) + { + case 1: + devpar.c_cflag &= ~CSTOPB; + break; + case 2: + devpar.c_cflag |= CSTOPB; + break; + default: + return -1; + } + + if (arg->paritymode) + { + if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0) + { + devpar.c_cflag |= PARENB; + devpar.c_cflag |= PARODD; + } + else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0) + { + devpar.c_cflag |= PARENB; + devpar.c_cflag &= ~PARODD; + } + else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0) + devpar.c_cflag &= ~PARENB; + else + return -1; + } + else + { + devpar.c_cflag &= ~PARENB; + } + +#if defined (CNEW_RTSCTS) + if ((arg->ctsenb) || (arg->rtsenb)) // Enable RTS/CTS protocol + devpar.c_cflag |= CNEW_RTSCTS; + else + devpar.c_cflag &= ~CNEW_RTSCTS; +#elif defined (CRTSCTS) + if ((arg->ctsenb) || (arg->rtsenb)) // Enable RTS/CTS protocol + devpar.c_cflag |= CRTSCTS; + else + devpar.c_cflag &= ~CRTSCTS; +#endif /* NEW_RTSCTS || CRTSCTS */ + +#if defined (CREAD) + // Enable/disable receiver + if (arg->rcvenb) + devpar.c_cflag |= CREAD; + else + devpar.c_cflag &= ~CREAD; +#endif /* CREAD */ + +#if defined (HUPCL) + // Cause DTR to drop after port close. + devpar.c_cflag |= HUPCL; +#endif /* HUPCL */ + +#if defined (CLOCAL) + // If device is not a modem set to local device. + if (arg->modem) + devpar.c_cflag &= ~CLOCAL; + else + devpar.c_cflag |= CLOCAL; +#endif /* CLOCAL */ + + devpar.c_iflag = IGNPAR | INPCK; + if (arg->databits < 8) + devpar.c_iflag |= ISTRIP; + +#if defined (IGNBRK) + // If device is not a modem set to ignore break points + if(arg->modem) + devpar.c_iflag &= ~IGNBRK; + else + devpar.c_iflag |= IGNBRK; +#endif /* IGNBRK */ + +#if defined (IXOFF) + // Enable/disable software flow control on input + if (arg->xinenb) + devpar.c_iflag |= IXOFF; + else + devpar.c_iflag &= ~IXOFF; +#endif /* IXOFF */ + +#if defined (IXON) + // Enable/disable software flow control on output + if (arg->xoutenb) + devpar.c_iflag |= IXON; + else + devpar.c_iflag &= ~IXON; +#endif /* IXON */ + +#if defined (ICANON) + // Enable noncanonical input processing mode + devpar.c_lflag &= ~ICANON; +#endif /* ICANON */ + +#if defined (ECHO) + // Disable echoing of input characters + devpar.c_lflag &= ~ECHO; +#endif /* ECHO */ + +#if defined (ECHOE) + // Disable echoing erase chareacter as BS-SP-BS + devpar.c_lflag &= ~ECHOE; +#endif /* ECHOE */ + +#if defined (ISIG) + // Disable SIGINTR, SIGSUSP, SIGDSUSP and SIGQUIT signals + devpar.c_lflag &= ~ISIG; +#endif /* ISIG */ + +#if defined (OPOST) + // Disable post-processing of output data + devpar.c_oflag &= ~OPOST; +#endif /* OPOST */ + + if (arg->readtimeoutmsec < 0) + { + // Settings for infinite timeout. + devpar.c_cc[VTIME] = 0; + // In case of infinite timeout [VMIN] must be at least 1. + if (arg->readmincharacters > UCHAR_MAX) + devpar.c_cc[VMIN] = UCHAR_MAX; + else if (arg->readmincharacters < 1) + devpar.c_cc[VMIN] = 1; + else + devpar.c_cc[VMIN] = static_cast(arg->readmincharacters); + } + else + { + devpar.c_cc[VTIME] = static_cast(arg->readtimeoutmsec / 100); + + if (arg->readmincharacters > UCHAR_MAX) + devpar.c_cc[VMIN] = UCHAR_MAX; + else if (arg->readmincharacters < 1) + devpar.c_cc[VMIN] = 0; + else + devpar.c_cc[VMIN] = static_cast(arg->readmincharacters); + } + +#if defined (TIOCMGET) + int status; + this->ACE_IO_SAP::control (TIOCMGET, &status); + + if (arg->dtrdisable) + status &= ~TIOCM_DTR; + else + status |= TIOCM_DTR; + + this->ACE_IO_SAP::control (TIOCMSET, &status); +#endif /* definded (TIOCMGET) */ + +#if defined (ACE_HAS_TERMIOS) + return tcsetattr (get_handle (), TCSANOW, &devpar); +#elif defined (TCSETS) + return this->ACE_IO_SAP::control (TCSETS, static_cast(&devpar)); +#elif defined (TCSETA) + return this->ACE_IO_SAP::control (TCSETA, static_cast(&devpar)); +#else + errno = ENOSYS; + return -1; +#endif /* ACE_HAS_TERMIOS */ + + case GETPARAMS: + return -1; // Not yet implemented. + default: + return -1; // Wrong cmd. + } +#elif defined (ACE_WIN32) + switch (cmd) + { + case SETPARAMS: + DCB dcb; + dcb.DCBlength = sizeof dcb; + if (!::GetCommState (this->get_handle (), &dcb)) + { + ACE_OS::set_errno_to_last_error (); + return -1; + } + + dcb.BaudRate = arg->baudrate; + + switch (arg->databits) + { + case 4: + case 5: + case 6: + case 7: + case 8: + dcb.ByteSize = arg->databits; + break; + default: + return -1; + } + + switch (arg->stopbits) + { + case 1: + dcb.StopBits = ONESTOPBIT; + break; + case 2: + dcb.StopBits = TWOSTOPBITS; + break; + default: + return -1; + } + + if (arg->paritymode) + { + dcb.fParity = TRUE; + if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0) + dcb.Parity = ODDPARITY; + else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0) + dcb.Parity = EVENPARITY; + else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0) + dcb.Parity = NOPARITY; + else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_MARK) == 0) + dcb.Parity = MARKPARITY; + else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_SPACE) == 0) + dcb.Parity = SPACEPARITY; + else + return -1; + } + else + { + dcb.fParity = FALSE; + dcb.Parity = NOPARITY; + } + + // Enable/disable RTS protocol. + switch (arg->rtsenb) + { + case 1: + dcb.fRtsControl = RTS_CONTROL_ENABLE; + break; + case 2: + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + break; + case 3: + dcb.fRtsControl = RTS_CONTROL_TOGGLE; + break; + default: + dcb.fRtsControl = RTS_CONTROL_DISABLE; + } + + // Enable/disable CTS protocol. + if (arg->ctsenb) + dcb.fOutxCtsFlow = TRUE; + else + dcb.fOutxCtsFlow = FALSE; + + // Enable/disable DSR protocol. + if (arg->dsrenb) + dcb.fOutxDsrFlow = TRUE; + else + dcb.fOutxDsrFlow = FALSE; + + // Disable/enable DTR protocol + if (arg->dtrdisable) + dcb.fDtrControl = DTR_CONTROL_DISABLE; + else + dcb.fDtrControl = DTR_CONTROL_ENABLE; + + // Enable/disable software flow control on input + if (arg->xinenb) + dcb.fInX = TRUE; + else + dcb.fInX = FALSE; + + // Enable/disable software flow control on output + if (arg->xoutenb) + dcb.fOutX = TRUE; + else + dcb.fOutX = FALSE; + + // Always set limits unless set to negative to use default. + if (arg->xonlim >= 0) + dcb.XonLim = static_cast(arg->xonlim); + if (arg->xofflim >= 0) + dcb.XoffLim = static_cast(arg->xofflim); + + dcb.fAbortOnError = FALSE; + dcb.fErrorChar = FALSE; + dcb.fNull = FALSE; + dcb.fBinary = TRUE; + + if (!::SetCommState (this->get_handle (), &dcb)) + { + ACE_OS::set_errno_to_last_error (); + return -1; + } + + COMMTIMEOUTS timeouts; + if (!::GetCommTimeouts (this->get_handle(), &timeouts)) + { + ACE_OS::set_errno_to_last_error (); + return -1; + } + + if (arg->readtimeoutmsec < 0) + { + // Settings for infinite timeout. + timeouts.ReadIntervalTimeout = 0; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.ReadTotalTimeoutConstant = 0; + } + else if (arg->readtimeoutmsec == 0) + { + // Return immediately if no data in the input buffer. + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.ReadTotalTimeoutConstant = 0; + } + else + { + // Wait for specified timeout for char to arrive before returning. + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + timeouts.ReadTotalTimeoutConstant = arg->readtimeoutmsec; + } + + if (!::SetCommTimeouts (this->get_handle (), &timeouts)) + { + ACE_OS::set_errno_to_last_error (); + return -1; + } + + return 0; + + case GETPARAMS: + ACE_NOTSUP_RETURN (-1); // Not yet implemented. + default: + return -1; // Wrong cmd. + + } // arg switch +#else + ACE_UNUSED_ARG (cmd); + ACE_UNUSED_ARG (arg); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TERMIOS || ACE_HAS_TERMIO */ +} + +#if defined (ACE_NEEDS_DEV_IO_CONVERSION) +ACE_TTY_IO::operator ACE_DEV_IO &() +{ + return static_cast(*this); +} +#endif /* ACE_NEEDS_DEV_IO_CONVERSION */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/TTY_IO.h b/dep/ACE_wrappers/ace/TTY_IO.h new file mode 100644 index 000000000..1029966e5 --- /dev/null +++ b/dep/ACE_wrappers/ace/TTY_IO.h @@ -0,0 +1,113 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TTY_IO.h + * + * $Id: TTY_IO.h 82271 2008-07-09 09:23:03Z olli $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TTY_IO_H +#define ACE_TTY_IO_H + +#include "ace/DEV_IO.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_TTY_IO + * + * @brief Class definitions for platform specific TTY features. + * + * This class represents an example interface for a specific + * device (a serial line). It extends the capability of the + * underlying DEV_IO class by adding a control method that takes + * a special structure (Serial_Params) as argument to allow a + * comfortable user interface (away from that annoying termios + * structure, which is very specific to UNIX). + */ +class ACE_Export ACE_TTY_IO : public ACE_DEV_IO +{ +public: + enum Control_Mode + { + SETPARAMS, ///< Set control parameters. + GETPARAMS ///< Get control parameters. + }; + + struct ACE_Export Serial_Params + { + Serial_Params (void); + + /** Specifies the baudrate at which the communnication port operates. */ + int baudrate; + /** Specifies the minimum number of bytes in input buffer before XON char + is sent. Negative value indicates that default value should + be used (Win32). */ + int xonlim; + /** Specifies the maximum number of bytes in input buffer before XOFF char + is sent. Negative value indicates that default value should + be used (Win32). */ + int xofflim; + /** Specifies the minimum number of characters for non-canonical + read (POSIX). */ + unsigned int readmincharacters; + /** Specifies the time to wait before returning from read. Negative value + means infinite timeout. */ + int readtimeoutmsec; + /** Specifies the parity mode. POSIX supports "none", "even" and + "odd" parity. Additionally Win32 supports "mark" and "space" + parity modes. */ + const char *paritymode; + /** Enable & set CTS mode. Note that RTS & CTS are enabled/disabled + together on some systems (RTS/CTS is enabled if either + ctsenb or rtsenb is set). */ + bool ctsenb; + /** Enable & set RTS mode. Note that RTS & CTS are enabled/disabled + together on some systems (RTS/CTS is enabled if either + ctsenb or rtsenb is set). + - 0 = Disable RTS. + - 1 = Enable RTS. + - 2 = Enable RTS flow-control handshaking (Win32). + - 3 = Specifies that RTS line will be high if bytes are available + for transmission. After transmission RTS will be low (Win32). */ + unsigned char rtsenb; + /** Enable/disable software flow control on input. */ + bool xinenb; + /** Enable/disable software flow control on output. */ + bool xoutenb; + /** Specifies if device is a modem (POSIX). If not set modem status + lines are ignored. */ + bool modem; + /** Enable/disable receiver (POSIX). */ + bool rcvenb; + /** Controls whether DSR is disabled or enabled (Win32). */ + bool dsrenb; + /** Controls whether DTR is disabled or enabled. */ + bool dtrdisable; + /** Data bits. Valid values 5, 6, 7 and 8 data bits. + Additionally Win32 supports 4 data bits. */ + unsigned char databits; + /** Stop bits. Valid values are 1 and 2. */ + unsigned char stopbits; + }; + + /** Interface for reading/writing serial device parameters. */ + int control (Control_Mode cmd, Serial_Params *arg) const; + +#if defined (ACE_NEEDS_DEV_IO_CONVERSION) + /** This is necessary to pass ACE_TTY_IO as parameter to DEV_Connector. */ + operator ACE_DEV_IO &(); +#endif /* ACE_NEEDS_DEV_IO_CONVERSION */ +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TTY_IO_H */ diff --git a/dep/ACE_wrappers/ace/Task.cpp b/dep/ACE_wrappers/ace/Task.cpp new file mode 100644 index 000000000..b3d8aad7a --- /dev/null +++ b/dep/ACE_wrappers/ace/Task.cpp @@ -0,0 +1,299 @@ +// $Id: Task.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Task.h" +#include "ace/Module.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Task.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID (ace, + Task, + "$Id: Task.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Task_Base::ACE_Task_Base (ACE_Thread_Manager *thr_man) + : thr_count_ (0), + thr_mgr_ (thr_man), + flags_ (0), + grp_id_ (-1) +#if !(defined (ACE_MVS) || defined(__TANDEM)) + ,last_thread_id_ (0) +#endif /* !defined (ACE_MVS) */ +{ +#if (defined (ACE_MVS) || defined(__TANDEM)) + ACE_OS::memset( &this->last_thread_id_, '\0', sizeof( this->last_thread_id_ )); +#endif /* defined (ACE_MVS) */ +} + +ACE_Task_Base::~ACE_Task_Base (void) +{ +} + +// Default ACE_Task service routine + +int +ACE_Task_Base::svc (void) +{ + ACE_TRACE ("ACE_Task_Base::svc"); + return 0; +} + +// Default ACE_Task open routine + +int +ACE_Task_Base::open (void *) +{ + ACE_TRACE ("ACE_Task_Base::open"); + return 0; +} + +// Default ACE_Task close routine + +int +ACE_Task_Base::close (u_long) +{ + ACE_TRACE ("ACE_Task_Base::close"); + return 0; +} + +// Forward the call to close() so that existing applications don't +// break. + +int +ACE_Task_Base::module_closed (void) +{ + return this->close (1); +} + +// Default ACE_Task put routine. + +int +ACE_Task_Base::put (ACE_Message_Block *, ACE_Time_Value *) +{ + ACE_TRACE ("ACE_Task_Base::put"); + return 0; +} + +// Wait for all threads running in a task to exit. + +int +ACE_Task_Base::wait (void) +{ + ACE_TRACE ("ACE_Task_Base::wait"); + + // If we don't have a thread manager, we probably were never + // activated. + if (this->thr_mgr () != 0) + return this->thr_mgr ()->wait_task (this); + else + return 0; +} + +// Suspend a task. +int +ACE_Task_Base::suspend (void) +{ + ACE_TRACE ("ACE_Task_Base::suspend"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + if (this->thr_count_ > 0) + return this->thr_mgr_->suspend_task (this); + + return 0; +} + +// Resume a suspended task. +int +ACE_Task_Base::resume (void) +{ + ACE_TRACE ("ACE_Task_Base::resume"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + if (this->thr_count_ > 0) + return this->thr_mgr_->resume_task (this); + + return 0; +} + +int +ACE_Task_Base::activate (long flags, + int n_threads, + int force_active, + long priority, + int grp_id, + ACE_Task_Base *task, + ACE_hthread_t thread_handles[], + void *stack[], + size_t stack_size[], + ACE_thread_t thread_ids[], + const char* thr_name[]) +{ + ACE_TRACE ("ACE_Task_Base::activate"); + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + // If the task passed in is zero, we will use + if (task == 0) + task = this; + + if (this->thr_count_ > 0 && force_active == 0) + return 1; // Already active. + else + { + if (this->thr_count_ > 0 && this->grp_id_ != -1) + // If we're joining an existing group of threads then make + // sure to use its group id. + grp_id = this->grp_id_; + this->thr_count_ += n_threads; + } + + // Use the ACE_Thread_Manager singleton if we're running as an + // active object and the caller didn't supply us with a + // Thread_Manager. + if (this->thr_mgr_ == 0) +# if defined (ACE_THREAD_MANAGER_LACKS_STATICS) + this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance (); +# else /* ! ACE_THREAD_MANAGER_LACKS_STATICS */ + this->thr_mgr_ = ACE_Thread_Manager::instance (); +# endif /* ACE_THREAD_MANAGER_LACKS_STATICS */ + + int grp_spawned = -1; + if (thread_ids == 0) + // Thread Ids were not specified + grp_spawned = + this->thr_mgr_->spawn_n (n_threads, + &ACE_Task_Base::svc_run, + (void *) this, + flags, + priority, + grp_id, + task, + thread_handles, + stack, + stack_size, + thr_name); + else + // thread names were specified + grp_spawned = + this->thr_mgr_->spawn_n (thread_ids, + n_threads, + &ACE_Task_Base::svc_run, + (void *) this, + flags, + priority, + grp_id, + stack, + stack_size, + thread_handles, + task, + thr_name); + if (grp_spawned == -1) + { + // If spawn_n fails, restore original thread count. + this->thr_count_ -= n_threads; + return -1; + } + + if (this->grp_id_ == -1) + this->grp_id_ = grp_spawned; + +#if defined (ACE_MVS) || defined(__TANDEM) + ACE_OS::memcpy( &this->last_thread_id_, '\0', sizeof(this->last_thread_id_)); +#else + this->last_thread_id_ = 0; // Reset to prevent inadvertant match on ID +#endif /* defined (ACE_MVS) */ + + return 0; + +#else + { + // Keep the compiler from complaining. + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (n_threads); + ACE_UNUSED_ARG (force_active); + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (grp_id); + ACE_UNUSED_ARG (task); + ACE_UNUSED_ARG (thread_handles); + ACE_UNUSED_ARG (stack); + ACE_UNUSED_ARG (stack_size); + ACE_UNUSED_ARG (thread_ids); + ACE_UNUSED_ARG (thr_name); + ACE_NOTSUP_RETURN (-1); + } +#endif /* ACE_MT_SAFE */ +} + +void +ACE_Task_Base::cleanup (void *object, void *) +{ + ACE_Task_Base *t = (ACE_Task_Base *) object; + + // The thread count must be decremented first in case the + // hook does something crazy like "delete this". + { + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, t->lock_)); + t->thr_count_--; + if (0 == t->thr_count_) + t->last_thread_id_ = ACE_Thread::self (); + } + + // @@ Is it possible to pass in the exit status somehow? + t->close (); + // t is undefined here. close() could have deleted it. +} + + +#if defined (ACE_HAS_SIG_C_FUNC) +extern "C" void +ACE_Task_Base_cleanup (void *object, void *) +{ + ACE_Task_Base::cleanup (object, 0); +} +#endif /* ACE_HAS_SIG_C_FUNC */ + +ACE_THR_FUNC_RETURN +ACE_Task_Base::svc_run (void *args) +{ + ACE_TRACE ("ACE_Task_Base::svc_run"); + + ACE_Task_Base *t = (ACE_Task_Base *) args; + + // Register ourself with our 's thread exit hook + // mechanism so that our close() hook will be sure to get invoked + // when this thread exits. + +#if defined ACE_HAS_SIG_C_FUNC + t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0); +#else + t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0); +#endif /* ACE_HAS_SIG_C_FUNC */ + + // Call the Task's svc() hook method. + int const svc_status = t->svc (); + ACE_THR_FUNC_RETURN status; +#if defined (ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN) + // Reinterpret case between integral types is not mentioned in the C++ spec + status = static_cast (svc_status); +#else + status = reinterpret_cast (svc_status); +#endif /* ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN */ + +// If we changed this zero change the other if in OS.cpp Thread_Adapter::invoke +#if 1 + // Call the close> hook. + ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr (); + + // This calls the Task->close () hook. + t->cleanup (t, 0); + + // This prevents a second invocation of the cleanup code + // (called later by . + thr_mgr_ptr->at_exit (t, 0, 0); +#endif + return status; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Task.h b/dep/ACE_wrappers/ace/Task.h new file mode 100644 index 000000000..f2ac03ca9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task.h @@ -0,0 +1,307 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Task.h + * + * $Id: Task.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TASK_H +#define ACE_TASK_H +#include /**/ "ace/pre.h" + +#include "ace/Service_Object.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Thread_Manager.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Task_Flags + * + * @brief These flags are used within the ACE_Task. + * + * These flags should be hidden within ACE_Task. Unfortunately, the + * HP/UX C++ compiler can't grok this... Fortunately, there's no + * code defined here, so we don't have to worry about multiple + * definitions. + */ +namespace ACE_Task_Flags +{ + enum + { + /// Identifies a Task as being the "reader" in a Module. + ACE_READER = 01, + /// Just flush data messages in the queue. + ACE_FLUSHDATA = 02, + /// Flush all messages in the Queue. + ACE_FLUSHALL = 04, + /// Flush read queue + ACE_FLUSHR = 010, + /// Flush write queue + ACE_FLUSHW = 020, + /// Flush both queues + ACE_FLUSHRW = 030 + }; +} + +/** + * @class ACE_Task_Base + * + * @brief Direct base class for the ACE_Task template. + * + * This class factors out the non-template code in order to + * reduce template bloat, as well as to make it possible for the + * ACE_Thread_Manager to store ACE_Task_Base *'s + * polymorphically. + */ +class ACE_Export ACE_Task_Base : public ACE_Service_Object +{ +public: + // = Initialization and termination methods. + /// Constructor. + ACE_Task_Base (ACE_Thread_Manager * = 0); + + /// Destructor. + virtual ~ACE_Task_Base (void); + + // = Initialization and termination hooks. + + // These methods should be overridden by subclasses if you'd like to + // provide -specific initialization and termination behavior. + + /// Hook called to initialize a task and prepare it for execution. + /// @a args can be used to pass arbitrary information into . + virtual int open (void *args = 0); + + /** + * Hook called from ACE_Thread_Exit when during thread exit and from + * the default implementation of . In general, this + * method shouldn't be called directly by an application, + * particularly if the is running as an Active Object. + * Instead, a special message should be passed into the via + * the method defined below, and the method should + * interpret this as a flag to shut down the . + */ + virtual int close (u_long flags = 0); + + /** + * Hook called during . The default + * implementation calls forwards the call to close(1). Please + * notice the changed value of the default argument of . + * This allows tasks to differ between the call has been originated + * from or from . Be aware that + * close(0) will be also called when a thread associated with the + * ACE_Task instance exits. + */ + virtual int module_closed (void); + + // = Immediate and deferred processing methods, respectively. + + // These methods should be overridden by subclasses if you'd like to + // provide -specific message processing behavior. + + /// A hook method that can be used to pass a message to a + /// task, where it can be processed immediately or queued for subsequent + /// processing in the hook method. + virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0); + + /// Run by a daemon thread to handle deferred processing. + virtual int svc (void); + + // = Active object activation method. + /** + * Turn the task into an active object, i.e., having @a n_threads of + * control, all running at the @a priority level (see below) with the + * same @a grp_id, all of which invoke . Returns -1 if + * failure occurs, returns 1 if Task is already an active object and + * @a force_active is false (i.e., do *not* create a new thread in + * this case), and returns 0 if Task was not already an active + * object and a thread is created successfully or thread is an + * active object and @a force_active is true. Note that if + * @a force_active is true and there are already threads spawned in + * this , the @a grp_id parameter is ignored and the @a grp_id + * of any newly activated thread(s) will inherit the existing + * @a grp_id of the existing thread(s) in the . + * + * The <{flags}> are a bitwise-OR of the following: + * = BEGIN + * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED, + * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED, + * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO, + * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED, + * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS + * = END + * If THR_SCHED_INHERIT is not desirable, applications should + * specifically pass in THR_EXPLICIT_SCHED. + * + * + * By default, or if <{priority}> is set to + * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for + * the given scheduling policy (specified in <{flags}>, e.g., + * ) is used. This value is calculated + * dynamically, and is the median value between the minimum and + * maximum priority values for the given policy. If an explicit + * value is given, it is used. Note that actual priority values are + * EXTREMEMLY implementation-dependent, and are probably best + * avoided. + * + * If @a thread_handles != 0 it is assumed to be an array of @a n + * thread_handles that will be assigned the values of the thread + * handles being spawned. Returns -1 on failure (@c errno will + * explain...), otherwise returns the group id of the threads. + * + * Assigning @a task allows you to associate the newly spawned + * threads with an instance of ACE_Task_Base. If @a task == 0, then + * the new threads are associated automatically with @c this + * ACE_Task_Base. Setting the @a task argument to value other than + * @c this makes the thread manipulating methods, such as wait(), + * suspend(), resume(), useless. Threads spawned with user + * specified @a task value must therefore be manipulated thru + * ACE_Thread_Manager directly. + * + * If @a stack != 0 it is assumed to be an array of @a n pointers to + * the base of the stacks to use for the threads being spawned. + * Likewise, if @a stack_size != 0 it is assumed to be an array of + * @a n values indicating how big each of the corresponding @a stacks + * are. + * + * + */ + virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, + int n_threads = 1, + int force_active = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_thread_t thread_ids[] = 0, + const char* thr_name[] = 0); + + /** + * Block until there are no more threads running in this task. + * This method will not wait for either detached or daemon threads; + * the threads must have been spawned with the @c THR_JOINABLE flag. + * Upon successful completion, the threads have been joined, so further + * attempts to join with any of the waited-for threads will fail. + * + * @retval 0 Success. + * @retval -1 Failure (consult errno for further information). + */ + virtual int wait (void); + + // = Suspend/resume a Task. + + // Note that these methods are not portable and should be avoided + // since they are inherently error-prone to use. They are only here + // for (the rare) applications that know how to use them correctly. + /// Suspend a task. + virtual int suspend (void); + /// Resume a suspended task. + virtual int resume (void); + + /// Get the current group id. + int grp_id (void) const; + + /// Set the current group id. + void grp_id (int); + + /// Get the thread manager associated with this Task. + ACE_Thread_Manager *thr_mgr (void) const; + + /// Set the thread manager associated with this Task. + void thr_mgr (ACE_Thread_Manager *); + + /// True if queue is a reader, else false. + int is_reader (void) const; + + /// True if queue is a writer, else false. + int is_writer (void) const; + + /** + * Returns the number of threads currently running within a task. + * If we're a passive object this value is 0, else it's greater than + * 0. + */ + size_t thr_count (void) const; + + /** + * Returns the thread ID of the thread whose exit caused this object's + * thread count to be decremented to 0. + * + * When a thread spawned in the context of this object (using activate()) + * returns from its svc() method ACE calls the close() hook. Before it does + * so, it decrements the number of active threads. If the number of threads + * is decremented to 0, the thread ID of the current thread is stored for + * access by this method. If the returned thread ID matches the calling + * thread's ID, the calling thread knows that there are no other threads + * still active in the ACE_Task. + * + * @retval ACE_thread_t of the last thread to close. 0 if the last thread + * is not yet known; for example, if no threads are active, or if + * multiple threads are active. + */ + ACE_thread_t last_thread (void) const; + + /// Routine that runs the service routine as a daemon thread. + static ACE_THR_FUNC_RETURN svc_run (void *); + + /// Cleanup hook that is called when a thread exits to gracefully + /// shutdown an ACE_Task. + static void cleanup (void *object, void *params); + +protected: + /** + * Count of the number of threads running within the task. If this + * value is greater than 0 then we're an active object and the value + * of is the number of active threads at this instant. + * If the value == 0, then we're a passive object. + */ + size_t thr_count_; + + /// Multi-threading manager. + ACE_Thread_Manager *thr_mgr_; + + /// ACE_Task flags. + u_long flags_; + + /// This maintains the group id of the Task. + int grp_id_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Protect the state of a Task during concurrent operations, but + /// only if we're configured as MT safe... + ACE_Thread_Mutex lock_; +#endif /* ACE_MT_SAFE */ + + /// Holds the thread ID of the last thread to exit svc() in this object. + ACE_thread_t last_thread_id_; + +private: + + // = Disallow these operations. + ACE_Task_Base &operator= (const ACE_Task_Base &); + ACE_Task_Base (const ACE_Task_Base &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Task.inl" +#endif /* __ACE_INLINE__ */ + +// Include the ACE_Task templates classes at this point. +#include "ace/Task_T.h" + +#include /**/ "ace/post.h" +#endif /* ACE_TASK_H */ diff --git a/dep/ACE_wrappers/ace/Task.inl b/dep/ACE_wrappers/ace/Task.inl new file mode 100644 index 000000000..9f70371e5 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task.inl @@ -0,0 +1,77 @@ +// -*- C++ -*- +// +// $Id: Task.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Get the current group id. +ACE_INLINE int +ACE_Task_Base::grp_id (void) const +{ + ACE_TRACE ("ACE_Task_Base::grp_id"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, const_cast (this->lock_), -1)); + return this->grp_id_; +} + +// Set the current group id. + +ACE_INLINE void +ACE_Task_Base::grp_id (int identifier) +{ + ACE_TRACE ("ACE_Task_Base::grp_id"); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); + + // Cache the group id in the task and then set it in the + // Thread_Manager, if there is one. + this->grp_id_ = identifier; + if (this->thr_mgr ()) + this->thr_mgr ()->set_grp (this, identifier); +} + +ACE_INLINE ACE_Thread_Manager * +ACE_Task_Base::thr_mgr (void) const +{ + ACE_TRACE ("ACE_Task_Base::thr_mgr"); + return this->thr_mgr_; +} + +ACE_INLINE void +ACE_Task_Base::thr_mgr (ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_Task_Base::thr_mgr"); + this->thr_mgr_ = thr_mgr; +} + +ACE_INLINE int +ACE_Task_Base::is_reader (void) const +{ + ACE_TRACE ("ACE_Task_Base::is_reader"); + return (ACE_BIT_ENABLED (this->flags_, ACE_Task_Flags::ACE_READER)); +} + +ACE_INLINE int +ACE_Task_Base::is_writer (void) const +{ + ACE_TRACE ("ACE_Task_Base::is_writer"); + return (ACE_BIT_DISABLED (this->flags_, ACE_Task_Flags::ACE_READER)); +} + +// Return the count of the current number of threads. +ACE_INLINE size_t +ACE_Task_Base::thr_count (void) const +{ + ACE_TRACE ("ACE_Task_Base::thr_count"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, const_cast (this->lock_), 0)); + + return this->thr_count_; +} + +// Return the thread ID of the last thread to exit svc(). +ACE_INLINE ACE_thread_t +ACE_Task_Base::last_thread (void) const +{ + ACE_TRACE ("ACE_Task_Base::last_thread"); + return this->last_thread_id_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Task_Ex_T.cpp b/dep/ACE_wrappers/ace/Task_Ex_T.cpp new file mode 100644 index 000000000..de97e5ba6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task_Ex_T.cpp @@ -0,0 +1,114 @@ +// $Id: Task_Ex_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TASK_EX_T_CPP +#define ACE_TASK_EX_T_CPP + +#include "ace/Task_Ex_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Module.h" +#include "ace/Null_Condition.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Task_Ex_T.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template void +ACE_Task_Ex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Task_Ex::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_mgr_ = %x"), this->thr_mgr_)); + this->msg_queue_->dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_msg_queue_ = %d\n"), this->delete_msg_queue_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags = %x"), this->flags_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmod_ = %x"), this->mod_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnext_ = %x"), this->next_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_count_ = %d"), this->thr_count_)); +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + this->lock_.dump (); +#endif /* ACE_MT_SAFE */ + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// If the user doesn't supply a ACE_Message_Queue_Ex pointer then we'll +// allocate one dynamically. Otherwise, we'll use the one they give. + +template +ACE_Task_Ex::ACE_Task_Ex (ACE_Thread_Manager *thr_man, + ACE_Message_Queue_Ex *mq) + : ACE_Task_Base (thr_man), + msg_queue_ (0), + delete_msg_queue_ (false), + mod_ (0), + next_ (0) +{ + ACE_TRACE ("ACE_Task_Ex::ACE_Task_Ex"); + + if (mq == 0) + { + ACE_NEW (mq, + (ACE_Message_Queue_Ex)); + this->delete_msg_queue_ = true; + } + + this->msg_queue_ = mq; +} + +template +ACE_Task_Ex::~ACE_Task_Ex (void) +{ + ACE_TRACE ("ACE_Task_Ex::~ACE_Task_Ex"); + if (this->delete_msg_queue_) + delete this->msg_queue_; + + // These assignments aren't strickly necessary but they help guard + // against odd race conditions... + this->delete_msg_queue_ = false; +} + +template ACE_Task * +ACE_Task_Ex::sibling (void) +{ + ACE_TRACE ("ACE_Task_Ex::sibling"); + /// @todo FIXME Need to impl ACE_Moudle to support ACE_Task as well. + /// Now always return 0 for sibling + return 0; +/* + if (this->mod_ == 0) + return 0; + else + return this->mod_->sibling (this); +*/ +} + +template const ACE_TCHAR * +ACE_Task_Ex::name (void) const +{ + ACE_TRACE ("ACE_Task_Ex::name"); + if (this->mod_ == 0) + return 0; + else + return this->mod_->name (); +} + +template ACE_Module * +ACE_Task_Ex::module (void) const +{ + ACE_TRACE ("ACE_Task_Ex::module"); + return this->mod_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TASK_EX_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Task_Ex_T.h b/dep/ACE_wrappers/ace/Task_Ex_T.h new file mode 100644 index 000000000..00233d4e7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task_Ex_T.h @@ -0,0 +1,205 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Task_Ex_T.h + * + * $Id: Task_Ex_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Kobi Cohen-Arazi + */ +//============================================================================= + +#ifndef ACE_TASK_EX_T_H +#define ACE_TASK_EX_T_H +#include /**/ "ace/pre.h" + +#include "ace/Service_Object.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Synch_Traits.h" +#include "ace/Task.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decls... +template class ACE_Module; + +/** + * @class ACE_Task_Ex + * + * @brief Primary interface for application message processing, as well + * as input and output message queueing. + * + * Unlike ACE_Task, these class doesn't have the ability to be a part of + * a Stream chain. I.e. You cannot (yet) chain modules based on ACE_Task_Ex. + * + * @todo: We can merge ACE_Task and ACE_Task_Ex to be one class. + * something like that: + * template + * class ACE_Task : public ACE_Task_Base + * { + * // use here the code from ACE_Task_Ex using ACE_Message_Queue_Ex + * }; + * + * Now specialized version of ACE_Task with ACE_Message_Block as its + * ACE_MESSAGE_TYPE... + * + * template + * class ACE_Task : public ACE_Task_Base + * { + * // put here the good old ACE_Task code + * }; + * + * When User (and legacy code) write ACE_Task, specialized ACE_Task + * code is in action. + */ +template +class ACE_Task_Ex : public ACE_Task_Base +{ +public: + friend class ACE_Module; + friend class ACE_Module_Type; + typedef ACE_Message_Queue_Ex MESSAGE_QUEUE_EX; + + // = Initialization/termination methods. + /** + * Initialize a Task, supplying a thread manager and a message + * queue. If the user doesn't supply a ACE_Message_Queue pointer + * then we'll allocate one dynamically. Otherwise, we'll use the + * one passed as a parameter. + */ + ACE_Task_Ex (ACE_Thread_Manager *thr_mgr = 0, + MESSAGE_QUEUE_EX *mq = 0); + + /// Destructor. + virtual ~ACE_Task_Ex (void); + + /// Gets the message queue associated with this task. + MESSAGE_QUEUE_EX *msg_queue (void); + + /// Sets the message queue associated with this task. + void msg_queue (MESSAGE_QUEUE_EX *); + +public: // Should be protected: + // = Message queue manipulation methods. + + // = Enqueue and dequeue methods. + + // For the following five method if @a timeout == 0, the caller will + // block until action is possible, else will wait until the + // <{absolute}> time specified in *@a timeout elapses). These calls + // will return, however, when queue is closed, deactivated, when a + // signal occurs, or if the time specified in timeout elapses, (in + // which case errno = EWOULDBLOCK). + + /// Insert message into the message queue. Note that @a timeout uses + /// <{absolute}> time rather than <{relative}> time. + int putq (ACE_MESSAGE_TYPE *, ACE_Time_Value *timeout = 0); + + /** + * Extract the first message from the queue (blocking). Note that + * @a timeout uses <{absolute}> time rather than <{relative}> time. + * Returns number of items in queue if the call succeeds or -1 otherwise. + */ + int getq (ACE_MESSAGE_TYPE *&mb, ACE_Time_Value *timeout = 0); + + /// Return a message to the queue. Note that @a timeout uses + /// <{absolute}> time rather than <{relative}> time. + int ungetq (ACE_MESSAGE_TYPE *, ACE_Time_Value *timeout = 0); + + /** + * Turn the message around and send it back down the Stream. Note + * that @a timeout uses <{absolute}> time rather than <{relative}> + * time. + */ + int reply (ACE_MESSAGE_TYPE *, ACE_Time_Value *timeout = 0); + + /** + * Transfer message to the adjacent ACE_Task_Ex in a ACE_Stream. Note + * that @a timeout uses <{absolute}> time rather than <{relative}> + * time. + */ + int put_next (ACE_MESSAGE_TYPE *msg, ACE_Time_Value *timeout = 0); + + /** + * Tests whether we can enqueue a message without blocking. + * @deprecated This method is deprecated and will go away in the future. + */ + int can_put (ACE_MESSAGE_TYPE *); + + // = ACE_Task utility routines to identify names et al. + /// Return the name of the enclosing Module if there's one associated + /// with the Task, else returns 0. + const ACE_TCHAR *name (void) const; + + // = Pointers to next ACE_Task_Base (if ACE is part of an ACE_Stream). + /// Get next Task pointer. + ACE_Task *next (void); + + /// Set next Task pointer. + void next (ACE_Task *); + + /// Alwasy return 0. @todo FIXME + ACE_Task *sibling (void); + + /// Return the Task's Module if there is one, else returns 0. + ACE_Module *module (void) const; + + /** + * Flush the task's queue, i.e., free all of the enqueued + * message blocks and releases any threads blocked on the queue. + * Note that if this conflicts with the C++ iostream + * function, just rewrite the iostream function as ::. + */ + int flush (u_long flag = ACE_Task_Flags::ACE_FLUSHALL); + + // = Special routines corresponding to certain message types. + + /// Manipulate watermarks. + void water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds, size_t); + + /// Queue of messages on the ACE_Task.. + MESSAGE_QUEUE_EX *msg_queue_; + + /// true if should delete Message_Queue, false otherwise. + bool delete_msg_queue_; + + /// Back-pointer to the enclosing module. + ACE_Module *mod_; + + /// Pointer to adjacent ACE_Task. + ACE_Task *next_; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + // = Disallow these operations. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Task_Ex &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Task_Ex (const ACE_Task_Ex &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Task_Ex_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Task_Ex_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Task_Ex_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TASK_EX_H */ diff --git a/dep/ACE_wrappers/ace/Task_Ex_T.inl b/dep/ACE_wrappers/ace/Task_Ex_T.inl new file mode 100644 index 000000000..dd90bcd49 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task_Ex_T.inl @@ -0,0 +1,109 @@ +// -*- C++ -*- +// +// $Id: Task_Ex_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE void +ACE_Task_Ex::water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, + size_t wm_size) +{ + ACE_TRACE ("ACE_Task_Ex::water_marks"); + if (cmd == ACE_IO_Cntl_Msg::SET_LWM) + this->msg_queue_->low_water_mark (wm_size); + else /* cmd == ACE_IO_Cntl_Msg::SET_HWM */ + this->msg_queue_->high_water_mark (wm_size); +} + +template ACE_INLINE int +ACE_Task_Ex::getq (ACE_MESSAGE_TYPE *&mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task_Ex::getq"); + return this->msg_queue_->dequeue_head (mb, tv); +} + +template ACE_INLINE int +ACE_Task_Ex::can_put (ACE_MESSAGE_TYPE *) +{ + ACE_TRACE ("ACE_Task_Ex::can_put"); + ACE_NOTSUP_RETURN (-1); +} + +template ACE_INLINE int +ACE_Task_Ex::putq (ACE_MESSAGE_TYPE *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task_Ex::putq"); + return this->msg_queue_->enqueue_tail (mb, tv); +} + +template ACE_INLINE int +ACE_Task_Ex::ungetq (ACE_MESSAGE_TYPE *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task_Ex::ungetq"); + return this->msg_queue_->enqueue_head (mb, tv); +} + +template ACE_INLINE int +ACE_Task_Ex::flush (u_long flag) +{ + ACE_TRACE ("ACE_Task_Ex::flush"); + if (ACE_BIT_ENABLED (flag, ACE_Task_Flags::ACE_FLUSHALL)) + return this->msg_queue_ != 0 && this->msg_queue_->close (); + else + return -1; // Note, need to be more careful about what we free... +} + +template ACE_INLINE void +ACE_Task_Ex::msg_queue (ACE_Message_Queue_Ex *mq) +{ + ACE_TRACE ("ACE_Task_Ex::msg_queue"); + if (this->delete_msg_queue_) + { + delete this->msg_queue_; + this->delete_msg_queue_ = false; + } + this->msg_queue_ = mq; +} + +template ACE_Message_Queue_Ex * +ACE_Task_Ex::msg_queue (void) +{ + ACE_TRACE ("ACE_Task_Ex::msg_queue"); + return this->msg_queue_; +} + +template ACE_INLINE int +ACE_Task_Ex::reply (ACE_MESSAGE_TYPE *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task_Ex::reply"); + ACE_UNUSED_ARG (mb); + ACE_UNUSED_ARG (tv); + return -1 ; // this->sibling ()->put_next (mb, tv); +} + +template ACE_INLINE ACE_Task * +ACE_Task_Ex::next (void) +{ + ACE_TRACE ("ACE_Task_Ex::next"); + return this->next_; +} + +template ACE_INLINE void +ACE_Task_Ex::next (ACE_Task *q) +{ + ACE_TRACE ("ACE_Task_Ex::next"); + this->next_ = q; +} + +// Transfer msg to the next ACE_Task_Ex. + +template ACE_INLINE int +ACE_Task_Ex::put_next ( + ACE_MESSAGE_TYPE * /* msg */, + ACE_Time_Value * /* tv */) +{ + ACE_TRACE ("ACE_Task_Ex::put_next"); + return -1; // this->next_ == 0 ? -1 : this->next_->put (msg, tv); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Task_T.cpp b/dep/ACE_wrappers/ace/Task_T.cpp new file mode 100644 index 000000000..08b36f82f --- /dev/null +++ b/dep/ACE_wrappers/ace/Task_T.cpp @@ -0,0 +1,108 @@ +// $Id: Task_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TASK_T_CPP +#define ACE_TASK_T_CPP + +#include "ace/Task_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Module.h" +#include "ace/Null_Condition.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Task_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template void +ACE_Task::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Task::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_mgr_ = %x"), this->thr_mgr_)); + this->msg_queue_->dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_msg_queue_ = %d\n"), this->delete_msg_queue_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags = %x"), this->flags_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmod_ = %x"), this->mod_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnext_ = %x"), this->next_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_count_ = %d"), this->thr_count_)); +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + this->lock_.dump (); +#endif /* ACE_MT_SAFE */ + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// If the user doesn't supply a ACE_Message_Queue pointer then we'll +// allocate one dynamically. Otherwise, we'll use the one they give. + +template +ACE_Task::ACE_Task (ACE_Thread_Manager *thr_man, + ACE_Message_Queue *mq) + : ACE_Task_Base (thr_man), + msg_queue_ (0), + delete_msg_queue_ (false), + mod_ (0), + next_ (0) +{ + ACE_TRACE ("ACE_Task::ACE_Task"); + + if (mq == 0) + { + ACE_NEW (mq, + ACE_Message_Queue); + this->delete_msg_queue_ = true; + } + + this->msg_queue_ = mq; +} + +template +ACE_Task::~ACE_Task (void) +{ + ACE_TRACE ("ACE_Task::~ACE_Task"); + if (this->delete_msg_queue_) + delete this->msg_queue_; + + // These assignments aren't strickly necessary but they help guard + // against odd race conditions... + this->delete_msg_queue_ = false; +} + +template ACE_Task * +ACE_Task::sibling (void) +{ + ACE_TRACE ("ACE_Task::sibling"); + if (this->mod_ == 0) + return 0; + else + return this->mod_->sibling (this); +} + +template const ACE_TCHAR * +ACE_Task::name (void) const +{ + ACE_TRACE ("ACE_Task::name"); + if (this->mod_ == 0) + return 0; + else + return this->mod_->name (); +} + +template ACE_Module * +ACE_Task::module (void) const +{ + ACE_TRACE ("ACE_Task::module"); + return this->mod_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TASK_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Task_T.h b/dep/ACE_wrappers/ace/Task_T.h new file mode 100644 index 000000000..b945bf375 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task_T.h @@ -0,0 +1,198 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Task_T.h + * + * $Id: Task_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TASK_T_H +#define ACE_TASK_T_H +#include /**/ "ace/pre.h" + +#include "ace/Message_Queue.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Synch_Traits.h" +#include "ace/Task.h" +#include "ace/IO_Cntl_Msg.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decls... +template class ACE_Module; + +/** + * @class ACE_Task + * + * @brief Primary interface for application message processing, as well + * as input and output message queueing. + * + * This class serves as the basis for passive and active objects + * in ACE. + */ +template +class ACE_Task : public ACE_Task_Base +{ +public: + friend class ACE_Module; + friend class ACE_Module_Type; + + // = Initialization/termination methods. + /** + * Initialize a Task, supplying a thread manager and a message + * queue. If the user doesn't supply a ACE_Message_Queue pointer + * then we'll allocate one dynamically. Otherwise, we'll use the + * one passed as a parameter. + */ + ACE_Task (ACE_Thread_Manager *thr_mgr = 0, + ACE_Message_Queue *mq = 0); + + /// Destructor. + virtual ~ACE_Task (void); + + /// Gets the message queue associated with this task. + ACE_Message_Queue *msg_queue (void); + + /// Sets the message queue associated with this task. + void msg_queue (ACE_Message_Queue *); + +public: // Should be protected: + // = Message queue manipulation methods. + + // = Enqueue and dequeue methods. + + // For the following five method if @a timeout == 0, the caller will + // block until action is possible, else will wait until the + // <{absolute}> time specified in *@a timeout elapses). These calls + // will return, however, when queue is closed, deactivated, when a + // signal occurs, or if the time specified in timeout elapses, (in + // which case errno = EWOULDBLOCK). + + /// Insert message into the message queue. Note that @a timeout uses + /// <{absolute}> time rather than <{relative}> time. + int putq (ACE_Message_Block *, ACE_Time_Value *timeout = 0); + + /** + * Extract the first message from the queue (blocking). Note that + * @a timeout uses <{absolute}> time rather than <{relative}> time. + * Returns number of items in queue if the call succeeds or -1 otherwise. + */ + int getq (ACE_Message_Block *&mb, ACE_Time_Value *timeout = 0); + + /// Return a message to the queue. Note that @a timeout uses + /// <{absolute}> time rather than <{relative}> time. + int ungetq (ACE_Message_Block *, ACE_Time_Value *timeout = 0); + + /** + * Turn the message around, sending it in the opposite direction in + * the stream. To do this, the message is put onto the task next in + * the stream after this task's sibling. + * + * @param ACE_Message_Block Pointer to the block that is used in the reply. + * @param timeout The absolute time at which the put operation used to + * send the message block to the next module in the stream + * will time out. If 0, this call blocks until it can be + * completed. + */ + int reply (ACE_Message_Block *, ACE_Time_Value *timeout = 0); + + /** + * Transfer message to the adjacent ACE_Task in a ACE_Stream. Note + * that @a timeout uses <{absolute}> time rather than <{relative}> + * time. + */ + int put_next (ACE_Message_Block *msg, ACE_Time_Value *timeout = 0); + + /** + * Tests whether we can enqueue a message without blocking. + * + * @deprecated This method is deprecated and will go away in the future. + */ + int can_put (ACE_Message_Block *); + + // = ACE_Task utility routines to identify names et al. + /// Return the name of the enclosing Module if there's one associated + /// with the Task, else returns 0. + const ACE_TCHAR *name (void) const; + + // = Pointers to next ACE_Task_Base (if ACE is part of an ACE_Stream). + /// Get next Task pointer. + ACE_Task *next (void); + + /// Set next Task pointer. + void next (ACE_Task *); + + /// Return the Task's sibling if there's one associated with the + /// Task's Module, else returns 0. + ACE_Task *sibling (void); + + /// Return the Task's Module if there is one, else returns 0. + ACE_Module *module (void) const; + + /** + * Flush the task's queue, i.e., free all of the enqueued + * message blocks and unblocks any threads waiting on the queue. + * Note that if this conflicts with the C++ iostream + * function, just rewrite the iostream function as ::. + */ + int flush (u_long flag = ACE_Task_Flags::ACE_FLUSHALL); + + // = Special routines corresponding to certain message types. + + /// Manipulate watermarks. + void water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds, size_t); + + /// Queue of messages on the ACE_Task.. + ACE_Message_Queue *msg_queue_; + + /// true if should delete Message_Queue, false otherwise. + bool delete_msg_queue_; + + /// Back-pointer to the enclosing module. + ACE_Module *mod_; + + /// Pointer to adjacent ACE_Task. + ACE_Task *next_; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + // = Disallow these operations. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Task &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Task (const ACE_Task &)) +}; + +#if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT +template class ACE_Export ACE_Task; +template class ACE_Export ACE_Task; +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Task_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Task_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Task_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TASK_T_H */ diff --git a/dep/ACE_wrappers/ace/Task_T.inl b/dep/ACE_wrappers/ace/Task_T.inl new file mode 100644 index 000000000..a441ca9d0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Task_T.inl @@ -0,0 +1,105 @@ +// -*- C++ -*- +// +// $Id: Task_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE void +ACE_Task::water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, + size_t wm_size) +{ + ACE_TRACE ("ACE_Task::water_marks"); + if (cmd == ACE_IO_Cntl_Msg::SET_LWM) + this->msg_queue_->low_water_mark (wm_size); + else /* cmd == ACE_IO_Cntl_Msg::SET_HWM */ + this->msg_queue_->high_water_mark (wm_size); +} + +template ACE_INLINE int +ACE_Task::getq (ACE_Message_Block *&mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::getq"); + return this->msg_queue_->dequeue_head (mb, tv); +} + +template ACE_INLINE int +ACE_Task::can_put (ACE_Message_Block *) +{ + ACE_TRACE ("ACE_Task::can_put"); + ACE_NOTSUP_RETURN (-1); +} + +template ACE_INLINE int +ACE_Task::putq (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::putq"); + return this->msg_queue_->enqueue_tail (mb, tv); +} + +template ACE_INLINE int +ACE_Task::ungetq (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::ungetq"); + return this->msg_queue_->enqueue_head (mb, tv); +} + +template ACE_INLINE int +ACE_Task::flush (u_long flag) +{ + ACE_TRACE ("ACE_Task::flush"); + if (ACE_BIT_ENABLED (flag, ACE_Task_Flags::ACE_FLUSHALL)) + return this->msg_queue_ != 0 && this->msg_queue_->close (); + else + return -1; // Note, need to be more careful about what we free... +} + +template ACE_INLINE void +ACE_Task::msg_queue (ACE_Message_Queue *mq) +{ + ACE_TRACE ("ACE_Task::msg_queue"); + if (this->delete_msg_queue_) + { + delete this->msg_queue_; + this->delete_msg_queue_ = false; + } + this->msg_queue_ = mq; +} + +template ACE_Message_Queue * +ACE_Task::msg_queue (void) +{ + ACE_TRACE ("ACE_Task::msg_queue"); + return this->msg_queue_; +} + +template ACE_INLINE int +ACE_Task::reply (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::reply"); + return this->sibling ()->put_next (mb, tv); +} + +template ACE_INLINE ACE_Task * +ACE_Task::next (void) +{ + ACE_TRACE ("ACE_Task::next"); + return this->next_; +} + +template ACE_INLINE void +ACE_Task::next (ACE_Task *q) +{ + ACE_TRACE ("ACE_Task::next"); + this->next_ = q; +} + +// Transfer msg to the next ACE_Task. + +template ACE_INLINE int +ACE_Task::put_next (ACE_Message_Block *msg, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::put_next"); + return this->next_ == 0 ? -1 : this->next_->put (msg, tv); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Test_and_Set.cpp b/dep/ACE_wrappers/ace/Test_and_Set.cpp new file mode 100644 index 000000000..15fbfe084 --- /dev/null +++ b/dep/ACE_wrappers/ace/Test_and_Set.cpp @@ -0,0 +1,51 @@ +// $Id: Test_and_Set.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TEST_AND_SET_CPP +#define ACE_TEST_AND_SET_CPP + +#include "ace/Test_and_Set.h" +#include "ace/Guard_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Test_and_Set::ACE_Test_and_Set (TYPE initial_value) + : is_set_ (initial_value) +{ +} + +// Returns true if we are done, else false. +template TYPE +ACE_Test_and_Set::is_set (void) const +{ + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->lock_, this->is_set_); + return this->is_set_; +} + +// Sets the status. +template TYPE +ACE_Test_and_Set::set (TYPE status) +{ + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, this->is_set_); + TYPE o_status = this->is_set_; + this->is_set_ = status; + return o_status; +} + +template int +ACE_Test_and_Set::handle_signal (int, siginfo_t *, ucontext_t *) +{ + // By setting this to 1, we are "signaling" to anyone calling + // or or that the "test and set" object is in the + // "signaled" state, i.e., it's "available" to be set back to 0. + this->set (1); + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TEST_AND_SET_CPP */ diff --git a/dep/ACE_wrappers/ace/Test_and_Set.h b/dep/ACE_wrappers/ace/Test_and_Set.h new file mode 100644 index 000000000..062de0bc8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Test_and_Set.h @@ -0,0 +1,75 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Test_and_Set.h + * + * $Id: Test_and_Set.h 80826 2008-03-04 14:51:23Z wotte $ + */ +//============================================================================= + + +#ifndef ACE_TEST_AND_SET_H +#define ACE_TEST_AND_SET_H + +#include /**/ "ace/pre.h" +#include "ace/Event_Handler.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Test_and_Set + * + * @brief Implements the classic ``test and set'' operation. + * + * + * This class keeps track of the status of , which can + * be set based on various events (such as receipt of a + * signal). This class is derived from ACE_Event_Handler so + * that it can be "signaled" by a Reactor when a signal occurs. + * We assume that is a data type that can be assigned the + * value 0 or 1. + */ +template +class ACE_Test_and_Set : public ACE_Event_Handler +{ +public: + ACE_Test_and_Set (TYPE initial_value = 0); + + /// Returns true if we are set, else false. + TYPE is_set (void) const; + + /// Sets the status, returning the original value of + /// . + TYPE set (TYPE); + + /// Called when object is signaled by OS (either via UNIX signals or + /// when a Win32 object becomes signaled). + virtual int handle_signal (int signum, + siginfo_t * = 0, + ucontext_t * = 0); + +private: + /// Keeps track of our state. + TYPE is_set_; + + /// Protect the state from race conditions. + ACE_LOCK lock_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Test_and_Set.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Test_and_Set.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TEST_AND_SET_H */ diff --git a/dep/ACE_wrappers/ace/Thread.cpp b/dep/ACE_wrappers/ace/Thread.cpp new file mode 100644 index 000000000..43d9a25ba --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread.cpp @@ -0,0 +1,99 @@ +// $Id: Thread.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Thread.h" + +ACE_RCSID(ace, + Thread, + "$Id: Thread.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (__ACE_INLINE__) +#include "ace/Thread.inl" +#endif /* !defined (__ACE_INLINE__) */ + +#if defined (ACE_HAS_THREADS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +size_t +ACE_Thread::spawn_n (size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + long priority, + void *stack[], + size_t stack_size[], + ACE_Thread_Adapter *thread_adapter, + const char* thr_name[]) +{ + ACE_TRACE ("ACE_Thread::spawn_n"); + ACE_thread_t t_id; + size_t i; + + for (i = 0; i < n; i++) + // Bail out if error occurs. + if (ACE_OS::thr_create (func, + arg, + flags, + &t_id, + 0, + priority, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i], + thread_adapter, + thr_name == 0 ? 0 : &thr_name[i]) != 0) + break; + + return i; +} + +size_t +ACE_Thread::spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + long priority, + void *stack[], + size_t stack_size[], + ACE_hthread_t thread_handles[], + ACE_Thread_Adapter *thread_adapter, + const char* thr_name[]) +{ + ACE_TRACE ("ACE_Thread::spawn_n"); + size_t i = 0; + + for (i = 0; i < n; i++) + { + ACE_thread_t t_id; + ACE_hthread_t t_handle; + + int const result = + ACE_OS::thr_create (func, + arg, + flags, + &t_id, + &t_handle, + priority, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i], + thread_adapter, + thr_name == 0 ? 0 : &thr_name[i]); + + if (result == 0) + { + if (thread_ids != 0) + thread_ids[i] = t_id; + if (thread_handles != 0) + thread_handles[i] = t_handle; + } + else + // Bail out if error occurs. + break; + } + + return i; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Thread.h b/dep/ACE_wrappers/ace/Thread.h new file mode 100644 index 000000000..4d44858fa --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread.h @@ -0,0 +1,282 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Thread.h + * + * $Id: Thread.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas Schmidt + */ +//========================================================================== + +#ifndef ACE_THREAD_H +#define ACE_THREAD_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_Thread.h" +#include "ace/Thread_Adapter.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +struct cancel_state +{ + /// e.g., PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE, + /// PTHREAD_CANCELED. + int cancelstate; + + /// e.g., PTHREAD_CANCEL_DEFERRED and PTHREAD_CANCEL_ASYNCHRONOUS. + int canceltype; +}; + +/** + * @class ACE_Thread + * + * @brief Provides a wrapper for threads. + * + * This class provides a common interface that is mapped onto + * POSIX Pthreads, Solaris threads, Win32 threads, VxWorks + * threads, or pSoS threads. Note, however, that it is + * generally a better idea to use the ACE_Thread_Manager + * programming API rather than the API since the + * thread manager is more powerful. + */ +class ACE_Export ACE_Thread +{ +public: + /** + * Creates a new thread having @a flags attributes and running @a func + * with (if is non-0 then @a func and + * are ignored and are obtained from ). + * and are set to the thread's ID and handle (?), + * respectively. The thread runs at @a priority priority (see + * below). + * + * The @a flags are a bitwise-OR of the following: + * = BEGIN + * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED, + * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED, + * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO, + * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED, + * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS + * = END + * + * By default, or if @a priority is set to + * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for + * the given scheduling policy (specified in , e.g., + * ) is used. This value is calculated + * dynamically, and is the median value between the minimum and + * maximum priority values for the given policy. If an explicit + * value is given, it is used. Note that actual priority values are + * EXTREMEMLY implementation-dependent, and are probably best + * avoided. + * + * Note that is always deleted when + * is called, so it must be allocated with global operator new. + */ + static int spawn (ACE_THR_FUNC func, + void *arg = 0, + long flags = THR_NEW_LWP | THR_JOINABLE, + ACE_thread_t *t_id = 0, + ACE_hthread_t *t_handle = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + void *stack = 0, + size_t stack_size = ACE_DEFAULT_THREAD_STACKSIZE, + ACE_Thread_Adapter *thread_adapter = 0, + const char** thr_name = 0); + + /** + * Spawn N new threads, which execute @a func with argument @a arg (if + * @a thread_adapter is non-0 then @a func and @a args are ignored and + * are obtained from @a thread_adapter). If @a stack != 0 it is + * assumed to be an array of @a n pointers to the base of the stacks + * to use for the threads being spawned. Likewise, if @a stack_size + * != 0 it is assumed to be an array of @a n values indicating how + * big each of the corresponding @a stacks are. Returns the number + * of threads actually spawned (if this doesn't equal the number + * requested then something has gone wrong and @c errno will + * explain...). + * + * @see spawn() + */ + static size_t spawn_n (size_t n, + ACE_THR_FUNC func, + void *arg = 0, + long flags = THR_NEW_LWP | THR_JOINABLE, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_Thread_Adapter *thread_adapter = 0, + const char* thr_name[] = 0); + + /** + * Spawn @a n new threads, which execute @a func with argument @a arg + * (if @a thread_adapter is non-0 then @a func and @a args are ignored + * and are obtained from @a thread_adapter). The thread_ids of + * successfully spawned threads will be placed into the + * buffer (which must be the same size as @a n). If @a stack != 0 it + * is assumed to be an array of @a n pointers to the base of the + * stacks to use for the threads being spawned. If @a stack_size != + * 0 it is assumed to be an array of @a n values indicating how big + * each of the corresponding @a stacks are. If @a thread_handles != 0 + * it is assumed to be an array of @a n thread_handles that will be + * assigned the values of the thread handles being spawned. Returns + * the number of threads actually spawned (if this doesn't equal the + * number requested then something has gone wrong and @c errno will + * explain...). + * + * @see spawn() + */ + static size_t spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_hthread_t thread_handles[] = 0, + ACE_Thread_Adapter *thread_adapter = 0, + const char* thr_name[] = 0); + + /** + * Wait for one or more threads to exit and reap their exit status. + * thr_join() returns successfully when the target thread terminates. + * + * @param thread_id is the ACE_thread_t ID of the thread to wait for. + * If @a thread_id is 0, join() waits for any + * undetached thread in the process to terminate + * on platforms that support this capability + * (for example, Solaris). + * @param departed points to a location that is set to the ID of the + * terminated thread if join() returns successfully. + * If @a departed is 0, it is ignored. + * @param status Points to the location that receives the joined + * thread's exit value. If @a status is 0, it is ignored. + * + * @retval 0 for success + * @retval -1 (with errno set) for failure. + */ + static int join (ACE_thread_t thread_id, + ACE_thread_t *departed, + ACE_THR_FUNC_RETURN *status); + + /// Wait for one thread to exit and reap its exit status. + static int join (ACE_hthread_t, + ACE_THR_FUNC_RETURN * = 0); + + /// Continue the execution of a previously suspended thread. + static int resume (ACE_hthread_t); + + /// Suspend the execution of a particular thread. + static int suspend (ACE_hthread_t); + + /// Get the priority of a particular thread. + static int getprio (ACE_hthread_t ht_id, int &priority); + + /// Get the priority and policy of a particular thread. + static int getprio (ACE_hthread_t ht_id, int &priority, int &policy); + + /// Set the priority of a particular thread. + static int setprio (ACE_hthread_t ht_id, int priority, int policy = -1); + + /// Send a signal to the thread. + static int kill (ACE_thread_t, int signum); + + /// Yield the thread to another. + static void yield (void); + + /** + * Return the unique kernel handle of the thread. Note that on + * Win32 this is actually a pseudohandle, which cannot be shared + * with other processes or waited on by threads. To locate the real + * handle, please use the ACE_Thread_Manager::thr_self() method. + */ + static void self (ACE_hthread_t &t_handle); + + /// Return the unique ID of the thread. + static ACE_thread_t self (void); + + /// Exit the current thread and return "status". + /// Should _not_ be called by main thread. + static void exit (ACE_THR_FUNC_RETURN status = 0); + + /// Get the LWP concurrency level of the process. + static int getconcurrency (void); + + /// Set the LWP concurrency level of the process. + static int setconcurrency (int new_level); + + /// Change and/or examine calling thread's signal mask. + static int sigsetmask (int how, + const sigset_t *sigset, + sigset_t *osigset = 0); + + /** + * Allocates a @a keyp that is used to identify data that is specific + * to each thread in the process. The key is global to all threads + * in the process. + */ + static int keycreate (ACE_thread_key_t *keyp, +#if defined (ACE_HAS_THR_C_DEST) + ACE_THR_C_DEST destructor, +#else + ACE_THR_DEST destructor, +#endif /* ACE_HAS_THR_C_DEST */ + void * = 0); + + /// Free up the key so that other threads can reuse it. + static int keyfree (ACE_thread_key_t key); + + /// Bind value to the thread-specific data key, @a key, for the calling + /// thread. + static int setspecific (ACE_thread_key_t key, + void *value); + + /// Stores the current value bound to @a key for the calling thread + /// into the location pointed to by @a valuep. + static int getspecific (ACE_thread_key_t key, + void **valuep); + + /// Disable thread cancellation. + static int disablecancel (struct cancel_state *old_state); + + /// Enable thread cancellation. + static int enablecancel (struct cancel_state *old_state, + int flag); + + /// Set the cancellation state. + static int setcancelstate (struct cancel_state &new_state, + struct cancel_state *old_state); + + /** + * Cancel a thread. + * @note This method is only portable on platforms, such as POSIX pthreads, + * that support thread cancellation. + */ + static int cancel (ACE_thread_t t_id); + + /// Test the cancel. + static void testcancel (void); + +private: + /// Ensure that we don't get instantiated. + ACE_Thread (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Thread.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_THREAD_H */ diff --git a/dep/ACE_wrappers/ace/Thread.inl b/dep/ACE_wrappers/ace/Thread.inl new file mode 100644 index 000000000..87e47e135 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread.inl @@ -0,0 +1,286 @@ +// -*- C++ -*- +// +// $Id: Thread.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Allocates a that is used to identify data that is specific +// to each thread in the process. The key is global to all threads in +// the process. + +ACE_INLINE int +ACE_Thread::keycreate (ACE_thread_key_t *keyp, +#if defined (ACE_HAS_THR_C_DEST) + ACE_THR_C_DEST destructor, +#else + ACE_THR_DEST destructor, +#endif /* ACE_HAS_THR_C_DEST */ + void *inst) +{ + // ACE_TRACE ("ACE_Thread::keycreate"); + return ACE_OS::thr_keycreate (keyp, destructor, inst); +} + +// Free up the key so that other threads can reuse it. + +ACE_INLINE int +ACE_Thread::keyfree (ACE_thread_key_t key) +{ + ACE_TRACE ("ACE_Thread::keyfree"); + return ACE_OS::thr_keyfree (key); +} + +// Bind value to the thread-specific data key, , for the calling +// thread. + +ACE_INLINE int +ACE_Thread::setspecific (ACE_thread_key_t key, void *value) +{ + // ACE_TRACE ("ACE_Thread::setspecific"); + return ACE_OS::thr_setspecific (key, value); +} + +// Stores the current value bound to for the calling thread +// into the location pointed to by . + +ACE_INLINE int +ACE_Thread::getspecific (ACE_thread_key_t key, void **valuep) +{ + // ACE_TRACE ("ACE_Thread::getspecific"); + return ACE_OS::thr_getspecific (key, valuep); +} + +ACE_INLINE ACE_thread_t +ACE_Thread::self (void) +{ +// ACE_TRACE ("ACE_Thread::self"); + return ACE_OS::thr_self (); +} + +ACE_INLINE void +ACE_Thread::exit (ACE_THR_FUNC_RETURN status) +{ + ACE_TRACE ("ACE_Thread::exit"); + ACE_OS::thr_exit (status); +} + +ACE_INLINE void +ACE_Thread::yield (void) +{ + ACE_TRACE ("ACE_Thread::yield"); + ACE_OS::thr_yield (); +} + +ACE_INLINE int +ACE_Thread::spawn (ACE_THR_FUNC func, + void *arg, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + long priority, + void *thr_stack, + size_t thr_stack_size, + ACE_Thread_Adapter *thread_adapter, + const char** thr_name) +{ + ACE_TRACE ("ACE_Thread::spawn"); + + return ACE_OS::thr_create (func, + arg, + flags, + t_id, + t_handle, + priority, + thr_stack, + thr_stack_size, + thread_adapter, + thr_name); +} + +ACE_INLINE int +ACE_Thread::resume (ACE_hthread_t t_id) +{ + ACE_TRACE ("ACE_Thread::resume"); + return ACE_OS::thr_continue (t_id); +} + +ACE_INLINE int +ACE_Thread::suspend (ACE_hthread_t t_id) +{ + ACE_TRACE ("ACE_Thread::suspend"); + return ACE_OS::thr_suspend (t_id); +} + +ACE_INLINE int +ACE_Thread::kill (ACE_thread_t t_id, int signum) +{ + ACE_TRACE ("ACE_Thread::kill"); + return ACE_OS::thr_kill (t_id, signum); +} + +ACE_INLINE int +ACE_Thread::join (ACE_thread_t wait_for, + ACE_thread_t *departed, + ACE_THR_FUNC_RETURN *status) +{ + ACE_TRACE ("ACE_Thread::join"); + return ACE_OS::thr_join (wait_for, departed, status); +} + +ACE_INLINE int +ACE_Thread::join (ACE_hthread_t wait_for, + ACE_THR_FUNC_RETURN *status) +{ + ACE_TRACE ("ACE_Thread::join"); + return ACE_OS::thr_join (wait_for, status); +} + +ACE_INLINE int +ACE_Thread::getconcurrency (void) +{ + ACE_TRACE ("ACE_Thread::getconcurrency"); + return ACE_OS::thr_getconcurrency (); +} + +ACE_INLINE int +ACE_Thread::setconcurrency (int new_level) +{ + ACE_TRACE ("ACE_Thread::setconcurrency"); + return ACE_OS::thr_setconcurrency (new_level); +} + +ACE_INLINE int +ACE_Thread::sigsetmask (int how, + const sigset_t *sigset, + sigset_t *osigset) +{ + ACE_TRACE ("ACE_Thread::sigsetmask"); + return ACE_OS::thr_sigsetmask (how, sigset, osigset); +} + +ACE_INLINE int +ACE_Thread::disablecancel (struct cancel_state *old_state) +{ + ACE_TRACE ("ACE_Thread::disablecancel"); + int old_cstate = 0; + int result = ACE_OS::thr_setcancelstate (THR_CANCEL_DISABLE, + &old_cstate); + if (result == 0 && old_state != 0) + { + ACE_OS::memset (old_state, + 0, + sizeof (old_state)); + old_state->cancelstate = old_cstate; + } + + return result; +} + +ACE_INLINE int +ACE_Thread::enablecancel (struct cancel_state *old_state, + int flag) +{ + ACE_TRACE ("ACE_Thread::enablecancel"); + int old_cstate = 0; + int old_ctype = 0; + int result; + + result = ACE_OS::thr_setcancelstate (THR_CANCEL_ENABLE, + &old_cstate); + if (result != 0) + return result; + + result = ACE_OS::thr_setcanceltype (flag, + &old_ctype); + if (result != 0) + return result; + + if (old_state != 0) + { + old_state->cancelstate = old_cstate; + old_state->canceltype = old_ctype; + } + + return 0; +} + +ACE_INLINE int +ACE_Thread::setcancelstate (struct cancel_state &new_state, + struct cancel_state *old_state) +{ + ACE_TRACE ("ACE_Thread::setcancelstate"); + int old_cstate = 0; + int old_ctype = 0; + + if (new_state.cancelstate != 0 + && ACE_OS::thr_setcancelstate (new_state.cancelstate, + &old_cstate) != 0) + return -1; + + if (new_state.canceltype != 0 + && ACE_OS::thr_setcanceltype (new_state.canceltype, + &old_ctype) != 0) + { + int o_cstate; + + ACE_OS::thr_setcancelstate (old_cstate, + &o_cstate); + return -1; + } + + if (old_state != 0) + { + old_state->cancelstate = old_cstate; + old_state->canceltype = old_ctype; + } + + return 0; +} + +ACE_INLINE int +ACE_Thread::cancel (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread::cancel"); + + return ACE_OS::thr_cancel (t_id); +} + +ACE_INLINE void +ACE_Thread::testcancel (void) +{ + ACE_TRACE ("ACE_Thread::testcancel"); + + ACE_OS::thr_testcancel (); +} + +ACE_INLINE void +ACE_Thread::self (ACE_hthread_t &t_id) +{ +// ACE_TRACE ("ACE_Thread::self"); + ACE_OS::thr_self (t_id); +} + +ACE_INLINE int +ACE_Thread::getprio (ACE_hthread_t ht_id, int &priority) +{ + ACE_TRACE ("ACE_Thread::getprio"); + return ACE_OS::thr_getprio (ht_id, priority); +} + +ACE_INLINE int +ACE_Thread::getprio (ACE_hthread_t ht_id, int &priority, int &policy) +{ + ACE_TRACE ("ACE_Thread::getprio"); + return ACE_OS::thr_getprio (ht_id, priority, policy); +} + +ACE_INLINE int +ACE_Thread::setprio (ACE_hthread_t ht_id, int priority, int policy) +{ + ACE_TRACE ("ACE_Thread::setprio"); + return ACE_OS::thr_setprio (ht_id, priority, policy); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Adapter.cpp b/dep/ACE_wrappers/ace/Thread_Adapter.cpp new file mode 100644 index 000000000..9dbad0580 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Adapter.cpp @@ -0,0 +1,228 @@ +// $Id: Thread_Adapter.cpp 81239 2008-04-04 22:28:48Z iliyan $ + +#include "ace/Thread_Adapter.h" +#include "ace/Thread_Manager.h" +#include "ace/Thread_Exit.h" +#include "ace/Thread_Hook.h" +#include "ace/Object_Manager_Base.h" +#include "ace/Service_Config.h" + +ACE_RCSID (ace, + Thread_Adapter, + "$Id: Thread_Adapter.cpp 81239 2008-04-04 22:28:48Z iliyan $") + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "ace/Thread_Adapter.inl" +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Thread_Adapter::ACE_Thread_Adapter (ACE_THR_FUNC user_func, + void *arg, + ACE_THR_C_FUNC entry_point, + ACE_Thread_Manager *tm, + ACE_Thread_Descriptor *td +#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , ACE_SEH_EXCEPT_HANDLER selector, + ACE_SEH_EXCEPT_HANDLER handler +#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ) + : ACE_Base_Thread_Adapter ( + user_func + , arg + , entry_point + , td +#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , selector + , handler +#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ) + , thr_mgr_ (tm) +{ + ACE_OS_TRACE ("ACE_Thread_Adapter::ACE_Thread_Adapter"); +} + +ACE_Thread_Adapter::~ACE_Thread_Adapter (void) +{ +} + +ACE_THR_FUNC_RETURN +ACE_Thread_Adapter::invoke (void) +{ + // Inherit the logging features if the parent thread has an + // ACE_Log_Msg instance in thread-specific storage. + this->inherit_log_msg (); + + ACE_Service_Config::current (ACE_Service_Config::global()); + +#if !defined(ACE_USE_THREAD_MANAGER_ADAPTER) + // NOTE: this preprocessor directive should match the one in above + // ACE_Thread_Exit::instance (). With the Xavier Pthreads package, + // the exit_hook in TSS causes a seg fault. So, this works around + // that by creating exit_hook on the stack. +# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION) + // Obtain our thread-specific exit hook and make sure that it knows + // how to clean us up! Note that we never use this pointer directly + // (it's stored in thread-specific storage), so it's ok to + // dereference it here and only store it as a reference. + + // Except if it is null, then the thr_mgr() method crashes. + // -jxh + + ACE_Thread_Exit *exit_hook_instance = ACE_Thread_Exit::instance (); + ACE_Thread_Exit_Maybe exit_hook_maybe (exit_hook_instance == 0); + ACE_Thread_Exit *exit_hook_ptr = exit_hook_instance + ? exit_hook_instance + : exit_hook_maybe.instance (); + ACE_Thread_Exit &exit_hook = *exit_hook_ptr; + + if (this->thr_mgr () != 0) + { + // Keep track of the that's associated with this + // . + exit_hook.thr_mgr (this->thr_mgr ()); + } +# else + // Without TSS, create an instance. When this + // function returns, its destructor will be called because the + // object goes out of scope. The drawback with this appraoch is + // that the destructor _won't_ get called if is called. + // So, threads shouldn't exit that way. Instead, they should return + // from . + ACE_Thread_Exit exit_hook; + exit_hook.thr_mgr (this->thr_mgr ()); +# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ + +#endif /* ! ACE_USE_THREAD_MANAGER_ADAPTER */ + + return this->invoke_i (); +} + +ACE_THR_FUNC_RETURN +ACE_Thread_Adapter::invoke_i (void) +{ + // Extract the arguments. + ACE_THR_FUNC func = reinterpret_cast (this->user_func_); + void *arg = this->arg_; + +#if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) + ACE_OS_Thread_Descriptor *thr_desc = this->thr_desc_; +#endif /* ACE_WIN32 && ACE_HAS_MFC && (ACE_HAS_MFC != 0) */ + + // Delete ourselves since we don't need anymore. Make sure + // not to access anywhere below this point. + delete this; + +#if defined (ACE_NEEDS_LWP_PRIO_SET) + // On SunOS, the LWP priority needs to be set in order to get + // preemption when running in the RT class. This is the ACE way to + // do that . . . + ACE_hthread_t thr_handle; + ACE_OS::thr_self (thr_handle); + int prio; + + // thr_getprio () on the current thread should never fail. + ACE_OS::thr_getprio (thr_handle, prio); + + // ACE_OS::thr_setprio () has the special logic to set the LWP priority, + // if running in the RT class. + ACE_OS::thr_setprio (prio); + +#endif /* ACE_NEEDS_LWP_PRIO_SET */ + + ACE_THR_FUNC_RETURN status = 0; + + ACE_SEH_TRY + { + ACE_SEH_TRY + { + ACE_Thread_Hook *hook = + ACE_OS_Object_Manager::thread_hook (); + + if (hook) + // Invoke the start hook to give the user a chance to + // perform some initialization processing before the + // is invoked. + status = hook->start (func, arg); + else + // Call thread entry point. + status = (*func) (arg); + } + +#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + ACE_SEH_EXCEPT (ACE_OS_Object_Manager::seh_except_selector ()( + (void *) GetExceptionInformation ())) + { + ACE_OS_Object_Manager::seh_except_handler ()(0); + } +#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + } + + ACE_SEH_FINALLY + { + // If we changed this to 1, change the respective if in + // Task::svc_run to 0. +#if 0 + // Call the close> hook. + if (func == reinterpret_cast ( + ACE_Task_Base::svc_run)) + { + ACE_Task_Base *task_ptr = (ACE_Task_Base *) arg; + ACE_Thread_Manager *thr_mgr_ptr = task_ptr->thr_mgr (); + + // This calls the Task->close () hook. + task_ptr->cleanup (task_ptr, 0); + + // This prevents a second invocation of the cleanup code + // (called later by . + thr_mgr_ptr->at_exit (task_ptr, 0, 0); + } +#endif /* 0 */ + +#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) +# if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) + int using_afx = -1; + if (thr_desc) + using_afx = ACE_BIT_ENABLED (thr_desc->flags (), THR_USE_AFX); +# endif /* ACE_WIN32 && ACE_HAS_MFC && (ACE_HAS_MFC != 0) */ + // Call TSS destructors. + ACE_OS::cleanup_tss (0 /* not main thread */); + +# if defined (ACE_WIN32) + // Exit the thread. Allow CWinThread-destructor to be invoked + // from AfxEndThread. _endthreadex will be called from + // AfxEndThread so don't exit the thread now if we are running + // an MFC thread. +# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) + if (using_afx != -1) + { + if (using_afx) + ::AfxEndThread ((DWORD) status); + else + ACE_ENDTHREADEX (status); + } + else + { + // Not spawned by ACE_Thread_Manager, use the old buggy + // version. You should seriously consider using + // ACE_Thread_Manager to spawn threads. The following code + // is know to cause some problem. + CWinThread *pThread = ::AfxGetThread (); + + if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ()) + ACE_ENDTHREADEX (status); + else + ::AfxEndThread ((DWORD)status); + } +# else + + ACE_ENDTHREADEX (status); +# endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/ +# endif /* ACE_WIN32 */ +#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */ + } + + return status; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Adapter.h b/dep/ACE_wrappers/ace/Thread_Adapter.h new file mode 100644 index 000000000..8f1f259ef --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Adapter.h @@ -0,0 +1,100 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Thread_Adapter.h + * + * $Id: Thread_Adapter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//============================================================================= + +#ifndef ACE_THREAD_ADAPTER_H +#define ACE_THREAD_ADAPTER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Base_Thread_Adapter.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl. +class ACE_Thread_Manager; +class ACE_Thread_Descriptor; + +/** + * @class ACE_Thread_Adapter + * + * @brief Converts a C++ function into a function that + * can be called from a thread creation routine + * (e.g., pthread_create() or _beginthreadex()) that expects an + * extern "C" entry point. This class also makes it possible to + * transparently provide hooks to register a thread with an + * ACE_Thread_Manager. + * + * This class is used in ACE_OS::thr_create(). In general, the + * thread that creates an object of this class is different from + * the thread that calls @c invoke() on this object. Therefore, + * the @c invoke() method is responsible for deleting itself. + */ +class ACE_Export ACE_Thread_Adapter : public ACE_Base_Thread_Adapter +{ +public: + /// Constructor. + ACE_Thread_Adapter (ACE_THR_FUNC user_func, + void *arg, + ACE_THR_C_FUNC entry_point = (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, + ACE_Thread_Manager *thr_mgr = 0, + ACE_Thread_Descriptor *td = 0 +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , ACE_SEH_EXCEPT_HANDLER selector = 0, + ACE_SEH_EXCEPT_HANDLER handler = 0 +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ); + + /** + * Execute the with the . This function deletes + * @c this, thereby rendering the object useless after the call + * returns. + */ + virtual ACE_THR_FUNC_RETURN invoke (void); + + /// Accessor for the optional ACE_Thread_Manager. + ACE_Thread_Manager *thr_mgr (void); + +protected: + + /// Ensure that this object must be allocated on the heap. + ~ACE_Thread_Adapter (void); + +private: + + /// Called by invoke, mainly here to separate the SEH stuff because + /// SEH on Win32 doesn't compile with local vars with destructors. + virtual ACE_THR_FUNC_RETURN invoke_i (void); + +private: + + /// Optional thread manager. + ACE_Thread_Manager *thr_mgr_; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "ace/Thread_Adapter.inl" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_ADAPTER_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Adapter.inl b/dep/ACE_wrappers/ace/Thread_Adapter.inl new file mode 100644 index 000000000..6def13be5 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Adapter.inl @@ -0,0 +1,13 @@ +// -*- C++ -*- +// +// $Id: Thread_Adapter.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ACE_Thread_Manager * +ACE_Thread_Adapter::thr_mgr (void) +{ + return this->thr_mgr_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Control.cpp b/dep/ACE_wrappers/ace/Thread_Control.cpp new file mode 100644 index 000000000..51d0f4c18 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Control.cpp @@ -0,0 +1,96 @@ +// $Id: Thread_Control.cpp 80826 2008-03-04 14:51:23Z wotte $ + +// +#include "ace/config-all.h" +#if defined (ACE_LEGACY_MODE) +// This silly include breaks a cycle when compiling in backwards +// compatibility mode +# include "ace/Thread_Exit.h" +#endif /* ACE_LEGACY_MODE */ +// + +#include "ace/Thread_Control.h" +#include "ace/Thread_Manager.h" + +ACE_RCSID(ace, Thread_Control, "$Id: Thread_Control.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "ace/Thread_Control.inl" +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_Thread_Control::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_OS_TRACE ("ACE_Thread_Control::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_Thread_Control::insert (ACE_Thread_Manager *tm, int insert) +{ + ACE_OS_TRACE ("ACE_Thread_Control::insert"); + + ACE_hthread_t t_id; + ACE_OS::thr_self (t_id); + this->tm_ = tm; + + if (insert) + return this->tm_->insert_thr (ACE_OS::thr_self (), t_id); + else + return 0; +} + +// Initialize the thread controller. + +ACE_Thread_Control::ACE_Thread_Control (ACE_Thread_Manager *t, + int insert) + : tm_ (t), + status_ (0) +{ + ACE_OS_TRACE ("ACE_Thread_Control::ACE_Thread_Control"); + + if (this->tm_ != 0 && insert) + { + ACE_hthread_t t_id; + ACE_OS::thr_self (t_id); + this->tm_->insert_thr (ACE_OS::thr_self (), t_id); + } +} + +// Automatically kill thread on exit. + +ACE_Thread_Control::~ACE_Thread_Control (void) +{ + ACE_OS_TRACE ("ACE_Thread_Control::~ACE_Thread_Control"); + +#if defined (ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS) || defined (ACE_HAS_TSS_EMULATION) || defined (ACE_WIN32) + this->exit (this->status_, 0); +#else + this->exit (this->status_, 1); +#endif /* ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS */ +} + +// Exit from thread (but clean up first). + +ACE_THR_FUNC_RETURN +ACE_Thread_Control::exit (ACE_THR_FUNC_RETURN exit_status, int do_thr_exit) +{ + ACE_OS_TRACE ("ACE_Thread_Control::exit"); + + if (this->tm_ != 0) + return this->tm_->exit (exit_status, do_thr_exit); + else + { +#if !defined (ACE_HAS_TSS_EMULATION) + // With ACE_HAS_TSS_EMULATION, we let ACE_Thread_Adapter::invoke () + // exit the thread after cleaning up TSS. + ACE_OS::thr_exit (exit_status); +#endif /* ! ACE_HAS_TSS_EMULATION */ + return 0; + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Control.h b/dep/ACE_wrappers/ace/Thread_Control.h new file mode 100644 index 000000000..3eb5185c8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Control.h @@ -0,0 +1,102 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Thread_Control.h + * + * $Id: Thread_Control.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//============================================================================= + + +#ifndef ACE_THREAD_CONTROL_H +#define ACE_THREAD_CONTROL_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Thread_Manager; + +/** + * @class ACE_Thread_Control + * + * @brief Used to keep track of a thread's activities within its entry + * point function. + * + * A ACE_Thread_Manager uses this class to ensure that threads + * it spawns automatically register and unregister themselves + * with it. + * This class can be stored in thread-specific storage using the + * ACE_TSS wrapper. When a thread exits the + * function deletes this object, thereby + * ensuring that it gets removed from its associated + * ACE_Thread_Manager. + */ +class ACE_Export ACE_Thread_Control +{ +public: + /// Initialize the thread control object. If @a insert != 0, then + /// register the thread with the Thread_Manager. + ACE_Thread_Control (ACE_Thread_Manager *tm = 0, + int insert = 0); + + /// Remove the thread from its associated and exit + /// the thread if is enabled. + ~ACE_Thread_Control (void); + + /// Remove this thread from its associated ACE_Thread_Manager and exit + /// the thread if @a do_thr_exit is enabled. + ACE_THR_FUNC_RETURN exit (ACE_THR_FUNC_RETURN status, + int do_thr_exit); + + /// Store the and use it to register ourselves for + /// correct shutdown. + int insert (ACE_Thread_Manager *tm, int insert = 0); + + /// Returns the current . + ACE_Thread_Manager *thr_mgr (void); + + /// Atomically set a new and return the old + /// . + ACE_Thread_Manager *thr_mgr (ACE_Thread_Manager *); + + /// Set the exit status (and return existing status). + ACE_THR_FUNC_RETURN status (ACE_THR_FUNC_RETURN status); + + /// Get the current exit status. + ACE_THR_FUNC_RETURN status (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the thread manager for this block of code. + ACE_Thread_Manager *tm_; + + /// Keeps track of the exit status for the thread. + ACE_THR_FUNC_RETURN status_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "ace/Thread_Control.inl" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_CONTROL_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Control.inl b/dep/ACE_wrappers/ace/Thread_Control.inl new file mode 100644 index 000000000..6ebd3ac2c --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Control.inl @@ -0,0 +1,46 @@ +// -*- C++ -*- +// +// $Id: Thread_Control.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Set the exit status. + +ACE_INLINE ACE_THR_FUNC_RETURN +ACE_Thread_Control::status (ACE_THR_FUNC_RETURN s) +{ + ACE_OS_TRACE ("ACE_Thread_Control::status"); + return this->status_ = s; +} + +// Get the exit status. + +ACE_INLINE ACE_THR_FUNC_RETURN +ACE_Thread_Control::status (void) +{ + ACE_OS_TRACE ("ACE_Thread_Control::status"); + return this->status_; +} + +// Returns the current . + +ACE_INLINE ACE_Thread_Manager * +ACE_Thread_Control::thr_mgr (void) +{ + ACE_OS_TRACE ("ACE_Thread_Control::thr_mgr"); + return this->tm_; +} + +// Atomically set a new and return the old +// . + +ACE_INLINE ACE_Thread_Manager * +ACE_Thread_Control::thr_mgr (ACE_Thread_Manager *tm) +{ + ACE_OS_TRACE ("ACE_Thread_Control::thr_mgr"); + ACE_Thread_Manager *o_tm = this->tm_; + this->tm_ = tm; + return o_tm; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Exit.cpp b/dep/ACE_wrappers/ace/Thread_Exit.cpp new file mode 100644 index 000000000..cc6a8620c --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Exit.cpp @@ -0,0 +1,123 @@ +// $Id: Thread_Exit.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Thread_Exit.h" +#include "ace/Managed_Object.h" +#include "ace/Thread_Manager.h" +#include "ace/Guard_T.h" + +ACE_RCSID(ace, Thread_Exit, "$Id: Thread_Exit.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +bool ACE_Thread_Exit::is_constructed_ = false; + +void +ACE_Thread_Exit::cleanup (void *instance) +{ + ACE_OS_TRACE ("ACE_Thread_Exit::cleanup"); + + delete (ACE_TSS_TYPE (ACE_Thread_Exit) *) instance; + + // Set the thr_exit_ static to null to keep things from crashing if + // ACE::fini() is enabled here. + ACE_Thread_Manager::thr_exit_ = 0; + + ACE_Thread_Exit::is_constructed_ = false; + // All TSS objects have been destroyed. Reset this flag so + // ACE_Thread_Exit singleton can be created again. +} + +// NOTE: this preprocessor directive should match the one in +// ACE_Task_Base::svc_run () below. This prevents the two statics +// from being defined. + +ACE_Thread_Exit * +ACE_Thread_Exit::instance (void) +{ +#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION) + ACE_OS_TRACE ("ACE_Thread_Exit::instance"); + + // Determines if we were dynamically allocated. + static ACE_TSS_TYPE (ACE_Thread_Exit) * volatile instance_; + + // Implement the Double Check pattern. + + if (!ACE_Thread_Exit::is_constructed_) + { + ACE_MT (ACE_Thread_Mutex *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_THREAD_EXIT_LOCK); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0)); + + if (!ACE_Thread_Exit::is_constructed_) + { + ACE_NEW_RETURN (instance_, + ACE_TSS_TYPE (ACE_Thread_Exit), + 0); + + ACE_Thread_Exit::is_constructed_ = true; + + ACE_Thread_Manager::set_thr_exit (instance_); + } + } + + return ACE_TSS_GET (instance_, ACE_Thread_Exit); +#else + return 0; +#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ +} + +// Grab hold of the Task * so that we can close() it in the +// destructor. + +ACE_Thread_Exit::ACE_Thread_Exit (void) +{ + ACE_OS_TRACE ("ACE_Thread_Exit::ACE_Thread_Exit"); +} + +// Set the this pointer... + +void +ACE_Thread_Exit::thr_mgr (ACE_Thread_Manager *tm) +{ + ACE_OS_TRACE ("ACE_Thread_Exit::thr_mgr"); + + if (tm != 0) + this->thread_control_.insert (tm, 0); +} + +// When this object is destroyed the Task is automatically closed +// down! + +ACE_Thread_Exit::~ACE_Thread_Exit (void) +{ + ACE_OS_TRACE ("ACE_Thread_Exit::~ACE_Thread_Exit"); +} + +ACE_Thread_Exit_Maybe::ACE_Thread_Exit_Maybe (int flag) + : instance_ (0) +{ + if (flag) + { + ACE_NEW (instance_, ACE_Thread_Exit); + } +} + +ACE_Thread_Exit_Maybe::~ACE_Thread_Exit_Maybe (void) +{ + delete this->instance_; +} + +ACE_Thread_Exit * +ACE_Thread_Exit_Maybe::operator -> (void) const +{ + return this->instance_; +} + +ACE_Thread_Exit * +ACE_Thread_Exit_Maybe::instance (void) const +{ + return this->instance_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Exit.h b/dep/ACE_wrappers/ace/Thread_Exit.h new file mode 100644 index 000000000..5b614e2e8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Exit.h @@ -0,0 +1,111 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Thread_Exit.h + * + * $Id: Thread_Exit.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//============================================================================= + + +#ifndef ACE_THREAD_EXIT_H +#define ACE_THREAD_EXIT_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Thread_Control.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Thread_Exit + * + * @brief Keep exit information for a Thread in thread specific storage. + * so that the thread-specific exit hooks will get called no + * matter how the thread exits (e.g., via , C++ + * or Win32 exception, "falling off the end" of the thread entry + * point function, etc.). + * + * This clever little helper class is stored in thread-specific + * storage using the wrapper. When a thread exits the + * function deletes this object, thereby + * closing it down gracefully. + */ +class ACE_Export ACE_Thread_Exit +{ +public: + /// Capture the Thread that will be cleaned up automatically. + ACE_Thread_Exit (void); + + /// Set the ACE_Thread_Manager. + void thr_mgr (ACE_Thread_Manager *tm); + + /// Destructor calls the thread-specific exit hooks when a thread + /// exits. + ~ACE_Thread_Exit (void); + + /// Singleton access point. + static ACE_Thread_Exit *instance (void); + + /// Cleanup method, used by the ACE_Object_Manager to destroy the + /// singleton. + static void cleanup (void *instance); + +private: + /// Automatically add/remove the thread from the + /// ACE_Thread_Manager. + ACE_Thread_Control thread_control_; + + /** + * Used to detect whether we should create a new instance (or not) + * within the instance method -- we don't trust the instance_ ptr + * because the destructor may have run (if ACE::fini() was called). + * See bug #526. + * We don't follow the singleton pattern due to dependency issues. + */ + static bool is_constructed_; +}; + +/** + * @class ACE_Thread_Exit_Maybe + * + * @brief A version of ACE_Thread_Exit that is created dynamically + * under the hood if the flag is set to TRUE. + * + * Allows the appearance of a "smart pointer", but is not + * always created. + */ +class ACE_Export ACE_Thread_Exit_Maybe +{ +public: + /// Don't create an ACE_Thread_Exit instance by default. + ACE_Thread_Exit_Maybe (int flag = 0); + + /// Destroys the underlying ACE_Thread_Exit instance if it exists. + ~ACE_Thread_Exit_Maybe (void); + + /// Delegates to underlying instance. + ACE_Thread_Exit * operator -> (void) const; + + /// Returns the underlying instance. + ACE_Thread_Exit * instance (void) const; + +private: + + /// Holds the underlying instance. + ACE_Thread_Exit *instance_; + +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_EXIT_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Hook.cpp b/dep/ACE_wrappers/ace/Thread_Hook.cpp new file mode 100644 index 000000000..79d937f9f --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Hook.cpp @@ -0,0 +1,33 @@ +// $Id: Thread_Hook.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Thread_Hook.h" +#include "ace/Object_Manager_Base.h" + +ACE_RCSID(ace, Thread_Hook, "$Id: Thread_Hook.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Thread_Hook::~ACE_Thread_Hook () +{ +} + +ACE_THR_FUNC_RETURN +ACE_Thread_Hook::start (ACE_THR_FUNC func, + void *arg) +{ + return (func) (arg); +} + +ACE_Thread_Hook * +ACE_Thread_Hook::thread_hook (ACE_Thread_Hook *hook) +{ + return ACE_OS_Object_Manager::thread_hook (hook); +} + +ACE_Thread_Hook * +ACE_Thread_Hook::thread_hook (void) +{ + return ACE_OS_Object_Manager::thread_hook (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Hook.h b/dep/ACE_wrappers/ace/Thread_Hook.h new file mode 100644 index 000000000..7bc3bcce4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Hook.h @@ -0,0 +1,65 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Thread_Hook.h + * + * $Id: Thread_Hook.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + */ +//============================================================================= + + +#ifndef ACE_THREAD_HOOK_H +#define ACE_THREAD_HOOK_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "ace/ACE_export.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Thread_Hook + * + * @brief This class makes it possible to provide user-defined "start" + * hooks that are called before the thread entry point function + * is invoked. + */ +class ACE_Export ACE_Thread_Hook +{ + +public: + + /// Destructor. + virtual ~ACE_Thread_Hook (void); + + /** + * This method can be overridden in a subclass to customize this + * pre-function call "hook" invocation that can perform + * initialization processing before the thread entry point @a func + * method is called back. The @a func and @a arg passed into the + * start hook are the same as those passed by the application that + * spawned the thread. + */ + virtual ACE_THR_FUNC_RETURN start (ACE_THR_FUNC func, + void *arg); + + /// sets the system wide thread hook, returns the previous thread + /// hook or 0 if none is set. + static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *hook); + + /// Returns the current system thread hook. + static ACE_Thread_Hook *thread_hook (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_HOOK_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Manager.cpp b/dep/ACE_wrappers/ace/Thread_Manager.cpp new file mode 100644 index 000000000..1cb7126b4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Manager.cpp @@ -0,0 +1,2221 @@ +// $Id: Thread_Manager.cpp 82600 2008-08-12 08:04:24Z johnnyw $ + +#include "ace/TSS_T.h" +#include "ace/Thread_Manager.h" +#include "ace/Dynamic.h" +#include "ace/Object_Manager.h" +#include "ace/Singleton.h" +#include "ace/Auto_Ptr.h" +#include "ace/Guard_T.h" +#include "ace/Time_Value.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/Truncate.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Thread_Manager.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Thread_Manager, + "$Id: Thread_Manager.cpp 82600 2008-08-12 08:04:24Z johnnyw $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_At_Thread_Exit::~ACE_At_Thread_Exit (void) +{ + this->do_apply (); +} + +ACE_At_Thread_Exit_Func::~ACE_At_Thread_Exit_Func (void) +{ + this->do_apply (); +} + +void +ACE_At_Thread_Exit_Func::apply (void) +{ + this->func_ (this->object_, this->param_); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Control) +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Manager) + +#if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) +// Process-wide Thread Manager. +ACE_Thread_Manager *ACE_Thread_Manager::thr_mgr_ = 0; + +// Controls whether the Thread_Manager is deleted when we shut down +// (we can only delete it safely if we created it!) +bool ACE_Thread_Manager::delete_thr_mgr_ = false; +#endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */ + +ACE_TSS_TYPE (ACE_Thread_Exit) *ACE_Thread_Manager::thr_exit_ = 0; + +int +ACE_Thread_Manager::set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit) *ptr) +{ + if (ACE_Thread_Manager::thr_exit_ == 0) + ACE_Thread_Manager::thr_exit_ = ptr; + else + return -1; + return 0; +} + +void +ACE_Thread_Manager::dump (void) +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Thread_Manager::dump"); + // Cast away const-ness of this in order to use its non-const lock_. + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, + ((ACE_Thread_Manager *) this)->lock_)); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncurrent_count_ = %d"), this->thr_list_.size ())); + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + iter.next ()->dump (); + } + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Thread_Descriptor::~ACE_Thread_Descriptor (void) +{ + delete this->sync_; +} + +void +ACE_Thread_Descriptor::at_pop (int apply) +{ + ACE_TRACE ("ACE_Thread_Descriptor::at_pop"); + // Get first at from at_exit_list + ACE_At_Thread_Exit* at = this->at_exit_list_; + // Remove at from at_exit list + this->at_exit_list_ = at->next_; + // Apply if required + if (apply) + { + at->apply (); + // Do the apply method + at->was_applied (true); + // Mark at has been applied to avoid double apply from + // at destructor + } + // If at is not owner delete at. + if (!at->is_owner ()) + delete at; +} + +void +ACE_Thread_Descriptor::at_push (ACE_At_Thread_Exit* cleanup, bool is_owner) +{ + ACE_TRACE ("ACE_Thread_Descriptor::at_push"); + cleanup->is_owner (is_owner); + cleanup->td_ = this; + cleanup->next_ = at_exit_list_; + at_exit_list_ = cleanup; +} + +int +ACE_Thread_Descriptor::at_exit (ACE_At_Thread_Exit& cleanup) +{ + ACE_TRACE ("ACE_Thread_Descriptor::at_exit"); + at_push (&cleanup, 1); + return 0; +} + +int +ACE_Thread_Descriptor::at_exit (ACE_At_Thread_Exit* cleanup) +{ + ACE_TRACE ("ACE_Thread_Descriptor::at_exit"); + if (cleanup==0) + return -1; + else + { + this->at_push (cleanup); + return 0; + } +} + +void +ACE_Thread_Descriptor::do_at_exit () +{ + ACE_TRACE ("ACE_Thread_Descriptor::do_at_exit"); + while (at_exit_list_!=0) + this->at_pop (); +} + +void +ACE_Thread_Descriptor::terminate () +{ + ACE_TRACE ("ACE_Thread_Descriptor::terminate"); + + if (!terminated_) + { + ACE_Log_Msg* log_msg = this->log_msg_; + terminated_ = true; + // Run at_exit hooks + this->do_at_exit (); + // We must remove Thread_Descriptor from Thread_Manager list + if (this->tm_ != 0) + { + int close_handle = 0; + +#if !defined (ACE_HAS_VXTHREADS) + // Threads created with THR_DAEMON shouldn't exist here, but + // just to be safe, let's put it here. + + if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_JOINING)) + { + if (ACE_BIT_DISABLED (this->flags_, THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (this->flags_, THR_JOINABLE)) + { + // Mark thread as terminated. + ACE_SET_BITS (this->thr_state_, ACE_Thread_Manager::ACE_THR_TERMINATED); + tm_->register_as_terminated (this); + // Must copy the information here because td will be + // "freed" below. + } +#if defined (ACE_WIN32) + else + { + close_handle = 1; + } +#endif /* ACE_WIN32 */ + } +#endif /* !ACE_HAS_VXTHREADS */ + + // Remove thread descriptor from the table. + if (this->tm_ != 0) + tm_->remove_thr (this, close_handle); + } + + // Check if we need delete ACE_Log_Msg instance + // If ACE_TSS_cleanup was not executed first log_msg == 0 + if (log_msg == 0) + { + // Only inform to ACE_TSS_cleanup that it must delete the log instance + // setting ACE_LOG_MSG thr_desc to 0. + ACE_LOG_MSG->thr_desc (0); + } + else + { + // Thread_Descriptor is the owner of the Log_Msg instance!! + // deleted. + this->log_msg_ = 0; + delete log_msg; + } + } +} + +int +ACE_Thread_Descriptor::at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param) +{ + ACE_TRACE ("ACE_Thread_Descriptor::at_exit"); + // To keep compatibility, when cleanup_hook is null really is a at_pop + // without apply. + if (cleanup_hook == 0) + { + if (this->at_exit_list_!= 0) + this->at_pop(0); + } + else + { + ACE_At_Thread_Exit* cleanup = 0; + ACE_NEW_RETURN (cleanup, + ACE_At_Thread_Exit_Func (object, + cleanup_hook, + param), + -1); + this->at_push (cleanup); + } + return 0; +} + +void +ACE_Thread_Descriptor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Thread_Descriptor::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_id_ = %d"), this->thr_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_handle_ = %d"), this->thr_handle_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_state_ = %d"), this->thr_state_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncleanup_info_.cleanup_hook_ = %x"), this->cleanup_info_.cleanup_hook_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = %x\n"), this->flags_)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Thread_Descriptor::ACE_Thread_Descriptor (void) + : log_msg_ (0), + at_exit_list_ (0), + terminated_ (false) +{ + ACE_TRACE ("ACE_Thread_Descriptor::ACE_Thread_Descriptor"); + ACE_NEW (this->sync_, + ACE_DEFAULT_THREAD_MANAGER_LOCK); +} + +void +ACE_Thread_Descriptor::acquire_release (void) +{ + // Just try to acquire the lock then release it. +#if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN) + if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED)) +#endif /* ACE_THREAD_MANAGER_USES_SAFE_SPAWN */ + { + this->sync_->acquire (); + // Acquire the lock before removing from the thread table. If + // this thread is in the table already, it should simply acquire the + // lock easily. + + // Once we get the lock, we must have registered. + ACE_ASSERT (ACE_BIT_ENABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED)); + + this->sync_->release (); + // Release the lock before putting it back to freelist. + } +} + +void +ACE_Thread_Descriptor::acquire (void) +{ + // Just try to acquire the lock then release it. +#if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN) + if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED)) +#endif /* ACE_THREAD_MANAGER_USES_SAFE_SPAWN */ + { + this->sync_->acquire (); + } +} + +void +ACE_Thread_Descriptor::release (void) +{ + // Just try to acquire the lock then release it. +#if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN) + if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED)) +#endif /* ACE_THREAD_MANAGER_USES_SAFE_SPAWN */ + { + this->sync_->release (); + // Release the lock before putting it back to freelist. + } +} + +// The following macro simplifies subsequence code. +#define ACE_FIND(OP,INDEX) \ + ACE_Thread_Descriptor *INDEX = OP; \ + +ACE_Thread_Descriptor * +ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id) +{ + ACE_TRACE ("ACE_Thread_Manager::thread_descriptor"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + ACE_FIND (this->find_thread (thr_id), ptr); + return ptr; +} + +ACE_Thread_Descriptor * +ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle) +{ + ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + ACE_FIND (this->find_hthread (thr_handle), ptr); + return ptr; +} + +// Return the thread descriptor (indexed by ACE_hthread_t). + +int +ACE_Thread_Manager::thr_self (ACE_hthread_t &self) +{ + ACE_TRACE ("ACE_Thread_Manager::thr_self"); + + ACE_Thread_Descriptor *desc = + this->thread_desc_self (); + + if (desc == 0) + return -1; + else + desc->self (self); + + return 0; +} + +// Initialize the synchronization variables. + +ACE_Thread_Manager::ACE_Thread_Manager (size_t prealloc, + size_t lwm, + size_t inc, + size_t hwm) + : grp_id_ (1), + automatic_wait_ (1) +#if defined (ACE_HAS_THREADS) + , zero_cond_ (lock_) +#endif /* ACE_HAS_THREADS */ + , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL, + prealloc, lwm, hwm, inc) +{ + ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager"); +} + +#if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) +ACE_Thread_Manager * +ACE_Thread_Manager::instance (void) +{ + ACE_TRACE ("ACE_Thread_Manager::instance"); + + if (ACE_Thread_Manager::thr_mgr_ == 0) + { + // Perform Double-Checked Locking Optimization. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + + if (ACE_Thread_Manager::thr_mgr_ == 0) + { + ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_, + ACE_Thread_Manager, + 0); + ACE_Thread_Manager::delete_thr_mgr_ = true; + } + } + + return ACE_Thread_Manager::thr_mgr_; +} + +ACE_Thread_Manager * +ACE_Thread_Manager::instance (ACE_Thread_Manager *tm) +{ + ACE_TRACE ("ACE_Thread_Manager::instance"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance (), 0)); + + ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_; + // We can't safely delete it since we don't know who created it! + ACE_Thread_Manager::delete_thr_mgr_ = false; + + ACE_Thread_Manager::thr_mgr_ = tm; + return t; +} + +void +ACE_Thread_Manager::close_singleton (void) +{ + ACE_TRACE ("ACE_Thread_Manager::close_singleton"); + + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance ())); + + if (ACE_Thread_Manager::delete_thr_mgr_) + { + // First, we clean up the thread descriptor list. + ACE_Thread_Manager::thr_mgr_->close (); + delete ACE_Thread_Manager::thr_mgr_; + ACE_Thread_Manager::thr_mgr_ = 0; + ACE_Thread_Manager::delete_thr_mgr_ = false; + } + + ACE_Thread_Exit::cleanup (ACE_Thread_Manager::thr_exit_); +} +#endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */ + +// Close up and release all resources. + +int +ACE_Thread_Manager::close () +{ + ACE_TRACE ("ACE_Thread_Manager::close"); + + // Clean up the thread descriptor list. + if (this->automatic_wait_) + this->wait (0, 1); + else + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + this->remove_thr_all (); + } + + return 0; +} + +ACE_Thread_Manager::~ACE_Thread_Manager (void) +{ + ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager"); + this->close (); +} + + +// Run the entry point for thread spawned under the control of the +// . This must be an extern "C" to make certain +// compilers happy... +// +// The interaction with and +// works like this, with +// ACE_HAS_THREAD_SPECIFIC_STORAGE or ACE_HAS_TSS_EMULATION: +// +// o Every thread in the is run with +// . +// +// o retrieves the singleton +// instance from . +// The singleton gets created in thread-specific storage +// in the first call to that function. The key point is that the +// instance is in thread-specific storage. +// +// o A thread can exit by various means, such as , C++ +// or Win32 exception, "falling off the end" of the thread entry +// point function, etc. +// +// o If you follow this so far, now it gets really fun . . . +// When the thread-specific storage (for the thread that +// is being destroyed) is cleaned up, the OS threads package (or +// the ACE emulation of thread-specific storage) will destroy any +// objects that are in thread-specific storage. It has a list of +// them, and just walks down the list and destroys each one. +// +// o That's where the ACE_Thread_Exit destructor gets called. + +#if defined(ACE_USE_THREAD_MANAGER_ADAPTER) +extern "C" void * +ace_thread_manager_adapter (void *args) +{ +#if defined (ACE_HAS_TSS_EMULATION) + // As early as we can in the execution of the new thread, allocate + // its local TS storage. Allocate it on the stack, to save dynamic + // allocation/dealloction. + void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]; + ACE_TSS_Emulation::tss_open (ts_storage); +#endif /* ACE_HAS_TSS_EMULATION */ + + ACE_Thread_Adapter *thread_args = reinterpret_cast (args); + + // NOTE: this preprocessor directive should match the one in above + // ACE_Thread_Exit::instance (). With the Xavier Pthreads package, + // the exit_hook in TSS causes a seg fault. So, this works around + // that by creating exit_hook on the stack. +#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION) + // Obtain our thread-specific exit hook and make sure that it knows + // how to clean us up! Note that we never use this pointer directly + // (it's stored in thread-specific storage), so it's ok to + // dereference it here and only store it as a reference. + ACE_Thread_Exit &exit_hook = *ACE_Thread_Exit::instance (); +#else + // Without TSS, create an instance. When this + // function returns, its destructor will be called because the + // object goes out of scope. The drawback with this appraoch is + // that the destructor _won't_ get called if is called. + // So, threads shouldn't exit that way. Instead, they should return + // from . + ACE_Thread_Exit exit_hook; +#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ + + // Keep track of the that's associated with this + // . + exit_hook.thr_mgr (thread_args->thr_mgr ()); + + // Invoke the user-supplied function with the args. + void *status = thread_args->invoke (); + + delete static_cast (thread_args); + return status; +} +#endif + +// Call the appropriate OS routine to spawn a thread. Should *not* be +// called with the lock_ held... + +int +ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + long priority, + int grp_id, + void *stack, + size_t stack_size, + ACE_Task_Base *task, + const char** thr_name) +{ + // First, threads created by Thread Manager should not be daemon threads. + // Using assertion is probably a bit too strong. However, it helps + // finding this kind of error as early as possible. Perhaps we can replace + // assertion by returning error. + ACE_ASSERT (ACE_BIT_DISABLED (flags, THR_DAEMON)); + + // Create a new thread running . *Must* be called with the + // held... + // Get a "new" Thread Descriptor from the freelist. + auto_ptr new_thr_desc (this->thread_desc_freelist_.remove ()); + + // Reset thread descriptor status + new_thr_desc->reset (this); + + ACE_Thread_Adapter *thread_args = 0; +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + ACE_NEW_RETURN (thread_args, + ACE_Thread_Adapter (func, + args, + (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, + this, + new_thr_desc.get (), + ACE_OS_Object_Manager::seh_except_selector(), + ACE_OS_Object_Manager::seh_except_handler()), + -1); +# else + ACE_NEW_RETURN (thread_args, + ACE_Thread_Adapter (func, + args, + (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, + this, + new_thr_desc.get ()), + -1); +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + auto_ptr auto_thread_args (static_cast (thread_args)); + + ACE_TRACE ("ACE_Thread_Manager::spawn_i"); + ACE_hthread_t thr_handle; + + ACE_thread_t thr_id; + if (t_id == 0) + t_id = &thr_id; + + // Acquire the lock to block the spawned thread from + // removing this Thread Descriptor before it gets put into our + // thread table. + new_thr_desc->sync_->acquire (); + + int const result = ACE_Thread::spawn (func, + args, + flags, + t_id, + &thr_handle, + priority, + stack, + stack_size, + thread_args, + thr_name); + + if (result != 0) + { + // _Don't_ clobber errno here! result is either 0 or -1, and + // ACE_OS::thr_create () already set errno! D. Levine 28 Mar 1997 + // errno = result; + ACE_Errno_Guard guard (errno); // Lock release may smash errno + new_thr_desc->sync_->release (); + return -1; + } + auto_thread_args.release (); + +#if defined (ACE_HAS_WTHREADS) + // Have to duplicate handle if client asks for it. + // @@ How are thread handles implemented on AIX? Do they + // also need to be duplicated? + if (t_handle != 0) +# if defined (ACE_HAS_WINCE) + *t_handle = thr_handle; +# else /* ! ACE_HAS_WINCE */ + (void) ::DuplicateHandle (::GetCurrentProcess (), + thr_handle, + ::GetCurrentProcess (), + t_handle, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); +# endif /* ! ACE_HAS_WINCE */ +#else /* ! ACE_HAS_WTHREADS */ + if (t_handle != 0) + *t_handle = thr_handle; +#endif /* ! ACE_HAS_WTHREADS */ + + // append_thr also put the into Thread_Manager's + // double-linked list. Only after this point, can we manipulate + // double-linked list from a spawned thread's context. + return this->append_thr (*t_id, + thr_handle, + ACE_THR_SPAWNED, + grp_id, + task, + flags, + new_thr_desc.release ()); +} + +int +ACE_Thread_Manager::spawn (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + long priority, + int grp_id, + void *stack, + size_t stack_size, + const char** thr_name) +{ + ACE_TRACE ("ACE_Thread_Manager::spawn"); + + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (grp_id == -1) + grp_id = this->grp_id_++; // Increment the group id. + + if (priority != ACE_DEFAULT_THREAD_PRIORITY) + ACE_CLR_BITS (flags, THR_INHERIT_SCHED); + + if (this->spawn_i (func, + args, + flags, + t_id, + t_handle, + priority, + grp_id, + stack, + stack_size, + 0, + thr_name) == -1) + return -1; + + return grp_id; +} + +// Create N new threads running FUNC. + +int +ACE_Thread_Manager::spawn_n (size_t n, + ACE_THR_FUNC func, + void *args, + long flags, + long priority, + int grp_id, + ACE_Task_Base *task, + ACE_hthread_t thread_handles[], + void *stack[], + size_t stack_size[], + const char* thr_name[]) +{ + ACE_TRACE ("ACE_Thread_Manager::spawn_n"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (grp_id == -1) + grp_id = this->grp_id_++; // Increment the group id. + + for (size_t i = 0; i < n; i++) + { + // @@ What should happen if this fails?! e.g., should we try to + // cancel the other threads that we've already spawned or what? + if (this->spawn_i (func, + args, + flags, + 0, + thread_handles == 0 ? 0 : &thread_handles[i], + priority, + grp_id, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i], + task, + thr_name == 0 ? 0 : &thr_name [i]) == -1) + return -1; + } + + return grp_id; +} + +// Create N new threads running FUNC. + +int +ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *args, + long flags, + long priority, + int grp_id, + void *stack[], + size_t stack_size[], + ACE_hthread_t thread_handles[], + ACE_Task_Base *task, + const char* thr_name[]) +{ + ACE_TRACE ("ACE_Thread_Manager::spawn_n"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (grp_id == -1) + grp_id = this->grp_id_++; // Increment the group id. + + for (size_t i = 0; i < n; i++) + { + // @@ What should happen if this fails?! e.g., should we try to + // cancel the other threads that we've already spawned or what? + if (this->spawn_i (func, + args, + flags, + thread_ids == 0 ? 0 : &thread_ids[i], + thread_handles == 0 ? 0 : &thread_handles[i], + priority, + grp_id, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i], + task, + thr_name == 0 ? 0 : &thr_name [i]) == -1) + return -1; + } + + return grp_id; +} + +// Append a thread into the pool (does not check for duplicates). +// Must be called with locks held. + +int +ACE_Thread_Manager::append_thr (ACE_thread_t t_id, + ACE_hthread_t t_handle, + ACE_UINT32 thr_state, + int grp_id, + ACE_Task_Base *task, + long flags, + ACE_Thread_Descriptor *td) +{ + ACE_TRACE ("ACE_Thread_Manager::append_thr"); + ACE_Thread_Descriptor *thr_desc = 0; + + if (td == 0) + { + ACE_NEW_RETURN (thr_desc, + ACE_Thread_Descriptor, + -1); + thr_desc->tm_ = this; + // Setup the Thread_Manager. + } + else + thr_desc = td; + + thr_desc->thr_id_ = t_id; + thr_desc->thr_handle_ = t_handle; + thr_desc->grp_id_ = grp_id; + thr_desc->task_ = task; + thr_desc->flags_ = flags; + + this->thr_list_.insert_head (thr_desc); + ACE_SET_BITS (thr_desc->thr_state_, thr_state); + thr_desc->sync_->release (); + + return 0; +} + +// Return the thread descriptor (indexed by ACE_hthread_t). + +ACE_Thread_Descriptor * +ACE_Thread_Manager::find_hthread (ACE_hthread_t h_id) +{ + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id)) + { + return iter.next (); + } + } + + return 0; +} + +// Locate the index in the table associated with . Must be +// called with the lock held. + +ACE_Thread_Descriptor * +ACE_Thread_Manager::find_thread (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::find_thread"); + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id)) + { + return iter.next (); + } + } + return 0; +} + +// Insert a thread into the pool (checks for duplicates and doesn't +// allow them to be inserted twice). + +int +ACE_Thread_Manager::insert_thr (ACE_thread_t t_id, + ACE_hthread_t t_handle, + int grp_id, + long flags) +{ + ACE_TRACE ("ACE_Thread_Manager::insert_thr"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + // Check for duplicates and bail out if we're already registered... + if (this->find_thread (t_id) != 0 ) + return -1; + + if (grp_id == -1) + grp_id = this->grp_id_++; + + if (this->append_thr (t_id, + t_handle, + ACE_THR_SPAWNED, + grp_id, + 0, + flags) == -1) + return -1; + + return grp_id; +} + +// Run the registered hooks when the thread exits. + +void +ACE_Thread_Manager::run_thread_exit_hooks (int i) +{ +#if 0 // currently unused! + ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks"); + + // @@ Currently, we have just one hook. This should clearly be + // generalized to support an arbitrary number of hooks. + + ACE_Thread_Descriptor *td = this->thread_desc_self (); + if (td != 0 && td->cleanup_info.cleanup_hook_ != 0) + { + (*td->cleanup_info_.cleanup_hook_) + (td->cleanup_info_.object_, + td->cleanup_info_.param_); + + td->cleanup_info_.cleanup_hook_ = 0; + } + ACE_UNUSED_ARG (i); +#else + ACE_UNUSED_ARG (i); +#endif /* 0 */ +} + +// Remove a thread from the pool. Must be called with locks held. + +void +ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td, + int close_handler) +{ + ACE_TRACE ("ACE_Thread_Manager::remove_thr"); + + td->tm_ = 0; + this->thr_list_.remove (td); + +#if defined (ACE_WIN32) + if (close_handler != 0) + ::CloseHandle (td->thr_handle_); +#else + ACE_UNUSED_ARG (close_handler); +#endif /* ACE_WIN32 */ + + this->thread_desc_freelist_.add (td); + +#if defined (ACE_HAS_THREADS) + // Tell all waiters when there are no more threads left in the pool. + if (this->thr_list_.size () == 0) + this->zero_cond_.broadcast (); +#endif /* ACE_HAS_THREADS */ +} + +// Repeatedly call remove_thr on all table entries until there +// is no thread left. Must be called with lock held. +void +ACE_Thread_Manager::remove_thr_all (void) +{ + ACE_Thread_Descriptor *td = 0; + + while ((td = this->thr_list_.delete_head ()) != 0) + { + this->remove_thr (td, 1); + } +} + +// ------------------------------------------------------------------ +// Factor out some common behavior to simplify the following methods. +#define ACE_THR_OP(OP,STATE) \ + int result = OP (td->thr_handle_); \ + if (result == -1) { \ + if (errno != ENOTSUP) \ + this->thr_to_be_removed_.enqueue_tail (td); \ + return -1; \ + } \ + else { \ + ACE_SET_BITS (td->thr_state_, STATE); \ + return 0; \ + } + +int +ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int) +{ + ACE_TRACE ("ACE_Thread_Manager::join_thr"); + int const result = ACE_Thread::join (td->thr_handle_); + if (result != 0) + { + // Since the thread are being joined, we should + // let it remove itself from the list. + + // this->remove_thr (td); + errno = result; + return -1; + } + + return 0; +} + +int +ACE_Thread_Manager::suspend_thr (ACE_Thread_Descriptor *td, int) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_thr"); + + int const result = ACE_Thread::suspend (td->thr_handle_); + if (result == -1) { + if (errno != ENOTSUP) + this->thr_to_be_removed_.enqueue_tail (td); + return -1; + } + else { + ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED); + return 0; + } +} + +int +ACE_Thread_Manager::resume_thr (ACE_Thread_Descriptor *td, int) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_thr"); + + int const result = ACE_Thread::resume (td->thr_handle_); + if (result == -1) { + if (errno != ENOTSUP) + this->thr_to_be_removed_.enqueue_tail (td); + return -1; + } + else { + ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED); + return 0; + } +} + +int +ACE_Thread_Manager::cancel_thr (ACE_Thread_Descriptor *td, int async_cancel) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel_thr"); + // Must set the state first and then try to cancel the thread. + ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED); + + if (async_cancel != 0) + // Note that this call only does something relevant if the OS + // platform supports asynchronous thread cancellation. Otherwise, + // it's a no-op. + return ACE_Thread::cancel (td->thr_id_); + + return 0; +} + +int +ACE_Thread_Manager::kill_thr (ACE_Thread_Descriptor *td, int signum) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_thr"); + + ACE_thread_t tid = td->thr_id_; + + int const result = ACE_Thread::kill (tid, signum); + + if (result != 0) + { + // Only remove a thread from us when there is a "real" error. + if (errno != ENOTSUP) + this->thr_to_be_removed_.enqueue_tail (td); + + return -1; + } + + return 0; +} + +// ------------------------------------------------------------------ +// Factor out some common behavior to simplify the following methods. +#define ACE_EXECUTE_OP(OP, ARG) \ + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); \ + ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); \ + ACE_FIND (this->find_thread (t_id), ptr); \ + if (ptr == 0) \ + { \ + errno = ENOENT; \ + return -1; \ + } \ + int result = OP (ptr, ARG); \ + ACE_Errno_Guard error (errno); \ + while (! this->thr_to_be_removed_.is_empty ()) { \ + ACE_Thread_Descriptor * td = 0; \ + this->thr_to_be_removed_.dequeue_head (td); \ + this->remove_thr (td, 1); \ + } \ + return result + +// Suspend a single thread. + +int +ACE_Thread_Manager::suspend (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend"); + ACE_EXECUTE_OP (this->suspend_thr, 0); +} + +// Resume a single thread. + +int +ACE_Thread_Manager::resume (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::resume"); + ACE_EXECUTE_OP (this->resume_thr, 0); +} + +// Cancel a single thread. + +int +ACE_Thread_Manager::cancel (ACE_thread_t t_id, int async_cancel) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel"); + ACE_EXECUTE_OP (this->cancel_thr, async_cancel); +} + +// Send a signal to a single thread. + +int +ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum) +{ + ACE_TRACE ("ACE_Thread_Manager::kill"); + ACE_EXECUTE_OP (this->kill_thr, signum); +} + +int +ACE_Thread_Manager::check_state (ACE_UINT32 state, + ACE_thread_t id, + int enable) +{ + ACE_TRACE ("ACE_Thread_Manager::check_state"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_UINT32 thr_state; + + int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ()); + + // If we're checking the state of our thread, try to get the cached + // value out of TSS to avoid lookup. + if (self_check) + { + ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); + if (desc == 0) + return 0; // Always return false. + thr_state = desc->thr_state_; + } + else + { + // Not calling from self, have to look it up from the list. + ACE_FIND (this->find_thread (id), ptr); + if (ptr == 0) + return 0; + thr_state = ptr->thr_state_; + } + if (enable) + return ACE_BIT_ENABLED (thr_state, state); + + return ACE_BIT_DISABLED (thr_state, state); +} + +// Test if a single thread has terminated. + +int +ACE_Thread_Manager::testterminate (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testterminate"); + return this->check_state (ACE_THR_TERMINATED, t_id); +} + +// Test if a single thread is suspended. + +int +ACE_Thread_Manager::testsuspend (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testsuspend"); + return this->check_state (ACE_THR_SUSPENDED, t_id); +} + +// Test if a single thread is active (i.e., resumed). + +int +ACE_Thread_Manager::testresume (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testresume"); + return this->check_state (ACE_THR_SUSPENDED, t_id, 0); +} + +// Test if a single thread is cancelled. + +int +ACE_Thread_Manager::testcancel (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testcancel"); + return this->check_state (ACE_THR_CANCELLED, t_id); +} + +// Thread information query functions. + +int +ACE_Thread_Manager::hthread_within (ACE_hthread_t handle) +{ + ACE_TRACE ("ACE_Thread_Manager::hthread_within"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1)); + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle)) + { + return 1; + } + } + + return 0; +} + +int +ACE_Thread_Manager::thread_within (ACE_thread_t tid) +{ + ACE_TRACE ("ACE_Thread_Manager::thread_within"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1)); + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid)) + { + return 1; + } + } + + return 0; +} + +// Get group ids for a particular thread id. + +int +ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::get_grp"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_FIND (this->find_thread (t_id), ptr); + + if (ptr) + grp_id = ptr->grp_id_; + else + return -1; + return 0; +} + +// Set group ids for a particular thread id. + +int +ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::set_grp"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_FIND (this->find_thread (t_id), ptr); + if (ptr) + ptr->grp_id_ = grp_id; + else + return -1; + return 0; +} + +// Suspend a group of threads. + +int +ACE_Thread_Manager::apply_grp (int grp_id, + ACE_THR_MEMBER_FUNC func, + int arg) +{ + ACE_TRACE ("ACE_Thread_Manager::apply_grp"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1)); + ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); + + int result = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (iter.next ()->grp_id_ == grp_id) + { + if ((this->*func) (iter.next (), arg) == -1) + { + result = -1; + } + } + } + + // Must remove threads after we have traversed the thr_list_ to + // prevent clobber thr_list_'s integrity. + + if (! this->thr_to_be_removed_.is_empty ()) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + + for (ACE_Thread_Descriptor *td; + this->thr_to_be_removed_.dequeue_head (td) != -1; + ) + this->remove_thr (td, 1); + } + + return result; +} + +int +ACE_Thread_Manager::suspend_grp (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_grp"); + return this->apply_grp (grp_id, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); +} + +// Resume a group of threads. + +int +ACE_Thread_Manager::resume_grp (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_grp"); + return this->apply_grp (grp_id, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); +} + +// Kill a group of threads. + +int +ACE_Thread_Manager::kill_grp (int grp_id, int signum) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_grp"); + return this->apply_grp (grp_id, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum); +} + +// Cancel a group of threads. + +int +ACE_Thread_Manager::cancel_grp (int grp_id, int async_cancel) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel_grp"); + return this->apply_grp (grp_id, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr), + async_cancel); +} + +int +ACE_Thread_Manager::apply_all (ACE_THR_MEMBER_FUNC func, int arg) +{ + ACE_TRACE ("ACE_Thread_Manager::apply_all"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); + + int result = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if ((this->*func)(iter.next (), arg) == -1) + { + result = -1; + } + } + + // Must remove threads after we have traversed the thr_list_ to + // prevent clobber thr_list_'s integrity. + + if (! this->thr_to_be_removed_.is_empty ()) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + + for (ACE_Thread_Descriptor *td; + this->thr_to_be_removed_.dequeue_head (td) != -1; + ) + this->remove_thr (td, 1); + } + + return result; +} + +// Resume all threads that are suspended. + +int +ACE_Thread_Manager::resume_all (void) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_all"); + return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); +} + +int +ACE_Thread_Manager::suspend_all (void) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_all"); + return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); +} + +int +ACE_Thread_Manager::kill_all (int sig) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_all"); + return this->apply_all (&ACE_Thread_Manager::kill_thr, sig); +} + +int +ACE_Thread_Manager::cancel_all (int async_cancel) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel_all"); + return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr), + async_cancel); +} + +int +ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status) +{ + ACE_TRACE ("ACE_Thread_Manager::join"); + + bool found = false; + ACE_Thread_Descriptor tdb; + + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + +#if !defined (ACE_HAS_VXTHREADS) + for (ACE_Double_Linked_List_Iterator biter (this->terminated_thr_list_); + !biter.done (); + biter.advance ()) + { + if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid)) + { + ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false); + if (ACE_Thread::join (tdb->thr_handle_, status) == -1) + { + return -1; + } + delete tdb; + + // return immediately if we've found the thread we want to join. + return 0; + } + } +#endif /* !ACE_HAS_VXTHREADS */ + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + // If threads are created as THR_DETACHED or THR_DAEMON, we + // can't help much. + if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) && + (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) + { + tdb = *iter.next (); + ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); + found = 1; + break; + } + } + + if (!found) + return -1; + // Didn't find the thread we want or the thread is not joinable. + } + + if (ACE_Thread::join (tdb.thr_handle_, status) == -1) + return -1; + + return 0; +} + +// Wait for group of threads + +int +ACE_Thread_Manager::wait_grp (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::wait_grp"); + + int copy_count = 0; + ACE_Thread_Descriptor_Base *copy_table = 0; + + // We have to make sure that while we wait for these threads to + // exit, we do not have the lock. Therefore we make a copy of all + // interesting entries and let go of the lock. + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + +#if !defined (ACE_HAS_VXTHREADS) + ACE_NEW_RETURN (copy_table, + ACE_Thread_Descriptor_Base [this->thr_list_.size () + + this->terminated_thr_list_.size ()], + -1); +#else + ACE_NEW_RETURN (copy_table, + ACE_Thread_Descriptor_Base [this->thr_list_.size ()], + -1); +#endif /* !ACE_HAS_VXTHREADS */ + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + // If threads are created as THR_DETACHED or THR_DAEMON, we + // can't help much. + if (iter.next ()->grp_id_ == grp_id && + (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) + { + ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); + copy_table[copy_count++] = *iter.next (); + } + } + +#if !defined (ACE_HAS_VXTHREADS) + for (ACE_Double_Linked_List_Iterator biter (this->terminated_thr_list_); + !biter.done (); + biter.advance ()) + { + // If threads are created as THR_DETACHED or THR_DAEMON, we + // can't help much. + if (biter.next ()->grp_id_ == grp_id) + { + ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false); + copy_table[copy_count++] = *tdb; + delete tdb; + } + } +#endif /* !ACE_HAS_VXTHREADS */ + } + + // Now actually join() with all the threads in this group. + int result = 0; + + for (int i = 0; + i < copy_count && result != -1; + i++) + { + if (ACE_Thread::join (copy_table[i].thr_handle_) == -1) + result = -1; + } + + delete [] copy_table; + + return result; +} + +// Must be called when thread goes out of scope to clean up its table +// slot. + +ACE_THR_FUNC_RETURN +ACE_Thread_Manager::exit (ACE_THR_FUNC_RETURN status, bool do_thread_exit) +{ + ACE_TRACE ("ACE_Thread_Manager::exit"); +#if defined (ACE_WIN32) + // Remove detached thread handle. + + if (do_thread_exit) + { +#if 0 + // @@ This callback is now taken care of by TSS_Cleanup. Do we + // need it anymore? + + // On Win32, if we really wants to exit from a thread, we must + // first clean up the thread specific storage. By doing so, + // ACE_Thread_Manager::exit will be called again with + // do_thr_exit = 0 and cleaning up the ACE_Cleanup_Info (but not + // exiting the thread.) After the following call returns, we + // are safe to exit this thread. + delete ACE_Thread_Exit::instance (); +#endif /* 0 */ + ACE_Thread::exit (status); + } +#endif /* ACE_WIN32 */ + + // Just hold onto the guard while finding this thread's id and + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + // Find the thread id, but don't use the cache. It might have been + // deleted already. + ACE_thread_t const id = ACE_OS::thr_self (); + ACE_Thread_Descriptor* td = this->find_thread (id); + if (td != 0) + { + // @@ We call Thread_Descriptor terminate this realize the cleanup + // process itself. + td->terminate(); + } + } + + if (do_thread_exit) + { + ACE_Thread::exit (status); + // On reasonable systems should not return. + // However, due to horrible semantics with Win32 thread-specific + // storage this call can return (don't ask...). + } + + return 0; +} + +// Wait for all the threads to exit. + +int +ACE_Thread_Manager::wait (const ACE_Time_Value *timeout, + bool abandon_detached_threads, + bool use_absolute_time) +{ + ACE_TRACE ("ACE_Thread_Manager::wait"); + + ACE_Time_Value local_timeout; + // Check to see if we're using absolute time or not. + if (use_absolute_time == false && timeout != 0) + { + local_timeout = *timeout; + local_timeout += ACE_OS::gettimeofday (); + timeout = &local_timeout; + } + +#if !defined (ACE_HAS_VXTHREADS) + ACE_Double_Linked_List term_thr_list_copy; +#endif /* ACE_HAS_VXTHREADS */ + +#if defined (ACE_HAS_THREADS) + { + // Just hold onto the guard while waiting. + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (ACE_Object_Manager::shutting_down () != 1) + { + // Program is not shutting down. Perform a normal wait on threads. + if (abandon_detached_threads != 0) + { + ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); + for (ACE_Double_Linked_List_Iterator + iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (ACE_BIT_ENABLED (iter.next ()->flags_, + THR_DETACHED | THR_DAEMON) + && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE)) + { + this->thr_to_be_removed_.enqueue_tail (iter.next ()); + ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); + } + } + + if (! this->thr_to_be_removed_.is_empty ()) + { + ACE_Thread_Descriptor *td = 0; + while (this->thr_to_be_removed_.dequeue_head (td) != -1) + this->remove_thr (td, 1); + } + } + + while (this->thr_list_.size () > 0) + if (this->zero_cond_.wait (timeout) == -1) + return -1; + } + else + // Program is shutting down, no chance to wait on threads. + // Therefore, we'll just remove threads from the list. + this->remove_thr_all (); + +#if !defined (ACE_HAS_VXTHREADS) + ACE_Thread_Descriptor_Base* item = 0; + while ((item = this->terminated_thr_list_.delete_head ()) != 0) + { + term_thr_list_copy.insert_tail (item); + } +#endif /* ACE_HAS_VXTHREADS */ + // Release the guard, giving other threads a chance to run. + } + +#if !defined (ACE_HAS_VXTHREADS) + // @@ VxWorks doesn't support thr_join (yet.) We are working + // on our implementation. Chorus'es thr_join seems broken. + ACE_Thread_Descriptor_Base *item = 0; + + while ((item = term_thr_list_copy.delete_head ()) != 0) + { + if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE)) + // Detached handles shouldn't reached here. + (void) ACE_Thread::join (item->thr_handle_); + + delete item; + } + +#endif /* !ACE_HAS_VXTHREADS */ +#else + ACE_UNUSED_ARG (timeout); + ACE_UNUSED_ARG (abandon_detached_threads); +#endif /* ACE_HAS_THREADS */ + + return 0; +} + +int +ACE_Thread_Manager::apply_task (ACE_Task_Base *task, + ACE_THR_MEMBER_FUNC func, + int arg) +{ + ACE_TRACE ("ACE_Thread_Manager::apply_task"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); + + int result = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + if (iter.next ()->task_ == task + && (this->*func) (iter.next (), arg) == -1) + result = -1; + + // Must remove threads after we have traversed the thr_list_ to + // prevent clobber thr_list_'s integrity. + + if (! this->thr_to_be_removed_.is_empty ()) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + + for (ACE_Thread_Descriptor *td; + this->thr_to_be_removed_.dequeue_head (td) != -1; + ) + this->remove_thr (td, 1); + } + + return result; +} + +// Wait for all threads to exit a task. + +int +ACE_Thread_Manager::wait_task (ACE_Task_Base *task) +{ + int copy_count = 0; + ACE_Thread_Descriptor_Base *copy_table = 0; + + // We have to make sure that while we wait for these threads to + // exit, we do not have the lock. Therefore we make a copy of all + // interesting entries and let go of the lock. + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + +#if !defined (ACE_HAS_VXTHREADS) + ACE_NEW_RETURN (copy_table, + ACE_Thread_Descriptor_Base [this->thr_list_.size () + + this->terminated_thr_list_.size ()], + -1); +#else + ACE_NEW_RETURN (copy_table, + ACE_Thread_Descriptor_Base [this->thr_list_.size ()], + -1); +#endif /* !ACE_HAS_VXTHREADS */ + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + // If threads are created as THR_DETACHED or THR_DAEMON, we + // can't wait on them here. + if (iter.next ()->task_ == task && + (ACE_BIT_DISABLED (iter.next ()->flags_, + THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (iter.next ()->flags_, + THR_JOINABLE))) + { + ACE_SET_BITS (iter.next ()->thr_state_, + ACE_THR_JOINING); + copy_table[copy_count++] = *iter.next (); + } + } + +#if !defined (ACE_HAS_VXTHREADS) + for (ACE_Double_Linked_List_Iterator titer (this->terminated_thr_list_); + !titer.done (); + titer.advance ()) + { + // If threads are created as THR_DETACHED or THR_DAEMON, we can't help much here. + if (titer.next ()->task_ == task) + { + ACE_Thread_Descriptor_Base *tdb = titer.advance_and_remove (false); + copy_table[copy_count++] = *tdb; + delete tdb; + } + } +#endif /* !ACE_HAS_VXTHREADS */ + } + + // Now to do the actual work + int result = 0; + + for (int i = 0; + i < copy_count && result != -1; + i++) + { + if (ACE_Thread::join (copy_table[i].thr_handle_) == -1) + result = -1; + } + + delete [] copy_table; + + return result; +} + +// Suspend a task + +int +ACE_Thread_Manager::suspend_task (ACE_Task_Base *task) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_task"); + return this->apply_task (task, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); +} + +// Resume a task. +int +ACE_Thread_Manager::resume_task (ACE_Task_Base *task) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_task"); + return this->apply_task (task, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); +} + +// Kill a task. + +int +ACE_Thread_Manager::kill_task (ACE_Task_Base *task, int /* signum */) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_task"); + return this->apply_task (task, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr)); +} + +// Cancel a task. +int +ACE_Thread_Manager::cancel_task (ACE_Task_Base *task, + int async_cancel) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel_task"); + return this->apply_task (task, + ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr), + async_cancel); +} + +// Locate the index in the table associated with from the +// beginning of the table up to an index. Must be called with the +// lock held. + +ACE_Thread_Descriptor * +ACE_Thread_Manager::find_task (ACE_Task_Base *task, size_t slot) +{ + ACE_TRACE ("ACE_Thread_Manager::find_task"); + + size_t i = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (i >= slot) + break; + + if (task == iter.next ()->task_) + return iter.next (); + + ++i; + } + + return 0; +} + +// Returns the number of ACE_Task in a group. + +int +ACE_Thread_Manager::num_tasks_in_group (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + int tasks_count = 0; + size_t i = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (iter.next ()->grp_id_ == grp_id + && this->find_task (iter.next ()->task_, i) == 0 + && iter.next ()->task_ != 0) + { + ++tasks_count; + } + + ++i; + } + return tasks_count; +} + +// Returns the number of threads in an ACE_Task. + +int +ACE_Thread_Manager::num_threads_in_task (ACE_Task_Base *task) +{ + ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + int threads_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (iter.next ()->task_ == task) + { + ++threads_count; + } + } + + return threads_count; +} + +// Returns in task_list a list of ACE_Tasks registered with ACE_Thread_Manager. + +ssize_t +ACE_Thread_Manager::task_all_list (ACE_Task_Base *task_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::task_all_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t task_list_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (task_list_count >= n) + { + break; + } + + ACE_Task_Base *task_p = iter.next ()->task_; + + if (0 != task_p) + { + // This thread has a task pointer; see if it's already in the + // list. Don't add duplicates. + size_t i = 0; + + for (; i < task_list_count; ++i) + { + if (task_list[i] == task_p) + { + break; + } + } + + if (i == task_list_count) // No match - add this one + { + task_list[task_list_count++] = task_p; + } + } + } + + return ACE_Utils::truncate_cast (task_list_count); +} + +// Returns in thread_list a list of all thread ids + +ssize_t +ACE_Thread_Manager::thread_all_list (ACE_thread_t thread_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::thread_all_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t thread_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (thread_count >= n) + { + break; + } + + thread_list[thread_count] = iter.next ()->thr_id_; + ++thread_count; + } + + return ACE_Utils::truncate_cast (thread_count); +} + + +int +ACE_Thread_Manager::thr_state (ACE_thread_t id, + ACE_UINT32& state) +{ + ACE_TRACE ("ACE_Thread_Manager::thr_state"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + int const self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ()); + + // If we're checking the state of our thread, try to get the cached + // value out of TSS to avoid lookup. + if (self_check) + { + ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); + + if (desc == 0) + { + return 0; // Always return false. + } + + state = desc->thr_state_; + } + else + { + // Not calling from self, have to look it up from the list. + ACE_FIND (this->find_thread (id), ptr); + + if (ptr == 0) + { + return 0; + } + + state = ptr->thr_state_; + } + + return 1; +} + +// Returns in task_list a list of ACE_Tasks in a group. + +ssize_t +ACE_Thread_Manager::task_list (int grp_id, + ACE_Task_Base *task_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::task_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_Task_Base **task_list_iterator = task_list; + size_t task_list_count = 0; + size_t i = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (task_list_count >= n) + { + break; + } + + if (iter.next ()->grp_id_ == grp_id + && this->find_task (iter.next ()->task_, i) == 0) + { + task_list_iterator[task_list_count] = iter.next ()->task_; + ++task_list_count; + } + + ++i; + } + + return ACE_Utils::truncate_cast (task_list_count); +} + +// Returns in thread_list a list of thread ids in an ACE_Task. + +ssize_t +ACE_Thread_Manager::thread_list (ACE_Task_Base *task, + ACE_thread_t thread_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::thread_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t thread_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (thread_count >= n) + { + break; + } + + if (iter.next ()->task_ == task) + { + thread_list[thread_count] = iter.next ()->thr_id_; + ++thread_count; + } + } + + return ACE_Utils::truncate_cast (thread_count); +} + +// Returns in thread_list a list of thread handles in an ACE_Task. + +ssize_t +ACE_Thread_Manager::hthread_list (ACE_Task_Base *task, + ACE_hthread_t hthread_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::hthread_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t hthread_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (hthread_count >= n) + { + break; + } + + if (iter.next ()->task_ == task) + { + hthread_list[hthread_count] = iter.next ()->thr_handle_; + ++hthread_count; + } + } + + return ACE_Utils::truncate_cast (hthread_count); +} + +ssize_t +ACE_Thread_Manager::thread_grp_list (int grp_id, + ACE_thread_t thread_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::thread_grp_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t thread_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (thread_count >= n) + { + break; + } + + if (iter.next ()->grp_id_ == grp_id) + { + thread_list[thread_count] = iter.next ()->thr_id_; + thread_count++; + } + } + + return ACE_Utils::truncate_cast (thread_count); +} + +// Returns in thread_list a list of thread handles in an ACE_Task. + +ssize_t +ACE_Thread_Manager::hthread_grp_list (int grp_id, + ACE_hthread_t hthread_list[], + size_t n) +{ + ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + size_t hthread_count = 0; + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (hthread_count >= n) + { + break; + } + + if (iter.next ()->grp_id_ == grp_id) + { + hthread_list[hthread_count] = iter.next ()->thr_handle_; + hthread_count++; + } + } + + return ACE_Utils::truncate_cast (hthread_count); +} + +int +ACE_Thread_Manager::set_grp (ACE_Task_Base *task, int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::set_grp"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + for (ACE_Double_Linked_List_Iterator iter (this->thr_list_); + !iter.done (); + iter.advance ()) + { + if (iter.next ()->task_ == task) + { + iter.next ()->grp_id_ = grp_id; + } + } + + return 0; +} + +int +ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::get_grp"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_FIND (this->find_task (task), ptr); + grp_id = ptr->grp_id_; + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Manager.h b/dep/ACE_wrappers/ace/Thread_Manager.h new file mode 100644 index 000000000..2703aae40 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Manager.h @@ -0,0 +1,1264 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Thread_Manager.h + * + * $Id: Thread_Manager.h 82588 2008-08-11 13:37:41Z johnnyw $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_THREAD_MANAGER_H +#define ACE_THREAD_MANAGER_H +#include /**/ "ace/pre.h" + +#include "ace/Thread.h" +#include "ace/Thread_Adapter.h" +#include "ace/Thread_Exit.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Condition_Thread_Mutex.h" +#include "ace/Unbounded_Queue.h" +#include "ace/Containers.h" +#include "ace/Free_List.h" +#include "ace/Singleton.h" +#include "ace/Log_Msg.h" +#include "ace/Synch_Traits.h" +#include "ace/Basic_Types.h" + +// The following macros control how a Thread Manager manages a pool of +// Thread_Descriptor. Currently, the default behavior is not to +// preallocate any thread descriptor and never (well, almost never) +// free up any thread descriptor until the Thread Manager gets +// destructed. Which means, once your system is stable, you rarely +// need to pay the price of memory allocation. On a deterministic +// system, which means, the number of threads spawned can be +// determined before hand, you can either redefine the memory pool +// size macros to suit your need or constructed the Thread_Manager +// accordingly. That way, you don't pay the price of memory +// allocation when the system is really doing its job. OTOH, on +// system with resources constraint, you may want to lower the size of +// ACE_DEFAULT_THREAD_MANAGER_HWM to avoid unused memory hanging +// around. + +#if !defined (ACE_DEFAULT_THREAD_MANAGER_PREALLOC) +# define ACE_DEFAULT_THREAD_MANAGER_PREALLOC 0 +#endif /* ACE_DEFAULT_THREAD_MANAGER_PREALLOC */ + +#if !defined (ACE_DEFAULT_THREAD_MANAGER_LWM) +# define ACE_DEFAULT_THREAD_MANAGER_LWM 1 +#endif /* ACE_DEFAULT_THREAD_MANAGER_LWM */ + +#if !defined (ACE_DEFAULT_THREAD_MANAGER_INC) +# define ACE_DEFAULT_THREAD_MANAGER_INC 1 +#endif /* ACE_DEFAULT_THREAD_MANAGER_INC */ + +#if !defined (ACE_DEFAULT_THREAD_MANAGER_HWM) +# define ACE_DEFAULT_THREAD_MANAGER_HWM ACE_DEFAULT_FREE_LIST_HWM +// this is a big number +#endif /* ACE_DEFAULT_THREAD_MANAGER_HWM */ + +// This is the synchronization mechanism used to prevent a thread +// descriptor gets removed from the Thread_Manager before it gets +// stash into it. If you want to disable this feature (and risk of +// corrupting the freelist,) you define the lock as ACE_Null_Mutex. +// Usually, if you can be sure that your threads will run for an +// extended period of time, you can safely disable the lock. + +#if !defined (ACE_DEFAULT_THREAD_MANAGER_LOCK) +# define ACE_DEFAULT_THREAD_MANAGER_LOCK ACE_SYNCH_MUTEX +#endif /* ACE_DEFAULT_THREAD_MANAGER_LOCK */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations. +class ACE_Task_Base; +class ACE_Thread_Manager; +class ACE_Thread_Descriptor; + +/** + * @class ACE_At_Thread_Exit + * + * @brief Contains a method to be applied when a thread is terminated. + */ +class ACE_Export ACE_At_Thread_Exit +{ + friend class ACE_Thread_Descriptor; + friend class ACE_Thread_Manager; +public: + /// Default constructor + ACE_At_Thread_Exit (void); + + /// The destructor + virtual ~ACE_At_Thread_Exit (void); + + /// At_Thread_Exit has the ownership? + bool is_owner (void) const; + + /// Set the ownership of the At_Thread_Exit. + bool is_owner (bool owner); + + /// This At_Thread_Exit was applied? + bool was_applied (void) const; + + /// Set applied state of At_Thread_Exit. + bool was_applied (bool applied); + +protected: + /// The next At_Thread_Exit hook in the list. + ACE_At_Thread_Exit *next_; + + /// Do the apply if necessary + void do_apply (void); + + /// The apply method. + virtual void apply (void) = 0; + + /// The Thread_Descriptor where this at is registered. + ACE_Thread_Descriptor* td_; + + /// The at was applied? + bool was_applied_; + + /// The at has the ownership of this? + bool is_owner_; +}; + +class ACE_Export ACE_At_Thread_Exit_Func : public ACE_At_Thread_Exit +{ +public: + /// Constructor + ACE_At_Thread_Exit_Func (void *object, + ACE_CLEANUP_FUNC func, + void *param = 0); + + virtual ~ACE_At_Thread_Exit_Func (void); + +protected: + /// The object to be cleanup + void *object_; + + /// The cleanup func + ACE_CLEANUP_FUNC func_; + + /// A param if required + void *param_; + + /// The apply method + void apply (void); +}; + +/** + * @class ACE_Thread_Descriptor_Base + * + * @brief Basic information for thread descriptors. These information + * gets extracted out because we need it after a thread is + * terminated. + * + * @internal + */ +class ACE_Export ACE_Thread_Descriptor_Base : public ACE_OS_Thread_Descriptor +{ + + friend class ACE_Thread_Manager; + friend class ACE_Double_Linked_List; + friend class ACE_Double_Linked_List_Iterator_Base; + friend class ACE_Double_Linked_List_Iterator; + friend class ACE_Double_Linked_List; + friend class ACE_Double_Linked_List_Iterator_Base; + friend class ACE_Double_Linked_List_Iterator; +public: + ACE_Thread_Descriptor_Base (void); + ~ACE_Thread_Descriptor_Base (void); + + // = We need the following operators to make Borland happy. + + /// Equality operator. + bool operator== (const ACE_Thread_Descriptor_Base &rhs) const; + + /// Inequality operator. + bool operator!= (const ACE_Thread_Descriptor_Base &rhs) const; + + /// Group ID. + int grp_id (void) const; + + /// Current state of the thread. + ACE_UINT32 state (void) const; + + /// Return the pointer to an ACE_Task_Base or NULL if there's no + /// ACE_Task_Base associated with this thread.; + ACE_Task_Base *task (void) const; + +protected: + /// Reset this base thread descriptor. + void reset (void); + + /// Unique thread ID. + ACE_thread_t thr_id_; + + /// Unique handle to thread (used by Win32 and AIX). + ACE_hthread_t thr_handle_; + + /// Group ID. + int grp_id_; + + /// Current state of the thread. + ACE_UINT32 thr_state_; + + /// Pointer to an ACE_Task_Base or NULL if there's no + /// ACE_Task_Base. + ACE_Task_Base *task_; + + /// We need these pointers to maintain the double-linked list in a + /// thread managers. + ACE_Thread_Descriptor_Base *next_; + ACE_Thread_Descriptor_Base *prev_; +}; + +/** + * @class ACE_Thread_Descriptor + * + * @brief Information for controlling threads that run under the control + * of the . + */ +class ACE_Export ACE_Thread_Descriptor : public ACE_Thread_Descriptor_Base +{ + friend class ACE_At_Thread_Exit; + friend class ACE_Thread_Manager; + friend class ACE_Double_Linked_List; + friend class ACE_Double_Linked_List_Iterator; +public: + // = Initialization method. + ACE_Thread_Descriptor (void); + + // = Accessor methods. + /// Unique thread id. + ACE_thread_t self (void) const; + + /// Unique handle to thread (used by Win32 and AIX). + void self (ACE_hthread_t &); + + /// Dump the state of an object. + void dump (void) const; + + /** + * This cleanup function must be called only for ACE_TSS_cleanup. + * The ACE_TSS_cleanup delegate Log_Msg instance destruction when + * Log_Msg cleanup is called before terminate. + */ + void log_msg_cleanup(ACE_Log_Msg* log_msg); + + /** + * Register an At_Thread_Exit hook and the ownership is acquire by + * Thread_Descriptor, this is the usual case when the AT is dynamically + * allocated. + */ + int at_exit (ACE_At_Thread_Exit* cleanup); + + /// Register an At_Thread_Exit hook and the ownership is retained for the + /// caller. Normally used when the at_exit hook is created in stack. + int at_exit (ACE_At_Thread_Exit& cleanup); + + /** + * Register an object (or array) for cleanup at thread termination. + * "cleanup_hook" points to a (global, or static member) function + * that is called for the object or array when it to be destroyed. + * It may perform any necessary cleanup specific for that object or + * its class. "param" is passed as the second parameter to the + * "cleanup_hook" function; the first parameter is the object (or + * array) to be destroyed. Returns 0 on success, non-zero on + * failure: -1 if virtual memory is exhausted or 1 if the object (or + * arrayt) had already been registered. + */ + int at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param); + + /// Do nothing destructor to keep some compilers happy + ~ACE_Thread_Descriptor (void); + + /** + * Do nothing but to acquire the thread descriptor's lock and + * release. This will first check if the thread is registered or + * not. If it is already registered, there's no need to reacquire + * the lock again. This is used mainly to get newly spawned thread + * in synch with thread manager and prevent it from accessing its + * thread descriptor before it gets fully built. This function is + * only called from ACE_Log_Msg::thr_desc. + */ + void acquire_release (void); + void acquire (void); + void release (void); + + /** + * Set/get the @c next_ pointer. These are required by the + * ACE_Free_List. + */ + void set_next (ACE_Thread_Descriptor *td); + ACE_Thread_Descriptor *get_next (void) const; + +private: + /// Reset this thread descriptor. + void reset (ACE_Thread_Manager *tm); + + /// Pop an At_Thread_Exit from at thread termination list, apply the at + /// if apply is true. + void at_pop (int apply = 1); + + /// Push an At_Thread_Exit to at thread termination list and set the + /// ownership of at. + void at_push (ACE_At_Thread_Exit* cleanup, + bool is_owner = false); + + /// Run the AT_Thread_Exit hooks. + void do_at_exit (void); + + /// Terminate realize the cleanup process to thread termination + void terminate (void); + + /// Thread_Descriptor is the ownership of ACE_Log_Msg if log_msg_!=0 + /// This can occur because ACE_TSS_cleanup was executed before terminate. + ACE_Log_Msg *log_msg_; + + /// The AT_Thread_Exit list + ACE_At_Thread_Exit *at_exit_list_; + + /** + * Stores the cleanup info for a thread. + * @note This should be generalized to be a stack of ACE_Cleanup_Info's. + */ + ACE_Cleanup_Info cleanup_info_; + + /// Pointer to an ACE_Thread_Manager or NULL if there's no + /// ACE_Thread_Manager> + ACE_Thread_Manager* tm_; + + /// Registration lock to prevent premature removal of thread descriptor. + ACE_DEFAULT_THREAD_MANAGER_LOCK *sync_; + + /// Keep track of termination status. + bool terminated_; +}; + +// Forward declaration. +class ACE_Thread_Control; + +// This typedef should be (and used to be) inside the +// ACE_Thread_Manager declaration. But, it caused compilation +// problems on g++/VxWorks/i960 with -g. Note that +// ACE_Thread_Manager::THR_FUNC is only used internally in +// ACE_Thread_Manager, so it's not useful for anyone else. +// It also caused problems on IRIX5 with g++. +#if defined (__GNUG__) +typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC)(ACE_Thread_Descriptor *, int); +#endif /* __GNUG__ */ + +/** + * @class ACE_Thread_Manager + * + * @brief Manages a pool of threads. + * + * This class allows operations on groups of threads atomically. + * The default behavior of thread manager is to wait on + * all threads under it's management when it gets destructed. + * Therefore, remember to remove a thread from thread manager if + * you don't want it to wait for the thread. There are also + * functions to disable this default wait-on-exit behavior. + * However, if your program depends on turning this off to run + * correctly, you are probably doing something wrong. Rule of + * thumb, use ACE_Thread to manage your daemon threads. + * Notice that if there're threads which live beyond the scope of + * main(), you are sure to have resource leaks in your program. + * Remember to wait on threads before exiting your main program if that + * could happen in your programs. + */ +class ACE_Export ACE_Thread_Manager +{ +public: + friend class ACE_Thread_Control; + + // Allow ACE_THread_Exit to register the global TSS instance object. + friend class ACE_Thread_Exit; + friend class ACE_Thread_Descriptor; + +#if !defined (__GNUG__) + typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC)(ACE_Thread_Descriptor *, int); +#endif /* !__GNUG__ */ + + /// These are the various states a thread managed by the + /// ACE_Thread_Manager can be in. + enum + { + /// Uninitialized. + ACE_THR_IDLE = 0x00000000, + + /// Created but not yet running. + ACE_THR_SPAWNED = 0x00000001, + + /// Thread is active (naturally, we don't know if it's actually + /// *running* because we aren't the scheduler...). + ACE_THR_RUNNING = 0x00000002, + + /// Thread is suspended. + ACE_THR_SUSPENDED = 0x00000004, + + /// Thread has been cancelled (which is an indiction that it needs to + /// terminate...). + ACE_THR_CANCELLED = 0x00000008, + + /// Thread has shutdown, but the slot in the thread manager hasn't + /// been reclaimed yet. + ACE_THR_TERMINATED = 0x00000010, + + /// Join operation has been invoked on the thread by thread manager. + ACE_THR_JOINING = 0x10000000 + }; + + /** + * @brief Initialization and termination methods. + * + * Internally, ACE_Thread_Manager keeps a freelist for caching + * resources it uses to keep track of managed threads (not the + * threads themselves.) @a prealloc, @a lwm, @a inc, @hwm + * determine the initial size, the low water mark, increment step, + * and high water mark of the freelist. + * + * @sa ACE_Free_List + */ + ACE_Thread_Manager (size_t preaolloc = ACE_DEFAULT_THREAD_MANAGER_PREALLOC, + size_t lwm = ACE_DEFAULT_THREAD_MANAGER_LWM, + size_t inc = ACE_DEFAULT_THREAD_MANAGER_INC, + size_t hwm = ACE_DEFAULT_THREAD_MANAGER_HWM); + ~ACE_Thread_Manager (void); + +#if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) + /// Get pointer to a process-wide ACE_Thread_Manager. + static ACE_Thread_Manager *instance (void); + + /// Set pointer to a process-wide ACE_Thread_Manager and return + /// existing pointer. + static ACE_Thread_Manager *instance (ACE_Thread_Manager *); + + /// Delete the dynamically allocated Singleton + static void close_singleton (void); +#endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */ + + /// No-op. Currently unused. + int open (size_t size = 0); + + /** + * Release all resources. + * By default, this method will wait until all threads exit. + * However, when called from close_singleton(), most global resources + * are destroyed and thus, close() does not try to wait; it simply cleans + * up internal thread records (the thread descriptor list). + */ + int close (void); + + /** + * Create a new thread, which executes @a func with argument @a arg. + * + * @param func The function that is called in the spawned thread. + * + * @param arg The value passed to each spawned thread's @a func. + * + * @param flags Flags to control attributes of the spawned threads. + * @sa ACE_OS::thr_create() for descriptions of the + * possible flags values and their interactions. + * + * @param t_id Pointer to a location to receive the spawned thread's + * ID. If 0, the ID is not returned. + * + * @param t_handle Pointer to a location to receive the spawned thread's + * thread handle. If 0, the handle is not returned. + * + * @param priority The priority at which the thread is spawned. + * + * @param grp_id The thread group that the spawned thread is + * added to. If -1 is specified, a new thread group is + * created for the spawned thread. + * + * @param stack Pointers to the base of a pre-allocated stack space + * for the thread's stack. If 0, the platform allocates + * stack space for the thread. If a stack is specified, + * it is recommended that @a stack_size also be supplied + * to specify the size of the stack. + * Not all platforms support pre-allocated stacks. If + * @a stack is specified for a platform which does not + * allow pre-allocated stack space this parameter is + * ignored. + * + * @param stack_size Indicate how large the thread's stack should be, in + * bytes. If a pre-allocated stack pointer is passed in + * @a stack, @a stack_size indicates the size of that + * stack area. If no pre-allocated stack is passed, + * the stack size specified is passed to the + * operating system to request that it allocate a stack + * of the specified size. + * + * @param thr_name Pointer to a name to assign to the spawned thread. + * This is only meaningful for platforms that have a + * capacity to name threads (e.g., VxWorks and some + * varieties of Pthreads). This argument is ignored if + * specified as 0 and on platforms that do not have the + * capability to name threads. + * + * @retval -1 on failure; @c errno contains an error value. + * @retval The group id of the spawned thread. + */ + int spawn (ACE_THR_FUNC func, + void *arg = 0, + long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, + ACE_thread_t *t_id = 0, + ACE_hthread_t *t_handle = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + void *stack = 0, + size_t stack_size = ACE_DEFAULT_THREAD_STACKSIZE, + const char** thr_name = 0); + + /** + * Spawn a specified number of threads, all of which execute @a func + * with argument @a arg. + * + * @param n The number of threads to spawn. + * + * @param func The function that is called in the spawned thread. + * + * @param arg The value passed to each spawned thread's @a func. + * + * @param flags Flags to control attributes of the spawned threads. + * @sa ACE_OS::thr_create() for descriptions of the + * possible flags values and their interactions. + * + * @param priority The priority at which the threads are spawned. + * + * @param grp_id The thread group that the spawned threads are + * added to. If -1 is specified, a new thread group is + * created for the spawned threads. + * + * @param task The ACE_Task that the spawned threads are associated + * with. If 0, the threads are not associated with an + * ACE_Task. This argument is usually assigned by the + * ACE_Task_Base::activate() method to associate the + * spawned threads with the spawning ACE_Task object. + * + * @param thread_handles An array of @a n entries which will receive + * the thread handles of the spawned threads. + * + * @param stack An array of @a n pointers to pre-allocated stack space + * for each thread's stack. If specified as 0, the + * platform allocates stack space for each thread. If + * a stack is specified, it is recommended that a + * @a stack_size element also be supplied that specifies + * the size of the stack. + * Not all platforms support pre-allocated stacks. If + * @a stack is specified for a platform which does not + * allow pre-allocated stack space this parameter is + * ignored. + * + * @param stack_size An array of @a n values which indicate how large + * each thread's stack should be, in bytes. + * If pre-allocated stacks are passed in @a stacks, these + * sizes are for those stacks. If no pre-allocated stacks + * are passed, the stack sizes are specified to the + * operating system to request that it allocate stacks + * of the specified sizes. If an array entry is 0, the + * platform defaults are used for the corresponding thread. + * If a 0 array pointer is specified, platform defaults + * are used for all thread stack sizes. + * + * @param thr_name An array of names to assign to the spawned threads. + * This is only meaningful for platforms that have a + * capacity to name threads (e.g., VxWorks and some + * varieties of Pthreads). This argument is ignored if + * specified as 0 and on platforms that do not have the + * capability to name threads. + * + * ACE_Thread_Manager can manipulate threads in groups based on + * @a grp_id or @a task using functions such as kill_grp() or + * cancel_task(). + * + * @retval -1 on failure; @c errno contains an error value. + * @retval The group id of the threads. + */ + int spawn_n (size_t n, + ACE_THR_FUNC func, + void *arg = 0, + long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0, + void *stack[] = 0, + size_t stack_size[] = 0, + const char* thr_name[] = 0); + + /** + * Spawn a specified number of threads, all of which execute @a func + * with argument @a arg. + * + * @param thread_ids An array to receive the thread IDs of successfully + * spawned buffer. If 0, the thread IDs are not returned. + * If specified, the array must be at least @a n entries. + * + * @param n The number of threads to spawn. + * + * @param func The function that is called in the spawned thread. + * + * @param arg The value passed to each spawned thread's @a func. + * + * @param flags Flags to control attributes of the spawned threads. + * @sa ACE_OS::thr_create() for descriptions of the + * possible flags values and their interactions. + * + * @param priority The priority at which the threads are spawned. + * + * @param grp_id The thread group that the spawned threads are + * added to. If -1 is specified, a new thread group is + * created for the spawned threads. + * + * @param stack An array of @a n pointers to pre-allocated stack space + * for each thread's stack. If specified as 0, the + * platform allocates stack space for each thread. If + * a stack is specified, it is recommended that a + * @a stack_size element also be supplied that specifies + * the size of the stack. + * Not all platforms support pre-allocated stacks. If + * @a stack is specified for a platform which does not + * allow pre-allocated stack space this parameter is + * ignored. + * + * @param stack_size An array of @a n values which indicate how large + * each thread's stack should be, in bytes. + * If pre-allocated stacks are passed in @a stacks, these + * sizes are for those stacks. If no pre-allocated stacks + * are passed, the stack sizes are specified to the + * operating system to request that it allocate stacks + * of the specified sizes. If an array entry is 0, the + * platform defaults are used for the corresponding thread. + * If a 0 array pointer is specified, platform defaults + * are used for all thread stack sizes. + * + * @param thread_handles An array of @a n entries which will receive + * the thread handles of the spawned threads. + * + * @param task The ACE_Task that the spawned threads are associated + * with. If 0, the threads are not associated with an + * ACE_Task. This argument is usually assigned by the + * ACE_Task_Base::activate() method to associate the + * spawned threads with the spawning ACE_Task object. + * + * @param thr_name An array of names to assign to the spawned threads. + * This is only meaningful for platforms that have a + * capacity to name threads (e.g., VxWorks and some + * varieties of Pthreads). This argument is ignored if + * specified as 0 and on platforms that do not have the + * capability to name threads. + * + * ACE_Thread_Manager can manipulate threads in groups based on + * @a grp_id or @a task using functions such as kill_grp() or + * cancel_task(). + * + * @retval -1 on failure; @c errno contains an error value. + * @retval The group id of the threads. + + */ + int spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_hthread_t thread_handles[] = 0, + ACE_Task_Base *task = 0, + const char* thr_name[] = 0); + + /** + * Called to clean up when a thread exits. + * + * @param do_thread_exit If non-0 then ACE_Thread::exit is called to + * exit the thread + * @param status If ACE_Thread_Exit is called, this is passed as + * the exit value of the thread. + * Should _not_ be called by main thread. + */ + ACE_THR_FUNC_RETURN exit (ACE_THR_FUNC_RETURN status = 0, + bool do_thread_exit = true); + + /** + * Block until there are no more threads running in this thread + * manager or @c timeout expires. + * + * @param timeout is treated as "absolute" time by default, but this + * can be changed to "relative" time by setting the @c + * use_absolute_time to false. + * @param abandon_detached_threads If true, @c wait() will first + * check thru its thread list for + * threads with THR_DETACHED or + * THR_DAEMON flags set and remove + * these threads. Notice that + * unlike other @c wait_*() methods, + * by default, @c wait() does wait on + * all thread spawned by this + * thread manager no matter the detached + * flags are set or not unless it is + * called with @c + * abandon_detached_threads flag set. + * @param use_absolute_time If true then treat @c timeout as + * absolute time, else relative time. + * @return 0 on success * and -1 on failure. + * + * @note If this function is called while the @c + * ACE_Object_Manager is shutting down (as a result of program + * rundown via @c ACE::fini()), it will not wait for any threads to + * complete. If you must wait for threads spawned by this thread + * manager to complete and you are in a ACE rundown situation (such + * as your object is being destroyed by the @c ACE_Object_Manager) + * you can use @c wait_grp() instead. + */ + int wait (const ACE_Time_Value *timeout = 0, + bool abandon_detached_threads = false, + bool use_absolute_time = true); + + /// Join a thread specified by @a tid. Do not wait on a detached thread. + int join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status = 0); + + /** + * Block until there are no more threads running in a group. + * Returns 0 on success and -1 on failure. Notice that wait_grp + * will not wait on detached threads. + */ + int wait_grp (int grp_id); + + /** + * Return the "real" handle to the calling thread, caching it if + * necessary in TSS to speed up subsequent lookups. This is + * necessary since on some platforms (e.g., Windows) we can't get this + * handle via direct method calls. Notice that you should *not* + * close the handle passed back from this method. It is used + * internally by Thread Manager. On the other hand, you *have to* + * use this internal thread handle when working on Thread_Manager. + * Return -1 if fail. + */ + int thr_self (ACE_hthread_t &); + + /** + * Return the unique ID of the calling thread. + * Same as calling ACE_Thread::self(). + */ + ACE_thread_t thr_self (void); + + /** + * Returns a pointer to the current ACE_Task_Base we're executing + * in if this thread is indeed running in an ACE_Task_Base, else + * return 0. + */ + ACE_Task_Base *task (void); + + /** + * @name Suspend and resume methods + * + * Suspend/resume is not supported on all platforms. For example, Pthreads + * does not support these functions. + */ + //@{ + + /// Suspend all threads + int suspend_all (void); + + /// Suspend a single thread. + int suspend (ACE_thread_t); + + /// Suspend a group of threads. + int suspend_grp (int grp_id); + + /** + * True if @a t_id is inactive (i.e., suspended), else false. Always + * return false if @a t_id is not managed by the Thread_Manager. + */ + int testsuspend (ACE_thread_t t_id); + + /// Resume all stopped threads + int resume_all (void); + + /// Resume a single thread. + int resume (ACE_thread_t); + + /// Resume a group of threads. + int resume_grp (int grp_id); + + /** + * True if @a t_id is active (i.e., resumed), else false. Always + * return false if @a t_id is not managed by the Thread_Manager. + */ + int testresume (ACE_thread_t t_id); + + //@} + + // = Send signals to one or more threads without blocking. + /** + * Send @a signum to all stopped threads. Not supported on platforms + * that do not have advanced signal support, such as Win32. + */ + int kill_all (int signum); + /** + * Send the @a signum to a single thread. Not supported on platforms + * that do not have advanced signal support, such as Win32. + */ + int kill (ACE_thread_t, int signum); + /** + * Send @a signum to a group of threads, not supported on platforms + * that do not have advanced signal support, such as Win32. + */ + int kill_grp (int grp_id, int signum); + + // = Cancel methods, which provides a cooperative thread-termination mechanism (will not block). + /** + * Cancel's all the threads. + */ + int cancel_all (int async_cancel = 0); + + /** + * Cancel a single thread. + */ + int cancel (ACE_thread_t, int async_cancel = 0); + + /** + * Cancel a group of threads. + */ + int cancel_grp (int grp_id, int async_cancel = 0); + + /** + * True if @a t_id is cancelled, else false. Always return false if + * @a t_id is not managed by the Thread_Manager. + */ + int testcancel (ACE_thread_t t_id); + + /** + * True if @a t_id has terminated (i.e., is no longer running), + * but the slot in the thread manager hasn't been reclaimed yet, + * else false. Always return false if @a t_id is not managed by the + * Thread_Manager. + */ + int testterminate (ACE_thread_t t_id); + + /// Set group ids for a particular thread id. + int set_grp (ACE_thread_t, + int grp_id); + + /// Get group ids for a particular thread id. + int get_grp (ACE_thread_t, + int &grp_id); + + /** + * @name Task-related operations + */ + //@{ + /** + * Block until there are no more threads running in a specified task. + * This method will not wait for either detached or daemon threads; + * the threads must have been spawned with the @c THR_JOINABLE flag. + * Upon successful completion, the threads have been joined, so further + * attempts to join with any of the waited-for threads will fail. + * + * @param task The ACE_Task_Base object whose threads are to waited for. + * + * @retval 0 Success. + * @retval -1 Failure (consult errno for further information). + */ + int wait_task (ACE_Task_Base *task); + + /** + * Suspend all threads in an ACE_Task. + */ + int suspend_task (ACE_Task_Base *task); + + /** + * Resume all threads in an ACE_Task. + */ + int resume_task (ACE_Task_Base *task); + + /** + * Send a signal @a signum to all threads in an ACE_Task. + */ + int kill_task (ACE_Task_Base *task, int signum); + + /** + * Cancel all threads in an ACE_Task. If is non-0, + * then asynchronously cancel these threads if the OS platform + * supports cancellation. Otherwise, perform a "cooperative" + * cancellation. + */ + int cancel_task (ACE_Task_Base *task, int async_cancel = 0); + + //@} + + // = Collect thread handles in the thread manager. Notice that + // the collected information is just a snapshot. + /// Check if the thread is managed by the thread manager. Return true if + /// the thread is found, false otherwise. + int hthread_within (ACE_hthread_t handle); + int thread_within (ACE_thread_t tid); + + /// Returns the number of ACE_Task_Base in a group. + int num_tasks_in_group (int grp_id); + + /// Returns the number of threads in an ACE_Task_Base. + int num_threads_in_task (ACE_Task_Base *task); + + /** + * Returns a list of ACE_Task_Base pointers corresponding to the tasks + * that have active threads in a specified thread group. + * + * @param grp_id The thread group ID to obtain task pointers for. + * + * @param task_list is a pointer to an array to receive the list of pointers. + * The caller is responsible for supplying an array with at + * least @arg n entries. + * + * @param n The maximum number of ACE_Task_Base pointers to write + * in @arg task_list. + * + * @retval If successful, the number of pointers returned, which will be + * no greater than @arg n. Returns -1 on error. + * + * @note This method has no way to indicate if there are more than + * @arg n ACE_Task_Base pointers available. Therefore, it may be + * wise to guess a larger value of @arg n than one thinks in cases + * where the exact number of tasks is not known. + * + * @sa num_tasks_in_group(), task_all_list() + */ + ssize_t task_list (int grp_id, + ACE_Task_Base *task_list[], + size_t n); + + /** + * Returns in @a thread_list a list of up to @a n thread ids in an + * ACE_Task_Base. The caller must allocate the memory for + * @a thread_list. In case of an error, -1 is returned. If no + * requested values are found, 0 is returned, otherwise correct + * number of retrieved values are returned. + */ + ssize_t thread_list (ACE_Task_Base *task, + ACE_thread_t thread_list[], + size_t n); + + /** + * Returns in @a hthread_list a list of up to @a n thread handles in + * an ACE_Task_Base. The caller must allocate memory for + * @a hthread_list. In case of an error, -1 is returned. If no + * requested values are found, 0 is returned, otherwise correct + * number of retrieved values are returned. + */ + ssize_t hthread_list (ACE_Task_Base *task, + ACE_hthread_t hthread_list[], + size_t n); + + /** + * Returns in @a thread_list a list of up to @a n thread ids in a + * group @a grp_id. The caller must allocate the memory for + * @a thread_list. In case of an error, -1 is returned. If no + * requested values are found, 0 is returned, otherwise correct + * number of retrieved values are returned. + */ + ssize_t thread_grp_list (int grp_id, + ACE_thread_t thread_list[], + size_t n); + + /** + * Returns in @a hthread_list a list of up to @a n thread handles in + * a group @a grp_id. The caller must allocate memory for + * @a hthread_list. + */ + ssize_t hthread_grp_list (int grp_id, + ACE_hthread_t hthread_list[], + size_t n); + + /** + * Returns a list of ACE_Task_Base pointers corresponding to the tasks + * that have active threads managed by this instance. + * + * @param task_list is a pointer to an array to receive the list of pointers. + * The caller is responsible for supplying an array with at + * least @arg n entries. + * + * @param n The maximum number of ACE_Task_Base pointers to write + * in @arg task_list. + * + * @retval If successful, the number of pointers returned, which will be + * no greater than @arg n. Returns -1 on error. + * + * @note This method has no way to indicate if there are more than + * @arg n ACE_Task_Base pointers available. Therefore, it may be + * wise to guess a larger value of @arg n than one thinks in cases + * where the exact number of tasks is not known. + * + * @sa count_threads() + */ + ssize_t task_all_list (ACE_Task_Base *task_list[], + size_t n); + + /** + * Returns in @a thread_list a list of up to @a n thread ids. The + * caller must allocate the memory for @a thread_list. In case of an + * error, -1 is returned. If no requested values are found, 0 is + * returned, otherwise correct number of retrieved values are + * returned. + */ + ssize_t thread_all_list (ACE_thread_t thread_list[], + size_t n); + + /// Set group ids for a particular task. + int set_grp (ACE_Task_Base *task, int grp_id); + + /// Get group ids for a particular task. + int get_grp (ACE_Task_Base *task, int &grp_id); + + /// Return a count of the current number of threads active in the + /// . + size_t count_threads (void) const; + + /// Get the state of the thread. Returns false if the thread is not + /// managed by this thread manager. + int thr_state (ACE_thread_t id, ACE_UINT32& state); + + /** + * Register an At_Thread_Exit hook and the ownership is acquire by + * Thread_Descriptor, this is the usual case when the AT is dynamically + * allocated. + */ + int at_exit (ACE_At_Thread_Exit* cleanup); + + /// Register an At_Thread_Exit hook and the ownership is retained for the + /// caller. Normally used when the at_exit hook is created in stack. + int at_exit (ACE_At_Thread_Exit& cleanup); + + /** + * + ***** + * @deprecated This function is deprecated. Please use the previous two + * at_exit method. Notice that you should avoid mixing this method + * with the previous two at_exit methods. + ***** + * + * Register an object (or array) for cleanup at + * thread termination. "cleanup_hook" points to a (global, or + * static member) function that is called for the object or array + * when it to be destroyed. It may perform any necessary cleanup + * specific for that object or its class. "param" is passed as the + * second parameter to the "cleanup_hook" function; the first + * parameter is the object (or array) to be destroyed. + * "cleanup_hook", for example, may delete the object (or array). + * If == 0, the will _NOT_ get cleanup at + * thread exit. You can use this to cancel the previously added + * at_exit. + */ + int at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param); + + /// Access function to determine whether the Thread_Manager will + /// wait for its thread to exit or not when being closing down. + void wait_on_exit (int dowait); + int wait_on_exit (void); + + /// Dump the state of an object. + void dump (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = Accessors for ACE_Thread_Descriptors. + /** + * Get a pointer to the calling thread's own thread_descriptor. + * This must be called from a spawn thread. This function will + * fetch the info from TSS. + */ + ACE_Thread_Descriptor *thread_desc_self (void); + + /// Return a pointer to the thread's Thread_Descriptor, + /// 0 if fail. + ACE_Thread_Descriptor *thread_descriptor (ACE_thread_t); + + /// Return a pointer to the thread's Thread_Descriptor, + /// 0 if fail. + ACE_Thread_Descriptor *hthread_descriptor (ACE_hthread_t); + + /// Create a new thread (must be called with locks held). + int spawn_i (ACE_THR_FUNC func, + void *arg, + long flags, + ACE_thread_t * = 0, + ACE_hthread_t *t_handle = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + void *stack = 0, + size_t stack_size = 0, + ACE_Task_Base *task = 0, + const char** thr_name = 0); + + /// Run the registered hooks when the thread exits. + void run_thread_exit_hooks (int i); + + /// Locate the index of the table slot occupied by . Returns + /// -1 if is not in the table doesn't contain . + ACE_Thread_Descriptor *find_thread (ACE_thread_t t_id); + + /// Locate the index of the table slot occupied by . Returns + /// -1 if is not in the table doesn't contain . + ACE_Thread_Descriptor *find_hthread (ACE_hthread_t h_id); + + /** + * Locate the thread descriptor address of the list occupied by + * @a task. Returns 0 if @a task is not in the table doesn't contain + * @a task. + */ + ACE_Thread_Descriptor *find_task (ACE_Task_Base *task, + size_t slot = 0); + + /// Insert a thread in the table (checks for duplicates). + int insert_thr (ACE_thread_t t_id, + ACE_hthread_t, + int grp_id = -1, + long flags = 0); + + /// Append a thread in the table (adds at the end, growing the table + /// if necessary). + int append_thr (ACE_thread_t t_id, ACE_hthread_t, + ACE_UINT32, + int grp_id, + ACE_Task_Base *task = 0, + long flags = 0, + ACE_Thread_Descriptor *td = 0); + + /// Remove thread from the table. + void remove_thr (ACE_Thread_Descriptor *td, + int close_handler); + + /// Remove all threads from the table. + void remove_thr_all (void); + + // = The following four methods implement a simple scheme for + // operating on a collection of threads atomically. + + /** + * Efficiently check whether @a thread is in a particular @a state. + * This call updates the TSS cache if possible to speed up + * subsequent searches. + */ + int check_state (ACE_UINT32 state, + ACE_thread_t thread, + int enable = 1); + + /// Apply @a func to all members of the table that match the @a task + int apply_task (ACE_Task_Base *task, + ACE_THR_MEMBER_FUNC func, + int = 0); + + /// Apply @a func to all members of the table that match the @a grp_id. + int apply_grp (int grp_id, + ACE_THR_MEMBER_FUNC func, + int arg = 0); + + /// Apply @a func to all members of the table. + int apply_all (ACE_THR_MEMBER_FUNC, + int = 0); + + /// Join the thread described in @a td. + int join_thr (ACE_Thread_Descriptor *td, + int = 0); + + /// Resume the thread described in @a td. + int resume_thr (ACE_Thread_Descriptor *td, + int = 0); + + /// Suspend the thread described in @a td. + int suspend_thr (ACE_Thread_Descriptor *td, + int = 0); + + /// Send signal @a signum to the thread described in @a td. + int kill_thr (ACE_Thread_Descriptor *td, + int signum); + + /// Set the cancellation flag for the thread described in @a td. + int cancel_thr (ACE_Thread_Descriptor *td, + int async_cancel = 0); + + /// Register a thread as terminated and put it into the . + int register_as_terminated (ACE_Thread_Descriptor *td); + + /// Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer. + static int set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit) *ptr); + + /** + * Keeping a list of thread descriptors within the thread manager. + * Double-linked list enables us to cache the entries in TSS + * and adding/removing thread descriptor entries without + * affecting other thread's descriptor entries. + */ + ACE_Double_Linked_List thr_list_; + +#if !defined (ACE_HAS_VXTHREADS) + /// Collect terminated but not yet joined thread entries. + ACE_Double_Linked_List terminated_thr_list_; +#endif /* !ACE_HAS_VXTHREADS */ + + /// Collect pointers to thread descriptors of threads to be removed later. + ACE_Unbounded_Queue thr_to_be_removed_; + + /// Keeps track of the next group id to assign. + int grp_id_; + + /// Set if we want the Thread_Manager to wait on all threads before + /// being closed, reset otherwise. + int automatic_wait_; + + // = ACE_Thread_Mutex and condition variable for synchronizing termination. +#if defined (ACE_HAS_THREADS) + /// Serialize access to the . + ACE_Thread_Mutex lock_; + + /// Keep track of when there are no more threads. + ACE_Condition_Thread_Mutex zero_cond_; +#endif /* ACE_HAS_THREADS */ + + ACE_Locked_Free_List thread_desc_freelist_; + +private: +#if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) + /// Pointer to a process-wide ACE_Thread_Manager. + static ACE_Thread_Manager *thr_mgr_; + + /// Must delete the thr_mgr_ if true. + static bool delete_thr_mgr_; + + /// Global ACE_TSS (ACE_Thread_Exit) object ptr. + static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_; +#endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */ +}; + +#if defined (ACE_THREAD_MANAGER_LACKS_STATICS) +#define ACE_THREAD_MANAGER_SINGLETON_DEFINE \ + ACE_Singleton; +typedef ACE_Singleton ACE_THREAD_MANAGER_SINGLETON; +#endif /* defined (ACE_THREAD_MANAGER_LACKS_STATICS) */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Thread_Manager.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_MANAGER_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Manager.inl b/dep/ACE_wrappers/ace/Thread_Manager.inl new file mode 100644 index 000000000..6be65a664 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Manager.inl @@ -0,0 +1,307 @@ +// -*- C++ -*- +// +// $Id: Thread_Manager.inl 82588 2008-08-11 13:37:41Z johnnyw $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_At_Thread_Exit::ACE_At_Thread_Exit (void) + : next_ (0), + td_ (0), + was_applied_ (false), + is_owner_ (true) +{ +} + +ACE_INLINE bool +ACE_At_Thread_Exit::was_applied() const +{ + return was_applied_; +} + +ACE_INLINE bool +ACE_At_Thread_Exit::was_applied (bool applied) +{ + was_applied_ = applied; + if (was_applied_) + td_ = 0; + return was_applied_; +} + +ACE_INLINE bool +ACE_At_Thread_Exit::is_owner() const +{ + return is_owner_; +} + +ACE_INLINE bool +ACE_At_Thread_Exit::is_owner (bool owner) +{ + is_owner_ = owner; + return is_owner_; +} + +ACE_INLINE void +ACE_At_Thread_Exit::do_apply (void) +{ + if (!this->was_applied_ && this->is_owner_) + td_->at_pop(); +} + +ACE_INLINE +ACE_At_Thread_Exit_Func::ACE_At_Thread_Exit_Func (void *object, + ACE_CLEANUP_FUNC func, + void *param) + : object_(object), + func_(func), + param_(param) +{ +} + +ACE_INLINE +ACE_Thread_Descriptor_Base::ACE_Thread_Descriptor_Base (void) + : ACE_OS_Thread_Descriptor (), + thr_id_ (ACE_OS::NULL_thread), + thr_handle_ (ACE_OS::NULL_hthread), + grp_id_ (0), + thr_state_ (ACE_Thread_Manager::ACE_THR_IDLE), + task_ (0), + next_ (0), + prev_ (0) +{ +} + +ACE_INLINE +ACE_Thread_Descriptor_Base::~ACE_Thread_Descriptor_Base (void) +{ +} + +ACE_INLINE bool +ACE_Thread_Descriptor_Base::operator== ( + const ACE_Thread_Descriptor_Base &rhs) const +{ + return + ACE_OS::thr_cmp (this->thr_handle_, rhs.thr_handle_) + && ACE_OS::thr_equal (this->thr_id_, rhs.thr_id_); +} + +ACE_INLINE bool +ACE_Thread_Descriptor_Base::operator!=(const ACE_Thread_Descriptor_Base &rhs) const +{ + return !(*this == rhs); +} + +ACE_INLINE ACE_Task_Base * +ACE_Thread_Descriptor_Base::task (void) const +{ + ACE_TRACE ("ACE_Thread_Descriptor_Base::task"); + return this->task_; +} + +// Group ID. + +ACE_INLINE int +ACE_Thread_Descriptor_Base::grp_id (void) const +{ + ACE_TRACE ("ACE_Thread_Descriptor_Base::grp_id"); + return grp_id_; +} + +// Current state of the thread. +ACE_INLINE ACE_UINT32 +ACE_Thread_Descriptor_Base::state (void) const +{ + ACE_TRACE ("ACE_Thread_Descriptor_Base::state"); + return thr_state_; +} + +// Reset this base descriptor. +ACE_INLINE void +ACE_Thread_Descriptor_Base::reset (void) +{ + ACE_TRACE ("ACE_Thread_Descriptor_Base::reset"); + this->thr_id_ = ACE_OS::NULL_thread; + this->thr_handle_ = ACE_OS::NULL_hthread; + this->grp_id_ = 0; + this->thr_state_ = ACE_Thread_Manager::ACE_THR_IDLE; + this->task_ = 0; + this->flags_ = 0; +} + +// Unique thread id. +ACE_INLINE ACE_thread_t +ACE_Thread_Descriptor::self (void) const +{ + ACE_TRACE ("ACE_Thread_Descriptor::self"); + return this->thr_id_; +} + +// Unique kernel-level thread handle. + +ACE_INLINE void +ACE_Thread_Descriptor::self (ACE_hthread_t &handle) +{ + ACE_TRACE ("ACE_Thread_Descriptor::self"); + handle = this->thr_handle_; +} + +ACE_INLINE void +ACE_Thread_Descriptor::log_msg_cleanup (ACE_Log_Msg* log_msg) + +{ + log_msg_ = log_msg; +} + +// Set the pointer +ACE_INLINE void +ACE_Thread_Descriptor::set_next (ACE_Thread_Descriptor *td) +{ + ACE_TRACE ("ACE_Thread_Descriptor::set_next"); + this->next_ = td; +} + +// Get the pointer +ACE_INLINE ACE_Thread_Descriptor * +ACE_Thread_Descriptor::get_next (void) const +{ + ACE_TRACE ("ACE_Thread_Descriptor::get_next"); + return static_cast (this->next_); +} + +// Reset this thread descriptor +ACE_INLINE void +ACE_Thread_Descriptor::reset (ACE_Thread_Manager *tm) +{ + ACE_TRACE ("ACE_Thread_Descriptor::reset"); + this->ACE_Thread_Descriptor_Base::reset (); + this->at_exit_list_ = 0; + // Start the at_exit hook list. + this->tm_ = tm; + // Setup the Thread_Manager. + this->log_msg_ = 0; + this->terminated_ = false; +} + +ACE_INLINE ACE_Thread_Descriptor * +ACE_Thread_Manager::thread_desc_self (void) +{ + // This method must be called with lock held. + + // Try to get it from cache. + ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); + +#if 1 + // ACE_ASSERT (desc != 0); + // Thread descriptor should always get cached. +#else + if (desc == 0) + { + ACE_thread_t id = ACE_OS::thr_self (); + + desc = this->find_thread (id); + + // Thread descriptor adapter might not have been put into the + // list yet. + if (desc != 0) + // Update the TSS cache. + ACE_LOG_MSG->thr_desc (desc); + } +#endif + return desc; +} + +// Return the unique ID of the thread. + +ACE_INLINE ACE_thread_t +ACE_Thread_Manager::thr_self (void) +{ + ACE_TRACE ("ACE_Thread_Manager::thr_self"); + return ACE_Thread::self (); +} + +ACE_INLINE ACE_Task_Base * +ACE_Thread_Manager::task (void) +{ + ACE_TRACE ("ACE_Thread_Manager::task"); + + ACE_Thread_Descriptor *td = this->thread_desc_self () ; + + if (td == 0) + return 0; + else + return td->task (); +} + +ACE_INLINE int +ACE_Thread_Manager::open (size_t) +{ + // Currently no-op. + return 0; +} + +ACE_INLINE int +ACE_Thread_Manager::at_exit (ACE_At_Thread_Exit* at) +{ + ACE_Thread_Descriptor *td = this->thread_desc_self (); + if (td == 0) + return -1; + else + return td->at_exit (at); +} + +ACE_INLINE int +ACE_Thread_Manager::at_exit (ACE_At_Thread_Exit& at) +{ + ACE_Thread_Descriptor *td = this->thread_desc_self (); + if (td == 0) + return -1; + else + return td->at_exit (at); +} + +ACE_INLINE int +ACE_Thread_Manager::at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param) +{ + ACE_Thread_Descriptor *td = this->thread_desc_self (); + if (td == 0) + return -1; + else + return td->at_exit (object, + cleanup_hook, + param); +} + +ACE_INLINE void +ACE_Thread_Manager::wait_on_exit (int do_wait) +{ + this->automatic_wait_ = do_wait; +} + +ACE_INLINE int +ACE_Thread_Manager::wait_on_exit (void) +{ + return this->automatic_wait_; +} + +ACE_INLINE int +ACE_Thread_Manager::register_as_terminated (ACE_Thread_Descriptor *td) +{ +#if defined (ACE_HAS_VXTHREADS) + ACE_UNUSED_ARG (td); +#else /* ! ACE_HAS_VXTHREADS */ + ACE_Thread_Descriptor_Base *tdb = 0; + ACE_NEW_RETURN (tdb, ACE_Thread_Descriptor_Base (*td), -1); + this->terminated_thr_list_.insert_tail (tdb); +#endif /* !ACE_HAS_VXTHREADS */ + return 0; +} + +ACE_INLINE size_t +ACE_Thread_Manager::count_threads (void) const +{ + return this->thr_list_.size (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Mutex.cpp b/dep/ACE_wrappers/ace/Thread_Mutex.cpp new file mode 100644 index 000000000..4ebdc412e --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Mutex.cpp @@ -0,0 +1,62 @@ +/** + * @file Thread_Mutex.cpp + * + * $Id: Thread_Mutex.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt + */ + +#include "ace/Thread_Mutex.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/Malloc_T.h" + +ACE_RCSID(ace, Thread_Mutex, "$Id: Thread_Mutex.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex) + +void +ACE_Thread_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Thread_Mutex::~ACE_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::~ACE_Thread_Mutex"); + this->remove (); +} + +ACE_Thread_Mutex::ACE_Thread_Mutex (const ACE_TCHAR *name, ACE_mutexattr_t *arg) + : removed_ (false) +{ +// ACE_TRACE ("ACE_Thread_Mutex::ACE_Thread_Mutex"); + + if (ACE_OS::thread_mutex_init (&this->lock_, + 0, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Thread_Mutex::ACE_Thread_Mutex"))); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Thread_Mutex.h b/dep/ACE_wrappers/ace/Thread_Mutex.h new file mode 100644 index 000000000..471434eb4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Mutex.h @@ -0,0 +1,175 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Thread_Mutex.h + * + * $Id: Thread_Mutex.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_THREAD_MUTEX_H +#define ACE_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Mutex.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include /**/ "ace/ACE_export.h" +#include "ace/OS_NS_Thread.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Thread_Mutex + * + * @brief ACE_Thread_Mutex wrapper (only valid for threads in the same + * process). + * + * This implementation is optimized for locking threads that are + * in the same process. It maps to s on NT + * and with set to on UNIX. + * ACE_Thread_Mutex is recursive on some platforms (like + * Win32). However, on most platforms (like Solaris) it is not + * recursive. To be totally safe and portable, developers + * should use ACE_Recursive_Thread_Mutex when they need a + * recursive mutex. + */ +class ACE_Export ACE_Thread_Mutex +{ + friend class ACE_Condition_Thread_Mutex; +public: + /// Constructor. + ACE_Thread_Mutex (const ACE_TCHAR *name = 0, + ACE_mutexattr_t *attributes = 0); + + /// Implicitly destroy the mutex. + ~ACE_Thread_Mutex (void); + + /** + * Explicitly destroy the mutex. Note that only one thread should + * call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Acquire lock ownership (wait on queue if necessary). + int acquire (void); + + /** + * Block the thread until we acquire the mutex or until @a tv times + * out, in which case -1 is returned with @c errno == @c ETIME. Note + * that @a tv is assumed to be in "absolute" rather than "relative" + * time. The value of @a tv is updated upon return to show the + * actual (absolute) acquisition time. + */ + int acquire (ACE_Time_Value &tv); + + /** + * If @a tv == 0 the call directly. Otherwise, Block the + * thread until we acquire the mutex or until @a tv times out, in + * which case -1 is returned with @c errno == @c ETIME. Note that + * @a tv is assumed to be in "absolute" rather than "relative" time. + * The value of @a tv is updated upon return to show the actual + * (absolute) acquisition time. + */ + int acquire (ACE_Time_Value *tv); + + /** + * Conditionally acquire lock (i.e., don't wait on queue). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, @c errno is set to @c EBUSY. + */ + int tryacquire (void); + + /// Release lock and unblock a thread at head of queue. + int release (void); + + /** + * Acquire mutex ownership. This calls acquire() and is only here + * to make the ACE_Thread_Mutex interface consistent with the + * other synchronization APIs. + */ + int acquire_read (void); + + /** + * Acquire mutex ownership. This calls acquire() and is only here + * to make the ACE_Thread_Mutex interface consistent with the + * other synchronization APIs. + */ + int acquire_write (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * tryacquire() and is only here to make the ACE_Thread_Mutex + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_read (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * tryacquire() and is only here to make the ACE_Thread_Mutex + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, @c errno is set to @c EBUSY. + */ + int tryacquire_write (void); + + /** + * This is only here to make the ACE_Thread_Mutex + * interface consistent with the other synchronization APIs. + * Assumes the caller has already acquired the mutex using one of + * the above calls, and returns 0 (success) always. + */ + int tryacquire_write_upgrade (void); + + /// Return the underlying mutex. + const ACE_thread_mutex_t &lock (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // protected: + /// Mutex type that supports single-process locking efficiently. + ACE_thread_mutex_t lock_; + + /// Keeps track of whether remove() has been called yet to avoid + /// multiple calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// on the same object, which is a bad idea anyway... + bool removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Thread_Mutex &); + ACE_Thread_Mutex (const ACE_Thread_Mutex &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_MUTEX_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Mutex.inl b/dep/ACE_wrappers/ace/Thread_Mutex.inl new file mode 100644 index 000000000..ff744684c --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Mutex.inl @@ -0,0 +1,97 @@ +// -*- C++ -*- +// +// $Id: Thread_Mutex.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE const ACE_thread_mutex_t & +ACE_Thread_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_Thread_Mutex::lock"); + return this->lock_; +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire_read"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire_write"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_read"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_write_upgrade (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write_upgrade"); + return 0; +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (ACE_Time_Value &tv) +{ + // ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_, tv); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (ACE_Time_Value *tv) +{ + // ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_, tv); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::release (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::release"); + return ACE_OS::thread_mutex_unlock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::remove"); + int result = 0; + if (this->removed_ == false) + { + this->removed_ = true; + result = ACE_OS::thread_mutex_destroy (&this->lock_); + } + return result; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Thread_Semaphore.cpp b/dep/ACE_wrappers/ace/Thread_Semaphore.cpp new file mode 100644 index 000000000..39b28931d --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Semaphore.cpp @@ -0,0 +1,62 @@ +/** + * @file Thread_Semaphore.cpp + * + * $Id: Thread_Semaphore.cpp 80826 2008-03-04 14:51:23Z wotte $ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt + */ + +#include "ace/Thread_Semaphore.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Thread_Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/ACE.h" + +ACE_RCSID(ace, Thread_Semaphore, "$Id: Thread_Semaphore.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +void +ACE_Thread_Semaphore::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Semaphore::dump"); + + ACE_Semaphore::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Thread_Semaphore::ACE_Thread_Semaphore (unsigned int count, + const ACE_TCHAR *name, + void *arg, + int max) + : ACE_Semaphore (count, USYNC_THREAD, name, arg, max) +{ +// ACE_TRACE ("ACE_Thread_Semaphore::ACE_Thread_Semaphore"); +} + +/*****************************************************************************/ + +ACE_Thread_Semaphore * +ACE_Malloc_Lock_Adapter_T::operator () (const ACE_TCHAR *name) +{ + ACE_Thread_Semaphore *p = 0; + if (name == 0) + ACE_NEW_RETURN (p, ACE_Thread_Semaphore (1, name), 0); + else + ACE_NEW_RETURN (p, ACE_Thread_Semaphore (1, ACE::basename (name, + ACE_DIRECTORY_SEPARATOR_CHAR)), + 0); + return p; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Thread_Semaphore.h b/dep/ACE_wrappers/ace/Thread_Semaphore.h new file mode 100644 index 000000000..b35ef334c --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Semaphore.h @@ -0,0 +1,89 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Thread_Semaphore.h + * + * $Id: Thread_Semaphore.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt + */ +//========================================================================== + +#ifndef ACE_THREAD_SEMAPHORE_H +#define ACE_THREAD_SEMAPHORE_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Semaphore.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include "ace/Semaphore.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Thread_Semaphore + * + * @brief Wrapper for Dijkstra style general semaphores that work + * only within one process. + */ +class ACE_Export ACE_Thread_Semaphore : public ACE_Semaphore +{ +public: + /// Initialize the semaphore, with an initial value of @a count, + /// maximum value of @a max, and unlocked by default. + ACE_Thread_Semaphore (unsigned int count = 1, // By default make this unlocked. + const ACE_TCHAR *name = 0, + void * = 0, + int max = 0x7FFFFFFF); + + /// Default dtor. + ~ACE_Thread_Semaphore (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +/*****************************************************************************/ + +template class ACE_Malloc_Lock_Adapter_T; + +/** + * @class ACE_Malloc_Lock_Adapter_T + * + * @brief Template specialization of ACE_Malloc_Lock_Adapter_T for + * ACE_Thread_Semaphore. + * + * This is needed since the ctor for ACE_Thread_Semaphore doesn't match + * the standard form used by other lock strategy classes. + */ +template<> +class ACE_Export ACE_Malloc_Lock_Adapter_T +{ +public: + ACE_Thread_Semaphore * operator () (const ACE_TCHAR *name); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Thread_Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_SEMAPHORE_H */ diff --git a/dep/ACE_wrappers/ace/Thread_Semaphore.inl b/dep/ACE_wrappers/ace/Thread_Semaphore.inl new file mode 100644 index 000000000..b64ec3c08 --- /dev/null +++ b/dep/ACE_wrappers/ace/Thread_Semaphore.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id: Thread_Semaphore.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_Thread_Semaphore::~ACE_Thread_Semaphore (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Throughput_Stats.cpp b/dep/ACE_wrappers/ace/Throughput_Stats.cpp new file mode 100644 index 000000000..6e6672997 --- /dev/null +++ b/dep/ACE_wrappers/ace/Throughput_Stats.cpp @@ -0,0 +1,202 @@ +// $Id: Throughput_Stats.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Throughput_Stats.h" + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/High_Res_Timer.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, Throughput_Stats, "$Id: Throughput_Stats.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Throughput_Stats::ACE_Throughput_Stats (void) + : ACE_Basic_Stats () + , throughput_last_ (0) +#if 0 + // @@TODO: This is what I really wanted to compute, but it just + // does not work. + , throughput_sum_x_ (0) + , throughput_sum_x2_ (0) + , throughput_sum_y_ (0) + , throughput_sum_y2_ (0) + , throughput_sum_xy_ (0) +#endif /* 0 */ +{ +} + +void +ACE_Throughput_Stats::sample (ACE_UINT64 throughput, + ACE_UINT64 latency) +{ + this->ACE_Basic_Stats::sample (latency); + + if (this->samples_count () == 1u) + { + + this->throughput_last_ = throughput; +#if 0 + // @@TODO: This is what I really wanted to compute, but it just + // does not work. + this->throughput_sum_y_ = this->samples_count_; + this->throughput_sum_y2_ = this->samples_count_ * this->samples_count_; + this->throughput_sum_x_ = throughput; + this->throughput_sum_x2_ = throughput * throughput; + this->throughput_sum_xy_ = throughput * this->samples_count_; + + ACE_OS::printf ("%f %qu\n", throughput / 400000000.0, this->samples_count_); +#endif /* 0 */ + } + else + { + this->throughput_last_ = throughput; + +#if 0 + // @@TODO: This is what I really wanted to compute, but it just + // does not work. + this->throughput_sum_y_ += this->samples_count_; + this->throughput_sum_y2_ += this->samples_count_ * this->samples_count_; + this->throughput_sum_x_ += throughput; + this->throughput_sum_x2_ += throughput * throughput; + this->throughput_sum_xy_ += throughput * this->samples_count_; + + ACE_OS::printf ("%f %qu\n", throughput / 400000000.0, this->samples_count_); +#endif /* 0 */ + } +} + +void +ACE_Throughput_Stats::accumulate (const ACE_Throughput_Stats &rhs) +{ + if (rhs.samples_count () == 0u) + return; + + this->ACE_Basic_Stats::accumulate (rhs); + + if (this->samples_count () == 0u) + { + this->throughput_last_ = rhs.throughput_last_; +#if 0 + // @@TODO: This is what I really wanted to compute, but it just + // does not work. + this->throughput_sum_x_ = rhs.throughput_sum_x_; + this->throughput_sum_x2_ = rhs.throughput_sum_x2_; + this->throughput_sum_y_ = rhs.throughput_sum_y_; + this->throughput_sum_y2_ = rhs.throughput_sum_y2_; + this->throughput_sum_xy_ = rhs.throughput_sum_xy_; +#endif /* 0 */ + + return; + } + + + if (this->throughput_last_ < rhs.throughput_last_) + this->throughput_last_ = rhs.throughput_last_; + +#if 0 + // @@TODO: This is what I really wanted to compute, but it just + // does not work. + this->throughput_sum_x_ += rhs.throughput_sum_x_; + this->throughput_sum_x2_ += rhs.throughput_sum_x2_; + this->throughput_sum_y_ += rhs.throughput_sum_y_; + this->throughput_sum_y2_ += rhs.throughput_sum_y2_; + this->throughput_sum_xy_ += rhs.throughput_sum_xy_; +#endif /* 0 */ +} + +void +ACE_Throughput_Stats::dump_results (const ACE_TCHAR* msg, + ACE_UINT32 sf) +{ + if (this->samples_count () == 0u) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s : no data collected\n"), msg)); + return; + } + + this->ACE_Basic_Stats::dump_results (msg, sf); + + ACE_Throughput_Stats::dump_throughput (msg, sf, + this->throughput_last_, + this->samples_count ()); + +#if 0 + // @@TODO: This is what I really wanted to generate, but it just + // doesn't work. + double t_sum_x = + ACE_CU64_TO_CU32 (this->throughput_sum_x_);// / sf); + //t_sum_x /= 1000000.0; + double t_sum_y = + ACE_CU64_TO_CU32 (this->throughput_sum_y_); + double t_sum_x2 = + ACE_CU64_TO_CU32 (this->throughput_sum_x2_);// / (sf*sf)); + //t_sum_x2 /= 1000000.0; + //t_sum_x2 /= 1000000.0; + double t_sum_y2 = + ACE_CU64_TO_CU32 (this->throughput_sum_y2_); + double t_sum_xy = + ACE_CU64_TO_CU32 (this->throughput_sum_xy_);// / sf); + //t_sum_xy /= 1000000.0; + double t_avgx = t_sum_x / this->samples_count (); + double t_avgy = t_sum_y / this->samples_count (); + + double t_a = + (this->samples_count () * t_sum_xy - t_sum_x * t_sum_y) + / (this->samples_count () * t_sum_x2 - t_sum_x * t_sum_x); + double t_b = (t_avgy - t_a * t_avgx); + + t_a *= 1000000.0; + + double d_r = + (t_sum_xy - t_avgx * t_sum_y - t_avgy * t_sum_x + + this->samples_count () * t_avgx * t_avgy); + double n_r = + (t_sum_x2 + - this->samples_count () * t_avgx * t_avgx) + * (t_sum_y2 + - this->samples_count () * t_avgy * t_avgy); + double t_r = d_r * d_r / n_r; + + // ACE_DEBUG ((LM_DEBUG, + // "%s throughput: %.2f/%.2f/%.2f/%.6f/%.2f (avg/a/b/r/elapsed)\n", + // msg, t_avg, t_a, t_b, t_r, seconds)); + // ACE_DEBUG ((LM_DEBUG, + // "%s data: %.2f/%.2f/%.2f/%.6f/%.2f (x/x2/y/y2/xy)\n", + // msg, t_sum_x, t_sum_x2, t_sum_y, t_sum_y2, t_sum_xy)); +#endif +} + +void +ACE_Throughput_Stats::dump_throughput (const ACE_TCHAR *msg, + ACE_UINT32 sf, + ACE_UINT64 elapsed_time, + ACE_UINT32 samples_count) +{ +#ifndef ACE_NLOGGING + double seconds = +# if defined ACE_LACKS_LONGLONG_T + elapsed_time / sf; +#elif defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + static_cast (ACE_UINT64_DBLCAST_ADAPTER ( + ACE_U_LongLong(elapsed_time / sf))); +# else /* ! ACE_LACKS_LONGLONG_T */ + static_cast (ACE_UINT64_DBLCAST_ADAPTER (elapsed_time / sf)); +# endif /* ! ACE_LACKS_LONGLONG_T */ + seconds /= ACE_HR_SCALE_CONVERSION; + + const double t_avg = samples_count / seconds; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s throughput: %.2f (events/second)\n"), + msg, t_avg)); +#else + ACE_UNUSED_ARG (msg); + ACE_UNUSED_ARG (sf); + ACE_UNUSED_ARG (elapsed_time); + ACE_UNUSED_ARG (samples_count); +#endif /* ACE_NLOGGING */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Throughput_Stats.h b/dep/ACE_wrappers/ace/Throughput_Stats.h new file mode 100644 index 000000000..c306c856c --- /dev/null +++ b/dep/ACE_wrappers/ace/Throughput_Stats.h @@ -0,0 +1,86 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Throughput_Stats.h + * + * $Id: Throughput_Stats.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author David L. Levine + */ +//========================================================================== + + +#ifndef ACE_THROUGHPUT_STATS_H +#define ACE_THROUGHPUT_STATS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Basic_Stats.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/// A simple class to make throughput and latency analysis. +/** + * + * Keep the relevant information to perform throughput and latency + * analysis, including: + * -# Minimum, Average and Maximum latency + * -# Jitter for the latency + * -# Linear regression for throughput + * -# Accumulate results from several samples to obtain aggregated + * results, across several threads or experiments. + * + * @todo The idea behind this class was to use linear regression to + * determine if the throughput was linear or exhibited jitter. + * Unfortunately it never worked quite right, so only average + * throughput is computed. + */ +class ACE_Export ACE_Throughput_Stats : public ACE_Basic_Stats +{ +public: + /// Constructor + ACE_Throughput_Stats (void); + + /// Store one sample + void sample (ACE_UINT64 throughput, ACE_UINT64 latency); + + /// Update the values to reflect the stats in @a throughput + void accumulate (const ACE_Throughput_Stats &throughput); + + /// Print down the stats + void dump_results (const ACE_TCHAR* msg, ACE_UINT32 scale_factor); + + /// Dump the average throughput stats. + static void dump_throughput (const ACE_TCHAR *msg, + ACE_UINT32 scale_factor, + ACE_UINT64 elapsed_time, + ACE_UINT32 samples_count); +private: + /// The last throughput measurement. + ACE_UINT64 throughput_last_; + +#if 0 + /// These are the fields that we should keep to perform linear + /// regression + //@{ + ///@} + ACE_UINT64 throughput_sum_x_; + ACE_UINT64 throughput_sum_x2_; + ACE_UINT64 throughput_sum_y_; + ACE_UINT64 throughput_sum_y2_; + ACE_UINT64 throughput_sum_xy_; +#endif /* 0 */ +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ! ACE_THROUGHPUT_STATS_H */ diff --git a/dep/ACE_wrappers/ace/Time_Value.cpp b/dep/ACE_wrappers/ace/Time_Value.cpp new file mode 100644 index 000000000..8ecfbe7d3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Time_Value.cpp @@ -0,0 +1,264 @@ +#include "ace/Time_Value.h" + +ACE_RCSID (ace, + Time_Value, + "$Id: Time_Value.cpp 80826 2008-03-04 14:51:23Z wotte $") + + +#if !defined (__ACE_INLINE__) +#include "ace/Time_Value.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Numeric_Limits.h" +#include "ace/If_Then_Else.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Static constant representing `zero-time'. +// Note: this object requires static construction. +const ACE_Time_Value ACE_Time_Value::zero; + +// Constant for maximum time representable. Note that this time +// is not intended for use with select () or other calls that may +// have *their own* implementation-specific maximum time representations. +// Its primary use is in time computations such as those used by the +// dynamic subpriority strategies in the ACE_Dynamic_Message_Queue class. +// Note: this object requires static construction. +const ACE_Time_Value ACE_Time_Value::max_time ( + ACE_Numeric_Limits::max (), + ACE_ONE_SECOND_IN_USECS - 1); + +ACE_ALLOC_HOOK_DEFINE (ACE_Time_Value) + +// Increment microseconds (the only reason this is here is to allow +// the use of ACE_Atomic_Op with ACE_Time_Value). + +ACE_Time_Value +ACE_Time_Value::operator ++ (int) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator ++ (int)"); + ACE_Time_Value tv (*this); + ++*this; + return tv; +} + +ACE_Time_Value & +ACE_Time_Value::operator ++ (void) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator ++ (void)"); + this->usec (this->usec () + 1); + this->normalize (); + return *this; +} + +// Decrement microseconds (the only reason this is here is / to allow +// the use of ACE_Atomic_Op with ACE_Time_Value). + +ACE_Time_Value +ACE_Time_Value::operator -- (int) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator -- (int)"); + ACE_Time_Value tv (*this); + --*this; + return tv; +} + +ACE_Time_Value & +ACE_Time_Value::operator -- (void) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator -- (void)"); + this->usec (this->usec () - 1); + this->normalize (); + return *this; +} + +#if defined (ACE_WIN32) +// Static constant to remove time skew between FILETIME and POSIX +// time. POSIX and Win32 use different epochs (Jan. 1, 1970 v.s. +// Jan. 1, 1601). The following constant defines the difference +// in 100ns ticks. +// +// In the beginning (Jan. 1, 1601), there was no time and no computer. +// And Bill said: "Let there be time," and there was time.... +# if defined (ACE_LACKS_LONGLONG_T) +const ACE_U_LongLong ACE_Time_Value::FILETIME_to_timval_skew = +ACE_U_LongLong (0xd53e8000, 0x19db1de); +# else +const DWORDLONG ACE_Time_Value::FILETIME_to_timval_skew = +ACE_INT64_LITERAL (0x19db1ded53e8000); +# endif + +// Initializes the ACE_Time_Value object from a Win32 FILETIME + +ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time) +{ + // // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (file_time); +} + +void ACE_Time_Value::set (const FILETIME &file_time) +{ + // Initializes the ACE_Time_Value object from a Win32 FILETIME +#if defined (ACE_LACKS_LONGLONG_T) + ACE_U_LongLong LL_100ns(file_time.dwLowDateTime, file_time.dwHighDateTime); + LL_100ns -= ACE_Time_Value::FILETIME_to_timval_skew; + // Convert 100ns units to seconds; + this->tv_.tv_sec = (long) (LL_100ns / ((double) (10000 * 1000))); + // Convert remainder to microseconds; + this->tv_.tv_usec = (suseconds_t)((LL_100ns % ((ACE_UINT32)(10000 * 1000))) / 10); +#else + // Don't use a struct initializer, gcc don't like it. + ULARGE_INTEGER _100ns; + _100ns.LowPart = file_time.dwLowDateTime; + _100ns.HighPart = file_time.dwHighDateTime; + + _100ns.QuadPart -= ACE_Time_Value::FILETIME_to_timval_skew; + + // Convert 100ns units to seconds; + this->tv_.tv_sec = (long) (_100ns.QuadPart / (10000 * 1000)); + // Convert remainder to microseconds; + this->tv_.tv_usec = (suseconds_t) ((_100ns.QuadPart % (10000 * 1000)) / 10); +#endif // ACE_LACKS_LONGLONG_T + this->normalize (); +} + +// Returns the value of the object as a Win32 FILETIME. + +ACE_Time_Value::operator FILETIME () const +{ + FILETIME file_time; + // ACE_OS_TRACE ("ACE_Time_Value::operator FILETIME"); + +#if defined (ACE_LACKS_LONGLONG_T) + ACE_U_LongLong LL_sec(this->tv_.tv_sec); + ACE_U_LongLong LL_usec(this->tv_.tv_usec); + ACE_U_LongLong LL_100ns = LL_sec * (ACE_UINT32)(10000 * 1000) + + LL_usec * (ACE_UINT32)10 + + ACE_Time_Value::FILETIME_to_timval_skew; + file_time.dwLowDateTime = LL_100ns.lo(); + file_time.dwHighDateTime = LL_100ns.hi(); +#else + ULARGE_INTEGER _100ns; + _100ns.QuadPart = (((DWORDLONG) this->tv_.tv_sec * (10000 * 1000) + + this->tv_.tv_usec * 10) + + ACE_Time_Value::FILETIME_to_timval_skew); + + file_time.dwLowDateTime = _100ns.LowPart; + file_time.dwHighDateTime = _100ns.HighPart; +#endif //ACE_LACKS_LONGLONG_T + + return file_time; +} + +#endif /* ACE_WIN32 */ + +void +ACE_Time_Value::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_OS_TRACE ("ACE_Time_Value::dump"); +#if 0 + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntv_sec_ = %d"), this->tv_.tv_sec)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntv_usec_ = %d\n"), this->tv_.tv_usec)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* 0 */ +#endif /* ACE_HAS_DUMP */ +} + +void +ACE_Time_Value::normalize (void) +{ + // // ACE_OS_TRACE ("ACE_Time_Value::normalize"); + // From Hans Rohnert... + + if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS) + { + /*! \todo This loop needs some optimization. + */ + do + { + ++this->tv_.tv_sec; + this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS; + } + while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS); + } + else if (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS) + { + /*! \todo This loop needs some optimization. + */ + do + { + --this->tv_.tv_sec; + this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS; + } + while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS); + } + + if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0) + { + --this->tv_.tv_sec; + this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS; + } +// tv_sec in qnxnto is unsigned +#if !defined ( __QNXNTO__) + else if (this->tv_.tv_sec < 0 && this->tv_.tv_usec > 0) + { + ++this->tv_.tv_sec; + this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS; + } +#endif /* __QNXNTO__ */ +} + + +ACE_Time_Value & +ACE_Time_Value::operator *= (double d) +{ + // The floating type to be used in the computations. It should be + // large enough to hold a time_t. We actually want a floating type + // with enough digits in its mantissa to hold a time_t without + // losing precision. For example, if FLT_RADIX is 2 and + // LDBL_MANT_DIG is 64, a long double has a 64 bit wide mantissa, + // which would be sufficient to hold a 64 bit time_t value without + // losing precision. + // + // For now we'll simply go with long double if it is larger than + // time_t. We're hosed if long double isn't large enough. + typedef ACE::If_Then_Else<(sizeof (double) > sizeof (time_t)), + double, + long double>::result_type float_type; + + float_type time_total = + (this->sec () + + static_cast (this->usec ()) / ACE_ONE_SECOND_IN_USECS) * d; + + // shall we saturate the result? + static const float_type max_int = + ACE_Numeric_Limits::max () + 0.999999; + static const float_type min_int = + ACE_Numeric_Limits::min () - 0.999999; + + if (time_total > max_int) + time_total = max_int; + if (time_total < min_int) + time_total = min_int; + + const time_t time_sec = static_cast (time_total); + + time_total -= time_sec; + time_total *= ACE_ONE_SECOND_IN_USECS; + + suseconds_t time_usec = static_cast (time_total); + + // round up the result to save the last usec + if (time_usec > 0 && (time_total - time_usec) >= 0.5) + ++time_usec; + else if (time_usec < 0 && (time_total - time_usec) <= -0.5) + --time_usec; + + this->set (time_sec, time_usec); + + return *this; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Time_Value.h b/dep/ACE_wrappers/ace/Time_Value.h new file mode 100644 index 000000000..b00410e2b --- /dev/null +++ b/dep/ACE_wrappers/ace/Time_Value.h @@ -0,0 +1,380 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Time_Value.h + * + * $Id: Time_Value.h 81914 2008-06-11 13:56:11Z sma $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TIME_VALUE_H +#define ACE_TIME_VALUE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +# include "ace/os_include/os_time.h" + +// Define some helpful constants. +// Not type-safe, and signed. For backward compatibility. +#define ACE_ONE_SECOND_IN_MSECS 1000L +suseconds_t const ACE_ONE_SECOND_IN_USECS = 1000000; +#define ACE_ONE_SECOND_IN_NSECS 1000000000L + +// needed for ACE_UINT64 +#include "ace/Basic_Types.h" + +// This forward declaration is needed by the set() and FILETIME() functions +#if defined (ACE_LACKS_LONGLONG_T) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Export ACE_U_LongLong; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_LACKS_LONGLONG_T */ + +// ------------------------------------------------------------------- + +/** + * @class ACE_Time_Value + * + * @brief Operations on "timeval" structures, which express time in + * seconds (secs) and microseconds (usecs). + * + * This class centralizes all the time related processing in + * ACE. These time values are typically used in conjunction with OS + * mechanisms like or other calls that may have + * *their own* implementation-specific maximum time representations. + * Its primary use is in time computations such as those used by the + * dynamic subpriority strategies in the ACE_Dynamic_Message_Queue + * class. + */ + static const ACE_Time_Value max_time; + + // = Initialization methods. + + /// Default Constructor. + ACE_Time_Value (void); + + /// Constructor. + explicit ACE_Time_Value (time_t sec, suseconds_t usec = 0); + + // = Methods for converting to/from various time formats. + + /// Construct the ACE_Time_Value from a timeval. + explicit ACE_Time_Value (const struct timeval &t); + + /// Construct the ACE_Time_Value object from a timespec_t. + explicit ACE_Time_Value (const timespec_t &t); + +# if defined (ACE_WIN32) + /// Construct the ACE_Time_Value object from a Win32 FILETIME + explicit ACE_Time_Value (const FILETIME &ft); +# endif /* ACE_WIN32 */ + + /// Initializes the ACE_Time_Value from seconds and useconds. + void set (time_t sec, suseconds_t usec); + + /// Initializes the ACE_Time_Value from a double, which is assumed to be + /// in second format, with any remainder treated as microseconds. + void set (double d); + + /// Initializes the ACE_Time_Value from a timeval. + void set (const timeval &t); + + /// Initializes the ACE_Time_Value object from a timespec_t. + void set (const timespec_t &t); + +# if defined (ACE_WIN32) + /// Initializes the ACE_Time_Value object from a Win32 FILETIME. + void set (const FILETIME &ft); +# endif /* ACE_WIN32 */ + + /// Converts from ACE_Time_Value format into milliseconds format. + /** + * @return Sum of second field (in milliseconds) and microsecond field + * (in milliseconds). Note that this method can overflow if + * the second and microsecond field values are large, so use + * the msec (ACE_UINT64 &ms) method instead. + * + * @note The semantics of this method differs from the sec() and + * usec() methods. There is no analogous "millisecond" + * component in an ACE_Time_Value. + */ + unsigned long msec (void) const; + + /// Converts from ACE_Time_Value format into milliseconds format. + /** + * @return Sum of second field (in milliseconds) and microsecond field + * (in milliseconds) and return them via the @param ms parameter. + * + * @note The semantics of this method differs from the sec() and + * usec() methods. There is no analogous "millisecond" + * component in an ACE_Time_Value. + */ + void msec (ACE_UINT64 &ms) const; + + /// Converts from ACE_Time_Value format into milliseconds format. + /** + * @return Sum of second field (in milliseconds) and microsecond field + * (in milliseconds) and return them via the @param ms parameter. + * + * @note The semantics of this method differs from the sec() and + * usec() methods. There is no analogous "millisecond" + * component in an ACE_Time_Value. + */ + void msec (ACE_UINT64 &ms) /* const */; + + /// Converts from milli-seconds format into ACE_Time_Value format. + /** + * @note The semantics of this method differs from the sec() and + * usec() methods. There is no analogous "millisecond" + * component in an ACE_Time_Value. + */ + void msec (long); + + /// Converts from milli-seconds format into ACE_Time_Value format. + /** + * @note The semantics of this method differs from the sec() and + * usec() methods. There is no analogous "millisecond" + * component in an ACE_Time_Value. + */ + void msec (int); // converted to long then calls above. + + /// Returns the value of the object as a timespec_t. + operator timespec_t () const; + + /// Returns the value of the object as a timeval. + operator timeval () const; + + /// Returns a pointer to the object as a timeval. + operator const timeval *() const; + +# if defined (ACE_WIN32) + /// Returns the value of the object as a Win32 FILETIME. + operator FILETIME () const; +# endif /* ACE_WIN32 */ + + // = The following are accessor/mutator methods. + + /// Get seconds. + /** + * @return The second field/component of this ACE_Time_Value. + * + * @note The semantics of this method differs from the msec() + * method. + */ + time_t sec (void) const; + + /// Set seconds. + void sec (time_t sec); + + /// Get microseconds. + /** + * @return The microsecond field/component of this ACE_Time_Value. + * + * @note The semantics of this method differs from the msec() + * method. + */ + suseconds_t usec (void) const; + + /// Set microseconds. + void usec (suseconds_t usec); + + /** + * @return Sum of second field (in microseconds) and microsecond field + * and return them via the @param usec parameter. + */ + void to_usec (ACE_UINT64 &usec) const; + + // = The following arithmetic methods operate on ACE_Time_Value's. + + /// Add @a tv to this. + ACE_Time_Value &operator += (const ACE_Time_Value &tv); + + /// Add @a tv to this. + ACE_Time_Value &operator += (time_t tv); + + /// Assign @ tv to this + ACE_Time_Value &operator = (const ACE_Time_Value &tv); + + /// Assign @ tv to this + ACE_Time_Value &operator = (time_t tv); + + /// Subtract @a tv to this. + ACE_Time_Value &operator -= (const ACE_Time_Value &tv); + + /// Substract @a tv to this. + ACE_Time_Value &operator -= (time_t tv); + + /** + \brief Multiply the time value by the @a d factor. + \note The result of the operator is valid for results from range + < (ACE_INT32_MIN, -999999), (ACE_INT32_MAX, 999999) >. Result + outside this range are saturated to a limit. + */ + ACE_Time_Value &operator *= (double d); + + /// Increment microseconds as postfix. + /** + * @note The only reason this is here is to allow the use of ACE_Atomic_Op + * with ACE_Time_Value. + */ + ACE_Time_Value operator++ (int); + + /// Increment microseconds as prefix. + /** + * @note The only reason this is here is to allow the use of ACE_Atomic_Op + * with ACE_Time_Value. + */ + ACE_Time_Value &operator++ (void); + + /// Decrement microseconds as postfix. + /** + * @note The only reason this is here is to allow the use of ACE_Atomic_Op + * with ACE_Time_Value. + */ + ACE_Time_Value operator-- (int); + + /// Decrement microseconds as prefix. + /** + * @note The only reason this is here is to allow the use of ACE_Atomic_Op + * with ACE_Time_Value. + */ + ACE_Time_Value &operator-- (void); + + /// Adds two ACE_Time_Value objects together, returns the sum. + friend ACE_Export ACE_Time_Value operator + (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// Subtracts two ACE_Time_Value objects, returns the difference. + friend ACE_Export ACE_Time_Value operator - (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// True if @a tv1 < @a tv2. + friend ACE_Export bool operator < (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// True if @a tv1 > @a tv2. + friend ACE_Export bool operator > (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// True if @a tv1 <= @a tv2. + friend ACE_Export bool operator <= (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// True if @a tv1 >= @a tv2. + friend ACE_Export bool operator >= (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// True if @a tv1 == @a tv2. + friend ACE_Export bool operator == (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + /// True if @a tv1 != @a tv2. + friend ACE_Export bool operator != (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2); + + //@{ + /// Multiplies the time value by @a d + friend ACE_Export ACE_Time_Value operator * (double d, + const ACE_Time_Value &tv); + + friend ACE_Export ACE_Time_Value operator * (const ACE_Time_Value &tv, + double d); + //@} + + /// Dump is a no-op. + /** + * The dump() method is a no-op. It's here for backwards compatibility + * only, but does not dump anything. Invoking logging methods here + * violates layering restrictions in ACE because this class is part + * of the OS layer and @c ACE_Log_Msg is at a higher level. + */ + void dump (void) const; + +# if defined (ACE_WIN32) + /// Const time difference between FILETIME and POSIX time. +# if defined (ACE_LACKS_LONGLONG_T) + static const ACE_U_LongLong FILETIME_to_timval_skew; +# else + static const DWORDLONG FILETIME_to_timval_skew; +# endif // ACE_LACKS_LONGLONG_T +# endif /* ACE_WIN32 */ + +private: + /// Put the timevalue into a canonical form. + void normalize (void); + + /// Store the values as a timeval. +#if defined (ACE_HAS_TIME_T_LONG_MISMATCH) + // Windows' timeval is non-conformant, so swap in a struct that conforms + // to the proper data types to represent the entire time range that this + // class's API can accept. + // Also, since this class can supply a pointer to a timeval that things + // like select() expect, we need the OS-defined one as well. To make this + // available, use a real timeval called ext_tv_ and set it up when needed. + // Since this is most often for relative times that don't approach 32 bits + // in size, reducing a time_t to fit should be no problem. + struct { + time_t tv_sec; + suseconds_t tv_usec; + } tv_; + timeval ext_tv_; +#else + timeval tv_; +#endif /* ACE_HAS_TIME_T_LONG_MISMATCH */ +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Time_Value.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_WIN32) && defined (_WIN32_WCE) +} +#endif + +#if defined (__MINGW32__) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +// The MingW linker has problems with the exported statics +// zero and max_time with these two statics the linker will be able to +// resolve the static exported symbols. +static const ACE_Time_Value& __zero_time = ACE_Time_Value::zero; +static const ACE_Time_Value& __max_time = ACE_Time_Value::max_time; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* __MINGW32__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_TIME_VALUE_H */ diff --git a/dep/ACE_wrappers/ace/Time_Value.inl b/dep/ACE_wrappers/ace/Time_Value.inl new file mode 100644 index 000000000..274333893 --- /dev/null +++ b/dep/ACE_wrappers/ace/Time_Value.inl @@ -0,0 +1,422 @@ +// -*- C++ -*- +// +// $Id: Time_Value.inl 82610 2008-08-12 19:46:36Z parsons $ + +#include "ace/Truncate.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_WIN32) && defined (_WIN32_WCE) +// Something is a bit brain-damaged here and I'm not sure what... this code +// compiled before the OS reorg for ACE 5.4. Since then it hasn't - eVC +// complains that the operators that return ACE_Time_Value are C-linkage +// functions that can't return a C++ class. The only way I've found to +// defeat this is to wrap the whole class in extern "C++". +// - Steve Huston, 23-Aug-2004 +extern "C++" { +#endif + +// Returns the value of the object as a timeval. + +ACE_INLINE +ACE_Time_Value::operator timeval () const +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator timeval"); +#if defined (ACE_HAS_TIME_T_LONG_MISMATCH) + // Recall that on some Windows we substitute another type for timeval in tv_ + ACE_Time_Value *me = const_cast (this); + me->ext_tv_.tv_sec = ACE_Utils::truncate_cast (this->tv_.tv_sec); + me->ext_tv_.tv_usec = ACE_Utils::truncate_cast (this->tv_.tv_usec); + return this->ext_tv_; +#else + return this->tv_; +#endif /* ACE_HAS_TIME_T_LONG_MISMATCH */ +} + +ACE_INLINE void +ACE_Time_Value::set (const timeval &tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::set"); + this->tv_.tv_sec = tv.tv_sec; + this->tv_.tv_usec = tv.tv_usec; + + this->normalize (); +} + +ACE_INLINE +ACE_Time_Value::ACE_Time_Value (const struct timeval &tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (tv); +} + +ACE_INLINE +ACE_Time_Value::operator const timeval * () const +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator const timeval *"); +#if defined (ACE_HAS_TIME_T_LONG_MISMATCH) + // Recall that on some Windows we substitute another type for timeval in tv_ + ACE_Time_Value *me = const_cast (this); + me->ext_tv_.tv_sec = ACE_Utils::truncate_cast (this->tv_.tv_sec); + me->ext_tv_.tv_usec = ACE_Utils::truncate_cast (this->tv_.tv_usec); + return (const timeval *) &this->ext_tv_; +#else + return (const timeval *) &this->tv_; +#endif /* ACE_HAS_TIME_T_LONG_MISMATCH */ +} + +ACE_INLINE void +ACE_Time_Value::set (time_t sec, suseconds_t usec) +{ + // ACE_OS_TRACE ("ACE_Time_Value::set"); + this->tv_.tv_sec = sec; + this->tv_.tv_usec = usec; +#if __GNUC__ + if (__builtin_constant_p(sec) && + __builtin_constant_p(usec) && + (sec >= 0 && usec >= 0 && usec < ACE_ONE_SECOND_IN_USECS)) + return; +#endif + this->normalize (); +} + +ACE_INLINE void +ACE_Time_Value::set (double d) +{ + // ACE_OS_TRACE ("ACE_Time_Value::set"); + long l = (long) d; + this->tv_.tv_sec = l; + this->tv_.tv_usec = (suseconds_t) ((d - (double) l) * ACE_ONE_SECOND_IN_USECS + .5); + this->normalize (); +} + +// Initializes a timespec_t. Note that this approach loses precision +// since it converts the nano-seconds into micro-seconds. But then +// again, do any real systems have nano-second timer precision?! + +ACE_INLINE void +ACE_Time_Value::set (const timespec_t &tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::set"); + + this->set (tv.tv_sec, + tv.tv_nsec / 1000); // Convert nanoseconds into microseconds. +} + +ACE_INLINE +ACE_Time_Value::ACE_Time_Value (void) + // : tv_ () +{ + // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (0, 0); +} + +ACE_INLINE +ACE_Time_Value::ACE_Time_Value (time_t sec, suseconds_t usec) +{ + // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (sec, usec); +} + +// Returns number of seconds. + +ACE_INLINE time_t +ACE_Time_Value::sec (void) const +{ + // ACE_OS_TRACE ("ACE_Time_Value::sec"); + return this->tv_.tv_sec; +} + +// Sets the number of seconds. + +ACE_INLINE void +ACE_Time_Value::sec (time_t sec) +{ + // ACE_OS_TRACE ("ACE_Time_Value::sec"); + this->tv_.tv_sec = ACE_Utils::truncate_cast (sec); +} + +// Converts from Time_Value format into milli-seconds format. + +ACE_INLINE unsigned long +ACE_Time_Value::msec (void) const +{ + // ACE_OS_TRACE ("ACE_Time_Value::msec"); + + // Note - we're truncating a value here, which can lose data. This is + // called out in the user documentation for this with a recommendation to + // use msec(ACE_UINT64&) instead, so just go ahead and truncate. + time_t secs = this->tv_.tv_sec * 1000 + this->tv_.tv_usec / 1000; + return ACE_Utils::truncate_cast (secs); +} + +ACE_INLINE void +ACE_Time_Value::msec (ACE_UINT64 &ms) const +{ + // ACE_OS_TRACE ("ACE_Time_Value::msec"); + ms = ACE_Utils::truncate_cast (this->tv_.tv_sec); + ms *= 1000; + ms += (this->tv_.tv_usec / 1000); +} + +ACE_INLINE void +ACE_Time_Value::msec (ACE_UINT64 &ms) /*const*/ +{ + // ACE_OS_TRACE ("ACE_Time_Value::msec"); + const ACE_Time_Value *tv = this; + tv->msec (ms); +} + +// Converts from milli-seconds format into Time_Value format. + +ACE_INLINE void +ACE_Time_Value::msec (long milliseconds) +{ + // ACE_OS_TRACE ("ACE_Time_Value::msec"); + // Convert millisecond units to seconds; + long secs = milliseconds / 1000; + this->tv_.tv_sec = secs; + // Convert remainder to microseconds; + this->tv_.tv_usec = (milliseconds - (secs * 1000)) * 1000; +} + +// Converts from milli-seconds format into Time_Value format. + +ACE_INLINE void +ACE_Time_Value::msec (int milliseconds) +{ + ACE_Time_Value::msec (static_cast (milliseconds)); +} + +// Returns number of micro-seconds. + +ACE_INLINE suseconds_t +ACE_Time_Value::usec (void) const +{ + // ACE_OS_TRACE ("ACE_Time_Value::usec"); + return this->tv_.tv_usec; +} + +// Sets the number of micro-seconds. + +ACE_INLINE void +ACE_Time_Value::usec (suseconds_t usec) +{ + // ACE_OS_TRACE ("ACE_Time_Value::usec"); + this->tv_.tv_usec = usec; +} + +ACE_INLINE void +ACE_Time_Value::to_usec (ACE_UINT64 & usec) const +{ + // ACE_OS_TRACE ("ACE_Time_Value::to_usec"); + +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + usec = ACE_U_LongLong (static_cast (this->tv_.tv_sec)); +#elif defined (ACE_LACKS_LONGLONG_T) + // No native 64-bit type, meaning time_t is most likely 32 bits. + usec = ACE_U_LongLong (this->tv_.tv_sec); +#else + usec = static_cast (this->tv_.tv_sec); +#endif /* ACE_LACKS_LONG_LONG_T */ + usec *= 1000000; + usec += this->tv_.tv_usec; +} + +ACE_INLINE ACE_Time_Value +operator * (double d, const ACE_Time_Value &tv) +{ + return ACE_Time_Value (tv) *= d; +} + +ACE_INLINE ACE_Time_Value +operator * (const ACE_Time_Value &tv, double d) +{ + return ACE_Time_Value (tv) *= d; +} + +// True if tv1 > tv2. + +ACE_INLINE bool +operator > (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator >"); + if (tv1.sec () > tv2.sec ()) + return 1; + else if (tv1.sec () == tv2.sec () + && tv1.usec () > tv2.usec ()) + return 1; + else + return 0; +} + +// True if tv1 >= tv2. + +ACE_INLINE bool +operator >= (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator >="); + if (tv1.sec () > tv2.sec ()) + return 1; + else if (tv1.sec () == tv2.sec () + && tv1.usec () >= tv2.usec ()) + return 1; + else + return 0; +} + +// Returns the value of the object as a timespec_t. + +ACE_INLINE +ACE_Time_Value::operator timespec_t () const +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator timespec_t"); + timespec_t tv; + tv.tv_sec = this->sec (); + // Convert microseconds into nanoseconds. + tv.tv_nsec = this->tv_.tv_usec * 1000; + return tv; +} + +// Initializes the ACE_Time_Value object from a timespec_t. + +ACE_INLINE +ACE_Time_Value::ACE_Time_Value (const timespec_t &tv) + // : tv_ () +{ + // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (tv); +} + +// True if tv1 < tv2. + +ACE_INLINE bool +operator < (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator <"); + return tv2 > tv1; +} + +// True if tv1 >= tv2. + +ACE_INLINE bool +operator <= (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator <="); + return tv2 >= tv1; +} + +// True if tv1 == tv2. + +ACE_INLINE bool +operator == (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator =="); + return tv1.sec () == tv2.sec () + && tv1.usec () == tv2.usec (); +} + +// True if tv1 != tv2. + +ACE_INLINE bool +operator != (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator !="); + return !(tv1 == tv2); +} + +// Add TV to this. + +ACE_INLINE ACE_Time_Value & +ACE_Time_Value::operator+= (const ACE_Time_Value &tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator+="); + this->sec (this->sec () + tv.sec ()); + this->usec (this->usec () + tv.usec ()); + this->normalize (); + return *this; +} + +ACE_INLINE ACE_Time_Value & +ACE_Time_Value::operator+= (time_t tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator+="); + this->sec (this->sec () + tv); + return *this; +} + +ACE_INLINE ACE_Time_Value & +ACE_Time_Value::operator= (const ACE_Time_Value &tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator="); + this->sec (tv.sec ()); + this->usec (tv.usec ()); + return *this; +} + +ACE_INLINE ACE_Time_Value & +ACE_Time_Value::operator= (time_t tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator="); + this->sec (tv); + this->usec (0); + return *this; +} + +// Subtract TV to this. + +ACE_INLINE ACE_Time_Value & +ACE_Time_Value::operator-= (const ACE_Time_Value &tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator-="); + this->sec (this->sec () - tv.sec ()); + this->usec (this->usec () - tv.usec ()); + this->normalize (); + return *this; +} + +ACE_INLINE ACE_Time_Value & +ACE_Time_Value::operator-= (time_t tv) +{ + // ACE_OS_TRACE ("ACE_Time_Value::operator-="); + this->sec (this->sec () - tv); + return *this; +} + +// Adds two ACE_Time_Value objects together, returns the sum. + +ACE_INLINE ACE_Time_Value +operator + (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator +"); + ACE_Time_Value sum (tv1); + sum += tv2; + + return sum; +} + +// Subtracts two ACE_Time_Value objects, returns the difference. + +ACE_INLINE ACE_Time_Value +operator - (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + // ACE_OS_TRACE ("operator -"); + ACE_Time_Value delta (tv1); + delta -= tv2; + + return delta; +} + +#if defined (ACE_WIN32) && defined (_WIN32_WCE) +} +#endif + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Timeprobe.cpp b/dep/ACE_wrappers/ace/Timeprobe.cpp new file mode 100644 index 000000000..1fe8459ed --- /dev/null +++ b/dep/ACE_wrappers/ace/Timeprobe.cpp @@ -0,0 +1,15 @@ +// $Id: Timeprobe.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/config-all.h" + +ACE_RCSID(ace, Timeprobe, "$Id: Timeprobe.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_COMPILE_TIMEPROBES) + +#include "ace/Timeprobe.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Timeprobe.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_COMPILE_TIMEPROBES */ diff --git a/dep/ACE_wrappers/ace/Timeprobe.h b/dep/ACE_wrappers/ace/Timeprobe.h new file mode 100644 index 000000000..ac2abe38d --- /dev/null +++ b/dep/ACE_wrappers/ace/Timeprobe.h @@ -0,0 +1,201 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timeprobe.h + * + * $Id: Timeprobe.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali + * + * If users want to use time probes, the ACE_COMPILE_TIMEPROBES + * flag must be defined when compiling ACE. This can be achieved + * by doing one of the following: + * + * . Use make probe = 1, if you are using the make utility. + * + * . Define ACE_COMPILE_TIMEPROBES in config.h + * + * . Define ACE_COMPILE_TIMEPROBES in the VC project file. + * + * . Other regular methods will also work. + * + * It is not necessary to define ACE_COMPILE_TIMEPROBES when using + * time probes, you simply need ACE_ENABLE_TIMEPROBES. You can use + * the ACE_TIMEPROBE_* macros to program the time probes, and use + * the ACE_ENABLE_TIMEPROBE to enable the time probes. If you + * define ACE_ENABLE_TIMEPROBE in your code, but forget to compile + * ACE with ACE_COMPILE_TIMEPROBES, you will end up with linker + * errors. + * + * Remember that ACE_COMPILE_TIMEPROBES means that the ACE library + * will contain code for time probes. This is only useful when + * compiling ACE. ACE_ENABLE_TIMEPROBES means that the + * ACE_TIMEPROBE_* macros should spring to life. + */ +//============================================================================= + +#ifndef ACE_TIMEPROBE_H +#define ACE_TIMEPROBE_H +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" +#include /**/ "ace/ACE_export.h" +#include "ace/Malloc_Allocator.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/* Enable ACE Timeprobes */ +#if defined (ACE_ENABLE_TIMEPROBES) + #if !defined (ACE_COMPILE_TIMEPROBES) + #define ACE_COMPILE_TIMEPROBES + #endif /* ACE_COMPILE_TIMEPROBES */ +#endif /* ACE_ENABLE_TIMEPROBES */ + +#if defined (ACE_COMPILE_TIMEPROBES) + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_Thread.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Event_Descriptions + * + * @brief Event Descriptions. + */ +class ACE_Export ACE_Event_Descriptions +{ +public: + /// Event descriptions + const char **descriptions_; + + /// Minimum id of this description set + u_long minimum_id_; + + /// Comparison + bool operator== (const ACE_Event_Descriptions &rhs) const; +}; + +/** + * @class ACE_timeprobe_t + * + * @brief Time probe record. + */ +class ACE_Export ACE_timeprobe_t +{ +public: + /// Events are record as strings or numbers. + union event + { + u_long event_number_; + const char *event_description_; + }; + + /// Type of event. + enum event_type + { + NUMBER, + STRING + }; + + /// Event. + event event_; + + /// Type of event. + event_type event_type_; + + /// Timestamp. + ACE_hrtime_t time_; + + /// Id of thread posting the time probe. + ACE_thread_t thread_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Timeprobe.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Synch_Traits.h" +#include "ace/Null_Mutex.h" +#include "ace/Singleton.h" +#include "ace/Timeprobe_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// If ACE_MT_TIMEPROBES is defined, use a Thread_Mutex to lock the +// internal state of ACE_Timerprobe. This allows multiple threads to +// use the same ACE_Timerprobe. +# if defined (ACE_MT_TIMEPROBES) +typedef ACE_SYNCH_MUTEX ACE_TIMEPROBE_MUTEX; +# else /* ACE_MT_TIMEPROBES */ +typedef ACE_SYNCH_NULL_MUTEX ACE_TIMEPROBE_MUTEX; +# endif /* ACE_MT_TIMEPROBES */ + +typedef ACE_New_Allocator ACE_TIMEPROBE_ALLOCATOR; + +typedef ACE_Timeprobe_Ex + ACE_TIMEPROBE_WITH_LOCKING; + +// If ACE_TSS_TIMEPROBES is defined, store the ACE_Timeprobe singleton +// in thread specific storage. This allows multiple threads to use +// their own instance of ACE_Timerprobe, without interfering with each +// other. + +# if defined (ACE_TSS_TIMEPROBES) +# define ACE_TIMEPROBE_SINGLETON_TYPE ACE_TSS_Singleton +# define ACE_TIMEPROBE_SINGLETON_LOCK_TYPE ACE_SYNCH_NULL_MUTEX +# else /* ACE_TSS_TIMEPROBES */ +# define ACE_TIMEPROBE_SINGLETON_TYPE ACE_Singleton +# define ACE_TIMEPROBE_SINGLETON_LOCK_TYPE ACE_SYNCH_MUTEX +# endif /* ACE_TSS_TIMEPROBES */ + +ACE_SINGLETON_DECLARE (ACE_TIMEPROBE_SINGLETON_TYPE, \ + ACE_TIMEPROBE_WITH_LOCKING, \ + ACE_TIMEPROBE_SINGLETON_LOCK_TYPE) + +typedef ACE_TIMEPROBE_SINGLETON_TYPE + ACE_TIMEPROBE_SINGLETON; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_COMPILE_TIMEPROBES */ + +// If ACE_ENABLE_TIMEPROBES is defined, the macros below will +// work. Otherwise, they just vanish. Using this macro, you can +// control which files/libraries are probed. +#if defined (ACE_ENABLE_TIMEPROBES) && defined (ACE_COMPILE_TIMEPROBES) + +# define ACE_TIMEPROBE_RESET ACE_TIMEPROBE_SINGLETON::instance ()->reset () + +# define ACE_TIMEPROBE(id) ACE_TIMEPROBE_SINGLETON::instance ()->timeprobe (id) + +# define ACE_TIMEPROBE_PRINT ACE_TIMEPROBE_SINGLETON::instance ()->print_times () + +# define ACE_TIMEPROBE_PRINT_ABSOLUTE ACE_TIMEPROBE_SINGLETON::instance ()->print_absolute_times () + +# define ACE_TIMEPROBE_EVENT_DESCRIPTIONS(descriptions, minimum_id) \ +static int ace_timeprobe_##descriptions##_return = \ + ACE_TIMEPROBE_SINGLETON::instance ()->event_descriptions \ + (descriptions, minimum_id) + +# define ACE_FUNCTION_TIMEPROBE(X) \ + ACE_Function_Timeprobe function_timeprobe \ + (*ACE_TIMEPROBE_SINGLETON::instance (), X) + +#else /* ACE_ENABLE_TIMEPROBES && ACE_COMPILE_TIMEPROBES */ + +# define ACE_TIMEPROBE_RESET +# define ACE_TIMEPROBE(id) +# define ACE_TIMEPROBE_PRINT +# define ACE_TIMEPROBE_PRINT_ABSOLUTE +# define ACE_TIMEPROBE_EVENT_DESCRIPTIONS(descriptions, minimum_id) +# define ACE_FUNCTION_TIMEPROBE(X) + +#endif /* ACE_ENABLE_TIMEPROBES && ACE_COMPILE_TIMEPROBES */ +#include /**/ "ace/post.h" +#endif /* ACE_TIMEPROBE_H */ diff --git a/dep/ACE_wrappers/ace/Timeprobe.inl b/dep/ACE_wrappers/ace/Timeprobe.inl new file mode 100644 index 000000000..aa7a92406 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timeprobe.inl @@ -0,0 +1,14 @@ +// -*- C++ -*- +// +// $Id: Timeprobe.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE bool +ACE_Event_Descriptions::operator== (const ACE_Event_Descriptions &rhs) const +{ + return this->minimum_id_ == rhs.minimum_id_ && + this->descriptions_ == rhs.descriptions_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Timeprobe_T.cpp b/dep/ACE_wrappers/ace/Timeprobe_T.cpp new file mode 100644 index 000000000..d23b7b8b8 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timeprobe_T.cpp @@ -0,0 +1,427 @@ +// $Id: Timeprobe_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMEPROBE_T_CPP +#define ACE_TIMEPROBE_T_CPP + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_COMPILE_TIMEPROBES) + +#include "ace/Timeprobe.h" +#include "ace/High_Res_Timer.h" +#include "ace/OS_NS_string.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +ACE_Timeprobe_Ex::ACE_Timeprobe_Ex (u_long size) + : timeprobes_ (0), + lock_ (), + max_size_ (size), + current_size_ (0), + report_buffer_full_ (0), + allocator_ (0) +{ + ACE_timeprobe_t *temp; + //FUZZ: disable check_for_lack_ACE_OS + ACE_NEW_MALLOC_ARRAY (temp, + (ACE_timeprobe_t *) this->allocator ()-> + malloc (this->max_size_*sizeof(ACE_timeprobe_t)), + ACE_timeprobe_t, + this->max_size_); + //FUZZ: enable check_for_lack_ACE_OS + this->timeprobes_ = temp; + +} + +template +ACE_Timeprobe_Ex:: +ACE_Timeprobe_Ex (ALLOCATOR *allocator, + u_long size) + : timeprobes_ (0), + lock_ (), + max_size_ (size), + current_size_ (0), + report_buffer_full_ (0), + allocator_ (allocator) +{ + ACE_timeprobe_t *temp = 0; + //FUZZ: disable check_for_lack_ACE_OS + ACE_NEW_MALLOC_ARRAY (temp, + (ACE_timeprobe_t *) this->allocator ()-> + malloc (this->max_size_*sizeof(ACE_timeprobe_t)), + ACE_timeprobe_t, + this->max_size_); + //FUZZ: enable check_for_lack_ACE_OS + this->timeprobes_ = temp; + +} + +template +ACE_Timeprobe_Ex::ACE_Timeprobe_Ex (const ACE_Timeprobe_Ex &) +{ + // + // Stupid MSVC is forcing me to define this; please don't use it. + // + + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_NOTSUP: %N, line %l\n"))); + errno = ENOTSUP; +} + +template +ACE_Timeprobe_Ex::~ACE_Timeprobe_Ex (void) +{ + ACE_DES_ARRAY_FREE ((ACE_timeprobe_t *) (this->timeprobes_), + this->max_size_, + this->allocator ()->free, + ACE_timeprobe_t); +} + +template void +ACE_Timeprobe_Ex::timeprobe (u_long event) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + this->timeprobes_[this->current_size_].event_.event_number_ = event; + this->timeprobes_[this->current_size_].event_type_ = ACE_timeprobe_t::NUMBER; + this->timeprobes_[this->current_size_].time_ = ACE_OS::gethrtime (); + this->timeprobes_[this->current_size_].thread_ = ACE_OS::thr_self (); + + ++this->current_size_; + +#if !defined (ACE_TIMEPROBE_ASSERTS_FIXED_SIZE) + // wrap around to the beginning on overflow + if (this->current_size_ >= this->max_size_) + { + this->current_size_ = 0; + this->report_buffer_full_ = 1; + } +#endif /* ACE_TIMEPROBE_ASSERTS_FIXED_SIZE */ + + ACE_ASSERT (this->current_size_ < this->max_size_); +} + +template void +ACE_Timeprobe_Ex::timeprobe (const char *event) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + this->timeprobes_[this->current_size_].event_.event_description_ = event; + this->timeprobes_[this->current_size_].event_type_ = ACE_timeprobe_t::STRING; + this->timeprobes_[this->current_size_].time_ = ACE_OS::gethrtime (); + this->timeprobes_[this->current_size_].thread_ = ACE_OS::thr_self (); + + ++this->current_size_; + +#if !defined (ACE_TIMEPROBE_ASSERTS_FIXED_SIZE) + // wrap around to the beginning on overflow + if (this->current_size_ >= this->max_size_) + { + this->current_size_ = 0; + this->report_buffer_full_ = 1; + } +#endif /* ACE_TIMEPROBE_ASSERTS_FIXED_SIZE */ + + ACE_ASSERT (this->current_size_ < this->max_size_); +} + +template void +ACE_Timeprobe_Ex::reset (void) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + this->current_size_ = 0; + this->report_buffer_full_ = 0; +} + +template void +ACE_Timeprobe_Ex::increase_size (u_long size) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + if (size > this->max_size_) + { + ACE_timeprobe_t *temp = 0; + //FUZZ: disable check_for_lack_ACE_OS + ACE_NEW_MALLOC_ARRAY (temp, + (ACE_timeprobe_t *) this->allocator ()-> + malloc (this->max_size_ + * sizeof (ACE_timeprobe_t)), + ACE_timeprobe_t, + size); + //FUZZ: enable check_for_lack_ACE_OS + + if (this->max_size_ > 0) + { + ACE_OS::memcpy (temp, + this->timeprobes_, + this->max_size_ * sizeof (ACE_timeprobe_t)); + + // Iterates over the array explicitly calling the destructor for + // each probe instance, then deallocates the memory + + ACE_DES_ARRAY_FREE ((ACE_timeprobe_t *)(this->timeprobes_), + this->max_size_, + this->allocator ()->free, + ACE_timeprobe_t); + } + this->timeprobes_ = temp; + this->max_size_ = size; + } +} + +template ACE_Unbounded_Set & +ACE_Timeprobe_Ex::event_descriptions (void) +{ + return this->event_descriptions_; +} + +template ACE_Unbounded_Set & +ACE_Timeprobe_Ex::sorted_event_descriptions (void) +{ + return this->sorted_event_descriptions_; +} + +template ACE_timeprobe_t * +ACE_Timeprobe_Ex::timeprobes (void) +{ + return this->timeprobes_; +} + +template ACE_LOCK & +ACE_Timeprobe_Ex::lock (void) +{ + return this->lock_; +} + +template u_long +ACE_Timeprobe_Ex::max_size (void) +{ + return this->max_size_; +} + +template u_long +ACE_Timeprobe_Ex::current_size (void) +{ + return this->current_size_; +} + +template int +ACE_Timeprobe_Ex::event_descriptions (const char **descriptions, + u_long minimum_id) +{ + ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); + + ACE_Event_Descriptions events; + events.descriptions_ = descriptions; + events.minimum_id_ = minimum_id; + + this->event_descriptions_.insert (events); + + return 0; +} + +template void +ACE_Timeprobe_Ex::print_times (void) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + // Sort the event descriptions + this->sort_event_descriptions_i (); + + u_long size = this->report_buffer_full_ ? this->max_size_ + : this->current_size_; + + ACE_DEBUG ((LM_DEBUG, + "\nACE_Timeprobe_Ex; %u timestamps were recorded:\n", + size)); + + if (size == 0) + return; + + ACE_DEBUG ((LM_DEBUG, + "\n%-50.50s %8.8s %13.13s\n\n", + "Event", + "thread", + "usec")); + + double gsf = ACE_High_Res_Timer::global_scale_factor (); + u_long i, j; + + // First element + i = this->report_buffer_full_ ? this->current_size_ : 0; + + ACE_DEBUG ((LM_DEBUG, + "%-50.50s %8.8x %13.13s\n", + this->find_description_i (i), + this->timeprobes_[i].thread_, + "START")); + + if (size == 1) + return; + + bool has_timestamp_inversion = false; + + j = i; + i = (i + 1) % this->max_size_; + + do + { + // When reusing the same ACE_Timeprobe from multiple threads + // with Linux on Intel SMP, it sometimes happens that the + // recorded times go backward in time if they are recorded from + // different threads (see bugzilla #2342). To obtain the + // correct signed difference between consecutive recorded times, + // one has to cast the time difference to an intermediate signed + // integral type of the same size as ACE_hrtime_t. + + double time_difference = + (ACE_INT64) (this->timeprobes_[i].time_ - this->timeprobes_[j].time_); + + if (time_difference < 0) + has_timestamp_inversion = true; + + // Convert to microseconds. + time_difference /= gsf; + + ACE_DEBUG ((LM_DEBUG, + "%-50.50s %8.8x %14.3f\n", + this->find_description_i (i), + this->timeprobes_[i].thread_, + time_difference)); + + j = i; + i = (i + 1) % this->max_size_; + } + while (i != this->current_size_); + + static bool inversion_warning_printed = false; + if (!inversion_warning_printed && has_timestamp_inversion) + { + inversion_warning_printed = true; + ACE_DEBUG ((LM_DEBUG, + "\nWARNING: The timestamps recorded by gethrtime() on" + " this platform are\n" + "not monotonic across different threads.\n")); + } +} + +template void +ACE_Timeprobe_Ex::print_absolute_times (void) +{ + ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); + + // Sort the event descriptions + this->sort_event_descriptions_i (); + + u_long size = this->report_buffer_full_ ? this->max_size_ + : this->current_size_; + + ACE_DEBUG ((LM_DEBUG, + "\nACE_Timeprobe_Ex; %u timestamps were recorded:\n", + size)); + + if (size == 0) + return; + + ACE_DEBUG ((LM_DEBUG, + "\n%-50.50s %8.8s %13.13s\n\n", + "Event", + "thread", + "stamp")); + + u_long i = this->report_buffer_full_ ? this->current_size_ : 0; + + ACE_Time_Value tv; // to convert ACE_hrtime_t + do + { + ACE_High_Res_Timer::hrtime_to_tv (tv, this->timeprobes_ [i].time_); + + ACE_DEBUG ((LM_DEBUG, + "%-50.50s %8.8x %12.12u\n", + this->find_description_i (i), + this->timeprobes_ [i].thread_, + tv.sec () * 1000000 + + tv.usec ())); + + // Modulus increment: loops around at the end. + i = (i + 1) % this->max_size_; + } + while (i != this->current_size_); +} + +template const char * +ACE_Timeprobe_Ex::find_description_i (u_long i) +{ + if (this->timeprobes_[i].event_type_ == ACE_timeprobe_t::STRING) + return this->timeprobes_[i].event_.event_description_; + else + { + EVENT_DESCRIPTIONS::iterator iterator = this->sorted_event_descriptions_.begin (); + for (u_long j = 0; + j < this->sorted_event_descriptions_.size () - 1; + iterator++, j++) + { + EVENT_DESCRIPTIONS::iterator next_event_descriptions = iterator; + ++next_event_descriptions; + + if (this->timeprobes_[i].event_.event_number_ < (*next_event_descriptions).minimum_id_) + break; + } + return (*iterator).descriptions_[this->timeprobes_[i].event_.event_number_ - (*iterator).minimum_id_]; + } +} + +template void +ACE_Timeprobe_Ex::sort_event_descriptions_i (void) +{ + size_t total_elements = this->event_descriptions_.size (); + + for (size_t i = 0; + i < total_elements; + i++) + { + EVENT_DESCRIPTIONS::iterator iterator = this->event_descriptions_.begin (); + ACE_Event_Descriptions min_entry = *iterator; + + for (; + iterator != this->event_descriptions_.end (); + iterator++) + if ((*iterator).minimum_id_ < min_entry.minimum_id_) + min_entry = *iterator; + + this->sorted_event_descriptions_.insert (min_entry); + this->event_descriptions_.remove (min_entry); + } +} + +template ALLOCATOR * +ACE_Timeprobe_Ex::allocator (void) +{ + return allocator_ ? allocator_ : ACE_Singleton::instance (); +} + +template +ACE_Function_Timeprobe::ACE_Function_Timeprobe (Timeprobe &timeprobe, + u_long event) + : timeprobe_ (timeprobe), + event_ (event) +{ + this->timeprobe_.timeprobe (this->event_); +} + +template +ACE_Function_Timeprobe::~ACE_Function_Timeprobe (void) +{ + this->timeprobe_.timeprobe (this->event_ + 1); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_COMPILE_TIMEPROBES */ +#endif /* ACE_TIMEPROBE_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Timeprobe_T.h b/dep/ACE_wrappers/ace/Timeprobe_T.h new file mode 100644 index 000000000..54e5ff4c1 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timeprobe_T.h @@ -0,0 +1,220 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timeprobe_T.h + * + * $Id: Timeprobe_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali + */ +//============================================================================= + + +#ifndef ACE_TIMEPROBE_T_H +#define ACE_TIMEPROBE_T_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_COMPILE_TIMEPROBES) + +#include "ace/Unbounded_Set.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Timeprobe_Ex + * + * @brief This class is used to instrument code. This is accomplished + * by inserting time probes at different location in the code. + * ACE_Timeprobe then measures the time difference between two + * time probes. + * + * This class provides a lightweight implementation for + * measuring the time required to execute code between two time + * probes. When a time probe executes, it records the time, the + * id of the calling thread, and an event description. The + * event description can either be an unsigned long or a string + * (char *). If string are used, care must be taken cause only + * pointer copies are done and the string data is *not* copied. + * The recorded time probes can then be printed by calling + * . If you have used unsigned longs as event + * descriptions in any of your time probes, you must have + * provided an event description table that maps the unsigned + * longs to readable strings. This map is a simple array of + * strings, and the event number is used as the index into the + * array when looking for the event description. If you have + * only used strings for the event description, this map is not + * necessary. + * Multiple maps can also be used to chunk up the time probes. + * Each one can be added by calling . + * Different tables are used internally by consulting the + * minimum_id for each table. It is up to the user to make sure + * that multiple tables do not share the same event id range. + */ +template +class ACE_Timeprobe_Ex +{ +public: + + /// Self + typedef ACE_Timeprobe_Ex + SELF; + + /** + * ACE_Timeprobe + */ + typedef ACE_Timeprobe_Ex ACE_Timeprobe; + + + /// We can hold multiple event description tables. + typedef ACE_Unbounded_Set + EVENT_DESCRIPTIONS; + + /// Create Timeprobes with @a size slots + ACE_Timeprobe_Ex (u_long size = ACE_DEFAULT_TIMEPROBE_TABLE_SIZE); + + /// Create Timeprobes with @a size slots + ACE_Timeprobe_Ex (ALLOCATOR *allocator, + u_long size = ACE_DEFAULT_TIMEPROBE_TABLE_SIZE); + /// Destructor. + ~ACE_Timeprobe_Ex (void); + + /// Record a time. @a event is used to describe this time probe. + void timeprobe (u_long event); + + /// Record a time. @a id is used to describe this time probe. + void timeprobe (const char *id); + + /// Record event descriptions. + int event_descriptions (const char **descriptions, + u_long minimum_id); + + /// Print the time probes. + void print_times (void); + + /// Print the time probes. + void print_absolute_times (void); + + /// Reset the slots. All old time probes will be lost. + void reset (void); + + void increase_size (u_long size); + + /// Not implemented (stupid MSVC won't let it be protected). + ACE_Timeprobe_Ex (const ACE_Timeprobe_Ex &); + + // = (Somewhat private) Accessors + + /// Event Descriptions + ACE_Unbounded_Set &event_descriptions (void); + + /// Sorted Event Descriptions. + ACE_Unbounded_Set &sorted_event_descriptions (void); + + /// Find description of event @a i + const char *find_description_i (u_long i); + + /// Sort event descriptions + void sort_event_descriptions_i (void); + + /// Time probe slots + ACE_timeprobe_t *timeprobes (void); + + /// Synchronization variable. + ACE_LOCK &lock (void); + + /// Max size of timestamp table + u_long max_size (void); + + /// Current size of timestamp table + u_long current_size (void); + +protected: + + /// Obtain an allocator pointer. If there is no allocator stored in + /// the instance, the singleton allocator in the current process is used. + ALLOCATOR * allocator (void); + + /// Event Descriptions + EVENT_DESCRIPTIONS event_descriptions_; + + /// Sorted Event Descriptions. + EVENT_DESCRIPTIONS sorted_event_descriptions_; + + /// Time probe slots + ACE_timeprobe_t *timeprobes_; + + /// Synchronization variable. + ACE_LOCK lock_; + + /// Max size of timestamp table + u_long max_size_; + + /// Current size of timestamp table + u_long current_size_; + + /// Flag indicating the report buffer has filled up, and is now + /// acting as a ring-buffer using modulus arithmetic: this saves the + /// max_size_ most recent time stamps and loses earlier ones until + /// drained. + u_short report_buffer_full_; + +private: + ALLOCATOR * allocator_; +}; + +// template +// class ACE_Timeprobe : public ACE_Timeprobe_Ex +// { +// public: +// // Initialize a ACE_Timeprobe with default size +// ACE_Timeprobe (ACE_Allocator *allocator = ACE_Allocator::instance()); + +// /// Create Timeprobes with @a size slots +// ACE_Timeprobe (ACE_Allocator *allocator = ACE_Allocator::instance(), +// u_long size = ACE_DEFAULT_TIMEPROBE_TABLE_SIZE); +// }; + +/** + * @class ACE_Function_Timeprobe + * + * @brief Auto pointer like time probes. It will record on + * construction and on destruction. + */ +template +class ACE_Function_Timeprobe +{ +public: + /// Constructor. + ACE_Function_Timeprobe (Timeprobe &timeprobe, u_long event); + + /// Destructor. + ~ACE_Function_Timeprobe (void); + +protected: + /// Reference to timeprobe. + Timeprobe &timeprobe_; + + /// Event. + u_long event_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Timeprobe_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Timeprobe_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_COMPILE_TIMEPROBES */ +#include /**/ "ace/post.h" +#endif /* ACE_TIMEPROBE_T_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Hash.h b/dep/ACE_wrappers/ace/Timer_Hash.h new file mode 100644 index 000000000..b381419da --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Hash.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Timer_Hash.h + * + * $Id: Timer_Hash.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Darrell Brunsch + */ +//============================================================================= + + +#ifndef ACE_TIMER_HASH_H +#define ACE_TIMER_HASH_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Hash_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Timer_Heap_T.h" +#include "ace/Timer_List_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The following typedef are here for ease of use + +typedef ACE_Timer_Hash_Upcall , + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Hash_Upcall; + +typedef ACE_Timer_List_T + ACE_Hash_Timer_List; + +typedef ACE_Timer_Heap_T + ACE_Hash_Timer_Heap; + + +typedef ACE_Timer_Hash_T, + ACE_SYNCH_RECURSIVE_MUTEX, + ACE_Hash_Timer_List> + + ACE_Timer_Hash; + +typedef ACE_Timer_Hash_Iterator_T, + ACE_SYNCH_RECURSIVE_MUTEX, + ACE_Hash_Timer_List> + ACE_Timer_Hash_Iterator; + +typedef ACE_Timer_Hash_T, + ACE_SYNCH_RECURSIVE_MUTEX, + ACE_Hash_Timer_Heap> + ACE_Timer_Hash_Heap; + +typedef ACE_Timer_Hash_Iterator_T, + ACE_SYNCH_RECURSIVE_MUTEX, + ACE_Hash_Timer_Heap> + ACE_Timer_Hash_Heap_Iterator; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_HASH_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Hash_T.cpp b/dep/ACE_wrappers/ace/Timer_Hash_T.cpp new file mode 100644 index 000000000..057668063 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Hash_T.cpp @@ -0,0 +1,873 @@ +// $Id: Timer_Hash_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMER_HASH_T_CPP +#define ACE_TIMER_HASH_T_CPP + +#include "ace/Timer_Hash_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_sys_time.h" +#include "ace/Guard_T.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ace, + Timer_Hash_T, + "$Id: Timer_Hash_T.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template +class Hash_Token +{ +public: + // This constructor is required by ACE_Locked_Free_List::alloc. + Hash_Token (void) + {} + + Hash_Token *get_next (void) + { + return this->next_; + } + + void set_next (Hash_Token *next) + { + this->next_ = next; + } + + void set (const void *act, + size_t pos, + long orig_id, + const TYPE &type) + { + this->act_ = act; + this->pos_ = pos; + this->orig_id_ = orig_id; + this->type_ = type; + this->next_ = 0; + } + + const void *act_; + size_t pos_; + long orig_id_; + TYPE type_; + /// Pointer to next token. + Hash_Token *next_; +}; + +// Default constructor + +template +ACE_Timer_Hash_Upcall::ACE_Timer_Hash_Upcall (void) + : timer_hash_ (0) +{ + // Nothing +} + +// Constructor that specifies a Timer_Hash to call up to + +template +ACE_Timer_Hash_Upcall::ACE_Timer_Hash_Upcall ( + ACE_Timer_Queue_T *timer_hash) + : timer_hash_ (timer_hash) +{ + // Nothing +} + +template int +ACE_Timer_Hash_Upcall::registration ( + TIMER_QUEUE &, + ACE_Event_Handler *, + const void *) +{ + // Registration will be handled by the upcall functor of the timer + // hash. + return 0; +} + +template int +ACE_Timer_Hash_Upcall::preinvoke (TIMER_QUEUE &, + ACE_Event_Handler *, + const void *, + int, + const ACE_Time_Value &, + const void *&) +{ + // This method should never be invoked since we don't invoke + // expire() on the buckets. + ACE_ASSERT (0); + return 0; +} + +template int +ACE_Timer_Hash_Upcall::postinvoke ( + TIMER_QUEUE &, + ACE_Event_Handler *, + const void *, + int, + const ACE_Time_Value &, + const void *) +{ + // This method should never be invoked since we don't invoke + // expire() on the buckets. + ACE_ASSERT (0); + return 0; +} + +// Calls up to timer_hash's upcall functor +template int +ACE_Timer_Hash_Upcall::timeout ( + TIMER_QUEUE &, + ACE_Event_Handler *, + const void *, + int, + const ACE_Time_Value &) +{ + // This method should never be invoked since we don't invoke + // expire() on the buckets. + ACE_ASSERT (0); + return 0; +} + +template int +ACE_Timer_Hash_Upcall::cancel_type ( + TIMER_QUEUE &, + ACE_Event_Handler *, + int, + int &) +{ + // Cancellation will be handled by the upcall functor of the timer + // hash. + return 0; +} + +template int +ACE_Timer_Hash_Upcall::cancel_timer ( + TIMER_QUEUE &, + ACE_Event_Handler *, + int, + int) +{ + // Cancellation will be handled by the upcall functor of the timer + // hash. + return 0; +} + +template int +ACE_Timer_Hash_Upcall::deletion ( + TIMER_QUEUE &, + ACE_Event_Handler *event_handler, + const void *arg) +{ + // Call up to the upcall functor of the timer hash since the timer + // hash does not invoke deletion() on its upcall functor directly. + Hash_Token *h = + reinterpret_cast *> (const_cast (arg)); + + int result = + this->timer_hash_->upcall_functor (). + deletion (*this->timer_hash_, + event_handler, + h->act_); + + return result; +} + +template +ACE_Timer_Hash_Iterator_T::ACE_Timer_Hash_Iterator_T (ACE_Timer_Hash_T &hash) + : timer_hash_ (hash) +{ + this->first (); + // Nothing +} + +// Positions the iterator at the first node in the timing hash table + +template void +ACE_Timer_Hash_Iterator_T::first (void) +{ + for (this->position_ = 0; + this->position_ < this->timer_hash_.table_size_; + ++this->position_) + { + // Check for an empty entry + if (!this->timer_hash_.table_[this->position_]->is_empty ()) + { + this->iter_ = &this->timer_hash_.table_[this->position_]->iter (); + this->iter_->first (); + return; + } + } + + // Didn't find any + this->iter_ = 0; +} + +// Positions the iterator at the next node in the bucket or goes to the next +// bucket + +template void +ACE_Timer_Hash_Iterator_T::next (void) +{ + if (this->isdone ()) + return; + + // If there is no more in the current bucket, go to the next + if (this->iter_->isdone ()) + { + for (++this->position_; + this->position_ < this->timer_hash_.table_size_; + ++this->position_) + { + // Check for an empty entry + if (!this->timer_hash_.table_[this->position_]->is_empty ()) + { + this->iter_ = &this->timer_hash_.table_[this->position_]->iter (); + this->iter_->first (); + return; + } + } + + // Didn't find any. + this->iter_ = 0; + } + else + this->iter_->next (); +} + +// Returns true when we are at the end (when bucket_item_ == 0) + +template bool +ACE_Timer_Hash_Iterator_T::isdone (void) const +{ + return this->iter_ == 0; +} + +// Returns the node at the current position in the sequence + +template +ACE_Timer_Node_T * +ACE_Timer_Hash_Iterator_T::item (void) +{ + if (this->isdone ()) + return 0; + + return this->iter_->item (); +} + +template +ACE_Timer_Queue_Iterator_T & +ACE_Timer_Hash_T::iter (void) +{ + this->iterator_->first (); + return *this->iterator_; +} + +// Create an empty queue. + +template +ACE_Timer_Hash_T::ACE_Timer_Hash_T ( + size_t table_size, + FUNCTOR *upcall_functor, + ACE_Free_List > *freelist) + : ACE_Timer_Queue_T (upcall_functor, freelist), + size_ (0), + table_size_ (table_size), + table_functor_ (this), + earliest_position_ (0) +#if defined (ACE_WIN64) + , pointer_base_ (0) +#endif /* ACE_WIN64 */ + , token_list_ () +{ + ACE_TRACE ("ACE_Timer_Hash_T::ACE_Timer_Hash_T"); + + ACE_NEW (table_, + BUCKET *[table_size]); + + this->gettimeofday (ACE_OS::gettimeofday); + + for (size_t i = 0; + i < table_size; + ++i) + { + ACE_NEW (this->table_[i], + BUCKET (&this->table_functor_, + this->free_list_)); + this->table_[i]->gettimeofday (ACE_OS::gettimeofday); + } + + ACE_NEW (iterator_, + HASH_ITERATOR (*this)); +} + + +template +ACE_Timer_Hash_T::ACE_Timer_Hash_T ( + FUNCTOR *upcall_functor, + ACE_Free_List > *freelist) + : ACE_Timer_Queue_T (upcall_functor, freelist), + size_ (0), + table_size_ (ACE_DEFAULT_TIMER_HASH_TABLE_SIZE), + table_functor_ (this), + earliest_position_ (0) +#if defined (ACE_WIN64) + , pointer_base_ (0) +#endif /* ACE_WIN64 */ + , token_list_ () +{ + ACE_TRACE ("ACE_Timer_Hash_T::ACE_Timer_Hash_T"); + + ACE_NEW (table_, + BUCKET *[ACE_DEFAULT_TIMER_HASH_TABLE_SIZE]); + + + this->gettimeofday (ACE_OS::gettimeofday); + + for (size_t i = 0; + i < this->table_size_; + ++i) + { + ACE_NEW (this->table_[i], + BUCKET (&this->table_functor_, + this->free_list_)); + this->table_[i]->gettimeofday (ACE_OS::gettimeofday); + } + + ACE_NEW (iterator_, + HASH_ITERATOR (*this)); +} + +// Remove all remaining items in the Queue. + +template +ACE_Timer_Hash_T::~ACE_Timer_Hash_T (void) +{ + ACE_TRACE ("ACE_Timer_Hash_T::~ACE_Timer_Hash_T"); + ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_)); + + delete iterator_; + + for (size_t i = 0; + i < this->table_size_; + ++i) + delete this->table_[i]; + + delete [] this->table_; +} + +// Checks if queue is empty. + +template bool +ACE_Timer_Hash_T::is_empty (void) const +{ + ACE_TRACE ("ACE_Timer_Hash_T::is_empty"); + return this->table_[this->earliest_position_]->is_empty (); +} + +// Returns earliest time in a non-empty bucket + +template +const ACE_Time_Value & +ACE_Timer_Hash_T::earliest_time (void) const +{ + ACE_TRACE ("ACE_Timer_Hash_T::earliest_time"); + return this->table_[this->earliest_position_]->earliest_time (); +} + +template void +ACE_Timer_Hash_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Timer_Hash_T::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntable_size_ = %d"), this->table_size_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nearliest_position_ = %d"), this->earliest_position_)); + + for (size_t i = 0; i < this->table_size_; ++i) + if (!this->table_[i]->is_empty ()) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nBucket %d contains nodes"), i)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// Reschedule a periodic timer. This function must be called with the +// mutex lock held. + +template +void +ACE_Timer_Hash_T::reschedule ( + ACE_Timer_Node_T *expired) +{ + ACE_TRACE ("ACE_Timer_Hash_T::reschedule"); + + Hash_Token *h = + reinterpret_cast *> ( + const_cast (expired->get_act ())); + + // Don't use ACE_Utils::truncate_cast<> here. A straight + // static_cast<> will provide more unique results when the number + // of seconds is greater than std::numeric_limits::max(). + size_t const secs_hash_input = + static_cast (expired->get_timer_value ().sec ()); + h->pos_ = secs_hash_input % this->table_size_; + + h->orig_id_ = + this->table_[h->pos_]->schedule (expired->get_type (), + h, + expired->get_timer_value (), + expired->get_interval ()); + ACE_ASSERT (h->orig_id_ != -1); + +#if 0 + ACE_DEBUG ((LM_DEBUG, "Hash::reschedule() resets %d in slot %d where it's id is %d and token is %x\n", + expired->get_timer_value ().msec (), + h->pos_, + h->orig_id_, + h)); +#endif + + // Since schedule() above will allocate a new node + // then here schedule for deletion. Don't call + // this->free_node() because that will invalidate + // and that's what user have as timer_id. + ACE_Timer_Queue_T::free_node (expired); + + if (this->table_[this->earliest_position_]->is_empty () + || this->table_[h->pos_]->earliest_time () + < this->table_[this->earliest_position_]->earliest_time ()) + this->earliest_position_ = h->pos_; +} + +// Insert a new handler that expires at time future_time; if interval +// is > 0, the handler will be reinvoked periodically. + +template +long +ACE_Timer_Hash_T::schedule_i ( + const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Timer_Hash_T::schedule_i"); + + // Don't use ACE_Utils::truncate_cast<> here. A straight + // static_cast<> will provide more unique results when the number + // of seconds is greater than std::numeric_limits::max(). + size_t const secs_hash_input = static_cast (future_time.sec ()); + size_t const position = secs_hash_input % this->table_size_; + + // Don't create Hash_Token directly. Instead we get one from Free_List + // and then set it properly. + Hash_Token *h = this->token_list_.remove (); + h->set (act, position, 0, type); + + h->orig_id_ = + this->table_[position]->schedule (type, + h, + future_time, + interval); + ACE_ASSERT (h->orig_id_ != -1); + +#if 0 + ACE_DEBUG ((LM_DEBUG, "Hash::schedule() placing %d in slot %d where it's id is %d and token is %x\n", + future_time.msec (), + position, + h->orig_id_, + h)); +#endif + + if (this->table_[this->earliest_position_]->is_empty () + || this->table_[position]->earliest_time () + < this->table_[this->earliest_position_]->earliest_time ()) + this->earliest_position_ = position; + + ++this->size_; + +#if defined (ACE_WIN64) + // This is a Win64 hack, necessary because of the original (bad) decision + // to use a pointer as the timer ID. This class doesn't follow the usual + // timer expiration rules (see comments in header file) and is probably + // not used much. The dynamic allocation of Hash_Tokens without + // recording them anywhere is a large problem for Win64 since the + // size of a pointer is 64 bits, but a long is 32. Since this class + // is not much used, I'm hacking this, at least for now. If it becomes + // an issue, I'll look at it again then. + intptr_t hi = reinterpret_cast (h); + if (this->pointer_base_ == 0) + this->pointer_base_ = hi & 0xffffffff00000000; + return static_cast (hi & 0xffffffff); +#else + return reinterpret_cast (h); +#endif +} + +// Locate and update the inteval on the timer_id + +template +int +ACE_Timer_Hash_T::reset_interval ( + long timer_id, + const ACE_Time_Value & interval) +{ + ACE_TRACE ("ACE_Timer_Hash_T::reset_interval"); + + // Make sure we are getting a valid , not an error + // returned by . + if (timer_id == -1) + return -1; + +#if defined (ACE_WIN64) + unsigned long const timer_offset = + static_cast (timer_id); + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + Hash_Token * const h = + reinterpret_cast *> (this->pointer_base_ + timer_offset); +#else + Hash_Token * const h = + reinterpret_cast *> (timer_id); + + // Grab the lock before accessing the table. We don't need to do so + // before this point since no members are accessed until now. + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); +#endif /* ACE_WIN64 */ + + return this->table_[h->pos_]->reset_interval (h->orig_id_, + interval); +} + +// Locate and remove the single with a value of +// @a timer_id from the correct table timer queue. + +template +int +ACE_Timer_Hash_T::cancel (long timer_id, + const void **act, + int dont_call) +{ + ACE_TRACE ("ACE_Timer_Hash_T::cancel"); + + // Make sure we are getting a valid , not an error + // returned by . + if (timer_id == -1) + return 0; + +#if defined (ACE_WIN64) + unsigned long const timer_offset = + static_cast (timer_id); + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + Hash_Token * const h = + reinterpret_cast *> (this->pointer_base_ + timer_offset); +#else + Hash_Token * const h = + reinterpret_cast *> (timer_id); + + // Grab the lock before accessing the table. We don't need to do so + // before this point since no members are accessed until now. + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); +#endif /* ACE_WIN64 */ + + int const result = this->table_[h->pos_]->cancel (h->orig_id_, + 0, + dont_call); + + if (result == 1) + { + // Call the close hooks. + int cookie = 0; + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + h->type_, + dont_call, + cookie); + + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + h->type_, + dont_call, + cookie); + + if (h->pos_ == this->earliest_position_) + this->find_new_earliest (); + + if (act != 0) + *act = h->act_; + + // We could destruct Hash_Token explicitly but we better + // schedule it for destruction. In this case next + // token_list_.remove () will use it. + this->token_list_.add (h); + + --this->size_; + } + + return result; +} + +// Locate and remove all values of from the timer queue. + +template +int +ACE_Timer_Hash_T::cancel (const TYPE &type, + int dont_call) +{ + ACE_TRACE ("ACE_Timer_Hash_T::cancel"); + + size_t i; // loop variable. + + Hash_Token **timer_ids = 0; + size_t pos = 0; + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + ACE_NEW_RETURN (timer_ids, + Hash_Token *[this->size_], + -1); + + for (i = 0; + i < this->table_size_; + ++i) + { + ACE_Timer_Queue_Iterator_T, + ACE_Null_Mutex> &iter = + this->table_[i]->iter (); + + for (iter.first (); + !iter.isdone (); + iter.next ()) + if (iter.item ()->get_type () == type) + timer_ids[pos++] = + reinterpret_cast *> ( + const_cast (iter.item ()->get_act ())); + } + + if (pos > this->size_) + return -1; + + for (i = 0; i < pos; ++i) + { + int const result = + this->table_[timer_ids[i]->pos_]->cancel (timer_ids[i]->orig_id_, + 0, + dont_call); + ACE_ASSERT (result == 1); + ACE_UNUSED_ARG (result); + + // We could destruct Hash_Token explicitly but we better + // schedule it for destruction. + this->token_list_.add (timer_ids[i]); + + --this->size_; + } + + delete [] timer_ids; + + this->find_new_earliest (); + + // Call the close hooks. + int cookie = 0; + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + type, + dont_call, + cookie); + + for (i = 0; + i < pos; + ++i) + { + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + type, + dont_call, + cookie); + } + + return static_cast (pos); +} + +// Removes the earliest node and finds the new earliest position + +template ACE_Timer_Node_T * +ACE_Timer_Hash_T::remove_first (void) +{ + if (this->is_empty ()) + return 0; + + ACE_Timer_Node_T *temp = + this->table_[this->earliest_position_]->remove_first (); + + this->find_new_earliest (); + + --this->size_; + + return temp; +} + +// Finds a new earliest position + +template void +ACE_Timer_Hash_T::find_new_earliest (void) +{ + for (size_t i = 0; i < this->table_size_; ++i) + if (!this->table_[i]->is_empty ()) + if (this->table_[this->earliest_position_]->is_empty () + || this->earliest_time () == ACE_Time_Value::zero + || this->table_[i]->earliest_time () <= this->earliest_time ()) + this->earliest_position_ = i; +} + +// Returns the earliest node without removing it + +template ACE_Timer_Node_T * +ACE_Timer_Hash_T::get_first (void) +{ + ACE_TRACE ("ACE_Timer_Hash_T::get_first"); + + if (this->is_empty ()) + return 0; + + return this->table_[this->earliest_position_]->get_first (); +} + +template void +ACE_Timer_Hash_T::free_node (ACE_Timer_Node_T *node) +{ + ACE_Timer_Queue_T::free_node (node); + + Hash_Token *h = + reinterpret_cast *> (const_cast (node->get_act ())); + this->token_list_.add (h); +} + +template int +ACE_Timer_Hash_T::dispatch_info_i (const ACE_Time_Value &cur_time, + ACE_Timer_Node_Dispatch_Info_T &info) +{ + int const result = + ACE_Timer_Queue_T::dispatch_info_i (cur_time, + info); + + if (result == 1) + { + Hash_Token *h = + reinterpret_cast *> (const_cast (info.act_)); + + info.act_ = h->act_; + } + + return result; +} + +// Dummy version of expire to get rid of warnings in Sun CC 4.2 + +template int +ACE_Timer_Hash_T::expire () +{ + return ACE_Timer_Queue_T::expire(); +} + +// Specialized expire for Timer Hash + +template int +ACE_Timer_Hash_T::expire (const ACE_Time_Value &cur_time) +{ + ACE_TRACE ("ACE_Timer_Hash_T::expire"); + + int number_of_timers_expired = 0; + + ACE_Timer_Node_T *expired = 0; + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + // Go through the table and expire anything that can be expired + + for (size_t i = 0; + i < this->table_size_; + ++i) + { + while (!this->table_[i]->is_empty () + && this->table_[i]->earliest_time () <= cur_time) + { + expired = this->table_[i]->remove_first (); + const void *act = expired->get_act (); + bool reclaim = true; + + Hash_Token *h = + reinterpret_cast *> (const_cast (act)); + + ACE_ASSERT (h->pos_ == i); + +#if 0 + ACE_DEBUG ((LM_DEBUG, "Hash::expire() expiring %d in slot %d where it's id is %d and token is %x\n", + expired->get_timer_value ().msec (), + h->pos_, + h->orig_id_, + h)); +#endif + + // Check if this is an interval timer. + if (expired->get_interval () > ACE_Time_Value::zero) + { + // Make sure that we skip past values that have already + // "expired". + do + expired->set_timer_value (expired->get_timer_value () + + expired->get_interval ()); + while (expired->get_timer_value () <= cur_time); + + // Since this is an interval timer, we need to + // reschedule it. + this->reschedule (expired); + reclaim = false; + } + else + { + this->free_node (expired); + } + + ACE_Timer_Node_Dispatch_Info_T info; + + // Get the dispatch info + expired->get_dispatch_info (info); + + info.act_ = h->act_; + + const void *upcall_act = 0; + + this->preinvoke (info, cur_time, upcall_act); + + this->upcall (info, cur_time); + + this->postinvoke (info, cur_time, upcall_act); + + if (reclaim) + { + --this->size_; + } + + ++number_of_timers_expired; + } + } + + if (number_of_timers_expired > 0) + this->find_new_earliest (); + + return number_of_timers_expired; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TIMER_HASH_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Timer_Hash_T.h b/dep/ACE_wrappers/ace/Timer_Hash_T.h new file mode 100644 index 000000000..b04e7cfbc --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Hash_T.h @@ -0,0 +1,342 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Timer_Hash_T.h + * + * $Id: Timer_Hash_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_TIMER_HASH_T_H +#define ACE_TIMER_HASH_T_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Queue_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Free_List.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration. +template +class ACE_Timer_Hash_T; +template +class Hash_Token; + +/** + * @class ACE_Timer_Hash_Upcall + * + * @brief Functor for Timer_Hash + * + * This class calls up to the Timer Hash's functor from the + * timer queues in the hash table + */ +template +class ACE_Timer_Hash_Upcall +{ +public: + typedef ACE_Timer_Queue_T, + ACE_Null_Mutex> + TIMER_QUEUE; + + /// Default constructor (creates an invalid object, but needs to be here + /// so timer queues using this functor can be constructed) + ACE_Timer_Hash_Upcall (void); + + /// Constructor that specifies a Timer_Hash to call up to + ACE_Timer_Hash_Upcall (ACE_Timer_Queue_T *timer_hash); + + /// This method is called when a timer is registered. + int registration (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg); + + /// This method is called before the timer expires. + int preinvoke (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time, + const void *&upcall_act); + + /// This method is called when the timer expires. + int timeout (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time); + + /// This method is called after the timer expires. + int postinvoke (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time, + const void *upcall_act); + + /// This method is called when a handler is cancelled + int cancel_type (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + int dont_call, + int &requires_reference_counting); + + /// This method is called when a timer is cancelled + int cancel_timer (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + int dont_call, + int requires_reference_counting); + + /// This method is called when the timer queue is destroyed and + /// the timer is still contained in it + int deletion (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg); + +private: + /// Timer Queue to do the calling up to + ACE_Timer_Queue_T *timer_hash_; + + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Hash_Upcall (const ACE_Timer_Hash_Upcall &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Hash_Upcall &)) +}; + +/** + * @class ACE_Timer_Hash_Iterator_T + * + * @brief Iterates over an ACE_Timer_Hash_T. + * + * This is a generic iterator that can be used to visit every + * node of a timer queue. Be aware that it doesn't transverse + * in the order of timeout values. + */ +template +class ACE_Timer_Hash_Iterator_T : public ACE_Timer_Queue_Iterator_T +{ +public: + /// Constructor. + ACE_Timer_Hash_Iterator_T (ACE_Timer_Hash_T &); + + /// Positions the iterator at the earliest node in the Timer Queue + virtual void first (void); + + /// Positions the iterator at the next node in the Timer Queue + virtual void next (void); + + /// Returns true when there are no more nodes in the sequence + virtual bool isdone (void) const; + + /// Returns the node at the current position in the sequence + virtual ACE_Timer_Node_T *item (void); + +protected: + /// Pointer to the ACE_Timer_Hash that we are iterating over. + ACE_Timer_Hash_T &timer_hash_; + + /// Current position in 's table + size_t position_; + + /// Current iterator used on 's bucket + ACE_Timer_Queue_Iterator_T, ACE_Null_Mutex> *iter_; +}; + +/** + * @class ACE_Timer_Hash_T + * + * @brief Provides a hash table of BUCKETs as an implementation for + * a timer queue. + * + * This implementation uses a hash table of BUCKETs. The hash + * is based on the time_value of the event. Unlike other Timer + * Queues, ACE_Timer_Hash does not expire events in order. + */ +template +class ACE_Timer_Hash_T : public ACE_Timer_Queue_T +{ +public: + /// Type of iterator + typedef ACE_Timer_Hash_Iterator_T + HASH_ITERATOR; + + /// Iterator is a friend + friend class ACE_Timer_Hash_Iterator_T; + + /// Type inherited from + typedef ACE_Timer_Queue_T INHERITED; + + // = Initialization and termination methods. + /** + * Default constructor. @a table_size determines the size of the + * hash table. @a upcall_functor is the instance of the FUNCTOR + * to be used by the buckets. If @a upcall_functor is 0, a default + * FUNCTOR will be created. + */ + ACE_Timer_Hash_T (size_t table_size, + FUNCTOR *upcall_functor = 0, + ACE_Free_List > *freelist = 0); + + /** + * Default constructor. @a upcall_functor is the instance of the + * FUNCTOR to be used by the queue. If @a upcall_functor is 0, Timer + * Hash will create a default FUNCTOR. @a freelist the freelist of + * timer nodes. If 0, then a default freelist will be created. The default + * size will be ACE_DEFAULT_TIMERS and there will be no preallocation. + */ + ACE_Timer_Hash_T (FUNCTOR *upcall_functor = 0, ACE_Free_List > *freelist = 0); + + /// Destructor + virtual ~ACE_Timer_Hash_T (void); + + /// True if queue is empty, else false. + virtual bool is_empty (void) const; + + /// Returns the time of the earlier node in the . + /// Must be called on a non-empty queue. + virtual const ACE_Time_Value &earliest_time (void) const; + + /** + * Resets the interval of the timer represented by @a timer_id to + * @a interval, which is specified in relative time to the current + * . If @a interval is equal to + * ACE_Time_Value::zero, the timer will become a non-rescheduling + * timer. Returns 0 if successful, -1 if not. + */ + virtual int reset_interval (long timer_id, + const ACE_Time_Value &interval); + + /** + * Cancel all timer associated with @a type. If is 0 + * then the will be invoked. Returns number of timers + * cancelled. If any valid timer is not cancelled before destruction + * of this instance of ACE_Timer_Hash_T then user will get a memory + * leak. + */ + virtual int cancel (const TYPE &type, + int dont_call_handle_close = 1); + + /** + * Cancel the single timer that matches the @a timer_id value (which + * was returned from the method). If act is non-NULL + * then it will be set to point to the ``magic cookie'' argument + * passed in when the timer was registered. This makes it possible + * to free up the memory and avoid memory leaks. If is + * 0 then the will be invoked. Returns 1 if cancellation + * succeeded and 0 if the @a timer_id wasn't found. If any valid + * timer is not cancelled before destruction of this instance of + * ACE_Timer_Hash_T then user will get a memory leak. + */ + virtual int cancel (long timer_id, + const void **act = 0, + int dont_call_handle_close = 1); + + /** + * Run the for all timers whose values are <= + * . Also accounts for . Returns + * the number of timers canceled. + */ + virtual int expire (void); + + /** + * Run the for all timers whose values are <= @a current_time. + * This does not account for . Returns the number of + * timers canceled. + */ + virtual int expire (const ACE_Time_Value ¤t_time); + + /// Returns a pointer to this ACE_Timer_Queue's iterator. + virtual ACE_Timer_Queue_Iterator_T &iter (void); + + /// Removes the earliest node from the queue and returns it + virtual ACE_Timer_Node_T *remove_first (void); + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Reads the earliest node from the queue and returns it. + virtual ACE_Timer_Node_T *get_first (void); + +protected: + /// Factory method that frees a previously allocated node. + virtual void free_node (ACE_Timer_Node_T *); + +private: + + /** + * Schedule @a type that will expire at @a future_time, + * which is specified in absolute time. If it expires then @a act is + * passed in as the value to the . If @a interval is != to + * ACE_Time_Value::zero then it is used to reschedule the @a type + * automatically, using relative time to the current . + * This method returns a that is a pointer to a token + * which stores information about the event. This can be + * used to cancel the timer before it expires. Returns -1 on + * failure. + */ + virtual long schedule_i (const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval); + + /// Non-locking version of dispatch_info () + virtual int dispatch_info_i (const ACE_Time_Value ¤t_time, + ACE_Timer_Node_Dispatch_Info_T &info); + + /// Reschedule an "interval" ACE_Timer_Node. + virtual void reschedule (ACE_Timer_Node_T *); + + /// Finds the earliest node + void find_new_earliest (void); + + /// Keeps track of the size of the queue + size_t size_; + + /// Table of BUCKETS + BUCKET **table_; + + /// Keeps track of the size of table_ + size_t table_size_; + + /// Functor used for the table's timer queues + ACE_Timer_Hash_Upcall table_functor_; + + /// Index to the position with the earliest entry + size_t earliest_position_; + + /// Iterator used to expire timers. + HASH_ITERATOR *iterator_; + +#if defined (ACE_WIN64) + // Part of a hack... see comments in schedule(). + // This is, essentially, the upper 32 bits of a 64-bit pointer on Win64. + ptrdiff_t pointer_base_; +#endif + + /// Hash_Token is usually allocated in schedule but its + /// deallocation is problematic and token_list_ helps with this. + ACE_Locked_Free_List, ACE_Null_Mutex> token_list_; + + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Hash_T (const ACE_Timer_Hash_T &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Hash_T &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Timer_Hash_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Timer_Hash_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_HASH_T_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Heap.h b/dep/ACE_wrappers/ace/Timer_Heap.h new file mode 100644 index 000000000..7dec5ec22 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Heap.h @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Timer_Heap.h + * + * $Id: Timer_Heap.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TIMER_HEAP_H +#define ACE_TIMER_HEAP_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Heap_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The following typedefs are here for ease of use and backward +// compatibility. + +typedef ACE_Timer_Heap_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_Heap; + +typedef ACE_Timer_Heap_Iterator_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_Heap_Iterator; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_HEAP_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Heap_T.cpp b/dep/ACE_wrappers/ace/Timer_Heap_T.cpp new file mode 100644 index 000000000..03893dac9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Heap_T.cpp @@ -0,0 +1,889 @@ +// $Id: Timer_Heap_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMER_HEAP_T_CPP +#define ACE_TIMER_HEAP_T_CPP + +#include "ace/Timer_Heap_T.h" +#include "ace/Log_Msg.h" +#include "ace/Guard_T.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_string.h" +#include "ace/Numeric_Limits.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/* +** The ACE_Timer_Heap::max_size_ and array loops, checks, etc. are all size_t. +** The timer IDs are long, and since they are indices into the heap, we need +** to be sure that the timer heap size can fit in a long. Hence, when size +** is (re)set, limit it to the maximum long value. We use the C++ standard +** limits if available. +*/ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Define some simple inlined functions to clarify the code. +inline size_t +ACE_HEAP_PARENT (size_t X) +{ + return (X == 0 ? 0 : ((X - 1) / 2)); +} + +inline size_t +ACE_HEAP_LCHILD (size_t X) +{ + return X + X + 1; +} + +// Constructor that takes in an to iterate over. + +template +ACE_Timer_Heap_Iterator_T::ACE_Timer_Heap_Iterator_T ( + ACE_Timer_Heap_T &heap) + : timer_heap_ (heap) +{ + ACE_TRACE ("ACE_Timer_Heap_Iterator_T::ACE_Timer_Heap_Iterator"); + this->first (); +} + +template +ACE_Timer_Heap_Iterator_T::~ACE_Timer_Heap_Iterator_T (void) +{ +} + +// Positions the iterator at the first node in the heap array + +template +void +ACE_Timer_Heap_Iterator_T::first (void) +{ + this->position_ = 0; +} + +// Positions the iterator at the next node in the heap array + +template +void +ACE_Timer_Heap_Iterator_T::next (void) +{ + if (this->position_ != this->timer_heap_.cur_size_) + ++this->position_; +} + +// Returns true the is at the end of the heap array + +template bool +ACE_Timer_Heap_Iterator_T::isdone (void) const +{ + return this->position_ == this->timer_heap_.cur_size_; +} + +// Returns the node at the current position in the heap or 0 if at the end + +template ACE_Timer_Node_T * +ACE_Timer_Heap_Iterator_T::item (void) +{ + if (this->position_ != this->timer_heap_.cur_size_) + return this->timer_heap_.heap_[this->position_]; + return 0; +} + +// Constructor +// Note that timer_ids_curr_ and timer_ids_min_free_ both start at 0. +// Since timer IDs are assigned by first incrementing the timer_ids_curr_ +// value, the first ID assigned will be 1 (just as in the previous design). +// When it's time to wrap, the next ID given out will be 0. +template +ACE_Timer_Heap_T::ACE_Timer_Heap_T ( + size_t size, + bool preallocated, + FUNCTOR *upcall_functor, + ACE_Free_List > *freelist) + : ACE_Timer_Queue_T (upcall_functor, freelist), + max_size_ (size), + cur_size_ (0), + cur_limbo_ (0), + timer_ids_curr_ (0), + timer_ids_min_free_ (0), + preallocated_nodes_ (0), + preallocated_nodes_freelist_ (0) +{ + ACE_TRACE ("ACE_Timer_Heap_T::ACE_Timer_Heap_T"); + + // Possibly reduce size to fit in a long. + if (size > static_cast (ACE_Numeric_Limits::max ())) + { + size = static_cast (ACE_Numeric_Limits::max ()); + this->max_size_ = size; + } + + // Create the heap array. + ACE_NEW (this->heap_, + ACE_Timer_Node_T *[size]); + + // Create the parallel + ACE_NEW (this->timer_ids_, + ssize_t[size]); + + // Initialize the "freelist," which uses negative values to + // distinguish freelist elements from "pointers" into the + // array. + for (size_t i = 0; i < size; ++i) + this->timer_ids_[i] = -1; + + if (preallocated) + { + ACE_NEW (this->preallocated_nodes_, + ACE_Timer_Node_T[size]); + + // Add allocated array to set of such arrays for deletion on + // cleanup. + this->preallocated_node_set_.insert (this->preallocated_nodes_); + + // Form the freelist by linking the next_ pointers together. + for (size_t j = 1; j < size; ++j) + this->preallocated_nodes_[j - 1].set_next (&this->preallocated_nodes_[j]); + + // NULL-terminate the freelist. + this->preallocated_nodes_[size - 1].set_next (0); + + // Assign the freelist pointer to the front of the list. + this->preallocated_nodes_freelist_ = + &this->preallocated_nodes_[0]; + } + + ACE_NEW (iterator_, + HEAP_ITERATOR (*this)); +} + +// Note that timer_ids_curr_ and timer_ids_min_free_ both start at 0. +// Since timer IDs are assigned by first incrementing the timer_ids_curr_ +// value, the first ID assigned will be 1 (just as in the previous design). +// When it's time to wrap, the next ID given out will be 0. +template +ACE_Timer_Heap_T::ACE_Timer_Heap_T ( + FUNCTOR *upcall_functor, + ACE_Free_List > *freelist) + : ACE_Timer_Queue_T (upcall_functor, freelist), + max_size_ (ACE_DEFAULT_TIMERS), + cur_size_ (0), + cur_limbo_ (0), + timer_ids_curr_ (0), + timer_ids_min_free_ (0), + preallocated_nodes_ (0), + preallocated_nodes_freelist_ (0) +{ + ACE_TRACE ("ACE_Timer_Heap_T::ACE_Timer_Heap_T"); + + // Possibly reduce size to fit in a long. + if (this->max_size_ > static_cast (ACE_Numeric_Limits::max ())) + this->max_size_ = static_cast (ACE_Numeric_Limits::max ()); + + // Create the heap array. + ACE_NEW (this->heap_, + ACE_Timer_Node_T *[this->max_size_]); + + // Create the parallel array. + ACE_NEW (this->timer_ids_, + ssize_t[this->max_size_]); + + // Initialize the "freelist," which uses negative values to + // distinguish freelist elements from "pointers" into the + // array. + for (size_t i = 0; i < this->max_size_; ++i) + this->timer_ids_[i] = -1; + + ACE_NEW (iterator_, + HEAP_ITERATOR (*this)); +} + +template +ACE_Timer_Heap_T::~ACE_Timer_Heap_T (void) +{ + ACE_TRACE ("ACE_Timer_Heap_T::~ACE_Timer_Heap_T"); + + delete iterator_; + + size_t current_size = + this->cur_size_; + + // Clean up all the nodes still in the queue + for (size_t i = 0; i < current_size; ++i) + { + // Grab the event_handler and act, then delete the node before calling + // back to the handler. Prevents a handler from trying to cancel_timer() + // inside handle_close(), ripping the current timer node out from + // under us. + TYPE eh = this->heap_[i]->get_type (); + const void *act = this->heap_[i]->get_act (); + this->free_node (this->heap_[i]); + this->upcall_functor ().deletion (*this, eh, act); + } + + delete [] this->heap_; + delete [] this->timer_ids_; + + // clean up any preallocated timer nodes + if (preallocated_nodes_ != 0) + { + ACE_Unbounded_Set_Iterator *> + set_iterator (this->preallocated_node_set_); + + for (ACE_Timer_Node_T **entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance ()) + delete [] *entry; + } +} + +template +long +ACE_Timer_Heap_T::pop_freelist (void) +{ + ACE_TRACE ("ACE_Timer_Heap_T::pop_freelist"); + + // Scan for a free timer ID. Note that since this function is called + // _after_ the check for a full timer heap, we are guaranteed to find + // a free ID, even if we need to wrap around and start reusing freed IDs. + // On entry, the curr_ index is at the previous ID given out; start + // up where we left off last time. + // NOTE - a timer_ids_ slot with -2 is out of the heap, but not freed. + // It must be either freed (free_node) or rescheduled (reschedule). + ++this->timer_ids_curr_; + while (this->timer_ids_curr_ < this->max_size_ && + (this->timer_ids_[this->timer_ids_curr_] >= 0 || + this->timer_ids_[this->timer_ids_curr_] == -2 )) + ++this->timer_ids_curr_; + if (this->timer_ids_curr_ == this->max_size_) + { + ACE_ASSERT (this->timer_ids_min_free_ < this->max_size_); + this->timer_ids_curr_ = this->timer_ids_min_free_; + // We restarted the free search at min. Since min won't be + // free anymore, and curr_ will just keep marching up the list + // on each successive need for an ID, reset min_free_ to the + // size of the list until an ID is freed that curr_ has already + // gone past (see push_freelist). + this->timer_ids_min_free_ = this->max_size_; + } + + return static_cast (this->timer_ids_curr_); +} + +template +void +ACE_Timer_Heap_T::push_freelist (long old_id) +{ + ACE_TRACE ("ACE_Timer_Heap_T::push_freelist"); + + // Since this ID has already been checked by one of the public + // functions, it's safe to cast it here. + size_t oldid = static_cast (old_id); + + // The freelist values in the are negative, so set the + // freed entry back to 'free'. If this is the new lowest value free + // timer ID that curr_ won't see on it's normal march through the list, + // remember it. + ACE_ASSERT (this->timer_ids_[oldid] >= 0 || this->timer_ids_[oldid] == -2); + if (this->timer_ids_[oldid] == -2) + --this->cur_limbo_; + else + --this->cur_size_; + this->timer_ids_[oldid] = -1; + if (oldid < this->timer_ids_min_free_ && oldid <= this->timer_ids_curr_) + this->timer_ids_min_free_ = oldid; + return; +} + +template +long +ACE_Timer_Heap_T::timer_id (void) +{ + ACE_TRACE ("ACE_Timer_Heap_T::timer_id"); + + // Return the next item off the freelist and use it as the timer id. + return this->pop_freelist (); +} + +// Checks if queue is empty. + +template +bool +ACE_Timer_Heap_T::is_empty (void) const +{ + ACE_TRACE ("ACE_Timer_Heap_T::is_empty"); + return this->cur_size_ == 0; +} + +template +ACE_Timer_Queue_Iterator_T & +ACE_Timer_Heap_T::iter (void) +{ + this->iterator_->first (); + return *this->iterator_; +} + +// Returns earliest time in a non-empty queue. + +template const ACE_Time_Value & +ACE_Timer_Heap_T::earliest_time (void) const +{ + ACE_TRACE ("ACE_Timer_Heap_T::earliest_time"); + return this->heap_[0]->get_timer_value (); +} + +template +void +ACE_Timer_Heap_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Timer_Heap_T::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmax_size_ = %d"), this->max_size_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d"), this->cur_size_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_limbo_= %d"), this->cur_limbo_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nids_curr_ = %d"), + this->timer_ids_curr_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmin_free_ = %d"), + this->timer_ids_min_free_)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nheap_ = \n"))); + + for (size_t i = 0; i < this->cur_size_; ++i) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%d\n"), + i)); + this->heap_[i]->dump (); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_ids_ = \n"))); + + for (size_t j = 0; j < this->max_size_; ++j) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%d\t%d\n"), + j, + this->timer_ids_[j])); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +void +ACE_Timer_Heap_T::copy ( + size_t slot, + ACE_Timer_Node_T *moved_node) +{ + // Insert into its new location in the heap. + this->heap_[slot] = moved_node; + + ACE_ASSERT (moved_node->get_timer_id () >= 0 + && moved_node->get_timer_id () < (int) this->max_size_); + + // Update the corresponding slot in the parallel array. + this->timer_ids_[moved_node->get_timer_id ()] = static_cast (slot); +} + +// Remove the slot'th timer node from the heap, but do not reclaim its +// timer ID or change the size of this timer heap object. The caller of +// this function must call either free_node (to reclaim the timer ID +// and the timer node memory, as well as decrement the size of the queue) +// or reschedule (to reinsert the node in the heap at a new time). +template +ACE_Timer_Node_T * +ACE_Timer_Heap_T::remove (size_t slot) +{ + ACE_Timer_Node_T *removed_node = + this->heap_[slot]; + + // NOTE - the cur_size_ is being decremented since the queue has one + // less active timer in it. However, this ACE_Timer_Node is not being + // freed, and there is still a place for it in timer_ids_ (the timer ID + // is not being relinquished). The node can still be rescheduled, or + // it can be freed via free_node. + --this->cur_size_; + + // Only try to reheapify if we're not deleting the last entry. + + if (slot < this->cur_size_) + { + ACE_Timer_Node_T *moved_node = + this->heap_[this->cur_size_]; + + // Move the end node to the location being removed and update + // the corresponding slot in the parallel array. + this->copy (slot, moved_node); + + // If the time_value_> is great than or equal its + // parent it needs be moved down the heap. + size_t parent = ACE_HEAP_PARENT (slot); + + if (moved_node->get_timer_value () + >= this->heap_[parent]->get_timer_value ()) + this->reheap_down (moved_node, + slot, + ACE_HEAP_LCHILD (slot)); + else + this->reheap_up (moved_node, + slot, + parent); + } + + this->timer_ids_[removed_node->get_timer_id ()] = -2; + ++this->cur_limbo_; + return removed_node; +} + +template void +ACE_Timer_Heap_T::reheap_down ( + ACE_Timer_Node_T *moved_node, + size_t slot, + size_t child) +{ + // Restore the heap property after a deletion. + + while (child < this->cur_size_) + { + // Choose the smaller of the two children. + if (child + 1 < this->cur_size_ + && this->heap_[child + 1]->get_timer_value () + < this->heap_[child]->get_timer_value ()) + child++; + + // Perform a if the child has a larger timeout value than + // the . + if (this->heap_[child]->get_timer_value () + < moved_node->get_timer_value ()) + { + this->copy (slot, + this->heap_[child]); + slot = child; + child = ACE_HEAP_LCHILD (child); + } + else + // We've found our location in the heap. + break; + } + + this->copy (slot, moved_node); +} + +template +void +ACE_Timer_Heap_T::reheap_up ( + ACE_Timer_Node_T *moved_node, + size_t slot, + size_t parent) +{ + // Restore the heap property after an insertion. + + while (slot > 0) + { + // If the parent node is greater than the we need + // to copy it down. + if (moved_node->get_timer_value () + < this->heap_[parent]->get_timer_value ()) + { + this->copy (slot, this->heap_[parent]); + slot = parent; + parent = ACE_HEAP_PARENT (slot); + } + else + break; + } + + // Insert the new node into its proper resting place in the heap and + // update the corresponding slot in the parallel array. + this->copy (slot, + moved_node); +} + +template +void +ACE_Timer_Heap_T::insert ( + ACE_Timer_Node_T *new_node) +{ + if (this->cur_size_ + this->cur_limbo_ + 2 >= this->max_size_) + this->grow_heap (); + + this->reheap_up (new_node, + this->cur_size_, + ACE_HEAP_PARENT (this->cur_size_)); + this->cur_size_++; +} + +template +void +ACE_Timer_Heap_T::grow_heap (void) +{ + // All the containers will double in size from max_size_. + size_t new_size = this->max_size_ * 2; + +#if 0 + // Yikes - there's no way to flag a failure of going out of range of + // a 'long' - this is a problem that should be addressed at some point. + if (new_size > ACE_Numeric_Limits::max ()) + new_size = ACE_Numeric_Limits::max (); + + if (new_size <= this->max_size_) // We are already at the limit + { + errno = ENOMEM; + return -1; + } +#endif /* 0 */ + + // First grow the heap itself. + + ACE_Timer_Node_T **new_heap = 0; + + ACE_NEW (new_heap, + ACE_Timer_Node_T *[new_size]); + + ACE_OS::memcpy (new_heap, + this->heap_, + this->max_size_ * sizeof *new_heap); + delete [] this->heap_; + this->heap_ = new_heap; + + // Grow the array of timer ids. + + ssize_t *new_timer_ids = 0; + + ACE_NEW (new_timer_ids, + ssize_t[new_size]); + + ACE_OS::memcpy (new_timer_ids, + this->timer_ids_, + this->max_size_ * sizeof (ssize_t)); + + delete [] timer_ids_; + this->timer_ids_ = new_timer_ids; + + // And add the new elements to the end of the "freelist". + for (size_t i = this->max_size_; i < new_size; ++i) + this->timer_ids_[i] = -(static_cast (i) + 1); + + // Grow the preallocation array (if using preallocation) + if (this->preallocated_nodes_ != 0) + { + // Create a new array with max_size elements to link in to + // existing list. + ACE_NEW (this->preallocated_nodes_, + ACE_Timer_Node_T[this->max_size_]); + + // Add it to the set for later deletion + this->preallocated_node_set_.insert (this->preallocated_nodes_); + + // Link new nodes together (as for original list). + for (size_t k = 1; k < this->max_size_; ++k) + this->preallocated_nodes_[k - 1].set_next (&this->preallocated_nodes_[k]); + + // NULL-terminate the new list. + this->preallocated_nodes_[this->max_size_ - 1].set_next (0); + + // Link new array to the end of the existling list. + if (this->preallocated_nodes_freelist_ == 0) + this->preallocated_nodes_freelist_ = + &preallocated_nodes_[0]; + else + { + ACE_Timer_Node_T *previous = + this->preallocated_nodes_freelist_; + + for (ACE_Timer_Node_T *current = this->preallocated_nodes_freelist_->get_next (); + current != 0; + current = current->get_next ()) + previous = current; + + previous->set_next (&this->preallocated_nodes_[0]); + } + } + + this->max_size_ = new_size; + // Force rescan of list from beginning for a free slot (I think...) + // This fixed Bugzilla #2447. + this->timer_ids_min_free_ = this->max_size_; +} + +// Reschedule a periodic timer. This function must be called with the +// mutex lock held. + +template +void +ACE_Timer_Heap_T::reschedule ( + ACE_Timer_Node_T *expired) +{ + ACE_TRACE ("ACE_Timer_Heap_T::reschedule"); + + // If we are rescheduling, then the most recent call was to + // remove_first (). That called remove () to remove the node from the + // heap, but did not free the timer ID. The ACE_Timer_Node still has + // its assigned ID - just needs to be inserted at the new proper + // place, and the heap restored properly. + if (this->timer_ids_[expired->get_timer_id ()] == -2) + --this->cur_limbo_; + this->insert (expired); +} + +template +ACE_Timer_Node_T * +ACE_Timer_Heap_T::alloc_node (void) +{ + ACE_Timer_Node_T *temp = 0; + + // Only allocate a node if we are *not* using the preallocated heap. + if (this->preallocated_nodes_ == 0) + ACE_NEW_RETURN (temp, + ACE_Timer_Node_T, + 0); + else + { + // check to see if the heap needs to grow + if (this->preallocated_nodes_freelist_ == 0) + this->grow_heap (); + + temp = this->preallocated_nodes_freelist_; + + // Remove the first element from the freelist. + this->preallocated_nodes_freelist_ = + this->preallocated_nodes_freelist_->get_next (); + } + return temp; +} + +template +void +ACE_Timer_Heap_T::free_node ( + ACE_Timer_Node_T *node) +{ + // Return this timer id to the freelist. + this->push_freelist (node->get_timer_id ()); + + // Only free up a node if we are *not* using the preallocated heap. + if (this->preallocated_nodes_ == 0) + delete node; + else + { + node->set_next (this->preallocated_nodes_freelist_); + this->preallocated_nodes_freelist_ = node; + } +} + +// Insert a new timer that expires at time future_time; if interval is +// > 0, the handler will be reinvoked periodically. + +template +long +ACE_Timer_Heap_T::schedule_i ( + const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Timer_Heap_T::schedule_i"); + + if ((this->cur_size_ + this->cur_limbo_) < this->max_size_) + { + // Obtain the next unique sequence number. + long timer_id = this->timer_id (); + + // Obtain the memory to the new node. + ACE_Timer_Node_T *temp = 0; + + ACE_ALLOCATOR_RETURN (temp, + this->alloc_node (), + -1); + temp->set (type, + act, + future_time, + interval, + 0, + timer_id); + + this->insert (temp); + return timer_id; + } + else + return -1; +} + +// Locate and remove the single timer with a value of @a timer_id from +// the timer queue. + +template +int +ACE_Timer_Heap_T::cancel (long timer_id, + const void **act, + int dont_call) +{ + ACE_TRACE ("ACE_Timer_Heap_T::cancel"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + // Locate the ACE_Timer_Node that corresponds to the timer_id. + + // Check to see if the timer_id is out of range + if (timer_id < 0 + || (size_t) timer_id > this->max_size_) + return 0; + + ssize_t timer_node_slot = this->timer_ids_[timer_id]; + + // Check to see if timer_id is still valid. + if (timer_node_slot < 0) + return 0; + + if (timer_id != this->heap_[timer_node_slot]->get_timer_id ()) + { + ACE_ASSERT (timer_id == this->heap_[timer_node_slot]->get_timer_id ()); + return 0; + } + else + { + ACE_Timer_Node_T *temp = + this->remove (timer_node_slot); + + // Call the close hooks. + int cookie = 0; + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + temp->get_type (), + dont_call, + cookie); + + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + temp->get_type (), + dont_call, + cookie); + + if (act != 0) + *act = temp->get_act (); + + this->free_node (temp); + return 1; + } +} + +// Locate and update the inteval on the timer_id + +template +int +ACE_Timer_Heap_T::reset_interval (long timer_id, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Timer_Heap_T::reset_interval"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + // Locate the ACE_Timer_Node that corresponds to the timer_id. + + // Check to see if the timer_id is out of range + if (timer_id < 0 + || (size_t) timer_id > this->max_size_) + return -1; + + ssize_t timer_node_slot = this->timer_ids_[timer_id]; + + // Check to see if timer_id is still valid. + if (timer_node_slot < 0) + return -1; + + if (timer_id != this->heap_[timer_node_slot]->get_timer_id ()) + { + ACE_ASSERT (timer_id == this->heap_[timer_node_slot]->get_timer_id ()); + return -1; + } + else + { + // Reset the timer interval + this->heap_[timer_node_slot]->set_interval (interval); + return 0; + } +} + +// Locate and remove all values of @a type from the timer queue. + +template +int +ACE_Timer_Heap_T::cancel (const TYPE &type, + int dont_call) +{ + ACE_TRACE ("ACE_Timer_Heap_T::cancel"); + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + int number_of_cancellations = 0; + + // Try to locate the ACE_Timer_Node that matches the timer_id. + + for (size_t i = 0; i < this->cur_size_; ) + { + if (this->heap_[i]->get_type () == type) + { + ACE_Timer_Node_T *temp = this->remove (i); + + ++number_of_cancellations; + + this->free_node (temp); + + // We reset to zero so that we don't miss checking any nodes + // if a reheapify occurs when a node is removed. There + // may be a better fix than this, however. + i = 0; + } + else + ++i; + } + + // Call the close hooks. + int cookie = 0; + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + type, + dont_call, + cookie); + + for (int j = 0; + j < number_of_cancellations; + ++j) + { + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + type, + dont_call, + cookie); + } + + return number_of_cancellations; +} + +// Returns the earliest node or returns 0 if the heap is empty. + +template +ACE_Timer_Node_T * +ACE_Timer_Heap_T::remove_first (void) +{ + ACE_TRACE ("ACE_Timer_Heap_T::remove_first"); + + if (this->cur_size_ == 0) + return 0; + + return this->remove (0); +} + +template +ACE_Timer_Node_T * +ACE_Timer_Heap_T::get_first (void) +{ + ACE_TRACE ("ACE_Timer_Heap_T::get_first"); + + return this->cur_size_ == 0 ? 0 : this->heap_[0]; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TIMER_HEAP_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Timer_Heap_T.h b/dep/ACE_wrappers/ace/Timer_Heap_T.h new file mode 100644 index 000000000..ac21a487f --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Heap_T.h @@ -0,0 +1,338 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Heap_T.h + * + * $Id: Timer_Heap_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TIMER_HEAP_T_H +#define ACE_TIMER_HEAP_T_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Queue_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Free_List.h" +#include "ace/Unbounded_Set.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration +template +class ACE_Timer_Heap_T; + +/** + * @class ACE_Timer_Heap_Iterator_T + * + * @brief Iterates over an ACE_Timer_Heap_T. + * + * This is a generic iterator that can be used to visit every + * node of a timer queue. Be aware that it doesn't transverse + * in the order of timeout values. + */ +template +class ACE_Timer_Heap_Iterator_T : public ACE_Timer_Queue_Iterator_T +{ +public: + /// Constructor. + ACE_Timer_Heap_Iterator_T (ACE_Timer_Heap_T &); + + /// Destructor. + ~ACE_Timer_Heap_Iterator_T (void); + + /// Positions the iterator at the earliest node in the Timer Queue + virtual void first (void); + + /// Positions the iterator at the next node in the Timer Queue + virtual void next (void); + + /// Returns true when there are no more nodes in the sequence + virtual bool isdone (void) const; + + /// Returns the node at the current position in the sequence + virtual ACE_Timer_Node_T *item (void); + +protected: + /// Pointer to the ACE_Timer_Heap that we are iterating over. + ACE_Timer_Heap_T &timer_heap_; + + /// Position in the array where the iterator is at + size_t position_; +}; + +/** + * @class ACE_Timer_Heap_T + * + * @brief Provides a very fast and predictable timer implementation. + * + * This implementation uses a heap-based callout queue of + * absolute times. Therefore, in the average and worst case, + * scheduling, canceling, and expiring timers is O(log N) (where + * N is the total number of timers). In addition, we can also + * preallocate as many @c ACE_Timer_Node objects as there are slots + * in the heap. This allows us to completely remove the need for + * dynamic memory allocation, which is important for real-time + * systems. + */ +template +class ACE_Timer_Heap_T : public ACE_Timer_Queue_T +{ +public: + typedef ACE_Timer_Heap_Iterator_T HEAP_ITERATOR; + friend class ACE_Timer_Heap_Iterator_T; + + typedef ACE_Timer_Queue_T INHERITED; + + // = Initialization and termination methods. + /** + * The Constructor creates a heap with specified number of elements. + * This can also take in a upcall functor and freelist (if 0, then + * defaults will be created). + * + * @param size The maximum number of timers that can be + * inserted into the new object. + * @param preallocated Default false, true then all the memory + * for the @c ACE_Timer_Node objects will be pre-allocated. This saves + * time and is more predictable (though it requires more space). + * Otherwise, timer nodes are allocated as needed. + * @param freelist is the freelist of timer nodes. + * @param upcall_functor If 0 Timer Heap will create a default FUNCTOR. + */ + ACE_Timer_Heap_T (size_t size, + bool preallocated = false, + FUNCTOR *upcall_functor = 0, + ACE_Free_List > *freelist = 0); + + /** + * Default constructor. @c upcall_functor is the instance of the + * FUNCTOR to be used by the queue. If @c upcall_functor is 0, Timer + * Heap will create a default FUNCTOR. @c freelist is the freelist of + * timer nodes. If 0, then a default freelist will be created. The default + * size will be ACE_DEFAULT_TIMERS and there will be no preallocation. + */ + ACE_Timer_Heap_T (FUNCTOR *upcall_functor = 0, + ACE_Free_List > *freelist = 0); + + /// Destructor. + virtual ~ACE_Timer_Heap_T (void); + + /// True if heap is empty, else false. + virtual bool is_empty (void) const; + + /// Returns the time of the earliest node in the Timer_Queue. + /// Must be called on a non-empty queue. + virtual const ACE_Time_Value &earliest_time (void) const; + + /** + * Resets the interval of the timer represented by @a timer_id to + * @a interval, which is specified in relative time to the current + * . If @a interval is equal to + * ACE_Time_Value::zero, the timer will become a non-rescheduling + * timer. Returns 0 if successful, -1 if not. + */ + virtual int reset_interval (long timer_id, + const ACE_Time_Value &interval); + + /** + * Cancel all timers associated with @a type. If @a dont_call_handle_close + * is 0then the will be invoked. Returns number of timers + * cancelled. + */ + virtual int cancel (const TYPE &type, + int dont_call_handle_close = 1); + + /** + * Cancel the single timer that matches the @a timer_id value (which + * was returned from the method). If act is non-NULL + * then it will be set to point to the ``magic cookie'' argument + * passed in when the timer was registered. This makes it possible + * to free up the memory and avoid memory leaks. If @a dont_call_handle_close + * is 0 then the will be invoked. Returns 1 if cancellation + * succeeded and 0 if the @a timer_id wasn't found. + */ + virtual int cancel (long timer_id, + const void **act = 0, + int dont_call_handle_close = 1); + + /// Returns a pointer to this ACE_Timer_Queue's iterator. + virtual ACE_Timer_Queue_Iterator_T &iter (void); + + /** + * Removes the earliest node from the queue and returns it. Note that + * the timer is removed from the heap, but is not freed, and its ID + * is not reclaimed. The caller is responsible for calling either + * @c reschedule() or @c free_node() after this function returns. Thus, + * this function is for support of @c ACE_Timer_Queue::expire and + * should not be used unadvisedly in other conditions. + */ + ACE_Timer_Node_T *remove_first (void); + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Reads the earliest node from the queue and returns it. + virtual ACE_Timer_Node_T *get_first (void); + +protected: + + /** + * Schedule a timer that may optionally auto-reset. + * Schedule @a type that will expire at @a future_time, + * which is specified in absolute time. If it expires then @a act is + * passed in as the value to the . If @a interval is != to + * ACE_Time_Value::zero then it is used to reschedule the @a type + * automatically, using relative time to the current . + * This method returns a that uniquely identifies the the + * @a type entry in an internal list. This can be used to + * cancel the timer before it expires. The cancellation ensures + * that are unique up to values of greater than 2 + * billion timers. As long as timers don't stay around longer than + * this there should be no problems with accidentally deleting the + * wrong timer. Returns -1 on failure (which is guaranteed never to + * be a valid ). + */ + virtual long schedule_i (const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval); + + /// Reschedule an "interval" ACE_Timer_Node. + virtual void reschedule (ACE_Timer_Node_T *); + + /// Factory method that allocates a new node (uses operator new if + /// we're *not* preallocating, otherwise uses an internal freelist). + virtual ACE_Timer_Node_T *alloc_node (void); + + /** + * Factory method that frees a previously allocated node (uses + * operator delete if we're *not* preallocating, otherwise uses an + * internal freelist). + */ + virtual void free_node (ACE_Timer_Node_T *); + +private: + /// Remove and return the @a sloth ACE_Timer_Node and restore the + /// heap property. + ACE_Timer_Node_T *remove (size_t slot); + + /// Insert @a new_node into the heap and restore the heap property. + void insert (ACE_Timer_Node_T *new_node); + + /** + * Doubles the size of the heap and the corresponding timer_ids array. + * If preallocation is used, will also double the size of the + * preallocated array of ACE_Timer_Nodes. + */ + void grow_heap (void); + + /// Restore the heap property, starting at @a slot. + void reheap_up (ACE_Timer_Node_T *new_node, + size_t slot, + size_t parent); + + /// Restore the heap property, starting at @a slot. + void reheap_down (ACE_Timer_Node_T *moved_node, + size_t slot, + size_t child); + + /// Copy @a moved_node into the @a slot slot of and move + /// @a slot into the corresponding slot in the array. + void copy (size_t slot, ACE_Timer_Node_T *moved_node); + + /** + * Returns a timer id that uniquely identifies this timer. This id + * can be used to cancel a timer via the method. The + * timer id returned from this method will never == -1 to avoid + * conflicts with other failure return values. + */ + long timer_id (void); + + /// Pops and returns a new timer id from the freelist. + long pop_freelist (void); + + /// Pushes @a old_id onto the freelist. + void push_freelist (long old_id); + + /// Maximum size of the heap. + size_t max_size_; + + /// Current size of the heap. + size_t cur_size_; + + /// Number of heap entries in transition (removed from the queue, but + /// not freed) and may be rescheduled or freed. + size_t cur_limbo_; + + /// Iterator used to expire timers. + HEAP_ITERATOR *iterator_; + + /** + * Current contents of the Heap, which is organized as a "heap" of + * ACE_Timer_Node *'s. In this context, a heap is a "partially + * ordered, almost complete" binary tree, which is stored in an + * array. + */ + ACE_Timer_Node_T **heap_; + + /** + * An array of "pointers" that allows each ACE_Timer_Node in the + * to be located in O(1) time. Basically, + * contains the slot in the array where an ACE_Timer_Node + * * with timer id \ resides. Thus, the timer id passed back from + * is really a slot into the array. The + * array serves two purposes: negative values are + * indications of free timer IDs, whereas positive values are + * "pointers" into the array for assigned timer IDs. + */ + ssize_t *timer_ids_; + + /// "Pointer" to the element in the array that was + /// last given out as a timer ID. + size_t timer_ids_curr_; + + /// Index representing the lowest timer ID that has been freed. When + /// the timer_ids_next_ value wraps around, it starts back at this + /// point. + size_t timer_ids_min_free_; + + /** + * If this is non-0, then we preallocate number of + * ACE_Timer_Node objects in order to reduce dynamic allocation + * costs. In auto-growing implementation, this points to the + * last array of nodes allocated. + */ + ACE_Timer_Node_T *preallocated_nodes_; + + /// This points to the head of the freelist, + /// which is organized as a stack. + ACE_Timer_Node_T *preallocated_nodes_freelist_; + + /// Set of pointers to the arrays of preallocated timer nodes. + /// Used to delete the allocated memory when required. + ACE_Unbounded_Set *> preallocated_node_set_; + + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Heap_T (const ACE_Timer_Heap_T &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Heap_T &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Timer_Heap_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Timer_Heap_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_HEAP_T_H */ diff --git a/dep/ACE_wrappers/ace/Timer_List.h b/dep/ACE_wrappers/ace/Timer_List.h new file mode 100644 index 000000000..f2d9cc2a4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_List.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_List.h + * + * $Id: Timer_List.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_TIMER_LIST_H +#define ACE_TIMER_LIST_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_List_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The following typedefs are here for ease of use and backward +// compatibility. + +typedef ACE_Timer_List_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_List; + +typedef ACE_Timer_List_Iterator_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_List_Iterator; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_LIST_H */ diff --git a/dep/ACE_wrappers/ace/Timer_List_T.cpp b/dep/ACE_wrappers/ace/Timer_List_T.cpp new file mode 100644 index 000000000..c3b837bb2 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_List_T.cpp @@ -0,0 +1,418 @@ +// $Id: Timer_List_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMER_LIST_T_C +#define ACE_TIMER_LIST_T_C + +#include "ace/Timer_List_T.h" +#include "ace/Guard_T.h" +#include "ace/Log_Msg.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, Timer_List_T, "$Id: Timer_List_T.cpp 80826 2008-03-04 14:51:23Z wotte $") + +// Default Constructor + +template +ACE_Timer_List_Iterator_T::ACE_Timer_List_Iterator_T (List& lst) + : list_ (lst) +{ + this->first(); +} + +template +ACE_Timer_List_Iterator_T::~ACE_Timer_List_Iterator_T (void) +{ +} + +// Positions the iterator at the node right after the dummy node + +template void +ACE_Timer_List_Iterator_T::first (void) +{ + this->current_node_ = this->list_.get_first(); +} + +// Positions the iterator at the next node in the Timer Queue + +template void +ACE_Timer_List_Iterator_T::next (void) +{ + // Make sure that if we are at the end, we don't wrap around + if (! this->isdone()) + this->current_node_ = this->current_node_->get_next (); + if (this->current_node_ == this->list_.head_) + this->current_node_ = 0; +} + +// Returns true when we are at + +template bool +ACE_Timer_List_Iterator_T::isdone (void) const +{ + return this->current_node_ == 0; +} + +// Returns the node at or 0 if we are at the end + +template ACE_Timer_Node_T * +ACE_Timer_List_Iterator_T::item (void) +{ + if (! this->isdone()) + return this->current_node_; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// Return our instance of the iterator + +template ACE_Timer_Queue_Iterator_T & +ACE_Timer_List_T::iter (void) +{ + this->iterator_->first (); + return *this->iterator_; +} + +// Create an empty list. + +template +ACE_Timer_List_T::ACE_Timer_List_T (FUNCTOR* uf, FreeList* fl) + : Base(uf, fl) + , head_ (new ACE_Timer_Node_T) + , id_counter_ (0) +{ + ACE_TRACE ("ACE_Timer_List_T::ACE_Timer_List_T"); + + this->head_->set_next (this->head_); + this->head_->set_prev (this->head_); + + ACE_NEW (iterator_, Iterator(*this)); +} + + +// Checks if list is empty. + +template bool +ACE_Timer_List_T::is_empty (void) const +{ + ACE_TRACE ("ACE_Timer_List_T::is_empty"); + return this->get_first_i() == 0; +} + + +// Returns earliest time in a non-empty list. + +template const ACE_Time_Value & +ACE_Timer_List_T::earliest_time (void) const +{ + ACE_TRACE ("ACE_Timer_List_T::earliest_time"); + ACE_Timer_Node_T* first = this->get_first_i(); + if (first != 0) + return first->get_timer_value (); + return ACE_Time_Value::zero; +} + + +// Remove all remaining items in the list. + +template +ACE_Timer_List_T::~ACE_Timer_List_T (void) +{ + ACE_TRACE ("ACE_Timer_List_T::~ACE_Timer_List_T"); + ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_)); + + delete iterator_; + + if (!this->is_empty()) + { + for (ACE_Timer_Node_T* n = this->get_first(); + n != this->head_; + ) + { + this->upcall_functor ().deletion (*this, + n->get_type(), + n->get_act()); + + ACE_Timer_Node_T *next = + n->get_next (); + + this->free_node (n); + + n = next; + } + } + + // delete the dummy node + delete this->head_; +} + +template void +ACE_Timer_List_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Timer_List_T::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + int count = 0; + + ACE_Timer_Node_T* n = this->get_first_i(); + if (n != 0) { + for (; n != this->head_; n = n->get_next()) { + ++count; + } + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsize_ = %d"), count)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + + +// Reschedule a periodic timer. This function must be called with the +// lock held. + +template void +ACE_Timer_List_T::reschedule (ACE_Timer_Node_T* n) +{ + ACE_TRACE ("ACE_Timer_List_T::reschedule"); + this->schedule_i(n, n->get_timer_value()); +} + + +// Insert a new handler that expires at time future_time; if interval +// is > 0, the handler will be reinvoked periodically. + +template long +ACE_Timer_List_T::schedule_i (const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Timer_List_T::schedule_i"); + + ACE_Timer_Node_T* n = this->alloc_node(); + + if (n != 0) + { + long id = this->id_counter_++; + + if (id != -1) { + n->set (type, act, future_time, interval, 0, 0, id); + this->schedule_i (n, future_time); + } + return id; + } + + // Failure return + errno = ENOMEM; + return -1; +} + +/// The shared scheduling functionality between schedule() and reschedule() +template void +ACE_Timer_List_T::schedule_i (ACE_Timer_Node_T* n, + const ACE_Time_Value& expire) +{ + if (this->is_empty()) { + n->set_prev(this->head_); + n->set_next(this->head_); + this->head_->set_prev(n); + this->head_->set_next(n); + return; + } + + // We always want to search backwards from the tail of the list, because + // this minimizes the search in the extreme case when lots of timers are + // scheduled for exactly the same time, and it also assumes that most of + // the timers will be scheduled later than existing timers. + ACE_Timer_Node_T* p = this->head_->get_prev(); + while (p != this->head_ && p->get_timer_value() > expire) + p = p->get_prev(); + + // insert after + n->set_prev(p); + n->set_next(p->get_next()); + p->get_next()->set_prev(n); + p->set_next(n); +} + +template +ACE_Timer_Node_T* +ACE_Timer_List_T::find_node (long timer_id) const +{ + ACE_Timer_Node_T* n = this->get_first_i(); + if (n == 0) + return 0; + + for (; n != this->head_; n = n->get_next()) { + if (n->get_timer_id() == timer_id) { + return n; + } + } + return 0; +} + +// Locate and update the inteval on the timer_id +template int +ACE_Timer_List_T::reset_interval (long timer_id, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Timer_List_T::reset_interval"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + ACE_Timer_Node_T* n = this->find_node(timer_id); + if (n != 0) { + n->set_interval(interval); // The interval will take effect the next time this node is expired. + return 0; + } + return -1; +} + +// Locate and remove the single with a value of +// @a timer_id from the timer queue. +template int +ACE_Timer_List_T::cancel (long timer_id, + const void **act, + int skip_close) +{ + ACE_TRACE ("ACE_Timer_List_T::cancel"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + ACE_Timer_Node_T* n = this->find_node(timer_id); + if (n != 0) + { + if (act != 0) + *act = n->get_act (); + + // Call the close hooks. + int cookie = 0; + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + n->get_type (), + skip_close, + cookie); + + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + n->get_type (), + skip_close, + cookie); + + this->cancel_i (n); + + return 1; + } + + return 0; +} + +// Locate and remove all values of from the timer queue. +template int +ACE_Timer_List_T::cancel (const TYPE &type, int skip_close) +{ + ACE_TRACE ("ACE_Timer_List_T::cancel"); + + int num_canceled = 0; // Note : Technically this can overflow. + + int cookie = 0; + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + if (!this->is_empty ()) + { + for (ACE_Timer_Node_T* n = this->get_first(); + n != this->head_; + ) + { + if (n->get_type() == type) // Note: Typically Type is an ACE_Event_Handler* + { + ++num_canceled; + + ACE_Timer_Node_T* tmp = n; + n = n->get_next(); + + this->cancel_i (tmp); + } + else + { + n = n->get_next(); + } + } + } + + // Call the close hooks. + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + type, + skip_close, + cookie); + + for (int i = 0; + i < num_canceled; + ++i) + { + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + type, + skip_close, + cookie); + } + + return num_canceled; +} + +template void +ACE_Timer_List_T::unlink (ACE_Timer_Node_T* n) +{ + n->get_prev()->set_next(n->get_next()); + n->get_next()->set_prev(n->get_prev()); + n->set_prev(0); + n->set_next(0); +} + +/// Shared subset of the two cancel() methods. +template void +ACE_Timer_List_T::cancel_i (ACE_Timer_Node_T* n) +{ + this->unlink (n); + this->free_node (n); +} + +// Reads the first node on the list and returns it. +template ACE_Timer_Node_T * +ACE_Timer_List_T::get_first (void) +{ + ACE_TRACE ("ACE_Timer_List_T::get_first"); + return this->get_first_i(); +} + +template ACE_Timer_Node_T * +ACE_Timer_List_T::get_first_i (void) const +{ + ACE_TRACE ("ACE_Timer_List_T::get_first_i"); + ACE_Timer_Node_T* first = this->head_->get_next(); + if (first != this->head_) // Note : is_empty() uses get_first() + return first; + return 0; +} + + +// Removes the first node on the list and returns it. + +template ACE_Timer_Node_T * +ACE_Timer_List_T::remove_first (void) +{ + ACE_TRACE ("ACE_Timer_List_T::remove_first"); + ACE_Timer_Node_T* first = this->get_first(); + if (first != 0) { + this->unlink(first); + return first; + } + return 0; +} + +#endif /* ACE_TIMER_LIST_T_C */ diff --git a/dep/ACE_wrappers/ace/Timer_List_T.h b/dep/ACE_wrappers/ace/Timer_List_T.h new file mode 100644 index 000000000..cabd47aea --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_List_T.h @@ -0,0 +1,226 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Timer_List_T.h + * + * $Id: Timer_List_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TIMER_LIST_T_H +#define ACE_TIMER_LIST_T_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Queue_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Forward declaration. +template +class ACE_Timer_List_T; + +/** + * @class ACE_Timer_List_Iterator_T + * + * @brief Iterates over an ACE_Timer_List. + * + * This is a generic iterator that can be used to visit every + * node of a timer queue. + */ +template +class ACE_Timer_List_Iterator_T +: public ACE_Timer_Queue_Iterator_T +{ +public: + typedef ACE_Timer_List_T List; + /// Constructor. + ACE_Timer_List_Iterator_T (List& lst); + + /// Destructor. + virtual ~ACE_Timer_List_Iterator_T (void); + + /// Positions the iterator at the earliest node in the Timer Queue + virtual void first (void); + + /// Positions the iterator at the next node in the Timer Queue + virtual void next (void); + + /// Returns true when there are no more nodes in the sequence + virtual bool isdone (void) const; + + /// Returns the node at the current position in the sequence + virtual ACE_Timer_Node_T *item (void); + +protected: + /// Pointer to the ACE_Timer_List that we are iterating over. + List& list_; + + /// Current position in the ACE_Timer_List + ACE_Timer_Node_T* current_node_; +}; + +/** + * @class ACE_Timer_List_T + * + * @brief Provides a simple implementation of timers. + * + * This implementation uses a linked list of absolute times. + * Therefore, in the average case, scheduling and canceling + * timers is O(N) (where N is the total number of timers) and + * expiring timers is O(K) (where K is the total number of timers + * that are < the current time of day). + * More clever implementations could use a delta-list, a heap, + * or timing wheels, etc. For instance, ACE_Timer_Heap + * is a subclass of ACE_Timer_List that implements a + * heap-based callout queue. For most applications, the + * ACE_Timer_Heap will perform substantially faster than the + * ACE_Timer_List. + */ +template +class ACE_Timer_List_T : public ACE_Timer_Queue_T +{ +public: + /// Type of iterator + typedef ACE_Timer_List_Iterator_T Iterator; + + /// Iterator is a friend + friend class ACE_Timer_List_Iterator_T; + + typedef ACE_Timer_Node_T Node; + /// Type inherited from + typedef ACE_Timer_Queue_T Base; + typedef ACE_Free_List FreeList; + + // = Initialization and termination methods. + /** + * Default constructor. @a upcall_functor is the instance of the + * FUNCTOR to be used by the list. If @a upcall_functor is 0, a + * default FUNCTOR will be created. @a freelist is the freelist of + * timer nodes. If 0, then a default freelist will be created. + */ + ACE_Timer_List_T (FUNCTOR* upcall_functor = 0, FreeList* freelist = 0); + + /// Destructor + virtual ~ACE_Timer_List_T (void); + + /// True if queue is empty, else false. + virtual bool is_empty (void) const; + + /// Returns the time of the earlier node in the ACE_Timer_List. + /// Must be called on a non-empty queue. + virtual const ACE_Time_Value& earliest_time (void) const; + + /** + * Resets the interval of the timer represented by @a timer_id to + * @a interval, which is specified in relative time to the current + * . If @a interval is equal to + * ACE_Time_Value::zero, the timer will become a non-rescheduling + * timer. Returns 0 if successful, -1 if not. + */ + virtual int reset_interval (long timer_id, + const ACE_Time_Value& interval); + + /** + * Cancel all timers associated with @a type. If dont_call_handle_close is 0 + * then the @a functor will be invoked. Returns the number of timers + * cancelled. + */ + virtual int cancel (const TYPE& type, + int dont_call_handle_close = 1); + + /** + * Cancel the single timer that matches the @a timer_id value (which + * was returned from the method). If act is non-NULL + * then it will be set to point to the ``magic cookie'' argument + * passed in when the timer was registered. This makes it possible + * to free up the memory and avoid memory leaks. If is + * 0 then the will be invoked. Returns 1 if cancellation + * succeeded and 0 if the @a timer_id wasn't found. + */ + virtual int cancel (long timer_id, + const void** act = 0, + int dont_call_handle_close = 1); + + /// Returns a pointer to this ACE_Timer_Queue's iterator. + virtual ACE_Timer_Queue_Iterator_T& iter (void); + + /// Removes the earliest node from the queue and returns it + virtual ACE_Timer_Node_T* remove_first (void); + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Reschedule an "interval" ACE_Timer_Node_T. This should be private + /// but for now it needs to be public for + virtual void reschedule (ACE_Timer_Node_T *); + + /// Reads the earliest node from the queue and returns it. + virtual ACE_Timer_Node_T* get_first (void); + +private: + + /** + * Schedule @a type that will expire at @a future_time, which is + * specified in absolute time. If it expires then @a act is passed + * in as the value to the . If @a interval is != to + * ACE_Time_Value::zero then it is used to reschedule the @a type + * automatically, using relative time to the current . + * This method returns a that uniquely identifies the the + * @a type entry in an internal list. This can be used to + * cancel the timer before it expires. The cancellation ensures + * that are unique up to values of greater than 2 + * billion timers. As long as timers don't stay around longer than + * this there should be no problems with accidentally deleting the + * wrong timer. Returns -1 on failure (which is guaranteed never to + * be a valid ). + */ + virtual long schedule_i (const TYPE& type, + const void* act, + const ACE_Time_Value& future_time, + const ACE_Time_Value& interval); + + void schedule_i(ACE_Timer_Node_T* n, const ACE_Time_Value& exp); + + ACE_Timer_Node_T* find_node(long timer_id) const; + + void cancel_i (ACE_Timer_Node_T* n); + + void unlink (ACE_Timer_Node_T* n); + + ACE_Timer_Node_T* get_first_i(void) const; + +private: + + /// Pointer to linked list of . + ACE_Timer_Node_T* head_; + + /// Iterator used to expire timers. + Iterator* iterator_; + + /** + * Keeps track of the timer id that uniquely identifies each timer. + * This id can be used to cancel a timer via the + * method. + */ + long id_counter_; + + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Timer_List_T (const ACE_Timer_List_T &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_List_T &)) +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Timer_List_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Timer_List_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_LIST_T_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Queue.h b/dep/ACE_wrappers/ace/Timer_Queue.h new file mode 100644 index 000000000..4644aa1b4 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue.h @@ -0,0 +1,52 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Queue.h + * + * $Id: Timer_Queue.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + * @author Irfan Pyarali + */ +//============================================================================= + +#ifndef ACE_TIMER_QUEUE_H +#define ACE_TIMER_QUEUE_H + +#include /**/ "ace/pre.h" + +#include "ace/Synch_Traits.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Timer_Queuefwd.h" +#include "ace/Timer_Queue_T.h" +#if defined (ACE_HAS_THREADS) +# include "ace/Recursive_Thread_Mutex.h" +#else +# include "ace/Null_Mutex.h" +#endif /* ACE_HAS_THREADS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The following typedef are here for ease of use and backward +// compatibility. +typedef ACE_Timer_Node_Dispatch_Info_T + ACE_Timer_Node_Dispatch_Info; + +typedef ACE_Timer_Node_T + ACE_Timer_Node; + +typedef ACE_Timer_Queue_Iterator_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_Queue_Iterator; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_TIMER_QUEUE_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Queue_Adapters.cpp b/dep/ACE_wrappers/ace/Timer_Queue_Adapters.cpp new file mode 100644 index 000000000..f6519ae9e --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue_Adapters.cpp @@ -0,0 +1,361 @@ +// $Id: Timer_Queue_Adapters.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMER_QUEUE_ADAPTERS_CPP +#define ACE_TIMER_QUEUE_ADAPTERS_CPP + +#include "ace/Timer_Queue_Adapters.h" + +#if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) +#include "ace/Functor.h" +#endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +# if !defined (__ACE_INLINE__) +# include "ace/Timer_Queue_Adapters.inl" +# endif /* __ACE_INLINE__ */ + +#include "ace/Signal.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_time.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template TQ & +ACE_Async_Timer_Queue_Adapter::timer_queue (void) +{ + return this->timer_queue_; +} + +template int +ACE_Async_Timer_Queue_Adapter::cancel (long timer_id, + const void **act) +{ + // Block designated signals. + ACE_Sig_Guard sg (&this->mask_); + ACE_UNUSED_ARG (sg); + + return this->timer_queue_.cancel (timer_id, act); +} + +template int +ACE_Async_Timer_Queue_Adapter::expire (void) +{ + // Block designated signals. + ACE_Sig_Guard sg (&this->mask_); + ACE_UNUSED_ARG (sg); + + return this->timer_queue_.expire (); +} + +template int +ACE_Async_Timer_Queue_Adapter::schedule_ualarm (void) +{ + ACE_Time_Value tv = this->timer_queue_.earliest_time () + - this->timer_queue_.gettimeofday (); + + // Beware of negative times and zero times (which cause problems for + // ). + if (tv < ACE_Time_Value::zero) + tv = ACE_Time_Value (0, 1); + + // @@ This code should be clever enough to avoid updating the + // if we haven't actually changed the earliest time. + // Schedule a new timer. + ACE_OS::ualarm (tv); + return 0; +} + +template long +ACE_Async_Timer_Queue_Adapter::schedule (ACE_Event_Handler *eh, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_UNUSED_ARG (act); + ACE_UNUSED_ARG (interval); + + // Block designated signals. + ACE_Sig_Guard sg (&this->mask_); + ACE_UNUSED_ARG (sg); + + // @@ We still need to implement interval timers... + long tid = this->timer_queue_.schedule (eh, act, future_time); + + if (tid == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("schedule_timer")), + -1); + + if (this->schedule_ualarm () == -1) + return 0; + + return tid; +} + +template +ACE_Async_Timer_Queue_Adapter::ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask) + // If == 0, block *all* signals when the SIGARLM handler is + // running, else just block those in the mask. + : mask_ (mask) +{ + // The following code is necessary to selectively "block" certain + // signals when SIGALRM is running. Also, we always restart system + // calls that are interrupted by the signals. + + ACE_Sig_Action sa ((ACE_SignalHandler) 0, + this->mask_, + SA_RESTART); + + if (this->sig_handler_.register_handler (SIGALRM, this, &sa) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("register_handler"))); +} + +// This is the signal handler function for the asynchronous timer +// list. It gets invoked asynchronously when the SIGALRM signal +// occurs. + +template int +ACE_Async_Timer_Queue_Adapter::handle_signal (int signum, + siginfo_t *, + ucontext_t *) +{ + switch (signum) + { + case SIGALRM: + { + // Expire the pending timers. + + // @@ We need to figure out how to implement interval + // timers... + this->timer_queue_.expire (); + + // Only schedule a new timer if there is one in the list. + + // @@ This code should also become smarter to avoid + // unnecessary calls to ualarm(). + if (this->timer_queue_.is_empty () == 0) + return this->schedule_ualarm (); + else + return 0; + /* NOTREACHED */ + } + default: + ACE_ERROR_RETURN ((LM_ERROR, + "unexpected signal %S\n", + signum), + -1); + /* NOTREACHED */ + } +} + +template +ACE_Thread_Timer_Queue_Adapter::ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager *tm, + TQ* timer_queue) + : ACE_Task_Base (tm), + timer_queue_(timer_queue), + delete_timer_queue_(false), + condition_ (mutex_), + active_ (true), // Assume that we start in active mode. + thr_id_ (ACE_OS::NULL_thread) +{ + if (timer_queue_ == 0) + { + ACE_NEW (this->timer_queue_, + TQ); + this->delete_timer_queue_ = true; + } +} + +template +ACE_Thread_Timer_Queue_Adapter::~ACE_Thread_Timer_Queue_Adapter (void) +{ + if (this->delete_timer_queue_) + { + delete this->timer_queue_; + this->timer_queue_ = 0; + this->delete_timer_queue_ = false; + } +} + +template ACE_SYNCH_RECURSIVE_MUTEX & +ACE_Thread_Timer_Queue_Adapter::mutex (void) +{ + return this->mutex_; +} + +template long +ACE_Thread_Timer_Queue_Adapter::schedule + (ACE_Event_Handler* handler, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1); + + long result = this->timer_queue_->schedule (handler, act, future_time, interval); + this->condition_.signal (); + return result; +} + +template int +ACE_Thread_Timer_Queue_Adapter::cancel (long timer_id, + const void **act) +{ + ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1); + + int result = this->timer_queue_->cancel (timer_id, act); + condition_.signal (); + return result; +} + +template void +ACE_Thread_Timer_Queue_Adapter::deactivate (void) +{ + ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_); + + this->active_ = false; + this->condition_.signal (); +} + +template int +ACE_Thread_Timer_Queue_Adapter::svc (void) +{ + ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1); + + this->thr_id_ = ACE_Thread::self (); + + // Thread cancellation point, if ACE supports it. + // + // Note: This call generates a warning under Solaris because the header + // file /usr/include/pthread.h redefines the routine argument. This + // is a bug in the Solaris header files and has nothing to do with + // ACE. +# if !defined (ACE_LACKS_PTHREAD_CANCEL) + ACE_PTHREAD_CLEANUP_PUSH (&this->condition_.mutex ().get_nesting_mutex ()); +# endif /* ACE_LACKS_PTHREAD_CANCEL */ + + while (this->active_) + { +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + // Temporarily suspend ownership of the timer queue mutex in + // order to dispatch deferred execution commands. These + // commands are to be treated as executing in a context + // "external" to the timer queue adapter, and thus must compete + // separately for this lock. + mutex_.release (); + this->dispatch_commands (); + + // Re-acquire ownership of the timer queue mutex in order to + // restore the "internal" timer queue adapter context + mutex_.acquire (); +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + + // If the queue is empty, sleep until there is a change on it. + if (this->timer_queue_->is_empty ()) + this->condition_.wait (); + else + { + // Compute the remaining time, being careful not to sleep + // for "negative" amounts of time. + ACE_Time_Value const tv_curr = this->timer_queue_->gettimeofday (); + ACE_Time_Value const tv_earl = this->timer_queue_->earliest_time (); + + if (tv_earl > tv_curr) + { + // The earliest time on the Timer_Queue is in future, so + // use ACE_OS::gettimeofday() to convert the tv to the + // absolute time. + ACE_Time_Value const tv = ACE_OS::gettimeofday () + (tv_earl - tv_curr); + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("waiting until %u.%3.3u secs\n"), + // tv.sec(), tv.msec())); + this->condition_.wait (&tv); + } + } + + // Expire timers anyway, at worst this is a no-op. + this->timer_queue_->expire (); + } + + // Thread cancellation point, if ACE supports it. +# if !defined (ACE_LACKS_PTHREAD_CANCEL) + ACE_PTHREAD_CLEANUP_POP (0); +# endif /* ACE_LACKS_PTHREAD_CANCEL */ + + return 0; +} + +template int +ACE_Thread_Timer_Queue_Adapter::activate (long flags, + int , + int , + long priority, + int grp_id, + ACE_Task_Base *task, + ACE_hthread_t [], + void *stack[], + size_t stack_size[], + ACE_thread_t thread_ids[], + const char* thr_name[]) +{ + // Make sure to set this flag in case we were deactivated earlier. + this->active_ = true; + + // Make sure that we only allow a single thread to be spawned for + // our adapter. Otherwise, too many weird things can happen. + return ACE_Task_Base::activate (flags, 1, 0, priority, grp_id, task, 0, + stack, stack_size, thread_ids, thr_name); +} + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + +// Enqueues a command object for execution just before waiting on the next +// timer event. This allows deferred execution of commands that cannot +// be performed in the timer event handler context, such as registering +// or cancelling timers on platforms where the timer queue mutex is not +// recursive. + +template int +ACE_Thread_Timer_Queue_Adapter::enqueue_command (ACE_Command_Base *cmd, + COMMAND_ENQUEUE_POSITION pos) +{ + // Serialize access to the command queue. + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->command_mutex_, -1); + + if (pos == ACE_Thread_Timer_Queue_Adapter::TAIL) + return command_queue_.enqueue_tail (cmd); + else + return command_queue_.enqueue_head (cmd); +} + +// Dispatches all command objects enqueued in the most recent event +// handler context. + +template int +ACE_Thread_Timer_Queue_Adapter::dispatch_commands (void) +{ + // Serialize access to the command queue. + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->command_mutex_, -1); + + // loop through the enqueued commands + ACE_Command_Base *cmd = 0; + while (command_queue_.dequeue_head (cmd) == 0) + if (cmd) + { + cmd->execute (); + delete cmd; + } + + return 0; +} + +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TIMER_QUEUE_ADAPTERS_CPP */ diff --git a/dep/ACE_wrappers/ace/Timer_Queue_Adapters.h b/dep/ACE_wrappers/ace/Timer_Queue_Adapters.h new file mode 100644 index 000000000..e6ef944ea --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue_Adapters.h @@ -0,0 +1,261 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Queue_Adapters.h + * + * $Id: Timer_Queue_Adapters.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt and + * Carlos O'Ryan + */ +//============================================================================= + +#ifndef ACE_TIMER_QUEUE_ADAPTERS_H +#define ACE_TIMER_QUEUE_ADAPTERS_H +#include /**/ "ace/pre.h" + +#include "ace/Task.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Signal.h" +#include "ace/Sig_Handler.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" + +#if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) +# include "ace/Unbounded_Queue.h" +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Command_Base; +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Sig_Set; + +/** + * @class ACE_Async_Timer_Queue_Adapter + * + * @brief Adapts an ACE timer queue to be driven asynchronously using signals. + * + * This implementation uses the ACE_OS::ualarm call, to generate + * the SIGARLM signal that is caught by this class. + * + * @note This adapter only works on platforms that support ualarm(). + * POSIX platforms generally do; Windows and some others do not. + * + * @todo This adapter does not automatically reschedule repeating timers. + */ +template +class ACE_Async_Timer_Queue_Adapter : public ACE_Event_Handler +{ +public: + typedef TQ TIMER_QUEUE; + + /// Constructor + /** + * Register the SIGALRM handler. If @a mask == 0 then block all + * signals when @c SIGALRM is run. Otherwise, just block the signals + * indicated in @a mask. + */ + ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask = 0); + + /// Schedule the timer according to the semantics of the + /// ACE_Timer_List. + /** + * This timer gets dispatched via a signal, rather than by a user + * calling expire(). Note that interval timers are not implemented + * yet. + */ + long schedule (ACE_Event_Handler *type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /// Cancel the @a timer_id and pass back the @a act if an address is + /// passed in. + int cancel (long timer_id, const void **act = 0); + + /// Dispatch all timers with expiry time at or before the current time. + /// Returns the number of timers expired. + int expire (void); + + /// Return a reference to the underlying timer queue. + TQ &timer_queue (void); + +private: + /// Perform the logic to compute the new ualarm(2) setting. + virtual int schedule_ualarm (void); + + /// Called back by @c SIGALRM handler. + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + /// Handler for the @c SIGALRM signal, so that we can access our state + /// without requiring any global variables. + ACE_Sig_Handler sig_handler_; + + /// Implementation of the timer queue (e.g., ACE_Timer_List, + /// ACE_Timer_Heap, etc.). + TQ timer_queue_; + + /// Mask of signals to be blocked when we're servicing @c SIGALRM. + ACE_Sig_Set mask_; +}; + +/** + * @class ACE_Thread_Timer_Queue_Adapter + * + * @brief Adapts an ACE timer queue using a separate thread for dispatching. + * + * This implementation uses a separate thread to dispatch the timers. + * The base queue need not be thread safe; this class takes all the + * necessary locks. + * + * @note This is a case where template parameters will be useful, but + * (IMHO) the effort and portability problems discourage their + * use. + * + */ +template +class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base +{ +public: + /// Trait for the underlying queue type. + typedef TQ TIMER_QUEUE; + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + + /// Typedef for the position at which to enqueue a deferred + /// execution command. + enum COMMAND_ENQUEUE_POSITION {HEAD, TAIL}; + +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + + /// Creates the timer queue. Activation of the task is the user's + /// responsibility. Optionally a pointer to a timer queue can be passed, + /// when no pointer is passed, a TQ is dynamically created + ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager * = ACE_Thread_Manager::instance (), + TQ* timer_queue = 0); + + /// Destructor. + virtual ~ACE_Thread_Timer_Queue_Adapter (void); + + /// Schedule the timer according to the semantics of the ; wakes + /// up the dispatching thread. + long schedule (ACE_Event_Handler *handler, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /// Cancel the @a timer_id and return the @a act parameter if an + /// address is passed in. Also wakes up the dispatching thread. + int cancel (long timer_id, const void **act = 0); + + /// Runs the dispatching thread. + virtual int svc (void); + + /// Inform the dispatching thread that it should terminate. + virtual void deactivate (void); + + /// Access the locking mechanism, useful for iteration. + ACE_SYNCH_RECURSIVE_MUTEX &mutex (void); + + /// Set a user-specified timer queue. + int timer_queue (TQ *tq); + + /// Return the current . + TQ *timer_queue (void) const; + + /// Return the thread id of our active object. + ACE_thread_t thr_id (void) const; + + /** + * We override the default activate() method so that we can ensure + * that only a single thread is ever spawned. Otherwise, too many + * weird things can happen... + */ + virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE, + int n_threads = 1, + int force_active = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_thread_t thread_ids[] = 0, + const char* thr_name[] = 0); + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + + /** + * Enqueues a command object for execution just before waiting on the next + * timer event. This allows deferred execution of commands that cannot + * be performed in the timer event handler context, such as registering + * or cancelling timers on platforms where the timer queue mutex is not + * recursive. + */ + int enqueue_command (ACE_Command_Base *command_, + COMMAND_ENQUEUE_POSITION pos = TAIL); + +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + +private: + +# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS) + /// Dispatches all command objects enqueued in the most + /// recent event handler context. + int dispatch_commands (void); + + /// Queue of commands for deferred execution. + ACE_Unbounded_Queue command_queue_; + + /// The mutual exclusion mechanism for the command queue. + ACE_SYNCH_MUTEX command_mutex_; +# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */ + + /// The underlying Timer_Queue. + TQ* timer_queue_; + + /// Keeps track of whether we should delete the timer queue (if we + /// didn't create it, then we don't delete it). + bool delete_timer_queue_; + + /// The mutual exclusion mechanism that is required to use the + /// . + ACE_SYNCH_RECURSIVE_MUTEX mutex_; + + /** + * The dispatching thread sleeps on this condition while waiting to + * dispatch the next timer; it is used to wake it up if there is a + * change on the timer queue. + */ + ACE_SYNCH_RECURSIVE_CONDITION condition_; + + /// When deactivate is called this variable turns to false and the + /// dispatching thread is signalled, to terminate its main loop. + bool active_; + + /// Thread id of our active object task. + ACE_thread_t thr_id_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "ace/Timer_Queue_Adapters.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +# include "ace/Timer_Queue_Adapters.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +# pragma implementation ("Timer_Queue_Adapters.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_QUEUE_ADAPTERS_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Queue_Adapters.inl b/dep/ACE_wrappers/ace/Timer_Queue_Adapters.inl new file mode 100644 index 000000000..77011eacf --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue_Adapters.inl @@ -0,0 +1,29 @@ +// -*- C++ -*- +// +// $Id: Timer_Queue_Adapters.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE TQ * +ACE_Thread_Timer_Queue_Adapter::timer_queue (void) const +{ + return this->timer_queue_; +} + +template ACE_INLINE int +ACE_Thread_Timer_Queue_Adapter::timer_queue (TQ *tq) +{ + if (this->delete_timer_queue_) + delete this->timer_queue_; + this->timer_queue_ = tq; + this->delete_timer_queue_ = false; + return 0; +} + +template ACE_INLINE ACE_thread_t +ACE_Thread_Timer_Queue_Adapter::thr_id (void) const +{ + return this->thr_id_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Timer_Queue_T.cpp b/dep/ACE_wrappers/ace/Timer_Queue_T.cpp new file mode 100644 index 000000000..58fbf9ad3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue_T.cpp @@ -0,0 +1,481 @@ +// $Id: Timer_Queue_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMER_QUEUE_T_CPP +#define ACE_TIMER_QUEUE_T_CPP + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/* + * Hook to specialize to add includes + */ +//@@ REACTOR_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK + +#include "ace/Timer_Queue_T.h" +#include "ace/Guard_T.h" +#include "ace/Log_Msg.h" +#include "ace/Reactor_Timer_Interface.h" +#include "ace/Null_Mutex.h" +#include "ace/OS_NS_sys_time.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Timer_Queue_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// This fudge factor can be overriden for timers that need it, such as on +// Solaris, by defining the ACE_TIMER_SKEW symbol in the appropriate config +// header. +#if !defined (ACE_TIMER_SKEW) +# define ACE_TIMER_SKEW 0 +#endif /* ACE_TIMER_SKEW */ + +template void +ACE_Timer_Node_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Timer_Node_T::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nact_ = %x"), this->act_)); + this->timer_value_.dump (); + this->interval_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nprev_ = %x"), this->prev_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnext_ = %x"), this->next_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_id_ = %d\n"), this->timer_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Timer_Node_T::ACE_Timer_Node_T (void) +{ + ACE_TRACE ("ACE_Timer_Node_T::ACE_Timer_Node_T"); +} + +template +ACE_Timer_Node_T::~ACE_Timer_Node_T (void) +{ + ACE_TRACE ("ACE_Timer_Node_T::~ACE_Timer_Node_T"); +} + +template +ACE_Timer_Queue_Iterator_T::ACE_Timer_Queue_Iterator_T (void) +{ +} + +template +ACE_Timer_Queue_Iterator_T::~ACE_Timer_Queue_Iterator_T (void) +{ +} + +template ACE_Time_Value * +ACE_Timer_Queue_T::calculate_timeout (ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, max_wait_time)); + + if (this->is_empty ()) + // Nothing on the Timer_Queue, so use whatever the caller gave us. + return max_wait_time; + else + { + ACE_Time_Value const cur_time = this->gettimeofday (); + + if (this->earliest_time () > cur_time) + { + // The earliest item on the Timer_Queue is still in the + // future. Therefore, use the smaller of (1) caller's wait + // time or (2) the delta time between now and the earliest + // time on the Timer_Queue. + + this->timeout_ = this->earliest_time () - cur_time; + if (max_wait_time == 0 || *max_wait_time > timeout_) + return &this->timeout_; + else + return max_wait_time; + } + else + { + // The earliest item on the Timer_Queue is now in the past. + // Therefore, we've got to "poll" the Reactor, i.e., it must + // just check the descriptors and then dispatch timers, etc. + this->timeout_ = ACE_Time_Value::zero; + return &this->timeout_; + } + } +} + +template ACE_Time_Value * +ACE_Timer_Queue_T::calculate_timeout (ACE_Time_Value *max_wait_time, + ACE_Time_Value *the_timeout) +{ + ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout"); + + if (the_timeout == 0) + return 0; + + if (this->is_empty ()) + { + // Nothing on the Timer_Queue, so use whatever the caller gave us. + if (max_wait_time) + *the_timeout = *max_wait_time; + else + return 0; + } + else + { + ACE_Time_Value cur_time = this->gettimeofday (); + + if (this->earliest_time () > cur_time) + { + // The earliest item on the Timer_Queue is still in the + // future. Therefore, use the smaller of (1) caller's wait + // time or (2) the delta time between now and the earliest + // time on the Timer_Queue. + + *the_timeout = this->earliest_time () - cur_time; + if (!(max_wait_time == 0 || *max_wait_time > *the_timeout)) + *the_timeout = *max_wait_time; + } + else + { + // The earliest item on the Timer_Queue is now in the past. + // Therefore, we've got to "poll" the Reactor, i.e., it must + // just check the descriptors and then dispatch timers, etc. + *the_timeout = ACE_Time_Value::zero; + } + } + return the_timeout; +} + +template void +ACE_Timer_Queue_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Timer_Queue_T::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->timeout_.dump (); + this->timer_skew_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Timer_Queue_T::ACE_Timer_Queue_T (FUNCTOR *upcall_functor, + ACE_Free_List > *freelist) + : gettimeofday_ (ACE_OS::gettimeofday), + delete_upcall_functor_ (upcall_functor == 0), + delete_free_list_ (freelist == 0), + timer_skew_ (0, ACE_TIMER_SKEW) +{ + ACE_TRACE ("ACE_Timer_Queue_T::ACE_Timer_Queue_T"); + + if (!freelist) + ACE_NEW (free_list_, + (ACE_Locked_Free_List,ACE_Null_Mutex>)); + else + free_list_ = freelist; + + if (!upcall_functor) + ACE_NEW (upcall_functor_, + FUNCTOR); + else + upcall_functor_ = upcall_functor; +} + +template +ACE_Timer_Queue_T::~ACE_Timer_Queue_T (void) +{ + ACE_TRACE ("ACE_Timer_Queue_T::~ACE_Timer_Queue_T"); + + // Cleanup the functor and free_list on the way out + if (this->delete_upcall_functor_) + delete this->upcall_functor_; + + if (this->delete_free_list_) + delete this->free_list_; +} + +template ACE_Timer_Node_T * +ACE_Timer_Queue_T::alloc_node (void) +{ + return this->free_list_->remove (); +} + +template void +ACE_Timer_Queue_T::free_node (ACE_Timer_Node_T *node) +{ + this->free_list_->add (node); +} + +template ACE_LOCK & +ACE_Timer_Queue_T::mutex (void) +{ + return this->mutex_; +} + +template long +ACE_Timer_Queue_T::schedule (const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + // Schedule the timer. + long const result = + this->schedule_i (type, + act, + future_time, + interval); + + // Return on failure. + if (result == -1) + return result; + + // Inform upcall functor of successful registration. + this->upcall_functor ().registration (*this, + type, + act); + + // Return result; + return result; +} + +// Run the method for all Timers whose values are <= +// . +template int +ACE_Timer_Queue_T::expire (const ACE_Time_Value &cur_time) +{ + ACE_TRACE ("ACE_Timer_Queue_T::expire"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + // Keep looping while there are timers remaining and the earliest + // timer is <= the passed in to the method. + + if (this->is_empty ()) + return 0; + + int number_of_timers_expired = 0; + int result = 0; + + ACE_Timer_Node_Dispatch_Info_T info; + + while ((result = this->dispatch_info_i (cur_time, info)) != 0) + { + const void *upcall_act = 0; + + this->preinvoke (info, cur_time, upcall_act); + + this->upcall (info, cur_time); + + this->postinvoke (info, cur_time, upcall_act); + + ++number_of_timers_expired; + + } + + ACE_UNUSED_ARG (result); + return number_of_timers_expired; +} + +template int +ACE_Timer_Queue_T::dispatch_info_i (const ACE_Time_Value &cur_time, + ACE_Timer_Node_Dispatch_Info_T &info) +{ + ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info_i"); + + if (this->is_empty ()) + return 0; + + ACE_Timer_Node_T *expired = 0; + + if (this->earliest_time () <= cur_time) + { + expired = this->remove_first (); + + // Get the dispatch info + expired->get_dispatch_info (info); + + // Check if this is an interval timer. + if (expired->get_interval () > ACE_Time_Value::zero) + { + // Make sure that we skip past values that have already + // "expired". + do + expired->set_timer_value (expired->get_timer_value () + + expired->get_interval ()); + while (expired->get_timer_value () <= cur_time); + + // Since this is an interval timer, we need to reschedule + // it. + this->reschedule (expired); + } + else + { + // Call the factory method to free up the node. + this->free_node (expired); + } + + return 1; + } + + return 0; +} + +template void +ACE_Timer_Queue_T::return_node (ACE_Timer_Node_T *node) +{ + ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_)); + this->free_node (node); +} + + +template +ACE_Event_Handler_Handle_Timeout_Upcall::ACE_Event_Handler_Handle_Timeout_Upcall (void) +{ +} + +template +ACE_Event_Handler_Handle_Timeout_Upcall::~ACE_Event_Handler_Handle_Timeout_Upcall (void) +{ +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::registration (TIMER_QUEUE &, + ACE_Event_Handler *event_handler, + const void *) +{ + event_handler->add_reference (); + return 0; +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::preinvoke (TIMER_QUEUE & /* timer_queue */, + ACE_Event_Handler *event_handler, + const void * /* timer_act */, + int /* recurring_timer */, + const ACE_Time_Value & /* cur_time */, + const void *&upcall_act) +{ + bool const requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + if (requires_reference_counting) + { + event_handler->add_reference (); + + upcall_act = &this->requires_reference_counting_; + } + + return 0; +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::postinvoke (TIMER_QUEUE & /* timer_queue */, + ACE_Event_Handler *event_handler, + const void * /* timer_act */, + int /* recurring_timer */, + const ACE_Time_Value & /* cur_time */, + const void *upcall_act) +{ + if (upcall_act == &this->requires_reference_counting_) + { + event_handler->remove_reference (); + } + + return 0; +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::timeout (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *event_handler, + const void *act, + int recurring_timer, + const ACE_Time_Value &cur_time) +{ + int requires_reference_counting = 0; + + if (!recurring_timer) + { + requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + } + + // Upcall to the s handle_timeout method. + if (event_handler->handle_timeout (cur_time, act) == -1) + { + if (event_handler->reactor_timer_interface ()) + event_handler->reactor_timer_interface ()->cancel_timer (event_handler, 0); + else + timer_queue.cancel (event_handler, 0); // 0 means "call handle_close()". + } + + if (!recurring_timer && + requires_reference_counting) + { + event_handler->remove_reference (); + } + + return 0; +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::cancel_type (TIMER_QUEUE &, + ACE_Event_Handler *event_handler, + int dont_call, + int &requires_reference_counting) +{ + requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + // Upcall to the s handle_close method + if (dont_call == 0) + event_handler->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::TIMER_MASK); + + return 0; +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::cancel_timer (TIMER_QUEUE &, + ACE_Event_Handler *event_handler, + int, + int requires_reference_counting) +{ + if (requires_reference_counting) + event_handler->remove_reference (); + + return 0; +} + +template int +ACE_Event_Handler_Handle_Timeout_Upcall::deletion (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *event_handler, + const void *) +{ + int requires_reference_counting = 0; + + this->cancel_type (timer_queue, + event_handler, + 0, + requires_reference_counting); + + this->cancel_timer (timer_queue, + event_handler, + 0, + requires_reference_counting); + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TIMER_QUEUE_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Timer_Queue_T.h b/dep/ACE_wrappers/ace/Timer_Queue_T.h new file mode 100644 index 000000000..591109c17 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue_T.h @@ -0,0 +1,562 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Queue_T.h + * + * $Id: Timer_Queue_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + * @author Irfan Pyarali and + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_TIMER_QUEUE_T_H +#define ACE_TIMER_QUEUE_T_H +#include /**/ "ace/pre.h" + +#include "ace/Free_List.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event_Handler.h" +#include "ace/Time_Value.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Timer_Node_Dispatch_Info_T + * + * @brief Maintains generated dispatch information for Timer nodes. + * + */ +template +class ACE_Timer_Node_Dispatch_Info_T +{ +public: + /// The type of object held in the queue + TYPE type_; + + /// Asynchronous completion token associated with the timer. + const void *act_; + + /// Flag to check if the timer is recurring. + int recurring_timer_; +}; + +/** + * @class ACE_Timer_Node_T + * + * @brief Maintains the state associated with a Timer entry. + */ +template +class ACE_Timer_Node_T +{ +public: + /// Default constructor + ACE_Timer_Node_T (void); + + /// Destructor + ~ACE_Timer_Node_T (void); + + /// Useful typedef .. + typedef ACE_Timer_Node_Dispatch_Info_T DISPATCH_INFO; + + /// Singly linked list + void set (const TYPE &type, + const void *a, + const ACE_Time_Value &t, + const ACE_Time_Value &i, + ACE_Timer_Node_T *n, + long timer_id); + + /// Doubly linked list version + void set (const TYPE &type, + const void *a, + const ACE_Time_Value &t, + const ACE_Time_Value &i, + ACE_Timer_Node_T *p, + ACE_Timer_Node_T *n, + long timer_id); + + // = Accessors + + /// Get the type. + TYPE &get_type (void); + + /// Set the type. + void set_type (TYPE &type); + + /// Get the asynchronous completion token. + const void *get_act (void); + + /// Set the asynchronous completion token. + void set_act (void *act); + + /// Get the timer value. + const ACE_Time_Value &get_timer_value (void) const; + + /// Set the timer value. + void set_timer_value (const ACE_Time_Value &timer_value); + + /// Get the timer interval. + const ACE_Time_Value &get_interval (void) const; + + /// Set the timer interval. + void set_interval (const ACE_Time_Value &interval); + + /// Get the previous pointer. + ACE_Timer_Node_T *get_prev (void); + + /// Set the previous pointer. + void set_prev (ACE_Timer_Node_T *prev); + + /// Get the next pointer. + ACE_Timer_Node_T *get_next (void); + + /// Set the next pointer. + void set_next (ACE_Timer_Node_T *next); + + /// Get the timer_id. + long get_timer_id (void) const; + + /// Set the timer_id. + void set_timer_id (long timer_id); + + /// Get the dispatch info. The dispatch information is got + /// through . This form helps us in preventing allocation and + /// deleting data along the criticl path. + /// @@TODO: We may want to have a copying version too, so that our + /// interface will be complete.. + void get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T &info); + + /// Dump the state of an TYPE. + void dump (void) const; + +private: + /// Type of object stored in the Queue + TYPE type_; + + /// Asynchronous completion token associated with the timer. + const void *act_; + + /// Time until the timer expires. + ACE_Time_Value timer_value_; + + /// If this is a periodic timer this holds the time until the next + /// timeout. + ACE_Time_Value interval_; + + /// Pointer to previous timer. + ACE_Timer_Node_T *prev_; + + /// Pointer to next timer. + ACE_Timer_Node_T *next_; + + /// Id of this timer (used to cancel timers before they expire). + long timer_id_; +}; + +/** + * @class ACE_Timer_Queue_Iterator_T + * + * @brief Generic interface for iterating over a subclass of + * ACE_Timer_Queue. + * + * This is a generic iterator that can be used to visit every + * node of a timer queue. Be aware that it isn't guaranteed + * that the transversal will be in order of timeout values. + */ +template +class ACE_Timer_Queue_Iterator_T +{ +public: + // = Initialization and termination methods. + /// Constructor. + ACE_Timer_Queue_Iterator_T (void); + + /// Destructor. + virtual ~ACE_Timer_Queue_Iterator_T (void); + + /// Positions the iterator at the earliest node in the Timer Queue + virtual void first (void) = 0; + + /// Positions the iterator at the next node in the Timer Queue + virtual void next (void) = 0; + + /// Returns true when there are no more nodes in the sequence + virtual bool isdone (void) const = 0; + + /// Returns the node at the current position in the sequence + virtual ACE_Timer_Node_T *item (void) = 0; +}; + +/** + * @class ACE_Timer_Queue_T + * + * @brief Provides an interface to timers. + * + * This is an abstract base class that provides hook for + * implementing specialized policies such as ACE_Timer_List + * and ACE_Timer_Heap. + */ +template +class ACE_Timer_Queue_T +{ +public: + /// Type of Iterator. + typedef ACE_Timer_Queue_Iterator_T ITERATOR; + + // = Initialization and termination methods. + /** + * Default constructor. @a upcall_functor is the instance of the + * FUNCTOR to be used by the queue. If @a upcall_functor is 0, Timer + * Queue will create a default FUNCTOR. @a freelist the freelist of + * timer nodes. If 0, then a default freelist will be created. + */ + ACE_Timer_Queue_T (FUNCTOR *upcall_functor = 0, + ACE_Free_List > *freelist = 0); + + /// Destructor - make virtual for proper destruction of inherited + /// classes. + virtual ~ACE_Timer_Queue_T (void); + + /// True if queue is empty, else false. + virtual bool is_empty (void) const = 0; + + /// Returns the time of the earlier node in the Timer_Queue. Must + /// be called on a non-empty queue. + virtual const ACE_Time_Value &earliest_time (void) const = 0; + + /** + * Schedule @a type that will expire at @a future_time, which is + * specified in absolute time. If it expires then @a act is passed + * in as the value to the . If @a interval is != to + * ACE_Time_Value::zero then it is used to reschedule the @a type + * automatically, using relative time to the current . + * This method returns a that uniquely identifies the the + * @a type entry in an internal list. This can be used to + * cancel the timer before it expires. The cancellation ensures + * that are unique up to values of greater than 2 + * billion timers. As long as timers don't stay around longer than + * this there should be no problems with accidentally deleting the + * wrong timer. Returns -1 on failure (which is guaranteed never to + * be a valid ). + */ + virtual long schedule (const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /** + * Resets the interval of the timer represented by @a timer_id to + * @a interval, which is specified in relative time to the current + * . If @a interval is equal to + * ACE_Time_Value::zero, the timer will become a non-rescheduling + * timer. Returns 0 if successful, -1 if not. + */ + virtual int reset_interval (long timer_id, + const ACE_Time_Value &interval) = 0; + + /** + * Cancel all timer associated with @a type. If + * @a dont_call_handle_close is 0 then the will be invoked, + * which typically invokes the hook. Returns number + * of timers cancelled. + */ + virtual int cancel (const TYPE &type, + int dont_call_handle_close = 1) = 0; + + /** + * Cancel the single timer that matches the @a timer_id value (which + * was returned from the method). If act is non-NULL + * then it will be set to point to the ``magic cookie'' argument + * passed in when the timer was registered. This makes it possible + * to free up the memory and avoid memory leaks. If + * @a dont_call_handle_close is 0 then the will be invoked, + * which typically calls the hook. Returns 1 if + * cancellation succeeded and 0 if the @a timer_id wasn't found. + */ + virtual int cancel (long timer_id, + const void **act = 0, + int dont_call_handle_close = 1) = 0; + + /** + * Run the for all timers whose values are <= @a current_time. + * This does not account for . Returns the number of + * timers canceled. + */ + virtual int expire (const ACE_Time_Value ¤t_time); + + /** + * Get the dispatch information for a timer whose value is <= @a current_time. + * This does not account for . Returns 1 if + * there is a node whose value <= @a current_time else returns a 0. + * + */ + virtual int dispatch_info (const ACE_Time_Value ¤t_time, + ACE_Timer_Node_Dispatch_Info_T &info); + + /** + * Run the for all timers whose values are <= + * . Also accounts for . + * + * Depending on the resolution of the underlying OS the system calls + * like select()/poll() might return at time different than that is + * specified in the timeout. Suppose the OS guarantees a resolution of t ms. + * The timeline will look like + * + * A B + * | | + * V V + * |-------------|-------------|-------------|-------------| + * t t t t t + * + * + * If you specify a timeout value of A, then the timeout will not occur + * at A but at the next interval of the timer, which is later than + * that is expected. Similarly, if your timeout value is equal to B, + * then the timeout will occur at interval after B. Now depending upon the + * resolution of your timeouts and the accuracy of the timeouts + * needed for your application, you should set the value of + * . In the above case, if you want the timeout A to fire + * no later than A, then you should specify your to be + * A % t. + * + * The timeout value should be specified via the macro ACE_TIMER_SKEW + * in your config.h file. The default value is zero. + * + * Things get interesting if the t before the timeout value B is zero + * i.e your timeout is less than the interval. In that case, you are + * almost sure of not getting the desired timeout behaviour. Maybe you + * should look for a better OS :-) + * + * Returns the number of timers canceled. + */ + + /* virtual */ int expire (void); + + /** + * Returns the current time of day. This method allows different + * implementations of the timer queue to use special high resolution + * timers. + */ + /* virtual */ ACE_Time_Value gettimeofday (void); + + /// Allows applications to control how the timer queue gets the time + /// of day. + void gettimeofday (ACE_Time_Value (*gettimeofday)(void)); + + /// Determine the next event to timeout. Returns @a max if there are + /// no pending timers or if all pending timers are longer than max. + /// This method acquires a lock internally since it modifies internal state. + virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max); + + /** + * Determine the next event to timeout. Returns @a max if there are + * no pending timers or if all pending timers are longer than max. + * should be a pointer to storage for the timeout value, + * and this value is also returned. This method does not acquire a + * lock internally since it doesn't modify internal state. If you + * need to call this method when the queue is being modified + * concurrently, however, you should make sure to acquire the + * externally before making the call. + */ + virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max, + ACE_Time_Value *the_timeout); + + /// Set the timer skew for the Timer_Queue. + void timer_skew (const ACE_Time_Value &skew); + + /// Get the timer skew for the Timer_Queue. + const ACE_Time_Value &timer_skew (void) const; + + /// Synchronization variable used by the queue + ACE_LOCK &mutex (void); + + /// Accessor to the upcall functor + FUNCTOR &upcall_functor (void); + + /// Returns a pointer to this ACE_Timer_Queue's iterator. + virtual ITERATOR &iter (void) = 0; + + /// Removes the earliest node from the queue and returns it + virtual ACE_Timer_Node_T *remove_first (void) = 0; + + /// Dump the state of a object. + virtual void dump (void) const; + + /// Reads the earliest node from the queue and returns it. + virtual ACE_Timer_Node_T *get_first (void) = 0; + + /// Method used to return a timer node to the queue's ownership + /// after it is returned by a method like . + virtual void return_node (ACE_Timer_Node_T *); + + /// This method will call the preinvoke() on . + void preinvoke (ACE_Timer_Node_Dispatch_Info_T &info, + const ACE_Time_Value &cur_time, + const void *&upcall_act); + + /// This method will call the timeout() on . + void upcall (ACE_Timer_Node_Dispatch_Info_T &info, + const ACE_Time_Value &cur_time); + + /// This method will call the postinvoke() on . + void postinvoke (ACE_Timer_Node_Dispatch_Info_T &info, + const ACE_Time_Value &cur_time, + const void *upcall_act); + +protected: + + /// Schedule a timer. + virtual long schedule_i (const TYPE &type, + const void *act, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) = 0; + + /// Reschedule an "interval" ACE_Timer_Node. + virtual void reschedule (ACE_Timer_Node_T *) = 0; + + /// Factory method that allocates a new node. + virtual ACE_Timer_Node_T *alloc_node (void); + + /// Factory method that frees a previously allocated node. + virtual void free_node (ACE_Timer_Node_T *); + + /// Non-locking version of dispatch_info () + virtual int dispatch_info_i (const ACE_Time_Value ¤t_time, + ACE_Timer_Node_Dispatch_Info_T &info); + + /// Synchronization variable for ACE_Timer_Queue. + /// @note The right name would be lock_, but HP/C++ will choke on that! + ACE_LOCK mutex_; + + /// Class that implements a free list + ACE_Free_List > *free_list_; + + /// Pointer to function that returns the current time of day. + ACE_Time_Value (*gettimeofday_)(void); + + /// Upcall functor + FUNCTOR *upcall_functor_; + + /// To delete or not to delete is the question? + bool const delete_upcall_functor_; + + /// Flag to delete only if the class created the + bool const delete_free_list_; + +private: + + /// Returned by . + ACE_Time_Value timeout_; + + /// Adjusts for timer skew in various clocks. + ACE_Time_Value timer_skew_; + + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Queue_T (const ACE_Timer_Queue_T &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Queue_T &)) +}; + +/** + * @class ACE_Event_Handler_Handle_Timeout_Upcall + * + * @brief Functor for Timer_Queues. + * + * This class implements the functor required by the Timer + * Queue to call on ACE_Event_Handlers. + */ +template +class ACE_Event_Handler_Handle_Timeout_Upcall +{ +public: + typedef ACE_Timer_Queue_T, + ACE_LOCK> + TIMER_QUEUE; + + // = Initialization and termination methods. + /// Constructor. + ACE_Event_Handler_Handle_Timeout_Upcall (void); + + /// Destructor. + ~ACE_Event_Handler_Handle_Timeout_Upcall (void); + + /// This method is called when a timer is registered. + int registration (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg); + + /// This method is called before the timer expires. + int preinvoke (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time, + const void *&upcall_act); + + /// This method is called when the timer expires. + int timeout (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time); + + /// This method is called after the timer expires. + int postinvoke (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg, + int recurring_timer, + const ACE_Time_Value &cur_time, + const void *upcall_act); + + /// This method is called when a handler is cancelled + int cancel_type (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + int dont_call, + int &requires_reference_counting); + + /// This method is called when a timer is cancelled + int cancel_timer (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + int dont_call, + int requires_reference_counting); + + /// This method is called when the timer queue is destroyed and + /// the timer is still contained in it + int deletion (TIMER_QUEUE &timer_queue, + ACE_Event_Handler *handler, + const void *arg); + +private: + + /// Flag indicating that reference counting is required for this + /// event handler upcall. + int requires_reference_counting_; + + // = Don't allow these operations for now. + ACE_UNIMPLEMENTED_FUNC (ACE_Event_Handler_Handle_Timeout_Upcall (const ACE_Event_Handler_Handle_Timeout_Upcall &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Event_Handler_Handle_Timeout_Upcall &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Timer_Queue_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Timer_Queue_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Timer_Queue_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_QUEUE_T_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Queue_T.inl b/dep/ACE_wrappers/ace/Timer_Queue_T.inl new file mode 100644 index 000000000..7606a2e1f --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queue_T.inl @@ -0,0 +1,222 @@ +// -*- C++ -*- +// +// $Id: Timer_Queue_T.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE void +ACE_Timer_Node_T::set (const TYPE &type, + const void *a, + const ACE_Time_Value &t, + const ACE_Time_Value &i, + ACE_Timer_Node_T *n, + long timer_id) +{ + this->type_ = type; + this->act_ = a; + this->timer_value_ = t; + this->interval_ = i; + this->next_ = n; + this->timer_id_ = timer_id; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set (const TYPE &type, + const void *a, + const ACE_Time_Value &t, + const ACE_Time_Value &i, + ACE_Timer_Node_T *p, + ACE_Timer_Node_T *n, + long timer_id) +{ + this->type_ = type; + this->act_ = a; + this->timer_value_ = t; + this->interval_ = i; + this->prev_ = p; + this->next_ = n; + this->timer_id_ = timer_id; +} + +template ACE_INLINE TYPE & +ACE_Timer_Node_T::get_type (void) +{ + return this->type_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_type (TYPE &type) +{ + this->type_ = type; +} + +template ACE_INLINE const void * +ACE_Timer_Node_T::get_act (void) +{ + return this->act_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_act (void *act) +{ + this->act_ = act; +} + +template ACE_INLINE const ACE_Time_Value & +ACE_Timer_Node_T::get_timer_value (void) const +{ + return this->timer_value_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_timer_value (const ACE_Time_Value &timer_value) +{ + this->timer_value_ = timer_value; +} + +template ACE_INLINE const ACE_Time_Value & +ACE_Timer_Node_T::get_interval (void) const +{ + return this->interval_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_interval (const ACE_Time_Value &interval) +{ + this->interval_ = interval; +} + +template ACE_INLINE ACE_Timer_Node_T * +ACE_Timer_Node_T::get_prev (void) +{ + return this->prev_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_prev (ACE_Timer_Node_T *prev) +{ + this->prev_ = prev; +} + +template ACE_INLINE ACE_Timer_Node_T * +ACE_Timer_Node_T::get_next (void) +{ + return this->next_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_next (ACE_Timer_Node_T *next) +{ + this->next_ = next; +} + +template ACE_INLINE long +ACE_Timer_Node_T::get_timer_id (void) const +{ + return this->timer_id_; +} + +template ACE_INLINE void +ACE_Timer_Node_T::set_timer_id (long timer_id) +{ + this->timer_id_ = timer_id; +} + +template ACE_INLINE void +ACE_Timer_Node_T::get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T &info) +{ + // Yes, do a copy + info.type_ = this->type_; + info.act_ = this->act_; + info.recurring_timer_ = + this->interval_ > ACE_Time_Value::zero; +} + +template ACE_INLINE void +ACE_Timer_Queue_T::timer_skew (const ACE_Time_Value &skew) +{ + timer_skew_ = skew; +} + +template ACE_INLINE const ACE_Time_Value & +ACE_Timer_Queue_T::timer_skew (void) const +{ + return timer_skew_; +} + +template ACE_INLINE int +ACE_Timer_Queue_T::expire (void) +{ + if (!this->is_empty ()) + return this->expire (this->gettimeofday () + timer_skew_); + else + return 0; +} + +template int +ACE_Timer_Queue_T::dispatch_info (const ACE_Time_Value &cur_time, + ACE_Timer_Node_Dispatch_Info_T &info) +{ + ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, 0)); + + return this->dispatch_info_i (cur_time, info); +} + +template ACE_INLINE void +ACE_Timer_Queue_T::upcall (ACE_Timer_Node_Dispatch_Info_T &info, + const ACE_Time_Value &cur_time) +{ + this->upcall_functor ().timeout (*this, + info.type_, + info.act_, + info.recurring_timer_, + cur_time); +} + +template ACE_INLINE void +ACE_Timer_Queue_T::preinvoke (ACE_Timer_Node_Dispatch_Info_T &info, + const ACE_Time_Value &cur_time, + const void *&upcall_act) +{ + this->upcall_functor ().preinvoke (*this, + info.type_, + info.act_, + info.recurring_timer_, + cur_time, + upcall_act); +} + +template ACE_INLINE void +ACE_Timer_Queue_T::postinvoke (ACE_Timer_Node_Dispatch_Info_T &info, + const ACE_Time_Value &cur_time, + const void *upcall_act) +{ + this->upcall_functor ().postinvoke (*this, + info.type_, + info.act_, + info.recurring_timer_, + cur_time, + upcall_act); +} + +template ACE_INLINE ACE_Time_Value +ACE_Timer_Queue_T::gettimeofday (void) +{ + // Invoke gettimeofday via pointer to function. + return this->gettimeofday_ (); +} + +template ACE_INLINE void +ACE_Timer_Queue_T::gettimeofday (ACE_Time_Value (*gettimeofday)(void)) +{ + this->gettimeofday_ = gettimeofday; +} + +template ACE_INLINE FUNCTOR & +ACE_Timer_Queue_T::upcall_functor (void) +{ + return *this->upcall_functor_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Timer_Queuefwd.h b/dep/ACE_wrappers/ace/Timer_Queuefwd.h new file mode 100644 index 000000000..662f29c04 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Queuefwd.h @@ -0,0 +1,38 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Queuefwd.h + * + * $Id: Timer_Queuefwd.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Forward declarations and typedefs of ACE_Timer_Queue class. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef ACE_TIMER_QUEUE_FWD_H +#define ACE_TIMER_QUEUE_FWD_H + +#include /**/ "ace/pre.h" + +#include "ace/Synch_Traits.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template class ACE_Timer_Queue_T; +template class ACE_Event_Handler_Handle_Timeout_Upcall; + +class ACE_Event_Handler; + +typedef ACE_Timer_Queue_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_Queue; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_TIMER_QUEUE_FWD_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Wheel.h b/dep/ACE_wrappers/ace/Timer_Wheel.h new file mode 100644 index 000000000..21ba87761 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Wheel.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Wheel.h + * + * $Id: Timer_Wheel.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Darrell Brunsch (brunsch@cs.wustl.edu) + */ +//============================================================================= + + +#ifndef ACE_TIMER_WHEEL_H +#define ACE_TIMER_WHEEL_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Wheel_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// The following typedefs are here for ease of use and backward +// compatibility. + +typedef ACE_Timer_Wheel_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_Wheel; + +typedef ACE_Timer_Wheel_Iterator_T, + ACE_SYNCH_RECURSIVE_MUTEX> + ACE_Timer_Wheel_Iterator; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_WHEEL_H */ diff --git a/dep/ACE_wrappers/ace/Timer_Wheel_T.cpp b/dep/ACE_wrappers/ace/Timer_Wheel_T.cpp new file mode 100644 index 000000000..f62ca7523 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Wheel_T.cpp @@ -0,0 +1,967 @@ +// $Id: Timer_Wheel_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TIMER_WHEEL_T_CPP +#define ACE_TIMER_WHEEL_T_CPP + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS_NS_sys_time.h" +#include "ace/Guard_T.h" +#include "ace/Timer_Wheel_T.h" +#include "ace/Log_Msg.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Design/implementation notes for ACE_Timer_Wheel_T. +// +// Each timer queue entry is represented by a ACE_Timer_Node. +// The timing wheel is divided into a number of "spokes"; there are +// spoke_count_ spokes in the wheel. Each timer is hashed into one of the +// spokes. Entries within each spoke are linked in a double-linked list +// in order of increasing expiration. The first ACE_Timer_Node in each +// spoke is a "dummy node" that marks the end of the list of ACE_Timer_Nodes +// in that spoke. +// +// The timer ID for a scheduled timer is formed by its spoke position in +// the wheel, and the number of timers that have been inserted in that spoke +// since the queue was initialized. N bits of the long timer_id are used +// to determine the spoke, and M bits are used as a counter. +// Each time a Node is inserted into a spoke, it's counter +// is incremented. The count is kept in the timer ID field +// of the dummy root Node. In the event of overflow of the counter, the spoke +// must be searched for each new id to make sure it's not already in use. To +// prevent having to do an exhaustive search each time, we keep extra data +// in the dummy root Node. +/** +* Default Constructor that sets defaults for spoke_count_ and resolution_ +* and doesn't do any preallocation. +* +* @param upcall_functor A pointer to a functor to use instead of the default +* @param freelist A pointer to a freelist to use instead of the default +*/ +template +ACE_Timer_Wheel_T::ACE_Timer_Wheel_T +(FUNCTOR* upcall_functor + , FreeList* freelist + ) +: Base (upcall_functor, freelist) +, spokes_(0) +, spoke_count_(0) // calculated in open_i +, spoke_bits_(0) +, res_bits_ (0) +, earliest_spoke_ (0) +, iterator_(0) +, timer_count_(0) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T"); + this->open_i (0, + ACE_DEFAULT_TIMER_WHEEL_SIZE, + ACE_DEFAULT_TIMER_WHEEL_RESOLUTION); +} + +/** +* Constructor that sets up the timing wheel and also may preallocate +* some nodes on the free list +* +* @param spoke_count The number of lists in the timer wheel +* @param resolution The time resolution in milliseconds used by the hashing function +* @param prealloc The number of entries to prealloc in the free_list +* @param upcall_functor A pointer to a functor to use instead of the default +* @param freelist A pointer to a freelist to use instead of the default +*/ +template +ACE_Timer_Wheel_T::ACE_Timer_Wheel_T + (u_int spoke_count, + u_int resolution, + size_t prealloc, + FUNCTOR* upcall_functor, + FreeList* freelist) +: Base (upcall_functor, freelist) +, spokes_ (0) +, spoke_count_ (0) // calculated in open_i +, spoke_bits_ (0) +, res_bits_ (0) +, earliest_spoke_ (0) +, iterator_ (0) +, timer_count_ (0) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T"); + this->open_i (prealloc, spoke_count, resolution); +} + +template int +ACE_Timer_Wheel_T::power2bits (int n, + int min_bits, + int max_bits) +{ + int max = (1 << max_bits) - 1; + if (n > max) + return max_bits; + + // count the bits in n. + int i = 0; + int tmp = n; + do + { + tmp >>= 1; + ++i; + } + while (tmp != 0); + + if (i <= min_bits) + return min_bits; + + // Which is nearest? + int a = (1 << i) - n; + int b = (1 << (i - 1)) - n; + if (b < 0) + b = -b; + if (b < a) + return i - 1; + return i; +} + +/** +* Initialize the queue. Uses the established members for all needed +* information. +*/ +template void +ACE_Timer_Wheel_T::open_i + (size_t prealloc, u_int spokes, u_int res) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::open_i"); + + this->gettimeofday (ACE_OS::gettimeofday); + + // Rather than waste bits in our timer id, we might as well round up + // the spoke count to the next power of two - 1 . (i.e 1,3,7,15,...127,etc.) + const int MIN_SPOKE_BITS = 3; // Allow between 8 and 4096 spokes + const int MAX_SPOKE_BITS = 12; + const int MAX_RES_BITS = 20; // 20 is plenty, even on 64 bit platforms. + + this->spoke_bits_ = power2bits (spokes, MIN_SPOKE_BITS, MAX_SPOKE_BITS); + this->res_bits_ = power2bits (res, 1, MAX_RES_BITS); + + this->spoke_count_ = 1 << this->spoke_bits_; + + this->free_list_->resize (prealloc + this->spoke_count_); + + this->wheel_time_.msec (1 << (this->res_bits_ + this->spoke_bits_)); + + ACE_NEW (this->spokes_, ACE_Timer_Node_T* [this->spoke_count_]); + + // Create the root nodes. These will be treated specially + for (u_int i = 0; i < this->spoke_count_; ++i) + { + ACE_Timer_Node_T* root = this->alloc_node (); + root->set (0, 0, ACE_Time_Value::zero, ACE_Time_Value::zero, root, root, 0); + this->spokes_[i] = root; + } + + ACE_NEW (iterator_, Iterator (*this)); +} + +/// Destructor just cleans up its memory +template +ACE_Timer_Wheel_T::~ACE_Timer_Wheel_T (void) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::~ACE_Timer_Wheel_T"); + + delete iterator_; + + for (u_int i = 0; i < this->spoke_count_; ++i) + { + // Free all the nodes starting at the root + ACE_Timer_Node_T* root = this->spokes_[i]; + for (ACE_Timer_Node_T* n = root->get_next (); n != root;) + { + ACE_Timer_Node_T* next = n->get_next (); + this->upcall_functor ().deletion (*this, + n->get_type (), + n->get_act ()); + this->free_node (n); + n = next; + } + delete root; + } + delete[] this->spokes_; +} + +/// Searches for a node by timer_id within one spoke. +template +ACE_Timer_Node_T* +ACE_Timer_Wheel_T::find_spoke_node + (u_int spoke, long timer_id) const +{ + ACE_Timer_Node_T* root = this->spokes_[spoke]; + for (ACE_Timer_Node_T* n = root->get_next (); + n != root; + n = n->get_next ()) + { + if (n->get_timer_id () == timer_id) + return n; + } + return 0; +} + +/// Searches all spokes for a node matching the specified timer_id +/// Uses the spoke encoded in the timer_id as a starting place. +template +ACE_Timer_Node_T* +ACE_Timer_Wheel_T::find_node (long timer_id) const +{ + if (timer_id == -1) + return 0; + + // Search the spoke where timer_id was originally scheduled + u_int spoke_mask = this->spoke_count_ - 1; + u_int start = timer_id & spoke_mask; + ACE_Timer_Node_T* n = this->find_spoke_node (start, timer_id); + if (n != 0) + return n; + + //ACE_ERROR((LM_ERROR, "Node not found in original spoke.\n")); + + // Search the rest of the spokes + for (u_int i = 0; i < this->spoke_count_; ++i) + { + if (i != start) + { // already searched this one + n = this->find_spoke_node (i, timer_id); + if (n != 0) + return n; + } + } + + //ACE_ERROR((LM_ERROR, "Node not found.\n")); + return 0; +} + +/** +* Check to see if the wheel is empty +* +* @return True if empty +*/ +template bool +ACE_Timer_Wheel_T::is_empty (void) const +{ + ACE_TRACE ("ACE_Timer_Wheel_T::is_empty"); + return timer_count_ == 0; +} + + +/** +* @return First (earliest) node in the wheel_'s earliest_spoke_ list +*/ +template const ACE_Time_Value & +ACE_Timer_Wheel_T::earliest_time (void) const +{ + ACE_TRACE ("ACE_Timer_Wheel_T::earliest_time"); + ACE_Timer_Node_T* n = this->get_first_i (); + if (n != 0) + return n->get_timer_value (); + return ACE_Time_Value::zero; +} + +/// Uses a simple hash to find which spoke to use based on when the +/// timer is due to expire. Hopefully the 64bit int operations avoid +/// any overflow problems. +template u_int +ACE_Timer_Wheel_T::calculate_spoke + (const ACE_Time_Value& t) const +{ + return static_cast ((t.msec () >> this->res_bits_) & (this->spoke_count_ - 1)); +} + +/// Generates a unique timer_id for the given spoke. It should be pretty +/// fast until the point where the counter overflows. At that time you +/// have to do exhaustive searches within the spoke to ensure that a particular +/// timer id is not already in use. Some optimizations are in place so +/// that this hopefully doesn't have to happen often. +template long +ACE_Timer_Wheel_T::generate_timer_id (u_int spoke) +{ + + int cnt_bits = sizeof (long) * 8 - this->spoke_bits_; + long max_cnt = ((long)1 << cnt_bits) - 1; + if (spoke == this->spoke_count_) + --max_cnt; // Because -1 is used as a special invalid timer_id. + + ACE_Timer_Node_T* root = this->spokes_[spoke]; + + if (root == root->get_next ()) + root->set_act(0); + + // We use this field to keep track of the next counter value that + // may be in use. Of course it may have expired, so we just use + // this field so that we know when we don't have to check for duplicates +#if defined (ACE_WIN64) + // The cast below is legit... we know that long is shorter than a + // pointer, but are only using it as a 'long' storage area. +# pragma warning(push) +# pragma warning(disable : 4311) +#endif /* ACE_WIN64 */ + long next_cnt = reinterpret_cast (root->get_act ()); +#if defined (ACE_WIN64) +# pragma warning(pop) +#endif /* ACE_WIN64 */ + + // This field is used as a counter instead of a timer_id. + long cnt = root->get_timer_id (); + + if (cnt >= max_cnt && root == root->get_next ()) + { + // Special case when we overflow on an empty spoke. We can just + // wrap the count around without searching for duplicates. We only + // want to do this when the counter overflows, so that we return + // unique timer_id values as often as possible. + root->set_timer_id (1); + return spoke; + } + else if (cnt >= max_cnt) + { // overflow + cnt = 0; // try again starting at zero + } + else if (next_cnt == 0 || cnt < next_cnt) + { + root->set_timer_id (cnt + 1); + return (cnt << this->spoke_bits_) | spoke; + } + + //ACE_ERROR((LM_ERROR, "Timer id overflow. We have to search now.\n")); + + // We've run out of consecutive id numbers so now we have to search + // for a unique id. + // We'll try increasing numbers until we find one that is not in use, + // and we'll record the next highest number so that we can avoid this + // search as often as possible. + for (; cnt < max_cnt - 1; ++cnt) + { + long id = (cnt << this->spoke_bits_) | spoke; + ACE_Timer_Node_T* n = this->find_spoke_node (spoke, id); + if (n == 0) + { + root->set_timer_id (cnt + 1); + // Now we need to find the next highest cnt in use + next_cnt = 0; + for (; n != root; n = n->get_next ()) + { + long tmp = n->get_timer_id () >> this->spoke_bits_; + if (tmp > cnt && (tmp < next_cnt || next_cnt == 0)) + next_cnt = tmp; + } +#if defined (ACE_WIN64) + // The cast below is legit... we know we're storing a long in + // a pointer, but are only using it as a 'long' storage area. +# pragma warning(push) +# pragma warning(disable : 4312) +#endif /* ACE_WIN64 */ + root->set_act (reinterpret_cast (next_cnt)); +#if defined (ACE_WIN64) +# pragma warning(pop) +#endif /* ACE_WIN64 */ + return id; + } + } + + return -1; // We did our best, but the spoke is full. +} + +/** +* Creates a ACE_Timer_Node_T based on the input parameters. Then inserts +* the node into the wheel using reschedule (). Then returns a timer_id. +* +* @param type The data of the timer node +* @param act Asynchronous Completion Token (AKA magic cookie) +* @param future_time The time the timer is scheduled for (absolute time) +* @param interval If not ACE_Time_Value::zero, then this is a periodic +* timer and interval is the time period +* +* @return Unique identifier (can be used to cancel the timer). +* -1 on failure. +*/ +template long +ACE_Timer_Wheel_T::schedule_i (const TYPE& type, + const void* act, + const ACE_Time_Value& future_time, + const ACE_Time_Value& interval) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::schedule_i"); + + ACE_Timer_Node_T* n = this->alloc_node (); + + if (n != 0) + { + u_int spoke = calculate_spoke (future_time); + long id = generate_timer_id (spoke); + + //ACE_ERROR((LM_ERROR, "Scheduling %x spoke:%d id:%d\n", (long) n, spoke, id)); + + if (id != -1) + { + n->set (type, act, future_time, interval, 0, 0, id); + this->schedule_i (n, spoke, future_time); + } + return id; + } + + // Failure return + errno = ENOMEM; + return -1; +} + +/** +* Takes an ACE_Timer_Node and inserts it into the correct position in +* the correct list. Also makes sure to update the earliest time. +* +* @param n The timer node to reschedule +*/ +template void +ACE_Timer_Wheel_T::reschedule (ACE_Timer_Node_T* n) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::reschedule"); + const ACE_Time_Value& expire = n->get_timer_value (); + u_int spoke = calculate_spoke (expire); + this->schedule_i (n, spoke, expire); +} + +/// The shared scheduling functionality between schedule() and reschedule() +template void +ACE_Timer_Wheel_T::schedule_i + (ACE_Timer_Node_T* n, + u_int spoke, + const ACE_Time_Value& expire) +{ + // See if we need to update the earliest time + if (this->is_empty() || expire < this->earliest_time ()) + this->earliest_spoke_ = spoke; + + ACE_Timer_Node_T* root = this->spokes_[spoke]; + ACE_Timer_Node_T* last = root->get_prev (); + + ++timer_count_; + + // If the spoke is empty + if (last == root) { + n->set_prev (root); + n->set_next (root); + root->set_prev (n); + root->set_next (n); + return; + } + + // We always want to search backwards from the tail of the list, because + // this minimizes the search in the extreme case when lots of timers are + // scheduled for exactly the same time + ACE_Timer_Node_T* p = root->get_prev (); + while (p != root && p->get_timer_value () > expire) + p = p->get_prev (); + + // insert after + n->set_prev (p); + n->set_next (p->get_next ()); + p->get_next ()->set_prev (n); + p->set_next (n); +} + + +/** +* Find the timer node by using the id as a pointer. Then use set_interval() +* on the node to update the interval. +* +* @param timer_id The timer identifier +* @param interval The new interval +* +* @return 0 if successful, -1 if no. +*/ +template int +ACE_Timer_Wheel_T::reset_interval (long timer_id, + const ACE_Time_Value &interval + ) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::reset_interval"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + ACE_Timer_Node_T* n = this->find_node (timer_id); + if (n != 0) + { + // The interval will take effect the next time this node is expired. + n->set_interval (interval); + return 0; + } + return -1; +} + + +/** +* Goes through every list in the wheel and whenever we find one with the +* correct type value, we remove it and continue. At the end make sure +* we reset the earliest time value in case the earliest timers were +* removed. +* +* @param type The value to search for. +* @param skip_close If this non-zero, the cancellation method of the +* functor will not be called for each cancelled timer. +* +* @return Number of timers cancelled +*/ +template int +ACE_Timer_Wheel_T::cancel (const TYPE& type, int skip_close) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::cancel"); + + int num_canceled = 0; // Note : Technically this can overflow. + int cookie = 0; + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + if (!this->is_empty ()) + { + ACE_Timer_Node_T* first = this->get_first (); + ACE_Time_Value last = first->get_timer_value (); + int recalc = 0; + + for (u_int i = 0; i < this->spoke_count_; ++i) + { + ACE_Timer_Node_T* root = this->spokes_[i]; + for (ACE_Timer_Node_T* n = root->get_next (); n != root; ) + { + if (n->get_type () == type) + { + ++num_canceled; + if (n == first) + recalc = 1; + + ACE_Timer_Node_T* tmp = n; + n = n->get_next (); + + this->cancel_i (tmp); + } + else + { + n = n->get_next (); + } + } + } + + if (recalc) + this->recalc_earliest (last); + } + + // Call the close hooks. + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + type, + skip_close, + cookie); + + for (int i = 0; + i < num_canceled; + ++i) + { + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + type, + skip_close, + cookie); + } + + return num_canceled; +} + + +/** +* Cancels the single timer that is specified by the timer_id. In this +* case the timer_id is actually a pointer to the node, so we cast it +* to the node. This can be dangerous if the timer_id is made up +* (or deleted twice) so we do a little sanity check. Finally we update +* the earliest time in case the earliest timer was removed. +* +* @param timer_id Timer Identifier +* @param act Asychronous Completion Token (AKA magic cookie): +* If this is non-zero, stores the magic cookie of +* the cancelled timer here. +* @param skip_close If this non-zero, the cancellation method of the +* functor will not be called. +* +* @return 1 for sucess and 0 if the timer_id wasn't found (or was +* found to be invalid) +*/ +template int +ACE_Timer_Wheel_T::cancel (long timer_id, + const void **act, + int skip_close) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::cancel"); + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + ACE_Timer_Node_T* n = this->find_node (timer_id); + if (n != 0) + { + ACE_Time_Value last = n->get_timer_value (); + + int recalc = (this->get_first_i () == n); + + // Call the close hooks. + int cookie = 0; + + // cancel_type() called once per . + this->upcall_functor ().cancel_type (*this, + n->get_type (), + skip_close, + cookie); + + // cancel_timer() called once per . + this->upcall_functor ().cancel_timer (*this, + n->get_type (), + skip_close, + cookie); + if (act != 0) + *act = n->get_act (); + + this->cancel_i (n); + + if (recalc) + this->recalc_earliest (last); + + return 1; + } + return 0; +} + +/// Shared subset of the two cancel() methods. +template void +ACE_Timer_Wheel_T::cancel_i (ACE_Timer_Node_T* n) +{ + this->unlink (n); + this->free_node (n); +} + +/// There are a few places where we have to figure out which timer +/// will expire next. This method makes the assumption that spokes +/// are always sorted, and that timers are always in the correct spoke +/// determined from their expiration time. +/// The last time is always passed in, even though you can often calculate +/// it as get_first()->get_timer_value(). +template void +ACE_Timer_Wheel_T::recalc_earliest + (const ACE_Time_Value& last) +{ + // This is possible because we use a count for is_empty() + if (this->is_empty ()) + return; + + ACE_Time_Value et = ACE_Time_Value::zero; + u_int es = 0; + u_int spoke = this->earliest_spoke_; + + // We will have to go around the wheel at most one time. + for (u_int i = 0; i < this->spoke_count_; ++i) + { + ACE_Timer_Node_T* root = this->spokes_[spoke]; + ACE_Timer_Node_T* n = root->get_next (); + if (n != root) + { + ACE_Time_Value t = n->get_timer_value (); + if (t < last + this->wheel_time_) + { + this->earliest_spoke_ = spoke; + return; + } + else if (et == ACE_Time_Value::zero || t < et) + { + et = t; + es = spoke; + } + } + if (++spoke >= this->spoke_count_) + spoke = 0; + } + + this->earliest_spoke_ = es; + //ACE_ERROR((LM_ERROR, "We had to search the whole wheel.\n")); +} + +/** +* Dumps out the size of the wheel, the resolution, and the contents +* of the wheel. +*/ +template void +ACE_Timer_Wheel_T::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Timer_Wheel_T::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\nspoke_count_ = %d"), this->spoke_count_)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\nresolution_ = %d"), 1 << this->res_bits_)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\nwheel_ = \n"))); + + for (u_int i = 0; i < this->spoke_count_; ++i) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d\n"), i)); + ACE_Timer_Node_T* root = this->spokes_[i]; + for (ACE_Timer_Node_T* n = root->get_next (); + n != root; + n = n->get_next ()) + { + n->dump (); + } + } + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + + +/** +* Removes the earliest node and then find the new +* +* @return The earliest timer node. +*/ +template ACE_Timer_Node_T * +ACE_Timer_Wheel_T::remove_first (void) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::remove_first"); + return remove_first_expired (ACE_Time_Value::max_time); +} + +template void +ACE_Timer_Wheel_T::unlink (ACE_Timer_Node_T* n) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::unlink"); + --timer_count_; + n->get_prev ()->set_next (n->get_next ()); + n->get_next ()->set_prev (n->get_prev ()); + n->set_prev (0); + n->set_next (0); +} + +template ACE_Timer_Node_T * +ACE_Timer_Wheel_T::remove_first_expired (const ACE_Time_Value& now) +{ + ACE_Timer_Node_T* n = this->get_first (); + if (n != 0 && n->get_timer_value() <= now) + { + this->unlink (n); + this->recalc_earliest (n->get_timer_value ()); + return n; + } + return 0; +} + +/** +* Returns the earliest node without removing it +* +* @return The earliest timer node. +*/ +template +ACE_Timer_Node_T* +ACE_Timer_Wheel_T::get_first (void) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::get_first"); + return this->get_first_i (); +} + +template +ACE_Timer_Node_T* +ACE_Timer_Wheel_T::get_first_i (void) const +{ + ACE_Timer_Node_T* root = this->spokes_[this->earliest_spoke_]; + ACE_Timer_Node_T* first = root->get_next (); + if (first != root) + return first; + return 0; +} + + +/** +* @return The iterator +*/ +template +ACE_Timer_Queue_Iterator_T& +ACE_Timer_Wheel_T::iter (void) +{ + this->iterator_->first (); + return *this->iterator_; +} + +/** +* Dummy version of expire to get rid of warnings in Sun CC 4.2 +* Just call the expire of the base class. +*/ +template int +ACE_Timer_Wheel_T::expire () +{ + return ACE_Timer_Queue_T::expire (); +} + +/** +* This is a specialized version of expire that is more suited for the +* internal data representation. +* +* @param cur_time The time to expire timers up to. +* +* @return Number of timers expired +*/ +template int +ACE_Timer_Wheel_T::expire (const ACE_Time_Value& cur_time) +{ + ACE_TRACE ("ACE_Timer_Wheel_T::expire"); + + int expcount = 0; + + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + ACE_Timer_Node_T* n = this->remove_first_expired (cur_time); + + while (n != 0) + { + ++expcount; + + //ACE_ERROR((LM_ERROR, "Expiring %x\n", (long) n)); + + ACE_Timer_Node_Dispatch_Info_T info; + + // Get the dispatch info + n->get_dispatch_info (info); + + if (n->get_interval () > ACE_Time_Value::zero) + { + // Make sure that we skip past values that have already + // "expired". + do + n->set_timer_value (n->get_timer_value () + + n->get_interval ()); + while (n->get_timer_value () <= cur_time); + + this->reschedule (n); + } + else + { + this->free_node (n); + } + + const void *upcall_act = 0; + + this->preinvoke (info, cur_time, upcall_act); + + this->upcall (info, cur_time); + + this->postinvoke (info, cur_time, upcall_act); + + n = this->remove_first_expired (cur_time); + } + + return expcount; +} + +/////////////////////////////////////////////////////////////////////////// +// ACE_Timer_Wheel_Iterator_T + +/** +* Just initializes the iterator with a ACE_Timer_Wheel_T and then calls +* first() to initialize the rest of itself. +* +* @param wheel A reference for a timer queue to iterate over +*/ +template +ACE_Timer_Wheel_Iterator_T::ACE_Timer_Wheel_Iterator_T +(Wheel& wheel) +: timer_wheel_ (wheel) +{ + this->first(); +} + + +/** +* Destructor, at this level does nothing. +*/ +template +ACE_Timer_Wheel_Iterator_T::~ACE_Timer_Wheel_Iterator_T (void) +{ +} + + +/** +* Positions the iterator at the first position in the timing wheel +* that contains something. spoke_ will be set to the spoke position of +* this entry and current_node_ will point to the first entry in that spoke. +* +* If the wheel is empty, spoke_ will be equal timer_wheel_.spoke_count_ and +* current_node_ would be 0. +*/ +template void +ACE_Timer_Wheel_Iterator_T::first (void) +{ + this->goto_next(0); +} + + +/** +* Positions the iterator at the next node. +*/ +template void +ACE_Timer_Wheel_Iterator_T::next (void) +{ + if (this->isdone()) + return; + + ACE_Timer_Node_T* n = this->current_node_->get_next (); + ACE_Timer_Node_T* root = this->timer_wheel_.spokes_[this->spoke_]; + if (n == root) + this->goto_next (this->spoke_ + 1); + else + this->current_node_ = n; +} + +/// Helper class for common functionality of next() and first() +template void +ACE_Timer_Wheel_Iterator_T::goto_next (u_int start_spoke) +{ + // Find the first non-empty entry. + u_int sc = this->timer_wheel_.spoke_count_; + for (u_int i = start_spoke; i < sc; ++i) + { + ACE_Timer_Node_T* root = this->timer_wheel_.spokes_[i]; + ACE_Timer_Node_T* n = root->get_next (); + if (n != root) + { + this->spoke_ = i; + this->current_node_ = n; + return; + } + } + // empty + this->spoke_ = sc; + this->current_node_ = 0; +} + +/** +* @return True when we there aren't any more items (when current_node_ == 0) +*/ +template bool +ACE_Timer_Wheel_Iterator_T::isdone (void) const +{ + return this->current_node_ == 0; +} + +/** +* @return The node at the current spokeition in the sequence or 0 if the wheel +* is empty +*/ +template ACE_Timer_Node_T * +ACE_Timer_Wheel_Iterator_T::item (void) +{ + return this->current_node_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TIMER_WHEEL_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Timer_Wheel_T.h b/dep/ACE_wrappers/ace/Timer_Wheel_T.h new file mode 100644 index 000000000..44fffed13 --- /dev/null +++ b/dep/ACE_wrappers/ace/Timer_Wheel_T.h @@ -0,0 +1,226 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Timer_Wheel_T.h + * + * $Id: Timer_Wheel_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_TIMER_WHEEL_T_H +#define ACE_TIMER_WHEEL_T_H +#include /**/ "ace/pre.h" + +#include "ace/Timer_Queue_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration +template +class ACE_Timer_Wheel_T; + +/** + * @class ACE_Timer_Wheel_Iterator_T + * + * @brief Iterates over an ACE_Timer_Wheel. + * + * This is a generic iterator that can be used to visit every + * node of a timer queue. Be aware that it doesn't traverse + * in the order of timeout values. + */ +template +class ACE_Timer_Wheel_Iterator_T + : public ACE_Timer_Queue_Iterator_T +{ +public: + typedef ACE_Timer_Wheel_T Wheel; + typedef ACE_Timer_Node_T Node; + + /// Constructor + ACE_Timer_Wheel_Iterator_T (Wheel &); + + /// Destructor + ~ACE_Timer_Wheel_Iterator_T (void); + + /// Positions the iterator at the earliest node in the Timer Queue + virtual void first (void); + + /// Positions the iterator at the next node in the Timer Queue + virtual void next (void); + + /// Returns true when there are no more nodes in the sequence + virtual bool isdone (void) const; + + /// Returns the node at the current position in the sequence + virtual ACE_Timer_Node_T* item (void); + +protected: + /// Pointer to the ACE_Timer_List that we are iterating over. + Wheel& timer_wheel_; + + /// Current position in the timing wheel + u_int spoke_; + + /// Pointer to the position in the the th list + ACE_Timer_Node_T* current_node_; +private: + void goto_next(u_int start_spoke); +}; + +/** + * @class ACE_Timer_Wheel_T + * + * @brief Provides a Timing Wheel version of ACE_Timer_Queue. + * + * This implementation uses a hash table of ordered doubly- + * linked lists of absolute times. The enhancements over the + * @c ACE_Timer_List include adding a free list and the ability + * to preallocate nodes. Timer Wheel is based on the timing + * wheel implementation used in Adam M. Costello and + * George Varghese's paper "Redesigning the BSD Callout and + * Timer Facilities" + * (http://dworkin.wustl.edu/~varghese/PAPERS/newbsd.ps.Z) + */ +template +class ACE_Timer_Wheel_T : public ACE_Timer_Queue_T +{ +public: + /// Type of iterator + typedef ACE_Timer_Wheel_Iterator_T Iterator; + /// Iterator is a friend + friend class ACE_Timer_Wheel_Iterator_T; + typedef ACE_Timer_Node_T Node; + /// Type inherited from + typedef ACE_Timer_Queue_T Base; + typedef ACE_Free_List FreeList; + + /// Default constructor + ACE_Timer_Wheel_T (FUNCTOR* upcall_functor = 0, FreeList* freelist = 0); + + /// Constructor with opportunities to set the wheelsize and resolution + ACE_Timer_Wheel_T (u_int spoke_count, + u_int resolution, + size_t prealloc = 0, + FUNCTOR* upcall_functor = 0, + FreeList* freelist = 0); + + /// Destructor + virtual ~ACE_Timer_Wheel_T (void); + + /// True if queue is empty, else false. + virtual bool is_empty (void) const; + + /// Returns the time of the earlier node in the ACE_Timer_Wheel. + /// Must be called on a non-empty queue. + virtual const ACE_Time_Value& earliest_time (void) const; + + /// Changes the interval of a timer (and can make it periodic or non + /// periodic by setting it to ACE_Time_Value::zero or not). + virtual int reset_interval (long timer_id, + const ACE_Time_Value& interval); + + /// Cancel all timer associated with @a type. If is 0 + /// then the will be invoked. Returns number of timers + /// cancelled. + virtual int cancel (const TYPE& type, + int dont_call_handle_close = 1); + + // Cancel a timer, storing the magic cookie in act (if nonzero). + // Calls the functor if dont_call_handle_close is 0 and returns 1 + // on success + virtual int cancel (long timer_id, + const void** act = 0, + int dont_call_handle_close = 1); + + /// Run the for all timers whose values are <= + /// . Also accounts for . Returns + /// the number of timers canceled. + virtual int expire (void); + + // Run the for all timers whose values are <= @a current_time. + // This does not account for . Returns the number of + // timers canceled. + int expire (const ACE_Time_Value& current_time); + + /// Returns a pointer to this 's iterator. + virtual ACE_Timer_Queue_Iterator_T& iter (void); + + /// Removes the earliest node from the queue and returns it + virtual ACE_Timer_Node_T* remove_first (void); + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Reads the earliest node from the queue and returns it. + virtual ACE_Timer_Node_T* get_first (void); + +protected: + + /// Schedules a timer. + virtual long schedule_i (const TYPE& type, + const void* act, + const ACE_Time_Value& future_time, + const ACE_Time_Value& interval); + +private: + // The following are documented in the .cpp file. + ACE_Timer_Node_T* get_first_i (void) const; + ACE_Timer_Node_T* remove_first_expired (const ACE_Time_Value& now); + void open_i (size_t prealloc, u_int spokes, u_int res); + virtual void reschedule (ACE_Timer_Node_T *); + ACE_Timer_Node_T* find_spoke_node(u_int spoke, long timer_id) const; + ACE_Timer_Node_T* find_node(long timer_id) const; + u_int calculate_spoke(const ACE_Time_Value& expire) const; + long generate_timer_id(u_int spoke); + void schedule_i (ACE_Timer_Node_T* n, u_int spoke, const ACE_Time_Value& expire); + void cancel_i (ACE_Timer_Node_T* n); + void unlink (ACE_Timer_Node_T* n); + void recalc_earliest(const ACE_Time_Value& last); + +private: + int power2bits (int n, int min_bits, int max_bits); + + /// Timing Wheel. + ACE_Timer_Node_T** spokes_; + /// Size of the timing wheel. + u_int spoke_count_; + /// Number of timer_id bits used for the spoke + int spoke_bits_; + /// Maximum number of timers per spoke + u_int max_per_spoke_; + /// Resolution (in microsoconds) of the timing wheel. + int res_bits_; + /// Index of the list with the earliest time + u_int earliest_spoke_; + /// Iterator used to expire timers. + Iterator* iterator_; + /// The total amount of time in one iteration of the wheel. (resolution * spoke_count) + ACE_Time_Value wheel_time_; + /// The total number of timers currently scheduled. + u_int timer_count_; + + // = Don't allow these operations for now, don't split into multiple lines + // breaks sun compilers + ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Wheel_T (const ACE_Timer_Wheel_T &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Wheel_T &)) +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Timer_Wheel_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Timer_Wheel_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TIMER_WHEEL_T_H */ diff --git a/dep/ACE_wrappers/ace/Token.cpp b/dep/ACE_wrappers/ace/Token.cpp new file mode 100644 index 000000000..ca2aea12f --- /dev/null +++ b/dep/ACE_wrappers/ace/Token.cpp @@ -0,0 +1,545 @@ +// $Id: Token.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Token.h" + +#if !defined (__ACE_INLINE__) +# include "ace/Token.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Token, "$Id: Token.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_THREADS) + +#include "ace/Thread.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_TOKEN_DEBUGGING) +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" +#endif /* ACE_TOKEN_DEBUGGING */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Token) + +void +ACE_Token::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Token::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthread = %d"), ACE_Thread::self ())); + // @@ Is there a portable way to do this? + // ACE_DEBUG ((LM_DEBUG, "\nowner_ = %d", (long) this->owner_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nowner_ addr = %x"), &this->owner_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nwaiters_ = %d"), this->waiters_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nin_use_ = %d"), this->in_use_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnesting level = %d"), this->nesting_level_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id) + : next_ (0), + thread_id_ (t_id), +#if defined (ACE_TOKEN_USES_SEMAPHORE) + cv_ (0), +#else + cv_ (m), +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + runable_ (0) +{ +#if defined (ACE_TOKEN_USES_SEMAPHORE) + ACE_UNUSED_ARG (m); +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + + ACE_TRACE ("ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry"); +} + +ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id, + ACE_Condition_Attributes &attributes) + : next_ (0), + thread_id_ (t_id), +#if defined (ACE_TOKEN_USES_SEMAPHORE) + cv_ (0), +#else + cv_ (m, attributes), +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + runable_ (0) +{ +#if defined (ACE_TOKEN_USES_SEMAPHORE) + ACE_UNUSED_ARG (m); + ACE_UNUSED_ARG (attributes); +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + + ACE_TRACE ("ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry"); +} + +ACE_Token::ACE_Token_Queue::ACE_Token_Queue (void) + : head_ (0), + tail_ (0) +{ + ACE_TRACE ("ACE_Token::ACE_Token_Queue::ACE_Token_Queue"); +} + +// +// Remove an entry from the list. Must be called with locks held. +// +void +ACE_Token::ACE_Token_Queue::remove_entry (ACE_Token::ACE_Token_Queue_Entry *entry) +{ + ACE_TRACE ("ACE_Token::ACE_Token_Queue::remove_entry"); + ACE_Token_Queue_Entry *curr = 0; + ACE_Token_Queue_Entry *prev = 0; + + if (this->head_ == 0) + return; + + for (curr = this->head_; + curr != 0 && curr != entry; + curr = curr->next_) + prev = curr; + + if (curr == 0) + // Didn't find the entry... + return; + else if (prev == 0) + // Delete at the head. + this->head_ = this->head_->next_; + else + // Delete in the middle. + prev->next_ = curr->next_; + + // We need to update the tail of the list if we've deleted the last + // entry. + if (curr->next_ == 0) + this->tail_ = prev; +} + +// +// Add an entry into the list. Must be called with locks held. +// +void +ACE_Token::ACE_Token_Queue::insert_entry (ACE_Token::ACE_Token_Queue_Entry &entry, + int requeue_position) +{ + if (this->head_ == 0) + { + // No other threads - just add me + this->head_ = &entry; + this->tail_ = &entry; + } + else if (requeue_position == -1) + { + // Insert at the end of the queue. + this->tail_->next_ = &entry; + this->tail_ = &entry; + } + else if (requeue_position == 0) + { + // Insert at head of queue. + entry.next_ = this->head_; + this->head_ = &entry; + } + else + // Insert in the middle of the queue somewhere. + { + // Determine where our thread should go in the queue of waiters. + + ACE_Token::ACE_Token_Queue_Entry *insert_after = this->head_; + while (requeue_position-- && insert_after->next_ != 0) + insert_after = insert_after->next_; + + entry.next_ = insert_after->next_; + + if (entry.next_ == 0) + this->tail_ = &entry; + + insert_after->next_ = &entry; + } +} + +ACE_Token::ACE_Token (const ACE_TCHAR *name, void *any) + : lock_ (name, (ACE_mutexattr_t *) any), + owner_ (ACE_OS::NULL_thread), + in_use_ (0), + waiters_ (0), + nesting_level_ (0), + attributes_ (USYNC_THREAD), + queueing_strategy_ (FIFO) +{ +// ACE_TRACE ("ACE_Token::ACE_Token"); +} + +ACE_Token::~ACE_Token (void) +{ + ACE_TRACE ("ACE_Token::~ACE_Token"); +} + +int +ACE_Token::shared_acquire (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout, + ACE_Token_Op_Type op_type) +{ + ACE_TRACE ("ACE_Token::shared_acquire"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + +#if defined (ACE_TOKEN_DEBUGGING) + this->dump (); +#endif /* ACE_TOKEN_DEBUGGING */ + + ACE_thread_t const thr_id = ACE_Thread::self (); + + // Nobody holds the token. + if (!this->in_use_) + { + // Its mine! + this->in_use_ = op_type; + this->owner_ = thr_id; + return 0; + } + + // + // Someone already holds the token. + // + + // Check if it is us. + if (ACE_OS::thr_equal (thr_id, this->owner_)) + { + ++this->nesting_level_; + return 0; + } + + // Do a quick check for "polling" behavior. + if (timeout != 0 && timeout->sec () == 0 && timeout->usec () == 0) + { + errno = ETIME; + return -1; + } + + // + // We've got to sleep until we get the token. + // + + // Which queue we should end up in... + ACE_Token_Queue *queue = (op_type == ACE_Token::READ_TOKEN + ? &this->readers_ + : &this->writers_); + + // Allocate queue entry on stack. This works since we don't exit + // this method's activation record until we've got the token. + ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_, + thr_id, + this->attributes_); + queue->insert_entry (my_entry, this->queueing_strategy_); + ++this->waiters_; + + // Execute appropriate callback. (@@ should these + // methods return a success/failure status, and if so, what should + // we do with it?) + int ret = 0; + if (sleep_hook_func) + { + (*sleep_hook_func) (arg); + ++ret; + } + else + { + // Execute virtual method. + this->sleep_hook (); + ++ret; + } + + bool timed_out = false; + bool error = false; + + // Sleep until we've got the token (ignore signals). + do + { + int const result = my_entry.wait (timeout, this->lock_); + + if (result == -1) + { + // Note, this should obey whatever thread-specific interrupt + // policy is currently in place... + if (errno == EINTR) + continue; + +#if defined (ACE_TOKEN_DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " acquire: " + << (errno == ETIME ? "timed out" : "error occurred") + << endl; +#endif /* ACE_TOKEN_DEBUGGING */ + + // We come here if a timeout occurs or some serious + // ACE_Condition object error. + if (errno == ETIME) + timed_out = true; + else + error = true; + + // Stop the loop. + break; + } + } + while (!ACE_OS::thr_equal (thr_id, this->owner_)); + + // Do this always and irrespective of the result of wait(). + --this->waiters_; + queue->remove_entry (&my_entry); + +#if defined (ACE_TOKEN_DEBUGGING) + ACE_DEBUG ((LM_DEBUG, "(%t) ACE_Token::shared_acquire (UNBLOCKED)\n")); +#endif /* ACE_TOKEN_DEBUGGING */ + + // If timeout occured + if (timed_out) + { + // This thread was still selected to own the token. + if (my_entry.runable_) + { + // Wakeup next waiter since this thread timed out. + this->wakeup_next_waiter (); + } + + // Return error. + return -1; + } + else if (error) + { + // Return error. + return -1; + } + + // If this is a normal wakeup, this thread should be runnable. + ACE_ASSERT (my_entry.runable_); + + return ret; +} + +// By default this is a no-op. + +/* virtual */ +void +ACE_Token::sleep_hook (void) +{ + ACE_TRACE ("ACE_Token::sleep_hook"); +} + +int +ACE_Token::acquire (ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::acquire"); + return this->shared_acquire (0, 0, timeout, ACE_Token::WRITE_TOKEN); +} + +// Acquire the token, sleeping until it is obtained or until +// expires. + +int +ACE_Token::acquire (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::acquire"); + return this->shared_acquire (sleep_hook_func, arg, timeout, ACE_Token::WRITE_TOKEN); +} + +// Try to renew the token. + +int +ACE_Token::renew (int requeue_position, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::renew"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + +#if defined (ACE_TOKEN_DEBUGGING) + this->dump (); +#endif /* ACE_TOKEN_DEBUGGING */ + // ACE_ASSERT (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_)); + + // Check to see if there are any waiters worth giving up the lock + // for. + + // If no writers and either we are a writer or there are no readers. + if (this->writers_.head_ == 0 && + (this->in_use_ == ACE_Token::WRITE_TOKEN || + this->readers_.head_ == 0)) + // Immediate return. + return 0; + + // We've got to sleep until we get the token again. + + // Determine which queue should this thread go to. + ACE_Token::ACE_Token_Queue *this_threads_queue = + this->in_use_ == ACE_Token::READ_TOKEN ? + &this->readers_ : &this->writers_; + + ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_, + this->owner_); + + this_threads_queue->insert_entry (my_entry, + // if requeue_position == 0 then we want to go next, + // otherwise use the queueing strategy, which might also + // happen to be 0. + requeue_position == 0 ? 0 : this->queueing_strategy_); + ++this->waiters_; + + // Remember nesting level... + int const save_nesting_level_ = this->nesting_level_; + + // Reset state for new owner. + this->nesting_level_ = 0; + + // Wakeup waiter. + this->wakeup_next_waiter (); + + bool timed_out = false; + bool error = false; + + // Sleep until we've got the token (ignore signals). + do + { + int const result = my_entry.wait (timeout, this->lock_); + + if (result == -1) + { + // Note, this should obey whatever thread-specific interrupt + // policy is currently in place... + if (errno == EINTR) + continue; + +#if defined (ACE_TOKEN_DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " renew: " + << (errno == ETIME ? "timed out" : "error occurred") + << endl; +#endif /* ACE_TOKEN_DEBUGGING */ + + // We come here if a timeout occurs or some serious + // ACE_Condition object error. + if (errno == ETIME) + timed_out = true; + else + error = true; + + // Stop the loop. + break; + } + } + while (!ACE_OS::thr_equal (my_entry.thread_id_, this->owner_)); + + // Do this always and irrespective of the result of wait(). + --this->waiters_; + this_threads_queue->remove_entry (&my_entry); + +#if defined (ACE_TOKEN_DEBUGGING) + ACE_DEBUG ((LM_DEBUG, "(%t) ACE_Token::renew (UNBLOCKED)\n")); +#endif /* ACE_TOKEN_DEBUGGING */ + + // If timeout occured + if (timed_out) + { + // This thread was still selected to own the token. + if (my_entry.runable_) + { + // Wakeup next waiter since this thread timed out. + this->wakeup_next_waiter (); + } + + // Return error. + return -1; + } + else if (error) + { + // Return error. + return -1; + } + + // If this is a normal wakeup, this thread should be runnable. + ACE_ASSERT (my_entry.runable_); + + // Reinstate nesting level. + this->nesting_level_ = save_nesting_level_; + + return 0; +} + +// Release the current holder of the token (which had +// better be the caller's thread!). + +int +ACE_Token::release (void) +{ + ACE_TRACE ("ACE_Token::release"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + +#if defined (ACE_TOKEN_DEBUGGING) + this->dump (); +#endif /* ACE_TOKEN_DEBUGGING */ + + // Nested release... + if (this->nesting_level_ > 0) + --this->nesting_level_; + else + { + // + // Regular release... + // + + // Wakeup waiter. + this->wakeup_next_waiter (); + } + + return 0; +} + +void +ACE_Token::wakeup_next_waiter (void) +{ + ACE_TRACE ("ACE_Token::wakeup_next_waiter"); + + // Reset state for new owner. + this->owner_ = ACE_OS::NULL_thread; + this->in_use_ = 0; + + // Any waiters... + if (this->writers_.head_ == 0 && + this->readers_.head_ == 0) + { + // No more waiters... + return; + } + + // Wakeup next waiter. + ACE_Token_Queue *queue = 0; + + // Writer threads get priority to run first. + if (this->writers_.head_ != 0) + { + this->in_use_ = ACE_Token::WRITE_TOKEN; + queue = &this->writers_; + } + else + { + this->in_use_ = ACE_Token::READ_TOKEN; + queue = &this->readers_; + } + + // Wake up waiter and make it runable. + queue->head_->runable_ = 1; + queue->head_->signal (); + + this->owner_ = queue->head_->thread_id_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/Token.h b/dep/ACE_wrappers/ace/Token.h new file mode 100644 index 000000000..f46726aa6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token.h @@ -0,0 +1,376 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Token.h + * + * $Id: Token.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Original author + * @author Karl-Heinz Dorn (kdorn@erlh.siemens.de) + * @author Ported to ACE by + * @author Douglas C. Schmidt (schmidt@cs.wustl.edu) + */ +//============================================================================= + +#ifndef ACE_TOKEN_H +#define ACE_TOKEN_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Null_Mutex.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Thread_Mutex.h" + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || defined (ACE_HAS_VXTHREADS) +// If platforms support semaphores with timed wait, then we use semaphores instead of c.v. +# define ACE_TOKEN_USES_SEMAPHORE +#endif /* (ACE_WIN32 && !ACE_HAS_WINCE) || VXWORKS */ + +#if defined (ACE_TOKEN_USES_SEMAPHORE) +# include "ace/Semaphore.h" +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + +#include "ace/Condition_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Time_Value; + +/** + * @class ACE_Token + * + * @brief Class that acquires, renews, and releases a synchronization + * token that is serviced in strict FIFO/LIFO ordering and that also + * supports (1) recursion and (2) readers/writer semantics. + * + * This class is a more general-purpose synchronization mechanism + * than many native OS mutexes. For example, it implements + * "recursive mutex" semantics, where a thread that owns the token + * can reacquire it without deadlocking. If the same thread calls + * multiple times, however, it must call an + * equal number of times before the token is actually released. + * Threads that are blocked awaiting the token are serviced in + * strict FIFO/LIFO order as other threads release the token (Solaris + * and Pthread mutexes don't strictly enforce an acquisition + * order). There are two lists within the class. Write + * acquires always have higher priority over read acquires. Which + * means, if you use both write/read operations, care must be + * taken to avoid starvation on the readers. Notice that the + * read/write acquire operations do not have the usual semantic of + * reader/writer locks. Only one reader can acquire the token at + * a time (which is different from the usual reader/writer locks + * where several readers can acquire a lock at the same time as + * long as there is no writer waiting for the lock). We choose + * the names to (1) borrow the semantic to give writers higher + * priority and (2) support a common interface for all locking + * classes in ACE. + */ +class ACE_Export ACE_Token +{ +public: + + /** + * Available queueing strategies. + */ + enum QUEUEING_STRATEGY + { + /// FIFO, First In, First Out. + FIFO = -1, + /// LIFO, Last In, First Out + LIFO = 0 + }; + + // = Initialization and termination. + + /// Constructor + ACE_Token (const ACE_TCHAR *name = 0, void * = 0); + + /// Destructor + virtual ~ACE_Token (void); + + // = Strategies + + /// Retrieve the current queueing strategy. + int queueing_strategy (void); + + /// Set the queueing strategy. + void queueing_strategy (int queueing_strategy); + + // = Synchronization operations. + + /** + * Acquire the token, sleeping until it is obtained or until the + * expiration of @a timeout, which is treated as "absolute" time. If + * some other thread currently holds the token then is + * called before our thread goes to sleep. This can be + * used by the requesting thread to unblock a token-holder that is + * sleeping, e.g., by means of writing to a pipe (the ACE + * ACE_Reactor uses this functionality). Return values: 0 if + * acquires without calling 1 if is + * called. 2 if the token is signaled. -1 if failure or timeout + * occurs (if timeout occurs errno == ETIME) If @a timeout == + * <&ACE_Time_Value::zero> then acquire has polling semantics (and + * does *not* call ). + */ + int acquire (void (*sleep_hook)(void *), + void *arg = 0, + ACE_Time_Value *timeout = 0); + + /** + * This behaves just like the previous method, except that + * it invokes the virtual function called that can be + * overridden by a subclass of ACE_Token. + */ + int acquire (ACE_Time_Value *timeout = 0); + + /** + * This should be overridden by a subclass to define the appropriate + * behavior before goes to sleep. By default, this is a + * no-op... + */ + virtual void sleep_hook (void); + + /** + * An optimized method that efficiently reacquires the token if no + * other threads are waiting. This is useful for situations where + * you don't want to degrade the quality of service if there are + * other threads waiting to get the token. If == + * -1 and there are other threads waiting to obtain the token we are + * queued according to the queueing strategy. If + * > -1 then it indicates how many entries to skip over before + * inserting our thread into the list of waiters (e.g., + * == 0 means "insert at front of the queue"). + * Renew has the rather odd semantics such that if there are other + * waiting threads it will give up the token even if the + * nesting_level_ > 1. I'm not sure if this is really the right + * thing to do (since it makes it possible for shared data to be + * changed unexpectedly) so use with caution... This method + * maintians the original token priority. As in , the + * @a timeout value is an absolute time. + */ + int renew (int requeue_position = 0, + ACE_Time_Value *timeout = 0); + + /// Become interface-compliant with other lock mechanisms (implements + /// a non-blocking ). + int tryacquire (void); + + /// Shuts down the ACE_Token instance. + int remove (void); + + /// Relinquish the token. If there are any waiters then the next one + /// in line gets it. + int release (void); + + /// Behaves like acquire() but at a lower priority. It should probably + /// be called acquire_yield() since the semantics aren't really + /// what's commonly expected for readers/writer locks. See the class + /// documentation above for more details. + int acquire_read (void); + + /// Behaves like acquire() but at a lower priority. It should probably + /// be called acquire_yield() since the semantics aren't really + /// what's commonly expected for readers/writer locks. See the class + /// documentation above for more details. + int acquire_read (void (*sleep_hook)(void *), + void *arg = 0, + ACE_Time_Value *timeout = 0); + + /// Calls acquire(). + int acquire_write (void); + + /// Calls acquire(). + int acquire_write (void (*sleep_hook)(void *), + void *arg = 0, + ACE_Time_Value *timeout = 0); + + /// Lower priority try_acquire(). + int tryacquire_read (void); + + /// Just calls . + int tryacquire_write (void); + + /// Assumes the caller has acquired the token and returns 0. + int tryacquire_write_upgrade (void); + + // = Accessor methods. + + /// Return the number of threads that are currently waiting to get + /// the token. + int waiters (void); + + /// Return the id of the current thread that owns the token. + ACE_thread_t current_owner (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// The following structure implements a LIFO/FIFO queue of waiter threads + /// that are asleep waiting to obtain the token. + struct ACE_Token_Queue_Entry + { + /// Constructor + ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id); + + /// Constructor using a pre-allocated attributes + ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id, + ACE_Condition_Attributes &attributes); + + /// Entry blocks on the token. + int wait (ACE_Time_Value *timeout, ACE_Thread_Mutex &lock); + + /// Notify (unblock) the entry. + int signal (void); + + /// Pointer to next waiter. + ACE_Token_Queue_Entry *next_; + + /// ACE_Thread id of this waiter. + ACE_thread_t thread_id_; + +#if defined (ACE_TOKEN_USES_SEMAPHORE) + /// ACE_Semaphore object used to wake up waiter when it can run again. + ACE_Semaphore cv_; +#else + /// ACE_Condition object used to wake up waiter when it can run again. + ACE_Condition_Thread_Mutex cv_; +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + + /// Ok to run. + int runable_; + }; + +private: + enum ACE_Token_Op_Type + { + READ_TOKEN = 1, + WRITE_TOKEN + }; + + struct ACE_Token_Queue + { + /// Constructor + ACE_Token_Queue (void); + + /// Remove a waiter from the queue. + void remove_entry (ACE_Token_Queue_Entry *); + + /// Insert a waiter into the queue. + void insert_entry (ACE_Token_Queue_Entry &entry, + int requeue_position = -1); + + /// Head of the list of waiting threads. + ACE_Token_Queue_Entry *head_; + + /// Tail of the list of waiting threads. + ACE_Token_Queue_Entry *tail_; + }; + + /// Implements the and methods above. + int shared_acquire (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout, + ACE_Token_Op_Type op_type); + + /// Wake next in line for ownership. + void wakeup_next_waiter (void); + + /// A queue of writer threads. + ACE_Token_Queue writers_; + + /// A queue of reader threads. + ACE_Token_Queue readers_; + + /// ACE_Thread_Mutex used to lock internal data structures. + ACE_Thread_Mutex lock_; + + /// Current owner of the token. + ACE_thread_t owner_; + + /// Some thread (i.e., ) is using the token. We need this + /// extra variable to deal with POSIX pthreads madness... + int in_use_; + + /// Number of waiters. + int waiters_; + + /// Current nesting level. + int nesting_level_; + + /// The attributes for the condition variables, optimizes lock time. + ACE_Condition_Attributes attributes_; + + /// Queueing strategy, LIFO/FIFO. + int queueing_strategy_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#else + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Export ACE_Token +{ +public: + int queueing_strategy (void) { ACE_NOTSUP_RETURN (-1); } + void queueing_strategy (int /*queueing_strategy*/) { } + int acquire (ACE_Time_Value * = 0) { ACE_NOTSUP_RETURN (-1); } + int tryacquire (void) { ACE_NOTSUP_RETURN (-1); } + int remove (void) { ACE_NOTSUP_RETURN (-1); } + int release (void) { ACE_NOTSUP_RETURN (-1); } +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Export ACE_Noop_Token : public ACE_Null_Mutex +{ +public: + /// Queueing strategy + enum QUEUEING_STRATEGY + { + FIFO = -1, + LIFO = 0 + }; + + /// Get queueing strategy. + int queueing_strategy (void); + + /// Set queueing strategy. + void queueing_strategy (int queueing_strategy); + + int renew (int = 0, ACE_Time_Value * =0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Token.inl" +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" +#endif /* ACE_TOKEN_H */ diff --git a/dep/ACE_wrappers/ace/Token.inl b/dep/ACE_wrappers/ace/Token.inl new file mode 100644 index 000000000..f09a0e6f3 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token.inl @@ -0,0 +1,176 @@ +// -*- C++ -*- +// +// $Id: Token.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/config-macros.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Guard_T.h" +#include "ace/Time_Value.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_Token::queueing_strategy (void) +{ + return this->queueing_strategy_; +} + +ACE_INLINE void +ACE_Token::queueing_strategy (int queueing_strategy) +{ + this->queueing_strategy_ = queueing_strategy == -1 ? -1 : 0; +} + +ACE_INLINE int +ACE_Token::remove (void) +{ + ACE_TRACE ("ACE_Token::remove"); + // Don't have an implementation for this yet... + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_Token::tryacquire (void) +{ + ACE_TRACE ("ACE_Token::tryacquire"); + return this->shared_acquire + (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero, ACE_Token::WRITE_TOKEN); +} + +ACE_INLINE int +ACE_Token::waiters (void) +{ + ACE_TRACE ("ACE_Token::waiters"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + int const ret = this->waiters_; + return ret; +} + +ACE_INLINE ACE_thread_t +ACE_Token::current_owner (void) +{ + ACE_TRACE ("ACE_Token::current_owner"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, this->owner_); + + return this->owner_; +} + +ACE_INLINE int +ACE_Token::acquire_read (void) +{ + ACE_TRACE ("ACE_Token::acquire_read"); + return this->shared_acquire + (0, 0, 0, ACE_Token::READ_TOKEN); +} + +ACE_INLINE int +ACE_Token::acquire_write (void) +{ + ACE_TRACE ("ACE_Token::acquire_write"); + return this->shared_acquire + (0, 0, 0, ACE_Token::WRITE_TOKEN); +} + +ACE_INLINE int +ACE_Token::tryacquire_read (void) +{ + ACE_TRACE ("ACE_Token::tryacquire_read"); + return this->shared_acquire + (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero, ACE_Token::READ_TOKEN); +} + +ACE_INLINE int +ACE_Token::acquire_read (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::acquire_read"); + return this->shared_acquire (sleep_hook_func, arg, timeout, ACE_Token::READ_TOKEN); +} + +ACE_INLINE int +ACE_Token::tryacquire_write (void) +{ + ACE_TRACE ("ACE_Token::tryacquire_write"); + return this->shared_acquire + (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero, ACE_Token::WRITE_TOKEN); +} + +ACE_INLINE int +ACE_Token::tryacquire_write_upgrade (void) +{ + ACE_TRACE ("ACE_Token::tryacquire_write_upgrade"); + return 0; +} + +ACE_INLINE int +ACE_Token::acquire_write (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::acquire_write"); + return this->shared_acquire (sleep_hook_func, arg, timeout, ACE_Token::WRITE_TOKEN); +} + +ACE_INLINE int +ACE_Token::ACE_Token_Queue_Entry::wait (ACE_Time_Value *timeout, ACE_Thread_Mutex &lock) +{ +#if defined (ACE_TOKEN_USES_SEMAPHORE) + lock.release (); + int const retv = (timeout == 0 ? + this->cv_.acquire () : + this->cv_.acquire (*timeout)); + lock.acquire (); + return retv; +#else + ACE_UNUSED_ARG (lock); + return this->cv_.wait (timeout); +#endif /* ACE_TOKEN_USES_SEMAPHORE */ +} + +ACE_INLINE int +ACE_Token::ACE_Token_Queue_Entry::signal (void) +{ + return +#if defined (ACE_TOKEN_USES_SEMAPHORE) + this->cv_.release (); +#else + this->cv_.signal (); +#endif /* ACE_TOKEN_USES_SEMAPHORE */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ + +/*****************************************************************************/ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_Noop_Token::queueing_strategy (void) +{ + return -1; +} + +ACE_INLINE void +ACE_Noop_Token::queueing_strategy (int /* queueing_strategy */) +{ +} + +ACE_INLINE int +ACE_Noop_Token::renew (int, ACE_Time_Value *) +{ + return 0; +} + +ACE_INLINE void +ACE_Noop_Token::dump (void) const +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + diff --git a/dep/ACE_wrappers/ace/Token_Collection.cpp b/dep/ACE_wrappers/ace/Token_Collection.cpp new file mode 100644 index 000000000..23a5813c9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Collection.cpp @@ -0,0 +1,294 @@ +#include "ace/Token_Collection.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#if !defined (__ACE_INLINE__) +#include "ace/Token_Collection.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID (ace, + Token_Collection, + "$Id: Token_Collection.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Token_Collection::ACE_Token_Collection (bool debug, + const ACE_TCHAR *name) +: debug_ (debug) +{ + ACE_TRACE ("ACE_Token_Collection::ACE_Token_Collection"); + + if (name == 0) + name = ACE_TEXT ("no name"); + + ACE_OS::strsncpy (this->name_, + const_cast (name), + ACE_MAXTOKENNAMELEN); +} + +int +ACE_Token_Collection::insert (ACE_Token_Proxy &new_token) +{ + ACE_TRACE ("ACE_Token_Collection::insert"); + + TOKEN_NAME name (new_token.name ()); + + // Check if the new_proxy is already in the list. + if (collection_.find (name) == 1) + // One already exists, so fail. + return -1; + + // Clone the new token. + ACE_Token_Proxy *temp = new_token.clone (); + + if (collection_.bind (name, temp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("bind failed\n")), -1); + return 0; +} + +int +ACE_Token_Collection::extract (const ACE_TCHAR *token_name, ACE_Token_Proxy *&proxy) +{ + ACE_TRACE ("ACE_Token_Collection::extract"); + TOKEN_NAME name (token_name); + return collection_.unbind (token_name, proxy); +} + +ACE_Token_Proxy * +ACE_Token_Collection::is_member (const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Collection::is_member"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // Get the token from the collection. + return collection_.find (name, temp) == -1 ? 0 : temp; +} + +int +ACE_Token_Collection::is_member (const ACE_Token_Proxy &token) +{ + ACE_TRACE ("ACE_Token_Collection::is_member"); + TOKEN_NAME token_name (token.name ()); + return collection_.find (token_name) == 0; +} + +int +ACE_Token_Collection::acquire (int notify, + void (*sleep_hook)(void *), + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::acquire"); + + COLLECTION::ITERATOR iterator (collection_); + + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("collection acquiring %s\n"), + temp->int_id_->name ())); + if (temp->int_id_->acquire (notify, + sleep_hook, + options) == -1) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + this->release (); + ACE_RETURN (-1); + } + } + + return 0; +} + +int +ACE_Token_Collection::acquire (const ACE_TCHAR *token_name, + int notify, + void (*sleep_hook)(void *), + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::acquire"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // Get the token from the collection. + int result = collection_.find (name, temp); + // did we find it? + if (result == -1) + return result; + // perform the operation + return temp->acquire (notify, sleep_hook, options); +} + + +int +ACE_Token_Collection::tryacquire (const ACE_TCHAR *token_name, + void (*sleep_hook)(void *)) +{ + ACE_TRACE ("ACE_Token_Collection::tryacquire"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // Get the token from the collection. + int result = collection_.find (name, temp); + // did we find it? + if (result == -1) + return result; + + // perform the operation + return temp->tryacquire (sleep_hook); +} + +int +ACE_Token_Collection::tryacquire (void (*sleep_hook)(void *)) +{ + ACE_TRACE ("ACE_Token_Collection::tryacquire"); + + COLLECTION::ITERATOR iterator (collection_); + + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("collection acquiring %s\n"), + temp->int_id_->name ())); + // We will fail if _any_ token is not free. + if (temp->int_id_->tryacquire (sleep_hook) == -1) + return -1; + } + + return 0; +} + +int +ACE_Token_Collection::renew (int requeue_position, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::renew"); + + COLLECTION::ITERATOR iterator (collection_); + + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("collection renewing %s\n"), + temp->int_id_->name ())); + if (temp->int_id_->renew (requeue_position, options) == -1) + return -1; + } + + return 0; +} + +int +ACE_Token_Collection::renew (const ACE_TCHAR *token_name, + int requeue_position, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::renew"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + + // Get the token from the collection. + int result = collection_.find (name, temp); + + // Did we find it? + if (result == -1) + ACE_ERROR_RETURN ((LM_DEBUG, ACE_TEXT ("%p %s\n"), + ACE_TEXT ("not in collection "), + token_name), -1); + // perform the operation + return temp->renew (requeue_position, options); +} + +int +ACE_Token_Collection::release (ACE_Synch_Options &) + +{ + ACE_TRACE ("ACE_Token_Collection::release"); + COLLECTION::ITERATOR iterator (collection_); + + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("collection releasing %s\n"), + temp->int_id_->name ())); + temp->int_id_->release (); + } + + return 0; +} + +int +ACE_Token_Collection::release (const ACE_TCHAR *token_name, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::release"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // get the token from the collection + int result = collection_.find (name, temp); + // did we find it? + if (result != 0) + return result; + // perform the operation + return temp->release (options); +} + +ACE_Token_Collection::~ACE_Token_Collection (void) +{ + ACE_TRACE ("ACE_Token_Collection::~ACE_Token_Collection"); + COLLECTION::ITERATOR iterator (collection_); + + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + delete temp->int_id_; + // The ext_id_'s delete themselves when the array of + // COLLECTION::ENTRYs goes away. + } +} + + +// This method doesn't mean anything for a collection. +ACE_Token_Proxy * +ACE_Token_Collection::clone (void) const +{ + ACE_TRACE ("ACE_Token_Collection::clone"); + return (ACE_Token_Proxy *) 0; +} + +// This method doesn't mean anything for a collection. +ACE_Tokens * +ACE_Token_Collection::create_token (const ACE_TCHAR *) +{ + ACE_TRACE ("ACE_Token_Collection::create_token"); + return (ACE_Tokens *) 0; +} + +void +ACE_Token_Collection::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Token_Collection::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Collection::dump:\n") + ACE_TEXT (" debug_ = %d\n"), debug_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("collection_\n"))); + collection_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n"))); + ACE_Token_Proxy::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Token_Collection.h b/dep/ACE_wrappers/ace/Token_Collection.h new file mode 100644 index 000000000..16a9bb412 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Collection.h @@ -0,0 +1,243 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Token_Collection.h + * + * $Id: Token_Collection.h 80826 2008-03-04 14:51:23Z wotte $ + * + * The ACE_Token class offers methods for acquiring, renewing, + * and releasing a synchronization token on a per-token basis. The + * ACE_Token_Collection offers an interface for performing + * operations on groups of tokens as a whole, or on a single token + * within the collection. + * + * The atomic group operations are not yet implemented. + * + * + * @author Douglas C. Schmidt (schmidt@cs.wustl.edu) + * @author Tim Harrison (harrison@cs.wustl.edu) + */ +//============================================================================= + +#ifndef ACE_TOKEN_COLLECTION_H +#define ACE_TOKEN_COLLECTION_H +#include /**/ "ace/pre.h" + +#include "ace/Map_Manager.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#include "ace/Local_Tokens.h" +#include "ace/Null_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Token_Collection + * + * @brief Allows atomic token group operations AND + * provides a ACE_Token manager interface. + * + * There are two types of operations offered by + * ACE_Token_Collection. The first is atomic operations on + * collections of Token_Proxies. In this respect, the + * ACE_Token_Collection can be thought of as a single token + * consisting of multiple Token_Proxies. The second role of the + * ACE_Token_Collection is as a ACE_Token manager. + * ACE_Token_Collection allows individual operations on single + * members of a collection of Token_Proxies. This provides a + * single access point for operations on multiple tokens. + * + * @bug Although ACE_Token_Collection inherits from ACE_Token_Proxy, it + * can not be including in a collection. This is because + * returns zero for now. + * + */ +class ACE_Export ACE_Token_Collection : public ACE_Token_Proxy +{ +public: + /** + * @a debug print out verbose debugging messages. @a name will give a + * name to the collection. Collections don't really need names, but + * are sometimes useful for debugging. + */ + ACE_Token_Collection (bool debug = false, + const ACE_TCHAR *name = 0); + +// Collection Management operations + + /** + * Insert a Token into the collection. All ACE_Token type + * operations performed on the collection will also be performed on + * the new_proxy until it is removed. Note that no operations + * performed prior to the insertion will be performed. Returns: 0 + * on success, -1 on failure with @c errno == problem. If a token + * proxy already exists in the collection with the same name, the + * insertion will fail. Also, is copied. Note that during + * the copy, client_id's are *not* inherited. The client ID of the + * thread using the collection will be used. Client ID's can be + * changed explicity on each proxy using is_member. + */ + int insert (ACE_Token_Proxy &token); + + /** + * Removes the ACE_Token matching the given token_name from the + * collection. On success, extract returns 0. On failure + * (token_name was not in the collection,) extract returns -1. On + * success, the state of the token found is copied into proxy. + * The returned ACE_Token_Proxy* must be deleted by the user. + */ + int extract (const ACE_TCHAR *token_name, ACE_Token_Proxy *&proxy); + + /// Returns the proxy if true. 0 otherwise. + ACE_Token_Proxy *is_member (const ACE_TCHAR *token_name); + + /** + * Is the specified token in the collection? + * 1, yes. + * 0, no. + */ + int is_member (const ACE_Token_Proxy &token); + +// = Collective operation semantics. + +// For acquire, renew, and release, there are two interfaces. Once +// interface allows an operation on a single token in the +// collection. The collective interfaces perform atomic operations +// on the entire collection. For instance, a collective acquire +// will perform an acquire for each and every token in the +// collection or the operation will fail. Currently, these +// operations are performed with no ordering heuristics. That is, +// the Collection steps through the tokens in the order they were +// inserted. For each one it performs the operation (acquire, +// renew, or release). + + /** + * Acquire "atomically" all resources in the collection. This is + * only successfull if all tokens in the collection could be + * acquired. options contains the blocking semantics, timeout + * value, etc. Returns: 0 on success, -1 on failure with @c errno == + * problem. If and error or deadlock occurs for one of the tokens, + * all the tokens will be released and the method will return -1. + * Note that returning on detection of deadlock prevents livelock + * between competing collections. If a collection returns after + * detecting deadlock, it is the application's responsibility to not + * to blindly loop on the collection::acquire operation. In other + * words, once the collection reports deadlock, it is out of our + * hands. + */ + virtual int acquire (int notify = 0, + void (*sleep_hook)(void *) = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + + /// Acquire the token corresponding to @a token_name. The other + /// parameters are passed to ::acquire. + virtual int acquire (const ACE_TCHAR *token_name, + int notify = 0, + void (*sleep_hook)(void *) = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + + /// Try to acquire all tokens in collection. + virtual int tryacquire (void (*sleep_hook)(void *) = 0); + + /// Try to acquire @a token_name. + virtual int tryacquire (const ACE_TCHAR *token_name, + void (*sleep_hook)(void *) = 0); + + /** + * Renews "atomically" all resources in the collection. This is + * only successfull if all tokens in the collection could be + * renewed. options contains the blocking semantics, timeout + * value, etc. Returns: 0 on success, -1 on failure with @c errno == + * problem. + */ + virtual int renew (int requeue_position = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + + + /// Renew the token corresponding to @a token_name. The other + /// parameters are passed to ::renew. + virtual int renew (const ACE_TCHAR *token_name, + int requeue_position = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + + /** + * Releases "atomically" all resources in the collection. This is + * only successfull if all tokens in the collection could be + * released. options contains the blocking semantics, timeout + * value, etc. Returns: 0 on success, -1 on failure with @c errno == + * problem. + */ + virtual int release (ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + + + /// Release the token corresponding to . The other + /// parameters are passed to ::release. + virtual int release (const ACE_TCHAR *token_name, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + + ~ACE_Token_Collection (void); + + /// Dump the state of the class. + void dump (void) const; + + /// Return the name of the collection. Not very functionally + /// important, but sometimes a useful debugging tool. + virtual const ACE_TCHAR *name (void) const; + +protected: + + typedef ACE_Token_Name TOKEN_NAME; + + /// COLLECTION maintains a mapping from token names to ACE_Tokens* + typedef ACE_Map_Manager + COLLECTION; + + /// Allows iterations through collection_ + /** + * @deprecated Deprecated typedef. Use COLLECTION::ITERATOR trait instead. + */ + typedef COLLECTION::ITERATOR COLLECTION_ITERATOR; + + /// Allows iterations through collection_ + /** + * @deprecated Deprecated typedef. Use COLLECTION::ENTRY trait instead. + */ + typedef COLLECTION::ENTRY COLLECTION_ENTRY; + + /// COLLECTION maintains a mapping from token names to ACE_Tokens*. + COLLECTION collection_; + + /// Whether to print out debug messages or not. + bool debug_; + + /// Name of the collection. + ACE_TCHAR name_[ACE_MAXTOKENNAMELEN]; + + // = I'm not sure what these mean, but they have to be defined since they're + // pure virtual in ACE_Token_Proxy. + virtual ACE_Token_Proxy *clone (void) const; + virtual ACE_Tokens *create_token (const ACE_TCHAR *name); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Token_Collection.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_TOKENS_LIBRARY */ + +#include /**/ "ace/post.h" +#endif /* ACE_TOKEN_COLLECTION_H */ diff --git a/dep/ACE_wrappers/ace/Token_Collection.inl b/dep/ACE_wrappers/ace/Token_Collection.inl new file mode 100644 index 000000000..73f1e95d7 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Collection.inl @@ -0,0 +1,17 @@ +// -*- C++ -*- +// +// $Id: Token_Collection.inl 80826 2008-03-04 14:51:23Z wotte $ + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE const ACE_TCHAR * +ACE_Token_Collection::name (void) const +{ + return name_; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Token_Invariants.cpp b/dep/ACE_wrappers/ace/Token_Invariants.cpp new file mode 100644 index 000000000..6c5d1bd52 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Invariants.cpp @@ -0,0 +1,355 @@ +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#include "ace/Object_Manager.h" + +ACE_RCSID (ace, + Token_Invariants, + "$Id: Token_Invariants.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_Token_Invariant_Manager *ACE_Token_Invariant_Manager::instance_ = 0; + +ACE_Token_Invariant_Manager * +ACE_Token_Invariant_Manager::instance (void) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::instance"); + + // Perform the Double-Check pattern... + if (instance_ == 0) + { + ACE_MT (ACE_TOKEN_CONST::MUTEX *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_TOKEN_INVARIANTS_CREATION_LOCK); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, *lock, 0)); + + if (instance_ == 0) + { + ACE_NEW_RETURN (instance_, + ACE_Token_Invariant_Manager, + 0); + // Register for destruction with ACE_Object_Manager. + ACE_Object_Manager::at_exit (instance_); + } + } + + return instance_; +} + +ACE_Token_Invariant_Manager::ACE_Token_Invariant_Manager (void) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::ACE_Token_Invariant_Manager"); +} + +int +ACE_Token_Invariant_Manager::mutex_acquired (const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::mutex_acquired"); + + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + ACE_Mutex_Invariants *inv = 0; + if (this->get_mutex (token_name, inv) == -1) + return -1; + + return inv->acquired (); +} + +int +ACE_Token_Invariant_Manager::acquired (const ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::acquired"); + + // Reach into the proxy to find the token type. + if (proxy->token_->type () == ACE_Tokens::MUTEX) + return this->mutex_acquired (proxy->name ()); + else // ACE_Tokens::RWLOCK. + { + if (proxy->type () == ACE_RW_Token::READER) + return this->reader_acquired (proxy->name ()); + else // ACE_RW_Token::WRITER. + return this->writer_acquired (proxy->name ()); + } +} + +void +ACE_Token_Invariant_Manager::releasing (const ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::releasing"); + + // Reach into the proxy to find the token type. + if (proxy->token_->type () == ACE_Tokens::MUTEX) + this->mutex_releasing (proxy->name ()); + else // ACE_Tokens::RWLOCK. + this->rwlock_releasing (proxy->name ()); +} + +void +ACE_Token_Invariant_Manager::mutex_releasing (const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::mutex_releasing"); + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + ACE_Mutex_Invariants *inv = 0; + if (this->get_mutex (token_name, inv) == 0) + inv->releasing (); +} + +int +ACE_Token_Invariant_Manager::reader_acquired (const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::reader_acquired"); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + ACE_RWLock_Invariants *inv = 0; + if (this->get_rwlock (token_name, inv) == -1) + return -1; + + return inv->reader_acquired (); +} + +int +ACE_Token_Invariant_Manager::writer_acquired (const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::writer_acquired"); + + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + ACE_RWLock_Invariants *inv = 0; + if (this->get_rwlock (token_name, inv) == -1) + return -1; + + return inv->writer_acquired (); +} + +void +ACE_Token_Invariant_Manager::rwlock_releasing (const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::rwlock_releasing"); + + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + ACE_RWLock_Invariants *inv = 0; + if (this->get_rwlock (token_name, inv) == 0) + inv->releasing (); +} + +void +ACE_Token_Invariant_Manager::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Token_Invariant_Manager::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("mutex_collection_:\n"))); + mutex_collection_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("rwlock_collection_:\n"))); + rwlock_collection_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + + +int +ACE_Token_Invariant_Manager::get_mutex (const ACE_TCHAR *token_name, + ACE_Mutex_Invariants *&inv) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::get_mutex"); + TOKEN_NAME name (token_name); + if (mutex_collection_.find (name, inv) == -1) + // We did not find one in the collection. + { + ACE_Mutex_Invariants *new_invariant; + + ACE_NEW_RETURN (new_invariant, + ACE_Mutex_Invariants, + -1); + if (mutex_collection_.bind (name, new_invariant) == -1) + { + delete new_invariant; + return -1; + } + + if (mutex_collection_.find (name, inv) == -1) + // We did not find one in the collection. + return -1; + } + + return 0; +} + +int +ACE_Token_Invariant_Manager::get_rwlock (const ACE_TCHAR *token_name, + ACE_RWLock_Invariants *&inv) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::get_rwlock"); + TOKEN_NAME name (token_name); + if (rwlock_collection_.find (name, inv) == -1) + // We did not find one in the collection. + { + ACE_RWLock_Invariants *new_invariant; + + ACE_NEW_RETURN (new_invariant, + ACE_RWLock_Invariants, + -1); + if (rwlock_collection_.bind (name, new_invariant) == -1) + return -1; + + if (rwlock_collection_.find (name, inv) == -1) + // We did not find one in the collection. + return -1; + } + + return 0; +} + + +ACE_Token_Invariant_Manager::~ACE_Token_Invariant_Manager (void) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::~ACE_Token_Invariant_Manager"); + + MUTEX_COLLECTION::ITERATOR iterator (mutex_collection_); + + for (MUTEX_COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + delete temp->int_id_; + + RWLOCK_COLLECTION::ITERATOR iterator2 (rwlock_collection_); + + for (RWLOCK_COLLECTION::ENTRY *temp2 = 0; + iterator2.next (temp2) != 0; + iterator2.advance ()) + delete temp2->int_id_; +} + +// ************************************************** +// ************************************************** +// ************************************************** + +ACE_Mutex_Invariants::ACE_Mutex_Invariants (void) +: owners_ (0) +{ +} + +int +ACE_Mutex_Invariants::acquired (void) +{ + if (++owners_ > 1) + { + owners_ = 42; + return 0; + } + else + return 1; +} + +void +ACE_Mutex_Invariants::releasing (void) +{ + if (owners_ == 1) + --owners_; +} + +ACE_Mutex_Invariants::ACE_Mutex_Invariants (const ACE_Mutex_Invariants &rhs) +: owners_ (rhs.owners_) +{ +} + +void +ACE_Mutex_Invariants::operator= (const ACE_Mutex_Invariants &rhs) +{ + owners_ = rhs.owners_; +} + +void +ACE_Mutex_Invariants::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Mutex_Invariants::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("owners_ = %d\n"), owners_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// ************************************************** +// ************************************************** +// ************************************************** + +ACE_RWLock_Invariants::ACE_RWLock_Invariants (void) +: writers_ (0), + readers_ (0) +{ +} + +int +ACE_RWLock_Invariants::writer_acquired (void) +{ + if (readers_ > 0) + { + writers_ = readers_ = 42; + return 0; + } + else if (++writers_ > 1) + { + writers_ = readers_ = 42; + return 0; + } + else + return 1; +} + +int +ACE_RWLock_Invariants::reader_acquired (void) +{ + if (writers_ > 0) + { + writers_ = readers_ = 42; + return 0; + } + else + { + ++readers_; + return 1; + } +} + +void +ACE_RWLock_Invariants::releasing (void) +{ + if (writers_ == 1) + writers_ = 0; + else if (readers_ > 0) + --readers_; +} + +ACE_RWLock_Invariants::ACE_RWLock_Invariants (const ACE_RWLock_Invariants &rhs) +: writers_ (rhs.writers_), + readers_ (rhs.readers_) +{ +} + +void +ACE_RWLock_Invariants::operator= (const ACE_RWLock_Invariants &rhs) +{ + writers_ = rhs.writers_; + readers_ = rhs.readers_; +} + +void +ACE_RWLock_Invariants::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_RWLock_Invariants::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("writers_ = %d readers_ = %d\n"), + writers_, readers_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Token_Invariants.h b/dep/ACE_wrappers/ace/Token_Invariants.h new file mode 100644 index 000000000..5cec39476 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Invariants.h @@ -0,0 +1,245 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Token_Invariants.h + * + * $Id: Token_Invariants.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Tim Harrison (harrison@cs.wustl.edu) + * + * Allows applications to test that invariants are always + * satisfied. Can test mutexes and readers/writer locks. Does + * not test recursive acquisition. + * + * + */ +//============================================================================= + +#ifndef ACE_TOKEN_INVARIANTS_H +#define ACE_TOKEN_INVARIANTS_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#include "ace/Map_Manager.h" +#include "ace/Local_Tokens.h" +#include "ace/Null_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Mutex_Invariants + * + * @brief Mutex Invariants + * = INVARIANTS + * 1. Only one owner at a time. + */ +class ACE_Export ACE_Mutex_Invariants +{ +public: + /// Default construction. + ACE_Mutex_Invariants (void); + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int acquired (void); + + /// Updates internal database. + void releasing (void); + + // = Map_Manager operations. + + /// Copy construction. + ACE_Mutex_Invariants (const ACE_Mutex_Invariants &rhs); + + /// Copy. + void operator= (const ACE_Mutex_Invariants &rhs); + + /// Dump the state of the class. + void dump (void) const; + +private: + /// Number of owners. This had better be 0 >= owners_ <= 1; + int owners_; +}; + +/** + * @class ACE_RWLock_Invariants + * + * @brief RWLock Invariants + * + * Preserve the following invariants: + * -# Only one writer at a time. + * -# If there is an owning writer, there are no owning readers. + */ +class ACE_Export ACE_RWLock_Invariants +{ +public: + /// Default construction. + ACE_RWLock_Invariants (void); + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int writer_acquired (void); + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int reader_acquired (void); + + /// Updates internal database. + void releasing (void); + + // = Map_Manager operations. + + /// Copy construction. + ACE_RWLock_Invariants (const ACE_RWLock_Invariants &rhs); + + /// Copy. + void operator= (const ACE_RWLock_Invariants &rhs); + + /// Dump the state of the class. + void dump (void) const; + +private: + /// Number of owning writers. + int writers_; + + /// Number of owning readers. + int readers_; +}; + +/** + * @class ACE_Token_Invariant_Manager + * + * @brief Token Invariants + * + * The Token Invariant Manager allows applications to test that + * invariants are always satisfied. Currently, Token_Invariants + * can test mutexes and readers/writer locks. Does not test + * recursive acquisition. + * Note that this class does not ever clean its database. Until + * destroyed, it's size will forever increase. + */ +class ACE_Export ACE_Token_Invariant_Manager : public ACE_Cleanup +{ +public: + + /// Singleton access point. + static ACE_Token_Invariant_Manager *instance (void); + + // = Polymorphic methods. Just pass in the proxy and the method + // figures out the type of the token. + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int acquired (const ACE_Token_Proxy *proxy); + + /// Updates internal database. + void releasing (const ACE_Token_Proxy *proxy); + + // = Explicit methods. These to not require actual proxies in order + // to test a scenario. + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int mutex_acquired (const ACE_TCHAR *token_name); + + /// Updates internal database. + void mutex_releasing (const ACE_TCHAR *token_name); + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int reader_acquired (const ACE_TCHAR *token_name); + + /// Returns 1 on success, 0 when an invariant has been violated and + /// -1 on error. + int writer_acquired (const ACE_TCHAR *token_name); + + /// Updates internal database. + void rwlock_releasing (const ACE_TCHAR *token_name); + + /// Dump the state of the class. + void dump (void) const; + + // = The following two method should be in the protected part of the + // class. Bugs with certain compilers preclude this. + /// Prevent non-singleton construction. + ACE_Token_Invariant_Manager (void); + + /// Destruction. + virtual ~ACE_Token_Invariant_Manager (void); + +protected: + /// Return or create. + int get_mutex (const ACE_TCHAR *token_name, + ACE_Mutex_Invariants *&inv); + + /// Return or create. + int get_rwlock (const ACE_TCHAR *token_name, + ACE_RWLock_Invariants *&inv); + + /// ACE_Mutex_Token used to lock internal data structures. + ACE_TOKEN_CONST::MUTEX lock_; + + /// This may be changed to a template type. + typedef ACE_Token_Name TOKEN_NAME; + + /// COLLECTION maintains a mapping from token names to mutexes. + typedef ACE_Map_Manager + MUTEX_COLLECTION; + + /// Allows iterations through collection. + /** + * @deprecated Deprecated typedef. Use MUTEX_COLLECTION::ITERATOR trait + * instead. + */ + typedef MUTEX_COLLECTION::ITERATOR MUTEX_COLLECTION_ITERATOR; + + /// Allows iterations through collection. + /** + * @deprecated Deprecated typedef. Use MUTEX_COLLECTION::ENTRY trait + * instead. + */ + typedef MUTEX_COLLECTION::ENTRY MUTEX_COLLECTION_ENTRY; + + /// MUTEX_COLLECTION maintains a mapping from token names to mutexes. + MUTEX_COLLECTION mutex_collection_; + + /// COLLECTION maintains a mapping from token names to mutexes. + typedef ACE_Map_Manager + RWLOCK_COLLECTION; + + /// Allows iterations through collection. + /** + * @deprecated Deprecated typedef. Use RWLOCK_COLLECTION::ITERATOR trait + * instead. + */ + typedef RWLOCK_COLLECTION::ITERATOR RWLOCK_COLLECTION_ITERATOR; + + /// Allows iterations through collection. + /** + * @deprecated Deprecated typedef. Use RWLOCK_COLLECTION::ENTRY trait + * instead. + */ + typedef RWLOCK_COLLECTION::ENTRY RWLOCK_COLLECTION_ENTRY; + + /// MUTEX_COLLECTION maintains a mapping from token names to mutexes. + RWLOCK_COLLECTION rwlock_collection_; + + /// Singleton pointer. + static ACE_Token_Invariant_Manager *instance_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ + +#include /**/ "ace/post.h" +#endif /* ACE_TOKEN_INVARIANTS_H */ diff --git a/dep/ACE_wrappers/ace/Token_Manager.cpp b/dep/ACE_wrappers/ace/Token_Manager.cpp new file mode 100644 index 000000000..22b6e9f9e --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Manager.cpp @@ -0,0 +1,273 @@ +#include "ace/Token_Manager.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#include "ace/Object_Manager.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Token_Manager.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Token_Manager, + "$Id: Token_Manager.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// singleton token manager +ACE_Token_Manager *ACE_Token_Manager::token_manager_ = 0; + +ACE_Token_Manager::ACE_Token_Manager () +{ + ACE_TRACE ("ACE_Token_Manager::ACE_Token_Manager"); +} + +ACE_Token_Manager::~ACE_Token_Manager () +{ + ACE_TRACE ("ACE_Token_Manager::~ACE_Token_Manager"); + + COLLECTION::ITERATOR iterator (collection_); + + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + // @ should I be doing an unbind here? + delete temp->int_id_; + // The ext_id_'s delete themselves when the array of + // COLLECTION::ENTRYs goes away. + } +} + +ACE_Token_Manager * +ACE_Token_Manager::instance (void) +{ + ACE_TRACE ("ACE_Token_Manager::instance"); + + // This first check is to avoid acquiring the mutex in the common + // case. Double-Check pattern rules. + if (token_manager_ == 0) + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_TOKEN_CONST::MUTEX *lock = + ACE_Managed_Object::get_preallocated_object + (ACE_Object_Manager::ACE_TOKEN_MANAGER_CREATION_LOCK); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, *lock, 0); +#endif /* ACE_MT_SAFE */ + + if (token_manager_ == 0) + { + ACE_NEW_RETURN (token_manager_, + ACE_Token_Manager, + 0); + // Register for destruction with ACE_Object_Manager. + ACE_Object_Manager::at_exit (token_manager_); + } + } + + return token_manager_; +} + +void +ACE_Token_Manager::get_token (ACE_Token_Proxy *proxy, + const ACE_TCHAR *token_name) +{ + ACE_TRACE ("ACE_Token_Manager::get_token"); + // Hmm. I think this makes sense. We perform our own locking here + // (see safe_acquire.) We have to make sure that only one thread + // uses the collection at a time. + + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + TOKEN_NAME name (token_name); + + if (collection_.find (name, proxy->token_) == -1) + // We did not find one in the collection. + { + // Make one. + proxy->token_ = proxy->create_token (token_name); + + // Put it in the collection. + if (collection_.bind (name, proxy->token_) == -1) + { + delete proxy->token_; + proxy->token_ = 0; + } + } + + if (proxy->token_ != 0) + proxy->token_->inc_reference (); + + // We may be returning proxy->token_ == 0 if new failed, caller must + // check. +} + +// 0. check_deadlock (TOKEN) +// 1. if TOKEN->visited (), return 0. +// 2. mark TOKEN visited. +// 3. get ALL_OWNERS +// 4. if CLIENT in ALL_OWNERS, return *DEADLOCK*. +// 5. for each OWNER in ALL_OWNERS, +// 6. if OWNER is not waiting for a NEW_TOKEN, continue. +// 7. else, if check_deadlock (NEW_TOKEN) == 1, return *DEADLOCK* +// 8. return 0. + +int +ACE_Token_Manager::check_deadlock (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Manager::check_deadlock"); + + // Start the recursive deadlock detection algorithm. + int result = this->check_deadlock (proxy->token_, proxy); + + // Whether or not we detect deadlock, we have to unmark all tokens + // for the next time. + COLLECTION::ITERATOR iterator (collection_); + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + temp->int_id_->visit (0); + + return result; +} + +int +ACE_Token_Manager::check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Manager::check_deadlock"); + + if (token->visited ()) + return 0; + + token->visit (1); + + ACE_Tokens::OWNER_STACK owners; + + int is_owner = token->owners (owners, proxy->client_id ()); + + switch (is_owner) + { + case -1: + // Error. + return -1; + case 1: + // The caller is an owner, so we have a deadlock situation. + if (debug_) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Deadlock detected.\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s owns %s and is waiting for %s.\n"), + proxy->client_id (), + token->name (), + proxy->token_->name ())); + } + + return 1; + case 0: + default: + // Recurse on each owner. + while (!owners.is_empty ()) + { + ACE_TPQ_Entry *e; + owners.pop (e); + // If the owner is waiting on another token, recurse. + ACE_Tokens *twf = this->token_waiting_for (e->client_id ()); + if ((twf != 0) && + (this->check_deadlock (twf, proxy) == 1)) + { + if (debug_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%s owns %s and is waiting for %s.\n"), + e->client_id (), + token->name (), + twf->name ())); + } + return 1; + } + // else, check the next owner. + } + + // We've checked all the owners and found no deadlock. + return 0; + } +} + + +ACE_Tokens * +ACE_Token_Manager::token_waiting_for (const ACE_TCHAR *client_id) +{ + COLLECTION::ITERATOR iterator (collection_); + for (COLLECTION::ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->int_id_->is_waiting_for (client_id)) + return temp->int_id_; + } + + // nothing was found, return NULL. + return 0; +} + +// Notify the token manager that a token is has been released. If +// as a result, there is no owner of the token, the token is +// deleted. +void +ACE_Token_Manager::release_token (ACE_Tokens *&token) +{ + ACE_TRACE ("ACE_Token_Manager::release_token"); + // again, let's perform our own locking here. + + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + if (token->dec_reference () == 0) + { + // No one has the token, so we can delete it and remove it from + // our collection. First, let's get it from the collection. + TOKEN_NAME token_name (token->name ()); + + ACE_Tokens *temp; + + if (collection_.unbind (token_name, temp) == -1) + // we did not find one in the collection + { + errno = ENOENT; + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Token Manager could not release %s:%d\n"), + token->name (), token->type ())); + // @@ bad + } + else + // we found it + { + // sanity pointer comparison. The token referenced by the + // proxy better be the one we found in the list. + ACE_ASSERT (token == temp); + delete token; // or delete temp + // we set their token to zero. if the calling proxy is + // still going to be used, it had better check it's token + // value before calling a method on it! + token = 0; + } + } + // else + // someone is still interested in the token, so keep it around. +} + +void +ACE_Token_Manager::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Token_Manager::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Manager::dump:\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("lock_\n"))); + lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("collection_\n"))); + collection_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Token_Manager.h b/dep/ACE_wrappers/ace/Token_Manager.h new file mode 100644 index 000000000..9882e28ef --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Manager.h @@ -0,0 +1,150 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Token_Manager.h + * + * $Id: Token_Manager.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Tim Harrison (harrison@cs.wustl.edu) + */ +//============================================================================= + +#ifndef ACE_TOKEN_MANAGER_H +#define ACE_TOKEN_MANAGER_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Local_Tokens.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#include "ace/Null_Mutex.h" +#include "ace/Map_Manager.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Local_Mutex; +class ACE_Mutex_Token; + +/** + * @class ACE_Token_Manager + * + * @brief Manages all tokens in a process space. + * + * Factory: Proxies use the token manager to obtain token + * references. This allows multiple proxies to reference the same + * logical token. + * Deadlock detection: Tokens use the manager to check for + * deadlock situations during acquires. + */ +class ACE_Export ACE_Token_Manager : public ACE_Cleanup +{ + + // To add a new type of token (e.g. semaphore), do the following + // steps: 1. Create a new derivation of ACE_Token. This class + // defines the semantics of the new Token. 2. Create a + // derivation of ACE_Token_Manager. You will only need to + // redefine make_mutex. +public: + ACE_Token_Manager (void); + virtual ~ACE_Token_Manager (void); + + /// Get the pointer to token manager singleton. + static ACE_Token_Manager *instance (void); + + /// Set the pointer to token manager singleton. + void instance (ACE_Token_Manager *); + + /** + * The Token manager uses ACE_Token_Proxy::token_id_ to look for + * an existing token. If none is found, the Token Manager calls + * ACE_Token_Proxy::create_token to create a new one. When + * finished, sets ACE_Token_Proxy::token_. @a token_name uniquely + * id's the token name. + */ + void get_token (ACE_Token_Proxy *, const ACE_TCHAR *token_name); + + /** + * Check whether acquire will cause deadlock or not. + * returns 1 if the acquire will _not_ cause deadlock. + * returns 0 if the acquire _will_ cause deadlock. + * This method ignores recursive acquisition. That is, it will not + * report deadlock if the client holding the token requests the + * token again. Thus, it assumes recursive mutexes. + */ + int check_deadlock (ACE_Token_Proxy *proxy); + int check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy); + + /// Notify the token manager that a token has been released. If as a + /// result, there is no owner of the token, the token is deleted. + void release_token (ACE_Tokens *&token); + + /** + * This is to allow Tokens to perform atomic transactions. The + * typical usage is to acquire this mutex, check for a safe_acquire, + * perform some queueing (if need be) and then release the lock. + * This is necessary since safe_acquire is implemented in terms of + * the Token queues. + */ + ACE_TOKEN_CONST::MUTEX &mutex (void); + + /// Dump the state of the class. + void dump (void) const; + + /// Turn debug mode on/off. + void debug (bool d); + +private: + /// Whether to print debug messages or not. + bool debug_; + + /// pointer to singleton token manager. + static ACE_Token_Manager *token_manager_; + + /// Return the token that the given client_id is waiting for, if any + ACE_Tokens *token_waiting_for (const ACE_TCHAR *client_id); + + /// ACE_Mutex_Token used to lock internal data structures. + ACE_TOKEN_CONST::MUTEX lock_; + + /// This may be changed to a template type. + typedef ACE_Token_Name TOKEN_NAME; + + /// COLLECTION maintains a mapping from token names to ACE_Tokens* + typedef ACE_Map_Manager + COLLECTION; + + /// Allows iterations through collection_ + /** + * @deprecated Deprecated typedef. Use COLLECTION::ITERATOR trait + * instead. + */ + typedef COLLECTION::ITERATOR COLLECTION_ITERATOR; + + /// Allows iterations through collection_ + /** + * @deprecated Deprecated typedef. Use COLLECTION::ENTRY trait + * instead. + */ + typedef COLLECTION::ENTRY COLLECTION_ENTRY; + + /// COLLECTION maintains a mapping from token names to ACE_Tokens*. + COLLECTION collection_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Token_Manager.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_TOKENS_LIBRARY */ + +#include /**/ "ace/post.h" +#endif /* ACE_TOKEN_MANAGER_H */ diff --git a/dep/ACE_wrappers/ace/Token_Manager.inl b/dep/ACE_wrappers/ace/Token_Manager.inl new file mode 100644 index 000000000..a44778c89 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Manager.inl @@ -0,0 +1,25 @@ +// -*- C++ -*- +// +// $Id: Token_Manager.inl 80826 2008-03-04 14:51:23Z wotte $ + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ACE_TOKEN_CONST::MUTEX & +ACE_Token_Manager::mutex (void) +{ + ACE_TRACE ("ACE_Token_Manager::mutex"); + return lock_; +} + +ACE_INLINE void +ACE_Token_Manager::debug (bool d) +{ + ACE_TRACE ("ACE_Token_Manager::debug"); + debug_ = d; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Token_Request_Reply.cpp b/dep/ACE_wrappers/ace/Token_Request_Reply.cpp new file mode 100644 index 000000000..598afe013 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Request_Reply.cpp @@ -0,0 +1,186 @@ +// $Id: Token_Request_Reply.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/Token_Request_Reply.h" + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#if !defined (__ACE_INLINE__) +#include "ace/Token_Request_Reply.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Token_Request_Reply, "$Id: Token_Request_Reply.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Default "do nothing" constructor. + +ACE_Token_Request::ACE_Token_Request (void) + : token_name_ (0), + client_id_ (0) +{ +} + +// Create a ACE_Token_Request message. + +ACE_Token_Request::ACE_Token_Request (int token_type, + int proxy_type, + ACE_UINT32 operation_type, + const ACE_TCHAR token_name[], + const ACE_TCHAR client_id[], + const ACE_Synch_Options &options) +{ + this->token_type (token_type); + this->proxy_type (proxy_type); + this->operation_type (operation_type); + this->requeue_position (0); // to avoid Purify UMR + this->notify (0); // to avoid Purify UMR + transfer_.arg_ = 0; // to avoid Purify UMR + ACE_OS::memset (transfer_.data_, 0, sizeof transfer_.data_); // to avoid Purify UMR + this->token_name (token_name, client_id); + this->options (options); +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the server. + +int +ACE_Token_Request::encode (void *&buf) +{ + buf = (void *) &this->transfer_; + return this->length (); +} + +// Decode the transfer buffer into host byte byte order +// so that it can be used by the server. + +int +ACE_Token_Request::decode (void) +{ + this->token_name_ = this->transfer_.data_; + + options_.set (transfer_.use_timeout_ == 1 ? ACE_Synch_Options::USE_TIMEOUT : 0, + ACE_Time_Value (transfer_.sec_, transfer_.usec_), + (void *) transfer_.arg_); + + // Decode the variable-sized portion. + size_t token_len = ACE_OS::strlen (this->token_name_); + + // Check to make sure this->tokenName_ isn't too long! + if (token_len >= ACE_MAXTOKENNAMELEN) + { + errno = ENAMETOOLONG; + return -1; + } + else // Skip this->tokenName_ + '\0' + ':'. + this->client_id_ = + &this->token_name_[(token_len + 2) * sizeof (ACE_TCHAR)]; + + // Fixed size header + // token_name_ plus '\0' + // ':' + // client_id_ plus '\0' + size_t data_size = ACE_TOKEN_REQUEST_HEADER_SIZE + + ACE_OS::strlen (this->token_name_) + 1 + + ACE_OS::strlen (this->client_id_) + 1 + + 1; + + // Make sure the message was correctly received and framed. + return this->length () == data_size ? 0 : -1; +} + +// Print out the current values of the ACE_Token_Request. + +void +ACE_Token_Request::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("*******\nlength = %d\ntoken name = %s\nclient id = %s\n"), + this->length (), this->token_name (), this->client_id ())); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("type = "))); + + if (this->token_type () == ACE_Tokens::MUTEX) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("MUTEX\n"))); + else // == ACE_Tokens::RWLOCK + { + if (this->proxy_type () == ACE_RW_Token::READER) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("RLOCK\n"))); + else // == WRITER + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("WLOCK\n"))); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("operation = "))); + switch (this->operation_type ()) + { + case ACE_Token_Request::ACQUIRE: + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACQUIRE\n"))); + break; + case ACE_Token_Request::RELEASE: + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("RELEASE\n"))); + break; + case ACE_Token_Request::RENEW: + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("RENEW\n"))); + break; + default: + ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" = %d\n"), this->operation_type ())); + break; + } + + if (this->options ()[ACE_Synch_Options::USE_TIMEOUT] == 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("blocking forever\n"))); + else + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("waiting for %d secs and %d usecs\n"), + this->options ().timeout ().sec (), this->options ().timeout ().usec ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +// Create a ACE_Token_Reply message. + +ACE_Token_Reply::ACE_Token_Reply (void) // Type of reply. +{ + this->arg (0); + this->errnum (0); + this->length (sizeof (Transfer)); +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the client. + +int +ACE_Token_Reply::encode (void *&buf) +{ + buf = (void *) &this->transfer_; + return this->length (); +} + +// Decode the transfer buffer into host byte order +// so that it can be used by the client. + +int +ACE_Token_Reply::decode (void) +{ + return 0; +} + +// Print out current values of the ACE_Token_Reply object. + +void +ACE_Token_Reply::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("*******\nlength = %d\nerrnum = %d"), + this->length (), this->errnum ())); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("arg = %d"), this->arg ())); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Token_Request_Reply.h b/dep/ACE_wrappers/ace/Token_Request_Reply.h new file mode 100644 index 000000000..01a7cfd3e --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Request_Reply.h @@ -0,0 +1,270 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Token_Request_Reply.h + * + * $Id: Token_Request_Reply.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Define the format used to exchange messages between the + * ACE_Token Server and its clients. + * + * + * @author Douglas C. Schmidt (schmidt@cs.wustl.edu) + * @author Tim Harrison (harrison@cs.wustl.edu) + */ +//============================================================================= + + +#ifndef ACE_TOKEN_REQUEST_REPLY_H +#define ACE_TOKEN_REQUEST_REPLY_H +#include /**/ "ace/pre.h" + +#include "ace/Local_Tokens.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/// Specifies the size of the fixed length portion of +/// the Transfer structure in ACE_Token_Request +#define ACE_TOKEN_REQUEST_HEADER_SIZE 40 + +/** + * @class ACE_Token_Request + * + * @brief Message format for delivering requests to the ACE_Token Server. + * + * This class is implemented to minimize data copying. + * In particular, all marshaling is done in situ... + */ +class ACE_Export ACE_Token_Request +{ +public: + /// Operation types. + enum OPERATION + { + /// Acquire the token. + ACQUIRE, + /// Release the token. + RELEASE, + /// Renew the token. + RENEW, + /// Remove the token. + REMOVE, + // Try to acquire the token. + TRY_ACQUIRE + }; + + /// Default constructor. + ACE_Token_Request (void); + + /** + * @param token_type MUTEX, RWLOCK + * @param proxy_type MUTEX, RLOCK, WLOCK (acquires mean different things) + * @param operation method + * @param token_name + * @param client_id + * @param options We check USE_TIMEOUT and use the arg. + */ + ACE_Token_Request (int token_type, + int proxy_type, + ACE_UINT32 operation, + const ACE_TCHAR token_name[], + const ACE_TCHAR client_id[], + const ACE_Synch_Options &options); + + /// Get the length of the encoded/decoded message. + ACE_UINT32 length (void) const; + + /// Set the length of the encoded/decoded message. + void length (ACE_UINT32); + + /// Get the type of proxy + int proxy_type (void) const; + + /// Set the type of proxy + void proxy_type (int proxy_type); + + /// Get the type of token + int token_type (void) const; + + /// Set the type of token + void token_type (int token_type); + + /// Get the type of the operation. + ACE_UINT32 operation_type (void) const; + + /// Set the type of the operation. + void operation_type (ACE_UINT32); + + /// Get the requeue position. These should be used when renew + /// is the operation type. + ACE_UINT32 requeue_position (void) const; + + /// Set the requeue position. These should be used when renew + /// is the operation type. + void requeue_position (ACE_UINT32); + + /// Get notify. These should be used when acquire is the operation type. + ACE_UINT32 notify (void) const; + + /// Set notify. These should be used when acquire is the operation type. + void notify (ACE_UINT32); + + /// Get the timeout. + ACE_Synch_Options &options (void) const; + + /// Set the timeout. + void options (const ACE_Synch_Options &options); + + // = Set/get the name of the token and the client id. The set + // method is combined to make it easier on us. We're copying the + // names as a contiguous buffer. + ACE_TCHAR *token_name (void) const; + ACE_TCHAR *client_id (void) const; + void token_name (const ACE_TCHAR *token_name, const ACE_TCHAR *client_id); + + /// Encode the message before transmission. + int encode (void *&); + + /// Decode message after reception. This must be called to set the + /// internal options. + int decode (void); + + /// Print out the values of the message for debugging purposes. + void dump (void) const; + +private: + // = The 5 fields in the struct are transmitted to the server. + // The remaining 2 fields are not tranferred -- they are used only on + // the server-side to simplify lookups. + + struct Transfer + { + /// Length of entire request. + ACE_UINT32 length_; + + /// Type of the request (i.e., MUTEX, RLOCK, WLOCK... + ACE_UINT32 token_type_; + + /// Type of the request (i.e., MUTEX, RLOCK, WLOCK... + ACE_UINT32 proxy_type_; + + /// Type of the request (i.e., , , , and ). + ACE_UINT32 operation_type_; + + /// this only makes sense when operation type is renew + ACE_UINT32 requeue_position_; + + /// this only makes sense when operation type is renew + ACE_UINT32 notify_; + + // = ACE_Synch_Options stuff + + /// Indicates if we should block forever. If 1, then + /// and indicates how long we should wait. If 0, + /// then we block forever. + ACE_UINT32 use_timeout_; + + /// Max seconds willing to wait for token if not blocking forever. + ACE_UINT32 sec_; + + /// Max micro seconds to wait for token if not blocking forever. + ACE_UINT32 usec_; + + /// value returned in ; + ACE_UINT32 arg_; + + /// The data portion contains the including a 0 terminator, + /// a ':', then the including a 0 terminator + ACE_TCHAR data_[ACE_MAXTOKENNAMELEN + ACE_MAXCLIENTIDLEN + 3]; + } transfer_; + + /// Pointer to the beginning of the token name in this->data_. + ACE_TCHAR *token_name_; + + /// Pointer to the beginning of the client id in this->data_; + ACE_TCHAR *client_id_; + + /// Holds arg, sec, usec, etc. + ACE_Synch_Options options_; +}; + +/** + * @class ACE_Token_Reply + * + * @brief Message format for delivering replies from the ACE_Token Server. + * + * This class is implemented to minimize data copying. + * In particular, all marshaling is done in situ... + */ +class ACE_Export ACE_Token_Reply +{ +public: + /// Default constructor. + ACE_Token_Reply (void); + + /// Get the length of the encoded/decoded message. + ACE_UINT32 length (void) const; + + /// Set the length of the encoded/decoded message. + void length (ACE_UINT32); + + /// Get the errno of a reply. + ACE_UINT32 errnum (void) const; + + /// Set the errno of a reply. + void errnum (ACE_UINT32); + + /// Get the arg of a reply. + ACE_UINT32 arg (void) const; + + /// Set the arg of a reply. + void arg (ACE_UINT32); + + /// Encode the message before transfer. + int encode (void *&); + + /// Decode a message after reception. + int decode (void); + + /// Print out the values of the message for debugging purposes. + void dump (void) const; + +private: + // = The 2 fields in the struct are transmitted to the server. + + struct Transfer + { + /// Length of entire reply. + ACE_UINT32 length_; + + /// Indicates why error occurred if type_> == . + /// Typical reasons include: + /// @c EWOULDBLOCK (if client requested a non-blocking check for the token). + /// @c ETIME (if the client timed out after waiting for the token). + /// (if the token lock was removed out from underneath a waiter). + /// (attempt to renew a token that isn't owned by the client). + ACE_UINT32 errno_; + + /// magic cookie + ACE_UINT32 arg_; + + } transfer_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Token_Request_Reply.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_TOKENS_LIBRARY */ + +#include /**/ "ace/post.h" +#endif /* ACE_TOKEN_REQUEST_REPLY_H */ diff --git a/dep/ACE_wrappers/ace/Token_Request_Reply.inl b/dep/ACE_wrappers/ace/Token_Request_Reply.inl new file mode 100644 index 000000000..4291bfa60 --- /dev/null +++ b/dep/ACE_wrappers/ace/Token_Request_Reply.inl @@ -0,0 +1,205 @@ +// -*- C++ -*- +// +// $Id: Token_Request_Reply.inl 80826 2008-03-04 14:51:23Z wotte $ + +#if defined (ACE_HAS_TOKENS_LIBRARY) + +#include "ace/Truncate.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// = Set/get the length of the encoded/decoded message. + +ACE_INLINE ACE_UINT32 +ACE_Token_Request::length (void) const +{ + return ntohl (this->transfer_.length_); +} + +ACE_INLINE void +ACE_Token_Request::length (ACE_UINT32 l) +{ + this->transfer_.length_ = htonl (l); +} + +// = Set/get the type of the message. +ACE_INLINE int +ACE_Token_Request::token_type (void) const +{ + return (int) ntohl (this->transfer_.token_type_); +} + +ACE_INLINE void +ACE_Token_Request::token_type (int t) +{ + this->transfer_.token_type_ = htonl ((ACE_UINT32) t); +} + +// = Set/get the type of the message. +ACE_INLINE int +ACE_Token_Request::proxy_type (void) const +{ + return (int) ntohl (this->transfer_.proxy_type_); +} + +ACE_INLINE void +ACE_Token_Request::proxy_type (int t) +{ + this->transfer_.proxy_type_ = htonl ((ACE_UINT32) t); +} + +// = Set/get the type of the message. +ACE_INLINE ACE_UINT32 +ACE_Token_Request::operation_type (void) const +{ + return ntohl (this->transfer_.operation_type_); +} + +ACE_INLINE void +ACE_Token_Request::operation_type (ACE_UINT32 t) +{ + this->transfer_.operation_type_ = htonl (t); +} + +// = Set/get the requeue position +ACE_INLINE ACE_UINT32 +ACE_Token_Request::requeue_position (void) const +{ + return ntohl (this->transfer_.requeue_position_); +} + +ACE_INLINE void +ACE_Token_Request::requeue_position (ACE_UINT32 rq) +{ + this->transfer_.requeue_position_ = htonl (rq); +} + +// = Set/get the requeue position +ACE_INLINE ACE_UINT32 +ACE_Token_Request::notify (void) const +{ + return ntohl (this->transfer_.notify_); +} + +ACE_INLINE void +ACE_Token_Request::notify (ACE_UINT32 rq) +{ + this->transfer_.notify_ = htonl (rq); +} + +// = Set/get the blocking semantics. +ACE_INLINE ACE_Synch_Options & +ACE_Token_Request::options (void) const +{ + return (ACE_Synch_Options &) options_; +} + +ACE_INLINE void +ACE_Token_Request::options (const ACE_Synch_Options &opt) +{ + // fight the friggin const from hell + ACE_Synch_Options *options = (ACE_Synch_Options *) &opt; + + transfer_.use_timeout_ = options->operator[](ACE_Synch_Options::USE_TIMEOUT); + if (transfer_.use_timeout_ == 1) + { + transfer_.usec_ = options->timeout ().usec (); + if (options->timeout ().sec () > (time_t) ACE_UINT32_MAX) + transfer_.sec_ = ACE_UINT32_MAX; + else + transfer_.sec_ = static_cast (options->timeout ().sec ()); + } + else + { + transfer_.usec_ = 0; + transfer_.sec_ = 0; + } +} + +// = Set/get the name of the token. +ACE_INLINE ACE_TCHAR * +ACE_Token_Request::token_name (void) const +{ + return token_name_; +} + +ACE_INLINE void +ACE_Token_Request::token_name (const ACE_TCHAR *token_name, + const ACE_TCHAR *client_id) +{ + size_t token_name_length = ACE_OS::strlen (token_name) + 1; // Add 1 for '\0'. + size_t client_id_length = ACE_OS::strlen (client_id) + 1; // Add 1 for '\0'. + + // Set up pointers and copy token_name and client_id into request. + token_name_ = this->transfer_.data_; + client_id_ = &this->token_name_[token_name_length + 1]; // Add 1 for ':'; + client_id_[-1] = ACE_TEXT (':'); // Insert the ':' before this->clientId_. + + (void) ACE_OS::memcpy (this->token_name_, + token_name, + token_name_length * sizeof (ACE_TCHAR)); + (void) ACE_OS::memcpy (this->client_id_, + client_id, + client_id_length * sizeof (ACE_TCHAR)); + + // Fixed length header size + size_t len = ACE_TOKEN_REQUEST_HEADER_SIZE; + + // ... then add in the amount of the variable-sized portion. + len += token_name_length + client_id_length + 1; + this->length (ACE_Utils::truncate_cast (len)); +} + +// = Set/get the id of the client. +ACE_INLINE ACE_TCHAR * +ACE_Token_Request::client_id (void) const +{ + return this->client_id_; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +// = Set/get the length of the encoded/decoded message. +ACE_INLINE ACE_UINT32 +ACE_Token_Reply::length (void) const +{ + return ntohl (this->transfer_.length_); +} + +ACE_INLINE void +ACE_Token_Reply::length (ACE_UINT32 l) +{ + this->transfer_.length_ = htonl (l); +} + +// = Set/get the errno of a failed reply. +ACE_INLINE ACE_UINT32 +ACE_Token_Reply::errnum (void) const +{ + return ntohl (this->transfer_.errno_); +} + +ACE_INLINE void +ACE_Token_Reply::errnum (ACE_UINT32 e) +{ + this->transfer_.errno_ = htonl (e); +} + +// = Set/get the length of the encoded/decoded message. +ACE_INLINE ACE_UINT32 +ACE_Token_Reply::arg (void) const +{ + return ntohl (this->transfer_.arg_); +} + +ACE_INLINE void +ACE_Token_Reply::arg (ACE_UINT32 arg) +{ + this->transfer_.arg_ = htonl (arg); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_TOKENS_LIBRARY */ diff --git a/dep/ACE_wrappers/ace/Trace.cpp b/dep/ACE_wrappers/ace/Trace.cpp new file mode 100644 index 000000000..12ccf135e --- /dev/null +++ b/dep/ACE_wrappers/ace/Trace.cpp @@ -0,0 +1,137 @@ +// $Id: Trace.cpp 80826 2008-03-04 14:51:23Z wotte $ + + +#include "ace/Trace.h" + +ACE_RCSID (ace, + Trace, + "$Id: Trace.cpp 80826 2008-03-04 14:51:23Z wotte $") + +// Turn off tracing for the duration of this file. +#if defined (ACE_NTRACE) +#undef ACE_NTRACE +#endif /* ACE_NTRACE */ +#define ACE_NTRACE 1 + +#include "ace/Log_Msg.h" +#include "ace/Object_Manager_Base.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// = Static initialization. + +// Keeps track of how far to indent per trace call. +int ACE_Trace::nesting_indent_ = ACE_Trace::DEFAULT_INDENT; + +// Is tracing enabled? +int ACE_Trace::enable_tracing_ = ACE_Trace::DEFAULT_TRACING; + +ACE_ALLOC_HOOK_DEFINE(ACE_Trace) + +void +ACE_Trace::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +#endif /* ACE_HAS_DUMP */ +} + +// Determine whether or not tracing is enabled + +int +ACE_Trace::is_tracing (void) +{ + return ACE_Trace::enable_tracing_; +} + +// Enable the tracing facility. + +void +ACE_Trace::start_tracing (void) +{ + ACE_Trace::enable_tracing_ = 1; +} + +// Disable the tracing facility. + +void +ACE_Trace::stop_tracing (void) +{ + ACE_Trace::enable_tracing_ = 0; +} + +// Change the nesting indentation level. + +void +ACE_Trace::set_nesting_indent (int indent) +{ + ACE_Trace::nesting_indent_ = indent; +} + +// Get the nesting indentation level. + +int +ACE_Trace::get_nesting_indent (void) +{ + return ACE_Trace::nesting_indent_; +} + +// Perform the first part of the trace, which prints out the string N, +// the LINE, and the ACE_FILE as the function is entered. + +ACE_Trace::ACE_Trace (const ACE_TCHAR *n, + int line, + const ACE_TCHAR *file) +{ +#if defined (ACE_NLOGGING) + ACE_UNUSED_ARG (line); + ACE_UNUSED_ARG (file); +#endif /* ACE_NLOGGING */ + + this->name_ = n; + + // If ACE has not yet been initialized, don't try to trace... there's + // too much stuff not yet initialized. + if (ACE_Trace::enable_tracing_ && !ACE_OS_Object_Manager::starting_up ()) + { + ACE_Log_Msg *lm = ACE_LOG_MSG; + if (lm->tracing_enabled () + && lm->trace_active () == 0) + { + lm->trace_active (1); + ACE_DEBUG ((LM_TRACE, + ACE_TEXT ("%*s(%t) calling %s in file `%s' on line %d\n"), + ACE_Trace::nesting_indent_ * lm->inc (), + ACE_TEXT (""), + this->name_, + file, + line)); + lm->trace_active (0); + } + } +} + +// Perform the second part of the trace, which prints out the NAME as +// the function is exited. + +ACE_Trace::~ACE_Trace (void) +{ + // If ACE has not yet been initialized, don't try to trace... there's + // too much stuff not yet initialized. + if (ACE_Trace::enable_tracing_ && !ACE_OS_Object_Manager::starting_up ()) + { + ACE_Log_Msg *lm = ACE_LOG_MSG; + if (lm->tracing_enabled () + && lm->trace_active () == 0) + { + lm->trace_active (1); + ACE_DEBUG ((LM_TRACE, + ACE_TEXT ("%*s(%t) leaving %s\n"), + ACE_Trace::nesting_indent_ * lm->dec (), + ACE_TEXT (""), + this->name_)); + lm->trace_active (0); + } + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Trace.h b/dep/ACE_wrappers/ace/Trace.h new file mode 100644 index 000000000..f11d634ee --- /dev/null +++ b/dep/ACE_wrappers/ace/Trace.h @@ -0,0 +1,96 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Trace.h + * + * $Id: Trace.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TRACE_H +#define ACE_TRACE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Trace + * + * @brief A C++ trace facility that keeps track of which methods are + * entered and exited. + * + * This class uses C++ constructors and destructors to automate + * the ACE_Trace nesting. In addition, thread-specific storage + * is used to enable multiple threads to work correctly. + */ +class ACE_Export ACE_Trace +{ +public: + // = Initialization and termination methods. + + /// Perform the first part of the trace, which prints out the string + /// N, the LINE, and the ACE_FILE as the function is entered. + ACE_Trace (const ACE_TCHAR *n, + int line = 0, + const ACE_TCHAR *file = ACE_TEXT ("")); + + /// Perform the second part of the trace, which prints out the NAME + /// as the function is exited. + ~ACE_Trace (void); + + // = Control the tracing level. + /// Determine if tracing is enabled (return == 1) or not (== 0) + static int is_tracing(void); + + /// Enable the tracing facility. + static void start_tracing (void); + + /// Disable the tracing facility. + static void stop_tracing (void); + + /// Change the nesting indentation level. + static void set_nesting_indent (int indent); + + /// Get the nesting indentation level. + static int get_nesting_indent (void); + + /// Dump the state of an object. + void dump (void) const; + +private: + // Keeps track of how deeply the call stack is nested (this is + // maintained in thread-specific storage to ensure correctness in + // multiple threads of control. + + /// Name of the method we are in. + const ACE_TCHAR *name_; + + /// Keeps track of how far to indent per trace call. + static int nesting_indent_; + + /// Is tracing enabled? + static int enable_tracing_; + + /// Default values. + enum + { + DEFAULT_INDENT = 3, + DEFAULT_TRACING = 1 + }; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_TRACE_H */ diff --git a/dep/ACE_wrappers/ace/Truncate.h b/dep/ACE_wrappers/ace/Truncate.h new file mode 100644 index 000000000..5b9a0e118 --- /dev/null +++ b/dep/ACE_wrappers/ace/Truncate.h @@ -0,0 +1,1055 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Truncate.h + * + * $Id: Truncate.h 82623 2008-08-13 14:41:09Z johnnyw $ + * + * @author Steve Huston + * @author Ossama Othman + * @author Russell Mora + */ +//============================================================================= + +#ifndef ACE_TRUNCATE_H +#define ACE_TRUNCATE_H + +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/If_Then_Else.h" +#include "ace/Numeric_Limits.h" + +#if defined (ACE_LACKS_LONGLONG_T) \ + || defined (__BORLANDC__) && __BORLANDC__ < 0x590 +# include "ace/Basic_Types.h" +#endif /* ACE_LACKS_LONGLONG_T || __BORLANDC__ < 0x590 */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE_Utils +{ + +#if !defined (__BORLANDC__) || __BORLANDC__ >= 0x590 + + template struct Sign_Check; + + // Specialize the unsigned signed cases. + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 0); }; + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 0); }; + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 0); }; + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 0); }; +#if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T)) +# ifdef __GNUC__ + // Silence g++ "-pedantic" warnings regarding use of "long long" + // type. + __extension__ +# endif /* __GNUC__ */ + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 0); }; +#else + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 0); }; +#endif /* !ACE_LACKS_LONGLONG_T */ + + // Specialize the signed cases. + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 1); }; + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 1); }; + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 1); }; + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 1); }; +#ifndef ACE_LACKS_LONGLONG_T +# ifdef __GNUC__ + // Silence g++ "-pedantic" warnings regarding use of "long long" + // type. + __extension__ +# endif /* __GNUC__ */ + template<> struct Sign_Check { ACE_STATIC_CONSTANT (bool, is_signed = 1); }; +#endif /* !ACE_LACKS_LONGLONG_T */ + + // ----------------------------------------------------- + + /** + * @struct To_Unsigned + * + * @brief Retrieve unsigned counterpart to given type or value. + * + * Retrieve unsigned counterpart to given type or value. + */ + template struct To_Unsigned; + + template<> + struct To_Unsigned + { + typedef unsigned char unsigned_type; + + unsigned_type operator() (unsigned_type x) { return x; } + }; + + template<> + struct To_Unsigned + { + typedef unsigned short unsigned_type; + + unsigned_type operator() (unsigned_type x) { return x; } + }; + + template<> + struct To_Unsigned + { + typedef unsigned int unsigned_type; + + unsigned_type operator() (unsigned_type x) { return x; } + }; + + template<> + struct To_Unsigned + { + typedef unsigned long unsigned_type; + + unsigned_type operator() (unsigned_type x) { return x; } + }; + +#if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T)) +# ifdef __GNUC__ + // Silence g++ "-pedantic" warnings regarding use of "long long" + // type. + __extension__ +# endif /* __GNUC__ */ + template<> + struct To_Unsigned + { + typedef unsigned long long unsigned_type; + + unsigned_type operator() (unsigned_type x) { return x; } + }; +#else + template<> + struct To_Unsigned + { + typedef ACE_U_LongLong unsigned_type; + + unsigned_type operator() (unsigned_type x) { return x; } + }; +#endif /* !ACE_LACKS_LONGLONG_T */ + + // ---------------- + + template<> + struct To_Unsigned + { + typedef signed char signed_type; + typedef unsigned char unsigned_type; + + unsigned_type operator() (signed_type x) + { + return static_cast (x); + } + }; + + template<> + struct To_Unsigned + { + typedef signed short signed_type; + typedef unsigned short unsigned_type; + + unsigned_type operator() (signed_type x) + { + return static_cast (x); + } + }; + + template<> + struct To_Unsigned + { + typedef signed int signed_type; + typedef unsigned int unsigned_type; + + unsigned_type operator() (signed_type x) + { + return static_cast (x); + } + }; + + template<> + struct To_Unsigned + { + typedef signed long signed_type; + typedef unsigned long unsigned_type; + + unsigned_type operator() (signed_type x) + { + return static_cast (x); + } + }; + +#if !(defined(ACE_LACKS_LONGLONG_T) || defined(ACE_LACKS_UNSIGNEDLONGLONG_T)) +# ifdef __GNUC__ + // Silence g++ "-pedantic" warnings regarding use of "long long" + // type. + __extension__ +# endif /* __GNUC__ */ + template<> + struct To_Unsigned + { + typedef signed long long signed_type; + typedef unsigned long long unsigned_type; + + unsigned_type operator() (signed_type x) + { + return static_cast (x); + } + }; +#endif /* !ACE_LACKS_LONGLONG_T */ + + // ----------------------------------------------------- + + /** + * @struct Safe_Comparator + * + * @brief Conservative comparison of types that may not be safely + * promoted and/or converted to each other. + * + * The comparison operations provided by this structure perform + * negative value checking when necessary to prevent wrap-around + * when explicitly casting to an unsigned type. + * + * @internal This structure is not meant for general use. + */ + template struct Safe_Comparator; + + // LEFT: signed, RIGHT: unsigned + template + struct Safe_Comparator + { + static bool greater_than (LEFT lhs, RIGHT rhs) + { + // Prevent wrap-around when casting to unsigned. + if (lhs < 0) + return false; // since rhs is always positive + else + { + // Implicit promotion of unsigned LEFT and RIGHT types here. + return To_Unsigned() (lhs) > rhs; + } + } + }; + + // LEFT: unsigned, RIGHT: signed + template + struct Safe_Comparator + { + static bool greater_than (LEFT lhs, RIGHT rhs) + { + // Prevent wrap-around when casting to unsigned. + if (rhs < 0) + return true; // since lhs is always positive + else + { + // Implicit promotion of unsigned LEFT and RIGHT types here. + return lhs > To_Unsigned() (rhs); + } + } + }; + + // LEFT: unsigned, RIGHT: unsigned + template + struct Safe_Comparator + { + static bool greater_than (LEFT lhs, RIGHT rhs) + { + // Implicit promotion of unsigned LEFT and RIGHT types here. + return lhs > rhs; + } + }; + + // LEFT: signed, RIGHT: signed + template + struct Safe_Comparator + { + static bool greater_than (LEFT lhs, RIGHT rhs) + { + // Implicit promotion of signed LEFT and RIGHT types here. + return lhs > rhs; + } + }; + + // ----------------------------------------------------- + + /** + * @struct Fast_Comparator + * + * @brief Quick comparison of types that can be safely promoted + * and/or converted to each other. + * + * The comparison operations provided by this structure perform no + * negative value checking, meaning it is not applicable to all + * types. Check the value of the @c USABLE enumerator to determine + * if it applies to the types in question. + * + * @internal This structure is not meant for general use. + */ + template + struct Fast_Comparator + { + ACE_STATIC_CONSTANT ( + bool, + USE_LEFT = ((sizeof (LEFT) > sizeof (RIGHT) + && (Sign_Check::is_signed == 1 + || Sign_Check::is_signed == 0)) + + // The following is basically the case where LEFT + // and RIGHT are the same integral type. + || (sizeof (LEFT) == sizeof (RIGHT) + // Can't portably do + // Sign_Check::is_signed == + // Sign_Check::is_signed, + // i.e. comparison of anonymous enumerations, + // without triggering a compiler diagnostic + // so expand the comparison. + && ((Sign_Check::is_signed == 1 + && Sign_Check::is_signed == 1) + || (Sign_Check::is_signed == 0 + && Sign_Check::is_signed == 0))))); + + ACE_STATIC_CONSTANT ( + bool, + USE_RIGHT = (sizeof (RIGHT) > sizeof (LEFT) + && (Sign_Check::is_signed == 1 + || Sign_Check::is_signed == 0))); + + ACE_STATIC_CONSTANT (bool, USABLE = (USE_LEFT || USE_RIGHT)); + + typedef typename ACE::If_Then_Else< + USE_LEFT, + LEFT, + typename ACE::If_Then_Else< + USE_RIGHT, + RIGHT, + void>::result_type>::result_type promote_type; + + static bool greater_than (LEFT lhs, RIGHT rhs) + { + // The explicit cast is assumed to change the type of rhs without + // changing its value. + return + (static_cast (lhs) > static_cast (rhs)); + } + + }; + + // ----------------------------------------------------- + + /** + * @struct Comparator + * + * @brief Structure that provides optimal comparison operation for + * given types. + * + * The comparison operations provided by this structure are chosen + * at compile time based on the signs and sizes of types being + * compared. + * @par + * Comparisons of values with the same sign or those with types that + * can be promoted safely are done quickly, without any range + * checking. + * @par + * Comparisons of values of different types that cannot be safely + * promoted incur an additional check for a negative value to allow + * the compiler to perform the appropriate implicit unsigned type + * promotion. + * + * @note In general, the operations found in this structure should + * not be used to work around compiler diagnostics regarding + * comparison of signed and unsigned types. Verify that your + * types are correct before relying on those operations. + * + * @internal This structure is not meant for general use. + */ + template + struct Comparator + { + typedef typename ACE::If_Then_Else< + Fast_Comparator::USABLE, + Fast_Comparator, + Safe_Comparator::is_signed, + Sign_Check::is_signed> >::result_type comp_type; + }; + + // ----------------------------------------------------- + + /** + * @struct Truncator + * + * @brief Truncate value of type @c FROM to value of type @c TO. + * + * Truncate a value of type @c FROM to value of type @c TO, if the + * value is larger than the maximum of value of type @c TO. + */ + template + struct Truncator + { + ACE_STATIC_CONSTANT ( + bool, + // max FROM always greater than max TO + MAX_FROM_GT_MAX_TO = (sizeof(FROM) > sizeof (TO) + || (sizeof(FROM) == sizeof (TO) + && Sign_Check::is_signed == 0))); + + typedef typename ACE::If_Then_Else< + MAX_FROM_GT_MAX_TO, + FROM, + TO>::result_type comp_to_type; + + // Take advantage of knowledge that we're casting a positive value + // to a type large enough to hold it so that we can bypass + // negative value checks at compile-time. Otherwise fallback on + // the safer comparison. + typedef typename ACE::If_Then_Else< + MAX_FROM_GT_MAX_TO, + Fast_Comparator, + typename Comparator::comp_type>::result_type comparator; + + /// Truncate a value of type @c FROM to value of type @c TO, if + /// the value is larger than the maximum of value of type @c TO. + TO operator() (FROM val) + { + return + (comparator::greater_than (val, ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + + }; + + // Partial specialization for the case where the types are the same. + // No truncation is necessary. + template + struct Truncator + { + T operator() (T val) + { + return val; + } + }; + + +#if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + // Partial specialization for the case where we're casting from + // ACE_U_LongLong to a smaller integer. We assume that we're always + // truncating from ACE_U_LongLong to a smaller type. The partial + // specialization above handles the case where both the FROM and TO + // types are ACE_U_LongLong. + template + struct Truncator + { + TO operator() (ACE_U_LongLong const & val) + { + // If val less than or equal to ACE_Numeric_Limits::max(), + // val.lo() must be less than or equal to + // ACE_Numeric_Limits::max (), as well. + return + (val > ACE_Numeric_Limits::max () + ? ACE_Numeric_Limits::max () + : static_cast (val.lo ())); + } + }; +#endif /* ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */ + + // ----------------------------------------------------- + /** + * @struct Noop_Truncator + * + * @brief No-op truncation. + * + * This structure/functor performs no truncation since it assumes + * that @c sizeof(FROM) @c < @c sizeof(TO), meaning that + * @c numeric_limits::max() @c < @c numeric_limits::max(). + */ + template + struct Noop_Truncator + { + TO operator() (FROM val) + { + return static_cast (val); + } + }; + // ----------------------------------------------------- + + /** + * @class truncate_cast + * + * @brief Helper function to truncate an integral value to the + * maximum value of the given type. + * + * Very useful since ACE methods return @c int very often and + * the value's source is often a different-size integral + * type, such as @c size_t. This function hides the + * truncation logic and resolves compiler diagnostics. + * + * @internal Internal use only. + */ + template + inline TO truncate_cast (FROM val) + { + // If the size of FROM is less than the size of TO, "val" will + // never be greater than the maximum "TO" value, so there is no + // need to attempt to truncate. + typedef typename ACE::If_Then_Else< + (sizeof (FROM) < sizeof (TO)), + Noop_Truncator, + Truncator >::result_type truncator; + + return truncator() (val); + } + +#else + + // Borland can't handle the template meta-programming above so + // provide explicit specializations for a few types. More will be + // added if necessary. + + /** + * @deprecated Borland ACE_Utils::Truncator<> specializations should + * be removed. + */ + + template struct Truncator; + + //---------------------------------------------------------- + // sizeof(FROM) > sizeof(TO) + //---------------------------------------------------------- + + template<> + struct Truncator + { + ACE_INT8 operator() (ACE_INT32 val) + { + return + (val > ACE_Numeric_Limits::max () + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + ACE_UINT8 operator() (ACE_UINT32 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + ACE_UINT8 operator() (ACE_INT32 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + ACE_INT8 operator() (ACE_UINT32 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + +#if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG < 8 + template<> + struct Truncator + { + signed long operator() (ACE_INT64 val) + { + return + (val > ACE_Numeric_Limits::max () + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + unsigned long operator() (ACE_INT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + unsigned long operator() (ACE_UINT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + signed long operator() (ACE_UINT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + signed long operator() (const ACE_UINT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + +#endif /* ACE_SIZEOF_LONG < 8 */ + +#if defined (ACE_SIZEOF_INT) && ACE_SIZEOF_INT < 8 + template<> + struct Truncator + { + ACE_INT32 operator() (ACE_INT64 val) + { + return + (val > ACE_Numeric_Limits::max () + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + ACE_UINT32 operator() (ACE_INT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + ACE_UINT32 operator() (ACE_UINT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + signed int operator() (ACE_UINT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + +#endif /* ACE_SIZEOF_INT < 8 */ + + //---------------------------------------------------------- + // sizeof(FROM) == sizeof(TO) + //---------------------------------------------------------- + + template<> + struct Truncator + { + char operator() (unsigned int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + wchar_t operator() (unsigned int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + unsigned int operator() (signed int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + signed int operator() (unsigned int val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + signed int operator() (const unsigned int val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + unsigned long operator() (signed long val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + signed long operator() (unsigned long val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + +#if defined (ACE_SIZEOF_INT) && defined (ACE_SIZEOF_LONG) \ + && ACE_SIZEOF_INT == ACE_SIZEOF_LONG + + template<> + struct Truncator + { + unsigned long operator() (signed int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + signed long operator() (signed int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + signed int operator() (unsigned long val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + signed int operator() (signed long val) + { + return static_cast (val); +// This code causes asserts and compiler crashes with BCB6 Static and +// BCB2007 Static +// return +// (val > static_cast (ACE_Numeric_Limits::max ()) +// ? ACE_Numeric_Limits::max () +// : static_cast (val)); + } + }; + + template<> + struct Truncator + { + unsigned int operator() (signed long val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + unsigned int operator() (const signed long val) + { + return static_cast (val); + } + }; + + + template<> + struct Truncator + { + signed long operator() (unsigned int val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + +#endif /* ACE_SIZEOF_INT == ACE_SIZEOF_LONG */ + + template<> + struct Truncator + { + ACE_UINT64 operator() (ACE_INT64 val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_INT64 operator() (ACE_UINT64 val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + //---------------------------------------------------------- + // sizeof(FROM) < sizeof(TO) + //---------------------------------------------------------- + + template<> + struct Truncator + { + ACE_INT32 operator() (ACE_INT8 val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_UINT32 operator() (ACE_UINT8 val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_INT32 operator() (ACE_UINT8 val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_UINT32 operator() (ACE_INT8 val) + { + return static_cast (val); + } + }; + +#if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG < 8 + template<> + struct Truncator + { + ACE_INT64 operator() (signed long val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_UINT64 operator() (signed long val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_UINT64 operator() (const signed long val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + template<> + struct Truncator + { + ACE_UINT64 operator() (unsigned long val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_INT64 operator() (unsigned long val) + { + return static_cast (val); + } + }; +#endif /* ACE_SIZEOF_LONG < 8 */ + +#if defined (ACE_SIZEOF_INT) && ACE_SIZEOF_INT < 8 + template<> + struct Truncator + { + ACE_INT64 operator() (signed int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_UINT64 operator() (signed int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_UINT64 operator() (unsigned int val) + { + return static_cast (val); + } + }; + + template<> + struct Truncator + { + ACE_INT64 operator() (unsigned int val) + { + return static_cast (val); + } + }; +#endif /* ACE_SIZEOF_INT < 8 */ + + template<> + struct Truncator + { + unsigned long operator() (size_t val) + { + return + (val > static_cast (ACE_Numeric_Limits::max ()) + ? ACE_Numeric_Limits::max () + : static_cast (val)); + } + }; + + // Partial specialization for the case where the types are the same. + // No truncation is necessary. + template + struct Truncator + { + T operator() (T val) + { + return val; + } + }; + + // Partial specialization for the case where the types are the same, + // but the from type is const. No truncation is necessary. + // + // This is only necessary to workaround a problem with the BCB6 + // compiler. + template + struct Truncator + { + T operator() (T val) + { + return val; + } + }; + + // ------------------------------------- + + template + inline TO truncate_cast (FROM val) + { + typedef Truncator truncator; + + return truncator() (val); + } + +#endif /* !__BORLANDC__ || __BORLANDC__ >= 0x590 */ + +} // namespace ACE_Utils + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_TRUNCATE_H*/ diff --git a/dep/ACE_wrappers/ace/Typed_SV_Message.cpp b/dep/ACE_wrappers/ace/Typed_SV_Message.cpp new file mode 100644 index 000000000..6be3d4c68 --- /dev/null +++ b/dep/ACE_wrappers/ace/Typed_SV_Message.cpp @@ -0,0 +1,30 @@ +// $Id: Typed_SV_Message.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TYPED_SV_MESSAGE_CPP +#define ACE_TYPED_SV_MESSAGE_CPP + +#include "ace/Typed_SV_Message.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Typed_SV_Message) + +template void +ACE_Typed_SV_Message::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Typed_SV_Message::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TYPED_SV_MESSAGE_CPP */ diff --git a/dep/ACE_wrappers/ace/Typed_SV_Message.h b/dep/ACE_wrappers/ace/Typed_SV_Message.h new file mode 100644 index 000000000..b43258e01 --- /dev/null +++ b/dep/ACE_wrappers/ace/Typed_SV_Message.h @@ -0,0 +1,107 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Typed_SV_Message.h + * + * $Id: Typed_SV_Message.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//========================================================================== + + +#ifndef ACE_TYPED_SV_MESSAGE_H +#define ACE_TYPED_SV_MESSAGE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Typed_SV_Message + * + * @brief Defines the header file for the C++ wrapper for System V + * message queues. + */ +template +class ACE_Typed_SV_Message +{ +public: + // = Initialization and termination methods. + ACE_Typed_SV_Message (long type = 0, + int length = sizeof (T), + int max_size = sizeof (T)); + ACE_Typed_SV_Message (const T &data, + long type = 0, + int length = sizeof (T), + int max_size = sizeof (T)); + ~ACE_Typed_SV_Message (void); + + /// Get the type of the message. + long type (void) const; + + /// Set the type of the message. + void type (long type); + + /// Get the length of the message. + int length (void) const; + + /// Set the length of the message. + void length (int l); + + /// Get the maximum size of the message. + int max_size (void) const; + + /// Set the maximum size of the message. + void max_size (int m); + + /// Get a pointer to the data in the message. + T &data (void); + + /// Set a pointer to the data in the message. + void data (const T &data); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Type of message. + long type_; + + /// Length of this message. + int length_; + + /// Maximum length of any message. + int max_; + + /// Data stored in a message. + T data_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Typed_SV_Message.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Typed_SV_Message.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_TYPED_SV_MESSAGE_H */ diff --git a/dep/ACE_wrappers/ace/Typed_SV_Message.inl b/dep/ACE_wrappers/ace/Typed_SV_Message.inl new file mode 100644 index 000000000..6d8ea7023 --- /dev/null +++ b/dep/ACE_wrappers/ace/Typed_SV_Message.inl @@ -0,0 +1,96 @@ +// -*- C++ -*- +// +// $Id: Typed_SV_Message.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/config-all.h" +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_Typed_SV_Message::ACE_Typed_SV_Message (long t, + int l, + int m) + : type_ (t) +{ + ACE_TRACE ("ACE_Typed_SV_Message::ACE_Typed_SV_Message"); + this->length (l); + this->max_size (m); +} + +template ACE_INLINE +ACE_Typed_SV_Message::ACE_Typed_SV_Message (const T &d, + long t, + int l, + int m) + : type_ (t), + data_ (d) +{ + ACE_TRACE ("ACE_Typed_SV_Message::ACE_Typed_SV_Message"); + this->length (l); + this->max_size (m); +} + +template ACE_INLINE +ACE_Typed_SV_Message::~ACE_Typed_SV_Message (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message::~ACE_Typed_SV_Message"); +} + +template ACE_INLINE long +ACE_Typed_SV_Message::type (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::type"); + return this->type_; +} + +template ACE_INLINE void +ACE_Typed_SV_Message::type (long t) +{ + ACE_TRACE ("ACE_Typed_SV_Message::type"); + this->type_ = t; +} + +template ACE_INLINE int +ACE_Typed_SV_Message::length (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::length"); + return this->length_; +} + +template ACE_INLINE void +ACE_Typed_SV_Message::length (int len) +{ + ACE_TRACE ("ACE_Typed_SV_Message::length"); + this->length_ = len + (sizeof *this - (sizeof this->type_ + sizeof this->data_)); +} + +template ACE_INLINE int +ACE_Typed_SV_Message::max_size (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::max_size"); + return this->max_; +} + +template ACE_INLINE void +ACE_Typed_SV_Message::max_size (int m) +{ + ACE_TRACE ("ACE_Typed_SV_Message::max_size"); + this->max_ = m + (sizeof *this - (sizeof this->type_ + sizeof this->data_)); +} + +template T & +ACE_Typed_SV_Message::data (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message::data"); + return this->data_; +} + +template void +ACE_Typed_SV_Message::data (const T &d) +{ + ACE_TRACE ("ACE_Typed_SV_Message::data"); + this->data_ = d; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.cpp b/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.cpp new file mode 100644 index 000000000..0adb589e6 --- /dev/null +++ b/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.cpp @@ -0,0 +1,56 @@ +// $Id: Typed_SV_Message_Queue.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_TYPED_SV_MESSAGE_QUEUE_CPP +#define ACE_TYPED_SV_MESSAGE_QUEUE_CPP + +#include "ace/Typed_SV_Message.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Typed_SV_Message_Queue.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message_Queue.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Typed_SV_Message_Queue) + +template void +ACE_Typed_SV_Message_Queue::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Typed_SV_Message_Queue::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue"); +} + +template +ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue (key_t external_id, + int create, + int perms) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue"); + if (this->open (external_id, create, perms) == -1) + ACE_ERROR ((LM_ERROR, + "ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue")); +} + +template +ACE_Typed_SV_Message_Queue::~ACE_Typed_SV_Message_Queue (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::~ACE_Typed_SV_Message_Queue"); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_TYPED_SV_MESSAGE_QUEUE_CPP */ diff --git a/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.h b/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.h new file mode 100644 index 000000000..12c0e5092 --- /dev/null +++ b/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.h @@ -0,0 +1,92 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Typed_SV_Message_Queue.h + * + * $Id: Typed_SV_Message_Queue.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_TYPED_MESSAGE_QUEUE_H +#define ACE_TYPED_MESSAGE_QUEUE_H +#include /**/ "ace/pre.h" + +#include "ace/SV_Message_Queue.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Typed_SV_Message.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Typed_SV_Message_Queue + * + * @brief Defines the header file for the C++ wrapper facade for typed message queues. + */ +template +class ACE_Typed_SV_Message_Queue +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0, + ACE_NOWAIT = IPC_NOWAIT + }; + + // = Initialization and termination operations. + ACE_Typed_SV_Message_Queue (void); + ACE_Typed_SV_Message_Queue (key_t external_id, + int create = ACE_OPEN, + int perms = ACE_DEFAULT_FILE_PERMS); + int open (key_t external_id, + int create = ACE_OPEN, + int perms = ACE_DEFAULT_FILE_PERMS); + int close (void); + int remove (void); + ~ACE_Typed_SV_Message_Queue (void); + + /// Send method. + int send (const ACE_Typed_SV_Message &mb, int mflags = 0); + + /// Recv method. + int recv (ACE_Typed_SV_Message &mb, int mflags = 0); + + /// Return the id of the underlying ACE_SV_Message_Queue. + int get_id (void) const; + + /// Control the underlying message queue. + int control (int option, void *arg = 0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + ACE_SV_Message_Queue message_queue_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Typed_SV_Message_Queue.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Typed_SV_Message_Queue.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TYPED_MESSAGE_QUEUE_H */ diff --git a/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.inl b/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.inl new file mode 100644 index 000000000..90539936e --- /dev/null +++ b/dep/ACE_wrappers/ace/Typed_SV_Message_Queue.inl @@ -0,0 +1,80 @@ +// -*- C++ -*- +// +// $Id: Typed_SV_Message_Queue.inl 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/SV_Message_Queue.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::open (key_t external_id, + int create, + int perms) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::open"); + return this->message_queue_.open (external_id, create, perms); +} + +// What does it mean to close a message queue?! + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::close (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::close"); + return 1; +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::recv (ACE_Typed_SV_Message &mb, + int mflags) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::recv"); + + int length = + this->message_queue_.recv (reinterpret_cast (mb), + mb.max_size (), + mb.type (), + mflags); + if (length != -1) + mb.length (length); + + return length; +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::send (const ACE_Typed_SV_Message &mb, + int mflags) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::send"); + return + this->message_queue_.send ( + reinterpret_cast ( + const_cast &> (mb)), + mb.length (), + mflags); +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::remove (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::remove"); + + return this->message_queue_.remove (); +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::control (int option, + void *arg) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::control"); + + return this->message_queue_.control (option, arg); +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::get_id (void) const +{ + return this->message_queue_.get_id (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/UNIX_Addr.cpp b/dep/ACE_wrappers/ace/UNIX_Addr.cpp new file mode 100644 index 000000000..013af8a33 --- /dev/null +++ b/dep/ACE_wrappers/ace/UNIX_Addr.cpp @@ -0,0 +1,151 @@ +// $Id: UNIX_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/UNIX_Addr.h" + +ACE_RCSID(ace, UNIX_Addr, "$Id: UNIX_Addr.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +#if !defined (__ACE_INLINE__) +#include "ace/UNIX_Addr.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_UNIX_Addr) + +// Set a pointer to the address. +void +ACE_UNIX_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_UNIX_Addr::set_addr"); + + this->ACE_Addr::base_set (AF_UNIX, len); + ACE_OS::memcpy ((void *) &this->unix_addr_, + (void *) addr, + len); +} + +// Return a pointer to the underlying address. + +void * +ACE_UNIX_Addr::get_addr (void) const +{ + return (void *) &this->unix_addr_; +} + +// Transform the string into the current addressing format. + +int +ACE_UNIX_Addr::string_to_addr (const char addr[]) +{ + ACE_OS::strsncpy (this->unix_addr_.sun_path, addr, + sizeof this->unix_addr_.sun_path); + return 0; +} + +// Transform the current address into string format. + +int +ACE_UNIX_Addr::addr_to_string (ACE_TCHAR s[], size_t len) const +{ + ACE_OS::strsncpy (s, + ACE_TEXT_CHAR_TO_TCHAR (this->unix_addr_.sun_path), + len); + return 0; +} + +u_long +ACE_UNIX_Addr::hash (void) const +{ + return ACE::hash_pjw (this->unix_addr_.sun_path); +} + +void +ACE_UNIX_Addr::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +#endif /* ACE_HAS_DUMP */ +} + +// Do nothing constructor. + +ACE_UNIX_Addr::ACE_UNIX_Addr (void) + : ACE_Addr (AF_UNIX, sizeof this->unix_addr_) +{ + (void) ACE_OS::memset ((void *) &this->unix_addr_, + 0, + sizeof this->unix_addr_); + + this->unix_addr_.sun_family = AF_UNIX; +} + +int +ACE_UNIX_Addr::set (const ACE_UNIX_Addr &sa) +{ + if (sa.get_type () == AF_ANY) + (void) ACE_OS::memset ((void *) &this->unix_addr_, + 0, + sizeof this->unix_addr_); + else + ACE_OS::strcpy (this->unix_addr_.sun_path, + sa.unix_addr_.sun_path); + + this->unix_addr_.sun_family = AF_UNIX; + this->base_set (sa.get_type (), sa.get_size ()); + + return 0; +} + +// Copy constructor. + +ACE_UNIX_Addr::ACE_UNIX_Addr (const ACE_UNIX_Addr &sa) + : ACE_Addr (AF_UNIX, sa.get_size ()) +{ + this->set (sa); +} + +int +ACE_UNIX_Addr::set (const sockaddr_un *un, int len) +{ + (void) ACE_OS::memset ((void *) &this->unix_addr_, 0, + sizeof this->unix_addr_); + this->unix_addr_.sun_family = AF_UNIX; + ACE_OS::strcpy (this->unix_addr_.sun_path, un->sun_path); + this->base_set (AF_UNIX, len); + return 0; +} + +ACE_UNIX_Addr::ACE_UNIX_Addr (const sockaddr_un *un, int len) +{ + this->set (un, len); +} + +int +ACE_UNIX_Addr::set (const char rendezvous_point[]) +{ + (void) ACE_OS::memset ((void *) &this->unix_addr_, + 0, + sizeof this->unix_addr_); + this->unix_addr_.sun_family = AF_UNIX; + (void) ACE_OS::strsncpy (this->unix_addr_.sun_path, + rendezvous_point, + sizeof this->unix_addr_.sun_path); + + this->ACE_Addr::base_set (AF_UNIX, + sizeof this->unix_addr_ - + sizeof (this->unix_addr_.sun_path) + + ACE_OS::strlen (this->unix_addr_.sun_path)); + return 0; +} + +// Create a ACE_Addr from a UNIX pathname. + +ACE_UNIX_Addr::ACE_UNIX_Addr (const char rendezvous_point[]) +{ + this->set (rendezvous_point); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/dep/ACE_wrappers/ace/UNIX_Addr.h b/dep/ACE_wrappers/ace/UNIX_Addr.h new file mode 100644 index 000000000..887529fe1 --- /dev/null +++ b/dep/ACE_wrappers/ace/UNIX_Addr.h @@ -0,0 +1,117 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file UNIX_Addr.h + * + * $Id: UNIX_Addr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_UNIX_ADDR_H +#define ACE_UNIX_ADDR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +#include "ace/Addr.h" +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/os_include/sys/os_un.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_UNIX_Addr + * + * @brief Defines the ``UNIX domain address family'' address format. + */ +class ACE_Export ACE_UNIX_Addr : public ACE_Addr +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_UNIX_Addr (void); + + /// Copy constructor. + ACE_UNIX_Addr (const ACE_UNIX_Addr &sa); + + /// Creates an ACE_UNIX_Addr from a string. + ACE_UNIX_Addr (const char rendezvous_point[]); + + /// Creates an ACE_INET_Addr from a sockaddr_un structure. + ACE_UNIX_Addr (const sockaddr_un *, int len); + + /// Creates an ACE_UNIX_Addr from another ACE_UNIX_Addr. + int set (const ACE_UNIX_Addr &sa); + + /// Creates an ACE_UNIX_Addr from a string. + int set (const char rendezvous_point[]); + + /// Creates an ACE_UNIX_Addr from a sockaddr_un structure. + int set (const sockaddr_un *, int len); + + /// Return a pointer to the underlying network address. + virtual void *get_addr (void) const; + + /// Set a pointer to the underlying network address. + virtual void set_addr (void *addr, int len); + + /// Transform the current address into string format. + virtual int addr_to_string (ACE_TCHAR addr[], size_t) const; + + /// Transform the string into the current addressing format. + virtual int string_to_addr (const char addr[]); + +#if defined (ACE_HAS_WCHAR) + /// Creates an ACE_UNIX_Addr from a string. + ACE_UNIX_Addr (const wchar_t rendezvous_point[]); + + /// Creates an ACE_UNIX_Addr from a string. + int set (const wchar_t rendezvous_point[]); +#endif /* ACE_HAS_WCHAR */ + + /// Compare two addresses for equality. + bool operator == (const ACE_UNIX_Addr &SAP) const; + + /// Compare two addresses for inequality. + bool operator != (const ACE_UNIX_Addr &SAP) const; + + /// Return the path name of the underlying rendezvous point. + const char *get_path_name (void) const; + + /// Computes and returns hash value. + virtual u_long hash (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Underlying socket address. + sockaddr_un unix_addr_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/UNIX_Addr.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_UNIX_ADDR_H */ diff --git a/dep/ACE_wrappers/ace/UNIX_Addr.inl b/dep/ACE_wrappers/ace/UNIX_Addr.inl new file mode 100644 index 000000000..5e801b56f --- /dev/null +++ b/dep/ACE_wrappers/ace/UNIX_Addr.inl @@ -0,0 +1,57 @@ +// -*- C++ -*- +// +// $Id: UNIX_Addr.inl 80826 2008-03-04 14:51:23Z wotte $ + + +#include "ace/OS_NS_string.h" + + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_HAS_WCHAR) +/// Creates an ACE_UNIX_Addr from a string. +ACE_INLINE +ACE_UNIX_Addr::ACE_UNIX_Addr (const wchar_t rendezvous_point[]) +{ + this->set (ACE_Wide_To_Ascii (rendezvous_point).char_rep ()); +} + +/// Creates an ACE_UNIX_Addr from a string. +ACE_INLINE int +ACE_UNIX_Addr::set (const wchar_t rendezvous_point[]) +{ + return this->set (ACE_Wide_To_Ascii (rendezvous_point).char_rep ()); +} +#endif /* ACE_HAS_WCHAR */ + +// Compare two addresses for equality. + +ACE_INLINE bool +ACE_UNIX_Addr::operator == (const ACE_UNIX_Addr &sap) const +{ + return ACE_OS::strncmp (this->unix_addr_.sun_path, + sap.unix_addr_.sun_path, + sizeof this->unix_addr_.sun_path) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE bool +ACE_UNIX_Addr::operator != (const ACE_UNIX_Addr &sap) const +{ + return !((*this) == sap); // This is lazy, of course... ;-) +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE const char * +ACE_UNIX_Addr::get_path_name (void) const +{ + return this->unix_addr_.sun_path; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Acceptor.cpp b/dep/ACE_wrappers/ace/UPIPE_Acceptor.cpp new file mode 100644 index 000000000..0b8954d5d --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Acceptor.cpp @@ -0,0 +1,129 @@ +// $Id: UPIPE_Acceptor.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/UPIPE_Acceptor.h" + +ACE_RCSID(ace, UPIPE_Acceptor, "$Id: UPIPE_Acceptor.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_unistd.h" + +#if !defined (__ACE_INLINE__) +#include "ace/UPIPE_Acceptor.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Acceptor) + +void +ACE_UPIPE_Acceptor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_UPIPE_Acceptor::dump"); +#endif /* ACE_HAS_DUMP */ +} + +/* Do nothing routine for constructor. */ + +ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor (void) + : mb_ (sizeof (ACE_UPIPE_Stream *)) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor"); +} + +ACE_UPIPE_Acceptor::~ACE_UPIPE_Acceptor (void) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::~ACE_UPIPE_Acceptor"); +} + +// General purpose routine for performing server ACE_UPIPE. + +int +ACE_UPIPE_Acceptor::open (const ACE_UPIPE_Addr &local_addr, + int reuse_addr) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::open"); + return this->ACE_SPIPE_Acceptor::open (local_addr, reuse_addr); +} + +int +ACE_UPIPE_Acceptor::close (void) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::close"); + return this->ACE_SPIPE_Acceptor::close (); +} + +// General purpose routine for accepting new connections. + +ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor (const ACE_UPIPE_Addr &local_addr, + int reuse_addr) + : mb_ (sizeof (ACE_UPIPE_Stream *)) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor"); + + if (this->open (local_addr, reuse_addr) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_UPIPE_Acceptor"))); +} + +int +ACE_UPIPE_Acceptor::accept (ACE_UPIPE_Stream &new_stream, + ACE_UPIPE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::accept"); + ACE_UNUSED_ARG (reset_new_handle); + + ACE_SPIPE_Stream new_io; + + if (this->ACE_SPIPE_Acceptor::accept (new_io, remote_addr, + timeout, restart) == -1) + return -1; + else + { + ACE_UPIPE_Stream *remote_stream = 0; + + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, new_stream.lock_, -1)); + + new_stream.set_handle (new_io.get_handle ()); + new_stream.reference_count_++; + + // Transfer address ownership. + new_io.get_local_addr (new_stream.local_addr_); + new_io.get_remote_addr (new_stream.remote_addr_); + + // Now that we got the handle, we'll read the address of the + // connector-side ACE_UPIPE_Stream out of the pipe and link that + // ACE_UPIPE_Stream to our ACE_UPIPE_Stream. + + if (ACE_OS::read (new_stream.get_handle (), + (char *) &remote_stream, + sizeof remote_stream) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_UPIPE_Acceptor: %p\n"), + ACE_TEXT ("read stream address failed"))); + else if (new_stream.stream_.link (remote_stream->stream_) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_UPIPE_Acceptor: %p\n"), + ACE_TEXT ("link streams failed"))); + // Send a message over the new streampipe to confirm acceptance. + else if (new_stream.send (&mb_, 0) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_UPIPE_Acceptor: %p\n"), + ACE_TEXT ("linked stream.put failed"))); + + // Close down the new_stream at this point in order to conserve + // handles. Note that we don't need the SPIPE connection + // anymore since we're now linked via the . + new_stream.ACE_SPIPE::close (); + return 0; + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Acceptor.h b/dep/ACE_wrappers/ace/UPIPE_Acceptor.h new file mode 100644 index 000000000..0fd33226e --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Acceptor.h @@ -0,0 +1,99 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file UPIPE_Acceptor.h + * + * $Id: UPIPE_Acceptor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer + * @author Douglas C. Schmidt + */ +//============================================================================= + + +#ifndef ACE_UPIPE_ACCEPTOR_H +#define ACE_UPIPE_ACCEPTOR_H +#include /**/ "ace/pre.h" + +#include "ace/UPIPE_Stream.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +#include "ace/SPIPE_Acceptor.h" +#include "ace/Thread_Manager.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_UPIPE_Acceptor + * + * @brief Defines the format and interface for the listener side of the + * ACE_UPIPE_Stream. + */ +class ACE_Export ACE_UPIPE_Acceptor : public ACE_SPIPE_Acceptor +{ +public: + // = Initialization and termination. + /// Default constructor. + ACE_UPIPE_Acceptor (void); + + /// Initialize passive endpoint. + ACE_UPIPE_Acceptor (const ACE_UPIPE_Addr &local_sap, + int reuse_addr = 0); + + /// Initialize passive endpoint. + int open (const ACE_UPIPE_Addr &local_sap, + int reuse_addr = 0); + + /// Close down and release resources. + ~ACE_UPIPE_Acceptor (void); + + /// Close down and release resources. + int close (void); + + /// Close down and release resources and remove the underlying SPIPE + /// rendezvous point. + int remove (void); + + // = Passive connection acceptance method. + /** + * Accept a new data transfer connection. A @a timeout of 0 means + * block forever, a @a timeout of {0, 0} means poll. @a restart == 1 + * means "restart if interrupted." + */ + int accept (ACE_UPIPE_Stream &server_stream, + ACE_UPIPE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int reset_new_handle = 0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Manage threads. + ACE_Thread_Manager tm; + + /// To confirm connection establishment. + ACE_Message_Block mb_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/UPIPE_Acceptor.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_UPIPE_ACCEPTOR_H */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Acceptor.inl b/dep/ACE_wrappers/ace/UPIPE_Acceptor.inl new file mode 100644 index 000000000..9432ad7bb --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Acceptor.inl @@ -0,0 +1,14 @@ +// -*- C++ -*- +// +// $Id: UPIPE_Acceptor.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE int +ACE_UPIPE_Acceptor::remove (void) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::remove"); + return this->ACE_SPIPE_Acceptor::remove (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/UPIPE_Addr.h b/dep/ACE_wrappers/ace/UPIPE_Addr.h new file mode 100644 index 000000000..aaf33b683 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Addr.h @@ -0,0 +1,33 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file UPIPE_Addr.h + * + * $Id: UPIPE_Addr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_UPIPE_ADDR_H +#define ACE_UPIPE_ADDR_H + +#include /**/ "ace/pre.h" + +#include "ace/SPIPE_Addr.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +typedef ACE_SPIPE_Addr ACE_UPIPE_Addr; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_UPIPE_ADDR_H */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Connector.cpp b/dep/ACE_wrappers/ace/UPIPE_Connector.cpp new file mode 100644 index 000000000..9b9bfcd38 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Connector.cpp @@ -0,0 +1,101 @@ +// $Id: UPIPE_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/UPIPE_Connector.h" + +ACE_RCSID(ace, UPIPE_Connector, "$Id: UPIPE_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_THREADS) + +#include "ace/Handle_Ops.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stropts.h" + +#if !defined (__ACE_INLINE__) +#include "ace/UPIPE_Connector.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Connector) + +void +ACE_UPIPE_Connector::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_UPIPE_Connector::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_UPIPE_Connector::ACE_UPIPE_Connector (void) +{ + ACE_TRACE ("ACE_UPIPE_Connector::ACE_UPIPE_Connector"); +} + +int +ACE_UPIPE_Connector::connect (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout, + const ACE_Addr & /* local_sap */, + int /* reuse_addr */, + int flags, + int perms) +{ + ACE_TRACE ("ACE_UPIPE_Connector::connect"); + ACE_ASSERT (new_stream.get_handle () == ACE_INVALID_HANDLE); + + ACE_HANDLE handle = ACE::handle_timed_open (timeout, + addr.get_path_name (), + flags, perms); + + if (handle == ACE_INVALID_HANDLE) + return -1; +#if !defined (ACE_WIN32) + else if (ACE_OS::isastream (handle) != 1) + return -1; +#endif + else // We're connected! + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, new_stream.lock_, -1)); + + ACE_UPIPE_Stream *ustream = &new_stream; + + new_stream.set_handle (handle); + new_stream.remote_addr_ = addr; // class copy. + new_stream.reference_count_++; + + // Now send the address of our ACE_UPIPE_Stream over this pipe + // to our corresponding ACE_UPIPE_Acceptor, so he may link the + // two streams. + ssize_t result = ACE_OS::write (handle, + (const char *) &ustream, + sizeof ustream); + if (result == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_UPIPE_Connector %p\n"), + ACE_TEXT ("write to pipe failed"))); + + // Wait for confirmation of stream linking. + ACE_Message_Block *mb_p = 0; + + // Our part is done, wait for server to confirm connection. + result = new_stream.recv (mb_p, 0); + + // Do *not* coalesce the following two checks for result == -1. + // They perform different checks and cannot be merged. + if (result == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_UPIPE_Connector %p\n"), + ACE_TEXT ("no confirmation from server"))); + else + // Close down the new_stream at this point in order to + // conserve handles. Note that we don't need the SPIPE + // connection anymore since we're linked via the Message_Queue + // now. + new_stream.ACE_SPIPE::close (); + return static_cast (result); + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Connector.h b/dep/ACE_wrappers/ace/UPIPE_Connector.h new file mode 100644 index 000000000..ea4fc2ec7 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Connector.h @@ -0,0 +1,115 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file UPIPE_Connector.h + * + * $Id: UPIPE_Connector.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer and Douglas C. Schmidt + */ +//============================================================================= + + +#ifndef ACE_UPIPE_CONNECTOR_H +#define ACE_UPIPE_CONNECTOR_H +#include /**/ "ace/pre.h" + +#include "ace/UPIPE_Stream.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_UPIPE_Connector + * + * @brief Defines an active connection factory for the + * ACE_UPIPE_STREAM wrappers. + */ +class ACE_Export ACE_UPIPE_Connector +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_UPIPE_Connector (void); + + /** + * Actively connect and produce a @a new_stream if things go well. + * The @a addr is the address that we are trying to connect + * with. The @a timeout is the amount of time to wait to connect. + * If it's 0 then we block indefinitely. If *timeout == {0, 0} then + * the connection is done using non-blocking mode. In this case, if + * the connection can't be made immediately the value of -1 is + * returned with @c errno == EWOULDBLOCK. If *timeout > {0, 0} then + * this is the maximum amount of time to wait before timing out. If the + * time expires before the connection is made @c errno == ETIME. The + * @a local_sap is the value of local address to bind to. If it's + * the default value of ACE_Addr::sap_any then the user is letting + * the OS do the binding. If @a reuse_addr == 1 then the + * @a local_addr is reused, even if it hasn't been cleanedup yet. + * The @a flags and @a perms arguments are passed down to the open() + * method. + */ + ACE_UPIPE_Connector (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + + /** + * Actively connect and produce a @a new_stream if things go well. + * The @a addr is the address that we are trying to connect + * with. The @a timeout is the amount of time to wait to connect. + * If it's 0 then we block indefinitely. If *timeout == {0, 0} then + * the connection is done using non-blocking mode. In this case, if + * the connection can't be made immediately the value of -1 is + * returned with @c errno == EWOULDBLOCK. If *timeout > {0, 0} then + * this is the maximum amount of time to wait before timing out. If the + * time expires before the connection is made @c errno == ETIME. The + * @a local_sap is the value of local address to bind to. If it's + * the default value of ACE_Addr::sap_any then the user is letting + * the OS do the binding. If @a reuse_addr == 1 then the + * @a local_addr is reused, even if it hasn't been cleanedup yet. + * The @a flags and @a perms arguments are passed down to the open() + * method. + */ + int connect (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + + /// Resets any event associations on this handle + int reset_new_handle (ACE_HANDLE handle); + + // = Meta-type info + typedef ACE_UPIPE_Addr PEER_ADDR; + typedef ACE_UPIPE_Stream PEER_STREAM; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/UPIPE_Connector.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_UPIPE_CONNECTOR_H */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Connector.inl b/dep/ACE_wrappers/ace/UPIPE_Connector.inl new file mode 100644 index 000000000..fa43dbea3 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Connector.inl @@ -0,0 +1,34 @@ +// -*- C++ -*- +// +// $Id: UPIPE_Connector.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Creates a Local ACE_UPIPE. +ACE_INLINE +ACE_UPIPE_Connector::ACE_UPIPE_Connector (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_UPIPE_Connector::ACE_UPIPE_Connector"); + if (this->connect (new_stream, addr, timeout, local_sap, + reuse_addr, flags, perms) == -1 + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME)) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("address %s, %p\n"), + addr.get_path_name (), + ACE_TEXT ("ACE_UPIPE_Connector"))); +} + +ACE_INLINE int +ACE_UPIPE_Connector::reset_new_handle (ACE_HANDLE /* handle */) +{ + // Nothing to do here since the handle is not a socket + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/UPIPE_Stream.cpp b/dep/ACE_wrappers/ace/UPIPE_Stream.cpp new file mode 100644 index 000000000..d07722a48 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Stream.cpp @@ -0,0 +1,234 @@ +// $Id: UPIPE_Stream.cpp 82559 2008-08-07 20:23:07Z parsons $ + +#include "ace/UPIPE_Stream.h" + +ACE_RCSID(ace, UPIPE_Stream, "$Id: UPIPE_Stream.cpp 82559 2008-08-07 20:23:07Z parsons $") + +#if defined (ACE_HAS_THREADS) + +#include "ace/OS_NS_string.h" + +#if !defined (__ACE_INLINE__) +#include "ace/UPIPE_Stream.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Stream) + +ACE_UPIPE_Stream::ACE_UPIPE_Stream (void) + : mb_last_ (0), + reference_count_ (0) +{ + ACE_TRACE ("ACE_UPIPE_Stream::ACE_UPIPE_STREAM"); +} + +ACE_UPIPE_Stream::~ACE_UPIPE_Stream (void) +{ + if (this->mb_last_ != 0) + { + this->mb_last_->release (); + this->mb_last_ = 0; + } +} + +int +ACE_UPIPE_Stream::control (int cmd, + void * val) const +{ + ACE_TRACE ("ACE_UPIPE_Stream::control"); + + return ((ACE_UPIPE_Stream *) this)->stream_.control + ((ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds) cmd, val); +} + +void +ACE_UPIPE_Stream::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_UPIPE_Stream::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_UPIPE_Stream::close (void) +{ + ACE_TRACE ("ACE_UPIPE_Stream::close"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + this->reference_count_--; + + if (this->reference_count_ == 0) + { + // Since the UPIPE should have been closed earlier we won't bother + // checking to see if closing it now fails. + + if (this->ACE_SPIPE::get_handle () != ACE_INVALID_HANDLE) + this->ACE_SPIPE::close (); + + // Close down the ACE_stream. + return this->stream_.close (); + } + return 0; +} + +int +ACE_UPIPE_Stream::get_remote_addr (ACE_UPIPE_Addr &remote_sap) const +{ + ACE_TRACE ("ACE_UPIPE_Stream::get_remote_addr"); + remote_sap = this->remote_addr_; + return 0; +} + +int +ACE_UPIPE_Stream::send (ACE_Message_Block *mb_p, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::send_msg"); + return this->stream_.put (mb_p, timeout) == -1 ? -1 : 0; +} + +int ACE_UPIPE_Stream::recv (ACE_Message_Block *& mb_p, + ACE_Time_Value *timeout) +{ + return this->stream_.get (mb_p, timeout) == -1 ? -1 : 0; +} + +// Send a buffer. + +ssize_t +ACE_UPIPE_Stream::send (const char *buffer, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::send"); + + ACE_Message_Block *mb_p; + ACE_NEW_RETURN (mb_p, + ACE_Message_Block (n), + -1); + mb_p->copy (buffer, n); + return + this->stream_.put (mb_p, timeout) == -1 + ? -1 + : static_cast (n); +} + +// Receive a buffer. + +ssize_t +ACE_UPIPE_Stream::recv (char *buffer, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::recv"); + // Index in buffer. + size_t bytes_read = 0; + + while (bytes_read < n) + if (this->mb_last_ != 0) + { + // We have remaining data in our last read Message_Buffer. + size_t this_len = this->mb_last_->length (); + if (this_len < n) + { + // The remaining data is not enough. + + ACE_OS::memcpy ((void *) &buffer[bytes_read], + this->mb_last_->rd_ptr (), + this_len); + bytes_read += this_len; + this->mb_last_ = this->mb_last_->release (); // mb_last_ now 0 + return static_cast (bytes_read); + } + else + { + // The remaining data is at least enough. If there's + // more, we'll get it the next time through. + ACE_OS::memcpy (&buffer[bytes_read], + this->mb_last_->rd_ptr (), + n); + bytes_read += n; + + // Advance rd_ptr. + this->mb_last_->rd_ptr (n); + + if (this->mb_last_->length () == 0) + // Now the Message_Buffer is empty. + this->mb_last_ = this->mb_last_->release (); + } + } + else + { + // We have to get a new Message_Buffer from our stream. + int result = this->stream_.get (this->mb_last_, timeout); + + if (result == -1) + { + if (errno == EWOULDBLOCK && bytes_read > 0) + // Return the number of bytes read before we timed out. + return static_cast (bytes_read); + else + return -1; + } + } + + return static_cast (bytes_read); +} + +ssize_t +ACE_UPIPE_Stream::send_n (const char *buf, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::send_n"); + + size_t bytes_written; + ssize_t len = 0; + + for (bytes_written = 0; bytes_written < n; bytes_written += len) + { + len = this->send (buf + bytes_written, + n - bytes_written, + timeout); + + if (len == -1) + { + return -1; + } + } + + return static_cast (bytes_written); +} + +ssize_t +ACE_UPIPE_Stream::recv_n (char *buf, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::recv_n"); + size_t bytes_read; + ssize_t len = 0; + + for (bytes_read = 0; bytes_read < n; bytes_read += len) + { + len = this->recv (buf + bytes_read, + n - bytes_read, + timeout); + + if (len == -1) + { + return -1; + } + else if (len == 0) + { + break; + } + } + + return static_cast< ssize_t> (bytes_read); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_THREADS */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Stream.h b/dep/ACE_wrappers/ace/UPIPE_Stream.h new file mode 100644 index 000000000..b10aef115 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Stream.h @@ -0,0 +1,140 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file UPIPE_Stream.h + * + * $Id: UPIPE_Stream.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Gerhard Lenzer + * @author Douglas C. Schmidt + */ +//============================================================================= + + +#ifndef ACE_UPIPE_STREAM_H +#define ACE_UPIPE_STREAM_H +#include /**/ "ace/pre.h" + +#include "ace/Stream.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +#include "ace/SPIPE.h" +#include "ace/Message_Queue.h" +#include "ace/UPIPE_Addr.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_UPIPE_Stream + * + * @brief Defines the method that transfer data on a UPIPE. + */ +class ACE_Export ACE_UPIPE_Stream : public ACE_SPIPE +{ +public: + friend class ACE_UPIPE_Acceptor; + friend class ACE_UPIPE_Connector; + + typedef ACE_Stream MT_Stream; + + // = Initialization and Termination. + + ACE_UPIPE_Stream (void); + + virtual ~ACE_UPIPE_Stream (void); + + /// Shut down the UPIPE and release resources. + int close (void); + + /// Return the underlying I/O handle. + ACE_HANDLE get_handle (void) const; + + // = Send/recv ACE Message_Blocks. + /// Send a message through the message queue. Returns -1 on error, + /// else 0. + int send (ACE_Message_Block *mb_p, + ACE_Time_Value *timeout = 0); + + /// Recv a message from the message queue. Returns -1 on error, else + /// 0. + int recv (ACE_Message_Block *&mb_p, + ACE_Time_Value *timeout = 0); + + // = Send/recv char buffers. + /// Send a buffer of @a n bytes through the message queue. Returns -1 + /// on error, else number of bytes sent. + ssize_t send (const char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + + /// Recv a buffer of upto @a n bytes from the message queue. Returns + /// -1 on error, else number of bytes read. + ssize_t recv (char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + + /// Send a buffer of exactly @a n bytes to the message queue. Returns + /// -1 on error, else number of bytes written (which should == n). + ssize_t send_n (const char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + + /// Recv a buffer of exactly @a n bytes from the message queue. + /// Returns -1 on error, else the number of bytes read. + ssize_t recv_n (char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + + /// Perform control operations on the UPIPE_Stream. + int control (int cmd, void *val) const; + + /// Return the remote address we are connected to. + int get_remote_addr (ACE_UPIPE_Addr &remote_sap) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Meta-type info + typedef ACE_UPIPE_Addr PEER_ADDR; + +private: + /// To hold the last ACE_Message_Block read out of the stream. Thus + /// allowing subsequent reads from one ACE_Message_Block + ACE_Message_Block *mb_last_; + + /// Address of who we are connected to. + ACE_UPIPE_Addr remote_addr_; + + /// Stream component used by the @c UPIPE_Acceptor and + /// @c UPIPE_Connector to link together two UPIPE_Streams. + MT_Stream stream_; + + /// Keep track of whether the sender and receiver have both shutdown. + int reference_count_; + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + /// Ensure that we are thread-safe. + ACE_Thread_Mutex lock_; +#endif /* ACE_MT_SAFE */ +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/UPIPE_Stream.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" + +#endif /*ACE_UPIPE_STREAM_H */ diff --git a/dep/ACE_wrappers/ace/UPIPE_Stream.inl b/dep/ACE_wrappers/ace/UPIPE_Stream.inl new file mode 100644 index 000000000..7a0d73c31 --- /dev/null +++ b/dep/ACE_wrappers/ace/UPIPE_Stream.inl @@ -0,0 +1,14 @@ +// -*- C++ -*- +// +// $Id: UPIPE_Stream.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE ACE_HANDLE +ACE_UPIPE_Stream::get_handle (void) const +{ + ACE_TRACE ("ACE_UPIPE_Stream::get_handle"); + return this->ACE_SPIPE::get_handle (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.cpp b/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.cpp new file mode 100644 index 000000000..0a51cf9fb --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.cpp @@ -0,0 +1,364 @@ +// $Id: UTF16_Encoding_Converter.cpp 80826 2008-03-04 14:51:23Z wotte $ + +// ====================================================================== +// +// The actual conversion methods are covered by the copyright information +// below. It is not the actual code provided by Unicode, Inc. but is an +// ACE-ified and only slightly modified version. +// Chad Elliott 4/28/2005 +// +// Copyright 2001-2004 Unicode, Inc. +// +// Limitations on Rights to Redistribute This Code +// +// Unicode, Inc. hereby grants the right to freely use the information +// supplied in this file in the creation of products supporting the +// Unicode Standard, and to make copies of this file in any form +// for internal or external distribution as long as this notice +// remains attached. +// +// ====================================================================== + +#include "ace/UTF16_Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +#include "ace/OS_NS_stdio.h" +#include "ace/OS_Memory.h" +#include "ace/Min_Max.h" + +#if !defined (__ACE_INLINE__) +#include "ace/UTF16_Encoding_Converter.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +static const ACE_UINT32 halfShift = 10; +static const ACE_UINT32 halfBase = 0x00010000; +static const ACE_UINT32 halfMask = 0x000003FF; + +static const ACE_UINT32 UNI_SUR_HIGH_START = 0x0000D800; +static const ACE_UINT32 UNI_SUR_HIGH_END = 0x0000DBFF; +static const ACE_UINT32 UNI_SUR_LOW_START = 0x0000DC00; +static const ACE_UINT32 UNI_SUR_LOW_END = 0x0000DFFF; +static const ACE_UINT32 UNI_REPLACEMENT_CHAR = 0x0000FFFD; +static const ACE_UINT32 UNI_MAX_BMP = 0x0000FFFF; +static const ACE_UINT32 UNI_MAX_UTF16 = 0x0010FFFF; + +// Once the bits are split out into bytes of UTF-8, this is a mask OR-ed +// into the first byte, depending on how many bytes follow. There are +// as many entries in this table as there are UTF-8 sequence types. +// (I.e., one byte sequence, two byte... etc.). Remember that sequencs +// for *legal* UTF-8 will be 4 or fewer bytes total. +static const ACE_Byte firstByteMark[7] = { 0x00, 0x00, 0xC0, + 0xE0, 0xF0, 0xF8, 0xFC }; + +// Index into the table below with the first byte of a UTF-8 sequence to +// get the number of trailing bytes that are supposed to follow it. +// Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is +// left as-is for anyone who may want to do such conversion, which was +// allowed in earlier algorithms. +static const ACE_Byte trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +// Magic values subtracted from a buffer value during UTF8 conversion. +// This table contains as many values as there might be trailing bytes +// in a UTF-8 sequence. +static const ACE_UINT32 offsetsFromUTF8[6] = { 0x00000000, 0x00003080, + 0x000E2080, 0x03C82080, + 0xFA082080, 0x82082080 }; + + +ACE_UTF16_Encoding_Converter::ACE_UTF16_Encoding_Converter (bool swap) + : swap_ (swap) +{ +} + +ACE_UTF16_Encoding_Converter::~ACE_UTF16_Encoding_Converter (void) +{ +} + +ACE_UTF16_Encoding_Converter::Result +ACE_UTF16_Encoding_Converter::to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool strict) +{ + static const ACE_UINT32 byteMask = 0xBF; + static const ACE_UINT32 byteMark = 0x80; + Result result = CONVERSION_OK; + + ACE_Byte* targetEnd = target + target_size; + const ACE_UINT16* sourceStart = static_cast (source); + const ACE_UINT16* sourceEnd = sourceStart + + (source_size / sizeof (ACE_UINT16)); + + while (sourceStart < sourceEnd) + { + ACE_UINT16 nw = *sourceStart++; + ACE_UINT32 ch = (this->swap_ ? ACE_SWAP_WORD (nw) : nw); + + // If we have a surrogate pair, convert to ACE_UINT32 first. + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) + { + // If the 16 bits following the high surrogate are in the + // sourceStart buffer... + if (sourceStart < sourceEnd) + { + ACE_UINT32 ch2 = (this->swap_ ? ACE_SWAP_WORD (*sourceStart) : + *sourceStart); + // If it's a low surrogate, convert to ACE_UINT32. + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) + { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + + (ch2 - UNI_SUR_LOW_START) + halfBase; + ++sourceStart; + } + else if (strict) + { + // it's an unpaired high surrogate + result = SOURCE_ILLEGAL; + break; + } + } + else + { + // We don't have the 16 bits following the high surrogate. + result = SOURCE_EXHAUSTED; + break; + } + } + else if (strict) + { + // UTF-16 surrogate values are illegal in UTF-32 + if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) + { + result = SOURCE_ILLEGAL; + break; + } + } + + // Figure out how many bytes the result will require + unsigned short bytesToWrite = 0; + if (ch < 0x80) + bytesToWrite = 1; + else if (ch < 0x800) + bytesToWrite = 2; + else if (ch < 0x10000) + bytesToWrite = 3; + else if (ch < 0x110000) + bytesToWrite = 4; + else + { + bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + } + + target += bytesToWrite; + if (target > targetEnd) + { + result = TARGET_EXHAUSTED; + break; + } + + // NOTE: Everything falls through for efficiency purposes. + switch (bytesToWrite) + { + case 4: + *--target = (ACE_Byte)((ch | byteMark) & byteMask); + ch >>= 6; + case 3: + *--target = (ACE_Byte)((ch | byteMark) & byteMask); + ch >>= 6; + case 2: + *--target = (ACE_Byte)((ch | byteMark) & byteMask); + ch >>= 6; + case 1: + *--target = (ACE_Byte)(ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + + return result; +} + +ACE_UTF16_Encoding_Converter::Result +ACE_UTF16_Encoding_Converter::from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict) +{ + Result result = CONVERSION_OK; + const ACE_Byte* sourceEnd = source + source_size; + ACE_UINT16* targetStart = static_cast (target); + ACE_UINT16* targetEnd = targetStart + target_size; + + while (source < sourceEnd) + { + ACE_UINT32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) + { + result = SOURCE_EXHAUSTED; + break; + } + + // Do this check whether lenient or strict + if (!this->is_legal_utf8 (source, extraBytesToRead + 1)) + { + result = SOURCE_ILLEGAL; + break; + } + + // The cases all fall through. See "Note A" below. + switch (extraBytesToRead) + { + case 5: // remember, illegal UTF-8 + ch += *source++; + ch <<= 6; + case 4: // remember, illegal UTF-8 + ch += *source++; + ch <<= 6; + case 3: + ch += *source++; + ch <<= 6; + case 2: + ch += *source++; + ch <<= 6; + case 1: + ch += *source++; + ch <<= 6; + case 0: + ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (targetStart >= targetEnd) + { + result = TARGET_EXHAUSTED; + break; + } + + if (ch <= UNI_MAX_BMP) // Target is a character <= 0xFFFF + { + // UTF-16 surrogate values are illegal in UTF-32 + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) + { + if (strict) + { + result = SOURCE_ILLEGAL; + break; + } + else + { + *targetStart++ = UNI_REPLACEMENT_CHAR; + } + } + else + { + *targetStart++ = (ACE_UINT16)ch; + } + } + else if (ch > UNI_MAX_UTF16) + { + if (strict) + { + result = SOURCE_ILLEGAL; + break; + } + else + { + *targetStart++ = UNI_REPLACEMENT_CHAR; + } + } + else + { + // targetStart is a character in range 0xFFFF - 0x10FFFF. + if (targetStart + 1 >= targetEnd) + { + result = TARGET_EXHAUSTED; + break; + } + ch -= halfBase; + *targetStart++ = (ACE_UINT16)((ch >> halfShift) + UNI_SUR_HIGH_START); + *targetStart++ = (ACE_UINT16)((ch & halfMask) + UNI_SUR_LOW_START); + } + } + + return result; +} + +ACE_UTF16_Encoding_Converter* +ACE_UTF16_Encoding_Converter::encoded (const ACE_Byte* source, + size_t source_size) +{ + static const size_t begin = 16; + static const size_t converted = begin * 4; + + ACE_Byte target[converted]; + ACE_UTF16_Encoding_Converter* converter; + ACE_NEW_RETURN (converter, + ACE_UTF16_Encoding_Converter (false), + 0); + if (converter->to_utf8 (source, + ACE_MIN (begin, source_size), + target, + converted) == CONVERSION_OK) + { + return converter; + } + else + { + delete converter; + } + + return 0; +} + +ACE_UINT32 +ACE_UTF16_Encoding_Converter::get_UNI_SUR_HIGH_START (void) +{ + return UNI_SUR_HIGH_START; +} + +ACE_UINT32 +ACE_UTF16_Encoding_Converter::get_UNI_SUR_LOW_END (void) +{ + return UNI_SUR_LOW_END; +} + +ACE_UINT32 +ACE_UTF16_Encoding_Converter::get_UNI_REPLACEMENT_CHAR (void) +{ + return UNI_REPLACEMENT_CHAR; +} + +const ACE_Byte* +ACE_UTF16_Encoding_Converter::get_first_byte_mark (void) +{ + return firstByteMark; +} + +const ACE_Byte* +ACE_UTF16_Encoding_Converter::get_trailing_bytes_for_utf8 (void) +{ + return trailingBytesForUTF8; +} + +const ACE_UINT32* +ACE_UTF16_Encoding_Converter::get_offsets_from_utf8 (void) +{ + return offsetsFromUTF8; +} + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ diff --git a/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.h b/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.h new file mode 100644 index 000000000..9bdcb21a0 --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.h @@ -0,0 +1,86 @@ +// -*- C++ -*- + +//========================================================================= +/** + * @file UTF16_Encoding_Converter.h + * + * $Id: UTF16_Encoding_Converter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * This class contains declarations for methods that convert between + * UTF-16 (both BE and LE) and UTF-8 + * + * @author Chad Elliott + */ +//========================================================================= + +#ifndef ACE_UTF16_ENCODING_CONVERTER_H +#define ACE_UTF16_ENCODING_CONVERTER_H + +#include /**/ "ace/pre.h" + +#include "ace/Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** Convert from UTF-16 to UTF-8 and from UTF-8 to UTF-16. + * This class implements the ACE_Encoding_Converter interface. + */ +class ACE_UTF16_Encoding_Converter: public ACE_Encoding_Converter +{ +public: + /// The swap parameter determines whether we need to swap byte order on + /// the stream as each word is pulled off when converting to UTF-8. + ACE_UTF16_Encoding_Converter (bool swap = false); + + /// This is a do nothing destructor. + virtual ~ACE_UTF16_Encoding_Converter (void); + + /// Convert the source from UTF-16 to UTF-8 and store it in the + /// provided target buffer. + virtual Result to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool strict = true); + + /// Convert the UTF-8 source into a UTF-16 encoding and store it + /// in the provided target buffer. + virtual Result from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict = true); + + /// This factory helper method determines if the source stream is UTF-16 + /// encoded. If it is, allocate an ACE_UTF16_Encoding_Converter and + /// return it. The caller then owns the allocated object. + static ACE_UTF16_Encoding_Converter* encoded (const ACE_Byte* source, + size_t source_size); + +protected: + /// Determines if the source buffer is legal UTF-8 + bool is_legal_utf8 (const ACE_Byte* source, + size_t length) const; + + static ACE_UINT32 get_UNI_SUR_HIGH_START (void); + static ACE_UINT32 get_UNI_SUR_LOW_END (void); + static ACE_UINT32 get_UNI_REPLACEMENT_CHAR (void); + static const ACE_Byte* get_first_byte_mark (void); + static const ACE_Byte* get_trailing_bytes_for_utf8 (void); + static const ACE_UINT32* get_offsets_from_utf8 (void); + + bool swap_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/UTF16_Encoding_Converter.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_USES_WCHAR */ + +#include /**/ "ace/post.h" + +#endif /* ACE_UTF16_ENCODING_CONVERTER_H */ diff --git a/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.inl b/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.inl new file mode 100644 index 000000000..e52927578 --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF16_Encoding_Converter.inl @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// $Id: UTF16_Encoding_Converter.inl 80826 2008-03-04 14:51:23Z wotte $ + +// ====================================================================== +// +// The actual conversion methods are covered by the copyright information +// below. +// Chad Elliott 4/28/2005 +// +// Copyright 2001-2004 Unicode, Inc. +// +// Limitations on Rights to Redistribute This Code +// +// Unicode, Inc. hereby grants the right to freely use the information +// supplied in this file in the creation of products supporting the +// Unicode Standard, and to make copies of this file in any form +// for internal or external distribution as long as this notice +// remains attached. +// +// ====================================================================== + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE bool +ACE_UTF16_Encoding_Converter::is_legal_utf8 (const ACE_Byte* source, + size_t length) const +{ + ACE_Byte a; + const ACE_Byte* srcptr = source + length; + + switch (length) + { + default: + return false; + + // Everything else falls through when "true"... + case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 2: if ((a = (*--srcptr)) > 0xBF) return false; + + switch (*source) + { + // no fall-through in this inner switch + case 0xE0: + if (a < 0xA0) + return false; + break; + case 0xED: + if (a > 0x9F) + return false; + break; + case 0xF0: + if (a < 0x90) + return false; + break; + case 0xF4: + if (a > 0x8F) + return false; + break; + default: + if (a < 0x80) + return false; + } + + case 1: + if (*source >= 0x80 && *source < 0xC2) + return false; + } + + if (*source > 0xF4) + return false; + + return true; +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/UTF32_Encoding_Converter.cpp b/dep/ACE_wrappers/ace/UTF32_Encoding_Converter.cpp new file mode 100644 index 000000000..459bf2530 --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF32_Encoding_Converter.cpp @@ -0,0 +1,254 @@ +// $Id: UTF32_Encoding_Converter.cpp 80826 2008-03-04 14:51:23Z wotte $ + +// ====================================================================== +// +// The actual conversion methods are covered by the copyright information +// below. It is not the actual code provided by Unicode, Inc. but is an +// ACE-ified and only slightly modified version. +// +// Chad Elliott 4/28/2005 +// +// Copyright 2001-2004 Unicode, Inc. +// +// Limitations on Rights to Redistribute This Code +// +// Unicode, Inc. hereby grants the right to freely use the information +// supplied in this file in the creation of products supporting the +// Unicode Standard, and to make copies of this file in any form +// for internal or external distribution as long as this notice +// remains attached. +// +// ====================================================================== + +#include "ace/UTF32_Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +#include "ace/OS_NS_stdio.h" +#include "ace/OS_Memory.h" +#include "ace/Min_Max.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +static const ACE_UINT32 UNI_MAX_LEGAL_UTF32 = 0x0010FFFF; + +ACE_UTF32_Encoding_Converter::ACE_UTF32_Encoding_Converter (bool swap) + : ACE_UTF16_Encoding_Converter (swap) +{ +} + +ACE_UTF32_Encoding_Converter::~ACE_UTF32_Encoding_Converter (void) +{ +} + +ACE_UTF32_Encoding_Converter::Result +ACE_UTF32_Encoding_Converter::to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool strict) +{ + static const ACE_UINT32 byteMask = 0xBF; + static const ACE_UINT32 byteMark = 0x80; + static const ACE_UINT32 UNI_SUR_HIGH_START = get_UNI_SUR_HIGH_START (); + static const ACE_UINT32 UNI_SUR_LOW_END = get_UNI_SUR_LOW_END (); + static const ACE_Byte* firstByteMark = get_first_byte_mark (); + + Result result = CONVERSION_OK; + ACE_Byte* targetEnd = target + target_size; + const ACE_UINT32* sourceStart = static_cast (source); + const ACE_UINT32* sourceEnd = sourceStart + (source_size / sizeof (ACE_UINT32)); + + while (sourceStart < sourceEnd) + { + ACE_UINT32 nw = *sourceStart++; + ACE_UINT32 ch = (this->swap_ ? ACE_SWAP_LONG (nw) : nw); + unsigned short bytesToWrite = 0; + + if (strict) + { + // UTF-16 surrogate values are illegal in UTF-32 + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) + { + result = SOURCE_ILLEGAL; + break; + } + } + + // Figure out how many bytes the result will require. Turn any + // illegally large ACE_UINT32 things (> Plane 17) into replacement + // chars. + if (ch < 0x80) + { + bytesToWrite = 1; + } + else if (ch < 0x800) + { + bytesToWrite = 2; + } + else if (ch < 0x10000) + { + bytesToWrite = 3; + } + else if (ch <= UNI_MAX_LEGAL_UTF32) + { + bytesToWrite = 4; + } + else + { + result = SOURCE_ILLEGAL; + break; + } + + target += bytesToWrite; + if (target > targetEnd) + { + result = TARGET_EXHAUSTED; + break; + } + + // NOTE: everything falls through. + switch (bytesToWrite) + { + case 4: + *--target = (ACE_Byte)((ch | byteMark) & byteMask); + ch >>= 6; + case 3: + *--target = (ACE_Byte)((ch | byteMark) & byteMask); + ch >>= 6; + case 2: + *--target = (ACE_Byte)((ch | byteMark) & byteMask); + ch >>= 6; + case 1: + *--target = (ACE_Byte) (ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + + return result; +} + +ACE_UTF32_Encoding_Converter::Result +ACE_UTF32_Encoding_Converter::from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict) +{ + static const ACE_UINT32 UNI_SUR_HIGH_START = get_UNI_SUR_HIGH_START (); + static const ACE_UINT32 UNI_SUR_LOW_END = get_UNI_SUR_LOW_END (); + static const ACE_UINT32 UNI_REPLACEMENT_CHAR = get_UNI_REPLACEMENT_CHAR (); + static const ACE_Byte* trailingBytesForUTF8 = get_trailing_bytes_for_utf8 (); + static const ACE_UINT32* offsetsFromUTF8 = get_offsets_from_utf8 (); + + Result result = CONVERSION_OK; + const ACE_Byte* sourceEnd = source + source_size; + ACE_UINT32* targetStart = static_cast (target); + ACE_UINT32* targetEnd = targetStart + target_size; + + while (source < sourceEnd) + { + ACE_UINT32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) + { + result = SOURCE_EXHAUSTED; + break; + } + + // Do this check whether lenient or strict + if (!this->is_legal_utf8 (source, extraBytesToRead + 1)) + { + result = SOURCE_ILLEGAL; + break; + } + + // The cases all fall through. See "Note A" below. + switch (extraBytesToRead) + { + case 5: + ch += *source++; + ch <<= 6; + case 4: + ch += *source++; + ch <<= 6; + case 3: + ch += *source++; + ch <<= 6; + case 2: + ch += *source++; + ch <<= 6; + case 1: + ch += *source++; + ch <<= 6; + case 0: + ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (targetStart >= targetEnd) + { + result = TARGET_EXHAUSTED; + break; + } + + if (ch <= UNI_MAX_LEGAL_UTF32) + { + // UTF-16 surrogate values are illegal in UTF-32, and anything + // over Plane 17 (> 0x10FFFF) is illegal. + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) + { + if (strict) + { + result = SOURCE_ILLEGAL; + break; + } + else + { + *targetStart++ = UNI_REPLACEMENT_CHAR; + } + } + else + { + *targetStart++ = ch; + } + } + else + { + result = SOURCE_ILLEGAL; + break; + } + } + + return result; +} + +ACE_UTF32_Encoding_Converter* +ACE_UTF32_Encoding_Converter::encoded (const ACE_Byte* source, + size_t source_size) +{ + static const size_t begin = 16; + static const size_t converted = begin * 4; + + ACE_Byte target[converted]; + ACE_UTF32_Encoding_Converter* converter = 0; + ACE_NEW_RETURN (converter, + ACE_UTF32_Encoding_Converter (false), + 0); + + if (converter->to_utf8 (source, + ACE_MIN (begin, source_size), + target, + converted) == CONVERSION_OK) + { + return converter; + } + else + { + delete converter; + } + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ diff --git a/dep/ACE_wrappers/ace/UTF32_Encoding_Converter.h b/dep/ACE_wrappers/ace/UTF32_Encoding_Converter.h new file mode 100644 index 000000000..214edeeee --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF32_Encoding_Converter.h @@ -0,0 +1,67 @@ +// -*- C++ -*- + +//========================================================================= +/** + * @file UTF32_Encoding_Converter.h + * + * $Id: UTF32_Encoding_Converter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * This class contains declarations for methods that convert between + * UTF-32 (both BE and LE) and UTF-8 + * + * @author Chad Elliott + */ +//========================================================================= + +#ifndef ACE_UTF32_ENCODING_CONVERTER_H +#define ACE_UTF32_ENCODING_CONVERTER_H + +#include /**/ "ace/pre.h" + +#include "ace/UTF16_Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** Convert from UTF-32 to UTF-8 and from UTF-8 to UTF-32. + * This class implements the ACE_Encoding_Converter interface. + */ +class ACE_UTF32_Encoding_Converter: public ACE_UTF16_Encoding_Converter +{ +public: + /// This class has some similarities to the UTF16 converter, so + /// we just construct our base class and pass the swap parameter. + ACE_UTF32_Encoding_Converter (bool swap = false); + + /// This is a do nothing destructor. + virtual ~ACE_UTF32_Encoding_Converter (void); + + /// Convert the source from UTF-32 to UTF-8 and store it in the + /// provided target buffer. + virtual Result to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool strict = true); + + /// Convert the UTF-8 source into a UTF-32 encoding and store it + /// in the provided target buffer. + virtual Result from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict = true); + + /// This factory helper method determines if the source stream is UTF-32 + /// encoded. If it is, allocate an ACE_UTF32_Encoding_Converter and + /// return it. The caller then owns the allocated object. + static ACE_UTF32_Encoding_Converter* encoded (const ACE_Byte* source, + size_t source_size); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ + +#include /**/ "ace/post.h" + +#endif /* ACE_UTF32_ENCODING_CONVERTER_H */ diff --git a/dep/ACE_wrappers/ace/UTF8_Encoding_Converter.cpp b/dep/ACE_wrappers/ace/UTF8_Encoding_Converter.cpp new file mode 100644 index 000000000..cd6c409d0 --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF8_Encoding_Converter.cpp @@ -0,0 +1,92 @@ +// $Id: UTF8_Encoding_Converter.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/UTF8_Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +#include "ace/UTF16_Encoding_Converter.h" +#include "ace/UTF32_Encoding_Converter.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_Memory.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_UTF8_Encoding_Converter::ACE_UTF8_Encoding_Converter (void) + : native_ (0) +{ + // Choose a converter for the ASCII or UTF-8 string to a wide character + // string which we will use in from_utf8. We have to make an + // assumption here about the encoding based on the size of ACE_TCHAR. + switch (sizeof (ACE_TCHAR)) + { + case 4: + ACE_NEW(this->native_, ACE_UTF32_Encoding_Converter); + break; + case 2: + ACE_NEW(this->native_, ACE_UTF16_Encoding_Converter); + break; + } +} + +ACE_UTF8_Encoding_Converter::~ACE_UTF8_Encoding_Converter (void) +{ + delete native_; +} + +ACE_UTF8_Encoding_Converter::Result +ACE_UTF8_Encoding_Converter::to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool /*strict*/) +{ + if (target_size >= source_size) + { + ACE_OS::memcpy (target, source, source_size); + return CONVERSION_OK; + } + + return TARGET_EXHAUSTED; +} + +ACE_UTF8_Encoding_Converter::Result +ACE_UTF8_Encoding_Converter::from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict) +{ + if (this->native_ != 0) + { + return this->native_->from_utf8(source, source_size, + target, target_size, strict); + } + + ACE_TCHAR* targetStart = static_cast (target); + ACE_OS::strncpy (targetStart, + ACE_TEXT_CHAR_TO_TCHAR ( + reinterpret_cast (source)), + source_size); + targetStart[source_size] = 0; + return CONVERSION_OK; +} + +ACE_UTF8_Encoding_Converter* +ACE_UTF8_Encoding_Converter::encoded (const ACE_Byte* source, + size_t source_size) +{ + for(size_t i = 0; i < source_size; i++) + { + if (source[i] < 0x01 || source[i] > 0x7f) + return 0; + } + + // All characters are "valid" ASCII + ACE_UTF8_Encoding_Converter* converter = 0; + ACE_NEW_RETURN (converter, + ACE_UTF8_Encoding_Converter, + 0); + return converter; +} + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ diff --git a/dep/ACE_wrappers/ace/UTF8_Encoding_Converter.h b/dep/ACE_wrappers/ace/UTF8_Encoding_Converter.h new file mode 100644 index 000000000..2cb6ed4e4 --- /dev/null +++ b/dep/ACE_wrappers/ace/UTF8_Encoding_Converter.h @@ -0,0 +1,72 @@ +// -*- C++ -*- + +//========================================================================= +/** + * @file UTF8_Encoding_Converter.h + * + * $Id: UTF8_Encoding_Converter.h 80826 2008-03-04 14:51:23Z wotte $ + * + * This class contains declarations for methods that convert between + * UTF-8 and the native ACE_TCHAR representation. + * + * @author Chad Elliott + */ +//========================================================================= + +#ifndef ACE_UTF8_ENCODING_CONVERTER_H +#define ACE_UTF8_ENCODING_CONVERTER_H + +#include /**/ "ace/pre.h" + +#include "ace/Encoding_Converter.h" + +#if defined (ACE_USES_WCHAR) +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** Convert from UTF-16 or UTF-32 to UTF-8. + * This class implements the ACE_Encoding_Converter interface. + */ +class ACE_UTF8_Encoding_Converter: public ACE_Encoding_Converter +{ +public: + /// Allocate the converter to be used by the from_utf8() method based + /// on the size of the native wide character. + ACE_UTF8_Encoding_Converter (void); + + /// De-allocate the native converter. + virtual ~ACE_UTF8_Encoding_Converter (void); + + /// Since the source *must be* UTF-8, there is no conversion required. + /// This method just copies the source to the target given that there + /// is enough space. + virtual Result to_utf8 (const void* source, + size_t source_size, + ACE_Byte* target, + size_t target_size, + bool strict = true); + + /// Utilize the native converter to convert the UTF-8 source into an + /// alternate encoding and store it in the provided target buffer. + virtual Result from_utf8 (const ACE_Byte* source, + size_t source_size, + void* target, + size_t target_size, + bool strict = true); + + + /// This factory helper method determines if the source stream is UTF-8 + /// encoded. If it is, allocate an ACE_UTF8_Encoding_Converter and + /// return it. The caller then owns the allocated object. + static ACE_UTF8_Encoding_Converter* encoded (const ACE_Byte* source, + size_t source_size); + +private: + ACE_Encoding_Converter* native_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL +#endif /* ACE_USES_WCHAR */ + +#include /**/ "ace/post.h" + +#endif /* ACE_UTF8_ENCODING_CONVERTER_H */ diff --git a/dep/ACE_wrappers/ace/UUID.cpp b/dep/ACE_wrappers/ace/UUID.cpp new file mode 100644 index 000000000..4ce2bcd0a --- /dev/null +++ b/dep/ACE_wrappers/ace/UUID.cpp @@ -0,0 +1,554 @@ +//$Id: UUID.cpp 81541 2008-04-30 13:56:12Z shuston $ + +#include "ace/UUID.h" +#include "ace/Guard_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/UUID.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/OS_NS_netdb.h" +#include "ace/OS_NS_unistd.h" +#include "ace/ACE.h" + +ACE_RCSID (ace, + UUID, + "$Id: UUID.cpp 81541 2008-04-30 13:56:12Z shuston $") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE_Utils +{ + UUID_Node::UUID_Node (void) + { + for (int i = 0; i < UUID_Node::NODE_ID_SIZE; ++i) + node_ID_[i] = 0; + } + + UUID_Node::Node_ID& + UUID_Node::node_ID (void) + { + return node_ID_; + } + + void + UUID_Node::node_ID (Node_ID& node_ID) + { + for (int i = 0; i < UUID_Node::NODE_ID_SIZE; ++i) + node_ID_[i] = node_ID[i]; + } + + UUID UUID::NIL_UUID; + + /// Construct a nil UUID. Such a UUID has every one of it's data + /// elements set to zero. + UUID::UUID (void) + : time_low_ (0), + time_mid_ (0), + time_hi_and_version_ (0), + clock_seq_hi_and_reserved_ (0), + clock_seq_low_ (0), + node_ (0), + node_release_ (true), + as_string_ (0) + { + ACE_NEW (node_, + UUID_Node); + } + + /// Construct a UUID from a string representation of an UUID. + UUID::UUID (const ACE_CString& uuid_string) + : time_low_ (0), + time_mid_ (0), + time_hi_and_version_ (0), + clock_seq_hi_and_reserved_ (0), + clock_seq_low_ (0), + node_ (0), + node_release_ (true), + as_string_ (0) + { + ACE_NEW (node_, + UUID_Node); + + this->from_string_i (uuid_string); + } + + UUID::UUID (const UUID &right) + : time_low_ (right.time_low_), + time_mid_ (right.time_mid_), + time_hi_and_version_ (right.time_hi_and_version_), + clock_seq_hi_and_reserved_ (right.clock_seq_hi_and_reserved_), + clock_seq_low_ (right.clock_seq_low_), + as_string_ (0) + { + ACE_NEW (node_, + UUID_Node (*right.node_)); + } + + UUID::~UUID (void) + { + if (node_release_) + delete node_; + + if (as_string_ != 0) + delete as_string_; + } + + const ACE_CString* + UUID::to_string (void) + { + /// Only compute the string representation once. + if (as_string_ == 0) + { + // Get a buffer exactly the correct size. Use the nil UUID as a + // gauge. Don't forget the trailing nul. + size_t UUID_STRING_LENGTH = 36 + thr_id_.length () + pid_.length (); + char *buf = 0; + + if ((thr_id_.length () != 0) && (pid_.length () != 0)) + { + UUID_STRING_LENGTH += 2; //for '-' + ACE_NEW_RETURN (buf, + char[UUID_STRING_LENGTH + 1], + 0); + + ACE_OS::sprintf (buf, + "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x-%s-%s", + this->time_low_, + this->time_mid_, + this->time_hi_and_version_, + this->clock_seq_hi_and_reserved_, + this->clock_seq_low_, + (this->node_->node_ID ()) [0], + (this->node_->node_ID ()) [1], + (this->node_->node_ID ()) [2], + (this->node_->node_ID ()) [3], + (this->node_->node_ID ()) [4], + (this->node_->node_ID ()) [5], + thr_id_.c_str (), + pid_.c_str () + ); + } + else + { + ACE_NEW_RETURN (buf, + char[UUID_STRING_LENGTH + 1], + 0); + + ACE_OS::sprintf (buf, + "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", + this->time_low_, + this->time_mid_, + this->time_hi_and_version_, + this->clock_seq_hi_and_reserved_, + this->clock_seq_low_, + (this->node_->node_ID ()) [0], + (this->node_->node_ID ()) [1], + (this->node_->node_ID ()) [2], + (this->node_->node_ID ()) [3], + (this->node_->node_ID ()) [4], + (this->node_->node_ID ()) [5] + ); + } + + // We allocated 'buf' above dynamically, so we shouldn't use + // ACE_NEW_RETURN here to avoid a possible memory leak. + ACE_NEW_NORETURN (this->as_string_, + ACE_CString (buf, UUID_STRING_LENGTH)); + + // we first free the dynamically allocated 'buf'. + delete [] buf; + + // then we test that ACE_NEW succeded for 'as_string_' + // if not, we return 0 (NULL) to indicate failure. + if (this->as_string_ == 0 ) + return 0; + } + + return as_string_; + } + + void + UUID::from_string_i (const ACE_CString& uuid_string) + { + if (uuid_string.length () < NIL_UUID.to_string ()->length ()) + { + ACE_ERROR ((LM_ERROR, + "%N ACE_UUID::from_string_i - " + "IllegalArgument (incorrect string length)\n")); + return; + } + + /// Special case for the nil UUID. + if (uuid_string == *NIL_UUID.to_string ()) + { + bool copy_constructor_not_supported = false; + ACE_ASSERT (copy_constructor_not_supported); + //*this = NIL_UUID; + ACE_UNUSED_ARG (copy_constructor_not_supported); + return; + } + + unsigned int time_low; + unsigned int time_mid; + unsigned int time_hi_and_version; + unsigned int clock_seq_hi_and_reserved; + unsigned int clock_seq_low; + unsigned int node [UUID_Node::NODE_ID_SIZE]; + char thr_pid_buf [BUFSIZ]; + + if (uuid_string.length () == NIL_UUID.to_string ()->length ()) + { + // This might seem quite strange this being in ACE, but it + // seems to be a bit difficult to write a facade for ::sscanf + // because some compilers dont support vsscanf, including + // MSVC. It appears that most platforms support sscanf though + // so we need to use it directly. + const int nScanned = +#if defined (ACE_HAS_TR24731_2005_CRT) + sscanf_s ( +#else + ::sscanf ( +#endif /* ACE_HAS_TR24731_2005_CRT */ + uuid_string.c_str (), + "%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x", + &time_low, + &time_mid, + &time_hi_and_version, + &clock_seq_hi_and_reserved, + &clock_seq_low, + &node[0], + &node[1], + &node[2], + &node[3], + &node[4], + &node[5] + ); + + if (nScanned != 11) + { + ACE_DEBUG ((LM_DEBUG, + "UUID::from_string_i - " + "IllegalArgument (invalid string representation)\n")); + return; + } + } + else + { + const int nScanned = +#if defined (ACE_HAS_TR24731_2005_CRT) + sscanf_s (uuid_string.c_str (), + "%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x-%s", + &time_low, + &time_mid, + &time_hi_and_version, + &clock_seq_hi_and_reserved, + &clock_seq_low, + &node[0], + &node[1], + &node[2], + &node[3], + &node[4], + &node[5], + thr_pid_buf, + BUFSIZ + ); +#else + ::sscanf (uuid_string.c_str (), + "%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x-%s", + &time_low, + &time_mid, + &time_hi_and_version, + &clock_seq_hi_and_reserved, + &clock_seq_low, + &node[0], + &node[1], + &node[2], + &node[3], + &node[4], + &node[5], + thr_pid_buf + ); +#endif /* ACE_HAS_TR24731_2005_CRT */ + + if (nScanned != 12) + { + ACE_DEBUG ((LM_DEBUG, + "ACE_UUID::from_string_i - " + "IllegalArgument (invalid string representation)\n")); + return; + } + } + + this->time_low_ = static_cast (time_low); + this->time_mid_ = static_cast (time_mid); + this->time_hi_and_version_ = static_cast (time_hi_and_version); + this->clock_seq_hi_and_reserved_ = static_cast (clock_seq_hi_and_reserved); + this->clock_seq_low_ = static_cast (clock_seq_low); + + UUID_Node::Node_ID node_id; + for (int i = 0; i < UUID_Node::NODE_ID_SIZE; ++i) + node_id [i] = static_cast (node[i]); + + this->node_->node_ID (node_id); + + // Support varient 10- only + if ((this->clock_seq_hi_and_reserved_ & 0xc0) != 0x80 && (this->clock_seq_hi_and_reserved_ & 0xc0) != 0xc0) + { + ACE_DEBUG ((LM_DEBUG, + "ACE_UUID::from_string_i - " + "IllegalArgument (unsupported variant)\n")); + return; + } + + /// Support versions 1, 3, and 4 only + ACE_UINT16 V1 = this->time_hi_and_version_; + + if ((V1 & 0xF000) != 0x1000 && + (V1 & 0xF000) != 0x3000 && + (V1 & 0xF000) != 0x4000) + { + ACE_DEBUG ((LM_DEBUG, + "ACE_UUID::from_string_i - " + "IllegalArgument (unsupported version)\n")); + return; + } + + if ((this->clock_seq_hi_and_reserved_ & 0xc0) == 0xc0) + { + if (uuid_string.length () == NIL_UUID.to_string ()->length ()) + { + ACE_DEBUG ((LM_DEBUG, + "ACE_UUID::from_string_i - " + "IllegalArgument (Missing Thread and Process Id)\n")); + return; + } + ACE_CString thr_pid_str (thr_pid_buf); + ssize_t pos = static_cast (thr_pid_str.find ('-')); + if (pos == -1) + ACE_DEBUG ((LM_DEBUG, + "ACE_UUID::from_string_i - " + "IllegalArgument (Thread and Process Id format incorrect)\n")); + + this->thr_id_ = thr_pid_str.substr (0, pos); + this->pid_ = thr_pid_str.substr (pos+1, thr_pid_str.length ()-pos-1); + } + } + + UUID_Generator::UUID_Generator () + : time_last_ (0), + destroy_lock_ (true) + { + ACE_NEW (lock_, + ACE_SYNCH_MUTEX); + } + + UUID_Generator::~UUID_Generator () + { + if (destroy_lock_) + delete lock_; + } + + void + UUID_Generator::init (void) + { + ACE_OS::macaddr_node_t macaddress; + int result = ACE_OS::getmacaddress (&macaddress); + + UUID_Node::Node_ID node_id; + if (result != -1) + { +// ACE_DEBUG ((LM_DEBUG, +// "%02X-%02X-%02X-%02X-%02X-%02X\n", +// macaddress.node [0], +// macaddress.node [1], +// macaddress.node [2], +// macaddress.node [3], +// macaddress.node [4], +// macaddress.node [5])); + + ACE_OS::memcpy (&node_id, + macaddress.node, + sizeof (node_id)); + } + else + { + node_id [0] = static_cast (ACE_OS::rand ()); + node_id [1] = static_cast (ACE_OS::rand ()); + node_id [2] = static_cast (ACE_OS::rand ()); + node_id [3] = static_cast (ACE_OS::rand ()); + node_id [4] = static_cast (ACE_OS::rand ()); + node_id [5] = static_cast (ACE_OS::rand ()); + } + + this->get_timestamp (time_last_); + + { + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, *lock_); + uuid_state_.timestamp = time_last_; + uuid_state_.node.node_ID (node_id); + } + } + + void + UUID_Generator::generate_UUID (UUID& uuid,ACE_UINT16 version, + u_char variant) + { + UUID_Time timestamp; + ACE_UINT16 clock_sequence; + + this->get_timestamp_and_clocksequence (timestamp, + clock_sequence); + + // Construct a Version 1 UUID with the information in the arguements. + uuid.time_low (static_cast (timestamp & 0xFFFFFFFF)); + uuid.time_mid (static_cast ((timestamp >> 32) & 0xFFFF)); + + ACE_UINT16 tHAV = static_cast ((timestamp >> 48) & 0xFFFF); + tHAV |= (version << 12); + uuid.time_hi_and_version (tHAV); + + u_char cseqHAV; + uuid.clock_seq_low (static_cast (clock_sequence & 0xFF)); + cseqHAV = static_cast ((clock_sequence & 0x3f00) >> 8); + uuid_state_.timestamp = timestamp; + + cseqHAV |= variant; + uuid.clock_seq_hi_and_reserved (cseqHAV); + uuid.node (& (uuid_state_.node)); + + if (variant == 0xc0) + { + ACE_Thread_ID thread_id; + char buf [BUFSIZ]; + thread_id.to_string (buf); + uuid.thr_id (buf); + + ACE_OS::sprintf (buf, + "%d", + static_cast (ACE_OS::getpid ())); + uuid.pid (buf); + } + } + + UUID* + UUID_Generator::generate_UUID (ACE_UINT16 version, u_char variant) + { + UUID* uuid; + ACE_NEW_RETURN (uuid, + UUID, + 0); + + this->generate_UUID (*uuid, version, variant); + return uuid; + } + + /// Obtain a new timestamp. If UUID's are being generated too quickly + /// the clock sequence will be incremented + void + UUID_Generator::get_timestamp (UUID_Time& timestamp) + { + ACE_GUARD (ACE_SYNCH_MUTEX, mon, *lock_); + + this->get_systemtime (timestamp); + + // Account for the clock being set back. Increment the clock / + // sequence. + if (timestamp <= time_last_) + { + uuid_state_.clock_sequence = static_cast + ((uuid_state_.clock_sequence + 1) & ACE_UUID_CLOCK_SEQ_MASK); + } + // If the system time ticked since the last UUID was + // generated. Set / the clock sequence back. + else if (timestamp > time_last_) + { + uuid_state_.clock_sequence = 0; + } + + time_last_ = timestamp; + } + + void + UUID_Generator::get_timestamp_and_clocksequence (UUID_Time& timestamp, + ACE_UINT16& clock_sequence) + { + ACE_GUARD (ACE_SYNCH_MUTEX, mon, *lock_); + + this->get_systemtime (timestamp); + + // Account for the clock being set back. Increment the clock / + // sequence. + if (timestamp <= time_last_) + uuid_state_.clock_sequence = static_cast ((uuid_state_.clock_sequence + 1) & ACE_UUID_CLOCK_SEQ_MASK); + + // If the system time ticked since the last UUID was + // generated. Set / the clock sequence back. + else if (timestamp > time_last_) + uuid_state_.clock_sequence = 0; + + time_last_ = timestamp; + clock_sequence = uuid_state_.clock_sequence; + } + + /** + * ACE_Time_Value is in POSIX time, seconds since Jan 1, 1970. UUIDs use + * time in 100ns ticks since 15 October 1582. The difference is: + * 15 Oct 1582 - 1 Jan 1600: 17 days in Oct, 30 in Nov, 31 in Dec + + * 17 years and 4 leap days (1584, 88, 92 and 96) + * 1 Jan 1600 - 1 Jan 1900: 3 centuries + 73 leap days ( 25 in 17th cent. + * and 24 each in 18th and 19th centuries) + * 1 Jan 1900 - 1 Jan 1970: 70 years + 17 leap days. + * This adds up, in days: (17+30+31+365*17+4)+ (365*300+73)+ (365*70+17) or + * 122192928000000000U (0x1B21DD213814000) 100 ns ticks. + */ + void + UUID_Generator::get_systemtime (UUID_Time & timestamp) + { + const UUID_Time timeOffset = +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + ACE_U_LongLong (ACE_INT64_LITERAL (0x1B21DD213814000)); +#elif defined (ACE_LACKS_LONGLONG_T) + ACE_U_LongLong (0x13814000u, 0x1B21DD2u); +#else + ACE_UINT64_LITERAL (0x1B21DD213814000); +#endif /* ACE_LACKS_UNSIGNEDLONGLONG_T */ + + /// Get the time of day, convert to 100ns ticks then add the offset. + ACE_Time_Value now = ACE_OS::gettimeofday (); + ACE_UINT64 time; + now.to_usec (time); + time = time * 10; + timestamp = time + timeOffset; +} + + ACE_SYNCH_MUTEX* + UUID_Generator::lock (void) + { + return this->lock_; + } + + void + UUID_Generator::lock (ACE_SYNCH_MUTEX* lock, + bool release_lock) + { + if (this->destroy_lock_) + delete this->lock_; + + this->lock_ = lock; + this->destroy_lock_ = release_lock; + } + +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton * + ACE_Singleton::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/UUID.h b/dep/ACE_wrappers/ace/UUID.h new file mode 100644 index 000000000..4f3c39d08 --- /dev/null +++ b/dep/ACE_wrappers/ace/UUID.h @@ -0,0 +1,239 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file UUID.h + * + * $Id: UUID.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Andrew T. Finnel + * @author Yamuna Krishnmaurthy + */ +//============================================================================= + +#ifndef ACE_UUID_H +#define ACE_UUID_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SString.h" +#include "ace/Singleton.h" +#include "ace/Synch_Traits.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE_Utils +{ + /// Class to hold a MAC address + class ACE_Export UUID_Node + { + public: + + /// Constructor + UUID_Node (void); + + enum {NODE_ID_SIZE = 6}; + typedef u_char Node_ID[NODE_ID_SIZE]; + + Node_ID &node_ID (void); + void node_ID (Node_ID&); + + ///// Equality Operations + bool operator == (const UUID_Node& right) const; + bool operator != (const UUID_Node& right) const; + + ///// Relational Operations + //bool operator < (const UUID_Node& right) const; + + private: + Node_ID node_ID_; + }; + + /** + * @class ACE_UUID + * + * ACE_UUID represents a Universally Unique IDentifier (UUID) as + * described in (the expired) INTERNET-DRAFT specification entitled + * UUIDs and GUIDs. All instances of UUID are of the time-based + * variety. That is, the version number part of the timeHiAndVersion + * field is 1. + * + * The default constructor creates a nil UUID. + * + * UUIDs have value semantics. In addition, they may be compared for + * ordering and equality. + * + * Additionally in this implementation provisions have been made to include + * process and thread ids to make the UUIDs more unique. The variant 0xc0 + * has been added to facilitate this. + */ + class ACE_Export UUID + { + public: + + /// Constructor + UUID (void); + + /// Constructs a UUID from a string representation. + UUID (const ACE_CString& uuidString); + + UUID (const UUID &right); + + // Destructor + ~UUID (void); + + ACE_UINT32 time_low (void) const; + void time_low (ACE_UINT32); + + ACE_UINT16 time_mid (void) const; + void time_mid (ACE_UINT16); + + ACE_UINT16 time_hi_and_version (void) const; + void time_hi_and_version (ACE_UINT16); + + u_char clock_seq_hi_and_reserved (void) const; + void clock_seq_hi_and_reserved (u_char); + + u_char clock_seq_low (void) const; + void clock_seq_low (u_char); + + UUID_Node* node (void) const; + void node (UUID_Node*); + + ACE_CString* thr_id (void); + void thr_id (char*); + + ACE_CString* pid (void); + void pid (char*); + + /// Returns a string representation of the UUID + const ACE_CString* to_string (void); + + /// Set the value using a string + void from_string (const ACE_CString& uuid_string); + + static UUID NIL_UUID; + + /// Equality Operations + bool operator== (const UUID &right) const; + bool operator!= (const UUID &right) const; + + /// Relational Operations + //bool operator< (const UUID &right) const; + //bool operator> (const UUID &right) const; + //bool operator<= (const UUID &right) const; + //bool operator>= (const UUID &right) const; + + private: + void from_string_i (const ACE_CString& uuid_string); + + UUID& operator= (const UUID&); + + /// Data Members for Class Attributes + ACE_UINT32 time_low_; + ACE_UINT16 time_mid_; + ACE_UINT16 time_hi_and_version_; + u_char clock_seq_hi_and_reserved_; + u_char clock_seq_low_; + UUID_Node* node_; + bool node_release_; + ACE_CString thr_id_; + ACE_CString pid_; + + /// The string representation of the UUID. This is created and + /// updated only on demand. + ACE_CString *as_string_; + }; + + /** + * @class ACE_UUID_Generator + * + * Singleton class that generates UUIDs. + * + */ + class ACE_Export UUID_Generator + { + public: + + enum {ACE_UUID_CLOCK_SEQ_MASK = 0x3FFF}; + + UUID_Generator(); + ~UUID_Generator(); + + void init (void); + + /// Format timestamp, clockseq, and nodeID into an UUID of the + /// specified version and variant. For generating UUID's with + /// thread and process ids use variant=0xc0 + void generate_UUID (UUID&, ACE_UINT16 version=0x0001, u_char variant=0x80); + + /// Format timestamp, clockseq, and nodeID into a VI UUID. For + /// generating UUID's with thread and process ids use variant=0xc0 + UUID* generate_UUID (ACE_UINT16 version=0x0001, u_char variant=0x80); + + /// Type to represent UTC as a count of 100 nanosecond intervals + /// since 00:00:00.00, 15 October 1582. + typedef ACE_UINT64 UUID_Time; + + /// The locking strategy prevents multiple generators from accessing + /// the UUID_state at the same time. Get the locking strategy. + ACE_SYNCH_MUTEX* lock (void); + + /// Set a new locking strategy and return the old one. + void lock (ACE_SYNCH_MUTEX* lock, + bool release_lock); + + private: + + /// The system time when that last uuid was generated. + UUID_Time time_last_; + + /// Type to contain the UUID generator persistent state. This will + /// be kept in memory mapped shared memory + struct UUID_State + { + UUID_Time timestamp; + UUID_Node node; + ACE_UINT16 clock_sequence; + }; + + /// Obtain a UUID timestamp. Compensate for the fact that the time + /// obtained from getSystem time has a resolution less than 100ns. + void get_timestamp (UUID_Time& timestamp); + + /// Obtain a UUID timestamp and clock sequence. Compensate for the + /// fact that the time obtained from getSystem time has a + /// resolution less than 100ns. + void get_timestamp_and_clocksequence (UUID_Time& timestamp, + ACE_UINT16& clockSequence); + + /// Obtain the system time in UTC as a count of 100 nanosecond intervals + /// since 00:00:00.00, 15 October 1582 (the date of Gregorian reform to + /// the Christian calendar). + void get_systemtime( UUID_Time& timeNow); + + /// The UUID generator persistent state. + UUID_State uuid_state_; + + ACE_SYNCH_MUTEX* lock_; + bool destroy_lock_; + }; + + typedef ACE_Singleton UUID_GENERATOR; + +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/UUID.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif // ACE_UUID_H + diff --git a/dep/ACE_wrappers/ace/UUID.inl b/dep/ACE_wrappers/ace/UUID.inl new file mode 100644 index 000000000..a60fb6ce1 --- /dev/null +++ b/dep/ACE_wrappers/ace/UUID.inl @@ -0,0 +1,200 @@ +// -*- C++ -*- +// +//$Id: UUID.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE_Utils +{ + + /// Data Members for Class Attributes + ACE_INLINE ACE_UINT32 + UUID::time_low (void) const + { + return this->time_low_; + } + + ACE_INLINE void + UUID::time_low (ACE_UINT32 timelow) + { + this->time_low_ = timelow; + } + + ACE_INLINE ACE_UINT16 + UUID::time_mid (void) const + { + return this->time_mid_; + } + + ACE_INLINE void + UUID::time_mid (ACE_UINT16 time_mid) + { + this->time_mid_ = time_mid; + } + + ACE_INLINE ACE_UINT16 + UUID::time_hi_and_version (void) const + { + return this->time_hi_and_version_; + } + + ACE_INLINE void + UUID::time_hi_and_version (ACE_UINT16 time_hi_and_version) + { + this->time_hi_and_version_ = time_hi_and_version; + } + + ACE_INLINE u_char + UUID::clock_seq_hi_and_reserved (void) const + { + return this->clock_seq_hi_and_reserved_; + } + + ACE_INLINE void + UUID::clock_seq_hi_and_reserved (u_char clock_seq_hi_and_reserved) + { + this->clock_seq_hi_and_reserved_ = clock_seq_hi_and_reserved; + } + + ACE_INLINE u_char + UUID::clock_seq_low (void) const + { + return this->clock_seq_low_; + } + + ACE_INLINE void + UUID::clock_seq_low (u_char clock_seq_low) + { + this->clock_seq_low_ = clock_seq_low; + } + + ACE_INLINE UUID_Node* + UUID::node (void) const + { + return this->node_; + } + + ACE_INLINE void + UUID::node (UUID_Node* node) + { + if (node_release_) + delete node_; + + this->node_ = node; + node_release_ = false; + } + + ACE_INLINE ACE_CString* + UUID::thr_id (void) + { + return &this->thr_id_; + } + + ACE_INLINE void + UUID::thr_id (char* thr_id) + { + this->thr_id_ = thr_id; + } + + ACE_INLINE ACE_CString* + UUID::pid (void) + { + return &this->pid_; + } + + ACE_INLINE void + UUID::pid (char* pid) + { + this->pid_ = pid; + } + + ACE_INLINE void + UUID::from_string (const ACE_CString& uuidString) + { + this->from_string_i (uuidString); + } + + ACE_INLINE bool + UUID::operator == (const UUID &right) const + { + if ((this->time_low_ != right.time_low ()) || + (this->time_mid_ != right.time_mid ()) || + (this->time_hi_and_version_ != right.time_hi_and_version ()) || + (this->clock_seq_hi_and_reserved_ != right.clock_seq_hi_and_reserved ()) || + (this->clock_seq_low_ != right.clock_seq_low ()) || + (*this->node_ != *right.node ())) + return false; + + return true; + } + + ACE_INLINE bool + UUID::operator != (const UUID &right) const + { + return !(*this == right); + } + +// ACE_INLINE bool +//UUID::operator < (const UUID &rt) const +// { +// UUID right (rt); +// if ((timeLow_ < right.timeLow ()) || +// (timeMid_ < right.timeMid ()) || +// (timeHiAndVersion_ < right.timeHiAndVersion ()) || +// (clockSeqHiAndReserved_ < right.clockSeqHiAndReserved ()) || +// (clockSeqLow_ < right.clockSeqLow ()) || +// (node_ < right.node ())) +// { +// return true; +// } +// +// return false; +// } +// +// ACE_INLINE bool +// UUID::operator > (const UUID &right) const +// { +// return right < *this; +// } +// +// ACE_INLINE bool +// UUID::operator <= (const UUID &right) const +// { +// return !(*this > right); +// } +// +// ACE_INLINE bool +// UUID::operator >= (const UUID &right) const +// { +// return !(*this < right); +// } +// + ACE_INLINE bool + UUID_Node::operator == (const UUID_Node& rt) const + { + for (size_t i = 0; i < NODE_ID_SIZE; ++i) + if (node_ID_ [i] != rt.node_ID_ [i]) + return false; + + return true; + } + + ACE_INLINE bool + UUID_Node::operator != (const UUID_Node& right) const + { + return !(*this == right); + } + +// ACE_INLINE bool +// UUID_node::operator < (const UUID_node& rt) const +// { +// UUID_node right = rt; +// for (size_t i = 0; i < NODE_ID_SIZE; ++i) +// if (nodeID_ [i] < right.nodeID ()[i]) +// return true; +// +// return false; +// } +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Unbounded_Queue.cpp b/dep/ACE_wrappers/ace/Unbounded_Queue.cpp new file mode 100644 index 000000000..aaaddc6a9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Queue.cpp @@ -0,0 +1,434 @@ +// $Id: Unbounded_Queue.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_UNBOUNDED_QUEUE_CPP +#define ACE_UNBOUNDED_QUEUE_CPP + +#include "ace/Unbounded_Queue.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Unbounded_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Malloc_Base.h" +#include "ace/Log_Msg.h" +#include "ace/os_include/os_errno.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Queue) + +template +ACE_Unbounded_Queue::ACE_Unbounded_Queue (ACE_Allocator *alloc) + : head_ (0), + cur_size_ (0), + allocator_ (alloc) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::ACE_Unbounded_Queue (void)"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (ACE_Node *) this->allocator_->malloc (sizeof (ACE_Node)), + ACE_Node); + // Make the list circular by pointing it back to itself. + this->head_->next_ = this->head_; +} + +template +ACE_Unbounded_Queue::ACE_Unbounded_Queue (const ACE_Unbounded_Queue &us) + : head_ (0), + cur_size_ (0), + allocator_ (us.allocator_) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::ACE_Unbounded_Queue"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (ACE_Node *) this->allocator_->malloc (sizeof (ACE_Node)), + ACE_Node); + this->head_->next_ = this->head_; + this->copy_nodes (us); +} + +template void +ACE_Unbounded_Queue::operator= (const ACE_Unbounded_Queue &us) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::operator="); + + if (this != &us) + { + this->delete_nodes (); + this->copy_nodes (us); + } +} + +template ACE_Unbounded_Queue_Iterator +ACE_Unbounded_Queue::begin (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::begin"); + return ACE_Unbounded_Queue_Iterator (*this); +} + +template ACE_Unbounded_Queue_Iterator +ACE_Unbounded_Queue::end (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::end"); + return ACE_Unbounded_Queue_Iterator (*this, 1); +} + +template void +ACE_Unbounded_Queue::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Queue::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhead_ = %u"), this->head_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhead_->next_ = %u"), this->head_->next_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d\n"), this->cur_size_)); + + T *item = 0; +#if !defined (ACE_NLOGGING) + size_t count = 1; +#endif /* ! ACE_NLOGGING */ + + for (ACE_Unbounded_Queue_Iterator iter (*(ACE_Unbounded_Queue *) this); + iter.next (item) != 0; + iter.advance ()) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("count = %d\n"), count++)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template void +ACE_Unbounded_Queue::copy_nodes (const ACE_Unbounded_Queue &us) +{ + for (ACE_Node *curr = us.head_->next_; + curr != us.head_; + curr = curr->next_) + if (this->enqueue_tail (curr->item_) == -1) + // @@ What's the right thing to do here? + this->delete_nodes (); +} + +template void +ACE_Unbounded_Queue::delete_nodes (void) +{ + for (ACE_Node *curr = this->head_->next_; + // Keep looking until we've hit the dummy node. + curr != this->head_; + ) + { + ACE_Node *temp = curr; + curr = curr->next_; + + ACE_DES_FREE_TEMPLATE (temp, + this->allocator_->free, + ACE_Node, + ); + --this->cur_size_; + // @@ Doesnt make sense to have this check since + // this will always be true. + // ACE_ASSERT (this->cur_size_ >= 0); + } + + // Reset the list to be a circular list with just a dummy node. + this->head_->next_ = this->head_; +} + +template +ACE_Unbounded_Queue::~ACE_Unbounded_Queue (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::~ACE_Unbounded_Queue (void)"); + + this->delete_nodes (); + ACE_DES_FREE_TEMPLATE (head_, + this->allocator_->free, + ACE_Node, + ); + this->head_ = 0; +} + +template int +ACE_Unbounded_Queue::enqueue_head (const T &new_item) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::enqueue_head"); + + ACE_Node *temp = 0; + + // Create a new node that points to the original head. + ACE_NEW_MALLOC_RETURN (temp, + static_cast *> (this->allocator_->malloc (sizeof (ACE_Node))), + ACE_Node (new_item, this->head_->next_), + -1); + // Link this pointer into the front of the list. Note that the + // "real" head of the queue is next_>, whereas is + // just a pointer to the dummy node. + this->head_->next_ = temp; + + ++this->cur_size_; + return 0; +} + +template int +ACE_Unbounded_Queue::enqueue_tail (const T &new_item) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::enqueue_tail"); + + // Insert into the old dummy node location. Note that this + // isn't actually the "head" item in the queue, it's a dummy node at + // the "tail" of the queue... + this->head_->item_ = new_item; + + ACE_Node *temp = 0; + + // Create a new dummy node. + ACE_NEW_MALLOC_RETURN (temp, + static_cast *> (this->allocator_->malloc (sizeof (ACE_Node))), + ACE_Node (this->head_->next_), + -1); + // Link this dummy pointer into the list. + this->head_->next_ = temp; + + // Point the head to the new dummy node. + this->head_ = temp; + + ++this->cur_size_; + return 0; +} + +template int +ACE_Unbounded_Queue::dequeue_head (T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::dequeue_head"); + + // Check for empty queue. + if (this->is_empty ()) + return -1; + + ACE_Node *temp = this->head_->next_; + + item = temp->item_; + this->head_->next_ = temp->next_; + ACE_DES_FREE_TEMPLATE (temp, + this->allocator_->free, + ACE_Node, + ); + --this->cur_size_; + return 0; +} + +template void +ACE_Unbounded_Queue::reset (void) +{ + ACE_TRACE ("reset"); + + this->delete_nodes (); +} + +template int +ACE_Unbounded_Queue::get (T *&item, size_t slot) const +{ + // ACE_TRACE ("ACE_Unbounded_Queue::get"); + + ACE_Node *curr = this->head_->next_; + + size_t i; + + for (i = 0; i < this->cur_size_; i++) + { + if (i == slot) + break; + + curr = curr->next_; + } + + if (i < this->cur_size_) + { + item = &curr->item_; + return 0; + } + else + return -1; +} + +template int +ACE_Unbounded_Queue::set (const T &item, + size_t slot) +{ + // ACE_TRACE ("ACE_Unbounded_Queue::set"); + + ACE_Node *curr = this->head_->next_; + + size_t i; + + for (i = 0; + i < slot && i < this->cur_size_; + ++i) + curr = curr->next_; + + if (i < this->cur_size_) + { + // We're in range, so everything's cool. + curr->item_ = item; + return 0; + } + else + { + // We need to expand the list. + + // A common case will be increasing the set size by 1. + // Therefore, we'll optimize for this case. + if (i == slot) + { + // Try to expand the size of the set by 1. + if (this->enqueue_tail (item) == -1) + return -1; + else + return 0; + } + else + { + T const dummy = T (); + + // We need to expand the list by multiple (dummy) items. + for (; i < slot; ++i) + { + // This head points to the existing dummy node, which is + // about to be overwritten when we add the new dummy + // node. + curr = this->head_; + + // Try to expand the size of the set by 1, but don't + // store anything in the dummy node (yet). + if (this->enqueue_tail (dummy) == -1) + return -1; + } + + curr->item_ = item; + return 0; + } + } +} + +// **************************************************************** + +template void +ACE_Unbounded_Queue_Const_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unbounded_Queue_Const_Iterator::ACE_Unbounded_Queue_Const_Iterator (const ACE_Unbounded_Queue &q, int end) + : current_ (end == 0 ? q.head_->next_ : q.head_ ), + queue_ (q) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator::ACE_Unbounded_Queue_Const_Iterator"); +} + +template int +ACE_Unbounded_Queue_Const_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator::advance"); + this->current_ = this->current_->next_; + return this->current_ != this->queue_.head_; +} + +template int +ACE_Unbounded_Queue_Const_Iterator::first (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator::first"); + this->current_ = this->queue_.head_->next_; + return this->current_ != this->queue_.head_; +} + +template int +ACE_Unbounded_Queue_Const_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator::done"); + + return this->current_ == this->queue_.head_; +} + +template int +ACE_Unbounded_Queue_Const_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Const_Iterator::next"); + if (this->current_ == this->queue_.head_) + return 0; + else + { + item = &this->current_->item_; + return 1; + } +} + +// **************************************************************** + +template void +ACE_Unbounded_Queue_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Queue_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unbounded_Queue_Iterator::ACE_Unbounded_Queue_Iterator (ACE_Unbounded_Queue &q, int end) + : current_ (end == 0 ? q.head_->next_ : q.head_ ), + queue_ (q) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Iterator::ACE_Unbounded_Queue_Iterator"); +} + +template int +ACE_Unbounded_Queue_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Iterator::advance"); + this->current_ = this->current_->next_; + return this->current_ != this->queue_.head_; +} + +template int +ACE_Unbounded_Queue_Iterator::first (void) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Iterator::first"); + this->current_ = this->queue_.head_->next_; + return this->current_ != this->queue_.head_; +} + +template int +ACE_Unbounded_Queue_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Unbounded_Queue_Iterator::done"); + + return this->current_ == this->queue_.head_; +} + +template int +ACE_Unbounded_Queue_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Unbounded_Queue_Iterator::next"); + if (this->current_ == this->queue_.head_) + return 0; + else + { + item = &this->current_->item_; + return 1; + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_UNBOUNDED_QUEUE_CPP */ diff --git a/dep/ACE_wrappers/ace/Unbounded_Queue.h b/dep/ACE_wrappers/ace/Unbounded_Queue.h new file mode 100644 index 000000000..b6e1c4eea --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Queue.h @@ -0,0 +1,297 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Unbounded_Queue.h + * + * $Id: Unbounded_Queue.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_UNBOUNDED_QUEUE_H +#define ACE_UNBOUNDED_QUEUE_H +#include /**/ "ace/pre.h" + +#include "ace/Node.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Allocator; + +template +class ACE_Unbounded_Queue; + +/** + * @class ACE_Unbounded_Queue_Iterator + * + * @brief Implement an iterator over an unbounded queue. + */ +template +class ACE_Unbounded_Queue_Iterator +{ +public: + // = Initialization method. + ACE_Unbounded_Queue_Iterator (ACE_Unbounded_Queue &q, int end = 0); + + // = Iteration methods. + + /// Pass back the @a next_item that hasn't been seen in the queue. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the queue have been seen, else 1. + int advance (void); + + /// Move to the first element in the queue. Returns 0 if the + /// queue is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the current node in the iteration. + ACE_Node *current_; + + /// Pointer to the queue we're iterating over. + ACE_Unbounded_Queue &queue_; +}; + +/** + * @class ACE_Unbounded_Queue_Const_Iterator + * + * @brief Implement an iterator over an const unbounded queue. + */ +template +class ACE_Unbounded_Queue_Const_Iterator +{ +public: + // = Initialization method. + ACE_Unbounded_Queue_Const_Iterator (const ACE_Unbounded_Queue &q, int end = 0); + + // = Iteration methods. + + /// Pass back the @a next_item that hasn't been seen in the queue. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the queue have been seen, else 1. + int advance (void); + + /// Move to the first element in the queue. Returns 0 if the + /// queue is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the current node in the iteration. + ACE_Node *current_; + + /// Pointer to the queue we're iterating over. + const ACE_Unbounded_Queue &queue_; +}; + +/** + * @class ACE_Unbounded_Queue + * + * @brief A Queue of "infinite" length. + * + * This implementation of an unbounded queue uses a circular + * linked list with a dummy node. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Circular linked list + * - Duplicates allowed? + * Yes + * - Random access allowed? + * No + * - Search speed + * N/A + * - Insert/replace speed + * N/A + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * Yes + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * + */ +template +class ACE_Unbounded_Queue +{ +public: + friend class ACE_Unbounded_Queue_Iterator; + friend class ACE_Unbounded_Queue_Const_Iterator; + + // Trait definition. + typedef ACE_Unbounded_Queue_Iterator ITERATOR; + typedef ACE_Unbounded_Queue_Const_Iterator CONST_ITERATOR; + + // = Initialization and termination methods. + /// Construction. Use user specified allocation strategy + /// if specified. + /** + * Initialize an empty queue using the strategy provided. + */ + ACE_Unbounded_Queue (ACE_Allocator *alloc = 0); + + /// Copy constructor. + /** + * Initialize the queue to be a copy of the provided queue. + */ + ACE_Unbounded_Queue (const ACE_Unbounded_Queue &); + + /// Assignment operator. + /** + * Perform a deep copy of rhs. + */ + void operator= (const ACE_Unbounded_Queue &); + + /// Destructor. + /** + * Clean up the memory for the queue. + */ + ~ACE_Unbounded_Queue (void); + + // = Check boundary conditions. + + /// Returns 1 if the container is empty, otherwise returns 0. + /** + * Constant time check to see if the queue is empty. + */ + int is_empty (void) const; + + /// Returns 0. + /** + * The queue cannot be full, so it always returns 0. + */ + int is_full (void) const; + + // = Classic queue operations. + + /// Adds @a new_item to the tail of the queue. Returns 0 on success, + /// -1 on failure. + /** + * Insert an item at the end of the queue. + */ + int enqueue_tail (const T &new_item); + + /// Adds @a new_item to the head of the queue. Returns 0 on success, + /// -1 on failure. + /** + * Insert an item at the head of the queue. + */ + int enqueue_head (const T &new_item); + + /// Removes and returns the first @a item on the queue. Returns 0 on + /// success, -1 if the queue was empty. + /** + * Remove an item from the head of the queue. + */ + int dequeue_head (T &item); + + // = Additional utility methods. + + /// Reset the ACE_Unbounded_Queue to be empty and release all its + /// dynamically allocated resources. + /** + * Delete the queue nodes. + */ + void reset (void); + + /// Get the @a slot th element in the set. Returns -1 if the element + /// isn't in the range {0..#cur_size_ - 1}, else 0. + /** + * Find the item in the queue between 0 and the provided index of the + * queue. + */ + int get (T *&item, size_t slot = 0) const; + + /// Set the @a slot th element of the queue to @a item. + /** + * Set the @a slot th element in the set. Will pad out the set with + * empty nodes if @a slot is beyond the range {0..#cur_size_ - 1}. + * Returns -1 on failure, 0 if @a slot isn't initially in range, and + * 0 otherwise. + */ + int set (const T &item, size_t slot); + + /// The number of items in the queue. + /** + * Return the size of the queue. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + // = STL-styled unidirectional iterator factory. + ACE_Unbounded_Queue_Iterator begin (void); + ACE_Unbounded_Queue_Iterator end (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Delete all the nodes in the queue. + void delete_nodes (void); + + /// Copy nodes into this queue. + void copy_nodes (const ACE_Unbounded_Queue &); + + /// Pointer to the dummy node in the circular linked Queue. + ACE_Node *head_; + + /// Current size of the queue. + size_t cur_size_; + + /// Allocation Strategy of the queue. + ACE_Allocator *allocator_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Unbounded_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Unbounded_Queue.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Unbounded_Queue.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_UNBOUNDED_QUEUE_H */ diff --git a/dep/ACE_wrappers/ace/Unbounded_Queue.inl b/dep/ACE_wrappers/ace/Unbounded_Queue.inl new file mode 100644 index 000000000..0758412b9 --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Queue.inl @@ -0,0 +1,27 @@ +// -*- C++ -*- +// +// $Id: Unbounded_Queue.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE size_t +ACE_Unbounded_Queue::size (void) const +{ + return this->cur_size_; +} + +template ACE_INLINE int +ACE_Unbounded_Queue::is_empty (void) const +{ + // ACE_TRACE ("ACE_Unbounded_Queue::is_empty"); + return this->head_ == this->head_->next_; +} + +template ACE_INLINE int +ACE_Unbounded_Queue::is_full (void) const +{ + // ACE_TRACE ("ACE_Unbounded_Queue::is_full"); + return 0; // We should implement a "node of last resort for this..." +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Unbounded_Set.cpp b/dep/ACE_wrappers/ace/Unbounded_Set.cpp new file mode 100644 index 000000000..c54e3fcfa --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Set.cpp @@ -0,0 +1,18 @@ +// $Id: Unbounded_Set.cpp 81624 2008-05-06 17:14:57Z wotte $ + +#ifndef ACE_UNBOUNDED_SET_CPP +#define ACE_UNBOUNDED_SET_CPP + +#include "ace/Unbounded_Set.h" +#include "ace/Malloc_Base.h" +#include "ace/Log_Msg.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Unbounded_Set.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_UNBOUNDED_SET_CPP */ diff --git a/dep/ACE_wrappers/ace/Unbounded_Set.h b/dep/ACE_wrappers/ace/Unbounded_Set.h new file mode 100644 index 000000000..a75eac18f --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Set.h @@ -0,0 +1,103 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Unbounded_Set.h + * + * $Id: Unbounded_Set.h 81642 2008-05-07 19:30:35Z shuston $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_UNBOUNDED_SET_H +#define ACE_UNBOUNDED_SET_H +#include /**/ "ace/pre.h" + +#include "ace/Unbounded_Set_Ex.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Allocator; + +/** + * @struct ACE_Unbounded_Set_Default_Comparator + * @brief Simple comparator that evaluates equality using == operator. + */ +template +struct ACE_Unbounded_Set_Default_Comparator +{ + bool operator() (const T&lhs, const T&rhs) const; +}; + +template +class ACE_Unbounded_Set; + +/** + * @class ACE_Unbounded_Set_Iterator + * @brief Compatibility wrapper for ACE_Unbounded_Set_Ex_Iterator. + */ +template +class ACE_Unbounded_Set_Iterator : public + ACE_Unbounded_Set_Ex_Iterator > +{ +public: + typedef ACE_Unbounded_Set_Ex_Iterator > base_type; + + // = Initialization method. + ACE_Unbounded_Set_Iterator (ACE_Unbounded_Set &s, bool end = false); + + ACE_Unbounded_Set_Iterator (const base_type &s); +}; + +/** + * @class ACE_Unbounded_Set_Const_Iterator + * @brief Compatibility wrapper for ACE_Unbounded_Set_Ex_Const_Iterator. + */ +template +class ACE_Unbounded_Set_Const_Iterator : public + ACE_Unbounded_Set_Ex_Const_Iterator > +{ +public: + + typedef ACE_Unbounded_Set_Ex_Const_Iterator > base_type; + + // = Initialization method. + ACE_Unbounded_Set_Const_Iterator (const ACE_Unbounded_Set &s, + bool end = false); + + ACE_Unbounded_Set_Const_Iterator (const base_type &s); +}; + +/** + * @class ACE_Unbounded_Set + * @brief Compatibility wrapper for ACE_Unbounded_Set_Ex. + */ +template +class ACE_Unbounded_Set : public + ACE_Unbounded_Set_Ex > +{ +public: + ACE_Unbounded_Set (ACE_Allocator *alloc = 0); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Unbounded_Set.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Unbounded_Set.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Unbounded_Set.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_UNBOUNDED_SET_H */ diff --git a/dep/ACE_wrappers/ace/Unbounded_Set.inl b/dep/ACE_wrappers/ace/Unbounded_Set.inl new file mode 100644 index 000000000..365b025c0 --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Set.inl @@ -0,0 +1,49 @@ +// -*- C++ -*- +// +// $Id: Unbounded_Set.inl 81642 2008-05-07 19:30:35Z shuston $ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE bool +ACE_Unbounded_Set_Default_Comparator::operator () (const T &lhs, const T &rhs) const +{ + return lhs == rhs; +} + +template +ACE_Unbounded_Set_Iterator::ACE_Unbounded_Set_Iterator (ACE_Unbounded_Set &s, + bool end) + : base_type (s, end) +{ +} + +template +ACE_Unbounded_Set_Iterator::ACE_Unbounded_Set_Iterator (const base_type & s) + : base_type (s) +{ +} + +template +ACE_Unbounded_Set_Const_Iterator:: +ACE_Unbounded_Set_Const_Iterator (const ACE_Unbounded_Set &s, + bool end) + : base_type (s, end) +{ +} + +template +ACE_Unbounded_Set_Const_Iterator::ACE_Unbounded_Set_Const_Iterator (const base_type & s) + : base_type (s) +{ +} + +template +ACE_Unbounded_Set::ACE_Unbounded_Set (ACE_Allocator *alloc) + : ACE_Unbounded_Set_Ex > (alloc) +{ +} + + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Unbounded_Set_Ex.cpp b/dep/ACE_wrappers/ace/Unbounded_Set_Ex.cpp new file mode 100644 index 000000000..c5cd9e27b --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Set_Ex.cpp @@ -0,0 +1,499 @@ +// $Id: Unbounded_Set_Ex.cpp 81702 2008-05-15 10:18:07Z johnnyw $ + +#ifndef ACE_UNBOUNDED_SET_EX_CPP +#define ACE_UNBOUNDED_SET_EX_CPP + +#include "ace/Unbounded_Set.h" +#include "ace/Malloc_Base.h" +#include "ace/Log_Msg.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (__ACE_INLINE__) +#include "ace/Unbounded_Set_Ex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Ex) + +template size_t +ACE_Unbounded_Set_Ex::size (void) const +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::size"); + return this->cur_size_; +} + +template int +ACE_Unbounded_Set_Ex::insert_tail (const T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::insert_tail"); + NODE *temp = 0; + + // Insert into the old dummy node location. + this->head_->item_ = item; + + // Create a new dummy node. + ACE_NEW_MALLOC_RETURN (temp, + static_cast (this->allocator_->malloc (sizeof (NODE))), + NODE (this->head_->next_), + -1); + // Link this pointer into the list. + this->head_->next_ = temp; + + // Point the head to the new dummy node. + this->head_ = temp; + + ++this->cur_size_; + return 0; +} + +template void +ACE_Unbounded_Set_Ex::reset (void) +{ + ACE_TRACE ("reset"); + + this->delete_nodes (); +} + +template void +ACE_Unbounded_Set_Ex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Unbounded_Set_Ex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhead_ = %u"), this->head_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhead_->next_ = %u"), this->head_->next_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncur_size_ = %d\n"), this->cur_size_)); + + T *item = 0; +#if !defined (ACE_NLOGGING) + size_t count = 1; +#endif /* ! ACE_NLOGGING */ + + const_iterator const the_end = this->end (); + for (const_iterator i (this->begin ()); + i != end; + ++i) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("count = %u\n"), count++)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template void +ACE_Unbounded_Set_Ex::copy_nodes (const ACE_Unbounded_Set_Ex &us) +{ + for (NODE *curr = us.head_->next_; + curr != us.head_; + curr = curr->next_) + this->insert_tail (curr->item_); +} + +template void +ACE_Unbounded_Set_Ex::delete_nodes (void) +{ + NODE *curr = this->head_->next_; + + // Keep looking until we've hit the dummy node. + + while (curr != this->head_) + { + NODE *temp = curr; + curr = curr->next_; + ACE_DES_FREE_TEMPLATE2 (temp, + this->allocator_->free, + ACE_Node, + T, C); + --this->cur_size_; + } + + // Reset the list to be a circular list with just a dummy node. + this->head_->next_ = this->head_; +} + +template +ACE_Unbounded_Set_Ex::~ACE_Unbounded_Set_Ex (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::~ACE_Unbounded_Set_Ex"); + + this->delete_nodes (); + + // Delete the dummy node. + ACE_DES_FREE_TEMPLATE2 (head_, + this->allocator_->free, + ACE_Node, + T, C); + this->head_ = 0; +} + +template +ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex (ACE_Allocator *alloc) + : head_ (0), + cur_size_ (0), + allocator_ (alloc) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (NODE*) this->allocator_->malloc (sizeof (NODE)), + NODE); + // Make the list circular by pointing it back to itself. + this->head_->next_ = this->head_; +} + +template +ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex (const C &comp, + ACE_Allocator *alloc) + : head_ (0), + cur_size_ (0), + allocator_ (alloc), + comp_ (comp) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (NODE*) this->allocator_->malloc (sizeof (NODE)), + NODE); + // Make the list circular by pointing it back to itself. + this->head_->next_ = this->head_; +} + +template +ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex (const ACE_Unbounded_Set_Ex &us) + : head_ (0), + cur_size_ (0), + allocator_ (us.allocator_), + comp_ (us.comp_) +{ + ACE_TRACE ("ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Allocator::instance (); + + ACE_NEW_MALLOC (this->head_, + (NODE*) this->allocator_->malloc (sizeof (NODE)), + NODE); + this->head_->next_ = this->head_; + this->copy_nodes (us); +} + +template ACE_Unbounded_Set_Ex & +ACE_Unbounded_Set_Ex::operator= (const ACE_Unbounded_Set_Ex &us) +{ + ACE_TRACE ("ACE_Unbounded_Set_Ex::operator="); + + if (this != &us) + { + this->delete_nodes (); + this->copy_nodes (us); + } + + return *this; +} + +template int +ACE_Unbounded_Set_Ex::find (const T &item) const +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::find"); + const_iterator const the_end = this->end (); + for (const_iterator i = this->begin (); i != the_end; ++i) + if (this->comp_(*i, item)) + return 0; + + return -1; +} + +template int +ACE_Unbounded_Set_Ex::insert (const T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::insert"); + if (this->find (item) == 0) + return 1; + else + return this->insert_tail (item); +} + +template int +ACE_Unbounded_Set_Ex::remove (const T &item) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::remove"); + + // Insert the item to be founded into the dummy node. + this->head_->item_ = item; + + NODE *curr = this->head_; + + while (!(this->comp_ (curr->next_->item_, item))) + curr = curr->next_; + + if (curr->next_ == this->head_) + return -1; // Item was not found. + else + { + NODE *temp = curr->next_; + // Skip over the node that we're deleting. + curr->next_ = temp->next_; + --this->cur_size_; + ACE_DES_FREE_TEMPLATE2 (temp, + this->allocator_->free, + ACE_Node, + T, C); + return 0; + } +} + +template typename ACE_Unbounded_Set_Ex::iterator +ACE_Unbounded_Set_Ex::begin (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::begin"); + return iterator (*this); +} + +template typename ACE_Unbounded_Set_Ex::iterator +ACE_Unbounded_Set_Ex::end (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::end"); + return iterator (*this, 1); +} + +template typename ACE_Unbounded_Set_Ex::const_iterator +ACE_Unbounded_Set_Ex::begin (void) const +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::begin"); + return const_iterator (*this); +} + +template typename ACE_Unbounded_Set_Ex::const_iterator +ACE_Unbounded_Set_Ex::end (void) const +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex::end"); + return const_iterator (*this, 1); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Ex_Iterator) + +template void +ACE_Unbounded_Set_Ex_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unbounded_Set_Ex_Iterator::ACE_Unbounded_Set_Ex_Iterator ( + ACE_Unbounded_Set_Ex &s, + bool end) + : current_ (!end ? s.head_->next_ : s.head_ ), + set_ (&s) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::ACE_Unbounded_Set_Ex_Iterator"); +} + +template int +ACE_Unbounded_Set_Ex_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::advance"); + this->current_ = this->current_->next_; + return this->current_ != this->set_->head_; +} + +template int +ACE_Unbounded_Set_Ex_Iterator::first (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::first"); + this->current_ = this->set_->head_->next_; + return this->current_ != this->set_->head_; +} + +template int +ACE_Unbounded_Set_Ex_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::done"); + + return this->current_ == this->set_->head_; +} + +template int +ACE_Unbounded_Set_Ex_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::next"); + if (this->current_ == this->set_->head_) + return 0; + else + { + item = &this->current_->item_; + return 1; + } +} + +template ACE_Unbounded_Set_Ex_Iterator +ACE_Unbounded_Set_Ex_Iterator::operator++ (int) +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator++ (int)"); + ACE_Unbounded_Set_Ex_Iterator retv (*this); + + // postfix operator + + this->advance (); + return retv; +} + +template ACE_Unbounded_Set_Ex_Iterator& +ACE_Unbounded_Set_Ex_Iterator::operator++ (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator++ (void)"); + + // prefix operator + + this->advance (); + return *this; +} + +template T& +ACE_Unbounded_Set_Ex_Iterator::operator* (void) +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator*"); + T *retv = 0; + + int result = this->next (retv); + ACE_ASSERT (result != 0); + ACE_UNUSED_ARG (result); + + return *retv; +} + +template bool +ACE_Unbounded_Set_Ex_Iterator::operator== (const ACE_Unbounded_Set_Ex_Iterator &rhs) const +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator=="); + return (this->set_ == rhs.set_ && this->current_ == rhs.current_); +} + +template bool +ACE_Unbounded_Set_Ex_Iterator::operator!= (const ACE_Unbounded_Set_Ex_Iterator &rhs) const +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator!="); + return (this->set_ != rhs.set_ || this->current_ != rhs.current_); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Ex_Const_Iterator) + +template void +ACE_Unbounded_Set_Ex_Const_Iterator::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::dump"); +#endif /* ACE_HAS_DUMP */ +} + +template +ACE_Unbounded_Set_Ex_Const_Iterator::ACE_Unbounded_Set_Ex_Const_Iterator ( + const ACE_Unbounded_Set_Ex &s, + bool end) + : current_ (!end ? s.head_->next_ : s.head_ ), + set_ (&s) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::ACE_Unbounded_Set_Ex_Const_Iterator"); +} + +template int +ACE_Unbounded_Set_Ex_Const_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::advance"); + this->current_ = this->current_->next_; + return this->current_ != this->set_->head_; +} + +template int +ACE_Unbounded_Set_Ex_Const_Iterator::first (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::first"); + this->current_ = this->set_->head_->next_; + return this->current_ != this->set_->head_; +} + +template int +ACE_Unbounded_Set_Ex_Const_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::done"); + + return this->current_ == this->set_->head_; +} + +template int +ACE_Unbounded_Set_Ex_Const_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::next"); + if (this->current_ == this->set_->head_) + return 0; + else + { + item = &this->current_->item_; + return 1; + } +} + +template ACE_Unbounded_Set_Ex_Const_Iterator +ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (int) +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (int)"); + ACE_Unbounded_Set_Ex_Const_Iterator retv (*this); + + // postfix operator + + this->advance (); + return retv; +} + +template ACE_Unbounded_Set_Ex_Const_Iterator& +ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (void) +{ + // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (void)"); + + // prefix operator + + this->advance (); + return *this; +} + +template T& +ACE_Unbounded_Set_Ex_Const_Iterator::operator* (void) +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator*"); + T *retv = 0; + + int const result = this->next (retv); + ACE_ASSERT (result != 0); + ACE_UNUSED_ARG (result); + + return *retv; +} + +template bool +ACE_Unbounded_Set_Ex_Const_Iterator::operator== (const ACE_Unbounded_Set_Ex_Const_Iterator &rhs) const +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator=="); + return (this->set_ == rhs.set_ && this->current_ == rhs.current_); +} + +template bool +ACE_Unbounded_Set_Ex_Const_Iterator::operator!= (const ACE_Unbounded_Set_Ex_Const_Iterator &rhs) const +{ + //ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator!="); + return (this->set_ != rhs.set_ || this->current_ != rhs.current_); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_UNBOUNDED_SET_EX_CPP */ diff --git a/dep/ACE_wrappers/ace/Unbounded_Set_Ex.h b/dep/ACE_wrappers/ace/Unbounded_Set_Ex.h new file mode 100644 index 000000000..262ef6043 --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Set_Ex.h @@ -0,0 +1,347 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Unbounded_Set_Ex.h + * + * $Id: Unbounded_Set_Ex.h 81624 2008-05-06 17:14:57Z wotte $ + * + * @author Douglas C. Schmidt + */ +//============================================================================= + +#ifndef ACE_UNBOUNDED_SET_EX_H +#define ACE_UNBOUNDED_SET_EX_H +#include /**/ "ace/pre.h" + +#include "ace/Node.h" +#include "ace/os_include/os_stddef.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Allocator; + +template +class ACE_Unbounded_Set_Ex_Iterator; + +template +class ACE_Unbounded_Set_Ex_Const_Iterator; + +template +class ACE_Unbounded_Set_Ex; + +/** + * @class ACE_Unbounded_Set_Ex_Iterator + * + * @brief Implement an iterator over an unbounded set. + */ +template +class ACE_Unbounded_Set_Ex_Iterator +{ +public: + // = Initialization method. + ACE_Unbounded_Set_Ex_Iterator (ACE_Unbounded_Set_Ex &s, bool end = false); + + // = Iteration methods. + + /// Pass back the that hasn't been seen in the Set. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Move to the first element in the set. Returns 0 if the + /// set is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + // = STL styled iteration, compare, and reference functions. + + /// Postfix advance. + ACE_Unbounded_Set_Ex_Iterator operator++ (int); + + /// Prefix advance. + ACE_Unbounded_Set_Ex_Iterator& operator++ (void); + + /// Returns a reference to the internal element @c this is pointing to. + T& operator* (void); + + /// Check if two iterators point to the same position + bool operator== (const ACE_Unbounded_Set_Ex_Iterator &) const; + bool operator!= (const ACE_Unbounded_Set_Ex_Iterator &) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /// Pointer to the current node in the iteration. + ACE_Node *current_; + + /// Pointer to the set we're iterating over. + ACE_Unbounded_Set_Ex *set_; +}; + +/** + * @class ACE_Unbounded_Set_Ex_Const_Iterator + * + * @brief Implement an const iterator over an unbounded set. + */ +template +class ACE_Unbounded_Set_Ex_Const_Iterator +{ +public: + // = Initialization method. + ACE_Unbounded_Set_Ex_Const_Iterator (const ACE_Unbounded_Set_Ex &s, + bool end = false); + + // = Iteration methods. + + /// Pass back the @a next_item that hasn't been seen in the Set. + /// @return Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Move to the first element in the set. Returns 0 if the + /// set is empty, else 1. + int first (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + // = STL styled iteration, compare, and reference functions. + + /// Postfix advance. + ACE_Unbounded_Set_Ex_Const_Iterator operator++ (int); + + /// Prefix advance. + ACE_Unbounded_Set_Ex_Const_Iterator& operator++ (void); + + /// Returns a reference to the internal element @c this is pointing to. + T& operator* (void); + + /// Check if two iterators point to the same position + bool operator== (const ACE_Unbounded_Set_Ex_Const_Iterator &) const; + bool operator!= (const ACE_Unbounded_Set_Ex_Const_Iterator &) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /// Pointer to the current node in the iteration. + ACE_Node *current_; + + /// Pointer to the set we're iterating over. + const ACE_Unbounded_Set_Ex *set_; +}; + +/** + * @class ACE_Unbounded_Set_Ex + * + * @brief Implement a simple unordered set of of unbounded size. + * + * This implementation of an unordered set uses a circular + * linked list with a dummy node. This implementation does not + * allow duplicates, but it maintains FIFO ordering of insertions. + * + * This implementation may also be parameterized with a comparator + * functor, which must implement bool operator () (const T&, const T&) const, + * returning true if the given items are equivalent. The default comparator + * is sufficient for objects reliably compared with operator==. + * + * Requirements and Performance Characteristics + * - Internal Structure + * Circular linked list + * - Duplicates allowed? + * No + * - Random access allowed? + * No + * - Search speed + * Linear + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * Yes + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + * -# operator== const + * + */ +template +class ACE_Unbounded_Set_Ex +{ +public: + friend class ACE_Unbounded_Set_Ex_Iterator; + friend class ACE_Unbounded_Set_Ex_Const_Iterator; + + // Trait definition. + typedef ACE_Unbounded_Set_Ex_Iterator ITERATOR; + typedef ACE_Unbounded_Set_Ex_Iterator iterator; + typedef ACE_Unbounded_Set_Ex_Const_Iterator CONST_ITERATOR; + typedef ACE_Unbounded_Set_Ex_Const_Iterator const_iterator; + typedef C COMP; + typedef ACE_Node NODE; + + // = Initialization and termination methods. + /// Constructor. Use user specified allocation strategy + /// if specified. + /** + * Initialize an empty set using the allocation strategy of the user if + * provided. + */ + ACE_Unbounded_Set_Ex (ACE_Allocator *alloc = 0); + + /** + * Initialize an empty set using the allocation strategy of the user if + * provided, and a given comparator functor. + */ + ACE_Unbounded_Set_Ex (const C &comparator, ACE_Allocator *alloc = 0); + + /// Copy constructor. + /** + * Initialize this set to be an exact copy of the set provided. + */ + ACE_Unbounded_Set_Ex (const ACE_Unbounded_Set_Ex &); + + /// Assignment operator. + /** + * Perform a deep copy of the rhs into the lhs. + */ + ACE_Unbounded_Set_Ex & operator= (const ACE_Unbounded_Set_Ex &); + + /// Destructor. + /** + * Destroy the nodes of the set. + */ + ~ACE_Unbounded_Set_Ex (void); + + // = Check boundary conditions. + + /// Returns @c true if the container is empty, otherwise returns @c false. + /** + * Constant time is_empty check. + */ + bool is_empty (void) const; + + /// Returns @c false. + /** + * Always returns @c false since the set can never fill up. + */ + bool is_full (void) const; + + // = Classic unordered set operations. + + /// Linear insertion of an item. + /** + * Insert @a new_item into the set (doesn't allow duplicates). + * Returns -1 if failures occur, 1 if item is already present, else + * 0. + */ + int insert (const T &new_item); + + /// Insert @a item at the tail of the set (doesn't check for + /// duplicates). + /** + * Constant time insert at the end of the set. + */ + int insert_tail (const T &item); + + /// Linear remove operation. + /** + * Remove first occurrence of @a item from the set. Returns 0 if + * it removes the item, -1 if it can't find the item, and -1 if a + * failure occurs. + */ + int remove (const T &item); + + /// Finds if @a item occurs in the set. Returns 0 if find succeeds, + /// else -1. + /** + * Performs a linear find operation. + */ + int find (const T &item) const; + + /// Size of the set. + /** + * Access the size of the set. + */ + size_t size (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Reset the ACE_Unbounded_Set_Ex to be empty. + /** + * Delete the nodes of the set. + */ + void reset (void); + + // = STL-styled unidirectional iterator factory. + iterator begin (void); + iterator end (void); + const_iterator begin (void) const; + const_iterator end (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Delete all the nodes in the Set. + void delete_nodes (void); + + /// Copy nodes into this set. + void copy_nodes (const ACE_Unbounded_Set_Ex &); + + /// Head of the linked list of Nodes. + NODE *head_; + + /// Current size of the set. + size_t cur_size_; + + /// Allocation strategy of the set. + ACE_Allocator *allocator_; + + /// Comparator to be used + COMP comp_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Unbounded_Set_Ex.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Unbounded_Set_Ex.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Unbounded_Set_Ex.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_UNBOUNDED_SET_H */ diff --git a/dep/ACE_wrappers/ace/Unbounded_Set_Ex.inl b/dep/ACE_wrappers/ace/Unbounded_Set_Ex.inl new file mode 100644 index 000000000..356a1f58f --- /dev/null +++ b/dep/ACE_wrappers/ace/Unbounded_Set_Ex.inl @@ -0,0 +1,23 @@ +// -*- C++ -*- +// +// $Id: Unbounded_Set_Ex.inl 81624 2008-05-06 17:14:57Z wotte $ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE bool +ACE_Unbounded_Set_Ex::is_empty (void) const +{ + ACE_TRACE ("ACE_Unbounded_Set_Ex::is_empty"); + return this->head_ == this->head_->next_; +} + +template ACE_INLINE bool +ACE_Unbounded_Set_Ex::is_full (void) const +{ + ACE_TRACE ("ACE_Unbounded_Set_Ex::is_full"); + return 0; // We should implement a "node of last resort for this..." +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/Value_Ptr.h b/dep/ACE_wrappers/ace/Value_Ptr.h new file mode 100644 index 000000000..c9272a90c --- /dev/null +++ b/dep/ACE_wrappers/ace/Value_Ptr.h @@ -0,0 +1,167 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Value_Ptr.h + * + * $Id: Value_Ptr.h 80826 2008-03-04 14:51:23Z wotte $ + * + * Value_Ptr implementation based on code in Herb Sutter's book "More + * Exceptional C++". + * + * @author Ossama Othman + */ +//========================================================================== + +#ifndef ACE_VALUE_PTR_H +#define ACE_VALUE_PTR_H + +#include "ace/config-lite.h" + +#include + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE +{ + /** + * @struct VP_traits + * + * @brief @c Value_Ptr traits template structure. + * + * The @c Value_Ptr template class delegates some operations to this + * template traits structure. + * + * Specialize this trait template if cloning through copy + * construction is not sufficient. For example, to avoid slicing + * when copying an object through a base class pointer, one can + * implement a virtual "clone" method that can be used to + * polymorphically invoke the appropriate cloning operation(s). + * That virtual method would then be invoked by the @c VP_traits\<\> + * specialization. + */ + template + struct VP_traits + { + /// Copy the given object. + static T * clone (T const * p) { return new T (*p); } + }; + + /** + * @class Value_Ptr + * + * @brief Smart pointer implementation designed for use as a class + * member. + * + * Using a @c std::auto_ptr\<\> as a class member is sometimes + * problematic since ownership of memory is transferred when copying + * such members. This @c Value_Ptr class is explicitly designed to + * avoid such problems by performing copies of the underlying object + * rather than transfer ownership. This, for example, allows it to + * be readily used as a member in classes placed inside STL + * containers. + * + * @see Item 31 in "More Exceptional C++" by Herb Sutter. + */ + template + class Value_Ptr + { + public: + + /// Constructor. + explicit Value_Ptr (T * p = 0) : p_ (p) { } + + /// Destructor. + ~Value_Ptr (void) { delete this->p_; } + + /// Deference operator. + T & operator* (void) const { return *this->p_; } + + /// Pointer operator. + T * operator-> (void) const { return this->p_; } + + /// Non-throwing swap operation used to make assignment strongly + /// exception-safe. + /** + * @note As implemented, the swap operation may not work correctly + * for @c auto_ptr\<\>s, but why would one use an @c + * auto_ptr\<\> as the template argument for this particular + * template class!? + */ + void swap (Value_Ptr & other) { std::swap (this->p_, other.p_); } + + /// Copy constructor. + Value_Ptr (Value_Ptr const & other) + : p_ (create_from (other.p_)) { } + + /// Assignment operator. + Value_Ptr & operator= (Value_Ptr const & other) + { + // Strongly exception-safe. + Value_Ptr temp (other); + this->swap (temp); + return *this; + } + +#ifndef ACE_LACKS_MEMBER_TEMPLATES + + // Compiler can't handle member templates so we lose converting + // copy operations. + + /// Converting copy constructor. + template + Value_Ptr (Value_Ptr const & other) + : p_ (create_from (other.p_)) { } + + /// Converting assignment operator. + template + Value_Ptr & operator= (Value_Ptr const & other) + { + // Strongly exception-safe. + Value_Ptr temp (other); + this->swap (temp); + return *this; + } + +#endif /* !ACE_LACKS_MEMBER_TEMPLATES */ + + private: + +#ifndef ACE_LACKS_MEMBER_TEMPLATES + + /// Copying method invoked when copy constructing. + template + T * create_from (U const * p) const + { + return p ? VP_traits::clone (p) : 0; + } + +#else + + // Compiler can't handle member templates so we lose converting + // copy operations. + + /// Copying method invoked when copy constructing. + T * create_from (T const * p) const + { + return p ? VP_traits::clone (p) : 0; + } + +#endif /* !ACE_LACKS_MEMBER_TEMPLATES */ + + private: + +#ifndef ACE_LACKS_MEMBER_TEMPLATES + template friend class Value_Ptr; +#endif /* !ACE_LACKS_MEMBER_TEMPLATES */ + + /// Object owned by this @c Value_Ptr. + T * p_; + + }; + +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_VALUE_PTR_H */ diff --git a/dep/ACE_wrappers/ace/Vector_T.cpp b/dep/ACE_wrappers/ace/Vector_T.cpp new file mode 100644 index 000000000..006e6db1b --- /dev/null +++ b/dep/ACE_wrappers/ace/Vector_T.cpp @@ -0,0 +1,154 @@ +// $Id: Vector_T.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_VECTOR_T_CPP +#define ACE_VECTOR_T_CPP + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Vector_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Vector_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_Vector) + +template +void ACE_Vector::resize (const size_t new_size, + const T& t) +{ + ACE_Array::size (new_size); + if (new_size > length_) + for (size_t i = length_; i < new_size; ++i) + (*this)[i]=t; + + curr_max_size_ = this->max_size (); + length_ = new_size; +} + +template +void ACE_Vector::push_back (const T& elem) +{ + if (length_ == curr_max_size_) + { + ACE_Array::size (curr_max_size_ * 2); + curr_max_size_ = this->max_size (); + } + else + ACE_Array::size (length_ + 1); + + ++length_; + (*this)[length_-1] = elem; +} + +template +void ACE_Vector::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +#if 0 + // Can't do this unless the vector is an object with a dump + // function. + for (size_t i = 0; i < this->size (); ++i) + (*this)[i].dump (); +#endif /* 0 */ +#endif /* ACE_HAS_DUMP */ +} + +// Compare this vector with for equality. +template bool +ACE_Vector::operator== (const ACE_Vector &s) const +{ + if (this == &s) + return true; + else if (this->size () != s.size ()) + return false; + + const size_t len = s.size (); + for (size_t slot = 0; slot < len; ++slot) + if ((*this)[slot] != s[slot]) + return false; + + return true; +} + +#if 0 +template +int compare(const ACE_Vector& v1, + const ACE_Vector& v2, + const size_t from_ndx, + const size_t to_ndx) +{ + size_t last1 = v1.size () - 1; + size_t last2 = v2.size () - 1; + if (last1 < from_ndx || last1 < to_ndx) + return false; + if (last2 < from_ndx || last2 < to_ndx) + return false; + if (last1 != last2) + return false; + + // cout<<"compare() <================="<"< +int partial_compare(const ACE_Vector& v1, + const ACE_Vector& v2, + const size_t from_ndx, + const size_t to_ndx) +{ + size_t last1 = v1.size () - 1; + size_t last2 = v2.size () - 1; + + if (last1 < from_ndx || last1 < to_ndx) + return false; + if (last2 < from_ndx || last2 < to_ndx) + return false; + + // cout<<"partial_compare() <================="<"< int +ACE_Vector_Iterator::next (T *&item) +{ + // ACE_TRACE ("ACE_Vector_Iterator::next"); + + if (this->done ()) + { + item = 0; + return 0; + } + else + { + item = &vector_[current_]; + return 1; + } +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_VECTOR_T_CPP */ diff --git a/dep/ACE_wrappers/ace/Vector_T.h b/dep/ACE_wrappers/ace/Vector_T.h new file mode 100644 index 000000000..2df3aa61d --- /dev/null +++ b/dep/ACE_wrappers/ace/Vector_T.h @@ -0,0 +1,316 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Vector_T.h + * + * $Id: Vector_T.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Craig L. Ching + * @author Gonzalo Diethelm + */ +//========================================================================== + +#ifndef ACE_VECTOR_T_H +#define ACE_VECTOR_T_H + +#include /**/ "ace/pre.h" + +#include "ace/Array.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/* + * Default size for an ACE_Vector. + */ +static const size_t ACE_VECTOR_DEFAULT_SIZE = 32; + +// Forward declaration. +template class ACE_Vector_Iterator; + +/** + * @class ACE_Vector + * + * @brief Defines an STL-like vector container. + * + * This is an STL-like template vector container, a wrapper around + * ACE_Array. It provides at least the basic std::vector look and + * feel: push_back(), clear(), resize(), capacity(). This template + * class uses the copy semantic paradigm, though it is okay to use + * reference counted smart pointers (see ACE_Ptr<T>) with this + * template class. + * + * Requirements and Performance Characteristics + * - Internal Structure + * ACE_Array + * - Duplicates allowed? + * Yes + * - Random access allowed? + * No + * - Search speed + * N/A + * - Insert/replace speed + * Linear + * - Iterator still valid after change to container? + * Yes + * - Frees memory for removed elements? + * No + * - Items inserted by + * Value + * - Requirements for contained type + * -# Default constructor + * -# Copy constructor + * -# operator= + */ +template +class ACE_Vector : public ACE_Array +{ +public: + /** + * A short name for iterator for ACE_Vector. + */ + typedef ACE_Vector_Iterator Iterator; + + + /** + * General constructor. + * + * @param init_size Initial size of the vector with the default + * value of DEFAULT_SIZE + * @param alloc Pointer to an ACE allocator. If it is NULL then the + * default ACE allocator is used + */ + ACE_Vector (const size_t init_size = DEFAULT_SIZE, + ACE_Allocator* alloc = 0); + + /** + * Destructor. + */ + ~ACE_Vector (); + + /** + * Returns the current vector capacity, that is, the currently + * allocated buffer size. + * + * @return Current buffer size of the vector + */ + size_t capacity (void) const; + + /** + * Returns the vector's dynamic size / actual current size of the + * vector. Do not confuse it with ACE_Array::size(), which returns + * the array's capacity. Unfortunately, ACE is not very consistent + * with the function names. + * + * @return Dynamic size / actual current size of the vector. + */ + size_t size (void) const; + + /** + * Clears out the vector. It does not reallocate the vector's + * buffer, it is just sets the vector's dynamic size to 0. + */ + void clear (void); + + /** + * Resizes the vector to the new capacity. If the vector's current + * capacity is smaller than the size to be specified, then the + * buffer gets reallocated. If the new capacity is less than the + * current capacity of the vector, the buffer size stays the same. + * + * @param new_size New capacity of the vector + * @param t A filler value (of the class T) for initializing the + * elements of the vector with. By default, if this + * parameter is not specified, the default value of the + * class T will be used (for more detail, see the + * initialization clause for this parameter). + */ + void resize (const size_t new_size, + const T& t); + + /** + * Appends a new element to the vector ("push back"). If the + * dynamic size of the vector is equal to the capacity of the vector + * (vector is at capacity), the vector automatically doubles its + * capacity. + * + * @param elem A reference to the new element to be appended. By + * default, this parameters gets initialized with the + * default value of the class T. + */ + void push_back (const T& elem); + + /** + * Deletes the last element from the vector ("pop back"). What this + * function really does is decrement the dynamic size of the + * vector. The vector's buffer does not get reallocated for + * performance. + */ + void pop_back (void); + + /** + * This function dumps the content of the vector. TO BE MOVED out + * of this class. It needs to be implemented as a global template + * function that accepts a const ACE_Vector<T>, in order to + * make instances of this class compile on Linux, AIX. G++ and xlC + * have template instantiation algoriths, which are different from + * the one in Visual C++. The algorithms try to instantiate ALL + * methods declared in the template class, regardless of whether the + * functions are used or not. That is, all of the classes, that are + * used as elements in ACE_Vector's, have to have the dump() methods + * defined in them (seems to be overkill). + * + * This function calls T::dump() for each element of the vector. + */ + void dump (void) const; + + // = Compare operators + + ///Equality comparison operator. + /** + * Compare this vector with @arg s for equality. Two vectors are equal + * if their sizes are equal and all the elements are equal. + */ + bool operator== (const ACE_Vector &s) const; + + ///Inequality comparison operator. + /** + * Compare this vector with @arg s for inequality such that @c *this != + * @arg s is always the complement of the boolean return value of + * @c *this == @arg s. + */ + bool operator!= (const ACE_Vector &s) const; + + void swap (ACE_Vector &rhs); + +protected: + + /** + * Dynamic size (length) of the vector. + */ + size_t length_; + + /** + * Current capacity (buffer size) of the vector. + */ + size_t curr_max_size_; + + friend class ACE_Vector_Iterator; +}; + +#if 0 +/* + * Not sure about including these functions, if for no other reason, + * because they polute the global namespace! + */ + +/** + * Compare two vectors in the range of [from_ndx..to_ndx]. This + * template function requires class T to have the bool operator!=() + * declared in the class. It is safe to define vectors of scalar data + * types, like int, double, etc., including class ACE_TString. + * + * @param v1 The first vector (out of the two) to be compared. + * @param v2 The Second vector (out of the two) to be compared. + * @param from_ndx Compare vector v1 and v2, starting with the + * "from_ndx" index . + * @param to_ndx Compare vector v1 and v2, from "from_ndx" to + * "to_ndx". + * @return Returns true if v1==v2 in the specified index range, + * returns false otherwise. Also, returns false in case if + * v1's size is not equal to v2's size. + */ +template +int compare (const ACE_Vector& v1, + const ACE_Vector& v2, + const size_t from_ndx, + const size_t to_ndx); + +/** + * Does a partial comparison of two vectors in the range of + * [from_ndx..to_ndx]. The only difference between this function and + * the template compare<T> function is that this function does + * not require v1 and v2 to be of equal size. + * + * @param v1 The first vector (out of the two) to be compared. + * @param v2 The Second vector (out of the two) to be compared. + * @param from_ndx Compare vector v1 and v2, starting with the + * "from_ndx" index . + * @param to_ndx Compare vector v1 and v2, from "from_ndx" to + * "to_ndx". + * @return Returns true if vector v1 and v2 are equal in the specified + * index range. + */ + +template +int partial_compare (const ACE_Vector& v1, + const ACE_Vector& v2, + const size_t from_ndx, + const size_t to_ndx); +#endif /* 0 */ +// **************************************************************** + +/** + * @class ACE_Vector_Iterator + * + * @brief Implement an iterator over an ACE_Vector. + * + * This iterator is safe in the face of vector element deletions. + * But it is NOT safe if the vector is resized via the assignment + * operator during iteration. That would be very odd, and dangerous. + */ +template +class ACE_Vector_Iterator +{ +public: + // = Initialization method. + ACE_Vector_Iterator (ACE_Vector &); + + // = Iteration methods. + + /// Pass back the that hasn't been seen in the vector. + /// Returns 0 when all items have been seen, else 1. + int next (T *&next_item); + + /// Move forward by one element in the vector. Returns 0 when all the + /// items in the vector have been seen, else 1. + int advance (void); + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Pointer to the current item in the iteration. + size_t current_; + + /// Reference to the vector we're iterating over. + ACE_Vector &vector_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Vector_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Vector_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Vector_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_VECTOR_T_H */ diff --git a/dep/ACE_wrappers/ace/Vector_T.inl b/dep/ACE_wrappers/ace/Vector_T.inl new file mode 100644 index 000000000..4b773109a --- /dev/null +++ b/dep/ACE_wrappers/ace/Vector_T.inl @@ -0,0 +1,107 @@ +// -*- C++ -*- +// +// $Id: Vector_T.inl 81478 2008-04-28 13:22:26Z schmidt $ + +#include + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template ACE_INLINE +ACE_Vector::ACE_Vector (const size_t init_size, + ACE_Allocator* alloc) + : ACE_Array (init_size == 0 ? DEFAULT_SIZE : init_size, alloc), + length_ (0) +{ + this->curr_max_size_ = this->max_size (); +} + +template ACE_INLINE +ACE_Vector::~ACE_Vector () +{ +} + +template ACE_INLINE +size_t ACE_Vector::capacity (void) const +{ + return curr_max_size_; +} + +template ACE_INLINE +size_t ACE_Vector::size (void) const +{ + return length_; +} + +template ACE_INLINE +void ACE_Vector::clear (void) +{ + length_ = 0; +} + +template ACE_INLINE +void ACE_Vector::pop_back (void) +{ + if (length_ > 0) + { + --length_; + ACE_Array::size (length_); + } +} + +// Compare this vector with for inequality. + +template ACE_INLINE bool +ACE_Vector::operator!= (const ACE_Vector &s) const +{ + return !(*this == s); +} + +template ACE_INLINE void +ACE_Vector::swap (ACE_Vector &rhs) +{ + ACE_Array::swap (rhs); + std::swap (this->length_, rhs.length_); + std::swap (this->curr_max_size_, rhs.curr_max_size_); +} + +// **************************************************************** + +template ACE_INLINE void +ACE_Vector_Iterator::dump (void) const +{ + // ACE_TRACE ("ACE_Vector_Iterator::dump"); +} + +template ACE_INLINE +ACE_Vector_Iterator::ACE_Vector_Iterator (ACE_Vector &v) + : current_ (0), + vector_ (v) +{ + // ACE_TRACE ("ACE_Vector_Iterator::ACE_Vector_Iterator"); +} + +template ACE_INLINE int +ACE_Vector_Iterator::advance (void) +{ + // ACE_TRACE ("ACE_Vector_Iterator::advance"); + + if (this->current_ < vector_.size ()) + { + ++this->current_; + return 1; + } + else + // Already finished iterating. + return 0; +} + +template ACE_INLINE int +ACE_Vector_Iterator::done (void) const +{ + ACE_TRACE ("ACE_Vector_Iterator::done"); + + return this->current_ >= vector_.size (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + diff --git a/dep/ACE_wrappers/ace/Version.h b/dep/ACE_wrappers/ace/Version.h new file mode 100644 index 000000000..0c8c9d7db --- /dev/null +++ b/dep/ACE_wrappers/ace/Version.h @@ -0,0 +1,9 @@ + +// -*- C++ -*- +// $Id: Version.h 82705 2008-09-15 11:08:20Z sma $ +// This is file was automatically generated by \$ACE_ROOT/bin/make_release. + +#define ACE_MAJOR_VERSION 5 +#define ACE_MINOR_VERSION 6 +#define ACE_BETA_VERSION 6 +#define ACE_VERSION "5.6.6" diff --git a/dep/ACE_wrappers/ace/Versioned_Namespace.h b/dep/ACE_wrappers/ace/Versioned_Namespace.h new file mode 100644 index 000000000..542254876 --- /dev/null +++ b/dep/ACE_wrappers/ace/Versioned_Namespace.h @@ -0,0 +1,51 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Versioned_Namespace.h + * + * $Id$ + * + * Versioned namespace support. + * + * Useful for preventing conflicts when using a third party library. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef ACE_VERSIONED_NAMESPACE_H +#define ACE_VERSIONED_NAMESPACE_H + +#ifndef ACE_CONFIG_MACROS_H +# error This header is only meant to be included by or after "ace/config-lite.h". +#endif /* !ACE_CONFIG_LITE_H */ + + +#if defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1 + +# ifndef ACE_VERSIONED_NAMESPACE_NAME +//# include "ace/Version.h" + +// Preprocessor symbols will not be expanded if they are +// concatenated. Force the preprocessor to expand them during the +// argument prescan by calling a macro that itself calls another that +// performs the actual concatenation. +# define ACE_MAKE_VERSIONED_NAMESPACE_NAME_IMPL(MAJOR,MINOR,BETA) ACE_ ## MAJOR ## _ ## MINOR ## _ ## BETA +# define ACE_MAKE_VERSIONED_NAMESPACE_NAME(MAJOR,MINOR,BETA) ACE_MAKE_VERSIONED_NAMESPACE_NAME_IMPL(MAJOR,MINOR,BETA) +# define ACE_VERSIONED_NAMESPACE_NAME ACE_MAKE_VERSIONED_NAMESPACE_NAME(ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION) +# endif /* !ACE_VERSIONED_NAMESPACE_NAME */ + +# define ACE_BEGIN_VERSIONED_NAMESPACE_DECL namespace ACE_VERSIONED_NAMESPACE_NAME { +# define ACE_END_VERSIONED_NAMESPACE_DECL } \ + using namespace ACE_VERSIONED_NAMESPACE_NAME; + +#else + +# define ACE_VERSIONED_NAMESPACE_NAME +# define ACE_BEGIN_VERSIONED_NAMESPACE_DECL +# define ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_VERSIONED_NAMESPACE */ + +#endif /* !ACE_VERSIONED_NAMESPACE_H */ diff --git a/dep/ACE_wrappers/ace/WFMO_Reactor.cpp b/dep/ACE_wrappers/ace/WFMO_Reactor.cpp new file mode 100644 index 000000000..7195749ad --- /dev/null +++ b/dep/ACE_wrappers/ace/WFMO_Reactor.cpp @@ -0,0 +1,2748 @@ +// $Id: WFMO_Reactor.cpp 81138 2008-03-28 09:18:15Z johnnyw $ + +#include "ace/WFMO_Reactor.h" + +#if defined (ACE_WIN32) + +#include "ace/Handle_Set.h" +#include "ace/Timer_Heap.h" +#include "ace/Thread.h" +#include "ace/OS_NS_errno.h" +#include "ace/Null_Condition.h" + +#if !defined (__ACE_INLINE__) +#include "ace/WFMO_Reactor.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, WFMO_Reactor, "$Id: WFMO_Reactor.cpp 81138 2008-03-28 09:18:15Z johnnyw $") + +#include "ace/Auto_Ptr.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_WFMO_Reactor_Handler_Repository::ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor) + : wfmo_reactor_ (wfmo_reactor) +{ +} + +int +ACE_WFMO_Reactor_Handler_Repository::open (size_t size) +{ + if (size > MAXIMUM_WAIT_OBJECTS) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%d exceeds MAXIMUM_WAIT_OBJECTS (%d)\n"), + size, + MAXIMUM_WAIT_OBJECTS), + -1); + + // Dynamic allocation + ACE_NEW_RETURN (this->current_handles_, + ACE_HANDLE[size], + -1); + ACE_NEW_RETURN (this->current_info_, + Current_Info[size], + -1); + ACE_NEW_RETURN (this->current_suspended_info_, + Suspended_Info[size], + -1); + ACE_NEW_RETURN (this->to_be_added_info_, + To_Be_Added_Info[size], + -1); + + // Initialization + this->max_size_ = size; + this->max_handlep1_ = 0; + this->suspended_handles_ = 0; + this->handles_to_be_added_ = 0; + this->handles_to_be_deleted_ = 0; + this->handles_to_be_suspended_ = 0; + this->handles_to_be_resumed_ = 0; + + for (size_t i = 0; i < size; ++i) + this->current_handles_[i] = ACE_INVALID_HANDLE; + + return 0; +} + +ACE_WFMO_Reactor_Handler_Repository::~ACE_WFMO_Reactor_Handler_Repository (void) +{ + // Free up dynamically allocated space + delete [] this->current_handles_; + delete [] this->current_info_; + delete [] this->current_suspended_info_; + delete [] this->to_be_added_info_; +} + +ACE_Reactor_Mask +ACE_WFMO_Reactor_Handler_Repository::bit_ops (long &existing_masks, + ACE_Reactor_Mask change_masks, + int operation) +{ + // Find the old reactor masks. This automatically does the work of + // the GET_MASK operation. + + ACE_Reactor_Mask old_masks = ACE_Event_Handler::NULL_MASK; + + if (ACE_BIT_ENABLED (existing_masks, FD_READ) + || ACE_BIT_ENABLED (existing_masks, FD_CLOSE)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::READ_MASK); + + if (ACE_BIT_ENABLED (existing_masks, FD_WRITE)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::WRITE_MASK); + + if (ACE_BIT_ENABLED (existing_masks, FD_OOB)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::EXCEPT_MASK); + + if (ACE_BIT_ENABLED (existing_masks, FD_ACCEPT)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::ACCEPT_MASK); + + if (ACE_BIT_ENABLED (existing_masks, FD_CONNECT)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::CONNECT_MASK); + + if (ACE_BIT_ENABLED (existing_masks, FD_QOS)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::QOS_MASK); + + if (ACE_BIT_ENABLED (existing_masks, FD_GROUP_QOS)) + ACE_SET_BITS (old_masks, ACE_Event_Handler::GROUP_QOS_MASK); + + switch (operation) + { + case ACE_Reactor::CLR_MASK: + // For the CLR_MASK operation, clear only the specific masks. + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::READ_MASK)) + { + ACE_CLR_BITS (existing_masks, FD_READ); + ACE_CLR_BITS (existing_masks, FD_CLOSE); + } + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::WRITE_MASK)) + ACE_CLR_BITS (existing_masks, FD_WRITE); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::EXCEPT_MASK)) + ACE_CLR_BITS (existing_masks, FD_OOB); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::ACCEPT_MASK)) + ACE_CLR_BITS (existing_masks, FD_ACCEPT); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::CONNECT_MASK)) + ACE_CLR_BITS (existing_masks, FD_CONNECT); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::QOS_MASK)) + ACE_CLR_BITS (existing_masks, FD_QOS); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::GROUP_QOS_MASK)) + ACE_CLR_BITS (existing_masks, FD_GROUP_QOS); + + break; + + case ACE_Reactor::SET_MASK: + // If the operation is a set, first reset any existing masks + + existing_masks = 0; + /* FALLTHRU */ + + case ACE_Reactor::ADD_MASK: + // For the ADD_MASK and the SET_MASK operation, add only the + // specific masks. + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::READ_MASK)) + { + ACE_SET_BITS (existing_masks, FD_READ); + ACE_SET_BITS (existing_masks, FD_CLOSE); + } + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::WRITE_MASK)) + ACE_SET_BITS (existing_masks, FD_WRITE); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::EXCEPT_MASK)) + ACE_SET_BITS (existing_masks, FD_OOB); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::ACCEPT_MASK)) + ACE_SET_BITS (existing_masks, FD_ACCEPT); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::CONNECT_MASK)) + ACE_SET_BITS (existing_masks, FD_CONNECT); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::QOS_MASK)) + ACE_SET_BITS (existing_masks, FD_QOS); + + if (ACE_BIT_ENABLED (change_masks, ACE_Event_Handler::GROUP_QOS_MASK)) + ACE_SET_BITS (existing_masks, FD_GROUP_QOS); + + break; + + case ACE_Reactor::GET_MASK: + + // The work for this operation is done in all cases at the + // begining of the function. + + ACE_UNUSED_ARG (change_masks); + + break; + } + + return old_masks; +} + +int +ACE_WFMO_Reactor_Handler_Repository::unbind_i (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + bool &changes_required) +{ + int error = 0; + + // Remember this value; only if it changes do we need to wakeup + // the other threads + size_t const original_handle_count = this->handles_to_be_deleted_; + size_t i; + + // Go through all the handles looking for . Even if we find + // it, we continue through the rest of the list since could + // appear multiple times. All handles are checked. + + // First check the current entries + for (i = 0; i < this->max_handlep1_ && error == 0; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->current_handles_[i] == handle + || this->current_info_[i].io_handle_ == handle) + && // Make sure that it is not already marked for deleted + !this->current_info_[i].delete_entry_) + { + if (this->remove_handler_i (i, mask) == -1) + error = 1; + } + + // Then check the suspended entries + for (i = 0; i < this->suspended_handles_ && error == 0; ++i) + // Since the handle can either be the event or the I/O handle, we + // have to check both + if ((this->current_suspended_info_[i].io_handle_ == handle + || this->current_suspended_info_[i].event_handle_ == handle) + && + // Make sure that it is not already marked for deleted + !this->current_suspended_info_[i].delete_entry_) + { + if (this->remove_suspended_handler_i (i, mask) == -1) + error = 1; + } + + // Then check the to_be_added entries + for (i = 0; i < this->handles_to_be_added_ && error == 0; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->to_be_added_info_[i].io_handle_ == handle + || this->to_be_added_info_[i].event_handle_ == handle) + && + // Make sure that it is not already marked for deleted + !this->to_be_added_info_[i].delete_entry_) + { + if (this->remove_to_be_added_handler_i (i, mask) == -1) + error = 1; + } + + // Only if the number of handlers to be deleted changes do we need + // to wakeup the other threads + if (original_handle_count < this->handles_to_be_deleted_) + changes_required = true; + + return error ? -1 : 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::remove_handler_i (size_t slot, + ACE_Reactor_Mask to_be_removed_masks) +{ + // I/O entries + if (this->current_info_[slot].io_entry_) + { + // See if there are other events that the is + // interested in + this->bit_ops (this->current_info_[slot].network_events_, + to_be_removed_masks, + ACE_Reactor::CLR_MASK); + + // Disassociate/Reassociate the event from/with the I/O handle. + // This will depend on the value of remaining set of network + // events that the is interested in. I don't + // think we can do anything about errors here, so I will not + // check this. + ::WSAEventSelect ((SOCKET) this->current_info_[slot].io_handle_, + this->current_handles_[slot], + this->current_info_[slot].network_events_); + } + // Normal event entries. + else if (ACE_BIT_ENABLED (to_be_removed_masks, ACE_Event_Handler::DONT_CALL)) + // Preserve DONT_CALL + to_be_removed_masks = ACE_Event_Handler::DONT_CALL; + else + // Make sure that the is the NULL_MASK + to_be_removed_masks = ACE_Event_Handler::NULL_MASK; + + // If this event was marked for suspension, undo the suspension flag + // and reduce the to be suspended count. + if (this->current_info_[slot].suspend_entry_) + { + // Undo suspension + this->current_info_[slot].suspend_entry_ = false; + // Decrement the handle count + --this->handles_to_be_suspended_; + } + + // If there are no more events that the is + // interested in, or this is a non-I/O entry, schedule the + // for removal + if (this->current_info_[slot].network_events_ == 0) + { + // Mark to be deleted + this->current_info_[slot].delete_entry_ = true; + // Remember the mask + this->current_info_[slot].close_masks_ = to_be_removed_masks; + // Increment the handle count + ++this->handles_to_be_deleted_; + } + + // Since it is not a complete removal, we'll call handle_close + // for all the masks that were removed. This does not change + // the internal state of the reactor. + // + // Note: this condition only applies to I/O entries + else if (ACE_BIT_ENABLED (to_be_removed_masks, ACE_Event_Handler::DONT_CALL) == 0) + { + ACE_HANDLE handle = this->current_info_[slot].io_handle_; + this->current_info_[slot].event_handler_->handle_close (handle, + to_be_removed_masks); + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::remove_suspended_handler_i (size_t slot, + ACE_Reactor_Mask to_be_removed_masks) +{ + // I/O entries + if (this->current_suspended_info_[slot].io_entry_) + { + // See if there are other events that the is + // interested in + this->bit_ops (this->current_suspended_info_[slot].network_events_, + to_be_removed_masks, + ACE_Reactor::CLR_MASK); + + // Disassociate/Reassociate the event from/with the I/O handle. + // This will depend on the value of remaining set of network + // events that the is interested in. I don't + // think we can do anything about errors here, so I will not + // check this. + ::WSAEventSelect ((SOCKET) this->current_suspended_info_[slot].io_handle_, + this->current_suspended_info_[slot].event_handle_, + this->current_suspended_info_[slot].network_events_); + } + // Normal event entries. + else if (ACE_BIT_ENABLED (to_be_removed_masks, ACE_Event_Handler::DONT_CALL)) + // Preserve DONT_CALL + to_be_removed_masks = ACE_Event_Handler::DONT_CALL; + else + // Make sure that the is the NULL_MASK + to_be_removed_masks = ACE_Event_Handler::NULL_MASK; + + // If this event was marked for resumption, undo the resumption flag + // and reduce the to be resumed count. + if (this->current_suspended_info_[slot].resume_entry_) + { + // Undo resumption + this->current_suspended_info_[slot].resume_entry_ = false; + // Decrement the handle count + --this->handles_to_be_resumed_; + } + + // If there are no more events that the is + // interested in, or this is a non-I/O entry, schedule the + // for removal + if (this->current_suspended_info_[slot].network_events_ == 0) + { + // Mark to be deleted + this->current_suspended_info_[slot].delete_entry_ = true; + // Remember the mask + this->current_suspended_info_[slot].close_masks_ = to_be_removed_masks; + // Increment the handle count + ++this->handles_to_be_deleted_; + } + // Since it is not a complete removal, we'll call handle_close for + // all the masks that were removed. This does not change the + // internal state of the reactor. + // + // Note: this condition only applies to I/O entries + else if (ACE_BIT_ENABLED (to_be_removed_masks, ACE_Event_Handler::DONT_CALL) == 0) + { + ACE_HANDLE handle = this->current_suspended_info_[slot].io_handle_; + this->current_suspended_info_[slot].event_handler_->handle_close (handle, + to_be_removed_masks); + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::remove_to_be_added_handler_i (size_t slot, + ACE_Reactor_Mask to_be_removed_masks) +{ + // I/O entries + if (this->to_be_added_info_[slot].io_entry_) + { + // See if there are other events that the is + // interested in + this->bit_ops (this->to_be_added_info_[slot].network_events_, + to_be_removed_masks, + ACE_Reactor::CLR_MASK); + + // Disassociate/Reassociate the event from/with the I/O handle. + // This will depend on the value of remaining set of network + // events that the is interested in. I don't + // think we can do anything about errors here, so I will not + // check this. + ::WSAEventSelect ((SOCKET) this->to_be_added_info_[slot].io_handle_, + this->to_be_added_info_[slot].event_handle_, + this->to_be_added_info_[slot].network_events_); + } + // Normal event entries. + else if (ACE_BIT_ENABLED (to_be_removed_masks, ACE_Event_Handler::DONT_CALL)) + // Preserve DONT_CALL + to_be_removed_masks = ACE_Event_Handler::DONT_CALL; + else + // Make sure that the is the NULL_MASK + to_be_removed_masks = ACE_Event_Handler::NULL_MASK; + + // If this event was marked for suspension, undo the suspension flag + // and reduce the to be suspended count. + if (this->to_be_added_info_[slot].suspend_entry_) + { + // Undo suspension + this->to_be_added_info_[slot].suspend_entry_ = false; + // Decrement the handle count + --this->handles_to_be_suspended_; + } + + // If there are no more events that the is + // interested in, or this is a non-I/O entry, schedule the + // for removal + if (this->to_be_added_info_[slot].network_events_ == 0) + { + // Mark to be deleted + this->to_be_added_info_[slot].delete_entry_ = true; + // Remember the mask + this->to_be_added_info_[slot].close_masks_ = to_be_removed_masks; + // Increment the handle count + ++this->handles_to_be_deleted_; + } + // Since it is not a complete removal, we'll call handle_close + // for all the masks that were removed. This does not change + // the internal state of the reactor. + // + // Note: this condition only applies to I/O entries + else if (ACE_BIT_ENABLED (to_be_removed_masks, ACE_Event_Handler::DONT_CALL) == 0) + { + ACE_HANDLE handle = this->to_be_added_info_[slot].io_handle_; + this->to_be_added_info_[slot].event_handler_->handle_close (handle, + to_be_removed_masks); + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::suspend_handler_i (ACE_HANDLE handle, + bool &changes_required) +{ + size_t i = 0; + + // Go through all the handles looking for . Even if we find + // it, we continue through the rest of the list since could + // appear multiple times. All handles are checked. + + // Check the current entries first. + for (i = 0; i < this->max_handlep1_; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->current_handles_[i] == handle || + this->current_info_[i].io_handle_ == handle) && + // Make sure that it is not already marked for suspension + !this->current_info_[i].suspend_entry_) + { + // Mark to be suspended + this->current_info_[i].suspend_entry_ = true; + // Increment the handle count + ++this->handles_to_be_suspended_; + // Changes will be required + changes_required = true; + } + + // Then check the suspended entries. + for (i = 0; i < this->suspended_handles_; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->current_suspended_info_[i].event_handle_ == handle || + this->current_suspended_info_[i].io_handle_ == handle) && + // Make sure that the resumption is not already undone + this->current_suspended_info_[i].resume_entry_) + { + // Undo resumption + this->current_suspended_info_[i].resume_entry_ = false; + // Decrement the handle count + --this->handles_to_be_resumed_; + // Changes will be required + changes_required = true; + } + + // Then check the to_be_added entries. + for (i = 0; i < this->handles_to_be_added_; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->to_be_added_info_[i].io_handle_ == handle || + this->to_be_added_info_[i].event_handle_ == handle) && + // Make sure that it is not already marked for suspension + !this->to_be_added_info_[i].suspend_entry_) + { + // Mark to be suspended + this->to_be_added_info_[i].suspend_entry_ = true; + // Increment the handle count + ++this->handles_to_be_suspended_; + // Changes will be required + changes_required = true; + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::resume_handler_i (ACE_HANDLE handle, + bool &changes_required) +{ + size_t i = 0; + + // Go through all the handles looking for . Even if we find + // it, we continue through the rest of the list since could + // appear multiple times. All handles are checked. + + // Check the current entries first. + for (i = 0; i < this->max_handlep1_; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->current_handles_[i] == handle || + this->current_info_[i].io_handle_ == handle) && + // Make sure that the suspension is not already undone + this->current_info_[i].suspend_entry_) + { + // Undo suspension + this->current_info_[i].suspend_entry_ = false; + // Decrement the handle count + --this->handles_to_be_suspended_; + // Changes will be required + changes_required = true; + } + + // Then check the suspended entries. + for (i = 0; i < this->suspended_handles_; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->current_suspended_info_[i].event_handle_ == handle || + this->current_suspended_info_[i].io_handle_ == handle) && + // Make sure that it is not already marked for resumption + !this->current_suspended_info_[i].resume_entry_) + { + // Mark to be resumed + this->current_suspended_info_[i].resume_entry_ = true; + // Increment the handle count + ++this->handles_to_be_resumed_; + // Changes will be required + changes_required = true; + } + + // Then check the to_be_added entries. + for (i = 0; i < this->handles_to_be_added_; ++i) + // Since the handle can either be the event or the I/O handle, + // we have to check both + if ((this->to_be_added_info_[i].io_handle_ == handle || + this->to_be_added_info_[i].event_handle_ == handle) && + // Make sure that the suspension is not already undone + this->to_be_added_info_[i].suspend_entry_) + { + // Undo suspension + this->to_be_added_info_[i].suspend_entry_ = false; + // Decrement the handle count + --this->handles_to_be_suspended_; + // Changes will be required + changes_required = true; + } + + return 0; +} + +void +ACE_WFMO_Reactor_Handler_Repository::unbind_all (void) +{ + { + ACE_GUARD (ACE_Process_Mutex, ace_mon, this->wfmo_reactor_.lock_); + + bool dummy; + size_t i; + + // Remove all the current handlers + for (i = 0; i < this->max_handlep1_; ++i) + this->unbind_i (this->current_handles_[i], + ACE_Event_Handler::ALL_EVENTS_MASK, + dummy); + + // Remove all the suspended handlers + for (i = 0; i < this->suspended_handles_; ++i) + this->unbind_i (this->current_suspended_info_[i].event_handle_, + ACE_Event_Handler::ALL_EVENTS_MASK, + dummy); + + // Remove all the to_be_added handlers + for (i = 0; i < this->handles_to_be_added_; ++i) + this->unbind_i (this->to_be_added_info_[i].event_handle_, + ACE_Event_Handler::ALL_EVENTS_MASK, + dummy); + } + + // The guard is released here + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wfmo_reactor_.wakeup_all_threads (); +} + +int +ACE_WFMO_Reactor_Handler_Repository::bind_i (bool io_entry, + ACE_Event_Handler *event_handler, + long network_events, + ACE_HANDLE io_handle, + ACE_HANDLE event_handle, + bool delete_event) +{ + if (event_handler == 0) + return -1; + + // Make sure that the is valid + if (event_handle == ACE_INVALID_HANDLE) + event_handle = event_handler->get_handle (); + if (this->invalid_handle (event_handle)) + return -1; + + size_t current_size = this->max_handlep1_ + + this->handles_to_be_added_ - + this->handles_to_be_deleted_ + + this->suspended_handles_; + + // Make sure that there's room in the table and that total pending + // additions should not exceed what the array + // can hold. + if (current_size < this->max_size_ && + this->handles_to_be_added_ < this->max_size_) + { + // Cache this set into the , till we come + // around to actually adding this to the + this->to_be_added_info_[this->handles_to_be_added_].set (event_handle, + io_entry, + event_handler, + io_handle, + network_events, + delete_event); + + ++this->handles_to_be_added_; + + event_handler->add_reference (); + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wfmo_reactor_.wakeup_all_threads (); + } + else + { + errno = EMFILE; // File descriptor table is full (better than nothing) + return -1; + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::make_changes_in_current_infos (void) +{ + // Go through the entire valid array and check for all handles that + // have been schedule for deletion + if (this->handles_to_be_deleted_ > 0 || this->handles_to_be_suspended_ > 0) + { + size_t i = 0; + while (i < this->max_handlep1_) + { + // This stuff is necessary here, since we should not make + // the upcall until all the internal data structures have + // been updated. This is to protect against upcalls that + // try to deregister again. + ACE_HANDLE handle = ACE_INVALID_HANDLE; + ACE_Reactor_Mask masks = ACE_Event_Handler::NULL_MASK; + ACE_Event_Handler *event_handler = 0; + + // See if this entry is scheduled for deletion + if (this->current_info_[i].delete_entry_) + { + // Calling the method here will ensure that we + // will only call it once per deregistering . + // This is essential in the case when the will + // do something like delete itself and we have multiple + // threads in WFMO_Reactor. + // + // Make sure that the DONT_CALL mask is not set + masks = this->current_info_[i].close_masks_; + if (ACE_BIT_ENABLED (masks, ACE_Event_Handler::DONT_CALL) == 0) + { + // Grab the correct handle depending on the type entry + if (this->current_info_[i].io_entry_) + handle = this->current_info_[i].io_handle_; + else + handle = this->current_handles_[i]; + + // Event handler + event_handler = this->current_info_[i].event_handler_; + } + + // If created the event, we need to clean it up + if (this->current_info_[i].delete_event_) + ACE_OS::event_destroy (&this->current_handles_[i]); + + // Reduce count by one + --this->handles_to_be_deleted_; + } + + // See if this entry is scheduled for suspension + else if (this->current_info_[i].suspend_entry_) + { + this->current_suspended_info_ [this->suspended_handles_].set (this->current_handles_[i], + this->current_info_[i]); + // Increase number of suspended handles + ++this->suspended_handles_; + + // Reduce count by one + --this->handles_to_be_suspended_; + } + + // See if this entry is scheduled for deletion or suspension + // If so we need to clean up + if (this->current_info_[i].delete_entry_ || + this->current_info_[i].suspend_entry_ ) + { + size_t last_valid_slot = this->max_handlep1_ - 1; + // If this is the last handle in the set, no need to swap + // places. Simply remove it. + if (i < last_valid_slot) + // Swap this handle with the last valid handle + { + // Struct copy + this->current_info_[i] = + this->current_info_[last_valid_slot]; + this->current_handles_[i] = + this->current_handles_[last_valid_slot]; + } + // Reset the info in this slot + this->current_info_[last_valid_slot].reset (); + this->current_handles_[last_valid_slot] = ACE_INVALID_HANDLE; + --this->max_handlep1_; + } + else + { + // This current entry is not up for deletion or + // suspension. Proceed to the next entry in the current + // handles. + ++i; + } + + // Now that all internal structures have been updated, make + // the upcall. + if (event_handler != 0) + { + bool const requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + event_handler->handle_close (handle, masks); + + if (requires_reference_counting) + { + event_handler->remove_reference (); + } + } + } + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::make_changes_in_suspension_infos (void) +{ + // Go through the array + if (this->handles_to_be_deleted_ > 0 || this->handles_to_be_resumed_ > 0) + { + size_t i = 0; + while (i < this->suspended_handles_) + { + // This stuff is necessary here, since we should not make + // the upcall until all the internal data structures have + // been updated. This is to protect against upcalls that + // try to deregister again. + ACE_HANDLE handle = ACE_INVALID_HANDLE; + ACE_Reactor_Mask masks = ACE_Event_Handler::NULL_MASK; + ACE_Event_Handler *event_handler = 0; + + // See if this entry is scheduled for deletion + if (this->current_suspended_info_[i].delete_entry_) + { + // Calling the method here will ensure that we + // will only call it once per deregistering . + // This is essential in the case when the will + // do something like delete itself and we have multiple + // threads in WFMO_Reactor. + // + // Make sure that the DONT_CALL mask is not set + masks = this->current_suspended_info_[i].close_masks_; + if (ACE_BIT_ENABLED (masks, ACE_Event_Handler::DONT_CALL) == 0) + { + // Grab the correct handle depending on the type entry + if (this->current_suspended_info_[i].io_entry_) + handle = this->current_suspended_info_[i].io_handle_; + else + handle = this->current_suspended_info_[i].event_handle_; + + // Upcall + event_handler = this->current_suspended_info_[i].event_handler_; + } + + // If created the event, we need to clean it up + if (this->current_suspended_info_[i].delete_event_) + ACE_OS::event_destroy (&this->current_suspended_info_[i].event_handle_); + + // Reduce count by one + --this->handles_to_be_deleted_; + } + + else if (this->current_suspended_info_[i].resume_entry_) + { + // Add to the end of the current handles set + this->current_handles_[this->max_handlep1_] = this->current_suspended_info_[i].event_handle_; + // Struct copy + this->current_info_[this->max_handlep1_].set (this->current_suspended_info_[i]); + ++this->max_handlep1_; + + // Reduce count by one + --this->handles_to_be_resumed_; + } + + // If an entry needs to be removed, either because it + // was deleted or resumed, remove it now before doing + // the upcall. + if (this->current_suspended_info_[i].resume_entry_ || + this->current_suspended_info_[i].delete_entry_) + { + size_t last_valid_slot = this->suspended_handles_ - 1; + // Net effect is that we're removing an entry and + // compressing the list from the end. So, if removing + // an entry from the middle, copy the last valid one to the + // removed slot. Reset the end and decrement the number + // of suspended handles. + if (i < last_valid_slot) + // Struct copy + this->current_suspended_info_[i] = + this->current_suspended_info_[last_valid_slot]; + this->current_suspended_info_[last_valid_slot].reset (); + --this->suspended_handles_; + } + else + { + // This current entry is not up for deletion or + // resumption. Proceed to the next entry in the + // suspended handles. + ++i; + } + + // Now that all internal structures have been updated, make + // the upcall. + if (event_handler != 0) + { + int requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + event_handler->handle_close (handle, masks); + + if (requires_reference_counting) + { + event_handler->remove_reference (); + } + } + } + } + + return 0; +} + +int +ACE_WFMO_Reactor_Handler_Repository::make_changes_in_to_be_added_infos (void) +{ + // Go through the arrays + for (size_t i = 0; i < this->handles_to_be_added_; ++i) + { + // This stuff is necessary here, since we should not make + // the upcall until all the internal data structures have + // been updated. This is to protect against upcalls that + // try to deregister again. + ACE_HANDLE handle = ACE_INVALID_HANDLE; + ACE_Reactor_Mask masks = ACE_Event_Handler::NULL_MASK; + ACE_Event_Handler *event_handler = 0; + + // See if this entry is scheduled for deletion + if (this->to_be_added_info_[i].delete_entry_) + { + // Calling the method here will ensure that we + // will only call it once per deregistering . + // This is essential in the case when the will + // do something like delete itself and we have multiple + // threads in WFMO_Reactor. + // + // Make sure that the DONT_CALL mask is not set + masks = this->to_be_added_info_[i].close_masks_; + if (ACE_BIT_ENABLED (masks, ACE_Event_Handler::DONT_CALL) == 0) + { + // Grab the correct handle depending on the type entry + if (this->to_be_added_info_[i].io_entry_) + handle = this->to_be_added_info_[i].io_handle_; + else + handle = this->to_be_added_info_[i].event_handle_; + + // Upcall + event_handler = this->to_be_added_info_[i].event_handler_; + } + + // If created the event, we need to clean it up + if (this->to_be_added_info_[i].delete_event_) + ACE_OS::event_destroy (&this->to_be_added_info_[i].event_handle_); + + // Reduce count by one + --this->handles_to_be_deleted_; + } + + // See if this entry is scheduled for suspension + else if (this->to_be_added_info_[i].suspend_entry_) + { + this->current_suspended_info_ [this->suspended_handles_].set (this->to_be_added_info_[i].event_handle_, + this->to_be_added_info_[i]); + // Increase number of suspended handles + ++this->suspended_handles_; + + // Reduce count by one + --this->handles_to_be_suspended_; + } + + // If neither of the two flags are on, add to current + else + { + // Add to the end of the current handles set + this->current_handles_[this->max_handlep1_] = this->to_be_added_info_[i].event_handle_; + // Struct copy + this->current_info_[this->max_handlep1_].set (this->to_be_added_info_[i]); + ++this->max_handlep1_; + } + + // Reset the + this->to_be_added_info_[i].reset (); + + // Now that all internal structures have been updated, make the + // upcall. + if (event_handler != 0) + { + int requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + event_handler->handle_close (handle, masks); + + if (requires_reference_counting) + { + event_handler->remove_reference (); + } + } + } + + // Since all to be added handles have been taken care of, reset the + // counter + this->handles_to_be_added_ = 0; + + return 0; +} + +void +ACE_WFMO_Reactor_Handler_Repository::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + size_t i = 0; + + ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Max size = %d\n"), + this->max_size_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Current info table\n\n"))); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\tSize = %d\n"), + this->max_handlep1_)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\tHandles to be suspended = %d\n"), + this->handles_to_be_suspended_)); + + for (i = 0; i < this->max_handlep1_; ++i) + this->current_info_[i].dump (this->current_handles_[i]); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n"))); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("To-be-added info table\n\n"))); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\tSize = %d\n"), + this->handles_to_be_added_)); + + for (i = 0; i < this->handles_to_be_added_; ++i) + this->to_be_added_info_[i].dump (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n"))); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Suspended info table\n\n"))); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\tSize = %d\n"), + this->suspended_handles_)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\tHandles to be resumed = %d\n"), + this->handles_to_be_resumed_)); + + for (i = 0; i < this->suspended_handles_; ++i) + this->current_suspended_info_[i].dump (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\n"))); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Total handles to be deleted = %d\n"), + this->handles_to_be_deleted_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +/************************************************************/ + +int +ACE_WFMO_Reactor::work_pending (const ACE_Time_Value &) +{ + ACE_NOTSUP_RETURN (-1); +} + +#if defined (ACE_WIN32_VC8) +# pragma warning (push) +# pragma warning (disable:4355) /* Use of 'this' in initializer list */ +# endif +ACE_WFMO_Reactor::ACE_WFMO_Reactor (ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq, + ACE_Reactor_Notify *notify) + : signal_handler_ (0), + delete_signal_handler_ (false), + timer_queue_ (0), + delete_timer_queue_ (false), + delete_handler_rep_ (false), + notify_handler_ (0), + delete_notify_handler_ (false), + lock_adapter_ (lock_), + handler_rep_ (*this), + // this event is initially signaled + ok_to_wait_ (1), + // this event is initially unsignaled + wakeup_all_threads_ (0), + // this event is initially unsignaled + waiting_to_change_state_ (0), + active_threads_ (0), + owner_ (ACE_Thread::self ()), + new_owner_ (0), + change_state_thread_ (0), + open_for_business_ (false), + deactivated_ (0) +{ + if (this->open (ACE_WFMO_Reactor::DEFAULT_SIZE, 0, sh, tq, 0, notify) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WFMO_Reactor"))); +} + +ACE_WFMO_Reactor::ACE_WFMO_Reactor (size_t size, + int unused, + ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq, + ACE_Reactor_Notify *notify) + : signal_handler_ (0), + delete_signal_handler_ (false), + timer_queue_ (0), + delete_timer_queue_ (false), + delete_handler_rep_ (false), + notify_handler_ (0), + delete_notify_handler_ (false), + lock_adapter_ (lock_), + handler_rep_ (*this), + // this event is initially signaled + ok_to_wait_ (1), + // this event is initially unsignaled + wakeup_all_threads_ (0), + // this event is initially unsignaled + waiting_to_change_state_ (0), + active_threads_ (0), + owner_ (ACE_Thread::self ()), + new_owner_ (0), + change_state_thread_ (0), + open_for_business_ (false), + deactivated_ (0) +{ + ACE_UNUSED_ARG (unused); + + if (this->open (size, 0, sh, tq, 0, notify) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WFMO_Reactor"))); +} +#if defined (ACE_WIN32_VC8) +# pragma warning (pop) +#endif + +int +ACE_WFMO_Reactor::current_info (ACE_HANDLE, size_t &) +{ + return -1; +} + +int +ACE_WFMO_Reactor::open (size_t size, + int unused, + ACE_Sig_Handler *sh, + ACE_Timer_Queue *tq, + int disable_notify_pipe, + ACE_Reactor_Notify *notify) +{ + ACE_UNUSED_ARG (unused); + ACE_UNUSED_ARG (disable_notify_pipe); + + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + // If we are already open, return -1 + if (this->open_for_business_) + return -1; + + // Timer Queue + if (this->delete_timer_queue_) + delete this->timer_queue_; + + if (tq == 0) + { + ACE_NEW_RETURN (this->timer_queue_, + ACE_Timer_Heap, + -1); + this->delete_timer_queue_ = true; + } + else + { + this->timer_queue_ = tq; + this->delete_timer_queue_ = false; + } + + // Signal Handler + if (this->delete_signal_handler_) + delete this->signal_handler_; + + if (sh == 0) + { + ACE_NEW_RETURN (this->signal_handler_, + ACE_Sig_Handler, + -1); + this->delete_signal_handler_ = true; + } + else + { + this->signal_handler_ = sh; + this->delete_signal_handler_ = false; + } + + // Setup the atomic wait array (used later in ) + this->atomic_wait_array_[0] = this->lock_.lock ().proc_mutex_; + this->atomic_wait_array_[1] = this->ok_to_wait_.handle (); + + // Prevent memory leaks when the ACE_WFMO_Reactor is reopened. + if (this->delete_handler_rep_) + { + if (this->handler_rep_.changes_required ()) + { + // Make necessary changes to the handler repository + this->handler_rep_.make_changes (); + // Turn off since all necessary changes + // have completed + this->wakeup_all_threads_.reset (); + } + + this->handler_rep_.~ACE_WFMO_Reactor_Handler_Repository (); + } + + // Open the handle repository. Two additional handles for internal + // purposes + if (this->handler_rep_.open (size + 2) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("opening handler repository")), + -1); + else + this->delete_handler_rep_ = true; + + if (this->notify_handler_ != 0 && this->delete_notify_handler_) + delete this->notify_handler_; + + this->notify_handler_ = notify; + + if (this->notify_handler_ == 0) + { + ACE_NEW_RETURN (this->notify_handler_, + ACE_WFMO_Reactor_Notify, + -1); + + if (this->notify_handler_ == 0) + return -1; + else + this->delete_notify_handler_ = true; + } + + /* NOTE */ + // The order of the following two registrations is very important + + // Open the notification handler + if (this->notify_handler_->open (this, this->timer_queue_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("opening notify handler ")), + -1); + + // Register for event + if (this->register_handler (&this->wakeup_all_threads_handler_, + this->wakeup_all_threads_.handle ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("registering thread wakeup handler")), + -1); + + // Since we have added two handles into the handler repository, + // update the + if (this->handler_rep_.changes_required ()) + { + // Make necessary changes to the handler repository + this->handler_rep_.make_changes (); + // Turn off since all necessary changes + // have completed + this->wakeup_all_threads_.reset (); + } + + // We are open for business + this->open_for_business_ = true; + + return 0; +} + +int +ACE_WFMO_Reactor::set_sig_handler (ACE_Sig_Handler *signal_handler) +{ + if (this->signal_handler_ != 0 && this->delete_signal_handler_) + delete this->signal_handler_; + this->signal_handler_ = signal_handler; + this->delete_signal_handler_ = false; + return 0; +} + +ACE_Timer_Queue * +ACE_WFMO_Reactor::timer_queue (void) const +{ + return this->timer_queue_; +} + +int +ACE_WFMO_Reactor::timer_queue (ACE_Timer_Queue *tq) +{ + if (this->timer_queue_ != 0 && this->delete_timer_queue_) + delete this->timer_queue_; + this->timer_queue_ = tq; + this->delete_timer_queue_ = false; + return 0; +} + +int +ACE_WFMO_Reactor::close (void) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + // If we are already closed, return error + if (!this->open_for_business_) + return -1; + + // We are now closed + this->open_for_business_ = false; + // This will unregister all handles + this->handler_rep_.close (); + + return 0; +} + +ACE_WFMO_Reactor::~ACE_WFMO_Reactor (void) +{ + // Assumption: No threads are left in the Reactor when this method + // is called (i.e., active_threads_ == 0) + + // Close down + this->close (); + + // Make necessary changes to the handler repository that we caused + // by . + this->handler_rep_.make_changes (); + + if (this->delete_timer_queue_) + { + delete this->timer_queue_; + this->timer_queue_ = 0; + this->delete_timer_queue_ = false; + } + + if (this->delete_signal_handler_) + { + delete this->signal_handler_; + this->signal_handler_ = 0; + this->delete_signal_handler_ = false; + } + + if (this->delete_notify_handler_) + { + delete this->notify_handler_; + this->notify_handler_ = 0; + this->delete_notify_handler_ = false; + } +} + +int +ACE_WFMO_Reactor::register_handler_i (ACE_HANDLE event_handle, + ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask new_masks) +{ + // If this is a Winsock 1 system, the underlying event assignment will + // not work, so don't try. Winsock 1 must use ACE_Select_Reactor for + // reacting to socket activity. + +#if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) + + ACE_UNUSED_ARG (event_handle); + ACE_UNUSED_ARG (io_handle); + ACE_UNUSED_ARG (event_handler); + ACE_UNUSED_ARG (new_masks); + ACE_NOTSUP_RETURN (-1); + +#else + + // Make sure that the is valid + if (io_handle == ACE_INVALID_HANDLE) + io_handle = event_handler->get_handle (); + + if (this->handler_rep_.invalid_handle (io_handle)) + { + errno = ERROR_INVALID_HANDLE; + return -1; + } + + long new_network_events = 0; + bool delete_event = false; + auto_ptr event; + + // Look up the repository to see if the is already + // there. + ACE_Reactor_Mask old_masks; + int found = this->handler_rep_.modify_network_events_i (io_handle, + new_masks, + old_masks, + new_network_events, + event_handle, + delete_event, + ACE_Reactor::ADD_MASK); + + // Check to see if the user passed us a valid event; If not then we + // need to create one + if (event_handle == ACE_INVALID_HANDLE) + { + // Note: don't change this since some C++ compilers have + // s that don't work properly... + auto_ptr tmp (new ACE_Auto_Event); + event = tmp; + event_handle = event->handle (); + delete_event = true; + } + + int result = ::WSAEventSelect ((SOCKET) io_handle, + event_handle, + new_network_events); + // If we had found the there is nothing more to do + if (found) + return result; + else if (result != SOCKET_ERROR && + this->handler_rep_.bind_i (1, + event_handler, + new_network_events, + io_handle, + event_handle, + delete_event) != -1) + { + // The was not found in the repository, add to + // the repository. + if (delete_event) + { + // Clear out the handle in the ACE_Auto_Event so that when + // it is destroyed, the handle isn't closed out from under + // the reactor. After setting it, running down the event + // (via auto_ptr<> event, above) at function return will + // cause an error because it'll try to close an invalid handle. + // To avoid that smashing the errno value, save the errno + // here, explicitly remove the event so the dtor won't do it + // again, then restore errno. + ACE_Errno_Guard guard (errno); + event->handle (ACE_INVALID_HANDLE); + event->remove (); + } + return 0; + } + else + return -1; + +#endif /* ACE_HAS_WINSOCK2 || ACE_HAS_WINSOCK2 == 0 */ + +} + +int +ACE_WFMO_Reactor::mask_ops_i (ACE_HANDLE io_handle, + ACE_Reactor_Mask new_masks, + int operation) +{ + // Make sure that the is valid + if (this->handler_rep_.invalid_handle (io_handle)) + return -1; + + long new_network_events = 0; + bool delete_event = false; + ACE_HANDLE event_handle = ACE_INVALID_HANDLE; + + // Look up the repository to see if the is already + // there. + ACE_Reactor_Mask old_masks; + int found = this->handler_rep_.modify_network_events_i (io_handle, + new_masks, + old_masks, + new_network_events, + event_handle, + delete_event, + operation); + if (found) + { + int result = ::WSAEventSelect ((SOCKET) io_handle, + event_handle, + new_network_events); + if (result == 0) + return old_masks; + else + return result; + } + else + return -1; +} + + + +int +ACE_WFMO_Reactor_Handler_Repository::modify_network_events_i (ACE_HANDLE io_handle, + ACE_Reactor_Mask new_masks, + ACE_Reactor_Mask &old_masks, + long &new_network_events, + ACE_HANDLE &event_handle, + bool &delete_event, + int operation) +{ + long *modified_network_events = &new_network_events; + int found = 0; + size_t i; + + // First go through the current entries + // + // Look for all entries in the current handles for matching handle + // (except those that have been scheduled for deletion) + for (i = 0; i < this->max_handlep1_ && !found; ++i) + if (io_handle == this->current_info_[i].io_handle_ && + !this->current_info_[i].delete_entry_) + { + found = 1; + modified_network_events = &this->current_info_[i].network_events_; + delete_event = this->current_info_[i].delete_event_; + event_handle = this->current_handles_[i]; + } + + // Then pass through the suspended handles + // + // Look for all entries in the suspended handles for matching handle + // (except those that have been scheduled for deletion) + for (i = 0; i < this->suspended_handles_ && !found; ++i) + if (io_handle == this->current_suspended_info_[i].io_handle_ && + !this->current_suspended_info_[i].delete_entry_) + { + found = 1; + modified_network_events = &this->current_suspended_info_[i].network_events_; + delete_event = this->current_suspended_info_[i].delete_event_; + event_handle = this->current_suspended_info_[i].event_handle_; + } + + // Then check the to_be_added handles + // + // Look for all entries in the to_be_added handles for matching + // handle (except those that have been scheduled for deletion) + for (i = 0; i < this->handles_to_be_added_ && !found; ++i) + if (io_handle == this->to_be_added_info_[i].io_handle_ && + !this->to_be_added_info_[i].delete_entry_) + { + found = 1; + modified_network_events = &this->to_be_added_info_[i].network_events_; + delete_event = this->to_be_added_info_[i].delete_event_; + event_handle = this->to_be_added_info_[i].event_handle_; + } + + old_masks = this->bit_ops (*modified_network_events, + new_masks, + operation); + + new_network_events = *modified_network_events; + + return found; +} + +ACE_Event_Handler * +ACE_WFMO_Reactor_Handler_Repository::find_handler (ACE_HANDLE handle) +{ + long existing_masks_ignored = 0; + return this->handler (handle, existing_masks_ignored); +} + +ACE_Event_Handler * +ACE_WFMO_Reactor_Handler_Repository::handler (ACE_HANDLE handle, + long &existing_masks) +{ + int found = 0; + size_t i = 0; + ACE_Event_Handler *event_handler = 0; + existing_masks = 0; + + // Look for the handle first + + // First go through the current entries + // + // Look for all entries in the current handles for matching handle + // (except those that have been scheduled for deletion) + for (i = 0; i < this->max_handlep1_ && !found; ++i) + if ((handle == this->current_info_[i].io_handle_ || + handle == this->current_handles_[i]) && + !this->current_info_[i].delete_entry_) + { + found = 1; + event_handler = this->current_info_[i].event_handler_; + existing_masks = this->current_info_[i].network_events_; + } + + // Then pass through the suspended handles + // + // Look for all entries in the suspended handles for matching handle + // (except those that have been scheduled for deletion) + for (i = 0; i < this->suspended_handles_ && !found; ++i) + if ((handle == this->current_suspended_info_[i].io_handle_ || + handle == this->current_suspended_info_[i].event_handle_) && + !this->current_suspended_info_[i].delete_entry_) + { + found = 1; + event_handler = this->current_suspended_info_[i].event_handler_; + existing_masks = this->current_suspended_info_[i].network_events_; + } + + // Then check the to_be_added handles + // + // Look for all entries in the to_be_added handles for matching + // handle (except those that have been scheduled for deletion) + for (i = 0; i < this->handles_to_be_added_ && !found; ++i) + if ((handle == this->to_be_added_info_[i].io_handle_ || + handle == this->to_be_added_info_[i].event_handle_) && + !this->to_be_added_info_[i].delete_entry_) + { + found = 1; + event_handler = this->to_be_added_info_[i].event_handler_; + existing_masks = this->to_be_added_info_[i].network_events_; + } + + if (event_handler) + event_handler->add_reference (); + + return event_handler; +} + +int +ACE_WFMO_Reactor_Handler_Repository::handler (ACE_HANDLE handle, + ACE_Reactor_Mask user_masks, + ACE_Event_Handler **user_event_handler) +{ + long existing_masks = 0; + int found = 0; + + ACE_Event_Handler_var safe_event_handler = + this->handler (handle, + existing_masks); + + if (safe_event_handler.handler ()) + found = 1; + + if (!found) + return -1; + + // Otherwise, make sure that the masks that the user is looking for + // are on. + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::READ_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_READ) && + !ACE_BIT_ENABLED (existing_masks, FD_CLOSE)) + found = 0; + + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::WRITE_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_WRITE)) + found = 0; + + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::EXCEPT_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_OOB)) + found = 0; + + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::ACCEPT_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_ACCEPT)) + found = 0; + + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::CONNECT_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_CONNECT)) + found = 0; + + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::QOS_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_QOS)) + found = 0; + + if (found && + ACE_BIT_ENABLED (user_masks, ACE_Event_Handler::GROUP_QOS_MASK)) + if (!ACE_BIT_ENABLED (existing_masks, FD_GROUP_QOS)) + found = 0; + + if (found && + user_event_handler) + *user_event_handler = safe_event_handler.release (); + + if (found) + return 0; + else + return -1; +} + +// Waits for and dispatches all events. Returns -1 on error, 0 if +// max_wait_time expired, or the number of events that were dispatched. +int +ACE_WFMO_Reactor::event_handling (ACE_Time_Value *max_wait_time, + int alertable) +{ + ACE_TRACE ("ACE_WFMO_Reactor::event_handling"); + + // Make sure we are not closed + if (!this->open_for_business_ || this->deactivated_) + return -1; + + // Stash the current time -- the destructor of this object will + // automatically compute how much time elapsed since this method was + // called. + ACE_Countdown_Time countdown (max_wait_time); + + int result; + do + { + // Check to see if it is ok to enter ::WaitForMultipleObjects + // This will acquire lock_> on success On failure, the + // lock will not be acquired + result = this->ok_to_wait (max_wait_time, alertable); + if (result != 1) + return result; + + // Increment the number of active threads + ++this->active_threads_; + + // Release the + this->lock_.release (); + + // Update the countdown to reflect time waiting to play with the + // mut and event. + countdown.update (); + + // Calculate timeout + int timeout = this->calculate_timeout (max_wait_time); + + // Wait for event to happen + DWORD wait_status = this->wait_for_multiple_events (timeout, + alertable); + + // Upcall + result = this->safe_dispatch (wait_status); + if (0 == result) + { + // wait_for_multiple_events timed out without dispatching + // anything. Because of rounding and conversion errors and + // such, it could be that the wait loop timed out, but + // the timer queue said it wasn't quite ready to expire a + // timer. In this case, max_wait_time won't have quite been + // reduced to 0, and we need to go around again. If max_wait_time + // is all the way to 0, just return, as the entire time the + // caller wanted to wait has been used up. + countdown.update (); // Reflect time waiting for events + if (0 == max_wait_time || max_wait_time->usec () == 0) + break; + } + } + while (result == 0); + + return result; +} + +int +ACE_WFMO_Reactor::ok_to_wait (ACE_Time_Value *max_wait_time, + int alertable) +{ + // Calculate the max time we should spend here + // + // Note: There is really no need to involve the here + // because even if a timeout in the does expire we + // will not be able to dispatch it + + // We need to wait for both the and event. + // If not on WinCE, use WaitForMultipleObjects() to wait for both atomically. + // On WinCE, the waitAll arg to WFMO must be false, so wait for the + // ok_to_wait_ event first (since that's likely to take the longest) then + // grab the lock and recheck the ok_to_wait_ event. When we can get them + // both, or there's an error/timeout, return. +#if defined (ACE_HAS_WINCE) + ACE_Time_Value timeout = ACE_OS::gettimeofday (); + if (max_wait_time != 0) + timeout += *max_wait_time; + while (1) + { + int status; + if (max_wait_time == 0) + status = this->ok_to_wait_.wait (); + else + status = this->ok_to_wait_.wait (&timeout); + if (status == -1) + return -1; + // The event is signaled, so it's ok to wait; grab the lock and + // recheck the event. If something has changed, restart the wait. + if (max_wait_time == 0) + status = this->lock_.acquire (); + else + status = this->lock_.acquire (timeout); + if (status == -1) + return -1; + + // Have the lock_, now re-check the event. If it's not signaled, + // another thread changed something so go back and wait again. + ACE_Time_Value poll_it = ACE_OS::gettimeofday (); + if (this->ok_to_wait_.wait (&poll_it) == 0) + break; + this->lock_.release (); + } + return 1; + +#else + int timeout = max_wait_time == 0 ? INFINITE : max_wait_time->msec (); + DWORD result = 0; + while (1) + { +# if defined (ACE_HAS_PHARLAP) + // PharLap doesn't implement WaitForMultipleObjectsEx, and doesn't + // do async I/O, so it's not needed in this case anyway. + result = ::WaitForMultipleObjects (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), + this->atomic_wait_array_, + TRUE, + timeout); + + if (result != WAIT_IO_COMPLETION) + break; + +# else + result = ::WaitForMultipleObjectsEx (sizeof this->atomic_wait_array_ / sizeof (ACE_HANDLE), + this->atomic_wait_array_, + TRUE, + timeout, + alertable); + + if (result != WAIT_IO_COMPLETION) + break; + +# endif /* ACE_HAS_PHARLAP */ + } + + switch (result) + { + case WAIT_TIMEOUT: + errno = ETIME; + return 0; + case WAIT_FAILED: + case WAIT_ABANDONED_0: + ACE_OS::set_errno_to_last_error (); + return -1; + default: + break; + } + + // It is ok to enter ::WaitForMultipleObjects + return 1; +#endif /* ACE_HAS_WINCE */ +} + +DWORD +ACE_WFMO_Reactor::wait_for_multiple_events (int timeout, + int alertable) +{ + // Wait for any of handles_ to be active, or until timeout expires. + // If is enabled allow asynchronous completion of + // ReadFile and WriteFile operations. + +#if defined (ACE_HAS_PHARLAP) || defined (ACE_HAS_WINCE) + // PharLap doesn't do async I/O and doesn't implement + // WaitForMultipleObjectsEx, so use WaitForMultipleObjects. + ACE_UNUSED_ARG (alertable); + return ::WaitForMultipleObjects (this->handler_rep_.max_handlep1 (), + this->handler_rep_.handles (), + FALSE, + timeout); +#else + return ::WaitForMultipleObjectsEx (this->handler_rep_.max_handlep1 (), + this->handler_rep_.handles (), + FALSE, + timeout, + alertable); +#endif /* ACE_HAS_PHARLAP */ +} + +DWORD +ACE_WFMO_Reactor::poll_remaining_handles (DWORD slot) +{ + return ::WaitForMultipleObjects (this->handler_rep_.max_handlep1 () - slot, + this->handler_rep_.handles () + slot, + FALSE, + 0); +} + +int +ACE_WFMO_Reactor::calculate_timeout (ACE_Time_Value *max_wait_time) +{ + ACE_Time_Value *time = 0; + if (this->owner_ == ACE_Thread::self ()) + time = this->timer_queue_->calculate_timeout (max_wait_time); + else + time = max_wait_time; + + if (time == 0) + return INFINITE; + else + return time->msec (); +} + + +int +ACE_WFMO_Reactor::expire_timers (void) +{ + // If "owner" thread + if (ACE_Thread::self () == this->owner_) + // expire all pending timers. + return this->timer_queue_->expire (); + + else + // Nothing to expire + return 0; +} + +int +ACE_WFMO_Reactor::dispatch (DWORD wait_status) +{ + int handlers_dispatched = 0; + + // Expire timers + handlers_dispatched += this->expire_timers (); + + switch (wait_status) + { + case WAIT_FAILED: // Failure. + ACE_OS::set_errno_to_last_error (); + return -1; + + case WAIT_TIMEOUT: // Timeout. + errno = ETIME; + return handlers_dispatched; + +#ifndef ACE_HAS_WINCE + case WAIT_IO_COMPLETION: // APC. + return handlers_dispatched; +#endif // ACE_HAS_WINCE + + default: // Dispatch. + // We'll let dispatch worry about abandoned mutes. + handlers_dispatched += this->dispatch_handles (wait_status); + return handlers_dispatched; + } +} + +// Dispatches any active handles from to +// , polling through our handle set looking +// for active handles. +int +ACE_WFMO_Reactor::dispatch_handles (DWORD wait_status) +{ + // dispatch_slot is the absolute slot. Only += is used to + // increment it. + DWORD dispatch_slot = 0; + + // Cache this value, this is the absolute value. + DWORD max_handlep1 = this->handler_rep_.max_handlep1 (); + + // nCount starts off at , this is a transient count of + // handles last waited on. + DWORD nCount = max_handlep1; + + for (int number_of_handlers_dispatched = 1; + ; + ++number_of_handlers_dispatched) + { + const bool ok = ( +#if ! defined(__BORLANDC__) \ + && !defined (ghs) \ + && !defined (__MINGW32__) \ + && !(defined (_MSC_VER) && _MSC_VER >= 1300) + // wait_status is unsigned in Borland, Green Hills, + // mingw32 and MSVC++ >= 7.1. + // This >= is always true, with a warning. + wait_status >= WAIT_OBJECT_0 && +#endif + wait_status <= (WAIT_OBJECT_0 + nCount)); + + if (ok) + dispatch_slot += wait_status - WAIT_OBJECT_0; + else + // Otherwise, a handle was abandoned. + dispatch_slot += wait_status - WAIT_ABANDONED_0; + + // Dispatch handler + if (this->dispatch_handler (dispatch_slot, max_handlep1) == -1) + return -1; + + // Increment slot + ++dispatch_slot; + + // We're done. + if (dispatch_slot >= max_handlep1) + return number_of_handlers_dispatched; + + // Readjust nCount + nCount = max_handlep1 - dispatch_slot; + + // Check the remaining handles + wait_status = this->poll_remaining_handles (dispatch_slot); + switch (wait_status) + { + case WAIT_FAILED: // Failure. + ACE_OS::set_errno_to_last_error (); + /* FALLTHRU */ + case WAIT_TIMEOUT: + // There are no more handles ready, we can return. + return number_of_handlers_dispatched; + } + } +} + +int +ACE_WFMO_Reactor::dispatch_handler (DWORD slot, + DWORD max_handlep1) +{ + // Check if there are window messages that need to be dispatched + if (slot == max_handlep1) + return this->dispatch_window_messages (); + + // Dispatch the handler if it has not been scheduled for deletion. + // Note that this is a very week test if there are multiple threads + // dispatching this slot as no locks are held here. Generally, you + // do not want to do something like deleting the this pointer in + // handle_close() if you have registered multiple times and there is + // more than one thread in WFMO_Reactor->handle_events(). + else if (!this->handler_rep_.scheduled_for_deletion (slot)) + { + ACE_HANDLE event_handle = *(this->handler_rep_.handles () + slot); + + if (this->handler_rep_.current_info ()[slot].io_entry_) + return this->complex_dispatch_handler (slot, + event_handle); + else + return this->simple_dispatch_handler (slot, + event_handle); + } + else + // The handle was scheduled for deletion, so we will skip it. + return 0; +} + +int +ACE_WFMO_Reactor::simple_dispatch_handler (DWORD slot, + ACE_HANDLE event_handle) +{ + // This dispatch is used for non-I/O entires + + // Assign the ``signaled'' HANDLE so that callers can get it. + // siginfo_t is an ACE - specific fabrication. Constructor exists. + siginfo_t sig (event_handle); + + ACE_Event_Handler *event_handler = + this->handler_rep_.current_info ()[slot].event_handler_; + + int requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + if (requires_reference_counting) + { + event_handler->add_reference (); + } + + // Upcall + if (event_handler->handle_signal (0, &sig) == -1) + this->handler_rep_.unbind (event_handle, + ACE_Event_Handler::NULL_MASK); + + // Call remove_reference() if needed. + if (requires_reference_counting) + { + event_handler->remove_reference (); + } + + return 0; +} + +int +ACE_WFMO_Reactor::complex_dispatch_handler (DWORD slot, + ACE_HANDLE event_handle) +{ + // This dispatch is used for I/O entires. + + ACE_WFMO_Reactor_Handler_Repository::Current_Info ¤t_info = + this->handler_rep_.current_info ()[slot]; + + WSANETWORKEVENTS events; + ACE_Reactor_Mask problems = ACE_Event_Handler::NULL_MASK; + if (::WSAEnumNetworkEvents ((SOCKET) current_info.io_handle_, + event_handle, + &events) == SOCKET_ERROR) + problems = ACE_Event_Handler::ALL_EVENTS_MASK; + else + { + // Prepare for upcalls. Clear the bits from representing + // events the handler is not interested in. If there are any left, + // do the upcall(s). upcall will replace events.lNetworkEvents + // with bits representing any functions that requested a repeat + // callback before checking handles again. In this case, continue + // to call back unless the handler is unregistered as a result of + // one of the upcalls. The way this is written, the upcalls will + // keep being done even if one or more upcalls reported problems. + // In practice this may turn out not so good, but let's see. If any + // problems, please notify Steve Huston + // before or after you change this code. + events.lNetworkEvents &= current_info.network_events_; + while (events.lNetworkEvents != 0) + { + ACE_Event_Handler *event_handler = + current_info.event_handler_; + + int reference_counting_required = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + // Call add_reference() if needed. + if (reference_counting_required) + { + event_handler->add_reference (); + } + + // Upcall + problems |= this->upcall (current_info.event_handler_, + current_info.io_handle_, + events); + + // Call remove_reference() if needed. + if (reference_counting_required) + { + event_handler->remove_reference (); + } + + if (this->handler_rep_.scheduled_for_deletion (slot)) + break; + } + } + + if (problems != ACE_Event_Handler::NULL_MASK + && !this->handler_rep_.scheduled_for_deletion (slot) ) + this->handler_rep_.unbind (event_handle, problems); + + return 0; +} + +ACE_Reactor_Mask +ACE_WFMO_Reactor::upcall (ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + WSANETWORKEVENTS &events) +{ + // This method figures out what exactly has happened to the socket + // and then calls appropriate methods. + ACE_Reactor_Mask problems = ACE_Event_Handler::NULL_MASK; + + // Go through the events and do the indicated upcalls. If the handler + // doesn't want to be called back, clear the bit for that event. + // At the end, set the bits back to to request a repeat call. + + long actual_events = events.lNetworkEvents; + int action; + + if (ACE_BIT_ENABLED (actual_events, FD_WRITE)) + { + action = event_handler->handle_output (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_WRITE); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::WRITE_MASK); + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_CONNECT)) + { + if (events.iErrorCode[FD_CONNECT_BIT] == 0) + { + // Successful connect + action = event_handler->handle_output (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_CONNECT); + if (action == -1) + ACE_SET_BITS (problems, + ACE_Event_Handler::CONNECT_MASK); + } + } + // Unsuccessful connect + else + { + action = event_handler->handle_input (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_CONNECT); + if (action == -1) + ACE_SET_BITS (problems, + ACE_Event_Handler::CONNECT_MASK); + } + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_OOB)) + { + action = event_handler->handle_exception (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_OOB); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::EXCEPT_MASK); + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_READ)) + { + action = event_handler->handle_input (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_READ); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::READ_MASK); + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_CLOSE) + && ACE_BIT_DISABLED (problems, ACE_Event_Handler::READ_MASK)) + { + action = event_handler->handle_input (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_CLOSE); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::READ_MASK); + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_ACCEPT)) + { + action = event_handler->handle_input (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_ACCEPT); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::ACCEPT_MASK); + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_QOS)) + { + action = event_handler->handle_qos (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_QOS); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::QOS_MASK); + } + } + + if (ACE_BIT_ENABLED (actual_events, FD_GROUP_QOS)) + { + action = event_handler->handle_group_qos (io_handle); + if (action <= 0) + { + ACE_CLR_BITS (actual_events, FD_GROUP_QOS); + if (action == -1) + ACE_SET_BITS (problems, ACE_Event_Handler::GROUP_QOS_MASK); + } + } + + events.lNetworkEvents = actual_events; + return problems; +} + + +int +ACE_WFMO_Reactor::update_state (void) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1); + + // Decrement active threads + --this->active_threads_; + + // Check if the state of the handler repository has changed or new + // owner has to be set + if (this->handler_rep_.changes_required () || this->new_owner ()) + { + if (this->change_state_thread_ == 0) + // Try to become the thread which will be responsible for the + // changes + { + this->change_state_thread_ = ACE_Thread::self (); + // Make sure no new threads are allowed to enter + this->ok_to_wait_.reset (); + + if (this->active_threads_ > 0) + // Check for other active threads + { + // Wake up all other threads + this->wakeup_all_threads_.signal (); + // Release + monitor.release (); + // Go to sleep waiting for all other threads to get done + this->waiting_to_change_state_.wait (); + // Re-acquire again + monitor.acquire (); + } + + // Note that make_changes() calls into user code which can + // request other changes. So keep looping until all + // requested changes are completed. + while (this->handler_rep_.changes_required ()) + // Make necessary changes to the handler repository + this->handler_rep_.make_changes (); + if (this->new_owner ()) + // Update the owner + this->change_owner (); + // Turn off + this->wakeup_all_threads_.reset (); + // Let everyone know that it is ok to go ahead + this->ok_to_wait_.signal (); + // Reset this flag + this->change_state_thread_ = 0; + } + else if (this->active_threads_ == 0) + // This thread did not get a chance to become the change + // thread. If it is the last one out, it will wakeup the + // change thread + this->waiting_to_change_state_.signal (); + } + // This is if we were woken up explicitily by the user and there are + // no state changes required. + else if (this->active_threads_ == 0) + // Turn off + this->wakeup_all_threads_.reset (); + + return 0; +} + +void +ACE_WFMO_Reactor::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_WFMO_Reactor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Count of currently active threads = %d\n"), + this->active_threads_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ID of owner thread = %d\n"), + this->owner_)); + + this->handler_rep_.dump (); + this->signal_handler_->dump (); + this->timer_queue_->dump (); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_WFMO_Reactor_Notify::dispatch_notifications (int & /*number_of_active_handles*/, + ACE_Handle_Set & /*rd_mask*/) +{ + return -1; +} + +int +ACE_WFMO_Reactor_Notify::is_dispatchable (ACE_Notification_Buffer & /*buffer*/) +{ + return 0; +} + +ACE_HANDLE +ACE_WFMO_Reactor_Notify::notify_handle (void) +{ + return ACE_INVALID_HANDLE; +} + +int +ACE_WFMO_Reactor_Notify::read_notify_pipe (ACE_HANDLE , + ACE_Notification_Buffer &) +{ + return 0; +} + +int +ACE_WFMO_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer &) +{ + return 0; +} + +int +ACE_WFMO_Reactor_Notify::close (void) +{ + return -1; +} + +ACE_WFMO_Reactor_Notify::ACE_WFMO_Reactor_Notify (size_t max_notifies) + : timer_queue_ (0), + message_queue_ (max_notifies * sizeof (ACE_Notification_Buffer), + max_notifies * sizeof (ACE_Notification_Buffer)), + max_notify_iterations_ (-1) +{ +} + +int +ACE_WFMO_Reactor_Notify::open (ACE_Reactor_Impl *wfmo_reactor, + ACE_Timer_Queue *timer_queue, + int ignore_notify) +{ + ACE_UNUSED_ARG (ignore_notify); + timer_queue_ = timer_queue; + return wfmo_reactor->register_handler (this); +} + +ACE_HANDLE +ACE_WFMO_Reactor_Notify::get_handle (void) const +{ + return this->wakeup_one_thread_.handle (); +} + +// Handle all pending notifications. + +int +ACE_WFMO_Reactor_Notify::handle_signal (int signum, + siginfo_t *siginfo, + ucontext_t *) +{ + ACE_UNUSED_ARG (signum); + + // Just check for sanity... + if (siginfo->si_handle_ != this->wakeup_one_thread_.handle ()) + return -1; + + // This will get called when wakeup_one_thread_> event + // is signaled. + // ACE_DEBUG ((LM_DEBUG, + // ACE_TEXT ("(%t) waking up to handle internal notifications\n"))); + + for (int i = 1; ; ++i) + { + ACE_Message_Block *mb = 0; + // Copy ACE_Time_Value::zero since dequeue_head will modify it. + ACE_Time_Value zero_timeout (ACE_Time_Value::zero); + if (this->message_queue_.dequeue_head (mb, &zero_timeout) == -1) + { + if (errno == EWOULDBLOCK) + // We've reached the end of the processing, return + // normally. + return 0; + else + return -1; // Something weird happened... + } + else + { + ACE_Notification_Buffer *buffer = + reinterpret_cast (mb->base ()); + + // If eh == 0 then we've got major problems! Otherwise, we + // need to dispatch the appropriate handle_* method on the + // ACE_Event_Handler pointer we've been passed. + + if (buffer->eh_ != 0) + { + ACE_Event_Handler *event_handler = + buffer->eh_; + + bool const requires_reference_counting = + event_handler->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; + + int result = 0; + + switch (buffer->mask_) + { + case ACE_Event_Handler::READ_MASK: + case ACE_Event_Handler::ACCEPT_MASK: + result = event_handler->handle_input (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::WRITE_MASK: + result = event_handler->handle_output (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::EXCEPT_MASK: + result = event_handler->handle_exception (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::QOS_MASK: + result = event_handler->handle_qos (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::GROUP_QOS_MASK: + result = event_handler->handle_group_qos (ACE_INVALID_HANDLE); + break; + default: + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("invalid mask = %d\n"), + buffer->mask_)); + break; + } + + if (result == -1) + event_handler->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::EXCEPT_MASK); + + if (requires_reference_counting) + { + event_handler->remove_reference (); + } + } + + // Make sure to delete the memory regardless of success or + // failure! + mb->release (); + + // Bail out if we've reached the . + // Note that by default is -1, so + // we'll loop until we're done. + if (i == this->max_notify_iterations_) + { + // If there are still notification in the queue, we need + // to wake up again + if (!this->message_queue_.is_empty ()) + this->wakeup_one_thread_.signal (); + + // Break the loop as we have reached max_notify_iterations_ + return 0; + } + } + } +} + +// Notify the WFMO_Reactor, potentially enqueueing the +// for subsequent processing in the WFMO_Reactor +// thread of control. + +int +ACE_WFMO_Reactor_Notify::notify (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + ACE_Time_Value *timeout) +{ + if (event_handler != 0) + { + ACE_Message_Block *mb = 0; + ACE_NEW_RETURN (mb, + ACE_Message_Block (sizeof (ACE_Notification_Buffer)), + -1); + + ACE_Notification_Buffer *buffer = + (ACE_Notification_Buffer *) mb->base (); + buffer->eh_ = event_handler; + buffer->mask_ = mask; + + // Convert from relative time to absolute time by adding the + // current time of day. This is what + // expects. + if (timeout != 0) + *timeout += timer_queue_->gettimeofday (); + + if (this->message_queue_.enqueue_tail + (mb, timeout) == -1) + { + mb->release (); + return -1; + } + + event_handler->add_reference (); + } + + return this->wakeup_one_thread_.signal (); +} + +void +ACE_WFMO_Reactor_Notify::max_notify_iterations (int iterations) +{ + ACE_TRACE ("ACE_WFMO_Reactor_Notify::max_notify_iterations"); + // Must always be > 0 or < 0 to optimize the loop exit condition. + if (iterations == 0) + iterations = 1; + + this->max_notify_iterations_ = iterations; +} + +int +ACE_WFMO_Reactor_Notify::max_notify_iterations (void) +{ + ACE_TRACE ("ACE_WFMO_Reactor_Notify::max_notify_iterations"); + return this->max_notify_iterations_; +} + +int +ACE_WFMO_Reactor_Notify::purge_pending_notifications (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_WFMO_Reactor_Notify::purge_pending_notifications"); + + // Go over message queue and take out all the matching event + // handlers. If eh == 0, purge all. Note that reactor notifies (no + // handler specified) are never purged, as this may lose a needed + // notify the reactor queued for itself. + + if (this->message_queue_.is_empty ()) + return 0; + + // Guard against new and/or delivered notifications while purging. + // WARNING!!! The use of the notification queue's lock object for + // this guard makes use of the knowledge that on Win32, the mutex + // protecting the queue is really a CriticalSection, which is + // recursive. This is how we can get away with locking it down here + // and still calling member functions on the queue object. + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, monitor, this->message_queue_.lock(), -1); + + // first, copy all to our own local queue. Since we've locked everyone out + // of here, there's no need to use any synchronization on this queue. + ACE_Message_Queue local_queue; + + size_t queue_size = this->message_queue_.message_count (); + int number_purged = 0; + + size_t index; + + for (index = 0; index < queue_size; ++index) + { + ACE_Message_Block *mb = 0; + if (-1 == this->message_queue_.dequeue_head (mb)) + return -1; // This shouldn't happen... + + ACE_Notification_Buffer *buffer = + reinterpret_cast (mb->base ()); + + // If this is not a Reactor notify (it is for a particular handler), + // and it matches the specified handler (or purging all), + // and applying the mask would totally eliminate the notification, then + // release it and count the number purged. + if ((0 != buffer->eh_) && + (0 == eh || eh == buffer->eh_) && + ACE_BIT_DISABLED (buffer->mask_, ~mask)) // the existing notification mask + // is left with nothing when + // applying the mask + { + ACE_Event_Handler *event_handler = buffer->eh_; + + event_handler->remove_reference (); + + mb->release (); + ++number_purged; + } + else + { + // To preserve it, move it to the local_queue. But first, if + // this is not a Reactor notify (it is for a + // particularhandler), and it matches the specified handler + // (or purging all), then apply the mask + if ((0 != buffer->eh_) && + (0 == eh || eh == buffer->eh_)) + ACE_CLR_BITS(buffer->mask_, mask); + if (-1 == local_queue.enqueue_head (mb)) + return -1; + } + } + + if (this->message_queue_.message_count ()) + { // Should be empty! + ACE_ASSERT (0); + return -1; + } + + // Now copy back from the local queue to the class queue, taking + // care to preserve the original order... + queue_size = local_queue.message_count (); + for (index = 0; index < queue_size; ++index) + { + ACE_Message_Block *mb = 0; + if (-1 == local_queue.dequeue_head (mb)) + { + ACE_ASSERT (0); + return -1; + } + + if (-1 == this->message_queue_.enqueue_head (mb)) + { + ACE_ASSERT (0); + return -1; + } + } + + return number_purged; +} + +void +ACE_WFMO_Reactor_Notify::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_WFMO_Reactor_Notify::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->timer_queue_->dump (); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Max. iteration: %d\n"), + this->max_notify_iterations_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +void +ACE_WFMO_Reactor::max_notify_iterations (int iterations) +{ + ACE_TRACE ("ACE_WFMO_Reactor::max_notify_iterations"); + ACE_GUARD (ACE_Process_Mutex, monitor, this->lock_); + + // Must always be > 0 or < 0 to optimize the loop exit condition. + this->notify_handler_->max_notify_iterations (iterations); +} + +int +ACE_WFMO_Reactor::max_notify_iterations (void) +{ + ACE_TRACE ("ACE_WFMO_Reactor::max_notify_iterations"); + ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1); + + return this->notify_handler_->max_notify_iterations (); +} + +int +ACE_WFMO_Reactor::purge_pending_notifications (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_WFMO_Reactor::purge_pending_notifications"); + if (this->notify_handler_ == 0) + return 0; + else + return this->notify_handler_->purge_pending_notifications (eh, mask); +} + +int +ACE_WFMO_Reactor::resumable_handler (void) +{ + ACE_TRACE ("ACE_WFMO_Reactor::resumable_handler"); + return 0; +} + + +// No-op WinSOCK2 methods to help WFMO_Reactor compile +#if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) +int +WSAEventSelect (SOCKET /* s */, + WSAEVENT /* hEventObject */, + long /* lNetworkEvents */) +{ + return -1; +} + +int +WSAEnumNetworkEvents (SOCKET /* s */, + WSAEVENT /* hEventObject */, + LPWSANETWORKEVENTS /* lpNetworkEvents */) +{ + return -1; +} +#endif /* !defined ACE_HAS_WINSOCK2 */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_WIN32 */ diff --git a/dep/ACE_wrappers/ace/WFMO_Reactor.h b/dep/ACE_wrappers/ace/WFMO_Reactor.h new file mode 100644 index 000000000..1bbf207ec --- /dev/null +++ b/dep/ACE_wrappers/ace/WFMO_Reactor.h @@ -0,0 +1,1368 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file WFMO_Reactor.h + * + * $Id: WFMO_Reactor.h 81138 2008-03-28 09:18:15Z johnnyw $ + * + * @author Irfan Pyarali + * @author Tim Harrison + * @author Doug Schmidt + */ +//============================================================================= + +#ifndef ACE_WFMO_REACTOR_H +#define ACE_WFMO_REACTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_WIN32) + +#include "ace/Signal.h" +#include "ace/Timer_Queue.h" +#include "ace/Event_Handler.h" +#include "ace/Auto_Event.h" +#include "ace/Manual_Event.h" +#include "ace/Condition_Thread_Mutex.h" +#include "ace/Lock_Adapter_T.h" +#include "ace/Reactor_Impl.h" +#include "ace/Message_Queue.h" +#include "ace/Process_Mutex.h" + +// If we don't have WinSOCK2, we need these defined +#if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) +/* + * WinSock 2 extension -- bit values and indices for FD_XXX network events + */ +#define FD_READ_BIT 0 +#define FD_WRITE_BIT 1 +#define FD_OOB_BIT 2 +#define FD_ACCEPT_BIT 3 +#define FD_CONNECT_BIT 4 +#define FD_CLOSE_BIT 5 +#define FD_QOS_BIT 6 +#define FD_GROUP_QOS_BIT 7 + +#define FD_QOS (1 << FD_QOS_BIT) +#define FD_GROUP_QOS (1 << FD_GROUP_QOS_BIT) + +#define FD_MAX_EVENTS 8 +#define FD_ALL_EVENTS ((1 << FD_MAX_EVENTS) - 1) + +#define WSAEVENT HANDLE + +typedef struct _WSANETWORKEVENTS +{ + long lNetworkEvents; + int iErrorCode[FD_MAX_EVENTS]; +} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS; + +int WSAEventSelect (SOCKET s, + WSAEVENT hEventObject, + long lNetworkEvents); + +int WSAEnumNetworkEvents (SOCKET s, + WSAEVENT hEventObject, + LPWSANETWORKEVENTS lpNetworkEvents); + +#endif /* !defined ACE_HAS_WINSOCK2 */ + +class ACE_WFMO_Reactor_Test; // Must be out of versioned namespace. + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl. +class ACE_WFMO_Reactor; +class ACE_Handle_Set; + +/** + * @class ACE_Wakeup_All_Threads_Handler + * + * @brief This is a helper class whose sole purpose is to handle events + * on wakeup_all_threads_> + */ +class ACE_Export ACE_Wakeup_All_Threads_Handler : public ACE_Event_Handler +{ +public: + /// Called when the wakeup_all_threads_> + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); +}; + +/** + * @class ACE_WFMO_Reactor_Handler_Repository + * + * @internal This class is for internal ACE use only. + * + * @brief Used to map ACE_HANDLEs onto the appropriate + * ACE_Event_Handler * and other information. + */ +class ACE_Export ACE_WFMO_Reactor_Handler_Repository +{ +public: + friend class ACE_WFMO_Reactor; + friend class ACE_WFMO_Reactor_Test; + + /** + * @class Common_Info + * + * @brief This struct contains the necessary information for every + * entry. The reason the event is not in this + * structure is because we need to pass an event array into + * WaitForMultipleObjects and therefore keeping the events + * seperate makes sense. + */ + class Common_Info + { + public: + /// This indicates whether this entry is for I/O or for a regular + /// event + bool io_entry_; + + /// The assosiated + ACE_Event_Handler *event_handler_; + + /// The I/O handle related to the . This entry is + /// only valid if the flag is true. + ACE_HANDLE io_handle_; + + /** + * This is the set of events that the is + * interested in. This entry is only valid if the flag + * is true. + */ + long network_events_; + + /** + * This flag indicates that created the event on + * behalf of the user. Therefore we need to clean this up when the + * removes itself from . This entry + * is only valid if the flag is true. + */ + bool delete_event_; + + /// This is set when the entry needed to be deleted. + bool delete_entry_; + + /** + * These are the masks related to for the + * . This is only valid when is + * set. + */ + ACE_Reactor_Mask close_masks_; + + /// Constructor used for initializing the structure + Common_Info (void); + + /// Reset the state of the structure + void reset (void); + + /// Set the structure to these new values + void set (bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry, + ACE_Reactor_Mask close_masks); + + /// Set the structure to these new values + void set (Common_Info &common_info); + + /// Dump the state of an object. + void dump (void) const; + }; + + /** + * @class Current_Info + * + * @brief This structure inherits from the common structure to add + * information for current entries. + */ + class Current_Info : public Common_Info + { + public: + /// This is set when the entry needed to be suspended. + bool suspend_entry_; + + /// Default constructor + Current_Info (void); + + /// Reset the state of the structure + void reset (void); + + /// Set the structure to these new values + void set (bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry = false, + ACE_Reactor_Mask close_masks = ACE_Event_Handler::NULL_MASK, + bool suspend_entry = false); + + /// Set the structure to these new values + void set (Common_Info &common_info, + bool suspend_entry = false); + + /// Dump the state of an object. + void dump (ACE_HANDLE event_handle) const; + }; + + /** + * @class To_Be_Added_Info + * + * @brief This structure inherits from the common structure to add + * information for entries. + */ + class To_Be_Added_Info : public Common_Info + { + public: + /// Handle for the event + ACE_HANDLE event_handle_; + + /// This is set when the entry needed to be suspended. + bool suspend_entry_; + + /// Default constructor + To_Be_Added_Info (void); + + /// Reset the state of the structure + void reset (void); + + /// Set the structure to these new values + void set (ACE_HANDLE event_handle, + bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry = false, + ACE_Reactor_Mask close_masks = ACE_Event_Handler::NULL_MASK, + bool suspend_entry = false); + + /// Set the structure to these new values + void set (ACE_HANDLE event_handle, + Common_Info &common_info, + bool suspend_entry = false); + + /// Dump the state of an object. + void dump (void) const; + }; + + /** + * @class Suspended_Info + * + * @brief This structure inherits from the common structure to add + * information for suspended entries. + */ + class Suspended_Info : public Common_Info + { + public: + /// Handle for the event + ACE_HANDLE event_handle_; + + /// This is set when the entry needed to be resumed. + bool resume_entry_; + + /// Constructor used for initializing the structure + Suspended_Info (void); + + /// Reset the state of the structure + void reset (void); + + /// Set the structure to these new values + void set (ACE_HANDLE event_handle, + bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry = false, + ACE_Reactor_Mask close_masks = 0, + bool resume_entry = false); + + /// Set the structure to these new values + void set (ACE_HANDLE event_handle, + Common_Info &common_info, + bool resume_entry = false); + + /// Dump the state of an object. + void dump (void) const; + }; + + /// Constructor. + ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor); + + /// Destructor. + virtual ~ACE_WFMO_Reactor_Handler_Repository (void); + + /// Initialize the repository of the approriate @a size. + int open (size_t size); + + /// Close down the handler repository. + int close (void); + + // = Search structure operations. + + /// Bind the to the ACE_HANDLE. This is for + /// the simple event entry. + int bind (ACE_HANDLE, ACE_Event_Handler *); + + /// Insert I/O entry into the system. This method + /// assumes that the lock are head *before* this method is invoked. + int bind_i (bool io_entry, + ACE_Event_Handler *event_handler, + long network_events, + ACE_HANDLE io_handle, + ACE_HANDLE event_handle, + bool delete_event); + + /// Remove the binding of ACE_HANDLE in accordance with the @a mask. + int unbind (ACE_HANDLE, + ACE_Reactor_Mask mask); + + /// Non-lock-grabbing version of + int unbind_i (ACE_HANDLE, + ACE_Reactor_Mask mask, + bool &changes_required); + + /// Remove all bindings of tuples. + void unbind_all (void); + + // = Sanity checking. + + // Check the to make sure it's a valid ACE_HANDLE + int invalid_handle (ACE_HANDLE handle) const; + + // = Accessors. + /// Maximum ACE_HANDLE value, plus 1. + DWORD max_handlep1 (void) const; + + /// Pointer to the beginning of the current array of ACE_HANDLE + /// *'s. + ACE_HANDLE *handles (void) const; + + /// Pointer to the beginning of the current array of + /// ACE_Event_Handler *'s. + Current_Info *current_info (void) const; + + /// Check if changes to the handle set are required. + virtual bool changes_required (void); + + /// Make changes to the handle set + virtual int make_changes (void); + + /// Check to see if @a slot has been scheduled for deletion + int scheduled_for_deletion (size_t slot) const; + + /** + * This method is used to calculate the network mask after a mask_op + * request to . Note that because the + * may already be in the handler repository, we may have to find the + * old event and the old network events + */ + int modify_network_events_i (ACE_HANDLE io_handle, + ACE_Reactor_Mask new_masks, + ACE_Reactor_Mask &old_masks, + long &new_network_events, + ACE_HANDLE &event_handle, + bool &delete_event, + int operation); + + /// This method is used to change the network mask left (if any) + /// after a remove request to + ACE_Reactor_Mask bit_ops (long &existing_masks, + ACE_Reactor_Mask to_be_removed_masks, + int operation); + + /// Temporarily suspend entry + int suspend_handler_i (ACE_HANDLE handle, + bool &changes_required); + + /// Resume suspended entry + int resume_handler_i (ACE_HANDLE handle, + bool &changes_required); + + /// Deletions and suspensions in current_info_ + int make_changes_in_current_infos (void); + + /// Deletions and resumptions in current_suspended_info_ + int make_changes_in_suspension_infos (void); + + /// Deletions in to_be_added_info_, or transfers to current_info_ or + /// current_suspended_info_ from to_be_added_info_ + int make_changes_in_to_be_added_infos (void); + + /// Removes the ACE_Event_Handler at @a slot from the table. + int remove_handler_i (size_t slot, + ACE_Reactor_Mask mask); + + /// Removes the ACE_Event_Handler at @a slot from the table. + int remove_suspended_handler_i (size_t slot, + ACE_Reactor_Mask mask); + + /// Removes the ACE_Event_Handler at @a slot from the table. + int remove_to_be_added_handler_i (size_t slot, + ACE_Reactor_Mask to_be_removed_masks); + + /** + * Return the Event_Handler associated with . Return 0 if + * is not registered. + */ + ACE_Event_Handler *find_handler (ACE_HANDLE handle); + + /** + * Check to see if is associated with a valid Event_Handler + * bound to @a mask. Return the associated with this + * @a handler if != 0. + */ + int handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **event_handler = 0); + + /** + * Check to see if is associated with a valid + * Event_Handler. Return Event_Handler and associated masks. + */ + ACE_Event_Handler *handler (ACE_HANDLE handle, + long &existing_masks); + + /// Dump the state of an object. + void dump (void) const; + +protected: + /// Reference to our . + ACE_WFMO_Reactor &wfmo_reactor_; + + /// Maximum number of handles. + size_t max_size_; + + /** + * Array of passed to . This + * is not part of the structure as the handle array needs to be + * passed directly to . + */ + ACE_HANDLE *current_handles_; + + /// Array of current entries in the table + Current_Info *current_info_; + + /// A count of the number of active handles. + DWORD max_handlep1_; + + /// Information for entries to be added + To_Be_Added_Info *to_be_added_info_; + + /// Number of records to be added + size_t handles_to_be_added_; + + /// Currently suspended handles + Suspended_Info *current_suspended_info_; + + /// Number of currently suspended handles + size_t suspended_handles_; + + /// Number of records to be suspended + size_t handles_to_be_suspended_; + + /// Number of records to be resumed + size_t handles_to_be_resumed_; + + /// Number of records to be deleted + size_t handles_to_be_deleted_; + +}; + +/** + * @class ACE_WFMO_Reactor_Notify + * + * @brief Unblock the from its event loop, passing + * it an optional ACE_Event_Handler to dispatch. + * + * This implementation is necessary for cases where the + * is run in a multi-threaded program. In + * this case, we need to be able to unblock + * when updates occur other than in the + * main thread. To do this, we signal an + * auto-reset event the is listening on. If + * an ACE_Event_Handler and ACE_Reactor_Mask is passed to + * , the appropriate method is dispatched. + */ +class ACE_Export ACE_WFMO_Reactor_Notify : public ACE_Reactor_Notify +{ +public: + /// Constructor + ACE_WFMO_Reactor_Notify (size_t max_notifies = 1024); + + /// Initialization. is stored to call . + virtual int open (ACE_Reactor_Impl *wfmo_reactor, + ACE_Timer_Queue *timer_queue, + int disable_notify = 0); + + /// No-op. + virtual int close (void); + + /** + * Special trick to unblock when updates + * occur. All we do is enqueue and @a mask onto the + * ACE_Message_Queue and wakeup the by signaling + * its handle. The ACE_Time_Value indicates how long + * to blocking trying to notify the . If @a timeout == + * 0, the caller will block until action is possible, else will wait + * until the relative time specified in @a timeout elapses). + */ + virtual int notify (ACE_Event_Handler *event_handler = 0, + ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK, + ACE_Time_Value *timeout = 0); + + /// No-op. + virtual int dispatch_notifications (int &number_of_active_handles, + ACE_Handle_Set &rd_mask); + + /// Returns a handle to the . + virtual ACE_HANDLE get_handle (void) const; + + /// Returns the ACE_HANDLE of the notify pipe on which the reactor + /// is listening for notifications so that other threads can unblock + /// the + virtual ACE_HANDLE notify_handle (void); + + /// Handle one of the notify call on the . This could be + /// because of a thread trying to unblock the + virtual int dispatch_notify (ACE_Notification_Buffer &buffer); + + /// Verify whether the buffer has dispatchable info or not. + virtual int is_dispatchable (ACE_Notification_Buffer &buffer); + + /// Read one of the notify call on the into the + /// . This could be because of a thread trying to unblock + /// the + virtual int read_notify_pipe (ACE_HANDLE handle, + ACE_Notification_Buffer &buffer); + + /** + * Set the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify queue before breaking out of its + * loop. By default, this is set to + * -1, which means "iterate until the queue is empty." Setting this + * to a value like "1 or 2" will increase "fairness" (and thus + * prevent starvation) at the expense of slightly higher dispatching + * overhead. + */ + void max_notify_iterations (int); + + /** + * Get the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify queue before breaking out of its + * loop. + */ + int max_notify_iterations (void); + + /** + * Purge any notifications pending in this reactor for the specified + * ACE_Event_Handler object. If == 0, all notifications for all + * handlers are removed (but not any notifications posted just to wake up + * the reactor itself). Returns the number of notifications purged. + * Returns -1 on error. + */ + virtual int purge_pending_notifications (ACE_Event_Handler *, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Dump the state of an object. + virtual void dump (void) const; + +private: + /// Pointer to the wfmo_reactor's timer queue. + ACE_Timer_Queue *timer_queue_; + + /** + * Called when the notification event waited on by + * is signaled. This dequeues all pending + * and dispatches them. + */ + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + /// An auto event is used so that we can it to wakeup one + /// thread up (e.g., when the method is called). + ACE_Auto_Event wakeup_one_thread_; + + /// Message queue that keeps track of pending . + /// This queue must be thread-safe because it can be called by + /// multiple threads of control. + ACE_Message_Queue message_queue_; + + /** + * Keeps track of the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify queue before breaking out of its + * loop. By default, this is set to + * -1, which means "iterate until the queue is empty." + */ + int max_notify_iterations_; +}; + +/** + * @class ACE_WFMO_Reactor + * + * @brief An object oriented event demultiplexor and event handler. + * ACE_WFMO_Reactor is a Windows-only implementation of the ACE_Reactor + * interface that uses the WaitForMultipleObjects() event demultiplexer. + * + * Like the other ACE Reactors, ACE_WFMO_Reactor can schedule timers. + * It also reacts to signalable handles, such as events (see the documentation + * for WaitForMultipleObjects() for a complete list of signalable handle + * types). Therefore, I/O handles are not directly usable for registering + * for input, output, and exception notification. The exception to this + * is ACE_SOCK-based handles, which can be registered for input, output, and + * exception notification just as with other platforms. See Chapter 4 in + * C++NPv2 for complete details. + * + * Note that changes to the state of ACE_WFMO_Reactor are not + * instantaneous. Most changes (registration, removal, + * suspension, and resumption of handles, and changes in + * ownership) are made when the ACE_WFMO_Reactor reaches a stable + * state. Users should be careful, especially when removing + * handlers. This is because the ACE_WFMO_Reactor will call + * handle_close() on the handler when it is finally removed and + * not when remove_handler() is called. If the registered handler's pointer + * is not valid when ACE_WFMO_Reactor calls ACE_Event_Handler::handle_close(), + * use the DONT_CALL flag with remove_handler(). Preferably, use dynamically + * allocated event handlers and call "delete this" inside the handle_close() + * hook method. + * + * Note that although multiple threads can concurrently run the + * ACE_WFMO_Reactor event loop, the concept of the reactor "owner" is still + * important. Only the owner thread can expire timers and wait on the + * notifications handle. Thus, be careful to properly set the owner thread + * when spawning threads to run the event loop while you are using timers + * or notifications. + */ +class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl +{ +public: + friend class ACE_WFMO_Reactor_Handler_Repository; + friend class ACE_WFMO_Reactor_Test; + + enum + { + /// Default size of the WFMO_Reactor's handle table. + /** + * Two slots will be added to the @a size parameter in the + * constructor and open methods which will store handles used for + * internal management purposes. + */ + DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2 + }; + + // = Initialization and termination methods. + + /// Initialize ACE_WFMO_Reactor with the default size. + ACE_WFMO_Reactor (ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + ACE_Reactor_Notify * = 0); + + /** + * Initialize ACE_WFMO_Reactor with the specified size. + * + * @param size The maximum number of handles the reactor can + * register. The value should not exceed + * ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be + * added to the @a size parameter which will store handles + * used for internal management purposes. + */ + ACE_WFMO_Reactor (size_t size, + int unused = 0, + ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + ACE_Reactor_Notify * = 0); + + /** + * Initialize ACE_WFMO_Reactor with the specified size. + * + * @param size The maximum number of handles the reactor can + * register. The value should not exceed + * ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be + * added to the @a size parameter which will store handles + * used for internal management purposes. + */ + virtual int open (size_t size = ACE_WFMO_Reactor::DEFAULT_SIZE, + int restart = 0, + ACE_Sig_Handler * = 0, + ACE_Timer_Queue * = 0, + int disable_notify_pipe = 0, + ACE_Reactor_Notify * = 0); + + /// Returns -1 (not used in this implementation); + virtual int current_info (ACE_HANDLE, size_t & /* size */); + + /// Use a user specified signal handler instead. + virtual int set_sig_handler (ACE_Sig_Handler *signal_handler); + + /// Set a user-specified timer queue. + virtual int timer_queue (ACE_Timer_Queue *tq); + + /// Return the current ACE_Timer_Queue. + virtual ACE_Timer_Queue *timer_queue (void) const; + + /// Close down the ACE_WFMO_Reactor and release all of its resources. + virtual int close (void); + + /// Close down the ACE_WFMO_Reactor and release all of its resources. + virtual ~ACE_WFMO_Reactor (void); + + // = Event loop drivers. + + /** + * This method is not currently implemented. We recommend that you + * use handle_events (ACE_Time_Value::zero) to get basically the + * same effect, i.e., it won't block the caller if there are no events. + */ + virtual int work_pending (const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero); + + /** + * This event loop driver blocks for up to @a max_wait_time before + * returning. It will return earlier if timer events, I/O events, + * or signal events occur. Note that @a max_wait_time can be 0, in + * which case this method blocks indefinitely until events occur. + * + * @a max_wait_time is decremented to reflect how much time this call + * took. For instance, if a time value of 3 seconds is passed to + * handle_events and an event occurs after 2 seconds, + * @a max_wait_time will equal 1 second. This can be used if an + * application wishes to handle events for some fixed amount of + * time. + * + * is used as the demultiplexing call + * + * Returns the total number of I/O and timer ACE_Event_Handlers + * that were dispatched, 0 if the @a max_wait_time elapsed without + * dispatching any handlers, or -1 if an error occurs. + * + * The only difference between and + * is that in the alertable case, TRUE is passed to + * for the option. + */ + virtual int handle_events (ACE_Time_Value *max_wait_time = 0); + virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0); + + /** + * This method is just like the one above, except the + * @a max_wait_time value is a reference and can therefore never be + * NULL. + * + * The only difference between and + * is that in the alertable case, TRUE is passed to + * for the option. + */ + virtual int handle_events (ACE_Time_Value &max_wait_time); + virtual int alertable_handle_events (ACE_Time_Value &max_wait_time); + + + // = Event handling control. + + /** + * Return the status of Reactor. If this function returns 0, the reactor is + * actively handling events. If it returns non-zero, and + * return -1 immediately. + */ + virtual int deactivated (void); + + /** + * Control whether the Reactor will handle any more incoming events or not. + * If == 1, the Reactor will be disabled. By default, a reactor + * is in active state and can be deactivated/reactived as wish. + */ + virtual void deactivate (int do_stop); + + // = Register and remove Handlers. + + /** + * Register an ACE_Event_Handler . Since no Event + * Mask is passed through this interface, it is assumed that the + * being passed in is an event handle and when the event + * becomes signaled, will call handle_signal on + * . If == the + * will call the method of + * to extract the underlying event handle. + */ + virtual int register_handler (ACE_Event_Handler *event_handler, + ACE_HANDLE event_handle = ACE_INVALID_HANDLE); + + /** + * Register an ACE_Event_Handler . @a mask specifies + * the network events that the is interested in. If + * == the will + * call the method of to extract the + * underlying I/O handle. If the == + * , WFMO_Reactor will create an event for + * associating it with the I/O handle. When the is + * signalled, the appropriate callback will be invoked on + * the + */ + virtual int register_handler (ACE_HANDLE event_handle, + ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * This is a simple version of the above method + * where the I/O handle is passed in and the event handle will + * always be created by + */ + virtual int register_handler (ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * This is a simple version of the above method + * where the I/O handle will always come from on the + * and the event handle will always be created by + * + */ + virtual int register_handler (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /// Register with all the in the + /// . + virtual int register_handler (const ACE_Handle_Set &handles, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * Register to handle the signal @a signum using the + * . Returns the that was previously registered + * (if any), along with the of the signal handler. + */ + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + + /// Registers to handle a set of signals using the + /// . + virtual int register_handler (const ACE_Sig_Set &sigset, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0); + + /** + * Removes from the . Note that + * the will call the method of + * to extract the underlying handle. If @a mask == + * ACE_Event_Handler::DONT_CALL then the method of + * the is not invoked. Note that the can + * either be the or the + */ + virtual int remove_handler (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /** + * Removes from the . If @a mask == + * ACE_Event_Handler::DONT_CALL then the method of + * the is not invoked. Note that the can + * either be the or the + * + * For the case of I/O entries, this removes the @a mask binding of + * whose handle is from . If + * there are no more bindings for this then it is + * removed from the WFMO_Reactor. For simple event entries, mask is + * mostly ignored and the is always removed from + * + */ + virtual int remove_handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask); + + /** + * Removes all the @a mask bindings for handles in the + * bind of . If there are no more bindings for any + * of these handles then they are removed from WFMO_Reactor. + */ + virtual int remove_handler (const ACE_Handle_Set &handle_set, + ACE_Reactor_Mask); + + /** + * Remove the ACE_Event_Handler currently associated with @a signum. + * is ignored in this implementation since there is only + * one instance of a signal handler. Install the new disposition + * (if given) and return the previous disposition (if desired by the + * caller). Returns 0 on success and -1 if @a signum is invalid. + */ + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + + /// Calls for every signal in . + virtual int remove_handler (const ACE_Sig_Set &sigset); + + // = Suspend and resume Handlers. + + /// Suspend temporarily. Use + /// to get the handle. + virtual int suspend_handler (ACE_Event_Handler *event_handler); + + /// Suspend temporarily. + virtual int suspend_handler (ACE_HANDLE handle); + + /// Suspend all in handle set temporarily. + virtual int suspend_handler (const ACE_Handle_Set &handles); + + /// Suspend all temporarily. + virtual int suspend_handlers (void); + + /// Resume . Use to + /// get the handle. + virtual int resume_handler (ACE_Event_Handler *event_handler); + + /// Resume . + virtual int resume_handler (ACE_HANDLE handle); + + /// Resume all in handle set. + virtual int resume_handler (const ACE_Handle_Set &handles); + + /// Resume all . + virtual int resume_handlers (void); + + /// Does the reactor allow the application to resume the handle on + /// its own ie. can it pass on the control of handle resumption to + /// the application. A positive value indicates that the handlers + /// are application resumable. A value of 0 indicates otherwise. + virtual int resumable_handler (void); + + /** + * Return 1 if we any event associations were made by the reactor + * for the handles that it waits on, 0 otherwise. Since the + * WFMO_Reactor does use event associations, this function always + * return 1. + */ + virtual int uses_event_associations (void); + + // Timer management. + + /** + * Schedule an ACE_Event_Handler that will expire after an amount + * of time. The return value of this method, a timer_id value, + * uniquely identifies the event_handler in the ACE_Reactor's + * internal list of timers. + * This timer_id value can be used to cancel the timer + * with the cancel_timer() call. + * + * @see cancel_timer() + * @see reset_timer_interval() + * + * @param event_handler event handler to schedule on reactor + * @param arg argument passed to the handle_timeout() method of event_handler + * @param delay time interval after which the timer will expire + * @param interval time interval after which the timer will be automatically rescheduled + * @return -1 on failure, a timer_id value on success + */ + virtual long schedule_timer (ACE_Event_Handler *event_handler, + const void *arg, + const ACE_Time_Value &delay, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + + /** + * Resets the interval of the timer represented by @a timer_id to + * @a interval, which is specified in relative time to the current + * . If @a interval is equal to + * ACE_Time_Value::zero, the timer will become a non-rescheduling + * timer. Returns 0 if successful, -1 if not. + */ + virtual int reset_timer_interval (long timer_id, + const ACE_Time_Value &interval); + + /// Cancel all Event_Handlers that match the address of + /// . Returns number of handler's cancelled. + virtual int cancel_timer (ACE_Event_Handler *event_handler, + int dont_call_handle_close = 1); + + /** + * Cancel the single Event_Handler that matches the @a timer_id value + * (which was returned from the schedule method). If arg is + * non-NULL then it will be set to point to the ``magic cookie'' + * argument passed in when the Event_Handler was registered. This + * makes it possible to free up the memory and avoid memory leaks. + * Returns 1 if cancellation succeeded and 0 if the @a timer_id + * wasn't found. + */ + virtual int cancel_timer (long timer_id, + const void **arg = 0, + int dont_call_handle_close = 1); + + // = High-level Event_Handler scheduling operations + + /** + * Add @a masks_to_be_added to the 's entry in + * WFMO_Reactor. must already have been registered + * with WFMO_Reactor. + */ + virtual int schedule_wakeup (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks_to_be_added); + + /** + * Add @a masks_to_be_added to the @a handle's entry in WFMO_Reactor. + * The Event_Handler associated with must already have been + * registered with WFMO_Reactor. + */ + virtual int schedule_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask masks_to_be_added); + + /** + * Remove to the 's entry in + * WFMO_Reactor. The Event_Handler associated with must + * already have been registered with WFMO_Reactor. + */ + virtual int cancel_wakeup (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks_to_be_deleted); + + /** + * Remove to the 's entry in + * WFMO_Reactor. The Event_Handler associated with must + * already have been registered with WFMO_Reactor. + */ + virtual int cancel_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask masks_to_be_deleted); + + // = Notification methods. + + /** + * Wakeup one thread if it is currently blocked + * in . The ACE_Time_Value indicates how + * long to blocking trying to notify the . If + * @a timeout == 0, the caller will block until action is possible, + * else will wait until the relative time specified in @a timeout + * elapses). + */ + virtual int notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, + ACE_Time_Value * = 0); + + /** + * Set the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify queue before breaking out of its + * loop. By default, this is set to + * -1, which means "iterate until the queue is empty." Setting this + * to a value like "1 or 2" will increase "fairness" (and thus + * prevent starvation) at the expense of slightly higher dispatching + * overhead. + */ + virtual void max_notify_iterations (int); + + /** + * Get the maximum number of times that the + * method will iterate and + * dispatch the that are passed in via the + * notify queue before breaking out of its + * loop. + */ + virtual int max_notify_iterations (void); + + /** + * Purge any notifications pending in this reactor for the specified + * ACE_Event_Handler object. Returns the number of notifications + * purged. Returns -1 on error. + */ + virtual int purge_pending_notifications (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + // = Assorted helper methods. + + /** + * Return the Event_Handler associated with . Return 0 if + * is not registered. + */ + ACE_Event_Handler *find_handler (ACE_HANDLE handle); + + /** + * Check to see if is associated with a valid Event_Handler + * bound to @a mask. Return the associated with this + * @a handler if != 0. + */ + virtual int handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **event_handler = 0); + + /** + * Check to see if @a signum is associated with a valid Event_Handler + * bound to a signal. Return the associated with + * this @a handler if != 0. + */ + virtual int handler (int signum, + ACE_Event_Handler ** = 0); + + /// Returns true if WFMO_Reactor has been successfully initialized, else + /// false. + virtual bool initialized (void); + + /// Returns the current size of the WFMO_Reactor's internal + /// descriptor table. + virtual size_t size (void) const; + + /// Returns a reference to the WFMO_Reactor's internal lock. + virtual ACE_Lock &lock (void); + + /// Wake up all threads in WaitForMultipleObjects so that they can + /// reconsult the handle set + virtual void wakeup_all_threads (void); + + /** + * Transfers ownership of the WFMO_Reactor to the . The + * transfer will not complete until all threads are ready (just like + * the handle set). + */ + virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0); + + /// Return the ID of the "owner" thread. + virtual int owner (ACE_thread_t *owner); + + /// Get the existing restart value. + virtual int restart (void); + + /// Set a new value for restart and return the original value. + virtual int restart (int r); + + /// Not implemented + virtual void requeue_position (int); + + /// Not implemented + virtual int requeue_position (void); + + // = Low-level wait_set mask manipulation methods. + + /** + * Modify @a masks of the 's entry in WFMO_Reactor + * depending upon . must already have + * been registered with WFMO_Reactor. + */ + virtual int mask_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks, + int operation); + + /** + * Modify @a masks of the 's entry in WFMO_Reactor depending + * upon . must already have been registered + * with WFMO_Reactor. + */ + virtual int mask_ops (ACE_HANDLE handle, + ACE_Reactor_Mask masks, + int ops); + + // = Low-level ready_set mask manipulation methods. + + /// Not implemented + virtual int ready_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + int ops); + + /// Not implemented + virtual int ready_ops (ACE_HANDLE handle, + ACE_Reactor_Mask, + int ops); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Dump the state of an object. + virtual void dump (void) const; + +protected: + /// Registration workhorse + virtual int register_handler_i (ACE_HANDLE event_handle, + ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask); + + /// Event handling workhorse + virtual int event_handling (ACE_Time_Value *max_wait_time = 0, + int alertable = 0); + + /// Bit masking workhorse + virtual int mask_ops_i (ACE_HANDLE io_handle, + ACE_Reactor_Mask masks, + int operation); + + /// Return the ID of the "owner" thread. Does not do any locking. + virtual ACE_thread_t owner_i (void); + + /// Wait up to @a max_wait_time until it's ok to enter + /// WaitForMultipleObjects. Returns 1 (and holding lock_) if ok to wait; + /// -1 (and not holding lock_) if not. + virtual int ok_to_wait (ACE_Time_Value *max_wait_time, + int alertable); + + /// Wait for timer and I/O events to occur. + virtual DWORD wait_for_multiple_events (int timeout, + int alertable); + + /// Check for activity on remaining handles. + virtual DWORD poll_remaining_handles (DWORD slot); + + /// Expire timers. Only the owner thread does useful stuff in this + /// function. + virtual int expire_timers (void); + + /// Dispatches the timers and I/O handlers. + virtual int dispatch (DWORD wait_status); + + /// Protect against structured exceptions caused by user code when + /// dispatching handles + virtual int safe_dispatch (DWORD wait_status); + + /** + * Dispatches any active handles from handles_[@a slot] to + * handles_[active_handles_] using to poll + * through our handle set looking for active handles. + */ + virtual int dispatch_handles (DWORD slot); + + /// Dispatches a single handler. Returns 0 on success, -1 if the + /// handler was removed. + virtual int dispatch_handler (DWORD slot, + DWORD max_handlep1); + + /// Dispatches a single handler. Returns 0 on success, -1 if the + /// handler was removed. + virtual int simple_dispatch_handler (DWORD slot, + ACE_HANDLE event_handle); + + /// Dispatches a single handler. Returns 0 on success, -1 if the + /// handler was removed. + virtual int complex_dispatch_handler (DWORD slot, + ACE_HANDLE event_handle); + + /// Dispatches window messages. Noop for WFMO_Reactor. + virtual int dispatch_window_messages (void); + + virtual ACE_Reactor_Mask upcall (ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + WSANETWORKEVENTS &events); + + /// Used to caluculate the next timeout + virtual int calculate_timeout (ACE_Time_Value *time); + + /// Update the state of the handler repository + virtual int update_state (void); + + /// Check to see if we have a new owner + virtual int new_owner (void); + + /// Set owner to new owner + virtual int change_owner (void); + + /// Handle signals without requiring global/static variables. + ACE_Sig_Handler *signal_handler_; + + /// Keeps track of whether we should delete the signal handler (if we + /// didn't create it, then we don't delete it). + bool delete_signal_handler_; + + /// Defined as a pointer to allow overriding by derived classes... + ACE_Timer_Queue *timer_queue_; + + /// Keeps track of whether we should delete the timer queue (if we + /// didn't create it, then we don't delete it). + bool delete_timer_queue_; + + /// Keeps track of whether we should delete the handler repository + bool delete_handler_rep_; + + /// Used when is called. + ACE_Reactor_Notify *notify_handler_; + + /// Keeps track of whether we should delete the notify handler. + bool delete_notify_handler_; + + /** + * Synchronization for the ACE_WFMO_Reactor. + * + * A Process Mutex is used here because of two reasons: + * (a) The implementation of ACE_Thread_Mutex uses CriticalSections + * CriticalSections are not waitable using ::WaitForMultipleObjects + * (b) This is really not a process mutex because it is not + * named. No other process can use this mutex. + */ + ACE_Process_Mutex lock_; + + /// Adapter used to return internal lock to outside world. + ACE_Lock_Adapter lock_adapter_; + + /// Table that maps to 's. + ACE_WFMO_Reactor_Handler_Repository handler_rep_; + + /// A manual event used to block threads from proceeding into + /// WaitForMultipleObjects + ACE_Manual_Event ok_to_wait_; + + /** + * A manual event is used so that we can wake everyone up (e.g., + * when are bounded and unbound from the + * handler repository). + */ + ACE_Manual_Event wakeup_all_threads_; + + /// Used when is signaled + ACE_Wakeup_All_Threads_Handler wakeup_all_threads_handler_; + + /// The changing thread waits on this event, till all threads are not + /// active anymore + ACE_Auto_Event waiting_to_change_state_; + + /// Count of currently active threads + size_t active_threads_; + + /** + * The thread which is "owner" of the WFMO_Reactor. The owner + * concept is used because we don't want multiple threads to try to + * expire timers. Therefore the "owner" thread is the only one + * allowed to expire timers. Also, the owner thread is the only + * thread which waits on the notify handle. Note that the ownership + * can be transferred. + */ + ACE_thread_t owner_; + + /// The owner to be of the WFMO_Reactor + ACE_thread_t new_owner_; + + /// This is the thread which is responsible for the changing the + /// state of the handle set + ACE_thread_t change_state_thread_; + + /// This is an array of ACE_HANDLEs which keep track of the + /// and handles + ACE_HANDLE atomic_wait_array_ [2]; + + /// This flag is used to keep track of whether we are already closed. + bool open_for_business_; + + /// This flag is used to keep track of whether we are actively handling + /// events or not. + sig_atomic_t deactivated_; + +private: + /// Deny access since member-wise won't work... + ACE_WFMO_Reactor (const ACE_WFMO_Reactor &); + ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/WFMO_Reactor.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_WIN32 */ +#include /**/ "ace/post.h" +#endif /* ACE_WFMO_REACTOR_H */ diff --git a/dep/ACE_wrappers/ace/WFMO_Reactor.inl b/dep/ACE_wrappers/ace/WFMO_Reactor.inl new file mode 100644 index 000000000..a155019d8 --- /dev/null +++ b/dep/ACE_wrappers/ace/WFMO_Reactor.inl @@ -0,0 +1,1200 @@ +// -*- C++ -*- +// +// $Id: WFMO_Reactor.inl 81138 2008-03-28 09:18:15Z johnnyw $ + +#include "ace/Handle_Set.h" +#include "ace/Reactor.h" +#include "ace/Thread.h" +#include "ace/Sig_Handler.h" +#include "ace/OS_NS_errno.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/************************************************************/ + +ACE_INLINE int +ACE_Wakeup_All_Threads_Handler::handle_signal (int /* signum */, + siginfo_t * /* siginfo */, + ucontext_t *) +{ + // This will get called when wakeup_all_threads_> event + // is signaled. There is nothing to be done here. + // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) waking up to get updated handle set info\n"))); + return 0; +} + +#if defined (ACE_WIN32) + +/************************************************************/ + +ACE_INLINE +ACE_WFMO_Reactor_Handler_Repository::Common_Info::Common_Info (void) + : io_entry_ (false), + event_handler_ (0), + io_handle_ (ACE_INVALID_HANDLE), + network_events_ (0), + delete_event_ (false), + delete_entry_ (false), + close_masks_ (ACE_Event_Handler::NULL_MASK) +{ +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Common_Info::reset (void) +{ + this->event_handler_ = 0; + this->io_entry_ = false; + this->io_handle_ = ACE_INVALID_HANDLE; + this->network_events_ = 0; + this->delete_event_ = false; + this->delete_entry_ = false; + this->close_masks_ = ACE_Event_Handler::NULL_MASK; +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Common_Info::set (bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry, + ACE_Reactor_Mask close_masks) +{ + this->event_handler_ = event_handler; + this->io_entry_ = io_entry; + this->io_handle_ = io_handle; + this->network_events_ = network_events; + this->delete_event_ = delete_event; + this->delete_entry_ = delete_entry; + this->close_masks_ = close_masks; +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Common_Info::set (Common_Info &common_info) +{ + *this = common_info; +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Common_Info::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::Common_Info::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("I/O Entry = %d\n"), + this->io_entry_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Event Handler = %d\n"), + this->event_handler_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("I/O Handle = %d\n"), + this->io_handle_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Network Events = %d\n"), + this->network_events_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Delete Event = %d\n"), + this->delete_event_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Delete Entry = %d\n"), + this->delete_entry_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Close Masks = %d\n"), + this->close_masks_)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +/************************************************************/ + +ACE_INLINE +ACE_WFMO_Reactor_Handler_Repository::Current_Info::Current_Info (void) + : suspend_entry_ (false) +{ +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Current_Info::set (bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry, + ACE_Reactor_Mask close_masks, + bool suspend_entry) +{ + this->suspend_entry_ = suspend_entry; + Common_Info::set (io_entry, + event_handler, + io_handle, + network_events, + delete_event, + delete_entry, + close_masks); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Current_Info::set (Common_Info &common_info, + bool suspend_entry) +{ + this->suspend_entry_ = suspend_entry; + Common_Info::set (common_info); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Current_Info::reset (void) +{ + this->suspend_entry_ = false; + Common_Info::reset (); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Current_Info::dump (ACE_HANDLE event_handle) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::Current_Info::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + Common_Info::dump (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Event Handle = %d\n"), + event_handle)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Suspend Entry = %d\n"), + this->suspend_entry_)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#else /* !ACE_HAS_DUMP */ + ACE_UNUSED_ARG (event_handle); +#endif /* ACE_HAS_DUMP */ +} + +/************************************************************/ + +ACE_INLINE +ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::To_Be_Added_Info (void) + : event_handle_ (ACE_INVALID_HANDLE), + suspend_entry_ (false) +{ +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle, + bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry, + ACE_Reactor_Mask close_masks, + bool suspend_entry) +{ + this->event_handle_ = event_handle; + this->suspend_entry_ = suspend_entry; + Common_Info::set (io_entry, + event_handler, + io_handle, + network_events, + delete_event, + delete_entry, + close_masks); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::set (ACE_HANDLE event_handle, + Common_Info &common_info, + bool suspend_entry) +{ + this->event_handle_ = event_handle; + this->suspend_entry_ = suspend_entry; + Common_Info::set (common_info); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::reset (void) +{ + this->event_handle_ = ACE_INVALID_HANDLE; + this->suspend_entry_ = false; + Common_Info::reset (); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::To_Be_Added_Info::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + Common_Info::dump (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Event Handle = %d\n"), + this->event_handle_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Suspend Entry = %d\n"), + this->suspend_entry_)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +/************************************************************/ + +ACE_INLINE +ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::Suspended_Info (void) + : event_handle_ (ACE_INVALID_HANDLE), + resume_entry_ (false) +{ +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::reset (void) +{ + this->event_handle_ = ACE_INVALID_HANDLE; + this->resume_entry_ = false; + Common_Info::reset (); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle, + bool io_entry, + ACE_Event_Handler *event_handler, + ACE_HANDLE io_handle, + long network_events, + bool delete_event, + bool delete_entry, + ACE_Reactor_Mask close_masks, + bool resume_entry) +{ + this->event_handle_ = event_handle; + this->resume_entry_ = resume_entry; + Common_Info::set (io_entry, + event_handler, + io_handle, + network_events, + delete_event, + delete_entry, + close_masks); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::set (ACE_HANDLE event_handle, + Common_Info &common_info, + bool resume_entry) +{ + this->event_handle_ = event_handle; + this->resume_entry_ = resume_entry; + Common_Info::set (common_info); +} + +ACE_INLINE void +ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::Suspended_Info::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + Common_Info::dump (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Event Handle = %d\n"), + this->event_handle_)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Resume Entry = %d\n"), + this->resume_entry_)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +/************************************************************/ + +ACE_INLINE int +ACE_WFMO_Reactor_Handler_Repository::close (void) +{ + // Let all the handlers know that the is closing down + this->unbind_all (); + + return 0; +} + +ACE_INLINE ACE_HANDLE * +ACE_WFMO_Reactor_Handler_Repository::handles (void) const +{ + // This code is probably too subtle to be useful in the long run... + // The basic idea is that all threads wait on all user handles plus + // the handle. The owner thread additional + // waits on the handle. This is to ensure that only the + // thread get to expire timers and handle event on the + // notify pipe. + if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ()) + return this->current_handles_; + else + return this->current_handles_ + 1; +} + +ACE_INLINE ACE_WFMO_Reactor_Handler_Repository::Current_Info * +ACE_WFMO_Reactor_Handler_Repository::current_info (void) const +{ + if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ()) + return this->current_info_; + else + return this->current_info_ + 1; +} + +ACE_INLINE DWORD +ACE_WFMO_Reactor_Handler_Repository::max_handlep1 (void) const +{ + if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ()) + return this->max_handlep1_; + else + return this->max_handlep1_ - 1; +} + +ACE_INLINE int +ACE_WFMO_Reactor_Handler_Repository::scheduled_for_deletion (size_t slot) const +{ + if (ACE_Thread::self () == this->wfmo_reactor_.owner_i ()) + return this->current_info_[slot].delete_entry_ == true; + else + return this->current_info_[slot + 1].delete_entry_ == true; +} + +ACE_INLINE int +ACE_WFMO_Reactor_Handler_Repository::invalid_handle (ACE_HANDLE handle) const +{ + ACE_TRACE ("ACE_WFMO_Reactor_Handler_Repository::invalid_handle"); + // It's too expensive to perform more exhaustive validity checks on + // Win32 due to the way that they implement SOCKET HANDLEs. + if (handle == ACE_INVALID_HANDLE) + { + errno = EINVAL; + return 1; + } + else + return 0; +} + +ACE_INLINE bool +ACE_WFMO_Reactor_Handler_Repository::changes_required (void) +{ + // Check if handles have be scheduled for additions or removal + return this->handles_to_be_added_ > 0 + || this->handles_to_be_deleted_ > 0 + || this->handles_to_be_suspended_ > 0 + || this->handles_to_be_resumed_ > 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor_Handler_Repository::make_changes (void) +{ + // This method must ONLY be called by the + // change_state_thread_>. We therefore assume that + // there will be no contention for this method and hence no guards + // are neccessary. + + // Deletions and suspensions in current_info_ + this->make_changes_in_current_infos (); + + // Deletions and resumptions in current_suspended_info_ + this->make_changes_in_suspension_infos (); + + // Deletions in to_be_added_info_, or transfers to current_info_ or + // current_suspended_info_ from to_be_added_info_ + this->make_changes_in_to_be_added_infos (); + + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor_Handler_Repository::unbind (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + if (this->invalid_handle (handle)) + return -1; + + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->wfmo_reactor_.lock_, -1); + + bool changes_required = false; + int const result = this->unbind_i (handle, + mask, + changes_required); + + if (changes_required) + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wfmo_reactor_.wakeup_all_threads (); + + return result; +} + +ACE_INLINE int +ACE_WFMO_Reactor::reset_timer_interval + (long timer_id, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_WFMO_Reactor::reset_timer_interval"); + + if (0 != this->timer_queue_) + { + long result = this->timer_queue_->reset_interval + (timer_id, + interval); + + // Wakeup the owner thread so that it gets the latest timer values + this->notify (); + + return result; + } + + errno = ESHUTDOWN; + return -1; +} + +ACE_INLINE long +ACE_WFMO_Reactor::schedule_timer (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &delay_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_WFMO_Reactor::schedule_timer"); + + if (0 != this->timer_queue_) + { + long result = this->timer_queue_->schedule + (handler, + arg, + timer_queue_->gettimeofday () + delay_time, + interval); + + // Wakeup the owner thread so that it gets the latest timer values + this->notify (); + + return result; + } + + errno = ESHUTDOWN; + return -1; +} + +ACE_INLINE int +ACE_WFMO_Reactor::cancel_timer (ACE_Event_Handler *handler, + int dont_call_handle_close) +{ + ACE_TRACE ("ACE_WFMO_Reactor::cancel_timer"); + if (0 != this->timer_queue_) + return this->timer_queue_->cancel (handler, dont_call_handle_close); + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::cancel_timer (long timer_id, + const void **arg, + int dont_call_handle_close) +{ + ACE_TRACE ("ACE_WFMO_Reactor::cancel_timer"); + if (0 != this->timer_queue_) + return this->timer_queue_->cancel (timer_id, arg, dont_call_handle_close); + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (ACE_Event_Handler *event_handler, + ACE_HANDLE event_handle) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->handler_rep_.bind_i (0, + event_handler, + 0, + ACE_INVALID_HANDLE, + event_handle, + 0); +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->register_handler_i (ACE_INVALID_HANDLE, + ACE_INVALID_HANDLE, + event_handler, + mask); +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->register_handler_i (ACE_INVALID_HANDLE, + io_handle, + event_handler, + mask); +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (ACE_HANDLE event_handle, + ACE_HANDLE io_handle, + ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->register_handler_i (event_handle, + io_handle, + event_handler, + mask); +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (const ACE_Handle_Set &handles, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->register_handler_i (h, + ACE_INVALID_HANDLE, + handler, + mask) == -1) + return -1; + + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::schedule_wakeup (ACE_HANDLE io_handle, + ACE_Reactor_Mask masks_to_be_added) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->mask_ops_i (io_handle, + masks_to_be_added, + ACE_Reactor::ADD_MASK); +} + +ACE_INLINE int +ACE_WFMO_Reactor::schedule_wakeup (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks_to_be_added) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->mask_ops_i (event_handler->get_handle (), + masks_to_be_added, + ACE_Reactor::ADD_MASK); +} + +ACE_INLINE int +ACE_WFMO_Reactor::cancel_wakeup (ACE_HANDLE io_handle, + ACE_Reactor_Mask masks_to_be_removed) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->mask_ops_i (io_handle, + masks_to_be_removed, + ACE_Reactor::CLR_MASK); +} + +ACE_INLINE int +ACE_WFMO_Reactor::cancel_wakeup (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask masks_to_be_removed) +{ + // This GUARD is necessary since we are updating shared state. + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->mask_ops_i (event_handler->get_handle (), + masks_to_be_removed, + ACE_Reactor::CLR_MASK); +} + +ACE_INLINE int +ACE_WFMO_Reactor::remove_handler (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask) +{ + return this->handler_rep_.unbind (event_handler->get_handle (), + mask); +} + +ACE_INLINE int +ACE_WFMO_Reactor::remove_handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + return this->handler_rep_.unbind (handle, + mask); +} + +ACE_INLINE int +ACE_WFMO_Reactor::remove_handler (const ACE_Handle_Set &handles, + ACE_Reactor_Mask mask) +{ + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + bool changes_required = false; + + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->handler_rep_.unbind_i (h, + mask, + changes_required) == -1) + return -1; + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::suspend_handler (ACE_HANDLE handle) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + bool changes_required = false; + int const result = + this->handler_rep_.suspend_handler_i (handle, + changes_required); + + if (changes_required) + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return result; +} + +ACE_INLINE int +ACE_WFMO_Reactor::suspend_handler (ACE_Event_Handler *event_handler) +{ + return this->suspend_handler (event_handler->get_handle ()); +} + +ACE_INLINE int +ACE_WFMO_Reactor::suspend_handler (const ACE_Handle_Set &handles) +{ + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + bool changes_required = false; + + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->handler_rep_.suspend_handler_i (h, + changes_required) == -1) + return -1; + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::suspend_handlers (void) +{ + bool error = false; + int result = 0; + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + // First suspend all current handles + bool changes_required = false; + + for (size_t i = 0; + i < this->handler_rep_.max_handlep1_ && !error; + i++) + { + result = + this->handler_rep_.suspend_handler_i (this->handler_rep_.current_handles_[i], + changes_required); + if (result == -1) + error = true; + } + + // Then suspend all to_be_added_handles + for (size_t i = 0; + i < this->handler_rep_.handles_to_be_added_ && !error; + i++) + { + if (this->handler_rep_.to_be_added_info_[i].io_entry_) + { + result = + this->handler_rep_.suspend_handler_i (this->handler_rep_.to_be_added_info_[i].io_handle_, + changes_required); + } + else + { + result = + this->handler_rep_.suspend_handler_i (this->handler_rep_.to_be_added_info_[i].event_handle_, + changes_required); + } + if (result == -1) + error = true; + } + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return error ? -1 : 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::resume_handler (ACE_HANDLE handle) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + bool changes_required = false; + int result = + this->handler_rep_.resume_handler_i (handle, changes_required); + + if (changes_required) + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return result; +} + +ACE_INLINE int +ACE_WFMO_Reactor::resume_handler (ACE_Event_Handler *event_handler) +{ + return this->resume_handler (event_handler->get_handle ()); +} + +ACE_INLINE int +ACE_WFMO_Reactor::resume_handler (const ACE_Handle_Set &handles) +{ + ACE_Handle_Set_Iterator handle_iter (handles); + ACE_HANDLE h; + bool changes_required = false; + + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + while ((h = handle_iter ()) != ACE_INVALID_HANDLE) + if (this->handler_rep_.resume_handler_i (h, + changes_required) == -1) + return -1; + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::resume_handlers (void) +{ + bool error = false; + int result = 0; + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + bool changes_required = false; + for (size_t i = 0; + i < this->handler_rep_.suspended_handles_ && !error; + i++) + { + result = + this->handler_rep_.resume_handler_i (this->handler_rep_.current_suspended_info_[i].event_handle_, + changes_required); + if (result == -1) + error = true; + } + + // Then resume all to_be_added_handles + for (size_t i = 0; + i < this->handler_rep_.handles_to_be_added_ && !error; + i++) + { + if (this->handler_rep_.to_be_added_info_[i].io_entry_) + { + result = + this->handler_rep_.resume_handler_i (this->handler_rep_.to_be_added_info_[i].io_handle_, + changes_required); + } + else + { + result = + this->handler_rep_.resume_handler_i (this->handler_rep_.to_be_added_info_[i].event_handle_, + changes_required); + } + if (result == -1) + error = true; + } + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the handle set + this->wakeup_all_threads (); + + return error ? -1 : 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::uses_event_associations (void) +{ + // Since the WFMO_Reactor does use event associations, this function + // always return 1. + return 1; +} + +ACE_INLINE int +ACE_WFMO_Reactor::handle_events (ACE_Time_Value &how_long) +{ + return this->event_handling (&how_long, FALSE); +} + +ACE_INLINE int +ACE_WFMO_Reactor::alertable_handle_events (ACE_Time_Value &how_long) +{ + return this->event_handling (&how_long, TRUE); +} + +ACE_INLINE int +ACE_WFMO_Reactor::handle_events (ACE_Time_Value *how_long) +{ + return this->event_handling (how_long, FALSE); +} + +ACE_INLINE int +ACE_WFMO_Reactor::alertable_handle_events (ACE_Time_Value *how_long) +{ + return this->event_handling (how_long, TRUE); +} + +ACE_INLINE int +ACE_WFMO_Reactor::deactivated (void) +{ + return this->deactivated_; +} + +ACE_INLINE void +ACE_WFMO_Reactor::deactivate (int do_stop) +{ + this->deactivated_ = do_stop; + this->wakeup_all_threads (); +} + +ACE_INLINE int +ACE_WFMO_Reactor::owner (ACE_thread_t *t) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + *t = this->owner_i (); + return 0; +} + +ACE_INLINE ACE_thread_t +ACE_WFMO_Reactor::owner_i (void) +{ + return this->owner_; +} + +ACE_INLINE int +ACE_WFMO_Reactor::owner (ACE_thread_t new_owner, ACE_thread_t *old_owner) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1); + this->new_owner_ = new_owner; + + if (old_owner != 0) + *old_owner = this->owner_i (); + + // Wake up all threads in WaitForMultipleObjects so that they can + // reconsult the new owner responsibilities + this->wakeup_all_threads (); + + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::new_owner (void) +{ + return this->new_owner_ != ACE_thread_t (0); +} + +ACE_INLINE int +ACE_WFMO_Reactor::change_owner (void) +{ + this->owner_ = this->new_owner_; + this->new_owner_ = ACE_thread_t (0); + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::safe_dispatch (DWORD wait_status) +{ + int result = -1; + ACE_SEH_TRY + { + result = this->dispatch (wait_status); + } + ACE_SEH_FINALLY + { + this->update_state (); + } + + return result; +} + +ACE_INLINE int +ACE_WFMO_Reactor::dispatch_window_messages (void) +{ + return 0; +} + +ACE_INLINE void +ACE_WFMO_Reactor::wakeup_all_threads (void) +{ + this->wakeup_all_threads_.signal (); +} + +ACE_INLINE int +ACE_WFMO_Reactor::notify (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + ACE_Time_Value *timeout) +{ + return this->notify_handler_->notify (event_handler, mask, timeout); +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + return this->signal_handler_->register_handler (signum, + new_sh, new_disp, + old_sh, old_disp); +} + +ACE_INLINE int +ACE_WFMO_Reactor::register_handler (const ACE_Sig_Set &sigset, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp) +{ + int result = 0; + +#if (ACE_NSIG > 0) + for (int s = 1; s < ACE_NSIG; s++) + if (sigset.is_member (s) + && this->signal_handler_->register_handler (s, + new_sh, + new_disp) == -1) + result = -1; +#else + ACE_UNUSED_ARG (sigset); + ACE_UNUSED_ARG (new_sh); + ACE_UNUSED_ARG (new_disp); +#endif /* ACE_NSIG */ + + return result; +} + +ACE_INLINE int +ACE_WFMO_Reactor::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + return this->signal_handler_->remove_handler (signum, + new_disp, + old_disp, + sigkey); +} + +ACE_INLINE int +ACE_WFMO_Reactor::remove_handler (const ACE_Sig_Set &sigset) +{ + int result = 0; + +#if (ACE_NSIG > 0) + for (int s = 1; s < ACE_NSIG; s++) + if (sigset.is_member (s) + && this->signal_handler_->remove_handler (s) == -1) + result = -1; +#else + ACE_UNUSED_ARG (sigset); +#endif /* ACE_NSIG */ + + return result; +} + +ACE_INLINE int +ACE_WFMO_Reactor::handler (int signum, ACE_Event_Handler **eh) +{ + ACE_Event_Handler *handler = + this->signal_handler_->handler (signum); + + if (handler == 0) + return -1; + else if (eh != 0) + *eh = handler; + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::mask_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + int operation) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1); + + return this->mask_ops_i (event_handler->get_handle (), + mask, + operation); +} + +ACE_INLINE int +ACE_WFMO_Reactor::mask_ops (ACE_HANDLE io_handle, + ACE_Reactor_Mask mask, + int operation) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, monitor, this->lock_, -1); + + return this->mask_ops_i (io_handle, + mask, + operation); +} + +ACE_INLINE void +ACE_WFMO_Reactor::requeue_position (int) +{ + // Not implemented +} + +ACE_INLINE int +ACE_WFMO_Reactor::requeue_position (void) +{ + // Don't have an implementation for this yet... + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_WFMO_Reactor::restart (void) +{ + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::restart (int) +{ + return 0; +} + +ACE_INLINE int +ACE_WFMO_Reactor::ready_ops (ACE_Event_Handler *event_handler, + ACE_Reactor_Mask mask, + int ops) +{ + // Don't have an implementation for this yet... + ACE_UNUSED_ARG (event_handler); + ACE_UNUSED_ARG (mask); + ACE_UNUSED_ARG (ops); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_WFMO_Reactor::ready_ops (ACE_HANDLE handle, + ACE_Reactor_Mask, + int ops) +{ + // Don't have an implementation for this yet... + ACE_UNUSED_ARG (handle); + ACE_UNUSED_ARG (ops); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE ACE_Event_Handler * +ACE_WFMO_Reactor::find_handler (ACE_HANDLE handle) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, 0); + + return this->handler_rep_.find_handler (handle); +} + +ACE_INLINE int +ACE_WFMO_Reactor::handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **event_handler) +{ + ACE_GUARD_RETURN (ACE_Process_Mutex, ace_mon, this->lock_, -1); + + return this->handler_rep_.handler (handle, + mask, + event_handler); +} + +ACE_INLINE bool +ACE_WFMO_Reactor::initialized (void) +{ + return this->open_for_business_; +} + +ACE_INLINE ACE_Lock & +ACE_WFMO_Reactor::lock (void) +{ + return this->lock_adapter_; +} + +ACE_INLINE size_t +ACE_WFMO_Reactor::size (void) const +{ + // Size of repository minus the 2 used for internal purposes + return this->handler_rep_.max_size_ - 2; +} +#else +ACE_INLINE bool +ACE_WFMO_Reactor_Handler_Repository::changes_required (void) +{ + return false; +} + +ACE_INLINE int +ACE_WFMO_Reactor_Handler_Repository::make_changes (void) +{ + return 0; +} + +ACE_INLINE +ACE_WFMO_Reactor_Handler_Repository::~ACE_WFMO_Reactor_Handler_Repository (void) +{ +} + +#endif /* ACE_WIN32 */ + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/WIN32_Asynch_IO.cpp b/dep/ACE_wrappers/ace/WIN32_Asynch_IO.cpp new file mode 100644 index 000000000..6f201accc --- /dev/null +++ b/dep/ACE_wrappers/ace/WIN32_Asynch_IO.cpp @@ -0,0 +1,3778 @@ +// $Id: WIN32_Asynch_IO.cpp 82444 2008-07-28 13:33:07Z johnnyw $ + +#include "ace/WIN32_Asynch_IO.h" + +ACE_RCSID (ace, + Win32_Asynch_IO, + "$Id: WIN32_Asynch_IO.cpp 82444 2008-07-28 13:33:07Z johnnyw $") + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) && \ + (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 1)) + +#include "ace/WIN32_Proactor.h" +#include "ace/Proactor.h" +#include "ace/Message_Block.h" +#include "ace/Service_Config.h" +#include "ace/INET_Addr.h" +#include "ace/Task_T.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_socket.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +size_t +ACE_WIN32_Asynch_Result::bytes_transferred (void) const +{ + return this->bytes_transferred_; +} + +const void * +ACE_WIN32_Asynch_Result::act (void) const +{ + return this->act_; +} + +int +ACE_WIN32_Asynch_Result::success (void) const +{ + return this->success_; +} + +const void * +ACE_WIN32_Asynch_Result::completion_key (void) const +{ + return this->completion_key_; +} + +u_long +ACE_WIN32_Asynch_Result::error (void) const +{ + return this->error_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Result::event (void) const +{ + return this->hEvent; +} + +u_long +ACE_WIN32_Asynch_Result::offset (void) const +{ + return this->Offset; +} + +u_long +ACE_WIN32_Asynch_Result::offset_high (void) const +{ + return this->OffsetHigh; +} + +int +ACE_WIN32_Asynch_Result::priority (void) const +{ + ACE_NOTSUP_RETURN (0); +} + +int +ACE_WIN32_Asynch_Result::signal_number (void) const +{ + ACE_NOTSUP_RETURN (0); +} + +int +ACE_WIN32_Asynch_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + // Get to the platform specific implementation. + ACE_WIN32_Proactor *win32_proactor = dynamic_cast (proactor); + + if (win32_proactor == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Dynamic cast to WIN32 Proactor failed\n")), + -1); + + // Post myself. + return win32_proactor->post_completion (this); +} + +void +ACE_WIN32_Asynch_Result::set_bytes_transferred (size_t nbytes) +{ + this->bytes_transferred_ = nbytes; +} + +void +ACE_WIN32_Asynch_Result::set_error (u_long errcode) +{ + this->error_ = errcode; +} + +ACE_WIN32_Asynch_Result::~ACE_WIN32_Asynch_Result (void) +{ +} + +ACE_WIN32_Asynch_Result::ACE_WIN32_Asynch_Result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + const void* act, + ACE_HANDLE event, + u_long offset, + u_long offset_high, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + OVERLAPPED (), + handler_proxy_ (handler_proxy), + act_ (act), + bytes_transferred_ (0), + success_ (0), + completion_key_ (0), + error_ (0) +{ + // Set the ACE_OVERLAPPED structure + this->Internal = 0; + this->InternalHigh = 0; + this->Offset = offset; + this->OffsetHigh = offset_high; + this->hEvent = event; + + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (signal_number); +} + +int +ACE_WIN32_Asynch_Operation::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + this->proactor_ = proactor; + this->handler_proxy_ = handler_proxy; + this->handle_ = handle; + + // Grab the handle from the if is invalid + if (this->handle_ == ACE_INVALID_HANDLE) + { + ACE_Handler *handler = handler_proxy.get ()->handler (); + if (handler != 0) + this->handle_ = handler->handle (); + } + if (this->handle_ == ACE_INVALID_HANDLE) + return -1; + + if (this->proactor_!= 0) + // update implementation. + this->win32_proactor_ = + dynamic_cast (this->proactor_->implementation ()); + + // Register with the . + return this->win32_proactor_->register_handle (this->handle_, + completion_key); +} + +int +ACE_WIN32_Asynch_Operation::cancel (void) +{ +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + // All I/O operations that are canceled will complete with the error + // ERROR_OPERATION_ABORTED. All completion notifications for the I/O + // operations will occur normally. + + // @@ This API returns 0 on failure. So, I am returning -1 in that + // case. Is that right? (Alex). + int const result = (int) ::CancelIo (this->handle_); + + if (result == 0) + // Couldn't cancel the operations. + return 2; + + // result is non-zero. All the operations are cancelled then. + return 0; + +#else /* !ACE_HAS_WIN32_OVERLAPPED_IO */ + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_AIO_CALLS */ +} + +ACE_Proactor * +ACE_WIN32_Asynch_Operation::proactor (void) const +{ + return this->proactor_; +} + +ACE_WIN32_Asynch_Operation::ACE_WIN32_Asynch_Operation (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + win32_proactor_ (win32_proactor), + proactor_ (0), + handle_ (ACE_INVALID_HANDLE) +{ +} + +ACE_WIN32_Asynch_Operation::~ACE_WIN32_Asynch_Operation (void) +{ +} + +// ************************************************************ + +size_t +ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read (void) const +{ + return this->bytes_to_read_; +} + +ACE_Message_Block & +ACE_WIN32_Asynch_Read_Stream_Result::message_block (void) const +{ + return this->message_block_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Read_Stream_Result::handle (void) const +{ + return this->handle_; +} + +ACE_WIN32_Asynch_Read_Stream_Result::ACE_WIN32_Asynch_Read_Stream_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number, + int scatter_enabled) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Read_Stream_Result_Impl (), + ACE_WIN32_Asynch_Result (handler_proxy, + act, + event, + 0, + 0, + priority, + signal_number), + bytes_to_read_ (bytes_to_read), + message_block_ (message_block), + handle_ (handle), + scatter_enabled_ (scatter_enabled) +{ +} + +void +ACE_WIN32_Asynch_Read_Stream_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + if (!this->scatter_enabled ()) + this->message_block_.wr_ptr (bytes_transferred); + else + { + for (ACE_Message_Block* mb = &this->message_block_; + (mb != 0) && (bytes_transferred > 0); + mb = mb->cont ()) + { + size_t len_part = mb->space (); + + if (len_part > bytes_transferred) + len_part = bytes_transferred; + + mb->wr_ptr (len_part); + + bytes_transferred -= len_part; + } + } + + // Create the interface result class. + ACE_Asynch_Read_Stream::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_read_stream (result); +} + +ACE_WIN32_Asynch_Read_Stream_Result::~ACE_WIN32_Asynch_Read_Stream_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Read_Stream_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Read_Stream_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Read_Stream_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Read_Stream_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Read_Stream_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Read_Stream_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Read_Stream_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Read_Stream_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Read_Stream_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Read_Stream_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Read_Stream_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +int +ACE_WIN32_Asynch_Read_Stream_Result::scatter_enabled (void) const +{ + return this->scatter_enabled_; +} + +ACE_WIN32_Asynch_Read_Stream::ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Read_Stream_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor) +{ +} + +int +ACE_WIN32_Asynch_Read_Stream::read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) +{ + size_t space = message_block.space (); + if (bytes_to_read > space) + bytes_to_read = space; + + if (bytes_to_read == 0) + { + errno = ENOSPC; + return -1; + } + + // Create the Asynch_Result. + ACE_WIN32_Asynch_Read_Stream_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_read, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + // Shared read + int const return_val = this->shared_read (result); + + // Upon errors + if (return_val == -1) + delete result; + + return return_val; +} + +int +ACE_WIN32_Asynch_Read_Stream::readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) +{ +#if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + // We should not read more than user requested, + // but it is allowed to read less + + for (const ACE_Message_Block* msg = &message_block; + msg != 0 && bytes_to_read > 0 && iovcnt < ACE_IOV_MAX; + msg = msg->cont () , ++iovcnt ) + { + size_t msg_space = msg->space (); + + // OS should correctly process zero length buffers + // if ( msg_space == 0 ) + // ACE_ERROR_RETURN ((LM_ERROR, + // ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:") + // ACE_TEXT ("No space in the message block\n")), + // -1); + + if (msg_space > bytes_to_read) + msg_space = bytes_to_read; + bytes_to_read -= msg_space; + + // Make as many iovec as needed to fit all of msg_space. + size_t wr_ptr_offset = 0; + + while (msg_space > 0 && iovcnt < ACE_IOV_MAX) + { + u_long this_chunk_length; + if (msg_space > ULONG_MAX) + this_chunk_length = ULONG_MAX; + else + this_chunk_length = static_cast (msg_space); + // Collect the data in the iovec. + iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset; + iov[iovcnt].iov_len = this_chunk_length; + msg_space -= this_chunk_length; + wr_ptr_offset += this_chunk_length; + + // Increment iovec counter if there's more to do. + if (msg_space > 0) + ++iovcnt; + } + if (msg_space > 0) // Ran out of iovecs before msg_space exhausted + { + errno = ERANGE; + return -1; + } + } + + // Re-calculate number bytes to read + bytes_to_read = 0; + + for (int i = 0; i < iovcnt ; ++i) + bytes_to_read += iov[i].iov_len; + + if (bytes_to_read == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:") + ACE_TEXT ("Attempt to read 0 bytes\n")), + -1); + + // Create the Asynch_Result. + ACE_WIN32_Asynch_Read_Stream_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_read, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number, + 1), // scatter read enabled + -1); + + // do the scatter recv + + result->set_error (0); // Clear error before starting IO. + + DWORD bytes_recvd = 0; + u_long flags = 0; + + int initiate_result = ::WSARecv (reinterpret_cast (result->handle ()), + reinterpret_cast (iov), + iovcnt, + &bytes_recvd, + &flags, + result, + 0); + + if (0 == initiate_result) + // Immediate success: the OVERLAPPED will still get queued. + return 1; + + ACE_ASSERT (initiate_result == SOCKET_ERROR); + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + initiate_result = 0; + break; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WSARecv"))); + } + + delete result; + initiate_result = -1; + break; + } + + return initiate_result; +#else + ACE_UNUSED_ARG (message_block); + ACE_UNUSED_ARG (bytes_to_read); + ACE_UNUSED_ARG (act); + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (signal_number); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */ +} + +ACE_WIN32_Asynch_Read_Stream::~ACE_WIN32_Asynch_Read_Stream (void) +{ +} + +int +ACE_WIN32_Asynch_Read_Stream::shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result) +{ + // ReadFile API limits us to DWORD range. + if (result->bytes_to_read () > MAXDWORD) + { + errno = ERANGE; + return -1; + } + DWORD bytes_to_read = static_cast (result->bytes_to_read ()); + u_long bytes_read; + + result->set_error (0); // Clear error before starting IO. + + // Initiate the read + int initiate_result = ::ReadFile (result->handle (), + result->message_block ().wr_ptr (), + bytes_to_read, + &bytes_read, + result); + if (initiate_result == 1) + // Immediate success: the OVERLAPPED will still get queued. + return 0; + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + /* FALLTHRU */ + case ERROR_MORE_DATA: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + return 0; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ReadFile"))); + } + + return -1; + } +} + +// Methods belong to ACE_WIN32_Asynch_Operation base class. These +// methods are defined here to avoid VC++ warnings. They route the +// call to the ACE_WIN32_Asynch_Operation base class. + +int +ACE_WIN32_Asynch_Read_Stream::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Read_Stream::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Read_Stream::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +size_t +ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write (void) const +{ + return this->bytes_to_write_; +} + +ACE_Message_Block & +ACE_WIN32_Asynch_Write_Stream_Result::message_block (void) const +{ + return this->message_block_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Write_Stream_Result::handle (void) const +{ + return this->handle_; +} + +ACE_WIN32_Asynch_Write_Stream_Result::ACE_WIN32_Asynch_Write_Stream_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number, + int gather_enabled) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Write_Stream_Result_Impl (), + ACE_WIN32_Asynch_Result + (handler_proxy, act, event, 0, 0, priority, signal_number), + bytes_to_write_ (bytes_to_write), + message_block_ (message_block), + handle_ (handle), + gather_enabled_ (gather_enabled) +{ +} + +void +ACE_WIN32_Asynch_Write_Stream_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by . + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + if (!this->gather_enabled ()) + this->message_block_.rd_ptr (bytes_transferred); + else + { + for (ACE_Message_Block* mb = &this->message_block_; + (mb != 0) && (bytes_transferred > 0); + mb = mb->cont ()) + { + size_t len_part = mb->length (); + + if ( len_part > bytes_transferred) + len_part = bytes_transferred; + + mb->rd_ptr (len_part); + + bytes_transferred -= len_part; + } + } + + // Create the interface result class. + ACE_Asynch_Write_Stream::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_write_stream (result); +} + +ACE_WIN32_Asynch_Write_Stream_Result::~ACE_WIN32_Asynch_Write_Stream_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Write_Stream_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Write_Stream_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Write_Stream_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Write_Stream_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Write_Stream_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Write_Stream_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Write_Stream_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Write_Stream_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Write_Stream_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Write_Stream_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Write_Stream_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +int +ACE_WIN32_Asynch_Write_Stream_Result::gather_enabled (void) const +{ + return this->gather_enabled_; +} + +ACE_WIN32_Asynch_Write_Stream::ACE_WIN32_Asynch_Write_Stream (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Write_Stream_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor) +{ +} + +int +ACE_WIN32_Asynch_Write_Stream::write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) +{ + size_t len = message_block.length(); + + if (bytes_to_write > len) + bytes_to_write = len ; + + if (bytes_to_write == 0) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::write:") + ACE_TEXT ("Attempt to write 0 bytes\n")), + -1); + + ACE_WIN32_Asynch_Write_Stream_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_write, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + // Shared write + int return_val = this->shared_write (result); + + // Upon errors + if (return_val == -1) + delete result; + + return return_val; +} + +int +ACE_WIN32_Asynch_Write_Stream::writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) +{ +#if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + // We should not write more than user requested, + // but it is allowed to write less + + for (const ACE_Message_Block* msg = &message_block; + msg != 0 && bytes_to_write > 0 && iovcnt < ACE_IOV_MAX; + msg = msg->cont ()) + { + size_t msg_len = msg->length (); + + // Skip 0-length blocks. + if (msg_len == 0) + continue; + if (msg_len > bytes_to_write) + msg_len = bytes_to_write; + bytes_to_write -= msg_len; + + // Make as many iovec as needed to fit all of msg_len. + size_t rd_ptr_offset = 0; + + while (msg_len > 0 && iovcnt < ACE_IOV_MAX) + { + u_long this_chunk_length; + if (msg_len > ULONG_MAX) + this_chunk_length = ULONG_MAX; + else + this_chunk_length = static_cast (msg_len); + // Collect the data in the iovec. + iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset; + iov[iovcnt].iov_len = this_chunk_length; + msg_len -= this_chunk_length; + rd_ptr_offset += this_chunk_length; + + // Increment iovec counter if there's more to do. + if (msg_len > 0) + iovcnt++; + } + if (msg_len > 0) // Ran out of iovecs before msg_space exhausted + { + errno = ERANGE; + return -1; + } + ++iovcnt; + } + + // Re-calculate number bytes to write + bytes_to_write = 0; + + for ( int i=0; i < iovcnt ; ++i ) + bytes_to_write += iov[i].iov_len; + + if ( bytes_to_write == 0 ) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Write_Stream::writev:") + ACE_TEXT ("Attempt to write 0 bytes\n")), + -1); + + + ACE_WIN32_Asynch_Write_Stream_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Write_Stream_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_write, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number, + 1), // gather write enabled + -1); + + // do the gather send + + u_long bytes_sent = 0; + + int initiate_result = ::WSASend (reinterpret_cast (result->handle ()), + reinterpret_cast (iov), + iovcnt, + &bytes_sent, + 0, // flags + result, + 0); + + if (0 == initiate_result) + // Immediate success: the OVERLAPPED will still get queued. + return 1; + + ACE_ASSERT (initiate_result == SOCKET_ERROR); + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + initiate_result = 0; + break; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WSASend"))); + } + + delete result; + initiate_result = -1; + break; + } + + return initiate_result; +#else + ACE_UNUSED_ARG (message_block); + ACE_UNUSED_ARG (bytes_to_write); + ACE_UNUSED_ARG (act); + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (signal_number); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */ +} + +ACE_WIN32_Asynch_Write_Stream::~ACE_WIN32_Asynch_Write_Stream (void) +{ +} + +int +ACE_WIN32_Asynch_Write_Stream::shared_write (ACE_WIN32_Asynch_Write_Stream_Result *result) +{ + u_long bytes_written; + if (result->bytes_to_write () > MAXDWORD) + { + errno = ERANGE; + return -1; + } + DWORD bytes_to_write = static_cast (result->bytes_to_write ()); + + result->set_error (0); // Clear error before starting IO. + + // Initiate the write; Winsock 2 is required for the higher-performing + // WSASend() function. For Winsock 1, fall back to the slower WriteFile(). + int initiate_result = 0; +#if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) + WSABUF iov; + iov.buf = result->message_block ().rd_ptr (); + iov.len = bytes_to_write; + initiate_result = ::WSASend (reinterpret_cast (result->handle ()), + &iov, + 1, + &bytes_written, + 0, // flags + result, + 0); + if (initiate_result == 0) + // Immediate success: the OVERLAPPED will still get queued. + return 0; +#else + initiate_result = ::WriteFile (result->handle (), + result->message_block ().rd_ptr (), + bytes_to_write, + &bytes_written, + result); + if (initiate_result == 1) + // Immediate success: the OVERLAPPED will still get queued. + return 0; +#endif /* ACE_HAS_WINSOCK2 */ + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + return 0; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Initiating write"))); + return -1; + } +} + +// Methods belong to ACE_WIN32_Asynch_Operation base class. These +// methods are defined here to avoid VC++ warnings. They route the +// call to the ACE_WIN32_Asynch_Operation base class. + +int +ACE_WIN32_Asynch_Write_Stream::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Write_Stream::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Write_Stream::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +ACE_WIN32_Asynch_Read_File_Result::ACE_WIN32_Asynch_Read_File_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number, + int scatter_enabled) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Read_Stream_Result_Impl (), + ACE_Asynch_Read_File_Result_Impl (), + ACE_WIN32_Asynch_Read_Stream_Result (handler_proxy, + handle, + message_block, + bytes_to_read, + act, + event, + priority, + signal_number, + scatter_enabled) +{ + this->Offset = offset; + this->OffsetHigh = offset_high; +} + +void +ACE_WIN32_Asynch_Read_File_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus. + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + if (!this->scatter_enabled ()) + this->message_block_.wr_ptr (bytes_transferred); + else + { + static const size_t page_size = ACE_OS::getpagesize(); + + for (ACE_Message_Block* mb = &this->message_block_; + (mb != 0) && (bytes_transferred > 0); + mb = mb->cont ()) + { + // mb->space () is ought to be >= page_size. + // this is verified in the readv method + // ACE_ASSERT (mb->space () >= page_size); + + size_t len_part = page_size ; + + if ( len_part > bytes_transferred) + len_part = bytes_transferred; + + mb->wr_ptr (len_part); + + bytes_transferred -= len_part; + } + } + + // Create the interface result class. + ACE_Asynch_Read_File::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_read_file (result); +} + +ACE_WIN32_Asynch_Read_File_Result::~ACE_WIN32_Asynch_Read_File_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Read_File_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Read_File_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Read_File_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Read_File_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Read_File_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Read_File_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Read_File_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Read_File_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Read_File_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Read_File_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +// The following methods belong to +// ACE_WIN32_Asynch_Read_Stream_Result. They are here to avoid VC++ +// warnings. These methods route their call to the +// ACE_WIN32_Asynch_Read_Stream_Result base class. + +size_t +ACE_WIN32_Asynch_Read_File_Result::bytes_to_read (void) const +{ + return ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read (); +} + +ACE_Message_Block & +ACE_WIN32_Asynch_Read_File_Result::message_block (void) const +{ + return ACE_WIN32_Asynch_Read_Stream_Result::message_block (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Read_File_Result::handle (void) const +{ + return ACE_WIN32_Asynch_Read_Stream_Result::handle (); +} + +int +ACE_WIN32_Asynch_Read_File_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +// ************************************************************ + +ACE_WIN32_Asynch_Read_File::ACE_WIN32_Asynch_Read_File (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Read_Stream_Impl (), + ACE_Asynch_Read_File_Impl (), + ACE_WIN32_Asynch_Read_Stream (win32_proactor) +{ +} + +int +ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block &message_block, + size_t bytes_to_read, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) +{ + size_t space = message_block.space (); + if ( bytes_to_read > space ) + bytes_to_read = space; + + if ( bytes_to_read == 0 ) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Read_File::read:") + ACE_TEXT ("Attempt to read 0 bytes or no space in the message block\n")), + -1); + + + ACE_WIN32_Asynch_Read_File_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_read, + act, + offset, + offset_high, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + // Shared read + int return_val = this->shared_read (result); + + // Upon errors + if (return_val == -1) + delete result; + + return return_val; +} + +int +ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) +{ +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + static const size_t page_size = ACE_OS::getpagesize(); + + FILE_SEGMENT_ELEMENT buffer_pointers[ACE_IOV_MAX + 1]; + int buffer_pointers_count = 0; + + // Each buffer must be at least the size of a system memory page + // and must be aligned on a system memory page size boundary + + // We should not read more than user requested, + // but it is allowed to read less + + size_t total_space = 0; + + for (const ACE_Message_Block* msg = &message_block; + msg != 0 && buffer_pointers_count < ACE_IOV_MAX && total_space < bytes_to_read; + msg = msg->cont(), ++buffer_pointers_count ) + { + size_t msg_space = msg->space (); + + if (msg_space < page_size) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Read_File::readv:") + ACE_TEXT ("Invalid message block size\n")), + -1); + + buffer_pointers[buffer_pointers_count].Buffer = msg->wr_ptr (); + total_space += page_size; + } + + // not read more than buffers space + if (bytes_to_read > total_space) + bytes_to_read = total_space; + + // ReadFileScatter API limits us to DWORD range. + if (bytes_to_read > MAXDWORD) + { + errno = ERANGE; + return -1; + } + DWORD dword_bytes_to_read = static_cast (bytes_to_read); + + // last one should be completely 0 + buffer_pointers[buffer_pointers_count].Buffer = 0; + + ACE_WIN32_Asynch_Read_File_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Read_File_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_read, + act, + offset, + offset_high, + this->win32_proactor_->get_handle (), + priority, + signal_number, + 1), // scatter read enabled + -1); + + // do the scatter read + result->set_error (0); // Clear error before starting IO. + + int initiate_result = ::ReadFileScatter (result->handle (), + buffer_pointers, + dword_bytes_to_read, + 0, // reserved, must be NULL + result); + + if (0 != initiate_result) + // Immediate success: the OVERLAPPED will still get queued. + return 1; + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + initiate_result = 0; + break; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ReadFileScatter"))); + } + + delete result; + initiate_result = -1; + break; + } + + return initiate_result; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32_OVERLAPPED_IO */ +} + + +ACE_WIN32_Asynch_Read_File::~ACE_WIN32_Asynch_Read_File (void) +{ +} + +int +ACE_WIN32_Asynch_Read_File::read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) +{ + return ACE_WIN32_Asynch_Read_Stream::read (message_block, + bytes_to_read, + act, + priority, + signal_number); +} + +int +ACE_WIN32_Asynch_Read_File::readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number) +{ + return ACE_WIN32_Asynch_Read_Stream::readv (message_block, + bytes_to_read, + act, + priority, + signal_number); +} + +// Methods belong to ACE_WIN32_Asynch_Operation base class. These +// methods are defined here to avoid VC++ warnings. They route the +// call to the ACE_WIN32_Asynch_Operation base class. + +int +ACE_WIN32_Asynch_Read_File::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Read_File::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Read_File::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +ACE_WIN32_Asynch_Write_File_Result::ACE_WIN32_Asynch_Write_File_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number, + int gather_enabled) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Write_Stream_Result_Impl (), + ACE_Asynch_Write_File_Result_Impl (), + ACE_WIN32_Asynch_Write_Stream_Result (handler_proxy, + handle, + message_block, + bytes_to_write, + act, + event, + priority, + signal_number, + gather_enabled) +{ + this->Offset = offset; + this->OffsetHigh = offset_high; +} + +void +ACE_WIN32_Asynch_Write_File_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + if (!this->gather_enabled ()) + this->message_block_.rd_ptr (bytes_transferred); + else + { + static const size_t page_size = ACE_OS::getpagesize(); + + for (ACE_Message_Block* mb = &this->message_block_; + (mb != 0) && (bytes_transferred > 0); + mb = mb->cont ()) + { + // mb->length () is ought to be >= page_size. + // this is verified in the writev method + // ACE_ASSERT (mb->length () >= page_size); + + size_t len_part = page_size; + + if ( len_part > bytes_transferred) + len_part = bytes_transferred; + + mb->rd_ptr (len_part); + + bytes_transferred -= len_part; + } + + } + + // Create the interface result class. + ACE_Asynch_Write_File::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_write_file (result); +} + +ACE_WIN32_Asynch_Write_File_Result::~ACE_WIN32_Asynch_Write_File_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Write_File_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Write_File_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Write_File_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Write_File_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Write_File_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Write_File_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Write_File_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Write_File_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Write_File_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Write_File_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +// The following methods belong to +// ACE_WIN32_Asynch_Write_Stream_Result. They are here to avoid VC++ +// warnings. These methods route their call to the +// ACE_WIN32_Asynch_Write_Stream_Result base class. + +size_t +ACE_WIN32_Asynch_Write_File_Result::bytes_to_write (void) const +{ + return ACE_WIN32_Asynch_Write_Stream_Result::bytes_to_write (); +} + +ACE_Message_Block & +ACE_WIN32_Asynch_Write_File_Result::message_block (void) const +{ + return ACE_WIN32_Asynch_Write_Stream_Result::message_block (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Write_File_Result::handle (void) const +{ + return ACE_WIN32_Asynch_Write_Stream_Result::handle (); +} + +int +ACE_WIN32_Asynch_Write_File_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +ACE_WIN32_Asynch_Write_File::ACE_WIN32_Asynch_Write_File (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Write_Stream_Impl (), + ACE_Asynch_Write_File_Impl (), + ACE_WIN32_Asynch_Write_Stream (win32_proactor) +{ +} + +int +ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block &message_block, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) +{ + size_t len = message_block.length (); + if ( bytes_to_write > len ) + bytes_to_write = len; + + if ( bytes_to_write == 0 ) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Write_File::write:") + ACE_TEXT ("Attempt to read 0 bytes\n")), + -1); + + ACE_WIN32_Asynch_Write_File_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_write, + act, + offset, + offset_high, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + // Shared write + int return_val = this->shared_write (result); + + // Upon errors + if (return_val == -1) + delete result; + + return return_val; +} + +int +ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number) +{ +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + static const size_t page_size = ACE_OS::getpagesize(); + + FILE_SEGMENT_ELEMENT buffer_pointers[ACE_IOV_MAX + 1]; + int buffer_pointers_count = 0; + + // Each buffer must be at least the size of a system memory page + // and must be aligned on a system memory page size boundary + + // We should not read more than user requested, + // but it is allowed to read less + + size_t total_len = 0; + + for (const ACE_Message_Block* msg = &message_block; + msg != 0 && buffer_pointers_count < ACE_IOV_MAX && total_len < bytes_to_write; + msg = msg->cont (), ++buffer_pointers_count ) + { + size_t msg_len = msg->length (); + + // Don't allow writing less than page_size, unless + // the size of the message block is big enough (so we don't write from + // memory which does not belong to the message block), and the message + // block is the last in the chain. + if (msg_len < page_size && + (msg->size () - (msg->rd_ptr () - msg->base ()) < page_size || // message block too small + bytes_to_write - total_len > page_size ))// NOT last chunk + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Write_File::writev:") + ACE_TEXT ("Invalid message block length\n")), + -1); + + buffer_pointers[buffer_pointers_count].Buffer = msg->rd_ptr (); + total_len += page_size; + } + + // not write more than we have in buffers + if (bytes_to_write > total_len) + bytes_to_write = total_len; + // WriteFileGather API limits us to DWORD range. + if (bytes_to_write > MAXDWORD) + { + errno = ERANGE; + return -1; + } + DWORD dword_bytes_to_write = static_cast (bytes_to_write); + + // last one should be completely 0 + buffer_pointers[buffer_pointers_count].Buffer = 0; + + ACE_WIN32_Asynch_Write_File_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Write_File_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_write, + act, + offset, + offset_high, + this->win32_proactor_->get_handle (), + priority, + signal_number, + 1), // gather write enabled + -1); + + result->set_error(0); + + // do the gather write + int initiate_result = ::WriteFileGather (result->handle (), + buffer_pointers, + dword_bytes_to_write, + 0, // reserved, must be NULL + result); + + if (0 != initiate_result) + // Immediate success: the OVERLAPPED will still get queued. + return 1; + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + initiate_result = 0; + break; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WriteFileGather"))); + } + + delete result; + initiate_result = -1; + break; + } + + return initiate_result; +#else + + ACE_NOTSUP_RETURN (-1); + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ +} + + +ACE_WIN32_Asynch_Write_File::~ACE_WIN32_Asynch_Write_File (void) +{ +} + +int +ACE_WIN32_Asynch_Write_File::write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) +{ + return ACE_WIN32_Asynch_Write_Stream::write (message_block, + bytes_to_write, + act, + priority, + signal_number); +} + +int +ACE_WIN32_Asynch_Write_File::writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number) +{ + return ACE_WIN32_Asynch_Write_Stream::writev (message_block, + bytes_to_write, + act, + priority, + signal_number); +} + +// Methods belong to ACE_WIN32_Asynch_Operation base class. These +// methods are defined here to avoid VC++ warnings. They route the +// call to the ACE_WIN32_Asynch_Operation base class. + +int +ACE_WIN32_Asynch_Write_File::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Write_File::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Write_File::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +size_t +ACE_WIN32_Asynch_Accept_Result::bytes_to_read (void) const +{ + return this->bytes_to_read_; +} + +ACE_Message_Block & +ACE_WIN32_Asynch_Accept_Result::message_block (void) const +{ + return this->message_block_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Accept_Result::listen_handle (void) const +{ + return this->listen_handle_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Accept_Result::accept_handle (void) const +{ + return this->accept_handle_; +} + +ACE_WIN32_Asynch_Accept_Result::ACE_WIN32_Asynch_Accept_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE listen_handle, + ACE_HANDLE accept_handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Accept_Result_Impl (), + ACE_WIN32_Asynch_Result (handler_proxy, + act, + event, + 0, + 0, + priority, + signal_number), + bytes_to_read_ (bytes_to_read), + message_block_ (message_block), + listen_handle_ (listen_handle), + accept_handle_ (accept_handle) +{ +} + +void +ACE_WIN32_Asynch_Accept_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + this->message_block_.wr_ptr (bytes_transferred); + + if (!success && this->accept_handle_ != ACE_INVALID_HANDLE) + { + ACE_OS::closesocket (this->accept_handle_); + this->accept_handle_ = ACE_INVALID_HANDLE; + } + + // Create the interface result class. + ACE_Asynch_Accept::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_accept (result); +} + +ACE_WIN32_Asynch_Accept_Result::~ACE_WIN32_Asynch_Accept_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Accept_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Accept_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Accept_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Accept_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Accept_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Accept_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Accept_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Accept_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Accept_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Accept_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Accept_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +ACE_WIN32_Asynch_Accept::ACE_WIN32_Asynch_Accept (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Accept_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor) +{ +} + +int +ACE_WIN32_Asynch_Accept::accept (ACE_Message_Block &message_block, + size_t bytes_to_read, + ACE_HANDLE accept_handle, + const void *act, + int priority, + int signal_number, + int addr_family) +{ +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) + // Sanity check: make sure that enough space has been allocated by + // the caller. + size_t address_size = +#if defined (ACE_HAS_IPV6) + addr_family == AF_INET ? sizeof (sockaddr_in) : sizeof (sockaddr_in6); +#else + sizeof (sockaddr_in); +#endif /* ACE_HAS_IPV6 */ + address_size += 16; // AcceptEx requires address size + 16 (minimum) + size_t available_space = message_block.space (); + size_t space_needed = bytes_to_read + 2 * address_size; + if (available_space < space_needed) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Buffer too small\n")), -1); + + // WIN Specific. + + // AcceptEx API limits us to DWORD range. + if (bytes_to_read > MAXDWORD) + { + errno = ERANGE; + return -1; + } + DWORD dword_bytes_to_read = static_cast (bytes_to_read); + + int close_accept_handle = 0; + // If the is invalid, we will create a new socket. + if (accept_handle == ACE_INVALID_HANDLE) + { + accept_handle = ACE_OS::socket (addr_family, + SOCK_STREAM, + 0); + if (accept_handle == ACE_INVALID_HANDLE) + { + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_OS::socket"))); + } + return -1; + } + else + // Remember to close the socket down if failures occur. + close_accept_handle = 1; + } + + // Common code for both WIN and POSIX. + ACE_WIN32_Asynch_Accept_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Accept_Result (this->handler_proxy_, + this->handle_, + accept_handle, + message_block, + bytes_to_read, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + u_long bytes_read; + + // Initiate the accept. + int initiate_result = ::AcceptEx ((SOCKET) result->listen_handle (), + (SOCKET) result->accept_handle (), + result->message_block ().wr_ptr (), + dword_bytes_to_read, + static_cast (address_size), + static_cast (address_size), + &bytes_read, + result); + if (initiate_result == 1) + // Immediate success: the OVERLAPPED will still get queued. + return 1; + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + return 0; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (close_accept_handle == 1) + // Close the newly created socket + ACE_OS::closesocket (accept_handle); + + // Cleanup dynamically allocated Asynch_Result. + delete result; + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("AcceptEx"))); + } + return -1; + } +#else + ACE_UNUSED_ARG (message_block); + ACE_UNUSED_ARG (bytes_to_read); + ACE_UNUSED_ARG (accept_handle); + ACE_UNUSED_ARG (act); + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (signal_number); + ACE_UNUSED_ARG (addr_family); + ACE_NOTSUP_RETURN (-1); +#endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) */ +} + +ACE_WIN32_Asynch_Accept::~ACE_WIN32_Asynch_Accept (void) +{ +} + +// Methods belong to ACE_WIN32_Asynch_Operation base class. These +// methods are defined here to avoid VC++ warnings. They route the +// call to the ACE_WIN32_Asynch_Operation base class. + +int +ACE_WIN32_Asynch_Accept::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Accept::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Accept::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +// ********************************************************************* + +ACE_HANDLE +ACE_WIN32_Asynch_Connect_Result::connect_handle (void) const +{ + return this->connect_handle_; +} + +void ACE_WIN32_Asynch_Connect_Result::connect_handle ( ACE_HANDLE handle ) +{ + this->connect_handle_ = handle; +} + + +ACE_WIN32_Asynch_Connect_Result::ACE_WIN32_Asynch_Connect_Result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE connect_handle, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Connect_Result_Impl (), + ACE_WIN32_Asynch_Result + (handler_proxy, act, event, 0, 0, priority, signal_number), + connect_handle_ (connect_handle) +{ + ; +} + +void +ACE_WIN32_Asynch_Connect_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data. + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Create the interface result class. + ACE_Asynch_Connect::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_connect (result); +} + +ACE_WIN32_Asynch_Connect_Result::~ACE_WIN32_Asynch_Connect_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Connect_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Connect_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Connect_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Connect_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Connect_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Connect_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Connect_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Connect_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Connect_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Connect_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Connect_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +// ********************************************************************* + +ACE_WIN32_Asynch_Connect::ACE_WIN32_Asynch_Connect (ACE_WIN32_Proactor * win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Connect_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor), + flg_open_ (false) +{ +} + +ACE_WIN32_Asynch_Connect::~ACE_WIN32_Asynch_Connect (void) +{ + this->close (); + this->reactor (0); // to avoid purge_pending_notifications +} + +ACE_Proactor * +ACE_WIN32_Asynch_Connect::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Connect::get_handle (void) const +{ + + ACE_ASSERT (0); + return ACE_INVALID_HANDLE; +} + +void +ACE_WIN32_Asynch_Connect::set_handle (ACE_HANDLE) +{ + ACE_ASSERT (0) ; +} + +int +ACE_WIN32_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE, + const void *completion_key, + ACE_Proactor *proactor) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::open"); + + // if we are already opened, + // we could not create a new handler without closing the previous + if (this->flg_open_) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::open:") + ACE_TEXT ("connector already open \n")), + -1); + + //int result = + ACE_WIN32_Asynch_Operation::open (handler_proxy, + ACE_INVALID_HANDLE, + completion_key, + proactor); + + // Ignore result as we pass ACE_INVALID_HANDLE + //if (result == -1) + // return result; + + this->flg_open_ = true; + + return 0; +} + +int +ACE_WIN32_Asynch_Connect::connect (ACE_HANDLE connect_handle, + const ACE_Addr & remote_sap, + const ACE_Addr & local_sap, + int reuse_addr, + const void *act, + int priority, + int signal_number) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::connect"); + + if (!this->flg_open_) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%N:%l:ACE_WIN32_Asynch_Connect::connect") + ACE_TEXT ("connector was not opened before\n")), + -1); + + // Common code for both WIN and WIN32. + // Create future Asynch_Connect_Result + ACE_WIN32_Asynch_Connect_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Connect_Result (this->handler_proxy_, + connect_handle, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + int rc = connect_i (result, + remote_sap, + local_sap, + reuse_addr); + + // update handle + connect_handle = result->connect_handle (); + + if (rc != 0) + return post_result (result, true); + + // Enqueue result we will wait for completion + { + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1)); + + if (this->result_map_.bind (connect_handle, result) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect: %p\n"), + ACE_TEXT ("bind"))); + result->set_error (EFAULT); + return post_result (result, true); + } + } + + ACE_Asynch_Pseudo_Task & task = + this->win32_proactor_->get_asynch_pseudo_task (); + + if (-1 == task.register_io_handler (connect_handle, + this, + ACE_Event_Handler::CONNECT_MASK, + 0)) // not to suspend after register + { + result = 0; + { + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1)); + this->result_map_.unbind (connect_handle, result); + } + if (result != 0) + { + result->set_error (EFAULT); + this->post_result (result, true); + } + } + + return 0; +} + +int ACE_WIN32_Asynch_Connect::post_result (ACE_WIN32_Asynch_Connect_Result * result, + bool post_enable) +{ + ACE_HANDLE handle = result->connect_handle (); + if (this->flg_open_ && post_enable) + { + // NOTE: result is invalid after post_completion(). It's either deleted + // or will be shortly via the proactor dispatch, regardless of success + // or fail of the call. + if (this->win32_proactor_ ->post_completion (result) == 0) + return 0; + + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Error:(%P | %t):%p\n"), + ACE_TEXT ("ACE_WIN32_Asynch_Connect::post_result: ") + ACE_TEXT (" failed"))); + } + else + { + // There was no call to post_completion() so manually delete result. + delete result; + } + + if (handle != ACE_INVALID_HANDLE) + ACE_OS::closesocket (handle); + + return -1; +} + +// connect_i +// return code : +// -1 errors before attempt to connect +// 0 connect started +// 1 connect finished ( may be unsuccessfully) + +int +ACE_WIN32_Asynch_Connect::connect_i (ACE_WIN32_Asynch_Connect_Result *result, + const ACE_Addr & remote_sap, + const ACE_Addr & local_sap, + int reuse_addr) +{ + result->set_bytes_transferred (0); + + ACE_HANDLE handle = result->connect_handle (); + if (handle == ACE_INVALID_HANDLE) + { + int protocol_family = remote_sap.get_type (); + handle = ACE_OS::socket (protocol_family, + SOCK_STREAM, + 0); + + // save it + result->connect_handle (handle); + if (handle == ACE_INVALID_HANDLE) + { + result->set_error (errno); + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"), + ACE_TEXT ("socket")), + -1); + } + + // Reuse the address + int one = 1; + if (protocol_family != PF_UNIX && + reuse_addr != 0 && + ACE_OS::setsockopt (handle, + SOL_SOCKET, + SO_REUSEADDR, + (const char*) &one, + sizeof one) == -1) + { + result->set_error (errno); + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"), + ACE_TEXT ("setsockopt")), + -1); + } + } + + if (local_sap != ACE_Addr::sap_any) + { + sockaddr * laddr = reinterpret_cast (local_sap.get_addr ()); + int size = local_sap.get_size (); + if (ACE_OS::bind (handle, laddr, size) == -1) + { + result->set_error (errno); + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"), + ACE_TEXT ("bind")), + -1); + } + } + + // set non blocking mode + if (ACE::set_flags (handle, ACE_NONBLOCK) != 0) + { + result->set_error (errno); + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Connect::connect_i: %p\n"), + ACE_TEXT ("set_flags")), + -1); + } + + for (;;) + { + int rc = ACE_OS::connect + (handle, + reinterpret_cast (remote_sap.get_addr ()), + remote_sap.get_size ()); + + if (rc < 0) // failure + { + if (errno == EWOULDBLOCK || errno == EINPROGRESS) + return 0; // connect started + + if (errno == EINTR) + continue; + + result->set_error (errno); + } + return 1 ; // connect finished + } +} + + +// cancel_uncompleted +// It performs cancellation of all pending requests +// +// Parameter flg_notify can be +// 0 - don't send notifications about canceled accepts +// !0 - notify user about canceled accepts +// according WIN32 standards we should receive notifications +// on canceled AIO requests +// +// Return value : number of cancelled requests +// + +int +ACE_WIN32_Asynch_Connect::cancel_uncompleted (bool flg_notify, + ACE_Handle_Set &set) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel_uncompleted"); + + int retval = 0; + + MAP_MANAGER::ITERATOR iter (result_map_); + MAP_MANAGER::ENTRY * me = 0; + + set.reset (); + + for (; iter.next (me) != 0; retval++, iter.advance ()) + { + ACE_HANDLE handle = me->ext_id_; + ACE_WIN32_Asynch_Connect_Result* result = me->int_id_ ; + + set.set_bit (handle); + + result->set_bytes_transferred (0); + result->set_error (ERROR_OPERATION_ABORTED); + this->post_result (result, flg_notify); + } + + result_map_.unbind_all (); + + return retval; +} + +int +ACE_WIN32_Asynch_Connect::cancel (void) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::cancel"); + + int rc = -1 ; // ERRORS + + ACE_Handle_Set set; + int num_cancelled = 0; + { + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1)); + + num_cancelled = cancel_uncompleted (flg_open_, set); + } + if (num_cancelled == 0) + rc = 1; // AIO_ALLDONE + else if (num_cancelled > 0) + rc = 0; // AIO_CANCELED + + if (!this->flg_open_) + return rc; + + ACE_Asynch_Pseudo_Task & task = + this->win32_proactor_->get_asynch_pseudo_task (); + + task.remove_io_handler (set); + return rc; +} + +int +ACE_WIN32_Asynch_Connect::close (void) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::close"); + + ACE_Handle_Set set; + int num_cancelled = 0; + { + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1)); + + num_cancelled = cancel_uncompleted (flg_open_, set); + } + if (num_cancelled == 0 || this->flg_open_ == 0) + { + this->flg_open_ = false; + return 0; + } + + ACE_Asynch_Pseudo_Task & task = + this->win32_proactor_->get_asynch_pseudo_task (); + + task.remove_io_handler (set); + return 0; +} + +int +ACE_WIN32_Asynch_Connect::handle_exception (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_exception"); + return handle_output (fd); +} + +int +ACE_WIN32_Asynch_Connect::handle_input (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_input"); + return handle_output (fd); +} + +int +ACE_WIN32_Asynch_Connect::handle_output (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_output"); + + ACE_WIN32_Asynch_Connect_Result* result = 0; + + { + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0)); + if (this->result_map_.unbind (fd, result) != 0) // not found + return -1; + } + + int sockerror = 0 ; + int lsockerror = sizeof sockerror; + + ACE_OS::getsockopt (fd, + SOL_SOCKET, + SO_ERROR, + (char*) & sockerror, + & lsockerror); + + // This previously just did a "return -1" and let handle_close() clean + // things up. However, this entire object may be gone as a result of + // the application's completion handler, so don't count on 'this' being + // legitimate on return from post_result(). + // remove_io_handler() contains flag DONT_CALL + this->win32_proactor_->get_asynch_pseudo_task().remove_io_handler (fd); + + result->set_bytes_transferred (0); + result->set_error (sockerror); + this->post_result (result, this->flg_open_); + return 0; +} + + +int +ACE_WIN32_Asynch_Connect::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_WIN32_Asynch_Connect::handle_close"); + + ACE_Asynch_Pseudo_Task & task = + this->win32_proactor_->get_asynch_pseudo_task (); + task.remove_io_handler (fd); + + ACE_WIN32_Asynch_Connect_Result* result = 0; + + { + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0)); + if (this->result_map_.unbind (fd, result) != 0) // not found + return -1; + } + + result->set_bytes_transferred (0); + result->set_error (ERROR_OPERATION_ABORTED); + this->post_result (result, this->flg_open_); + + return 0; +} + +// ********************************************************************* + +ACE_HANDLE +ACE_WIN32_Asynch_Transmit_File_Result::socket (void) const +{ + return this->socket_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Transmit_File_Result::file (void) const +{ + return this->file_; +} + +ACE_Asynch_Transmit_File::Header_And_Trailer * +ACE_WIN32_Asynch_Transmit_File_Result::header_and_trailer (void) const +{ + return this->header_and_trailer_; +} + +size_t +ACE_WIN32_Asynch_Transmit_File_Result::bytes_to_write (void) const +{ + return this->bytes_to_write_; +} + +size_t +ACE_WIN32_Asynch_Transmit_File_Result::bytes_per_send (void) const +{ + return this->bytes_per_send_; +} + +u_long +ACE_WIN32_Asynch_Transmit_File_Result::flags (void) const +{ + return this->flags_; +} + +ACE_WIN32_Asynch_Transmit_File_Result::ACE_WIN32_Asynch_Transmit_File_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE socket, + ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Transmit_File_Result_Impl (), + ACE_WIN32_Asynch_Result (handler_proxy, + act, + event, + offset, + offset_high, + priority, + signal_number), + socket_ (socket), + file_ (file), + header_and_trailer_ (header_and_trailer), + bytes_to_write_ (bytes_to_write), + bytes_per_send_ (bytes_per_send), + flags_ (flags) +{ +} + +void +ACE_WIN32_Asynch_Transmit_File_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // We will not do this because (a) the header and trailer blocks may + // be the same message_blocks and (b) in cases of failures we have + // no idea how much of what (header, data, trailer) was sent. + /* + if (this->success_ && this->header_and_trailer_ != 0) + { + ACE_Message_Block *header = this->header_and_trailer_->header (); + if (header != 0) + header->rd_ptr (this->header_and_trailer_->header_bytes ()); + + ACE_Message_Block *trailer = this->header_and_trailer_->trailer (); + if (trailer != 0) + trailer->rd_ptr (this->header_and_trailer_->trailer_bytes ()); + } + */ + + // Create the interface result class. + ACE_Asynch_Transmit_File::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_transmit_file (result); +} + +ACE_WIN32_Asynch_Transmit_File_Result::~ACE_WIN32_Asynch_Transmit_File_Result (void) +{ +} + +// Base class operations. These operations are here to kill dominance +// warnings. These methods call the base class methods. + +size_t +ACE_WIN32_Asynch_Transmit_File_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Transmit_File_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Transmit_File_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Transmit_File_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Transmit_File_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Transmit_File_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Transmit_File_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Transmit_File_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Transmit_File_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Transmit_File_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Transmit_File_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +ACE_WIN32_Asynch_Transmit_File::ACE_WIN32_Asynch_Transmit_File (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Transmit_File_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor) +{ +} + +int +ACE_WIN32_Asynch_Transmit_File::transmit_file (ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + int priority, + int signal_number) +{ +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) + + // TransmitFile API limits us to DWORD range. + if (bytes_to_write > MAXDWORD || bytes_per_send > MAXDWORD) + { + errno = ERANGE; + return -1; + } + DWORD dword_bytes_to_write = static_cast (bytes_to_write); + DWORD dword_bytes_per_send = static_cast (bytes_per_send); + + ACE_WIN32_Asynch_Transmit_File_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Transmit_File_Result (this->handler_proxy_, + this->handle_, + file, + header_and_trailer, + bytes_to_write, + offset, + offset_high, + bytes_per_send, + flags, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + ACE_LPTRANSMIT_FILE_BUFFERS transmit_buffers = 0; + if (result->header_and_trailer () != 0) + transmit_buffers = result->header_and_trailer ()->transmit_buffers (); + + // Initiate the transmit file + int initiate_result = ::TransmitFile ((SOCKET) result->socket (), + result->file (), + dword_bytes_to_write, + dword_bytes_per_send, + result, + transmit_buffers, + result->flags ()); + if (initiate_result == 1) + // Immediate success: the OVERLAPPED will still get queued. + return 1; + + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + return 0; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + // Cleanup dynamically allocated Asynch_Result + delete result; + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("TransmitFile"))); + } + return -1; + } +#else + ACE_UNUSED_ARG (file); + ACE_UNUSED_ARG (header_and_trailer); + ACE_UNUSED_ARG (bytes_to_write); + ACE_UNUSED_ARG (offset); + ACE_UNUSED_ARG (offset_high); + ACE_UNUSED_ARG (bytes_per_send); + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (act); + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (signal_number); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_WINSOCK2 */ +} + +ACE_WIN32_Asynch_Transmit_File::~ACE_WIN32_Asynch_Transmit_File (void) +{ +} + +// Methods belong to ACE_WIN32_Asynch_Operation base class. These +// methods are defined here to avoid VC++ warnings. They route the +// call to the ACE_WIN32_Asynch_Operation base class. + +int +ACE_WIN32_Asynch_Transmit_File::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Transmit_File::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Transmit_File::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +size_t +ACE_WIN32_Asynch_Read_Dgram_Result::bytes_to_read (void) const +{ + return this->bytes_to_read_; +} + +ACE_Message_Block* +ACE_WIN32_Asynch_Read_Dgram_Result::message_block (void) const +{ + return this->message_block_; +} + + +int +ACE_WIN32_Asynch_Read_Dgram_Result::remote_address (ACE_Addr& addr) const +{ + int retVal = -1; // failure + + // make sure the addresses are of the same type + if (addr.get_type () == this->remote_address_->get_type ()) + { // copy the remote_address_ into addr + addr.set_addr (this->remote_address_->get_addr (), + this->remote_address_->get_size ()); + retVal = 0; // success + } + + return retVal; +} + +sockaddr * +ACE_WIN32_Asynch_Read_Dgram_Result::saddr () const +{ + return (sockaddr *) this->remote_address_->get_addr (); +} + + +int +ACE_WIN32_Asynch_Read_Dgram_Result::flags (void) const +{ + return this->flags_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Read_Dgram_Result::handle (void) const +{ + return this->handle_; +} + +size_t +ACE_WIN32_Asynch_Read_Dgram_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Read_Dgram_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Read_Dgram_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Read_Dgram_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Read_Dgram_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Read_Dgram_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Read_Dgram_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Read_Dgram_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Read_Dgram_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Read_Dgram_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Read_Dgram_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +ACE_WIN32_Asynch_Read_Dgram_Result::ACE_WIN32_Asynch_Read_Dgram_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_read, + int flags, + int protocol_family, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Read_Dgram_Result_Impl(), + ACE_WIN32_Asynch_Result (handler_proxy, act, event, 0, 0, priority, signal_number), + bytes_to_read_ (bytes_to_read), + message_block_ (message_block), + remote_address_ (0), + addr_len_ (0), + flags_ (flags), + handle_ (handle) +{ + ACE_ASSERT (protocol_family == PF_INET); // only supporting INET addresses + + ACE_NEW (remote_address_, ACE_INET_Addr); + addr_len_ = remote_address_->get_size (); + + ACE_UNUSED_ARG (protocol_family); +} + +void +ACE_WIN32_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + for (ACE_Message_Block* mb = this->message_block_; + (mb != 0) && (bytes_transferred > 0); + mb = mb->cont ()) + { + size_t len_part = mb->space (); + + if ( len_part > bytes_transferred) + len_part = bytes_transferred; + + mb->wr_ptr (len_part); + + bytes_transferred -= len_part; + } + + // Adjust the address length + this->remote_address_->set_size (this->addr_len_); + + // Create the interface result class. + ACE_Asynch_Read_Dgram::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_read_dgram (result); +} + +ACE_WIN32_Asynch_Read_Dgram_Result::~ACE_WIN32_Asynch_Read_Dgram_Result (void) +{ + delete this->remote_address_; +} + +//*************************************************************************** + +ACE_WIN32_Asynch_Read_Dgram::~ACE_WIN32_Asynch_Read_Dgram (void) +{ +} + +ssize_t +ACE_WIN32_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block, + size_t & number_of_bytes_recvd, + int flags, + int protocol_family, + const void *act, + int priority, + int signal_number) +{ + number_of_bytes_recvd = 0; + + size_t bytes_to_read = 0; + + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + for (const ACE_Message_Block* msg = message_block; + msg != 0 && iovcnt < ACE_IOV_MAX; + msg = msg->cont () , ++iovcnt ) + { + size_t msg_space = msg->space (); + + // OS should correctly process zero length buffers + // if ( msg_space == 0 ) + // ACE_ERROR_RETURN ((LM_ERROR, + // ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:") + // ACE_TEXT ("No space in the message block\n")), + // -1); + + bytes_to_read += msg_space; + + // Make as many iovec as needed to fit all of msg_len. + size_t wr_ptr_offset = 0; + + while (msg_space > 0 && iovcnt < ACE_IOV_MAX) + { + u_long this_chunk_length; + if (msg_space > ULONG_MAX) + this_chunk_length = ULONG_MAX; + else + this_chunk_length = static_cast (msg_space); + // Collect the data in the iovec. + iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset; + iov[iovcnt].iov_len = this_chunk_length; + msg_space -= this_chunk_length; + wr_ptr_offset += this_chunk_length; + + // Increment iovec counter if there's more to do. + if (msg_space > 0) + iovcnt++; + } + if (msg_space > 0) // Ran out of iovecs before msg_space exhausted + { + errno = ERANGE; + return -1; + } + } + + if (bytes_to_read == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:") + ACE_TEXT ("Attempt to read 0 bytes\n")), + -1); + + // Create the Asynch_Result. + ACE_WIN32_Asynch_Read_Dgram_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Read_Dgram_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_read, + flags, + protocol_family, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + // do the scatter/gather recv + ssize_t initiate_result = ACE_OS::recvfrom (result->handle (), + iov, + iovcnt, + number_of_bytes_recvd, + result->flags_, + result->saddr (), + &(result->addr_len_), + result, + 0); + if (initiate_result == SOCKET_ERROR) + { + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + initiate_result = 0; + break; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WSARecvFrom"))); + } + + delete result; + initiate_result = -1; + break; + } + + } + else + { + // Immediate success: the OVERLAPPED will still get queued. + // number_of_bytes_recvd contains the number of bytes recvd + // addr contains the peer address + // flags was updated + + // number_of_bytes_recvd = bytes_recvd; + initiate_result = 1; + } + + return initiate_result; +} + +int +ACE_WIN32_Asynch_Read_Dgram::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Read_Dgram::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Read_Dgram::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +ACE_WIN32_Asynch_Read_Dgram::ACE_WIN32_Asynch_Read_Dgram (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Read_Dgram_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor) +{ +} + +//*********************************************** + +size_t +ACE_WIN32_Asynch_Write_Dgram_Result::bytes_to_write (void) const +{ + return this->bytes_to_write_; +} + +ACE_Message_Block* +ACE_WIN32_Asynch_Write_Dgram_Result::message_block () const +{ + return this->message_block_; +} + +int +ACE_WIN32_Asynch_Write_Dgram_Result::flags (void) const +{ + return this->flags_; +} + +ACE_HANDLE +ACE_WIN32_Asynch_Write_Dgram_Result::handle (void) const +{ + return this->handle_; +} + +size_t +ACE_WIN32_Asynch_Write_Dgram_Result::bytes_transferred (void) const +{ + return ACE_WIN32_Asynch_Result::bytes_transferred (); +} + +const void * +ACE_WIN32_Asynch_Write_Dgram_Result::act (void) const +{ + return ACE_WIN32_Asynch_Result::act (); +} + +int +ACE_WIN32_Asynch_Write_Dgram_Result::success (void) const +{ + return ACE_WIN32_Asynch_Result::success (); +} + +const void * +ACE_WIN32_Asynch_Write_Dgram_Result::completion_key (void) const +{ + return ACE_WIN32_Asynch_Result::completion_key (); +} + +u_long +ACE_WIN32_Asynch_Write_Dgram_Result::error (void) const +{ + return ACE_WIN32_Asynch_Result::error (); +} + +ACE_HANDLE +ACE_WIN32_Asynch_Write_Dgram_Result::event (void) const +{ + return ACE_WIN32_Asynch_Result::event (); +} + +u_long +ACE_WIN32_Asynch_Write_Dgram_Result::offset (void) const +{ + return ACE_WIN32_Asynch_Result::offset (); +} + +u_long +ACE_WIN32_Asynch_Write_Dgram_Result::offset_high (void) const +{ + return ACE_WIN32_Asynch_Result::offset_high (); +} + +int +ACE_WIN32_Asynch_Write_Dgram_Result::priority (void) const +{ + return ACE_WIN32_Asynch_Result::priority (); +} + +int +ACE_WIN32_Asynch_Write_Dgram_Result::signal_number (void) const +{ + return ACE_WIN32_Asynch_Result::signal_number (); +} + +int +ACE_WIN32_Asynch_Write_Dgram_Result::post_completion (ACE_Proactor_Impl *proactor) +{ + return ACE_WIN32_Asynch_Result::post_completion (proactor); +} + +ACE_WIN32_Asynch_Write_Dgram_Result::ACE_WIN32_Asynch_Write_Dgram_Result ( + const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_write, + int flags, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_Asynch_Write_Dgram_Result_Impl(), + ACE_WIN32_Asynch_Result (handler_proxy, + act, + event, + 0, + 0, + priority, + signal_number), + bytes_to_write_ (bytes_to_write), + message_block_ (message_block), + flags_ (flags), + handle_ (handle) +{ +} + +void +ACE_WIN32_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error) +{ + // Copy the data which was returned by GetQueuedCompletionStatus + this->bytes_transferred_ = bytes_transferred; + this->success_ = success; + this->completion_key_ = completion_key; + this->error_ = error; + + // Appropriately move the pointers in the message block. + for (ACE_Message_Block* mb = this->message_block_; + (mb != 0) && (bytes_transferred > 0); + mb = mb->cont ()) + { + size_t len_part = mb->length (); + + if ( len_part > bytes_transferred) + len_part = bytes_transferred; + + mb->rd_ptr (len_part); + + bytes_transferred -= len_part; + } + + // Create the interface result class. + ACE_Asynch_Write_Dgram::Result result (this); + + // Call the application handler. + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_write_dgram (result); +} + +ACE_WIN32_Asynch_Write_Dgram_Result::~ACE_WIN32_Asynch_Write_Dgram_Result (void) +{ +} + + +//*********************************************** + +ACE_WIN32_Asynch_Write_Dgram::~ACE_WIN32_Asynch_Write_Dgram (void) +{ +} + +ssize_t +ACE_WIN32_Asynch_Write_Dgram::send (ACE_Message_Block *message_block, + size_t &number_of_bytes_sent, + int flags, + const ACE_Addr &addr, + const void *act, + int priority, + int signal_number) +{ + number_of_bytes_sent = 0; + + size_t bytes_to_write = 0; + + iovec iov[ACE_IOV_MAX]; + int iovcnt = 0; + + for (const ACE_Message_Block* msg = message_block; + msg != 0 && iovcnt < ACE_IOV_MAX; + msg = msg->cont () , ++iovcnt ) + { + size_t msg_len = msg->length (); + + bytes_to_write += msg_len; + + // Make as many iovec as needed to fit all of msg_len. + size_t rd_ptr_offset = 0; + + do + { + if (msg_len >= 0 && iovcnt < ACE_IOV_MAX) + { + u_long this_chunk_length; + if (msg_len > ULONG_MAX) + this_chunk_length = ULONG_MAX; + else + this_chunk_length = static_cast (msg_len); + + // Collect the data in the iovec. + iov[iovcnt].iov_base = msg->rd_ptr () + rd_ptr_offset; + iov[iovcnt].iov_len = this_chunk_length; + msg_len -= this_chunk_length; + rd_ptr_offset += this_chunk_length; + + // Increment iovec counter if there's more to do. + if (msg_len > 0) + iovcnt++; + } + } + while (msg_len > 0 && iovcnt < ACE_IOV_MAX); + + if (msg_len > 0) // Ran out of iovecs before msg_space exhausted + { + errno = ERANGE; + return -1; + } + } + + // Create the Asynch_Result. + ACE_WIN32_Asynch_Write_Dgram_Result *result = 0; + ACE_NEW_RETURN (result, + ACE_WIN32_Asynch_Write_Dgram_Result (this->handler_proxy_, + this->handle_, + message_block, + bytes_to_write, + flags, + act, + this->win32_proactor_->get_handle (), + priority, + signal_number), + -1); + + // do the scatter/gather send + + ssize_t initiate_result = ACE_OS::sendto (result->handle (), + iov, + iovcnt, + number_of_bytes_sent, + result->flags_, + (sockaddr *) addr.get_addr (), + addr.get_size(), + result, + 0); + + + if (initiate_result == SOCKET_ERROR) + { + // If initiate failed, check for a bad error. + ACE_OS::set_errno_to_last_error (); + switch (errno) + { + case ERROR_IO_PENDING: + // The IO will complete proactively: the OVERLAPPED will still + // get queued. + initiate_result = 0; + break; + + default: + // Something else went wrong: the OVERLAPPED will not get + // queued. + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("WSASendTo"))); + } + + delete result; + initiate_result = -1; + break; + } + + } + else + { + // Immediate success: the OVERLAPPED will still get queued. + // number_of_bytes_recvd contains the number of bytes recvd + // addr contains the peer address + // flags was updated + + // number_of_bytes_sent = bytes_sent; + initiate_result = 1; + } + + return initiate_result; +} + +int +ACE_WIN32_Asynch_Write_Dgram::open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor) +{ + return ACE_WIN32_Asynch_Operation::open (handler_proxy, + handle, + completion_key, + proactor); +} + +int +ACE_WIN32_Asynch_Write_Dgram::cancel (void) +{ + return ACE_WIN32_Asynch_Operation::cancel (); +} + +ACE_Proactor * +ACE_WIN32_Asynch_Write_Dgram::proactor (void) const +{ + return ACE_WIN32_Asynch_Operation::proactor (); +} + +ACE_WIN32_Asynch_Write_Dgram::ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor *win32_proactor) + : ACE_Asynch_Operation_Impl (), + ACE_Asynch_Write_Dgram_Impl (), + ACE_WIN32_Asynch_Operation (win32_proactor) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO && ACE_HAS_WINSOCK2 */ diff --git a/dep/ACE_wrappers/ace/WIN32_Asynch_IO.h b/dep/ACE_wrappers/ace/WIN32_Asynch_IO.h new file mode 100644 index 000000000..34af77dab --- /dev/null +++ b/dep/ACE_wrappers/ace/WIN32_Asynch_IO.h @@ -0,0 +1,1937 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file WIN32_Asynch_IO.h + * + * $Id: WIN32_Asynch_IO.h 80826 2008-03-04 14:51:23Z wotte $ + * + * + * These classes only works on Win32 platforms. + * + * The implementation of ACE_Asynch_Transmit_File, + * ACE_Asynch_Accept, and ACE_Asynch_Connect are only supported if + * ACE_HAS_WINSOCK2 is defined or you are on WinNT 4.0 or higher. + * + * + * @author Irfan Pyarali + * @author Tim Harrison + * @author Alexander Babu Arulanthu + * @author Roger Tragin + * @author Alexander Libman + */ +//============================================================================= + +#ifndef ACE_WIN32_ASYNCH_IO_H +#define ACE_WIN32_ASYNCH_IO_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) && \ + (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 1)) + +#include "ace/Asynch_IO_Impl.h" +#include "ace/Addr.h" +#include "ace/Event_Handler.h" +#include "ace/Handle_Set.h" +#include "ace/Map_Manager.h" +#include "ace/Null_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declaration +class ACE_WIN32_Proactor; + +/** + * @class ACE_WIN32_Asynch_Result + * + * @brief An abstract class which adds information to the OVERLAPPED + * structure to make it more useful. + * + * An abstract base class from which you can obtain some basic + * information like the number of bytes transferred, the ACT + * associated with the asynchronous operation, indication of + * success or failure, etc. Subclasses may want to store more + * information that is particular to the asynchronous operation + * it represents. + */ +class ACE_Export ACE_WIN32_Asynch_Result : public virtual ACE_Asynch_Result_Impl, + public OVERLAPPED +{ + /// Factory class has special permissions. + friend class ACE_WIN32_Asynch_Accept; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Result (void); + + /// Simulate error value to use in the post_completion () + void set_error (u_long errcode); + + /// Simulate value to use in the post_completion () + void set_bytes_transferred (size_t nbytes); + +protected: + /// Constructor. + ACE_WIN32_Asynch_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + const void* act, + ACE_HANDLE event, + u_long offset, + u_long offset_high, + int priority, + int signal_number = 0); + + /// Proxy for the ACE_Handler that will be called back. + ACE_Handler::Proxy_Ptr handler_proxy_; + + /// ACT for this operation. + const void *act_; + + /// Bytes transferred by this operation. + size_t bytes_transferred_; + + /// Success indicator. + int success_; + + /// ACT associated with handle. + const void *completion_key_; + + /// Error if operation failed. + u_long error_; +}; + +/** + * @class ACE_WIN32_Asynch_Operation + * + * @brief This class abstracts out the common things needed for + * implementing Asynch_Operation for WIN32 platform. + * + */ +class ACE_Export ACE_WIN32_Asynch_Operation : public virtual ACE_Asynch_Operation_Impl +{ +public: + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + // = Access methods. + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +protected: + /// Constructor. + ACE_WIN32_Asynch_Operation (ACE_WIN32_Proactor *win32_proactor); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Operation (void); + + /// Win32 Proactor. + ACE_WIN32_Proactor *win32_proactor_; + + /// Proactor that this asynch IO is registered with. + ACE_Proactor *proactor_; + + /// Handler that will receive the callback. + ACE_Handler::Proxy_Ptr handler_proxy_; + + /// I/O handle used for reading. + ACE_HANDLE handle_; +}; + +/** + * @class ACE_WIN32_Asynch_Read_Stream_Result + * + * @brief This class provides concrete implementation for + * ACE_Asynch_Read_Stream::Result class. + */ +class ACE_Export ACE_WIN32_Asynch_Read_Stream_Result : public virtual ACE_Asynch_Read_Stream_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory class will have special permissions. + friend class ACE_WIN32_Asynch_Read_Stream; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// The number of bytes which were requested at the start of the + /// asynchronous read. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for reading. + ACE_HANDLE handle (void) const; + + // Base class operations. These operations are here to kill + // dominance warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + + /// Accessor for the scatter read flag + int scatter_enabled (void) const; + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Read_Stream factory. + ACE_WIN32_Asynch_Read_Stream_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0, + int scatter_enabled = 0); + + /// Proactor will call this method when the read completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Read_Stream_Result (void); + + /// Bytes requested when the asynchronous read was initiated. + size_t bytes_to_read_; + + /// Message block for reading the data into. + ACE_Message_Block &message_block_; + + /// I/O handle used for reading. + ACE_HANDLE handle_; + + /// Flag for scatter read + int scatter_enabled_; +}; + +/** + * @class ACE_WIN32_Asynch_Read_Stream + * + * @brief This class is a factory for starting off asynchronous reads + * on a stream. + * + * Once is called, multiple asynchronous s can + * started using this class. An ACE_Asynch_Read_Stream::Result + * will be passed back to the @a handler when the asynchronous + * reads completes through the + * callback. + */ +class ACE_Export ACE_WIN32_Asynch_Read_Stream : public virtual ACE_Asynch_Read_Stream_Impl, + public ACE_WIN32_Asynch_Operation +{ + +public: + /// Constructor. + ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor); + + /// This starts off an asynchronous read. Upto @a bytes_to_read will + /// be read and stored in the @a message_block. + int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number = 0); + + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + */ + int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number = 0); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Read_Stream (void); + + // Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid VC++ warnings. They route the + // call to the ACE_WIN32_Asynch_Operation base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +protected: + /// This is the method which does the real work and is there so that + /// the ACE_Asynch_Read_File class can use it too. + int shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result); +}; + +/** + * @class ACE_WIN32_Asynch_Write_Stream_Result + * + * @brief This class provides concrete implementation for + * ACE_Asynch_Write_Stream::Result class. + */ +class ACE_Export ACE_WIN32_Asynch_Write_Stream_Result : public virtual ACE_Asynch_Write_Stream_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory class willl have special permissions. + friend class ACE_WIN32_Asynch_Write_Stream; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write (void) const; + + /// Message block that contains the data to be written. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for writing. + ACE_HANDLE handle (void) const; + + // = Base class operations. These operations are here to kill some + // warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + + /// Accessor for the gather write flag + int gather_enabled (void) const; + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Write_Stream factory. + ACE_WIN32_Asynch_Write_Stream_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0, + int gather_enabled = 0); + + /// ACE_Proactor will call this method when the write completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Write_Stream_Result (void); + + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write_; + + /// Message block that contains the data to be written. + ACE_Message_Block &message_block_; + + /// I/O handle used for writing. + ACE_HANDLE handle_; + + /// Flag for gather write + int gather_enabled_; +}; + +/** + * @class ACE_WIN32_Asynch_Write_Stream + * + * @brief This class is a factory for starting off asynchronous writes + * on a stream. + * + * + * Once is called, multiple asynchronous s can + * started using this class. A ACE_Asynch_Write_Stream::Result + * will be passed back to the @a handler when the asynchronous + * write completes through the + * callback. + */ +class ACE_Export ACE_WIN32_Asynch_Write_Stream : public virtual ACE_Asynch_Write_Stream_Impl, + public ACE_WIN32_Asynch_Operation +{ +public: + /// Constructor. + ACE_WIN32_Asynch_Write_Stream (ACE_WIN32_Proactor *win32_proactor); + + /// This starts off an asynchronous write. Upto @a bytes_to_write + /// will be written from the @a message_block. + int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number = 0); + + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + */ + int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number = 0); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Write_Stream (void); + + // = Methods belonging to base class. + + // These methods are defined here to avoid VC++ warnings. They route + // the call to the base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +protected: + /// This is the method which does the real work and is there so that + /// the ACE_Asynch_Write_File class can use it too. + int shared_write (ACE_WIN32_Asynch_Write_Stream_Result *result); +}; + +/** + * @class ACE_WIN32_Asynch_Read_File_Result + * + * @brief This class provides concrete implementation for + * ACE_Asynch_Read_File::Result class. + */ +class ACE_Export ACE_WIN32_Asynch_Read_File_Result : public virtual ACE_Asynch_Read_File_Result_Impl, + public ACE_WIN32_Asynch_Read_Stream_Result +{ + /// Factory class will have special permissions. + friend class ACE_WIN32_Asynch_Read_File; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + // = These methods belong to ACE_WIN32_Asynch_Result class base + // class. These operations are here to kill some warnings. These + // methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + // The following methods belong to + // ACE_WIN32_Asynch_Read_Stream_Result. They are here to avoid VC++ + // dominance warnings. These methods route their call to the + // ACE_WIN32_Asynch_Read_Stream_Result base class. + + /// The number of bytes which were requested at the start of the + /// asynchronous read. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for reading. + ACE_HANDLE handle (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Read_File factory. + ACE_WIN32_Asynch_Read_File_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number = 0, + int scatter_enabled = 0); + + /// ACE_Proactor will call this method when the read completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Read_File_Result (void); +}; + +/** + * @class ACE_WIN32_Asynch_Read_File + * + * @brief This class is a factory for starting off asynchronous reads + * on a file. + * + * Once is called, multiple asynchronous s can + * started using this class. A ACE_Asynch_Read_File::Result + * will be passed back to the @a handler when the asynchronous + * reads completes through the + * callback. + * + * This class differs slightly from ACE_Asynch_Read_Stream as it + * allows the user to specify an offset for the read. + */ +class ACE_Export ACE_WIN32_Asynch_Read_File : public virtual ACE_Asynch_Read_File_Impl, + public ACE_WIN32_Asynch_Read_Stream +{ + +public: + /// Constructor. + ACE_WIN32_Asynch_Read_File (ACE_WIN32_Proactor *win32_proactor); + + /** + * This starts off an asynchronous read. Upto @a bytes_to_read will + * be read and stored in the @a message_block. The read will start + * at @a offset from the beginning of the file. + */ + int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number = 0); + + /** + * Same as above but with scatter support, through chaining of + * composite message blocks using the continuation field. + * @note Each data block payload must be at least the size of a + * system memory page and must be aligned on a system memory page + * size boundary + */ + int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number = 0); + + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Read_File (void); + + // = Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid VC++ warnings. They route the + // call to the ACE_WIN32_Asynch_Operation base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +private: + /** + * This method belongs to ACE_WIN32_Asynch_Read_Stream. It is here + * to avoid the compiler warnings. We forward this call to the + * ACE_WIN32_Asynch_Read_Stream class. + */ + int read (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number = 0); + + /** + * Same as above but with scatter support, through chaining of composite + * message blocks using the continuation field. + */ + int readv (ACE_Message_Block &message_block, + size_t bytes_to_read, + const void *act, + int priority, + int signal_number = 0); +}; + +/** + * @class ACE_WIN32_Asynch_Write_File_Result + * + * @brief This class provides implementation for + * ACE_Asynch_Write_File_Result for WIN32 platforms. + * + * This class has all the information necessary for the + * @a handler to uniquiely identify the completion of the + * asynchronous write. + * + * This class differs slightly from + * ACE_Asynch_Write_Stream::Result as it calls back + * on the @a handler instead + * of . No additional state + * is required by this class as ACE_Asynch_Result can store + * the @a offset. + */ +class ACE_Export ACE_WIN32_Asynch_Write_File_Result : public virtual ACE_Asynch_Write_File_Result_Impl, + public ACE_WIN32_Asynch_Write_Stream_Result +{ + /// Factory class will have special permission. + friend class ACE_WIN32_Asynch_Write_File; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + // = Base class operations. These operations are here to kill some + // warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + // The following methods belong to + // ACE_WIN32_Asynch_Read_Stream_Result. They are here to avoid VC++ + // warnings. These methods route their call to the + // ACE_WIN32_Asynch_Read_Stream_Result base class. + + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write (void) const; + + /// Message block that contains the data to be written. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for writing. + ACE_HANDLE handle (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Write_File factory. + ACE_WIN32_Asynch_Write_File_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number = 0, + int gather_enabled = 0); + + /// ACE_Proactor will call this method when the write completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Write_File_Result (void); +}; + +/** + * @class ACE_WIN32_Asynch_Write_File + * + * @brief This class is a factory for starting off asynchronous writes + * on a file. + * + * Once is called, multiple asynchronous s can be + * started using this class. A ACE_Asynch_Write_File::Result + * will be passed back to the @a handler when the asynchronous + * writes completes through the + * callback. + */ +class ACE_Export ACE_WIN32_Asynch_Write_File : public virtual ACE_Asynch_Write_File_Impl, + public ACE_WIN32_Asynch_Write_Stream +{ +public: + /// Constructor. + ACE_WIN32_Asynch_Write_File (ACE_WIN32_Proactor *win32_proactor); + + /** + * This starts off an asynchronous write. Upto @a bytes_to_write + * will be write and stored in the @a message_block. The write will + * start at @a offset from the beginning of the file. + */ + int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number = 0); + + /** + * Same as above but with gather support, through chaining of + * composite message blocks using the continuation field. + * @note Each data block payload must be at least the size of a + * system memory page and must be aligned on a system memory page + * size boundary + */ + int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + const void *act, + int priority, + int signal_number = 0); + + /// Destrcutor. + virtual ~ACE_WIN32_Asynch_Write_File (void); + + // = Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid VC++ warnings. They route the + // call to the ACE_WIN32_Asynch_Operation base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +private: + /** + * This method belongs to ACE_WIN32_Asynch_Write_Stream. It is here + * to avoid compiler warnings. This method is forwarded to the + * ACE_WIN32_Asynch_Write_Stream class. + */ + int write (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number = 0); + + /** + * Same as above but with gather support, through chaining of composite + * message blocks using the continuation field. + */ + int writev (ACE_Message_Block &message_block, + size_t bytes_to_write, + const void *act, + int priority, + int signal_number = 0); +}; + +/** + * @class ACE_WIN32_Asynch_Accept_Result + * + * @brief This class implements ACE_Asynch_Accept::Result for WIN32 + * platform. + * + * This class has all the information necessary for the + * @a handler to uniquiely identify the completion of the + * asynchronous accept. + */ +class ACE_Export ACE_WIN32_Asynch_Accept_Result : public virtual ACE_Asynch_Accept_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory will have special permission. + friend class ACE_WIN32_Asynch_Accept; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// The number of bytes which were requested at the start of the + /// asynchronous accept. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data. + ACE_Message_Block &message_block (void) const; + + /// I/O handle used for accepting new connections. + ACE_HANDLE listen_handle (void) const; + + /// I/O handle for the new connection. + ACE_HANDLE accept_handle (void) const; + + // = Base class operations. These operations are here to kill some + // warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Accept factory. + ACE_WIN32_Asynch_Accept_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE listen_handle, + ACE_HANDLE accept_handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// ACE_Proactor will call this method when the accept completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Accept_Result (void); + + /// Bytes requested when the asynchronous read was initiated. + size_t bytes_to_read_; + + /// Message block for reading the data into. + ACE_Message_Block &message_block_; + + /// I/O handle used for accepting new connections. + ACE_HANDLE listen_handle_; + + /// I/O handle for the new connection. + ACE_HANDLE accept_handle_; +}; + +/** + * @class ACE_WIN32_Asynch_Accept + * + * @brief This class is a factory for starting off asynchronous accepts + * on a listen handle. + * + * Once is called, multiple asynchronous s can + * started using this class. A ACE_Asynch_Accept::Result will + * be passed back to the @a handler when the asynchronous accept + * completes through the + * callback. + */ +class ACE_Export ACE_WIN32_Asynch_Accept : public virtual ACE_Asynch_Accept_Impl, + public ACE_WIN32_Asynch_Operation +{ +public: + /// Constructor. + ACE_WIN32_Asynch_Accept (ACE_WIN32_Proactor *win32_proactor); + + /** + * This starts off an asynchronous accept. The asynchronous accept + * call also allows any initial data to be returned to the + * @a handler. Upto @a bytes_to_read will be read and stored in the + * @a message_block. The will be used for the + * call. If ( == INVALID_HANDLE), a new + * handle will be created. + * + * @a message_block must be specified. This is because the address of + * the new connection is placed at the end of this buffer. + */ + int accept (ACE_Message_Block &message_block, + size_t bytes_to_read, + ACE_HANDLE accept_handle, + const void *act, + int priority, + int signal_number = 0, + int addr_family = AF_INET); + + /// Destructor. + ~ACE_WIN32_Asynch_Accept (void); + + // Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid VC++ warnings. They route the + // call to the ACE_WIN32_Asynch_Operation base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; +}; + +/** + * @class ACE_WIN32_Asynch_Connect_Result + * + * @brief This is that class which will be passed back to the + * completion handler when the asynchronous connect completes. + * + * This class has all the information necessary for the + * completion handler to uniquiely identify the completion of the + * asynchronous connect. + */ +class ACE_Export ACE_WIN32_Asynch_Connect_Result : public virtual ACE_Asynch_Connect_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory classes will have special permissions. + friend class ACE_WIN32_Asynch_Connect; + + /// The Proactor constructs the Result class for faking results. + friend class ACE_WIN32_Proactor; + +public: + + /// I/O handle for the connection. + ACE_HANDLE connect_handle (void) const; + + // = Base class operations. These operations are here to kill some + // warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * Returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post this object to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Connect factory. + ACE_WIN32_Asynch_Connect_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE connect_handle, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number); + + /// ACE_Proactor will call this method when the accept completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Connect_Result (void); + + /// Set the I/O handle for the new connection. + void connect_handle (ACE_HANDLE handle); + + ACE_HANDLE connect_handle_; +}; + + +/** + * @class ACE_WIN32_Asynch_Connect + */ +class ACE_Export ACE_WIN32_Asynch_Connect : + public virtual ACE_Asynch_Connect_Impl, + public ACE_WIN32_Asynch_Operation, + public ACE_Event_Handler +{ +public: + + /// Constructor. + ACE_WIN32_Asynch_Connect (ACE_WIN32_Proactor * win32_proactor); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Connect (void); + + /** + * This open belongs to ACE_WIN32_Asynch_Operation. We forward + * this call to that method. We have put this here to avoid the + * compiler warnings. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor = 0); + + /** + * Start an asynchronous connect. + * + * @param connect_handle Handle to use for the connect. If the value + * ACE_INVALID_HANDLE, a new handle will be created. + * + * @retval 0 Success + * @retval -1 Error + */ + int connect (ACE_HANDLE connect_handle, + const ACE_Addr &remote_sap, + const ACE_Addr &local_sap, + int reuse_addr, + const void *act, + int priority, + int signal_number = 0); + + /** + * Cancel all pending pseudo-asynchronus requests + * Behavior as usual AIO request + */ + int cancel (void); + + /** + * Close performs cancellation of all pending requests + * and close the connect handle + */ + int close (void); + + /// Virtual from ACE_Event_Handler + ACE_HANDLE get_handle (void) const; + + /// Virtual from ACE_Event_Handler + void set_handle (ACE_HANDLE handle); + + /// Virtual from ACE_Event_Handler + int handle_input ( ACE_HANDLE handle); + int handle_output ( ACE_HANDLE handle); + int handle_exception ( ACE_HANDLE handle); + + /// Virtual from ACE_Event_Handler + int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask) ; + + // = Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid dominace warnings. They route + // the call to the ACE_WIN32_Asynch_Operation base class. + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +private: + int connect_i (ACE_WIN32_Asynch_Connect_Result *result, + const ACE_Addr &remote_sap, + const ACE_Addr &local_sap, + int reuse_addr); + + int post_result (ACE_WIN32_Asynch_Connect_Result *result, bool flg_post); + + /// Cancel uncompleted connect operations. + /** + * @param flg_notify Indicates whether or not to send notification about + * canceled connect operations. If false, don't send + * notifications. If true, notify user about canceled + * connects. + * According WIN32 standards we should receive + * notifications on canceled AIO requests. + * + * @param set Receives the set of I/O handles on which asynchronous + * connect requests were canceled as a result of this + * method. The contents of @a set are completely + * replaced. + */ + int cancel_uncompleted (bool flg_notify, ACE_Handle_Set &set); + + /// true - Connect is registered in ACE_Asynch_Pseudo_Task + /// false - Accept is deregisted in ACE_Asynch_Pseudo_Task + bool flg_open_ ; + + typedef ACE_Map_Manager + MAP_MANAGER; + + /// Map of Result pointers that correspond to all the 's + /// pending. + MAP_MANAGER result_map_; + + /// The lock to protect the result map which is shared. The queue + /// is updated by main thread in the register function call and + /// through the auxillary thread in the asynch pseudo task. + ACE_SYNCH_MUTEX lock_; +}; + +/** + * @class ACE_WIN32_Asynch_Transmit_File_Result + * + * + * @brief This class implements ACE_Asynch_Transmit_File::Result for + * WIN32 platforms. + * + * This class has all the information necessary for the + * @a handler to uniquiely identify the completion of the + * asynchronous transmit file. + */ +class ACE_Export ACE_WIN32_Asynch_Transmit_File_Result : public virtual ACE_Asynch_Transmit_File_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory class will have special permission. + friend class ACE_WIN32_Asynch_Transmit_File; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// Socket used for transmitting the file. + ACE_HANDLE socket (void) const; + + /// File from which the data is read. + ACE_HANDLE file (void) const; + + /// Header and trailer data associated with this transmit file. + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer (void) const; + + /// The number of bytes which were requested at the start of the + /// asynchronous transmit file. + size_t bytes_to_write (void) const; + + /// Number of bytes per send requested at the start of the transmit + /// file. + size_t bytes_per_send (void) const; + + /// Flags which were passed into transmit file. + u_long flags (void) const; + + // Base class operations. These operations are here to kill some + // warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Transmit_File factory. + ACE_WIN32_Asynch_Transmit_File_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE socket, + ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// Proactor will call this method when the write completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Transmit_File_Result (void); + + /// Network I/O handle. + ACE_HANDLE socket_; + + /// File I/O handle. + ACE_HANDLE file_; + + /// Header and trailer data associated with this transmit file. + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer_; + + /// The number of bytes which were requested at the start of the + /// asynchronous transmit file. + size_t bytes_to_write_; + + /// Number of bytes per send requested at the start of the transmit + /// file. + size_t bytes_per_send_; + + /// Flags which were passed into transmit file. + u_long flags_; +}; + +/** + * @class ACE_WIN32_Asynch_Transmit_File + * + * @brief This class is a factory for starting off asynchronous + * transmit files on a stream. + * + * Once is called, multiple asynchronous s + * can started using this class. A + * ACE_Asynch_Transmit_File::Result will be passed back to the + * @a handler when the asynchronous transmit file completes + * through the callback. + * + * The transmit_file function transmits file data over a + * connected network connection. The function uses the operating + * system's cache manager to retrieve the file data. This + * function provides high-performance file data transfer over + * network connections. This function would be of great use in + * a Web Server, Image Server, etc. + */ +class ACE_Export ACE_WIN32_Asynch_Transmit_File : public virtual ACE_Asynch_Transmit_File_Impl, + public ACE_WIN32_Asynch_Operation +{ +public: + /// Constructor. + ACE_WIN32_Asynch_Transmit_File (ACE_WIN32_Proactor *win32_proactor); + + /** + * This starts off an asynchronous transmit file. The is a + * handle to an open file. is a pointer to a + * data structure that contains pointers to data to send before and + * after the file data is sent. Set this parameter to 0 if you only + * want to transmit the file data. Upto @a bytes_to_write will be + * written to the . If you want to send the entire file, + * let @a bytes_to_write = 0. @a bytes_per_send is the size of each + * block of data sent per send operation. Please read the Win32 + * documentation on what the flags should be. + */ + int transmit_file (ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + int priority, + int signal_number = 0); + + /// Destructor. + ~ACE_WIN32_Asynch_Transmit_File (void); + + // Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid VC++ warnings. They route the + // call to the ACE_WIN32_Asynch_Operation base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; +}; + +/** + * @class ACE_WIN32_Asynch_Read_Dgram_Result + * + * @brief This class provides concrete implementation for + * ACE_Asynch_Read_Dgram::Result class. + */ +class ACE_Export ACE_WIN32_Asynch_Read_Dgram_Result : public virtual ACE_Asynch_Read_Dgram_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory class will have special permissions. + friend class ACE_WIN32_Asynch_Read_Dgram; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// The number of bytes which were requested at the start of the + /// asynchronous read. + size_t bytes_to_read (void) const; + + /// Message block which contains the read data + ACE_Message_Block *message_block (void) const; + + /// The address of where the packet came from + int remote_address (ACE_Addr& addr) const; + + sockaddr *saddr () const; + + /// The flags used in the read + int flags (void) const; + + /// I/O handle used for reading. + ACE_HANDLE handle (void) const; + + // Base class operations. These operations are here to kill + // dominance warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Read_Dgram factory. + ACE_WIN32_Asynch_Read_Dgram_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_read, + int flags, + int protocol_family, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// Proactor will call this method when the read completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Read_Dgram_Result (void); + + /// Bytes requested when the asynchronous read was initiated. + size_t bytes_to_read_; + + /// Message block for reading the data into. + ACE_Message_Block *message_block_; + + /// The address of where the packet came from + ACE_Addr *remote_address_; + + int addr_len_; + + /// The flags used in the read + int flags_; + + /// I/O handle used for reading. + ACE_HANDLE handle_; +}; + +/** + * @class ACE_WIN32_Asynch_Read_Dgram + * + * @brief This class is a factory for starting off asynchronous reads + * on a UDP socket. + * + * Once is called, multiple asynchronous s can be + * started using this class. An ACE_Asynch_Read_Dgram::Result + * will be passed back to the @a handler when the asynchronous + * reads completes through the + * callback. + * + */ +class ACE_Export ACE_WIN32_Asynch_Read_Dgram : public virtual ACE_Asynch_Read_Dgram_Impl, + public ACE_WIN32_Asynch_Operation +{ +public: + /// Constructor. + ACE_WIN32_Asynch_Read_Dgram (ACE_WIN32_Proactor *win32_proactor); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Read_Dgram (void); + + /** This starts off an asynchronous read. Upto + * total_size()> will be read and stored in the + * @a message_block. @a message_block's will be updated to reflect + * the added bytes if the read operation is successfully completed. + * Return code of 1 means immediate success and + * will contain number of bytes read. The + * method will still be called. Return code of 0 means the IO will + * complete proactively. Return code of -1 means there was an error, use + * errno to get the error code. + * + * Scatter/gather is supported on WIN32 by using the cont()> + * method. Up to ACE_IOV_MAX @a message_block's are supported. Upto + * size()> bytes will be read into each for + * a total of total_size()> bytes. All @a message_block's + * 's will be updated to reflect the added bytes for each + * @a message_block + */ + virtual ssize_t recv (ACE_Message_Block *message_block, + size_t &number_of_bytes_recvd, + int flags, + int protocol_family, + const void *act, + int priority, + int signal_number); + + // Methods belong to ACE_WIN32_Asynch_Operation base class. These + // methods are defined here to avoid VC++ warnings. They route the + // call to the ACE_WIN32_Asynch_Operation base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +protected: + /// Do-nothing constructor. + ACE_WIN32_Asynch_Read_Dgram (void); +}; + +/** + * @class ACE_WIN32_Asynch_Write_Dgram_Result + * + * @brief This class provides concrete implementation for + * ACE_Asynch_Write_Dgram::Result class. + */ +class ACE_Export ACE_WIN32_Asynch_Write_Dgram_Result : public virtual ACE_Asynch_Write_Dgram_Result_Impl, + public ACE_WIN32_Asynch_Result +{ + /// Factory class willl have special permissions. + friend class ACE_WIN32_Asynch_Write_Dgram; + + /// Proactor class has special permission. + friend class ACE_WIN32_Proactor; + +public: + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write (void) const; + + /// Message block which contains the sent data + ACE_Message_Block *message_block (void) const; + + /// The flags using in the write + int flags (void) const; + + /// I/O handle used for writing. + ACE_HANDLE handle (void) const; + + // = Base class operations. These operations are here to kill some + // warnings. These methods call the base class methods. + + /// Number of bytes transferred by the operation. + size_t bytes_transferred (void) const; + + /// ACT associated with the operation. + const void *act (void) const; + + /// Did the operation succeed? + int success (void) const; + + /** + * This returns the ACT associated with the handle when it was + * registered with the I/O completion port. This ACT is not the + * same as the ACT associated with the asynchronous operation. + */ + const void *completion_key (void) const; + + /// Error value if the operation fail. + u_long error (void) const; + + /// Event associated with the OVERLAPPED structure. + ACE_HANDLE event (void) const; + + /// This really make sense only when doing file I/O. + u_long offset (void) const; + + /// Offset_high associated with the OVERLAPPED structure. + u_long offset_high (void) const; + + /// The priority of the asynchronous operation. Currently, this is + /// not supported on Win32. + int priority (void) const; + + /// No-op. Returns 0. + int signal_number (void) const; + + /// Post @c this to the Proactor's completion port. + int post_completion (ACE_Proactor_Impl *proactor); + +protected: + /// Constructor is protected since creation is limited to + /// ACE_Asynch_Write_Stream factory. + ACE_WIN32_Asynch_Write_Dgram_Result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_write, + int flags, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// ACE_Proactor will call this method when the write completes. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Write_Dgram_Result (void); + + /// The number of bytes which were requested at the start of the + /// asynchronous write. + size_t bytes_to_write_; + + /// Message block used for the send. + ACE_Message_Block *message_block_; + + /// The flags using in the write + int flags_; + + /// I/O handle used for writing. + ACE_HANDLE handle_; +}; + +/** + * @class ACE_WIN32_Asynch_Write_Dgram + * + * @brief This class is a factory for starting off asynchronous writes + * on a UDP socket. + * + * + * Once is called, multiple asynchronous s can + * started using this class. A ACE_Asynch_Write_Stream::Result + * will be passed back to the @a handler when the asynchronous + * write completes through the + * callback. + */ +class ACE_Export ACE_WIN32_Asynch_Write_Dgram : public virtual ACE_Asynch_Write_Dgram_Impl, + public ACE_WIN32_Asynch_Operation +{ +public: + /// Constructor. + ACE_WIN32_Asynch_Write_Dgram (ACE_WIN32_Proactor *win32_proactor); + + /// Destructor. + virtual ~ACE_WIN32_Asynch_Write_Dgram (void); + + /** This starts off an asynchronous send. Upto + * total_length()> will be sent. @a message_block's + * will be updated to reflect the sent bytes if the send operation + * is successfully completed. + * Return code of 1 means immediate success and + * is updated to number of bytes sent. The + * method will still be called. Return code of 0 means the IO will + * complete proactively. Return code of -1 means there was an error, use + * errno to get the error code. + * + * Scatter/gather is supported on WIN32 by using the cont()> + * method. Up to ACE_IOV_MAX @a message_block's are supported. Upto + * length()> bytes will be sent from each + * for a total of total_length()> bytes. All + * @a message_block's 's will be updated to reflect the bytes sent + * from each @a message_block. + */ + virtual ssize_t send (ACE_Message_Block *message_block, + size_t &number_of_bytes_sent, + int flags, + const ACE_Addr &addr, + const void *act, + int priority, + int signal_number); + + // = Methods belonging to base class. + + // These methods are defined here to avoid VC++ warnings. They route + // the call to the base class. + + /** + * Initializes the factory with information which will be used with + * each asynchronous call. If ( == ACE_INVALID_HANDLE), + * will be called on the @a handler to get the + * correct handle. + */ + int open (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + const void *completion_key, + ACE_Proactor *proactor); + + /** + * This cancels all pending accepts operations that were issued by + * the calling thread. The function does not cancel asynchronous + * operations issued by other threads. + */ + int cancel (void); + + /// Return the underlying proactor. + ACE_Proactor* proactor (void) const; + +protected: + /// Do-nothing constructor. + ACE_WIN32_Asynch_Write_Dgram (void); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO && ACE_HAS_WINSOCK2 */ +#include /**/ "ace/post.h" +#endif /* ACE_WIN32_ASYNCH_IO_H */ diff --git a/dep/ACE_wrappers/ace/WIN32_Proactor.cpp b/dep/ACE_wrappers/ace/WIN32_Proactor.cpp new file mode 100644 index 000000000..a55983897 --- /dev/null +++ b/dep/ACE_wrappers/ace/WIN32_Proactor.cpp @@ -0,0 +1,804 @@ +// $Id: WIN32_Proactor.cpp 80826 2008-03-04 14:51:23Z wotte $ + +// ACE_RCSID(ace, Proactor, "$Id: WIN32_Proactor.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#include "ace/WIN32_Proactor.h" + +#if defined (ACE_WIN32) && defined (ACE_HAS_WIN32_OVERLAPPED_IO) +// WIN implemenatation of the Proactor. + +#include "ace/Log_Msg.h" +#include "ace/Object_Manager.h" +#include "ace/OS_NS_errno.h" +#include "ace/OS_NS_unistd.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_WIN32_Wakeup_Completion + * + * This is result object is used by the of the + * ACE_Proactor interface to wake up all the threads blocking + * for completions. + */ +class ACE_WIN32_Wakeup_Completion : public ACE_WIN32_Asynch_Result +{ + +public: + /// Constructor. + ACE_WIN32_Wakeup_Completion (ACE_Handler::Proxy_Ptr &handler_proxy, + const void *act = 0, + ACE_HANDLE event = ACE_INVALID_HANDLE, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + + /// Destructor. + virtual ~ACE_WIN32_Wakeup_Completion (void); + + /// This method calls the 's method. + virtual void complete (size_t bytes_transferred = 0, + int success = 1, + const void *completion_key = 0, + u_long error = 0); +}; + +ACE_WIN32_Proactor::ACE_WIN32_Proactor (size_t number_of_threads, + bool used_with_reactor_event_loop) + : completion_port_ (0), + // This *MUST* be 0, *NOT* ACE_INVALID_HANDLE !!! + number_of_threads_ (static_cast (number_of_threads)), + used_with_reactor_event_loop_ (used_with_reactor_event_loop) +{ + // Create the completion port. + this->completion_port_ = ::CreateIoCompletionPort (INVALID_HANDLE_VALUE, + 0, + 0, + this->number_of_threads_); + if (this->completion_port_ == 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("CreateIoCompletionPort"))); + + this->get_asynch_pseudo_task ().start (); +} + +ACE_WIN32_Proactor::~ACE_WIN32_Proactor (void) +{ + this->get_asynch_pseudo_task ().stop (); + + this->close (); +} + +ACE_Asynch_Pseudo_Task & +ACE_WIN32_Proactor::get_asynch_pseudo_task () +{ + return this->pseudo_task_; +} + +int +ACE_WIN32_Proactor::close (void) +{ + // Close the completion port + if (this->completion_port_ != 0) + { + // To avoid memory leaks we should delete all results from queue. + + for (;;) + { + ACE_OVERLAPPED *overlapped = 0; + u_long bytes_transferred = 0; + ULONG_PTR completion_key = 0; + + // Get the next asynchronous operation that completes + BOOL res = ::GetQueuedCompletionStatus + (this->completion_port_, + &bytes_transferred, + &completion_key, + &overlapped, + 0); // poll + + if (overlapped == 0 || res == FALSE) + break; + + ACE_WIN32_Asynch_Result *asynch_result = + (ACE_WIN32_Asynch_Result *) overlapped; + + delete asynch_result; + } + + int result = ACE_OS::close (this->completion_port_); + this->completion_port_ = 0; + return result; + } + + return 0; +} + +int +ACE_WIN32_Proactor::register_handle (ACE_HANDLE handle, + const void *completion_key) +{ + ULONG_PTR comp_key (reinterpret_cast (completion_key)); + + // No locking is needed here as no state changes. + ACE_HANDLE cp = ::CreateIoCompletionPort (handle, + this->completion_port_, + comp_key, + this->number_of_threads_); + if (cp == 0) + { + ACE_OS::set_errno_to_last_error (); + // If errno == ERROR_INVALID_PARAMETER, then this handle was + // already registered. + if (errno != ERROR_INVALID_PARAMETER) + { + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("CreateIoCompletionPort"))); + } + return -1; + } + } + return 0; +} + +ACE_Asynch_Read_Stream_Impl * +ACE_WIN32_Proactor::create_asynch_read_stream (void) +{ + ACE_Asynch_Read_Stream_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Read_Stream (this), + 0); + return implementation; +} + +ACE_Asynch_Write_Stream_Impl * +ACE_WIN32_Proactor::create_asynch_write_stream (void) +{ + ACE_Asynch_Write_Stream_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Write_Stream (this), + 0); + return implementation; +} + +ACE_Asynch_Read_Dgram_Impl * +ACE_WIN32_Proactor::create_asynch_read_dgram (void) +{ + ACE_Asynch_Read_Dgram_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Read_Dgram (this), + 0); + return implementation; +} + +ACE_Asynch_Write_Dgram_Impl * +ACE_WIN32_Proactor::create_asynch_write_dgram (void) +{ + ACE_Asynch_Write_Dgram_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Write_Dgram (this), + 0); + return implementation; +} + +ACE_Asynch_Read_File_Impl * +ACE_WIN32_Proactor::create_asynch_read_file (void) +{ + ACE_Asynch_Read_File_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Read_File (this), + 0); + return implementation; +} + +ACE_Asynch_Write_File_Impl * +ACE_WIN32_Proactor::create_asynch_write_file (void) +{ + ACE_Asynch_Write_File_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Write_File (this), + 0); + return implementation; +} + +ACE_Asynch_Accept_Impl * +ACE_WIN32_Proactor::create_asynch_accept (void) +{ + ACE_Asynch_Accept_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Accept (this), + 0); + return implementation; +} + +ACE_Asynch_Connect_Impl * +ACE_WIN32_Proactor::create_asynch_connect (void) +{ + ACE_Asynch_Connect_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Connect (this), + 0); + return implementation; +} + +ACE_Asynch_Transmit_File_Impl * +ACE_WIN32_Proactor::create_asynch_transmit_file (void) +{ + ACE_Asynch_Transmit_File_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Transmit_File (this), + 0); + return implementation; +} + +ACE_Asynch_Read_Stream_Result_Impl * +ACE_WIN32_Proactor::create_asynch_read_stream_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Read_Stream_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Read_Stream_Result (handler_proxy, + handle, + message_block, + bytes_to_read, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Write_Stream_Result_Impl * +ACE_WIN32_Proactor::create_asynch_write_stream_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Write_Stream_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Write_Stream_Result (handler_proxy, + handle, + message_block, + bytes_to_write, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Read_File_Result_Impl * +ACE_WIN32_Proactor::create_asynch_read_file_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Read_File_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Read_File_Result (handler_proxy, + handle, + message_block, + bytes_to_read, + act, + offset, + offset_high, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Write_File_Result_Impl * +ACE_WIN32_Proactor::create_asynch_write_file_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Write_File_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Write_File_Result (handler_proxy, + handle, + message_block, + bytes_to_write, + act, + offset, + offset_high, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Read_Dgram_Result_Impl * +ACE_WIN32_Proactor::create_asynch_read_dgram_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_read, + int flags, + int protocol_family, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Read_Dgram_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Read_Dgram_Result (handler_proxy, + handle, + message_block, + bytes_to_read, + flags, + protocol_family, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Write_Dgram_Result_Impl * +ACE_WIN32_Proactor::create_asynch_write_dgram_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_read, + int flags, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Write_Dgram_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Write_Dgram_Result(handler_proxy, + handle, + message_block, + bytes_to_read, + flags, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Accept_Result_Impl * +ACE_WIN32_Proactor::create_asynch_accept_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE listen_handle, + ACE_HANDLE accept_handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Accept_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Accept_Result (handler_proxy, + listen_handle, + accept_handle, + message_block, + bytes_to_read, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Connect_Result_Impl * +ACE_WIN32_Proactor::create_asynch_connect_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE connect_handle, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Connect_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Connect_Result (handler_proxy, + connect_handle, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Transmit_File_Result_Impl * +ACE_WIN32_Proactor::create_asynch_transmit_file_result + (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE socket, + ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Transmit_File_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Transmit_File_Result (handler_proxy, + socket, + file, + header_and_trailer, + bytes_to_write, + offset, + offset_high, + bytes_per_send, + flags, + act, + event, + priority, + signal_number), + 0); + return implementation; +} + +ACE_Asynch_Result_Impl * +ACE_WIN32_Proactor::create_asynch_timer (const ACE_Handler::Proxy_Ptr &handler_proxy, + const void *act, + const ACE_Time_Value &tv, + ACE_HANDLE event, + int priority, + int signal_number) +{ + ACE_Asynch_Result_Impl *implementation = 0; + ACE_NEW_RETURN (implementation, + ACE_WIN32_Asynch_Timer (handler_proxy, + act, + tv, + event, + priority, + signal_number), + 0); + return implementation; +} + +int +ACE_WIN32_Proactor::handle_signal (int, siginfo_t *, ucontext_t *) +{ + // Perform a non-blocking "poll" for all the I/O events that have + // completed in the I/O completion queue. + + int result = 0; + + for (ACE_Time_Value timeout (0, 0); + ; + ) + { + result = this->handle_events (timeout); + + if (result != 1) + break; + } + + // If our handle_events failed, we'll report a failure to the + // Reactor. + return result == -1 ? -1 : 0; +} + +int +ACE_WIN32_Proactor::handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask) +{ + ACE_UNUSED_ARG (close_mask); + ACE_UNUSED_ARG (handle); + + return this->close (); +} + +ACE_HANDLE +ACE_WIN32_Proactor::get_handle (void) const +{ + if (this->used_with_reactor_event_loop_) + return this->event_.handle (); + else + return 0; +} + +int +ACE_WIN32_Proactor::handle_events (ACE_Time_Value &wait_time) +{ + // Decrement with the amount of time spent in the method + ACE_Countdown_Time countdown (&wait_time); + return this->handle_events (wait_time.msec ()); +} + +int +ACE_WIN32_Proactor::handle_events (void) +{ + return this->handle_events (ACE_INFINITE); +} + +int +ACE_WIN32_Proactor::handle_events (unsigned long milli_seconds) +{ + ACE_OVERLAPPED *overlapped = 0; + u_long bytes_transferred = 0; + ULONG_PTR completion_key = 0; + + // Get the next asynchronous operation that completes + BOOL result = ::GetQueuedCompletionStatus (this->completion_port_, + &bytes_transferred, + &completion_key, + &overlapped, + milli_seconds); + if (result == FALSE && overlapped == 0) + { + ACE_OS::set_errno_to_last_error (); + + switch (errno) + { + case WAIT_TIMEOUT: + errno = ETIME; + return 0; + + case ERROR_SUCCESS: + // Calling GetQueuedCompletionStatus with timeout value 0 + // returns FALSE with extended errno "ERROR_SUCCESS" errno = + // ETIME; ?? I don't know if this has to be done !! + return 0; + + default: + if (ACE::debug ()) + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("GetQueuedCompletionStatus"))); + return -1; + } + } + else if (overlapped != 0) + { + // Narrow the result. + ACE_WIN32_Asynch_Result *asynch_result = (ACE_WIN32_Asynch_Result *) overlapped; + + // If errors happen, grab the error. + if (result == FALSE) + ACE_OS::set_errno_to_last_error (); + else + errno = 0; + + u_long result_err = asynch_result->error (); + + // if "result_err" is 0 than + // It is normal OS/WIN32 AIO completion. + // We have cleared asynch_result->error_ + // during shared_read/shared_write. + // The real error code is already stored in "errno", + // so copy "errno" value to the "result_err" + // and pass this "result_err" code + // to the application_specific_code () + // else + // "result_err" non zero + // it means we have "post_completed" result + // so pass this "result_err" code + // to the application_specific_code () + + if (result_err == 0) + result_err = errno ; + + this->application_specific_code (asynch_result, + static_cast (bytes_transferred), + (void *) completion_key, + result_err); + } + return 1; +} + +void +ACE_WIN32_Proactor::application_specific_code (ACE_WIN32_Asynch_Result *asynch_result, + size_t bytes_transferred, + const void *completion_key, + u_long error) +{ + ACE_SEH_TRY + { + // Call completion hook + asynch_result->complete (bytes_transferred, + error ? 0 : 1, + (void *) completion_key, + error); + } + ACE_SEH_FINALLY + { + // This is crucial to prevent memory leaks + delete asynch_result; + } +} + +int +ACE_WIN32_Proactor::post_completion (ACE_WIN32_Asynch_Result *result) +{ + // Grab the event associated with the Proactor + HANDLE handle = this->get_handle (); + + // pass + // bytes_transferred + // completion_key + // to the ::PostQueuedCompletionStatus() + // error will be extracted later in handle_events() + + DWORD bytes_transferred = 0; + const void * completion_key = 0 ; + + if (result != 0) + { + // This cast is ok since the original API calls restricted the transfer + // counts to DWORD range. + bytes_transferred = static_cast (result->bytes_transferred ()); + completion_key = result->completion_key(); + } + + ULONG_PTR comp_key (reinterpret_cast (completion_key)); + + // Post a completion + if (::PostQueuedCompletionStatus (this->completion_port_, // completion port + bytes_transferred, // xfer count + comp_key, // completion key + result // overlapped + ) == FALSE) + { + delete result; + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("PostQueuedCompletionStatus failed"))); + } + return -1; + } + + // If Proactor event is valid, signal it + if (handle != ACE_INVALID_HANDLE + && handle != 0) + ACE_OS::event_signal (&handle); + + return 0; +} + +int +ACE_WIN32_Proactor::post_wakeup_completions (int how_many) +{ + ACE_WIN32_Wakeup_Completion *wakeup_completion = 0; + + for (ssize_t ci = 0; ci < how_many; ci++) + { + ACE_NEW_RETURN + (wakeup_completion, + ACE_WIN32_Wakeup_Completion (this->wakeup_handler_.proxy ()), + -1); + + if (wakeup_completion->post_completion (this) == -1) + return -1; + } + + return 0; +} + +int +ACE_WIN32_Proactor::wake_up_dispatch_threads (void) +{ + return 0; +} + +int +ACE_WIN32_Proactor::close_dispatch_threads (int) +{ + return 0; +} + +size_t +ACE_WIN32_Proactor::number_of_threads (void) const +{ + return static_cast (this->number_of_threads_); +} + +void +ACE_WIN32_Proactor::number_of_threads (size_t threads) +{ + this->number_of_threads_ = static_cast (threads); +} + +ACE_WIN32_Asynch_Timer::ACE_WIN32_Asynch_Timer + (const ACE_Handler::Proxy_Ptr &handler_proxy, + const void *act, + const ACE_Time_Value &tv, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_WIN32_Asynch_Result (handler_proxy, act, event, 0, 0, priority, + signal_number), + time_ (tv) +{ +} + +void +ACE_WIN32_Asynch_Timer::complete (size_t, + int, + const void *, + u_long) +{ + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_time_out (this->time_, this->act ()); +} + +ACE_WIN32_Wakeup_Completion::ACE_WIN32_Wakeup_Completion + (ACE_Handler::Proxy_Ptr &handler_proxy, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number) + : ACE_Asynch_Result_Impl (), + ACE_WIN32_Asynch_Result + (handler_proxy, act, event, 0, 0, priority, signal_number) +{ +} + +ACE_WIN32_Wakeup_Completion::~ACE_WIN32_Wakeup_Completion (void) +{ +} + +void +ACE_WIN32_Wakeup_Completion::complete (size_t /* bytes_transferred */, + int /* success */, + const void * /* completion_key */, + u_long /* error */) +{ + ACE_Handler *handler = this->handler_proxy_.get ()->handler (); + if (handler != 0) + handler->handle_wakeup (); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_WIN32 */ diff --git a/dep/ACE_wrappers/ace/WIN32_Proactor.h b/dep/ACE_wrappers/ace/WIN32_Proactor.h new file mode 100644 index 000000000..4fb686d7a --- /dev/null +++ b/dep/ACE_wrappers/ace/WIN32_Proactor.h @@ -0,0 +1,325 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file WIN32_Proactor.h + * + * $Id: WIN32_Proactor.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali (irfan@cs.wustl.edu) + * @author Tim Harrison (harrison@cs.wustl.edu) + * @author Alexander Babu Arulanthu + * @author Roger Tragin + * @author Alexander Libman + */ +//============================================================================= + +#ifndef ACE_WIN32_PROACTOR_H +#define ACE_WIN32_PROACTOR_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_WIN32) && defined (ACE_HAS_WIN32_OVERLAPPED_IO) +// WIN32 implementation of the Proactor. + +#include "ace/WIN32_Asynch_IO.h" +#include "ace/Event_Handler.h" + +#include "ace/Proactor_Impl.h" +#include "ace/Asynch_Pseudo_Task.h" +#include "ace/Auto_Event.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations. +class ACE_WIN32_Asynch_Result; +class ACE_WIN32_Proactor_Timer_Handler; + +/** + * @class ACE_WIN32_Proactor + * + * @brief A manager for asynchronous event demultiplexing on Win32. + * + * See the Proactor pattern description at + * http://www.cs.wustl.edu/~schmidt/PDF/proactor.pdf for more + * details. + */ +class ACE_Export ACE_WIN32_Proactor : public ACE_Proactor_Impl +{ + friend class ACE_WIN32_Asynch_Connect; + +public: + /// A do nothing constructor. + ACE_WIN32_Proactor (size_t number_of_threads = 0, + bool used_with_reactor_event_loop = false); + + /// Virtual destruction. + virtual ~ACE_WIN32_Proactor (void); + + /// Close the IO completion port. + virtual int close (void); + + /// This method adds the @a handle to the I/O completion port. This + /// function is a no-op function for Unix systems. + virtual int register_handle (ACE_HANDLE handle, + const void *completion_key); + + /** + * Dispatch a single set of events. If @a wait_time elapses before + * any events occur, return 0. Return 1 on success i.e., when a + * completion is dispatched, non-zero (-1) on errors and errno is + * set accordingly. + */ + virtual int handle_events (ACE_Time_Value &wait_time); + + /** + * Block indefinitely until at least one event is dispatched. + * Dispatch a single set of events. Return 1 on success i.e., when a + * completion is dispatched, non-zero (-1) on errors and errno is + * set accordingly. + */ + virtual int handle_events (void); + + /** + * Post a result to the completion port of the Proactor. If errors + * occur, the result will be deleted by this method. If successful, + * the result will be deleted by the Proactor when the result is + * removed from the completion port. Therefore, the result should + * have been dynamically allocated and should be orphaned by the + * user once this method is called. + */ + virtual int post_completion (ACE_WIN32_Asynch_Result *result); + + /// Add wakeup dispatch threads (reinit). + int wake_up_dispatch_threads (void); + + /// Close all dispatch threads. + int close_dispatch_threads (int wait); + + /// Get number of thread used as a parameter to @c CreateIoCompletionPort. + size_t number_of_threads (void) const; + + /// Set number of thread used as a parameter to @c CreateIoCompletionPort. + void number_of_threads (size_t threads); + + /// Get the event handle. + virtual ACE_HANDLE get_handle (void) const; + + virtual ACE_Asynch_Read_Stream_Impl *create_asynch_read_stream (void); + virtual ACE_Asynch_Write_Stream_Impl *create_asynch_write_stream (void); + virtual ACE_Asynch_Read_File_Impl *create_asynch_read_file (void); + virtual ACE_Asynch_Write_File_Impl *create_asynch_write_file (void); + virtual ACE_Asynch_Read_Dgram_Impl *create_asynch_read_dgram (void); + virtual ACE_Asynch_Write_Dgram_Impl *create_asynch_write_dgram (void); + virtual ACE_Asynch_Accept_Impl *create_asynch_accept (void); + virtual ACE_Asynch_Connect_Impl *create_asynch_connect (void); + virtual ACE_Asynch_Transmit_File_Impl *create_asynch_transmit_file (void); + + // Methods used to create Asynch_IO_Result objects. We create the right + // objects here in these methods. + + virtual ACE_Asynch_Read_Stream_Result_Impl *create_asynch_read_stream_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + virtual ACE_Asynch_Write_Stream_Result_Impl *create_asynch_write_stream_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + virtual ACE_Asynch_Read_File_Result_Impl *create_asynch_read_file_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + virtual ACE_Asynch_Write_File_Result_Impl *create_asynch_write_file_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + size_t bytes_to_write, + const void* act, + u_long offset, + u_long offset_high, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// Create the correct implementation class for ACE_Asynch_Read_Dgram::Result. + virtual ACE_Asynch_Read_Dgram_Result_Impl *create_asynch_read_dgram_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_read, + int flags, + int protocol_family, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// Create the correct implementation class for ACE_Asynch_Write_Dgram::Result. + virtual ACE_Asynch_Write_Dgram_Result_Impl *create_asynch_write_dgram_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE handle, + ACE_Message_Block *message_block, + size_t bytes_to_write, + int flags, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + virtual ACE_Asynch_Accept_Result_Impl *create_asynch_accept_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE listen_handle, + ACE_HANDLE accept_handle, + ACE_Message_Block &message_block, + size_t bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + virtual ACE_Asynch_Connect_Result_Impl *create_asynch_connect_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE connect_handle, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + + virtual ACE_Asynch_Transmit_File_Result_Impl *create_asynch_transmit_file_result (const ACE_Handler::Proxy_Ptr &handler_proxy, + ACE_HANDLE socket, + ACE_HANDLE file, + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, + size_t bytes_to_write, + u_long offset, + u_long offset_high, + size_t bytes_per_send, + u_long flags, + const void *act, + ACE_HANDLE event, + int priority, + int signal_number = 0); + + /// Create a timer result object which can be used with the Timer + /// mechanism of the Proactor. + virtual ACE_Asynch_Result_Impl *create_asynch_timer (const ACE_Handler::Proxy_Ptr &handler_proxy, + const void *act, + const ACE_Time_Value &tv, + ACE_HANDLE event, + int priority, + int signal_number = 0); + +protected: + /// Task to process pseudo-asynchronous operations + ACE_Asynch_Pseudo_Task & get_asynch_pseudo_task (void); + + /// Called when object is signaled by OS (either via UNIX signals or + /// when a Win32 object becomes signaled). + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + /// Called when object is removed from the ACE_Reactor. + virtual int handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask close_mask); + + /** + * Dispatch a single set of events. If @a milli_seconds elapses + * before any events occur, return 0. Return 1 if a completion is + * dispatched. Return -1 on errors. + */ + virtual int handle_events (unsigned long milli_seconds); + + /// Protect against structured exceptions caused by user code when + /// dispatching handles. + void application_specific_code (ACE_WIN32_Asynch_Result *asynch_result, + size_t bytes_transferred, + const void *completion_key, + u_long error); + + /** + * Post @a how_many completions to the completion port so that all + * threads can wake up. This is used in conjunction with the + * run_event_loop(). + */ + virtual int post_wakeup_completions (int how_many); + + /// Handle for the completion port. Unix doesnt have completion + /// ports. + ACE_HANDLE completion_port_; + + /// This number is passed to the @c CreateIOCompletionPort system + /// call. + DWORD number_of_threads_; + + /// This event is used in conjunction with Reactor when we try to + /// integrate the event loops of Reactor and the Proactor. + ACE_Auto_Event event_; + + /// Flag that indicates whether we are used in conjunction with + /// Reactor. + bool const used_with_reactor_event_loop_; + + /// Handler to handle the wakeups. This works in conjunction with the + /// ACE_Proactor::run_event_loop(). + ACE_Handler wakeup_handler_; + + /// Pseudo-task for asynch connect ( NT/2000) + /// In future should removed in XP with ConnectEx support + ACE_Asynch_Pseudo_Task pseudo_task_; +}; + +/** + * @class ACE_WIN32_Asynch_Timer + * + * @brief This class is posted to the completion port when a timer + * expires. When the complete method of this object is + * called, the @a handler's handle_timeout method will be + * called. + */ +class ACE_WIN32_Asynch_Timer : public ACE_WIN32_Asynch_Result +{ + /// The factory method for this class is with the POSIX_Proactor + /// class. + friend class ACE_WIN32_Proactor; + +protected: + /// Constructor. + ACE_WIN32_Asynch_Timer (const ACE_Handler::Proxy_Ptr &handler_proxy, + const void *act, + const ACE_Time_Value &tv, + ACE_HANDLE event = ACE_INVALID_HANDLE, + int priority = 0, + int signal_number = 0); + + /// This method calls the @a handler's handle_timeout method. + virtual void complete (size_t bytes_transferred, + int success, + const void *completion_key, + u_long error = 0); + + /// Time value requested by caller + ACE_Time_Value time_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_WIN32 */ +#include /**/ "ace/post.h" +#endif /* ACE_PROACTOR_H */ diff --git a/dep/ACE_wrappers/ace/XML_Svc_Conf.cpp b/dep/ACE_wrappers/ace/XML_Svc_Conf.cpp new file mode 100644 index 000000000..23dddad84 --- /dev/null +++ b/dep/ACE_wrappers/ace/XML_Svc_Conf.cpp @@ -0,0 +1,15 @@ +// $Id: XML_Svc_Conf.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/XML_Svc_Conf.h" + +#if (ACE_USES_CLASSIC_SVC_CONF == 0) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_XML_Svc_Conf::~ACE_XML_Svc_Conf (void) +{ +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ diff --git a/dep/ACE_wrappers/ace/XML_Svc_Conf.h b/dep/ACE_wrappers/ace/XML_Svc_Conf.h new file mode 100644 index 000000000..883151e05 --- /dev/null +++ b/dep/ACE_wrappers/ace/XML_Svc_Conf.h @@ -0,0 +1,65 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file XML_Svc_Conf.h + * + * $Id: XML_Svc_Conf.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Nanbor Wang + */ +//============================================================================= + + +#ifndef ACE_XML_SVC_CONF_H +#define ACE_XML_SVC_CONF_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if (ACE_USES_CLASSIC_SVC_CONF==0) + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_XML_Svc_Conf + * + * @brief This abstract class defines the common operations + * ACE_Service_Config expects when using the XML Service Config Parser. + * + * When implementing a concret XML_Svc_Conf class, be sure to overload + * the new/delete function so the dynamically created concret XML_Svc_Conf + * instance can be deleted from the original heap in the DLL/SO. The + * concret XML_Svc_Conf implementation will be put into a DLL/SO that + * ACE applications can link to dynamically using the ACE_DLL class. + * This DLL should include an operation as follow: + * + * extern "C" ACE_XML_Svc_Conf_Parser * _ACEXML_create_XML_Svc_Conf_Object (void); + * + * + */ + +class ACE_Export ACE_XML_Svc_Conf +{ +public: + typedef ACE_XML_Svc_Conf *(*Factory)(void); + + virtual ~ACE_XML_Svc_Conf (void) = 0; + + virtual int parse_file (const ACE_TCHAR file[]) = 0; + + virtual int parse_string (const ACE_TCHAR str[]) = 0; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ + +#include /**/ "ace/post.h" + +#endif /* ACE_XML_SVC_CONF_H */ diff --git a/dep/ACE_wrappers/ace/XTI_ATM_Mcast.cpp b/dep/ACE_wrappers/ace/XTI_ATM_Mcast.cpp new file mode 100644 index 000000000..503e3fea0 --- /dev/null +++ b/dep/ACE_wrappers/ace/XTI_ATM_Mcast.cpp @@ -0,0 +1,70 @@ +// $Id: XTI_ATM_Mcast.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/XTI_ATM_Mcast.h" + +ACE_RCSID(ace, XTI_ATM_Mcast, "$Id: XTI_ATM_Mcast.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ACE_HAS_XTI_ATM) + +#if !defined (__ACE_INLINE__) +#include "ace/XTI_ATM_Mcast.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_ALLOC_HOOK_DEFINE(ACE_XTI_ATM_Mcast) + +void +ACE_XTI_ATM_Mcast::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_XTI_ATM_Mcast::dump"); +#endif /* ACE_HAS_DUMP */ +} + +ACE_XTI_ATM_Mcast::ACE_XTI_ATM_Mcast (void) +{ + ACE_TRACE ("ACE_XTI_ATM_Mcast::ACE_XTI_ATM_Mcast"); +} + +// Add a leaf to the current connection (i.e., multicast). + +int +ACE_XTI_ATM_Mcast::add_leaf (ACE_TLI_Stream ¤t_stream, + const ACE_Addr &remote_sap, + ACE_INT32 leaf_id, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_XTI_ATM_Mcast::add_leaf"); + + struct netbuf call_req; + memset(&call_req, 0, sizeof(call_req)); + call_req.len = remote_sap.get_size (); + call_req.buf = (char *)remote_sap.get_addr (); + + if (::t_addleaf(current_stream.get_handle(), + leaf_id, + &call_req) < 0) + { + // Check for asynchronous event + if (t_errno == TLOOK) + { + int const event = ACE_OS::t_look(current_stream.get_handle()); + if (event != TNODATA && event != T_DATA) + return -1; + else + // If this doesn't work for asynchronous calls we need to call + // the XTI/ATM t_rcvleafchange() function to check for t_addleaf + // completion. + return complete (current_stream, 0, timeout); + } + else + return -1; + } + + return 0; +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_XTI_ATM */ diff --git a/dep/ACE_wrappers/ace/XTI_ATM_Mcast.h b/dep/ACE_wrappers/ace/XTI_ATM_Mcast.h new file mode 100644 index 000000000..bfdfa92c9 --- /dev/null +++ b/dep/ACE_wrappers/ace/XTI_ATM_Mcast.h @@ -0,0 +1,137 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file XTI_ATM_Mcast.h + * + * $Id: XTI_ATM_Mcast.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Joe Hoffert + */ +//============================================================================= + + +#ifndef ACE_XTI_ATM_MCAST_H +#define ACE_XTI_ATM_MCAST_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_XTI_ATM) + +#include "ace/TLI_Connector.h" +#include "ace/ATM_Addr.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_XTI_ATM_Mcast + * + * @brief Defines an active connection factory for the ACE_TLI C++ + * wrappers to support XTI/ATM multicast. + */ +class ACE_Export ACE_XTI_ATM_Mcast : public ACE_TLI_Connector +{ +public: + // = Initialization methods. + /// Default constructor. + ACE_XTI_ATM_Mcast (void); + + /** + * Actively connect and produce a @a new_stream if things go well. + * The @a remote_sap is the address that we are trying to connect + * with. The @a timeout is the amount of time to wait to connect. + * If it's 0 then we block indefinitely. If *timeout == {0, 0} then + * the connection is done using non-blocking mode. In this case, if + * the connection can't be made immediately the value of -1 is + * returned with @c errno == EWOULDBLOCK. If *timeout > {0, 0} then + * this is the amount of time to wait before timing out. If the + * time expires before the connection is made @c errno == ETIME. The + * @a local_sap is the value of local address to bind to. If it's + * the default value of ACE_Addr::sap_any then the user is letting + * the OS do the binding. If @a reuse_addr == 1 then the + * is reused, even if it hasn't been cleanedup yet. + */ + ACE_XTI_ATM_Mcast (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0, + const char device[] = ACE_XTI_ATM_DEVICE, + struct t_info *info = 0, + int rw_flag = 1, + struct netbuf *udata = 0, + struct netbuf *opt = 0); + + /** + * Actively connect and produce a @a new_stream if things go well. + * The @a remote_sap is the address that we are trying to connect + * with. The @a timeout is the amount of time to wait to connect. + * If it's 0 then we block indefinitely. If *timeout == {0, 0} then + * the connection is done using non-blocking mode. In this case, if + * the connection can't be made immediately the value of -1 is + * returned with @c errno == EWOULDBLOCK. If *timeout > {0, 0} then + * this is the amount of time to wait before timing out. If the + * time expires before the connection is made @c errno == ETIME. The + * @a local_sap is the value of local address to bind to. If it's + * the default value of ACE_Addr::sap_any then the user is letting + * the OS do the binding. If @a reuse_addr == 1 then the + * is reused, even if it hasn't been cleanedup yet. + */ + int connect (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0, + const char device[] = ACE_XTI_ATM_DEVICE, + struct t_info *info = 0, + int rw_flag = 1, + struct netbuf *udata = 0, + struct netbuf *opt = 0); + + /** + * Actively add a leaf to the currently connected stream (i.e., + * multicast). The @a remote_sap is the address of the leaf that we + * are trying to add. The @a timeout is the amount of time to wait to + * connect. If it's 0 then we block indefinitely. If *timeout == + * {0, 0} then the connection is done using non-blocking mode. In + * this case, if the connection can't be made immediately the value + * of -1 is returned with @c errno == EWOULDBLOCK. If *timeout > + * {0, 0} then this is the amount of time to wait before timing out. + * If the time expires before the connection is made @c errno == ETIME. + */ + int add_leaf (ACE_TLI_Stream ¤t_stream, + const ACE_Addr &remote_sap, + ACE_INT32 leaf_id, + ACE_Time_Value *timeout = 0); + + // = Meta-type info + typedef ACE_ATM_Addr PEER_ADDR; + typedef ACE_TLI_Stream PEER_STREAM; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/XTI_ATM_Mcast.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_XTI_ATM */ + +#include /**/ "ace/post.h" + +#endif /* ACE_XTI_ATM_MCAST_H */ diff --git a/dep/ACE_wrappers/ace/XTI_ATM_Mcast.inl b/dep/ACE_wrappers/ace/XTI_ATM_Mcast.inl new file mode 100644 index 000000000..b182bb41b --- /dev/null +++ b/dep/ACE_wrappers/ace/XTI_ATM_Mcast.inl @@ -0,0 +1,65 @@ +// -*- C++ -*- +// +// $Id: XTI_ATM_Mcast.inl 80826 2008-03-04 14:51:23Z wotte $ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +ACE_XTI_ATM_Mcast::ACE_XTI_ATM_Mcast (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + const char device[], + struct t_info *info, + int rw_flag, + struct netbuf *udata, + struct netbuf *opt) +{ + ACE_TRACE ("ACE_XTI_ATM_Mcast::ACE_XTI_ATM_Mcast"); + if (this->connect (new_stream, remote_sap, timeout, local_sap, reuse_addr, + flags, perms, device, + info, rw_flag, + udata, opt) == ACE_INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME)) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_TLI_Stream::ACE_TLI_Stream"))); +} + +// Connect the to the , waiting up to +// amount of time if necessary. This is simple a pass- +// through function to ACE_TLI_Connector::connect(). It is over- +// ridden to change the default device from TCP to XTI/ATM. + +ACE_INLINE +int +ACE_XTI_ATM_Mcast::connect (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + const char device[], + struct t_info *info, + int rw_flag, + struct netbuf *udata, + struct netbuf *opt) +{ + ACE_TRACE ("ACE_XTI_ATM_Mcast::connect"); + return ACE_TLI_Connector::connect(new_stream, + remote_sap, + timeout, + local_sap, + reuse_addr, + flags, + perms, + device, + info, + rw_flag, + udata, + opt); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ace.rc b/dep/ACE_wrappers/ace/ace.rc new file mode 100644 index 000000000..547924919 --- /dev/null +++ b/dep/ACE_wrappers/ace/ace.rc @@ -0,0 +1,38 @@ +#include "Version.h" + +1 VERSIONINFO + FILEVERSION ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION,0 + PRODUCTVERSION ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "FileDescription", "ACE\0" + VALUE "FileVersion", ACE_VERSION "\0" + VALUE "InternalName", "ACEDLL\0" + VALUE "LegalCopyright", "\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "ACE.DLL\0" + VALUE "ProductName", "ACE\0" + VALUE "ProductVersion", ACE_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +/* + * The following resource is used by the ACE logger to write messages + * to the NT event log. If you are statically linking to the ACE + * library, and you wish to use the NT event log, you should copy this + * message table to your application's resource script. + */ +1 MESSAGETABLE ace_message_table.bin diff --git a/dep/ACE_wrappers/ace/ace_ce_dll.cfg b/dep/ACE_wrappers/ace/ace_ce_dll.cfg new file mode 100644 index 000000000..80c479b32 --- /dev/null +++ b/dep/ACE_wrappers/ace/ace_ce_dll.cfg @@ -0,0 +1 @@ +WCE_CFG=WCE200; \ No newline at end of file diff --git a/dep/ACE_wrappers/ace/ace_message_table.bin b/dep/ACE_wrappers/ace/ace_message_table.bin new file mode 100644 index 000000000..6ac08e5dc Binary files /dev/null and b/dep/ACE_wrappers/ace/ace_message_table.bin differ diff --git a/dep/ACE_wrappers/ace/ace_wchar.cpp b/dep/ACE_wrappers/ace/ace_wchar.cpp new file mode 100644 index 000000000..bec825544 --- /dev/null +++ b/dep/ACE_wrappers/ace/ace_wchar.cpp @@ -0,0 +1,17 @@ +// -*- C++ -*- +// +// $Id: ace_wchar.cpp 80826 2008-03-04 14:51:23Z wotte $ + +#include "ace/config-macros.h" +#include "ace/ace_wchar.h" + +ACE_RCSID(ace, ace_wchar, "$Id: ace_wchar.cpp 80826 2008-03-04 14:51:23Z wotte $") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +#if defined(ACE_HAS_ICONV) +iconv_t ACE_Wide_To_Ascii::ACE_Wide_To_Ascii_iconv_env = 0; +iconv_t ACE_Ascii_To_Wide::ACE_Ascii_To_Wide_iconv_env = 0; +#endif + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/dep/ACE_wrappers/ace/ace_wchar.h b/dep/ACE_wrappers/ace/ace_wchar.h new file mode 100644 index 000000000..f556e0f9c --- /dev/null +++ b/dep/ACE_wrappers/ace/ace_wchar.h @@ -0,0 +1,385 @@ +//* -*- C++ -*- */ + +//============================================================================= +/** + * @file ace_wchar.h + * + * $Id: ace_wchar.h 82441 2008-07-28 13:04:13Z johnnyw $ + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_WCHAR_H +#define ACE_WCHAR_H + +#include "ace/config-macros.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// These macros have been deprecated and should be replaced by their +// ACE_TEXT_* equivalents. These macros are just hacks and may not +// completely provide the old functionality. +#if defined (ACE_LEGACY_MODE) +// Convert the old unicode indicators +# if defined (ACE_HAS_MOSTLY_UNICODE_APIS) +# define ACE_USES_WCHAR +# endif /* ACE_HAS_MOSTLY_UNICODE_APIS */ +# if defined (ACE_HAS_UNICODE) +# define ACE_HAS_WCHAR +# endif /* ACE_HAS_UNICODE */ + +// These are defined to get older stuff to compile +// FUZZ: disable check_for_tchar +# define ASYS_TCHAR ACE_TCHAR +# define ASYS_TEXT ACE_TEXT +# define ASYS_ONLY_MULTIBYTE_STRING ACE_TEXT_ALWAYS_CHAR +# define ASYS_MULTIBYTE_STRING ACE_TEXT_CHAR_TO_TCHAR +# define ASYS_WIDE_STRING ACE_TEXT_CHAR_TO_TCHAR +# define ACE_WIDE_STRING ACE_TEXT_CHAR_TO_TCHAR + +# if defined (ACE_USES_WCHAR) +# define ASYS_ONLY_WIDE_STRING(STRING) STRING +# else /* ACE_USES_WCHAR */ +# define ASYS_ONLY_WIDE_STRING(STRING) \ + ACE_Ascii_To_Wide (STRING).wchar_rep () +# endif /* ACE_USES_WCHAR */ + +# define ACE_TEXT_STRING ACE_TString + +#endif /* ACE_LEGACY_MODE */ + +#if defined (ACE_HAS_XPG4_MULTIBYTE_CHAR) +# if !defined (ACE_HAS_WCHAR) +# define ACE_HAS_WCHAR +# endif +# include /**/ +#endif /* ACE_HAS_XPG4_MULTIBYTE_CHAR */ + +#if defined (ACE_HAS_WCHAR) +# if defined (ACE_VXWORKS) +# include /**/ /* For wchar_t */ +# include /**/ /* For mbstowcs, etc. */ +# include /**/ /* For strlen */ +# if !defined (__RTP__) +# define wint_t unsigned int /* VxWorks has wchar_t but not wint_t */ +# else +# include /**/ +# include /**/ +# endif +# elif defined (ACE_OPENVMS) +# include /**/ +# include /**/ +# elif defined (ACE_HAS_STANDARD_CPP_LIBRARY) && \ + (ACE_HAS_STANDARD_CPP_LIBRARY != 0) +# include /**/ +# include /**/ +# elif defined (ACE_HAS_WINCE) +# include /**/ +# else +# include /**/ +# endif /* ACE_HAS_STANDARD_CPP_LIBRARY */ +#endif /* ACE_HAS_WCHAR */ + +#if defined (ACE_HAS_ICONV) +# include /**/ +# if !defined (ACE_MAX_ICONV_BUFFER) +# define ACE_MAX_ICONV_BUFFER 16*1024 +# endif +#endif /* ACE_HAS_ICONV */ + +#if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \ + (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0) +using std::size_t; +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */ + +// This makes the somewhat dubious assumption that if a platform lacks +// a native wchar_t type, then it will typedef it as unsigned short. +#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_NATIVE_WCHAR_T) +# if !defined (ACE_WSTRING_HAS_USHORT_SUPPORT) +# define ACE_WSTRING_HAS_USHORT_SUPPORT +# endif /* ACE_WSTRING_HAS_USHORT_SUPPORT */ +#endif /* ACE_HAS_WCHAR && !ACE_LACKS_NATIVE_WCHAR_T */ + +// Set the default behaviour for ACE_TEXT_WIDE to use the L-prefix +#if !defined (ACE_USES_L_PREFIX) +# define ACE_USES_L_PREFIX 1 +#endif /* ACE_USES_L_PREFIX */ + +// Define the unicode/wchar related macros correctly + +# if !defined (ACE_TEXT_WIDE) +# if (ACE_USES_L_PREFIX == 1) +# define ACE_TEXT_WIDE_I(STRING) L##STRING +# else /* ACE_USES_L_PREFIX */ +# define ACE_TEXT_WIDE_I(STRING) STRING +# endif /* ACE_USES_L_PREFIX */ +# define ACE_TEXT_WIDE(STRING) ACE_TEXT_WIDE_I (STRING) +# endif /* ACE_TEXT_WIDE */ + +#if defined (ACE_USES_WCHAR) +typedef wchar_t ACE_TCHAR; +typedef char ACE_ANTI_TCHAR; +# define ACE_TEXT(STRING) ACE_TEXT_WIDE (STRING) +# if !defined (ACE_LACKS_DEPRECATED_MACROS) +# define ACE_LIB_TEXT(STRING) ACE_TEXT_WIDE (STRING) +# endif +# define ACE_TEXT_ALWAYS_CHAR(STRING) ACE_Wide_To_Ascii (STRING).char_rep () +# define ACE_TEXT_ALWAYS_WCHAR(STRING) STRING +# define ACE_TEXT_CHAR_TO_TCHAR(STRING) ACE_Ascii_To_Wide (STRING).wchar_rep () +# define ACE_TEXT_WCHAR_TO_TCHAR(STRING) STRING +# define ACE_TEXT_ANTI_TO_TCHAR(STRING) ACE_Ascii_To_Wide (STRING).wchar_rep () +#else /* ACE_USES_WCHAR */ +typedef char ACE_TCHAR; +typedef wchar_t ACE_ANTI_TCHAR; +# define ACE_TEXT(STRING) STRING +# if !defined (ACE_LACKS_DEPRECATED_MACROS) +# define ACE_LIB_TEXT(STRING) STRING +# endif +# define ACE_TEXT_ALWAYS_CHAR(STRING) STRING +# define ACE_TEXT_ALWAYS_WCHAR(STRING) ACE_Ascii_To_Wide (STRING).wchar_rep () +# define ACE_TEXT_CHAR_TO_TCHAR(STRING) STRING +# define ACE_TEXT_WCHAR_TO_TCHAR(STRING) ACE_Wide_To_Ascii (STRING).char_rep () +# define ACE_TEXT_ANTI_TO_TCHAR(STRING) ACE_Wide_To_Ascii (STRING).char_rep () +#endif /* ACE_USES_WCHAR */ + +// The OS_String module defines some wide-char functions that are not +// universally available. In particular, they're not part of the +// XPG4 Worldwide Portability Interface wide-character string handling +// functions. So, if ACE_HAS_XPG4_MULTIBYTE_CHAR is defined, note that +// these functions are missing. +#if defined (ACE_HAS_XPG4_MULTIBYTE_CHAR) + +# if !defined (ACE_LACKS_ITOW) +# define ACE_LACKS_ITOW +# endif + +# if !defined (ACE_LACKS_WCSICMP) +# define ACE_LACKS_WCSICMP +# endif + +# if !defined (ACE_LACKS_WCSNICMP) +# define ACE_LACKS_WCSNICMP +# endif + +# if !defined (ACE_LACKS_WCSDUP) +# define ACE_LACKS_WCSDUP +# endif + +#endif /* ACE_HAS_XPG4_MULTIBYTE_CHAR */ + +#if defined ACE_HAS_WCHAR + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Wide_To_Ascii + * + * @brief A lightweight wchar* to char* string conversion class. + * + * The purpose of this class is to perform conversion from + * wchar* to char* strings. It is not intended for general + * purpose use. + */ +class ACE_Wide_To_Ascii +{ +public: + /// Ctor must take a wchar string. + ACE_Wide_To_Ascii (const wchar_t *s); + + /// Dtor will free up the memory. + ~ACE_Wide_To_Ascii (void); + + /// Return the internal char* representation. + char *char_rep (void); + + /// Converts an wchar_t string to ascii and returns a new string. + static char *convert (const wchar_t *wstr); + +private: + /// Internal pointer to the converted string. + char *s_; + +#if defined (ACE_HAS_ICONV) + static iconv_t ACE_Wide_To_Ascii_iconv_env; +#endif /* ACE_HAS_ICONV */ + + /// Disallow these operation. + ACE_Wide_To_Ascii (void); + ACE_Wide_To_Ascii (ACE_Wide_To_Ascii &); + ACE_Wide_To_Ascii& operator= (ACE_Wide_To_Ascii &); +}; + +/** + * @class ACE_Ascii_To_Wide + * + * @brief A lightweight char* to wchar* string conversion class. + * + * The purpose of this class is to perform conversion from + * char* to wchar* strings. It is not intended for general + * purpose use. + */ +class ACE_Ascii_To_Wide +{ +public: + /// Ctor must take a wchar string. + ACE_Ascii_To_Wide (const char *s); + + /// Dtor will free up the memory. + ~ACE_Ascii_To_Wide (void); + + /// Return the internal wchar* representation. + wchar_t *wchar_rep (void); + + /// Converts an char string to unicode/wide and returns a new string. + static wchar_t *convert (const char *str); + +private: + /// Internal pointer to the converted string. + wchar_t *s_; + +#if defined (ACE_HAS_ICONV) + static iconv_t ACE_Ascii_To_Wide_iconv_env; +#endif /* ACE_HAS_ICONV */ + + /// Disallow these operation. + ACE_Ascii_To_Wide (void); + ACE_Ascii_To_Wide (ACE_Ascii_To_Wide &); + ACE_Ascii_To_Wide operator= (ACE_Ascii_To_Wide &); +}; + +#if defined (ACE_LEGACY_MODE) +typedef ACE_Ascii_To_Wide ACE_OS_CString; +typedef ACE_Wide_To_Ascii ACE_OS_WString; +#endif /* ACE_LEGACY_MODE */ + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_WCHAR */ + +#if defined (ACE_WIN32) +#if defined (ACE_USES_WCHAR) +#define ACE_LPSTR LPWSTR +#define ACE_TEXT_SERVICE_TABLE_ENTRY SERVICE_TABLE_ENTRYW +#define ACE_TEXT_STARTUPINFO STARTUPINFOW +#define ACE_TEXT_WIN32_FIND_DATA WIN32_FIND_DATAW +#define ACE_TEXT_OSVERSIONINFO OSVERSIONINFOW +#define ACE_TEXT_EXPLICIT_ACCESS EXPLICIT_ACCESS_W + +#define ACE_TEXT_CreateEvent ::CreateEventW +#define ACE_TEXT_CreateFile ::CreateFileW +#define ACE_TEXT_CreateFileMapping ::CreateFileMappingW +#define ACE_TEXT_CreateMutex ::CreateMutexW +#define ACE_TEXT_CreateProcess ::CreateProcessW +#define ACE_TEXT_CreateSemaphore ::CreateSemaphoreW +#define ACE_TEXT_CreateService ::CreateServiceW +#define ACE_TEXT_ExpandEnvironmentStrings ::ExpandEnvironmentStringsW +#define ACE_TEXT_FindFirstChangeNotification ::FindFirstChangeNotificationW +#define ACE_TEXT_FindFirstFile ::FindFirstFileW +#define ACE_TEXT_FindNextFile ::FindNextFileW +#define ACE_TEXT_FormatMessage ::FormatMessageW +#define ACE_TEXT_FreeEnvironmentStrings ::FreeEnvironmentStringsW +#define ACE_TEXT_GetComputerName ::GetComputerNameW +#define ACE_TEXT_GetEnvironmentStrings ::GetEnvironmentStringsW +#define ACE_TEXT_GetFileAttributes ::GetFileAttributesW +#define ACE_TEXT_GetModuleFileName ::GetModuleFileNameW +#define ACE_TEXT_GetTempPath ::GetTempPathW +#define ACE_TEXT_GetUserName ::GetUserNameW +#define ACE_TEXT_GetUserNameEx ::GetUserNameExW +#define ACE_TEXT_GetVersionEx ::GetVersionExW +#define ACE_TEXT_LoadLibrary ::LoadLibraryW +#define ACE_TEXT_MoveFileEx ::MoveFileExW +#define ACE_TEXT_WaitNamedPipe ::WaitNamedPipeW +#define ACE_TEXT_OpenFileMapping ::OpenFileMappingW +#define ACE_TEXT_OpenSCManager ::OpenSCManagerW +#define ACE_TEXT_OpenService ::OpenServiceW +#define ACE_TEXT_OutputDebugString ::OutputDebugStringW +#define ACE_TEXT_RegisterEventSource ::RegisterEventSourceW +#define ACE_TEXT_RegisterServiceCtrlHandler ::RegisterServiceCtrlHandlerW +#define ACE_TEXT_RegConnectRegistry ::RegConnectRegistryW +#define ACE_TEXT_RegCreateKeyEx ::RegCreateKeyExW +#define ACE_TEXT_RegDeleteKey ::RegDeleteKeyW +#define ACE_TEXT_RegDeleteValue ::RegDeleteValueW +#define ACE_TEXT_RegEnumKeyEx ::RegEnumKeyExW +#define ACE_TEXT_RegEnumValue ::RegEnumValueW +#define ACE_TEXT_RegCreateKey ::RegCreateKeyW +#define ACE_TEXT_RegOpenKey ::RegOpenKeyW +#define ACE_TEXT_RegOpenKeyEx ::RegOpenKeyExW +#define ACE_TEXT_RegQueryValueEx ::RegQueryValueExW +#define ACE_TEXT_RegSetValueEx ::RegSetValueExW +#define ACE_TEXT_ReportEvent ::ReportEventW +#define ACE_TEXT_SearchPath ::SearchPathW +#define ACE_TEXT_StartService ::StartServiceW +#define ACE_TEXT_StartServiceCtrlDispatcher ::StartServiceCtrlDispatcherW +#define ACE_TEXT_SetFileSecurity ::SetFileSecurityW +#define ACE_TEXT_SetEntriesInAcl ::SetEntriesInAclW +#define ACE_TEXT_PdhExpandCounterPath ::PdhExpandCounterPathW +#define ACE_TEXT_PdhOpenQuery ::PdhOpenQueryW +#define ACE_TEXT_PdhAddCounter ::PdhAddCounterW + +#else /* ACE_USES_WCHAR */ +#define ACE_LPSTR LPSTR +#define ACE_TEXT_SERVICE_TABLE_ENTRY SERVICE_TABLE_ENTRYA +#define ACE_TEXT_STARTUPINFO STARTUPINFOA +#define ACE_TEXT_WIN32_FIND_DATA WIN32_FIND_DATAA +#define ACE_TEXT_OSVERSIONINFO OSVERSIONINFOA +#define ACE_TEXT_EXPLICIT_ACCESS EXPLICIT_ACCESS_A + +#define ACE_TEXT_CreateEvent ::CreateEventA +#define ACE_TEXT_CreateFile ::CreateFileA +#define ACE_TEXT_CreateFileMapping ::CreateFileMappingA +#define ACE_TEXT_CreateMutex ::CreateMutexA +#define ACE_TEXT_CreateProcess ::CreateProcessA +#define ACE_TEXT_CreateSemaphore ::CreateSemaphoreA +#define ACE_TEXT_CreateService ::CreateServiceA +#define ACE_TEXT_ExpandEnvironmentStrings ::ExpandEnvironmentStringsA +#define ACE_TEXT_FindFirstChangeNotification ::FindFirstChangeNotificationA +#define ACE_TEXT_FindFirstFile ::FindFirstFileA +#define ACE_TEXT_FindNextFile ::FindNextFileA +#define ACE_TEXT_FormatMessage ::FormatMessageA +#define ACE_TEXT_FreeEnvironmentStrings ::FreeEnvironmentStringsA +#define ACE_TEXT_GetComputerName ::GetComputerNameA +#define ACE_TEXT_GetEnvironmentStrings ::GetEnvironmentStringsA +#define ACE_TEXT_GetFileAttributes ::GetFileAttributesA +#define ACE_TEXT_GetModuleFileName ::GetModuleFileNameA +#define ACE_TEXT_GetTempPath ::GetTempPathA +#define ACE_TEXT_GetUserName ::GetUserNameA +#define ACE_TEXT_GetUserNameEx ::GetUserNameExA +#define ACE_TEXT_GetVersionEx ::GetVersionExA +#define ACE_TEXT_LoadLibrary ::LoadLibraryA +#define ACE_TEXT_MoveFileEx ::MoveFileExA +#define ACE_TEXT_WaitNamedPipe ::WaitNamedPipeA +#define ACE_TEXT_OpenFileMapping ::OpenFileMappingA +#define ACE_TEXT_OpenSCManager ::OpenSCManagerA +#define ACE_TEXT_OpenService ::OpenServiceA +#define ACE_TEXT_OutputDebugString ::OutputDebugStringA +#define ACE_TEXT_RegisterEventSource ::RegisterEventSourceA +#define ACE_TEXT_RegisterServiceCtrlHandler ::RegisterServiceCtrlHandlerA +#define ACE_TEXT_RegConnectRegistry ::RegConnectRegistryA +#define ACE_TEXT_RegCreateKeyEx ::RegCreateKeyExA +#define ACE_TEXT_RegDeleteKey ::RegDeleteKeyA +#define ACE_TEXT_RegDeleteValue ::RegDeleteValueA +#define ACE_TEXT_RegEnumKeyEx ::RegEnumKeyExA +#define ACE_TEXT_RegEnumValue ::RegEnumValueA +#define ACE_TEXT_RegCreateKey ::RegCreateKeyA +#define ACE_TEXT_RegOpenKey ::RegOpenKeyA +#define ACE_TEXT_RegOpenKeyEx ::RegOpenKeyExA +#define ACE_TEXT_RegQueryValueEx ::RegQueryValueExA +#define ACE_TEXT_RegSetValueEx ::RegSetValueExA +#define ACE_TEXT_ReportEvent ::ReportEventA +#define ACE_TEXT_SearchPath ::SearchPathA +#define ACE_TEXT_StartService ::StartServiceA +#define ACE_TEXT_StartServiceCtrlDispatcher ::StartServiceCtrlDispatcherA +#define ACE_TEXT_SetFileSecurity ::SetFileSecurityA +#define ACE_TEXT_SetEntriesInAcl ::SetEntriesInAclA +#define ACE_TEXT_PdhExpandCounterPath ::PdhExpandCounterPathA +#define ACE_TEXT_PdhOpenQuery ::PdhOpenQueryA +#define ACE_TEXT_PdhAddCounter ::PdhAddCounterA +#endif /* ACE_USES_WCHAR */ +#endif /* ACE_WIN32 */ + +#include "ace/ace_wchar.inl" + +#endif /* ACE_WCHAR_H */ diff --git a/dep/ACE_wrappers/ace/ace_wchar.inl b/dep/ACE_wrappers/ace/ace_wchar.inl new file mode 100644 index 000000000..744b44f5e --- /dev/null +++ b/dep/ACE_wrappers/ace/ace_wchar.inl @@ -0,0 +1,183 @@ +// -*- C++ -*- +// +// $Id: ace_wchar.inl 80826 2008-03-04 14:51:23Z wotte $ + +// These are always inlined +// FUZZ: disable check_for_inline + +#if defined (ACE_HAS_WCHAR) + +#if !defined (ACE_WIN32) +# include /**/ // Need to see strlen() +#endif /* ACE_WIN32 */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +inline +ACE_Wide_To_Ascii::~ACE_Wide_To_Ascii (void) +{ + delete [] this->s_; +} + +inline char * +ACE_Wide_To_Ascii::char_rep (void) +{ + return this->s_; +} + +inline char * +ACE_Wide_To_Ascii::convert (const wchar_t *wstr) +{ + // Short circuit null pointer case + if (wstr == 0) + return 0; + +# if defined (ACE_WIN32) + UINT const cp = GetACP (); // Codepage + int const len = ::WideCharToMultiByte (cp, + 0, + wstr, + -1, + 0, + 0, + 0, + 0); +# elif defined (ACE_LACKS_WCSLEN) + const wchar_t * wtemp = wstr; + while ((*wtemp) != 0) // Hopefully the string is null terminated! + ++wtemp; + + int const len = wtemp - wstr + 1; +# else /* ACE_WIN32 */ + size_t const len = ::wcslen (wstr) + 1; +# endif /* ACE_WIN32 */ + +#if !defined (ACE_HAS_ICONV) + char *str = new char[len]; +#endif + +# if defined (ACE_WIN32) + ::WideCharToMultiByte (cp, 0, wstr, -1, str, len, 0, 0); +# elif defined (ACE_VXWORKS) + ::wcstombs (str, wstr, len); +# elif defined (ACE_HAS_ICONV) + wchar_t * wstri = const_cast (wstr); + size_t lensi = ACE_MAX_ICONV_BUFFER; + size_t lenwi = len * sizeof(wchar_t); + char buf[ACE_MAX_ICONV_BUFFER]; + char *stri = buf; + + size_t hr = iconv (ACE_Wide_To_Ascii_iconv_env, (char**)&wstri, &lenwi, &stri, &lensi); + if ((hr==size_t(-1))||(lensi==ACE_MAX_ICONV_BUFFER)) + { + char *str=new char[len]; + for (size_t i = 0; i < len; i++) + { + wchar_t *t = const_cast (wstr); + str[i] = static_cast (*(t + i)); + } + + return str; + } + char *str = new char[ACE_MAX_ICONV_BUFFER-lensi]; + ::memcpy(str, buf, ACE_MAX_ICONV_BUFFER-lensi); +# else /* ACE_HAS_ICONV */ + for (size_t i = 0; i < len; ++i) + { + wchar_t *t = const_cast (wstr); + str[i] = static_cast (*(t + i)); + } +# endif /* ACE_WIN32 */ + return str; +} + +inline +ACE_Wide_To_Ascii::ACE_Wide_To_Ascii (const wchar_t *s) +{ +#if defined(ACE_HAS_ICONV) + if (ACE_Wide_To_Ascii_iconv_env == 0) + { + ACE_Wide_To_Ascii_iconv_env = iconv_open("", "WCHAR_T"); + } +#endif + s_ = ACE_Wide_To_Ascii::convert (s); +} + +inline +ACE_Ascii_To_Wide::~ACE_Ascii_To_Wide (void) +{ + delete [] this->s_; +} + +inline wchar_t * +ACE_Ascii_To_Wide::wchar_rep (void) +{ + return this->s_; +} + +inline wchar_t * +ACE_Ascii_To_Wide::convert (const char *str) +{ + // Short circuit null pointer case + if (str == 0) + return 0; + +# if defined (ACE_WIN32) + UINT const cp = GetACP (); // Codepage + int const len = ::MultiByteToWideChar (cp, 0, str, -1, 0, 0); +# else /* ACE_WIN32 */ + size_t const len = strlen (str) + 1; +# endif /* ACE_WIN32 */ + +#if !defined (ACE_HAS_ICONV) + wchar_t *wstr = new wchar_t[len]; +#endif + +# if defined (ACE_WIN32) + ::MultiByteToWideChar (cp, 0, str, -1, wstr, len); +# elif defined (ACE_VXWORKS) + ::mbstowcs (wstr, str, len); +# elif defined (ACE_HAS_ICONV) /* ACE_VXWORKS */ + char *stri = const_cast(str); + size_t lensi = len; + size_t lenwi = ACE_MAX_ICONV_BUFFER; + wchar_t buf[ACE_MAX_ICONV_BUFFER/sizeof(wchar_t)]; + wchar_t *wstri=buf; + + size_t hr=iconv(ACE_Ascii_To_Wide_iconv_env, &stri, &lensi, (char**)&wstri, &lenwi); + if((hr==size_t(-1))||(lenwi==ACE_MAX_ICONV_BUFFER)){ + wchar_t *wstr=new wchar_t[len*sizeof(wchar_t)]; + for (size_t i = 0; i < len; i++){ + char *t = const_cast (str); + wstr[i] = static_cast (*((unsigned char*)t + i)); + } + + return wstr; + } + wchar_t *wstr=new wchar_t[(ACE_MAX_ICONV_BUFFER-lenwi)/sizeof(wchar_t)]; + ::memcpy(wstr,buf,ACE_MAX_ICONV_BUFFER-lenwi); +# else /* ACE_HAS_ICONV */ + for (size_t i = 0; i < len; ++i) + { + char *t = const_cast (str); + wstr[i] = static_cast (*((unsigned char*)(t + i))); + } +# endif /* ACE_WIN32 */ + return wstr; +} + +inline +ACE_Ascii_To_Wide::ACE_Ascii_To_Wide (const char *s) +{ +#if defined(ACE_HAS_ICONV) + if (ACE_Ascii_To_Wide_iconv_env == 0) + { + ACE_Ascii_To_Wide_iconv_env = iconv_open("WCHAR_T", ""); + } +#endif + s_ = ACE_Ascii_To_Wide::convert (s); +} + +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /* ACE_HAS_WCHAR */ diff --git a/dep/ACE_wrappers/ace/checked_iterator.h b/dep/ACE_wrappers/ace/checked_iterator.h new file mode 100644 index 000000000..7792fbb9e --- /dev/null +++ b/dep/ACE_wrappers/ace/checked_iterator.h @@ -0,0 +1,58 @@ +// -*- C++ -*- + +#ifndef ACE_CHECKED_ITERATOR_H +#define ACE_CHECKED_ITERATOR_H + +/** + * @file checked_iterator.h + * + * @brief Checked iterator factory function. + * + * Some compilers (e.g. MSVC++ >= 8) issue security related + * diagnostics if algorithms such as std::copy() are used in an unsafe + * way. Normally this isn't an issue if STL container iterators are + * used in conjuction with the standard algorithms. However, in cases + * where application-specific iterators are use with standard + * algorithms that could potentially overrun a buffer, extra care must + * be taken to prevent such an overrun. If supported, checked + * iterators can be used to address the potential destination buffer + * overrun. + * + * This header provides function templates that generate the + * appropriate checked iterator. In cases where checked iterators are + * not supported, the pointer passed to the function is returned + * instead. + * + * $Id: checked_iterator.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @internal The functions and types in this header are meant for + * internal use. They may change at any point between + * releases. + * + * @author Ossama Othman + */ + +# if defined (_MSC_VER) && (_MSC_FULL_VER >= 140050000) +// Checked iterators are currently only supported in MSVC++ 8 or better. +# include +# endif /* _MSC_VER >= 1400 */ + +# if defined (_MSC_VER) && (_MSC_FULL_VER >= 140050000) +template +stdext::checked_array_iterator +ACE_make_checked_array_iterator (PTR buf, size_t len) +{ + return stdext::checked_array_iterator (buf, len); +} +# else +template +PTR +ACE_make_checked_array_iterator (PTR buf, size_t /* len */) +{ + // Checked iterators are unsupported. Just return the pointer to + // the buffer itself. + return buf; +} +# endif /* _MSC_VER >= 1400 */ + +#endif /* ACE_CHECKED_ITERATOR_H */ diff --git a/dep/ACE_wrappers/ace/codecs.mpb b/dep/ACE_wrappers/ace/codecs.mpb new file mode 100644 index 000000000..03ecfef76 --- /dev/null +++ b/dep/ACE_wrappers/ace/codecs.mpb @@ -0,0 +1,8 @@ +// -*- MPC -*- +// $Id: codecs.mpb 80826 2008-03-04 14:51:23Z wotte $ + +feature(ace_codecs) { + Source_Files(ACE_COMPONENTS) { + Codecs.cpp + } +} diff --git a/dep/ACE_wrappers/ace/config-WinCE.h b/dep/ACE_wrappers/ace/config-WinCE.h new file mode 100644 index 000000000..f3b65a44c --- /dev/null +++ b/dep/ACE_wrappers/ace/config-WinCE.h @@ -0,0 +1,240 @@ +// $Id: config-WinCE.h 81693 2008-05-14 12:35:01Z johnnyw $ + +// Note: For WinCE build, simply use: #include "ace/config-win32.h" +// It is same as config.h for Windows NT/2k so that you can +// share same files and directories for both WinCE and NT/2k +// builds, unless you add additional definition(s) for each +// specific build or change the output directory. + +#ifndef ACE_CONFIG_WINCE_H +#define ACE_CONFIG_WINCE_H + +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +# error Use config-win32.h in config.h instead of this header +#endif // ACE_CONFIG_WIN32_H + +#if !defined (UNDER_CE) +# error Define UNDER_CE to version (i.e. 300 = 3.0) +#endif // UNDER_CE + +#if (UNDER_CE < 300) +# error ACE requires Windows CE 3.0 and later. +#endif // UNDER_CE + +#if (UNDER_CE < 400) +// CE 3 doesn't have Winsock 2, but CE 4 does. +# if !defined (ACE_HAS_WINSOCK2) +# define ACE_HAS_WINSOCK2 0 +# endif +# define ACE_LACKS_ASSERT_H +# define ACE_LACKS_SEARCH_H +# define ACE_LACKS_WCHAR_H +# define ACE_LACKS_WCTYPE_H +# define ACE_LACKS_STDDEF_H +# define ACE_LACKS_PTRDIFF_T +#endif /* UNDER_CE < 400 */ + +#if !defined (ACE_HAS_WINCE) +# define ACE_HAS_WINCE 1 +#endif + +#if defined (_MSC_VER) && (_MSC_VER < 1400) +// WinCE prior to Visual Studio 2005 integration doesn't have most of +// the standard C library time functions. It also doesn't define struct tm. +// SYSTEMTIME has pretty much the same info though, so we can map it when +// needed. Define struct tm here and use it when needed. This is taken +// from the standard C library. +# define ACE_LACKS_STRUCT_TM +#endif + +// We need these libraries to build: +#pragma comment(lib,"corelibc.lib") +#pragma comment(linker, "/nodefaultlib:oldnames.lib") + +// Only DLL version is supported on CE. +//#if defined (ACE_HAS_DLL) +//# undef ACE_HAS_DLL +//#endif // ACE_HAS_DLL +//#define ACE_HAS_DLL 1 + +// Need to define LD search path explicitly on CE because +// CE doesn't have environment variables and we can't get +// the information using getenv. +#define ACE_DEFAULT_LD_SEARCH_PATH ACE_TEXT (".\\;\\windows") + +#define ACE_LACKS_FCNTL_H +#define ACE_LACKS_SYS_TYPES_H +#define ACE_LACKS_GETCWD +#define ACE_LACKS_ASCTIME +#define ACE_LACKS_ASCTIME_R +#define ACE_LACKS_GMTIME +#define ACE_LACKS_GMTIME_R +#define ACE_LACKS_LOCALTIME +#define ACE_LACKS_PERROR +#define ACE_LACKS_STRFTIME +#define ACE_LACKS_WIN32_SETFILEPOINTEREX +#define ACE_LACKS_WIN32_SERVICES +#define ACE_LACKS_WIN32_SECURITY_DESCRIPTORS +#define ACE_LACKS_GETPROCESSTIMES +#define ACE_LACKS_PDH_H +#define ACE_LACKS_PDHMSG_H + +#define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1 + +#define ACE_LACKS_MSG_WFMO +#define ACE_LACKS_UMASK + +// WinCE only supports the UNICODE API +#if !defined (ACE_USES_WCHAR) +# define ACE_USES_WCHAR +#endif /* ACE_USES_WCHAR */ + +#define ACE_USES_WINCE_SEMA_SIMULATION + +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER 1 + +// FILE stuff isn't always defined in CE +#if (_MSC_VER < 1400) && !defined (_FILE_DEFINED) + typedef void FILE; +# define _FILE_DEFINED +#endif /* _MSC_VER < 1400 && !_FILE_DEFINED */ + +// This was defined in previous versions of CE, but not 2.11 +#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION + +#define ACE_MAIN WINAPI WinMain + +// SH3 cross-compiler can't handle inline functions correctly +// (along with other bugs.) +#if defined (SH3) +# define ACE_LACKS_INLINE_FUNCTIONS +#endif // SH3 && _DEBUG + +#ifndef ACE_DEFAULT_SERVER_HOST +# define ACE_DEFAULT_SERVER_HOST ACE_TEXT("localhost") +#endif // ACE_DEFAULT_SERVER_HOST + +// @@ Need to remap every function that uses any of these flags to +// Win32 API. These are for ANSI styled function and are not +// available on WinCE. + +#define _O_RDONLY 0x0000 // open for reading only +#define _O_WRONLY 0x0001 // open for writing only +#define _O_RDWR 0x0002 // open for reading and writing +#define _O_APPEND 0x0008 // writes done at eof + +#define _O_CREAT 0x0100 // create and open file +#define _O_TRUNC 0x0200 // open and truncate +#define _O_EXCL 0x0400 // open only if file doesn't already exist + +// O_TEXT files have sequences translated to on read()'s, +// and sequences translated to on write()'s +#define _O_TEXT 0x4000 // file mode is text (translated) +#define _O_BINARY 0x8000 // file mode is binary (untranslated) + +// macro to translate the C 2.0 name used to force binary mode for files +//#define _O_RAW _O_BINARY + +// Open handle inherit bit +//#define _O_NOINHERIT 0x0080 // child process doesn't inherit file + +// Temporary file bit - file is deleted when last handle is closed +#define _O_TEMPORARY 0x0040 // temporary file bit + +// temporary access hint +//#define _O_SHORT_LIVED 0x1000 // temporary storage file, try not to flush + +// sequential/random access hints +//#define _O_SEQUENTIAL 0x0020 // file access is primarily sequential +//#define _O_RANDOM 0x0010 // file access is primarily random + + +// Non-ANSI names +#define O_RDONLY _O_RDONLY +#define O_WRONLY _O_WRONLY +#define O_RDWR _O_RDWR +#define O_APPEND _O_APPEND +#define O_CREAT _O_CREAT +#define O_TRUNC _O_TRUNC +#define O_EXCL _O_EXCL +#define O_TEXT _O_TEXT +#define O_BINARY _O_BINARY +#define O_TEMPORARY _O_TEMPORARY +//#define O_RAW _O_BINARY +//#define O_NOINHERIT _O_NOINHERIT +//#define O_SEQUENTIAL _O_SEQUENTIAL +//#define O_RANDOM _O_RANDOM + + +// @@ NSIG value. This is definitely not correct. +#define NSIG 23 + + +// @@ For some reason, WinCE forgot to define this. +// Need to find out what it is. (Used in MapViewOfFile ().) +#define FILE_MAP_COPY 0 + + +#define ACE_LACKS_STRCASECMP // WinCE doesn't support _stricmp +#define ACE_LACKS_GETSERVBYNAME +#define ACE_LACKS_ACCESS +#define ACE_LACKS_FILELOCKS +#define ACE_LACKS_EXEC +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_STRRCHR +#define ACE_LACKS_BSEARCH +#define ACE_LACKS_SOCKET_BUFSIZ +#define ACE_LACKS_ISATTY +#define ACE_LACKS_STRERROR +#define ACE_LACKS_SYSTEM +#define ACE_LACKS_SIGACTION +#define ACE_LACKS_PIPE + +//#define ACE_LACKS_CUSERID +//#define ACE_LACKS_CHDIR +#define ACE_LACKS_ENV +#define ACE_LACKS_HOSTNAME +#define ACE_LACKS_REALPATH +#define ACE_LACKS_READLINK +#define ACE_LACKS_SWAB +#define ACE_LACKS_TEMPNAM +#define ACE_LACKS_GETPROTOBYNUMBER +#define ACE_LACKS_GETPROTOBYNAME + +#if defined (_WIN32_WCE_EMULATION) +// @@ For some reason, qsort isn't defined correctly (_stdcall vs _cdecl) +// under emulation. So for right now, exclude it. +# define ACE_LACKS_QSORT +#endif // _WIN32_WCE_EMULATION + +#if !defined (BUFSIZ) +# define BUFSIZ 1024 +#endif + +typedef void (__cdecl * __sighandler_t)(int); // keep Signal compilation happy +typedef long off_t; + +#define ACE_LACKS_MALLOC_H // We do have malloc.h, but don't use it. + +#define ACE_HAS_WINCE_BROKEN_ERRNO + +#define ACE_HAS_STRDUP_EMULATION + +// WinCE can't do fixed addresses for memory-mapped files. +#if defined (ACE_DEFAULT_BASE_ADDR) +# undef ACE_DEFAULT_BASE_ADDR +#endif +#define ACE_DEFAULT_BASE_ADDR 0 + +#define ACE_HAS_TSS_EMULATION + +// This is still true up thru VC8... +#define ACE_LACKS_ERRNO_H +#define ACE_LACKS_SIGNAL_H +#define ACE_LACKS_SYS_STAT_H + +#include /**/ "ace/post.h" + +#endif // ACE_CONFIG_WINCE_H diff --git a/dep/ACE_wrappers/ace/config-aix-5.x.h b/dep/ACE_wrappers/ace/config-aix-5.x.h new file mode 100644 index 000000000..30507a05f --- /dev/null +++ b/dep/ACE_wrappers/ace/config-aix-5.x.h @@ -0,0 +1,333 @@ +// $Id: config-aix-5.x.h 80826 2008-03-04 14:51:23Z wotte $ +// +// Config file for AIX 5.1 and higher. + +#ifndef ACE_CONFIG_AIX_5_X_H +#define ACE_CONFIG_AIX_5_X_H + +// This define is needed for building with Visual Age C++ 5 in incremental +// mode. In the batch mode build, platform_aix_ibm.GNU sets it. The incremental +// mode compiler won't be supported after ACE 5.3, so this will also go away +// in that timeframe, so don't worry about future AIX versions. +#if !defined (ACE_AIX_VERS) +# define ACE_AIX_VERS 501 +#endif + +// AIX 5.1 has AIO, but it doesn't have the same API as other POSIX +// systems, and the semantics of operations are a bit different. Will take +// some real work to get this going. +// AIX 5.2, however, has the POSIX API implemented. However, the libc functions +// to implement it aren't exported by default. You need to use smit to enable +// them. So, leave AIO disabled unless the user explicitly enables it. +// config-aix-4.x.h will set ACE_HAS_AIO_CALLS if config-posix.h senses the +// feature-test macros, so set up _ACE_DISABLE_AIO_CALLS_ if the user didn't +// set it. Then check for it after including config-aix-4.x.h and remove +// ACE_HAS_AIO_CALLS if so. +#if !defined (ACE_HAS_AIO_CALLS) +# define _ACE_DISABLE_AIO_CALLS_ +#endif + +// Both IBM and g++ compilers set _THREAD_SAFE if compiler is asked to compile +// threaded code (xlC_r, as opposed to xlC; and g++ -pthread) +#if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0) +# if defined (ACE_HAS_THREADS) +# undef ACE_HAS_THREADS +# endif +# if defined (_THREAD_SAFE) +# define ACE_HAS_THREADS 1 +// # else +// # define ACE_HAS_THREADS 0 +# endif /* _THREAD_SAFE */ +#endif /* !ACE_MT_SAFE || (ACE_MT_SAFE != 0) */ + +#if defined (__xlC__) || defined (__IBMCPP__) + // AIX xlC, IBM C/C++, and Visual Age C++ compilers + //******************************************************************** + // + +// Compiler does this with a builtin - it's not in libc. +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//# define ACE_HAS_ALLOCA + +// Compiler supports the ssize_t typedef. +# define ACE_HAS_SSIZE_T + + // Keep an eye on this as the compiler and standards converge... +# define ACE_LACKS_LINEBUFFERED_STREAMBUF +# define ACE_LACKS_PRAGMA_ONCE + + // C Set++ 3.1, IBM C/C++ 3.6, and Visual Age C++ 5 batch (__xlC__) +# if defined (__xlC__) +# if (__xlC__ < 0x0500) +# define ACE_LACKS_PLACEMENT_OPERATOR_DELETE +# endif /* __xlC__ < 0x0500 */ +# endif + + // These are for Visual Age C++ only +# if defined (__IBMCPP__) && (__IBMCPP__ >= 600) +# define ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS + // When using -qtempinc, we don't need to see template implementation + // source (though we do need a pragma to find the correct source file). + // However, without -qtempinc (either -qnotempinc or -qtemplateregistry) + // we do need to see the source. +# if defined (__TEMPINC__) +# if !defined ACE_TEMPLATES_REQUIRE_PRAGMA +# define ACE_TEMPLATES_REQUIRE_PRAGMA +# endif +# else +# if !defined (ACE_TEMPLATES_REQUIRE_SOURCE) +# define ACE_TEMPLATES_REQUIRE_SOURCE +# endif +# endif /* __TEMPINC__ */ + +# undef WIFEXITED +# undef WEXITSTATUS +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 + +# if (__IBMCPP__ >= 600) /* Visual Age 6 and XL C/C++ 7 and up */ +# define ACE_HAS_TEMPLATE_TYPEDEFS +# define ACE_HAS_CUSTOM_EXPORT_MACROS +# define ACE_Proper_Export_Flag +# define ACE_Proper_Import_Flag +# define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) extern template class SINGLETON_TYPE < CLASS, LOCK >; +# endif /* __IBMCPP__ >= 600 */ +# endif /* __IBMCPP__ */ + +#elif defined (__GNUG__) + // config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so + // this must appear before its #include. +# define ACE_HAS_STRING_CLASS + +# include "ace/config-g++-common.h" + // Denotes that GNU has cstring.h as standard, to redefine memchr(). +# define ACE_HAS_GNU_CSTRING_H +# define ACE_HAS_SSIZE_T + +# if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)) +// We have to explicitly instantiate static template members prior to g++ 4.1 +# define ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION +#endif /* g++ prior to 4.1 */ + +# if !defined (ACE_MT_SAFE) || ACE_MT_SAFE != 0 + // ACE_MT_SAFE is #defined below, for all compilers. +# if !defined (_REENTRANT) +# define _REENTRANT +# endif /* _REENTRANT */ +# endif /* !ACE_MT_SAFE */ + +#else /* ! __xlC__ && ! __GNUG__ */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler in ace/config-aix-5.x.h +# endif /* __cplusplus */ +#endif /* ! __xlC__ && ! __GNUG__ */ + +// Compiling for AIX. +#ifndef AIX +# define AIX +#endif /* AIX */ + +// Pick up all the detectable settings. +#include "ace/config-posix.h" + +// Regardless of what config-posix.h may indicate, AIX 5.3 is the first +// to support sem_timedwait(). Prior to that, use the emulation. +#if defined (ACE_HAS_POSIX_SEM_TIMEOUT) && \ + (defined (ACE_AIX_VERS) && (ACE_AIX_VERS < 503)) +# undef ACE_HAS_POSIX_SEM_TIMEOUT +#endif /* ACE_HAS_POSIX_SEM_TIMEOUT && ACE_AIX_VERS < 503 */ + +#if defined (ACE_DLL_SUFFIX) +# undef ACE_DLL_SUFFIX +#endif +#define ACE_DLL_SUFFIX ".so" + +#define ACE_DEFAULT_BASE_ADDR ((char *) 0x80000000) + +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + +#define ACE_HAS_SOCKLEN_T +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG + +// AIX has AIO, but the functions don't match those of other AIO-enabled +// platforms. If this is to work, it'll require some significant work, +// maybe moving the OS-abstraction stuff to an OS_AIO or some such thing. +//# define ACE_HAS_AIO_CALLS + +#define ACE_HAS_AIX_HI_RES_TIMER + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// OS has readdir and friends. +#define ACE_HAS_DIRENT + +// OS supports the getrusage() system call +#define ACE_HAS_GETRUSAGE + +#define ACE_HAS_GPERF + +#define ACE_HAS_H_ERRNO + +#define ACE_LACKS_STDINT_H +#define ACE_LACKS_SYS_SYSCTL_H + +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_IP_MULTICAST + +// Lacks perfect filtering, must bind group address. +#if !defined ACE_LACKS_PERFECT_MULTICAST_FILTERING +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING */ + +#define ACE_HAS_MSG + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +#define ACE_HAS_POSIX_TIME +// ... but needs to include another header for it on 4.2+ +# define ACE_HAS_BROKEN_POSIX_TIME +// ... and needs another typedef +#define ACE_LACKS_TIMESPEC_T +#define ACE_HAS_SELECT_H + +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_HAS_P_READ_WRITE + +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_STRBUF_T + +// Compiler supports stropts.h +#define ACE_HAS_STREAMS +// #define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// AIX bzero() +#define ACE_HAS_STRINGS + +#define ACE_HAS_STRUCT_NETDB_DATA + +// Dynamic linking is in good shape on newer OS/patch levels. If you have +// trouble with the dynamic linking parts of ACE, and can't patch your OS +// up to latest levels, comment this out. +#define ACE_HAS_SVR4_DYNAMIC_LINKING +// This is tightly related to dynamic linking... +#define ACE_HAS_AUTOMATIC_INIT_FINI + +#define ACE_HAS_SVR4_GETTIMEOFDAY + +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_TIMOD_H +#define ACE_HAS_XTI +#define ACE_HAS_BROKEN_T_ERROR +#define ACE_TLI_TCP_DEVICE "/dev/xti/tcp" + +#define ACE_HAS_UALARM + +#define ACE_HAS_UCONTEXT_T + +#define ACE_HAS_UTIME + +// Platform has XPG4 wide character type and functions. However, the size +// of wchar_t changes for 32- vs. 64-bit builds (unsigned short vs. unsigned +// int, respectively). +#define ACE_HAS_XPG4_MULTIBYTE_CHAR +#ifdef __64BIT__ +# define ACE_SIZEOF_WCHAR 4 +#else +# define ACE_SIZEOF_WCHAR 2 +#endif /* __64BIT__ */ + +#define ACE_LACKS_NETINET_TCP_H + +// AIX uses LIBPATH to search for libraries +#define ACE_LD_SEARCH_PATH "LIBPATH" + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +//************************************************************** +// +// Threads related definitions. +// +// The threads on AIX are generally POSIX P1003.1c (ACE_HAS_PTHREADS). +// However, there is also a kernel thread ID (tid_t) that is used in +// ACE_Log_Msg (printing the thread ID). The tid_t is not the same as +// pthread_t, and can't derive one from the other - thread_self() gets +// the tid_t (kernel thread ID) if called from a thread. +// Thanks very much to Chris Lahey for straightening this out. + +#if defined (ACE_HAS_THREADS) +# if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +# endif + +# define ACE_HAS_PTHREADS +# define ACE_HAS_PTHREADS_UNIX98_EXT +# define ACE_HAS_PTHREAD_CONTINUE_NP +# define ACE_HAS_PTHREAD_SUSPEND_NP +# define ACE_HAS_RECURSIVE_MUTEXES +# define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +# define ACE_HAS_SIGTHREADMASK +# define ACE_HAS_THREAD_SPECIFIC_STORAGE + +# define ACE_LACKS_THREAD_PROCESS_SCOPING +#else +# undef ACE_HAS_THREADS +#endif /* ACE_HAS_THREADS != 0 */ + +#define ACE_MALLOC_ALIGN 8 + +#if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) && !defined(_UNIX95) +# define ACE_HAS_3_PARAM_WCSTOK +#endif /* (_XOPEN_SOURCE -0) >= 500 && !_UNIX95 */ + +#if defined (_ACE_DISABLE_AIO_CALLS_) +# if defined (ACE_HAS_AIO_CALLS) +# undef ACE_HAS_AIO_CALLS +# endif +# undef _ACE_DISABLE_AIO_CALLS_ +#endif + +// AIX's /usr/include/unistd.h sets _POSIX_SEMAPHORE to indicate the system +// supplies such a facility, but the headers don't enable it unless +// _XOPEN_SOURCE >= 500. So disable semaphores here if _XOPEN_SOURCE isn't +// up to snuff. +#if defined (ACE_HAS_POSIX_SEM) && \ + (!defined (_XOPEN_SOURCE) || (_XOPEN_SOURCE-0 < 500)) +# undef ACE_HAS_POSIX_SEM +#endif + +// I think this is correct, but needs to be verified... -Steve Huston +#define ACE_HAS_SIGTIMEDWAIT + +// AIX 5.1 has netinet/tcp.h +#undef ACE_LACKS_NETINET_TCP_H + +#define ACE_HAS_3_PARAM_READDIR_R +#define ACE_HAS_POSIX_GETPWNAM_R +#define ACE_HAS_SCANDIR +#define ACE_SCANDIR_CMP_USES_VOIDPTR +#define ACE_SCANDIR_SEL_LACKS_CONST +#define ACE_HAS_SIGSUSPEND +#define ACE_HAS_TIMEZONE /* Call tzset() to set timezone */ + +#endif /* ACE_CONFIG_AIX_5_X_H */ diff --git a/dep/ACE_wrappers/ace/config-all.h b/dep/ACE_wrappers/ace/config-all.h new file mode 100644 index 000000000..2a57a7ee3 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-all.h @@ -0,0 +1,89 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file config-all.h + * + * $Id: config-all.h 81661 2008-05-09 12:05:34Z johnnyw $ + * + * @author (Originally in OS.h)Doug Schmidt + * @author Jesper S. M|ller + * @author and a cast of thousands... + */ +//========================================================================== + +#ifndef ACE_CONFIG_ALL_H +#define ACE_CONFIG_ALL_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// This is used to indicate that a platform doesn't support a +// particular feature. +#if defined ACE_HAS_VERBOSE_NOTSUP + // Print a console message with the file and line number of the + // unsupported function. +# include "ace/OS_NS_stdio.h" +# define ACE_NOTSUP_RETURN(FAILVALUE) do { errno = ENOTSUP; ACE_OS::fprintf (stderr, ACE_TEXT ("ACE_NOTSUP: %s, line %d\n"), __FILE__, __LINE__); return FAILVALUE; } while (0) +# define ACE_NOTSUP do { errno = ENOTSUP; ACE_OS::fprintf (stderr, ACE_TEXT ("ACE_NOTSUP: %s, line %d\n"), __FILE__, __LINE__); return; } while (0) +#else /* ! ACE_HAS_VERBOSE_NOTSUP */ +# define ACE_NOTSUP_RETURN(FAILVALUE) do { errno = ENOTSUP ; return FAILVALUE; } while (0) +# define ACE_NOTSUP do { errno = ENOTSUP; return; } while (0) +#endif /* ! ACE_HAS_VERBOSE_NOTSUP */ + +// ---------------------------------------------------------------- + +# define ACE_TRACE_IMPL(X) ACE_Trace ____ (ACE_TEXT (X), __LINE__, ACE_TEXT (__FILE__)) + +// By default tracing is turned off. +#if !defined (ACE_NTRACE) +# define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#if (ACE_NTRACE == 1) +# define ACE_TRACE(X) +#else +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define ACE_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* ACE_NTRACE */ + +// By default we perform no tracing on the OS layer, otherwise the +// coupling between the OS layer and Log_Msg is too tight. But the +// application can override the default if they wish to. +#if !defined (ACE_OS_NTRACE) +# define ACE_OS_NTRACE 1 +#endif /* ACE_OS_NTRACE */ + +#if (ACE_OS_NTRACE == 1) +# define ACE_OS_TRACE(X) +#else +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define ACE_OS_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* ACE_OS_NTRACE */ + +#if !defined (ACE_HAS_MONITOR_FRAMEWORK) +# define ACE_HAS_MONITOR_FRAMEWORK 1 +#endif + +#if !defined (ACE_HAS_MONITOR_POINTS) +# define ACE_HAS_MONITOR_POINTS 0 +#endif + +// These includes are here to avoid circular dependencies. +// Keep this at the bottom of the file. It contains the main macros. +#include "ace/OS_main.h" + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_ALL_H */ diff --git a/dep/ACE_wrappers/ace/config-borland-common.h b/dep/ACE_wrappers/ace/config-borland-common.h new file mode 100644 index 000000000..c57ddb07f --- /dev/null +++ b/dep/ACE_wrappers/ace/config-borland-common.h @@ -0,0 +1,66 @@ +// -*- C++ -*- +//$Id: config-borland-common.h 82294 2008-07-12 13:03:37Z johnnyw $ + +// The following configuration file contains defines for Borland compilers. + +#ifndef ACE_CONFIG_BORLAND_COMMON_H +#define ACE_CONFIG_BORLAND_COMMON_H +#include /**/ "ace/pre.h" + +#define ACE_HAS_CUSTOM_EXPORT_MACROS +#define ACE_Proper_Export_Flag __declspec (dllexport) +#define ACE_Proper_Import_Flag __declspec (dllimport) +#define ACE_EXPORT_SINGLETON_DECLARATION(T) template class __declspec (dllexport) T +#define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class __declspec (dllexport) SINGLETON_TYPE; +#define ACE_IMPORT_SINGLETON_DECLARATION(T) template class __declspec (dllimport) T +#define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class __declspec (dllimport) SINGLETON_TYPE ; + +// In later versions of C++Builder we will prefer inline functions by +// default. The debug configuration of ACE is built with functions +// out-of-line, so when linking your application against a debug ACE +// build, you can choose to use the out-of-line functions by adding +// ACE_NO_INLINE=1 to your project settings. +# if !defined (__ACE_INLINE__) +# define __ACE_INLINE__ 1 +# endif /* __ACE_INLINE__ */ + +# define ACE_CC_NAME ACE_TEXT ("Borland C++ Builder") +# define ACE_CC_MAJOR_VERSION (__BORLANDC__ / 0x100) +# define ACE_CC_MINOR_VERSION (__BORLANDC__ % 0x100) +# define ACE_CC_BETA_VERSION (0) + +# ifndef ACE_USING_MCPP_PREPROCESSOR +# define ACE_CC_PREPROCESSOR_ARGS "-q -P- -o%s" +# endif + +# define ACE_EXPORT_NESTED_CLASSES 1 +# define ACE_HAS_CPLUSPLUS_HEADERS 1 +# define ACE_HAS_EXCEPTIONS +# define ACE_HAS_GNU_CSTRING_H 1 +# define ACE_HAS_NONCONST_SELECT_TIMEVAL +# define ACE_HAS_SIG_ATOMIC_T +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_HAS_STDCPP_STL_INCLUDES 1 +# define ACE_HAS_STRERROR +# define ACE_HAS_STRING_CLASS 1 +# define ACE_HAS_TEMPLATE_TYPEDEFS 1 +# define ACE_HAS_USER_MODE_MASKS 1 +# define ACE_LACKS_ACE_IOSTREAM 1 +# define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 +# define ACE_LACKS_STRPTIME 1 +# if (__BORLANDC__ < 0x590) +# define ACE_LACKS_PLACEMENT_OPERATOR_DELETE 1 +# endif +# define ACE_LACKS_PRAGMA_ONCE 1 +# define ACE_HAS_NEW_NOTHROW +# define ACE_TEMPLATES_REQUIRE_SOURCE 1 +# define ACE_SIZEOF_LONG_DOUBLE 10 +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%Lu") +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%Ld") +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDC_LIB 0 +# define ACE_ENDTHREADEX(STATUS) ::_endthreadex ((DWORD) STATUS) +# define ACE_LACKS_SWAB + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_BORLAND_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-cray.h b/dep/ACE_wrappers/ace/config-cray.h new file mode 100644 index 000000000..28038b15b --- /dev/null +++ b/dep/ACE_wrappers/ace/config-cray.h @@ -0,0 +1,213 @@ +/* -*- C++ -*- */ +// $Id: config-cray.h 81935 2008-06-12 22:01:53Z jtc $ + +#ifndef ACE_CONFIG_CRAY_H +#define ACE_CONFIG_CRAY_H +#include /**/ "ace/pre.h" + +/* + The following predefined macros are used within ACE ifdefs. + These are defined when using the Cray compilers. _CRAYMPP + is defined, for example, if you are running on a Cray T3E + massively parallel machine. Moreover, in the case of the T3E, + _CRAYT3E will be defined. This is used to determine the + ACE_SIZEOF defines for primitive types. + + _UNICOS is defined as either the major version of UNICOS being run, + e.g. 9 or 10 on the vector machines (e.g. C90, T90, J90, YMP, ...) + or the major+minor+level UNICOS/mk version, e.g. 2.0.3 => 203, + being run on an MPP machine. + + Summary: + + _CRAYMPP (defined only if running on MPP machine, e.g. T3E, UNICOS/mk) + _CRAYT3E (defined specifically if compiling on a Cray T3E) + _UNICOS (defined if running UNICOS or UNICOS/mk) + + Tested on UNICOS 10.0.0.5, UNICOS/mk 2.0.4.57 + Compiles on UNICOS 9.0.2.8, but some tests deadlock + + Contributed by Doug Anderson +*/ + +#if defined (_UNICOS) && !defined (MAXPATHLEN) +#define MAXPATHLEN 1023 +#endif /* _UNICOS */ + +#define ACE_DEFAULT_CLOSE_ALL_HANDLES 0 + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#define ACE_HAS_CPLUSPLUS_HEADERS + +#define ACE_HAS_SSIZE_T + +#define ACE_HAS_SYSV_IPC + +#define ACE_MT_SAFE 1 + +#define ACE_HAS_THREADS + +#define ACE_HAS_PTHREADS + +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +#define ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP + +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + +#define ACE_HAS_POSIX_TIME + +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +#define ACE_HAS_POSIX_NONBLOCK + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#define ACE_HAS_DIRENT + +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +#define ACE_HAS_IP_MULTICAST + +#define ACE_HAS_SOCKADDR_IN_SIN_LEN + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +#define ACE_HAS_NONCONST_READLINK + +#define ACE_HAS_CHARPTR_SOCKOPT + +#define ACE_HAS_NONCONST_GETBY + +// has man pages, but links with missing symbols and I can't find lib yet +/* #define ACE_HAS_REGEX */ + +#define ACE_HAS_SIG_MACROS + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +#if _UNICOS > 9 +# define ACE_HAS_SIGWAIT +#endif + +#define ACE_HAS_SIG_ATOMIC_T + +#define ACE_HAS_SIGISMEMBER_BUG + +#define ACE_HAS_MSG + +#define ACE_HAS_STRERROR + +#define ACE_HAS_GPERF + +// Special modifications that apply to UNICOS/mk +#if defined(_CRAYMPP) + +# define ACE_HAS_SIGINFO_T +# define ACE_HAS_UCONTEXT_T + +#endif + +// The Cray T90 supposedly supports SYSV SHMEM, but I was unable to get it +// working. Of course, all other Cray PVP and MPP systems do NOT support it, +// so it's probably good to just define like this for consistency +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_MMAP +#define ACE_LACKS_CONST_TIMESPEC_PTR +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_MADVISE +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_PTHREAD_CLEANUP +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +#if !defined(_CRAYMPP) + +#define ACE_LACKS_PTHREAD_CANCEL +#define ACE_LACKS_PTHREAD_KILL + +#endif + +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_PRI_T +#define ACE_LACKS_GETPGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_MPROTECT +#define ACE_LACKS_MSYNC +#define ACE_LACKS_READV +#define ACE_LACKS_RLIMIT + +// we probably want to fake not having this, since Cray memory mgmt is different +#define ACE_LACKS_SBRK + +#define ACE_LACKS_SETSCHED + +#define ACE_LACKS_SIGINFO_H + +#define ACE_LACKS_TIMESPEC_T + +#define ACE_LACKS_WRITEV + +// Cray vector machines are "word" oriented, and modern ones are hard 64-bit. +// "char" is somewhat of a special case. Most problems arise when code thinks +// it can address 32-bit quantities and the like. MPP crays are typically +// byte oriented, e.g. T3E uses Alpha processors, so we don't need as much +// special treatment. + +#ifndef _CRAYMPP + +# define ACE_SIZEOF_CHAR 1 +# define ACE_SIZEOF_SHORT 8 +# define ACE_SIZEOF_INT 8 +# define ACE_SIZEOF_LONG 8 +# define ACE_SIZEOF_LONG_LONG 8 +# define ACE_SIZEOF_FLOAT 8 +# define ACE_SIZEOF_DOUBLE 8 +# define ACE_SIZEOF_LONG_DOUBLE 16 +# define ACE_SIZEOF_VOID_P 8 + +#elif defined(_CRAYT3E) + +# define ACE_SIZEOF_CHAR 1 +# define ACE_SIZEOF_SHORT 4 +# define ACE_SIZEOF_INT 8 +# define ACE_SIZEOF_LONG 8 +# define ACE_SIZEOF_LONG_LONG 8 +# define ACE_SIZEOF_FLOAT 4 +# define ACE_SIZEOF_DOUBLE 8 +# define ACE_SIZEOF_LONG_DOUBLE 8 +# define ACE_SIZEOF_VOID_P 8 + +#endif + +// Ones to check out at some point + +/* #define ACE_HAS_SYS_SIGLIST */ + +// C++ Compiler stuff to verify +/* #define ACE_NEW_THROWS_EXCEPTIONS */ +/* #define ACE_HAS_TEMPLATE_TYPEDEFS */ + +// thread issues to check out +/* #define ACE_LACKS_TIMEDWAIT_PROTOTYPES */ + +// Cray does seem to support it, in -lnsl and has tiuser.h header +/* #define ACE_HAS_TLI */ +/* #define ACE_HAS_TIUSER_H */ +/* #define ACE_HAS_TLI_PROTOTYPES */ +/* #define ACE_LACKS_T_ERRNO */ + +/* #define ACE_LACKS_NAMED_POSIX_SEM */ + +/* #define ACE_HAS_SYS_ERRLIST */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_CRAY_H */ diff --git a/dep/ACE_wrappers/ace/config-cxx-common.h b/dep/ACE_wrappers/ace/config-cxx-common.h new file mode 100644 index 000000000..024c25fd2 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-cxx-common.h @@ -0,0 +1,86 @@ +// -*- C++ -*- +// +// $Id: config-cxx-common.h 81935 2008-06-12 22:01:53Z jtc $ + +#ifndef ACE_CXX_COMMON_H +#define ACE_CXX_COMMON_H +#include /**/ "ace/pre.h" + +#if !defined (ACE_CONFIG_INCLUDE_CXX_COMMON) +# error ace/config-cxx-common.h: ACE configuration error! Do not #include this file directly! +#endif + +#if defined (__DECCXX) +# if !defined (linux) +# define ACE_HAS_STRING_CLASS +# if (__DECCXX_VER >= 60090010) +# define ACE_HAS_STDCPP_STL_INCLUDES +# endif /* __DECCXX_VER < 60090010 */ +# endif /* ! linux */ + +# define DEC_CXX +# define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR +# define ACE_LACKS_LINEBUFFERED_STREAMBUF +# define ACE_LACKS_SIGNED_CHAR +# define ACE_HAS_CPLUSPLUS_HEADERS +# define ACE_TEMPLATES_REQUIRE_SOURCE +# if (__DECCXX_VER >= 60090010) + // DEC CXX 6.0 supports exceptions, etc., by default. Exceptions + // are enabled by platform_osf1_4.x.GNU/wrapper_macros.GNU. +# if defined (ACE_HAS_EXCEPTIONS) +# define ACE_NEW_THROWS_EXCEPTIONS +# endif /* ACE_HAS_EXCEPTIONS */ +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_HAS_TEMPLATE_TYPEDEFS + +# define ACE_ENDLESS_LOOP \ + unsigned int ace_endless_loop____ = 0; if (ace_endless_loop____) break; + +# if defined (__USE_STD_IOSTREAM) +# define ACE_LACKS_CHAR_RIGHT_SHIFTS +# define ACE_LACKS_IOSTREAM_FX +# define ACE_LACKS_UNBUFFERED_STREAMBUF +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# else /* ! __USE_STD_IOSTREAM */ +# define ACE_USES_OLD_IOSTREAMS +# endif /* ! __USE_STD_IOSTREAM */ + +// 9: nested comment not allowed. (/usr/include/pdsc.h!) (nestcomment) +// 177: variable was declared but never referenced (declbutnotref) +// 193: zero used for undefined preprocessing identifier (undpreid) +// 236: controlling expression is constant (boolexprconst) +// 401: base_class_with_nonvirtual_dtor (basclsnondto) +// 1016: expected type is incompatible with declared type of int (incint) +// 1136: conversion to smaller size integer could lose data (intconlosbit) + +# pragma message disable basclsnondto +# pragma message disable boolexprconst +# pragma message disable undpreid +# pragma message disable notusetmpfunprm +# pragma message disable bltinclnk + +# if (__DECCXX_VER >= 60190029) + // 6.1-029 and later support msg 1136. Disable it because it + // causes warnings from ACE and/or TAO. +# pragma message disable intconlosbit +# endif /* __DECCXX_VER >= 60190029 */ + +# if (__DECCXX_VER == 60190027) + // Seems that this version of cxx doesn't have reset +# define ACE_AUTO_PTR_LACKS_RESET +# endif /* __DECCXX_VER == 60190027 */ + +# if defined (DIGITAL_UNIX) && DIGITAL_UNIX >= 0x40D + // variable "PTHREAD_THIS_CATCH_NP" was declared but never referenced +# pragma message disable declbutnotref +# endif /* DIGITAL_UNIX >= 4.0f */ + +# else /* __DECCXX_VER < 60090010 */ +# define ACE_LACKS_PRAGMA_ONCE +# endif /* __DECCXX_VER < 60090010 */ +#else /* ! __DECCXX */ +# error ace/config-cxx-common.h can only be used with Compaq CXX! +#endif /* ! __DECCXX */ + +#include /**/ "ace/post.h" +#endif /* ACE_CXX_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-cygwin32.h b/dep/ACE_wrappers/ace/config-cygwin32.h new file mode 100644 index 000000000..3dde02798 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-cygwin32.h @@ -0,0 +1,206 @@ +/* -*- C++ -*- */ +// $Id: config-cygwin32.h 81809 2008-05-30 13:40:21Z vzykov $ + +// The following configuration file is designed to work for CygWin +// platforms using GNU C++. + +#ifndef ACE_CONFIG_CYGWIN32_H +#define ACE_CONFIG_CYGWIN32_H + +#include /**/ "ace/pre.h" + +#if !defined (ACE_MT_SAFE) +#define ACE_MT_SAFE 1 +#endif + +#define CYGWIN32 + +// We trust this file will get included before +#if !defined(FD_SETSIZE) +# define FD_SETSIZE 1024 +#endif + +#if !defined (ACE_IOV_MAX) +# define ACE_IOV_MAX 64 +#endif /* ACE_IOV_MAX */ + +// Define custom export macros for export/import of symbols from/of dll's +#define ACE_HAS_CUSTOM_EXPORT_MACROS +#define ACE_Proper_Export_Flag __declspec (dllexport) +#define ACE_Proper_Import_Flag __declspec (dllimport) +#define ACE_EXPORT_SINGLETON_DECLARATION(T) template class __declspec (dllexport) T +#define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class __declspec (dllexport) SINGLETON_TYPE; +#define ACE_IMPORT_SINGLETON_DECLARATION(T) extern template class T +#define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) extern template class SINGLETON_TYPE ; + +#define ACE_HAS_SELECT_H + +#define ACE_LACKS_PRAGMA_ONCE + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#include /**/ + +// Needed to differentiate between libc 5 and libc 6 (aka glibc). +// It's there on all libc 5 systems I checked. +#include /**/ + +// config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so +// this must appear before its #include. +#define ACE_HAS_STRING_CLASS + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#else +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler in ace/config-cygwin32.h +# endif /* __cplusplus */ +#endif /* __GNUG__ */ + +#define ACE_HAS_VOIDPTR_SOCKOPT 1 +#define ACE_HAS_UALARM 1 +#define ACE_HAS_SYS_ERRLIST 1 +#define ACE_HAS_STRNLEN 1 +#define ACE_HAS_POSIX_GETPWNAM_R 1 +#define ACE_HAS_POSIX_NONBLOCK 1 +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_CLOCK_GETTIME 1 +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_HAS_MSG +#define ACE_DEFAULT_BASE_ADDR ((char *) 0x8000000) +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_SVR4_DYNAMIC_LINKING +//#define ACE_HAS_SYSV_IPC +#define ACE_HAS_VOIDPTR_MMAP +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_POLL +#define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1 +#define ACE_HAS_SOCKADDR_MSG_NAME 1 +#define ACE_LACKS_PRI_T 1 +#define ACE_HAS_3_PARAM_READDIR_R + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you want ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +#define ACE_HAS_IP_MULTICAST + +#define ACE_HAS_BIG_FD_SET + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 65535 + +#define ACE_DEFAULT_SELECT_REACTOR_SIZE 256 + +#define ACE_HAS_GETPAGESIZE + +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +#define ACE_HAS_SOCKLEN_T 1 + +#define ACE_HAS_GPERF + +#define ACE_HAS_DIRENT +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG + +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_FGETWC 1 +#define ACE_LACKS_NAMED_POSIX_SEM +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_MADVISE +#define ACE_LACKS_GETPGID_PROTOTYPE +#define ACE_LACKS_GETHOSTENT +#define ACE_LACKS_ITOW 1 +#define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS 1 +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RWLOCK_T 1 +#define ACE_LACKS_SUSECONDS_T +#define ACE_LACKS_SYS_SYSCTL_H + +#define ACE_LACKS_FGETWS 1 +#define ACE_LACKS_FPUTWS 1 + +#define ACE_LACKS_WCSTOULL 1 + +#define ACE_HAS_AUTOMATIC_INIT_FINI + +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGACTION_CONSTP2 +#define ACE_HAS_SIGSUSPEND +#define ACE_HAS_SIG_C_FUNC 1 +#define ACE_HAS_SIG_ATOMIC_T + +#define ACE_HAS_POSIX_SEM + +#define ACE_HAS_P_READ_WRITE + +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + +// Cygwin DLL suffix is .dll +#define ACE_DLL_SUFFIX ACE_TEXT (".dll") + +// Cygwin runs on Windows, so we have to get the environment variable PATH and +// not LD_LIBRARY_PATH which is the default in ACE +#define ACE_LD_SEARCH_PATH ACE_TEXT ("PATH") + +#if ACE_MT_SAFE +// Yes, we do have threads. +# define ACE_HAS_THREADS +// And they're even POSIX pthreads (LinuxThreads implementation) +# define ACE_HAS_PTHREADS + +# define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS + +// Compiler/platform has thread-specific storage +# define ACE_HAS_THREAD_SPECIFIC_STORAGE + +# define ACE_HAS_PTHREADS_UNIX98_EXT +# define ACE_HAS_PTHREAD_CONTINUE 1 +# define ACE_HAS_PTHREAD_SUSPEND 1 + +# define ACE_LACKS_PTHREAD_ATTR_SETSTACKADDR +// Cygwin (see pthread.h): Not supported or implemented. +# define ACE_LACKS_SETSCHED +# define ACE_LACKS_SETDETACH +# define ACE_LACKS_PTHREAD_CANCEL +# define ACE_LACKS_THREAD_PROCESS_SCOPING +# define ACE_LACKS_MUTEXATTR_PSHARED +# define ACE_LACKS_RWLOCKATTR_PSHARED +# define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 +# define ACE_LACKS_PTHREAD_YIELD 1 +# define ACE_LACKS_PTHREAD_ATTR_SETSTACK + +// In the 1.5.9 release of Cygwin the pthread_kill gives an access violation +// so for the time being we say Cygwin doesn't support pthread_kill. +# define ACE_LACKS_PTHREAD_KILL + +#endif /* ACE_MT_SAFE */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_CYGWIN32_H */ diff --git a/dep/ACE_wrappers/ace/config-doxygen.h b/dep/ACE_wrappers/ace/config-doxygen.h new file mode 100644 index 000000000..2bc89c982 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-doxygen.h @@ -0,0 +1,120 @@ +// -*- C++ -*- + +/** + * This is a configuration file to define all the macros that Doxygen + * needs + * + * @file config-doxygen.h + * + * $Id: config-doxygen.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Carlos O'Ryan + * @author Darrell Brunsch + * + */ +#ifndef ACE_CONFIG_DOXYGEN_H +#define ACE_CONFIG_DOXYGEN_H + +/// Make sure that we always turn inlining on. +#define __ACE_INLINE__ + +/// Make the wchar_t interfaces available. +#define ACE_HAS_WCHAR + +/// Make all the emulation versions of string operations visible +// #define ACE_LACKS_WCSTOK +#define ACE_LACKS_ITOW +#define ACE_LACKS_STRCASECMP +#define ACE_LACKS_STRRCHR +#define ACE_LACKS_WCSCAT +#define ACE_LACKS_WCSCHR +#define ACE_LACKS_WCSCMP +#define ACE_LACKS_WCSCPY +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSLEN +#define ACE_LACKS_WCSNCAT +#define ACE_LACKS_WCSNCMP +#define ACE_LACKS_WCSNCPY +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSPBRK +#define ACE_LACKS_WCSRCHR +#define ACE_LACKS_WCSCSPN +#define ACE_LACKS_WCSSPN +#define ACE_LACKS_WCSSTR + +/// Support for threads enables several important classes +#define ACE_HAS_THREADS + +/// Support for Win32 enables the WFMO_Reactor and several Async I/O +/// classes +#define ACE_WIN32 + +/// Enable support for POSIX Asynchronous I/O calls +#define ACE_HAS_AIO_CALLS + +/// Enable support for TLI interfaces +#define ACE_HAS_TLI + +/// Enable support for the SSL wrappers +#define ACE_HAS_SSL 1 + +/// Enable exceptions +#define ACE_HAS_EXCEPTIONS + +/// Enable timeprobes +#define ACE_COMPILE_TIMEPROBES + +/// Enable unicode to generate ACE_Registry_Name_Space +#define UNICODE + +/// These defines make sure that Svc_Conf_y.cpp and Svc_Conf_l.cpp are correctly +/// parsed +#define __cplusplus +#define ACE_YY_USE_PROTOS + +/// TAO features that should be documented too +#define TAO_HAS_RT_CORBA 1 +#define TAO_HAS_MINIMUM_CORBA 0 +#define TAO_HAS_AMI 1 +#define TAO_HAS_INTERCEPTORS 1 +#define TAO_HAS_SCIOP 1 +#define TAO_HAS_COIOP 1 +#define TAO_HAS_TRANSPORT_CURRENT 1 + +/// Generate token library documentation +#define ACE_HAS_TOKENS_LIBRARY + +/// Generate ACE ATM classes documentation +#define ACE_HAS_ATM + +/// Generate ACE XTI ATM class documentation +#define ACE_HAS_XTI_ATM + +/// Generate ACE_Dev_Poll_Reactor documentation +#define ACE_HAS_DEV_POLL + +/// Generate ACE_Event_Handler_T documentation +#define ACE_HAS_TEMPLATE_TYPEDEFS + +/// Generate ACE_Log_Msg_NT_Event_Log documentation +#define ACE_HAS_LOG_MSG_NT_EVENT_LOG + +/// Generate icmp documentation +#define ACE_HAS_ICMP_SUPPORT 1 + +/// Don't expand ACE_RCSID macro +#define ACE_USE_RCSID 0 + +/// Parse some ACE_SSL classes that depend on recent versions of +/// OpenSSL. +#define OPENSSL_VERSION_NUMBER 0x00905820L + +/// Enable IPv6 +#define ACE_HAS_IPV6 + +/// Enable netlink socket support +#define ACE_HAS_NETLINK + +#define ACE_HAS_IP_MULTICAST + +#endif /* ACE_CONFIG_DOXYGEN_H */ diff --git a/dep/ACE_wrappers/ace/config-freebsd.h b/dep/ACE_wrappers/ace/config-freebsd.h new file mode 100644 index 000000000..3461bec8d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-freebsd.h @@ -0,0 +1,284 @@ +/* -*- C++ -*- */ +// $Id: config-freebsd.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for FreeBSD + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#if ACE_MT_SAFE + // Yes, we do have threads. +# define ACE_HAS_THREADS 1 +#else + // Set to 0 since that's what config-posix.h checks for. +# define ACE_HAS_THREADS 0 +#endif /* ACE_MT_SAFE */ + +#include "ace/config-posix.h" + +#include +// Make sure we source in the OS version. + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#if (__FreeBSD_version < 220000) +#if defined (ACE_HAS_THREADS) +#error Threads are not supported. +#endif /* ACE_HAS_THREADS */ +#endif /* __FreeBSD_version < 220000 */ + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +#if defined (ACE_HAS_PENTIUM) +# undef ACE_HAS_PENTIUM +#endif /* ACE_HAS_PENTIUM */ + +// Platform specific directives +// gcc defines __FreeBSD__ automatically for us. +#ifdef ACE_HAS_THREADS +#if !defined (_THREAD_SAFE) +#define _THREAD_SAFE +#endif /* _THREAD_SAFE */ +#endif + +#define ACE_HAS_GPERF + +#if (__FreeBSD_version < 420000) +#define ACE_LACKS_GETPGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_PTHREAD_CANCEL +#endif /* __FreeBSD_version < 420000 */ + +#define ACE_HAS_ALT_CUSERID +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +#define ACE_HAS_SIG_MACROS +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_CHARPTR_DL + +#if (__FreeBSD_version < 400000) +#define ACE_LACKS_SIGSET +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_SETSCHED +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_RAND_REENTRANT_FUNCTIONS +#endif + +#define ACE_NEEDS_SCHED_H + +#if (__FreeBSD_version < 400000) +enum schedparam_policy { + SCHED_RR, + SCHED_IO, + SCHED_FIFO, + SCHED_OTHER +}; +#endif + +// Use of is deprecated. +#define ACE_LACKS_MALLOC_H + + +// This won't be necessary after it is fixed in the system include headers. +extern "C" { char * cuserid (char *s); } + +// Platform supports POSIX timers via struct timespec. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_UALARM + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +#if (__FreeBSD_version < 501000) +#define ACE_LACKS_STDINT_H +#endif + +#define ACE_HAS_SYSCTL +#define ACE_LACKS_STRRECVFD + +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +#if (__FreeBSD_version >= 220000) +#define ACE_HAS_VASPRINTF +#endif + +#if (__FreeBSD_version >= 300000) +#define ACE_HAS_SIGINFO_T +#endif /* __FreeBSD_version >= 300000 */ + +#if (__FreeBSD_version >= 320000) +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#endif /* __FreeBSD_version >= 320000 */ + +#if (__FreeBSD_version >= 440000) +#define ACE_HAS_GETPROGNAME +#define ACE_HAS_SETPROGNAME +#endif + +#if (__FreeBSD_version < 501000) +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS +#endif + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_LOG2 +#define ACE_LACKS_SI_ADDR + +// Compiler/platform supports SVR4 signal typedef +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform supports SVR4 dynamic linking semantics.. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Explicit dynamic linking permits "lazy" symbol resolution +#define ACE_HAS_RTLD_LAZY_V + +// platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Lacks perfect filtering, must bind group address. +#if !defined ACE_LACKS_PERFECT_MULTICAST_FILTERING +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING */ + +// Compiler/platform has +//#define ACE_HAS_ALLOCA_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports sys_siglist array. +// *** This refers to (_sys_siglist) instead of (sys_siglist) +// #define ACE_HAS_SYS_SIGLIST + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform/compiler supports timezone * as second parameter to gettimeofday(). +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +#define ACE_HAS_MSG +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG + +#if (__FreeBSD_version < 500100) +# define ACE_HAS_NONCONST_MSGSND +#endif + +// Thread specific settings +// Yes, we do have threads. +#ifdef ACE_HAS_THREADS +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif /* ! ACE_MT_SAFE */ +#endif /* ACE_HAS_THREADS */ + +#define ACE_LACKS_THREAD_PROCESS_SCOPING +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_DIRENT + +#define ACE_HAS_SIGWAIT + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#if (__FreeBSD_version > 400000) +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_SOCKLEN_T +#define ACE_HAS_GETIFADDRS +#define ACE_HAS_PTHREADS_UNIX98_EXT +#endif + +// Note, on FreeBSD 5, POSIX aio is now an optional kernel module which +// must be loaded. +// Read the aio(4) man page for what to do, otherwise any aio_* call +// will coredump. + +// By default use Proactor which does not use POSIX Real-time Signals. +#ifdef ACE_HAS_AIO_CALLS +# ifndef ACE_POSIX_AIOCB_PROACTOR +# define ACE_POSIX_AIOCB_PROACTOR +# endif /* ACE_POSIX_AIOCB_PROACTOR */ +#endif /* ACE_HAS_AIO_CALLS */ + +#define ACE_LACKS_STROPTS_H + +// Needed when ACE_HAS_WCHAR is defined. +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSDUP +#define ACE_LACKS_ITOW +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_HAS_3_PARAM_READDIR_R + +#if (__FreeBSD_version >= 501000) +# define ACE_HAS_PTHREAD_SETSTACK +#endif + +#if (__FreeBSD_version < 700007) +# define ACE_HAS_SIGVAL_SIGVAL_INT +# define ACE_HAS_BROKEN_SIGEVENT_STRUCT +#endif + +#if (__FreeBSD_version >= 700028) +# define ACE_HAS_SCTP +# define ACE_HAS_LKSCTP +#endif + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-g++-common.h b/dep/ACE_wrappers/ace/config-g++-common.h new file mode 100644 index 000000000..8ac8eb974 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-g++-common.h @@ -0,0 +1,136 @@ +// -*- C++ -*- +// +// $Id: config-g++-common.h 82495 2008-08-04 07:23:01Z johnnyw $ + +// This configuration file is designed to be included by another, +// specific configuration file. It provides config information common +// to all g++ platforms, including egcs. + +#ifndef ACE_GNUG_COMMON_H +#define ACE_GNUG_COMMON_H +#include /**/ "ace/pre.h" + +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_STDCPP_STL_INCLUDES +#define ACE_HAS_TEMPLATE_TYPEDEFS +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#if ( __GNUC__ == 2 && __GNUC_MINOR__ < 97 ) + // gcc 2.97 and lower use old iostreams +# define ACE_USES_OLD_IOSTREAMS +#endif /* __GNUC__ >= 2.97 */ + +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS +#endif /* __GNUC__ >= 3.4 */ + +#if (__GNUC__ < 3) +# define ACE_LACKS_MEMBER_TEMPLATES +#endif /* __GNUC__ < 3 */ + +// __EXCEPTIONS is defined with -fexceptions, the egcs default. It +// is not defined with -fno-exceptions, the ACE default for g++. +// ACE_HAS_EXCEPTIONS is defined in +// include/makeinclude/wrapper_macros.GNU, so this really isn't +// necessary. Just in case . . . +#if defined (__EXCEPTIONS) && !defined (ACE_HAS_EXCEPTIONS) +# define ACE_HAS_EXCEPTIONS +#endif /* __EXCEPTIONS && ! ACE_HAS_EXCEPTIONS */ + +#if defined (ACE_HAS_EXCEPTIONS) +# define ACE_NEW_THROWS_EXCEPTIONS +# if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) +// Versions of g++ prior to 3.3 had a buggy operator // new(nothrow)[](). +# define ACE_HAS_NEW_NOTHROW +# endif /* __GNUC__ >= 3.3 */ +#endif /* ACE_HAS_EXCEPTIONS */ + +#if (defined (i386) || defined (__i386__)) && !defined (ACE_SIZEOF_LONG_DOUBLE) +# define ACE_SIZEOF_LONG_DOUBLE 12 +#endif /* i386 */ + +#if !defined (__MINGW32__) && (defined (i386) || defined (__i386__)) + // If running an Intel, assume that it's a Pentium so that + // ACE_OS::gethrtime () can use the RDTSC instruction. If running a + // 486 or lower, be sure to comment this out. (If not running an + // Intel CPU, this #define will not be seen because of the i386 + // protection, so it can be ignored.) +# define ACE_HAS_PENTIUM +#endif /* i386 */ + +#if (defined (ACE_HAS_PENTIUM) || defined (__amd64__) || defined (__x86_64__)) +# define ACE_HAS_INTEL_ASSEMBLY +#endif + +// GNU g++ >= 4.x implements "#pragma once". +#if (__GNUC__ < 4) && !defined (ACE_LACKS_PRAGMA_ONCE) +// We define it with a -D with make depend. +# define ACE_LACKS_PRAGMA_ONCE +#endif /* ! ACE_LACKS_PRAGMA_ONCE */ + +// Take advantage of G++ (>= 4.x) visibility attributes to generate +// improved shared library binaries. +#if (__GNUC__ >= 4) && !defined (__MINGW32__) + +# if defined (ACE_HAS_CUSTOM_EXPORT_MACROS) && ACE_HAS_CUSTOM_EXPORT_MACROS == 0 +# undef ACE_HAS_CUSTOM_EXPORT_MACROS +# if defined (ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS) +# undef ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS +# endif /* ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS */ +# define ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 0 +# else +# ifndef ACE_HAS_CUSTOM_EXPORT_MACROS +# define ACE_HAS_CUSTOM_EXPORT_MACROS +# endif /* !ACE_HAS_CUSTOM_EXPORT_MACROS */ +# define ACE_Proper_Export_Flag __attribute__ ((visibility("default"))) +# define ACE_Proper_Import_Flag __attribute__ ((visibility("default"))) + +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) +// Sadly, G++ 4.x silently ignores visibility attributes on +// template instantiations, which breaks singletons. +// As a workaround, we use the GCC visibility pragmas. +// And to make them fit in a macro, we use C99's _Pragma() +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17470 +// This has been fixed in GCC 4.1.1 with FC6 but not with SuSE 10.2 +// that gets shipped with GCC 4.1.2 so we assume that with GCC 4.2 +// this will be fixed on the head. With FC6 just set this define yourself +# ifndef ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS +# define ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 1 +# endif +# endif + +# if defined (ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS) && ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS == 1 +# define ACE_EXPORT_SINGLETON_DECLARATION(T) template class ACE_Proper_Export_Flag T +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class ACE_Proper_Export_Flag SINGLETON_TYPE ; +# else /* ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS */ +# define ACE_EXPORT_SINGLETON_DECLARATION(T) \ + _Pragma ("GCC visibility push(default)") \ + template class T \ + _Pragma ("GCC visibility pop") +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) \ + _Pragma ("GCC visibility push(default)") \ + template class SINGLETON_TYPE; \ + _Pragma ("GCC visibility pop") +# endif /* ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS */ + +// Note that the "__extension__" is needed to prevent g++ from issuing +// an error when using its "-pedantic" command line flag. +# define ACE_IMPORT_SINGLETON_DECLARATION(T) __extension__ extern template class T +# define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) __extension__ extern template class SINGLETON_TYPE; + +# endif /* ACE_HAS_CUSTOM_EXPORT_MACROS == 0 */ +#endif /* __GNU__ >= 4 */ + +#if defined (ACE_HAS_GNU_REPO) + // -frepo causes unresolved symbols of basic_string left- and + // right-shift operators with ACE_HAS_STRING_CLASS. +# if defined (ACE_HAS_STRING_CLASS) +# undef ACE_HAS_STRING_CLASS +# endif /* ACE_HAS_STRING_CLASS */ +#endif /* ! ACE_HAS_GNU_REPO */ + +#include /**/ "ace/post.h" +#endif /* ACE_GNUG_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-ghs-common.h b/dep/ACE_wrappers/ace/config-ghs-common.h new file mode 100644 index 000000000..ffa554c04 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-ghs-common.h @@ -0,0 +1,43 @@ +/* -*- C++ -*- */ +// $Id: config-ghs-common.h 80826 2008-03-04 14:51:23Z wotte $ + +// This configuration file is designed to be included by another, +// specific configuration file. It provides config information common +// to all Green Hills platforms. + +#ifndef ACE_GHS_COMMON_H +#define ACE_GHS_COMMON_H +#include /**/ "ace/pre.h" + +#if !defined (ACE_CONFIG_INCLUDE_GHS_COMMON) +# error ace/config-ghs-common.h: ACE configuration error! Do not #include this file directly! +#endif + +#if defined (ghs) + +# if defined (sun) + // Need nonstatic Object_Manager on Solaris to prevent seg fault + // on startup. +# define ACE_HAS_NONSTATIC_OBJECT_MANAGER +# endif /* sun */ + +# if defined (__STANDARD_CXX) + // Green Hills 1.8.9, but not 1.8.8. +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_LACKS_AUTO_PTR +# define ACE_LACKS_CHAR_RIGHT_SHIFTS +# define ACE_LACKS_UNBUFFERED_STREAMBUF +# else +# define ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA +# endif /* __STANDARD_CXX */ + +# define ACE_LACKS_LINEBUFFERED_STREAMBUF +# define ACE_LACKS_LONGLONG_T +# define ACE_LACKS_SIGNED_CHAR + +#else /* ! ghs */ +# error ace/config-ghs-common.h can only be used with Green Hills compilers! +#endif /* ! ghs */ + +#include /**/ "ace/post.h" +#endif /* ACE_GHS_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-hpux-11.00.h b/dep/ACE_wrappers/ace/config-hpux-11.00.h new file mode 100644 index 000000000..3af693e3e --- /dev/null +++ b/dep/ACE_wrappers/ace/config-hpux-11.00.h @@ -0,0 +1,449 @@ +/* -*- C++ -*- */ +// $Id: config-hpux-11.00.h 81992 2008-06-16 19:09:50Z wotte $ + +// The following configuration file is designed to work for HP +// platforms running HP-UX 11.00 using aC++ or gcc (2.95 and up). + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#define ACE_LACKS_STDINT_H +#define ACE_LACKS_SYS_SELECT_H + +#if defined (__GNUG__) + +// config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so +// this must appear before its #include. +# define ACE_HAS_STRING_CLASS + +# include "ace/config-g++-common.h" + +#else + +// aC++... + +// Precompiler needs extra flags to ignore "invalid #pragma directive" +# ifndef ACE_USING_MCPP_PREPROCESSOR +# define ACE_CC_PREPROCESSOR_ARGS "-E +W 67" +# endif +// Compiler supports C++ exception handling. It's on by default. If the +// +noeh compiler option is used to disable exceptions, the compiler defines +// __HPACC_NOEH. +# if !defined (__HPACC_NOEH) +# define ACE_HAS_EXCEPTIONS 1 +# endif + +// If the -AA compile option is used, the compiler defines _HP_NAMESPACE_STD. +// The -AA option enables the 2.0 standard C++ library. If not used, then +// we have the old, 1.2.1 C++ library. +# if defined (_HP_NAMESPACE_STD) +# if defined (ACE_HAS_STANDARD_CPP_LIBRARY) +# undef ACE_HAS_STANDARD_CPP_LIBRARY +# endif +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +# undef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB +# endif +# if defined (RWSTD_NO_NAMESPACE) + namespace std {} using namespace std; +# else +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# endif /* RWSTD_NO_NAMESPACE */ +# else +# define ACE_USES_OLD_IOSTREAMS + // There's no support in ACE's use of numeric_limits for those that + // aren't in std:: +# define ACE_LACKS_NUMERIC_LIMITS +# endif /* _HP_NAMESPACE_STD */ + +// Compiler implements templates that support typedefs inside of classes +// used as formal arguments to a template class. +# define ACE_HAS_TEMPLATE_TYPEDEFS + +# define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR + +// Platform lacks streambuf "linebuffered ()". +# define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 + +// Lack of (and broken) support for placement operator delete is a known +// bug by HP, up until aC++ A.03.55.02. +# if (__HP_aCC < 35502) +# define ACE_LACKS_PLACEMENT_OPERATOR_DELETE +# endif /* __HP_aCC < 35502 */ + +// Compiler's 'new' throws exceptions on failure, regardless of whether or +// not exception handling is enabled in the compiler options. Fortunately, +// new(nothrow_t) is offered. +# define ACE_NEW_THROWS_EXCEPTIONS +# define ACE_HAS_NEW_NOTHROW +# define ACE_HAS_NEW_NO_H 1 + +// Compiler's template mechanism must see source code (i.e., .C files). +# define ACE_TEMPLATES_REQUIRE_SOURCE + +// Compiler doesn't handle 'signed char' correctly (used in ace/IOStream.h) +# define ACE_LACKS_SIGNED_CHAR + +#endif /* __GNUG__, HP */ + +//********************************************************************* +// +// From here down is the compiler-INdependent OS settings. +// +//********************************************************************* + +// Compiling for HPUX. +#if !defined (HPUX) +#define HPUX +#endif /* HPUX */ +#define HPUX_11 + +#ifndef _HPUX_SOURCE +#define _HPUX_SOURCE +#endif + +#include /**/ + +// HP-UX is a POSIX-compliant system - see what's available. +#include "ace/config-posix.h" + +// config-posix.h sets up ACE_HAS_AIO_CALLS if the headers define the +// proper things. In HP-UX 11's case, the AIOCB Proactor works the best +// overall. If the user hasn't overridden it, select AIOCB. +#if defined (ACE_HAS_AIO_CALLS) +# if !defined (ACE_POSIX_AIOCB_PROACTOR) && !defined (ACE_POSIX_SIG_PROACTOR) +# define ACE_POSIX_AIOCB_PROACTOR +# endif /* !ACE_HAS_POSIX_AIOCB_PROACTOR && !ACE_POSIX_SIG_PROACTOR */ +#endif /* ACE_HAS_AIO_CALLS */ + +//////////////////////////////////////////////////////////////////////////// +// +// General OS information - see README for more details on what they mean +// +/////////////////////////////////////////////////////////////////////////// + +// HP/UX needs to have these addresses in a special range. +// If this is on a 64-bit model, the default is to use 64-bit addressing. +// It can also be set so that the mapped region is shareable with 32-bit +// programs. To enable the 32/64 sharing, comment out the first definition +// of ACE_DEFAULT_BASE_ADDR and uncomment the two lines after it. +#if defined (__LP64__) +# define ACE_DEFAULT_BASE_ADDR ((char *) 0x0000001100000000) +//# define ACE_DEFAULT_BASE_ADDR ((char *) 0x80000000) +//# define ACE_OS_EXTRA_MMAP_FLAGS MAP_ADDR32 + +# define ACE_DEFAULT_BASE_ADDRL (0x0000001100000000) +//# define ACE_DEFAULT_BASE_ADDRL (0x80000000) +#else +# define ACE_DEFAULT_BASE_ADDR ((char *) 0x80000000) +#endif /* __LP64__ */ + +// Preprocessor needs some help with data types +#if defined (__LP64__) +# define ACE_SIZEOF_LONG 8 +#else +# define ACE_SIZEOF_LONG 4 +#endif + +// Platform can do async I/O (aio_*) (set up in config-posix.h) +// ... but seems to require this in order to keep from hanging. Needs some +// investigation, maybe with HP. John Mulhern determined this value +// empirically. YMMV. If it does vary, set it up in your own config.h which +// then includes the ACE-supplied config. +#if !defined (ACE_INFINITE) +# define ACE_INFINITE 10000000 +#endif + +/* Compiler/platform correctly calls init()/fini() for shared libraries. */ +#define ACE_HAS_AUTOMATIC_INIT_FINI 1 + +// Manually tweak the malloc control block paddings to properly align +// things. +#define ACE_MALLOC_PADDING 16 +#define ACE_MALLOC_ALIGN 8 +#define ACE_PI_CONTROL_BLOCK_ALIGN_LONGS 3 + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +#define ACE_HAS_SYS_PSTAT_H + +// But doesn't have a prototype for syscall() +#define ACE_LACKS_SYSCALL + +// Platform supports POSIX.1b clock_gettime () +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform has Dirent iterator functions. +#define ACE_HAS_DIRENT + +#define ACE_HAS_VSWPRINTF + +// Platform supports getpagesize() call +#define ACE_HAS_GETPAGESIZE +// But we define this just to be safe +#define ACE_PAGE_SIZE 4096 + +// Can run gperf on this platform (needed for TAO) +# define ACE_HAS_GPERF + +// Optimize ACE_Handle_Set for select(). +# define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST +// At least for 11iv2, lacks perfect filtering. +#if (HPUX_VERS >= 1123) && !defined (ACE_LACKS_PERFECT_MULTICAST_FILTERING) +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif + +/* Platform defines MAP_FAILED as a long constant. */ +#define ACE_HAS_LONG_MAP_FAILED 1 + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Platform's select() has non-const timeval argument +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +/* Platform supports "position-independent" features provided by + ACE_Based_Pointer<>. */ +#define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1 + +/* Platform supports POSIX getpwnam_r() function */ +#define ACE_HAS_POSIX_GETPWNAM_R 1 + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Platform supports the POSIX struct timespec type +#define ACE_HAS_POSIX_TIME + +/* Platform has pread() and pwrite() support. */ +#define ACE_HAS_P_READ_WRITE 1 + +/* Platform will recurse infinitely on thread exits from TSS cleanup routines + (e.g., AIX) */ +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS 1 + +// Platform supports reentrant functions (all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS +// ctime_r and asctime_r conform to POSIX.1c (2 param version) +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + +// Platform offers scandir(), and requires no adjustments for its API. +#define ACE_HAS_SCANDIR + +// HP-UX 11 has reentrant netdb functions. The catch is that the old +// functions (gethostbyname, etc.) are thread-safe and the _r versions are +// not used and will be removed at some point. So, define things so +// the _r versions are not used. This will slow things down a bit due to +// the extra mutex lock in the ACE_NETDBCALL_RETURN macro, and will be fixed +// in the future (problem ID P64). +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS + +/* Platform lacks pri_t (e.g., Tandem NonStop UNIX). */ +#define ACE_LACKS_PRI_T 1 + +// Platform has shm_open +#define ACE_HAS_SHM_OPEN + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +/* Compiler requires extern "C" functions for signals. */ +#define ACE_HAS_SIG_C_FUNC 1 + +// Platform's sigaction() function takes const sigaction* as 2nd parameter. +#define ACE_HAS_SIGACTION_CONSTP2 + +#define ACE_HAS_SSIZE_T + +// Platform supports SVR4 extended signals +#define ACE_HAS_SIGINFO_T + +/* Define to 1 if platform has sigsuspend(). */ +#define ACE_HAS_SIGSUSPEND 1 + +// Platform doesn't detect a signal out of range unless it's way out of range. +#define ACE_HAS_SIGISMEMBER_BUG + +/* Platform provides socklen_t type, such as Linux with glibc2. */ +#define ACE_HAS_SOCKLEN_T 1 + +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +/* Platform/compiler supports _sys_errlist symbol */ +#define ACE_HAS_SYS_ERRLIST 1 + +#define ACE_HAS_UALARM + +// Platform supports ucontext_t (which is used in the extended signal API). +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Platform/compiler supports void * as second parameter to gettimeofday(). +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY + +/* Platform requires void * for mmap(). */ +#define ACE_HAS_VOIDPTR_MMAP 1 + +/* OS/compiler uses void * arg 4 setsockopt() rather than const char * */ +#define ACE_HAS_VOIDPTR_SOCKOPT 1 + +// Platform supports SVR4 dynamic linking semantics. +// When used, this requires -ldl on the ACE library link line. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform supports the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +/* Define to 1 if platform has the declaration of getrusage(). */ +#define ACE_HAS_GETRUSAGE_PROTOTYPE 1 + +// Platform has the sigwait function in a header file +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIGTIMEDWAIT + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// accept() is thread-safe +#define ACE_HAS_THREAD_SAFE_ACCEPT + +// Platform lacks a typedef for timespec_t, but has struct timespec +#define ACE_LACKS_TIMESPEC_T + +// dlopen() takes a char* instead of const char* +#define ACE_HAS_CHARPTR_DL + +// lacks setegid and seteuid +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETEUID + +#define ACE_LACKS_SUSECONDS_T +#define ACE_LACKS_SYS_SYSCTL_H + +// @@ TODO: It looks like HP-UX provides strtoull and wcstoull +// but some more work is needed to plug them in correctly. +#define ACE_LACKS_STRTOULL +#define ACE_LACKS_WCSTOULL + +// Shared library name/path components +#if defined (__ia64) +# define ACE_DLL_SUFFIX ACE_TEXT (".so") +#else +# define ACE_DLL_SUFFIX ACE_TEXT (".sl") +#endif /* __ia64 */ +#if defined (__LP64__) +# define ACE_LD_SEARCH_PATH ACE_TEXT ("LD_LIBRARY_PATH") +#else +# define ACE_LD_SEARCH_PATH ACE_TEXT ("SHLIB_PATH") +#endif /* __LP64__ */ + +#if defined (_INCLUDE__STDC_A1_SOURCE) +# define ACE_HAS_3_PARAM_WCSTOK +#endif + +#define ACE_HAS_3_PARAM_READDIR_R + + +////////////////////////////////////////////////////////////////////////// +// +// STREAMS information +// +////////////////////////////////////////////////////////////////////////// + +// Platform supports STREAMS +#define ACE_HAS_STREAMS +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T +// But the putmsg signature doesn't have it as const... +// Well, it really does, but it depends on preprocessor defines. +#define ACE_LACKS_CONST_STRBUF_PTR +/* Platform supports TLI timod STREAMS module */ +#define ACE_HAS_TIMOD_H 1 + +// Platform supports STREAM pipes +// This is possible, but not by default - need to rebuild the kernel to +// get them enabled - see pipe(2) and "STREAMS/UX for the HP 9000" +// #define ACE_HAS_STREAM_PIPES + +///////////////////////////////////////////////////////////////////////// +// +// TLI/XTI information +// +//////////////////////////////////////////////////////////////////////// + +// Platform supports XTI (includes TLI). +#define ACE_HAS_XTI +// HP-UX 11 conforms to the XPG4 spec, which ACE calls broken for the +// errmsg not being const... +#define ACE_HAS_BROKEN_T_ERROR +// The definitions of TCP_NODELAY and TCP_MAXSEG conflict between +// sys/xti.h and netinet/tcp.h. +#define ACE_HAS_CONFLICTING_XTI_MACROS +/* Platform provides header */ +#define ACE_HAS_SYS_XTI_H 1 + +///////////////////////////////////////////////////////////////////////// +// +// Threads information. +// +// Use of threads is controlled by the 'threads' argument to make. See +// include/makeinclude/platform_hpux_aCC.GNU for details. If it's not set, +// the default is to enable it, since kernel threads are always available +// on HP-UX 11, as opposed to 10.x where it was optional software. +// +//////////////////////////////////////////////////////////////////////// + +#if defined (ACE_HAS_THREADS) +# if (ACE_HAS_THREADS == 0) +# undef ACE_HAS_THREADS +# endif /* ACE_HAS_THREADS == 0 */ +#else +# define ACE_HAS_THREADS +#endif /* ACE_HAS_THREADS */ + +#if defined (ACE_HAS_THREADS) + +# if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +# endif + +// HP-UX doesn't define _POSIX_THREADS since it doesn't implement all +// features (lacks thread priority inheritance and protection), so +// config-posix.h doesn't get this one... +# define ACE_HAS_PTHREADS +# define ACE_HAS_PTHREADS_UNIX98_EXT +# define ACE_HAS_PTHREAD_CONTINUE +# define ACE_HAS_PTHREAD_RESUME_NP +# define ACE_HAS_PTHREAD_SUSPEND +# define ACE_HAS_RECURSIVE_MUTEXES +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_LACKS_PTHREAD_ATTR_SETSTACK +#endif /* ACE_HAS_THREADS */ + +#define ACE_HAS_POSIX_SEM + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// gethostbyaddr does not handle IPv6-mapped-IPv4 addresses +#define ACE_HAS_BROKEN_GETHOSTBYADDR_V4MAPPED + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-icc-common.h b/dep/ACE_wrappers/ace/config-icc-common.h new file mode 100644 index 000000000..1ebd0c52e --- /dev/null +++ b/dep/ACE_wrappers/ace/config-icc-common.h @@ -0,0 +1,113 @@ +// -*- C++ -*- +// +// $Id: config-icc-common.h 81935 2008-06-12 22:01:53Z jtc $ + +#ifndef ACE_LINUX_ICC_COMMON_H +#define ACE_LINUX_ICC_COMMON_H +#include /**/ "ace/pre.h" + +# define ACE_HAS_CPLUSPLUS_HEADERS +# define ACE_HAS_STDCPP_STL_INCLUDES +# define ACE_HAS_TEMPLATE_TYPEDEFS +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_HAS_STRING_CLASS + +#if defined (ACE_HAS_CUSTOM_EXPORT_MACROS) && ACE_HAS_CUSTOM_EXPORT_MACROS == 0 +# undef ACE_HAS_CUSTOM_EXPORT_MACROS +# if defined (ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS) +# undef ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS +# endif /* ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS */ +# define ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 0 +#else +# ifndef ACE_HAS_CUSTOM_EXPORT_MACROS +# define ACE_HAS_CUSTOM_EXPORT_MACROS +# endif /* !ACE_HAS_CUSTOM_EXPORT_MACROS */ +# define ACE_Proper_Export_Flag __attribute__ ((visibility("default"))) +# define ACE_Proper_Import_Flag __attribute__ ((visibility("default"))) + +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) +// Sadly, G++ 4.x silently ignores visibility attributes on +// template instantiations, which breaks singletons. +// As a workaround, we use the GCC visibility pragmas. +// And to make them fit in a macro, we use C99's _Pragma() +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17470 +// This has been fixed in GCC 4.1.1 with FC6 but not with SuSE 10.2 +// that gets shipped with GCC 4.1.2 so we assume that with GCC 4.2 +// this will be fixed on the head. With FC6 just set this define yourself +# ifndef ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS +# define ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 1 +# endif +# endif + +# if defined (ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS) && ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS == 1 +# define ACE_EXPORT_SINGLETON_DECLARATION(T) template class ACE_Proper_Export_Flag T +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class ACE_Proper_Export_Flag SINGLETON_TYPE ; +# else /* ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS */ +# define ACE_EXPORT_SINGLETON_DECLARATION(T) \ + _Pragma ("GCC visibility push(default)") \ + template class T \ + _Pragma ("GCC visibility pop") +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) \ + _Pragma ("GCC visibility push(default)") \ + template class SINGLETON_TYPE; \ + _Pragma ("GCC visibility pop") +# endif /* ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS */ + +// Note that the "__extension__" is needed to prevent g++ from issuing +// an error when using its "-pedantic" command line flag. +# define ACE_IMPORT_SINGLETON_DECLARATION(T) __extension__ extern template class T +# define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) __extension__ extern template class SINGLETON_TYPE; +#endif /* ACE_HAS_CUSTOM_EXPORT_MACROS == 0 */ + +// __EXCEPTIONS is defined with -fexceptions, the egcs default. It +// is not defined with -fno-exceptions, the ACE default for g++. +// ACE_HAS_EXCEPTIONS is defined in +// include/makeinclude/wrapper_macros.GNU, so this really isn't +// necessary. Just in case . . . +# if defined (__EXCEPTIONS) && !defined (ACE_HAS_EXCEPTIONS) +# define ACE_HAS_EXCEPTIONS +# endif /* __EXCEPTIONS && ! ACE_HAS_EXCEPTIONS */ + +# if defined (ACE_HAS_EXCEPTIONS) +# define ACE_NEW_THROWS_EXCEPTIONS +# endif /* ACE_HAS_EXCEPTIONS */ + +#if (defined (i386) || defined (__i386__)) && !defined (ACE_SIZEOF_LONG_DOUBLE) +# define ACE_SIZEOF_LONG_DOUBLE 12 +#endif /* i386 */ + +#if !defined (__MINGW32__) && (defined (i386) || defined (__i386__)) + // If running an Intel, assume that it's a Pentium so that + // ACE_OS::gethrtime () can use the RDTSC instruction. If running a + // 486 or lower, be sure to comment this out. (If not running an + // Intel CPU, this #define will not be seen because of the i386 + // protection, so it can be ignored.) +# define ACE_HAS_PENTIUM +#endif /* i386 */ + +#if (defined (ACE_HAS_PENTIUM) || defined (__amd64__) || defined (__x86_64__)) +# define ACE_HAS_INTEL_ASSEMBLY +#endif + +#if !defined (ACE_LACKS_PRAGMA_ONCE) + // We define it with a -D with make depend. +# define ACE_LACKS_PRAGMA_ONCE +#endif /* ! ACE_LACKS_PRAGMA_ONCE */ + +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#if (__INTEL_COMPILER >= 910) +# define ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS +#endif + +#if defined (__ia64) +# define ACE_HAS_IA64INTRIN_H +# define ACE_HAS_INTRINSIC_INTERLOCKED +#else +# define ACE_HAS_IA32INTRIN_H +#endif + +#include /**/ "ace/post.h" +#endif /* ACE_LINUX_ICC_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-integritySCA.h b/dep/ACE_wrappers/ace/config-integritySCA.h new file mode 100644 index 000000000..62a5d5963 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-integritySCA.h @@ -0,0 +1,233 @@ +// -*- C++ -*- + +#ifndef ACE_INT_CONFIG_H +#define ACE_INT_CONFIG_H + +/* + * This config.h file is for version 4.0.x of the + * Integrity RTOS with SCA from Green Hills Software + * http://www.ghs.com/products/rtos/integrity.html + * + * $Id: config-integritySCA.h 81935 2008-06-12 22:01:53Z jtc $ + */ + +#define ghs +/* compilation defines */ +#define ACE_LACKS_GETPGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETSID +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETUID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_GETEUID +#define ACE_LACKS_GETUID +#define ACE_LACKS_GETEGID +#define ACE_LACKS_GETGID + +#ifndef ACE_HAS_EXCEPTIONS + #define ACE_HAS_EXCEPTIONS +#endif +#define ACE_NEW_THROWS_EXCEPTIONS +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#define ACE_TEMPLATES_REQUIRE_SOURCE 1 +#define ACE_HAS_TEMPLATE_TYPEDEFS +#define TAO_USE_SEQUENCE_TEMPLATES +#define ACE_NEEDS_FUNC_DEFINITIONS +#define _REENTRANT +#define ACE_MT_SAFE 1 + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +#define ACE_HAS_SHM_OPEN + +/***** Operating System Defines *****/ + +/***** ANSI defines *****/ +#define ACE_LACKS_TEMPNAM /* believe it or not, this is ANSI C */ +#define ACE_HAS_STRERROR + + +#define ACE_LACKS_SENDMSG + +/***** End Stack Defines *****/ + + +/* SCA STUFF */ +#if defined(INTEGRITY_VERSION) && (INTEGRITY_VERSION >= 40108) +#define ACE_HAS_SIG_ATOMIC_T +#endif /* INTEGRITY_VERSION */ +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIGACTION +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_UCONTEXT_H +#define ACE_HAS_SIG_C_FUNC +#define ACE_LACKS_SI_ADDR +#define ACE_HAS_AIO_CALLS + +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_DIRENT + +#define ACE_HAS_THREADS + +#define ACE_HAS_PTHREADS +/***** End Threading Defines *****/ + +/***** Hardware Defines *****/ +#define ACE_PAGE_SIZE 4096 +/***** End Hardware Defines *****/ + +/****** SYSV_IPC STUFF *****/ +#define ACE_LACKS_KEY_T + +/****** Posix Defines *****/ +#define ACE_LACKS_WAIT +#define ACE_LACKS_WAITPID +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_POSIX_SEM +#define ACE_HAS_STRDUP_EMULATION +#define ACE_HAS_MSG +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_EXEC +#define ACE_LACKS_FORK +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_MPROTECT +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_PIPE +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RECVMSG +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS +#define ACE_LACKS_USER +#define ACE_LACKS_FILE_FCNTL +#define ACE_LACKS_FCNTL +#define ACE_LACKS_UMASK +#define ACE_LACKS_SEEK +#define ACE_LACKS_SHARED_MEMORY +#define ACE_LACKS_MSYNC +#define ACE_LACKS_PID_STUFF +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_IPC_H +#define ACE_LACKS_SETGID +#define ACE_LACKS_PIPE +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_UTSNAME_T +#define ACE_LACKS_UNAME +#define ACE_LACKS_UMASK +#define ACE_LACKS_ISATTY +#define ACE_LACKS_GETOPT +#define ACE_LACKS_STRCASECMP +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_PWD_FUNCTIONS +#define ACE_LACKS_UNIX_SIGNALS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_PUTENV +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_LACKS_THREAD_PROCESS_SCOPING +#define ACE_LACKS_SETSCHED +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_WRITEV +#define ACE_LACKS_READV +#define ACE_LACKS_SYSCONF +#define ACE_LACKS_GETOPT +/* below refers to fcntl style locking */ +#define ACE_LACKS_FILELOCKS + +#define ACE_LACKS_REALPATH +#define ACE_HAS_CONST_CHAR_SWAB +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +/***** Not tied to standards AFAIK ****/ +#define ACE_LACKS_MADVISE /* paging optimization not needed with INTEGRITY */ +#define ACE_LACKS_MALLOC_H /* netbsd's just includes stdlib.h */ +#define ACE_LACKS_MEMORY_H /* netbsd's just includes string.h */ +#define ACE_LACKS_INTTYPES_H +#define ACE_LACKS_SYS_RESOURCE_H +#define ACE_LACKS_SYS_WAIT_H +#define ACE_LACKS_SEARCH_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_REGEX_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_TERMIOS_H + +/***** STUFF INTEGRITY 4.0.8 APPEARS TO SUPPORT ****/ +/* note, possibly untested with ace */ + +/***** TAO STUFF ****/ +#define TAO_USE_DOTTED_DECIMAL_ADDRESSES 1 + +#include + +#include + +typedef void (*__sighandler_t)(int); + +extern "C" +{ + inline int isatty(int) { return 0; } +} + +#ifdef ppc +#define ACE_HAS_POWERPC_TIMER +#endif + +/* MIKEC Addtions */ +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#include // needed to define iovec +#define ACE_LACKS_READLINK +#define ACE_LACKS_GETPPID +#define NSIG (SIGRTMAX+1) +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#define ACE_USE_RCSID 0 +#define ACE_LACKS_CUSERID +#define ACE_NEEDS_HUGE_THREAD_STACKSIZE 0x5000 +#define fileno(file) ((file)->io_channel) //Hack to get Svc_Conf_l.cpp compiled +#define ACE_DEFAULT_THREAD_PRIORITY 127 +#define PRI_FIFO_MIN 1 +#define PRI_FIFO_MAX 127 +#define ACE_THR_PRI_FIFO_DEF 127 +#define PRI_RR_MIN 1 +#define PRI_RR_MAX 127 +#define ACE_THR_PRI_RR_DEF 127 +#define PRI_OTHER_MIN 1 +#define PRI_OTHER_MAX 127 +#define ACE_THR_PRI_OTHER_DEF 127 +#define ACE_PTHREAD_RETURN_ON_EXIT +#undef ACE_LACKS_UNLINK + +#define ACE_HAS_TIMED_MESSAGE_BLOCKS + +extern "C" { +int unlink(const char *); +} + +#define ACE_LACKS_SETSID +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY +#define ACE_LACKS_UNIX_SYSLOG +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_GETHOSTENT + + +/* end MIKEC Addtions */ + +// Hack to avoid ensure that things defined in ind_io.h +// have the right linkage +#include + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-irix6.5.x-sgic++.h b/dep/ACE_wrappers/ace/config-irix6.5.x-sgic++.h new file mode 100644 index 000000000..2d501010b --- /dev/null +++ b/dep/ACE_wrappers/ace/config-irix6.5.x-sgic++.h @@ -0,0 +1,18 @@ +// -*- C++ -*- +// $Id: config-irix6.5.x-sgic++.h 80826 2008-03-04 14:51:23Z wotte $ + +// Use this file for IRIX 6.5.x + +#ifndef ACE_CONFIG_IRIX65X_H +#define ACE_CONFIG_IRIX65X_H +#include /**/ "ace/pre.h" + +// Include IRIX 6.[234] configuration +#include "ace/config-irix6.x-sgic++.h" + +// Irix 6.5 man pages show that they exist +#undef ACE_LACKS_CONDATTR_PSHARED +#undef ACE_LACKS_MUTEXATTR_PSHARED + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_IRIX65X_H */ diff --git a/dep/ACE_wrappers/ace/config-irix6.x-common.h b/dep/ACE_wrappers/ace/config-irix6.x-common.h new file mode 100644 index 000000000..d968fa422 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-irix6.x-common.h @@ -0,0 +1,257 @@ +/* -*- C++ -*- */ +// +// $Id: config-irix6.x-common.h 81697 2008-05-14 18:33:11Z johnnyw $ +// +// This file contains the common configuration options for both +// SGI/MIPSPro C++ and g++ under IRIX 6.X +// +// For IRIX 6.2 there are several patches that should be applied to +// get reliable operation with multi-threading and exceptions. +// Specifically you should get a reasonable current IRIX, Compiler +// and POSIX patch-sets. + +// For IRIX 6.[34] it's less critical, but it's still recommended +// that you apply the applicable patch-sets (IRIX and Compiler I believe). + +// These patches are updated frequently, so you should ask your support +// contact or search SGI's web site (http://www.sgi.com) for the latest +// version. + +// Use this file for IRIX 6.[234] if you have the pthreads patches +// installed. + +#ifndef ACE_CONFIG_IRIX6X_COMMON_H + +#ifndef IRIX6 +# define IRIX6 +#endif + +#if ! defined(ACE_CONFIG_H) +#error "This file may only be included by config-irix6.x-sgic++.h, config-irix6.x-kcc.h or config-irix6.x-g++.h" +#endif + +// The Irix 6.x float.h doesn't allow us to distinguish between a +// double and a long double. So, we have to hard-code this. Thanks +// to Bob Laferriere for figuring it out. +#if defined (_MIPS_SIM) /* 6.X System */ +# include +# if defined (__GNUC__) +# define ACE_SIZEOF_LONG_DOUBLE 16 +# elif defined (_MIPS_SIM_NABI32) && (_MIPS_SIM == _MIPS_SIM_NABI32) +# define ACE_SIZEOF_LONG_DOUBLE 16 +# elif defined (_MIPS_SIM_ABI32) && (_MIPS_SIM == _MIPS_SIM_ABI32) +# define ACE_SIZEOF_LONG_DOUBLE 8 +# elif defined (_MIPS_SIM_ABI64) && (_MIPS_SIM == _MIPS_SIM_ABI64) +# define ACE_SIZEOF_LONG_DOUBLE 16 +# elif !defined (ACE_SIZEOF_LONG_DOUBLE) +# define ACE_SIZEOF_LONG_DOUBLE 8 +# endif +#else +# define ACE_SIZEOF_LONG_DOUBLE 8 /* 5.3 System */ +#endif + +// petern, Next part of it: + +// Platform supports getpagesize() call. +#define ACE_HAS_GETPAGESIZE + +// Platform has no implementation of pthread_condattr_setpshared(), +// even though it supports pthreads! (like Irix 6.2) +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_MUTEXATTR_PSHARED + +#define ACE_LACKS_SUSECONDS_T + +// Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform requires void * for mmap(). +#define ACE_HAS_VOIDPTR_MMAP + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Compiler/platform supports alloca() +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Irix needs to define bzero() in this odd file +#define ACE_HAS_BSTRING + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST +#ifdef ACE_LACKS_PERFECT_MULTICAST_FILTERING + #undef ACE_LACKS_PERFECT_MULTICAST_FILTERING +#endif +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 + +//************************************************************** +// Not so sure how next lines should look like + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME + +//************************************************************** + +// IRIX 6.4 and below do not support reentrant netdb functions +// (getprotobyname_r, getprotobynumber_r, gethostbyaddr_r, +// gethostbyname_r, getservbyname_r). +#if (ACE_IRIX_VERS <= 64) && !defined (ACE_HAS_NETDB_REENTRANT_FUNCTIONS) +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#endif /* ACE_HAS_NETDB_REENTRANT_FUNCTIONS */ + +#define ACE_HAS_DIRENT +// Unless the thread enabled version is used the readdir_r interface +// does not get defined in IRIX 6.2 +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_RWLOCK_T + +#define ACE_HAS_GPERF + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_BROKEN_DGRAM_SENDV + +#define ACE_LACKS_PLACEMENT_OPERATOR_DELETE +#define ACE_PI_CONTROL_BLOCK_ALIGN_LONGS 2 + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// IRIX 6.5 supports AIO +#define ACE_HAS_AIO_CALLS +#define ACE_POSIX_AIOCB_PROACTOR +#define ACE_HAS_SGIDLADD +#define ACE_HAS_P_READ_WRITE +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_STDINT_H +#define ACE_HAS_SYSENT_H +#define ACE_HAS_SYSINFO +#define ACE_HAS_SYS_SYSTEMINFO_H + +// Platform has support for multi-byte character support compliant +// with the XPG4 Worldwide Portability Interface wide-character +// classification. +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +// We need to setup a very high address or Naming_Test won't run. +#define ACE_DEFAULT_BASE_ADDR ((char *) (1024U * 1024 * 1024)) + +#define ACE_LACKS_SIGNED_CHAR + +// Platform supports reentrant functions (i.e., all the POSIX *_r +// functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Platform does not support reentrant password file accessor functiions. +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS + +// uses ctime_r & asctime_r with only two parameters vs. three +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +#define ACE_HAS_UALARM + +// Scheduling functions are declared in +#define ACE_NEEDS_SCHED_H + +// Compile using multi-thread libraries by default +#if !defined (ACE_MT_SAFE) + #define ACE_MT_SAFE 1 +#endif /* ACE_MT_SAFE */ + +#if (ACE_MT_SAFE != 0) + +// Add threading support + +#define ACE_HAS_IRIX62_THREADS + +// Needed for the threading stuff? +#include /**/ +#define PTHREAD_MIN_PRIORITY PX_PRIO_MIN +#define PTHREAD_MAX_PRIORITY PX_PRIO_MAX + +// ACE supports threads. +#define ACE_HAS_THREADS + +// Platform has no implementation of pthread_condattr_setpshared(), +// even though it supports pthreads! (like Irix 6.2) +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_MUTEXATTR_PSHARED + +// IRIX 6.2 supports a variant of POSIX Pthreads, supposedly POSIX 1c +#define ACE_HAS_PTHREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// The pthread_cond_timedwait call does not reset the timer. +#define ACE_LACKS_COND_TIMEDWAIT_RESET 1 + +// When threads are enabled READDIR_R is supported on IRIX. +#undef ACE_LACKS_READDIR_R + +#endif /* (ACE_MT_SAFE == 0) */ + + +#endif /* ACE_CONFIG_IRIX6X_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-irix6.x-g++.h b/dep/ACE_wrappers/ace/config-irix6.x-g++.h new file mode 100644 index 000000000..2211e0e7c --- /dev/null +++ b/dep/ACE_wrappers/ace/config-irix6.x-g++.h @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// $Id: config-irix6.x-g++.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for the SGI +// Indigo2EX running Irix 6.2 platform using the GNU C++ Compiler + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +// config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so +// this must appear before its #include. +#define ACE_HAS_STRING_CLASS + +#include "ace/config-g++-common.h" +#include "ace/config-irix6.x-common.h" + +// Denotes that GNU has cstring.h as standard +// which redefines memchr() +#define ACE_HAS_GNU_CSTRING_H + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-irix6.x-sgic++.h b/dep/ACE_wrappers/ace/config-irix6.x-sgic++.h new file mode 100644 index 000000000..8bba07ac6 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-irix6.x-sgic++.h @@ -0,0 +1,36 @@ +/* -*- C++ -*- */ +// $Id: config-irix6.x-sgic++.h 81935 2008-06-12 22:01:53Z jtc $ + +// Use this file for IRIX 6.[234] if you have the pthreads patches +// installed. + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#include "ace/config-irix6.x-common.h" + +// This is the config file for IRIX 6.2, 6.4 and hopefully 6.3, using +// the SGI C++ compiler (7.1 or higher). + +// The following three should be enabled/disabled together. +#if _COMPILER_VERSION < 720 +#define ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA +#endif /* _COMPILER_VERSION < 720 */ +#define ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_NEEDS_FUNC_DEFINITIONS + +// Platform supports STREAM pipes (note that this is disabled by +// default, see the manual page on pipe(2) to find out how to enable +// it). +// #define ACE_HAS_STREAM_PIPES + +#if defined (_COMPILER_VERSION) +# define ACE_CC_NAME ACE_TEXT ("SGI/MIPSPro") +# define ACE_CC_MAJOR_VERSION (_COMPILER_VERSION / 100) +# define ACE_CC_MINOR_VERSION (_COMPILER_VERSION % 100) +# define ACE_CC_BETA_VERSION (0) +#endif /* _COMPILER_VERSION */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-linux-common.h b/dep/ACE_wrappers/ace/config-linux-common.h new file mode 100644 index 000000000..bbb10b175 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-linux-common.h @@ -0,0 +1,448 @@ +/* -*- C++ -*- */ +// $Id: config-linux-common.h 82516 2008-08-05 19:22:59Z shuston $ + +// Do not use this configuration file directly since it's designed to +// be included by another, specific configuration file, such as +// config-linux.h. It provides config information common to all Linux +// platforms. It automatically determines the CPU architecture, +// compiler (g++ or egcs), and libc (libc5 or glibc), and configures +// based on those. + +#ifndef ACE_LINUX_COMMON_H +#define ACE_LINUX_COMMON_H +#include /**/ "ace/pre.h" + +#define ACE_HAS_BYTESEX_H + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Needed to differentiate between libc 5 and libc 6 (aka glibc). +#include + +#if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) +# define ACE_HAS_PTHREADS_UNIX98_EXT +#endif /* _XOPEN_SOURCE - 0 >= 500 */ + +#if !defined (ACE_LACKS_LINUX_NPTL) + +# include "ace/config-posix.h" + + // Temporary fix because NPTL kernels do have shm_open but there is a problem + // with shm_open/shm_unlink pairing in ACE which needs to be fixed when I have time. +# if defined (ACE_HAS_SHM_OPEN) +# undef ACE_HAS_SHM_OPEN +# endif /* ACE_HAS_SHM_OPEN */ + +# if defined (ACE_USES_FIFO_SEM) + // Don't use this for Linux NPTL since this has complete + // POSIX semaphores which are more efficient +# undef ACE_USES_FIFO_SEM +# endif /* ACE_USES_FIFO_SEM */ + +# if defined (ACE_HAS_POSIX_SEM) + // Linux NPTL may not define the right POSIX macro + // but they have the actual runtime support for this stuff +# if !defined (ACE_HAS_POSIX_SEM_TIMEOUT) && (((_POSIX_C_SOURCE - 0) >= 200112L) || (_XOPEN_SOURCE >= 600)) +# define ACE_HAS_POSIX_SEM_TIMEOUT +# endif /* !ACE_HAS_POSIX_SEM_TIMEOUT && (((_POSIX_C_SOURCE - 0) >= 200112L) || (_XOPEN_SOURCE >= 600)) */ +# endif /* ACE_HAS_POSIX_SEM */ +#endif /* !ACE_LACKS_LINUX_NPTL */ + +// First the machine specific part + +#if defined (__powerpc__) || defined (__x86_64__) +# if !defined (ACE_DEFAULT_BASE_ADDR) +# define ACE_DEFAULT_BASE_ADDR ((char *) 0x40000000) +# endif /* ! ACE_DEFAULT_BASE_ADDR */ +#elif defined (__ia64) +# if !defined (ACE_DEFAULT_BASE_ADDR) +// Zero base address should work fine for Linux of IA-64: it just lets +// the kernel to choose the right value. +# define ACE_DEFAULT_BASE_ADDR ((char *) 0x0000000000000000) +# endif /* ! ACE_DEFAULT_BASE_ADDR */ +#endif /* ! __powerpc__ && ! __ia64 */ + +// Then glibc/libc5 specific parts + +#if defined(__GLIBC__) +# if (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1) +# define ACE_HAS_NONCONST_SETRLIMIT +# endif +# if (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 3) +# define ACE_HAS_RUSAGE_WHO_ENUM enum __rusage_who +# define ACE_HAS_RLIMIT_RESOURCE_ENUM enum __rlimit_resource +# endif +# define ACE_HAS_SOCKLEN_T +# define ACE_HAS_4_4BSD_SENDMSG_RECVMSG + + // glibc defines both of these, used in OS_String. +# if defined (_GNU_SOURCE) +# define ACE_HAS_STRNLEN +# define ACE_HAS_WCSNLEN + + // This is probably not a 100%-sure-fire check... Red Hat Linux 9 + // and Enterprise Linux 3 and up have a new kernel that can send signals + // across threads. This was not possible prior because there was no real + // difference between a process and a thread. With this, the + // ACE_POSIX_SIG_Proactor is the only chance of getting asynch I/O working. + // There are restrictions, such as all socket operations being silently + // converted to synchronous by the kernel, that make aio a non-starter + // for most Linux platforms at this time. But we'll start to crawl... +# define ACE_POSIX_SIG_PROACTOR +# endif + + // To avoid the strangeness with Linux's ::select (), which modifies + // its timeout argument, use ::poll () instead. +# define ACE_HAS_POLL + +// Don't define _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED in ACE to make +// getpgid() prototype visible. ACE shouldn't depend on feature test +// macros to make prototypes visible. +# define ACE_LACKS_GETPGID_PROTOTYPE + +// @note the following defines are necessary with glibc 2.0 (0.961212-5) +// on Alpha. I assume that they're necessary on Intel as well, +// but that may depend on the version of glibc that is used. +//# define ACE_HAS_DLFCN_H_BROKEN_EXTERN_C +# define ACE_HAS_VOIDPTR_SOCKOPT + +// Don't define _POSIX_SOURCE in ACE to make strtok() prototype +// visible. ACE shouldn't depend on feature test macros to make +// prototypes visible. +# define ACE_LACKS_STRTOK_R_PROTOTYPE +// @note end of glibc 2.0 (0.961212-5)-specific configuration. + +# if __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 + // These were suggested by Robert Hanzlik to get + // ACE to compile on Linux using glibc 2.1 and libg++/gcc 2.8. +# undef ACE_HAS_BYTESEX_H +# define ACE_HAS_SIGINFO_T +# define ACE_LACKS_SIGINFO_H +# define ACE_HAS_UCONTEXT_T + + // Pre-glibc (RedHat 5.2) doesn't have sigtimedwait. +# define ACE_HAS_SIGTIMEDWAIT +# endif /* __GLIBC__ 2.1+ */ +#else /* ! __GLIBC__ */ + // Fixes a problem with some non-glibc versions of Linux... +# define ACE_LACKS_MADVISE +# define ACE_LACKS_MSG_ACCRIGHTS +#endif /* ! __GLIBC__ */ + +// Don't define _LARGEFILE64_SOURCE in ACE to make llseek() or +// lseek64() prototype visible. ACE shouldn't depend on feature test +// macros to make prototypes visible. +#if __GLIBC__ > 1 +# if __GLIBC_MINOR__ == 0 +# define ACE_HAS_LLSEEK +# define ACE_LACKS_LLSEEK_PROTOTYPE +# else /* __GLIBC_MINOR__ > 0 */ +# define ACE_HAS_LSEEK64 +# define ACE_LACKS_LSEEK64_PROTOTYPE +# endif +#endif /* __GLIBC__ > 1 */ + +#if __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 +# define ACE_HAS_P_READ_WRITE +# define ACE_LACKS_PREAD_PROTOTYPE +// Use ACE's alternate cuserid() implementation since the use of the +// system cuserid() is discouraged. +# define ACE_HAS_ALT_CUSERID +#endif /* __GLIBC__ > 1 && __GLIBC_MINOR__ >= 0 */ + +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) +# define ACE_HAS_ISASTREAM_PROTOTYPE +# define ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE +# define ACE_HAS_CPU_SET_T +#endif /* __GLIBC__ > 2 || __GLIBC__ === 2 && __GLIBC_MINOR__ >= 3) */ + +// Then the compiler specific parts + +#if defined (__INTEL_COMPILER) +# include "ace/config-icc-common.h" +#elif defined (__GNUG__) + // config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so + // this must appear before its #include. +# define ACE_HAS_STRING_CLASS +# include "ace/config-g++-common.h" +#define ACE_CC_NAME ACE_TEXT ("g++") +#define ACE_CC_MAJOR_VERSION __GNUC__ +#define ACE_CC_MINOR_VERSION __GNUC_MINOR__ +//#define ACE_CC_BETA_VERSION 0 /* ??? */ +#elif defined (__DECCXX) +# define ACE_CONFIG_INCLUDE_CXX_COMMON +# include "ace/config-cxx-common.h" +#elif defined (__BORLANDC__) +# undef ACE_HAS_LLSEEK +# undef ACE_HAS_LSEEK64 +# undef ACE_LACKS_LLSEEK_PROTOTYPE +# undef ACE_LACKS_LSEEK64_PROTOTYPE +# include "ace/config-borland-common.h" +#elif defined (__SUNCC_PRO) +# include "ace/config-suncc-common.h" +#elif defined (__PGI) +// Portable group compiler +# define ACE_HAS_CPLUSPLUS_HEADERS +# define ACE_HAS_STDCPP_STL_INCLUDES +# define ACE_HAS_TEMPLATE_TYPEDEFS +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_LACKS_SWAB +#elif defined (__GNUC__) +/** + * GNU C compiler. + * + * We need to recognize the GNU C compiler since TAO has at least one + * C source header and file + * (TAO/orbsvcs/orbsvcs/SSLIOP/params_dup.{h,c}) that may indirectly + * include this + */ +#else /* ! __GNUG__ && !__DECCXX && !__INTEL_COMPILER && !__BORLANDC__ && !__PGI */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler in ace/config-linux-common.h +# endif /* __cplusplus */ +#endif /* ! __GNUG__*/ + +// Completely common part :-) + +// Platform/compiler has the sigwait(2) prototype +# define ACE_HAS_SIGWAIT + +# define ACE_HAS_SIGSUSPEND + +# define ACE_HAS_UALARM + +#if __GLIBC__ >= 2 +#ifndef ACE_HAS_POSIX_REALTIME_SIGNALS +#define ACE_HAS_POSIX_REALTIME_SIGNALS +#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */ + +#ifndef ACE_HAS_AIO_CALLS +#define ACE_HAS_AIO_CALLS +#endif /* ACE_HAS_AIO_CALLS */ +#endif + +#if __GLIBC__ >= 2 +// glibc 2 and higher has wchar support +# define ACE_HAS_XPG4_MULTIBYTE_CHAR +# define ACE_HAS_VFWPRINTF +#endif + +#if __GLIBC__ < 2 +// These are present in glibc 2 and higher +# define ACE_LACKS_WCSTOK +# define ACE_LACKS_WCSDUP_PROTOTYPE +#endif /* __GLIBC__ < 2 */ + +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP + +#if __GLIBC__ >= 2 +# define ACE_HAS_3_PARAM_WCSTOK +#endif + +#define ACE_HAS_3_PARAM_READDIR_R + +#if !defined (ACE_DEFAULT_BASE_ADDR) +# define ACE_DEFAULT_BASE_ADDR ((char *) 0x80000000) +#endif /* ! ACE_DEFAULT_BASE_ADDR */ + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_SYS_SYSINFO_H +#define ACE_HAS_LINUX_SYSINFO + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE +#define ACE_HAS_GETRUSAGE_PROTOTYPE + +#define ACE_HAS_BYTESWAP_H +#define ACE_HAS_BSWAP_16 +#define ACE_HAS_BSWAP_32 + +#if defined __GNUC__ && __GNUC__ >= 2 +# define ACE_HAS_BSWAP_64 +#endif + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// ONLY define this if you have config'd multicast into a 2.0.34 or +// prior kernel. It is enabled by default in 2.0.35 kernels. +#if !defined (ACE_HAS_IP_MULTICAST) +# define ACE_HAS_IP_MULTICAST +#endif /* ! ACE_HAS_IP_MULTICAST */ + +// At least for IPv4, Linux lacks perfect filtering. +#if !defined ACE_LACKS_PERFECT_MULTICAST_FILTERING +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING */ + +#define ACE_HAS_BIG_FD_SET + +// Linux defines struct msghdr in /usr/include/socket.h +#define ACE_HAS_MSG + +// Linux "improved" the interface to select() so that it modifies +// the struct timeval to reflect the amount of time not slept +// (see NOTES in Linux's select(2) man page). +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 65535 + +#define ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE 1 + +#define ACE_HAS_GETPAGESIZE 1 + +#if (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) +// glibc supports wchar, but lacks fgetwc and ungetwc +# define ACE_LACKS_FGETWC +# define ACE_HAS_NONCONST_MSGSND +# define ACE_LACKS_STRNLEN_PROTOTYPE +#endif + +// glibc requires _XOPEN_SOURCE_EXTENDED to make this prototype +// visible, so force ACE to declare one. Yuk! +#ifndef _XOPEN_SOURCE_EXTENDED +# define ACE_LACKS_MKSTEMP_PROTOTYPE +#endif /* !_XOPEN_SOURCE_EXTENDED */ + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +// Platform supplies scandir() +#define ACE_HAS_SCANDIR +// Although the scandir man page says otherwise, this setting is correct. +#define ACE_SCANDIR_CMP_USES_CONST_VOIDPTR + +// A conflict appears when including both and +// with recent glibc headers. +//#define ACE_HAS_PROC_FS + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Platform/compiler supports global timezone variable. +#define ACE_HAS_TIMEZONE + +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Don't define _XOPEN_SOURCE in ACE to make strptime() prototype +// visible. ACE shouldn't depend on feature test macros to make +// prototypes visible. +#define ACE_LACKS_STRPTIME_PROTOTYPE + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +#define ACE_HAS_POSIX_TIME + +#define ACE_HAS_GPERF + +#define ACE_HAS_DIRENT + +// Starting with FC9 rawhide this file is not available anymore but +// this define is set +#if defined _XOPEN_STREAMS && _XOPEN_STREAMS == -1 +# define ACE_LACKS_STROPTS_H +# define ACE_LACKS_STRRECVFD +#endif + +#if !defined (ACE_LACKS_STROPTS_H) +# define ACE_HAS_STRBUF_T +#endif + +#if defined (__ia64) || defined(__alpha) || defined (__x86_64__) +// On 64 bit platforms, the "long" type is 64-bits. Override the +// default 32-bit platform-specific format specifiers appropriately. +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%lu") +# define ACE_SSIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%ld") +# define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%lu") +#endif /* __ia64 */ + +#define ACE_SIZEOF_WCHAR 4 + +#define ACE_LACKS_GETIPNODEBYADDR +#define ACE_LACKS_GETIPNODEBYNAME + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// Linux implements sendfile(). +#define ACE_HAS_SENDFILE + +#define ACE_HAS_VOIDPTR_MMAP + +#if defined (ACE_LACKS_NETWORKING) +# include "ace/config-posix-nonetworking.h" +#else +# define ACE_HAS_NETLINK +# define ACE_HAS_GETIFADDRS +#endif + +#if !defined (ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO) +// Detect if getsockname() and getpeername() returns random values in +// the sockaddr_in::sin_zero field by evaluation of the kernel +// version. Since version 2.5.47 this problem is fixed. +# if !defined (ACE_LACKS_LINUX_VERSION_H) +# include +# endif /* !ACE_LACKS_LINUX_VERSION_H */ +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47)) +# define ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO 0 +# else +# define ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO 1 +# endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,47)) */ +#endif /* ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO */ + +#if defined (ACE_HAS_EVENT_POLL) +// The sys_epoll interface was introduced in Linux kernel 2.5.45. +// Don't support backported versions since they appear to be buggy. +// The obsolete ioctl()-based interface is no longer supported. +#if 0 +// linux/version.h may not be accurate. It's not for Fedora Core 2... +# if !defined (ACE_LACKS_LINUX_VERSION_H) +# include +# endif /* !ACE_LACKS_LINUX_VERSION_H */ +# if (LINUX_VERSION_CODE < KERNEL_VERSION (2,5,45)) +# undef ACE_HAS_EVENT_POLL +# error Disabling Linux epoll support. Kernel used in C library is too old. +# error Linux kernel 2.5.45 or better is required. +# endif /* LINUX_VERSION_CODE < KERNEL_VERSION (2,5,45) */ +#endif /* ACE_HAS_EVENT_POLL */ +#endif + +#if !defined (ACE_HAS_EVENT_POLL) && !defined (ACE_HAS_DEV_POLL) +# if !defined (ACE_LACKS_LINUX_VERSION_H) +# include +# endif /* !ACE_LACKS_LINUX_VERSION_H */ +# if (LINUX_VERSION_CODE > KERNEL_VERSION (2,6,0)) +# define ACE_HAS_EVENT_POLL +# endif +#endif + +#include /**/ "ace/post.h" + +#endif /* ACE_LINUX_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-linux.h b/dep/ACE_wrappers/ace/config-linux.h new file mode 100644 index 000000000..8b79c13a4 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-linux.h @@ -0,0 +1,75 @@ +// -*- C++ -*- +// +// $Id: config-linux.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for Linux +// platforms using GNU C++. + +#ifndef ACE_CONFIG_LINUX_H +#define ACE_CONFIG_LINUX_H +#include /**/ "ace/pre.h" + +#define ACE_PLATFORM_CONFIG config-linux.h + +#include "ace/config-linux-common.h" + +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE + +#if !defined (ACE_MT_SAFE) +#define ACE_MT_SAFE 1 // JCEJ 12/22/96 #1 +#endif + +#if ACE_MT_SAFE +// Yes, we do have threads. +#define ACE_HAS_THREADS +// And they're even POSIX pthreads (LinuxThreads implementation) +#define ACE_HAS_PTHREADS + +// On linux this is part of pthreads +# if (defined _POSIX_C_SOURCE && (_POSIX_C_SOURCE - 0) >= 199309L) +# if !defined (ACE_HAS_CLOCK_GETTIME) +# if !defined(__PGI) +# define ACE_HAS_CLOCK_GETTIME +# endif /* __PGI */ +# define ACE_HAS_CLOCK_SETTIME +# endif /* !ACE_HAS_CLOCK_GETTIME */ +# endif /* _POSIX_C_SOURCE >= 199309L */ + +#if !defined (ACE_HAS_PTHREADS_UNIX98_EXT) +# define ACE_LACKS_RWLOCK_T +#else +# define ACE_HAS_RECURSIVE_MUTEXES +#endif /* !ACE_HAS_PTHREADS_UNIX98_EXT */ + +#define ACE_HAS_THREAD_SPECIFIC_STORAGE // jcej 12/22/96 #2 + +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS // JCEJ 1/7-8/96 + +#if defined(__GLIBC__) +// Platform supports reentrant functions (i.e., all the POSIX *_r +// functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +#if (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1) + // Older versions of glibc lacked reentrant netdb functions +# define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS + + // glibc < 2.1 lacks pthread_attr_setstacksize() +# define ACE_LACKS_PTHREAD_ATTR_SETSTACKSIZE +#endif /* (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1) */ + +// uses ctime_r & asctime_r with only two parameters vs. three +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#endif + +#else +// AIO support pulls in the rt library, which pulls in the pthread +// library. Disable AIO in single-threaded builds. +# undef ACE_HAS_AIO_CALLS +#endif /* ACE_MT_SAFE */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_LINUX_H */ diff --git a/dep/ACE_wrappers/ace/config-lite.h b/dep/ACE_wrappers/ace/config-lite.h new file mode 100644 index 000000000..0992925a6 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-lite.h @@ -0,0 +1,164 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file config-lite.h + * + * $Id: config-lite.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author (Originally in OS.h)Doug Schmidt + * @author Jesper S. M|ller + * @author and a cast of thousands... + * + * This file contains the contents of the old config-all.h in order to + * avoid a circular dependency problem caused by some of the new + * includes added to config-all.h, e.g., OS_main.h. + */ +//========================================================================== + +#ifndef ACE_CONFIG_LITE_H +#define ACE_CONFIG_LITE_H + +#include /**/ "ace/pre.h" + +#include "ace/config-macros.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Empty ACE_OS namespace to help identify compiler errors more +// easily. -- @@ Do we really need this? +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +namespace ACE_OS {} +ACE_END_VERSIONED_NAMESPACE_DECL + +// ============================================================================ +// UNICODE macros (to be added later) +// ============================================================================ + +// Get the unicode (i.e. ACE_TCHAR) defines +# include "ace/ace_wchar.h" + +// ============================================================================ +// at_exit declarations +// ============================================================================ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Marker for cleanup, used by ACE_Exit_Info. +extern int ace_exit_hook_marker; + +ACE_END_VERSIONED_NAMESPACE_DECL + +// For use by . +extern "C" +{ + typedef void (*ACE_EXIT_HOOK) (void); +} + +// Signature for registering a cleanup function that is used by the +// ACE_Object_Manager and the ACE_Thread_Manager. +# if defined (ACE_HAS_SIG_C_FUNC) +extern "C" { +# endif /* ACE_HAS_SIG_C_FUNC */ +typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */; +# if defined (ACE_HAS_SIG_C_FUNC) +} +# endif /* ACE_HAS_SIG_C_FUNC */ + +// ============================================================================ +// log_msg declarations +// ============================================================================ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) +typedef int (*ACE_SEH_EXCEPT_HANDLER)(void *); +// Prototype of win32 structured exception handler functions. +// They are used to get the exception handling expression or +// as exception handlers. +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + +class ACE_OS_Thread_Descriptor; +class ACE_OS_Log_Msg_Attributes; +typedef void (*ACE_INIT_LOG_MSG_HOOK) (ACE_OS_Log_Msg_Attributes &attr +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , ACE_SEH_EXCEPT_HANDLER selector + , ACE_SEH_EXCEPT_HANDLER handler +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + ); +typedef void (*ACE_INHERIT_LOG_MSG_HOOK) (ACE_OS_Thread_Descriptor*, + ACE_OS_Log_Msg_Attributes &); + +typedef void (*ACE_CLOSE_LOG_MSG_HOOK) (void); + +typedef void (*ACE_SYNC_LOG_MSG_HOOK) (const ACE_TCHAR *prog_name); + +typedef ACE_OS_Thread_Descriptor *(*ACE_THR_DESC_LOG_MSG_HOOK) (void); + +ACE_END_VERSIONED_NAMESPACE_DECL + +/** + * @deprecated ACE_DECLARE_STL_REVERSE_ITERATORS is a crutch to be + * used until all C++ compiler supported by ACE support + * the standard reverse_iterator adapters. + * @internal ACE_DECLARE_STL_REVERSE_ITERATORS is not meant for use + * outside of ACE. + */ +// STL reverse_iterator declaration generator +// Make sure you include in the file you're using this +// generator, and that the following traits are available: +// +// iterator +// const_iterator +// value_type +// reference +// pointer +// const_reference +// const_pointer +// difference_type +// +// Once all C++ compilers support the standard reverse_iterator +// adapters, we can drop this generator macro or at least drop the +// MSVC++ or Sun Studio preprocessor conditional blocks. +#if defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x590 \ + && !defined (_STLPORT_VERSION) + // If we're not using the stlport4 C++ library (which has standard + // iterators), we need to ensure this is included in order to test + // the _RWSTD_NO_CLASS_PARTIAL_SPEC feature test macro below. +# include +#endif /* __SUNPRO_CC <= 0x580 */ +#if (defined (_MSC_VER) && (_MSC_VER <= 1310) && defined (_WIN64)) \ + || defined (ACE_HAS_BROKEN_STD_REVERSE_ITERATOR) + // VC 7.1 and the latest 64-bit platform SDK still don't define a standard + // compliant reverse_iterator adapter. +# define ACE_DECLARE_STL_REVERSE_ITERATORS \ + typedef std::reverse_iterator reverse_iterator; \ + typedef std::reverse_iterator const_reverse_iterator; +#elif defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x590 \ + && defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) +# define ACE_DECLARE_STL_REVERSE_ITERATORS \ + typedef std::reverse_iterator reverse_iterator; \ + typedef std::reverse_iterator const_reverse_iterator; +#else +# define ACE_DECLARE_STL_REVERSE_ITERATORS \ + typedef std::reverse_iterator reverse_iterator; \ + typedef std::reverse_iterator const_reverse_iterator; +#endif /* _MSC_VER && _WIN64 */ + + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_LITE_H */ diff --git a/dep/ACE_wrappers/ace/config-lynxos.h b/dep/ACE_wrappers/ace/config-lynxos.h new file mode 100644 index 000000000..c65e9b0f7 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-lynxos.h @@ -0,0 +1,162 @@ +// $Id: config-lynxos.h 81780 2008-05-26 13:56:49Z olli $ + +// The following configuration file is designed to work for LynxOS, +// version 4.0.0 and later, using the GNU g++ compiler. + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +// Compile using multi-thread libraries. +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#include "ace/config-posix.h" + +#if defined (__x86__) +# define ACE_HAS_PENTIUM +#elif defined (__powerpc__) + // It looks like the default stack size is 15000. + // ACE's Recursive_Mutex_Test needs more. +# define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 + // This doesn't work on LynxOS 3.0.0, because it resets the TimeBaseRegister. + // # define ACE_HAS_POWERPC_TIMER +#endif /* __x86__ || __powerpc__ */ + +#define ACE_DEFAULT_BASE_ADDR ((char *) 0) +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_ALLOCA +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK 1 +#define ACE_HAS_BROKEN_SIGEVENT_STRUCT +#define ACE_HAS_CHARPTR_SHMAT +#define ACE_HAS_CHARPTR_SHMDT +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_GETPAGESIZE +#define ACE_HAS_GETRUSAGE +#define ACE_HAS_GNU_CSTRING_H +#define ACE_HAS_GPERF +#define ACE_HAS_ICMP_SUPPORT 1 +#define ACE_HAS_IP_MULTICAST +#define ACE_HAS_LYNXOS_SIGNALS +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_CLOCK_SETTIME +#define ACE_HAS_NONCONST_MSGSND +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONCONST_SETRLIMIT +#define ACE_HAS_NONCONST_WRITEV +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +#define ACE_HAS_SCANDIR +#define ACE_HAS_SEMUN +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRBUF_T +#define ACE_HAS_STREAMS +#define ACE_HAS_STRERROR +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_SYS_SIGLIST +#define ACE_HAS_SYS_SOCKIO_H +#define ACE_HAS_TERMIOS +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_LACKS_ALPHASORT_PROTOTYPE +#define ACE_LACKS_CONST_TIMESPEC_PTR +#define ACE_LACKS_GETPGID +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MKSTEMP_PROTOTYPE +#define ACE_LACKS_MKTEMP_PROTOTYPE +#define ACE_LACKS_PUTENV_PROTOTYPE +#define ACE_LACKS_REALPATH +#define ACE_LACKS_RLIMIT_NOFILE +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SCANDIR_PROTOTYPE +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_STRPTIME +#define ACE_LACKS_SUSECONDS_T +#define ACE_LACKS_SWAB_PROTOTYPE +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_USECONDS_T +#define ACE_LACKS_VSNPRINTF +#define ACE_LACKS_WCHAR_H +#define ACE_MALLOC_ALIGN 8 +#define ACE_PAGE_SIZE 4096 +#define ACE_POSIX_SIG_PROACTOR +#define ACE_SCANDIR_CMP_USES_CONST_VOIDPTR + +// LynxOS has poll.h but it is unusable since implementation is not provided +#define ACE_LACKS_POLL_H + +#if ACE_MT_SAFE == 1 + // Platform supports threads. +# define ACE_HAS_PTHREADS +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_LACKS_NULL_PTHREAD_STATUS +# define ACE_LACKS_THREAD_PROCESS_SCOPING +# define ACE_LACKS_PTHREAD_ATTR_SETSTACK +# if ACE_LYNXOS_MAJOR == 4 && ACE_LYNXOS_MINOR == 0 +# define ACE_LACKS_SETDETACH +# define ACE_LACKS_PTHREAD_ATTR_SETSTACKADDR +# endif +#endif /* ACE_MT_SAFE */ + +#if __GNUC__ < 3 +# define ACE_LACKS_NUMERIC_LIMITS +#endif /* __GNUC__ < 3 */ + +// By default, don't include RCS Id strings in object code. +#if !defined (ACE_USE_RCSID) +# define ACE_USE_RCSID 0 +#endif /* ! ACE_USE_RCSID */ + +// System include files are not in sys/, this gets rid of warning. +#define __NO_INCLUDE_WARN__ + +// "changes signedness" error (OS.i and many other files) +#define ACE_HAS_SOCKLEN_T +// LSOCK.cpp uses a macro from param.h, not included +#define ALIGNBYTES (sizeof(int) - 1) +#define ALIGN(p) (((unsigned)p + ALIGNBYTES) & ~ALIGNBYTES) + +#if ACE_LYNXOS_MAJOR == 4 && ACE_LYNXOS_MINOR == 0 +# define ACE_LACKS_GETOPT_PROTOTYPE +# define ACE_LACKS_INET_ATON_PROTOTYPE +# define ACE_LACKS_REGEX_H +# define ACE_LACKS_STRCASECMP_PROTOTYPE +# define ACE_LACKS_STRNCASECMP_PROTOTYPE +# define ACE_LACKS_SYS_SELECT_H +# define ACE_HAS_NONCONST_GETBY +#endif + +#if (ACE_LYNXOS_MAJOR > 4) || (ACE_LYNXOS_MAJOR == 4 && ACE_LYNXOS_MINOR >= 2) +// LynxOS 4.2 additons +# define ACE_HAS_POSIX_SEM_TIMEOUT +# define ACE_HAS_MUTEX_TIMEOUTS +#endif + +#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) +# define ACE_HAS_BROKEN_THREAD_KEYFREE +#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-macosx-leopard.h b/dep/ACE_wrappers/ace/config-macosx-leopard.h new file mode 100644 index 000000000..a56067b97 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-macosx-leopard.h @@ -0,0 +1,227 @@ +/* -*- C++ -*- */ +// $Id: config-macosx-leopard.h 81858 2008-06-07 03:31:22Z dai_y $ + +// This configuration file is designed to work with the MacOS X operating system. + +#ifndef ACE_CONFIG_MACOSX_LEOPARD_H +#define ACE_CONFIG_MACOSX_LEOPARD_H + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#if !defined (ACE_SIZEOF_LONG_DOUBLE) +# if (__GNUC__ == 3 && __GNUC_MINOR__ == 3) + // Size of long double in GCC 3.3 is 8. +# define ACE_SIZEOF_LONG_DOUBLE 8 +# else // Else, the compiler is GCC4 + // For GCC4, the size is 16. +# define ACE_SIZEOF_LONG_DOUBLE 16 +# endif // GCC 3.3 +#endif // ACE_SIZEOF_LONG_DOUBLE + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +#ifndef ACE_HAS_NONCONST_FD_ISSET +#define ACE_HAS_NONCONST_FD_ISSET +#endif + +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR + +#define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%lu") + +#if !defined (__i386__) +# if defined (ACE_HAS_PENTIUM) +# undef ACE_HAS_PENTIUM +# endif /* ACE_HAS_PENTIUM */ +#else // __i386__ +# define ACE_HAS_PENTIUM +#endif //__i386__ + +#if !defined (_THREAD_SAFE) +#define _THREAD_SAFE +#endif /* _THREAD_SAFE */ + +#define ACE_HAS_GPERF +#define ACE_HAS_POSIX_SEM + +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +#define ACE_LACKS_STROPTS_H + +// Platform provides header. +#define ACE_HAS_EXECINFO_H + +// Wcharness.... +#define ACE_HAS_WCHAR +#define ACE_SIZEOF_WCHAR 4 + + +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSDUP + +// Mac lacks the following pthread features +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_CONDATTR_PSHARED +// +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports SVR4 signal typedef +#define ACE_HAS_SVR4_SIGNAL_T + +//Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +#define ACE_HAS_AIO_CALLS + +//Platform supports sigsuspend() +#define ACE_HAS_SIGSUSPEND + +//Platform/compiler has macros for sig{empty,fill,add,del}set (e.g., SCO and FreeBSD) +#define ACE_HAS_SIG_MACROS + +#define ACE_LACKS_GETPGID +#define ACE_LACKS_RWLOCK_T + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +//? +#define ACE_LACKS_SIGSET + +#define ACE_NEEDS_SCHED_H + +// Use of is deprecated. +#define ACE_LACKS_MALLOC_H + +#define ACE_HAS_ALT_CUSERID + +// Platform supports POSIX timers via struct timespec. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_UALARM + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +#define ACE_LACKS_STRRECVFD + +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// platform supports IP multicast +#define ACE_HAS_IP_MULTICAST +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Compiler/platform provides the socklen_t type. +#define ACE_HAS_SOCKLEN_T + +// Defines the page size of the system. +#define ACE_HAS_GETPAGESIZE + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform/compiler supports timezone * as second parameter to gettimeofday(). +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_MSQ_PROTOS +#define ACE_HAS_MSG +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_MSGSND + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#if ACE_MT_SAFE == 1 +// Yes, we do have threads. +# define ACE_HAS_THREADS +// And they're even POSIX pthreads +# define ACE_HAS_PTHREADS +# define ACE_HAS_PTHREADS_STD +# define ACE_HAS_PTHREAD_SCHEDPARAM +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +#endif /* ACE_MT_SAFE == 1 */ + +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +#define ACE_HAS_DIRENT +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SEARCH_H + +#define ACE_LACKS_SETSCHED +//#define ACE_HAS_RECURSIVE_MUTEXES + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#define ACE_HAS_SEMUN +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_GETIFADDRS +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_UNNAMED_SEMAPHORE + +// dlcompat package (not part of base Darwin) is needed for dlopen(). +// You may download directly from sourceforge and install or use fink +// Fink installer puts libraries in /sw/lib and headers in /sw/include +// In order to install dlcompat do the following: +// - download fink from http://fink.sf.net +// - type: +// fink install dlcompat +// as of Dec 2002, if you use fink you will need to uncomment the next line +// #define ACE_NEEDS_DL_UNDERSCORE +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_LD_SEARCH_PATH ACE_TEXT ("DYLD_LIBRARY_PATH") +#define ACE_DLL_SUFFIX ACE_TEXT (".dylib") +//#define ACE_LACKS_DLCLOSE + +// gperf seems to need this +//#define ACE_HAS_NONSTATIC_OBJECT_MANAGER + +#if defined(__APPLE_CC__) && (__APPLE_CC__ < 1173) +#error "Compiler must be upgraded, see http://developer.apple.com" +#endif /* __APPLE_CC__ */ + +#endif /* ACE_CONFIG_MACOSX_TIGER_H */ diff --git a/dep/ACE_wrappers/ace/config-macosx-panther.h b/dep/ACE_wrappers/ace/config-macosx-panther.h new file mode 100644 index 000000000..8b4010e79 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-macosx-panther.h @@ -0,0 +1,191 @@ +/* -*- C++ -*- */ +// $Id: config-macosx-panther.h 80826 2008-03-04 14:51:23Z wotte $ + +// This configuration file is designed to work with the MacOS X operating system. + +#ifndef ACE_CONFIG_MACOSX_H +#define ACE_CONFIG_MACOSX_H + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +#define ACE_LACKS_SUSECONDS_T +#define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%lu") + +#if defined (ACE_HAS_PENTIUM) +# undef ACE_HAS_PENTIUM +#endif /* ACE_HAS_PENTIUM */ + +#if !defined (_THREAD_SAFE) +#define _THREAD_SAFE +#endif /* _THREAD_SAFE */ + +#define ACE_HAS_GPERF +#define ACE_HAS_POSIX_SEM + +//#define ACE_HAS_SVR4_TLI + +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_WCHAR_H + +// +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports SVR4 signal typedef +#define ACE_HAS_SVR4_SIGNAL_T + +//Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +//Platform supports sigsuspend() +#define ACE_HAS_SIGSUSPEND + +//Platform/compiler has macros for sig{empty,fill,add,del}set (e.g., SCO and FreeBSD) +#define ACE_HAS_SIG_MACROS + +//#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +#define ACE_LACKS_GETPGID +#define ACE_LACKS_RWLOCK_T + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +//? +#define ACE_LACKS_SIGSET + +#define ACE_NEEDS_SCHED_H + +// Use of is deprecated. +#define ACE_LACKS_MALLOC_H + +#define ACE_HAS_ALT_CUSERID + +// Platform supports POSIX timers via struct timespec. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_UALARM + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +#define ACE_LACKS_STRRECVFD + +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Explicit dynamic linking permits "lazy" symbol resolution +//#define ACE_HAS_RTLD_LAZY_V + +// platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// platform supports IP multicast +#define ACE_HAS_IP_MULTICAST +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Defines the page size of the system. +#define ACE_HAS_GETPAGESIZE + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform/compiler supports timezone * as second parameter to gettimeofday(). +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_MSQ_PROTOS +#define ACE_HAS_MSG +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_MSGSND + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#if ACE_MT_SAFE == 1 +// Yes, we do have threads. +# define ACE_HAS_THREADS +// And they're even POSIX pthreads +# define ACE_HAS_PTHREADS +# define ACE_HAS_PTHREAD_SCHEDPARAM +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +#endif /* ACE_MT_SAFE == 1 */ + +# define ACE_LACKS_THREAD_PROCESS_SCOPING + +#define ACE_HAS_DIRENT +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SEARCH_H + +#define ACE_LACKS_SETSCHED +//#define ACE_HAS_RECURSIVE_MUTEXES + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#define ACE_HAS_SEMUN +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_GETIFADDRS +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_UNNAMED_SEMAPHORE + +// dlcompat package (not part of base Darwin) is needed for dlopen(). +// You may download directly from sourceforge and install or use fink +// Fink installer puts libraries in /sw/lib and headers in /sw/include +// In order to install dlcompat do the following: +// - download fink from http://fink.sf.net +// - type: +// fink install dlcompat +// as of Dec 2002, if you use fink you will need to uncomment the next line +//#define ACE_NEEDS_DL_UNDERSCORE +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_LD_SEARCH_PATH ACE_TEXT ("DYLD_LIBRARY_PATH") +#define ACE_DLL_SUFFIX ACE_TEXT (".dylib") +//#define ACE_LACKS_DLCLOSE + +// gperf seems to need this +//#define ACE_HAS_NONSTATIC_OBJECT_MANAGER + +#if defined(__APPLE_CC__) && (__APPLE_CC__ < 1173) +#error "Compiler must be upgraded, see http://developer.apple.com" +#endif /* __APPLE_CC__ */ + +#endif /* ACE_CONFIG_MACOSX_H */ diff --git a/dep/ACE_wrappers/ace/config-macosx-tiger.h b/dep/ACE_wrappers/ace/config-macosx-tiger.h new file mode 100644 index 000000000..f920690ed --- /dev/null +++ b/dep/ACE_wrappers/ace/config-macosx-tiger.h @@ -0,0 +1,219 @@ +/* -*- C++ -*- */ +// $Id: config-macosx-tiger.h 82344 2008-07-19 20:04:18Z johnnyw $ + +// This configuration file is designed to work with the MacOS X operating system. + +#ifndef ACE_CONFIG_MACOSX_TIGER_H +#define ACE_CONFIG_MACOSX_TIGER_H + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#if !defined (ACE_SIZEOF_LONG_DOUBLE) +# if (__GNUC__ == 3 && __GNUC_MINOR__ == 3) + // Size of long double in GCC 3.3 is 8. +# define ACE_SIZEOF_LONG_DOUBLE 8 +# else // Else, the compiler is GCC4 + // For GCC4, the size is 16. +# define ACE_SIZEOF_LONG_DOUBLE 16 +# endif // GCC 3.3 +#endif // ACE_SIZEOF_LONG_DOUBLE + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR + +#define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%lu") + +#if !defined (__i386__) +# if defined (ACE_HAS_PENTIUM) +# undef ACE_HAS_PENTIUM +# endif /* ACE_HAS_PENTIUM */ +#else // __i386__ +# define ACE_HAS_PENTIUM +#endif //__i386__ + +#if !defined (_THREAD_SAFE) +#define _THREAD_SAFE +#endif /* _THREAD_SAFE */ + +#define ACE_HAS_GPERF +#define ACE_HAS_POSIX_SEM + +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +#define ACE_LACKS_STROPTS_H + +// Wcharness.... +#define ACE_HAS_WCHAR +#define ACE_SIZEOF_WCHAR 4 + + +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSDUP + +// Mac lacks the following pthread features +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_CONDATTR_PSHARED +// +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports SVR4 signal typedef +#define ACE_HAS_SVR4_SIGNAL_T + +//Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +#define ACE_HAS_AIO_CALLS + +//Platform supports sigsuspend() +#define ACE_HAS_SIGSUSPEND + +//Platform/compiler has macros for sig{empty,fill,add,del}set (e.g., SCO and FreeBSD) +#define ACE_HAS_SIG_MACROS + +#define ACE_LACKS_GETPGID +#define ACE_LACKS_RWLOCK_T + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +//? +#define ACE_LACKS_SIGSET + +#define ACE_NEEDS_SCHED_H + +// Use of is deprecated. +#define ACE_LACKS_MALLOC_H + +#define ACE_HAS_ALT_CUSERID + +// Platform supports POSIX timers via struct timespec. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_UALARM + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +#define ACE_LACKS_STRRECVFD + +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// platform supports IP multicast +#define ACE_HAS_IP_MULTICAST +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Compiler/platform provides the socklen_t type. +#define ACE_HAS_SOCKLEN_T + +// Defines the page size of the system. +#define ACE_HAS_GETPAGESIZE + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform/compiler supports timezone * as second parameter to gettimeofday(). +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_MSQ_PROTOS +#define ACE_HAS_MSG +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_MSGSND + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#if ACE_MT_SAFE == 1 +// Yes, we do have threads. +# define ACE_HAS_THREADS +// And they're even POSIX pthreads +# define ACE_HAS_PTHREADS +# define ACE_HAS_PTHREAD_SCHEDPARAM +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +#endif /* ACE_MT_SAFE == 1 */ + +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +#define ACE_HAS_DIRENT +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SEARCH_H + +#define ACE_LACKS_SETSCHED +//#define ACE_HAS_RECURSIVE_MUTEXES + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#define ACE_HAS_SEMUN +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_GETIFADDRS +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_UNNAMED_SEMAPHORE + +// dlcompat package (not part of base Darwin) is needed for dlopen(). +// You may download directly from sourceforge and install or use fink +// Fink installer puts libraries in /sw/lib and headers in /sw/include +// In order to install dlcompat do the following: +// - download fink from http://fink.sf.net +// - type: +// fink install dlcompat +// as of Dec 2002, if you use fink you will need to uncomment the next line +// #define ACE_NEEDS_DL_UNDERSCORE +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_LD_SEARCH_PATH ACE_TEXT ("DYLD_LIBRARY_PATH") +#define ACE_DLL_SUFFIX ACE_TEXT (".dylib") +//#define ACE_LACKS_DLCLOSE + +// gperf seems to need this +//#define ACE_HAS_NONSTATIC_OBJECT_MANAGER + +#if defined(__APPLE_CC__) && (__APPLE_CC__ < 1173) +#error "Compiler must be upgraded, see http://developer.apple.com" +#endif /* __APPLE_CC__ */ + +#endif /* ACE_CONFIG_MACOSX_TIGER_H */ diff --git a/dep/ACE_wrappers/ace/config-macosx.h b/dep/ACE_wrappers/ace/config-macosx.h new file mode 100644 index 000000000..904eae5ac --- /dev/null +++ b/dep/ACE_wrappers/ace/config-macosx.h @@ -0,0 +1,191 @@ +/* -*- C++ -*- */ +// $Id: config-macosx.h 80826 2008-03-04 14:51:23Z wotte $ + +// This configuration file is designed to work with the MacOS X operating system, version 10.2 (Jaguar). + +#ifndef ACE_CONFIG_MACOSX_H +#define ACE_CONFIG_MACOSX_H + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +#define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%lu") + +#if defined (ACE_HAS_PENTIUM) +# undef ACE_HAS_PENTIUM +#endif /* ACE_HAS_PENTIUM */ + +#if !defined (_THREAD_SAFE) +#define _THREAD_SAFE +#endif /* _THREAD_SAFE */ + +#define ACE_HAS_GPERF +#define ACE_HAS_POSIX_SEM + +//#define ACE_HAS_SVR4_TLI + +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_WCHAR_H + +#define ACE_SYS_SELECT_NEEDS_UNISTD_H + +// +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports SVR4 signal typedef +#define ACE_HAS_SVR4_SIGNAL_T + +//Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +//Platform supports sigsuspend() +#define ACE_HAS_SIGSUSPEND + +//Platform/compiler has macros for sig{empty,fill,add,del}set (e.g., SCO and FreeBSD) +#define ACE_HAS_SIG_MACROS + +//#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +#define ACE_LACKS_GETPGID +#define ACE_LACKS_RWLOCK_T + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +#define ACE_HAS_SYSCTL + +//? +#define ACE_LACKS_SIGSET + +#define ACE_NEEDS_SCHED_H + +// Use of is deprecated. +#define ACE_LACKS_MALLOC_H + +#define ACE_HAS_ALT_CUSERID + +// Platform supports POSIX timers via struct timespec. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_UALARM + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +#define ACE_LACKS_STRRECVFD + +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +//#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Explicit dynamic linking permits "lazy" symbol resolution +//#define ACE_HAS_RTLD_LAZY_V + +// platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// platform supports IP multicast +#define ACE_HAS_IP_MULTICAST +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Defines the page size of the system. +#define ACE_HAS_GETPAGESIZE + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform/compiler supports timezone * as second parameter to gettimeofday(). +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_MSQ_PROTOS +#define ACE_HAS_MSG +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_MSGSND + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#if ACE_MT_SAFE == 1 +// Yes, we do have threads. +# define ACE_HAS_THREADS +// And they're even POSIX pthreads +# define ACE_HAS_PTHREADS +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_LACKS_THREAD_PROCESS_SCOPING +#endif /* ACE_MT_SAFE == 1 */ + +#define ACE_HAS_DIRENT +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SEARCH_H + +#define ACE_LACKS_SETSCHED +//#define ACE_HAS_RECURSIVE_MUTEXES + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +#define ACE_HAS_SEMUN +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_GETIFADDRS +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_UNNAMED_SEMAPHORE + +// dlcompat package (not part of base Darwin) is needed for dlopen(). +// You may download directly from sourceforge and install or use fink +// Fink installer puts libraries in /sw/lib and headers in /sw/include +// In order to install dlcompat do the following: +// - download fink from http://fink.sf.net +// - type: +// fink install dlcompat +// as of Dec 2002, if you use fink you will need to uncomment the next line +//#define ACE_NEEDS_DL_UNDERSCORE +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_LD_SEARCH_PATH ACE_TEXT ("DYLD_LIBRARY_PATH") +#define ACE_DLL_SUFFIX ACE_TEXT (".dylib") +#define ACE_LACKS_DLCLOSE + +// gperf seems to need this +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER + +#if defined(__APPLE_CC__) && (__APPLE_CC__ < 1173) +#error "Compiler must be upgraded, see http://developer.apple.com" +#endif /* __APPLE_CC__ */ + +#endif /* ACE_CONFIG_MACOSX_H */ diff --git a/dep/ACE_wrappers/ace/config-macros.h b/dep/ACE_wrappers/ace/config-macros.h new file mode 100644 index 000000000..ca7f49c31 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-macros.h @@ -0,0 +1,636 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file config-macros.h + * + * $Id: config-macros.h 82495 2008-08-04 07:23:01Z johnnyw $ + * + * @author (Originally in OS.h)Doug Schmidt + * @author Jesper S. M|ller + * @author and a cast of thousands... + * + * This file contains the contents of the old config-lite.h header + * without C++ code (except for C++ code in macros). Specifically, + * only macros or C language constructs are found in this header. + * Allows configuration values and macros to be used by some C + * language sources. + */ +//========================================================================== + +#ifndef ACE_CONFIG_MACROS_H +#define ACE_CONFIG_MACROS_H + +#ifdef _WIN32 +#include "ace/config-win32.h" +#else +#include "ace/config.h" +#endif //_WIN32 + +#include "ace/Version.h" +#include "ace/Versioned_Namespace.h" + +// ACE_HAS_TLI is used to decide whether to try any XTI/TLI functionality +// so if it isn't set, set it. Capabilities and differences between +// XTI and TLI favor XTI, but when deciding to do anything, as opposed to +// ACE_NOTSUP_RETURN for example, ACE_HAS_TLI is the deciding factor. +#if !defined (ACE_HAS_TLI) +# if defined (ACE_HAS_XTI) +# define ACE_HAS_TLI +# endif /* ACE_HAS_XTI */ +#endif /* ACE_HAS_TLI */ + +#define ACE_BITS_PER_ULONG (8 * sizeof (u_long)) + +#if !defined (ACE_OSTREAM_TYPE) +# if defined (ACE_LACKS_IOSTREAM_TOTALLY) +# define ACE_OSTREAM_TYPE FILE +# else /* ! ACE_LACKS_IOSTREAM_TOTALLY */ +# define ACE_OSTREAM_TYPE ostream +# endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ +#endif /* ! ACE_OSTREAM_TYPE */ + +#if !defined (ACE_DEFAULT_LOG_STREAM) +# if defined (ACE_LACKS_IOSTREAM_TOTALLY) +# define ACE_DEFAULT_LOG_STREAM 0 +# else /* ! ACE_LACKS_IOSTREAM_TOTALLY */ +# define ACE_DEFAULT_LOG_STREAM (&cerr) +# endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ +#endif /* ! ACE_DEFAULT_LOG_STREAM */ + +// These two are only for backward compatibility. You should avoid +// using them if not necessary. +#if !defined (ACE_LACKS_DEPRECATED_MACROS) +/** + * @deprecated The ACE_SYNCH_1 macro is deprecated + */ +# define ACE_SYNCH_1 ACE_SYNCH_DECL +/** + * @deprecated The ACE_SYNCH_2 macro is deprecated + */ +# define ACE_SYNCH_2 ACE_SYNCH_USE +#endif + +// For Win32 compatibility... +# if !defined (ACE_WSOCK_VERSION) +# define ACE_WSOCK_VERSION 0, 0 +# endif /* ACE_WSOCK_VERSION */ + +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +# define ACE_MT(X) X +# if !defined (_REENTRANT) +# define _REENTRANT +# endif /* _REENTRANT */ +# else +# define ACE_MT(X) +# endif /* ACE_MT_SAFE */ + +# if defined (ACE_HAS_PURIFY) +# define ACE_INITIALIZE_MEMORY_BEFORE_USE +# endif /* ACE_HAS_PURIFY */ + +# if defined (ACE_HAS_VALGRIND) +# define ACE_INITIALIZE_MEMORY_BEFORE_USE +# endif /* ACE_HAS_VALGRIND */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) +/** + * @deprecated The @c ACE_HAS_USING macros are deprecated + */ +# define ACE_USING using +#endif /* !ACE_LACKS_DEPRECATED_MACROS */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) +/** + * @deprecated The @c ACE_TYPENAME macros is deprecated. Use standard + * C++ keyword typename instead. + */ +# define ACE_TYPENAME typename +#endif /* !ACE_LACKS_DEPRECATED_MACROS */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) +/** + * @deprecated The @c ACE_TEMPLATE_SPECIALIZATION and + * @c ACE_TEMPLATE_CLASS_MEMBER_SPECIALIZATION macros are + * deprecated. Use standard C++ template specialization + * syntax instead. + */ +# define ACE_TEMPLATE_SPECIALIZATION template<> +# define ACE_TEMPLATE_CLASS_MEMBER_SPECIALIZATION +#endif /* !ACE_LACKS_DEPRECATED_MACROS */ + +// ========================================================================= +// Perfect Multicast filting refers to RFC 3376, where a socket is only +// delivered dgrams for groups joined even if it didn't bind the group +// address. We turn this option off by default, although most OS's +// except for Windows and Solaris probably lack perfect filtering. +// ========================================================================= + +# if !defined (ACE_LACKS_PERFECT_MULTICAST_FILTERING) +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 0 +# endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING */ + +// ========================================================================= +// Enable/Disable Features By Default +// ========================================================================= + +# if !defined (ACE_HAS_POSITION_INDEPENDENT_POINTERS) +# define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1 +# endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */ + +# if !defined (ACE_HAS_PROCESS_SPAWN) +# if !defined (ACE_LACKS_FORK) || \ + (defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP)) || \ + defined (ACE_WINCE) || defined (ACE_OPENVMS) +# define ACE_HAS_PROCESS_SPAWN 1 +# endif +# endif /* ACE_HAS_PROCESS_SPAWN */ + +# if !defined (ACE_HAS_DYNAMIC_LINKING) +# if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) || defined (ACE_WIN32) || defined (ACE_VXWORKS) || defined (__hpux) +# define ACE_HAS_DYNAMIC_LINKING 1 +# endif +# endif /* ACE_HAS_DYNAMIC_LINKING */ + +# if defined (ACE_USES_FIFO_SEM) +# if defined (ACE_HAS_POSIX_SEM) || defined (ACE_LACKS_MKFIFO) || defined (ACE_LACKS_FCNTL) +# undef ACE_USES_FIFO_SEM +# endif +# endif /* ACE_USES_FIFO_SEM */ + +// ========================================================================= +// RCSID Macros +// ========================================================================= + +// By default, DO NOT include RCS Id strings in object code. +#if ! defined (ACE_USE_RCSID) +# define ACE_USE_RCSID 0 +#endif /* #if ! defined (ACE_USE_RCSID) */ + +#if (defined (ACE_USE_RCSID) && (ACE_USE_RCSID != 0)) +# if ! defined (ACE_RCSID) + + // This hack has the following purposes: + // 1. To define the RCS id string variable as a static char*, so + // that there won't be any duplicate extern symbols at link + // time. + // 2. To have a RCS id string variable with a unique name for each + // file. + // 3. To avoid warnings of the type "variable declared and never + // used". + +# define ACE_RCSID(path, file, id) \ + static inline const char* get_rcsid_ ## path ## _ ## file (const char*) \ + { \ + return id ; \ + } \ + static const char* rcsid_ ## path ## _ ## file = \ + get_rcsid_ ## path ## _ ## file ( rcsid_ ## path ## _ ## file ) ; + +# endif /* #if ! defined (ACE_RCSID) */ +#else + + // RCS id strings are not wanted. +# if defined (ACE_RCSID) +# undef ACE_RCSID +# endif /* #if defined (ACE_RCSID) */ +# define ACE_RCSID(path, file, id) /* noop */ +#endif /* #if (defined (ACE_USE_RCSID) && (ACE_USE_RCSID != 0)) */ + +// ========================================================================= +// INLINE macros +// +// These macros handle all the inlining of code via the .i or .inl files +// ========================================================================= + +#if defined (ACE_LACKS_INLINE_FUNCTIONS) && !defined (ACE_NO_INLINE) +# define ACE_NO_INLINE +#endif /* defined (ACE_LACKS_INLINE_FUNCTIONS) && !defined (ACE_NO_INLINE) */ + +// ACE inlining has been explicitly disabled. Implement +// internally within ACE by undefining __ACE_INLINE__. +#if defined (ACE_NO_INLINE) +# undef __ACE_INLINE__ +#endif /* ! ACE_NO_INLINE */ + +#if defined (__ACE_INLINE__) +# define ACE_INLINE inline +# if !defined (ACE_HAS_INLINED_OSCALLS) +# define ACE_HAS_INLINED_OSCALLS +# endif /* !ACE_HAS_INLINED_OSCALLS */ +#else +# define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + // ========================================================================= + // EXPLICIT macro + // ========================================================================= + + /** + * @deprecated explicit is deprecated. ACE requires C++ + * "explicit" keyword support. + */ + # define ACE_EXPLICIT explicit +#endif /* ACE_LACKS_DEPRECATED_MACROS */ + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + // ========================================================================= + // MUTABLE macro + // ========================================================================= + + /** + * @deprecated ACE_MUTABLE is deprecated. ACE requires C++ "mutable" + * keyword support. + */ + # define ACE_MUTABLE mutable + # define ACE_CONST_WHEN_MUTABLE const +#endif /* ACE_LACKS_DEPRECATED_MACROS */ + +// ============================================================================ +// EXPORT macros +// +// Since Win32 DLL's do not export all symbols by default, they must be +// explicitly exported (which is done by *_Export macros). +// ============================================================================ + +// Win32 should have already defined the macros in config-win32-common.h +#if !defined (ACE_HAS_CUSTOM_EXPORT_MACROS) +# define ACE_Proper_Export_Flag +# define ACE_Proper_Import_Flag +# define ACE_EXPORT_SINGLETON_DECLARATION(T) +# define ACE_IMPORT_SINGLETON_DECLARATION(T) +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#else +// An export macro should at the very least have been defined. + +# ifndef ACE_Proper_Import_Flag +# define ACE_Proper_Import_Flag +# endif /* !ACE_Proper_Import_Flag */ + +# ifndef ACE_EXPORT_SINGLETON_DECLARATION +# define ACE_EXPORT_SINGLETON_DECLARATION(T) +# endif /* !ACE_EXPORT_SINGLETON_DECLARATION */ + +# ifndef ACE_IMPORT_SINGLETON_DECLARATION +# define ACE_IMPORT_SINGLETON_DECLARATION(T) +# endif /* !ACE_IMPORT_SINGLETON_DECLARATION */ + +# ifndef ACE_EXPORT_SINGLETON_DECLARE +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* !ACE_EXPORT_SINGLETON_DECLARE */ + +# ifndef ACE_IMPORT_SINGLETON_DECLARE +# define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* !ACE_IMPORT_SINGLETON_DECLARE */ + +#endif /* !ACE_HAS_CUSTOM_EXPORT_MACROS */ + +// This is a whim of mine -- that instead of annotating a class with +// ACE_Export in its declaration, we make the declaration near the TOP +// of the file with ACE_DECLARE_EXPORT. +// TS = type specifier (e.g., class, struct, int, etc.) +// ID = identifier +// So, how do you use it? Most of the time, just use ... +// ACE_DECLARE_EXPORT(class, someobject); +// If there are global functions to be exported, then use ... +// ACE_DECLARE_EXPORT(void, globalfunction) (int, ...); +// Someday, when template libraries are supported, we made need ... +// ACE_DECLARE_EXPORT(template class, sometemplate) ; +# define ACE_DECLARE_EXPORT(TS,ID) TS ACE_Export ID + +// ============================================================================ +// Cast macros +// +// These macros are used to choose between the old cast style and the new +// *_cast<> operators +// ============================================================================ + +# define ACE_sap_any_cast(TYPE) reinterpret_cast (const_cast (ACE_Addr::sap_any)) + +#if !defined (ACE_LACKS_DEPRECATED_MACROS) + /** + * @deprecated ACE_{static,reinterpret,dynamic,const}_cast@<@> is + * deprecated. Directly use standard C++ casts instead. + */ + # define ACE_static_cast(TYPE, EXPR) static_cast (EXPR) + # define ACE_static_cast_1_ptr(TYPE, T1, EXPR) static_cast *> (EXPR) + # define ACE_static_cast_2_ptr(TYPE, T1, T2, EXPR) static_cast *> (EXPR) + # define ACE_static_cast_3_ptr(TYPE, T1, T2, T3, EXPR) static_cast *> (EXPR) + # define ACE_static_cast_4_ptr(TYPE, T1, T2, T3, T4, EXPR) static_cast *> (EXPR) + # define ACE_static_cast_5_ptr(TYPE, T1, T2, T3, T4, T5, EXPR) static_cast *> (EXPR) + # define ACE_static_cast_1_ref(TYPE, T1, EXPR) static_cast &> (EXPR) + # define ACE_static_cast_2_ref(TYPE, T1, T2, EXPR) static_cast &> (EXPR) + # define ACE_static_cast_3_ref(TYPE, T1, T2, T3, EXPR) static_cast &> (EXPR) + # define ACE_static_cast_4_ref(TYPE, T1, T2, T3, T4, EXPR) static_cast &> (EXPR) + # define ACE_static_cast_5_ref(TYPE, T1, T2, T3, T4, T5, EXPR) static_cast &> (EXPR) + + # define ACE_const_cast(TYPE, EXPR) const_cast (EXPR) + # define ACE_const_cast_1_ptr(TYPE, T1, EXPR) const_cast *> (EXPR) + # define ACE_const_cast_2_ptr(TYPE, T1, T2, EXPR) const_cast *> (EXPR) + # define ACE_const_cast_3_ptr(TYPE, T1, T2, T3, EXPR) const_cast *> (EXPR) + # define ACE_const_cast_4_ptr(TYPE, T1, T2, T3, T4, EXPR) const_cast *> (EXPR) + # define ACE_const_cast_5_ptr(TYPE, T1, T2, T3, T4, T5, EXPR) const_cast *> (EXPR) + # define ACE_const_cast_1_ref(TYPE, T1, EXPR) const_cast &> (EXPR) + # define ACE_const_cast_2_ref(TYPE, T1, T2, EXPR) const_cast &> (EXPR) + # define ACE_const_cast_3_ref(TYPE, T1, T2, T3, EXPR) const_cast &> (EXPR) + # define ACE_const_cast_4_ref(TYPE, T1, T2, T3, T4, EXPR) const_cast &> (EXPR) + # define ACE_const_cast_5_ref(TYPE, T1, T2, T3, T4, T5, EXPR) const_cast &> (EXPR) + + # define ACE_reinterpret_cast(TYPE, EXPR) reinterpret_cast (EXPR) + # define ACE_reinterpret_cast_1_ptr(TYPE, T1, EXPR) reinterpret_cast *> (EXPR) + # define ACE_reinterpret_cast_2_ptr(TYPE, T1, T2, EXPR) reinterpret_cast *> (EXPR) + # define ACE_reinterpret_cast_3_ptr(TYPE, T1, T2, T3, EXPR) reinterpret_cast *> (EXPR) + # define ACE_reinterpret_cast_4_ptr(TYPE, T1, T2, T3, T4, EXPR) reinterpret_cast *> (EXPR) + # define ACE_reinterpret_cast_5_ptr(TYPE, T1, T2, T3, T4, T5, EXPR) reinterpret_cast *> (EXPR) + # define ACE_reinterpret_cast_1_ref(TYPE, T1, EXPR) reinterpret_cast &> (EXPR) + # define ACE_reinterpret_cast_2_ref(TYPE, T1, T2, EXPR) reinterpret_cast &> (EXPR) + # define ACE_reinterpret_cast_3_ref(TYPE, T1, T2, T3, EXPR) reinterpret_cast &> (EXPR) + # define ACE_reinterpret_cast_4_ref(TYPE, T1, T2, T3, T4, EXPR) reinterpret_cast &> (EXPR) + # define ACE_reinterpret_cast_5_ref(TYPE, T1, T2, T3, T4, T5, EXPR) reinterpret_cast &> (EXPR) + + # define ACE_dynamic_cast(TYPE, EXPR) dynamic_cast (EXPR) + # define ACE_dynamic_cast_1_ptr(TYPE, T1, EXPR) dynamic_cast *> (EXPR) + # define ACE_dynamic_cast_2_ptr(TYPE, T1, T2, EXPR) dynamic_cast *> (EXPR) + # define ACE_dynamic_cast_3_ptr(TYPE, T1, T2, T3, EXPR) dynamic_cast *> (EXPR) + # define ACE_dynamic_cast_4_ptr(TYPE, T1, T2, T3, T4, EXPR) dynamic_cast *> (EXPR) + # define ACE_dynamic_cast_5_ptr(TYPE, T1, T2, T3, T4, T5, EXPR) dynamic_cast *> (EXPR) + # define ACE_dynamic_cast_1_ref(TYPE, T1, EXPR) dynamic_cast &> (EXPR) + # define ACE_dynamic_cast_2_ref(TYPE, T1, T2, EXPR) dynamic_cast &> (EXPR) + # define ACE_dynamic_cast_3_ref(TYPE, T1, T2, T3, EXPR) dynamic_cast &> (EXPR) + # define ACE_dynamic_cast_4_ref(TYPE, T1, T2, T3, T4, EXPR) dynamic_cast &> (EXPR) + # define ACE_dynamic_cast_5_ref(TYPE, T1, T2, T3, T4, T5, EXPR) dynamic_cast &> (EXPR) +#endif /* ACE_LACKS_DEPRECATED_MACROS */ + +# if !defined (ACE_CAST_CONST) + // Sun CC 4.2, for example, requires const in reinterpret casts of + // data members in const member functions. But, other compilers + // complain about the useless const. This keeps everyone happy. +# if defined (__SUNPRO_CC) +# define ACE_CAST_CONST const +# else /* ! __SUNPRO_CC */ +# define ACE_CAST_CONST +# endif /* ! __SUNPRO_CC */ +# endif /* ! ACE_CAST_CONST */ + +// ============================================================================ +// Compiler Silencing macros +// +// Some compilers complain about parameters that are not used. This macro +// should keep them quiet. +// ============================================================================ + +#if !defined (ACE_UNUSED_ARG) +# if defined (__GNUC__) && ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) +# define ACE_UNUSED_ARG(a) (void) (a) +# elif defined (__GNUC__) || defined (ghs) || defined (__hpux) || defined (__sgi) || defined (__DECCXX) || defined (__rational__) || defined (__USLC__) || defined (ACE_RM544) || defined (__DCC__) || defined (__PGI) || defined (__TANDEM) +// Some compilers complain about "statement with no effect" with (a). +// This eliminates the warnings, and no code is generated for the null +// conditional statement. @note that may only be true if -O is enabled, +// such as with GreenHills (ghs) 1.8.8. +# define ACE_UNUSED_ARG(a) do {/* null */} while (&a == 0) +# elif defined (__DMC__) + #define ACE_UNUSED_ID(identifier) + template + inline void ACE_UNUSED_ARG(const T& ACE_UNUSED_ID(t)) { } +# else /* ghs || __GNUC__ || ..... */ +# define ACE_UNUSED_ARG(a) (a) +# endif /* ghs || __GNUC__ || ..... */ +#endif /* !ACE_UNUSED_ARG */ + +#if defined (_MSC_VER) || defined(__sgi) || defined (ghs) || defined (__DECCXX) || defined(__BORLANDC__) || defined (ACE_RM544) || defined (__USLC__) || defined (__DCC__) || defined (__PGI) || defined (__TANDEM) || (defined (__HP_aCC) && (__HP_aCC >= 60500)) +# define ACE_NOTREACHED(a) +#else /* __sgi || ghs || ..... */ +# define ACE_NOTREACHED(a) a +#endif /* __sgi || ghs || ..... */ + +// ============================================================================ +// ACE_ALLOC_HOOK* macros +// +// Macros to declare and define class-specific allocation operators. +// ============================================================================ + +# if defined (ACE_HAS_ALLOC_HOOKS) +# define ACE_ALLOC_HOOK_DECLARE \ + void *operator new (size_t bytes); \ + void operator delete (void *ptr); + + // Note that these are just place holders for now. Some day they + // may be be replaced by . +# define ACE_ALLOC_HOOK_DEFINE(CLASS) \ + void *CLASS::operator new (size_t bytes) { return ::new char[bytes]; } \ + void CLASS::operator delete (void *ptr) { delete [] ((char *) ptr); } +# else +# define ACE_ALLOC_HOOK_DECLARE struct __Ace {} /* Just need a dummy... */ +# define ACE_ALLOC_HOOK_DEFINE(CLASS) +# endif /* ACE_HAS_ALLOC_HOOKS */ + +// ============================================================================ +/** + * ACE_OSCALL* macros + * + * @deprecated ACE_OSCALL_RETURN and ACE_OSCALL should not be used. + * Please restart system calls in your application code. + * See the @c sigaction(2) man page for documentation + * regarding enabling restartable system calls across + * signals via the @c SA_RESTART flag. + * + * The following two macros used ensure that system calls are properly + * restarted (if necessary) when interrupts occur. However, that + * capability was never enabled by any of our supported platforms. + * In fact, some parts of ACE would not function properly when that + * ability was enabled. Furthermore, they assumed that ability to + * restart system calls was determined statically. That assumption + * does not hold for modern platforms, where that ability is + * determined dynamically at run-time. + */ +// ============================================================================ + +#define ACE_OSCALL_RETURN(X,TYPE,FAILVALUE) \ + do \ + return (TYPE) (X); \ + while (0) +#define ACE_OSCALL(X,TYPE,FAILVALUE,RESULT) \ + do \ + RESULT = (TYPE) (X); \ + while (0) + +#if defined (ACE_WIN32) +# define ACE_WIN32CALL_RETURN(X,TYPE,FAILVALUE) \ + do { \ + TYPE ace_result_ = (TYPE) X; \ + if (ace_result_ == FAILVALUE) \ + ACE_OS::set_errno_to_last_error (); \ + return ace_result_; \ + } while (0) +# define ACE_WIN32CALL(X,TYPE,FAILVALUE,RESULT) \ + do { \ + RESULT = (TYPE) X; \ + if (RESULT == FAILVALUE) \ + ACE_OS::set_errno_to_last_error (); \ + } while (0) +#endif /* ACE_WIN32 */ + +// The C99 security-improved run-time returns an error value on failure; +// 0 on success. +#if defined (ACE_HAS_TR24731_2005_CRT) +# define ACE_SECURECRTCALL(X,TYPE,FAILVALUE,RESULT) \ + do { \ + errno_t ___ = X; \ + if (___ != 0) { errno = ___; RESULT = FAILVALUE; } \ + } while (0) +#endif /* ACE_HAS_TR24731_2005_CRT */ + +// ============================================================================ +// Fundamental types +// ============================================================================ + +#if defined (ACE_WIN32) + +typedef HANDLE ACE_HANDLE; +typedef SOCKET ACE_SOCKET; +# define ACE_INVALID_HANDLE INVALID_HANDLE_VALUE + +#else /* ! ACE_WIN32 */ + +typedef int ACE_HANDLE; +typedef ACE_HANDLE ACE_SOCKET; +# define ACE_INVALID_HANDLE -1 + +#endif /* ACE_WIN32 */ + +// Define the type that's returned from the platform's native thread +// functions. ACE_THR_FUNC_RETURN is the type defined as the thread +// function's return type, except when the thread function doesn't return +// anything (pSoS). The ACE_THR_FUNC_NO_RETURN_VAL macro is used to +// indicate that the actual thread function doesn't return anything. The +// rest of ACE uses a real type so there's no a ton of conditional code +// everywhere to deal with the possibility of no return type. +# if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS) +# include /**/ +typedef int ACE_THR_FUNC_RETURN; +#define ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN +# elif defined (ACE_WIN32) +typedef DWORD ACE_THR_FUNC_RETURN; +#define ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN +# else +typedef void* ACE_THR_FUNC_RETURN; +# endif /* ACE_VXWORKS */ +typedef ACE_THR_FUNC_RETURN (*ACE_THR_FUNC)(void *); + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +typedef void (*ACE_THR_C_DEST)(void *); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +typedef void (*ACE_THR_DEST)(void *); + +// Now some platforms have special requirements... +# if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS) +typedef FUNCPTR ACE_THR_FUNC_INTERNAL; // where typedef int (*FUNCPTR) (...) +# else +typedef ACE_THR_FUNC ACE_THR_FUNC_INTERNAL; +# endif /* ACE_VXWORKS */ + +# ifdef __cplusplus +extern "C" +{ +# endif /* __cplusplus */ +# if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS) +typedef FUNCPTR ACE_THR_C_FUNC; // where typedef int (*FUNCPTR) (...) +# else +typedef ACE_THR_FUNC_RETURN (*ACE_THR_C_FUNC)(void *); +# endif /* ACE_VXWORKS */ +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +// ============================================================================ +// Macros for controlling the lifetimes of dlls loaded by ACE_DLL--including +// all dlls loaded via the ACE Service Config framework. +// +// Please don't change these values or add new ones wantonly, since we use +// the ACE_BIT_ENABLED, etc..., macros to test them. +// ============================================================================ + +// Per-process policy that unloads dlls eagerly. +#define ACE_DLL_UNLOAD_POLICY_PER_PROCESS 0 +// Apply policy on a per-dll basis. If the dll doesn't use one of the macros +// below, the current per-process policy will be used. +#define ACE_DLL_UNLOAD_POLICY_PER_DLL 1 +// Don't unload dll when refcount reaches zero, i.e., wait for either an +// explicit unload request or program exit. +#define ACE_DLL_UNLOAD_POLICY_LAZY 2 +// Default policy allows dlls to control their own destinies, but will +// unload those that don't make a choice eagerly. +#define ACE_DLL_UNLOAD_POLICY_DEFAULT ACE_DLL_UNLOAD_POLICY_PER_DLL + +// Add this macro you one of your cpp file in your dll. X should +// be either ACE_DLL_UNLOAD_POLICY_DEFAULT or ACE_DLL_UNLOAD_POLICY_LAZY. +#define ACE_DLL_UNLOAD_POLICY(CLS,X) \ +extern "C" u_long CLS##_Export _get_dll_unload_policy (void) \ + { return X;} + +// ============================================================================ +// ACE_USES_CLASSIC_SVC_CONF macro +// ============================================================================ + +// For now, default is to use the classic svc.conf format. +#if !defined (ACE_USES_CLASSIC_SVC_CONF) +# if defined (ACE_HAS_CLASSIC_SVC_CONF) && defined (ACE_HAS_XML_SVC_CONF) +# error You can only use either CLASSIC or XML svc.conf, not both. +# endif +// Change the ACE_HAS_XML_SVC_CONF to ACE_HAS_CLASSIC_SVC_CONF when +// we switch ACE to use XML svc.conf as default format. +# if defined (ACE_HAS_XML_SVC_CONF) +# define ACE_USES_CLASSIC_SVC_CONF 0 +# else +# define ACE_USES_CLASSIC_SVC_CONF 1 +# endif /* ACE_HAS_XML_SVC_CONF */ +#endif /* ACE_USES_CLASSIC_SVC_CONF */ + +// ============================================================================ +// Default svc.conf file extension. +// ============================================================================ +#if defined (ACE_USES_CLASSIC_SVC_CONF) && (ACE_USES_CLASSIC_SVC_CONF == 1) +# define ACE_DEFAULT_SVC_CONF_EXT ".conf" +#else +# define ACE_DEFAULT_SVC_CONF_EXT ".conf.xml" +#endif /* ACE_USES_CLASSIC_SVC_CONF && ACE_USES_CLASSIC_SVC_CONF == 1 */ + +// ============================================================================ +// Miscellaneous macros +// ============================================================================ + +#if defined (ACE_USES_EXPLICIT_STD_NAMESPACE) +# define ACE_STD_NAMESPACE std +#else +# define ACE_STD_NAMESPACE +#endif + +#if !defined (ACE_OS_String) +# define ACE_OS_String ACE_OS +#endif /* ACE_OS_String */ +#if !defined (ACE_OS_Memory) +# define ACE_OS_Memory ACE_OS +#endif /* ACE_OS_Memory */ +#if !defined (ACE_OS_Dirent) +# define ACE_OS_Dirent ACE_OS +#endif /* ACE_OS_Dirent */ +#if !defined (ACE_OS_TLI) +# define ACE_OS_TLI ACE_OS +#endif /* ACE_OS_TLI */ + +// ------------------------------------------------------------------- +// Preprocessor symbols will not be expanded if they are +// concatenated. Force the preprocessor to expand them during the +// argument prescan by calling a macro that itself calls another that +// performs the actual concatenation. +#define ACE_PREPROC_CONCATENATE_IMPL(A,B) A ## B +#define ACE_PREPROC_CONCATENATE(A,B) ACE_PREPROC_CONCATENATE_IMPL(A,B) +// ------------------------------------------------------------------- + +#endif /* ACE_CONFIG_MACROS_H */ diff --git a/dep/ACE_wrappers/ace/config-minimal.h b/dep/ACE_wrappers/ace/config-minimal.h new file mode 100644 index 000000000..4cf2e8a48 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-minimal.h @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +// $Id: config-minimal.h 80826 2008-03-04 14:51:23Z wotte $ + +// This configuration file is designed to build only the minimal +// ACE_OS adaptation layer. + +#ifndef ACE_CONFIG_MINIMAL_H +#define ACE_CONFIG_MINIMAL_H +#include /**/ "ace/pre.h" + +#define ACE_HAS_MINIMAL_ACE_OS + +// Only instantiate the ACE_OS_Object_Manager. +#define ACE_MAIN_OBJECT_MANAGER \ + ACE_OS_Object_Manager ace_os_object_manager; + +#if !defined(ACE_USE_THREAD_MANAGER_ADAPTER) + // To prevent use of ACE_Thread_Exit functions in + // ACE_Thread_Adapter::invoke (). +# define ACE_USE_THREAD_MANAGER_ADAPTER +#endif /* ! ACE_USE_THREAD_MANAGER_ADAPTER */ + +#if defined (ACE_ASSERT) +# undef ACE_ASSERT +#endif /* ACE_ASSERT */ +#define ACE_ASSERT(x) + +#if defined (ACE_DEBUG) +# undef ACE_DEBUG +#endif /* ACE_DEBUG */ +#define ACE_DEBUG(x) + +#if defined (ACE_ERROR) +# undef ACE_ERROR +#endif /* ACE_ERROR */ +#define ACE_ERROR(x) + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_MINIMAL_H */ diff --git a/dep/ACE_wrappers/ace/config-mvs.h b/dep/ACE_wrappers/ace/config-mvs.h new file mode 100644 index 000000000..c37bac258 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-mvs.h @@ -0,0 +1,131 @@ +/* -*- C++ -*- */ +// $Id: config-mvs.h 81992 2008-06-16 19:09:50Z wotte $ + +// Config file for MVS with OpenEdition + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +// The following #defines are hacks to get around things +// that seem to be missing or different in MVS land +#define MAXPATHLEN 1024 /* sys/param.h not on MVS */ +#define NSIG 44 /* missing from Signal.h */ +#define MAXHOSTNAMELEN 256 /* missing form netdb.h */ +#define howmany __howmany /* MVS uses different names than most others */ +#define fd_mask __fd_mask +#define MAXNAMLEN __DIR_NAME_MAX +#if defined (log) /* log is a macro in math.h */ +# undef log /* conflicts with log function in ACE */ +#endif /* log */ + +#define ACE_MVS + +// Preprocesor requires an extra argument +#ifndef ACE_USING_MCPP_PREPROCESSOR +# define ACE_CC_PREPROCESSOR_ARGS "-+ -E" +#endif + +// See the README file in this directory +// for a description of the following ACE_ macros + +#if __COMPILER_VER__ >= 0x21020000 /* OS/390 r2 or higher */ +# define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +# define ACE_HAS_UCONTEXT_T +#else /* __COMPILER_VER__ < 0x21020000 */ +# define ACE_LACKS_UCONTEXT_H +#endif /* __COMPILER_VER__ < 0x21020000 */ + +#if __COMPILER_VER__ < 0x22060000 /* before OS/390 r2.6 */ +# define ACE_LACKS_LONGLONG_T +#endif /* __COMPILER_VER__ < 0x22060000 */ + +#define ERRMAX __sys_nerr + +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_HAS_BROKEN_CTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_GETPAGESIZE +#define ACE_HAS_GETRUSAGE +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_LIMITED_RUSAGE_T +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONSCALAR_THREAD_KEY_T +#define ACE_HAS_POLL +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_PTHREADS +#define ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP +#define ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIG_C_FUNC +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SIZET_SOCKET_LEN +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_STRBUF_T +#define ACE_HAS_STRINGS +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_TEMPLATE_TYPEDEFS +#define ACE_HAS_THREADS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_THR_C_DEST +#define ACE_HAS_THR_C_FUNC +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_HAS_UALARM +#define ACE_HAS_UTIME +#define ACE_HAS_VOIDPTR_MMAP +#define ACE_HAS_VOIDPTR_SOCKOPT +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_INET_ATON +#define ACE_LACKS_MSGBUF_T +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_IOSTREAM_FX +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MALLOC_H +#define ACE_LACKS_PARAM_H +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_PLACEMENT_OPERATOR_DELETE +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SCHED_H +#define ACE_LACKS_SETSCHED +#define ACE_LACKS_SEMAPHORE_H +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_STDINT_H +#define ACE_LACKS_SYS_NERR +#define ACE_LACKS_SYS_SELECT_H +#define ACE_LACKS_SYS_SYSCTL_H +#define ACE_LACKS_SYSTIME_H +#define ACE_LACKS_NETINET_TCP_H +#define ACE_LACKS_TCP_H +#define ACE_LACKS_THREAD_PROCESS_SCOPING +#define ACE_LACKS_PTHREAD_ATTR_SETSTACKADDR +#define ACE_LACKS_TIMESPEC_T + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +#define ACE_NEEDS_DEV_IO_CONVERSION + +#define ACE_SIZEOF_FLOAT 4 +#define ACE_SIZEOF_DOUBLE 8 +#define ACE_SIZEOF_LONG_DOUBLE 16 +#define ACE_HAS_EBCDIC + +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000) +#define IN_MULTICAST(a) IN_CLASSD(a) +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-netbsd.h b/dep/ACE_wrappers/ace/config-netbsd.h new file mode 100644 index 000000000..551718015 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-netbsd.h @@ -0,0 +1,167 @@ +/* -*- C++ -*- */ +// $Id: config-netbsd.h 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H + +#ifndef ACE_MT_SAFE +#define ACE_MT_SAFE 1 +#endif + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +#if defined(ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +# define ACE_HAS_THREADS 1 +# define ACE_HAS_PTHREADS 1 +# define ACE_HAS_PTHREADS_UNIX98_EXT 1 +# define ACE_HAS_PTHREAD_RESUME_NP 1 +# define ACE_HAS_PTHREAD_SUSPEND_NP 1 +# define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 +# define ACE_LACKS_PTHREAD_YIELD 1 +#endif /* ACE_MT_SAFE */ + +#define ACE_HAS_CLOCK_SETTIME 1 +#define ACE_HAS_CLOCK_GETTIME 1 +#define ACE_HAS_SETTIMEOFDAY 1 +#define ACE_HAS_GETTIMEOFDAY 1 +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R 1 +#define ACE_HAS_3_PARAM_WCSTOK 1 +#define ACE_HAS_3_PARAM_READDIR_R 1 +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG 1 +#define ACE_HAS_ALT_CUSERID 1 +#define ACE_HAS_AUTOMATIC_INIT_FINI 1 +#define ACE_HAS_CLOCK_GETTIME 1 +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES 1 +#define ACE_HAS_DIRENT 1 +#define ACE_HAS_EXCEPTIONS 1 +#define ACE_HAS_GETIFADDRS 1 +#define ACE_HAS_GETPAGESIZE 1 +#define ACE_HAS_GETPROGNAME 1 +#define ACE_HAS_GETRUSAGE 1 +#define ACE_HAS_GETRUSAGE_PROTOTYPE 1 +#define ACE_HAS_GNU_CSTRING_H 1 +#define ACE_HAS_GPERF 1 +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT 1 +#define ACE_HAS_IP_MULTICAST 1 +#define ACE_HAS_MSG 1 +#define ACE_HAS_NEW_NO_H 1 +#define ACE_HAS_NONCONST_SELECT_TIMEVAL 1 +#define ACE_HAS_ONLY_SCHED_OTHER 1 +#define ACE_HAS_POLL 1 +#define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1 +#define ACE_HAS_POSIX_NONBLOCK 1 +#define ACE_HAS_POSIX_TIME 1 +#define ACE_HAS_P_READ_WRITE 1 +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS 1 +#define ACE_HAS_REENTRANT_FUNCTIONS 1 +#define ACE_HAS_SCANDIR 1 +#define ACE_HAS_SETPROGNAME 1 +#define ACE_HAS_SIGACTION_CONSTP2 1 +#define ACE_HAS_SIGINFO_T 1 +#define ACE_HAS_SIGSUSPEND 1 +#define ACE_HAS_SIGTIMEDWAIT 1 +#define ACE_HAS_SIGWAIT 1 +#define ACE_HAS_SIG_ATOMIC_T 1 +#define ACE_HAS_SIG_C_FUNC 1 +#define ACE_HAS_SOCKADDR_IN_SIN_LEN 1 +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN 1 +#define ACE_HAS_SOCKADDR_MSG_NAME 1 +#define ACE_HAS_SOCKLEN_T 1 +#define ACE_HAS_SSIZE_T 1 +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#define ACE_HAS_STDEXCEPT_NO_H 1 +#define ACE_HAS_STRERROR 1 +#define ACE_HAS_STRINGS 1 +#define ACE_HAS_STRING_CLASS 1 +#define ACE_HAS_SVR4_DYNAMIC_LINKING 1 +#define ACE_HAS_SYSV_IPC 1 +#define ACE_HAS_SYS_ERRLIST 1 +#define ACE_HAS_SYS_FILIO_H 1 +#define ACE_HAS_SYS_SIGLIST 1 +#define ACE_HAS_SYS_SOCKIO_H 1 +#define ACE_HAS_SYS_SYSCALL_H 1 +#define ACE_HAS_SYSCTL +#define ACE_HAS_TERMIOS 1 +#define ACE_HAS_THREAD_SPECIFIC_STORAGE 1 +#define ACE_HAS_TIMEZONE 1 +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY 1 +#define ACE_HAS_UALARM 1 +#define ACE_HAS_UCONTEXT_T 1 +#define ACE_HAS_VOIDPTR_MMAP 1 +#define ACE_HAS_VOIDPTR_SOCKOPT 1 +#define ACE_HAS_WCHAR 1 +#define ACE_HAS_XPG4_MULTIBYTE_CHAR 1 +#define ACE_IOCTL_TYPE_ARG2 u_long +#define ACE_LACKS_CONDATTR_PSHARED 1 +#define ACE_LACKS_GETHOSTENT 1 +#define ACE_LACKS_GETIPNODEBYADDR 1 +#define ACE_LACKS_GETIPNODEBYNAME 1 +#define ACE_LACKS_IOSTREAM_FX 1 +#define ACE_LACKS_ITOW 1 +#define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 +#define ACE_LACKS_LOG2 1 +#define ACE_LACKS_MSG_ACCRIGHTS 1 +#define ACE_LACKS_MUTEXATTR_PSHARED 1 +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS 1 +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#define ACE_LACKS_PRI_T 1 +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 +#define ACE_LACKS_PTHREAD_YIELD 1 +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS 1 +#define ACE_LACKS_RWLOCKATTR_PSHARED 1 +#define ACE_LACKS_RWLOCK_T 1 +#define ACE_LACKS_SETSCHED 1 +#define ACE_LACKS_SIGINFO_H 1 +#define ACE_LACKS_STROPTS_H 1 +#define ACE_LACKS_STRRECVFD 1 +#define ACE_LACKS_TIMEDWAIT_PROTOTYPES 1 +#define ACE_LACKS_TIMESPEC_T 1 +#define ACE_LACKS_UNBUFFERED_STREAMBUF 1 +#define ACE_LACKS_WCSDUP 1 +#define ACE_LACKS_WCSICMP 1 +#define ACE_LACKS_WCSNICMP 1 +#define ACE_SCANDIR_CMP_USES_CONST_VOIDPTR 1 + +#if defined(__x86_64__) +#define ACE_SIZEOF_DOUBLE 8 +#define ACE_SIZEOF_FLOAT 4 +#define ACE_SIZEOF_INT 4 +#define ACE_SIZEOF_LONG 8 +#define ACE_SIZEOF_LONG_DOUBLE 16 +#define ACE_SIZEOF_LONG_LONG 8 +#define ACE_SIZEOF_SHORT 2 +#define ACE_SIZEOF_VOID_P 8 +#define ACE_SIZEOF_WCHAR 4 + +typedef unsigned long ACE_UINT64; +typedef signed long ACE_INT64; + +#define ACE_SSIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%ld") +#define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%lu") + +#elif defined(__i386__) + +#define ACE_SIZEOF_DOUBLE 8 +#define ACE_SIZEOF_FLOAT 4 +#define ACE_SIZEOF_INT 4 +#define ACE_SIZEOF_LONG 4 +#define ACE_SIZEOF_LONG_DOUBLE 12 +#define ACE_SIZEOF_LONG_LONG 8 +#define ACE_SIZEOF_SHORT 2 +#define ACE_SIZEOF_VOID_P 4 +#define ACE_SIZEOF_WCHAR 4 + +typedef unsigned long long ACE_UINT64; +typedef signed long long ACE_INT64; + +#else +# error unknown CPU architecture +#endif + +#endif /* ACE_CONFIG_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/dep/ACE_wrappers/ace/config-openbsd.h b/dep/ACE_wrappers/ace/config-openbsd.h new file mode 100644 index 000000000..a730c810d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-openbsd.h @@ -0,0 +1,235 @@ +/* -*- C++ -*- */ +// $Id: config-openbsd.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for OpenBSD +// platforms using GNU g++. + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if defined (ACE_HAS_THREADS) +#include /**/ +#endif /* ACE_HAS_THREADS */ + +#include "ace/config-posix.h" + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#define ACE_SIZEOF_LONG_DOUBLE 12 + +#if defined (__GNUG__) +# include "ace/config-g++-common.h" +#endif /* __GNUG__ */ + +// Platform specific directives +// gcc defines __OpenBSD__ automatically for us. +#include + +#if defined (ACE_HAS_THREADS) +#if !defined (_THREAD_SAFE) +#define _THREAD_SAFE +#endif /* _THREAD_SAFE */ + +// Check if pthreads and native exceptions are being used together. +// This causes SEGVs to tbe thrown somewhat randomly for some +// reason. According to newsgroup postings, it appears to be an +// OpenBSD or gcc bug. +#if defined (ACE_USES_NATIVE_EXCEPTIONS) +#error "OpenBSD pthreads and native exceptions currently do not work. See OpenBSD bug #1750" +#endif /* ACE_USES_NATIVE_EXCEPTIONS */ + +#endif /* ACE_HAS_THREADS */ + +#define ACE_HAS_GPERF + +// Platform specific directives +/* Are the following true? */ +#define ACE_LACKS_GETPGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID + +#define ACE_HAS_ALT_CUSERID +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS + +#define ACE_LACKS_RWLOCK_T +#define ACE_HAS_SIG_MACROS +#define ACE_HAS_CHARPTR_DL +#define ACE_HAS_DIRENT + +// OpenBSD 3.6 +#if (OpenBSD < 200411) +# define ACE_USES_ASM_SYMBOL_IN_DLSYM +#endif + +#define ACE_LACKS_UCONTEXT_H + +// ucontext_t is in OpenBSD 3.5 and later. +#if (OpenBSD >= 200405) +# define ACE_HAS_UCONTEXT_T +#endif /* OpenBSD >= 200405 */ + + +// OpenBSD has sigwait defined +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIGINFO_T + +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS +#define ACE_LACKS_RAND_REENTRANT_FUNCTIONS +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + +#define ACE_HAS_SOCKLEN_T + +#define ACE_HAS_POLL + +// Use of is deprecated. +#define ACE_LACKS_MALLOC_H + +// NetBSD appears to have a sigset_t type. +// #define ACE_LACKS_SIGSET + +// Platform supports POSIX timers via struct timespec. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_UALARM + +// Platform defines struct timespec but not timespec_t +#define ACE_LACKS_TIMESPEC_T + +#define ACE_LACKS_STDINT_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_WCHAR_H + +#define ACE_LACKS_STRRECVFD + +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// OpenBSD supports the getifaddrs interface +#define ACE_HAS_GETIFADDRS + +// Compiler/platform supports SVR4 signal typedef +#define ACE_HAS_SVR4_SIGNAL_T +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports alloca(). +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform supports SVR4 dynamic linking semantics.. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Explicit dynamic linking permits "lazy" symbol resolution +#define ACE_HAS_RTLD_LAZY_V + +// platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Lacks perfect filtering, must bind group address. +#if !defined ACE_LACKS_PERFECT_MULTICAST_FILTERING +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_LACKS_PERFECT_MULTICAST_FILTERING */ + +// Compiler/platform has +//#define ACE_HAS_ALLOCA_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +#define ACE_HAS_SYSCTL + +// Platform/compiler supports timezone * as second parameter to gettimeofday(). +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +// OpenBSD's dlsym call segfaults when passed an invalid handle. +// It seems as if most other OSs detect this and just report an +// error. +#define ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE + +#define ACE_HAS_MSG +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_MSGSND + +#ifdef ACE_HAS_THREADS +// Thread specific settings + +// And they're even POSIX pthreads +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif /* ! ACE_MT_SAFE */ +#endif /* ACE_HAS_THREADS */ + +#define ACE_HAS_SIGWAIT + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_LACKS_THREAD_PROCESS_SCOPING +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_DIRENT + +#if !defined (ACE_HAS_THREADS) +// OpenBSD really has readdir_r () in single threaded mode, +// but the #ifdefs in OS.i select one with the wrong parameter +// sets if the ACE_HAS_POSIX_STD isn't defined (which is defined +// when ACE_HAS_THREADS is defined.) + +#define ACE_LACKS_READDIR_R + +#endif /* ! ACE_HAD_THREADS */ + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// OpenBSD 3.2 lacks sched_setscheduler (see /usr/src/lib/libc_r/TODO) +#define ACE_LACKS_SETSCHED + +// OpenBSD supports IPv6 by default, but ACE IPv6 code +// has compile errors. +//#define ACE_HAS_IPV6 + +#define ACE_HAS_3_PARAM_READDIR_R + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-openvms.h b/dep/ACE_wrappers/ace/config-openvms.h new file mode 100644 index 000000000..0b3d3c15f --- /dev/null +++ b/dep/ACE_wrappers/ace/config-openvms.h @@ -0,0 +1,195 @@ +/* -*- C++ -*- */ +// $Id: config-openvms.h 81935 2008-06-12 22:01:53Z jtc $ + +// The following configuration file is designed to work for OpenVMS 7.3-2 + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H + +#if !defined (ACE_USE_RCSID) +# define ACE_USE_RCSID 0 +#endif + +#ifdef __cplusplus +#pragma message disable CODCAUUNR +#pragma message disable CODEUNREACHABLE +//#pragma message disable DOLLARID +//#pragma message disable NOSIMPINT +//#pragma message disable NOSTDLONGLONG +#pragma message disable NARROWPTR +//#pragma message disable LONGEXTERN +#pragma message disable UNSCOMZER +#endif + +// Use a signed int to match POSIX +#define __SIGNED_INT_TIME_T + +#define ACE_OPENVMS __VMS_VER + +#define ACE_DLL_SUFFIX ACE_TEXT("") + +#define ACE_HAS_DUMP 1 + +// need this includes to ensure proper sequence of definitions so that +// f.i. HP C/C++ does not '#define ' memcpy, memmove etc. +#include +#include +#include +#undef clearerr +#undef memset +#undef memcpy +#undef memmove + +#if defined(__ia64__) + // on OpenVMS IA64 we need this get the singleton exported since we build + // ACE/TAO with the NOTEMPLATES export option which prohibits exporting + // of any template symbols unless explicitly exported + #define ACE_HAS_CUSTOM_EXPORT_MACROS + #define ACE_Proper_Export_Flag + #define ACE_Proper_Import_Flag + #define ACE_EXPORT_SINGLETON_DECLARATION(T) template class __declspec (dllexport) T + #define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class __declspec (dllexport) SINGLETON_TYPE; +#else + #define ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION +#endif + +#define ACE_DEFAULT_BASE_ADDR ((char*)(0x30000000)) + +#define ACE_MAX_UDP_PACKET_SIZE 65535 + +#define ACE_HAS_STDCPP_STL_INCLUDES 1 + +/* missing system headers */ +#define ACE_LACKS_STDINT_H 1 +#define ACE_LACKS_SYS_IPC_H 1 +#define ACE_LACKS_SYS_SEM_H 1 +#define ACE_LACKS_SEMAPHORE_H 1 +#define ACE_LACKS_SYS_SELECT_H 1 +#define ACE_LACKS_TERMIOS_H 1 +#define ACE_LACKS_SYS_SHM_H 1 +#define ACE_LACKS_SYS_MSG_H 1 +#define ACE_LACKS_REGEX_H 1 +#define ACE_LACKS_SEARCH_H 1 +#define ACE_LACKS_SCHED_H 1 +#define ACE_LACKS_SYS_SYSCTL_H 1 +#define ACE_LACKS_MALLOC_H 1 +#define ACE_LACKS_SYS_PARAM_H 1 +#define ACE_LACKS_SIGINFO_H 1 +#define ACE_LACKS_UCONTEXT_H 1 + +/* missing rtl functions */ +#define ACE_LACKS_SETPGID 1 +#define ACE_LACKS_SETREUID 1 +#define ACE_LACKS_SETREGID 1 +#define ACE_LACKS_FORK 1 +#define ACE_LACKS_GETPGID 1 +#define ACE_LACKS_SETSID 1 +#define ACE_LACKS_FCNTL 1 +#define ACE_LACKS_SETEGID 1 +#define ACE_LACKS_SETEUID 1 + +#define ACE_LACKS_REALPATH 1 + +#define ACE_LACKS_SYMLINKS 1 + +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS 1 +#define ACE_LACKS_RAND_REENTRANT_FUNCTIONS 1 + +#define ACE_HAS_P_READ_WRITE +#define ACE_HAS_CHARPTR_DL 1 +#define ACE_HAS_CLOCK_GETTIME 1 +#define ACE_HAS_CLOCK_SETTIME 1 +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY 1 +#define ACE_HAS_DIRENT 1 +#define ACE_HAS_GETPAGESIZE 1 +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_SELECT_TIMEVAL 1 +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R 1 +#define ACE_HAS_3_PARAM_WCSTOK 1 +#define ACE_HAS_SIGSUSPEND 1 +#define ACE_HAS_SIG_MACROS 1 +#define ACE_HAS_SIGWAIT 1 +#define ACE_HAS_SIGTIMEDWAIT 1 + +#define ACE_HAS_SIG_C_FUNC 1 +#define ACE_HAS_SIGISMEMBER_BUG +#define ACE_HAS_STRNLEN 1 +#define ACE_HAS_STREAMS 1 +#define ACE_HAS_STRERROR 1 +#define ACE_HAS_UALARM 1 +#define ACE_HAS_VOIDPTR_MMAP 1 +#define ACE_HAS_VOIDPTR_SOCKOPT 1 +#define ACE_LACKS_LSTAT 1 +#define ACE_LACKS_MADVISE 1 +#define ACE_LACKS_MKFIFO 1 +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS 1 +#define ACE_LACKS_READLINK 1 +#define ACE_LACKS_RLIMIT 1 +#define ACE_LACKS_RLIMIT_PROTOTYPE 1 +#define ACE_LACKS_SETSCHED +#define ACE_LACKS_SYSCALL 1 +#define ACE_LACKS_WCSTOULL 1 + +/* (missing) standard data types */ +#define ACE_LACKS_CONST_TIMESPEC_PTR 1 +#define ACE_LACKS_SUSECONDS_T 1 +#define ACE_HAS_IDTYPE_T 1 +#define ACE_HAS_SIGINFO_T 1 +#define ACE_HAS_XPG4_MULTIBYTE_CHAR 1 +#define ACE_HAS_SIZET_SOCKET_LEN 1 +#define ACE_HAS_SSIZE_T 1 +#define ACE_LACKS_PRI_T 1 +#define ACE_LACKS_SEMBUF_T 1 +#define ACE_LACKS_STRRECVFD 1 +#define ACE_LACKS_T_ERRNO 1 + +/* POSIX threads ompatibilities */ +#define ACE_LACKS_RWLOCK_T 1 +#define ACE_LACKS_PTHREAD_KILL 1 +#define ACE_LACKS_THREAD_PROCESS_SCOPING 1 + +#define ACE_HAS_PTHREADS 1 +#define ACE_HAS_PTHREAD_PROCESS_ENUM 1 +#define ACE_LACKS_UNNAMED_SEMAPHORE 1 +#define ACE_MT_SAFE 1 +#define ACE_HAS_THREADS 1 +#define ACE_HAS_THREAD_SPECIFIC_STORAGE 1 +#define ACE_HAS_THR_C_DEST 1 +#define ACE_HAS_THR_C_FUNC 1 +#define ACE_LACKS_PTHREAD_SIGMASK 1 +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 +#define ACE_NEEDS_HUGE_THREAD_STACKSIZE (64U*1024) +#define ACE_HAS_PTHREAD_SETCONCURRENCY 1 +#define ACE_HAS_PTHREAD_GETCONCURRENCY 1 +#define ACE_HAS_PTHREAD_SCHEDPARAM 1 + +/* language/platform conformance */ +#define ACE_NEW_THROWS_EXCEPTIONS 1 +#define ACE_TEMPLATES_REQUIRE_SOURCE 1 +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#define ACE_HAS_AUTOMATIC_INIT_FINI 1 +#define ACE_LACKS_UNIX_SIGNALS 1 + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES 1 +#define ACE_HAS_CPLUSPLUS_HEADERS 1 +#define ACE_HAS_EXCEPTIONS 1 +#define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 + +#define ACE_HAS_GPERF 1 +#define ACE_HAS_IP_MULTICAST 1 +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#define ACE_HAS_POSIX_NONBLOCK 1 +#define ACE_HAS_POSIX_TIME 1 +#define ACE_HAS_BROKEN_POSIX_TIME 1 +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#define ACE_HAS_STRING_CLASS 1 +#define ACE_HAS_SVR4_DYNAMIC_LINKING 1 + +#define ACE_HAS_TEMPLATE_TYPEDEFS 1 +#define ACE_LACKS_NAMED_POSIX_SEM 1 +#define ACE_LACKS_SYSV_SHMEM 1 +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS 1 +#define ACE_LACKS_UNIX_SYSLOG 1 +#define ACE_LACKS_ALPHASORT 1 + +#endif diff --git a/dep/ACE_wrappers/ace/config-pharlap.h b/dep/ACE_wrappers/ace/config-pharlap.h new file mode 100644 index 000000000..8a0d2792a --- /dev/null +++ b/dep/ACE_wrappers/ace/config-pharlap.h @@ -0,0 +1,90 @@ +/* -*- C++ -*- */ +// $Id: config-pharlap.h 81837 2008-06-04 22:48:08Z shuston $ + +// This configuration file is for use with the PharLap Realtime ETS Kernel. +// It has been tested with PharLap TNT Embedded ToolSuite version 9.1. + +#ifndef ACE_CONFIG_PHARLAP_H +#define ACE_CONFIG_PHARLAP_H +#include /**/ "ace/pre.h" + +#define ACE_HAS_PHARLAP +// Some features are only available with the Realtime edition of ETS. +// Assume that if using ACE, the realtime version is also being used, but +// allow it to be turned off as well. +#ifndef ACE_HAS_PHARLAP_RT +# define ACE_HAS_PHARLAP_RT +#else +# if (ACE_HAS_PHARLAP_RT == 0) +# undef ACE_HAS_PHARLAP_RT +# endif +#endif + +// Fortunately, PharLap ETS offers much of the Win32 API. But it's still on +// Winsock 1.1 +#define ACE_HAS_WINSOCK2 0 + +// The TSS implementation doesn't pass muster on the TSS_Test, but it works +// well with ACE's TSS emulation. +#define ACE_HAS_TSS_EMULATION + +#define ACE_LACKS_MMAP +#define ACE_LACKS_MPROTECT +#define ACE_LACKS_MSYNC +#define ACE_LACKS_TCP_NODELAY +#define ACE_LACKS_MSG_WFMO +#define ACE_LACKS_WIN32_MOVEFILEEX +#define ACE_LACKS_WIN32_REGISTRY +#define ACE_LACKS_WIN32_SECURITY_DESCRIPTORS +#define ACE_LACKS_WIN32_SERVICES +#define ACE_LACKS_WIN32_SETFILEPOINTEREX + +// There's no host table, by default. So using "localhost" won't work. +// If your system does have the ability to use "localhost" and you want to, +// define it before including this file. +#if !defined (ACE_LOCALHOST) +# define ACE_LOCALHOST "127.0.0.1" +#endif /* ACE_LOCALHOST */ + +// The normal Windows default stack size doesn't hold for ETS. Set what you +// want explicitly. +#if !defined (ACE_DEFAULT_THREAD_STACKSIZE) +# define ACE_DEFAULT_THREAD_STACKSIZE (1024*1024) +#endif /* ACE_DEFAULT_THREAD_STACKSIZE */ + +// Don't know how to get the page size at execution time. This is most likely +// the correct value. +#define ACE_PAGE_SIZE 4096 + +#if defined (ACE_HAS_PHARLAP_RT) +# define ACE_HAS_IP_MULTICAST + // ETS winsock doesn't define IP level socket options +//# define IP_TOS 8 +#endif /* ACE_HAS_PHARLAP_RT */ + +// Let the config-win32.h file do its thing +#undef ACE_CONFIG_H +#include "ace/config-win32.h" +// Now remove things that desktop/server Windows has but Pharlap ETS doesn't. +#undef ACE_HAS_INTERLOCKED_EXCHANGEADD +#undef ACE_HAS_WCHAR + +// PharLap's exports apparantly define LockFile, but it's documented as +// unsupported. LockFileEx is not present. +#define ACE_LACKS_FILELOCKS + +#include /**/ +#if defined (ACE_HAS_PHARLAP_RT) +# include /**/ +#define ACE_LACKS_IP_ADD_MEMBERSHIP +#endif /* ACE_HAS_PHARLAP_RT */ + +// Although IN_CLASSD is defined in both winsock.h and winsock2.h, it ends +// up undefined for Pharlap ETS builds. If this is the case, set things up +// so nothing looks like class D. +#if !defined (IN_CLASSD) +# define IN_CLASSD(i) (0) +#endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_PHARLAP_H */ diff --git a/dep/ACE_wrappers/ace/config-posix-nonetworking.h b/dep/ACE_wrappers/ace/config-posix-nonetworking.h new file mode 100644 index 000000000..7edc31d0d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-posix-nonetworking.h @@ -0,0 +1,86 @@ +/* -*- C -*- */ +// $Id: config-posix-nonetworking.h 80826 2008-03-04 14:51:23Z wotte $ + +/* The following configuration file is designed to work for RTEMS + platforms using GNU C. +*/ + +#ifndef ACE_CONFIG_POSIX_NONETWORKING_H +#define ACE_CONFIG_POSIX_NONETWORKING_H + +// Missing header files +# define ACE_LACKS_SYS_UIO_H +# define ACE_LACKS_SYS_SOCKET_H +# define ACE_LACKS_NETINET_IN_H +# define ACE_LACKS_NETDB_H +# define ACE_LACKS_ARPA_INET_H +# define ACE_LACKS_SYS_SELECT_H +# define ACE_LACKS_NET_IF_H +# define ACE_LACKS_SYSLOG_H +# define ACE_LACKS_SYS_UN_H +# define ACE_LACKS_MEMORY_H +# define ACE_LACKS_SYS_SYSCTL_H +# define ACE_LACKS_NETINET_TCP_H + +// Missing types +# define ACE_LACKS_IOVEC +# define ACE_LACKS_IN_ADDR +# define ACE_LACKS_SOCKADDR_IN +# define ACE_LACKS_SOCKADDR_UN +# define ACE_LACKS_HOSTENT +# define ACE_LACKS_SOCKADDR +# define ACE_LACKS_IP_MREQ +# define ACE_LACKS_PROTOENT +# define ACE_LACKS_SERVENT +# define ACE_LACKS_IFREQ +# define ACE_LACKS_IFCONF +# define ACE_LACKS_LINGER + +// Missing methods +# define ACE_LACKS_GETHOSTBYADDR +# define ACE_LACKS_GETHOSTBYNAME +# define ACE_LACKS_GETIPNODEBYADDR +# define ACE_LACKS_LISTEN +# define ACE_LACKS_BIND +# define ACE_LACKS_NTOHL +# define ACE_LACKS_HTONL +# define ACE_LACKS_HTONS +# define ACE_LACKS_NTOHS +# define ACE_LACKS_SELECT +# define ACE_LACKS_SOCKET +# define ACE_LACKS_SHUTDOWN +# define ACE_LACKS_SETSOCKOPT +# define ACE_LACKS_INET_ATON +# define ACE_LACKS_INET_ADDR +# define ACE_LACKS_INET_NTOA +# define ACE_LACKS_GET_BCAST_ADDR +# define ACE_LACKS_GETHOSTENT +# define ACE_LACKS_GETSERVBYNAME +# define ACE_LACKS_ACCEPT +# define ACE_LACKS_CONNECT +# define ACE_LACKS_GETPEERNAME +# define ACE_LACKS_GETSOCKNAME +# define ACE_LACKS_GETSOCKOPT +# define ACE_LACKS_RECV +# define ACE_LACKS_SEND +# define ACE_LACKS_SENDTO +# define ACE_LACKS_RECVFROM +# define ACE_LACKS_RECVMSG +# define ACE_LACKS_SENDMSG +# define ACE_LACKS_GETHOSTBYADDR_R +# define ACE_LACKS_GETPROTOBYNAME +# define ACE_LACKS_GETPROTOBYNUMBER +# define ACE_LACKS_GETSERVBYNAME +# define ACE_LACKS_READV +# define ACE_LACKS_WRITEV +# define ACE_LACKS_SOCKETPAIR +# undef ACE_HAS_MSG + +// Missing OS features +# define ACE_LACKS_UNIX_SYSLOG +# define ACE_LACKS_TCP_NODELAY + +// Missing ACE features +# define ACE_DISABLE_NOTIFY_PIPE_DEFAULT 1 + +#endif /* ACE_CONFIG_POSIX_NONETWORKING_H */ diff --git a/dep/ACE_wrappers/ace/config-posix.h b/dep/ACE_wrappers/ace/config-posix.h new file mode 100644 index 000000000..09b4e0671 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-posix.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// $Id: config-posix.h 82517 2008-08-05 19:36:26Z shuston $ + +#ifndef ACE_CONFIG_POSIX_H +#define ACE_CONFIG_POSIX_H + +#include + +/* The following POSIX constants are defined after is + * included. They are documented in: + * http://www.opengroup.org/onlinepubs/007904975/basedefs/unistd.h.html + */ +#if defined(_POSIX_REALTIME_SIGNALS) && (_POSIX_REALTIME_SIGNALS-0 != -1 ) +# if !defined(ACE_HAS_POSIX_REALTIME_SIGNALS) +# define ACE_HAS_POSIX_REALTIME_SIGNALS +# endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */ +#endif /* _POSIX_REALTIME_SIGNALS */ + +#if defined(_POSIX_ASYNCHRONOUS_IO) && (_POSIX_ASYNCHRONOUS_IO-0 != -1 ) +# if !defined(ACE_HAS_AIO_CALLS) +# define ACE_HAS_AIO_CALLS +# endif /* ACE_HAS_AIO_CALLS */ +#endif /* _POSIX_ASYNCHRONOUS_IO */ + +#if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0) +# if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES-0 != -1 ) +# if !defined(ACE_HAS_POSIX_SEM) +# define ACE_HAS_POSIX_SEM +# endif /* ACE_HAS_POSIX_SEM */ +# if defined(ACE_HAS_POSIX_SEM) +# if !defined (ACE_HAS_POSIX_SEM_TIMEOUT) && \ + (defined (_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS-0 != -1)) +# define ACE_HAS_POSIX_SEM_TIMEOUT +# endif /* ACE_HAS_POSIX_SEM_TIMEOUT && _POSIX_TIMEOUTS */ +# endif /* ACE_HAS_POSIX_SEM */ +# endif /* ACE_HAS_POSIX_SEM */ +#endif /* !ACE_MT_SAFE */ + +#if defined(_POSIX_SHARED_MEMORY_OBJECTS) && (_POSIX_SHARED_MEMORY_OBJECTS-0 != -1 ) +# if !defined(ACE_HAS_SHM_OPEN) +# define ACE_HAS_SHM_OPEN +# endif /* ACE_HAS_SHM_OPEN */ +#endif /* _POSIX_SHARED_MEMORY_OBJECTS */ + +// Check if threading enabled/disable through platform_macros +#if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0) +// Allow the user to disable use of threads by setting ACE_HAS_THREADS to 0 +// before including this file. The platform config (not macros) file can +// often detect that the compiler was invoked with or without threads support +// and set this accordingly. +# if defined (ACE_HAS_THREADS) && (ACE_HAS_THREADS == 0) +# undef ACE_HAS_THREADS +# else +# if defined(_POSIX_THREADS) && (_POSIX_THREADS-0 != -1 ) +# if !defined(ACE_HAS_THREADS) +# define ACE_HAS_THREADS +# endif /* ACE_HAS_THREADS */ + +# if !defined(ACE_HAS_PTHREADS) +# define ACE_HAS_PTHREADS +# endif /* ACE_HAS_PTHREADS */ + +# endif /* _POSIX_THREADS */ +# endif /* ACE_HAS_THREADS */ +#endif /* !ACE_MT_SAFE */ + +#if defined(_POSIX_MESSAGE_PASSING) && (_POSIX_MESSAGE_PASSING-0 != -1 ) +# if !defined(ACE_HAS_POSIX_MESSAGE_PASSING) +# define ACE_HAS_POSIX_MESSAGE_PASSING +# endif /* ACE_HAS_POSIX_MESSAGE_PASSING */ +#endif /* _POSIX_MESSAGE_PASSING */ + +#endif /* ACE_CONFIG_POSIX_H */ diff --git a/dep/ACE_wrappers/ace/config-qnx-neutrino.h b/dep/ACE_wrappers/ace/config-qnx-neutrino.h new file mode 100644 index 000000000..745b86491 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-qnx-neutrino.h @@ -0,0 +1,137 @@ +// -*- C++ -*- +// $Id: config-qnx-neutrino.h 80826 2008-03-04 14:51:23Z wotte $ +// The following configuration file is designed to work for Neutrino +// 2.0 (Beta) with GNU C++ and the POSIX (pthread) threads package. + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#define _POSIX_C_SOURCE 199506 +#define _QNX_SOURCE + +// These constants are in i386-nto/include/limits.h, but egcs +// picks up its own limits.h instead: +#define _POSIX_NAME_MAX 14 /* Max bytes in a filename */ +#define _POSIX_PATH_MAX 256 /* Num. bytes in pathname (excl. NULL) */ + +#if defined(__OPTIMIZE__) +# if defined(__X86__) + // string.h can't be used by ACE with __OPTIMIZE__. +# undef __OPTIMIZE__ +# include +# define __OPTIMIZE__ +# endif /* __X86__ */ +#endif /* __OPTIMIZE__ */ + +#include "ace/config-g++-common.h" + +// The following defines the Neutrino compiler. +// gcc should know to call g++ as necessary +#ifdef __GNUC__ +# define ACE_CC_NAME ACE_TEXT ("gcc") +#else +# define ACE_CC_NAME ACE_TEXT ("NTO compiler ??") +#endif + +// /usr/nto/include/float.h defines +// FLT_MAX_EXP 127 +// DBL_MAX_EXP 1023 +// ace expects 128 & 1024 respectively +// to set the following macros in ace/Basic_Types.h +// These macros are: +// #define ACE_SIZEOF_DOUBLE 8 +// #define ACE_SIZEOF_FLOAT 4 + +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_DIRENT +#define ACE_HAS_GETPAGESIZE +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_INLINED_OSCALLS +#define ACE_HAS_IP_MULTICAST +#define ACE_HAS_MSG +#define ACE_HAS_MT_SAFE_MKTIME +#define ACE_HAS_MUTEX_TIMEOUTS +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONCONST_SWAB +#define ACE_HAS_POSIX_SEM +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_PTHREADS +#define ACE_HAS_P_READ_WRITE +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SELECT_H +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGISMEMBER_BUG +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIG_MACROS +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_STRINGS +#define ACE_HAS_SVR4_GETTIMEOFDAY +#define ACE_HAS_TERMIOS +#define ACE_HAS_THREADS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_THR_C_DEST +#define ACE_HAS_THR_C_FUNC +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_HAS_UALARM +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_VOIDPTR_MMAP +#define ACE_HAS_VOIDPTR_SOCKOPT +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_CONST_TIMESPEC_PTR +#define ACE_LACKS_CUSERID +#define ACE_LACKS_FORK +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_NAMED_POSIX_SEM +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_POLL_H +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_SOCKET_BUFSIZ +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_STREAM_MODULES +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_TCP_NODELAY +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_T_ERRNO +#define ACE_LACKS_UALARM_PROTOTYPE +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS +#define ACE_LACKS_U_LONGLONG_T +#define ACE_MT_SAFE 1 +#define ACE_NEEDS_FUNC_DEFINITIONS +#define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 +#define ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_THR_PRI_FIFO_DEF 10 +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-qnx-rtp-62x.h b/dep/ACE_wrappers/ace/config-qnx-rtp-62x.h new file mode 100644 index 000000000..3574153ba --- /dev/null +++ b/dep/ACE_wrappers/ace/config-qnx-rtp-62x.h @@ -0,0 +1,129 @@ +// -*- C++ -*- +// $Id: config-qnx-rtp-62x.h 80826 2008-03-04 14:51:23Z wotte $ +// The following configuration file is designed to work for QNX RTP 621 +// GNU C++ and the POSIX (pthread) threads package. You can get QNX +// RTP at http://get.qnx.com +#ifndef ACE_CONFIG_QNX_RTP_62x_H +#define ACE_CONFIG_QNX_RTP_62x_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-qnx-rtp-common.h" + +///////////////////////////////////////////////////////////////// +// Definition of the features that are available. +// +// ACE_HAS Section +///////////////////////////////////////////////////////////////// +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_HAS_3_PARAM_READDIR_R +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_ALT_CUSERID +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_DIRENT +#define ACE_HAS_GETPAGESIZE +#define ACE_HAS_GETIFADDRS +// Enable gperf, this is a hosted configuration. +#define ACE_HAS_GPERF +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +//#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_IP_MULTICAST +#define ACE_HAS_MSG +#define ACE_HAS_MT_SAFE_MKTIME +#define ACE_HAS_MUTEX_TIMEOUTS +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONCONST_SWAB +#define ACE_HAS_POSIX_SEM +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_PTHREADS +#define ACE_HAS_P_READ_WRITE +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SELECT_H +#define ACE_HAS_SHM_OPEN +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGISMEMBER_BUG +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIG_MACROS +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKLEN_T +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_STRINGS +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_SVR4_GETTIMEOFDAY +#define ACE_HAS_TERMIOS +#define ACE_HAS_THREADS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_THR_C_DEST +#define ACE_HAS_THR_C_FUNC +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_HAS_UALARM +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_VOIDPTR_MMAP +#define ACE_HAS_VOIDPTR_SOCKOPT + +///////////////////////////////////////////////////////////////// +// Definition of the features that are not available. +// +// ACE_LACKS Section +///////////////////////////////////////////////////////////////// +#define ACE_LACKS_CONST_TIMESPEC_PTR +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_MADVISE +// lacks mqueue mgr or speed-up named sem by shm emulation +#define ACE_LACKS_NAMED_POSIX_SEM +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +// Multicast_Tests reports for NTO 621 frames from unsubscribed groups +#define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#define ACE_LACKS_POLL_H +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SOCKET_BUFSIZ +#define ACE_LACKS_STREAM_MODULES +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_STRPTIME +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_T_ERRNO +#define ACE_LACKS_U_LONGLONG_T +#define ACE_LACKS_ALPHASORT + +#define ACE_LACKS_RLIMIT // QNX rlimit syscalls don't work properly with ACE. + +#define ACE_MT_SAFE 1 +#define ACE_NEEDS_FUNC_DEFINITIONS +#define ACE_NEEDS_HUGE_THREAD_STACKSIZE 64000 +#define ACE_THR_PRI_FIFO_DEF 10 +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND + +#define ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK 1 + +#define ACE_SIZEOF_WCHAR 4 + +// No prototypes +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSDUP +// The default value of FD_SETSIZE is 32, but actually x86 NTO +// supports by default at least 1000 descriptors in fd_set. +#if defined( FD_SETSIZE ) +#undef FD_SETSIZE +#endif +#define FD_SETSIZE 1000 +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_QNX_RTP_62x_H*/ diff --git a/dep/ACE_wrappers/ace/config-qnx-rtp-common.h b/dep/ACE_wrappers/ace/config-qnx-rtp-common.h new file mode 100644 index 000000000..410d94e4e --- /dev/null +++ b/dep/ACE_wrappers/ace/config-qnx-rtp-common.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +// $Id: config-qnx-rtp-common.h 80826 2008-03-04 14:51:23Z wotte $ +// several macros common to various qnx neutrino version. + +#ifndef ACE_CONFIG_QNX_RTP_COMMON_H +#define ACE_CONFIG_QNX_RTP_COMMON_H +#include /**/ "ace/pre.h" + +#define _POSIX_C_SOURCE 199506 +#define _QNX_SOURCE + +// These constants are in i386-nto/include/limits.h, but egcs +// picks up its own limits.h instead: +#define _POSIX_NAME_MAX 14 /* Max bytes in a filename */ +#define _POSIX_PATH_MAX 256 /* Num. bytes in pathname (excl. NULL) */ + +#if defined(__OPTIMIZE__) +# if defined(__X86__) + // string.h can't be used by ACE with __OPTIMIZE__. +# undef __OPTIMIZE__ +# include +# define __OPTIMIZE__ +# endif /* __X86__ */ +#endif /* __OPTIMIZE__ */ + +#include "ace/config-g++-common.h" + +// The following defines the Neutrino compiler. +// gcc should know to call g++ as necessary +#ifdef __GNUC__ +# define ACE_CC_NAME ACE_TEXT ("gcc") +#else +# define ACE_CC_NAME ACE_TEXT ("QNX-RTP compiler ??") +#endif + +// /usr/nto/include/float.h defines +// FLT_MAX_EXP 127 +// DBL_MAX_EXP 1023 +// ace expects 128 & 1024 respectively +// to set the following macros in ace/Basic_Types.h +// These macros are: +#define ACE_SIZEOF_DOUBLE 8 +#define ACE_SIZEOF_FLOAT 4 + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_QNX_RTP_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-qnx-rtp-pre62x.h b/dep/ACE_wrappers/ace/config-qnx-rtp-pre62x.h new file mode 100644 index 000000000..92adf76b1 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-qnx-rtp-pre62x.h @@ -0,0 +1,151 @@ +// -*- C++ -*- +// $Id: config-qnx-rtp-pre62x.h 80826 2008-03-04 14:51:23Z wotte $ +// The following configuration file is designed to work for QNX RTP +// GNU C++ and the POSIX (pthread) threads package. You can get QNX +// RTP at http://get.qnx.com + +#ifndef ACE_CONFIG_RTP_PRE62x_H +#define ACE_CONFIG_RTP_PRE62x_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-qnx-rtp-common.h" + +///////////////////////////////////////////////////////////////// +// Definition of the features that are available. +// +// ACE_HAS Section +///////////////////////////////////////////////////////////////// + +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_DIRENT +#define ACE_HAS_GETPAGESIZE +// Enable gperf, this is a hosted configuration. +#define ACE_HAS_GPERF +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +//#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_INLINED_OSCALLS +#define ACE_HAS_IP_MULTICAST +#define ACE_HAS_MSG +#define ACE_HAS_MT_SAFE_MKTIME +#define ACE_HAS_MUTEX_TIMEOUTS +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_POSIX_SEM +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_PTHREADS +#define ACE_HAS_P_READ_WRITE +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SELECT_H +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGISMEMBER_BUG +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIG_MACROS +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +// #define ACE_HAS_SIZET_SOCKET_LEN +#define ACE_HAS_SOCKLEN_T +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_STRINGS +#define ACE_HAS_SVR4_GETTIMEOFDAY +#define ACE_HAS_TERMIOS +#define ACE_HAS_THREADS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_THR_C_DEST +#define ACE_HAS_THR_C_FUNC +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_HAS_UALARM +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_VOIDPTR_MMAP +#define ACE_HAS_VOIDPTR_SOCKOPT + +///////////////////////////////////////////////////////////////// +// Definition of the features that are not available. +// +// ACE_LACKS Section +///////////////////////////////////////////////////////////////// +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_CONST_TIMESPEC_PTR +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MUTEXATTR_PSHARED +#define ACE_LACKS_NAMED_POSIX_SEM +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_SOCKET_BUFSIZ +#define ACE_LACKS_SOCKETPAIR +// Even if the QNX RTP docs says that socket pair are +// available, there is actually no implementation of +// soket-pairs. +#define ACE_LACKS_STREAM_MODULES +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_ALPHASORT +//#define ACE_LACKS_TCP_NODELAY // Based on the QNX RTP documentation, this option seems to + // to be supported. +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_T_ERRNO +#define ACE_LACKS_UALARM_PROTOTYPE +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS +#define ACE_LACKS_U_LONGLONG_T + +#define ACE_LACKS_RLIMIT // QNX rlimit syscalls don't work properly with ACE. + +#define ACE_MT_SAFE 1 +#define ACE_NEEDS_FUNC_DEFINITIONS +#define ACE_NEEDS_HUGE_THREAD_STACKSIZE 64000 +#define ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_THR_PRI_FIFO_DEF 10 +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND + +#define ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK 1 + +#define ACE_SIZEOF_WCHAR 4 + +// Not really, but the prototype returns wchar_t instead of wchar_t * +#define ACE_LACKS_WCSSTR + +// No prototypes +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSDUP + +// And these have prototypes but no implementation +#define ACE_LACKS_WCSLEN +#define ACE_LACKS_WCSNCMP +#define ACE_LACKS_WCSCPY +#define ACE_LACKS_WCSNCPY +#define ACE_LACKS_TOWLOWER +#define ACE_LACKS_TOWUPPER +#define ACE_LACKS_WCSCMP +#define ACE_LACKS_WCSCAT +#define ACE_LACKS_WCSNCAT +#define ACE_LACKS_WCSSPN +#define ACE_LACKS_WCSCHR +#define ACE_LACKS_WCSPBRK +#define ACE_LACKS_WCSRCHR + +#define ACE_LACKS_ACE_IOSTREAM + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_RTP_PRE62x_H */ diff --git a/dep/ACE_wrappers/ace/config-qnx-rtp.h b/dep/ACE_wrappers/ace/config-qnx-rtp.h new file mode 100644 index 000000000..c55a4abb9 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-qnx-rtp.h @@ -0,0 +1,25 @@ +// -*- C++ -*- +// $Id: config-qnx-rtp.h 80826 2008-03-04 14:51:23Z wotte $ +// The following configuration file is designed to work for QNX RTP +// GNU C++ and the POSIX (pthread) threads package. You can get QNX +// RTP at http://get.qnx.com. +// This header is intended to switch between configuration for +// various NTO versions. +#ifndef ACE_CONFIG_QNX_RTP_H +#define ACE_CONFIG_QNX_RTP_H +#include /**/ "ace/pre.h" + +#include +#if !defined(_NTO_VERSION) +# error "Could not detect QNX version from macro _NTO_VERSION" +#else +# define ACE_NTO_VERS _NTO_VERSION +# if ACE_NTO_VERS < 620 +# include /**/ "ace/config-qnx-rtp-pre62x.h" +# else +# include /**/ "ace/config-qnx-rtp-62x.h" +# endif +#endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_QNX_RTP_H */ diff --git a/dep/ACE_wrappers/ace/config-rtems.h b/dep/ACE_wrappers/ace/config-rtems.h new file mode 100644 index 000000000..e2b458615 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-rtems.h @@ -0,0 +1,165 @@ +/* -*- C -*- */ +// $Id: config-rtems.h 80826 2008-03-04 14:51:23Z wotte $ + +/* The following configuration file is designed to work for RTEMS + platforms using GNU C. +*/ + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H + +#if ! defined (__ACE_INLINE__) +#define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Needed to make some prototypes visible. +// #if ! defined (_GNU_SOURCE) +// #define _GNU_SOURCE +// #endif /* ! _GNU_SOURCE */ + +// First the machine specific part +// There are no known port specific issues with the RTEMS port of ACE. +// XXX Pentium and PowerPC have high res timer support in ACE. + +// Then the compiler specific parts +#if defined (__GNUG__) + // config-g-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so + // this must appear before its #include. +# define ACE_HAS_STRING_CLASS +# include "ace/config-g++-common.h" +#else /* ! __GNUG__ */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler in ace/config-rtems.h +# endif /* __cplusplus */ +#endif /* ! __GNUG__ */ + +#include "ace/config-posix.h" + +// Completely common part :-) + +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER + +#define ACE_LACKS_ALPHASORT +#define ACE_LACKS_REGEX_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_STRINGS_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_POLL_H +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_LACKS_STRCASECMP +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_STRDUP +#define ACE_LACKS_STRTOK_R +#define ACE_LACKS_RAND_REENTRANT_FUNCTIONS +#define ACE_LACKS_REALPATH +#define ACE_LACKS_TEMPNAM + +// Temporarily, enabling this results in compile errors with +// rtems 4.6.6. +#define ACE_LACKS_WCHAR_H + +#if !defined (ACE_MT_SAFE) +#define ACE_MT_SAFE 1 +#endif + +#if ACE_MT_SAFE +# define ACE_HAS_THREADS +# define ACE_HAS_PTHREADS +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_HAS_PTHREAD_SCHEDPARAM +# define ACE_LACKS_THREAD_PROCESS_SCOPING +#else +# define ACE_HAS_POSIX_GETPWNAM_R +# define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#endif + +#define ACE_HAS_ALT_CUSERID +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_3_PARAM_READDIR_R +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_DIRENT +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_MSG +#define ACE_HAS_MT_SAFE_MKTIME +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_GETPAGESIZE +#define ACE_HAS_POSIX_SEM +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SIGACTION_CONSTP2 +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGSUSPEND +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY +#define ACE_HAS_SYS_ERRLIST +#define ACE_HAS_SYS_FILIO_H +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY +#define ACE_LACKS_EXEC +#define ACE_LACKS_FILELOCKS +#define ACE_LACKS_FORK +#define ACE_LACKS_GETPGID +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MMAP +#define ACE_LACKS_MPROTECT +#define ACE_LACKS_MSYNC +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_READLINK +#define ACE_LACKS_READV +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RLIMIT_PROTOTYPE +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETREUID_PROTOTYPE +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREGID_PROTOTYPE +#define ACE_LACKS_STRPTIME +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_UCONTEXT_H +#define ACE_HAS_NONCONST_WRITEV +#define ACE_LACKS_WRITEV +#define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 +#define ACE_NEEDS_SCHED_H +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_TERMIOS + +// rtems 4.7 or higher +#if (__RTEMS_MAJOR__ > 4) || (__RTEMS_MAJOR__ == 4 && __RTEMS_MINOR__ > 6) +# define ACE_HAS_UALARM +#else +# define ACE_HAS_NOTSUP_SC_PAGESIZE +# define ACE_LACKS_SUSECONDS_T +# define ACE_LACKS_INTPTR_T +# undef ACE_HAS_SHM_OPEN +# undef ACE_HAS_AIO_CALLS +#endif + +// __RTEMS_REVISION__ could also be used but this is broken according +// to the rtems people + +#if !defined (_POSIX_REALTIME_SIGNALS) +# define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#endif + +#if defined (ACE_LACKS_NETWORKING) +# include "ace/config-posix-nonetworking.h" +#endif + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sco-5.0.0-nothread.h b/dep/ACE_wrappers/ace/config-sco-5.0.0-nothread.h new file mode 100644 index 000000000..b83680639 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sco-5.0.0-nothread.h @@ -0,0 +1,14 @@ +/* -*- C++ -*- */ +// $Id: config-sco-5.0.0-nothread.h 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#include "ace/config-g++-common.h" +#include "ace/config-sco-5.0.0.h" + +#define ACE_HAS_GNU_CSTRING_H + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sco-5.0.0.h b/dep/ACE_wrappers/ace/config-sco-5.0.0.h new file mode 100644 index 000000000..22849e505 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sco-5.0.0.h @@ -0,0 +1,97 @@ +/* -*- C++ -*- */ +// $Id: config-sco-5.0.0.h 80826 2008-03-04 14:51:23Z wotte $ + +#ifndef ACE_CONFIG_SCO_5_0_0_H +#define ACE_CONFIG_SCO_5_0_0_H +#include /**/ "ace/pre.h" + +// Compiling for SCO. +#if !defined (SCO) +#define SCO +#endif /* SCO */ + +#if defined (SCO) && !defined (MAXPATHLEN) +#define MAXPATHLEN 1023 +#endif /* SCO */ + +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_SIG_MACROS +#define ACE_LACKS_CONST_TIMESPEC_PTR +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_STRRECVFD +#define ACE_NEEDS_FTRUNCATE +#define ACE_LACKS_MADVISE +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS + +#define ACE_DEFAULT_CLOSE_ALL_HANDLES 0 + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_NONCONST_MSGSND +#define ACE_HAS_BIG_FD_SET +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// Compiler/platform contains the file. +//#define ACE_HAS_SYS_SYSCALL_H + +// Fixes a problem with HP/UX not wrapping the mmap(2) header files +// with extern "C". +//#define ACE_HAS_BROKEN_MMAP_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Header files lack t_errno for ACE_TLI. +//#define ACE_LACKS_T_ERRNO + +// Compiler/platform supports poll(). +// #define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler supports the ssize_t typedef. +//#define ACE_HAS_SSIZE_T + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +// Note, this only works if the flag is set above! +//#define ACE_HAS_GETRUSAGE + +// Platform uses int for select() rather than fd_set. +#define ACE_HAS_SELECT_H + +// Platform has prototypes for ACE_TLI. +#define ACE_HAS_TLI_PROTOTYPES +// Platform has the XLI version of ACE_TLI. +// #define ACE_HAS_XLI + +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +#define ACE_LACKS_STRCASECMP + +// #define ACE_HAS_POSIX_TIME +#define ACE_HAS_IP_MULTICAST +#define ACE_HAS_DIRENT +#define ACE_LACKS_READDIR_R +#define ACE_HAS_GPERF + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_SCO_5_0_0_H */ diff --git a/dep/ACE_wrappers/ace/config-suncc-common.h b/dep/ACE_wrappers/ace/config-suncc-common.h new file mode 100644 index 000000000..3f0bae8a2 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-suncc-common.h @@ -0,0 +1,67 @@ +// -*- C++ -*- +// +// $Id: config-suncc-common.h 81935 2008-06-12 22:01:53Z jtc $ + +#ifndef ACE_SUNCC_COMMON_H +#define ACE_SUNCC_COMMON_H +#include /**/ "ace/pre.h" + +# define ACE_HAS_CPLUSPLUS_HEADERS +# define ACE_HAS_STDCPP_STL_INCLUDES +# define ACE_HAS_TEMPLATE_TYPEDEFS +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_HAS_STRING_CLASS +# define ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS +# define ACE_HAS_THR_C_DEST 1 +# define ACE_LACKS_SWAB +#if defined (ACE_HAS_CUSTOM_EXPORT_MACROS) && ACE_HAS_CUSTOM_EXPORT_MACROS == 0 +# undef ACE_HAS_CUSTOM_EXPORT_MACROS +#else +# ifndef ACE_HAS_CUSTOM_EXPORT_MACROS +# define ACE_HAS_CUSTOM_EXPORT_MACROS +# endif /* !ACE_HAS_CUSTOM_EXPORT_MACROS */ +# define ACE_Proper_Export_Flag __attribute__ ((visibility("default"))) +# define ACE_Proper_Import_Flag +# define ACE_EXPORT_SINGLETON_DECLARATION(T) template class ACE_Proper_Export_Flag T +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class ACE_Proper_Export_Flag SINGLETON_TYPE ; +# define ACE_IMPORT_SINGLETON_DECLARATION(T) __extension__ extern template class T +# define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) __extension__ extern template class SINGLETON_TYPE; +#endif /* ACE_HAS_CUSTOM_EXPORT_MACROS == 0 */ + +// __EXCEPTIONS is defined with -fexceptions, the egcs default. It +// is not defined with -fno-exceptions, the ACE default for g++. +// ACE_HAS_EXCEPTIONS is defined in +// include/makeinclude/wrapper_macros.GNU, so this really isn't +// necessary. Just in case . . . +# if defined (__EXCEPTIONS) && !defined (ACE_HAS_EXCEPTIONS) +# define ACE_HAS_EXCEPTIONS +# endif /* __EXCEPTIONS && ! ACE_HAS_EXCEPTIONS */ + +# if defined (ACE_HAS_EXCEPTIONS) +# define ACE_NEW_THROWS_EXCEPTIONS +# endif /* ACE_HAS_EXCEPTIONS */ + +#if (defined (i386) || defined (__i386__)) && !defined (ACE_SIZEOF_LONG_DOUBLE) +# define ACE_SIZEOF_LONG_DOUBLE 12 +#endif /* i386 */ + +#if defined (i386) || defined (__i386__) + // If running an Intel, assume that it's a Pentium so that + // ACE_OS::gethrtime () can use the RDTSC instruction. If running a + // 486 or lower, be sure to comment this out. (If not running an + // Intel CPU, this #define will not be seen because of the i386 + // protection, so it can be ignored.) +# define ACE_HAS_PENTIUM +#endif /* i386 */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) + // We define it with a -D with make depend. +# define ACE_LACKS_PRAGMA_ONCE +#endif /* ! ACE_LACKS_PRAGMA_ONCE */ + +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#include /**/ "ace/post.h" +#endif /* ACE_SUNCC_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.10.h b/dep/ACE_wrappers/ace/config-sunos5.10.h new file mode 100644 index 000000000..79ec20a63 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.10.h @@ -0,0 +1,51 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.10.h 81805 2008-05-30 10:14:59Z vzykov $ + +// The following configuration file is designed to work for SunOS 5.10 +// (Solaris 10) platforms using the SunC++ 5.x (Sun Studio 8-10), or g++ +// compilers. + +#ifndef ACE_CONFIG_H + +// ACE_CONFIG_H is defined by one of the following #included headers. + +// #include the SunOS 5.9 config, then add any SunOS 5.10 updates below. +#include "ace/config-sunos5.9.h" + +// Solaris 10 can do sem_timedwait() (see ACE_OS::sema_wait). +#define ACE_HAS_POSIX_SEM_TIMEOUT + +#define ACE_HAS_SCANDIR + +// Solaris 10 offers a useable alphasort() unlike previous Solaris versions. +#if defined (ACE_LACKS_ALPHASORT) +# undef ACE_LACKS_ALPHASORT +#endif + +// Solaris 10 offers a useable log2() unlike previous Solaris versions. +#if defined (ACE_LACKS_LOG2) +# undef ACE_LACKS_LOG2 +#endif + +// Solaris 10 delivers pthread_attr_setstack +#if defined (ACE_LACKS_PTHREAD_ATTR_SETSTACK) +# undef ACE_LACKS_PTHREAD_ATTR_SETSTACK +#endif + +// Solaris 10 introduced printf() modifiers for [s]size_t types. +#if defined (ACE_SSIZE_T_FORMAT_SPECIFIER) +# undef ACE_SSIZE_T_FORMAT_SPECIFIER +# define ACE_SSIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%zd") +#endif /* ACE_SSIZE_T_FORMAT_SPECIFIER */ + +#if defined (ACE_SIZE_T_FORMAT_SPECIFIER) +# undef ACE_SIZE_T_FORMAT_SPECIFIER +# define ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("%zu") +#endif /* ACE_SIZE_T_FORMAT_SPECIFIER */ + +// Solaris 10 offers wcstoull() +#if defined (ACE_LACKS_WCSTOULL) +# undef ACE_LACKS_WCSTOULL +#endif /* ACE_LACKS_WCSTOULL */ + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.11.h b/dep/ACE_wrappers/ace/config-sunos5.11.h new file mode 100644 index 000000000..bbfd91c82 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.11.h @@ -0,0 +1,15 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.11.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for SunOS 5.11 +// (Solaris 11) platforms using the SunC++ 5.x (Sun Studio 10-12), or g++ +// compilers. + +#ifndef ACE_CONFIG_H + +// ACE_CONFIG_H is defined by one of the following #included headers. + +// #include the SunOS 5.10 config, then add any SunOS 5.11 updates below. +#include "ace/config-sunos5.10.h" + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.4-g++.h b/dep/ACE_wrappers/ace/config-sunos5.4-g++.h new file mode 100644 index 000000000..f911da8d3 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.4-g++.h @@ -0,0 +1,181 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.4-g++.h 81697 2008-05-14 18:33:11Z johnnyw $ + +// The following configuration file is designed to work for SunOS 5.4 +// platforms using the GNU g++ compiler. + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so +// this must appear before its #include. +#define ACE_HAS_STRING_CLASS + +#include "ace/config-g++-common.h" +#define ACE_HAS_GNU_CSTRING_H + +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Platform supports pread() and pwrite() +#define ACE_HAS_P_READ_WRITE + +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_NONCONST_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +#define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYS_SYSTEMINFO_H +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports alloca() +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Platform lacks pthread_sigaction +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK + +// Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +# if !defined (_REENTRANT) +# define _REENTRANT +# endif /* _REENTRANT */ +#endif /* !ACE_MT_SAFE */ + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +/* end threading defines */ + +#define ACE_HAS_PRIOCNTL +#define ACE_NEEDS_LWP_PRIO_SET + +// Platform supports TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 +#define ACE_HAS_IDTYPE_T +#define ACE_HAS_GPERF +#define ACE_HAS_DIRENT + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.4-sunc++-4.x.h b/dep/ACE_wrappers/ace/config-sunos5.4-sunc++-4.x.h new file mode 100644 index 000000000..36a155cdb --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.4-sunc++-4.x.h @@ -0,0 +1,190 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.4-sunc++-4.x.h 81935 2008-06-12 22:01:53Z jtc $ + +// The following configuration file is designed to work for SunOS 5.4 +// platforms using the SunC++ 4.0.x compiler. + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Platform supports pread() and pwrite() +#define ACE_HAS_P_READ_WRITE + +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_NONCONST_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +#define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYS_SYSTEMINFO_H +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library. +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports alloca() +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Platform lacks pthread_sigaction +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +/* end threading defines */ + +#define ACE_HAS_PRIOCNTL +#define ACE_NEEDS_LWP_PRIO_SET + +// Reactor detects deadlock +// #define ACE_REACTOR_HAS_DEADLOCK_DETECTION + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +#define ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_SIGNED_CHAR + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +#define ACE_NEEDS_DEV_IO_CONVERSION + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 +#define ACE_HAS_IDTYPE_T + +#define ACE_HAS_GPERF +#define ACE_HAS_DIRENT + +# if defined (ACE_HAS_EXCEPTIONS) + // If exceptions are enabled and we are using Sun/CC then + // throws an exception instead of returning 0. +# define ACE_NEW_THROWS_EXCEPTIONS +# endif /* ACE_HAS_EXCEPTIONS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.5.h b/dep/ACE_wrappers/ace/config-sunos5.5.h new file mode 100644 index 000000000..3608a28ab --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.5.h @@ -0,0 +1,417 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.5.h 81971 2008-06-16 12:15:00Z parsons $ + +// This configuration file is designed to work for SunOS 5.5 platforms +// using the following compilers: +// * Sun C++ 4.2 and later (including 5.x), patched as noted below +// * g++ 2.7.2 and later, including egcs +// * Green Hills 1.8.8 and later + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#define ACE_LACKS_STDINT_H + +// alphasort() is present on earlier Solaris versions but is marked as not for +// use on non-BSD systems and not supported for use in applications that use +// system libraries or with multiple threads. So it's mostly useless. +#define ACE_LACKS_ALPHASORT + +// Solaris doesn't support log2() +#define ACE_LACKS_LOG2 + +// SunOS 5.5 does not provide getloadavg() +#define ACE_LACKS_GETLOADAVG + +// Before we do anything, we should include to +// ensure that things are set up properly. +#include + +// Sun has the posix defines so let this file sort out what Sun delivers +#include "ace/config-posix.h" + +// Compiler version-specific settings: +#if defined (__SUNPRO_CC) +# if (__SUNPRO_CC < 0x410) + // The following might not be necessary, but I can't tell: my build + // with Sun C++ 4.0.1 never completes. +# define ACE_NEEDS_DEV_IO_CONVERSION +# elif (__SUNPRO_CC >= 0x420) +# if (__SUNPRO_CC >= 0x500) + // string.h and memory.h conflict for memchr definitions +# define ACE_LACKS_MEMORY_H + // If -compat=4 is turned on, the old 4.2 settings for iostreams are used, + // but the newer, explicit instantiation is used (above) +# if (__SUNPRO_CC_COMPAT >= 5) +# define ACE_HAS_TEMPLATE_TYPEDEFS +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_HAS_THR_C_DEST +# endif /* __SUNPRO_CC_COMPAT >= 5 */ +# if defined (ACE_HAS_EXCEPTIONS) +# define ACE_HAS_NEW_NOTHROW +# else + // See /opt/SUNWspro_5.0/SC5.0/include/CC/stdcomp.h: +# define _RWSTD_NO_EXCEPTIONS 1 +# endif /* ! ACE_HAS_EXCEPTIONS */ +# elif (__SUNPRO_CC == 0x420) || (__SUNPRO_CC == 0x410) +# define ACE_LACKS_PLACEMENT_OPERATOR_DELETE +# endif /* __SUNPRO_CC >= 0x500 */ +# endif /* __SUNPRO_CC >= 0x420 */ + +# define ACE_CAST_CONST const +# define ACE_HAS_HI_RES_TIMER +# define ACE_HAS_SIG_C_FUNC /* Sun CC 5.0 needs this, 4.2 doesn't mind. */ +# define ACE_HAS_XPG4_MULTIBYTE_CHAR +# define ACE_LACKS_LINEBUFFERED_STREAMBUF +# define ACE_LACKS_SIGNED_CHAR + + // ACE_HAS_EXCEPTIONS precludes -noex in + // include/makeinclude/platform_macros.GNU. But beware, we have + // seen problems with exception handling on multiprocessor + // UltraSparcs: threaded executables core dump when threads exit. + // This problem does not seem to appear on single-processor UltraSparcs. + // And, it is solved with the application of patch + // 104631-02 "C++ 4.2: Jumbo Patch for C++ 4.2 on Solaris SPARC" + // to Sun C++ 4.2. + // To provide optimum performance, ACE_HAS_EXCEPTIONS is disabled by + // default. It can be enabled by adding "exceptions=1" to the "make" + // invocation. See include/makeinclude/platform_sunos5_sunc++.GNU + // for details. + +# if defined (ACE_HAS_EXCEPTIONS) + // If exceptions are enabled and we are using Sun/CC then + // throws an exception instead of returning 0. +# define ACE_NEW_THROWS_EXCEPTIONS +# endif /* ACE_HAS_EXCEPTIONS */ + + /* If you want to disable threading with Sun CC, remove -mt + from your CFLAGS, e.g., using make threads=0. */ + + +// Take advantage of Sun Studio 8 (Sun C++ 5.5) or better symbol +// visibility to generate improved shared library binaries. +# if (__SUNPRO_CC > 0x540) + +# if defined (ACE_HAS_CUSTOM_EXPORT_MACROS) && ACE_HAS_CUSTOM_EXPORT_MACROS == 0 +# undef ACE_HAS_CUSTOM_EXPORT_MACROS +# else +# ifndef ACE_HAS_CUSTOM_EXPORT_MACROS +# define ACE_HAS_CUSTOM_EXPORT_MACROS +# endif /* !ACE_HAS_CUSTOM_EXPORT_MACROS */ +# define ACE_Proper_Export_Flag __symbolic +# define ACE_Proper_Import_Flag __global + +# define ACE_EXPORT_SINGLETON_DECLARATION(T) template class ACE_Proper_Export_Flag T +# define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class ACE_Proper_Export_Flag SINGLETON_TYPE ; + +// # define ACE_IMPORT_SINGLETON_DECLARATION(T) extern template class T +// # define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) extern template class SINGLETON_TYPE; + +# endif /* ACE_HAS_CUSTOM_EXPORT_MACROS == 0 */ +# endif /* __SUNPRO_CC > 0x540 (> Sun C++ 5.4) */ + +#elif defined (__GNUG__) + // config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so + // this must appear before its #include. +# define ACE_HAS_STRING_CLASS +# include "ace/config-g++-common.h" +# define ACE_HAS_HI_RES_TIMER + // Denotes that GNU has cstring.h as standard, to redefine memchr(). +# define ACE_HAS_GNU_CSTRING_H +# define ACE_HAS_XPG4_MULTIBYTE_CHAR + +# if !defined (ACE_MT_SAFE) || ACE_MT_SAFE != 0 + // ACE_MT_SAFE is #defined below, for all compilers. +# if !defined (_REENTRANT) + /* If you want to disable threading, comment out the following + line. Or, add -DACE_MT_SAFE=0 to your CFLAGS, e.g., using + make threads=0. */ +# define _REENTRANT +# endif /* _REENTRANT */ +# endif /* !ACE_MT_SAFE */ + +#elif defined (ghs) + +# if !defined (ACE_MT_SAFE) || ACE_MT_SAFE != 0 + // ACE_MT_SAFE is #defined below, for all compilers. +# if !defined (_REENTRANT) + /* If you want to disable threading, comment out the following + line. Or, add -DACE_MT_SAFE=0 to your CFLAGS, e.g., using + make threads=0. */ +# define _REENTRANT +# endif /* _REENTRANT */ +# endif /* !ACE_MT_SAFE */ + +# define ACE_CONFIG_INCLUDE_GHS_COMMON +# include "ace/config-ghs-common.h" + + // To avoid warning about inconsistent declaration between Sun's + // stdlib.h and Green Hills' ctype.h. +# include + + // IOStream_Test never halts with Green Hills 1.8.9. +# define ACE_LACKS_ACE_IOSTREAM + +#else /* ! __SUNPRO_CC && ! __GNUG__ && ! ghs */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler in ace/config-sunos5.5.h +# endif /* __cplusplus */ +#endif /* ! __SUNPRO_CC && ! __GNUG__ && ! ghs */ + +#if !defined (__ACE_INLINE__) +// @note If you have link problems with undefined inline template +// functions with Sun C++, be sure that the #define of __ACE_INLINE__ +// below is not commented out. +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Platform supports the POSIX regular expression library. +// @note Please comment out the ACE_HAS_REGEX #define if you +// have link problems with g++ or egcs on SunOS 5.5. +#define ACE_HAS_REGEX + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// select()'s timeval arg is not declared as const and may be modified +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +// Platform supports pread() and pwrite() +#define ACE_HAS_P_READ_WRITE +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +#define ACE_HAS_UALARM +#define ACE_LACKS_UALARM_PROTOTYPE + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platform supports system configuration information. +#define ACE_HAS_SYS_SYSTEMINFO_H +#define ACE_HAS_SYSINFO + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// This setting was determined by running the autoconf tests. If it doesn't +// work uniformly, will need some tweaking, possibly based on other +// XPG feature-test macros. +#define ACE_HAS_CONST_CHAR_SWAB + +// Compiler/platform supports alloca() +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME + +// ACE_HAS_CLOCK_GETTIME requires linking with -lposix4. +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T +#define ACE_HAS_GETRUSAGE + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SYS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// SunOS 5.5.x does not support mkstemp +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_SYS_SYSCTL_H + +#if !(defined(_XOPEN_SOURCE) && (_XOPEN_VERSION - 0 >= 4)) +# define ACE_HAS_CHARPTR_SHMDT +#endif + +// Platform has posix getpwnam_r +#if (defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE - 0 >= 199506L) || \ + defined(_POSIX_PTHREAD_SEMANTICS) +# define ACE_HAS_POSIX_GETPWNAM_R +#endif /* _POSIX_C_SOURCE || _POSIX_PTHREAD_SEMANTICS */ + +#if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE == 1) +#if defined (_REENTRANT) || \ + (defined (_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L)) || \ + defined (_POSIX_PTHREAD_SEMANTICS) + // Compile using multi-thread libraries. +# define ACE_HAS_THREADS + +# if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +# endif /* ACE_MT_SAFE */ + + // Platform supports POSIX pthreads *and* Solaris threads, by + // default! If you only want to use POSIX pthreads, add + // -D_POSIX_PTHREAD_SEMANTICS to your CFLAGS. Or, #define it right + // here. See the Intro (3) man page for information on + // -D_POSIX_PTHREAD_SEMANTICS. +# if defined (_POSIX_PTHREAD_SEMANTICS) +# define ACE_LACKS_RWLOCK_T +# else +# define ACE_HAS_STHREADS +# endif /* ! _POSIX_PTHREAD_SEMANTICS */ + +# define ACE_HAS_PTHREADS + // . . . but only supports SCHED_OTHER scheduling policy +# define ACE_HAS_ONLY_SCHED_OTHER +# define ACE_HAS_SIGWAIT +# define ACE_HAS_SIGTIMEDWAIT +# define ACE_HAS_SIGSUSPEND +# define ACE_LACKS_PTHREAD_ATTR_SETSTACK + + // Compiler/platform has thread-specific storage +# define ACE_HAS_THREAD_SPECIFIC_STORAGE + + // Platform supports reentrant functions (i.e., all the POSIX *_r functions). +# define ACE_HAS_REENTRANT_FUNCTIONS + +# define ACE_NEEDS_LWP_PRIO_SET +# define ACE_HAS_THR_YIELD +# define ACE_LACKS_PTHREAD_YIELD +#endif /* _REENTRANT || _POSIX_C_SOURCE >= 199506L || \ + _POSIX_PTHREAD_SEMANTICS */ +#endif /* !ACE_MT_SAFE || ACE_MT_SAFE == 1 */ + +#define ACE_HAS_PRIOCNTL + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform has broken t_error() prototype. +#define ACE_HAS_BROKEN_T_ERROR + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +#define ACE_HAS_GETPAGESIZE 1 + +#define ACE_HAS_STL_MAP_CONFLICT + +#define ACE_HAS_IDTYPE_T + +#define ACE_HAS_GPERF +#define ACE_HAS_DIRENT + +#if defined (__SUNPRO_CC) +# define ACE_CC_NAME ACE_TEXT ("SunPro C++") +# define ACE_CC_MAJOR_VERSION (__SUNPRO_CC >> 8) +# define ACE_CC_MINOR_VERSION (__SUNPRO_CC & 0x00ff) +# define ACE_CC_BETA_VERSION (0) +#elif defined (__GNUG__) +# define ACE_CC_MAJOR_VERSION __GNUC__ +# define ACE_CC_MINOR_VERSION __GNUC_MINOR__ +# define ACE_CC_BETA_VERSION (0) +# if __GNUC_MINOR__ >= 90 +# define ACE_CC_NAME ACE_TEXT ("egcs") +# else +# define ACE_CC_NAME ACE_TEXT ("g++") +# endif /* __GNUC_MINOR__ */ +#endif /* __GNUG__ */ + +#if defined (i386) && (_FILE_OFFSET_BITS==32) +# define ACE_HAS_X86_STAT_MACROS +#endif /* i386 && _FILE_OFFSET_BITS==32 */ + +#define ACE_MALLOC_ALIGN ((size_t)8) +#define ACE_LACKS_SETREUID_PROTOTYPE +#define ACE_LACKS_SETREGID_PROTOTYPE + +// Solaris does indeed implement the inet_aton() function, but it is +// found in `libresolv.*'. It doesn't seem worth it to link another +// library just for that function. Just use the emulation in ACE that +// has been used for years. +#define ACE_LACKS_INET_ATON + +// Solaris doesn't have wcstoull +#define ACE_LACKS_WCSTOULL + +#if defined (_LARGEFILE_SOURCE) || (_FILE_OFFSET_BITS==64) +#undef ACE_HAS_PROC_FS +#undef ACE_HAS_PRUSAGE_T +#endif /* (_LARGEFILE_SOURCE) || (_FILE_OFFSET_BITS==64) */ + +#if defined (_POSIX_PTHREAD_SEMANTICS) || (_FILE_OFFSET_BITS == 64) || (_POSIX_C_SOURCE - 0 >= 199506L) +# define ACE_HAS_3_PARAM_READDIR_R +#endif + +// Sum of the iov_len values can't be larger then SSIZE_MAX +#define ACE_HAS_SOCK_BUF_SIZE_MAX + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.6.h b/dep/ACE_wrappers/ace/config-sunos5.6.h new file mode 100644 index 000000000..d100627a2 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.6.h @@ -0,0 +1,126 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.6.h 81935 2008-06-12 22:01:53Z jtc $ + +// The following configuration file is designed to work for SunOS 5.6 +// platforms using the SunC++ 4.x or g++ compilers. + +#ifndef ACE_CONFIG_H + +// ACE_CONFIG_H is defined by one of the following #included headers. + +// #include the SunOS 5.5 config file, then add SunOS 5.6 updates below. + +#include "ace/config-sunos5.5.h" + +#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE > 2) || \ + defined (__EXTENSIONS__) +// The asctime_r/ctime_r parameters change at POSIX.1c-1995 +# if (defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199506L) +# define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +# endif /* POSIX_C_SOURCE >= 199506L */ +# define ACE_HAS_SIGWAIT +// Hack 'cuz _POSIX_C_SOURCE > 2 and -DEXTENSIONS hides this. +# define ACE_LACKS_MADVISE_PROTOTYPE +#endif /* _POSIX_C_SOURCE > 2 || __EXTENSIONS__ */ + +// Support for the SunC++ 5.2 compiler. +// Do not undefine for compat mode < 5 +#if defined (__SUNPRO_CC) && __SUNPRO_CC > 0x510 +#if defined (__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT >= 5) +#ifdef ACE_LACKS_ACE_IOSTREAM +#undef ACE_LACKS_ACE_IOSTREAM +#endif /* ACE_LACKS_ACE_IOSTREAM */ +#endif /* defined (__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT >= 5) */ + +#ifndef ACE_LACKS_UNBUFFERED_STREAMBUF +#define ACE_LACKS_UNBUFFERED_STREAMBUF 1 +#endif /* ACE_LACKS_UNBUFFERED_STREAMBUF */ +#ifndef ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_TEMPLATES_REQUIRE_SOURCE 1 +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#ifndef ACE_HAS_TEMPLATE_TYPEDEFS +#define ACE_HAS_TEMPLATE_TYPEDEFS 1 +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ +// Forte 7 seems to botch this one... +#if __SUNPRO_CC == 0x540 +#undef ACE_HAS_TEMPLATE_TYPEDEFS +#endif +#ifndef ACE_HAS_THR_C_DEST +#define ACE_HAS_THR_C_DEST 1 +#endif /* ACE_HAS_THR_C_DEST */ +#ifndef ACE_HAS_THR_C_FUNC +#define ACE_HAS_THR_C_FUNC 1 +#endif /* ACE_HAS_THR_C_FUNC */ +#ifndef ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES 1 +#endif /* ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES */ +#ifndef ACE_HAS_SIG_C_FUNC +#define ACE_HAS_SIG_C_FUNC 1 +#endif /* ACE_HAS_SIG_C_FUNC */ +#ifndef ACE_HAS_STDCPP_STL_INCLUDES +#define ACE_HAS_STDCPP_STL_INCLUDES 1 +#endif /* ACE_HAS_STDCPP_STL_INCLUDES */ +#ifndef ACE_HAS_STRING_CLASS +#define ACE_HAS_STRING_CLASS 1 +#endif /* ACE_HAS_STRING_CLASS */ +#ifndef ACE_HAS_STANDARD_CPP_LIBRARY +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#endif /* ACE_HAS_STANDARD_CPP_LIBRARY */ +#ifndef ACE_HAS_STDCPP_STL_INCLUDES +#define ACE_HAS_STDCPP_STL_INCLUDES 1 +#endif /* ACE_HAS_STDCPP_STL_INCLUDES */ +#ifndef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ +#ifndef ACE_LACKS_IOSTREAM_FX +#define ACE_LACKS_IOSTREAM_FX 1 +#endif /* ACE_LACKS_IOSTREAM_FX */ +#ifndef ACE_LACKS_LINEBUFFERED_STREAMBUF +#define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 +#endif /* ACE_LACKS_LINEBUFFERED_STREAMBUF */ + +#endif /* defined (__SUNPRO_CC) && __SUNPRO_CC > 0x510 */ + +// SunOS 5.6 and above support mkstemp +#undef ACE_LACKS_MKSTEMP + + +// SunOS 5.6 has AIO calls. +#if !defined (ACE_HAS_AIO_CALLS) +#define ACE_HAS_AIO_CALLS +#endif /* ACE_HAS_AIO_CALLS */ + +#if !defined (ACE_HAS_POSIX_REALTIME_SIGNALS) +#define ACE_HAS_POSIX_REALTIME_SIGNALS +#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */ + +#if !defined (ACE_HAS_POSIX_MESSAGE_PASSING) +#define ACE_HAS_POSIX_MESSAGE_PASSING +#endif /* ACE_HAS_POSIX_MESSAGE_PASSING */ + +#if !defined (ACE_HAS_POSIX_SEM) +#define ACE_HAS_POSIX_SEM +#endif /* ACE_HAS_POSIX_SEM */ + +// Sunos 5.6's aio_* with RT signals is broken. +#if !defined (ACE_POSIX_AIOCB_PROACTOR) +#define ACE_POSIX_AIOCB_PROACTOR +#endif /* ACE_POSIX_AIOCB_PROACTOR */ + +// SunOS 5.6 has a buggy select +#define ACE_HAS_LIMITED_SELECT + +// SunOS 5.6 introduced shm_open, but need to turn on POSIX.1b or higher +// to pick it up. +#if defined (_POSIX_C_SOURCE) && (_POSIX_C_SOURCE > 2) +# define ACE_HAS_SHM_OPEN +#else +# undef ACE_HAS_SHM_OPEN +#endif /* _POSIX_C_SOURCE > 2 */ + +// The struct msghdr is conditional on SunOS 5.6 based on _XPG4_2 +#if defined(_XPG4_2) +# define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#endif /* _XPG4_2 */ + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.7.h b/dep/ACE_wrappers/ace/config-sunos5.7.h new file mode 100644 index 000000000..60e1d993a --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.7.h @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.7.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for SunOS 5.7 +// (Solaris 7) platforms using the SunC++ 4.x, 5.x, or g++ compilers. + +#ifndef ACE_CONFIG_H + +// ACE_CONFIG_H is defined by one of the following #included headers. + +// #include the SunOS 5.6 config file, then add SunOS 5.7 updates below. + +#include "ace/config-sunos5.6.h" + +// This may be true for earlier Solaris versions, but I can only verify +// it for Solaris 7 and later. +#define ACE_HAS_VFWPRINTF +#if defined (ACE_HAS_SHM_OPEN) +# define ACE_SHM_OPEN_REQUIRES_ONE_SLASH +#endif + +// Sun began distributing with SunOS 5.7 +#define ACE_HAS_SYS_LOADAVG_H + +// SunOS 5.7 has getloadavg() +#undef ACE_LACKS_GETLOADAVG + +#if defined (ghs) + // SunOS 5.7's /usr/include/sys/procfs_isa.h needs uint64_t, + // but /usr/include/sys/int_types.h doesn't #define it because + // _NO_LONGLONG is # +# undef ACE_HAS_PROC_FS +# undef ACE_HAS_PRUSAGE_T + +#elif defined (__SUNPRO_CC) && (__SUNPRO_CC <= 0x530) + // Wide character methods are in std:: when using SunCC 5.3 +# define ACE_WCHAR_IN_STD_NAMESPACE +#endif /* __GNUG__ || ghs */ + +// SunOS 5.7 supports SCHED_FIFO and SCHED_RR, as well as SCHED_OTHER. +#undef ACE_HAS_ONLY_SCHED_OTHER + +// SunOS 5.7 gets this right . . . +#undef ACE_HAS_BROKEN_T_ERROR + +// And doesn't need to set LWP priorities, as shown by +// performance-tests/Misc/preempt. +#undef ACE_NEEDS_LWP_PRIO_SET + +// SunOS 5.7 can support Real-Time Signals and POSIX4 AIO operations +// are supported. + +#if !defined (ACE_HAS_AIO_CALLS) +#define ACE_HAS_AIO_CALLS +#endif /* !ACE_HAS_AIO_CALLS */ + +#ifdef ACE_HAS_LIMITED_SELECT +#undef ACE_HAS_LIMITED_SELECT +#endif /* ACE_HAS_LIMITED_SELECT */ + +// SunOS 5.7 has socklen_t +#define ACE_HAS_SOCKLEN_T + +#if defined (__sparcv9) +#define _LP64 +#define ACE_SIZEOF_LONG 8 /* Needed to circumvent compiler bug #4294969 */ +#endif /* __sparcv9 */ + +#if (defined(_XOPEN_SOURCE) && (_XOPEN_VERSION - 0 == 4)) /* XPG4 or XPG4v2 */ +// 2 parameter wcstok() +#else /* XPG4 or XPG4v2 */ +# define ACE_HAS_3_PARAM_WCSTOK +#endif + +// Solaris 7 started to support /dev/poll +#define ACE_HAS_DEV_POLL + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.8.h b/dep/ACE_wrappers/ace/config-sunos5.8.h new file mode 100644 index 000000000..eb83e9149 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.8.h @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.8.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for SunOS 5.8 +// (Solaris 8) platforms using the SunC++ 4.x, 5.x, 6.x, or g++ compilers. + +#ifndef ACE_CONFIG_H + +// ACE_CONFIG_H is defined by one of the following #included headers. + +// #include the SunOS 5.7 config, then add any SunOS 5.8 updates below. +#include "ace/config-sunos5.7.h" + +#undef ACE_WCHAR_IN_STD_NAMESPACE + +// This may be true for versions prior to Solaris 8 as well, but I don't +// have any to try it on. +#if !defined (ACE_HAS_TIMEZONE) +# define ACE_HAS_TIMEZONE +#endif + +// The range of thread priorities for 5.8 differs from 5.7 in the +// minimum priority for the SCHED_OTHER policy (i.e., +// ACE_THR_PRI_OTHER_MIN) +# define ACE_THR_PRI_OTHER_MIN (long) -20 + +# if defined (_POSIX_PTHREAD_SEMANTICS) +# ifdef ACE_LACKS_RWLOCK_T +# undef ACE_LACKS_RWLOCK_T +# endif /* ACE_LACKS_RWLOCK_T */ +# endif /* _POSIX_PTHREAD_SEMANTICS */ + +// This is no longer the case for Sun 5.9 onwards +# undef ACE_HAS_X86_STAT_MACROS + +// gethostbyaddr does not handle IPv6-mapped-IPv4 addresses +#define ACE_HAS_BROKEN_GETHOSTBYADDR_V4MAPPED + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-sunos5.9.h b/dep/ACE_wrappers/ace/config-sunos5.9.h new file mode 100644 index 000000000..0e6aa8d5b --- /dev/null +++ b/dep/ACE_wrappers/ace/config-sunos5.9.h @@ -0,0 +1,18 @@ +/* -*- C++ -*- */ +// $Id: config-sunos5.9.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for SunOS 5.9 +// (Solaris 9) platforms using the SunC++ 5.x (Forte 6 and 7), or g++ +// compilers. + +#ifndef ACE_CONFIG_H + +// ACE_CONFIG_H is defined by one of the following #included headers. + +// #include the SunOS 5.8 config, then add any SunOS 5.9 updates below. +#include "ace/config-sunos5.8.h" + +#define ACE_HAS_SENDFILE +#define ACE_LACKS_THR_CONCURRENCY_FUNCS + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-tandem-nsk-mips-v2.h b/dep/ACE_wrappers/ace/config-tandem-nsk-mips-v2.h new file mode 100644 index 000000000..20d555321 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-tandem-nsk-mips-v2.h @@ -0,0 +1,401 @@ +// -*- C++ -*- +// +// $Id: config-tandem-nsk-mips-v2.h 81935 2008-06-12 22:01:53Z jtc $ + +#ifndef ACE_CONFIG_NSK_H +#define ACE_CONFIG_NSK_H + +#include /**/ "ace/pre.h" + +// The following configuration file contains defines for Tandem NSK +// platform, MIPS processor, version 2 C++ compiler. + + +//========================================================================= +// Tandem NSK specific parts +//========================================================================= + + +// Disable pthread renaming of symbols such as "open" and "close" +#define _CMA_NOWRAPPERS_ 1 + +// Get Handle_Set.cpp to generate correct bit operations for NSK platform +#define ACE_TANDEM_NSK_BIT_ORDER + +// Use facilities provided by T1248 version of pthreads. +// (If not defined, will use old version of pthreads.) +#define ACE_TANDEM_T1248_PTHREADS + +// Use all available T1248 thread aware wrapper functions for providing +// non-blocking I/O. +// [@note this causes a significant performance degradation] +//#define ACE_TANDEM_T1248_PTHREADS_ALL_IO_WRAPPERS + + +// Need this include here because some symbols defined by pthreads +// (e.g. timespec_t) are needed before spthread.h is normally included +// by ACE +#ifdef ACE_TANDEM_T1248_PTHREADS +#include +#else +#include "pthread.h" +#include "dce/cma_dispatch_coop.h" +#endif + +// The following #defines are hacks to get around things +// that seem to be missing or different in Tandem land +#define NSIG 32 // missing from Signal.h + // note: on nsk TNS/R there is room in + // sigset_t for 128 signals but those + // above 31 are not valid. +typedef long fd_mask; // should be in select.h but no such file +#define NBBY 8 // must be consistent with value in sys/types.h +#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */ +#define MAXNAMLEN 248 // missing from dirent.h +#define ERRMAX 4218 // from errno.h + +// Following seems to be missing from G06.20 version of standard +// pthreads includes (it appeared in older version of standard pthreads) +// (SCHED_FIFO (aka cma_c_sched_fifo) used in Dynamic_Priority_Test) +#ifdef ACE_TANDEM_T1248_PTHREADS +typedef enum CMA_T_SCHED_POLICY { + cma_c_sched_fifo = 0, + cma_c_sched_rr = 1, + cma_c_sched_throughput = 2, + cma_c_sched_background = 3, + cma_c_sched_ada_low = 4 + } cma_t_sched_policy; +#endif + +// T1248 doesn't define these constants. They're defined in spt/cma.h +// (formerly dce/cma.h), but this header is not included or provided +// by T1248 G07-AAL. +#define cma_c_prio_fifo_min 16 +#define cma_c_prio_fifo_mid 24 +#define cma_c_prio_fifo_max 31 +#define cma_c_prio_rr_min 16 +#define cma_c_prio_rr_mid 24 +#define cma_c_prio_rr_max 31 +#define cma_c_prio_through_min 8 +#define cma_c_prio_through_mid 12 +#define cma_c_prio_through_max 15 +#define cma_c_prio_back_min 1 +#define cma_c_prio_back_mid 4 +#define cma_c_prio_back_max 7 + +// Enable NSK Pluggable Protocols +#define TAO_HAS_NSKPW 1 +#define TAO_HAS_NSKFS 1 + +//========================================================================= +// Platform specific parts +//========================================================================= + +// Platform lacks getpwnam_r() methods (e.g., SGI 6.2). +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS + +// Platform/compiler lacks {get,set}rlimit() function +#define ACE_LACKS_RLIMIT + +// The platform doesn't have mmap(2) +#define ACE_LACKS_MMAP + +// Platform lacks streambuf "linebuffered ()". [C++ iostream] +#define ACE_LACKS_LINEBUFFERED_STREAMBUF + +// Platform supports recvmsg and sendmsg +#define ACE_HAS_MSG + +// Platform defines ACE_HAS_MSG, but lacks msg_accrights{,len}. +#define ACE_LACKS_MSG_ACCRIGHTS + +// Platform supports sigsuspend() +#define ACE_HAS_SIGSUSPEND + +// Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// OS/compiler uses size_t * rather than int * for socket lengths +#define ACE_HAS_SIZET_SOCKET_LEN + +// OS/compiler uses void * arg 4 setsockopt() rather than const char * +#define ACE_HAS_VOIDPTR_SOCKOPT + +// The platform doesn't have mprotect(2) +#define ACE_LACKS_MPROTECT + +// Platform lacks msync() +#define ACE_LACKS_MSYNC + +// Platform does not support reentrant netdb functions (getprotobyname_r, +// getprotobynumber_r, gethostbyaddr_r, gethostbyname_r, getservbyname_r). +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS Platform does not support + +// Platform lacks madvise() +#define ACE_LACKS_MADVISE + +// Platform lacks pri_t +#define ACE_LACKS_PRI_T + +// Platform lacks a working sbrk() +#define ACE_LACKS_SBRK + +// Platform doesn't have syscall() prototype +#define ACE_LACKS_SYSCALL + +// Platform lacks the inet_aton() function. +#define ACE_LACKS_INET_ATON + +// Compiler/platform has Dirent iterator functions +#define ACE_HAS_DIRENT + +// Platform uses ACE_HAS_DIRENT but does not have readdir_r() +#define ACE_LACKS_READDIR_R + +// Platform supports getpagesize() call (otherwise, +// ACE_PAGE_SIZE must be defined) +#define ACE_HAS_GETPAGESIZE + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Platform's select() uses non-const timeval* +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +// Platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// Platform lacks named POSIX semaphores +#define ACE_LACKS_NAMED_POSIX_SEM + +// Platform has support for multi-byte character support compliant +// with the XPG4 Worldwide Portability Interface wide-character +// classification. +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +// No wcsstr function available for this compiler +#define ACE_LACKS_WCSSTR + +// No wctype.h available for this compiler +#define ACE_LACKS_WCTYPE_H + +// Platform supports the POSIX regular expression library. +// [Note Tandem NSK platform does have regular expresson support but it +// does not follow the assumptions made by ACE. To use it would need +// to make some ACE modifications.] +//#define ACE_HAS_REGEX + +// Compiler/platform supports strerror () +#define ACE_HAS_STRERROR + +// Platform doesn't have truncate() +#define ACE_LACKS_TRUNCATE + +// Platform lacks readers/writer locks. +#define ACE_LACKS_RWLOCK_T + +// Compiler's 'new' throws exception on failure (ANSI C++ behavior). +#define ACE_NEW_THROWS_EXCEPTIONS + +// Optimize ACE_Handle_Set::count_bits for select() operations (common +// case) +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Platform lacks setreuid() +#define ACE_LACKS_SETREUID + +// Platform lacks setregid() +#define ACE_LACKS_SETREGID + +// Compile using multi-thread libraries +#define ACE_MT_SAFE 1 + + + +// Platform supports System V IPC +#define ACE_HAS_SYSV_IPC + +// Platform lacks the socketpair() call +// [Needed due to failure of Pipe_Test. even though nsk platform +// has socketpair(), Pipe.cpp tries to set socket buf size but this +// is not allowed for AF_UNIX protocol on nsk.] +#define ACE_LACKS_SOCKET_BUFSIZ + +// Platform lacks the socketpair() call +#define ACE_LACKS_SOCKETPAIR + +// Platform limits the maximum socket message size. +#define ACE_HAS_SOCK_BUF_SIZE_MAX + +// hrtime_t is a basic type that doesn't require ACE_U64_TO_U32 conversion +#define ACE_HRTIME_T_IS_BASIC_TYPE + +// printf format specifiers for 64 bit integers +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%Ld") +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%Ld") + +//========================================================================= +// Threads specific parts +//========================================================================= + +// Platform supports threads +#define ACE_HAS_THREADS + +// Platform supports POSIX Pthreads, of one form or another. This +// macro says the platform has a pthreads variety - should also define +// one of the below to say which one. Also may need some +// ACE_HAS_... thing for extensions. +#define ACE_HAS_PTHREADS + +// Standard pthreads supports only SCHED_FIFO +#define ACE_HAS_ONLY_SCHED_FIFO + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform has no implementation of pthread_condattr_setpshared(), +// even though it supports pthreads! +#define ACE_LACKS_CONDATTR_PSHARED + +// pthread_cond_timedwait does *not* reset the time argument when the +// lock is acquired. +#define ACE_LACKS_COND_TIMEDWAIT_RESET + +// Platform lacks pthread_attr_setsched() +#define ACE_LACKS_SETSCHED + +// Platform has pthread_mutexattr_setkind_np(). +#define ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP + +// Platform lacks pthread_mutexattr_setpshared(). +#define ACE_LACKS_MUTEXATTR_PSHARED + +// Platform lacks pthread_attr_setscope() +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +// Platform lacks pthread_attr_setstackaddr +#define ACE_LACKS_PTHREAD_ATTR_SETSTACKADDR + +// Defining ACE_HAS_UCONTEXT_T since G06.21 version of spthreads has +// a definition for it. +#ifdef ACE_TANDEM_T1248_PTHREADS +#define ACE_HAS_UCONTEXT_T +#endif + +//========================================================================= +// Include file characteristics +//========================================================================= + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Platform lacks malloc.h +#define ACE_LACKS_MALLOC_H + +// Platform lacks the siginfo.h include file +#define ACE_LACKS_SIGINFO_H + +// Platform doesn't define struct strrecvfd. +#define ACE_LACKS_STRRECVFD + +// Platform lacks the ucontext.h file +#define ACE_LACKS_UCONTEXT_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platform supports the POSIX struct timespec type +#define ACE_HAS_POSIX_TIME + +// Platform/compiler supports timezone * as second parameter to gettimeofday() +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +// Platform has (which contains bzero() prototype) +#define ACE_HAS_STRINGS 1 + + +// OS/compiler omits the const from the iovec parameter in the +// writev() prototype. +#define ACE_HAS_NONCONST_WRITEV + +// Platform lacks +#define ACE_LACKS_STDINT_H + +// Platform lacks +#define ACE_LACKS_INTTYPES_H + +// Platform lacks +#define ACE_LACKS_SYS_SELECT_H + +// Platform lacks +#define ACE_LACKS_DLFCN_H + +// Platform lacks +#define ACE_LACKS_SEMAPHORE_H + +// Platform lacks +#define ACE_LACKS_POLL_H + +//========================================================================= +// Compiler specific parts +//========================================================================= + +// Compiler supports C++ exception handling +#define ACE_HAS_EXCEPTIONS + +// Compiler/platform has correctly prototyped header files +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform does not support the unsigned long long datatype. +#define ACE_LACKS_LONGLONG_T + +// Compiler supports the ssize_t typedef +#define ACE_HAS_SSIZE_T + +// Platform/compiler supports Standard C++ Library +#define ACE_HAS_STANDARD_CPP_LIBRARY 0 + +// Compiler's template mechanism must see source code (i.e., +// .cpp files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Compiler implements templates that support typedefs inside +// of classes used as formal arguments to a template class. +#define ACE_HAS_TEMPLATE_TYPEDEFS + +// Platform has its standard c++ library in the namespace std. +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 + +// Compiler doesn't support static data member templates +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Platform lacks "signed char" type (broken!) +// Following will not be needed if use standard c library (G06.20 and later) +#define ACE_LACKS_SIGNED_CHAR + +//========================================================================= +// Build options +//========================================================================= + +// Disable the inclusion of RCS ids in the generated code. +#define ACE_USE_RCSID 0 + +// For debugging problems in os calls (but this doesn't work too well +// since output is not interleaved properly with output from ACE_TRACE +//# define ACE_OS_TRACE(X) ::printf(X) + +// Uncomment the following if timed message blocks are needed (e.g. +// for Dynamic_Priority_Test. Otherwise leave this disabled because +// enabling it adds overhead to message blocks and timed message blocks +// are "rarely used." +//#define ACE_HAS_TIMED_MESSAGE_BLOCKS + +// Uncomment the following if tokens library is needed. +//#define ACE_HAS_TOKENS_LIBRARY + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_NSK_H */ diff --git a/dep/ACE_wrappers/ace/config-tandem-nsk-mips-v3.h b/dep/ACE_wrappers/ace/config-tandem-nsk-mips-v3.h new file mode 100644 index 000000000..0e6fd291c --- /dev/null +++ b/dep/ACE_wrappers/ace/config-tandem-nsk-mips-v3.h @@ -0,0 +1,471 @@ +// -*- C++ -*- +// +// $Id: config-tandem-nsk-mips-v3.h 81935 2008-06-12 22:01:53Z jtc $ + + +#ifndef ACE_CONFIG_NSK_H +#define ACE_CONFIG_NSK_H + +#include /**/ "ace/pre.h" + +// The following configuration file contains defines for Tandem NSK +// platform, MIPS processor, version 3 C++ compiler. + + +//========================================================================= +// Tandem NSK specific parts +//========================================================================= + + +// Disable pthread renaming of symbols such as "open" and "close" +#define _CMA_NOWRAPPERS_ 1 + +// Get Handle_Set.cpp to generate correct bit operations for NSK platform +#define ACE_TANDEM_NSK_BIT_ORDER + +// Use facilities provided by T1248 version of pthreads. +// (If not defined, will use old version of pthreads.) +#define ACE_TANDEM_T1248_PTHREADS + +// Use all available T1248 thread aware wrapper functions for providing +// non-blocking I/O. +// [Note: this causes a significant performance degradation] +//#define ACE_TANDEM_T1248_PTHREADS_ALL_IO_WRAPPERS + + +// Need this include here because some symbols defined by pthreads +// (e.g. timespec_t) are needed before spthread.h is normally included +// by ACE +#ifdef ACE_TANDEM_T1248_PTHREADS +#include +#else +#include "pthread.h" +#include "dce/cma_dispatch_coop.h" +#endif + +// The following #defines are hacks to get around things +// that seem to be missing or different in Tandem land +#define NSIG 32 // missing from Signal.h + // note: on nsk TNS/R there is room in + // sigset_t for 128 signals but those + // above 31 are not valid. +typedef long fd_mask; // should be in select.h but no such file +#define NBBY 8 // must be consistent with value in sys/types.h +#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */ +#define MAXNAMLEN 248 // missing from dirent.h +#define ERRMAX 4218 // from errno.h + +// Following seems to be missing from G06.20 version of standard +// pthreads includes (it appeared in older version of standard pthreads) +// (SCHED_FIFO (aka cma_c_sched_fifo) used in Dynamic_Priority_Test) +#ifdef ACE_TANDEM_T1248_PTHREADS +typedef enum CMA_T_SCHED_POLICY { + cma_c_sched_fifo = 0, + cma_c_sched_rr = 1, + cma_c_sched_throughput = 2, + cma_c_sched_background = 3, + cma_c_sched_ada_low = 4 + } cma_t_sched_policy; +#endif + +// T1248 doesn't define these constants. They're defined in spt/cma.h +// (formerly dce/cma.h), but this header is not included or provided +// by T1248 G07-AAL. +#define cma_c_prio_fifo_min 16 +#define cma_c_prio_fifo_mid 24 +#define cma_c_prio_fifo_max 31 +#define cma_c_prio_rr_min 16 +#define cma_c_prio_rr_mid 24 +#define cma_c_prio_rr_max 31 +#define cma_c_prio_through_min 8 +#define cma_c_prio_through_mid 12 +#define cma_c_prio_through_max 15 +#define cma_c_prio_back_min 1 +#define cma_c_prio_back_mid 4 +#define cma_c_prio_back_max 7 + +// Enable NSK Pluggable Protocols +#define TAO_HAS_NSKPW 1 +#define TAO_HAS_NSKFS 1 + +//========================================================================= +// Platform specific parts +//========================================================================= + +// Platform lacks getpwnam_r() methods (e.g., SGI 6.2). +#define ACE_LACKS_PWD_REENTRANT_FUNCTIONS + +// Platform/compiler lacks {get,set}rlimit() function +#define ACE_LACKS_RLIMIT + +// The platform doesn't have mmap(2) +#define ACE_LACKS_MMAP + +// Platform lacks streambuf "linebuffered ()". [C++ iostream] +#define ACE_LACKS_LINEBUFFERED_STREAMBUF + +// Platform supports recvmsg and sendmsg +#define ACE_HAS_MSG + +// Platform defines ACE_HAS_MSG, but lacks msg_accrights{,len}. +#define ACE_LACKS_MSG_ACCRIGHTS + +// Platform supports sigsuspend() +#define ACE_HAS_SIGSUSPEND + +// Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// OS/compiler uses size_t * rather than int * for socket lengths +#define ACE_HAS_SIZET_SOCKET_LEN + +// OS/compiler uses void * arg 4 setsockopt() rather than const char * +#define ACE_HAS_VOIDPTR_SOCKOPT + +// The platform doesn't have mprotect(2) +#define ACE_LACKS_MPROTECT + +// Platform lacks msync() +#define ACE_LACKS_MSYNC + +// Platform does not support reentrant netdb functions (getprotobyname_r, +// getprotobynumber_r, gethostbyaddr_r, gethostbyname_r, getservbyname_r). +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS Platform does not support + +// Platform lacks madvise() +#define ACE_LACKS_MADVISE + +// Platform lacks pri_t +#define ACE_LACKS_PRI_T + +// Platform lacks a working sbrk() +#define ACE_LACKS_SBRK + +// Platform doesn't have syscall() prototype +#define ACE_LACKS_SYSCALL + +// Platform lacks the inet_aton() function. +#define ACE_LACKS_INET_ATON + +// Compiler/platform has Dirent iterator functions +#define ACE_HAS_DIRENT + +// Platform uses ACE_HAS_DIRENT but does not have readdir_r() +#define ACE_LACKS_READDIR_R + +// Platform supports getpagesize() call (otherwise, +// ACE_PAGE_SIZE must be defined) +#define ACE_HAS_GETPAGESIZE + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Platform's select() uses non-const timeval* +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +// Platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// Platform lacks named POSIX semaphores +#define ACE_LACKS_NAMED_POSIX_SEM + +// Platform has support for multi-byte character support compliant +// with the XPG4 Worldwide Portability Interface wide-character +// classification. +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +// No wcsstr function available for this compiler +#define ACE_LACKS_WCSSTR + +// No wctype.h available for this compiler +#define ACE_LACKS_WCTYPE_H + +// Platform supports the POSIX regular expression library. +// [Note Tandem NSK platform does have regular expresson support but it +// does not follow the assumptions made by ACE. To use it would need +// to make some ACE modifications.] +//#define ACE_HAS_REGEX + +// Compiler/platform supports strerror () +#define ACE_HAS_STRERROR + +// Platform doesn't have truncate() +#define ACE_LACKS_TRUNCATE + +// Platform lacks readers/writer locks. +#define ACE_LACKS_RWLOCK_T + +// Compiler's 'new' throws exception on failure (ANSI C++ behavior). +#define ACE_NEW_THROWS_EXCEPTIONS + +// Optimize ACE_Handle_Set::count_bits for select() operations (common +// case) +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Platform lacks setreuid() +#define ACE_LACKS_SETREUID + +// Platform lacks setregid() +#define ACE_LACKS_SETREGID + +// Compile using multi-thread libraries +#define ACE_MT_SAFE 1 + + + +// Platform supports System V IPC +#define ACE_HAS_SYSV_IPC + +// Platform lacks the socketpair() call +// [Needed due to failure of Pipe_Test. even though nsk platform +// has socketpair(), Pipe.cpp tries to set socket buf size but this +// is not allowed for AF_UNIX protocol on nsk.] +#define ACE_LACKS_SOCKET_BUFSIZ + +// Platform lacks the socketpair() call +#define ACE_LACKS_SOCKETPAIR + +// Platform limits the maximum socket message size. +#define ACE_HAS_SOCK_BUF_SIZE_MAX + +// hrtime_t is a basic type that doesn't require ACE_U64_TO_U32 conversion +#define ACE_HRTIME_T_IS_BASIC_TYPE + +// printf format specifiers for 64 bit integers +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%Ld") +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%Ld") + +// Use larger default buffer size for ease of interoperability +#define ACE_DEFAULT_CDR_BUFSIZE 4096 + +// Size of a wchar +#define ACE_SIZEOF_WCHAR 2 + +// Platform lacks time typedefs +#define ACE_LACKS_SUSECONDS_T +#define ACE_LACKS_USECONDS_T + +// Platform lacks setegid() and seteuid() +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETEUID + +// Platform lacks vsnprintf() +#define ACE_LACKS_VSNPRINTF + +// Platform lacks log2() +#define ACE_LACKS_LOG2 + +// Platform lacks alphasort() +#define ACE_LACKS_ALPHASORT + + +//========================================================================= +// Threads specific parts +//========================================================================= + +// Platform supports threads +#define ACE_HAS_THREADS + +// Platform supports POSIX Pthreads, of one form or another. This +// macro says the platform has a pthreads variety - should also define +// one of the below to say which one. Also may need some +// ACE_HAS_... thing for extensions. +#define ACE_HAS_PTHREADS + +// Standard pthreads supports only SCHED_FIFO +#define ACE_HAS_ONLY_SCHED_FIFO + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform has no implementation of pthread_condattr_setpshared(), +// even though it supports pthreads! +#define ACE_LACKS_CONDATTR_PSHARED + +// pthread_cond_timedwait does *not* reset the time argument when the +// lock is acquired. +#define ACE_LACKS_COND_TIMEDWAIT_RESET + +// Platform lacks pthread_attr_setsched() +#define ACE_LACKS_SETSCHED + +// Platform has pthread_getschedparam and pthread_setschedparam +// even when ACE_LACKS_SETSCHED is defined. +#define ACE_HAS_PTHREAD_SCHEDPARAM + +// Platform has pthread_mutexattr_setkind_np(). +#define ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP + +// Platform lacks pthread_mutexattr_setpshared(). +#define ACE_LACKS_MUTEXATTR_PSHARED + +// Platform lacks pthread_attr_setscope() +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +// Platform lacks pthread_attr_setstackaddr +#define ACE_LACKS_PTHREAD_ATTR_SETSTACKADDR + +// Platform lacks pthread_attr_setstack +#define ACE_LACKS_PTHREAD_ATTR_SETSTACK + +// Defining ACE_HAS_UCONTEXT_T since G06.21 version of spthreads has +// a definition for it. +#ifdef ACE_TANDEM_T1248_PTHREADS +#define ACE_HAS_UCONTEXT_T +#endif + +//========================================================================= +// Include file characteristics +//========================================================================= + +// Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +// Platform lacks malloc.h +#define ACE_LACKS_MALLOC_H + +// Platform lacks the siginfo.h include file +#define ACE_LACKS_SIGINFO_H + +// Platform doesn't define struct strrecvfd. +#define ACE_LACKS_STRRECVFD + +// Platform lacks the ucontext.h file +#define ACE_LACKS_UCONTEXT_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platform supports the POSIX struct timespec type +#define ACE_HAS_POSIX_TIME + +// Platform/compiler supports timezone * as second parameter to gettimeofday() +#define ACE_HAS_TIMEZONE_GETTIMEOFDAY + +// Platform has (which contains bzero() prototype) +#define ACE_HAS_STRINGS 1 + + +// OS/compiler omits the const from the iovec parameter in the +// writev() prototype. +#define ACE_HAS_NONCONST_WRITEV + +// Platform lacks +#define ACE_LACKS_STDINT_H + +// Platform lacks +#define ACE_LACKS_INTTYPES_H + +// Platform lacks +#define ACE_LACKS_SYS_SELECT_H + +// Platform lacks +#define ACE_LACKS_DLFCN_H + +// Platform lacks +#define ACE_LACKS_SEMAPHORE_H + +// Platform lacks +#define ACE_LACKS_POLL_H + +// Platform lacks +#define ACE_LACKS_SYS_SYSCTL_H + +//========================================================================= +// Compiler specific parts +//========================================================================= + +// Compiler supports C++ exception handling +#define ACE_HAS_EXCEPTIONS 1 + +// Compiler/platform has correctly prototyped header files +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform does not support the unsigned long long datatype. +#define ACE_LACKS_UNSIGNEDLONGLONG_T + +// Compiler supports the ssize_t typedef +#define ACE_HAS_SSIZE_T + +// Platform/compiler supports Standard C++ Library +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 + +// Compiler's template mechanism must see source code (i.e., +// .cpp files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Compiler implements templates that support typedefs inside +// of classes used as formal arguments to a template class. +#define ACE_HAS_TEMPLATE_TYPEDEFS + +// Platform/Compiler supports a String class +#define ACE_HAS_STRING_CLASS +#define ACE_HAS_STDCPP_STL_INCLUDES + +// Platform has its standard c++ library in the namespace std. +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 + +// Compiler doesn't support static data member templates +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Platform lacks "signed char" type (broken!) +// Following will not be needed if use standard c library (G06.20 and later) +#define ACE_LACKS_SIGNED_CHAR + +// Compiler can handle any operators in namespace +#define ACE_ANY_OPS_USE_NAMESPACE + +// Platform lacks intptr_t typedef +#define ACE_LACKS_INTPTR_T + +//========================================================================= +// C++ version3 import/export macros +//========================================================================= + +// Define the export macros needed to export symbols outside a DLL +// The ACE_IMPORT_SINGLETON_DECLARE macro has been modified to not explicitly +// instantiate the class template. +#if defined(USE_EXPLICIT_EXPORT) +#define ACE_LACKS_INLINE_FUNCTIONS + +#define ACE_HAS_CUSTOM_EXPORT_MACROS +#define ACE_Proper_Export_Flag export$ +#define ACE_Proper_Import_Flag import$ +#define ACE_EXPORT_SINGLETON_DECLARATION(T) template class export$ T +#define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class export$ SINGLETON_TYPE; +#define ACE_IMPORT_SINGLETON_DECLARATION(T) template class import$ T +#define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class import$ SINGLETON_TYPE ; +#endif + + +//========================================================================= +// Build options +//========================================================================= + +// Disable the inclusion of RCS ids in the generated code. +#define ACE_USE_RCSID 0 + +// For debugging problems in os calls (but this doesn't work too well +// since output is not interleaved properly with output from ACE_TRACE +//# define ACE_OS_TRACE(X) ::printf(X) + +// Uncomment the following if timed message blocks are needed (e.g. +// for Dynamic_Priority_Test. Otherwise leave this disabled because +// enabling it adds overhead to message blocks and timed message blocks +// are "rarely used." +//#define ACE_HAS_TIMED_MESSAGE_BLOCKS + +// Uncomment the following if tokens library is needed. +//#define ACE_HAS_TOKENS_LIBRARY + +// NonStop CORBA uses the XML Service Configurator +#define ACE_HAS_XML_SVC_CONF + +#define ACE_LD_SEARCH_PATH "_RLD_LIB_PATH" + +#include /**/ "ace/post.h" + +#endif /* ACE_CONFIG_NSK_H */ diff --git a/dep/ACE_wrappers/ace/config-tandem.h b/dep/ACE_wrappers/ace/config-tandem.h new file mode 100644 index 000000000..981fdfb2d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-tandem.h @@ -0,0 +1,193 @@ +/* -*- C++ -*- */ +// Testing TANDEM +// $Id: config-tandem.h 81697 2008-05-14 18:33:11Z johnnyw $ + +// The following configuration file is designed to work for Tandems NonStop-UX +// 4.2MP platforms using the NCC 3.20 compiler. + +// Note this is a test version it might include several errors I +// have done a test and set/unset until I errors disappered. +// Some of the options that should be set aren't because of the simple fact +// that i haven't the time to check what is wrong. +// e.g. widecharacter are supported but a wcstok which only take 2 parameters +// are included by the compiler, to get the correct wcstok that takes 3 params +// we must set _XOPEN_SOURCE and we get ALOT of errors and warnings. +// So this config is done to get things to start to work it isn't finished. +// Janne (Jan.Perman@osd.Ericsson.se) + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +#define ACE_HAS_IDTYPE_T +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Tandem doesn't include this although they are defined +// in sys/time.h and sys/resource.h +#define ACE_LACKS_RLIMIT_PROTOTYPE // jjpp +// Tandem has a function to set t_errno (set_t_errno) +#define ACE_HAS_SET_T_ERRNO // jjpp + +//Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// OS/compiler omits the const from the sendmsg() prototype. +#define ACE_HAS_NONCONST_SENDMSG + +//Platform supports system configuration information +#define ACE_HAS_SYS_SYSTEMINFO_H +#define ACE_HAS_SYSINFO + +//Platform supports the POSIX regular expression library +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg +#define ACE_HAS_MSG + +//Compiler/platform contains the file. +#define ACE_HAS_SYS_SYSCALL_H + +//Platform provides header +#define ACE_HAS_SYSENT_H + +// Platform has POSIX terminal interface. +#define ACE_HAS_TERMIOS + +//Platform supports POSIX O_NONBLOCK semantics +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files +#define ACE_HAS_CPLUSPLUS_HEADERS + +//Compiler/platform supports alloca() +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA + +//Compiler/platform has +#define ACE_HAS_ALLOCA_H + +//Platform contains +#define ACE_HAS_POLL + +// Platform supports the POSIX struct timespec type +#define ACE_HAS_POSIX_TIME // As i understand it, but i'm in deep water +//Platform supports the SVR4 timestruc_t type + +// To get this to work a patch in sys/signal must be made +// typedef void SIG_FUNC_TYPE(int); +//#if defined (__cplusplus) +// void (*sa_handler)(int); +//#else +// ... +//#endif +//#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_TANDEM_SIGNALS +//Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T +//Platform supports SVR4 extended signals +#define ACE_HAS_SIGINFO_T +//Platform supports ucontext_t (which is used in the extended signal API). +#define ACE_HAS_UCONTEXT_T + +// Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +//Compiler/platform provides the sockio.h file +#define ACE_HAS_SYS_SOCKIO_H + +// Compiler supports the ssize_t typedef +#define ACE_HAS_SSIZE_T // Limits.h must be included + +//Platform supports STREAMS +#define ACE_HAS_STREAMS + +#define ACE_HAS_STREAM_PIPES +//Platform supports STREAM pipes + +//Compiler/platform supports strerror () +#define ACE_HAS_STRERROR + +//Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +//Compiler/platform supports SVR4 dynamic linking semantics +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +//Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +//Platform provides header +#define ACE_HAS_SYS_FILIO_H + +//Platform supports TLI timod STREAMS module +#define ACE_HAS_TIMOD_H +//Platform supports TLI tiuser header +#define ACE_HAS_TIUSER_H + +//Platform supports TLI +#define ACE_HAS_TLI +//Platform provides TLI function prototypes +#define ACE_HAS_TLI_PROTOTYPES + +//Platform lacks streambuf "linebuffered ()". +#define ACE_LACKS_LINEBUFFERED_STREAMBUF + +// Platform lacks "signed char" type (broken!) +#define ACE_LACKS_SIGNED_CHAR + + +#define ACE_PAGE_SIZE 4096 +// Defines the page size of the system (not used on Win32 or +// with ACE_HAS_GETPAGESIZE). + +/****** THREAD SPECIFIC **********/ +/* If you want to remove threading then comment out the following four #defines .*/ +#if !defined (ACE_MT_SAFE) + #define ACE_MT_SAFE 1 //Compile using multi-thread libraries +#endif +#define ACE_HAS_THREADS //Platform supports threads +#define ACE_HAS_STHREADS //Platform supports Solaris threads + +// Compiler/platform has threadspecific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +//Platform supports thr_keydelete (e.g,. UNIXWARE) + +#define ACE_HAS_THR_MINSTACK // Tandem uses thr_minstack instead of thr_min_stack +#define ACE_LACKS_PRI_T // Tandem lacks pri_t +#define ACE_HAS_THR_KEYDELETE + +//************************************* + +/*********************************/ + +/******* SIGNAL STUFF *******/ + +//Platform uses non-const char * in calls to gethostbyaddr, gethostbyname, +// getservbyname +#define ACE_HAS_NONCONST_GETBY +// Platform's select() uses non-const timeval* (only found on Linux right now) +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +// And on Tandem :-) +//Uses ctime_r & asctime_r with only two parameters vs. three. +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +//Platform has special header for select(). +#define ACE_HAS_SELECT_H +// Platform/compiler supports Standard C++ Library +#define ACE_HAS_STANDARD_CPP_LIBRARY +//Platform lacks madvise() (e.g., Linux) +#define ACE_LACKS_MADVISE +//Compiler/platform lacks strcasecmp() (e.g., DG/UX, UNIXWARE, VXWORKS) +#define ACE_LACKS_STRCASECMP + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-tru64.h b/dep/ACE_wrappers/ace/config-tru64.h new file mode 100644 index 000000000..f2825b996 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-tru64.h @@ -0,0 +1,154 @@ +/* -*- C++ -*- */ +// $Id: config-tru64.h 81935 2008-06-12 22:01:53Z jtc $ + +// The following configuration file is designed to work for the +// Digital UNIX V4.0a and later platforms. It relies on +// config-osf1-4.0.h, and adds deltas for newer platforms. + +#ifndef ACE_CONFIG_TRU64_H +#define ACE_CONFIG_TRU64_H +#include /**/ "ace/pre.h" + +#if !defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Compile using multi-thread libraries. +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif /* ! ACE_MT_SAFE */ + +/*clearerr is not defined when _REENTRANT is not defined*/ +#if ACE_MT_SAFE == 0 +#define ACE_LACKS_CLEARERR +#endif /* ACE_MT_SAFE == 0 */ + +#include "ace/config-posix.h" + +// Configuration-specific #defines: +// 1) g++ or cxx +// 2) pthreads or DCE threads +#if defined (__GNUG__) + // g++ with pthreads + + // config-g++-common.h undef's ACE_HAS_STRING_CLASS with -frepo, so + // this must appear before its #include. +# define ACE_HAS_STRING_CLASS + +# include "ace/config-g++-common.h" + +# define ACE_HAS_GNU_CSTRING_H +# define ACE_HAS_REENTRANT_FUNCTIONS +#elif defined (__DECCXX) + +# define ACE_CONFIG_INCLUDE_CXX_COMMON +# include "ace/config-cxx-common.h" + +#elif defined (__rational__) +# define ACE_HAS_REENTRANT_FUNCTIONS +# define ACE_HAS_STRING_CLASS +# define ACE_LACKS_LINEBUFFERED_STREAMBUF +# define ACE_LACKS_SIGNED_CHAR + + // Exceptions are enabled by platform_osf1_4.0_rcc.GNU. +# define ACE_HAS_STDCPP_STL_INCLUDES +#else +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler on Digital Unix +# endif /* __cplusplus */ +#endif /* ! __GNUG__ && ! __DECCXX && ! __rational__ */ + +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#define ACE_HAS_BROKEN_IF_HEADER +#define ACE_HAS_BROKEN_R_ROUTINES +#if (ACE_MT_SAFE != 0) +# define ACE_HAS_PTHREADS +# define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS +#endif /* ACE_MT_SAFE != 0 */ +#define ACE_LACKS_T_ERRNO +#if !defined (DIGITAL_UNIX) +# define DIGITAL_UNIX 0x400 +#endif /* ! DIGITAL_UNIX */ + +#define ACE_SIZEOF_LONG 8 + +#define ACE_DEFAULT_BASE_ADDR ((char *) 0x80000000) +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_NONCONST_SETRLIMIT +#define ACE_HAS_BROKEN_T_ERROR +#define ACE_HAS_NONCONST_WRITEV +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_GETRUSAGE +#define ACE_HAS_GPERF +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_IP_MULTICAST +#define ACE_HAS_LLSEEK +#define ACE_HAS_LONG_MAP_FAILED +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONCONST_SENDMSG +#define ACE_HAS_OSF1_GETTIMEOFDAY +#define ACE_HAS_OSF_TIMOD_H +#define ACE_HAS_POLL +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_PRIOCNTL +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRBUF_T +#define ACE_HAS_STREAMS +#define ACE_HAS_STRERROR +#define ACE_HAS_STRPTIME +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_SVR4_SIGNAL_T +#define ACE_HAS_SYS_SYSCALL_H +#define ACE_HAS_SYSV_IPC +#if (ACE_MT_SAFE == 0) +// clearerr is not defined when _REENTRANT is not defined +#define ACE_LACKS_CLEARERR +#else /* ACE_MT_SAFE != 0 */ +#define ACE_HAS_THREADS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_LACKS_PTHREAD_ATTR_SETSTACKADDR +#endif /* ACE_MT_SAFE != 0 */ +#define ACE_HAS_TIUSER_H +#define ACE_HAS_XTI +#define ACE_HAS_TLI_PROTOTYPES +#define ACE_HAS_UALARM +#define ACE_HAS_UCONTEXT_T +#define ACE_LACKS_PRI_T +#define ACE_LACKS_RWLOCK_T +#define ACE_PAGE_SIZE 8192 +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND + +// DJT 6/10/96 All these broken macro's can now be removed with the +// approporiate ordering of the include files. The Platinum release +// now temporarily supports both forms. Platform's implementation of +// sendmsg() has a non-const msgheader parameter. +#define ACE_HAS_NONCONST_SENDMSG +#define ACE_HAS_IDTYPE_T +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER + +#if DIGITAL_UNIX >= 0x500 +# define ACE_HAS_XPG4_MULTIBYTE_CHAR 1 +#endif /* DIGITAL_UNIX >= 0x500 */ + +#if DIGITAL_UNIX >= 0x40E +# define ACE_LACKS_STDINT_H +#endif /* DIGITAL_UNIX >= 0x40E */ + +#if (DIGITAL_UNIX >= 0x400) && (DIGITAL_UNIX < 0x500) +#define ACE_LACKS_PREAD_PROTOTYPE +#endif /* (DIGITAL_UNIX >= 0x400) && (DIGITAL_UNIX < 0x500) */ + +// gethostbyaddr does not handle IPv6-mapped-IPv4 addresses +#define ACE_HAS_BROKEN_GETHOSTBYADDR_V4MAPPED + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_TRU64_H */ diff --git a/dep/ACE_wrappers/ace/config-unixware-7.1.0.h b/dep/ACE_wrappers/ace/config-unixware-7.1.0.h new file mode 100644 index 000000000..b75fac4dc --- /dev/null +++ b/dep/ACE_wrappers/ace/config-unixware-7.1.0.h @@ -0,0 +1,412 @@ +/* -*- C++ -*- */ +// $Id: config-unixware-7.1.0.h 82267 2008-07-08 16:39:19Z jtc $ + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H + +/* ACE configuration header file */ + +/* Include the commong gnu config file */ +#include "config-g++-common.h" + +/* For unixware 7.1 && g++ 2.91.57, see if this fixes my problem */ +#ifndef UNIXWARE_7_1 +#define UNIXWARE_7_1 +#endif + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if lex declares yytext as a char * by default, not a char[]. */ +#define YYTEXT_POINTER 1 + +/* Define _REENTRANT if reentrant functions should be used. */ +#ifndef _REENTRANT +# define _REENTRANT 1 +#endif + +#define ACE_HAS_NEW_NO_H 1 +#define ACE_HAS_STDEXCEPT_NO_H 1 + +#define ACE_THREAD_MIN_PRIORITY 0 +#if defined (ACE_THREAD_MIN_PRIORITY) +# define PTHREAD_MIN_PRIORITY ACE_THREAD_MIN_PRIORITY +#endif /* #if defined (ACE_THREAD_MIN_PRIORITY) */ + +#define ACE_THREAD_MAX_PRIORITY 99 +#if defined (ACE_THREAD_MAX_PRIORITY) +# define PTHREAD_MAX_PRIORITY ACE_THREAD_MAX_PRIORITY +#endif /* #if defined (ACE_THREAD_MAX_PRIORITY) */ + +/* Specify sizes of given built-in types. If a size isn't defined here, + then ace/Basic_Types.h will attempt to deduce the size. */ +/* #undef ACE_SIZEOF_CHAR */ +#define ACE_SIZEOF_SHORT 2 +#define ACE_SIZEOF_INT 4 +#define ACE_SIZEOF_LONG 4 +#define ACE_SIZEOF_LONG_LONG 8 +#define ACE_SIZEOF_VOID_P 4 +#define ACE_SIZEOF_FLOAT 4 +#define ACE_SIZEOF_DOUBLE 8 +#define ACE_SIZEOF_LONG_DOUBLE 12 + +/* Enable ACE inlining */ +#define __ACE_INLINE__ 1 + +/* OS has priocntl (2) */ +#define ACE_HAS_PRIOCNTL 1 + +/* Platform has pread() and pwrite() support */ +#define ACE_HAS_P_READ_WRITE 1 + +/* Compiler/platform supports alloca() */ +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA 1 + +/* Compiler/platform correctly calls init()/fini() for shared libraries */ +#define ACE_HAS_AUTOMATIC_INIT_FINI 1 + +/* Platform doesn't cast MAP_FAILED to a (void *). */ +/* #undef ACE_HAS_BROKEN_MAP_FAILED */ +/* Staller: oh yes, let's do this! */ +#define ACE_HAS_BROKEN_MAP_FAILED + +/* Prototypes for both signal() and struct sigaction are consistent. */ +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES 1 + +/* Platform supports operations on directories via struct dirent, + readdir_r, etc. */ +#define ACE_HAS_DIRENT 1 + +/* Compiler supports C++ exception handling */ +// MM-Graz if ! defined inserted, to prevent warnings, because it is already +// defined in config-g++common.h +# if !defined (ACE_HAS_EXCEPTIONS) +#define ACE_HAS_EXCEPTIONS 1 +# endif + +/* Platform supports getpagesize() call (otherwise, ACE_PAGE_SIZE must be + defined, except on Win32) */ +#define ACE_HAS_GETPAGESIZE 1 + +/* Platform supports the getrusage() system call. */ +#define ACE_HAS_GETRUSAGE 1 + +/* Platform has a getrusage () prototype in sys/resource.h that differs from + the one in ace/OS.i. */ +#define ACE_HAS_GETRUSAGE_PROTOTYPE 1 + +/* Denotes that GNU has cstring.h as standard which redefines memchr() */ +#define ACE_HAS_GNU_CSTRING_H + +/* The GPERF utility is compiled for this platform */ +#define ACE_HAS_GPERF 1 + +/* Optimize ACE_Handle_Set::count_bits for select() operations (common case) */ +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT 1 + +/* Compiler/platform supports idtype_t. */ +#define ACE_HAS_IDTYPE_T 1 + +/* Platform supports IP multicast */ +#define ACE_HAS_IP_MULTICAST 1 + +/* Platform supports thr_keydelete (e.g,. UNIXWARE) */ +#define ACE_HAS_THR_KEYDELETE 1 + +/* Platform calls thr_minstack() rather than thr_min_stack() (e.g., Tandem). */ +#define ACE_HAS_THR_MINSTACK 1 + +/* Platform supports recvmsg and sendmsg */ +#define ACE_HAS_MSG 1 + +/* Platform's select() uses non-const timeval* (only found on Linux right + now) */ +#define ACE_HAS_NONCONST_SELECT_TIMEVAL 1 + +/* Uses ctime_r & asctime_r with only two parameters vs. three. */ +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R 1 + +/* Platform is an Intel Pentium microprocessor. */ +/* There is a problem with the gethrtime() because of (apparently) a problem + with the inline assembly instruction. Hopefully there is a way to resolve + that with an improvement to the assembler +*/ +#ifdef ACE_HAS_PENTIUM +#undef ACE_HAS_PENTIUM +#endif /* ACE_HAS_PENTIUM */ + + +/* Platform contains */ +#define ACE_HAS_POLL 1 + +/* Platform supports POSIX O_NONBLOCK semantics */ +#define ACE_HAS_POSIX_NONBLOCK 1 + +/* Platform supports the POSIX struct timespec type */ +#define ACE_HAS_POSIX_TIME 1 + +/* Platform supports the /proc file system and defines tid_t + in */ +#define ACE_HAS_PROC_FS 1 + +/* Platform supports POSIX Threads */ +#define ACE_HAS_PTHREADS 1 + +/* pthread.h declares an enum with PTHREAD_PROCESS_PRIVATE and + PTHREAD_PROCESS_SHARED values */ +#define ACE_HAS_PTHREAD_PROCESS_ENUM 1 + +/* Platform will recurse infinitely on thread exits from TSS cleanup routines + (e.g., AIX) */ +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS 1 + +/* Platform supports reentrant functions (i.e., all the POSIX *_r + functions). */ +#define ACE_HAS_REENTRANT_FUNCTIONS 1 + +/* Platform has support for multi-byte character support compliant with the + XPG4 Worldwide Portability Interface wide-character classification. */ +#define ACE_HAS_XPG4_MULTIBYTE_CHAR 1 + +/* Platform does not support reentrant netdb functions (getprotobyname_r, + getprotobynumber_r, gethostbyaddr_r, gethostbyname_r, getservbyname_r). */ +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS 1 + +/* Platform supports the POSIX regular expression library */ +#define ACE_HAS_REGEX 1 + +/* Platform has special header for select(). */ +#define ACE_HAS_SELECT_H 1 + +/* Platform has a function to set t_errno (e.g., Tandem). */ +#define ACE_HAS_SET_T_ERRNO 1 + +/* Platform supports SVR4 extended signals */ +#define ACE_HAS_SIGINFO_T 1 + +/* Platform/compiler has the sigwait(2) prototype */ +#define ACE_HAS_SIGWAIT 1 + +/* Compiler/platform defines the sig_atomic_t typedef */ +#define ACE_HAS_SIG_ATOMIC_T 1 + +/* Platform supports new BSD inet_addr len field. */ +#define ACE_HAS_SOCKADDR_IN_SIN_LEN 1 + +/* OS/compiler uses size_t * rather than int * for socket lengths */ +#define ACE_HAS_SIZET_SOCKET_LEN 1 + +/* Compiler/platform provides the sys/sockio.h file */ +#define ACE_HAS_SYS_SOCKIO_H 1 + +/* Compiler supports the ssize_t typedef */ +#define ACE_HAS_SSIZE_T 1 + +/* Platform supports UNIX International Threads */ +#define ACE_HAS_STHREADS 1 + +/* Platform has thr_yield() */ +#define ACE_HAS_THR_YIELD 1 + +/* Compiler/platform supports struct strbuf */ +#define ACE_HAS_STRBUF_T 1 + +/* Platform supports STREAMS */ +#define ACE_HAS_STREAMS 1 + +/* Platform supports STREAM pipes */ +#define ACE_HAS_STREAM_PIPES 1 + +/* Compiler/platform supports strerror () */ +#define ACE_HAS_STRERROR 1 + +/* Platform/Compiler supports a String class (e.g., GNU or Win32). */ +#define ACE_HAS_STRING_CLASS 1 + +/* Platform has (which contains bzero() prototype) */ +#define ACE_HAS_STRINGS 1 + +/* Platform/compiler supports void * as second parameter to gettimeofday(). */ +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY 1 + +/* Compiler/platform supports SVR4 dynamic linking semantics */ +#define ACE_HAS_SVR4_DYNAMIC_LINKING 1 + +/* Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... */ +#define ACE_HAS_SVR4_TLI 1 + +/* Compiler/platform contains the file. */ +#define ACE_HAS_SYS_SYSCALL_H 1 + +/* Platform supports system configuration information */ +#define ACE_HAS_SYS_SYSTEMINFO_H +#define ACE_HAS_SYSINFO 1 + +/* Platform supports System V IPC (most versions of UNIX, but not Win32) */ +#define ACE_HAS_SYSV_IPC 1 + +/* Platform provides header */ +#define ACE_HAS_SYS_FILIO_H 1 + +/* Platform provides header */ +#define ACE_HAS_SYS_XTI_H 1 + +/* Platform has POSIX terminal interface. */ +#define ACE_HAS_TERMIOS 1 + +/* Platform supports threads */ +#define ACE_HAS_THREADS 1 + +/* Compiler/platform has thread-specific storage */ +#define ACE_HAS_THREAD_SPECIFIC_STORAGE 1 + +/* Platform supports TLI timod STREAMS module */ +#define ACE_HAS_TIMOD_H 1 + +/* Platform supports TLI tiuser header */ +#define ACE_HAS_TIUSER_H 1 + +/* Platform supports TLI. Also see ACE_TLI_TCP_DEVICE. */ +#define ACE_HAS_TLI 1 + +/* Platform provides TLI function prototypes */ +#define ACE_HAS_TLI_PROTOTYPES 1 + +/* Platform supports ualarm() */ +#define ACE_HAS_UALARM 1 + +/* Platform supports ucontext_t (which is used in the extended signal API). */ +#define ACE_HAS_UCONTEXT_T 1 + +/* Platform has header file */ +#define ACE_HAS_UTIME 1 + +/* Platform requires void * for mmap(). */ +#define ACE_HAS_VOIDPTR_MMAP 1 + +/* Platform has XTI (X/Open-standardized superset of TLI). Implies + ACE_HAS_TLI but uses a different header file. */ +#define ACE_HAS_XTI 1 + +/* Platform can not build ace/IOStream{,_T}.cpp. This does not necessarily + mean that the platform does not support iostreams. */ +#define ACE_LACKS_ACE_IOSTREAM 1 + +/* Platform does not have u_longlong_t typedef */ +#define ACE_LACKS_U_LONGLONG_T 1 + +/* Platform lacks madvise() (e.g., Linux) */ +#define ACE_LACKS_MADVISE 1 + +/* Platform lacks pri_t (e.g., Tandem NonStop UNIX). */ +#define ACE_LACKS_PRI_T 1 + +/* Platform lacks pthread_thr_sigsetmask (e.g., MVS, HP/UX, and OSF/1 3.2) */ +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 + +/* Platfrom lack pthread_yield() support. */ +#define ACE_LACKS_PTHREAD_YIELD 1 + +/* Platform lacks readers/writer locks. */ +#define ACE_LACKS_RWLOCK_T 1 + +/* MIT pthreads platform lacks the timedwait prototypes */ +#define ACE_LACKS_TIMEDWAIT_PROTOTYPES 1 + +/* Platform does not define timepec_t as a typedef for struct timespec. */ +#define ACE_LACKS_TIMESPEC_T 1 + +/* Compile using multi-thread libraries */ +#define ACE_MT_SAFE 1 + +/* Platform needs to #include to get thread scheduling defs. */ +#define ACE_NEEDS_SCHED_H 1 + +/*********************************************************************/ +/* Compiler's template mechanim must see source code (i.e., .cpp files). This + is used for GNU G++. */ +/* Staller -> make 0 */ +// #undef ACE_TEMPLATES_REQUIRE_SOURCE + +/*********************************************************************/ + +/* The OS/platform supports the poll() event demultiplexor */ +#define ACE_USE_POLL 1 + +/* Platform has its standard c++ library in the namespace std. */ +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 + +/* The number of bytes in a double. */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in a float. */ +#define SIZEOF_FLOAT 4 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* The number of bytes in a long double. */ +#define SIZEOF_LONG_DOUBLE 12 + +/* The number of bytes in a long long. */ +#define SIZEOF_LONG_LONG 8 + +/* The number of bytes in a short. */ +#define SIZEOF_SHORT 2 + +/* The number of bytes in a signed char. */ +#define SIZEOF_SIGNED_CHAR 1 + +/* The number of bytes in a void *. */ +#define SIZEOF_VOID_P 4 + +/* Define if you have the execv function. */ +#define HAVE_EXECV 1 + +/* Define if you have the execve function. */ +#define HAVE_EXECVE 1 + +/* Define if you have the execvp function. */ +#define HAVE_EXECVP 1 + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_FSTREAM 1 + +/* Define if you have the header file. */ +#define HAVE_IOMANIP 1 + +/* Define if you have the header file. */ +#define HAVE_IOSTREAM 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Name of package */ +#define PACKAGE "ace" + +/* Added by Staller */ +#define ENUM_BOOLEAN // See file /usr/local/lib/gcc-lib/i486-pc-sysv5/egcs-2.91.60/include/sys/types.h +#define howmany(x, y) (((x)+((y)-1))/(y)) +#define ACE_HAS_BROKEN_T_ERROR // make a nasty warning disappear in OS.i +#define __USLC__ 1 +#define __IOCTL_VERSIONED__ // By Carlo! + +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-unixware-7.1.0.udk.h b/dep/ACE_wrappers/ace/config-unixware-7.1.0.udk.h new file mode 100644 index 000000000..477130d3d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-unixware-7.1.0.udk.h @@ -0,0 +1,460 @@ +/* -*- C++ -*- */ +#ifndef ACE_CONFIG_UNIXWARE_UDK_H +#define ACE_CONFIG_UNIXWARE_UDK_H + +// $Id: config-unixware-7.1.0.udk.h 82267 2008-07-08 16:39:19Z jtc $ + +// Configuration for the unixware UDK compiler. derived from the unixware/g++ config +// which was itself derived from an autoconfig run. + +/* ACE configuration header file */ + +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#ifndef UNIXWARE_7_1 +#define UNIXWARE_7_1 +#endif + +#define ACE_LACKS_PLACEMENT_OPERATOR_DELETE + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if lex declares yytext as a char * by default, not a char[]. */ +#define YYTEXT_POINTER 1 + +/* Define _REENTRANT if reentrant functions should be used. */ +#ifndef _REENTRANT +# define _REENTRANT 1 +#endif + +#define ACE_HAS_NEW_NO_H 1 +#define ACE_HAS_STDEXCEPT_NO_H 1 + +/* + * TODO: These two next #defines have an #undef before them, in + * case the variable being defined already had a value. + * The #undefs are being picked up by configure, and are commented out! + */ +#define ACE_THREAD_MIN_PRIORITY 0 +#if defined (ACE_THREAD_MIN_PRIORITY) +/* # undef PTHREAD_MIN_PRIORITY */ +# define PTHREAD_MIN_PRIORITY ACE_THREAD_MIN_PRIORITY +#endif /* #if defined (ACE_THREAD_MIN_PRIORITY) */ + +#define ACE_THREAD_MAX_PRIORITY 99 +#if defined (ACE_THREAD_MAX_PRIORITY) +/* # undef PTHREAD_MAX_PRIORITY */ +# define PTHREAD_MAX_PRIORITY ACE_THREAD_MAX_PRIORITY +#endif /* #if defined (ACE_THREAD_MAX_PRIORITY) */ + + + +/* UnixWare specific configuration parameters */ +/* #undef UNIXWARE */ +/* #undef UNIXWARE_2_0 */ +/* #undef UNIXWARE_2_1 */ + +/* Specify sizes of given built-in types. If a size isn't defined here, + then ace/Basic_Types.h will attempt to deduce the size. */ +/* #undef ACE_SIZEOF_CHAR */ +#define ACE_SIZEOF_SHORT 2 +#define ACE_SIZEOF_INT 4 +#define ACE_SIZEOF_LONG 4 +#define ACE_SIZEOF_LONG_LONG 8 +#define ACE_SIZEOF_VOID_P 4 +#define ACE_SIZEOF_FLOAT 4 +#define ACE_SIZEOF_DOUBLE 8 +#define ACE_SIZEOF_LONG_DOUBLE 12 + +/* Enable ACE inlining */ +#define __ACE_INLINE__ 1 + +/* Platform supports Asynchronous IO calls */ +/* #define ACE_HAS_AIO_CALLS */ + +/* Specify this if you don't want threads to inherit parent thread's + ACE_Log_Msg properties. */ +/* #undef ACE_THREADS_DONT_INHERIT_LOG_MSG */ + +/* OS has priocntl (2) */ +#define ACE_HAS_PRIOCNTL 1 + +/* Platform has pread() and pwrite() support */ +#define ACE_HAS_P_READ_WRITE 1 + +/* Compiler/platform correctly calls init()/fini() for shared libraries */ +#define ACE_HAS_AUTOMATIC_INIT_FINI 1 + +/* Compiler handles explicit calling of template destructor correctly. + See "ace/OS.h" for details. */ +/* Staller: already defined by config-g++-common.h +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR 1 +*/ + +/* Platform doesn't cast MAP_FAILED to a (void *). */ +/* #undef ACE_HAS_BROKEN_MAP_FAILED */ +/* Staller: oh yes, let's do this! */ +#define ACE_HAS_BROKEN_MAP_FAILED + + +/* Prototypes for both signal() and struct sigaction are consistent. */ +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES 1 + +/* Compiler/platform has correctly prototyped header files */ +#define ACE_HAS_CPLUSPLUS_HEADERS + +/* Platform supports operations on directories via struct dirent, + readdir_r, etc. */ +#define ACE_HAS_DIRENT + +/* Compiler supports C++ exception handling */ +# if !defined (ACE_HAS_EXCEPTIONS) +#define ACE_HAS_EXCEPTIONS +# endif + +/* Platform supports getpagesize() call (otherwise, ACE_PAGE_SIZE must be + defined, except on Win32) */ +#define ACE_HAS_GETPAGESIZE + +/* Platform supports the getrusage() system call. */ +#define ACE_HAS_GETRUSAGE + +/* Platform has a getrusage () prototype in sys/resource.h that differs from + the one in ace/OS.i. */ +#define ACE_HAS_GETRUSAGE_PROTOTYPE + +/* The GPERF utility is compiled for this platform */ +#define ACE_HAS_GPERF + +/* Optimize ACE_Handle_Set::count_bits for select() operations (common case) */ +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT 1 + +/* Compiler/platform supports SunOS high resolution timers */ +/* #undef ACE_HAS_HI_RES_TIMER */ + +/* Compiler/platform supports idtype_t. */ +#define ACE_HAS_IDTYPE_T + +/* Inline all the static class OS methods to remove call overhead */ +/* Note: This gets defined by OS.h if __ACE_INLINE__ is defined */ +/* #undef ACE_HAS_INLINED_OSCALLS */ + +/* Platform supports IP multicast */ +#define ACE_HAS_IP_MULTICAST + +/* Platform supports thr_keydelete (e.g,. UNIXWARE) */ +#define ACE_HAS_THR_KEYDELETE + +/* Platform calls thr_minstack() rather than thr_min_stack() (e.g., Tandem). */ +#define ACE_HAS_THR_MINSTACK + +/* Some files, such as ace/streams.h, want to include new style C++ stream + headers. These headers are iomanip, ios, iostream, istream, ostream, + fstream and streambuf. If _all_ of these headers aren't available, then + assume that only iostream.h and fstream.h are available. */ +/* #define ACE_USES_OLD_IOSTREAMS */ + +/* Platform supports recvmsg and sendmsg */ +#define ACE_HAS_MSG + +/* Platform's select() uses non-const timeval* (only found on Linux right + now) */ +#define ACE_HAS_NONCONST_SELECT_TIMEVAL + +/* Uses ctime_r & asctime_r with only two parameters vs. three. */ +#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + + +/* Platform is an Intel Pentium microprocessor. */ +/* There is a problem with the gethrtime() because of (apparently) a problem + with the inline assembly instruction. Hopefully there is a way to resolve + that with an improvement to the assembler +*/ +#ifdef ACE_HAS_PENTIUM +//#undef ACE_HAS_PENTIUM +#endif /* ACE_HAS_PENTIUM */ + + +/* Platform contains */ +#define ACE_HAS_POLL + +/* Platform supports POSIX O_NONBLOCK semantics */ +#define ACE_HAS_POSIX_NONBLOCK + +/* Platform supports the POSIX struct timespec type */ +#define ACE_HAS_POSIX_TIME + +/* Platform supports the /proc file system and defines tid_t + in */ +#define ACE_HAS_PROC_FS + +/* Platform supports POSIX Threads */ +#define ACE_HAS_PTHREADS + +/* pthread.h declares an enum with PTHREAD_PROCESS_PRIVATE and + PTHREAD_PROCESS_SHARED values */ +#define ACE_HAS_PTHREAD_PROCESS_ENUM + +/* Platform will recurse infinitely on thread exits from TSS cleanup routines + (e.g., AIX) */ +#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS + +/* Platform supports reentrant functions (i.e., all the POSIX *_r + functions). */ +#define ACE_HAS_REENTRANT_FUNCTIONS + +/* Platform has support for multi-byte character support compliant with the + XPG4 Worldwide Portability Interface wide-character classification. */ +#define ACE_HAS_XPG4_MULTIBYTE_CHAR + +/* Platform does not support reentrant netdb functions (getprotobyname_r, + getprotobynumber_r, gethostbyaddr_r, gethostbyname_r, getservbyname_r). */ +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS + +/* Platform supports the POSIX regular expression library */ +#define ACE_HAS_REGEX + +/* Platform has special header for select(). */ +#define ACE_HAS_SELECT_H + +/* Platform has a function to set t_errno (e.g., Tandem). */ +#define ACE_HAS_SET_T_ERRNO + +/* Platform supports SVR4 extended signals */ +#define ACE_HAS_SIGINFO_T + +/* Platform/compiler has the sigwait(2) prototype */ +#define ACE_HAS_SIGWAIT + +/* Compiler/platform defines the sig_atomic_t typedef */ +#define ACE_HAS_SIG_ATOMIC_T + +/* Platform supports new BSD inet_addr len field. */ +#define ACE_HAS_SOCKADDR_IN_SIN_LEN + +/* OS/compiler uses size_t * rather than int * for socket lengths */ +#define ACE_HAS_SIZET_SOCKET_LEN + +/* Compiler/platform provides the sys/sockio.h file */ +#define ACE_HAS_SYS_SOCKIO_H + +/* Compiler supports the ssize_t typedef */ +#define ACE_HAS_SSIZE_T + +/* Platform supports UNIX International Threads */ +#define ACE_HAS_STHREADS + +/* Platform has thr_yield() */ +#define ACE_HAS_THR_YIELD + +/* Platform/compiler supports Standard C++ Library */ +/* It seems that UDK provides std-like declarations for only portions + such as +*/ +#define ACE_HAS_STANDARD_CPP_LIBRARY 0 + +/* Compiler/platform supports struct strbuf */ +#define ACE_HAS_STRBUF_T + +/* Platform supports STREAMS */ +#define ACE_HAS_STREAMS + +/* Platform supports STREAM pipes */ +#define ACE_HAS_STREAM_PIPES + +/* Compiler/platform supports strerror () */ +#define ACE_HAS_STRERROR + +/* Platform/Compiler supports a String class (e.g., GNU or Win32). */ +#define ACE_HAS_STRING_CLASS + +/* Platform has (which contains bzero() prototype) */ +#define ACE_HAS_STRINGS + +/* Platform/compiler supports void * as second parameter to gettimeofday(). */ +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY + +/* Compiler/platform supports SVR4 dynamic linking semantics */ +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +/* Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... */ +#define ACE_HAS_SVR4_TLI + +/* Compiler/platform contains the file. */ +#define ACE_HAS_SYS_SYSCALL_H + +/* Platform supports system configuration information */ +#define ACE_HAS_SYS_SYSTEMINFO_H +#define ACE_HAS_SYSINFO 1 + +/* Platform supports System V IPC (most versions of UNIX, but not Win32) */ +#define ACE_HAS_SYSV_IPC 1 + +/* Platform provides header */ +#define ACE_HAS_SYS_FILIO_H 1 + +/* Platform provides header */ +#define ACE_HAS_SYS_XTI_H 1 + +/* Compiler implements templates that support typedefs inside of classes used + as formal arguments to a template class. */ +#define ACE_HAS_TEMPLATE_TYPEDEFS 1 + +/* Platform has POSIX terminal interface. */ +#define ACE_HAS_TERMIOS 1 + +/* Platform supports threads */ +#define ACE_HAS_THREADS 1 + +/* Compiler/platform has thread-specific storage */ +#define ACE_HAS_THREAD_SPECIFIC_STORAGE 1 + +/* Platform supports TLI timod STREAMS module */ +#define ACE_HAS_TIMOD_H 1 + +/* Platform supports TLI tiuser header */ +#define ACE_HAS_TIUSER_H 1 + +/* Platform supports TLI. Also see ACE_TLI_TCP_DEVICE. */ +#define ACE_HAS_TLI 1 + +/* Platform provides TLI function prototypes */ +#define ACE_HAS_TLI_PROTOTYPES 1 + +/* Platform supports ualarm() */ +#define ACE_HAS_UALARM 1 + +/* Platform supports ucontext_t (which is used in the extended signal API). */ +#define ACE_HAS_UCONTEXT_T 1 + +/* Platform has header file */ +#define ACE_HAS_UTIME 1 + +/* Prints out console message in ACE_NOTSUP. Useful for tracking down origin + of ACE_NOTSUP. */ +/* #undef ACE_HAS_VERBOSE_NOTSUP */ + +/* Platform requires void * for mmap(). */ +#define ACE_HAS_VOIDPTR_MMAP 1 + +/* Platform has XTI (X/Open-standardized superset of TLI). Implies + ACE_HAS_TLI but uses a different header file. */ +#define ACE_HAS_XTI 1 + +/* Platform can not build ace/IOStream{,_T}.cpp. This does not necessarily + mean that the platform does not support iostreams. */ +#define ACE_LACKS_ACE_IOSTREAM 1 + +/* Platform does not have u_longlong_t typedef */ +#define ACE_LACKS_U_LONGLONG_T 1 + +/* Platform lacks madvise() (e.g., Linux) */ +#define ACE_LACKS_MADVISE 1 + +/* Platform lacks pri_t (e.g., Tandem NonStop UNIX). */ +#define ACE_LACKS_PRI_T 1 + +/* Platform lacks pthread_thr_sigsetmask (e.g., MVS, HP/UX, and OSF/1 3.2) */ +#define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 + +/* Platfrom lack pthread_yield() support. */ +#define ACE_LACKS_PTHREAD_YIELD 1 + +/* Platform lacks readers/writer locks. */ +#define ACE_LACKS_RWLOCK_T 1 + +/* MIT pthreads platform lacks the timedwait prototypes */ +#define ACE_LACKS_TIMEDWAIT_PROTOTYPES 1 + +/* Platform does not define timepec_t as a typedef for struct timespec. */ +#define ACE_LACKS_TIMESPEC_T 1 + +/* Compile using multi-thread libraries */ +#define ACE_MT_SAFE 1 + +/* Platform needs to #include to get thread scheduling defs. */ +#define ACE_NEEDS_SCHED_H 1 + +/* The OS/platform supports the poll() event demultiplexor */ +#define ACE_USE_POLL 1 + +/* Platform has its standard c++ library in the namespace std. */ +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 + +/* The number of bytes in a double. */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in a float. */ +#define SIZEOF_FLOAT 4 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* The number of bytes in a long double. */ +#define SIZEOF_LONG_DOUBLE 12 + +/* The number of bytes in a long long. */ +#define SIZEOF_LONG_LONG 8 + +/* The number of bytes in a short. */ +#define SIZEOF_SHORT 2 + +/* The number of bytes in a signed char. */ +#define SIZEOF_SIGNED_CHAR 1 + +/* The number of bytes in a void *. */ +#define SIZEOF_VOID_P 4 + +/* Define if you have the execv function. */ +#define HAVE_EXECV 1 + +/* Define if you have the execve function. */ +#define HAVE_EXECVE 1 + +/* Define if you have the execvp function. */ +#define HAVE_EXECVP 1 + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_FSTREAM 1 + +/* Define if you have the header file. */ +#define HAVE_IOMANIP 1 + +/* Define if you have the header file. */ +#define HAVE_IOSTREAM 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Name of package */ +#define PACKAGE "ace" + +/* Version number of package */ +#define VERSION "4.6.37" + +/* Added by Staller */ +#define ENUM_BOOLEAN // See file /usr/local/lib/gcc-lib/i486-pc-sysv5/egcs-2.91.60/include/sys/types.h +/* Hat nix gebracht +#define ACE_DEFAULT_SELECT_REACTOR_SIZE 256 // this is like in linux config fileto avoid another error +*/ +#define howmany(x, y) (((x)+((y)-1))/(y)) +#define ACE_HAS_BROKEN_T_ERROR // let disappear a nasty warning from OS.i +#if !defined (__USLC__) +# define __USLC__ 1 +#endif + +#define __IOCTL_VERSIONED__ // By Carlo! +#endif /* ACE_UNIXWARE_UDK_H */ diff --git a/dep/ACE_wrappers/ace/config-visualage.h b/dep/ACE_wrappers/ace/config-visualage.h new file mode 100644 index 000000000..4cef8108b --- /dev/null +++ b/dep/ACE_wrappers/ace/config-visualage.h @@ -0,0 +1,20 @@ +/* -*- C++ -*- */ +// $Id: config-visualage.h 80826 2008-03-04 14:51:23Z wotte $ + +// This configuration file automatically includes the proper +// configurations for IBM's VisualAge C++ compiler on Win32 and AIX. + +#ifndef CONFIG_VISUALAGE_H +#define CONFIG_VISUALAGE_H +#include /**/ "ace/pre.h" + +#ifdef __TOS_WIN__ + #include "ace/config-win32.h" +#elif __TOS_AIX__ + #include "ace/config-aix-4.x.h" +#else + #include "PLATFORM NOT SPECIFIED" +#endif /* __TOS_WIN__ */ + +#include /**/ "ace/post.h" +#endif //CONFIG_VISUALAGE_H diff --git a/dep/ACE_wrappers/ace/config-vxworks.h b/dep/ACE_wrappers/ace/config-vxworks.h new file mode 100644 index 000000000..bb6ed5796 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks.h @@ -0,0 +1,55 @@ +//* -*- C++ -*- */ +// $Id: config-vxworks.h 81046 2008-03-21 10:11:12Z johnnyw $ + +// The following configuration file is designed to work for VxWorks +// Based on ACE_VXWORKS it will select the correct config file + +#ifndef ACE_CONFIG_VXWORKS_H +#define ACE_CONFIG_VXWORKS_H +#include /**/ "ace/pre.h" + +// If ACE_VXWORKS is not defined try to figure out the VxWorks version +#if !defined (ACE_VXWORKS) +# include "vxWorks.h" +# if !defined (_WRS_VXWORKS_MAJOR) && !defined (_WRS_VXWORKS_MINOR) +# error You must define ACE_VXWORKS +# else +# if (_WRS_VXWORKS_MAJOR == 6) +# if (_WRS_VXWORKS_MINOR == 0) +# define ACE_VXWORKS 0x600 +# elif (_WRS_VXWORKS_MINOR == 1) +# define ACE_VXWORKS 0x610 +# elif (_WRS_VXWORKS_MINOR == 2) +# define ACE_VXWORKS 0x620 +# elif (_WRS_VXWORKS_MINOR == 3) +# define ACE_VXWORKS 0x630 +# elif (_WRS_VXWORKS_MINOR == 4) +# define ACE_VXWORKS 0x640 +# elif (_WRS_VXWORKS_MINOR == 5) +# define ACE_VXWORKS 0x650 +# elif (_WRS_VXWORKS_MINOR == 6) +# define ACE_VXWORKS 0x660 +# endif +# endif +# endif +#endif /* ! ACE_VXWORKS */ + +#if (ACE_VXWORKS == 0x551) +# include "ace/config-vxworks5.x.h" +#elif (ACE_VXWORKS == 0x620) +# include "ace/config-vxworks6.2.h" +#elif (ACE_VXWORKS == 0x630) +# include "ace/config-vxworks6.3.h" +#elif (ACE_VXWORKS == 0x640) +# include "ace/config-vxworks6.4.h" +#elif (ACE_VXWORKS == 0x650) +# include "ace/config-vxworks6.5.h" +#elif (ACE_VXWORKS == 0x660) +# include "ace/config-vxworks6.6.h" +#else +#error Unknown VxWorks version +#endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_VXWORKS_H */ + diff --git a/dep/ACE_wrappers/ace/config-vxworks5.x.h b/dep/ACE_wrappers/ace/config-vxworks5.x.h new file mode 100644 index 000000000..a13ce4720 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks5.x.h @@ -0,0 +1,345 @@ +/* -*- C++ -*- */ +// $Id: config-vxworks5.x.h 81850 2008-06-06 08:39:54Z vzykov $ + +// The following configuration file is designed to work for VxWorks +// 5.5.x platforms using one of these compilers: +// 1) The GNU g++ compiler that is shipped with Tornado 2.2 or newer. +// 2) The Green Hills 1.8.8 and newer 1.8.9 compilers (not tested +// already for a long time) +// 3) The WindRiver Compiler (formerly known as Diab) + +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H +#include /**/ "ace/pre.h" + +#if ! defined (VXWORKS) +# define VXWORKS +#endif /* ! VXWORKS */ + +#if ! defined (ACE_VXWORKS) +# define ACE_VXWORKS 0x551 +#endif /* ! ACE_VXWORKS */ + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Compiler-specific configuration. +#if defined (__GNUG__) +# include "ace/config-g++-common.h" + +# define ACE_LACKS_IOSTREAM_FX + +# if !defined (ACE_MAIN) +# define ACE_MAIN ace_main +# endif /* ! ACE_MAIN */ + +# define ACE_LACKS_LINEBUFFERED_STREAMBUF + +# if (__GNUC__ == 2) +# define ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE 1 +# endif + +# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) + // GNU 3.3+ toolchain supports long long types but fails to define this so STL + // skips some definitions +# if !defined (_GLIBCPP_USE_LONG_LONG) +# define _GLIBCPP_USE_LONG_LONG +# endif +# endif /* (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) */ + +#elif defined (ghs) + // Processor type, if necessary. Green Hills defines "ppc". +# if defined (ppc) +# define ACE_HAS_POWERPC_TIMER +# define ACE_LACKS_CLEARERR +# endif /* ppc */ + +# define ACE_CONFIG_INCLUDE_GHS_COMMON +# include "ace/config-ghs-common.h" + +# define ACE_LACKS_UNISTD_H +# define ACE_LACKS_IOSTREAM_TOTALLY + +// Short-circuit the include of +// Green Hills has a problem with multiply defined functions +// with different parameters. +# define __INCineth + +#elif defined (__DCPLUSPLUS__) || defined (__DCC__) + // Diab 4.2a or later. +# if !defined (ACE_LACKS_PRAGMA_ONCE) + // We define it with a -D with make depend. +# define ACE_LACKS_PRAGMA_ONCE +# endif /* ! ACE_LACKS_PRAGMA_ONCE */ + + // Diab doesn't support VxWorks' iostream libraries. +# define ACE_LACKS_IOSTREAM_TOTALLY +# define ACE_LACKS_ACE_IOSTREAM + +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 0 + +# define ACE_TEMPLATES_REQUIRE_SOURCE + +#else /* ! __GNUG__ && ! ghs && !__DCC__ */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler on VxWorks +# endif /* __cplusplus */ +#endif /* ! __GNUG__ && ! ghs */ + +// OS-specific configuration +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R +#define ACE_MKDIR_LACKS_MODE +#define ACE_HAS_NONCONST_GETBY +#define ACE_HAS_NONCONST_STAT +#define ACE_HAS_NONCONST_SWAB +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_NONCONST_CHDIR +#define ACE_HAS_NONCONST_UNLINK +#define ACE_HAS_NONCONST_OPENDIR +#define ACE_LACKS_UNIX_SYSLOG +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 32768 +#define ACE_DEFAULT_THREAD_KEYS 16 +#define ACE_HAS_BROKEN_ACCEPT_ADDR +#define ACE_HAS_NONCONST_SENDMSG +#define ACE_HAS_NONCONST_WRITEV +#define ACE_HAS_CHARPTR_DL +#define ACE_HAS_CHARPTR_SOCKOPT +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_DLL 0 +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_IOCTL_INT_3_PARAM +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN +#define ACE_HAS_STRDUP_EMULATION +#define ACE_HAS_STRERROR +#define ACE_HAS_THREADS +#define ACE_LACKS_ALPHASORT +#define ACE_LACKS_ACCESS +#define ACE_LACKS_EXEC +#define ACE_LACKS_FCNTL +#define ACE_LACKS_FILELOCKS +#define ACE_LACKS_FORK +#define ACE_LACKS_FSYNC +#define ACE_LACKS_GETHOSTENT +#define ACE_LACKS_GETOPT +#define ACE_LACKS_GETPID +#define ACE_LACKS_GETPPID +#define ACE_LACKS_GETSERVBYNAME +#define ACE_LACKS_KEY_T +#define ACE_LACKS_LSTAT +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MALLOC_H +#define ACE_LACKS_MEMORY_H +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_MMAP +#define ACE_LACKS_MPROTECT +#define ACE_LACKS_MSYNC +#define ACE_LACKS_NUMERIC_LIMITS +#define ACE_LACKS_GETPROTOBYNAME +#define ACE_LACKS_GETPROTOBYNUMBER +#define ACE_LACKS_GETHOSTBYADDR +#define ACE_LACKS_GETHOSTBYNAME +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_PWD_FUNCTIONS +#define ACE_LACKS_RAND_REENTRANT_FUNCTIONS +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_READLINK +#define ACE_LACKS_REALPATH +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_STRCASECMP +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_SYSCONF +#define ACE_LACKS_SYS_SYSCTL_H +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_TEMPNAM +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_UMASK +#define ACE_LACKS_UTSNAME_T +#define ACE_LACKS_UNAME +#define ACE_LACKS_STRPTIME +#define ACE_LACKS_VSNPRINTF +#define ACE_LACKS_WAIT +#define ACE_LACKS_WAITPID +#define ACE_LACKS_DUP2 +#define ACE_LACKS_DUP +#define ACE_LACKS_SUSECONDS_T +#define ACE_LACKS_USECONDS_T +#define ACE_LACKS_INTPTR_T +#define ACE_PAGE_SIZE 4096 +#define ACE_THR_PRI_FIFO_DEF 101 +#define ACE_THR_PRI_OTHER_DEF ACE_THR_PRI_FIFO_DEF +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND +#if !defined (ACE_VXWORKS_SPARE) +# define ACE_VXWORKS_SPARE spare4 +#endif /* ! ACE_VXWORKS_SPARE */ + +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETSID +#define ACE_LACKS_SETUID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_GETEGID +#define ACE_LACKS_GETGID +#define ACE_LACKS_GETEUID +#define ACE_LACKS_GETUID +#define ACE_LACKS_SETGID +#define ACE_LACKS_GETPGID + +#define ACE_LACKS_PIPE +#define ACE_LACKS_STDINT_H +#define ACE_LACKS_INTTYPES_H +#define ACE_LACKS_UNISTD_H +#define ACE_LACKS_SYS_SELECT_H +#define ACE_LACKS_SYS_TIME_H +#define ACE_LACKS_SYS_RESOURCE_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_WCHAR_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_SEARCH_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_STRINGS_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_WCTYPE_H + +// Not sure if these should always be defined. +#define ACE_LACKS_SYS_UN_H + +// Some string things +#define ACE_LACKS_WCSCAT +#define ACE_LACKS_WCSCHR +#define ACE_LACKS_WCSCMP +#define ACE_LACKS_WCSCPY +#define ACE_LACKS_WCSCSPN +#define ACE_LACKS_WCSLEN +#define ACE_LACKS_WCSNCAT +#define ACE_LACKS_WCSNCMP +#define ACE_LACKS_WCSNCPY +#define ACE_LACKS_WCSPBRK +#define ACE_LACKS_WCSRCHR +#define ACE_LACKS_WCSSPN +#define ACE_LACKS_WCSSTR +#define ACE_LACKS_WCSTOK +#define ACE_LACKS_TOWLOWER +#define ACE_LACKS_TOWUPPER +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_WCSTOD +#define ACE_LACKS_WCSTOL +#define ACE_LACKS_WCSTOUL +#define ACE_LACKS_WCSDUP +#define ACE_LACKS_STRTOULL +#define ACE_LACKS_WCSTOULL + +#define ACE_LACKS_SYMLINKS +#define ACE_LACKS_FGETWC +#define ACE_LACKS_FGETWS +#define ACE_LACKS_FPUTWS + +#if defined (ACE_HAS_VXWORKS551_PID) || (ACE_HAS_VXWORKS551_PCD) || (ACE_HAS_VXWORKS551_PNE) +# define ACE_HAS_VXWORKS551_MEDUSA +#endif + +#if defined (ACE_HAS_VXWORKS551_MEDUSA) +# define ACE_HAS_GETIFADDRS +#endif + +// It is possible to enable pthread support with VxWorks, when the user decides +// to use this, we need some more defines +#if defined ACE_HAS_PTHREADS +# define ACE_LACKS_CONDATTR_PSHARED +# define ACE_LACKS_MUTEXATTR_PSHARED +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_HAS_POSIX_SEM +// Include this file, the sys/stat.h file shipped with VxWorks has old types +// and without this include we get a lot of compile errors. A TSR has been filed +// so that hopefully in the future we can zap this include +#include "types/vxTypesOld.h" +#else +# define ACE_HAS_VXTHREADS +# define ACE_LACKS_PTHREAD_H +# define ACE_LACKS_COND_T +// VxWorks has no recursive mutexes. This was set in the past but it doesn't +// work with the pthread support, so only set it for the time being when pthread +// is disabled +# define ACE_HAS_RECURSIVE_MUTEXES +// VxWorks does not have the pthread_mutex_timedlock operation, but there is +// an emulation for this when not using the pthread mapping +#define ACE_HAS_MUTEX_TIMEOUTS +#define ACE_HAS_TSS_EMULATION +#endif + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +// Needed include to get all VxWorks CPU types +#include "types/vxCpu.h" +#if (CPU == PENTIUM || CPU == PENTIUM2 || CPU == PENTIUM3 || CPU == PENTIUM4) +// If running an Intel Pentium the +// ACE_OS::gethrtime () can use the RDTSC instruction. +# define ACE_HAS_PENTIUM +#endif + +# if defined (TOOL) && (TOOL == gnu) +# if defined (CPU) && (CPU == PPC85XX || CPU == PPC604 || CPU == PPC603) +// These PPC's do lack log2 +# define ACE_LACKS_LOG2 +# endif +# endif + +#if !defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE) +# define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 +#endif /* ACE_NEEDS_HUGE_THREAD_STACKSIZE */ + +#if !defined (ACE_NTRACE) +# define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// By default, don't include RCS Id strings in object code. +#if !defined (ACE_USE_RCSID) +#define ACE_USE_RCSID 0 +#endif /* !ACE_USE_RCSID */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_H */ diff --git a/dep/ACE_wrappers/ace/config-vxworks6.2.h b/dep/ACE_wrappers/ace/config-vxworks6.2.h new file mode 100644 index 000000000..0d03b44cd --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks6.2.h @@ -0,0 +1,328 @@ +/* -*- C++ -*- */ +// $Id: config-vxworks6.2.h 81850 2008-06-06 08:39:54Z vzykov $ + +// The following configuration file is designed to work for VxWorks +// 6.2 platforms using one of these compilers: +// 1) The GNU g++ compiler that is shipped with VxWorks 6.2 + +#ifndef ACE_CONFIG_VXWORKS_6_2_H +#define ACE_CONFIG_VXWORKS_6_2_H +#include /**/ "ace/pre.h" + +#if ! defined (VXWORKS) +# define VXWORKS +#endif /* ! VXWORKS */ + +#if ! defined (ACE_VXWORKS) +# define ACE_VXWORKS 0x620 +#endif /* ! ACE_VXWORKS */ + +#if defined __RTP__ + // Fix wrong typedef in unistd.h (unsigned short) + #define _SUSECONDS_T + typedef long suseconds_t; +#endif +#include + +// Fix for including right typedef for pid_t in VxTypes.h (int) +#include + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Compiler-specific configuration. +#if defined (__GNUG__) +# include "ace/config-g++-common.h" + +# define ACE_LACKS_IOSTREAM_FX +# define ACE_LACKS_LINEBUFFERED_STREAMBUF + +# if defined (__RTP__) && !defined (_HAS_C9X) +// Workaround for the fact that under RTP the log2 method can't be used +// without this define set, see TSR560446 +# if !defined (_C99) +# define _C99 +# endif +# endif + +#elif defined (__DCPLUSPLUS__) || defined (__DCC__) + // Diab 4.2a or later. +# if !defined (ACE_LACKS_PRAGMA_ONCE) + // We define it with a -D with make depend. +# define ACE_LACKS_PRAGMA_ONCE +# endif /* ! ACE_LACKS_PRAGMA_ONCE */ + +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_TEMPLATES_REQUIRE_SOURCE + +#else /* ! __GNUG__ && ! ghs && !__DCC__ */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler on VxWorks +# endif /* __cplusplus */ +#endif /* ! __GNUG__ && ! ghs */ + +#if !defined __RTP__ +# if defined (TOOL) && (TOOL == gnu) +# if defined (CPU) && (CPU == PPC85XX || CPU == PPC604 || CPU == PPC603) +// These PPC's do lack log2 in kernel mode +# define ACE_LACKS_LOG2 +# endif +# endif +#endif + +// OS-specific configuration +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_GETBY +#define ACE_HAS_NONCONST_SWAB +#define ACE_HAS_NONCONST_READV +#define ACE_LACKS_UNIX_SYSLOG +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 32768 +#define ACE_DEFAULT_THREAD_KEYS 16 +#define ACE_HAS_BROKEN_ACCEPT_ADDR +#define ACE_HAS_NONCONST_SENDMSG +#define ACE_HAS_NONCONST_WRITEV +#define ACE_HAS_CHARPTR_DL +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_DLL 0 +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_IOCTL_INT_3_PARAM +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SIGACTION_CONSTP2 +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN +#define ACE_HAS_STRERROR +#define ACE_HAS_THREADS +#define ACE_HAS_SYSCTL +#define ACE_LACKS_ALPHASORT +#define ACE_LACKS_EXEC +#define ACE_LACKS_FILELOCKS +#define ACE_LACKS_FORK +#define ACE_LACKS_GETHOSTENT +#define ACE_LACKS_GETSERVBYNAME +#define ACE_LACKS_GETPROTOBYNAME +#define ACE_LACKS_GETPROTOBYNUMBER +#define ACE_LACKS_KEY_T +#define ACE_LACKS_LSTAT +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MALLOC_H +#define ACE_LACKS_MEMORY_H +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_MMAP +#define ACE_LACKS_MPROTECT +#define ACE_LACKS_MSYNC +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_PWD_FUNCTIONS +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_READLINK +#define ACE_LACKS_REALPATH +#define ACE_LACKS_PIPE +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_TEMPNAM +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_USECONDS_T +#define ACE_LACKS_UMASK +#define ACE_LACKS_STRPTIME +#define ACE_PAGE_SIZE 4096 +#define ACE_THR_PRI_FIFO_DEF 101 +#define ACE_THR_PRI_OTHER_DEF ACE_THR_PRI_FIFO_DEF +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND +#if !defined (ACE_VXWORKS_SPARE) +# define ACE_VXWORKS_SPARE spare4 +#endif /* ! ACE_VXWORKS_SPARE */ +#define ACE_HAS_GETIFADDRS + +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETSID +#define ACE_LACKS_SETUID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_GETEUID +#define ACE_LACKS_GETUID +#define ACE_LACKS_GETPGID +#define ACE_LACKS_GETEGID +#define ACE_LACKS_GETGID +#define ACE_LACKS_SETGID + +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_FCNTL + +// Some string things +#define ACE_LACKS_STRCASECMP +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSDUP +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_STRTOULL +#define ACE_LACKS_WCSTOULL + +#define ACE_HAS_CHARPTR_SOCKOPT +#define ACE_LACKS_SYMLINKS + +#if defined __RTP__ + // We are building for RTP mode + #if !defined (ACE_AS_STATIC_LIBS) + # define ACE_HAS_SVR4_DYNAMIC_LINKING + #endif + #define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + #define ACE_LACKS_REGEX_H + #define ACE_LACKS_PUTENV + #define ACE_HAS_SETENV + #define ACE_HAS_3_PARAM_WCSTOK + #define ACE_HAS_WCHAR + #define ACE_HAS_VFWPRINTF + #define ACE_SIZEOF_WCHAR 2 +#else + // We are building for kernel mode + #define ACE_LACKS_INTPTR_T + #define ACE_LACKS_SUSECONDS_T + #define ACE_LACKS_INTTYPES_H + #define ACE_LACKS_STDINT_H + #define ACE_LACKS_UNAME + #define ACE_LACKS_UTSNAME_T + #define ACE_LACKS_RAND_REENTRANT_FUNCTIONS + #define ACE_LACKS_DLFCN_H + #define ACE_LACKS_WAIT + #define ACE_LACKS_WAITPID + #define ACE_LACKS_SYS_TIME_H + #define ACE_LACKS_SYS_SELECT_H + #define ACE_LACKS_STRINGS_H + #define ACE_MKDIR_LACKS_MODE + #define ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R + #define ACE_LACKS_SEARCH_H + #define ACE_LACKS_SYSCONF + #define ACE_LACKS_GETPID + #define ACE_LACKS_GETPPID + #define ACE_LACKS_WCHAR_H + #define ACE_LACKS_WCTYPE_H + #define ACE_LACKS_WCSCAT + #define ACE_LACKS_WCSCHR + #define ACE_LACKS_WCSCMP + #define ACE_LACKS_WCSCPY + #define ACE_LACKS_WCSCSPN + #define ACE_LACKS_WCSLEN + #define ACE_LACKS_WCSNCAT + #define ACE_LACKS_WCSNCMP + #define ACE_LACKS_WCSNCPY + #define ACE_LACKS_WCSPBRK + #define ACE_LACKS_WCSRCHR + #define ACE_LACKS_WCSSPN + #define ACE_LACKS_WCSSTR + #define ACE_LACKS_WCSTOK + #define ACE_LACKS_TOWLOWER + #define ACE_LACKS_TOWUPPER + #define ACE_LACKS_WCSTOD + #define ACE_LACKS_WCSTOL + #define ACE_LACKS_WCSTOUL + #define ACE_LACKS_FGETWC + #define ACE_LACKS_FGETWS + #define ACE_LACKS_FPUTWS + #if !defined (ACE_MAIN) + # define ACE_MAIN ace_main + #endif /* ! ACE_MAIN */ +#endif + +// It is possible to enable pthread support with VxWorks, when the user decides +// to use this, we need some more defines +#if defined ACE_HAS_PTHREADS +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_HAS_POSIX_SEM +# define ACE_LACKS_MUTEXATTR_PSHARED +# define ACE_LACKS_CONDATTR_PSHARED +// Include this file, the sys/stat.h file shipped with VxWorks has old types +// and without this include we get a lot of compile errors. A TSR has been filed +// so that hopefully in the future we can zap this include +#include "types/vxTypesOld.h" +#else +# define ACE_LACKS_PTHREAD_H +# define ACE_HAS_VXTHREADS +# if !defined __RTP__ +// Only when building for kernel mode we can use TSS emulation, in rtp mode +// we can't use the WIND_TCB struct anymore +# define ACE_HAS_TSS_EMULATION +# endif +// VxWorks has no recursive mutexes. This was set in the past but it doesn't +// work with the pthread support, so only set it for the time being when pthread +// is disabled +# define ACE_HAS_RECURSIVE_MUTEXES +# define ACE_LACKS_COND_T +# define ACE_HAS_MUTEX_TIMEOUTS +#endif + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +// Needed include to get all VxWorks CPU types +#include "types/vxCpu.h" +#if (CPU == PENTIUM || CPU == PENTIUM2 || CPU == PENTIUM3 || CPU == PENTIUM4) +// If running an Intel Pentium the +// ACE_OS::gethrtime () can use the RDTSC instruction. +# define ACE_HAS_PENTIUM +#endif + +// VxWorks defines the CPU define MAP, undef it to prevent problems with +// application code +#if defined (MAP) +#undef MAP +#endif /* MAP */ + +#if !defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE) +# define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 +#endif /* ACE_NEEDS_HUGE_THREAD_STACKSIZE */ + +#if !defined (ACE_NTRACE) +# define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// By default, don't include RCS Id strings in object code. +#if !defined (ACE_USE_RCSID) +#define ACE_USE_RCSID 0 +#endif /* !ACE_USE_RCSID */ + +#if defined (ACE_HAS_IP_MULTICAST) +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_HAS_IP_MULTICAST */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_VXWORKS_6_2_H */ diff --git a/dep/ACE_wrappers/ace/config-vxworks6.3.h b/dep/ACE_wrappers/ace/config-vxworks6.3.h new file mode 100644 index 000000000..1b7cd4100 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks6.3.h @@ -0,0 +1,317 @@ +/* -*- C++ -*- */ +// $Id: config-vxworks6.3.h 81850 2008-06-06 08:39:54Z vzykov $ + +// The following configuration file is designed to work for VxWorks +// 6.3 platforms using one of these compilers: +// 1) The GNU g++ compiler that is shipped with VxWorks 6.3 + +#ifndef ACE_CONFIG_VXWORKS_6_3_H +#define ACE_CONFIG_VXWORKS_6_3_H +#include /**/ "ace/pre.h" + +#if ! defined (VXWORKS) +# define VXWORKS +#endif /* ! VXWORKS */ + +#if ! defined (ACE_VXWORKS) +# define ACE_VXWORKS 0x630 +#endif /* ! ACE_VXWORKS */ + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Compiler-specific configuration. +#if defined (__GNUG__) +# include "ace/config-g++-common.h" + +# define ACE_LACKS_IOSTREAM_FX +# define ACE_LACKS_LINEBUFFERED_STREAMBUF + +# if defined (__RTP__) && !defined (_HAS_C9X) +// Workaround for the fact that under RTP the log2 method can't be used +// without this define set, see TSR560446 +# if !defined (_C99) +# define _C99 +# endif +# endif + +#elif defined (__DCC__) +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_TEMPLATES_REQUIRE_SOURCE +#else /* ! __GNUG__ && ! ghs && !__DCC__ */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler on VxWorks +# endif /* __cplusplus */ +#endif /* ! __GNUG__ && ! ghs */ + +#if !defined __RTP__ +# if defined (TOOL) && (TOOL == gnu) +# if defined (CPU) && (CPU == PPC85XX || CPU == PPC604 || CPU == PPC603) +// These PPC's do lack log2 in kernel mode +# define ACE_LACKS_LOG2 +# endif +# endif +#endif + +// OS-specific configuration +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_NONCONST_GETBY +#define ACE_HAS_NONCONST_SWAB +#define ACE_LACKS_UNIX_SYSLOG +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 32768 +#define ACE_DEFAULT_THREAD_KEYS 16 +#define ACE_HAS_BROKEN_ACCEPT_ADDR +#define ACE_HAS_NONCONST_SENDMSG +#define ACE_HAS_NONCONST_WRITEV +#define ACE_HAS_CHARPTR_DL +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_DLL 0 +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SIGACTION_CONSTP2 +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN +#define ACE_HAS_STRERROR +#define ACE_HAS_THREADS +#define ACE_HAS_SYSCTL +#define ACE_LACKS_ALPHASORT +#define ACE_LACKS_EXEC +#define ACE_LACKS_FILELOCKS +#define ACE_LACKS_FORK +#define ACE_LACKS_GETHOSTENT +#define ACE_LACKS_GETSERVBYNAME +#define ACE_LACKS_GETPROTOBYNAME +#define ACE_LACKS_GETPROTOBYNUMBER +#define ACE_LACKS_GETIPNODEBYADDR +#define ACE_LACKS_GETIPNODEBYNAME_IPV6 +#define ACE_LACKS_LSTAT +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MALLOC_H +#define ACE_LACKS_MEMORY_H +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_PWD_FUNCTIONS +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_READLINK +#define ACE_LACKS_REALPATH +#define ACE_LACKS_PIPE +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_TEMPNAM +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_USECONDS_T +#define ACE_LACKS_UMASK +#define ACE_LACKS_STRPTIME +#define ACE_PAGE_SIZE 4096 +#define ACE_THR_PRI_FIFO_DEF 101 +#define ACE_THR_PRI_OTHER_DEF ACE_THR_PRI_FIFO_DEF +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND +#define ACE_HAS_GETIFADDRS + +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETSID +#define ACE_LACKS_SETUID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_GETEUID +#define ACE_LACKS_GETUID +#define ACE_LACKS_GETPGID +#define ACE_LACKS_GETEGID +#define ACE_LACKS_GETGID +#define ACE_LACKS_SETGID + +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_FCNTL + +// Some string things +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSDUP +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_STRTOULL +#define ACE_LACKS_WCSTOULL + +#define ACE_HAS_CHARPTR_SOCKOPT +#define ACE_LACKS_SYMLINKS + +#if defined __RTP__ + // We are building for RTP mode + #if !defined (ACE_AS_STATIC_LIBS) + # define ACE_HAS_SVR4_DYNAMIC_LINKING + #endif + #define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + #define ACE_LACKS_REGEX_H + #define ACE_LACKS_PUTENV + #define ACE_HAS_SETENV + #define ACE_HAS_3_PARAM_WCSTOK + #define ACE_HAS_WCHAR + #define ACE_HAS_VFWPRINTF + #define ACE_SIZEOF_WCHAR 2 + #define ACE_HAS_SHM_OPEN + #if defined (ACE_AS_STATIC_LIBS) + # define ACE_HAS_AIO_CALLS + #endif + #define ACE_LACKS_STRCASECMP + // VxWorks seems to either not define this or define as zero up till now + #if !defined (IOV_MAX) || (IOV_MAX == 0) + #define ACE_IOV_MAX 16 + #endif +#else + // We are building for kernel mode + #define ACE_LACKS_SUSECONDS_T + #define ACE_LACKS_INTPTR_T + #define ACE_LACKS_INTTYPES_H + #define ACE_LACKS_STDINT_H + #define ACE_LACKS_UNAME + #define ACE_LACKS_UTSNAME_T + #define ACE_LACKS_RAND_REENTRANT_FUNCTIONS + #define ACE_LACKS_DLFCN_H + #define ACE_LACKS_WAIT + #define ACE_LACKS_WAITPID + #define ACE_LACKS_SYS_TIME_H + #define ACE_LACKS_SYS_SELECT_H + #define ACE_MKDIR_LACKS_MODE + #define ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R + #define ACE_LACKS_SEARCH_H + #define ACE_LACKS_SYSCONF + #define ACE_LACKS_GETPID + #define ACE_LACKS_GETPPID + #define ACE_LACKS_WCHAR_H + #define ACE_LACKS_WCTYPE_H + #define ACE_LACKS_WCSCAT + #define ACE_LACKS_WCSCHR + #define ACE_LACKS_WCSCMP + #define ACE_LACKS_WCSCPY + #define ACE_LACKS_WCSCSPN + #define ACE_LACKS_WCSLEN + #define ACE_LACKS_WCSNCAT + #define ACE_LACKS_WCSNCMP + #define ACE_LACKS_WCSNCPY + #define ACE_LACKS_WCSPBRK + #define ACE_LACKS_WCSRCHR + #define ACE_LACKS_WCSSPN + #define ACE_LACKS_WCSSTR + #define ACE_LACKS_WCSTOK + #define ACE_LACKS_TOWLOWER + #define ACE_LACKS_TOWUPPER + #define ACE_LACKS_WCSTOD + #define ACE_LACKS_WCSTOL + #define ACE_LACKS_WCSTOUL + #define ACE_LACKS_FGETWC + #define ACE_LACKS_FGETWS + #define ACE_LACKS_FPUTWS + #define ACE_HAS_IOCTL_INT_3_PARAM + #define ACE_LACKS_MMAP + #define ACE_LACKS_MSYNC + #define ACE_LACKS_MPROTECT + #if !defined (ACE_MAIN) + # define ACE_MAIN ace_main + #endif /* ! ACE_MAIN */ +#endif + +// It is possible to enable pthread support with VxWorks, when the user decides +// to use this, we need some more defines +#if defined ACE_HAS_PTHREADS +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# define ACE_HAS_POSIX_SEM +# define ACE_LACKS_MUTEXATTR_PSHARED +# define ACE_LACKS_CONDATTR_PSHARED +// Include this file, the sys/stat.h file shipped with VxWorks has old types +// and without this include we get a lot of compile errors. A TSR has been filed +// so that hopefully in the future we can zap this include +#include "types/vxTypesOld.h" +#else +# define ACE_LACKS_PTHREAD_H +# define ACE_HAS_VXTHREADS +# if !defined __RTP__ +// Only when building for kernel mode we can use TSS emulation, in rtp mode +// we can't use the WIND_TCB struct anymore +# define ACE_HAS_TSS_EMULATION +# if !defined (ACE_VXWORKS_SPARE) +# define ACE_VXWORKS_SPARE spare4 +# endif /* ! ACE_VXWORKS_SPARE */ +# endif +// VxWorks has no recursive mutexes. This was set in the past but it doesn't +// work with the pthread support, so only set it for the time being when pthread +// is disabled +# define ACE_HAS_RECURSIVE_MUTEXES +# define ACE_LACKS_COND_T +# define ACE_HAS_MUTEX_TIMEOUTS +#endif + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +// Needed include to get all VxWorks CPU types +#include "types/vxCpu.h" +#if defined (CPU) && (CPU == PENTIUM || CPU == PENTIUM2 || CPU == PENTIUM3 || CPU == PENTIUM4) + // If running an Intel Pentium the + // ACE_OS::gethrtime () can use the RDTSC instruction. + # define ACE_HAS_PENTIUM +#endif + +// VxWorks defines the CPU define MAP, undef it to prevent problems with +// application code +#if defined (MAP) +#undef MAP +#endif /* MAP */ + +#if !defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE) +# define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 +#endif /* ACE_NEEDS_HUGE_THREAD_STACKSIZE */ + +#if !defined (ACE_NTRACE) +# define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// By default, don't include RCS Id strings in object code. +#if !defined (ACE_USE_RCSID) +#define ACE_USE_RCSID 0 +#endif /* !ACE_USE_RCSID */ + +#if defined (ACE_HAS_IP_MULTICAST) +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_HAS_IP_MULTICAST */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_VXWORKS_6_3_H */ diff --git a/dep/ACE_wrappers/ace/config-vxworks6.4.h b/dep/ACE_wrappers/ace/config-vxworks6.4.h new file mode 100644 index 000000000..2d8db5294 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks6.4.h @@ -0,0 +1,340 @@ +//* -*- C++ -*- */ +// $Id: config-vxworks6.4.h 81850 2008-06-06 08:39:54Z vzykov $ + +// The following configuration file is designed to work for VxWorks +// 6.4 platforms using one of these compilers: +// 1) The GNU g++ compiler that is shipped with VxWorks 6.4 +// 2) The Diab compiler that is shipped with VxWorks 6.4 + +#ifndef ACE_CONFIG_VXWORKS_6_4_H +#define ACE_CONFIG_VXWORKS_6_4_H +#include /**/ "ace/pre.h" + +#if ! defined (VXWORKS) +# define VXWORKS +#endif /* ! VXWORKS */ + +#if ! defined (ACE_VXWORKS) +# define ACE_VXWORKS 0x640 +#endif /* ! ACE_VXWORKS */ + +#if !defined (__RTP__) + // Fix for wrong typedef of time_t in kernel mode + #ifndef _TIME_T + #define _TIME_T + typedef long time_t; + #endif +#endif + +#if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ +#endif /* ! __ACE_INLINE__ */ + +// Compiler-specific configuration. +#if defined (__GNUG__) +# include "ace/config-g++-common.h" + +# define ACE_LACKS_IOSTREAM_FX +# define ACE_LACKS_LINEBUFFERED_STREAMBUF + +# if defined (__RTP__) && !defined (_HAS_C9X) +// Workaround for the fact that under RTP the log2 method can't be used +// without this define set, see TSR560446 +# if !defined (_C99) +# define _C99 +# endif +# endif + +#elif defined (__DCC__) +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_TEMPLATES_REQUIRE_SOURCE +#else /* ! __GNUG__ && ! ghs && !__DCC__ */ +# ifdef __cplusplus /* Let it slide for C compilers. */ +# error unsupported compiler on VxWorks +# endif /* __cplusplus */ +#endif /* ! __GNUG__ && ! ghs */ + +// Needed include to get all VxWorks CPU types +#include "types/vxCpu.h" +#if defined __RTP__ + #if defined (_VX_CPU) && (_VX_CPU == _VX_PENTIUM || _VX_CPU == _VX_PENTIUM2 || _VX_CPU == _VX_PENTIUM3 || _VX_CPU == _VX_PENTIUM4) + // If running an Intel Pentium the + // ACE_OS::gethrtime () can use the RDTSC instruction. + # define ACE_HAS_PENTIUM + #endif +#else + #if defined (CPU) && (CPU == PENTIUM || CPU == PENTIUM2 || CPU == PENTIUM3 || CPU == PENTIUM4) + // If running an Intel Pentium the + // ACE_OS::gethrtime () can use the RDTSC instruction. + # define ACE_HAS_PENTIUM + #endif +#endif + +#if !defined __RTP__ +# if defined (TOOL) && (TOOL == gnu) +# if defined (CPU) && (CPU == PPC85XX || CPU == PPC604 || CPU == PPC603) +// These PPC's do lack log2 in kernel mode +# define ACE_LACKS_LOG2 +# endif +# endif +#endif + +// OS-specific configuration +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +#define ACE_HAS_3_PARAM_READDIR_R +#define ACE_HAS_NONCONST_GETBY +#define ACE_HAS_NONCONST_SWAB +#define ACE_LACKS_UNIX_SYSLOG +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 32768 +#define ACE_DEFAULT_THREAD_KEYS 16 +#define ACE_HAS_BROKEN_ACCEPT_ADDR +#define ACE_HAS_NONCONST_SENDMSG +#define ACE_HAS_NONCONST_WRITEV +#define ACE_HAS_CHARPTR_DL +#define ACE_HAS_CLOCK_GETTIME +#define ACE_HAS_CLOCK_SETTIME +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_DIRENT +#define ACE_HAS_DLL 0 +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT +#define ACE_HAS_MSG +#define ACE_HAS_NONCONST_READV +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SIGACTION_CONSTP2 +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_SOCKADDR_IN6_SIN6_LEN +#define ACE_HAS_STRERROR +#define ACE_HAS_THREADS +#define ACE_HAS_SYSCTL +#define ACE_LACKS_ALPHASORT +#define ACE_LACKS_EXEC +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_FILELOCKS +#define ACE_LACKS_FORK +#define ACE_LACKS_GETHOSTENT +#define ACE_LACKS_GETSERVBYNAME +#define ACE_LACKS_GETPROTOBYNAME +#define ACE_LACKS_GETPROTOBYNUMBER +#define ACE_LACKS_GETIPNODEBYADDR +#define ACE_LACKS_GETIPNODEBYNAME_IPV6 +#define ACE_LACKS_LSTAT +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MALLOC_H +#define ACE_LACKS_MEMORY_H +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_PWD_FUNCTIONS +#define ACE_LACKS_READLINK +#define ACE_LACKS_REALPATH +#define ACE_LACKS_PIPE +#define ACE_LACKS_RWLOCK_T +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_TELLDIR +#define ACE_LACKS_TIMESPEC_T +#define ACE_LACKS_TRUNCATE +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_USECONDS_T +#define ACE_LACKS_UMASK +#define ACE_LACKS_STRPTIME +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_TEMPNAM +#define ACE_PAGE_SIZE 4096 +#define ACE_THR_PRI_FIFO_DEF 101 +#define ACE_THR_PRI_OTHER_DEF ACE_THR_PRI_FIFO_DEF +#define ACE_HAS_SIGTIMEDWAIT +#define ACE_HAS_SIGSUSPEND +#define ACE_HAS_GETIFADDRS + +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETSID +#define ACE_LACKS_SETUID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_GETEUID +#define ACE_LACKS_GETUID +#define ACE_LACKS_GETPGID +#define ACE_LACKS_GETEGID +#define ACE_LACKS_GETGID +#define ACE_LACKS_SETGID + +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_FCNTL + +// Some string things +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSDUP +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_LACKS_STRTOULL +#define ACE_LACKS_WCSTOULL + +#define ACE_HAS_CHARPTR_SOCKOPT +#define ACE_LACKS_SYMLINKS + +#if defined __RTP__ + // We are building for RTP mode + #if !defined (ACE_AS_STATIC_LIBS) + # define ACE_HAS_SVR4_DYNAMIC_LINKING + #endif + #define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R + #define ACE_LACKS_REGEX_H + #if defined ACE_HAS_PENTIUM + // Bug to workaround VxWorks 6.4 x86 + # define ACE_LACKS_PUTENV + #endif + #define ACE_HAS_SETENV + #define ACE_LACKS_STRCASECMP + #define ACE_HAS_3_PARAM_WCSTOK + #define ACE_HAS_WCHAR + #define ACE_HAS_VFWPRINTF + #define ACE_SIZEOF_WCHAR 2 + #define ACE_HAS_SHM_OPEN + #if defined (ACE_AS_STATIC_LIBS) + # define ACE_HAS_AIO_CALLS + #endif + // VxWorks seems to either not define this or define as zero up till now + #if !defined (IOV_MAX) || (IOV_MAX == 0) + #define ACE_IOV_MAX 16 + #endif +#else + // We are building for kernel mode + #define ACE_LACKS_SUSECONDS_T + #define ACE_LACKS_INTPTR_T + #define ACE_LACKS_INTTYPES_H + #define ACE_LACKS_STDINT_H + #define ACE_LACKS_UNAME + #define ACE_LACKS_UTSNAME_T + #define ACE_LACKS_RAND_REENTRANT_FUNCTIONS + #define ACE_LACKS_DLFCN_H + #define ACE_LACKS_WAIT + #define ACE_LACKS_WAITPID + #define ACE_LACKS_SYS_TIME_H + #define ACE_LACKS_SYS_SELECT_H + #define ACE_MKDIR_LACKS_MODE + #define ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R + #define ACE_LACKS_SEARCH_H + #define ACE_LACKS_SYSCONF + #define ACE_LACKS_GETPPID + #define ACE_LACKS_WCHAR_H + #define ACE_LACKS_WCTYPE_H + #define ACE_LACKS_WCSCAT + #define ACE_LACKS_WCSCHR + #define ACE_LACKS_WCSCMP + #define ACE_LACKS_WCSCPY + #define ACE_LACKS_WCSCSPN + #define ACE_LACKS_WCSLEN + #define ACE_LACKS_WCSNCAT + #define ACE_LACKS_WCSNCMP + #define ACE_LACKS_WCSNCPY + #define ACE_LACKS_WCSPBRK + #define ACE_LACKS_WCSRCHR + #define ACE_LACKS_WCSSPN + #define ACE_LACKS_WCSSTR + #define ACE_LACKS_WCSTOK + #define ACE_LACKS_TOWLOWER + #define ACE_LACKS_TOWUPPER + #define ACE_LACKS_WCSTOD + #define ACE_LACKS_WCSTOL + #define ACE_LACKS_WCSTOUL + #define ACE_LACKS_FGETWC + #define ACE_LACKS_FGETWS + #define ACE_LACKS_FPUTWS + #define ACE_HAS_IOCTL_INT_3_PARAM + #define ACE_LACKS_MMAP + #define ACE_LACKS_MSYNC + #define ACE_LACKS_MPROTECT + #if !defined (ACE_MAIN) + # define ACE_MAIN ace_main + #endif /* ! ACE_MAIN */ +#endif + +// It is possible to enable pthread support with VxWorks, when the user decides +// to use this, we need some more defines +#if defined ACE_HAS_PTHREADS +# define ACE_HAS_THREAD_SPECIFIC_STORAGE +# if !defined __RTP__ +# define ACE_LACKS_PTHREAD_ATTR_SETSTACK +# endif +# define ACE_HAS_PTHREAD_ATTR_SETNAME +# define ACE_HAS_POSIX_SEM +# define ACE_LACKS_MUTEXATTR_PSHARED +# define ACE_LACKS_CONDATTR_PSHARED +// Include this file, the sys/stat.h file shipped with VxWorks has old types +// and without this include we get a lot of compile errors. A TSR has been filed +// so that hopefully in the future we can zap this include +#include "types/vxTypesOld.h" +#else +# define ACE_LACKS_PTHREAD_H +# define ACE_HAS_VXTHREADS +# if !defined __RTP__ +// Only when building for kernel mode we can use TSS emulation, in rtp mode +// we can't use the WIND_TCB struct anymore +# define ACE_HAS_TSS_EMULATION +# if !defined (ACE_VXWORKS_SPARE) +# define ACE_VXWORKS_SPARE spare4 +# endif /* ! ACE_VXWORKS_SPARE */ +# endif +// VxWorks has no recursive mutexes. This was set in the past but it doesn't +// work with the pthread support, so only set it for the time being when pthread +// is disabled +# define ACE_HAS_RECURSIVE_MUTEXES +# define ACE_LACKS_COND_T +# define ACE_HAS_MUTEX_TIMEOUTS +#endif + +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +// VxWorks defines the CPU define MAP, undef it to prevent problems with +// application code +#if defined (MAP) +#undef MAP +#endif /* MAP */ + +#if !defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE) +# define ACE_NEEDS_HUGE_THREAD_STACKSIZE 65536 +#endif /* ACE_NEEDS_HUGE_THREAD_STACKSIZE */ + +#if !defined (ACE_NTRACE) +# define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// By default, don't include RCS Id strings in object code. +#if !defined (ACE_USE_RCSID) +#define ACE_USE_RCSID 0 +#endif /* !ACE_USE_RCSID */ + +#if defined (ACE_HAS_IP_MULTICAST) +# define ACE_LACKS_PERFECT_MULTICAST_FILTERING 1 +#endif /* ACE_HAS_IP_MULTICAST */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_VXWORKS_6_4_H */ diff --git a/dep/ACE_wrappers/ace/config-vxworks6.5.h b/dep/ACE_wrappers/ace/config-vxworks6.5.h new file mode 100644 index 000000000..19273e6ca --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks6.5.h @@ -0,0 +1,25 @@ +//* -*- C++ -*- */ +// $Id: config-vxworks6.5.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for VxWorks +// 6.5 platforms using one of these compilers: +// 1) The GNU g++ compiler that is shipped with VxWorks 6.5 +// 2) The Diab compiler that is shipped with VxWorks 6.5 + +#ifndef ACE_CONFIG_VXWORKS_6_5_H +#define ACE_CONFIG_VXWORKS_6_5_H +#include /**/ "ace/pre.h" + +#if !defined (ACE_VXWORKS) +# define ACE_VXWORKS 0x650 +#endif /* ! ACE_VXWORKS */ + +#include "ace/config-vxworks6.4.h" + +#if defined (__RTP__) +# undef ACE_HAS_GETIFADDRS +#endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_VXWORKS_6_5_H */ + diff --git a/dep/ACE_wrappers/ace/config-vxworks6.6.h b/dep/ACE_wrappers/ace/config-vxworks6.6.h new file mode 100644 index 000000000..98787f39e --- /dev/null +++ b/dep/ACE_wrappers/ace/config-vxworks6.6.h @@ -0,0 +1,29 @@ +//* -*- C++ -*- */ +// $Id: config-vxworks6.6.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for VxWorks +// 6.6 platforms using one of these compilers: +// 1) The GNU g++ compiler that is shipped with VxWorks 6.6 +// 2) The Diab compiler that is shipped with VxWorks 6.6 + +#ifndef ACE_CONFIG_VXWORKS_6_6_H +#define ACE_CONFIG_VXWORKS_6_6_H +#include /**/ "ace/pre.h" + +#if !defined (ACE_VXWORKS) +# define ACE_VXWORKS 0x660 +#endif /* ! ACE_VXWORKS */ + +#include "ace/config-vxworks6.5.h" + +#if defined (ACE_HAS_PENTIUM) +# define ACE_LACKS_LOG2 +#endif + +#if !defined (__RTP__) +# undef ACE_HAS_IOCTL_INT_3_PARAM +#endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_VXWORKS_6_6_H */ + diff --git a/dep/ACE_wrappers/ace/config-win32-borland.h b/dep/ACE_wrappers/ace/config-win32-borland.h new file mode 100644 index 000000000..2c05bc074 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-borland.h @@ -0,0 +1,125 @@ +// -*- C++ -*- +//$Id: config-win32-borland.h 82643 2008-08-19 14:02:12Z johnnyw $ + +// The following configuration file contains defines for Borland compilers. + +#ifndef ACE_CONFIG_WIN32_BORLAND_H +#define ACE_CONFIG_WIN32_BORLAND_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#include "config-borland-common.h" + +// Automatically define WIN32 macro if the compiler tells us it is our +// target platform. +# if defined (__WIN32__) && !defined (WIN32) +# define WIN32 1 +# endif + +// When building a VCL application, the main VCL header file should be +// included before anything else. You can define ACE_HAS_VCL=1 in your +// project settings to have this file included for you automatically. +# if defined (ACE_HAS_VCL) && (ACE_HAS_VCL != 0) +# include /**/ +# endif + +# define ACE_CC_PREPROCESSOR "CPP32.EXE" + +# include "ace/config-win32-common.h" + +// Borland on win32 has swab +# undef ACE_LACKS_SWAB + +# define ACE_WSTRING_HAS_USHORT_SUPPORT 1 +# define ACE_HAS_DIRENT + +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDC_LIB +#undef ACE_USES_STD_NAMESPACE_FOR_STDC_LIB +#define ACE_USES_STD_NAMESPACE_FOR_STDC_LIB 1 +#endif + +#define ACE_NEEDS_DL_UNDERSCORE + +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_NETINET_TCP_H +#define ACE_LACKS_REGEX_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_STRINGS_H +#define ACE_LACKS_SEMAPHORE_H +#define ACE_LACKS_INTTYPES_H +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_SYS_SELECT_H +#define ACE_LACKS_SYS_TIME_H +#define ACE_LACKS_SYS_RESOURCE_H +#define ACE_LACKS_SYS_WAIT_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_SYS_MMAN_H +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_SOCKET_H +#define ACE_LACKS_NETINET_IN_H +#define ACE_LACKS_NETDB_H +#define ACE_LACKS_NET_IF_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_SYS_IOCTL_H +#define ACE_LACKS_STROPTS_H + +#undef ACE_LACKS_STRUCT_DIR +#undef ACE_LACKS_CLOSEDIR +#undef ACE_LACKS_OPENDIR +#undef ACE_LACKS_READDIR +#undef ACE_LACKS_REWINDDIR + +#define ACE_HAS_WOPENDIR +#define ACE_HAS_WCLOSEDIR +#define ACE_HAS_WREADDIR +#define ACE_HAS_WREWINDDIR + +#define ACE_LACKS_STRRECVFD +#define ACE_USES_EXPLICIT_STD_NAMESPACE + +#if defined(ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +// must have _MT defined to include multithreading +// features from win32 headers +# if !defined(__MT__) +// *** DO NOT *** defeat this error message by defining __MT__ yourself. +// You must link with the multi threaded libraries. Add -tWM to your +// compiler options +# error You must link against multi-threaded libraries when using ACE (check your project settings) +# endif /* !_MT && !ACE_HAS_WINCE */ +#endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */ + +#if (__BORLANDC__ < 0x580) +# define ACE_LACKS_INTPTR_T +# define ACE_HAS_NONCONST_SWAB +# define ACE_HAS_NONCONST_FDOPEN +#endif + +#if (__BORLANDC__ < 0x610) +# define ACE_HAS_NONCONST_TEMPNAM +# define ACE_LACKS_STRTOULL +# define ACE_LACKS_WCSTOULL +#endif + +#if (__BORLANDC__ <= 0x610) +// Older Borland compilers can't handle assembly in inline methods or +// templates (E2211). When we build for pentium optimized and we are inlining +// then we disable inline assembly +# if defined (ACE_HAS_PENTIUM) && defined(__ACE_INLINE__) +# define ACE_LACKS_INLINE_ASSEMBLY +# endif +#endif + +#define ACE_WCSDUP_EQUIVALENT ::_wcsdup +#define ACE_STRCASECMP_EQUIVALENT ::stricmp +#define ACE_STRNCASECMP_EQUIVALENT ::strnicmp +#define ACE_HAS_ITOA 1 + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_BORLAND_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-common.h b/dep/ACE_wrappers/ace/config-win32-common.h new file mode 100644 index 000000000..837f9ce4d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-common.h @@ -0,0 +1,666 @@ +/* -*- C++ -*- */ +// $Id: config-win32-common.h 82316 2008-07-15 01:28:39Z johnnyw $ + + +#ifndef ACE_CONFIG_WIN32_COMMON_H +#define ACE_CONFIG_WIN32_COMMON_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + + +// Windows Mobile (CE) stuff is primarily further restrictions to what's +// in the rest of this file. Also, it defined ACE_HAS_WINCE, which is used +// in this file. +#if defined (_WIN32_WCE) +# include "ace/config-WinCE.h" +#endif /* _WIN32_WCE */ + +// Complain if WIN32 is not already defined. +#if !defined (WIN32) && !defined (ACE_HAS_WINCE) +# error Please define WIN32 in your project settings. +#endif + +#define ACE_WIN32 +#if defined (_WIN64) || defined (WIN64) +# define ACE_WIN64 + +// Use 64-bit file offsets by default in the WIN64 case, similar to +// what 64-bit UNIX systems do. +// +// Note that _FILE_OFFSET_BITS is not recognized by Windows. It is, +// however, recognized by ACE. +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif /* !_FILE_OFFSET_BITS */ +#endif /* _WIN64 || WIN64 */ + +#if !defined (_WIN32_WINNT) +# define _WIN32_WINNT 0x0501 // pretend it's at least Windows XP or Win2003 +#endif + +// If the invoking procedure turned off debugging by setting NDEBUG, then +// also set ACE_NDEBUG, unless the user has already set it. +#if defined (NDEBUG) +# if !defined (ACE_NDEBUG) +# define ACE_NDEBUG +# endif /* ACE_NDEBUG */ +#endif /* NDEBUG */ + +// Define ACE_HAS_MFC to 1, if you want ACE to use CWinThread. This should +// be defined, if your application uses MFC. +// Setting applies to : building ACE +// Runtime restrictions: MFC DLLs must be installed +// Additonal notes : If both ACE_HAS_MFC and ACE_MT_SAFE are +// defined, the MFC DLL (not the static lib) +// will be used from ACE. +#if !defined (ACE_HAS_MFC) +# define ACE_HAS_MFC 0 +#endif + +// ACE_USES_STATIC_MFC always implies ACE_HAS_MFC +#if defined (ACE_USES_STATIC_MFC) +# if defined (ACE_HAS_MFC) +# undef ACE_HAS_MFC +# endif +# define ACE_HAS_MFC 1 +#endif /* ACE_USES_STATIC_MFC */ + +// Define ACE_HAS_STRICT to 1 in your config.h file if you want to use +// STRICT type checking. It is disabled by default because it will +// break existing application code. However, if ACE_HAS_MFC is turned on, +// ACE_HAS_STRICT is required by MFC. +// Setting applies to : building ACE, linking with ACE +// Runtime restrictions: - +#if !defined (ACE_HAS_STRICT) +# define ACE_HAS_STRICT 0 +#endif + +// MFC itself defines STRICT. +#if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) +# undef ACE_HAS_STRICT +# define ACE_HAS_STRICT 1 +#endif + +// Turn off the following define if you want to disable threading. +// Compile using multi-thread libraries. +// Setting applies to : building ACE, linking with ACE +// Runtime restrictions: multithreaded runtime DLL must be installed +#if !defined (ACE_MT_SAFE) +# define ACE_MT_SAFE 1 +#endif + +// Build ACE services as DLLs. If you write a library and want it to +// use ACE_Svc_Export, this will cause those macros to build dlls. If +// you want your ACE service to be a static library, comment out this +// line. As far as I know, the only reason to have a library be an +// ACE "service" is to leverage the ACE_Svc_Export macros. It's just +// as easy to define your own export macros. +// #if !defined (ACE_SVC_HAS_DLL) +// # define ACE_SVC_HAS_DLL 1 +// #endif + +// Define the special export macros needed to export symbols outside a dll +#if !defined(__BORLANDC__) +#define ACE_HAS_CUSTOM_EXPORT_MACROS 1 +#define ACE_Proper_Export_Flag __declspec (dllexport) +#define ACE_Proper_Import_Flag __declspec (dllimport) +#define ACE_EXPORT_SINGLETON_DECLARATION(T) template class __declspec (dllexport) T +#define ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) template class __declspec (dllexport) SINGLETON_TYPE; +#define ACE_IMPORT_SINGLETON_DECLARATION(T) extern template class T +#define ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) extern template class SINGLETON_TYPE ; +#endif /* !__BORLANDC__ */ + +// Define ACE_HAS_WINSOCK2 to 0 in your config.h file if you do *not* +// want to compile with WinSock 2.0. +// Setting applies to : building ACE +// Runtime restrictions: winsock2 must be installed. +// #define ACE_HAS_WINSOCK2 0 + +// By default, we use non-static object manager on Win32. That is, +// the object manager is allocated in main's stack memory. If this +// does not suit your need, i.e., if your programs depend on the use +// of static object manager, you neet to disable the behavior by adding +// +// #undef ACE_HAS_NONSTATIC_OBJECT_MANAGER +// +// in the config.h after including config-win32.h +// +// MFC users: the main function is defined within a MFC library and +// therefore, ACE won't be able to meddle with main function and +// instantiate the non-static object manager for you. To solve the +// problem, you'll need to instantiate the ACE_Object_Manager by +// either: +// +// 1. Using static object manager (as described above), however, using +// the non-static object manager is prefered, therefore, +// 2. Instantiate the non-static object manager yourself by either 1) +// call ACE::init () at the beginning and ACE::fini () at the end, +// _or_ 2) instantiate the ACE_Object_Manager in your CWinApp +// derived class. +// +// Optionally, you can #define +// ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER in your +// ace/config.h and always take care of the business by yourself. +// ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER has no effect when +// using static object managers. +#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) +# define ACE_HAS_NONSTATIC_OBJECT_MANAGER +#elif (ACE_HAS_NONSTATIC_OBJECT_MANAGER == 0) +# undef ACE_HAS_NONSTATIC_OBJECT_MANAGER +#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ + +#define ACE_HAS_GPERF + +// By default, don't include RCS Id strings in object code. +#if !defined (ACE_USE_RCSID) +# define ACE_USE_RCSID 0 +#endif /* ! ACE_USE_RCSID */ + +// ---------------- platform features or lack of them ------------- + +// By default WIN32 has FD_SETSIZE of 64, which places the limit +// between 61 and 64 on the number of clients a server using the +// Select Reactor can support at the same time (i.e., 64 - standard in, +// out, error). Here we raise the limit to 1024. Adjust the definition +// below if you need to raise or lower it. + +#if !defined (FD_SETSIZE) +#define FD_SETSIZE 1024 +#endif /* FD_SETSIZE */ + + +// Windows doesn't like 65536 ;-) If 65536 is specified, it is +// silently ignored by the OS, i.e., setsockopt does not fail, and you +// get stuck with the default size of 8k. +#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 65535 + +// It seems like Win32 does not have a limit on the number of buffers +// that can be transferred by the scatter/gather type of I/O +// functions, e.g., WSASend and WSARecv. We are setting this to be 64 +// for now. The typically use case is to create an I/O vector array +// of size ACE_IOV_MAX on the stack and then filled in. Note that we +// probably don't want too big a value for ACE_IOV_MAX since it may +// mostly go to waste or the size of the activation record may become +// excessively large. +#if !defined (ACE_IOV_MAX) +# define ACE_IOV_MAX 64 +#endif /* ACE_IOV_MAX */ + +#if !defined (ACE_HAS_WINCE) +// Platform supports pread() and pwrite() +# define ACE_HAS_P_READ_WRITE +#endif /* ! ACE_HAS_WINCE */ + +#if !defined (__MINGW32__) +# define ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS +#endif /* __MINGW32__ */ + +#define ACE_DEFAULT_THREAD_PRIORITY 0 + +#define ACE_HAS_DIRENT +#define ACE_HAS_MSG +#define ACE_HAS_RECURSIVE_MUTEXES +#define ACE_HAS_SOCKADDR_MSG_NAME +#define ACE_HAS_THREAD_SAFE_ACCEPT + +/* LACKS dir-related facilities */ +#define ACE_LACKS_READDIR_R +#define ACE_LACKS_REWINDDIR +#define ACE_LACKS_SEEKDIR +#define ACE_LACKS_TELLDIR + +/* LACKS gid/pid/sid/uid facilities */ +#define ACE_LACKS_GETPGID +#define ACE_LACKS_GETPPID +#define ACE_LACKS_SETPGID +#define ACE_LACKS_SETREGID +#define ACE_LACKS_SETREUID +#define ACE_LACKS_SETSID +#define ACE_LACKS_SETEGID +#define ACE_LACKS_SETUID +#define ACE_LACKS_SETEUID +#define ACE_LACKS_GETGID +#define ACE_LACKS_GETEGID +#define ACE_LACKS_GETUID +#define ACE_LACKS_GETEUID +#define ACE_LACKS_SETGID + +/* LACKS miscellaneous */ +#define ACE_LACKS_ALARM +#define ACE_LACKS_ARPA_INET_H +#define ACE_LACKS_DUP2 +#define ACE_LACKS_FORK +#define ACE_LACKS_GETHOSTENT +#define ACE_LACKS_GETOPT +#define ACE_LACKS_GETIPNODEBYNAME_IPV6 +#define ACE_LACKS_KILL +#define ACE_LACKS_INET_ATON +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MKFIFO +#define ACE_LACKS_MODE_MASKS +#define ACE_LACKS_PTHREAD_H +#define ACE_LACKS_PWD_FUNCTIONS +#define ACE_LACKS_READLINK +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_SBRK +#define ACE_LACKS_SCHED_H +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SIGACTION +#define ACE_LACKS_SIGSET +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_SUSECONDS_T +#define ACE_LACKS_USECONDS_T +#define ACE_LACKS_SYS_PARAM_H +#define ACE_LACKS_SYS_SYSCTL_H +#define ACE_LACKS_SYSCONF +#define ACE_LACKS_SYSV_SHMEM +#define ACE_LACKS_UNISTD_H +#define ACE_LACKS_UNIX_SIGNALS +#define ACE_LACKS_UNIX_SYSLOG +#define ACE_LACKS_UTSNAME_T +#define ACE_LACKS_UNAME +#define ACE_LACKS_WAIT +#define ACE_LACKS_IOVEC +#define ACE_LACKS_LOG2 + +#define ACE_HAS_PDH_H +#define ACE_HAS_PDHMSG_H + +#define ACE_HAS_VFWPRINTF + +#define ACE_MKDIR_LACKS_MODE + +#define ACE_SIZEOF_LONG_LONG 8 +// Green Hills Native x86 does not support __int64 keyword +// Neither does mingw32. +#if !defined (ACE_LACKS_LONGLONG_T) && !defined (__MINGW32__) +#define ACE_INT64_TYPE signed __int64 +#define ACE_UINT64_TYPE unsigned __int64 +#endif /* (ghs) */ + +#if defined (__MINGW32__) +#define ACE_INT64_TYPE signed long long +#define ACE_UINT64_TYPE unsigned long long +#endif + +// Optimize ACE_Handle_Set for select(). +#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT + +// Win32 has wide-char support. Use of the compiler-defined wchar_t type +// is controlled in compiler configs since it's a compiler switch. +#define ACE_HAS_WCHAR + +// Compiler/platform correctly calls init()/fini() for shared +// libraries. - applied for DLLs ? +//define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +//define ACE_HAS_POSIX_NONBLOCK + +// Platform contains . +//define ACE_HAS_POLL + +// Platform supports the /proc file system. +//define ACE_HAS_PROC_FS + +// Platform supports the rusage struct. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform supports SVR4 signal typedef. +//define ACE_HAS_SVR4_SIGNAL_T + +// Platform provides header. +//define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +//define ACE_HAS_SYS_SIGLIST + +// Platform supports ACE_TLI timod STREAMS module. +//define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +//define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +// For Win32, this is not really true, but saves a lot of hassle! +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +//define ACE_HAS_TLI + +// I'm pretty sure NT lacks these +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS + +// Windows NT needs readv() and writev() +#define ACE_LACKS_WRITEV +#define ACE_LACKS_READV + +#define ACE_LACKS_COND_T +#define ACE_LACKS_RWLOCK_T + +#define ACE_LACKS_KEY_T + +// No system support for replacing any previous mappings. +#define ACE_LACKS_AUTO_MMAP_REPLACEMENT + +// ACE_HAS_PENTIUM is used to optimize some CDR operations; it's used for +// some other time-related things using g++, but not for VC. Current VC +// compilers set _M_IX86 > 400 by default so if you're not using a Pentium +// class CPU, set the project code generation options appropriately. +#if !defined(ACE_HAS_PENTIUM) && (_M_IX86 > 400) +# define ACE_HAS_PENTIUM +#endif + +#if defined(ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +// Platform supports threads. +# define ACE_HAS_THREADS + +// Platform supports Windows32 threads. +# define ACE_HAS_WTHREADS + +// Compiler/platform has thread-specific storage +# define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Win32 doesn't have fcntl +#define ACE_LACKS_FCNTL + +#endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */ + +#if !defined(_DEBUG) +// If we are making a release, and the user has not specified +// inline directives, we will default to inline +# if ! defined (__ACE_INLINE__) +# define __ACE_INLINE__ 1 +# endif /* __ACE_INLINE__ */ +#endif + +// If __ACE_INLINE__ is defined to be 0, we will undefine it +#if defined (__ACE_INLINE__) && (__ACE_INLINE__ == 0) +# undef __ACE_INLINE__ +#endif /* __ACE_INLINE__ */ + +// We are build ACE and want to use MFC (multithreaded) +#if defined(ACE_HAS_MFC) && (ACE_HAS_MFC != 0) && defined (_MT) +# if (ACE_HAS_DLL != 0) && defined(ACE_BUILD_DLL) && !defined (_WINDLL) +// force multithreaded MFC DLL +# define _WINDLL +# endif /* _AFXDLL */ +# if !defined (_AFXDLL) && !defined (ACE_USES_STATIC_MFC) +# define _AFXDLL +# endif /* _AFXDLL */ +#endif + +// and MFC's are mutually +// incompatible. is brain-dead about MFC; it doesn't check +// to see whether MFC stuff is anticipated or already in progress +// before doing its thing. ACE needs (practically always) , +// and winsock in turn needs support either from windows.h or from +// afxwin.h. One or the other, not both. +// +// The MSVC++ V4.0 environment defines preprocessor macros that +// indicate the programmer has chosen something from the +// Build-->Settings-->General-->MFC combo-box. defines a +// macro itself to protect against double inclusion. We'll take +// advantage of all this to select the proper support for winsock. - +// trl 26-July-1996 + +// This is necessary since MFC users apparently can't #include +// directly. +#if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) +# include /**/ /* He is doing MFC */ +// Windows.h will be included via afxwin.h->afx.h->afx_ver_.h->afxv_w32.h +// #define _INC_WINDOWS // Prevent winsock.h from including windows.h +#elif defined (ACE_HAS_WINCE) +# include /**/ +#endif + +#if !defined (_INC_WINDOWS) /* Already include windows.h ? */ +// Must define strict before including windows.h ! +# if defined (ACE_HAS_STRICT) && (ACE_HAS_STRICT != 0) && !defined (STRICT) +# define STRICT 1 +# endif /* ACE_HAS_STRICT */ + +# if !defined (WIN32_LEAN_AND_MEAN) && !defined (ACE_NO_WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# endif /* WIN32_LEAN_AND_MEAN */ + +#endif /* !defined (_INC_WINDOWS) */ + +// Always use WS2 when available +#if !defined(ACE_HAS_WINSOCK2) +# define ACE_HAS_WINSOCK2 1 +#endif /* !defined(ACE_HAS_WINSOCK2) */ + + +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) +# if !defined (_WINSOCK2API_) +// will also include windows.h, if not present +# include /**/ +// WinCE 4 doesn't define the Exxx values without the WSA prefix, so do that +// here. This is all lifted from the #if 0'd out part of winsock2.h. +# if defined (UNDER_CE) +# define EWOULDBLOCK WSAEWOULDBLOCK +# define EINPROGRESS WSAEINPROGRESS +# define EALREADY WSAEALREADY +# define ENOTSOCK WSAENOTSOCK +# define EDESTADDRREQ WSAEDESTADDRREQ +# define EMSGSIZE WSAEMSGSIZE +# define EPROTOTYPE WSAEPROTOTYPE +# define ENOPROTOOPT WSAENOPROTOOPT +# define EPROTONOSUPPORT WSAEPROTONOSUPPORT +# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +# define EOPNOTSUPP WSAEOPNOTSUPP +# define EPFNOSUPPORT WSAEPFNOSUPPORT +# define EAFNOSUPPORT WSAEAFNOSUPPORT +# define EADDRINUSE WSAEADDRINUSE +# define EADDRNOTAVAIL WSAEADDRNOTAVAIL +# define ENETDOWN WSAENETDOWN +# define ENETUNREACH WSAENETUNREACH +# define ENETRESET WSAENETRESET +# define ECONNABORTED WSAECONNABORTED +# define ECONNRESET WSAECONNRESET +# define ENOBUFS WSAENOBUFS +# define EISCONN WSAEISCONN +# define ENOTCONN WSAENOTCONN +# define ESHUTDOWN WSAESHUTDOWN +# define ETOOMANYREFS WSAETOOMANYREFS +# define ETIMEDOUT WSAETIMEDOUT +# define ECONNREFUSED WSAECONNREFUSED +# define ELOOP WSAELOOP +# define ENAMETOOLONG WSAENAMETOOLONG +# define EHOSTDOWN WSAEHOSTDOWN +# define EHOSTUNREACH WSAEHOSTUNREACH +# define ENOTEMPTY WSAENOTEMPTY +# define EPROCLIM WSAEPROCLIM +# define EUSERS WSAEUSERS +# define EDQUOT WSAEDQUOT +# define ESTALE WSAESTALE +# define EREMOTE WSAEREMOTE +# endif /* UNDER_CE */ +# endif /* _WINSOCK2API */ + +# if defined (ACE_HAS_FORE_ATM_WS2) +# include /**/ +# endif /*ACE_HAS_FORE_ATM_WS2 */ + +// CE doesn't have Microsoft Winsock 2 extensions +# if !defined _MSWSOCK_ && !defined (ACE_HAS_WINCE) +# include /**/ +# endif /* _MSWSOCK_ */ + +# if defined (_MSC_VER) +# if defined (ACE_HAS_WINCE) +# pragma comment(lib, "ws2.lib") +# else +# pragma comment(lib, "ws2_32.lib") +# pragma comment(lib, "mswsock.lib") +# if defined (ACE_HAS_IPV6) +# pragma comment(lib, "iphlpapi.lib") +# endif +# endif /* ACE_HAS_WINCE */ +# endif /* _MSC_VER */ + +# define ACE_WSOCK_VERSION 2, 0 +#else +# if !defined (_WINSOCKAPI_) + // will also include windows.h, if not present +# include /**/ +# endif /* _WINSOCKAPI */ + +// PharLap ETS has its own winsock lib, so don't grab the one +// supplied with the OS. +# if defined (_MSC_VER) && !defined (UNDER_CE) && !defined (ACE_HAS_PHARLAP) +# pragma comment(lib, "wsock32.lib") +# endif /* _MSC_VER */ + +// We can't use recvmsg and sendmsg unless WinSock 2 is available +# define ACE_LACKS_RECVMSG +# define ACE_LACKS_SENDMSG + +// Version 1.1 of WinSock +# define ACE_WSOCK_VERSION 1, 1 +#endif /* ACE_HAS_WINSOCK2 */ + +// Platform supports IP multicast on Winsock 2 +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) +# define ACE_HAS_IP_MULTICAST +#endif /* ACE_HAS_WINSOCK2 */ + +#if !defined (ACE_HAS_WINCE) || defined (PPC) /* CE only on some CPUs */ +# define ACE_HAS_INTERLOCKED_EXCHANGEADD +#endif +#define ACE_HAS_WIN32_TRYLOCK + +#if !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP) +# define ACE_HAS_SIGNAL_OBJECT_AND_WAIT + +// If CancelIO is undefined get the updated sp2-sdk from MS +# define ACE_HAS_CANCEL_IO +# define ACE_HAS_WIN32_OVERLAPPED_IO +# define ACE_HAS_WIN32_NAMED_PIPES +#endif /* !defined (ACE_USES_WINCE_SEMA_SIMULATION) && !ACE_HAS_PHARLAP */ + +#if !defined (ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION) +# define ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION EXCEPTION_CONTINUE_SEARCH +#endif /* ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION */ + +// ACE_HAS_QOS is defined in the qos.mpb base project. +// If qos=1 in default.features, then this macro will be defined. +#if defined (ACE_HAS_QOS) && !defined (ACE_HAS_WINSOCK2_GQOS) +# if defined (WINSOCK_VERSION) +# define ACE_HAS_WINSOCK2_GQOS 1 +# endif /* WINSOCK_VERSION */ +#endif /* ACE_HAS_WINSOCK2_GQOS */ + +// These are the defaults and can be overridden by a user's config.h +#if !defined (ACE_DEFAULT_FILE_PERMS) +# define ACE_DEFAULT_FILE_PERMS (FILE_SHARE_READ | FILE_SHARE_WRITE | \ + FILE_SHARE_DELETE) +// This alternate used to be used for pre-NT4 systems; may still be needed +// by knock-offs such as CE and Pharlap. +//# define ACE_DEFAULT_FILE_PERMS (FILE_SHARE_READ | FILE_SHARE_WRITE) +#endif /* !defined (ACE_DEFAULT_FILE_PERMS) */ + +#define ACE_SIZEOF_WCHAR 2 +#define ACE_HAS_MUTEX_TIMEOUTS +#define ACE_LACKS_STRUCT_DIR +#define ACE_LACKS_OPENDIR +#define ACE_LACKS_CLOSEDIR +#define ACE_LACKS_READDIR +#define ACE_LACKS_ALPHASORT +#define ACE_LACKS_MKSTEMP +#define ACE_LACKS_LSTAT +// Looks like Win32 has a non-const swab function +#define ACE_HAS_NONCONST_SWAB + +// If we are using winsock2 then the SO_REUSEADDR feature is broken +// SO_REUSEADDR=1 behaves like SO_REUSEPORT=1. (SO_REUSEPORT is an +// extension to sockets on some platforms) +// We define SO_REUSEPORT here so that ACE_OS::setsockopt() can still +// allow the user to specify that a socketaddr can *always* be reused. +#if defined (ACE_HAS_WINSOCK2) && ACE_HAS_WINSOCK2 != 0 && ! defined(SO_REUSEPORT) +#define SO_REUSEPORT 0x0400 // We just have to pick a value that won't conflict +#endif + +#if defined (ACE_WIN64) +// Data must be aligned on 8-byte boundaries, at a minimum. +# define ACE_MALLOC_ALIGN 8 +// Void pointers are 8 bytes +# define ACE_SIZEOF_VOID_P 8 +#endif /* ACE_WIN64 */ + +#if !defined (ACE_DISABLES_THREAD_LIBRARY_CALLS) +# define ACE_DISABLES_THREAD_LIBRARY_CALLS 0 +#endif /* ACE_DISABLES_THREAD_LIBRARY_CALLS */ + +#if !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP) +# define ACE_HAS_LOG_MSG_NT_EVENT_LOG +#endif /* !ACE_HAS_WINCE && !ACE_HAS_PHARLAP */ + +#if !defined (ACE_HAS_WINCE) +# define ACE_HAS_LLSEEK +#endif /* !ACE_HAS_WINCE */ + +// Needed for obtaining the MAC address +// I dont believe this will work under CE, notice the +// check for ACE_HAS_WINCE. +# if !defined (ACE_HAS_WINCE) +# include +# if defined (_MSC_VER) +# pragma comment(lib, "netapi32.lib") // needed for obtaing MACaddress +# endif +# endif /* !ACE_HAS_WINCE */ + +#if !defined (WINVER) +# define WINVER 0x0400 // pretend it's at least WinNT 4.0 +#endif + +/////////////////////////////////////// +// windows version-specific definitions +// see: http://msdn2.microsoft.com/en-us/library/aa383745.aspx +// +// For TSS information +// see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/thread_local_storage.asp + +#if (WINVER>=0x0600) +// Windows Server 2008 definitions go here +// Windows Vista defintions go here +# if ! defined(ACE_DEFAULT_THREAD_KEYS) +# define ACE_DEFAULT_THREAD_KEYS 1088 +# endif // ! defined(ACE_DEFAULT_THREAD_KEYS) +#elif (WINVER>=0x0502) + // Windows Server 2003 SP1 definitions go here +# if ! defined(ACE_DEFAULT_THREAD_KEYS) +# define ACE_DEFAULT_THREAD_KEYS 1088 +# endif // ! defined(ACE_DEFAULT_THREAD_KEYS) +#elif (WINVER>=0x0501) +// Windows XP definitions go here +# if ! defined(ACE_DEFAULT_THREAD_KEYS) +# define ACE_DEFAULT_THREAD_KEYS 1088 +# endif // ! defined(ACE_DEFAULT_THREAD_KEYS) +#elif (WINVER>=0x0500) +// Windows 2000 definitions go here +# if ! defined(ACE_DEFAULT_THREAD_KEYS) +# define ACE_DEFAULT_THREAD_KEYS 1088 +# endif // ! defined(ACE_DEFAULT_THREAD_KEYS) +#elif (WINVER>=0x0410) +// Windows 98 definitions go here +# if ! defined(ACE_DEFAULT_THREAD_KEYS) +# define ACE_DEFAULT_THREAD_KEYS 80 +# endif // ! defined(ACE_DEFAULT_THREAD_KEYS) +#else +// antique windows +# if ! defined(ACE_DEFAULT_THREAD_KEYS) +# define ACE_DEFAULT_THREAD_KEYS 64 +# endif // ! defined(ACE_DEFAULT_THREAD_KEYS) +#endif + +#if !defined (ACE_DEFAULT_BACKLOG) +# define ACE_DEFAULT_BACKLOG SOMAXCONN +#endif /* ACE_DEFAULT_BACKLOG */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_COMMON_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-dmc.h b/dep/ACE_wrappers/ace/config-win32-dmc.h new file mode 100644 index 000000000..91adf86b8 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-dmc.h @@ -0,0 +1,110 @@ +// -*- C++ -*- +// $Id: config-win32-dmc.h 81992 2008-06-16 19:09:50Z wotte $ + +// The following configuration file contains defines for Digital Mars compilers. + +#ifndef ACE_CONFIG_WIN32_DMC_H +#define ACE_CONFIG_WIN32_DMC_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#ifndef WIN32 +# define WIN32 +#endif /* WIN32 */ + +#undef _M_IX86 +// This turns on ACE_HAS_PENTIUM +#define _M_IX86 500 + +#if defined ACE_LACKS_STRUCT_DIR +# undef ACE_LACKS_STRUCT_DIR +#endif + +// Changed ACE_TEXT to ACE_TEXT in the following line +# define ACE_CC_NAME ACE_TEXT ("Digital Mars") +# define ACE_CC_MAJOR_VERSION (1) +# define ACE_CC_MINOR_VERSION (8) +# define ACE_CC_BETA_VERSION (9) +# ifndef ACE_USING_MCPP_PREPROCESSOR +# define ACE_CC_PREPROCESSOR "DMC.EXE" +# define ACE_CC_PREPROCESSOR_ARGS "-E" +# endif + +// Microsoft's standard cpp library auto_ptr doesn't have reset (). +# define ACE_AUTO_PTR_LACKS_RESET + +#define ACE_ENDTHREADEX(STATUS) ::_endthreadex ((DWORD) STATUS) + +// This section below was extracted from config-win32-msvc +#define ACE_HAS_ITOA +#define ACE_ITOA_EQUIVALENT ::_itoa +#define ACE_STRCASECMP_EQUIVALENT ::_stricmp +#define ACE_STRNCASECMP_EQUIVALENT ::_strnicmp +#define ACE_WCSDUP_EQUIVALENT ::_wcsdup +// This section above was extracted from config-win32-msvc + +# define ACE_EXPORT_NESTED_CLASSES 1 +# define ACE_HAS_CPLUSPLUS_HEADERS 1 +//# define ACE_HAS_EXCEPTIONS 1 +# define ACE_HAS_GNU_CSTRING_H 1 +# define ACE_HAS_NONCONST_SELECT_TIMEVAL 1 +# define ACE_HAS_SIG_ATOMIC_T 1 +# define ACE_HAS_STANDARD_CPP_LIBRARY 0 +# define ACE_HAS_STDCPP_STL_INCLUDES 1 +# define ACE_HAS_STRERROR 1 +# define ACE_HAS_STRING_CLASS 1 +# define ACE_HAS_TEMPLATE_TYPEDEFS 1 +# define ACE_HAS_USER_MODE_MASKS 1 +//# define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 +# define ACE_LACKS_STRPTIME 1 +//# define ACE_LACKS_PRAGMA_ONCE 1 +//# define ACE_NEW_THROWS_EXCEPTIONS 1 +# define ACE_SIZEOF_LONG_DOUBLE 10 +# define ACE_TEMPLATES_REQUIRE_SOURCE 1 +// Changed ACE_TEXT to ACE_TEXT in the following two lines +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_HAS_STRBUF_T +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_USES_OLD_IOSTREAMS +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_SYS_RESOURCE_H +#define ACE_LACKS_SYS_WAIT_H +#define ACE_LACKS_STRINGS_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_SEMAPHORE_H +#define ACE_LACKS_SYS_MMAN_H +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_SOCKET_H +#define ACE_LACKS_NETINET_IN_H +#define ACE_LACKS_SYS_IOCTL_H +#define ACE_LACKS_SYS_SELECT_H +#define ACE_LACKS_NET_IF_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_NETDB_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_REGEX_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_NETINET_TCP_H +#define ACE_LACKS_UNISTD_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_ACE_IOSTREAM +#define ACE_HAS_NONCONST_TEMPNAM + +// Typedefs which we expect DMC to do, but they don't do that +typedef long o_uid_t; +typedef long o_gid_t; + +#include "io.h" +#undef umask; +#undef tell; + +# if !defined (ACE_LD_DECORATOR_STR) && defined (_DEBUG) +# define ACE_LD_DECORATOR_STR ACE_TEXT ("d") +# endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_DMC_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-ghs.h b/dep/ACE_wrappers/ace/config-win32-ghs.h new file mode 100644 index 000000000..77cff1d80 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-ghs.h @@ -0,0 +1,96 @@ +// -*- C++ -*- +// $Id: config-win32-ghs.h 81992 2008-06-16 19:09:50Z wotte $ + +// The following configuration file contains defines for Green Hills compilers. + +#ifndef ACE_CONFIG_WIN32_GHS_H +#define ACE_CONFIG_WIN32_GHS_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#ifndef WIN32 +# define WIN32 +#endif /* WIN32 */ + +#undef _M_IX86 +// This turns on ACE_HAS_PENTIUM +#define _M_IX86 500 +// GHS does not provide DLL support +#define ACE_HAS_DLL 0 +#define TAO_HAS_DLL 0 +#undef _DLL + +//Green Hills Native x86 does not support structural exceptions +# undef ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS +# undef ACE_HAS_WCHAR +# define ACE_CONFIG_INCLUDE_GHS_COMMON +# include "ace/config-ghs-common.h" + +// Changed ACE_TEXT to ACE_TEXT in the following line +# define ACE_CC_NAME ACE_TEXT ("Green Hills C++") +# define ACE_CC_MAJOR_VERSION (1) +# define ACE_CC_MINOR_VERSION (8) +# define ACE_CC_BETA_VERSION (9) +# ifndef ACE_USING_MCPP_PREPROCESSOR +# define ACE_CC_PREPROCESSOR "GCX.EXE" +# define ACE_CC_PREPROCESSOR_ARGS "-E" +# endif + +// GHS uses Microsoft's standard cpp library, which has auto_ptr. +# undef ACE_LACKS_AUTO_PTR +// Microsoft's standard cpp library auto_ptr doesn't have reset (). +# define ACE_AUTO_PTR_LACKS_RESET + +#define ACE_ENDTHREADEX(STATUS) ::_endthreadex ((DWORD) STATUS) + +// This section below was extracted from config-win32-msvc +#define ACE_HAS_ITOA +#define ACE_ITOA_EQUIVALENT ::_itoa +#define ACE_STRCASECMP_EQUIVALENT ::_stricmp +#define ACE_STRNCASECMP_EQUIVALENT ::_strnicmp +#define ACE_WCSDUP_EQUIVALENT ::_wcsdup +// This section above was extracted from config-win32-msvc + +# define ACE_EXPORT_NESTED_CLASSES 1 +# define ACE_HAS_CPLUSPLUS_HEADERS 1 +//# define ACE_HAS_EXCEPTIONS 1 +# define ACE_HAS_GNU_CSTRING_H 1 +# define ACE_HAS_NONCONST_SELECT_TIMEVAL 1 +# define ACE_HAS_SIG_ATOMIC_T 1 +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_HAS_STDCPP_STL_INCLUDES 1 +# define ACE_HAS_STRERROR 1 +# define ACE_HAS_STRING_CLASS 1 +# define ACE_HAS_TEMPLATE_TYPEDEFS 1 +# define ACE_HAS_USER_MODE_MASKS 1 +# define ACE_LACKS_ACE_IOSTREAM 1 +//# define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 +# define ACE_LACKS_STRPTIME 1 +//# define ACE_LACKS_PRAGMA_ONCE 1 +# define ACE_LACKS_STRRECVFD 1 +//# define ACE_NEW_THROWS_EXCEPTIONS 1 +# define ACE_SIZEOF_LONG_DOUBLE 10 +# define ACE_TEMPLATES_REQUIRE_SOURCE 1 +// Changed ACE_TEXT to ACE_TEXT in the following two lines +# define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%I64u") +# define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%I64d") +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +// Set the following to zero to placate SString.h ACE_WString CTOR +# undef ACE_WSTRING_HAS_USHORT_SUPPORT + +// Green Hills Native x86 does not support __int64 keyword +# define ACE_LACKS_LONGLONG_T + +/* need to ensure these are included before */ +# include +# include + +# if !defined (ACE_LD_DECORATOR_STR) && defined (_DEBUG) +# define ACE_LD_DECORATOR_STR ACE_TEXT ("d") +# endif + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_GHS_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-interix.h b/dep/ACE_wrappers/ace/config-win32-interix.h new file mode 100644 index 000000000..d613444fa --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-interix.h @@ -0,0 +1,100 @@ +// -*- C++ -*- +// $Id: config-win32-interix.h 80826 2008-03-04 14:51:23Z wotte $ + +// The following configuration file is designed to work for Interix +// platforms using GNU g++ (Interix == Microsoft's Services for Unix) + +#ifndef ACE_CONFIG_WIN32_INTERIX_H +#define ACE_CONFIG_WIN32_INTERIX_H +#include /**/ "ace/pre.h" +#include + +# define ACE_LACKS_SENDMSG +# define ACE_LACKS_RECVMSG +# define ACE_LACKS_STDINT_H +# define ACE_LACKS_INTTYPES_H +# define ACE_LACKS_PRAGMA_ONCE +# define ACE_LACKS_RWLOCK_T +# define ACE_LACKS_GETPGID // Don't have getpgid(), have setpgid() though... +# define ACE_LACKS_UCONTEXT_H +# define ACE_HAS_REENTRANT_FUNCTIONS +# define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS // Don't have gethostbyaddr_r and friends. +# define ACE_HAS_DIRENT +# define ACE_HAS_STDCPP_STL_INCLUDES +# define ACE_HAS_STANDARD_CPP_LIBRARY 1 +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# define ACE_HAS_NONCONST_SELECT_TIMEVAL +# define ACE_HAS_SIGWAIT +# define ACE_HAS_SIGINFO_T + +#include "ace/config-g++-common.h" + +#define ACE_HAS_NEW_NOTHROW // Need to know 'new's failure semantics. + +#if defined (ACE_HAS_THREADS) +#define ACE_HAS_THREADS +#define ACE_HAS_PTHREADS +#define _THREAD_SAFE +#define ACE_MTSAFE 1 +#define ACE_MT_SAFE 1 +#define ACE_LACKS_PTHREAD_YIELD +#define ACE_HAS_MUTEX_TIMEOUTS +#else + error "You need to enable threads for this Interix port." +#endif /* ACE_HAS_THREADS */ + +// INTERIX has the following, just an issue with porting for the moment +#define ACE_LACKS_ACCESS +// END INTERIX has the following.... + +#define ACE_SIZEOF_LONG_DOUBLE 12 +#define ACE_PAGE_SIZE 4096 + +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_SVR4_SIGNAL_T +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_POSIX_TIME // Supports POSIX timers via struct timespec. +#define ACE_LACKS_TIMESPEC_T // Defines struct timespec but not timespec_t. +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SETSCHED +#define ACE_HAS_SOCKADDR_IN_SIN_LEN +#define ACE_HAS_RTLD_LAZY_V +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_GETRUSAGE +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SEMUN +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_SVR4_GETTIMEOFDAY +#define ACE_HAS_UALARM +#define ACE_HAS_TERMIOS +#define ACE_HAS_SIGWAIT + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// NOTE: In debugging some of the test apps they would all memory fault in using +// ACE_Errno_Guard. Upon inspection of that code it uses TSS to save ERRNO in +// a TSS pointer. Access to that pointer caused the fault. The work around here +// is to tell ACE we have TSS and use emulation. More investigation is needed to +// determine whether Interix TSS is broken or the correct semantics for usage under +// Interix simply need to be ported. +// To get around the issue ACE_HAS_TSS_EMULATION is defined to use TSS emulation +// however while many test programs that use TSS pass the TSS_Test program fails. +#define ACE_HAS_THREAD_SPECIFIC_STORAGE // We need thread specific storage even though... +#define ACE_HAS_TSS_EMULATION // It would appear to be broken in Interix! + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_INTERIX_H */ + +/* +The following tests do not run. +Dynamic_Priority_Test.log ACE_HAS_TIMED_MESSAGE_BLOCKS +Enum_Interfaces_Test.log +IOStream_Test.log ACE_IOSTREAM not supported on this platform +*/ + + diff --git a/dep/ACE_wrappers/ace/config-win32-mingw.h b/dep/ACE_wrappers/ace/config-win32-mingw.h new file mode 100644 index 000000000..f4439865d --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-mingw.h @@ -0,0 +1,100 @@ +// -*- C++ -*- +// $Id: config-win32-mingw.h 81693 2008-05-14 12:35:01Z johnnyw $ + +// +// The following configuration file is designed to work for win32 +// platforms using gcc/g++ with mingw32 (http://www.mingw.org). +// + +#ifndef ACE_CONFIG_WIN32_MINGW_H +#define ACE_CONFIG_WIN32_MINGW_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +# error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#define ACE_CC_NAME ACE_TEXT ("g++") +#define ACE_CC_PREPROCESSOR "cpp" +#define ACE_CC_PREPROCESOR_ARGS "" + +// Why all this is not in config-g++-common.h? +#define ACE_CC_MAJOR_VERSION __GNUC__ +#define ACE_CC_MINOR_VERSION __GNUC_MINOR__ +#define ACE_CC_BETA_VERSION (0) + +#if !defined(__MINGW32__) +# error You do not seem to be using mingw32 +#endif + +#include "ace/config-g++-common.h" + +#include /**/ <_mingw.h> +#include /**/ + +#define ACE_HAS_USER_MODE_MASKS + +#if (__MINGW32_MAJOR_VERSION < 2) +# error You need a newer version (>= 2.0) of mingw32/w32api +#endif + +#if (__MINGW32_MAJOR_VERSION >= 3) +# define ACE_HAS_SSIZE_T +# undef ACE_LACKS_STRUCT_DIR +# undef ACE_LACKS_OPENDIR +# undef ACE_LACKS_CLOSEDIR +# undef ACE_LACKS_READDIR +# undef ACE_LACKS_TELLDIR +# undef ACE_LACKS_SEEKDIR +# undef ACE_LACKS_REWINDDIR +#else +# define ACE_LACKS_DIRENT_H +#endif + +#undef ACE_LACKS_SIGSET + +#define ACE_LACKS_SIGSET_DEFINITIONS +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_NETINET_TCP_H +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_STRPTIME +#define ACE_HAS_STRERROR +#define ACE_LACKS_POLL_H +#define ACE_LACKS_REGEX_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_SEMAPHORE_H +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_SYS_SELECT_H +#define ACE_LACKS_SYS_RESOURCE_H +#define ACE_LACKS_SYS_WAIT_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_SYS_MMAN_H +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_SOCKET_H +#define ACE_LACKS_NETINET_IN_H +#define ACE_LACKS_NETDB_H +#define ACE_LACKS_NET_IF_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_SYS_IOCTL_H +#define ACE_LACKS_PDH_H +#define ACE_LACKS_PDHMSG_H +#define ACE_HAS_NONCONST_WCSDUP +#define ACE_HAS_WINSOCK2_GQOS + +// We trust the user: He must have used -mpentiumpro or -mpentium +// if that is what he wants. +#if defined(pentiumpro) || defined(pentium) +# define ACE_HAS_PENTIUM +#endif + +#define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%I64d") +#define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%I64u") + +#define ACE_ENDTHREADEX(STATUS) ::_endthreadex ((DWORD) (STATUS)) + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_MINGW_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-msvc-7.h b/dep/ACE_wrappers/ace/config-win32-msvc-7.h new file mode 100644 index 000000000..535643a8f --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-msvc-7.h @@ -0,0 +1,125 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file config-win32-msvc-7.h + * + * $Id: config-win32-msvc-7.h 81935 2008-06-12 22:01:53Z jtc $ + * + * @brief Microsoft Visual C++ 7.0 configuration file. + * + * This file is the ACE configuration file for Microsoft Visual C++ version 7. + * + * @note Do not include this file directly, include config-win32.h instead. + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_CONFIG_WIN32_MSVC_7_H +#define ACE_CONFIG_WIN32_MSVC_7_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +// Visual C++ 7.0 (.NET) deprecated the old iostreams +#if !defined (ACE_HAS_STANDARD_CPP_LIBRARY) +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#endif + +#if !defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#endif + +// Win64 SDK compiler claims std::auto_ptr<>::reset not available. +#if defined (_WIN64) || defined (WIN64) +#define ACE_AUTO_PTR_LACKS_RESET +#endif + +#define ACE_HAS_ITOA +#define ACE_HAS_HEADER_ALLOCATED_CLASS_STATIC_CONST_INT_STOREAGE +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR + +#define ACE_ITOA_EQUIVALENT ::_itoa +#define ACE_STRCASECMP_EQUIVALENT ::_stricmp +#define ACE_STRNCASECMP_EQUIVALENT ::_strnicmp +#define ACE_WCSDUP_EQUIVALENT ::_wcsdup + +#if !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_EXCEPTIONS) +#define ACE_HAS_EXCEPTIONS +#endif /* ACE_HAS_WINCE */ + +#define ACE_HAS_STRERROR +#define ACE_LACKS_STRPTIME + +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_STRRECVFD +#define ACE_HAS_CPLUSPLUS_HEADERS + +#define ACE_HAS_TEMPLATE_TYPEDEFS +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Platform provides ACE_TLI function prototypes. +// For Win32, this is not really true, but saves a lot of hassle! +#define ACE_HAS_TLI_PROTOTYPES + +// Platform support linebuffered streaming is broken +#define ACE_LACKS_LINEBUFFERED_STREAMBUF + +#if !defined (ACE_HAS_WINCE) && !(defined (__INTEL_COMPILER) && (__INTEL_COMPILER == 900)) +# define ACE_HAS_INTRINSIC_INTERLOCKED +# define ACE_HAS_INTRINSIC_BYTESWAP +#endif + +#if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && (ACE_HAS_STANDARD_CPP_LIBRARY != 0) + +// Platform has its Standard C++ library in the namespace std +# if !defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + +// ace/iostream.h does not work with the standard cpp library (yet). +# if !defined (ACE_USES_OLD_IOSTREAMS) +# define ACE_LACKS_ACE_IOSTREAM +# endif /* ! ACE_USES_OLD_IOSTREAMS */ + +// Starting with MSVC 7.1, std::new throws std::bad_alloc on out-of-memory. +// Since we don't support MSVC 7.0, don't test for it. +# define ACE_NEW_THROWS_EXCEPTIONS +# define ACE_HAS_NEW_NOTHROW + +#else + +// iostream header lacks ipfx (), isfx (), etc., declarations +# define ACE_LACKS_IOSTREAM_FX + +#endif + +// There are too many instances of this warning to fix it right now. +// Maybe in the future. +// 'this' : used in base member initializer list +#pragma warning(disable:4355) + +// 'class1' : inherits 'class2::member' via dominance +#pragma warning(disable:4250) + +// C++ Exception Specification ignored +#pragma warning(disable:4290) + +// Disable warning of using Microsoft Extension. +#pragma warning(disable:4231) + +// 'function' : unreferenced local function has been removed +# pragma warning(disable:4505) + +// A template can not be exported. Only an instantiation may be exported. +#define ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT + +// At least for ACE_UNIMPLEMENTED_FUNC in class templates, this is needed to +// explicitly instantiate a template that has ACE_UNIMPLEMENTED_FUNC. +# define ACE_NEEDS_FUNC_DEFINITIONS + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_MSVC_7_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-msvc-8.h b/dep/ACE_wrappers/ace/config-win32-msvc-8.h new file mode 100644 index 000000000..73c29e1d4 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-msvc-8.h @@ -0,0 +1,148 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file config-win32-msvc-8.h + * + * $Id: config-win32-msvc-8.h 81935 2008-06-12 22:01:53Z jtc $ + * + * @brief Microsoft Visual C++ 8.0 configuration file. + * + * This file is the ACE configuration file for Microsoft Visual C++ version 8. + * + * @note Do not include this file directly, include config-win32.h instead. + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_CONFIG_WIN32_MSVC_8_H +#define ACE_CONFIG_WIN32_MSVC_8_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#ifndef ACE_WIN32_VC8 +# define ACE_WIN32_VC8 +#endif + +// Visual C++ 8.0 (.NET) deprecated the old iostreams +#if !defined (ACE_HAS_STANDARD_CPP_LIBRARY) +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#endif + +#if !defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#endif + +// Windows' timeval is non-conformant (defined in terms of long instead of +// time_t) and VC8 (on desktop, not CE) changed time_t to a 64-bit value +// even when compiling a 32-bit application. Therefore, ace/Time_Value +// needs to rearrange a few things for this compiler. See Time_Value.h +// for complete details. +#if !defined (ACE_HAS_WINCE) +# define ACE_HAS_TIME_T_LONG_MISMATCH +#endif + +#define ACE_HAS_ITOA +#define ACE_HAS_HEADER_ALLOCATED_CLASS_STATIC_CONST_INT_STOREAGE +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR + +#define ACE_ITOA_EQUIVALENT ::_itoa +#define ACE_STRCASECMP_EQUIVALENT ::_stricmp +#define ACE_STRNCASECMP_EQUIVALENT ::_strnicmp +#define ACE_WCSDUP_EQUIVALENT ::_wcsdup + +#define ACE_HAS_EXCEPTIONS + +// Windows Mobile 5 doesn't do sig_atomic_t, but maybe future versions will. +# if !defined (_WIN32_WCE) || (_WIN32_WCE > 0x501) +# define ACE_HAS_SIG_ATOMIC_T +# endif /* !Win CE 5.0 or less */ + +#define ACE_HAS_STRERROR +#define ACE_LACKS_STRPTIME + +#if !defined (ACE_HAS_WINCE) +# define ACE_HAS_INTRIN_H +# define ACE_HAS_INTRINSIC_INTERLOCKED +#endif + +#if !defined (_WIN32_WCE) || (_WIN32_WCE >= 0x501) +# define ACE_HAS_INTRINSIC_BYTESWAP +#endif + +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_STRRECVFD +#define ACE_HAS_CPLUSPLUS_HEADERS + +#define ACE_HAS_TEMPLATE_TYPEDEFS +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Platform provides ACE_TLI function prototypes. +// For Win32, this is not really true, but saves a lot of hassle! +#define ACE_HAS_TLI_PROTOTYPES + +// Platform support linebuffered streaming is broken +#define ACE_LACKS_LINEBUFFERED_STREAMBUF + +#if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && (ACE_HAS_STANDARD_CPP_LIBRARY != 0) + +// Platform has its Standard C++ library in the namespace std +# if !defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + +// ace/iostream.h does not work with the standard cpp library (yet). +# if !defined (ACE_USES_OLD_IOSTREAMS) +# define ACE_LACKS_ACE_IOSTREAM +# endif /* ! ACE_USES_OLD_IOSTREAMS */ + +// Starting with MSVC 7.1, std::new throws std::bad_alloc on out-of-memory. +#define ACE_NEW_THROWS_EXCEPTIONS +#define ACE_HAS_NEW_NOTHROW + +#else + +// iostream header lacks ipfx (), isfx (), etc., declarations +# define ACE_LACKS_IOSTREAM_FX + +#endif + +// There are too many instances of this warning to fix it right now. +// Maybe in the future. + +// Disable warning of using Microsoft Extension. +# pragma warning(disable:4231) + +// CE (at least thru Windows Mobile 5) doesn't have the new, secure CRT. +#if !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_TR24731_2005_CRT) +# define ACE_HAS_TR24731_2005_CRT +#endif + +//Detect Platform SDK 64-bit (AMD64) compiler using _MSC_FULL_VER +#if (defined (_WIN64) || defined (WIN64)) && _MSC_FULL_VER < 140050000 +# define ACE_AUTO_PTR_LACKS_RESET +# define ACE_MSVC_USES_DOUBLE_UNDERSCORE_STAT64 +# define ACE_HAS_BROKEN_STD_REVERSE_ITERATOR +# define ACE_LACKS_NUMERIC_LIMITS_64_BIT_TYPES +# undef ACE_HAS_TR24731_2005_CRT +# undef ACE_HAS_INTRIN_H +#endif + +// On CE w/o MFC config-WinCE.h needs to declare a placement new. This +// triggers a warning that there's no placement delete, which can be ignored. +#if defined (ACE_HAS_WINCE) && !defined (ACE_HAS_MFC) +# pragma warning(disable:4291) +#endif + +// A template can not be exported. Only an instantiation may be exported. +#define ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT + +// At least for ACE_UNIMPLEMENTED_FUNC in class templates, this is needed to +// explicitly instantiate a template that has ACE_UNIMPLEMENTED_FUNC. +# define ACE_NEEDS_FUNC_DEFINITIONS + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_MSVC_8_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-msvc-9.h b/dep/ACE_wrappers/ace/config-win32-msvc-9.h new file mode 100644 index 000000000..8f148b4c0 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-msvc-9.h @@ -0,0 +1,140 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file config-win32-msvc-9.h + * + * $Id: config-win32-msvc-9.h 81935 2008-06-12 22:01:53Z jtc $ + * + * @brief Microsoft Visual C++ 9.0 configuration file. + * + * This file is the ACE configuration file for Microsoft Visual C++ version 9. + * + * @note Do not include this file directly, include config-win32.h instead. + */ +//============================================================================= + +#ifndef ACE_CONFIG_WIN32_MSVC_9_H +#define ACE_CONFIG_WIN32_MSVC_9_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#ifndef ACE_WIN32_VC9 +# define ACE_WIN32_VC9 +#endif + +// Visual C++ 9.0 (.NET) deprecated the old iostreams +#if !defined (ACE_HAS_STANDARD_CPP_LIBRARY) +#define ACE_HAS_STANDARD_CPP_LIBRARY 1 +#endif + +#if !defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +#endif + +// Windows' timeval is non-conformant (defined in terms of long instead of +// time_t) and VC9 (on desktop, not CE) changed time_t to a 64-bit value +// even when compiling a 32-bit application. Therefore, ace/Time_Value +// needs to rearrange a few things for this compiler. See Time_Value.h +// for complete details. +#if !defined (ACE_HAS_WINCE) +# define ACE_HAS_TIME_T_LONG_MISMATCH +#endif + +#define ACE_HAS_ITOA +#define ACE_HAS_HEADER_ALLOCATED_CLASS_STATIC_CONST_INT_STOREAGE +#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR + +#define ACE_ITOA_EQUIVALENT ::_itoa +#define ACE_STRCASECMP_EQUIVALENT ::_stricmp +#define ACE_STRNCASECMP_EQUIVALENT ::_strnicmp +#define ACE_WCSDUP_EQUIVALENT ::_wcsdup + +#define ACE_HAS_EXCEPTIONS + +// Windows Mobile 5 doesn't do sig_atomic_t, but maybe future versions will. +# if !defined (_WIN32_WCE) || (_WIN32_WCE > 0x501) +# define ACE_HAS_SIG_ATOMIC_T +# endif /* !Win CE 5.0 or less */ + +#define ACE_HAS_STRERROR +#define ACE_LACKS_STRPTIME + +// Evaluate this with a WinCE build; maybe things have improved since VC8. +//#if !defined (ACE_HAS_WINCE) +# define ACE_HAS_INTRIN_H +# define ACE_HAS_INTRINSIC_INTERLOCKED +//#endif + +#if !defined (_WIN32_WCE) || (_WIN32_WCE >= 0x501) +# define ACE_HAS_INTRINSIC_BYTESWAP +#endif + +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_STRRECVFD +#define ACE_HAS_CPLUSPLUS_HEADERS + +#define ACE_HAS_TEMPLATE_TYPEDEFS +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Platform provides ACE_TLI function prototypes. +// For Win32, this is not really true, but saves a lot of hassle! +#define ACE_HAS_TLI_PROTOTYPES + +// Platform support linebuffered streaming is broken +#define ACE_LACKS_LINEBUFFERED_STREAMBUF + +#if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && (ACE_HAS_STANDARD_CPP_LIBRARY != 0) + +// Platform has its Standard C++ library in the namespace std +# if !defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) +# define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + +// ace/iostream.h does not work with the standard cpp library (yet). +# if !defined (ACE_USES_OLD_IOSTREAMS) +# define ACE_LACKS_ACE_IOSTREAM +# endif /* ! ACE_USES_OLD_IOSTREAMS */ + +// Starting with MSVC 7.1, std::new throws std::bad_alloc on out-of-memory. +#define ACE_NEW_THROWS_EXCEPTIONS +#define ACE_HAS_NEW_NOTHROW + +#else + +// iostream header lacks ipfx (), isfx (), etc., declarations +# define ACE_LACKS_IOSTREAM_FX + +#endif + +// There are too many instances of this warning to fix it right now. +// Maybe in the future. + +// Disable warning of using Microsoft Extension. +# pragma warning(disable:4231) + +// 'class1' : inherits 'class2::member' via dominance +#pragma warning(disable:4250) + +// CE (at least thru Windows Mobile 5) doesn't have the new, secure CRT. +#if !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_TR24731_2005_CRT) +# define ACE_HAS_TR24731_2005_CRT +#endif + +// On CE w/o MFC config-WinCE.h needs to declare a placement new. This +// triggers a warning that there's no placement delete, which can be ignored. +#if defined (ACE_HAS_WINCE) && !defined (ACE_HAS_MFC) +# pragma warning(disable:4291) +#endif + +// A template can not be exported. Only an instantiation may be exported. +#define ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT + +// At least for ACE_UNIMPLEMENTED_FUNC in class templates, this is needed to +// explicitly instantiate a template that has ACE_UNIMPLEMENTED_FUNC. +# define ACE_NEEDS_FUNC_DEFINITIONS + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_MSVC_9_H */ diff --git a/dep/ACE_wrappers/ace/config-win32-msvc.h b/dep/ACE_wrappers/ace/config-win32-msvc.h new file mode 100644 index 000000000..a7f8898fc --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32-msvc.h @@ -0,0 +1,169 @@ +//============================================================================= +/** + * @file config-win32-msvc.h + * + * $Id: config-win32-msvc.h 82643 2008-08-19 14:02:12Z johnnyw $ + * + * @brief Microsoft Visual C++ configuration file. + * + * This file is the ACE configuration file for Microsoft Visual C++ versions + * 5.0, 6.0, and 7.0 (.NET) + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_CONFIG_WIN32_MSVC_H +#define ACE_CONFIG_WIN32_MSVC_H +#include /**/ "ace/pre.h" + +#ifndef ACE_CONFIG_WIN32_H +#error Use config-win32.h in config.h instead of this header +#endif /* ACE_CONFIG_WIN32_H */ + +#define ACE_CC_NAME ACE_TEXT ("Visual C++") +#ifndef ACE_USING_MCPP_PREPROCESSOR +# define ACE_CC_PREPROCESSOR "CL.EXE" +# define ACE_CC_PREPROCESSOR_ARGS "-nologo -E" +#endif + +#define ACE_CC_MAJOR_VERSION (_MSC_VER / 100 - 6) +#define ACE_CC_MINOR_VERSION (_MSC_VER % 100) +#define ACE_CC_BETA_VERSION (0) + +#if !defined (ACE_LD_DECORATOR_STR) +# if defined (_DEBUG) +# define ACE_LD_DECORATOR_STR ACE_TEXT ("d") +# endif /* _DEBUG */ +#endif /* ACE_LD_DECORATOR_STR */ + +#if !defined(_NATIVE_WCHAR_T_DEFINED) + #define ACE_LACKS_NATIVE_WCHAR_T +#endif + +// Win Mobile still does thread exits differently than PC Windows. +#if defined (_WIN32_WCE) +# define ACE_ENDTHREADEX(STATUS) ExitThread ((DWORD) STATUS) +#else +# define ACE_ENDTHREADEX(STATUS) ::_endthreadex ((DWORD) STATUS) +#endif /* _WIN32_WCE */ + +#if (_MSC_VER >= 1500) +# include "ace/config-win32-msvc-9.h" +#elif (_MSC_VER >= 1400) +# include "ace/config-win32-msvc-8.h" +#elif (_MSC_VER >= 1310) +# include "ace/config-win32-msvc-7.h" +#else +# error This version of Microsoft Visual C++ is not supported. +#endif + +// MFC changes the behavior of operator new at all MSVC versions from 6 up +// by throwing a static CMemoryException* instead of std::bad_alloc +// (see ace/OS_Memory.h). This MFC exception object needs to be cleaned up +// by calling its Delete() method. +#if defined (ACE_HAS_MFC) && (ACE_HAS_MFC == 1) +# if !defined (ACE_NEW_THROWS_EXCEPTIONS) +# define ACE_NEW_THROWS_EXCEPTIONS +# endif +# if defined (ACE_bad_alloc) +# undef ACE_bad_alloc +# endif +# define ACE_bad_alloc CMemoryException *e +# if defined (ACE_del_bad_alloc) +# undef ACE_del_bad_alloc +# endif +# define ACE_del_bad_alloc e->Delete(); +#endif /* ACE_HAS_MFC && ACE_HAS_MFC==1 */ + +#if defined(ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +// must have _MT defined to include multithreading +// features from win32 headers +# if !defined(_MT) && !defined (ACE_HAS_WINCE) +// *** DO NOT *** defeat this error message by defining _MT yourself. +// On MSVC, this is changed by selecting the Multithreaded +// DLL or Debug Multithreaded DLL in the Project Settings +// under C++ Code Generation. +# error You must link against multi-threaded libraries when using ACE (check your project settings) +# endif /* !_MT && !ACE_HAS_WINCE */ +#endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */ + +#include +// Although ACE does have alloca() on this compiler/platform combination, it is +// disabled by default since it can be dangerous. Uncomment the following line +// if you ACE to use it. +//#define ACE_HAS_ALLOCA 1 + +#define ACE_LACKS_DIRENT_H +#define ACE_LACKS_DLFCN_H +#define ACE_LACKS_INTTYPES_H +#define ACE_LACKS_NETDB_H +#define ACE_LACKS_NET_IF_H +#define ACE_LACKS_NETINET_IN_H +#define ACE_LACKS_STDINT_H +#define ACE_LACKS_STROPTS_H +#define ACE_LACKS_SYS_IOCTL_H +#define ACE_LACKS_SYS_IPC_H +#define ACE_LACKS_SYS_MMAN_H +#define ACE_LACKS_SYS_RESOURCE_H +#define ACE_LACKS_SYS_SELECT_H +#define ACE_LACKS_SYS_SEM_H +#define ACE_LACKS_SYS_SOCKET_H +#define ACE_LACKS_SYS_TIME_H +#define ACE_LACKS_SYS_UIO_H +#define ACE_LACKS_SYS_WAIT_H +#define ACE_LACKS_UCONTEXT_H + +#define ACE_LACKS_SEMAPHORE_H +#define ACE_LACKS_STRINGS_H +#define ACE_LACKS_PWD_H +#define ACE_LACKS_POLL_H +#define ACE_LACKS_SYS_SHM_H +#define ACE_LACKS_SYS_MSG_H +#define ACE_LACKS_NETINET_TCP_H +#define ACE_LACKS_TERMIOS_H +#define ACE_LACKS_REGEX_H + +#define ACE_INT64_FORMAT_SPECIFIER ACE_TEXT ("%I64d") +#define ACE_UINT64_FORMAT_SPECIFIER ACE_TEXT ("%I64u") + +#define ACE_STRTOULL_EQUIVALENT ::_strtoui64 +#define ACE_WCSTOOULL_EQUIVALENT ::_wcstoui64 + +// Turn off warnings for /W4 +// To resume any of these warning: #pragma warning(default: 4xxx) +// which should be placed after these defines + +#if !defined (ALL_WARNINGS) && defined(_MSC_VER) && !defined(ghs) && !defined(__MINGW32__) +# pragma warning(disable: 4127) /* constant expression for TRACE/ASSERT */ +# pragma warning(disable: 4134) /* message map member fxn casts */ +# pragma warning(disable: 4511) /* private copy constructors are good to have */ +# pragma warning(disable: 4512) /* private operator= are good to have */ +# pragma warning(disable: 4514) /* unreferenced inlines are common */ +# pragma warning(disable: 4710) /* private constructors are disallowed */ +# pragma warning(disable: 4705) /* statement has no effect in optimized code */ +# pragma warning(disable: 4791) /* loss of debugging info in retail version */ +# pragma warning(disable: 4275) /* deriving exported class from non-exported */ +# pragma warning(disable: 4251) /* using non-exported as public in exported */ +# pragma warning(disable: 4786) /* identifier was truncated to '255' characters in the browser information */ +# pragma warning(disable: 4097) /* typedef-name used as synonym for class-name */ +# pragma warning(disable: 4800) /* converting int to boolean */ +# if defined (__INTEL_COMPILER) +# pragma warning(disable: 1744) /* field of class type without a DLL interface used in a class with a DLL interface */ +# pragma warning(disable: 1738) +# endif +#endif /* !ALL_WARNINGS && _MSV_VER && !ghs && !__MINGW32__ */ + +// STRICT type checking in WINDOWS.H enhances type safety for Windows +// programs by using distinct types to represent all the different +// HANDLES in Windows. So for example, STRICT prevents you from +// mistakenly passing an HPEN to a routine expecting an HBITMAP. +// Note that we only use this if we +# if defined (ACE_HAS_STRICT) && (ACE_HAS_STRICT != 0) +# if !defined (STRICT) /* may already be defined */ +# define STRICT +# endif /* !STRICT */ +# endif /* ACE_HAS_STRICT */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_MSVC_H */ diff --git a/dep/ACE_wrappers/ace/config-win32.h b/dep/ACE_wrappers/ace/config-win32.h new file mode 100644 index 000000000..76f258eb3 --- /dev/null +++ b/dep/ACE_wrappers/ace/config-win32.h @@ -0,0 +1,93 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file config-win32.h + * + * $Id: config-win32.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @brief Microsoft Windows configuration file. + * + * This file is the ACE configuration file for all of Microsoft Windows + * platforms that ACE runs on. Based on preprocessor definitions, it + * includes other more specific configuration files. + * + * @author Darrell Brunsch + */ +//============================================================================= + +#ifndef ACE_CONFIG_WIN32_H +#define ACE_CONFIG_WIN32_H +#include /**/ "ace/pre.h" + +// by derex ,I include the win32 specific header here, +// this violates the idea of this file a bit ;) +#define ACE_HAS_REACTOR_NOTIFICATION_QUEUE + +// Max amount of connections for non-epoll platforms +#ifndef FD_SETSIZE + #define FD_SETSIZE 4096 +#endif + +//disable some deprecate warnings on windows +#ifndef _CRT_NONSTDC_NO_WARNINGS + #define _CRT_NONSTDC_NO_WARNINGS +#endif + +#ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS +#endif + +#ifndef _CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE +#endif + +#ifndef _WINDOWS + #define _WINDOWS +#endif + +// end custom config stuff + + +// NOTE: Please do not add anything besides #include's here. Put other stuff +// (definitions, etc.) in the included headers + +// We need to ensure that for Borland vcl.h can be included before +// windows.h. So we will not include config-win32-common.h from here, +// but instead let it be included at the appropriate place in +// config-win32-borland.h. +#if !defined (__BORLANDC__) +# include "ace/config-win32-common.h" +#endif /* !__BORLANDC__ */ + +// Include the config-win32-* file specific to the compiler +#if defined (__BORLANDC__) +# include "ace/config-win32-borland.h" +#elif defined (_MSC_VER) +# include "ace/config-win32-msvc.h" +#elif defined (ghs) +# include "ace/config-win32-ghs.h" +#elif defined (__MINGW32__) +# include "ace/config-win32-mingw.h" +#elif defined (__DMC__) +# include "ace/config-win32-dmc.h" +#else +# error Compiler is not supported +#endif + +// gethostbyaddr does not handle IPv6-mapped-IPv4 addresses +#define ACE_HAS_BROKEN_GETHOSTBYADDR_V4MAPPED + +// TODO remove this at some point when we add ACE::init and ACE::fini +// by derex +#ifdef ACE_HAS_NONSTATIC_OBJECT_MANAGER +#undef ACE_HAS_NONSTATIC_OBJECT_MANAGER +#endif //ACE_HAS_NONSTATIC_OBJECT_MANAGER + + +#include /**/ "ace/post.h" +#endif /* ACE_CONFIG_WIN32_H */ + diff --git a/dep/ACE_wrappers/ace/filecache.mpb b/dep/ACE_wrappers/ace/filecache.mpb new file mode 100644 index 000000000..16c714833 --- /dev/null +++ b/dep/ACE_wrappers/ace/filecache.mpb @@ -0,0 +1,8 @@ +// -*- MPC -*- +// $Id: filecache.mpb 80826 2008-03-04 14:51:23Z wotte $ + +feature(ace_filecache) { + Source_Files(ACE_COMPONENTS) { + Filecache.cpp + } +} diff --git a/dep/ACE_wrappers/ace/gethrtime.cpp b/dep/ACE_wrappers/ace/gethrtime.cpp new file mode 100644 index 000000000..69de03153 --- /dev/null +++ b/dep/ACE_wrappers/ace/gethrtime.cpp @@ -0,0 +1,60 @@ +// $Id: gethrtime.cpp 80826 2008-03-04 14:51:23Z wotte $ +// +// Build this file with g++. It can be linked in to a ACE application +// that was compiled with GreenHills. It wouldn't be necessary if I +// knew a way to correctly move values from registers to a 64-bit +// variable in GHS asm code. That's easy with g++ asm. + +#include "ace/config-all.h" + +ACE_RCSID(ace, gethrtime, "$Id: gethrtime.cpp 80826 2008-03-04 14:51:23Z wotte $") + +#if defined (ghs) && (defined (i386) || defined(__i386__)) + +#include "ace/OS_NS_time.h" + +extern "C" +ACE_hrtime_t +ACE_GETHRTIME_NAME (void) +{ +#if defined (ACE_HAS_PENTIUM) + // ACE_TRACE ("ACE_GETHRTIME_NAME"); + +#if defined (ACE_LACKS_LONGLONG_T) + double now; +#else /* ! ACE_LACKS_LONGLONG_T */ + ACE_hrtime_t now; +#endif /* ! ACE_LACKS_LONGLONG_T */ + + // Read the high-res tick counter directly into memory variable + // "now". The A constraint signifies a 64-bit int. +#if defined (__GNUG__) + asm volatile ("rdtsc" : "=A" (now) : : "memory"); +// #elif defined (ghs) +// The following doesn't work. For now, this file must be compile with g++. +// asm ("rdtsc"); +// asm ("movl %edx,-16(%ebp)"); +// asm ("movl %eax,-12(%ebp)"); +#else +# error unsupported compiler +#endif + +#if defined (ACE_LACKS_LONGLONG_T) + // ACE_U_LongLong doesn't have the same layout as now, so construct + // it "properly". + ACE_UINT32 least, most; + ACE_OS::memcpy (&least, &now, sizeof (ACE_UINT32)); + ACE_OS::memcpy (&most, (unsigned char *) &now + sizeof (ACE_UINT32), + sizeof (ACE_UINT32)); + + const ACE_hrtime_t ret (least, most); + return ret; +#else /* ! ACE_LACKS_LONGLONG_T */ + return now; +#endif /* ! ACE_LACKS_LONGLONG_T */ + +#else /* ! ACE_HAS_PENTIUM */ +# error This file can _only_ be compiled with ACE_HAS_PENTIUM. +#endif /* ! ACE_HAS_PENTIUM */ +} +#endif /* ghs */ diff --git a/dep/ACE_wrappers/ace/iosfwd.h b/dep/ACE_wrappers/ace/iosfwd.h new file mode 100644 index 000000000..b07a9f11b --- /dev/null +++ b/dep/ACE_wrappers/ace/iosfwd.h @@ -0,0 +1,99 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file iosfwd.h + * + * $Id: iosfwd.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Irfan Pyarali + * + * This file contains the portability ugliness for the Standard C++ + * Library. As implementations of the "standard" emerge, this file + * will need to be updated. + * + * This files deals with forward declaration for the stream + * classes. Remember that since the new Standard C++ Library code + * for streams uses templates, simple forward declaration will not + * work. + */ +//============================================================================= + + +#ifndef ACE_IOSFWD_H +#define ACE_IOSFWD_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + +#if defined (__APPLE_CC__) +// Should this really be here? dhinton +// FUZZ: disable check_for_streams_include +# include "ace/streams.h" +#endif + +#if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && \ + (ACE_HAS_STANDARD_CPP_LIBRARY != 0) + +# if !defined (ACE_USES_OLD_IOSTREAMS) +# include /**/ +# else + // @note If these forward declarations don't work (e.g. aren't + // portable), we may have to include "ace/streams.h" as a last + // resort. Doing so would defeat the purpose of this header, + // unfortunately. + class ios; + class streambuf; + class istream; + class ostream; + class iostream; + class filebuf; + class ifstream; + class ofstream; + class fstream; +# endif /* ! ACE_USES_OLD_IOSTREAMS */ + +# if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) && \ + (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB != 0) + +# if !defined (ACE_USES_OLD_IOSTREAMS) + // Make these available in the global name space + using std::ios; + using std::streambuf; + using std::istream; + using std::ostream; + using std::iostream; + using std::filebuf; + using std::ifstream; + using std::ofstream; + using std::fstream; +# endif /* ! ACE_USES_OLD_IOSTREAMS */ + +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + +#else /* ! ACE_HAS_STANDARD_CPP_LIBRARY */ + + class ios; + class streambuf; + class istream; + class ostream; + class iostream; + class filebuf; + class ifstream; + class ofstream; + class fstream; + +# endif /* ! ACE_HAS_STANDARD_CPP_LIBRARY */ + +#include /**/ "ace/post.h" + +#endif /* ACE_LACKS_IOSTREAM_TOTALLY */ + +#endif /* ACE_IOSFWD_H */ diff --git a/dep/ACE_wrappers/ace/os_include/arpa/os_inet.h b/dep/ACE_wrappers/ace/os_include/arpa/os_inet.h new file mode 100644 index 000000000..090484d28 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/arpa/os_inet.h @@ -0,0 +1,74 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_inet.h + * + * definitions for internet operations + * + * $Id: os_inet.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_ARPA_OS_INET_H +#define ACE_OS_INCLUDE_ARPA_OS_INET_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/netinet/os_in.h" + +#if !defined (ACE_LACKS_ARPA_INET_H) + extern "C" { +# include /**/ + } +#endif /* !ACE_LACKS_ARPA_INET_H */ + +#if defined (ACE_VXWORKS) +# include /**/ +#endif /* ACE_VXWORKS */ + +/** + * In some environments it is useful to swap the bytes on write, for + * instance: a fast server can be feeding a lot of slow clients that + * happen to have the wrong byte order. + * Because this is a rarely used feature we disable it by default to + * minimize footprint. + * This macro enables the functionality, but we still need a way to + * activate it on a per-connection basis. + */ +// #define ACE_ENABLE_SWAP_ON_WRITE + +/** + * In some environements we never need to swap bytes when reading, for + * instance embebbed systems (such as avionics) or homogenous + * networks. + * Setting this macro disables the capabilities to demarshall streams + * in the wrong byte order. + */ +// #define ACE_DISABLE_SWAP_ON_READ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_INET_ATON_PROTOTYPE) + int inet_aton (const char *, struct in_addr *); +#endif /* ACE_LACKS_INET_ATON_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_ARPA_OS_INET_H */ diff --git a/dep/ACE_wrappers/ace/os_include/net/os_if.h b/dep/ACE_wrappers/ace/os_include/net/os_if.h new file mode 100644 index 000000000..1f59a1772 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/net/os_if.h @@ -0,0 +1,119 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_if.h + * + * sockets local interfaces + * + * $Id: os_if.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_NET_OS_IF_H +#define ACE_OS_INCLUDE_NET_OS_IF_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_NET_IF_H) + // This part if to avoid STL name conflict with the map structure + // in net/if.h. +# if defined (ACE_HAS_STL_MAP_CONFLICT) +# define map _Resource_Allocation_Map_ +# endif /* ACE_HAS_STL_MAP_CONFLICT */ + extern "C" { +# include /**/ + } +# if defined (ACE_HAS_STL_MAP_CONFLICT) +# undef map +# endif /* ACE_HAS_STL_MAP_CONFLICT */ +# if defined (HPUX) && defined (IOR) + /* HP-UX 11.11 defines IOR in /usr/include/pa/inline.h + and we don't want that definition. See IOP_IORC.h. + Thanks to Torsten Kopper for this patch.*/ +# undef IOR +# endif /* HPUX && IOR */ +#endif /* !ACE_LACKS_NET_IF_H */ + +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) +# include /**/ +#endif /* ACE_HAS_WINSOCK2 */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_HAS_BROKEN_IF_HEADER) + struct ifafilt; +#endif /* ACE_HAS_BROKEN_IF_HEADER */ + +#if defined (ACE_LACKS_IFREQ) +struct ifreq { +#define IFNAMSIZ 16 + char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_dstaddr; + struct sockaddr ifru_broadaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + int ifru_phys; + int ifru_media; + caddr_t ifru_data; + int (*ifru_tap)(struct ifnet *, struct ether_header *, struct mbuf *); + } ifr_ifru; +#define ifr_addr ifr_ifru.ifru_addr /* address */ +#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ +#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define ifr_flags ifr_ifru.ifru_flags /* flags */ +#define ifr_metric ifr_ifru.ifru_metric /* metric */ +#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ +#define ifr_phys ifr_ifru.ifru_phys /* physical wire */ +#define ifr_media ifr_ifru.ifru_media /* physical media */ +#define ifr_data ifr_ifru.ifru_data /* for use by interface */ +#define ifr_tap ifr_ifru.ifru_tap /* tap function */ +}; +#endif /* ACE_LACKS_IFREQ */ + +#if defined (ACE_LACKS_IFCONF) +struct ifconf { + int ifc_len; + union { + caddr_t ifcu_buf; + struct ifreq *ifcu_req; + } ifc_ifcu; +#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ +#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ + }; +#endif /* ACE_LACKS_IFCONF */ + +#if !defined (IFF_UP) +# define IFF_UP 0x1 +#endif /* IFF_UP */ + +#if !defined (IFF_LOOPBACK) +# define IFF_LOOPBACK 0x8 +#endif /* IFF_LOOPBACK */ + +#if !defined (IFF_BROADCAST) +# define IFF_BROADCAST 0x2 +#endif /* IFF_BROADCAST */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_NET_OS_IF_H */ diff --git a/dep/ACE_wrappers/ace/os_include/netinet/os_in.h b/dep/ACE_wrappers/ace/os_include/netinet/os_in.h new file mode 100644 index 000000000..4a4346ed4 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/netinet/os_in.h @@ -0,0 +1,185 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_in.h + * + * Internet address family + * + * $Id: os_in.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_NETINET_OS_IN_H +#define ACE_OS_INCLUDE_NETINET_OS_IN_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_inttypes.h" +#include "ace/os_include/sys/os_socket.h" + +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) +# include /**/ +#endif /* ACE_HAS_WINSOCK2 */ + +#if !defined (ACE_LACKS_NETINET_IN_H) +# if defined (ACE_HAS_STL_QUEUE_CONFLICT) +# define queue _Queue_ +# endif /* ACE_HAS_STL_QUEUE_CONFLICT */ + extern "C" { +# include /**/ + } +# if defined (ACE_HAS_STL_QUEUE_CONFLICT) +# undef queue +# endif /* ACE_HAS_STL_QUEUE_CONFLICT */ +#endif /* !ACE_LACKS_NETINET_IN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +# if defined (ACE_HAS_PHARLAP_RT) +# define ACE_IPPROTO_TCP SOL_SOCKET +# else +# define ACE_IPPROTO_TCP IPPROTO_TCP +# endif /* ACE_HAS_PHARLAP_RT */ + +# if !defined (ACE_HAS_IP_MULTICAST) && defined (ACE_LACKS_IP_ADD_MEMBERSHIP) + // Even if ACE_HAS_IP_MULTICAST is not defined, if IP_ADD_MEMBERSHIP + // is defined, assume that the ip_mreq struct is also defined + // (presumably in netinet/in.h). + struct ip_mreq + { + /// IP multicast address of group + struct in_addr imr_multiaddr; + /// Local IP address of interface + struct in_addr imr_interface; + }; +# endif /* ! ACE_HAS_IP_MULTICAST && ACE_LACKS_IP_ADD_MEMBERSHIP */ + +# if defined (ACE_LACKS_IN_ADDR) + struct in_addr + { + u_long s_addr; + }; +# endif /* ACE_LACKS_IN_ADDR */ + +# if defined (ACE_LACKS_SOCKADDR_IN) + struct sockaddr_in + { + short sin_family; // e.g. AF_INET + unsigned short sin_port; // e.g. htons(3490) + struct in_addr sin_addr; // see struct in_addr, below + char sin_zero[8]; // zero this if you want to + }; +# endif /* ACE_LACKS_SOCKADDR_IN */ + +# if defined (ACE_LACKS_SOCKADDR_UN) + struct sockaddr_un { + u_char sun_len; /* sockaddr len including null */ + u_char sun_family; /* AF_UNIX */ + char sun_path[104]; /* path name (gag) */ + }; +#endif /* ACE_LACKS_SOCKADDR_UN */ + +# if defined (ACE_LACKS_IP_MREQ) + struct ip_mreq + { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ + }; +# endif /* ACE_LACKS_IP_MREQ */ + +#if !defined (IPPORT_RESERVED) +# define IPPORT_RESERVED 1024 +#endif /* !IPPORT_RESERVED */ + +#if !defined (IPPORT_USERRESERVED) +# define IPPORT_USERRESERVED 5000 +#endif /* !IPPORT_USERRESERVED */ + +// Define INET loopback address constant if it hasn't been defined +// Dotted Decimal 127.0.0.1 == Hexidecimal 0x7f000001 +#if !defined (INADDR_LOOPBACK) +# define INADDR_LOOPBACK ((ACE_UINT32) 0x7f000001) +#endif /* INADDR_LOOPBACK */ + +// The INADDR_NONE address is generally 255.255.255.255. +#if !defined (INADDR_NONE) +# define INADDR_NONE ((ACE_UINT32) 0xffffffff) +#endif /* INADDR_NONE */ + +// Define INET string length constants if they haven't been defined +// +// for IPv4 dotted-decimal +#if !defined (INET_ADDRSTRLEN) +# define INET_ADDRSTRLEN 16 +#endif /* INET_ADDRSTRLEN */ +// +// for IPv6 hex string +#if !defined (INET6_ADDRSTRLEN) +# define INET6_ADDRSTRLEN 46 +#endif /* INET6_ADDRSTRLEN */ + +# if !defined (IP_DROP_MEMBERSHIP) +# define IP_DROP_MEMBERSHIP 0 +# endif /* IP_DROP_MEMBERSHIP */ + +# if !defined (IP_ADD_MEMBERSHIP) +# define IP_ADD_MEMBERSHIP 0 +# define ACE_LACKS_IP_ADD_MEMBERSHIP +# endif /* IP_ADD_MEMBERSHIP */ + +# if !defined (IP_DEFAULT_MULTICAST_TTL) +# define IP_DEFAULT_MULTICAST_TTL 0 +# endif /* IP_DEFAULT_MULTICAST_TTL */ + +# if !defined (IP_DEFAULT_MULTICAST_LOOP) +# define IP_DEFAULT_MULTICAST_LOOP 0 +# endif /* IP_DEFAULT_MULTICAST_LOOP */ + +# if !defined (IP_MULTICAST_IF) +# define IP_MULTICAST_IF 0 +# endif /* IP_MULTICAST_IF */ + +# if !defined (IP_MULTICAST_TTL) +# define IP_MULTICAST_TTL 1 +# endif /* IP_MULTICAST_TTL */ + +# if !defined (IP_MULTICAST_LOOP) +# define IP_MULTICAST_LOOP 2 +# endif /* IP_MULTICAST_LOOP */ + +# if !defined (IP_MAX_MEMBERSHIPS) +# define IP_MAX_MEMBERSHIPS 0 +# endif /* IP_MAX_MEMBERSHIP */ + +# if !defined (IPPROTO_IP) +# define IPPROTO_IP 0 +# endif /* IPPROTO_IP */ + +# if !defined (IPPROTO_TCP) +# define IPPROTO_TCP 6 +# endif /* IPPROTO_TCP */ + +# if !defined (INADDR_ANY) +# define INADDR_ANY (u_long)0x00000000 +# endif /* INADDR_ANY */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_NETINET_OS_IN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/netinet/os_tcp.h b/dep/ACE_wrappers/ace/os_include/netinet/os_tcp.h new file mode 100644 index 000000000..6e6c66757 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/netinet/os_tcp.h @@ -0,0 +1,46 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_tcp.h + * + * definitions for the Internet Transmission Control Protocol (TCP) + * + * $Id: os_tcp.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_NETINET_OS_TCP_H +#define ACE_OS_INCLUDE_NETINET_OS_TCP_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_NETINET_TCP_H) +# include /**/ +#endif /* !ACE_LACKS_NETIINET_TCP_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +# if !defined (TCP_NODELAY) +# define TCP_NODELAY 0x01 +# endif /* TCP_NODELAY */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_NETINET_OS_TCP_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_aio.h b/dep/ACE_wrappers/ace/os_include/os_aio.h new file mode 100644 index 000000000..4ec9fe9d1 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_aio.h @@ -0,0 +1,47 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_aio.h + * + * asynchronous input and output (REALTIME) + * + * $Id: os_aio.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_AIO_H +#define ACE_OS_INCLUDE_OS_AIO_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Inclusion of the header may make visible symbols defined in +// the headers , , , and . + +#include "ace/os_include/os_signal.h" // for sigevent + +#if !defined (ACE_LACKS_AIO_H) +# include /**/ +#endif /* !ACE_LACKS_AIO_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_AIO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_assert.h b/dep/ACE_wrappers/ace/os_include/os_assert.h new file mode 100644 index 000000000..fdca573fe --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_assert.h @@ -0,0 +1,46 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_assert.h + * + * verify program assertion + * + * $Id: os_assert.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_ASSERT_H +#define ACE_OS_INCLUDE_OS_ASSERT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_ASSERT_H) +# include /**/ +#endif /* !ACE_LACKS_ASSERT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_ASSERT_MACRO) +# define assert(expr) +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_ASSERT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_byteswap.h b/dep/ACE_wrappers/ace/os_include/os_byteswap.h new file mode 100644 index 000000000..b55754ee8 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_byteswap.h @@ -0,0 +1,41 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_byteswap.h + * + * Byteswap methods + * + * $Id: os_byteswap.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_BYTESWAP_H +#define ACE_OS_INCLUDE_OS_BYTESWAP_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_BYTESWAP_H) +# include /**/ +#endif /* !ACE_HAS_INTRIN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_BYTESWAP_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_complex.h b/dep/ACE_wrappers/ace/os_include/os_complex.h new file mode 100644 index 000000000..5e6546f82 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_complex.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_complex.h + * + * complex arithmetic + * + * $Id: os_complex.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_COMPLEX_H +#define ACE_OS_INCLUDE_OS_COMPLEX_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_COMPLEX_H) +# include /**/ +#endif /* !ACE_LACKS_COMPLEX_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_COMPLEX_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_cpio.h b/dep/ACE_wrappers/ace/os_include/os_cpio.h new file mode 100644 index 000000000..2c06e8eb2 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_cpio.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_cpio.h + * + * cpio archive values + * + * $Id: os_cpio.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_CPIO_H +#define ACE_OS_INCLUDE_OS_CPIO_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_CPIO_H) +# include /**/ +#endif /* !ACE_LACKS_CPIO_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_CPIO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_ctype.h b/dep/ACE_wrappers/ace/os_include/os_ctype.h new file mode 100644 index 000000000..faa04af65 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_ctype.h @@ -0,0 +1,45 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_ctype.h + * + * character types + * + * $Id: os_ctype.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_CTYPE_H +#define ACE_OS_INCLUDE_OS_CTYPE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_CTYPE_H) +# include /**/ +#endif /* !ACE_LACKS_CTYPE_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +// @todo move the is* and is* emulation methods in ACE_OS here +// and let ACE_OS just call them. + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_CTYPE_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_dirent.h b/dep/ACE_wrappers/ace/os_include/os_dirent.h new file mode 100644 index 000000000..2db95c65a --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_dirent.h @@ -0,0 +1,108 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_dirent.h + * + * format of directory entries + * + * $Id: os_dirent.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_DIRENT_H +#define ACE_OS_INCLUDE_OS_DIRENT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" +#include "ace/os_include/os_limits.h" + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) +# include "ace/os_include/os_unistd.h" // VxWorks needs this to compile +#endif /* ACE_VXWORKS */ + +#if !defined (ACE_LACKS_DIRENT_H) +# include /**/ +#endif /* !ACE_LACKS_DIRENT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined (MAXNAMLEN) +# define MAXNAMLEN NAME_MAX +#endif /* !MAXNAMLEN */ + +// At least compile on some of the platforms without info yet. +#if !defined (ACE_HAS_DIRENT) +typedef int ACE_DIR; +struct dirent { +}; +#endif /* ACE_HAS_DIRENT */ + +#if defined (ACE_LACKS_STRUCT_DIR) +struct dirent { + unsigned short d_ino; + unsigned short d_off; + unsigned short d_reclen; + // This must be a ACE_TCHAR * and not a one element + // ACE_TCHAR array. It causes problems on wide + // character builds with Visual C++ 6.0. + ACE_TCHAR *d_name; +}; + +#define ACE_DIRENT dirent + +struct ACE_DIR { + /// The name of the directory we are looking into + ACE_TCHAR *directory_name_; + + /// Remember the handle between calls. + HANDLE current_handle_; + + /// The struct for the results + ACE_DIRENT *dirent_; + + /// The struct for intermediate results. + ACE_TEXT_WIN32_FIND_DATA fdata_; + + /// A flag to remember if we started reading already. + int started_reading_; +}; +#elif defined (ACE_WIN32) && (__BORLANDC__) && defined (ACE_USES_WCHAR) +#define ACE_DIRENT wdirent +typedef wDIR ACE_DIR; +#else +#define ACE_DIRENT dirent +typedef DIR ACE_DIR; +#endif /* ACE_LACKS_STRUCT_DIR */ + +#if defined (ACE_LACKS_SCANDIR_PROTOTYPE) +int scandir (const char *, + struct dirent ***, + int (*) (const struct dirent *), + int (*) (const void *, const void *)); +#endif /* ACE_LACKS_SCANDIR_PROTOTYPE */ + +#if defined (ACE_LACKS_ALPHASORT_PROTOTYPE) +int alphasort (const void *, const void *); +#endif /* ACE_LACKS_ALPHASORT_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_DIRENT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_dlfcn.h b/dep/ACE_wrappers/ace/os_include/os_dlfcn.h new file mode 100644 index 000000000..0f74437fb --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_dlfcn.h @@ -0,0 +1,101 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_dlfcn.h + * + * dynamic linking + * + * $Id: os_dlfcn.h 82273 2008-07-09 14:21:45Z jtc $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_DLFCN_H +#define ACE_OS_INCLUDE_OS_DLFCN_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_DLFCN_H) +# include /**/ +#endif /* !ACE_LACKS_DLFCN_H */ + +#if defined (__hpux) +# if defined(__GNUC__) || __cplusplus >= 199707L +# include /**/ +# else +# include /**/ +# endif /* (g++ || HP aC++) vs. HP C++ */ +#endif /* __hpux */ + +#if defined (ACE_VXWORKS) && !defined (__RTP__) +# include /**/ /* for module load */ +# include /**/ /* for module unload */ +# include /**/ /* for findSymbol */ +# include /**/ /* for global symbol table */ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (_M_UNIX) + int _dlclose (void *); + char *_dlerror (void); + void *_dlopen (const char *, int); + void * _dlsym (void *, const char *); +#endif /* _M_UNIX */ + +/* Set the proper handle type for dynamically-loaded libraries. */ +/* Also define a default 'mode' for loading a library - the names and values */ +/* differ between OSes, so if you write code that uses the mode, be careful */ +/* of the platform differences. */ +#if defined (ACE_WIN32) + // Dynamic loading-related types - used for dlopen and family. + typedef HINSTANCE ACE_SHLIB_HANDLE; +# define ACE_SHLIB_INVALID_HANDLE 0 +# define ACE_DEFAULT_SHLIB_MODE 0 +#elif defined (ACE_HAS_SVR4_DYNAMIC_LINKING) + typedef void *ACE_SHLIB_HANDLE; +# define ACE_SHLIB_INVALID_HANDLE 0 + // This is needed to for dynamic_cast to work properly on objects passed to + // libraries. +# define ACE_DEFAULT_SHLIB_MODE RTLD_LAZY | RTLD_GLOBAL +#elif defined (__hpux) + typedef shl_t ACE_SHLIB_HANDLE; +# define ACE_SHLIB_INVALID_HANDLE 0 +# define ACE_DEFAULT_SHLIB_MODE BIND_DEFERRED | DYNAMIC_PATH +#else /* !ACE_WIN32 && !ACE_HAS_SVR4_DYNAMIC_LINKING && !__hpux */ + typedef void *ACE_SHLIB_HANDLE; +# define ACE_SHLIB_INVALID_HANDLE 0 +# define ACE_DEFAULT_SHLIB_MODE RTLD_LAZY +#endif /* ACE_WIN32 */ + +#if !defined (RTLD_LAZY) +#define RTLD_LAZY 1 +#endif /* !RTLD_LAZY */ + +#if !defined (RTLD_NOW) +#define RTLD_NOW 2 +#endif /* !RTLD_NOW */ + +#if !defined (RTLD_GLOBAL) +#define RTLD_GLOBAL 3 +#endif /* !RTLD_GLOBAL */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_DLFCN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_errno.h b/dep/ACE_wrappers/ace/os_include/os_errno.h new file mode 100644 index 000000000..1e297e364 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_errno.h @@ -0,0 +1,153 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_errno.h + * + * system error numbers + * + * $Id: os_errno.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_ERRNO_H +#define ACE_OS_INCLUDE_OS_ERRNO_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_ERRNO_H) +# include /**/ +#endif /* !ACE_LACKS_ERRNO_H */ + +#if defined (ACE_VXWORKS) +// Needed for VxWorks to pickup errnoSet() +#include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_WIN32) + // error code mapping for windows +# define ETIME ERROR_SEM_TIMEOUT +# define EWOULDBLOCK WSAEWOULDBLOCK +# define EINPROGRESS WSAEINPROGRESS +# define EALREADY WSAEALREADY +# define ENOTSOCK WSAENOTSOCK +# define EDESTADDRREQ WSAEDESTADDRREQ +# define EMSGSIZE WSAEMSGSIZE +# define EPROTOTYPE WSAEPROTOTYPE +# define ENOPROTOOPT WSAENOPROTOOPT +# define EPROTONOSUPPORT WSAEPROTONOSUPPORT +# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +# define EOPNOTSUPP WSAEOPNOTSUPP +# define EPFNOSUPPORT WSAEPFNOSUPPORT +# define EAFNOSUPPORT WSAEAFNOSUPPORT +# define EADDRINUSE WSAEADDRINUSE +# define EADDRNOTAVAIL WSAEADDRNOTAVAIL +# define ENETDOWN WSAENETDOWN +# define ENETUNREACH WSAENETUNREACH +# define ENETRESET WSAENETRESET +# define ECONNABORTED WSAECONNABORTED +# define ECONNRESET WSAECONNRESET +# define ENOBUFS WSAENOBUFS +# define EISCONN WSAEISCONN +# define ENOTCONN WSAENOTCONN +# define ESHUTDOWN WSAESHUTDOWN +# define ETOOMANYREFS WSAETOOMANYREFS +# define ETIMEDOUT WSAETIMEDOUT +# define ECONNREFUSED WSAECONNREFUSED +# define ELOOP WSAELOOP +# define EHOSTDOWN WSAEHOSTDOWN +# define EHOSTUNREACH WSAEHOSTUNREACH +# define EPROCLIM WSAEPROCLIM +# define EUSERS WSAEUSERS +# define EDQUOT WSAEDQUOT +# define ESTALE WSAESTALE +# define EREMOTE WSAEREMOTE + // Grrr! ENAMETOOLONG and ENOTEMPTY are already defined by the horrible + // 'standard' library. + // #define ENAMETOOLONG WSAENAMETOOLONG +# define EADDRINUSE WSAEADDRINUSE + + // CE needs this... +# if !defined (EPERM) +# define EPERM ERROR_ACCESS_DENIED +# endif +#endif /* ACE_WIN32 */ + +#if defined (ACE_HAS_H_ERRNO) +void herror (const char *str); +#endif /* ACE_HAS_H_ERRNO */ + +#if !defined (ACE_WIN32) && defined (ACE_LACKS_T_ERRNO) +extern int t_errno; +#endif /* ACE_WIN32 && ACE_LACKS_T_ERRNO */ + +#if !defined (ENOSYS) +# define ENOSYS EFAULT /* Operation not supported or unknown error. */ +#endif /* !ENOSYS */ + +#if !defined (ENOTSUP) +# define ENOTSUP ENOSYS /* Operation not supported. */ +#endif /* !ENOTSUP */ + +#if !defined (ESUCCESS) +# define ESUCCESS 0 +#endif /* !ESUCCESS */ + +#if !defined (EIDRM) +# define EIDRM 0 +#endif /* !EIDRM */ + +#if !defined (ENFILE) +# define ENFILE EMFILE /* No more socket descriptors are available. */ +#endif /* !ENFILE */ + +#if !defined (ECOMM) + // Not the same, but ECONNABORTED is provided on NT. +# define ECOMM ECONNABORTED +#endif /* ECOMM */ + +#if !defined (EDEADLK) +# define EDEADLK 1000 /* Some large number.... */ +#endif /* !EDEADLK */ + +#if !defined (ENXIO) /* Needed in SOCK_Dgram_Mcast */ +# define ENXIO 6 +#endif /* ENXIO */ + +#if !defined (ETIMEDOUT) && defined (ETIME) +# define ETIMEDOUT ETIME +#endif /* ETIMEDOUT */ + +#if !defined (ETIME) && defined (ETIMEDOUT) +# define ETIME ETIMEDOUT +#endif /* ETIMED */ + +#if !defined (EBUSY) +# define EBUSY ETIME +#endif /* EBUSY */ + +#if !defined (ECANCELED) +# define ECANCELED 125 +#endif /* ECANCELED */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_ERRNO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_fcntl.h b/dep/ACE_wrappers/ace/os_include/os_fcntl.h new file mode 100644 index 000000000..048ff62ae --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_fcntl.h @@ -0,0 +1,106 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_fcntl.h + * + * file control options + * + * $Id: os_fcntl.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_FCNTL_H +#define ACE_OS_INCLUDE_OS_FCNTL_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_stat.h" +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_FCNTL_H) +# include /**/ +#endif /* !ACE_LACKS_FCNTL_H */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) +// for creat(), open() +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (__BORLANDC__) +# define _O_CREAT O_CREAT +# define _O_EXCL O_EXCL +# define _O_TRUNC O_TRUNC + // 0x0800 is used for O_APPEND. 0x08 looks free. +# define _O_TEMPORARY 0x08 /* see fcntl.h */ +# define _O_RDWR O_RDWR +# define _O_WRONLY O_WRONLY +# define _O_RDONLY O_RDONLY +# define _O_APPEND O_APPEND +# define _O_BINARY O_BINARY +# define _O_TEXT O_TEXT +#endif /* __BORLANDC__ */ + +#if defined (__DMC__) +# define _O_TEMPORARY 0x08 /* see fcntl.h */ +#endif /* __DMC__ */ + +// defined Win32 specific macros for UNIX platforms +#if !defined (O_BINARY) +# define O_BINARY 0 +#endif /* O_BINARY */ +#if !defined (_O_BINARY) +# define _O_BINARY O_BINARY +#endif /* _O_BINARY */ +#if !defined (O_TEXT) +# define O_TEXT 0 +#endif /* O_TEXT */ +#if !defined (_O_TEXT) +# define _O_TEXT O_TEXT +#endif /* _O_TEXT */ +#if !defined (O_RAW) +# define O_RAW 0 +#endif /* O_RAW */ +#if !defined (_O_RAW) +# define _O_RAW O_RAW +#endif /* _O_RAW */ + +#if defined (ACE_WIN32) +# define O_NDELAY 1 +#endif /* ACE_WIN32 */ + +# if !defined (O_NONBLOCK) +# define O_NONBLOCK 1 +# endif /* O_NONBLOCK */ + +#if defined (ACE_HAS_POSIX_NONBLOCK) +# define ACE_NONBLOCK O_NONBLOCK +#else +# define ACE_NONBLOCK O_NDELAY +#endif /* ACE_HAS_POSIX_NONBLOCK */ + +# if !defined (F_GETFL) +# define F_GETFL 0 +# endif /* F_GETFL */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_FCNTL_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_fenv.h b/dep/ACE_wrappers/ace/os_include/os_fenv.h new file mode 100644 index 000000000..cbf5ab411 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_fenv.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_fenv.h + * + * floating-point environment + * + * $Id: os_fenv.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_FENV_H +#define ACE_OS_INCLUDE_OS_FENV_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_FENV_H) +# include /**/ +#endif /* !ACE_LACKS_FENV_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_FENV_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_float.h b/dep/ACE_wrappers/ace/os_include/os_float.h new file mode 100644 index 000000000..ac4b2f8f9 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_float.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_float.h + * + * floating types + * + * $Id: os_float.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_FLOAT_H +#define ACE_OS_INCLUDE_OS_FLOAT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_FLOAT_H) +# include /**/ +#endif /* !ACE_LACKS_FLOAT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_FLOAT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_fmtmsg.h b/dep/ACE_wrappers/ace/os_include/os_fmtmsg.h new file mode 100644 index 000000000..74251a950 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_fmtmsg.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_fmtmsg.h + * + * message display structures + * + * $Id: os_fmtmsg.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_FMTMSG_H +#define ACE_OS_INCLUDE_OS_FMTMSG_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_FMTMSG_H) +# include /**/ +#endif /* !ACE_LACKS_FMTMSG_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_FMTMSG_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_fnmatch.h b/dep/ACE_wrappers/ace/os_include/os_fnmatch.h new file mode 100644 index 000000000..36726e293 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_fnmatch.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_fnmatch.h + * + * filename-matching types + * + * $Id: os_fnmatch.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_FNMATCH_H +#define ACE_OS_INCLUDE_OS_FNMATCH_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_FNMATCH_H) +# include /**/ +#endif /* !ACE_LACKS_FNMATCH_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_FNMATCH_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_ftw.h b/dep/ACE_wrappers/ace/os_include/os_ftw.h new file mode 100644 index 000000000..225d32513 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_ftw.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_ftw.h + * + * file tree traversal + * + * $Id: os_ftw.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_FTW_H +#define ACE_OS_INCLUDE_OS_FTW_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_stat.h" + +#if !defined (ACE_LACKS_FTW_H) +# include /**/ +#endif /* !ACE_LACKS_FTW_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_FTW_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_glob.h b/dep/ACE_wrappers/ace/os_include/os_glob.h new file mode 100644 index 000000000..0ced3a362 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_glob.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_glob.h + * + * pathname pattern-matching types + * + * $Id: os_glob.h 81692 2008-05-14 12:25:02Z johnnyw $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_GLOB_H +#define ACE_OS_INCLUDE_OS_GLOB_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_GLOB_H) +# include /**/ +#endif /* !ACE_LACKS_GLOB_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_GLOB_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_grp.h b/dep/ACE_wrappers/ace/os_include/os_grp.h new file mode 100644 index 000000000..74bb6e647 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_grp.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_grp.h + * + * group structure + * + * $Id: os_grp.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_GRP_H +#define ACE_OS_INCLUDE_OS_GRP_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" // for gid_t + +#if !defined (ACE_LACKS_GRP_H) +# include /**/ +#endif /* !ACE_LACKS_GRP_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_GRP_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_iconv.h b/dep/ACE_wrappers/ace/os_include/os_iconv.h new file mode 100644 index 000000000..33b061cd7 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_iconv.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_iconv.h + * + * codeset conversion facility + * + * $Id: os_iconv.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_ICONV_H +#define ACE_OS_INCLUDE_OS_ICONV_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_ICONV_H) +# include /**/ +#endif /* !ACE_LACKS_ICONV_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_ICONV_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_intrin.h b/dep/ACE_wrappers/ace/os_include/os_intrin.h new file mode 100644 index 000000000..37b669500 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_intrin.h @@ -0,0 +1,57 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_intrin.h + * + * Intrinsic methods + * + * $Id: os_intrin.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_INTRIN_H +#define ACE_OS_INCLUDE_OS_INTRIN_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_INTRIN_H) +# include /**/ +#endif /* !ACE_HAS_INTRIN_H */ + +#if defined (ACE_HAS_IA64INTRIN_H) +# include /**/ +#endif /* !ACE_HAS_IA64INTRIN_H */ + +#if defined (ACE_HAS_IA32INTRIN_H) +# include /**/ +#endif /* !ACE_HAS_IA32INTRIN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (_MSC_VER) && (_MSC_VER < 1400) && !(defined (__INTEL_COMPILER) && (__INTEL_COMPILER == 900)) +// See http://msdn2.microsoft.com/en-us/library/f24ya7ct(VS.71).aspx +LONG __cdecl _InterlockedIncrement (LONG volatile *Addend); +LONG __cdecl _InterlockedDecrement (LONG volatile *Addend); +LONG __cdecl _InterlockedExchange (LONG volatile *Target, LONG Value); +LONG __cdecl _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); +#endif //_MSC_VER + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_INTRIN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_inttypes.h b/dep/ACE_wrappers/ace/os_include/os_inttypes.h new file mode 100644 index 000000000..2f0c18869 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_inttypes.h @@ -0,0 +1,46 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_inttypes.h + * + * fixed size integer types + * + * $Id: os_inttypes.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_INTTYPES_H +#define ACE_OS_INCLUDE_OS_INTTYPES_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stdint.h" + +#if !defined (ACE_LACKS_INTTYPES_H) +# include /**/ +#endif /* !ACE_LACKS_INTTYPES_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +// @todo if needbe, we can define the macros if they aren't available. + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_INTTYPES_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_iso646.h b/dep/ACE_wrappers/ace/os_include/os_iso646.h new file mode 100644 index 000000000..0c5ab2ae4 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_iso646.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_iso646.h + * + * alternative spellings + * + * $Id: os_iso646.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_ISO646_H +#define ACE_OS_INCLUDE_OS_ISO646_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_ISO646_H) +# include /**/ +#endif /* !ACE_LACKS_ISO646_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_ISO646_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_kstat.h b/dep/ACE_wrappers/ace/os_include/os_kstat.h new file mode 100644 index 000000000..31836cd27 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_kstat.h @@ -0,0 +1,43 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_kstat.h + * + * $Id: os_kstat.h 81692 2008-05-14 12:25:02Z johnnyw $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_KSTAT_H +#define ACE_OS_INCLUDE_OS_KSTAT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_KSTAT) +# define ACE_HAS_KSTAT_H +#endif /* ACE_HAS_KSTAT */ + +#if defined (ACE_HAS_KSTAT_H) +# include +#endif /* ACE_HAS_KSTAT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_KSTAT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_langinfo.h b/dep/ACE_wrappers/ace/os_include/os_langinfo.h new file mode 100644 index 000000000..bfcd67cc2 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_langinfo.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_langinfo.h + * + * language information constants + * + * $Id: os_langinfo.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_LANGINFO_H +#define ACE_OS_INCLUDE_OS_LANGINFO_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_nl_types.h" + +#if !defined (ACE_LACKS_LANGINFO_H) +# include /**/ +#endif /* !ACE_LACKS_LANGINFO_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_LANGINFO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_libgen.h b/dep/ACE_wrappers/ace/os_include/os_libgen.h new file mode 100644 index 000000000..ca24a4d7f --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_libgen.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_libgen.h + * + * definitions for pattern matching functions + * + * $Id: os_libgen.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_LIBGEN_H +#define ACE_OS_INCLUDE_OS_LIBGEN_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_LIBGEN_H) +# include /**/ +#endif /* !ACE_LACKS_LIBGEN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_LIBGEN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_limits.h b/dep/ACE_wrappers/ace/os_include/os_limits.h new file mode 100644 index 000000000..1b1267721 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_limits.h @@ -0,0 +1,143 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_limits.h + * + * implementation-defined constants + * + * $Id: os_limits.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_LIMITS_H +#define ACE_OS_INCLUDE_OS_LIMITS_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_unistd.h" +#include "ace/os_include/os_stdio.h" // for FILENAME_MAX on Windows + +#if !defined (ACE_LACKS_LIMITS_H) +# include /**/ +#endif /* !ACE_LACKS_LIMITS_H */ + +#if !defined (ACE_LACKS_SYS_PARAM_H) +# include /**/ +#endif /* ACE_LACKS_SYS_PARAM_H */ + +// On VxWorks 5.5.1 _POSIX_TIMER_MAX is defined in time.h +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if ! defined (howmany) +# define howmany(x, y) (((x)+((y)-1))/(y)) +#endif /* howmany */ + +#if !defined (NAME_MAX) +# if defined (MAXNAMLEN) +# define NAME_MAX MAXNAMLEN +# elif defined (MAXNAMELEN) +# define NAME_MAX MAXNAMELEN +# elif defined (FILENAME_MAX) +# define NAME_MAX FILENAME_MAX +# elif defined (_MAX_FNAME) +# define NAME_MAX _MAX_FNAME +# else /* _MAX_FNAME */ +# define NAME_MAX 256 +# endif /* MAXNAMLEN */ +#endif /* !NAME_MAX */ + +#if !defined (MAXNAMELEN) +# define MAXNAMELEN NAME_MAX +#endif /* MAXNAMELEN */ + +#if !defined (HOST_NAME_MAX) +# define HOST_NAME_MAX 256 +#endif /* !HOST_NAME_MAX */ + +// Note that we are using PATH_MAX instead of _POSIX_PATH_MAX, since +// _POSIX_PATH_MAX is the *minimun* maximum value for PATH_MAX and is +// defined by POSIX as 256. +#if !defined (PATH_MAX) +# if defined (_MAX_PATH) +# define PATH_MAX _MAX_PATH +# elif defined (MAX_PATH) +# define PATH_MAX MAX_PATH +# else /* !_MAX_PATH */ +# define PATH_MAX 1024 +# endif /* _MAX_PATH */ +#endif /* !PATH_MAX */ + +// Leaving this for backward compatibility, but PATH_MAX should always be +// used directly. +#if !defined (MAXPATHLEN) +# define MAXPATHLEN PATH_MAX +#endif /* !MAXPATHLEN */ + +// This is defined by XOPEN to be a minimum of 16. POSIX.1g +// also defines this value. platform-specific config.h can +// override this if need be. +#if !defined (IOV_MAX) +# define IOV_MAX 16 +#endif /* IOV_MAX */ + +#if !defined (ACE_IOV_MAX) +# define ACE_IOV_MAX IOV_MAX +#endif /* ACE_IOV_MAX */ + +#if defined (ACE_VXWORKS) && ((ACE_VXWORKS >= 0x620) && (ACE_VXWORKS <= 0x660)) && !defined (__RTP__) +# if defined (PIPE_BUF) && (PIPE_BUF == -1) +# undef PIPE_BUF +# endif +#endif /* ACE_VXWORKS */ + +#if !defined (PIPE_BUF) +# define PIPE_BUF 5120 +#endif /* PIPE_BUF */ + +#if defined (ACE_HAS_POSIX_REALTIME_SIGNALS) + // = Giving unique ACE scoped names for some important + // RTSignal-Related constants. Becuase sometimes, different + // platforms use different names for these constants. + + // Number of realtime signals provided in the system. + // _POSIX_RTSIG_MAX is the upper limit on the number of real time + // signals supported in a posix-4 compliant system. +# if defined (_POSIX_RTSIG_MAX) +# define ACE_RTSIG_MAX _POSIX_RTSIG_MAX +# else /* not _POSIX_RTSIG_MAX */ + // POSIX-4 compilant system has to provide atleast 8 RT signals. + // @@ Make sure the platform does *not* define this constant with + // some other name. If yes, use that instead of 8. +# define ACE_RTSIG_MAX 8 +# endif /* _POSIX_RTSIG_MAX */ +#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */ + + // The maximum number of concurrent timers per process. +# if !defined (_POSIX_TIMER_MAX) +# define _POSIX_TIMER_MAX 44 +# endif /* _POSIX_TIMER_MAX */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_LIMITS_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_local.h b/dep/ACE_wrappers/ace/os_include/os_local.h new file mode 100644 index 000000000..b5752f9ab --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_local.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_local.h + * + * category macros + * + * $Id: os_local.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_LOCAL_H +#define ACE_OS_INCLUDE_OS_LOCAL_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" + +#if !defined (ACE_LACKS_LOCAL_H) +# include /**/ +#endif /* !ACE_LACKS_LOCAL_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_LOCAL_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_math.h b/dep/ACE_wrappers/ace/os_include/os_math.h new file mode 100644 index 000000000..6fb53cb15 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_math.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_math.h + * + * mathematical declarations + * + * $Id: os_math.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_MATH_H +#define ACE_OS_INCLUDE_OS_MATH_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// FUZZ: disable check_for_math_include + +#if !defined (ACE_LACKS_MATH_H) +# include /**/ +#endif /* !ACE_LACKS_MATH_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_MATH_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_monetary.h b/dep/ACE_wrappers/ace/os_include/os_monetary.h new file mode 100644 index 000000000..6e956885a --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_monetary.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_monetary.h + * + * monetary types + * + * $Id: os_monetary.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_MONETARY_H +#define ACE_OS_INCLUDE_OS_MONETARY_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_MONETARY_H) +# include /**/ +#endif /* !ACE_LACKS_MONETARY_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_MONETARY_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_mqueue.h b/dep/ACE_wrappers/ace/os_include/os_mqueue.h new file mode 100644 index 000000000..7b3cbb920 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_mqueue.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_mqueue.h + * + * message queues (REALTIME) + * + * $Id: os_mqueue.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_MQUEUE_H +#define ACE_OS_INCLUDE_OS_MQUEUE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_signal.h" + +#if !defined (ACE_LACKS_MQUEUE_H) +# include /**/ +#endif /* !ACE_LACKS_MQUEUE_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_MQUEUE_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_ndbm.h b/dep/ACE_wrappers/ace/os_include/os_ndbm.h new file mode 100644 index 000000000..042dcebf2 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_ndbm.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_ndbm.h + * + * definitions for ndbm database operations + * + * $Id: os_ndbm.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_NDBM_H +#define ACE_OS_INCLUDE_OS_NDBM_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_NDBM_H) +# include /**/ +#endif /* !ACE_LACKS_NDBM_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_NDBM_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_netdb.h b/dep/ACE_wrappers/ace/os_include/os_netdb.h new file mode 100644 index 000000000..286cb2754 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_netdb.h @@ -0,0 +1,108 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_netdb.h + * + * definitions for network database operations + * + * $Id: os_netdb.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_NETDB_H +#define ACE_OS_INCLUDE_OS_NETDB_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/netinet/os_in.h" +#include "ace/os_include/os_limits.h" + +#if !defined (ACE_LACKS_NETDB_H) +# if defined (ACE_HAS_STL_QUEUE_CONFLICT) +# define queue _Queue_ +# endif /* ACE_HAS_STL_QUEUE_CONFLICT */ + extern "C" { +# include /**/ + } +# if defined (ACE_HAS_STL_QUEUE_CONFLICT) +# undef queue +# endif /* ACE_HAS_STL_QUEUE_CONFLICT */ +#endif /* !ACE_LACKS_NETDB_H */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_HOSTENT) +struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +#define h_addr h_addr_list[0] /* address, for backward compatibility */ +}; +#endif /* ACE_LACKS_HOSTENT */ + +#if defined (ACE_LACKS_PROTOENT) +struct protoent { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol # */ +}; +#endif /* ACE_LACKS_PROTOENT */ + +#if defined (ACE_LACKS_SERVENT) +struct servent { + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + int s_port; /* port # */ + char *s_proto; /* protocol to use */ +}; +#endif /* ACE_LACKS_SERVENT */ + +#if defined (ACE_HAS_STRUCT_NETDB_DATA) + typedef char ACE_HOSTENT_DATA[sizeof(struct hostent_data)]; + typedef char ACE_SERVENT_DATA[sizeof(struct servent_data)]; + typedef char ACE_PROTOENT_DATA[sizeof(struct protoent_data)]; +#else +# if !defined ACE_HOSTENT_DATA_SIZE +# define ACE_HOSTENT_DATA_SIZE (4*1024) +# endif /*ACE_HOSTENT_DATA_SIZE */ +# if !defined ACE_SERVENT_DATA_SIZE +# define ACE_SERVENT_DATA_SIZE (4*1024) +# endif /*ACE_SERVENT_DATA_SIZE */ +# if !defined ACE_PROTOENT_DATA_SIZE +# define ACE_PROTOENT_DATA_SIZE (2*1024) +# endif /*ACE_PROTOENT_DATA_SIZE */ + typedef char ACE_HOSTENT_DATA[ACE_HOSTENT_DATA_SIZE]; + typedef char ACE_SERVENT_DATA[ACE_SERVENT_DATA_SIZE]; + typedef char ACE_PROTOENT_DATA[ACE_PROTOENT_DATA_SIZE]; +#endif /* ACE_HAS_STRUCT_NETDB_DATA */ + +# if !defined(MAXHOSTNAMELEN) +# define MAXHOSTNAMELEN HOST_NAME_MAX +# endif /* MAXHOSTNAMELEN */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_NETDB_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_nl_types.h b/dep/ACE_wrappers/ace/os_include/os_nl_types.h new file mode 100644 index 000000000..e043f6ae6 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_nl_types.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_nl_types.h + * + * data types + * + * $Id: os_nl_types.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_NL_TYPES_H +#define ACE_OS_INCLUDE_OS_NL_TYPES_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_NL_TYPES_H) +# include /**/ +#endif /* !ACE_LACKS_nl_types_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_NL_TYPES_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_pdh.h b/dep/ACE_wrappers/ace/os_include/os_pdh.h new file mode 100644 index 000000000..5c60c60d1 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_pdh.h @@ -0,0 +1,45 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_pdh.h + * + * definitions for the windows pdh API + * + * $Id: os_pdh.h 81614 2008-05-05 14:04:25Z johnnyw $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_PDH_H +#define ACE_OS_INCLUDE_OS_PDH_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_PDH_H) && !defined (ACE_LACKS_PDH_H) +# include /**/ +#endif /* ACE_HAS_PDH_H && !ACE_LACKS_PDH_H */ + +#if defined (ACE_HAS_PDH_H) && !defined (ACE_LACKS_PDH_H) +# define ACE_HAS_WIN32_PDH +#endif + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_PDH_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_pdhmsg.h b/dep/ACE_wrappers/ace/os_include/os_pdhmsg.h new file mode 100644 index 000000000..2156236e0 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_pdhmsg.h @@ -0,0 +1,41 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_pdhmsg.h + * + * definitions for the windows pdh API + * + * $Id: os_pdhmsg.h 81693 2008-05-14 12:35:01Z johnnyw $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_PDHMSG_H +#define ACE_OS_INCLUDE_OS_PDHMSG_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_PDHMSG_H) && !defined (ACE_LACKS_PDHMSG_H) +# include /**/ +#endif /* ACE_HAS_PDH_H && !ACE_LACKS_PDH_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_PDHMSG_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_poll.h b/dep/ACE_wrappers/ace/os_include/os_poll.h new file mode 100644 index 000000000..646c1bb85 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_poll.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_poll.h + * + * definitions for the poll() function + * + * $Id: os_poll.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_POLL_H +#define ACE_OS_INCLUDE_OS_POLL_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_POLL_H) +# include /**/ +#endif /* !ACE_LACKS_POLL_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_POLL_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_pthread.h b/dep/ACE_wrappers/ace/os_include/os_pthread.h new file mode 100644 index 000000000..368f4254a --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_pthread.h @@ -0,0 +1,424 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_pthread.h + * + * threads + * + * $Id: os_pthread.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_PTHREAD_H +#define ACE_OS_INCLUDE_OS_PTHREAD_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_PRIOCNTL) + // Need to #include thread.h before #defining THR_BOUND, etc., + // when building without threads on SunOS 5.x. +# if defined (sun) +# include /**/ +# endif /* sun */ + + // Need to #include these before #defining USYNC_PROCESS on SunOS 5.x. +# include /**/ +# include /**/ +#endif /* ACE_HAS_PRIOCNTL */ + +#include "ace/os_include/sys/os_types.h" + +// This needs to go here *first* to avoid problems with AIX. +# if defined (ACE_HAS_PTHREADS) +# define ACE_DONT_INCLUDE_ACE_SIGNAL_H +# include "ace/os_include/os_signal.h" +# undef ACE_DONT_INCLUDE_ACE_SIGNAL_H +# if defined (DIGITAL_UNIX) +# define pthread_self __pthread_self +extern "C" pthread_t pthread_self (void); +# endif /* DIGITAL_UNIX */ +# endif /* ACE_HAS_PTHREADS */ + + +#if !defined (ACE_LACKS_PTHREAD_H) + extern "C" { +# if defined (ACE_TANDEM_T1248_PTHREADS) +# include /**/ +# else +# include /**/ +# endif + } +#endif /* !ACE_LACKS_PTHREAD_H */ + +#if defined (ACE_HAS_PTHREAD_NP_H) +// FreeBSD declares _np (non-portable) pthread extensions in +# include /**/ +#endif + +// @todo: need to reoganize to put includes at the top and the rest of the +// code at the bottom. Also, move the classes out of this file. +#if defined (ACE_HAS_PTHREADS) +# define ACE_SCHED_OTHER SCHED_OTHER +# define ACE_SCHED_FIFO SCHED_FIFO +# define ACE_SCHED_RR SCHED_RR + +// Definitions for THREAD- and PROCESS-LEVEL priorities...some +// implementations define these while others don't. In order to +// further complicate matters, we don't redefine the default (*_DEF) +// values if they've already been defined, which allows individual +// programs to have their own ACE-wide "default". + +// PROCESS-level values +# if (defined (_POSIX_PRIORITY_SCHEDULING) || defined (ACE_TANDEM_T1248_PTHREADS)) \ + && !defined(_UNICOS) && !defined(UNIXWARE_7_1) +# define ACE_PROC_PRI_FIFO_MIN (sched_get_priority_min(SCHED_FIFO)) +# define ACE_PROC_PRI_RR_MIN (sched_get_priority_min(SCHED_RR)) +# if defined (HPUX) + // HP-UX's other is the SCHED_HPUX class, which uses historical + // values that have reverse semantics from POSIX (low value is + // more important priority). To use these in pthreads calls, + // the values need to be converted. The other scheduling classes + // don't need this special treatment. +# define ACE_PROC_PRI_OTHER_MIN \ + (sched_get_priority_min(SCHED_OTHER)) +# else +# define ACE_PROC_PRI_OTHER_MIN (sched_get_priority_min(SCHED_OTHER)) +# endif /* HPUX */ +# else /* UNICOS is missing a sched_get_priority_min() implementation, + SCO too */ +# define ACE_PROC_PRI_FIFO_MIN 0 +# define ACE_PROC_PRI_RR_MIN 0 +# define ACE_PROC_PRI_OTHER_MIN 0 +# endif + +# if defined (_POSIX_PRIORITY_SCHEDULING) && !defined(UNIXWARE_7_1) +# define ACE_PROC_PRI_FIFO_MAX (sched_get_priority_max(SCHED_FIFO)) +# define ACE_PROC_PRI_RR_MAX (sched_get_priority_max(SCHED_RR)) +# if defined (HPUX) +# define ACE_PROC_PRI_OTHER_MAX \ + (sched_get_priority_max(SCHED_OTHER)) +# else +# define ACE_PROC_PRI_OTHER_MAX (sched_get_priority_max(SCHED_OTHER)) +# endif /* HPUX */ +# else /* SCO missing sched_get_priority_max() implementation */ +# define ACE_PROC_PRI_FIFO_MAX 59 +# define ACE_PROC_PRI_RR_MAX 59 +# define ACE_PROC_PRI_OTHER_MAX 59 +# endif + +# if !defined(ACE_PROC_PRI_FIFO_DEF) +# define ACE_PROC_PRI_FIFO_DEF (ACE_PROC_PRI_FIFO_MIN + (ACE_PROC_PRI_FIFO_MAX - ACE_PROC_PRI_FIFO_MIN)/2) +# endif +# if !defined(ACE_PROC_PRI_RR_DEF) +# define ACE_PROC_PRI_RR_DEF (ACE_PROC_PRI_RR_MIN + (ACE_PROC_PRI_RR_MAX - ACE_PROC_PRI_RR_MIN)/2) +# endif +# if !defined(ACE_PROC_PRI_OTHER_DEF) +# define ACE_PROC_PRI_OTHER_DEF (ACE_PROC_PRI_OTHER_MIN + (ACE_PROC_PRI_OTHER_MAX - ACE_PROC_PRI_OTHER_MIN)/2) +# endif + +// THREAD-level values +# if defined(PRI_FIFO_MIN) && defined(PRI_FIFO_MAX) && defined(PRI_RR_MIN) && defined(PRI_RR_MAX) && defined(PRI_OTHER_MIN) && defined(PRI_OTHER_MAX) +# if !defined (ACE_THR_PRI_FIFO_MIN) +# define ACE_THR_PRI_FIFO_MIN (long) PRI_FIFO_MIN +# endif /* !ACE_THR_PRI_FIFO_MIN */ +# if !defined (ACE_THR_PRI_FIFO_MAX) +# define ACE_THR_PRI_FIFO_MAX (long) PRI_FIFO_MAX +# endif /* !ACE_THR_PRI_FIFO_MAX */ +# if !defined (ACE_THR_PRI_RR_MIN) +# define ACE_THR_PRI_RR_MIN (long) PRI_RR_MIN +# endif /* !ACE_THR_PRI_RR_MIN */ +# if !defined (ACE_THR_PRI_RR_MAX) +# define ACE_THR_PRI_RR_MAX (long) PRI_RR_MAX +# endif /* !ACE_THR_PRI_RR_MAX */ +# if !defined (ACE_THR_PRI_OTHER_MIN) +# define ACE_THR_PRI_OTHER_MIN (long) PRI_OTHER_MIN +# endif /* !ACE_THR_PRI_OTHER_MIN */ +# if !defined (ACE_THR_PRI_OTHER_MAX) +# define ACE_THR_PRI_OTHER_MAX (long) PRI_OTHER_MAX +# endif /* !ACE_THR_PRI_OTHER_MAX */ +# elif defined (AIX) + // AIX's priority range is 1 (low) to 127 (high). There aren't + // any preprocessor macros I can find. PRIORITY_MIN is for + // process priorities, as far as I can see, and does not apply + // to thread priority. The 1 to 127 range is from the + // pthread_attr_setschedparam man page (Steve Huston, 18-May-2001). +# if !defined (ACE_THR_PRI_FIFO_MIN) +# define ACE_THR_PRI_FIFO_MIN (long) 1 +# endif /* !ACE_THR_PRI_FIFO_MIN */ +# if !defined (ACE_THR_PRI_FIFO_MAX) +# define ACE_THR_PRI_FIFO_MAX (long) 127 +# endif /* !ACE_THR_PRI_FIFO_MAX */ +# if !defined (ACE_THR_PRI_RR_MIN) +# define ACE_THR_PRI_RR_MIN (long) 1 +# endif /* !ACE_THR_PRI_RR_MIN */ +# if !defined (ACE_THR_PRI_RR_MAX) +# define ACE_THR_PRI_RR_MAX (long) 127 +# endif /* !ACE_THR_PRI_RR_MAX */ +# if !defined (ACE_THR_PRI_OTHER_MIN) +# define ACE_THR_PRI_OTHER_MIN (long) 1 +# endif /* !ACE_THR_PRI_OTHER_MIN */ +# if !defined (ACE_THR_PRI_OTHER_MAX) +# define ACE_THR_PRI_OTHER_MAX (long) 127 +# endif /* !ACE_THR_PRI_OTHER_MAX */ +# elif defined (sun) +# if !defined (ACE_THR_PRI_FIFO_MIN) +# define ACE_THR_PRI_FIFO_MIN (long) 0 +# endif /* !ACE_THR_PRI_FIFO_MIN */ +# if !defined (ACE_THR_PRI_FIFO_MAX) +# define ACE_THR_PRI_FIFO_MAX (long) 59 +# endif /* !ACE_THR_PRI_FIFO_MAX */ +# if !defined (ACE_THR_PRI_RR_MIN) +# define ACE_THR_PRI_RR_MIN (long) 0 +# endif /* !ACE_THR_PRI_RR_MIN */ +# if !defined (ACE_THR_PRI_RR_MAX) +# define ACE_THR_PRI_RR_MAX (long) 59 +# endif /* !ACE_THR_PRI_RR_MAX */ +# if !defined (ACE_THR_PRI_OTHER_MIN) +# define ACE_THR_PRI_OTHER_MIN (long) 0 +# endif /* !ACE_THR_PRI_OTHER_MIN */ +# if !defined (ACE_THR_PRI_OTHER_MAX) +# define ACE_THR_PRI_OTHER_MAX (long) 127 +# endif /* !ACE_THR_PRI_OTHER_MAX */ +# else +# if !defined (ACE_THR_PRI_FIFO_MIN) +# define ACE_THR_PRI_FIFO_MIN (long) ACE_PROC_PRI_FIFO_MIN +# endif /* !ACE_THR_PRI_FIFO_MIN */ +# if !defined (ACE_THR_PRI_FIFO_MAX) +# define ACE_THR_PRI_FIFO_MAX (long) ACE_PROC_PRI_FIFO_MAX +# endif /* !ACE_THR_PRI_FIFO_MAX */ +# if !defined (ACE_THR_PRI_RR_MIN) +# define ACE_THR_PRI_RR_MIN (long) ACE_PROC_PRI_RR_MIN +# endif /* !ACE_THR_PRI_RR_MIN */ +# if !defined (ACE_THR_PRI_RR_MAX) +# define ACE_THR_PRI_RR_MAX (long) ACE_PROC_PRI_RR_MAX +# endif /* !ACE_THR_PRI_RR_MAX */ +# if !defined (ACE_THR_PRI_OTHER_MIN) +# define ACE_THR_PRI_OTHER_MIN (long) ACE_PROC_PRI_OTHER_MIN +# endif /* !ACE_THR_PRI_OTHER_MIN */ +# if !defined (ACE_THR_PRI_OTHER_MAX) +# define ACE_THR_PRI_OTHER_MAX (long) ACE_PROC_PRI_OTHER_MAX +# endif /* !ACE_THR_PRI_OTHER_MAX */ +# endif +# if !defined(ACE_THR_PRI_FIFO_DEF) +# define ACE_THR_PRI_FIFO_DEF ((ACE_THR_PRI_FIFO_MIN + ACE_THR_PRI_FIFO_MAX)/2) +# endif +# if !defined(ACE_THR_PRI_RR_DEF) +# define ACE_THR_PRI_RR_DEF ((ACE_THR_PRI_RR_MIN + ACE_THR_PRI_RR_MAX)/2) +# endif +# if !defined(ACE_THR_PRI_OTHER_DEF) +# define ACE_THR_PRI_OTHER_DEF ((ACE_THR_PRI_OTHER_MIN + ACE_THR_PRI_OTHER_MAX)/2) +# endif + // Typedefs to help compatibility with Windows NT and Pthreads. + typedef pthread_t ACE_hthread_t; + typedef pthread_t ACE_thread_t; + + // native TSS key type + typedef pthread_key_t ACE_OS_thread_key_t; + // TSS key type to be used by application +# if defined (ACE_HAS_TSS_EMULATION) + typedef u_int ACE_thread_key_t; +# else /* ! ACE_HAS_TSS_EMULATION */ + typedef ACE_OS_thread_key_t ACE_thread_key_t; +# endif /* ! ACE_HAS_TSS_EMULATION */ + +# if !defined (ACE_LACKS_COND_T) + typedef pthread_mutex_t ACE_mutex_t; + typedef pthread_cond_t ACE_cond_t; + typedef pthread_condattr_t ACE_condattr_t; + typedef pthread_mutexattr_t ACE_mutexattr_t; +# endif /* ! ACE_LACKS_COND_T */ + typedef pthread_mutex_t ACE_thread_mutex_t; + +# if !defined (PTHREAD_CANCEL_DISABLE) +# define PTHREAD_CANCEL_DISABLE 0 +# endif /* PTHREAD_CANCEL_DISABLE */ + +# if !defined (PTHREAD_CANCEL_ENABLE) +# define PTHREAD_CANCEL_ENABLE 0 +# endif /* PTHREAD_CANCEL_ENABLE */ + +# if !defined (PTHREAD_CANCEL_DEFERRED) +# define PTHREAD_CANCEL_DEFERRED 0 +# endif /* PTHREAD_CANCEL_DEFERRED */ + +# if !defined (PTHREAD_CANCEL_ASYNCHRONOUS) +# define PTHREAD_CANCEL_ASYNCHRONOUS 0 +# endif /* PTHREAD_CANCEL_ASYNCHRONOUS */ + +# define THR_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE +# define THR_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE +# define THR_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED +# define THR_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS + +# if !defined (PTHREAD_CREATE_JOINABLE) +# if defined (PTHREAD_CREATE_UNDETACHED) +# define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED +# else +# define PTHREAD_CREATE_JOINABLE 0 +# endif /* PTHREAD_CREATE_UNDETACHED */ +# endif /* PTHREAD_CREATE_JOINABLE */ + +# if !defined (PTHREAD_CREATE_DETACHED) +# define PTHREAD_CREATE_DETACHED 1 +# endif /* PTHREAD_CREATE_DETACHED */ + +# if !defined (PTHREAD_PROCESS_PRIVATE) && !defined (ACE_HAS_PTHREAD_PROCESS_ENUM) +# if defined (PTHREAD_MUTEXTYPE_FAST) +# define PTHREAD_PROCESS_PRIVATE PTHREAD_MUTEXTYPE_FAST +# else +# define PTHREAD_PROCESS_PRIVATE 0 +# endif /* PTHREAD_MUTEXTYPE_FAST */ +# endif /* PTHREAD_PROCESS_PRIVATE */ + +# if !defined (PTHREAD_PROCESS_SHARED) && !defined (ACE_HAS_PTHREAD_PROCESS_ENUM) +# if defined (PTHREAD_MUTEXTYPE_FAST) +# define PTHREAD_PROCESS_SHARED PTHREAD_MUTEXTYPE_FAST +# else +# define PTHREAD_PROCESS_SHARED 1 +# endif /* PTHREAD_MUTEXTYPE_FAST */ +# endif /* PTHREAD_PROCESS_SHARED */ + +# if !defined (ACE_HAS_STHREADS) +# if !defined (USYNC_THREAD) +# define USYNC_THREAD PTHREAD_PROCESS_PRIVATE +# endif /* ! USYNC_THREAD */ +# if !defined (USYNC_PROCESS) +# define USYNC_PROCESS PTHREAD_PROCESS_SHARED +# endif /* ! USYNC_PROCESS */ +# endif /* ACE_HAS_STHREADS */ + + /* MM-Graz: prevent warnings */ +# if !defined (UNIXWARE_7_1) +# undef THR_BOUND +# undef THR_NEW_LWP +# undef THR_DETACHED +# undef THR_SUSPENDED +# undef THR_DAEMON + +# define THR_BOUND 0x00000001 +# define THR_NEW_LWP 0x00000002 +# define THR_DETACHED 0x00000040 +# define THR_SUSPENDED 0x00000080 +# define THR_DAEMON 0x00000100 +# define THR_SCHED_FIFO 0x00020000 +# define THR_SCHED_RR 0x00040000 +# define THR_SCHED_DEFAULT 0x00080000 +# endif /* UNIXWARE_7_1 */ + +# define THR_JOINABLE 0x00010000 + +# if defined (ACE_HAS_IRIX62_THREADS) +# define THR_SCOPE_SYSTEM 0x00100000 +# else +# define THR_SCOPE_SYSTEM THR_BOUND +# endif /*ACE_HAS_IRIX62_THREADS*/ + +# define THR_SCOPE_PROCESS 0x00200000 +# define THR_INHERIT_SCHED 0x00400000 +# define THR_EXPLICIT_SCHED 0x00800000 +# define THR_SCHED_IO 0x01000000 + +# if !defined (ACE_HAS_STHREADS) +# if !defined (ACE_HAS_POSIX_SEM) && !defined (ACE_USES_FIFO_SEM) + +// This needs to be moved out of here. +#include /**/ "ace/ACE_export.h" +/** + * @class ACE_sema_t + * + * @brief This is used to implement semaphores for platforms that support + * POSIX pthreads, but do *not* support POSIX semaphores, i.e., + * it's a different type than the POSIX . + */ +class ACE_Export ACE_sema_t +{ +public: + /// Serialize access to internal state. + ACE_mutex_t lock_; + + /// Block until there are no waiters. + ACE_cond_t count_nonzero_; + + /// Count of the semaphore. + u_long count_; + + /// Number of threads that have called . + u_long waiters_; +}; +# endif /* !ACE_HAS_POSIX_SEM */ + +# if defined (ACE_LACKS_PTHREAD_YIELD) && defined (ACE_HAS_THR_YIELD) + // If we are on Solaris we can just reuse the existing + // implementations of these synchronization types. +# if !defined (ACE_LACKS_RWLOCK_T) && !defined (ACE_HAS_PTHREADS_UNIX98_EXT) +# include /**/ + typedef rwlock_t ACE_rwlock_t; +# endif /* !ACE_LACKS_RWLOCK_T */ +# include /**/ +# endif /* (ACE_LACKS_PTHREAD_YIELD) && defined (ACE_HAS_THR_YIELD) */ + +# else +# if !defined (ACE_HAS_POSIX_SEM) + typedef sema_t ACE_sema_t; +# endif /* !ACE_HAS_POSIX_SEM */ +# endif /* !ACE_HAS_STHREADS */ + +# if defined (ACE_HAS_PTHREADS_UNIX98_EXT) + typedef pthread_rwlock_t ACE_rwlock_t; +# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */ + +# if defined (__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) + + // glibc 2.2.x or better has pthread_mutex_timedlock() +# ifndef ACE_HAS_MUTEX_TIMEOUTS +# define ACE_HAS_MUTEX_TIMEOUTS +# endif /* ACE_HAS_MUTEX_TIMEOUTS */ + + // Use new pthread_attr_setstack if XPG6 support is enabled. +# if defined (_XOPEN_SOURCE) && (_XOPEN_SOURCE - 0) < 600 +# define ACE_LACKS_PTHREAD_ATTR_SETSTACK +# endif /* (_XOPEN_SOURCE - 0) < 600 */ + +# if !defined (_XOPEN_SOURCE) \ + || (defined (_XOPEN_SOURCE) && (_XOPEN_SOURCE - 0) < 600) + // pthread_mutex_timedlock() prototype is not visible if _XOPEN_SOURCE + // is not >= 600 (i.e. for XPG6). + extern "C" int pthread_mutex_timedlock (pthread_mutex_t *mutex, + const struct timespec * abstime); +# endif /* _XOPEN_SOURCE && _XOPEN_SOURCE < 600 */ + +# endif /* linux && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) */ + +#elif defined (ACE_HAS_STHREADS) +# if !defined (ACE_THR_PRI_FIFO_MIN) +# define ACE_THR_PRI_FIFO_MIN (long) 0 +# endif /* !ACE_THR_PRI_FIFO_MIN */ +# if !defined (ACE_THR_PRI_FIFO_MAX) +# define ACE_THR_PRI_FIFO_MAX (long) 59 +# endif /* !ACE_THR_PRI_FIFO_MAX */ +# if !defined (ACE_THR_PRI_RR_MIN) +# define ACE_THR_PRI_RR_MIN (long) 0 +# endif /* !ACE_THR_PRI_RR_MIN */ +# if !defined (ACE_THR_PRI_RR_MAX) +# define ACE_THR_PRI_RR_MAX (long) 59 +# endif /* !ACE_THR_PRI_RR_MAX */ +# if !defined (ACE_THR_PRI_OTHER_MIN) +# define ACE_THR_PRI_OTHER_MIN (long) 0 +# endif /* !ACE_THR_PRI_OTHER_MIN */ +# if !defined (ACE_THR_PRI_OTHER_MAX) +# define ACE_THR_PRI_OTHER_MAX (long) 127 +# endif /* !ACE_THR_PRI_OTHER_MAX */ +#endif /* ACE_HAS_PTHREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_PTHREAD_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_pwd.h b/dep/ACE_wrappers/ace/os_include/os_pwd.h new file mode 100644 index 000000000..b1bc94af3 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_pwd.h @@ -0,0 +1,58 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_pwd.h + * + * password structure + * + * $Id: os_pwd.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_PWD_H +#define ACE_OS_INCLUDE_OS_PWD_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_PWD_H) +# include /**/ +#endif /* !ACE_LACKS_PWD_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined (ACE_WIN32) +// VAC++ doesn't correctly grok the ::getpwnam_r - the function is redefined +// in pwd.h, and that redefinition is used here +# if defined (_AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 400) + extern int _posix_getpwnam_r(const char *, struct passwd *, char *, + int, struct passwd **); +# endif /* AIX and VAC++ 4 */ +#endif /* !ACE_WIN32 */ + +#if defined (DIGITAL_UNIX) + extern int _Pgetpwnam_r (const char *, struct passwd *, + char *, size_t, struct passwd **); +#endif /* DIGITAL_UNIX */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_PWD_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_regex.h b/dep/ACE_wrappers/ace/os_include/os_regex.h new file mode 100644 index 000000000..1c856da26 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_regex.h @@ -0,0 +1,48 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_regex.h + * + * regular expression matching types + * + * $Id: os_regex.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_REGEX_H +#define ACE_OS_INCLUDE_OS_REGEX_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_REGEX_H) +# include /**/ +#endif /* !ACE_LACKS_REGEX_H */ + +#if defined (ACE_HAS_REGEX) +# include /**/ +#endif /* ACE_HAS_REGEX */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_REGEX_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_sched.h b/dep/ACE_wrappers/ace/os_include/os_sched.h new file mode 100644 index 000000000..a80b454df --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_sched.h @@ -0,0 +1,52 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_sched.h + * + * execution scheduling (REALTIME) + * + * $Id: os_sched.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SCHED_H +#define ACE_OS_INCLUDE_OS_SCHED_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_time.h" + +#if !defined (ACE_LACKS_SCHED_H) +# include /**/ +#endif /* !ACE_LACKS_SCHED_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined (__cpu_set_t_defined) || !defined (ACE_HAS_CPU_SET_T) +# define ACE_CPU_SETSIZE 1024 + typedef struct + { + ACE_UINT32 bit_array_[ACE_CPU_SETSIZE / (8 * sizeof (ACE_UINT32))]; + } cpu_set_t; +#endif /* !ACE_HAS_CPU_SET_T || !__cpu_set_t_defined */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SCHED_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_search.h b/dep/ACE_wrappers/ace/os_include/os_search.h new file mode 100644 index 000000000..605fd365c --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_search.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_search.h + * + * search tables + * + * $Id: os_search.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SEARCH_H +#define ACE_OS_INCLUDE_OS_SEARCH_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SEARCH_H) +# include /**/ +#endif /* !ACE_LACKS_SEARCH_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SEARCH_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_semaphore.h b/dep/ACE_wrappers/ace/os_include/os_semaphore.h new file mode 100644 index 000000000..7fad7dafb --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_semaphore.h @@ -0,0 +1,77 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_semaphore.h + * + * semaphores (REALTIME) + * + * $Id: os_semaphore.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SEMAPHORE_H +#define ACE_OS_INCLUDE_OS_SEMAPHORE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_time.h" + +#if !defined (ACE_LACKS_SEMAPHORE_H) +# include /**/ +#endif /* !ACE_LACKS_SEMAPHORE_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_HAS_POSIX_SEM) +# if !defined (SEM_FAILED) && !defined (ACE_LACKS_NAMED_POSIX_SEM) +# define SEM_FAILED ((sem_t *) -1) +# endif /* !SEM_FAILED */ + + typedef struct + { + /// Pointer to semaphore handle. This is allocated by ACE if we are + /// working with an unnamed POSIX semaphore or by the OS if we are + /// working with a named POSIX semaphore. + sem_t *sema_; + + /// Name of the semaphore (if this is non-NULL then this is a named + /// POSIX semaphore, else its an unnamed POSIX semaphore). + char *name_; + +# if defined (ACE_LACKS_NAMED_POSIX_SEM) + /// this->sema_ doesn't always get created dynamically if a platform + /// doesn't support named posix semaphores. We use this flag to + /// remember if we need to delete or not. + bool new_sema_; +# endif /* ACE_LACKS_NAMED_POSIX_SEM */ + +# if !defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION) + /// Serialize access to internal state. + ACE_mutex_t lock_; + + /// Block until there are no waiters. + ACE_cond_t count_nonzero_; +# endif /* !ACE_HAS_POSIX_SEM_TIMEOUT && !ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */ + } ACE_sema_t; +#endif /* ACE_HAS_POSIX_SEM */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SEMAPHORE_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_setjmp.h b/dep/ACE_wrappers/ace/os_include/os_setjmp.h new file mode 100644 index 000000000..2ab4a18a9 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_setjmp.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_setjmp.h + * + * stack environment declarations + * + * $Id: os_setjmp.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SETJMP_H +#define ACE_OS_INCLUDE_OS_SETJMP_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_SETJMP_H) +# include /**/ +#endif /* !ACE_LACKS_SETJMP_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SETJMP_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_signal.h b/dep/ACE_wrappers/ace/os_include/os_signal.h new file mode 100644 index 000000000..fdfd21e99 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_signal.h @@ -0,0 +1,253 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_signal.h + * + * signals + * + * $Id: os_signal.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SIGNAL_H +#define ACE_OS_INCLUDE_OS_SIGNAL_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SIGNAL_H) + extern "C" { +# include /**/ + } +#endif /* !ACE_LACKS_SIGNAL_H */ + +// This must come after signal.h is #included. +#if defined (SCO) +# define SIGIO SIGPOLL +# include /**/ +#endif /* SCO */ + +#if defined (ACE_HAS_SIGINFO_T) +# if !defined (ACE_LACKS_SIGINFO_H) +# if defined (__QNX__) || defined (__OpenBSD__) || defined (__INTERIX) +# include /**/ +# else /* __QNX__ || __OpenBSD__ */ +# include /**/ +# endif /* __QNX__ || __OpenBSD__ */ +# endif /* ACE_LACKS_SIGINFO_H */ +#endif /* ACE_HAS_SIGINFO_T */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) && !defined (__RTP__) +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_SIGSET) + typedef u_int sigset_t; +#endif /* ACE_LACKS_SIGSET */ + +#if defined (ACE_HAS_SIG_MACROS) +# undef sigemptyset +# undef sigfillset +# undef sigaddset +# undef sigdelset +# undef sigismember +#endif /* ACE_HAS_SIG_MACROS */ + +// This must come after signal.h is #included. It's to counteract +// the sigemptyset and sigfillset #defines, which only happen +// when __OPTIMIZE__ is #defined (really!) on Linux. +#if defined (linux) && defined (__OPTIMIZE__) +# undef sigemptyset +# undef sigfillset +#endif /* linux && __OPTIMIZE__ */ + +#if !defined (ACE_HAS_SIG_ATOMIC_T) + typedef int sig_atomic_t; +#endif /* !ACE_HAS_SIG_ATOMIC_T */ + +# if !defined (SA_SIGINFO) +# define SA_SIGINFO 0 +# endif /* SA_SIGINFO */ + +# if !defined (SA_RESTART) +# define SA_RESTART 0 +# endif /* SA_RESTART */ + +#if !defined (SIGHUP) +# define SIGHUP 0 +#endif /* SIGHUP */ + +#if !defined (SIGINT) +# define SIGINT 0 +#endif /* SIGINT */ + +#if !defined (SIGSEGV) +# define SIGSEGV 0 +#endif /* SIGSEGV */ + +#if !defined (SIGIO) +# define SIGIO 0 +#endif /* SIGSEGV */ + +#if !defined (SIGUSR1) +# define SIGUSR1 0 +#endif /* SIGUSR1 */ + +#if !defined (SIGUSR2) +# define SIGUSR2 0 +#endif /* SIGUSR2 */ + +#if !defined (SIGCHLD) +# define SIGCHLD 0 +#endif /* SIGCHLD */ + +#if !defined (SIGCLD) +# define SIGCLD SIGCHLD +#endif /* SIGCLD */ + +#if !defined (SIGQUIT) +# define SIGQUIT 0 +#endif /* SIGQUIT */ + +#if !defined (SIGPIPE) +# define SIGPIPE 0 +#endif /* SIGPIPE */ + +#if !defined (SIGALRM) +# define SIGALRM 0 +#endif /* SIGALRM */ + +#if !defined (SIG_DFL) +# define SIG_DFL ((__sighandler_t) 0) +#endif /* SIG_DFL */ + +#if !defined (SIG_IGN) +# define SIG_IGN ((__sighandler_t) 1) /* ignore signal */ +#endif /* SIG_IGN */ + +#if !defined (SIG_ERR) +# define SIG_ERR ((__sighandler_t) -1) /* error return from signal */ +#endif /* SIG_ERR */ + +// These are used by the and +// methods. They must be unique and cannot +// conflict with the value of . We make the numbers +// negative here so they won't conflict with other values like SIGIO, +// etc. +# define ACE_SIGIO -1 +# define ACE_SIGURG -2 +# define ACE_CLOEXEC -3 + +#if defined (ACE_VXWORKS) +# define ACE_NSIG (_NSIGS + 1) +#elif defined (__Lynx__) || defined (ACE_HAS_RTEMS) +# define ACE_NSIG (NSIG + 1) +#else + // All other platforms set NSIG to one greater than the + // highest-numbered signal. +# define ACE_NSIG NSIG +#endif /* __Lynx__ */ + +#if defined (ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES) + // Prototypes for both signal() and struct sigaction are consistent.. + typedef void (*ACE_SignalHandler)(int); + typedef void (*ACE_SignalHandlerV)(int); +#elif defined (ACE_HAS_LYNXOS_SIGNALS) || defined (ACE_HAS_TANDEM_SIGNALS) + typedef void (*ACE_SignalHandler)(...); + typedef void (*ACE_SignalHandlerV)(...); +#elif defined (ACE_HAS_SVR4_SIGNAL_T) + // SVR4 Signals are inconsistent (e.g., see struct sigaction).. + typedef void (*ACE_SignalHandler)(int); + typedef void (*ACE_SignalHandlerV)(void); +#elif defined (ACE_WIN32) + typedef void (__cdecl *ACE_SignalHandler)(int); + typedef void (__cdecl *ACE_SignalHandlerV)(int); +#elif defined (ACE_HAS_UNIXWARE_SVR4_SIGNAL_T) + typedef void (*ACE_SignalHandler)(int); + typedef void (*ACE_SignalHandlerV)(...); +#elif defined (INTEGRITY) + typedef void (*ACE_SignalHandler)(); + typedef void (*ACE_SignalHandlerV)(int); +#elif defined (ACE_HAS_RTEMS) + typedef void (*ACE_SignalHandler)(); + typedef void (*ACE_SignalHandlerV)(); +#else /* This is necessary for some older broken version of cfront */ +# if defined (SIG_PF) +# define ACE_SignalHandler SIG_PF +# else + typedef void (*ACE_SignalHandler)(int); +# endif /* SIG_PF */ + typedef void (*ACE_SignalHandlerV)(...); +#endif /* ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES */ + +#if defined (ACE_LACKS_SIGACTION) + struct sigaction + { + int sa_flags; + ACE_SignalHandlerV sa_handler; + sigset_t sa_mask; + }; +#endif /* ACE_LACKS_SIGACTION */ + +// Defining POSIX4 real-time signal range. +#if defined(ACE_HAS_POSIX_REALTIME_SIGNALS) +# define ACE_SIGRTMIN SIGRTMIN +# define ACE_SIGRTMAX SIGRTMAX +#else /* !ACE_HAS_POSIX_REALTIME_SIGNALS */ +# ifndef ACE_SIGRTMIN +# define ACE_SIGRTMIN 0 +# endif /* ACE_SIGRTMIN */ +# ifndef ACE_SIGRTMAX +# define ACE_SIGRTMAX 0 +# endif /* ACE_SIGRTMAX */ +#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */ + +#if defined (DIGITAL_UNIX) + // sigwait is yet another macro on Digital UNIX 4.0, just causing + // trouble when introducing member functions with the same name. + // Thanks to Thilo Kielmann" for + // this fix. +# if defined (__DECCXX_VER) +# undef sigwait + // cxx on Digital Unix 4.0 needs this declaration. With it, + // <::_Psigwait> works with cxx -pthread. g++ does _not_ need + // it. + int _Psigwait __((const sigset_t *set, int *sig)); +# endif /* __DECCXX_VER */ +#elif !defined (ACE_HAS_SIGWAIT) +# if defined(ACE_HAS_RTEMS) + int sigwait (const sigset_t *set, int *sig); +# else + int sigwait (sigset_t *set); +# endif /* ACE_HAS_RTEMS */ +#endif /* ! DIGITAL_UNIX && ! ACE_HAS_SIGWAIT */ + +#if !defined (ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE) + int pthread_sigmask(int, const sigset_t *, sigset_t *); +#endif /*!ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include "ace/os_include/os_ucontext.h" + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SIGNAL_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_spawn.h b/dep/ACE_wrappers/ace/os_include/os_spawn.h new file mode 100644 index 000000000..0f825640f --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_spawn.h @@ -0,0 +1,46 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_spawn.h + * + * spawn (ADVANCED REALTIME) + * + * $Id: os_spawn.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SPAWN_H +#define ACE_OS_INCLUDE_OS_SPAWN_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_signal.h" +#include "ace/os_include/sys/os_types.h" +#include "ace/os_include/os_sched.h" + +#if !defined (ACE_LACKS_SPAWN_H) +# include /**/ +#endif /* !ACE_LACKS_SPAWN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SPAWN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stdarg.h b/dep/ACE_wrappers/ace/os_include/os_stdarg.h new file mode 100644 index 000000000..0e9d234b5 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stdarg.h @@ -0,0 +1,50 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stdarg.h + * + * handle variable argument list + * + * $Id: os_stdarg.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STDARG_H +#define ACE_OS_INCLUDE_OS_STDARG_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_STDARG_H) +# include /**/ +#endif /* !ACE_LACKS_STDARG_H */ + +#if !defined (va_copy) +#if defined (__va_copy) +#define va_copy(d, s) __va_copy((d),(s)) +#else +#define va_copy(d, s) memcpy((void *)&(d),(void *)&(s),sizeof(va_list)) +#endif +#endif + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STDARG_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stdbool.h b/dep/ACE_wrappers/ace/os_include/os_stdbool.h new file mode 100644 index 000000000..ddb3f8e0d --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stdbool.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stdbool.h + * + * boolean type and values + * + * $Id: os_stdbool.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STDBOOL_H +#define ACE_OS_INCLUDE_OS_STDBOOL_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_STDBOOL_H) +# include /**/ +#endif /* !ACE_LACKS_STDBOOL_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STDBOOL_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stddef.h b/dep/ACE_wrappers/ace/os_include/os_stddef.h new file mode 100644 index 000000000..b842ffe80 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stddef.h @@ -0,0 +1,97 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stddef.h + * + * standard type definitions + * + * $Id: os_stddef.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +// From http://www.UNIX-systems.org/single_unix_specification/ + +#ifndef ACE_OS_INCLUDE_OS_STDDEF_H +#define ACE_OS_INCLUDE_OS_STDDEF_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_STDDEF_H) +# include /**/ +#endif /* !ACE_LACKS_STDDEF_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +//FUZZ: disable check_for_NULL +// NULL pointer constant +#if defined (ACE_LACKS_NULL) +# undef NULL +# if defined(__cplusplus) +# define NULL 0 +# else +# define NULL ((void *)0) +# endif +#endif /* ACE_LACKS_NULL */ +//FUZZ: enable check_for_NULL + +/* + Integer constant expression of type size_t, the value of which is the offset + in bytes to the structure member (member-designator), from the beginning of + its structure (type). +*/ +#if defined (ACE_LACKS_OFFSETOF) +# undef offsetof +# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif /* ACE_LACKS_OFFSETOF */ + +// Signed integer type of the result of subtracting two pointers. +#if defined (ACE_LACKS_PTRDIFF_T) +# if !defined (ACE_PTRDIFF_T_TYPE) +# define ACE_PTRDIFF_T_TYPE unsigned long +# endif /* !ACE_PTRDIFF_T_TYPE */ + typedef ACE_PTRDIFF_T_TYPE ptrdiff_t; +#endif /* ACE_LACKS_PTRDIFF_T */ + +/* + Integer type whose range of values can represent distinct wide-character + codes for all members of the largest character set specified among the + locales supported by the compilation environment: the null character has + the code value 0 and each member of the portable character set has a code + value equal to its value when used as the lone character in an integer + character constant. +*/ +#if defined (ACE_LACKS_WCHAR_T) +# if !defined (ACE_WCHAR_T_TYPE) +# define ACE_WCHAR_T_TYPE long; +# endif /* !ACE_WCHAR_T_TYPE */ + typedef ACE_WCHAR_T_TYPE wchar_t; +#endif /* ACE_LACKS_WCHAR_T */ + +// Unsigned integer type of the result of the sizeof operator. +#if defined (ACE_LACKS_SIZE_T) +# if !defined (ACE_SIZE_T_TYPE) +# define ACE_SIZE_T_TYPE unsigned int; +# endif /* !ACE_SIZE_T_TYPE */ + typedef ACE_SIZE_T_TYPE size_t; +#endif /* ACE_LACKS_SIZE_T */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STDDEF_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stdint.h b/dep/ACE_wrappers/ace/os_include/os_stdint.h new file mode 100644 index 000000000..ac6fec664 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stdint.h @@ -0,0 +1,141 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stdint.h + * + * integer types + * + * $Id: os_stdint.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STDINT_H +#define ACE_OS_INCLUDE_OS_STDINT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_STDINT_H) +# include /**/ +#endif /* !ACE_LACKS_STDINT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +// BSD style types +#if defined (ACE_LACKS_SYS_TYPES_H) \ + || (defined (__GLIBC__) && !defined (_BSD_SOURCE)) + typedef unsigned char u_char; + typedef unsigned short u_short; + typedef unsigned int u_int; + typedef unsigned long u_long; + + typedef unsigned char uchar_t; + typedef unsigned short ushort_t; + typedef unsigned int uint_t; + typedef unsigned long ulong_t; +#endif /* ACE_LACKS_SYS_TYPES_H */ + +/* Define required types if missing */ + +#if defined (ACE_LACKS_INT8_T) +# if !defined (ACE_INT8_T_TYPE) +# define ACE_INT8_T_TYPE char +# endif /* !ACE_INT8_T_TYPE */ + typedef ACE_INT8_T_TYPE int8_t; +#endif /* ACE_LACKS_INT8_T */ + +#if defined (ACE_LACKS_UINT8_T) +# if !defined (ACE_UINT8_T_TYPE) +# define ACE_UINT8_T_TYPE unsigned char +# endif /* !ACE_UINT8_T_TYPE */ + typedef ACE_UINT8_T_TYPE int8_t; +#endif /* ACE_LACKS_UINT8_T */ + +#if defined (ACE_LACKS_INT16_T) +# if !defined (ACE_INT16_T_TYPE) +# define ACE_INT16_T_TYPE short +# endif /* !ACE_INT16_T_TYPE */ + typedef ACE_INT16_T_TYPE int16_t; +#endif /* ACE_LACKS_INT16_T */ + +#if defined (ACE_LACKS_UINT16_T) +# if !defined (ACE_UINT16_T_TYPE) +# define ACE_UINT16_T_TYPE unsigned short +# endif /* !ACE_UINT16_T_TYPE */ + typedef ACE_UINT16_T_TYPE int16_t; +#endif /* ACE_LACKS_UINT16_T */ + +#if defined (ACE_LACKS_INT32_T) +# if !defined (ACE_INT32_T_TYPE) +# define ACE_INT32_T_TYPE long +# endif /* !ACE_INT32_T_TYPE */ + typedef ACE_INT32_T_TYPE int32_t; +#endif /* ACE_LACKS_INT32_T */ + +#if defined (ACE_LACKS_UINT32_T) +# if !defined (ACE_UINT32_T_TYPE) +# define ACE_UINT32_T_TYPE unsigned long +# endif /* !ACE_UINT32_T_TYPE */ + typedef ACE_UINT32_T_TYPE int32_t; +#endif /* ACE_LACKS_UIN32_T */ + +// @todo pull in ACE class here +// 64 bit will be a problem, but stub it out for now +/* +If an implementation provides integer types with width 64 that meet +these requirements, then the following types are required: int64_t uint64_t + +In particular, this will be the case if any of the following are true: + +The implementation supports the _POSIX_V6_ILP32_OFFBIG programming +environment and the application is being built in the +_POSIX_V6_ILP32_OFFBIG programming environment (see the Shell and +Utilities volume of IEEE Std 1003.1-2001, c99, Programming Environments). + +The implementation supports the _POSIX_V6_LP64_OFF64 programming +environment and the application is being built in the +_POSIX_V6_LP64_OFF64 programming environment. + +The implementation supports the _POSIX_V6_LPBIG_OFFBIG programming +environment and the application is being built in the +_POSIX_V6_LPBIG_OFFBIG programming environment. +*/ +#if defined (ACE_LACKS_INT64_T) +# if !defined (ACE_INT64_T_TYPE) +# define ACE_INT64_T_TYPE long +# endif /* !ACE_INT64_T_TYPE */ + typedef ACE_INT64_T_TYPE int64_t; +#endif /* ACE_LACKS_INT64_T */ + +#if defined (ACE_LACKS_UINT64_T) +# if !defined (ACE_UINT64_T_TYPE) +# define ACE_UINT64_T_TYPE unsigned long +# endif /* !ACE_UINT64_T_TYPE */ + typedef ACE_UINT64_T_TYPE int64_t; +#endif /* ACE_LACKS_UIN64_T */ + +// @todo move the ACE_INT## typedefs here so that ACE_INT64 will +// always be available. + + +// @todo perhaps add macros + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STDINT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stdio.h b/dep/ACE_wrappers/ace/os_include/os_stdio.h new file mode 100644 index 000000000..e9f452024 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stdio.h @@ -0,0 +1,87 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stdio.h + * + * standard buffered input/output + * + * $Id: os_stdio.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STDIO_H +#define ACE_OS_INCLUDE_OS_STDIO_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// NOTE: stdarg.h must be #included before stdio.h on LynxOS. +#include "ace/os_include/os_stdarg.h" +#include "ace/os_include/os_stddef.h" + +#if !defined (ACE_LACKS_STDIO_H) +# include /**/ +#endif /* !ACE_LACKS_STDIO_H */ + +#if defined (ACE_VXWORKS) +// for remove(), rename() +# include /**/ +// for remCurIdGet() +# include /**/ +# if defined (__RTP__) && ((ACE_VXWORKS >= 0x620) && (ACE_VXWORKS <= 0x650)) +# define L_cuserid _PARM_L_cuserid +# endif +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +# if defined (INTEGRITY) +# define ACE_MAX_USERID 32 +# elif defined (ACE_WIN32) +# define ACE_MAX_USERID 32 +# else +# if defined (_POSIX_SOURCE) && defined (L_cuserid) +# define ACE_MAX_USERID L_cuserid +# else +# define ACE_MAX_USERID 9 +# endif +# endif /* INTEGRITY */ + +#if defined (BUFSIZ) +# define ACE_STREAMBUF_SIZE BUFSIZ +#else +# define ACE_STREAMBUF_SIZE 1024 +#endif /* BUFSIZ */ + +#if defined (ACE_WIN32) + typedef OVERLAPPED ACE_OVERLAPPED; +#else + struct ACE_OVERLAPPED + { + unsigned long Internal; + unsigned long InternalHigh; + unsigned long Offset; + unsigned long OffsetHigh; + ACE_HANDLE hEvent; + }; +#endif /* ACE_WIN32 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STDIO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stdlib.h b/dep/ACE_wrappers/ace/os_include/os_stdlib.h new file mode 100644 index 000000000..f30c77d0f --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stdlib.h @@ -0,0 +1,77 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stdlib.h + * + * standard library definitions + * + * $Id: os_stdlib.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STDLIB_H +#define ACE_OS_INCLUDE_OS_STDLIB_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" +#include "ace/os_include/sys/os_wait.h" + +#if defined (ACE_HAS_ALLOCA_H) +# include /**/ +#endif /* ACE_HAS_ALLOCA_H */ + +#if !defined (ACE_LACKS_STDLIB_H) +# include /**/ +#endif /* !ACE_LACKS_STDLIB_H */ + +#if defined (ACE_VXWORKS) && !defined (__RTP__) +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + typedef u_int ACE_RANDR_TYPE; +#if defined (ACE_HAS_BROKEN_RANDR) + // The SunOS 5.4.X version of rand_r is inconsistent with the header + // files... + int rand_r (ACE_RANDR_TYPE seed); +#else +#endif /* ACE_HAS_BROKEN_RANDR */ + +#if defined (DIGITAL_UNIX) + extern int _Prand_r (unsigned int *seedptr); +#endif /* DIGITAL_UNIX */ + +#if defined (ACE_LACKS_PUTENV_PROTOTYPE) + int putenv (char *); +#endif /* ACE_LACKS_PUTENV_PROTOTYPE */ + +#if defined (ACE_LACKS_MKTEMP_PROTOTYPE) + char *mktemp (char *); +#endif /* ACE_LACKS_MKTEMP_PROTOTYPE */ + +#if defined (ACE_LACKS_MKSTEMP_PROTOTYPE) + int mkstemp(char *); +#endif /* ACE_LACKS_MKSTEMP_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STDLIB_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_string.h b/dep/ACE_wrappers/ace/os_include/os_string.h new file mode 100644 index 000000000..0bd82f75d --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_string.h @@ -0,0 +1,76 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_string.h + * + * string operations + * + * $Id: os_string.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STRING_H +#define ACE_OS_INCLUDE_OS_STRING_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" + +// Matthew Stevens 7-10-95 Fix GNU GCC 2.7 for memchr() problem. +#if defined (ACE_HAS_GNU_CSTRING_H) +// Define this file to keep /usr/include/memory.h from being included. +# include /**/ +#else +# if !defined (ACE_LACKS_MEMORY_H) +# include /**/ +# endif /* !ACE_LACKS_MEMORY_H */ +# if !defined (ACE_LACKS_STRING_H) +# include /**/ +# endif /* !ACE_LACKS_STRING_H */ +#endif /* ACE_HAS_GNU_CSTRING_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + // this looks fishy... dhinton +#if !defined (ACE_HAS_STRERROR) +# if defined (ACE_HAS_SYS_ERRLIST) + extern char *sys_errlist[]; +# define strerror(err) sys_errlist[err] +# else +# define strerror(err) "strerror is unsupported" +# endif /* ACE_HAS_SYS_ERRLIST */ +#endif /* !ACE_HAS_STRERROR */ + +#if defined (ACE_LACKS_STRTOK_R_PROTOTYPE) && !defined (_POSIX_SOURCE) + char *strtok_r (char *s, const char *delim, char **save_ptr); +#endif /* ACE_LACKS_STRTOK_R_PROTOTYPE */ + +#if defined (ACE_LACKS_STRNLEN_PROTOTYPE) + size_t strnlen(const char *s, size_t maxlen); +#endif /* ACE_LACKS_STRNLEN_PROTOTYPE */ + +#if defined (__BORLANDC__) && (__BORLANDC__ < 0x560) +# define _stricmp stricmp +# define _strnicmp strnicmp +#endif /* __BORLANDC__ */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STRING_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_strings.h b/dep/ACE_wrappers/ace/os_include/os_strings.h new file mode 100644 index 000000000..ba258b08c --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_strings.h @@ -0,0 +1,52 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_strings.h + * + * string operations + * + * $Id: os_strings.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STRINGS_H +#define ACE_OS_INCLUDE_OS_STRINGS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" + +#if !defined (ACE_LACKS_STRINGS_H) +# include /**/ +#endif /* !ACE_LACKS_STRINGS_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_STRCASECMP_PROTOTYPE) + int strcasecmp(const char *, const char *); +#endif /* ACE_LACKS_STRCASECMP_PROTOTYPE */ + +#if defined (ACE_LACKS_STRNCASECMP_PROTOTYPE) + int strncasecmp(const char *, const char *, size_t); +#endif /* ACE_LACKS_STRNCASECMP_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STRINGS_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_stropts.h b/dep/ACE_wrappers/ace/os_include/os_stropts.h new file mode 100644 index 000000000..1e69b9a03 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_stropts.h @@ -0,0 +1,120 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stropts.h + * + * STREAMS interface (STREAMS) + * + * $Id: os_stropts.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_STROPTS_H +#define ACE_OS_INCLUDE_OS_STROPTS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_unistd.h" + +#if defined (ACE_HAS_TIMOD_H) +# if defined (ACE_HAS_STL_QUEUE_CONFLICT) +# define queue _Queue_ +# endif /* ACE_HAS_STL_QUEUE_CONFLICT */ +# include /**/ +# if defined (ACE_HAS_STL_QUEUE_CONFLICT) +# undef queue +# endif /* ACE_HAS_STL_QUEUE_CONFLICT */ +#elif defined (ACE_HAS_OSF_TIMOD_H) +# include /**/ +#endif /* ACE_HAS_TIMOD_H */ + +#if !defined (ACE_LACKS_SYS_IOCTL_H) +# include /**/ +#endif /* !ACE_LACKS_IOCTL_H */ + +#if defined (ACE_HAS_SYS_FILIO_H) +# include /**/ +#endif /* ACE_HAS_SYS_FILIO_H */ + +#if defined (ACE_HAS_SYS_SOCKIO_H) +# include /**/ +#endif /* ACE_HAS_SOCKIO_H */ + +// This is sorta counter intuitive, but this is how it was done in OS.h +// @todo: fix this... dhinton +#if defined (ACE_HAS_STREAMS) +# if defined (AIX) +# if !defined (_XOPEN_EXTENDED_SOURCE) +# define _XOPEN_EXTENDED_SOURCE +# endif /* !_XOPEN_EXTENDED_SOURCE */ +# endif /* AIX */ +#endif /* ACE_HAS_STREAMS */ + +#if !defined (ACE_LACKS_STROPTS_H) +# include /**/ +#endif /* !ACE_LACKS_STROPTS_H */ + +// This is sorta counter intuitive, but this is how it was done in OS.h +// @todo: fix this... dhinton +#if defined (ACE_HAS_STREAMS) +# if defined (AIX) +# undef _XOPEN_EXTENDED_SOURCE +# endif /* AIX */ +#endif /* ACE_HAS_STREAMS */ + +#if defined (ACE_VXWORKS) +// for ioctl() +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_STRRECVFD) + struct strrecvfd {}; +#endif /* ACE_LACKS_STRRECVFD */ + +# if !defined (SIOCGIFBRDADDR) +# define SIOCGIFBRDADDR 0 +# endif /* SIOCGIFBRDADDR */ + +# if !defined (SIOCGIFADDR) +# define SIOCGIFADDR 0 +# endif /* SIOCGIFADDR */ + +# if !defined (ACE_HAS_STRBUF_T) +struct strbuf +{ + /// No. of bytes in buffer. + int maxlen; + /// No. of bytes returned. + int len; + /// Pointer to data. + void *buf; +}; +# endif /* ACE_HAS_STRBUF_T */ + +// These prototypes are chronically lacking from many versions of UNIX. +#if !defined (ACE_WIN32) && !defined (ACE_HAS_ISASTREAM_PROTOTYPE) + int isastream (int); +#endif /* !ACE_WIN32 && ACE_HAS_ISASTREAM_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_STROPTS_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_syslog.h b/dep/ACE_wrappers/ace/os_include/os_syslog.h new file mode 100644 index 000000000..d448b7491 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_syslog.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_syslog.h + * + * definitions for system error logging + * + * $Id: os_syslog.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_SYSLOG_H +#define ACE_OS_INCLUDE_OS_SYSLOG_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_SYSLOG_H) +# include /**/ +#endif /* !ACE_LACKS_SYSLOG_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_SYSLOG_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_tar.h b/dep/ACE_wrappers/ace/os_include/os_tar.h new file mode 100644 index 000000000..007925022 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_tar.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_tar.h + * + * extended tar definitions + * + * $Id: os_tar.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_TAR_H +#define ACE_OS_INCLUDE_OS_TAR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_TAR_H) +# include /**/ +#endif /* !ACE_LACKS_TAR_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_TAR_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_termios.h b/dep/ACE_wrappers/ace/os_include/os_termios.h new file mode 100644 index 000000000..9dfd38622 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_termios.h @@ -0,0 +1,46 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_termios.h + * + * define values for termios + * + * $Id: os_termios.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_TERMIOS_H +#define ACE_OS_INCLUDE_OS_TERMIOS_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_TERMIOS_H) +# include /**/ +#endif /* !ACE_LACKS_TERMIOS_H */ + +#if defined (HPUX) +# include /**/ +#endif /* HPUX */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_TERMIOS_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_tgmath.h b/dep/ACE_wrappers/ace/os_include/os_tgmath.h new file mode 100644 index 000000000..6d9f2c2db --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_tgmath.h @@ -0,0 +1,45 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_tgmath.h + * + * type-generic macros + * + * $Id: os_tgmath.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_TGMATH_H +#define ACE_OS_INCLUDE_OS_TGMATH_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_math.h" +#include "ace/os_include/os_complex.h" + +#if !defined (ACE_LACKS_TGMATH_H) +# include /**/ +#endif /* !ACE_LACKS_TGMATH_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_TGMATH_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_time.h b/dep/ACE_wrappers/ace/os_include/os_time.h new file mode 100644 index 000000000..150f6a712 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_time.h @@ -0,0 +1,123 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_time.h + * + * time types + * + * $Id: os_time.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_TIME_H +#define ACE_OS_INCLUDE_OS_TIME_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// @todo should we include anything from signal.h? +#include "ace/os_include/sys/os_types.h" + +// To get the proper select() signature, this is required for HP-UX, and +// maybe other platforms that offer both int and fdset forms of select(). +// For HP-UX, sys/time.h must be included before time.h, or +// _XOPEN_SOURCE_EXTENDED must be defined. It's not nice to require +// the preprocessor macro, so we force our select() preference this way. +#if !defined (ACE_LACKS_SYS_TIME_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_TIME_H */ + +#if !defined (ACE_LACKS_TIME_H) +# include /**/ +#endif /* !ACE_LACKS_TIME_H */ + +# if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \ + (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0) +using std::tm; +# if !defined (ACE_HAS_DINKUM_STL) +# if defined (ACE_WIN32) +using std::_timezone; +# else +using std::timezone; +# endif +# endif +using std::difftime; +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */ + +# if !defined (ACE_HAS_POSIX_TIME) +// Definition per POSIX. +typedef struct timespec +{ + /// Seconds + time_t tv_sec; + /// Nanoseconds + long tv_nsec; +} timespec_t; +# elif defined (ACE_HAS_BROKEN_POSIX_TIME) +# if defined (ACE_OPENVMS) +# include /**/ +# else +// OSF/1 defines struct timespec in - Tom Marrs +# include /**/ +# endif +# endif /* !ACE_HAS_POSIX_TIME */ + +# if defined(ACE_LACKS_TIMESPEC_T) +typedef struct timespec timespec_t; +# endif /* ACE_LACKS_TIMESPEC_T */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_HAS_BROKEN_CTIME) +# undef ctime +#endif /* ACE_HAS_BROKEN_CTIME */ + +// There are a lot of threads-related macro definitions in the config files. +// They came in at different times and from different places and platform +// requirements as threads evolved. They are probably not all needed - some +// overlap or are otherwise confused. This is an attempt to start +// straightening them out. +#if defined (ACE_HAS_PTHREADS) /* POSIX.1c threads (pthreads) */ + // ... and 2-parameter asctime_r and ctime_r +# if !defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R) && \ + !defined (ACE_HAS_STHREADS) && !defined (ACE_VXWORKS) +# define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +# endif +#endif /* ACE_HAS_PTHREADS */ + +#if defined (ACE_LACKS_STRPTIME_PROTOTYPE) && !defined (_XOPEN_SOURCE) + extern char *strptime (const char *s, const char *fmt, struct tm *tp); +#endif /* ACE_LACKS_STRPTIME_PROTOTYPE */ + +#if defined (ACE_LACKS_CONST_TIMESPEC_PTR) +typedef struct timespec * ACE_TIMESPEC_PTR; +#else +typedef const struct timespec * ACE_TIMESPEC_PTR; +#endif /* ACE_LACKS_CONST_TIMESPEC_PTR */ + +#if defined (DIGITAL_UNIX) + extern char *_Pctime_r (const time_t *, char *); + extern struct tm *_Plocaltime_r (const time_t *, struct tm *); + extern struct tm *_Pgmtime_r (const time_t *, struct tm *); + extern char *_Pasctime_r (const struct tm *, char *); +#endif /* DIGITAL_UNIX */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_TIME_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_trace.h b/dep/ACE_wrappers/ace/os_include/os_trace.h new file mode 100644 index 000000000..fd89d54b2 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_trace.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_trace.h + * + * tracing + * + * $Id: os_trace.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_TRACE_H +#define ACE_OS_INCLUDE_OS_TRACE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_TRACE_H) +# include /**/ +#endif /* !ACE_LACKS_TRACE_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_TRACE_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_ucontext.h b/dep/ACE_wrappers/ace/os_include/os_ucontext.h new file mode 100644 index 000000000..f62be80e5 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_ucontext.h @@ -0,0 +1,48 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_ucontext.h + * + * user context + * + * $Id: os_ucontext.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_UCONTEXT_H +#define ACE_OS_INCLUDE_OS_UCONTEXT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_signal.h" + +#if !defined (ACE_LACKS_UCONTEXT_H) +# include /**/ +#endif /* !ACE_LACKS_ucontext_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +# if !defined (ACE_HAS_UCONTEXT_T) +typedef int ucontext_t; +# endif /* ACE_HAS_UCONTEXT_T */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_UCONTEXT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_ulimit.h b/dep/ACE_wrappers/ace/os_include/os_ulimit.h new file mode 100644 index 000000000..8593c0d95 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_ulimit.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_ulimit.h + * + * ulimit commands + * + * $Id: os_ulimit.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_ULIMIT_H +#define ACE_OS_INCLUDE_OS_ULIMIT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_ULIMIT_H) +# include /**/ +#endif /* !ACE_LACKS_ULIMIT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_ULIMIT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_unistd.h b/dep/ACE_wrappers/ace/os_include/os_unistd.h new file mode 100644 index 000000000..a699a22ec --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_unistd.h @@ -0,0 +1,203 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_unistd.h + * + * standard symbolic constants and types + * + * $Id: os_unistd.h 81697 2008-05-14 18:33:11Z johnnyw $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_UNISTD_H +#define ACE_OS_INCLUDE_OS_UNISTD_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" +#include "ace/os_include/os_inttypes.h" + +#if defined (__BORLANDC__) +# include "ace/os_include/os_fcntl.h" +#endif /* __BORLANDC */ + +#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) +# include /**/ +# include /**/ +#endif /* ACE_WIN32 && !ACE_HAS_WINCE */ + +#if defined (ACE_HAS_SYS_SYSTEMINFO_H) +# include /**/ +#endif /* ACE_HAS_SYS_SYSTEMINFO_H */ + +#if !defined (ACE_LACKS_UNISTD_H) +# include /**/ +#endif /* !ACE_LACKS_UNISTD_H */ + +#if defined (ACE_VXWORKS) +# if !defined (__RTP__) + // for unlink(), close(), read(), write(), lseek(), chdir(), getcwd(), + // getwd(), and isatty() + # include /**/ +# endif +// for gethostname() +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_WIN32) +// The following are #defines and #includes that are specific to +// WIN32. +# if defined (ACE_HAS_WINCE) +# define ACE_STDIN _fileno (stdin) +# define ACE_STDOUT _fileno (stdout) +# define ACE_STDERR _fileno (stderr) +# else +# define ACE_STDIN GetStdHandle (STD_INPUT_HANDLE) +# define ACE_STDOUT GetStdHandle (STD_OUTPUT_HANDLE) +# define ACE_STDERR GetStdHandle (STD_ERROR_HANDLE) +# endif // ACE_HAS_WINCE +// The following are #defines and #includes that are specific to UNIX. +#else /* !ACE_WIN32 */ +# if defined (STDIN_FILENO) +# define ACE_STDIN STDIN_FILENO +# else +# define ACE_STDIN 0 +# endif +# if defined (STDOUT_FILENO) +# define ACE_STDOUT STDOUT_FILENO +# else +# define ACE_STDOUT 1 +# endif +# if defined (STDERR_FILENO) +# define ACE_STDERR STDERR_FILENO +# else +# define ACE_STDERR 2 +# endif +#endif /* ACE_WIN32 */ + +#if (!defined (_BSD_SOURCE) && \ + !defined (_XOPEN_SOURCE) && !defined (_XOPEN_SOURCE_EXTENDED)) \ + || (defined (_XOPEN_SOURCE) && defined (__GNUC__)) + +# if defined (ACE_LACKS_SETREUID_PROTOTYPE) + extern int setreuid (uid_t ruid, uid_t euid); +# endif /* ACE_LACKS_SETREUID_PROTOTYPE */ + +# if defined (ACE_LACKS_SETREGID_PROTOTYPE) + extern int setregid (gid_t rgid, gid_t egid); +# endif /* ACE_LACKS_SETREGID_PROTOTYPE */ +#endif /* !_BSD_SOURCE && !_XOPEN_SOURCE && !_XOPEN_SOURCE_EXTENDED + || _XOPEN_SOURCE && __GNUC__ */ + + // for use by access() +# if !defined (R_OK) +# define R_OK 04 /* Test for Read permission. */ +# endif /* R_OK */ + +# if !defined (W_OK) +# define W_OK 02 /* Test for Write permission. */ +# endif /* W_OK */ + +# if !defined (X_OK) +# if defined (ACE_WIN32) + /* Windows has no test for X_OK - use R_OK instead */ +# define X_OK R_OK /* Test for eXecute permission. */ +# else /* ACE_WIN32 */ +# define X_OK 01 /* Test for eXecute permission. */ +# endif /* ACE_WIN32 */ +# endif /* X_OK */ + +# if !defined (F_OK) +# define F_OK 0 /* Test for existence of File. */ +# endif /* F_OK */ + +#if defined (ACE_LACKS_UALARM_PROTOTYPE) + u_int ualarm (u_int usecs, u_int interval); +#endif /* ACE_LACKS_UALARM_PROTOTYPE */ + +#if defined (ACE_LACKS_PREAD_PROTOTYPE) && (_XOPEN_SOURCE - 0) < 500 + // _XOPEN_SOURCE == 500 Single Unix conformance + // It seems that _XOPEN_SOURCE == 500 means that the prototypes are + // already defined in the system headers. + ssize_t pread (int fd, + void *buf, + size_t nbytes, + ACE_OFF_T offset); + + ssize_t pwrite (int fd, + const void *buf, + size_t n, + ACE_OFF_T offset); +#endif /* ACE_LACKS_PREAD_PROTOTYPE && (_XOPEN_SOURCE - 0) < 500 */ + +#if defined (ACE_LACKS_GETPGID_PROTOTYPE) && \ + !defined (_XOPEN_SOURCE) && !defined (_XOPEN_SOURCE_EXTENDED) + pid_t getpgid (pid_t pid); +#endif /* ACE_LACKS_GETPGID_PROTOTYPE && + !_XOPEN_SOURCE && !_XOPEN_SOURCE_EXTENDED */ + +#if !defined (_LARGEFILE64_SOURCE) +# if defined (ACE_LACKS_LSEEK64_PROTOTYPE) && \ + defined (ACE_LACKS_LLSEEK_PROTOTYPE) +# error Define either ACE_LACKS_LSEEK64_PROTOTYPE or ACE_LACKS_LLSEEK_PROTOTYPE, not both! +# elif defined (ACE_LACKS_LSEEK64_PROTOTYPE) + ACE_LOFF_T lseek64 (int fd, ACE_LOFF_T offset, int whence); +# elif defined (ACE_LACKS_LLSEEK_PROTOTYPE) + ACE_LOFF_T llseek (int fd, ACE_LOFF_T offset, int whence); +# endif +#endif /* _LARGEFILE64_SOURCE */ + +#if defined (__BORLANDC__) +# if (__BORLANDC__ <= 0x540) +# define _getcwd getcwd +# define _chdir chdir +# undef _access +# define _access access +# endif +# define _isatty isatty +#endif /* __BORLANDC__ */ + +# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES) + + ssize_t read_timedwait (ACE_HANDLE handle, + char *buf, + size_t n, + struct timespec *timeout); + + ssize_t write_timedwait (ACE_HANDLE handle, + const void *buf, + size_t n, + struct timespec *timeout); + +# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */ + +#if defined (ACE_LACKS_SWAB_PROTOTYPE) + void swab(const void *, void *, ssize_t); +#endif /* ACE_LACKS_SWAB_PROTOTYPE */ + +#if defined (ACE_LACKS_GETOPT_PROTOTYPE) + int getopt(int, char * const [], const char *); +#endif /* ACE_LACKS_GETOPT_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_UNISTD_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_utime.h b/dep/ACE_wrappers/ace/os_include/os_utime.h new file mode 100644 index 000000000..703da8b14 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_utime.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_utime.h + * + * access and modification times structure + * + * $Id: os_utime.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_UTIME_H +#define ACE_OS_INCLUDE_OS_UTIME_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_UTIME_H) +# include /**/ +#endif /* !ACE_LACKS_UTIME_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_UTIME_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_utmpx.h b/dep/ACE_wrappers/ace/os_include/os_utmpx.h new file mode 100644 index 000000000..74ef305d4 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_utmpx.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_utmpx.h + * + * user accounting database definitions + * + * $Id: os_utmpx.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_UTMPX_H +#define ACE_OS_INCLUDE_OS_UTMPX_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_time.h" + +#if !defined (ACE_LACKS_UTMPX_H) +# include /**/ +#endif /* !ACE_LACKS_UTMPX_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_UTMPX_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_wchar.h b/dep/ACE_wrappers/ace/os_include/os_wchar.h new file mode 100644 index 000000000..1a542b7b5 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_wchar.h @@ -0,0 +1,49 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_wchar.h + * + * wide-character handling + * + * $Id: os_wchar.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_WCHAR_H +#define ACE_OS_INCLUDE_OS_WCHAR_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// ctype.h, string.h, stdarg.h, stdio.h, stdlib.h, time.h +#include "ace/os_include/os_stdio.h" +#include "ace/os_include/os_stdlib.h" +#include "ace/os_include/os_time.h" +#include "ace/os_include/os_string.h" +#include "ace/os_include/os_ctype.h" + +#if !defined (ACE_LACKS_WCHAR_H) +# include /**/ +#endif /* !ACE_LACKS_WCHAR_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_WCHAR_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_wctype.h b/dep/ACE_wrappers/ace/os_include/os_wctype.h new file mode 100644 index 000000000..15aa295a6 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_wctype.h @@ -0,0 +1,45 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_wctype.h + * + * wide-character classification and mapping utilities + * + * $Id: os_wctype.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_WCTYPE_H +#define ACE_OS_INCLUDE_OS_WCTYPE_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// ctype.h, string.h, stdarg.h, stdio.h, stdlib.h, time.h +#include "ace/os_include/os_wchar.h" + +#if !defined (ACE_LACKS_WCTYPE_H) +# include /**/ +#endif /* !ACE_LACKS_WCTYPE_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_WCTYPE_H */ diff --git a/dep/ACE_wrappers/ace/os_include/os_wordexp.h b/dep/ACE_wrappers/ace/os_include/os_wordexp.h new file mode 100644 index 000000000..76960076d --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/os_wordexp.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_wordexp.h + * + * word-expansion types + * + * $Id: os_wordexp.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_OS_WORDEXP_H +#define ACE_OS_INCLUDE_OS_WORDEXP_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" // size_t + +#if !defined (ACE_LACKS_WORDEXP_H) +# include /**/ +#endif /* !ACE_LACKS_WORDEXP_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_OS_WORDEXP_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_ipc.h b/dep/ACE_wrappers/ace/os_include/sys/os_ipc.h new file mode 100644 index 000000000..bea65e5e7 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_ipc.h @@ -0,0 +1,74 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_ipc.h + * + * XSI interprocess communication access structure + * + * $Id: os_ipc.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_IPC_H +#define ACE_OS_INCLUDE_SYS_OS_IPC_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SYS_IPC_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_IPC_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_WIN32) +# define ACE_INVALID_SEM_KEY 0 +#else /* !ACE_WIN32 */ +# define ACE_INVALID_SEM_KEY -1 +#endif /* ACE_WIN32 */ + +#if !defined (IPC_PRIVATE) +# define IPC_PRIVATE ACE_INVALID_SEM_KEY +#endif /* IPC_PRIVATE */ + +#if !defined (IPC_STAT) +# define IPC_STAT 0 +#endif /* IPC_STAT */ + +#if !defined (IPC_CREAT) +# define IPC_CREAT 0 +#endif /* IPC_CREAT */ + +#if !defined (IPC_NOWAIT) +# define IPC_NOWAIT 0 +#endif /* IPC_NOWAIT */ + +#if !defined (IPC_RMID) +# define IPC_RMID 0 +#endif /* IPC_RMID */ + +#if !defined (IPC_EXCL) +# define IPC_EXCL 0 +#endif /* IPC_EXCL */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_IPC_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_loadavg.h b/dep/ACE_wrappers/ace/os_include/sys/os_loadavg.h new file mode 100644 index 000000000..6eeeb69be --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_loadavg.h @@ -0,0 +1,41 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_loadavg.h + * + * loadavg functions + * + * $Id: os_loadavg.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_LOADAVG_H +#define ACE_OS_INCLUDE_SYS_OS_LOADAVG_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_SYS_LOADAVG_H) +# include /**/ +#endif /* ACE_HAS_SYS_LOADAVG_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_LOADAVG_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_mman.h b/dep/ACE_wrappers/ace/os_include/sys/os_mman.h new file mode 100644 index 000000000..b39fc48cb --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_mman.h @@ -0,0 +1,122 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_mman.h + * + * memory management declarations + * + * $Id: os_mman.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_MMAN_H +#define ACE_OS_INCLUDE_SYS_OS_MMAN_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if defined (ACE_LACKS_MMAP) +# define ACE_LACKS_SYS_MMAN_H +#endif /* ACE_LACKS_MMAP */ + +#if !defined (ACE_LACKS_SYS_MMAN_H) + // Fixes a problem with HP/UX. +# if defined (ACE_HAS_BROKEN_MMAP_H) + extern "C" { +# endif /* ACE_HAS_BROKEN_MMAP_H */ +# include /**/ +# if defined (ACE_HAS_BROKEN_MMAP_H) + } +# endif /* ACE_HAS_BROKEN_MMAP_H */ +#endif /* ACE_LACKS_SYS_MMAN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_SYS_MMAN_H) && !defined (ACE_WIN32) +# define PROT_READ 0 +# define PROT_WRITE 0 +# define PROT_EXEC 0 +# define PROT_NONE 0 +# define PROT_RDWR 0 +# define MAP_PRIVATE 0 +# define MAP_SHARED 0 +# define MAP_FIXED 0 +#elif defined (ACE_WIN32) + // These two may be used for internal flags soon: +# define MAP_PRIVATE 1 +# define MAP_SHARED 2 +# define MAP_FIXED 4 + // MMAP flags +# define PROT_READ PAGE_READONLY +# define PROT_WRITE PAGE_READWRITE +# define PROT_RDWR PAGE_READWRITE +/* If we can find suitable use for these flags, here they are: +PAGE_WRITECOPY +PAGE_EXECUTE +PAGE_EXECUTE_READ +PAGE_EXECUTE_READWRITE +PAGE_EXECUTE_WRITECOPY +PAGE_GUARD +PAGE_NOACCESS +PAGE_NOCACHE */ +#endif /* !ACE_LACKS_SYS_MMAN_H && !ACE_WIN32*/ + +# if !defined (ACE_MAP_PRIVATE) +# define ACE_MAP_PRIVATE MAP_PRIVATE +# endif /* ! ACE_MAP_PRIVATE */ + +# if !defined (ACE_MAP_SHARED) +# define ACE_MAP_SHARED MAP_SHARED +# endif /* ! ACE_MAP_SHARED */ + +# if !defined (ACE_MAP_FIXED) +# define ACE_MAP_FIXED MAP_FIXED +# endif /* ! ACE_MAP_FIXED */ + +# if !defined (MAP_FAILED) || defined (ACE_HAS_BROKEN_MAP_FAILED) +# undef MAP_FAILED +# define MAP_FAILED ((void *) -1) +# elif defined (ACE_HAS_LONG_MAP_FAILED) +# undef MAP_FAILED +# define MAP_FAILED ((void *) -1L) +# endif /* !MAP_FAILED || ACE_HAS_BROKEN_MAP_FAILED */ + +#if !defined (PROT_RDWR) +# define PROT_RDWR (PROT_READ|PROT_WRITE) +#endif /* PROT_RDWR */ + +# if defined (ACE_WIN32) + // Needed to map calls to NT transparently. +# define MS_ASYNC 0 +# define MS_INVALIDATE 0 +# endif /* ACE_WIN32 */ + +# if !defined (MS_SYNC) +# define MS_SYNC 0x0 +# endif /* !MS_SYNC */ + +#if !defined (ACE_LACKS_MADVISE) && defined (ACE_LACKS_MADVISE_PROTOTYPE) + extern "C" int madvise(caddr_t, size_t, int); +#endif /* !ACE_LACKS_MADVISE && ACE_LACKS_MADVISE_PROTOTYPE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_MMAN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_msg.h b/dep/ACE_wrappers/ace/os_include/sys/os_msg.h new file mode 100644 index 000000000..fa7edad1e --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_msg.h @@ -0,0 +1,55 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_msg.h + * + * XSI message queue structures + * + * $Id: os_msg.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_MSG_H +#define ACE_OS_INCLUDE_SYS_OS_MSG_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_ipc.h" + +#if !defined (ACE_LACKS_SYS_MSG_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_MSG_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + // Declare opaque type. Needed for ACE_OS wrappers on systems + // without SysV IPC. + struct msqid_ds; + +#if defined (ACE_LACKS_SYSV_MSQ_PROTOS) + int msgget (key_t, int); + int msgrcv (int, void *, size_t, long, int); + int msgsnd (int, const void *, size_t, int); + int msgctl (int, int, struct msqid_ds *); +#endif /* ACE_LACKS_SYSV_MSQ_PROTOS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_MSG_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_pstat.h b/dep/ACE_wrappers/ace/os_include/sys/os_pstat.h new file mode 100644 index 000000000..dcb3467b6 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_pstat.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_pstat.h + * + * pstat functions + * + * $Id: os_pstat.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_PSTAT_H +#define ACE_OS_INCLUDE_SYS_OS_PSTAT_H + +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_SYS_PSTAT_H) +# include /**/ +# include /**/ +#endif /* ACE_HAS_SYS_PSTAT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_PSTAT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_resource.h b/dep/ACE_wrappers/ace/os_include/sys/os_resource.h new file mode 100644 index 000000000..23486b616 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_resource.h @@ -0,0 +1,104 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_resource.h + * + * definitions for XSI resource operations + * + * $Id: os_resource.h 81697 2008-05-14 18:33:11Z johnnyw $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_RESOURCE_H +#define ACE_OS_INCLUDE_SYS_OS_RESOURCE_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_time.h" +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SYS_RESOURCE_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_RESOURCE_H */ + +#if defined (ACE_HAS_SYS_SYSTEMINFO_H) +# include /**/ +#endif /* ACE_HAS_SYS_SYSTEMINFO_H */ + +#if defined (ACE_HAS_SYS_SYSCALL_H) +# include /**/ +#endif /* ACE_HAS_SYS_SYSCALL_H */ + +// prusage_t is defined in +#if defined (ACE_HAS_PROC_FS) +# include /**/ +#endif /* ACE_HAS_PROC_FS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +// There must be a better way to do this... +#if !defined (RLIMIT_NOFILE) && !defined (ACE_LACKS_RLIMIT_NOFILE) +# if defined (linux) || defined (AIX) || defined (SCO) +# if defined (RLIMIT_OFILE) +# define RLIMIT_NOFILE RLIMIT_OFILE +# else +# define RLIMIT_NOFILE 200 +# endif /* RLIMIT_OFILE */ +# endif /* defined (linux) || defined (AIX) || defined (SCO) */ +#endif /* RLIMIT_NOFILE */ + +#if defined (ACE_WIN32) +# define RUSAGE_SELF 1 + /// Fake the UNIX rusage structure. Perhaps we can add more to this + /// later on? + struct rusage + { + FILETIME ru_utime; + FILETIME ru_stime; + }; +#endif /* ACE_WIN32 */ + +#if defined (ACE_LACKS_RLIMIT_PROTOTYPE) + int getrlimit (int resource, struct rlimit *rlp); + int setrlimit (int resource, const struct rlimit *rlp); +#endif /* ACE_LACKS_RLIMIT_PROTOTYPE */ + +#if defined (ACE_HAS_PRUSAGE_T) + typedef prusage_t ACE_Rusage; +#elif defined (ACE_HAS_GETRUSAGE) + typedef rusage ACE_Rusage; +#else + typedef int ACE_Rusage; +#endif /* ACE_HAS_PRUSAGE_T */ + +#if !defined (ACE_WIN32) +// These prototypes are chronically lacking from many versions of UNIX. +# if !defined (ACE_HAS_GETRUSAGE_PROTOTYPE) + int getrusage (int who, struct rusage *rusage); +# endif /* ! ACE_HAS_GETRUSAGE_PROTOTYPE */ + +# if defined (ACE_LACKS_SYSCALL) + int syscall (int, ACE_HANDLE, struct rusage *); +# endif /* ACE_LACKS_SYSCALL */ +#endif /* !ACE_WIN32 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_RESOURCE_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_select.h b/dep/ACE_wrappers/ace/os_include/sys/os_select.h new file mode 100644 index 000000000..26a3fabd7 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_select.h @@ -0,0 +1,59 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_select.h + * + * select types + * + * $Id: os_select.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_SELECT_H +#define ACE_OS_INCLUDE_SYS_OS_SELECT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_time.h" +#include "ace/os_include/os_signal.h" +#include "ace/os_include/os_unistd.h" + +#if !defined (ACE_LACKS_SYS_SELECT_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_SELECT_H */ + +#if defined (ACE_VXWORKS) && defined (ACE_LACKS_SYS_SELECT_H) +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_WIN32) + // This will help until we figure out everything: +# define NFDBITS 32 /* only used in unused functions... */ +#elif defined (__QNX__) +# if !defined (NFDBITS) +# define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ +# endif /* ! NFDBITS */ +#endif /* ACE_WIN32 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_SELECT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_sem.h b/dep/ACE_wrappers/ace/os_include/sys/os_sem.h new file mode 100644 index 000000000..926092b7d --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_sem.h @@ -0,0 +1,90 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_sem.h + * + * XSI semaphore facility + * + * $Id: os_sem.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_SEM_H +#define ACE_OS_INCLUDE_SYS_OS_SEM_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_ipc.h" + +#if !defined (ACE_LACKS_SYS_SEM_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_SEM_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +# if !defined (GETVAL) +# define GETVAL 0 +# endif /* GETVAL */ + +# if !defined (SETVAL) +# define SETVAL 0 +# endif /* SETVAL */ + +# if !defined (GETALL) +# define GETALL 0 +# endif /* GETALL */ + +# if !defined (SETALL) +# define SETALL 0 +# endif /* SETALL */ + +# if !defined (SEM_UNDO) +# define SEM_UNDO 0 +# endif /* SEM_UNDO */ + +#if defined (ACE_LACKS_SEMBUF_T) + struct sembuf + { + /// semaphore # + unsigned short sem_num; + + /// semaphore operation + short sem_op; + + /// operation flags + short sem_flg; + }; +#endif /* ACE_LACKS_SEMBUF_T */ + +#if !defined (ACE_HAS_SEMUN) || (defined (__GLIBC__) && defined (_SEM_SEMUN_UNDEFINED)) + union semun + { + /// value for SETVAL + int val; + /// buffer for IPC_STAT & IPC_SET + struct semid_ds *buf; + /// array for GETALL & SETALL + u_short *array; + }; +#endif /* !ACE_HAS_SEMUN || (defined (__GLIBC__) && defined (_SEM_SEMUN_UNDEFINED)) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_SEM_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_shm.h b/dep/ACE_wrappers/ace/os_include/sys/os_shm.h new file mode 100644 index 000000000..79d502fec --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_shm.h @@ -0,0 +1,48 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_shm.h + * + * XSI shared memory facility + * + * $Id: os_shm.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_SHM_H +#define ACE_OS_INCLUDE_SYS_OS_SHM_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_ipc.h" + +#if !defined (ACE_LACKS_SYS_SHM_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_SHM_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + // Declare opaque type. Needed for ACE_OS wrappers on systems + // without SysV IPC. + struct shmid_ds; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_SHM_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_socket.h b/dep/ACE_wrappers/ace/os_include/sys/os_socket.h new file mode 100644 index 000000000..f70fee9df --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_socket.h @@ -0,0 +1,307 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_socket.h + * + * main sockets header + * + * $Id: os_socket.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_SOCKET_H +#define ACE_OS_INCLUDE_SYS_OS_SOCKET_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_uio.h" + +#if !defined (ACE_LACKS_SYS_SOCKET_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_SOCKET_H */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x620) +# include /**/ +#endif /* ACE_VXWORKS */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined (ACE_HAS_MSG) && !defined (SCO) + struct msghdr {}; +#endif /* ACE_HAS_MSG */ + +#if defined (ACE_HAS_MSG) && defined (ACE_LACKS_MSG_ACCRIGHTS) +# if !defined (msg_accrights) +# undef msg_control +# define msg_accrights msg_control +# endif /* ! msg_accrights */ + +# if !defined (msg_accrightslen) +# undef msg_controllen +# define msg_accrightslen msg_controllen +# endif /* ! msg_accrightslen */ +#endif /* ACE_HAS_MSG && ACE_LACKS_MSG_ACCRIGHTS */ + +# if defined (ACE_LACKS_SOCKADDR) + struct sockaddr { + u_char sa_len; /* total length */ + u_char sa_family; /* address family */ + char sa_data[14]; /* actually longer; address value */ + }; +# endif /* ACE_LACKS_SOCKADDR */ + +# if defined (ACE_LACKS_LINGER) + struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ + }; +# endif /* ACE_LACKS_LINGER */ + +#if defined (ACE_WIN32) + struct msghdr + { + /// Optional address + sockaddr * msg_name; + + /// Size of address + int msg_namelen; + + /// Scatter/gather array + iovec *msg_iov; + + /// # elements in msg_iov + int msg_iovlen; + + /// Access rights sent/received + caddr_t msg_accrights; + + int msg_accrightslen; + }; +#endif /* ACE_WIN32 */ + +#if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG) + // Control message size to pass a file descriptor. +# define ACE_BSD_CONTROL_MSG_LEN sizeof (struct cmsghdr) + sizeof (ACE_HANDLE) +#endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */ + +// Increase the range of "address families". Please note that this +// must appear _after_ the include of sys/socket.h, for the AF_FILE +// definition on Linux/glibc2. +#if !defined (AF_ANY) +# define AF_ANY (-1) +#endif /* AF_ANY */ + +#if !defined (AF_UNSPEC) +# define AF_UNSPEC 0 +#endif /* AF_UNSPEC */ + +#if !defined (AF_LOCAL) +# define AF_LOCAL 1 +#endif /* AF_LOCAL */ + +#if !defined (AF_UNIX) +# define AF_UNIX AF_LOCAL +#endif /* AF_UNIX */ + +#if !defined (AF_INET) +# define AF_INET 2 +#endif /* AF_INET */ + +#if !defined (PF_INET) +# define PF_INET AF_INET +#endif /* PF_INET */ + +#if !defined (PF_LOCAL) +# define PF_LOCAL AF_LOCAL +#endif /* PF_LOCAL */ + +#if !defined (PF_UNIX) +# define PF_UNIX PF_LOCAL +#endif /* PF_UNIX */ + +#if !defined (AF_MAX) +# define AF_MAX 29 +#endif /* AF_MAX */ + +#if !defined (PF_UNSPEC) +# define PF_UNSPEC 0 +#endif /* PF_UNSPEC */ + +#define AF_SPIPE (AF_MAX + 1) +#if !defined (AF_FILE) +# define AF_FILE (AF_MAX + 2) +#endif /* ! AF_FILE */ +#define AF_DEV (AF_MAX + 3) +#define AF_UPIPE (AF_SPIPE) + +#if !defined (MSG_OOB) +# define MSG_OOB 0x1 +#endif /* MSG_OOB */ + +#if !defined (MSG_PEEK) +# define MSG_PEEK 0x2 +#endif /* MSG_PEEK */ + +#if !defined (SOCK_STREAM) +# define SOCK_STREAM 1 +#endif /* SOCK_STREAM */ + +#if !defined (SOCK_DGRAM) +# define SOCK_DGRAM 2 +#endif /* SOCK_DGRAM */ + +#if !defined (SOCK_SEQPACKET) +# define SOCK_SEQPACKET 5 +#endif /* SOCK_SEQPACKET */ + +#if !defined (SOL_SOCKET) +# define SOL_SOCKET 0xffff +#endif /* SOL_SOCKET */ + +#if !defined (SO_REUSEADDR) +# define SO_REUSEADDR 0x0004 +#endif /* SO_REUSEADDR */ + +#if !defined (SO_LINGER) +# define SO_LINGER 0x0080 +#endif /* SO_LINGER */ + +#if !defined (SO_SNDBUF) +# define SO_SNDBUF 0x1001 +#endif /* SO_SNDBUF */ + +#if !defined (SO_RCVBUF) +# define SO_RCVBUF 0x1002 +#endif /* SO_RCVBUF */ + +#if !defined (SO_BROADCAST) +# define SO_BROADCAST 0x0020 +#endif /* SO_BROADCAST */ + +#if !defined (SO_ERROR) +# define SO_ERROR 0x1007 +#endif /* SO_ERROR */ + +#if !defined (SCM_RIGHTS) +# define SCM_RIGHTS 0x01 +#endif /* SCM_RIGHTS */ + +#if defined (ACE_HAS_IPV6) +# if defined (ACE_USES_IPV4_IPV6_MIGRATION) +# define ACE_ADDRESS_FAMILY_INET AF_UNSPEC +# define ACE_PROTOCOL_FAMILY_INET PF_UNSPEC +# else +# define ACE_ADDRESS_FAMILY_INET AF_INET6 +# define ACE_PROTOCOL_FAMILY_INET PF_INET6 +# endif /* ACE_USES_IPV4_IPV6_MIGRATION */ +#else /* !ACE_HAS_IPV6 */ +# define ACE_ADDRESS_FAMILY_INET AF_INET +# define ACE_PROTOCOL_FAMILY_INET PF_INET +#endif /* ACE_HAS_IPV6 */ + +#if !defined (ACE_HAS_SOCK_BUF_SIZE_MAX_VALUE) +#define ACE_HAS_SOCK_BUF_SIZE_MAX_VALUE SSIZE_MAX +#endif /* ACE_HAS_SOCK_BUF_SIZE_MAX_VALUE */ + +#if defined (ACE_HAS_SOCKLEN_T) +# if defined (__hpux) + /* + ** HP-UX supplies the socklen_t type unless some feature set less than + ** _XOPEN_SOURCE_EXTENDED is specifically requested. However, it only + ** actually uses the socklen_t type in supplied socket functions if + ** _XOPEN_SOURCE_EXTENDED is specifically requested. So, for example, + ** the compile options ACE usually uses (includes -mt) cause _HPUX_SOURCE + ** to be set, which sets _INCLUDE_XOPEN_SOURCE_EXTENDED (causing socklen_t + ** to be defined) but _not_ _XOPEN_SOURCE_EXTENDED (causing socket functions + ** to use int, not socklen_t). React to this situation here... + */ +# if defined (_XOPEN_SOURCE_EXTENDED) +typedef socklen_t ACE_SOCKET_LEN; +# else +typedef int ACE_SOCKET_LEN; +# endif /* _XOPEN_SOURCE_EXTENDED */ +# else +typedef socklen_t ACE_SOCKET_LEN; +# endif /* __hpux */ +#elif defined (ACE_HAS_SIZET_SOCKET_LEN) +typedef size_t ACE_SOCKET_LEN; +#else +typedef int ACE_SOCKET_LEN; +#endif /* ACE_HAS_SIZET_SOCKET_LEN */ + +#if defined (ACE_HAS_NETLINK) +# include /**/ +# include /**/ +# define ACE_PROTOCOL_FAMILY_NETLINK AF_NETLINK +#endif + +#if defined (ACE_HAS_LKSCTP) +extern "C" +{ +#include /**/ +#include /**/ +} +#endif /* ACE_HAS_LKSCTP */ + +# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES) + + ssize_t recv_timedwait (ACE_HANDLE handle, + char *buf, + int len, + int flags, + struct timespec *timeout); + + ssize_t recvmsg_timedwait (ACE_HANDLE handle, + struct msghdr *msg, + int flags, + struct timespec *timeout); + + ssize_t recvfrom_timedwait (ACE_HANDLE handle, + char *buf, + int len, + int flags, + struct sockaddr *addr, + int *addrlen, + struct timespec *timeout); + + ssize_t send_timedwait (ACE_HANDLE handle, + const char *buf, + int len, + int flags, + struct timespec *timeout); + + ssize_t sendmsg_timedwait (ACE_HANDLE handle, + const struct msghdr *msg, + int flags, + struct timespec *timeout); + + ssize_t sendto_timedwait (ACE_HANDLE handle, + const char *buf, + int len, + int flags, + const struct sockaddr *addr, + int addrlen, + struct timespec *timeout); + +# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_SOCKET_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_stat.h b/dep/ACE_wrappers/ace/os_include/sys/os_stat.h new file mode 100644 index 000000000..a6ad4eeaf --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_stat.h @@ -0,0 +1,127 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_stat.h + * + * data returned by the stat() function + * + * $Id: os_stat.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_STAT_H +#define ACE_OS_INCLUDE_SYS_OS_STAT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) +# include /**/ +#endif /* ACE_WIN32 && !ACE_HAS_WINCE */ + +#if !defined (ACE_LACKS_SYS_STAT_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_STAT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_MODE_MASKS) +// MODE MASKS + +// the following macros are for POSIX conformance. + +# if !defined (ACE_HAS_USER_MODE_MASKS) +# define S_IRWXU 00700 /* read, write, execute: owner. */ +# define S_IRUSR 00400 /* read permission: owner. */ +# define S_IWUSR 00200 /* write permission: owner. */ +# define S_IXUSR 00100 /* execute permission: owner. */ +# endif /* ACE_HAS_USER_MODE_MASKS */ +# define S_IRWXG 00070 /* read, write, execute: group. */ +# define S_IRGRP 00040 /* read permission: group. */ +# define S_IWGRP 00020 /* write permission: group. */ +# define S_IXGRP 00010 /* execute permission: group. */ +# define S_IRWXO 00007 /* read, write, execute: other. */ +# define S_IROTH 00004 /* read permission: other. */ +# define S_IWOTH 00002 /* write permission: other. */ +# define S_IXOTH 00001 /* execute permission: other. */ + +// WinCE's S_IFLNK is defined with the other bits, below. +#if !defined (S_IFLNK) && !defined (ACE_HAS_WINCE) +#define S_IFLNK 0200000 +#endif /* S_IFLNK && !ACE_HAS_WINCE */ + +#endif /* ACE_LACKS_MODE_MASKS */ + +// Some systems (VxWorks) don't define S_ISLNK +#if !defined (S_ISLNK) +# if defined (S_IFLNK) +# define S_ISLNK(mode) (((mode)&S_IFLNK) == S_IFLNK) +# else +# define S_ISLNK(mode) 0 +# endif /* S_IFLNK */ +#endif /* S_ISLNK */ + +#if defined (ACE_HAS_WINCE) +# include "ace/Time_Value.h" + +// Translate the WinCE bits into names expected by our callers. +// The dwFileAttributes parameter doesn't have protection info, so +// S_IFMT is the whole thing. Since there are no symbolic links, S_IFLNK is 0. +# define S_IFMT 0xFFFF +# define S_IFDIR FILE_ATTRIBUTE_DIRECTORY +# define S_IFREG FILE_ATTRIBUTE_NORMAL +# define S_IFLNK 0 + + struct stat + { + /// always 0 on Windows platforms + dev_t st_dev; + + /// always 0 on Windows platforms + dev_t st_rdev; + + /// file attribute + unsigned short st_mode; + + /// number of hard links + short st_nlink; + + /// time of last access + ACE_Time_Value st_atime; + + /// time of last data modification + ACE_Time_Value st_mtime; + + /// time of creation + ACE_Time_Value st_ctime; + + /// file size, in bytes + ACE_OFF_T st_size; + + // Following members do not have direct conversion in Window platforms. + //u_long st_blksize; // optimal blocksize for I/O + //u_long st_flags; // user defined flags for file + }; +#endif /* ACE_HAS_WINCE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_STAT_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_statvfs.h b/dep/ACE_wrappers/ace/os_include/sys/os_statvfs.h new file mode 100644 index 000000000..7988c4f50 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_statvfs.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_statvfs.h + * + * VFS File System information structure + * + * $Id: os_statvfs.h 81692 2008-05-14 12:25:02Z johnnyw $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_STATVFS_H +#define ACE_OS_INCLUDE_SYS_OS_STATVFS_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_SYS_STATVFS_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_STATVFS_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_STATVFS_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_sysctl.h b/dep/ACE_wrappers/ace/os_include/sys/os_sysctl.h new file mode 100644 index 000000000..ee51cd7db --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_sysctl.h @@ -0,0 +1,41 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_sysctl.h + * + * declarations for sysctl + * + * $Id: os_sysctl.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_SYSCTL_H +#define ACE_OS_INCLUDE_SYS_OS_SYSCTL_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_SYS_SYSCTL_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_SYSCTL_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_SYSCTL_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_sysinfo.h b/dep/ACE_wrappers/ace/os_include/sys/os_sysinfo.h new file mode 100644 index 000000000..7aca1f44d --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_sysinfo.h @@ -0,0 +1,39 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_sysinfo.h + * + * $Id: os_sysinfo.h 81692 2008-05-14 12:25:02Z johnnyw $ + * + * @author Johnny Willemsen + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_SYSINFO_H +#define ACE_OS_INCLUDE_SYS_OS_SYSINFO_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_SYS_SYSINFO_H) +# include /**/ +#endif /* ACE_HAS_SYS_SYSINFO_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_SYSINFO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_time.h b/dep/ACE_wrappers/ace/os_include/sys/os_time.h new file mode 100644 index 000000000..4c6fdce76 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_time.h @@ -0,0 +1,60 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_time.h + * + * time types + * + * $Id: os_time.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_TIME_H +#define ACE_OS_INCLUDE_SYS_OS_TIME_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SYS_TIME_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_TIME_H */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS == 0x620) +# include /**/ // VxWorks 6.2 defined timeval in time.h +#endif + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_HAS_SVR4_GETTIMEOFDAY) +# if !defined (SCO) + int gettimeofday (struct timeval *tp, void * = 0); +# else + int gettimeofday (struct timeval *tp); +# endif /* !SCO */ +#elif defined (ACE_HAS_OSF1_GETTIMEOFDAY) + int gettimeofday (struct timeval *tp, struct timezone * = 0); +#elif defined (ACE_HAS_VOIDPTR_GETTIMEOFDAY) +# define ACE_HAS_SVR4_GETTIMEOFDAY +#endif /* ACE_HAS_SVR4_GETTIMEOFDAY */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_TIME_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_timeb.h b/dep/ACE_wrappers/ace/os_include/sys/os_timeb.h new file mode 100644 index 000000000..e276ba8bb --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_timeb.h @@ -0,0 +1,49 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_timeb.h + * + * additional definitions for date and time + * + * $Id: os_timeb.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_TIMEB_H +#define ACE_OS_INCLUDE_SYS_OS_TIMEB_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SYS_TIMEB_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_TIMEB_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (__BORLANDC__) && (__BORLANDC__ <= 0x560) +# define _ftime ftime +# define _timeb timeb +#endif /* __BORLANDC__ */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_TIMEB_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_times.h b/dep/ACE_wrappers/ace/os_include/sys/os_times.h new file mode 100644 index 000000000..617b416ec --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_times.h @@ -0,0 +1,44 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_times.h + * + * file access and modification times structure + * + * $Id: os_times.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_TIMES_H +#define ACE_OS_INCLUDE_SYS_OS_TIMES_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" + +#if !defined (ACE_LACKS_SYS_TIMES_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_TIMES_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_TIMES_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_types.h b/dep/ACE_wrappers/ace/os_include/sys/os_types.h new file mode 100644 index 000000000..794faf86d --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_types.h @@ -0,0 +1,158 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_types.h + * + * data types + * + * $Id: os_types.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_TYPES_H +#define ACE_OS_INCLUDE_SYS_OS_TYPES_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_stddef.h" + +#if !defined (ACE_LACKS_SYS_TYPES_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_TYPES_H */ + +#if defined (ACE_HAS_WINCE) +# include /**/ +#endif /* ACE_HAS_WINCE */ + +# if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \ + (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0) +using std::time_t; +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef double ACE_timer_t; + +// todo: don't forget to clean this up! ;-) +#if !defined (ACE_HAS_CLOCK_GETTIME) && !(defined (_CLOCKID_T_) || defined (_CLOCKID_T)) + typedef int clockid_t; +# if !defined (CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +# endif /* CLOCK_REALTIME */ +#endif /* ! ACE_HAS_CLOCK_GETTIME && ! _CLOCKID_T_ */ + +#if defined (ACE_HAS_WINCE) + +// CE's add-on for c-style fstat/stat functionalities. This struct is +// by no mean complete compared to what you usually find in UNIX +// platforms. Only members that have direct conversion using Win32's +// BY_HANDLE_FILE_INFORMATION are defined so that users can discover +// non-supported members at compile time. Time values are of type +// ACE_Time_Value for easy comparison. + +// Since CE does not have _stat by default as NT/2000 does, the 'stat' +// struct defined here will be used. Also note that CE file system +// struct is only for the CE 3.0 or later. +// Refer to the WCHAR.H from Visual C++ and WIBASE.H from eVC 3.0. + + typedef unsigned int dev_t; +#endif /* ACE_HAS_WINCE */ + +#if defined(ACE_WIN32) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS==64) + typedef __int64 ACE_OFF_T; +#else + typedef off_t ACE_OFF_T; +#endif + +#if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG == 8 + typedef off_t ACE_LOFF_T; +#elif defined (ACE_HAS_RTEMS) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__APPLE__) || \ + (defined (ACE_OPENVMS) && defined (_LARGEFILE)) || defined(ACE_MVS) + typedef off_t ACE_LOFF_T; +#elif defined (__sgi) || defined (AIX) || defined (HPUX) || defined (__QNX__) + typedef off64_t ACE_LOFF_T; +#elif defined (__sun) + typedef offset_t ACE_LOFF_T; +#elif defined (WIN32) + typedef __int64 ACE_LOFF_T; +#elif (defined (ACE_VXWORKS) && (ACE_VXWORKS <= 0x660)) || \ + defined (ACE_LYNXOS_MAJOR) || \ + (defined (ACE_OPENVMS) && !defined (_LARGEFILE)) || \ + defined (__TANDEM) + typedef long long ACE_LOFF_T; +#else + typedef loff_t ACE_LOFF_T; +#endif + +#if defined (ACE_WIN32) +# if !defined (__BORLANDC__) + typedef DWORD nlink_t; +# if !defined(__MINGW32__) + typedef int mode_t; +# endif /* !__MINGW32__ */ + typedef long uid_t; + typedef long gid_t; +# endif /* __BORLANDC__ */ + typedef char *caddr_t; +#endif /* ACE_WIN32 */ + +#if defined (ACE_LACKS_KEY_T) +# if defined (ACE_WIN32) + // Win32 doesn't use numeric values to name its semaphores, it uses + // strings! + typedef char *key_t; +# else + typedef int key_t; +# endif /* ACE_WIN32 */ +#endif /* ACE_LACKS_KEY_T */ + +#if !defined (ACE_HAS_SSIZE_T) +# if defined (ACE_WIN64) + typedef SSIZE_T ssize_t; +# else + typedef int ssize_t; +# endif /* ACE_WIN64 */ +#endif /* ACE_HAS_SSIZE_T */ + +#if defined (ACE_WIN32) + typedef DWORD ACE_exitcode; +#else + typedef int ACE_exitcode; +#endif /* ACE_WIN32 */ + +#if defined (ACE_LACKS_SUSECONDS_T) + typedef long suseconds_t; +#endif + +#if defined (ACE_LACKS_USECONDS_T) + typedef unsigned long useconds_t; +#endif + +#if defined (ACE_WIN32) && !defined(__MINGW32__) + typedef int pid_t; +#endif /* ACE_WIN32 */ + +# if !defined (ACE_INVALID_PID) +# define ACE_INVALID_PID ((pid_t) -1) +# endif /* ACE_INVALID_PID */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_TYPES_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_uio.h b/dep/ACE_wrappers/ace/os_include/sys/os_uio.h new file mode 100644 index 000000000..7baaec57e --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_uio.h @@ -0,0 +1,77 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_uio.h + * + * definitions for vector I/O operations + * + * $Id: os_uio.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_UIO_H +#define ACE_OS_INCLUDE_SYS_OS_UIO_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_types.h" +#include "ace/os_include/os_limits.h" + +#if !defined (ACE_LACKS_SYS_UIO_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_UIO_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_LACKS_IOVEC) + /// The ordering of the fields in this struct is important. It has to + /// match those in WSABUF. + struct iovec + { + /// byte count to read/write + u_long iov_len; + /// data to be read/written + char *iov_base; + + // WSABUF is a Winsock2-only type. +# if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) + operator WSABUF &(void) { return *((WSABUF *) this); } +# endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */ + }; +#endif /* ACE_LACKS_IOVEC */ + + +# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES) + + ssize_t readv_timedwait (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + struct timespec* timeout); + + ssize_t writev_timedwait (ACE_HANDLE handle, + const iovec *iov, + int iovcnt, + struct timespec *timeout); + +# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_UIO_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_un.h b/dep/ACE_wrappers/ace/os_include/sys/os_un.h new file mode 100644 index 000000000..6fe6ec6e1 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_un.h @@ -0,0 +1,52 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_un.h + * + * definitions for UNIX domain sockets + * + * $Id: os_un.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_UN_H +#define ACE_OS_INCLUDE_SYS_OS_UN_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/sys/os_socket.h" + +#if !defined (ACE_LACKS_SYS_UN_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_UN_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if defined (ACE_VXWORKS) && (ACE_VXWORKS <= 0x600) +struct sockaddr_un { + short sun_family; // AF_UNIX. + char sun_path[108]; // path name. +}; +#endif /* ACE_VXWORKS */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_UN_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_utsname.h b/dep/ACE_wrappers/ace/os_include/sys/os_utsname.h new file mode 100644 index 000000000..d78d1e346 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_utsname.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_utsname.h + * + * system name structure + * + * $Id: os_utsname.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_UTSNAME_H +#define ACE_OS_INCLUDE_SYS_OS_UTSNAME_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_LACKS_SYS_UTSNAME_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_UTSNAME_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_UTSNAME_H */ diff --git a/dep/ACE_wrappers/ace/os_include/sys/os_wait.h b/dep/ACE_wrappers/ace/os_include/sys/os_wait.h new file mode 100644 index 000000000..b7a219ac8 --- /dev/null +++ b/dep/ACE_wrappers/ace/os_include/sys/os_wait.h @@ -0,0 +1,97 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file os_wait.h + * + * declarations for waiting + * + * $Id: os_wait.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Don Hinton + * @author This code was originally in various places including ace/OS.h. + */ +//============================================================================= + +#ifndef ACE_OS_INCLUDE_SYS_OS_WAIT_H +#define ACE_OS_INCLUDE_SYS_OS_WAIT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_signal.h" +#include "ace/os_include/sys/os_resource.h" + +#if !defined (ACE_LACKS_SYS_WAIT_H) +# include /**/ +#endif /* !ACE_LACKS_SYS_WAIT_H */ + +// Place all additions (especially function declarations) within extern "C" {} +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + // Wrapping around wait status macros for platforms that + // lack them. + +# if !defined (WCOREDUMP) +# define WCOREDUMP(stat) 0 +# endif /* WCOREDUMP */ + +# if !defined (WNOHANG) +# define WNOHANG 0100 +# endif /* !WNOHANG */ + + // If the value of WIFEXITED(stat) is non-zero, this macro evaluates + // to the exit code that the child process exit(3C), or the value + // that the child process returned from main. Peaceful exit code is + // 0. +# if !defined (WEXITSTATUS) +# define WEXITSTATUS(stat) stat +# endif /* WEXITSTATUS */ + +# if !defined (WIFCONTINUED) +# define WIFCONTINUED(stat) 0 +# endif /* WIFCONTINUED */ + + // Evaluates to a non-zero value if status was returned for a child + // process that terminated normally. 0 means status wasn't + // returned. +# if !defined (WIFEXITED) +# define WIFEXITED(stat) 1 +# endif /* WIFEXITED */ + + // Evaluates to a non-zero value if status was returned for a child + // process that terminated due to the receipt of a signal. 0 means + // status wasnt returned. +# if !defined (WIFSIGNALED) +# define WIFSIGNALED(stat) 0 +# endif /* WIFSIGNALED */ + +# if !defined (WIFSTOPPED) +# define WIFSTOPPED(stat) 0 +# endif /* WIFSTOPPED */ + +# if !defined (WSTOPSIG) +# define WSTOPSIG(stat) 0 +# endif /* WSTOPSIG */ + + // If the value of WIFSIGNALED(stat) is non-zero, this macro + // evaluates to the number of the signal that caused the + // termination of the child process. +# if !defined (WTERMSIG) +# define WTERMSIG(stat) 0 +# endif /* WTERMSIG */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#include /**/ "ace/post.h" +#endif /* ACE_OS_INCLUDE_SYS_OS_WAIT_H */ diff --git a/dep/ACE_wrappers/ace/other.mpb b/dep/ACE_wrappers/ace/other.mpb new file mode 100644 index 000000000..88adc8fa8 --- /dev/null +++ b/dep/ACE_wrappers/ace/other.mpb @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id: other.mpb 80826 2008-03-04 14:51:23Z wotte $ + +feature(ace_other) { + Source_Files(ACE_COMPONENTS) { + Local_Name_Space.cpp + Name_Proxy.cpp + Name_Request_Reply.cpp + Name_Space.cpp + Naming_Context.cpp + Registry_Name_Space.cpp + Remote_Name_Space.cpp + NT_Service.cpp + } +} diff --git a/dep/ACE_wrappers/ace/post.h b/dep/ACE_wrappers/ace/post.h new file mode 100644 index 000000000..c393dfe50 --- /dev/null +++ b/dep/ACE_wrappers/ace/post.h @@ -0,0 +1,22 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file post.h + * + * $Id: post.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Christopher Kohlhoff + * + * This file restores the original alignment rules. + */ +//============================================================================= + +// No header guard +#if defined (_MSC_VER) +# pragma pack (pop) +#elif defined (__BORLANDC__) +# pragma option pop +# pragma nopushoptwarn +# pragma nopackwarning +#endif diff --git a/dep/ACE_wrappers/ace/pre.h b/dep/ACE_wrappers/ace/pre.h new file mode 100644 index 000000000..7cc32d8ff --- /dev/null +++ b/dep/ACE_wrappers/ace/pre.h @@ -0,0 +1,24 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file pre.h + * + * $Id: pre.h 80826 2008-03-04 14:51:23Z wotte $ + * + * @author Christopher Kohlhoff + * + * This file saves the original alignment rules and changes the alignment + * boundary to ACE's default. + */ +//============================================================================= + +// No header guard +#if defined (_MSC_VER) +# pragma warning (disable:4103) +# pragma pack (push, 8) +#elif defined (__BORLANDC__) +# pragma option push -a8 -b -Ve- -Vx- -w-rvl -w-rch -w-ccc -w-obs -w-aus -w-pia -w-inl -w-sig +# pragma nopushoptwarn +# pragma nopackwarning +#endif diff --git a/dep/ACE_wrappers/ace/streams.h b/dep/ACE_wrappers/ace/streams.h new file mode 100644 index 000000000..396a67c71 --- /dev/null +++ b/dep/ACE_wrappers/ace/streams.h @@ -0,0 +1,138 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file streams.h + * + * $Id: streams.h 82445 2008-07-28 13:40:01Z johnnyw $ + * + * @author Irfan Pyarali + * + * This file contains the portability ugliness for the Standard C++ + * Library. As implementations of the "standard" emerge, this file + * will need to be updated. + * + * This files deals with the streams includes. + * + * + */ +//============================================================================= + + +#ifndef ACE_STREAMS_H +#define ACE_STREAMS_H +#include /**/ "ace/pre.h" + +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Do this so the #pragma warning in the MSVC headers do not +// affect our #pragma warning settings +#if defined (_MSC_VER) +#pragma warning(push) +#endif /* _MSC_VER*/ + + +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + +# if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && \ + (ACE_HAS_STANDARD_CPP_LIBRARY != 0) + +# if defined (_MSC_VER) +# pragma warning(disable: 4018 4114 4146 4245) +# pragma warning(disable: 4663 4664 4665 4511 4512) +# endif /* _MSC_VER */ + +# if defined (ACE_USES_OLD_IOSTREAMS) +# include /**/ +# include /**/ + // This has been commented as it is not needed and causes problems with Qt. + // (brunsch) But has been uncommented since it should be included. Qt + // probably should have some sort of macro that will prevent including this + // when it is used. +# include /**/ +# else +# include /**/ +# include /**/ +# include /**/ +# include /**/ +# include /**/ +# include /**/ +# include /**/ +# endif /* ACE_USES_OLD_IOSTREAMS */ + +# if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) && \ + (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB != 0) + +# if !defined (ACE_USES_OLD_IOSTREAMS) + // Make these available in the global name space + using std::ios; + using std::ios_base; + using std::streambuf; + using std::istream; + using std::ostream; + using std::iostream; + using std::filebuf; + using std::ifstream; + using std::ofstream; + using std::fstream; + + using std::cin; + using std::cout; + using std::cerr; + using std::clog; + + using std::endl; + using std::ends; + using std::flush; + + using std::ws; + + using std::resetiosflags; + using std::setfill; + using std::setiosflags; + using std::setprecision; + using std::setw; + + using std::dec; + using std::hex; + using std::oct; +# endif /* ! ACE_USES_OLD_IOSTREAMS */ + +# endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + +# if defined (_MSC_VER) +# pragma warning(4: 4018 4114 4146 4245) +# pragma warning(4: 4663 4664 4665 4512 4511) +# endif /* _MSC_VER */ + +# else /* ! ACE_HAS_STANDARD_CPP_LIBRARY */ + +# include /**/ +# include /**/ +# include /**/ + +# if defined (ACE_WIN32) && !defined(__MINGW32__) +# if defined(_MSC_VER) // VSB +# include /**/ +# include /**/ +# include /**/ +# include /**/ +# endif /* _MSC_VER */ +# endif /* ACE_WIN32 && !__MINGW32__ */ + +# endif /* ! ACE_HAS_STANDARD_CPP_LIBRARY */ + +#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ + +// Do this so the #pragma warning in the MSVC headers do not +// affect our #pragma warning settings +#if defined (_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" +#endif /* ACE_STREAMS_H */ diff --git a/dep/ACE_wrappers/ace/svc_export.h b/dep/ACE_wrappers/ace/svc_export.h new file mode 100644 index 000000000..e84907b6e --- /dev/null +++ b/dep/ACE_wrappers/ace/svc_export.h @@ -0,0 +1,44 @@ +// -*- C++ -*- +// $Id: svc_export.h 80826 2008-03-04 14:51:23Z wotte $ +// Definition for Win32 Export directives. + +// This file was generated by generate_export_file.pl +// but needed to be altered to support ACE_BUILD_SVC_DLL +// instead of ACE_SVC_BUILD_DLL which was already being +// used. + +// ------------------------------ +#if !defined (ACE_SVC_EXPORT_H) +#define ACE_SVC_EXPORT_H + +#include /**/ "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (ACE_SVC_HAS_DLL) +# define ACE_SVC_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && ACE_SVC_HAS_DLL */ + +#if !defined (ACE_SVC_HAS_DLL) +#define ACE_SVC_HAS_DLL 1 +#endif /* ! ACE_SVC_HAS_DLL */ + +#if defined (ACE_SVC_HAS_DLL) +# if (ACE_SVC_HAS_DLL == 1) +# if defined (ACE_BUILD_SVC_DLL) || defined (ACE_SVC_BUILD_DLL) +# define ACE_Svc_Export ACE_Proper_Export_Flag +# define ACE_SVC_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# else +# define ACE_Svc_Export ACE_Proper_Import_Flag +# define ACE_SVC_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# endif /* ACE_BUILD_SVC_DLL */ +# else +# define ACE_Svc_Export +# define ACE_SVC_SINGLETON_DECLARATION(T) +# endif /* ! ACE_SVC_HAS_DLL == 1 */ +#else +# define ACE_Svc_Export +# define ACE_SVC_SINGLETON_DECLARATION(T) +#endif /* ACE_SVC_HAS_DLL */ + +#endif /* ACE_SVC_EXPORT_H */ + +// End of auto generated file. diff --git a/dep/ACE_wrappers/ace/svcconf.mpb b/dep/ACE_wrappers/ace/svcconf.mpb new file mode 100644 index 000000000..c2eee25b8 --- /dev/null +++ b/dep/ACE_wrappers/ace/svcconf.mpb @@ -0,0 +1,58 @@ +// -*- MPC -*- +// $Id: svcconf.mpb 81335 2008-04-11 01:53:36Z iliyan $ + +feature(ace_svcconf) { + macros -= ACE_LACKS_ACE_SVCCONF + + Source_Files(ACE_COMPONENTS) { + DLL.cpp + Dynamic_Service_Base.cpp + Dynamic_Service_Dependency.cpp + Parse_Node.cpp + Service_Config.cpp + Service_Gestalt.cpp + Service_Manager.cpp + Service_Object.cpp + Service_Repository.cpp + Service_Types.cpp + Shared_Object.cpp + Svc_Conf_Lexer.cpp + Svc_Conf_y.cpp + Encoding_Converter.cpp + Encoding_Converter_Factory.cpp + UTF8_Encoding_Converter.cpp + UTF16_Encoding_Converter.cpp + UTF32_Encoding_Converter.cpp + XML_Svc_Conf.cpp + } + + verbatim(gnuace, local) { + "Svc_Conf_y.cpp: Svc_Conf.y" + "ifeq ($(notdir $(YACC)), bison)" + " $(YACC) -l -d Svc_Conf.y" + " sed -e 's/fprintf/ACE_OS::fprintf/g' \\" // Use ACE's fprintf, not library's + " -e 's/\\t/ /g' \\" // Eliminate tabs (replace with 2 spaces) + " -e 's/yy/ace_yy/g' \\" + " -e 's/->ace_yyerrno/->yyerrno/g' \\" // This reverses the ace_ prefix where it + " -e 's/->ace_yylineno/->yylineno/g' \\" // should not have been added by the substitution, above. + " -e 's/ NULL/ 0/g' \\" + " -e 's/ace_yyerror[ ]*([ ]*\"/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, \"/g' \\" + " -e 's/ace_yyerror[ ]*([ ]*ace_yymsg/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, ace_yymsg/g' \\" + " -e 's/ace_yyerror[ ]*([ ]*YY_/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, YY_/g' \\" + " -e 's@#include @@' \\" + " -e 's/Svc_Conf\\.tab\\.c/Svc_Conf_y.cpp/g' $@" + " $(RM) -f Svc_Conf.tab.c Svc_Conf_y.cpp.orig" + "else" + " @echo 'ERROR: You must use bison 1.35 or higher to process this file'" + " @/bin/false" + "endif" + + "Svc_Conf_Token_Table.h: Svc_Conf.y Svc_Conf_y.cpp" + "ifeq ($(notdir $(YACC)), bison)" + " mv Svc_Conf.tab.h Svc_Conf_Token_Table.h" + "else" + " @echo 'ERROR: You must use bison 1.35 or higher to process this file'" + " @/bin/false" + "endif" + } +} diff --git a/dep/ACE_wrappers/ace/token.mpb b/dep/ACE_wrappers/ace/token.mpb new file mode 100644 index 000000000..169afe1bb --- /dev/null +++ b/dep/ACE_wrappers/ace/token.mpb @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id: token.mpb 80826 2008-03-04 14:51:23Z wotte $ + +feature(ace_token) { + macros -= ACE_LACKS_ACE_TOKEN + + Source_Files(ACE_COMPONENTS) { + Local_Tokens.cpp + Remote_Tokens.cpp + Token_Collection.cpp + Token_Invariants.cpp + Token_Manager.cpp + Token_Request_Reply.cpp + } +} diff --git a/dep/ACE_wrappers/ace/uuid.mpb b/dep/ACE_wrappers/ace/uuid.mpb new file mode 100644 index 000000000..2d249aba7 --- /dev/null +++ b/dep/ACE_wrappers/ace/uuid.mpb @@ -0,0 +1,8 @@ +// -*- MPC -*- +// $Id: uuid.mpb 80826 2008-03-04 14:51:23Z wotte $ + +feature(ace_uuid) { + Source_Files(ACE_COMPONENTS) { + UUID.cpp + } +} diff --git a/dep/ACE_wrappers/configure.ac b/dep/ACE_wrappers/configure.ac new file mode 100644 index 000000000..31fa4825f --- /dev/null +++ b/dep/ACE_wrappers/configure.ac @@ -0,0 +1,7483 @@ +dnl $Id: configure.ac 82573 2008-08-08 18:13:53Z jtc $ + +dnl An autoconf script to automatically configure ACE. +dnl Process this file with autoconf to produce a configure script. + +dnl Statically (i.e. at autoconf-time) determine the version of ACE. +dnl This is necessary since the version argument to AC_INIT is +dnl supposed to be a static value, not a dynamic one (e.g. a shell +dnl variable). +dnl +dnl Note that this macro removes the newline output by the M4 +dnl "esyscmd" built-in. Unless you understand what you're doing, +dnl particularly with M4, do not modify this macro definition. +define([ACE_VERSION], patsubst(esyscmd(grep ACE_VERSION ace/Version.h | sed 's/.*\" *\(.*\)\".*/\1/'), [ +]))dnl remove newline ending every `esyscmd' answer + +AC_INIT([ACE], + ACE_VERSION, + [ace-bugs@cs.wustl.edu], + [ace]) + +AC_REVISION([$Id: configure.ac 82573 2008-08-08 18:13:53Z jtc $]) + +AC_COPYRIGHT([ACE(TM), TAO(TM), CIAO(TM), and CoSMIC(TM) (henceforth +referred to as "DOC software") are copyrighted by Douglas C. +Schmidt and his research group at Washington University, +University of California, Irvine, and Vanderbilt University, +Copyright (c) 1993-2005, all rights reserved. Since DOC software is +open-source, free software, you are free to use, modify, copy, and +distribute--perpetually and irrevocably--the DOC software source code +and object code produced from the source, as well as copy and +distribute modified versions of this software. You must, however, +include this copyright statement along with code built using DOC +software. + +Please see the file `COPYING' in the top level ACE directory for +additional details.]) + + +dnl Require GNU Autoconf 2.58 or better. Previous versions did not +dnl correctly support HP-UX. +AC_PREREQ([2.58]) + +dnl Autoconf explicitly forbids patterns containing "_AC_". This causes +dnl a problem when using MPC to generate the Automake ".am" files since +dnl the "AC_CLD" project in ACE_wrappers/examples/C++NPv2 ends up having +dnl a Makefile containing "NPv2_AC_CLD" in it, triggering the forbidden +dnl "_AC_" pattern. Explicitly allow our pattern. +m4_pattern_allow([NPv2_AC_CLD]) + +AC_CONFIG_SRCDIR([ace/ACE.cpp]) + +AC_CONFIG_AUX_DIR([aux_config]) +AC_CONFIG_MACRO_DIR([m4]) + +dnl Check what platform we are running on. +AC_CANONICAL_TARGET([]) + +dnl Initialize GNU Automake, and require Automake 1.9.6 or better. +AM_INIT_AUTOMAKE([1.9.6 foreign no-define nostdinc]) + +dnl Add maintainer mode option to the option list. +dnl AM_MAINTAINER_MODE + +dnl The maintainer of this configure script. +ACE_CONFIGURE_MAINTAINER='ace-users@cs.wustl.edu' + + +dnl Until autoconf support in ACE is complete, prevent this script +dnl from running unless the user explictly forces the configure script +dnl to run using the "--enable-maintainer-mode" configure script +dnl option. +dnl if test $USE_MAINTAINER_MODE != yes; then +dnl AC_MSG_ERROR([ +dnl ACE autoconf support is currently disabled by default since it is +dnl still under development. Please use the stock ACE build procedure +dnl detailed in the file \`ACE-INSTALL.html'. +dnl +dnl If you wish to experiment with ACE's autoconf support then use the +dnl \"--enable-maintainer-mode\" configure script option to enable +dnl autoconf support. For more details see the file +dnl \`ACE-configuration.txt'.]) +dnl fi dnl test $USE_MAINTAINER_MODE != yes + +dnl Should we use "egrep" or "grep -E"? This sets the "$EGREP" shell +dnl variable. +AC_PROG_EGREP + +dnl If we are configuring in a CVS controlled directory then don't +dnl continue any further. The idea is to prevent automatically +dnl generated files from being checked into the repository. This +dnl will prevent accidental overwrites of ACE's current Makefiles by +dnl the automatically generated ones, for example. +dnl ACE_CHECK_FOR_CVS_DIR + +dnl Prevent the configure script from continuing any further if +dnl configuration is being performed in the top-level directory. The +dnl idea is to prevent files generated during configuration and build +dnl from overwriting the stock files of the same name. +ACE_CHECK_TOP_SRCDIR + +dnl Prepare the `ace/config.h.in' header template. +ACE_PREP_CONFIG_HEADER + +dnl Allow the standard program name transformations. +dnl We probably don't need AC_ARG_PROGRAM any longer since AM_INIT_AUTOMAKE +dnl handles this functionality. -- Ossama +dnl AC_ARG_PROGRAM + +dnl Generate a header file with all settings. +AC_CONFIG_HEADERS([ace/config.h]) + +dnl Move before the AC_ARG_ENABLE stuff to prevent autoconf complaints. +dnl This is a bit messy but it makes life easier for me. +dnl -Ossama +dnl +dnl SECTION: checks for programs +dnl + +dnl Check if system supports "#! /bin/sh" line in scripts +AC_SYS_INTERPRETER + +dnl Check the C compiler and preprocessor. +dnl AC_PROG_CC +dnl AC_PROG_CPP +dnl AC_PROG_CC_C_O + +dnl Check the C++ compiler and preprocessor. +AC_PROG_CXX +AC_PROG_CXXCPP + +dnl Set the test language as C++ +AC_LANG([C++]) + +dnl If we are cross compiling disable certain things in the Makefiles. +AM_CONDITIONAL([ACE_CROSS_COMPILED], [test X$cross_compiling = Xyes]) + +dnl Look for the best awk-style program available. +AC_PROG_AWK + +dnl Parse the version information argument. +dnl Note that "ACE_VERSION" is an m4 macro. +ace_version_temp=ACE_VERSION +ace_save_ifs="$IFS"; IFS='.' +set dummy $ace_version_temp 0 0 0 +IFS="$ace_save_ifs" + +ACE_MAJOR=$2 +ACE_MINOR=$3 +ACE_BETA=$4 +ACE_VERSION_NAME=ACE_VERSION + +AC_SUBST([ACE_MAJOR]) +AC_SUBST([ACE_MINOR]) +AC_SUBST([ACE_BETA]) +AC_SUBST([ACE_VERSION_NAME]) + +dnl Do the usual install settings; don't forget to include a +dnl `install-sh' script, in case there is no BSD compatible `install' +dnl installed (no pun intended) in your machine. + +dnl We don't need this anymore since AM_INIT_AUTOMAKE calls AC_PROG_INSTALL. +dnl -- Ossama +dnl AC_PROG_INSTALL + +dnl Special handling for some UNIX variants and Cygwin32 +dnl AC_AIX + +dnl AC_MINIX + +case $host_os in + *cygwin* ) CYGWIN=yes;; + * ) CYGWIN=no;; +esac + + +dnl Check if we support symbolic links +AC_PROG_LN_S + +dnl Check if a lexical analyzer exists (lex, flex, etc.) +AM_PROG_LEX + +dnl Check if some implementation of YACC exists (yacc, byacc, bison, etc.) +AC_PROG_YACC +dnl if test -z "$YACC"; then +dnl ./missing yacc +dnl fi + +dnl Check for perfect hash function generator +AC_CHECK_PROG([GPERF],[gperf],[gperf]) + +dnl Check for profiling progam +AC_CHECK_PROGS([PROF],[gprof prof],) + +dnl The user's/default C++ flags are stored in "CXXFLAGS." We use +dnl the variable "ACE_CXXFLAGS" to set the C++ flags we want. At the end +dnl of the configuration process we combine ACE_CXXFLAGS and CXXFLAGS +dnl into CXXFLAGS (e.g., CXXFLAGS="$ACE_CXXFLAGS $CXXFLAGS"). CXXFLAGS +dnl goes after ACE_CXXFLAGS so that the user's C++ flag command line +dnl choices always override the configure script's choices. +ACE_CXXFLAGS="" +ACE_CFLAGS="" + + + +dnl SECTION 2: Configure script command line options + + +dnl Determine which subsets to build +dnl This is done using the autoconf "--enable-foobar" mechanism. +ACE_CHECK_SUBSETS + +dnl Some of the third party libraries (X11, openssl, etc.) depend on +dnl other libraries. Check for those before the processing --enable +dnl options. + +dnl Check if the socket library is available +AC_SEARCH_LIBS([socket],[socket],,,[-lnsl]) + +dnl Check for gethostbyname in -lnsl since some platforms (e.g. Solaris) +dnl put it there. +AC_SEARCH_LIBS([gethostbyname],[nsl],,) + + +dnl Add --{enable,disable,with,without}-feature options. +ACE_CONFIGURATION_OPTIONS +ACE_COMPILATION_OPTIONS + +# Autoconf's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +# Libtool's setup macro calls AC_OBJEXT and AC_EXEEXT without setting +# the test language to C. We do it before any libtool setup macros are +# called so that the proper values are cached beforehand. We also do +# it before any linker flags (LDFLAGS) are set so that C++ specific +# ones don't break the tests. +dnl AC_LANG_PUSH([C]) +dnl AC_OBJEXT +dnl AC_EXEEXT +dnl AC_LANG_POP([C]) + +dnl Call ACE_SET_COMPILER_FLAGS before AC_PROG_LIBTOOL and after the +dnl AC_ARG_ENABLE and AC_ARG_WITH calls. +ACE_SET_COMPILER_FLAGS + + +dnl SECTION 3: check for programs <--- moved before section 2 (Ossama) + + +dnl Platform specific libraries needed for ACE's autoconf tests +dnl that currently do not have tests themselves. +dnl Platform specific flags +case "$host" in + *osf3.2*) + LIBS="$LIBS -lmach -lsys5 -lcxx -lc" + ;; + *osf4.0* | *osf5.0*) + LIBS="$LIBS -lmach" + ;; + *psos*) + LIBS="$LIBS -lm" + ;; +esac + + +dnl SECTION 4: checks for libraries + + +dnl Additional X library checks +dnl We only check for these libraries if the user has +dnl enabled XtReactor support. + +xt_reactor_go=no + +if test "$ace_user_enable_xt_reactor" = yes; then +XTREACTOR_TEST_XLIBS="" +dnl Check for Motif if we have X + T_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $X_LIBS" + +dnl Note that ACE currently only needs -lX11 and -lXt for the XtReactor +dnl so we define another library variable that contains additional +dnl libraries for the XtReactor test since it needs either Motif or the +dnl Athena widget set. + + AC_CHECK_LIB([Xm],[XmCreateRowColumn], + [ + AC_DEFINE([ACE_HAS_XT]) + XTREACTOR_TEST_XLIBS="-lXm" + xt_reactor_go=yes + ], + [ + AC_DEFINE([ACE_LACKS_MOTIF]) + AC_CHECK_LIB([Xaw],[XawInitializeWidgetSet], + [ + AC_DEFINE([ACE_HAS_XT]) + XTREACTOR_TEST_XLIBS="-lXaw -lXmu" + xt_reactor_go=yes + ], + [ + xt_reactor_go=no + AC_MSG_WARN([No usable X widget libraries were found.]) + AC_MSG_WARN([XtReactor support will be disabled.]) + ],[-lXmu]) + ],[-lXt]) + + AC_SUBST([XTREACTOR_TEST_XLIBS]) + +dnl Restore pre-test linker flags + LDFLAGS="$T_LDFLAGS" + +fi dnl test "$ace_user_enable_xt_reactor"= yes + + AM_CONDITIONAL([COMPILE_XTREACTOR_TEST],[test X$xt_reactor_go = Xyes]) + +dnl End additional X library checks + +dnl Some platforms do not have a dynamic linking library, however the +dnl dlopen, dlclose, etc., functions may exist in the C library. +dnl (e.g. Digital UNIX) +dnl Check for dynamic linking library +AC_SEARCH_LIBS([dlopen],[dl svld],[ace_has_svr4_dynamic_linking=yes], + [ + ace_has_svr4_dynamic_linking=no + AC_CHECK_LIB([dld],[shl_get],,) + ]) + +dnl Check for getservbyname in -lxnet since some platforms (e.g. Solaris) +dnl may put it there. +AC_SEARCH_LIBS([getservbyname],[socket xnet],,[AC_DEFINE([ACE_LACKS_GETSERVBYNAME])],[-lnsl]) + +dnl Check for compile() regex function in -lgen. Solaris, for example, +dnl may put it there. +AC_SEARCH_LIBS([compile],[gen],,) + +dnl Check for exception handling library (e.g. for Digital UNIX) +AC_SEARCH_LIBS([exc_continue],[exc],,) + +dnl Check for ctime_r in -lc_r. Some platforms, such as Digital UNIX, +dnl put reentrant functions such as asctime_r, ctime_r, gmtime_r, and +dnl localtime_r in -lc_r. +AC_SEARCH_LIBS([ctime_r],[c_r],,) + +dnl XTI/TLI check. Check for XTI first, since it's preferred. If there's +dnl no XTI, try for TLI. t_getprotaddr() is only in XTI. +AC_SEARCH_LIBS([t_getprotaddr],[xti nsl], + [ace_has_xti_funcs=yes],[ace_has_xti_funcs=no]) +AS_IF([test "$ace_has_xti_funcs" = no], + [ + AC_SEARCH_LIBS([t_accept],[tli_r tli nsl], + [ace_has_tli_funcs=yes],[ace_has_tli_funcs=no]) + ],[]) + +dnl Check for all of the things we need to compile and link threads +dnl properly. +AS_IF([test "$ace_user_enable_threads" = yes], + [ + ACE_CHECK_THREADS + ],[]) + +dnl Setup Libtool + +dnl This should be done in the "programs" section of this file but +dnl libtool may then be unaware of compiler flags set during the +dnl thread checks. + +dnl Disable building of static libraries by default +AC_DISABLE_STATIC + +dnl Enable Libtool module support +AC_LIBTOOL_DLOPEN + +dnl Enable support for "clean" DLLs. +AC_LIBTOOL_WIN32_DLL + +dnl +dnl ###### Relies on the as of yet unreleased Libtool 1.6 distribuion ### +dnl +dnl Only enable C++ libtool support. Support for other languages is +dnl unnecessary. +dnl AC_LIBTOOL_TAGS([CXX]) + +dnl FIXME: Temporary hack to make libtool work with g++. +dnl Shared library support will only work with GNU g++ and GNU ld +dnl right now. +dnl save_CC="$CC" +dnl CC="$CXX" + +dnl Check for libtool and turn on Automake processing for Libtool +AC_PROG_LIBTOOL + +dnl Enable C++ support in libtool +dnl AC_LIBTOOL_CXX + +dnl Temporary hack until I get integrate libtool's new tag support +dnl into automake. +dnl This hack forces libtool to always use the C++ tag. +dnl LIBTOOL="$LIBTOOL --tag=CXX" + +dnl Check for sched_yield() in posix4 library. +dnl Some platforms, such as Solaris, may define sched_yield() there. +dnl Later we run AC_CHECK_FUNC(sched_yield), which is redundant in this case +dnl but is needed if sched_yield() is defined in one of the other libraries +dnl we check for. +AC_SEARCH_LIBS([sched_yield],[rt posix4],[ace_has_sched_yield=yes],) + +dnl Check for asynchronous IO calls (perform check *after* thread check!) +ACE_CHECK_ASYNCH_IO + +dnl Additional `-lposix4' library check since it may not be added by the +dnl above checks on some platforms that may need it +dnl AC_SEARCH_LIBS([clock_gettime], +dnl [rt posix4],[AC_DEFINE(ACE_HAS_CLOCK_GETTIME)],) + +dnl This check was added to work around a system-supplied header +dnl (/usr/include/netinet/ip.h) that won't compile with Visual Age C++ +dnl unless the _NO_BITFIELDS preprocessor macro is defined. The comments +dnl there recommend use of _NO_BITFIELDS (and recode where needed to allow +dnl that), but we won't just turn it on. Check to see if it's needed. Note +dnl that this check is related to headers but done before we really know if +dnl the header is present. Thus, if the bare compile fails, but succeeds +dnl with _NO_BITFIELDS, set the flag, else leave things alone. + +AC_CACHE_CHECK([to see if _NO_BITFIELDS needed to compile netinet/ip.h], +[ac_cv_needs_no_bitfields], +[ + ace_save_CXXFLAGS="$CXXFLAGS" + + dnl Try compiling without any flags first. + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ +#include + ], + [ + return 0; + ]) + ], + [ + ac_cv_needs_no_bitfields=no + ], + [ + CXXFLAGS="$CXXFLAGS -D_NO_BITFIELDS" + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ +#include + ], + [ + return 0; + ]) + ], + [ + ac_cv_needs_no_bitfields=yes + ], + [ + ac_cv_needs_no_bitfields=no + CXXFLAGS="$ace_save_CXXFLAGS" + ]) + ]) +]) + + +dnl SECTION 5: checks for header files + +dnl Set known platform specific flags +ACE_SET_PLATFORM_MACROS + +dnl Check for dirent headers +AC_HEADER_DIRENT + +AS_IF([test "$ac_cv_header_dirent_dirent_h" = yes || + test "$ac_cv_header_dirent_sys_ndir_h" = yes || + test "$ac_cv_header_dirent_sys_dir_h" = yes || + test "$ac_cv_header_dirent_ndir_h" = yes], + [ + AC_DEFINE([ACE_HAS_DIRENT]) + ],[]) + +dnl Check for sys/wait.h Posix.1 compliance +AC_HEADER_SYS_WAIT + +AC_CHECK_HEADER([dlfcn.h], + [ + dnl We already checked for dlopen in the previous library checks however, + dnl it is possible that ac_cv_func_dlopen=yes if dlopen wasn't found before + dnl the library test. Hence we cannot use AC_CHECK_FUNC(dlopen) here + dnl the previously cached value may prevent ACE_HAS_SVR4_DYNAMIC_LINKING + dnl from being defined. + dnl -Ossama + AS_IF([test "$ace_has_svr4_dynamic_linking" = yes], + [ + AC_DEFINE([ACE_HAS_SVR4_DYNAMIC_LINKING]) + + case "$host_os" in + darwin*) + AC_DEFINE([ACE_LD_SEARCH_PATH], + [ACE_LIB_TEXT ("DYLD_LIBRARY_PATH")], + [Define to environment variable used for DLL search path]) + AC_DEFINE([ACE_DLL_SUFFIX], + [ACE_LIB_TEXT (".dylib")], + [Define to DLL file suffix]) + ;; + esac + ],[]) + ],) + +ACE_CHECK_LACKS_HEADERS(inttypes.h malloc.h memory.h stdint.h) + +ACE_CHECK_HAS_HEADERS(bytesex.h) + +AC_CHECK_HEADER([sys/msg.h], + [ + ACE_CACHE_CHECK([if _KERNEL is needed for msg prototypes], + [ace_cv_lib_broken_msg_h], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef UNIXWARE_7_1 +# define _KMEMUSER +#endif + +#include + ]],[[ + struct msg ace_msg; + ]])],[ + ace_cv_lib_broken_msg_h=no + ],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef _KERNEL +# define _KERNEL +# ifdef UNIXWARE_7_1 +# define _KMEMUSER +# endif +#endif +#include + ]], + [[ + struct msg ace_msg; + ]])], + [ + ace_cv_lib_broken_msg_h=yes + ], + [ + dnl If we get here, then we have no idea if it is broken or not. + ace_cv_lib_broken_msg_h=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_BROKEN_MSG_H]) + ],) + ], + [AC_DEFINE([ACE_LACKS_SYS_MSG_H])]) + +AC_CHECK_HEADER([sys/sem.h],,) +AC_CHECK_HEADER([sys/shm.h],,) + +ACE_CHECK_LACKS_HEADERS(sys/param.h) + +AC_CHECK_HEADER([sys/priocntl.h],[],[]) + +dnl Check for _before_ +ACE_CHECK_LACKS_HEADERS(ucontext.h) + +AC_CHECK_HEADER([sys/procfs.h], + [ + dnl Check if conflicts with + dnl Some (early?) versions of glibc2.1 define the same variables + dnl in and . + ACE_CACHE_CHECK([if sys/procfs.h conflicts with ucontext.h], + [ace_cv_has_procfs_conflict], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_UCONTEXT_H +# include +#endif + +#include + ]],[[ + int a = 0; + ]])],[ + ace_cv_has_procfs_conflict=no + ],[ + ace_cv_has_procfs_conflict=yes + ]) + ], + [ + ], + [ + dnl If ace_cv_has_procfs_conflict = no then define ACE_HAS_PROC_FS. + AC_DEFINE([ACE_HAS_PROC_FS]) + ]) + ],) + +ACE_CHECK_LACKS_HEADERS(arpa/inet.h) + +ACE_CHECK_HAS_HEADERS(byteswap.h) + +ACE_CHECK_LACKS_HEADERS(dirent.h) + +ACE_CHECK_LACKS_HEADERS(dlfcn.h) + +ACE_CHECK_LACKS_HEADERS(errno.h) + +ACE_CHECK_LACKS_HEADERS(execinfo.h) + +ACE_CHECK_LACKS_HEADERS(fcntl.h) + +ACE_CHECK_HAS_HEADERS(pdh.h) + +ACE_CHECK_HAS_HEADERS(pthread_np.h) + +ACE_CHECK_LACKS_HEADERS(sched.h) + +ACE_CHECK_LACKS_HEADERS(search.h) + +ACE_CHECK_HAS_HEADERS(select.h) + +ACE_CHECK_LACKS_HEADERS(semaphore.h) + +ACE_CHECK_LACKS_HEADERS(signal.h) + +ACE_CHECK_LACKS_HEADERS(stdlib.h) + +ACE_CHECK_LACKS_HEADERS(string.h) + +ACE_CHECK_LACKS_HEADERS(strings.h) + +ACE_CHECK_LACKS_HEADERS(netdb.h) + +ACE_CHECK_LACKS_HEADERS(netinet/in.h) + +ACE_CHECK_LACKS_HEADERS(netinet/tcp.h) + +ACE_CHECK_LACKS_HEADERS(sys/socket.h) + +ACE_CHECK_LACKS_HEADERS(net/if.h, [], [], +[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#ifndef ACE_LACKS_SYS_SOCKET_H +# include +# endif +]) + +ACE_CHECK_HAS_HEADERS(sys/filio.h) + +ACE_CHECK_HAS_HEADERS(intrin.h) + +ACE_CHECK_HAS_HEADERS(ia64intrin.h) + +ACE_CHECK_HAS_HEADERS(ia32intrin.h) + +ACE_CHECK_LACKS_HEADERS(sys/ioctl.h) + +ACE_CHECK_LACKS_HEADERS(sys/ipc.h) + +ACE_CHECK_HAS_HEADERS(sys/loadavg.h) + +ACE_CHECK_LACKS_HEADERS(sys/mman.h) + +ACE_CHECK_HAS_HEADERS(sys/pstat.h) + +ACE_CHECK_LACKS_HEADERS(sys/resource.h) + +ACE_CHECK_LACKS_HEADERS(sys/sem.h) + +ACE_CHECK_LACKS_HEADERS(sys/shm.h) + +ACE_CHECK_LACKS_HEADERS(sys/select.h) + +ACE_CHECK_HAS_HEADERS(sys/sockio.h) + +ACE_CHECK_LACKS_HEADERS(sys/stat.h) + +dnl Test for out of alphabetical order, since it must +dnl be (conditionally) #included in other feature tests. +ACE_CHECK_LACKS_HEADERS(sys/types.h) + +ACE_CHECK_LACKS_HEADERS(sys/sysctl.h, [], [], +[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#ifndef ACE_LACKS_SYS_PARAM_H +# include +#endif +]) + +ACE_CHECK_HAS_HEADERS(sys/sysinfo.h) + +ACE_CHECK_HAS_HEADERS(sys/systeminfo.h) + +ACE_CHECK_LACKS_HEADERS(sys/time.h) + +ACE_CHECK_LACKS_HEADERS(sys/uio.h) + +ACE_CHECK_LACKS_HEADERS(sys/un.h) + +ACE_CHECK_LACKS_HEADERS(sys/wait.h) + +ACE_CHECK_HAS_HEADERS(sysent.h) + +ACE_CHECK_LACKS_HEADERS(time.h) + +ACE_CHECK_LACKS_HEADERS(termio.h termios.h) + +ACE_CHECK_LACKS_HEADERS(wctype.h) + +AC_CHECK_HEADER([sys/systeminfo.h],[],[]) + +AC_CHECK_TYPE([struct termio], + [AC_DEFINE([ACE_HAS_TERMIO], 1, + [Define to 1 if system supports SysV tty API.])], + [], + [ +#ifndef ACE_LACKS_TERMIO_H +#include +#endif + ]) + +AC_CHECK_TYPE([struct termios], + [AC_DEFINE([ACE_HAS_TERMIOS], 1, + [Define to 1 if system supports POSIX tty API.])], + [], + [ +#ifndef ACE_LACKS_TERMIOS_H +#include +#endif + ]) + +dnl If the platform has XTI, don't bother with the TLI checks as XTI is +dnl preferred. +AS_IF([test "$ace_has_xti_funcs" = yes], + [ + AC_CHECK_HEADER([xti.h], + [ + ace_has_xti=yes + AC_DEFINE([ACE_HAS_XTI]) + ],) + + AC_CHECK_HEADER([sys/xti.h], + [ + ace_has_xti=yes + AC_DEFINE([ACE_HAS_SYS_XTI_H]) + AC_DEFINE([ACE_HAS_XTI]) + ],) + + AC_CHECK_HEADER([sys/timod.h], + [ + AC_DEFINE([ACE_HAS_TIMOD_H]) + ],) + +dnl Check if XTI headers define TCP macros that conflict with netinet/tcp.h's + ACE_CACHE_CHECK([if TCP macros in sys/xti.h conflict with netinet/tcp.h], + [ace_cv_lib_has_conflicting_xti_macros], + [ + ACE_CONVERT_WARNINGS_TO_ERRORS([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# if defined (ACE_HAS_XTI) +# include +# if defined (ACE_HAS_SYS_XTI_H) +# include /**/ +# else +# include /**/ +# endif /* ACE_HAS_SYS_XTI_H */ +# else +# if defined (ACE_HAS_TIUSER_H) +# include /**/ +# endif +# endif /* ACE_HAS_XTI */ +# if !defined (ACE_LACKS_NETINET_TCP_H) +# include /**/ +# endif /* !ACE_LACKS_NETIINET_TCP_H */ + ]],[[ + int a = 0; + ]])],[ + ace_cv_lib_has_conflicting_xti_macros=no + ],[ + ace_cv_lib_has_conflicting_xti_macros=yes + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_CONFLICTING_XTI_MACROS]) + ],) + + ],[]) + +AS_IF([test "$ace_has_tli_funcs" = yes], + [ + AC_CHECK_HEADER([tiuser.h], + [ + ace_has_tli=yes + AC_DEFINE([ACE_HAS_TIUSER_H]) + AC_DEFINE([ACE_HAS_TLI]) + ],) + + AC_CHECK_HEADER([sys/timod.h], + [ + AC_DEFINE([ACE_HAS_TIMOD_H]) + ], + [ + AC_CHECK_HEADER([tli/timod.h], + [ + AC_DEFINE([ACE_HAS_OSF_TIMOD_H]) + ],) + ]) + + AC_CHECK_FUNC([t_getname], + [AC_DEFINE([ACE_HAS_SVR4_TLI])],) + + +if test "$ac_cv_header_tiuser_h" = yes; then + ACE_CACHE_CHECK([if tiuser.h is protected by extern "C"], + [ace_cv_lib_tiuser_with_extern_c],[ + AC_EGREP_HEADER([extern \"C\"],[tiuser.h], + [ + ace_cv_lib_tiuser_with_extern_c=yes + ], + [ + ace_cv_lib_tiuser_with_extern_c=no + ]) + ],,[AC_DEFINE([ACE_HAS_TIUSER_H_BROKEN_EXTERN_C])]) +fi dnl test "$ac_cv_header_tiuser_h" = yes + +AC_CHECK_HEADER([xliuser.h], + [ + ace_has_tli=yes + AC_DEFINE([ACE_HAS_XLI]) + AC_DEFINE([ACE_HAS_TLI]) + ],) + + +dnl Check for TLI prototypes. +if test "$ace_has_tli" = yes; then + ACE_CACHE_CHECK([for TLI prototypes], + [ace_cv_lib_tli_prototypes], + [ +dnl We only check for t_accept. This should hopefully be enough. + AC_EGREP_CPP([t_accept], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif + +#if defined (ACE_HAS_TIMOD_H) +# include +#endif + +#if defined (ACE_HAS_OSF_TIMOD_H) +# include +#endif + +#if defined (ACE_HAS_TIUSER_H) +# include /**/ +#endif /* ACE_HAS_TIUSER_H */ + +#if defined (ACE_HAS_XLI) +# include +#endif + ], + [ + ace_cv_lib_tli_prototypes=yes + ], + [ + ace_cv_lib_tli_prototypes=no + ]) + ],[AC_DEFINE([ACE_HAS_TLI_PROTOTYPES])],) + +dnl Check for t_errno type in TLI headers + ACE_CACHE_CHECK([for t_errno in TLI headers], + [ace_cv_lib_has_t_errno], + [ + dnl Check if t_errno is declared in the TLI headers + AC_EGREP_CPP([t_errno], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif + +#if defined (ACE_HAS_TIMOD_H) +# include +#endif + +#if defined (ACE_HAS_OSF_TIMOD_H) +# include +#endif + +#if defined (ACE_HAS_TIUSER_H) +# include /**/ +#endif /* ACE_HAS_TIUSER_H */ + +#if defined (ACE_HAS_XLI) +# include +#endif + ], + [ + ace_cv_lib_has_t_errno=yes + ], + [ + ace_cv_lib_has_t_errno=no + ]) + ],,[AC_DEFINE([ACE_LACKS_T_ERRNO])]) + +fi dnl test "$ace_has_tli_funcs" = yes +],[]) + +dnl These checks are needed for both XTI and TLI. +AS_IF([test "$ace_has_xti" = yes || test "$ace_has_tli" = yes], + [ + dnl Check if t_error incorrectly accepts char * + ACE_CONVERT_WARNINGS_TO_ERRORS([ + ACE_CACHE_CHECK([if t_error incorrectly accepts char *], + [ace_cv_lib_has_broken_t_error], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif + +#if defined (ACE_HAS_XTI) +# if defined (ACE_HAS_SYS_XTI_H) +# include +# else +# include +# endif /* ACE_HAS_SYS_XTI_H */ +#elif defined (ACE_HAS_TIUSER_H) +# include /**/ +#endif /* ACE_HAS_TIUSER_H */ + +#if defined (ACE_HAS_XLI) +# include +#endif + ]],[[ + const char *ace_errmsg = "FOO"; + t_error (ace_errmsg); + ]])],[ + ace_cv_lib_has_broken_t_error=no + ],[ + ace_cv_lib_has_broken_t_error=yes + ]) + ], + [ + AC_DEFINE([ACE_HAS_BROKEN_T_ERROR]) + ],) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + + ],[]) + +dnl See the notes about ACE_LACKS_MMAP in the functions section of this +dnl configure script. +dnl -Ossama +AC_CHECK_HEADER([sys/mman.h], + [ + AC_EGREP_HEADER([extern \"C\"],[sys/mman.h], + , + [ + AC_DEFINE([ACE_HAS_BROKEN_MMAP_H]) + ]) + ], + [ + AC_DEFINE([ACE_LACKS_MMAP]) + ]) + +dnl Check for bzero() prototype if bstring.h exists. +AC_CHECK_HEADER([bstring.h], + [ + AC_EGREP_HEADER([bzero],[bstring.h], + [ + AC_DEFINE([ACE_HAS_BSTRING]) + ],) + ],) + +AC_CHECK_HEADER([strings.h], + [ + AC_EGREP_HEADER([bzero],[strings.h], + [ + AC_DEFINE([ACE_HAS_STRINGS]) + ],) + ],) + +ACE_CHECK_HAS_HEADERS(sys/syscall.h) + +AC_CHECK_HEADER([poll.h], + [AC_DEFINE([ACE_HAS_POLL])],) + +ACE_CHECK_LACKS_HEADERS(pwd.h) + +AC_CHECK_HEADER([regexpr.h], + [AC_DEFINE([ACE_HAS_REGEX])],) + +AC_CHECK_HEADER([stropts.h], + [AC_DEFINE([ACE_HAS_STREAMS])], + [AC_DEFINE([ACE_LACKS_STROPTS_H])]) + +ACE_CHECK_LACKS_HEADERS(siginfo.h) + +ACE_CHECK_LACKS_HEADERS(unistd.h) + +ACE_CHECK_LACKS_HEADERS(utime.h) + +ACE_CHECK_LACKS_HEADERS(wchar.h) + +AC_CHECK_HEADER([wchar.h], + [AC_DEFINE([ACE_HAS_WCHAR])],) + +AC_CHECK_HEADER([new], + [AC_DEFINE([ACE_HAS_NEW_NO_H])], + [ + ACE_CHECK_HAS_HEADERS([new.h]) + ]) + +dnl ace/OS.i can #include ,not #include +dnl "cstring" is the correct form. +dnl TODO: Double check the above comment. +AC_CHECK_HEADER([cstring], + [AC_DEFINE([ACE_HAS_GNU_CSTRING_H])],) + +AC_CHECK_HEADER([memory],,) + +dnl Check for availablity of "new style" C++ stream headers +AC_CHECK_HEADERS([iomanip ios iostream istream ostream fstream streambuf], + , + [AC_CHECK_HEADERS([iostream.h fstream.h], + [AC_DEFINE([ACE_USES_OLD_IOSTREAMS])], + [AC_DEFINE([ACE_LACKS_IOSTREAM_TOTALLY])])]) + +dnl Check for old malloc() prototype. +ACE_CONVERT_WARNINGS_TO_ERRORS([ +ACE_CACHE_CHECK([for old malloc() prototype], + [ace_cv_lib_old_malloc_proto], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifndef ACE_LACKS_MALLOC_H +# include +#endif + ]],[[ + char *s = 0; + s = malloc(sizeof(int)); + ]])],[ + ace_cv_lib_old_malloc_proto=yes + ],[ + ace_cv_lib_old_malloc_proto=no + ]) + ],[AC_DEFINE([ACE_HAS_OLD_MALLOC])],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + + +dnl Check for *_timedwait() prototypes +dnl TODO: We only check for one of the *_timedwait() prototypes. +dnl Is this enough? +AC_CHECK_DECL([recv_timedwait], + [], + [AC_DEFINE([ACE_LACKS_TIMEDWAIT_PROTOTYPES], 1, + [Define to 1 if platform lacks the declarations + of recv_timedwait, send_timedwait, etc.])], + [#include + #include ]) + +dnl Check for {get,set}rlimit prototypes +AC_CHECK_DECL([getrlimit],[],[],[#include ]) +AC_CHECK_DECL([setrlimit],[],[],[#include ]) +if test "$ac_cv_have_decl_getrlimit" != yes || + test "$ac_cv_have_decl_setrlimit" != yes; then + AC_DEFINE([ACE_LACKS_RLIMIT_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration of + {get,set}rlimit().]) +fi + + +dnl SECTION 6: Checks for typedefs + +dnl dnl Standard typedef checks (All of them may not be needed) +dnl AC_TYPE_UID_T +dnl AC_TYPE_MODE_T +dnl AC_TYPE_OFF_T +dnl AC_TYPE_PID_T +dnl AC_TYPE_SIZE_T + +dnl AC_CHECK_TYPE([off64_t],[long long]) + +dnl Specific typedef checks +dnl TODO: Check whether these typedefs can be defined somewhere else. +AC_CHECK_TYPE([cpu_set_t], + [AC_DEFINE([ACE_HAS_CPU_SET_T], 1, + [Define to 1 if the system has the type `cpu_set_t'.])], + [], + [ +#if !defined(ACE_LACKS_SCHED_H) +#include +#endif + ]) + +AC_CHECK_TYPE([idtype_t], + [AC_DEFINE([ACE_HAS_IDTYPE_T], 1, + [Define to 1 if the system has the type `idtype_t'.])], + [], + [#include ]) + +AC_CHECK_TYPE([key_t], + [], + [AC_DEFINE([ACE_LACKS_KEY_T], 1, + [Define to 1 if the system lacks the type `key_t'.])], + [#include ]) + +ACE_CHECK_TYPE([sem_t],[semaphore.h],,) + +AC_CHECK_TYPE([pri_t], + [], + [AC_DEFINE([ACE_LACKS_PRI_T], 1, + [Define to 1 if the system lacks the type 'pri_t'.])], + [#include ]) + +AC_CHECK_TYPE([sig_atomic_t], + [AC_DEFINE([ACE_HAS_SIG_ATOMIC_T], 1, + [Define to 1 if the system has the type 'sig_atomic_t'.])], + [], + [#include ]) + +AC_CHECK_TYPE([union sigval], + [], + [], + [#include ]) + +if test "$ac_cv_type_union_sigval" = yes; then + dnl Depending on the system, the field names of union sigval have + dnl either a sival_ (POSIX) or sigval_ (older versions of FreeBSD) + dnl prefix. Define ACE_HAS_SIGVAL_SIGVAL_INT accordingly. + AC_CHECK_MEMBER([union sigval.sigval_int], + [AC_DEFINE([ACE_HAS_SIGVAL_SIGVAL_INT], 1, + [Define to 1 if `sigval_int' is a member of `union sigval'.])], + [], + [#include ]) + + dnl Depending on the system, the field names of union sigval have + dnl either a sival_ (POSIX) or sigval_ (older versions of FreeBSD) + dnl prefix. Define ACE_HAS_SIGVAL_SIGVAL_PTR accordingly. + AC_CHECK_MEMBER([union sigval.sigval_ptr], + [AC_DEFINE([ACE_HAS_SIGVAL_SIGVAL_PTR], 1, + [Define to 1 if `sigval_ptr' is a member of `union sigval'.])], + [], + [#include ]) +fi + +AC_CHECK_TYPE([ssize_t], + [AC_DEFINE([ACE_HAS_SSIZE_T], 1, + [Define to 1 if the system has the type `ssize_t'.])], + [], + [#include ]) + +AC_CHECK_TYPE([suseconds_t], + [], + [AC_DEFINE([ACE_LACKS_SUSECONDS_T], 1, + [Define to 1 if the system lacks the type 'suseconds_t'.])], + [#include ]) + +AC_CHECK_TYPE([useconds_t], + [], + [AC_DEFINE([ACE_LACKS_USECONDS_T], 1, + [Define to 1 if the system lacks the type 'useconds_t'.])], + [#include ]) + + +dnl Some platforms define ucontext_t in , but ACE +dnl doesn't explicitly include that header. However, it is very +dnl likely that does, either directly or indirectly. +AC_CHECK_TYPE([ucontext_t], + [AC_DEFINE([ACE_HAS_UCONTEXT_T], 1, + [Define to 1 if the system has the type `ucontext_t'.])], + [], +[#include +#ifndef ACE_LACKS_UCONTEXT_H +# include +#endif +]) + +AC_CHECK_TYPE([u_longlong_t], + [], + [AC_DEFINE([ACE_LACKS_U_LONGLONG_T], 1, + [Define to 1 if the system lacks the type `u_long_long_t'.])], + [#include ]) + +AC_CHECK_TYPE([wchar_t], + [], + [AC_DEFINE([ACE_LACKS_WCHAR_T], 1, + [Define to 1 if the system lacks the type `wchar_t'.])], +[#include +#include +]) + +AC_CHECK_TYPE([socklen_t], + [AC_DEFINE([ACE_HAS_SOCKLEN_T], 1, + [Define to 1 if the system has the type `socklen_t'.])], + [], +[ +#ifndef ACE_LACKS_SYS_TYPES_H +#include +#endif +#ifndef ACE_LACKS_SYS_SOCKET_H +#include +#endif +]) + +if test $ac_cv_type_socklen_t = no; then + dnl The compiler in linux just issues a warning, and the test + dnl passes!!! + + dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ + dnl -Ossama + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ + dnl Check if socket size is denoted by size_t + ACE_CACHE_CHECK([if socket size is denoted by size_t], + [ace_cv_lib_posix_socket_len_size_t],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#ifndef ACE_LACKS_SYS_SOCKET_H +# include +#endif + ]],[[ + int s = 0; + struct sockaddr* addr = 0; + int* addrlen = 0; + accept(s, addr, addrlen); + ]])],[ + ace_cv_lib_posix_socket_len_size_t=no + ],[ + dnl Now see if it really does take a size_t socket size + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#ifndef ACE_LACKS_SYS_SOCKET_H +# include +#endif + ]], + [[ + int s = 0; + struct sockaddr* addr = 0; + size_t* addrlen = 0; + accept(s, addr, addrlen); + ]])], + [ + ace_cv_lib_posix_socket_len_size_t=yes + ], + [ + ace_cv_lib_posix_socket_len_size_t=no + ]) + ]) + ],[AC_DEFINE([ACE_HAS_SIZET_SOCKET_LEN])],) + ]) +fi + + +dnl SECTION 7: checks for structures + + +dnl TODO: Check whether these structures can be defined somewhere else. +ACE_CHECK_STRUCT([dirent],[dirent.h],,[AC_DEFINE([ACE_LACKS_STRUCT_DIR])]) +ACE_CHECK_STRUCT([flock],[fcntl.h],,[AC_DEFINE([ACE_LACKS_FILELOCKS])]) +ACE_CHECK_STRUCT([rwlock_t],[synch.h],,[AC_DEFINE([ACE_LACKS_RWLOCK_T])]) +ACE_CHECK_STRUCT([strbuf],[stropts.h],[AC_DEFINE([ACE_HAS_STRBUF_T])],) +case "$host" in +*irix*) + dnl IRIX prusage fields don't match what ACE currently supports. + ;; +*) + ACE_CHECK_STRUCT([prusage_t],[sys/procfs.h],[AC_DEFINE([ACE_HAS_PRUSAGE_T])],) + ;; +esac +ACE_CHECK_STRUCT([strrecvfd],[stropts.h],,[AC_DEFINE([ACE_LACKS_STRRECVFD])]) +ACE_CHECK_STRUCT([sigaction],[signal.h],,[AC_DEFINE([ACE_LACKS_SIGACTION])]) +ACE_CHECK_STRUCT([sigset_t],[signal.h],,[AC_DEFINE([ACE_LACKS_SIGSET])]) +ACE_CHECK_STRUCT([utsname],[sys/utsname.h],,[AC_DEFINE([ACE_LACKS_UTSNAME_T])]) + +ACE_CACHE_CHECK([for struct sembuf],[ace_cv_struct_sembuf], + [ + dnl Some platforms may need to include some headers before . + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]],[[ + struct sembuf ace_sembuf; + ]])],[ + ace_cv_struct_sembuf=yes + ],[ +dnl Some compilers don't like the "struct" but we need the struct for +dnl some platforms to resolve ambiguities between functions and +dnl structures with with the same name. So, we try the same test but +dnl without "struct" if the above test with "struct" fails. If both +dnl tests fail, then we can be reasonably sure that we don't have the +dnl structure we are testing for. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]], + [[ + sembuf ace_sembuf; + ]])], + [ + ace_cv_struct_sembuf=yes + ], + [ + ace_cv_struct_sembuf=no + ]) + ]) + ],,[AC_DEFINE([ACE_LACKS_SEMBUF_T])]) + +dnl Thanks to Konstantinos Margaritis for pointing out +dnl that struct siginfo_t may also be defined in signal.h +AC_CHECK_TYPE([siginfo_t], + [AC_DEFINE([ACE_HAS_SIGINFO_T], 1, + [Define to 1 if the system has the type `siginfo_t'.])], + [], + [#include +#ifndef ACE_LACKS_SIGINFO_H +#include +#endif]) + +if test "$ac_cv_type_siginfo_t" = yes; then + AC_CHECK_MEMBER([siginfo_t.si_addr], + [], + [AC_DEFINE([ACE_LACKS_SI_ADDR], 1, + [Define to 1 if `si_addr' is not a member of `siginfo_t'.])], + [#include +#ifndef ACE_LACKS_SIGINFO_H +#include +#endif]) +fi + + +dnl Some platforms need to include sys/types.h before sys/socket.h +dnl in order for struct msghdr to work. +dnl Check for msghdr structure. +ACE_CACHE_CHECK([for struct msghdr],[ace_cv_struct_msghdr], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]],[[ + struct msghdr ace_msghdr; + ]])],[ + ace_cv_struct_msghdr=yes + ],[ + ace_cv_struct_msghdr=no + ]) + ], [AC_DEFINE([ACE_HAS_MSG])],) + +ACE_CACHE_CHECK([for condition variable support],[ace_cv_struct_cond_t], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ + pthread_cond_t ace_pthread_cond_t; + ]])],[ + ace_cv_struct_cond_t=yes + ],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + cond_t ace_cond_t; + ]])], + [ + ace_cv_struct_cond_t=yes + ], + [ + ace_cv_struct_cond_t=no + ]) + ]) + ],,[AC_DEFINE([ACE_LACKS_COND_T])]) + +dnl Check for struct timespec +ACE_CACHE_CHECK([for POSIX timer structure], + [ace_cv_lib_posix_timer_struct], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if !defined(ACE_LACKS_SYS_TIME_H) +# include +#endif +#include + ]],[[ + timespec sr; + ]])],[ + ace_cv_lib_posix_timer_struct=yes + ],[ + dnl Check if platform uses struct timestruc_t for POSIX timers + dnl instead of struct timespec. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + timestruc_t sr; + ]])], + [ + ace_cv_lib_posix_timer_struct=yes + dnl Check for struct timespec in + ACE_CACHE_CHECK([for struct timespec in sys/timers.h], + [ace_cv_lib_posix_struct_timespec_broken],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + timespec sr; + ]])], + [ + ace_cv_lib_posix_struct_timespec_broken=yes + ], + [ + ace_cv_lib_posix_struct_timespec_broken=no + ]) + ],,) + ], + [ + ace_cv_lib_posix_timer_struct=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_POSIX_TIME]) + if test "$ace_cv_lib_posix_struct_timespec_broken" = yes; then + AC_DEFINE([ACE_HAS_BROKEN_POSIX_TIME]) + fi + ], + [ + dnl Check for struct timespec in + ACE_CACHE_CHECK([for struct timespec in sys/timers.h], + [ace_cv_lib_posix_struct_timespec_broken],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ + timespec sr; + ]])],[ + ace_cv_lib_posix_struct_timespec_broken=yes + ],[ + ace_cv_lib_posix_struct_timespec_broken=no + ]) + ],[AC_DEFINE([ACE_HAS_BROKEN_POSIX_TIME])],) + ]) + +dnl Check for typedef timespec_t +dnl TODO: Check whether this typedef can be defined somewhere else. +ACE_CACHE_CHECK([for timespec_t], + [ace_cv_lib_posix_timespec_t],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ + timespec_t tt; + ]])],[ + ace_cv_lib_posix_timespec_t=yes + ],[ + ace_cv_lib_posix_timespec_t=no + ]) +],,[AC_DEFINE([ACE_LACKS_TIMESPEC_T])]) + +dnl Check for union semun +ACE_CACHE_CHECK([for union semun], + [ace_cv_lib_posix_defines_union_semun],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]],[[ +/* We could also check if the macro _SEM_SEMUN_UNDEFINED is defined. + No big deal. */ + +semun us; + ]])],[ + ace_cv_lib_posix_defines_union_semun=yes + ],[ + ace_cv_lib_posix_defines_union_semun=no + ]) +],[AC_DEFINE([ACE_HAS_SEMUN])],) + + + +dnl SECTION 8: checks for variables + +dnl Check for more than two fields in struct rusage +ACE_CACHE_CHECK([for limited struct rusage], + [ace_cv_lib_limited_rusage],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + ]],[[ + rusage ace_rusage; + /* + We just pick three (i.e. > 2) of the fields that + ACE uses to see if we have a struct rusage that + has more than two fields. + */ + ace_rusage.ru_ixrss = 0; + ace_rusage.ru_idrss = 0; + ace_rusage.ru_isrss = 0; + ]])],[ + ace_cv_lib_limited_rusage=no + ],[ + ace_cv_lib_limited_rusage=yes + ]) +],[AC_DEFINE([ACE_HAS_LIMITED_RUSAGE_T])],) + +if test "$ace_cv_struct_siginfo_t" = yes; then + dnl Check for si_addr member in struct siginfo_t + ACE_CACHE_CHECK([for si_addr member in struct siginfo_t], + [ace_cv_lib_posix_si_addr],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SIGINFO_H +# include +#endif +#include + ]],[[ + siginfo_t acesig; + acesig.si_addr = 0; + ]])],[ + ace_cv_lib_posix_si_addr=yes + ],[ + ace_cv_lib_posix_si_addr=no + ]) + ],,[AC_DEFINE([ACE_LACKS_SI_ADDR])]) +fi dnl test "$ace_cv_struct_siginfo_t" = yes + +dnl Check for sin_len member in struct sockaddr_in +AC_CHECK_MEMBER([struct sockaddr_in.sin_len], + [AC_DEFINE([ACE_HAS_SOCKADDR_IN_SIN_LEN], 1, + [Define to 1 if `sin_len' is a member of `sockaddr_in'.])], + [], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]) + +dnl Check for sin6_len member in struct sockaddr_in6 +AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len], + [AC_DEFINE([ACE_HAS_SOCKADDR_IN6_SIN6_LEN], 1, + [Define to 1 if `sin6_len' is a member of `sockaddr_in6'.])], + [], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]) + +dnl Check for sys_siglist +dnl TODO: Check whether this variable can be defined somewhere else. +dnl [OSSAMA: Should we use autoconf's AC_CHECK_DECLS([sys_siglist]) +dnl test instead?] +ACE_CACHE_CHECK([for sys_siglist], + [ace_cv_lib_posix_sys_siglist],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_UNISTD_H +# include +#endif +#include +#if !defined (_sys_siglist) +# define _sys_siglist sys_siglist +#endif + ]],[[ + void* vp = (void*) &_sys_siglist; + ]])],[ + ace_cv_lib_posix_sys_siglist=yes + ],[ + ace_cv_lib_posix_sys_siglist=no + ]) +],[AC_DEFINE([ACE_HAS_SYS_SIGLIST])],) + +dnl Check for sys_errlist +dnl TODO: Check whether this variable can be defined somewhere else. +ACE_CACHE_CHECK([for sys_errlist], + [ace_cv_lib_posix_sys_errlist],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#if !defined (_sys_errlist) +# define _sys_errlist sys_errlist +#endif + ]],[[ + void* vp = (void*) &_sys_errlist; + ]])],[ + ace_cv_lib_posix_sys_errlist=yes + ],[ + dnl Check if sys_errlist is a global variable in a library + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include +#include + +#if !defined (_sys_errlist) +# define _sys_errlist sys_errlist +#endif + +extern const char * const _sys_errlist[]; + ]], + [[ + void* vp = (void*) &_sys_errlist; + ]])], + [ + ace_cv_lib_posix_sys_errlist=yes + ], + [ + ace_cv_lib_posix_sys_errlist=no + ]) + ]) + ],[AC_DEFINE([ACE_HAS_SYS_ERRLIST])],) + +dnl Save the cache for debugging purposes +AC_CACHE_SAVE + + +dnl SECTION 9: checks for compiler characteristics + + +dnl Check if compiler accepts "#pragma once" directive +ACE_CONVERT_WARNINGS_TO_ERRORS([ + ACE_CACHE_CHECK([if compiler accepts "pragma once" directive], + [ace_cv_has_pragma_once], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma once + ]],[[ + int a = 0; /* Put this here so we don't have an empty main(). */ + ]])],[ + ace_cv_has_pragma_once=yes + ],[ + ace_cv_has_pragma_once=no + ]) + ],,[AC_DEFINE([ACE_LACKS_PRAGMA_ONCE])]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl If we are using GNU C++, see if it accepts the -pipe compiler flag. +dnl "-pipe" on cygwin32 doesn't seem to work, for example. +if test "$GXX" = yes; then + PREPIPECXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -pipe" + PREPIPECFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -pipe" + ACE_CACHE_CHECK([if "-pipe" compiler flag is supported], + [ace_cv_feature_gxx_has_pipe], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[int a = 0;]])],[ + ace_cv_feature_gxx_has_pipe=yes + ],[ + ace_cv_feature_gxx_has_pipe=no + ]) + ], + [ + dnl We don't need to add "-pipe" here since it was already added + dnl for the test. + dnl CXXFLAGS="$PREPIPECXXFLAGS -pipe" + dnl CFLAGS="$PREPIPECFLAGS -pipe" + ], + [ + CXXFLAGS="$PREPIPECXXFLAGS" + CFLAGS="$PREPIPECFLAGS" + ]) +fi + +dnl Check to see if we are running on a big endian platform +dnl "ace/Basic_Types.h" should perhaps be modified to take advantage +dnl of the results of this test. +dnl Do not run this test if we are using a cross-compiler. +AS_IF([test "$cross_compiling" != yes], + [ + AC_C_BIGENDIAN + ],[]) + +dnl Check type sizes +dnl If we get a size of zero, then the type is unknown to the compiler. + +dnl We don't need to check for sizeof(char) right now. Also conflicts with +dnl ACE definition in Basic_Types.h, so we leave the test out. +if test "$cross_compiling" != yes; then + AC_CHECK_SIZEOF([wchar_t]) + if test "$ac_cv_sizeof_wchar_t" != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_WCHAR],[$ac_cv_sizeof_wchar_t], + [Size of the native "wchar_t" type]) + fi + AC_CHECK_SIZEOF([short]) + if test "$ac_cv_sizeof_short" != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_SHORT],[$ac_cv_sizeof_short], + [Size of the native "short" type]) + fi + AC_CHECK_SIZEOF([int]) + if test $ac_cv_sizeof_int != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_INT],[$ac_cv_sizeof_int], + [Size of the native "int" type]) + fi + AC_CHECK_SIZEOF([long]) + if test $ac_cv_sizeof_long != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_LONG],[$ac_cv_sizeof_long], + [Size of the native "long" type]) + fi + AC_CHECK_SIZEOF([long long]) + if test $ac_cv_sizeof_long_long != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_LONG_LONG],[$ac_cv_sizeof_long_long], + [Size of the native "long long" type]) + else + AC_DEFINE([ACE_LACKS_LONGLONG_T]) + fi + AC_CHECK_SIZEOF([void *]) + if test $ac_cv_sizeof_void_p != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_VOID_P],[$ac_cv_sizeof_void_p], + [Size of the native "pointer to void" type]) + fi + AC_CHECK_SIZEOF([float]) + if test $ac_cv_sizeof_float != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_FLOAT],[$ac_cv_sizeof_float], + [Size of the native "float" type]) + fi + AC_CHECK_SIZEOF([double]) + if test $ac_cv_sizeof_double != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_DOUBLE],[$ac_cv_sizeof_double], + [Size of the native "double" type]) + fi + AC_CHECK_SIZEOF([long double]) + if test $ac_cv_sizeof_long_double != 0; then + AC_DEFINE_UNQUOTED([ACE_SIZEOF_LONG_DOUBLE],[$ac_cv_sizeof_long_double], + [Size of the native "long double" type]) + fi + + dnl Set the 64 bit typedefs + ACE_INT64="" + ACE_UINT64="" + dnl if test "$ace_cv_type_u_longlong_t" = yes; then + dnl This doesn't work: AC_CHECK_SIZEOF([u_longlong_t],[8]) + dnl if test $ac_cv_sizeof_u_longlong_t = 8; then + dnl ACE_UINT64="u_longlong_t" + dnl ace_u_long_long_typedef_set=yes + dnl fi + dnl elif test $ac_cv_sizeof_long = 8; then + if test $ac_cv_sizeof_long = 8; then + ACE_INT64="signed long" + ACE_UINT64="unsigned long" + ace_u_long_long_typedef_set=yes + elif test $ac_cv_sizeof_long_long = 8; then + ACE_INT64="signed long long" + ACE_UINT64="unsigned long long" + ace_u_long_long_typedef_set=yes + else + ace_u_long_long_typedef_set=no + fi + + dnl Check for broken "signed char" + dnl If AC_CHECK_SIZEOF(signed char) returns zero then "signed char" + dnl is broken. + AC_CHECK_SIZEOF([signed char],[1]) + if test $ac_cv_sizeof_signed_char = 0; then + AC_DEFINE([ACE_LACKS_SIGNED_CHAR]) + fi +else + ace_u_long_long_typedef_set=no +fi dnl test "$cross_compiling" != yes + +AC_CHECK_TYPE([intmax_t], + [], + [AC_DEFINE([ACE_LACKS_INTMAX_T], 1, + [Define to 1 if the system lacks the type `intmax_t'.])], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([uintmax_t], + [], + [AC_DEFINE([ACE_LACKS_UINTMAX_T], 1, + [Define to 1 if the system lacks the type `uintmax_t'.])], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([intptr_t], + [], + [AC_DEFINE([ACE_LACKS_INTPTR_T], 1, + [Define to 1 if the system lacks the type `intptr_t'.])], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([uintptr_t], + [], + [AC_DEFINE([ACE_LACKS_UINTPTR_T], 1, + [Define to 1 if the system lacks the type `uintptr_t'.])], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([int8_t], + [AC_DEFINE([ACE_HAS_INT8_T], 1, + [Define to 1 if the system has the type `int8_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([uint8_t], + [AC_DEFINE([ACE_HAS_UINT8_T], 1, + [Define to 1 if the system has the type `uint8_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([int16_t], + [AC_DEFINE([ACE_HAS_INT16_T], 1, + [Define to 1 if the system has the type `int16_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([uint16_t], + [AC_DEFINE([ACE_HAS_UINT16_T], 1, + [Define to 1 if the system has the type `uint16_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([int32_t], + [AC_DEFINE([ACE_HAS_INT32_T], 1, + [Define to 1 if the system has the type `int32_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([uint32_t], + [AC_DEFINE([ACE_HAS_UINT32_T], 1, + [Define to 1 if the system has the type `uint32_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([int64_t], + [AC_DEFINE([ACE_HAS_INT64_T], 1, + [Define to 1 if the system has the type `int64_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +AC_CHECK_TYPE([uint64_t], + [AC_DEFINE([ACE_HAS_UINT64_T], 1, + [Define to 1 if the system has the type `uint64_t'.])], + [], + [ +#ifndef ACE_LACKS_STDINT_H +#include +#endif +#ifndef ACE_LACKS_INTTYPES_H +#include +#endif]) + +ACE_CACHE_CHECK([for std::numeric_limits<>], +[ace_cv_func_numeric_limits], +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], + [return std::numeric_limits::max();])], + [ace_cv_func_numeric_limits=yes], + [ace_cv_func_numeric_limits=no]) +],,[AC_DEFINE([ACE_LACKS_NUMERIC_LIMITS])]) + +dnl Other checks + +ACE_VAR_TIMEZONE + + +dnl Check for istream operator>> for char, unsigned char and signed char +ACE_CACHE_CHECK([for istream operator>> for char types], + [ace_cv_feature_char_right_shifts], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ +unsigned char a = 0; +cin >> a; + +#ifndef ACE_LACKS_SIGNED_CHAR +signed char b = 0; +cin >> b; +#endif + ]])],[ + ace_cv_feature_char_right_shifts=yes + ],[ + ace_cv_feature_char_right_shifts=no + ]) + ],,[AC_DEFINE([ACE_LACKS_CHAR_RIGHT_SHIFTS])]) + + +dnl Check for istream operator>> for char *, unsigned char * and signed char * +ACE_CACHE_CHECK([for istream operator>> for char * types], + [ace_cv_feature_char_ptr_right_shifts], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ +unsigned char * a = 0; +cin >> a; + +#ifndef ACE_LACKS_SIGNED_CHAR +signed char * b = 0; +cin >> b; +#endif + ]])],[ + ace_cv_feature_char_ptr_right_shifts=yes + ],[ + ace_cv_feature_char_ptr_right_shifts=no + ]) + ],,[AC_DEFINE([ACE_LACKS_CHAR_STAR_RIGHT_SHIFTS])]) + +dnl Check to see how to call the explicit destructor on a template. +dnl There are a few different possibilities: +dnl ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR (two cases): +dnl ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS: ~CLASS() +dnl (no other settings): ~CLASS() +dnl w/o ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR: +dnl CLASS::~CLASS() +dnl +dnl The first seems to be the most widely used form, although very few +dnl hand-made configs have it set. Many compilers take all three forms. +dnl The only one that seems to be less-used is #2 above, ~CLASS(). +dnl So, we check for the first two cases, and if neither of them work, +dnl we assume the third (no config macros). + +ACE_CACHE_CHECK([to see if template destructor call takes template args], + [ace_cv_feature_explicit_template_des_takes_args], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + +class dyn +{ + public: + dyn () { } + ~dyn () { } +}; + +template +class Base +{ + public: + Base () { } + virtual void f (void) { } + ~Base () { } +}; + +template +class Derived +{ + public: + Derived () + { + x_ = new Base (); + } + virtual void f (void) { } + ~Derived () { x_->~Base (); } + private: + Base *x_; + T t_; +}; + ]],[[ + Derived *x = new Derived (); + + x->f (); + + delete x; + return 0; + ]])],[ + ace_cv_feature_explicit_template_des_takes_args=yes + ],[ + ace_cv_feature_explicit_template_des_takes_args=no + ]) + ],[ + AC_DEFINE([ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS]) + AC_DEFINE([ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR]) + ], +) + +dnl Check for the second form of C++ explicit template destructors +dnl Thanks to Nanbor Wang for providing this test. +if test "$ace_cv_feature_explicit_template_des_takes_args" = no; then +ACE_CACHE_CHECK([for working C++ explicit template destructors], + [ace_cv_feature_working_explicit_des], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + +class dyn +{ + public: + dyn () { } + ~dyn () { } +}; + +template +class Base +{ + public: + Base () { } + virtual void f (void) { } + ~Base () { } +}; + +template +class Derived +{ + public: + Derived () + { + x_ = new Base (); + } + virtual void f (void) { } + ~Derived () { x_->~Base (); } + private: + Base *x_; + T t_; +}; + ]],[[ + Derived *x = new Derived (); + + x->f (); + + delete x; + return 0; + ]])],[ + ace_cv_feature_working_explicit_des=yes + ],[ + ace_cv_feature_working_explicit_des=no + ]) + ],[AC_DEFINE([ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR])],) +fi + +dnl Check for C++ "std" namespace +ACE_CACHE_CHECK([for C++ "std" namespace], + [ace_cv_feature_posix_uses_std_namespace],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if defined (ACE_USES_OLD_IOSTREAMS) +# include +#else +# include +#endif + ]],[[ + std::cout << "FOO" << std::endl; + ]])],[ + ace_cv_feature_posix_uses_std_namespace=yes + ],[ + ace_cv_feature_posix_uses_std_namespace=no + ]) + ],[AC_DEFINE([ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB])],) + +dnl Check for new style C++ include file support +ACE_CACHE_CHECK([for new style C++ include file support], + [ace_cv_lib_posix_standard_includes],[ + ace_cv_lib_posix_standard_includes=no + if test "$ace_cv_feature_posix_uses_std_namespace" = yes; then + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + std::string str; +#else + string str; +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + ]])],[ace_cv_lib_posix_standard_includes=yes],[]) + fi + ], + [ + AC_DEFINE([ACE_HAS_STDCPP_STL_INCLUDES]) + AC_DEFINE([ACE_HAS_STRING_CLASS]) + ],) + +AC_CHECK_HEADER([map], +[ + AC_CHECK_HEADER([net/if.h], + [ + ACE_CACHE_CHECK([if STL map class conflicts with map struct], + [ace_cv_header_stl_map_conflict], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]],[[ +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + std::map ace_map; +#else + map ace_map; +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + ]])],[ + ace_cv_header_stl_map_conflict=no + ],[ + ace_cv_header_stl_map_conflict=yes + ]) + ],[AC_DEFINE([ACE_HAS_STL_MAP_CONFLICT])],) + ],) +],) + +AC_CHECK_HEADER([queue], +[ + AC_CHECK_HEADER([netinet/in.h], + [ + ACE_CACHE_CHECK([if STL queue class conflicts with queue struct], + [ace_cv_header_stl_queue_conflict], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]],[[ +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + std::queue ace_queue; +#else + queue ace_queue; +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + ]])],[ + ace_cv_header_stl_queue_conflict=no + ],[ + ace_cv_header_stl_queue_conflict=yes + ]) + ],[AC_DEFINE([ACE_HAS_STL_QUEUE_CONFLICT])],) + ],) +],) + +dnl Check whether platform supports the standard C++ library +dnl TODO: For now, check whether headers , +dnl and exist; is there a better way? +if test "$ac_cv_header_new" = yes && + test "$ac_cv_header_iomanip" = yes && + test "$ac_cv_header_memory" = yes; then + + dnl Check for auto_ptr class + ACE_CACHE_CHECK([for C++ auto_ptr class], + [ace_cv_lib_auto_ptr_class], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ + int *foo = new int; + +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + std::auto_ptr safe (foo); +#else + auto_ptr safe (foo); +#endif + foo = safe.release (); + + delete foo; + ]])],[ + ace_cv_lib_auto_ptr_class=yes + ],[ + ace_cv_lib_auto_ptr_class=no + ]) + ], + [ + AC_DEFINE([ACE_HAS_STANDARD_CPP_LIBRARY]) + ], + [ + AC_DEFINE([ACE_LACKS_AUTO_PTR]) + ]) +fi + +if test "$ace_cv_lib_auto_ptr_class" = yes; then + dnl Check for auto_ptr reset method + ACE_CACHE_CHECK([for C++ auto_ptr reset method], + [ace_cv_lib_auto_ptr_reset], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]],[[ + int *foo = new int; + +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + std::auto_ptr safe (foo); +#else + auto_ptr safe (foo); +#endif + int *bar = new int; + + safe.reset (bar); + + foo = safe.release (); + ]])],[ + ace_cv_lib_auto_ptr_reset=yes + ],[ + ace_cv_lib_auto_ptr_reset=no + ]) + ],,[AC_DEFINE([ACE_AUTO_PTR_LACKS_RESET])]) +fi dnl test $ace_cv_lib_auto_ptr_class=yes + +dnl Check if platform supports placement new operator +ACE_CACHE_CHECK([for C++ placement new operator], + [ace_cv_feature_placement_new],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if defined (ACE_HAS_NEW_NO_H) +# include +#elif defined (ACE_HAS_NEW_H) +# include +#endif + +class foo +{ +public: + void *operator new (size_t, void *p) { return p; } +}; + ]],[[ +int *x = 0; +foo *f = new (x) foo; + ]])],[ + ace_cv_feature_placement_new=yes + ],[ + ace_cv_feature_placement_new=no + ]) + ],,[AC_DEFINE([ACE_LACKS_PLACEMENT_OPERATOR_NEW])]) + +dnl Check if platform supports placement delete operator +ACE_CACHE_CHECK([for C++ placement delete operator], + [ace_cv_feature_placement_delete],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if defined (ACE_HAS_NEW_NO_H) +# include +#elif defined (ACE_HAS_NEW_H) +# include +#endif + +class foo +{ +public: + void *operator new (size_t, void *p) { return p; } + void operator delete (void *p, void *) {} +}; + ]],[[ +int *x = 0; +foo *f = new (x) foo; + +// delete f; // Don't call delete for this test! + ]])],[ + ace_cv_feature_placement_delete=yes + ],[ + ace_cv_feature_placement_delete=no + ]) + ],,[AC_DEFINE([ACE_LACKS_PLACEMENT_OPERATOR_DELETE])]) + + +dnl Check if templates require source on platform +dnl +dnl FIXME: This test may be broken. +dnl +dnl FIXME: This test contains vestigial bits of tests for explicit +dnl template instantiation feature macros, even though support for +dnl the same has been removed. +dnl +dnl A rewrite to test only whether ACE_TEMPLATES_REQUIRE_SOURCE or +dnl ACE_TEMPLATES_REQUIRE_PRAGMA is clearly needed. +dnl +ACE_CACHE_CHECK([if templates require source], + [ace_cv_feature_templates_require_source], + [ + dnl Create the common header file + cat > ace_test.h < +class Foo +{ + public: + Foo (T val); + private: + T value_; +}; + +template +class Bar +{ + public: + Bar (Foo *); + private: + Foo *foo_ptr; +}; +#endif /* FOO_H */ +EOF + + dnl Create template source test file + cat > ace_test.$ac_ext < +Foo::Foo (T val) + : value_ (val) +{ + // Nothing else to do. +} + +template +Bar::Bar (Foo *val) + : foo_ptr (val) +{ + // Nothing else to do. +} +#endif /* FOO_CXX */ +EOF + + dnl Add the ACE-specific compiler flags to the compiler flags for + dnl the duration of this test. + ace_cxx_template_save_CXXFLAGS="$CXXFLAGS" + ace_cxx_template_save_CPPFLAGS="$CPPFLAGS" + ace_cxx_template_save_LDFLAGS="$LDFLAGS" + CXXFLAGS="$ACE_CXXFLAGS $CXXFLAGS" + CPPFLAGS="$ACE_CPPFLAGS $CPPFLAGS" + LDFLAGS="$ACE_LDFLAGS $LDFLAGS" + + dnl Remove any template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl First try without explicit template instantiation. + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include "ace_test.h" + ]],[[ +Foo foo (15); +Bar bar (0); + ]])],[ + dnl Template source is not required. + ace_cv_feature_templates_require_source=no + + dnl Template source does not require pragma. + AC_CACHE_VAL([ace_cv_feature_templates_require_pragma], + [ace_cv_feature_templates_require_pragma=no]) + + dnl Explicit template instantiation is not required. + AC_CACHE_VAL([ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=no]) + + dnl Pragma template instantiation is not required. + AC_CACHE_VAL([ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=no]) + ],[ + dnl Remove any template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Now try including the template source. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" +#include "ace_test.$ac_ext" + ]], + [[ +Foo foo (15); + +Bar bar (0); + ]])], + [ + dnl Template source is required! + ace_cv_feature_templates_require_source=yes + + dnl Template source does not require pragma. + AC_CACHE_VAL([ace_cv_feature_templates_require_pragma], + [ace_cv_feature_templates_require_pragma=no]) + + dnl Explicit template instantiation is not required. + AC_CACHE_VAL([ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=no]) + + dnl Pragma template instantiation is not required. + AC_CACHE_VAL([ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=no]) + ], + [ +dnl BEGIN OUTER REQUIRE SOURCE ######################################### + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Now try with explicit template instantiation. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" + +template class Foo; +template class Bar; + ]], + [[ +Foo foo (15); +Bar bar (0); + ]])], + [ + dnl Template source is not required. + ace_cv_feature_templates_require_source=no + + dnl Template source does not require pragma. + AC_CACHE_VAL([ace_cv_feature_templates_require_pragma], + [ace_cv_feature_templates_require_pragma=no]) + + dnl Explicit template instantiation is required. + AC_CACHE_VAL([ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=yes]) + + dnl Pragma template instantiation is not required. + AC_CACHE_VAL([ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=no]) + ], + [ + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Don't set + dnl ace_cv_feature_pragma_template_instantiation + dnl to "no" here. It should only be set to "no" if + dnl explicit template instantiation works. + + dnl Now try including the template source. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" +#include "ace_test.$ac_ext" + +template class Foo; +template class Bar; + ]], + [[ +Foo foo (15); +Bar bar (0); + ]])], + [ + dnl Template source is required! + ace_cv_feature_templates_require_source=yes + + dnl Template source does not require pragma. + AC_CACHE_VAL([ace_cv_feature_templates_require_pragma], + [ace_cv_feature_templates_require_pragma=no]) + + dnl Explicit template instantiation is required. + AC_CACHE_VAL( + [ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=yes]) + + dnl Pragma template instantiation is not required. + AC_CACHE_VAL( + [ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=no]) + ], + [ +dnl BEGIN INNER REQUIRE SOURCE ######################################### + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Don't set + dnl ace_cv_feature_explicit_template_instantiation + dnl to "no" here. It should only be set to "no" if + dnl pragma template instantiation works. + + dnl Now try with pragma template instantiation. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" + +#pragma instantiate Foo +#pragma instantiate Bar + ]], + [[ +Foo foo (15); +Bar bar (0); + ]])], + [ + dnl Template source is not required. + ace_cv_feature_templates_require_source=no + + dnl Template source does not require pragma. + AC_CACHE_VAL( + [ace_cv_feature_templates_require_pragma], + [ace_cv_feature_templates_require_pragma=no]) + + dnl Explicit template instantiation is not required. + AC_CACHE_VAL( + [ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=no]) + + dnl Pragma template instantiation is required. + AC_CACHE_VAL( + [ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=yes]) + ], + [ + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Don't set + dnl ace_cv_feature_explicit_template_instantiation + dnl to "no" here. It should only be set to "no" if + dnl pragma template instantiation works. + + dnl Now try including the template source. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" +#include "ace_test.$ac_ext" + +#pragma instantiate Foo +#pragma instantiate Bar + ]], + [[ +Foo foo (15); +Bar bar (0); + ]])], + [ + dnl Template source is required! + ace_cv_feature_templates_require_source=yes + + dnl Template source does not require pragma. + AC_CACHE_VAL( + [ace_cv_feature_templates_require_pragma], + [ace_cv_feature_templates_require_pragma=no]) + + dnl Explicit template instantiation is not required. + AC_CACHE_VAL( + [ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=no]) + + dnl Pragma template instantiation is required. + AC_CACHE_VAL( + [ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=yes]) + ], + [ + dnl If we get here, then we have no idea what is needed! + ace_cv_feature_templates_require_source=no + ]) + ]) +dnl END INNER REQUIRE SOURCE ######################################### + ]) + ]) +dnl END OUTER REQUIRE SOURCE ######################################### + ]) + ]) + + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Remove the test additional test files. + rm -f ace_test* + + dnl Restore the compiler flags + CXXFLAGS="$ace_cxx_template_save_CXXFLAGS" + CPPFLAGS="$ace_cxx_template_save_CPPFLAGS" + LDFLAGS="$ace_cxx_template_save_LDFLAGS" + ], + [ + AC_DEFINE([ACE_TEMPLATES_REQUIRE_SOURCE]) + ], + [ + dnl Check if templates require pragma. + ACE_CACHE_CHECK([if templates require pragma], + [ace_cv_feature_templates_require_pragma], + [ + dnl Create the common header file + cat > ace_test.h < +class Foo +{ + public: + Foo (T val); + private: + T value_; +}; + +template +class Bar +{ + public: + Bar (Foo *); + private: + Foo *foo_ptr; +}; +#endif /* FOO_H */ +EOF + + dnl Create template source test file + cat > ace_test.$ac_ext < +Foo::Foo (T val) + : value_ (val) +{ + // Nothing else to do. +} + +template +Bar::Bar (Foo *val) + : foo_ptr (val) +{ + // Nothing else to do. +} +#endif /* FOO_CXX */ +EOF + + dnl Add the ACE-specific compiler flags to the compiler flags for + dnl the duration of this test. + ace_cxx_template_save_CXXFLAGS="$CXXFLAGS" + ace_cxx_template_save_CPPFLAGS="$CPPFLAGS" + ace_cxx_template_save_LDFLAGS="$LDFLAGS" + CXXFLAGS="$ACE_CXXFLAGS $CXXFLAGS" + CPPFLAGS="$ACE_CPPFLAGS $CPPFLAGS" + LDFLAGS="$ACE_LDFLAGS $LDFLAGS" + + dnl Remove any template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl We already know that the simplest case doesn't work so go + dnl straight to the "require pragma" test. + + dnl Now try including the template pragma. + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include "ace_test.h" + +#pragma implementation ("ace_test.$ac_ext") + ]],[[ +Foo foo (15); +Bar bar (0); + ]])],[ + dnl Template source is required! + ace_cv_feature_templates_require_pragma=yes + ],[ +dnl BEGIN OUTER REQUIRE PRAGMA ######################################### + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Now try with explicit template instantiation. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" + +#pragma implementation ("ace_test.$ac_ext") + +template class Foo; +template class Bar; + ]], + [[ +Foo foo (15); +Bar bar (0); + ]])], + [ + dnl Template pragma is required! + ace_cv_feature_templates_require_pragma=yes + + dnl Explicit template instantiation is required. + AC_CACHE_VAL( + [ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=yes]) + + dnl Pragma template instantiation is not required. + AC_CACHE_VAL( + [ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=no]) + ], + [ +dnl BEGIN INNER REQUIRE PRAGMA ######################################### + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Now try with pragma template instantiation. + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include "ace_test.h" + +#pragma implementation ("ace_test.$ac_ext") + +#pragma instantiate Foo +#pragma instantiate Bar + ]], + [[ +Foo foo (15); +Bar bar (0); + ]])], + [ + dnl Template pragma is required! + ace_cv_feature_templates_require_pragma=yes + + dnl Explicit template instantiation is not required. + AC_CACHE_VAL( + [ace_cv_feature_explicit_template_instantiation], + [ace_cv_feature_explicit_template_instantiation=no]) + + dnl Pragma template instantiation is required. + AC_CACHE_VAL( + [ace_cv_feature_pragma_template_instantiation], + [ace_cv_feature_pragma_template_instantiation=yes]) + ], + [ + dnl If we get here, then we have no idea what is needed! + ace_cv_feature_templates_require_pragma=no + ]) +dnl END INNER REQUIRE PRAGMA ######################################### + ]) +dnl END OUTER REQUIRE PRAGMA ######################################### + ]) + + dnl Remove any generated template repositories. + rm -rf Templates.DB SunWS_cache ptrepository *.rpo + + dnl Remove the additional test files. + rm -f ace_test* + + dnl Restore the compiler flags + CXXFLAGS="$ace_cxx_template_save_CXXFLAGS" + CPPFLAGS="$ace_cxx_template_save_CPPFLAGS" + LDFLAGS="$ace_cxx_template_save_LDFLAGS" + ], + [ + AC_DEFINE([ACE_TEMPLATES_REQUIRE_PRAGMA]) + ], + [ + dnl Do nothing. + ]) + ]) + + +dnl Check if platform supports template typedefs +ACE_CACHE_CHECK([for template typedefs], + [ace_cv_feature_posix_template_typedefs],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + +class Bar +{ +public: + typedef int Y; + Bar(int bar) : bar_(bar) {} + int value() const { return bar_; } +private: + int bar_; +}; + +template +class Foo +{ +public: + typedef typename T::Y Y; + Foo(T* foo) : foo_(foo) {} + void print(Y); +private: + T* foo_; +}; + +template +void Foo::print(typename T::Y) +{ +} + ]],[[ +Bar bar(15); +Foo foo(&bar); +foo.print(11); + ]])],[ + ace_cv_feature_posix_template_typedefs=yes + ],[ + ace_cv_feature_posix_template_typedefs=no + ]) + ],[AC_DEFINE([ACE_HAS_TEMPLATE_TYPEDEFS])],) + +dnl Check if platform supports static data member templates +ACE_CACHE_CHECK([for static data member templates], + [ace_cv_feature_posix_static_data_member_templates],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +template +class Foo +{ +public: + static T* sdm; +}; + +template T* Foo::sdm = 0; + ]],[[ + /* No body */ + ]])],[ + ace_cv_feature_posix_static_data_member_templates=yes + ],[ + ace_cv_feature_posix_static_data_member_templates=no + ]) + ],,[AC_DEFINE([ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES])]) + +dnl Check if compiler needs definitions for hidden functions +ACE_CACHE_CHECK([if definition is needed for hidden functions], + [ace_cv_feature_need_func_def], + [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + class Foo + { + public: + Foo (void) { a_ = 0; } + private: + Foo (const Foo &); + void operator= (const Foo &); + + int a_; + }; + ]],[[ + Foo Bar; + ]])],[ + ace_cv_feature_need_func_def=no + ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ + class Foo + { + public: + Foo (void) { a_ = 0; } + private: + Foo (const Foo &); + const Foo & operator= (const Foo &); + + int a_; + }; + + Foo::Foo (const Foo &) + { + a_ = 0; + } + + const Foo & + Foo::operator= (const Foo &) + { + a_ = 0; + + return *this; + } + ]], + [[ + Foo Bar; + ]])], + [ + ace_cv_feature_need_func_def=yes + ], + [ + dnl If we get here then we don't know what is needed! + ace_cv_feature_need_func_def=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_NEEDS_FUNC_DEFINITIONS]) + ],) + +dnl Check if platform supports C++ exceptions +if test "$ace_user_enable_exceptions" = yes; then + ACE_CACHE_CHECK([for C++ exceptions], + [ace_cv_feature_posix_exceptions],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[ + int ret = 0; + class ACE {}; + try + { + throw ACE(); + } + catch (ACE) + { + ret = 1; + } + ]])],[ + ace_cv_feature_posix_exceptions=yes + ],[ + ace_cv_feature_posix_exceptions=no + ]) + ],[AC_DEFINE([ACE_HAS_EXCEPTIONS])],[ace_user_enable_exceptions=no]) + +fi dnl test "$ace_user_enable_exceptions" = yes + +dnl Check if we need a non-static object manager +dnl TODO / FIXME +dnl ACE_CACHE_CHECK([if we need a non-static object manager], +dnl [ace_cv_feature_nonstatic_object_manager],[ +dnl ace_cv_feature_nonstatic_object_manager=yes + dnl TODO: Should we check for this thing (and HOW), or + dnl should it be the user's choice? + + dnl For now, we will leave it as a user's choice. + dnl -Ossama +dnl ], +dnl [ + dnl Don't define anything until we have a test for this. + dnl AC_DEFINE([ACE_HAS_NONSTATIC_OBJECT_MANAGER]) +dnl ],) + +dnl Save the cache for debugging purposes +AC_CACHE_SAVE + + +dnl SECTION 10: checks for library functions + +ACE_FUNC_STRCASECMP +ACE_FUNC_STRNCASECMP +ACE_FUNC_STRDUP +ACE_FUNC_WCSCASECMP +ACE_FUNC_WCSNCASECMP +ACE_FUNC_WCSDUP + +if test "$ace_user_enable_alloca" = yes; then + AC_FUNC_ALLOCA + if test "$ac_cv_header_alloca_h" = yes; then + AC_DEFINE([ACE_HAS_ALLOCA_H]) + fi + if test "$ac_cv_func_alloca_works" = yes; then + AC_DEFINE([ACE_HAS_ALLOCA]) + fi +fi + +dnl ACE should really have something for both the sys/mman.h header +dnl and the mmap function since we need sys/mman.h for functions like +dnl mprotect and msync, but don't want to use mmap if it doesn't work. +dnl For now, we just check for the sys/mman.h header earlier in this +dnl configure script. + +dnl AC_FUNC_MMAP +dnl if test "$ac_cv_func_mmap_fixed_mapped" = no; then +dnl Even if we have mmap, do not use if broken! +dnl AC_DEFINE(ACE_LACKS_MMAP) +dnl fi + +dnl Check if closedir() returns a meaningful value +AC_FUNC_CLOSEDIR_VOID + +dnl Check for PWD functions +AC_CHECK_FUNC([getpwnam],,) +AC_CHECK_FUNC([setpwent],,) +AC_CHECK_FUNC([endpwent],,) +AC_CHECK_FUNC([getpwent],,) +AC_CHECK_FUNC([getpwuid],,) + +if test "$ac_cv_func_getpwnam" != yes || + test "$ac_cv_func_setpwent" != yes || + test "$ac_cv_func_endpwent" != yes || + test "$ac_cv_func_getpwent" != yes || + test "$ac_cv_func_getpwuid" != yes; then + AC_DEFINE([ACE_LACKS_PWD_FUNCTIONS]) +else + dnl The password file related functions above are required for ACE's + dnl alternate implementation. + + ACE_CONVERT_WARNINGS_TO_ERRORS([ + dnl Check for functions necessary for ACE's alternate implementation + dnl of the now obsolete cuserid() function. + ACE_CACHE_CHECK([checking if ACE cuserid() implementation should be used], + [ace_cv_lib_use_alt_cuserid], + [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +/* Undefine _XOPEN_SOURCE since it may make the cuserid() prototype + visible. ACE should not rely on such feature test macros. */ +#undef _XOPEN_SOURCE +#ifndef ACE_LACKS_UNISTD_H +# include +#else +# error No unistd.h header. Need header where cuserid() is located. +#endif /* ACE_LACKS_UNISTD_H */ + ]],[[ + char * foo = cuserid ((char *)0); + ]])],[ + dnl If successful then use the system cuserid() implementation, + dnl despite the fact that ACE's implementation may be safer. + ace_cv_lib_use_alt_cuserid=no + ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#undef _XOPEN_SOURCE +#ifndef ACE_LACKS_UNISTD_H +# include +#else +# error No unistd.h header. Need header where geteuid() is located. +#endif + ]], + [[ + uid_t foo = geteuid (); + ]])], + [ + dnl All of the functions necessary for ACE's cuserid() + dnl implementation exist. + ace_cv_lib_use_alt_cuserid=yes + ], + [ + dnl If we get here, we're hosed! + ace_cv_lib_use_alt_cuserid=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_ALT_CUSERID]) + ],) + ]) +fi + + + +dnl Check for `strftime' in the `intl' library, for SCO UNIX +AC_FUNC_STRFTIME + +case "$host_os" in + *win32*) + AC_CHECK_FUNC([CancelIO], + [AC_DEFINE([ACE_HAS_CANCEL_IO])],) + + AC_CHECK_FUNC([SignalObjectAndWait], + [AC_DEFINE([ACE_HAS_SIGNAL_OBJECT_AND_WAIT])],) + + AC_CHECK_FUNC([TryEnterCriticalSection], + [AC_DEFINE([ACE_HAS_WIN32_TRYLOCK])],) + ;; + *) + ;; +esac + +ACE_CHECK_HAS_FUNCS(_InterlockedIncrement _InterlockedDecrement _InterlockedExchangeAdd) +if test "$ac_cv_func__InterlockedIncrement" == yes && + test "$ac_cv_func__InterlockedDecrement" == yes && + test "$ac_cv_func__InterlockedExchangeAdd" == yes; then + AC_DEFINE([ACE_HAS_INTRINSIC_INTERLOCKED]) +fi + +ACE_CHECK_LACKS_FUNCS(access) + +ACE_CHECK_LACKS_FUNCS(alphasort) + +ACE_CHECK_LACKS_FUNCS(asctime) + +ACE_CHECK_LACKS_FUNCS(asctime_r) + +ACE_CHECK_LACKS_FUNCS(alarm) + +ACE_CHECK_LACKS_FUNCS(bsearch) + +ACE_CHECK_HAS_DEFINES([bswap16]) +if test "$ace_cv_defined_bswap16" = no; then + ACE_CHECK_HAS_DEFINES([bswap_16],[],[],[ +#if ACE_HAS_BYTESWAP_H +#include +#endif]) +fi +ACE_CHECK_HAS_DEFINES([bswap32]) +if test "$ace_cv_defined_bswap32" = no; then + ACE_CHECK_HAS_DEFINES([bswap_32],[],[],[ +#if ACE_HAS_BYTESWAP_H +#include +#endif]) +fi +ACE_CHECK_HAS_DEFINES([bswap64]) +if test "$ace_cv_defined_bswap64" = no; then + ACE_CHECK_HAS_DEFINES([bswap_64],[],[],[ +#if ACE_HAS_BYTESWAP_H +#include +#endif]) +fi + +ACE_CHECK_LACKS_FUNCS(chdir) + +ACE_CHECK_HAS_FUNCS(clock_gettime clock_settime nanosleep) + +ACE_CHECK_LACKS_FUNCS(difftime) + +ACE_CHECK_LACKS_FUNCS(dup) + +ACE_CHECK_LACKS_FUNCS(dup2) + +dnl ACE uses execv, execvp and execve, so we don't bother to check +dnl for the others (e.g. execl, execlp, execle) +AC_CHECK_FUNC(execv) +AC_CHECK_FUNC(execvp) +AC_CHECK_FUNC(execve) +if test "$ac_cv_func_execv" != yes && + test "$ac_cv_func_execvp" != yes && + test "$ac_cv_func_execve" != yes; then + AC_DEFINE([ACE_LACKS_EXEC]) +fi + +ACE_CHECK_LACKS_FUNCS(fgetwc fcntl fork fsync) + +ACE_CHECK_LACKS_FUNCS(getcwd) + +ACE_CHECK_LACKS_FUNCS(gethostent) + +ACE_CHECK_LACKS_FUNCS(getipnodebyaddr) + +ACE_CHECK_LACKS_FUNCS(getipnodebyname) + +ACE_CHECK_HAS_FUNCS(getifaddrs) + +ACE_CHECK_LACKS_FUNCS(getegid geteuid getgid) + +ACE_CHECK_LACKS_FUNCS(getopt) +if test $ac_cv_func_getopt = yes; then + AC_CHECK_DECL([getopt], + [], + [AC_DEFINE([ACE_LACKS_GETOPT_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of getopt().])], + [#include + #ifndef ACE_LACKS_UNISTD_H + # include + #endif]) +fi + +AC_CHECK_FUNC([getpagesize], + [AC_DEFINE([ACE_HAS_GETPAGESIZE])], + [AC_DEFINE([ACE_PAGE_SIZE], [4096])]) + +ACE_CHECK_LACKS_FUNCS(getpid) + +ACE_CHECK_LACKS_FUNCS([getpgid]) +if test "$ac_cv_func_getpgid" = yes; then + dnl Check if _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED macros are + dnl needed to make the getpgid() prototype visible. + ACE_CACHE_CHECK([for getpgid prototype], + [ace_cv_lib_has_getpgid_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_xopen="-U_XOPEN_SOURCE -U_XOPEN_SOURCE_EXTENDED" + CPPFLAGS="$CPPFLAGS $ace_no_xopen" + AC_EGREP_HEADER([[^_]+getpgid], [unistd.h], + [ + ace_cv_lib_has_getpgid_prototype=yes + ], + [ + ace_cv_lib_has_getpgid_prototype=no + ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],, [AC_DEFINE([ACE_LACKS_GETPGID_PROTOTYPE])]) + AH_TEMPLATE([ACE_LACKS_GETPGID_PROTOTYPE], + [Define to 1 if platform lacks getpgid() declaration in .]) +fi + +ACE_CHECK_LACKS_FUNCS(getppid) + +ACE_CHECK_HAS_FUNCS(getprogname) + +ACE_CHECK_HAS_FUNCS(getrusage) +if test $ac_cv_func_getrusage = yes; then + AC_CHECK_DECL([getrusage], + [AC_DEFINE([ACE_HAS_GETRUSAGE_PROTOTYPE], 1, + [Define to 1 if platform has the declaration + of getrusage().])], + [], + [#include ]) +fi + +ACE_CHECK_LACKS_FUNCS(getuid) + +ACE_CHECK_LACKS_FUNCS(gmtime) + +ACE_CHECK_LACKS_FUNCS(gmtime_r) + +ACE_CHECK_LACKS_FUNCS(inet_aton) + +ACE_CHECK_LACKS_FUNCS(isatty) + +AC_CHECK_FUNC(isastream) +if test $ac_cv_func_isastream = yes; then + AC_CHECK_DECL([isastream], + [AC_DEFINE([ACE_HAS_ISASTREAM_PROTOTYPE], 1, + [Define to 1 if platform has the declaration + of isastream().])], + [], + [#include ]) +fi + +ACE_CHECK_HAS_FUNCS(itoa) + +dnl Check for 64 bit llseek() or lseek64() +case "$host" in + *UnixWare7*) + dnl Skip the check + ;; + *) + ACE_CHECK_LSEEK64 + ;; +esac + +ACE_CHECK_LACKS_FUNCS(kill) + +ACE_CHECK_LACKS_FUNCS(localtime) + +ACE_CHECK_LACKS_FUNCS(log2) + +ACE_CHECK_LACKS_FUNCS(lstat) + +ACE_CHECK_LACKS_FUNCS(madvise) +if test $ac_cv_func_madvise = yes; then + AC_CHECK_DECL([madvise], + [], + [AC_DEFINE([ACE_LACKS_MADVISE_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of madvise().])], + [ +#if !defined(ACE_LACKS_SYS_TYPES_H) +# include +#endif +#include + ]) +fi + +ACE_CHECK_HAS_FUNCS(mkdir) + +if test "$ac_cv_func_mkdir" = yes; then +dnl The mkdir() function has only one argument on Windows and VxWorks +AC_MSG_CHECKING([for 1- or 2-param mkdir]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + const char path[] = "mypath"; + int result = mkdir (path); + ]])], + [ + AC_DEFINE([ACE_MKDIR_LACKS_MODE], 1, + [Define to 1 if platform has 1 parameter mkdir()]) + AC_MSG_RESULT([1]) + ], + [ + AC_MSG_RESULT([2]) + ]) +fi dnl test "$ac_cv_func_mkdir" = yes + +ACE_CHECK_HAS_FUNCS(memchr) + +ACE_CHECK_LACKS_FUNCS(mkfifo) + +ACE_CHECK_LACKS_FUNCS(mkstemp) +if test $ac_cv_func_mkstemp = yes; then + AC_CHECK_DECL([mkstemp], + [], + [AC_DEFINE([ACE_LACKS_MKSTEMP_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of mkstemp().])], + [#include ]) +fi + +ACE_CHECK_LACKS_FUNCS(mktemp) +if test $ac_cv_func_mktemp = yes; then + AC_CHECK_DECL([mktemp], + [], + [AC_DEFINE([ACE_LACKS_MKTEMP_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of mktemp().])], + [#include ]) +fi + +ACE_CHECK_LACKS_FUNCS(msync mprotect) + +ACE_CHECK_LACKS_FUNCS(pipe) + +ACE_CHECK_LACKS_FUNCS(qsort) + +ACE_CHECK_LACKS_FUNCS(realpath) + +ACE_CHECK_LACKS_FUNCS(setegid seteuid setgid) + +ACE_CHECK_LACKS_FUNCS([setpgid]) +if test "$ac_cv_func_setpgid" = yes; then + dnl Check if _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED macros are + dnl needed to make the setpgid() prototype visible. + ACE_CACHE_CHECK([for setpgid prototype], + [ace_cv_lib_has_setpgid_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_xopen="-U_XOPEN_SOURCE -U_XOPEN_SOURCE_EXTENDED" + CPPFLAGS="$CPPFLAGS $ace_no_xopen" + AC_EGREP_HEADER([[^_]+setpgid], [unistd.h], + [ + ace_cv_lib_has_setpgid_prototype=yes + ], + [ + ace_cv_lib_has_setpgid_prototype=no + ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],, [AC_DEFINE([ACE_LACKS_SETPGID_PROTOTYPE])]) + AH_TEMPLATE([ACE_LACKS_SETPGID_PROTOTYPE], + [Define to 1 if platform lacks setpgid() declaration in .]) +fi + +ACE_CHECK_HAS_FUNCS([setprogname]) + +ACE_CHECK_LACKS_FUNCS([setregid]) +if test "$ac_cv_func_setregid" = yes; then + dnl Check if _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED macros are + dnl needed to make the setregid() prototype visible. + ACE_CACHE_CHECK([for setregid prototype], + [ace_cv_lib_has_setregid_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_xopen="-U_BSD_SOURCE -U_XOPEN_SOURCE -U_XOPEN_SOURCE_EXTENDED" + CPPFLAGS="$CPPFLAGS $ace_no_xopen" + AC_EGREP_HEADER([[^_]+setregid], [unistd.h], + [ + ace_cv_lib_has_setregid_prototype=yes + ], + [ + ace_cv_lib_has_setregid_prototype=no + ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],, [AC_DEFINE([ACE_LACKS_SETREGID_PROTOTYPE])]) + AH_TEMPLATE([ACE_LACKS_SETREGID_PROTOTYPE], + [Define to 1 if platform lacks setregid() declaration in .]) +fi + +ACE_CHECK_LACKS_FUNCS([setreuid]) +if test "$ac_cv_func_setreuid" = yes; then + dnl Check if _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED macros are + dnl needed to make the setreuid() prototype visible. + ACE_CACHE_CHECK([for setreuid prototype], + [ace_cv_lib_has_setreuid_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_xopen="-U_BSD_SOURCE -U_XOPEN_SOURCE -U_XOPEN_SOURCE_EXTENDED" + CPPFLAGS="$CPPFLAGS $ace_no_xopen" + AC_EGREP_HEADER([[^_]+setreuid], [unistd.h], + [ + ace_cv_lib_has_setreuid_prototype=yes + ], + [ + ace_cv_lib_has_setreuid_prototype=no + ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],, [AC_DEFINE([ACE_LACKS_SETREUID_PROTOTYPE])]) + AH_TEMPLATE([ACE_LACKS_SETREUID_PROTOTYPE], + [Define to 1 if platform lacks setreuid() declaration in .]) +fi + +ACE_CHECK_LACKS_FUNCS(setsid setuid) + +ACE_CHECK_LACKS_FUNCS(sigaction) + +ACE_CHECK_HAS_FUNCS(strnlen) +if test "$ac_cv_func_strnlen" = yes; then + AC_CHECK_DECL([strnlen], + [], + [AC_DEFINE([ACE_LACKS_STRNLEN_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of strnlen().])], + [#include ]) +fi + +ACE_CHECK_LACKS_FUNCS(strchr) + +# believe it or not, both ACE_LACKS_STRERROR and ACE_HAS_STRERROR +# feature test macros are currently used. +ACE_CHECK_HAS_FUNCS(strerror) +ACE_CHECK_LACKS_FUNCS(strerror) + +ACE_CHECK_LACKS_FUNCS(strftime) + +ACE_CHECK_LACKS_FUNCS(strpbrk) + +ACE_CHECK_LACKS_FUNCS(strrchr) + +ACE_CHECK_LACKS_FUNCS(strspn) + +ACE_CHECK_LACKS_FUNCS(strtod) + +ACE_CHECK_LACKS_FUNCS(strtol) + +ACE_CHECK_LACKS_FUNCS(strtoul) + +ACE_CHECK_LACKS_FUNCS(strtoull) + +# swab() comes in a number of forms: +# swab (const void*, void*, size_t) is POSIX, XPG4, SUS, SUSv2 standard. +# swab (const char*, char*, size_t) is SVID third edition. +# swab (char*, char*, size_t) is on some odd platforms like Windows. +# So, if swab() is available, figure out which of the three variants it is. +# The second and third have ACE config settings. +ACE_CHECK_LACKS_FUNCS([swab], + [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +#include +#include + ], + [ +// If this compiles, we have the POSIX, XPG4, etc. standard. +const char src[2] = {'a', 'b'}; +char dst[2]; +const void *vsrc = src; +void *vdst = dst; +swab (vsrc, vdst, 2); + ]) + ], + [ + ace_cv_std_swab=yes + ], + [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +#include +#include + ], + [ +// If this compiles, we have the SVID3 version, else it's the odd, +// non-const one. +const char src[2] = {'a', 'b'}; +char dst[2]; +swab (src, dst, 2); + ]) + ], + [ + AC_DEFINE([ACE_HAS_CONST_CHAR_SWAB]) + ], + [ + AC_DEFINE([ACE_HAS_NONCONST_SWAB]) + ]) + ]) + ], +) + +ACE_CHECK_LACKS_FUNCS(sysconf) + +ACE_CHECK_HAS_FUNCS(sysctl) + +AC_CHECK_FUNC([sysinfo], + [ + if test "$ac_cv_header_sys_systeminfo_h" = yes; then + AC_DEFINE([ACE_HAS_SYSINFO]) + fi + ],) + +ACE_CHECK_LACKS_FUNCS(system) + +AC_CHECK_FUNC([getmsg], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef ACE_LACKS_UNISTD_H +# include +#endif /* !ACE_LACKS_UNISTD_H */ + +#ifndef ACE_LACKS_SYS_IOCTL_H +# include +#endif /* ACE_LACKS_SYS_IOCTL_H */ + +#ifdef ACE_HAS_STREAMS +# include +#endif /* ACE_HAS_STREAMS */ + +int +main () +{ + int fds[2]; + + if (pipe (fds) != 0) + return -1; + +/* + * Verify that we can actually set a STREAM option that ACE uses. + * This is particularly necessary for platforms where compiling and + * linking succeed but fail at run-time due to a missing actual + * STREAMS implementation. For example, Linux/glibc requires a + * STREAMS patch/add-on. + */ + + int arg = RMSGN; + + if (ioctl (fds[0], I_SRDOPT, (void *) arg) != 0) + return -1; + + return 0; +} + ]])],[ + AC_DEFINE([ACE_HAS_STREAM_PIPES]) + ],[],[ + dnl action if cross-compiling + AC_DEFINE([ACE_HAS_STREAM_PIPES]) + ]) + ],) + +AC_CHECK_FUNC([gethostbyaddr],,) + +case "$host" in + *linux*) + dnl Linux Event Poll + ACE_CACHE_CHECK([for epoll_create], + [ace_cv_linux_event_poll], + [ + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([ +#include + ], + [ +int const ACE_NUM_DESCRIPTORS = 10; +return epoll_create (ACE_NUM_DESCRIPTORS) == -1 ? -1 : 0; + ]) + ], + [ + ace_cv_linux_event_poll=yes + ], + [ + ace_cv_linux_event_poll=no + ]) + ], + [ + AC_DEFINE([ACE_HAS_EVENT_POLL]) + ], + []) + ;; + *) + dnl Check if /dev/poll character device file exists and is + dnl useable. Just because /dev/poll is present doesn't mean its + dnl useable - this is the case on HP-UX 11. /dev/poll is there, but + dnl getting it to work requires a set of patches. + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ +#include +#include + +int +main () +{ + int fd = open ("/dev/poll", O_RDWR); + close (fd); + return fd == -1 ? -1 : 0; +} + ]])], + [ + AC_DEFINE([ACE_HAS_DEV_POLL]) + ], + [], + []) + ;; +esac + +AC_CHECK_FUNC([gethrtime], + [ + ACE_CHECK_TYPE([hrtime_t],[sys/time.h],[AC_DEFINE([ACE_HAS_HI_RES_TIMER])],) + ],) + +AC_CHECK_FUNC([pread], + [AC_CHECK_FUNC([pwrite], + [ + AC_DEFINE([ACE_HAS_P_READ_WRITE]) + dnl Check if _XOPEN_SOURCE=500 macro is needed to make the pread() and + dnl pwrite() prototypes visible. + ACE_CACHE_CHECK([for pread prototype], + [ace_cv_lib_has_pread_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_xopen="-U_XOPEN_SOURCE" + CPPFLAGS="$CPPFLAGS $ace_no_xopen" + AC_EGREP_HEADER([[^_]+pread], [unistd.h], + [ + ace_cv_lib_has_pread_prototype=yes + ], + [ + ace_cv_lib_has_pread_prototype=no + ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],,[AC_DEFINE([ACE_LACKS_PREAD_PROTOTYPE])]) + ],)],) + +ACE_CHECK_LACKS_FUNCS(readv writev) + +ACE_CHECK_HAS_FUNCS(set_t_errno) + +ACE_CHECK_HAS_FUNCS(sigsuspend sigtimedwait) + +ACE_CHECK_LACKS_FUNCS(socketpair) + +AC_CHECK_FUNC(strptime) +if test "$ac_cv_func_strptime" == yes; then + dnl strptime() is available, but its prototype is not always visible to + dnl the compiler. Check if _XOPEN_SOURCE macro is needed to make the + dnl strptime() prototype visible. + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_xopen="-U_XOPEN_SOURCE" + CPPFLAGS="$CPPFLAGS $ace_no_xopen" + AC_CHECK_DECL([strptime], + [], + [AC_DEFINE([ACE_LACKS_STRPTIME_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of strptime().])], + [#include ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" +else + AC_DEFINE([ACE_LACKS_STRPTIME], 1, + [Define to 1 if platform lacks strptime().]) +fi + +if test "$ac_cv_type_wchar_t" = yes; then + AC_CHECK_FUNC([wcslen], + [AC_DEFINE([ACE_HAS_XPG4_MULTIBYTE_CHAR])],) +fi + +ACE_CHECK_LACKS_FUNCS(syscall) + +AC_CHECK_FUNC([alarm],,) +AC_CHECK_FUNC([signal],,) + +if test "$ac_cv_func_alarm" != yes && + test "$ac_cv_func_signal" != yes; then + AC_DEFINE([ACE_LACKS_UNIX_SIGNALS]) +fi + +AC_CHECK_FUNC([getrlimit]) +AC_CHECK_FUNC([setrlimit]) +if test "$ac_cv_func_getrlimit" != yes || + test "$ac_cv_func_setrlimit" != yes; then + AC_DEFINE([ACE_LACKS_RLIMIT]) +fi + +ACE_CHECK_LACKS_FUNCS(readlink rename recvmsg sendmsg) + +if test "$ac_cv_header_sys_priocntl_h" = yes; then + AC_CHECK_FUNC([priocntl], + [AC_DEFINE([ACE_HAS_PRIOCNTL])],) + +dnl Some platforms define priocntl as a macro! + if test "$ac_cv_func_priocntl" = no; then + ACE_CACHE_CHECK([for priocntl macro], + [ace_cv_lib_has_priocntl_macro], + [ + AC_EGREP_CPP([ACE_PRIOCNTL_MACRO], + [ +#include + +#if defined (priocntl) + ACE_PRIOCNTL_MACRO +#endif + ], + [ + ace_cv_lib_has_priocntl_macro=yes + ], + [ + ace_cv_lib_has_priocntl_macro=no + ]) + ], [AC_DEFINE([ACE_HAS_PRIOCNTL])],) + fi dnl test "$ac_cv_func_priocntl" = no +fi dnl test "$ac_cv_header_sys_priocntl_h" = yes + +dnl FIXME: How do we check for a working sbrk()? Do we need to? +ACE_CHECK_LACKS_FUNCS(sbrk) + +ACE_CHECK_HAS_FUNCS(ualarm) +if test $ac_cv_func_ualarm = yes; then + AC_CHECK_DECL([ualarm], + [], + [AC_DEFINE([ACE_LACKS_UALARM_PROTOTYPE], 1, + [Define to 1 if platform lacks the declaration + of ualarm().])], + [#include ]) +fi + +ACE_CHECK_LACKS_FUNCS(umask) + +ACE_CHECK_LACKS_FUNCS(uname) + +ACE_CHECK_LACKS_FUNCS(unlink) + +ACE_CHECK_HAS_FUNCS(vasprintf vaswprintf vfwprintf vswprintf) + +ACE_CHECK_HAS_FUNCS(wcsnlen) + +ACE_CHECK_LACKS_FUNCS(fgetws fputws itow towlower towupper wcscat wcschr wcscmp wcscpy wcscspn wcslen wcsncat wcsncmp wcsncpy wcsnicmp wcspbrk wcsrchr wcsspn wcsstr wcstod wcstok wcstol wcstoul wcstoull) + +if test "$ac_cv_func_wcstok" = yes; then +dnl The wcstok() function varies with standards. Check which one we have. +AC_MSG_CHECKING([for 2- or 3-param wcstok]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + wchar_t str[] = L"junk"; + const wchar_t delim[] = L"\t\n"; + wchar_t *ptr; + wchar_t *p = wcstok (str, delim, &ptr); + ]])], + [ + AC_DEFINE([ACE_HAS_3_PARAM_WCSTOK], 1, + [Define to 1 if platform has 3 parameter wcstok()]) + AC_MSG_RESULT([3]) + ], + [ + AC_MSG_RESULT([2]) + ]) +fi dnl test "$ac_cv_func_wcstok" = yes + +dnl Check for SYSV IPC functions +dnl +dnl Although Darwin/OS X does not implement any of the SysV IPC API, +dnl its C library contains stubs for all the system calls (probably +dnl left over from the BSD libc). This causes false positives from +dnl AC_CHECK_FUNC which results in configure reporting that SysV IPC +dnl is supported. We avoid this problem by avoiding the function +dnl checks if the cooresponding headers were not detected earlier. +dnl +if test "$ac_cv_header_sys_msg_h" = yes; then + AC_CHECK_FUNC([msgctl],,) + + AC_CHECK_FUNC([msgget],,) + + AC_CHECK_FUNC([msgrcv],,) +fi dnl test "$ac_cv_header_sys_msg_h" = yes + +if test "$ac_cv_header_sys_sem_h" = yes; then + AC_CHECK_FUNC([semctl],,) + + AC_CHECK_FUNC([semget],,) + + AC_CHECK_FUNC([semop],,) +fi dnl test "$ac_cv_header_sys_sem_h" = yes + +if test "$ac_cv_header_sys_shm_h" = yes; then + AC_CHECK_FUNC([shmat],,) + + AC_CHECK_FUNC([shmctl],,) + + AC_CHECK_FUNC([shmdt],,) + + AC_CHECK_FUNC([shmget],,) +fi dnl test "$ac_cv_header_sys_shm_h" = yes + +dnl End check for SYSV IPC functions + +AC_CHECK_FUNC([read_real_time], + [AC_DEFINE([ACE_HAS_AIX_HI_RES_TIMER])],) + +dnl See shm_open() test after this one ... +dnl AC_CHECK_FUNC([shm_open], [AC_DEFINE([ACE_HAS_SHM_OPEN])],) + +dnl Use a more comprehensive test for shm_open() since the prototype +dnl may not be visible on all platforms without enabling POSIX.1b +dnl support (e.g. when the user defines _POSIX_C_SOURCE > 2). +AC_MSG_CHECKING([for shm_open]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include +#include + ]], + [[ + const char name[] = "Foo"; + const int oflag = O_RDONLY; + const mode_t mode = 0400; /* Whatever */ + const int fd = shm_open (name, oflag, mode); + ]])], + [ + AC_DEFINE([ACE_HAS_SHM_OPEN]) + AC_MSG_RESULT([yes]) + + dnl Now see if running it requires a leading slash. + ACE_CACHE_CHECK([if shm_open requires one slash], + [ace_cv_shm_open_requires_one_slash], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + const char name[] = "ACE_Foo"; + const char name2[] = "/ACE_Foo"; + const int oflag = O_RDWR | O_CREAT; + const mode_t mode = 0400; /* Whatever */ + int fd = shm_open (name, oflag, mode); + if (fd != -1) + { + close (fd); + shm_unlink (name); + return 1; /* Don't need the slash */ + } + fd = shm_open (name2, oflag, mode); + if (fd != -1) + { + close (fd); + shm_unlink (name2); + return 0; + } + return 1; /* Nothing worked, so say 'no' */ +} + ]])],[ + ace_cv_shm_open_requires_one_slash=yes + ],[ + ace_cv_shm_open_requires_one_slash=no + ],[ + dnl action if cross-compiling + ace_cv_shm_open_requires_one_slash=no + ]) + ],AC_DEFINE([ACE_SHM_OPEN_REQUIRES_ONE_SLASH]),) + ], + [ + AC_MSG_RESULT([no]) + ]) + +dnl if test "$ace_cv_shm_open_requires_one_slash" = yes; then +dnl AC_DEFINE([ACE_SHM_OPEN_REQUIRES_ONE_SLASH]) +dnl fi + +ACE_CHECK_HAS_FUNCS(snprintf) + +ACE_CHECK_LACKS_FUNCS(tempnam truncate) + +dnl Save the cache for debugging purposes +AC_CACHE_SAVE + +dnl Check for POSIX Semaphore functions +dnl We only check for a few of them since some platforms don't have these. +dnl On some platforms, a separate library is required, so use AC_SEARCH_LIBS +dnl instead of AC_CHECK_FUNC. This will add any needed library to LIBS. +AC_SEARCH_LIBS([sem_init],rt,[ace_cv_func_sem_init=yes],,) +AC_SEARCH_LIBS([sem_destroy],rt,[ace_cv_func_sem_destroy=yes],,) + +if test "$ace_cv_func_sem_init" = yes && + test "$ace_cv_func_sem_destroy" = yes && + test "$ace_cv_type_sem_t" = yes; then + +dnl Only enable POSIX semaphore support if process shared semaphores +dnl are supported. Presumably process shared semaphores are only +dnl available if the _POSIX_THREAD_PROCESS_SHARED macro is defined by +dnl the platform. + AC_EGREP_CPP([WE_HAVE_SHARED_POSIX_SEMAPHORES], + [ +#ifndef _REENTRANT +#define _REENTRANT +#endif + +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif + +#ifndef ACE_LACKS_UNISTD_H +# include /* needed for _POSIX_THREAD_PROCESS_SHARED */ +#endif + +#include +#include + +#if defined (_POSIX_THREAD_PROCESS_SHARED) +WE_HAVE_SHARED_POSIX_SEMAPHORES +#endif + ], + [ + AC_DEFINE([ACE_HAS_POSIX_SEM]) + + AC_CHECK_FUNC([sem_open]) + AC_CHECK_FUNC([sem_close]) + AC_CHECK_FUNC([sem_unlink]) + if test "$ac_cv_func_sem_open" = no || + test "$ac_cv_func_sem_close" = no || + test "$ac_cv_func_sem_unlink" = no; then + + AC_DEFINE([ACE_LACKS_NAMED_POSIX_SEM]) + else + dnl Check if it works! For example, in glibc 2.x sem_open exists + dnl but it appears to be a stub. However, it isn't listed as a + dnl stub in so the configure script thinks it is + dnl implemented! + ACE_CACHE_CHECK([if sem_open works], + [ace_cv_sem_open_works], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef ACE_LACKS_SYS_TYPES_H +#include +#endif + +#include +#include + +#include /* for definition of "NULL" */ + +#include + +#ifndef SEM_FAILED +# define SEM_FAILED ((sem_t *) -1) +#endif + +int +main () +{ + sem_t *s = 0; + + s = sem_open ("ace_semaphore_foo", O_CREAT | O_EXCL, 0600, 1); + if (s == SEM_FAILED) + return -1; /* FAILURE */ + + sem_unlink ("ace_semaphore_foo"); + if (sem_close (s) != 0) + return -1; /* Something went wrong! */ + + return 0; +} + ]])],[ + ace_cv_sem_open_works=yes + ],[ + ace_cv_sem_open_works=no + ],[ + dnl action if cross-compiling + ace_cv_sem_open_works=yes + ]) + ],, [AC_DEFINE([ACE_LACKS_NAMED_POSIX_SEM])]) + fi + ],) + +fi dnl check for POSIX Semaphore functions + +dnl If we have POSIX semaphores available, check to see if we also have +dnl the timed wait capability. +if test "$ac_cv_func_sem_open" = yes && + test "$ac_cv_func_sem_close" = yes && + test "$ac_cv_func_sem_unlink" = yes; then + dnl Check if sem_timedwait() works - often it compiles and will run + dnl but if called return ENOTSUP. In that case, we don't want it. + ACE_CACHE_CHECK([if sem_timedwait works], + [ace_cv_sem_timedwait_works], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef ACE_LACKS_SYS_TYPES_H +#include +#endif + +#include +#include +#include +#include /* for definition of "NULL" */ +#if !defined (ACE_LACKS_ERRNO_H) +# include +#endif +#include + +#ifndef SEM_FAILED +# define SEM_FAILED ((sem_t *) -1) +#endif + +int +main () +{ + sem_t *s = 0; + struct timespec tmo; + int status = 0; + s = sem_open ("ace_semaphore_foo", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + return -1; /* FAILURE */ + + /* Don't care about the time, only whether the call works */ + tmo.tv_sec = 0; + tmo.tv_nsec = 0; + if (sem_timedwait (s, &tmo) == -1) + { + if (errno == ENOTSUP) + status = -1; + } + else + sem_post (s); + + sem_unlink ("ace_semaphore_foo"); + sem_close (s); + + return status; +} + ]])],[ + ace_cv_sem_timedwait_works=yes + ],[ + ace_cv_sem_timedwait_works=no + ],[ + dnl action if cross-compiling + ace_cv_sem_timedwait_works=yes + ]) + ], + [AC_DEFINE([ACE_HAS_POSIX_SEM_TIMEOUT])],) +fi + + +dnl The following tests are performed only when the user has enabled +dnl support for threads. + +dnl NOTE: Make sure the thread library is in "LIBS" +dnl (e.g.: LIBS="$LIBS -lpthread") +dnl otherwise the below thread "CHECK_FUNCs" +dnl will not work correctly. +if test "$ace_user_enable_threads" = yes; then + + if test "$ace_has_pthreads" = yes; then +dnl Digital UNIX 4.0 "mangles" the following pthread functions: +dnl pthread_attr_getguardsize_np +dnl pthread_attr_getinheritsched +dnl pthread_attr_getstacksize +dnl pthread_attr_setguardsize_np +dnl pthread_attr_setinheritsched +dnl pthread_attr_setstacksize +dnl pthread_cancel +dnl pthread_cond_broadcast +dnl pthread_cond_destroy +dnl pthread_cond_init +dnl pthread_cond_sig_preempt_int_np +dnl pthread_cond_signal +dnl pthread_cond_signal_int_np +dnl pthread_cond_timedwait +dnl pthread_cond_wait +dnl pthread_create +dnl pthread_delay_np +dnl pthread_detach +dnl pthread_equal +dnl pthread_exit +dnl pthread_get_expiration_np +dnl pthread_getspecific +dnl pthread_join +dnl pthread_lock_global_np +dnl pthread_mutex_destroy +dnl pthread_mutex_init +dnl pthread_mutex_lock +dnl pthread_mutex_trylock +dnl pthread_mutex_unlock +dnl pthread_once +dnl pthread_self +dnl pthread_setspecific +dnl pthread_testcancel +dnl pthread_unlock_global_np +dnl These functions have a double underscore "__" prepended to maintain +dnl backwards compatibility with Pthread Draft 4 functions of the same +dnl name. + + ACE_CHECK_LACKS_FUNCS(pthread_sigmask) + if test $ac_cv_func_pthread_sigmask = yes; then + AC_CHECK_DECL([pthread_sigmask], + [AC_DEFINE([ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE], 1, + [Define to 1 if platform has the declaration + of pthread_sigmask().])], + [], + [#include + #include ]) + fi + + AC_CHECK_FUNC([pthread_key_create], + [AC_DEFINE([ACE_HAS_THREAD_SPECIFIC_STORAGE])], + [ + AC_CHECK_FUNC([pthread_keycreate], + [AC_DEFINE(ACE_HAS_THREAD_SPECIFIC_STORAGE)], + [AC_DEFINE(ACE_HAS_TSS_EMULATION)]) + ]) + + ACE_CHECK_HAS_FUNCS(pthread_condattr_setkind_np) + ACE_CHECK_HAS_FUNCS(pthread_mutexattr_setkind_np) + + dnl Can't use ACE_CHECK_LACKS_FUNCS because the macro doesn't match the + dnl tested function name. + AC_CHECK_FUNC([pthread_condattr_setpshared], + , + [AC_DEFINE([ACE_LACKS_CONDATTR_PSHARED])]) + + dnl ACE_CHECK_LACKS_FUNCS(pthread_attr_setstack) + dnl Can't use ACE_CHECK_LACKS_FUNCS because the lower-down AC macros build + dnl a program with a stubbed-out pthread_attr_setstack(), avoiding the need + dnl to see pthread_attr_setstack() in pthreads.h. This is usually not a + dnl problem since the link will fail. However, on HP-UX 11iv2 there is a + dnl pthread_attr_setstack() in libpthread, but not in the header. Thus, + dnl the test passes, but ACE build fails. Don't hack in use of this until + dnl HP sees fit to include it in pthread.h (which it does at 11iv3). + AC_MSG_CHECKING([for pthread_attr_setstack]) + AH_TEMPLATE([ACE_LACKS_PTHREAD_ATTR_SETSTACK], + [Define to 1 if platform lacks pthread_attr_setstack()]) + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + pthread_attr_t attr; + void *stack; + size_t size; + pthread_attr_setstack (&attr, stack, size); + ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + AC_DEFINE([ACE_LACKS_PTHREAD_ATTR_SETSTACK]) + ]) + + ACE_CHECK_LACKS_FUNCS(pthread_attr_setstackaddr) + ACE_CHECK_LACKS_FUNCS(pthread_attr_setstacksize) + + ACE_CHECK_FUNC([pthread_cancel], [pthread.h], + [ + dnl Make sure the prototype actually exists. Some platforms, + dnl such as FreeBSD 4, appear to have a missing prototype. If + dnl the prototype is missing, then don't use pthread_cancel. + dnl Creating a prototype for it in ACE is probably a bad idea. + + ace_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ACE_THR_CPPFLAGS" + + AC_EGREP_HEADER([pthread_cancel], [pthread.h],, + [ + AC_DEFINE([ACE_LACKS_PTHREAD_CANCEL]) + ]) + + dnl Reset the preprocessor flags + CPPFLAGS="$ace_save_CPPFLAGS" + ], + [ + AC_DEFINE([ACE_LACKS_PTHREAD_CANCEL]) + ]) + + ACE_CHECK_LACKS_FUNCS(pthread_yield) + ACE_CHECK_LACKS_FUNCS(pthread_thr_sigsetmask) + + AC_CHECK_FUNC([pthread_attr_setdetachstate], + , + [AC_DEFINE([ACE_LACKS_SETDETACH])]) + + dnl ACE currently doesn't provide enough fine grained control over + dnl these functions so both must be present in order to prevent + dnl ACE_LACKS_SETSCHED from being defined. + AC_CHECK_FUNC([sched_setscheduler], + [ + AC_CHECK_FUNC([pthread_attr_setschedpolicy],, + [AC_CHECK_FUNC([pthread_attr_setsched],, + [AC_DEFINE([ACE_LACKS_SETSCHED])])]) + ], + [ + AC_DEFINE([ACE_LACKS_SETSCHED]) + ]) + + AC_CHECK_FUNC([pthread_attr_setscope], + , + [AC_DEFINE([ACE_LACKS_THREAD_PROCESS_SCOPING])]) + + AC_CHECK_FUNC([pthread_mutexattr_setpshared], + , + [AC_DEFINE([ACE_LACKS_MUTEXATTR_PSHARED])]) + +dnl Check for POSIX Threads Draft 4 functions + AC_CHECK_FUNC([pthread_mutexattr_create],,) + AC_CHECK_FUNC([pthread_mutexattr_delete],,) + AC_CHECK_FUNC([pthread_condattr_delete],,) + AC_CHECK_FUNC([pthread_condattr_create],,) + AC_CHECK_FUNC([pthread_setprio],,) + AC_CHECK_FUNC([pthread_getprio],,) + AC_CHECK_FUNC([pthread_setcancel],,) + AC_CHECK_FUNC([pthread_setasynccancel],,) + AC_CHECK_FUNC([pthread_kill],,) +dnl Check for POSIX Threads Draft 6 functions + AC_CHECK_FUNC([pthread_attr_setprio],,) + AC_CHECK_FUNC([pthread_attr_getprio],,) + AC_CHECK_FUNC([pthread_setintr],,) + AC_CHECK_FUNC([pthread_setintrtype],,) +dnl Check for POSIX threads Draft 6, 7 and Standard common functions + AC_CHECK_FUNC([pthread_mutexattr_init],,) + AC_CHECK_FUNC([pthread_mutexattr_destroy],,) + AC_CHECK_FUNC([pthread_condattr_init],,) + AC_CHECK_FUNC([pthread_condattr_destroy],,) +dnl Check for POSIX Threads Draft 7 and Draft Standard common functions + AC_CHECK_FUNC([pthread_setschedparam],,) + AC_CHECK_FUNC([pthread_getschedparam],,) + AC_CHECK_FUNC([pthread_setcancelstate],,) + AC_CHECK_FUNC([pthread_setcanceltype],,) +dnl Check for POSIX Threads Draft Standard functions +dnl sched_yield() is in the C library or perhaps in "-lposix4." +dnl We need to add other library checks in this script's "check libraries" +dnl section if it is in another library. +dnl AC_CHECK_FUNC(sched_yield,,) +dnl We already check for this during the library checks. + +dnl Check for Unix98 pthreads extensions + ACE_CACHE_CHECK([for struct pthread_rwlock_t], + [ace_cv_struct_pthread_rwlock_t], + [ + dnl Since we are checking for pthread_rwlock_t in more than one header + dnl we can't use the ACE_CHECK_STRUCT macro so we have to do things + dnl manually. + ACE_TRY_COMPILE_STRUCT([pthread_rwlock_t], [pthread.h], + [ + ace_cv_struct_pthread_rwlock_t=yes + ], + [ + ACE_TRY_COMPILE_STRUCT([pthread_rwlock_t], [sys/types.h], + [ + ace_cv_struct_pthread_rwlock_t=yes + ], + [ + ace_cv_struct_pthread_rwlock_t=no + ]) + ]) + ],,) + + ACE_CACHE_CHECK([for struct pthread_rwlockattr_t], + [ace_cv_struct_pthread_rwlockattr_t], + [ + dnl Since we are checking for pthread_rwlockattr_t in more than one + dnl header, we can't use the ACE_CHECK_STRUCT macro so we have to do + dnl things manually. + ACE_TRY_COMPILE_STRUCT([pthread_rwlockattr_t], [pthread.h], + [ + ace_cv_struct_pthread_rwlockattr_t=yes + ], + [ + ACE_TRY_COMPILE_STRUCT([pthread_rwlockattr_t], [sys/types.h], + [ + ace_cv_struct_pthread_rwlockattr_t=yes + ], + [ + ace_cv_struct_pthread_rwlockattr_t=no + ]) + ]) + ],,) + + ACE_CHECK_HAS_FUNCS(pthread_continue pthread_continue_np pthread_resume_np pthread_suspend pthread_suspend_np) + ACE_CHECK_HAS_FUNCS(pthread_getconcurrency pthread_setconcurrency) + ACE_CHECK_HAS_FUNCS(pthread_attr_setcreatesuspend_np) + +dnl Don't test for pthread_getaffinity_np() or pthread_setaffinity_np() +dnl if the system doesn't also have cpu_set_t. The functions are almost +dnl certainly incompatible with our wrapper facade, as we use a "dummy" +dnl cpu_set_t defined in ace/os_include/os_sched.h. +if test "$ac_cv_type_cpu_set_t" = yes; then + ACE_CHECK_HAS_FUNCS(pthread_getaffinity_np pthread_setaffinity_np) +fi + +dnl Linux's sched_{set,get}affinity interface has changed three times: +dnl +dnl In glibc 2.3.2, it was: +dnl +dnl int sched_setaffinity(pid_t __pid, +dnl unsigned int __len, unsigned long * __mask); +dnl +dnl In glibc 2.3.3, it was changed to: +dnl +dnl int sched_setaffinity(pid_t __pid, const cpu_set_t* __mask); +dnl +dnl And in glibc ?.?.?, it was changed again to: +dnl +dnl int sched_setaffinity(pid_t __pid, size_t __cpusetsize, +dnl const cpu_set_t* __cpuset); +dnl +dnl The following feature tests attempt to determine which (if any) +dnl version is supported by the system. A further complication is +dnl that the C library may support one version, the kernel may not, +dnl and vice versa. +dnl +dnl As of this writing, ACE's ACE_OS::sched_setaffinity() wrapper +dnl facade implementation only supports the latter two varients. So +dnl if the system doesn't define cpu_set_t, we simply avoid checking +dnl for sched_setaffinity(). No attempt is made to verify C library / +dnl kernel consistency. +dnl +dnl The "right" thing to do is to implement something similar to the +dnl PLPA (Portable Linux Processor Affinity) Library, converting the +dnl arguments and invoking the syscall directly (instead of calling +dnl the C library wrapper). +dnl + +if test "$ac_cv_type_cpu_set_t" = yes; then + + ACE_CHECK_HAS_FUNCS(sched_getaffinity) +if test "$ac_cv_func_sched_getaffinity" = yes; then +dnl The sched_getaffinity() function varies between linux versions +dnl Check which one we have. +AC_MSG_CHECKING([for 2- or 3-param sched_getaffinity]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#if !defined(ACE_LACKS_SYS_TYPES_H) +#include +#endif +#if !defined(ACE_LACKS_SCHED_H) +#include +#endif + ]], + [[ + pid_t pid; + cpu_set_t cpuset; + sched_getaffinity(pid, sizeof(cpuset), &cpuset); + ]])], + [ + AC_MSG_RESULT([3]) + ], + [ + AC_MSG_RESULT([2]) + AC_DEFINE([ACE_HAS_2_PARAM_SCHED_GETAFFINITY], 1, + [Define to 1 if platform has 2 parameter sched_getaffinity()]) + ]) +fi dnl test "$ac_cv_func_sched_getaffinity" = yes + + ACE_CHECK_HAS_FUNCS(sched_setaffinity) +if test "$ac_cv_func_sched_setaffinity" = yes; then +dnl The sched_setaffinity() function varies between linux versions +dnl Check which one we have. +AC_MSG_CHECKING([for 2- or 3-param sched_setaffinity]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#if !defined(ACE_LACKS_SYS_TYPES_H) +#include +#endif +#if !defined(ACE_LACKS_SCHED_H) +#include +#endif + ]], + [[ + pid_t pid; + cpu_set_t cpuset; + sched_setaffinity(pid, sizeof(cpuset), &cpuset); + ]])], + [ + AC_MSG_RESULT([3]) + ], + [ + AC_MSG_RESULT([2]) + AC_DEFINE([ACE_HAS_2_PARAM_SCHED_SETAFFINITY], 1, + [Define to 1 if platform has 2 parameter sched_setaffinity()]) + ]) +fi dnl test "$ac_cv_func_sched_setaffinity" = yes + +fi dnl test "$ac_cv_type_cpu_set_t" = yes + + AC_CHECK_FUNC([pthread_rwlock_init],,) + AC_CHECK_FUNC([pthread_rwlock_destroy],,) + AC_CHECK_FUNC([pthread_rwlock_rdlock],,) + AC_CHECK_FUNC([pthread_rwlock_wrlock],,) + AC_CHECK_FUNC([pthread_rwlock_unlock],,) + AC_CHECK_FUNC([pthread_rwlock_tryrdlock],,) + AC_CHECK_FUNC([pthread_rwlock_trywrlock],,) + AC_CHECK_FUNC([pthread_rwlockattr_init],,) + AC_CHECK_FUNC([pthread_rwlockattr_destroy],,) + AC_CHECK_FUNC([pthread_rwlockattr_setpshared], + , + [AC_DEFINE([ACE_LACKS_RWLOCKATTR_PSHARED])]) + + if test "$ace_cv_struct_pthread_rwlock_t" = yes && + test "$ace_cv_struct_pthread_rwlockattr_t" = yes && + test "$ac_cv_func_pthread_rwlock_init" = yes && + test "$ac_cv_func_pthread_rwlock_destroy" = yes && + test "$ac_cv_func_pthread_rwlock_rdlock" = yes && + test "$ac_cv_func_pthread_rwlock_wrlock" = yes && + test "$ac_cv_func_pthread_rwlock_unlock" = yes && + test "$ac_cv_func_pthread_rwlock_tryrdlock" = yes && + test "$ac_cv_func_pthread_rwlock_trywrlock" = yes && + test "$ac_cv_func_pthread_rwlockattr_init" = yes && + test "$ac_cv_func_pthread_rwlockattr_destroy" = yes; then + AC_DEFINE([ACE_HAS_PTHREADS_UNIX98_EXT]) + fi dnl Unix98 pthreads extensions + +dnl Check if platform has thread_self() rather than pthread_self() + ACE_CHECK_FUNC([pthread_self], [pthread.h], + , + [ + AC_CHECK_FUNC([thread_self], + [ + AC_DEFINE([ACE_HAS_THREAD_SELF]) + ],) + ]) + +dnl Check if pthread.h declares an enum with PTHREAD_PROCESS_PRIVATE and +dnl PTHREAD_PROCESS_SHARED values. + ACE_CACHE_CHECK([for PTHREAD_PROCESS_* enumeration in pthread.h], + [ace_cv_lib_pthread_process_enum], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ +/* Undefine PTHREAD_PROCESS_SHARED in case some platforms #define it */ +#undef PTHREAD_PROCESS_SHARED +int foo = PTHREAD_PROCESS_SHARED; + ]])],[ + ace_cv_lib_pthread_process_enum=yes + ],[ + ace_cv_lib_pthread_process_enum=no + ]) + ], + [ + AC_DEFINE([ACE_HAS_PTHREAD_PROCESS_ENUM]) + ],) + +dnl Check if pthread_create requires an extern "C" start routine +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if pthread_create requires an extern "C" start routine], + [ace_cv_lib_pthread_c_func],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +void *ace_start_routine(void *); + ]], [[ +pthread_create(0, 0, ace_start_routine, 0); + ]])],[ + ace_cv_lib_pthread_c_func=no + ],[ + dnl Check if extern "C" start routine is required. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + +extern "C" void *ace_start_routine(void *); + ]], + [[ +pthread_create(0, 0, ace_start_routine, 0); + ]])], + [ + ace_cv_lib_pthread_c_func=yes + ], + [ + ace_cv_lib_pthread_c_func=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_THR_C_FUNC]) + ],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if pthread_key_create has a standard arg thread destructor +ACE_CACHE_CHECK([if pthread_key_create has std arg thread destructor], + [ace_cv_lib_pthread_stdarg_dest],[ + if test "$ac_cv_func_pthread_key_create" = yes; then + ace_pthread_key_create=pthread_key_create + else + ace_pthread_key_create=pthread_keycreate + fi + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +void ace_destructor(void *); + ]], [[ +${ace_pthread_key_create}(0, ace_destructor); + ]])],[ + ace_cv_lib_pthread_stdarg_dest=no + ],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + +void ace_destructor(...); + ]], + [[ +${ace_pthread_key_create}(0, ace_destructor); + ]])], + [ + ace_cv_lib_pthread_stdarg_dest=yes + ], + [ + ace_cv_lib_pthread_stdarg_dest=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_STDARG_THR_DEST]) + ],) + +dnl Check if pthread_key_create requires an extern "C" start routine +ACE_CONVERT_WARNINGS_TO_ERRORS([ +ACE_CACHE_CHECK([if pthread_key_create requires an extern "C" start routine], + [ace_cv_lib_pthread_c_dest],[ + if test "$ac_cv_func_pthread_key_create" = yes; then + ace_pthread_key_create=pthread_key_create + else + ace_pthread_key_create=pthread_keycreate + fi + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +void ace_destructor(void *); + ]], [[ +${ace_pthread_key_create}(0, ace_destructor); + ]])],[ + ace_cv_lib_pthread_c_dest=no + ],[ + dnl Check if extern "C" start routine is required. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + +extern "C" void ace_destructor(void *); + ]], + [[ +${ace_pthread_key_create}(0, ace_destructor); + ]])], + [ + ace_cv_lib_pthread_c_dest=yes + ], + [ + ace_cv_lib_pthread_c_dest=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_THR_C_DEST]) + ],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + + +AC_CHECK_FUNC([sched_get_priority_min],, + [ +dnl Check if the PTHREAD_MIN_PRIORITY constant exists. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + int p = (int) PTHREAD_MIN_PRIORITY; + ]]) + ], + [ + dnl Since we have PTHREAD_MIN_PRIORITY, denote that PX_PRIO_MIN + dnl should not be used. + ace_has_px_prio_min=no + ], + [ + dnl PTHREAD_MIN_PRIORITY doesn't appear to be defined, so + dnl check if the platform defines PX_PRIO_MIN, instead. + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + int p = (int) PX_PRIO_MIN; + ]])], + [ + ace_has_px_prio_min=yes + ], + [ + ace_has_px_prio_min=no + ]) + ]) + ]) + + if test "$ace_has_px_prio_min" = yes; then + AC_DEFINE([PTHREAD_MIN_PRIORITY], + [PX_PRIO_MIN], + [Minimum thread priority]) + fi + +AC_CHECK_FUNC([sched_get_priority_max],, + [ +dnl Check if the PTHREAD_MAX_PRIORITY constant exists. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + int p = (int) PTHREAD_MAX_PRIORITY; + ]]) + ], + [ + dnl Since we have PTHREAD_MAX_PRIORITY, denote that PX_PRIO_MAX + dnl should not be used. + ace_has_px_prio_max=no + ], + [ + dnl PTHREAD_MAX_PRIORITY doesn't appear to be defined, so + dnl check if the platform defines PX_PRIO_MAX, instead. + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + int p = (int) PX_PRIO_MAX; + ]])], + [ + ace_has_px_prio_max=yes + ], + [ + ace_has_px_prio_max=no + ]) + ]) + ]) + + if test "$ace_has_px_prio_max" = yes; then + AC_DEFINE([PTHREAD_MAX_PRIORITY], + [PX_PRIO_MAX], + [Maximum thread priority]) + fi + + fi dnl test "$ace_has_pthreads" = yes + + if test "$ace_has_sthreads" = yes; then +dnl Only check for these functions if we have the UNIX International +dnl Threads library "thread." + AC_CHECK_FUNC([thr_keycreate], + [AC_DEFINE([ACE_HAS_THREAD_SPECIFIC_STORAGE])], + [AC_DEFINE([ACE_HAS_TSS_EMULATION])]) + + AC_CHECK_FUNC([thr_yield], + [AC_DEFINE([ACE_HAS_THR_YIELD])],) + + AC_CHECK_FUNC([thr_keydelete], + [AC_DEFINE([ACE_HAS_THR_KEYDELETE])],) + + AC_CHECK_FUNC([thr_min_stack],[], + [ + AC_CHECK_FUNC([thr_minstack], + [AC_DEFINE([ACE_HAS_THR_MINSTACK])],) + ]) + + fi dnl test "$ace_has_sthreads" = yes + +fi dnl test "$ace_user_enable_threads" = yes + +dnl +dnl By Eric: +dnl ACE will define a sigwait function if we lie and say we don't have +dnl one. Unfortunately, the ACE function may conflict with our +dnl function, so we'll go ahead and turn this on, even if we are +dnl ignoring threads. +ACE_CHECK_HAS_FUNCS(sigwait) + + +dnl Check for reentrant functions +if test "$ace_user_enable_reentrant_funcs" = yes; then + AC_CHECK_FUNC([rand_r]) + + AC_CHECK_FUNC([strtok_r], + [ + dnl Check if _POSIX_SOURCE macro is needed to make the strtok_r() + dnl prototype visible. + ACE_CACHE_CHECK([for strtok_r prototype], + [ace_cv_lib_has_strtok_r_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_posix="-U_POSIX_SOURCE $ACE_THR_CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ace_no_posix" + AC_EGREP_HEADER([[^_]+strtok_r], [string.h], + [ + ace_cv_lib_has_strtok_r_prototype=yes + ], + [ + ace_cv_lib_has_strtok_r_prototype=no + ]) + dnl Reset the preprocessor flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],, [AC_DEFINE([ACE_LACKS_STRTOK_R_PROTOTYPE])]) + ],) + + AC_CHECK_FUNC([getpwnam_r], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef _REENTRANT +# define _REENTRANT +#endif +#ifndef ACE_LACKS_PWD_H +# include +#endif +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif + ]], + [[ + const char * name; + struct passwd * pwent; + char * buffer; + int buflen; + struct passwd * result; + + int status = getpwnam_r (name, pwent, buffer, buflen, &result); + ]])], + [ + if test "$ace_user_enable_reentrant_funcs" = yes; then + AC_DEFINE([ACE_HAS_POSIX_GETPWNAM_R]) + fi + ], + [ + dnl Nothing to do! + ]) + ], + [AC_DEFINE([ACE_LACKS_PWD_REENTRANT_FUNCTIONS])]) + + AC_CHECK_FUNC([ctime_r],,) + + AC_CHECK_FUNC([localtime_r],,) + + AC_CHECK_FUNC([gmtime_r],,) + + AC_CHECK_FUNC([asctime_r],,) + + AC_CHECK_FUNC([getprotobyname_r],,) + + AC_CHECK_FUNC([getprotobynumber_r],,) + + AC_CHECK_FUNC([gethostbyaddr_r],,) + + AC_CHECK_FUNC([gethostbyname_r],,) + + AC_CHECK_FUNC([getservbyname_r],,) +fi dnl End checks for reentrant functions + + +ACE_CHECK_LACKS_FUNCS(readdir_r) +if test "$ac_cv_func_readdir_r" = yes; then +dnl The readdir_r() function varies with standards. Check which one we have. +AC_MSG_CHECKING([for 2- or 3-param readdir_r]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +readdir_r(0, 0, 0); + ]])], + [ + AC_DEFINE([ACE_HAS_3_PARAM_READDIR_R], 1, + [Define to 1 if platform has 3 parameter readdir_r()]) + AC_MSG_RESULT([3]) + ], + [ + AC_MSG_RESULT([2]) + ]) +fi dnl test "$ac_cv_func_readdir" = yes + + +dnl Disabled until we figure out what to do with the comparator +dnl function argument inconsistencies between different platforms. +dnl For example: +dnl int comparator (const void * d1, const void * d2) +dnl instead of: +dnl int comparator (const dirent ** d1, const dirent ** d2) +dnl +dnl ACE_CHECK_HAS_FUNCS([scandir]) + +ACE_CHECK_LACKS_FUNCS(seekdir telldir) + + +dnl +dnl SECTION 11: checks for function characteristics +dnl + +ACE_CONVERT_WARNINGS_TO_ERRORS([ +dnl Check if dlopen takes a char * arg instead of const char * + if test "$ace_has_svr4_dynamic_linking" = yes; then + ACE_CACHE_CHECK([if dlopen takes a char *], + [ace_cv_lib_charptr_dl], + [ + dnl Check if it takes a const char *, first. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + const char *filename = 0; + int flag = 0; + void *ptr = dlopen(filename, flag); + ]])],[ + ace_cv_lib_charptr_dl=no + ],[ + dnl Now check if it takes a non-const char *. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + char *filename = 0; + int flag = 0; + void *ptr = dlopen(filename, flag); + ]])], + [ + ace_cv_lib_charptr_dl=yes + ], + [ + ace_cv_lib_charptr_dl=no + ]) + ]) + ], [AC_DEFINE([ACE_HAS_CHARPTR_DL])],) + fi dnl test "$ace_has_svr4_dynamic_linking" = yes +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +ACE_CONVERT_WARNINGS_TO_ERRORS([ +dnl Check if "getby" functions use a non-const char * argument + if test "$ac_cv_func_gethostbyaddr" = yes; then + ACE_CACHE_CHECK(["getby" functions take a non-const char *], + [ace_cv_lib_nonconst_getby], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + char *addr = 0; + int len = 0; + int type = 0; + struct hostent *mystruct = 0; + + mystruct = gethostbyaddr(name, len, type); + ]])],[ + ace_cv_lib_nonconst_getby=yes + ],[ + ace_cv_lib_nonconst_getby=no + ]) + ], [AC_DEFINE([ACE_HAS_NONCONST_GETBY])],) + fi dnl test "$ac_cv_func_gethostbyaddr" = yes +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if new throws exception upon failure +if test "$ace_user_enable_exceptions" = yes; then + ACE_CACHE_CHECK([if new throws std::bad_alloc exception on failure], + [ace_cv_new_throws_bad_alloc_exception], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#if defined (ACE_HAS_NEW_NO_H) +# include +#elif defined (ACE_HAS_NEW_H) +# include +#endif + +#if defined (ACE_HAS_STDEXCEPT_NO_H) +# include +#elif defined (ACE_HAS_EXCEPTION_H) +# include +#endif + +/* We already checked for ACE_LACKS_NUMERIC_LIMITS */ +#if !defined ACE_LACKS_NUMERIC_LIMITS +#include +#endif + +/* We already checked for ACE_LACKS_SYS_RESOURCE_H */ +#if !defined ACE_LACKS_SYS_RESOURCE_H +#include +#endif + + int main(int, char *[]) { +#if defined ACE_LACKS_NUMERIC_LIMITS + const size_t ALLOC_SIZE = 2 * 1024 * 1024 * 1024; +#else + const size_t ALLOC_SIZE = std::numeric_limits::max () / 2; +#endif + +#if !defined (ACE_LACKS_RLIMIT) + /* set memory limit to the allocation size, so this test + should terminate on the first iteration. */ + struct rlimit rlimit; + if (getrlimit(RLIMIT_DATA, &rlimit) == 0) { + rlimit.rlim_cur = ALLOC_SIZE; + setrlimit(RLIMIT_DATA, &rlimit); + } +#endif + + while (1) { + try { + char *a = new char[ALLOC_SIZE]; + if (a == 0) { + return 1; /* new() does NOT throw exceptions */ + } + } + +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + catch (std::bad_alloc) +#else + catch (bad_alloc) +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ + { + return 0; /* new() does throw exceptions */ + } + }; + + return 1; /* ERROR: We shouldn't get this far! */ + } + ]])],[ + ace_cv_new_throws_bad_alloc_exception=yes + ],[ + ace_cv_new_throws_bad_alloc_exception=no + ],[ + ace_cv_new_throws_bad_alloc_exception=no + ]) + ], [AC_DEFINE([ACE_NEW_THROWS_EXCEPTIONS])],) + + if test "$ace_cv_new_throws_bad_alloc_exception" != yes; then + ACE_CACHE_CHECK([if new throws xalloc exception on failure], + [ace_cv_new_throws_xalloc_exception], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#if defined (ACE_HAS_NEW_NO_H) +# include +#elif defined (ACE_HAS_NEW_H) +# include +#endif + +#if defined (ACE_HAS_STDEXCEPT_NO_H) +# include +#elif defined (ACE_HAS_EXCEPTION_H) +# include +#endif + +/* We already checked for ACE_LACKS_NUMERIC_LIMITS */ +#if !defined ACE_LACKS_NUMERIC_LIMITS +#include +#endif + +/* We already checked for ACE_LACKS_SYS_RESOURCE_H */ +#if !defined ACE_LACKS_SYS_RESOURCE_H +#include +#endif + + + int main(int, char *[]) { +#if defined ACE_LACKS_NUMERIC_LIMITS + const size_t ALLOC_SIZE = 2 * 1024 * 1024 * 1024; +#else + const size_t ALLOC_SIZE = std::numeric_limits::max () / 2; +#endif + +#if !defined (ACE_LACKS_RLIMIT) + /* set memory limit to the allocation size, so this test + should terminate on the first iteration. */ + struct rlimit rlimit; + if (getrlimit(RLIMIT_DATA, &rlimit) == 0) { + rlimit.rlim_cur = ALLOC_SIZE; + setrlimit(RLIMIT_DATA, &rlimit); + } +#endif + + while (1) { + try { + char *a = new char[ALLOC_SIZE]; + if (a == 0) { + return 1; /* new() does NOT throw exceptions */ + } + } + + catch (xalloc) + { + return 0; /* new() does throw exceptions */ + } + }; + + return 1; /* ERROR: We shouldn't get this far! */ + } + ]])],[ + ace_cv_new_throws_xalloc_exception=yes + ],[ + ace_cv_new_throws_xalloc_exception=no + ],[ + ace_cv_new_throws_xalloc_exception=no + ]) + ], [AC_DEFINE([ACE_NEW_THROWS_EXCEPTIONS])],) + fi dnl ace_cv_new_throws_bad_alloc_exceptions = no +fi dnl $ace_user_enable_exceptions = yes + +AC_CACHE_CHECK([if compiler supports new(std::nothrow)], + [ace_cv_has_new_nothrow], + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#if defined (ACE_HAS_NEW_NO_H) +# include +#elif defined (ACE_HAS_NEW_H) +# include +#endif + +int main(int, char*[]) { + int *foo; + +#ifdef ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB + foo = new (std::nothrow) int; +#else + foo = new (nothrow) int; +#endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */ +}]])], [ + ace_cv_has_new_nothrow=yes + ],[ + ace_cv_has_new_nothrow=no + ])]) +if test $ace_cv_has_new_nothrow = yes; then + AC_DEFINE([ACE_HAS_NEW_NOTHROW]) +fi + +ACE_CONVERT_WARNINGS_TO_ERRORS([ +dnl Check if putmsg takes a const struct strbuf * +dnl If we have getmsg() we can be pretty sure that we have putmsg() + if test "$ac_cv_func_getmsg" = yes || + test "$ac_cv_header_stropts_h" = yes; then + ACE_CACHE_CHECK([if putmsg takes a const struct strbuf*], + [ace_cv_lib_const_strbufptr], + [ + dnl Check if it takes a const struct strbuf *, first. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + int result = 0; + int fd = 0; + const struct strbuf * ace_str = 0; + int flags = 0; + + result = putmsg(fd, ace_str, ace_str, flags); + ]])],[ + ace_cv_lib_const_strbufptr=yes + ],[ + ace_cv_lib_const_strbufptr=no + ]) + ],, [AC_DEFINE([ACE_LACKS_CONST_STRBUF_PTR])]) + fi dnl "$ac_cv_func_getmsg" = yes || "$ac_cv_header_stropts_h" = yes +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if setrlimit() takes an enum as 1st argument +ACE_CHECK_SETRLIMIT_ENUM + +dnl This test fails (i.e. passes when it shouldn't) when compiling with +dnl GCC/G++ since the compiler treats passing a const to a non-const +dnl argument as a warning and not as an error since the const is +dnl simply discarded. To correct this problem, we use "-Werror" which +dnl converts all warnings to errors, whenever we are compiling with +dnl G++. +dnl -Ossama + +dnl Check if getrusage() takes an enum as 1st argument +ACE_CHECK_GETRUSAGE_ENUM + +dnl TODO: This doesn't work. +dnl The compiler in linux just issues a warning, and the test passes!!! +dnl +dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ +dnl -Ossama +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +dnl Check if select takes a const fifth argument (timeval) +ACE_CACHE_CHECK([if select takes a const struct timeval], + [ace_cv_lib_posix_select_const_timeval],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#ifndef ACE_LACKS_UNISTD_H +# include +#endif +#ifndef ACE_LACKS_SYS_SELECT_H +# include +#endif + ]], [[ + int n = 0; + fd_set *readfds = 0; + fd_set *writefds = 0; + fd_set *exceptfds = 0; + const struct timeval* timeout = 0; + select(n, readfds, writefds, exceptfds, timeout); + ]])],[ + ace_cv_lib_posix_select_const_timeval=yes + ],[ + ace_cv_lib_posix_select_const_timeval=no + ]) + ], , [AC_DEFINE([ACE_HAS_NONCONST_SELECT_TIMEVAL])]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + + +dnl Only run the following tests if the msghdr structure exists. +if test "$ace_cv_struct_msghdr" = yes && + test "$ac_cv_func_sendmsg" = yes; then + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ +dnl Check if sendmsg takes a const 2nd argument + ACE_CACHE_CHECK([if sendmsg omits const qualifier from the msghdr argument], + [ace_cv_lib_nonconst_sendmsg],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + int s = 0; + const struct msghdr *msg = 0; + unsigned int flags = 0; + + int result = 0; + + result = (int) sendmsg(s, msg, flags); + ]])],[ + ace_cv_lib_nonconst_sendmsg=no + ],[ + ace_cv_lib_nonconst_sendmsg=yes + ]) + ], [AC_DEFINE([ACE_HAS_NONCONST_SENDMSG])],) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS +fi dnl "$ace_cv_struct_msghdr" = yes && $ac_cv_func_sendmsg = yes + + +dnl Only run the following tests if the setrlimit function exists +if test "$ac_cv_func_setrlimit" = yes; then + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ +dnl Check if setrlimit() takes a const pointer as 2nd argument + ACE_CACHE_CHECK([if setrlimit omits const qualifier from the rlimit argument], + [ace_cv_lib_nonconst_setrlimit],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + ]], [[ + const struct rlimit* rlp = 0; + setrlimit(RLIMIT_CPU, rlp); + ]])],[ + ace_cv_lib_nonconst_setrlimit=no + ],[ + ace_cv_lib_nonconst_setrlimit=yes + ]) + ], [AC_DEFINE([ACE_HAS_NONCONST_SETRLIMIT])]) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS +fi dnl "$ac_cv_func_setrlimit" = yes; then + + +dnl Only run the following tests if the readv function exists +if test "$ac_cv_header_sys_uio_h" = yes && + test "$ac_cv_func_readv" = yes; then + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ +dnl Check if readv omits the const from the iovec argument + ACE_CACHE_CHECK([if readv omits const qualifier from the iovec argument], + [ace_cv_lib_nonconst_readv],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + +#include + ]], [[ + int filedes = 0; + const struct iovec *vector = 0; + size_t count = 0; + + int result = 0; + + result = (int) readv(filedes, vector, count); + ]])],[ + ace_cv_lib_nonconst_readv=no + ],[ + ace_cv_lib_nonconst_readv=yes + ]) + ], [AC_DEFINE([ACE_HAS_NONCONST_READV])],) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS +fi dnl $ac_cv_header_sys_uio_h = yes && $ac_cv_func_writev = yes + + +dnl Only run the following tests if the writev function exists +if test "$ac_cv_header_sys_uio_h" = yes && + test "$ac_cv_func_writev" = yes; then + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ +dnl Check if writev omits the const from the iovec argument + ACE_CACHE_CHECK([if writev omits const qualifier from the iovec argument], + [ace_cv_lib_nonconst_writev],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + +#include + ]], [[ + int filedes = 0; + const struct iovec *vector = 0; + size_t count = 0; + + int result = 0; + + result = (int) writev(filedes, vector, count); + ]])],[ + ace_cv_lib_nonconst_writev=no + ],[ + ace_cv_lib_nonconst_writev=yes + ]) + ], [AC_DEFINE([ACE_HAS_NONCONST_WRITEV])],) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS +fi dnl $ac_cv_header_sys_uio_h = yes && $ac_cv_func_writev = yes + + +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([for (struct sockaddr *) msg_name field in msghdr], + [ace_cv_lib_sockaddr_msg_name],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + msghdr ace_msghdr; + struct sockaddr *addr = 0; + + /* + * Note that some platforms declare msg_name to be a void*, + * in which case this assignment will work. + * Should we _not_ define ACE_HAS_SOCKADDR_MSG_NAME in that + * case? I tend to think it is more appropriate to define + * ACE_HAS_SOCKADDR_MSG_NAME rather than cast addr to a char*, + * as is done in ACE when the macro is not defined. + * -Ossama + */ + ace_msghdr.msg_name = (struct sockaddr *)addr; + ]])],[ + ace_cv_lib_sockaddr_msg_name=yes + ],[ + ace_cv_lib_sockaddr_msg_name=no + ]) + ], [AC_DEFINE([ACE_HAS_SOCKADDR_MSG_NAME])],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + + +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if setsockopt() takes a void* fourth argument], + [ace_cv_lib_posix_setsockopt_voidp_4], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + int s = 0; + int level = 0; + int optname = 0; + void* optval = 0; + +#if defined (ACE_HAS_SOCKLEN_T) + socklen_t optlen = 0; +#elif defined (ACE_HAS_SIZET_SOCKET_LEN) + size_t optlen = 0; +#else + int optlen = 0; +#endif + + setsockopt (s, level, optname, optval, optlen); + ]])],[ + ace_cv_lib_posix_setsockopt_voidp_4=yes + ],[ + ace_cv_lib_posix_setsockopt_voidp_4=no + ]) + ], + [ + AC_DEFINE([ACE_HAS_VOIDPTR_SOCKOPT]) + ], + [ + ACE_CACHE_CHECK([if setsockopt() takes a char* fourth argument], + [ace_cv_lib_posix_setsockopt_charp_4], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + int s = 0; + int level = 0; + int optname = 0; + char* optval = 0; + +#if defined (ACE_HAS_SOCKLEN_T) + socklen_t optlen = 0; +#elif defined (ACE_HAS_SIZET_SOCKET_LEN) + size_t optlen = 0; +#else + int optlen = 0; +#endif + + setsockopt (s, level, optname, optval, optlen); + ]])],[ + ace_cv_lib_posix_setsockopt_charp_4=yes + ],[ + ace_cv_lib_posix_setsockopt_charp_4=no + ]) + ], + [ + AC_DEFINE([ACE_HAS_CHARPTR_SOCKOPT]) + ],) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if mmap() takes a void* first argument], + [ace_cv_lib_posix_voidptr_mmap],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#ifndef ACE_LACKS_UNISTD_H +# include +#endif +#include + ]], [[ + void *start = 0; + size_t length = 0; + int prot = 0; + int flags = 0; + int fd = 0; + off_t offset = 0; + + void *result = 0; + + result = (void *)mmap(start, length, prot, flags, fd, offset); + ]])],[ + ace_cv_lib_posix_voidptr_mmap=yes + ],[ + ace_cv_lib_posix_voidptr_mmap=no + ]) + ], [AC_DEFINE([ACE_HAS_VOIDPTR_MMAP])],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if platform has iostream method ipfx() +ACE_CACHE_CHECK([for iostream method ipfx()], + [ace_cv_feature_has_iostream_ipfx],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + cin.ipfx(); + ]])],[ + ace_cv_feature_has_iostream_ipfx=yes + ],[ + ace_cv_feature_has_iostream_ipfx=no + ]) + ], , [AC_DEFINE([ACE_LACKS_IOSTREAM_FX])]) + +dnl Check if platform has line-buffered streambufs +ACE_CACHE_CHECK([for line-buffered streambufs], + [ace_cv_feature_has_linebuffered_streambuf],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + cin.rdbuf()->linebuffered(1); + ]])],[ + ace_cv_feature_has_linebuffered_streambuf=yes + ],[ + ace_cv_feature_has_linebuffered_streambuf=no + ]) + ], , [AC_DEFINE([ACE_LACKS_LINEBUFFERED_STREAMBUF])]) + +dnl Check if platform has unbuffered streambufs +ACE_CACHE_CHECK([for unbuffered streambufs], + [ace_cv_feature_has_unbuffered_streambuf],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + cin.rdbuf()->unbuffered(1); + ]])],[ + ace_cv_feature_has_unbuffered_streambuf=yes + ],[ + ace_cv_feature_has_unbuffered_streambuf=no + ]) + ], , [AC_DEFINE([ACE_LACKS_UNBUFFERED_STREAMBUF])]) + + +dnl Check if signal takes a void (*)(int) as second argument +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if signal takes a void (*)(int) as second argument], + [ace_cv_lib_signal_vi1_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(int); + static void handler(int) { } + ]], [[ + SA nn = handler; + signal(SIGINT, nn); + ]])],[ + ace_cv_lib_signal_vi1_2=yes + ],[ + dnl Check if extern "C" signal handler is required. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include +extern "C" + { + typedef void (*SA)(int); + void handler(int) { } + } + ]], + [[ + SA nn = handler; + signal(SIGINT, nn); + ]])], + [ + ace_cv_lib_signal_vi1_2=yes + ], + [ + ace_cv_lib_signal_vi1_2=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_SIG_C_FUNC]) + ],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if signal takes a void (*)(void) as second argument +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if signal takes a void (*)(void) as second argument], + [ace_cv_lib_signal_vv1_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(void); + void handler(void) { } + ]], [[ + SA nn = handler; + signal(SIGINT, nn); + ]])],[ + ace_cv_lib_signal_vv1_2=yes + ],[ + dnl Check if extern "C" signal handler is required. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include +extern "C" + { + typedef void (*SA)(void); + void handler(void) { } + } + ]], + [[ + SA nn = handler; + signal(SIGINT, nn); + ]])], + [ + ace_cv_lib_signal_vv1_2=yes + ], + [ + ace_cv_lib_signal_vv1_2=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_SIG_C_FUNC]) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if signal takes a void (*)(int, ...) as second argument +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if signal takes a void (*)(int, ...) as second argument], + [ace_cv_lib_signal_vi1a2_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(int, ...); + void handler(int, ...) { } + ]], [[ + SA nn = handler; + signal(SIGINT, nn); + ]])],[ + ace_cv_lib_signal_vi1a2_2=yes + ],[ + dnl Check if extern "C" signal handler is required. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include +extern "C" + { + typedef void (*SA)(int, ...); + void handler(int, ...) { } + } + ]], + [[ + SA nn = handler; + signal(SIGINT, nn); + ]])], + [ + ace_cv_lib_signal_vi1a2_2=yes + ], + [ + ace_cv_lib_signal_vi1a2_2=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_SIG_C_FUNC]) + ],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if signal takes a void (*)(...) as second argument +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +ACE_CACHE_CHECK([if signal takes a void (*)(...) as second argument], + [ace_cv_lib_signal_va1_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(...); + void handler(...) { } + ]], [[ + SA nn = handler; + signal(SIGINT, nn); + ]])],[ + ace_cv_lib_signal_va1_2=yes + ],[ + dnl Check if extern "C" signal handler is required. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include +extern "C" + { + typedef void (*SA)(...); + void handler(...) { } + } + ]], + [[ + SA nn = handler; + signal(SIGINT, nn); + ]])], + [ + ace_cv_lib_signal_va1_2=yes + ], + [ + ace_cv_lib_signal_va1_2=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_HAS_SIG_C_FUNC]) + ],) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl Check if signal returns a void (*)(int) +AC_CACHE_CHECK([if signal returns a void (*)(int)], + [ace_cv_lib_signal_vi1_ret],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +typedef void (*SA)(int); +void foo(SA nn) { } + ]], [[ +SA nn = SIG_DFL; +nn = signal(SIGINT, 0); +foo(nn); + ]])],[ + ace_cv_lib_signal_vi1_ret=yes + ],[ + ace_cv_lib_signal_vi1_ret=no + ]) + ]) + +dnl Check if signal returns a void (*)(void) +AC_CACHE_CHECK([if signal returns a void (*)(void)], + [ace_cv_lib_signal_vv1_ret],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +typedef void (*SA)(void); +void foo(SA nn) { } + ]], [[ +SA nn = SIG_DFL; +nn = signal(SIGINT, 0); +foo(nn); + ]])],[ + ace_cv_lib_signal_vv1_ret=yes + ],[ + ace_cv_lib_signal_vv1_ret=no + ]) + ]) + +dnl Check if signal returns a void (*)(int, ...) +AC_CACHE_CHECK([if signal returns a void (*)(int, ...)], + [ace_cv_lib_signal_vi1a2_ret],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +typedef void (*SA)(int, ...); + ]], [[ + SA oo = signal(SIGINT, 0); + ]])],[ + ace_cv_lib_signal_vi1a2_ret=yes + ],[ + ace_cv_lib_signal_vi1a2_ret=no + ]) + ]) + +dnl Check if signal returns a void (*)(...) +AC_CACHE_CHECK([if signal returns a void (*)(...)], + [ace_cv_lib_signal_va1_ret],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +typedef void (*SA)(...); + ]], [[ + SA oo = signal(SIGINT, 0); + ]])],[ + ace_cv_lib_signal_va1_ret=yes + ],[ + ace_cv_lib_signal_va1_ret=no + ]) + ]) + +if test "$ace_cv_struct_sigaction" = yes; then +dnl Check if struct sigaction takes a void (*)(int) handler + AC_CACHE_CHECK([if struct sigaction takes a void (*)(int) handler], + [ace_cv_lib_struct_sigaction_vi1_handler],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(int); + void foo(struct sigaction* sa, SA nn) { } + ]], [[ + struct sigaction sa; + SA nn = SIG_DFL; + sa.sa_handler = nn; + foo(&sa, nn); + ]])],[ + ace_cv_lib_struct_sigaction_vi1_handler=yes + ],[ + ace_cv_lib_struct_sigaction_vi1_handler=no + ]) + ]) + +dnl Check if struct sigaction takes a void (*)(void) handler + AC_CACHE_CHECK([if struct sigaction takes a void (*)(void) handler], + [ace_cv_lib_struct_sigaction_vv1_handler],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(void); + void foo(struct sigaction* sa, SA nn) { } + ]], [[ + struct sigaction sa; + SA nn = SIG_DFL; + sa.sa_handler = nn; + foo(&sa, nn); + ]])],[ + ace_cv_lib_struct_sigaction_vv1_handler=yes + ],[ + ace_cv_lib_struct_sigaction_vv1_handler=no + ]) + ]) + +dnl Check if struct sigaction takes a void (*)(int, ...) handler + AC_CACHE_CHECK([if struct sigaction takes a void (*)(int, ...) handler], + [ace_cv_lib_struct_sigaction_vi1a2_handler],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(int, ...); + void foo(struct sigaction* sa, SA nn) { } + ]], [[ + struct sigaction sa; + SA nn = SIG_DFL; + sa.sa_handler = nn; + foo(&sa, nn); + ]])],[ + ace_cv_lib_struct_sigaction_vi1a2_handler=yes + ],[ + ace_cv_lib_struct_sigaction_vi1a2_handler=no + ]) + ]) + +dnl Check if struct sigaction takes a void (*)(...) handler + AC_CACHE_CHECK([if struct sigaction takes a void (*)(...) handler], + [ace_cv_lib_struct_sigaction_va1_handler],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + typedef void (*SA)(...); + void foo(struct sigaction* sa, SA nn) { } + ]], [[ + struct sigaction sa; + SA nn = SIG_DFL; + sa.sa_handler = nn; + foo(&sa, nn); + ]])],[ + ace_cv_lib_struct_sigaction_va1_handler=yes + ],[ + ace_cv_lib_struct_sigaction_va1_handler=no + ]) + ]) +fi dnl test "$ace_cv_struct_sigaction" = yes + +dnl TODO: This doesn't work. +dnl The linux compiler issues a warning regarding the invalid void* +dnl conversion. +dnl +dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ +dnl -Ossama +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +dnl Check if msgsnd() takes a struct msgbuf* second argument +ACE_CACHE_CHECK([if msgsnd() takes a struct msgbuf* second argument], + [ace_cv_lib_posix_msgsnd_msgbufp_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +# include +#ifndef ACE_LACKS_SYS_MSG_H +# include +#endif + ]], [[ + int msqid = 0; + struct msgbuf* msgp = 0; + int msgsz = 0; + int msgflg = 0; + msgsnd(msqid, msgp, msgsz, msgflg); + ]])],[ + ace_cv_lib_posix_msgsnd_msgbufp_2=yes + ],[ + ace_cv_lib_posix_msgsnd_msgbufp_2=no + ]) + ], + [ + dnl "ACTIONS-IF-SUCCESSFUL" handled later in configure.in + ], + [ + dnl Check if msgsnd() takes a const void* second argument + ACE_CACHE_CHECK([if msgsnd() takes a const void* second argument], + [ace_cv_lib_posix_msgsnd_cvoidp_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +# include +#ifndef ACE_LACKS_SYS_MSG_H +# include +#endif + ]], [[ + int msqid = 0; + const void* msgp = 0; + int msgsz = 0; + int msgflg = 0; + msgsnd(msqid, msgp, msgsz, msgflg); + ]])],[ + ace_cv_lib_posix_msgsnd_cvoidp_2=yes + ],[ + ace_cv_lib_posix_msgsnd_cvoidp_2=no + ]) + ], + [ + dnl Do nothing if msgsnd takes a const void* second argument + ], + [ + dnl If we get this far we presumably have a non-const void* second param + AC_DEFINE([ACE_HAS_NONCONST_MSGSND]) + ]) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +dnl TODO: This doesn't work. +dnl The linux compiler issues a warning regarding the invalid void* +dnl conversion. +dnl +dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ +dnl -Ossama +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +dnl Check if msgrcv() takes a void* second argument +AC_CACHE_CHECK([if msgrcv() takes a void* second argument], + [ace_cv_lib_posix_msgrcv_voidp_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +# include +#ifndef ACE_LACKS_SYS_MSG_H +# include +#endif + ]], [[ + int msqid = 0; + void* msgp = 0; + int msgsz = 0; + long msgtyp = 0; + int msgflg = 0; + msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); + ]])],[ + ace_cv_lib_posix_msgrcv_voidp_2=yes + ],[ + ace_cv_lib_posix_msgrcv_voidp_2=no + ]) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + + +if test "$ac_cv_func_shmat" = yes; then + dnl TODO: This doesn't work. + dnl The linux compiler issues a warning regarding the invalid void* + dnl conversion. + dnl + dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ + dnl -Ossama + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ + dnl Check if shmat() takes a void* second argument + AC_CACHE_CHECK([if shmat() takes a void* second argument], + [ace_cv_lib_posix_shmat_voidp_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #ifndef ACE_LACKS_SYS_TYPES_H + # include + #endif + # include + # include + ]], [[ + int shmid = 0; + void* shmaddr = 0; + int shmflg = 0; + shmat(shmid, shmaddr, shmflg); + ]])],[ + ace_cv_lib_posix_shmat_voidp_2=yes + ],[ + ace_cv_lib_posix_shmat_voidp_2=no + ]) + ]) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + if test "$ace_cv_lib_posix_shmat_voidp_2" = no; then + AC_DEFINE([ACE_HAS_CHARPTR_SHMAT], 1, + [Define to 1 if arg 2 of 'shmat' is char *']) + fi +fi + +if test "$ac_cv_func_shmdt" = yes; then + dnl TODO: This doesn't work. + dnl The linux compiler issues a warning regarding the invalid void* + dnl conversion. + dnl + dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ + dnl -Ossama + ACE_CONVERT_WARNINGS_TO_ERRORS( + [ + dnl Check if shmdt() takes a void* second argument + AC_CACHE_CHECK([if shmdt() takes a void* argument], + [ace_cv_lib_posix_shmdt_voidp],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #ifndef ACE_LACKS_SYS_TYPES_H + # include + #endif + # include + # include + ]], [[ + void* shmaddr = 0; + shmdt(shmaddr); + ]])],[ + ace_cv_lib_posix_shmdt_voidp=yes + ],[ + ace_cv_lib_posix_shmdt_voidp=no + ]) + ]) + ]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + if test "$ace_cv_lib_posix_shmdt_voidp" = no; then + AC_DEFINE([ACE_HAS_CHARPTR_SHMDT], 1, + [Define to 1 if arg 1 of 'shmdt' is char *']) + fi +fi + +dnl TODO: This doesn't work. +dnl The linux compiler issues a warning regarding the invalid void* +dnl conversion. +dnl +dnl FIXED by adding "-Werror" to compiler flags when using GNU C++ +dnl -Ossama +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +dnl Check if sigaction() takes a const* second argument +AC_CACHE_CHECK([if sigaction() takes a const* second argument], + [ace_cv_lib_posix_sigaction_constp_2],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + int signum = 0; + const struct sigaction* act = 0; + struct sigaction* oldact = 0; + sigaction(signum, act, oldact); + ]])],[ + ace_cv_lib_posix_sigaction_constp_2=yes + ],[ + ace_cv_lib_posix_sigaction_constp_2=no + ]) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +if test "$ace_cv_lib_posix_sigaction_constp_2" = yes; then + AC_DEFINE([ACE_HAS_SIGACTION_CONSTP2]) +fi + +dnl We need to use the ACE_CONVERT_WARNINGS_TO_ERRORS() macro since +dnl passing a void * just caused implicit conversion warnings when +dnl using GNU C++, for example. +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +dnl Check for SVR4 style gettimeofday() +AC_CACHE_CHECK([if gettimeofday() takes a void * second argument], + [ace_cv_lib_voidptr_gettimeofday], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + ]], [[ + struct timeval *tv = 0; + void *tzp = 0; + + gettimeofday(tv, tzp); + ]])],[ + ace_cv_lib_voidptr_gettimeofday=yes + ],[ + ace_cv_lib_voidptr_gettimeofday=no + ]) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS + +if test "$ace_cv_lib_voidptr_gettimeofday" = no; then +ACE_CONVERT_WARNINGS_TO_ERRORS( +[ +dnl Check for old OSF1 style gettimeofday() + AC_CACHE_CHECK([if gettimeofday() takes a struct timezone * second argument], + [ace_cv_lib_timezone_gettimeofday], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + ]], [[ + struct timeval *tv = 0; + struct timezone *tzp = 0; + + gettimeofday(tv, tzp); + ]])],[ + ace_cv_lib_timezone_gettimeofday=yes + ],[ + ace_cv_lib_timezone_gettimeofday=no + ]) + ]) +]) dnl ACE_CONVERT_WARNINGS_TO_ERRORS +fi dnl test "$ace_cv_lib_voidptr_gettimeofday" = no + +dnl Check for gettimeofday() protoype +if test "$ace_cv_lib_voidptr_gettimeofday" = yes || + test "$ace_cv_lib_timezone_gettimeofday" = yes; then + +AC_CHECK_DECL([gettimeofday], + [ +if test "$ace_cv_lib_voidptr_gettimeofday" = yes; then + AC_DEFINE([ACE_HAS_VOIDPTR_GETTIMEOFDAY]) +else + AC_DEFINE([ACE_HAS_TIMEZONE_GETTIMEOFDAY]) +fi + ],[ +if test "$ace_cv_lib_voidptr_gettimeofday" = yes; then + AC_DEFINE([ACE_HAS_SVR4_GETTIMEOFDAY]) +else + AC_DEFINE([ACE_HAS_OSF1_GETTIMEOFDAY]) +fi + ], + [ +#include +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + ]) + +fi dnl Check for gettimeofday() protoype + + +dnl Check if ctime_r() takes two arguments +if test "$ac_cv_func_ctime_r" = yes; then + ACE_CACHE_CHECK([if ctime_r() takes two arguments], + [ace_cv_lib_posix_ctime_r_2_params], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef _REENTRANT +# define _REENTRANT +#endif + +#include + ]], [[ + const time_t *t = 0; + char *buf; + ctime_r(t, buf); + ]])],[ + ace_cv_lib_posix_ctime_r_2_params=yes + ],[ + ace_cv_lib_posix_ctime_r_2_params=no + ]) + ], [AC_DEFINE([ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R])],) +fi dnl test "$ac_cv_func_ctime_r" = yes + + +dnl +dnl SECTION 12: checks for type characteristics +dnl + +dnl struct msghdr stuff +dnl Only run the following tests if the msghdr structure exists. +if test "$ace_cv_struct_msghdr" = yes; then + + ACE_CACHE_CHECK([if struct msghdr has a msg_accrights member], + [ace_cv_lib_posix_struct_msghdr_has_msg_accrights],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + msghdr mh; + mh.msg_accrights = 0; + ]])],[ + ace_cv_lib_posix_struct_msghdr_has_msg_accrights=yes + ],[ + ace_cv_lib_posix_struct_msghdr_has_msg_accrights=no + ]) + ]) + + ACE_CACHE_CHECK([if struct msghdr has a msg_accrightslen member], + [ace_cv_lib_posix_struct_msghdr_has_msg_accrightslen],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + msghdr mh; + mh.msg_accrightslen = 0; + ]])],[ + ace_cv_lib_posix_struct_msghdr_has_msg_accrightslen=yes + ],[ + ace_cv_lib_posix_struct_msghdr_has_msg_accrightslen=no + ]) + ]) + +dnl Check for 4.4 BSD style struct msghdr members +dnl The following test should only be run if the above two testsfail. + if test "$ace_cv_lib_posix_struct_msghdr_has_msg_accrights" = no && + test "$ace_cv_lib_posix_struct_msghdr_has_msg_accrightslen" = no; then + AC_DEFINE([ACE_LACKS_MSG_ACCRIGHTS]) + ACE_CACHE_CHECK([for 4.4 BSD style struct msghdr], + [ace_cv_lib_4_4bsd_msghdr],[ + AC_EGREP_HEADER([msg_control], [sys/socket.h], + [ + ace_cv_lib_4_4bsd_msghdr=yes + ], + [ + ace_cv_lib_4_4bsd_msghdr=no + ]) + ], + [ + AC_DEFINE([ACE_HAS_4_4BSD_SENDMSG_RECVMSG]) + ], + [ + AC_MSG_WARN([No supported msghdr structure was found. ACE may not compile or function properly.]) + ]) + fi + +fi dnl End struct msghdr_stuff + +dnl +dnl SECTION 13: checks for system services +dnl + +dnl Check if platform defines ctime() as a macro +ACE_CACHE_CHECK([for ctime() macro], + [ace_cv_feature_have_ctime_macro], + [ + AC_EGREP_CPP([ACE_CTIME_MACRO], + [ +#include + +#if defined (ctime) + ACE_CTIME_MACRO +#endif + ], + [ + ace_cv_feature_have_ctime_macro=yes + ], + [ + ace_cv_feature_have_ctime_macro=no + ]) + ], [AC_DEFINE([ACE_HAS_BROKEN_CTIME])],) + +dnl Check if platform defines ctime_r, asctime_r, rand_r or getpwnam_r +dnl as macros. +ACE_CACHE_CHECK([for reentrant function macros], + [ace_cv_feature_has_broken_r_routines], + [ + AC_EGREP_CPP([ACE_R_MACROS], + [ +#ifndef _REENTRANT +# define _REENTRANT +#endif + +#include + +#if !defined (ACE_LACKS_PWD_H) +# include +#endif + +#if defined (ctime_r) || \ + defined (asctime_r) || \ + defined (rand_r) || \ + defined (getpwnam_r) + ACE_R_MACROS +#endif + ], + [ + ace_cv_feature_has_broken_r_routines=yes + ], + [ + ace_cv_feature_has_broken_r_routines=no + ]) + ], [AC_DEFINE([ACE_HAS_BROKEN_R_ROUTINES])],) + +dnl Check if platform defines sig{empty,fill,add,del}set as macros +ACE_CACHE_CHECK([for sig{empty fill add del}set macros], + [ace_cv_feature_have_sig_macros], + [ + AC_EGREP_CPP([ACE_SIG_MACROS], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + +#if defined (sigemptyset) || \ + defined (sigfillset) || \ + defined (sigaddset) || \ + defined (sigdelset) || \ + defined (sigismember) + ACE_SIG_MACROS +#endif + ], + [ + ace_cv_feature_have_sig_macros=yes + ], + [ + ace_cv_feature_have_sig_macros=no + ]) + ], [AC_DEFINE([ACE_HAS_SIG_MACROS])],) + +dnl Check for open() mode masks +ACE_CACHE_CHECK([for open() mode masks], + [ace_cv_feature_have_open_mode_masks],[ + AC_EGREP_CPP([ACE_OPEN_MODE_MASKS_EXIST], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + +/* These are ORed so that ACE will not redefine any of them if any of + them exist. */ +#if defined (S_IRWXU) || \ + defined (S_IRUSR) || \ + defined (S_IWUSR) || \ + defined (S_IXUSR) || \ + defined (S_IRWXG) || \ + defined (S_IRGRP) || \ + defined (S_IWGRP) || \ + defined (S_IXGRP) || \ + defined (S_IRWXO) || \ + defined (S_IROTH) || \ + defined (S_IWOTH) || \ + defined (S_IXOTH) + ACE_OPEN_MODE_MASKS_EXIST +#endif + ], + [ + ace_cv_feature_have_open_mode_masks=yes + ], + [ + ace_cv_feature_have_open_mode_masks=no + ]) + ], , [AC_DEFINE([ACE_LACKS_MODE_MASKS])]) + + +dnl Check if platform supports POSIX O_NONBLOCK semantics +ACE_CACHE_CHECK([for POSIX O_NONBLOCK semantics], + [ace_cv_feature_posix_o_nonblock],[ + AC_EGREP_CPP([ACE_POSIX_O_NONBLOCK], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + +#if defined (O_NONBLOCK) + ACE_POSIX_O_NONBLOCK +#endif + ], + [ + ace_cv_feature_posix_o_nonblock=yes + ], + [ + ace_cv_feature_posix_o_nonblock=no + ]) + ], [AC_DEFINE([ACE_HAS_POSIX_NONBLOCK])],) + +dnl Check for MAP_FAILED constant +ACE_CACHE_CHECK([for MAP_FAILED constant], + [ace_cv_lib_have_map_failed],[ + dnl We need the square brackets around "ACEMAPFAILED.+[0-9]" to + dnl prevent the character class "[0-9]" from becoming "0-9" due to + dnl M4 quoting. + AC_EGREP_CPP([ACEMAPFAILED.+[0-9]], + [ +#include + ACEMAPFAILED MAP_FAILED + ], + [ + ace_cv_lib_have_map_failed=yes + ], + [ + ace_cv_lib_have_map_failed=no + ]) + ], + [ + dnl Check if platform defines MAP_FAILED as a long constant + ACE_CACHE_CHECK([if MAP_FAILED is a long constant], + [ace_cv_feature_long_map_failed],[ + dnl We need the square brackets around "ACEMAPFAILED.+[0-9]L" to + dnl prevent the character class "[0-9]" from becoming "0-9" due to + dnl M4 quoting. + AC_EGREP_CPP([ACEMAPFAILED.+[0-9]L], + [ +#include + ACEMAPFAILED MAP_FAILED + ], + [ + ace_cv_feature_long_map_failed=yes + ], + [ + ace_cv_feature_long_map_failed=no + ]) + ], [AC_DEFINE([ACE_HAS_LONG_MAP_FAILED])], + [ + dnl Check if MAP_FAILED is _not_ cast to void * + ACE_CACHE_CHECK([if MAP_FAILED is not cast to void *], + [ace_cv_have_broken_map_failed],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[ + void * foo = MAP_FAILED; + ]])],[ + ace_cv_have_broken_map_failed=no + ],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + void * foo = (void *) MAP_FAILED; + ]])], + [ + ace_cv_have_broken_map_failed=yes + ], + [ + dnl If we get here then we have no idea what is wrong! + ace_cv_have_broken_map_failed=no + ]) + ]) + ], [AC_DEFINE([ACE_HAS_BROKEN_MAP_FAILED])],) + ]) + ],) + +dnl Check if platform supports TCP_NODELAY support +ACE_CACHE_CHECK([for TCP_NODELAY support], + [ace_cv_feature_tcp_nodelay],[ + AC_EGREP_CPP([ACE_TCPNODELAY], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + +#if defined (TCP_NODELAY) + ACE_TCPNODELAY +#endif + ], + [ + ace_cv_feature_tcp_nodelay=yes + ], + [ + ace_cv_feature_tcp_nodelay=no + ]) + ], , [AC_DEFINE([ACE_LACKS_TCP_NODELAY])]) + +dnl Check if platform supports SO_SNDBUF/SO_RCVBUF socket options +ACE_CACHE_CHECK([for SO_SNDBUF/SO_RCVBUF socket options], + [ace_cv_feature_so_sndbuf_rcvbuf],[ + AC_EGREP_CPP([ACE_SO_BUF], + [ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + +#if defined (SO_SNDBUF) && \ + defined (SO_RCVBUF) + ACE_SO_BUF +#endif + ], + [ + ace_cv_feature_so_sndbuf_rcvbuf=yes + ], + [ + ace_cv_feature_so_sndbuf_rcvbuf=no + ]) + ], , [AC_DEFINE([ACE_LACKS_SOCKET_BUFSIZ])]) + +dnl Check if memcpy is faster or loop unrolling is faster on a given +dnl platform +ACE_CACHE_CHECK([if ACE memcpy needs loop unrolling], [ace_cv_memcpy_loop_unroll], +[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include +#include + +void* +smemcpy (void* dest, const void* src, const size_t n) +{ + unsigned char* to = static_cast( dest) ; + const unsigned char* from = static_cast( src) ; + // Unroll the loop... + switch (n) + { + case 16: to[15] = from[15] ; + case 15: to[14] = from[14] ; + case 14: to[13] = from[13] ; + case 13: to[12] = from[12] ; + case 12: to[11] = from[11] ; + case 11: to[10] = from[10] ; + case 10: to[9] = from[9] ; + case 9: to[8] = from[8] ; + case 8: to[7] = from[7] ; + case 7: to[6] = from[6] ; + case 6: to[5] = from[5] ; + case 5: to[4] = from[4] ; + case 4: to[3] = from[3] ; + case 3: to[2] = from[2] ; + case 2: to[1] = from[1] ; + case 1: to[0] = from[0] ; + case 0: return dest; + default: return memcpy (dest, src, n); + } +} + +// Function pointer +void* (* test_func) (void *dst, const void* src, size_t); + +namespace { enum { ITERATIONS = 100000 }; } + +#include +#include + +int +main(int argc, char* argv[]) +{ + struct timeval start, now; + double value; + + // Test buffer + char dest [16]; + const void* src = " THIS IS A TEST"; + + // We want to test if the loop unrolling is faster for sizes + // from 1..16 + for (size_t counter = 16; counter >=1; counter--) + { + test_func = smemcpy; + + // Warm up + for (int i = ITERATIONS ; i > 0 ; --i) + test_func ((void *)dest, src, counter); + + gettimeofday (&start, 0) ; + for (int j = ITERATIONS ; j > 0 ; --j) + test_func ((void *)dest, src, counter); + gettimeofday (&now, 0); + + double fast = 1000000 * (now.tv_sec - start.tv_sec) + + now.tv_usec - start.tv_usec ; + + test_func = memcpy; + + // Warm up + for (int k = ITERATIONS ; k > 0 ; --k) + test_func ((void *)dest, src, counter); + + gettimeofday (&start, 0) ; + for (int l = ITERATIONS ; l > 0 ; --l) + test_func ((void *)dest, src, counter); + gettimeofday (&now, 0) ; + + double slow = 1000000 * (now.tv_sec-start.tv_sec) + + now.tv_usec - start.tv_usec ; + if (fast > slow) + return 1; // Unrolling was slower than actual memcpy + + if (1.10*fast > slow) + return 1; // Unrolling was not faster by 10% + } + return 0; // Unrolling was faster -- success +}]])], [ace_cv_memcpy_loop_unroll=yes], + [ace_cv_memcpy_loop_unroll=no], + dnl Cross compilation case + [ace_cv_memcpy_loop_unroll=no])], + dnl only if the test succeeds set the macro + [AC_DEFINE([ACE_HAS_MEMCPY_LOOP_UNROLL], 1, + [Define to 1 if unrolled ACE_OS::fast_memcpy() is faster than system memcpy()])],) + +dnl TODO: We only check for ACE_HAS_AUTOMATIC_INIT_FINI on platforms that +dnl have SVR4 dynamic linking since ACE doesn't support it otherwise. +if test "$ac_cv_header_dlfcn_h" = yes && + test "$ace_has_svr4_dynamic_linking" = yes; then +dnl Check if platform calls init/fini automatically + ACE_CACHE_CHECK([for automatic init/fini calls], + [ace_cv_feature_auto_init_fini],[ + ace_cv_feature_auto_init_fini=yes + # TODO: We know how to check for this, but we need to: + # + # 1. Compile one file. + # 2. Compile and link another file. + # 3. Run file in point (2); it returns what we need. + # + # How do we do all that? + ], [AC_DEFINE([ACE_HAS_AUTOMATIC_INIT_FINI])],) +fi dnl test "$ac_cv_header_dlfcn_h" = yes && + dnl "$ace_has_svr4_dynamic_linking" = yes + +dnl Check for recursive thread exit semantics +if test "$ace_user_enable_threads" = yes; then + ACE_CACHE_CHECK([for recursive thread exit semantics], + [ace_cv_feature_recursive_thr_exit],[ + ace_cv_feature_recursive_thr_exit=yes + # TODO: How do we check for recursive thread exit semantics + ], [AC_DEFINE([ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS])],) +fi + +dnl Check for UNIX domain sockets +ACE_CACHE_CHECK([for UNIX domain sockets], + [ace_cv_feature_unix_sockets], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + sockaddr_un su; + ]])],[ + ace_cv_feature_unix_sockets=yes + ],[ + ace_cv_feature_unix_sockets=no + ]) + ], , [AC_DEFINE([ACE_LACKS_UNIX_DOMAIN_SOCKETS])]) + +dnl Check for raw sockets +ACE_CACHE_CHECK([for raw sockets], + [ace_cv_feature_raw_sockets], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include + ]], [[ +return socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + ]])],[ + ace_cv_feature_raw_sockets=yes + ],[ + ace_cv_feature_raw_sockets=no + ]) + ], [AC_DEFINE([ACE_HAS_ICMP_SUPPORT])]) + +dnl Check for ACE_Handle_Set optimized for select() +ACE_CACHE_CHECK([for ACE_Handle_Set optimized for select()], + [ace_cv_feature_handle_set_optimized_for_select],[ + ace_cv_feature_handle_set_optimized_for_select=yes + # TODO: We know how to check this. We need to: + # + # 1. Compile and link a file. + # 2. Run nm on that file. + # + # How do we do that? + ], [AC_DEFINE([ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT])],) + +dnl Even we if we don't have IP multicasting, we still need to define +dnl "ACE_HAS_IP_MULTICAST" since struct ip_mreq gets redefined by ACE. +dnl What do we do about this problem? +dnl -Ossama +dnl Check for IP multicast support +ACE_CACHE_CHECK([for IP multicast support], + [ace_cv_feature_ip_multicast],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], [[ + ip_mreq im; + ]])],[ + ace_cv_feature_ip_multicast=yes + ],[ +dnl Some platforms define ip_mreq in . + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include + ]], + [[ + ip_mreq im; + ]])], + [ + ace_cv_feature_ip_multicast=yes + ], + [ + ace_cv_feature_ip_multicast=no + ]) + ]) + ], [AC_DEFINE([ACE_HAS_IP_MULTICAST])],) + +ACE_CACHE_CHECK([if running on an Alpha], + [ace_cv_feature_alpha],[ + case "$host" in + alpha*) + ace_cv_feature_alpha=yes + ;; + *) + ace_cv_feature_alpha=no + ;; + esac + ], + [ + case "$host" in + *linux*) + dnl We only define ACE_HAS_ALPHA_TIMER if we are running Linux + dnl on an Alpha and are using GNU C++! + if test "$GXX" = yes; then + AC_DEFINE([ACE_HAS_ALPHA_TIMER], 1, + [Define to 1 if system should use Alpha's cycle counter]) + fi + ;; + esac + ],) + +ACE_CACHE_CHECK([if running on a Power PC], + [ace_cv_feature_powerpc],[ + case "$host" in + powerpc*) + ace_cv_feature_powerpc=yes + ;; + *) + ace_cv_feature_powerpc=no + ;; + esac + ], + [ + case "$host" in + *aix*) + dnl We don't do anything for AIX since AIX already has a + dnl hi-res timer function! + ;; + *) + dnl Only define ACE_HAS_POWERPC_TIMER when using GNU C++! + if test "$GXX" = yes; then + AC_DEFINE([ACE_HAS_POWERPC_TIMER], 1, + [Define to 1 if system should use PowerPC's cycle counter]) + fi + ;; + esac + ],) + +ACE_CACHE_CHECK([if running on a Pentium(tm) processor], + [ace_cv_feature_pentium],[ + case "$host" in + i386-* | i486-* |i586-* | i686-*) +dnl If we do have a pentium, than define ACE_HAS_PENTIUM and add +dnl gethrtime.cpp to the source list, but only if we're using GNU C++ +dnl since gethrtime.cpp uses assembler code specific to that compiler. + if test "$GXX" = yes; then + ace_cv_feature_pentium=yes + else + ace_cv_feature_pentium=no + fi + ;; + *) + ace_cv_feature_pentium=no + ;; + esac + ], + [ + AC_DEFINE([ACE_HAS_PENTIUM], 1, + [Define to 1 if system is using Intel Pentium(tm) processor]) + ],) +AM_CONDITIONAL([ACE_ON_PENTIUM], [test X$ace_cv_feature_pentium = Xyes]) + +case "$host" in + i386-* | i486-* | i586-* | i686-* | x86_64-*) + if test "$GXX" = yes; then + ace_cv_has_intel_assembly=yes + else + ace_cv_has_intel_assembly=no + fi + ;; + *) + ace_cv_has_intel_assembly=no + ;; +esac +if test "$ace_cv_has_intel_assembly" != "no"; then + AC_DEFINE([ACE_HAS_INTEL_ASSEMBLY], 1, + [Define to 1 if the system supports x86/x86_64 inline assembly]) +fi + +dnl +dnl SECTION 14: checks for aggregated features +dnl TODO: Little by little, get rid of these... +dnl + + +dnl Macro ACE_HAS_REENTRANT_FUNCTIONS means the following functions +dnl are usable: +dnl +dnl rand_r +dnl strtok_r +dnl getpwnam_r (if we don't have, define ACE_LACKS_PWD_REENTRANT_FUNCTIONS) +dnl ctime_r +dnl localtime_r +dnl gmtime_r +dnl asctime_r +dnl * getprotobyname_r +dnl * getprotobynumber_r +dnl * gethostbyaddr_r +dnl * gethostbyname_r +dnl * getservbyname_r +dnl +dnl Those marked with '*' are NOT usable if +dnl ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) is defined. +dnl +dnl The time has come to create feature macros for each of these... +dnl With the separate feature macros, we will define (for now) +dnl ACE_HAS_REENTRANT_FUNCTIONS only when all of those WITHOUHT a '*' +dnl are defined. Also, if any of those with '*' are missing, we will +dnl define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS. + +dnl Don't bother with reentrant functions if they are disabled by the user. +if test "$ace_user_enable_reentrant_funcs" = yes && + test "$ac_cv_func_rand_r" = yes && + test "$ac_cv_func_strtok_r" = yes && + test "$ac_cv_func_ctime_r" = yes && + test "$ac_cv_func_localtime_r" = yes && + test "$ac_cv_func_gmtime_r" = yes && + test "$ac_cv_func_asctime_r" = yes; then + AC_DEFINE([ACE_HAS_REENTRANT_FUNCTIONS]) + # Explicitly enable reentrant functions if thread support is not enabled. + if test "$ace_user_enable_threads" = no; then + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_REENTRANT" + fi +fi + +dnl Don't bother with reentrant functions if they are disabled by the user. +if test "$ace_user_enable_reentrant_funcs" = no || + test "$ac_cv_func_getprotobyname_r" = no || + test "$ac_cv_func_getprotobynumber_r" = no || + test "$ac_cv_func_gethostbyaddr_r" = no || + test "$ac_cv_func_gethostbyname_r" = no || + test "$ac_cv_func_getservbyname_r" = no; then + AC_DEFINE([ACE_LACKS_NETDB_REENTRANT_FUNCTIONS]) +fi + +dnl FIXME!!! +dnl The following is a kludge until the netdb reentrant function +dnl number of arguments is handled. +case "$host" in + *linux*) AC_DEFINE([ACE_LACKS_NETDB_REENTRANT_FUNCTIONS]);; + *) ;; +esac + + +dnl Macro ACE_LACKS_SOME_POSIX_PROTOTYPES implies any of the following +dnl features: +dnl +dnl ! ACE_HAS_MSGSND_MSGBUFP_2 +dnl ! ACE_LACKS_MSGRCV_VOIDP_2 +dnl ! ACE_LACKS_SHMAT_VOIDP_2 +dnl +dnl So, for now, we define it if any of those were autoconf'ed. + +dnl @@ THESE NEED TO BE ADDED AS PROPER CONFIG SETTINGS. --Steve +dnl if test "$ace_cv_lib_posix_msgsnd_msgbufp_2" = yes || +dnl test "$ace_cv_lib_posix_msgrcv_voidp_2" != yes || +dnl test "$ace_cv_lib_posix_shmat_voidp_2" != yes ; then +dnl AC_DEFINE([ACE_LACKS_SOME_POSIX_PROTOTYPES]) +dnl fi + +if test "$ac_cv_func_msgctl" = yes && + test "$ac_cv_func_msgget" = yes && + test "$ac_cv_func_msgrcv" = yes && + test "$ac_cv_func_semctl" = yes && + test "$ac_cv_func_semget" = yes && + test "$ac_cv_func_semop" = yes && + test "$ac_cv_func_shmat" = yes && + test "$ac_cv_func_shmctl" = yes && + test "$ac_cv_func_shmdt" = yes && + test "$ac_cv_func_shmget" = yes; then + AC_DEFINE([ACE_HAS_SYSV_IPC]) +fi + +if test "$ac_cv_func_shmat" != yes || + test "$ac_cv_func_shmctl" != yes || + test "$ac_cv_func_shmdt" != yes || + test "$ac_cv_func_shmget" != yes; then + AC_DEFINE([ACE_LACKS_SYSV_SHMEM]) +fi + +dnl Check for what POSIX threads draft we have +AC_MSG_CHECKING([which POSIX thread library was found]) + +ace_has_pthreads=no + +dnl Check if we have Pthreads Draft 4 +dnl if test "$ac_cv_func_pthread_delay_np" = yes && +if test "$ac_cv_func_pthread_mutexattr_create" = yes && +dnl test "$ac_cv_func_pthread_mutexattr_setkind_np" = yes && + test "$ac_cv_func_pthread_mutexattr_delete" = yes && + test "$ac_cv_func_pthread_condattr_delete" = yes && + test "$ac_cv_func_pthread_condattr_create" = yes && + test "$ac_cv_func_pthread_setprio" = yes && + test "$ac_cv_func_pthread_getprio" = yes && +dnl test "$ac_cv_func_pthread_getspecific" = yes && + test "$ac_cv_func_pthread_setcancel" = yes && + test "$ac_cv_func_pthread_setasynccancel" = yes && + test "$ac_cv_func_pthread_kill" = yes; then + ace_has_pthreads=yes + AC_MSG_RESULT([POSIX Threads Draft 4]) + AC_DEFINE([ACE_HAS_PTHREADS_DRAFT4], 1, + [Platform supports POSIX Threads .4a Draft 4]) +dnl Check if we have Pthreads Draft 6 +elif test "$ac_cv_func_pthread_mutexattr_init" = yes && + test "$ac_cv_func_pthread_mutexattr_destroy" = yes && + test "$ac_cv_func_pthread_condattr_destroy" = yes && + test "$ac_cv_func_pthread_condattr_init" = yes && + test "$ac_cv_func_pthread_attr_setprio" = yes && + test "$ac_cv_func_pthread_attr_getprio" = yes && + test "$ac_cv_func_pthread_setintr" = yes && + test "$ac_cv_func_pthread_setintrtype" = yes; then + ace_has_pthreads=yes + AC_MSG_RESULT([POSIX Threads Draft 6]) + AC_DEFINE([ACE_HAS_PTHREADS_DRAFT6], 1, + [Platform supports POSIX Threads .4a Draft 6]) +dnl Check if we have Pthreads Draft 7 +elif test "$ac_cv_func_pthread_mutexattr_init" = yes && + test "$ac_cv_func_pthread_mutexattr_destroy" = yes && + test "$ac_cv_func_pthread_condattr_destroy" = yes && + test "$ac_cv_func_pthread_condattr_init" = yes && + test "$ac_cv_func_pthread_setschedparam" = yes && + test "$ac_cv_func_pthread_getschedparam" = yes && + test "$ac_cv_func_pthread_setcancelstate" = yes && + test "$ac_cv_func_pthread_setcanceltype" = yes && + test "$ace_has_sched_yield" != yes; then + ace_has_pthreads=yes + AC_MSG_RESULT([POSIX Threads Draft 7]) + AC_DEFINE([ACE_HAS_PTHREADS_DRAFT7], 1, + [Platform supports POSIX Threads .1c Draft 7]) +dnl Check if we have Pthreads Draft Standard +elif test "$ac_cv_func_pthread_mutexattr_init" = yes && + test "$ac_cv_func_pthread_mutexattr_destroy" = yes && + test "$ac_cv_func_pthread_condattr_destroy" = yes && + test "$ac_cv_func_pthread_condattr_init" = yes && + test "$ac_cv_func_pthread_setschedparam" = yes && + test "$ac_cv_func_pthread_getschedparam" = yes && + test "$ac_cv_func_pthread_setcancelstate" = yes && + test "$ac_cv_func_pthread_setcanceltype" = yes && + test "$ace_has_sched_yield" = yes; then + ace_has_pthreads=yes + AC_MSG_RESULT([POSIX Threads Draft Standard]) + AC_DEFINE([ACE_HAS_PTHREADS_STD], 1, + [Platform supports POSIX.1c-1995 threads]) +else + ace_has_pthreads=no + AC_MSG_RESULT([none]) +fi dnl PTHREAD DRAFT CHECKS + +dnl Check if we have UNIX International threads +AC_MSG_CHECKING([if a UNIX International thread library was found]) +if test "$ace_has_sthreads" = yes; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +if test "$ace_user_enable_threads" != yes || + test "$ace_has_pthreads" != yes && + test "$ace_has_sthreads" != yes; then + dnl We don't have a usable thread library! + ace_user_enable_threads=no + dnl Make sure _REENTRANT and _THREAD_SAFE are not in the + dnl preprocessor flags since thread support is being disabled. + dnl Removal of these flags is only performed if the configure script + dnl added them. + if test -n "$ACE_THR_CPPFLAGS"; then +dnl changequote(, )dnl + CPPFLAGS=`eval "echo $CPPFLAGS | sed -e 's/$ACE_THR_CPPFLAGS//' -e 's/-D_THREAD_SAFE\(=[[0-9]]*\)\?//'"` +dnl changequote([, ])dnl + fi + + AC_MSG_WARN([It appears that you do NOT have any usable thread libraries]) + AC_MSG_WARN([or thread support was explicitly disabled.]) + AC_MSG_WARN([Disabling thread support.]) + dnl ACE uses different versions of readdir_r depending on the thread + dnl library being used, i.e. on the ACE_HAS_*THREADS* macros. Since + dnl it doesn't seem like a good idea to define any ACE_HAS_*THREADS* + dnl macro if ACE won't be supporting threads, define ACE_LACKS_READDIR_R + dnl regardless if readdir_r() exists. + if test "$ac_cv_func_readdir_r" = yes; then + AC_MSG_WARN([Disabling support for readdir_r() since thread support]) + AC_MSG_WARN([is being disabled.]) + AC_DEFINE([ACE_LACKS_READDIR_R]) + fi dnl test "$ac_cv_func_readdir_r" = yes +fi dnl + +if test "$ace_user_enable_threads" = yes; then +dnl If we get this far then we have threads. +dnl FIXME: The "_POSIX" macros may need to be defined _before_ the checks for +dnl reentrant functions! However, we don't want to define them if +dnl the UNIX International threads library was detected. + AC_DEFINE([ACE_HAS_THREADS]) + AC_DEFINE([ACE_MT_SAFE]) + ACE_CPPFLAGS="$ACE_CPPFLAGS $ACE_THR_CPPFLAGS" + + if test "$ace_has_pthreads" = yes; then + + dnl Check if OS requires non-null status pointer for ::pthread_join () + dnl + dnl This test must be performed after the POSIX threads implementation + dnl that the platform supports has been determined. + ACE_CACHE_CHECK([for pthread_join null status pointer support], + [ace_cv_have_null_status_pthread_join],[ + AC_EGREP_CPP([WE_HAVE_PTHREADS_D4], + [ +#if defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREADS_DRAFT4) +/* This test is only valid for Pthreads Draft 4 */ +WE_HAVE_PTHREADS_D4 +#endif + ], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef _REENTRANT +#define _REENTRANT +#endif + +#include + +/* _THREAD_SAFE is defined in on some platforms. */ +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif + +#include + +#ifdef __cplusplus +extern "C" +#endif +void * +nothing (void *unused) +{ + return (void *) 34; +}; + +int +main () +{ + pthread_attr_t attr; + pthread_t id; + void *status; + int retval = 0; + + /* ----- */ + /* We return 0 on error for these calls since we only want to + return an error status if pthread_join fails. If these calls + fail then we've got other problems! */ + if (pthread_attr_create (&attr) != 0) return 0 /*1*/; + + if (pthread_create (&id, attr, nothing, 0) != 0) return 0 /*2*/; + + if (pthread_attr_delete (&attr) != 0) return /*3*/; + /* ----- */ + + /* With a second (status) arg of 0, LynxOS 3.0.0 pthread_join () + will fail with errno 14 (address fault detected). */ + if (pthread_join (id, 0) == -1) { + fprintf (stderr, "%s: %d; ", __FILE__, __LINE__); + perror ("pthread_join"); + retval = 1; + } + + if (pthread_join (id, &status) == -1) { + fprintf (stderr, "%s: %d; ", __FILE__, __LINE__); + perror ("pthread_join"); + retval = 2; + } + + return retval; +} + ]])],[ + ace_cv_have_null_status_pthread_join=yes + ],[ + ace_cv_have_null_status_pthread_join=no + ],[ + dnl If we are cross-compiling let's hope that + dnl that we have a working null status pointer + dnl for pthread_join. + ace_cv_have_null_status_pthread_join=yes + ]) + ], + [ + ace_cv_have_null_status_pthread_join=yes + ]) + ], , [AC_DEFINE([ACE_LACKS_NULL_PTHREAD_STATUS])]) + + dnl Check if OS supports mutex timeouts + dnl (e.g. pthread_mutex_timedlock()). + ACE_CACHE_CHECK([for mutex timeouts], + [ace_cv_have_mutex_timeouts],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef _REENTRANT +#define _REENTRANT +#endif + +#include + +/* _THREAD_SAFE is defined in on some platforms. */ +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif + +#include + +#include +#include + +#include +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +#ifdef __cplusplus +extern "C" +#endif +void *threadFunc (void *parm) +{ + int rc; + int i; + struct timespec deltatime; + struct timeval tv; + + if (gettimeofday (&tv, 0) != 0) + { + return 0; + } + + deltatime.tv_sec = tv.tv_sec + 5; + deltatime.tv_nsec = 0; + + rc = pthread_mutex_timedlock (&mutex, &deltatime); + + if (rc != ETIMEDOUT) + { + /* printf("Got an incorrect return code from pthread_mutex_timedlock\n"); */ + } + + return 0; +} + +int main (void) +{ + int rc =0; + pthread_t thread; + + rc = pthread_mutex_lock (&mutex); + if (rc != 0) + { + exit (-1); + } + + rc = pthread_create (&thread, NULL, threadFunc, NULL); + if (rc != 0) + { + exit (-1); + } + + rc = pthread_join (thread, NULL); + if (rc != 0) + { + exit (-1); + } + + pthread_mutex_destroy (&mutex); + + return 0; +} + ]])],[ + ace_cv_have_mutex_timeouts=yes + ],[ + ace_cv_have_mutex_timeouts=no + ],[ + dnl Cross-compiled case + AC_CHECK_FUNC([pthread_mutex_timedlock], + [ace_cv_have_mutex_timeouts=yes], + [ace_cv_have_mutex_timeouts=no]) + ]) + ], [AC_DEFINE([ACE_HAS_MUTEX_TIMEOUTS])],) + + dnl Check if platform needs to #include to get thread + dnl scheduling defs. + ACE_CACHE_CHECK([if sched.h is needed for thread scheduling definitions], + [ace_cv_needs_sched_h], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef ACE_HAS_STHREADS +#include +#endif + +#ifdef ACE_HAS_PTHREADS +#include +#endif + ]], [[ +int foo = SCHED_OTHER; + ]])],[ + ace_cv_needs_sched_h=no + ],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#ifdef ACE_HAS_STHREADS +#include +#endif + +#ifdef ACE_HAS_PTHREADS +#include +#endif + +#include + ]], + [[ +int foo = SCHED_OTHER; + ]])], + [ + ace_cv_needs_sched_h=yes + ], + [ + dnl We're hosed if we get here! + ace_cv_needs_sched_h=no + ]) + ]) + ], + [ + AC_DEFINE([ACE_NEEDS_SCHED_H]) + ],) + + dnl Check if platform only supports SCHED_OTHER scheduling policy + dnl + dnl This test must be performed after the POSIX threads implementation + dnl that the platform supports has been determined. + ACE_CACHE_CHECK([if SCHED_OTHER is only scheduling policy], + [ace_cv_feature_only_have_sched_other], + [ + AC_EGREP_CPP([WE_ONLY_HAVE_SCHED_OTHER], + [ +#ifdef ACE_HAS_STHREADS +# include +#endif + +#ifdef ACE_HAS_PTHREADS +# include +#endif + +#if defined (ACE_NEEDS_SCHED_H) +# include +#endif + + /* These are ORed so that ACE will not redefine + any of them if any of them exist. */ +#if !defined (SCHED_FIFO) && \ + !defined (SCHED_RR) && \ + defined (SCHED_OTHER) + WE_ONLY_HAVE_SCHED_OTHER +#endif + ], + [ + ace_cv_feature_only_have_sched_other=yes + ], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef _REENTRANT +#define _REENTRANT +#endif + +#include + +/* _THREAD_SAFE is defined in on some platforms. */ +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif + +#include +#include + +int main () +{ + pthread_attr_t ace_attr; + +#if defined (ACE_HAS_PTHREADS_DRAFT4) + if (pthread_attr_create (&ace_attr) != 0) +#else + if (pthread_attr_init (&ace_attr) != 0) +#endif + { + perror ("pthread_attr_init"); + return 0; /* Return "successfully" since only the policy call + will return with an error for this test. */ + } + +#if defined (ACE_HAS_PTHREADS_DRAFT4) + if (pthread_attr_setsched (&ace_attr, SCHED_FIFO) != 0) +#else + if (pthread_attr_setschedpolicy (&ace_attr, SCHED_FIFO) != 0) +#endif + { + perror ("pthread_attr_setschedpolicy"); + return -1; + } + +#if defined (ACE_HAS_PTHREADS_DRAFT4) + if (pthread_attr_delete (&ace_attr) != 0) +#else + if (pthread_attr_destroy (&ace_attr) != 0) +#endif + { + perror ("pthread_attr_destroy"); + return 0; /* Return "successfully" since only the policy call + will return with an error for this test. */ + } + + return 0; +} + ]])],[ + ace_cv_feature_only_have_sched_other=no + ],[ + ace_cv_feature_only_have_sched_other=yes + ],[ + dnl We only get here if polices other than SCHED_OTHER + dnl were found in the headers and we are cross-compiling. + dnl + dnl If we are cross-compiling let's hope that the + dnl scheduling policies found in the headers + dnl besides SCHED_OTHER (e.g. SCHED_FIFO, SCHED_RR) + dnl are supported. + ace_cv_feature_only_have_sched_other=no + ]) + ]) + ], [AC_DEFINE([ACE_HAS_ONLY_SCHED_OTHER])],) + fi dnl test "$ace_has_pthreads" = yes +fi dnl test "$ace_user_enable_threads" = yes + + +AC_CHECK_HEADER(libc.h) +AC_CHECK_HEADER(osfcn.h) +if test "$ac_cv_header_libc_h" != yes || + test "$ac_cv_header_osfcn_h" != yes; then + AC_DEFINE([ACE_HAS_CPLUSPLUS_HEADERS]) +fi + + + +if test "$ace_cv_lib_signal_vi1_2" = yes && + test "$ace_cv_lib_signal_vi1_ret" = yes && + test "$ace_cv_lib_struct_sigaction_vi1_handler" = yes; then + AC_DEFINE([ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES]) +elif test "$ace_cv_lib_signal_vi1_2" != yes && + test "$ace_cv_lib_signal_vv1_2" != yes && + test "$ace_cv_lib_signal_vi1a2_2" != yes && + test "$ace_cv_lib_signal_va1_2" = yes && + test "$ace_cv_lib_signal_vi1_ret" != yes && + test "$ace_cv_lib_signal_vv1_ret" != yes && + test "$ace_cv_lib_signal_vi1a2_ret" != yes && + test "$ace_cv_lib_signal_va1_ret" = yes && + test "$ace_cv_lib_struct_sigaction_vi1_handler" != yes && + test "$ace_cv_lib_struct_sigaction_vv1_handler" != yes && + test "$ace_cv_lib_struct_sigaction_vi1a2_handler" != yes && + test "$ace_cv_lib_struct_sigaction_va1_handler" = yes; then + AC_DEFINE([ACE_HAS_LYNXOS_SIGNALS]) + AC_DEFINE([ACE_HAS_TANDEM_SIGNALS]) +elif test "$ace_cv_lib_signal_vi1_2" = yes && + test "$ace_cv_lib_signal_vi1_ret" = yes && + test "$ace_cv_lib_struct_sigaction_vi1_handler" != yes; then + AC_DEFINE([ACE_HAS_SVR4_SIGNAL_T]) +elif test "$ace_cv_lib_signal_vi1_2" = yes && + test "$ace_cv_lib_signal_vv1_ret" = yes && + test "$ace_cv_lib_struct_sigaction_vv1_handler" = yes; then + AC_DEFINE([ACE_HAS_SVR4_SIGNAL_T]) +elif test "$ace_cv_lib_signal_vi1_2" = yes && + test "$ace_cv_lib_signal_vi1_ret" != yes && + test "$ace_cv_lib_signal_vv1_ret" != yes && + test "$ace_cv_lib_signal_vi1a2_ret" != yes && + test "$ace_cv_lib_signal_va1_ret" = yes && + test "$ace_cv_lib_struct_sigaction_vi1_handler" != yes && + test "$ace_cv_lib_struct_sigaction_vv1_handler" != yes && + test "$ace_cv_lib_struct_sigaction_vi1a2_handler" != yes && + test "$ace_cv_lib_struct_sigaction_va1_handler" = yes; then + AC_DEFINE([ACE_HAS_UNIXWARE_SVR4_SIGNAL_T]) +fi dnl ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +dnl +dnl SECTION 15: Final checks +dnl + +dnl Make final substitutions and defines +if test "$ace_u_long_long_typedef_set" = yes; then + AC_DEFINE_UNQUOTED([ACE_INT64_TYPE], [$ACE_INT64], + [Define to signed 64 bit integer type]) + AC_DEFINE_UNQUOTED([ACE_UINT64_TYPE], [$ACE_UINT64], + [Define to unsigned 64 bit integer type]) +fi + +dnl Combine package set flags with user's flags. +dnl User's flags go after package flags to allow user to override +dnl package defaults. +dnl X_CFLAGS comes from AC_PATH_XTRA. It may include, for example, +dnl additional include file paths or macros that need to be defined +dnl in order for X11 related files to be compiled properly. +if test "$ace_user_enable_optimize"; then + dnl We want OCXXFLAGS to be on the end, so we use CXXFLAGS, + dnl not ACE_CXXFLAGS! + CXXFLAGS="$CXXFLAGS $OCXXFLAGS" + CFLAGS="$CFLAGS $OCFLAGS" +fi +CXXFLAGS="$ACE_CXXFLAGS $X_CFLAGS $CXXFLAGS" +CFLAGS="$ACE_CFLAGS $X_CFLAGS $CFLAGS" +CPPFLAGS="$ACE_CPPFLAGS $CPPFLAGS" +LDFLAGS="$ACE_LDFLAGS $LDFLAGS" + +dnl The following tests should be performed _after_ the bulk of the +dnl ACE macros have been defined. + +dnl Flush the cache so that it is easier to debug the configure script +dnl if the following integrity check fails. +AC_CACHE_SAVE + +dnl Verify the integrity of the current configuration. +ACE_CACHE_CHECK([if generated ACE configuration is usable], + [ace_cv_configuration_is_usable], + [ + dnl We want an empty ace/config.h to prevent multiple defines + dnl with Autoconf's confdefs.h + ACE_USE_TEMP_FILE([ace/config.h], + [ + dnl Now run the compilation test + ACE_TRY_COMPILE([-I. -I${srcdir}], + [ +// Include ".cpp" files instead of headers so that we can get a more +// thorough test compile. +#include "ace/Time_Value.cpp" +#include "ace/Reactor.cpp" + ], + [ + ACE_Time_Value t = ACE_OS::gettimeofday (); + t++; + + ACE_Reactor * r = ACE_Reactor::instance (); + + (void) r->close (); + ], + [ + ace_cv_configuration_is_usable=yes + ], + [ + ace_cv_configuration_is_usable=no + ]) + ]) + ], + [ + dnl Looks good! Do nothing. + dnl It appears that ace/OS.cpp compiled. If it didn't compile then + dnl there would be no chance that the rest of ACE would compile. + ], + [ + AC_MSG_ERROR( + [ +The generated configuration appears to be unusable. Please verify +that your system path and environment variables are correct. If they +appear to be correct then please send the maintainer of this configure +script $ACE_CONFIGURE_MAINTAINER the *COMPRESSED* 'config.log' file +and the following information: + + ACE 'configure' Script Information + ================================== + [RCS] translit([$Id: configure.ac 82573 2008-08-08 18:13:53Z jtc $], [$"]) + + + ACE Version: ACE_VERSION + C++ Compiler: $CXX + C++ Preprocessor: $CXXCPP + C++ Flags: $CXXFLAGS + Preprocessor Flags: $CPPFLAGS + Linker: $LD + Linker Flags: $LDFLAGS + Libraries: $LIBS + System type information: + Build: $build Host: $host + +In the meantime, please use the stock ACE build procedure detailed in +the file 'ACE-INSTALL.html'. + ]) + ]) + +dnl " + +dnl Check for ACE_IOStream support +ACE_CACHE_CHECK([for ACE_IOStream support], + [ace_cv_feature_ace_iostream], + [ + dnl We want an empty ace/config.h to prevent multiple defines + dnl with Autoconf's confdefs.h + ACE_USE_TEMP_FILE([ace/config.h], + [ + dnl Now run the compilation test + ACE_TRY_COMPILE([-I. -I${srcdir}], + [ +#include "ace/IOStream.cpp" + ], + [ + int a = 0; a += 1; + ], + [ + ace_cv_feature_ace_iostream=yes + ], + [ + ace_cv_feature_ace_iostream=no + ]) + ]) + ], , [AC_DEFINE([ACE_LACKS_ACE_IOSTREAM])]) + +dnl Check if ACE needs conversion to pass ACE_TTY_IO to DEV_Connector +ACE_CACHE_CHECK([if ACE needs conversion to pass ACE_TTY_IO to DEV_Connector], + [ace_cv_lib_need_dev_io_conv], + [ + dnl We want an empty ace/config.h to prevent multiple defines + dnl with Autoconf's confdefs.h + ACE_USE_TEMP_FILE([ace/config.h], + [ + dnl Now run the compilation test + ACE_TRY_COMPILE([-I. -I${srcdir}], + [ +#include "ace/OS.cpp" + ], + [ + int a=0; a += 1; + ], + [ + ace_cv_lib_need_dev_io_conv=no + ], + [ + dnl Now check if ACE_NEEDS_DEV_IO_CONVERSION makes + dnl compilation work! + ACE_TRY_COMPILE([-I. -I${srcdir}], + [ +#define ACE_NEEDS_DEV_IO_CONVERSION +#include "ace/DEV_Connector.cpp" + ], + [ + int a=0; a += 1; + ], + [ + ace_cv_lib_need_dev_io_conv=yes + ], + [ + dnl If we get here, then we have no idea what is wrong! + ace_cv_lib_need_dev_io_conv=no + ]) + ]) + ]) + ], [AC_DEFINE([ACE_NEEDS_DEV_IO_CONVERSION])],) + +dnl End ACE macro tests! + +dnl Substitute whatever X libraries ACE needs, if any. +AC_SUBST([ACE_XLIBS]) + +dnl Prepend purify and quantify command lines if purify and quantify are +dnl enabled. Otherwise, PURELINK and PRELINK will just be "blank." +LD="$PURELINK $PRELINK $LD" +dnl LDFLAGS="$ACE_LDFLAGS $LDFLAGS" + +dnl AC_SUBST(LDFLAGS) +dnl AC_SUBST(LIBOBJS) + +dnl Force CXXFLAGS to be substituted in Makefiles that don't "need" them. +AC_SUBST([CXXFLAGS]) + +dnl Precompute the absolute pathname of the ACE tests directory so +dnl that we can avoid using GNU Make extensions in the ACE tests +dnl Makefile. +ACE_TESTS_DIR=`pwd`/tests +AC_SUBST([ACE_TESTS_DIR]) + +dnl +dnl SECTION 16: AC_CONFIG_FILES([FILE...]) +dnl +dnl +dnl We can finally create all the files listed here; Makefile is +dnl created from Makefile.in, etc. Top-level Makefiles should be +dnl created first. + +dnl Makefile +dnl ace/Makefile +dnl apps/Makefile +dnl apps/gperf/Makefile +dnl apps/gperf/src/Makefile +dnl man/Makefile +dnl man/man3/Makefile +dnl netsvcs/Makefile +dnl netsvcs/clients/Makefile +dnl netsvcs/clients/Logger/Makefile +dnl netsvcs/clients/Naming/Makefile +dnl netsvcs/clients/Naming/Client/Makefile +dnl netsvcs/clients/Naming/Dump_Restore/Makefile +dnl netsvcs/clients/Tokens/Makefile +dnl netsvcs/clients/Tokens/collection/Makefile +dnl netsvcs/clients/Tokens/deadlock/Makefile +dnl netsvcs/clients/Tokens/invariant/Makefile +dnl netsvcs/clients/Tokens/manual/Makefile +dnl netsvcs/clients/Tokens/mutex/Makefile +dnl netsvcs/clients/Tokens/rw_lock/Makefile +dnl netsvcs/lib/Makefile +dnl netsvcs/servers/Makefile +dnl tests/Makefile + +AC_CONFIG_FILES([ + Makefile + ace/Makefile +]) + +dnl Note that the "ACE_VERSION" in the message below is an M4 macro +dnl that expands to the version of ACE being configured. +AC_CONFIG_COMMANDS([default],[ + echo "" + echo "Configuration of ACE ACE_VERSION is now complete." + echo "" + ],[]) +AC_OUTPUT diff --git a/dep/ACE_wrappers/m4/ace.m4 b/dep/ACE_wrappers/m4/ace.m4 new file mode 100644 index 000000000..f04555763 --- /dev/null +++ b/dep/ACE_wrappers/m4/ace.m4 @@ -0,0 +1,1770 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: ace.m4 82523 2008-08-06 08:36:01Z johnnyw $ +dnl +dnl ace.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl for enabling/disabling certain ACE features. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2000, 2002 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +dnl Macros that add ACE configuration options to a `configure' script. +dnl ACE_CONFIGURATION_OPTIONS +AC_DEFUN([ACE_CONFIGURATION_OPTIONS], +[ + AM_CONDITIONAL([BUILD_ACE_FOR_TAO], false) + + AC_ARG_ENABLE([ace-codecs], + AS_HELP_STRING(--enable-ace-codecs,build ACE with codecs support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_ace_codecs=yes + ;; + no) + ace_user_enable_ace_codecs=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-codecs]) + ;; + esac + ], + [ + ace_user_enable_ace_codecs=yes + ]) + AM_CONDITIONAL([BUILD_ACE_CODECS], [test X$ace_user_enable_ace_codecs = Xyes]) + + AC_ARG_ENABLE([ace-filecache], + AS_HELP_STRING(--enable-ace-filecache,build ACE_Filecache support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_ace_filecache=yes + ;; + no) + ace_user_enable_ace_filecache=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-filecache]) + ;; + esac + ], + [ + dnl Enable ACE_Filecache support by default since it's never turned off + dnl in the ACE lib itself. Just required for some things like JAWS. + ace_user_enable_ace_filecache=yes + ]) + AM_CONDITIONAL([BUILD_ACE_FILECACHE], [test X$ace_user_enable_ace_filecache = Xyes]) + + AC_ARG_ENABLE([ace-other], + AS_HELP_STRING(--enable-ace-other,build ACE with all misc pieces [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_ace_other=yes + ;; + no) + ace_user_enable_ace_other=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-other]) + ;; + esac + ], + [ + ace_user_enable_ace_other=yes + ]) + AM_CONDITIONAL([BUILD_ACE_OTHER], [test X$ace_user_enable_ace_other = Xyes]) + + AC_ARG_ENABLE([ace-token], + AS_HELP_STRING(--enable-ace-token,build ACE with tokens support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_ace_token=yes + ;; + no) + ace_user_enable_ace_token=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-token]) + ;; + esac + ], + [ + ace_user_enable_ace_token=yes + ]) + AM_CONDITIONAL([BUILD_ACE_TOKEN], [test X$ace_user_enable_ace_token = Xyes]) + + AC_ARG_ENABLE([ace-uuid], + AS_HELP_STRING(--enable-ace-uuid,build ACE with UUID support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_ace_uuid=yes + ;; + no) + ace_user_enable_ace_uuid=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-uuid]) + ;; + esac + ], + [ + ace_user_enable_ace_uuid=yes + ]) + AM_CONDITIONAL([BUILD_ACE_UUID], [test X$ace_user_enable_ace_uuid = Xyes]) + + AC_ARG_ENABLE([alloca], + AS_HELP_STRING(--enable-alloca,compile with alloca() support [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_alloca=yes + ;; + no) + ace_user_enable_alloca=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-alloca]) + ;; + esac + ], + [ + dnl Disable alloca() support by default since its use is generally + dnl not recommended. + ace_user_enable_alloca=no + ]) + + AC_ARG_ENABLE([rwho], + AS_HELP_STRING(--enable-rwho,build the distributed rwho program [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_rwho=yes + ;; + no) + ace_user_enable_rwho=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-rwho]) + ;; + esac + ],) + AM_CONDITIONAL([BUILD_RWHO], [test X$ace_user_enable_rwho = Xyes]) + + AC_ARG_ENABLE([ipv4-ipv6], + AS_HELP_STRING(--enable-ipv4-ipv6,compile with IPv4/IPv6 migration support [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE(ACE_HAS_IPV6) + AC_DEFINE(ACE_USES_IPV4_IPV6_MIGRATION) + ;; + no) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ipv4-ipv6]) + ;; + esac + ],) + + AC_ARG_ENABLE([ipv6], + AS_HELP_STRING(--enable-ipv6,compile with IPv6 support [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE(ACE_HAS_IPV6) + ace_user_enable_ipv6=yes + ;; + no) + ace_user_enable_ipv6=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ipv6]) + ;; + esac + ],) + AM_CONDITIONAL([BUILD_IPV6], [test X$ace_user_enable_ipv6 = Xyes]) + + AC_ARG_ENABLE([log-msg-prop], + AS_HELP_STRING(--enable-log-msg-prop,enable threads inheriting ACE_Log_Msg properties from parent thread [[[yes]]]), + [ + case "${enableval}" in + yes) + dnl nothing to do + ;; + no) + AC_DEFINE(ACE_THREADS_DONT_INHERIT_LOG_MSG) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-log-msg-prop]) + ;; + esac + ],) + + AC_ARG_ENABLE([logging], + AS_HELP_STRING(--enable-logging,enable ACE logging macros [[[yes]]]), + [ + case "${enableval}" in + yes) + dnl nothing to do + ;; + no) + AC_DEFINE([ACE_NLOGGING]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-logging]) + ;; + esac + ],) + + AC_ARG_ENABLE([malloc-stats], + AS_HELP_STRING(--enable-malloc-stats,enable malloc statistics collection [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([ACE_HAS_MALLOC_STATS]) + ;; + no) + dnl nothing to do + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-malloc-stats]) + ;; + esac + ],) + + AC_ARG_ENABLE([pi-pointers], + AS_HELP_STRING(--enable-pi-pointers,enable pos. indep. pointers [[[yes]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([ACE_HAS_POSITION_INDEPENDENT_POINTERS]) + ;; + no) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-pi-pointers]) + ;; + esac + ], + [ + AC_DEFINE([ACE_HAS_POSITION_INDEPENDENT_POINTERS]) + ]) + + AC_ARG_ENABLE([posix-sem-timeout-emulation], + AS_HELP_STRING(--enable-posix-sem-timeout-emulation,enable POSIX semaphore timeout emulation [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION]) + ;; + no) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-posix-sem-timeout-emulation]) + ;; + esac + ],) + + AC_ARG_ENABLE([probe], + AS_HELP_STRING(--enable-probe,enable ACE_Timeprobes [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([ACE_COMPILE_TIMEPROBES]) + ;; + no) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-probe]) + ;; + esac + ],) + + AC_ARG_ENABLE([static-obj-mgr], + AS_HELP_STRING(--enable-static-obj-mgr,enable static Object_Manager [[[yes]]]), + [ + case "${enableval}" in + yes) + dnl nothing to do + ;; + no) + AC_DEFINE([ACE_HAS_NONSTATIC_OBJECT_MANAGER]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-static-obj-mgr]) + ;; + esac + ],) + + + AC_ARG_ENABLE([threads], + AS_HELP_STRING(--enable-threads,enable thread support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_threads=yes + ;; + no) + ace_user_enable_threads=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-threads]) + ;; + esac + ], + [ + ace_user_enable_threads=yes + ]) + AM_CONDITIONAL([BUILD_THREADS], [test X$ace_user_enable_threads = Xyes]) + + AC_ARG_ENABLE([pthreads], + AS_HELP_STRING(--enable-pthreads,enable POSIX thread (Pthreads) support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_pthreads=yes + ;; + no) + ace_user_enable_pthreads=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-pthreads]) + ;; + esac + ], + [ + ace_user_enable_pthreads=yes + ]) + + AC_ARG_ENABLE([aio], + AS_HELP_STRING(--enable-aio,enable aio support [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_aio=yes + ;; + no) + ace_user_enable_aio=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-aio]) + ;; + esac + ], + [ + ace_user_enable_aio=yes + ]) + + AC_ARG_ENABLE([uithreads], + AS_HELP_STRING(--enable-uithreads,enable UNIX International thread support [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_uithreads=yes + ;; + no) + ace_user_enable_uithreads=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-uithreads]) + ;; + esac + ], + [ + dnl The default is to disable UI threads. However, on Solaris, we + dnl enable it by default since it's functionality is very useful and + dnl has traditionally been enabled in ACE. + case "$host" in + *solaris2*) + ace_user_enable_uithreads=yes + AC_MSG_NOTICE([[--enable-uithreads enabled by default for Solaris; use --enable-uithreads=no to disable it.]]) + ;; + *) + ace_user_enable_uithreads=no + ;; + esac + ]) + + AC_ARG_ENABLE([verb-not-sup], + AS_HELP_STRING(--enable-verb-not-sup,enable verbose ENOTSUP reports [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([ACE_HAS_VERBOSE_NOTSUP]) + ;; + no) + dnl Do nothing + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-verb-not-sup]) + ;; + esac + ],) + + AC_ARG_ENABLE([rcsid], + AS_HELP_STRING(--enable-rcsid,compile RCS id strings into object files [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_rcsid=yes + ;; + no) + ace_user_enable_rcsid=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-rcsid]) + ;; + esac + ]) + if test X$ace_user_enable_rcsid = Xyes; then + AC_DEFINE(ACE_USE_RCSID, 1, + [Define to 1 to embed RCS ID strings into compiled object files.]) + fi + + dnl The ace/config-all.h file defaults ACE_NTRACE properly, so only emit + dnl something if the user specifies this option. + AC_ARG_ENABLE([trace], + AS_HELP_STRING(--enable-trace,enable ACE tracing [[[no]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([ACE_NTRACE],0) + ;; + no) + AC_DEFINE([ACE_NTRACE],1) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-trace]) + ;; + esac + ],) + + AC_ARG_ENABLE([wfmo], + AS_HELP_STRING(--enable-wfmo,build WFMO-using examples [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_wfmo=yes + ;; + no) + ace_user_enable_wfmo=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-wfmo]) + ;; + esac + ], + [ + case "$host" in + *win32*) + ace_user_enable_wfmo=yes + ;; + *) + ace_user_enable_wfmo=no + ;; + esac + ]) + AM_CONDITIONAL([BUILD_WFMO], [test X$ace_user_enable_wfmo = Xyes]) + + AC_ARG_ENABLE([wince], + AS_HELP_STRING(--enable-wince,build Windows CE/Mobile-using examples [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_wince=no + ;; + no) + ace_user_enable_wince=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-wince]) + ;; + esac + ], + [ + case "$host" in + *win32*) + ace_user_enable_wince=yes + ;; + *) + ace_user_enable_wince=no + ;; + esac + ]) + AM_CONDITIONAL([BUILD_WINCE], [test X$ace_user_enable_wince = Xyes]) + + AC_ARG_ENABLE([winregistry], + AS_HELP_STRING(--enable-winregistry,build Windows registry-using examples [[[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_winregistry=no + ;; + no) + ace_user_enable_winregistry=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-winregistry]) + ;; + esac + ], + [ + case "$host" in + *win32*) + ace_user_enable_winregistry=yes + ;; + *) + ace_user_enable_winregistry=no + ;; + esac + ]) + AM_CONDITIONAL([BUILD_WINREGISTRY], [test X$ace_user_enable_winregistry = Xyes]) + + ACE_ENABLE_FL_REACTOR + ACE_ENABLE_QT_REACTOR + ACE_ENABLE_TK_REACTOR + ACE_ENABLE_XT_REACTOR + ACE_ENABLE_FOX_REACTOR + + # placeholder for WxWindows/wxWidgets support + AM_CONDITIONAL([BUILD_WXWINDOWS], false) + + ACE_PATH_BZIP2 + ACE_PATH_ZLIB + ACE_PATH_ZZIP + + AC_ARG_ENABLE([gperf], + AS_HELP_STRING(--enable-gperf,compile the gperf program [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_gperf=yes + ;; + no) + ace_user_enable_gperf=no + ;; + *) + AC_MSG_ERROR([bad value ${withval} for --with-gperf]) + ;; + esac + ], + [ + ace_user_enable_gperf=yes + ]) + if test "$ace_user_enable_gperf" = yes; then + AC_DEFINE([ACE_HAS_GPERF]) + AS_IF([test -n "$GPERF"], + [ + AC_MSG_WARN([gperf program already exists]) + AC_MSG_WARN([existing gperf may be overwritten during installation]) + ],[]) + fi + AM_CONDITIONAL([BUILD_GPERF], [test X$ace_user_enable_gperf = Xyes]) + + ACE_ENABLE_QOS + ACE_ENABLE_SSL + ACE_ENABLE_ACEXML + + AC_ARG_WITH([tao], + AS_HELP_STRING(--with-tao,build TAO (the ACE ORB) [[[yes]]]), + [ + case "${withval}" in + yes) + ace_user_with_tao=yes + ;; + no) + ace_user_with_tao=no + ;; + *) + AC_MSG_ERROR([bad value ${withval} for --with-tao]) + ;; + esac + ], + [ + ace_user_with_tao=yes + ]) + + AC_ARG_WITH([tli-device], + AS_HELP_STRING(--with-tli-device(=DEV),device for TCP on TLI [[/dev/tcp]]), + [ + case "${withval}" in + yes) + AC_MSG_ERROR([Specify the TLI/TCP device if you use this option.]) + ;; + no) + ;; + *) + if test -e "${withval}"; then + AC_DEFINE_UNQUOTED([ACE_TLI_TCP_DEVICE], ["${withval}"]) + else + AC_MSG_ERROR([TLI/TCP device ${withval} does not exist.]) + fi + ;; + esac + ],) + + AC_ARG_ENABLE([reentrant], + AS_HELP_STRING(--enable-reentrant,enable reentrant functions [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_reentrant_funcs=yes + ;; + no) + ace_user_enable_reentrant_funcs=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-reentrant]) + ;; + esac + ], + [ + ace_user_enable_reentrant_funcs=yes + ]) + + AC_ARG_ENABLE([ace-examples], + AS_HELP_STRING(--enable-ace-examples,build ACE examples [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_build_examples=yes + ;; + no) + ace_build_examples=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-examples]) + ;; + esac + ], + [ + ace_build_examples=yes + ]) + AM_CONDITIONAL([BUILD_EXAMPLES], [test X$ace_build_examples = Xyes]) + + AC_ARG_ENABLE([ace-tests], + AS_HELP_STRING(--enable-ace-tests,build ACE tests [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_build_tests=yes + ;; + no) + ace_build_tests=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ace-tests]) + ;; + esac + ], + [ + ace_build_tests=yes + ]) + AM_CONDITIONAL([BUILD_TESTS], [test X$ace_build_tests = Xyes]) + + ACE_ENABLE_CDR_SWAP_ON_READ + ACE_ENABLE_CDR_SWAP_ON_WRITE + ACE_ENABLE_CDR_ALIGNMENT + ACE_ENABLE_REACTOR_NOTIFICATION_QUEUE + ACE_ENABLE_STRDUP_EMULATION + ACE_ENABLE_WCSDUP_EMULATION +]) + +AC_DEFUN([ACE_CHECK_LIB64], +[ + AC_ARG_ENABLE(libsuffix, + AC_HELP_STRING([--enable-libsuffix], + [/lib directory suffix (64,32,none,auto[=default])]), + acelibsuff=$enableval, acelibsuff="auto") + + if test "$acelibsuff" = "auto"; then + +cat > conftest.cpp << _ACEOF +#include +int main(int, char **) { + return 0; +} +_ACEOF + acelibsuff=`$CXX conftest.cpp -o conftest.out; ldd conftest.out |sed -ne '/libc.so/{ + s,.*/lib\([[^\/]]*\)/.*,\1, + p +}'` + rm -rf conftest.* + fi + + if test "$acelibsuff" = "no" || test "$acelibsuff" = "none"; then + acelibsuff= + fi + if test -z "$acelibsuff"; then + AC_MSG_RESULT([not using lib directory suffix]) + else + AC_MSG_RESULT([using lib directory suffix $acelibsuff]) + fi +]) + +dnl Macros that add ACE compilation options to a `configure' script. +dnl ACE_COMPILATION_OPTIONS +AC_DEFUN([ACE_COMPILATION_OPTIONS], +[ + AC_ARG_ENABLE([debug], + AS_HELP_STRING(--enable-debug,enable debugging [[[yes]]]), + [ + case "${enableval}" in + yes) + ACE_CXXFLAGS="$ACE_CXXFLAGS $DCXXFLAGS" + ;; + no) + AC_DEFINE([ACE_NDEBUG]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) + ;; + esac + ],) + + AC_ARG_ENABLE([exceptions], + AS_HELP_STRING(--enable-exceptions,enable C++ exception handling [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_exceptions=yes + ;; + no) + ace_user_enable_exceptions=no + if test "$GXX" = yes; then + if $CXX --version | $EGREP -v '^2\.[[0-7]]' > /dev/null; then + ACE_CXXFLAGS="$ACE_CXXFLAGS -fno-exceptions" + fi + fi + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-exceptions]) + ;; + esac + ], + [ + ace_user_enable_exceptions=yes + +dnl THE FOLLOWING WAS ONLY USED WHEN DISABLING EXCEPTION SUPPORT BY +dnl DEFAULT. +dnl +dnl if test "$GXX" = yes; then +dnl if $CXX --version | $EGREP -v '^2\.[[0-7]]' > /dev/null; then +dnl ACE_CXXFLAGS="$ACE_CXXFLAGS -fno-exceptions" +dnl fi +dnl fi + ]) + AM_CONDITIONAL([BUILD_EXCEPTIONS], [test X$ace_user_enable_exceptions = Xyes]) + + AC_ARG_ENABLE([fast], + AS_HELP_STRING(--enable-fast,enable -fast flag (e.g. Sun C++) [[[no]]]), + [ + case "${enableval}" in + yes) + ACE_CXXFLAGS="$ACE_CXXFLAGS -fast" + ACE_CFLAGS="$ACE_CFLAGS -fast" + ;; + no) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-fast]) + ;; + esac + ],) + + AC_ARG_ENABLE([ipo], + AS_HELP_STRING(--enable-ipo,enable -ipo flag (e.g. Intel C++) [[[no]]]), + [ + case "${enableval}" in + yes) + ACE_CXXFLAGS="$ACE_CXXFLAGS -ipo" + ACE_CFLAGS="$ACE_CFLAGS -ipo" + ;; + no) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-ipo]) + ;; + esac + ],) + + AC_ARG_ENABLE([inline], + AS_HELP_STRING(--enable-inline,enable code inlining [[[yes]]]), + [ + case "${enableval}" in + yes) + AC_DEFINE([__ACE_INLINE__]) + ;; + no) + AC_DEFINE([ACE_NO_INLINE]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-inline]) + ;; + esac + ], + [ + AC_DEFINE([__ACE_INLINE__]) + ]) + + AC_ARG_ENABLE([optimize], + AS_HELP_STRING(--enable-optimize,enable additional optimizations [[[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_optimize=yes + ;; + no) + AC_MSG_WARN([Optimization configure support not fully implemented yet.]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-optimize]) + ;; + esac + ], + [ + ace_user_enable_optimize=yes + ]) + + + AC_ARG_ENABLE([profile], + AS_HELP_STRING(--enable-profile,enable profiling [[[no]]]), + [ + case "${enableval}" in + yes) + if test -z "$PROF"; then + AC_MSG_WARN([No profiling program found. Assuming 'prof' exists.]) + ACE_CXXFLAGS="$ACE_CXXFLAGS -p" + ACE_CFLAGS="$ACE_CFLAGS -p" + else + case "$PROF" in + gprof) + echo "Building with 'gprof' support" + ACE_CXXFLAGS="$ACE_CXXFLAGS -pg" + ACE_CFLAGS="$ACE_CFLAGS -pg" + ;; + prof) + echo "Building with 'prof' support" + ACE_CXXFLAGS="$ACE_CXXFLAGS -p" + ACE_CFLAGS="$ACE_CFLAGS -p" + ;; + *) + dnl We shouldn't get here. + AC_MSG_WARN([Assuming 'prof' exists.]) + ACE_CXXFLAGS="$ACE_CXXFLAGS -p" + ACE_CFLAGS="$ACE_CFLAGS -p" + ;; + esac + fi + ;; + no) + dnl Do nothing + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-profile]) + ;; + esac + ],) + + AC_ARG_ENABLE([purify], + AS_HELP_STRING(--enable-purify,Purify all executables [[[no]]]), + [ + case "${enableval}" in + yes) + AC_CHECK_PROG([PURIFY], [purify], [purify],[]) + if test -n "$PURIFY"; then + PURE_CACHE_BASE_DIR=/tmp/purifycache + PURE_CACHE_DIR="${PURE_CACHE_BASE_DIR}-${LOGNAME}" + PURE_CACHE_DIR="${PURE_CACHE_DIR}-"`basename $CXX` + PURELINK="$PURIFY -best-effort -chain-length=20 -cache-dir=$PURE_CACHE_DIR -fds-inuse-at-exit=no -inuse-at-exit -max_threads=100" + dnl Pick up Quantify directory from the users PATH. + ACE_PURIFY_DIR=`type purify | sed -e 's/.* is //' -e 's%/purify'` + ACE_CPPFLAGS="-DACE_HAS_PURIFY -I$ACE_PURIFY_DIR" + else + AC_MSG_WARN([Purify program was not found.]) + AC_MSG_WARN([Disabling purify support.]) + fi + ;; + no) + PURELINK="" + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-purify]) + ;; + esac + ], PURELINK="") + + AC_ARG_ENABLE([quantify], + AS_HELP_STRING(--enable-quantify,Quantify all executables [[[no]]]), + [ + case "${enableval}" in + yes) + AC_CHECK_PROG([QUANTIFY], [quantify], [quantify],[]) + if test -n "$QUANTIFY"; then + PURE_CACHE_BASE_DIR=/tmp/purifycache + PURE_CACHE_DIR="${PURE_CACHE_BASE_DIR}-${LOGNAME}" + PURE_CACHE_DIR="${PURE_CACHE_DIR}-"`basename $CXX` + + PRELINK="$QUANTIFY -best-effort -max_threads=100 -cache-dir=$PURE_CACHE_DIR" + dnl Pick up Quantify directory from the users PATH. + ACE_QUANTIFY_DIR=`type quantify | sed -e 's/.* is //' -e 's%/quantify$$%%'` + ACE_CPPFLAGS="-DACE_HAS_QUANTIFY -I$ACE_QUANTIFY_DIR" + else + AC_MSG_WARN([Quantify program was not found.]) + AC_MSG_WARN([Disabling quantify support.]) + fi + ;; + no) + PRELINK="" + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-quantify]) + ;; + esac + ], PRELINK="") + + AC_ARG_ENABLE([repo], + AS_HELP_STRING(--enable-repo,use GNU template repository GNU C++ with repo patches and EGCS only [[[no]]]), + [ + case "${enableval}" in + yes) + if test "$GXX" = yes; then + ace_user_enable_repo=yes + ACE_CXXFLAGS="$ACE_CXXFLAGS -frepo" + AC_DEFINE(ACE_HAS_GNU_REPO) + else + ace_user_enable_repo=no + AC_MSG_WARN([Not using GNU C++! GNU template respository disabled.]) + fi + ;; + no) + ace_user_enable_repo=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-repo]) + ;; + esac + ], + [ + ace_user_enable_repo=no + ]) + + AC_ARG_ENABLE([stdcpplib], + AS_HELP_STRING([--enable-stdcpplib],[enable standard C++ library [[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_stdcpplib=yes + ;; + no) + ace_user_enable_stdcpplib=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-stdcpplib]) + ;; + esac + ], + [ + ace_user_enable_stdcpplib=yes + ]) + + AC_ARG_ENABLE([uses-wchar], + AS_HELP_STRING([--enable-uses-wchar], + [enable use of wide characters [[no]]]), + [case "${enableval}" in + yes) + AC_DEFINE([ACE_USES_WCHAR]) + ace_cv_user_enable_wide_char=yes + ;; + no) + ace_cv_user_enable_wide_char=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-uses-wchar]) + ;; + esac]) + AC_CACHE_CHECK([whether to use wide characters internally], + [ace_cv_user_enable_wide_char], [ace_cv_user_enable_wide_char=no]) + AM_CONDITIONAL([BUILD_USES_WCHAR], [test X$ace_cv_user_enable_wide_char = Xyes]) + +]) + +# ACE_ENABLE_CDR_SWAP_ON_READ +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_CDR_SWAP_ON_READ], +[AC_ARG_ENABLE([ace-cdr-swap-on-read], + AS_HELP_STRING([--enable-ace-cdr-swap-on-read], + [configure CDR to support swap on read [[yes]]]), + [case "${enableval}" in + yes) + ace_user_cdr_swap_on_read=yes + ;; + no) + ace_user_cdr_swap_on_read=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ace-cdr-swap-on-read) + ;; + esac],[ + ace_user_cdr_swap_on_read=yes + ]) +if test X$ace_user_cdr_swap_on_read = Xno; then + AC_DEFINE(ACE_DISABLE_SWAP_ON_READ, 1, + [Define to 1 to disable swapping swapping CDR on read]) +fi +]) + +# ACE_ENABLE_CDR_SWAP_ON_WRITE +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_CDR_SWAP_ON_WRITE], +[AC_ARG_ENABLE([ace-cdr-swap-on-write], + AS_HELP_STRING([--enable-ace-cdr-swap-on-write], + [configure CDR to support swap on write [[no]]]), + [case "${enableval}" in + yes) + ace_user_cdr_swap_on_write=yes + ;; + no) + ace_user_cdr_swap_on_write=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ace-cdr-swap-on-write) + ;; + esac],[ + ace_user_cdr_swap_on_write=no + ]) +if test X$ace_user_cdr_swap_on_write = Xyes; then + AC_DEFINE(ACE_ENABLE_SWAP_ON_WRITE, 1, + [Define to 1 to enable swapping swapping CDR on write]) +fi +]) + +# ACE_ENABLE_CDR_ALIGNMENT +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_CDR_ALIGNMENT], +[AC_ARG_ENABLE([ace-cdr-alignment], + AS_HELP_STRING([--enable-ace-cdr-alignment], + [configure CDR to require aligned access [[yes]]]), + [case "${enableval}" in + yes) + ace_user_cdr_alignment=yes + ;; + no) + ace_user_cdr_alignment=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ace-cdr-alignment) + ;; + esac],[ + ace_user_cdr_alignment=yes + ]) +if test X$ace_user_cdr_alignment = Xno; then + AC_DEFINE(ACE_LACKS_CDR_ALIGNMENT, 1, + [Define to 1 to support unaligned CDR]) +fi +]) + +# ACE_ENABLE_REACTOR_NOTIFICATION_QUEUE +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_REACTOR_NOTIFICATION_QUEUE], +[AC_ARG_ENABLE([ace-reactor-notification-queue], + AS_HELP_STRING([--enable-ace-reactor-notification-queue], + [configure Reactor to use a user-space queue for notifications [[no]]]), + [case "${enableval}" in + yes) + ace_user_reactor_notification_queue=yes + ;; + no) + ace_user_reactor_notification_queue=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ace-reactor-notification-queue) + ;; + esac],[ + ace_user_reactor_notification_queue=no + ]) +if test X$ace_user_reactor_notification_queue = Xyes; then + AC_DEFINE([ACE_HAS_REACTOR_NOTIFICATION_QUEUE], 1, + [Define to 1 to configure Reactor to use a user-space queue for notifications]) +fi +]) + + +# ACE_ENABLE_STRDUP_EMULATION +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_STRDUP_EMULATION], +[AC_ARG_ENABLE([ace-strdup-emulation], + AS_HELP_STRING([--enable-ace-strdup-emulation], + [use ACE's strdup emulation [[no]]]), + [case "${enableval}" in + yes) + ace_user_strdup_emulation=yes + ;; + no) + ace_user_strdup_emulation=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ace-strdup-emulation) + ;; + esac],[ + ace_user_strdup_emulation=no + ]) +if test X$ace_user_strdup_emulation = Xyes; then + AC_DEFINE(ACE_HAS_STRDUP_EMULATION, 1, + [Define to 1 use ACE's strdup() emulation]) +fi +]) + +# ACE_ENABLE_WCSDUP_EMULATION +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_WCSDUP_EMULATION], +[AC_ARG_ENABLE([ace-wcsdup-emulation], + AS_HELP_STRING([--enable-ace-wcsdup-emulation], + [use ACE's wcsdup emulation [[no]]]), + [case "${enableval}" in + yes) + ace_user_wcsdup_emulation=yes + ;; + no) + ace_user_wcsdup_emulation=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ace-wcsdup-emulation) + ;; + esac],[ + ace_user_wcsdup_emulation=no + ]) +if test X$ace_user_wcsdup_emulation = Xyes; then + AC_DEFINE(ACE_HAS_WCSDUP_EMULATION, 1, + [Define to 1 use ACE's wcsdup() emulation]) +fi +]) + +AC_DEFUN([ACE_ENABLE_QOS], +[AC_ARG_ENABLE([qos], + AS_HELP_STRING([--enable-qos], + [compile/use the ACE_QoS library [[no]]]), + [case "${enableval}" in + yes) + ace_cv_user_enable_qos=yes + ;; + no) + ace_cv_user_enable_qos=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-qos) + ;; + esac]) +AC_CACHE_CHECK([whether to compile/use the ACE_QoS library], + [ace_cv_user_enable_qos],[ace_cv_user_enable_qos=no]) +AM_CONDITIONAL([BUILD_QOS], [test X$ace_cv_user_enable_qos = Xyes]) +]) + +AC_DEFUN([ACE_ENABLE_SSL], +[AC_REQUIRE([ACE_CHECK_TLS]) +AC_ARG_ENABLE([ssl], + AS_HELP_STRING([--enable-ssl], + [compile/use the ACE_SSL library [[yes]]]), + [case "${enableval}" in + yes) + ace_cv_user_enable_ssl=yes + ;; + no) + ace_cv_user_enable_ssl=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-ssl) + ;; + esac]) +AC_CACHE_CHECK([whether to compile/use the ACE_SSL library], + [ace_cv_user_enable_ssl], [ace_cv_user_enable_ssl=yes]) +AM_CONDITIONAL([BUILD_SSL], [test X$ace_cv_user_enable_ssl = Xyes]) +]) + +AC_DEFUN([ACE_ENABLE_ACEXML], +[AC_ARG_ENABLE([acexml], + AS_HELP_STRING([--enable-acexml], + [compile/use the ACEXML library [[yes]]]), + [case "${enableval}" in + yes) + ace_cv_user_enable_acexml=yes + ;; + no) + ace_cv_user_enable_acexml=no + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-acexml) + ;; + esac], + [ + ace_cv_user_enable_acexml=yes + ]) +AC_CACHE_CHECK([whether to compile/use the ACEXML library], + [ace_cv_user_enable_acexml], [ace_cv_user_enable_acexml=yes]) +AM_CONDITIONAL([BUILD_ACEXML], [test X$ace_cv_user_enable_acexml = Xyes]) +]) + + +# ACE_PATH_GL +#--------------------------------------------------------------------------- +# Find OpenGL Libraries, flags, etc. +AC_DEFUN([ACE_PATH_GL], +[ +]) + + +# ACE_PATH_FL +#--------------------------------------------------------------------------- +# Find FL/TK Libraries, flags, etc. +AC_DEFUN([ACE_PATH_FL], +[AC_REQUIRE([ACE_PATH_GL]) + AC_ARG_WITH([fltkconfig], + AS_HELP_STRING([--with-fltkconfig=DIR], + [path to fltk-config [[automatic]]]), + [ ac_fltkconfig_dir="${withval}" ]) + if test X"${ac_fltkconfig_dir}" = X; then + AC_PATH_PROG([FLTKCONFIG], [fltk-config], []) + else + AC_MSG_CHECKING([whether fltk-config exists in ${ac_fltkconfig_dir}]) + if test -f "${ac_fltkconfig_dir}/fltk-config"; then + FLTKCONFIG="${ac_fltkconfig_dir}/fltk-config" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + if test X"${FLTKCONFIG}" != X; then + ACE_FLTK_CPPFLAGS=`$FLTKCONFIG --use-gl --cxxflags 2>/dev/null` + ACE_FLTK_LIBS=`$FLTKCONFIG --use-gl --ldflags 2>/dev/null` + + AC_SUBST(ACE_FLTK_CPPFLAGS) + AC_SUBST(ACE_FLTK_LIBS) + fi +]) + + +# ACE_PATH_QT +#--------------------------------------------------------------------------- +# Find Qt Libraries, flags, etc. +AC_DEFUN([ACE_PATH_QT], +[ + ac_qt_found=no + PKG_CHECK_MODULES([Qt], [qt-mt], + [ac_qt_found=yes], + [AC_MSG_RESULT([not found])]) + if test X"${ac_qt_found}" = Xyes; then + ACE_QT_CPPFLAGS="${Qt_CFLAGS}" + ACE_QT_LIBS="${Qt_LIBS}" + AC_SUBST(ACE_QT_CPPFLAGS) + AC_SUBST(ACE_QT_LIBS) + + AS_IF([test -n "$QTDIR"], + [], + [QTDIR=`$PKG_CONFIG --variable=prefix qt-mt 2>/dev/null`]) + AC_SUBST(QTDIR) + fi +]) + + +# ACE_PATH_TCL +#--------------------------------------------------------------------------- +# Find Tcl Libraries, flags, etc. +AC_DEFUN([ACE_PATH_TCL], +[AC_REQUIRE([ACE_CHECK_LIB64]) + AC_ARG_WITH([tclconfig], + AS_HELP_STRING([--with-tclconfig=DIR], + [path to tclConfig.sh [[automatic]]]), + [ ac_tclconfig_dir="${withval}" ]) + + if test X"${ac_tclconfig_dir}" = X; then + for i in `ls -d ${exec_prefix}/lib${acelibsuff} 2>/dev/null` \ + `ls -d ${prefix}/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/local/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/contrib/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/pkg/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/lib${acelibsuff}/tcl8.[[43]]* 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_tclconfig_dir=`(cd $i; pwd)` + break + fi + done + fi + + AC_MSG_CHECKING([whether tclConfig.sh exists in ${ac_tclconfig_dir}]) + if test -f "${ac_tclconfig_dir}/tclConfig.sh"; then + TCLCONFIG="${ac_tclconfig_dir}/tclConfig.sh" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + + if test X"${TCLCONFIG}" != X; then + . ${TCLCONFIG} + + ACE_TCL_CPPFLAGS="${TCL_INCLUDE_SPEC}" + eval "ACE_TCL_LIBS=\"${TCL_LIB_SPEC}\"" + + AC_SUBST(ACE_TCL_CPPFLAGS) + AC_SUBST(ACE_TCL_LIBS) + fi +]) + + +# ACE_PATH_TK +#--------------------------------------------------------------------------- +# Find Tk Libraries, flags, etc. +AC_DEFUN([ACE_PATH_TK], +[AC_REQUIRE([ACE_PATH_TCL]) + AC_ARG_WITH([tkconfig], + AS_HELP_STRING([--with-tkconfig=DIR], + [path to tkConfig.sh [[automatic]]]), + [ ac_tkconfig_dir="${withval}" ]) + if test X"${ac_tkconfig_dir}" = X; then + if test X"${ac_tclconfig_dir}" != X && test -f ${ac_tclconfig_dir}/tkConfig.sh; then + ac_tkconfig_dir=$ac_tclconfig_dir; + else + for i in `ls -d ${exec_prefix}/lib${acelibsuff} 2>/dev/null` \ + `ls -d ${prefix}/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/local/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/contrib/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/pkg/lib${acelibsuff} 2>/dev/null` \ + `ls -d /usr/lib${acelibsuff}/tk8.[[43]]* 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_tkconfig_dir=`(cd $i; pwd)` + break + fi + done + fi + fi + + AC_MSG_CHECKING([whether tkConfig.sh exists in ${ac_tkconfig_dir}]) + if test -f "${ac_tkconfig_dir}/tkConfig.sh"; then + TKCONFIG="${ac_tkconfig_dir}/tkConfig.sh" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + + if test X"${TKCONFIG}" != X; then + . ${TKCONFIG} + + ACE_TK_CPPFLAGS="${TK_INCLUDE_SPEC} ${TK_XINCLUDES}" + ACE_TK_LIBS="${TK_LIB_SPEC} ${TK_XLIBSW}" + + AC_SUBST(ACE_TK_CPPFLAGS) + AC_SUBST(ACE_TK_LIBS) + fi +]) + + +# ACE_PATH_XT +#--------------------------------------------------------------------------- +# Find Xt libraries, flags, etc. +AC_DEFUN([ACE_PATH_XT], +[AC_REQUIRE([ACE_PATH_X11]) + +if test "$no_x" != yes; then + ACE_XT_CPPFLAGS="" + ACE_XT_LDFLAGS="" + ACE_XT_LIBS="-lXt" + + AC_SUBST(ACE_XT_CPPFLAGS) + AC_SUBST(ACE_XT_LDFLAGS) + AC_SUBST(ACE_XT_LIBS) +fi +AM_CONDITIONAL([BUILD_ATHENA], true) +AM_CONDITIONAL([BUILD_MOTIF], false) +]) + + +# ACE_PATH_X11 +#--------------------------------------------------------------------------- +# Find X11 libraries, flags, etc. +AC_DEFUN([ACE_PATH_X11], +[AC_REQUIRE([AC_PATH_XTRA]) + +if test "$no_x" != yes; then + ACE_X11_CPPFLAGS="${X_CFLAGS}" + ACE_X11_LDFLAGS="${X_LIBS}" + ACE_X11_LIBS="${X_PRE_LIBS} -lX11 ${X_EXTRA_LIBS}" + + AC_SUBST(ACE_X11_CPPFLAGS) + AC_SUBST(ACE_X11_LDFLAGS) + AC_SUBST(ACE_X11_LIBS) +fi + +AM_CONDITIONAL([BUILD_X11], [test X$no_x != Xyes]) +]) + + +# ACE_PATH_BZIP2 +#--------------------------------------------------------------------------- +# Find bzip2 Libraries, flags, etc. +AC_DEFUN([ACE_PATH_BZIP2], +[ +ACE_BZIP2_CPPFLAGS="" +ACE_BZIP2_LDFLAGS="" + +dnl TODO: default to false, at least until we add a check to see if +dnl the bzip2 library is usable. +AC_ARG_WITH([bzip2], + AS_HELP_STRING([--with-bzip2@<:@=DIR@:>@], + [root directory of bzip2 installation]), + [ + ace_with_bzip2="${withval}" + if test "${ace_with_bzip2}" != yes; then + ace_bzip2_include="${ace_with_bzip2}/include" + ace_bzip2_libdir="${ace_with_bzip2}/lib" + fi + ],[ace_with_bzip2=no]) + +dnl TODO: let's wait and see before adding options to specify header +dnl and library location separately. +dnl +dnl AC_ARG_WITH([bzip2_include], +dnl AS_HELP_STRING([--with-bzip2-include=DIR], +dnl [specify exact include dir for bzip2 headers]), +dnl [ace_bzip2_include="$withval"]) +dnl +dnl AC_ARG_WITH([bzip2_libdir], +dnl AS_HELP_STRING([--with-bzip2-libdir=DIR], +dnl [specify exact include dir for bzip2 libraries]), +dnl [ace_bzip2_libdir="$withval"]) + +if test "${ace_bzip2_include}"; then + ACE_BZIP2_CPPFLAGS="-I$ace_bzip2_include" +fi + +if test "${ace_bzip2_libdir}"; then + ACE_BZIP2_LDFLAGS="-L$ace_bzip2_libdir" +fi + +ACE_BZIP2_CPPFLAGS="${ACE_BZIP2_CPPFLAGS} -DBZIP2" + +if test "${ace_with_bzip2}" != no; then + ACE_BZIP2_LIBS="-lbz2" + AC_SUBST(ACE_BZIP2_CPPFLAGS) + AC_SUBST(ACE_BZIP2_LDFLAGS) + AC_SUBST(ACE_BZIP2_LIBS) +fi +AM_CONDITIONAL([BUILD_BZIP2], test "${ace_with_bzip2}" != no) +]) + + +# ACE_PATH_ZLIB +#--------------------------------------------------------------------------- +# Find zlib Libraries, flags, etc. +AC_DEFUN([ACE_PATH_ZLIB], +[ +ACE_ZLIB_CPPFLAGS="" +ACE_ZLIB_LDFLAGS="" + +dnl TODO: default to false, at least until we add a check to see if +dnl the zlib library is usable. +AC_ARG_WITH([zlib], + AS_HELP_STRING([--with-zlib@<:@=DIR@:>@], + [root directory of zlib installation]), + [ + ace_with_zlib="${withval}" + if test "${ace_with_zlib}" != yes; then + ace_zlib_include="${ace_with_zlib}/include" + ace_zlib_libdir="${ace_with_zlib}/lib" + fi + ],[ace_with_zlib=no]) + +dnl TODO: let's wait and see before adding options to specify header +dnl and library location separately. +dnl +dnl AC_ARG_WITH([zlib_include], +dnl AS_HELP_STRING([--with-zlib-include=DIR], +dnl [specify exact include dir for zlib headers]), +dnl [ace_zlib_include="$withval"]) +dnl +dnl AC_ARG_WITH([zlib_libdir], +dnl AS_HELP_STRING([--with-zlib-libdir=DIR], +dnl [specify exact include dir for zlib libraries]), +dnl [ace_zlib_libdir="$withval"]) + +if test "${ace_zlib_include}"; then + ACE_ZLIB_CPPFLAGS="-I$ace_zlib_include" +fi + +if test "${ace_zlib_libdir}"; then + ACE_ZLIB_LDFLAGS="-L$ace_zlib_libdir" +fi + +ACE_ZLIB_CPPFLAGS="${ACE_ZLIB_CPPFLAGS} -DZLIB" + +if test "${ace_with_zlib}" != no; then + ACE_ZLIB_LIBS="-lz" + AC_SUBST(ACE_ZLIB_CPPFLAGS) + AC_SUBST(ACE_ZLIB_LDFLAGS) + AC_SUBST(ACE_ZLIB_LIBS) +fi +AM_CONDITIONAL([BUILD_ZLIB], test "${ace_with_zlib}" != no) +]) + + +# ACE_PATH_ZZIP +#--------------------------------------------------------------------------- +# Find zziplib Libraries, flags, etc. +AC_DEFUN([ACE_PATH_ZZIP], +[AC_REQUIRE([ACE_PATH_ZLIB]) + +ACE_ZZIP_CPPFLAGS="" +ACE_ZZIP_LDFLAGS="" + +dnl TODO: default to false, at least until we add a check to see if +dnl the zlib library is usable. +AC_ARG_WITH([zzip], + AS_HELP_STRING([--with-zzip@<:@=DIR@:>@], + [root directory of zzip installation]), + [ + ace_with_zzip="${withval}" + if test "${ace_with_zzip}" != yes; then + ace_zzip_include="${ace_with_zzip}/include" + ace_zzip_libdir="${ace_with_zzip}/lib" + fi + ],[ace_with_zzip=no]) + +dnl TODO: let's wait and see before adding options to specify header +dnl and library location separately. +dnl +dnl AC_ARG_WITH([zzip_include], +dnl AS_HELP_STRING([--with-zzip-include=DIR], +dnl [specify exact include dir for zzip headers]), +dnl [ace_zzip_include="$withval"]) +dnl +dnl AC_ARG_WITH([zzip_libdir], +dnl AS_HELP_STRING([--with-zzip-libdir=DIR], +dnl [specify exact include dir for zzip libraries]), +dnl [ace_zzip_libdir="$withval"]) + +if test "${ace_zzip_include}"; then + ACE_ZZIP_CPPFLAGS="-I$ace_zzip_include" +fi + +if test "${ace_zzip_libdir}"; then + ACE_ZZIP_LDFLAGS="-L$ace_zzip_libdir" +fi + +ACE_ZZIP_CPPFLAGS="${ACE_ZZIP_CPPFLAGS} -DUSE_ZZIP" + +if test "${ace_with_zzip}" != no; then + ACE_ZZIP_LIBS="-lzzip" + AC_SUBST(ACE_ZZIP_CPPFLAGS) + AC_SUBST(ACE_ZZIP_LDFLAGS) + AC_SUBST(ACE_ZZIP_LIBS) +fi +AM_CONDITIONAL([BUILD_ZZIP], test "${ace_with_zzip}" != no) +]) + +# ACE_ENABLE_FL_REACTOR +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_FL_REACTOR], +[AC_REQUIRE([ACE_PATH_FL]) +AC_REQUIRE([ACE_PATH_X11]) +AC_ARG_ENABLE([fl-reactor], + AS_HELP_STRING([--enable-fl-reactor], + [build support for the FlReactor [[no]]]), + [case "${enableval}" in + yes) + AS_IF([test X"${FLTKCONFIG}" != X], + [ace_user_enable_fl_reactor=yes], + [AC_MSG_ERROR([ACE_FlReactor cannot be enabled: fltk-config not found.])]) + ;; + no) + ace_user_enable_fl_reactor=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-fl-reactor]) + ;; + esac], + [ + ace_user_enable_fl_reactor=no + ]) +AM_CONDITIONAL([BUILD_GL], [test X$ace_user_enable_fl_reactor = Xyes]) +AM_CONDITIONAL([BUILD_FL], [test X$ace_user_enable_fl_reactor = Xyes]) +AM_CONDITIONAL([BUILD_ACE_FLREACTOR], + [test X$ace_user_enable_fl_reactor = Xyes]) +AM_CONDITIONAL([BUILD_TAO_FLRESOURCE], + [test X$ace_user_enable_fl_reactor = Xyes]) +]) + + +# ACE_ENABLE_QT_REACTOR +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_QT_REACTOR], +[AC_REQUIRE([ACE_PATH_QT]) +AC_ARG_ENABLE([qt-reactor], + AS_HELP_STRING([--enable-qt-reactor], + [build support for the QtReactor [[no]]]), + [case "${enableval}" in + yes) + AS_IF([test X"${ac_qt_found}" = Xyes], + [ace_user_enable_qt_reactor=yes], + [AC_MSG_ERROR([ACE_QtReactor cannot be enabled: Qt not found.])]) + ;; + no) + ace_user_enable_qt_reactor=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-qt-reactor]) + ;; + esac], + [ + ace_user_enable_qt_reactor=no + ]) +AM_CONDITIONAL([BUILD_QT], [test X$ace_user_enable_qt_reactor = Xyes]) +AM_CONDITIONAL([BUILD_ACE_QTREACTOR], + [test X$ace_user_enable_qt_reactor = Xyes]) +AM_CONDITIONAL([BUILD_TAO_QTRESOURCE], + [test X$ace_user_enable_qt_reactor = Xyes]) +]) + + +# ACE_ENABLE_TK_REACTOR +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_TK_REACTOR], +[AC_REQUIRE([ACE_PATH_TK]) +AC_ARG_ENABLE([tk-reactor], + AS_HELP_STRING([--enable-tk-reactor], + [build support for the TkReactor [[no]]]), + [case "${enableval}" in + yes) + AS_IF([test X"${TCLCONFIG}" != X], + [AS_IF([test X"${TKCONFIG}" != X], + [ace_user_enable_tk_reactor=yes], + [AC_MSG_ERROR([ACE_TkReactor cannot be enabled: tkConfig not found.])])], + [AC_MSG_ERROR([ACE_TkReactor cannot be enabled: tclConfig not found.])]) + ;; + no) + ace_user_enable_tk_reactor=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-tk-reactor]) + ;; + esac], + [ + ace_user_enable_tk_reactor=no + ]) +AM_CONDITIONAL([BUILD_TK], [test X$ace_user_enable_tk_reactor = Xyes]) +AM_CONDITIONAL([BUILD_ACE_TKREACTOR], + [test X$ace_user_enable_tk_reactor = Xyes]) +AM_CONDITIONAL([BUILD_TAO_TKRESOURCE], + [test X$ace_user_enable_tk_reactor = Xyes]) +]) + + +# ACE_ENABLE_XT_REACTOR +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_XT_REACTOR], +[AC_REQUIRE([ACE_PATH_XT]) +AC_ARG_ENABLE([xt-reactor], + AS_HELP_STRING([--enable-xt-reactor], + [build support for the XtReactor [[no]]]), + [case "${enableval}" in + yes) +dnl Here, if X isn't found or the user sets "--without-x" on the command +dnl line, then "no_x" is set to "yes." + AS_IF([test "$no_x" != yes], + [ + ace_user_enable_xt_reactor=yes + ],[ + ace_user_enable_xt_reactor=no + AC_MSG_WARN([X was not found or it was disabled.]) + AC_MSG_WARN([ACE_XtReactor will not be enabled.]) + ]) + ;; + no) + ace_user_enable_xt_reactor=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-xt-reactor]) + ;; + esac], + [ + ace_user_enable_xt_reactor=no + ]) +AM_CONDITIONAL([BUILD_XT], [test X$ace_user_enable_xt_reactor = Xyes]) +AM_CONDITIONAL([BUILD_ACE_XTREACTOR], + [test X$ace_user_enable_xt_reactor = Xyes]) +AM_CONDITIONAL([BUILD_TAO_XTRESOURCE], + [test X$ace_user_enable_xt_reactor = Xyes]) +]) + +# ACE_PATH_FOX +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_PATH_FOX], +[AC_ARG_WITH([fox-config], + AS_HELP_STRING([--with-fox-config=DIR], + [path to fox-config [[automatic]]]), + [ ac_fox_config_dir="${withval}" ]) + if test X"${ac_fox_config_dir}" = X; then + AC_PATH_PROG([FOXCONFIG], [fox-config], [], []) + else + AC_MSG_CHECKING([whether fox-config exists in ${ac_fox_config_dir}]) + if test -f "${ac_fox_config_dir}/fox-config"; then + FOXCONFIG="${ac_fox_config_dir}/fox-config" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + if test X"${FOXCONFIG}" != X; then + ACE_FOX_CPPFLAGS=`$FOXCONFIG --cflags 2>/dev/null` + ACE_FOX_LIBS=`$FOXCONFIG --libs 2>/dev/null` + AC_SUBST(ACE_FOX_CPPFLAGS) + AC_SUBST(ACE_FOX_LIBS) + fi +]) + +# ACE_ENABLE_FOX_REACTOR +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_ENABLE_FOX_REACTOR], +[AC_REQUIRE([ACE_PATH_FOX]) +AC_ARG_ENABLE([fox-reactor], + AS_HELP_STRING([--enable-fox-reactor], + [build support for the FoxReactor [[no]]]), + [case "${enableval}" in + yes) + AS_IF([test X"${FOXCONFIG}" != X], + [ace_user_enable_fox_reactor=yes], + [AC_MSG_ERROR([ACE_FoxReactor cannot be enabled: fox-config not found.])]) + ;; + no) + ace_user_enable_fox_reactor=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-fox-reactor]) + ;; + esac], + [ + ace_user_enable_fox_reactor=no + ]) +AM_CONDITIONAL([BUILD_FOX], [test X$ace_user_enable_fox_reactor = Xyes]) +AM_CONDITIONAL([BUILD_ACE_FOXREACTOR], + [test X$ace_user_enable_fox_reactor = Xyes]) +AM_CONDITIONAL([BUILD_TAO_FOXRESOURCE], + [test X$ace_user_enable_fox_reactor = Xyes]) +]) diff --git a/dep/ACE_wrappers/m4/ace_defines.m4 b/dep/ACE_wrappers/m4/ace_defines.m4 new file mode 100644 index 000000000..bb5ba514a --- /dev/null +++ b/dep/ACE_wrappers/m4/ace_defines.m4 @@ -0,0 +1,48 @@ +# ACE_CHECK_DEFINE(DEFINE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], +# [INCLUDES = 'default-includes']) +#----------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ace_cv_defined_$1])dnl +AC_CACHE_CHECK([for $1], ac_var, +AC_COMPILE_IFELSE([AC_LANG_SOURCE([AC_INCLUDES_DEFAULT([$4]) +#ifdef $1 +int ok; +#else +choke me +#endif +])],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no))) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +# ACE_CHECK_HAS_DEFINES(DEFINE..., [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], +# [INCLUDES = 'default-includes']) +#----------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_HAS_DEFINES], +[AC_FOREACH([ACE_Def], [$1], + [AH_TEMPLATE(AS_TR_CPP(ACE_HAS_[]ACE_Def), + [Define to 1 if platform has ]ACE_Def[().])])dnl +for ace_def in $1 +do +ACE_CHECK_DEFINE($ace_def, + [AC_DEFINE_UNQUOTED([AS_TR_CPP([ACE_HAS_$ace_def])]) $2], + [$3], + [$4])dnl +done +]) + +# ACE_CHECK_LACKS_DEFINES(DEFINE..., [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# [INCLUDES = 'default-includes']) +#----------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_LACKS_DEFINES], +[AC_FOREACH([ACE_Def], [$1], + [AH_TEMPLATE(AS_TR_CPP(ACE_LACKS_[]ACE_Def), + [Define to 1 if platform lacks ]ACE_Def[().])])dnl +for ace_def in $1 +do +ACE_CHECK_DEFINE($ace_def, + [$2], + [AC_DEFINE_UNQUOTED([AS_TR_CPP([ACE_LACKS_$ace_def])]) $3], + [$4])dnl +done +]) diff --git a/dep/ACE_wrappers/m4/ace_func.m4 b/dep/ACE_wrappers/m4/ace_func.m4 new file mode 100644 index 000000000..52ff1a0b2 --- /dev/null +++ b/dep/ACE_wrappers/m4/ace_func.m4 @@ -0,0 +1,148 @@ +# ACE_FUNC_STRCASECMP +# + Defines ACE_LACKS_STRCASECMP to 1 if platform lacks strcasecmp() +# + Defines ACE_STRCASECMP_EQUIVALENT to identifier name if platform +# has a equivalent function that differs in name only. +# + Defines ACE_LACKS_STRCASECMP_PROTOTYPE to 1 if platform lacks +# declaration for strcasecmp(). +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_STRCASECMP], +[ACE_CHECK_LACKS_FUNCS(strcasecmp) +if test "$ac_cv_func_strcasecmp" = yes; then + AC_CHECK_DECL([strcasecmp], + [], + [AC_DEFINE([ACE_LACKS_STRCASECMP_PROTOTYPE], 1, + [Define to 1 if platform lacks a declaration for strcasecmp()])], + [ +#if !defined(ACE_LACKS_STRINGS_H) +#include +#endif +#if !defined(ACE_LACKS_STRING_H) +#include +#endif + ]) +else + AC_CHECK_FUNC(stricmp) + if test "$ac_cv_func_stricmp" = yes; then + AC_DEFINE(ACE_STRCASECMP_EQUIVALENT, [::stricmp], + [Define to function that is equivalent to strcasecmp()]) + else + AC_CHECK_FUNC(_stricmp) + if test "$ac_cv_func__stricmp" = yes; then + AC_DEFINE(ACE_STRCASECMP_EQUIVALENT, [::_stricmp]) + fi + fi +fi +]) + +# ACE_FUNC_STRNCASECMP +# + Defines ACE_LACKS_STRCASECMP to 1 if platform lacks strcasecmp() +# + Defines ACE_STRCASECMP_EQUIVALENT to identifier name if platform +# has a equivalent function that differs in name only. +# + Defines ACE_LACKS_STRNCASECMP_PROTOTYPE to 1 if platform lacks +# declaration for strncasecmp(). +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_STRNCASECMP], +[ACE_CHECK_LACKS_FUNCS(strncasecmp) +if test "$ac_cv_func_strncasecmp" = yes; then + AC_CHECK_DECL([strncasecmp], + [], + [AC_DEFINE([ACE_LACKS_STRNCASECMP_PROTOTYPE], 1, + [Define to 1 if platform lacks a declaration for strncasecmp()])], + [ +#if !defined(ACE_LACKS_STRINGS_H) +#include +#endif +#if !defined(ACE_LACKS_STRING_H) +#include +#endif + ]) +else + AC_CHECK_FUNC(strnicmp) + if test "$ac_cv_func_strnicmp" = yes; then + AC_DEFINE(ACE_STRNCASECMP_EQUIVALENT, [::strnicmp], + [Define to function that is equivalent to strncasecmp()]) + else + AC_CHECK_FUNC(_strnicmp) + if test "$ac_cv_func__strnicmp" = yes; then + AC_DEFINE(ACE_STRNCASECMP_EQUIVALENT, [::_strnicmp]) + fi + fi +fi +]) + +# ACE_FUNC_STRDUP +# + Defines ACE_LACKS_STRDUP to 1 if platform lacks strdup() +# + Defines ACE_STRDUP_EQUIVALENT to identifier name if platform +# has a equivalent function that differs in name only. +# + Defines ACE_HAS_NONCONST_STRDUP if argument is char*. (TODO) +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_STRDUP], +[ACE_CHECK_LACKS_FUNCS(strdup) +if test "$ac_cv_func_strdup" = no; then + AC_CHECK_FUNC(_strdup) + if test "$ac_cv_func__strdup" = yes; then + AC_DEFINE(ACE_STRDUP_EQUIVALENT, [::_strdup], + [Define to function that is equivalent to strdup()]) + fi +fi +]) + + +# ACE_FUNC_WCSCASECMP +# + Defines ACE_LACKS_WCSCASECMP to 1 if platform lacks strcasecmp() +# + Defines ACE_WCSCASECMP_EQUIVALENT to identifier name if platform +# has a equivalent function that differs in name only. +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_WCSCASECMP], +[ACE_CHECK_LACKS_FUNCS(wcscasecmp) +if test "$ac_cv_func_wcscasecmp" = no; then + AC_CHECK_FUNC(wcsicmp) + if test "$ac_cv_func_wcsicmp" = yes; then + AC_DEFINE(ACE_WCSCASECMP_EQUIVALENT, [::wcsicmp], + [Define to function that is equivalent to wcscasecmp()]) + else + AC_CHECK_FUNC(_wcsicmp) + if test "$ac_cv_func__wcsicmp" = yes; then + AC_DEFINE(ACE_WCSCASECMP_EQUIVALENT, [::_wcsicmp]) + fi + fi +fi +]) + +# ACE_FUNC_WCSNCASECMP +# + Defines ACE_LACKS_WCSNCASECMP to 1 if platform lacks strcasecmp() +# + Defines ACE_WCSNCASECMP_EQUIVALENT to identifier name if platform +# has a equivalent function that differs in name only. +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_WCSNCASECMP], +[ACE_CHECK_LACKS_FUNCS(wcsncasecmp) +if test "$ac_cv_func_wcsncasecmp" = no; then + AC_CHECK_FUNC(wcsnicmp) + if test "$ac_cv_func_wcsnicmp" = yes; then + AC_DEFINE(ACE_WCSNCASECMP_EQUIVALENT, [::wcsnicmp], + [Define to function that is equivalent to wcsncasecmp()]) + else + AC_CHECK_FUNC(_wcsnicmp) + if test "$ac_cv_func__wcsnicmp" = yes; then + AC_DEFINE(ACE_WCSNCASECMP_EQUIVALENT, [::_wcsnicmp]) + fi + fi +fi +]) + +# ACE_FUNC_WCSDUP +# + Defines ACE_LACKS_WCSDUP to 1 if platform lacks wcsdup() +# + Defines ACE_WCSDUP_EQUIVALENT to identifier name if platform +# has a equivalent function that differs in name only. +# + Defines ACE_HAS_NONCONST_WCSDUP if argument is char*. (TODO) +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_WCSDUP], +[ACE_CHECK_LACKS_FUNCS(wcsdup) +if test "$ac_cv_func_wcsdup" = no; then + AC_CHECK_FUNC(_wcsdup) + if test "$ac_cv_func__wcsdup" = yes; then + AC_DEFINE(ACE_WCSDUP_EQUIVALENT, [::_wcsdup], + [Define to function that is equivalent to wcsdup()]) + fi +fi +]) diff --git a/dep/ACE_wrappers/m4/ace_functions.m4 b/dep/ACE_wrappers/m4/ace_functions.m4 new file mode 100644 index 000000000..97f70eab0 --- /dev/null +++ b/dep/ACE_wrappers/m4/ace_functions.m4 @@ -0,0 +1,27 @@ +# ACE_CHECK_HAS_FUNCS(FUNCTION..., [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_HAS_FUNCS], +[AC_FOREACH([ACE_Func], [$1], + [AH_TEMPLATE(AS_TR_CPP(ACE_HAS_[]ACE_Func), + [Define to 1 if platform has ]ACE_Func[().])])dnl +for ace_func in $1 +do +AC_CHECK_FUNC($ace_func, + [AC_DEFINE_UNQUOTED([AS_TR_CPP([ACE_HAS_$ace_func])]) $2], + [$3])dnl +done +]) + +# ACE_CHECK_LACKS_FUNCS(FUNCTION..., [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +#----------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_LACKS_FUNCS], +[AC_FOREACH([ACE_Func], [$1], + [AH_TEMPLATE(AS_TR_CPP(ACE_LACKS_[]ACE_Func), + [Define to 1 if platform lacks ]ACE_Func[().])])dnl +for ace_func in $1 +do +AC_CHECK_FUNC($ace_func, + [$2], + [AC_DEFINE_UNQUOTED([AS_TR_CPP([ACE_LACKS_$ace_func])]) $3])dnl +done +]) diff --git a/dep/ACE_wrappers/m4/ace_headers.m4 b/dep/ACE_wrappers/m4/ace_headers.m4 new file mode 100644 index 000000000..e873fc640 --- /dev/null +++ b/dep/ACE_wrappers/m4/ace_headers.m4 @@ -0,0 +1,35 @@ +# ACE_CHECK_HAS_HEADERS(HEADER-FILE..., +# [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND], +# [INCLUDES = 'default-includes']) +#----------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_HAS_HEADERS], +[AC_FOREACH([ACE_Header], [$1], + [AH_TEMPLATE(AS_TR_CPP(ACE_HAS_[]ACE_Header), + [Define to 1 if platform has the <]ACE_Header[> header file.])])dnl +for ace_header in $1 +do +AC_CHECK_HEADER($ace_header, + [AC_DEFINE_UNQUOTED([AS_TR_CPP([ACE_HAS_$ace_header])]) $2], + [$3], + [$4])dnl +done +]) + +# ACE_CHECK_LACKS_HEADERS(HEADER-FILE..., +# [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND], +# [INCLUDES = 'default-includes']) +#----------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_LACKS_HEADERS], +[AC_FOREACH([ACE_Header], [$1], + [AH_TEMPLATE(AS_TR_CPP(ACE_LACKS_[]ACE_Header), + [Define to 1 if platform lacks the <]ACE_Header[> header file.])])dnl +for ace_header in $1 +do +AC_CHECK_HEADER($ace_header, + [$2], + [AC_DEFINE_UNQUOTED([AS_TR_CPP([ACE_LACKS_$ace_header])]) $3], + [$4])dnl +done +]) diff --git a/dep/ACE_wrappers/m4/acinclude.m4 b/dep/ACE_wrappers/m4/acinclude.m4 new file mode 100644 index 000000000..de18884ce --- /dev/null +++ b/dep/ACE_wrappers/m4/acinclude.m4 @@ -0,0 +1,602 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: acinclude.m4 80826 2008-03-04 14:51:23Z wotte $ +dnl +dnl ACE M4 include file which contains general M4 macros +dnl to be used by the ACE configure script. +dnl +dnl The macros in this file were designed for ACE but should be +dnl general enough for general use. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2000, 2002 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +dnl miscellaneous macros + +dnl Prevent the configure script continuing any further if a CVS control +dnl directory is found. The idea is to prevent files generated during +dnl configuration and build from be checked in to the CVS repository that +dnl the sources are checked into. This should only be an issue for +dnl maintainers, not end-users. Maintainers should configure and build in +dnl a directory that doesn't contain any CVS controlled sources and files, +dnl i.e. that doesn't contain a CVS directory. +dnl +dnl Usage: ACE_CHECK_FOR_CVS_DIR +AC_DEFUN([ACE_CHECK_FOR_CVS_DIR], +[ + if test -d CVS; then + AC_MSG_ERROR( + [ + This error is meant for maintainers: + + Please configure and build in a non-CVS controlled directory. + Doing so will prevent accidentally committing automatically + generated files into the CVS repository and help ensure that + the generated files and build scheme are correct. + + For example, try the following from the top-level source + directory: + + mkdir objdir + cd objdir + ../configure + make + + This will create a build space in the directory `objdir' and + start a build in that directory. + ]) + fi +]) + + +dnl Prevent the configure script from continuing any further if +dnl configuration is being performed in the top-level directory. The +dnl idea is to prevent files generated during configuration and build +dnl from overwriting the stock files of the same name. +dnl Usage: ACE_CHECK_TOP_SRCDIR +AC_DEFUN([ACE_CHECK_TOP_SRCDIR], +[ + if test "$srcdir" = "." && test "$USE_MAINTAINER_MODE" != "yes"; then + AC_MSG_ERROR( + [ + Please configure and build in a directory other than the + top-level source directory. Doing so will prevent files + distributed with the package from being overwritten. This is + currently necessary since autoconf support is still + experimental. If you encounter problems please use the stock + build procedure. + + For example, try the following from the top-level source + directory: + + mkdir objdir + cd objdir + ../configure + make + + This will create a build space in the directory `objdir' and + start a build in that directory. + ]) + fi +]) + +dnl Add compiler flags to the CXXFLAGS and CFLAGS variables when doing an +dnl AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) (not ACE_TRY_COMPILE). +dnl Use this macro when adding include directories to the compiler flags, +dnl for example. +dnl Usage: ACE_TRY_COMPILE(COMPILER-FLAGS, INCLUDES, FUNCTION-BODY, +dnl [ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]) +AC_DEFUN([ACE_TRY_COMPILE], +[ + AC_LANG([C++]) + AC_REQUIRE([AC_LANG]) + + ace_pre_try_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $1" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])],[$4],[$5]) + + dnl Restore the C++ flags + CXXFLAGS="$ace_pre_try_CXXFLAGS" + +]) + +dnl Create a temporary empty file and remove it after commands are done using +dnl it. The directory in which the temporary file will be created in must +dnl exist. Files will be created under the source directory, not the build +dnl directory. +dnl Use this macro when you need a particular file available but want it to be +dnl empty. This is useful to prevent conflicts with autoconf's confdefs.h +dnl header when doing an AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]). +dnl Usage: ACE_USE_TEMP_FILE(TEMP-FILE-TO-CREATE, COMMANDS-THAT-WILL-USE-IT) +AC_DEFUN([ACE_USE_TEMP_FILE], +[ + test -d $1 && AC_MSG_ERROR([cannot create file: $acetmp is a directory]) + + dnl Make sure contents of existing file don't override the contents + dnl of the temporary one. + test -f ${srcdir}/$1 && mv ${srcdir}/$1 ${srcdir}/$1.conf + + if test ${srcdir} != "."; then + dnl Create all of the sub-directories. + AS_MKDIR_P([`AS_DIRNAME(["$1"])`]) + fi + + touch $1 + + $2 + + if test -f ${srcdir}/$1.conf; then + mv ${srcdir}/$1.conf ${srcdir}/$1 + fi + + if test ${srcdir} != "."; then + dnl Remove the file. Any sub-directories will not be removed + dnl since we have no way to tell if they existed prior to the + dnl creation of this file. + rm $1 + fi +]) + +dnl Run given test(s) with warnings converted to errors +dnl Usage: ACE_CONVERT_WARNINGS_TO_ERRORS(TEST-BLOCK) +AC_DEFUN([ACE_CONVERT_WARNINGS_TO_ERRORS], +[ +dnl $WERROR is set in the ACE_SET_COMPILER_FLAGS macro. + AC_REQUIRE([ACE_SET_COMPILER_FLAGS]) + +dnl Some tests may pass because the compiler issues warnings +dnl instead of errors when errors should occur. This macro converts +dnl warnings to errors when executing the action/test passed to this +dnl macro so that action/test fails when it is supposed to fail; at +dnl least that is the idea. + + ace_pre_warning_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $WERROR" + + $1 + + CXXFLAGS="$ace_pre_warning_CXXFLAGS" +]) + +dnl Wrapper around AC_CACHE_VAL used to ensure "ACTION-IF" commands are run +dnl even if results have been previously cached. +dnl Usage: ACE_CACHE_CHECK(MESSAGE, CACHE-ID, COMMANDS-TO-SET-CACHE-VAL, +dnl ACTION-IF-CACHE-ID-IS-YES, +dnl ACTION-IF-CACHE-ID-IS-NO) +dnl The COMMANDS-TO-SET-CACHE-VAL should set the CACHE-ID to yes or "no," +dnl otherwise the "ACTION-IF*" commands may not run. The +dnl COMMANDS-TO-SET-CACHE-VAL should only set the CACHE value. For example, +dnl no AC_DEFINES should be placed in the COMMANDS-TO-SET-CACHE-VAL. +AC_DEFUN([ACE_CACHE_CHECK], +[ + AC_MSG_CHECKING([$1]) + AC_CACHE_VAL([$2], [$3]) + AC_MSG_RESULT([[$]$2]) + if test "[$]$2" != no; then + ace_just_a_place_holder=fixme +ifelse([$4], , :, [$4]) + else + ace_just_a_place_holder=fixme +ifelse([$5], , , [$5 +]) + fi +]) + +dnl checks for programs + +dnl checks for libraries + +dnl checks for header files + +dnl checks for typedefs + +dnl Check for specific typedef in given header file +dnl Usage: ACE_CHECK_TYPE(TYPEDEF, INCLUDE, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl This macro can only check for one typedef in one header file at a time!! +AC_DEFUN([ACE_CHECK_TYPE], +[ +dnl AC_REQUIRE([AC_PROG_CXX]) +dnl AC_REQUIRE([AC_PROG_CXXCPP]) +dnl AC_LANG([C++]) +dnl AC_REQUIRE([AC_LANG]) + + ACE_CACHE_CHECK([for $1 in $2], [ace_cv_type_$1], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <$2> + ]], [[ + $1 ace_$1; + ]])],[ + ace_cv_type_$1=yes + ],[ + ace_cv_type_$1=no + ]) + ],[$3],[$4]) +]) + + +dnl checks for structures + +dnl Check for specific struct in given header file +dnl Usage: ACE_CHECK_STRUCT(STRUCTURE, INCLUDE, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl This macro can only check for one struct in one header file at a time!! +AC_DEFUN([ACE_CHECK_STRUCT], +[ +dnl AC_REQUIRE([AC_PROG_CXX]) +dnl AC_REQUIRE([AC_PROG_CXXCPP]) +dnl AC_LANG([C++]) +dnl AC_REQUIRE([AC_LANG]) + +dnl Do the transliteration at runtime so arg 1 can be a shell variable. +dnl ac_safe=`echo "$1" | sed 'y%./+-%__p_%'` + + ACE_CACHE_CHECK([for struct $1 in $2], [ace_cv_struct_$1], + [ + ACE_TRY_COMPILE_STRUCT([$1], [$2], + [ + ace_cv_struct_$1=yes + ], + [ + ace_cv_struct_$1=no + ]) + ], $3, $4) +]) + +dnl Check for specific struct in given header file by compiling a test +dnl program. This macro is used by ACE_CHECK_STRUCT. +dnl Usage: ACE_TRY_COMPILE_STRUCT(STRUCTURE, INCLUDE, +dnl [ACTION-IF-SUCCESSFUL[, ACTION-IF-NOT-SUCCESSFUL]]) +dnl This macro can only check for one struct in one header file at a time!! +AC_DEFUN([ACE_TRY_COMPILE_STRUCT], +[ +dnl AC_REQUIRE([AC_PROG_CXX]) +dnl AC_REQUIRE([AC_PROG_CXXCPP]) +dnl AC_LANG([C++]) +dnl AC_REQUIRE([AC_LANG]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <$2> + ]], [[ + struct $1 ace_$1; + ]])],[ + $3 + ],[ +dnl Some compilers don't like the "struct" but we need the struct for +dnl some platforms to resolve ambiguities between functions and +dnl structures with with the same name. So, we try the same test but +dnl without "struct" if the above test with "struct" fails. If both +dnl tests fail, then we can be reasonably sure that we don't have the +dnl structure we are testing for. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include <$2> + ]], + [[ + $1 ace_$1; + ]])], + [ + $3 + ], + [ + $4 + ]) + ]) +]) + +dnl checks for variables + +dnl checks for compiler characteristics + +dnl checks for library functions + +dnl Check for function using prototype in header +dnl This macro is used if a function is called a different name in a given +dnl library than what is in the header file but the difference is made +dnl transparent to the user since the header may provide a macro to make +dnl things "transparent." If the given header does not exist then this +dnl macro acts just like the standard AC_CHECK_FUNC macro. +dnl Usage: ACE_CHECK_FUNC(FUNCTION, HEADER, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([ACE_CHECK_FUNC], +[ +dnl AC_REQUIRE([AC_PROG_CXX]) +dnl AC_REQUIRE([AC_PROG_CXXCPP]) +dnl AC_LANG([C++]) +dnl AC_REQUIRE([AC_LANG]) + AC_REQUIRE([AC_PROG_AWK]) + + AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ +#include <$2> + ]])],[ace_header_exists=yes],[ace_header_exists=no]) + + cat > conftest.$ac_ext < + ACE_REAL_FUNCTION $1 + +EOF + + if test "$ace_header_exists" = yes; then + if test -z "$AWK"; then + AC_MSG_WARN([No awk program found. Real $1 function may not be found.]) + fi + + if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "ACE_REAL_FUNCTION" | + (eval "$AWK '{print \[$]2}' > conftest.awk 2>&1"); then + rm -f conftest.$ac_ext + ace_real_function=`cat conftest.awk` + rm -f conftest.awk + fi + + if test $1 != "$ace_real_function"; then + AC_MSG_CHECKING([for real $1 from $2]) + AC_MSG_RESULT([$ace_real_function]) + fi + else + ace_real_function=$1 + fi dnl test "$ace_header_not_exist" != yes + + AC_CHECK_FUNC([$ace_real_function],[$3],[$4]) +]) + +dnl Check for function in library using prototype in header +dnl This macro is used if a function is called a different name in a given +dnl library than what is in the header file but the difference is made +dnl transparent to the user since the header may provide a macro to make +dnl things "transparent." If the given header does not exist then this +dnl macro acts just like the standard AC_CHECK_LIB macro. +dnl Usage: ACE_CHECK_LIB(LIBRARY, FUNCTION, HEADER, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([ACE_CHECK_LIB], +[ +dnl AC_REQUIRE([AC_PROG_CXX]) +dnl AC_REQUIRE([AC_PROG_CXXCPP]) +dnl AC_LANG([C++]) +dnl AC_REQUIRE([AC_LANG]) + AC_REQUIRE([AC_PROG_AWK]) + + AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ +#include <$3> + ]])],[ace_header_exists=yes],[ace_header_exists=no]) + + cat > conftest.$ac_ext < + ACE_REAL_FUNCTION $2 + +EOF + + if test "$ace_header_exists" = yes; then + if test -z "$AWK"; then + AC_MSG_WARN([No awk program found. "Real" function in library may not be found.]) + fi + + if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "ACE_REAL_FUNCTION" | + eval "$AWK '{print \[$]2}'" > conftest.awk 2>&1; then + rm -f conftest.$ac_ext + ace_real_function=`cat conftest.awk` + rm -f conftest.awk + fi + + if test $2 != "$ace_real_function"; then + AC_MSG_CHECKING([for real $2 from $3]) + AC_MSG_RESULT([$ace_real_function]) + fi + else + ace_real_function=$2 + fi dnl test "$ace_header_not_exist" != yes + + AC_CHECK_LIB([$1], [$ace_real_function], [$4], [$5]) +]) + + +dnl Check if getrlimit() takes an enum as 1st argument +dnl Usage: ACE_CHECK_SETRLIMIT_ENUM +AC_DEFUN([ACE_CHECK_SETRLIMIT_ENUM], +[ +if test "$ac_cv_func_setrlimit" = yes; then + AC_MSG_CHECKING([if setrlimit() takes an enum as 1st argument]) + AC_EGREP_HEADER([setrlimit.*\(.*[^,]*enum], sys/resource.h, + [ + cat > conftest.$ac_ext < +EOF + +dnl Here we attempt to determine the type of the first argument of +dnl getrusage from its prototype. It should either be an int or an +dnl enum. If it is an enum, determine the enum type. + ace_setrlimit_enum=`eval "$ac_cpp conftest.$ac_ext" | \ + $EGREP '[[ ]]+setrlimit.*\(.*[[^,]]*enum' | \ + sed -e 's/^.*setrlimit.*(.*enum//' -e 's/[[^ ]]*,.*$//'` + + ace_setrlimit_enum="enum $ace_setrlimit_enum" + + AC_MSG_RESULT([$ace_setrlimit_enum]) + +if test -n "$ace_setrlimit_enum"; then + AC_DEFINE_UNQUOTED([ACE_HAS_RLIMIT_RESOURCE_ENUM], [$ace_setrlimit_enum]) +fi + + rm -rf conftest* + +dnl Do not remove this parenthesis --> ) +dnl It's only purpose to keep Emacs from getting confused about mismatched +dnl parentheses. + ], + [ + AC_MSG_RESULT([no]) + ]) + +fi dnl test "$ac_cv_func_setrlimit" = yes +]) + +dnl Check if getrusage() takes an enum as 1st argument +dnl Usage: ACE_CHECK_GETRUSAGE_ENUM +AC_DEFUN([ACE_CHECK_GETRUSAGE_ENUM], +[ +if test "$ac_cv_func_getrusage" = yes; then + AC_MSG_CHECKING([if getrusage() takes an enum as 1st argument]) + AC_EGREP_HEADER([getrusage.*\(.*[^,]*enum], [sys/resource.h], + [ + cat > conftest.$ac_ext < +EOF + +dnl Here we attempt to determine the type of the first argument of +dnl getrusage from its prototype. It should either be an int or an +dnl enum. If it is an enum, determine the enum type. + ace_rusage_who=`eval "$ac_cpp conftest.$ac_ext" | \ + $EGREP '[[ ]]+getrusage.*\(.*[[^,]]*enum' | \ + sed -e 's/^.*getrusage.*(.*enum//' -e 's/[[^ ]]*,.*$//'` + + ace_rusage_who="enum $ace_rusage_who" + + AC_MSG_RESULT([$ace_rusage_who]) + +if test -n "$ace_rusage_who"; then + AC_DEFINE_UNQUOTED([ACE_HAS_RUSAGE_WHO_ENUM], [$ace_rusage_who]) +fi + + rm -rf conftest* + +dnl Do not remove this parenthesis --> ) +dnl It's only purpose to keep Emacs from getting confused about mismatched +dnl parentheses. + ], + [ + AC_MSG_RESULT([no]) + ]) + +fi dnl test "$ac_cv_func_getrusage" = yes +]) + + +dnl Check for 64 bit llseek() or lseek64() +dnl Usage: ACE_CHECK_LSEEK64 +AC_DEFUN([ACE_CHECK_LSEEK64], +[ + AC_CHECK_FUNC([lseek64], + [ + AC_DEFINE([ACE_HAS_LSEEK64]) + + dnl Check for 64 bit offset type in the lseek64() prototype, if it + dnl exists. + dnl ACE_CHECK_OFF64_T([lseek64]) + + dnl Check if _LARGEFILE64_SOURCE macro is needed to make the + dnl lseek64() prototype visible, or if the prototype itself is missing. + ACE_CACHE_CHECK([for lseek64 prototype], + [ace_cv_lib_has_lseek64_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_largefile64="-U_LARGEFILE64_SOURCE" + CPPFLAGS="$CPPFLAGS $ace_no_largefile64" + AC_EGREP_HEADER([[^_]+lseek64], [unistd.h], + [ + ace_cv_lib_has_lseek64_prototype=yes + ], + [ + ace_cv_lib_has_lseek64_prototype=no + ]) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],[],[AC_DEFINE([ACE_LACKS_LSEEK64_PROTOTYPE])]) + ], + [ + AC_CHECK_FUNC([llseek], + [ + AC_DEFINE([ACE_HAS_LLSEEK]) + dnl Check if _LARGEFILE64_SOURCE macro is needed to make the + dnl llseek() prototype visible, or if the prototype itself is + dnl missing. + + dnl Check for 64 bit offset type in the llseek() prototype, if + dnl it exists. + dnl ACE_CHECK_OFF64_T([llseek]) + + ACE_CACHE_CHECK([for llseek prototype], + [ace_cv_lib_has_llseek_prototype], + [ + ace_save_CPPFLAGS="$CPPFLAGS" + ace_no_largefile64="-U_LARGEFILE64_SOURCE" + CPPFLAGS="$CPPFLAGS $ace_no_largefile64" + AC_EGREP_HEADER([[^_]+llseek],[unistd.h], + [ + ace_cv_lib_has_llseek_prototype=no + ], + [ + ace_cv_lib_has_llseek_prototype=yes + ],) + dnl Reset the compiler flags + CPPFLAGS="$ace_save_CPPFLAGS" + ],[],[AC_DEFINE([ACE_LACKS_LLSEEK_PROTOTYPE])]) + + + ],) + ]) +]) + +dnl Check what the 64 bit offset type is by checking what the offset +dnl argument for llseek()/lseek64() is. +dnl Usage: ACE_CHECK_LOFF_64(LSEEK64-FUNC) +AC_DEFUN([ACE_CHECK_OFF64_T], +[ + AC_MSG_CHECKING([for 64 bit offset type]) + AC_EGREP_HEADER([[ ]+$1.*\(.*],[unistd.h], + [ + cat > conftest.$ac_ext < /* needed for lseek64()/llseek() prototype */ +#endif +EOF + +dnl Here we attempt to determine the type of the second argument of +dnl lseek64()/llseek() from its prototype. + ace_off64_t=`eval "$ac_cpp conftest.$ac_ext" | \ + $EGREP '[[ ]]+lseek64.*\(.*' | \ + sed -e 's/^.*(.*,[[ ]]*\(.*\) .*,.*$/\1/'` + + +if test -n "$ace_off64_t"; then + AC_MSG_RESULT([$ace_off64_t]) + AC_DEFINE_UNQUOTED([ACE_LOFF_T_TYPEDEF], [$ace_off64_t]) +fi + + rm -rf conftest* + +dnl Do not remove this parenthesis --> ) +dnl It's only purpose is to keep Emacs from getting confused about +dnl mismatched parentheses. + ], + [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl checks for structures + +dnl checks for system services diff --git a/dep/ACE_wrappers/m4/aio.m4 b/dep/ACE_wrappers/m4/aio.m4 new file mode 100644 index 000000000..b38a8b981 --- /dev/null +++ b/dep/ACE_wrappers/m4/aio.m4 @@ -0,0 +1,633 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: aio.m4 80826 2008-03-04 14:51:23Z wotte $ +dnl +dnl aio.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl that determine availablility of POSIX asynchronous IO +dnl support. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2002 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +dnl Asynchronous IO check +dnl Use this macro to determine if asynchronous IO is working on a +dnl given platform. +dnl Usage: ACE_CHECK_ASYNCH_IO +AC_DEFUN([ACE_CHECK_ASYNCH_IO], +[ + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PROG_CXXCPP]) + AC_LANG([C++]) + AC_REQUIRE([AC_LANG]) + AC_REQUIRE([ACE_CHECK_THREADS]) + + dnl In case a library with the asynchronous libraries is found but + dnl the asynchronous IO support is not functional then save a copy + dnl of the list of libraries before the asynch IO function library + dnl is added to the list so that we can revert the list to its + dnl pre-asynch-IO check state. + ace_save_LIBS="$LIBS" + + dnl Asynchronous IO library check + dnl Some platforms, such as Solaris puts aio_read in -lposix4, for example. + dnl In some cases, the thread library must be linked to in addition to the + dnl real-time support library. As such, make sure these checks are done + dnl after the thread library checks. + AC_SEARCH_LIBS([aio_read], [aio rt posix4], + [ace_has_aio_funcs=yes], [ace_has_aio_funcs=no]) + +if test "$ace_has_aio_funcs" = yes; then + ACE_CACHE_CHECK([for working asynchronous IO], + [ace_cv_feature_aio_calls], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifndef ACE_LACKS_UNISTD_H +#include +#endif +#include +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include +#include +#include +#include +#include + +#include + +class Test_Aio +{ +public: + Test_Aio (void); + // Default constructor. + + int init (void); + // Initting the output file and the buffer. + + int do_aio (void); + // Doing the testing stuff. + + ~Test_Aio (void); + // Destructor. +private: + int out_fd_; + // Output file descriptor. + + struct aiocb *aiocb_write_; + // For writing to the file. + + struct aiocb *aiocb_read_; + // Reading stuff from the file. + + char *buffer_write_; + // The buffer to be written to the out_fd. + + char *buffer_read_; + // The buffer to be read back from the file. +}; + +Test_Aio::Test_Aio (void) + : out_fd_ (0), + aiocb_write_ (new struct aiocb), + aiocb_read_ (new struct aiocb), + buffer_write_ (0), + buffer_read_ (0) +{ +} + +Test_Aio::~Test_Aio (void) +{ + if (close (this->out_fd_) != 0) + perror ("close"); + + delete aiocb_write_; + delete aiocb_read_; + delete [] buffer_write_; + delete [] buffer_read_; +} + +// Init the output file and init the buffer. +int +Test_Aio::init (void) +{ + // Open the output file. + this->out_fd_ = open ("test_aio.log", O_RDWR | O_CREAT | O_TRUNC, 0600); + if (this->out_fd_ == -1) + { + perror ("open"); + return -1; + } + + unlink ("test_aio.log"); // Unlink now so we don't have to do so later. + + const char message[] = "Welcome to the world of AIO... AIO Rules !!!"; + + // Init the buffers. + this->buffer_write_ = new char [sizeof (message) + 1]; + strcpy (this->buffer_write_, message); + // cout << "The buffer : " << this->buffer_write_ << endl; + this->buffer_read_ = new char [sizeof (message) + 1]; + + return 0; +} + +// Set the necessary things for the AIO stuff. +// Write the buffer asynchly.hmm Disable signals. +// Go on aio_suspend. Wait for completion. +// Print out the result. +int +Test_Aio::do_aio (void) +{ + // = Write to the file. + + // Setup AIOCB. + this->aiocb_write_->aio_fildes = this->out_fd_; + this->aiocb_write_->aio_offset = 0; + this->aiocb_write_->aio_buf = this->buffer_write_; + this->aiocb_write_->aio_nbytes = strlen (this->buffer_write_); + this->aiocb_write_->aio_reqprio = 0; + this->aiocb_write_->aio_sigevent.sigev_notify = SIGEV_NONE; + //this->this->aiocb_.aio_sigevent.sigev_signo = SIGRTMAX; + this->aiocb_write_->aio_sigevent.sigev_value.sival_ptr = + (void *) this->aiocb_write_; + + // Fire off the aio write. + if (aio_write (this->aiocb_write_) != 0) + { + perror ("aio_write"); + return -1; + } + + // = Read from that file. + + // Setup AIOCB. + this->aiocb_read_->aio_fildes = this->out_fd_; + this->aiocb_read_->aio_offset = 0; + this->aiocb_read_->aio_buf = this->buffer_read_; + this->aiocb_read_->aio_nbytes = strlen (this->buffer_write_); + this->aiocb_read_->aio_reqprio = 0; + this->aiocb_read_->aio_sigevent.sigev_notify = SIGEV_NONE; + //this->this->aiocb_.aio_sigevent.sigev_signo = SIGRTMAX; + this->aiocb_read_->aio_sigevent.sigev_value.sival_ptr = + (void *) this->aiocb_read_; + + // Fire off the aio write. If it doesnt get queued, carry on to get + // the completion for the first one. + if (aio_read (this->aiocb_read_) < 0) + perror ("aio_read"); + + // Wait for the completion on aio_suspend. + struct aiocb *list_aiocb[2]; + list_aiocb [0] = this->aiocb_write_; + list_aiocb [1] = this->aiocb_read_; + + // Do suspend till all the aiocbs in the list are done. + int done = 0; + while (!done) + { + if (aio_suspend (list_aiocb, 2, 0) != 0) + { + perror ("aio_suspend"); + return -1; + } + + // Analyze return and error values. + if (list_aiocb [0] != 0 && aio_error (list_aiocb [0]) != EINPROGRESS) + { + if (aio_return (list_aiocb [0]) == -1) + { + perror ("aio_return"); + return -1; + } + else + { + // Successful. Store the pointer somewhere and make the + // entry NULL in the list. + // @@ no need ----> this->aiocb_write_ = list_aiocb [0]; + list_aiocb [0] = 0; + } + } +// else +// cout << "AIO in progress" << endl; + + if (list_aiocb [1] != 0 && aio_error (list_aiocb [1]) != EINPROGRESS) + { + if (aio_return (list_aiocb [1]) == -1) + { + perror ("aio_return"); + return -1; + } + else + { + // Successful. Store the pointer somewhere and make the + // entry NULL in the list. + // @@ no need ----> this->aiocb_read_ = list_aiocb [1]; + list_aiocb [1] = 0; + } + } +// else +// cout << "AIO in progress" << endl; + + // Is it done? + if ((list_aiocb [0] == 0) && (list_aiocb [1] == 0)) + done = 1; + } + + //cout << "Both the AIO operations done." << endl; + //cout << "The buffer is :" << this->buffer_read_ << endl; + + return 0; +} + +int +main () +{ + Test_Aio test_aio; + + if (test_aio.init () != 0) + { + //printf ("AIOCB test failed:\n" + // "ACE_POSIX_AIOCB_PROACTOR may not work in this platform\n"); + return -1; + } + + if (test_aio.do_aio () != 0) + { + //printf ("AIOCB test failed:\n" + // "ACE_POSIX_AIOCB_PROACTOR may not work in this platform\n"); + return -1; + } + //printf ("AIOCB test successful:\n" + // "ACE_POSIX_AIOCB_PROACTOR should work in this platform\n"); + return 0; +} + ]])],[ + ace_cv_feature_aio_calls=yes + ],[ + ace_cv_feature_aio_calls=no + ],[ + dnl Asynchronous IO test for cross-compiled platforms + dnl This test is weaker than the above run-time tests but it will + dnl have to do. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#include + ]], + [[ + aiocb* aiocb_ptr (void); + ]])], + [ + ace_cv_feature_aio_calls=yes + ], + [ + ace_cv_feature_aio_calls=no + ]) + ]) + ],[AC_DEFINE([ACE_HAS_AIO_CALLS])],[LIBS="$ace_save_LIBS"]) +fi dnl test "$ace_has_aio_funcs" = yes + + +if test "$ace_cv_feature_aio_calls" = yes; then + ACE_CACHE_CHECK([for working POSIX realtime signals], + [ace_cv_feature_posix_rt_sigs], + [ + dnl Create a file for the test program to read. + cat > test_aiosig.txt < +} +#ifndef ACE_LACKS_UNISTD_H +#include +#endif +#include +#ifndef ACE_LACKS_SYS_TYPES_H +# include +#endif +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef __cplusplus +extern "C" +#endif +void null_handler (int /* signal_number */, + siginfo_t * /* info */, + void * /* context */); + +int file_handle = -1; +char mb1[BUFSIZ + 1]; +char mb2[BUFSIZ + 1]; +aiocb aiocb1, aiocb2; +sigset_t completion_signal; + +// Function prototypes. +int setup_signal_delivery (void); +int issue_aio_calls (void); +int query_aio_completions (void); +int test_aio_calls (void); +int setup_signal_handler (void); +int setup_signal_handler (int signal_number); + +int +setup_signal_delivery (void) +{ + // Make the sigset_t consisting of the completion signal. + if (sigemptyset (&completion_signal) == -1) + { + perror ("Error:Couldn't init the RT completion signal set\n"); + return -1; + } + + if (sigaddset (&completion_signal, SIGRTMIN) == -1) + { + perror ("Error:Couldn't init the RT completion signal set\n"); + return -1; + } + + // Mask them. + if (pthread_sigmask (SIG_BLOCK, &completion_signal, 0) == -1) + { + perror ("Error:Couldn't make the RT completion signals\n"); + return -1; + } + + return setup_signal_handler (SIGRTMIN); +} + +int +issue_aio_calls (void) +{ + // Setup AIOCB. + aiocb1.aio_fildes = file_handle; + aiocb1.aio_offset = 0; + aiocb1.aio_buf = mb1; + aiocb1.aio_nbytes = BUFSIZ; + aiocb1.aio_reqprio = 0; + aiocb1.aio_sigevent.sigev_notify = SIGEV_SIGNAL; + aiocb1.aio_sigevent.sigev_signo = SIGRTMIN; + aiocb1.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb1; + + // Fire off the aio write. + if (aio_read (&aiocb1) == -1) + { + // Queueing failed. + perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n"); + return -1; + } + + // Setup AIOCB. + aiocb2.aio_fildes = file_handle; + aiocb2.aio_offset = BUFSIZ + 1; + aiocb2.aio_buf = mb2; + aiocb2.aio_nbytes = BUFSIZ; + aiocb2.aio_reqprio = 0; + aiocb2.aio_sigevent.sigev_notify = SIGEV_SIGNAL; + aiocb2.aio_sigevent.sigev_signo = SIGRTMIN; + aiocb2.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb2; + + // Fire off the aio write. + if (aio_read (&aiocb2) == -1) + { + // Queueing failed. + perror ("Error:Asynch_Read_Stream: aio_read queueing failed\n"); + return -1; + } + return 0; +} + +int +query_aio_completions (void) +{ + int result = 0; + size_t number_of_completions = 0; + for (number_of_completions = 0; + number_of_completions < 2; + number_of_completions++) + { + // Wait for amount of time. + // @@ Assigning to tv_sec. + timespec timeout; + timeout.tv_sec = 5; + timeout.tv_nsec = 0; + + // To get back the signal info. + siginfo_t sig_info; + + // Await the RT completion signal. + int sig_return = sigtimedwait (&completion_signal, + &sig_info, + &timeout); + + // Error case. + // If failure is coz of timeout, then return *0* but set + // errno appropriately. This is what the WinNT proactor + // does. + if (sig_return == -1) + { + perror ("Error:Error waiting for RT completion signals\n"); + return -1; + } + + // RT completion signals returned. + if (sig_return != SIGRTMIN) + { + //printf ("Unexpected signal (%d) has been received while waiting for RT Completion Signals\n", + // sig_return); + return -1; + } + + // @@ Debugging. + //printf ("Sig number found in the sig_info block : %d\n", + // sig_info.si_signo); + + // Is the signo returned consistent? + if (sig_info.si_signo != sig_return) + { + //printf ("Inconsistent signal number (%d) in the signal info block\n", + // sig_info.si_signo); + return -1; + } + + // @@ Debugging. + //printf ("Signal code for this signal delivery : %d\n", + // sig_info.si_code); + + // Is the signal code an aio completion one? + if ((sig_info.si_code != SI_ASYNCIO) && + (sig_info.si_code != SI_QUEUE)) + { + //printf ("Unexpected signal code (%d) returned on completion querying\n", + // sig_info.si_code); + return -1; + } + + // Retrive the aiocb. + aiocb* aiocb_ptr = (aiocb *) sig_info.si_value.sival_ptr; + + // Analyze error and return values. Return values are + // actually 's associated with the call + // corresponding to aiocb_ptr. + int error_code = aio_error (aiocb_ptr); + if (error_code == -1) + { + perror ("Error:Invalid control block was sent to for compleion querying\n"); + return -1; + } + + if (error_code != 0) + { + // Error occurred in the call. Return the errno + // corresponding to that call. + //printf ("Error:An AIO call has failed:Error code = %d\n", + // error_code); + return -1; + } + + // No error occured in the AIO operation. + int nbytes = aio_return (aiocb_ptr); + if (nbytes == -1) + { + perror ("Error:Invalid control block was sent to \n"); + return -1; + } + + //if (number_of_completions == 0) + // Print the buffer. + //printf ("Number of bytes transferred : %d\n The buffer : %s \n", + // nbytes, + // mb1); + //else + // Print the buffer. + //printf ("Number of bytes transferred : %d\n The buffer : %s \n", + // nbytes, + // mb2); + } + return 0; +} + +int +test_aio_calls (void) +{ + // Set up the input file. + // Open file (in SEQUENTIAL_SCAN mode) + file_handle = open ("test_aiosig.txt", O_RDONLY); + + if (file_handle == -1) + { + perror ("open"); + return -1; + } + + unlink ("test_aiosig.txt"); // Unlink now so we don't have to do so later. + + if (setup_signal_delivery () < 0) + return -1; + + if (issue_aio_calls () < 0) + return -1; + + if (query_aio_completions () < 0) + return -1; + + if (close (file_handle) != 0) + { + perror ("close"); + return -1; + } + + return 0; +} + +int +setup_signal_handler (int signal_number) +{ + // Setting up the handler(!) for these signals. + struct sigaction reaction; + sigemptyset (&reaction.sa_mask); // Nothing else to mask. + reaction.sa_flags = SA_SIGINFO; // Realtime flag. +#if defined (SA_SIGACTION) + // Lynx says, it is better to set this bit to be portable. + reaction.sa_flags &= SA_SIGACTION; +#endif /* SA_SIGACTION */ + reaction.sa_sigaction = null_handler; // Null handler. + int sigaction_return = sigaction (SIGRTMIN, + &reaction, + 0); + if (sigaction_return == -1) + { + perror ("Error:Proactor couldn't do sigaction for the RT SIGNAL"); + return -1; + } + + return 0; +} + +void +null_handler (int /* signal_number */, + siginfo_t * /* info */, + void * /* context */) +{ +} + +int +main () +{ + if (test_aio_calls () == 0) + { + // printf ("RT SIG test successful:\n" + // "ACE_POSIX_SIG_PROACTOR should work in this platform\n"); + return 0; + } + + //printf ("RT SIG test failed:\n" + // "ACE_POSIX_SIG_PROACTOR may not work in this platform\n"); + return -1; + +} + ]])], + [ + ace_cv_feature_posix_rt_sigs=yes + ], + [ + ace_cv_feature_posix_rt_sigs=no + ], + [ + dnl Don't bother doing anything for cross-compiling here + dnl since the basic aio run-time test will prevent this + dnl rt sig run-time test from ever running when cross-compiling. + dnl We just put something in here to prevent autoconf + dnl from complaining. + ace_just_a_place_holder=ignoreme + ]) + ],[AC_DEFINE([ACE_HAS_POSIX_REALTIME_SIGNALS])],[]) +fi dnl test "$ace_cv_feature_aio_calls" = yes + +]) diff --git a/dep/ACE_wrappers/m4/compiler.m4 b/dep/ACE_wrappers/m4/compiler.m4 new file mode 100644 index 000000000..549d29cc9 --- /dev/null +++ b/dep/ACE_wrappers/m4/compiler.m4 @@ -0,0 +1,426 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: compiler.m4 80826 2008-03-04 14:51:23Z wotte $ +dnl +dnl compiler.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl that set/determine compiler configurations for ACE. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2003 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +dnl Macros to set flags for a given compiler on a given platform. +dnl The flags set here are generally only useful for _KNOWN_ compilers. + +dnl ACE_SET_COMPILER_FLAGS +dnl Usage: ACE_SET_COMPILER_FLAGS +AC_DEFUN([ACE_SET_COMPILER_FLAGS], +[ +dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL]) + + dnl Make sure we know what C++ compiler and preprocessor we have! + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PROG_CXXCPP]) + AC_LANG([C++]) + AC_REQUIRE([AC_LANG]) + + AC_REQUIRE([ACE_COMPILATION_OPTIONS]) + + ACE_GXX_MAJOR_VERSION=0 + + if test "$GXX" = yes; then + ACE_GXX_MAJOR_VERSION=`$CXX -dumpversion | sed -e 's/\..*$//'` + +dnl @todo Clean up / consolidate these conditionals + + if test "$ACE_GXX_MAJOR_VERSION -ge 3"; then + if test "$ace_user_enable_exceptions" != yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS -fcheck-new" + fi + else + case `$CXX --version` in + 2.9*) + if test "$ace_user_enable_exceptions" != yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS -fcheck-new" + fi + ;; + esac + fi + fi + + dnl Compiler Flag Key + dnl CXXFLAGS - C++ flags to use during the configure script run and + dnl during ACE compilation. The user may set this prior to + dnl running the configure script. As such, it is important + dnl not to replace the existing value of CXXFLAGS; rather + dnl one should only add to it. + dnl ACE_CXXFLAGS + dnl - General C++ flags the configure script should set before + dnl CXXFLAGS to allow the user override them. + dnl DCXXFLAGS - C++ debugging flags + dnl OCXXFLAGS - C++ optimization flags + dnl CPPFLAGS - C++ preprocessor flags + dnl ACE_CPPFLAGS + dnl - General C++ preprocessor flags the configure + dnl script should set before CPPFLAGS to allow the + dnl user to override them. + dnl WERROR - Compiler flag that converts warnings to errors + + if test "$GXX" = yes; then + WERROR="-Werror" + fi + + case "$host" in + *aix*) + dnl In case anything here or in the config depends on OS + dnl version number, grab it here and pass it all to the + dnl compiler as well. + AIX_VERS=`uname -v`0`uname -r` + ACE_CPPFLAGS="$ACE_CPPFLAGS -DACE_AIX_VERS=$AIX_VERS" + + case "$CXX" in + xlC*) + dnl AIX compilers need to have RTTI enabled and ACE requires it. + CXXFLAGS="$CXXFLAGS -qrtti=all" + TEMPLATE_OPTION='-qnotempinc -qnotemplateregistry -DACE_TEMPLATES_REQUIRE_SOURCE' + ACE_CXXFLAGS="$ACE_CXXFLAGS $TEMPLATE_OPTION" + DCXXFLAGS="-g -qcheck=nobounds:div:null" + OCXXFLAGS="-qlibansi -qarch=com" + CPPFLAGS="$CPPFLAGS" + # Use -qhalt=i to cause the compiler to signal failure on any + # diagnostic when converting warnings to errors. This helps to + # find that #pragma once is invalid, even though xlC only triggers + # an informational message, not a warning. + WERROR="-qhalt=i" + ;; + *) + if test "$GXX" = yes; then + ACE_CXXFLAGS="-mcpu=common" + fi + ;; + esac + ;; + *chorus*) + ;; + *cray*) + ;; + *dgux*) + case "$CXX" in + ec++) + CXXFLAGS="$CXXFLAGS" + ACE_CXXFLAGS="$ACE_CXXFLAGS -relax -v -eh" + DCXXFLAGS="-g" + OCXXFLAGS="" + ;; + *) + if test "$GXX" = yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS" + fi + ;; + esac + ;; + *freebsd*) + ;; + *hpux*) + # In case anything here or in the config depends on OS + # version number, grab it here and pass it all to the + # compiler as well. + OSVERS=`uname -r | $AWK 'BEGIN{FS=".";OFS="";}{print [$][2],[$][3]}' -` + ACE_CPPFLAGS="$ACE_CPPFLAGS -DHPUX_VERS=$OSVERS" + + # HP-UX OS version specific settings. + case "$host" in + *hpux11*) +# aCC's "-mt" flag detected by the configure script should already set +# the appropriate preprocessor, compiler and linker flags. +# if test "$ace_user_enable_threads" = yes; then +# # Prefer kernel threads over CMA (user) threads. +# ACE_CPPFLAGS="$ACE_CPPFLAGS -D_POSIX_C_SOURCE=199506L" +# fi + ;; + esac + + # HP-UX compiler specific settings. + case "$CXX" in + CC) + CXXFLAGS="$CXXFLAGS -pta -ti,/bin/true -tr,/bin/true" + ACE_CXXFLAGS="$ACE_CXXFLAGS -Aa -z +a1" + DCXXFLAGS="-g" + OCXXFLAGS="" + ;; + aCC) + CFLAGS = "${CFLAGS:-} -Ae" + # -AA has been available since aC++ x.27 (2001?) - if using a + # compiler without this support, must --enable_stdcpplib=no. + if test "$ace_user_enable_stdcpplib" = yes; then + CXXFLAGS="$CXXFLAGS -AA" + fi + # Warning 930 is spurious when new(std::nothrow) is + # used. Reported to HP as support call 3201224717. (Steve + # Huston, 23-Nov-2002) + # + # Suppress warning 302 ((...) parameter list is a + # non-portable feature) + # + # Additionally, on HP-UX 10.20, suppress 495 to shut up the + # warnings from the system header files. 667 is also + # suppressed, but the compiler still tells you there was a + # future error, but at least you can pick out any real errors + # by quickly scanning the output. 829 is suppressed because + # the system headers have offending string literals assigned + # to char *. + ACE_CXXFLAGS="$ACE_CXXFLAGS +W302,495,667,829,908,930" + DCXXFLAGS="-g" + OCXXFLAGS="-O" + # Warning 67: Invalid pragma name -- needed for + # ACE_LACKS_PRAGMA_ONCE + WERROR="+We67 +p +We" + + # If exception support is explicitly disabled, tell the + # compiler. This is not recommended since the run-time + # library can throw exceptions. + if test "$ace_user_enable_exceptions" != yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS +noeh" + fi + ;; + *) + if test "$GXX" = yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS -w" + fi + ;; + esac + ;; + *irix5*) + case "$CXX" in + CC) + CXXFLAGS="$CXXFLAGS -ptused -prelink +pp -woff 3203,3209,3161,3262,3665" + ACE_CXXFLAGS="$ACE_CXXFLAGS " + DCXXFLAGS="-g" + OCXXFLAGS="" + ;; + *) + ;; + esac + ;; + *irix6*) + case "$CXX" in + CC) + CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE" + CXXFLAGS="$CXXFLAGS -exceptions -ptnone -no_prelink -Wl,-woff,15 -Wl,-woff,84 -Wl,-woff,85 -Wl,-woff,133" + ACE_CXXFLAGS="$ACE_CXXFLAGS " + DCXXFLAGS="-g" + OCXXFLAGS="-O -OPT:Olimit=0" + ;; + esac + ;; + *linux*) + case "$CXX" in + *icpc|*icc) + CXXFLAGS="$CXXFLAGS -i-dynamic -w1" + ACE_CXXFLAGS="$ACE_CXXFLAGS" + DCXXFLAGS="$DCXXFLAGS" + WERROR="-Werror -wr -Wall" + ;; + *) + if test "$GXX" = yes; then + CXXFLAGS="$CXXFLAGS" + ACE_CXXFLAGS="$ACE_CXXFLAGS" + DCXXFLAGS="$DCXXFLAGS" + OCXXFLAGS="-O3" + fi + ;; + esac + ;; + *lynxos*) + ;; + *m88k*) + ;; + *mvs*) + ;; + *netbsd*) + ;; + *osf*) + ;; + *psos*) + ;; + *sco*) + ;; + *sunos4*) + ;; + *solaris2*) + case "$CXX" in + CC) + WERROR="-xwe" + + if test "$ace_user_enable_exceptions" != yes; then + CXXFLAGS="$CXXFLAGS -noex" + fi + + dnl Some flags only work with Sun C++ 4.2. ACE requires RTTI. + if (CC -V 2>&1 | $EGREP 'Compilers 4\.2' > /dev/null); then + CXXFLAGS="$CXXFLAGS -features=castop -features=rtti" + fi + + dnl Sun C++ 5.0 weirdness + if (CC -V 2>&1 | $EGREP 'Compilers 5\.0' > /dev/null); then + if test "$ace_user_enable_stdcpplib" = yes; then + CXXFLAGS="$CXXFLAGS -library=Cstd" + else + CXXFLAGS="$CXXFLAGS -library=iostream,no%Cstd" + AC_DEFINE([ACE_USES_OLD_IOSTREAMS]) + fi + + dnl Inlining appears to cause link problems with early + dnl releases of CC 5.0. + AC_DEFINE([ACE_LACKS_INLINE_FUNCTIONS]) + + if test "$ace_user_enable_exceptions" != yes; then + dnl See /opt/SUNWspro_5.0/SC5.0/include/CC/stdcomp.h. + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_RWSTD_NO_EXCEPTIONS" + fi + + CXXFLAGS="$CXXFLAGS -instances=explicit" + fi + + CXXFLAGS="$CXXFLAGS" + ACE_CXXFLAGS="$ACE_CXXFLAGS" + DCXXFLAGS="$DCXXFLAGS -g" + OCXXFLAGS="$OCXXFLAGS -O" + ;; + esac + ;; + *tandem*) + ;; + *unixware*) + ;; + *vxworks*) + ;; + *) + CXXFLAGS="$CXXFLAGS" + ACE_CXXFLAGS="$ACE_CXXFLAGS" + DCXXFLAGS="-g" + OCXXFLAGS="-O" + ;; + esac + + dnl Warning flags + if test "$GCC" = yes; then + ACE_CFLAGS="$ACE_CFLAGS -W -Wall -Wpointer-arith" + fi + if test "$GXX" = yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS -W -Wall -Wpointer-arith" + fi + + dnl Symbol Visibility flags + dnl Take advantage of visibility attributes when using g++ 4.0 or + dnl better. + if test "$GXX" = yes; then + dnl As of this writing, there are symbol visibility issues on some + dnl platforms. The --disable-symbol-visibility option is intended + dnl to allow users to explicitly disable symbol visibility support + dnl in the cases where it does not work (or does not work properly), + dnl but the feature test selects it anyway. + + AC_ARG_ENABLE([symbol-visibility], + AS_HELP_STRING([--enable-symbol-visibility], + [build with gcc symbol visibility attributes [[[no]]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_symbol_visibility=yes + ;; + no) + ace_user_enable_symbol_visibility=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-symbol-visibility]) + ;; + esac + ], + [ + ace_user_enable_symbol_visibility=no + ]) + + if test "$ace_user_enable_symbol_visibility" = yes; then + ACE_CHECK_CXXFLAGS([fvisibility=hidden], + [ + ACE_CXXFLAGS="$ACE_CXXFLAGS -fvisibility=hidden" + AC_DEFINE([ACE_HAS_CUSTOM_EXPORT_MACROS]) + AC_DEFINE([ACE_Proper_Export_Flag], + [__attribute__ ((visibility("default")))]) + ]) + ACE_CHECK_CXXFLAGS([fvisibility-inlines-hidden], + [ + ACE_CXXFLAGS="$ACE_CXXFLAGS -fvisibility-inlines-hidden" + ]) + fi + fi + + dnl Additional flags + if test "$GXX" = yes; then + case `$CXX --version` in + 2.9*) + if test "$ace_user_enable_exceptions" != yes; then + ACE_CXXFLAGS="$ACE_CXXFLAGS -fcheck-new" + fi + ;; + esac + +dnl if test "$ace_user_enable_repo" = no; then +dnl ACE_CXXFLAGS="$ACE_CXXFLAGS -fno-implicit-templates" +dnl fi + fi +]) + +AC_DEFUN([ACE_CHECK_CFLAGS], +[ +AS_VAR_PUSHDEF([VAR],'ace_cv_cflag_$1') +AC_MSG_CHECKING([whether $CC supports -$1]) +AC_LANG_SAVE +AC_LANG([C]) +ace_save_CFLAGS=$CFLAGS +CFLAGS="$CFLAGS -$1" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0])],[VAR=yes],[VAR=no]) +CFLAGS=$ace_save_CFLAGS +AC_LANG_RESTORE +if test $VAR = yes; then + AC_MSG_RESULT([yes]) + $2 +else + AC_MSG_RESULT([no]) + $3 +fi +AS_VAR_POPDEF([VAR]) +]) + +AC_DEFUN([ACE_CHECK_CXXFLAGS], +[ +AS_VAR_PUSHDEF([VAR],'ace_cv_cxxflag_$1') +AC_MSG_CHECKING([whether $CXX supports -$1]) +AC_LANG_SAVE +AC_LANG([C++]) +ace_save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS -$1" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0])],[VAR=yes],[VAR=no]) +CXXFLAGS=$ace_save_CXXFLAGS +AC_LANG_RESTORE +if test $VAR = yes; then + AC_MSG_RESULT([yes]) + $2 +else + AC_MSG_RESULT([no]) + $3 +fi +AS_VAR_POPDEF([VAR]) +]) diff --git a/dep/ACE_wrappers/m4/config_h.m4 b/dep/ACE_wrappers/m4/config_h.m4 new file mode 100644 index 000000000..6338b290f --- /dev/null +++ b/dep/ACE_wrappers/m4/config_h.m4 @@ -0,0 +1,976 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: config_h.m4 82277 2008-07-09 17:45:59Z jtc $ +dnl +dnl config_h.m4 +dnl +dnl ACE M4 include file which contains preprocessor constants +dnl and other items to be place in the generated ace/config.h +dnl header. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 2002, 2003 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +dnl Prepare the ace/config.h.in template. +dnl +dnl Usage: ACE_PREP_CONFIG_HEADER +AC_DEFUN([ACE_PREP_CONFIG_HEADER], +[ +dnl Text to be placed at the top of the `ace/config.h' header. +AH_TOP([ +#ifndef ACE_CONFIG_H +#define ACE_CONFIG_H + +// ACE configuration header file + + +]) + +dnl Text to be placed at the bottom of the `ace/config.h' header. +dnl +dnl @note Do not remove the "] [" between the words "Local Variables". +dnl The generated Emacs "Local Variables" block will not contain +dnl those characters. They are merely interpreted by M4 as two +dnl concatenated text blocks. This is necessary to prevent +dnl Emacs from inadvertently applying the "Local Variables" +dnl block being placed in the generated "config.h" header to +dnl this Autoconf/M4 file. +AH_BOTTOM([ + + +#endif /* ACE_CONFIG_H */ + + +// Local] [Variables: +// mode:C++ +// End: + +]) + + +dnl ACE currently doesn't use these; however the configure script does +AH_TEMPLATE([ACE_LACKS_UNBUFFERED_STREAMBUF],[]) +AH_TEMPLATE([ACE_HAS_STDCPP_STL_INCLUDES],[]) + +AH_TEMPLATE([ACE_HAS_NEW_NO_H],[Platform provides new style C++ header]) +AH_TEMPLATE([ACE_HAS_STDEXCEPT_NO_H],[Platform provides C++ header]) + +dnl Deprecated! (or soon to be?) +AH_TEMPLATE([ACE_HAS_OSF1_GETTIMEOFDAY], +[timezone* 2nd parameter & no prototype]) +AH_TEMPLATE([ACE_HAS_LYNXOS_SIGNALS],[]) +AH_TEMPLATE([ACE_HAS_TANDEM_SIGNALS],[]) + +AH_TEMPLATE([PTHREAD_STACK_MIN],[]) + +dnl ///////////////////// OSSAMA'S NEW STUFF ////////////////// */ +dnl THIS STUFF WILL REPLACE THE ABOVE OLDER STUFF AND/OR WILL BE MERGED INTO IT + + +dnl /* results from checks for programs */ +dnl /* results from checks for libraries */ +dnl /* results from checks for header files */ +dnl /* results from checks for typedefs */ +dnl /* results from checks for structures */ +dnl /* results from checks for variables */ +dnl /* results from checks for compiler characteristics */ +dnl /* results from checks for library functions */ +dnl /* results from checks for system services */ + +dnl AIX specific configuration parameters +AH_TEMPLATE([AIX],[Configure for use on AIX]) + +dnl FreeBSD specific configuration parameters +dnl Nothing yet + +dnl HP/UX specific configuration parameters +AH_TEMPLATE([HPUX],[Configure for use on HP-UX]) +AH_TEMPLATE([HPUX_10],[Configure for use on HP-UX 10]) +AH_TEMPLATE([HPUX_11],[Configure for use on HP-UX 11]) + +dnl Irix specific configuration parameters +AH_TEMPLATE([IRIX5],[Configure for use on Irix 5]) +AH_TEMPLATE([IRIX6],[Configure for use on Irix 6]) +AH_TEMPLATE([ACE_HAS_IRIX62_THREADS], +[Platform supports the very odd IRIX 6.2 threads...]) + +dnl Linux specific configuration parameters +dnl Nothing yet */ + +dnl LynxOS specific configuration parameters +AH_TEMPLATE([__NO_INCLUDE_WARN__],[]) + +dnl MVS specific configuration parameters +dnl Nothing yet + +dnl NetBSD specific configuration parameters +dnl Nothing yet + +dnl OSF/1 and Digital Unix specific configuration parameters +AH_TEMPLATE([DEC_CXX],[]) +AH_TEMPLATE([DIGITAL_UNIX],[Configure for use on Digital Unix]) + +dnl SCO specific configuration parameters +AH_TEMPLATE([SCO],[]) + +dnl Tandem specific configuration parameters +dnl Nothing yet + +dnl UnixWare specific configuration parameters +AH_TEMPLATE([UNIXWARE],[Configure for use on UnixWare]) +AH_TEMPLATE([UNIXWARE_2_0],[]) +AH_TEMPLATE([UNIXWARE_2_1],[]) +AH_TEMPLATE([UNIXWARE_7_1],[]) +AH_TEMPLATE([__IOCTL_VERSIONED__],[]) + +dnl VXWorks specific configuration parameters +AH_TEMPLATE([VXWORKS],[Configure for use on VxWorks]) + +dnl Win32 specific configuration parameters +AH_TEMPLATE([ACE_WIN32],[Configure for use on Win32]) + +AH_TEMPLATE([ACE_DISABLE_DEBUG_DLL_CHECK], +[Define this if you don't want debug version ACE search for debug version +DLLs first before looking for the DLL names specified.]) + +AH_TEMPLATE([ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS], +[Platform/compiler supports Win32 structural exceptions.]) + +AH_TEMPLATE([ACE_WSOCK_VERSION], +[A parameter list indicating the version of WinSock (e.g., "1, 1" is +version 1.1).]) + +AH_TEMPLATE([ACE_HAS_MFC],[Platform supports Microsoft Foundation Classes]) + +AH_TEMPLATE([ACE_USES_STATIC_MFC], +[When linking MFC as a static library is desired]) + +AH_TEMPLATE([ACE_HAS_CANCEL_IO], +[Platform supports the Win32 CancelIO() function. (WinNT 4.0 and beyond)]) + +AH_TEMPLATE([ACE_HAS_WIN32_TRYLOCK], +[The Win32 platform support TryEnterCriticalSection(). (WinNT 4.0 and +beyond)]) + +AH_TEMPLATE([ACE_HAS_WINSOCK2],[The Win32 platform supports WinSock 2.0.]) + +AH_TEMPLATE([ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL], +[For Win32: Use Select_Reactor as default implementation of Reactor + instead of WFMO_Reactor.]) + +AH_TEMPLATE([ACE_HAS_DLL],[Build ACE using the frigging PC DLL nonsense...]) + +AH_TEMPLATE([ACE_HAS_STRICT],[Use the STRICT compilation mode on Win32.]) + +AH_TEMPLATE([CYGWIN32], [GNU Win32 environement]) + + +dnl ACE internals +AH_TEMPLATE([ACE_DEFAULT_BASE_ADDR],[]) +AH_TEMPLATE([ACE_DEFAULT_BASE_ADDRL],[]) +AH_TEMPLATE([ACE_DEFAULT_CLOSE_ALL_HANDLES],[]) +AH_TEMPLATE([ACE_DEFAULT_MAX_SOCKET_BUFSIZ],[]) +AH_TEMPLATE([ACE_DEFAULT_SELECT_REACTOR_SIZE],[The default number of handles the select()-based reactor should handle]) +AH_TEMPLATE([ACE_MALLOC_ALIGN],[]) +AH_TEMPLATE([ACE_MAP_PRIVATE],[]) +AH_TEMPLATE([ACE_THR_PRI_FIFO_DEF],[]) +AH_TEMPLATE([ACE_TIMER_SKEW],[]) +AH_TEMPLATE([IP_ADD_MEMBERSHIP],[]) +AH_TEMPLATE([IP_DROP_MEMBERSHIP],[]) + +AH_TEMPLATE([ACE_LOFF_T_TYPEDEF],[typedef for ACE_LOFF_T]) + +AH_TEMPLATE([__ACE_INLINE__],[Enable ACE inlining]) + +AH_TEMPLATE([ACE_NO_INLINE],[Explicitly disable ACE inlining]) + +AH_TEMPLATE([ACE_COMPILE_TIMEPROBES],[Enable ACE_Timeprobes]) + +AH_TEMPLATE([ACE_HAS_GNU_REPO], +[Enable use of GNU template repositories. GNU C++ w/repo patch +and EGCS only]) + +AH_TEMPLATE([ACE_HAS_AIO_CALLS],[Platform supports Asynchronous IO calls]) + +AH_TEMPLATE([ACE_HAS_ALT_CUSERID], +[Use ACE's alternate cuserid() implementation since a system +cuserid() may not exist, or it is not desirable to use it. The +implementation requires ACE_LACKS_PWD_FUNCTIONS to be undefined and +that the geteuid() system call exists.]) + +AH_TEMPLATE([ACE_DEFAULT_THREAD_KEYS], +[Number of TSS keys, with ACE_HAS_TSS_EMULATION _only_. Defaults to 64.]) + +AH_TEMPLATE([ACE_THREADS_DONT_INHERIT_LOG_MSG], +[Specify this if you don't want threads to inherit parent thread's +ACE_Log_Msg properties.]) + +AH_TEMPLATE([ACE_HAS_PRIOCNTL],[OS has priocntl (2)]) + +AH_TEMPLATE([ACE_HAS_RLIMIT_RESOURCE_ENUM], +[Platform has enum instead of int for first argument to ::{get,set}rlimit (). +The value of this macro is the enum definition, e.g., +enum __rlimit_resource, for Linux glibc 2.0.]) + +AH_TEMPLATE([ACE_HAS_RUSAGE_WHO_ENUM], +[Platform has enum instead of int for first argument to ::getrusage (). The +value of this macro is the enum definition, e.g., enum __rusage_who, for +Linux glibc 2.0.]) + +AH_TEMPLATE([ACE_HAS_STDARG_THR_DEST], +[Platform has void (*)(...) prototype for pthread_key_create() +destructor (e.g., LynxOS).]) + +AH_TEMPLATE([ACE_HAS_STL_MAP_CONFLICT], +[Used when users want to compile ACE with STL and STL map class +conflicts with map struct.]) + +AH_TEMPLATE([ACE_HAS_STL_QUEUE_CONFLICT], +[Used when users want to compile ACE with STL and STL queue class +conflicts with queue struct.]) + +AH_TEMPLATE([ACE_HAS_4_4BSD_SENDMSG_RECVMSG], +[Platform has BSD 4.4 sendmsg()/recvmsg() APIs.]) + +AH_TEMPLATE([ACE_HAS_P_READ_WRITE], +[Platform has pread() and pwrite() support.]) + +AH_TEMPLATE([ACE_HAS_AIX_HI_RES_TIMER], +[Platform has AIX4 ::read_real_time()]) + +AH_TEMPLATE([ACE_HAS_ALLOCA],[Compiler/platform supports alloca().]) + +AH_TEMPLATE([ACE_HAS_ALLOCA_H],[Compiler/platform has ]) + +AH_TEMPLATE([ACE_HAS_AUTOMATIC_INIT_FINI], +[Compiler/platform correctly calls init()/fini() for shared libraries.]) + +AH_TEMPLATE([ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR], +[Compiler handles explicit calling of template destructor correctly.]) + +AH_TEMPLATE([ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS], +[Compiler requires template args when explicitly calling template destructor.]) + +AH_TEMPLATE([ACE_HAS_BROKEN_MAP_FAILED], +[Platform doesn't cast MAP_FAILED to a (void *).]) + +AH_TEMPLATE([ACE_HAS_BROKEN_CTIME], +[Compiler/platform uses macro for ctime (e.g., MVS)]) + +AH_TEMPLATE([ACE_HAS_BROKEN_DGRAM_SENDV], +[Platform sendv() does not work properly with datagrams, i.e. it +fails when the iovec size is IOV_MAX.]) + +AH_TEMPLATE([ACE_HAS_BROKEN_MSG_H], +[Platform headers don't support prototypes]) + +AH_TEMPLATE([ACE_HAS_BROKEN_MMAP_H], +[HP/UX does not wrap the mmap(2) header files with extern "C".]) + +AH_TEMPLATE([ACE_HAS_BROKEN_POSIX_TIME], +[Platform defines struct timespec in ]) + +AH_TEMPLATE([ACE_HAS_BROKEN_R_ROUTINES], +[Platform defines ctime_r, asctime_r, rand_r and getpwnam_r as macros]) + +AH_TEMPLATE([ACE_HAS_BROKEN_RANDR], +[OS/compiler's header files are inconsistent with libC definition of +rand_r().]) + +AH_TEMPLATE([ACE_HAS_BROKEN_T_ERROR], +[Compiler/platform has the wrong prototype for t_error(), i.e., +t_error(char *) rather than t_error(const char *).]) + +AH_TEMPLATE([ACE_HAS_BSTRING], +[Platform has (which contains bzero() prototype)]) + +AH_TEMPLATE([ACE_HAS_CHARPTR_DL], +[OS/platform uses char * for dlopen/dlsym args, rather than const char *.]) + +AH_TEMPLATE([ACE_HAS_CHARPTR_SOCKOPT], +[OS/platform uses char * for sockopt, rather than const char *]) + +AH_TEMPLATE([ACE_HAS_CONFLICTING_XTI_MACROS], +[OS header files have some problems with XTI (HP/UX 11).]) + +AH_TEMPLATE([ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES], +[Prototypes for both signal() and struct sigaction are consistent.]) + +AH_TEMPLATE([ACE_HAS_CONST_CHAR_SWAB], +[Platform has swab(const char*, char*, ssize_t) variant.]) + +AH_TEMPLATE([ACE_HAS_CPLUSPLUS_HEADERS], +[Compiler/platform has correctly prototyped header files.]) + +AH_TEMPLATE([ACE_HAS_DIRENT], +[Platform supports operations on directories via struct dirent, +readdir_r, etc.]) + +AH_TEMPLATE([ACE_HAS_EXCEPTIONS],[Compiler supports C++ exception handling.]) + +AH_TEMPLATE([ACE_HAS_FL],[Platform has Fast-Light (FL) toolkit installed.]) + +AH_TEMPLATE([ACE_HAS_GETPAGESIZE], +[Platform supports getpagesize() call (otherwise, ACE_PAGE_SIZE must +be defined, except on Win32).]) + +AH_TEMPLATE([ACE_HAS_GNU_CSTRING_H], +[Denotes that GNU has cstring.h as standard which redefines memchr()]) + +AH_TEMPLATE([ACE_HAS_INTRINSIC_INTERLOCKED], +[Platform supports the intrinsic interlocked optimizations.]) + +AH_TEMPLATE([ACE_HAS_GPERF], +[The GPERF utility is compiled for this platform]) + +AH_TEMPLATE([ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT], +[Optimize ACE_Handle_Set::count_bits for select() operations (common case)]) + +AH_TEMPLATE([ACE_HAS_LSEEK64], +[Platform supports lseek64(). This should not be defined if + ACE_HAS_LLSEEK is defined.]) + +AH_TEMPLATE([ACE_HAS_LLSEEK], +[Platform supports llseek(). This should not be defined if + ACE_HAS_LSEEK64 is defined.]) + +AH_TEMPLATE([ACE_HAS_HI_RES_TIMER], +[Compiler/platform supports SunOS high resolution timers]) + +AH_TEMPLATE([ACE_HAS_INLINED_OSCALLS],[ +Inline all the static class OS methods to remove call overhead +Note: This gets defined by OS.h if __ACE_INLINE__ is defined]) + +AH_TEMPLATE([ACE_HAS_IP_MULTICAST],[Platform supports IP multicast]) + +AH_TEMPLATE([ACE_HAS_IPV6],[Platform supports IPv6]) +AH_TEMPLATE([ACE_USES_IPV4_IPV6_MIGRATION], +[Enable IPv6 support on platforms that don't have IPv6 turned on by default]) + +AH_TEMPLATE([ACE_HAS_NEW_NOTHROW], +[Compiler supports new (std::nothrow)]) + +AH_TEMPLATE([ACE_HAS_NONCONST_SWAB], +[Platform has swab(char*, char*, ssize_t) variant.]) + +AH_TEMPLATE([ACE_HAS_NONSTATIC_OBJECT_MANAGER], +[Causes the ACE_Object_Manager instance to be created in + main (int, char *[]), instead of as a static (global) instance.]) + +AH_TEMPLATE([ACE_HAS_THR_KEYDELETE], +[Platform supports thr_keydelete (e.g,. UNIXWARE)]) + +AH_TEMPLATE([ACE_HAS_THR_MINSTACK], +[Platform calls thr_minstack() rather than thr_min_stack() (e.g., Tandem).]) + +AH_TEMPLATE([ACE_HAS_LIMITED_RUSAGE_T], +[The rusage_t structure has only two fields.]) + +AH_TEMPLATE([ACE_HAS_BIG_FD_SET], +[Compiler/platform has "big" fd_set, i.e. large number of bits set + in fd_set passed back from select().]) + +AH_TEMPLATE([ACE_HAS_LONG_MAP_FAILED], +[Platform defines MAP_FAILED as a long constant.]) + +AH_TEMPLATE([ACE_HAS_MALLOC_STATS], [Enabled malloc statistics collection.]) + +AH_TEMPLATE([ACE_USES_OLD_IOSTREAMS], +[Some files, such as ace/streams.h, want to include new style C++ + stream headers. These headers are iomanip, ios, iostream, istream, + ostream, fstream and streambuf. If _all_ of these headers aren't + available, then assume that only iostream.h and fstream.h are + available.]) + +AH_TEMPLATE([ACE_HAS_MSG],[Platform supports recvmsg and sendmsg]) + +AH_TEMPLATE([ACE_HAS_MT_SAFE_MKTIME], +[Platform supports MT safe mktime() call (do any of them?)]) + +AH_TEMPLATE([ACE_HAS_MT_SAFE_SOCKETS], +[Sockets may be called in multi-threaded programs]) + +AH_TEMPLATE([ACE_HAS_NONCONST_GETBY], +[Platform uses non-const char * in calls to gethostbyaddr, + gethostbyname, getservbyname]) + +AH_TEMPLATE([ACE_HAS_NONCONST_MSGSND], +[Platform has a non-const parameter to msgsnd() (e.g., SCO).]) + +AH_TEMPLATE([ACE_HAS_NONCONST_READV], +[Platform omits const qualifier from iovec parameter in readv() prototype.]) + +AH_TEMPLATE([ACE_HAS_NONCONST_SELECT_TIMEVAL], +[Platform's select() uses non-const timeval* (only found on Linux + right now)]) + +AH_TEMPLATE([ACE_HAS_NONCONST_SENDMSG], +[Platform omits const qualifier from msghdr parameter in sendmsg() + prototype.]) + +AH_TEMPLATE([ACE_HAS_NONCONST_SETRLIMIT], +[Platform omits const qualifier from rlimit parameter in setrlimit() + prototype.]) + +AH_TEMPLATE([ACE_HAS_NONCONST_WRITEV], +[Platform omits const qualifier from iovec parameter in writev() prototype.]) + +AH_TEMPLATE([ACE_HAS_OLD_MALLOC], +[Compiler/platform uses old malloc()/free() prototypes (ugh)]) + +AH_TEMPLATE([ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R], +[Uses ctime_r & asctime_r with only two parameters vs. three.]) + +AH_TEMPLATE([ACE_HAS_ONLY_SCHED_OTHER], +[Platform, e.g., Solaris 2.5, only supports SCHED_OTHER POSIX + scheduling policy.]) + +AH_TEMPLATE([ACE_HAS_OPTIMIZED_MESSAGE_QUEUE], +[Use the semaphore implementation of ACE_Message_Queue rather than + the emulated condition variable (NT and VxWorks).]) + +AH_TEMPLATE([ACE_HAS_OSF_TIMOD_H], +[Platform supports the OSF TLI timod STREAMS module]) + +AH_TEMPLATE([ACE_HAS_POLL],[Platform contains ]) + +AH_TEMPLATE([ACE_HAS_POSITION_INDEPENDENT_POINTERS], +[Platform supports "position-independent" features provided by + ACE_Based_Pointer<>.]) + +AH_TEMPLATE([ACE_HAS_POSIX_GETPWNAM_R], +[Platform supports POSIX getpwnam_r() function]) + +AH_TEMPLATE([ACE_HAS_POSIX_NONBLOCK], +[Platform supports POSIX O_NONBLOCK semantics]) + +AH_TEMPLATE([ACE_HAS_POSIX_REALTIME_SIGNALS], +[Platform supports POSIX realtime signals]) + +AH_TEMPLATE([ACE_HAS_POSIX_SEM], +[Platform supports POSIX real-time semaphores (e.g., VxWorks and + Solaris)]) + +AH_TEMPLATE([ACE_HAS_POSIX_SEM_TIMEOUT], +[Platform supports timed POSIX semaphore acquisitions (sem_timedwait()).]) + +AH_TEMPLATE([ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION], +[Do not include emulation for timed semaphore acquisitions.]) + +AH_TEMPLATE([ACE_HAS_POSIX_TIME], +[Platform supports the POSIX struct timespec type]) + +AH_TEMPLATE([ACE_HAS_PROC_FS], +[Platform supports the /proc file system and defines tid_t + in ]) + +AH_TEMPLATE([ACE_HAS_PRUSAGE_T],[Platform supports the prusage_t struct]) + +AH_TEMPLATE([ACE_HAS_PTHREADS_UNIX98_EXT], +[Platform has the UNIX98 extensions to Pthreads (rwlocks)]) + +AH_TEMPLATE([ACE_HAS_PTHREAD_PROCESS_ENUM], +[pthread.h declares an enum with PTHREAD_PROCESS_PRIVATE and + PTHREAD_PROCESS_SHARED values]) + +AH_TEMPLATE([ACE_HAS_PURIFY],[Purify'ing. Defined on command line.]) + +AH_TEMPLATE([ACE_HAS_QUANTIFY],[Quantify'ing. Defined on command line.]) + +AH_TEMPLATE([ACE_HAS_RECURSIVE_MUTEXES], +[Mutexes are inherently recursive (e.g., Win32) ]) + +AH_TEMPLATE([ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS], +[Platform will recurse infinitely on thread exits from TSS cleanup + routines (e.g., AIX)]) + +AH_TEMPLATE([ACE_HAS_SIGACTION_CONSTP2], +[Platform's sigaction() function takes const sigaction* as 2nd parameter]) + +AH_TEMPLATE([ACE_HAS_REENTRANT_FUNCTIONS], +[Platform supports reentrant functions (i.e., all the POSIX *_r + functions).]) + +AH_TEMPLATE([ACE_HAS_X86_STAT_MACROS], +[Solaris for intel uses macros for fstat() and stat(), these are + wrappers for _fxstat() and _xstat() uses of the macros. Causes + compile and runtime problems.]) + +AH_TEMPLATE([ACE_HAS_XPG4_MULTIBYTE_CHAR], +[Platform has support for multi-byte character support compliant + with the XPG4 Worldwide Portability Interface wide-character + classification.]) + +AH_TEMPLATE([ACE_LACKS_AUTO_MMAP_REPLACEMENT], +[No system support for replacing any previous mappings.]) + +AH_TEMPLATE([ACE_LACKS_AUTO_PTR], +[Platform lacks support for the standard C++ auto_ptr class]) + +AH_TEMPLATE([ACE_AUTO_PTR_LACKS_RESET], +[Compiler/platform standard C++ auto_ptr implementation lacks + reset() method]) + +AH_TEMPLATE([ACE_LACKS_READDIR_R],[Platform lacks readdir_r()]) + +AH_TEMPLATE([ACE_LACKS_INLINE_FUNCTIONS], +[Platform can't handle "inline" keyword correctly.]) + +AH_TEMPLATE([ACE_LACKS_IOSTREAM_TOTALLY], +[iostreams are not supported adequately on the given platform.]) + +AH_TEMPLATE([ACE_LACKS_NETDB_REENTRANT_FUNCTIONS], +[Platform does not support reentrant netdb functions + (getprotobyname_r, getprotobynumber_r, gethostbyaddr_r, + gethostbyname_r, getservbyname_r).]) + +AH_TEMPLATE([ACE_HAS_REGEX], +[Platform supports the POSIX regular expression library]) + +AH_TEMPLATE([ACE_HAS_SEMUN], +[Compiler/platform defines a union semun for SysV shared memory ]) + +AH_TEMPLATE([ACE_HAS_SHM_OPEN],[Platform has shm_open()]) +AH_TEMPLATE([ACE_SHM_OPEN_REQUIRES_ONE_SLASH],[shm_open() requires a leading slash in name]) + +AH_TEMPLATE([ACE_HAS_SIGISMEMBER_BUG], +[Platform has bug with sigismember() (HP/UX 11).]) + +AH_TEMPLATE([ACE_HAS_SIG_MACROS], +[Platform/compiler has macros for sig{empty,fill,add,del}set (e.g., + SCO and FreeBSD)]) + +AH_TEMPLATE([ACE_HAS_SIGNAL_OBJECT_AND_WAIT], +[Platform supports the Win32 SignalObjectAndWait() function (WinNT + 4.0 and beyond).]) + +AH_TEMPLATE([ACE_HAS_SIG_C_FUNC], +[Compiler requires extern "C" functions for signals.]) + +AH_TEMPLATE([ACE_HAS_SIZET_SOCKET_LEN], +[OS/compiler uses size_t * rather than int * for socket lengths]) + +AH_TEMPLATE([ACE_HAS_SOCKADDR_MSG_NAME], +[Platform requires (struct sockaddr *) for msg_name field of + struct msghdr.]) + +AH_TEMPLATE([ACE_HAS_THR_YIELD],[Platform has thr_yield()]) + +AH_TEMPLATE([ACE_HAS_STANDARD_CPP_LIBRARY], +[Platform/compiler supports Standard C++ Library]) + +AH_TEMPLATE([ACE_HAS_STRBUF_T],[Compiler/platform supports struct strbuf]) + +AH_TEMPLATE([ACE_HAS_STREAMS],[Platform supports STREAMS]) + +AH_TEMPLATE([ACE_HAS_STREAM_PIPES],[Platform supports STREAM pipes]) + +AH_TEMPLATE([ACE_LACKS_STROPTS_H],[Platform lacks stropts.h]) + +AH_TEMPLATE([ACE_HAS_STRING_CLASS], +[Platform/Compiler supports a String class (e.g., GNU or Win32).]) + +AH_TEMPLATE([ACE_HAS_STRINGS], +[Platform has (which contains bzero() prototype)]) + +AH_TEMPLATE([ACE_HAS_STRUCT_NETDB_DATA], +[Compiler/platform has strange hostent API for socket *_r() calls]) + +AH_TEMPLATE([ACE_HAS_SVR4_DYNAMIC_LINKING], +[Compiler/platform supports SVR4 dynamic linking semantics]) + +AH_TEMPLATE([ACE_HAS_SVR4_GETTIMEOFDAY], +[Compiler/platform supports SVR4 gettimeofday() prototype but + doesn't have a prototype]) + +AH_TEMPLATE([ACE_HAS_SVR4_SIGNAL_T], +[Compiler/platform supports SVR4 signal typedef.]) + +AH_TEMPLATE([ACE_HAS_SVR4_TLI], +[Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff).]) + +AH_TEMPLATE([ACE_HAS_SYSINFO], +[Platform supports system configuration information.]) + +AH_TEMPLATE([ACE_HAS_SYSV_IPC], +[Platform supports System V IPC (most versions of UNIX, but not Win32)]) + +AH_TEMPLATE([ACE_HAS_SYS_ERRLIST], +[Platform/compiler supports _sys_errlist symbol]) + +AH_TEMPLATE([ACE_HAS_SYS_SIGLIST], +[Compiler/platform supports _sys_siglist array]) + +AH_TEMPLATE([ACE_HAS_SYS_XTI_H],[Platform provides header]) + +AH_TEMPLATE([ACE_HAS_TEMPLATE_TYPEDEFS], +[Compiler implements templates that support typedefs inside of + classes used as formal arguments to a template class.]) + +AH_TEMPLATE([ACE_HAS_THREADS],[Platform supports threads.]) + +AH_TEMPLATE([ACE_HAS_THREAD_SAFE_ACCEPT], +[Platform allows multiple threads to call accept() on the same port + (e.g., WinNT).]) + +AH_TEMPLATE([ACE_HAS_THREAD_SELF], +[Platform has thread_self() rather than pthread_self() (e.g., + DCETHREADS and AIX)]) + +AH_TEMPLATE([ACE_HAS_THREAD_SPECIFIC_STORAGE], +[Compiler/platform has thread-specific storage]) + +AH_TEMPLATE([ACE_HAS_THR_C_DEST], +[The pthread_keycreate() routine *must* take extern C functions.]) + +AH_TEMPLATE([ACE_HAS_THR_C_FUNC], +[The pthread_create() routine *must* take extern C functions.]) + +AH_TEMPLATE([ACE_HAS_TIMEZONE_GETTIMEOFDAY], +[Platform/compiler supports timezone * as second parameter to + gettimeofday() and has a prototype.]) + +AH_TEMPLATE([ACE_HAS_TIMOD_H], +[Platform supports TLI timod STREAMS module]) + +AH_TEMPLATE([ACE_HAS_TIUSER_H],[Platform supports TLI tiuser header]) + +AH_TEMPLATE([ACE_HAS_TIUSER_H_BROKEN_EXTERN_C], +[Platform does not protect with extern "C"]) + +AH_TEMPLATE([ACE_HAS_TLI], +[Platform supports TLI. Also see ACE_TLI_TCP_DEVICE.]) + +AH_TEMPLATE([ACE_HAS_TLI_PROTOTYPES], +[Platform provides TLI function prototypes]) + +AH_TEMPLATE([ACE_HAS_TSS_EMULATION], +[ACE provides TSS emulation. See also ACE_DEFAULT_THREAD_KEYS.]) + +AH_TEMPLATE([ACE_HAS_UCONTEXT_T], +[Platform supports ucontext_t (which is used in the extended signal API).]) + +AH_TEMPLATE([ACE_HAS_UNIXWARE_SVR4_SIGNAL_T], +[Has inconsistent SVR4 signal stuff, but not the same as the other + platforms]) + +AH_TEMPLATE([ACE_HAS_WCHAR],[Platform/compiler supports wchar_t]) +AH_TEMPLATE([ACE_USES_WCHAR],[ACE is built to use wide characters internally]) + +AH_TEMPLATE([ACE_HAS_VERBOSE_NOTSUP], +[Prints out console message in ACE_NOTSUP. Useful for tracking down + origin of ACE_NOTSUP.]) + +AH_TEMPLATE([ACE_HAS_VOIDPTR_GETTIMEOFDAY], +[Platform/compiler supports void * as second parameter to + gettimeofday() and has a prototype.]) + +AH_TEMPLATE([ACE_HAS_VOIDPTR_MMAP],[Platform requires void * for mmap().]) + +AH_TEMPLATE([ACE_HAS_VOIDPTR_SOCKOPT], +[OS/compiler uses void * arg 4 setsockopt() rather than const char *]) + +AH_TEMPLATE([ACE_HAS_XLI],[Platform has the XLI version of TLI]) + +AH_TEMPLATE([ACE_HAS_XT],[Platform has Xt Intrinsics Toolkit]) + +AH_TEMPLATE([ACE_LACKS_MOTIF], +[Platform does not have Motif X toolkit available]) + +AH_TEMPLATE([ACE_HAS_XTI], +[Platform has XTI (X/Open-standardized superset of TLI). Implies + ACE_HAS_TLI but uses a different header file.]) + +AH_TEMPLATE([ACE_LACKS_ACE_IOSTREAM], +[Platform can not build ace/IOStream{,_T}.cpp. This does not + necessarily mean that the platform does not support iostreams.]) + +AH_TEMPLATE([ACE_LACKS_ACE_CODECS], +[Do not compile support for the "Codecs" ACE features.]) + +AH_TEMPLATE([ACE_LACKS_ACE_OTHER], +[Do not compile support for the "other" ACE features, such as CORBA + handling, name services, and QoS.]) + +AH_TEMPLATE([ACE_LACKS_ACE_SVCCONF], +[Do not compile support for the ACE Service Configurator.]) + +AH_TEMPLATE([ACE_LACKS_ACE_TOKEN], +[Do not compile support for the ACE Token feature.]) + +AH_TEMPLATE([ACE_LACKS_ACE_UUID], +[Do not compile support for the ACE UUID feature.]) + +AH_TEMPLATE([ACE_LACKS_COND_T], +[Platform lacks condition variables (e.g., Win32 and VxWorks)]) + +AH_TEMPLATE([ACE_LACKS_COND_TIMEDWAIT_RESET], +[pthread_cond_timedwait does *not* reset the time argument when + the lock is acquired.]) + +AH_TEMPLATE([ACE_LACKS_CONDATTR_PSHARED], +[Platform has no implementation of pthread_condattr_setpshared(), even + though it supports pthreads!]) + +AH_TEMPLATE([ACE_LACKS_CONST_STRBUF_PTR], +[Platform uses struct strbuf * rather than const struct strbuf * + (e.g., HP/UX 10.x)]) + +AH_TEMPLATE([ACE_LACKS_CONST_TIMESPEC_PTR], +[Platform forgot const in cond_timewait (e.g., HP/UX).]) + +AH_TEMPLATE([ACE_LACKS_EXEC], +[Platform lacks the exec() family of system calls (e.g., Win32, + VxWorks, Chorus)]) + +AH_TEMPLATE([ACE_LACKS_FILELOCKS],[Platform lacks file locking mechanism]) + +AH_TEMPLATE([ACE_LACKS_GETSERVBYNAME], +[Platforms lacks getservbyname() (e.g., VxWorks and Chorus).]) + +AH_TEMPLATE([ACE_LACKS_IOSTREAM_FX], +[iostream header does not declare ipfx (), opfx (), etc.]) + +AH_TEMPLATE([ACE_LACKS_LINEBUFFERED_STREAMBUF], +[Platform lacks streambuf "linebuffered ()".]) + +AH_TEMPLATE([ACE_LACKS_LONGLONG_T], +[Compiler/platform does not support the unsigned long long datatype.]) + +AH_TEMPLATE([ACE_LACKS_U_LONGLONG_T], +[Platform does not have u_longlong_t typedef]) + +AH_TEMPLATE([ACE_LACKS_MMAP], +[The platform doesn't have mmap(2) (e.g., SCO UNIX).]) + +AH_TEMPLATE([ACE_LACKS_MODE_MASKS], +[Platform/compiler doesn't have open() mode masks.]) + +AH_TEMPLATE([ACE_LACKS_MSG_ACCRIGHTS], +[Platform defines ACE_HAS_MSG, but lacks msg_accrights{len}.]) + +AH_TEMPLATE([ACE_LACKS_MUTEXATTR_PSHARED], +[Platform lacks pthread_mutexattr_setpshared().]) + +AH_TEMPLATE([ACE_LACKS_NULL_PTHREAD_STATUS], +[OS requires non-null status pointer for pthread_join ()]) + +AH_TEMPLATE([ACE_HAS_MUTEX_TIMEOUTS], +[Compiler supports timed mutex acquisitions (e.g. pthread_mutex_timedlock()).]) + +AH_TEMPLATE([ACE_LACKS_NAMED_POSIX_SEM], +[Platform lacks named POSIX semaphores (e.g., Chorus)]) + +AH_TEMPLATE([ACE_LACKS_STRPTIME], +[Platform lacks native strptime() implementation.]) + +AH_TEMPLATE([ACE_LACKS_RLIMIT], +[Platform/compiler lacks {get,set}rlimit() function (e.g., VxWorks, + Chorus, and SCO UNIX)]) + +AH_TEMPLATE([ACE_LACKS_RWLOCKATTR_PSHARED], +[Platform lacks pthread_rwlockattr_setpshared().]) + +AH_TEMPLATE([ACE_LACKS_PLACEMENT_OPERATOR_NEW], +[Compiler doesn't support placement operator new(size_t, void *).]) + +AH_TEMPLATE([ACE_LACKS_PLACEMENT_OPERATOR_DELETE], +[Compiler doesn't support placement operator delete(void *, void *).]) + +AH_TEMPLATE([ACE_LACKS_PRAGMA_ONCE], +[Compiler complains about use of obsolete "pragma once"]) + +AH_TEMPLATE([ACE_LACKS_PTHREAD_CANCEL],[Platform lacks pthread_cancel()]) + +AH_TEMPLATE([ACE_LACKS_PWD_FUNCTIONS], +[Platform lacks, getpwnam(), etc.]) + +AH_TEMPLATE([ACE_LACKS_PWD_REENTRANT_FUNCTIONS], +[Platform lacks getpwnam_r() methods (e.g., SGI 6.2).]) + +AH_TEMPLATE([ACE_LACKS_RWLOCK_T],[Platform lacks readers/writer locks.]) + +AH_TEMPLATE([ACE_LACKS_SEMBUF_T], +[Platform lacks struct sembuf (e.g., Win32 and VxWorks)]) + +AH_TEMPLATE([ACE_LACKS_SETDETACH], +[Platform lacks pthread_attr_setdetachstate() (e.g., HP/UX 10.x)]) + +AH_TEMPLATE([ACE_LACKS_SETSCHED], +[Platform lacks pthread_attr_setsched() (e.g. MVS)]) + +AH_TEMPLATE([ACE_LACKS_SIGACTION], +[Platform lacks struct sigaction (e.g., Win32 and Chorus)]) + +AH_TEMPLATE([ACE_LACKS_SIGNED_CHAR], +[Platform lacks "signed char" type (broken!)]) + +AH_TEMPLATE([ACE_LACKS_SIGSET], +[Platform lacks signal sets (e.g., Chorus and Win32)]) + +AH_TEMPLATE([ACE_LACKS_STRUCT_DIR], +[Platform lacks dirent structure.]) + +AH_TEMPLATE([ACE_LACKS_SYS_MSG_H], +[Platform lacks sys/msg.h (e.g., Chorus and VxWorks)]) + +AH_TEMPLATE([ACE_LACKS_SYSV_MSQ_PROTOS], +[Platform lacks SYSV message queue prototypes]) + +AH_TEMPLATE([ACE_LACKS_SI_ADDR], +[Platform lacks the si_addr field of siginfo_t (e.g., VxWorks and + HP/UX 10.x)]) + +AH_TEMPLATE([ACE_LACKS_SYSV_SHMEM], +[Platform lacks System V shared memory (e.g., Win32 and VxWorks)]) + +AH_TEMPLATE([ACE_LACKS_SOCKET_BUFSIZ], +[Platform doesn't support SO_SNDBUF/SO_RCVBUF (used in TAO)]) + +AH_TEMPLATE([ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES], +[Compiler doesn't support static data member templates]) + +AH_TEMPLATE([ACE_LACKS_STRRECVFD],[Platform doesn't define struct strrecvfd.]) + +AH_TEMPLATE([ACE_LACKS_T_ERRNO],[Header files lack t_errno for TLI]) + +AH_TEMPLATE([ACE_LACKS_TCP_NODELAY],[OS does not support TCP_NODELAY]) + +AH_TEMPLATE([ACE_LACKS_THREAD_PROCESS_SCOPING], +[Platform lacks pthread_attr_setscope()]) + +AH_TEMPLATE([ACE_LACKS_TIMESPEC_T], +[Platform does not define timepec_t as a typedef for struct timespec.]) + +AH_TEMPLATE([ACE_LACKS_STRTOK_R_PROTOTYPE], +[Platform/compiler lacks the strtok_r() prototype]) + +AH_TEMPLATE([ACE_LACKS_LSEEK64_PROTOTYPE], +[Platform/compiler lacks the lseek64() prototype. This should not + be defined if ACE_LACKS_LLSEEK_PROTOTYPE is defined.]) + +AH_TEMPLATE([ACE_LACKS_LLSEEK_PROTOTYPE], +[Platform/compiler lacks the llseek() prototype. This should not + be defined if ACE_LACKS_LSEEK64_PROTOTYPE is defined.]) + +AH_TEMPLATE([ACE_LACKS_PREAD_PROTOTYPE], +[Platform/compiler lacks the pread() and pwrite() prototypes]) + +AH_TEMPLATE([ACE_LACKS_CHAR_RIGHT_SHIFTS], +[Compiler does not have any istream operator>> for chars, u_chars, or + signed chars.]) + +AH_TEMPLATE([ACE_LACKS_CHAR_STAR_RIGHT_SHIFTS], +[Compiler does not have operator>> (istream &, u_char *) or + operator>> (istream &, signed char *)]) + +AH_TEMPLATE([ACE_LACKS_NUMERIC_LIMITS],[Platform lacks std::numeric_limits<>]) + +AH_TEMPLATE([ACE_LACKS_UNIX_DOMAIN_SOCKETS], +[ACE platform has no UNIX domain sockets]) + +AH_TEMPLATE([ACE_LACKS_UNIX_SIGNALS], +[Platform lacks full signal support (e.g., Win32 and Chorus).]) + +AH_TEMPLATE([ACE_LACKS_UTSNAME_T], +[Platform lacks struct utsname (e.g., Win32 and VxWorks)]) + +AH_TEMPLATE([ACE_MAIN], +[Renames "main (int, char *[])", for platforms such as g++/VxWorks + that don't allow main. Requires the use of + ACE_HAS_NONSTATIC_OBJECT_MANAGER.]) + +AH_TEMPLATE([ACE_MT_SAFE],[Compile using multi-thread libraries]) + +AH_TEMPLATE([ACE_NDEBUG],[Turns off debugging features]) + +AH_TEMPLATE([ACE_NEEDS_DEV_IO_CONVERSION], +[Necessary with some compilers to pass ACE_TTY_IO as parameter to + DEV_Connector.]) + +AH_TEMPLATE([ACE_NEEDS_HUGE_THREAD_STACKSIZE], +[Required by platforms with small default stacks.]) + +AH_TEMPLATE([ACE_NEEDS_LWP_PRIO_SET], +[OS has LWPs, and when the priority of a bound thread is set, then + the LWP priority must be set also.]) + +AH_TEMPLATE([ACE_NEEDS_SCHED_H], +[Platform needs to #include to get thread scheduling defs.]) + +AH_TEMPLATE([ACE_NEW_THROWS_EXCEPTIONS], +[Compiler's 'new' throws exception on failure (ANSI C++ behavior).]) + +AH_TEMPLATE([ACE_NLOGGING], +[Turns off the LM_DEBUG and LM_ERROR logging macros...]) + +AH_TEMPLATE([ACE_NTRACE],[Turns off the tracing feature.]) + +AH_TEMPLATE([ACE_PAGE_SIZE], +[Defines the page size of the system (not used on Win32 or with + ACE_HAS_GETPAGESIZE).]) + +AH_TEMPLATE([ACE_REDEFINES_XTI_FUNCTIONS], +[Platform redefines the t_... names (UnixWare)]) + +AH_TEMPLATE([ACE_TEMPLATES_REQUIRE_PRAGMA], +[Compiler's template mechanism must use a pragma. This is used for + AIX's C++ compiler.]) + +AH_TEMPLATE([ACE_TEMPLATES_REQUIRE_SOURCE], +[Compiler's template mechanim must see source code (i.e., .cpp + files). This is used for GNU G++.]) + +AH_TEMPLATE([ACE_HAS_ICMP_SUPPORT], +[Defined to 1 if platform supports ICMP over raw sockets]) + +AH_TEMPLATE([ACE_NEEDS_FUNC_DEFINITIONS], +[Compiler requires a definition for a "hidden" function, e.g., a + private, unimplemented copy constructor or assignment operator. + The SGI C++ compiler needs this, in template classes, with + ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA.]) + +AH_TEMPLATE([ACE_TLI_TCP_DEVICE], +[Device the platform uses for TCP on TLI. Only needed if not + /dev/tcp.]) + +AH_TEMPLATE([ACE_USE_POLL], +[The OS/platform supports the poll() event demultiplexor]) + +AH_TEMPLATE([ACE_HAS_EVENT_POLL],[Platform (Linux) supports event poll + interface.]) + +AH_TEMPLATE([ACE_HAS_DEV_POLL],[Platform supports /dev/poll character + device.]) + +AH_TEMPLATE([ACE_USES_ASM_SYMBOL_IN_DLSYM], +[Platform uses assembly symbols instead of C symbols in dlsym()]) + +AH_TEMPLATE([ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB], +[Platform has its standard C++ library in the namespace std.]) + +dnl DSO/DLL export macros. +AH_TEMPLATE([ACE_HAS_CUSTOM_EXPORT_MACROS], +[Platform defines custom DSO/DLL symbol export macros.]) + +AH_TEMPLATE([ACE_Proper_Export_Flag], +[Flag that denotes the symbol should be exported from the DSO/DLL.]) + +AH_TEMPLATE([ACE_Proper_Import_Flag], +[Flag that denotes the symbol should be imported from the DSO/DLL.]) + +dnl ACE_EXPORT_SINGLETON_DECLARATION(T) +dnl ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +dnl ACE_IMPORT_SINGLETON_DECLARATION(T) +dnl ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) + +]) dnl End ACE_PREP_CONFIG_HEADER diff --git a/dep/ACE_wrappers/m4/pkg.m4 b/dep/ACE_wrappers/m4/pkg.m4 new file mode 100644 index 000000000..cbb46dbf8 --- /dev/null +++ b/dep/ACE_wrappers/m4/pkg.m4 @@ -0,0 +1,156 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant . +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [$4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/dep/ACE_wrappers/m4/platform.m4 b/dep/ACE_wrappers/m4/platform.m4 new file mode 100644 index 000000000..f5f1f04b6 --- /dev/null +++ b/dep/ACE_wrappers/m4/platform.m4 @@ -0,0 +1,545 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: platform.m4 82266 2008-07-08 16:09:00Z jtc $ +dnl +dnl platform.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl that set/determine which known platform specific C++ macros +dnl to define. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2000, 2002, 2003 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +dnl Check for thread related libraries and compiler flags +dnl Usage: ACE_SET_PLATFORM_MACROS +AC_DEFUN([ACE_SET_PLATFORM_MACROS], +[ +dnl Begin ACE_SET_PLATFORM_MACROS + +dnl At some point the below platform specific settings should be +dnl automated as much as possible! We set things manually just to get +dnl things going with the auto{conf,make}/libtool integration into the +dnl ACE source tree. + +dnl Platform specific flags +case "$host" in + *aix3*) + AC_DEFINE([AIX]) + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + ;; + *aix4.1*) + AC_DEFINE([AIX]) + dnl Use BSD 4.4 socket definitions for pre-AIX 4.2. The _BSD + dnl setting also controls the data type used for waitpid(), + dnl wait(), and wait3(). + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_BSD=44" + dnl pre-AIX 4.3 requires _BSD_INCLUDES + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_BSD_INCLUDES" + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + ;; + *aix4.2*) + AC_DEFINE([AIX]) + dnl pre-AIX 4.3 requires _BSD_INCLUDES + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_BSD_INCLUDES" + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + AC_DEFINE([ACE_TLI_TCP_DEVICE], ["/dev/xti/tcp"]) + ;; + *aix*) + AC_DEFINE([AIX]) + ;; +dnl /* Cray specific configuration parameters */ +dnl /* +dnl * The following predefined macros are used within ACE ifdefs. +dnl * These are defined when using the Cray compilers. _CRAYMPP +dnl * is defined, for example, if you are running on a Cray T3E +dnl * massively parallel machine. Moreover, in the case of the T3E, +dnl * _CRAYT3E will be defined. This is used to determine the +dnl * ACE_SIZEOF defines for primitive types. +dnl * +dnl * _UNICOS is defined as either the major version of UNICOS being run, +dnl * e.g. 9 or 10 on the vector machines (e.g. C90, T90, J90, YMP, ...) +dnl * or the major+minor+level UNICOS/mk version, e.g. 2.0.3 => 203, +dnl * being run on an MPP machine. +dnl * +dnl * Summary: +dnl * +dnl * _CRAYMPP (defined only if running on MPP machine, e.g. T3E, UNICOS/mk) +dnl * _CRAYT3E (defined specifically if compiling on a Cray T3E) +dnl * _UNICOS (defined if running UNICOS or UNICOS/mk) +dnl * +dnl * Tested on UNICOS 10.0.0.2, UNICOS/mk 2.0.3.10 +dnl * +dnl * Contributed by Doug Anderson +dnl */ + t3e-cray-unicosmk*) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_CRAYMPP -D_CRAYT3E -D_UNICOS" + ;; + t3e-cray*) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_CRAYT3E -D_UNICOS" + ;; + *cray-unicos*) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_UNICOS" + ;; + *hpux9*) + AC_DEFINE([HPUX]) + ;; + *hpux10*) + AC_DEFINE([HPUX]) + AC_DEFINE([HPUX_10]) + dnl _HPUX_SOURCE : Enable HP-UX specific features in platform headers + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_HPUX_SOURCE" + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + AC_DEFINE([ACE_TLI_TCP_DEVICE], ["/dev/inet_cots"]) + ;; + *hpux11*) + AC_DEFINE([HPUX]) + AC_DEFINE([HPUX_11]) + AC_EGREP_CPP([ACE_ON_64BIT_HP], + [ +#ifdef __LP64__ + ACE_ON_64BIT_HP +#endif + ], + [ + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x0000001100000000)]) + AC_DEFINE([ACE_DEFAULT_BASE_ADDRL], [((char *) 0x0000001100000000)]) + ], + [ + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + ]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + ;; + *irix5.2*) + AC_DEFINE([IRIX5]) + ;; + *irix5.3*) + AC_DEFINE([IRIX5]) + if test "$GXX" = no; then + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_BSD_TYPES" + fi + ;; + *irix6*) + AC_DEFINE([IRIX6]) + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) (1024U * 1024 * 1024))]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + dnl _MODERN_C_ : Enable modern features in SGI C++ compiler + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_SGI_MP_SOURCE -D_MODERN_C_" + + case "$host" in + *irix6.2*) + dnl Recent versions of IRIX do not appear to require this macro. + if test "$ace_user_enable_threads" = yes; then + AC_DEFINE([ACE_HAS_IRIX62_THREADS]) + fi + ;; + esac + ;; + *linux*) + AC_DEFINE([ACE_DEFAULT_MAX_SOCKET_BUFSIZ], [65535]) + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + AC_DEFINE([ACE_HAS_BIG_FD_SET]) dnl FIXME: We need a test for this! + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + dnl Does this box have NPTL? + NPTL=`getconf GNU_LIBPTHREAD_VERSION | $AWK '{print [$][1]}' -` + if test "$NPTL" != NPTL; then + ACE_CPPFLAGS="$ACE_CPPFLAGS -DACE_LACKS_LINUX_NPTL" + fi + ;; + *lynxos*) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_POSIX_THREADS_CALLS" + AC_DEFINE([__NO_INCLUDE_WARN__]) + AC_DEFINE([ACE_MALLOC_ALIGN], [8]) + AC_DEFINE([ACE_MAP_PRIVATE], [ACE_MAP_SHARED]) + AC_DEFINE([ACE_HAS_LYNXOS_SIGNALS]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + ;; + *mvs*) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_ALL_SOURCE" + ;; + *osf3.2*) + AC_EGREP_CPP([ACE_DEC_CXX], + [ +#if defined(__DECCXX) + ACE_DEC_CXX +#endif + ], + [ + AC_DEFINE([DEC_CXX]) + ],) + ;; + *osf4.0*) +dnl We need to add checks for g++, DEC C++ and Rational C++ + AC_EGREP_CPP([ACE_DEC_CXX], + [ +#if defined(__DECCXX) + ACE_DEC_CXX +#endif + ], + [ + AC_DEFINE([DEC_CXX]) + ],) +dnl Check for _POSIX_C_SOURCE macro + AC_EGREP_CPP([ACE_ON_DEC_WITH_POS_SRC], + [ + /* Include unistd.h to define _POSIX_C_SOURCE. */ +#ifndef ACE_LACKS_UNISTD_H +# include +#endif + +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199506L) + ACE_ON_DEC_WITH_POS_SRC +#endif + ], + [ + AC_DEFINE([DIGITAL_UNIX]) + ],) + AC_DEFINE([ACE_DEFAULT_BASE_ADDR], [((char *) 0x80000000)]) + AC_DEFINE([ACE_NEEDS_HUGE_THREAD_STACKSIZE], [(1024 * 1024)]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + ;; + *sco4.2*) + AC_DEFINE([SCO]) + AC_DEFINE([ACE_DEFAULT_CLOSE_ALL_HANDLES], [0]) + ;; + *sco5*) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_SVID3" + AC_DEFINE([SCO]) + AC_DEFINE([ACE_DEFAULT_CLOSE_ALL_HANDLES], [0]) + AC_DEFINE([ACE_HAS_BIG_FD_SET]) dnl FIXME: We need a test for this! + ;; + *sunos4*) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + ;; + *solaris2.4*) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + AC_DEFINE([ACE_NEEDS_LWP_PRIO_SET]) + ;; + *solaris2.5*) + AC_DEFINE([ACE_MALLOC_ALIGN], [8]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + AC_DEFINE([ACE_NEEDS_LWP_PRIO_SET]) + ;; + *solaris2.6*) + AC_DEFINE([ACE_MALLOC_ALIGN], [8]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + AC_DEFINE([ACE_NEEDS_LWP_PRIO_SET]) + ;; + *solaris2.7*) + AC_DEFINE([ACE_MALLOC_ALIGN], [8]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + AC_DEFINE([ACE_NEEDS_LWP_PRIO_SET]) + ;; + *86*solaris*) + AC_DEFINE([ACE_HAS_X86_STAT_MACROS]) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + AC_DEFINE([ACE_NEEDS_LWP_PRIO_SET]) + ;; + *tandem*) + AC_DEFINE([ACE_TIMER_SKEW], [(1000 * 10)]) + ;; + *unixware2.0*) + AC_DEFINE([UNIXWARE]) + AC_DEFINE([UNIXWARE_2_0]) + ;; + *unixware2.1*) + AC_DEFINE([UNIXWARE]) + AC_DEFINE([UNIXWARE_2_1]) + ;; + *UnixWare7.1*) + AC_DEFINE([UNIXWARE]) + AC_DEFINE([UNIXWARE_7_1]) + AC_DEFINE([__IOCTL_VERSIONED__]) + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_REENTRANT" + ;; + *vxworks*) + AC_DEFINE([VXWORKS]) + AC_DEFINE([ACE_MAIN], [ace_main]) + AC_DEFINE([ACE_DEFAULT_MAX_SOCKET_BUFSIZ], [32768]) + dnl need ACE_HAS_TSS_EMULATION for ACE_DEFAULT_THREAD_KEYS! + AC_EGREP_CPP([ACE_TSS_EMULATION], + [ +#if defined (ACE_HAS_TSS_EMULATION) + ACE_TSS_EMULATION +#endif + ], [AC_DEFINE([ACE_DEFAULT_THREAD_KEYS], [16])],[]) + AC_DEFINE([ACE_THR_PRI_FIFO_DEF], [101]) + ;; + *cygwin32*) + AC_DEFINE([CYGWIN32]) + ;; + *mingw32*) + AC_DEFINE([ACE_WIN32]) + ;; + *win32*) + AC_DEFINE([ACE_WIN32]) +dnl AC_DEFINE(ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) + if test "$ace_u_long_long_typedef_set" != yes; then + ACE_UINT64="unsigned __int64" + ace_u_long_long_typedef_set=yes + fi dnl "$ace_u_long_long_typedef_set" != yes + ;; + *qnx* | *nto* | *neutrino*) + dnl These should be defined on the command line, not in config.h. + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_QNX_SOURCE -D_POSIX_C_SOURCE=199506" + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_POSIX_NAME_MAX=14" # Max bytes in a + # filename + ACE_CPPFLAGS="$ACE_CPPFLAGS -D_POSIX_PATH_MAX=256" # Num. bytes in + # pathname (excl. NULL) + case "$host" in + i[[3456]]86*) + if test "$GXX" = yes; then + # Neutrino defines memcpy as a macro on x86, which then + # hoses the ACE_OS::memcpy() method. Undefining + # __OPTIMIZE__ prevents this from happening. + ACE_CPPFLAGS="$ACE_CPPFLAGS -U__OPTIMIZE__" + fi + ;; + esac + ;; + *) + ;; +esac + +ACE_FUNC_IOCTL_ARGTYPES +ACE_CHECK_GETNAME_RETURNS_RANDOM_SIN_ZERO +ACE_CHECK_HAS_NONCONST_FD_ISSET +ACE_CHECK_FORMAT_SPECIFIERS +ACE_CHECK_LACKS_PERFECT_MULTICAST_FILTERING +ACE_CHECK_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE + +dnl End ACE_SET_PLATFORM_MACROS +]) + + + +# ACE_CHECK_FORMAT_SPECIFIERS +# +# Override default *printf format specifiers for size_t, ssize_t, ACE_INT64, +# and ACE_UINT64 +# +# FIXME: Is it possible to write a portable feature test, or is checking +# the the target OS / target CPU the best we can do? +# +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_FORMAT_SPECIFIERS], +[dnl +AH_TEMPLATE([ACE_SIZE_T_FORMAT_SPECIFIER], +[Define to the *printf format specifier (e.g. "%u") for size_t])dnl +AH_TEMPLATE([ACE_SSIZE_T_FORMAT_SPECIFIER], +[Define to the *printf format specifier (e.g. "%d") for ssize_t])dnl +AH_TEMPLATE([ACE_INT64_FORMAT_SPECIFIER], +[Define to the *printf format specifier (e.g. "%lld") for ACE_INT64])dnl +AH_TEMPLATE([ACE_UINT64_FORMAT_SPECIFIER], +[Define to the *printf format specifier (e.g. "%llu") for ACE_UINT64])dnl + +case "$host_os" in +darwin*) + AC_DEFINE([ACE_SIZE_T_FORMAT_SPECIFIER], ["%lu"]) + ;; + +linux*) + case "$host_cpu" in + alpha|ia64|x86_64) + AC_DEFINE([ACE_SIZE_T_FORMAT_SPECIFIER], ["%lu"]) + AC_DEFINE([ACE_SSIZE_T_FORMAT_SPECIFIER], ["%ld"]) + AC_DEFINE([ACE_INT64_FORMAT_SPECIFIER], ["%ld"]) + AC_DEFINE([ACE_UINT64_FORMAT_SPECIFIER], ["%lu"]) + ;; + *) + ;; + esac + ;; + +mingw32*) + AC_DEFINE([ACE_INT64_FORMAT_SPECIFIER], ["%I64d"]) + AC_DEFINE([ACE_UINT64_FORMAT_SPECIFIER], ["%I64u"]) + ;; + +netbsd*) + case "$host_cpu" in + x86_64) + AC_DEFINE([ACE_SIZE_T_FORMAT_SPECIFIER], ["%lu"]) + AC_DEFINE([ACE_SSIZE_T_FORMAT_SPECIFIER], ["%ld"]) + ;; + *) + ;; + esac + ;; + +win32*) + AC_DEFINE([ACE_INT64_FORMAT_SPECIFIER], ["%I64d"]) + AC_DEFINE([ACE_UINT64_FORMAT_SPECIFIER], ["%I64u"]) + ;; + +*) + ;; +esac]) + + +# ACE_CHECK_PERFECT_MULTICAST_FILTERING +# +# Checks whether platform lacks "perfect" multicast filtering. +# +# FIXME: Is it possible to write a portable feature test, or is checking +# the the target OS the best we can do? +# +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_LACKS_PERFECT_MULTICAST_FILTERING], +[AC_CACHE_CHECK([whether platform lacks perfect multicast filtering], + [ace_cv_lacks_perfect_multicast_filtering], + [case "$host_os" in + darwin* | freebsd* | netbsd* | openbsd* | qnx*) + ace_cv_lacks_perfect_multicast_filtering=yes ;; + *) + ace_cv_lacks_perfect_multicast_filtering=no ;; + esac]) + +if test $ace_cv_lacks_perfect_multicast_filtering = yes; then + AC_DEFINE([ACE_LACKS_PERFECT_MULTICAST_FILTERING], 1, +[Define to 1 if platform lacks IGMPv3 "perfect" filtering of multicast +datagrams at the socket level. If defined, ACE_SOCK_Dgram_Mcast will bind +the first joined multicast group to the socket, and all future joins on that +socket will fail with an error.]) +fi +]) + + +# ACE_FUNC_IOCTL_ARGTYPES +# +# Determine the correct type to be passed to ioctl's second argument and +# define the types in ACE_IOCTL_TYPE_ARG2. +# +# FIXME: Should we support ioctl's third argument as well...? +# +# FIXME: Is it possible to write a portable feature test, or is checking +# the the target OS the best we can do? +# +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_FUNC_IOCTL_ARGTYPES], +[AC_CACHE_CHECK([types of arguments for ioctl()], + [ace_cv_func_ioctl_arg2], + [case "$host_os" in + darwin* | freebsd* | netbsd* | openbsd*) + ace_cv_func_ioctl_arg2="unsigned long" ;; + *) + ace_cv_func_ioctl_arg2="int" ;; + esac]) + +AC_DEFINE_UNQUOTED(ACE_IOCTL_TYPE_ARG2, $ace_cv_func_ioctl_arg2, + [Define to the type of arg 2 for `ioctl'.]) +]) + + +# ACE_VAR_TIMEZONE +# +# Checks whether platform has global "timezone" variable. +# +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_VAR_TIMEZONE], +[AC_CACHE_CHECK([for timezone variable], + [ace_cv_var_timezone], + [AC_TRY_LINK([#include ], + [return (int) timezone(0, 0);], + [ace_cv_var_timezone=no], + [AC_TRY_LINK([#include ], + [return (int) timezone;], + [ace_cv_var_timezone=yes], + [ace_cv_var_timezone=no])]) + ]) +if test "$ace_cv_var_timezone" = yes; then + AC_DEFINE([ACE_HAS_TIMEZONE], 1, + [Define to 1 if platform has global timezone variable]) +fi +]) + + +# ACE_CHECK_GETNAME_RETURNS_RANDOM_SIN_ZERO +# +# Checks whether getsockname() and getpeername() return random values +# in the sockaddr_in.sin_zero field. +# +# FIXME: Is it possible to write a portable feature test, or is checking +# the the target OS the best we can do? +# +AC_DEFUN([ACE_CHECK_GETNAME_RETURNS_RANDOM_SIN_ZERO], +[AC_CACHE_CHECK([whether getsockname() and getpeername() return random values in sockaddr_in.sin_zero], + [ace_cv_getname_returns_random_sin_zero], + [case "$host_os" in + linux*) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include ], + [ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47)) + int ok; + #else + choke me + #endif + ]) + ], + [ace_cv_getname_returns_random_sin_zero=no], + [ace_cv_getname_returns_random_sin_zero=yes]) + ;; + *) + ace_cv_getname_returns_random_sin_zero=no + ;; + esac]) + +if test $ace_cv_getname_returns_random_sin_zero = yes; then + AC_DEFINE([ACE_GETNAME_RETURNS_RANDOM_SIN_ZERO], 1, +[Define to 1 if the getsockname() and getpeername() return random values in the sockaddr_in.sin_zero field.]) +fi +]) + + +# ACE_CHECK_HAS_NONCONST_FD_ISSET +# +# Checks if system has a nonconst FD_ISSET macro. +# +#--------------------------------------------------------------------------- +AC_DEFUN([ACE_CHECK_HAS_NONCONST_FD_ISSET], +[dnl + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include ], + [ + //const fd_set* temp = new fd_set(); + //FD_ISSET(0, const_cast< fd_set* >( temp ) ); + const fd_set* temp = new fd_set(); + FD_ISSET(0, temp ); + ]) + ],[],[AC_DEFINE([ACE_HAS_NONCONST_FD_ISSET], 1, + [Define to 1 if system has nonconst FD_ISSET() macro.])] + ) +]) + +# ACE_CHECK_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE +# +# Checks whether the dlsym() call segfaults when passed an invalid handle. +# +# FIXME: Is it possible to write a portable feature test, or is checking +# the the target OS the best we can do? +# +AC_DEFUN([ACE_CHECK_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE], +[AC_CACHE_CHECK([whether dlsym() segfaults when passed an invalid handle], + [ace_cv_has_dlsym_segfault_on_invalid_handle], + [case "$host_os" in + linux* | openbsd*) + ace_cv_has_dlsym_segfault_on_invalid_handle=yes ;; + *) + ace_cv_has_dlsym_segfault_on_invalid_handle=no;; + esac]) + +if test $ace_cv_has_dlsym_segfault_on_invalid_handle = yes; then + AC_DEFINE([ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE], 1, +[Define to 1 if the dlsym() call segfaults when passed an invalid handle.]) +fi +]) diff --git a/dep/ACE_wrappers/m4/subsets.m4 b/dep/ACE_wrappers/m4/subsets.m4 new file mode 100644 index 000000000..87b2dee7c --- /dev/null +++ b/dep/ACE_wrappers/m4/subsets.m4 @@ -0,0 +1,770 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: subsets.m4 80826 2008-03-04 14:51:23Z wotte $ +dnl +dnl subsets.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl that set/determine which ACE subsets to build. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2001 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +dnl Check for thread related libraries and compiler flags +dnl Usage: ACE_CHECK_SUBSETS +AC_DEFUN([ACE_CHECK_SUBSETS], +[ +dnl Begin ACE_CHECK_SUBSETS + +dnl Assume all subsets will be built, including the full ACE library. +dnl If any of the components is explicitly enabled or disabled by the user +dnl then do NOT build the full ACE library. +AC_ARG_ENABLE([lib-all], + AS_HELP_STRING([--enable-lib-all],[build all ACE components [[no]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_lib_all=yes + ;; + no) + ace_user_enable_lib_all=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-all]) + ;; + esac + ], + [ + ace_user_enable_lib_all=no + ]) + +AC_ARG_ENABLE([lib-full], + AS_HELP_STRING([--enable-lib-full],[build the full ACE library [[yes]]]), + [ + case "${enableval}" in + yes) + ace_user_enable_lib_full=yes + ;; + no) + ace_user_enable_lib_full=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-full]) + ;; + esac + ], + [ + ace_user_enable_lib_full=yes + ]) + +AC_ARG_ENABLE([lib-os], + AS_HELP_STRING([--enable-lib-os],[build ACE_OS library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_OS + ;; + no) + ace_user_enable_lib_os=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-os]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-codecs], + AS_HELP_STRING([--enable-lib-codecs],[build ACE_Codecs library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_CODECS + ;; + no) + ace_user_enable_lib_codecs=no + AC_DEFINE([ACE_LACKS_ACE_CODECS]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-codecs]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-connection], + AS_HELP_STRING([--enable-lib-connection],[build ACE_Connection library ]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_CONNECTION + ;; + no) + ace_user_enable_lib_connection=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-connection]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-demux], + AS_HELP_STRING([--enable-lib-demux],[build ACE_Demux library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_DEMUX + ;; + no) + ace_user_enable_lib_demux=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-demux]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-filecache], + AS_HELP_STRING([--enable-lib-filecache],[build ACE_Filecache library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_FILECACHE + ;; + no) + ace_user_enable_lib_filecache=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-filecache]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-ipc], + AS_HELP_STRING([--enable-lib-ipc],[build ACE_IPC library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_IPC + ;; + no) + ace_user_enable_lib_ipc=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-ipc]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-logging], + AS_HELP_STRING([--enable-lib-logging],[build ACE_Logging library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_LOGGING + ;; + no) + ace_user_enable_lib_logging=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-logging]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-memory], + AS_HELP_STRING([--enable-lib-memory],[build ACE_Memory library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_MEMORY + ;; + no) + ace_user_enable_lib_memory=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-memory]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-metrics], + AS_HELP_STRING([--enable-lib-metrics],[build ACE_Metrics library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_METRICS + ;; + no) + ace_user_enable_lib_metrics=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-metrics]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-sockets], + AS_HELP_STRING([--enable-lib-sockets],[build ACE_Sockets library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_SOCKETS + ;; + no) + ace_user_enable_lib_sockets=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-sockets]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-streams], + AS_HELP_STRING([--enable-lib-streams],[build ACE_Streams library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_STREAMS + ;; + no) + ace_user_enable_lib_streams=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-streams]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-svcconf], + AS_HELP_STRING([--enable-lib-svcconf],[build ACE_Svcconf library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_SVCCONF + ;; + no) + ace_user_enable_lib_svcconf=no + AC_DEFINE([ACE_LACKS_ACE_SVCCONF]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-svcconf]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-threads], + AS_HELP_STRING([--enable-lib-threads],[build ACE_Threads library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_THREADS + ;; + no) + ace_user_enable_lib_threads=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-threads]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-timer], + AS_HELP_STRING([--enable-lib-timer],[build ACE_Timer library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_TIMER + ;; + no) + ace_user_enable_lib_timer=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-timer]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-token], + AS_HELP_STRING([--enable-lib-token],[build ACE_Token library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_TOKEN + ;; + no) + ace_user_enable_lib_token=no + AC_DEFINE([ACE_LACKS_ACE_TOKEN]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-token]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-utils], + AS_HELP_STRING([--enable-lib-utils],[build ACE_Utils library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_UTILS + ;; + no) + ace_user_enable_lib_utils=no + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-utils]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-uuid], + AS_HELP_STRING([--enable-lib-uuid],[build ACE_UUID library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_UUID + ;; + no) + ace_user_enable_lib_uuid=no + AC_DEFINE([ACE_LACKS_ACE_UUID]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-uuid]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + +AC_ARG_ENABLE([lib-other], + AS_HELP_STRING([--enable-lib-other],[build ACE_Other library]), + [ + case "${enableval}" in + yes) + ACE_CREATE_LIBACE_OTHER + ;; + no) + ace_user_enable_lib_other=no + AC_DEFINE([ACE_LACKS_ACE_OTHER]) + ;; + *) + AC_MSG_ERROR([bad value ${enableval} for --enable-lib-other]) + ;; + esac + + dnl Disable full ACE library build + ace_user_enable_lib_full=no + ],) + + +dnl If no ACE subsets were explicitly enabled or disabled then build +dnl all of them. +if test $ace_user_enable_lib_all = yes; then + + ACE_CREATE_ALL_COMPONENTS + +elif test $ace_user_enable_lib_all = no; then + + ACE_DISABLE_ALL_COMPONENTS + +fi + +if test $ace_user_enable_lib_full = no && + test $ace_user_enable_lib_os = no && + test $ace_user_enable_lib_codecs = no && + test $ace_user_enable_lib_connection = no && + test $ace_user_enable_lib_demux = no && + test $ace_user_enable_lib_filecache = no && + test $ace_user_enable_lib_ipc = no && + test $ace_user_enable_lib_logging = no && + test $ace_user_enable_lib_memory = no && + test $ace_user_enable_lib_metrics = no && + test $ace_user_enable_lib_threads = no && + test $ace_user_enable_lib_sockets = no && + test $ace_user_enable_lib_svcconf = no && + test $ace_user_enable_lib_streams = no && + test $ace_user_enable_lib_timer = no && + test $ace_user_enable_lib_token = no && + test $ace_user_enable_lib_utils = no && + test $ace_user_enable_lib_uuid = no && + test $ace_user_enable_lib_other = no; then + + dnl If we get here then no ACE libraries will be built! + AC_MSG_ERROR([No ACE components will be built. Specify which components to build.]) + +fi dnl No components will be built! + +dnl Set which ACE subsets to build +AM_CONDITIONAL(BUILD_OS_FILES, + test X$ace_user_enable_lib_os = Xyes) + +AM_CONDITIONAL(BUILD_CODECS_FILES, + test X$ace_user_enable_lib_codecs = Xyes) + +AM_CONDITIONAL(BUILD_CONNECTION_FILES, + test X$ace_user_enable_lib_connection = Xyes) + +AM_CONDITIONAL(BUILD_DEMUX_FILES, + test X$ace_user_enable_lib_demux = Xyes) + +AM_CONDITIONAL(BUILD_FILECACHE_FILES, + test X$ace_user_enable_lib_filecache = Xyes) + +AM_CONDITIONAL(BUILD_IPC_FILES, + test X$ace_user_enable_lib_ipc = Xyes) + +AM_CONDITIONAL(BUILD_LOGGING_FILES, + test X$ace_user_enable_lib_logging = Xyes) + +AM_CONDITIONAL(BUILD_MEMORY_FILES, + test X$ace_user_enable_lib_memory = Xyes) + +AM_CONDITIONAL(BUILD_METRICS_FILES, + test X$ace_user_enable_lib_metrics = Xyes) + +AM_CONDITIONAL(BUILD_SOCKETS_FILES, + test X$ace_user_enable_lib_sockets = Xyes) + +AM_CONDITIONAL(BUILD_STREAMS_FILES, + test X$ace_user_enable_lib_streams = Xyes) + +AM_CONDITIONAL(BUILD_SVCCONF_FILES, + test X$ace_user_enable_lib_svcconf = Xyes) + +AM_CONDITIONAL(BUILD_THREADS_FILES, + test X$ace_user_enable_lib_threads = Xyes) + +AM_CONDITIONAL(BUILD_TIMER_FILES, + test X$ace_user_enable_lib_timer = Xyes) + +AM_CONDITIONAL(BUILD_TOKEN_FILES, + test X$ace_user_enable_lib_token = Xyes) + +AM_CONDITIONAL(BUILD_UTILS_FILES, + test X$ace_user_enable_lib_utils = Xyes) + +AM_CONDITIONAL(BUILD_UUID_FILES, + test X$ace_user_enable_lib_uuid = Xyes) + +AM_CONDITIONAL(BUILD_OTHER_FILES, + test X$ace_user_enable_lib_other = Xyes) + +AM_CONDITIONAL(BUILD_FULL_LIBRARY, + test X$ace_user_enable_lib_full = Xyes) + +dnl End ACE_CHECK_SUBSETS +]) + +dnl Set the component dependencies for the libACE_OS library +dnl Usage: ACE_CREATE_LIBACE_OS +AC_DEFUN([ACE_CREATE_LIBACE_OS], +[ + ace_user_enable_lib_os=yes +]) + +dnl Set the component dependencies for the libACE_Utils library +dnl Usage: ACE_CREATE_LIBACE_UTILS +AC_DEFUN([ACE_CREATE_LIBACE_UTILS], +[ + ace_user_enable_lib_utils=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_UUID library +dnl Usage: ACE_CREATE_LIBACE_UUID +AC_DEFUN([ACE_CREATE_LIBACE_UUID], +[ + ace_user_enable_lib_uuid=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Filecache library +dnl Usage: ACE_CREATE_LIBACE_FILECACHE +AC_DEFUN([ACE_CREATE_LIBACE_FILECACHE], +[ + ace_user_enable_lib_filecache=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Logging library +dnl Usage: ACE_CREATE_LIBACE_LOGGING +AC_DEFUN([ACE_CREATE_LIBACE_LOGGING], +[ + ace_user_enable_lib_logging=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Metrics library +dnl Usage: ACE_CREATE_LIBACE_METRICS +AC_DEFUN([ACE_CREATE_LIBACE_METRICS], +[ + ace_user_enable_lib_metrics=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Threads library +dnl Usage: ACE_CREATE_LIBACE_THREADS +AC_DEFUN([ACE_CREATE_LIBACE_THREADS], +[ + ace_user_enable_lib_threads=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Demux library +dnl Usage: ACE_CREATE_LIBACE_DEMUX +AC_DEFUN([ACE_CREATE_LIBACE_DEMUX], +[ + ace_user_enable_lib_demux=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_THREADS +]) + +dnl Set the component dependencies for the libACE_Connection library +dnl Usage: ACE_CREATE_LIBACE_CONNECTION +AC_DEFUN([ACE_CREATE_LIBACE_CONNECTION], +[ + ace_user_enable_lib_connection=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_THREADS + ACE_CREATE_LIBACE_DEMUX +]) + +dnl Set the component dependencies for the libACE_Sockets library +dnl Usage: ACE_CREATE_LIBACE_SOCKETS +AC_DEFUN([ACE_CREATE_LIBACE_SOCKETS], +[ + ace_user_enable_lib_sockets=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_IPC library +dnl Usage: ACE_CREATE_LIBACE_IPC +AC_DEFUN([ACE_CREATE_LIBACE_IPC], +[ + ace_user_enable_lib_ipc=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_SOCKETS +]) + +dnl Set the component dependencies for the libACE_Svcconf library +dnl Usage: ACE_CREATE_LIBACE_SVCCONF +AC_DEFUN([ACE_CREATE_LIBACE_SVCCONF], +[ + ace_user_enable_lib_svcconf=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_THREADS + ACE_CREATE_LIBACE_DEMUX + ACE_CREATE_LIBACE_SOCKETS +]) + +dnl Set the component dependencies for the libACE_Streams library +dnl Usage: ACE_CREATE_LIBACE_STREAMS +AC_DEFUN([ACE_CREATE_LIBACE_STREAMS], +[ + ace_user_enable_lib_streams=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_THREADS + ACE_CREATE_LIBACE_DEMUX +]) + +dnl Set the component dependencies for the libACE_Memory library +dnl Usage: ACE_CREATE_LIBACE_MEMORY +AC_DEFUN([ACE_CREATE_LIBACE_MEMORY], +[ + ace_user_enable_lib_memory=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Timer library +dnl Usage: ACE_CREATE_LIBACE_TIMER +AC_DEFUN([ACE_CREATE_LIBACE_TIMER], +[ + ace_user_enable_lib_timer=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Token library +dnl Usage: ACE_CREATE_LIBACE_TOKEN +AC_DEFUN([ACE_CREATE_LIBACE_TOKEN], +[ + ace_user_enable_lib_token=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_UTILS + ACE_CREATE_LIBACE_LOGGING + ACE_CREATE_LIBACE_THREADS + ACE_CREATE_LIBACE_DEMUX + ACE_CREATE_LIBACE_CONNECTION + ACE_CREATE_LIBACE_SOCKETS + ACE_CREATE_LIBACE_IPC + ACE_CREATE_LIBACE_SVCCONF + ACE_CREATE_LIBACE_STREAMS + ACE_CREATE_LIBACE_MEMORY + dnl ACE_CREATE_LIBACE_OTHER +]) + +dnl Set the component dependencies for the libACE_Codecs library +dnl Usage: ACE_CREATE_LIBACE_CODECS +AC_DEFUN([ACE_CREATE_LIBACE_CODECS], +[ + ace_user_enable_lib_codecs=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS +]) + +dnl Set the component dependencies for the libACE_Other library +dnl Usage: ACE_CREATE_LIBACE_OTHER +AC_DEFUN([ACE_CREATE_LIBACE_OTHER], +[ + ace_user_enable_lib_other=yes + + dnl Be careful not to go into a circular/recursive loop with these macros! + ACE_CREATE_LIBACE_OS + ACE_CREATE_LIBACE_UTILS + ACE_CREATE_LIBACE_LOGGING + ACE_CREATE_LIBACE_THREADS + ACE_CREATE_LIBACE_DEMUX + ACE_CREATE_LIBACE_CONNECTION + ACE_CREATE_LIBACE_SOCKETS + ACE_CREATE_LIBACE_IPC + ACE_CREATE_LIBACE_SVCCONF + ACE_CREATE_LIBACE_STREAMS + ACE_CREATE_LIBACE_MEMORY + dnl ACE_CREATE_LIBACE_TOKEN +]) + +dnl Build all ACE component libraries +dnl Usage: ACE_CREATE_ALL_COMPONENTS +AC_DEFUN([ACE_CREATE_ALL_COMPONENTS], +[ + ace_user_enable_lib_os=yes + ace_user_enable_lib_codecs=yes + ace_user_enable_lib_connection=yes + ace_user_enable_lib_demux=yes + ace_user_enable_lib_filecache=yes + ace_user_enable_lib_ipc=yes + ace_user_enable_lib_logging=yes + ace_user_enable_lib_memory=yes + ace_user_enable_lib_metrics=yes + ace_user_enable_lib_sockets=yes + ace_user_enable_lib_streams=yes + ace_user_enable_lib_svcconf=yes + ace_user_enable_lib_threads=yes + ace_user_enable_lib_timer=yes + ace_user_enable_lib_token=yes + ace_user_enable_lib_utils=yes + ace_user_enable_lib_uuid=yes + ace_user_enable_lib_other=yes +]) + +dnl Disable all ACE component libraries +dnl Usage: ACE_CREATE_ALL_COMPONENTS +AC_DEFUN([ACE_DISABLE_ALL_COMPONENTS], +[ + ace_user_enable_lib_os=no + ace_user_enable_lib_codecs=no + ace_user_enable_lib_connection=no + ace_user_enable_lib_demux=no + ace_user_enable_lib_filecache=no + ace_user_enable_lib_ipc=no + ace_user_enable_lib_logging=no + ace_user_enable_lib_memory=no + ace_user_enable_lib_metrics=no + ace_user_enable_lib_sockets=no + ace_user_enable_lib_streams=no + ace_user_enable_lib_svcconf=no + ace_user_enable_lib_threads=no + ace_user_enable_lib_timer=no + ace_user_enable_lib_token=no + ace_user_enable_lib_utils=no + ace_user_enable_lib_uuid=no + ace_user_enable_lib_other=no +]) diff --git a/dep/ACE_wrappers/m4/threads.m4 b/dep/ACE_wrappers/m4/threads.m4 new file mode 100644 index 000000000..f8b2058d9 --- /dev/null +++ b/dep/ACE_wrappers/m4/threads.m4 @@ -0,0 +1,334 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: threads.m4 80826 2008-03-04 14:51:23Z wotte $ +dnl +dnl threads.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl for configuring thread support. This file is to be used +dnl with the configure script. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 1998, 1999, 2002 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +dnl Make sure thread library exists +dnl We need to be careful when tests for other thread libraries are +dnl added that we don't screw up handling of "ace_user_enable_threads" +dnl Tests should probably be more platform specific later on. + +dnl Check for thread related libraries and compiler flags +dnl Usage: ACE_CHECK_THREADS +AC_DEFUN([ACE_CHECK_THREADS], +[ +dnl AC_REQUIRE([AC_PROG_CXX]) +dnl AC_REQUIRE([AC_PROG_CXXCPP]) +dnl AC_LANG([C++]) +dnl AC_REQUIRE([AC_LANG]) + + dnl Check if compiler accepts specific flag to enable threads + ACE_CACHE_CHECK([if compiler may need a command line thread flag], + [ace_cv_feature_may_need_thread_flag], + [ + ace_save_CXXFLAGS="$CXXFLAGS" + + ACE_CHECK_THREAD_FLAGS( + [ + ace_cv_feature_may_need_thread_flag=no + ], + [ + ace_cv_feature_may_need_thread_flag=yes + ]) + dnl Reset the flags to a consistent state. + dnl This prevents duplicate flags from being added to + dnl the C/CXXFLAGS variable. + CXXFLAGS="$ace_save_CXXFLAGS" + ], + [ + dnl The compiler/platform has no thread support linked in by default + dnl so search for a usable compiler flag to enable thread support. + dnl If no thread flag is found then the remaining tests should still + dnl figure out how to enable thread support via library checks. + ACE_SEARCH_THREAD_FLAGS( + [mt pthread pthreads mthreads threads Kthread kthread -thread_safe],,) + dnl NOTE: "-thread_safe" is correct, not "thread_safe." + dnl KAI C++ uses the flag "--thread_safe" which is why + dnl "-thread_safe" is passed as the flag to test. + ], + [ + dnl Do nothing + ]) + + dnl Check for UNIX International Threads (ACE calls this STHREADS) + dnl This used to check for thr_create(), but AIX has a semi-functional + dnl UI Threads capability that includes thr_create(). We don't want to + dnl find such a half-hearted UI Threads, so this was changed to look for + dnl a UI Threads function that AIX doesn't offer. + AS_IF([test "$ace_user_enable_uithreads" = yes], + [ AC_MSG_CHECKING([for UNIX International threads capability]) + AC_SEARCH_LIBS([mutex_lock], [thread], + [ + ace_has_sthreads=yes + AC_DEFINE([ACE_HAS_STHREADS], 1, + [Define to 1 if platform has UNIX International Threads]) + ], + [ + ace_has_sthreads=no + ]) + dnl Sometimes thr_create is actually found with explicitly linking against + dnl -lthread, so try a more "exotic" function. + AC_SEARCH_LIBS([rwlock_destroy], [thread],[],[]) + AC_MSG_RESULT([$ace_has_sthreads]) + ],[]) + + dnl Check if any thread related preprocessor flags are needed. + ACE_CHECK_THREAD_CPPFLAGS + + dnl Check for POSIX threads + ace_has_pthreads=no + AS_IF([test "$ace_user_enable_pthreads" = yes], + [ AC_MSG_CHECKING([for POSIX threads library]) + ACE_CHECK_POSIX_THREADS( + [ + ace_has_pthreads=yes + AC_DEFINE([ACE_HAS_PTHREADS], 1, + [Define to 1 if platform has POSIX threads]) + AC_MSG_RESULT([none required]) + ], + []) + + AS_IF([test "$ace_has_pthreads" != yes], + [ + ace_posix_threads_search_LIBS="$LIBS" + for ace_p in pthread pthreads c_r gthreads; do + LIBS="-l$ace_p $ace_posix_threads_search_LIBS" + ACE_CHECK_POSIX_THREADS( + [ + ace_has_pthreads=yes + AC_DEFINE([ACE_HAS_PTHREADS]) + AC_MSG_RESULT([-l$ace_p]) + break + ], + []) + done + + AS_IF([test "$ace_has_pthreads" != yes], + [ + AC_MSG_RESULT([no]) + LIBS="$ace_posix_threads_search_LIBS" + ],[]) + ], + []) + ], + [ + AC_MSG_NOTICE([Pthreads disabled by user; not checking for it]) + ]) + + dnl If we don't have any thread library, then disable threading altogether! + AS_IF([test "$ace_has_pthreads" != yes && test "$ace_has_sthreads" != yes], + [ + ace_user_enable_threads=no + ]) +]) + +dnl This macro will check that the current compiler flags do something +dnl useful in terms of thread libraries and/or functions. +dnl Usage: ACE_CHECK_THREAD_FLAGS(ACTION-IF-USABLE [, ACTION-IF-NOT-USABLE]]) +AC_DEFUN([ACE_CHECK_THREAD_FLAGS], +[ + ACE_CONVERT_WARNINGS_TO_ERRORS([ + dnl Check for UI thread support first. + + dnl Because some platforms are brain damaged enough to provide + dnl useless thread function stubs, link tests may succeed despite the + dnl fact the stubs are no-ops. This forces us to use a run-time test + dnl to get around this nuisance by checking the return value of + dnl thr_create(). The cross-compiled case will use a link-time + dnl test, instead. + dnl Furthermore, we need the implementation to be a real one, not + dnl a half-hearted attempt such as that provided on AIX 5. So, we + dnl make sure it can at least work with a mutex. + + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#if ((THR_BOUND & THR_SUSPEND & THR_DETACHED) != 0) +# error This is a silly UI Threads implementation. +#endif + +extern "C" void * +ace_start_func (void *) +{ + mutex_t m; + mutex_init (&m, USYNC_THREAD, NULL); + mutex_lock (&m); + mutex_unlock (&m); + mutex_destroy (&m); + return 0; +} + +int +main () +{ + thread_t tid = 0; + + return thr_create (0, 0, ace_start_func, 0, 0, &tid); +} + ]])], + [$1], + [ + dnl Now check for POSIX thread support. + ACE_CHECK_POSIX_THREADS([$1],[$2]) + + ], + [ + dnl UI threads cross-compiled case + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include + +extern "C" void * +ace_start_func (void *) +{ + return 0; +} + ]], + [[ + thread_t tid = 0; + + (void) thr_create (&tid, 0, ace_start_func, 0); + ]])], + [$1], + [$2]) + ]) + ]) +]) + +dnl Check what compiler thread flag may be used, if any, from the given list. +dnl The flag list is separated by white space. +dnl Usage: ACE_SEARCH_THREAD_FLAGS(THREAD-FLAG-LIST, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +AC_DEFUN([ACE_SEARCH_THREAD_FLAGS], +[ + AC_LANG([C++]) + AC_REQUIRE([AC_LANG]) + + ACE_CACHE_CHECK([for compiler thread flag], + [ace_cv_thread_flag_search], + [ + ace_save_CXXFLAGS="$CXXFLAGS" + + for i in $1; do + CXXFLAGS="$CXXFLAGS -$i" + + ACE_CHECK_THREAD_FLAGS( + [ + ace_cv_thread_flag_search="-$i" + + dnl A usable flag was found so break out of the loop. + break; + ], + [ + ace_cv_thread_flag_search=no + ]) + + dnl Reset the flags for the next flag check. + CXXFLAGS="$ace_save_CXXFLAGS" + done + + dnl Reset the flags to a consistent state. + dnl This prevents duplicate flags from being added to + dnl the CCXXFLAGS variable. + CXXFLAGS="$ace_save_CXXFLAGS" + ], + [ + dnl Add the found/cached thread flag to the C/CXXFLAGS variables + CXXFLAGS="$CXXFLAGS $ace_cv_thread_flag_search" + + $2 + ], + [ + $3 + ]) +]) + + +dnl Check if the compiler defines thread related preprocessor flags. +dnl If not, then provide them. +dnl Usage: ACE_CHECK_THREAD_CPPFLAGS +AC_DEFUN([ACE_CHECK_THREAD_CPPFLAGS], +[ + dnl A compile-time test is used instead of a preprocesse-time test + dnl because compiler thread flags defined in CFLAGS or CXXFLAGS + dnl should be used for this test. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if !defined (_REENTRANT) && !defined (_THREAD_SAFE) +#error Neither _REENTRANT nor _THREAD_SAFE were defined. +THROW ME AN ERROR! +#endif + ]], [[ + int a = 0; a++; + ]])],[ + ACE_THR_CPPFLAGS= + ],[ + ACE_THR_CPPFLAGS="-D_REENTRANT -D_THREAD_SAFE" + ]) +]) + +dnl Check for POSIX threads support. +dnl Usage: ACE_CHECK_POSIX_THREADS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +AC_DEFUN([ACE_CHECK_POSIX_THREADS], +[ + dnl Because some platforms are brain damaged enough to provide + dnl useless thread function stubs, link tests may succeed despite the + dnl fact the stubs are no-ops. This forces us to use a run-time test + dnl to get around this nuisance by checking the return value of + dnl pthread_create(). The cross-compiled case will use a link-time + dnl test, instead. + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include + +extern "C" void * +ace_start_func (void *) +{ + return 0; +} + +int +main () +{ + pthread_t tid = 0; + + return pthread_create (&tid, 0, ace_start_func, 0); +} + ]])], + [$1], + [$2], + [ + dnl POSIX threads check -- cross-compiled case + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include + +extern "C" void * +ace_start_func (void *) +{ + return 0; +} + ]], + [[ + pthread_t tid = 0; + + (void) pthread_create (&tid, 0, ace_start_func, 0); + ]])], + [$1], + [$2]) + ]) +]) diff --git a/dep/ACE_wrappers/m4/tls.m4 b/dep/ACE_wrappers/m4/tls.m4 new file mode 100644 index 000000000..b28023f69 --- /dev/null +++ b/dep/ACE_wrappers/m4/tls.m4 @@ -0,0 +1,220 @@ +dnl ------------------------------------------------------------------------- +dnl $Id: tls.m4 80826 2008-03-04 14:51:23Z wotte $ +dnl +dnl tls.m4 +dnl +dnl ACE M4 include file which contains ACE specific M4 macros +dnl that determine availablility of SSL/TLS support. +dnl +dnl ------------------------------------------------------------------------- + +dnl Copyright (C) 2003 Ossama Othman +dnl +dnl All Rights Reserved +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the current ACE distribution terms. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +dnl TLS/SSL library IO check +dnl Use this macro to determine if TLS/SSL support is available on the +dnl current host. +dnl Usage: ACE_CHECK_TLS +AC_DEFUN([ACE_CHECK_TLS], +[ + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PROG_CXXCPP]) + AC_LANG([C++]) + AC_REQUIRE([AC_LANG]) + + ace_TLS_CPPFLAGS="" + ace_TLS_LDFLAGS="" + + AC_ARG_WITH([openssl], + AS_HELP_STRING([--with-openssl@<:@=DIR@:>@], + [root directory of openssl installation]), + [ + ace_with_openssl="${withval}" + if test "${ace_with_openssl}" != yes; then + ace_openssl_include="${ace_with_openssl}/include" + ace_openssl_libdir="${ace_with_openssl}/lib" + fi + ]) + + AC_ARG_WITH([openssl_include], + AS_HELP_STRING([--with-openssl-include=DIR], + [specify exact include dir for openssl headers]), + [ace_openssl_include="$withval"]) + + AC_ARG_WITH([openssl_libdir], + AS_HELP_STRING([--with-openssl-libdir=DIR], + [specify exact include dir for openssl libraries]), + [ace_openssl_libdir="$withval"]) + + if test "${ace_openssl_include}"; then + ace_TLS_CPPFLAGS="-I${ace_openssl_include}" + fi + + if test "${ace_openssl_libdir}"; then + ace_TLS_LDFLAGS="-L${ace_openssl_libdir}" + fi + + dnl Save the current library and preprocessor flagslist. We do not + dnl want to add the SSL/TLS-specific ones to the general library link + dnl and preprocessor flags list since they should only be used when + dnl building the ACE_SSL library and/or binaries that use the ACE_SSL + dnl library. + ace_save_LIBS="$LIBS" + ace_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ace_TLS_CPPFLAGS" + ace_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $ace_TLS_LDFLAGS" + + dnl --------------------------------------------------------- + + dnl Check if OpenSSL requires the Kerberos include directory to be + dnl added to the header search path. + + AC_CACHE_CHECK([for Kerberos include flags needed by OpenSSL], + [ac_cv_kerberos_dir], + [ + dnl Try compiling without any Kerberos-specific flags first. + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ +#include + ], + [ +// ... THIS CODE DOES NOTHING! IT IS JUST USED FOR COMPILE TESTS ... + +// ... Perform TCP connection ... + +// ... Perform TLS/SSL stuff ... +CRYPTO_set_locking_callback (0); +SSLeay_add_ssl_algorithms (); +SSL_load_error_strings (); +SSL_METHOD * meth = TLSv1_method (); +SSL_CTX * ctx = SSL_CTX_new (meth); +SSL * ssl = SSL_new (ctx); +int fd = 2000; // Dummy file descriptor value. +SSL_set_fd (ssl, fd); +SSL_connect (ssl); +SSL_shutdown (ssl); + +// ... + ]) + ], + [ + ac_cv_kerberos_dir=no + ], + [ + ace_kerberos_dir="" + for ace_kerberos in /usr /usr/local; do + ace_kerberos_dir="${ace_kerberos}/kerberos/include" + ace_kerberos_CPPFLAGS="-I${ace_kerberos_dir}" + + CPPFLAGS="$ace_save_CPPFLAGS $ace_TLS_CPPFLAGS $ace_kerberos_CPPFLAGS" + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ +#include + ], + [ +// ... THIS CODE DOES NOTHING! IT IS JUST USED FOR COMPILE TESTS ... + +// ... Perform TCP connection ... + +// ... Perform TLS/SSL stuff ... +CRYPTO_set_locking_callback (0); +SSLeay_add_ssl_algorithms (); +SSL_load_error_strings (); +SSL_METHOD * meth = TLSv1_method (); +SSL_CTX * ctx = SSL_CTX_new (meth); +SSL * ssl = SSL_new (ctx); +int fd = 2000; // Dummy file descriptor value. +SSL_set_fd (ssl, fd); +SSL_connect (ssl); +SSL_shutdown (ssl); + +// ... + ]) + ], + [ + ac_cv_kerberos_dir="$ace_kerberos_dir" + break + ], + [ + ac_cv_kerberos_dir=no + ]) + done + ]) + ]) + + AS_IF([test "$ac_cv_kerberos_dir" = no], + [ + AC_SUBST([ACE_KERBEROS_INCLUDES],[.]) + ], + [ + ace_TLS_CPPFLAGS="$ace_TLS_CPPFLAGS -I${ac_cv_kerberos_dir}" + AC_SUBST([ACE_KERBEROS_INCLUDES],[$ac_cv_kerberos_dir]) + ]) + + dnl --------------------------------------------------------- + + dnl Add the TLS/SSL libraries to the library list. + ace_TLS_LIBS="-lssl -lcrypto" + + LIBS="$ace_TLS_LIBS $LIBS" + LDFLAGS="$ace_TLS_LDFLAGS $LDFLAGS" + + AC_CACHE_CHECK([for OpenSSL libraries], + [ac_cv_openssl_libs], + [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +#include + ], + [ +// ... THIS PROGRAM DOES NOTHING! IT IS JUST USED FOR LINK TESTS ... + +// ... Perform TCP connection ... + +// ... Perform TLS/SSL stuff ... +CRYPTO_set_locking_callback (0); +SSLeay_add_ssl_algorithms (); +SSL_load_error_strings (); +SSL_METHOD * meth = TLSv1_method (); +SSL_CTX * ctx = SSL_CTX_new (meth); +SSL * ssl = SSL_new (ctx); +int fd = 2000; // Dummy file descriptor value. +SSL_set_fd (ssl, fd); +SSL_connect (ssl); +SSL_shutdown (ssl); + +// ... + ]) + ], + [ + ac_cv_openssl_libs=yes + ], + [ + ac_cv_openssl_libs=no + ]) + ]) + + AS_IF([test $ac_cv_openssl_libs != no], + [ +AC_SUBST([ACE_TLS_CPPFLAGS],[$ace_TLS_CPPFLAGS]) +AC_SUBST([ACE_TLS_LDFLAGS],[$ace_TLS_LDFLAGS]) +AC_SUBST([ACE_TLS_LIBS],[$ace_TLS_LIBS]) + ], + []) + + dnl Restore the original library list and preprocessor flags. + LIBS="$ace_save_LIBS" + CPPFLAGS="$ace_save_CPPFLAGS" + LDFLAGS="$ace_save_LDFLAGS" +]) diff --git a/dep/Makefile.am b/dep/Makefile.am new file mode 100644 index 000000000..2bd06d3a2 --- /dev/null +++ b/dep/Makefile.am @@ -0,0 +1,27 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = include lib src + +if MANGOS_BUILD_ACE +SUBDIRS += ACE_wrappers +endif + +## Additional files to include when running 'make dist' +# Nothing yet. diff --git a/dep/include/Makefile.am b/dep/include/Makefile.am new file mode 100644 index 000000000..a14294146 --- /dev/null +++ b/dep/include/Makefile.am @@ -0,0 +1,261 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## Additional files to include when running 'make dist' +# G3DLite header files +EXTRA_DIST = \ + g3dlite/G3D/AABox.h \ + g3dlite/G3D/Array.h \ + g3dlite/G3D/Box.h \ + g3dlite/G3D/CollisionDetection.h \ + g3dlite/G3D/CoordinateFrame.h \ + g3dlite/G3D/Crypto.h \ + g3dlite/G3D/debug.h \ + g3dlite/G3D/format.h \ + g3dlite/G3D/g3dmath.h \ + g3dlite/G3D/g3dmath.inl \ + g3dlite/G3D/GCamera.h \ + g3dlite/G3D/Line.h \ + g3dlite/G3D/Matrix3.h \ + g3dlite/G3D/Plane.h \ + g3dlite/G3D/platform.h \ + g3dlite/G3D/Quat.h \ + g3dlite/G3D/Quat.inl \ + g3dlite/G3D/Ray.h \ + g3dlite/G3D/RegistryUtil.h \ + g3dlite/G3D/Sphere.h \ + g3dlite/G3D/stringutils.h \ + g3dlite/G3D/System.h \ + g3dlite/G3D/Table.h \ + g3dlite/G3D/Triangle.h \ + g3dlite/G3D/Vector2.h \ + g3dlite/G3D/Vector2.inl \ + g3dlite/G3D/Vector2int16.h \ + g3dlite/G3D/Vector3.h \ + g3dlite/G3D/Vector3.inl \ + g3dlite/G3D/Vector3int16.h \ + g3dlite/G3D/Vector4.h \ + g3dlite/G3D/Vector4.inl + +# MySQL header files for Win32 builds +EXTRA_DIST += \ + mysql/config-netware.h \ + mysql/config-os2.h \ + mysql/config-win.h \ + mysql/errmsg.h \ + mysql/libmysqld.def \ + mysql/Libmysql.def \ + mysql/m_ctype.h \ + mysql/m_string.h \ + mysql/my_alloc.h \ + mysql/my_dbug.h \ + mysql/my_getopt.h \ + mysql/my_global.h \ + mysql/my_list.h \ + mysql/my_pthread.h \ + mysql/mysql_com.h \ + mysql/mysqld_error.h \ + mysql/mysql_embed.h \ + mysql/mysql.h \ + mysql/mysql_time.h \ + mysql/mysql_version.h \ + mysql/my_sys.h \ + mysql/raid.h \ + mysql/typelib.h + +# OpenSSL header files for Win32 builds +EXTRA_DIST += \ + openssl/aes.h \ + openssl/asn1.h \ + openssl/asn1_mac.h \ + openssl/asn1t.h \ + openssl/bio.h \ + openssl/blowfish.h \ + openssl/bn.h \ + openssl/buffer.h \ + openssl/cast.h \ + openssl/comp.h \ + openssl/conf_api.h \ + openssl/conf.h \ + openssl/crypto.h \ + openssl/des.h \ + openssl/des_old.h \ + openssl/dh.h \ + openssl/dsa.h \ + openssl/dso.h \ + openssl/dtls1.h \ + openssl/ebcdic.h \ + openssl/ecdh.h \ + openssl/ecdsa.h \ + openssl/ec.h \ + openssl/engine.h \ + openssl/e_os2.h \ + openssl/err.h \ + openssl/evp.h \ + openssl/hmac.h \ + openssl/idea.h \ + openssl/krb5_asn.h \ + openssl/kssl.h \ + openssl/lhash.h \ + openssl/md2.h \ + openssl/md4.h \ + openssl/md5.h \ + openssl/mdc2.h \ + openssl/objects.h \ + openssl/obj_mac.h \ + openssl/ocsp.h \ + openssl/opensslconf.h \ + openssl/opensslv.h \ + openssl/ossl_typ.h \ + openssl/pem2.h \ + openssl/pem.h \ + openssl/pkcs12.h \ + openssl/pkcs7.h \ + openssl/pq_compat.h \ + openssl/pqueue.h \ + openssl/rand.h \ + openssl/rc2.h \ + openssl/rc4.h \ + openssl/rc5.h \ + openssl/ripemd.h \ + openssl/rsa.h \ + openssl/safestack.h \ + openssl/sha.h \ + openssl/ssl23.h \ + openssl/ssl2.h \ + openssl/ssl3.h \ + openssl/ssl.h \ + openssl/stack.h \ + openssl/store.h \ + openssl/symhacks.h \ + openssl/tls1.h \ + openssl/tmdiff.h \ + openssl/txt_db.h \ + openssl/ui_compat.h \ + openssl/ui.h \ + openssl/x509.h \ + openssl/x509v3.h \ + openssl/x509_vfy.h + +# PostgreSQL header files for Win32 builds +EXTRA_DIST += \ + postgre/libpq-fe.h \ + postgre/pg_type.h \ + postgre/postgres_ext.h + +# SQLite header files for Win32 builds +EXTRA_DIST += \ + sqlite/sqlite.h + +# Sockets header files for Win32 builds +EXTRA_DIST += \ + sockets\Base64.h \ + sockets\CircularBuffer.h \ + sockets\IFile.h \ + sockets\Ipv4Address.h \ + sockets\Ipv6Address.h \ + sockets\ISocketHandler.h \ + sockets\ListenSocket.h \ + sockets\Mutex.h \ + sockets\Parse.h \ + sockets\RandomNumber.h \ + sockets\ResolvServer.h \ + sockets\ResolvSocket.h \ + sockets\SctpSocket.h \ + sockets\Socket.h \ + sockets\socket_include.h \ + sockets\SocketAddress.h \ + sockets\SocketHandler.h \ + sockets\sockets-config.h \ + sockets\StdLog.h \ + sockets\StdoutLog.h \ + sockets\TcpSocket.h \ + sockets\Thread.h \ + sockets\UdpSocket.h \ + sockets\Uid.h \ + sockets\Utility.h + +# VLD header files for Win32 builds +EXTRA_DIST += \ + vld/vld.h + +# Zlib header files for Win32 builds +EXTRA_DIST += \ + zlib/zconf.h \ + zlib/zlib.h + +# ZThread header files for Win32 builds +EXTRA_DIST += \ + zthread/AtomicCount.h \ + zthread/Barrier.h \ + zthread/BiasedReadWriteLock.h \ + zthread/BlockingQueue.h \ + zthread/BoundedQueue.h \ + zthread/Cancelable.h \ + zthread/ClassLockable.h \ + zthread/ConcurrentExecutor.h \ + zthread/Condition.h \ + zthread/Config.h \ + zthread/CountedPtr.h \ + zthread/CountingSemaphore.h \ + zthread/Exceptions.h \ + zthread/Executor.h \ + zthread/FairReadWriteLock.h \ + zthread/FastMutex.h \ + zthread/FastRecursiveMutex.h \ + zthread/Guard.h \ + zthread/GuardedClass.h \ + zthread/Lockable.h \ + zthread/LockedQueue.h \ + zthread/MonitoredQueue.h \ + zthread/Mutex.h \ + zthread/NonCopyable.h \ + zthread/PoolExecutor.h \ + zthread/Priority.h \ + zthread/PriorityCondition.h \ + zthread/PriorityInheritanceMutex.h \ + zthread/PriorityMutex.h \ + zthread/PrioritySemaphore.h \ + zthread/Queue.h \ + zthread/ReadWriteLock.h \ + zthread/RecursiveMutex.h \ + zthread/Runnable.h \ + zthread/Semaphore.h \ + zthread/Singleton.h \ + zthread/SynchronousExecutor.h \ + zthread/Task.h \ + zthread/Thread.h \ + zthread/ThreadLocal.h \ + zthread/ThreadLocalImpl.h \ + zthread/ThreadedExecutor.h \ + zthread/Time.h \ + zthread/Waitable.h \ + zthread/ZThread.h + +# Mersenne Twister random number generator header files +EXTRA_DIST += \ + mersennetwister/MersenneTwister.h + +# UTF8-CPP header files +EXTRA_DIST += \ + utf8cpp/utf8.h \ + utf8cpp/utf8/checked.h \ + utf8cpp/utf8/core.h \ + utf8cpp/utf8/unchecked.h diff --git a/dep/include/g3dlite/G3D/AABox.h b/dep/include/g3dlite/G3D/AABox.h new file mode 100644 index 000000000..b5e862a77 --- /dev/null +++ b/dep/include/g3dlite/G3D/AABox.h @@ -0,0 +1,255 @@ +/** + @file AABox.h + + Axis-aligned box class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2004-01-10 + @edited 2006-02-10 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_AABOX_H +#define G3D_AABOX_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/debug.h" +#include "G3D/Array.h" + +namespace G3D { + +/** + An axis-aligned box. + */ +class AABox { +private: + + /** Optional argument placeholder */ + static int dummy; + + Vector3 lo; + Vector3 hi; + +public: + + /** Does not initialize the fields */ + inline AABox() {} + + /** + Constructs a zero-area AABox at v. + */ + inline AABox(const Vector3& v) { + lo = hi = v; + } + + /** Assumes that low is less than or equal to high along each dimension. + To have this automatically enforced, use + AABox(low.min(high), low.max(high)); + */ + inline AABox(const Vector3& low, const Vector3& high) { + set(low, high); + } + + /** Assumes that low is less than or equal to high along each dimension. + */ + inline void set(const Vector3& low, const Vector3& high) { + debugAssert( + (low.x <= high.x) && + (low.y <= high.y) && + (low.z <= high.z)); + lo = low; + hi = high; + } + + + inline const Vector3& low() const { + return lo; + } + + inline const Vector3& high() const { + return hi; + } + + /** + The largest possible finite box. + */ + static inline const AABox& maxFinite() { + static const AABox b = AABox(Vector3::minFinite(), Vector3::maxFinite()); + return b; + } + + static inline const AABox& inf() { + static const AABox b = AABox(-Vector3::inf(), Vector3::inf()); + return b; + } + + static inline const AABox& zero() { + static const AABox b = AABox(Vector3::zero(), Vector3::zero()); + return b; + } + + /** + Returns the centroid of the box. + */ + inline Vector3 center() const { + return (lo + hi) * 0.5; + } + + /** + Distance from corner(0) to the next corner along axis a. + */ + inline double extent(int a) const { + debugAssert(a < 3); + return hi[a] - lo[a]; + } + + inline Vector3 extent() const { + return hi - lo; + } + + /** + @deprecated Use culledBy(Array&) + */ + bool culledBy( + const class Plane* plane, + int numPlanes, + int32& cullingPlaneIndex, + const uint32 testMask, + uint32& childMask) const; + + /** + @deprecated Use culledBy(Array&) + */ + bool culledBy( + const class Plane* plane, + int numPlanes, + int32& cullingPlaneIndex = dummy, + const uint32 testMask = 0xFFFFFF) const; + + /** + Splits the box into two AABoxes along the specified axis. low contains + the part that was closer to negative infinity along axis, high contains + the other part. Either may have zero volume. + */ + void split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const; + + /** + Conservative culling test for up to 32 planes. + Returns true if there exists a plane[p] for + which the entire object is in the negative half space + (opposite the plane normal). + + testMask and childMask + are used for optimizing bounding volume hierarchies. + The version of this method that produces childMask + is slower than the version without; it should only + be used for parent nodes. + + @param cullingPlaneIndex The index of the first plane for which + the entire object is in the negative half-space. The function + exits early when one plane is found. -1 when the function + returns false (i.e. when no plane culls the whole object). + + @param testMask If bit p is 0, the + bounding volume automatically passes the culling test for + plane[p] (i.e. it is known that the volume + is entirely within the positive half space). The function + must return false if testMask is 0 and test all planes + when testMask is -1 (0xFFFFFFFF). + + @param childMask Test mask for the children of this volume. + + */ + bool culledBy( + const Array& plane, + int32& cullingPlaneIndex, + const uint32 testMask, + uint32& childMask) const; + + /** + Conservative culling test that does not produce a mask for children. + */ + bool culledBy( + const Array& plane, + int32& cullingPlaneIndex = dummy, + const uint32 testMask = -1) const; + + inline bool contains( + const Vector3& point) const { + return + (point.x >= lo.x) && + (point.y >= lo.y) && + (point.z >= lo.z) && + (point.x <= hi.x) && + (point.y <= hi.y) && + (point.z <= hi.z); + } + + /** @deprecated */ + inline float surfaceArea() const { + Vector3 diag = hi - lo; + return 2.0f * (diag.x * diag.y + diag.y * diag.z + diag.x * diag.z); + } + + inline float area() const { + return surfaceArea(); + } + + inline float volume() const { + Vector3 diag = hi - lo; + return diag.x * diag.y * diag.z; + } + + Vector3 randomInteriorPoint() const; + + Vector3 randomSurfacePoint() const; + + /** @deprecated use Box constructor */ + class Box toBox() const; + + /** Returns true if there is any overlap */ + bool intersects(const AABox& other) const; + + /** Returns true if there is any overlap. + @cite Jim Arvo's algorithm from Graphics Gems II*/ + bool intersects(const class Sphere& other) const; + + /** Return the intersection of the two boxes */ + AABox intersect(const AABox& other) const { + Vector3 H = hi.min(other.hi); + Vector3 L = lo.max(other.lo).min(H); + return AABox(L, H); + } + + inline unsigned int hashCode() const { + return lo.hashCode() + hi.hashCode(); + } + + inline bool operator==(const AABox& b) const { + return (lo == b.lo) && (hi == b.hi); + } + + inline bool operator!=(const AABox& b) const { + return !((lo == b.lo) && (hi == b.hi)); + } + + void getBounds(AABox& out) const { + out = *this; + } +}; + +} + +/** + Hashing function for use with Table. + */ +inline unsigned int hashCode(const G3D::AABox& b) { + return b.hashCode(); +} + + +#endif diff --git a/dep/include/g3dlite/G3D/Array.h b/dep/include/g3dlite/G3D/Array.h new file mode 100644 index 000000000..290563b67 --- /dev/null +++ b/dep/include/g3dlite/G3D/Array.h @@ -0,0 +1,1156 @@ +/** + @file Array.h + + @maintainer Morgan McGuire, graphics3d.com + @cite Portions written by Aaron Orenstein, a@orenstein.name + + @created 2001-03-11 + @edited 2007-05-12 + + Copyright 2000-2007, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_ARRAY_H +#define G3D_ARRAY_H + +#include "G3D/platform.h" +#include "G3D/debug.h" +#include "G3D/System.h" +#ifdef G3D_DEBUG +// For formatting error messages +# include "G3D/format.h" +#endif +#include +#include + +#ifdef G3D_WIN32 +# include + +# pragma warning (push) + // debug information too long +# pragma warning( disable : 4312) +# pragma warning( disable : 4786) +#endif + + +namespace G3D { + +/** + Constant for passing to Array::resize + */ +const bool DONT_SHRINK_UNDERLYING_ARRAY = false; + +/** Constant for Array::sort */ +const int SORT_INCREASING = 1; +/** Constant for Array::sort */ +const int SORT_DECREASING = -1; + +/** + Dynamic 1D array. + + Objects must have a default constructor (constructor that + takes no arguments) in order to be used with this template. + You will get the error "no appropriate default constructor found" + if they do not. + + Do not use with objects that overload placement operator new, + since the speed of Array is partly due to pooled allocation. + + If SSE is defined Arrays allocate the first element aligned to + 16 bytes. + + + Array is highly optimized compared to std::vector. + Array operations are less expensive than on std::vector and for large + amounts of data, Array consumes only 1.5x the total size of the + data, while std::vector consumes 2.0x. The default + array takes up zero heap space. The first resize (or append) + operation grows it to a reasonable internal size so it is efficient + to append to small arrays. Memory is allocated using + System::alignedMalloc, which produces pointers aligned to 16-byte + boundaries for use with SSE instructions and uses pooled storage for + fast allocation. When Array needs to copy + data internally on a resize operation it correctly invokes copy + constructors of the elements (the MSVC6 implementation of + std::vector uses realloc, which can create memory leaks for classes + containing references and pointers). Array provides a guaranteed + safe way to access the underlying data as a flat C array -- + Array::getCArray. Although (T*)std::vector::begin() can be used for + this purpose, it is not guaranteed to succeed on all platforms. + + To serialize an array, see G3D::serialize. + + Do not subclass an Array. + */ +template +class Array { +private: + /** 0...num-1 are initialized elements, num...numAllocated-1 are not */ + T* data; + + int num; + int numAllocated; + + void init(int n, int a) { + debugAssert(n <= a); + debugAssert(n >= 0); + this->num = 0; + this->numAllocated = 0; + data = NULL; + if (a > 0) { + resize(n); + } else { + data = NULL; + } + } + + void _copy(const Array &other) { + init(other.num, other.num); + for (int i = 0; i < num; i++) { + data[i] = other.data[i]; + } + } + + /** + Returns true iff address points to an element of this array. + Used by append. + */ + inline bool inArray(const T* address) { + return (address >= data) && (address < data + num); + } + + + /** Only compiled if you use the sort procedure. */ + static bool __cdecl compareGT(const T& a, const T& b) { + return a > b; + } + + + /** + Allocates a new array of size numAllocated (not a parameter to the method) + and then copies at most oldNum elements from the old array to it. Destructors are + called for oldNum elements of the old array. + */ + void realloc(int oldNum) { + T* oldData = data; + + // The allocation is separate from the constructor invocation because we don't want + // to pay for the cost of constructors until the newly allocated + // elements are actually revealed to the application. They + // will be constructed in the resize() method. + + data = (T*)System::alignedMalloc(sizeof(T) * numAllocated, 16); + + // Call the copy constructors + {const int N = iMin(oldNum, numAllocated); + const T* end = data + N; + T* oldPtr = oldData; + for (T* ptr = data; ptr < end; ++ptr, ++oldPtr) { + + // Use placement new to invoke the constructor at the location + // that we determined. Use the copy constructor to make the assignment. + const T* constructed = new (ptr) T(*oldPtr); + + (void)constructed; + debugAssertM(constructed == ptr, + "new returned a different address than the one provided by Array."); + }} + + // Call destructors on the old array (if there is no destructor, this will compile away) + {const T* end = oldData + oldNum; + for (T* ptr = oldData; ptr < end; ++ptr) { + ptr->~T(); + }} + + + System::alignedFree(oldData); + } + +public: + + /** + C++ STL style iterator variable. Call begin() to get + the first iterator, pre-increment (++i) the iterator to get to + the next value. Use dereference (*i) to access the element. + */ + typedef T* Iterator; + typedef const T* ConstIterator; + + /** + C++ STL style iterator method. Returns the first iterator element. + Do not change the size of the array while iterating. + */ + Iterator begin() { + return data; + } + + ConstIterator begin() const { + return data; + } + /** + C++ STL style iterator method. Returns one after the last iterator + element. + */ + ConstIterator end() const { + return data + num; + } + + Iterator end() { + return data + num; + } + + /** + The array returned is only valid until the next append() or resize call, or + the Array is deallocated. + */ + T* getCArray() { + return data; + } + + /** + The array returned is only valid until the next append() or resize call, or + the Array is deallocated. + */ + const T* getCArray() const { + return data; + } + + /** Creates a zero length array (no heap allocation occurs until resize). */ + Array() { + init(0, 0); + } + + /** + Creates an array of size. + */ + Array(int size) { + init(size, size); + } + + /** + Copy constructor + */ + Array(const Array& other) { + _copy(other); + } + + /** + Destructor does not delete() the objects if T is a pointer type + (e.g. T = int*) instead, it deletes the pointers themselves and + leaves the objects. Call deleteAll if you want to dealocate + the objects referenced. Do not call deleteAll if T is not a pointer + type (e.g. do call Array::deleteAll, do not call Array::deleteAll). + */ + ~Array() { + // Invoke the destructors on the elements + for (int i = 0; i < num; i++) { + (data + i)->~T(); + } + + System::alignedFree(data); + // Set to 0 in case this Array is global and gets referenced during app exit + data = NULL; + num = 0; + numAllocated = 0; + } + + + /** + Removes all elements. Use resize(0, false) or fastClear if you want to + remove all elements without deallocating the underlying array + so that future append() calls will be faster. + */ + void clear() { + resize(0); + } + + /** resize(0, false) */ + void fastClear() { + resize(0, false); + } + + /** + Assignment operator. + */ + Array& operator=(const Array& other) { + resize(other.num); + for (int i = 0; i < num; ++i) { + data[i] = other[i]; + } + return *this; + } + + Array& operator=(const std::vector& other) { + resize((int)other.size()); + for (int i = 0; i < num; ++i) { + data[i] = other[i]; + } + return *this; + } + + /** + Number of elements in the array. + */ + inline int size() const { + return num; + } + + /** + Number of elements in the array. (Same as size; this is just + here for convenience). + */ + inline int length() const { + return size(); + } + + /** + Swaps element index with the last element in the array then + shrinks the array by one. + */ + void fastRemove(int index) { + debugAssert(index >= 0); + debugAssert(index < num); + data[index] = data[num - 1]; + resize(size() - 1); + } + + /** + Resizes, calling the default constructor for + newly created objects and shrinking the underlying + array as needed (and calling destructors as needed). + */ + void resize(int n) { + resize(n, true); + } + + /** Resizes without shrinking the underlying array */ + void fastResize(int n) { + resize(n, false); + } + + + /** + Inserts at the specified index and shifts all other elements up by one. + */ + void insert(int n, const T& value) { + // Add space for the extra element + resize(num + 1, false); + + for (int i = num - 1; i > n; --i) { + data[i] = data[i - 1]; + } + data[n] = value; + } + + /** @param shrinkIfNecessary if false, memory will never be + reallocated when the array shrinks. This makes resizing much + faster but can waste memory. */ + void resize(int n, bool shrinkIfNecessary) { + int oldNum = num; + num = n; + + // Call the destructors on newly hidden elements if there are any + for (int i = num; i < oldNum; ++i) { + (data + i)->~T(); + } + + // Once allocated, always maintain 10 elements or 32 bytes, whichever is higher. + static const int minSize = iMax(10, 32 / sizeof(T)); + + if (num > numAllocated) { + // Grow the underlying array + + if (numAllocated == 0) { + // First allocation; grow to exactly the size requested to avoid wasting space. + numAllocated = n; + debugAssert(oldNum == 0); + realloc(oldNum); + } else { + + if (num < minSize) { + // Grow to at least the minimum size + numAllocated = minSize; + + } else { + + // Increase the underlying size of the array. Grow aggressively + // up to 64k, less aggressively up to 400k, and then grow relatively + // slowly (1.5x per resize) to avoid excessive space consumption. + // + // These numbers are tweaked according to performance tests. + + float growFactor = 3.0; + + size_t oldSizeBytes = numAllocated * sizeof(T); + if (oldSizeBytes > 400000) { + // Avoid bloat + growFactor = 1.5; + } else if (oldSizeBytes > 64000) { + // This is what std:: uses at all times + growFactor = 2.0; + } + + numAllocated = (num - numAllocated) + (int)(numAllocated * growFactor); + + if (numAllocated < minSize) { + numAllocated = minSize; + } + } + + realloc(oldNum); + } + + } else if ((num <= numAllocated / 3) && shrinkIfNecessary && (num > minSize)) { + // Shrink the underlying array + + // Only copy over old elements that still remain after resizing + // (destructors were called for others if we're shrinking) + realloc(iMin(num, oldNum)); + + } + + // Call the constructors on newly revealed elements. + // Do not use parens because we don't want the intializer + // invoked for POD types. + for (int i = oldNum; i < num; ++i) { + new (data + i) T; + } + } + + /** + Add an element to the end of the array. Will not shrink the underlying array + under any circumstances. It is safe to append an element that is already + in the array. + */ + inline void append(const T& value) { + + if (num < numAllocated) { + // This is a simple situation; just stick it in the next free slot using + // the copy constructor. + new (data + num) T(value); + ++num; + } else if (inArray(&value)) { + // The value was in the original array; resizing + // is dangerous because it may move the value + // we have a reference to. + T tmp = value; + append(tmp); + } else { + // Here we run the empty initializer where we don't have to, but + // this simplifies the computation. + resize(num + 1, DONT_SHRINK_UNDERLYING_ARRAY); + data[num - 1] = value; + } + } + + + inline void append(const T& v1, const T& v2) { + if (inArray(&v1) || inArray(&v2)) { + T t1 = v1; + T t2 = v2; + append(t1, t2); + } else if (num + 1 < numAllocated) { + // This is a simple situation; just stick it in the next free slot using + // the copy constructor. + new (data + num) T(v1); + new (data + num + 1) T(v2); + num += 2; + } else { + resize(num + 2, DONT_SHRINK_UNDERLYING_ARRAY); + data[num - 2] = v1; + data[num - 1] = v2; + } + } + + + inline void append(const T& v1, const T& v2, const T& v3) { + if (inArray(&v1) || inArray(&v2) || inArray(&v3)) { + T t1 = v1; + T t2 = v2; + T t3 = v3; + append(t1, t2, t3); + } else if (num + 2 < numAllocated) { + // This is a simple situation; just stick it in the next free slot using + // the copy constructor. + new (data + num) T(v1); + new (data + num + 1) T(v2); + new (data + num + 2) T(v3); + num += 3; + } else { + resize(num + 3, DONT_SHRINK_UNDERLYING_ARRAY); + data[num - 3] = v1; + data[num - 2] = v2; + data[num - 1] = v3; + } + } + + + inline void append(const T& v1, const T& v2, const T& v3, const T& v4) { + if (inArray(&v1) || inArray(&v2) || inArray(&v3) || inArray(&v4)) { + T t1 = v1; + T t2 = v2; + T t3 = v3; + T t4 = v4; + append(t1, t2, t3, t4); + } else if (num + 3 < numAllocated) { + // This is a simple situation; just stick it in the next free slot using + // the copy constructor. + new (data + num) T(v1); + new (data + num + 1) T(v2); + new (data + num + 2) T(v3); + new (data + num + 3) T(v4); + num += 4; + } else { + resize(num + 4, DONT_SHRINK_UNDERLYING_ARRAY); + data[num - 4] = v1; + data[num - 3] = v2; + data[num - 2] = v3; + data[num - 1] = v4; + } + } + + /** + Returns true if the given element is in the array. + */ + bool contains(const T& e) const { + for (int i = 0; i < size(); ++i) { + if ((*this)[i] == e) { + return true; + } + } + + return false; + } + + /** + Append the elements of array. Cannot be called with this array + as an argument. + */ + void append(const Array& array) { + debugAssert(this != &array); + int oldNum = num; + int arrayLength = array.length(); + + resize(num + arrayLength, false); + + for (int i = 0; i < arrayLength; i++) { + data[oldNum + i] = array.data[i]; + } + } + + /** + Pushes a new element onto the end and returns its address. + This is the same as A.resize(A.size() + 1, false); A.last() + */ + inline T& next() { + resize(num + 1, false); + return last(); + } + + /** + Pushes an element onto the end (appends) + */ + inline void push(const T& value) { + append(value); + } + + inline void push(const Array& array) { + append(array); + } + + /** Alias to provide std::vector compatibility */ + inline void push_back(const T& v) { + push(v); + } + + /** "The member function removes the last element of the controlled sequence, which must be non-empty." + For compatibility with std::vector. */ + inline void pop_back() { + pop(); + } + + /** + "The member function returns the storage currently allocated to hold the controlled + sequence, a value at least as large as size()" + For compatibility with std::vector. + */ + int capacity() const { + return numAllocated; + } + + /** + "The member function returns a reference to the first element of the controlled sequence, + which must be non-empty." + For compatibility with std::vector. + */ + T& front() { + return (*this)[0]; + } + + /** + "The member function returns a reference to the first element of the controlled sequence, + which must be non-empty." + For compatibility with std::vector. + */ + const T& front() const { + return (*this)[0]; + } + + /** + Removes the last element and returns it. By default, shrinks the underlying array. + */ + inline T pop(bool shrinkUnderlyingArrayIfNecessary = true) { + debugAssert(num > 0); + T temp = data[num - 1]; + resize(num - 1, shrinkUnderlyingArrayIfNecessary); + return temp; + } + + /** Pops the last element and discards it without returning anything. Faster than pop. + By default, does not shrink the underlying array.*/ + inline void popDiscard(bool shrinkUnderlyingArrayIfNecessary = false) { + debugAssert(num > 0); + resize(num - 1, shrinkUnderlyingArrayIfNecessary); + } + + + /** + "The member function swaps the controlled sequences between *this and str." + Note that this is slower than the optimal std implementation. + + For compatibility with std::vector. + */ + void swap(Array& str) { + Array temp = str; + str = *this; + *this = temp; + } + + + /** + Performs bounds checks in debug mode + */ + inline T& operator[](int n) { + debugAssertM((n >= 0) && (n < num), format("Array index out of bounds. n = %d, size() = %d", n, num)); + debugAssert(data!=NULL); + return data[n]; + } + + inline T& operator[](unsigned int n) { + debugAssertM(((int)n < num), format("Array index out of bounds. n = %d, size() = %d", n, num)); + return data[n]; + } + + /** + Performs bounds checks in debug mode + */ + inline const T& operator[](int n) const { + debugAssert((n >= 0) && (n < num)); + debugAssert(data!=NULL); + return data[n]; + } + + inline const T& operator[](unsigned int n) const { + debugAssert((n < (unsigned int)num)); + debugAssert(data!=NULL); + return data[n]; + } + + inline T& randomElement() { + debugAssert(num > 0); + debugAssert(data!=NULL); + return data[iRandom(0, num - 1)]; + } + + inline const T& randomElement() const { + debugAssert(num > 0); + debugAssert(data!=NULL); + return data[iRandom(0, num - 1)]; + } + + /** + Returns the last element, performing a check in + debug mode that there is at least one element. + */ + inline const T& last() const { + debugAssert(num > 0); + debugAssert(data!=NULL); + return data[num - 1]; + } + + /** Returns element lastIndex() */ + inline T& last() { + debugAssert(num > 0); + debugAssert(data!=NULL); + return data[num - 1]; + } + + /** Returns size() - 1 */ + inline int lastIndex() const { + debugAssertM(num > 0, "Array is empty"); + return num - 1; + } + + inline int firstIndex() const { + debugAssertM(num > 0, "Array is empty"); + return 0; + } + + /** Returns element firstIndex(), performing a check in debug mode to ensure that there is at least one */ + inline T& first() { + debugAssertM(num > 0, "Array is empty"); + return data[0]; + } + + inline const T& first() const { + debugAssertM(num > 0, "Array is empty"); + return data[0]; + } + + /** Returns iFloor(size() / 2), throws an assertion in debug mode if the array is empty */ + inline int middleIndex() const { + debugAssertM(num > 0, "Array is empty"); + return num >> 1; + } + + /** Returns element middleIndex() */ + inline const T& middle() const { + debugAssertM(num > 0, "Array is empty"); + return data[num >> 1]; + } + + /** Returns element middleIndex() */ + inline T& middle() { + debugAssertM(num > 0, "Array is empty"); + return data[num >> 1]; + } + + /** + Calls delete on all objects[0...size-1] + and sets the size to zero. + */ + void deleteAll() { + for (int i = 0; i < num; i++) { + delete data[i]; + } + resize(0); + } + + /** + Returns the index of (the first occurance of) an index or -1 if + not found. + */ + int findIndex(const T& value) const { + for (int i = 0; i < num; ++i) { + if (data[i] == value) { + return i; + } + } + return -1; + } + + /** + Finds an element and returns the iterator to it. If the element + isn't found then returns end(). + */ + Iterator find(const T& value) { + for (int i = 0; i < num; ++i) { + if (data[i] == value) { + return data + i; + } + } + return end(); + } + + ConstIterator find(const T& value) const { + for (int i = 0; i < num; ++i) { + if (data[i] == value) { + return data + i; + } + } + return end(); + } + + /** + Removes count elements from the array + referenced either by index or Iterator. + */ + void remove(Iterator element, int count = 1) { + debugAssert((element >= begin()) && (element < end())); + debugAssert((count > 0) && (element + count) <= end()); + Iterator last = end() - count; + + while(element < last) { + element[0] = element[count]; + ++element; + } + + resize(num - count); + } + + void remove(int index, int count = 1) { + debugAssert((index >= 0) && (index < num)); + debugAssert((count > 0) && (index + count <= num)); + + remove(begin() + index, count); + } + + /** + Reverse the elements of the array in place. + */ + void reverse() { + T temp; + + int n2 = num / 2; + for (int i = 0; i < n2; ++i) { + temp = data[num - 1 - i]; + data[num - 1 - i] = data[i]; + data[i] = temp; + } + } + + /** + Sort using a specific less-than function, e.g.: + +
+    bool __cdecl myLT(const MyClass& elem1, const MyClass& elem2) {
+        return elem1.x < elem2.x;
+    }
+    
+ + Note that for pointer arrays, the const must come + after the class name, e.g., Array uses: + +
+    bool __cdecl myLT(MyClass*const& elem1, MyClass*const& elem2) {
+        return elem1->x < elem2->x;
+    }
+    
+ */ + void sort(bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) { + std::sort(data, data + num, lessThan); + } + + + /** + Sorts the array in increasing order using the > or < operator. To + invoke this method on Array, T must override those operator. + You can overide these operators as follows: + + bool T::operator>(const T& other) const { + return ...; + } + bool T::operator<(const T& other) const { + return ...; + } + + */ + void sort(int direction = SORT_INCREASING) { + if (direction == SORT_INCREASING) { + std::sort(data, data + num); + } else { + std::sort(data, data + num, compareGT); + } + } + + /** + Sorts elements beginIndex through and including endIndex. + */ + void sortSubArray(int beginIndex, int endIndex, int direction = SORT_INCREASING) { + if (direction == SORT_INCREASING) { + std::sort(data + beginIndex, data + endIndex + 1); + } else { + std::sort(data + beginIndex, data + endIndex + 1, compareGT); + } + } + + void sortSubArray(int beginIndex, int endIndex, bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) { + std::sort(data + beginIndex, data + endIndex + 1, lessThan); + } + + /** + The StrictWeakOrdering can be either a class that overloads the function call operator() or + a function pointer of the form bool (__cdecl *lessThan)(const T& elem1, const T& elem2) + */ + template + void sortSubArray(int beginIndex, int endIndex, StrictWeakOrdering& lessThan) { + std::sort(data + beginIndex, data + endIndex + 1, lessThan); + } + + /** Uses < and == to evaluate operator(); this is the default comparator for Array::partition. */ + class DefaultComparator { + public: + inline int operator()(const T& A, const T& B) const { + if (A < B) { + return 1; + } else if (A == B) { + return 0; + } else { + return -1; + } + } + }; + + /** The output arrays are resized with fastClear() so that if they are already of the same size + as this array no memory is allocated during partitioning. + + @param comparator A function, or class instance with an overloaded operator() that compares + two elements of type T and returns 0 if they are equal, -1 if the second is smaller, + and 1 if the first is smaller (i.e., following the conventions of std::string::compare). For example: + +
+        int compare(int A, int B) {
+            if (A < B) {
+                return 1;
+            } else if (A == B) {
+                return 0;
+            } else {
+                return -1;
+            }
+        }
+        
+ */ + template + void partition( + const T& partitionElement, + Array& ltArray, + Array& eqArray, + Array& gtArray, + const Comparator& comparator) const { + + // Make sure all arrays are independent + debugAssert(<Array != this); + debugAssert(&eqArray != this); + debugAssert(>Array != this); + debugAssert(<Array != &eqArray); + debugAssert(<Array != >Array); + debugAssert(&eqArray != >Array); + + // Clear the arrays + ltArray.fastClear(); + eqArray.fastClear(); + gtArray.fastClear(); + + // Form a table of buckets for lt, eq, and gt + Array* bucket[3] = {<Array, &eqArray, >Array}; + + for (int i = 0; i < num; ++i) { + int c = comparator(partitionElement, data[i]); + debugAssertM(c >= -1 && c <= 1, "Comparator returned an illegal value."); + + // Insert into the correct bucket, 0, 1, or 2 + bucket[c + 1]->append(data[i]); + } + } + + /** + Uses < and == on elements to perform a partition. See partition(). + */ + void partition( + const T& partitionElement, + Array& ltArray, + Array& eqArray, + Array& gtArray) const { + + partition(partitionElement, ltArray, eqArray, gtArray, typename Array::DefaultComparator()); + } + + /** + Paritions the array into those below the median, those above the median, and those elements + equal to the median in expected O(n) time using quickselect. If the array has an even + number of different elements, the median for partition purposes is the largest value + less than the median. + + @param tempArray used for working scratch space + @param comparator see parition() for a discussion.*/ + template + void medianPartition( + Array& ltMedian, + Array& eqMedian, + Array& gtMedian, + Array& tempArray, + const Comparator& comparator) const { + + ltMedian.fastClear(); + eqMedian.fastClear(); + gtMedian.fastClear(); + + // Handle trivial cases first + switch (size()) { + case 0: + // Array is empty; no parition is possible + return; + + case 1: + // One element + eqMedian.append(first()); + return; + + case 2: + { + // Two element array; median is the smaller + int c = comparator(first(), last()); + + switch (c) { + case -1: + // first was bigger + eqMedian.append(last()); + gtMedian.append(first()); + break; + + case 0: + // Both equal to the median + eqMedian.append(first(), last()); + break; + + case 1: + // Last was bigger + eqMedian.append(first()); + gtMedian.append(last()); + break; + } + } + return; + } + + // All other cases use a recursive randomized median + + // Number of values less than all in the current arrays + int ltBoost = 0; + + // Number of values greater than all in the current arrays + int gtBoost = 0; + + // For even length arrays, force the gt array to be one larger than the + // lt array: + // [1 2 3] size = 3, choose half = (s + 1) /2 + // + int lowerHalfSize, upperHalfSize; + if (isEven(size())) { + lowerHalfSize = size() / 2; + upperHalfSize = lowerHalfSize + 1; + } else { + lowerHalfSize = upperHalfSize = (size() + 1) / 2; + } + const T* xPtr = NULL; + + // Maintain pointers to the arrays; we'll switch these around during sorting + // to avoid copies. + const Array* source = this; + Array* lt = <Median; + Array* eq = &eqMedian; + Array* gt = >Median; + Array* extra = &tempArray; + + while (true) { + // Choose a random element -- choose the middle element; this is theoretically + // suboptimal, but for loosly sorted array is actually the best strategy + + xPtr = &(source->middle()); + if (source->size() == 1) { + // Done; there's only one element left + break; + } + const T& x = *xPtr; + + // Note: partition (fast) clears the arrays for us + source->partition(x, *lt, *eq, *gt, comparator); + + int L = lt->size() + ltBoost + eq->size(); + int U = gt->size() + gtBoost + eq->size(); + if ((L >= lowerHalfSize) && + (U >= upperHalfSize)) { + + // x must be the partition median + break; + + } else if (L < lowerHalfSize) { + + // x must be smaller than the median. Recurse into the 'gt' array. + ltBoost += lt->size() + eq->size(); + + // The new gt array will be the old source array, unless + // that was the this pointer (i.e., unless we are on the + // first iteration) + Array* newGt = (source == this) ? extra : const_cast*>(source); + + // Now set up the gt array as the new source + source = gt; + gt = newGt; + + } else { + + // x must be bigger than the median. Recurse into the 'lt' array. + gtBoost += gt->size() + eq->size(); + + // The new lt array will be the old source array, unless + // that was the this pointer (i.e., unless we are on the + // first iteration) + Array* newLt = (source == this) ? extra : const_cast*>(source); + + // Now set up the lt array as the new source + source = lt; + lt = newLt; + } + } + + // Now that we know the median, make a copy of it (since we're about to destroy the array that it + // points into). + T median = *xPtr; + xPtr = NULL; + + // Partition the original array (note that this fast clears for us) + partition(median, ltMedian, eqMedian, gtMedian, comparator); + } + + /** + Computes a median partition using the default comparator and a dynamically allocated temporary + working array. If the median is not in the array, it is chosen to be the largest value smaller + than the true median. + */ + void medianPartition( + Array& ltMedian, + Array& eqMedian, + Array& gtMedian) const { + + Array temp; + medianPartition(ltMedian, eqMedian, gtMedian, temp, DefaultComparator()); + } + + + /** Redistributes the elements so that the new order is statistically independent + of the original order. O(n) time.*/ + void randomize() { + T temp; + + for (int i = size() - 1; i >= 0; --i) { + int x = iRandom(0, i); + + temp = data[i]; + data[i] = data[x]; + data[x] = temp; + } + } + + +}; + + +/** Array::contains for C-arrays */ +template bool contains(const T* array, int len, const T& e) { + for (int i = len - 1; i >= 0; --i) { + if (array[i] == e) { + return true; + } + } + return false; +} + +} // namespace + +#endif + +#ifdef G3D_WIN32 +# pragma warning (push) +#endif diff --git a/dep/include/g3dlite/G3D/Box.h b/dep/include/g3dlite/G3D/Box.h new file mode 100644 index 000000000..f097c10e1 --- /dev/null +++ b/dep/include/g3dlite/G3D/Box.h @@ -0,0 +1,228 @@ +/** + @file Box.h + + Box class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com + @created 2001-06-02 + @edited 2006-01-05 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_BOX_H +#define G3D_BOX_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/Array.h" +#include "G3D/Plane.h" + +namespace G3D { + +class CoordinateFrame; + +/** + An arbitrary 3D box, useful as a bounding box. + + + To construct a box from a coordinate frame, center and extent, use the idiom: + + Box box = cframe.toObjectSpace(Box(center - extent/2, center + extent/2)); + */ +class Box { +private: + + static int32 dummy; + + friend class CoordinateFrame; + + /** +
+       3    2       7    6
+    
+       0    1       4    5
+
+       front    back (seen through front)
+      
+ */ + Vector3 _corner[8]; + + /** + Unit axes. + */ + Vector3 _axis[3]; + + Vector3 _center; + + /** + Extent along each axis. + */ + Vector3 _extent; + + float _area; + float _volume; + + void init( + const Vector3& min, + const Vector3& max); + +public: + + /** + Does not initialize the fields. + */ + Box(); + + /** + Constructs a box from two opposite corners. + */ + Box( + const Vector3& min, + const Vector3& max); + + Box(const class AABox& b); + + + /** + Returns the object to world transformation for + this box. localFrame().worldToObject(...) takes + objects into the space where the box axes are + (1,0,0), (0,1,0), (0,0,1). Note that there + is no scaling in this transformation. + */ + CoordinateFrame localFrame() const; + + void getLocalFrame(CoordinateFrame& frame) const; + + /** + Returns the centroid of the box. + */ + inline Vector3 center() const { + return _center; + } + + inline Vector3 getCenter() const { + return center(); + } + + /** + Returns a corner (0 <= i < 8) + @deprecated + */ + inline Vector3 getCorner(int i) const { + debugAssert(i < 8); + return _corner[i]; + } + + inline Vector3 corner(int i) const { + debugAssert(i < 8); + return _corner[i]; + } + + /** + Unit length. + */ + inline Vector3 axis(int a) const { + debugAssert(a < 3); + return _axis[a]; + } + + /** + Distance from corner(0) to the next corner + along the box's local axis a. + */ + inline float extent(int a) const { + debugAssert(a < 3); + return (float)_extent[a]; + } + + inline Vector3 extent() const { + return _extent; + } + + /** + Returns the four corners of a face (0 <= f < 6). + The corners are returned to form a counter clockwise quad facing outwards. + */ + void getFaceCorners( + int f, + Vector3& v0, + Vector3& v1, + Vector3& v2, + Vector3& v3) const; + +/** + @deprecated Use culledBy(Array&) + */ + bool culledBy( + const class Plane* plane, + int numPlanes, + int32& cullingPlaneIndex, + const uint32 testMask, + uint32& childMask) const; + + /** + @deprecated Use culledBy(Array&) + */ + bool culledBy( + const class Plane* plane, + int numPlanes, + int32& cullingPlaneIndex = dummy, + const uint32 testMask = -1) const; + + /** + See AABox::culledBy + */ + bool culledBy( + const Array& plane, + int32& cullingPlaneIndex, + const uint32 testMask, + uint32& childMask) const; + + /** + Conservative culling test that does not produce a mask for children. + */ + bool culledBy( + const Array& plane, + int32& cullingPlaneIndex = dummy, + const uint32 testMask = -1) const; + + bool contains( + const Vector3& point) const; + + /** @deprecated */ + float surfaceArea() const; + + inline float area() const { + return surfaceArea(); + } + + float volume() const; + + void getRandomSurfacePoint(Vector3& P, Vector3& N = Vector3::dummy) const; + + /** + @deprecated + Uniformly distributed on the surface. + */ + inline Vector3 randomSurfacePoint() const { + Vector3 V; + getRandomSurfacePoint(V); + return V; + } + + /** + Uniformly distributed on the interior (includes surface) + */ + Vector3 randomInteriorPoint() const; + + void getBounds(class AABox&) const; +}; + +} + +#endif diff --git a/dep/include/g3dlite/G3D/CollisionDetection.h b/dep/include/g3dlite/G3D/CollisionDetection.h new file mode 100644 index 000000000..4dc8b2653 --- /dev/null +++ b/dep/include/g3dlite/G3D/CollisionDetection.h @@ -0,0 +1,1157 @@ +/** + @file CollisionDetection.h + + + Moving collision detection for simple primitives. + + @author Morgan McGuire, matrix@graphics3d.com + @cite Spherical collision based on Paul Nettle's + ftp://ftp.3dmaileffects.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf + and comments by Max McGuire. Ray-sphere intersection by Eric Haines. + Box-Box intersection written by Kevin Egan. + Thanks to Max McGuire of Iron Lore for various bug fixes. + + @created 2001-11-19 + @edited 2006-01-10 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_COLLISIONDETECTION_H +#define G3D_COLLISIONDETECTION_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/Plane.h" +#include "G3D/Box.h" +#include "G3D/Triangle.h" +#include "G3D/Array.h" +#include "G3D/Ray.h" +#include "G3D/Line.h" + +namespace G3D { + + +/** + Collision detection primitives and tools for building + higher order collision detection schemes. + + These routines provide moving and static collision detection. + Moving collision detection allows the calculation of collisions that + occur during a period of time -- as opposed to the intersection of + two static bodies. + + Moving collision detection routines detect collisions between + only static primitives and moving spheres or points. Since the + reference frame can be user defined, these functions can be used to + detect the collision between two moving bodies by subtracting + the velocity vector of one object from the velocity vector of the + sphere or point the detection is to occur with. This unified + velocity vector will act as if both objects are moving simultaneously. + + Collisions are detected for single-sided objects only. That is, + no collision is detected when leaving a primitive or passing + through a plane or triangle opposite the normal... except for the + point-sphere calculation or when otherwise noted. + + For a sphere, the collision location returned is the point in world + space where the surface of the sphere and the fixed object meet. + It is not the position of the center of the sphere at + the time of the collision. + + The collision normal returned is the surface normal to the fixed + object at the collision location. + +

+ Static Collision Detection: (Neither object is moving) + + + + + + + + + + + + + + +
Vector3LineSegmentRay *LinePlaneTriangleSphereCylinderCapsuleAABoxBox
Vector3Vector3::operator== Vector3::fuzzyEq G3D::distance
LineSegmentLineSegment::closestPoint LineSegment::distance CollisionDetection::closestPointOnLineSegment
Ray *Ray::closestPoint Ray::distance
LineLine::closestPoint Line::distanceCollisionDetection::closestPointsBetweenLineAndLine
Plane
Triangle
SphereSphere::contains
CylinderCylinder::contains
CapsuleCapsule::contains
AABoxAABox::contains
BoxBox::contains(treat as Ray)CollisionDetection::collisionTimeForMovingPointFixedBox(treat as Ray)CollisionDetection::penetrationDepthForFixedBoxFixedPlaneCollisionDetection::penetrationDepthForFixedBoxFixedPlaneCollisionDetection::penetrationDepthForFixedSphereFixedBoxNone (use OPCODE)CollisionDetection::movingSpherePassesThroughFixedBoxCollisionDetection::penetrationDepthForFixedBoxFixedBoxCollisionDetection::penetrationDepthForFixedBoxFixedBox
+ +

+ Moving Collision Detection: + + * Note: Moving collision detection against certain primitives is equivalent to static collision + detection against a bigger primitive. Ray, Line Segment == ``moving Point''; Capsule ==``moving Sphere''; Plane == ``moving Line'' + */ +class CollisionDetection { +private: + + /** + Default parameter if value passed to a function as reference is + not to be calculated. Must be explicitly supported by function. + */ + static Vector3 ignore; + + /** + Default parameter if value passed to a function as reference is + not to be calculated. Must be explicitly supported by function. + */ + static bool ignoreBool; + + /** + Default parameter if value passed to a function as reference is + not to be calculated. Must be explicitly supported by function. + */ + static Array ignoreArray; + + + // Static class! + CollisionDetection() {} + virtual ~CollisionDetection() {} + +public: + + /** + Converts an index [0, 15] to the corresponding separating axis. + Does not return normalized vector in the edge-edge case + (indices 6 through 15). + + @param separatingAxisIndex Separating axis. + @param box1 Box 1. + @param box2 Box 2. + + @return Axis that separates the two boxes. + */ + static Vector3 separatingAxisForSolidBoxSolidBox( + const int separatingAxisIndex, + const Box & box1, + const Box & box2); + + /** + Tests whether two boxes have axes that are parallel to + each other. If they are, axis1 and axis2 are set to be + the parallel axes for both box1 and box2 respectively. + + @param ca Dot products of each of the boxes axes + @param epsilon Fudge factor (small unit by which the dot + products may vary and still be considered + zero). + @param axis1 Parallel Axis 1. [Post Condition] + @param axis2 Parallel Axis 2. [Post Condition] + + @return true - If boxes have a parallel axis + @return false - otherwise. + */ + static bool parallelAxisForSolidBoxSolidBox( + const double* ca, + const double epsilon, + int & axis1, + int & axis2); + + /** + Calculates the projected distance between the two boxes along + the specified separating axis, negative distances correspond + to an overlap along that separating axis. The distance is not + divided by denominator dot(L, L), see + penetrationDepthForFixedSphereFixedBox() for more details + + @param separatingAxisIndex + @param a Box 1's bounding sphere vector + @param b Box 2's bounding sphere vector + @param D Vector between Box 1 and Box 2's center points + @param c Pointer to array of dot products of the axes of Box 1 + and Box 2. + @param ca Pointer to array of unsigned dot products of the axes + of Box 1 and Box 2. + @param ad Pointer to array of dot products of Box 1 axes and D. + @param bd Pointer to array of dot products of Box 2 axes and D. + + @return Projected distance between the two boxes along the + specified separating axis. + */ + static float projectedDistanceForSolidBoxSolidBox( + const int separatingAxisIndex, + const Vector3 & a, + const Vector3 & b, + const Vector3 & D, + const double* c, + const double* ca, + const double* ad, + const double* bd); + + + /** + Creates a set of standard information about two boxes in order to + solve for their collision. This information includes a vector to + the radius of the bounding sphere for each box, the vector between + each boxes' center and a series of dot products between differing + important vectors. These dot products include those between the axes + of both boxes (signed and unsigned values), and the dot products + between all the axes of box1 and the boxes' center vector and box2 + and the boxes' center vector. + + @pre The following space requirements must be met: + - c[] 9 elements + - ca[] 9 elements + - ad[] 3 elements + - bd[] 3 elements + + @cite dobted from David Eberly's papers, variables used in this function + correspond to variables used in pages 6 and 7 in the pdf + http://www.magic-software.com/Intersection.html + http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf + + @note Links are out-dated. (Kept to preserve origin and authorship) + + @param box1 Box 1 + @param box2 Box 2 + @param a Box 1's bounding sphere vector + @param b Box 2's bounding sphere vector + @param D Vector between Box 1 and Box 2's center points + @param c Pointer to array of dot products of the axes of Box 1 + and Box 2. + @param ca Pointer to array of unsigned dot products of the axes + of Box 1 and Box 2. + @param ad Pointer to array of dot products of Box 1 axes and D. + @param bd Pointer to array of dot products of Box 2 axes and D. + */ + static void fillSolidBoxSolidBoxInfo( + const Box & box1, + const Box & box2, + Vector3 & a, + Vector3 & b, + Vector3 & D, + double* c, + double* ca, + double* ad, + double* bd); + + /** + Performs a simple bounding sphere check between two boxes to determine + whether these boxes could possibly intersect. This is a very + cheap operation (three dot products, two sqrts and a few others). If + it returns true, an intersection is possible, but not necessarily + guaranteed. + + @param a Vector from box A's center to an outer vertex + @param b Vector from box B's center to an outer vertex + @param D Distance between the centers of the two boxes + + @return true - if possible intersection + @return false - otherwise (This does not guarantee an intersection) + */ + static bool conservativeBoxBoxTest( + const Vector3 & a, + const Vector3 & b, + const Vector3 & D); + + /** + Determines whether two fixed solid boxes intersect. + + @note To speed up collision detection, the lastSeparatingAxis from + the previous time step can be passed in and that plane can be + checked first. If the separating axis was not saved, or if the + two boxes intersected then lastSeparatingAxis should equal -1. + + @cite Adobted from David Eberly's papers, variables used in this function + correspond to variables used in pages 6 and 7 in the pdf + http://www.magic-software.com/Intersection.html + http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf + + @param box1 Box 1. + @param box2 Box 2. + @param lastSeparatingAxis Last separating axis. + (optimization - see note) + + @return true - Intersection. + @return false - otherwise. + */ + static bool fixedSolidBoxIntersectsFixedSolidBox( + const Box& box1, + const Box& box2, + const int lastSeparatingAxis = -1); + + /** + Calculates the closest points on two lines with each other. If the + lines are parallel then using the starting point, else calculate the + closest point on each line to the other. + + @note This is very similiar to calculating the intersection of two lines. + Logically then, the two points calculated would be identical if calculated + with inifinite precision, but with the finite precision of floating point + calculations, these values could (will) differ as the line slope approaches + zero or inifinity. + + @cite variables and algorithm based on derivation at the following website: + http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm + + @param line1 Line 1. + @param line2 Line 2. + @param closest1 Closest point on line 1. + @param closest2 Closest point on line 2. + */ + static void closestPointsBetweenLineAndLine( + const Line & line1, + const Line & line2, + Vector3 & closest1, + Vector3 & closest2); + + /** + Calculates the depth of penetration between two fixed boxes. + Contact normal faces away from box1 and into box2. If there is + contact, only one contact point is returned. The minimally + violated separating plane is computed + - if the separating axis corresponds to a face + the contact point is half way between the deepest vertex + and the face + - if the separating axis corresponds to two edges + the contact point is the midpoint of the smallest line + segment between the two edge lines + + @note This is very similiar to calculating the intersection of two lines. + Logically then, the two points calculated would be identical if calculated + with inifinite precision, but with the finite precision of floating point + calculations, these values could (will) differ as the line slope approaches + zero or inifinity. + + @cite adobted from David Eberly's papers, variables used in this function + correspond to variables used in pages 6 and 7 in the pdf + http://www.magic-software.com/Intersection.html + http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf + + @param box1 Box 1 + @param box2 Box 2 + @param contactPoints Contact point between boxes. [Post Condition] + @param contactNormals Surface normal at contact point. [Post Condition] + @param lastSeparatingAxis Last separating axis. (Used for optimization) + + @return Depth of penetration between the two boxes. If there is no + intersection between the boxes, then a negative value is returned. + */ + static float penetrationDepthForFixedBoxFixedBox( + const Box& box1, + const Box& box2, + Array& contactPoints, + Array& contactNormals, + const int lastSeparatingAxis = -1); + + /** + Calculates the depth of penetration between two fixed spheres as well + as the deepest point of Sphere A that penetrates Sphere B. The normal + returned points away from the object A, although it may + represent a perpendicular to either the faces of object B or object A + depending on their relative orientations. + + @param sphereA Fixed Sphere A. + @param sphereB Fixed Sphere B. + @param contactPoints Sphere A's deepest point that penetrates Sphere B. + [Post Condition] + @param contactNormals Normal at penetration point. [Post Condition] + + @return Depth of penetration. If there is no intersection between the + objects then the depth will be a negative value. + */ + static float penetrationDepthForFixedSphereFixedSphere( + const class Sphere& sphereA, + const Sphere& sphereB, + Array& contactPoints, + Array& contactNormals = ignoreArray); + + /** + Calculates the depth of penetration between a fixed sphere and a fixed + box as well as the deepest point of the sphere that penetrates the box + and the normal at that intersection. + + @note There are three possible intersections between a sphere and box. + - Sphere completely contained in the box + - Sphere intersects one edge + - Sphere intersects one vertex + + The contact point and contact normal vary for each of these situations. + - Sphere contained in Box: + - Normal is based on side of least penetration (as is the depth calculation). + - Point is based on center of sphere + - Sphere intersects one edge + - Normal is based on vector from the box center to the point of depth. + - Point is closest point to the sphere on the line + - Sphere intersects one vertex + - Normal is based on vector from the box center to the vertex of penetration. + - Point is vertex of penetration. + + @cite Adapted from Jim Arvo's method in Graphics Gems + See also http://www.win.tue.nl/~gino/solid/gdc2001depth.pdf + + @param sphere Fixed Sphere. + @param box Fixed Box. + @param contactPoints Sphere point that penetrates the box. [Post Condition] + @param contactNormals Normal at the penetration point. [Post Condition] + + @return Depth of penetration. If there is no intersection between the + objects then the depth will be a negative value. + */ + static float penetrationDepthForFixedSphereFixedBox( + const Sphere& sphere, + const Box& box, + Array& contactPoints, + Array& contactNormals = ignoreArray); + + /** + Calculates the depth of penetration between a Fixed Sphere and a Fixed + Plane as well as the deepest point of the sphere that penetrates the plane + and the plane normal at that intersection. + + @param sphere Fixed Sphere. + @param plane Fixed Plane. + @param contactPoints Sphere point that penetrates the plane. + [Post Condition] + @param contactNormals Normal at penetration point. [Post Condition] + + @return Depth of penetration. If there is no intersection between the + objects then the depth will be a negative value. + */ + static float penetrationDepthForFixedSphereFixedPlane( + const Sphere& sphereA, + const class Plane& planeB, + Array& contactPoints, + Array& contactNormals = ignoreArray); + + /** + Calculates the depth of penetration between a fixed box and a fixed + plane as well as the vertexes of the box that penetrate the plane + and the plane normals at those intersections. + + @param box Fixed Box. + @param plane Fixed Plane. + @param contactPoints Box points that penetrate the plane. + [Post Condition] + @param contactNormals Normals at penetration points [Post Condition] + + @return Depth of penetration. If there is no intersection between the + objects then the depth will be a negative value. + */ + static float penetrationDepthForFixedBoxFixedPlane( + const Box& box, + const Plane& plane, + Array& contactPoints, + Array& contactNormals = ignoreArray); + + /** + Calculates time between the intersection of a moving point and a fixed + plane. + + @note This is only a one sided collision test. The side defined by + the plane's surface normal is the only one tested. For a two sided + collision, call the function once for each side's surface normal. + + @param point Moving point. + @param velocity Point's velocity. + @param plane Fixed plane. + @param location Location of collision. [Post Condition] + (Infinite vector on no collision) + @param outNormal Plane's surface normal. [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingPointFixedPlane( + const Vector3& point, + const Vector3& velocity, + const class Plane& plane, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving point and a fixed + triangle. + + @note This is only a one sided collision test. The side defined by + the triangle's surface normal is the only one tested. For a two sided + collision, call the function once for each side's surface normal. + + @param orig Moving point. + @param dir Point's velocity. + @param v0 Triangle vertex 1. + @param v1 Triangle vertex 2. + @param v2 Triangle vertex 3 + @param location Location of collision. [Post Condition] + (Infinite vector on no collision) + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + inline static float collisionTimeForMovingPointFixedTriangle( + const Vector3& orig, + const Vector3& dir, + const Vector3& v0, + const Vector3& v1, + const Vector3& v2) { + return Ray::fromOriginAndDirection(orig, dir).intersectionTime(v0, v1, v2); + } + + /** + Calculates time between the intersection of a moving point and a fixed + triangle. + + @note This is only a one sided collision test. The side defined by + the triangle's surface normal is the only one tested. For a two sided + collision, call the function once for each side's surface normal. + + @param orig Moving point. + @param dir Point's velocity. + @param v0 Triangle vertex 1. + @param v1 Triangle vertex 2. + @param v2 Triangle vertex 3 + @param location Location of collision. [Post Condition] + (Infinite vector on no collision) + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + inline static float collisionTimeForMovingPointFixedTriangle( + const Vector3& orig, + const Vector3& dir, + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + Vector3& location) { + float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2); + if (t < inf()) { + location = orig + dir * t; + } + return t; + } + + /** + Calculates time between the intersection of a moving point and a fixed + triangle. + + @note This is only a one sided collision test. The side defined by + the triangle's surface normal is the only one tested. For a two sided + collision, call the function once for each side's surface normal. + + @param orig Moving point. + @param dir Point's velocity. + @param tri Fixed triangle. + @param location Location of collision. [Post Condition] + (Infinite vector on no collision) + @param normal Triangle's surface normal. [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + inline static float collisionTimeForMovingPointFixedTriangle( + const Vector3& orig, + const Vector3& dir, + const Triangle& tri, + Vector3& location = ignore, + Vector3& normal = ignore) { + + float t = collisionTimeForMovingPointFixedTriangle( + orig, dir, tri.vertex(0), tri.vertex(1), tri.vertex(2)); + + if ((t < inf()) && (&location != &ignore)) { + location = orig + dir * t; + normal = tri.normal(); + } + return t; + } + + /** + Calculates time between the intersection of a moving point and a fixed + triangle. + + @note This is only a one sided collision test. The side defined by + the triangle's surface normal is the only one tested. For a two sided + collision, call the function once for each side's surface normal. + + @param orig Moving point. + @param dir Point's velocity. + @param v0 Triangle vertex 1. + @param v1 Triangle vertex 2. + @param v2 Triangle vertex 3 + @param location Location of collision. [Post Condition] + (Infinite vector on no collision) + @param normal Triangle's surface normal. [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + inline static float collisionTimeForMovingPointFixedTriangle( + const Vector3& orig, + const Vector3& dir, + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + Vector3& location, + Vector3& normal) { + float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2); + if (t < inf()) { + location = orig + dir * t; + normal = (v2 - v0).cross(v1 - v0).direction(); + } + return t; + } + + /** + Unlike other methods, does not support an output normal. + If the ray origin is inside the box, returns inf() but inside + is set to true. + Beta API + + @cite Andrew Woo, from "Graphics Gems", Academic Press, 1990 + @cite Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500) + @cite Epsilon value added by Klaus Hartmann + @cite http://www.codercorner.com/RayAABB.cpp + */ + static float collisionTimeForMovingPointFixedAABox( + const Vector3& point, + const Vector3& velocity, + const class AABox& box, + Vector3& outLocation, + bool& inside = ignoreBool, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving point and a fixed + Axis-Aligned Box (AABox). + + @note Avoids the sqrt from collisionTimeForMovingPointFixedAABox. + + @param point Moving point. + @param velocity Sphere's velocity. + @param box Fixed AAbox. + @param location Location of collision. [Post Condition] + @param Inside Does the ray originate inside the box? [Post Condition] + @param normal Box's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static bool collisionLocationForMovingPointFixedAABox( + const Vector3& point, + const Vector3& velocity, + const class AABox& box, + Vector3& outLocation, + bool& inside = ignoreBool, + Vector3& normal = ignore); + + /** + Calculates time between the intersection of a moving point and a fixed + sphere. + + @note When ray is starts inside the rectangle, the exiting intersection + is detected. + + @param point Moving point. + @param velocity Point's velocity. + @param Sphere Fixed Sphere. + @param location Location of collision. [Post Condition] + @param outNormal Sphere's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingPointFixedSphere( + const Vector3& point, + const Vector3& velocity, + const class Sphere& sphere, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving point and a fixed + box. + + @note If the point is already inside the box, no collision: inf is returned. + + @param point Moving point. + @param velocity Sphere's velocity. + @param box Fixed box. + @param location Position of collision. [Post Condition] + @param outNormal Box's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingPointFixedBox( + const Vector3& point, + const Vector3& velocity, + const class Box& box, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving point and a fixed + rectangle defined by the points v0, v1, v2, & v3. + + @note This is only a one sided collision test. The side defined by + the rectangle's surface normal is the only one tested. For a two sided + collision, call the function once for each side's surface normal. + + @param point Moving point. + @param velocity Sphere's velocity. + @param v0 Rectangle vertex 1. + @param v1 Rectangle vertex 2. + @param v2 Rectangle vertex 3 + @param v3 Rectangle vertex 4. + @param location Location of collision [Post Condition] + @param outNormal Rectangle's surface normal. [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingPointFixedRectangle( + const Vector3& point, + const Vector3& velocity, + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& v3, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving point and a fixed + capsule. + + @param point Moving point. + @param velocity Point's velocity. + @param capsule Fixed capsule. + @param location Location of collision. [Post Condition] + @param outNormal Capsule's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingPointFixedCapsule( + const Vector3& point, + const Vector3& velocity, + const class Capsule& capsule, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving sphere and a fixed + triangle. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param plane Fixed Plane. + @param location Location of collision -- not center position of sphere + at the collision time. [Post Condition] + @param outNormal Box's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingSphereFixedPlane( + const class Sphere& sphere, + const Vector3& velocity, + const class Plane& plane, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving sphere and a fixed + triangle. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param triangle Fixed Triangle. + @param location Location of collision -- not center position of sphere + at the collision time. [Post Condition] + @param outNormal Box's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingSphereFixedTriangle( + const class Sphere& sphere, + const Vector3& velocity, + const Triangle& triangle, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving sphere and a fixed + rectangle defined by the points v0, v1, v2, & v3. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param v0 Rectangle vertex 1. + @param v1 Rectangle vertex 2. + @param v2 Rectangle vertex 3 + @param v3 Rectangle vertex 4. + @param location Location of collision -- not center position of sphere + at the collision time. [Post Condition] + @param outNormal Box's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingSphereFixedRectangle( + const class Sphere& sphere, + const Vector3& velocity, + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& v3, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving sphere and a fixed + box. + + @note This function will not detect an intersection between a moving object + that is already interpenetrating the fixed object. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param box Fixed box. + @param location Location of collision -- not center position of sphere + at the collision time. [Post Condition] + @param outNormal Box's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingSphereFixedBox( + const class Sphere& sphere, + const Vector3& velocity, + const class Box& box, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving sphere and a fixed + sphere. + + @note This won't detect a collision if the sphere is already interpenetrating + the fixed sphere. + + @param movingSphere Moving sphere. + @param velocity Sphere's velocity. + @param fixedSphere Fixed Sphere. + @param location Location of collision -- not center position of sphere + at the collision time. [Post Condition] + @param outNormal Sphere's surface normal to collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingSphereFixedSphere( + const class Sphere& sphere, + const Vector3& velocity, + const class Sphere& fixedSphere, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Calculates time between the intersection of a moving sphere and a fixed + capsule. + + @note This won't detect a collision if the sphere is already + interpenetrating the capsule. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param capsule Fixed capsule. + @param location Location of collision -- not center position of sphere + at the collision time. [Post Condition] + @param outNormal Capsule's surface normal to the collision [Post Condition] + + @return Time til collision. If there is no collision then the return + value will be inf(). + */ + static float collisionTimeForMovingSphereFixedCapsule( + const class Sphere& sphere, + const Vector3& velocity, + const class Capsule& capsule, + Vector3& outLocation, + Vector3& outNormal = ignore); + + /** + Finds the direction of bounce that a sphere would have when it + intersects an object with the given time of collision, the + collision location and the collision normal. + + @note This function works like a pong style ball bounce. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param collisionTime Time of collision. + @param collisionLocation Collision location. + @param collisionNormal Surface collision normal. + + @return Direction of bounce. + */ + static Vector3 bounceDirection( + const class Sphere& sphere, + const Vector3& velocity, + const float collisionTime, + const Vector3& collisionLocation, + const Vector3& collisionNormal); + + /** + Finds the direction of slide given a moving sphere, its velocity, the + time of collision and the collision location. This function works as + if the sphere intersects the surface and continues to hug it. + + @note The result will work well for calculating the movement of a player + who collides with an object and continues moving along the object instead + of just bouncing off it. + + @param sphere Moving sphere. + @param velocity Sphere's velocity. + @param collisionTime Time of collision + @param collisionLocation Collision location. + + @return Direction of slide. + */ + static Vector3 slideDirection( + const class Sphere& sphere, + const Vector3& velocity, + const float collisionTime, + const Vector3& collisionLocation); + + /** + Finds the closest point on a line segment to a given point. + + @param v0 line vertex 1. + @param v1 line vertex 2. + @param point External point. + + @return Closests point to point on the line segment. + */ + static Vector3 closestPointOnLineSegment( + const Vector3& v0, + const Vector3& v1, + const Vector3& point); + + /** + Finds the closest point on a line segment to a given point. + + @note This is an optimization to closestPointOnLineSegment. Edge length + and direction can be used in this function if already pre-calculated. This + prevents doing the same work twice. + + @param v0 line vertex 1. + @param v1 line vertex 2. + @param edgeDirection The direction of the segment (unit length). + @param edgeLength The length of the segment. + @param point External point. + + @return Closests point to point on the line segment. + */ + static Vector3 closestPointOnLineSegment( + const Vector3& v0, + const Vector3& v1, + const Vector3& edgeDirection, + float edgeLength, + const Vector3& point); + + /** + Finds the closest point on the perimeter of the triangle to an external point; + given a triangle defined by three points v0, v1, & v2, and the external point. + + @param v0 Triangle vertex 1. + @param v1 Triangle vertex 2. + @param v2 Triangle vertex 3. + @param point External point. + + @return Closests point to point on the perimeter of the + triangle. + */ + static Vector3 closestPointToTrianglePerimeter( + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& point); + + /** + Finds the closest point on the perimeter of the triangle to an external point; + given a triangle defined by the array of points v, its edge directions and + their lengths, as well as the external point. + + @note This is an optimization to closestPointToTrianglePerimeter. Edge length + and direction can be used in this function if already pre-calculated. This + prevents doing the same work twice. + + @param v0 Triangle vertex 1. + @param v1 Triangle vertex 2. + @param v2 Triangle vertex 3. + @param point External point. + + @return Closests point to point on the perimeter of the + triangle. + */ + static Vector3 closestPointToTrianglePerimeter( + const Vector3 v[3], + const Vector3 edgeDirection[3], + const double edgeLength[3], + const Vector3& point); + + /** + Tests whether a point is contained within the triangle defined by + v0, v1, & v2 and its plane's normal. + + @param v0 Triangle vertex 1. + @param v1 Triangle vertex 2. + @param v2 Triangle vertex 3. + @param normal Normal to triangle's plane. + @param point The point in question. + @param primaryAxis Primary axis of triangle. This will be detected + if not given. This parameter is provided as an optimization. + + @return true - if point is inside the triangle. + @return false - otherwise + */ + static bool isPointInsideTriangle( + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& normal, + const Vector3& point, + Vector3::Axis primaryAxis = Vector3::DETECT_AXIS); + + /** + Tests for the intersection of a moving sphere and a fixed box in a + given time limit. + + @note Returns true if any part of the sphere is inside the box + during the time period (inf means "ever"). Useful for + performing bounding-box collision detection. + + @param sphere Moving sphere. + @param velocity Velocity of moving sphere. + @param box Fixed box. + @param timeLimit Time limit for intersection test. + + @return true - if the two objects will touch. + @return false - if there is no intersection. + */ + static bool movingSpherePassesThroughFixedBox( + const Sphere& sphere, + const Vector3& velocity, + const Box& box, + double timeLimit = inf()); + + /** + Tests for the intersection of a moving sphere and a fixed sphere in a + given time limit. + + @note This function will not detect an intersection between a moving object + that is already interpenetrating the fixed object. + + @param sphere Moving sphere. + @param velocity Velocity of moving sphere. + @param fixedSphere Fixed sphere. + @param timeLimit Time limit for intersection test. + + @return true - if the two spheres will touch. + @return false - if there is no intersection. + */ + static bool movingSpherePassesThroughFixedSphere( + const Sphere& sphere, + const Vector3& velocity, + const Sphere& fixedSphere, + double timeLimit = inf()); + + /** + Tests for the intersection of two fixed spheres. + + @param sphere1 Fixed sphere 1. + @param sphere2 Fixed sphere 2. + + @return true - if the two spheres touch. + @return false - if there is no intersection. + */ + static bool fixedSolidSphereIntersectsFixedSolidSphere( + const Sphere& sphere1, + const Sphere& sphere2); + + /** + Tests for the intersection of a fixed sphere and a fixed box. + + @param sphere Fixed sphere. + @param box Fixed box. + + @return true - if the two objects touch. + @return false - if there is no intersection. + */ + static bool fixedSolidSphereIntersectsFixedSolidBox( + const Sphere& sphere, + const Box& box); + + /** + Tests whether a point is inside a rectangle defined by the vertexes + v0, v1, v2, & v3, and the rectangle's plane normal. + + @param v0 Rectangle vertex 1. + @param v1 Rectangle vertex 2. + @param v2 Rectangle vertex 3. + @param v3 Rectangle vertex 4. + @param normal Normal to rectangle's plane. + @param point The point in question. + + @return true - if point is inside the rectangle. + @return false - otherwise + */ + static bool isPointInsideRectangle( + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& v3, + const Vector3& normal, + const Vector3& point); + + /** + Finds the closest point on the perimeter of the rectangle to an + external point; given a rectangle defined by four points v0, v1, + v2, & v3, and the external point. + + @param v0 Rectangle vertex 1. + @param v1 Rectangle vertex 2. + @param v2 Rectangle vertex 3. + @param v3 Rectangle vertex 4. + @param point External point. + + @return Closests point to point on the perimeter of the + rectangle. + */ + static Vector3 closestPointToRectanglePerimeter( + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& v3, + const Vector3& point); + + /** + Finds the closest point in the rectangle to an external point; Given + a rectangle defined by four points v0, v1, v2, & v3, and the external + point. + + @param v0 Rectangle vertex 1. + @param v1 Rectangle vertex 2. + @param v2 Rectangle vertex 3 + @param v3 Rectangle vertex 4. + @param point External point. + + @return Closet point in the rectangle to the external point. + */ + static Vector3 closestPointToRectangle( + const Vector3& v0, + const Vector3& v1, + const Vector3& v2, + const Vector3& v3, + const Vector3& point); +}; + +} // namespace + +#endif // G3D_COLLISIONDETECTION_H diff --git a/dep/include/g3dlite/G3D/CoordinateFrame.h b/dep/include/g3dlite/G3D/CoordinateFrame.h new file mode 100644 index 000000000..657323eea --- /dev/null +++ b/dep/include/g3dlite/G3D/CoordinateFrame.h @@ -0,0 +1,318 @@ +/** + @file CoordinateFrame.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-03-04 + @edited 2006-04-07 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. +*/ + +#ifndef G3D_COORDINATEFRAME_H +#define G3D_COORDINATEFRAME_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/Vector4.h" +#include "G3D/Matrix3.h" +#include "G3D/Array.h" +#include +#include +#include +#include +#include + +namespace G3D { + +/** + A rigid body RT (rotation-translation) transformation. + +CoordinateFrame abstracts a 4x4 matrix that maps object space to world space: + + v_world = C * v_object + +CoordinateFrame::rotation is the upper 3x3 submatrix, CoordinateFrame::translation +is the right 3x1 column. The 4th row is always [0 0 0 1], so it isn't stored. +So you don't have to remember which way the multiplication and transformation work, +it provides explicit toWorldSpace and toObjectSpace methods. Also, points, vectors +(directions), and surface normals transform differently, so they have separate methods. + +Some helper functions transform whole primitives like boxes in and out of object space. + +Convert to Matrix4 using CoordinateFrame::toMatrix4. You can construct a CoordinateFrame +from a Matrix4 using Matrix4::approxCoordinateFrame, however, because a Matrix4 is more +general than a CoordinateFrame, some information may be lost. + +See also: G3D::Matrix4, G3D::Quat +*/ +class CoordinateFrame { +public: + + /** + Takes object space points to world space. + */ + Matrix3 rotation; + + /** + Takes object space points to world space. + */ + Vector3 translation; + + /** + The direction an object "looks" relative to its own axes. + @deprecated This is always -1 and will be fixed at that value in future releases. + */ + static const float zLookDirection; + + inline bool operator==(const CoordinateFrame& other) const { + return (translation == other.translation) && (rotation == other.rotation); + } + + inline bool operator!=(const CoordinateFrame& other) const { + return !(*this == other); + } + + bool fuzzyEq(const CoordinateFrame& other) const; + + bool fuzzyIsIdentity() const; + + bool isIdentity() const; + + /** + Initializes to the identity coordinate frame. + */ + inline CoordinateFrame() : + rotation(Matrix3::identity()), translation(Vector3::zero()) { + } + + CoordinateFrame(const Vector3& _translation) : + rotation(Matrix3::identity()), translation(_translation) { + } + + CoordinateFrame(const Matrix3 &rotation, const Vector3 &translation) : + rotation(rotation), translation(translation) { + } + + CoordinateFrame(const Matrix3 &rotation) : + rotation(rotation), translation(Vector3::zero()) { + } + + CoordinateFrame(const CoordinateFrame &other) : + rotation(other.rotation), translation(other.translation) {} + + /** + Computes the inverse of this coordinate frame. + */ + inline CoordinateFrame inverse() const { + CoordinateFrame out; + out.rotation = rotation.transpose(); + out.translation = -out.rotation * translation; + return out; + } + + inline ~CoordinateFrame() {} + + /** See also Matrix4::approxCoordinateFrame */ + class Matrix4 toMatrix4() const; + + /** + Produces an XML serialization of this coordinate frame. + */ + std::string toXML() const; + + /** + Returns the heading of the lookVector as an angle in radians relative to + the world -z axis. That is, a counter-clockwise heading where north (-z) + is 0 and west (-x) is PI/2. + + Note that the heading ignores the Y axis, so an inverted + object has an inverted heading. + */ + inline float getHeading() const { + Vector3 look = rotation.getColumn(2); + float angle = -(float) atan2(-look.x, look.z); + return angle; + } + + /** + Takes the coordinate frame into object space. + this->inverse() * c + */ + inline CoordinateFrame toObjectSpace(const CoordinateFrame& c) const { + return this->inverse() * c; + } + + inline Vector4 toObjectSpace(const Vector4& v) const { + return this->inverse().toWorldSpace(v); + } + + inline Vector4 toWorldSpace(const Vector4& v) const { + return Vector4(rotation * Vector3(v.x, v.y, v.z) + translation * v.w, v.w); + } + + /** + Transforms the point into world space. + */ + inline Vector3 pointToWorldSpace(const Vector3& v) const { + return Vector3( + rotation[0][0] * v[0] + rotation[0][1] * v[1] + rotation[0][2] * v[2] + translation[0], + rotation[1][0] * v[0] + rotation[1][1] * v[1] + rotation[1][2] * v[2] + translation[1], + rotation[2][0] * v[0] + rotation[2][1] * v[1] + rotation[2][2] * v[2] + translation[2]); + } + + /** + Transforms the point into object space. + */ + inline Vector3 pointToObjectSpace(const Vector3& v) const { + float p[3]; + p[0] = v[0] - translation[0]; + p[1] = v[1] - translation[1]; + p[2] = v[2] - translation[2]; + return Vector3( + rotation[0][0] * p[0] + rotation[1][0] * p[1] + rotation[2][0] * p[2], + rotation[0][1] * p[0] + rotation[1][1] * p[1] + rotation[2][1] * p[2], + rotation[0][2] * p[0] + rotation[1][2] * p[1] + rotation[2][2] * p[2]); + } + + /** + Transforms the vector into world space (no translation). + */ + inline Vector3 vectorToWorldSpace(const Vector3& v) const { + return rotation * v; + } + + inline Vector3 normalToWorldSpace(const Vector3& v) const { + return rotation * v; + } + + class Ray toObjectSpace(const Ray& r) const; + + Ray toWorldSpace(const Ray& r) const; + + /** + Transforms the vector into object space (no translation). + */ + inline Vector3 vectorToObjectSpace(const Vector3 &v) const { + // Multiply on the left (same as rotation.transpose() * v) + return v * rotation; + } + + inline Vector3 normalToObjectSpace(const Vector3 &v) const { + // Multiply on the left (same as rotation.transpose() * v) + return v * rotation; + } + + void pointToWorldSpace(const Array& v, Array& vout) const; + + void normalToWorldSpace(const Array& v, Array& vout) const; + + void vectorToWorldSpace(const Array& v, Array& vout) const; + + void pointToObjectSpace(const Array& v, Array& vout) const; + + void normalToObjectSpace(const Array& v, Array& vout) const; + + void vectorToObjectSpace(const Array& v, Array& vout) const; + + class Box toWorldSpace(const class AABox& b) const; + + class Box toWorldSpace(const class Box& b) const; + + class Cylinder toWorldSpace(const class Cylinder& b) const; + + class Capsule toWorldSpace(const class Capsule& b) const; + + class Plane toWorldSpace(const class Plane& p) const; + + class Sphere toWorldSpace(const class Sphere& b) const; + + class Triangle toWorldSpace(const class Triangle& t) const; + + class Box toObjectSpace(const AABox& b) const; + + class Box toObjectSpace(const Box& b) const; + + class Plane toObjectSpace(const Plane& p) const; + + class Sphere toObjectSpace(const Sphere& b) const; + + Triangle toObjectSpace(const Triangle& t) const; + + /** Compose: create the transformation that is other followed by this.*/ + CoordinateFrame operator*(const CoordinateFrame &other) const { + return CoordinateFrame(rotation * other.rotation, + pointToWorldSpace(other.translation)); + } + + CoordinateFrame operator+(const Vector3& v) const { + return CoordinateFrame(rotation, translation + v); + } + + CoordinateFrame operator-(const Vector3& v) const { + return CoordinateFrame(rotation, translation - v); + } + + void lookAt(const Vector3& target); + + void lookAt( + const Vector3& target, + Vector3 up); + + /** @deprecated See lookVector */ + inline Vector3 getLookVector() const { + return rotation.getColumn(2) * zLookDirection; + } + + /** The direction this camera is looking (its negative z axis)*/ + inline Vector3 lookVector() const { + return rotation.getColumn(2) * zLookDirection; + } + + /** Returns the ray starting at the camera origin travelling in direction CoordinateFrame::lookVector. */ + class Ray lookRay() const; + + /** Up direction for this camera (its y axis). */ + inline Vector3 upVector() const { + return rotation.getColumn(1); + } + + /** + If a viewer looks along the look vector, this is the viewer's "left" + @deprecated leftVector + */ + inline Vector3 getLeftVector() const { + return -rotation.getColumn(0); + } + + /** @deprecated See rightVector */ + inline Vector3 getRightVector() const { + return rotation.getColumn(0); + } + + /** + If a viewer looks along the look vector, this is the viewer's "left". + Useful for strafing motions and building alternative coordinate frames. + */ + inline Vector3 leftVector() const { + return -rotation.getColumn(0); + } + + inline Vector3 rightVector() const { + return rotation.getColumn(0); + } + + /** + Linearly interpolates between two coordinate frames, using + Quat::slerp for the rotations. + */ + CoordinateFrame lerp( + const CoordinateFrame& other, + float alpha) const; + +}; + +} // namespace + +#endif diff --git a/dep/include/g3dlite/G3D/Crypto.h b/dep/include/g3dlite/G3D/Crypto.h new file mode 100644 index 000000000..f4e7bfad6 --- /dev/null +++ b/dep/include/g3dlite/G3D/Crypto.h @@ -0,0 +1,46 @@ +/** + @file Crypto.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + + @created 2006-03-29 + @edited 2006-04-06 + */ + +#ifndef G3D_CRYPTO_H +#define G3D_CRYPTO_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include + +namespace G3D { + +/** Cryptography and hashing helper functions */ +class Crypto { +public: + + /** + Computes the CRC32 value of a byte array. CRC32 is designed to be a hash + function that produces different values for similar strings. + + This implementation is compatible with PKZIP and GZIP. + + Based on http://www.gamedev.net/reference/programming/features/crc32/ + */ + static uint32 crc32(const void* bytes, size_t numBytes); + + /** + Returns the nth prime less than 2000 in constant time. The first prime has index + 0 and is the number 2. + */ + static int smallPrime(int n); + + /** Returns 1 + the largest value that can be passed to smallPrime. */ + static int numSmallPrimes(); +}; + +} + +#endif diff --git a/dep/include/g3dlite/G3D/GCamera.h b/dep/include/g3dlite/G3D/GCamera.h new file mode 100644 index 000000000..3205f3904 --- /dev/null +++ b/dep/include/g3dlite/G3D/GCamera.h @@ -0,0 +1,251 @@ +/** + @file GCamera.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2006-02-11 +*/ + +#ifndef G3D_GCAMERA_H +#define G3D_GCAMERA_H + +#include "G3D/platform.h" +#include "G3D/CoordinateFrame.h" +#include "G3D/Vector3.h" +#include "G3D/Plane.h" + +namespace G3D { + +/** + There is a viewport of width x height size in world space that corresponds to + a screenWidth x screenHeight pixel grid on a + renderDevice->getWidth() x renderDevice->getHeight() + window. + + All viewport arguments are the pixel bounds of the viewport-- e.g., + RenderDevice::getViewport(). + */ +class GCamera { +private: + + /** + Vertical field of view (in radians) + */ + float fieldOfView; + + /** + The image plane depth corresponding to a vertical field of + view, where the film size is 1x1. + */ + float imagePlaneDepth; + + /** + Clipping plane, *not* imaging plane. Positive numbers. + */ + float nearPlane; + + /** + Positive + */ + float farPlane; + + CoordinateFrame cframe; + +public: + + class Frustum { + public: + class Face { + public: + /** Counter clockwise indices into vertexPos */ + int vertexIndex[4]; + + /** The plane containing the face. */ + Plane plane; + }; + + /** The vertices, in homogeneous space. If w == 0, + a vertex is at infinity. */ + Array vertexPos; + + /** The faces in the frustum. When the + far plane is at infinity, there are 5 faces, + otherwise there are 6. The faces are in the order + N,R,L,B,T,[F]. + */ + Array faceArray; + }; + + GCamera(); + + virtual ~GCamera(); + + + CoordinateFrame getCoordinateFrame() const; + void getCoordinateFrame(CoordinateFrame& c) const; + void setCoordinateFrame(const CoordinateFrame& c); + + /** + Sets the horizontal field of view, in radians. The + initial angle is toRadians(55). +

    +
  • toRadians(50) - Telephoto +
  • toRadians(110) - Normal +
  • toRadians(140) - Wide angle +
+ */ + void setFieldOfView(float angle); + + /** + Sets the field of view based on a desired image plane depth + (s') and film dimensions in world space. Depth must be positive. Width, + depth, and height are measured in the same units (meters are + recommended). The field of view will span the diagonal to the + image.

Note: to simulate a 35mm GCamera, set width = + 0.36 mm and height = 0.24 mm. The width and height used are + generally not the pixel dimensions of the image. + */ + void setImagePlaneDepth( + float depth, + const class Rect2D& viewport); + + inline double getFieldOfView() const { + return fieldOfView; + } + + /** + Projects a world space point onto a width x height screen. The + returned coordinate uses pixmap addressing: x = right and y = + down. The resulting z value is rhw. + + If the point is behind the camera, Vector3::inf() is returned. + */ + G3D::Vector3 project( + const G3D::Vector3& point, + const class Rect2D& viewport) const; + + /** + Returns the pixel area covered by a shape of the given + world space area at the given z value (z must be negative). + */ + float worldToScreenSpaceArea(float area, float z, const class Rect2D& viewport) const; + + /** + Returns the world space 3D viewport corners. These + are at the near clipping plane. The corners are constructed + from the nearPlaneZ, getViewportWidth, and getViewportHeight. + "left" and "right" are from the GCamera's perspective. + */ + void get3DViewportCorners( + const class Rect2D& viewport, + Vector3& outUR, + Vector3& outUL, + Vector3& outLL, + Vector3& outLR) const; + + /** + Returns the image plane depth, s', given the current field + of view for film of dimensions width x height. See + setImagePlaneDepth for a discussion of worldspace values width and height. + */ + float getImagePlaneDepth( + const class Rect2D& viewport) const; + + + /** + Returns the world space ray passing through the center of pixel + (x, y) on the image plane. The pixel x and y axes are opposite + the 3D object space axes: (0,0) is the upper left corner of the screen. + They are in viewport coordinates, not screen coordinates. + + + Integer (x, y) values correspond to + the upper left corners of pixels. If you want to cast rays + through pixel centers, add 0.5 to x and y. + */ + Ray worldRay( + float x, + float y, + const class Rect2D& viewport) const; + + + /** + Returns a negative z-value. + */ + inline float getNearPlaneZ() const { + return -nearPlane; + } + + /** + Returns a negative z-value. + */ + inline float getFarPlaneZ() const { + return -farPlane; + } + + inline void setFarPlaneZ(float z) { + debugAssert(z < 0); + farPlane = -z; + } + + inline void setNearPlaneZ(float z) { + debugAssert(z < 0); + nearPlane = -z; + } + + /** + Returns the GCamera space width of the viewport. + */ + float getViewportWidth( + const class Rect2D& viewport) const; + + /** + Returns the GCamera space height of the viewport. + */ + float getViewportHeight( + const class Rect2D& viewport) const; + + /** + Read back a GCamera space z-value at pixel (x, y) from the depth buffer. + double getZValue( + double x, + double y, + const class Rect2D& viewport, + double polygonOffset = 0) const; + */ + + void setPosition(const Vector3& t); + + void lookAt(const Vector3& position, const Vector3& up = Vector3::unitY()); + + /** + Returns the clipping planes of the frustum, in world space. + The planes have normals facing into the view frustum. + + The plane order is guaranteed to be: + Near, Right, Left, Top, Bottom, [Far] + + If the far plane is at infinity, the resulting array will have + 5 planes, otherwise there will be 6. + + The viewport is used only to determine the aspect ratio of the screen; the + absolute dimensions and xy values don't matter. + */ + void getClipPlanes( + const Rect2D& viewport, + Array& outClip) const; + + /** + Returns the world space view frustum, which is a truncated pyramid describing + the volume of space seen by this camera. + */ + void getFrustum(const Rect2D& viewport, GCamera::Frustum& f) const; + + GCamera::Frustum frustum(const Rect2D& viewport) const; + +}; + +} // namespace G3D + +#endif diff --git a/dep/include/g3dlite/G3D/Line.h b/dep/include/g3dlite/G3D/Line.h new file mode 100644 index 000000000..5dd82c19b --- /dev/null +++ b/dep/include/g3dlite/G3D/Line.h @@ -0,0 +1,85 @@ +/** + @file Line.h + + Line class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2006-02-28 + */ + +#ifndef G3D_LINE_H +#define G3D_LINE_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" + +namespace G3D { + +class Plane; + +/** + An infinite 3D line. + */ +class Line { +protected: + + Vector3 _point; + Vector3 _direction; + + Line(const Vector3& point, const Vector3& direction) { + _point = point; + _direction = direction.direction(); + } + +public: + + /** Undefined (provided for creating Array only) */ + inline Line() {} + + virtual ~Line() {} + + /** + Constructs a line from two (not equal) points. + */ + static Line fromTwoPoints(const Vector3 &point1, const Vector3 &point2) { + return Line(point1, point2 - point1); + } + + /** + Creates a line from a point and a (nonzero) direction. + */ + static Line fromPointAndDirection(const Vector3& point, const Vector3& direction) { + return Line(point, direction); + } + + /** + Returns the closest point on the line to point. + */ + Vector3 closestPoint(const Vector3& pt) const; + + /** + Returns the distance between point and the line + */ + double distance(const Vector3& point) const { + return (closestPoint(point) - point).magnitude(); + } + + /** Returns a point on the line */ + Vector3 point() const; + + /** Returns the direction (or negative direction) of the line */ + Vector3 direction() const; + + /** + Returns the point where the line and plane intersect. If there + is no intersection, returns a point at infinity. + */ + Vector3 intersection(const Plane &plane) const; +}; + +};// namespace + + +#endif diff --git a/dep/include/g3dlite/G3D/Matrix3.h b/dep/include/g3dlite/G3D/Matrix3.h new file mode 100644 index 000000000..19eda497a --- /dev/null +++ b/dep/include/g3dlite/G3D/Matrix3.h @@ -0,0 +1,311 @@ +/** + @file Matrix3.h + + 3x3 matrix class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com + + @created 2001-06-02 + @edited 2006-04-05 + */ + +#ifndef G3D_MATRIX3_H +#define G3D_MATRIX3_H + +#include "G3D/platform.h" +#include "G3D/System.h" +#include "G3D/Vector3.h" +#include "G3D/Vector4.h" + +namespace G3D { + +/** + 3x3 matrix. Do not subclass. + */ +class Matrix3 { +private: + + float elt[3][3]; + + // Hidden operators + bool operator<(const Matrix3&) const; + bool operator>(const Matrix3&) const; + bool operator<=(const Matrix3&) const; + bool operator>=(const Matrix3&) const; + +public: + + /** Initial values are undefined for performance. See also + Matrix3::zero(), Matrix3::identity(), Matrix3::fromAxisAngle, etc.*/ + inline Matrix3() {} + + Matrix3 (const float aafEntry[3][3]); + Matrix3 (const Matrix3& rkMatrix); + Matrix3 (float fEntry00, float fEntry01, float fEntry02, + float fEntry10, float fEntry11, float fEntry12, + float fEntry20, float fEntry21, float fEntry22); + + bool fuzzyEq(const Matrix3& b) const; + + /** Constructs a matrix from a quaternion. + @cite Graphics Gems II, p. 351--354 + @cite Implementation from Watt and Watt, pg 362*/ + Matrix3(const class Quat& q); + + + /** + Sets all elements. + */ + void set(float fEntry00, float fEntry01, float fEntry02, + float fEntry10, float fEntry11, float fEntry12, + float fEntry20, float fEntry21, float fEntry22); + + /** + * member access, allows use of construct mat[r][c] + */ + inline float* operator[] (int iRow) { + debugAssert(iRow >= 0); + debugAssert(iRow < 3); + return (float*)&elt[iRow][0]; + } + + inline const float* operator[] (int iRow) const { + debugAssert(iRow >= 0); + debugAssert(iRow < 3); + return (const float*)&elt[iRow][0]; + } + + inline operator float* () { + return (float*)&elt[0][0]; + } + + inline operator const float* () const{ + return (const float*)&elt[0][0]; + } + + Vector3 getColumn (int iCol) const; + Vector3 getRow (int iRow) const; + void setColumn(int iCol, const Vector3 &vector); + void setRow(int iRow, const Vector3 &vector); + + // assignment and comparison + inline Matrix3& operator= (const Matrix3& rkMatrix) { + System::memcpy(elt, rkMatrix.elt, 9 * sizeof(float)); + return *this; + } + + bool operator== (const Matrix3& rkMatrix) const; + bool operator!= (const Matrix3& rkMatrix) const; + + // arithmetic operations + Matrix3 operator+ (const Matrix3& rkMatrix) const; + Matrix3 operator- (const Matrix3& rkMatrix) const; + /** Matrix-matrix multiply */ + Matrix3 operator* (const Matrix3& rkMatrix) const; + Matrix3 operator- () const; + + Matrix3& operator+= (const Matrix3& rkMatrix); + Matrix3& operator-= (const Matrix3& rkMatrix); + Matrix3& operator*= (const Matrix3& rkMatrix); + + /** + * matrix * vector [3x3 * 3x1 = 3x1] + */ + inline Vector3 operator* (const Vector3& v) const { + Vector3 kProd; + + for (int r = 0; r < 3; ++r) { + kProd[r] = + elt[r][0] * v[0] + + elt[r][1] * v[1] + + elt[r][2] * v[2]; + } + + return kProd; + } + + + /** + * vector * matrix [1x3 * 3x3 = 1x3] + */ + friend Vector3 operator* (const Vector3& rkVector, + const Matrix3& rkMatrix); + + /** + * matrix * scalar + */ + Matrix3 operator* (float fScalar) const; + + /** scalar * matrix */ + friend Matrix3 operator* (double fScalar, const Matrix3& rkMatrix); + friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix); + friend Matrix3 operator* (int fScalar, const Matrix3& rkMatrix); + +private: + /** Multiplication where out != A and out != B */ + static void _mul(const Matrix3& A, const Matrix3& B, Matrix3& out); +public: + + /** Optimized implementation of out = A * B. It is safe (but slow) to call + with A, B, and out possibly pointer equal to one another.*/ + // This is a static method so that it is not ambiguous whether "this" + // is an input or output argument. + inline static void mul(const Matrix3& A, const Matrix3& B, Matrix3& out) { + if ((&out == &A) || (&out == &B)) { + // We need a temporary anyway, so revert to the stack method. + out = A * B; + } else { + // Optimized in-place multiplication. + _mul(A, B, out); + } + } + +private: + static void _transpose(const Matrix3& A, Matrix3& out); +public: + + /** Optimized implementation of out = A.transpose(). It is safe (but slow) to call + with A and out possibly pointer equal to one another. + + Note that A.transpose() * v can be computed + more efficiently as v * A. + */ + inline static void transpose(const Matrix3& A, Matrix3& out) { + if (&A == &out) { + out = A.transpose(); + } else { + _transpose(A, out); + } + } + + /** Returns true if the rows and column L2 norms are 1.0 and the rows are orthogonal. */ + bool isOrthonormal() const; + + Matrix3 transpose () const; + bool inverse (Matrix3& rkInverse, float fTolerance = 1e-06) const; + Matrix3 inverse (float fTolerance = 1e-06) const; + float determinant () const; + + /** singular value decomposition */ + void singularValueDecomposition (Matrix3& rkL, Vector3& rkS, + Matrix3& rkR) const; + /** singular value decomposition */ + void singularValueComposition (const Matrix3& rkL, + const Vector3& rkS, const Matrix3& rkR); + + /** Gram-Schmidt orthonormalization (applied to columns of rotation matrix) */ + void orthonormalize(); + + /** orthogonal Q, diagonal D, upper triangular U stored as (u01,u02,u12) */ + void qDUDecomposition (Matrix3& rkQ, Vector3& rkD, + Vector3& rkU) const; + + float spectralNorm () const; + + /** matrix must be orthonormal */ + void toAxisAngle(Vector3& rkAxis, float& rfRadians) const; + + static Matrix3 fromAxisAngle(const Vector3& rkAxis, float fRadians); + + /** + * The matrix must be orthonormal. The decomposition is yaw*pitch*roll + * where yaw is rotation about the Up vector, pitch is rotation about the + * right axis, and roll is rotation about the Direction axis. + */ + bool toEulerAnglesXYZ (float& rfYAngle, float& rfPAngle, + float& rfRAngle) const; + bool toEulerAnglesXZY (float& rfYAngle, float& rfPAngle, + float& rfRAngle) const; + bool toEulerAnglesYXZ (float& rfYAngle, float& rfPAngle, + float& rfRAngle) const; + bool toEulerAnglesYZX (float& rfYAngle, float& rfPAngle, + float& rfRAngle) const; + bool toEulerAnglesZXY (float& rfYAngle, float& rfPAngle, + float& rfRAngle) const; + bool toEulerAnglesZYX (float& rfYAngle, float& rfPAngle, + float& rfRAngle) const; + static Matrix3 fromEulerAnglesXYZ (float fYAngle, float fPAngle, float fRAngle); + static Matrix3 fromEulerAnglesXZY (float fYAngle, float fPAngle, float fRAngle); + static Matrix3 fromEulerAnglesYXZ (float fYAngle, float fPAngle, float fRAngle); + static Matrix3 fromEulerAnglesYZX (float fYAngle, float fPAngle, float fRAngle); + static Matrix3 fromEulerAnglesZXY (float fYAngle, float fPAngle, float fRAngle); + static Matrix3 fromEulerAnglesZYX (float fYAngle, float fPAngle, float fRAngle); + + /** eigensolver, matrix must be symmetric */ + void eigenSolveSymmetric (float afEigenvalue[3], + Vector3 akEigenvector[3]) const; + + static void tensorProduct (const Vector3& rkU, const Vector3& rkV, + Matrix3& rkProduct); + std::string toString() const; + + static const float EPSILON; + + // Special values. + // The unguaranteed order of initialization of static variables across + // translation units can be a source of annoying bugs, so now the static + // special values (like Vector3::ZERO, Color3::WHITE, ...) are wrapped + // inside static functions that return references to them. + // These functions are intentionally not inlined, because: + // "You might be tempted to write [...] them as inline functions + // inside their respective header files, but this is something you + // must definitely not do. An inline function can be duplicated + // in every file in which it appears – and this duplication + // includes the static object definition. Because inline functions + // automatically default to internal linkage, this would result in + // having multiple static objects across the various translation + // units, which would certainly cause problems. So you must + // ensure that there is only one definition of each wrapping + // function, and this means not making the wrapping functions inline", + // according to Chapter 10 of "Thinking in C++, 2nd ed. Volume 1" by Bruce Eckel, + // http://www.mindview.net/ + static const Matrix3& zero(); + static const Matrix3& identity(); + + // Deprecated. + /** @deprecated Use Matrix3::zero() */ + static const Matrix3 ZERO; + /** @deprecated Use Matrix3::identity() */ + static const Matrix3 IDENTITY; + +protected: + // support for eigensolver + void tridiagonal (float afDiag[3], float afSubDiag[3]); + bool qLAlgorithm (float afDiag[3], float afSubDiag[3]); + + // support for singular value decomposition + static const float ms_fSvdEpsilon; + static const int ms_iSvdMaxIterations; + static void bidiagonalize (Matrix3& kA, Matrix3& kL, + Matrix3& kR); + static void golubKahanStep (Matrix3& kA, Matrix3& kL, + Matrix3& kR); + + // support for spectral norm + static float maxCubicRoot (float afCoeff[3]); + +}; + + +//---------------------------------------------------------------------------- +/** v * M == M.transpose() * v */ +inline Vector3 operator* (const Vector3& rkPoint, const Matrix3& rkMatrix) { + Vector3 kProd; + + for (int r = 0; r < 3; ++r) { + kProd[r] = + rkPoint[0] * rkMatrix.elt[0][r] + + rkPoint[1] * rkMatrix.elt[1][r] + + rkPoint[2] * rkMatrix.elt[2][r]; + } + + return kProd; +} + + +} // namespace + +#endif + diff --git a/dep/include/g3dlite/G3D/Plane.h b/dep/include/g3dlite/G3D/Plane.h new file mode 100644 index 000000000..f00c15c09 --- /dev/null +++ b/dep/include/g3dlite/G3D/Plane.h @@ -0,0 +1,156 @@ +/** + @file Plane.h + + Plane class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2004-07-18 +*/ + +#ifndef G3D_PLANE_H +#define G3D_PLANE_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/Vector4.h" + +namespace G3D { + +/** + An infinite 2D plane in 3D space. + */ +class Plane { +private: + + /** normal.Dot(x,y,z) = distance */ + Vector3 _normal; + float _distance; + + /** + Assumes the normal has unit length. + */ + Plane(const Vector3& n, float d) : _normal(n), _distance(d) { + } + +public: + + Plane() : _normal(Vector3::unitY()), _distance(0) { + } + + /** + Constructs a plane from three points. + */ + Plane( + const Vector3& point0, + const Vector3& point1, + const Vector3& point2); + + /** + Constructs a plane from three points, where at most two are + at infinity (w = 0, not xyz = inf). + */ + Plane( + Vector4 point0, + Vector4 point1, + Vector4 point2); + + /** + The normal will be unitized. + */ + Plane( + const Vector3& __normal, + const Vector3& point); + + static Plane fromEquation(float a, float b, float c, float d); + + virtual ~Plane() {} + + /** + Returns true if point is on the side the normal points to or + is in the plane. + */ + inline bool halfSpaceContains(Vector3 point) const { + // Clamp to a finite range for testing + point = point.clamp(Vector3::minFinite(), Vector3::maxFinite()); + + // We can get away with putting values *at* the limits of the float32 range into + // a dot product, since the dot product is carried out on float64. + return _normal.dot(point) >= _distance; + } + + /** + Returns true if point is on the side the normal points to or + is in the plane. + */ + inline bool halfSpaceContains(const Vector4& point) const { + if (point.w == 0) { + return _normal.dot(point.xyz()) > 0; + } else { + return halfSpaceContains(point.xyz() / point.w); + } + } + + /** + Returns true if point is on the side the normal points to or + is in the plane. Only call on finite points. Faster than halfSpaceContains. + */ + inline bool halfSpaceContainsFinite(const Vector3& point) const { + debugAssert(point.isFinite()); + return _normal.dot(point) >= _distance; + } + + /** + Returns true if the point is nearly in the plane. + */ + inline bool fuzzyContains(const Vector3 &point) const { + return fuzzyEq(point.dot(_normal), _distance); + } + + inline const Vector3& normal() const { + return _normal; + } + + /** + Returns distance from point to plane. Distance is negative if point is behind (not in plane in direction opposite normal) the plane. + */ + inline float distance(const Vector3& x) const { + return (_normal.dot(x) - _distance); + } + + inline Vector3 closestPoint(const Vector3& x) const { + return x + (_normal * (-distance(x))); + } + + /** Returns normal * distance from origin */ + Vector3 center() const { + return _normal * _distance; + } + + /** + Inverts the facing direction of the plane so the new normal + is the inverse of the old normal. + */ + void flip(); + + /** + Returns the equation in the form: + + normal.Dot(Vector3(x, y, z)) + d = 0 + */ + void getEquation(Vector3 &normal, double& d) const; + void getEquation(Vector3 &normal, float& d) const; + + /** + ax + by + cz + d = 0 + */ + void getEquation(double& a, double& b, double& c, double& d) const; + void getEquation(float& a, float& b, float& c, float& d) const; + + std::string toString() const; +}; + +} // namespace + +#endif diff --git a/dep/include/g3dlite/G3D/Quat.h b/dep/include/g3dlite/G3D/Quat.h new file mode 100644 index 000000000..b852fe0fd --- /dev/null +++ b/dep/include/g3dlite/G3D/Quat.h @@ -0,0 +1,702 @@ +/** + @file Quat.h + + Quaternion + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2002-01-23 + @edited 2006-05-10 + */ + +#ifndef G3D_QUAT_H +#define G3D_QUAT_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include "G3D/Vector3.h" +#include "G3D/Matrix3.h" +#include + +namespace G3D { + +/** + Unit quaternions are used in computer graphics to represent + rotation about an axis. Any 3x3 rotation matrix can + be stored as a quaternion. + + A quaternion represents the sum of a real scalar and + an imaginary vector: ix + jy + kz + w. A unit quaternion + representing a rotation by A about axis v has the form + [sin(A/2)*v, cos(A/2)]. For a unit quaternion, q.conj() == q.inverse() + is a rotation by -A about v. -q is the same rotation as q + (negate both the axis and angle). + + A non-unit quaterion q represents the same rotation as + q.unitize() (Dam98 pg 28). + + Although quaternion-vector operations (eg. Quat + Vector3) are + well defined, they are not supported by this class because + they typically are bugs when they appear in code. + + Do not subclass. + + BETA API -- subject to change + @cite Erik B. Dam, Martin Koch, Martin Lillholm, Quaternions, Interpolation and Animation. Technical Report DIKU-TR-98/5, Department of Computer Science, University of Copenhagen, Denmark. 1998. + */ +class Quat { +private: + // Hidden operators + bool operator<(const Quat&) const; + bool operator>(const Quat&) const; + bool operator<=(const Quat&) const; + bool operator>=(const Quat&) const; + +public: + + /** + q = [sin(angle / 2) * axis, cos(angle / 2)] + + In Watt & Watt's notation, s = w, v = (x, y, z) + In the Real-Time Rendering notation, u = (x, y, z), w = w + */ + float x, y, z, w; + + /** + Initializes to a zero degree rotation. + */ + inline Quat() : x(0), y(0), z(0), w(1) {} + + Quat( + const Matrix3& rot); + + inline Quat(float _x, float _y, float _z, float _w) : + x(_x), y(_y), z(_z), w(_w) {} + + /** Defaults to a pure vector quaternion */ + inline Quat(const Vector3& v, float _w = 0) : x(v.x), y(v.y), z(v.z), w(_w) { + } + + /** + The real part of the quaternion. + */ + inline const float& real() const { + return w; + } + + inline float& real() { + return w; + } + + /** Note: two quats can represent the Quat::sameRotation and not be equal. */ + bool fuzzyEq(const Quat& q) { + return G3D::fuzzyEq(x, q.x) && G3D::fuzzyEq(y, q.y) && G3D::fuzzyEq(z, q.z) && G3D::fuzzyEq(w, q.w); + } + + /** True if these quaternions represent the same rotation (note that every rotation is + represented by two values; q and -q). + */ + bool sameRotation(const Quat& q) { + return fuzzyEq(q) || fuzzyEq(-q); + } + + inline Quat operator-() const { + return Quat(-x, -y, -z, -w); + } + + /** + Returns the imaginary part (x, y, z) + */ + inline const Vector3& imag() const { + return *(reinterpret_cast(this)); + } + + inline Vector3& imag() { + return *(reinterpret_cast(this)); + } + + /** q = [sin(angle/2)*axis, cos(angle/2)] */ + static Quat fromAxisAngleRotation( + const Vector3& axis, + float angle); + + /** Returns the axis and angle of rotation represented + by this quaternion (i.e. q = [sin(angle/2)*axis, cos(angle/2)]) */ + void toAxisAngleRotation( + Vector3& axis, + double& angle) const; + + void toAxisAngleRotation( + Vector3& axis, + float& angle) const { + double d; + toAxisAngleRotation(axis, d); + angle = (float)d; + } + + Matrix3 toRotationMatrix() const; + + void toRotationMatrix( + Matrix3& rot) const; + + /** + Spherical linear interpolation: linear interpolation along the + shortest (3D) great-circle route between two quaternions. + + Note: Correct rotations are expected between 0 and PI in the right order. + + @cite Based on Game Physics -- David Eberly pg 538-540 + @param threshold Critical angle between between rotations at which + the algorithm switches to normalized lerp, which is more + numerically stable in those situations. 0.0 will always slerp. + */ + Quat slerp( + const Quat& other, + float alpha, + float threshold = 0.05f) const; + + /** Normalized linear interpolation of quaternion components. */ + Quat nlerp(const Quat& other, float alpha) const; + + /** + Negates the imaginary part. + */ + inline Quat conj() const { + return Quat(-x, -y, -z, w); + } + + inline float sum() const { + return x + y + z + w; + } + + inline float average() const { + return sum() / 4.0f; + } + + inline Quat operator*(float s) const { + return Quat(x * s, y * s, z * s, w * s); + } + + /** @cite Based on Watt & Watt, page 360 */ + friend Quat operator* (float s, const Quat& q); + + inline Quat operator/(float s) const { + return Quat(x / s, y / s, z / s, w / s); + } + + inline float dot(const Quat& other) const { + return (x * other.x) + (y * other.y) + (z * other.z) + (w * other.w); + } + + /** Note that q-1 = q.conj() for a unit quaternion. + @cite Dam99 page 13 */ + inline Quat inverse() const { + return conj() / dot(*this); + } + + Quat operator-(const Quat& other) const; + + Quat operator+(const Quat& other) const; + + /** + Quaternion multiplication (composition of rotations). + Note that this does not commute. + */ + Quat operator*(const Quat& other) const; + + /* (*this) * other.inverse() */ + Quat operator/(const Quat& other) const { + return (*this) * other.inverse(); + } + + + /** Is the magnitude nearly 1.0? */ + inline bool isUnit(float tolerance = 1e-5) const { + return abs(dot(*this) - 1.0f) < tolerance; + } + + + inline float magnitude() const { + return sqrtf(dot(*this)); + } + + inline Quat log() const { + if ((x == 0) && (y == 0) && (z == 0)) { + if (w > 0) { + return Quat(0, 0, 0, ::logf(w)); + } else if (w < 0) { + // Log of a negative number. Multivalued, any number of the form + // (PI * v, ln(-q.w)) + return Quat((float)G3D_PI, 0, 0, ::logf(-w)); + } else { + // log of zero! + return Quat((float)nan(), (float)nan(), (float)nan(), (float)nan()); + } + } else { + // Partly imaginary. + float imagLen = sqrtf(x * x + y * y + z * z); + float len = sqrtf(imagLen * imagLen + w * w); + float theta = atan2f(imagLen, (float)w); + float t = theta / imagLen; + return Quat(t * x, t * y, t * z, ::logf(len)); + } + } + /** log q = [Av, 0] where q = [sin(A) * v, cos(A)]. + Only for unit quaternions + debugAssertM(isUnit(), "Log only defined for unit quaternions"); + // Solve for A in q = [sin(A)*v, cos(A)] + Vector3 u(x, y, z); + double len = u.magnitude(); + + if (len == 0.0) { + return + } + double A = atan2((double)w, len); + Vector3 v = u / len; + + return Quat(v * A, 0); + } + */ + + /** exp q = [sin(A) * v, cos(A)] where q = [Av, 0]. + Only defined for pure-vector quaternions */ + inline Quat exp() const { + debugAssertM(w == 0, "exp only defined for vector quaternions"); + Vector3 u(x, y, z); + float A = u.magnitude(); + Vector3 v = u / A; + return Quat(sinf(A) * v, cosf(A)); + } + + + /** + Raise this quaternion to a power. For a rotation, this is + the effect of rotating x times as much as the original + quaterion. + + Note that q.pow(a).pow(b) == q.pow(a + b) + @cite Dam98 pg 21 + */ + inline Quat pow(float x) const { + return (log() * x).exp(); + } + + + /** + @deprecated + Use toUnit() + */ + inline Quat unitize() const { + float mag2 = dot(*this); + if (G3D::fuzzyEq(mag2, 1.0f)) { + return *this; + } else { + return *this / sqrtf(mag2); + } + } + + /** + Returns a unit quaterion obtained by dividing through by + the magnitude. + */ + inline Quat toUnit() const { + return unitize(); + } + + /** + The linear algebra 2-norm, sqrt(q dot q). This matches + the value used in Dam's 1998 tech report but differs from the + n(q) value used in Eberly's 1999 paper, which is the square of the + norm. + */ + inline float norm() const { + return magnitude(); + } + + // access quaternion as q[0] = q.x, q[1] = q.y, q[2] = q.z, q[3] = q.w + // + // WARNING. These member functions rely on + // (1) Quat not having virtual functions + // (2) the data packed in a 4*sizeof(float) memory block + const float& operator[] (int i) const; + float& operator[] (int i); + + /** Generate uniform random unit quaternion (i.e. random "direction") + @cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III. + */ + static Quat unitRandom(); + + // 2-char swizzles + + Vector2 xx() const; + Vector2 yx() const; + Vector2 zx() const; + Vector2 wx() const; + Vector2 xy() const; + Vector2 yy() const; + Vector2 zy() const; + Vector2 wy() const; + Vector2 xz() const; + Vector2 yz() const; + Vector2 zz() const; + Vector2 wz() const; + Vector2 xw() const; + Vector2 yw() const; + Vector2 zw() const; + Vector2 ww() const; + + // 3-char swizzles + + Vector3 xxx() const; + Vector3 yxx() const; + Vector3 zxx() const; + Vector3 wxx() const; + Vector3 xyx() const; + Vector3 yyx() const; + Vector3 zyx() const; + Vector3 wyx() const; + Vector3 xzx() const; + Vector3 yzx() const; + Vector3 zzx() const; + Vector3 wzx() const; + Vector3 xwx() const; + Vector3 ywx() const; + Vector3 zwx() const; + Vector3 wwx() const; + Vector3 xxy() const; + Vector3 yxy() const; + Vector3 zxy() const; + Vector3 wxy() const; + Vector3 xyy() const; + Vector3 yyy() const; + Vector3 zyy() const; + Vector3 wyy() const; + Vector3 xzy() const; + Vector3 yzy() const; + Vector3 zzy() const; + Vector3 wzy() const; + Vector3 xwy() const; + Vector3 ywy() const; + Vector3 zwy() const; + Vector3 wwy() const; + Vector3 xxz() const; + Vector3 yxz() const; + Vector3 zxz() const; + Vector3 wxz() const; + Vector3 xyz() const; + Vector3 yyz() const; + Vector3 zyz() const; + Vector3 wyz() const; + Vector3 xzz() const; + Vector3 yzz() const; + Vector3 zzz() const; + Vector3 wzz() const; + Vector3 xwz() const; + Vector3 ywz() const; + Vector3 zwz() const; + Vector3 wwz() const; + Vector3 xxw() const; + Vector3 yxw() const; + Vector3 zxw() const; + Vector3 wxw() const; + Vector3 xyw() const; + Vector3 yyw() const; + Vector3 zyw() const; + Vector3 wyw() const; + Vector3 xzw() const; + Vector3 yzw() const; + Vector3 zzw() const; + Vector3 wzw() const; + Vector3 xww() const; + Vector3 yww() const; + Vector3 zww() const; + Vector3 www() const; + + // 4-char swizzles + + Vector4 xxxx() const; + Vector4 yxxx() const; + Vector4 zxxx() const; + Vector4 wxxx() const; + Vector4 xyxx() const; + Vector4 yyxx() const; + Vector4 zyxx() const; + Vector4 wyxx() const; + Vector4 xzxx() const; + Vector4 yzxx() const; + Vector4 zzxx() const; + Vector4 wzxx() const; + Vector4 xwxx() const; + Vector4 ywxx() const; + Vector4 zwxx() const; + Vector4 wwxx() const; + Vector4 xxyx() const; + Vector4 yxyx() const; + Vector4 zxyx() const; + Vector4 wxyx() const; + Vector4 xyyx() const; + Vector4 yyyx() const; + Vector4 zyyx() const; + Vector4 wyyx() const; + Vector4 xzyx() const; + Vector4 yzyx() const; + Vector4 zzyx() const; + Vector4 wzyx() const; + Vector4 xwyx() const; + Vector4 ywyx() const; + Vector4 zwyx() const; + Vector4 wwyx() const; + Vector4 xxzx() const; + Vector4 yxzx() const; + Vector4 zxzx() const; + Vector4 wxzx() const; + Vector4 xyzx() const; + Vector4 yyzx() const; + Vector4 zyzx() const; + Vector4 wyzx() const; + Vector4 xzzx() const; + Vector4 yzzx() const; + Vector4 zzzx() const; + Vector4 wzzx() const; + Vector4 xwzx() const; + Vector4 ywzx() const; + Vector4 zwzx() const; + Vector4 wwzx() const; + Vector4 xxwx() const; + Vector4 yxwx() const; + Vector4 zxwx() const; + Vector4 wxwx() const; + Vector4 xywx() const; + Vector4 yywx() const; + Vector4 zywx() const; + Vector4 wywx() const; + Vector4 xzwx() const; + Vector4 yzwx() const; + Vector4 zzwx() const; + Vector4 wzwx() const; + Vector4 xwwx() const; + Vector4 ywwx() const; + Vector4 zwwx() const; + Vector4 wwwx() const; + Vector4 xxxy() const; + Vector4 yxxy() const; + Vector4 zxxy() const; + Vector4 wxxy() const; + Vector4 xyxy() const; + Vector4 yyxy() const; + Vector4 zyxy() const; + Vector4 wyxy() const; + Vector4 xzxy() const; + Vector4 yzxy() const; + Vector4 zzxy() const; + Vector4 wzxy() const; + Vector4 xwxy() const; + Vector4 ywxy() const; + Vector4 zwxy() const; + Vector4 wwxy() const; + Vector4 xxyy() const; + Vector4 yxyy() const; + Vector4 zxyy() const; + Vector4 wxyy() const; + Vector4 xyyy() const; + Vector4 yyyy() const; + Vector4 zyyy() const; + Vector4 wyyy() const; + Vector4 xzyy() const; + Vector4 yzyy() const; + Vector4 zzyy() const; + Vector4 wzyy() const; + Vector4 xwyy() const; + Vector4 ywyy() const; + Vector4 zwyy() const; + Vector4 wwyy() const; + Vector4 xxzy() const; + Vector4 yxzy() const; + Vector4 zxzy() const; + Vector4 wxzy() const; + Vector4 xyzy() const; + Vector4 yyzy() const; + Vector4 zyzy() const; + Vector4 wyzy() const; + Vector4 xzzy() const; + Vector4 yzzy() const; + Vector4 zzzy() const; + Vector4 wzzy() const; + Vector4 xwzy() const; + Vector4 ywzy() const; + Vector4 zwzy() const; + Vector4 wwzy() const; + Vector4 xxwy() const; + Vector4 yxwy() const; + Vector4 zxwy() const; + Vector4 wxwy() const; + Vector4 xywy() const; + Vector4 yywy() const; + Vector4 zywy() const; + Vector4 wywy() const; + Vector4 xzwy() const; + Vector4 yzwy() const; + Vector4 zzwy() const; + Vector4 wzwy() const; + Vector4 xwwy() const; + Vector4 ywwy() const; + Vector4 zwwy() const; + Vector4 wwwy() const; + Vector4 xxxz() const; + Vector4 yxxz() const; + Vector4 zxxz() const; + Vector4 wxxz() const; + Vector4 xyxz() const; + Vector4 yyxz() const; + Vector4 zyxz() const; + Vector4 wyxz() const; + Vector4 xzxz() const; + Vector4 yzxz() const; + Vector4 zzxz() const; + Vector4 wzxz() const; + Vector4 xwxz() const; + Vector4 ywxz() const; + Vector4 zwxz() const; + Vector4 wwxz() const; + Vector4 xxyz() const; + Vector4 yxyz() const; + Vector4 zxyz() const; + Vector4 wxyz() const; + Vector4 xyyz() const; + Vector4 yyyz() const; + Vector4 zyyz() const; + Vector4 wyyz() const; + Vector4 xzyz() const; + Vector4 yzyz() const; + Vector4 zzyz() const; + Vector4 wzyz() const; + Vector4 xwyz() const; + Vector4 ywyz() const; + Vector4 zwyz() const; + Vector4 wwyz() const; + Vector4 xxzz() const; + Vector4 yxzz() const; + Vector4 zxzz() const; + Vector4 wxzz() const; + Vector4 xyzz() const; + Vector4 yyzz() const; + Vector4 zyzz() const; + Vector4 wyzz() const; + Vector4 xzzz() const; + Vector4 yzzz() const; + Vector4 zzzz() const; + Vector4 wzzz() const; + Vector4 xwzz() const; + Vector4 ywzz() const; + Vector4 zwzz() const; + Vector4 wwzz() const; + Vector4 xxwz() const; + Vector4 yxwz() const; + Vector4 zxwz() const; + Vector4 wxwz() const; + Vector4 xywz() const; + Vector4 yywz() const; + Vector4 zywz() const; + Vector4 wywz() const; + Vector4 xzwz() const; + Vector4 yzwz() const; + Vector4 zzwz() const; + Vector4 wzwz() const; + Vector4 xwwz() const; + Vector4 ywwz() const; + Vector4 zwwz() const; + Vector4 wwwz() const; + Vector4 xxxw() const; + Vector4 yxxw() const; + Vector4 zxxw() const; + Vector4 wxxw() const; + Vector4 xyxw() const; + Vector4 yyxw() const; + Vector4 zyxw() const; + Vector4 wyxw() const; + Vector4 xzxw() const; + Vector4 yzxw() const; + Vector4 zzxw() const; + Vector4 wzxw() const; + Vector4 xwxw() const; + Vector4 ywxw() const; + Vector4 zwxw() const; + Vector4 wwxw() const; + Vector4 xxyw() const; + Vector4 yxyw() const; + Vector4 zxyw() const; + Vector4 wxyw() const; + Vector4 xyyw() const; + Vector4 yyyw() const; + Vector4 zyyw() const; + Vector4 wyyw() const; + Vector4 xzyw() const; + Vector4 yzyw() const; + Vector4 zzyw() const; + Vector4 wzyw() const; + Vector4 xwyw() const; + Vector4 ywyw() const; + Vector4 zwyw() const; + Vector4 wwyw() const; + Vector4 xxzw() const; + Vector4 yxzw() const; + Vector4 zxzw() const; + Vector4 wxzw() const; + Vector4 xyzw() const; + Vector4 yyzw() const; + Vector4 zyzw() const; + Vector4 wyzw() const; + Vector4 xzzw() const; + Vector4 yzzw() const; + Vector4 zzzw() const; + Vector4 wzzw() const; + Vector4 xwzw() const; + Vector4 ywzw() const; + Vector4 zwzw() const; + Vector4 wwzw() const; + Vector4 xxww() const; + Vector4 yxww() const; + Vector4 zxww() const; + Vector4 wxww() const; + Vector4 xyww() const; + Vector4 yyww() const; + Vector4 zyww() const; + Vector4 wyww() const; + Vector4 xzww() const; + Vector4 yzww() const; + Vector4 zzww() const; + Vector4 wzww() const; + Vector4 xwww() const; + Vector4 ywww() const; + Vector4 zwww() const; + Vector4 wwww() const; +}; + +inline Quat exp(const Quat& q) { + return q.exp(); +} + +inline Quat log(const Quat& q) { + return q.log(); +} + +inline G3D::Quat operator*(double s, const G3D::Quat& q) { + return q * (float)s; +} + +inline G3D::Quat operator*(float s, const G3D::Quat& q) { + return q * s; +} + +} // Namespace G3D + +// Outside the namespace to avoid overloading confusion for C++ +inline G3D::Quat pow(const G3D::Quat& q, double x) { + return q.pow((float)x); +} + + + +#include "Quat.inl" + +#endif diff --git a/dep/include/g3dlite/G3D/Quat.inl b/dep/include/g3dlite/G3D/Quat.inl new file mode 100644 index 000000000..705cb0455 --- /dev/null +++ b/dep/include/g3dlite/G3D/Quat.inl @@ -0,0 +1,38 @@ +/** + Quat.inl + + @cite Quaternion implementation based on Watt & Watt page 363. + Thanks to Max McGuire for slerp optimizations. + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2002-01-23 + @edited 2004-03-04 + */ + +namespace G3D { + +inline float& Quat::operator[] (int i) { + debugAssert(i >= 0); + debugAssert(i < 4); + return ((float*)this)[i]; +} + +inline const float& Quat::operator[] (int i) const { + debugAssert(i >= 0); + debugAssert(i < 4); + return ((float*)this)[i]; +} + + + +inline Quat Quat::operator-(const Quat& other) const { + return Quat(x - other.x, y - other.y, z - other.z, w - other.w); +} + +inline Quat Quat::operator+(const Quat& other) const { + return Quat(x + other.x, y + other.y, z + other.z, w + other.w); +} + +} + diff --git a/dep/include/g3dlite/G3D/Ray.h b/dep/include/g3dlite/G3D/Ray.h new file mode 100644 index 000000000..3b54f145c --- /dev/null +++ b/dep/include/g3dlite/G3D/Ray.h @@ -0,0 +1,327 @@ +/** + @file Ray.h + + Ray class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2002-07-12 + @edited 2006-02-21 + */ + +#ifndef G3D_RAY_H +#define G3D_RAY_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/Triangle.h" + +namespace G3D { + +/** + A 3D Ray. + */ +class Ray { +private: + Ray(const Vector3& origin, const Vector3& direction) { + this->origin = origin; + this->direction = direction; + } + +public: + Vector3 origin; + + /** + Not unit length + */ + Vector3 direction; + + Ray() : origin(Vector3::zero()), direction(Vector3::zero()) {} + + virtual ~Ray() {} + + /** + Creates a Ray from a origin and a (nonzero) direction. + */ + static Ray fromOriginAndDirection(const Vector3& point, const Vector3& direction) { + return Ray(point, direction); + } + + Ray unit() const { + return Ray(origin, direction.unit()); + } + + /** + Returns the closest point on the Ray to point. + */ + Vector3 closestPoint(const Vector3& point) const { + float t = direction.dot(point - this->origin); + if (t < 0) { + return this->origin; + } else { + return this->origin + direction * t; + } + } + + /** + Returns the closest distance between point and the Ray + */ + float distance(const Vector3& point) const { + return (closestPoint(point) - point).magnitude(); + } + + /** + Returns the point where the Ray and plane intersect. If there + is no intersection, returns a point at infinity. + + Planes are considered one-sided, so the ray will not intersect + a plane where the normal faces in the traveling direction. + */ + Vector3 intersection(const class Plane& plane) const; + + /** + Returns the distance until intersection with the (solid) sphere. + Will be 0 if inside the sphere, inf if there is no intersection. + + The ray direction is not normalized. If the ray direction + has unit length, the distance from the origin to intersection + is equal to the time. If the direction does not have unit length, + the distance = time * direction.length(). + + See also the G3D::CollisionDetection "movingPoint" methods, + which give more information about the intersection. + */ + float intersectionTime(const class Sphere& sphere) const; + + float intersectionTime(const class Plane& plane) const; + + float intersectionTime(const class Box& box) const; + + float intersectionTime(const class AABox& box) const; + + /** + The three extra arguments are the weights of vertices 0, 1, and 2 + at the intersection point; they are useful for texture mapping + and interpolated normals. + */ + float intersectionTime( + const Vector3& v0, const Vector3& v1, const Vector3& v2, + const Vector3& edge01, const Vector3& edge02, + double& w0, double& w1, double& w2) const; + + /** + Ray-triangle intersection for a 1-sided triangle. Fastest version. + @cite http://www.acm.org/jgt/papers/MollerTrumbore97/ + http://www.graphics.cornell.edu/pubs/1997/MT97.html + */ + inline float intersectionTime( + const Vector3& vert0, + const Vector3& vert1, + const Vector3& vert2, + const Vector3& edge01, + const Vector3& edge02) const; + + + inline float intersectionTime( + const Vector3& vert0, + const Vector3& vert1, + const Vector3& vert2) const { + + return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0); + } + + + inline float intersectionTime( + const Vector3& vert0, + const Vector3& vert1, + const Vector3& vert2, + double& w0, + double& w1, + double& w2) const { + + return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0, w0, w1, w2); + } + + /* One-sided triangle + */ + inline float intersectionTime(const Triangle& triangle) const { + return intersectionTime( + triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), + triangle.edge01, triangle.edge02); + } + + inline float intersectionTime( + const Triangle& triangle, + double& w0, + double& w1, + double& w2) const { + return intersectionTime(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), + triangle.edge01, triangle.edge02, w0, w1, w2); + } + + /** Refracts about the normal + using G3D::Vector3::refractionDirection + and bumps the ray slightly from the newOrigin. */ + Ray refract( + const Vector3& newOrigin, + const Vector3& normal, + float iInside, + float iOutside) const; + + /** Reflects about the normal + using G3D::Vector3::reflectionDirection + and bumps the ray slightly from + the newOrigin. */ + Ray reflect( + const Vector3& newOrigin, + const Vector3& normal) const; +}; + + +#define EPSILON 0.000001 +#define CROSS(dest,v1,v2) \ + dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ + dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ + dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; + +#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) + +#define SUB(dest,v1,v2) \ + dest[0]=v1[0]-v2[0]; \ + dest[1]=v1[1]-v2[1]; \ + dest[2]=v1[2]-v2[2]; + +inline float Ray::intersectionTime( + const Vector3& vert0, + const Vector3& vert1, + const Vector3& vert2, + const Vector3& edge1, + const Vector3& edge2) const { + + (void)vert1; + (void)vert2; + + // Barycenteric coords + float u, v; + + float tvec[3], pvec[3], qvec[3]; + + // begin calculating determinant - also used to calculate U parameter + CROSS(pvec, direction, edge2); + + // if determinant is near zero, ray lies in plane of triangle + const float det = DOT(edge1, pvec); + + if (det < EPSILON) { + return (float)inf(); + } + + // calculate distance from vert0 to ray origin + SUB(tvec, origin, vert0); + + // calculate U parameter and test bounds + u = DOT(tvec, pvec); + if ((u < 0.0f) || (u > det)) { + // Hit the plane outside the triangle + return (float)inf(); + } + + // prepare to test V parameter + CROSS(qvec, tvec, edge1); + + // calculate V parameter and test bounds + v = DOT(direction, qvec); + if ((v < 0.0f) || (u + v > det)) { + // Hit the plane outside the triangle + return (float)inf(); + } + + + // Case where we don't need correct (u, v): + const float t = DOT(edge2, qvec); + + if (t >= 0.0f) { + // Note that det must be positive + return t / det; + } else { + // We had to travel backwards in time to intersect + return (float)inf(); + } +} + + +inline float Ray::intersectionTime( + const Vector3& vert0, + const Vector3& vert1, + const Vector3& vert2, + const Vector3& edge1, + const Vector3& edge2, + double& w0, + double& w1, + double& w2) const { + + (void)vert1; + (void)vert2; + + // Barycenteric coords + float u, v; + + float tvec[3], pvec[3], qvec[3]; + + // begin calculating determinant - also used to calculate U parameter + CROSS(pvec, direction, edge2); + + // if determinant is near zero, ray lies in plane of triangle + const float det = DOT(edge1, pvec); + + if (det < EPSILON) { + return (float)inf(); + } + + // calculate distance from vert0 to ray origin + SUB(tvec, origin, vert0); + + // calculate U parameter and test bounds + u = DOT(tvec, pvec); + if ((u < 0.0f) || (u > det)) { + // Hit the plane outside the triangle + return (float)inf(); + } + + // prepare to test V parameter + CROSS(qvec, tvec, edge1); + + // calculate V parameter and test bounds + v = DOT(direction, qvec); + if ((v < 0.0f) || (u + v > det)) { + // Hit the plane outside the triangle + return (float)inf(); + } + + float t = DOT(edge2, qvec); + + if (t >= 0) { + const float inv_det = 1.0f / det; + t *= inv_det; + u *= inv_det; + v *= inv_det; + + w0 = (1.0f - u - v); + w1 = u; + w2 = v; + + return t; + } else { + // We had to travel backwards in time to intersect + return (float)inf(); + } +} + +#undef EPSILON +#undef CROSS +#undef DOT +#undef SUB + +}// namespace + +#endif diff --git a/dep/include/g3dlite/G3D/RegistryUtil.h b/dep/include/g3dlite/G3D/RegistryUtil.h new file mode 100644 index 000000000..97de8d067 --- /dev/null +++ b/dep/include/g3dlite/G3D/RegistryUtil.h @@ -0,0 +1,86 @@ +/** + @file RegistryUtil.h + + @created 2006-04-06 + @edited 2006-04-06 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. +*/ + +#ifndef G3D_REGISTRYUTIL_H +#define G3D_REGISTRYUTIL_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" + +// This file is only used on Windows +#ifdef G3D_WIN32 + +#include + +namespace G3D { + +/** + Provides generalized Windows registry querying. + + All key names are one string in the format: + "[base key]\[sub-keys]\value" + + [base key] can be any of the following: + HKEY_CLASSES_ROOT + HKEY_CURRENT_CONFIG + HKEY_CURRENT_USER + HKEY_LOCAL_MACHINE + HKEY_PERFORMANCE_DATA + HKEY_PERFORMANCE_NLSTEXT + HKEY_PERFORMANCE_TEXT + HKEY_USERS + + keyExists() should be used to validate a key before reading or writing + to ensure that a debug assert or false return is for a different error. +*/ +class RegistryUtil { + +public: + /** returns true if the key exists */ + static bool keyExists(const std::string& key); + + /** returns false if the key could not be read for any reason. */ + static bool readInt32(const std::string& key, int32& valueData); + + /** + Reads an arbitrary amount of data from a binary registry key. + returns false if the key could not be read for any reason. + + @beta + @param valueData pointer to the output buffer of sufficient size. Pass NULL as valueData in order to have available data size returned in dataSize. + @param dataSize size of the output buffer. When NULL is passed for valueData, contains the size of available data on successful return. + */ + static bool readBytes(const std::string& key, uint8* valueData, uint32& dataSize); + + /** returns false if the key could not be read for any reason. */ + static bool readString(const std::string& key, std::string& valueData); + + /** returns false if the key could not be written for any reason. */ + static bool writeInt32(const std::string& key, int32 valueData); + + /** + Writes an arbitrary amount of data to a binary registry key. + returns false if the key could not be written for any reason. + + @param valueData pointer to the input buffer + @param dataSize size of the input buffer that should be written + */ + static bool writeBytes(const std::string& key, const uint8* valueData, uint32 dataSize); + + /** returns false if the key could not be written for any reason. */ + static bool writeString(const std::string& key, const std::string& valueData); + +}; + +} // namespace G3D + +#endif // G3D_WIN32 + +#endif // G3D_REGISTRYTUIL_H \ No newline at end of file diff --git a/dep/include/g3dlite/G3D/Sphere.h b/dep/include/g3dlite/G3D/Sphere.h new file mode 100644 index 000000000..39097e018 --- /dev/null +++ b/dep/include/g3dlite/G3D/Sphere.h @@ -0,0 +1,128 @@ +/** + @file Sphere.h + + Sphere class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2004-07-05 + */ + +#ifndef G3D_SPHERE_H +#define G3D_SPHERE_H + +#include "G3D/platform.h" +#include "G3D/Vector3.h" +#include "G3D/Array.h" +#include "G3D/Sphere.h" + +namespace G3D { + +/** + Sphere. + */ +class Sphere { +private: + + static int32 dummy; + +public: + Vector3 center; + float radius; + + Sphere() { + center = Vector3::zero(); + radius = 0; + } + + Sphere( + const Vector3& center, + float radius) { + + this->center = center; + this->radius = radius; + } + + virtual ~Sphere() {} + + bool operator==(const Sphere& other) const { + return (center == other.center) && (radius == other.radius); + } + + bool operator!=(const Sphere& other) const { + return !((center == other.center) && (radius == other.radius)); + } + + /** + Returns true if point is less than or equal to radius away from + the center. + */ + bool contains(const Vector3& point) const; + +/** + @deprecated Use culledBy(Array&) + */ + bool culledBy( + const class Plane* plane, + int numPlanes, + int32& cullingPlaneIndex, + const uint32 testMask, + uint32& childMask) const; + + /** + @deprecated Use culledBy(Array&) + */ + bool culledBy( + const class Plane* plane, + int numPlanes, + int32& cullingPlaneIndex = dummy, + const uint32 testMask = -1) const; + + /** + See AABox::culledBy + */ + bool culledBy( + const Array& plane, + int32& cullingPlaneIndex, + const uint32 testMask, + uint32& childMask) const; + + /** + Conservative culling test that does not produce a mask for children. + */ + bool culledBy( + const Array& plane, + int32& cullingPlaneIndex = dummy, + const uint32 testMask = -1) const; + virtual std::string toString() const; + + float volume() const; + + /** @deprecated */ + float surfaceArea() const; + + inline float area() const { + return surfaceArea(); + } + + /** + Uniformly distributed on the surface. + */ + Vector3 randomSurfacePoint() const; + + /** + Uniformly distributed on the interior (includes surface) + */ + Vector3 randomInteriorPoint() const; + + void getBounds(class AABox& out) const; +}; + +} // namespace + +inline unsigned int hashCode(const G3D::Sphere& sphere) { + return (unsigned int)(hashCode(sphere.center) + (sphere.radius * 13)); +} + +#endif diff --git a/dep/include/g3dlite/G3D/System.h b/dep/include/g3dlite/G3D/System.h new file mode 100644 index 000000000..507b44670 --- /dev/null +++ b/dep/include/g3dlite/G3D/System.h @@ -0,0 +1,122 @@ +/** + @file System.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm + @cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1 + @cite Michael Herf http://www.stereopsis.com/memcpy.html + + @created 2003-01-25 + @edited 2006-04-26 + */ + +#ifndef G3D_SYSTEM_H +#define G3D_SYSTEM_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include + +#ifdef G3D_OSX +# include +#endif + + +namespace G3D { + +typedef double RealTime; + +class System { +public: + + /** Called automatically by the other System routines.*/ + static void init(); + + /** + Guarantees that the start of the array is aligned to the + specified number of bytes. + */ + static void* alignedMalloc(size_t bytes, size_t alignment); + + /** + Uses pooled storage to optimize small allocations (1 byte to 5 kilobytes). + Can be 10x to 100x faster than calling ::malloc or new. + + The result must be freed with free. + + Threadsafe on Win32. + + @sa calloc realloc OutOfMemoryCallback free + */ + static void* malloc(size_t bytes); + + static void* calloc(size_t n, size_t x); + + /** + @param size Size of memory that the system was trying to allocate + @param recoverable If true, the system will attempt to allocate again + if the callback returns true. If false, malloc is going to return + NULL and this invocation is just to notify the application. + @return Return true to force malloc to attempt allocation again if the + error was recoverable. + */ + typedef bool (*OutOfMemoryCallback)(size_t size, bool recoverable); + + /** + When System::malloc fails to allocate memory because the system is + out of memory, it invokes this handler (if it is not NULL). + The argument to the callback is the amount of memory that malloc + was trying to allocate when it ran out. If the callback returns + true, System::malloc will attempt to allocate the memory again. + If the callback returns false, then System::malloc will return NULL. + + You can use outOfMemoryCallback to free data structures or to + register the failure. + */ + static OutOfMemoryCallback outOfMemoryCallback; + + /** + Version of realloc that works with System::malloc. + */ + static void* realloc(void* block, size_t bytes); + + /** Returns a string describing how well System::malloc is using its internal pooled storage. + "heap" memory was slow to allocate; the other data sizes are comparatively fast.*/ + static std::string mallocPerformance(); + static void resetMallocPerformanceCounters(); + + /** + Returns a string describing the current usage of the buffer pools used for + optimizing System::malloc. + */ + static std::string mallocStatus(); + + /** + Free data allocated with System::malloc. + + Threadsafe on Win32. + */ + static void free(void* p); + + /** + Frees memory allocated with alignedMalloc. + */ + static void alignedFree(void* ptr); + + /** An implementation of memcpy that may be up to 2x as fast as the C library + one on some processors. Guaranteed to have the same behavior as memcpy + in all cases. */ + static void memcpy(void* dst, const void* src, size_t numBytes); + + /** An implementation of memset that may be up to 2x as fast as the C library + one on some processors. Guaranteed to have the same behavior as memset + in all cases. */ + static void memset(void* dst, uint8 value, size_t numBytes); + +}; + + +} // namespace + +#endif diff --git a/dep/include/g3dlite/G3D/Table.h b/dep/include/g3dlite/G3D/Table.h new file mode 100644 index 000000000..285d774d2 --- /dev/null +++ b/dep/include/g3dlite/G3D/Table.h @@ -0,0 +1,695 @@ +/** + @file Table.h + + Templated hash table class. + + @maintainer Morgan McGuire, matrix@graphics3d.com + @created 2001-04-22 + @edited 2006-10-14 + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_TABLE_H +#define G3D_TABLE_H + +#include "G3D/platform.h" +#include "G3D/Array.h" +#include "G3D/debug.h" +#include "G3D/System.h" +#include "G3D/g3dmath.h" +#include "G3D/Crypto.h" +#include +#include + +#ifdef G3D_WIN32 +# pragma warning (push) + // Debug name too long warning +# pragma warning (disable : 4786) +#endif + + +template +struct GHashCode{}; + +template <> +struct GHashCode +{ + size_t operator()(int key) const { return static_cast(key); } +}; + +template <> +struct GHashCode +{ + size_t operator()(G3D::uint32 key) const { return static_cast(key); } +}; + +template <> +struct GHashCode +{ + size_t operator()(G3D::uint64 key) const { return static_cast(key); } +}; + +template <> +struct GHashCode +{ + size_t operator()(const void* key) const { return reinterpret_cast(key); } +}; + +template +struct GHashCode +{ + size_t operator()(const T* key) const { return reinterpret_cast(key); } +}; + +template <> +struct GHashCode +{ + size_t operator()(const std::string& key) const { return static_cast(G3D::Crypto::crc32(key.c_str(), key.size())); } +}; + +template <> +struct GHashCode +{ + size_t operator()(const std::string& key) const { return static_cast(G3D::Crypto::crc32(key.c_str(), key.size())); } +}; + +namespace G3D { + + +/** + An unordered data structure mapping keys to values. + + Key must be a pointer, an int, a std::string, a class with a hashCode() method, + or provide overloads for: + +

+    template<> struct GHashCode {
+        size_t operator()(Key key) const { return reinterpret_cast( ... ); }
+    };
+
+   bool operator==(const Key&, const Key&);
+  
+ + G3D pre-defines GHashCode functions for common types (like int and std::string). + If you use a Table with a different type you must write those functions yourself. For example, + an enum would use: + +
+    template<> struct GHashCode {
+        size_t operator()(MyEnum key) const { return reinterpret_cast( key ); }
+    };
+  
+ + And rely on the default enum operator==. + + + Periodically check that debugGetLoad() is low (> 0.1). When it gets near + 1.0 your hash function is badly designed and maps too many inputs to + the same output. + */ +template > +class Table { +public: + + /** + The pairs returned by iterator. + */ + class Entry { + public: + Key key; + Value value; + }; + +private: + /** + Linked list nodes used internally by HashTable. + */ + class Node { + public: + size_t hashCode; + Entry entry; + Node* next; + + + /** Provide pooled allocation for speed. */ + inline void* operator new (size_t size) { + return System::malloc(size); + } + + inline void operator delete (void* p) { + System::free(p); + } + + + Node(Key key, Value value, size_t hashCode, Node* next) { + this->entry.key = key; + this->entry.value = value; + this->hashCode = hashCode; + this->next = next; + } + + /** + Clones a whole chain; + */ + Node* clone() { + return new Node(this->entry.key, this->entry.value, hashCode, (next == NULL) ? NULL : next->clone()); + } + }; + + HashFunc m_HashFunc; + + /** + Number of elements in the table. + */ + size_t _size; + + /** + Array of Node*. + We don't use Array because Table is lower level. + Some elements may be NULL. + */ + Node** bucket; + + /** + Length of the bucket array. + */ + size_t numBuckets; + + /** + Re-hashes for a larger bucket size. + */ + void resize(size_t numBuckets) { + + Node** oldBucket = bucket; + bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16); + System::memset(bucket, 0, sizeof(Node*) * numBuckets); + + for (size_t b = 0; b < this->numBuckets; b++) { + Node* node = oldBucket[b]; + + while (node != NULL) { + Node* nextNode = node->next; + + // insert at the head of the list for bucket[i] + size_t i = node->hashCode % numBuckets; + node->next = bucket[i]; + bucket[i] = node; + + node = nextNode; + } + } + + System::alignedFree(oldBucket); + this->numBuckets = numBuckets; + } + + void copyFrom(const Table& h) { + this->_size = h._size; + this->numBuckets = h.numBuckets; + this->bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16); + System::memset(this->bucket, 0, sizeof(Node*) * numBuckets); + for (size_t b = 0; b < this->numBuckets; b++) { + if (h.bucket[b] != NULL) { + bucket[b] = h.bucket[b]->clone(); + } + } + } + + /** + Frees the heap structures for the nodes. + */ + void freeMemory() { + for (size_t b = 0; b < numBuckets; b++) { + Node* node = bucket[b]; + while (node != NULL) { + Node* next = node->next; + delete node; + node = next; + } + } + System::alignedFree(bucket); + bucket = NULL; + numBuckets = 0; + _size = 0; + } + +public: + + /** + Creates an empty hash table. This causes some heap allocation to occur. + */ + Table() { + numBuckets = 10; + _size = 0; + bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16); + System::memset(bucket, 0, sizeof(Node*) * numBuckets); + } + + /** + Destroys all of the memory allocated by the table, but does not + call delete on keys or values if they are pointers. If you want to + deallocate things that the table points at, use getKeys() and Array::deleteAll() + to delete them. + */ + virtual ~Table() { + freeMemory(); + } + + Table(const Table& h) { + this->copyFrom(h); + } + + Table& operator=(const Table& h) { + // No need to copy if the argument is this + if (this != &h) { + // Free the existing nodes + freeMemory(); + this->copyFrom(h); + } + return *this; + } + + /** + Returns the length of the deepest bucket. + */ + size_t debugGetDeepestBucketSize() const { + size_t deepest = 0; + + for (size_t b = 0; b < numBuckets; b++) { + size_t count = 0; + Node* node = bucket[b]; + while (node != NULL) { + node = node->next; + ++count; + } + + if (count > deepest) { + deepest = count; + } + } + + return deepest; + } + + /** + A small load (close to zero) means the hash table is acting very + efficiently most of the time. A large load (close to 1) means + the hash table is acting poorly-- all operations will be very slow. + A large load will result from a bad hash function that maps too + many keys to the same code. + */ + double debugGetLoad() const { + return debugGetDeepestBucketSize() / (double)size(); + } + + /** + Returns the number of buckets. + */ + size_t debugGetNumBuckets() const { + return numBuckets; + } + + /** + C++ STL style iterator variable. See begin(). + */ + class Iterator { + private: + friend class Table; + + /** + Bucket index. + */ + size_t index; + + /** + Linked list node. + */ + Node* node; + Table* table; + size_t numBuckets; + Node** bucket; + bool isDone; + + /** + Creates the end iterator. + */ + Iterator(const Table* table) : table(const_cast*>(table)) { + isDone = true; + } + + Iterator(const Table* table, size_t numBuckets, Node** bucket) : + table(const_cast*>(table)), + numBuckets(numBuckets), + bucket(bucket) { + + if (numBuckets == 0) { + // Empty table + isDone = true; + return; + } + + index = 0; + node = bucket[index]; + isDone = false; + findNext(); + } + + /** + Finds the next element, setting isDone if one can't be found. + Looks at the current element first. + */ + void findNext() { + while (node == NULL) { + index++; + if (index >= numBuckets) { + isDone = true; + break; + } else { + node = bucket[index]; + } + } + } + + public: + inline bool operator!=(const Iterator& other) const { + return !(*this == other); + } + + bool operator==(const Iterator& other) const { + if (other.isDone || isDone) { + // Common case; check against isDone. + return (isDone == other.isDone) && (other.table == table); + } else { + return + (table == other.table) && + (node == other.node) && + (index == other.index); + } + } + + /** + Pre increment. + */ + Iterator& operator++() { + node = node->next; + findNext(); + return *this; + } + + /** + Post increment (slower than preincrement). + */ + Iterator operator++(int) { + Iterator old = *this; + ++(*this); + return old; + } + + const Entry& operator*() const { + return node->entry; + } + + Entry* operator->() const { + return &(node->entry); + } + + operator Entry*() const { + return &(node->entry); + } + }; + + + /** + C++ STL style iterator method. Returns the first Entry, which + contains a key and value. Use preincrement (++entry) to get to + the next element. Do not modify the table while iterating. + */ + Iterator begin() const { + return Iterator(this, numBuckets, bucket); + } + + /** + C++ STL style iterator method. Returns one after the last iterator + element. + */ + const Iterator end() const { + return Iterator(this); + } + + /** + Removes all elements + */ + void clear() { + freeMemory(); + numBuckets = 20; + _size = 0; + bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16); + System::memset(bucket, 0, sizeof(Node*) * numBuckets); + } + + + /** + Returns the number of keys. + */ + size_t size() const { + return _size; + } + + + /** + If you insert a pointer into the key or value of a table, you are + responsible for deallocating the object eventually. Inserting + key into a table is O(1), but may cause a potentially slow rehashing. + */ + void set(const Key& key, const Value& value) { + size_t code = m_HashFunc(key); + size_t b = code % numBuckets; + + // Go to the bucket + Node* n = bucket[b]; + + // No bucket, so this must be the first + if (n == NULL) { + bucket[b] = new Node(key, value, code, NULL); + ++_size; + return; + } + + size_t bucketLength = 1; + + // Sometimes a bad hash code will cause all elements + // to collide. Detect this case and don't rehash when + // it occurs; nothing good will come from the rehashing. + bool allSameCode = true; + + // Try to find the node + do { + allSameCode = allSameCode && (code == n->hashCode); + + if ((code == n->hashCode) && (n->entry.key == key)) { + // Replace the existing node. + n->entry.value = value; + return; + } + + n = n->next; + ++bucketLength; + } while (n != NULL); + + const size_t maxBucketLength = 5; + if ((bucketLength > maxBucketLength) & ! allSameCode && (numBuckets < _size * 20)) { + // This bucket was really large; rehash if all elements + // don't have the same hashcode the number of buckets is reasonable. + resize(numBuckets * 2 + 1); + } + + // Not found; insert at the head. + b = code % numBuckets; + bucket[b] = new Node(key, value, code, bucket[b]); + ++_size; + } + + /** + Removes an element from the table if it is present. It is an error + to remove an element that isn't present. + */ + void remove(const Key& key) { + + size_t code = m_HashFunc(key); + size_t b = code % numBuckets; + + // Go to the bucket + Node* n = bucket[b]; + + // Make sure it was found + alwaysAssertM(n != NULL, "Tried to remove a key that was not in the table."); + + Node* previous = NULL; + + // Try to find the node + do { + if ((code == n->hashCode) && (n->entry.key == key)) { + // This is the node; remove it + if (previous == NULL) { + bucket[b] = n->next; + } else { + previous->next = n->next; + } + // Delete the node + delete n; + --_size; + return; + } + + previous = n; + n = n->next; + } while (n != NULL); + + + alwaysAssertM(false, "Tried to remove a key that was not in the table."); + } + + /** + Returns the value associated with key. + @deprecated Use get(key, val) or + */ + Value& get(const Key& key) const { + + size_t code = m_HashFunc(key); + size_t b = code % numBuckets; + + Node* node = bucket[b]; + + while (node != NULL) { + if ((node->hashCode == code) && (node->entry.key == key)) { + return node->entry.value; + } + node = node->next; + } + + debugAssertM(false, "Key not found"); + // The next line is here just to make + // a compiler warning go away. + return node->entry.value; + } + + /** + If the key is present in the table, val is set to the associated value and returns true. + If the key is not present, returns false. + */ + bool get(const Key& key, Value& val) const { + size_t code = m_HashFunc(key); + size_t b = code % numBuckets; + + Node* node = bucket[b]; + + while (node != NULL) { + if ((node->hashCode == code) && (node->entry.key == key)) { + // found key + val = node->entry.value; + return true; + } + node = node->next; + } + + // Failed to find key + return false; + } + + /** + Returns true if key is in the table. + */ + bool containsKey(const Key& key) const { + size_t code = m_HashFunc(key); + size_t b = code % numBuckets; + + Node* node = bucket[b]; + + while (node != NULL) { + if ((node->hashCode == code) && (node->entry.key == key)) { + return true; + } + node = node->next; + } while (node != NULL); + + return false; + } + + + /** + Short syntax for get. + */ + inline Value& operator[](const Key &key) const { + return get(key); + } + + + /** + Returns an array of all of the keys in the table. + You can iterate over the keys to get the values. + */ + Array getKeys() const { + Array keyArray; + getKeys(keyArray); + return keyArray; + } + + void getKeys(Array& keyArray) const { + keyArray.resize(0, DONT_SHRINK_UNDERLYING_ARRAY); + for (size_t i = 0; i < numBuckets; i++) { + Node* node = bucket[i]; + while (node != NULL) { + keyArray.append(node->entry.key); + node = node->next; + } + } + } + + /** + Calls delete on all of the keys. Does not clear the table, + however, so you are left with a table of dangling pointers. + + Same as getKeys().deleteAll(); + + To delete all of the values, you may want something like +
+        Array keys = table.getKeys();
+        Set value;
+        for (int k = 0; k < keys.length(); k++) {
+           value.insert(keys[k]);
+        }
+        value.getMembers().deleteAll();
+        keys.deleteAll();
+    
+ */ + void deleteKeys() { + getKeys().deleteAll(); + } + + /** + Calls delete on all of the values. This is unsafe-- + do not call unless you know that each value appears + at most once. + + Does not clear the table, so you are left with a table + of dangling pointers. + */ + void deleteValues() { + for (int i = 0; i < numBuckets; i++) { + Node* node = bucket[i]; + while (node != NULL) { + delete node->entry.value; + node = node->next; + } + } + } +}; + +} // namespace + +#ifdef G3D_WIN32 +# pragma warning (pop) +#endif + +#endif diff --git a/dep/include/g3dlite/G3D/Triangle.h b/dep/include/g3dlite/G3D/Triangle.h new file mode 100644 index 000000000..cbe46a8cf --- /dev/null +++ b/dep/include/g3dlite/G3D/Triangle.h @@ -0,0 +1,116 @@ +/** + @file Triangle.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2003-04-05 + @edited 2004-03-14 + + @cite Random point method by Greg Turk, Generating random points in triangles. In A. S. Glassner, ed., Graphics Gems, pp. 24-28. Academic Press, 1990 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_TRIANGLE_H +#define G3D_TRIANGLE_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include "G3D/Vector3.h" +#include "G3D/Plane.h" +#include + +namespace G3D { + +/** + A generic triangle representation. This should not be used + as the underlying triangle for creating models; it is intended + for providing fast property queries but requires a lot of + storage and is mostly immutable. + */ +class Triangle { +private: + friend class CollisionDetection; + friend class Ray; + + Vector3 _vertex[3]; + + /** edgeDirection[i] is the normalized vector v[i+1] - v[i] */ + Vector3 edgeDirection[3]; + double edgeMagnitude[3]; + Plane _plane; + Vector3::Axis _primaryAxis; + + /** vertex[1] - vertex[0] */ + Vector3 edge01; + /** vertex[2] - vertex[0] */ + Vector3 edge02; + + float _area; + + void init(const Vector3& v0, const Vector3& v1, const Vector3& v2); + +public: + + Triangle(); + + Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2); + + ~Triangle(); + + /** 0, 1, or 2 */ + inline const Vector3& vertex(int n) const { + debugAssert((n >= 0) && (n < 3)); + return _vertex[n]; + } + + double area() const; + + Vector3::Axis primaryAxis() const { + return _primaryAxis; + } + + const Vector3& normal() const; + + /** Barycenter */ + Vector3 center() const; + + const Plane& plane() const; + + /** Returns a random point in the triangle. */ + Vector3 randomPoint() const; + + /** + For two triangles to be equal they must have + the same vertices in the same order. + That is, vertex[0] == vertex[0], etc. + */ + inline bool operator==(const Triangle& other) const { + for (int i = 0; i < 3; ++i) { + if (_vertex[i] != other._vertex[i]) { + return false; + } + } + + return true; + } + + inline unsigned int hashCode() const { + return + _vertex[0].hashCode() + + (_vertex[1].hashCode() >> 2) + + _vertex[2].hashCode(); + } + + void getBounds(class AABox&) const; + +}; + +} // namespace + +inline unsigned int hashCode(const G3D::Triangle& t) { + return t.hashCode(); +} + +#endif diff --git a/dep/include/g3dlite/G3D/Vector2.h b/dep/include/g3dlite/G3D/Vector2.h new file mode 100644 index 000000000..2d9d26626 --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector2.h @@ -0,0 +1,438 @@ +/** + @file Vector2.h + + 2D vector class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2006-01-14 + Copyright 2000-2006, Morgan McGuire. + All rights reserved. +*/ + +#ifndef G3D_VECTOR2_H +#define G3D_VECTOR2_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include "Vector2int16.h" +#include + +namespace G3D { + +class Vector2; +class Vector3; +class Vector4; + +/** + Do not subclass-- this implementation makes assumptions about the + memory layout. + */ +class Vector2 { +private: + // Hidden operators + bool operator<(const Vector2&) const; + bool operator>(const Vector2&) const; + bool operator<=(const Vector2&) const; + bool operator>=(const Vector2&) const; + +public: + // coordinates + float x, y; + + // construction + Vector2(); + Vector2(float x, float y); + Vector2(float coordinate[2]); + Vector2(double coordinate[2]); + Vector2(const Vector2& rkVector); + Vector2(const class Vector2int16& v); + + float& operator[] (int i); + const float& operator[] (int i) const; + operator float* (); + operator const float* () const; + + // assignment and comparison + Vector2& operator= (const Vector2& rkVector); + bool operator== (const Vector2& rkVector) const; + bool operator!= (const Vector2& rkVector) const; + unsigned int hashCode() const; + bool fuzzyEq(const Vector2& other) const; + bool fuzzyNe(const Vector2& other) const; + /** Returns true if this vector has finite length */ + bool isFinite() const; + + /** Returns true if this vector has length == 0 */ + bool isZero() const; + + /** Returns true if this vector has length == 1 */ + bool isUnit() const; + + // arithmetic operations + Vector2 operator+ (const Vector2& rkVector) const; + Vector2 operator- (const Vector2& rkVector) const; + Vector2 operator* (float fScalar) const; + Vector2 operator* (const Vector2& rkVector) const; + Vector2 operator/ (const Vector2& rkVector) const; + Vector2 operator/ (float fScalar) const; + Vector2 operator- () const; + + inline float sum() const { + return x + y; + } + + /** + Linear interpolation + */ + inline Vector2 lerp(const Vector2& v, float alpha) const { + return (*this) + (v - *this) * alpha; + } + + inline Vector2 clamp(const Vector2& low, const Vector2& high) const { + return Vector2( + G3D::clamp(x, low.x, high.x), + G3D::clamp(y, low.y, high.y)); + } + + inline Vector2 clamp(float low, float high) const { + return Vector2( + (float)G3D::clamp(x, low, high), + (float)G3D::clamp(y, low, high)); + } + + // arithmetic updates + Vector2& operator+= (const Vector2& rkVector); + Vector2& operator-= (const Vector2& rkVector); + Vector2& operator*= (float fScalar); + Vector2& operator/= (float fScalar); + Vector2& operator*= (const Vector2& rkVector); + Vector2& operator/= (const Vector2& rkVector); + + // vector operations + float length() const; + Vector2 direction() const; + /** + Potentially less accurate but faster than direction(). + Only works if System::hasSSE is true. + */ + Vector2 fastDirection() const { + return direction(); + } + + float squaredLength () const; + float dot (const Vector2& rkVector) const; + float unitize (float fTolerance = 1e-06); + + Vector2 min(const Vector2 &v) const; + Vector2 max(const Vector2 &v) const; + + // Random unit vector + static Vector2 random(); + + // Special values. + // Intentionally not inlined: see Matrix3::identity() for details. + static const Vector2& zero(); + inline static const Vector2& one() { static const Vector2 v(1, 1); return v; } + static const Vector2& unitX(); + static const Vector2& unitY(); + static const Vector2& inf(); + static const Vector2& nan(); + /** smallest (most negative) representable vector */ + static const Vector2& minFinite(); + /** Largest representable vector */ + static const Vector2& maxFinite(); + + + + // Deprecated. See Matrix3::identity() for details. + /** @deprecated Use Vector2::zero() */ + static const Vector2 ZERO; + /** @deprecated Use Vector2::unitX() */ + static const Vector2 UNIT_S; + /** @deprecated Use Vector2::unitY() */ + static const Vector2 UNIT_T; + + std::string toString() const; + + // 2-char swizzles + + Vector2 xx() const; + Vector2 yx() const; + Vector2 xy() const; + Vector2 yy() const; + + // 3-char swizzles + + Vector3 xxx() const; + Vector3 yxx() const; + Vector3 xyx() const; + Vector3 yyx() const; + Vector3 xxy() const; + Vector3 yxy() const; + Vector3 xyy() const; + Vector3 yyy() const; + + // 4-char swizzles + + Vector4 xxxx() const; + Vector4 yxxx() const; + Vector4 xyxx() const; + Vector4 yyxx() const; + Vector4 xxyx() const; + Vector4 yxyx() const; + Vector4 xyyx() const; + Vector4 yyyx() const; + Vector4 xxxy() const; + Vector4 yxxy() const; + Vector4 xyxy() const; + Vector4 yyxy() const; + Vector4 xxyy() const; + Vector4 yxyy() const; + Vector4 xyyy() const; + Vector4 yyyy() const; + +}; + +inline Vector2 operator*(double s, const Vector2& v) { + return v * (float)s; +} + +inline Vector2 operator*(float s, const Vector2& v) { + return v * s; +} + +inline Vector2 operator*(int s, const Vector2& v) { + return v * (float)s; +} + + +inline unsigned int hashCode(const G3D::Vector2& v) { + return v.hashCode(); +} + + +inline Vector2::Vector2 () : x(0.0f), y(0.0f) { +} + + +inline Vector2::Vector2(float _x, float _y) : x(_x), y(_y) { +} + + +inline Vector2::Vector2 (float afCoordinate[2]) { + x = afCoordinate[0]; + y = afCoordinate[1]; +} + + + +inline Vector2::Vector2 (double afCoordinate[2]) { + x = (float)afCoordinate[0]; + y = (float)afCoordinate[1]; +} + + +inline Vector2::Vector2 (const Vector2& rkVector) { + x = rkVector.x; + y = rkVector.y; +} + + +inline Vector2::Vector2 (const Vector2int16& v) : x(v.x), y(v.y) { +} + + +inline float& Vector2::operator[] (int i) { + return ((float*)this)[i]; +} + + +inline const float& Vector2::operator[] (int i) const { + return ((float*)this)[i]; +} + + +inline Vector2::operator float* () { + return (float*)this; +} + +inline Vector2::operator const float* () const { + return (float*)this; +} + + +inline Vector2& Vector2::operator= (const Vector2& rkVector) { + x = rkVector.x; + y = rkVector.y; + return *this; +} + + +inline bool Vector2::operator== (const Vector2& rkVector) const { + return ( x == rkVector.x && y == rkVector.y); +} + + +inline bool Vector2::operator!= (const Vector2& rkVector) const { + return ( x != rkVector.x || y != rkVector.y); +} + + +inline Vector2 Vector2::operator+ (const Vector2& rkVector) const { + return Vector2(x + rkVector.x, y + rkVector.y); +} + + +inline Vector2 Vector2::operator- (const Vector2& rkVector) const { + return Vector2(x - rkVector.x, y - rkVector.y); +} + + +inline Vector2 Vector2::operator* (float fScalar) const { + return Vector2(fScalar*x, fScalar*y); +} + + + +inline Vector2 Vector2::operator- () const { + return Vector2( -x, -y); +} + + + +inline Vector2& Vector2::operator+= (const Vector2& rkVector) { + x += rkVector.x; + y += rkVector.y; + return *this; +} + + + +inline Vector2& Vector2::operator-= (const Vector2& rkVector) { + x -= rkVector.x; + y -= rkVector.y; + return *this; +} + + + +inline Vector2& Vector2::operator*= (float fScalar) { + x *= fScalar; + y *= fScalar; + return *this; +} + + + + +inline Vector2& Vector2::operator*= (const Vector2& rkVector) { + x *= rkVector.x; + y *= rkVector.y; + return *this; +} + + + +inline Vector2& Vector2::operator/= (const Vector2& rkVector) { + x /= rkVector.x; + y /= rkVector.y; + return *this; +} + + +inline Vector2 Vector2::operator* (const Vector2& rkVector) const { + return Vector2(x * rkVector.x, y * rkVector.y); +} + + + +inline Vector2 Vector2::operator/ (const Vector2& rkVector) const { + return Vector2(x / rkVector.x, y / rkVector.y); +} + + +inline float Vector2::squaredLength () const { + return x*x + y*y; +} + + +inline float Vector2::length () const { + return sqrtf(x*x + y*y); +} + + +inline Vector2 Vector2::direction () const { + float lenSquared = x * x + y * y; + + if (lenSquared != 1.0f) { + return *this / sqrtf(lenSquared); + } else { + return *this; + } +} + + + +inline float Vector2::dot (const Vector2& rkVector) const { + return x*rkVector.x + y*rkVector.y; +} + + + +inline Vector2 Vector2::min(const Vector2 &v) const { + return Vector2(G3D::min(v.x, x), G3D::min(v.y, y)); +} + + + +inline Vector2 Vector2::max(const Vector2 &v) const { + return Vector2(G3D::max(v.x, x), G3D::max(v.y, y)); +} + + + +inline bool Vector2::fuzzyEq(const Vector2& other) const { + return G3D::fuzzyEq((*this - other).squaredLength(), 0); +} + + + +inline bool Vector2::fuzzyNe(const Vector2& other) const { + return G3D::fuzzyNe((*this - other).squaredLength(), 0); +} + + + +inline bool Vector2::isFinite() const { + return G3D::isFinite(x) && G3D::isFinite(y); +} + + + +inline bool Vector2::isZero() const { + return (x == 0.0f) && (y == 0.0f); +} + + + +inline bool Vector2::isUnit() const { + return squaredLength() == 1.0f; +} + +} + +// Intentionally outside namespace to avoid operator overloading confusion +inline G3D::Vector2 operator*(double s, const G3D::Vector2& v) { + return v * (float)s; +} +inline G3D::Vector2 operator*(int s, const G3D::Vector2& v) { + return v * (float)s; +} + + +inline unsigned int hashCode(const G3D::Vector2& v); + + +#endif diff --git a/dep/include/g3dlite/G3D/Vector2.inl b/dep/include/g3dlite/G3D/Vector2.inl new file mode 100644 index 000000000..27abecf02 --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector2.inl @@ -0,0 +1,20 @@ +/** + @file Vector2.inl + + @maintainer Morgan McGuire, matrix@graphics3d.com + @cite Portions by Laura Wollstadt, graphics3d.com + + @cite Portions based on Dave Eberly'x Magic Software Library + at http://www.magic-software.com + + + @created 2001-06-02 + @edited 2006-01-14 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + + +} + diff --git a/dep/include/g3dlite/G3D/Vector2int16.h b/dep/include/g3dlite/G3D/Vector2int16.h new file mode 100644 index 000000000..cadb4a80c --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector2int16.h @@ -0,0 +1,75 @@ +/** + @file Vector2int16.h + + @maintainer Morgan McGuire, matrix@brown.edu + + @created 2003-08-09 + @edited 2004-01-03 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef VECTOR2INT16_H +#define VECTOR2INT16_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" + +namespace G3D { + +/** + A Vector2 that packs its fields into uint16s. + */ +#ifdef G3D_WIN32 + // Switch to tight alignment + #pragma pack(push, 2) +#endif + +class Vector2int16 { +private: + // Hidden operators + bool operator<(const Vector2int16&) const; + bool operator>(const Vector2int16&) const; + bool operator<=(const Vector2int16&) const; + bool operator>=(const Vector2int16&) const; + +public: + G3D::int16 x; + G3D::int16 y; + + Vector2int16() : x(0), y(0) {} + Vector2int16(G3D::int16 _x, G3D::int16 _y) : x(_x), y(_y){} + Vector2int16(const class Vector2& v); + + inline G3D::int16& operator[] (int i) { + debugAssert(((unsigned int)i) <= 1); + return ((G3D::int16*)this)[i]; + } + + inline const G3D::int16& operator[] (int i) const { + debugAssert(((unsigned int)i) <= 1); + return ((G3D::int16*)this)[i]; + } + + + inline bool operator== (const Vector2int16& rkVector) const { + return ((int32*)this)[0] == ((int32*)&rkVector)[0]; + } + + inline bool operator!= (const Vector2int16& rkVector) const { + return ((int32*)this)[0] != ((int32*)&rkVector)[0]; + } + +} +#if defined(G3D_LINUX) || defined(G3D_OSX) + __attribute((aligned(1))) +#endif +; + +#ifdef G3D_WIN32 + #pragma pack(pop) +#endif + +} +#endif diff --git a/dep/include/g3dlite/G3D/Vector3.h b/dep/include/g3dlite/G3D/Vector3.h new file mode 100644 index 000000000..79c28fb5e --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector3.h @@ -0,0 +1,504 @@ +/** + @file Vector3.h + + 3D vector class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2005-08-23 + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_VECTOR3_H +#define G3D_VECTOR3_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include "G3D/Vector2.h" +#include +#include + +namespace G3D { + +class Vector2; +class Vector3; +class Vector4; + +/** + Swizzles + Vector classes have swizzle operators, e.g. v.xy(), that + allow selection of arbitrary sub-fields. These cannot be used as write + masks. Examples + +
+Vector3 v(1, 2, 3);
+Vector3 j;
+Vector2 b;
+
+b = v.xz();
+j = b.xx();
+
+ + + Warning + + Do not subclass-- this implementation makes assumptions about the + memory layout. + */ +class Vector3 { +private: + /** + Reflect this vector about the (not necessarily unit) normal. + Note that if used for a collision or ray reflection you + must negate the resulting vector to get a direction pointing + away from the collision. + +
+       V'    N      V
+                 
+         r   ^   -,
+          \  |  /
+            \|/
+     
+ + See also Vector3::reflectionDirection + */ + Vector3 reflectAbout(const Vector3& normal) const; + + // Hidden operators + bool operator<(const Vector3&) const; + bool operator>(const Vector3&) const; + bool operator<=(const Vector3&) const; + bool operator>=(const Vector3&) const; + +public: + // construction + Vector3(); + Vector3(float _x, float _y, float _z); + Vector3(const class Vector2& v, float _z); + Vector3(float coordinate[3]); + Vector3(double coordinate[3]); + Vector3(const Vector3& rkVector); + Vector3(const class Vector3int16& v); + + // coordinates + float x, y, z; + + // access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z + // + // WARNING. These member functions rely on + // (1) Vector3 not having virtual functions + // (2) the data packed in a 3*sizeof(float) memory block + const float& operator[] (int i) const; + float& operator[] (int i); + + inline operator float* () { + return (float*)this; + } + + operator const float* () const { + return (float*)this; + } + + enum Axis {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, DETECT_AXIS=-1}; + + /** + Returns the largest dimension. Particularly convenient for determining + which plane to project a triangle onto for point-in-polygon tests. + */ + Axis primaryAxis() const; + + // assignment and comparison + Vector3& operator= (const Vector3& rkVector); + bool operator== (const Vector3& rkVector) const; + bool operator!= (const Vector3& rkVector) const; + unsigned int hashCode() const; + bool fuzzyEq(const Vector3& other) const; + bool fuzzyNe(const Vector3& other) const; + + /** Returns true if this vector has finite length. */ + bool isFinite() const; + + /** Returns true if this vector has length ~= 0 */ + bool isZero() const; + + /** Returns true if this vector has length ~= 1 */ + bool isUnit() const; + + // arithmetic operations + Vector3 operator+ (const Vector3& v) const; + Vector3 operator- (const Vector3& v) const; + Vector3 operator* (float s) const; + Vector3 operator/ (float s) const; + Vector3 operator* (const Vector3& v) const; + Vector3 operator/ (const Vector3& v) const; + Vector3 operator- () const; + + // arithmetic updates + Vector3& operator+= (const Vector3& v); + Vector3& operator-= (const Vector3& v); + Vector3& operator*= (float s); + Vector3& operator/= (float s); + Vector3& operator*= (const Vector3& v); + Vector3& operator/= (const Vector3& v); + + /** @deprecated Use magnitude */ + float G3D_DEPRECATED length() const; + + float magnitude() const; + + /** + The result is a nan vector if the length is almost zero. + */ + Vector3 direction() const; + + /** + Potentially less accurate but faster than direction(). + Only works if System::hasSSE is true. + */ + Vector3 fastDirection() const; + + + /** + See also G3D::Ray::reflect. + The length is 1. +
+       V'    N       V
+                 
+         r   ^    /
+          \  |  /
+            \|'-
+     
+ */ + Vector3 reflectionDirection(const Vector3& normal) const; + + + /** + Returns Vector3::zero() if the length is nearly zero, otherwise + returns a unit vector. + */ + inline Vector3 directionOrZero() const { + float mag = magnitude(); + if (G3D::fuzzyEq(mag, 0.0f)) { + return Vector3::zero(); + } else if (G3D::fuzzyEq(mag, 1.0f)) { + return *this; + } else { + return *this * (1.0f / mag); + } + } + + /** + Returns the direction of a refracted ray, + where iExit is the index of refraction for the + previous material and iEnter is the index of refraction + for the new material. Like Vector3::reflectionDirection, + the result has length 1 and is + pointed away from the intersection. + + Returns Vector3::zero() in the case of total internal refraction. + + @param iOutside The index of refraction (eta) outside + (on the positive normal side) of the surface. + + @param iInside The index of refraction (eta) inside + (on the negative normal side) of the surface. + + See also G3D::Ray::refract. +
+              N      V
+                  
+              ^    /
+              |  /
+              |'-
+          __--
+     V'<--
+     
+ */ + Vector3 refractionDirection( + const Vector3& normal, + float iInside, + float iOutside) const; + + /** Synonym for direction */ + inline Vector3 unit() const { + return direction(); + } + + /** Returns a normalized vector. May be computed with lower precision than unit */ + inline Vector3 fastUnit() const { + return fastDirection(); + } + + /** @deprecated Use squaredMagnitude */ + float G3D_DEPRECATED squaredLength() const; + + float squaredMagnitude () const; + + /** @deprecated Use squaredMagnitude */ + inline float G3D_DEPRECATED norm() const { + return squaredMagnitude(); + } + + float dot(const Vector3& rkVector) const; + + float G3D_DEPRECATED unitize(float fTolerance = 1e-06); + + /** Cross product. Note that two cross products in a row + can be computed more cheaply: v1 x (v2 x v3) = (v1 dot v3) v2 - (v1 dot v2) v3. + */ + Vector3 cross(const Vector3& rkVector) const; + Vector3 unitCross (const Vector3& rkVector) const; + + /** + Returns a matrix such that v.cross() * w = v.cross(w). +
+     [ 0  -v.z  v.y ]
+     [ v.z  0  -v.x ]
+     [ -v.y v.x  0  ]
+     
+ */ + class Matrix3 cross() const; + + Vector3 min(const Vector3 &v) const; + Vector3 max(const Vector3 &v) const; + + std::string toString() const; + + inline Vector3 clamp(const Vector3& low, const Vector3& high) const { + return Vector3( + G3D::clamp(x, low.x, high.x), + G3D::clamp(y, low.y, high.y), + G3D::clamp(z, low.z, high.z)); + } + + inline Vector3 clamp(float low, float high) const { + return Vector3( + G3D::clamp(x, low, high), + G3D::clamp(y, low, high), + G3D::clamp(z, low, high)); + } + + /** + Linear interpolation + */ + inline Vector3 lerp(const Vector3& v, float alpha) const { + return (*this) + (v - *this) * alpha; + } + + /** Gram-Schmidt orthonormalization. */ + static void orthonormalize (Vector3 akVector[3]); + + /** Random unit vector, uniformly distributed */ + static Vector3 random(); + + /** Random unit vector, distributed + so that the probability of V is proportional + to max(V dot Normal, 0). + + @cite Henrik Wann Jensen, Realistic Image Synthesis using Photon Mapping eqn 2.24 + */ + static Vector3 cosRandom(const Vector3& normal); + + + /** + Random vector distributed over the hemisphere about normal. + */ + static Vector3 hemiRandom(const Vector3& normal); + + // Input W must be initialize to a nonzero vector, output is {U,V,W} + // an orthonormal basis. A hint is provided about whether or not W + // is already unit length. + static void generateOrthonormalBasis (Vector3& rkU, Vector3& rkV, + Vector3& rkW, bool bUnitLengthW = true); + + inline float sum() const { + return x + y + z; + } + + inline float average() const { + return sum() / 3.0f; + } + + // Special values. + inline static const Vector3& zero() { static Vector3 v(0, 0, 0); return v; } + inline static const Vector3& one() { static Vector3 v(1, 1, 1); return v; } + inline static const Vector3& unitX() { static Vector3 v(1, 0, 0); return v; } + inline static const Vector3& unitY() { static Vector3 v(0, 1, 0); return v; } + inline static const Vector3& unitZ() { static Vector3 v(0, 0, 1); return v; } + inline static const Vector3& inf() { static Vector3 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; } + inline static const Vector3& nan() { static Vector3 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; } + /** Smallest (most negative) representable vector */ + inline static const Vector3& minFinite(){ static Vector3 v(-FLT_MAX, -FLT_MAX, -FLT_MAX); return v; } + /** Largest representable vector */ + inline static const Vector3& maxFinite(){ static Vector3 v(FLT_MAX, FLT_MAX, FLT_MAX); return v; } + + // Deprecated. See Matrix3::identity() for details. + /** @deprecated Use Vector3::zero() */ + static const Vector3 ZERO; + /** @deprecated Use Vector3::zero() */ + static const Vector3 ZERO3; + /** @deprecated Use Vector3::unitX() */ + static const Vector3 UNIT_X; + /** @deprecated Use Vector3::unitY() */ + static const Vector3 UNIT_Y; + /** @deprecated Use Vector3::unitZ() */ + static const Vector3 UNIT_Z; + /** @deprecated Use Vector3::inf() */ + static const Vector3 INF3; + /** @deprecated Use Vector3::nan() */ + static const Vector3 NAN3; + + // 2-char swizzles + + Vector2 xx() const; + Vector2 yx() const; + Vector2 zx() const; + Vector2 xy() const; + Vector2 yy() const; + Vector2 zy() const; + Vector2 xz() const; + Vector2 yz() const; + Vector2 zz() const; + + // 3-char swizzles + + Vector3 xxx() const; + Vector3 yxx() const; + Vector3 zxx() const; + Vector3 xyx() const; + Vector3 yyx() const; + Vector3 zyx() const; + Vector3 xzx() const; + Vector3 yzx() const; + Vector3 zzx() const; + Vector3 xxy() const; + Vector3 yxy() const; + Vector3 zxy() const; + Vector3 xyy() const; + Vector3 yyy() const; + Vector3 zyy() const; + Vector3 xzy() const; + Vector3 yzy() const; + Vector3 zzy() const; + Vector3 xxz() const; + Vector3 yxz() const; + Vector3 zxz() const; + Vector3 xyz() const; + Vector3 yyz() const; + Vector3 zyz() const; + Vector3 xzz() const; + Vector3 yzz() const; + Vector3 zzz() const; + + // 4-char swizzles + + Vector4 xxxx() const; + Vector4 yxxx() const; + Vector4 zxxx() const; + Vector4 xyxx() const; + Vector4 yyxx() const; + Vector4 zyxx() const; + Vector4 xzxx() const; + Vector4 yzxx() const; + Vector4 zzxx() const; + Vector4 xxyx() const; + Vector4 yxyx() const; + Vector4 zxyx() const; + Vector4 xyyx() const; + Vector4 yyyx() const; + Vector4 zyyx() const; + Vector4 xzyx() const; + Vector4 yzyx() const; + Vector4 zzyx() const; + Vector4 xxzx() const; + Vector4 yxzx() const; + Vector4 zxzx() const; + Vector4 xyzx() const; + Vector4 yyzx() const; + Vector4 zyzx() const; + Vector4 xzzx() const; + Vector4 yzzx() const; + Vector4 zzzx() const; + Vector4 xxxy() const; + Vector4 yxxy() const; + Vector4 zxxy() const; + Vector4 xyxy() const; + Vector4 yyxy() const; + Vector4 zyxy() const; + Vector4 xzxy() const; + Vector4 yzxy() const; + Vector4 zzxy() const; + Vector4 xxyy() const; + Vector4 yxyy() const; + Vector4 zxyy() const; + Vector4 xyyy() const; + Vector4 yyyy() const; + Vector4 zyyy() const; + Vector4 xzyy() const; + Vector4 yzyy() const; + Vector4 zzyy() const; + Vector4 xxzy() const; + Vector4 yxzy() const; + Vector4 zxzy() const; + Vector4 xyzy() const; + Vector4 yyzy() const; + Vector4 zyzy() const; + Vector4 xzzy() const; + Vector4 yzzy() const; + Vector4 zzzy() const; + Vector4 xxxz() const; + Vector4 yxxz() const; + Vector4 zxxz() const; + Vector4 xyxz() const; + Vector4 yyxz() const; + Vector4 zyxz() const; + Vector4 xzxz() const; + Vector4 yzxz() const; + Vector4 zzxz() const; + Vector4 xxyz() const; + Vector4 yxyz() const; + Vector4 zxyz() const; + Vector4 xyyz() const; + Vector4 yyyz() const; + Vector4 zyyz() const; + Vector4 xzyz() const; + Vector4 yzyz() const; + Vector4 zzyz() const; + Vector4 xxzz() const; + Vector4 yxzz() const; + Vector4 zxzz() const; + Vector4 xyzz() const; + Vector4 yyzz() const; + Vector4 zyzz() const; + Vector4 xzzz() const; + Vector4 yzzz() const; + Vector4 zzzz() const; + + /** A value that can be passed to ignore a parameter. Never look at the result of dummy. */ + static Vector3 dummy; +}; + +inline G3D::Vector3 operator*(float s, const G3D::Vector3& v) { + return v * s; +} + +inline G3D::Vector3 operator*(double s, const G3D::Vector3& v) { + return v * (float)s; +} + +inline G3D::Vector3 operator*(int s, const G3D::Vector3& v) { + return v * (float)s; +} + +std::ostream& operator<<(std::ostream& os, const Vector3&); + +} + +unsigned int hashCode(const G3D::Vector3& v); + +#include "Vector3.inl" + +#endif diff --git a/dep/include/g3dlite/G3D/Vector3.inl b/dep/include/g3dlite/G3D/Vector3.inl new file mode 100644 index 000000000..99110ffc8 --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector3.inl @@ -0,0 +1,250 @@ +/** + @file Vector3.inl + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com + + @created 2001-06-02 + @edited 2004-05-21 + Copyright 2000-2004, Morgan McGuire. + All rights reserved. + */ + +//---------------------------------------------------------------------------- +#ifdef SSE + // If you receive an error on this line, it is because you do not have the file + // xmmintrin.h needed for MMX & SSE extensions. Download and install + // + // http://download.microsoft.com/download/vstudio60ent/SP5/Wideband-Full/WIN98Me/EN-US/vs6sp5.exe + // and + // http://download.microsoft.com/download/vb60ent/Update/6/W9X2KXP/EN-US/vcpp5.exe + // + // to get this file. +# include +#endif + +inline unsigned int hashCode(const G3D::Vector3& v) { + return v.hashCode(); +} + +namespace G3D { + +//---------------------------------------------------------------------------- +inline Vector3::Vector3() : x(0.0f), y(0.0f), z(0.0f) { +} + +//---------------------------------------------------------------------------- + +inline Vector3::Vector3 (float fX, float fY, float fZ) : x(fX), y(fY), z(fZ) { +} + +//---------------------------------------------------------------------------- +inline Vector3::Vector3 (float V[3]) : x(V[0]), y(V[1]), z(V[2]){ +} +//---------------------------------------------------------------------------- +inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){ +} + +//---------------------------------------------------------------------------- +inline Vector3::Vector3 (const Vector3& V) : x(V.x), y(V.y), z(V.z) { +} + +//---------------------------------------------------------------------------- + +//inline Vector3::Vector3 (const __m128& m) { + // Cast from SSE packed floats +// *this = *(Vector3*)&m; +//} + +//---------------------------------------------------------------------------- +inline const float& Vector3::operator[] (int i) const { + return ((float*)this)[i]; +} + +inline float& Vector3::operator[] (int i) { + return ((float*)this)[i]; +} + + +//---------------------------------------------------------------------------- +inline Vector3& Vector3::operator= (const Vector3& rkVector) { + x = rkVector.x; + y = rkVector.y; + z = rkVector.z; + return *this; +} + +//---------------------------------------------------------------------------- + +inline bool Vector3::fuzzyEq(const Vector3& other) const { + return G3D::fuzzyEq((*this - other).squaredMagnitude(), 0); +} + +//---------------------------------------------------------------------------- + +inline bool Vector3::fuzzyNe(const Vector3& other) const { + return G3D::fuzzyNe((*this - other).squaredMagnitude(), 0); +} + +//---------------------------------------------------------------------------- + +inline bool Vector3::isFinite() const { + return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z); +} + +//---------------------------------------------------------------------------- +inline bool Vector3::operator== (const Vector3& rkVector) const { + return ( x == rkVector.x && y == rkVector.y && z == rkVector.z ); +} + +//---------------------------------------------------------------------------- +inline bool Vector3::operator!= (const Vector3& rkVector) const { + return ( x != rkVector.x || y != rkVector.y || z != rkVector.z ); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::operator+ (const Vector3& rkVector) const { + return Vector3(x + rkVector.x, y + rkVector.y, z + rkVector.z); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::operator- (const Vector3& rkVector) const { + return Vector3(x - rkVector.x, y - rkVector.y, z - rkVector.z); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::operator* (const Vector3& rkVector) const { + return Vector3(x * rkVector.x, y * rkVector.y, z * rkVector.z); +} + +inline Vector3 Vector3::operator*(float f) const { + return Vector3(x * f, y * f, z * f); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::operator/ (const Vector3& rkVector) const { + return Vector3(x / rkVector.x, y / rkVector.y, z / rkVector.z); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::operator- () const { + return Vector3(-x, -y, -z); +} + +//---------------------------------------------------------------------------- +inline Vector3& Vector3::operator+= (const Vector3& rkVector) { + x += rkVector.x; + y += rkVector.y; + z += rkVector.z; + return *this; +} + +//---------------------------------------------------------------------------- +inline Vector3& Vector3::operator-= (const Vector3& rkVector) { + x -= rkVector.x; + y -= rkVector.y; + z -= rkVector.z; + return *this; +} + +//---------------------------------------------------------------------------- +inline Vector3& Vector3::operator*= (float fScalar) { + x *= fScalar; + y *= fScalar; + z *= fScalar; + return *this; +} + +//---------------------------------------------------------------------------- +inline Vector3& Vector3::operator*= (const Vector3& rkVector) { + x *= rkVector.x; + y *= rkVector.y; + z *= rkVector.z; + return *this; +} + +//---------------------------------------------------------------------------- +inline Vector3& Vector3::operator/= (const Vector3& rkVector) { + x /= rkVector.x; + y /= rkVector.y; + z /= rkVector.z; + return *this; +} + +//---------------------------------------------------------------------------- +inline float Vector3::squaredMagnitude () const { + return x*x + y*y + z*z; +} + +//---------------------------------------------------------------------------- +inline float Vector3::squaredLength () const { + return squaredMagnitude(); +} + +//---------------------------------------------------------------------------- +inline float Vector3::magnitude() const { + return sqrtf(x*x + y*y + z*z); +} + +//---------------------------------------------------------------------------- +inline float Vector3::length() const { + return magnitude(); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::direction () const { + float lenSquared = squaredMagnitude(); + float invSqrt = 1.0f / sqrtf(lenSquared); + return Vector3(x * invSqrt, y * invSqrt, z * invSqrt); +} + +//---------------------------------------------------------------------------- + +inline Vector3 Vector3::fastDirection () const { + float lenSquared = x * x + y * y + z * z; + float invSqrt = rsq(lenSquared); + return Vector3(x * invSqrt, y * invSqrt, z * invSqrt); +} + +//---------------------------------------------------------------------------- +inline float Vector3::dot (const Vector3& rkVector) const { + return x*rkVector.x + y*rkVector.y + z*rkVector.z; +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::cross (const Vector3& rkVector) const { + return Vector3(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z, + x*rkVector.y - y*rkVector.x); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::unitCross (const Vector3& rkVector) const { + Vector3 kCross(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z, + x*rkVector.y - y*rkVector.x); + kCross.unitize(); + return kCross; +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::min(const Vector3 &v) const { + return Vector3(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z)); +} + +//---------------------------------------------------------------------------- +inline Vector3 Vector3::max(const Vector3 &v) const { + return Vector3(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z)); +} + +//---------------------------------------------------------------------------- +inline bool Vector3::isZero() const { + return G3D::fuzzyEq(squaredMagnitude(), 0.0f); +} + +//---------------------------------------------------------------------------- + +inline bool Vector3::isUnit() const { + return G3D::fuzzyEq(squaredMagnitude(), 1.0f); +} + +} // namespace diff --git a/dep/include/g3dlite/G3D/Vector3int16.h b/dep/include/g3dlite/G3D/Vector3int16.h new file mode 100644 index 000000000..9fd344b2d --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector3int16.h @@ -0,0 +1,55 @@ +/** + @file Vector3int16.h + + @maintainer Morgan McGuire, matrix@brown.edu + + @created 2003-04-07 + @edited 2003-06-24 + Copyright 2000-2004, Morgan McGuire. + All rights reserved. + */ + +#ifndef VECTOR3INT16_H +#define VECTOR3INT16_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" + +namespace G3D { + +/** + A Vector3 that packs its fields into uint16s. + */ +#ifdef G3D_WIN32 + // Switch to tight alignment + #pragma pack(push, 2) +#endif + +class Vector3int16 { +private: + // Hidden operators + bool operator<(const Vector3int16&) const; + bool operator>(const Vector3int16&) const; + bool operator<=(const Vector3int16&) const; + bool operator>=(const Vector3int16&) const; + +public: + G3D::int16 x; + G3D::int16 y; + G3D::int16 z; + + Vector3int16() : x(0), y(0), z(0) {} + Vector3int16(G3D::int16 _x, G3D::int16 _y, G3D::int16 _z) : x(_x), y(_y), z(_z) {} + Vector3int16(const class Vector3& v); +} +#if defined(G3D_LINUX) || defined(G3D_OSX) + __attribute((aligned(1))) +#endif +; + +#ifdef G3D_WIN32 + #pragma pack(pop) +#endif + +} +#endif diff --git a/dep/include/g3dlite/G3D/Vector4.h b/dep/include/g3dlite/G3D/Vector4.h new file mode 100644 index 000000000..b86bf95b0 --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector4.h @@ -0,0 +1,524 @@ +/** + @file Vector4.h + + Homogeneous vector class. + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2002-07-09 + @edited 2005-03-28 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_VECTOR4_H +#define G3D_VECTOR4_H + +#include "G3D/platform.h" +#include "G3D/g3dmath.h" +#include "G3D/Vector3.h" +#include "G3D/Vector2.h" +#include + +namespace G3D { + +class Vector2; +class Vector3; +class Vector4; + +/** + Do not subclass-- this implementation makes assumptions about the + memory layout. + */ +class Vector4 { +private: + // Hidden operators + bool operator<(const Vector4&) const; + bool operator>(const Vector4&) const; + bool operator<=(const Vector4&) const; + bool operator>=(const Vector4&) const; + +public: + // construction + Vector4(); + Vector4(float fX, float fY, float fZ, float fW); + Vector4(float afCoordinate[4]); + Vector4(const Vector4& rkVector); + Vector4(const class Color4& c); + Vector4(const Vector3& rkVector, float fW); + Vector4(const Vector2& v1, const Vector2& v2); + Vector4(const Vector2& v1, float fz, float fw); + + // coordinates + float x, y, z, w; + + // access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z, etc. + // + // WARNING. These member functions rely on + // (1) Vector4 not having virtual functions + // (2) the data packed in a 4*sizeof(float) memory block + float& operator[] (int i); + const float& operator[] (int i) const; + operator float* (); + operator const float* () const; + + // assignment and comparison + Vector4& operator= (const Vector4& rkVector); + bool operator== (const Vector4& rkVector) const; + bool operator!= (const Vector4& rkVector) const; + + inline void set(float _x, float _y, float _z, float _w) { + x = _x; + y = _y; + z = _z; + w = _w; + } + + inline void set(const Vector3& v, float _w) { + x = v.x; + y = v.y; + z = v.z; + w = _w; + } + + inline void set(const Vector2& v, float _z, float _w) { + x = v.x; + y = v.y; + z = _z; + w = _w; + } + + unsigned int hashCode() const; + bool fuzzyEq(const Vector4& other) const; + bool fuzzyNe(const Vector4& other) const; + + inline static const Vector4& inf() { static Vector4 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; } + inline static const Vector4& nan() { static Vector4 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; } + + /** sqrt(this->dot(*this)) */ + float length() const; + float squaredLength() const; + + inline float sum() const { + return x + y + z + w; + } + + /** Returns true if this vector has finite length */ + bool isFinite() const; + + /** Returns true if this vector has length == 0 */ + bool isZero() const; + + /** Returns true if this vector has length == 1 */ + bool isUnit() const; + + // arithmetic operations + Vector4 operator+ (const Vector4& rkVector) const; + Vector4 operator- (const Vector4& rkVector) const; + + inline Vector4 operator*(const Vector4& rkVector) const { + return Vector4(x * rkVector.x, y * rkVector.y, z * rkVector.z, w * rkVector.w); + } + + inline Vector4 operator/(const Vector4& rkVector) const { + return Vector4(x / rkVector.x, y / rkVector.y, z / rkVector.z, w / rkVector.w); + } + + Vector4 operator* (float fScalar) const; + Vector4 operator/ (float fScalar) const; + Vector4 operator- () const; + friend Vector4 operator* (float, const Vector4& rkVector); + + // arithmetic updates + Vector4& operator+= (const Vector4& rkVector); + Vector4& operator-= (const Vector4& rkVector); + Vector4& operator*= (float fScalar); + Vector4& operator/= (float fScalar); + + inline Vector4 clamp(const Vector4& low, const Vector4& high) const { + return Vector4( + G3D::clamp(x, low.x, high.x), + G3D::clamp(y, low.y, high.y), + G3D::clamp(z, low.z, high.z), + G3D::clamp(w, low.w, high.w)); + } + + inline Vector4 clamp(float low, float high) const { + return Vector4( + G3D::clamp(x, low, high), + G3D::clamp(y, low, high), + G3D::clamp(z, low, high), + G3D::clamp(w, low, high)); + } + + float dot (const Vector4& rkVector) const; + + Vector4 min(const Vector4& v) const; + Vector4 max(const Vector4& v) const; + + std::string toString() const; + + /** + Linear interpolation + */ + Vector4 lerp(const Vector4& v, float alpha) const; + + // 2-char swizzles + + Vector2 xx() const; + Vector2 yx() const; + Vector2 zx() const; + Vector2 wx() const; + Vector2 xy() const; + Vector2 yy() const; + Vector2 zy() const; + Vector2 wy() const; + Vector2 xz() const; + Vector2 yz() const; + Vector2 zz() const; + Vector2 wz() const; + Vector2 xw() const; + Vector2 yw() const; + Vector2 zw() const; + Vector2 ww() const; + + // 3-char swizzles + + Vector3 xxx() const; + Vector3 yxx() const; + Vector3 zxx() const; + Vector3 wxx() const; + Vector3 xyx() const; + Vector3 yyx() const; + Vector3 zyx() const; + Vector3 wyx() const; + Vector3 xzx() const; + Vector3 yzx() const; + Vector3 zzx() const; + Vector3 wzx() const; + Vector3 xwx() const; + Vector3 ywx() const; + Vector3 zwx() const; + Vector3 wwx() const; + Vector3 xxy() const; + Vector3 yxy() const; + Vector3 zxy() const; + Vector3 wxy() const; + Vector3 xyy() const; + Vector3 yyy() const; + Vector3 zyy() const; + Vector3 wyy() const; + Vector3 xzy() const; + Vector3 yzy() const; + Vector3 zzy() const; + Vector3 wzy() const; + Vector3 xwy() const; + Vector3 ywy() const; + Vector3 zwy() const; + Vector3 wwy() const; + Vector3 xxz() const; + Vector3 yxz() const; + Vector3 zxz() const; + Vector3 wxz() const; + Vector3 xyz() const; + Vector3 yyz() const; + Vector3 zyz() const; + Vector3 wyz() const; + Vector3 xzz() const; + Vector3 yzz() const; + Vector3 zzz() const; + Vector3 wzz() const; + Vector3 xwz() const; + Vector3 ywz() const; + Vector3 zwz() const; + Vector3 wwz() const; + Vector3 xxw() const; + Vector3 yxw() const; + Vector3 zxw() const; + Vector3 wxw() const; + Vector3 xyw() const; + Vector3 yyw() const; + Vector3 zyw() const; + Vector3 wyw() const; + Vector3 xzw() const; + Vector3 yzw() const; + Vector3 zzw() const; + Vector3 wzw() const; + Vector3 xww() const; + Vector3 yww() const; + Vector3 zww() const; + Vector3 www() const; + + // 4-char swizzles + + Vector4 xxxx() const; + Vector4 yxxx() const; + Vector4 zxxx() const; + Vector4 wxxx() const; + Vector4 xyxx() const; + Vector4 yyxx() const; + Vector4 zyxx() const; + Vector4 wyxx() const; + Vector4 xzxx() const; + Vector4 yzxx() const; + Vector4 zzxx() const; + Vector4 wzxx() const; + Vector4 xwxx() const; + Vector4 ywxx() const; + Vector4 zwxx() const; + Vector4 wwxx() const; + Vector4 xxyx() const; + Vector4 yxyx() const; + Vector4 zxyx() const; + Vector4 wxyx() const; + Vector4 xyyx() const; + Vector4 yyyx() const; + Vector4 zyyx() const; + Vector4 wyyx() const; + Vector4 xzyx() const; + Vector4 yzyx() const; + Vector4 zzyx() const; + Vector4 wzyx() const; + Vector4 xwyx() const; + Vector4 ywyx() const; + Vector4 zwyx() const; + Vector4 wwyx() const; + Vector4 xxzx() const; + Vector4 yxzx() const; + Vector4 zxzx() const; + Vector4 wxzx() const; + Vector4 xyzx() const; + Vector4 yyzx() const; + Vector4 zyzx() const; + Vector4 wyzx() const; + Vector4 xzzx() const; + Vector4 yzzx() const; + Vector4 zzzx() const; + Vector4 wzzx() const; + Vector4 xwzx() const; + Vector4 ywzx() const; + Vector4 zwzx() const; + Vector4 wwzx() const; + Vector4 xxwx() const; + Vector4 yxwx() const; + Vector4 zxwx() const; + Vector4 wxwx() const; + Vector4 xywx() const; + Vector4 yywx() const; + Vector4 zywx() const; + Vector4 wywx() const; + Vector4 xzwx() const; + Vector4 yzwx() const; + Vector4 zzwx() const; + Vector4 wzwx() const; + Vector4 xwwx() const; + Vector4 ywwx() const; + Vector4 zwwx() const; + Vector4 wwwx() const; + Vector4 xxxy() const; + Vector4 yxxy() const; + Vector4 zxxy() const; + Vector4 wxxy() const; + Vector4 xyxy() const; + Vector4 yyxy() const; + Vector4 zyxy() const; + Vector4 wyxy() const; + Vector4 xzxy() const; + Vector4 yzxy() const; + Vector4 zzxy() const; + Vector4 wzxy() const; + Vector4 xwxy() const; + Vector4 ywxy() const; + Vector4 zwxy() const; + Vector4 wwxy() const; + Vector4 xxyy() const; + Vector4 yxyy() const; + Vector4 zxyy() const; + Vector4 wxyy() const; + Vector4 xyyy() const; + Vector4 yyyy() const; + Vector4 zyyy() const; + Vector4 wyyy() const; + Vector4 xzyy() const; + Vector4 yzyy() const; + Vector4 zzyy() const; + Vector4 wzyy() const; + Vector4 xwyy() const; + Vector4 ywyy() const; + Vector4 zwyy() const; + Vector4 wwyy() const; + Vector4 xxzy() const; + Vector4 yxzy() const; + Vector4 zxzy() const; + Vector4 wxzy() const; + Vector4 xyzy() const; + Vector4 yyzy() const; + Vector4 zyzy() const; + Vector4 wyzy() const; + Vector4 xzzy() const; + Vector4 yzzy() const; + Vector4 zzzy() const; + Vector4 wzzy() const; + Vector4 xwzy() const; + Vector4 ywzy() const; + Vector4 zwzy() const; + Vector4 wwzy() const; + Vector4 xxwy() const; + Vector4 yxwy() const; + Vector4 zxwy() const; + Vector4 wxwy() const; + Vector4 xywy() const; + Vector4 yywy() const; + Vector4 zywy() const; + Vector4 wywy() const; + Vector4 xzwy() const; + Vector4 yzwy() const; + Vector4 zzwy() const; + Vector4 wzwy() const; + Vector4 xwwy() const; + Vector4 ywwy() const; + Vector4 zwwy() const; + Vector4 wwwy() const; + Vector4 xxxz() const; + Vector4 yxxz() const; + Vector4 zxxz() const; + Vector4 wxxz() const; + Vector4 xyxz() const; + Vector4 yyxz() const; + Vector4 zyxz() const; + Vector4 wyxz() const; + Vector4 xzxz() const; + Vector4 yzxz() const; + Vector4 zzxz() const; + Vector4 wzxz() const; + Vector4 xwxz() const; + Vector4 ywxz() const; + Vector4 zwxz() const; + Vector4 wwxz() const; + Vector4 xxyz() const; + Vector4 yxyz() const; + Vector4 zxyz() const; + Vector4 wxyz() const; + Vector4 xyyz() const; + Vector4 yyyz() const; + Vector4 zyyz() const; + Vector4 wyyz() const; + Vector4 xzyz() const; + Vector4 yzyz() const; + Vector4 zzyz() const; + Vector4 wzyz() const; + Vector4 xwyz() const; + Vector4 ywyz() const; + Vector4 zwyz() const; + Vector4 wwyz() const; + Vector4 xxzz() const; + Vector4 yxzz() const; + Vector4 zxzz() const; + Vector4 wxzz() const; + Vector4 xyzz() const; + Vector4 yyzz() const; + Vector4 zyzz() const; + Vector4 wyzz() const; + Vector4 xzzz() const; + Vector4 yzzz() const; + Vector4 zzzz() const; + Vector4 wzzz() const; + Vector4 xwzz() const; + Vector4 ywzz() const; + Vector4 zwzz() const; + Vector4 wwzz() const; + Vector4 xxwz() const; + Vector4 yxwz() const; + Vector4 zxwz() const; + Vector4 wxwz() const; + Vector4 xywz() const; + Vector4 yywz() const; + Vector4 zywz() const; + Vector4 wywz() const; + Vector4 xzwz() const; + Vector4 yzwz() const; + Vector4 zzwz() const; + Vector4 wzwz() const; + Vector4 xwwz() const; + Vector4 ywwz() const; + Vector4 zwwz() const; + Vector4 wwwz() const; + Vector4 xxxw() const; + Vector4 yxxw() const; + Vector4 zxxw() const; + Vector4 wxxw() const; + Vector4 xyxw() const; + Vector4 yyxw() const; + Vector4 zyxw() const; + Vector4 wyxw() const; + Vector4 xzxw() const; + Vector4 yzxw() const; + Vector4 zzxw() const; + Vector4 wzxw() const; + Vector4 xwxw() const; + Vector4 ywxw() const; + Vector4 zwxw() const; + Vector4 wwxw() const; + Vector4 xxyw() const; + Vector4 yxyw() const; + Vector4 zxyw() const; + Vector4 wxyw() const; + Vector4 xyyw() const; + Vector4 yyyw() const; + Vector4 zyyw() const; + Vector4 wyyw() const; + Vector4 xzyw() const; + Vector4 yzyw() const; + Vector4 zzyw() const; + Vector4 wzyw() const; + Vector4 xwyw() const; + Vector4 ywyw() const; + Vector4 zwyw() const; + Vector4 wwyw() const; + Vector4 xxzw() const; + Vector4 yxzw() const; + Vector4 zxzw() const; + Vector4 wxzw() const; + Vector4 xyzw() const; + Vector4 yyzw() const; + Vector4 zyzw() const; + Vector4 wyzw() const; + Vector4 xzzw() const; + Vector4 yzzw() const; + Vector4 zzzw() const; + Vector4 wzzw() const; + Vector4 xwzw() const; + Vector4 ywzw() const; + Vector4 zwzw() const; + Vector4 wwzw() const; + Vector4 xxww() const; + Vector4 yxww() const; + Vector4 zxww() const; + Vector4 wxww() const; + Vector4 xyww() const; + Vector4 yyww() const; + Vector4 zyww() const; + Vector4 wyww() const; + Vector4 xzww() const; + Vector4 yzww() const; + Vector4 zzww() const; + Vector4 wzww() const; + Vector4 xwww() const; + Vector4 ywww() const; + Vector4 zwww() const; + Vector4 wwww() const; + +}; + +} + +inline G3D::Vector4 operator* (float s, const G3D::Vector4& v) { + return v * s; +} + +unsigned int hashCode(const G3D::Vector4& v); + +#include "Vector4.inl" + +#endif diff --git a/dep/include/g3dlite/G3D/Vector4.inl b/dep/include/g3dlite/G3D/Vector4.inl new file mode 100644 index 000000000..48ebf5427 --- /dev/null +++ b/dep/include/g3dlite/G3D/Vector4.inl @@ -0,0 +1,193 @@ +/** + @file Vector4.inl + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2002-07-09 + @edited 2003-02-10 + */ + +//---------------------------------------------------------------------------- + +inline unsigned int hashCode(const G3D::Vector4& v) { + return v.hashCode(); +} + +namespace G3D { + +//---------------------------------------------------------------------------- +inline Vector4::Vector4() { + x = y = z = w = 0; +} + +//---------------------------------------------------------------------------- + +inline Vector4::Vector4 (float fX, float fY, float fZ, float fW) { + x = fX; + y = fY; + z = fZ; + w = fW; +} + +//---------------------------------------------------------------------------- +inline Vector4::Vector4 (float afCoordinate[4]) { + x = afCoordinate[0]; + y = afCoordinate[1]; + z = afCoordinate[2]; + w = afCoordinate[3]; +} + +//---------------------------------------------------------------------------- +inline Vector4::Vector4(const Vector4& rkVector) { + x = rkVector.x; + y = rkVector.y; + z = rkVector.z; + w = rkVector.w; +} +//---------------------------------------------------------------------------- +inline Vector4::Vector4(const Vector3& rkVector, float fW) { + x = rkVector.x; + y = rkVector.y; + z = rkVector.z; + w = fW; +} + +//---------------------------------------------------------------------------- +inline float& Vector4::operator[] (int i) { + return ((float*)this)[i]; +} + +//---------------------------------------------------------------------------- +inline const float& Vector4::operator[] (int i) const { + return ((float*)this)[i]; +} + +//---------------------------------------------------------------------------- +inline Vector4::operator float* () { + return (float*)this; +} + +inline Vector4::operator const float* () const { + return (float*)this; +} + +//---------------------------------------------------------------------------- +inline Vector4& Vector4::operator= (const Vector4& rkVector) { + x = rkVector.x; + y = rkVector.y; + z = rkVector.z; + w = rkVector.w; + return *this; +} + +//---------------------------------------------------------------------------- +inline bool Vector4::operator== (const Vector4& rkVector) const { + return ( (x == rkVector.x) && (y == rkVector.y) && (z == rkVector.z) && (w == rkVector.w)); +} + +//---------------------------------------------------------------------------- +inline bool Vector4::operator!= (const Vector4& rkVector) const { + return ( x != rkVector.x || y != rkVector.y || z != rkVector.z || w != rkVector.w); +} + +//---------------------------------------------------------------------------- +inline Vector4 Vector4::operator+ (const Vector4& rkVector) const { + return Vector4(x + rkVector.x, y + rkVector.y, z + rkVector.z, w + rkVector.w); +} + +//---------------------------------------------------------------------------- +inline Vector4 Vector4::operator- (const Vector4& rkVector) const { + return Vector4(x - rkVector.x, y - rkVector.y, z - rkVector.z, w - rkVector.w); +} + +//---------------------------------------------------------------------------- +inline Vector4 Vector4::operator* (float fScalar) const { + return Vector4(fScalar*x, fScalar*y, fScalar*z, fScalar*w); +} + +//---------------------------------------------------------------------------- +inline Vector4 Vector4::operator- () const { + return Vector4( -x, -y, -z, -w); +} + +//---------------------------------------------------------------------------- +inline Vector4& Vector4::operator+= (const Vector4& rkVector) { + x += rkVector.x; + y += rkVector.y; + z += rkVector.z; + w += rkVector.w; + return *this; +} + +//---------------------------------------------------------------------------- +inline Vector4& Vector4::operator-= (const Vector4& rkVector) { + x -= rkVector.x; + y -= rkVector.y; + z -= rkVector.z; + w -= rkVector.w; + return *this; +} + +//---------------------------------------------------------------------------- + +inline Vector4 Vector4::lerp(const Vector4& v, float alpha) const { + return (*this) + (v - *this) * alpha; +} + + +//---------------------------------------------------------------------------- +inline Vector4& Vector4::operator*= (float fScalar) { + x *= fScalar; + y *= fScalar; + z *= fScalar; + w *= fScalar; + return *this; +} + + +//---------------------------------------------------------------------------- +inline float Vector4::dot(const Vector4& rkVector) const { + return x*rkVector.x + y*rkVector.y + z*rkVector.z + w*rkVector.w; +} + +//---------------------------------------------------------------------------- +inline Vector4 Vector4::min(const Vector4 &v) const { + return Vector4(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z), G3D::min(v.w, w)); +} + +//---------------------------------------------------------------------------- +inline Vector4 Vector4::max(const Vector4 &v) const { + return Vector4(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z), G3D::max(v.w, w)); +} + +//---------------------------------------------------------------------------- +inline bool Vector4::isZero() const { + return (x == 0.0f) && (y == 0.0f) && (z == 0.0f) && (w == 0.0f); +} + +//---------------------------------------------------------------------------- + +inline bool Vector4::isFinite() const { + return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z) && G3D::isFinite(w); +} + +//---------------------------------------------------------------------------- + +inline bool Vector4::isUnit() const { + return squaredLength() == 1.0; +} + +//---------------------------------------------------------------------------- + +inline float Vector4::length() const { + return sqrtf(squaredLength()); +} + +//---------------------------------------------------------------------------- + +inline float Vector4::squaredLength() const { + return x * x + y * y + z * z + w * w; +} + +} + diff --git a/dep/include/g3dlite/G3D/debug.h b/dep/include/g3dlite/G3D/debug.h new file mode 100644 index 000000000..0216d1daf --- /dev/null +++ b/dep/include/g3dlite/G3D/debug.h @@ -0,0 +1,11 @@ + +#ifndef G3D_LITE_DEBUG_H +#define G3D_LITE_DEBUG_H + +#define debugStatement(x) +#define debugAssert(x) +#define debugAssertM(x, y) +#define alwaysAssertM(x, y) + +#endif + diff --git a/dep/include/g3dlite/G3D/format.h b/dep/include/g3dlite/G3D/format.h new file mode 100644 index 000000000..b031300ab --- /dev/null +++ b/dep/include/g3dlite/G3D/format.h @@ -0,0 +1,57 @@ +/** + @file format.h + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @author 2000-09-09 + @edited 2005-11-03 + + Copyright 2000-2005, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_FORMAT_H +#define G3D_FORMAT_H + +#include "G3D/platform.h" +#include +#include +#include +#include +#ifndef G3D_WIN32 + // Don't include varargs.h for some random + // gcc reason + //#include + #include +#endif + +#ifndef _MSC_VER + #ifndef __cdecl + #define __cdecl __attribute__((cdecl)) + #endif +#endif + +namespace G3D { + +/** + Produces a string from arguments of the style of printf. This avoids + problems with buffer overflows when using sprintf and makes it easy + to use the result functionally. This function is fast when the resulting + string is under 160 characters (not including terminator) and slower + when the string is longer. + */ +std::string format( + const char* fmt + ...) G3D_CHECK_PRINTF_ARGS; + +/** + Like format, but can be called with the argument list from a ... function. + */ +std::string vformat( + const char* fmt, + va_list argPtr) G3D_CHECK_VPRINTF_ARGS; + + +}; // namespace + +#endif diff --git a/dep/include/g3dlite/G3D/g3dmath.h b/dep/include/g3dlite/G3D/g3dmath.h new file mode 100644 index 000000000..1f3eaaae5 --- /dev/null +++ b/dep/include/g3dlite/G3D/g3dmath.h @@ -0,0 +1,525 @@ +/** + @file g3dmath.h + + Math util class. + + @maintainer Morgan McGuire, matrix@graphics3d.com + @cite highestBit by Jukka Liimatta + + @created 2001-06-02 + @edited 2006-01-16 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3DMATH_H +#define G3DMATH_H + +#ifdef _MSC_VER +// Disable conditional expression is constant, which occurs incorrectly on inlined functions +# pragma warning (push) +# pragma warning (disable : 4127) +// disable: "C++ exception handler used" +# pragma warning (disable : 4530) +#endif + +#include "G3D/platform.h" +#include +#include +#include +#include + +/*These defines enable functionality introduced with the 1999 ISO C +**standard. They must be defined before the inclusion of math.h to +**engage them. If optimisation is enabled, these functions will be +**inlined. With optimisation switched off, you have to link in the +**maths library using -lm. +*/ + +#define _ISOC9X_SOURCE1 +#define _ISOC99_SOURCE1 +#define __USE_ISOC9X1 +#define __USE_ISOC991 + +#include + +#include "G3D/debug.h" + +#undef min +#undef max + +namespace G3D { + +#if defined(_MSC_VER) + +#if !defined(_WIN64) + +/** + Win32 implementation of the C99 fast rounding routines. + + @cite routines are + Copyright (C) 2001 Erik de Castro Lopo + + Permission to use, copy, modify, distribute, and sell this file for any + purpose is hereby granted without fee, provided that the above copyright + and this permission notice appear in all copies. No representations are + made about the suitability of this software for any purpose. It is + provided "as is" without express or implied warranty. +*/ + +__inline long int lrint (double flt) { + int intgr; + + _asm { + fld flt + fistp intgr + }; + + return intgr; +} + +__inline long int lrintf(float flt) { + int intgr; + + _asm { + fld flt + fistp intgr + }; + + return intgr; +} + +#else + + __inline long int lrint (double flt) { + return (long int)floor(flt+0.5f); + } + + __inline long int lrintf(float flt) { + return (long int)floorf(flt+0.5f); + } + + +#endif + +#endif + + +const double fuzzyEpsilon = 0.00001; + +/** Returns a reference to a static double. + This value should not be tested against directly, instead + G3D::isNan() and G3D::isFinite() will return reliable results. */ +inline const double& inf() { + +// We already have included but +// not using it in older gcc for safe compilations +#if (__GNUC__ == 2) + static const double i = 1.0/sin(0.0); +#else + // double is a standard type and should have infinity + static const double i = std::numeric_limits::infinity(); +#endif + return i; +} + +/** Returns a reference to a static double. + This value should not be tested against directly, instead + G3D::isNan() and G3D::isFinite() will return reliable results. */ +inline const double& nan() { + +// We already have included but +// not using it in older gcc for safe compilations +#if (__GNUC__ == 2) + static const double n = 0.0/sin(0.0); +#else + // double is a standard type and should have quiet NaN + static const double n = std::numeric_limits::quiet_NaN(); +#endif + return n; +} + +/** Returns a reference to a static double. Use instead of G3D_PI. */ +inline const double& pi() { + static const double p = 3.1415926535898; + return p; +} + +/** Returns a reference to a static double. Use instead of G3D_HALF_PI. */ +inline const double& halfPi() { + static const double p = 1.5707963267949; + return p; +} + +/** Returns a reference to a static double. Use instead of G3D_TWO_PI. */ +inline const double& twoPi() { + static const double p = 6.283185; + return p; +} + +/** @def G3D_PI + @deprecated Use G3D::pi() instead. */ +#define G3D_PI (3.1415926535898) +/** @def G3D_HALF_PI + @deprecated Use G3D::halfPi() instead. */ +#define G3D_HALF_PI (1.5707963267949) +/** @def G3D_TWO_PI + @deprecated Use G3D::twoPi() instead. */ +#define G3D_TWO_PI (6.283185) + +typedef signed char int8; +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; +typedef int int32; +typedef unsigned int uint32; + +#ifdef _MSC_EXTENSIONS + typedef __int64 int64; + typedef unsigned __int64 uint64; +#else + typedef long long int64; + typedef unsigned long long uint64; +#endif +typedef unsigned int uint; + +typedef float float32; +typedef double float64; + +int iAbs(int iValue); +int iCeil(double fValue); + +/** + Clamps the value to the range [low, hi] (inclusive) + */ +int iClamp(int val, int low, int hi); +double clamp(double val, double low, double hi); +float clamp(float val, float low, float hi); + +/** + Returns a + (b - a) * f; + */ +inline double lerp(double a, double b, double f) { + return a + (b - a) * f; +} + +inline float lerp(float a, float b, float f) { + return a + (b - a) * f; +} + +/** + Wraps the value to the range [0, hi) (exclusive + on the high end). This is like the clock arithmetic + produced by % (modulo) except the result is guaranteed + to be positive. + */ +int iWrap(int val, int hi); + +int iFloor(double fValue); + +int iSign(int iValue); +int iSign(double fValue); + +inline int iSign(float f) { + return iSign((double)f); +} + + +/** + Fast round to integer using the lrint routine. + Typically 6x faster than casting to integer. + */ +inline int iRound(double fValue) { + return lrint(fValue); +} + +/** + Fast round to integer using the lrint routine. + Typically 6x faster than casting to integer. + */ +inline int iRound(float f) { + return lrintf(f); +} + +/** + Returns a random number uniformly at random between low and hi + (inclusive). + */ +int iRandom(int low, int hi); + +double abs (double fValue); +double aCos (double fValue); +double aSin (double fValue); +double aTan (double fValue); +double aTan2 (double fY, double fX); +double sign (double fValue); +double square (double fValue); + +/** + Returns true if the argument is a finite real number. + */ +bool isFinite(double x); + +/** + Returns true if the argument is NaN (not a number). + You can't use x == nan to test this because all + comparisons against nan return false. + */ +bool isNaN(double x); + +/** + Computes x % 3. + */ +int iMod3(int x); + +/** + [0, 1] + @deprecated use uniformRandom() + */ +double unitRandom (); + +/** + Uniform random number between low and hi, inclusive. + @deprecated use uniformRandom() + */ +double random(double low, double hi); + +/** + [-1, 1] + @deprecated use uniformRandom() + */ +double symmetricRandom (); + +/** + Uniform random number between low and hi, inclusive. [low, hi] + */ +float uniformRandom(float low = 0.0f, float hi = 1.0f); + +/** + Normally distributed random number. + */ +float gaussRandom(float mean = 0.0f, float stdev = 1.0f); + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) + + /** VC6 lacks std::min and std::max */ + inline double min(double x, double y) { + return std::_cpp_min(x, y); + } + + /** VC6 lacks std::min and std::max */ + inline float min(float x, float y) { + return std::_cpp_min(x, y); + } + + /** VC6 lacks std::min and std::max */ + inline int min(int x, int y) { + return std::_cpp_min(x, y); + } + + /** VC6 lacks std::min and std::max */ + inline double max(double x, double y) { + return std::_cpp_max(x, y); + } + + /** VC6 lacks std::min and std::max */ + inline float max(float x, float y) { + return std::_cpp_max(x, y); + } + + /** VC6 lacks std::min and std::max */ + inline int max(int x, int y) { + return std::_cpp_max(x, y); + } + +#else + template + inline T min(const T& x, const T& y) { + return std::min(x, y); + } + + template + inline T max(const T& x, const T& y) { + return std::max(x, y); + } + +#endif + +int iMin(int x, int y); +int iMax(int x, int y); + +double square(double x); +double sumSquares(double x, double y); +double sumSquares(double x, double y, double z); +double distance(double x, double y); +double distance(double x, double y, double z); + +/** + Returnes the 0-based index of the highest 1 bit from + the left. -1 means the number was 0. + + @cite Based on code by jukka@liimatta.org + */ +int highestBit(uint32 x); + +/** + Note that fuzzyEq(a, b) && fuzzyEq(b, c) does not imply + fuzzyEq(a, c), although that will be the case on some + occasions. + */ +bool fuzzyEq(double a, double b); + +/** True if a is definitely not equal to b. + Guaranteed false if a == b. + Possibly false when a != b.*/ +bool fuzzyNe(double a, double b); + +/** Is a strictly greater than b? (Guaranteed false if a <= b). + (Possibly false if a > b) */ +bool fuzzyGt(double a, double b); + +/** Is a near or greater than b? */ +bool fuzzyGe(double a, double b); + +/** Is a strictly less than b? (Guaranteed false if a >= b)*/ +bool fuzzyLt(double a, double b); + +/** Is a near or less than b? */ +bool fuzzyLe(double a, double b); + +/** + Computes 1 / sqrt(x). + */ +inline float rsq(float x) { + return 1.0f / sqrtf(x); +} + +/** + Uses SSE to implement rsq. + @cite Nick nicolas@capens.net + */ +inline float SSErsq(float x) { + + #if defined(SSE) && defined(G3D_WIN32) && !defined(_WIN64) + __asm { + movss xmm0, x + rsqrtss xmm0, xmm0 + movss x, xmm0 + } + return x; + #else + return 1.0f / sqrt(x); + #endif +} + +/** + Return the next power of 2 higher than the input + If the input is already a power of 2, the output will be the same + as the input. + */ +int ceilPow2(unsigned int in); + +/** + * True if num is a power of two. + */ +bool isPow2(int num); + +bool isOdd(int num); +bool isEven(int num); + +double toRadians(double deg); +double toDegrees(double rad); + +/** + Returns true if x is not exactly equal to 0.0f. + */ +inline bool any(float x) { + return x != 0; +} + +/** + Returns true if x is not exactly equal to 0.0f. + */ +inline bool all(float x) { + return x != 0; +} + +/** + v / v (for DirectX/Cg support) + */ +inline float normalize(float v) { + return v / v; +} + +/** + a * b (for DirectX/Cg support) + */ +inline float dot(float a, float b) { + return a * b; +} + + +/** + a * b (for DirectX/Cg support) + */ +inline float mul(float a, float b) { + return a * b; +} + +/** + 2^x + */ +inline double exp2(double x) { + return pow(2.0, x); +} + +inline double rsqrt(double x) { + return 1.0 / sqrt(x); +} + + +/** + sin(x)/x + */ +inline double sinc(double x) { + double r = sin(x) / x; + + if (isNaN(r)) { + return 1.0; + } else { + return r; + } +} + +/** + Computes a floating point modulo; the result is t wrapped to the range [lo, hi). + */ +inline double wrap(double t, double lo, double hi) { + if ((t >= lo) && (t < hi)) { + return t; + } + + debugAssert(hi > lo); + + double interval = hi - lo; + + return t - interval * iFloor((t - lo) / interval); + +} + +inline double wrap(double t, double hi) { + return wrap(t, 0, hi); +} + + +} // namespace + +#ifdef _MSC_VER +# pragma warning (pop) +#endif + +#include "g3dmath.inl" + +#endif + diff --git a/dep/include/g3dlite/G3D/g3dmath.inl b/dep/include/g3dlite/G3D/g3dmath.inl new file mode 100644 index 000000000..1068ed5bf --- /dev/null +++ b/dep/include/g3dlite/G3D/g3dmath.inl @@ -0,0 +1,289 @@ +/** + @file g3dmath.inl + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2006-01-14 + */ + +#include + +#ifdef _MSC_VER +// Disable conditional expression is constant, which occurs incorrectly on inlined functions +# pragma warning (push) +# pragma warning( disable : 4127 ) +#endif + +namespace G3D { + +inline bool isNaN(double x) { + bool b1 = (x < 0.0); + bool b2 = (x >= 0.0); + bool b3 = !(b1 || b2); + return b3; +} + +inline bool isFinite(double x) { + return ! isNaN(x) && (x < G3D::inf()) && (x > -G3D::inf()); +} + +//---------------------------------------------------------------------------- +inline int iAbs (int iValue) { + return ( iValue >= 0 ? iValue : -iValue ); +} + +//---------------------------------------------------------------------------- +inline int iCeil (double fValue) { + return int(::ceil(fValue)); +} + +//---------------------------------------------------------------------------- + +inline int iClamp(int val, int low, int hi) { + debugAssert(low <= hi); + if (val <= low) { + return low; + } else if (val >= hi) { + return hi; + } else { + return val; + } +} + +//---------------------------------------------------------------------------- + +inline double clamp(double val, double low, double hi) { + debugAssert(low <= hi); + if (val <= low) { + return low; + } else if (val >= hi) { + return hi; + } else { + return val; + } +} + +inline float clamp(float val, float low, float hi) { + debugAssert(low <= hi); + if (val <= low) { + return low; + } else if (val >= hi) { + return hi; + } else { + return val; + } +} +//---------------------------------------------------------------------------- + +inline int iWrap(int val, int hi) { + if (val < 0) { + return ((val % hi) + hi) % hi; + } else { + return val % hi; + } +} + +//---------------------------------------------------------------------------- +inline int iFloor (double fValue) { + return int(::floor(fValue)); +} + +//---------------------------------------------------------------------------- +inline int iSign (int iValue) { + return ( iValue > 0 ? + 1 : ( iValue < 0 ? -1 : 0 ) ); +} + +inline int iSign (double fValue) { + return ( fValue > 0.0 ? + 1 : ( fValue < 0.0 ? -1 : 0 ) ); +} + +//---------------------------------------------------------------------------- +inline double abs (double fValue) { + return double(::fabs(fValue)); +} + +//---------------------------------------------------------------------------- +inline double aCos (double fValue) { + if ( -1.0 < fValue ) { + if ( fValue < 1.0 ) + return double(::acos(fValue)); + else + return 0.0; + } else { + return G3D_PI; + } +} + +//---------------------------------------------------------------------------- +inline double aSin (double fValue) { + if ( -1.0 < fValue ) { + if ( fValue < 1.0 ) { + return double(::asin(fValue)); + } else { + return -G3D_HALF_PI; + } + } else { + return G3D_HALF_PI; + } +} + +//---------------------------------------------------------------------------- +inline double aTan (double fValue) { + return double(::atan(fValue)); +} + +//---------------------------------------------------------------------------- +inline double aTan2 (double fY, double fX) { + return double(::atan2(fY, fX)); +} + +//---------------------------------------------------------------------------- +inline double sign (double fValue) { + if (fValue > 0.0) { + return 1.0; + } + + if (fValue < 0.0) { + return -1.0; + } + + return 0.0; +} + +inline double G3D_DEPRECATED unitRandom () { + return double(::rand()) / double(RAND_MAX); +} + +inline float uniformRandom(float low, float hi) { + return (hi - low) * float(::rand()) / float(RAND_MAX) + low; +} + + +//---------------------------------------------------------------------------- +inline double G3D_DEPRECATED symmetricRandom () { + return 2.0 * double(::rand()) / double(RAND_MAX) - 1.0; +} + +//---------------------------------------------------------------------------- +inline double square(double x) { + return x * x; +} + +//---------------------------------------------------------------------------- +inline double sumSquares(double x, double y) { + return x*x + y*y; +} + +//---------------------------------------------------------------------------- +inline double sumSquares(double x, double y, double z) { + return x*x + y*y + z*z; +} + +//---------------------------------------------------------------------------- +inline double distance(double x, double y) { + return sqrt(sumSquares(x, y)); +} + +//---------------------------------------------------------------------------- +inline double distance(double x, double y, double z) { + return sqrt(sumSquares(x, y, z)); +} + +//---------------------------------------------------------------------------- + +/** @deprecated use G3D::min */ +inline int iMin(int x, int y) { + return (x >= y) ? y : x; +} + +//---------------------------------------------------------------------------- +/** @deprecated use G3D::min */ +inline int iMax(int x, int y) { + return (x >= y) ? x : y; +} + +//---------------------------------------------------------------------------- +inline int ceilPow2(unsigned int in) { + in -= 1; + + in |= in >> 16; + in |= in >> 8; + in |= in >> 4; + in |= in >> 2; + in |= in >> 1; + + return in + 1; +} + +inline bool isPow2(int num) { + return ((num & -num) == num); +} + +inline bool isOdd(int num) { + return (num & 1) == 1; +} + +inline bool isEven(int num) { + return (num & 1) == 0; +} + +inline double toRadians(double deg) { + return deg * G3D_PI / 180.0; +} + +inline double toDegrees(double rad) { + return rad * 180.0 / G3D_PI; +} + +/** + Computes an appropriate epsilon for comparing a and b. + */ +inline double eps(double a, double b) { + // For a and b to be nearly equal, they must have nearly + // the same magnitude. This means that we can ignore b + // since it either has the same magnitude or the comparison + // will fail anyway. + (void)b; + const double aa = abs(a) + 1; + if (aa == inf()) { + return fuzzyEpsilon; + } else { + return fuzzyEpsilon * aa; + } +} + +inline bool fuzzyEq(double a, double b) { + return (a == b) || (abs(a - b) <= eps(a, b)); +} + +inline bool fuzzyNe(double a, double b) { + return ! fuzzyEq(a, b); +} + +inline bool fuzzyGt(double a, double b) { + return a > b + eps(a, b); +} + +inline bool fuzzyGe(double a, double b) { + return a > b - eps(a, b); +} + +inline bool fuzzyLt(double a, double b) { + return a < b - eps(a, b); +} + +inline bool fuzzyLe(double a, double b) { + return a < b + eps(a, b); +} + +inline int iMod3(int x) { + return x % 3; +} + +} // namespace G3D + +#ifdef _MSC_VER +// Disable conditional expression is constant, which occurs incorrectly on inlined functions +# pragma warning (pop) +#endif diff --git a/dep/include/g3dlite/G3D/platform.h b/dep/include/g3dlite/G3D/platform.h new file mode 100644 index 000000000..fed9c7b53 --- /dev/null +++ b/dep/include/g3dlite/G3D/platform.h @@ -0,0 +1,269 @@ +/** + @file platform.h + + #defines for platform specific issues. + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2003-06-09 + @edited 2006-01-16 + */ + +#ifndef G3D_PLATFORM_H +#define G3D_PLATFORM_H + +/** + The version number of G3D in the form: MmmBB -> + version M.mm [beta BB] + */ +#define G3D_VER 61000 + +#if defined(G3D_RELEASEDEBUG) +# define G3D_DEBUGRELEASE +#endif + +#if defined(G3D_DEBUGRELEASE) && defined(_DEBUG) +# undef _DEBUG +#endif + +#if !defined(G3D_DEBUG) && (defined(_DEBUG) || defined(G3D_DEBUGRELEASE)) +# define G3D_DEBUG +#endif + +#ifdef _MSC_VER + #define G3D_WIN32 +#elif defined(__MINGW32__) + #define G3D_WIN32 + #define G3D_MINGW32 +#elif defined(__linux__) + #define G3D_LINUX +#elif defined(__OpenBSD__) + #define G3D_LINUX +#elif defined(__FreeBSD__) + #define G3D_LINUX +#elif defined(__NetBSD__) + #define G3D_LINUX +#elif defined(__APPLE__) + #define G3D_OSX +#else + #error Unknown platform +#endif + + +// Default to compiling with SSE, but if you want to compile +// without installing SP5.0 and the Processor Pack on Windows, compile with NO_SSE +// defined (can be passed to the compiler command line with /D "NO_SSE") +#if !defined(NO_SSE) + #define SSE +#endif + +#ifdef G3D_WIN32 +// Turn off warnings about deprecated C routines (TODO: revisit) +# pragma warning (disable : 4996) +#endif + +// On g++, recognize cases where the -msse2 flag was not specified +#if defined(SSE) && defined(__GNUC__) && ! defined (__SSE__) +# undef SSE +#endif + +#if defined(__GNUC__) +# if __STDC_VERSION__ < 199901 +# define restrict __restrict__ +# endif +#endif + + +// Verify that the supported compilers are being used and that this is a known +// processor. + +#ifdef G3D_LINUX +# ifndef __GNUC__ +# error G3D only supports the gcc compiler on Linux. +# endif + +//# ifndef __i386__ +//# error G3D only supports x86 machines on Linux. +//# endif + +# define G3D_DEPRECATED __attribute__((__deprecated__)) + +# ifndef __cdecl +# define __cdecl __attribute__((cdecl)) +# endif + +# ifndef __stdcall +# define __stdcall __attribute__((stdcall)) +# endif + +# define G3D_CHECK_PRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 3))) +# define G3D_CHECK_VPRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 0))) +# define G3D_CHECK_PRINTF_ARGS __attribute__((__format__(__printf__, 1, 2))) +# define G3D_CHECK_VPRINTF_ARGS __attribute__((__format__(__printf__, 1, 0))) +#endif + + +#ifdef G3D_OSX + #ifndef __GNUC__ + #error G3D only supports the gcc compiler on OS X. + #endif + + #if defined(__i386__) + #define G3D_OSX_INTEL + #elif defined(__PPC__) + #define G3D_OSX_PPC + #else + #define G3D_OSX_UNKNOWN + #endif + +# ifndef __cdecl +# define __cdecl __attribute__((cdecl)) +# endif + +# ifndef __stdcall +# define __stdcall __attribute__((stdcall)) +# endif + +# define G3D_DEPRECATED __attribute__((__deprecated__)) + +# define G3D_CHECK_PRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 3))) +# define G3D_CHECK_VPRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 0))) +# define G3D_CHECK_PRINTF_ARGS __attribute__((__format__(__printf__, 1, 2))) +# define G3D_CHECK_VPRINTF_ARGS __attribute__((__format__(__printf__, 1, 0))) +#endif + + +#ifdef G3D_WIN32 +// Microsoft Visual C++ 7.1 _MSC_VER = 1310 +// Microsoft Visual C++ 7.0 _MSC_VER = 1300 +// Microsoft Visual C++ 6.0 _MSC_VER = 1200 +// Microsoft Visual C++ 5.0 _MSC_VER = 1100 + + // Old versions of MSVC (6.0 and previous) don't + // support C99 for loop scoping rules. This fixes them. +# if (_MSC_VER <= 1200) + // This trick will generate a warning; disable the warning +# pragma warning (disable : 4127) +# define for if (false) {} else for +# endif + +# if (_MSC_VER <= 1200) +// Nothing we can do on VC6 for deprecated functions +# define G3D_DEPRECATED +# else +# define G3D_DEPRECATED __declspec(deprecated) +# endif + +// Prevent Winsock conflicts by hiding the winsock API +#ifndef _WINSOCKAPI_ +# define _G3D_INTERNAL_HIDE_WINSOCK_ +# define _WINSOCKAPI_ +# endif + +// Disable 'name too long for browse information' warning +# pragma warning (disable : 4786) +// TODO: remove +# pragma warning (disable : 4244) + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) + // VC6 std:: has signed problems in it +# pragma warning (disable : 4018) +# endif + +# define ZLIB_WINAPI + +// Mingw32 defines restrict +# ifndef G3D_MINGW32 +# define restrict +# endif + +# define G3D_CHECK_PRINTF_ARGS +# define G3D_CHECK_VPRINTF_ARGS +# define G3D_CHECK_PRINTF_METHOD_ARGS +# define G3D_CHECK_VPRINTF_METHOD_ARGS + + // On MSVC, we need to link against the multithreaded DLL version of + // the C++ runtime because that is what SDL and ZLIB are compiled + // against. This is not the default for MSVC, so we set the following + // defines to force correct linking. + // + // For documentation on compiler options, see: + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_Compiler_Reference.asp + // + +#if 0 //ignore that for mangos + // DLL runtime + #ifndef _DLL + #define _DLL + #endif + + // Multithreaded runtime + #ifndef _MT + #define _MT 1 + #endif + // Ensure that we aren't forced into the static lib + #ifdef _STATIC_CPPLIB + #undef _STATIC_CPPLIB + #endif +#endif + + #ifdef _DEBUG + #pragma comment (linker, "/NODEFAULTLIB:libc.lib") + #pragma comment (linker, "/NODEFAULTLIB:libcmt.lib") + #pragma comment (linker, "/NODEFAULTLIB:msvcrt.lib") + #pragma comment (linker, "/NODEFAULTLIB:libcd.lib") + #pragma comment (linker, "/NODEFAULTLIB:msvcrtd.lib") + #else + #pragma comment(linker, "/NODEFAULTLIB:LIBC.LIB") + #pragma comment(linker, "/NODEFAULTLIB:msvcrt.lib") + #pragma comment(linker, "/NODEFAULTLIB:libcd.lib") + #pragma comment(linker, "/NODEFAULTLIB:libcmtd.lib") + #pragma comment(linker, "/NODEFAULTLIB:msvcrtd.lib") + #endif + + // Now set up external linking + + #ifdef _DEBUG + // zlib and SDL were linked against the release MSVCRT; force + // the debug version. + #pragma comment(linker, "/NODEFAULTLIB:MSVCRT.LIB") +# endif + +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif + + +# define NOMINMAX 1 +# include +# undef WIN32_LEAN_AND_MEAN +# undef NOMINMAX + +#ifdef _G3D_INTERNAL_HIDE_WINSOCK_ +# undef _G3D_INTERNAL_HIDE_WINSOCK_ +# undef _WINSOCKAPI_ +#endif + +#endif + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) + // VC6 std:: has signed/unsigned problems +# pragma warning (disable : 4018) +# endif + +/** + @def STR(expression) + + Creates a string from the expression. Frequently used with G3D::Shader + to express shading programs inline. + + STR(this becomes a string)
 evaluates the same as "this becomes a string"
+ */
+#define STR(x) #x
+
+#undef G3D_DEPRECATED
+#define G3D_DEPRECATED
+
+// Header guard
+#endif
diff --git a/dep/include/g3dlite/G3D/stringutils.h b/dep/include/g3dlite/G3D/stringutils.h
new file mode 100644
index 000000000..9080d00b6
--- /dev/null
+++ b/dep/include/g3dlite/G3D/stringutils.h
@@ -0,0 +1,130 @@
+/**
+ @file stringutils.h
+ 
+ @maintainer Morgan McGuire, matrix@graphics3d.com
+ 
+ @author  2000-09-09
+ @edited  2002-11-30
+ */
+
+#ifndef G3D_STRINGUTILS_H
+#define G3D_STRINGUTILS_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include 
+
+namespace G3D {
+
+extern const char* NEWLINE;
+
+/**
+ Returns true if the test string begins with the pattern string.
+ */
+bool beginsWith(
+    const std::string&          test,
+    const std::string&          pattern);
+
+/**
+ Returns true if the test string ends with the pattern string.
+ */
+bool endsWith(
+    const std::string&          test,
+    const std::string&          pattern);
+
+/**
+ Produces a new string that is the input string
+ wrapped at a certain number of columns (where
+ the line is broken at the latest space before the
+ column limit.)  Platform specific NEWLINEs
+ are inserted to wrap.
+ */
+std::string wordWrap(
+    const std::string&          input,
+    int                         numCols);
+
+/**
+ A comparison function for passing to Array::sort.
+ */
+int stringCompare(
+    const std::string&          s1,
+    const std::string&          s2);
+
+int stringPtrCompare(
+    const std::string*          s1,
+    const std::string*          s2);
+
+/**
+ Returns a new string that is an uppercase version of x.
+ */
+std::string toUpper(
+    const std::string&          x);
+
+std::string toLower(
+    const std::string&          x);
+
+/**
+ Splits x at each occurance of splitChar.
+ */
+G3D::Array stringSplit(
+    const std::string&          x,
+    char                        splitChar);
+
+/**
+ joinChar is not inserted at the beginning or end, just in between
+ elements.
+ */
+std::string stringJoin(
+    const G3D::Array&   a,
+    char                        joinChar);
+
+std::string stringJoin(
+    const G3D::Array&   a,
+    const std::string&               joinStr);
+
+/**
+ Strips whitespace from both ends of the string.
+ */
+std::string trimWhitespace(
+    const std::string&              s);
+
+/** These standard C functions are renamed for clarity/naming
+   conventions and to return bool, not int.
+   */
+inline bool isWhiteSpace(const char c) {
+    return isspace(c) != 0;
+}
+
+/** These standard C functions are renamed for clarity/naming
+   conventions and to return bool, not int.
+   */
+inline bool isNewline(const char c) {
+    return (c == '\n') || (c == '\r');
+}
+
+/** These standard C functions are renamed for clarity/naming
+   conventions and to return bool, not int.
+   */
+inline bool isDigit(const char c) {
+    return isdigit(c) != 0;
+}
+
+/** These standard C functions are renamed for clarity/naming
+   conventions and to return bool, not int.
+   */
+inline bool isLetter(const char c) {
+    return isalpha(c) != 0;
+}
+
+inline bool isSlash(const char c) {
+    return (c == '\\') || (c == '/');
+}
+
+inline bool isQuote(const char c) {
+    return (c == '\'') || (c == '\"');
+}
+
+}; // namespace
+
+#endif
+
diff --git a/dep/include/mersennetwister/MersenneTwister.h b/dep/include/mersennetwister/MersenneTwister.h
new file mode 100644
index 000000000..9c6994bdf
--- /dev/null
+++ b/dep/include/mersennetwister/MersenneTwister.h
@@ -0,0 +1,414 @@
+// MersenneTwister.h
+// Mersenne Twister random number generator -- a C++ class MTRand
+// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
+// Richard J. Wagner  v1.0  15 May 2003  rjwagner@writeme.com
+
+// The Mersenne Twister is an algorithm for generating random numbers.  It
+// was designed with consideration of the flaws in various other generators.
+// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
+// are far greater.  The generator is also fast; it avoids multiplication and
+// division, and it benefits from caches and pipelines.  For more information
+// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
+
+// Reference
+// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
+// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
+// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
+
+// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+// Copyright (C) 2000 - 2003, Richard J. Wagner
+// All rights reserved.                          
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//   1. Redistributions of source code must retain the above copyright
+//      notice, this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. The names of its contributors may not be used to endorse or promote 
+//      products derived from this software without specific prior written 
+//      permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The original code included the following notice:
+//
+//     When you use this, send an email to: matumoto@math.keio.ac.jp
+//     with an appropriate reference to your work.
+//
+// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
+// when you write.
+
+#ifndef MERSENNETWISTER_H
+#define MERSENNETWISTER_H
+
+// Not thread safe (unless auto-initialization is avoided and each thread has
+// its own MTRand object)
+
+#include"Platform/Define.h"
+
+#include 
+#include 
+#include 
+
+class MTRand {
+// Data
+public:
+    typedef ::uint32 uint32;
+	enum { N = 624 };       // length of state vector
+	enum { SAVE = N + 1 };  // length of array for save()
+
+protected:
+	enum { M = 397 };  // period parameter
+	
+	uint32 state[N];   // internal state
+	uint32 *pNext;     // next value to get from state
+	int left;          // number of values left before reload needed
+
+
+//Methods
+public:
+	MTRand( const uint32& oneSeed );  // initialize with a simple uint32
+	MTRand( uint32 *const bigSeed, uint32 const seedLength = N );  // or an array
+	MTRand();                         // auto-initialize with /dev/urandom or time() and clock()
+    MTRand(const MTRand&);            // prevent copy constructor
+    MTRand& operator=(const MTRand&); // no-op operator=
+	
+	// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
+	// values together, otherwise the generator state can be learned after
+	// reading 624 consecutive values.
+	
+	// Access to 32-bit random numbers
+	double rand();                          // real number in [0,1]
+	double rand( const double& n );         // real number in [0,n]
+	double randExc();                       // real number in [0,1)
+	double randExc( const double& n );      // real number in [0,n)
+	double randDblExc();                    // real number in (0,1)
+	double randDblExc( const double& n );   // real number in (0,n)
+	uint32 randInt();                       // integer in [0,2^32-1]
+	uint32 randInt( const uint32& n );      // integer in [0,n] for n < 2^32
+	double operator()() { return rand(); }  // same as rand()
+	
+	// Access to 53-bit random numbers (capacity of IEEE double precision)
+	double rand53();  // real number in [0,1)
+	
+	// Access to nonuniform random number distributions
+	double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
+	
+	// Re-seeding functions with same behavior as initializers
+	void seed( const uint32 oneSeed );
+	void seed( uint32 *const bigSeed, const uint32 seedLength = N );
+	void seed();
+	
+	// Saving and loading generator state
+	void save( uint32* saveArray ) const;  // to array of size SAVE
+	void load( uint32 *const loadArray );  // from such array
+    /* Mangos not use streams for random values output
+	friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
+	friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
+    */
+protected:
+	void initialize( const uint32 oneSeed );
+	void reload();
+	uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
+	uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
+	uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
+	uint32 mixBits( const uint32& u, const uint32& v ) const
+		{ return hiBit(u) | loBits(v); }
+	uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
+		{ return m ^ (mixBits(s0,s1)>>1) ^ uint32(-(int32)(loBit(s1) & 0x9908b0dfUL)); }
+	static uint32 hash( time_t t, clock_t c );
+};
+
+inline MTRand::MTRand(const MTRand&)
+    { seed(); }
+
+inline MTRand& MTRand::operator=(const MTRand&) 
+    { return *this; }
+
+inline MTRand::MTRand( const uint32& oneSeed )
+	{ seed(oneSeed); }
+
+inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
+	{ seed(bigSeed,seedLength); }
+
+inline MTRand::MTRand()
+	{ seed(); }
+
+inline double MTRand::rand()
+	{ return double(randInt()) * (1.0/4294967295.0); }
+
+inline double MTRand::rand( const double& n )
+	{ return rand() * n; }
+
+inline double MTRand::randExc()
+	{ return double(randInt()) * (1.0/4294967296.0); }
+
+inline double MTRand::randExc( const double& n )
+	{ return randExc() * n; }
+
+inline double MTRand::randDblExc()
+	{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
+
+inline double MTRand::randDblExc( const double& n )
+	{ return randDblExc() * n; }
+
+inline double MTRand::rand53()
+{
+	uint32 a = randInt() >> 5, b = randInt() >> 6;
+	return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);  // by Isaku Wada
+}
+
+inline double MTRand::randNorm( const double& mean, const double& variance )
+{
+	// Return a real number from a normal (Gaussian) distribution with given
+	// mean and variance by Box-Muller method
+	double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
+	double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
+	return mean + r * cos(phi);
+}
+
+inline MTRand::uint32 MTRand::randInt()
+{
+	// Pull a 32-bit integer from the generator state
+	// Every other access function simply transforms the numbers extracted here
+	
+	if( left == 0 ) reload();
+	--left;
+		
+	register uint32 s1;
+	s1 = *pNext++;
+	s1 ^= (s1 >> 11);
+	s1 ^= (s1 <<  7) & 0x9d2c5680UL;
+	s1 ^= (s1 << 15) & 0xefc60000UL;
+	return ( s1 ^ (s1 >> 18) );
+}
+
+inline MTRand::uint32 MTRand::randInt( const uint32& n )
+{
+	// Find which bits are used in n
+	// Optimized by Magnus Jonsson (magnus@smartelectronix.com)
+	uint32 used = n;
+	used |= used >> 1;
+	used |= used >> 2;
+	used |= used >> 4;
+	used |= used >> 8;
+	used |= used >> 16;
+	
+	// Draw numbers until one is found in [0,n]
+	uint32 i;
+	do
+		i = randInt() & used;  // toss unused bits to shorten search
+	while( i > n );
+	return i;
+}
+
+
+inline void MTRand::seed( const uint32 oneSeed )
+{
+	// Seed the generator with a simple uint32
+	initialize(oneSeed);
+	reload();
+}
+
+
+inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
+{
+	// Seed the generator with an array of uint32's
+	// There are 2^19937-1 possible initial states.  This function allows
+	// all of those to be accessed by providing at least 19937 bits (with a
+	// default seed length of N = 624 uint32's).  Any bits above the lower 32
+	// in each element are discarded.
+	// Just call seed() if you want to get array from /dev/urandom
+	initialize(19650218UL);
+	register int i = 1;
+	register uint32 j = 0;
+	register int k = ( N > seedLength ? N : seedLength );
+	for( ; k; --k )
+	{
+		state[i] =
+			state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
+		state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
+		state[i] &= 0xffffffffUL;
+		++i;  ++j;
+		if( i >= N ) { state[0] = state[N-1];  i = 1; }
+		if( j >= seedLength ) j = 0;
+	}
+	for( k = N - 1; k; --k )
+	{
+		state[i] =
+			state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
+		state[i] -= i;
+		state[i] &= 0xffffffffUL;
+		++i;
+		if( i >= N ) { state[0] = state[N-1];  i = 1; }
+	}
+	state[0] = 0x80000000UL;  // MSB is 1, assuring non-zero initial array
+	reload();
+}
+
+
+inline void MTRand::seed()
+{
+	// Seed the generator with hash of time() and clock() values
+	seed( hash( time(NULL), clock() ) );
+}
+
+
+inline void MTRand::initialize( const uint32 seed )
+{
+	// Initialize generator state with seed
+	// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
+	// In previous versions, most significant bits (MSBs) of the seed affect
+	// only MSBs of the state array.  Modified 9 Jan 2002 by Makoto Matsumoto.
+	register uint32 *s = state;
+	register uint32 *r = state;
+	register int i = 1;
+	*s++ = seed & 0xffffffffUL;
+	for( ; i < N; ++i )
+	{
+		*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
+		r++;
+	}
+}
+
+
+inline void MTRand::reload()
+{
+	// Generate N new values in state
+	// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
+	register uint32 *p = state;
+	register int i;
+	for( i = N - M; i--; ++p )
+		*p = twist( p[M], p[0], p[1] );
+	for( i = M; --i; ++p )
+		*p = twist( p[M-N], p[0], p[1] );
+	*p = twist( p[M-N], p[0], state[0] );
+
+	left = N, pNext = state;
+}
+
+
+inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
+{
+	// Get a uint32 from t and c
+	// Better than uint32(x) in case x is floating point in [0,1]
+	// Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
+
+	static uint32 differ = 0;  // guarantee time-based seeds will change
+
+	uint32 h1 = 0;
+	unsigned char *p = (unsigned char *) &t;
+	for( size_t i = 0; i < sizeof(t); ++i )
+	{
+		h1 *= UCHAR_MAX + 2U;
+		h1 += p[i];
+	}
+	uint32 h2 = 0;
+	p = (unsigned char *) &c;
+	for( size_t j = 0; j < sizeof(c); ++j )
+	{
+		h2 *= UCHAR_MAX + 2U;
+		h2 += p[j];
+	}
+	return ( h1 + differ++ ) ^ h2;
+}
+
+
+inline void MTRand::save( uint32* saveArray ) const
+{
+	register uint32 *sa = saveArray;
+	register const uint32 *s = state;
+	register int i = N;
+	for( ; i--; *sa++ = *s++ ) {}
+	*sa = left;
+}
+
+
+inline void MTRand::load( uint32 *const loadArray )
+{
+	register uint32 *s = state;
+	register uint32 *la = loadArray;
+	register int i = N;
+	for( ; i--; *s++ = *la++ ) {}
+	left = *la;
+	pNext = &state[N-left];
+}
+
+/* Mangos not use streams for random values output
+inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
+{
+	register const MTRand::uint32 *s = mtrand.state;
+	register int i = mtrand.N;
+	for( ; i--; os << *s++ << "\t" ) {}
+	return os << mtrand.left;
+}
+
+
+inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
+{
+	register MTRand::uint32 *s = mtrand.state;
+	register int i = mtrand.N;
+	for( ; i--; is >> *s++ ) {}
+	is >> mtrand.left;
+	mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
+	return is;
+}
+*/
+
+#endif  // MERSENNETWISTER_H
+
+// Change log:
+//
+// v0.1 - First release on 15 May 2000
+//      - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
+//      - Translated from C to C++
+//      - Made completely ANSI compliant
+//      - Designed convenient interface for initialization, seeding, and
+//        obtaining numbers in default or user-defined ranges
+//      - Added automatic seeding from /dev/urandom or time() and clock()
+//      - Provided functions for saving and loading generator state
+//
+// v0.2 - Fixed bug which reloaded generator one step too late
+//
+// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
+//
+// v0.4 - Removed trailing newline in saved generator format to be consistent
+//        with output format of built-in types
+//
+// v0.5 - Improved portability by replacing static const int's with enum's and
+//        clarifying return values in seed(); suggested by Eric Heimburg
+//      - Removed MAXINT constant; use 0xffffffffUL instead
+//
+// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
+//      - Changed integer [0,n] generator to give better uniformity
+//
+// v0.7 - Fixed operator precedence ambiguity in reload()
+//      - Added access for real numbers in (0,1) and (0,n)
+//
+// v0.8 - Included time.h header to properly support time_t and clock_t
+//
+// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
+//      - Allowed for seeding with arrays of any length
+//      - Added access for real numbers in [0,1) with 53-bit resolution
+//      - Added access for real numbers from normal (Gaussian) distributions
+//      - Increased overall speed by optimizing twist()
+//      - Doubled speed of integer [0,n] generation
+//      - Fixed out-of-range number generation on 64-bit machines
+//      - Improved portability by substituting literal constants for long enum's
+//      - Changed license from GNU LGPL to BSD
diff --git a/dep/include/mysql/Libmysql.def b/dep/include/mysql/Libmysql.def
new file mode 100644
index 000000000..81f86dc87
--- /dev/null
+++ b/dep/include/mysql/Libmysql.def
@@ -0,0 +1,153 @@
+LIBRARY		LIBMYSQL
+VERSION		6.0
+EXPORTS
+	_dig_vec_lower
+	_dig_vec_upper
+	bmove_upp
+	delete_dynamic
+	free_defaults
+	getopt_compare_strings
+	getopt_ull_limit_value
+	handle_options
+	init_dynamic_array
+	insert_dynamic
+	int2str
+	is_prefix
+	list_add
+	list_delete
+	load_defaults
+	my_end
+	my_getopt_print_errors
+	my_init
+	my_malloc
+	my_memdup
+	my_no_flags_free
+	my_path
+	mysql_get_parameters
+	my_print_help
+	my_print_variables
+	my_realloc
+	my_strdup
+	mysql_thread_end
+	mysql_thread_init
+	myodbc_remove_escape
+	mysql_affected_rows
+	mysql_autocommit
+	mysql_stmt_bind_param
+	mysql_stmt_bind_result
+	mysql_change_user
+	mysql_character_set_name
+	mysql_close
+	mysql_commit
+	mysql_data_seek
+	mysql_debug
+	mysql_dump_debug_info
+	mysql_eof
+	mysql_errno
+	mysql_error
+	mysql_escape_string
+	mysql_hex_string
+	mysql_stmt_execute
+	mysql_stmt_fetch
+	mysql_stmt_fetch_column
+	mysql_fetch_field
+	mysql_fetch_field_direct
+	mysql_fetch_fields
+	mysql_fetch_lengths
+	mysql_fetch_row
+	mysql_field_count
+	mysql_field_seek
+	mysql_field_tell
+	mysql_free_result
+	mysql_get_client_info
+	mysql_get_host_info
+	mysql_get_proto_info
+	mysql_get_server_info
+	mysql_get_client_version
+	mysql_get_ssl_cipher
+	mysql_info
+	mysql_init
+	mysql_insert_id
+	mysql_kill
+	mysql_set_server_option
+	mysql_list_dbs
+	mysql_list_fields
+	mysql_list_processes
+	mysql_list_tables
+	mysql_more_results
+	mysql_next_result
+	mysql_num_fields
+	mysql_num_rows
+	mysql_options
+	mysql_stmt_param_count
+	mysql_stmt_param_metadata
+	mysql_ping
+	mysql_stmt_result_metadata
+	mysql_query
+	mysql_read_query_result
+	mysql_real_connect
+	mysql_real_escape_string
+	mysql_real_query
+	mysql_refresh
+	mysql_rollback
+	mysql_row_seek
+	mysql_row_tell
+	mysql_select_db
+	mysql_stmt_send_long_data
+	mysql_send_query
+	mysql_shutdown
+	mysql_ssl_set
+	mysql_stat
+	mysql_stmt_affected_rows
+	mysql_stmt_close
+	mysql_stmt_reset
+	mysql_stmt_data_seek
+	mysql_stmt_errno
+	mysql_stmt_error
+	mysql_stmt_free_result
+	mysql_stmt_num_rows
+	mysql_stmt_row_seek
+	mysql_stmt_row_tell
+	mysql_stmt_store_result
+	mysql_store_result
+	mysql_thread_id
+	mysql_thread_safe
+	mysql_use_result
+	mysql_warning_count
+	mysql_stmt_sqlstate
+	mysql_sqlstate
+	mysql_get_server_version
+	set_dynamic
+	strcend
+	strcont
+	strdup_root
+	strfill
+	strinstr
+	strmake
+	strmov
+	strxmov
+	mysql_stmt_prepare
+	mysql_stmt_init
+	mysql_stmt_insert_id
+	mysql_stmt_attr_get
+	mysql_stmt_attr_set
+	mysql_stmt_field_count
+	client_errors
+	mysql_set_local_infile_default
+	mysql_set_local_infile_handler
+	mysql_disable_reads_from_master
+	mysql_disable_rpl_parse
+	mysql_enable_reads_from_master
+	mysql_enable_rpl_parse
+	mysql_master_query
+	mysql_rpl_parse_enabled
+	mysql_rpl_probe
+	mysql_rpl_query_type
+	mysql_slave_query
+	mysql_embedded
+	mysql_server_init
+	mysql_server_end
+	mysql_set_character_set
+	mysql_get_character_set_info
+	get_defaults_options
+	modify_defaults_file
diff --git a/dep/include/mysql/config-netware.h b/dep/include/mysql/config-netware.h
new file mode 100644
index 000000000..9c9930578
--- /dev/null
+++ b/dep/include/mysql/config-netware.h
@@ -0,0 +1,141 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Header for NetWare compatible with MySQL */
+
+#ifndef _config_netware_h
+#define _config_netware_h
+
+/* required headers */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* required adjustments */
+#undef HAVE_READDIR_R
+#undef HAVE_RWLOCK_INIT
+#undef HAVE_SCHED_H
+#undef HAVE_SYS_MMAN_H
+#undef HAVE_SYNCH_H
+#undef HAVE_MMAP
+#undef HAVE_RINT
+
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+#define HAVE_PTHREAD_SIGMASK 1
+#define HAVE_PTHREAD_YIELD_ZERO_ARG 1
+#define HAVE_BROKEN_REALPATH 1
+
+/* changes made to make use of LibC-June-2004 for building purpose */
+#undef HAVE_POSIX_SIGNALS
+#undef HAVE_PTHREAD_ATTR_SETSCOPE
+#undef HAVE_ALLOC_A
+#undef HAVE_FINITE
+#undef HAVE_GETPWNAM
+#undef HAVE_GETPWUID
+#undef HAVE_PTHREAD_SETSCHEDPARAM
+#undef HAVE_READLINK
+#undef HAVE_STPCPY
+/* changes  end  */
+
+/* no libc crypt() function */
+#ifdef HAVE_OPENSSL
+  #define HAVE_CRYPT 1
+#else
+  #undef HAVE_CRYPT
+#endif /* HAVE_OPENSSL */
+
+/* Netware has an ancient zlib */
+#undef HAVE_COMPRESS
+#define HAVE_COMPRESS
+#undef HAVE_ARCHIVE_DB
+
+/* include the old function apis */
+#define USE_OLD_FUNCTIONS 1
+
+/* no case sensitivity */
+#define FN_NO_CASE_SENCE 1
+
+/* the thread alarm is not used */
+#define DONT_USE_THR_ALARM 1
+
+/* signals do not interrupt sockets */
+#define SIGNALS_DONT_BREAK_READ 1
+
+/* signal by closing the sockets */
+#define SIGNAL_WITH_VIO_CLOSE 1
+
+/* On NetWare, stack grows towards lower address*/
+#define STACK_DIRECTION -1
+
+/* On NetWare, we need to set stack size for threads, otherwise default 16K is used */
+#define NW_THD_STACKSIZE 65536
+
+/* On NetWare, to fix the problem with the deletion of open files */
+#define CANT_DELETE_OPEN_FILES 1
+
+#define FN_LIBCHAR '\\'
+#define FN_ROOTDIR "\\"
+#define FN_DEVCHAR ':'
+
+/* default directory information */
+#define	DEFAULT_MYSQL_HOME    "sys:/mysql"
+#define PACKAGE               "mysql"
+#define DEFAULT_BASEDIR       "sys:/"
+#define SHAREDIR              "share/"
+#define DEFAULT_CHARSET_HOME  "sys:/mysql/"
+#define DATADIR               "data/"
+
+/* 64-bit file system calls */
+#define SIZEOF_OFF_T          8
+#define off_t                 off64_t
+#define chsize                chsize64
+#define ftruncate             ftruncate64
+#define lseek                 lseek64
+#define pread                 pread64
+#define pwrite                pwrite64
+#define tell                  tell64
+
+/* do not use the extended time in LibC sys\stat.h */
+#define _POSIX_SOURCE
+
+/* Some macros for portability */
+
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=time(NULL)+(SEC); (ABSTIME).tv_nsec=0; }
+
+/* extra protection against CPU Hogs on NetWare */
+#define NETWARE_YIELD pthread_yield()
+/* Screen mode for help texts */
+#define NETWARE_SET_SCREEN_MODE(A) setscreenmode(A)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _config_netware_h */
diff --git a/dep/include/mysql/config-os2.h b/dep/include/mysql/config-os2.h
new file mode 100644
index 000000000..8e2d0e2e8
--- /dev/null
+++ b/dep/include/mysql/config-os2.h
@@ -0,0 +1,835 @@
+/* Copyright (C) 2000 MySQL AB & Yuri Dario
+   All the above parties has a full, independent copyright to
+   the following code, including the right to use the code in
+   any manner without any demands from the other parties.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; version 2
+   of the License.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA */
+
+/* Defines for OS2 to make it compatible for MySQL */
+
+#ifndef __CONFIG_OS2_H__
+#define __CONFIG_OS2_H__
+
+#include 
+#include 
+#include 
+#include 
+
+/* Define to name of system eg solaris*/
+#define SYSTEM_TYPE "IBM OS/2 Warp"
+/* Define to machine type name eg sun10 */
+#define MACHINE_TYPE "i686"
+/* Name of package */
+#define PACKAGE "mysql"
+/* Version number of package */
+#define VERSION MYSQL_SERVER_VERSION
+/* Default socket */
+#define MYSQL_UNIX_ADDR "\\socket\\MySQL"
+
+#define FN_LIBCHAR		 '\\'
+#define FN_ROOTDIR		 "\\"
+#define MY_NFILE		1024  /* This is only used to save filenames */
+
+#define HAVE_ACCESS
+
+#define DEFAULT_MYSQL_HOME	"c:\\mysql"
+#define DEFAULT_BASEDIR		"C:\\"
+#define SHAREDIR		"share"
+#define DEFAULT_CHARSET_HOME	"C:/mysql/"
+#define _POSIX_PATH_MAX		255
+#define DWORD			ULONG
+
+#define O_SHARE		0x1000		/* Open file in sharing mode */
+#define FILE_BINARY	O_BINARY	/* my_fopen in binary mode */
+#define S_IROTH		S_IREAD		/* for my_lib */
+
+#define CANT_DELETE_OPEN_FILES		/* saves open files in a list, for delayed delete */
+
+#define O_NONBLOCK	0x10
+
+#define NO_OPEN_3			/* For my_create() */
+#define SIGQUIT		SIGTERM		/* No SIGQUIT */
+#define SIGALRM		14		/* Alarm */
+
+#define NO_FCNTL_NONBLOCK
+
+#define EFBIG			   E2BIG
+/*#define ENFILE		  EMFILE    */
+/*#define ENAMETOOLONG		(EOS2ERR+2) */
+/*#define ETIMEDOUT		  145       */
+/*#define EPIPE			  146       */
+#define EROFS			147
+
+#define sleep(A)	DosSleep((A)*1000)
+#define closesocket(A)	soclose(A)
+
+#define F_OK		0
+#define W_OK		2
+
+#define bzero(x,y)	memset((x),'\0',(y))
+#define bcopy(x,y,z)	memcpy((y),(x),(z))
+#define bcmp(x,y,z)	memcmp((y),(x),(z))
+
+#define F_RDLCK		4	    /* Read lock.  */
+#define F_WRLCK		2	    /* Write lock.  */
+#define F_UNLCK		0	    /* Remove lock.  */
+
+#define S_IFMT		0x17000	    /* Mask for file type */
+#define F_TO_EOF	0L	    /* Param to lockf() to lock rest of file */
+
+#define HUGE_PTR
+
+#ifdef __cplusplus
+extern "C"
+#endif
+double _cdecl rint( double nr);
+
+DWORD	 TlsAlloc( void);
+BOOL	 TlsFree( DWORD);
+PVOID	 TlsGetValue( DWORD);
+BOOL	 TlsSetValue( DWORD, PVOID);
+
+/* support for > 2GB file size */
+#define SIZEOF_OFF_T	8
+#define lseek(A,B,C)	_lseek64( A, B, C)
+#define tell(A)		_lseek64( A, 0, SEEK_CUR)
+
+void* dlopen( char* path, int flag);
+char* dlerror( void);
+void* dlsym( void* hmod, char* fn);
+void  dlclose( void* hmod);
+
+/* Some typedefs */
+typedef unsigned long long os_off_t;
+
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro.  */
+#define HAVE_ALLOCA 1
+
+/* Define if you have  and it should be used (not on Ultrix).  */
+/* #define HAVE_ALLOCA_H 1 */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have a working `mmap' system call.  */
+/* #undef HAVE_MMAP */
+
+/* Define if system calls automatically restart after interruption
+   by a signal.  */
+/* #undef HAVE_RESTARTABLE_SYSCALLS */
+
+/* Define if your struct stat has st_rdev.  */
+#define HAVE_ST_RDEV 1
+
+/* Define if you have  that is POSIX.1 compatible.	*/
+/* #define HAVE_SYS_WAIT_H 1 */
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#define HAVE_TZNAME 1
+
+/* Define if utime(file, NULL) sets file's timestamp to the present.  */
+#define HAVE_UTIME_NULL 1
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define as __inline if that's what the C compiler calls it.  */
+/* #undef inline */
+
+/* Define to `long' if  doesn't define.  */
+/* #undef off_t */
+
+/* Define as the return type of signal handlers (int or void).	*/
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if  doesn't define.  */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#define STACK_DIRECTION -1
+
+/* Define if the `S_IS*' macros in  do not work properly.  */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define if you have the ANSI C header files.	*/
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both  and .  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your  declares struct tm.  */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).	*/
+/* #undef WORDS_BIGENDIAN */
+
+/* Version of .frm files */
+#define DOT_FRM_VERSION 6
+
+/* READLINE: */
+#define FIONREAD_IN_SYS_IOCTL 1
+
+/* READLINE: Define if your system defines TIOCGWINSZ in sys/ioctl.h.  */
+/* #undef GWINSZ_IN_SYS_IOCTL */
+
+/* Do we have FIONREAD */
+#define FIONREAD_IN_SYS_IOCTL 1
+
+/* atomic_add() from  (Linux only) */
+/* #undef HAVE_ATOMIC_ADD */
+
+/* atomic_sub() from  (Linux only) */
+/* #undef HAVE_ATOMIC_SUB */
+
+/* bool is not defined by all C++ compilators */
+#define HAVE_BOOL 1
+
+/* Have berkeley db installed */
+/* #define HAVE_BERKELEY_DB 1 */
+
+/* DSB style signals ? */
+/* #undef HAVE_BSD_SIGNALS */
+
+/* Can netinet be included */
+/* #undef HAVE_BROKEN_NETINET_INCLUDES */
+
+/* READLINE: */
+/* #undef HAVE_BSD_SIGNALS */
+
+/* ZLIB and compress: */
+#define HAVE_COMPRESS 1
+
+/* Define if we are using OSF1 DEC threads */
+/* #undef HAVE_DEC_THREADS */
+
+/* Define if we are using OSF1 DEC threads on 3.2 */
+/* #undef HAVE_DEC_3_2_THREADS */
+
+/* fp_except from ieeefp.h */
+/* #undef HAVE_FP_EXCEPT */
+
+/* READLINE: */
+/* #undef HAVE_GETPW_DECLS */
+
+/* Solaris define gethostbyname_r with 5 arguments. glibc2 defines
+   this with 6 arguments */
+/* #undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE */
+
+/* In OSF 4.0f the 3'd argument to gethostname_r is hostent_data * */
+/* #undef HAVE_GETHOSTBYNAME_R_RETURN_INT */
+
+/* Define if int8, int16 and int32 types exist */
+/* #undef HAVE_INT_8_16_32 */
+
+/* Define if have -lwrap */
+/* #undef HAVE_LIBWRAP */
+
+/* Define if we are using Xavier Leroy's LinuxThreads */
+/* #undef HAVE_LINUXTHREADS */
+
+/* Do we use user level threads */
+/* #undef HAVE_mit_thread */
+
+/* For some non posix threads */
+/* #undef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC */
+
+/* For some non posix threads */
+/* #undef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */
+
+/* READLINE: */
+#define HAVE_POSIX_SIGNALS 0
+
+/* sigwait with one argument */
+/* #undef HAVE_NONPOSIX_SIGWAIT */
+
+/* pthread_attr_setscope */
+#define HAVE_PTHREAD_ATTR_SETSCOPE 1
+
+/* POSIX readdir_r */
+/* #undef HAVE_READDIR_R */
+
+/* POSIX sigwait */
+/* #undef HAVE_SIGWAIT */
+
+/* crypt */
+#define HAVE_CRYPT 1
+
+/* Solaris define gethostbyaddr_r with 7 arguments. glibc2 defines
+   this with 8 arguments */
+/* #undef HAVE_SOLARIS_STYLE_GETHOST */
+
+/* Timespec has a ts_sec instead of tv_sev  */
+#define HAVE_TIMESPEC_TS_SEC 1
+
+/* Have the tzname variable */
+#define HAVE_TZNAME 1
+
+/* Define if the system files define uchar */
+/* #undef HAVE_UCHAR */
+
+/* Define if the system files define uint */
+/* #undef HAVE_UINT */
+
+/* Define if the system files define ulong */
+/* #undef HAVE_ULONG */
+
+/* UNIXWARE7 threads are not posix */
+/* #undef HAVE_UNIXWARE7_THREADS */
+
+/* new UNIXWARE7 threads that are not yet posix */
+/* #undef HAVE_UNIXWARE7_POSIX */
+
+/* READLINE: */
+/* #undef HAVE_USG_SIGHOLD */
+
+/* Define if want -lwrap */
+/* #undef LIBWRAP */
+
+/* mysql client protocoll version */
+#define PROTOCOL_VERSION 10
+
+/* Define if qsort returns void */
+#define QSORT_TYPE_IS_VOID 1
+
+/* Define as the return type of qsort (int or void). */
+#define RETQSORTTYPE void
+
+/* Define as the base type of the last arg to accept */
+#define SOCKET_SIZE_TYPE int
+
+/* Last argument to get/setsockopt */
+/* #undef SOCKOPT_OPTLEN_TYPE */
+
+/* #undef SPEED_T_IN_SYS_TYPES */
+/* #undef SPRINTF_RETURNS_PTR */
+#define SPRINTF_RETURNS_INT 1
+/* #undef SPRINTF_RETURNS_GARBAGE */
+
+/* #undef STRUCT_DIRENT_HAS_D_FILENO */
+#define STRUCT_DIRENT_HAS_D_INO 1
+
+/* Define if you want to have threaded code. This may be undef on client code */
+#define THREAD 1
+
+/* Should be client be thread safe */
+/* #undef THREAD_SAFE_CLIENT */
+
+/* READLINE: */
+/* #undef TIOCSTAT_IN_SYS_IOCTL */
+
+/* Use multi-byte character routines */
+/* #undef USE_MB */
+/* #undef USE_MB_IDENT */
+
+/* Use MySQL RAID */
+/* #undef USE_RAID */
+
+/* Use strcoll() functions when comparing and sorting. */
+/* #undef USE_STRCOLL */
+
+/* READLINE: */
+#define VOID_SIGHANDLER 1
+
+/* The number of bytes in a char.  */
+#define SIZEOF_CHAR 1
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long.	*/
+#define SIZEOF_LONG_LONG 8
+
+/* Define if you have the alarm function.  */
+#define HAVE_ALARM 1
+
+/* Define if you have the atod function.  */
+/* #undef HAVE_ATOD */
+
+/* Define if you have the bcmp function.  */
+#define HAVE_BCMP 1
+
+/* Define if you have the bfill function.  */
+/* #undef HAVE_BFILL */
+
+/* Define if you have the bmove function.  */
+/* #undef HAVE_BMOVE */
+
+/* Define if you have the bzero function.  */
+#define HAVE_BZERO 1
+
+/* Define if you have the chsize function.  */
+#define HAVE_CHSIZE 1
+
+/* Define if you have the cuserid function.  */
+/* #define HAVE_CUSERID 1 */
+
+/* Define if you have the dlerror function.  */
+#define HAVE_DLERROR 1
+
+/* Define if you have the dlopen function.  */
+#define HAVE_DLOPEN 1
+
+/* Define if you have the fchmod function.  */
+/* #undef HAVE_FCHMOD */
+
+/* Define if you have the fcntl function.  */
+/* #define HAVE_FCNTL 1 */
+
+/* Define if you have the fconvert function.  */
+/* #undef HAVE_FCONVERT */
+
+/* Define if you have the finite function.  */
+/* #undef HAVE_FINITE */
+
+/* Define if you have the fpresetsticky function.  */
+/* #undef HAVE_FPRESETSTICKY */
+
+/* Define if you have the fpsetmask function.  */
+/* #undef HAVE_FPSETMASK */
+
+/* Define if you have the fseeko function.  */
+/* #undef HAVE_FSEEKO */
+
+/* Define if you have the ftruncate function.  */
+/* #define HAVE_FTRUNCATE 1 */
+
+/* Define if you have the getcwd function.  */
+#define HAVE_GETCWD 1
+
+/* Define if you have the gethostbyaddr_r function.  */
+/* #undef HAVE_GETHOSTBYADDR_R */
+
+/* Define if you have the gethostbyname_r function.  */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* Define if you have the getpagesize function.  */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the getpass function.  */
+/*#define HAVE_GETPASS 1 */
+
+/* Define if you have the getpassphrase function.  */
+/* #undef HAVE_GETPASSPHRASE */
+
+/* Define if you have the getpwnam function.  */
+/* #define HAVE_GETPWNAM 1 */
+
+/* Define if you have the getpwuid function.  */
+/* #define HAVE_GETPWUID 1 */
+
+/* Define if you have the getrlimit function.  */
+/* #undef HAVE_GETRLIMIT */
+
+/* Define if you have the getrusage function.  */
+/* #undef HAVE_GETRUSAGE */
+
+/* Define if you have the getwd function.  */
+#define HAVE_GETWD 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* Define if you have the index function.  */
+#define HAVE_INDEX 1
+
+/* Define if you have the initgroups function.	*/
+/* #undef HAVE_INITGROUPS */
+
+/* Define if you have the localtime_r function.  */
+#define HAVE_LOCALTIME_R 1
+
+/* Define if you have the locking function.  */
+/* #undef HAVE_LOCKING */
+
+/* Define if you have the longjmp function.  */
+#define HAVE_LONGJMP 1
+
+/* Define if you have the lrand48 function.  */
+/* #undef HAVE_LRAND48 */
+
+/* Define if you have the lstat function.  */
+/* #undef HAVE_LSTAT */
+
+/* Define if you have the madvise function.  */
+/* #undef HAVE_MADVISE */
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the mkstemp function.  */
+/* #define HAVE_MKSTEMP 1 */
+
+/* Define if you have the mlockall function.  */
+/* #undef HAVE_MLOCKALL */
+
+/* Define if you have the perror function.  */
+#define HAVE_PERROR 1
+
+/* Define if you have the poll function.  */
+/* #undef HAVE_POLL */
+
+/* Define if you have the pread function.  */
+/* #undef HAVE_PREAD */
+
+/* Define if you have the pthread_attr_create function.  */
+/* #undef HAVE_PTHREAD_ATTR_CREATE */
+
+/* Define if you have the pthread_attr_setprio function.  */
+#define HAVE_PTHREAD_ATTR_SETPRIO 1
+
+/* Define if you have the pthread_attr_setschedparam function.	*/
+/* #undef HAVE_PTHREAD_ATTR_SETSCHEDPARAM */
+
+/* Define if you have the pthread_attr_setstacksize function.  */
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+
+/* Define if you have the pthread_condattr_create function.  */
+/* #undef HAVE_PTHREAD_CONDATTR_CREATE */
+
+/* Define if you have the pthread_getsequence_np function.  */
+/* #undef HAVE_PTHREAD_GETSEQUENCE_NP */
+
+/* Define if you have the pthread_init function.  */
+/* #undef HAVE_PTHREAD_INIT */
+
+/* Define if you have the pthread_rwlock_rdlock function.  */
+/* #undef HAVE_PTHREAD_RWLOCK_RDLOCK */
+
+/* Define if you have the pthread_setprio function.  */
+#define HAVE_PTHREAD_SETPRIO 1
+
+/* Define if you have the pthread_setprio_np function.	*/
+/* #undef HAVE_PTHREAD_SETPRIO_NP */
+
+/* Define if you have the pthread_setschedparam function.  */
+/* #undef HAVE_PTHREAD_SETSCHEDPARAM */
+
+/* Define if you have the pthread_sigmask function.  */
+#define HAVE_PTHREAD_SIGMASK 1
+
+/* Define if you have the putenv function.  */
+#define HAVE_PUTENV 1
+
+/* Define if you have the readlink function.  */
+/* #undef HAVE_READLINK */
+
+/* Define if you have the realpath function.  */
+/* #undef HAVE_REALPATH */
+
+/* Define if you have the rename function.  */
+#define HAVE_RENAME 1
+
+/* Define if you have the rint function.  */
+#define HAVE_RINT 1
+
+/* Define if you have the rwlock_init function.  */
+/* #undef HAVE_RWLOCK_INIT */
+
+/* Define if you have the select function.  */
+#define HAVE_SELECT 1
+
+/* Define if you have the setenv function.  */
+/* #undef HAVE_SETENV */
+
+/* Define if you have the setlocale function.  */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setupterm function.  */
+/* #undef HAVE_SETUPTERM */
+
+/* Define if you have the sighold function.  */
+/* #undef HAVE_SIGHOLD */
+
+/* Define if you have the sigset function.  */
+/* #undef HAVE_SIGSET */
+
+/* Define if you have the sigthreadmask function.  */
+/* #undef HAVE_SIGTHREADMASK */
+
+/* Define if you have the snprintf function.  */
+/* #define HAVE_SNPRINTF 1 */
+
+/* Define if you have the socket function.  */
+#define HAVE_SOCKET 1
+
+/* Define if you have the stpcpy function.  */
+/* #undef HAVE_STPCPY */
+
+/* Define if you have the strcasecmp function.	*/
+/* #undef HAVE_STRCASECMP */
+
+/* Define if you have the strcoll function.  */
+#define HAVE_STRCOLL 1
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strnlen function.  */
+/* #undef HAVE_STRNLEN */
+
+/* Define if you have the strpbrk function.  */
+#define HAVE_STRPBRK 1
+
+/* Define if you have the strstr function.  */
+#define HAVE_STRSTR 1
+
+/* Define if you have the strtok_r function.  */
+/* #undef HAVE_STRTOK_R */
+
+/* Define if you have the strtol function.  */
+#define HAVE_STRTOL 1
+
+/* Define if you have the strtoul function.  */
+#define HAVE_STRTOUL 1
+
+/* Define if you have the strtoull function.  */
+/* #undef HAVE_STRTOULL */
+
+/* Define if you have the tcgetattr function.  */
+#define HAVE_TCGETATTR 1
+
+/* Define if you have the tell function.  */
+#define HAVE_TELL 1
+
+/* Define if you have the tempnam function.  */
+#define HAVE_TEMPNAM 1
+
+/* Define if you have the thr_setconcurrency function.	*/
+/* #undef HAVE_THR_SETCONCURRENCY */
+
+/* Define if you have the vidattr function.  */
+/* #undef HAVE_VIDATTR */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_ALLOCA_H 1 */
+
+/* Define if you have the  header file.  */
+#define HAVE_ARPA_INET_H 1
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_ASM_TERMBITS_H */
+
+/* Define if you have the  header file.  */
+#define HAVE_CRYPT_H 1
+
+/* Define if you have the  header file.  */
+/* #define HAVE_CURSES_H 1 */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_DIRENT_H 1 */
+
+/* Define if you have the  header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_FLOAT_H 1
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_FLOATINGPOINT_H */
+
+/* Define if you have the  header file.	*/
+/* #define HAVE_GRP_H 1 */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_IEEEFP_H */
+
+/* Define if you have the  header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the  header file.  */
+#define HAVE_NETINET_IN_H 1
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_PATHS_H */
+
+/* Define if you have the  header file.	*/
+/* #define HAVE_PWD_H 1 */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SCHED_H */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SELECT_H */
+
+/* Define if you have the  header file.  */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_STDDEF_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the  header file.  */
+/* #define HAVE_STRINGS_H 1 */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SYNCH_H */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_SYS_DIR_H 1 */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_SYS_FILE_H 1 */
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SYS_MMAN_H */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SYS_PTE_H */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SYS_PTEM_H */
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_SYS_STREAM_H */
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_UN_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_SYS_UTIME_H 1
+
+/* Define if you have the  header file.	*/
+/* #undef HAVE_SYS_VADVISE_H */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_SYS_WAIT_H 1 */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_TERM_H */
+
+/* Define if you have the  header file.  */
+/* #undef HAVE_TERMBITS_H */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_TERMCAP_H 1 */
+
+/* Define if you have the  header file.  */
+/* /#define HAVE_TERMIO_H 1 */
+
+/* Define if you have the  header file.  */
+/* #define HAVE_TERMIOS_H 1 */
+
+/* Define if you have the  header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_UTIME_H 1
+
+/* Define if you have the  header file.  */
+#define HAVE_VARARGS_H 1
+
+/* Define if you have the bind library (-lbind).  */
+/* #undef HAVE_LIBBIND */
+
+/* Define if you have the c_r library (-lc_r).	*/
+/* #undef HAVE_LIBC_R */
+
+/* Define if you have the compat library (-lcompat).  */
+/* #undef HAVE_LIBCOMPAT */
+
+/* Define if you have the crypt library (-lcrypt).  */
+#define HAVE_LIBCRYPT 1
+
+/* Define if you have the dl library (-ldl).  */
+#define HAVE_LIBDL 1
+
+/* Define if you have the gen library (-lgen).	*/
+/* #undef HAVE_LIBGEN */
+
+/* Define if you have the m library (-lm).  */
+#define HAVE_LIBM 1
+
+/* Define if you have the nsl library (-lnsl).	*/
+/* #undef HAVE_LIBNSL */
+
+/* Define if you have the nsl_r library (-lnsl_r).  */
+/* #undef HAVE_LIBNSL_R */
+
+/* Define if you have the pthread library (-lpthread).	*/
+/* #undef HAVE_LIBPTHREAD */
+
+/* Define if you have the socket library (-lsocket).  */
+/* #undef HAVE_LIBSOCKET */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define to make fseeko etc. visible, on some hosts. */
+/* #undef _LARGEFILE_SOURCE */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+#endif /* __CONFIG_OS2_H__ */
diff --git a/dep/include/mysql/config-win.h b/dep/include/mysql/config-win.h
new file mode 100644
index 000000000..45bfeb5ba
--- /dev/null
+++ b/dep/include/mysql/config-win.h
@@ -0,0 +1,460 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Defines for Win32 to make it compatible for MySQL */
+
+#ifdef __WIN2000__
+/* We have to do this define before including windows.h to get the AWE API
+functions */
+#define _WIN32_WINNT     0x0500
+#else
+/* Get NT 4.0 functions */
+#define _WIN32_WINNT     0x0400
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+/* Avoid endless warnings about sprintf() etc. being unsafe. */
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+#include 
+#include 
+#include 			/* Because of rint() */
+#include 
+#include 
+#include 
+
+#define BIG_TABLES 1
+#define HAVE_SMEM 1
+
+#if defined(_WIN64) || defined(WIN64) 
+#define SYSTEM_TYPE	"Win64" 
+#elif defined(_WIN32) || defined(WIN32) 
+#define SYSTEM_TYPE	"Win32" 
+#else
+#define SYSTEM_TYPE	"Windows"
+#endif
+
+#if defined(_M_IA64) 
+#define MACHINE_TYPE	"ia64" 
+#elif defined(_M_IX86) 
+#define MACHINE_TYPE	"ia32" 
+#elif defined(_M_ALPHA) 
+#define MACHINE_TYPE	"axp" 
+#else
+#define MACHINE_TYPE	"unknown"	/* Define to machine type name */
+#endif 
+ 
+#if !(defined(_WIN64) || defined(WIN64)) 
+#ifndef _WIN32
+#define _WIN32				/* Compatible with old source */
+#endif
+#ifndef __WIN32__
+#define __WIN32__
+#endif
+#endif /* _WIN64 */
+#ifndef __WIN__
+#define __WIN__			      /* To make it easier in VC++ */
+#endif
+
+#ifndef MAX_INDEXES
+#define MAX_INDEXES 64
+#endif
+
+/* File and lock constants */
+#define O_SHARE		0x1000		/* Open file in sharing mode */
+#ifdef __BORLANDC__
+#define F_RDLCK		LK_NBLCK	/* read lock */
+#define F_WRLCK		LK_NBRLCK	/* write lock */
+#define F_UNLCK		LK_UNLCK	/* remove lock(s) */
+#else
+#define F_RDLCK		_LK_NBLCK	/* read lock */
+#define F_WRLCK		_LK_NBRLCK	/* write lock */
+#define F_UNLCK		_LK_UNLCK	/* remove lock(s) */
+#endif
+
+#define F_EXCLUSIVE	1		/* We have only exclusive locking */
+#define F_TO_EOF	(INT_MAX32/2)	/* size for lock of all file */
+#define F_OK		0		/* parameter to access() */
+#define W_OK		2
+
+#define S_IROTH		S_IREAD		/* for my_lib */
+
+#ifdef __BORLANDC__
+#define FILE_BINARY	O_BINARY	/* my_fopen in binary mode */
+#define O_TEMPORARY	0
+#define O_SHORT_LIVED	0
+#define SH_DENYNO	_SH_DENYNO
+#else
+#define O_BINARY	_O_BINARY	/* compability with MSDOS */
+#define FILE_BINARY	_O_BINARY	/* my_fopen in binary mode */
+#define O_TEMPORARY	_O_TEMPORARY
+#define O_SHORT_LIVED	_O_SHORT_LIVED
+#define SH_DENYNO	_SH_DENYNO
+#endif
+#define NO_OPEN_3			/* For my_create() */
+
+#define SIGQUIT		SIGTERM		/* No SIGQUIT */
+
+#undef _REENTRANT			/* Crashes something for win32 */
+#undef SAFE_MUTEX			/* Can't be used on windows */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310
+#define LL(A)           A##ll
+#define ULL(A)          A##ull
+#else
+#define LL(A)           ((__int64) A)
+#define ULL(A)          ((unsigned __int64) A)
+#endif
+
+#define LONGLONG_MIN	LL(0x8000000000000000)
+#define LONGLONG_MAX	LL(0x7FFFFFFFFFFFFFFF)
+#define ULONGLONG_MAX	ULL(0xFFFFFFFFFFFFFFFF)
+
+/* Type information */
+
+#if defined(__EMX__) || !defined(HAVE_UINT)
+#undef HAVE_UINT
+#define HAVE_UINT
+typedef unsigned short	ushort;
+typedef unsigned int	uint;
+#endif /* defined(__EMX__) || !defined(HAVE_UINT) */
+
+typedef unsigned __int64 ulonglong;	/* Microsofts 64 bit types */
+typedef __int64 longlong;
+#ifndef HAVE_SIGSET_T
+typedef int sigset_t;
+#endif
+#define longlong_defined
+/*
+  off_t should not be __int64 because of conflicts in header files;
+  Use my_off_t or os_off_t instead
+*/
+#ifndef HAVE_OFF_T
+typedef long off_t;
+#endif
+typedef __int64 os_off_t;
+#ifdef _WIN64
+typedef UINT_PTR rf_SetTimer;
+#else
+#ifndef HAVE_SIZE_T
+typedef unsigned int size_t;
+#endif
+typedef uint rf_SetTimer;
+#endif
+
+#define Socket_defined
+#define my_socket SOCKET
+#define bool BOOL
+#define SIGPIPE SIGINT
+#define RETQSORTTYPE void
+#define QSORT_TYPE_IS_VOID
+#define RETSIGTYPE void
+#define SOCKET_SIZE_TYPE int
+#define my_socket_defined
+#define bool_defined
+#define byte_defined
+#define HUGE_PTR
+#define STDCALL __stdcall	    /* Used by libmysql.dll */
+#define isnan(X) _isnan(X)
+#define finite(X) _finite(X)
+
+#ifndef UNDEF_THREAD_HACK
+#define THREAD
+#endif
+#define VOID_SIGHANDLER
+#define SIZEOF_CHAR		1
+#define SIZEOF_LONG		4
+#define SIZEOF_LONG_LONG	8
+#define SIZEOF_OFF_T		8
+#ifdef _WIN64
+#define SIZEOF_CHARP		8
+#else
+#define SIZEOF_CHARP		4
+#endif
+#define HAVE_BROKEN_NETINET_INCLUDES
+#ifdef __NT__
+#define HAVE_NAMED_PIPE			/* We can only create pipes on NT */
+#endif
+
+/* ERROR is defined in wingdi.h */
+#undef ERROR
+
+/* We need to close files to break connections on shutdown */
+#ifndef SIGNAL_WITH_VIO_CLOSE
+#define SIGNAL_WITH_VIO_CLOSE
+#endif
+
+/* Use all character sets in MySQL */
+#define USE_MB 1
+#define USE_MB_IDENT 1
+#define USE_STRCOLL 1
+
+/* All windows servers should support .sym files */
+#undef USE_SYMDIR
+#define USE_SYMDIR
+
+/* If LOAD DATA LOCAL INFILE should be enabled by default */
+#define ENABLED_LOCAL_INFILE 1
+
+/* Convert some simple functions to Posix */
+
+#define my_sigset(A,B) signal((A),(B))
+#define finite(A) _finite(A)
+#define sleep(A)  Sleep((A)*1000)
+#define popen(A,B) _popen((A),(B))
+#define pclose(A) _pclose(A)
+
+#ifndef __BORLANDC__
+#define access(A,B) _access(A,B)
+#endif
+
+#if !defined(__cplusplus)
+#define inline __inline
+#endif /* __cplusplus */
+
+inline double rint(double nr)
+{
+  double f = floor(nr);
+  double c = ceil(nr);
+  return (((c-nr) >= (nr-f)) ? f :c);
+}
+
+#ifdef _WIN64
+#define ulonglong2double(A) ((double) (ulonglong) (A))
+#define my_off_t2double(A)  ((double) (my_off_t) (A))
+
+#else
+inline double ulonglong2double(ulonglong value)
+{
+  longlong nr=(longlong) value;
+  if (nr >= 0)
+    return (double) nr;
+  return (18446744073709551616.0 + (double) nr);
+}
+#define my_off_t2double(A) ulonglong2double(A)
+#endif /* _WIN64 */
+
+#if SIZEOF_OFF_T > 4
+#define lseek(A,B,C) _lseeki64((A),(longlong) (B),(C))
+#define tell(A) _telli64(A)
+#endif
+
+
+#define STACK_DIRECTION -1
+
+/* Optimized store functions for Intel x86 */
+
+#ifndef _WIN64
+#define sint2korr(A)	(*((int16 *) (A)))
+#define sint3korr(A)	((int32) ((((uchar) (A)[2]) & 128) ? \
+				  (((uint32) 255L << 24) | \
+				   (((uint32) (uchar) (A)[2]) << 16) |\
+				   (((uint32) (uchar) (A)[1]) << 8) | \
+				   ((uint32) (uchar) (A)[0])) : \
+				  (((uint32) (uchar) (A)[2]) << 16) |\
+				  (((uint32) (uchar) (A)[1]) << 8) | \
+				  ((uint32) (uchar) (A)[0])))
+#define sint4korr(A)	(*((long *) (A)))
+#define uint2korr(A)	(*((uint16 *) (A)))
+/*
+   ATTENTION !
+   
+    Please, note, uint3korr reads 4 bytes (not 3) !
+    It means, that you have to provide enough allocated space !
+*/
+#define uint3korr(A)	(long) (*((unsigned int *) (A)) & 0xFFFFFF)
+#define uint4korr(A)	(*((unsigned long *) (A)))
+#define uint5korr(A)	((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+				    (((uint32) ((uchar) (A)[1])) << 8) +\
+				    (((uint32) ((uchar) (A)[2])) << 16) +\
+				    (((uint32) ((uchar) (A)[3])) << 24)) +\
+				    (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A)	(*((ulonglong *) (A)))
+#define sint8korr(A)	(*((longlong *) (A)))
+#define int2store(T,A)	*((uint16*) (T))= (uint16) (A)
+#define int3store(T,A)		{ *(T)=  (uchar) ((A));\
+				  *(T+1)=(uchar) (((uint) (A) >> 8));\
+				  *(T+2)=(uchar) (((A) >> 16)); }
+#define int4store(T,A)	*((long *) (T))= (long) (A)
+#define int5store(T,A)	{ *(T)= (uchar)((A));\
+			  *((T)+1)=(uchar) (((A) >> 8));\
+			  *((T)+2)=(uchar) (((A) >> 16));\
+			  *((T)+3)=(uchar) (((A) >> 24)); \
+			  *((T)+4)=(uchar) (((A) >> 32)); }
+#define int8store(T,A)	*((ulonglong *) (T))= (ulonglong) (A)
+
+#define doubleget(V,M)	do { *((long *) &V) = *((long*) M); \
+			    *(((long *) &V)+1) = *(((long*) M)+1); } while(0)
+#define doublestore(T,V) do { *((long *) T) = *((long*) &V); \
+			      *(((long *) T)+1) = *(((long*) &V)+1); } while(0)
+#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
+#define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float))
+#define floatget(V,M)   memcpy((byte*)(&V), (byte*)(M), sizeof(float))
+#define float8get(V,M) doubleget((V),(M))
+#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* _WIN64 */
+
+#define HAVE_PERROR
+#define HAVE_VFPRINT
+#define HAVE_RENAME		/* Have rename() as function */
+#define HAVE_BINARY_STREAMS	/* Have "b" flag in streams */
+#define HAVE_LONG_JMP		/* Have long jump function */
+#define HAVE_LOCKING		/* have locking() call */
+#define HAVE_ERRNO_AS_DEFINE	/* errno is a define */
+#define HAVE_STDLIB		/* everything is include in this file */
+#define HAVE_MEMCPY
+#define HAVE_MEMMOVE
+#define HAVE_GETCWD
+#define HAVE_TELL
+#define HAVE_TZNAME
+#define HAVE_PUTENV
+#define HAVE_SELECT
+#define HAVE_SETLOCALE
+#define HAVE_SOCKET		/* Giangi */
+#define HAVE_FLOAT_H
+#define HAVE_LIMITS_H
+#define HAVE_STDDEF_H
+#define HAVE_RINT		/* defined in this file */
+#define NO_FCNTL_NONBLOCK	/* No FCNTL */
+#define HAVE_ALLOCA
+#define HAVE_STRPBRK
+#define HAVE_STRSTR
+#define HAVE_COMPRESS
+#define HAVE_CREATESEMAPHORE
+#define HAVE_ISNAN
+#define HAVE_FINITE
+#define HAVE_QUERY_CACHE
+#define SPRINTF_RETURNS_INT
+#define HAVE_SETFILEPOINTER
+#define HAVE_VIO_READ_BUFF
+#define HAVE_STRNLEN
+
+#ifndef __NT__
+#undef FILE_SHARE_DELETE
+#define FILE_SHARE_DELETE 0     /* Not implemented on Win 98/ME */
+#endif
+
+#ifdef NOT_USED
+#define HAVE_SNPRINTF		/* Gave link error */
+#define _snprintf snprintf
+#endif
+
+#ifdef _MSC_VER
+#define HAVE_LDIV		/* The optimizer breaks in zortech for ldiv */
+#define HAVE_ANSI_INCLUDE
+#define HAVE_SYS_UTIME_H
+#define HAVE_STRTOUL
+#endif
+#define my_reinterpret_cast(A) reinterpret_cast 
+#define my_const_cast(A) const_cast
+
+
+/* MYSQL OPTIONS */
+
+#ifdef _CUSTOMCONFIG_
+#include 
+#else
+#define DEFAULT_MYSQL_HOME	"c:\\mysql"
+#define DATADIR         	"c:\\mysql\\data"
+#define PACKAGE			"mysql"
+#define DEFAULT_BASEDIR		"C:\\"
+#define SHAREDIR		"share"
+#define DEFAULT_CHARSET_HOME	"C:/mysql/"
+#endif
+#ifndef DEFAULT_HOME_ENV
+#define DEFAULT_HOME_ENV MYSQL_HOME
+#endif
+#ifndef DEFAULT_GROUP_SUFFIX_ENV
+#define DEFAULT_GROUP_SUFFIX_ENV MYSQL_GROUP_SUFFIX
+#endif
+
+/* File name handling */
+
+#define FN_LIBCHAR	'\\'
+#define FN_ROOTDIR	"\\"
+#define FN_DEVCHAR	':'
+#define FN_NETWORK_DRIVES	/* Uses \\ to indicate network drives */
+#define FN_NO_CASE_SENCE	/* Files are not case-sensitive */
+#define OS_FILE_LIMIT	2048
+
+#define DO_NOT_REMOVE_THREAD_WRAPPERS
+#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
+#define thread_safe_decrement(V,L) InterlockedDecrement((long*) &(V))
+/* The following is only used for statistics, so it should be good enough */
+#ifdef __NT__  /* This should also work on Win98 but .. */
+#define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C))
+#define thread_safe_sub(V,C,L) InterlockedExchangeAdd((long*) &(V),-(long) (C))
+#define statistic_add(V,C,L) thread_safe_add((V),(C),(L))
+#else
+#define thread_safe_add(V,C,L) \
+	pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L));
+#define thread_safe_sub(V,C,L) \
+	pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L));
+#define statistic_add(V,C,L)	 (V)+=(C)
+#endif
+#define statistic_increment(V,L) thread_safe_increment((V),(L))
+#define statistic_decrement(V,L) thread_safe_decrement((V),(L))
+
+#define shared_memory_buffer_length 16000
+#define default_shared_memory_base_name "MYSQL"
+
+#define MYSQL_DEFAULT_CHARSET_NAME "latin1"
+#define MYSQL_DEFAULT_COLLATION_NAME "latin1_swedish_ci"
+
+#define HAVE_SPATIAL 1
+#define HAVE_RTREE_KEYS 1
+
+#define HAVE_OPENSSL 1
+#define HAVE_YASSL 1
+
+/* Define charsets you want */
+/* #undef HAVE_CHARSET_armscii8 */
+/* #undef HAVE_CHARSET_ascii */
+#define HAVE_CHARSET_big5 1
+#define HAVE_CHARSET_cp1250 1
+/* #undef HAVE_CHARSET_cp1251 */
+/* #undef HAVE_CHARSET_cp1256 */
+/* #undef HAVE_CHARSET_cp1257 */
+/* #undef HAVE_CHARSET_cp850 */
+/* #undef HAVE_CHARSET_cp852 */
+/* #undef HAVE_CHARSET_cp866 */
+#define HAVE_CHARSET_cp932 1
+/* #undef HAVE_CHARSET_dec8 */
+#define HAVE_CHARSET_eucjpms 1
+#define HAVE_CHARSET_euckr 1
+#define HAVE_CHARSET_gb2312 1
+#define HAVE_CHARSET_gbk 1
+/* #undef HAVE_CHARSET_greek */
+/* #undef HAVE_CHARSET_hebrew */
+/* #undef HAVE_CHARSET_hp8 */
+/* #undef HAVE_CHARSET_keybcs2 */
+/* #undef HAVE_CHARSET_koi8r */
+/* #undef HAVE_CHARSET_koi8u */
+#define HAVE_CHARSET_latin1 1
+#define HAVE_CHARSET_latin2 1
+/* #undef HAVE_CHARSET_latin5 */
+/* #undef HAVE_CHARSET_latin7 */
+/* #undef HAVE_CHARSET_macce */
+/* #undef HAVE_CHARSET_macroman */
+#define HAVE_CHARSET_sjis 1
+/* #undef HAVE_CHARSET_swe7 */
+#define HAVE_CHARSET_tis620 1
+#define HAVE_CHARSET_ucs2 1
+#define HAVE_CHARSET_ujis 1
+#define HAVE_CHARSET_utf8 1
+#define HAVE_UCA_COLLATIONS 1
+
diff --git a/dep/include/mysql/errmsg.h b/dep/include/mysql/errmsg.h
new file mode 100644
index 000000000..8b20b36ee
--- /dev/null
+++ b/dep/include/mysql/errmsg.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Error messages for MySQL clients */
+/* (Error messages for the daemon are in share/language/errmsg.sys) */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+void	init_client_errs(void);
+void	finish_client_errs(void);
+extern const char *client_errors[];	/* Error messages */
+#ifdef	__cplusplus
+}
+#endif
+
+#define CR_MIN_ERROR		2000	/* For easier client code */
+#define CR_MAX_ERROR		2999
+#if defined(OS2) && defined(MYSQL_SERVER)
+#define CER(X) client_errors[(X)-CR_MIN_ERROR]
+#elif !defined(ER)
+#define ER(X) client_errors[(X)-CR_MIN_ERROR]
+#endif
+#define CLIENT_ERRMAP		2	/* Errormap used by my_error() */
+
+/* Do not add error numbers before CR_ERROR_FIRST. */
+/* If necessary to add lower numbers, change CR_ERROR_FIRST accordingly. */
+#define CR_ERROR_FIRST  	2000 /*Copy first error nr.*/
+#define CR_UNKNOWN_ERROR	2000
+#define CR_SOCKET_CREATE_ERROR	2001
+#define CR_CONNECTION_ERROR	2002
+#define CR_CONN_HOST_ERROR	2003
+#define CR_IPSOCK_ERROR		2004
+#define CR_UNKNOWN_HOST		2005
+#define CR_SERVER_GONE_ERROR	2006
+#define CR_VERSION_ERROR	2007
+#define CR_OUT_OF_MEMORY	2008
+#define CR_WRONG_HOST_INFO	2009
+#define CR_LOCALHOST_CONNECTION 2010
+#define CR_TCP_CONNECTION	2011
+#define CR_SERVER_HANDSHAKE_ERR 2012
+#define CR_SERVER_LOST		2013
+#define CR_COMMANDS_OUT_OF_SYNC 2014
+#define CR_NAMEDPIPE_CONNECTION 2015
+#define CR_NAMEDPIPEWAIT_ERROR  2016
+#define CR_NAMEDPIPEOPEN_ERROR  2017
+#define CR_NAMEDPIPESETSTATE_ERROR 2018
+#define CR_CANT_READ_CHARSET	2019
+#define CR_NET_PACKET_TOO_LARGE 2020
+#define CR_EMBEDDED_CONNECTION	2021
+#define CR_PROBE_SLAVE_STATUS   2022
+#define CR_PROBE_SLAVE_HOSTS    2023
+#define CR_PROBE_SLAVE_CONNECT  2024
+#define CR_PROBE_MASTER_CONNECT 2025
+#define CR_SSL_CONNECTION_ERROR 2026
+#define CR_MALFORMED_PACKET     2027
+#define CR_WRONG_LICENSE	2028
+
+/* new 4.1 error codes */
+#define CR_NULL_POINTER		2029
+#define CR_NO_PREPARE_STMT	2030
+#define CR_PARAMS_NOT_BOUND	2031
+#define CR_DATA_TRUNCATED	2032
+#define CR_NO_PARAMETERS_EXISTS 2033
+#define CR_INVALID_PARAMETER_NO 2034
+#define CR_INVALID_BUFFER_USE	2035
+#define CR_UNSUPPORTED_PARAM_TYPE 2036
+
+#define CR_SHARED_MEMORY_CONNECTION             2037
+#define CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR  2038
+#define CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR   2039
+#define CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR 2040
+#define CR_SHARED_MEMORY_CONNECT_MAP_ERROR      2041
+#define CR_SHARED_MEMORY_FILE_MAP_ERROR         2042
+#define CR_SHARED_MEMORY_MAP_ERROR              2043
+#define CR_SHARED_MEMORY_EVENT_ERROR     	2044
+#define CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR 2045
+#define CR_SHARED_MEMORY_CONNECT_SET_ERROR      2046
+#define CR_CONN_UNKNOW_PROTOCOL 		2047
+#define CR_INVALID_CONN_HANDLE			2048
+#define CR_SECURE_AUTH                          2049
+#define CR_FETCH_CANCELED                       2050
+#define CR_NO_DATA                              2051
+#define CR_NO_STMT_METADATA                     2052
+#define CR_NO_RESULT_SET                        2053
+#define CR_NOT_IMPLEMENTED                      2054
+#define CR_SERVER_LOST_EXTENDED			2055
+#define CR_ERROR_LAST  /*Copy last error nr:*/  2055
+/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
+
diff --git a/dep/include/mysql/m_ctype.h b/dep/include/mysql/m_ctype.h
new file mode 100644
index 000000000..218ec2daa
--- /dev/null
+++ b/dep/include/mysql/m_ctype.h
@@ -0,0 +1,521 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/*
+  A better inplementation of the UNIX ctype(3) library.
+  Notes:   my_global.h should be included before ctype.h
+*/
+
+#ifndef _m_ctype_h
+#define _m_ctype_h
+
+#include 
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define MY_CS_NAME_SIZE			32
+#define MY_CS_CTYPE_TABLE_SIZE		257
+#define MY_CS_TO_LOWER_TABLE_SIZE	256
+#define MY_CS_TO_UPPER_TABLE_SIZE	256
+#define MY_CS_SORT_ORDER_TABLE_SIZE	256
+#define MY_CS_TO_UNI_TABLE_SIZE		256
+
+#define CHARSET_DIR	"charsets/"
+
+#define my_wc_t ulong
+
+typedef struct unicase_info_st
+{
+  uint16 toupper;
+  uint16 tolower;
+  uint16 sort;
+} MY_UNICASE_INFO;
+
+
+extern MY_UNICASE_INFO *my_unicase_default[256];
+extern MY_UNICASE_INFO *my_unicase_turkish[256];
+
+
+/* wm_wc and wc_mb return codes */
+#define MY_CS_ILSEQ	0     /* Wrong by sequence: wb_wc                   */
+#define MY_CS_ILUNI	0     /* Cannot encode Unicode to charset: wc_mb    */
+#define MY_CS_TOOSMALL  -101  /* Need at least one byte:    wc_mb and mb_wc */
+#define MY_CS_TOOSMALL2 -102  /* Need at least two bytes:   wc_mb and mb_wc */
+#define MY_CS_TOOSMALL3 -103  /* Need at least three bytes: wc_mb and mb_wc */
+/* These following three are currently not really used */
+#define MY_CS_TOOSMALL4 -104  /* Need at least 4 bytes: wc_mb and mb_wc */
+#define MY_CS_TOOSMALL5 -105  /* Need at least 5 bytes: wc_mb and mb_wc */
+#define MY_CS_TOOSMALL6 -106  /* Need at least 6 bytes: wc_mb and mb_wc */
+/* A helper macros for "need at least n bytes" */
+#define MY_CS_TOOSMALLN(n)    (-100-(n))
+
+#define MY_SEQ_INTTAIL	1
+#define MY_SEQ_SPACES	2
+
+        /* My charsets_list flags */
+#define MY_CS_COMPILED  1      /* compiled-in sets               */
+#define MY_CS_CONFIG    2      /* sets that have a *.conf file   */
+#define MY_CS_INDEX     4      /* sets listed in the Index file  */
+#define MY_CS_LOADED    8      /* sets that are currently loaded */
+#define MY_CS_BINSORT	16     /* if binary sort order           */
+#define MY_CS_PRIMARY	32     /* if primary collation           */
+#define MY_CS_STRNXFRM	64     /* if strnxfrm is used for sort   */
+#define MY_CS_UNICODE	128    /* is a charset is full unicode   */
+#define MY_CS_READY	256    /* if a charset is initialized    */
+#define MY_CS_AVAILABLE	512    /* If either compiled-in or loaded*/
+#define MY_CS_CSSORT	1024   /* if case sensitive sort order   */	
+#define MY_CS_PUREASCII 2048   /* if a charset is pure ascii     */
+#define MY_CHARSET_UNDEFINED 0
+
+/* Character repertoire flags */
+#define MY_REPERTOIRE_ASCII      1 /* Pure ASCII            U+0000..U+007F */
+#define MY_REPERTOIRE_EXTENDED   2 /* Extended characters:  U+0080..U+FFFF */
+#define MY_REPERTOIRE_UNICODE30  3 /* ASCII | EXTENDED:     U+0000..U+FFFF */
+
+
+typedef struct my_uni_idx_st
+{
+  uint16 from;
+  uint16 to;
+  uchar  *tab;
+} MY_UNI_IDX;
+
+typedef struct
+{
+  uint beg;
+  uint end;
+  uint mb_len;
+} my_match_t;
+
+enum my_lex_states
+{
+  MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT, 
+  MY_LEX_IDENT_SEP, MY_LEX_IDENT_START,
+  MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_BIN_NUMBER,
+  MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END,
+  MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL,
+  MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE, 
+  MY_LEX_LONG_COMMENT, MY_LEX_END_LONG_COMMENT, MY_LEX_SEMICOLON, 
+  MY_LEX_SET_VAR, MY_LEX_USER_END, MY_LEX_HOSTNAME, MY_LEX_SKIP, 
+  MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR,
+  MY_LEX_IDENT_OR_KEYWORD,
+  MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR,
+  MY_LEX_STRING_OR_DELIMITER
+};
+
+struct charset_info_st;
+
+
+/* See strings/CHARSET_INFO.txt for information about this structure  */
+typedef struct my_collation_handler_st
+{
+  my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
+  /* Collation routines */
+  int     (*strnncoll)(struct charset_info_st *,
+		       const uchar *, uint, const uchar *, uint, my_bool);
+  int     (*strnncollsp)(struct charset_info_st *,
+                         const uchar *, uint, const uchar *, uint,
+                         my_bool diff_if_only_endspace_difference);
+  int     (*strnxfrm)(struct charset_info_st *,
+		      uchar *, uint, const uchar *, uint);
+  uint    (*strnxfrmlen)(struct charset_info_st *, uint); 
+  my_bool (*like_range)(struct charset_info_st *,
+			const char *s, uint s_length,
+			pchar w_prefix, pchar w_one, pchar w_many, 
+			uint res_length,
+			char *min_str, char *max_str,
+			uint *min_len, uint *max_len);
+  int     (*wildcmp)(struct charset_info_st *,
+  		     const char *str,const char *str_end,
+                     const char *wildstr,const char *wildend,
+                     int escape,int w_one, int w_many);
+
+  int  (*strcasecmp)(struct charset_info_st *, const char *, const char *);
+  
+  uint (*instr)(struct charset_info_st *,
+                const char *b, uint b_length,
+                const char *s, uint s_length,
+                my_match_t *match, uint nmatch);
+  
+  /* Hash calculation */
+  void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len,
+		    ulong *nr1, ulong *nr2); 
+  my_bool (*propagate)(struct charset_info_st *cs, const uchar *str, uint len);
+} MY_COLLATION_HANDLER;
+
+extern MY_COLLATION_HANDLER my_collation_mb_bin_handler;
+extern MY_COLLATION_HANDLER my_collation_8bit_bin_handler;
+extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler;
+extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler;
+
+
+/* See strings/CHARSET_INFO.txt about information on this structure  */
+typedef struct my_charset_handler_st
+{
+  my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
+  /* Multibyte routines */
+  int     (*ismbchar)(struct charset_info_st *, const char *, const char *);
+  int     (*mbcharlen)(struct charset_info_st *, uint);
+  uint    (*numchars)(struct charset_info_st *, const char *b, const char *e);
+  uint    (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos);
+  uint    (*well_formed_len)(struct charset_info_st *,
+                             const char *b,const char *e,
+                             uint nchars, int *error);
+  uint    (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
+  uint    (*numcells)(struct charset_info_st *, const char *b, const char *e);
+  
+  /* Unicode convertion */
+  int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc,
+	       const unsigned char *s,const unsigned char *e);
+  int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc,
+	       unsigned char *s,unsigned char *e);
+  
+  /* Functions for case and sort convertion */
+  uint    (*caseup_str)(struct charset_info_st *, char *);
+  uint    (*casedn_str)(struct charset_info_st *, char *);
+  uint    (*caseup)(struct charset_info_st *, char *src, uint srclen,
+                                              char *dst, uint dstlen);
+  uint    (*casedn)(struct charset_info_st *, char *src, uint srclen,
+                                              char *dst, uint dstlen);
+  
+  /* Charset dependant snprintf() */
+  int  (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt,
+		   ...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5);
+  int  (*long10_to_str)(struct charset_info_st *, char *to, uint n, int radix,
+			long int val);
+  int (*longlong10_to_str)(struct charset_info_st *, char *to, uint n,
+			   int radix, longlong val);
+  
+  void (*fill)(struct charset_info_st *, char *to, uint len, int fill);
+  
+  /* String-to-number convertion routines */
+  long        (*strntol)(struct charset_info_st *, const char *s, uint l,
+			 int base, char **e, int *err);
+  ulong      (*strntoul)(struct charset_info_st *, const char *s, uint l,
+			 int base, char **e, int *err);
+  longlong   (*strntoll)(struct charset_info_st *, const char *s, uint l,
+			 int base, char **e, int *err);
+  ulonglong (*strntoull)(struct charset_info_st *, const char *s, uint l,
+			 int base, char **e, int *err);
+  double      (*strntod)(struct charset_info_st *, char *s, uint l, char **e,
+			 int *err);
+  longlong    (*strtoll10)(struct charset_info_st *cs,
+                           const char *nptr, char **endptr, int *error);
+  ulonglong   (*strntoull10rnd)(struct charset_info_st *cs,
+                                const char *str, uint length, int unsigned_fl,
+                                char **endptr, int *error);
+  ulong        (*scan)(struct charset_info_st *, const char *b, const char *e,
+		       int sq);
+} MY_CHARSET_HANDLER;
+
+extern MY_CHARSET_HANDLER my_charset_8bit_handler;
+extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
+
+
+/* See strings/CHARSET_INFO.txt about information on this structure  */
+typedef struct charset_info_st
+{
+  uint      number;
+  uint      primary_number;
+  uint      binary_number;
+  uint      state;
+  const char *csname;
+  const char *name;
+  const char *comment;
+  const char *tailoring;
+  uchar    *ctype;
+  uchar    *to_lower;
+  uchar    *to_upper;
+  uchar    *sort_order;
+  uint16   *contractions;
+  uint16   **sort_order_big;
+  uint16      *tab_to_uni;
+  MY_UNI_IDX  *tab_from_uni;
+  MY_UNICASE_INFO **caseinfo;
+  uchar     *state_map;
+  uchar     *ident_map;
+  uint      strxfrm_multiply;
+  uchar     caseup_multiply;
+  uchar     casedn_multiply;
+  uint      mbminlen;
+  uint      mbmaxlen;
+  uint16    min_sort_char;
+  uint16    max_sort_char; /* For LIKE optimization */
+  uchar     pad_char;
+  my_bool   escape_with_backslash_is_dangerous;
+  
+  MY_CHARSET_HANDLER *cset;
+  MY_COLLATION_HANDLER *coll;
+  
+} CHARSET_INFO;
+
+
+extern CHARSET_INFO my_charset_bin;
+extern CHARSET_INFO my_charset_big5_chinese_ci;
+extern CHARSET_INFO my_charset_big5_bin;
+extern CHARSET_INFO my_charset_cp932_japanese_ci;
+extern CHARSET_INFO my_charset_cp932_bin;
+extern CHARSET_INFO my_charset_eucjpms_japanese_ci;
+extern CHARSET_INFO my_charset_eucjpms_bin;
+extern CHARSET_INFO my_charset_euckr_korean_ci;
+extern CHARSET_INFO my_charset_euckr_bin;
+extern CHARSET_INFO my_charset_gb2312_chinese_ci;
+extern CHARSET_INFO my_charset_gb2312_bin;
+extern CHARSET_INFO my_charset_gbk_chinese_ci;
+extern CHARSET_INFO my_charset_gbk_bin;
+extern CHARSET_INFO my_charset_latin1;
+extern CHARSET_INFO my_charset_latin1_german2_ci;
+extern CHARSET_INFO my_charset_latin1_bin;
+extern CHARSET_INFO my_charset_latin2_czech_ci;
+extern CHARSET_INFO my_charset_sjis_japanese_ci;
+extern CHARSET_INFO my_charset_sjis_bin;
+extern CHARSET_INFO my_charset_tis620_thai_ci;
+extern CHARSET_INFO my_charset_tis620_bin;
+extern CHARSET_INFO my_charset_ucs2_general_ci;
+extern CHARSET_INFO my_charset_ucs2_bin;
+extern CHARSET_INFO my_charset_ucs2_unicode_ci;
+extern CHARSET_INFO my_charset_ujis_japanese_ci;
+extern CHARSET_INFO my_charset_ujis_bin;
+extern CHARSET_INFO my_charset_utf8_general_ci;
+extern CHARSET_INFO my_charset_utf8_unicode_ci;
+extern CHARSET_INFO my_charset_utf8_bin;
+extern CHARSET_INFO my_charset_cp1250_czech_ci;
+
+/* declarations for simple charsets */
+extern int  my_strnxfrm_simple(CHARSET_INFO *, uchar *, uint, const uchar *,
+                               uint); 
+uint  my_strnxfrmlen_simple(CHARSET_INFO *, uint); 
+extern int  my_strnncoll_simple(CHARSET_INFO *, const uchar *, uint,
+				const uchar *, uint, my_bool);
+
+extern int  my_strnncollsp_simple(CHARSET_INFO *, const uchar *, uint,
+                                  const uchar *, uint,
+                                  my_bool diff_if_only_endspace_difference);
+
+extern void my_hash_sort_simple(CHARSET_INFO *cs,
+				const uchar *key, uint len,
+				ulong *nr1, ulong *nr2); 
+
+extern uint my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, uint length);
+
+extern uint my_instr_simple(struct charset_info_st *,
+                            const char *b, uint b_length,
+                            const char *s, uint s_length,
+                            my_match_t *match, uint nmatch);
+
+
+/* Functions for 8bit */
+extern uint my_caseup_str_8bit(CHARSET_INFO *, char *);
+extern uint my_casedn_str_8bit(CHARSET_INFO *, char *);
+extern uint my_caseup_8bit(CHARSET_INFO *, char *src, uint srclen,
+                                           char *dst, uint dstlen);
+extern uint my_casedn_8bit(CHARSET_INFO *, char *src, uint srclen,
+                                           char *dst, uint dstlen);
+
+extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *);
+
+int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc, const uchar *s,const uchar *e);
+int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e);
+
+ulong my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq);
+
+int my_snprintf_8bit(struct charset_info_st *, char *to, uint n,
+		     const char *fmt, ...)
+  ATTRIBUTE_FORMAT(printf, 4, 5);
+
+long        my_strntol_8bit(CHARSET_INFO *, const char *s, uint l, int base,
+			    char **e, int *err);
+ulong      my_strntoul_8bit(CHARSET_INFO *, const char *s, uint l, int base,
+			    char **e, int *err);
+longlong   my_strntoll_8bit(CHARSET_INFO *, const char *s, uint l, int base,
+			    char **e, int *err);
+ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, uint l, int base,
+			    char **e, int *err);
+double      my_strntod_8bit(CHARSET_INFO *, char *s, uint l,char **e,
+			    int *err);
+int  my_long10_to_str_8bit(CHARSET_INFO *, char *to, uint l, int radix,
+			   long int val);
+int my_longlong10_to_str_8bit(CHARSET_INFO *, char *to, uint l, int radix,
+			      longlong val);
+
+longlong my_strtoll10_8bit(CHARSET_INFO *cs,
+                           const char *nptr, char **endptr, int *error);
+longlong my_strtoll10_ucs2(CHARSET_INFO *cs, 
+                           const char *nptr, char **endptr, int *error);
+
+ulonglong my_strntoull10rnd_8bit(CHARSET_INFO *cs,
+                                 const char *str, uint length, int unsigned_fl,
+                                 char **endptr, int *error);
+ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs, 
+                                 const char *str, uint length, int unsigned_fl,
+                                 char **endptr, int *error);
+
+void my_fill_8bit(CHARSET_INFO *cs, char* to, uint l, int fill);
+
+my_bool  my_like_range_simple(CHARSET_INFO *cs,
+			      const char *ptr, uint ptr_length,
+			      pbool escape, pbool w_one, pbool w_many,
+			      uint res_length,
+			      char *min_str, char *max_str,
+			      uint *min_length, uint *max_length);
+
+my_bool  my_like_range_mb(CHARSET_INFO *cs,
+			  const char *ptr, uint ptr_length,
+			  pbool escape, pbool w_one, pbool w_many,
+			  uint res_length,
+			  char *min_str, char *max_str,
+			  uint *min_length, uint *max_length);
+
+my_bool  my_like_range_ucs2(CHARSET_INFO *cs,
+			    const char *ptr, uint ptr_length,
+			    pbool escape, pbool w_one, pbool w_many,
+			    uint res_length,
+			    char *min_str, char *max_str,
+			    uint *min_length, uint *max_length);
+
+
+int my_wildcmp_8bit(CHARSET_INFO *,
+		    const char *str,const char *str_end,
+		    const char *wildstr,const char *wildend,
+		    int escape, int w_one, int w_many);
+
+int my_wildcmp_bin(CHARSET_INFO *,
+		   const char *str,const char *str_end,
+		   const char *wildstr,const char *wildend,
+		   int escape, int w_one, int w_many);
+
+uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
+uint my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e);
+uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos);
+uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e,
+                             uint pos, int *error);
+int my_mbcharlen_8bit(CHARSET_INFO *, uint c);
+
+
+/* Functions for multibyte charsets */
+extern uint my_caseup_str_mb(CHARSET_INFO *, char *);
+extern uint my_casedn_str_mb(CHARSET_INFO *, char *);
+extern uint my_caseup_mb(CHARSET_INFO *, char *src, uint srclen,
+                                         char *dst, uint dstlen);
+extern uint my_casedn_mb(CHARSET_INFO *, char *src, uint srclen,
+                                         char *dst, uint dstlen);
+extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *);
+
+int my_wildcmp_mb(CHARSET_INFO *,
+		  const char *str,const char *str_end,
+		  const char *wildstr,const char *wildend,
+		  int escape, int w_one, int w_many);
+uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
+uint my_numcells_mb(CHARSET_INFO *, const char *b, const char *e);
+uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos);
+uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e,
+                           uint pos, int *error);
+uint my_instr_mb(struct charset_info_st *,
+                 const char *b, uint b_length,
+                 const char *s, uint s_length,
+                 my_match_t *match, uint nmatch);
+
+int my_wildcmp_unicode(CHARSET_INFO *cs,
+                       const char *str, const char *str_end,
+                       const char *wildstr, const char *wildend,
+                       int escape, int w_one, int w_many,
+                       MY_UNICASE_INFO **weights);
+
+extern my_bool my_parse_charset_xml(const char *bug, uint len,
+				    int (*add)(CHARSET_INFO *cs));
+
+my_bool my_propagate_simple(CHARSET_INFO *cs, const uchar *str, uint len);
+my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, uint len);
+
+
+uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
+my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
+my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
+
+
+#define	_MY_U	01	/* Upper case */
+#define	_MY_L	02	/* Lower case */
+#define	_MY_NMR	04	/* Numeral (digit) */
+#define	_MY_SPC	010	/* Spacing character */
+#define	_MY_PNT	020	/* Punctuation */
+#define	_MY_CTR	040	/* Control character */
+#define	_MY_B	0100	/* Blank */
+#define	_MY_X	0200	/* heXadecimal digit */
+
+
+#define	my_isascii(c)	(!((c) & ~0177))
+#define	my_toascii(c)	((c) & 0177)
+#define my_tocntrl(c)	((c) & 31)
+#define my_toprint(c)	((c) | 64)
+#define my_toupper(s,c)	(char) ((s)->to_upper[(uchar) (c)])
+#define my_tolower(s,c)	(char) ((s)->to_lower[(uchar) (c)])
+#define	my_isalpha(s, c)  (((s)->ctype+1)[(uchar) (c)] & (_MY_U | _MY_L))
+#define	my_isupper(s, c)  (((s)->ctype+1)[(uchar) (c)] & _MY_U)
+#define	my_islower(s, c)  (((s)->ctype+1)[(uchar) (c)] & _MY_L)
+#define	my_isdigit(s, c)  (((s)->ctype+1)[(uchar) (c)] & _MY_NMR)
+#define	my_isxdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _MY_X)
+#define	my_isalnum(s, c)  (((s)->ctype+1)[(uchar) (c)] & (_MY_U | _MY_L | _MY_NMR))
+#define	my_isspace(s, c)  (((s)->ctype+1)[(uchar) (c)] & _MY_SPC)
+#define	my_ispunct(s, c)  (((s)->ctype+1)[(uchar) (c)] & _MY_PNT)
+#define	my_isprint(s, c)  (((s)->ctype+1)[(uchar) (c)] & (_MY_PNT | _MY_U | _MY_L | _MY_NMR | _MY_B))
+#define	my_isgraph(s, c)  (((s)->ctype+1)[(uchar) (c)] & (_MY_PNT | _MY_U | _MY_L | _MY_NMR))
+#define	my_iscntrl(s, c)  (((s)->ctype+1)[(uchar) (c)] & _MY_CTR)
+
+/* Some macros that should be cleaned up a little */
+#define my_isvar(s,c)                 (my_isalnum(s,c) || (c) == '_')
+#define my_isvar_start(s,c)           (my_isalpha(s,c) || (c) == '_')
+
+#define my_binary_compare(s)	      ((s)->state  & MY_CS_BINSORT)
+#define use_strnxfrm(s)               ((s)->state  & MY_CS_STRNXFRM)
+#define my_strnxfrm(s, a, b, c, d)    ((s)->coll->strnxfrm((s), (a), (b), (c), (d)))
+#define my_strnncoll(s, a, b, c, d) ((s)->coll->strnncoll((s), (a), (b), (c), (d), 0))
+#define my_like_range(s, a, b, c, d, e, f, g, h, i, j) \
+   ((s)->coll->like_range((s), (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)))
+#define my_wildcmp(cs,s,se,w,we,e,o,m) ((cs)->coll->wildcmp((cs),(s),(se),(w),(we),(e),(o),(m)))
+#define my_strcasecmp(s, a, b)        ((s)->coll->strcasecmp((s), (a), (b)))
+#define my_charpos(cs, b, e, num)     (cs)->cset->charpos((cs), (const char*) (b), (const char *)(e), (num))
+
+
+#define use_mb(s)                     ((s)->cset->ismbchar != NULL)
+#define my_ismbchar(s, a, b)          ((s)->cset->ismbchar((s), (a), (b)))
+#ifdef USE_MB
+#define my_mbcharlen(s, a)            ((s)->cset->mbcharlen((s),(a)))
+#else
+#define my_mbcharlen(s, a)            1
+#endif
+
+#define my_caseup_str(s, a)           ((s)->cset->caseup_str((s), (a)))
+#define my_casedn_str(s, a)           ((s)->cset->casedn_str((s), (a)))
+#define my_strntol(s, a, b, c, d, e)  ((s)->cset->strntol((s),(a),(b),(c),(d),(e)))
+#define my_strntoul(s, a, b, c, d, e) ((s)->cset->strntoul((s),(a),(b),(c),(d),(e)))
+#define my_strntoll(s, a, b, c, d, e) ((s)->cset->strntoll((s),(a),(b),(c),(d),(e)))
+#define my_strntoull(s, a, b, c,d, e) ((s)->cset->strntoull((s),(a),(b),(c),(d),(e)))
+#define my_strntod(s, a, b, c, d)     ((s)->cset->strntod((s),(a),(b),(c),(d)))
+
+
+/* XXX: still need to take care of this one */
+#ifdef MY_CHARSET_TIS620
+#error The TIS620 charset is broken at the moment.  Tell tim to fix it.
+#define USE_TIS620
+#include "t_ctype.h"
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _m_ctype_h */
diff --git a/dep/include/mysql/m_string.h b/dep/include/mysql/m_string.h
new file mode 100644
index 000000000..c26d0fb92
--- /dev/null
+++ b/dep/include/mysql/m_string.h
@@ -0,0 +1,266 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* There may be prolems include all of theese. Try to test in
+   configure with ones are needed? */
+
+/*  This is needed for the definitions of strchr... on solaris */
+
+#ifndef _m_string_h
+#define _m_string_h
+#ifndef __USE_GNU
+#define __USE_GNU				/* We want to use stpcpy */
+#endif
+#if defined(HAVE_STRINGS_H)
+#include 
+#endif
+#if defined(HAVE_STRING_H)
+#include 
+#endif
+
+/* need by my_vsnprintf */
+#include  
+
+/* Correct some things for UNIXWARE7 */
+#ifdef HAVE_UNIXWARE7_THREADS
+#undef HAVE_STRINGS_H
+#undef HAVE_MEMORY_H
+#define HAVE_MEMCPY
+#ifndef HAVE_MEMMOVE
+#define HAVE_MEMMOVE
+#endif
+#undef HAVE_BCMP
+#undef bcopy
+#undef bcmp
+#undef bzero
+#endif /* HAVE_UNIXWARE7_THREADS */
+#ifdef _AIX
+#undef HAVE_BCMP
+#endif
+
+/*  This is needed for the definitions of bzero... on solaris */
+#if defined(HAVE_STRINGS_H) && !defined(HAVE_mit_thread)
+#include 
+#endif
+
+/*  This is needed for the definitions of memcpy... on solaris */
+#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
+#include 
+#endif
+
+#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
+# define memcpy(d, s, n)	bcopy ((s), (d), (n))
+# define memset(A,C,B)		bfill((A),(B),(C))
+# define memmove(d, s, n)	bmove ((d), (s), (n))
+#elif defined(HAVE_MEMMOVE)
+# define bmove(d, s, n)		memmove((d), (s), (n))
+#else
+# define memmove(d, s, n)	bmove((d), (s), (n)) /* our bmove */
+#endif
+
+/* Unixware 7 */
+#if !defined(HAVE_BFILL)
+# define bfill(A,B,C)           memset((A),(C),(B))
+# define bmove_align(A,B,C)    memcpy((A),(B),(C))
+#endif
+
+#if !defined(HAVE_BCMP)
+# define bcopy(s, d, n)		memcpy((d), (s), (n))
+# define bcmp(A,B,C)		memcmp((A),(B),(C))
+# define bzero(A,B)		memset((A),0,(B))
+# define bmove_align(A,B,C)    memcpy((A),(B),(C))
+#endif
+
+#if defined(__cplusplus) && !defined(OS2)
+extern "C" {
+#endif
+
+/*
+  my_str_malloc() and my_str_free() are assigned to implementations in
+  strings/alloc.c, but can be overridden in the calling program.
+ */
+extern void *(*my_str_malloc)(size_t);
+extern void (*my_str_free)(void *);
+
+#if defined(HAVE_STPCPY) && !defined(HAVE_mit_thread)
+#define strmov(A,B) stpcpy((A),(B))
+#ifndef stpcpy
+extern char *stpcpy(char *, const char *);	/* For AIX with gcc 2.95.3 */
+#endif
+#endif
+
+/* Declared in int2str() */
+extern char NEAR _dig_vec_upper[];
+extern char NEAR _dig_vec_lower[];
+
+/* Defined in strtod.c */
+extern const double log_10[309];
+
+#ifdef BAD_STRING_COMPILER
+#define strmov(A,B)  (memccpy(A,B,0,INT_MAX)-1)
+#else
+#define strmov_overlapp(A,B) strmov(A,B)
+#define strmake_overlapp(A,B,C) strmake(A,B,C)
+#endif
+
+#ifdef BAD_MEMCPY			/* Problem with gcc on Alpha */
+#define memcpy_fixed(A,B,C) bmove((A),(B),(C))
+#else
+#define memcpy_fixed(A,B,C) memcpy((A),(B),(C))
+#endif
+
+#ifdef MSDOS
+#undef bmove_align
+#define bmove512(A,B,C) bmove_align(A,B,C)
+extern	void bmove_align(gptr dst,const gptr src,uint len);
+#endif
+
+#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
+#define bmove512(A,B,C) memcpy(A,B,C)
+#endif
+
+	/* Prototypes for string functions */
+
+#if !defined(bfill) && !defined(HAVE_BFILL)
+extern	void bfill(gptr dst,uint len,pchar fill);
+#endif
+
+#if !defined(bzero) && !defined(HAVE_BZERO)
+extern	void bzero(gptr dst,uint len);
+#endif
+
+#if !defined(bcmp) && !defined(HAVE_BCMP)
+extern	int bcmp(const char *s1,const char *s2,uint len);
+#endif
+#ifdef HAVE_purify
+extern	int my_bcmp(const char *s1,const char *s2,uint len);
+#undef bcmp
+#define bcmp(A,B,C) my_bcmp((A),(B),(C))
+#endif
+
+#ifndef bmove512
+extern	void bmove512(gptr dst,const gptr src,uint len);
+#endif
+
+#if !defined(HAVE_BMOVE) && !defined(bmove)
+extern	void bmove(char *dst, const char *src,uint len);
+#endif
+
+extern	void bmove_upp(char *dst,const char *src,uint len);
+extern	void bchange(char *dst,uint old_len,const char *src,
+		     uint new_len,uint tot_len);
+extern	void strappend(char *s,uint len,pchar fill);
+extern	char *strend(const char *s);
+extern  char *strcend(const char *, pchar);
+extern	char *strfield(char *src,int fields,int chars,int blanks,
+			   int tabch);
+extern	char *strfill(my_string s,uint len,pchar fill);
+extern	uint strinstr(const char *str,const char *search);
+extern  uint r_strinstr(reg1 my_string str,int from, reg4 my_string search);
+extern	char *strkey(char *dst,char *head,char *tail,char *flags);
+extern	char *strmake(char *dst,const char *src,uint length);
+#ifndef strmake_overlapp
+extern	char *strmake_overlapp(char *dst,const char *src, uint length);
+#endif
+
+#ifndef strmov
+extern	char *strmov(char *dst,const char *src);
+#endif
+extern	char *strnmov(char *dst,const char *src,uint n);
+extern	char *strsuff(const char *src,const char *suffix);
+extern	char *strcont(const char *src,const char *set);
+extern	char *strxcat _VARARGS((char *dst,const char *src, ...));
+extern	char *strxmov _VARARGS((char *dst,const char *src, ...));
+extern	char *strxcpy _VARARGS((char *dst,const char *src, ...));
+extern	char *strxncat _VARARGS((char *dst,uint len, const char *src, ...));
+extern	char *strxnmov _VARARGS((char *dst,uint len, const char *src, ...));
+extern	char *strxncpy _VARARGS((char *dst,uint len, const char *src, ...));
+
+/* Prototypes of normal stringfunctions (with may ours) */
+
+#ifdef WANT_STRING_PROTOTYPES
+extern char *strcat(char *, const char *);
+extern char *strchr(const char *, pchar);
+extern char *strrchr(const char *, pchar);
+extern char *strcpy(char *, const char *);
+extern int strcmp(const char *, const char *);
+#ifndef __GNUC__
+extern size_t strlen(const char *);
+#endif
+#endif
+#ifndef HAVE_STRNLEN
+extern uint strnlen(const char *s, uint n);
+#endif
+
+#if !defined(__cplusplus)
+#ifndef HAVE_STRPBRK
+extern char *strpbrk(const char *, const char *);
+#endif
+#ifndef HAVE_STRSTR
+extern char *strstr(const char *, const char *);
+#endif
+#endif
+extern int is_prefix(const char *, const char *);
+
+/* Conversion routines */
+double my_strtod(const char *str, char **end, int *error);
+double my_atof(const char *nptr);
+
+extern char *llstr(longlong value,char *buff);
+extern char *ullstr(longlong value,char *buff);
+#ifndef HAVE_STRTOUL
+extern long strtol(const char *str, char **ptr, int base);
+extern ulong strtoul(const char *str, char **ptr, int base);
+#endif
+
+extern char *int2str(long val, char *dst, int radix, int upcase);
+extern char *int10_to_str(long val,char *dst,int radix);
+extern char *str2int(const char *src,int radix,long lower,long upper,
+			 long *val);
+longlong my_strtoll10(const char *nptr, char **endptr, int *error);
+#if SIZEOF_LONG == SIZEOF_LONG_LONG
+#define longlong2str(A,B,C) int2str((A),(B),(C),1)
+#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
+#undef strtoll
+#define strtoll(A,B,C) strtol((A),(B),(C))
+#define strtoull(A,B,C) strtoul((A),(B),(C))
+#ifndef HAVE_STRTOULL
+#define HAVE_STRTOULL
+#endif
+#ifndef HAVE_STRTOLL
+#define HAVE_STRTOLL
+#endif
+#else
+#ifdef HAVE_LONG_LONG
+extern char *longlong2str(longlong val,char *dst,int radix);
+extern char *longlong10_to_str(longlong val,char *dst,int radix);
+#if (!defined(HAVE_STRTOULL) || defined(HAVE_mit_thread)) || defined(NO_STRTOLL_PROTO)
+extern longlong strtoll(const char *str, char **ptr, int base);
+extern ulonglong strtoull(const char *str, char **ptr, int base);
+#endif
+#endif
+#endif
+
+/* my_vsnprintf.c */
+
+extern int my_vsnprintf( char *str, size_t n,
+                                const char *format, va_list ap );
+extern int my_snprintf(char *to, size_t n, const char *fmt, ...)
+  ATTRIBUTE_FORMAT(printf, 3, 4);
+
+#if defined(__cplusplus) && !defined(OS2)
+}
+#endif
+#endif
diff --git a/dep/include/mysql/my_alloc.h b/dep/include/mysql/my_alloc.h
new file mode 100644
index 000000000..657394a36
--- /dev/null
+++ b/dep/include/mysql/my_alloc.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* 
+   Data structures for mysys/my_alloc.c (root memory allocator)
+*/
+
+#ifndef _my_alloc_h
+#define _my_alloc_h
+
+#define ALLOC_MAX_BLOCK_TO_DROP			4096
+#define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP	10
+
+typedef struct st_used_mem
+{				   /* struct for once_alloc (block) */
+  struct st_used_mem *next;	   /* Next block in use */
+  unsigned int	left;		   /* memory left in block  */
+  unsigned int	size;		   /* size of block */
+} USED_MEM;
+
+
+typedef struct st_mem_root
+{
+  USED_MEM *free;                  /* blocks with free memory in it */
+  USED_MEM *used;                  /* blocks almost without free memory */
+  USED_MEM *pre_alloc;             /* preallocated block */
+  /* if block have less memory it will be put in 'used' list */
+  unsigned int min_malloc;
+  unsigned int block_size;         /* initial block size */
+  unsigned int block_num;          /* allocated blocks counter */
+  /* 
+     first free block in queue test counter (if it exceed 
+     MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list)
+  */
+  unsigned int first_block_usage;
+
+  void (*error_handler)(void);
+} MEM_ROOT;
+#endif
diff --git a/dep/include/mysql/my_dbug.h b/dep/include/mysql/my_dbug.h
new file mode 100644
index 000000000..31fd507ec
--- /dev/null
+++ b/dep/include/mysql/my_dbug.h
@@ -0,0 +1,107 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef _dbug_h
+#define _dbug_h
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+#if !defined(DBUG_OFF) && !defined(_lint)
+extern	int _db_on_,_no_db_;
+extern	FILE *_db_fp_;
+extern	char *_db_process_;
+extern	int _db_keyword_(const char *keyword);
+extern  int _db_strict_keyword_(const char *keyword);
+extern	void _db_setjmp_(void);
+extern	void _db_longjmp_(void);
+extern	void _db_push_(const char *control);
+extern	void _db_pop_(void);
+extern	void _db_enter_(const char *_func_,const char *_file_,uint _line_,
+			const char **_sfunc_,const char **_sfile_,
+			uint *_slevel_, char ***);
+extern	void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
+			 uint *_slevel_);
+extern	void _db_pargs_(uint _line_,const char *keyword);
+extern	void _db_doprnt_ _VARARGS((const char *format,...))
+  ATTRIBUTE_FORMAT(printf, 1, 2);
+extern	void _db_dump_(uint _line_,const char *keyword,const char *memory,
+		       uint length);
+extern	void _db_output_(uint flag);
+extern	void _db_end_(void);
+extern	void _db_lock_file(void);
+extern	void _db_unlock_file(void);
+
+#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
+	char **_db_framep_; \
+	_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
+		    &_db_framep_)
+#define DBUG_LEAVE \
+	(_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
+#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);}
+#define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
+#define DBUG_EXECUTE(keyword,a1) \
+	{if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
+#define DBUG_PRINT(keyword,arglist) \
+	{if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
+#define DBUG_PUSH(a1) _db_push_ (a1)
+#define DBUG_POP() _db_pop_ ()
+#define DBUG_PROCESS(a1) (_db_process_ = a1)
+#define DBUG_FILE (_db_fp_)
+#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
+#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
+#define DBUG_DUMP(keyword,a1,a2)\
+	{if (_db_on_) {_db_dump_(__LINE__,keyword,a1,a2);}}
+#define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr)
+#define DEBUGGER_OFF _no_db_=1;_db_on_=0;
+#define DEBUGGER_ON  _no_db_=0
+#define DBUG_END()  _db_end_ ()
+#define DBUG_LOCK_FILE { _db_lock_file(); }
+#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
+#define DBUG_OUTPUT(A) { _db_output_(A); }
+#define DBUG_ASSERT(A) assert(A)
+#define DBUG_EXECUTE_IF(keyword,a1) \
+        {if (_db_on_) {if (_db_strict_keyword_ (keyword)) { a1 }}}
+#define IF_DBUG(A) A
+#else						/* No debugger */
+
+#define DBUG_ENTER(a1)
+#define DBUG_RETURN(a1) return(a1)
+#define DBUG_VOID_RETURN return
+#define DBUG_EXECUTE(keyword,a1) {}
+#define DBUG_EXECUTE_IF(keyword,a1) {}
+#define DBUG_PRINT(keyword,arglist) {}
+#define DBUG_PUSH(a1) {}
+#define DBUG_POP() {}
+#define DBUG_PROCESS(a1) {}
+#define DBUG_FILE (stderr)
+#define DBUG_SETJMP setjmp
+#define DBUG_LONGJMP longjmp
+#define DBUG_DUMP(keyword,a1,a2) {}
+#define DBUG_IN_USE 0
+#define DEBUGGER_OFF
+#define DEBUGGER_ON
+#define DBUG_END()
+#define DBUG_LOCK_FILE
+#define DBUG_UNLOCK_FILE
+#define DBUG_OUTPUT(A)
+#define DBUG_ASSERT(A) {}
+#define DBUG_LEAVE
+#define IF_DBUG(A)
+#endif
+#ifdef	__cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/mysql/my_getopt.h b/dep/include/mysql/my_getopt.h
new file mode 100644
index 000000000..f5688a372
--- /dev/null
+++ b/dep/include/mysql/my_getopt.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 2002-2004 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef _my_getopt_h
+#define _my_getopt_h
+
+C_MODE_START
+
+#define GET_NO_ARG     1
+#define GET_BOOL       2
+#define GET_INT        3
+#define GET_UINT       4
+#define GET_LONG       5
+#define GET_ULONG      6
+#define GET_LL         7
+#define GET_ULL        8
+#define GET_STR        9
+#define GET_STR_ALLOC 10
+#define GET_DISABLED  11
+
+#define GET_ASK_ADDR	 128
+#define GET_TYPE_MASK	 127
+
+enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
+
+struct my_option
+{
+  const char *name;                     /* Name of the option */
+  int        id;                        /* unique id or short option */
+  const char *comment;                  /* option comment, for autom. --help */
+  gptr       *value;                    /* The variable value */
+  gptr       *u_max_value;              /* The user def. max variable value */
+  const char **str_values;              /* Pointer to possible values */
+  ulong     var_type;
+  enum get_opt_arg_type arg_type;
+  longlong   def_value;                 /* Default value */
+  longlong   min_value;                 /* Min allowed value */
+  longlong   max_value;                 /* Max allowed value */
+  longlong   sub_size;                  /* Subtract this from given value */
+  long       block_size;                /* Value should be a mult. of this */
+  int        app_type;                  /* To be used by an application */
+};
+
+typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
+typedef void (* my_error_reporter) (enum loglevel level, const char *format, ... );
+
+extern char *disabled_my_option;
+extern my_bool my_getopt_print_errors;
+extern my_error_reporter my_getopt_error_reporter;
+
+extern int handle_options (int *argc, char ***argv, 
+			   const struct my_option *longopts, my_get_one_option);
+extern void my_print_help(const struct my_option *options);
+extern void my_print_variables(const struct my_option *options);
+extern void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint,
+							   const struct my_option *));
+
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
+                                 bool *fixed);
+my_bool getopt_compare_strings(const char *s, const char *t, uint length);
+
+C_MODE_END
+
+#endif /* _my_getopt_h */
+
diff --git a/dep/include/mysql/my_global.h b/dep/include/mysql/my_global.h
new file mode 100644
index 000000000..08877300d
--- /dev/null
+++ b/dep/include/mysql/my_global.h
@@ -0,0 +1,1354 @@
+/* Copyright (C) 2000-2003 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* This is the include file that should be included 'first' in every C file. */
+
+#ifndef _global_h
+#define _global_h
+
+#ifndef EMBEDDED_LIBRARY
+#define HAVE_REPLICATION
+#define HAVE_EXTERNAL_CLIENT
+#endif
+
+#if defined( __EMX__) && !defined( MYSQL_SERVER)
+/* moved here to use below VOID macro redefinition */
+#define INCL_BASE
+#define INCL_NOPMAPI
+#include 
+#endif /* __EMX__ */
+
+#ifdef __CYGWIN__
+/* We use a Unix API, so pretend it's not Windows */
+#undef WIN
+#undef WIN32
+#undef _WIN
+#undef _WIN32
+#undef _WIN64
+#undef __WIN__
+#undef __WIN32__
+#define HAVE_ERRNO_AS_DEFINE
+#endif /* __CYGWIN__ */
+
+#if defined(__QNXNTO__) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 1024         /* Max number of file descriptor bits in
+                                   fd_set, used when calling 'select'
+                                   Must be defined before including
+                                   "sys/select.h" and "sys/time.h"
+                                 */
+#endif
+
+
+/* to make command line shorter we'll define USE_PRAGMA_INTERFACE here */
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#define USE_PRAGMA_INTERFACE
+#endif
+
+#if defined(i386) && !defined(__i386__)
+#define __i386__
+#endif
+
+/* Macros to make switching between C and C++ mode easier */
+#ifdef __cplusplus
+#define C_MODE_START    extern "C" {
+#define C_MODE_END	}
+#else
+#define C_MODE_START
+#define C_MODE_END
+#endif
+
+#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
+#include 
+#elif defined(OS2)
+#include 
+#elif defined(__NETWARE__)
+#include 
+#include 
+#if defined(__cplusplus) && defined(inline)
+#undef inline				/* fix configure problem */
+#endif
+#else
+#include 
+#if defined(__cplusplus) && defined(inline)
+#undef inline				/* fix configure problem */
+#endif
+#endif /* _WIN32... */
+
+/* Make it easier to add conditionl code for windows */
+#ifdef __WIN__
+#define IF_WIN(A,B) (A)
+#else
+#define IF_WIN(A,B) (B)
+#endif
+
+
+/* Some defines to avoid ifdefs in the code */
+#ifndef NETWARE_YIELD
+#define NETWARE_YIELD
+#define NETWARE_SET_SCREEN_MODE(A)
+#endif
+
+/* Workaround for _LARGE_FILES and _LARGE_FILE_API incompatibility on AIX */
+#if defined(_AIX) && defined(_LARGE_FILE_API)
+#undef _LARGE_FILE_API
+#endif
+
+/*
+  The macros below are used to allow build of Universal/fat binaries of
+  MySQL and MySQL applications under darwin. 
+*/
+#if defined(__APPLE__) && defined(__MACH__)
+#  undef SIZEOF_CHARP 
+#  undef SIZEOF_SHORT 
+#  undef SIZEOF_INT 
+#  undef SIZEOF_LONG 
+#  undef SIZEOF_LONG_LONG 
+#  undef SIZEOF_OFF_T 
+#  undef WORDS_BIGENDIAN
+#  define SIZEOF_SHORT 2
+#  define SIZEOF_INT 4
+#  define SIZEOF_LONG_LONG 8
+#  define SIZEOF_OFF_T 8
+#  if defined(__i386__) || defined(__ppc__)
+#    define SIZEOF_CHARP 4
+#    define SIZEOF_LONG 4
+#  elif defined(__x86_64__) || defined(__ppc64__)
+#    define SIZEOF_CHARP 8
+#    define SIZEOF_LONG 8
+#  else
+#    error Building FAT binary for an unknown architecture.
+#  endif
+#  if defined(__ppc__) || defined(__ppc64__)
+#    define WORDS_BIGENDIAN
+#  endif
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+
+/*
+  The macros below are borrowed from include/linux/compiler.h in the
+  Linux kernel. Use them to indicate the likelyhood of the truthfulness
+  of a condition. This serves two purposes - newer versions of gcc will be
+  able to optimize for branch predication, which could yield siginficant
+  performance gains in frequently executed sections of the code, and the
+  other reason to use them is for documentation
+*/
+
+#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
+#define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define likely(x)	__builtin_expect((x),1)
+#define unlikely(x)	__builtin_expect((x),0)
+
+
+/* Fix problem with S_ISLNK() on Linux */
+#if defined(TARGET_OS_LINUX) || defined(__GLIBC__)
+#undef  _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+/*
+  Temporary solution to solve bug#7156. Include "sys/types.h" before
+  the thread headers, else the function madvise() will not be defined
+*/
+#if defined(HAVE_SYS_TYPES_H) && ( defined(sun) || defined(__sun) )
+#include 
+#endif
+
+/* The client defines this to avoid all thread code */
+#if defined(UNDEF_THREADS_HACK)
+#undef THREAD
+#undef HAVE_mit_thread
+#undef HAVE_LINUXTHREADS
+#undef HAVE_NPTL
+#undef HAVE_UNIXWARE7_THREADS
+#endif
+
+#ifdef HAVE_THREADS_WITHOUT_SOCKETS
+/* MIT pthreads does not work with unix sockets */
+#undef HAVE_SYS_UN_H
+#endif
+
+#define __EXTENSIONS__ 1	/* We want some extension */
+#ifndef __STDC_EXT__
+#define __STDC_EXT__ 1          /* To get large file support on hpux */
+#endif
+
+/*
+  Solaris 9 include file  refers to X/Open document
+
+    System Interfaces and Headers, Issue 5
+
+  saying we should define _XOPEN_SOURCE=500 to get POSIX.1c prototypes,
+  but apparently other systems (namely FreeBSD) don't agree.
+
+  On a newer Solaris 10, the above file recognizes also _XOPEN_SOURCE=600.
+  Furthermore, it tests that if a program requires older standard
+  (_XOPEN_SOURCE<600 or _POSIX_C_SOURCE<200112L) it cannot be
+  run on a new compiler (that defines _STDC_C99) and issues an #error.
+  It's also an #error if a program requires new standard (_XOPEN_SOURCE=600
+  or _POSIX_C_SOURCE=200112L) and a compiler does not define _STDC_C99.
+
+  To add more to this mess, Sun Studio C compiler defines _STDC_C99 while
+  C++ compiler does not!
+
+  So, in a desperate attempt to get correct prototypes for both
+  C and C++ code, we define either _XOPEN_SOURCE=600 or _XOPEN_SOURCE=500
+  depending on the compiler's announced C standard support.
+
+  Cleaner solutions are welcome.
+*/
+#ifdef __sun
+#if __STDC_VERSION__ - 0 >= 199901L
+#define _XOPEN_SOURCE 600
+#else
+#define _XOPEN_SOURCE 500
+#endif
+#endif
+
+#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
+#ifndef _POSIX_PTHREAD_SEMANTICS
+#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
+#endif
+
+#if !defined(SCO)
+#define _REENTRANT	1	/* Some thread libraries require this */
+#endif
+#if !defined(_THREAD_SAFE) && !defined(_AIX)
+#define _THREAD_SAFE            /* Required for OSF1 */
+#endif
+#ifndef HAVE_mit_thread
+#ifdef HAVE_UNIXWARE7_THREADS
+#include 
+#else
+#if defined(HPUX10) || defined(HPUX11)
+C_MODE_START			/* HPUX needs this, signal.h bug */
+#include 
+C_MODE_END
+#else
+#include 		/* AIX must have this included first */
+#endif
+#endif /* HAVE_UNIXWARE7_THREADS */
+#endif /* HAVE_mit_thread */
+#if !defined(SCO) && !defined(_REENTRANT)
+#define _REENTRANT	1	/* Threads requires reentrant code */
+#endif
+#endif /* THREAD */
+
+/* Go around some bugs in different OS and compilers */
+#ifdef _AIX			/* By soren@t.dk */
+#define _H_STRINGS
+#define _SYS_STREAM_H
+/* #define _AIX32_CURSES */	/* XXX: this breaks AIX 4.3.3 (others?). */
+#define ulonglong2double(A) my_ulonglong2double(A)
+#define my_off_t2double(A)  my_ulonglong2double(A)
+C_MODE_START
+double my_ulonglong2double(unsigned long long A);
+C_MODE_END
+#endif /* _AIX */
+
+#ifdef HAVE_BROKEN_SNPRINTF	/* HPUX 10.20 don't have this defined */
+#undef HAVE_SNPRINTF
+#endif
+#ifdef HAVE_BROKEN_PREAD
+/*
+  pread()/pwrite() are not 64 bit safe on HP-UX 11.0 without
+  installing the kernel patch PHKL_20349 or greater
+*/
+#undef HAVE_PREAD
+#undef HAVE_PWRITE
+#endif
+#if defined(HAVE_BROKEN_INLINE) && !defined(__cplusplus)
+#undef inline
+#define inline
+#endif
+
+#ifdef UNDEF_HAVE_GETHOSTBYNAME_R		/* For OSF4.x */
+#undef HAVE_GETHOSTBYNAME_R
+#endif
+#ifdef UNDEF_HAVE_INITGROUPS			/* For AIX 4.3 */
+#undef HAVE_INITGROUPS
+#endif
+
+/* gcc/egcs issues */
+
+#if defined(__GNUC) && defined(__EXCEPTIONS)
+#error "Please add -fno-exceptions to CXXFLAGS and reconfigure/recompile"
+#endif
+
+
+/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */
+#if SIZEOF_LONG == 4 && defined(__LONG_MAX__) && (__GNUC__ == 2 && __GNUC_MINOR__ == 8)
+#undef __LONG_MAX__             /* Is a longlong value in gcc 2.8.0 ??? */
+#define __LONG_MAX__ 2147483647
+#endif
+
+/* egcs 1.1.2 has a problem with memcpy on Alpha */
+#if defined(__GNUC__) && defined(__alpha__) && ! (__GNUC__ > 2 || (__GNUC__ == 2 &&  __GNUC_MINOR__ >= 95))
+#define BAD_MEMCPY
+#endif
+
+#if defined(_lint) && !defined(lint)
+#define lint
+#endif
+#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
+#define _LONG_LONG 1		/* For AIX string library */
+#endif
+
+#ifndef stdin
+#include 
+#endif
+#ifdef HAVE_STDLIB_H
+#include 
+#endif
+#ifdef HAVE_STDDEF_H
+#include 
+#endif
+
+#include 
+#ifdef HAVE_LIMITS_H
+#include 
+#endif
+#ifdef HAVE_FLOAT_H
+#include 
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include 
+#endif
+#ifdef HAVE_FCNTL_H
+#include 
+#endif
+#ifdef HAVE_SYS_TIMEB_H
+#include 				/* Avoid warnings on SCO */
+#endif
+#if TIME_WITH_SYS_TIME
+# include 
+# include 
+#else
+# if HAVE_SYS_TIME_H
+#  include 
+# else
+#  include 
+# endif
+#endif /* TIME_WITH_SYS_TIME */
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
+#undef HAVE_ALLOCA
+#undef HAVE_ALLOCA_H
+#endif
+#ifdef HAVE_ALLOCA_H
+#include 
+#endif
+#ifdef HAVE_ATOMIC_ADD
+#define new my_arg_new
+#define need_to_restore_new 1
+C_MODE_START
+#include 
+C_MODE_END
+#ifdef need_to_restore_new /* probably safer than #ifdef new */
+#undef new
+#undef need_to_restore_new
+#endif
+#endif
+#include 				/* Recommended by debian */
+/* We need the following to go around a problem with openssl on solaris */
+#if defined(HAVE_CRYPT_H)
+#include 
+#endif
+
+/*
+  A lot of our programs uses asserts, so better to always include it
+  This also fixes a problem when people uses DBUG_ASSERT without including
+  assert.h
+*/
+#include 
+
+/* Go around some bugs in different OS and compilers */
+#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
+#include 		/* HPUX 10.20 defines ulong here. UGLY !!! */
+#define HAVE_ULONG
+#endif
+#ifdef DONT_USE_FINITE		/* HPUX 11.x has is_finite() */
+#undef HAVE_FINITE
+#endif
+#if defined(HPUX10) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
+/* Fix bug in setrlimit */
+#undef setrlimit
+#define setrlimit cma_setrlimit64
+#endif
+/* Declare madvise where it is not declared for C++, like Solaris */
+#if HAVE_MADVISE && !HAVE_DECL_MADVISE && defined(__cplusplus)
+extern "C" int madvise(void *addr, size_t len, int behav);
+#endif
+
+#ifdef __QNXNTO__
+/* This has to be after include limits.h */
+#define HAVE_ERRNO_AS_DEFINE
+#define HAVE_FCNTL_LOCK
+#undef  HAVE_FINITE
+#undef  LONGLONG_MIN            /* These get wrongly defined in QNX 6.2 */
+#undef  LONGLONG_MAX            /* standard system library 'limits.h' */
+#ifdef __cplusplus
+#ifndef HAVE_RINT
+#define HAVE_RINT
+#endif                          /* rint() and isnan() functions are not */
+#define rint(a) std::rint(a)    /* visible in C++ scope due to an error */
+#define isnan(a) std::isnan(a)  /* in the usr/include/math.h on QNX     */
+#endif
+#endif
+
+/* We can not live without the following defines */
+
+#define USE_MYFUNC 1		/* Must use syscall indirection */
+#define MASTER 1		/* Compile without unireg */
+#define ENGLISH 1		/* Messages in English */
+#define POSIX_MISTAKE 1		/* regexp: Fix stupid spec error */
+#define USE_REGEX 1		/* We want the use the regex library */
+/* Do not define for ultra sparcs */
+#ifndef OS2
+#define USE_BMOVE512 1		/* Use this unless system bmove is faster */
+#endif
+
+#define QUOTE_ARG(x)		#x	/* Quote argument (before cpp) */
+#define STRINGIFY_ARG(x) QUOTE_ARG(x)	/* Quote argument, after cpp */
+
+/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
+#ifdef I_AM_PARANOID
+#define DONT_ALLOW_USER_CHANGE 1
+#define DONT_USE_MYSQL_PWD 1
+#endif
+
+/* Does the system remember a signal handler after a signal ? */
+#ifndef HAVE_BSD_SIGNALS
+#define DONT_REMEMBER_SIGNAL
+#endif
+
+/* Define void to stop lint from generating "null effekt" comments */
+#ifndef DONT_DEFINE_VOID
+#ifdef _lint
+int	__void__;
+#define VOID(X)		(__void__ = (int) (X))
+#else
+#undef VOID
+#define VOID(X)		(X)
+#endif
+#endif /* DONT_DEFINE_VOID */
+
+#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
+#define LINT_INIT(var)	var=0			/* No uninitialize-warning */
+#else
+#define LINT_INIT(var)
+#endif
+
+#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(HAVE_purify)
+#define PURIFY_OR_LINT_INIT(var) var=0
+#else
+#define PURIFY_OR_LINT_INIT(var)
+#endif
+
+/* Define some useful general macros */
+#if !defined(max)
+#define max(a, b)	((a) > (b) ? (a) : (b))
+#define min(a, b)	((a) < (b) ? (a) : (b))
+#endif
+
+#if defined(__EMX__) || !defined(HAVE_UINT)
+#undef HAVE_UINT
+#define HAVE_UINT
+typedef unsigned int uint;
+typedef unsigned short ushort;
+#endif
+
+#define CMP_NUM(a,b)    (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
+#define sgn(a)		(((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
+#define swap_variables(t, a, b) { register t dummy; dummy= a; a= b; b= dummy; }
+#define test(a)		((a) ? 1 : 0)
+#define set_if_bigger(a,b)  do { if ((a) < (b)) (a)=(b); } while(0)
+#define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
+#define test_all_bits(a,b) (((a) & (b)) == (b))
+#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
+#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
+#ifndef HAVE_RINT
+#define rint(A) floor((A)+(((A) < 0)? -0.5 : 0.5))
+#endif
+
+/* Define some general constants */
+#ifndef TRUE
+#define TRUE		(1)	/* Logical true */
+#define FALSE		(0)	/* Logical false */
+#endif
+
+#if defined(__GNUC__)
+#define function_volatile	volatile
+#define my_reinterpret_cast(A) reinterpret_cast
+#define my_const_cast(A) const_cast
+# ifndef GCC_VERSION
+#  define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+# endif
+#elif !defined(my_reinterpret_cast)
+#define my_reinterpret_cast(A) (A)
+#define my_const_cast(A) (A)
+#endif
+
+#include 
+
+/*
+  Wen using the embedded library, users might run into link problems,
+  duplicate declaration of __cxa_pure_virtual, solved by declaring it a
+  weak symbol.
+*/
+#if defined(USE_MYSYS_NEW) && ! defined(DONT_DECLARE_CXA_PURE_VIRTUAL)
+C_MODE_START
+int __cxa_pure_virtual () __attribute__ ((weak));
+C_MODE_END
+#endif
+
+/* From old s-system.h */
+
+/*
+  Support macros for non ansi & other old compilers. Since such
+  things are no longer supported we do nothing. We keep then since
+  some of our code may still be needed to upgrade old customers.
+*/
+#define _VARARGS(X) X
+#define _STATIC_VARARGS(X) X
+#define _PC(X)	X
+
+#if defined(DBUG_ON) && defined(DBUG_OFF)
+#undef DBUG_OFF
+#endif
+
+#if defined(_lint) && !defined(DBUG_OFF)
+#define DBUG_OFF
+#endif
+
+#include 
+
+#define MIN_ARRAY_SIZE	0	/* Zero or One. Gcc allows zero*/
+#define ASCII_BITS_USED 8	/* Bit char used */
+#define NEAR_F			/* No near function handling */
+
+/* Some types that is different between systems */
+
+typedef int	File;		/* File descriptor */
+#ifndef Socket_defined
+typedef int	my_socket;	/* File descriptor for sockets */
+#define INVALID_SOCKET -1
+#endif
+/* Type for fuctions that handles signals */
+#define sig_handler RETSIGTYPE
+C_MODE_START
+typedef void	(*sig_return)();/* Returns type from signal */
+C_MODE_END
+#if defined(__GNUC__) && !defined(_lint)
+typedef char	pchar;		/* Mixed prototypes can take char */
+typedef char	puchar;		/* Mixed prototypes can take char */
+typedef char	pbool;		/* Mixed prototypes can take char */
+typedef short	pshort;		/* Mixed prototypes can take short int */
+typedef float	pfloat;		/* Mixed prototypes can take float */
+#else
+typedef int	pchar;		/* Mixed prototypes can't take char */
+typedef uint	puchar;		/* Mixed prototypes can't take char */
+typedef int	pbool;		/* Mixed prototypes can't take char */
+typedef int	pshort;		/* Mixed prototypes can't take short int */
+typedef double	pfloat;		/* Mixed prototypes can't take float */
+#endif
+C_MODE_START
+typedef int	(*qsort_cmp)(const void *,const void *);
+typedef int	(*qsort_cmp2)(void*, const void *,const void *);
+C_MODE_END
+#ifdef HAVE_mit_thread
+#define qsort_t void
+#undef QSORT_TYPE_IS_VOID
+#define QSORT_TYPE_IS_VOID
+#else
+#define qsort_t RETQSORTTYPE	/* Broken GCC cant handle typedef !!!! */
+#endif
+#ifdef HAVE_mit_thread
+#define size_socket socklen_t	/* Type of last arg to accept */
+#else
+#ifdef HAVE_SYS_SOCKET_H
+#include 
+#endif
+typedef SOCKET_SIZE_TYPE size_socket;
+#endif
+
+#ifndef SOCKOPT_OPTLEN_TYPE
+#define SOCKOPT_OPTLEN_TYPE size_socket
+#endif
+
+/* file create flags */
+
+#ifndef O_SHARE			/* Probably not windows */
+#define O_SHARE		0	/* Flag to my_open for shared files */
+#ifndef O_BINARY
+#define O_BINARY	0	/* Flag to my_open for binary files */
+#endif
+#ifndef FILE_BINARY
+#define FILE_BINARY	O_BINARY /* Flag to my_fopen for binary streams */
+#endif
+#ifdef HAVE_FCNTL
+#define HAVE_FCNTL_LOCK
+#define F_TO_EOF	0L	/* Param to lockf() to lock rest of file */
+#endif
+#endif /* O_SHARE */
+
+#ifndef O_TEMPORARY
+#define O_TEMPORARY	0
+#endif
+#ifndef O_SHORT_LIVED
+#define O_SHORT_LIVED	0
+#endif
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW      0
+#endif
+
+/* additional file share flags for win32 */
+#ifdef __WIN__
+#define _SH_DENYRWD     0x110    /* deny read/write mode & delete */
+#define _SH_DENYWRD     0x120    /* deny write mode & delete      */
+#define _SH_DENYRDD     0x130    /* deny read mode & delete       */
+#define _SH_DENYDEL     0x140    /* deny delete only              */
+#endif /* __WIN__ */
+
+
+/* #define USE_RECORD_LOCK	*/
+
+	/* Unsigned types supported by the compiler */
+#define UNSINT8			/* unsigned int8 (char) */
+#define UNSINT16		/* unsigned int16 */
+#define UNSINT32		/* unsigned int32 */
+
+	/* General constants */
+#define SC_MAXWIDTH	256	/* Max width of screen (for error messages) */
+#define FN_LEN		256	/* Max file name len */
+#define FN_HEADLEN	253	/* Max length of filepart of file name */
+#define FN_EXTLEN	20	/* Max length of extension (part of FN_LEN) */
+#define FN_REFLEN	512	/* Max length of full path-name */
+#define FN_EXTCHAR	'.'
+#define FN_HOMELIB	'~'	/* ~/ is used as abbrev for home dir */
+#define FN_CURLIB	'.'	/* ./ is used as abbrev for current dir */
+#define FN_PARENTDIR	".."	/* Parent directory; Must be a string */
+
+#ifndef FN_LIBCHAR
+#ifdef __EMX__
+#define FN_LIBCHAR	'\\'
+#define FN_ROOTDIR	"\\"
+#else
+#define FN_LIBCHAR	'/'
+#define FN_ROOTDIR	"/"
+#endif
+#endif
+#define MY_NFILE	64	/* This is only used to save filenames */
+#ifndef OS_FILE_LIMIT
+#define OS_FILE_LIMIT	65535
+#endif
+
+/* #define EXT_IN_LIBNAME     */
+/* #define FN_NO_CASE_SENCE   */
+/* #define FN_UPPER_CASE TRUE */
+
+/*
+  Io buffer size; Must be a power of 2 and a multiple of 512. May be
+  smaller what the disk page size. This influences the speed of the
+  isam btree library. eg to big to slow.
+*/
+#define IO_SIZE			4096
+/*
+  How much overhead does malloc have. The code often allocates
+  something like 1024-MALLOC_OVERHEAD bytes
+*/
+#ifdef SAFEMALLOC
+#define MALLOC_OVERHEAD (8+24+4)
+#else
+#define MALLOC_OVERHEAD 8
+#endif
+	/* get memory in huncs */
+#define ONCE_ALLOC_INIT		(uint) (4096-MALLOC_OVERHEAD)
+	/* Typical record cash */
+#define RECORD_CACHE_SIZE	(uint) (64*1024-MALLOC_OVERHEAD)
+	/* Typical key cash */
+#define KEY_CACHE_SIZE		(uint) (8*1024*1024-MALLOC_OVERHEAD)
+	/* Default size of a key cache block  */
+#define KEY_CACHE_BLOCK_SIZE	(uint) 1024
+
+
+	/* Some things that this system doesn't have */
+
+#define NO_HASH			/* Not needed anymore */
+#ifdef __WIN__
+#define NO_DIR_LIBRARY		/* Not standar dir-library */
+#define USE_MY_STAT_STRUCT	/* For my_lib */
+#endif
+
+/* Some defines of functions for portability */
+
+#undef remove		/* Crashes MySQL on SCO 5.0.0 */
+#ifndef __WIN__
+#ifdef OS2
+#define closesocket(A)	soclose(A)
+#else
+#define closesocket(A)	close(A)
+#endif
+#ifndef ulonglong2double
+#define ulonglong2double(A) ((double) (ulonglong) (A))
+#define my_off_t2double(A)  ((double) (my_off_t) (A))
+#endif
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#define ulong_to_double(X) ((double) (ulong) (X))
+#define SET_STACK_SIZE(X)	/* Not needed on real machines */
+
+#if !defined(HAVE_mit_thread) && !defined(HAVE_STRTOK_R)
+#define strtok_r(A,B,C) strtok((A),(B))
+#endif
+
+/* Remove some things that mit_thread break or doesn't support */
+#if defined(HAVE_mit_thread) && defined(THREAD)
+#undef HAVE_PREAD
+#undef HAVE_REALPATH
+#undef HAVE_MLOCK
+#undef HAVE_TEMPNAM				/* Use ours */
+#undef HAVE_PTHREAD_SETPRIO
+#undef HAVE_FTRUNCATE
+#undef HAVE_READLINK
+#endif
+
+/* This is from the old m-machine.h file */
+
+#if SIZEOF_LONG_LONG > 4
+#define HAVE_LONG_LONG 1
+#endif
+
+/*
+  Some pre-ANSI-C99 systems like AIX 5.1 and Linux/GCC 2.95 define
+  ULONGLONG_MAX, LONGLONG_MIN, LONGLONG_MAX; we use them if they're defined.
+  Also on Windows we define these constants by hand in config-win.h.
+*/
+
+#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
+#define LONGLONG_MIN	((long long) 0x8000000000000000LL)
+#define LONGLONG_MAX	((long long) 0x7FFFFFFFFFFFFFFFLL)
+#endif
+
+#if defined(HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)
+/* First check for ANSI C99 definition: */
+#ifdef ULLONG_MAX
+#define ULONGLONG_MAX  ULLONG_MAX
+#else
+#define ULONGLONG_MAX ((unsigned long long)(~0ULL))
+#endif
+#endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/
+
+#define INT_MIN32       (~0x7FFFFFFFL)
+#define INT_MAX32       0x7FFFFFFFL
+#define UINT_MAX32      0xFFFFFFFFL
+#define INT_MIN24       (~0x007FFFFF)
+#define INT_MAX24       0x007FFFFF
+#define UINT_MAX24      0x00FFFFFF
+#define INT_MIN16       (~0x7FFF)
+#define INT_MAX16       0x7FFF
+#define UINT_MAX16      0xFFFF
+#define INT_MIN8        (~0x7F)
+#define INT_MAX8        0x7F
+#define UINT_MAX8       0xFF
+
+/* From limits.h instead */
+#ifndef DBL_MIN
+#define DBL_MIN		4.94065645841246544e-324
+#define FLT_MIN		((float)1.40129846432481707e-45)
+#endif
+#ifndef DBL_MAX
+#define DBL_MAX		1.79769313486231470e+308
+#define FLT_MAX		((float)3.40282346638528860e+38)
+#endif
+
+#ifndef HAVE_FINITE
+#define finite(x) (1.0 / fabs(x) > 0.0)
+#endif
+
+#ifndef HAVE_ISNAN
+#define isnan(x) ((x) != (x))
+#endif
+
+#ifdef HAVE_ISINF
+/* isinf() can be used in both C and C++ code */
+#define my_isinf(X) isinf(X)
+#else
+#define my_isinf(X) (!finite(X) && !isnan(X))
+#endif
+
+/* Define missing math constants. */
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_E
+#define M_E 2.7182818284590452354
+#endif
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+
+/*
+  Max size that must be added to a so that we know Size to make
+  adressable obj.
+*/
+#if SIZEOF_CHARP == 4
+typedef long		my_ptrdiff_t;
+#else
+typedef long long	my_ptrdiff_t;
+#endif
+
+#define MY_ALIGN(A,L)	(((A) + (L) - 1) & ~((L) - 1))
+#define ALIGN_SIZE(A)	MY_ALIGN((A),sizeof(double))
+/* Size to make adressable obj. */
+#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t)))
+			 /* Offset of field f in structure t */
+#define OFFSET(t, f)	((size_t)(char *)&((t *)0)->f)
+#define ADD_TO_PTR(ptr,size,type) (type) ((byte*) (ptr)+size)
+#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((byte*) (A) - (byte*) (B))
+
+/*
+  Custom version of standard offsetof() macro which can be used to get
+  offsets of members in class for non-POD types (according to the current
+  version of C++ standard offsetof() macro can't be used in such cases and
+  attempt to do so causes warnings to be emitted, OTOH in many cases it is
+  still OK to assume that all instances of the class has the same offsets
+  for the same members).
+
+  This is temporary solution which should be removed once File_parser class
+  and related routines are refactored.
+*/
+
+#define my_offsetof(TYPE, MEMBER) \
+        ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
+
+#define NullS		(char *) 0
+/* Nowdays we do not support MessyDos */
+#ifndef NEAR
+#define NEAR				/* Who needs segments ? */
+#define FAR				/* On a good machine */
+#ifndef HUGE_PTR
+#define HUGE_PTR
+#endif
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+/* This was  _System _Export but caused a lot of warnings on _AIX43 */
+#define STDCALL
+#elif !defined( STDCALL)
+#define STDCALL
+#endif
+
+/* Typdefs for easyier portability */
+
+#if defined(VOIDTYPE)
+typedef void	*gptr;		/* Generic pointer */
+#else
+typedef char	*gptr;		/* Generic pointer */
+#endif
+#ifndef HAVE_INT_8_16_32
+typedef signed char int8;       /* Signed integer >= 8  bits */
+typedef short	int16;		/* Signed integer >= 16 bits */
+#endif
+#ifndef HAVE_UCHAR
+typedef unsigned char	uchar;	/* Short for unsigned char */
+#endif
+typedef unsigned char	uint8;	/* Short for unsigned integer >= 8  bits */
+typedef unsigned short	uint16; /* Short for unsigned integer >= 16 bits */
+
+#if SIZEOF_INT == 4
+#ifndef HAVE_INT_8_16_32
+typedef int		int32;
+#endif
+typedef unsigned int	uint32; /* Short for unsigned integer >= 32 bits */
+#elif SIZEOF_LONG == 4
+#ifndef HAVE_INT_8_16_32
+typedef long		int32;
+#endif
+typedef unsigned long	uint32; /* Short for unsigned integer >= 32 bits */
+#else
+#error "Neither int or long is of 4 bytes width"
+#endif
+
+#if !defined(HAVE_ULONG) && !defined(TARGET_OS_LINUX) && !defined(__USE_MISC)
+typedef unsigned long	ulong;		  /* Short for unsigned long */
+#endif
+#ifndef longlong_defined
+/* 
+  Using [unsigned] long long is preferable as [u]longlong because we use 
+  [unsigned] long long unconditionally in many places, 
+  for example in constants with [U]LL suffix.
+*/
+#if defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8
+typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
+typedef long long int	longlong;
+#else
+typedef unsigned long	ulonglong;	  /* ulong or unsigned long long */
+typedef long		longlong;
+#endif
+#endif
+
+#if defined(NO_CLIENT_LONG_LONG)
+typedef unsigned long my_ulonglong;
+#elif defined (__WIN__)
+typedef unsigned __int64 my_ulonglong;
+#else
+typedef unsigned long long my_ulonglong;
+#endif
+
+#ifdef USE_RAID
+/*
+  The following is done with a if to not get problems with pre-processors
+  with late define evaluation
+*/
+#if SIZEOF_OFF_T == 4
+#define SYSTEM_SIZEOF_OFF_T 4
+#else
+#define SYSTEM_SIZEOF_OFF_T 8
+#endif
+#undef  SIZEOF_OFF_T
+#define SIZEOF_OFF_T	    8
+#else
+#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
+#endif /* USE_RAID */
+
+#if SIZEOF_OFF_T > 4
+typedef ulonglong my_off_t;
+#else
+typedef unsigned long my_off_t;
+#endif
+#define MY_FILEPOS_ERROR	(~(my_off_t) 0)
+#if !defined(__WIN__) && !defined(OS2)
+typedef off_t os_off_t;
+#endif
+
+#if defined(__WIN__)
+#define socket_errno	WSAGetLastError()
+#define SOCKET_EINTR	WSAEINTR
+#define SOCKET_EAGAIN	WSAEINPROGRESS
+#define SOCKET_ETIMEDOUT WSAETIMEDOUT
+#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
+#define SOCKET_EADDRINUSE WSAEADDRINUSE
+#define SOCKET_ENFILE	ENFILE
+#define SOCKET_EMFILE	EMFILE
+#elif defined(OS2)
+#define socket_errno	sock_errno()
+#define SOCKET_EINTR	SOCEINTR
+#define SOCKET_EAGAIN	SOCEINPROGRESS
+#define SOCKET_ETIMEDOUT SOCKET_EINTR
+#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK
+#define SOCKET_EADDRINUSE SOCEADDRINUSE
+#define SOCKET_ENFILE	SOCENFILE
+#define SOCKET_EMFILE	SOCEMFILE
+#define closesocket(A)	soclose(A)
+#else /* Unix */
+#define socket_errno	errno
+#define closesocket(A)	close(A)
+#define SOCKET_EINTR	EINTR
+#define SOCKET_EAGAIN	EAGAIN
+#define SOCKET_ETIMEDOUT SOCKET_EINTR
+#define SOCKET_EWOULDBLOCK EWOULDBLOCK
+#define SOCKET_EADDRINUSE EADDRINUSE
+#define SOCKET_ENFILE	ENFILE
+#define SOCKET_EMFILE	EMFILE
+#endif
+
+typedef uint8		int7;	/* Most effective integer 0 <= x <= 127 */
+typedef short		int15;	/* Most effective integer 0 <= x <= 32767 */
+typedef char		*my_string; /* String of characters */
+typedef unsigned long	size_s; /* Size of strings (In string-funcs) */
+typedef int		myf;	/* Type of MyFlags in my_funcs */
+#ifndef byte_defined
+typedef char		byte;	/* Smallest addressable unit */
+#endif
+typedef char		my_bool; /* Small bool */
+#if !defined(bool) && !defined(bool_defined) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
+typedef char		bool;	/* Ordinary boolean values 0 1 */
+#endif
+	/* Macros for converting *constants* to the right type */
+#define INT8(v)		(int8) (v)
+#define INT16(v)	(int16) (v)
+#define INT32(v)	(int32) (v)
+#define MYF(v)		(myf) (v)
+
+#ifndef LL
+#ifdef HAVE_LONG_LONG
+#define LL(A) A ## LL
+#else
+#define LL(A) A ## L
+#endif
+#endif
+
+#ifndef ULL
+#ifdef HAVE_LONG_LONG
+#define ULL(A) A ## ULL
+#else
+#define ULL(A) A ## UL
+#endif
+#endif
+
+/*
+  Defines to make it possible to prioritize register assignments. No
+  longer that important with modern compilers.
+*/
+#ifndef USING_X
+#define reg1 register
+#define reg2 register
+#define reg3 register
+#define reg4 register
+#define reg5 register
+#define reg6 register
+#define reg7 register
+#define reg8 register
+#define reg9 register
+#define reg10 register
+#define reg11 register
+#define reg12 register
+#define reg13 register
+#define reg14 register
+#define reg15 register
+#define reg16 register
+#endif
+
+/*
+  Sometimes we want to make sure that the variable is not put into
+  a register in debugging mode so we can see its value in the core
+*/
+
+#ifndef DBUG_OFF
+#define dbug_volatile volatile
+#else
+#define dbug_volatile
+#endif
+
+/* Defines for time function */
+#define SCALE_SEC	100
+#define SCALE_USEC	10000
+#define MY_HOW_OFTEN_TO_ALARM	2	/* How often we want info on screen */
+#define MY_HOW_OFTEN_TO_WRITE	1000	/* How often we want info on screen */
+
+
+
+/*
+  Define-funktions for reading and storing in machine independent format
+  (low byte first)
+*/
+
+/* Optimized store functions for Intel x86 */
+#if defined(__i386__) && !defined(_WIN64)
+#define sint2korr(A)	(*((int16 *) (A)))
+#define sint3korr(A)	((int32) ((((uchar) (A)[2]) & 128) ? \
+				  (((uint32) 255L << 24) | \
+				   (((uint32) (uchar) (A)[2]) << 16) |\
+				   (((uint32) (uchar) (A)[1]) << 8) | \
+				   ((uint32) (uchar) (A)[0])) : \
+				  (((uint32) (uchar) (A)[2]) << 16) |\
+				  (((uint32) (uchar) (A)[1]) << 8) | \
+				  ((uint32) (uchar) (A)[0])))
+#define sint4korr(A)	(*((long *) (A)))
+#define uint2korr(A)	(*((uint16 *) (A)))
+#ifdef HAVE_purify
+#define uint3korr(A)	(uint32) (((uint32) ((uchar) (A)[0])) +\
+				  (((uint32) ((uchar) (A)[1])) << 8) +\
+				  (((uint32) ((uchar) (A)[2])) << 16))
+#else
+/*
+   ATTENTION !
+   
+    Please, note, uint3korr reads 4 bytes (not 3) !
+    It means, that you have to provide enough allocated space !
+*/
+#define uint3korr(A)	(long) (*((unsigned int *) (A)) & 0xFFFFFF)
+#endif
+#define uint4korr(A)	(*((uint32 *) (A)))
+#define uint5korr(A)	((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+				    (((uint32) ((uchar) (A)[1])) << 8) +\
+				    (((uint32) ((uchar) (A)[2])) << 16) +\
+				    (((uint32) ((uchar) (A)[3])) << 24)) +\
+				    (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A)	(*((ulonglong *) (A)))
+#define sint8korr(A)	(*((longlong *) (A)))
+#define int2store(T,A)	*((uint16*) (T))= (uint16) (A)
+#define int3store(T,A)  do { *(T)=  (uchar) ((A));\
+                            *(T+1)=(uchar) (((uint) (A) >> 8));\
+                            *(T+2)=(uchar) (((A) >> 16)); } while (0)
+#define int4store(T,A)	*((long *) (T))= (long) (A)
+#define int5store(T,A)  do { *(T)= (uchar)((A));\
+                             *((T)+1)=(uchar) (((A) >> 8));\
+                             *((T)+2)=(uchar) (((A) >> 16));\
+                             *((T)+3)=(uchar) (((A) >> 24)); \
+                             *((T)+4)=(uchar) (((A) >> 32)); } while(0)
+#define int8store(T,A)	*((ulonglong *) (T))= (ulonglong) (A)
+
+typedef union {
+  double v;
+  long m[2];
+} doubleget_union;
+#define doubleget(V,M)	\
+do { doubleget_union _tmp; \
+     _tmp.m[0] = *((long*)(M)); \
+     _tmp.m[1] = *(((long*) (M))+1); \
+     (V) = _tmp.v; } while(0)
+#define doublestore(T,V) do { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
+			     *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; \
+                         } while (0)
+#define float4get(V,M)   do { *((float *) &(V)) = *((float*) (M)); } while(0)
+#define float8get(V,M)   doubleget((V),(M))
+#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
+#define floatstore(T,V)  memcpy((byte*)(T), (byte*)(&V),sizeof(float))
+#define floatget(V,M)    memcpy((byte*) &V,(byte*) (M),sizeof(float))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* __i386__ */
+
+#ifndef sint2korr
+/*
+  We're here if it's not a IA-32 architecture (Win32 and UNIX IA-32 defines
+  were done before)
+*/
+#define sint2korr(A)	(int16) (((int16) ((uchar) (A)[0])) +\
+				 ((int16) ((int16) (A)[1]) << 8))
+#define sint3korr(A)	((int32) ((((uchar) (A)[2]) & 128) ? \
+				  (((uint32) 255L << 24) | \
+				   (((uint32) (uchar) (A)[2]) << 16) |\
+				   (((uint32) (uchar) (A)[1]) << 8) | \
+				   ((uint32) (uchar) (A)[0])) : \
+				  (((uint32) (uchar) (A)[2]) << 16) |\
+				  (((uint32) (uchar) (A)[1]) << 8) | \
+				  ((uint32) (uchar) (A)[0])))
+#define sint4korr(A)	(int32) (((int32) ((uchar) (A)[0])) +\
+				(((int32) ((uchar) (A)[1]) << 8)) +\
+				(((int32) ((uchar) (A)[2]) << 16)) +\
+				(((int32) ((int16) (A)[3]) << 24)))
+#define sint8korr(A)	(longlong) uint8korr(A)
+#define uint2korr(A)	(uint16) (((uint16) ((uchar) (A)[0])) +\
+				  ((uint16) ((uchar) (A)[1]) << 8))
+#define uint3korr(A)	(uint32) (((uint32) ((uchar) (A)[0])) +\
+				  (((uint32) ((uchar) (A)[1])) << 8) +\
+				  (((uint32) ((uchar) (A)[2])) << 16))
+#define uint4korr(A)	(uint32) (((uint32) ((uchar) (A)[0])) +\
+				  (((uint32) ((uchar) (A)[1])) << 8) +\
+				  (((uint32) ((uchar) (A)[2])) << 16) +\
+				  (((uint32) ((uchar) (A)[3])) << 24))
+#define uint5korr(A)	((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+				    (((uint32) ((uchar) (A)[1])) << 8) +\
+				    (((uint32) ((uchar) (A)[2])) << 16) +\
+				    (((uint32) ((uchar) (A)[3])) << 24)) +\
+				    (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A)	((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+				    (((uint32) ((uchar) (A)[1])) << 8) +\
+				    (((uint32) ((uchar) (A)[2])) << 16) +\
+				    (((uint32) ((uchar) (A)[3])) << 24)) +\
+			(((ulonglong) (((uint32) ((uchar) (A)[4])) +\
+				    (((uint32) ((uchar) (A)[5])) << 8) +\
+				    (((uint32) ((uchar) (A)[6])) << 16) +\
+				    (((uint32) ((uchar) (A)[7])) << 24))) <<\
+				    32))
+#define int2store(T,A)       do { uint def_temp= (uint) (A) ;\
+                                  *((uchar*) (T))=  (uchar)(def_temp); \
+                                   *((uchar*) (T)+1)=(uchar)((def_temp >> 8)); \
+                             } while(0)
+#define int3store(T,A)       do { /*lint -save -e734 */\
+                                  *((uchar*)(T))=(uchar) ((A));\
+                                  *((uchar*) (T)+1)=(uchar) (((A) >> 8));\
+                                  *((uchar*)(T)+2)=(uchar) (((A) >> 16)); \
+                                  /*lint -restore */} while(0)
+#define int4store(T,A)       do { *((char *)(T))=(char) ((A));\
+                                  *(((char *)(T))+1)=(char) (((A) >> 8));\
+                                  *(((char *)(T))+2)=(char) (((A) >> 16));\
+                                  *(((char *)(T))+3)=(char) (((A) >> 24)); } while(0)
+#define int5store(T,A)       do { *((char *)(T))=((A));\
+                                  *(((char *)(T))+1)=(((A) >> 8));\
+                                  *(((char *)(T))+2)=(((A) >> 16));\
+                                  *(((char *)(T))+3)=(((A) >> 24)); \
+                                  *(((char *)(T))+4)=(((A) >> 32)); } while(0)
+#define int8store(T,A)       do { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \
+                                  int4store((T),def_temp); \
+                                  int4store((T+4),def_temp2); } while(0)
+#ifdef WORDS_BIGENDIAN
+#define float4store(T,A) do { *(T)= ((byte *) &A)[3];\
+                              *((T)+1)=(char) ((byte *) &A)[2];\
+                              *((T)+2)=(char) ((byte *) &A)[1];\
+                              *((T)+3)=(char) ((byte *) &A)[0]; } while(0)
+
+#define float4get(V,M)   do { float def_temp;\
+                              ((byte*) &def_temp)[0]=(M)[3];\
+                              ((byte*) &def_temp)[1]=(M)[2];\
+                              ((byte*) &def_temp)[2]=(M)[1];\
+                              ((byte*) &def_temp)[3]=(M)[0];\
+                              (V)=def_temp; } while(0)
+#define float8store(T,V) do { *(T)= ((byte *) &V)[7];\
+                              *((T)+1)=(char) ((byte *) &V)[6];\
+                              *((T)+2)=(char) ((byte *) &V)[5];\
+                              *((T)+3)=(char) ((byte *) &V)[4];\
+                              *((T)+4)=(char) ((byte *) &V)[3];\
+                              *((T)+5)=(char) ((byte *) &V)[2];\
+                              *((T)+6)=(char) ((byte *) &V)[1];\
+                              *((T)+7)=(char) ((byte *) &V)[0]; } while(0)
+
+#define float8get(V,M)   do { double def_temp;\
+                              ((byte*) &def_temp)[0]=(M)[7];\
+                              ((byte*) &def_temp)[1]=(M)[6];\
+                              ((byte*) &def_temp)[2]=(M)[5];\
+                              ((byte*) &def_temp)[3]=(M)[4];\
+                              ((byte*) &def_temp)[4]=(M)[3];\
+                              ((byte*) &def_temp)[5]=(M)[2];\
+                              ((byte*) &def_temp)[6]=(M)[1];\
+                              ((byte*) &def_temp)[7]=(M)[0];\
+                              (V) = def_temp; } while(0)
+#else
+#define float4get(V,M)   memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
+#define float4store(V,M) memcpy_fixed((byte*) V,(byte*) (&M),sizeof(float))
+
+#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
+#define doublestore(T,V) do { *(((char*)T)+0)=(char) ((byte *) &V)[4];\
+                              *(((char*)T)+1)=(char) ((byte *) &V)[5];\
+                              *(((char*)T)+2)=(char) ((byte *) &V)[6];\
+                              *(((char*)T)+3)=(char) ((byte *) &V)[7];\
+                              *(((char*)T)+4)=(char) ((byte *) &V)[0];\
+                              *(((char*)T)+5)=(char) ((byte *) &V)[1];\
+                              *(((char*)T)+6)=(char) ((byte *) &V)[2];\
+                              *(((char*)T)+7)=(char) ((byte *) &V)[3]; }\
+                         while(0)
+#define doubleget(V,M)   do { double def_temp;\
+                              ((byte*) &def_temp)[0]=(M)[4];\
+                              ((byte*) &def_temp)[1]=(M)[5];\
+                              ((byte*) &def_temp)[2]=(M)[6];\
+                              ((byte*) &def_temp)[3]=(M)[7];\
+                              ((byte*) &def_temp)[4]=(M)[0];\
+                              ((byte*) &def_temp)[5]=(M)[1];\
+                              ((byte*) &def_temp)[6]=(M)[2];\
+                              ((byte*) &def_temp)[7]=(M)[3];\
+                              (V) = def_temp; } while(0)
+#endif /* __FLOAT_WORD_ORDER */
+
+#define float8get(V,M)   doubleget((V),(M))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* WORDS_BIGENDIAN */
+
+#endif /* sint2korr */
+
+/*
+  Macro for reading 32-bit integer from network byte order (big-endian)
+  from unaligned memory location.
+*/
+#define int4net(A)        (int32) (((uint32) ((uchar) (A)[3]))        |\
+				  (((uint32) ((uchar) (A)[2])) << 8)  |\
+				  (((uint32) ((uchar) (A)[1])) << 16) |\
+				  (((uint32) ((uchar) (A)[0])) << 24))
+/*
+  Define-funktions for reading and storing in machine format from/to
+  short/long to/from some place in memory V should be a (not
+  register) variable, M is a pointer to byte
+*/
+
+#ifdef WORDS_BIGENDIAN
+
+#define ushortget(V,M)  do { V = (uint16) (((uint16) ((uchar) (M)[1]))+\
+                                 ((uint16) ((uint16) (M)[0]) << 8)); } while(0)
+#define shortget(V,M)   do { V = (short) (((short) ((uchar) (M)[1]))+\
+                                 ((short) ((short) (M)[0]) << 8)); } while(0)
+#define longget(V,M)    do { int32 def_temp;\
+                             ((byte*) &def_temp)[0]=(M)[0];\
+                             ((byte*) &def_temp)[1]=(M)[1];\
+                             ((byte*) &def_temp)[2]=(M)[2];\
+                             ((byte*) &def_temp)[3]=(M)[3];\
+                             (V)=def_temp; } while(0)
+#define ulongget(V,M)   do { uint32 def_temp;\
+                            ((byte*) &def_temp)[0]=(M)[0];\
+                            ((byte*) &def_temp)[1]=(M)[1];\
+                            ((byte*) &def_temp)[2]=(M)[2];\
+                            ((byte*) &def_temp)[3]=(M)[3];\
+                            (V)=def_temp; } while(0)
+#define shortstore(T,A) do { uint def_temp=(uint) (A) ;\
+                             *(((char*)T)+1)=(char)(def_temp); \
+                             *(((char*)T)+0)=(char)(def_temp >> 8); } while(0)
+#define longstore(T,A)  do { *(((char*)T)+3)=((A));\
+                             *(((char*)T)+2)=(((A) >> 8));\
+                             *(((char*)T)+1)=(((A) >> 16));\
+                             *(((char*)T)+0)=(((A) >> 24)); } while(0)
+
+#define floatget(V,M)    memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
+#define floatstore(T,V)  memcpy_fixed((byte*) (T),(byte*)(&V),sizeof(float))
+#define doubleget(V,M)	 memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
+#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
+#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
+#define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
+
+#else
+
+#define ushortget(V,M)	do { V = uint2korr(M); } while(0)
+#define shortget(V,M)	do { V = sint2korr(M); } while(0)
+#define longget(V,M)	do { V = sint4korr(M); } while(0)
+#define ulongget(V,M)   do { V = uint4korr(M); } while(0)
+#define shortstore(T,V) int2store(T,V)
+#define longstore(T,V)	int4store(T,V)
+#ifndef floatstore
+#define floatstore(T,V)  memcpy_fixed((byte*) (T),(byte*) (&V),sizeof(float))
+#define floatget(V,M)    memcpy_fixed((byte*) &V, (byte*) (M), sizeof(float))
+#endif
+#ifndef doubleget
+#define doubleget(V,M)	 memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
+#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
+#endif /* doubleget */
+#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
+#define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
+
+#endif /* WORDS_BIGENDIAN */
+
+/* sprintf does not always return the number of bytes :- */
+#ifdef SPRINTF_RETURNS_INT
+#define my_sprintf(buff,args) sprintf args
+#else
+#ifdef SPRINTF_RETURNS_PTR
+#define my_sprintf(buff,args) ((int)(sprintf args - buff))
+#else
+#define my_sprintf(buff,args) ((ulong) sprintf args, (ulong) strlen(buff))
+#endif
+#endif
+
+#ifndef THREAD
+#define thread_safe_increment(V,L) (V)++
+#define thread_safe_add(V,C,L)     (V)+=(C)
+#define thread_safe_sub(V,C,L)     (V)-=(C)
+#define statistic_increment(V,L)   (V)++
+#define statistic_add(V,C,L)       (V)+=(C)
+#endif
+
+#ifdef HAVE_CHARSET_utf8
+#define MYSQL_UNIVERSAL_CLIENT_CHARSET "utf8"
+#else
+#define MYSQL_UNIVERSAL_CLIENT_CHARSET MYSQL_DEFAULT_CHARSET_NAME
+#endif
+
+#if defined(EMBEDDED_LIBRARY) && !defined(HAVE_EMBEDDED_PRIVILEGE_CONTROL)
+#define NO_EMBEDDED_ACCESS_CHECKS
+#endif
+
+
+/* Length of decimal number represented by INT32. */
+
+#define MY_INT32_NUM_DECIMAL_DIGITS 11
+
+/* Length of decimal number represented by INT64. */
+
+#define MY_INT64_NUM_DECIMAL_DIGITS 21
+
+#endif /* my_global_h */
diff --git a/dep/include/mysql/my_list.h b/dep/include/mysql/my_list.h
new file mode 100644
index 000000000..4a1737d4c
--- /dev/null
+++ b/dep/include/mysql/my_list.h
@@ -0,0 +1,45 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef _list_h_
+#define _list_h_
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct st_list {
+  struct st_list *prev,*next;
+  void *data;
+} LIST;
+
+typedef int (*list_walk_action)(void *,void *);
+
+extern LIST *list_add(LIST *root,LIST *element);
+extern LIST *list_delete(LIST *root,LIST *element);
+extern LIST *list_cons(void *data,LIST *root);
+extern LIST *list_reverse(LIST *root);
+extern void list_free(LIST *root,unsigned int free_data);
+extern unsigned int list_length(LIST *);
+extern int list_walk(LIST *,list_walk_action action,gptr argument);
+
+#define list_rest(a) ((a)->next)
+#define list_push(a,b) (a)=list_cons((b),(a))
+#define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old) ; my_free((gptr) old,MYF(MY_FAE)); }
+
+#ifdef	__cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/mysql/my_pthread.h b/dep/include/mysql/my_pthread.h
new file mode 100644
index 000000000..13b7cf93d
--- /dev/null
+++ b/dep/include/mysql/my_pthread.h
@@ -0,0 +1,799 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Defines to make different thread packages compatible */
+
+#ifndef _my_pthread_h
+#define _my_pthread_h
+
+#include 
+#ifndef ETIME
+#define ETIME ETIMEDOUT				/* For FreeBSD */
+#endif
+
+#ifdef  __cplusplus
+#define EXTERNC extern "C"
+extern "C" {
+#else
+#define EXTERNC
+#endif /* __cplusplus */ 
+
+#if defined(__WIN__) || defined(OS2)
+
+#ifdef OS2
+typedef ULONG     HANDLE;
+typedef ULONG     DWORD;
+typedef int sigset_t;
+#endif
+
+#ifdef OS2
+typedef HMTX             pthread_mutex_t;
+#else
+typedef CRITICAL_SECTION pthread_mutex_t;
+#endif
+typedef HANDLE		 pthread_t;
+typedef struct thread_attr {
+    DWORD dwStackSize ;
+    DWORD dwCreatingFlag ;
+    int priority ;
+} pthread_attr_t ;
+
+typedef struct { int dummy; } pthread_condattr_t;
+
+/* Implementation of posix conditions */
+
+typedef struct st_pthread_link {
+  DWORD thread_id;
+  struct st_pthread_link *next;
+} pthread_link;
+
+typedef struct {
+  uint32 waiting;
+  CRITICAL_SECTION lock_waiting;
+ 
+  enum {
+    SIGNAL= 0,
+    BROADCAST= 1,
+    MAX_EVENTS= 2
+  } EVENTS;
+
+  HANDLE events[MAX_EVENTS];
+  HANDLE broadcast_block_event;
+
+} pthread_cond_t;
+
+typedef int pthread_mutexattr_t;
+#define win_pthread_self my_thread_var->pthread_self
+#ifdef OS2
+#define pthread_handler_t EXTERNC void * _Optlink
+typedef void * (_Optlink *pthread_handler)(void *);
+#else
+#define pthread_handler_t EXTERNC void * __cdecl
+typedef void * (__cdecl *pthread_handler)(void *);
+#endif
+
+/*
+  Struct and macros to be used in combination with the
+  windows implementation of pthread_cond_timedwait
+*/
+
+/*
+   Declare a union to make sure FILETIME is properly aligned
+   so it can be used directly as a 64 bit value. The value
+   stored is in 100ns units.
+ */
+ union ft64 {
+  FILETIME ft;
+  __int64 i64;
+ };
+struct timespec {
+  union ft64 tv;
+  /* The max timeout value in millisecond for pthread_cond_timedwait */
+  long max_timeout_msec;
+};
+#define set_timespec(ABSTIME,SEC) { \
+  GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
+  (ABSTIME).tv.i64+= (__int64)(SEC)*10000000; \
+  (ABSTIME).max_timeout_msec= (long)((SEC)*1000); \
+}
+#define set_timespec_nsec(ABSTIME,NSEC) { \
+  GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
+  (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
+  (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
+}
+
+void win_pthread_init(void);
+int win_pthread_setspecific(void *A,void *B,uint length);
+int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+			   struct timespec *abstime);
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_attr_init(pthread_attr_t *connect_att);
+int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
+int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
+int pthread_attr_destroy(pthread_attr_t *connect_att);
+struct tm *localtime_r(const time_t *timep,struct tm *tmp);
+struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
+
+
+void pthread_exit(void *a);	 /* was #define pthread_exit(A) ExitThread(A)*/
+
+#ifndef OS2
+#define ETIMEDOUT 145		    /* Win32 doesn't have this */
+#define getpid() GetCurrentThreadId()
+#endif
+#define pthread_self() win_pthread_self
+#define HAVE_LOCALTIME_R		1
+#define _REENTRANT			1
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE	1
+
+#ifdef USE_TLS					/* For LIBMYSQL.DLL */
+#undef SAFE_MUTEX				/* This will cause conflicts */
+#define pthread_key(T,V)  DWORD V
+#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
+#define pthread_key_delete(A) TlsFree(A)
+#define pthread_getspecific(A) (TlsGetValue(A))
+#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
+#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
+#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
+#define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
+#else
+#define pthread_key(T,V) __declspec(thread) T V
+#define pthread_key_create(A,B) pthread_dummy(0)
+#define pthread_key_delete(A) pthread_dummy(0)
+#define pthread_getspecific(A) (&(A))
+#define my_pthread_getspecific(T,A) (&(A))
+#define my_pthread_getspecific_ptr(T,V) (V)
+#define my_pthread_setspecific_ptr(T,V) ((T)=(V),0)
+#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
+#endif /* USE_TLS */
+
+#define pthread_equal(A,B) ((A) == (B))
+#ifdef OS2
+extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
+extern int pthread_mutex_lock (pthread_mutex_t *);
+extern int pthread_mutex_unlock (pthread_mutex_t *);
+extern int pthread_mutex_destroy (pthread_mutex_t *);
+#define my_pthread_setprio(A,B)  DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A)
+#define pthread_kill(A,B) raise(B)
+#define pthread_exit(A) pthread_dummy()
+#else
+#define pthread_mutex_init(A,B)  (InitializeCriticalSection(A),0)
+#define pthread_mutex_lock(A)	 (EnterCriticalSection(A),0)
+#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
+#define pthread_mutex_unlock(A)  LeaveCriticalSection(A)
+#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
+#define my_pthread_setprio(A,B)  SetThreadPriority(GetCurrentThread(), (B))
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
+#endif /* OS2 */
+
+/* Dummy defines for easier code */
+#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
+#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B)
+#define pthread_attr_setscope(A,B)
+#define pthread_detach_this_thread()
+#define pthread_condattr_init(A)
+#define pthread_condattr_destroy(A)
+
+#define my_pthread_getprio(thread_id) pthread_dummy(0)
+
+#elif defined(HAVE_UNIXWARE7_THREADS)
+
+#include 
+#include 
+
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+
+#define HAVE_NONPOSIX_SIGWAIT
+#define pthread_t thread_t
+#define pthread_cond_t cond_t
+#define pthread_mutex_t mutex_t
+#define pthread_key_t thread_key_t
+typedef int pthread_attr_t;			/* Needed by Unixware 7.0.0 */
+
+#define pthread_key_create(A,B) thr_keycreate((A),(B))
+#define pthread_key_delete(A) thr_keydelete(A)
+
+#define pthread_handler_t EXTERNC void *
+#define pthread_key(T,V) pthread_key_t V
+
+void *	my_pthread_getspecific_imp(pthread_key_t key);
+#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
+#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,V)
+
+#define pthread_setspecific(A,B) thr_setspecific(A,B)
+#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,V)
+
+#define pthread_create(A,B,C,D) thr_create(NULL,65536L,(C),(D),THR_DETACHED,(A))
+#define pthread_cond_init(a,b) cond_init((a),USYNC_THREAD,NULL)
+#define pthread_cond_destroy(a) cond_destroy(a)
+#define pthread_cond_signal(a) cond_signal(a)
+#define pthread_cond_wait(a,b) cond_wait((a),(b))
+#define pthread_cond_timedwait(a,b,c) cond_timedwait((a),(b),(c))
+#define pthread_cond_broadcast(a) cond_broadcast(a)
+
+#define pthread_mutex_init(a,b) mutex_init((a),USYNC_THREAD,NULL)
+#define pthread_mutex_lock(a) mutex_lock(a)
+#define pthread_mutex_unlock(a) mutex_unlock(a)
+#define pthread_mutex_destroy(a) mutex_destroy(a)
+
+#define pthread_self() thr_self()
+#define pthread_exit(A) thr_exit(A)
+#define pthread_equal(A,B) (((A) == (B)) ? 1 : 0)
+#define pthread_kill(A,B) thr_kill((A),(B))
+#define HAVE_PTHREAD_KILL
+
+#define pthread_sigmask(A,B,C) thr_sigsetmask((A),(B),(C))
+
+extern int my_sigwait(const sigset_t *set,int *sig);
+
+#define pthread_detach_this_thread() pthread_dummy(0)
+
+#define pthread_attr_init(A) pthread_dummy(0)
+#define pthread_attr_destroy(A) pthread_dummy(0)
+#define pthread_attr_setscope(A,B) pthread_dummy(0)
+#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
+#define my_pthread_setprio(A,B) pthread_dummy (0)
+#define my_pthread_getprio(A) pthread_dummy (0)
+#define my_pthread_attr_setprio(A,B) pthread_dummy(0)
+
+#else /* Normal threads */
+
+#ifdef HAVE_rts_threads
+#define sigwait org_sigwait
+#include 
+#undef sigwait
+#endif
+#include 
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+#ifdef HAVE_THR_SETCONCURRENCY
+#include 			/* Probably solaris */
+#endif
+#ifdef HAVE_SCHED_H
+#include 
+#endif
+#ifdef HAVE_SYNCH_H
+#include 
+#endif
+#if defined(__EMX__) && (!defined(EMX_PTHREAD_REV) || (EMX_PTHREAD_REV < 2))
+#error Requires at least rev 2 of EMX pthreads library.
+#endif
+
+#ifdef __NETWARE__
+void my_pthread_exit(void *status);
+#define pthread_exit(A) my_pthread_exit(A)
+#endif
+
+extern int my_pthread_getprio(pthread_t thread_id);
+
+#define pthread_key(T,V) pthread_key_t V
+#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
+#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
+#define pthread_detach_this_thread()
+#define pthread_handler_t EXTERNC void *
+typedef void *(* pthread_handler)(void *);
+
+/* Test first for RTS or FSU threads */
+
+#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
+#define HAVE_rts_threads
+extern int my_pthread_create_detached;
+#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
+#define PTHREAD_CREATE_DETACHED &my_pthread_create_detached
+#define PTHREAD_SCOPE_SYSTEM  PTHREAD_SCOPE_GLOBAL
+#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL
+#define USE_ALARM_THREAD
+#elif defined(HAVE_mit_thread)
+#define USE_ALARM_THREAD
+#undef	HAVE_LOCALTIME_R
+#define HAVE_LOCALTIME_R
+#undef	HAVE_GMTIME_R
+#define HAVE_GMTIME_R
+#undef	HAVE_PTHREAD_ATTR_SETSCOPE
+#define HAVE_PTHREAD_ATTR_SETSCOPE
+#undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE	/* If we are running linux */
+#undef HAVE_RWLOCK_T
+#undef HAVE_RWLOCK_INIT
+#undef HAVE_PTHREAD_RWLOCK_RDLOCK
+#undef HAVE_SNPRINTF
+
+#define my_pthread_attr_setprio(A,B)
+#endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */
+
+#if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910
+int sigwait(sigset_t *set, int *sig);
+#endif
+
+#ifndef HAVE_NONPOSIX_SIGWAIT
+#define my_sigwait(A,B) sigwait((A),(B))
+#else
+int my_sigwait(const sigset_t *set,int *sig);
+#endif
+
+#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
+#ifndef SAFE_MUTEX
+#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
+extern int my_pthread_mutex_init(pthread_mutex_t *mp,
+				 const pthread_mutexattr_t *attr);
+#endif /* SAFE_MUTEX */
+#define pthread_cond_init(a,b) my_pthread_cond_init((a),(b))
+extern int my_pthread_cond_init(pthread_cond_t *mp,
+				const pthread_condattr_t *attr);
+#endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */
+
+#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
+#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
+#endif
+
+#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX)
+int sigwait(sigset_t *setp, int *sigp);		/* Use our implemention */
+#endif
+
+
+/*
+  We define my_sigset() and use that instead of the system sigset() so that
+  we can favor an implementation based on sigaction(). On some systems, such
+  as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
+  we want to make sure that no such flags are set.
+*/
+#if defined(HAVE_SIGACTION) && !defined(my_sigset)
+#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
+                            DBUG_ASSERT((A) != 0);                          \
+                            sigemptyset(&l_set);                            \
+                            l_s.sa_handler = (B);                           \
+                            l_s.sa_mask   = l_set;                          \
+                            l_s.sa_flags   = 0;                             \
+                            l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
+                            DBUG_ASSERT(l_rc == 0);                         \
+                          } while (0)
+#elif defined(HAVE_SIGSET) && !defined(my_sigset)
+#define my_sigset(A,B) sigset((A),(B))
+#elif !defined(my_sigset)
+#define my_sigset(A,B) signal((A),(B))
+#endif
+
+#ifndef my_pthread_setprio
+#if defined(HAVE_PTHREAD_SETPRIO_NP)		/* FSU threads */
+#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
+#elif defined(HAVE_PTHREAD_SETPRIO)
+#define my_pthread_setprio(A,B) pthread_setprio((A),(B))
+#else
+extern void my_pthread_setprio(pthread_t thread_id,int prior);
+#endif
+#endif
+
+#ifndef my_pthread_attr_setprio
+#ifdef HAVE_PTHREAD_ATTR_SETPRIO
+#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
+#else
+extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
+#endif
+#endif
+
+#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS)
+#define pthread_attr_setscope(A,B)
+#undef	HAVE_GETHOSTBYADDR_R			/* No definition */
+#endif
+
+#if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX)
+extern int my_pthread_cond_timedwait(pthread_cond_t *cond,
+				     pthread_mutex_t *mutex,
+				     struct timespec *abstime);
+#define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C))
+#endif
+
+#if defined(OS2)
+#define my_pthread_getspecific(T,A) ((T) &(A))
+#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
+#elif !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
+#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B))
+#else
+#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
+void *my_pthread_getspecific_imp(pthread_key_t key);
+#endif /* OS2 */
+
+#ifndef HAVE_LOCALTIME_R
+struct tm *localtime_r(const time_t *clock, struct tm *res);
+#endif
+
+#ifndef HAVE_GMTIME_R
+struct tm *gmtime_r(const time_t *clock, struct tm *res);
+#endif
+
+#ifdef HAVE_PTHREAD_CONDATTR_CREATE
+/* DCE threads on HPUX 10.20 */
+#define pthread_condattr_init pthread_condattr_create
+#define pthread_condattr_destroy pthread_condattr_delete
+#endif
+
+/* FSU THREADS */
+#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
+#define pthread_key_delete(A) pthread_dummy(0)
+#endif
+
+#ifdef HAVE_CTHREADS_WRAPPER			/* For MacOSX */
+#define pthread_cond_destroy(A) pthread_dummy(0)
+#define pthread_mutex_destroy(A) pthread_dummy(0)
+#define pthread_attr_delete(A) pthread_dummy(0)
+#define pthread_condattr_delete(A) pthread_dummy(0)
+#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
+#define pthread_equal(A,B) ((A) == (B))
+#define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b))
+#define pthread_attr_init(A) pthread_attr_create(A)
+#define pthread_attr_destroy(A) pthread_attr_delete(A)
+#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
+#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
+#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
+#undef	pthread_detach_this_thread
+#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
+#endif
+
+#ifdef HAVE_DARWIN5_THREADS
+#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
+#define pthread_condattr_init(A) pthread_dummy(0)
+#define pthread_condattr_destroy(A) pthread_dummy(0)
+#undef	pthread_detach_this_thread
+#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
+#endif
+
+#if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER)
+/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
+#define pthread_key_create(A,B) \
+		pthread_keycreate(A,(B) ?\
+				  (pthread_destructor_t) (B) :\
+				  (pthread_destructor_t) pthread_dummy)
+#define pthread_attr_init(A) pthread_attr_create(A)
+#define pthread_attr_destroy(A) pthread_attr_delete(A)
+#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
+#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
+#ifndef pthread_sigmask
+#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
+#endif
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
+#undef	pthread_detach_this_thread
+#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
+#elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */
+#define HAVE_PTHREAD_KILL
+#endif
+
+#endif /* defined(__WIN__) */
+
+#if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
+#undef pthread_cond_timedwait
+#define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c))
+int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+			      struct timespec *abstime);
+#endif
+
+#if defined(HPUX10)
+#define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B)
+void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size);
+#endif
+
+#if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
+#undef pthread_mutex_trylock
+#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
+int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
+#endif
+
+/*
+  The defines set_timespec and set_timespec_nsec should be used
+  for calculating an absolute time at which
+  pthread_cond_timedwait should timeout
+*/
+#ifdef HAVE_TIMESPEC_TS_SEC
+#ifndef set_timespec
+#define set_timespec(ABSTIME,SEC) \
+{ \
+  (ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
+  (ABSTIME).ts_nsec=0; \
+}
+#endif /* !set_timespec */
+#ifndef set_timespec_nsec
+#define set_timespec_nsec(ABSTIME,NSEC) \
+{ \
+  ulonglong now= my_getsystime() + (NSEC/100); \
+  (ABSTIME).ts_sec=  (now / ULL(10000000)); \
+  (ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
+}
+#endif /* !set_timespec_nsec */
+#else
+#ifndef set_timespec
+#define set_timespec(ABSTIME,SEC) \
+{\
+  struct timeval tv;\
+  gettimeofday(&tv,0);\
+  (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
+  (ABSTIME).tv_nsec=tv.tv_usec*1000;\
+}
+#endif /* !set_timespec */
+#ifndef set_timespec_nsec
+#define set_timespec_nsec(ABSTIME,NSEC) \
+{\
+  ulonglong now= my_getsystime() + (NSEC/100); \
+  (ABSTIME).tv_sec=  (time_t) (now / ULL(10000000));                  \
+  (ABSTIME).tv_nsec= (long) (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
+}
+#endif /* !set_timespec_nsec */
+#endif /* HAVE_TIMESPEC_TS_SEC */
+
+	/* safe_mutex adds checking to mutex for easier debugging */
+
+#if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY)
+#define SAFE_MUTEX_DETECT_DESTROY
+#endif
+
+typedef struct st_safe_mutex_t
+{
+  pthread_mutex_t global,mutex;
+  const char *file;
+  uint line,count;
+  pthread_t thread;
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+  struct st_safe_mutex_info_t *info;	/* to track destroying of mutexes */
+#endif
+} safe_mutex_t;
+
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+/*
+  Used to track the destroying of mutexes. This needs to be a seperate
+  structure because the safe_mutex_t structure could be freed before
+  the mutexes are destroyed.
+*/
+
+typedef struct st_safe_mutex_info_t
+{
+  struct st_safe_mutex_info_t *next;
+  struct st_safe_mutex_info_t *prev;
+  const char *init_file;
+  uint32 init_line;
+} safe_mutex_info_t;
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
+
+int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
+                    const char *file, uint line);
+int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
+int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
+int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
+int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
+		   uint line);
+int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
+			struct timespec *abstime, const char *file, uint line);
+void safe_mutex_global_init(void);
+void safe_mutex_end(FILE *file);
+
+	/* Wrappers if safe mutex is actually used */
+#ifdef SAFE_MUTEX
+#undef pthread_mutex_init
+#undef pthread_mutex_lock
+#undef pthread_mutex_unlock
+#undef pthread_mutex_destroy
+#undef pthread_mutex_wait
+#undef pthread_mutex_timedwait
+#undef pthread_mutex_t
+#undef pthread_cond_wait
+#undef pthread_cond_timedwait
+#undef pthread_mutex_trylock
+#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
+#define pthread_mutex_lock(A) safe_mutex_lock((A), FALSE, __FILE__, __LINE__)
+#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
+#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
+#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
+#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
+#define pthread_mutex_trylock(A) safe_mutex_lock((A), TRUE, __FILE__, __LINE__)
+#define pthread_mutex_t safe_mutex_t
+#define safe_mutex_assert_owner(mp) \
+          DBUG_ASSERT((mp)->count > 0 && \
+                      pthread_equal(pthread_self(), (mp)->thread))
+#define safe_mutex_assert_not_owner(mp) \
+          DBUG_ASSERT(! (mp)->count || \
+                      ! pthread_equal(pthread_self(), (mp)->thread))
+#else
+#define safe_mutex_assert_owner(mp)
+#define safe_mutex_assert_not_owner(mp)
+#endif /* SAFE_MUTEX */
+
+	/* READ-WRITE thread locking */
+
+#ifdef HAVE_BROKEN_RWLOCK			/* For OpenUnix */
+#undef HAVE_PTHREAD_RWLOCK_RDLOCK
+#undef HAVE_RWLOCK_INIT
+#undef HAVE_RWLOCK_T
+#endif
+
+#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
+/* use these defs for simple mutex locking */
+#define rw_lock_t pthread_mutex_t
+#define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
+#define rw_rdlock(A) pthread_mutex_lock((A))
+#define rw_wrlock(A) pthread_mutex_lock((A))
+#define rw_tryrdlock(A) pthread_mutex_trylock((A))
+#define rw_trywrlock(A) pthread_mutex_trylock((A))
+#define rw_unlock(A) pthread_mutex_unlock((A))
+#define rwlock_destroy(A) pthread_mutex_destroy((A))
+#elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
+#define rw_lock_t pthread_rwlock_t
+#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
+#define rw_rdlock(A) pthread_rwlock_rdlock(A)
+#define rw_wrlock(A) pthread_rwlock_wrlock(A)
+#define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
+#define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
+#define rw_unlock(A) pthread_rwlock_unlock(A)
+#define rwlock_destroy(A) pthread_rwlock_destroy(A)
+#elif defined(HAVE_RWLOCK_INIT)
+#ifdef HAVE_RWLOCK_T				/* For example Solaris 2.6-> */
+#define rw_lock_t rwlock_t
+#endif
+#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
+#else
+/* Use our own version of read/write locks */
+typedef struct _my_rw_lock_t {
+	pthread_mutex_t lock;		/* lock for structure		*/
+	pthread_cond_t	readers;	/* waiting readers		*/
+	pthread_cond_t	writers;	/* waiting writers		*/
+	int		state;		/* -1:writer,0:free,>0:readers	*/
+	int		waiters;	/* number of waiting writers	*/
+} my_rw_lock_t;
+
+#define rw_lock_t my_rw_lock_t
+#define rw_rdlock(A) my_rw_rdlock((A))
+#define rw_wrlock(A) my_rw_wrlock((A))
+#define rw_tryrdlock(A) my_rw_tryrdlock((A))
+#define rw_trywrlock(A) my_rw_trywrlock((A))
+#define rw_unlock(A) my_rw_unlock((A))
+#define rwlock_destroy(A) my_rwlock_destroy((A))
+
+extern int my_rwlock_init(my_rw_lock_t *, void *);
+extern int my_rwlock_destroy(my_rw_lock_t *);
+extern int my_rw_rdlock(my_rw_lock_t *);
+extern int my_rw_wrlock(my_rw_lock_t *);
+extern int my_rw_unlock(my_rw_lock_t *);
+extern int my_rw_tryrdlock(my_rw_lock_t *);
+extern int my_rw_trywrlock(my_rw_lock_t *);
+#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
+
+#define GETHOSTBYADDR_BUFF_SIZE 2048
+
+#ifndef HAVE_THR_SETCONCURRENCY
+#define thr_setconcurrency(A) pthread_dummy(0)
+#endif
+#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
+#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
+#endif
+
+/* Define mutex types, see my_thr_init.c */
+#define MY_MUTEX_INIT_SLOW   NULL
+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+extern pthread_mutexattr_t my_fast_mutexattr;
+#define MY_MUTEX_INIT_FAST &my_fast_mutexattr
+#else
+#define MY_MUTEX_INIT_FAST   NULL
+#endif
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+extern pthread_mutexattr_t my_errorcheck_mutexattr;
+#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
+#else
+#define MY_MUTEX_INIT_ERRCHK   NULL
+#endif
+
+#ifndef ESRCH
+/* Define it to something */
+#define ESRCH 1
+#endif
+
+extern my_bool my_thread_global_init(void);
+extern void my_thread_global_end(void);
+extern my_bool my_thread_init(void);
+extern void my_thread_end(void);
+extern const char *my_thread_name(void);
+extern long my_thread_id(void);
+extern int pthread_no_free(void *);
+extern int pthread_dummy(int);
+
+/* All thread specific variables are in the following struct */
+
+#define THREAD_NAME_SIZE 10
+#ifndef DEFAULT_THREAD_STACK
+#if SIZEOF_CHARP > 4
+/*
+  MySQL can survive with 32K, but some glibc libraries require > 128K stack
+  To resolve hostnames. Also recursive stored procedures needs stack.
+*/
+#define DEFAULT_THREAD_STACK	(256*1024L)
+#else
+#define DEFAULT_THREAD_STACK	(192*1024)
+#endif
+#endif
+
+struct st_my_thread_var
+{
+  int thr_errno;
+  pthread_cond_t suspend;
+  pthread_mutex_t mutex;
+  pthread_mutex_t * volatile current_mutex;
+  pthread_cond_t * volatile current_cond;
+  pthread_t pthread_self;
+  long id;
+  int cmp_length;
+  int volatile abort;
+  my_bool init;
+  struct st_my_thread_var *next,**prev;
+  void *opt_info;
+#ifndef DBUG_OFF
+  gptr dbug;
+  char name[THREAD_NAME_SIZE+1];
+#endif
+};
+
+extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
+extern uint my_thread_end_wait_time;
+#define my_thread_var (_my_thread_var())
+#define my_errno my_thread_var->thr_errno
+/*
+  Keep track of shutdown,signal, and main threads so that my_end() will not
+  report errors with them
+*/
+
+/* Which kind of thread library is in use */
+
+#define THD_LIB_OTHER 1
+#define THD_LIB_NPTL  2
+#define THD_LIB_LT    4
+
+extern uint thd_lib_detected;
+
+	/* statistics_xxx functions are for not essential statistic */
+
+#ifndef thread_safe_increment
+#ifdef HAVE_ATOMIC_ADD
+#define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V)
+#define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V)
+#define thread_safe_add(V,C,L)     atomic_add((C),(atomic_t*) &V)
+#define thread_safe_sub(V,C,L)     atomic_sub((C),(atomic_t*) &V)
+#else
+#define thread_safe_increment(V,L) \
+        (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
+#define thread_safe_decrement(V,L) \
+        (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
+#define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
+#define thread_safe_sub(V,C,L) \
+        (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
+#endif /* HAVE_ATOMIC_ADD */
+#ifdef SAFE_STATISTICS
+#define statistic_increment(V,L)   thread_safe_increment((V),(L))
+#define statistic_decrement(V,L)   thread_safe_decrement((V),(L))
+#define statistic_add(V,C,L)       thread_safe_add((V),(C),(L))
+#else
+#define statistic_decrement(V,L) (V)--
+#define statistic_increment(V,L) (V)++
+#define statistic_add(V,C,L)     (V)+=(C)
+#endif /* SAFE_STATISTICS */
+#endif /* thread_safe_increment */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif /* _my_ptread_h */
diff --git a/dep/include/mysql/my_sys.h b/dep/include/mysql/my_sys.h
new file mode 100644
index 000000000..d656326e9
--- /dev/null
+++ b/dep/include/mysql/my_sys.h
@@ -0,0 +1,936 @@
+/* Copyright (C) 2000-2003 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef _my_sys_h
+#define _my_sys_h
+C_MODE_START
+
+#ifdef HAVE_AIOWAIT
+#include 			/* Used by record-cache */
+typedef struct my_aio_result {
+  aio_result_t result;
+  int	       pending;
+} my_aio_result;
+#endif
+
+#ifndef THREAD
+extern int NEAR my_errno;		/* Last error in mysys */
+#else
+#include 
+#endif
+
+#include                     /* for CHARSET_INFO */
+#include 
+#include 
+
+#define MYSYS_PROGRAM_USES_CURSES()  { error_handler_hook = my_message_curses;	mysys_uses_curses=1; }
+#define MYSYS_PROGRAM_DONT_USE_CURSES()  { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
+#define MY_INIT(name);		{ my_progname= name; my_init(); }
+
+#define ERRMSGSIZE	(SC_MAXWIDTH)	/* Max length of a error message */
+#define NRERRBUFFS	(2)	/* Buffers for parameters */
+#define MY_FILE_ERROR	((uint) ~0)
+
+	/* General bitmaps for my_func's */
+#define MY_FFNF		1	/* Fatal if file not found */
+#define MY_FNABP	2	/* Fatal if not all bytes read/writen */
+#define MY_NABP		4	/* Error if not all bytes read/writen */
+#define MY_FAE		8	/* Fatal if any error */
+#define MY_WME		16	/* Write message on error */
+#define MY_WAIT_IF_FULL 32	/* Wait and try again if disk full error */
+#define MY_IGNORE_BADFD 32      /* my_sync: ignore 'bad descriptor' errors */
+#define MY_RAID         64      /* Support for RAID */
+#define MY_FULL_IO     512      /* For my_read - loop intil I/O is complete */
+#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
+#define MY_LINK_WARNING 32	/* my_redel() gives warning if links */
+#define MY_COPYTIME	64	/* my_redel() copys time */
+#define MY_DELETE_OLD	256	/* my_create_with_symlink() */
+#define MY_RESOLVE_LINK 128	/* my_realpath(); Only resolve links */
+#define MY_HOLD_ORIGINAL_MODES 128  /* my_copy() holds to file modes */
+#define MY_REDEL_MAKE_BACKUP 256
+#define MY_SEEK_NOT_DONE 32	/* my_lock may have to do a seek */
+#define MY_DONT_WAIT	64	/* my_lock() don't wait if can't lock */
+#define MY_ZEROFILL	32	/* my_malloc(), fill array with zero */
+#define MY_ALLOW_ZERO_PTR 64	/* my_realloc() ; zero ptr -> malloc */
+#define MY_FREE_ON_ERROR 128	/* my_realloc() ; Free old ptr on error */
+#define MY_HOLD_ON_ERROR 256	/* my_realloc() ; Return old ptr on error */
+#define MY_DONT_OVERWRITE_FILE 1024	/* my_copy: Don't overwrite file */
+#define MY_THREADSAFE 2048      /* my_seek(): lock fd mutex */
+
+#define MY_CHECK_ERROR	1	/* Params to my_end; Check open-close */
+#define MY_GIVE_INFO	2	/* Give time info about process*/
+#define MY_DONT_FREE_DBUG 4     /* Do not call DBUG_END() in my_end() */
+
+#define ME_HIGHBYTE	8	/* Shift for colours */
+#define ME_NOCUR	1	/* Don't use curses message */
+#define ME_OLDWIN	2	/* Use old window */
+#define ME_BELL		4	/* Ring bell then printing message */
+#define ME_HOLDTANG	8	/* Don't delete last keys */
+#define ME_WAITTOT	16	/* Wait for errtime secs of for a action */
+#define ME_WAITTANG	32	/* Wait for a user action  */
+#define ME_NOREFRESH	64	/* Dont refresh screen */
+#define ME_NOINPUT	128	/* Dont use the input libary */
+#define ME_COLOUR1	((1 << ME_HIGHBYTE))	/* Possibly error-colours */
+#define ME_COLOUR2	((2 << ME_HIGHBYTE))
+#define ME_COLOUR3	((3 << ME_HIGHBYTE))
+
+	/* Bits in last argument to fn_format */
+#define MY_REPLACE_DIR		1	/* replace dir in name with 'dir' */
+#define MY_REPLACE_EXT		2	/* replace extension with 'ext' */
+#define MY_UNPACK_FILENAME	4	/* Unpack name (~ -> home) */
+#define MY_PACK_FILENAME	8	/* Pack name (home -> ~) */
+#define MY_RESOLVE_SYMLINKS	16	/* Resolve all symbolic links */
+#define MY_RETURN_REAL_PATH	32	/* return full path for file */
+#define MY_SAFE_PATH		64	/* Return NULL if too long path */
+#define MY_RELATIVE_PATH	128	/* name is relative to 'dir' */
+
+	/* My seek flags */
+#define MY_SEEK_SET	0
+#define MY_SEEK_CUR	1
+#define MY_SEEK_END	2
+
+	/* Some constants */
+#define MY_WAIT_FOR_USER_TO_FIX_PANIC	60	/* in seconds */
+#define MY_WAIT_GIVE_USER_A_MESSAGE	10	/* Every 10 times of prev */
+#define MIN_COMPRESS_LENGTH		50	/* Don't compress small bl. */
+#define DFLT_INIT_HITS  3
+
+	/* root_alloc flags */
+#define MY_KEEP_PREALLOC	1
+#define MY_MARK_BLOCKS_FREE     2  /* move used to free list and reuse them */
+
+	/* Internal error numbers (for assembler functions) */
+#define MY_ERRNO_EDOM		33
+#define MY_ERRNO_ERANGE		34
+
+	/* Bits for get_date timeflag */
+#define GETDATE_DATE_TIME	1
+#define GETDATE_SHORT_DATE	2
+#define GETDATE_HHMMSSTIME	4
+#define GETDATE_GMT		8
+#define GETDATE_FIXEDLENGTH	16
+
+	/* defines when allocating data */
+#ifdef SAFEMALLOC
+#define my_malloc(SZ,FLAG) _mymalloc((SZ), __FILE__, __LINE__, FLAG )
+#define my_malloc_ci(SZ,FLAG) _mymalloc((SZ), sFile, uLine, FLAG )
+#define my_realloc(PTR,SZ,FLAG) _myrealloc((PTR), (SZ), __FILE__, __LINE__, FLAG )
+#define my_checkmalloc() _sanity( __FILE__, __LINE__ )
+#define my_free(PTR,FLAG) _myfree((PTR), __FILE__, __LINE__,FLAG)
+#define my_memdup(A,B,C) _my_memdup((A),(B), __FILE__,__LINE__,C)
+#define my_strdup(A,C) _my_strdup((A), __FILE__,__LINE__,C)
+#define my_strdup_with_length(A,B,C) _my_strdup_with_length((A),(B),__FILE__,__LINE__,C)
+#define TRASH(A,B) bfill(A, B, 0x8F)
+#define QUICK_SAFEMALLOC sf_malloc_quick=1
+#define NORMAL_SAFEMALLOC sf_malloc_quick=0
+extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
+extern ulonglong sf_malloc_mem_limit;
+
+#define CALLER_INFO_PROTO   , const char *sFile, uint uLine
+#define CALLER_INFO         , __FILE__, __LINE__
+#define ORIG_CALLER_INFO    , sFile, uLine
+#else
+#define my_checkmalloc()
+#undef TERMINATE
+#define TERMINATE(A) {}
+#define QUICK_SAFEMALLOC
+#define NORMAL_SAFEMALLOC
+extern gptr my_malloc(size_t Size, myf MyFlags);
+#define my_malloc_ci(SZ,FLAG) my_malloc( SZ, FLAG )
+extern gptr my_realloc(gptr oldpoint,uint Size,myf MyFlags);
+extern void my_no_flags_free(gptr ptr);
+extern gptr my_memdup(const byte *from, size_t length, myf MyFlags);
+extern char *my_strdup(const char *from,myf MyFlags);
+extern char *my_strdup_with_length(const char *from, size_t length,
+                                   myf MyFlags);
+/* we do use FG (as a no-op) in below so that a typo on FG is caught */
+#define my_free(PTR,FG) ((void)FG,my_no_flags_free(PTR))
+#define CALLER_INFO_PROTO   /* nothing */
+#define CALLER_INFO         /* nothing */
+#define ORIG_CALLER_INFO    /* nothing */
+#define TRASH(A,B) /* nothing */
+#endif
+
+#ifdef HAVE_LARGE_PAGES
+extern uint my_get_large_page_size(void);
+extern gptr my_large_malloc(size_t size, myf my_flags);
+extern void my_large_free(gptr ptr, myf my_flags);
+#else
+#define my_get_large_page_size() (0)
+#define my_large_malloc(A,B) my_malloc_lock((A),(B))
+#define my_large_free(A,B) my_free_lock((A),(B))
+#endif /* HAVE_LARGE_PAGES */
+
+#ifdef HAVE_ALLOCA
+#if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43)
+#pragma alloca
+#endif /* _AIX */
+#if defined(__MWERKS__)
+#undef alloca
+#define alloca _alloca
+#endif /* __MWERKS__ */
+#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && ! defined(alloca)
+#define alloca __builtin_alloca
+#endif /* GNUC */
+#define my_alloca(SZ) alloca((size_t) (SZ))
+#define my_afree(PTR) {}
+#else
+#define my_alloca(SZ) my_malloc(SZ,MYF(0))
+#define my_afree(PTR) my_free(PTR,MYF(MY_WME))
+#endif /* HAVE_ALLOCA */
+
+#ifdef MSDOS
+#ifdef __ZTC__
+void * __CDECL halloc(long count,size_t length);
+void   __CDECL hfree(void *ptr);
+#endif
+#if defined(USE_HALLOC)
+#if defined(_VCM_) || defined(M_IC80386)
+#undef USE_HALLOC
+#endif
+#endif
+#ifdef USE_HALLOC
+#define malloc(a) halloc((long) (a),1)
+#define free(a) hfree(a)
+#endif
+#endif /* MSDOS */
+
+#ifndef errno				/* did we already get it? */
+#ifdef HAVE_ERRNO_AS_DEFINE
+#include 			/* errno is a define */
+#else
+extern int errno;			/* declare errno */
+#endif
+#endif					/* #ifndef errno */
+extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE];
+extern char *home_dir;			/* Home directory for user */
+extern const char *my_progname;		/* program-name (printed in errors) */
+extern char NEAR curr_dir[];		/* Current directory for user */
+extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
+extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
+				       myf MyFlags);
+extern uint my_file_limit;
+
+#ifdef HAVE_LARGE_PAGES
+extern my_bool my_use_large_pages;
+extern uint    my_large_page_size;
+#endif
+
+/* charsets */
+extern CHARSET_INFO *default_charset_info;
+extern CHARSET_INFO *all_charsets[256];
+extern CHARSET_INFO compiled_charsets[];
+
+/* statistics */
+extern ulong	my_file_opened,my_stream_opened, my_tmp_file_created;
+extern uint	mysys_usage_id;
+extern my_bool	my_init_done;
+
+					/* Point to current my_message() */
+extern void (*my_sigtstp_cleanup)(void),
+					/* Executed before jump to shell */
+	    (*my_sigtstp_restart)(void),
+	    (*my_abort_hook)(int);
+					/* Executed when comming from shell */
+extern int NEAR my_umask,		/* Default creation mask  */
+	   NEAR my_umask_dir,
+	   NEAR my_recived_signals,	/* Signals we have got */
+	   NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
+	   NEAR my_dont_interrupt;	/* call remember_intr when set */
+extern my_bool NEAR mysys_uses_curses, my_use_symdir;
+extern ulong sf_malloc_cur_memory, sf_malloc_max_memory;
+
+extern ulong	my_default_record_cache_size;
+extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
+               NEAR my_disable_flush_key_blocks, NEAR my_disable_symlinks;
+extern char	wild_many,wild_one,wild_prefix;
+extern const char *charsets_dir;
+/* from default.c */
+extern char *my_defaults_extra_file;
+extern const char *my_defaults_group_suffix;
+extern const char *my_defaults_file;
+
+extern my_bool timed_mutexes;
+
+typedef struct wild_file_pack	/* Struct to hold info when selecting files */
+{
+  uint		wilds;		/* How many wildcards */
+  uint		not_pos;	/* Start of not-theese-files */
+  my_string	*wild;		/* Pointer to wildcards */
+} WF_PACK;
+
+enum loglevel {
+   ERROR_LEVEL,
+   WARNING_LEVEL,
+   INFORMATION_LEVEL
+};
+
+enum cache_type
+{
+  TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
+  SEQ_READ_APPEND		/* sequential read or append */,
+  READ_FIFO, READ_NET,WRITE_NET};
+
+enum flush_type
+{
+  FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE
+};
+
+typedef struct st_record_cache	/* Used when cacheing records */
+{
+  File file;
+  int	rc_seek,error,inited;
+  uint	rc_length,read_length,reclength;
+  my_off_t rc_record_pos,end_of_file;
+  byte	*rc_buff,*rc_buff2,*rc_pos,*rc_end,*rc_request_pos;
+#ifdef HAVE_AIOWAIT
+  int	use_async_io;
+  my_aio_result aio_result;
+#endif
+  enum cache_type type;
+} RECORD_CACHE;
+
+enum file_type
+{
+  UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, STREAM_BY_FOPEN, STREAM_BY_FDOPEN,
+  FILE_BY_MKSTEMP, FILE_BY_DUP
+};
+
+struct st_my_file_info
+{
+  my_string		name;
+  enum file_type	type;
+#if defined(THREAD) && !defined(HAVE_PREAD)
+  pthread_mutex_t	mutex;
+#endif
+};
+
+extern struct st_my_file_info *my_file_info;
+
+typedef struct st_dynamic_array
+{
+  char *buffer;
+  uint elements,max_element;
+  uint alloc_increment;
+  uint size_of_element;
+} DYNAMIC_ARRAY;
+
+typedef struct st_my_tmpdir
+{
+  DYNAMIC_ARRAY full_list;
+  char **list;
+  uint cur, max;
+#ifdef THREAD
+  pthread_mutex_t mutex;
+#endif
+} MY_TMPDIR;
+
+typedef struct st_dynamic_string
+{
+  char *str;
+  uint length,max_length,alloc_increment;
+} DYNAMIC_STRING;
+
+struct st_io_cache;
+typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
+
+#ifdef THREAD
+typedef struct st_io_cache_share
+{
+  pthread_mutex_t       mutex;           /* To sync on reads into buffer. */
+  pthread_cond_t        cond;            /* To wait for signals. */
+  pthread_cond_t        cond_writer;     /* For a synchronized writer. */
+  /* Offset in file corresponding to the first byte of buffer. */
+  my_off_t              pos_in_file;
+  /* If a synchronized write cache is the source of the data. */
+  struct st_io_cache    *source_cache;
+  byte                  *buffer;         /* The read buffer. */
+  byte                  *read_end;       /* Behind last valid byte of buffer. */
+  int                   running_threads; /* threads not in lock. */
+  int                   total_threads;   /* threads sharing the cache. */
+  int                   error;           /* Last error. */
+#ifdef NOT_YET_IMPLEMENTED
+  /* whether the structure should be free'd */
+  my_bool alloced;
+#endif
+} IO_CACHE_SHARE;
+#endif
+
+typedef struct st_io_cache		/* Used when cacheing files */
+{
+  /* Offset in file corresponding to the first byte of byte* buffer. */
+  my_off_t pos_in_file;
+  /*
+    The offset of end of file for READ_CACHE and WRITE_CACHE.
+    For SEQ_READ_APPEND it the maximum of the actual end of file and
+    the position represented by read_end.
+  */
+  my_off_t end_of_file;
+  /* Points to current read position in the buffer */
+  byte	*read_pos;
+  /* the non-inclusive boundary in the buffer for the currently valid read */
+  byte  *read_end;
+  byte  *buffer;				/* The read buffer */
+  /* Used in ASYNC_IO */
+  byte  *request_pos;
+
+  /* Only used in WRITE caches and in SEQ_READ_APPEND to buffer writes */
+  byte  *write_buffer;
+  /*
+    Only used in SEQ_READ_APPEND, and points to the current read position
+    in the write buffer. Note that reads in SEQ_READ_APPEND caches can
+    happen from both read buffer (byte* buffer) and write buffer
+    (byte* write_buffer).
+  */
+  byte *append_read_pos;
+  /* Points to current write position in the write buffer */
+  byte *write_pos;
+  /* The non-inclusive boundary of the valid write area */
+  byte *write_end;
+
+  /*
+    Current_pos and current_end are convenience variables used by
+    my_b_tell() and other routines that need to know the current offset
+    current_pos points to &write_pos, and current_end to &write_end in a
+    WRITE_CACHE, and &read_pos and &read_end respectively otherwise
+  */
+  byte  **current_pos, **current_end;
+#ifdef THREAD
+  /*
+    The lock is for append buffer used in SEQ_READ_APPEND cache
+    need mutex copying from append buffer to read buffer.
+  */
+  pthread_mutex_t append_buffer_lock;
+  /*
+    The following is used when several threads are reading the
+    same file in parallel. They are synchronized on disk
+    accesses reading the cached part of the file asynchronously.
+    It should be set to NULL to disable the feature.  Only
+    READ_CACHE mode is supported.
+  */
+  IO_CACHE_SHARE *share;
+#endif
+  /*
+    A caller will use my_b_read() macro to read from the cache
+    if the data is already in cache, it will be simply copied with
+    memcpy() and internal variables will be accordinging updated with
+    no functions invoked. However, if the data is not fully in the cache,
+    my_b_read() will call read_function to fetch the data. read_function
+    must never be invoked directly.
+  */
+  int (*read_function)(struct st_io_cache *,byte *,uint);
+  /*
+    Same idea as in the case of read_function, except my_b_write() needs to
+    be replaced with my_b_append() for a SEQ_READ_APPEND cache
+  */
+  int (*write_function)(struct st_io_cache *,const byte *,uint);
+  /*
+    Specifies the type of the cache. Depending on the type of the cache
+    certain operations might not be available and yield unpredicatable
+    results. Details to be documented later
+  */
+  enum cache_type type;
+  /*
+    Callbacks when the actual read I/O happens. These were added and
+    are currently used for binary logging of LOAD DATA INFILE - when a
+    block is read from the file, we create a block create/append event, and
+    when IO_CACHE is closed, we create an end event. These functions could,
+    of course be used for other things
+  */
+  IO_CACHE_CALLBACK pre_read;
+  IO_CACHE_CALLBACK post_read;
+  IO_CACHE_CALLBACK pre_close;
+  /*
+    Counts the number of times, when we were forced to use disk. We use it to
+    increase the binlog_cache_disk_use status variable.
+  */
+  ulong disk_writes;
+  void* arg;				/* for use by pre/post_read */
+  char *file_name;			/* if used with 'open_cached_file' */
+  char *dir,*prefix;
+  File file; /* file descriptor */
+  /*
+    seek_not_done is set by my_b_seek() to inform the upcoming read/write
+    operation that a seek needs to be preformed prior to the actual I/O
+    error is 0 if the cache operation was successful, -1 if there was a
+    "hard" error, and the actual number of I/O-ed bytes if the read/write was
+    partial.
+  */
+  int	seek_not_done,error;
+  /* buffer_length is memory size allocated for buffer or write_buffer */
+  uint	buffer_length;
+  /* read_length is the same as buffer_length except when we use async io */
+  uint  read_length;
+  myf	myflags;			/* Flags used to my_read/my_write */
+  /*
+    alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
+    0 if it was supplied by the user.
+    Currently READ_NET is the only one that will use a buffer allocated
+    somewhere else
+  */
+  my_bool alloced_buffer;
+#ifdef HAVE_AIOWAIT
+  /*
+    As inidicated by ifdef, this is for async I/O, which is not currently
+    used (because it's not reliable on all systems)
+  */
+  uint inited;
+  my_off_t aio_read_pos;
+  my_aio_result aio_result;
+#endif
+} IO_CACHE;
+
+typedef int (*qsort2_cmp)(const void *, const void *, const void *);
+
+	/* defines for mf_iocache */
+
+	/* Test if buffer is inited */
+#define my_b_clear(info) (info)->buffer=0
+#define my_b_inited(info) (info)->buffer
+#define my_b_EOF INT_MIN
+
+#define my_b_read(info,Buffer,Count) \
+  ((info)->read_pos + (Count) <= (info)->read_end ?\
+   (memcpy(Buffer,(info)->read_pos,(size_t) (Count)), \
+    ((info)->read_pos+=(Count)),0) :\
+   (*(info)->read_function)((info),Buffer,Count))
+
+#define my_b_write(info,Buffer,Count) \
+ ((info)->write_pos + (Count) <=(info)->write_end ?\
+  (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\
+   ((info)->write_pos+=(Count)),0) : \
+   (*(info)->write_function)((info),(Buffer),(Count)))
+
+#define my_b_get(info) \
+  ((info)->read_pos != (info)->read_end ?\
+   ((info)->read_pos++, (int) (uchar) (info)->read_pos[-1]) :\
+   _my_b_get(info))
+
+	/* my_b_write_byte dosn't have any err-check */
+#define my_b_write_byte(info,chr) \
+  (((info)->write_pos < (info)->write_end) ?\
+   ((*(info)->write_pos++)=(chr)) :\
+   (_my_b_write(info,0,0) , ((*(info)->write_pos++)=(chr))))
+
+#define my_b_fill_cache(info) \
+  (((info)->read_end=(info)->read_pos),(*(info)->read_function)(info,0,0))
+
+#define my_b_tell(info) ((info)->pos_in_file + \
+			 (uint) (*(info)->current_pos - (info)->request_pos))
+
+#define my_b_get_buffer_start(info) (info)->request_pos 
+#define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end -   \
+  (char*) my_b_get_buffer_start(info)
+#define my_b_get_pos_in_file(info) (info)->pos_in_file
+
+
+/* tell write offset in the SEQ_APPEND cache */
+my_off_t my_b_append_tell(IO_CACHE* info);
+my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */
+
+#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
+					  *(info)->current_pos)
+
+typedef uint32 ha_checksum;
+
+/* Define the type of function to be passed to process_default_option_files */
+typedef int (*Process_option_func)(void *ctx, const char *group_name,
+                                   const char *option);
+
+#include 
+
+
+	/* Prototypes for mysys and my_func functions */
+
+extern int my_copy(const char *from,const char *to,myf MyFlags);
+extern int my_append(const char *from,const char *to,myf MyFlags);
+extern int my_delete(const char *name,myf MyFlags);
+extern int my_getwd(my_string buf,uint size,myf MyFlags);
+extern int my_setwd(const char *dir,myf MyFlags);
+extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags);
+extern gptr my_once_alloc(uint Size,myf MyFlags);
+extern void my_once_free(void);
+extern char *my_once_strdup(const char *src,myf myflags);
+extern char *my_once_memdup(const char *src, uint len, myf myflags);
+extern File my_open(const char *FileName,int Flags,myf MyFlags);
+extern File my_register_filename(File fd, const char *FileName,
+				 enum file_type type_of_file,
+				 uint error_message_number, myf MyFlags);
+extern File my_create(const char *FileName,int CreateFlags,
+		      int AccsesFlags, myf MyFlags);
+extern int my_close(File Filedes,myf MyFlags);
+extern File my_dup(File file, myf MyFlags);
+extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
+extern int my_readlink(char *to, const char *filename, myf MyFlags);
+extern int my_realpath(char *to, const char *filename, myf MyFlags);
+extern File my_create_with_symlink(const char *linkname, const char *filename,
+				   int createflags, int access_flags,
+				   myf MyFlags);
+extern int my_delete_with_symlink(const char *name, myf MyFlags);
+extern int my_rename_with_symlink(const char *from,const char *to,myf MyFlags);
+extern int my_symlink(const char *content, const char *linkname, myf MyFlags);
+extern uint my_read(File Filedes,byte *Buffer,uint Count,myf MyFlags);
+extern uint my_pread(File Filedes,byte *Buffer,uint Count,my_off_t offset,
+		     myf MyFlags);
+extern int my_rename(const char *from,const char *to,myf MyFlags);
+extern my_off_t my_seek(File fd,my_off_t pos,int whence,myf MyFlags);
+extern my_off_t my_tell(File fd,myf MyFlags);
+extern uint my_write(File Filedes,const byte *Buffer,uint Count,
+		     myf MyFlags);
+extern uint my_pwrite(File Filedes,const byte *Buffer,uint Count,
+		      my_off_t offset,myf MyFlags);
+extern uint my_fread(FILE *stream,byte *Buffer,uint Count,myf MyFlags);
+extern uint my_fwrite(FILE *stream,const byte *Buffer,uint Count,
+		      myf MyFlags);
+extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags);
+extern my_off_t my_ftell(FILE *stream,myf MyFlags);
+extern gptr _mymalloc(size_t uSize, const char *sFile,
+                       uint uLine, myf MyFlag);
+extern gptr _myrealloc(gptr pPtr, size_t uSize, const char *sFile,
+                        uint uLine, myf MyFlag);
+extern gptr my_multi_malloc _VARARGS((myf MyFlags, ...));
+extern void _myfree(gptr pPtr, const char *sFile, uint uLine, myf MyFlag);
+extern int _sanity(const char *sFile,unsigned int uLine);
+extern gptr _my_memdup(const byte *from, size_t length,
+                        const char *sFile, uint uLine, myf MyFlag);
+extern my_string _my_strdup(const char *from, const char *sFile, uint uLine,
+			    myf MyFlag);
+extern char *_my_strdup_with_length(const char *from, size_t length,
+				    const char *sFile, uint uLine,
+				    myf MyFlag);
+
+/* implemented in my_memmem.c */
+extern void *my_memmem(const void *haystack, size_t haystacklen,
+    const void *needle, size_t needlelen);
+
+
+#ifdef __WIN__
+extern int my_access(const char *path, int amode);
+extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+#else
+#define my_access access
+#endif
+extern int check_if_legal_filename(const char *path);
+
+#if defined(__WIN__) && defined(__NT__)
+extern int nt_share_delete(const char *name,myf MyFlags);
+#define my_delete_allow_opened(fname,flags)  nt_share_delete((fname),(flags))
+#else
+#define my_delete_allow_opened(fname,flags)  my_delete((fname),(flags))
+#endif
+
+#ifndef TERMINATE
+extern void TERMINATE(FILE *file);
+#endif
+extern void init_glob_errs(void);
+extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
+extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
+extern int my_fclose(FILE *fd,myf MyFlags);
+extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
+extern int my_sync(File fd, myf my_flags);
+extern int my_error _VARARGS((int nr,myf MyFlags, ...));
+extern int my_printf_error _VARARGS((uint my_err, const char *format,
+				     myf MyFlags, ...))
+				    ATTRIBUTE_FORMAT(printf, 2, 4);
+extern int my_error_register(const char **errmsgs, int first, int last);
+extern const char **my_error_unregister(int first, int last);
+extern int my_message(uint my_err, const char *str,myf MyFlags);
+extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
+extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
+extern my_bool my_init(void);
+extern void my_end(int infoflag);
+extern int my_redel(const char *from, const char *to, int MyFlags);
+extern int my_copystat(const char *from, const char *to, int MyFlags);
+extern my_string my_filename(File fd);
+
+#ifndef THREAD
+extern void dont_break(void);
+extern void allow_break(void);
+#else
+#define dont_break()
+#define allow_break()
+#endif
+
+extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist);
+extern char *my_tmpdir(MY_TMPDIR *tmpdir);
+extern void free_tmpdir(MY_TMPDIR *tmpdir);
+
+extern void my_remember_signal(int signal_number,sig_handler (*func)(int));
+extern uint dirname_part(my_string to,const char *name);
+extern uint dirname_length(const char *name);
+#define base_name(A) (A+dirname_length(A))
+extern int test_if_hard_path(const char *dir_name);
+extern my_bool has_path(const char *name);
+extern char *convert_dirname(char *to, const char *from, const char *from_end);
+extern void to_unix_path(my_string name);
+extern my_string fn_ext(const char *name);
+extern my_string fn_same(my_string toname,const char *name,int flag);
+extern my_string fn_format(my_string to,const char *name,const char *dir,
+			   const char *form, uint flag);
+extern size_s strlength(const char *str);
+extern void pack_dirname(my_string to,const char *from);
+extern uint unpack_dirname(my_string to,const char *from);
+extern uint cleanup_dirname(my_string to,const char *from);
+extern uint system_filename(my_string to,const char *from);
+extern uint unpack_filename(my_string to,const char *from);
+extern my_string intern_filename(my_string to,const char *from);
+extern my_string directory_file_name(my_string dst, const char *src);
+extern int pack_filename(my_string to, const char *name, size_s max_length);
+extern my_string my_path(my_string to,const char *progname,
+			 const char *own_pathname_part);
+extern my_string my_load_path(my_string to, const char *path,
+			      const char *own_path_prefix);
+extern int wild_compare(const char *str,const char *wildstr,pbool str_is_pattern);
+extern WF_PACK *wf_comp(my_string str);
+extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
+extern void wf_end(struct wild_file_pack *buffer);
+extern size_s strip_sp(my_string str);
+extern my_bool array_append_string_unique(const char *str,
+                                          const char **array, size_t size);
+extern void get_date(my_string to,int timeflag,time_t use_time);
+extern void soundex(CHARSET_INFO *, my_string out_pntr, my_string in_pntr,pbool remove_garbage);
+extern int init_record_cache(RECORD_CACHE *info,uint cachesize,File file,
+			     uint reclength,enum cache_type type,
+			     pbool use_async_io);
+extern int read_cache_record(RECORD_CACHE *info,byte *to);
+extern int end_record_cache(RECORD_CACHE *info);
+extern int write_cache_record(RECORD_CACHE *info,my_off_t filepos,
+			      const byte *record,uint length);
+extern int flush_write_cache(RECORD_CACHE *info);
+extern long my_clock(void);
+extern sig_handler sigtstp_handler(int signal_number);
+extern void handle_recived_signals(void);
+
+extern sig_handler my_set_alarm_variable(int signo);
+extern void my_string_ptr_sort(void *base,uint items,size_s size);
+extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
+				  size_s size_of_element,uchar *buffer[]);
+extern qsort_t my_qsort(void *base_ptr, size_t total_elems, size_t size,
+                        qsort_cmp cmp);
+extern qsort_t my_qsort2(void *base_ptr, size_t total_elems, size_t size,
+                         qsort2_cmp cmp, void *cmp_argument);
+extern qsort2_cmp get_ptr_compare(uint);
+void my_store_ptr(byte *buff, uint pack_length, my_off_t pos);
+my_off_t my_get_ptr(byte *ptr, uint pack_length);
+extern int init_io_cache(IO_CACHE *info,File file,uint cachesize,
+			 enum cache_type type,my_off_t seek_offset,
+			 pbool use_async_io, myf cache_myflags);
+extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
+			       my_off_t seek_offset,pbool use_async_io,
+			       pbool clear_cache);
+extern void setup_io_cache(IO_CACHE* info);
+extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
+#ifdef THREAD
+extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);
+extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
+                                IO_CACHE *write_cache, uint num_threads);
+extern void remove_io_thread(IO_CACHE *info);
+#endif
+extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count);
+extern int _my_b_net_read(IO_CACHE *info,byte *Buffer,uint Count);
+extern int _my_b_get(IO_CACHE *info);
+extern int _my_b_async_read(IO_CACHE *info,byte *Buffer,uint Count);
+extern int _my_b_write(IO_CACHE *info,const byte *Buffer,uint Count);
+extern int my_b_append(IO_CACHE *info,const byte *Buffer,uint Count);
+extern int my_b_safe_write(IO_CACHE *info,const byte *Buffer,uint Count);
+
+extern int my_block_write(IO_CACHE *info, const byte *Buffer,
+			  uint Count, my_off_t pos);
+extern int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
+
+#define flush_io_cache(info) my_b_flush_io_cache((info),1)
+
+extern int end_io_cache(IO_CACHE *info);
+extern uint my_b_fill(IO_CACHE *info);
+extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+extern uint my_b_gets(IO_CACHE *info, char *to, uint max_length);
+extern my_off_t my_b_filelength(IO_CACHE *info);
+extern uint my_b_printf(IO_CACHE *info, const char* fmt, ...);
+extern uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
+extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
+				 const char *prefix, uint cache_size,
+				 myf cache_myflags);
+extern my_bool real_open_cached_file(IO_CACHE *cache);
+extern void close_cached_file(IO_CACHE *cache);
+File create_temp_file(char *to, const char *dir, const char *pfx,
+		      int mode, myf MyFlags);
+#define my_init_dynamic_array(A,B,C,D) init_dynamic_array(A,B,C,D CALLER_INFO)
+#define my_init_dynamic_array_ci(A,B,C,D) init_dynamic_array(A,B,C,D ORIG_CALLER_INFO)
+extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size,
+                                  uint init_alloc,uint alloc_increment
+                                  CALLER_INFO_PROTO);
+extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,gptr element);
+extern byte *alloc_dynamic(DYNAMIC_ARRAY *array);
+extern byte *pop_dynamic(DYNAMIC_ARRAY*);
+extern my_bool set_dynamic(DYNAMIC_ARRAY *array,gptr element,uint array_index);
+extern void get_dynamic(DYNAMIC_ARRAY *array,gptr element,uint array_index);
+extern void delete_dynamic(DYNAMIC_ARRAY *array);
+extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index);
+extern void freeze_size(DYNAMIC_ARRAY *array);
+#define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element)
+#define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
+#define push_dynamic(A,B) insert_dynamic(A,B)
+#define reset_dynamic(array) ((array)->elements= 0)
+
+extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
+				   uint init_alloc,uint alloc_increment);
+extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
+my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
+			  uint length);
+extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append,
+                                       ...);
+extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
+extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
+extern void dynstr_free(DYNAMIC_STRING *str);
+#ifdef HAVE_MLOCK
+extern byte *my_malloc_lock(uint length,myf flags);
+extern void my_free_lock(byte *ptr,myf flags);
+#else
+#define my_malloc_lock(A,B) my_malloc((A),(B))
+#define my_free_lock(A,B) my_free((A),(B))
+#endif
+#define alloc_root_inited(A) ((A)->min_malloc != 0)
+#define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8)
+#define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; (A)->min_malloc=0;} while(0)
+extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
+			    uint pre_alloc_size);
+extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
+extern gptr multi_alloc_root(MEM_ROOT *mem_root, ...);
+extern void free_root(MEM_ROOT *root, myf MyFLAGS);
+extern void set_prealloc_root(MEM_ROOT *root, char *ptr);
+extern void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
+                                uint prealloc_size);
+extern char *strdup_root(MEM_ROOT *root,const char *str);
+extern char *strmake_root(MEM_ROOT *root,const char *str,uint len);
+extern char *memdup_root(MEM_ROOT *root,const char *str,uint len);
+extern int get_defaults_options(int argc, char **argv,
+                                char **defaults, char **extra_defaults,
+                                char **group_suffix);
+extern int load_defaults(const char *conf_file, const char **groups,
+			 int *argc, char ***argv);
+extern int modify_defaults_file(const char *file_location, const char *option,
+                                const char *option_value,
+                                const char *section_name, int remove_option);
+extern int my_search_option_files(const char *conf_file, int *argc,
+                                  char ***argv, uint *args_used,
+                                  Process_option_func func, void *func_ctx);
+extern void free_defaults(char **argv);
+extern void my_print_default_files(const char *conf_file);
+extern void print_defaults(const char *conf_file, const char **groups);
+extern my_bool my_compress(byte *, ulong *, ulong *);
+extern my_bool my_uncompress(byte *, ulong *, ulong *);
+extern byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
+extern ha_checksum my_checksum(ha_checksum crc, const byte *mem, uint count);
+extern uint my_bit_log2(ulong value);
+extern uint my_count_bits(ulonglong v);
+extern uint my_count_bits_ushort(ushort v);
+extern void my_sleep(ulong m_seconds);
+extern ulong crc32(ulong crc, const uchar *buf, uint len);
+extern uint my_set_max_open_files(uint files);
+void my_free_open_file_info(void);
+
+ulonglong my_getsystime(void);
+my_bool my_gethwaddr(uchar *to);
+
+#ifdef HAVE_SYS_MMAN_H
+#include 
+
+#ifndef MAP_NOSYNC
+#define MAP_NOSYNC      0
+#endif
+
+#define my_mmap(a,b,c,d,e,f)    mmap(a,b,c,d,e,f)
+#define my_munmap(a,b)          munmap((a),(b))
+
+#else
+/* not a complete set of mmap() flags, but only those that nesessary */
+#define PROT_READ        1
+#define PROT_WRITE       2
+#define MAP_SHARED       0x0001
+#define MAP_NOSYNC       0x0800
+#define MAP_FAILED       ((void *)-1)
+#define MS_SYNC          0x0000
+
+#ifndef __NETWARE__
+#define HAVE_MMAP
+#endif
+
+void *my_mmap(void *, size_t, int, int, int, my_off_t);
+int my_munmap(void *, size_t);
+#endif
+
+/* my_getpagesize */
+#ifdef HAVE_GETPAGESIZE
+#define my_getpagesize()        getpagesize()
+#else
+int my_getpagesize(void);
+#endif
+
+int my_msync(int, void *, size_t, int);
+
+/* character sets */
+extern uint get_charset_number(const char *cs_name, uint cs_flags);
+extern uint get_collation_number(const char *name);
+extern const char *get_charset_name(uint cs_number);
+
+extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
+extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
+extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
+					   uint cs_flags, myf my_flags);
+extern CHARSET_INFO *get_compatible_charset_with_ctype(CHARSET_INFO
+                                                       *original_cs);
+extern void free_charsets(void);
+extern char *get_charsets_dir(char *buf);
+extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
+extern my_bool init_compiled_charsets(myf flags);
+extern void add_compiled_collation(CHARSET_INFO *cs);
+extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
+                                     char *to, ulong to_length,
+                                     const char *from, ulong length);
+#ifdef __WIN__
+#define BACKSLASH_MBTAIL
+/* File system character set */
+extern CHARSET_INFO *fs_character_set(void);
+#endif
+extern ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
+                                     char *to, ulong to_length,
+                                     const char *from, ulong length);
+
+extern void thd_increment_bytes_sent(ulong length);
+extern void thd_increment_bytes_received(ulong length);
+extern void thd_increment_net_big_packet_count(ulong length);
+
+#ifdef __WIN__
+extern my_bool have_tcpip;		/* Is set if tcpip is used */
+
+/* implemented in my_windac.c */
+
+int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
+                            DWORD owner_rights, DWORD everybody_rights);
+
+void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
+
+/* implemented in my_conio.c */
+char* my_cgets(char *string, unsigned long clen, unsigned long* plen);
+
+#endif
+#ifdef __NETWARE__
+void netware_reg_user(const char *ip, const char *user,
+		      const char *application);
+#endif
+
+C_MODE_END
+#include "raid.h"
+#endif /* _my_sys_h */
diff --git a/dep/include/mysql/mysql.h b/dep/include/mysql/mysql.h
new file mode 100644
index 000000000..18b82b8a9
--- /dev/null
+++ b/dep/include/mysql/mysql.h
@@ -0,0 +1,871 @@
+/* Copyright (C) 2000-2003 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/*
+  This file defines the client API to MySQL and also the ABI of the
+  dynamically linked libmysqlclient.
+
+  The ABI should never be changed in a released product of MySQL
+  thus you need to take great care when changing the file. In case
+  the file is changed so the ABI is broken, you must also
+  update the SHAREDLIB_MAJOR_VERSION in configure.in .
+
+*/
+
+#ifndef _mysql_h
+#define _mysql_h
+
+#ifdef _AIX           /* large-file support will break without this */
+#include 
+#endif
+
+#ifdef __CYGWIN__     /* CYGWIN implements a UNIX API */
+#undef WIN
+#undef _WIN
+#undef _WIN32
+#undef _WIN64
+#undef __WIN__
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef _global_h				/* If not standard header */
+#include 
+#ifdef __LCC__
+#include 				/* For windows */
+#endif
+typedef char my_bool;
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__)
+#define __WIN__
+#endif
+#if !defined(__WIN__)
+#define STDCALL
+#else
+#define STDCALL __stdcall
+#endif
+typedef char * gptr;
+
+#ifndef my_socket_defined
+#ifdef __WIN__
+#define my_socket SOCKET
+#else
+typedef int my_socket;
+#endif /* __WIN__ */
+#endif /* my_socket_defined */
+#endif /* _global_h */
+
+#include "mysql_version.h"
+#include "mysql_com.h"
+#include "mysql_time.h"
+#include "typelib.h"
+
+#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */
+
+extern unsigned int mysql_port;
+extern char *mysql_unix_port;
+
+#define CLIENT_NET_READ_TIMEOUT		365*24*3600	/* Timeout on read */
+#define CLIENT_NET_WRITE_TIMEOUT	365*24*3600	/* Timeout on write */
+
+#ifdef __NETWARE__
+// GCC have alternative #pragma pack(8) syntax and old gcc version not support pack(push,8), also any gcc version not support it at some paltform
+#if defined( __GNUC__ )
+#pragma pack(8) 
+#else 
+#pragma pack(push,8) 
+#endif 
+
+#endif
+
+#define IS_PRI_KEY(n)	((n) & PRI_KEY_FLAG)
+#define IS_NOT_NULL(n)	((n) & NOT_NULL_FLAG)
+#define IS_BLOB(n)	((n) & BLOB_FLAG)
+#define IS_NUM(t)	((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)
+#define IS_NUM_FIELD(f)	 ((f)->flags & NUM_FLAG)
+#define INTERNAL_NUM_FIELD(f) (((f)->type <= FIELD_TYPE_INT24 && ((f)->type != FIELD_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == FIELD_TYPE_YEAR)
+#define IS_LONGDATA(t) ((t) >= MYSQL_TYPE_TINY_BLOB && (t) <= MYSQL_TYPE_STRING)
+
+
+typedef struct st_mysql_field {
+  char *name;                 /* Name of column */
+  char *org_name;             /* Original column name, if an alias */
+  char *table;                /* Table of column if column was a field */
+  char *org_table;            /* Org table name, if table was an alias */
+  char *db;                   /* Database for table */
+  char *catalog;	      /* Catalog for table */
+  char *def;                  /* Default value (set by mysql_list_fields) */
+  unsigned long length;       /* Width of column (create length) */
+  unsigned long max_length;   /* Max width for selected set */
+  unsigned int name_length;
+  unsigned int org_name_length;
+  unsigned int table_length;
+  unsigned int org_table_length;
+  unsigned int db_length;
+  unsigned int catalog_length;
+  unsigned int def_length;
+  unsigned int flags;         /* Div flags */
+  unsigned int decimals;      /* Number of decimals in field */
+  unsigned int charsetnr;     /* Character set */
+  enum enum_field_types type; /* Type of field. See mysql_com.h for types */
+} MYSQL_FIELD;
+
+typedef char **MYSQL_ROW;		/* return data as array of strings */
+typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
+
+#ifndef _global_h
+#if defined(NO_CLIENT_LONG_LONG)
+typedef unsigned long my_ulonglong;
+#elif defined (__WIN__)
+typedef unsigned __int64 my_ulonglong;
+#else
+typedef unsigned long long my_ulonglong;
+#endif
+#endif
+
+#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
+
+/* backward compatibility define - to be removed eventually */
+#define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED
+
+typedef struct st_mysql_rows {
+  struct st_mysql_rows *next;		/* list of rows */
+  MYSQL_ROW data;
+  unsigned long length;
+} MYSQL_ROWS;
+
+typedef MYSQL_ROWS *MYSQL_ROW_OFFSET;	/* offset to current row */
+
+#include "my_alloc.h"
+
+typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
+typedef struct st_mysql_data {
+  my_ulonglong rows;
+  unsigned int fields;
+  MYSQL_ROWS *data;
+  MEM_ROOT alloc;
+  /* extra info for embedded library */
+  struct embedded_query_result *embedded_info;
+} MYSQL_DATA;
+
+enum mysql_option 
+{
+  MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
+  MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
+  MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
+  MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
+  MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
+  MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
+  MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
+  MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+  MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+};
+
+struct st_mysql_options {
+  unsigned int connect_timeout, read_timeout, write_timeout;
+  unsigned int port, protocol;
+  unsigned long client_flag;
+  char *host,*user,*password,*unix_socket,*db;
+  struct st_dynamic_array *init_commands;
+  char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
+  char *ssl_key;				/* PEM key file */
+  char *ssl_cert;				/* PEM cert file */
+  char *ssl_ca;					/* PEM CA file */
+  char *ssl_capath;				/* PEM directory of CA-s? */
+  char *ssl_cipher;				/* cipher to use */
+  char *shared_memory_base_name;
+  unsigned long max_allowed_packet;
+  my_bool use_ssl;				/* if to use SSL or not */
+  my_bool compress,named_pipe;
+ /*
+   On connect, find out the replication role of the server, and
+   establish connections to all the peers
+ */
+  my_bool rpl_probe;
+ /*
+   Each call to mysql_real_query() will parse it to tell if it is a read
+   or a write, and direct it to the slave or the master
+ */
+  my_bool rpl_parse;
+ /*
+   If set, never read from a master, only from slave, when doing
+   a read that is replication-aware
+ */
+  my_bool no_master_reads;
+#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
+  my_bool separate_thread;
+#endif
+  enum mysql_option methods_to_use;
+  char *client_ip;
+  /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
+  my_bool secure_auth;
+  /* 0 - never report, 1 - always report (default) */
+  my_bool report_data_truncation;
+
+  /* function pointers for local infile support */
+  int (*local_infile_init)(void **, const char *, void *);
+  int (*local_infile_read)(void *, char *, unsigned int);
+  void (*local_infile_end)(void *);
+  int (*local_infile_error)(void *, char *, unsigned int);
+  void *local_infile_userdata;
+};
+
+enum mysql_status 
+{
+  MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
+};
+
+enum mysql_protocol_type 
+{
+  MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
+  MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
+};
+/*
+  There are three types of queries - the ones that have to go to
+  the master, the ones that go to a slave, and the adminstrative
+  type which must happen on the pivot connectioin
+*/
+enum mysql_rpl_type 
+{
+  MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
+};
+
+typedef struct character_set
+{
+  unsigned int      number;     /* character set number              */
+  unsigned int      state;      /* character set state               */
+  const char        *csname;    /* collation name                    */
+  const char        *name;      /* character set name                */
+  const char        *comment;   /* comment                           */
+  const char        *dir;       /* character set directory           */
+  unsigned int      mbminlen;   /* min. length for multibyte strings */
+  unsigned int      mbmaxlen;   /* max. length for multibyte strings */
+} MY_CHARSET_INFO;
+
+struct st_mysql_methods;
+struct st_mysql_stmt;
+
+typedef struct st_mysql
+{
+  NET		net;			/* Communication parameters */
+  gptr		connector_fd;		/* ConnectorFd for SSL */
+  char		*host,*user,*passwd,*unix_socket,*server_version,*host_info,*info;
+  char          *db;
+  struct charset_info_st *charset;
+  MYSQL_FIELD	*fields;
+  MEM_ROOT	field_alloc;
+  my_ulonglong affected_rows;
+  my_ulonglong insert_id;		/* id if insert on table with NEXTNR */
+  my_ulonglong extra_info;		/* Not used */
+  unsigned long thread_id;		/* Id for connection in server */
+  unsigned long packet_length;
+  unsigned int	port;
+  unsigned long client_flag,server_capabilities;
+  unsigned int	protocol_version;
+  unsigned int	field_count;
+  unsigned int 	server_status;
+  unsigned int  server_language;
+  unsigned int	warning_count;
+  struct st_mysql_options options;
+  enum mysql_status status;
+  my_bool	free_me;		/* If free in mysql_close */
+  my_bool	reconnect;		/* set to 1 if automatic reconnect */
+
+  /* session-wide random string */
+  char	        scramble[SCRAMBLE_LENGTH+1];
+
+ /*
+   Set if this is the original connection, not a master or a slave we have
+   added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()
+ */
+  my_bool rpl_pivot;
+  /*
+    Pointers to the master, and the next slave connections, points to
+    itself if lone connection.
+  */
+  struct st_mysql* master, *next_slave;
+
+  struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
+ /* needed for send/read/store/use result to work correctly with replication */
+  struct st_mysql* last_used_con;
+
+  LIST  *stmts;                     /* list of all statements */
+  const struct st_mysql_methods *methods;
+  void *thd;
+  /*
+    Points to boolean flag in MYSQL_RES  or MYSQL_STMT. We set this flag 
+    from mysql_stmt_close if close had to cancel result set of this object.
+  */
+  my_bool *unbuffered_fetch_owner;
+#if defined(EMBEDDED_LIBRARY) || defined(EMBEDDED_LIBRARY_COMPATIBLE) || MYSQL_VERSION_ID >= 50100
+  /* needed for embedded server - no net buffer to store the 'info' */
+  char *info_buffer;
+#endif
+} MYSQL;
+
+typedef struct st_mysql_res {
+  my_ulonglong row_count;
+  MYSQL_FIELD	*fields;
+  MYSQL_DATA	*data;
+  MYSQL_ROWS	*data_cursor;
+  unsigned long *lengths;		/* column lengths of current row */
+  MYSQL		*handle;		/* for unbuffered reads */
+  MEM_ROOT	field_alloc;
+  unsigned int	field_count, current_field;
+  MYSQL_ROW	row;			/* If unbuffered read */
+  MYSQL_ROW	current_row;		/* buffer to current row */
+  my_bool	eof;			/* Used by mysql_fetch_row */
+  /* mysql_stmt_close() had to cancel this result */
+  my_bool       unbuffered_fetch_cancelled;  
+  const struct st_mysql_methods *methods;
+} MYSQL_RES;
+
+#define MAX_MYSQL_MANAGER_ERR 256  
+#define MAX_MYSQL_MANAGER_MSG 256
+
+#define MANAGER_OK           200
+#define MANAGER_INFO         250
+#define MANAGER_ACCESS       401
+#define MANAGER_CLIENT_ERR   450
+#define MANAGER_INTERNAL_ERR 500
+
+#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT)
+#define MYSQL_CLIENT
+#endif
+
+
+typedef struct st_mysql_manager
+{
+  NET net;
+  char *host,*user,*passwd;
+  unsigned int port;
+  my_bool free_me;
+  my_bool eof;
+  int cmd_status;
+  int last_errno;
+  char* net_buf,*net_buf_pos,*net_data_end;
+  int net_buf_size;
+  char last_error[MAX_MYSQL_MANAGER_ERR];
+} MYSQL_MANAGER;
+
+typedef struct st_mysql_parameters
+{
+  unsigned long *p_max_allowed_packet;
+  unsigned long *p_net_buffer_length;
+} MYSQL_PARAMETERS;
+
+#if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet)
+#define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length)
+#endif
+
+/*
+  Set up and bring down the server; to ensure that applications will
+  work when linked against either the standard client library or the
+  embedded server library, these functions should be called.
+*/
+int STDCALL mysql_server_init(int argc, char **argv, char **groups);
+void STDCALL mysql_server_end(void);
+/*
+  mysql_server_init/end need to be called when using libmysqld or
+  libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so
+  you don't need to call it explicitely; but you need to call
+  mysql_server_end() to free memory). The names are a bit misleading
+  (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general
+  names which suit well whether you're using libmysqld or libmysqlclient. We
+  intend to promote these aliases over the mysql_server* ones.
+*/
+#define mysql_library_init mysql_server_init
+#define mysql_library_end mysql_server_end
+
+MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void);
+
+/*
+  Set up and bring down a thread; these function should be called
+  for each thread in an application which opens at least one MySQL
+  connection.  All uses of the connection(s) should be between these
+  function calls.
+*/
+my_bool STDCALL mysql_thread_init(void);
+void STDCALL mysql_thread_end(void);
+
+/*
+  Functions to get information from the MYSQL and MYSQL_RES structures
+  Should definitely be used if one uses shared libraries.
+*/
+
+my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
+unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
+my_bool STDCALL mysql_eof(MYSQL_RES *res);
+MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
+					      unsigned int fieldnr);
+MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res);
+
+unsigned int STDCALL mysql_field_count(MYSQL *mysql);
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
+my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
+unsigned int STDCALL mysql_errno(MYSQL *mysql);
+const char * STDCALL mysql_error(MYSQL *mysql);
+const char *STDCALL mysql_sqlstate(MYSQL *mysql);
+unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
+const char * STDCALL mysql_info(MYSQL *mysql);
+unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
+const char * STDCALL mysql_character_set_name(MYSQL *mysql);
+int          STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname);
+
+MYSQL *		STDCALL mysql_init(MYSQL *mysql);
+my_bool		STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
+				      const char *cert, const char *ca,
+				      const char *capath, const char *cipher);
+const char *    STDCALL mysql_get_ssl_cipher(MYSQL *mysql);
+my_bool		STDCALL mysql_change_user(MYSQL *mysql, const char *user, 
+					  const char *passwd, const char *db);
+MYSQL *		STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
+					   const char *user,
+					   const char *passwd,
+					   const char *db,
+					   unsigned int port,
+					   const char *unix_socket,
+					   unsigned long clientflag);
+int		STDCALL mysql_select_db(MYSQL *mysql, const char *db);
+int		STDCALL mysql_query(MYSQL *mysql, const char *q);
+int		STDCALL mysql_send_query(MYSQL *mysql, const char *q,
+					 unsigned long length);
+int		STDCALL mysql_real_query(MYSQL *mysql, const char *q,
+					unsigned long length);
+MYSQL_RES *     STDCALL mysql_store_result(MYSQL *mysql);
+MYSQL_RES *     STDCALL mysql_use_result(MYSQL *mysql);
+
+/* perform query on master */
+my_bool		STDCALL mysql_master_query(MYSQL *mysql, const char *q,
+					   unsigned long length);
+my_bool		STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
+						unsigned long length);
+/* perform query on slave */  
+my_bool		STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
+					  unsigned long length);
+my_bool		STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
+					       unsigned long length);
+void        STDCALL mysql_get_character_set_info(MYSQL *mysql,
+                           MY_CHARSET_INFO *charset);
+
+/* local infile support */
+
+#define LOCAL_INFILE_ERROR_LEN 512
+
+void
+mysql_set_local_infile_handler(MYSQL *mysql,
+                               int (*local_infile_init)(void **, const char *,
+                            void *),
+                               int (*local_infile_read)(void *, char *,
+							unsigned int),
+                               void (*local_infile_end)(void *),
+                               int (*local_infile_error)(void *, char*,
+							 unsigned int),
+                               void *);
+
+void
+mysql_set_local_infile_default(MYSQL *mysql);
+
+
+/*
+  enable/disable parsing of all queries to decide if they go on master or
+  slave
+*/
+void            STDCALL mysql_enable_rpl_parse(MYSQL* mysql);
+void            STDCALL mysql_disable_rpl_parse(MYSQL* mysql);
+/* get the value of the parse flag */  
+int             STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
+
+/*  enable/disable reads from master */
+void            STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
+void            STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
+/* get the value of the master read flag */  
+my_bool		STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
+
+enum mysql_rpl_type     STDCALL mysql_rpl_query_type(const char* q, int len);  
+
+/* discover the master and its slaves */  
+my_bool		STDCALL mysql_rpl_probe(MYSQL* mysql);
+
+/* set the master, close/free the old one, if it is not a pivot */
+int             STDCALL mysql_set_master(MYSQL* mysql, const char* host,
+					 unsigned int port,
+					 const char* user,
+					 const char* passwd);
+int             STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
+					unsigned int port,
+					const char* user,
+					const char* passwd);
+
+int		STDCALL mysql_shutdown(MYSQL *mysql,
+                                       enum mysql_enum_shutdown_level
+                                       shutdown_level);
+int		STDCALL mysql_dump_debug_info(MYSQL *mysql);
+int		STDCALL mysql_refresh(MYSQL *mysql,
+				     unsigned int refresh_options);
+int		STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
+int		STDCALL mysql_set_server_option(MYSQL *mysql,
+						enum enum_mysql_set_option
+						option);
+int		STDCALL mysql_ping(MYSQL *mysql);
+const char *	STDCALL mysql_stat(MYSQL *mysql);
+const char *	STDCALL mysql_get_server_info(MYSQL *mysql);
+const char *	STDCALL mysql_get_client_info(void);
+unsigned long	STDCALL mysql_get_client_version(void);
+const char *	STDCALL mysql_get_host_info(MYSQL *mysql);
+unsigned long	STDCALL mysql_get_server_version(MYSQL *mysql);
+unsigned int	STDCALL mysql_get_proto_info(MYSQL *mysql);
+MYSQL_RES *	STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
+MYSQL_RES *	STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
+MYSQL_RES *	STDCALL mysql_list_processes(MYSQL *mysql);
+int		STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
+				      const char *arg);
+void		STDCALL mysql_free_result(MYSQL_RES *result);
+void		STDCALL mysql_data_seek(MYSQL_RES *result,
+					my_ulonglong offset);
+MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
+						MYSQL_ROW_OFFSET offset);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
+					   MYSQL_FIELD_OFFSET offset);
+MYSQL_ROW	STDCALL mysql_fetch_row(MYSQL_RES *result);
+unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result);
+MYSQL_FIELD *	STDCALL mysql_fetch_field(MYSQL_RES *result);
+MYSQL_RES *     STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
+					  const char *wild);
+unsigned long	STDCALL mysql_escape_string(char *to,const char *from,
+					    unsigned long from_length);
+unsigned long	STDCALL mysql_hex_string(char *to,const char *from,
+                                         unsigned long from_length);
+unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
+					       char *to,const char *from,
+					       unsigned long length);
+void		STDCALL mysql_debug(const char *debug);
+void 		STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
+unsigned int	STDCALL mysql_thread_safe(void);
+my_bool		STDCALL mysql_embedded(void);
+MYSQL_MANAGER*  STDCALL mysql_manager_init(MYSQL_MANAGER* con);  
+MYSQL_MANAGER*  STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
+					      const char* host,
+					      const char* user,
+					      const char* passwd,
+					      unsigned int port);
+void            STDCALL mysql_manager_close(MYSQL_MANAGER* con);
+int             STDCALL mysql_manager_command(MYSQL_MANAGER* con,
+						const char* cmd, int cmd_len);
+int             STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
+						  char* res_buf,
+						 int res_buf_size);
+my_bool         STDCALL mysql_read_query_result(MYSQL *mysql);
+
+
+/*
+  The following definitions are added for the enhanced 
+  client-server protocol
+*/
+
+/* statement state */
+enum enum_mysql_stmt_state
+{
+  MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
+  MYSQL_STMT_FETCH_DONE
+};
+
+
+/*
+  This structure is used to define bind information, and
+  internally by the client library.
+  Public members with their descriptions are listed below
+  (conventionally `On input' refers to the binds given to
+  mysql_stmt_bind_param, `On output' refers to the binds given
+  to mysql_stmt_bind_result):
+
+  buffer_type    - One of the MYSQL_* types, used to describe
+                   the host language type of buffer.
+                   On output: if column type is different from
+                   buffer_type, column value is automatically converted
+                   to buffer_type before it is stored in the buffer.
+  buffer         - On input: points to the buffer with input data.
+                   On output: points to the buffer capable to store
+                   output data.
+                   The type of memory pointed by buffer must correspond
+                   to buffer_type. See the correspondence table in
+                   the comment to mysql_stmt_bind_param.
+
+  The two above members are mandatory for any kind of bind.
+
+  buffer_length  - the length of the buffer. You don't have to set
+                   it for any fixed length buffer: float, double,
+                   int, etc. It must be set however for variable-length
+                   types, such as BLOBs or STRINGs.
+
+  length         - On input: in case when lengths of input values
+                   are different for each execute, you can set this to
+                   point at a variable containining value length. This
+                   way the value length can be different in each execute.
+                   If length is not NULL, buffer_length is not used.
+                   Note, length can even point at buffer_length if
+                   you keep bind structures around while fetching:
+                   this way you can change buffer_length before
+                   each execution, everything will work ok.
+                   On output: if length is set, mysql_stmt_fetch will
+                   write column length into it.
+
+  is_null        - On input: points to a boolean variable that should
+                   be set to TRUE for NULL values.
+                   This member is useful only if your data may be
+                   NULL in some but not all cases.
+                   If your data is never NULL, is_null should be set to 0.
+                   If your data is always NULL, set buffer_type
+                   to MYSQL_TYPE_NULL, and is_null will not be used.
+
+  is_unsigned    - On input: used to signify that values provided for one
+                   of numeric types are unsigned.
+                   On output describes signedness of the output buffer.
+                   If, taking into account is_unsigned flag, column data
+                   is out of range of the output buffer, data for this column
+                   is regarded truncated. Note that this has no correspondence
+                   to the sign of result set column, if you need to find it out
+                   use mysql_stmt_result_metadata.
+  error          - where to write a truncation error if it is present.
+                   possible error value is:
+                   0  no truncation
+                   1  value is out of range or buffer is too small
+
+  Please note that MYSQL_BIND also has internals members.
+*/
+
+typedef struct st_mysql_bind
+{
+  unsigned long	*length;          /* output length pointer */
+  my_bool       *is_null;	  /* Pointer to null indicator */
+  void		*buffer;	  /* buffer to get/put data */
+  /* set this if you want to track data truncations happened during fetch */
+  my_bool       *error;
+  enum enum_field_types buffer_type;	/* buffer type */
+  /* output buffer length, must be set when fetching str/binary */
+  unsigned long buffer_length;
+  unsigned char *row_ptr;         /* for the current data position */
+  unsigned long offset;           /* offset position for char/binary fetch */
+  unsigned long	length_value;     /* Used if length is 0 */
+  unsigned int	param_number;	  /* For null count and error messages */
+  unsigned int  pack_length;	  /* Internal length for packed data */
+  my_bool       error_value;      /* used if error is 0 */
+  my_bool       is_unsigned;      /* set if integer type is unsigned */
+  my_bool	long_data_used;	  /* If used with mysql_send_long_data */
+  my_bool	is_null_value;    /* Used if is_null is 0 */
+  void (*store_param_func)(NET *net, struct st_mysql_bind *param);
+  void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *,
+                       unsigned char **row);
+  void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
+		      unsigned char **row);
+} MYSQL_BIND;
+
+
+/* statement handler */
+typedef struct st_mysql_stmt
+{
+  MEM_ROOT       mem_root;             /* root allocations */
+  LIST           list;                 /* list to keep track of all stmts */
+  MYSQL          *mysql;               /* connection handle */
+  MYSQL_BIND     *params;              /* input parameters */
+  MYSQL_BIND     *bind;                /* output parameters */
+  MYSQL_FIELD    *fields;              /* result set metadata */
+  MYSQL_DATA     result;               /* cached result set */
+  MYSQL_ROWS     *data_cursor;         /* current row in cached result */
+  /* copy of mysql->affected_rows after statement execution */
+  my_ulonglong   affected_rows;
+  my_ulonglong   insert_id;            /* copy of mysql->insert_id */
+  /*
+    mysql_stmt_fetch() calls this function to fetch one row (it's different
+    for buffered, unbuffered and cursor fetch).
+  */
+  int            (*read_row_func)(struct st_mysql_stmt *stmt, 
+                                  unsigned char **row);
+  unsigned long	 stmt_id;	       /* Id for prepared statement */
+  unsigned long  flags;                /* i.e. type of cursor to open */
+  unsigned long  prefetch_rows;        /* number of rows per one COM_FETCH */
+  /*
+    Copied from mysql->server_status after execute/fetch to know
+    server-side cursor status for this statement.
+  */
+  unsigned int   server_status;
+  unsigned int	 last_errno;	       /* error code */
+  unsigned int   param_count;          /* input parameter count */
+  unsigned int   field_count;          /* number of columns in result set */
+  enum enum_mysql_stmt_state state;    /* statement state */
+  char		 last_error[MYSQL_ERRMSG_SIZE]; /* error message */
+  char		 sqlstate[SQLSTATE_LENGTH+1];
+  /* Types of input parameters should be sent to server */
+  my_bool        send_types_to_server;
+  my_bool        bind_param_done;      /* input buffers were supplied */
+  unsigned char  bind_result_done;     /* output buffers were supplied */
+  /* mysql_stmt_close() had to cancel this result */
+  my_bool       unbuffered_fetch_cancelled;  
+  /*
+    Is set to true if we need to calculate field->max_length for 
+    metadata fields when doing mysql_stmt_store_result.
+  */
+  my_bool       update_max_length;     
+} MYSQL_STMT;
+
+enum enum_stmt_attr_type
+{
+  /*
+    When doing mysql_stmt_store_result calculate max_length attribute
+    of statement metadata. This is to be consistent with the old API, 
+    where this was done automatically.
+    In the new API we do that only by request because it slows down
+    mysql_stmt_store_result sufficiently.
+  */
+  STMT_ATTR_UPDATE_MAX_LENGTH,
+  /*
+    unsigned long with combination of cursor flags (read only, for update,
+    etc)
+  */
+  STMT_ATTR_CURSOR_TYPE,
+  /*
+    Amount of rows to retrieve from server per one fetch if using cursors.
+    Accepts unsigned long attribute in the range 1 - ulong_max
+  */
+  STMT_ATTR_PREFETCH_ROWS
+};
+
+
+typedef struct st_mysql_methods
+{
+  my_bool (*read_query_result)(MYSQL *mysql);
+  my_bool (*advanced_command)(MYSQL *mysql,
+			      enum enum_server_command command,
+			      const char *header,
+			      unsigned long header_length,
+			      const char *arg,
+			      unsigned long arg_length,
+			      my_bool skip_check,
+                              MYSQL_STMT *stmt);
+  MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+			   unsigned int fields);
+  MYSQL_RES * (*use_result)(MYSQL *mysql);
+  void (*fetch_lengths)(unsigned long *to, 
+			MYSQL_ROW column, unsigned int field_count);
+  void (*flush_use_result)(MYSQL *mysql);
+#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
+  MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
+  my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
+  int (*stmt_execute)(MYSQL_STMT *stmt);
+  int (*read_binary_rows)(MYSQL_STMT *stmt);
+  int (*unbuffered_fetch)(MYSQL *mysql, char **row);
+  void (*free_embedded_thd)(MYSQL *mysql);
+  const char *(*read_statistics)(MYSQL *mysql);
+  my_bool (*next_result)(MYSQL *mysql);
+  int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
+  int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
+#endif
+} MYSQL_METHODS;
+
+
+MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
+int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
+                               unsigned long length);
+int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt);
+int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt);
+int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, 
+                                    unsigned int column,
+                                    unsigned long offset);
+int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt);
+unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt);
+my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
+                                    enum enum_stmt_attr_type attr_type,
+                                    const void *attr);
+my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
+                                    enum enum_stmt_attr_type attr_type,
+                                    void *attr);
+my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
+my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
+my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
+my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt);
+my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt);
+my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, 
+                                          unsigned int param_number,
+                                          const char *data, 
+                                          unsigned long length);
+MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt);
+MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt);
+unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
+const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
+const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt);
+MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, 
+                                             MYSQL_ROW_OFFSET offset);
+MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt);
+void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset);
+my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt);
+my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt);
+my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt);
+unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt);
+
+my_bool STDCALL mysql_commit(MYSQL * mysql);
+my_bool STDCALL mysql_rollback(MYSQL * mysql);
+my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
+my_bool STDCALL mysql_more_results(MYSQL *mysql);
+int STDCALL mysql_next_result(MYSQL *mysql);
+void STDCALL mysql_close(MYSQL *sock);
+
+
+/* status return codes */
+#define MYSQL_NO_DATA        100
+#define MYSQL_DATA_TRUNCATED 101
+
+#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
+
+#ifdef USE_OLD_FUNCTIONS
+MYSQL *		STDCALL mysql_connect(MYSQL *mysql, const char *host,
+				      const char *user, const char *passwd);
+int		STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
+int		STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+#define	 mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
+#endif
+#define HAVE_MYSQL_REAL_CONNECT
+
+/*
+  The following functions are mainly exported because of mysqlbinlog;
+  They are not for general usage
+*/
+
+#define simple_command(mysql, command, arg, length, skip_check) \
+  (*(mysql)->methods->advanced_command)(mysql, command, NullS,  \
+                                        0, arg, length, skip_check, NULL)
+#define stmt_command(mysql, command, arg, length, stmt) \
+  (*(mysql)->methods->advanced_command)(mysql, command, NullS,  \
+                                        0, arg, length, 1, stmt)
+
+#ifdef __NETWARE__
+
+// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform
+#if defined( __GNUC__ )
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif 
+
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _mysql_h */
diff --git a/dep/include/mysql/mysql_com.h b/dep/include/mysql/mysql_com.h
new file mode 100644
index 000000000..94b34c1c3
--- /dev/null
+++ b/dep/include/mysql/mysql_com.h
@@ -0,0 +1,467 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/*
+** Common definition between mysql server & client
+*/
+
+#ifndef _mysql_com_h
+#define _mysql_com_h
+
+#define NAME_LEN	64		/* Field/table name length */
+#define HOSTNAME_LENGTH 60
+#define USERNAME_LENGTH 16
+#define SERVER_VERSION_LENGTH 60
+#define SQLSTATE_LENGTH 5
+
+/*
+  USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
+  username and hostname parts of the user identifier with trailing zero in
+  MySQL standard format:
+  user_name_part@host_name_part\0
+*/
+#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2
+
+#define LOCAL_HOST	"localhost"
+#define LOCAL_HOST_NAMEDPIPE "."
+
+
+#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
+#define MYSQL_NAMEDPIPE "MySQL"
+#define MYSQL_SERVICENAME "MySQL"
+#endif /* __WIN__ */
+
+/*
+  You should add new commands to the end of this list, otherwise old
+  servers won't be able to handle them as 'unsupported'.
+*/
+
+enum enum_server_command
+{
+  COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
+  COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
+  COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
+  COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
+  COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
+  COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE,
+  COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH,
+  /* don't forget to update const char *command_name[] in sql_parse.cc */
+
+  /* Must be last */
+  COM_END
+};
+
+
+/*
+  Length of random string sent by server on handshake; this is also length of
+  obfuscated password, recieved from client
+*/
+#define SCRAMBLE_LENGTH 20
+#define SCRAMBLE_LENGTH_323 8
+/* length of password stored in the db: new passwords are preceeded with '*' */
+#define SCRAMBLED_PASSWORD_CHAR_LENGTH (SCRAMBLE_LENGTH*2+1)
+#define SCRAMBLED_PASSWORD_CHAR_LENGTH_323 (SCRAMBLE_LENGTH_323*2)
+
+
+#define NOT_NULL_FLAG	1		/* Field can't be NULL */
+#define PRI_KEY_FLAG	2		/* Field is part of a primary key */
+#define UNIQUE_KEY_FLAG 4		/* Field is part of a unique key */
+#define MULTIPLE_KEY_FLAG 8		/* Field is part of a key */
+#define BLOB_FLAG	16		/* Field is a blob */
+#define UNSIGNED_FLAG	32		/* Field is unsigned */
+#define ZEROFILL_FLAG	64		/* Field is zerofill */
+#define BINARY_FLAG	128		/* Field is binary   */
+
+/* The following are only sent to new clients */
+#define ENUM_FLAG	256		/* field is an enum */
+#define AUTO_INCREMENT_FLAG 512		/* field is a autoincrement field */
+#define TIMESTAMP_FLAG	1024		/* Field is a timestamp */
+#define SET_FLAG	2048		/* field is a set */
+#define NO_DEFAULT_VALUE_FLAG 4096	/* Field doesn't have default value */
+#define NUM_FLAG	32768		/* Field is num (for clients) */
+#define PART_KEY_FLAG	16384		/* Intern; Part of some key */
+#define GROUP_FLAG	32768		/* Intern: Group field */
+#define UNIQUE_FLAG	65536		/* Intern: Used by sql_yacc */
+#define BINCMP_FLAG	131072		/* Intern: Used by sql_yacc */
+
+#define REFRESH_GRANT		1	/* Refresh grant tables */
+#define REFRESH_LOG		2	/* Start on new log file */
+#define REFRESH_TABLES		4	/* close all tables */
+#define REFRESH_HOSTS		8	/* Flush host cache */
+#define REFRESH_STATUS		16	/* Flush status variables */
+#define REFRESH_THREADS		32	/* Flush thread cache */
+#define REFRESH_SLAVE           64      /* Reset master info and restart slave
+					   thread */
+#define REFRESH_MASTER          128     /* Remove all bin logs in the index
+					   and truncate the index */
+
+/* The following can't be set with mysql_refresh() */
+#define REFRESH_READ_LOCK	16384	/* Lock tables for read */
+#define REFRESH_FAST		32768	/* Intern flag */
+
+/* RESET (remove all queries) from query cache */
+#define REFRESH_QUERY_CACHE	65536
+#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
+#define REFRESH_DES_KEY_FILE	0x40000L
+#define REFRESH_USER_RESOURCES	0x80000L
+
+#define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
+#define CLIENT_FOUND_ROWS	2	/* Found instead of affected rows */
+#define CLIENT_LONG_FLAG	4	/* Get all column flags */
+#define CLIENT_CONNECT_WITH_DB	8	/* One can specify db on connect */
+#define CLIENT_NO_SCHEMA	16	/* Don't allow database.table.column */
+#define CLIENT_COMPRESS		32	/* Can use compression protocol */
+#define CLIENT_ODBC		64	/* Odbc client */
+#define CLIENT_LOCAL_FILES	128	/* Can use LOAD DATA LOCAL */
+#define CLIENT_IGNORE_SPACE	256	/* Ignore spaces before '(' */
+#define CLIENT_PROTOCOL_41	512	/* New 4.1 protocol */
+#define CLIENT_INTERACTIVE	1024	/* This is an interactive client */
+#define CLIENT_SSL              2048	/* Switch to SSL after handshake */
+#define CLIENT_IGNORE_SIGPIPE   4096    /* IGNORE sigpipes */
+#define CLIENT_TRANSACTIONS	8192	/* Client knows about transactions */
+#define CLIENT_RESERVED         16384   /* Old flag for 4.1 protocol  */
+#define CLIENT_SECURE_CONNECTION 32768  /* New 4.1 authentication */
+#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
+#define CLIENT_MULTI_RESULTS    (1UL << 17) /* Enable/disable multi-results */
+
+#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
+#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
+
+#define SERVER_STATUS_IN_TRANS     1	/* Transaction has started */
+#define SERVER_STATUS_AUTOCOMMIT   2	/* Server in auto_commit mode */
+#define SERVER_MORE_RESULTS_EXISTS 8    /* Multi query - next query exists */
+#define SERVER_QUERY_NO_GOOD_INDEX_USED 16
+#define SERVER_QUERY_NO_INDEX_USED      32
+/*
+  The server was able to fulfill the clients request and opened a
+  read-only non-scrollable cursor for a query. This flag comes
+  in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
+*/
+#define SERVER_STATUS_CURSOR_EXISTS 64
+/*
+  This flag is sent when a read-only cursor is exhausted, in reply to
+  COM_STMT_FETCH command.
+*/
+#define SERVER_STATUS_LAST_ROW_SENT 128
+#define SERVER_STATUS_DB_DROPPED        256 /* A database was dropped */
+#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512
+
+#define MYSQL_ERRMSG_SIZE	512
+#define NET_READ_TIMEOUT	30		/* Timeout on read */
+#define NET_WRITE_TIMEOUT	60		/* Timeout on write */
+#define NET_WAIT_TIMEOUT	8*60*60		/* Wait for new query */
+
+#define ONLY_KILL_QUERY         1
+
+struct st_vio;					/* Only C */
+typedef struct st_vio Vio;
+
+#define MAX_TINYINT_WIDTH       3       /* Max width for a TINY w.o. sign */
+#define MAX_SMALLINT_WIDTH      5       /* Max width for a SHORT w.o. sign */
+#define MAX_MEDIUMINT_WIDTH     8       /* Max width for a INT24 w.o. sign */
+#define MAX_INT_WIDTH           10      /* Max width for a LONG w.o. sign */
+#define MAX_BIGINT_WIDTH        20      /* Max width for a LONGLONG */
+#define MAX_CHAR_WIDTH		255	/* Max length for a CHAR colum */
+#define MAX_BLOB_WIDTH		8192	/* Default width for blob */
+
+typedef struct st_net {
+#if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY)
+  Vio* vio;
+  unsigned char *buff,*buff_end,*write_pos,*read_pos;
+  my_socket fd;					/* For Perl DBI/dbd */
+  unsigned long max_packet,max_packet_size;
+  unsigned int pkt_nr,compress_pkt_nr;
+  unsigned int write_timeout, read_timeout, retry_count;
+  int fcntl;
+  my_bool compress;
+  /*
+    The following variable is set if we are doing several queries in one
+    command ( as in LOAD TABLE ... FROM MASTER ),
+    and do not want to confuse the client with OK at the wrong time
+  */
+  unsigned long remain_in_buf,length, buf_length, where_b;
+  unsigned int *return_status;
+  unsigned char reading_or_writing;
+  char save_char;
+  my_bool no_send_ok;  /* For SPs and other things that do multiple stmts */
+  my_bool no_send_eof; /* For SPs' first version read-only cursors */
+  /*
+    Set if OK packet is already sent, and we do not need to send error
+    messages
+  */
+  my_bool no_send_error;
+  /*
+    Pointer to query object in query cache, do not equal NULL (0) for
+    queries in cache that have not stored its results yet
+  */
+#endif
+  char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1];
+  unsigned int last_errno;
+  unsigned char error;
+
+  /*
+    'query_cache_query' should be accessed only via query cache
+    functions and methods to maintain proper locking.
+  */
+  gptr query_cache_query;
+
+  my_bool report_error; /* We should report error (we have unreported error) */
+  my_bool return_errno;
+} NET;
+
+#define packet_error (~(unsigned long) 0)
+
+enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
+			MYSQL_TYPE_SHORT,  MYSQL_TYPE_LONG,
+			MYSQL_TYPE_FLOAT,  MYSQL_TYPE_DOUBLE,
+			MYSQL_TYPE_NULL,   MYSQL_TYPE_TIMESTAMP,
+			MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
+			MYSQL_TYPE_DATE,   MYSQL_TYPE_TIME,
+			MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
+			MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
+			MYSQL_TYPE_BIT,
+                        MYSQL_TYPE_NEWDECIMAL=246,
+			MYSQL_TYPE_ENUM=247,
+			MYSQL_TYPE_SET=248,
+			MYSQL_TYPE_TINY_BLOB=249,
+			MYSQL_TYPE_MEDIUM_BLOB=250,
+			MYSQL_TYPE_LONG_BLOB=251,
+			MYSQL_TYPE_BLOB=252,
+			MYSQL_TYPE_VAR_STRING=253,
+			MYSQL_TYPE_STRING=254,
+			MYSQL_TYPE_GEOMETRY=255
+
+};
+
+/* For backward compatibility */
+#define CLIENT_MULTI_QUERIES    CLIENT_MULTI_STATEMENTS    
+#define FIELD_TYPE_DECIMAL     MYSQL_TYPE_DECIMAL
+#define FIELD_TYPE_NEWDECIMAL  MYSQL_TYPE_NEWDECIMAL
+#define FIELD_TYPE_TINY        MYSQL_TYPE_TINY
+#define FIELD_TYPE_SHORT       MYSQL_TYPE_SHORT
+#define FIELD_TYPE_LONG        MYSQL_TYPE_LONG
+#define FIELD_TYPE_FLOAT       MYSQL_TYPE_FLOAT
+#define FIELD_TYPE_DOUBLE      MYSQL_TYPE_DOUBLE
+#define FIELD_TYPE_NULL        MYSQL_TYPE_NULL
+#define FIELD_TYPE_TIMESTAMP   MYSQL_TYPE_TIMESTAMP
+#define FIELD_TYPE_LONGLONG    MYSQL_TYPE_LONGLONG
+#define FIELD_TYPE_INT24       MYSQL_TYPE_INT24
+#define FIELD_TYPE_DATE        MYSQL_TYPE_DATE
+#define FIELD_TYPE_TIME        MYSQL_TYPE_TIME
+#define FIELD_TYPE_DATETIME    MYSQL_TYPE_DATETIME
+#define FIELD_TYPE_YEAR        MYSQL_TYPE_YEAR
+#define FIELD_TYPE_NEWDATE     MYSQL_TYPE_NEWDATE
+#define FIELD_TYPE_ENUM        MYSQL_TYPE_ENUM
+#define FIELD_TYPE_SET         MYSQL_TYPE_SET
+#define FIELD_TYPE_TINY_BLOB   MYSQL_TYPE_TINY_BLOB
+#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB
+#define FIELD_TYPE_LONG_BLOB   MYSQL_TYPE_LONG_BLOB
+#define FIELD_TYPE_BLOB        MYSQL_TYPE_BLOB
+#define FIELD_TYPE_VAR_STRING  MYSQL_TYPE_VAR_STRING
+#define FIELD_TYPE_STRING      MYSQL_TYPE_STRING
+#define FIELD_TYPE_CHAR        MYSQL_TYPE_TINY
+#define FIELD_TYPE_INTERVAL    MYSQL_TYPE_ENUM
+#define FIELD_TYPE_GEOMETRY    MYSQL_TYPE_GEOMETRY
+#define FIELD_TYPE_BIT         MYSQL_TYPE_BIT
+
+
+/* Shutdown/kill enums and constants */ 
+
+/* Bits for THD::killable. */
+#define MYSQL_SHUTDOWN_KILLABLE_CONNECT    (unsigned char)(1 << 0)
+#define MYSQL_SHUTDOWN_KILLABLE_TRANS      (unsigned char)(1 << 1)
+#define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1 << 2)
+#define MYSQL_SHUTDOWN_KILLABLE_UPDATE     (unsigned char)(1 << 3)
+
+enum mysql_enum_shutdown_level {
+  /*
+    We want levels to be in growing order of hardness (because we use number
+    comparisons). Note that DEFAULT does not respect the growing property, but
+    it's ok.
+  */
+  SHUTDOWN_DEFAULT = 0,
+  /* wait for existing connections to finish */
+  SHUTDOWN_WAIT_CONNECTIONS= MYSQL_SHUTDOWN_KILLABLE_CONNECT,
+  /* wait for existing trans to finish */
+  SHUTDOWN_WAIT_TRANSACTIONS= MYSQL_SHUTDOWN_KILLABLE_TRANS,
+  /* wait for existing updates to finish (=> no partial MyISAM update) */
+  SHUTDOWN_WAIT_UPDATES= MYSQL_SHUTDOWN_KILLABLE_UPDATE,
+  /* flush InnoDB buffers and other storage engines' buffers*/
+  SHUTDOWN_WAIT_ALL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1),
+  /* don't flush InnoDB buffers, flush other storage engines' buffers*/
+  SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1,
+  /* Now the 2 levels of the KILL command */
+#if MYSQL_VERSION_ID >= 50000
+  KILL_QUERY= 254,
+#endif
+  KILL_CONNECTION= 255
+};
+
+
+enum enum_cursor_type
+{
+  CURSOR_TYPE_NO_CURSOR= 0,
+  CURSOR_TYPE_READ_ONLY= 1,
+  CURSOR_TYPE_FOR_UPDATE= 2,
+  CURSOR_TYPE_SCROLLABLE= 4
+};
+
+
+/* options for mysql_set_option */
+enum enum_mysql_set_option
+{
+  MYSQL_OPTION_MULTI_STATEMENTS_ON,
+  MYSQL_OPTION_MULTI_STATEMENTS_OFF
+};
+
+#define net_new_transaction(net) ((net)->pkt_nr=0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+my_bool	my_net_init(NET *net, Vio* vio);
+void	my_net_local_init(NET *net);
+void	net_end(NET *net);
+void	net_clear(NET *net);
+my_bool net_realloc(NET *net, unsigned long length);
+my_bool	net_flush(NET *net);
+my_bool	my_net_write(NET *net,const char *packet,unsigned long len);
+my_bool	net_write_command(NET *net,unsigned char command,
+			  const char *header, unsigned long head_len,
+			  const char *packet, unsigned long len);
+int	net_real_write(NET *net,const char *packet,unsigned long len);
+unsigned long my_net_read(NET *net);
+
+#ifdef _global_h
+void my_net_set_write_timeout(NET *net, uint timeout);
+void my_net_set_read_timeout(NET *net, uint timeout);
+#endif
+
+/*
+  The following function is not meant for normal usage
+  Currently it's used internally by manager.c
+*/
+struct sockaddr;
+int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
+	       unsigned int timeout);
+
+struct rand_struct {
+  unsigned long seed1,seed2,max_value;
+  double max_value_dbl;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+  /* The following is for user defined functions */
+
+enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT,
+                  DECIMAL_RESULT};
+
+typedef struct st_udf_args
+{
+  unsigned int arg_count;		/* Number of arguments */
+  enum Item_result *arg_type;		/* Pointer to item_results */
+  char **args;				/* Pointer to argument */
+  unsigned long *lengths;		/* Length of string arguments */
+  char *maybe_null;			/* Set to 1 for all maybe_null args */
+  char **attributes;                    /* Pointer to attribute name */
+  unsigned long *attribute_lengths;     /* Length of attribute arguments */
+} UDF_ARGS;
+
+  /* This holds information about the result */
+
+typedef struct st_udf_init
+{
+  my_bool maybe_null;          /* 1 if function can return NULL */
+  unsigned int decimals;       /* for real functions */
+  unsigned long max_length;    /* For string functions */
+  char *ptr;                   /* free pointer for function data */
+  my_bool const_item;          /* 1 if function always returns the same value */
+} UDF_INIT;
+/* 
+  TODO: add a notion for determinism of the UDF. 
+  See Item_udf_func::update_used_tables ()
+*/
+
+  /* Constants when using compression */
+#define NET_HEADER_SIZE 4		/* standard header size */
+#define COMP_HEADER_SIZE 3		/* compression header extra size */
+
+  /* Prototypes to password functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+  These functions are used for authentication by client and server and
+  implemented in sql/password.c
+*/
+
+void randominit(struct rand_struct *, unsigned long seed1,
+                unsigned long seed2);
+double my_rnd(struct rand_struct *);
+void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st);
+
+void hash_password(unsigned long *to, const char *password, unsigned int password_len);
+void make_scrambled_password_323(char *to, const char *password);
+void scramble_323(char *to, const char *message, const char *password);
+my_bool check_scramble_323(const char *, const char *message,
+                           unsigned long *salt);
+void get_salt_from_password_323(unsigned long *res, const char *password);
+void make_password_from_salt_323(char *to, const unsigned long *salt);
+
+void make_scrambled_password(char *to, const char *password);
+void scramble(char *to, const char *message, const char *password);
+my_bool check_scramble(const char *reply, const char *message,
+                       const unsigned char *hash_stage2);
+void get_salt_from_password(unsigned char *res, const char *password);
+void make_password_from_salt(char *to, const unsigned char *hash_stage2);
+char *octet2hex(char *to, const char *str, unsigned int len);
+
+/* end of password.c */
+
+char *get_tty_password(char *opt_message);
+const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
+
+/* Some other useful functions */
+
+my_bool my_init(void);
+extern int modify_defaults_file(const char *file_location, const char *option,
+                                const char *option_value,
+                                const char *section_name, int remove_option);
+int load_defaults(const char *conf_file, const char **groups,
+		  int *argc, char ***argv);
+my_bool my_thread_init(void);
+void my_thread_end(void);
+
+#ifdef _global_h
+ulong STDCALL net_field_length(uchar **packet);
+my_ulonglong net_field_length_ll(uchar **packet);
+char *net_store_length(char *pkg, ulonglong length);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */
+#define MYSQL_STMT_HEADER       4
+#define MYSQL_LONG_DATA_HEADER  6
+
+#endif
diff --git a/dep/include/mysql/mysql_embed.h b/dep/include/mysql/mysql_embed.h
new file mode 100644
index 000000000..7416283d8
--- /dev/null
+++ b/dep/include/mysql/mysql_embed.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Defines that are unique to the embedded version of MySQL */
+
+#ifdef EMBEDDED_LIBRARY
+
+/* Things we don't need in the embedded version of MySQL */
+/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
+
+#undef HAVE_PSTACK				/* No stacktrace */
+#undef HAVE_DLOPEN				/* No udf functions */
+#undef HAVE_OPENSSL
+#undef HAVE_SMEM				/* No shared memory */
+#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
+
+#define DONT_USE_RAID
+
+#endif /* EMBEDDED_LIBRARY */
diff --git a/dep/include/mysql/mysql_time.h b/dep/include/mysql/mysql_time.h
new file mode 100644
index 000000000..0a3f17a81
--- /dev/null
+++ b/dep/include/mysql/mysql_time.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004 MySQL AB
+
+ 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; version 2 of the License.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef _mysql_time_h_
+#define _mysql_time_h_
+
+/*
+  Time declarations shared between the server and client API:
+  you should not add anything to this header unless it's used
+  (and hence should be visible) in mysql.h.
+  If you're looking for a place to add new time-related declaration,
+  it's most likely my_time.h. See also "C API Handling of Date
+  and Time Values" chapter in documentation.
+*/
+
+enum enum_mysql_timestamp_type
+{
+  MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+  MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+
+
+/*
+  Structure which is used to represent datetime values inside MySQL.
+
+  We assume that values in this structure are normalized, i.e. year <= 9999,
+  month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions
+  in server such as my_system_gmt_sec() or make_time() family of functions
+  rely on this (actually now usage of make_*() family relies on a bit weaker
+  restriction). Also functions that produce MYSQL_TIME as result ensure this.
+  There is one exception to this rule though if this structure holds time
+  value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold
+  bigger values.
+*/
+typedef struct st_mysql_time
+{
+  unsigned int  year, month, day, hour, minute, second;
+  unsigned long second_part;
+  my_bool       neg;
+  enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+
+#endif /* _mysql_time_h_ */
diff --git a/dep/include/mysql/mysql_version.h b/dep/include/mysql/mysql_version.h
new file mode 100644
index 000000000..3ec91e409
--- /dev/null
+++ b/dep/include/mysql/mysql_version.h
@@ -0,0 +1,30 @@
+/* Copyright Abandoned 1996, 1999, 2001 MySQL AB
+   This file is public domain and comes with NO WARRANTY of any kind */
+
+/* Version numbers for protocol & mysqld */
+
+#ifndef _mysql_version_h
+#define _mysql_version_h
+#ifdef _CUSTOMCONFIG_
+#include 
+#else
+#define PROTOCOL_VERSION		10
+#define MYSQL_SERVER_VERSION		"5.0.56"
+#define MYSQL_BASE_VERSION		"mysqld-5.0"
+#define MYSQL_SERVER_SUFFIX_DEF		"-nt"
+#define FRM_VER				6
+#define MYSQL_VERSION_ID		50056
+#define MYSQL_PORT			3306
+#define MYSQL_PORT_DEFAULT		0
+#define MYSQL_UNIX_ADDR			"/tmp/mysql.sock"
+#define MYSQL_CONFIG_NAME		"my"
+#define MYSQL_COMPILATION_COMMENT	"From Sources"
+
+/* mysqld compile time options */
+#endif /* _CUSTOMCONFIG_ */
+
+#ifndef LICENSE
+#define LICENSE				GPL
+#endif /* LICENSE */
+
+#endif /* _mysql_version_h */
diff --git a/dep/include/mysql/mysqld_error.h b/dep/include/mysql/mysqld_error.h
new file mode 100644
index 000000000..591ff78c5
--- /dev/null
+++ b/dep/include/mysql/mysqld_error.h
@@ -0,0 +1,480 @@
+/* Autogenerated file, please don't edit */
+
+#define ER_ERROR_FIRST 1000
+#define ER_HASHCHK 1000
+#define ER_NISAMCHK 1001
+#define ER_NO 1002
+#define ER_YES 1003
+#define ER_CANT_CREATE_FILE 1004
+#define ER_CANT_CREATE_TABLE 1005
+#define ER_CANT_CREATE_DB 1006
+#define ER_DB_CREATE_EXISTS 1007
+#define ER_DB_DROP_EXISTS 1008
+#define ER_DB_DROP_DELETE 1009
+#define ER_DB_DROP_RMDIR 1010
+#define ER_CANT_DELETE_FILE 1011
+#define ER_CANT_FIND_SYSTEM_REC 1012
+#define ER_CANT_GET_STAT 1013
+#define ER_CANT_GET_WD 1014
+#define ER_CANT_LOCK 1015
+#define ER_CANT_OPEN_FILE 1016
+#define ER_FILE_NOT_FOUND 1017
+#define ER_CANT_READ_DIR 1018
+#define ER_CANT_SET_WD 1019
+#define ER_CHECKREAD 1020
+#define ER_DISK_FULL 1021
+#define ER_DUP_KEY 1022
+#define ER_ERROR_ON_CLOSE 1023
+#define ER_ERROR_ON_READ 1024
+#define ER_ERROR_ON_RENAME 1025
+#define ER_ERROR_ON_WRITE 1026
+#define ER_FILE_USED 1027
+#define ER_FILSORT_ABORT 1028
+#define ER_FORM_NOT_FOUND 1029
+#define ER_GET_ERRNO 1030
+#define ER_ILLEGAL_HA 1031
+#define ER_KEY_NOT_FOUND 1032
+#define ER_NOT_FORM_FILE 1033
+#define ER_NOT_KEYFILE 1034
+#define ER_OLD_KEYFILE 1035
+#define ER_OPEN_AS_READONLY 1036
+#define ER_OUTOFMEMORY 1037
+#define ER_OUT_OF_SORTMEMORY 1038
+#define ER_UNEXPECTED_EOF 1039
+#define ER_CON_COUNT_ERROR 1040
+#define ER_OUT_OF_RESOURCES 1041
+#define ER_BAD_HOST_ERROR 1042
+#define ER_HANDSHAKE_ERROR 1043
+#define ER_DBACCESS_DENIED_ERROR 1044
+#define ER_ACCESS_DENIED_ERROR 1045
+#define ER_NO_DB_ERROR 1046
+#define ER_UNKNOWN_COM_ERROR 1047
+#define ER_BAD_NULL_ERROR 1048
+#define ER_BAD_DB_ERROR 1049
+#define ER_TABLE_EXISTS_ERROR 1050
+#define ER_BAD_TABLE_ERROR 1051
+#define ER_NON_UNIQ_ERROR 1052
+#define ER_SERVER_SHUTDOWN 1053
+#define ER_BAD_FIELD_ERROR 1054
+#define ER_WRONG_FIELD_WITH_GROUP 1055
+#define ER_WRONG_GROUP_FIELD 1056
+#define ER_WRONG_SUM_SELECT 1057
+#define ER_WRONG_VALUE_COUNT 1058
+#define ER_TOO_LONG_IDENT 1059
+#define ER_DUP_FIELDNAME 1060
+#define ER_DUP_KEYNAME 1061
+#define ER_DUP_ENTRY 1062
+#define ER_WRONG_FIELD_SPEC 1063
+#define ER_PARSE_ERROR 1064
+#define ER_EMPTY_QUERY 1065
+#define ER_NONUNIQ_TABLE 1066
+#define ER_INVALID_DEFAULT 1067
+#define ER_MULTIPLE_PRI_KEY 1068
+#define ER_TOO_MANY_KEYS 1069
+#define ER_TOO_MANY_KEY_PARTS 1070
+#define ER_TOO_LONG_KEY 1071
+#define ER_KEY_COLUMN_DOES_NOT_EXITS 1072
+#define ER_BLOB_USED_AS_KEY 1073
+#define ER_TOO_BIG_FIELDLENGTH 1074
+#define ER_WRONG_AUTO_KEY 1075
+#define ER_READY 1076
+#define ER_NORMAL_SHUTDOWN 1077
+#define ER_GOT_SIGNAL 1078
+#define ER_SHUTDOWN_COMPLETE 1079
+#define ER_FORCING_CLOSE 1080
+#define ER_IPSOCK_ERROR 1081
+#define ER_NO_SUCH_INDEX 1082
+#define ER_WRONG_FIELD_TERMINATORS 1083
+#define ER_BLOBS_AND_NO_TERMINATED 1084
+#define ER_TEXTFILE_NOT_READABLE 1085
+#define ER_FILE_EXISTS_ERROR 1086
+#define ER_LOAD_INFO 1087
+#define ER_ALTER_INFO 1088
+#define ER_WRONG_SUB_KEY 1089
+#define ER_CANT_REMOVE_ALL_FIELDS 1090
+#define ER_CANT_DROP_FIELD_OR_KEY 1091
+#define ER_INSERT_INFO 1092
+#define ER_UPDATE_TABLE_USED 1093
+#define ER_NO_SUCH_THREAD 1094
+#define ER_KILL_DENIED_ERROR 1095
+#define ER_NO_TABLES_USED 1096
+#define ER_TOO_BIG_SET 1097
+#define ER_NO_UNIQUE_LOGFILE 1098
+#define ER_TABLE_NOT_LOCKED_FOR_WRITE 1099
+#define ER_TABLE_NOT_LOCKED 1100
+#define ER_BLOB_CANT_HAVE_DEFAULT 1101
+#define ER_WRONG_DB_NAME 1102
+#define ER_WRONG_TABLE_NAME 1103
+#define ER_TOO_BIG_SELECT 1104
+#define ER_UNKNOWN_ERROR 1105
+#define ER_UNKNOWN_PROCEDURE 1106
+#define ER_WRONG_PARAMCOUNT_TO_PROCEDURE 1107
+#define ER_WRONG_PARAMETERS_TO_PROCEDURE 1108
+#define ER_UNKNOWN_TABLE 1109
+#define ER_FIELD_SPECIFIED_TWICE 1110
+#define ER_INVALID_GROUP_FUNC_USE 1111
+#define ER_UNSUPPORTED_EXTENSION 1112
+#define ER_TABLE_MUST_HAVE_COLUMNS 1113
+#define ER_RECORD_FILE_FULL 1114
+#define ER_UNKNOWN_CHARACTER_SET 1115
+#define ER_TOO_MANY_TABLES 1116
+#define ER_TOO_MANY_FIELDS 1117
+#define ER_TOO_BIG_ROWSIZE 1118
+#define ER_STACK_OVERRUN 1119
+#define ER_WRONG_OUTER_JOIN 1120
+#define ER_NULL_COLUMN_IN_INDEX 1121
+#define ER_CANT_FIND_UDF 1122
+#define ER_CANT_INITIALIZE_UDF 1123
+#define ER_UDF_NO_PATHS 1124
+#define ER_UDF_EXISTS 1125
+#define ER_CANT_OPEN_LIBRARY 1126
+#define ER_CANT_FIND_DL_ENTRY 1127
+#define ER_FUNCTION_NOT_DEFINED 1128
+#define ER_HOST_IS_BLOCKED 1129
+#define ER_HOST_NOT_PRIVILEGED 1130
+#define ER_PASSWORD_ANONYMOUS_USER 1131
+#define ER_PASSWORD_NOT_ALLOWED 1132
+#define ER_PASSWORD_NO_MATCH 1133
+#define ER_UPDATE_INFO 1134
+#define ER_CANT_CREATE_THREAD 1135
+#define ER_WRONG_VALUE_COUNT_ON_ROW 1136
+#define ER_CANT_REOPEN_TABLE 1137
+#define ER_INVALID_USE_OF_NULL 1138
+#define ER_REGEXP_ERROR 1139
+#define ER_MIX_OF_GROUP_FUNC_AND_FIELDS 1140
+#define ER_NONEXISTING_GRANT 1141
+#define ER_TABLEACCESS_DENIED_ERROR 1142
+#define ER_COLUMNACCESS_DENIED_ERROR 1143
+#define ER_ILLEGAL_GRANT_FOR_TABLE 1144
+#define ER_GRANT_WRONG_HOST_OR_USER 1145
+#define ER_NO_SUCH_TABLE 1146
+#define ER_NONEXISTING_TABLE_GRANT 1147
+#define ER_NOT_ALLOWED_COMMAND 1148
+#define ER_SYNTAX_ERROR 1149
+#define ER_DELAYED_CANT_CHANGE_LOCK 1150
+#define ER_TOO_MANY_DELAYED_THREADS 1151
+#define ER_ABORTING_CONNECTION 1152
+#define ER_NET_PACKET_TOO_LARGE 1153
+#define ER_NET_READ_ERROR_FROM_PIPE 1154
+#define ER_NET_FCNTL_ERROR 1155
+#define ER_NET_PACKETS_OUT_OF_ORDER 1156
+#define ER_NET_UNCOMPRESS_ERROR 1157
+#define ER_NET_READ_ERROR 1158
+#define ER_NET_READ_INTERRUPTED 1159
+#define ER_NET_ERROR_ON_WRITE 1160
+#define ER_NET_WRITE_INTERRUPTED 1161
+#define ER_TOO_LONG_STRING 1162
+#define ER_TABLE_CANT_HANDLE_BLOB 1163
+#define ER_TABLE_CANT_HANDLE_AUTO_INCREMENT 1164
+#define ER_DELAYED_INSERT_TABLE_LOCKED 1165
+#define ER_WRONG_COLUMN_NAME 1166
+#define ER_WRONG_KEY_COLUMN 1167
+#define ER_WRONG_MRG_TABLE 1168
+#define ER_DUP_UNIQUE 1169
+#define ER_BLOB_KEY_WITHOUT_LENGTH 1170
+#define ER_PRIMARY_CANT_HAVE_NULL 1171
+#define ER_TOO_MANY_ROWS 1172
+#define ER_REQUIRES_PRIMARY_KEY 1173
+#define ER_NO_RAID_COMPILED 1174
+#define ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE 1175
+#define ER_KEY_DOES_NOT_EXITS 1176
+#define ER_CHECK_NO_SUCH_TABLE 1177
+#define ER_CHECK_NOT_IMPLEMENTED 1178
+#define ER_CANT_DO_THIS_DURING_AN_TRANSACTION 1179
+#define ER_ERROR_DURING_COMMIT 1180
+#define ER_ERROR_DURING_ROLLBACK 1181
+#define ER_ERROR_DURING_FLUSH_LOGS 1182
+#define ER_ERROR_DURING_CHECKPOINT 1183
+#define ER_NEW_ABORTING_CONNECTION 1184
+#define ER_DUMP_NOT_IMPLEMENTED 1185
+#define ER_FLUSH_MASTER_BINLOG_CLOSED 1186
+#define ER_INDEX_REBUILD 1187
+#define ER_MASTER 1188
+#define ER_MASTER_NET_READ 1189
+#define ER_MASTER_NET_WRITE 1190
+#define ER_FT_MATCHING_KEY_NOT_FOUND 1191
+#define ER_LOCK_OR_ACTIVE_TRANSACTION 1192
+#define ER_UNKNOWN_SYSTEM_VARIABLE 1193
+#define ER_CRASHED_ON_USAGE 1194
+#define ER_CRASHED_ON_REPAIR 1195
+#define ER_WARNING_NOT_COMPLETE_ROLLBACK 1196
+#define ER_TRANS_CACHE_FULL 1197
+#define ER_SLAVE_MUST_STOP 1198
+#define ER_SLAVE_NOT_RUNNING 1199
+#define ER_BAD_SLAVE 1200
+#define ER_MASTER_INFO 1201
+#define ER_SLAVE_THREAD 1202
+#define ER_TOO_MANY_USER_CONNECTIONS 1203
+#define ER_SET_CONSTANTS_ONLY 1204
+#define ER_LOCK_WAIT_TIMEOUT 1205
+#define ER_LOCK_TABLE_FULL 1206
+#define ER_READ_ONLY_TRANSACTION 1207
+#define ER_DROP_DB_WITH_READ_LOCK 1208
+#define ER_CREATE_DB_WITH_READ_LOCK 1209
+#define ER_WRONG_ARGUMENTS 1210
+#define ER_NO_PERMISSION_TO_CREATE_USER 1211
+#define ER_UNION_TABLES_IN_DIFFERENT_DIR 1212
+#define ER_LOCK_DEADLOCK 1213
+#define ER_TABLE_CANT_HANDLE_FT 1214
+#define ER_CANNOT_ADD_FOREIGN 1215
+#define ER_NO_REFERENCED_ROW 1216
+#define ER_ROW_IS_REFERENCED 1217
+#define ER_CONNECT_TO_MASTER 1218
+#define ER_QUERY_ON_MASTER 1219
+#define ER_ERROR_WHEN_EXECUTING_COMMAND 1220
+#define ER_WRONG_USAGE 1221
+#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1222
+#define ER_CANT_UPDATE_WITH_READLOCK 1223
+#define ER_MIXING_NOT_ALLOWED 1224
+#define ER_DUP_ARGUMENT 1225
+#define ER_USER_LIMIT_REACHED 1226
+#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
+#define ER_LOCAL_VARIABLE 1228
+#define ER_GLOBAL_VARIABLE 1229
+#define ER_NO_DEFAULT 1230
+#define ER_WRONG_VALUE_FOR_VAR 1231
+#define ER_WRONG_TYPE_FOR_VAR 1232
+#define ER_VAR_CANT_BE_READ 1233
+#define ER_CANT_USE_OPTION_HERE 1234
+#define ER_NOT_SUPPORTED_YET 1235
+#define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236
+#define ER_SLAVE_IGNORED_TABLE 1237
+#define ER_INCORRECT_GLOBAL_LOCAL_VAR 1238
+#define ER_WRONG_FK_DEF 1239
+#define ER_KEY_REF_DO_NOT_MATCH_TABLE_REF 1240
+#define ER_OPERAND_COLUMNS 1241
+#define ER_SUBQUERY_NO_1_ROW 1242
+#define ER_UNKNOWN_STMT_HANDLER 1243
+#define ER_CORRUPT_HELP_DB 1244
+#define ER_CYCLIC_REFERENCE 1245
+#define ER_AUTO_CONVERT 1246
+#define ER_ILLEGAL_REFERENCE 1247
+#define ER_DERIVED_MUST_HAVE_ALIAS 1248
+#define ER_SELECT_REDUCED 1249
+#define ER_TABLENAME_NOT_ALLOWED_HERE 1250
+#define ER_NOT_SUPPORTED_AUTH_MODE 1251
+#define ER_SPATIAL_CANT_HAVE_NULL 1252
+#define ER_COLLATION_CHARSET_MISMATCH 1253
+#define ER_SLAVE_WAS_RUNNING 1254
+#define ER_SLAVE_WAS_NOT_RUNNING 1255
+#define ER_TOO_BIG_FOR_UNCOMPRESS 1256
+#define ER_ZLIB_Z_MEM_ERROR 1257
+#define ER_ZLIB_Z_BUF_ERROR 1258
+#define ER_ZLIB_Z_DATA_ERROR 1259
+#define ER_CUT_VALUE_GROUP_CONCAT 1260
+#define ER_WARN_TOO_FEW_RECORDS 1261
+#define ER_WARN_TOO_MANY_RECORDS 1262
+#define ER_WARN_NULL_TO_NOTNULL 1263
+#define ER_WARN_DATA_OUT_OF_RANGE 1264
+#define WARN_DATA_TRUNCATED 1265
+#define ER_WARN_USING_OTHER_HANDLER 1266
+#define ER_CANT_AGGREGATE_2COLLATIONS 1267
+#define ER_DROP_USER 1268
+#define ER_REVOKE_GRANTS 1269
+#define ER_CANT_AGGREGATE_3COLLATIONS 1270
+#define ER_CANT_AGGREGATE_NCOLLATIONS 1271
+#define ER_VARIABLE_IS_NOT_STRUCT 1272
+#define ER_UNKNOWN_COLLATION 1273
+#define ER_SLAVE_IGNORED_SSL_PARAMS 1274
+#define ER_SERVER_IS_IN_SECURE_AUTH_MODE 1275
+#define ER_WARN_FIELD_RESOLVED 1276
+#define ER_BAD_SLAVE_UNTIL_COND 1277
+#define ER_MISSING_SKIP_SLAVE 1278
+#define ER_UNTIL_COND_IGNORED 1279
+#define ER_WRONG_NAME_FOR_INDEX 1280
+#define ER_WRONG_NAME_FOR_CATALOG 1281
+#define ER_WARN_QC_RESIZE 1282
+#define ER_BAD_FT_COLUMN 1283
+#define ER_UNKNOWN_KEY_CACHE 1284
+#define ER_WARN_HOSTNAME_WONT_WORK 1285
+#define ER_UNKNOWN_STORAGE_ENGINE 1286
+#define ER_WARN_DEPRECATED_SYNTAX 1287
+#define ER_NON_UPDATABLE_TABLE 1288
+#define ER_FEATURE_DISABLED 1289
+#define ER_OPTION_PREVENTS_STATEMENT 1290
+#define ER_DUPLICATED_VALUE_IN_TYPE 1291
+#define ER_TRUNCATED_WRONG_VALUE 1292
+#define ER_TOO_MUCH_AUTO_TIMESTAMP_COLS 1293
+#define ER_INVALID_ON_UPDATE 1294
+#define ER_UNSUPPORTED_PS 1295
+#define ER_GET_ERRMSG 1296
+#define ER_GET_TEMPORARY_ERRMSG 1297
+#define ER_UNKNOWN_TIME_ZONE 1298
+#define ER_WARN_INVALID_TIMESTAMP 1299
+#define ER_INVALID_CHARACTER_STRING 1300
+#define ER_WARN_ALLOWED_PACKET_OVERFLOWED 1301
+#define ER_CONFLICTING_DECLARATIONS 1302
+#define ER_SP_NO_RECURSIVE_CREATE 1303
+#define ER_SP_ALREADY_EXISTS 1304
+#define ER_SP_DOES_NOT_EXIST 1305
+#define ER_SP_DROP_FAILED 1306
+#define ER_SP_STORE_FAILED 1307
+#define ER_SP_LILABEL_MISMATCH 1308
+#define ER_SP_LABEL_REDEFINE 1309
+#define ER_SP_LABEL_MISMATCH 1310
+#define ER_SP_UNINIT_VAR 1311
+#define ER_SP_BADSELECT 1312
+#define ER_SP_BADRETURN 1313
+#define ER_SP_BADSTATEMENT 1314
+#define ER_UPDATE_LOG_DEPRECATED_IGNORED 1315
+#define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1316
+#define ER_QUERY_INTERRUPTED 1317
+#define ER_SP_WRONG_NO_OF_ARGS 1318
+#define ER_SP_COND_MISMATCH 1319
+#define ER_SP_NORETURN 1320
+#define ER_SP_NORETURNEND 1321
+#define ER_SP_BAD_CURSOR_QUERY 1322
+#define ER_SP_BAD_CURSOR_SELECT 1323
+#define ER_SP_CURSOR_MISMATCH 1324
+#define ER_SP_CURSOR_ALREADY_OPEN 1325
+#define ER_SP_CURSOR_NOT_OPEN 1326
+#define ER_SP_UNDECLARED_VAR 1327
+#define ER_SP_WRONG_NO_OF_FETCH_ARGS 1328
+#define ER_SP_FETCH_NO_DATA 1329
+#define ER_SP_DUP_PARAM 1330
+#define ER_SP_DUP_VAR 1331
+#define ER_SP_DUP_COND 1332
+#define ER_SP_DUP_CURS 1333
+#define ER_SP_CANT_ALTER 1334
+#define ER_SP_SUBSELECT_NYI 1335
+#define ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG 1336
+#define ER_SP_VARCOND_AFTER_CURSHNDLR 1337
+#define ER_SP_CURSOR_AFTER_HANDLER 1338
+#define ER_SP_CASE_NOT_FOUND 1339
+#define ER_FPARSER_TOO_BIG_FILE 1340
+#define ER_FPARSER_BAD_HEADER 1341
+#define ER_FPARSER_EOF_IN_COMMENT 1342
+#define ER_FPARSER_ERROR_IN_PARAMETER 1343
+#define ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER 1344
+#define ER_VIEW_NO_EXPLAIN 1345
+#define ER_FRM_UNKNOWN_TYPE 1346
+#define ER_WRONG_OBJECT 1347
+#define ER_NONUPDATEABLE_COLUMN 1348
+#define ER_VIEW_SELECT_DERIVED 1349
+#define ER_VIEW_SELECT_CLAUSE 1350
+#define ER_VIEW_SELECT_VARIABLE 1351
+#define ER_VIEW_SELECT_TMPTABLE 1352
+#define ER_VIEW_WRONG_LIST 1353
+#define ER_WARN_VIEW_MERGE 1354
+#define ER_WARN_VIEW_WITHOUT_KEY 1355
+#define ER_VIEW_INVALID 1356
+#define ER_SP_NO_DROP_SP 1357
+#define ER_SP_GOTO_IN_HNDLR 1358
+#define ER_TRG_ALREADY_EXISTS 1359
+#define ER_TRG_DOES_NOT_EXIST 1360
+#define ER_TRG_ON_VIEW_OR_TEMP_TABLE 1361
+#define ER_TRG_CANT_CHANGE_ROW 1362
+#define ER_TRG_NO_SUCH_ROW_IN_TRG 1363
+#define ER_NO_DEFAULT_FOR_FIELD 1364
+#define ER_DIVISION_BY_ZERO 1365
+#define ER_TRUNCATED_WRONG_VALUE_FOR_FIELD 1366
+#define ER_ILLEGAL_VALUE_FOR_TYPE 1367
+#define ER_VIEW_NONUPD_CHECK 1368
+#define ER_VIEW_CHECK_FAILED 1369
+#define ER_PROCACCESS_DENIED_ERROR 1370
+#define ER_RELAY_LOG_FAIL 1371
+#define ER_PASSWD_LENGTH 1372
+#define ER_UNKNOWN_TARGET_BINLOG 1373
+#define ER_IO_ERR_LOG_INDEX_READ 1374
+#define ER_BINLOG_PURGE_PROHIBITED 1375
+#define ER_FSEEK_FAIL 1376
+#define ER_BINLOG_PURGE_FATAL_ERR 1377
+#define ER_LOG_IN_USE 1378
+#define ER_LOG_PURGE_UNKNOWN_ERR 1379
+#define ER_RELAY_LOG_INIT 1380
+#define ER_NO_BINARY_LOGGING 1381
+#define ER_RESERVED_SYNTAX 1382
+#define ER_WSAS_FAILED 1383
+#define ER_DIFF_GROUPS_PROC 1384
+#define ER_NO_GROUP_FOR_PROC 1385
+#define ER_ORDER_WITH_PROC 1386
+#define ER_LOGGING_PROHIBIT_CHANGING_OF 1387
+#define ER_NO_FILE_MAPPING 1388
+#define ER_WRONG_MAGIC 1389
+#define ER_PS_MANY_PARAM 1390
+#define ER_KEY_PART_0 1391
+#define ER_VIEW_CHECKSUM 1392
+#define ER_VIEW_MULTIUPDATE 1393
+#define ER_VIEW_NO_INSERT_FIELD_LIST 1394
+#define ER_VIEW_DELETE_MERGE_VIEW 1395
+#define ER_CANNOT_USER 1396
+#define ER_XAER_NOTA 1397
+#define ER_XAER_INVAL 1398
+#define ER_XAER_RMFAIL 1399
+#define ER_XAER_OUTSIDE 1400
+#define ER_XAER_RMERR 1401
+#define ER_XA_RBROLLBACK 1402
+#define ER_NONEXISTING_PROC_GRANT 1403
+#define ER_PROC_AUTO_GRANT_FAIL 1404
+#define ER_PROC_AUTO_REVOKE_FAIL 1405
+#define ER_DATA_TOO_LONG 1406
+#define ER_SP_BAD_SQLSTATE 1407
+#define ER_STARTUP 1408
+#define ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR 1409
+#define ER_CANT_CREATE_USER_WITH_GRANT 1410
+#define ER_WRONG_VALUE_FOR_TYPE 1411
+#define ER_TABLE_DEF_CHANGED 1412
+#define ER_SP_DUP_HANDLER 1413
+#define ER_SP_NOT_VAR_ARG 1414
+#define ER_SP_NO_RETSET 1415
+#define ER_CANT_CREATE_GEOMETRY_OBJECT 1416
+#define ER_FAILED_ROUTINE_BREAK_BINLOG 1417
+#define ER_BINLOG_UNSAFE_ROUTINE 1418
+#define ER_BINLOG_CREATE_ROUTINE_NEED_SUPER 1419
+#define ER_EXEC_STMT_WITH_OPEN_CURSOR 1420
+#define ER_STMT_HAS_NO_OPEN_CURSOR 1421
+#define ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG 1422
+#define ER_NO_DEFAULT_FOR_VIEW_FIELD 1423
+#define ER_SP_NO_RECURSION 1424
+#define ER_TOO_BIG_SCALE 1425
+#define ER_TOO_BIG_PRECISION 1426
+#define ER_M_BIGGER_THAN_D 1427
+#define ER_WRONG_LOCK_OF_SYSTEM_TABLE 1428
+#define ER_CONNECT_TO_FOREIGN_DATA_SOURCE 1429
+#define ER_QUERY_ON_FOREIGN_DATA_SOURCE 1430
+#define ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST 1431
+#define ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE 1432
+#define ER_FOREIGN_DATA_STRING_INVALID 1433
+#define ER_CANT_CREATE_FEDERATED_TABLE 1434
+#define ER_TRG_IN_WRONG_SCHEMA 1435
+#define ER_STACK_OVERRUN_NEED_MORE 1436
+#define ER_TOO_LONG_BODY 1437
+#define ER_WARN_CANT_DROP_DEFAULT_KEYCACHE 1438
+#define ER_TOO_BIG_DISPLAYWIDTH 1439
+#define ER_XAER_DUPID 1440
+#define ER_DATETIME_FUNCTION_OVERFLOW 1441
+#define ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG 1442
+#define ER_VIEW_PREVENT_UPDATE 1443
+#define ER_PS_NO_RECURSION 1444
+#define ER_SP_CANT_SET_AUTOCOMMIT 1445
+#define ER_MALFORMED_DEFINER 1446
+#define ER_VIEW_FRM_NO_USER 1447
+#define ER_VIEW_OTHER_USER 1448
+#define ER_NO_SUCH_USER 1449
+#define ER_FORBID_SCHEMA_CHANGE 1450
+#define ER_ROW_IS_REFERENCED_2 1451
+#define ER_NO_REFERENCED_ROW_2 1452
+#define ER_SP_BAD_VAR_SHADOW 1453
+#define ER_TRG_NO_DEFINER 1454
+#define ER_OLD_FILE_FORMAT 1455
+#define ER_SP_RECURSION_LIMIT 1456
+#define ER_SP_PROC_TABLE_CORRUPT 1457
+#define ER_SP_WRONG_NAME 1458
+#define ER_TABLE_NEEDS_UPGRADE 1459
+#define ER_SP_NO_AGGREGATE 1460
+#define ER_MAX_PREPARED_STMT_COUNT_REACHED 1461
+#define ER_VIEW_RECURSIVE 1462
+#define ER_NON_GROUPING_FIELD_USED 1463
+#define ER_TABLE_CANT_HANDLE_SPKEYS 1464
+#define ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA 1465
+#define ER_REMOVED_SPACES 1466
+#define ER_AUTOINC_READ_FAILED 1467
+#define ER_USERNAME 1468
+#define ER_HOSTNAME 1469
+#define ER_WRONG_STRING_LENGTH 1470
+#define ER_NON_INSERTABLE_TABLE 1471
+#define ER_ADMIN_WRONG_MRG_TABLE 1472
+#define ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT 1473
+#define ER_NAME_BECOMES_EMPTY 1474
+#define ER_AMBIGUOUS_FIELD_TERM 1475
+#define ER_ERROR_LAST 1475
diff --git a/dep/include/mysql/raid.h b/dep/include/mysql/raid.h
new file mode 100644
index 000000000..9d098305d
--- /dev/null
+++ b/dep/include/mysql/raid.h
@@ -0,0 +1,158 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* Parser needs these defines  always, even if USE_RAID is not defined */
+#define RAID_TYPE_0 1       /* Striping */
+#define RAID_TYPE_x 2       /* Some new modes */
+#define RAID_TYPE_y 3
+
+#define RAID_DEFAULT_CHUNKS 4
+#define RAID_DEFAULT_CHUNKSIZE 256*1024 /* 256kB */
+
+C_MODE_START
+#define my_raid_type(raid_type)  raid_type_string[(int)(raid_type)]
+extern const char *raid_type_string[];
+C_MODE_END
+
+#ifdef DONT_USE_RAID
+#undef USE_RAID
+#endif
+#if defined(USE_RAID)
+
+#include "my_dir.h"
+
+/* Trap all occurences of my_...() in source and use our wrapper around this function */
+
+#ifdef MAP_TO_USE_RAID
+#define my_read(A,B,C,D)     my_raid_read(A,B,C,D)
+#define my_write(A,B,C,D)    my_raid_write(A,B,C,D)
+#define my_pwrite(A,B,C,D,E) my_raid_pwrite(A,B,C,D,E)
+#define my_pread(A,B,C,D,E)  my_raid_pread(A,B,C,D,E)
+#define my_chsize(A,B,C,D)   my_raid_chsize(A,B,C,D)
+#define my_close(A,B)        my_raid_close(A,B)
+#define my_tell(A,B)         my_raid_tell(A,B)
+#define my_seek(A,B,C,D)     my_raid_seek(A,B,C,D)
+#define my_lock(A,B,C,D,E)     my_raid_lock(A,B,C,D,E)
+#define my_fstat(A,B,C)     my_raid_fstat(A,B,C)
+#endif /* MAP_TO_USE_RAID */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  void init_raid(void);
+  void end_raid(void);
+
+  bool is_raid(File fd);
+  File my_raid_create(const char *FileName, int CreateFlags, int access_flags,
+		      uint raid_type, uint raid_chunks, ulong raid_chunksize,
+		      myf MyFlags);
+  File my_raid_open(const char *FileName, int Flags,
+		    uint raid_type, uint raid_chunks, ulong raid_chunksize,
+		    myf MyFlags);
+  int my_raid_rename(const char *from, const char *to, uint raid_chunks,
+		     myf MyFlags);
+  int my_raid_delete(const char *from, uint raid_chunks, myf MyFlags);
+  int my_raid_redel(const char *old_name, const char *new_name,
+		    uint raid_chunks, myf MyFlags);
+
+  my_off_t my_raid_seek(File fd, my_off_t pos, int whence, myf MyFlags);
+  my_off_t my_raid_tell(File fd, myf MyFlags);
+
+  uint my_raid_write(File,const byte *Buffer, uint Count, myf MyFlags);
+  uint my_raid_read(File Filedes, byte *Buffer, uint Count, myf MyFlags);
+
+  uint my_raid_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
+		     myf MyFlags);
+  uint my_raid_pwrite(int Filedes, const byte *Buffer, uint Count,
+		      my_off_t offset, myf MyFlags);
+
+  int my_raid_lock(File,int locktype, my_off_t start, my_off_t length,
+		   myf MyFlags);
+  int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags);
+  int my_raid_close(File, myf MyFlags);
+  int my_raid_fstat(int Filedes, struct stat *buf,  myf MyFlags);
+
+#ifdef __cplusplus
+}
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface			/* gcc class implementation */
+#endif
+
+class RaidName {
+  public:
+    RaidName(const char *FileName);
+    ~RaidName();
+    bool IsRaid();
+    int Rename(const char * from, const char * to, myf MyFlags);
+  private:
+    uint _raid_type;       /* RAID_TYPE_0 or RAID_TYPE_1 or RAID_TYPE_5 */
+    uint _raid_chunks;     /* 1..n */
+    ulong _raid_chunksize; /* 1..n in bytes */
+};
+
+class RaidFd {
+  public:
+    RaidFd(uint raid_type, uint raid_chunks , ulong raid_chunksize);
+    ~RaidFd();
+    File Create(const char *FileName, int CreateFlags, int access_flags,
+		myf MyFlags);
+    File Open(const char *FileName, int Flags, myf MyFlags);
+    my_off_t Seek(my_off_t pos,int whence,myf MyFlags);
+    my_off_t Tell(myf MyFlags);
+    int Write(const byte *Buffer, uint Count, myf MyFlags);
+    int Read(const byte *Buffer, uint Count, myf MyFlags);
+    int Lock(int locktype, my_off_t start, my_off_t length, myf MyFlags);
+    int Chsize(File fd, my_off_t newlength, int filler, myf MyFlags);
+    int Fstat(int fd, MY_STAT *stat_area, myf MyFlags );
+    int Close(myf MyFlags);
+    static bool IsRaid(File fd);
+    static DYNAMIC_ARRAY _raid_map;		/* Map of RaidFD* */
+  private:
+
+    uint _raid_type;       /* RAID_TYPE_0 or RAID_TYPE_1 or RAID_TYPE_5 */
+    uint _raid_chunks;     /* 1..n */
+    ulong _raid_chunksize; /* 1..n in bytes */
+
+    ulong _total_block;    /* We are operating with block no x (can be 0..many). */
+    uint _this_block;      /* can be 0.._raid_chunks */
+    uint _remaining_bytes; /* Maximum bytes that can be written in this block */
+
+    my_off_t _position;
+    my_off_t _size;        /* Cached file size for faster seek(SEEK_END) */
+    File _fd;
+    File *_fd_vector;		/* Array of File */
+    off_t *_seek_vector;	/* Array of cached seek positions */
+
+    inline void Calculate()
+    {
+      DBUG_ENTER("RaidFd::_Calculate");
+      DBUG_PRINT("info",("_position: %lu  _raid_chunksize: %lu  _size: %lu",
+			 (ulong) _position, _raid_chunksize, (ulong) _size));
+
+      _total_block = (ulong) (_position / _raid_chunksize);
+      _this_block = _total_block % _raid_chunks;    /* can be 0.._raid_chunks */
+      _remaining_bytes = (uint) (_raid_chunksize -
+				 (_position - _total_block * _raid_chunksize));
+      DBUG_PRINT("info",
+		 ("_total_block: %lu  this_block: %d  _remaining_bytes: %d",
+		  _total_block, _this_block, _remaining_bytes));
+      DBUG_VOID_RETURN;
+    }
+};
+
+#endif /* __cplusplus */
+#endif /* USE_RAID */
diff --git a/dep/include/mysql/typelib.h b/dep/include/mysql/typelib.h
new file mode 100644
index 000000000..75d170e59
--- /dev/null
+++ b/dep/include/mysql/typelib.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2000 MySQL AB
+
+   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; version 2 of the License.
+
+   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, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+
+#ifndef _typelib_h
+#define _typelib_h
+
+#include "my_alloc.h"
+
+typedef struct st_typelib {	/* Different types saved here */
+  unsigned int count;		/* How many types */
+  const char *name;		/* Name of typelib */
+  const char **type_names;
+  unsigned int *type_lengths;
+} TYPELIB;
+
+extern int find_type(char *x,TYPELIB *typelib,unsigned int full_name);
+extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
+extern const char *get_type(TYPELIB *typelib,unsigned int nr);
+extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
+
+extern TYPELIB sql_protocol_typelib;
+
+#endif /* _typelib_h */
diff --git a/dep/include/openssl/aes.h b/dep/include/openssl/aes.h
new file mode 100644
index 000000000..e6fc44a24
--- /dev/null
+++ b/dep/include/openssl/aes.h
@@ -0,0 +1,138 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_H
+#define HEADER_AES_H
+
+#include 
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#define AES_ENCRYPT	1
+#define AES_DECRYPT	0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+#ifdef AES_LONG
+    unsigned long rd_key[4 *(AES_MAXNR + 1)];
+#else
+    unsigned int rd_key[4 *(AES_MAXNR + 1)];
+#endif
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+	AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+	AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
+			    const int nbits,const AES_KEY *key,
+			    unsigned char *ivec,const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num);
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char ivec[AES_BLOCK_SIZE],
+	unsigned char ecount_buf[AES_BLOCK_SIZE],
+	unsigned int *num);
+
+/* For IGE, see also http://www.links.org/files/openssl-ige.pdf */
+/* NB: the IV is _two_ blocks long */
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+		     const unsigned long length, const AES_KEY *key,
+		     unsigned char *ivec, const int enc);
+/* NB: the IV is _four_ blocks long */
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+			const unsigned long length, const AES_KEY *key,
+			const AES_KEY *key2, const unsigned char *ivec,
+			const int enc);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
diff --git a/dep/include/openssl/asn1.h b/dep/include/openssl/asn1.h
new file mode 100644
index 000000000..30f1eecd5
--- /dev/null
+++ b/dep/include/openssl/asn1.h
@@ -0,0 +1,1233 @@
+/* crypto/asn1/asn1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_H
+#define HEADER_ASN1_H
+
+#include 
+#include 
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+#include 
+
+#include 
+
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define V_ASN1_UNIVERSAL		0x00
+#define	V_ASN1_APPLICATION		0x40
+#define V_ASN1_CONTEXT_SPECIFIC		0x80
+#define V_ASN1_PRIVATE			0xc0
+
+#define V_ASN1_CONSTRUCTED		0x20
+#define V_ASN1_PRIMITIVE_TAG		0x1f
+#define V_ASN1_PRIMATIVE_TAG		0x1f
+
+#define V_ASN1_APP_CHOOSE		-2	/* let the recipient choose */
+#define V_ASN1_OTHER			-3	/* used in ASN1_TYPE */
+#define V_ASN1_ANY			-4	/* used in ASN1 template code */
+
+#define V_ASN1_NEG			0x100	/* negative flag */
+
+#define V_ASN1_UNDEF			-1
+#define V_ASN1_EOC			0
+#define V_ASN1_BOOLEAN			1	/**/
+#define V_ASN1_INTEGER			2
+#define V_ASN1_NEG_INTEGER		(2 | V_ASN1_NEG)
+#define V_ASN1_BIT_STRING		3
+#define V_ASN1_OCTET_STRING		4
+#define V_ASN1_NULL			5
+#define V_ASN1_OBJECT			6
+#define V_ASN1_OBJECT_DESCRIPTOR	7
+#define V_ASN1_EXTERNAL			8
+#define V_ASN1_REAL			9
+#define V_ASN1_ENUMERATED		10
+#define V_ASN1_NEG_ENUMERATED		(10 | V_ASN1_NEG)
+#define V_ASN1_UTF8STRING		12
+#define V_ASN1_SEQUENCE			16
+#define V_ASN1_SET			17
+#define V_ASN1_NUMERICSTRING		18	/**/
+#define V_ASN1_PRINTABLESTRING		19
+#define V_ASN1_T61STRING		20
+#define V_ASN1_TELETEXSTRING		20	/* alias */
+#define V_ASN1_VIDEOTEXSTRING		21	/**/
+#define V_ASN1_IA5STRING		22
+#define V_ASN1_UTCTIME			23
+#define V_ASN1_GENERALIZEDTIME		24	/**/
+#define V_ASN1_GRAPHICSTRING		25	/**/
+#define V_ASN1_ISO64STRING		26	/**/
+#define V_ASN1_VISIBLESTRING		26	/* alias */
+#define V_ASN1_GENERALSTRING		27	/**/
+#define V_ASN1_UNIVERSALSTRING		28	/**/
+#define V_ASN1_BMPSTRING		30
+
+/* For use with d2i_ASN1_type_bytes() */
+#define B_ASN1_NUMERICSTRING	0x0001
+#define B_ASN1_PRINTABLESTRING	0x0002
+#define B_ASN1_T61STRING	0x0004
+#define B_ASN1_TELETEXSTRING	0x0004
+#define B_ASN1_VIDEOTEXSTRING	0x0008
+#define B_ASN1_IA5STRING	0x0010
+#define B_ASN1_GRAPHICSTRING	0x0020
+#define B_ASN1_ISO64STRING	0x0040
+#define B_ASN1_VISIBLESTRING	0x0040
+#define B_ASN1_GENERALSTRING	0x0080
+#define B_ASN1_UNIVERSALSTRING	0x0100
+#define B_ASN1_OCTET_STRING	0x0200
+#define B_ASN1_BIT_STRING	0x0400
+#define B_ASN1_BMPSTRING	0x0800
+#define B_ASN1_UNKNOWN		0x1000
+#define B_ASN1_UTF8STRING	0x2000
+#define B_ASN1_UTCTIME		0x4000
+#define B_ASN1_GENERALIZEDTIME	0x8000
+#define B_ASN1_SEQUENCE		0x10000
+
+/* For use with ASN1_mbstring_copy() */
+#define MBSTRING_FLAG		0x1000
+#define MBSTRING_UTF8		(MBSTRING_FLAG)
+#define MBSTRING_ASC		(MBSTRING_FLAG|1)
+#define MBSTRING_BMP		(MBSTRING_FLAG|2)
+#define MBSTRING_UNIV		(MBSTRING_FLAG|4)
+
+struct X509_algor_st;
+
+#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */
+#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */
+
+/* We MUST make sure that, except for constness, asn1_ctx_st and
+   asn1_const_ctx are exactly the same.  Fortunately, as soon as
+   the old ASN1 parsing macros are gone, we can throw this away
+   as well... */
+typedef struct asn1_ctx_st
+	{
+	unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	unsigned char *max; /* largest value of p allowed */
+	unsigned char *q;/* temporary variable */
+	unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_CTX;
+
+typedef struct asn1_const_ctx_st
+	{
+	const unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	const unsigned char *max; /* largest value of p allowed */
+	const unsigned char *q;/* temporary variable */
+	const unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_const_CTX;
+
+/* These are used internally in the ASN1_OBJECT to keep track of
+ * whether the names and data need to be free()ed */
+#define ASN1_OBJECT_FLAG_DYNAMIC	 0x01	/* internal use */
+#define ASN1_OBJECT_FLAG_CRITICAL	 0x02	/* critical x509v3 object id */
+#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04	/* internal use */
+#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 	 0x08	/* internal use */
+typedef struct asn1_object_st
+	{
+	const char *sn,*ln;
+	int nid;
+	int length;
+	unsigned char *data;
+	int flags;	/* Should we free this one */
+	} ASN1_OBJECT;
+
+#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
+/* This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should
+ * be inserted in the memory buffer 
+ */
+#define ASN1_STRING_FLAG_NDEF 0x010 
+/* This is the base type that holds just about everything :-) */
+typedef struct asn1_string_st
+	{
+	int length;
+	int type;
+	unsigned char *data;
+	/* The value of the following field depends on the type being
+	 * held.  It is mostly being used for BIT_STRING so if the
+	 * input data has a non-zero 'unused bits' value, it will be
+	 * handled correctly */
+	long flags;
+	} ASN1_STRING;
+
+/* ASN1_ENCODING structure: this is used to save the received
+ * encoding of an ASN1 type. This is useful to get round
+ * problems with invalid encodings which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st
+	{
+	unsigned char *enc;	/* DER encoding */
+	long len;		/* Length of encoding */
+	int modified;		 /* set to 1 if 'enc' is invalid */
+	} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+#define ASN1_LONG_UNDEF	0x7fffffffL
+
+#define STABLE_FLAGS_MALLOC	0x01
+#define STABLE_NO_MASK		0x02
+#define DIRSTRING_TYPE	\
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+	int nid;
+	long minsize;
+	long maxsize;
+	unsigned long mask;
+	unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name				32768
+#define ub_common_name			64
+#define ub_locality_name		128
+#define ub_state_name			128
+#define ub_organization_name		64
+#define ub_organization_unit_name	64
+#define ub_title			64
+#define ub_email_address		128
+
+/* Declarations for template structures: for full definitions
+ * see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+#define	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+	type *d2i_##name(type **a, const unsigned char **in, long len); \
+	int i2d_##name(type *a, unsigned char **out); \
+	DECLARE_ASN1_ITEM(itname)
+
+#define	DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+	type *d2i_##name(type **a, const unsigned char **in, long len); \
+	int i2d_##name(const type *a, unsigned char **out); \
+	DECLARE_ASN1_ITEM(name)
+
+#define	DECLARE_ASN1_NDEF_FUNCTION(name) \
+	int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+#define DECLARE_ASN1_FUNCTIONS_const(name) \
+	name *name##_new(void); \
+	void name##_free(name *a);
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	type *name##_new(void); \
+	void name##_free(type *a);
+
+#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+#define I2D_OF(type) int (*)(type *,unsigned char **)
+#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/* The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ *      ...
+ *      ASN1_ITEM_EXP *iptr;
+ *      ...
+ * } SOMETHING; 
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#define DECLARE_ASN1_ITEM(name) \
+	OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+#else
+
+/* Platforms that can't easily handle shared global variables are declared
+ * as functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM * ASN1_ITEM_EXP(void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#define DECLARE_ASN1_ITEM(name) \
+	const ASN1_ITEM * name##_it(void);
+
+#endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/* These determine which characters to escape:
+ * RFC2253 special characters, control characters and
+ * MSB set characters
+ */
+
+#define ASN1_STRFLGS_ESC_2253		1
+#define ASN1_STRFLGS_ESC_CTRL		2
+#define ASN1_STRFLGS_ESC_MSB		4
+
+
+/* This flag determines how we do escaping: normally
+ * RC2253 backslash only, set this to use backslash and
+ * quote.
+ */
+
+#define ASN1_STRFLGS_ESC_QUOTE		8
+
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+#define CHARTYPE_PRINTABLESTRING	0x10
+/* Character needs escaping if it is the first character */
+#define CHARTYPE_FIRST_ESC_2253		0x20
+/* Character needs escaping if it is the last character */
+#define CHARTYPE_LAST_ESC_2253		0x40
+
+/* NB the internal flags are safely reused below by flags
+ * handled at the top level.
+ */
+
+/* If this is set we convert all character strings
+ * to UTF8 first 
+ */
+
+#define ASN1_STRFLGS_UTF8_CONVERT	0x10
+
+/* If this is set we don't attempt to interpret content:
+ * just assume all strings are 1 byte per character. This
+ * will produce some pretty odd looking output!
+ */
+
+#define ASN1_STRFLGS_IGNORE_TYPE	0x20
+
+/* If this is set we include the string type in the output */
+#define ASN1_STRFLGS_SHOW_TYPE		0x40
+
+/* This determines which strings to display and which to
+ * 'dump' (hex dump of content octets or DER encoding). We can
+ * only dump non character strings or everything. If we
+ * don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to
+ * the usual escaping options.
+ */
+
+#define ASN1_STRFLGS_DUMP_ALL		0x80
+#define ASN1_STRFLGS_DUMP_UNKNOWN	0x100
+
+/* These determine what 'dumping' does, we can dump the
+ * content octets or the DER encoding: both use the
+ * RFC2253 #XXXXX notation.
+ */
+
+#define ASN1_STRFLGS_DUMP_DER		0x200
+
+/* All the string flags consistent with RFC2253,
+ * escaping control characters isn't essential in
+ * RFC2253 but it is advisable anyway.
+ */
+
+#define ASN1_STRFLGS_RFC2253	(ASN1_STRFLGS_ESC_2253 | \
+				ASN1_STRFLGS_ESC_CTRL | \
+				ASN1_STRFLGS_ESC_MSB | \
+				ASN1_STRFLGS_UTF8_CONVERT | \
+				ASN1_STRFLGS_DUMP_UNKNOWN | \
+				ASN1_STRFLGS_DUMP_DER)
+
+DECLARE_STACK_OF(ASN1_INTEGER)
+DECLARE_ASN1_SET_OF(ASN1_INTEGER)
+
+DECLARE_STACK_OF(ASN1_GENERALSTRING)
+
+typedef struct asn1_type_st
+	{
+	int type;
+	union	{
+		char *ptr;
+		ASN1_BOOLEAN		boolean;
+		ASN1_STRING *		asn1_string;
+		ASN1_OBJECT *		object;
+		ASN1_INTEGER *		integer;
+		ASN1_ENUMERATED *	enumerated;
+		ASN1_BIT_STRING *	bit_string;
+		ASN1_OCTET_STRING *	octet_string;
+		ASN1_PRINTABLESTRING *	printablestring;
+		ASN1_T61STRING *	t61string;
+		ASN1_IA5STRING *	ia5string;
+		ASN1_GENERALSTRING *	generalstring;
+		ASN1_BMPSTRING *	bmpstring;
+		ASN1_UNIVERSALSTRING *	universalstring;
+		ASN1_UTCTIME *		utctime;
+		ASN1_GENERALIZEDTIME *	generalizedtime;
+		ASN1_VISIBLESTRING *	visiblestring;
+		ASN1_UTF8STRING *	utf8string;
+		/* set and sequence are left complete and still
+		 * contain the set or sequence bytes */
+		ASN1_STRING *		set;
+		ASN1_STRING *		sequence;
+		} value;
+	} ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef struct asn1_method_st
+	{
+	i2d_of_void *i2d;
+	d2i_of_void *d2i;
+	void *(*create)(void);
+	void (*destroy)(void *);
+	} ASN1_METHOD;
+
+/* This is used when parsing some Netscape objects */
+typedef struct asn1_header_st
+	{
+	ASN1_OCTET_STRING *header;
+	void *data;
+	ASN1_METHOD *meth;
+	} ASN1_HEADER;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+	int bitnum;
+	const char *lname;
+	const char *sname;
+} BIT_STRING_BITNAME;
+
+
+#define M_ASN1_STRING_length(x)	((x)->length)
+#define M_ASN1_STRING_length_set(x, n)	((x)->length = (n))
+#define M_ASN1_STRING_type(x)	((x)->type)
+#define M_ASN1_STRING_data(x)	((x)->data)
+
+/* Macros for string operations */
+#define M_ASN1_BIT_STRING_new()	(ASN1_BIT_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+#define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+		ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+#define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
+		ASN1_STRING_type_new(V_ASN1_INTEGER)
+#define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+
+#define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
+		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+#define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+
+#define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+#define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+		ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+#define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
+#define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
+#define M_i2d_ASN1_OCTET_STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+		V_ASN1_UNIVERSAL)
+
+#define B_ASN1_TIME \
+			B_ASN1_UTCTIME | \
+			B_ASN1_GENERALIZEDTIME
+
+#define B_ASN1_PRINTABLE \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_T61STRING| \
+			B_ASN1_IA5STRING| \
+			B_ASN1_BIT_STRING| \
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING|\
+			B_ASN1_SEQUENCE|\
+			B_ASN1_UNKNOWN
+
+#define B_ASN1_DIRECTORYSTRING \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_TELETEXSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_UTF8STRING
+
+#define B_ASN1_DISPLAYTEXT \
+			B_ASN1_IA5STRING| \
+			B_ASN1_VISIBLESTRING| \
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING
+
+#define M_ASN1_PRINTABLE_new()	ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_PRINTABLE_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+		pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_PRINTABLE)
+
+#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_DIRECTORYSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DIRECTORYSTRING(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_DIRECTORYSTRING)
+
+#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DISPLAYTEXT(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_DISPLAYTEXT)
+
+#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_ASN1_PRINTABLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+		(ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+#define M_ASN1_T61STRING_new()	(ASN1_T61STRING *)\
+		ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_T61STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_T61STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_T61STRING(a,pp,l) \
+		(ASN1_T61STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+#define M_ASN1_IA5STRING_new()	(ASN1_IA5STRING *)\
+		ASN1_STRING_type_new(V_ASN1_IA5STRING)
+#define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_IA5STRING_dup(a)	\
+			(ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_i2d_ASN1_IA5STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_IA5STRING(a,pp,l) \
+		(ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+			B_ASN1_IA5STRING)
+
+#define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+
+#define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+#define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+	(ASN1_STRING *)a)
+
+#define M_ASN1_TIME_new()	(ASN1_TIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+
+#define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+#define M_ASN1_GENERALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_GENERALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+		(ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+#define M_ASN1_UNIVERSALSTRING_new()	(ASN1_UNIVERSALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+#define M_ASN1_UNIVERSALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+		(ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+#define M_ASN1_BMPSTRING_new()	(ASN1_BMPSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+#define M_ASN1_BMPSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_BMPSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+		(ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+#define M_ASN1_VISIBLESTRING_new()	(ASN1_VISIBLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_ASN1_VISIBLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+		(ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+#define M_ASN1_UTF8STRING_new()	(ASN1_UTF8STRING *)\
+		ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+#define M_ASN1_UTF8STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UTF8STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+		(ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+  /* for the is_set parameter to i2d_ASN1_SET */
+#define IS_SEQUENCE	0
+#define IS_SET		1
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+
+ASN1_OBJECT *	ASN1_OBJECT_new(void );
+void		ASN1_OBJECT_free(ASN1_OBJECT *a);
+int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
+ASN1_OBJECT *	c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+			long length);
+ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+			long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING *	ASN1_STRING_new(void);
+void		ASN1_STRING_free(ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_dup(ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_type_new(int type );
+int 		ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
+  /* Since this is used to store all sorts of things, via macros, for now, make
+     its data void * */
+int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+int ASN1_STRING_length(ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int		i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
+			long length);
+int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
+			int length );
+int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+
+#ifndef OPENSSL_NO_BIO
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+				BIT_STRING_BITNAME *tbl, int indent);
+#endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+				BIT_STRING_BITNAME *tbl);
+
+int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
+int 		d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+int		i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+			long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+			long length);
+ASN1_INTEGER *	ASN1_INTEGER_dup(ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+#if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
+#endif
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a);
+int 	ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b);
+int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+int ASN1_TIME_check(ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+
+int i2d_ASN1_SET(STACK *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
+STACK *	d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
+		     d2i_of_void *d2i, void (*free_func)(void *),
+		     int ex_tag, int ex_class);
+
+#ifndef OPENSSL_NO_BIO
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+#endif
+int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
+	const char *sn, const char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+	long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
+		long length,int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+int asn1_const_Finish(ASN1_const_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+	int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+int ASN1_const_check_infinite_end(const unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+	int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
+#define ASN1_dup_of(type,i2d,d2i,x) \
+	((type *(*)(I2D_OF(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x)
+#define ASN1_dup_of_const(type,i2d,d2i,x) \
+	((type *(*)(I2D_OF_const(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x)
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
+#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+	((type *(*)(type *(*)(void),D2I_OF(type),FILE *,type **))openssl_fcast(ASN1_d2i_fp))(xnew,d2i,in,x)
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
+#define ASN1_i2d_fp_of(type,i2d,out,x) \
+	((int (*)(I2D_OF(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x)
+#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+	((int (*)(I2D_OF_const(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x)
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+#endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+#ifndef OPENSSL_NO_BIO
+void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
+#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+	((type *(*)(type *(*)(void),D2I_OF(type),BIO *,type **))openssl_fcast(ASN1_d2i_bio))(xnew,d2i,in,x)
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+#define ASN1_i2d_bio_of(type,i2d,out,x) \
+	((int (*)(I2D_OF(type),BIO *,type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x)
+#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+	((int (*)(I2D_OF_const(type),BIO *,const type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x)
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp,ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp,ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
+int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
+#endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert/key */
+int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp);
+ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length);
+ASN1_HEADER *ASN1_HEADER_new(void );
+void ASN1_HEADER_free(ASN1_HEADER *a);
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+/* Not used that much at this point, except for the first two */
+ASN1_METHOD *X509_asn1_meth(void);
+ASN1_METHOD *RSAPrivateKey_asn1_meth(void);
+ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void);
+ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
+	unsigned char *data, int max_len);
+
+STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
+		       d2i_of_void *d2i, void (*free_func)(void *));
+unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d,
+			     unsigned char **buf, int *len );
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
+			      ASN1_OCTET_STRING **oct);
+#define ASN1_pack_string_of(type,obj,i2d,oct) \
+	((ASN1_STRING *(*)(type *,I2D_OF(type),ASN1_OCTET_STRING **))openssl_fcast(ASN1_pack_string))(obj,i2d,oct)
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask, 
+					long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
+		const unsigned char *in, int inlen, int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+	
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+#define ASN1_F_A2D_ASN1_OBJECT				 100
+#define ASN1_F_A2I_ASN1_ENUMERATED			 101
+#define ASN1_F_A2I_ASN1_INTEGER				 102
+#define ASN1_F_A2I_ASN1_STRING				 103
+#define ASN1_F_APPEND_EXP				 176
+#define ASN1_F_ASN1_BIT_STRING_SET_BIT			 183
+#define ASN1_F_ASN1_CB					 177
+#define ASN1_F_ASN1_CHECK_TLEN				 104
+#define ASN1_F_ASN1_COLLATE_PRIMITIVE			 105
+#define ASN1_F_ASN1_COLLECT				 106
+#define ASN1_F_ASN1_D2I_EX_PRIMITIVE			 108
+#define ASN1_F_ASN1_D2I_FP				 109
+#define ASN1_F_ASN1_D2I_READ_BIO			 107
+#define ASN1_F_ASN1_DIGEST				 184
+#define ASN1_F_ASN1_DO_ADB				 110
+#define ASN1_F_ASN1_DUP					 111
+#define ASN1_F_ASN1_ENUMERATED_SET			 112
+#define ASN1_F_ASN1_ENUMERATED_TO_BN			 113
+#define ASN1_F_ASN1_EX_C2I				 204
+#define ASN1_F_ASN1_FIND_END				 190
+#define ASN1_F_ASN1_GENERALIZEDTIME_SET			 185
+#define ASN1_F_ASN1_GENERATE_V3				 178
+#define ASN1_F_ASN1_GET_OBJECT				 114
+#define ASN1_F_ASN1_HEADER_NEW				 115
+#define ASN1_F_ASN1_I2D_BIO				 116
+#define ASN1_F_ASN1_I2D_FP				 117
+#define ASN1_F_ASN1_INTEGER_SET				 118
+#define ASN1_F_ASN1_INTEGER_TO_BN			 119
+#define ASN1_F_ASN1_ITEM_D2I_FP				 206
+#define ASN1_F_ASN1_ITEM_DUP				 191
+#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW			 121
+#define ASN1_F_ASN1_ITEM_EX_D2I				 120
+#define ASN1_F_ASN1_ITEM_I2D_BIO			 192
+#define ASN1_F_ASN1_ITEM_I2D_FP				 193
+#define ASN1_F_ASN1_ITEM_PACK				 198
+#define ASN1_F_ASN1_ITEM_SIGN				 195
+#define ASN1_F_ASN1_ITEM_UNPACK				 199
+#define ASN1_F_ASN1_ITEM_VERIFY				 197
+#define ASN1_F_ASN1_MBSTRING_NCOPY			 122
+#define ASN1_F_ASN1_OBJECT_NEW				 123
+#define ASN1_F_ASN1_PACK_STRING				 124
+#define ASN1_F_ASN1_PCTX_NEW				 205
+#define ASN1_F_ASN1_PKCS5_PBE_SET			 125
+#define ASN1_F_ASN1_SEQ_PACK				 126
+#define ASN1_F_ASN1_SEQ_UNPACK				 127
+#define ASN1_F_ASN1_SIGN				 128
+#define ASN1_F_ASN1_STR2TYPE				 179
+#define ASN1_F_ASN1_STRING_SET				 186
+#define ASN1_F_ASN1_STRING_TABLE_ADD			 129
+#define ASN1_F_ASN1_STRING_TYPE_NEW			 130
+#define ASN1_F_ASN1_TEMPLATE_EX_D2I			 132
+#define ASN1_F_ASN1_TEMPLATE_NEW			 133
+#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I			 131
+#define ASN1_F_ASN1_TIME_SET				 175
+#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 134
+#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 135
+#define ASN1_F_ASN1_UNPACK_STRING			 136
+#define ASN1_F_ASN1_UTCTIME_SET				 187
+#define ASN1_F_ASN1_VERIFY				 137
+#define ASN1_F_BITSTR_CB				 180
+#define ASN1_F_BN_TO_ASN1_ENUMERATED			 138
+#define ASN1_F_BN_TO_ASN1_INTEGER			 139
+#define ASN1_F_C2I_ASN1_BIT_STRING			 189
+#define ASN1_F_C2I_ASN1_INTEGER				 194
+#define ASN1_F_C2I_ASN1_OBJECT				 196
+#define ASN1_F_COLLECT_DATA				 140
+#define ASN1_F_D2I_ASN1_BIT_STRING			 141
+#define ASN1_F_D2I_ASN1_BOOLEAN				 142
+#define ASN1_F_D2I_ASN1_BYTES				 143
+#define ASN1_F_D2I_ASN1_GENERALIZEDTIME			 144
+#define ASN1_F_D2I_ASN1_HEADER				 145
+#define ASN1_F_D2I_ASN1_INTEGER				 146
+#define ASN1_F_D2I_ASN1_OBJECT				 147
+#define ASN1_F_D2I_ASN1_SET				 148
+#define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
+#define ASN1_F_D2I_ASN1_UINTEGER			 150
+#define ASN1_F_D2I_ASN1_UTCTIME				 151
+#define ASN1_F_D2I_NETSCAPE_RSA				 152
+#define ASN1_F_D2I_NETSCAPE_RSA_2			 153
+#define ASN1_F_D2I_PRIVATEKEY				 154
+#define ASN1_F_D2I_PUBLICKEY				 155
+#define ASN1_F_D2I_RSA_NET				 200
+#define ASN1_F_D2I_RSA_NET_2				 201
+#define ASN1_F_D2I_X509					 156
+#define ASN1_F_D2I_X509_CINF				 157
+#define ASN1_F_D2I_X509_PKEY				 159
+#define ASN1_F_I2D_ASN1_SET				 188
+#define ASN1_F_I2D_ASN1_TIME				 160
+#define ASN1_F_I2D_DSA_PUBKEY				 161
+#define ASN1_F_I2D_EC_PUBKEY				 181
+#define ASN1_F_I2D_PRIVATEKEY				 163
+#define ASN1_F_I2D_PUBLICKEY				 164
+#define ASN1_F_I2D_RSA_NET				 162
+#define ASN1_F_I2D_RSA_PUBKEY				 165
+#define ASN1_F_LONG_C2I					 166
+#define ASN1_F_OID_MODULE_INIT				 174
+#define ASN1_F_PARSE_TAGGING				 182
+#define ASN1_F_PKCS5_PBE2_SET				 167
+#define ASN1_F_PKCS5_PBE_SET				 202
+#define ASN1_F_X509_CINF_NEW				 168
+#define ASN1_F_X509_CRL_ADD0_REVOKED			 169
+#define ASN1_F_X509_INFO_NEW				 170
+#define ASN1_F_X509_NAME_ENCODE				 203
+#define ASN1_F_X509_NAME_EX_D2I				 158
+#define ASN1_F_X509_NAME_EX_NEW				 171
+#define ASN1_F_X509_NEW					 172
+#define ASN1_F_X509_PKEY_NEW				 173
+
+/* Reason codes. */
+#define ASN1_R_ADDING_OBJECT				 171
+#define ASN1_R_AUX_ERROR				 100
+#define ASN1_R_BAD_CLASS				 101
+#define ASN1_R_BAD_OBJECT_HEADER			 102
+#define ASN1_R_BAD_PASSWORD_READ			 103
+#define ASN1_R_BAD_TAG					 104
+#define ASN1_R_BN_LIB					 105
+#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
+#define ASN1_R_BUFFER_TOO_SMALL				 107
+#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 108
+#define ASN1_R_DATA_IS_WRONG				 109
+#define ASN1_R_DECODE_ERROR				 110
+#define ASN1_R_DECODING_ERROR				 111
+#define ASN1_R_DEPTH_EXCEEDED				 174
+#define ASN1_R_ENCODE_ERROR				 112
+#define ASN1_R_ERROR_GETTING_TIME			 173
+#define ASN1_R_ERROR_LOADING_SECTION			 172
+#define ASN1_R_ERROR_PARSING_SET_ELEMENT		 113
+#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS		 114
+#define ASN1_R_EXPECTING_AN_INTEGER			 115
+#define ASN1_R_EXPECTING_AN_OBJECT			 116
+#define ASN1_R_EXPECTING_A_BOOLEAN			 117
+#define ASN1_R_EXPECTING_A_TIME				 118
+#define ASN1_R_EXPLICIT_LENGTH_MISMATCH			 119
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED		 120
+#define ASN1_R_FIELD_MISSING				 121
+#define ASN1_R_FIRST_NUM_TOO_LARGE			 122
+#define ASN1_R_HEADER_TOO_LONG				 123
+#define ASN1_R_ILLEGAL_BITSTRING_FORMAT			 175
+#define ASN1_R_ILLEGAL_BOOLEAN				 176
+#define ASN1_R_ILLEGAL_CHARACTERS			 124
+#define ASN1_R_ILLEGAL_FORMAT				 177
+#define ASN1_R_ILLEGAL_HEX				 178
+#define ASN1_R_ILLEGAL_IMPLICIT_TAG			 179
+#define ASN1_R_ILLEGAL_INTEGER				 180
+#define ASN1_R_ILLEGAL_NESTED_TAGGING			 181
+#define ASN1_R_ILLEGAL_NULL				 125
+#define ASN1_R_ILLEGAL_NULL_VALUE			 182
+#define ASN1_R_ILLEGAL_OBJECT				 183
+#define ASN1_R_ILLEGAL_OPTIONAL_ANY			 126
+#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE		 170
+#define ASN1_R_ILLEGAL_TAGGED_ANY			 127
+#define ASN1_R_ILLEGAL_TIME_VALUE			 184
+#define ASN1_R_INTEGER_NOT_ASCII_FORMAT			 185
+#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
+#define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
+#define ASN1_R_INVALID_DIGIT				 130
+#define ASN1_R_INVALID_MODIFIER				 186
+#define ASN1_R_INVALID_NUMBER				 187
+#define ASN1_R_INVALID_SEPARATOR			 131
+#define ASN1_R_INVALID_TIME_FORMAT			 132
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 133
+#define ASN1_R_INVALID_UTF8STRING			 134
+#define ASN1_R_IV_TOO_LARGE				 135
+#define ASN1_R_LENGTH_ERROR				 136
+#define ASN1_R_LIST_ERROR				 188
+#define ASN1_R_MISSING_EOC				 137
+#define ASN1_R_MISSING_SECOND_NUMBER			 138
+#define ASN1_R_MISSING_VALUE				 189
+#define ASN1_R_MSTRING_NOT_UNIVERSAL			 139
+#define ASN1_R_MSTRING_WRONG_TAG			 140
+#define ASN1_R_NESTED_ASN1_STRING			 197
+#define ASN1_R_NON_HEX_CHARACTERS			 141
+#define ASN1_R_NOT_ASCII_FORMAT				 190
+#define ASN1_R_NOT_ENOUGH_DATA				 142
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE			 143
+#define ASN1_R_NULL_IS_WRONG_LENGTH			 144
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT			 191
+#define ASN1_R_ODD_NUMBER_OF_CHARS			 145
+#define ASN1_R_PRIVATE_KEY_HEADER_MISSING		 146
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE			 147
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH			 148
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED			 149
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG		 192
+#define ASN1_R_SHORT_LINE				 150
+#define ASN1_R_STRING_TOO_LONG				 151
+#define ASN1_R_STRING_TOO_SHORT				 152
+#define ASN1_R_TAG_VALUE_TOO_HIGH			 153
+#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+#define ASN1_R_TIME_NOT_ASCII_FORMAT			 193
+#define ASN1_R_TOO_LONG					 155
+#define ASN1_R_TYPE_NOT_CONSTRUCTED			 156
+#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
+#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
+#define ASN1_R_UNEXPECTED_EOC				 159
+#define ASN1_R_UNKNOWN_FORMAT				 160
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
+#define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
+#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 163
+#define ASN1_R_UNKNOWN_TAG				 194
+#define ASN1_R_UNKOWN_FORMAT				 195
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE		 164
+#define ASN1_R_UNSUPPORTED_CIPHER			 165
+#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 166
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 167
+#define ASN1_R_UNSUPPORTED_TYPE				 196
+#define ASN1_R_WRONG_TAG				 168
+#define ASN1_R_WRONG_TYPE				 169
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/asn1_mac.h b/dep/include/openssl/asn1_mac.h
new file mode 100644
index 000000000..d958ca60d
--- /dev/null
+++ b/dep/include/openssl/asn1_mac.h
@@ -0,0 +1,571 @@
+/* crypto/asn1/asn1_mac.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_MAC_H
+#define HEADER_ASN1_MAC_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASN1_MAC_ERR_LIB
+#define ASN1_MAC_ERR_LIB	ERR_LIB_ASN1
+#endif 
+
+#define ASN1_MAC_H_err(f,r,line) \
+	ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))
+
+#define M_ASN1_D2I_vars(a,type,func) \
+	ASN1_const_CTX c; \
+	type ret=NULL; \
+	\
+	c.pp=(const unsigned char **)pp; \
+	c.q= *(const unsigned char **)pp; \
+	c.error=ERR_R_NESTED_ASN1_ERROR; \
+	if ((a == NULL) || ((*a) == NULL)) \
+		{ if ((ret=(type)func()) == NULL) \
+			{ c.line=__LINE__; goto err; } } \
+	else	ret=(*a);
+
+#define M_ASN1_D2I_Init() \
+	c.p= *(const unsigned char **)pp; \
+	c.max=(length == 0)?0:(c.p+length);
+
+#define M_ASN1_D2I_Finish_2(a) \
+	if (!asn1_const_Finish(&c)) \
+		{ c.line=__LINE__; goto err; } \
+	*(const unsigned char **)pp=c.p; \
+	if (a != NULL) (*a)=ret; \
+	return(ret);
+
+#define M_ASN1_D2I_Finish(a,func,e) \
+	M_ASN1_D2I_Finish_2(a); \
+err:\
+	ASN1_MAC_H_err((e),c.error,c.line); \
+	asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+	return(NULL)
+
+#define M_ASN1_D2I_start_sequence() \
+	if (!asn1_GetSequence(&c,&length)) \
+		{ c.line=__LINE__; goto err; }
+/* Begin reading ASN1 without a surrounding sequence */
+#define M_ASN1_D2I_begin() \
+	c.slen = length;
+
+/* End reading ASN1 with no check on length */
+#define M_ASN1_D2I_Finish_nolen(a, func, e) \
+	*pp=c.p; \
+	if (a != NULL) (*a)=ret; \
+	return(ret); \
+err:\
+	ASN1_MAC_H_err((e),c.error,c.line); \
+	asn1_add_error(*pp,(int)(c.q- *pp)); \
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+	return(NULL)
+
+#define M_ASN1_D2I_end_sequence() \
+	(((c.inf&1) == 0)?(c.slen <= 0): \
+		(c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+#define M_ASN1_D2I_get(b, func) \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+#define M_ASN1_D2I_get_x(type,b,func) \
+	c.q=c.p; \
+	if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+/* use this instead () */
+#define M_ASN1_D2I_get_int(b,func) \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) < 0) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_opt(b,func,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+		== (V_ASN1_UNIVERSAL|(type)))) \
+		{ \
+		M_ASN1_D2I_get(b,func); \
+		}
+
+#define M_ASN1_D2I_get_imp(b,func, type) \
+	M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
+	c.slen-=(c.p-c.q);\
+	M_ASN1_next_prev=_tmp;
+
+#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
+		(V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
+		{ \
+		unsigned char _tmp = M_ASN1_next; \
+		M_ASN1_D2I_get_imp(b,func, type);\
+		}
+
+#define M_ASN1_D2I_get_set(r,func,free_func) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func, \
+			V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
+			V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_opt(r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+		{ M_ASN1_D2I_get_set(r,func,free_func); }
+
+#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+		{ M_ASN1_D2I_get_set_type(type,r,func,free_func); }
+
+#define M_ASN1_I2D_len_SET_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_len_SET(a,f);
+
+#define M_ASN1_I2D_put_SET_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_put_SET(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
+	if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
+
+#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
+	if ((c.slen != 0) && \
+		(M_ASN1_next == \
+		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+		{ \
+		M_ASN1_D2I_get_imp_set(b,func,free_func,\
+			tag,V_ASN1_CONTEXT_SPECIFIC); \
+		}
+
+#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
+	if ((c.slen != 0) && \
+		(M_ASN1_next == \
+		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+		{ \
+		M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
+			tag,V_ASN1_CONTEXT_SPECIFIC); \
+		}
+
+#define M_ASN1_D2I_get_seq(r,func,free_func) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func,\
+			V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+					    V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq(r,func,free_func); }
+
+#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
+
+#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func,\
+			x,V_ASN1_CONTEXT_SPECIFIC);
+
+#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+			x,V_ASN1_CONTEXT_SPECIFIC);
+
+#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
+		(void (*)())free_func,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
+				   free_func,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_set_strings(r,func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
+	if ((c.slen != 0L) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (func(&(r),&c.p,Tlen) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
+			(void (*)())free_func, \
+			b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
+			free_func,b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+/* New macros */
+#define M_ASN1_New_Malloc(ret,type) \
+	if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
+		{ c.line=__LINE__; goto err2; }
+
+#define M_ASN1_New(arg,func) \
+	if (((arg)=func()) == NULL) return(NULL)
+
+#define M_ASN1_New_Error(a) \
+/*	err:	ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
+		return(NULL);*/ \
+	err2:	ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
+		return(NULL)
+
+
+/* BIG UGLY WARNING!  This is so damn ugly I wanna puke.  Unfortunately,
+   some macros that use ASN1_const_CTX still insist on writing in the input
+   stream.  ARGH!  ARGH!  ARGH!  Let's get rid of this macro package.
+   Please?						-- Richard Levitte */
+#define M_ASN1_next		(*((unsigned char *)(c.p)))
+#define M_ASN1_next_prev	(*((unsigned char *)(c.q)))
+
+/*************************************************/
+
+#define M_ASN1_I2D_vars(a)	int r=0,ret=0; \
+				unsigned char *p; \
+				if (a == NULL) return(0)
+
+/* Length Macros */
+#define M_ASN1_I2D_len(a,f)	ret+=f(a,NULL)
+#define M_ASN1_I2D_len_IMP_opt(a,f)	if (a != NULL) M_ASN1_I2D_len(a,f)
+
+#define M_ASN1_I2D_len_SET(a,f) \
+		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SET_type(type,a,f) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
+					    V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SEQUENCE(a,f) \
+		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+				  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
+					    V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
+
+#define M_ASN1_I2D_len_IMP_SET(a,f,x) \
+		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+					    V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+					  IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+					       V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
+		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+					  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+						    V_ASN1_CONTEXT_SPECIFIC, \
+						    IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
+		if (a != NULL)\
+			{ \
+			v=f(a,NULL); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
+				       IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
+						 V_ASN1_UNIVERSAL, \
+						 IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+/* Put Macros */
+#define M_ASN1_I2D_put(a,f)	f(a,&p)
+
+#define M_ASN1_I2D_put_IMP_opt(a,f,t)	\
+		if (a != NULL) \
+			{ \
+			unsigned char *q=p; \
+			f(a,&p); \
+			*q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
+			}
+
+#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
+			V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_SET_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+			V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+			V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
+					     V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+			    IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				       IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+						 V_ASN1_CONTEXT_SPECIFIC, \
+						 IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				       IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+						 V_ASN1_CONTEXT_SPECIFIC, \
+						 IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
+		if (a != NULL) \
+			{ \
+			ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
+			f(a,&p); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
+					       IS_SEQUENCE); \
+			}
+
+#define M_ASN1_I2D_seq_total() \
+		r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
+		if (pp == NULL) return(r); \
+		p= *pp; \
+		ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_I2D_INF_seq_start(tag,ctx) \
+		*(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
+		*(p++)=0x80
+
+#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
+
+#define M_ASN1_I2D_finish()	*pp=p; \
+				return(r);
+
+int asn1_GetSequence(ASN1_const_CTX *c, long *length);
+void asn1_add_error(const unsigned char *address,int offset);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/asn1t.h b/dep/include/openssl/asn1t.h
new file mode 100644
index 000000000..adbc2a63d
--- /dev/null
+++ b/dep/include/openssl/asn1t.h
@@ -0,0 +1,886 @@
+/* asn1t.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ASN1T_H
+#define HEADER_ASN1T_H
+
+#include 
+#include 
+#include 
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#define ASN1_ITEM_start(itname) \
+	OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
+
+#define ASN1_ITEM_end(itname) \
+		};
+
+#else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
+
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#define ASN1_ITEM_start(itname) \
+	const ASN1_ITEM * itname##_it(void) \
+	{ \
+		static const ASN1_ITEM local_it = { 
+
+#define ASN1_ITEM_end(itname) \
+		}; \
+	return &local_it; \
+	}
+
+#endif
+
+
+/* Macros to aid ASN1 template writing */
+
+#define ASN1_ITEM_TEMPLATE(tname) \
+	static const ASN1_TEMPLATE tname##_item_tt 
+
+#define ASN1_ITEM_TEMPLATE_END(tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_PRIMITIVE,\
+		-1,\
+		&tname##_item_tt,\
+		0,\
+		NULL,\
+		0,\
+		#tname \
+	ASN1_ITEM_end(tname)
+
+
+/* This is a ASN1 type which just embeds a template */
+ 
+/* This pair helps declare a SEQUENCE. We can do:
+ *
+ * 	ASN1_SEQUENCE(stname) = {
+ * 		... SEQUENCE components ...
+ * 	} ASN1_SEQUENCE_END(stname)
+ *
+ * 	This will produce an ASN1_ITEM called stname_it
+ *	for a structure called stname.
+ *
+ * 	If you want the same structure but a different
+ *	name then use:
+ *
+ * 	ASN1_SEQUENCE(itname) = {
+ * 		... SEQUENCE components ...
+ * 	} ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ *	This will create an item called itname_it using
+ *	a structure called stname.
+ */
+
+#define ASN1_SEQUENCE(tname) \
+	static const ASN1_TEMPLATE tname##_seq_tt[] 
+
+#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+#define ASN1_SEQUENCE_END_name(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_NDEF_SEQUENCE(tname) \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_cb(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_BROKEN_SEQUENCE(tname) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_ref(tname, cb, lck) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_enc(tname, enc, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_NDEF_SEQUENCE_END(tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_NDEF_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(tname),\
+		#tname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
+
+#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+#define ASN1_SEQUENCE_END_ref(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+
+/* This pair helps declare a CHOICE type. We can do:
+ *
+ * 	ASN1_CHOICE(chname) = {
+ * 		... CHOICE options ...
+ * 	ASN1_CHOICE_END(chname)
+ *
+ * 	This will produce an ASN1_ITEM called chname_it
+ *	for a structure called chname. The structure
+ *	definition must look like this:
+ *	typedef struct {
+ *		int type;
+ *		union {
+ *			ASN1_SOMETHING *opt1;
+ *			ASN1_SOMEOTHER *opt2;
+ *		} value;
+ *	} chname;
+ *	
+ *	the name of the selector must be 'type'.
+ * 	to use an alternative selector name use the
+ *      ASN1_CHOICE_END_selector() version.
+ */
+
+#define ASN1_CHOICE(tname) \
+	static const ASN1_TEMPLATE tname##_ch_tt[] 
+
+#define ASN1_CHOICE_cb(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	ASN1_CHOICE(tname)
+
+#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+#define ASN1_CHOICE_END_selector(stname, tname, selname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_CHOICE,\
+		offsetof(stname,selname) ,\
+		tname##_ch_tt,\
+		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_CHOICE_END_cb(stname, tname, selname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_CHOICE,\
+		offsetof(stname,selname) ,\
+		tname##_ch_tt,\
+		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+	(flags), (tag), 0,\
+	#name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+	(flags), (tag), offsetof(stname, field),\
+	#field, ASN1_ITEM_ref(type) }
+
+/* used when the structure is combined with the parent */
+
+#define ASN1_EX_COMBINE(flags, tag, type) { \
+	(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+#define ASN1_IMP_EX(stname, field, type, tag, ex) \
+		ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+#define ASN1_EXP_EX(stname, field, type, tag, ex) \
+		ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#else
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+#endif
+/* Plain simple type */
+#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+
+/* OPTIONAL simple type */
+#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+#define ASN1_SEQUENCE_OF(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+#define ASN1_SET_OF(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+#define ASN1_SET_OF_OPT(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+#define ASN1_IMP_SET_OF(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_EXP_SET_OF(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* EXPLICIT OPTIONAL using indefinite length constructed form */
+#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
+
+/* Macros for the ASN1_ADB structure */
+
+#define ASN1_ADB(name) \
+	static const ASN1_ADB_TABLE name##_adbtbl[] 
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+	;\
+	static const ASN1_ADB name##_adb = {\
+		flags,\
+		offsetof(name, field),\
+		app_table,\
+		name##_adbtbl,\
+		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+		def,\
+		none\
+	}
+
+#else
+
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+	;\
+	static const ASN1_ITEM *name##_adb(void) \
+	{ \
+	static const ASN1_ADB internal_adb = \
+		{\
+		flags,\
+		offsetof(name, field),\
+		app_table,\
+		name##_adbtbl,\
+		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+		def,\
+		none\
+		}; \
+		return (const ASN1_ITEM *) &internal_adb; \
+	} \
+	void dummy_function(void)
+
+#endif
+
+#define ADB_ENTRY(val, template) {val, template}
+
+#define ASN1_ADB_TEMPLATE(name) \
+	static const ASN1_TEMPLATE name##_tt 
+
+/* This is the ASN1 template structure that defines
+ * a wrapper round the actual type. It determines the
+ * actual position of the field in the value structure,
+ * various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+unsigned long flags;		/* Various flags */
+long tag;			/* tag, not used if no tagging */
+unsigned long offset;		/* Offset of this field in structure */
+#ifndef NO_ASN1_FIELD_NAMES
+const char *field_name;		/* Field name */
+#endif
+ASN1_ITEM_EXP *item;		/* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+#define ASN1_TEMPLATE_item(t) (t->item_ptr)
+#define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+	unsigned long flags;	/* Various flags */
+	unsigned long offset;	/* Offset of selector field */
+	STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
+	const ASN1_ADB_TABLE *tbl;	/* Table of possible types */
+	long tblcount;		/* Number of entries in tbl */
+	const ASN1_TEMPLATE *default_tt;  /* Type to use if no match */
+	const ASN1_TEMPLATE *null_tt;  /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+	long value;		/* NID for an object or value for an int */
+	const ASN1_TEMPLATE tt;		/* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+#define ASN1_TFLG_OPTIONAL	(0x1)
+
+/* Field is a SET OF */
+#define ASN1_TFLG_SET_OF	(0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+#define ASN1_TFLG_SEQUENCE_OF	(0x2 << 1)
+
+/* Special case: this refers to a SET OF that
+ * will be sorted into DER order when encoded *and*
+ * the corresponding STACK will be modified to match
+ * the new order.
+ */
+#define ASN1_TFLG_SET_ORDER	(0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+#define ASN1_TFLG_SK_MASK	(0x3 << 1)
+
+/* These flags mean the tag should be taken from the
+ * tag field. If EXPLICIT then the underlying type
+ * is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+#define ASN1_TFLG_IMPTAG	(0x1 << 3)
+
+
+/* EXPLICIT tagging, inner tag from underlying type */
+#define ASN1_TFLG_EXPTAG	(0x2 << 3)
+
+#define ASN1_TFLG_TAG_MASK	(0x3 << 3)
+
+/* context specific IMPLICIT */
+#define ASN1_TFLG_IMPLICIT	ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+#define ASN1_TFLG_EXPLICIT	ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/* If tagging is in force these determine the
+ * type of tag to use. Otherwise the tag is
+ * determined by the underlying type. These 
+ * values reflect the actual octet format.
+ */
+
+/* Universal tag */ 
+#define ASN1_TFLG_UNIVERSAL	(0x0<<6)
+/* Application tag */ 
+#define ASN1_TFLG_APPLICATION	(0x1<<6)
+/* Context specific tag */ 
+#define ASN1_TFLG_CONTEXT	(0x2<<6)
+/* Private tag */ 
+#define ASN1_TFLG_PRIVATE	(0x3<<6)
+
+#define ASN1_TFLG_TAG_CLASS	(0x3<<6)
+
+/* These are for ANY DEFINED BY type. In this case
+ * the 'item' field points to an ASN1_ADB structure
+ * which contains a table of values to decode the
+ * relevant type
+ */
+
+#define ASN1_TFLG_ADB_MASK	(0x3<<8)
+
+#define ASN1_TFLG_ADB_OID	(0x1<<8)
+
+#define ASN1_TFLG_ADB_INT	(0x1<<9)
+
+/* This flag means a parent structure is passed
+ * instead of the field: this is useful is a
+ * SEQUENCE is being combined with a CHOICE for
+ * example. Since this means the structure and
+ * item name will differ we need to use the
+ * ASN1_CHOICE_END_name() macro for example.
+ */
+
+#define ASN1_TFLG_COMBINE	(0x1<<10)
+
+/* This flag when present in a SEQUENCE OF, SET OF
+ * or EXPLICIT causes indefinite length constructed
+ * encoding to be used if required.
+ */
+
+#define ASN1_TFLG_NDEF		(0x1<<11)
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+char itype;			/* The item type, primitive, SEQUENCE, CHOICE or extern */
+long utype;			/* underlying type */
+const ASN1_TEMPLATE *templates;	/* If SEQUENCE or CHOICE this contains the contents */
+long tcount;			/* Number of templates if SEQUENCE or CHOICE */
+const void *funcs;		/* functions that handle this type */
+long size;			/* Structure size (usually)*/
+#ifndef NO_ASN1_FIELD_NAMES
+const char *sname;		/* Structure name */
+#endif
+};
+
+/* These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single 
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions. 
+ *
+ * For COMPAT types the funcs field gives a
+ * set of functions that handle this type, this
+ * supports the old d2i, i2d convention.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ * NDEF_SEQUENCE is the same as SEQUENCE except
+ * that it will use indefinite length constructed
+ * encoding if requested.
+ *
+ */
+
+#define ASN1_ITYPE_PRIMITIVE		0x0
+
+#define ASN1_ITYPE_SEQUENCE		0x1
+
+#define ASN1_ITYPE_CHOICE		0x2
+
+#define ASN1_ITYPE_COMPAT		0x3
+
+#define ASN1_ITYPE_EXTERN		0x4
+
+#define ASN1_ITYPE_MSTRING		0x5
+
+#define ASN1_ITYPE_NDEF_SEQUENCE	0x6
+
+/* Cache for ASN1 tag and length, so we
+ * don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st{
+	char valid;	/* Values below are valid */
+	int ret;	/* return value */
+	long plen;	/* length */
+	int ptag;	/* class value */
+	int pclass;	/* class value */
+	int hdrlen;	/* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+
+typedef ASN1_VALUE * ASN1_new_func(void);
+typedef void ASN1_free_func(ASN1_VALUE *a);
+typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
+typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
+
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
+					int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+
+typedef struct ASN1_COMPAT_FUNCS_st {
+	ASN1_new_func *asn1_new;
+	ASN1_free_func *asn1_free;
+	ASN1_d2i_func *asn1_d2i;
+	ASN1_i2d_func *asn1_i2d;
+} ASN1_COMPAT_FUNCS;
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+	void *app_data;
+	ASN1_ex_new_func *asn1_ex_new;
+	ASN1_ex_free_func *asn1_ex_free;
+	ASN1_ex_free_func *asn1_ex_clear;
+	ASN1_ex_d2i *asn1_ex_d2i;
+	ASN1_ex_i2d *asn1_ex_i2d;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+	void *app_data;
+	unsigned long flags;
+	ASN1_ex_new_func *prim_new;
+	ASN1_ex_free_func *prim_free;
+	ASN1_ex_free_func *prim_clear;
+	ASN1_primitive_c2i *prim_c2i;
+	ASN1_primitive_i2c *prim_i2c;
+} ASN1_PRIMITIVE_FUNCS;
+
+/* This is the ASN1_AUX structure: it handles various
+ * miscellaneous requirements. For example the use of
+ * reference counts and an informational callback.
+ *
+ * The "informational callback" is called at various
+ * points during the ASN1 encoding and decoding. It can
+ * be used to provide minor customisation of the structures
+ * used. This is most useful where the supplied routines
+ * *almost* do the right thing but need some extra help
+ * at a few points. If the callback returns zero then
+ * it is assumed a fatal error has occurred and the 
+ * main operation should be abandoned.
+ *
+ * If major changes in the default behaviour are required
+ * then an external type is more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it);
+
+typedef struct ASN1_AUX_st {
+	void *app_data;
+	int flags;
+	int ref_offset;		/* Offset of reference value */
+	int ref_lock;		/* Lock type to use */
+	ASN1_aux_cb *asn1_cb;
+	int enc_offset;		/* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+#define ASN1_AFLG_REFCOUNT	1
+/* Save the encoding of structure (useful for signatures) */
+#define ASN1_AFLG_ENCODING	2
+/* The Sequence length is invalid */
+#define ASN1_AFLG_BROKEN	4
+
+/* operation values for asn1_cb */
+
+#define ASN1_OP_NEW_PRE		0
+#define ASN1_OP_NEW_POST	1
+#define ASN1_OP_FREE_PRE	2
+#define ASN1_OP_FREE_POST	3
+#define ASN1_OP_D2I_PRE		4
+#define ASN1_OP_D2I_POST	5
+#define ASN1_OP_I2D_PRE		6
+#define ASN1_OP_I2D_POST	7
+
+/* Macro to implement a primitive type */
+#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+				ASN1_ITEM_start(itname) \
+					ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+				ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+#define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+				ASN1_ITEM_start(itname) \
+					ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+				ASN1_ITEM_end(itname)
+
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */
+
+#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
+
+#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
+	static const ASN1_COMPAT_FUNCS sname##_ff = { \
+		(ASN1_new_func *)sname##_new, \
+		(ASN1_free_func *)sname##_free, \
+		(ASN1_d2i_func *)d2i_##sname, \
+		(ASN1_i2d_func *)i2d_##sname, \
+	}; \
+	ASN1_ITEM_start(sname) \
+		ASN1_ITYPE_COMPAT, \
+		tag, \
+		NULL, \
+		0, \
+		&sname##_ff, \
+		0, \
+		#sname \
+	ASN1_ITEM_end(sname)
+
+#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+	ASN1_ITEM_start(sname) \
+		ASN1_ITYPE_EXTERN, \
+		tag, \
+		NULL, \
+		0, \
+		&fptrs, \
+		0, \
+		#sname \
+	ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+	stname *fname##_new(void) \
+	{ \
+		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+	} \
+	void fname##_free(stname *a) \
+	{ \
+		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+	}
+
+#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+	{ \
+		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+	} \
+	int i2d_##fname(stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+	} 
+
+#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
+	int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
+	} 
+
+/* This includes evil casts to remove const: they will go away when full
+ * ASN1 constification is done.
+ */
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+	{ \
+		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+	} \
+	int i2d_##fname(const stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+	} 
+
+#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+	stname * stname##_dup(stname *x) \
+        { \
+        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+        }
+
+#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+
+DECLARE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
+
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/bio.h b/dep/include/openssl/bio.h
new file mode 100644
index 000000000..2c9e8a7c8
--- /dev/null
+++ b/dep/include/openssl/bio.h
@@ -0,0 +1,775 @@
+/* crypto/bio/bio.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BIO_H
+#define HEADER_BIO_H
+
+#include 
+
+#ifndef OPENSSL_NO_FP_API
+# include 
+#endif
+#include 
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These are the 'types' of BIOs */
+#define BIO_TYPE_NONE		0
+#define BIO_TYPE_MEM		(1|0x0400)
+#define BIO_TYPE_FILE		(2|0x0400)
+
+#define BIO_TYPE_FD		(4|0x0400|0x0100)
+#define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
+#define BIO_TYPE_NULL		(6|0x0400)
+#define BIO_TYPE_SSL		(7|0x0200)
+#define BIO_TYPE_MD		(8|0x0200)		/* passive filter */
+#define BIO_TYPE_BUFFER		(9|0x0200)		/* filter */
+#define BIO_TYPE_CIPHER		(10|0x0200)		/* filter */
+#define BIO_TYPE_BASE64		(11|0x0200)		/* filter */
+#define BIO_TYPE_CONNECT	(12|0x0400|0x0100)	/* socket - connect */
+#define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)	/* socket for accept */
+#define BIO_TYPE_PROXY_CLIENT	(14|0x0200)		/* client proxy BIO */
+#define BIO_TYPE_PROXY_SERVER	(15|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NBIO_TEST	(16|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NULL_FILTER	(17|0x0200)
+#define BIO_TYPE_BER		(18|0x0200)		/* BER -> bin filter */
+#define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
+#define BIO_TYPE_LINEBUFFER	(20|0x0200)		/* filter */
+#define BIO_TYPE_DGRAM		(21|0x0400|0x0100)
+
+#define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
+#define BIO_TYPE_FILTER		0x0200
+#define BIO_TYPE_SOURCE_SINK	0x0400
+
+/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
+#define BIO_NOCLOSE		0x00
+#define BIO_CLOSE		0x01
+
+/* These are used in the following macros and are passed to
+ * BIO_ctrl() */
+#define BIO_CTRL_RESET		1  /* opt - rewind/zero etc */
+#define BIO_CTRL_EOF		2  /* opt - are we at the eof */
+#define BIO_CTRL_INFO		3  /* opt - extra tit-bits */
+#define BIO_CTRL_SET		4  /* man - set the 'IO' type */
+#define BIO_CTRL_GET		5  /* man - get the 'IO' type */
+#define BIO_CTRL_PUSH		6  /* opt - internal, used to signify change */
+#define BIO_CTRL_POP		7  /* opt - internal, used to signify change */
+#define BIO_CTRL_GET_CLOSE	8  /* man - set the 'close' on free */
+#define BIO_CTRL_SET_CLOSE	9  /* man - set the 'close' on free */
+#define BIO_CTRL_PENDING	10  /* opt - is their more data buffered */
+#define BIO_CTRL_FLUSH		11  /* opt - 'flush' buffered output */
+#define BIO_CTRL_DUP		12  /* man - extra stuff for 'duped' BIO */
+#define BIO_CTRL_WPENDING	13  /* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+#define BIO_CTRL_SET_CALLBACK	14  /* opt - set callback function */
+#define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */
+
+#define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */
+
+/* dgram BIO stuff */
+#define BIO_CTRL_DGRAM_CONNECT       31  /* BIO dgram special */
+#define BIO_CTRL_DGRAM_SET_CONNECTED 32  /* allow for an externally
+										  * connected socket to be
+										  * passed in */ 
+#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */
+#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */
+#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */
+#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */
+
+#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */
+#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */
+					
+/* #ifdef IP_MTU_DISCOVER */
+#define BIO_CTRL_DGRAM_MTU_DISCOVER       39 /* set DF bit on egress packets */
+/* #endif */
+
+#define BIO_CTRL_DGRAM_QUERY_MTU          40 /* as kernel for current MTU */
+#define BIO_CTRL_DGRAM_GET_MTU            41 /* get cached value for MTU */
+#define BIO_CTRL_DGRAM_SET_MTU            42 /* set cached value for
+											  * MTU. want to use this
+                                              * if asking the kernel
+                                              * fails */
+
+#define BIO_CTRL_DGRAM_MTU_EXCEEDED       43 /* check whether the MTU
+											  * was exceed in the
+											  * previous write
+											  * operation */
+
+#define BIO_CTRL_DGRAM_SET_PEER           44 /* Destination for the data */
+
+
+/* modifiers */
+#define BIO_FP_READ		0x02
+#define BIO_FP_WRITE		0x04
+#define BIO_FP_APPEND		0x08
+#define BIO_FP_TEXT		0x10
+
+#define BIO_FLAGS_READ		0x01
+#define BIO_FLAGS_WRITE		0x02
+#define BIO_FLAGS_IO_SPECIAL	0x04
+#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+#define BIO_FLAGS_SHOULD_RETRY	0x08
+#ifndef	BIO_FLAGS_UPLINK
+/* "UPLINK" flag denotes file descriptors provided by application.
+   It defaults to 0, as most platforms don't require UPLINK interface. */
+#define	BIO_FLAGS_UPLINK	0
+#endif
+
+/* Used in BIO_gethostbyname() */
+#define BIO_GHBN_CTRL_HITS		1
+#define BIO_GHBN_CTRL_MISSES		2
+#define BIO_GHBN_CTRL_CACHE_SIZE	3
+#define BIO_GHBN_CTRL_GET_ENTRY		4
+#define BIO_GHBN_CTRL_FLUSH		5
+
+/* Mostly used in the SSL BIO */
+/* Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP	0x40
+ */
+
+#define BIO_FLAGS_BASE64_NO_NL	0x100
+
+/* This is used with memory BIOs: it means we shouldn't free up or change the
+ * data in any way.
+ */
+#define BIO_FLAGS_MEM_RDONLY	0x200
+
+typedef struct bio_st BIO;
+
+void BIO_set_flags(BIO *b, int flags);
+int  BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
+#define BIO_set_retry_special(b) \
+		BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_read(b) \
+		BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_write(b) \
+		BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+#define BIO_clear_retry_flags(b) \
+		BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_get_retry_flags(b) \
+		BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+#define BIO_should_read(a)		BIO_test_flags(a, BIO_FLAGS_READ)
+#define BIO_should_write(a)		BIO_test_flags(a, BIO_FLAGS_WRITE)
+#define BIO_should_io_special(a)	BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+#define BIO_retry_type(a)		BIO_test_flags(a, BIO_FLAGS_RWS)
+#define BIO_should_retry(a)		BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
+
+/* The next three are used in conjunction with the
+ * BIO_should_io_special() condition.  After this returns true,
+ * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 
+ * stack and return the 'reason' for the special and the offending BIO.
+ * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
+/* Returned from the SSL bio when the certificate retrieval code had an error */
+#define BIO_RR_SSL_X509_LOOKUP		0x01
+/* Returned from the connect BIO when a connect would have blocked */
+#define BIO_RR_CONNECT			0x02
+/* Returned from the accept BIO when an accept would have blocked */
+#define BIO_RR_ACCEPT			0x03
+
+/* These are passed by the BIO callback */
+#define BIO_CB_FREE	0x01
+#define BIO_CB_READ	0x02
+#define BIO_CB_WRITE	0x03
+#define BIO_CB_PUTS	0x04
+#define BIO_CB_GETS	0x05
+#define BIO_CB_CTRL	0x06
+
+/* The callback is called before and after the underling operation,
+ * The BIO_CB_RETURN flag indicates if it is after the call */
+#define BIO_CB_RETURN	0x80
+#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
+#define BIO_cb_pre(a)	(!((a)&BIO_CB_RETURN))
+#define BIO_cb_post(a)	((a)&BIO_CB_RETURN)
+
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long);
+void BIO_set_callback(BIO *b, 
+	long (*callback)(struct bio_st *,int,const char *,int, long,long));
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
+
+const char * BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
+
+typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
+
+#ifndef OPENSSL_SYS_WIN16
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (*bwrite)(BIO *, const char *, int);
+	int (*bread)(BIO *, char *, int);
+	int (*bputs)(BIO *, const char *);
+	int (*bgets)(BIO *, char *, int);
+	long (*ctrl)(BIO *, int, long, void *);
+	int (*create)(BIO *);
+	int (*destroy)(BIO *);
+        long (*callback_ctrl)(BIO *, int, bio_info_cb *);
+	} BIO_METHOD;
+#else
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (_far *bwrite)();
+	int (_far *bread)();
+	int (_far *bputs)();
+	int (_far *bgets)();
+	long (_far *ctrl)();
+	int (_far *create)();
+	int (_far *destroy)();
+	long (_far *callback_ctrl)();
+	} BIO_METHOD;
+#endif
+
+struct bio_st
+	{
+	BIO_METHOD *method;
+	/* bio, mode, argp, argi, argl, ret */
+	long (*callback)(struct bio_st *,int,const char *,int, long,long);
+	char *cb_arg; /* first argument for the callback */
+
+	int init;
+	int shutdown;
+	int flags;	/* extra storage */
+	int retry_reason;
+	int num;
+	void *ptr;
+	struct bio_st *next_bio;	/* used by filter BIOs */
+	struct bio_st *prev_bio;	/* used by filter BIOs */
+	int references;
+	unsigned long num_read;
+	unsigned long num_write;
+
+	CRYPTO_EX_DATA ex_data;
+	};
+
+DECLARE_STACK_OF(BIO)
+
+typedef struct bio_f_buffer_ctx_struct
+	{
+	/* BIO *bio; */ /* this is now in the BIO struct */
+	int ibuf_size;	/* how big is the input buffer */
+	int obuf_size;	/* how big is the output buffer */
+
+	char *ibuf;		/* the char array */
+	int ibuf_len;		/* how many bytes are in it */
+	int ibuf_off;		/* write/read offset */
+
+	char *obuf;		/* the char array */
+	int obuf_len;		/* how many bytes are in it */
+	int obuf_off;		/* write/read offset */
+	} BIO_F_BUFFER_CTX;
+
+/* connect BIO stuff */
+#define BIO_CONN_S_BEFORE		1
+#define BIO_CONN_S_GET_IP		2
+#define BIO_CONN_S_GET_PORT		3
+#define BIO_CONN_S_CREATE_SOCKET	4
+#define BIO_CONN_S_CONNECT		5
+#define BIO_CONN_S_OK			6
+#define BIO_CONN_S_BLOCKED_CONNECT	7
+#define BIO_CONN_S_NBIO			8
+/*#define BIO_CONN_get_param_hostname	BIO_ctrl */
+
+#define BIO_C_SET_CONNECT			100
+#define BIO_C_DO_STATE_MACHINE			101
+#define BIO_C_SET_NBIO				102
+#define BIO_C_SET_PROXY_PARAM			103
+#define BIO_C_SET_FD				104
+#define BIO_C_GET_FD				105
+#define BIO_C_SET_FILE_PTR			106
+#define BIO_C_GET_FILE_PTR			107
+#define BIO_C_SET_FILENAME			108
+#define BIO_C_SET_SSL				109
+#define BIO_C_GET_SSL				110
+#define BIO_C_SET_MD				111
+#define BIO_C_GET_MD				112
+#define BIO_C_GET_CIPHER_STATUS			113
+#define BIO_C_SET_BUF_MEM			114
+#define BIO_C_GET_BUF_MEM_PTR			115
+#define BIO_C_GET_BUFF_NUM_LINES		116
+#define BIO_C_SET_BUFF_SIZE			117
+#define BIO_C_SET_ACCEPT			118
+#define BIO_C_SSL_MODE				119
+#define BIO_C_GET_MD_CTX			120
+#define BIO_C_GET_PROXY_PARAM			121
+#define BIO_C_SET_BUFF_READ_DATA		122 /* data to read first */
+#define BIO_C_GET_CONNECT			123
+#define BIO_C_GET_ACCEPT			124
+#define BIO_C_SET_SSL_RENEGOTIATE_BYTES		125
+#define BIO_C_GET_SSL_NUM_RENEGOTIATES		126
+#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT	127
+#define BIO_C_FILE_SEEK				128
+#define BIO_C_GET_CIPHER_CTX			129
+#define BIO_C_SET_BUF_MEM_EOF_RETURN		130/*return end of input value*/
+#define BIO_C_SET_BIND_MODE			131
+#define BIO_C_GET_BIND_MODE			132
+#define BIO_C_FILE_TELL				133
+#define BIO_C_GET_SOCKS				134
+#define BIO_C_SET_SOCKS				135
+
+#define BIO_C_SET_WRITE_BUF_SIZE		136/* for BIO_s_bio */
+#define BIO_C_GET_WRITE_BUF_SIZE		137
+#define BIO_C_MAKE_BIO_PAIR			138
+#define BIO_C_DESTROY_BIO_PAIR			139
+#define BIO_C_GET_WRITE_GUARANTEE		140
+#define BIO_C_GET_READ_REQUEST			141
+#define BIO_C_SHUTDOWN_WR			142
+#define BIO_C_NREAD0				143
+#define BIO_C_NREAD				144
+#define BIO_C_NWRITE0				145
+#define BIO_C_NWRITE				146
+#define BIO_C_RESET_READ_REQUEST		147
+#define BIO_C_SET_MD_CTX			148
+
+
+#define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
+#define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+#define BIO_set_conn_ip(b,ip)	  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+#define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+#define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+#define BIO_get_conn_ip(b) 		 BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
+#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3)
+
+
+#define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept_socket() */
+#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+#define BIO_get_accept_port(b)	BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL)
+#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+#define BIO_BIND_NORMAL			0
+#define BIO_BIND_REUSEADDR_IF_UNUSED	1
+#define BIO_BIND_REUSEADDR		2
+#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+#define BIO_do_connect(b)	BIO_do_handshake(b)
+#define BIO_do_accept(b)	BIO_do_handshake(b)
+#define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+#define BIO_set_url(b,url)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+#define BIO_set_proxies(b,p)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
+#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+#define BIO_get_url(b,url)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+#define BIO_get_no_connect_return(b)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+#define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+#define BIO_get_fd(b,c)		BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+#define BIO_set_fp(b,fp,c)	BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+#define BIO_get_fp(b,fpp)	BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+#define BIO_seek(b,ofs)	(int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+#define BIO_tell(b)	(int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/* name is cast to lose const, but might be better to route through a function
+   so we can do it safely */
+#ifdef CONST_STRICT
+/* If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b,const char *name);
+#else
+#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ,(char *)name)
+#endif
+#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_WRITE,name)
+#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_APPEND,name)
+#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/* WARNING WARNING, this ups the reference count on the read bio of the
+ * SSL structure.  This is because the ssl read BIO is now pointed to by
+ * the next_bio field in the bio.  So when you free the BIO, make sure
+ * you are doing a BIO_free_all() to catch the underlying BIO. */
+#define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+#define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+#define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+#define BIO_set_ssl_renegotiate_bytes(b,num) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+#define BIO_get_num_renegotiates(b) \
+	BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
+#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)	BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+#define BIO_get_mem_data(b,pp)	BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+#define BIO_set_mem_buf(b,bm,c)	BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+#define BIO_get_mem_ptr(b,pp)	BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+#define BIO_set_mem_eof_return(b,v) \
+				BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+#define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+#define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+#define BIO_dup_state(b,ret)	BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+#define BIO_reset(b)		(int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+#define BIO_eof(b)		(int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+#define BIO_set_close(b,c)	(int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+#define BIO_get_close(b)	(int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+#define BIO_pending(b)		(int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+#define BIO_wpending(b)		(int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+#define BIO_flush(b)		(int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+						   cbp)
+#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+#define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+#define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+#define BIO_ctrl_dgram_connect(b,peer)  \
+                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
+#define BIO_ctrl_set_connected(b, state, peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
+#define BIO_dgram_recv_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+#define BIO_dgram_send_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+#define BIO_dgram_set_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio,int idx,void *data);
+void *BIO_get_ex_data(BIO *bio,int idx);
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+unsigned long BIO_number_read(BIO *bio);
+unsigned long BIO_number_written(BIO *bio);
+
+# ifndef OPENSSL_NO_FP_API
+#  if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL)
+BIO_METHOD *BIO_s_file_internal(void);
+BIO *BIO_new_file_internal(char *filename, char *mode);
+BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
+#    define BIO_s_file	BIO_s_file_internal
+#    define BIO_new_file	BIO_new_file_internal
+#    define BIO_new_fp	BIO_new_fp_internal
+#  else /* FP_API */
+BIO_METHOD *BIO_s_file(void );
+BIO *BIO_new_file(const char *filename, const char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+#    define BIO_s_file_internal		BIO_s_file
+#    define BIO_new_file_internal	BIO_new_file
+#    define BIO_new_fp_internal		BIO_s_file
+#  endif /* FP_API */
+# endif
+BIO *	BIO_new(BIO_METHOD *type);
+int	BIO_set(BIO *a,BIO_METHOD *type);
+int	BIO_free(BIO *a);
+void	BIO_vfree(BIO *a);
+int	BIO_read(BIO *b, void *data, int len);
+int	BIO_gets(BIO *bp,char *buf, int size);
+int	BIO_write(BIO *b, const void *data, int len);
+int	BIO_puts(BIO *bp,const char *buf);
+int	BIO_indent(BIO *b,int indent,int max);
+long	BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long));
+char *	BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
+long	BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
+BIO *	BIO_push(BIO *b,BIO *append);
+BIO *	BIO_pop(BIO *b);
+void	BIO_free_all(BIO *a);
+BIO *	BIO_find_type(BIO *b,int bio_type);
+BIO *	BIO_next(BIO *b);
+BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
+int	BIO_get_retry_reason(BIO *bio);
+BIO *	BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+#ifndef OPENSSL_SYS_WIN16
+long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+#else
+long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+#endif
+
+BIO_METHOD *BIO_s_mem(void);
+BIO *BIO_new_mem_buf(void *buf, int len);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+#ifndef OPENSSL_SYS_OS2
+BIO_METHOD *BIO_s_log(void);
+#endif
+BIO_METHOD *BIO_s_bio(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+#ifdef OPENSSL_SYS_VMS
+BIO_METHOD *BIO_f_linebuffer(void);
+#endif
+BIO_METHOD *BIO_f_nbio_test(void);
+#ifndef OPENSSL_NO_DGRAM
+BIO_METHOD *BIO_s_datagram(void);
+#endif
+
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_dgram_non_fatal_error(int error);
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
+		void *u, const char *s, int len);
+int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
+		       void *u, const char *s, int len, int indent);
+int BIO_dump(BIO *b,const char *bytes,int len);
+int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent);
+#ifndef OPENSSL_NO_FP_API
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+#endif
+struct hostent *BIO_gethostbyname(const char *name);
+/* We might want a thread-safe interface too:
+ * struct hostent *BIO_gethostbyname_r(const char *name,
+ *     struct hostent *result, void *buffer, size_t buflen);
+ * or something similar (caller allocates a struct hostent,
+ * pointed to by "result", and additional buffer space for the various
+ * substructures; if the buffer does not suffice, NULL is returned
+ * and an appropriate error code is set).
+ */
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd,int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port,int mode);
+int BIO_accept(int sock,char **ip_port);
+int BIO_sock_init(void );
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock,int turn_on);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_dgram(int fd, int close_flag);
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(char *host_port);
+BIO *BIO_new_accept(char *host_port);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+	BIO **bio2, size_t writebuf2);
+/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
+ * Size 0 uses default value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/
+
+#ifdef __GNUC__
+#  define __bio_h__attr__ __attribute__
+#else
+#  define __bio_h__attr__(x)
+#endif
+int BIO_printf(BIO *bio, const char *format, ...)
+	__bio_h__attr__((__format__(__printf__,2,3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+	__bio_h__attr__((__format__(__printf__,2,0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+	__bio_h__attr__((__format__(__printf__,3,4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+	__bio_h__attr__((__format__(__printf__,3,0)));
+#undef __bio_h__attr__
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BIO_strings(void);
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+#define BIO_F_ACPT_STATE				 100
+#define BIO_F_BIO_ACCEPT				 101
+#define BIO_F_BIO_BER_GET_HEADER			 102
+#define BIO_F_BIO_CALLBACK_CTRL				 131
+#define BIO_F_BIO_CTRL					 103
+#define BIO_F_BIO_GETHOSTBYNAME				 120
+#define BIO_F_BIO_GETS					 104
+#define BIO_F_BIO_GET_ACCEPT_SOCKET			 105
+#define BIO_F_BIO_GET_HOST_IP				 106
+#define BIO_F_BIO_GET_PORT				 107
+#define BIO_F_BIO_MAKE_PAIR				 121
+#define BIO_F_BIO_NEW					 108
+#define BIO_F_BIO_NEW_FILE				 109
+#define BIO_F_BIO_NEW_MEM_BUF				 126
+#define BIO_F_BIO_NREAD					 123
+#define BIO_F_BIO_NREAD0				 124
+#define BIO_F_BIO_NWRITE				 125
+#define BIO_F_BIO_NWRITE0				 122
+#define BIO_F_BIO_PUTS					 110
+#define BIO_F_BIO_READ					 111
+#define BIO_F_BIO_SOCK_INIT				 112
+#define BIO_F_BIO_WRITE					 113
+#define BIO_F_BUFFER_CTRL				 114
+#define BIO_F_CONN_CTRL					 127
+#define BIO_F_CONN_STATE				 115
+#define BIO_F_FILE_CTRL					 116
+#define BIO_F_FILE_READ					 130
+#define BIO_F_LINEBUFFER_CTRL				 129
+#define BIO_F_MEM_READ					 128
+#define BIO_F_MEM_WRITE					 117
+#define BIO_F_SSL_NEW					 118
+#define BIO_F_WSASTARTUP				 119
+
+/* Reason codes. */
+#define BIO_R_ACCEPT_ERROR				 100
+#define BIO_R_BAD_FOPEN_MODE				 101
+#define BIO_R_BAD_HOSTNAME_LOOKUP			 102
+#define BIO_R_BROKEN_PIPE				 124
+#define BIO_R_CONNECT_ERROR				 103
+#define BIO_R_EOF_ON_MEMORY_BIO				 127
+#define BIO_R_ERROR_SETTING_NBIO			 104
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET	 105
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET	 106
+#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET		 107
+#define BIO_R_INVALID_ARGUMENT				 125
+#define BIO_R_INVALID_IP_ADDRESS			 108
+#define BIO_R_IN_USE					 123
+#define BIO_R_KEEPALIVE					 109
+#define BIO_R_NBIO_CONNECT_ERROR			 110
+#define BIO_R_NO_ACCEPT_PORT_SPECIFIED			 111
+#define BIO_R_NO_HOSTNAME_SPECIFIED			 112
+#define BIO_R_NO_PORT_DEFINED				 113
+#define BIO_R_NO_PORT_SPECIFIED				 114
+#define BIO_R_NO_SUCH_FILE				 128
+#define BIO_R_NULL_PARAMETER				 115
+#define BIO_R_TAG_MISMATCH				 116
+#define BIO_R_UNABLE_TO_BIND_SOCKET			 117
+#define BIO_R_UNABLE_TO_CREATE_SOCKET			 118
+#define BIO_R_UNABLE_TO_LISTEN_SOCKET			 119
+#define BIO_R_UNINITIALIZED				 120
+#define BIO_R_UNSUPPORTED_METHOD			 121
+#define BIO_R_WRITE_TO_READ_ONLY_BIO			 126
+#define BIO_R_WSASTARTUP				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/blowfish.h b/dep/include/openssl/blowfish.h
new file mode 100644
index 000000000..cd49e85ab
--- /dev/null
+++ b/dep/include/openssl/blowfish.h
@@ -0,0 +1,127 @@
+/* crypto/bf/blowfish.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BLOWFISH_H
+#define HEADER_BLOWFISH_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_BF
+#error BF is disabled.
+#endif
+
+#define BF_ENCRYPT	1
+#define BF_DECRYPT	0
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! BF_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define BF_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define BF_LONG unsigned long
+#define BF_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					
+ */
+#else
+#define BF_LONG unsigned int
+#endif
+
+#define BF_ROUNDS	16
+#define BF_BLOCK	8
+
+typedef struct bf_key_st
+	{
+	BF_LONG P[BF_ROUNDS+2];
+	BF_LONG S[4*256];
+	} BF_KEY;
+
+ 
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data,const BF_KEY *key);
+void BF_decrypt(BF_LONG *data,const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/bn.h b/dep/include/openssl/bn.h
new file mode 100644
index 000000000..95c5d643c
--- /dev/null
+++ b/dep/include/openssl/bn.h
@@ -0,0 +1,827 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#include 
+#ifndef OPENSSL_NO_FP_API
+#include  /* FILE */
+#endif
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These preprocessor symbols control various aspects of the bignum headers and
+ * library code. They're not defined by any "normal" configuration, as they are
+ * intended for development and testing purposes. NB: defining all three can be
+ * useful for debugging application code as well as openssl itself.
+ *
+ * BN_DEBUG - turn on various debugging alterations to the bignum code
+ * BN_DEBUG_RAND - uses random poisoning of unused words to trip up
+ * mismanagement of bignum internals. You must also define BN_DEBUG.
+ */
+/* #define BN_DEBUG */
+/* #define BN_DEBUG_RAND */
+
+#define BN_MUL_COMBA
+#define BN_SQR_COMBA
+#define BN_RECURSION
+
+/* This next option uses the C libraries (2 word)/(1 word) function.
+ * If it is not defined, I use my C version (which is slower).
+ * The reason for this flag is that when the particular C compiler
+ * library routine is used, and the library is linked with a different
+ * compiler, the library is missing.  This mostly happens when the
+ * library is built with gcc and then linked using normal cc.  This would
+ * be a common occurrence because gcc normally produces code that is
+ * 2 times faster than system compilers for the big number stuff.
+ * For machines with only one compiler (or shared libraries), this should
+ * be on.  Again this in only really a problem on machines
+ * using "long long's", are 32bit, and are not using my assembler code. */
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+    defined(OPENSSL_SYS_WIN32) || defined(linux)
+# ifndef BN_DIV2W
+#  define BN_DIV2W
+# endif
+#endif
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG	unsigned long long
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK		(0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2	(0xffffffffffffffffL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000L)
+#define BN_MASK2h1	(0xffffffff80000000L)
+#define BN_TBIT		(0x8000000000000000L)
+#define BN_DEC_CONV	(10000000000000000000UL)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%019lu"
+#define BN_DEC_NUM	19
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevant
+ * assembler code :-).  Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG	unsigned long long
+#define BN_LONG		long long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK2	(0xffffffffffffffffLL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000LL)
+#define BN_MASK2h1	(0xffffffff80000000LL)
+#define BN_TBIT		(0x8000000000000000LL)
+#define BN_DEC_CONV	(10000000000000000000ULL)
+#define BN_DEC_FMT1	"%llu"
+#define BN_DEC_FMT2	"%019llu"
+#define BN_DEC_NUM	19
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#ifdef BN_LLONG
+# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
+#  define BN_ULLONG	unsigned __int64
+# else
+#  define BN_ULLONG	unsigned long long
+# endif
+#endif
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		64
+#define BN_BYTES	4
+#define BN_BITS2	32
+#define BN_BITS4	16
+#ifdef OPENSSL_SYS_WIN32
+/* VC++ doesn't like the LL suffix */
+#define BN_MASK		(0xffffffffffffffffL)
+#else
+#define BN_MASK		(0xffffffffffffffffLL)
+#endif
+#define BN_MASK2	(0xffffffffL)
+#define BN_MASK2l	(0xffff)
+#define BN_MASK2h1	(0xffff8000L)
+#define BN_MASK2h	(0xffff0000L)
+#define BN_TBIT		(0x80000000L)
+#define BN_DEC_CONV	(1000000000L)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%09lu"
+#define BN_DEC_NUM	9
+#endif
+
+#ifdef SIXTEEN_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG	unsigned long
+#define BN_ULONG	unsigned short
+#define BN_LONG		short
+#define BN_BITS		32
+#define BN_BYTES	2
+#define BN_BITS2	16
+#define BN_BITS4	8
+#define BN_MASK		(0xffffffff)
+#define BN_MASK2	(0xffff)
+#define BN_MASK2l	(0xff)
+#define BN_MASK2h1	(0xff80)
+#define BN_MASK2h	(0xff00)
+#define BN_TBIT		(0x8000)
+#define BN_DEC_CONV	(100000)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%05u"
+#define BN_DEC_NUM	5
+#endif
+
+#ifdef EIGHT_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG	unsigned short
+#define BN_ULONG	unsigned char
+#define BN_LONG		char
+#define BN_BITS		16
+#define BN_BYTES	1
+#define BN_BITS2	8
+#define BN_BITS4	4
+#define BN_MASK		(0xffff)
+#define BN_MASK2	(0xff)
+#define BN_MASK2l	(0xf)
+#define BN_MASK2h1	(0xf8)
+#define BN_MASK2h	(0xf0)
+#define BN_TBIT		(0x80)
+#define BN_DEC_CONV	(100)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%02u"
+#define BN_DEC_NUM	2
+#endif
+
+#define BN_DEFAULT_BITS	1280
+
+#define BN_FLG_MALLOCED		0x01
+#define BN_FLG_STATIC_DATA	0x02
+#define BN_FLG_EXP_CONSTTIME	0x04 /* avoid leaking exponent information through timings
+                            	      * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
+#ifndef OPENSSL_NO_DEPRECATED
+#define BN_FLG_FREE		0x8000	/* used for debuging */
+#endif
+#define BN_set_flags(b,n)	((b)->flags|=(n))
+#define BN_get_flags(b,n)	((b)->flags&(n))
+
+/* get a clone of a BIGNUM with changed flags, for *temporary* use only
+ * (the two BIGNUMs cannot not be used in parallel!) */
+#define BN_with_flags(dest,b,n)  ((dest)->d=(b)->d, \
+                                  (dest)->top=(b)->top, \
+                                  (dest)->dmax=(b)->dmax, \
+                                  (dest)->neg=(b)->neg, \
+                                  (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
+                                                 |  ((b)->flags & ~BN_FLG_MALLOCED) \
+                                                 |  BN_FLG_STATIC_DATA \
+                                                 |  (n)))
+
+/* Already declared in ossl_typ.h */
+#if 0
+typedef struct bignum_st BIGNUM;
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+#endif
+
+struct bignum_st
+	{
+	BN_ULONG *d;	/* Pointer to an array of 'BN_BITS2' bit chunks. */
+	int top;	/* Index of last used d +1. */
+	/* The next are internal book keeping for bn_expand. */
+	int dmax;	/* Size of the d array. */
+	int neg;	/* one if the number is negative */
+	int flags;
+	};
+
+/* Used for montgomery multiplication */
+struct bn_mont_ctx_st
+	{
+	int ri;        /* number of bits in R */
+	BIGNUM RR;     /* used to convert to montgomery form */
+	BIGNUM N;      /* The modulus */
+	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
+	                * (Ni is only stored for bignum algorithm) */
+	BN_ULONG n0;   /* least significant word of Ni */
+	int flags;
+	};
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+struct bn_recp_ctx_st
+	{
+	BIGNUM N;	/* the divisor */
+	BIGNUM Nr;	/* the reciprocal */
+	int num_bits;
+	int shift;
+	int flags;
+	};
+
+/* Used for slow "generation" functions. */
+struct bn_gencb_st
+	{
+	unsigned int ver;	/* To handle binary (in)compatibility */
+	void *arg;		/* callback-specific data */
+	union
+		{
+		/* if(ver==1) - handles old style callbacks */
+		void (*cb_1)(int, int, void *);
+		/* if(ver==2) - new callback style */
+		int (*cb_2)(int, int, BN_GENCB *);
+		} cb;
+	};
+/* Wrapper function to make using BN_GENCB easier,  */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+/* Macro to populate a BN_GENCB structure with an "old"-style callback */
+#define BN_GENCB_set_old(gencb, callback, cb_arg) { \
+		BN_GENCB *tmp_gencb = (gencb); \
+		tmp_gencb->ver = 1; \
+		tmp_gencb->arg = (cb_arg); \
+		tmp_gencb->cb.cb_1 = (callback); }
+/* Macro to populate a BN_GENCB structure with a "new"-style callback */
+#define BN_GENCB_set(gencb, callback, cb_arg) { \
+		BN_GENCB *tmp_gencb = (gencb); \
+		tmp_gencb->ver = 2; \
+		tmp_gencb->arg = (cb_arg); \
+		tmp_gencb->cb.cb_2 = (callback); }
+
+#define BN_prime_checks 0 /* default: select number of iterations
+			     based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                                (b) >=  850 ?  3 : \
+                                (b) >=  650 ?  4 : \
+                                (b) >=  550 ?  5 : \
+                                (b) >=  450 ?  6 : \
+                                (b) >=  400 ?  7 : \
+                                (b) >=  350 ?  8 : \
+                                (b) >=  300 ?  9 : \
+                                (b) >=  250 ? 12 : \
+                                (b) >=  200 ? 15 : \
+                                (b) >=  150 ? 18 : \
+                                /* b >= 100 */ 27)
+
+#define BN_num_bytes(a)	((BN_num_bits(a)+7)/8)
+
+/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
+#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
+				(((w) == 0) && ((a)->top == 0)))
+#define BN_is_zero(a)       ((a)->top == 0)
+#define BN_is_one(a)        (BN_abs_is_word((a),1) && !(a)->neg)
+#define BN_is_word(a,w)     (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
+#define BN_is_odd(a)	    (((a)->top > 0) && ((a)->d[0] & 1))
+
+#define BN_one(a)	(BN_set_word((a),1))
+#define BN_zero_ex(a) \
+	do { \
+		BIGNUM *_tmp_bn = (a); \
+		_tmp_bn->top = 0; \
+		_tmp_bn->neg = 0; \
+	} while(0)
+#ifdef OPENSSL_NO_DEPRECATED
+#define BN_zero(a)	BN_zero_ex(a)
+#else
+#define BN_zero(a)	(BN_set_word((a),0))
+#endif
+
+const BIGNUM *BN_value_one(void);
+char *	BN_options(void);
+BN_CTX *BN_CTX_new(void);
+#ifndef OPENSSL_NO_DEPRECATED
+void	BN_CTX_init(BN_CTX *c);
+#endif
+void	BN_CTX_free(BN_CTX *c);
+void	BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void	BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int	BN_rand_range(BIGNUM *rnd, BIGNUM *range);
+int	BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
+int	BN_num_bits(const BIGNUM *a);
+int	BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void	BN_init(BIGNUM *);
+void	BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+void	BN_swap(BIGNUM *a, BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2bin(const BIGNUM *a, unsigned char *to);
+BIGNUM *BN_mpi2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int	BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int	BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
+/** BN_set_negative sets sign of a BIGNUM
+ * \param  b  pointer to the BIGNUM object
+ * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise 
+ */
+void	BN_set_negative(BIGNUM *b, int n);
+/** BN_is_negative returns 1 if the BIGNUM is negative
+ * \param  a  pointer to the BIGNUM object
+ * \return 1 if a < 0 and 0 otherwise
+ */
+#define BN_is_negative(a) ((a)->neg != 0)
+
+int	BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+	BN_CTX *ctx);
+#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int	BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int	BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int	BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int	BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int	BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int	BN_mul_word(BIGNUM *a, BN_ULONG w);
+int	BN_add_word(BIGNUM *a, BN_ULONG w);
+int	BN_sub_word(BIGNUM *a, BN_ULONG w);
+int	BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int	BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void	BN_free(BIGNUM *a);
+int	BN_is_bit_set(const BIGNUM *a, int n);
+int	BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int	BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
+
+int	BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m,BN_CTX *ctx);
+int	BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
+int	BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int	BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+	const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
+	BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int	BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m,BN_CTX *ctx);
+
+int	BN_mask_bits(BIGNUM *a,int n);
+#ifndef OPENSSL_NO_FP_API
+int	BN_print_fp(FILE *fp, const BIGNUM *a);
+#endif
+#ifdef HEADER_BIO_H
+int	BN_print(BIO *fp, const BIGNUM *a);
+#else
+int	BN_print(void *fp, const BIGNUM *a);
+#endif
+int	BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int	BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void	BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int	BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int	BN_set_bit(BIGNUM *a, int n);
+int	BN_clear_bit(BIGNUM *a, int n);
+char *	BN_bn2hex(const BIGNUM *a);
+char *	BN_bn2dec(const BIGNUM *a);
+int 	BN_hex2bn(BIGNUM **a, const char *str);
+int 	BN_dec2bn(BIGNUM **a, const char *str);
+int	BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
+int	BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+
+/* Deprecated versions */
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
+	const BIGNUM *add, const BIGNUM *rem,
+	void (*callback)(int,int,void *),void *cb_arg);
+int	BN_is_prime(const BIGNUM *p,int nchecks,
+	void (*callback)(int,int,void *),
+	BN_CTX *ctx,void *cb_arg);
+int	BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+	void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+	int do_trial_division);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* Newer versions */
+int	BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add,
+		const BIGNUM *rem, BN_GENCB *cb);
+int	BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
+int	BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
+		int do_trial_division, BN_GENCB *cb);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
+	BN_MONT_CTX *mont, BN_CTX *ctx);
+#define BN_to_montgomery(r,a,mont,ctx)	BN_mod_mul_montgomery(\
+	(r),(a),&((mont)->RR),(mont),(ctx))
+int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
+	BN_MONT_CTX *mont, BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+					const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+#define	BN_BLINDING_NO_UPDATE	0x00000001
+#define	BN_BLINDING_NO_RECREATE	0x00000002
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
+void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
+	BN_MONT_CTX *m_ctx);
+
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+#endif
+
+void	BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void	BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int	BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int	BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+	BN_RECP_CTX *recp,BN_CTX *ctx);
+int	BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx);
+int	BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+	BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* Functions for arithmetic over binary polynomials represented by BIGNUMs. 
+ *
+ * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
+ * ignored.
+ *
+ * Note that input arguments are not const so that their bit arrays can
+ * be expanded to the appropriate size if needed.
+ */
+
+int	BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/
+#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/
+int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r = (a * a) mod p */
+int	BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p,
+	BN_CTX *ctx); /* r = (1 / b) mod p */
+int	BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
+int	BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
+int	BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r = sqrt(a) mod p */
+int	BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r^2 + r = a mod p */
+#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
+/* Some functions allow for representation of the irreducible polynomials
+ * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]);
+	/* r = a mod p */
+int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[],
+	BN_CTX *ctx); /* r = (a * a) mod p */
+int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[],
+	BN_CTX *ctx); /* r = (1 / b) mod p */
+int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
+int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
+int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+	const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
+int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+	const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
+int	BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
+int	BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
+
+/* faster mod functions for the 'NIST primes' 
+ * 0 <= a < p^2 */
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+const BIGNUM *BN_get0_nist_prime_192(void);
+const BIGNUM *BN_get0_nist_prime_224(void);
+const BIGNUM *BN_get0_nist_prime_256(void);
+const BIGNUM *BN_get0_nist_prime_384(void);
+const BIGNUM *BN_get0_nist_prime_521(void);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
+#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
+#endif
+
+/* Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ *   bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ *     consistent. (ed: only if BN_DEBUG_RAND is defined)
+ *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+
+#ifdef BN_DEBUG
+
+/* We only need assert() when debugging */
+#include 
+
+#ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+#ifndef RAND_pseudo_bytes
+int RAND_pseudo_bytes(unsigned char *buf,int num);
+#define BN_DEBUG_TRIX
+#endif
+#define bn_pollute(a) \
+	do { \
+		const BIGNUM *_bnum1 = (a); \
+		if(_bnum1->top < _bnum1->dmax) { \
+			unsigned char _tmp_char; \
+			/* We cast away const without the compiler knowing, any \
+			 * *genuinely* constant variables that aren't mutable \
+			 * wouldn't be constructed with top!=dmax. */ \
+			BN_ULONG *_not_const; \
+			memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
+			RAND_pseudo_bytes(&_tmp_char, 1); \
+			memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
+				(_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
+		} \
+	} while(0)
+#ifdef BN_DEBUG_TRIX
+#undef RAND_pseudo_bytes
+#endif
+#else
+#define bn_pollute(a)
+#endif
+#define bn_check_top(a) \
+	do { \
+		const BIGNUM *_bnum2 = (a); \
+		if (_bnum2 != NULL) { \
+			assert((_bnum2->top == 0) || \
+				(_bnum2->d[_bnum2->top - 1] != 0)); \
+			bn_pollute(_bnum2); \
+		} \
+	} while(0)
+
+#define bn_fix_top(a)		bn_check_top(a)
+
+#else /* !BN_DEBUG */
+
+#define bn_pollute(a)
+#define bn_check_top(a)
+#define bn_fix_top(a)		bn_correct_top(a)
+
+#endif
+
+#define bn_correct_top(a) \
+        { \
+        BN_ULONG *ftl; \
+	if ((a)->top > 0) \
+		{ \
+		for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
+		if (*(ftl--)) break; \
+		} \
+	bn_pollute(a); \
+	}
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+
+/* Primes from RFC 2409 */
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);
+
+/* Primes from RFC 3526 */
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BN_strings(void);
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BNRAND					 127
+#define BN_F_BN_BLINDING_CONVERT_EX			 100
+#define BN_F_BN_BLINDING_CREATE_PARAM			 128
+#define BN_F_BN_BLINDING_INVERT_EX			 101
+#define BN_F_BN_BLINDING_NEW				 102
+#define BN_F_BN_BLINDING_UPDATE				 103
+#define BN_F_BN_BN2DEC					 104
+#define BN_F_BN_BN2HEX					 105
+#define BN_F_BN_CTX_GET					 116
+#define BN_F_BN_CTX_NEW					 106
+#define BN_F_BN_CTX_START				 129
+#define BN_F_BN_DIV					 107
+#define BN_F_BN_DIV_RECP				 130
+#define BN_F_BN_EXP					 123
+#define BN_F_BN_EXPAND2					 108
+#define BN_F_BN_EXPAND_INTERNAL				 120
+#define BN_F_BN_GF2M_MOD				 131
+#define BN_F_BN_GF2M_MOD_EXP				 132
+#define BN_F_BN_GF2M_MOD_MUL				 133
+#define BN_F_BN_GF2M_MOD_SOLVE_QUAD			 134
+#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR			 135
+#define BN_F_BN_GF2M_MOD_SQR				 136
+#define BN_F_BN_GF2M_MOD_SQRT				 137
+#define BN_F_BN_MOD_EXP2_MONT				 118
+#define BN_F_BN_MOD_EXP_MONT				 109
+#define BN_F_BN_MOD_EXP_MONT_CONSTTIME			 124
+#define BN_F_BN_MOD_EXP_MONT_WORD			 117
+#define BN_F_BN_MOD_EXP_RECP				 125
+#define BN_F_BN_MOD_EXP_SIMPLE				 126
+#define BN_F_BN_MOD_INVERSE				 110
+#define BN_F_BN_MOD_LSHIFT_QUICK			 119
+#define BN_F_BN_MOD_MUL_RECIPROCAL			 111
+#define BN_F_BN_MOD_SQRT				 121
+#define BN_F_BN_MPI2BN					 112
+#define BN_F_BN_NEW					 113
+#define BN_F_BN_RAND					 114
+#define BN_F_BN_RAND_RANGE				 122
+#define BN_F_BN_USUB					 115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3				 100
+#define BN_R_BAD_RECIPROCAL				 101
+#define BN_R_BIGNUM_TOO_LONG				 114
+#define BN_R_CALLED_WITH_EVEN_MODULUS			 102
+#define BN_R_DIV_BY_ZERO				 103
+#define BN_R_ENCODING_ERROR				 104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA		 105
+#define BN_R_INPUT_NOT_REDUCED				 110
+#define BN_R_INVALID_LENGTH				 106
+#define BN_R_INVALID_RANGE				 115
+#define BN_R_NOT_A_SQUARE				 111
+#define BN_R_NOT_INITIALIZED				 107
+#define BN_R_NO_INVERSE					 108
+#define BN_R_NO_SOLUTION				 116
+#define BN_R_P_IS_NOT_PRIME				 112
+#define BN_R_TOO_MANY_ITERATIONS			 113
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES		 109
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/buffer.h b/dep/include/openssl/buffer.h
new file mode 100644
index 000000000..1db960745
--- /dev/null
+++ b/dep/include/openssl/buffer.h
@@ -0,0 +1,118 @@
+/* crypto/buffer/buffer.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BUFFER_H
+#define HEADER_BUFFER_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include 
+
+#if !defined(NO_SYS_TYPES_H)
+#include 
+#endif
+
+/* Already declared in ossl_typ.h */
+/* typedef struct buf_mem_st BUF_MEM; */
+
+struct buf_mem_st
+	{
+	int length;	/* current number of bytes */
+	char *data;
+	int max;	/* size of buffer */
+	};
+
+BUF_MEM *BUF_MEM_new(void);
+void	BUF_MEM_free(BUF_MEM *a);
+int	BUF_MEM_grow(BUF_MEM *str, int len);
+int	BUF_MEM_grow_clean(BUF_MEM *str, int len);
+char *	BUF_strdup(const char *str);
+char *	BUF_strndup(const char *str, size_t siz);
+void *	BUF_memdup(const void *data, size_t siz);
+
+/* safe string functions */
+size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
+size_t BUF_strlcat(char *dst,const char *src,size_t siz);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BUF_strings(void);
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+#define BUF_F_BUF_MEMDUP				 103
+#define BUF_F_BUF_MEM_GROW				 100
+#define BUF_F_BUF_MEM_GROW_CLEAN			 105
+#define BUF_F_BUF_MEM_NEW				 101
+#define BUF_F_BUF_STRDUP				 102
+#define BUF_F_BUF_STRNDUP				 104
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/cast.h b/dep/include/openssl/cast.h
new file mode 100644
index 000000000..90b45b950
--- /dev/null
+++ b/dep/include/openssl/cast.h
@@ -0,0 +1,105 @@
+/* crypto/cast/cast.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CAST_H
+#define HEADER_CAST_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include 
+
+#ifdef OPENSSL_NO_CAST
+#error CAST is disabled.
+#endif
+
+#define CAST_ENCRYPT	1
+#define CAST_DECRYPT	0
+
+#define CAST_LONG unsigned long
+
+#define CAST_BLOCK	8
+#define CAST_KEY_LENGTH	16
+
+typedef struct cast_key_st
+	{
+	CAST_LONG data[32];
+	int short_key;	/* Use reduced rounds for short key */
+	} CAST_KEY;
+
+ 
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+void CAST_ecb_encrypt(const unsigned char *in,unsigned char *out,CAST_KEY *key,
+		      int enc);
+void CAST_encrypt(CAST_LONG *data,CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data,CAST_KEY *key);
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		      CAST_KEY *ks, unsigned char *iv, int enc);
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, CAST_KEY *schedule, unsigned char *ivec,
+			int *num, int enc);
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, 
+			long length, CAST_KEY *schedule, unsigned char *ivec,
+			int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/comp.h b/dep/include/openssl/comp.h
new file mode 100644
index 000000000..5d59354a5
--- /dev/null
+++ b/dep/include/openssl/comp.h
@@ -0,0 +1,66 @@
+
+#ifndef HEADER_COMP_H
+#define HEADER_COMP_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct comp_ctx_st COMP_CTX;
+
+typedef struct comp_method_st
+	{
+	int type;		/* NID for compression library */
+	const char *name;	/* A text string to identify the library */
+	int (*init)(COMP_CTX *ctx);
+	void (*finish)(COMP_CTX *ctx);
+	int (*compress)(COMP_CTX *ctx,
+			unsigned char *out, unsigned int olen,
+			unsigned char *in, unsigned int ilen);
+	int (*expand)(COMP_CTX *ctx,
+		      unsigned char *out, unsigned int olen,
+		      unsigned char *in, unsigned int ilen);
+	/* The following two do NOTHING, but are kept for backward compatibility */
+	long (*ctrl)(void);
+	long (*callback_ctrl)(void);
+	} COMP_METHOD;
+
+struct comp_ctx_st
+	{
+	COMP_METHOD *meth;
+	unsigned long compress_in;
+	unsigned long compress_out;
+	unsigned long expand_in;
+	unsigned long expand_out;
+
+	CRYPTO_EX_DATA	ex_data;
+	};
+
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
+void COMP_CTX_free(COMP_CTX *ctx);
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	unsigned char *in, int ilen);
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	unsigned char *in, int ilen);
+COMP_METHOD *COMP_rle(void );
+COMP_METHOD *COMP_zlib(void );
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_COMP_strings(void);
+
+/* Error codes for the COMP functions. */
+
+/* Function codes. */
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/conf.h b/dep/include/openssl/conf.h
new file mode 100644
index 000000000..4c073dd83
--- /dev/null
+++ b/dep/include/openssl/conf.h
@@ -0,0 +1,253 @@
+/* crypto/conf/conf.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef  HEADER_CONF_H
+#define HEADER_CONF_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+	{
+	char *section;
+	char *name;
+	char *value;
+	} CONF_VALUE;
+
+DECLARE_STACK_OF(CONF_VALUE)
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
+struct conf_st;
+struct conf_method_st;
+typedef struct conf_method_st CONF_METHOD;
+
+struct conf_method_st
+	{
+	const char *name;
+	CONF *(*create)(CONF_METHOD *meth);
+	int (*init)(CONF *conf);
+	int (*destroy)(CONF *conf);
+	int (*destroy_data)(CONF *conf);
+	int (*load_bio)(CONF *conf, BIO *bp, long *eline);
+	int (*dump)(const CONF *conf, BIO *bp);
+	int (*is_number)(const CONF *conf, char c);
+	int (*to_int)(const CONF *conf, char c);
+	int (*load)(CONF *conf, const char *name, long *eline);
+	};
+
+/* Module definitions */
+
+typedef struct conf_imodule_st CONF_IMODULE;
+typedef struct conf_module_st CONF_MODULE;
+
+/* DSO module function typedefs */
+typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
+typedef void conf_finish_func(CONF_IMODULE *md);
+
+#define	CONF_MFLAGS_IGNORE_ERRORS	0x1
+#define CONF_MFLAGS_IGNORE_RETURN_CODES	0x2
+#define CONF_MFLAGS_SILENT		0x4
+#define CONF_MFLAGS_NO_DSO		0x8
+#define CONF_MFLAGS_IGNORE_MISSING_FILE	0x10
+
+int CONF_set_default_method(CONF_METHOD *meth);
+void CONF_set_nconf(CONF *conf,LHASH *hash);
+LHASH *CONF_load(LHASH *conf,const char *file,long *eline);
+#ifndef OPENSSL_NO_FP_API
+LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline);
+#endif
+LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section);
+char *CONF_get_string(LHASH *conf,const char *group,const char *name);
+long CONF_get_number(LHASH *conf,const char *group,const char *name);
+void CONF_free(LHASH *conf);
+int CONF_dump_fp(LHASH *conf, FILE *out);
+int CONF_dump_bio(LHASH *conf, BIO *out);
+
+void OPENSSL_config(const char *config_name);
+void OPENSSL_no_config(void);
+
+/* New conf code.  The semantics are different from the functions above.
+   If that wasn't the case, the above functions would have been replaced */
+
+struct conf_st
+	{
+	CONF_METHOD *meth;
+	void *meth_data;
+	LHASH *data;
+	};
+
+CONF *NCONF_new(CONF_METHOD *meth);
+CONF_METHOD *NCONF_default(void);
+CONF_METHOD *NCONF_WIN32(void);
+#if 0 /* Just to give you an idea of what I have in mind */
+CONF_METHOD *NCONF_XML(void);
+#endif
+void NCONF_free(CONF *conf);
+void NCONF_free_data(CONF *conf);
+
+int NCONF_load(CONF *conf,const char *file,long *eline);
+#ifndef OPENSSL_NO_FP_API
+int NCONF_load_fp(CONF *conf, FILE *fp,long *eline);
+#endif
+int NCONF_load_bio(CONF *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section);
+char *NCONF_get_string(const CONF *conf,const char *group,const char *name);
+int NCONF_get_number_e(const CONF *conf,const char *group,const char *name,
+		       long *result);
+int NCONF_dump_fp(const CONF *conf, FILE *out);
+int NCONF_dump_bio(const CONF *conf, BIO *out);
+
+#if 0 /* The following function has no error checking,
+	 and should therefore be avoided */
+long NCONF_get_number(CONF *conf,char *group,char *name);
+#else
+#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
+#endif
+  
+/* Module functions */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+		      unsigned long flags);
+int CONF_modules_load_file(const char *filename, const char *appname,
+			   unsigned long flags);
+void CONF_modules_unload(int all);
+void CONF_modules_finish(void);
+void CONF_modules_free(void);
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+		    conf_finish_func *ffunc);
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md);
+const char *CONF_imodule_get_value(const CONF_IMODULE *md);
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
+void *CONF_module_get_usr_data(CONF_MODULE *pmod);
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
+
+char *CONF_get1_default_config_file(void);
+
+int CONF_parse_list(const char *list, int sep, int nospc,
+	int (*list_cb)(const char *elem, int len, void *usr), void *arg);
+
+void OPENSSL_load_builtin_modules(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CONF_strings(void);
+
+/* Error codes for the CONF functions. */
+
+/* Function codes. */
+#define CONF_F_CONF_DUMP_FP				 104
+#define CONF_F_CONF_LOAD				 100
+#define CONF_F_CONF_LOAD_BIO				 102
+#define CONF_F_CONF_LOAD_FP				 103
+#define CONF_F_CONF_MODULES_LOAD			 116
+#define CONF_F_DEF_LOAD					 120
+#define CONF_F_DEF_LOAD_BIO				 121
+#define CONF_F_MODULE_INIT				 115
+#define CONF_F_MODULE_LOAD_DSO				 117
+#define CONF_F_MODULE_RUN				 118
+#define CONF_F_NCONF_DUMP_BIO				 105
+#define CONF_F_NCONF_DUMP_FP				 106
+#define CONF_F_NCONF_GET_NUMBER				 107
+#define CONF_F_NCONF_GET_NUMBER_E			 112
+#define CONF_F_NCONF_GET_SECTION			 108
+#define CONF_F_NCONF_GET_STRING				 109
+#define CONF_F_NCONF_LOAD				 113
+#define CONF_F_NCONF_LOAD_BIO				 110
+#define CONF_F_NCONF_LOAD_FP				 114
+#define CONF_F_NCONF_NEW				 111
+#define CONF_F_STR_COPY					 101
+
+/* Reason codes. */
+#define CONF_R_ERROR_LOADING_DSO			 110
+#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
+#define CONF_R_MISSING_EQUAL_SIGN			 101
+#define CONF_R_MISSING_FINISH_FUNCTION			 111
+#define CONF_R_MISSING_INIT_FUNCTION			 112
+#define CONF_R_MODULE_INITIALIZATION_ERROR		 109
+#define CONF_R_NO_CLOSE_BRACE				 102
+#define CONF_R_NO_CONF					 105
+#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE		 106
+#define CONF_R_NO_SECTION				 107
+#define CONF_R_NO_SUCH_FILE				 114
+#define CONF_R_NO_VALUE					 108
+#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION		 103
+#define CONF_R_UNKNOWN_MODULE_NAME			 113
+#define CONF_R_VARIABLE_HAS_NO_VALUE			 104
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/conf_api.h b/dep/include/openssl/conf_api.h
new file mode 100644
index 000000000..87a954aff
--- /dev/null
+++ b/dep/include/openssl/conf_api.h
@@ -0,0 +1,89 @@
+/* conf_api.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef  HEADER_CONF_API_H
+#define HEADER_CONF_API_H
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+					       const char *section);
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
+char *_CONF_get_string(const CONF *conf, const char *section,
+		       const char *name);
+long _CONF_get_number(const CONF *conf, const char *section, const char *name);
+
+int _CONF_new_data(CONF *conf);
+void _CONF_free_data(CONF *conf);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/crypto.h b/dep/include/openssl/crypto.h
new file mode 100644
index 000000000..d2b5ffe33
--- /dev/null
+++ b/dep/include/openssl/crypto.h
@@ -0,0 +1,550 @@
+/* crypto/crypto.h */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_CRYPTO_H
+#define HEADER_CRYPTO_H
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_FP_API
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CHARSET_EBCDIC
+#include 
+#endif
+
+/* Resolve problems on some operating systems with symbol names that clash
+   one way or another */
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Backward compatibility to SSLeay */
+/* This is more to be used to check the correct DLL is being used
+ * in the MS world. */
+#define SSLEAY_VERSION_NUMBER	OPENSSL_VERSION_NUMBER
+#define SSLEAY_VERSION		0
+/* #define SSLEAY_OPTIONS	1 no longer supported */
+#define SSLEAY_CFLAGS		2
+#define SSLEAY_BUILT_ON		3
+#define SSLEAY_PLATFORM		4
+#define SSLEAY_DIR		5
+
+/* Already declared in ossl_typ.h */
+#if 0
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Called when a new object is created */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when an object is free()ed */
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when we need to dup an object */
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+#endif
+
+/* A generic structure to pass assorted data in a expandable way */
+typedef struct openssl_item_st
+	{
+	int code;
+	void *value;		/* Not used for flag attributes */
+	size_t value_size;	/* Max size of value for output, length for input */
+	size_t *value_length;	/* Returned length of value for output */
+	} OPENSSL_ITEM;
+
+
+/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * names in cryptlib.c
+ */
+
+#define	CRYPTO_LOCK_ERR			1
+#define	CRYPTO_LOCK_EX_DATA		2
+#define	CRYPTO_LOCK_X509		3
+#define	CRYPTO_LOCK_X509_INFO		4
+#define	CRYPTO_LOCK_X509_PKEY		5
+#define CRYPTO_LOCK_X509_CRL		6
+#define CRYPTO_LOCK_X509_REQ		7
+#define CRYPTO_LOCK_DSA			8
+#define CRYPTO_LOCK_RSA			9
+#define CRYPTO_LOCK_EVP_PKEY		10
+#define CRYPTO_LOCK_X509_STORE		11
+#define CRYPTO_LOCK_SSL_CTX		12
+#define CRYPTO_LOCK_SSL_CERT		13
+#define CRYPTO_LOCK_SSL_SESSION		14
+#define CRYPTO_LOCK_SSL_SESS_CERT	15
+#define CRYPTO_LOCK_SSL			16
+#define CRYPTO_LOCK_SSL_METHOD		17
+#define CRYPTO_LOCK_RAND		18
+#define CRYPTO_LOCK_RAND2		19
+#define CRYPTO_LOCK_MALLOC		20
+#define CRYPTO_LOCK_BIO			21
+#define CRYPTO_LOCK_GETHOSTBYNAME	22
+#define CRYPTO_LOCK_GETSERVBYNAME	23
+#define CRYPTO_LOCK_READDIR		24
+#define CRYPTO_LOCK_RSA_BLINDING	25
+#define CRYPTO_LOCK_DH			26
+#define CRYPTO_LOCK_MALLOC2		27
+#define CRYPTO_LOCK_DSO			28
+#define CRYPTO_LOCK_DYNLOCK		29
+#define CRYPTO_LOCK_ENGINE		30
+#define CRYPTO_LOCK_UI			31
+#define CRYPTO_LOCK_ECDSA               32
+#define CRYPTO_LOCK_EC			33
+#define CRYPTO_LOCK_ECDH		34
+#define CRYPTO_LOCK_BN  		35
+#define CRYPTO_LOCK_EC_PRE_COMP		36
+#define CRYPTO_LOCK_STORE		37
+#define CRYPTO_LOCK_COMP		38
+#define CRYPTO_NUM_LOCKS		39
+
+#define CRYPTO_LOCK		1
+#define CRYPTO_UNLOCK		2
+#define CRYPTO_READ		4
+#define CRYPTO_WRITE		8
+
+#ifndef OPENSSL_NO_LOCKING
+#ifndef CRYPTO_w_lock
+#define CRYPTO_w_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_w_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_r_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_r_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_add(addr,amount,type)	\
+	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+#endif
+#else
+#define CRYPTO_w_lock(a)
+#define CRYPTO_w_unlock(a)
+#define CRYPTO_r_lock(a)
+#define CRYPTO_r_unlock(a)
+#define CRYPTO_add(a,b,c)	((*(a))+=(b))
+#endif
+
+/* Some applications as well as some parts of OpenSSL need to allocate
+   and deallocate locks in a dynamic fashion.  The following typedef
+   makes this possible in a type-safe manner.  */
+/* struct CRYPTO_dynlock_value has to be defined by the application. */
+typedef struct
+	{
+	int references;
+	struct CRYPTO_dynlock_value *data;
+	} CRYPTO_dynlock;
+
+
+/* The following can be used to detect memory leaks in the SSLeay library.
+ * It used, it turns on malloc checking */
+
+#define CRYPTO_MEM_CHECK_OFF	0x0	/* an enume */
+#define CRYPTO_MEM_CHECK_ON	0x1	/* a bit */
+#define CRYPTO_MEM_CHECK_ENABLE	0x2	/* a bit */
+#define CRYPTO_MEM_CHECK_DISABLE 0x3	/* an enume */
+
+/* The following are bit values to turn on or off options connected to the
+ * malloc checking functionality */
+
+/* Adds time to the memory checking information */
+#define V_CRYPTO_MDEBUG_TIME	0x1 /* a bit */
+/* Adds thread number to the memory checking information */
+#define V_CRYPTO_MDEBUG_THREAD	0x2 /* a bit */
+
+#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
+
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+struct crypto_ex_data_st
+	{
+	STACK *sk;
+	int dummy; /* gcc is screwing up this data structure :-( */
+	};
+
+/* This stuff is basically class callback functions
+ * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
+
+typedef struct crypto_ex_data_func_st
+	{
+	long argl;	/* Arbitary long */
+	void *argp;	/* Arbitary void * */
+	CRYPTO_EX_new *new_func;
+	CRYPTO_EX_free *free_func;
+	CRYPTO_EX_dup *dup_func;
+	} CRYPTO_EX_DATA_FUNCS;
+
+DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
+
+/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+#define CRYPTO_EX_INDEX_BIO		0
+#define CRYPTO_EX_INDEX_SSL		1
+#define CRYPTO_EX_INDEX_SSL_CTX		2
+#define CRYPTO_EX_INDEX_SSL_SESSION	3
+#define CRYPTO_EX_INDEX_X509_STORE	4
+#define CRYPTO_EX_INDEX_X509_STORE_CTX	5
+#define CRYPTO_EX_INDEX_RSA		6
+#define CRYPTO_EX_INDEX_DSA		7
+#define CRYPTO_EX_INDEX_DH		8
+#define CRYPTO_EX_INDEX_ENGINE		9
+#define CRYPTO_EX_INDEX_X509		10
+#define CRYPTO_EX_INDEX_UI		11
+#define CRYPTO_EX_INDEX_ECDSA		12
+#define CRYPTO_EX_INDEX_ECDH		13
+#define CRYPTO_EX_INDEX_COMP		14
+#define CRYPTO_EX_INDEX_STORE		15
+
+/* Dynamically assigned indexes start from this value (don't use directly, use
+ * via CRYPTO_ex_data_new_class). */
+#define CRYPTO_EX_INDEX_USER		100
+
+
+/* This is the default callbacks, but we can have others as well:
+ * this is needed in Win32 where the application malloc and the
+ * library malloc may not be the same.
+ */
+#define CRYPTO_malloc_init()	CRYPTO_set_mem_functions(\
+	malloc, realloc, free)
+
+#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
+# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */
+#  define CRYPTO_MDEBUG
+# endif
+#endif
+
+/* Set standard debugging functions (not done by default
+ * unless CRYPTO_MDEBUG is defined) */
+#define CRYPTO_malloc_debug_init()	do {\
+	CRYPTO_set_mem_debug_functions(\
+		CRYPTO_dbg_malloc,\
+		CRYPTO_dbg_realloc,\
+		CRYPTO_dbg_free,\
+		CRYPTO_dbg_set_options,\
+		CRYPTO_dbg_get_options);\
+	} while(0)
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_is_mem_check_on(void);
+
+/* for applications */
+#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+#define MemCheck_stop()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+
+/* for library-internal use */
+#define MemCheck_on()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+#define MemCheck_off()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+#define is_MemCheck_on() CRYPTO_is_mem_check_on()
+
+#define OPENSSL_malloc(num)	CRYPTO_malloc((int)num,__FILE__,__LINE__)
+#define OPENSSL_realloc(addr,num) \
+	CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
+#define OPENSSL_realloc_clean(addr,old_num,num) \
+	CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
+#define OPENSSL_remalloc(addr,num) \
+	CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
+#define OPENSSL_freeFunc	CRYPTO_free
+#define OPENSSL_free(addr)	CRYPTO_free(addr)
+
+#define OPENSSL_malloc_locked(num) \
+	CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
+#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
+
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int OPENSSL_issetugid(void);
+
+/* An opaque type representing an implementation of "ex_data" support */
+typedef struct st_CRYPTO_EX_DATA_IMPL	CRYPTO_EX_DATA_IMPL;
+/* Return an opaque pointer to the current "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
+/* Sets the "ex_data" implementation to be used (if it's not too late) */
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
+/* Get a new "ex_data" class, and return the corresponding "class_index" */
+int CRYPTO_ex_data_new_class(void);
+/* Within a given class, get/register a new index */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given
+ * class (invokes whatever per-class callbacks are applicable) */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+		CRYPTO_EX_DATA *from);
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index
+ * (relative to the class type involved) */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad,int idx);
+/* This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions. */
+void CRYPTO_cleanup_all_ex_data(void);
+
+int CRYPTO_get_new_lockid(char *name);
+
+int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
+void CRYPTO_lock(int mode, int type,const char *file,int line);
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+					      const char *file,int line));
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+		int line);
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+					      const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+					  const char *file,int line);
+void CRYPTO_set_id_callback(unsigned long (*func)(void));
+unsigned long (*CRYPTO_get_id_callback(void))(void);
+unsigned long CRYPTO_thread_id(void);
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
+		    int line);
+
+int CRYPTO_get_new_dynlockid(void);
+void CRYPTO_destroy_dynlockid(int i);
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line));
+void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line));
+void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line));
+struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file,int line);
+void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file,int line);
+void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file,int line);
+
+/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions --
+ * call the latter last if you need different functions */
+int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
+int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *));
+int CRYPTO_set_mem_ex_functions(void *(*m)(size_t,const char *,int),
+                                void *(*r)(void *,size_t,const char *,int),
+                                void (*f)(void *));
+int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t,const char *,int),
+                                       void (*free_func)(void *));
+int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
+				   void (*r)(void *,void *,int,const char *,int,int),
+				   void (*f)(void *,int),
+				   void (*so)(long),
+				   long (*go)(void));
+void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
+void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
+void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                 void *(**r)(void *, size_t,const char *,int),
+                                 void (**f)(void *));
+void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                        void (**f)(void *));
+void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
+				    void (**r)(void *,void *,int,const char *,int,int),
+				    void (**f)(void *,int),
+				    void (**so)(long),
+				    long (**go)(void));
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line);
+void CRYPTO_free_locked(void *);
+void *CRYPTO_malloc(int num, const char *file, int line);
+void CRYPTO_free(void *);
+void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
+void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
+			   int line);
+void *CRYPTO_remalloc(void *addr,int num, const char *file, int line);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+void CRYPTO_set_mem_debug_options(long bits);
+long CRYPTO_get_mem_debug_options(void);
+
+#define CRYPTO_push_info(info) \
+        CRYPTO_push_info_(info, __FILE__, __LINE__);
+int CRYPTO_push_info_(const char *info, const char *file, int line);
+int CRYPTO_pop_info(void);
+int CRYPTO_remove_all_info(void);
+
+
+/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
+ * used as default in CRYPTO_MDEBUG compilations): */
+/* The last argument has the following significance:
+ *
+ * 0:	called before the actual memory allocation has taken place
+ * 1:	called after the actual memory allocation has taken place
+ */
+void CRYPTO_dbg_malloc(void *addr,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_realloc(void *addr1,void *addr2,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_free(void *addr,int before_p);
+/* Tell the debugging code about options.  By default, the following values
+ * apply:
+ *
+ * 0:                           Clear all options.
+ * V_CRYPTO_MDEBUG_TIME (1):    Set the "Show Time" option.
+ * V_CRYPTO_MDEBUG_THREAD (2):  Set the "Show Thread Number" option.
+ * V_CRYPTO_MDEBUG_ALL (3):     1 + 2
+ */
+void CRYPTO_dbg_set_options(long bits);
+long CRYPTO_dbg_get_options(void);
+
+
+#ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+#endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *);
+void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);
+
+/* die if we have to */
+void OpenSSLDie(const char *file,int line,const char *assertion);
+#define OPENSSL_assert(e)       (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1))
+
+unsigned long *OPENSSL_ia32cap_loc(void);
+#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CRYPTO_strings(void);
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX		 100
+#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID		 103
+#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID			 101
+#define CRYPTO_F_CRYPTO_SET_EX_DATA			 102
+#define CRYPTO_F_DEF_ADD_INDEX				 104
+#define CRYPTO_F_DEF_GET_CLASS				 105
+#define CRYPTO_F_INT_DUP_EX_DATA			 106
+#define CRYPTO_F_INT_FREE_EX_DATA			 107
+#define CRYPTO_F_INT_NEW_EX_DATA			 108
+
+/* Reason codes. */
+#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK		 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/des.h b/dep/include/openssl/des.h
new file mode 100644
index 000000000..3cbc2b568
--- /dev/null
+++ b/dep/include/openssl/des.h
@@ -0,0 +1,244 @@
+/* crypto/des/des.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_NEW_DES_H
+#define HEADER_NEW_DES_H
+
+#include 	/* OPENSSL_EXTERN, OPENSSL_NO_DES,
+				   DES_LONG (via openssl/opensslconf.h */
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock *
+ * and const_DES_cblock * are incompatible pointer types. */
+
+typedef struct DES_ks
+    {
+    union
+	{
+	DES_cblock cblock;
+	/* make sure things are correct size on machines with
+	 * 8 byte longs */
+	DES_LONG deslong[2];
+	} ks[16];
+    } DES_key_schedule;
+
+#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
+# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
+#  define OPENSSL_ENABLE_OLD_DES_SUPPORT
+# endif
+#endif
+
+#ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
+# include 
+#endif
+
+#define DES_KEY_SZ 	(sizeof(DES_cblock))
+#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+#define DES_ENCRYPT	1
+#define DES_DECRYPT	0
+
+#define DES_CBC_MODE	0
+#define DES_PCBC_MODE	1
+
+#define DES_ecb2_encrypt(i,o,k1,k2,e) \
+	DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int,DES_check_key);	/* defaults to false */
+#define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+OPENSSL_DECLARE_GLOBAL(int,DES_rw_mode);	/* defaults to DES_PCBC_MODE */
+#define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)
+
+const char *DES_options(void);
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+		      DES_key_schedule *ks1,DES_key_schedule *ks2,
+		      DES_key_schedule *ks3, int enc);
+DES_LONG DES_cbc_cksum(const unsigned char *input,DES_cblock *output,
+		       long length,DES_key_schedule *schedule,
+		       const_DES_cblock *ivec);
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input,unsigned char *output,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		     int enc);
+void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      int enc);
+void DES_xcbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      const_DES_cblock *inw,const_DES_cblock *outw,int enc);
+void DES_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		     int enc);
+void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output,
+		     DES_key_schedule *ks,int enc);
+
+/* 	This is the DES encryption function that gets called by just about
+	every other DES routine in the library.  You should not use this
+	function except to implement 'modes' of DES.  I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.  The characters are loaded 'little endian'.
+	Data is a pointer to 2 unsigned long's and ks is the
+	DES_key_schedule to use.  enc, is non zero specifies encryption,
+	zero if decryption. */
+void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc);
+
+/* 	This functions is the same as DES_encrypt1() except that the DES
+	initial permutation (IP) and final permutation (FP) have been left
+	out.  As for DES_encrypt1(), you should not use this function.
+	It is used by the routines in the library that implement triple DES.
+	IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same
+	as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */
+void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc);
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, 
+			  long length,
+			  DES_key_schedule *ks1,DES_key_schedule *ks2,
+			  DES_key_schedule *ks3,DES_cblock *ivec,int enc);
+void DES_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out,
+			   long length,
+			   DES_key_schedule *ks1,DES_key_schedule *ks2,
+			   DES_key_schedule *ks3,
+			   DES_cblock *ivec1,DES_cblock *ivec2,
+			   int enc);
+void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out,
+			    long length,DES_key_schedule *ks1,
+			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+			    DES_cblock *ivec,int *num,int enc);
+void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
+			  int numbits,long length,DES_key_schedule *ks1,
+			  DES_key_schedule *ks2,DES_key_schedule *ks3,
+			  DES_cblock *ivec,int enc);
+void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out,
+			    long length,DES_key_schedule *ks1,
+			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+			    DES_cblock *ivec,int *num);
+
+void DES_xwhite_in2out(const_DES_cblock *DES_key,const_DES_cblock *in_white,
+		       DES_cblock *out_white);
+
+int DES_enc_read(int fd,void *buf,int len,DES_key_schedule *sched,
+		 DES_cblock *iv);
+int DES_enc_write(int fd,const void *buf,int len,DES_key_schedule *sched,
+		  DES_cblock *iv);
+char *DES_fcrypt(const char *buf,const char *salt, char *ret);
+char *DES_crypt(const char *buf,const char *salt);
+void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec);
+void DES_pcbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      int enc);
+DES_LONG DES_quad_cksum(const unsigned char *input,DES_cblock output[],
+			long length,int out_count,DES_cblock *seed);
+int DES_random_key(DES_cblock *ret);
+void DES_set_odd_parity(DES_cblock *key);
+int DES_check_key_parity(const_DES_cblock *key);
+int DES_is_weak_key(const_DES_cblock *key);
+/* DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise. */
+int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
+int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule);
+int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule);
+void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
+void DES_string_to_key(const char *str,DES_cblock *key);
+void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2);
+void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+		       DES_key_schedule *schedule,DES_cblock *ivec,int *num,
+		       int enc);
+void DES_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+		       DES_key_schedule *schedule,DES_cblock *ivec,int *num);
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify);
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
+	int verify);
+
+#define DES_fixup_key_parity DES_set_odd_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/des_old.h b/dep/include/openssl/des_old.h
new file mode 100644
index 000000000..1b0620c3a
--- /dev/null
+++ b/dep/include/openssl/des_old.h
@@ -0,0 +1,445 @@
+/* crypto/des/des_old.h -*- mode:C; c-file-style: "eay" -*- */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * The function names in here are deprecated and are only present to
+ * provide an interface compatible with openssl 0.9.6 and older as
+ * well as libdes.  OpenSSL now provides functions where "des_" has
+ * been replaced with "DES_" in the names, to make it possible to
+ * make incompatible changes that are needed for C type security and
+ * other stuff.
+ *
+ * This include files has two compatibility modes:
+ *
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API
+ *     that is compatible with libdes and SSLeay.
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an
+ *     API that is compatible with OpenSSL 0.9.5x to 0.9.6x.
+ *
+ * Note that these modes break earlier snapshots of OpenSSL, where
+ * libdes compatibility was the only available mode or (later on) the
+ * prefered compatibility mode.  However, after much consideration
+ * (and more or less violent discussions with external parties), it
+ * was concluded that OpenSSL should be compatible with earlier versions
+ * of itself before anything else.  Also, in all honesty, libdes is
+ * an old beast that shouldn't really be used any more.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones.  The des_ functions will disappear completely before
+ * OpenSSL 1.0!
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#include 	/* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#ifndef HEADER_NEW_DES_H
+#error You must include des.h, not des_old.h directly.
+#endif
+
+#ifdef _KERBEROS_DES_H
+#error  replaces .
+#endif
+
+#include 
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef _
+#undef _
+#endif
+
+typedef unsigned char _ossl_old_des_cblock[8];
+typedef struct _ossl_old_des_ks_struct
+	{
+	union	{
+		_ossl_old_des_cblock _;
+		/* make sure things are correct size on machines with
+		 * 8 byte longs */
+		DES_LONG pad[2];
+		} ks;
+	} _ossl_old_des_key_schedule[16];
+
+#ifndef OPENSSL_DES_LIBDES_COMPATIBILITY
+#define des_cblock DES_cblock
+#define const_des_cblock const_DES_cblock
+#define des_key_schedule DES_key_schedule
+#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+	DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e))
+#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+	DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e))
+#define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\
+	DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e))
+#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+	DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e))
+#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+	DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n))
+#define des_options()\
+	DES_options()
+#define des_cbc_cksum(i,o,l,k,iv)\
+	DES_cbc_cksum((i),(o),(l),&(k),(iv))
+#define des_cbc_encrypt(i,o,l,k,iv,e)\
+	DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_ncbc_encrypt(i,o,l,k,iv,e)\
+	DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+	DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e))
+#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+	DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e))
+#define des_ecb_encrypt(i,o,k,e)\
+	DES_ecb_encrypt((i),(o),&(k),(e))
+#define des_encrypt1(d,k,e)\
+	DES_encrypt1((d),&(k),(e))
+#define des_encrypt2(d,k,e)\
+	DES_encrypt2((d),&(k),(e))
+#define des_encrypt3(d,k1,k2,k3)\
+	DES_encrypt3((d),&(k1),&(k2),&(k3))
+#define des_decrypt3(d,k1,k2,k3)\
+	DES_decrypt3((d),&(k1),&(k2),&(k3))
+#define des_xwhite_in2out(k,i,o)\
+	DES_xwhite_in2out((k),(i),(o))
+#define des_enc_read(f,b,l,k,iv)\
+	DES_enc_read((f),(b),(l),&(k),(iv))
+#define des_enc_write(f,b,l,k,iv)\
+	DES_enc_write((f),(b),(l),&(k),(iv))
+#define des_fcrypt(b,s,r)\
+	DES_fcrypt((b),(s),(r))
+#if 0
+#define des_crypt(b,s)\
+	DES_crypt((b),(s))
+#if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
+#define crypt(b,s)\
+	DES_crypt((b),(s))
+#endif
+#endif
+#define des_ofb_encrypt(i,o,n,l,k,iv)\
+	DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv))
+#define des_pcbc_encrypt(i,o,l,k,iv,e)\
+	DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_quad_cksum(i,o,l,c,s)\
+	DES_quad_cksum((i),(o),(l),(c),(s))
+#define des_random_seed(k)\
+	_ossl_096_des_random_seed((k))
+#define des_random_key(r)\
+	DES_random_key((r))
+#define des_read_password(k,p,v) \
+	DES_read_password((k),(p),(v))
+#define des_read_2passwords(k1,k2,p,v) \
+	DES_read_2passwords((k1),(k2),(p),(v))
+#define des_set_odd_parity(k)\
+	DES_set_odd_parity((k))
+#define des_check_key_parity(k)\
+	DES_check_key_parity((k))
+#define des_is_weak_key(k)\
+	DES_is_weak_key((k))
+#define des_set_key(k,ks)\
+	DES_set_key((k),&(ks))
+#define des_key_sched(k,ks)\
+	DES_key_sched((k),&(ks))
+#define des_set_key_checked(k,ks)\
+	DES_set_key_checked((k),&(ks))
+#define des_set_key_unchecked(k,ks)\
+	DES_set_key_unchecked((k),&(ks))
+#define des_string_to_key(s,k)\
+	DES_string_to_key((s),(k))
+#define des_string_to_2keys(s,k1,k2)\
+	DES_string_to_2keys((s),(k1),(k2))
+#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+	DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e))
+#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+	DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n))
+		
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define des_check_key DES_check_key
+#define des_rw_mode DES_rw_mode
+#else /* libdes compatibility */
+/* Map all symbol names to _ossl_old_des_* form, so we avoid all
+   clashes with libdes */
+#define des_cblock _ossl_old_des_cblock
+#define des_key_schedule _ossl_old_des_key_schedule
+#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+	_ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e))
+#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+	_ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e))
+#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+	_ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e))
+#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+	_ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n))
+#define des_options()\
+	_ossl_old_des_options()
+#define des_cbc_cksum(i,o,l,k,iv)\
+	_ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv))
+#define des_cbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_ncbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+	_ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e))
+#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+	_ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e))
+#define des_ecb_encrypt(i,o,k,e)\
+	_ossl_old_des_ecb_encrypt((i),(o),(k),(e))
+#define des_encrypt(d,k,e)\
+	_ossl_old_des_encrypt((d),(k),(e))
+#define des_encrypt2(d,k,e)\
+	_ossl_old_des_encrypt2((d),(k),(e))
+#define des_encrypt3(d,k1,k2,k3)\
+	_ossl_old_des_encrypt3((d),(k1),(k2),(k3))
+#define des_decrypt3(d,k1,k2,k3)\
+	_ossl_old_des_decrypt3((d),(k1),(k2),(k3))
+#define des_xwhite_in2out(k,i,o)\
+	_ossl_old_des_xwhite_in2out((k),(i),(o))
+#define des_enc_read(f,b,l,k,iv)\
+	_ossl_old_des_enc_read((f),(b),(l),(k),(iv))
+#define des_enc_write(f,b,l,k,iv)\
+	_ossl_old_des_enc_write((f),(b),(l),(k),(iv))
+#define des_fcrypt(b,s,r)\
+	_ossl_old_des_fcrypt((b),(s),(r))
+#define des_crypt(b,s)\
+	_ossl_old_des_crypt((b),(s))
+#if 0
+#define crypt(b,s)\
+	_ossl_old_crypt((b),(s))
+#endif
+#define des_ofb_encrypt(i,o,n,l,k,iv)\
+	_ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv))
+#define des_pcbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_quad_cksum(i,o,l,c,s)\
+	_ossl_old_des_quad_cksum((i),(o),(l),(c),(s))
+#define des_random_seed(k)\
+	_ossl_old_des_random_seed((k))
+#define des_random_key(r)\
+	_ossl_old_des_random_key((r))
+#define des_read_password(k,p,v) \
+	_ossl_old_des_read_password((k),(p),(v))
+#define des_read_2passwords(k1,k2,p,v) \
+	_ossl_old_des_read_2passwords((k1),(k2),(p),(v))
+#define des_set_odd_parity(k)\
+	_ossl_old_des_set_odd_parity((k))
+#define des_is_weak_key(k)\
+	_ossl_old_des_is_weak_key((k))
+#define des_set_key(k,ks)\
+	_ossl_old_des_set_key((k),(ks))
+#define des_key_sched(k,ks)\
+	_ossl_old_des_key_sched((k),(ks))
+#define des_string_to_key(s,k)\
+	_ossl_old_des_string_to_key((s),(k))
+#define des_string_to_2keys(s,k1,k2)\
+	_ossl_old_des_string_to_2keys((s),(k1),(k2))
+#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+	_ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e))
+#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+	_ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n))
+		
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define des_check_key DES_check_key
+#define des_rw_mode DES_rw_mode
+#endif
+
+const char *_ossl_old_des_options(void);
+void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	_ossl_old_des_key_schedule ks1,_ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, int enc);
+DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
+void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,
+	_ossl_old_des_cblock *inw,_ossl_old_des_cblock *outw,int enc);
+void _ossl_old_des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	_ossl_old_des_key_schedule ks,int enc);
+void _ossl_old_des_encrypt(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt2(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, _ossl_old_des_cblock *output, 
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2, 
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc);
+void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num);
+
+void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), _ossl_old_des_cblock (*in_white),
+	_ossl_old_des_cblock (*out_white));
+
+int _ossl_old_des_enc_read(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
+	_ossl_old_des_cblock *iv);
+int _ossl_old_des_enc_write(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
+	_ossl_old_des_cblock *iv);
+char *_ossl_old_des_fcrypt(const char *buf,const char *salt, char *ret);
+char *_ossl_old_des_crypt(const char *buf,const char *salt);
+#if !defined(PERL5) && !defined(NeXT)
+char *_ossl_old_crypt(const char *buf,const char *salt);
+#endif
+void _ossl_old_des_ofb_encrypt(unsigned char *in,unsigned char *out,
+	int numbits,long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
+void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,int out_count,_ossl_old_des_cblock *seed);
+void _ossl_old_des_random_seed(_ossl_old_des_cblock key);
+void _ossl_old_des_random_key(_ossl_old_des_cblock ret);
+int _ossl_old_des_read_password(_ossl_old_des_cblock *key,const char *prompt,int verify);
+int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2,
+	const char *prompt,int verify);
+void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key);
+int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key);
+int _ossl_old_des_set_key(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
+int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
+void _ossl_old_des_string_to_key(char *str,_ossl_old_des_cblock *key);
+void _ossl_old_des_string_to_2keys(char *str,_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2);
+void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num, int enc);
+void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num);
+
+void _ossl_096_des_random_seed(des_cblock *key);
+
+/* The following definitions provide compatibility with the MIT Kerberos
+ * library. The _ossl_old_des_key_schedule structure is not binary compatible. */
+
+#define _KERBEROS_DES_H
+
+#define KRBDES_ENCRYPT DES_ENCRYPT
+#define KRBDES_DECRYPT DES_DECRYPT
+
+#ifdef KERBEROS
+#  define ENCRYPT DES_ENCRYPT
+#  define DECRYPT DES_DECRYPT
+#endif
+
+#ifndef NCOMPAT
+#  define C_Block des_cblock
+#  define Key_schedule des_key_schedule
+#  define KEY_SZ DES_KEY_SZ
+#  define string_to_key des_string_to_key
+#  define read_pw_string des_read_pw_string
+#  define random_key des_random_key
+#  define pcbc_encrypt des_pcbc_encrypt
+#  define set_key des_set_key
+#  define key_sched des_key_sched
+#  define ecb_encrypt des_ecb_encrypt
+#  define cbc_encrypt des_cbc_encrypt
+#  define ncbc_encrypt des_ncbc_encrypt
+#  define xcbc_encrypt des_xcbc_encrypt
+#  define cbc_cksum des_cbc_cksum
+#  define quad_cksum des_quad_cksum
+#  define check_parity des_check_key_parity
+#endif
+
+#define des_fixup_key_parity DES_fixup_key_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* for DES_read_pw_string et al */
+#include 
+
+#endif
diff --git a/dep/include/openssl/dh.h b/dep/include/openssl/dh.h
new file mode 100644
index 000000000..ccdf35ae1
--- /dev/null
+++ b/dep/include/openssl/dh.h
@@ -0,0 +1,234 @@
+/* crypto/dh/dh.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DH_H
+#define HEADER_DH_H
+
+#include 
+
+#ifdef OPENSSL_NO_DH
+#error DH is disabled.
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+	
+#ifndef OPENSSL_DH_MAX_MODULUS_BITS
+# define OPENSSL_DH_MAX_MODULUS_BITS	10000
+#endif
+
+#define DH_FLAG_CACHE_MONT_P     0x01
+#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
+                                       * implementation now uses constant time
+                                       * modular exponentiation for secret exponents
+                                       * by default. This flag causes the
+                                       * faster variable sliding window method to
+                                       * be used for all exponents.
+                                       */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+struct dh_method
+	{
+	const char *name;
+	/* Methods here */
+	int (*generate_key)(DH *dh);
+	int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+	int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
+				const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+
+	int (*init)(DH *dh);
+	int (*finish)(DH *dh);
+	int flags;
+	char *app_data;
+	/* If this is non-NULL, it will be used to generate parameters */
+	int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb);
+	};
+
+struct dh_st
+	{
+	/* This first argument is used to pick up errors when
+	 * a DH is passed instead of a EVP_PKEY */
+	int pad;
+	int version;
+	BIGNUM *p;
+	BIGNUM *g;
+	long length; /* optional */
+	BIGNUM *pub_key;	/* g^x */
+	BIGNUM *priv_key;	/* x */
+
+	int flags;
+	BN_MONT_CTX *method_mont_p;
+	/* Place holders if we want to do X9.42 DH */
+	BIGNUM *q;
+	BIGNUM *j;
+	unsigned char *seed;
+	int seedlen;
+	BIGNUM *counter;
+
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DH_METHOD *meth;
+	ENGINE *engine;
+	};
+
+#define DH_GENERATOR_2		2
+/* #define DH_GENERATOR_3	3 */
+#define DH_GENERATOR_5		5
+
+/* DH_check error codes */
+#define DH_CHECK_P_NOT_PRIME		0x01
+#define DH_CHECK_P_NOT_SAFE_PRIME	0x02
+#define DH_UNABLE_TO_CHECK_GENERATOR	0x04
+#define DH_NOT_SUITABLE_GENERATOR	0x08
+
+/* DH_check_pub_key error codes */
+#define DH_CHECK_PUBKEY_TOO_SMALL	0x01
+#define DH_CHECK_PUBKEY_TOO_LARGE	0x02
+
+/* primes p where (p-1)/2 is prime too are called "safe"; we define
+   this for backward compatibility: */
+#define DH_CHECK_P_NOT_STRONG_PRIME	DH_CHECK_P_NOT_SAFE_PRIME
+
+#define DHparams_dup(x) ASN1_dup_of_const(DH,i2d_DHparams,d2i_DHparams,x)
+#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+		(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
+#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *	DH_new(void);
+void	DH_free(DH *dh);
+int	DH_up_ref(DH *dh);
+int	DH_size(const DH *dh);
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+DH *	DH_generate_parameters(int prime_len,int generator,
+		void (*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb);
+
+int	DH_check(const DH *dh,int *codes);
+int	DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes);
+int	DH_generate_key(DH *dh);
+int	DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+DH *	d2i_DHparams(DH **a,const unsigned char **pp, long length);
+int	i2d_DHparams(const DH *a,unsigned char **pp);
+#ifndef OPENSSL_NO_FP_API
+int	DHparams_print_fp(FILE *fp, const DH *x);
+#endif
+#ifndef OPENSSL_NO_BIO
+int	DHparams_print(BIO *bp, const DH *x);
+#else
+int	DHparams_print(char *bp, const DH *x);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DH_strings(void);
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+#define DH_F_COMPUTE_KEY				 102
+#define DH_F_DHPARAMS_PRINT				 100
+#define DH_F_DHPARAMS_PRINT_FP				 101
+#define DH_F_DH_BUILTIN_GENPARAMS			 106
+#define DH_F_DH_NEW_METHOD				 105
+#define DH_F_GENERATE_KEY				 103
+#define DH_F_GENERATE_PARAMETERS			 104
+
+/* Reason codes. */
+#define DH_R_BAD_GENERATOR				 101
+#define DH_R_INVALID_PUBKEY				 102
+#define DH_R_MODULUS_TOO_LARGE				 103
+#define DH_R_NO_PRIVATE_VALUE				 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/dsa.h b/dep/include/openssl/dsa.h
new file mode 100644
index 000000000..3a8fe5b56
--- /dev/null
+++ b/dep/include/openssl/dsa.h
@@ -0,0 +1,285 @@
+/* crypto/dsa/dsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch .  He basically did the
+ * work and I have just tweaked them a little to fit into my
+ * stylistic vision for SSLeay :-) */
+
+#ifndef HEADER_DSA_H
+#define HEADER_DSA_H
+
+#include 
+
+#ifdef OPENSSL_NO_DSA
+#error DSA is disabled.
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#ifndef OPENSSL_NO_DH
+# include 
+#endif
+#endif
+
+#ifndef OPENSSL_DSA_MAX_MODULUS_BITS
+# define OPENSSL_DSA_MAX_MODULUS_BITS	10000
+#endif
+
+#define DSA_FLAG_CACHE_MONT_P	0x01
+#define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
+                                              * implementation now uses constant time
+                                              * modular exponentiation for secret exponents
+                                              * by default. This flag causes the
+                                              * faster variable sliding window method to
+                                              * be used for all exponents.
+                                              */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dsa_st DSA; */
+/* typedef struct dsa_method DSA_METHOD; */
+
+typedef struct DSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} DSA_SIG;
+
+struct dsa_method
+	{
+	const char *name;
+	DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
+	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+								BIGNUM **rp);
+	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
+							DSA_SIG *sig, DSA *dsa);
+	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+			BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+			BN_MONT_CTX *in_mont);
+	int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+				const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(DSA *dsa);
+	int (*finish)(DSA *dsa);
+	int flags;
+	char *app_data;
+	/* If this is non-NULL, it is used to generate DSA parameters */
+	int (*dsa_paramgen)(DSA *dsa, int bits,
+			unsigned char *seed, int seed_len,
+			int *counter_ret, unsigned long *h_ret,
+			BN_GENCB *cb);
+	/* If this is non-NULL, it is used to generate DSA keys */
+	int (*dsa_keygen)(DSA *dsa);
+	};
+
+struct dsa_st
+	{
+	/* This first variable is used to pick up errors where
+	 * a DSA is passed instead of of a EVP_PKEY */
+	int pad;
+	long version;
+	int write_params;
+	BIGNUM *p;
+	BIGNUM *q;	/* == 20 */
+	BIGNUM *g;
+
+	BIGNUM *pub_key;  /* y public key */
+	BIGNUM *priv_key; /* x private key */
+
+	BIGNUM *kinv;	/* Signing pre-calc */
+	BIGNUM *r;	/* Signing pre-calc */
+
+	int flags;
+	/* Normally used to cache montgomery values */
+	BN_MONT_CTX *method_mont_p;
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DSA_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+	};
+
+#define DSAparams_dup(x) ASN1_dup_of_const(DSA,i2d_DSAparams,d2i_DSAparams,x)
+#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
+#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
+
+
+DSA_SIG * DSA_SIG_new(void);
+void	DSA_SIG_free(DSA_SIG *a);
+int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa);
+int	DSA_do_verify(const unsigned char *dgst,int dgst_len,
+		      DSA_SIG *sig,DSA *dsa);
+
+const DSA_METHOD *DSA_OpenSSL(void);
+
+void	DSA_set_default_method(const DSA_METHOD *);
+const DSA_METHOD *DSA_get_default_method(void);
+int	DSA_set_method(DSA *dsa, const DSA_METHOD *);
+
+DSA *	DSA_new(void);
+DSA *	DSA_new_method(ENGINE *engine);
+void	DSA_free (DSA *r);
+/* "up" the DSA object's reference count */
+int	DSA_up_ref(DSA *r);
+int	DSA_size(const DSA *);
+	/* next 4 return -1 on error */
+int	DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
+int	DSA_sign(int type,const unsigned char *dgst,int dlen,
+		unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int	DSA_verify(int type,const unsigned char *dgst,int dgst_len,
+		const unsigned char *sigbuf, int siglen, DSA *dsa);
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DSA_set_ex_data(DSA *d, int idx, void *arg);
+void *DSA_get_ex_data(DSA *d, int idx);
+
+DSA *	d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
+DSA *	d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
+DSA * 	d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+DSA *	DSA_generate_parameters(int bits,
+		unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret,void
+		(*callback)(int, int, void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	DSA_generate_parameters_ex(DSA *dsa, int bits,
+		unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+
+int	DSA_generate_key(DSA *a);
+int	i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+int 	i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int	i2d_DSAparams(const DSA *a,unsigned char **pp);
+
+#ifndef OPENSSL_NO_BIO
+int	DSAparams_print(BIO *bp, const DSA *x);
+int	DSA_print(BIO *bp, const DSA *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int	DSAparams_print_fp(FILE *fp, const DSA *x);
+int	DSA_print_fp(FILE *bp, const DSA *x, int off);
+#endif
+
+#define DSS_prime_checks 50
+/* Primality test according to FIPS PUB 186[-1], Appendix 2.1:
+ * 50 rounds of Rabin-Miller */
+#define DSA_is_prime(n, callback, cb_arg) \
+	BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
+
+#ifndef OPENSSL_NO_DH
+/* Convert DSA structure (key or just parameters) into DH structure
+ * (be careful to avoid small subgroup attacks when using this!) */
+DH *DSA_dup_DH(const DSA *r);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSA_strings(void);
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+#define DSA_F_D2I_DSA_SIG				 110
+#define DSA_F_DSAPARAMS_PRINT				 100
+#define DSA_F_DSAPARAMS_PRINT_FP			 101
+#define DSA_F_DSA_DO_SIGN				 112
+#define DSA_F_DSA_DO_VERIFY				 113
+#define DSA_F_DSA_NEW_METHOD				 103
+#define DSA_F_DSA_PRINT					 104
+#define DSA_F_DSA_PRINT_FP				 105
+#define DSA_F_DSA_SIGN					 106
+#define DSA_F_DSA_SIGN_SETUP				 107
+#define DSA_F_DSA_SIG_NEW				 109
+#define DSA_F_DSA_VERIFY				 108
+#define DSA_F_I2D_DSA_SIG				 111
+#define DSA_F_SIG_CB					 114
+
+/* Reason codes. */
+#define DSA_R_BAD_Q_VALUE				 102
+#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
+#define DSA_R_MISSING_PARAMETERS			 101
+#define DSA_R_MODULUS_TOO_LARGE				 103
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/dso.h b/dep/include/openssl/dso.h
new file mode 100644
index 000000000..3e51913a7
--- /dev/null
+++ b/dep/include/openssl/dso.h
@@ -0,0 +1,368 @@
+/* dso.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DSO_H
+#define HEADER_DSO_H
+
+#include 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These values are used as commands to DSO_ctrl() */
+#define DSO_CTRL_GET_FLAGS	1
+#define DSO_CTRL_SET_FLAGS	2
+#define DSO_CTRL_OR_FLAGS	3
+
+/* By default, DSO_load() will translate the provided filename into a form
+ * typical for the platform (more specifically the DSO_METHOD) using the
+ * dso_name_converter function of the method. Eg. win32 will transform "blah"
+ * into "blah.dll", and dlfcn will transform it into "libblah.so". The
+ * behaviour can be overriden by setting the name_converter callback in the DSO
+ * object (using DSO_set_name_converter()). This callback could even utilise
+ * the DSO_METHOD's converter too if it only wants to override behaviour for
+ * one or two possible DSO methods. However, the following flag can be set in a
+ * DSO to prevent *any* native name-translation at all - eg. if the caller has
+ * prompted the user for a path to a driver library so the filename should be
+ * interpreted as-is. */
+#define DSO_FLAG_NO_NAME_TRANSLATION		0x01
+/* An extra flag to give if only the extension should be added as
+ * translation.  This is obviously only of importance on Unix and
+ * other operating systems where the translation also may prefix
+ * the name with something, like 'lib', and ignored everywhere else.
+ * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used
+ * at the same time. */
+#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY	0x02
+
+/* The following flag controls the translation of symbol names to upper
+ * case.  This is currently only being implemented for OpenVMS.
+ */
+#define DSO_FLAG_UPCASE_SYMBOL			0x10
+
+/* This flag loads the library with public symbols.
+ * Meaning: The exported symbols of this library are public
+ * to all libraries loaded after this library.
+ * At the moment only implemented in unix.
+ */
+#define DSO_FLAG_GLOBAL_SYMBOLS			0x20
+
+
+typedef void (*DSO_FUNC_TYPE)(void);
+
+typedef struct dso_st DSO;
+
+/* The function prototype used for method functions (or caller-provided
+ * callbacks) that transform filenames. They are passed a DSO structure pointer
+ * (or NULL if they are to be used independantly of a DSO object) and a
+ * filename to transform. They should either return NULL (if there is an error
+ * condition) or a newly allocated string containing the transformed form that
+ * the caller will need to free with OPENSSL_free() when done. */
+typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
+/* The function prototype used for method functions (or caller-provided
+ * callbacks) that merge two file specifications. They are passed a
+ * DSO structure pointer (or NULL if they are to be used independantly of
+ * a DSO object) and two file specifications to merge. They should
+ * either return NULL (if there is an error condition) or a newly allocated
+ * string containing the result of merging that the caller will need
+ * to free with OPENSSL_free() when done.
+ * Here, merging means that bits and pieces are taken from each of the
+ * file specifications and added together in whatever fashion that is
+ * sensible for the DSO method in question.  The only rule that really
+ * applies is that if the two specification contain pieces of the same
+ * type, the copy from the first string takes priority.  One could see
+ * it as the first specification is the one given by the user and the
+ * second being a bunch of defaults to add on if they're missing in the
+ * first. */
+typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
+
+typedef struct dso_meth_st
+	{
+	const char *name;
+	/* Loads a shared library, NB: new DSO_METHODs must ensure that a
+	 * successful load populates the loaded_filename field, and likewise a
+	 * successful unload OPENSSL_frees and NULLs it out. */
+	int (*dso_load)(DSO *dso);
+	/* Unloads a shared library */
+	int (*dso_unload)(DSO *dso);
+	/* Binds a variable */
+	void *(*dso_bind_var)(DSO *dso, const char *symname);
+	/* Binds a function - assumes a return type of DSO_FUNC_TYPE.
+	 * This should be cast to the real function prototype by the
+	 * caller. Platforms that don't have compatible representations
+	 * for different prototypes (this is possible within ANSI C)
+	 * are highly unlikely to have shared libraries at all, let
+	 * alone a DSO_METHOD implemented for them. */
+	DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname);
+
+/* I don't think this would actually be used in any circumstances. */
+#if 0
+	/* Unbinds a variable */
+	int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr);
+	/* Unbinds a function */
+	int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+#endif
+	/* The generic (yuck) "ctrl()" function. NB: Negative return
+	 * values (rather than zero) indicate errors. */
+	long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);
+	/* The default DSO_METHOD-specific function for converting filenames to
+	 * a canonical native form. */
+	DSO_NAME_CONVERTER_FUNC dso_name_converter;
+	/* The default DSO_METHOD-specific function for converting filenames to
+	 * a canonical native form. */
+	DSO_MERGER_FUNC dso_merger;
+
+	/* [De]Initialisation handlers. */
+	int (*init)(DSO *dso);
+	int (*finish)(DSO *dso);
+	} DSO_METHOD;
+
+/**********************************************************************/
+/* The low-level handle type used to refer to a loaded shared library */
+
+struct dso_st
+	{
+	DSO_METHOD *meth;
+	/* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS
+	 * doesn't use anything but will need to cache the filename
+	 * for use in the dso_bind handler. All in all, let each
+	 * method control its own destiny. "Handles" and such go in
+	 * a STACK. */
+	STACK *meth_data;
+	int references;
+	int flags;
+	/* For use by applications etc ... use this for your bits'n'pieces,
+	 * don't touch meth_data! */
+	CRYPTO_EX_DATA ex_data;
+	/* If this callback function pointer is set to non-NULL, then it will
+	 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
+	 * should normally set using DSO_set_name_converter(). */
+	DSO_NAME_CONVERTER_FUNC name_converter;
+	/* If this callback function pointer is set to non-NULL, then it will
+	 * be used in DSO_load() in place of meth->dso_merger. NB: This
+	 * should normally set using DSO_set_merger(). */
+	DSO_MERGER_FUNC merger;
+	/* This is populated with (a copy of) the platform-independant
+	 * filename used for this DSO. */
+	char *filename;
+	/* This is populated with (a copy of) the translated filename by which
+	 * the DSO was actually loaded. It is NULL iff the DSO is not currently
+	 * loaded. NB: This is here because the filename translation process
+	 * may involve a callback being invoked more than once not only to
+	 * convert to a platform-specific form, but also to try different
+	 * filenames in the process of trying to perform a load. As such, this
+	 * variable can be used to indicate (a) whether this DSO structure
+	 * corresponds to a loaded library or not, and (b) the filename with
+	 * which it was actually loaded. */
+	char *loaded_filename;
+	};
+
+
+DSO *	DSO_new(void);
+DSO *	DSO_new_method(DSO_METHOD *method);
+int	DSO_free(DSO *dso);
+int	DSO_flags(DSO *dso);
+int	DSO_up_ref(DSO *dso);
+long	DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
+
+/* This function sets the DSO's name_converter callback. If it is non-NULL,
+ * then it will be used instead of the associated DSO_METHOD's function. If
+ * oldcb is non-NULL then it is set to the function pointer value being
+ * replaced. Return value is non-zero for success. */
+int	DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+				DSO_NAME_CONVERTER_FUNC *oldcb);
+/* These functions can be used to get/set the platform-independant filename
+ * used for a DSO. NB: set will fail if the DSO is already loaded. */
+const char *DSO_get_filename(DSO *dso);
+int	DSO_set_filename(DSO *dso, const char *filename);
+/* This function will invoke the DSO's name_converter callback to translate a
+ * filename, or if the callback isn't set it will instead use the DSO_METHOD's
+ * converter. If "filename" is NULL, the "filename" in the DSO itself will be
+ * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
+ * simply duplicated. NB: This function is usually called from within a
+ * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that
+ * caller-created DSO_METHODs can do the same thing. A non-NULL return value
+ * will need to be OPENSSL_free()'d. */
+char	*DSO_convert_filename(DSO *dso, const char *filename);
+/* This function will invoke the DSO's merger callback to merge two file
+ * specifications, or if the callback isn't set it will instead use the
+ * DSO_METHOD's merger.  A non-NULL return value will need to be
+ * OPENSSL_free()'d. */
+char	*DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
+/* If the DSO is currently loaded, this returns the filename that it was loaded
+ * under, otherwise it returns NULL. So it is also useful as a test as to
+ * whether the DSO is currently loaded. NB: This will not necessarily return
+ * the same value as DSO_convert_filename(dso, dso->filename), because the
+ * DSO_METHOD's load function may have tried a variety of filenames (with
+ * and/or without the aid of the converters) before settling on the one it
+ * actually loaded. */
+const char *DSO_get_loaded_filename(DSO *dso);
+
+void	DSO_set_default_method(DSO_METHOD *meth);
+DSO_METHOD *DSO_get_default_method(void);
+DSO_METHOD *DSO_get_method(DSO *dso);
+DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
+
+/* The all-singing all-dancing load function, you normally pass NULL
+ * for the first and third parameters. Use DSO_up and DSO_free for
+ * subsequent reference count handling. Any flags passed in will be set
+ * in the constructed DSO after its init() function but before the
+ * load operation. If 'dso' is non-NULL, 'flags' is ignored. */
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
+
+/* This function binds to a variable inside a shared library. */
+void *DSO_bind_var(DSO *dso, const char *symname);
+
+/* This function binds to a function inside a shared library. */
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
+
+/* This method is the default, but will beg, borrow, or steal whatever
+ * method should be the default on any particular platform (including
+ * DSO_METH_null() if necessary). */
+DSO_METHOD *DSO_METHOD_openssl(void);
+
+/* This method is defined for all platforms - if a platform has no
+ * DSO support then this will be the only method! */
+DSO_METHOD *DSO_METHOD_null(void);
+
+/* If DSO_DLFCN is defined, the standard dlfcn.h-style functions
+ * (dlopen, dlclose, dlsym, etc) will be used and incorporated into
+ * this method. If not, this method will return NULL. */
+DSO_METHOD *DSO_METHOD_dlfcn(void);
+
+/* If DSO_DL is defined, the standard dl.h-style functions (shl_load, 
+ * shl_unload, shl_findsym, etc) will be used and incorporated into
+ * this method. If not, this method will return NULL. */
+DSO_METHOD *DSO_METHOD_dl(void);
+
+/* If WIN32 is defined, use DLLs. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_win32(void);
+
+/* If VMS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_vms(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSO_strings(void);
+
+/* Error codes for the DSO functions. */
+
+/* Function codes. */
+#define DSO_F_DLFCN_BIND_FUNC				 100
+#define DSO_F_DLFCN_BIND_VAR				 101
+#define DSO_F_DLFCN_LOAD				 102
+#define DSO_F_DLFCN_MERGER				 130
+#define DSO_F_DLFCN_NAME_CONVERTER			 123
+#define DSO_F_DLFCN_UNLOAD				 103
+#define DSO_F_DL_BIND_FUNC				 104
+#define DSO_F_DL_BIND_VAR				 105
+#define DSO_F_DL_LOAD					 106
+#define DSO_F_DL_MERGER					 131
+#define DSO_F_DL_NAME_CONVERTER				 124
+#define DSO_F_DL_UNLOAD					 107
+#define DSO_F_DSO_BIND_FUNC				 108
+#define DSO_F_DSO_BIND_VAR				 109
+#define DSO_F_DSO_CONVERT_FILENAME			 126
+#define DSO_F_DSO_CTRL					 110
+#define DSO_F_DSO_FREE					 111
+#define DSO_F_DSO_GET_FILENAME				 127
+#define DSO_F_DSO_GET_LOADED_FILENAME			 128
+#define DSO_F_DSO_LOAD					 112
+#define DSO_F_DSO_MERGE					 132
+#define DSO_F_DSO_NEW_METHOD				 113
+#define DSO_F_DSO_SET_FILENAME				 129
+#define DSO_F_DSO_SET_NAME_CONVERTER			 122
+#define DSO_F_DSO_UP_REF				 114
+#define DSO_F_VMS_BIND_SYM				 115
+#define DSO_F_VMS_LOAD					 116
+#define DSO_F_VMS_MERGER				 133
+#define DSO_F_VMS_UNLOAD				 117
+#define DSO_F_WIN32_BIND_FUNC				 118
+#define DSO_F_WIN32_BIND_VAR				 119
+#define DSO_F_WIN32_JOINER				 135
+#define DSO_F_WIN32_LOAD				 120
+#define DSO_F_WIN32_MERGER				 134
+#define DSO_F_WIN32_NAME_CONVERTER			 125
+#define DSO_F_WIN32_SPLITTER				 136
+#define DSO_F_WIN32_UNLOAD				 121
+
+/* Reason codes. */
+#define DSO_R_CTRL_FAILED				 100
+#define DSO_R_DSO_ALREADY_LOADED			 110
+#define DSO_R_EMPTY_FILE_STRUCTURE			 113
+#define DSO_R_FAILURE					 114
+#define DSO_R_FILENAME_TOO_BIG				 101
+#define DSO_R_FINISH_FAILED				 102
+#define DSO_R_INCORRECT_FILE_SYNTAX			 115
+#define DSO_R_LOAD_FAILED				 103
+#define DSO_R_NAME_TRANSLATION_FAILED			 109
+#define DSO_R_NO_FILENAME				 111
+#define DSO_R_NO_FILE_SPECIFICATION			 116
+#define DSO_R_NULL_HANDLE				 104
+#define DSO_R_SET_FILENAME_FAILED			 112
+#define DSO_R_STACK_ERROR				 105
+#define DSO_R_SYM_FAILURE				 106
+#define DSO_R_UNLOAD_FAILED				 107
+#define DSO_R_UNSUPPORTED				 108
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/dtls1.h b/dep/include/openssl/dtls1.h
new file mode 100644
index 000000000..b377cc5f6
--- /dev/null
+++ b/dep/include/openssl/dtls1.h
@@ -0,0 +1,212 @@
+/* ssl/dtls1.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DTLS1_H 
+#define HEADER_DTLS1_H 
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define DTLS1_VERSION			0x0100
+#define DTLS1_VERSION_MAJOR		0x01
+#define DTLS1_VERSION_MINOR		0x00
+
+#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
+
+/* lengths of messages */
+#define DTLS1_COOKIE_LENGTH                     32
+
+#define DTLS1_RT_HEADER_LENGTH                  13
+
+#define DTLS1_HM_HEADER_LENGTH                  12
+
+#define DTLS1_HM_BAD_FRAGMENT                   -2
+#define DTLS1_HM_FRAGMENT_RETRY                 -3
+
+#define DTLS1_CCS_HEADER_LENGTH                  3
+
+#define DTLS1_AL_HEADER_LENGTH                   7
+
+
+typedef struct dtls1_bitmap_st
+	{
+	PQ_64BIT map;
+	unsigned long length;     /* sizeof the bitmap in bits */
+	PQ_64BIT max_seq_num;  /* max record number seen so far */
+	} DTLS1_BITMAP;
+
+struct hm_header_st
+	{
+	unsigned char type;
+	unsigned long msg_len;
+	unsigned short seq;
+	unsigned long frag_off;
+	unsigned long frag_len;
+	unsigned int is_ccs;
+	};
+
+struct ccs_header_st
+	{
+	unsigned char type;
+	unsigned short seq;
+	};
+
+struct dtls1_timeout_st
+	{
+	/* Number of read timeouts so far */
+	unsigned int read_timeouts;
+	
+	/* Number of write timeouts so far */
+	unsigned int write_timeouts;
+	
+	/* Number of alerts received so far */
+	unsigned int num_alerts;
+	};
+
+typedef struct record_pqueue_st
+	{
+	unsigned short epoch;
+	pqueue q;
+	} record_pqueue;
+
+typedef struct hm_fragment_st
+	{
+	struct hm_header_st msg_header;
+	unsigned char *fragment;
+	} hm_fragment;
+
+typedef struct dtls1_state_st
+	{
+	unsigned int send_cookie;
+	unsigned char cookie[DTLS1_COOKIE_LENGTH];
+	unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
+	unsigned int cookie_len;
+
+	/* 
+	 * The current data and handshake epoch.  This is initially
+	 * undefined, and starts at zero once the initial handshake is
+	 * completed 
+	 */
+	unsigned short r_epoch;
+	unsigned short w_epoch;
+
+	/* records being received in the current epoch */
+	DTLS1_BITMAP bitmap;
+
+	/* renegotiation starts a new set of sequence numbers */
+	DTLS1_BITMAP next_bitmap;
+
+	/* handshake message numbers */
+	unsigned short handshake_write_seq;
+	unsigned short next_handshake_write_seq;
+
+	unsigned short handshake_read_seq;
+
+	/* Received handshake records (processed and unprocessed) */
+	record_pqueue unprocessed_rcds;
+	record_pqueue processed_rcds;
+
+	/* Buffered handshake messages */
+	pqueue buffered_messages;
+
+	/* Buffered (sent) handshake records */
+	pqueue sent_messages;
+
+	unsigned int mtu; /* max wire packet size */
+
+	struct hm_header_st w_msg_hdr;
+	struct hm_header_st r_msg_hdr;
+
+	struct dtls1_timeout_st timeout;
+	
+	/* storage for Alert/Handshake protocol data received but not
+	 * yet processed by ssl3_read_bytes: */
+	unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
+	unsigned int alert_fragment_len;
+	unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
+	unsigned int handshake_fragment_len;
+
+	unsigned int retransmitting;
+
+	} DTLS1_STATE;
+
+typedef struct dtls1_record_data_st
+	{
+	unsigned char *packet;
+	unsigned int   packet_length;
+	SSL3_BUFFER    rbuf;
+	SSL3_RECORD    rrec;
+	} DTLS1_RECORD_DATA;
+
+
+/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
+#define DTLS1_TMO_READ_COUNT                      2
+#define DTLS1_TMO_WRITE_COUNT                     2
+
+#define DTLS1_TMO_ALERT_COUNT                     12
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/e_os2.h b/dep/include/openssl/e_os2.h
new file mode 100644
index 000000000..9da0b6544
--- /dev/null
+++ b/dep/include/openssl/e_os2.h
@@ -0,0 +1,279 @@
+/* e_os2.h */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#ifndef HEADER_E_OS2_H
+#define HEADER_E_OS2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * Detect operating systems.  This probably needs completing.
+ * The result is that at least one OPENSSL_SYS_os macro should be defined.
+ * However, if none is defined, Unix is assumed.
+ **/
+
+#define OPENSSL_SYS_UNIX
+
+/* ----------------------- Macintosh, before MacOS X ----------------------- */
+#if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MACINTOSH_CLASSIC
+#endif
+
+/* ----------------------- NetWare ----------------------------------------- */
+#if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_NETWARE
+#endif
+
+/* ---------------------- Microsoft operating systems ---------------------- */
+
+/* Note that MSDOS actually denotes 32-bit environments running on top of
+   MS-DOS, such as DJGPP one. */
+#if defined(OPENSSL_SYSNAME_MSDOS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MSDOS
+#endif
+
+/* For 32 bit environment, there seems to be the CygWin environment and then
+   all the others that try to do the same thing Microsoft does... */
+#if defined(OPENSSL_SYSNAME_UWIN)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN32_UWIN
+#else
+# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WIN32_CYGWIN
+# else
+#  if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WIN32
+#  endif
+#  if defined(OPENSSL_SYSNAME_WINNT)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WINNT
+#  endif
+#  if defined(OPENSSL_SYSNAME_WINCE)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WINCE
+#  endif
+# endif
+#endif
+
+/* Anything that tries to look like Microsoft is "Windows" */
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_SYS_MSDOS
+#  define OPENSSL_SYS_MSDOS
+# endif
+#endif
+
+/* DLL settings.  This part is a bit tough, because it's up to the application
+   implementor how he or she will link the application, so it requires some
+   macro to be used. */
+#ifdef OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_OPT_WINDLL
+#  if defined(_WINDLL) /* This is used when building OpenSSL to indicate that
+                          DLL linkage should be used */
+#   define OPENSSL_OPT_WINDLL
+#  endif
+# endif
+#endif
+
+/* -------------------------------- OpenVMS -------------------------------- */
+#if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_VMS
+# if defined(__DECC)
+#  define OPENSSL_SYS_VMS_DECC
+# elif defined(__DECCXX)
+#  define OPENSSL_SYS_VMS_DECC
+#  define OPENSSL_SYS_VMS_DECCXX
+# else
+#  define OPENSSL_SYS_VMS_NODECC
+# endif
+#endif
+
+/* --------------------------------- OS/2 ---------------------------------- */
+#if defined(__EMX__) || defined(__OS2__)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_OS2
+#endif
+
+/* --------------------------------- Unix ---------------------------------- */
+#ifdef OPENSSL_SYS_UNIX
+# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
+#  define OPENSSL_SYS_LINUX
+# endif
+# ifdef OPENSSL_SYSNAME_MPE
+#  define OPENSSL_SYS_MPE
+# endif
+# ifdef OPENSSL_SYSNAME_SNI
+#  define OPENSSL_SYS_SNI
+# endif
+# ifdef OPENSSL_SYSNAME_ULTRASPARC
+#  define OPENSSL_SYS_ULTRASPARC
+# endif
+# ifdef OPENSSL_SYSNAME_NEWS4
+#  define OPENSSL_SYS_NEWS4
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX
+#  define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
+#  define OPENSSL_SYS_MACOSX_RHAPSODY
+#  define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_SUNOS
+#  define OPENSSL_SYS_SUNOS
+#endif
+# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
+#  define OPENSSL_SYS_CRAY
+# endif
+# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
+#  define OPENSSL_SYS_AIX
+# endif
+#endif
+
+/* --------------------------------- VOS ----------------------------------- */
+#ifdef OPENSSL_SYSNAME_VOS
+# define OPENSSL_SYS_VOS
+#endif
+
+/* ------------------------------- VxWorks --------------------------------- */
+#ifdef OPENSSL_SYSNAME_VXWORKS
+# define OPENSSL_SYS_VXWORKS
+#endif
+
+/**
+ * That's it for OS-specific stuff
+ *****************************************************************************/
+
+
+/* Specials for I/O an exit */
+#ifdef OPENSSL_SYS_MSDOS
+# define OPENSSL_UNISTD_IO 
+# define OPENSSL_DECLARE_EXIT extern void exit(int);
+#else
+# define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */
+#endif
+
+/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
+   certain global symbols that, with some compilers under VMS, have to be
+   defined and declared explicitely with globaldef and globalref.
+   Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
+   DLL exports and imports for compilers under Win32.  These are a little
+   more complicated to use.  Basically, for any library that exports some
+   global variables, the following code must be present in the header file
+   that declares them, before OPENSSL_EXTERN is used:
+
+   #ifdef SOME_BUILD_FLAG_MACRO
+   # undef OPENSSL_EXTERN
+   # define OPENSSL_EXTERN OPENSSL_EXPORT
+   #endif
+
+   The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
+   have some generally sensible values, and for OPENSSL_EXTERN to have the
+   value OPENSSL_IMPORT.
+*/
+
+#if defined(OPENSSL_SYS_VMS_NODECC)
+# define OPENSSL_EXPORT globalref
+# define OPENSSL_IMPORT globalref
+# define OPENSSL_GLOBAL globaldef
+#elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
+# define OPENSSL_EXPORT extern __declspec(dllexport)
+# define OPENSSL_IMPORT extern __declspec(dllimport)
+# define OPENSSL_GLOBAL
+#else
+# define OPENSSL_EXPORT extern
+# define OPENSSL_IMPORT extern
+# define OPENSSL_GLOBAL
+#endif
+#define OPENSSL_EXTERN OPENSSL_IMPORT
+
+/* Macros to allow global variables to be reached through function calls when
+   required (if a shared library version requvres it, for example.
+   The way it's done allows definitions like this:
+
+	// in foobar.c
+	OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+	// in foobar.h
+	OPENSSL_DECLARE_GLOBAL(int,foobar);
+	#define foobar OPENSSL_GLOBAL_REF(foobar)
+*/
+#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name)			     \
+	extern type _hide_##name;				     \
+	type *_shadow_##name(void) { return &_hide_##name; }	     \
+	static type _hide_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+#else
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+# define OPENSSL_GLOBAL_REF(name) _shadow_##name
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/ebcdic.h b/dep/include/openssl/ebcdic.h
new file mode 100644
index 000000000..6d65afcf9
--- /dev/null
+++ b/dep/include/openssl/ebcdic.h
@@ -0,0 +1,19 @@
+/* crypto/ebcdic.h */
+
+#ifndef HEADER_EBCDIC_H
+#define HEADER_EBCDIC_H
+
+#include 
+
+/* Avoid name clashes with other applications */
+#define os_toascii   _openssl_os_toascii
+#define os_toebcdic  _openssl_os_toebcdic
+#define ebcdic2ascii _openssl_ebcdic2ascii
+#define ascii2ebcdic _openssl_ascii2ebcdic
+
+extern const unsigned char os_toascii[256];
+extern const unsigned char os_toebcdic[256];
+void *ebcdic2ascii(void *dest, const void *srce, size_t count);
+void *ascii2ebcdic(void *dest, const void *srce, size_t count);
+
+#endif
diff --git a/dep/include/openssl/ec.h b/dep/include/openssl/ec.h
new file mode 100644
index 000000000..3c96fbd0d
--- /dev/null
+++ b/dep/include/openssl/ec.h
@@ -0,0 +1,525 @@
+/* crypto/ec/ec.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_EC_H
+#define HEADER_EC_H
+
+#include 
+
+#ifdef OPENSSL_NO_EC
+#error EC is disabled.
+#endif
+
+#include 
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#elif defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+
+#ifndef OPENSSL_ECC_MAX_FIELD_BITS
+# define OPENSSL_ECC_MAX_FIELD_BITS 661
+#endif
+
+typedef enum {
+	/* values as defined in X9.62 (ECDSA) and elsewhere */
+	POINT_CONVERSION_COMPRESSED = 2,
+	POINT_CONVERSION_UNCOMPRESSED = 4,
+	POINT_CONVERSION_HYBRID = 6
+} point_conversion_form_t;
+
+
+typedef struct ec_method_st EC_METHOD;
+
+typedef struct ec_group_st
+	/*
+	 EC_METHOD *meth;
+	 -- field definition
+	 -- curve coefficients
+	 -- optional generator with associated information (order, cofactor)
+	 -- optional extra data (precomputed table for fast computation of multiples of generator)
+	 -- ASN1 stuff
+	*/
+	EC_GROUP;
+
+typedef struct ec_point_st EC_POINT;
+
+
+/* EC_METHODs for curves over GF(p).
+ * EC_GFp_simple_method provides the basis for the optimized methods.
+ */
+const EC_METHOD *EC_GFp_simple_method(void);
+const EC_METHOD *EC_GFp_mont_method(void);
+const EC_METHOD *EC_GFp_nist_method(void);
+
+/* EC_METHOD for curves over GF(2^m).
+ */
+const EC_METHOD *EC_GF2m_simple_method(void);
+
+
+EC_GROUP *EC_GROUP_new(const EC_METHOD *);
+void EC_GROUP_free(EC_GROUP *);
+void EC_GROUP_clear_free(EC_GROUP *);
+int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
+
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
+int EC_METHOD_get_field_type(const EC_METHOD *);
+
+int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
+int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
+int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+
+void EC_GROUP_set_curve_name(EC_GROUP *, int nid);
+int EC_GROUP_get_curve_name(const EC_GROUP *);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *);
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
+size_t EC_GROUP_get_seed_len(const EC_GROUP *);
+size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
+
+int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+
+/* returns the number of bits needed to represent a field element */
+int EC_GROUP_get_degree(const EC_GROUP *);
+
+/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
+/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
+ * elliptic curve is not zero, 0 otherwise */
+int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
+
+/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */
+int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *);
+
+/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
+ * after choosing an appropriate EC_METHOD */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+
+/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure
+ * specified by a curve name (in form of a NID) */
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
+/* handling of internal curves */
+typedef struct { 
+	int nid;
+	const char *comment;
+	} EC_builtin_curve;
+/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 
+ * of all available curves or zero if a error occurred. 
+ * In case r ist not zero nitems EC_builtin_curve structures 
+ * are filled with the data of the first nitems internal groups */
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
+
+
+/* EC_POINT functions */
+
+EC_POINT *EC_POINT_new(const EC_GROUP *);
+void EC_POINT_free(EC_POINT *);
+void EC_POINT_clear_free(EC_POINT *);
+int EC_POINT_copy(EC_POINT *, const EC_POINT *);
+EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
+ 
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
+
+int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+
+size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+        unsigned char *buf, size_t len, BN_CTX *);
+int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
+        const unsigned char *buf, size_t len, BN_CTX *);
+
+/* other interfaces to point2oct/oct2point: */
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
+	point_conversion_form_t form, BIGNUM *, BN_CTX *);
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
+	EC_POINT *, BN_CTX *);
+char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
+	point_conversion_form_t form, BN_CTX *);
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
+	EC_POINT *, BN_CTX *);
+
+int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+
+int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+
+int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+
+
+int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *);
+int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *);
+
+/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */
+int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
+/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *);
+
+
+
+/* ASN1 stuff */
+
+/* EC_GROUP_get_basis_type() returns the NID of the basis type
+ * used to represent the field elements */
+int EC_GROUP_get_basis_type(const EC_GROUP *);
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, 
+	unsigned int *k2, unsigned int *k3);
+
+#define OPENSSL_EC_NAMED_CURVE	0x001
+
+typedef struct ecpk_parameters_st ECPKPARAMETERS;
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
+int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
+
+#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
+#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
+#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
+                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
+#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
+		(unsigned char *)(x))
+
+#ifndef OPENSSL_NO_BIO
+int     ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int     ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
+#endif
+
+/* the EC_KEY stuff */
+typedef struct ec_key_st EC_KEY;
+
+/* some values for the encoding_flag */
+#define EC_PKEY_NO_PARAMETERS	0x001
+#define EC_PKEY_NO_PUBKEY	0x002
+
+EC_KEY *EC_KEY_new(void);
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
+void EC_KEY_free(EC_KEY *);
+EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
+EC_KEY *EC_KEY_dup(const EC_KEY *);
+
+int EC_KEY_up_ref(EC_KEY *);
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
+int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
+int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
+int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
+unsigned EC_KEY_get_enc_flags(const EC_KEY *);
+void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
+void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+/* functions to set/get method specific data  */
+void *EC_KEY_get_key_method_data(EC_KEY *, 
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *, int);
+int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx);
+
+/* EC_KEY_generate_key() creates a ec private (public) key */
+int EC_KEY_generate_key(EC_KEY *);
+/* EC_KEY_check_key() */
+int EC_KEY_check_key(const EC_KEY *);
+
+/* de- and encoding functions for SEC1 ECPrivateKey */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
+/* de- and encoding functions for EC parameters */
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
+int i2d_ECParameters(EC_KEY *a, unsigned char **out);
+/* de- and encoding functions for EC public key
+ * (octet string, not DER -- hence 'o2i' and 'i2o') */
+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len);
+int i2o_ECPublicKey(EC_KEY *a, unsigned char **out);
+
+#ifndef OPENSSL_NO_BIO
+int	ECParameters_print(BIO *bp, const EC_KEY *x);
+int	EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int	ECParameters_print_fp(FILE *fp, const EC_KEY *x);
+int	EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
+#endif
+
+#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
+
+#ifndef __cplusplus
+#if defined(__SUNPRO_C)
+#  if __SUNPRO_C >= 0x520
+# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+#  endif
+# endif
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EC_strings(void);
+
+/* Error codes for the EC functions. */
+
+/* Function codes. */
+#define EC_F_COMPUTE_WNAF				 143
+#define EC_F_D2I_ECPARAMETERS				 144
+#define EC_F_D2I_ECPKPARAMETERS				 145
+#define EC_F_D2I_ECPRIVATEKEY				 146
+#define EC_F_ECPARAMETERS_PRINT				 147
+#define EC_F_ECPARAMETERS_PRINT_FP			 148
+#define EC_F_ECPKPARAMETERS_PRINT			 149
+#define EC_F_ECPKPARAMETERS_PRINT_FP			 150
+#define EC_F_ECP_NIST_MOD_192				 203
+#define EC_F_ECP_NIST_MOD_224				 204
+#define EC_F_ECP_NIST_MOD_256				 205
+#define EC_F_ECP_NIST_MOD_521				 206
+#define EC_F_EC_ASN1_GROUP2CURVE			 153
+#define EC_F_EC_ASN1_GROUP2FIELDID			 154
+#define EC_F_EC_ASN1_GROUP2PARAMETERS			 155
+#define EC_F_EC_ASN1_GROUP2PKPARAMETERS			 156
+#define EC_F_EC_ASN1_PARAMETERS2GROUP			 157
+#define EC_F_EC_ASN1_PKPARAMETERS2GROUP			 158
+#define EC_F_EC_EX_DATA_SET_DATA			 211
+#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY		 208
+#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT	 159
+#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE		 195
+#define EC_F_EC_GF2M_SIMPLE_OCT2POINT			 160
+#define EC_F_EC_GF2M_SIMPLE_POINT2OCT			 161
+#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
+#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
+#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES	 164
+#define EC_F_EC_GFP_MONT_FIELD_DECODE			 133
+#define EC_F_EC_GFP_MONT_FIELD_ENCODE			 134
+#define EC_F_EC_GFP_MONT_FIELD_MUL			 131
+#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE		 209
+#define EC_F_EC_GFP_MONT_FIELD_SQR			 132
+#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE		 189
+#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP		 135
+#define EC_F_EC_GFP_NIST_FIELD_MUL			 200
+#define EC_F_EC_GFP_NIST_FIELD_SQR			 201
+#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE		 202
+#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT	 165
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE		 166
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP		 100
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR		 101
+#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE			 102
+#define EC_F_EC_GFP_SIMPLE_OCT2POINT			 103
+#define EC_F_EC_GFP_SIMPLE_POINT2OCT			 104
+#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE		 137
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES	 167
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES	 168
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES	 169
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
+#define EC_F_EC_GROUP_CHECK				 170
+#define EC_F_EC_GROUP_CHECK_DISCRIMINANT		 171
+#define EC_F_EC_GROUP_COPY				 106
+#define EC_F_EC_GROUP_GET0_GENERATOR			 139
+#define EC_F_EC_GROUP_GET_COFACTOR			 140
+#define EC_F_EC_GROUP_GET_CURVE_GF2M			 172
+#define EC_F_EC_GROUP_GET_CURVE_GFP			 130
+#define EC_F_EC_GROUP_GET_DEGREE			 173
+#define EC_F_EC_GROUP_GET_ORDER				 141
+#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS		 193
+#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS		 194
+#define EC_F_EC_GROUP_NEW				 108
+#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME			 174
+#define EC_F_EC_GROUP_NEW_FROM_DATA			 175
+#define EC_F_EC_GROUP_PRECOMPUTE_MULT			 142
+#define EC_F_EC_GROUP_SET_CURVE_GF2M			 176
+#define EC_F_EC_GROUP_SET_CURVE_GFP			 109
+#define EC_F_EC_GROUP_SET_EXTRA_DATA			 110
+#define EC_F_EC_GROUP_SET_GENERATOR			 111
+#define EC_F_EC_KEY_CHECK_KEY				 177
+#define EC_F_EC_KEY_COPY				 178
+#define EC_F_EC_KEY_GENERATE_KEY			 179
+#define EC_F_EC_KEY_NEW					 182
+#define EC_F_EC_KEY_PRINT				 180
+#define EC_F_EC_KEY_PRINT_FP				 181
+#define EC_F_EC_POINTS_MAKE_AFFINE			 136
+#define EC_F_EC_POINTS_MUL				 138
+#define EC_F_EC_POINT_ADD				 112
+#define EC_F_EC_POINT_CMP				 113
+#define EC_F_EC_POINT_COPY				 114
+#define EC_F_EC_POINT_DBL				 115
+#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M	 183
+#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP	 116
+#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP	 117
+#define EC_F_EC_POINT_INVERT				 210
+#define EC_F_EC_POINT_IS_AT_INFINITY			 118
+#define EC_F_EC_POINT_IS_ON_CURVE			 119
+#define EC_F_EC_POINT_MAKE_AFFINE			 120
+#define EC_F_EC_POINT_MUL				 184
+#define EC_F_EC_POINT_NEW				 121
+#define EC_F_EC_POINT_OCT2POINT				 122
+#define EC_F_EC_POINT_POINT2OCT				 123
+#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M	 185
+#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP	 124
+#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M	 186
+#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP	 125
+#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP	 126
+#define EC_F_EC_POINT_SET_TO_INFINITY			 127
+#define EC_F_EC_PRE_COMP_DUP				 207
+#define EC_F_EC_WNAF_MUL				 187
+#define EC_F_EC_WNAF_PRECOMPUTE_MULT			 188
+#define EC_F_I2D_ECPARAMETERS				 190
+#define EC_F_I2D_ECPKPARAMETERS				 191
+#define EC_F_I2D_ECPRIVATEKEY				 192
+#define EC_F_I2O_ECPUBLICKEY				 151
+#define EC_F_O2I_ECPUBLICKEY				 152
+
+/* Reason codes. */
+#define EC_R_ASN1_ERROR					 115
+#define EC_R_ASN1_UNKNOWN_FIELD				 116
+#define EC_R_BUFFER_TOO_SMALL				 100
+#define EC_R_D2I_ECPKPARAMETERS_FAILURE			 117
+#define EC_R_DISCRIMINANT_IS_ZERO			 118
+#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE		 119
+#define EC_R_FIELD_TOO_LARGE				 138
+#define EC_R_GROUP2PKPARAMETERS_FAILURE			 120
+#define EC_R_I2D_ECPKPARAMETERS_FAILURE			 121
+#define EC_R_INCOMPATIBLE_OBJECTS			 101
+#define EC_R_INVALID_ARGUMENT				 112
+#define EC_R_INVALID_COMPRESSED_POINT			 110
+#define EC_R_INVALID_COMPRESSION_BIT			 109
+#define EC_R_INVALID_ENCODING				 102
+#define EC_R_INVALID_FIELD				 103
+#define EC_R_INVALID_FORM				 104
+#define EC_R_INVALID_GROUP_ORDER			 122
+#define EC_R_INVALID_PENTANOMIAL_BASIS			 132
+#define EC_R_INVALID_PRIVATE_KEY			 123
+#define EC_R_INVALID_TRINOMIAL_BASIS			 137
+#define EC_R_MISSING_PARAMETERS				 124
+#define EC_R_MISSING_PRIVATE_KEY			 125
+#define EC_R_NOT_A_NIST_PRIME				 135
+#define EC_R_NOT_A_SUPPORTED_NIST_PRIME			 136
+#define EC_R_NOT_IMPLEMENTED				 126
+#define EC_R_NOT_INITIALIZED				 111
+#define EC_R_NO_FIELD_MOD				 133
+#define EC_R_PASSED_NULL_PARAMETER			 134
+#define EC_R_PKPARAMETERS2GROUP_FAILURE			 127
+#define EC_R_POINT_AT_INFINITY				 106
+#define EC_R_POINT_IS_NOT_ON_CURVE			 107
+#define EC_R_SLOT_FULL					 108
+#define EC_R_UNDEFINED_GENERATOR			 113
+#define EC_R_UNDEFINED_ORDER				 128
+#define EC_R_UNKNOWN_GROUP				 129
+#define EC_R_UNKNOWN_ORDER				 114
+#define EC_R_UNSUPPORTED_FIELD				 131
+#define EC_R_WRONG_ORDER				 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/ecdh.h b/dep/include/openssl/ecdh.h
new file mode 100644
index 000000000..b4b58ee65
--- /dev/null
+++ b/dep/include/openssl/ecdh.h
@@ -0,0 +1,123 @@
+/* crypto/ecdh/ecdh.h */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ECDH_H
+#define HEADER_ECDH_H
+
+#include 
+
+#ifdef OPENSSL_NO_ECDH
+#error ECDH is disabled.
+#endif
+
+#include 
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const ECDH_METHOD *ECDH_OpenSSL(void);
+
+void	  ECDH_set_default_method(const ECDH_METHOD *);
+const ECDH_METHOD *ECDH_get_default_method(void);
+int 	  ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
+                     void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+
+int 	  ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
+		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int 	  ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
+void 	  *ECDH_get_ex_data(EC_KEY *d, int idx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ECDH_strings(void);
+
+/* Error codes for the ECDH functions. */
+
+/* Function codes. */
+#define ECDH_F_ECDH_COMPUTE_KEY				 100
+#define ECDH_F_ECDH_DATA_NEW_METHOD			 101
+
+/* Reason codes. */
+#define ECDH_R_KDF_FAILED				 102
+#define ECDH_R_NO_PRIVATE_VALUE				 100
+#define ECDH_R_POINT_ARITHMETIC_FAILURE			 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/ecdsa.h b/dep/include/openssl/ecdsa.h
new file mode 100644
index 000000000..f20c8ee73
--- /dev/null
+++ b/dep/include/openssl/ecdsa.h
@@ -0,0 +1,271 @@
+/* crypto/ecdsa/ecdsa.h */
+/**
+ * \file   crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
+ * \author Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ECDSA_H
+#define HEADER_ECDSA_H
+
+#include 
+
+#ifdef OPENSSL_NO_ECDSA
+#error ECDSA is disabled.
+#endif
+
+#include 
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ECDSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} ECDSA_SIG;
+
+/** ECDSA_SIG *ECDSA_SIG_new(void)
+ * allocates and initialize a ECDSA_SIG structure
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_SIG_new(void);
+
+/** ECDSA_SIG_free
+ * frees a ECDSA_SIG structure
+ * \param a pointer to the ECDSA_SIG structure
+ */
+void	  ECDSA_SIG_free(ECDSA_SIG *a);
+
+/** i2d_ECDSA_SIG
+ * DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ * (*pp += length of the DER encoded signature)).
+ * \param a  pointer to the ECDSA_SIG object
+ * \param pp pointer to a unsigned char pointer for the output or NULL
+ * \return the length of the DER encoded ECDSA_SIG object or 0 
+ */
+int	  i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp);
+
+/** d2i_ECDSA_SIG
+ * decodes a DER encoded ECDSA signature (note: this function changes *pp
+ * (*pp += len)). 
+ * \param v pointer to ECDSA_SIG pointer (may be NULL)
+ * \param pp buffer with the DER encoded signature
+ * \param len bufferlength
+ * \return pointer to the decoded ECDSA_SIG structure (or NULL)
+ */
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len);
+
+/** ECDSA_do_sign
+ * computes the ECDSA signature of the given hash value using
+ * the supplied private key and returns the created signature.
+ * \param dgst pointer to the hash value
+ * \param dgst_len length of the hash value
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL
+ */
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
+
+/** ECDSA_do_sign_ex
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param kinv optional pointer to a pre-computed inverse k
+ * \param rp optional pointer to the pre-computed rp value (see 
+ *        ECDSA_sign_setup
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
+		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
+/** ECDSA_do_verify
+ * verifies that the supplied signature is a valid ECDSA
+ * signature of the supplied hash value using the supplied public key.
+ * \param dgst pointer to the hash value
+ * \param dgst_len length of the hash value
+ * \param sig  pointer to the ECDSA_SIG structure
+ * \param eckey pointer to the EC_KEY object containing a public EC key
+ * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+ */
+int	  ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+		const ECDSA_SIG *sig, EC_KEY* eckey);
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void);
+
+/** ECDSA_set_default_method
+ * sets the default ECDSA method
+ * \param meth the new default ECDSA_METHOD
+ */
+void	  ECDSA_set_default_method(const ECDSA_METHOD *meth);
+
+/** ECDSA_get_default_method
+ * returns the default ECDSA method
+ * \return pointer to ECDSA_METHOD structure containing the default method
+ */
+const ECDSA_METHOD *ECDSA_get_default_method(void);
+
+/** ECDSA_set_method
+ * sets method to be used for the ECDSA operations
+ * \param eckey pointer to the EC_KEY object
+ * \param meth  pointer to the new method
+ * \return 1 on success and 0 otherwise 
+ */
+int 	  ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
+
+/** ECDSA_size
+ * returns the maximum length of the DER encoded signature
+ * \param  eckey pointer to a EC_KEY object
+ * \return numbers of bytes required for the DER encoded signature
+ */
+int	  ECDSA_size(const EC_KEY *eckey);
+
+/** ECDSA_sign_setup
+ * precompute parts of the signing operation. 
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \param ctx  pointer to a BN_CTX object (may be NULL)
+ * \param kinv pointer to a BIGNUM pointer for the inverse of k
+ * \param rp   pointer to a BIGNUM pointer for x coordinate of k * generator
+ * \return 1 on success and 0 otherwise
+ */
+int 	  ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
+		BIGNUM **rp);
+
+/** ECDSA_sign
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig buffer to hold the DER encoded signature
+ * \param siglen pointer to the length of the returned signature
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int	  ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 
+		unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+
+/** ECDSA_sign_ex
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig buffer to hold the DER encoded signature
+ * \param siglen pointer to the length of the returned signature
+ * \param kinv optional pointer to a pre-computed inverse k
+ * \param rp optional pointer to the pre-computed rp value (see 
+ *        ECDSA_sign_setup
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int	  ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 
+		unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
+		const BIGNUM *rp, EC_KEY *eckey);
+
+/** ECDSA_verify
+ * verifies that the given signature is valid ECDSA signature
+ * of the supplied hash value using the specified public key.
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value 
+ * \param dgstlen length of the hash value
+ * \param sig  pointer to the DER encoded signature
+ * \param siglen length of the DER encoded signature
+ * \param eckey pointer to the EC_KEY object containing a public EC key
+ * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+ */
+int 	  ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 
+		const unsigned char *sig, int siglen, EC_KEY *eckey);
+
+/* the standard ex_data functions */
+int 	  ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
+		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int 	  ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
+void 	  *ECDSA_get_ex_data(EC_KEY *d, int idx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ECDSA_strings(void);
+
+/* Error codes for the ECDSA functions. */
+
+/* Function codes. */
+#define ECDSA_F_ECDSA_DATA_NEW_METHOD			 100
+#define ECDSA_F_ECDSA_DO_SIGN				 101
+#define ECDSA_F_ECDSA_DO_VERIFY				 102
+#define ECDSA_F_ECDSA_SIGN_SETUP			 103
+
+/* Reason codes. */
+#define ECDSA_R_BAD_SIGNATURE				 100
+#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 101
+#define ECDSA_R_ERR_EC_LIB				 102
+#define ECDSA_R_MISSING_PARAMETERS			 103
+#define ECDSA_R_NEED_NEW_SETUP_VALUES			 106
+#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED		 104
+#define ECDSA_R_SIGNATURE_MALLOC_FAILED			 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/engine.h b/dep/include/openssl/engine.h
new file mode 100644
index 000000000..3ec59338f
--- /dev/null
+++ b/dep/include/openssl/engine.h
@@ -0,0 +1,785 @@
+/* openssl/engine.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_H
+#define HEADER_ENGINE_H
+
+#include 
+
+#ifdef OPENSSL_NO_ENGINE
+#error ENGINE is disabled.
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include 
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include 
+#endif
+#include 
+#include 
+#include 
+#include 
+#endif
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These flags are used to control combinations of algorithm (methods)
+ * by bitwise "OR"ing. */
+#define ENGINE_METHOD_RSA		(unsigned int)0x0001
+#define ENGINE_METHOD_DSA		(unsigned int)0x0002
+#define ENGINE_METHOD_DH		(unsigned int)0x0004
+#define ENGINE_METHOD_RAND		(unsigned int)0x0008
+#define ENGINE_METHOD_ECDH		(unsigned int)0x0010
+#define ENGINE_METHOD_ECDSA		(unsigned int)0x0020
+#define ENGINE_METHOD_CIPHERS		(unsigned int)0x0040
+#define ENGINE_METHOD_DIGESTS		(unsigned int)0x0080
+#define ENGINE_METHOD_STORE		(unsigned int)0x0100
+/* Obvious all-or-nothing cases. */
+#define ENGINE_METHOD_ALL		(unsigned int)0xFFFF
+#define ENGINE_METHOD_NONE		(unsigned int)0x0000
+
+/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
+ * internally to control registration of ENGINE implementations, and can be set
+ * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
+ * initialise registered ENGINEs if they are not already initialised. */
+#define ENGINE_TABLE_FLAG_NOINIT	(unsigned int)0x0001
+
+/* ENGINE flags that can be set by ENGINE_set_flags(). */
+/* #define ENGINE_FLAGS_MALLOCED	0x0001 */ /* Not used */
+
+/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
+ * control commands on their own. Without this flag, ENGINE_ctrl() handles these
+ * control commands on behalf of the ENGINE using their "cmd_defns" data. */
+#define ENGINE_FLAGS_MANUAL_CMD_CTRL	(int)0x0002
+
+/* This flag is for ENGINEs who return new duplicate structures when found via
+ * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
+ * commands are called in sequence as part of some stateful process like
+ * key-generation setup and execution), it can set this flag - then each attempt
+ * to obtain the ENGINE will result in it being copied into a new structure.
+ * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
+ * the existing ENGINE's structural reference count. */
+#define ENGINE_FLAGS_BY_ID_COPY		(int)0x0004
+
+/* ENGINEs can support their own command types, and these flags are used in
+ * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
+ * command expects. Currently only numeric and string input is supported. If a
+ * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
+ * then it is regarded as an "internal" control command - and not for use in
+ * config setting situations. As such, they're not available to the
+ * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
+ * this list of 'command types' should be reflected carefully in
+ * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
+
+/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_NUMERIC		(unsigned int)0x0001
+/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
+ * ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_STRING		(unsigned int)0x0002
+/* Indicates that the control command takes *no* input. Ie. the control command
+ * is unparameterised. */
+#define ENGINE_CMD_FLAG_NO_INPUT	(unsigned int)0x0004
+/* Indicates that the control command is internal. This control command won't
+ * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
+ * function. */
+#define ENGINE_CMD_FLAG_INTERNAL	(unsigned int)0x0008
+
+/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
+ * relying on these commands should compile conditional support for
+ * compatibility (eg. if these symbols are defined) but should also migrate the
+ * same functionality to their own ENGINE-specific control functions that can be
+ * "discovered" by calling applications. The fact these control commands
+ * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
+ * fact that application code can find and use them without requiring per-ENGINE
+ * hacking. */
+
+/* These flags are used to tell the ctrl function what should be done.
+ * All command numbers are shared between all engines, even if some don't
+ * make sense to some engines.  In such a case, they do nothing but return
+ * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
+#define ENGINE_CTRL_SET_LOGSTREAM		1
+#define ENGINE_CTRL_SET_PASSWORD_CALLBACK	2
+#define ENGINE_CTRL_HUP				3 /* Close and reinitialise any
+						     handles/connections etc. */
+#define ENGINE_CTRL_SET_USER_INTERFACE          4 /* Alternative to callback */
+#define ENGINE_CTRL_SET_CALLBACK_DATA           5 /* User-specific data, used
+						     when calling the password
+						     callback and the user
+						     interface */
+#define ENGINE_CTRL_LOAD_CONFIGURATION		6 /* Load a configuration, given
+						     a string that represents a
+						     file name or so */
+#define ENGINE_CTRL_LOAD_SECTION		7 /* Load data from a given
+						     section in the already loaded
+						     configuration */
+
+/* These control commands allow an application to deal with an arbitrary engine
+ * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
+ * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
+ * including ENGINE-specific command types, return zero for an error.
+ *
+ * An ENGINE can choose to implement these ctrl functions, and can internally
+ * manage things however it chooses - it does so by setting the
+ * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
+ * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
+ * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
+ * handler need only implement its own commands - the above "meta" commands will
+ * be taken care of. */
+
+/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
+ * all the remaining control commands will return failure, so it is worth
+ * checking this first if the caller is trying to "discover" the engine's
+ * capabilities and doesn't want errors generated unnecessarily. */
+#define ENGINE_CTRL_HAS_CTRL_FUNCTION		10
+/* Returns a positive command number for the first command supported by the
+ * engine. Returns zero if no ctrl commands are supported. */
+#define ENGINE_CTRL_GET_FIRST_CMD_TYPE		11
+/* The 'long' argument specifies a command implemented by the engine, and the
+ * return value is the next command supported, or zero if there are no more. */
+#define ENGINE_CTRL_GET_NEXT_CMD_TYPE		12
+/* The 'void*' argument is a command name (cast from 'const char *'), and the
+ * return value is the command that corresponds to it. */
+#define ENGINE_CTRL_GET_CMD_FROM_NAME		13
+/* The next two allow a command to be converted into its corresponding string
+ * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
+ * case, the return value is the length of the command name (not counting a
+ * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
+ * large enough, and it will be populated with the name of the command (WITH a
+ * trailing EOL). */
+#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD	14
+#define ENGINE_CTRL_GET_NAME_FROM_CMD		15
+/* The next two are similar but give a "short description" of a command. */
+#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD	16
+#define ENGINE_CTRL_GET_DESC_FROM_CMD		17
+/* With this command, the return value is the OR'd combination of
+ * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
+ * engine-specific ctrl command expects. */
+#define ENGINE_CTRL_GET_CMD_FLAGS		18
+
+/* ENGINE implementations should start the numbering of their own control
+ * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
+#define ENGINE_CMD_BASE				200
+
+/* NB: These 2 nCipher "chil" control commands are deprecated, and their
+ * functionality is now available through ENGINE-specific control commands
+ * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
+ * commands should be migrated to the more general command handling before these
+ * are removed. */
+
+/* Flags specific to the nCipher "chil" engine */
+#define ENGINE_CTRL_CHIL_SET_FORKCHECK		100
+	/* Depending on the value of the (long)i argument, this sets or
+	 * unsets the SimpleForkCheck flag in the CHIL API to enable or
+	 * disable checking and workarounds for applications that fork().
+	 */
+#define ENGINE_CTRL_CHIL_NO_LOCKING		101
+	/* This prevents the initialisation function from providing mutex
+	 * callbacks to the nCipher library. */
+
+/* If an ENGINE supports its own specific control commands and wishes the
+ * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
+ * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
+ * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
+ * supports the stated commands (ie. the "cmd_num" entries as described by the
+ * array). NB: The array must be ordered in increasing order of cmd_num.
+ * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
+ * to zero and/or cmd_name set to NULL. */
+typedef struct ENGINE_CMD_DEFN_st
+	{
+	unsigned int cmd_num; /* The command number */
+	const char *cmd_name; /* The command name itself */
+	const char *cmd_desc; /* A short description of the command */
+	unsigned int cmd_flags; /* The input the command expects */
+	} ENGINE_CMD_DEFN;
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR)(void);
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
+/* Generic load_key function pointer */
+typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
+	UI_METHOD *ui_method, void *callback_data);
+/* These callback types are for an ENGINE's handler for cipher and digest logic.
+ * These handlers have these prototypes;
+ *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+ *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
+ * Looking at how to implement these handlers in the case of cipher support, if
+ * the framework wants the EVP_CIPHER for 'nid', it will call;
+ *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
+ * If the framework wants a list of supported 'nid's, it will call;
+ *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
+ */
+/* Returns to a pointer to the array of supported cipher 'nid's. If the second
+ * parameter is non-NULL it is set to the size of the returned array. */
+typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
+typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
+
+/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
+ * structures where the pointers have a "structural reference". This means that
+ * their reference is to allowed access to the structure but it does not imply
+ * that the structure is functional. To simply increment or decrement the
+ * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
+ * required when iterating using ENGINE_get_next as it will automatically
+ * decrement the structural reference count of the "current" ENGINE and
+ * increment the structural reference count of the ENGINE it returns (unless it
+ * is NULL). */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+/* Add all the built-in engines. */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+#ifndef OPENSSL_NO_STATIC_ENGINE
+void ENGINE_load_4758cca(void);
+void ENGINE_load_aep(void);
+void ENGINE_load_atalla(void);
+void ENGINE_load_chil(void);
+void ENGINE_load_cswift(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+void ENGINE_load_nuron(void);
+void ENGINE_load_sureware(void);
+void ENGINE_load_ubsec(void);
+#endif
+void ENGINE_load_cryptodev(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_builtin_engines(void);
+
+/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
+ * "registry" handling. */
+unsigned int ENGINE_get_table_flags(void);
+void ENGINE_set_table_flags(unsigned int flags);
+
+/* Manage registration of ENGINEs per "table". For each type, there are 3
+ * functions;
+ *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
+ *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
+ *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
+ * Cleanup is automatically registered from each table when required, so
+ * ENGINE_cleanup() will reverse any "register" operations. */
+
+int ENGINE_register_RSA(ENGINE *e);
+void ENGINE_unregister_RSA(ENGINE *e);
+void ENGINE_register_all_RSA(void);
+
+int ENGINE_register_DSA(ENGINE *e);
+void ENGINE_unregister_DSA(ENGINE *e);
+void ENGINE_register_all_DSA(void);
+
+int ENGINE_register_ECDH(ENGINE *e);
+void ENGINE_unregister_ECDH(ENGINE *e);
+void ENGINE_register_all_ECDH(void);
+
+int ENGINE_register_ECDSA(ENGINE *e);
+void ENGINE_unregister_ECDSA(ENGINE *e);
+void ENGINE_register_all_ECDSA(void);
+
+int ENGINE_register_DH(ENGINE *e);
+void ENGINE_unregister_DH(ENGINE *e);
+void ENGINE_register_all_DH(void);
+
+int ENGINE_register_RAND(ENGINE *e);
+void ENGINE_unregister_RAND(ENGINE *e);
+void ENGINE_register_all_RAND(void);
+
+int ENGINE_register_STORE(ENGINE *e);
+void ENGINE_unregister_STORE(ENGINE *e);
+void ENGINE_register_all_STORE(void);
+
+int ENGINE_register_ciphers(ENGINE *e);
+void ENGINE_unregister_ciphers(ENGINE *e);
+void ENGINE_register_all_ciphers(void);
+
+int ENGINE_register_digests(ENGINE *e);
+void ENGINE_unregister_digests(ENGINE *e);
+void ENGINE_register_all_digests(void);
+
+/* These functions register all support from the above categories. Note, use of
+ * these functions can result in static linkage of code your application may not
+ * need. If you only need a subset of functionality, consider using more
+ * selective initialisation. */
+int ENGINE_register_complete(ENGINE *e);
+int ENGINE_register_all_complete(void);
+
+/* Send parametrised control commands to the engine. The possibilities to send
+ * down an integer, a pointer to data or a function pointer are provided. Any of
+ * the parameters may or may not be NULL, depending on the command number. In
+ * actuality, this function only requires a structural (rather than functional)
+ * reference to an engine, but many control commands may require the engine be
+ * functional. The caller should be aware of trying commands that require an
+ * operational ENGINE, and only use functional references in such situations. */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* This function tests if an ENGINE-specific command is usable as a "setting".
+ * Eg. in an application's config file that gets processed through
+ * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
+ * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+
+/* This function works like ENGINE_ctrl() with the exception of taking a
+ * command name instead of a command number, and can handle optional commands.
+ * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
+ * use the cmd_name and cmd_optional. */
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+        long i, void *p, void (*f)(void), int cmd_optional);
+
+/* This function passes a command-name and argument to an ENGINE. The cmd_name
+ * is converted to a command number and the control command is called using
+ * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
+ * which case no control command is called). The command is checked for input
+ * flags, and if necessary the argument will be converted to a numeric value. If
+ * cmd_optional is non-zero, then if the ENGINE doesn't support the given
+ * cmd_name the return value will be success anyway. This function is intended
+ * for applications to use so that users (or config files) can supply
+ * engine-specific config data to the ENGINE at run-time to control behaviour of
+ * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
+ * functions that return data, deal with binary data, or that are otherwise
+ * supposed to be used directly through ENGINE_ctrl() in application code. Any
+ * "return" data from an ENGINE_ctrl() operation in this function will be lost -
+ * the return value is interpreted as failure if the return value is zero,
+ * success otherwise, and this function returns a boolean value as a result. In
+ * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
+ * implementations with parameterisations that work in this scheme, so that
+ * compliant ENGINE-based applications can work consistently with the same
+ * configuration for the same ENGINE-enabled devices, across applications. */
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+				int cmd_optional);
+
+/* These functions are useful for manufacturing new ENGINE structures. They
+ * don't address reference counting at all - one uses them to populate an ENGINE
+ * structure with personalised implementations of things prior to using it
+ * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
+ * here so that the ENGINE structure doesn't have to be exposed and break binary
+ * compatibility! */
+ENGINE *ENGINE_new(void);
+int ENGINE_free(ENGINE *e);
+int ENGINE_up_ref(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
+int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_flags(ENGINE *e, int flags);
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+/* These functions allow control over any per-structure ENGINE data. */
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
+ * automatically ensures the list cleanup function is registered to be called
+ * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
+ * ENGINE_cleanup() will clean up after them. */
+void ENGINE_cleanup(void);
+
+/* These return values from within the ENGINE structure. These can be useful
+ * with functional references as well as structural references - it depends
+ * which you obtained. Using the result for functional purposes if you only
+ * obtained a structural reference may be problematic! */
+const char *ENGINE_get_id(const ENGINE *e);
+const char *ENGINE_get_name(const ENGINE *e);
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
+const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+int ENGINE_get_flags(const ENGINE *e);
+
+/* FUNCTIONAL functions. These functions deal with ENGINE structures
+ * that have (or will) be initialised for use. Broadly speaking, the
+ * structural functions are useful for iterating the list of available
+ * engine types, creating new engine types, and other "list" operations.
+ * These functions actually deal with ENGINEs that are to be used. As
+ * such these functions can fail (if applicable) when particular
+ * engines are unavailable - eg. if a hardware accelerator is not
+ * attached or not functioning correctly. Each ENGINE has 2 reference
+ * counts; structural and functional. Every time a functional reference
+ * is obtained or released, a corresponding structural reference is
+ * automatically obtained or released too. */
+
+/* Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently
+ * operational and cannot initialise. */
+int ENGINE_init(ENGINE *e);
+/* Free a functional reference to a engine type. This does not require
+ * a corresponding call to ENGINE_free as it also releases a structural
+ * reference. */
+int ENGINE_finish(ENGINE *e);
+
+/* The following functions handle keys that are stored in some secondary
+ * location, handled by the engine.  The storage may be on a card or
+ * whatever. */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+
+/* This returns a pointer for the current ENGINE structure that
+ * is (by default) performing any RSA operations. The value returned
+ * is an incremented reference, so it should be free'd (ENGINE_finish)
+ * before it is discarded. */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_ECDH(void);
+ENGINE *ENGINE_get_default_ECDSA(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+/* These functions can be used to get a functional reference to perform
+ * ciphering or digesting corresponding to "nid". */
+ENGINE *ENGINE_get_cipher_engine(int nid);
+ENGINE *ENGINE_get_digest_engine(int nid);
+
+/* This sets a new default ENGINE structure for performing RSA
+ * operations. If the result is non-zero (success) then the ENGINE
+ * structure will have had its reference count up'd so the caller
+ * should still free their own reference 'e'. */
+int ENGINE_set_default_RSA(ENGINE *e);
+int ENGINE_set_default_string(ENGINE *e, const char *def_list);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_ECDH(ENGINE *e);
+int ENGINE_set_default_ECDSA(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_ciphers(ENGINE *e);
+int ENGINE_set_default_digests(ENGINE *e);
+
+/* The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
+ * function, this function can result in unnecessary static linkage. If your
+ * application requires only specific functionality, consider using more
+ * selective functions. */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+void ENGINE_add_conf_module(void);
+
+/* Deprecated functions ... */
+/* int ENGINE_clear_defaults(void); */
+
+/**************************/
+/* DYNAMIC ENGINE SUPPORT */
+/**************************/
+
+/* Binary/behaviour compatibility levels */
+#define OSSL_DYNAMIC_VERSION		(unsigned long)0x00020000
+/* Binary versions older than this are too old for us (whether we're a loader or
+ * a loadee) */
+#define OSSL_DYNAMIC_OLDEST		(unsigned long)0x00020000
+
+/* When compiling an ENGINE entirely as an external shared library, loadable by
+ * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
+ * type provides the calling application's (or library's) error functionality
+ * and memory management function pointers to the loaded library. These should
+ * be used/set in the loaded library code so that the loading application's
+ * 'state' will be used/changed in all operations. The 'static_state' pointer
+ * allows the loaded library to know if it shares the same static data as the
+ * calling application (or library), and thus whether these callbacks need to be
+ * set or not. */
+typedef void *(*dyn_MEM_malloc_cb)(size_t);
+typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
+typedef void (*dyn_MEM_free_cb)(void *);
+typedef struct st_dynamic_MEM_fns {
+	dyn_MEM_malloc_cb			malloc_cb;
+	dyn_MEM_realloc_cb			realloc_cb;
+	dyn_MEM_free_cb				free_cb;
+	} dynamic_MEM_fns;
+/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
+ * these types so we (and any other dependant code) can simplify a bit?? */
+typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
+typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
+typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
+						const char *,int);
+typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
+						const char *,int);
+typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
+						const char *,int);
+typedef struct st_dynamic_LOCK_fns {
+	dyn_lock_locking_cb			lock_locking_cb;
+	dyn_lock_add_lock_cb			lock_add_lock_cb;
+	dyn_dynlock_create_cb			dynlock_create_cb;
+	dyn_dynlock_lock_cb			dynlock_lock_cb;
+	dyn_dynlock_destroy_cb			dynlock_destroy_cb;
+	} dynamic_LOCK_fns;
+/* The top-level structure */
+typedef struct st_dynamic_fns {
+	void 					*static_state;
+	const ERR_FNS				*err_fns;
+	const CRYPTO_EX_DATA_IMPL		*ex_data_fns;
+	dynamic_MEM_fns				mem_fns;
+	dynamic_LOCK_fns			lock_fns;
+	} dynamic_fns;
+
+/* The version checking function should be of this prototype. NB: The
+ * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
+ * If this function returns zero, it indicates a (potential) version
+ * incompatibility and the loaded library doesn't believe it can proceed.
+ * Otherwise, the returned value is the (latest) version supported by the
+ * loading library. The loader may still decide that the loaded code's version
+ * is unsatisfactory and could veto the load. The function is expected to
+ * be implemented with the symbol name "v_check", and a default implementation
+ * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
+typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
+#define IMPLEMENT_DYNAMIC_CHECK_FN() \
+	OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
+		if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
+		return 0; }
+
+/* This function is passed the ENGINE structure to initialise with its own
+ * function and command settings. It should not adjust the structural or
+ * functional reference counts. If this function returns zero, (a) the load will
+ * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
+ * structure, and (c) the shared library will be unloaded. So implementations
+ * should do their own internal cleanup in failure circumstances otherwise they
+ * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
+ * the loader is looking for. If this is NULL, the shared library can choose to
+ * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
+ * library must initialise only an ENGINE matching the passed 'id'. The function
+ * is expected to be implemented with the symbol name "bind_engine". A standard
+ * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
+ * the parameter 'fn' is a callback function that populates the ENGINE structure
+ * and returns an int value (zero for failure). 'fn' should have prototype;
+ *    [static] int fn(ENGINE *e, const char *id); */
+typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
+				const dynamic_fns *fns);
+#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+	OPENSSL_EXPORT \
+	int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
+		if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
+		if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
+			fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
+			return 0; \
+		CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
+		CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
+		CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
+		CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
+		CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
+		if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
+			return 0; \
+		if(!ERR_set_implementation(fns->err_fns)) return 0; \
+	skip_cbs: \
+		if(!fn(e,id)) return 0; \
+		return 1; }
+
+/* If the loading application (or library) and the loaded ENGINE library share
+ * the same static data (eg. they're both dynamically linked to the same
+ * libcrypto.so) we need a way to avoid trying to set system callbacks - this
+ * would fail, and for the same reason that it's unnecessary to try. If the
+ * loaded ENGINE has (or gets from through the loader) its own copy of the
+ * libcrypto static data, we will need to set the callbacks. The easiest way to
+ * detect this is to have a function that returns a pointer to some static data
+ * and let the loading application and loaded ENGINE compare their respective
+ * values. */
+void *ENGINE_get_static_state(void);
+
+#if defined(__OpenBSD__) || defined(__FreeBSD__)
+void ENGINE_setup_bsd_cryptodev(void);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ENGINE_strings(void);
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+#define ENGINE_F_DYNAMIC_CTRL				 180
+#define ENGINE_F_DYNAMIC_GET_DATA_CTX			 181
+#define ENGINE_F_DYNAMIC_LOAD				 182
+#define ENGINE_F_DYNAMIC_SET_DATA_CTX			 183
+#define ENGINE_F_ENGINE_ADD				 105
+#define ENGINE_F_ENGINE_BY_ID				 106
+#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE		 170
+#define ENGINE_F_ENGINE_CTRL				 142
+#define ENGINE_F_ENGINE_CTRL_CMD			 178
+#define ENGINE_F_ENGINE_CTRL_CMD_STRING			 171
+#define ENGINE_F_ENGINE_FINISH				 107
+#define ENGINE_F_ENGINE_FREE_UTIL			 108
+#define ENGINE_F_ENGINE_GET_CIPHER			 185
+#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE		 177
+#define ENGINE_F_ENGINE_GET_DIGEST			 186
+#define ENGINE_F_ENGINE_GET_NEXT			 115
+#define ENGINE_F_ENGINE_GET_PREV			 116
+#define ENGINE_F_ENGINE_INIT				 119
+#define ENGINE_F_ENGINE_LIST_ADD			 120
+#define ENGINE_F_ENGINE_LIST_REMOVE			 121
+#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY		 150
+#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY			 151
+#define ENGINE_F_ENGINE_NEW				 122
+#define ENGINE_F_ENGINE_REMOVE				 123
+#define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
+#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE		 126
+#define ENGINE_F_ENGINE_SET_ID				 129
+#define ENGINE_F_ENGINE_SET_NAME			 130
+#define ENGINE_F_ENGINE_TABLE_REGISTER			 184
+#define ENGINE_F_ENGINE_UNLOAD_KEY			 152
+#define ENGINE_F_ENGINE_UNLOCKED_FINISH			 191
+#define ENGINE_F_ENGINE_UP_REF				 190
+#define ENGINE_F_INT_CTRL_HELPER			 172
+#define ENGINE_F_INT_ENGINE_CONFIGURE			 188
+#define ENGINE_F_INT_ENGINE_MODULE_INIT			 187
+#define ENGINE_F_LOG_MESSAGE				 141
+
+/* Reason codes. */
+#define ENGINE_R_ALREADY_LOADED				 100
+#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER		 133
+#define ENGINE_R_CMD_NOT_EXECUTABLE			 134
+#define ENGINE_R_COMMAND_TAKES_INPUT			 135
+#define ENGINE_R_COMMAND_TAKES_NO_INPUT			 136
+#define ENGINE_R_CONFLICTING_ENGINE_ID			 103
+#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED		 119
+#define ENGINE_R_DH_NOT_IMPLEMENTED			 139
+#define ENGINE_R_DSA_NOT_IMPLEMENTED			 140
+#define ENGINE_R_DSO_FAILURE				 104
+#define ENGINE_R_DSO_NOT_FOUND				 132
+#define ENGINE_R_ENGINES_SECTION_ERROR			 148
+#define ENGINE_R_ENGINE_IS_NOT_IN_LIST			 105
+#define ENGINE_R_ENGINE_SECTION_ERROR			 149
+#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY		 128
+#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY		 129
+#define ENGINE_R_FINISH_FAILED				 106
+#define ENGINE_R_GET_HANDLE_FAILED			 107
+#define ENGINE_R_ID_OR_NAME_MISSING			 108
+#define ENGINE_R_INIT_FAILED				 109
+#define ENGINE_R_INTERNAL_LIST_ERROR			 110
+#define ENGINE_R_INVALID_ARGUMENT			 143
+#define ENGINE_R_INVALID_CMD_NAME			 137
+#define ENGINE_R_INVALID_CMD_NUMBER			 138
+#define ENGINE_R_INVALID_INIT_VALUE			 151
+#define ENGINE_R_INVALID_STRING				 150
+#define ENGINE_R_NOT_INITIALISED			 117
+#define ENGINE_R_NOT_LOADED				 112
+#define ENGINE_R_NO_CONTROL_FUNCTION			 120
+#define ENGINE_R_NO_INDEX				 144
+#define ENGINE_R_NO_LOAD_FUNCTION			 125
+#define ENGINE_R_NO_REFERENCE				 130
+#define ENGINE_R_NO_SUCH_ENGINE				 116
+#define ENGINE_R_NO_UNLOAD_FUNCTION			 126
+#define ENGINE_R_PROVIDE_PARAMETERS			 113
+#define ENGINE_R_RSA_NOT_IMPLEMENTED			 141
+#define ENGINE_R_UNIMPLEMENTED_CIPHER			 146
+#define ENGINE_R_UNIMPLEMENTED_DIGEST			 147
+#define ENGINE_R_VERSION_INCOMPATIBILITY		 145
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/err.h b/dep/include/openssl/err.h
new file mode 100644
index 000000000..b723cd977
--- /dev/null
+++ b/dep/include/openssl/err.h
@@ -0,0 +1,318 @@
+/* crypto/err/err.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ERR_H
+#define HEADER_ERR_H
+
+#include 
+
+#ifndef OPENSSL_NO_FP_API
+#include 
+#include 
+#endif
+
+#include 
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#ifndef OPENSSL_NO_LHASH
+#include 
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSSL_NO_ERR
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,d,e)
+#else
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,NULL,0)
+#endif
+
+#include 
+
+#define ERR_TXT_MALLOCED	0x01
+#define ERR_TXT_STRING		0x02
+
+#define ERR_FLAG_MARK		0x01
+
+#define ERR_NUM_ERRORS	16
+typedef struct err_state_st
+	{
+	unsigned long pid;
+	int err_flags[ERR_NUM_ERRORS];
+	unsigned long err_buffer[ERR_NUM_ERRORS];
+	char *err_data[ERR_NUM_ERRORS];
+	int err_data_flags[ERR_NUM_ERRORS];
+	const char *err_file[ERR_NUM_ERRORS];
+	int err_line[ERR_NUM_ERRORS];
+	int top,bottom;
+	} ERR_STATE;
+
+/* library */
+#define ERR_LIB_NONE		1
+#define ERR_LIB_SYS		2
+#define ERR_LIB_BN		3
+#define ERR_LIB_RSA		4
+#define ERR_LIB_DH		5
+#define ERR_LIB_EVP		6
+#define ERR_LIB_BUF		7
+#define ERR_LIB_OBJ		8
+#define ERR_LIB_PEM		9
+#define ERR_LIB_DSA		10
+#define ERR_LIB_X509		11
+/* #define ERR_LIB_METH         12 */
+#define ERR_LIB_ASN1		13
+#define ERR_LIB_CONF		14
+#define ERR_LIB_CRYPTO		15
+#define ERR_LIB_EC		16
+#define ERR_LIB_SSL		20
+/* #define ERR_LIB_SSL23        21 */
+/* #define ERR_LIB_SSL2         22 */
+/* #define ERR_LIB_SSL3         23 */
+/* #define ERR_LIB_RSAREF       30 */
+/* #define ERR_LIB_PROXY        31 */
+#define ERR_LIB_BIO		32
+#define ERR_LIB_PKCS7		33
+#define ERR_LIB_X509V3		34
+#define ERR_LIB_PKCS12		35
+#define ERR_LIB_RAND		36
+#define ERR_LIB_DSO		37
+#define ERR_LIB_ENGINE		38
+#define ERR_LIB_OCSP            39
+#define ERR_LIB_UI              40
+#define ERR_LIB_COMP            41
+#define ERR_LIB_ECDSA		42
+#define ERR_LIB_ECDH		43
+#define ERR_LIB_STORE           44
+
+#define ERR_LIB_USER		128
+
+#define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__)
+#define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__)
+#define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__)
+#define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__)
+#define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__)
+#define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__)
+#define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
+#define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__)
+#define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__)
+#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__)
+#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
+#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__)
+#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__)
+#define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__)
+#define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__)
+#define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__)
+#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__)
+#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__)
+#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__)
+#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__)
+#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__)
+#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__)
+#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__)
+#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__)
+#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__)
+#define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
+#define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
+#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
+
+/* Borland C seems too stupid to be able to shift and do longs in
+ * the pre-processor :-( */
+#define ERR_PACK(l,f,r)		(((((unsigned long)l)&0xffL)*0x1000000)| \
+				((((unsigned long)f)&0xfffL)*0x1000)| \
+				((((unsigned long)r)&0xfffL)))
+#define ERR_GET_LIB(l)		(int)((((unsigned long)l)>>24L)&0xffL)
+#define ERR_GET_FUNC(l)		(int)((((unsigned long)l)>>12L)&0xfffL)
+#define ERR_GET_REASON(l)	(int)((l)&0xfffL)
+#define ERR_FATAL_ERROR(l)	(int)((l)&ERR_R_FATAL)
+
+
+/* OS functions */
+#define SYS_F_FOPEN		1
+#define SYS_F_CONNECT		2
+#define SYS_F_GETSERVBYNAME	3
+#define SYS_F_SOCKET		4
+#define SYS_F_IOCTLSOCKET	5
+#define SYS_F_BIND		6
+#define SYS_F_LISTEN		7
+#define SYS_F_ACCEPT		8
+#define SYS_F_WSASTARTUP	9 /* Winsock stuff */
+#define SYS_F_OPENDIR		10
+#define SYS_F_FREAD		11
+
+
+/* reasons */
+#define ERR_R_SYS_LIB	ERR_LIB_SYS       /* 2 */
+#define ERR_R_BN_LIB	ERR_LIB_BN        /* 3 */
+#define ERR_R_RSA_LIB	ERR_LIB_RSA       /* 4 */
+#define ERR_R_DH_LIB	ERR_LIB_DH        /* 5 */
+#define ERR_R_EVP_LIB	ERR_LIB_EVP       /* 6 */
+#define ERR_R_BUF_LIB	ERR_LIB_BUF       /* 7 */
+#define ERR_R_OBJ_LIB	ERR_LIB_OBJ       /* 8 */
+#define ERR_R_PEM_LIB	ERR_LIB_PEM       /* 9 */
+#define ERR_R_DSA_LIB	ERR_LIB_DSA      /* 10 */
+#define ERR_R_X509_LIB	ERR_LIB_X509     /* 11 */
+#define ERR_R_ASN1_LIB	ERR_LIB_ASN1     /* 13 */
+#define ERR_R_CONF_LIB	ERR_LIB_CONF     /* 14 */
+#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO  /* 15 */
+#define ERR_R_EC_LIB	ERR_LIB_EC       /* 16 */
+#define ERR_R_SSL_LIB	ERR_LIB_SSL      /* 20 */
+#define ERR_R_BIO_LIB	ERR_LIB_BIO      /* 32 */
+#define ERR_R_PKCS7_LIB	ERR_LIB_PKCS7    /* 33 */
+#define ERR_R_X509V3_LIB ERR_LIB_X509V3  /* 34 */
+#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12  /* 35 */
+#define ERR_R_RAND_LIB	ERR_LIB_RAND     /* 36 */
+#define ERR_R_DSO_LIB	ERR_LIB_DSO      /* 37 */
+#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE  /* 38 */
+#define ERR_R_OCSP_LIB  ERR_LIB_OCSP     /* 39 */
+#define ERR_R_UI_LIB    ERR_LIB_UI       /* 40 */
+#define ERR_R_COMP_LIB	ERR_LIB_COMP     /* 41 */
+#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA	 /* 42 */
+#define ERR_R_ECDH_LIB  ERR_LIB_ECDH	 /* 43 */
+#define ERR_R_STORE_LIB ERR_LIB_STORE    /* 44 */
+
+#define ERR_R_NESTED_ASN1_ERROR			58
+#define ERR_R_BAD_ASN1_OBJECT_HEADER		59
+#define ERR_R_BAD_GET_ASN1_OBJECT_CALL		60
+#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE	61
+#define ERR_R_ASN1_LENGTH_MISMATCH		62
+#define ERR_R_MISSING_ASN1_EOS			63
+
+/* fatal error */
+#define ERR_R_FATAL				64
+#define	ERR_R_MALLOC_FAILURE			(1|ERR_R_FATAL)
+#define	ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	(2|ERR_R_FATAL)
+#define	ERR_R_PASSED_NULL_PARAMETER		(3|ERR_R_FATAL)
+#define	ERR_R_INTERNAL_ERROR			(4|ERR_R_FATAL)
+#define	ERR_R_DISABLED				(5|ERR_R_FATAL)
+
+/* 99 is the maximum possible ERR_R_... code, higher values
+ * are reserved for the individual libraries */
+
+
+typedef struct ERR_string_data_st
+	{
+	unsigned long error;
+	const char *string;
+	} ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func,int reason,const char *file,int line);
+void ERR_set_error_data(char *data,int flags);
+
+unsigned long ERR_get_error(void);
+unsigned long ERR_get_error_line(const char **file,int *line);
+unsigned long ERR_get_error_line_data(const char **file,int *line,
+				      const char **data, int *flags);
+unsigned long ERR_peek_error(void);
+unsigned long ERR_peek_error_line(const char **file,int *line);
+unsigned long ERR_peek_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+unsigned long ERR_peek_last_error(void);
+unsigned long ERR_peek_last_error_line(const char **file,int *line);
+unsigned long ERR_peek_last_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+void ERR_clear_error(void );
+char *ERR_error_string(unsigned long e,char *buf);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
+			 void *u);
+#ifndef OPENSSL_NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+#endif
+#ifndef OPENSSL_NO_BIO
+void ERR_print_errors(BIO *bp);
+void ERR_add_error_data(int num, ...);
+#endif
+void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_unload_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void);
+void ERR_load_crypto_strings(void);
+void ERR_free_strings(void);
+
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+ERR_STATE *ERR_get_state(void);
+
+#ifndef OPENSSL_NO_LHASH
+LHASH *ERR_get_string_table(void);
+LHASH *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH **hash);
+#endif
+
+int ERR_get_next_error_library(void);
+
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
+/* Already defined in ossl_typ.h */
+/* typedef struct st_ERR_FNS ERR_FNS; */
+/* An application can use this function and provide the return value to loaded
+ * modules that should use the application's ERR state/functionality */
+const ERR_FNS *ERR_get_implementation(void);
+/* A loaded module should call this function prior to any ERR operations using
+ * the application's "ERR_FNS". */
+int ERR_set_implementation(const ERR_FNS *fns);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/evp.h b/dep/include/openssl/evp.h
new file mode 100644
index 000000000..636f426c6
--- /dev/null
+++ b/dep/include/openssl/evp.h
@@ -0,0 +1,970 @@
+/* crypto/evp/evp.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ENVELOPE_H
+#define HEADER_ENVELOPE_H
+
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# include 
+#else
+# define OPENSSL_ALGORITHM_DEFINES
+# include 
+# undef OPENSSL_ALGORITHM_DEFINES
+#endif
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+
+/*
+#define EVP_RC2_KEY_SIZE		16
+#define EVP_RC4_KEY_SIZE		16
+#define EVP_BLOWFISH_KEY_SIZE		16
+#define EVP_CAST5_KEY_SIZE		16
+#define EVP_RC5_32_12_16_KEY_SIZE	16
+*/
+#define EVP_MAX_MD_SIZE			64	/* longest known is SHA512 */
+#define EVP_MAX_KEY_LENGTH		32
+#define EVP_MAX_IV_LENGTH		16
+#define EVP_MAX_BLOCK_LENGTH		32
+
+#define PKCS5_SALT_LEN			8
+/* Default PKCS#5 iteration count */
+#define PKCS5_DEFAULT_ITER		2048
+
+#include 
+
+#define EVP_PK_RSA	0x0001
+#define EVP_PK_DSA	0x0002
+#define EVP_PK_DH	0x0004
+#define EVP_PK_EC	0x0008
+#define EVP_PKT_SIGN	0x0010
+#define EVP_PKT_ENC	0x0020
+#define EVP_PKT_EXCH	0x0040
+#define EVP_PKS_RSA	0x0100
+#define EVP_PKS_DSA	0x0200
+#define EVP_PKS_EC	0x0400
+#define EVP_PKT_EXP	0x1000 /* <= 512 bit key */
+
+#define EVP_PKEY_NONE	NID_undef
+#define EVP_PKEY_RSA	NID_rsaEncryption
+#define EVP_PKEY_RSA2	NID_rsa
+#define EVP_PKEY_DSA	NID_dsa
+#define EVP_PKEY_DSA1	NID_dsa_2
+#define EVP_PKEY_DSA2	NID_dsaWithSHA
+#define EVP_PKEY_DSA3	NID_dsaWithSHA1
+#define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
+#define EVP_PKEY_DH	NID_dhKeyAgreement
+#define EVP_PKEY_EC	NID_X9_62_id_ecPublicKey
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Type needs to be a bit field
+ * Sub-type needs to be for variations on the method, as in, can it do
+ * arbitrary encryption.... */
+struct evp_pkey_st
+	{
+	int type;
+	int save_type;
+	int references;
+	union	{
+		char *ptr;
+#ifndef OPENSSL_NO_RSA
+		struct rsa_st *rsa;	/* RSA */
+#endif
+#ifndef OPENSSL_NO_DSA
+		struct dsa_st *dsa;	/* DSA */
+#endif
+#ifndef OPENSSL_NO_DH
+		struct dh_st *dh;	/* DH */
+#endif
+#ifndef OPENSSL_NO_EC
+		struct ec_key_st *ec;	/* ECC */
+#endif
+		} pkey;
+	int save_parameters;
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	} /* EVP_PKEY */;
+
+#define EVP_PKEY_MO_SIGN	0x0001
+#define EVP_PKEY_MO_VERIFY	0x0002
+#define EVP_PKEY_MO_ENCRYPT	0x0004
+#define EVP_PKEY_MO_DECRYPT	0x0008
+
+#if 0
+/* This structure is required to tie the message digest and signing together.
+ * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
+ * oid, md and pkey.
+ * This is required because for various smart-card perform the digest and
+ * signing/verification on-board.  To handle this case, the specific
+ * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
+ * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
+ * This can either be software or a token to provide the required low level
+ * routines.
+ */
+typedef struct evp_pkey_md_st
+	{
+	int oid;
+	EVP_MD *md;
+	EVP_PKEY_METHOD *pkey;
+	} EVP_PKEY_MD;
+
+#define EVP_rsa_md2() \
+		EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_md2())
+#define EVP_rsa_md5() \
+		EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_md5())
+#define EVP_rsa_sha0() \
+		EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_sha())
+#define EVP_rsa_sha1() \
+		EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_sha1())
+#define EVP_rsa_ripemd160() \
+		EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
+			EVP_rsa_pkcs1(),EVP_ripemd160())
+#define EVP_rsa_mdc2() \
+		EVP_PKEY_MD_add(NID_mdc2WithRSA,\
+			EVP_rsa_octet_string(),EVP_mdc2())
+#define EVP_dsa_sha() \
+		EVP_PKEY_MD_add(NID_dsaWithSHA,\
+			EVP_dsa(),EVP_sha())
+#define EVP_dsa_sha1() \
+		EVP_PKEY_MD_add(NID_dsaWithSHA1,\
+			EVP_dsa(),EVP_sha1())
+
+typedef struct evp_pkey_method_st
+	{
+	char *name;
+	int flags;
+	int type;		/* RSA, DSA, an SSLeay specific constant */
+	int oid;		/* For the pub-key type */
+	int encrypt_oid;	/* pub/priv key encryption */
+
+	int (*sign)();
+	int (*verify)();
+	struct	{
+		int (*set)();	/* get and/or set the underlying type */
+		int (*get)();
+		int (*encrypt)();
+		int (*decrypt)();
+		int (*i2d)();
+		int (*d2i)();
+		int (*dup)();
+		} pub,priv;
+	int (*set_asn1_parameters)();
+	int (*get_asn1_parameters)();
+	} EVP_PKEY_METHOD;
+#endif
+
+#ifndef EVP_MD
+struct env_md_st
+	{
+	int type;
+	int pkey_type;
+	int md_size;
+	unsigned long flags;
+	int (*init)(EVP_MD_CTX *ctx);
+	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
+	int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
+	int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
+	int (*cleanup)(EVP_MD_CTX *ctx);
+
+	/* FIXME: prototype these some day */
+	int (*sign)(int type, const unsigned char *m, unsigned int m_length,
+		    unsigned char *sigret, unsigned int *siglen, void *key);
+	int (*verify)(int type, const unsigned char *m, unsigned int m_length,
+		      const unsigned char *sigbuf, unsigned int siglen,
+		      void *key);
+	int required_pkey_type[5]; /*EVP_PKEY_xxx */
+	int block_size;
+	int ctx_size; /* how big does the ctx->md_data need to be */
+	} /* EVP_MD */;
+
+typedef int evp_sign_method(int type,const unsigned char *m,
+			    unsigned int m_length,unsigned char *sigret,
+			    unsigned int *siglen, void *key);
+typedef int evp_verify_method(int type,const unsigned char *m,
+			    unsigned int m_length,const unsigned char *sigbuf,
+			    unsigned int siglen, void *key);
+
+#define EVP_MD_FLAG_ONESHOT	0x0001 /* digest can only handle a single
+					* block */
+
+#define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_DSA_method	(evp_sign_method *)DSA_sign, \
+				(evp_verify_method *)DSA_verify, \
+				{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+					EVP_PKEY_DSA4,0}
+#else
+#define EVP_PKEY_DSA_method	EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+#define EVP_PKEY_ECDSA_method   (evp_sign_method *)ECDSA_sign, \
+				(evp_verify_method *)ECDSA_verify, \
+                                 {EVP_PKEY_EC,0,0,0}
+#else   
+#define EVP_PKEY_ECDSA_method   EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_RSA_method	(evp_sign_method *)RSA_sign, \
+				(evp_verify_method *)RSA_verify, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+				(evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
+				(evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#else
+#define EVP_PKEY_RSA_method	EVP_PKEY_NULL_method
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+#endif
+
+#endif /* !EVP_MD */
+
+struct env_md_ctx_st
+	{
+	const EVP_MD *digest;
+	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
+	unsigned long flags;
+	void *md_data;
+	} /* EVP_MD_CTX */;
+
+/* values for EVP_MD_CTX flags */
+
+#define EVP_MD_CTX_FLAG_ONESHOT		0x0001 /* digest update will be called
+						* once only */
+#define EVP_MD_CTX_FLAG_CLEANED		0x0002 /* context has already been
+						* cleaned */
+#define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
+						* in EVP_MD_CTX_cleanup */
+
+struct evp_cipher_st
+	{
+	int nid;
+	int block_size;
+	int key_len;		/* Default value for variable length ciphers */
+	int iv_len;
+	unsigned long flags;	/* Various flags */
+	int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		    const unsigned char *iv, int enc);	/* init key */
+	int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			 const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
+	int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
+	int ctx_size;		/* how big ctx->cipher_data needs to be */
+	int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
+	int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
+	int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
+	void *app_data;		/* Application data */
+	} /* EVP_CIPHER */;
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+#define		EVP_CIPH_STREAM_CIPHER		0x0
+#define		EVP_CIPH_ECB_MODE		0x1
+#define		EVP_CIPH_CBC_MODE		0x2
+#define		EVP_CIPH_CFB_MODE		0x3
+#define		EVP_CIPH_OFB_MODE		0x4
+#define 	EVP_CIPH_MODE			0x7
+/* Set if variable length cipher */
+#define 	EVP_CIPH_VARIABLE_LENGTH	0x8
+/* Set if the iv handling should be done by the cipher itself */
+#define 	EVP_CIPH_CUSTOM_IV		0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+#define 	EVP_CIPH_ALWAYS_CALL_INIT	0x20
+/* Call ctrl() to init cipher parameters */
+#define 	EVP_CIPH_CTRL_INIT		0x40
+/* Don't use standard key length function */
+#define 	EVP_CIPH_CUSTOM_KEY_LENGTH	0x80
+/* Don't use standard block padding */
+#define 	EVP_CIPH_NO_PADDING		0x100
+/* cipher handles random key generation */
+#define 	EVP_CIPH_RAND_KEY		0x200
+
+/* ctrl() values */
+
+#define		EVP_CTRL_INIT			0x0
+#define 	EVP_CTRL_SET_KEY_LENGTH		0x1
+#define 	EVP_CTRL_GET_RC2_KEY_BITS	0x2
+#define 	EVP_CTRL_SET_RC2_KEY_BITS	0x3
+#define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
+#define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
+#define 	EVP_CTRL_RAND_KEY		0x6
+
+typedef struct evp_cipher_info_st
+	{
+	const EVP_CIPHER *cipher;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	} EVP_CIPHER_INFO;
+
+struct evp_cipher_ctx_st
+	{
+	const EVP_CIPHER *cipher;
+	ENGINE *engine;	/* functional reference if 'cipher' is ENGINE-provided */
+	int encrypt;		/* encrypt or decrypt */
+	int buf_len;		/* number we have left */
+
+	unsigned char  oiv[EVP_MAX_IV_LENGTH];	/* original iv */
+	unsigned char  iv[EVP_MAX_IV_LENGTH];	/* working iv */
+	unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
+	int num;				/* used by cfb/ofb mode */
+
+	void *app_data;		/* application stuff */
+	int key_len;		/* May change for variable length cipher */
+	unsigned long flags;	/* Various flags */
+	void *cipher_data; /* per EVP data */
+	int final_used;
+	int block_mask;
+	unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
+	} /* EVP_CIPHER_CTX */;
+
+typedef struct evp_Encode_Ctx_st
+	{
+	int num;	/* number saved in a partial encode/decode */
+	int length;	/* The length is either the output line length
+			 * (in input bytes) or the shortest input line
+			 * length that is ok.  Once decoding begins,
+			 * the length is adjusted up each time a longer
+			 * line is decoded */
+	unsigned char enc_data[80];	/* data to encode */
+	int line_num;	/* number read on current line */
+	int expect_nl;
+	} EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+		ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                const EVP_MD *md, int en_de);
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+					(char *)(rsa))
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+					(char *)(dsa))
+#endif
+
+#ifndef OPENSSL_NO_DH
+#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+					(char *)(dh))
+#endif
+
+#ifndef OPENSSL_NO_EC
+#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+                                        (char *)(eckey))
+#endif
+
+/* Add some extra combinations */
+#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+int EVP_MD_type(const EVP_MD *md);
+#define EVP_MD_nid(e)			EVP_MD_type(e)
+#define EVP_MD_name(e)			OBJ_nid2sn(EVP_MD_nid(e))
+int EVP_MD_pkey_type(const EVP_MD *md);	
+int EVP_MD_size(const EVP_MD *md);
+int EVP_MD_block_size(const EVP_MD *md);
+
+const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+#define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
+#define EVP_MD_CTX_block_size(e)	EVP_MD_block_size(EVP_MD_CTX_md(e))
+#define EVP_MD_CTX_type(e)		EVP_MD_type(EVP_MD_CTX_md(e))
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
+#define EVP_CIPHER_name(e)		OBJ_nid2sn(EVP_CIPHER_nid(e))
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+#define EVP_CIPHER_mode(e)		(EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+
+const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
+#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
+#define EVP_CIPHER_CTX_mode(e)		(EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
+
+#define EVP_ENCODE_LENGTH(l)	(((l+2)/3*4)+(l/48+1)*2+80)
+#define EVP_DECODE_LENGTH(l)	((l+3)/4*3+80)
+
+#define EVP_SignInit_ex(a,b,c)		EVP_DigestInit_ex(a,b,c)
+#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
+#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define	EVP_VerifyInit_ex(a,b,c)	EVP_DigestInit_ex(a,b,c)
+#define	EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
+#define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
+#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+
+#ifdef CONST_STRICT
+void BIO_set_md(BIO *,const EVP_MD *md);
+#else
+# define BIO_set_md(b,md)		BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+#endif
+#define BIO_get_md(b,mdp)		BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+#define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+#define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
+#define BIO_get_cipher_status(b)	BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+#define BIO_get_cipher_ctx(b,c_pp)	BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+int EVP_Cipher(EVP_CIPHER_CTX *c,
+		unsigned char *out,
+		const unsigned char *in,
+		unsigned int inl);
+
+#define EVP_add_cipher_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_add_digest_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_delete_cipher_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+#define EVP_delete_digest_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+void	EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+int	EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_create(void);
+void	EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+int     EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+void	EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
+void	EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
+int 	EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags);
+int	EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+int	EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
+			 size_t cnt);
+int	EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+int	EVP_Digest(const void *data, size_t count,
+		unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl);
+
+int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+int	EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+
+int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
+void	EVP_set_pw_prompt(const char *prompt);
+char *	EVP_get_pw_prompt(void);
+
+int	EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
+		const unsigned char *salt, const unsigned char *data,
+		int datal, int count, unsigned char *key,unsigned char *iv);
+
+int	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+int	EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int	EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		       const unsigned char *key,const unsigned char *iv,
+		       int enc);
+int	EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		       const unsigned char *key,const unsigned char *iv,
+		       int enc);
+int	EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int	EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
+		EVP_PKEY *pkey);
+
+int	EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
+		unsigned int siglen,EVP_PKEY *pkey);
+
+int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
+		const unsigned char *ek, int ekl, const unsigned char *iv,
+		EVP_PKEY *priv);
+int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+		 unsigned char **ek, int *ekl, unsigned char *iv,
+		EVP_PKEY **pubk, int npubk);
+int	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
+
+void	EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void	EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		const unsigned char *in,int inl);
+void	EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
+int	EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void	EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int	EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		const unsigned char *in, int inl);
+int	EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+		char *out, int *outl);
+int	EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_md(void);
+BIO_METHOD *BIO_f_base64(void);
+BIO_METHOD *BIO_f_cipher(void);
+BIO_METHOD *BIO_f_reliable(void);
+void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,const unsigned char *k,
+		const unsigned char *i, int enc);
+#endif
+
+const EVP_MD *EVP_md_null(void);
+#ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void);
+#endif
+#ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void);
+#endif
+#ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void);
+#endif
+#ifndef OPENSSL_NO_SHA
+const EVP_MD *EVP_sha(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_dss(void);
+const EVP_MD *EVP_dss1(void);
+const EVP_MD *EVP_ecdsa(void);
+#endif
+#ifndef OPENSSL_NO_SHA256
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+#endif
+#ifndef OPENSSL_NO_SHA512
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+#endif
+#ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void);
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+const EVP_MD *EVP_ripemd160(void);
+#endif
+const EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
+#ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void);
+const EVP_CIPHER *EVP_des_ede(void);
+const EVP_CIPHER *EVP_des_ede3(void);
+const EVP_CIPHER *EVP_des_ede_ecb(void);
+const EVP_CIPHER *EVP_des_ede3_ecb(void);
+const EVP_CIPHER *EVP_des_cfb64(void);
+# define EVP_des_cfb EVP_des_cfb64
+const EVP_CIPHER *EVP_des_cfb1(void);
+const EVP_CIPHER *EVP_des_cfb8(void);
+const EVP_CIPHER *EVP_des_ede_cfb64(void);
+# define EVP_des_ede_cfb EVP_des_ede_cfb64
+#if 0
+const EVP_CIPHER *EVP_des_ede_cfb1(void);
+const EVP_CIPHER *EVP_des_ede_cfb8(void);
+#endif
+const EVP_CIPHER *EVP_des_ede3_cfb64(void);
+# define EVP_des_ede3_cfb EVP_des_ede3_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb1(void);
+const EVP_CIPHER *EVP_des_ede3_cfb8(void);
+const EVP_CIPHER *EVP_des_ofb(void);
+const EVP_CIPHER *EVP_des_ede_ofb(void);
+const EVP_CIPHER *EVP_des_ede3_ofb(void);
+const EVP_CIPHER *EVP_des_cbc(void);
+const EVP_CIPHER *EVP_des_ede_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_desx_cbc(void);
+/* This should now be supported through the dev_crypto ENGINE. But also, why are
+ * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */
+#if 0
+# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_dev_crypto_rc4(void);
+const EVP_MD *EVP_dev_crypto_md5(void);
+# endif
+#endif
+#endif
+#ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void);
+const EVP_CIPHER *EVP_rc4_40(void);
+#endif
+#ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void);
+const EVP_CIPHER *EVP_idea_cfb64(void);
+# define EVP_idea_cfb EVP_idea_cfb64
+const EVP_CIPHER *EVP_idea_ofb(void);
+const EVP_CIPHER *EVP_idea_cbc(void);
+#endif
+#ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void);
+const EVP_CIPHER *EVP_rc2_cbc(void);
+const EVP_CIPHER *EVP_rc2_40_cbc(void);
+const EVP_CIPHER *EVP_rc2_64_cbc(void);
+const EVP_CIPHER *EVP_rc2_cfb64(void);
+# define EVP_rc2_cfb EVP_rc2_cfb64
+const EVP_CIPHER *EVP_rc2_ofb(void);
+#endif
+#ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void);
+const EVP_CIPHER *EVP_bf_cbc(void);
+const EVP_CIPHER *EVP_bf_cfb64(void);
+# define EVP_bf_cfb EVP_bf_cfb64
+const EVP_CIPHER *EVP_bf_ofb(void);
+#endif
+#ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void);
+const EVP_CIPHER *EVP_cast5_cbc(void);
+const EVP_CIPHER *EVP_cast5_cfb64(void);
+# define EVP_cast5_cfb EVP_cast5_cfb64
+const EVP_CIPHER *EVP_cast5_ofb(void);
+#endif
+#ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
+# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+#endif
+#ifndef OPENSSL_NO_AES
+const EVP_CIPHER *EVP_aes_128_ecb(void);
+const EVP_CIPHER *EVP_aes_128_cbc(void);
+const EVP_CIPHER *EVP_aes_128_cfb1(void);
+const EVP_CIPHER *EVP_aes_128_cfb8(void);
+const EVP_CIPHER *EVP_aes_128_cfb128(void);
+# define EVP_aes_128_cfb EVP_aes_128_cfb128
+const EVP_CIPHER *EVP_aes_128_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_128_ctr(void);
+#endif
+const EVP_CIPHER *EVP_aes_192_ecb(void);
+const EVP_CIPHER *EVP_aes_192_cbc(void);
+const EVP_CIPHER *EVP_aes_192_cfb1(void);
+const EVP_CIPHER *EVP_aes_192_cfb8(void);
+const EVP_CIPHER *EVP_aes_192_cfb128(void);
+# define EVP_aes_192_cfb EVP_aes_192_cfb128
+const EVP_CIPHER *EVP_aes_192_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_192_ctr(void);
+#endif
+const EVP_CIPHER *EVP_aes_256_ecb(void);
+const EVP_CIPHER *EVP_aes_256_cbc(void);
+const EVP_CIPHER *EVP_aes_256_cfb1(void);
+const EVP_CIPHER *EVP_aes_256_cfb8(void);
+const EVP_CIPHER *EVP_aes_256_cfb128(void);
+# define EVP_aes_256_cfb EVP_aes_256_cfb128
+const EVP_CIPHER *EVP_aes_256_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_256_ctr(void);
+#endif
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+const EVP_CIPHER *EVP_camellia_128_ecb(void);
+const EVP_CIPHER *EVP_camellia_128_cbc(void);
+const EVP_CIPHER *EVP_camellia_128_cfb1(void);
+const EVP_CIPHER *EVP_camellia_128_cfb8(void);
+const EVP_CIPHER *EVP_camellia_128_cfb128(void);
+# define EVP_camellia_128_cfb EVP_camellia_128_cfb128
+const EVP_CIPHER *EVP_camellia_128_ofb(void);
+const EVP_CIPHER *EVP_camellia_192_ecb(void);
+const EVP_CIPHER *EVP_camellia_192_cbc(void);
+const EVP_CIPHER *EVP_camellia_192_cfb1(void);
+const EVP_CIPHER *EVP_camellia_192_cfb8(void);
+const EVP_CIPHER *EVP_camellia_192_cfb128(void);
+# define EVP_camellia_192_cfb EVP_camellia_192_cfb128
+const EVP_CIPHER *EVP_camellia_192_ofb(void);
+const EVP_CIPHER *EVP_camellia_256_ecb(void);
+const EVP_CIPHER *EVP_camellia_256_cbc(void);
+const EVP_CIPHER *EVP_camellia_256_cfb1(void);
+const EVP_CIPHER *EVP_camellia_256_cfb8(void);
+const EVP_CIPHER *EVP_camellia_256_cfb128(void);
+# define EVP_camellia_256_cfb EVP_camellia_256_cfb128
+const EVP_CIPHER *EVP_camellia_256_ofb(void);
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void);
+void OPENSSL_add_all_algorithms_conf(void);
+
+#ifdef OPENSSL_LOAD_CONF
+#define OpenSSL_add_all_algorithms() \
+		OPENSSL_add_all_algorithms_conf()
+#else
+#define OpenSSL_add_all_algorithms() \
+		OPENSSL_add_all_algorithms_noconf()
+#endif
+
+void OpenSSL_add_all_ciphers(void);
+void OpenSSL_add_all_digests(void);
+#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+#define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(const EVP_CIPHER *cipher);
+int EVP_add_digest(const EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+void EVP_cleanup(void);
+
+int		EVP_PKEY_decrypt(unsigned char *dec_key,
+			const unsigned char *enc_key,int enc_key_len,
+			EVP_PKEY *private_key);
+int		EVP_PKEY_encrypt(unsigned char *enc_key,
+			const unsigned char *key,int key_len,
+			EVP_PKEY *pub_key);
+int		EVP_PKEY_type(int type);
+int		EVP_PKEY_bits(EVP_PKEY *pkey);
+int		EVP_PKEY_size(EVP_PKEY *pkey);
+int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key);
+
+#ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,struct rsa_st *key);
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,struct dsa_st *key);
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey,struct dh_st *key);
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_EC
+struct ec_key_st;
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,struct ec_key_st *key);
+struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+#endif
+
+EVP_PKEY *	EVP_PKEY_new(void);
+void		EVP_PKEY_free(EVP_PKEY *pkey);
+
+EVP_PKEY *	d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
+			long length);
+int		i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *	d2i_PrivateKey(int type,EVP_PKEY **a, const unsigned char **pp,
+			long length);
+EVP_PKEY *	d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+			long length);
+int		i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de);
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+		    EVP_PBE_KEYGEN *keygen);
+void EVP_PBE_cleanup(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EVP_strings(void);
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+#define EVP_F_AES_INIT_KEY				 133
+#define EVP_F_CAMELLIA_INIT_KEY				 159
+#define EVP_F_D2I_PKEY					 100
+#define EVP_F_DSAPKEY2PKCS8				 134
+#define EVP_F_DSA_PKEY2PKCS8				 135
+#define EVP_F_ECDSA_PKEY2PKCS8				 129
+#define EVP_F_ECKEY_PKEY2PKCS8				 132
+#define EVP_F_EVP_CIPHERINIT_EX				 123
+#define EVP_F_EVP_CIPHER_CTX_CTRL			 124
+#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH		 122
+#define EVP_F_EVP_DECRYPTFINAL_EX			 101
+#define EVP_F_EVP_DIGESTINIT_EX				 128
+#define EVP_F_EVP_ENCRYPTFINAL_EX			 127
+#define EVP_F_EVP_MD_CTX_COPY_EX			 110
+#define EVP_F_EVP_OPENINIT				 102
+#define EVP_F_EVP_PBE_ALG_ADD				 115
+#define EVP_F_EVP_PBE_CIPHERINIT			 116
+#define EVP_F_EVP_PKCS82PKEY				 111
+#define EVP_F_EVP_PKEY2PKCS8_BROKEN			 113
+#define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
+#define EVP_F_EVP_PKEY_DECRYPT				 104
+#define EVP_F_EVP_PKEY_ENCRYPT				 105
+#define EVP_F_EVP_PKEY_GET1_DH				 119
+#define EVP_F_EVP_PKEY_GET1_DSA				 120
+#define EVP_F_EVP_PKEY_GET1_ECDSA			 130
+#define EVP_F_EVP_PKEY_GET1_EC_KEY			 131
+#define EVP_F_EVP_PKEY_GET1_RSA				 121
+#define EVP_F_EVP_PKEY_NEW				 106
+#define EVP_F_EVP_RIJNDAEL				 126
+#define EVP_F_EVP_SIGNFINAL				 107
+#define EVP_F_EVP_VERIFYFINAL				 108
+#define EVP_F_PKCS5_PBE_KEYIVGEN			 117
+#define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
+#define EVP_F_PKCS8_SET_BROKEN				 112
+#define EVP_F_RC2_MAGIC_TO_METH				 109
+#define EVP_F_RC5_CTRL					 125
+
+/* Reason codes. */
+#define EVP_R_AES_KEY_SETUP_FAILED			 143
+#define EVP_R_ASN1_LIB					 140
+#define EVP_R_BAD_BLOCK_LENGTH				 136
+#define EVP_R_BAD_DECRYPT				 100
+#define EVP_R_BAD_KEY_LENGTH				 137
+#define EVP_R_BN_DECODE_ERROR				 112
+#define EVP_R_BN_PUBKEY_ERROR				 113
+#define EVP_R_CAMELLIA_KEY_SETUP_FAILED			 157
+#define EVP_R_CIPHER_PARAMETER_ERROR			 122
+#define EVP_R_CTRL_NOT_IMPLEMENTED			 132
+#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED		 133
+#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH		 138
+#define EVP_R_DECODE_ERROR				 114
+#define EVP_R_DIFFERENT_KEY_TYPES			 101
+#define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
+#define EVP_R_EXPECTING_AN_RSA_KEY			 127
+#define EVP_R_EXPECTING_A_DH_KEY			 128
+#define EVP_R_EXPECTING_A_DSA_KEY			 129
+#define EVP_R_EXPECTING_A_ECDSA_KEY			 141
+#define EVP_R_EXPECTING_A_EC_KEY			 142
+#define EVP_R_INITIALIZATION_ERROR			 134
+#define EVP_R_INPUT_NOT_INITIALIZED			 111
+#define EVP_R_INVALID_KEY_LENGTH			 130
+#define EVP_R_IV_TOO_LARGE				 102
+#define EVP_R_KEYGEN_FAILURE				 120
+#define EVP_R_MISSING_PARAMETERS			 103
+#define EVP_R_NO_CIPHER_SET				 131
+#define EVP_R_NO_DIGEST_SET				 139
+#define EVP_R_NO_DSA_PARAMETERS				 116
+#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
+#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
+#define EVP_R_PUBLIC_KEY_NOT_RSA			 106
+#define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
+#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
+#define EVP_R_UNSUPPORTED_CIPHER			 107
+#define EVP_R_UNSUPPORTED_KEYLENGTH			 123
+#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
+#define EVP_R_UNSUPPORTED_KEY_SIZE			 108
+#define EVP_R_UNSUPPORTED_PRF				 125
+#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM		 118
+#define EVP_R_UNSUPPORTED_SALT_TYPE			 126
+#define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
+#define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/hmac.h b/dep/include/openssl/hmac.h
new file mode 100644
index 000000000..719fc408a
--- /dev/null
+++ b/dep/include/openssl/hmac.h
@@ -0,0 +1,108 @@
+/* crypto/hmac/hmac.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#ifndef HEADER_HMAC_H
+#define HEADER_HMAC_H
+
+#include 
+
+#ifdef OPENSSL_NO_HMAC
+#error HMAC is disabled.
+#endif
+
+#include 
+
+#define HMAC_MAX_MD_CBLOCK	128	/* largest known is SHA512 */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct hmac_ctx_st
+	{
+	const EVP_MD *md;
+	EVP_MD_CTX md_ctx;
+	EVP_MD_CTX i_ctx;
+	EVP_MD_CTX o_ctx;
+	unsigned int key_length;
+	unsigned char key[HMAC_MAX_MD_CBLOCK];
+	} HMAC_CTX;
+
+#define HMAC_size(e)	(EVP_MD_size((e)->md))
+
+
+void HMAC_CTX_init(HMAC_CTX *ctx);
+void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
+
+void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+	       const EVP_MD *md); /* deprecated */
+void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+		  const EVP_MD *md, ENGINE *impl);
+void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
+void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+		    const unsigned char *d, size_t n, unsigned char *md,
+		    unsigned int *md_len);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/idea.h b/dep/include/openssl/idea.h
new file mode 100644
index 000000000..bf97a37e3
--- /dev/null
+++ b/dep/include/openssl/idea.h
@@ -0,0 +1,100 @@
+/* crypto/idea/idea.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_IDEA_H
+#define HEADER_IDEA_H
+
+#include  /* IDEA_INT, OPENSSL_NO_IDEA */
+
+#ifdef OPENSSL_NO_IDEA
+#error IDEA is disabled.
+#endif
+
+#define IDEA_ENCRYPT	1
+#define IDEA_DECRYPT	0
+
+#define IDEA_BLOCK	8
+#define IDEA_KEY_LENGTH	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct idea_key_st
+	{
+	IDEA_INT data[9][6];
+	} IDEA_KEY_SCHEDULE;
+
+const char *idea_options(void);
+void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	IDEA_KEY_SCHEDULE *ks);
+void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
+void idea_set_decrypt_key(const IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
+void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc);
+void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+	int *num,int enc);
+void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num);
+void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/krb5_asn.h b/dep/include/openssl/krb5_asn.h
new file mode 100644
index 000000000..41725d0dc
--- /dev/null
+++ b/dep/include/openssl/krb5_asn.h
@@ -0,0 +1,256 @@
+/* krb5_asn.h */
+/* Written by Vern Staats  for the OpenSSL project,
+** using ocsp/{*.h,*asn*.c} as a starting point
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_KRB5_ASN_H
+#define HEADER_KRB5_ASN_H
+
+/*
+#include 
+*/
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/*	ASN.1 from Kerberos RFC 1510
+*/
+
+/*	EncryptedData ::=   SEQUENCE {
+**		etype[0]                      INTEGER, -- EncryptionType
+**		kvno[1]                       INTEGER OPTIONAL,
+**		cipher[2]                     OCTET STRING -- ciphertext
+**	}
+*/
+typedef	struct	krb5_encdata_st
+	{
+	ASN1_INTEGER			*etype;
+	ASN1_INTEGER			*kvno;
+	ASN1_OCTET_STRING		*cipher;
+	}	KRB5_ENCDATA;
+
+DECLARE_STACK_OF(KRB5_ENCDATA)
+
+/*	PrincipalName ::=   SEQUENCE {
+**		name-type[0]                  INTEGER,
+**		name-string[1]                SEQUENCE OF GeneralString
+**	}
+*/
+typedef	struct	krb5_princname_st
+	{
+	ASN1_INTEGER			*nametype;
+	STACK_OF(ASN1_GENERALSTRING)	*namestring;
+	}	KRB5_PRINCNAME;
+
+DECLARE_STACK_OF(KRB5_PRINCNAME)
+
+
+/*	Ticket ::=	[APPLICATION 1] SEQUENCE {
+**		tkt-vno[0]                    INTEGER,
+**		realm[1]                      Realm,
+**		sname[2]                      PrincipalName,
+**		enc-part[3]                   EncryptedData
+**	}
+*/
+typedef	struct	krb5_tktbody_st
+	{
+	ASN1_INTEGER			*tktvno;
+	ASN1_GENERALSTRING		*realm;
+	KRB5_PRINCNAME			*sname;
+	KRB5_ENCDATA			*encdata;
+	}	KRB5_TKTBODY;
+
+typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
+DECLARE_STACK_OF(KRB5_TKTBODY)
+
+
+/*	AP-REQ ::=      [APPLICATION 14] SEQUENCE {
+**		pvno[0]                       INTEGER,
+**		msg-type[1]                   INTEGER,
+**		ap-options[2]                 APOptions,
+**		ticket[3]                     Ticket,
+**		authenticator[4]              EncryptedData
+**	}
+**
+**	APOptions ::=   BIT STRING {
+**		reserved(0), use-session-key(1), mutual-required(2) }
+*/
+typedef	struct	krb5_ap_req_st
+	{
+	ASN1_INTEGER			*pvno;
+	ASN1_INTEGER			*msgtype;
+	ASN1_BIT_STRING			*apoptions;
+	KRB5_TICKET			*ticket;
+	KRB5_ENCDATA			*authenticator;
+	}	KRB5_APREQBODY;
+
+typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
+DECLARE_STACK_OF(KRB5_APREQBODY)
+
+
+/*	Authenticator Stuff	*/
+
+
+/*	Checksum ::=   SEQUENCE {
+**		cksumtype[0]                  INTEGER,
+**		checksum[1]                   OCTET STRING
+**	}
+*/
+typedef	struct	krb5_checksum_st
+	{
+	ASN1_INTEGER			*ctype;
+	ASN1_OCTET_STRING		*checksum;
+	}	KRB5_CHECKSUM;
+
+DECLARE_STACK_OF(KRB5_CHECKSUM)
+
+
+/*	EncryptionKey ::=   SEQUENCE {
+**		keytype[0]                    INTEGER,
+**		keyvalue[1]                   OCTET STRING
+**	}
+*/
+typedef struct  krb5_encryptionkey_st
+	{
+	ASN1_INTEGER			*ktype;
+	ASN1_OCTET_STRING		*keyvalue;
+	}	KRB5_ENCKEY;
+
+DECLARE_STACK_OF(KRB5_ENCKEY)
+
+
+/*	AuthorizationData ::=   SEQUENCE OF SEQUENCE {
+**		ad-type[0]                    INTEGER,
+**              ad-data[1]                    OCTET STRING
+**	}
+*/
+typedef struct	krb5_authorization_st
+	{
+	ASN1_INTEGER			*adtype;
+	ASN1_OCTET_STRING		*addata;
+	}	KRB5_AUTHDATA;
+
+DECLARE_STACK_OF(KRB5_AUTHDATA)
+
+			
+/*	-- Unencrypted authenticator
+**	Authenticator ::=    [APPLICATION 2] SEQUENCE    {
+**		authenticator-vno[0]          INTEGER,
+**		crealm[1]                     Realm,
+**		cname[2]                      PrincipalName,
+**		cksum[3]                      Checksum OPTIONAL,
+**		cusec[4]                      INTEGER,
+**		ctime[5]                      KerberosTime,
+**		subkey[6]                     EncryptionKey OPTIONAL,
+**		seq-number[7]                 INTEGER OPTIONAL,
+**		authorization-data[8]         AuthorizationData OPTIONAL
+**	}
+*/
+typedef struct	krb5_authenticator_st
+	{
+	ASN1_INTEGER			*avno;
+	ASN1_GENERALSTRING		*crealm;
+	KRB5_PRINCNAME			*cname;
+	KRB5_CHECKSUM			*cksum;
+	ASN1_INTEGER			*cusec;
+	ASN1_GENERALIZEDTIME		*ctime;
+	KRB5_ENCKEY			*subkey;
+	ASN1_INTEGER			*seqnum;
+	KRB5_AUTHDATA			*authorization;
+	}	KRB5_AUTHENTBODY;
+
+typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
+DECLARE_STACK_OF(KRB5_AUTHENTBODY)
+
+
+/*  DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
+**	type *name##_new(void);
+**	void name##_free(type *a);
+**	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
+**	 DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
+**	  type *d2i_##name(type **a, const unsigned char **in, long len);
+**	  int i2d_##name(type *a, unsigned char **out);
+**	  DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
+*/
+
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
+DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)
+
+DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/kssl.h b/dep/include/openssl/kssl.h
new file mode 100644
index 000000000..a3d20e1cc
--- /dev/null
+++ b/dep/include/openssl/kssl.h
@@ -0,0 +1,179 @@
+/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats  for the OpenSSL project 2000.
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+**	19990701	VRS 	Started.
+*/
+
+#ifndef	KSSL_H
+#define	KSSL_H
+
+#include 
+
+#ifndef OPENSSL_NO_KRB5
+
+#include 
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+**	Depending on which KRB5 implementation used, some types from
+**	the other may be missing.  Resolve that here and now
+*/
+#ifdef KRB5_HEIMDAL
+typedef unsigned char krb5_octet;
+#define FAR
+#else
+
+#ifndef FAR
+#define FAR
+#endif
+
+#endif
+
+/*	Uncomment this to debug kssl problems or
+**	to trace usage of the Kerberos session key
+**
+**	#define		KSSL_DEBUG
+*/
+
+#ifndef	KRB5SVC
+#define KRB5SVC	"host"
+#endif
+
+#ifndef	KRB5KEYTAB
+#define KRB5KEYTAB	"/etc/krb5.keytab"
+#endif
+
+#ifndef KRB5SENDAUTH
+#define KRB5SENDAUTH	1
+#endif
+
+#ifndef KRB5CHECKAUTH
+#define KRB5CHECKAUTH	1
+#endif
+
+#ifndef KSSL_CLOCKSKEW
+#define	KSSL_CLOCKSKEW	300;
+#endif
+
+#define	KSSL_ERR_MAX	255
+typedef struct kssl_err_st  {
+	int  reason;
+	char text[KSSL_ERR_MAX+1];
+	} KSSL_ERR;
+
+
+/*	Context for passing
+**		(1) Kerberos session key to SSL, and
+**		(2)	Config data between application and SSL lib
+*/
+typedef struct kssl_ctx_st
+        {
+                                /*	used by:    disposition:            */
+	char *service_name;	/*	C,S	    default ok (kssl)       */
+	char *service_host;	/*	C	    input, REQUIRED         */
+	char *client_princ;	/*	S	    output from krb5 ticket */
+	char *keytab_file;	/*      S	    NULL (/etc/krb5.keytab) */
+	char *cred_cache;	/*	C	    NULL (default)          */
+	krb5_enctype enctype;
+	int length;
+	krb5_octet FAR *key;
+	} KSSL_CTX;
+
+#define	KSSL_CLIENT 	1
+#define KSSL_SERVER 	2
+#define	KSSL_SERVICE	3
+#define	KSSL_KEYTAB 	4
+
+#define KSSL_CTX_OK 	0
+#define KSSL_CTX_ERR	1
+#define KSSL_NOMEM	2
+
+/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
+krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
+KSSL_CTX *kssl_ctx_new(void);
+KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
+void kssl_ctx_show(KSSL_CTX *kssl_ctx);
+krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+        krb5_data *realm, krb5_data *entity, int nentities);
+krb5_error_code	kssl_cget_tkt(KSSL_CTX *kssl_ctx,  krb5_data **enc_tktp,
+        krb5_data *authenp, KSSL_ERR *kssl_err);
+krb5_error_code	kssl_sget_tkt(KSSL_CTX *kssl_ctx,  krb5_data *indata,
+        krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
+krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
+void	kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
+void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
+krb5_error_code  kssl_build_principal_2(krb5_context context,
+			krb5_principal *princ, int rlen, const char *realm,
+			int slen, const char *svc, int hlen, const char *host);
+krb5_error_code  kssl_validate_times(krb5_timestamp atime,
+					krb5_ticket_times *ttimes);
+krb5_error_code  kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
+			            krb5_timestamp *atimep, KSSL_ERR *kssl_err);
+unsigned char	*kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif	/* OPENSSL_NO_KRB5	*/
+#endif	/* KSSL_H 	*/
diff --git a/dep/include/openssl/lhash.h b/dep/include/openssl/lhash.h
new file mode 100644
index 000000000..d392d0cd8
--- /dev/null
+++ b/dep/include/openssl/lhash.h
@@ -0,0 +1,200 @@
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+#define HEADER_LHASH_H
+
+#include 
+#ifndef OPENSSL_NO_FP_API
+#include 
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct lhash_node_st
+	{
+	void *data;
+	struct lhash_node_st *next;
+#ifndef OPENSSL_NO_HASH_COMP
+	unsigned long hash;
+#endif
+	} LHASH_NODE;
+
+typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *);
+typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *);
+typedef void (*LHASH_DOALL_FN_TYPE)(void *);
+typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *);
+
+/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks.
+ * This way, callbacks can be provided to LHASH structures without function
+ * pointer casting and the macro-defined callbacks provide per-variable casting
+ * before deferring to the underlying type-specific callbacks. NB: It is
+ * possible to place a "static" in front of both the DECLARE and IMPLEMENT
+ * macros if the functions are strictly internal. */
+
+/* First: "hash" functions */
+#define DECLARE_LHASH_HASH_FN(f_name,o_type) \
+	unsigned long f_name##_LHASH_HASH(const void *);
+#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \
+	unsigned long f_name##_LHASH_HASH(const void *arg) { \
+		o_type a = (o_type)arg; \
+		return f_name(a); }
+#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH
+
+/* Second: "compare" functions */
+#define DECLARE_LHASH_COMP_FN(f_name,o_type) \
+	int f_name##_LHASH_COMP(const void *, const void *);
+#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \
+	int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+		o_type a = (o_type)arg1; \
+		o_type b = (o_type)arg2; \
+		return f_name(a,b); }
+#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP
+
+/* Third: "doall" functions */
+#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \
+	void f_name##_LHASH_DOALL(void *);
+#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \
+	void f_name##_LHASH_DOALL(void *arg) { \
+		o_type a = (o_type)arg; \
+		f_name(a); }
+#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL
+
+/* Fourth: "doall_arg" functions */
+#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
+	void f_name##_LHASH_DOALL_ARG(void *, void *);
+#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
+	void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+		o_type a = (o_type)arg1; \
+		a_type b = (a_type)arg2; \
+		f_name(a,b); }
+#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG
+
+typedef struct lhash_st
+	{
+	LHASH_NODE **b;
+	LHASH_COMP_FN_TYPE comp;
+	LHASH_HASH_FN_TYPE hash;
+	unsigned int num_nodes;
+	unsigned int num_alloc_nodes;
+	unsigned int p;
+	unsigned int pmax;
+	unsigned long up_load; /* load times 256 */
+	unsigned long down_load; /* load times 256 */
+	unsigned long num_items;
+
+	unsigned long num_expands;
+	unsigned long num_expand_reallocs;
+	unsigned long num_contracts;
+	unsigned long num_contract_reallocs;
+	unsigned long num_hash_calls;
+	unsigned long num_comp_calls;
+	unsigned long num_insert;
+	unsigned long num_replace;
+	unsigned long num_delete;
+	unsigned long num_no_delete;
+	unsigned long num_retrieve;
+	unsigned long num_retrieve_miss;
+	unsigned long num_hash_comps;
+
+	int error;
+	} LHASH;
+
+#define LH_LOAD_MULT	256
+
+/* Indicates a malloc() error in the last call, this is only bad
+ * in lh_insert(). */
+#define lh_error(lh)	((lh)->error)
+
+LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(LHASH *lh);
+void *lh_insert(LHASH *lh, void *data);
+void *lh_delete(LHASH *lh, const void *data);
+void *lh_retrieve(LHASH *lh, const void *data);
+void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+unsigned long lh_strhash(const char *c);
+unsigned long lh_num_items(const LHASH *lh);
+
+#ifndef OPENSSL_NO_FP_API
+void lh_stats(const LHASH *lh, FILE *out);
+void lh_node_stats(const LHASH *lh, FILE *out);
+void lh_node_usage_stats(const LHASH *lh, FILE *out);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+void lh_stats_bio(const LHASH *lh, BIO *out);
+void lh_node_stats_bio(const LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const LHASH *lh, BIO *out);
+#endif
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/dep/include/openssl/md2.h b/dep/include/openssl/md2.h
new file mode 100644
index 000000000..a46120e7d
--- /dev/null
+++ b/dep/include/openssl/md2.h
@@ -0,0 +1,92 @@
+/* crypto/md/md2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD2_H
+#define HEADER_MD2_H
+
+#include  /* OPENSSL_NO_MD2, MD2_INT */
+#ifdef OPENSSL_NO_MD2
+#error MD2 is disabled.
+#endif
+#include 
+
+#define MD2_DIGEST_LENGTH	16
+#define MD2_BLOCK       	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct MD2state_st
+	{
+	unsigned int num;
+	unsigned char data[MD2_BLOCK];
+	MD2_INT cksm[MD2_BLOCK];
+	MD2_INT state[MD2_BLOCK];
+	} MD2_CTX;
+
+const char *MD2_options(void);
+int MD2_Init(MD2_CTX *c);
+int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
+int MD2_Final(unsigned char *md, MD2_CTX *c);
+unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/md4.h b/dep/include/openssl/md4.h
new file mode 100644
index 000000000..5598c93a4
--- /dev/null
+++ b/dep/include/openssl/md4.h
@@ -0,0 +1,117 @@
+/* crypto/md4/md4.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD4_H
+#define HEADER_MD4_H
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MD4
+#error MD4 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD4_LONG_LOG2 has to be defined along.			   !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define MD4_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define MD4_LONG unsigned long
+#define MD4_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					
+ */
+#else
+#define MD4_LONG unsigned int
+#endif
+
+#define MD4_CBLOCK	64
+#define MD4_LBLOCK	(MD4_CBLOCK/4)
+#define MD4_DIGEST_LENGTH 16
+
+typedef struct MD4state_st
+	{
+	MD4_LONG A,B,C,D;
+	MD4_LONG Nl,Nh;
+	MD4_LONG data[MD4_LBLOCK];
+	unsigned int num;
+	} MD4_CTX;
+
+int MD4_Init(MD4_CTX *c);
+int MD4_Update(MD4_CTX *c, const void *data, size_t len);
+int MD4_Final(unsigned char *md, MD4_CTX *c);
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
+void MD4_Transform(MD4_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/md5.h b/dep/include/openssl/md5.h
new file mode 100644
index 000000000..dbdc0e1ab
--- /dev/null
+++ b/dep/include/openssl/md5.h
@@ -0,0 +1,117 @@
+/* crypto/md5/md5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD5_H
+#define HEADER_MD5_H
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MD5
+#error MD5 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD5_LONG_LOG2 has to be defined along.			   !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define MD5_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define MD5_LONG unsigned long
+#define MD5_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					
+ */
+#else
+#define MD5_LONG unsigned int
+#endif
+
+#define MD5_CBLOCK	64
+#define MD5_LBLOCK	(MD5_CBLOCK/4)
+#define MD5_DIGEST_LENGTH 16
+
+typedef struct MD5state_st
+	{
+	MD5_LONG A,B,C,D;
+	MD5_LONG Nl,Nh;
+	MD5_LONG data[MD5_LBLOCK];
+	unsigned int num;
+	} MD5_CTX;
+
+int MD5_Init(MD5_CTX *c);
+int MD5_Update(MD5_CTX *c, const void *data, size_t len);
+int MD5_Final(unsigned char *md, MD5_CTX *c);
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/mdc2.h b/dep/include/openssl/mdc2.h
new file mode 100644
index 000000000..e5ba226ca
--- /dev/null
+++ b/dep/include/openssl/mdc2.h
@@ -0,0 +1,96 @@
+/* crypto/mdc2/mdc2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MDC2_H
+#define HEADER_MDC2_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MDC2
+#error MDC2 is disabled.
+#endif
+
+#define MDC2_BLOCK              8
+#define MDC2_DIGEST_LENGTH      16
+
+typedef struct mdc2_ctx_st
+	{
+	int num;
+	unsigned char data[MDC2_BLOCK];
+	DES_cblock h,hh;
+	int pad_type; /* either 1 or 2, default 1 */
+	} MDC2_CTX;
+
+
+int MDC2_Init(MDC2_CTX *c);
+int MDC2_Update(MDC2_CTX *c, const unsigned char *data, unsigned long len);
+int MDC2_Final(unsigned char *md, MDC2_CTX *c);
+unsigned char *MDC2(const unsigned char *d, unsigned long n,
+	unsigned char *md);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/dep/include/openssl/obj_mac.h b/dep/include/openssl/obj_mac.h
new file mode 100644
index 000000000..f447bbe69
--- /dev/null
+++ b/dep/include/openssl/obj_mac.h
@@ -0,0 +1,3408 @@
+/* crypto/objects/obj_mac.h */
+
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num obj_mac.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_itu_t		"ITU-T"
+#define LN_itu_t		"itu-t"
+#define NID_itu_t		645
+#define OBJ_itu_t		0L
+
+#define NID_ccitt		404
+#define OBJ_ccitt		OBJ_itu_t
+
+#define SN_iso		"ISO"
+#define LN_iso		"iso"
+#define NID_iso		181
+#define OBJ_iso		1L
+
+#define SN_joint_iso_itu_t		"JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t		"joint-iso-itu-t"
+#define NID_joint_iso_itu_t		646
+#define OBJ_joint_iso_itu_t		2L
+
+#define NID_joint_iso_ccitt		393
+#define OBJ_joint_iso_ccitt		OBJ_joint_iso_itu_t
+
+#define SN_member_body		"member-body"
+#define LN_member_body		"ISO Member Body"
+#define NID_member_body		182
+#define OBJ_member_body		OBJ_iso,2L
+
+#define SN_identified_organization		"identified-organization"
+#define NID_identified_organization		676
+#define OBJ_identified_organization		OBJ_iso,3L
+
+#define SN_certicom_arc		"certicom-arc"
+#define NID_certicom_arc		677
+#define OBJ_certicom_arc		OBJ_identified_organization,132L
+
+#define SN_international_organizations		"international-organizations"
+#define LN_international_organizations		"International Organizations"
+#define NID_international_organizations		647
+#define OBJ_international_organizations		OBJ_joint_iso_itu_t,23L
+
+#define SN_wap		"wap"
+#define NID_wap		678
+#define OBJ_wap		OBJ_international_organizations,43L
+
+#define SN_wap_wsg		"wap-wsg"
+#define NID_wap_wsg		679
+#define OBJ_wap_wsg		OBJ_wap,13L
+
+#define SN_selected_attribute_types		"selected-attribute-types"
+#define LN_selected_attribute_types		"Selected Attribute Types"
+#define NID_selected_attribute_types		394
+#define OBJ_selected_attribute_types		OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance		"clearance"
+#define NID_clearance		395
+#define OBJ_clearance		OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US		"ISO-US"
+#define LN_ISO_US		"ISO US Member Body"
+#define NID_ISO_US		183
+#define OBJ_ISO_US		OBJ_member_body,840L
+
+#define SN_X9_57		"X9-57"
+#define LN_X9_57		"X9.57"
+#define NID_X9_57		184
+#define OBJ_X9_57		OBJ_ISO_US,10040L
+
+#define SN_X9cm		"X9cm"
+#define LN_X9cm		"X9.57 CM ?"
+#define NID_X9cm		185
+#define OBJ_X9cm		OBJ_X9_57,4L
+
+#define SN_dsa		"DSA"
+#define LN_dsa		"dsaEncryption"
+#define NID_dsa		116
+#define OBJ_dsa		OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1		"DSA-SHA1"
+#define LN_dsaWithSHA1		"dsaWithSHA1"
+#define NID_dsaWithSHA1		113
+#define OBJ_dsaWithSHA1		OBJ_X9cm,3L
+
+#define SN_ansi_X9_62		"ansi-X9-62"
+#define LN_ansi_X9_62		"ANSI X9.62"
+#define NID_ansi_X9_62		405
+#define OBJ_ansi_X9_62		OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType		OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field		"prime-field"
+#define NID_X9_62_prime_field		406
+#define OBJ_X9_62_prime_field		OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field		"characteristic-two-field"
+#define NID_X9_62_characteristic_two_field		407
+#define OBJ_X9_62_characteristic_two_field		OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis		"id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis		680
+#define OBJ_X9_62_id_characteristic_two_basis		OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis		"onBasis"
+#define NID_X9_62_onBasis		681
+#define OBJ_X9_62_onBasis		OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis		"tpBasis"
+#define NID_X9_62_tpBasis		682
+#define OBJ_X9_62_tpBasis		OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis		"ppBasis"
+#define NID_X9_62_ppBasis		683
+#define OBJ_X9_62_ppBasis		OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType		OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey		"id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey		408
+#define OBJ_X9_62_id_ecPublicKey		OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve		OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve		OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1		"c2pnb163v1"
+#define NID_X9_62_c2pnb163v1		684
+#define OBJ_X9_62_c2pnb163v1		OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2		"c2pnb163v2"
+#define NID_X9_62_c2pnb163v2		685
+#define OBJ_X9_62_c2pnb163v2		OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3		"c2pnb163v3"
+#define NID_X9_62_c2pnb163v3		686
+#define OBJ_X9_62_c2pnb163v3		OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1		"c2pnb176v1"
+#define NID_X9_62_c2pnb176v1		687
+#define OBJ_X9_62_c2pnb176v1		OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1		"c2tnb191v1"
+#define NID_X9_62_c2tnb191v1		688
+#define OBJ_X9_62_c2tnb191v1		OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2		"c2tnb191v2"
+#define NID_X9_62_c2tnb191v2		689
+#define OBJ_X9_62_c2tnb191v2		OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3		"c2tnb191v3"
+#define NID_X9_62_c2tnb191v3		690
+#define OBJ_X9_62_c2tnb191v3		OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4		"c2onb191v4"
+#define NID_X9_62_c2onb191v4		691
+#define OBJ_X9_62_c2onb191v4		OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5		"c2onb191v5"
+#define NID_X9_62_c2onb191v5		692
+#define OBJ_X9_62_c2onb191v5		OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1		"c2pnb208w1"
+#define NID_X9_62_c2pnb208w1		693
+#define OBJ_X9_62_c2pnb208w1		OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1		"c2tnb239v1"
+#define NID_X9_62_c2tnb239v1		694
+#define OBJ_X9_62_c2tnb239v1		OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2		"c2tnb239v2"
+#define NID_X9_62_c2tnb239v2		695
+#define OBJ_X9_62_c2tnb239v2		OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3		"c2tnb239v3"
+#define NID_X9_62_c2tnb239v3		696
+#define OBJ_X9_62_c2tnb239v3		OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4		"c2onb239v4"
+#define NID_X9_62_c2onb239v4		697
+#define OBJ_X9_62_c2onb239v4		OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5		"c2onb239v5"
+#define NID_X9_62_c2onb239v5		698
+#define OBJ_X9_62_c2onb239v5		OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1		"c2pnb272w1"
+#define NID_X9_62_c2pnb272w1		699
+#define OBJ_X9_62_c2pnb272w1		OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1		"c2pnb304w1"
+#define NID_X9_62_c2pnb304w1		700
+#define OBJ_X9_62_c2pnb304w1		OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1		"c2tnb359v1"
+#define NID_X9_62_c2tnb359v1		701
+#define OBJ_X9_62_c2tnb359v1		OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1		"c2pnb368w1"
+#define NID_X9_62_c2pnb368w1		702
+#define OBJ_X9_62_c2pnb368w1		OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1		"c2tnb431r1"
+#define NID_X9_62_c2tnb431r1		703
+#define OBJ_X9_62_c2tnb431r1		OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve		OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1		"prime192v1"
+#define NID_X9_62_prime192v1		409
+#define OBJ_X9_62_prime192v1		OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2		"prime192v2"
+#define NID_X9_62_prime192v2		410
+#define OBJ_X9_62_prime192v2		OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3		"prime192v3"
+#define NID_X9_62_prime192v3		411
+#define OBJ_X9_62_prime192v3		OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1		"prime239v1"
+#define NID_X9_62_prime239v1		412
+#define OBJ_X9_62_prime239v1		OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2		"prime239v2"
+#define NID_X9_62_prime239v2		413
+#define OBJ_X9_62_prime239v2		OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3		"prime239v3"
+#define NID_X9_62_prime239v3		414
+#define OBJ_X9_62_prime239v3		OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1		"prime256v1"
+#define NID_X9_62_prime256v1		415
+#define OBJ_X9_62_prime256v1		OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType		OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1		"ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1		416
+#define OBJ_ecdsa_with_SHA1		OBJ_X9_62_id_ecSigType,1L
+
+#define OBJ_secg_ellipticCurve		OBJ_certicom_arc,0L
+
+#define SN_secp112r1		"secp112r1"
+#define NID_secp112r1		704
+#define OBJ_secp112r1		OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2		"secp112r2"
+#define NID_secp112r2		705
+#define OBJ_secp112r2		OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1		"secp128r1"
+#define NID_secp128r1		706
+#define OBJ_secp128r1		OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2		"secp128r2"
+#define NID_secp128r2		707
+#define OBJ_secp128r2		OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1		"secp160k1"
+#define NID_secp160k1		708
+#define OBJ_secp160k1		OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1		"secp160r1"
+#define NID_secp160r1		709
+#define OBJ_secp160r1		OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2		"secp160r2"
+#define NID_secp160r2		710
+#define OBJ_secp160r2		OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1		"secp192k1"
+#define NID_secp192k1		711
+#define OBJ_secp192k1		OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1		"secp224k1"
+#define NID_secp224k1		712
+#define OBJ_secp224k1		OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1		"secp224r1"
+#define NID_secp224r1		713
+#define OBJ_secp224r1		OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1		"secp256k1"
+#define NID_secp256k1		714
+#define OBJ_secp256k1		OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1		"secp384r1"
+#define NID_secp384r1		715
+#define OBJ_secp384r1		OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1		"secp521r1"
+#define NID_secp521r1		716
+#define OBJ_secp521r1		OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1		"sect113r1"
+#define NID_sect113r1		717
+#define OBJ_sect113r1		OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2		"sect113r2"
+#define NID_sect113r2		718
+#define OBJ_sect113r2		OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1		"sect131r1"
+#define NID_sect131r1		719
+#define OBJ_sect131r1		OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2		"sect131r2"
+#define NID_sect131r2		720
+#define OBJ_sect131r2		OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1		"sect163k1"
+#define NID_sect163k1		721
+#define OBJ_sect163k1		OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1		"sect163r1"
+#define NID_sect163r1		722
+#define OBJ_sect163r1		OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2		"sect163r2"
+#define NID_sect163r2		723
+#define OBJ_sect163r2		OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1		"sect193r1"
+#define NID_sect193r1		724
+#define OBJ_sect193r1		OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2		"sect193r2"
+#define NID_sect193r2		725
+#define OBJ_sect193r2		OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1		"sect233k1"
+#define NID_sect233k1		726
+#define OBJ_sect233k1		OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1		"sect233r1"
+#define NID_sect233r1		727
+#define OBJ_sect233r1		OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1		"sect239k1"
+#define NID_sect239k1		728
+#define OBJ_sect239k1		OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1		"sect283k1"
+#define NID_sect283k1		729
+#define OBJ_sect283k1		OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1		"sect283r1"
+#define NID_sect283r1		730
+#define OBJ_sect283r1		OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1		"sect409k1"
+#define NID_sect409k1		731
+#define OBJ_sect409k1		OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1		"sect409r1"
+#define NID_sect409r1		732
+#define OBJ_sect409r1		OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1		"sect571k1"
+#define NID_sect571k1		733
+#define OBJ_sect571k1		OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1		"sect571r1"
+#define NID_sect571r1		734
+#define OBJ_sect571r1		OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid		OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1		"wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1		735
+#define OBJ_wap_wsg_idm_ecid_wtls1		OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3		"wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3		736
+#define OBJ_wap_wsg_idm_ecid_wtls3		OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4		"wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4		737
+#define OBJ_wap_wsg_idm_ecid_wtls4		OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5		"wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5		738
+#define OBJ_wap_wsg_idm_ecid_wtls5		OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6		"wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6		739
+#define OBJ_wap_wsg_idm_ecid_wtls6		OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7		"wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7		740
+#define OBJ_wap_wsg_idm_ecid_wtls7		OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8		"wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8		741
+#define OBJ_wap_wsg_idm_ecid_wtls8		OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9		"wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9		742
+#define OBJ_wap_wsg_idm_ecid_wtls9		OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10		"wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10		743
+#define OBJ_wap_wsg_idm_ecid_wtls10		OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11		"wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11		744
+#define OBJ_wap_wsg_idm_ecid_wtls11		OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12		"wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12		745
+#define OBJ_wap_wsg_idm_ecid_wtls12		OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc		"CAST5-CBC"
+#define LN_cast5_cbc		"cast5-cbc"
+#define NID_cast5_cbc		108
+#define OBJ_cast5_cbc		OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb		"CAST5-ECB"
+#define LN_cast5_ecb		"cast5-ecb"
+#define NID_cast5_ecb		109
+
+#define SN_cast5_cfb64		"CAST5-CFB"
+#define LN_cast5_cfb64		"cast5-cfb"
+#define NID_cast5_cfb64		110
+
+#define SN_cast5_ofb64		"CAST5-OFB"
+#define LN_cast5_ofb64		"cast5-ofb"
+#define NID_cast5_ofb64		111
+
+#define LN_pbeWithMD5AndCast5_CBC		"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC		112
+#define OBJ_pbeWithMD5AndCast5_CBC		OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_rsadsi		"rsadsi"
+#define LN_rsadsi		"RSA Data Security, Inc."
+#define NID_rsadsi		1
+#define OBJ_rsadsi		OBJ_ISO_US,113549L
+
+#define SN_pkcs		"pkcs"
+#define LN_pkcs		"RSA Data Security, Inc. PKCS"
+#define NID_pkcs		2
+#define OBJ_pkcs		OBJ_rsadsi,1L
+
+#define SN_pkcs1		"pkcs1"
+#define NID_pkcs1		186
+#define OBJ_pkcs1		OBJ_pkcs,1L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption		7
+#define OBJ_md2WithRSAEncryption		OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption		"RSA-MD4"
+#define LN_md4WithRSAEncryption		"md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption		396
+#define OBJ_md4WithRSAEncryption		OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption		8
+#define OBJ_md5WithRSAEncryption		OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption		"RSA-SHA1"
+#define LN_sha1WithRSAEncryption		"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption		65
+#define OBJ_sha1WithRSAEncryption		OBJ_pkcs1,5L
+
+#define SN_sha256WithRSAEncryption		"RSA-SHA256"
+#define LN_sha256WithRSAEncryption		"sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption		668
+#define OBJ_sha256WithRSAEncryption		OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption		"RSA-SHA384"
+#define LN_sha384WithRSAEncryption		"sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption		669
+#define OBJ_sha384WithRSAEncryption		OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption		"RSA-SHA512"
+#define LN_sha512WithRSAEncryption		"sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption		670
+#define OBJ_sha512WithRSAEncryption		OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption		"RSA-SHA224"
+#define LN_sha224WithRSAEncryption		"sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption		671
+#define OBJ_sha224WithRSAEncryption		OBJ_pkcs1,14L
+
+#define SN_pkcs3		"pkcs3"
+#define NID_pkcs3		27
+#define OBJ_pkcs3		OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_pkcs5		"pkcs5"
+#define NID_pkcs5		187
+#define OBJ_pkcs5		OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC		9
+#define OBJ_pbeWithMD2AndDES_CBC		OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC		10
+#define OBJ_pbeWithMD5AndDES_CBC		OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC		168
+#define OBJ_pbeWithMD2AndRC2_CBC		OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC		169
+#define OBJ_pbeWithMD5AndRC2_CBC		OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC		"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC		"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC		170
+#define OBJ_pbeWithSHA1AndDES_CBC		OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC		"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC		"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC		68
+#define OBJ_pbeWithSHA1AndRC2_CBC		OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2		"PBKDF2"
+#define NID_id_pbkdf2		69
+#define OBJ_id_pbkdf2		OBJ_pkcs5,12L
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs5,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs5,14L
+
+#define SN_pkcs7		"pkcs7"
+#define NID_pkcs7		20
+#define OBJ_pkcs7		OBJ_pkcs,7L
+
+#define LN_pkcs7_data		"pkcs7-data"
+#define NID_pkcs7_data		21
+#define OBJ_pkcs7_data		OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed		"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped		"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped		24
+#define OBJ_pkcs7_signedAndEnveloped		OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest		"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define SN_pkcs9		"pkcs9"
+#define NID_pkcs9		47
+#define OBJ_pkcs9		OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName		"unstructuredName"
+#define NID_pkcs9_unstructuredName		49
+#define OBJ_pkcs9_unstructuredName		OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature		"countersignature"
+#define NID_pkcs9_countersignature		53
+#define OBJ_pkcs9_countersignature		OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword		"challengePassword"
+#define NID_pkcs9_challengePassword		54
+#define OBJ_pkcs9_challengePassword		OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress		"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress		55
+#define OBJ_pkcs9_unstructuredAddress		OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes		"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes		56
+#define OBJ_pkcs9_extCertAttributes		OBJ_pkcs9,9L
+
+#define SN_ext_req		"extReq"
+#define LN_ext_req		"Extension Request"
+#define NID_ext_req		172
+#define OBJ_ext_req		OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_SMIME		"SMIME"
+#define LN_SMIME		"S/MIME"
+#define NID_SMIME		188
+#define OBJ_SMIME		OBJ_pkcs9,16L
+
+#define SN_id_smime_mod		"id-smime-mod"
+#define NID_id_smime_mod		189
+#define OBJ_id_smime_mod		OBJ_SMIME,0L
+
+#define SN_id_smime_ct		"id-smime-ct"
+#define NID_id_smime_ct		190
+#define OBJ_id_smime_ct		OBJ_SMIME,1L
+
+#define SN_id_smime_aa		"id-smime-aa"
+#define NID_id_smime_aa		191
+#define OBJ_id_smime_aa		OBJ_SMIME,2L
+
+#define SN_id_smime_alg		"id-smime-alg"
+#define NID_id_smime_alg		192
+#define OBJ_id_smime_alg		OBJ_SMIME,3L
+
+#define SN_id_smime_cd		"id-smime-cd"
+#define NID_id_smime_cd		193
+#define OBJ_id_smime_cd		OBJ_SMIME,4L
+
+#define SN_id_smime_spq		"id-smime-spq"
+#define NID_id_smime_spq		194
+#define OBJ_id_smime_spq		OBJ_SMIME,5L
+
+#define SN_id_smime_cti		"id-smime-cti"
+#define NID_id_smime_cti		195
+#define OBJ_id_smime_cti		OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms		"id-smime-mod-cms"
+#define NID_id_smime_mod_cms		196
+#define OBJ_id_smime_mod_cms		OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess		"id-smime-mod-ess"
+#define NID_id_smime_mod_ess		197
+#define OBJ_id_smime_mod_ess		OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid		"id-smime-mod-oid"
+#define NID_id_smime_mod_oid		198
+#define OBJ_id_smime_mod_oid		OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3		"id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3		199
+#define OBJ_id_smime_mod_msg_v3		OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88		"id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88		200
+#define OBJ_id_smime_mod_ets_eSignature_88		OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97		"id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97		201
+#define OBJ_id_smime_mod_ets_eSignature_97		OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88		"id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88		202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88		OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97		"id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97		203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97		OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt		"id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt		204
+#define OBJ_id_smime_ct_receipt		OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData		"id-smime-ct-authData"
+#define NID_id_smime_ct_authData		205
+#define OBJ_id_smime_ct_authData		OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert		"id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert		206
+#define OBJ_id_smime_ct_publishCert		OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo		"id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo		207
+#define OBJ_id_smime_ct_TSTInfo		OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo		"id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo		208
+#define OBJ_id_smime_ct_TDTInfo		OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo		"id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo		209
+#define OBJ_id_smime_ct_contentInfo		OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData		"id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData		210
+#define OBJ_id_smime_ct_DVCSRequestData		OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData		"id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData		211
+#define OBJ_id_smime_ct_DVCSResponseData		OBJ_id_smime_ct,8L
+
+#define SN_id_smime_aa_receiptRequest		"id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest		212
+#define OBJ_id_smime_aa_receiptRequest		OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel		"id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel		213
+#define OBJ_id_smime_aa_securityLabel		OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory		"id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory		214
+#define OBJ_id_smime_aa_mlExpandHistory		OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint		"id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint		215
+#define OBJ_id_smime_aa_contentHint		OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest		"id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest		216
+#define OBJ_id_smime_aa_msgSigDigest		OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType		"id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType		217
+#define OBJ_id_smime_aa_encapContentType		OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier		"id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier		218
+#define OBJ_id_smime_aa_contentIdentifier		OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue		"id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue		219
+#define OBJ_id_smime_aa_macValue		OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels		"id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels		220
+#define OBJ_id_smime_aa_equivalentLabels		OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference		"id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference		221
+#define OBJ_id_smime_aa_contentReference		OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref		"id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref		222
+#define OBJ_id_smime_aa_encrypKeyPref		OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate		"id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate		223
+#define OBJ_id_smime_aa_signingCertificate		OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts		"id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts		224
+#define OBJ_id_smime_aa_smimeEncryptCerts		OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken		"id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken		225
+#define OBJ_id_smime_aa_timeStampToken		OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId		"id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId		226
+#define OBJ_id_smime_aa_ets_sigPolicyId		OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType		"id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType		227
+#define OBJ_id_smime_aa_ets_commitmentType		OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation		"id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation		228
+#define OBJ_id_smime_aa_ets_signerLocation		OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr		"id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr		229
+#define OBJ_id_smime_aa_ets_signerAttr		OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert		"id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert		230
+#define OBJ_id_smime_aa_ets_otherSigCert		OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp		"id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp		231
+#define OBJ_id_smime_aa_ets_contentTimestamp		OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs		"id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs		232
+#define OBJ_id_smime_aa_ets_CertificateRefs		OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs		"id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs		233
+#define OBJ_id_smime_aa_ets_RevocationRefs		OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues		"id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues		234
+#define OBJ_id_smime_aa_ets_certValues		OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues		"id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues		235
+#define OBJ_id_smime_aa_ets_revocationValues		OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp		"id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp		236
+#define OBJ_id_smime_aa_ets_escTimeStamp		OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp		"id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp		237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp		OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp		"id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp		238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp		OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType		"id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType		239
+#define OBJ_id_smime_aa_signatureType		OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc		"id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc		240
+#define OBJ_id_smime_aa_dvcs_dvc		OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES		"id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES		241
+#define OBJ_id_smime_alg_ESDHwith3DES		OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2		"id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2		242
+#define OBJ_id_smime_alg_ESDHwithRC2		OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap		"id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap		243
+#define OBJ_id_smime_alg_3DESwrap		OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap		"id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap		244
+#define OBJ_id_smime_alg_RC2wrap		OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH		"id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH		245
+#define OBJ_id_smime_alg_ESDH		OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap		"id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap		246
+#define OBJ_id_smime_alg_CMS3DESwrap		OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap		"id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap		247
+#define OBJ_id_smime_alg_CMSRC2wrap		OBJ_id_smime_alg,7L
+
+#define SN_id_smime_cd_ldap		"id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap		248
+#define OBJ_id_smime_cd_ldap		OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri		"id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri		249
+#define OBJ_id_smime_spq_ets_sqt_uri		OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice		"id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice		250
+#define OBJ_id_smime_spq_ets_sqt_unotice		OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin		"id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin		251
+#define OBJ_id_smime_cti_ets_proofOfOrigin		OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt		"id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt		252
+#define OBJ_id_smime_cti_ets_proofOfReceipt		OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery		"id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery		253
+#define OBJ_id_smime_cti_ets_proofOfDelivery		OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender		"id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender		254
+#define OBJ_id_smime_cti_ets_proofOfSender		OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval		"id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval		255
+#define OBJ_id_smime_cti_ets_proofOfApproval		OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation		"id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation		256
+#define OBJ_id_smime_cti_ets_proofOfCreation		OBJ_id_smime_cti,6L
+
+#define LN_friendlyName		"friendlyName"
+#define NID_friendlyName		156
+#define OBJ_friendlyName		OBJ_pkcs9,20L
+
+#define LN_localKeyID		"localKeyID"
+#define NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9,21L
+
+#define SN_ms_csp_name		"CSPName"
+#define LN_ms_csp_name		"Microsoft CSP Name"
+#define NID_ms_csp_name		417
+#define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define OBJ_certTypes		OBJ_pkcs9,22L
+
+#define LN_x509Certificate		"x509Certificate"
+#define NID_x509Certificate		158
+#define OBJ_x509Certificate		OBJ_certTypes,1L
+
+#define LN_sdsiCertificate		"sdsiCertificate"
+#define NID_sdsiCertificate		159
+#define OBJ_sdsiCertificate		OBJ_certTypes,2L
+
+#define OBJ_crlTypes		OBJ_pkcs9,23L
+
+#define LN_x509Crl		"x509Crl"
+#define NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes,1L
+
+#define OBJ_pkcs12		OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4		"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4		"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4		144
+#define OBJ_pbe_WithSHA1And128BitRC4		OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4		"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4		"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4		145
+#define OBJ_pbe_WithSHA1And40BitRC4		OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC		"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC		"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC		146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC		"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC		"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC		147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC		148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC		OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC		"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC		"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC		149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC		OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1		OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds		OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag		"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag		151
+#define OBJ_pkcs8ShroudedKeyBag		OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag		"safeContentsBag"
+#define NID_safeContentsBag		155
+#define OBJ_safeContentsBag		OBJ_pkcs12_BagIds,6L
+
+#define SN_md2		"MD2"
+#define LN_md2		"md2"
+#define NID_md2		3
+#define OBJ_md2		OBJ_rsadsi,2L,2L
+
+#define SN_md4		"MD4"
+#define LN_md4		"md4"
+#define NID_md4		257
+#define OBJ_md4		OBJ_rsadsi,2L,4L
+
+#define SN_md5		"MD5"
+#define LN_md5		"md5"
+#define NID_md5		4
+#define OBJ_md5		OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1		"MD5-SHA1"
+#define LN_md5_sha1		"md5-sha1"
+#define NID_md5_sha1		114
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1		163
+#define OBJ_hmacWithSHA1		OBJ_rsadsi,2L,7L
+
+#define SN_rc2_cbc		"RC2-CBC"
+#define LN_rc2_cbc		"rc2-cbc"
+#define NID_rc2_cbc		37
+#define OBJ_rc2_cbc		OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb		"RC2-ECB"
+#define LN_rc2_ecb		"rc2-ecb"
+#define NID_rc2_ecb		38
+
+#define SN_rc2_cfb64		"RC2-CFB"
+#define LN_rc2_cfb64		"rc2-cfb"
+#define NID_rc2_cfb64		39
+
+#define SN_rc2_ofb64		"RC2-OFB"
+#define LN_rc2_ofb64		"rc2-ofb"
+#define NID_rc2_ofb64		40
+
+#define SN_rc2_40_cbc		"RC2-40-CBC"
+#define LN_rc2_40_cbc		"rc2-40-cbc"
+#define NID_rc2_40_cbc		98
+
+#define SN_rc2_64_cbc		"RC2-64-CBC"
+#define LN_rc2_64_cbc		"rc2-64-cbc"
+#define NID_rc2_64_cbc		166
+
+#define SN_rc4		"RC4"
+#define LN_rc4		"rc4"
+#define NID_rc4		5
+#define OBJ_rc4		OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40		"RC4-40"
+#define LN_rc4_40		"rc4-40"
+#define NID_rc4_40		97
+
+#define SN_des_ede3_cbc		"DES-EDE3-CBC"
+#define LN_des_ede3_cbc		"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc		"RC5-CBC"
+#define LN_rc5_cbc		"rc5-cbc"
+#define NID_rc5_cbc		120
+#define OBJ_rc5_cbc		OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb		"RC5-ECB"
+#define LN_rc5_ecb		"rc5-ecb"
+#define NID_rc5_ecb		121
+
+#define SN_rc5_cfb64		"RC5-CFB"
+#define LN_rc5_cfb64		"rc5-cfb"
+#define NID_rc5_cfb64		122
+
+#define SN_rc5_ofb64		"RC5-OFB"
+#define LN_rc5_ofb64		"rc5-ofb"
+#define NID_rc5_ofb64		123
+
+#define SN_ms_ext_req		"msExtReq"
+#define LN_ms_ext_req		"Microsoft Extension Request"
+#define NID_ms_ext_req		171
+#define OBJ_ms_ext_req		1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind		"msCodeInd"
+#define LN_ms_code_ind		"Microsoft Individual Code Signing"
+#define NID_ms_code_ind		134
+#define OBJ_ms_code_ind		1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com		"msCodeCom"
+#define LN_ms_code_com		"Microsoft Commercial Code Signing"
+#define NID_ms_code_com		135
+#define OBJ_ms_code_com		1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign		"msCTLSign"
+#define LN_ms_ctl_sign		"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign		136
+#define OBJ_ms_ctl_sign		1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc		"msSGC"
+#define LN_ms_sgc		"Microsoft Server Gated Crypto"
+#define NID_ms_sgc		137
+#define OBJ_ms_sgc		1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs		"msEFS"
+#define LN_ms_efs		"Microsoft Encrypted File System"
+#define NID_ms_efs		138
+#define OBJ_ms_efs		1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login		"msSmartcardLogin"
+#define LN_ms_smartcard_login		"Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login		648
+#define OBJ_ms_smartcard_login		1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn		"msUPN"
+#define LN_ms_upn		"Microsoft Universal Principal Name"
+#define NID_ms_upn		649
+#define OBJ_ms_upn		1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc		"IDEA-CBC"
+#define LN_idea_cbc		"idea-cbc"
+#define NID_idea_cbc		34
+#define OBJ_idea_cbc		1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb		"IDEA-ECB"
+#define LN_idea_ecb		"idea-ecb"
+#define NID_idea_ecb		36
+
+#define SN_idea_cfb64		"IDEA-CFB"
+#define LN_idea_cfb64		"idea-cfb"
+#define NID_idea_cfb64		35
+
+#define SN_idea_ofb64		"IDEA-OFB"
+#define LN_idea_ofb64		"idea-ofb"
+#define NID_idea_ofb64		46
+
+#define SN_bf_cbc		"BF-CBC"
+#define LN_bf_cbc		"bf-cbc"
+#define NID_bf_cbc		91
+#define OBJ_bf_cbc		1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb		"BF-ECB"
+#define LN_bf_ecb		"bf-ecb"
+#define NID_bf_ecb		92
+
+#define SN_bf_cfb64		"BF-CFB"
+#define LN_bf_cfb64		"bf-cfb"
+#define NID_bf_cfb64		93
+
+#define SN_bf_ofb64		"BF-OFB"
+#define LN_bf_ofb64		"bf-ofb"
+#define NID_bf_ofb64		94
+
+#define SN_id_pkix		"PKIX"
+#define NID_id_pkix		127
+#define OBJ_id_pkix		1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod		"id-pkix-mod"
+#define NID_id_pkix_mod		258
+#define OBJ_id_pkix_mod		OBJ_id_pkix,0L
+
+#define SN_id_pe		"id-pe"
+#define NID_id_pe		175
+#define OBJ_id_pe		OBJ_id_pkix,1L
+
+#define SN_id_qt		"id-qt"
+#define NID_id_qt		259
+#define OBJ_id_qt		OBJ_id_pkix,2L
+
+#define SN_id_kp		"id-kp"
+#define NID_id_kp		128
+#define OBJ_id_kp		OBJ_id_pkix,3L
+
+#define SN_id_it		"id-it"
+#define NID_id_it		260
+#define OBJ_id_it		OBJ_id_pkix,4L
+
+#define SN_id_pkip		"id-pkip"
+#define NID_id_pkip		261
+#define OBJ_id_pkip		OBJ_id_pkix,5L
+
+#define SN_id_alg		"id-alg"
+#define NID_id_alg		262
+#define OBJ_id_alg		OBJ_id_pkix,6L
+
+#define SN_id_cmc		"id-cmc"
+#define NID_id_cmc		263
+#define OBJ_id_cmc		OBJ_id_pkix,7L
+
+#define SN_id_on		"id-on"
+#define NID_id_on		264
+#define OBJ_id_on		OBJ_id_pkix,8L
+
+#define SN_id_pda		"id-pda"
+#define NID_id_pda		265
+#define OBJ_id_pda		OBJ_id_pkix,9L
+
+#define SN_id_aca		"id-aca"
+#define NID_id_aca		266
+#define OBJ_id_aca		OBJ_id_pkix,10L
+
+#define SN_id_qcs		"id-qcs"
+#define NID_id_qcs		267
+#define OBJ_id_qcs		OBJ_id_pkix,11L
+
+#define SN_id_cct		"id-cct"
+#define NID_id_cct		268
+#define OBJ_id_cct		OBJ_id_pkix,12L
+
+#define SN_id_ppl		"id-ppl"
+#define NID_id_ppl		662
+#define OBJ_id_ppl		OBJ_id_pkix,21L
+
+#define SN_id_ad		"id-ad"
+#define NID_id_ad		176
+#define OBJ_id_ad		OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88		"id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88		269
+#define OBJ_id_pkix1_explicit_88		OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88		"id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88		270
+#define OBJ_id_pkix1_implicit_88		OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93		"id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93		271
+#define OBJ_id_pkix1_explicit_93		OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93		"id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93		272
+#define OBJ_id_pkix1_implicit_93		OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf		"id-mod-crmf"
+#define NID_id_mod_crmf		273
+#define OBJ_id_mod_crmf		OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc		"id-mod-cmc"
+#define NID_id_mod_cmc		274
+#define OBJ_id_mod_cmc		OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88		"id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88		275
+#define OBJ_id_mod_kea_profile_88		OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93		"id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93		276
+#define OBJ_id_mod_kea_profile_93		OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp		"id-mod-cmp"
+#define NID_id_mod_cmp		277
+#define OBJ_id_mod_cmp		OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88		"id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88		278
+#define OBJ_id_mod_qualified_cert_88		OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93		"id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93		279
+#define OBJ_id_mod_qualified_cert_93		OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert		"id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert		280
+#define OBJ_id_mod_attribute_cert		OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol		"id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol		281
+#define OBJ_id_mod_timestamp_protocol		OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp		"id-mod-ocsp"
+#define NID_id_mod_ocsp		282
+#define OBJ_id_mod_ocsp		OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs		"id-mod-dvcs"
+#define NID_id_mod_dvcs		283
+#define OBJ_id_mod_dvcs		OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000		"id-mod-cmp2000"
+#define NID_id_mod_cmp2000		284
+#define OBJ_id_mod_cmp2000		OBJ_id_pkix_mod,16L
+
+#define SN_info_access		"authorityInfoAccess"
+#define LN_info_access		"Authority Information Access"
+#define NID_info_access		177
+#define OBJ_info_access		OBJ_id_pe,1L
+
+#define SN_biometricInfo		"biometricInfo"
+#define LN_biometricInfo		"Biometric Info"
+#define NID_biometricInfo		285
+#define OBJ_biometricInfo		OBJ_id_pe,2L
+
+#define SN_qcStatements		"qcStatements"
+#define NID_qcStatements		286
+#define OBJ_qcStatements		OBJ_id_pe,3L
+
+#define SN_ac_auditEntity		"ac-auditEntity"
+#define NID_ac_auditEntity		287
+#define OBJ_ac_auditEntity		OBJ_id_pe,4L
+
+#define SN_ac_targeting		"ac-targeting"
+#define NID_ac_targeting		288
+#define OBJ_ac_targeting		OBJ_id_pe,5L
+
+#define SN_aaControls		"aaControls"
+#define NID_aaControls		289
+#define OBJ_aaControls		OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock		"sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock		290
+#define OBJ_sbgp_ipAddrBlock		OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum		"sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum		291
+#define OBJ_sbgp_autonomousSysNum		OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier		"sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier		292
+#define OBJ_sbgp_routerIdentifier		OBJ_id_pe,9L
+
+#define SN_ac_proxying		"ac-proxying"
+#define NID_ac_proxying		397
+#define OBJ_ac_proxying		OBJ_id_pe,10L
+
+#define SN_sinfo_access		"subjectInfoAccess"
+#define LN_sinfo_access		"Subject Information Access"
+#define NID_sinfo_access		398
+#define OBJ_sinfo_access		OBJ_id_pe,11L
+
+#define SN_proxyCertInfo		"proxyCertInfo"
+#define LN_proxyCertInfo		"Proxy Certificate Information"
+#define NID_proxyCertInfo		663
+#define OBJ_proxyCertInfo		OBJ_id_pe,14L
+
+#define SN_id_qt_cps		"id-qt-cps"
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_qt,1L
+
+#define SN_id_qt_unotice		"id-qt-unotice"
+#define LN_id_qt_unotice		"Policy Qualifier User Notice"
+#define NID_id_qt_unotice		165
+#define OBJ_id_qt_unotice		OBJ_id_qt,2L
+
+#define SN_textNotice		"textNotice"
+#define NID_textNotice		293
+#define OBJ_textNotice		OBJ_id_qt,3L
+
+#define SN_server_auth		"serverAuth"
+#define LN_server_auth		"TLS Web Server Authentication"
+#define NID_server_auth		129
+#define OBJ_server_auth		OBJ_id_kp,1L
+
+#define SN_client_auth		"clientAuth"
+#define LN_client_auth		"TLS Web Client Authentication"
+#define NID_client_auth		130
+#define OBJ_client_auth		OBJ_id_kp,2L
+
+#define SN_code_sign		"codeSigning"
+#define LN_code_sign		"Code Signing"
+#define NID_code_sign		131
+#define OBJ_code_sign		OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem		"ipsecEndSystem"
+#define LN_ipsecEndSystem		"IPSec End System"
+#define NID_ipsecEndSystem		294
+#define OBJ_ipsecEndSystem		OBJ_id_kp,5L
+
+#define SN_ipsecTunnel		"ipsecTunnel"
+#define LN_ipsecTunnel		"IPSec Tunnel"
+#define NID_ipsecTunnel		295
+#define OBJ_ipsecTunnel		OBJ_id_kp,6L
+
+#define SN_ipsecUser		"ipsecUser"
+#define LN_ipsecUser		"IPSec User"
+#define NID_ipsecUser		296
+#define OBJ_ipsecUser		OBJ_id_kp,7L
+
+#define SN_time_stamp		"timeStamping"
+#define LN_time_stamp		"Time Stamping"
+#define NID_time_stamp		133
+#define OBJ_time_stamp		OBJ_id_kp,8L
+
+#define SN_OCSP_sign		"OCSPSigning"
+#define LN_OCSP_sign		"OCSP Signing"
+#define NID_OCSP_sign		180
+#define OBJ_OCSP_sign		OBJ_id_kp,9L
+
+#define SN_dvcs		"DVCS"
+#define LN_dvcs		"dvcs"
+#define NID_dvcs		297
+#define OBJ_dvcs		OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert		"id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert		298
+#define OBJ_id_it_caProtEncCert		OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes		"id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes		299
+#define OBJ_id_it_signKeyPairTypes		OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes		"id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes		300
+#define OBJ_id_it_encKeyPairTypes		OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg		"id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg		301
+#define OBJ_id_it_preferredSymmAlg		OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo		"id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo		302
+#define OBJ_id_it_caKeyUpdateInfo		OBJ_id_it,5L
+
+#define SN_id_it_currentCRL		"id-it-currentCRL"
+#define NID_id_it_currentCRL		303
+#define OBJ_id_it_currentCRL		OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs		"id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs		304
+#define OBJ_id_it_unsupportedOIDs		OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest		"id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest		305
+#define OBJ_id_it_subscriptionRequest		OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse		"id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse		306
+#define OBJ_id_it_subscriptionResponse		OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq		"id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq		307
+#define OBJ_id_it_keyPairParamReq		OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep		"id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep		308
+#define OBJ_id_it_keyPairParamRep		OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase		"id-it-revPassphrase"
+#define NID_id_it_revPassphrase		309
+#define OBJ_id_it_revPassphrase		OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm		"id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm		310
+#define OBJ_id_it_implicitConfirm		OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime		"id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime		311
+#define OBJ_id_it_confirmWaitTime		OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage		"id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage		312
+#define OBJ_id_it_origPKIMessage		OBJ_id_it,15L
+
+#define SN_id_regCtrl		"id-regCtrl"
+#define NID_id_regCtrl		313
+#define OBJ_id_regCtrl		OBJ_id_pkip,1L
+
+#define SN_id_regInfo		"id-regInfo"
+#define NID_id_regInfo		314
+#define OBJ_id_regInfo		OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken		"id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken		315
+#define OBJ_id_regCtrl_regToken		OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator		"id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator		316
+#define OBJ_id_regCtrl_authenticator		OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo		"id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo		317
+#define OBJ_id_regCtrl_pkiPublicationInfo		OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions		"id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions		318
+#define OBJ_id_regCtrl_pkiArchiveOptions		OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID		"id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID		319
+#define OBJ_id_regCtrl_oldCertID		OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey		"id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey		320
+#define OBJ_id_regCtrl_protocolEncrKey		OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs		"id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs		321
+#define OBJ_id_regInfo_utf8Pairs		OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq		"id-regInfo-certReq"
+#define NID_id_regInfo_certReq		322
+#define OBJ_id_regInfo_certReq		OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40		"id-alg-des40"
+#define NID_id_alg_des40		323
+#define OBJ_id_alg_des40		OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature		"id-alg-noSignature"
+#define NID_id_alg_noSignature		324
+#define OBJ_id_alg_noSignature		OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1		"id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1		325
+#define OBJ_id_alg_dh_sig_hmac_sha1		OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop		"id-alg-dh-pop"
+#define NID_id_alg_dh_pop		326
+#define OBJ_id_alg_dh_pop		OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo		"id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo		327
+#define OBJ_id_cmc_statusInfo		OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification		"id-cmc-identification"
+#define NID_id_cmc_identification		328
+#define OBJ_id_cmc_identification		OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof		"id-cmc-identityProof"
+#define NID_id_cmc_identityProof		329
+#define OBJ_id_cmc_identityProof		OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn		"id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn		330
+#define OBJ_id_cmc_dataReturn		OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId		"id-cmc-transactionId"
+#define NID_id_cmc_transactionId		331
+#define OBJ_id_cmc_transactionId		OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce		"id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce		332
+#define OBJ_id_cmc_senderNonce		OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce		"id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce		333
+#define OBJ_id_cmc_recipientNonce		OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions		"id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions		334
+#define OBJ_id_cmc_addExtensions		OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP		"id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP		335
+#define OBJ_id_cmc_encryptedPOP		OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP		"id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP		336
+#define OBJ_id_cmc_decryptedPOP		OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness		"id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness		337
+#define OBJ_id_cmc_lraPOPWitness		OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert		"id-cmc-getCert"
+#define NID_id_cmc_getCert		338
+#define OBJ_id_cmc_getCert		OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL		"id-cmc-getCRL"
+#define NID_id_cmc_getCRL		339
+#define OBJ_id_cmc_getCRL		OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest		"id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest		340
+#define OBJ_id_cmc_revokeRequest		OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo		"id-cmc-regInfo"
+#define NID_id_cmc_regInfo		341
+#define OBJ_id_cmc_regInfo		OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo		"id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo		342
+#define OBJ_id_cmc_responseInfo		OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending		"id-cmc-queryPending"
+#define NID_id_cmc_queryPending		343
+#define OBJ_id_cmc_queryPending		OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom		"id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom		344
+#define OBJ_id_cmc_popLinkRandom		OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness		"id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness		345
+#define OBJ_id_cmc_popLinkWitness		OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance		"id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance		346
+#define OBJ_id_cmc_confirmCertAcceptance		OBJ_id_cmc,24L
+
+#define SN_id_on_personalData		"id-on-personalData"
+#define NID_id_on_personalData		347
+#define OBJ_id_on_personalData		OBJ_id_on,1L
+
+#define SN_id_pda_dateOfBirth		"id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth		348
+#define OBJ_id_pda_dateOfBirth		OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth		"id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth		349
+#define OBJ_id_pda_placeOfBirth		OBJ_id_pda,2L
+
+#define SN_id_pda_gender		"id-pda-gender"
+#define NID_id_pda_gender		351
+#define OBJ_id_pda_gender		OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship		"id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship		352
+#define OBJ_id_pda_countryOfCitizenship		OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence		"id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence		353
+#define OBJ_id_pda_countryOfResidence		OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo		"id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo		354
+#define OBJ_id_aca_authenticationInfo		OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity		"id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity		355
+#define OBJ_id_aca_accessIdentity		OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity		"id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity		356
+#define OBJ_id_aca_chargingIdentity		OBJ_id_aca,3L
+
+#define SN_id_aca_group		"id-aca-group"
+#define NID_id_aca_group		357
+#define OBJ_id_aca_group		OBJ_id_aca,4L
+
+#define SN_id_aca_role		"id-aca-role"
+#define NID_id_aca_role		358
+#define OBJ_id_aca_role		OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs		"id-aca-encAttrs"
+#define NID_id_aca_encAttrs		399
+#define OBJ_id_aca_encAttrs		OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1		"id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1		359
+#define OBJ_id_qcs_pkixQCSyntax_v1		OBJ_id_qcs,1L
+
+#define SN_id_cct_crs		"id-cct-crs"
+#define NID_id_cct_crs		360
+#define OBJ_id_cct_crs		OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData		"id-cct-PKIData"
+#define NID_id_cct_PKIData		361
+#define OBJ_id_cct_PKIData		OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse		"id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse		362
+#define OBJ_id_cct_PKIResponse		OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage		"id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage		"Any language"
+#define NID_id_ppl_anyLanguage		664
+#define OBJ_id_ppl_anyLanguage		OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll		"id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll		"Inherit all"
+#define NID_id_ppl_inheritAll		665
+#define OBJ_id_ppl_inheritAll		OBJ_id_ppl,1L
+
+#define SN_Independent		"id-ppl-independent"
+#define LN_Independent		"Independent"
+#define NID_Independent		667
+#define OBJ_Independent		OBJ_id_ppl,2L
+
+#define SN_ad_OCSP		"OCSP"
+#define LN_ad_OCSP		"OCSP"
+#define NID_ad_OCSP		178
+#define OBJ_ad_OCSP		OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_ad_timeStamping		"ad_timestamping"
+#define LN_ad_timeStamping		"AD Time Stamping"
+#define NID_ad_timeStamping		363
+#define OBJ_ad_timeStamping		OBJ_id_ad,3L
+
+#define SN_ad_dvcs		"AD_DVCS"
+#define LN_ad_dvcs		"ad dvcs"
+#define NID_ad_dvcs		364
+#define OBJ_ad_dvcs		OBJ_id_ad,4L
+
+#define OBJ_id_pkix_OCSP		OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic		"basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic		"Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic		365
+#define OBJ_id_pkix_OCSP_basic		OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce		"Nonce"
+#define LN_id_pkix_OCSP_Nonce		"OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce		366
+#define OBJ_id_pkix_OCSP_Nonce		OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID		"CrlID"
+#define LN_id_pkix_OCSP_CrlID		"OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID		367
+#define OBJ_id_pkix_OCSP_CrlID		OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses		"acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses		"Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses		368
+#define OBJ_id_pkix_OCSP_acceptableResponses		OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck		"noCheck"
+#define LN_id_pkix_OCSP_noCheck		"OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck		369
+#define OBJ_id_pkix_OCSP_noCheck		OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff		"archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff		"OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff		370
+#define OBJ_id_pkix_OCSP_archiveCutoff		OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator		"serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator		"OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator		371
+#define OBJ_id_pkix_OCSP_serviceLocator		OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus		"extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus		"Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus		372
+#define OBJ_id_pkix_OCSP_extendedStatus		OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid		"valid"
+#define NID_id_pkix_OCSP_valid		373
+#define OBJ_id_pkix_OCSP_valid		OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path		"path"
+#define NID_id_pkix_OCSP_path		374
+#define OBJ_id_pkix_OCSP_path		OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot		"trustRoot"
+#define LN_id_pkix_OCSP_trustRoot		"Trust Root"
+#define NID_id_pkix_OCSP_trustRoot		375
+#define OBJ_id_pkix_OCSP_trustRoot		OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm		"algorithm"
+#define LN_algorithm		"algorithm"
+#define NID_algorithm		376
+#define OBJ_algorithm		1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA		"RSA-NP-MD5"
+#define LN_md5WithRSA		"md5WithRSA"
+#define NID_md5WithRSA		104
+#define OBJ_md5WithRSA		OBJ_algorithm,3L
+
+#define SN_des_ecb		"DES-ECB"
+#define LN_des_ecb		"des-ecb"
+#define NID_des_ecb		29
+#define OBJ_des_ecb		OBJ_algorithm,6L
+
+#define SN_des_cbc		"DES-CBC"
+#define LN_des_cbc		"des-cbc"
+#define NID_des_cbc		31
+#define OBJ_des_cbc		OBJ_algorithm,7L
+
+#define SN_des_ofb64		"DES-OFB"
+#define LN_des_ofb64		"des-ofb"
+#define NID_des_ofb64		45
+#define OBJ_des_ofb64		OBJ_algorithm,8L
+
+#define SN_des_cfb64		"DES-CFB"
+#define LN_des_cfb64		"des-cfb"
+#define NID_des_cfb64		30
+#define OBJ_des_cfb64		OBJ_algorithm,9L
+
+#define SN_rsaSignature		"rsaSignature"
+#define NID_rsaSignature		377
+#define OBJ_rsaSignature		OBJ_algorithm,11L
+
+#define SN_dsa_2		"DSA-old"
+#define LN_dsa_2		"dsaEncryption-old"
+#define NID_dsa_2		67
+#define OBJ_dsa_2		OBJ_algorithm,12L
+
+#define SN_dsaWithSHA		"DSA-SHA"
+#define LN_dsaWithSHA		"dsaWithSHA"
+#define NID_dsaWithSHA		66
+#define OBJ_dsaWithSHA		OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption		42
+#define OBJ_shaWithRSAEncryption		OBJ_algorithm,15L
+
+#define SN_des_ede_ecb		"DES-EDE"
+#define LN_des_ede_ecb		"des-ede"
+#define NID_des_ede_ecb		32
+#define OBJ_des_ede_ecb		OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb		"DES-EDE3"
+#define LN_des_ede3_ecb		"des-ede3"
+#define NID_des_ede3_ecb		33
+
+#define SN_des_ede_cbc		"DES-EDE-CBC"
+#define LN_des_ede_cbc		"des-ede-cbc"
+#define NID_des_ede_cbc		43
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+#define SN_desx_cbc		"DESX-CBC"
+#define LN_desx_cbc		"desx-cbc"
+#define NID_desx_cbc		80
+
+#define SN_sha		"SHA"
+#define LN_sha		"sha"
+#define NID_sha		41
+#define OBJ_sha		OBJ_algorithm,18L
+
+#define SN_sha1		"SHA1"
+#define LN_sha1		"sha1"
+#define NID_sha1		64
+#define OBJ_sha1		OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_sha1WithRSA		"RSA-SHA1-2"
+#define LN_sha1WithRSA		"sha1WithRSA"
+#define NID_sha1WithRSA		115
+#define OBJ_sha1WithRSA		OBJ_algorithm,29L
+
+#define SN_ripemd160		"RIPEMD160"
+#define LN_ripemd160		"ripemd160"
+#define NID_ripemd160		117
+#define OBJ_ripemd160		1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet		"SXNetID"
+#define LN_sxnet		"Strong Extranet ID"
+#define NID_sxnet		143
+#define OBJ_sxnet		1L,3L,101L,1L,4L,1L
+
+#define SN_X500		"X500"
+#define LN_X500		"directory services (X.500)"
+#define NID_X500		11
+#define OBJ_X500		2L,5L
+
+#define SN_X509		"X509"
+#define NID_X509		12
+#define OBJ_X509		OBJ_X500,4L
+
+#define SN_commonName		"CN"
+#define LN_commonName		"commonName"
+#define NID_commonName		13
+#define OBJ_commonName		OBJ_X509,3L
+
+#define SN_surname		"SN"
+#define LN_surname		"surname"
+#define NID_surname		100
+#define OBJ_surname		OBJ_X509,4L
+
+#define LN_serialNumber		"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_countryName		"C"
+#define LN_countryName		"countryName"
+#define NID_countryName		14
+#define OBJ_countryName		OBJ_X509,6L
+
+#define SN_localityName		"L"
+#define LN_localityName		"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define LN_streetAddress		"streetAddress"
+#define NID_streetAddress		660
+#define OBJ_streetAddress		OBJ_X509,9L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName		"OU"
+#define LN_organizationalUnitName		"organizationalUnitName"
+#define NID_organizationalUnitName		18
+#define OBJ_organizationalUnitName		OBJ_X509,11L
+
+#define LN_title		"title"
+#define NID_title		106
+#define OBJ_title		OBJ_X509,12L
+
+#define LN_description		"description"
+#define NID_description		107
+#define OBJ_description		OBJ_X509,13L
+
+#define LN_postalCode		"postalCode"
+#define NID_postalCode		661
+#define OBJ_postalCode		OBJ_X509,17L
+
+#define SN_name		"name"
+#define LN_name		"name"
+#define NID_name		173
+#define OBJ_name		OBJ_X509,41L
+
+#define SN_givenName		"GN"
+#define LN_givenName		"givenName"
+#define NID_givenName		99
+#define OBJ_givenName		OBJ_X509,42L
+
+#define LN_initials		"initials"
+#define NID_initials		101
+#define OBJ_initials		OBJ_X509,43L
+
+#define LN_generationQualifier		"generationQualifier"
+#define NID_generationQualifier		509
+#define OBJ_generationQualifier		OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier		"x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier		503
+#define OBJ_x500UniqueIdentifier		OBJ_X509,45L
+
+#define SN_dnQualifier		"dnQualifier"
+#define LN_dnQualifier		"dnQualifier"
+#define NID_dnQualifier		174
+#define OBJ_dnQualifier		OBJ_X509,46L
+
+#define LN_pseudonym		"pseudonym"
+#define NID_pseudonym		510
+#define OBJ_pseudonym		OBJ_X509,65L
+
+#define SN_role		"role"
+#define LN_role		"role"
+#define NID_role		400
+#define OBJ_role		OBJ_X509,72L
+
+#define SN_X500algorithms		"X500algorithms"
+#define LN_X500algorithms		"directory services - algorithms"
+#define NID_X500algorithms		378
+#define OBJ_X500algorithms		OBJ_X500,8L
+
+#define SN_rsa		"RSA"
+#define LN_rsa		"rsa"
+#define NID_rsa		19
+#define OBJ_rsa		OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA		"RSA-MDC2"
+#define LN_mdc2WithRSA		"mdc2WithRSA"
+#define NID_mdc2WithRSA		96
+#define OBJ_mdc2WithRSA		OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2		"MDC2"
+#define LN_mdc2		"mdc2"
+#define NID_mdc2		95
+#define OBJ_mdc2		OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce		"id-ce"
+#define NID_id_ce		81
+#define OBJ_id_ce		OBJ_X500,29L
+
+#define SN_subject_directory_attributes		"subjectDirectoryAttributes"
+#define LN_subject_directory_attributes		"X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes		769
+#define OBJ_subject_directory_attributes		OBJ_id_ce,9L
+
+#define SN_subject_key_identifier		"subjectKeyIdentifier"
+#define LN_subject_key_identifier		"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier		82
+#define OBJ_subject_key_identifier		OBJ_id_ce,14L
+
+#define SN_key_usage		"keyUsage"
+#define LN_key_usage		"X509v3 Key Usage"
+#define NID_key_usage		83
+#define OBJ_key_usage		OBJ_id_ce,15L
+
+#define SN_private_key_usage_period		"privateKeyUsagePeriod"
+#define LN_private_key_usage_period		"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period		84
+#define OBJ_private_key_usage_period		OBJ_id_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_id_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_id_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_id_ce,19L
+
+#define SN_crl_number		"crlNumber"
+#define LN_crl_number		"X509v3 CRL Number"
+#define NID_crl_number		88
+#define OBJ_crl_number		OBJ_id_ce,20L
+
+#define SN_crl_reason		"CRLReason"
+#define LN_crl_reason		"X509v3 CRL Reason Code"
+#define NID_crl_reason		141
+#define OBJ_crl_reason		OBJ_id_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_id_ce,24L
+
+#define SN_delta_crl		"deltaCRL"
+#define LN_delta_crl		"X509v3 Delta CRL Indicator"
+#define NID_delta_crl		140
+#define OBJ_delta_crl		OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point		"issuingDistributionPoint"
+#define LN_issuing_distribution_point		"X509v3 Issuing Distrubution Point"
+#define NID_issuing_distribution_point		770
+#define OBJ_issuing_distribution_point		OBJ_id_ce,28L
+
+#define SN_certificate_issuer		"certificateIssuer"
+#define LN_certificate_issuer		"X509v3 Certificate Issuer"
+#define NID_certificate_issuer		771
+#define OBJ_certificate_issuer		OBJ_id_ce,29L
+
+#define SN_name_constraints		"nameConstraints"
+#define LN_name_constraints		"X509v3 Name Constraints"
+#define NID_name_constraints		666
+#define OBJ_name_constraints		OBJ_id_ce,30L
+
+#define SN_crl_distribution_points		"crlDistributionPoints"
+#define LN_crl_distribution_points		"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points		103
+#define OBJ_crl_distribution_points		OBJ_id_ce,31L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies		89
+#define OBJ_certificate_policies		OBJ_id_ce,32L
+
+#define SN_any_policy		"anyPolicy"
+#define LN_any_policy		"X509v3 Any Policy"
+#define NID_any_policy		746
+#define OBJ_any_policy		OBJ_certificate_policies,0L
+
+#define SN_policy_mappings		"policyMappings"
+#define LN_policy_mappings		"X509v3 Policy Mappings"
+#define NID_policy_mappings		747
+#define OBJ_policy_mappings		OBJ_id_ce,33L
+
+#define SN_authority_key_identifier		"authorityKeyIdentifier"
+#define LN_authority_key_identifier		"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier		90
+#define OBJ_authority_key_identifier		OBJ_id_ce,35L
+
+#define SN_policy_constraints		"policyConstraints"
+#define LN_policy_constraints		"X509v3 Policy Constraints"
+#define NID_policy_constraints		401
+#define OBJ_policy_constraints		OBJ_id_ce,36L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_id_ce,37L
+
+#define SN_inhibit_any_policy		"inhibitAnyPolicy"
+#define LN_inhibit_any_policy		"X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy		748
+#define OBJ_inhibit_any_policy		OBJ_id_ce,54L
+
+#define SN_target_information		"targetInformation"
+#define LN_target_information		"X509v3 AC Targeting"
+#define NID_target_information		402
+#define OBJ_target_information		OBJ_id_ce,55L
+
+#define SN_no_rev_avail		"noRevAvail"
+#define LN_no_rev_avail		"X509v3 No Revocation Available"
+#define NID_no_rev_avail		403
+#define OBJ_no_rev_avail		OBJ_id_ce,56L
+
+#define SN_netscape		"Netscape"
+#define LN_netscape		"Netscape Communications Corp."
+#define NID_netscape		57
+#define OBJ_netscape		2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension		"nsCertExt"
+#define LN_netscape_cert_extension		"Netscape Certificate Extension"
+#define NID_netscape_cert_extension		58
+#define OBJ_netscape_cert_extension		OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url		"nsRevocationUrl"
+#define LN_netscape_revocation_url		"Netscape Revocation Url"
+#define NID_netscape_revocation_url		73
+#define OBJ_netscape_revocation_url		OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url		"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url		"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url		74
+#define OBJ_netscape_ca_revocation_url		OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url		75
+#define OBJ_netscape_renewal_url		OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url		"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url		"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url		76
+#define OBJ_netscape_ca_policy_url		OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name		"nsSslServerName"
+#define LN_netscape_ssl_server_name		"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name		77
+#define OBJ_netscape_ssl_server_name		OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence		"nsCertSequence"
+#define LN_netscape_cert_sequence		"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence		79
+#define OBJ_netscape_cert_sequence		OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc		"nsSGC"
+#define LN_ns_sgc		"Netscape Server Gated Crypto"
+#define NID_ns_sgc		139
+#define OBJ_ns_sgc		OBJ_netscape,4L,1L
+
+#define SN_org		"ORG"
+#define LN_org		"org"
+#define NID_org		379
+#define OBJ_org		OBJ_iso,3L
+
+#define SN_dod		"DOD"
+#define LN_dod		"dod"
+#define NID_dod		380
+#define OBJ_dod		OBJ_org,6L
+
+#define SN_iana		"IANA"
+#define LN_iana		"iana"
+#define NID_iana		381
+#define OBJ_iana		OBJ_dod,1L
+
+#define OBJ_internet		OBJ_iana
+
+#define SN_Directory		"directory"
+#define LN_Directory		"Directory"
+#define NID_Directory		382
+#define OBJ_Directory		OBJ_internet,1L
+
+#define SN_Management		"mgmt"
+#define LN_Management		"Management"
+#define NID_Management		383
+#define OBJ_Management		OBJ_internet,2L
+
+#define SN_Experimental		"experimental"
+#define LN_Experimental		"Experimental"
+#define NID_Experimental		384
+#define OBJ_Experimental		OBJ_internet,3L
+
+#define SN_Private		"private"
+#define LN_Private		"Private"
+#define NID_Private		385
+#define OBJ_Private		OBJ_internet,4L
+
+#define SN_Security		"security"
+#define LN_Security		"Security"
+#define NID_Security		386
+#define OBJ_Security		OBJ_internet,5L
+
+#define SN_SNMPv2		"snmpv2"
+#define LN_SNMPv2		"SNMPv2"
+#define NID_SNMPv2		387
+#define OBJ_SNMPv2		OBJ_internet,6L
+
+#define LN_Mail		"Mail"
+#define NID_Mail		388
+#define OBJ_Mail		OBJ_internet,7L
+
+#define SN_Enterprises		"enterprises"
+#define LN_Enterprises		"Enterprises"
+#define NID_Enterprises		389
+#define OBJ_Enterprises		OBJ_Private,1L
+
+#define SN_dcObject		"dcobject"
+#define LN_dcObject		"dcObject"
+#define NID_dcObject		390
+#define OBJ_dcObject		OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs		"mime-mhs"
+#define LN_mime_mhs		"MIME MHS"
+#define NID_mime_mhs		504
+#define OBJ_mime_mhs		OBJ_Mail,1L
+
+#define SN_mime_mhs_headings		"mime-mhs-headings"
+#define LN_mime_mhs_headings		"mime-mhs-headings"
+#define NID_mime_mhs_headings		505
+#define OBJ_mime_mhs_headings		OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies		"mime-mhs-bodies"
+#define LN_mime_mhs_bodies		"mime-mhs-bodies"
+#define NID_mime_mhs_bodies		506
+#define OBJ_mime_mhs_bodies		OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message		"id-hex-partial-message"
+#define LN_id_hex_partial_message		"id-hex-partial-message"
+#define NID_id_hex_partial_message		507
+#define OBJ_id_hex_partial_message		OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message		"id-hex-multipart-message"
+#define LN_id_hex_multipart_message		"id-hex-multipart-message"
+#define NID_id_hex_multipart_message		508
+#define OBJ_id_hex_multipart_message		OBJ_mime_mhs_headings,2L
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
+
+#define OBJ_csor		2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms		OBJ_csor,4L
+
+#define OBJ_aes		OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb		"AES-128-ECB"
+#define LN_aes_128_ecb		"aes-128-ecb"
+#define NID_aes_128_ecb		418
+#define OBJ_aes_128_ecb		OBJ_aes,1L
+
+#define SN_aes_128_cbc		"AES-128-CBC"
+#define LN_aes_128_cbc		"aes-128-cbc"
+#define NID_aes_128_cbc		419
+#define OBJ_aes_128_cbc		OBJ_aes,2L
+
+#define SN_aes_128_ofb128		"AES-128-OFB"
+#define LN_aes_128_ofb128		"aes-128-ofb"
+#define NID_aes_128_ofb128		420
+#define OBJ_aes_128_ofb128		OBJ_aes,3L
+
+#define SN_aes_128_cfb128		"AES-128-CFB"
+#define LN_aes_128_cfb128		"aes-128-cfb"
+#define NID_aes_128_cfb128		421
+#define OBJ_aes_128_cfb128		OBJ_aes,4L
+
+#define SN_aes_192_ecb		"AES-192-ECB"
+#define LN_aes_192_ecb		"aes-192-ecb"
+#define NID_aes_192_ecb		422
+#define OBJ_aes_192_ecb		OBJ_aes,21L
+
+#define SN_aes_192_cbc		"AES-192-CBC"
+#define LN_aes_192_cbc		"aes-192-cbc"
+#define NID_aes_192_cbc		423
+#define OBJ_aes_192_cbc		OBJ_aes,22L
+
+#define SN_aes_192_ofb128		"AES-192-OFB"
+#define LN_aes_192_ofb128		"aes-192-ofb"
+#define NID_aes_192_ofb128		424
+#define OBJ_aes_192_ofb128		OBJ_aes,23L
+
+#define SN_aes_192_cfb128		"AES-192-CFB"
+#define LN_aes_192_cfb128		"aes-192-cfb"
+#define NID_aes_192_cfb128		425
+#define OBJ_aes_192_cfb128		OBJ_aes,24L
+
+#define SN_aes_256_ecb		"AES-256-ECB"
+#define LN_aes_256_ecb		"aes-256-ecb"
+#define NID_aes_256_ecb		426
+#define OBJ_aes_256_ecb		OBJ_aes,41L
+
+#define SN_aes_256_cbc		"AES-256-CBC"
+#define LN_aes_256_cbc		"aes-256-cbc"
+#define NID_aes_256_cbc		427
+#define OBJ_aes_256_cbc		OBJ_aes,42L
+
+#define SN_aes_256_ofb128		"AES-256-OFB"
+#define LN_aes_256_ofb128		"aes-256-ofb"
+#define NID_aes_256_ofb128		428
+#define OBJ_aes_256_ofb128		OBJ_aes,43L
+
+#define SN_aes_256_cfb128		"AES-256-CFB"
+#define LN_aes_256_cfb128		"aes-256-cfb"
+#define NID_aes_256_cfb128		429
+#define OBJ_aes_256_cfb128		OBJ_aes,44L
+
+#define SN_aes_128_cfb1		"AES-128-CFB1"
+#define LN_aes_128_cfb1		"aes-128-cfb1"
+#define NID_aes_128_cfb1		650
+
+#define SN_aes_192_cfb1		"AES-192-CFB1"
+#define LN_aes_192_cfb1		"aes-192-cfb1"
+#define NID_aes_192_cfb1		651
+
+#define SN_aes_256_cfb1		"AES-256-CFB1"
+#define LN_aes_256_cfb1		"aes-256-cfb1"
+#define NID_aes_256_cfb1		652
+
+#define SN_aes_128_cfb8		"AES-128-CFB8"
+#define LN_aes_128_cfb8		"aes-128-cfb8"
+#define NID_aes_128_cfb8		653
+
+#define SN_aes_192_cfb8		"AES-192-CFB8"
+#define LN_aes_192_cfb8		"aes-192-cfb8"
+#define NID_aes_192_cfb8		654
+
+#define SN_aes_256_cfb8		"AES-256-CFB8"
+#define LN_aes_256_cfb8		"aes-256-cfb8"
+#define NID_aes_256_cfb8		655
+
+#define SN_des_cfb1		"DES-CFB1"
+#define LN_des_cfb1		"des-cfb1"
+#define NID_des_cfb1		656
+
+#define SN_des_cfb8		"DES-CFB8"
+#define LN_des_cfb8		"des-cfb8"
+#define NID_des_cfb8		657
+
+#define SN_des_ede3_cfb1		"DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1		"des-ede3-cfb1"
+#define NID_des_ede3_cfb1		658
+
+#define SN_des_ede3_cfb8		"DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8		"des-ede3-cfb8"
+#define NID_des_ede3_cfb8		659
+
+#define OBJ_nist_hashalgs		OBJ_nistAlgorithms,2L
+
+#define SN_sha256		"SHA256"
+#define LN_sha256		"sha256"
+#define NID_sha256		672
+#define OBJ_sha256		OBJ_nist_hashalgs,1L
+
+#define SN_sha384		"SHA384"
+#define LN_sha384		"sha384"
+#define NID_sha384		673
+#define OBJ_sha384		OBJ_nist_hashalgs,2L
+
+#define SN_sha512		"SHA512"
+#define LN_sha512		"sha512"
+#define NID_sha512		674
+#define OBJ_sha512		OBJ_nist_hashalgs,3L
+
+#define SN_sha224		"SHA224"
+#define LN_sha224		"sha224"
+#define NID_sha224		675
+#define OBJ_sha224		OBJ_nist_hashalgs,4L
+
+#define SN_hold_instruction_code		"holdInstructionCode"
+#define LN_hold_instruction_code		"Hold Instruction Code"
+#define NID_hold_instruction_code		430
+#define OBJ_hold_instruction_code		OBJ_id_ce,23L
+
+#define OBJ_holdInstruction		OBJ_X9_57,2L
+
+#define SN_hold_instruction_none		"holdInstructionNone"
+#define LN_hold_instruction_none		"Hold Instruction None"
+#define NID_hold_instruction_none		431
+#define OBJ_hold_instruction_none		OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer		"holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer		"Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer		432
+#define OBJ_hold_instruction_call_issuer		OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject		"holdInstructionReject"
+#define LN_hold_instruction_reject		"Hold Instruction Reject"
+#define NID_hold_instruction_reject		433
+#define OBJ_hold_instruction_reject		OBJ_holdInstruction,3L
+
+#define SN_data		"data"
+#define NID_data		434
+#define OBJ_data		OBJ_itu_t,9L
+
+#define SN_pss		"pss"
+#define NID_pss		435
+#define OBJ_pss		OBJ_data,2342L
+
+#define SN_ucl		"ucl"
+#define NID_ucl		436
+#define OBJ_ucl		OBJ_pss,19200300L
+
+#define SN_pilot		"pilot"
+#define NID_pilot		437
+#define OBJ_pilot		OBJ_ucl,100L
+
+#define LN_pilotAttributeType		"pilotAttributeType"
+#define NID_pilotAttributeType		438
+#define OBJ_pilotAttributeType		OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax		"pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax		439
+#define OBJ_pilotAttributeSyntax		OBJ_pilot,3L
+
+#define LN_pilotObjectClass		"pilotObjectClass"
+#define NID_pilotObjectClass		440
+#define OBJ_pilotObjectClass		OBJ_pilot,4L
+
+#define LN_pilotGroups		"pilotGroups"
+#define NID_pilotGroups		441
+#define OBJ_pilotGroups		OBJ_pilot,10L
+
+#define LN_iA5StringSyntax		"iA5StringSyntax"
+#define NID_iA5StringSyntax		442
+#define OBJ_iA5StringSyntax		OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax		"caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax		443
+#define OBJ_caseIgnoreIA5StringSyntax		OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject		"pilotObject"
+#define NID_pilotObject		444
+#define OBJ_pilotObject		OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson		"pilotPerson"
+#define NID_pilotPerson		445
+#define OBJ_pilotPerson		OBJ_pilotObjectClass,4L
+
+#define SN_account		"account"
+#define NID_account		446
+#define OBJ_account		OBJ_pilotObjectClass,5L
+
+#define SN_document		"document"
+#define NID_document		447
+#define OBJ_document		OBJ_pilotObjectClass,6L
+
+#define SN_room		"room"
+#define NID_room		448
+#define OBJ_room		OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries		"documentSeries"
+#define NID_documentSeries		449
+#define OBJ_documentSeries		OBJ_pilotObjectClass,9L
+
+#define SN_Domain		"domain"
+#define LN_Domain		"Domain"
+#define NID_Domain		392
+#define OBJ_Domain		OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart		"rFC822localPart"
+#define NID_rFC822localPart		450
+#define OBJ_rFC822localPart		OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain		"dNSDomain"
+#define NID_dNSDomain		451
+#define OBJ_dNSDomain		OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject		"domainRelatedObject"
+#define NID_domainRelatedObject		452
+#define OBJ_domainRelatedObject		OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry		"friendlyCountry"
+#define NID_friendlyCountry		453
+#define OBJ_friendlyCountry		OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject		"simpleSecurityObject"
+#define NID_simpleSecurityObject		454
+#define OBJ_simpleSecurityObject		OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization		"pilotOrganization"
+#define NID_pilotOrganization		455
+#define OBJ_pilotOrganization		OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA		"pilotDSA"
+#define NID_pilotDSA		456
+#define OBJ_pilotDSA		OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData		"qualityLabelledData"
+#define NID_qualityLabelledData		457
+#define OBJ_qualityLabelledData		OBJ_pilotObjectClass,22L
+
+#define SN_userId		"UID"
+#define LN_userId		"userId"
+#define NID_userId		458
+#define OBJ_userId		OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress		"textEncodedORAddress"
+#define NID_textEncodedORAddress		459
+#define OBJ_textEncodedORAddress		OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox		"mail"
+#define LN_rfc822Mailbox		"rfc822Mailbox"
+#define NID_rfc822Mailbox		460
+#define OBJ_rfc822Mailbox		OBJ_pilotAttributeType,3L
+
+#define SN_info		"info"
+#define NID_info		461
+#define OBJ_info		OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink		"favouriteDrink"
+#define NID_favouriteDrink		462
+#define OBJ_favouriteDrink		OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber		"roomNumber"
+#define NID_roomNumber		463
+#define OBJ_roomNumber		OBJ_pilotAttributeType,6L
+
+#define SN_photo		"photo"
+#define NID_photo		464
+#define OBJ_photo		OBJ_pilotAttributeType,7L
+
+#define LN_userClass		"userClass"
+#define NID_userClass		465
+#define OBJ_userClass		OBJ_pilotAttributeType,8L
+
+#define SN_host		"host"
+#define NID_host		466
+#define OBJ_host		OBJ_pilotAttributeType,9L
+
+#define SN_manager		"manager"
+#define NID_manager		467
+#define OBJ_manager		OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier		"documentIdentifier"
+#define NID_documentIdentifier		468
+#define OBJ_documentIdentifier		OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle		"documentTitle"
+#define NID_documentTitle		469
+#define OBJ_documentTitle		OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion		"documentVersion"
+#define NID_documentVersion		470
+#define OBJ_documentVersion		OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor		"documentAuthor"
+#define NID_documentAuthor		471
+#define OBJ_documentAuthor		OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation		"documentLocation"
+#define NID_documentLocation		472
+#define OBJ_documentLocation		OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber		"homeTelephoneNumber"
+#define NID_homeTelephoneNumber		473
+#define OBJ_homeTelephoneNumber		OBJ_pilotAttributeType,20L
+
+#define SN_secretary		"secretary"
+#define NID_secretary		474
+#define OBJ_secretary		OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox		"otherMailbox"
+#define NID_otherMailbox		475
+#define OBJ_otherMailbox		OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime		"lastModifiedTime"
+#define NID_lastModifiedTime		476
+#define OBJ_lastModifiedTime		OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy		"lastModifiedBy"
+#define NID_lastModifiedBy		477
+#define OBJ_lastModifiedBy		OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent		"DC"
+#define LN_domainComponent		"domainComponent"
+#define NID_domainComponent		391
+#define OBJ_domainComponent		OBJ_pilotAttributeType,25L
+
+#define LN_aRecord		"aRecord"
+#define NID_aRecord		478
+#define OBJ_aRecord		OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27		"pilotAttributeType27"
+#define NID_pilotAttributeType27		479
+#define OBJ_pilotAttributeType27		OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord		"mXRecord"
+#define NID_mXRecord		480
+#define OBJ_mXRecord		OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord		"nSRecord"
+#define NID_nSRecord		481
+#define OBJ_nSRecord		OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord		"sOARecord"
+#define NID_sOARecord		482
+#define OBJ_sOARecord		OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord		"cNAMERecord"
+#define NID_cNAMERecord		483
+#define OBJ_cNAMERecord		OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain		"associatedDomain"
+#define NID_associatedDomain		484
+#define OBJ_associatedDomain		OBJ_pilotAttributeType,37L
+
+#define LN_associatedName		"associatedName"
+#define NID_associatedName		485
+#define OBJ_associatedName		OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress		"homePostalAddress"
+#define NID_homePostalAddress		486
+#define OBJ_homePostalAddress		OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle		"personalTitle"
+#define NID_personalTitle		487
+#define OBJ_personalTitle		OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber		"mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber		488
+#define OBJ_mobileTelephoneNumber		OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber		"pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber		489
+#define OBJ_pagerTelephoneNumber		OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName		"friendlyCountryName"
+#define NID_friendlyCountryName		490
+#define OBJ_friendlyCountryName		OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus		"organizationalStatus"
+#define NID_organizationalStatus		491
+#define OBJ_organizationalStatus		OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox		"janetMailbox"
+#define NID_janetMailbox		492
+#define OBJ_janetMailbox		OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption		"mailPreferenceOption"
+#define NID_mailPreferenceOption		493
+#define OBJ_mailPreferenceOption		OBJ_pilotAttributeType,47L
+
+#define LN_buildingName		"buildingName"
+#define NID_buildingName		494
+#define OBJ_buildingName		OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality		"dSAQuality"
+#define NID_dSAQuality		495
+#define OBJ_dSAQuality		OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality		"singleLevelQuality"
+#define NID_singleLevelQuality		496
+#define OBJ_singleLevelQuality		OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality		"subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality		497
+#define OBJ_subtreeMinimumQuality		OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality		"subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality		498
+#define OBJ_subtreeMaximumQuality		OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature		"personalSignature"
+#define NID_personalSignature		499
+#define OBJ_personalSignature		OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect		"dITRedirect"
+#define NID_dITRedirect		500
+#define OBJ_dITRedirect		OBJ_pilotAttributeType,54L
+
+#define SN_audio		"audio"
+#define NID_audio		501
+#define OBJ_audio		OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher		"documentPublisher"
+#define NID_documentPublisher		502
+#define OBJ_documentPublisher		OBJ_pilotAttributeType,56L
+
+#define SN_id_set		"id-set"
+#define LN_id_set		"Secure Electronic Transactions"
+#define NID_id_set		512
+#define OBJ_id_set		OBJ_international_organizations,42L
+
+#define SN_set_ctype		"set-ctype"
+#define LN_set_ctype		"content types"
+#define NID_set_ctype		513
+#define OBJ_set_ctype		OBJ_id_set,0L
+
+#define SN_set_msgExt		"set-msgExt"
+#define LN_set_msgExt		"message extensions"
+#define NID_set_msgExt		514
+#define OBJ_set_msgExt		OBJ_id_set,1L
+
+#define SN_set_attr		"set-attr"
+#define NID_set_attr		515
+#define OBJ_set_attr		OBJ_id_set,3L
+
+#define SN_set_policy		"set-policy"
+#define NID_set_policy		516
+#define OBJ_set_policy		OBJ_id_set,5L
+
+#define SN_set_certExt		"set-certExt"
+#define LN_set_certExt		"certificate extensions"
+#define NID_set_certExt		517
+#define OBJ_set_certExt		OBJ_id_set,7L
+
+#define SN_set_brand		"set-brand"
+#define NID_set_brand		518
+#define OBJ_set_brand		OBJ_id_set,8L
+
+#define SN_setct_PANData		"setct-PANData"
+#define NID_setct_PANData		519
+#define OBJ_setct_PANData		OBJ_set_ctype,0L
+
+#define SN_setct_PANToken		"setct-PANToken"
+#define NID_setct_PANToken		520
+#define OBJ_setct_PANToken		OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly		"setct-PANOnly"
+#define NID_setct_PANOnly		521
+#define OBJ_setct_PANOnly		OBJ_set_ctype,2L
+
+#define SN_setct_OIData		"setct-OIData"
+#define NID_setct_OIData		522
+#define OBJ_setct_OIData		OBJ_set_ctype,3L
+
+#define SN_setct_PI		"setct-PI"
+#define NID_setct_PI		523
+#define OBJ_setct_PI		OBJ_set_ctype,4L
+
+#define SN_setct_PIData		"setct-PIData"
+#define NID_setct_PIData		524
+#define OBJ_setct_PIData		OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned		"setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned		525
+#define OBJ_setct_PIDataUnsigned		OBJ_set_ctype,6L
+
+#define SN_setct_HODInput		"setct-HODInput"
+#define NID_setct_HODInput		526
+#define OBJ_setct_HODInput		OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage		"setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage		527
+#define OBJ_setct_AuthResBaggage		OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage		"setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage		528
+#define OBJ_setct_AuthRevReqBaggage		OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage		"setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage		529
+#define OBJ_setct_AuthRevResBaggage		OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq		"setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq		530
+#define OBJ_setct_CapTokenSeq		OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData		"setct-PInitResData"
+#define NID_setct_PInitResData		531
+#define OBJ_setct_PInitResData		OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS		"setct-PI-TBS"
+#define NID_setct_PI_TBS		532
+#define OBJ_setct_PI_TBS		OBJ_set_ctype,13L
+
+#define SN_setct_PResData		"setct-PResData"
+#define NID_setct_PResData		533
+#define OBJ_setct_PResData		OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS		"setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS		534
+#define OBJ_setct_AuthReqTBS		OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS		"setct-AuthResTBS"
+#define NID_setct_AuthResTBS		535
+#define OBJ_setct_AuthResTBS		OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX		"setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX		536
+#define OBJ_setct_AuthResTBSX		OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS		"setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS		537
+#define OBJ_setct_AuthTokenTBS		OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData		"setct-CapTokenData"
+#define NID_setct_CapTokenData		538
+#define OBJ_setct_CapTokenData		OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS		"setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS		539
+#define OBJ_setct_CapTokenTBS		OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg		"setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg		540
+#define OBJ_setct_AcqCardCodeMsg		OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS		"setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS		541
+#define OBJ_setct_AuthRevReqTBS		OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData		"setct-AuthRevResData"
+#define NID_setct_AuthRevResData		542
+#define OBJ_setct_AuthRevResData		OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS		"setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS		543
+#define OBJ_setct_AuthRevResTBS		OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS		"setct-CapReqTBS"
+#define NID_setct_CapReqTBS		544
+#define OBJ_setct_CapReqTBS		OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX		"setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX		545
+#define OBJ_setct_CapReqTBSX		OBJ_set_ctype,27L
+
+#define SN_setct_CapResData		"setct-CapResData"
+#define NID_setct_CapResData		546
+#define OBJ_setct_CapResData		OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS		"setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS		547
+#define OBJ_setct_CapRevReqTBS		OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX		"setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX		548
+#define OBJ_setct_CapRevReqTBSX		OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData		"setct-CapRevResData"
+#define NID_setct_CapRevResData		549
+#define OBJ_setct_CapRevResData		OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS		"setct-CredReqTBS"
+#define NID_setct_CredReqTBS		550
+#define OBJ_setct_CredReqTBS		OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX		"setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX		551
+#define OBJ_setct_CredReqTBSX		OBJ_set_ctype,33L
+
+#define SN_setct_CredResData		"setct-CredResData"
+#define NID_setct_CredResData		552
+#define OBJ_setct_CredResData		OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS		"setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS		553
+#define OBJ_setct_CredRevReqTBS		OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX		"setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX		554
+#define OBJ_setct_CredRevReqTBSX		OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData		"setct-CredRevResData"
+#define NID_setct_CredRevResData		555
+#define OBJ_setct_CredRevResData		OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData		"setct-PCertReqData"
+#define NID_setct_PCertReqData		556
+#define OBJ_setct_PCertReqData		OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS		"setct-PCertResTBS"
+#define NID_setct_PCertResTBS		557
+#define OBJ_setct_PCertResTBS		OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData		"setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData		558
+#define OBJ_setct_BatchAdminReqData		OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData		"setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData		559
+#define OBJ_setct_BatchAdminResData		OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS		"setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS		560
+#define OBJ_setct_CardCInitResTBS		OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS		"setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS		561
+#define OBJ_setct_MeAqCInitResTBS		OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS		"setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS		562
+#define OBJ_setct_RegFormResTBS		OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData		"setct-CertReqData"
+#define NID_setct_CertReqData		563
+#define OBJ_setct_CertReqData		OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS		"setct-CertReqTBS"
+#define NID_setct_CertReqTBS		564
+#define OBJ_setct_CertReqTBS		OBJ_set_ctype,46L
+
+#define SN_setct_CertResData		"setct-CertResData"
+#define NID_setct_CertResData		565
+#define OBJ_setct_CertResData		OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS		"setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS		566
+#define OBJ_setct_CertInqReqTBS		OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS		"setct-ErrorTBS"
+#define NID_setct_ErrorTBS		567
+#define OBJ_setct_ErrorTBS		OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE		"setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE		568
+#define OBJ_setct_PIDualSignedTBE		OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE		"setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE		569
+#define OBJ_setct_PIUnsignedTBE		OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE		"setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE		570
+#define OBJ_setct_AuthReqTBE		OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE		"setct-AuthResTBE"
+#define NID_setct_AuthResTBE		571
+#define OBJ_setct_AuthResTBE		OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX		"setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX		572
+#define OBJ_setct_AuthResTBEX		OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE		"setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE		573
+#define OBJ_setct_AuthTokenTBE		OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE		"setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE		574
+#define OBJ_setct_CapTokenTBE		OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX		"setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX		575
+#define OBJ_setct_CapTokenTBEX		OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE		"setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE		576
+#define OBJ_setct_AcqCardCodeMsgTBE		OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE		"setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE		577
+#define OBJ_setct_AuthRevReqTBE		OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE		"setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE		578
+#define OBJ_setct_AuthRevResTBE		OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB		"setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB		579
+#define OBJ_setct_AuthRevResTBEB		OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE		"setct-CapReqTBE"
+#define NID_setct_CapReqTBE		580
+#define OBJ_setct_CapReqTBE		OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX		"setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX		581
+#define OBJ_setct_CapReqTBEX		OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE		"setct-CapResTBE"
+#define NID_setct_CapResTBE		582
+#define OBJ_setct_CapResTBE		OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE		"setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE		583
+#define OBJ_setct_CapRevReqTBE		OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX		"setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX		584
+#define OBJ_setct_CapRevReqTBEX		OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE		"setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE		585
+#define OBJ_setct_CapRevResTBE		OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE		"setct-CredReqTBE"
+#define NID_setct_CredReqTBE		586
+#define OBJ_setct_CredReqTBE		OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX		"setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX		587
+#define OBJ_setct_CredReqTBEX		OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE		"setct-CredResTBE"
+#define NID_setct_CredResTBE		588
+#define OBJ_setct_CredResTBE		OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE		"setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE		589
+#define OBJ_setct_CredRevReqTBE		OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX		"setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX		590
+#define OBJ_setct_CredRevReqTBEX		OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE		"setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE		591
+#define OBJ_setct_CredRevResTBE		OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE		"setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE		592
+#define OBJ_setct_BatchAdminReqTBE		OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE		"setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE		593
+#define OBJ_setct_BatchAdminResTBE		OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE		"setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE		594
+#define OBJ_setct_RegFormReqTBE		OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE		"setct-CertReqTBE"
+#define NID_setct_CertReqTBE		595
+#define OBJ_setct_CertReqTBE		OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX		"setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX		596
+#define OBJ_setct_CertReqTBEX		OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE		"setct-CertResTBE"
+#define NID_setct_CertResTBE		597
+#define OBJ_setct_CertResTBE		OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS		"setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS		598
+#define OBJ_setct_CRLNotificationTBS		OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS		"setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS		599
+#define OBJ_setct_CRLNotificationResTBS		OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS		"setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS		600
+#define OBJ_setct_BCIDistributionTBS		OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt		"setext-genCrypt"
+#define LN_setext_genCrypt		"generic cryptogram"
+#define NID_setext_genCrypt		601
+#define OBJ_setext_genCrypt		OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth		"setext-miAuth"
+#define LN_setext_miAuth		"merchant initiated auth"
+#define NID_setext_miAuth		602
+#define OBJ_setext_miAuth		OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure		"setext-pinSecure"
+#define NID_setext_pinSecure		603
+#define OBJ_setext_pinSecure		OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny		"setext-pinAny"
+#define NID_setext_pinAny		604
+#define OBJ_setext_pinAny		OBJ_set_msgExt,5L
+
+#define SN_setext_track2		"setext-track2"
+#define NID_setext_track2		605
+#define OBJ_setext_track2		OBJ_set_msgExt,7L
+
+#define SN_setext_cv		"setext-cv"
+#define LN_setext_cv		"additional verification"
+#define NID_setext_cv		606
+#define OBJ_setext_cv		OBJ_set_msgExt,8L
+
+#define SN_set_policy_root		"set-policy-root"
+#define NID_set_policy_root		607
+#define OBJ_set_policy_root		OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot		"setCext-hashedRoot"
+#define NID_setCext_hashedRoot		608
+#define OBJ_setCext_hashedRoot		OBJ_set_certExt,0L
+
+#define SN_setCext_certType		"setCext-certType"
+#define NID_setCext_certType		609
+#define OBJ_setCext_certType		OBJ_set_certExt,1L
+
+#define SN_setCext_merchData		"setCext-merchData"
+#define NID_setCext_merchData		610
+#define OBJ_setCext_merchData		OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired		"setCext-cCertRequired"
+#define NID_setCext_cCertRequired		611
+#define OBJ_setCext_cCertRequired		OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling		"setCext-tunneling"
+#define NID_setCext_tunneling		612
+#define OBJ_setCext_tunneling		OBJ_set_certExt,4L
+
+#define SN_setCext_setExt		"setCext-setExt"
+#define NID_setCext_setExt		613
+#define OBJ_setCext_setExt		OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf		"setCext-setQualf"
+#define NID_setCext_setQualf		614
+#define OBJ_setCext_setQualf		OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities		"setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities		615
+#define OBJ_setCext_PGWYcapabilities		OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier		"setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier		616
+#define OBJ_setCext_TokenIdentifier		OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data		"setCext-Track2Data"
+#define NID_setCext_Track2Data		617
+#define OBJ_setCext_Track2Data		OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType		"setCext-TokenType"
+#define NID_setCext_TokenType		618
+#define OBJ_setCext_TokenType		OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities		"setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities		619
+#define OBJ_setCext_IssuerCapabilities		OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert		"setAttr-Cert"
+#define NID_setAttr_Cert		620
+#define OBJ_setAttr_Cert		OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap		"setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap		"payment gateway capabilities"
+#define NID_setAttr_PGWYcap		621
+#define OBJ_setAttr_PGWYcap		OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType		"setAttr-TokenType"
+#define NID_setAttr_TokenType		622
+#define OBJ_setAttr_TokenType		OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap		"setAttr-IssCap"
+#define LN_setAttr_IssCap		"issuer capabilities"
+#define NID_setAttr_IssCap		623
+#define OBJ_setAttr_IssCap		OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb		"set-rootKeyThumb"
+#define NID_set_rootKeyThumb		624
+#define OBJ_set_rootKeyThumb		OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy		"set-addPolicy"
+#define NID_set_addPolicy		625
+#define OBJ_set_addPolicy		OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV		"setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV		626
+#define OBJ_setAttr_Token_EMV		OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime		"setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime		627
+#define OBJ_setAttr_Token_B0Prime		OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM		"setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM		628
+#define OBJ_setAttr_IssCap_CVM		OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2		"setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2		629
+#define OBJ_setAttr_IssCap_T2		OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig		"setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig		630
+#define OBJ_setAttr_IssCap_Sig		OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm		"setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm		"generate cryptogram"
+#define NID_setAttr_GenCryptgrm		631
+#define OBJ_setAttr_GenCryptgrm		OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc		"setAttr-T2Enc"
+#define LN_setAttr_T2Enc		"encrypted track 2"
+#define NID_setAttr_T2Enc		632
+#define OBJ_setAttr_T2Enc		OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt		"setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt		"cleartext track 2"
+#define NID_setAttr_T2cleartxt		633
+#define OBJ_setAttr_T2cleartxt		OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig		"setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig		"ICC or token signature"
+#define NID_setAttr_TokICCsig		634
+#define OBJ_setAttr_TokICCsig		OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig		"setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig		"secure device signature"
+#define NID_setAttr_SecDevSig		635
+#define OBJ_setAttr_SecDevSig		OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA		"set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA		636
+#define OBJ_set_brand_IATA_ATA		OBJ_set_brand,1L
+
+#define SN_set_brand_Diners		"set-brand-Diners"
+#define NID_set_brand_Diners		637
+#define OBJ_set_brand_Diners		OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress		"set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress		638
+#define OBJ_set_brand_AmericanExpress		OBJ_set_brand,34L
+
+#define SN_set_brand_JCB		"set-brand-JCB"
+#define NID_set_brand_JCB		639
+#define OBJ_set_brand_JCB		OBJ_set_brand,35L
+
+#define SN_set_brand_Visa		"set-brand-Visa"
+#define NID_set_brand_Visa		640
+#define OBJ_set_brand_Visa		OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard		"set-brand-MasterCard"
+#define NID_set_brand_MasterCard		641
+#define OBJ_set_brand_MasterCard		OBJ_set_brand,5L
+
+#define SN_set_brand_Novus		"set-brand-Novus"
+#define NID_set_brand_Novus		642
+#define OBJ_set_brand_Novus		OBJ_set_brand,6011L
+
+#define SN_des_cdmf		"DES-CDMF"
+#define LN_des_cdmf		"des-cdmf"
+#define NID_des_cdmf		643
+#define OBJ_des_cdmf		OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET		"rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET		644
+#define OBJ_rsaOAEPEncryptionSET		OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3		"Oakley-EC2N-3"
+#define LN_ipsec3		"ipsec3"
+#define NID_ipsec3		749
+
+#define SN_ipsec4		"Oakley-EC2N-4"
+#define LN_ipsec4		"ipsec4"
+#define NID_ipsec4		750
+
+#define SN_camellia_128_cbc		"CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc		"camellia-128-cbc"
+#define NID_camellia_128_cbc		751
+#define OBJ_camellia_128_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc		"CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc		"camellia-192-cbc"
+#define NID_camellia_192_cbc		752
+#define OBJ_camellia_192_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc		"CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc		"camellia-256-cbc"
+#define NID_camellia_256_cbc		753
+#define OBJ_camellia_256_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define OBJ_ntt_ds		0L,3L,4401L,5L
+
+#define OBJ_camellia		OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb		"CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb		"camellia-128-ecb"
+#define NID_camellia_128_ecb		754
+#define OBJ_camellia_128_ecb		OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128		"CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128		"camellia-128-ofb"
+#define NID_camellia_128_ofb128		766
+#define OBJ_camellia_128_ofb128		OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128		"CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128		"camellia-128-cfb"
+#define NID_camellia_128_cfb128		757
+#define OBJ_camellia_128_cfb128		OBJ_camellia,4L
+
+#define SN_camellia_192_ecb		"CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb		"camellia-192-ecb"
+#define NID_camellia_192_ecb		755
+#define OBJ_camellia_192_ecb		OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128		"CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128		"camellia-192-ofb"
+#define NID_camellia_192_ofb128		767
+#define OBJ_camellia_192_ofb128		OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128		"CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128		"camellia-192-cfb"
+#define NID_camellia_192_cfb128		758
+#define OBJ_camellia_192_cfb128		OBJ_camellia,24L
+
+#define SN_camellia_256_ecb		"CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb		"camellia-256-ecb"
+#define NID_camellia_256_ecb		756
+#define OBJ_camellia_256_ecb		OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128		"CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128		"camellia-256-ofb"
+#define NID_camellia_256_ofb128		768
+#define OBJ_camellia_256_ofb128		OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128		"CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128		"camellia-256-cfb"
+#define NID_camellia_256_cfb128		759
+#define OBJ_camellia_256_cfb128		OBJ_camellia,44L
+
+#define SN_camellia_128_cfb1		"CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1		"camellia-128-cfb1"
+#define NID_camellia_128_cfb1		760
+
+#define SN_camellia_192_cfb1		"CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1		"camellia-192-cfb1"
+#define NID_camellia_192_cfb1		761
+
+#define SN_camellia_256_cfb1		"CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1		"camellia-256-cfb1"
+#define NID_camellia_256_cfb1		762
+
+#define SN_camellia_128_cfb8		"CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8		"camellia-128-cfb8"
+#define NID_camellia_128_cfb8		763
+
+#define SN_camellia_192_cfb8		"CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8		"camellia-192-cfb8"
+#define NID_camellia_192_cfb8		764
+
+#define SN_camellia_256_cfb8		"CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8		"camellia-256-cfb8"
+#define NID_camellia_256_cfb8		765
+
diff --git a/dep/include/openssl/objects.h b/dep/include/openssl/objects.h
new file mode 100644
index 000000000..7242f76fb
--- /dev/null
+++ b/dep/include/openssl/objects.h
@@ -0,0 +1,1049 @@
+/* crypto/objects/objects.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_OBJECTS_H
+#define HEADER_OBJECTS_H
+
+#define USE_OBJ_MAC
+
+#ifdef USE_OBJ_MAC
+#include 
+#else
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_Algorithm			"Algorithm"
+#define LN_algorithm			"algorithm"
+#define NID_algorithm			38
+#define OBJ_algorithm			1L,3L,14L,3L,2L
+
+#define LN_rsadsi			"rsadsi"
+#define NID_rsadsi			1
+#define OBJ_rsadsi			1L,2L,840L,113549L
+
+#define LN_pkcs				"pkcs"
+#define NID_pkcs			2
+#define OBJ_pkcs			OBJ_rsadsi,1L
+
+#define SN_md2				"MD2"
+#define LN_md2				"md2"
+#define NID_md2				3
+#define OBJ_md2				OBJ_rsadsi,2L,2L
+
+#define SN_md5				"MD5"
+#define LN_md5				"md5"
+#define NID_md5				4
+#define OBJ_md5				OBJ_rsadsi,2L,5L
+
+#define SN_rc4				"RC4"
+#define LN_rc4				"rc4"
+#define NID_rc4				5
+#define OBJ_rc4				OBJ_rsadsi,3L,4L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs,1L,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption	7
+#define OBJ_md2WithRSAEncryption	OBJ_pkcs,1L,2L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption	8
+#define OBJ_md5WithRSAEncryption	OBJ_pkcs,1L,4L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC	9
+#define OBJ_pbeWithMD2AndDES_CBC	OBJ_pkcs,5L,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC	10
+#define OBJ_pbeWithMD5AndDES_CBC	OBJ_pkcs,5L,3L
+
+#define LN_X500				"X500"
+#define NID_X500			11
+#define OBJ_X500			2L,5L
+
+#define LN_X509				"X509"
+#define NID_X509			12
+#define OBJ_X509			OBJ_X500,4L
+
+#define SN_commonName			"CN"
+#define LN_commonName			"commonName"
+#define NID_commonName			13
+#define OBJ_commonName			OBJ_X509,3L
+
+#define SN_countryName			"C"
+#define LN_countryName			"countryName"
+#define NID_countryName			14
+#define OBJ_countryName			OBJ_X509,6L
+
+#define SN_localityName			"L"
+#define LN_localityName			"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName	"OU"
+#define LN_organizationalUnitName	"organizationalUnitName"
+#define NID_organizationalUnitName	18
+#define OBJ_organizationalUnitName	OBJ_X509,11L
+
+#define SN_rsa				"RSA"
+#define LN_rsa				"rsa"
+#define NID_rsa				19
+#define OBJ_rsa				OBJ_X500,8L,1L,1L
+
+#define LN_pkcs7			"pkcs7"
+#define NID_pkcs7			20
+#define OBJ_pkcs7			OBJ_pkcs,7L
+
+#define LN_pkcs7_data			"pkcs7-data"
+#define NID_pkcs7_data			21
+#define OBJ_pkcs7_data			OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed			"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped	"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped	24
+#define OBJ_pkcs7_signedAndEnveloped	OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest			"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define LN_pkcs3			"pkcs3"
+#define NID_pkcs3			27
+#define OBJ_pkcs3			OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_des_ecb			"DES-ECB"
+#define LN_des_ecb			"des-ecb"
+#define NID_des_ecb			29
+#define OBJ_des_ecb			OBJ_algorithm,6L
+
+#define SN_des_cfb64			"DES-CFB"
+#define LN_des_cfb64			"des-cfb"
+#define NID_des_cfb64			30
+/* IV + num */
+#define OBJ_des_cfb64			OBJ_algorithm,9L
+
+#define SN_des_cbc			"DES-CBC"
+#define LN_des_cbc			"des-cbc"
+#define NID_des_cbc			31
+/* IV */
+#define OBJ_des_cbc			OBJ_algorithm,7L
+
+#define SN_des_ede			"DES-EDE"
+#define LN_des_ede			"des-ede"
+#define NID_des_ede			32
+/* ?? */
+#define OBJ_des_ede			OBJ_algorithm,17L
+
+#define SN_des_ede3			"DES-EDE3"
+#define LN_des_ede3			"des-ede3"
+#define NID_des_ede3			33
+
+#define SN_idea_cbc			"IDEA-CBC"
+#define LN_idea_cbc			"idea-cbc"
+#define NID_idea_cbc			34
+#define OBJ_idea_cbc			1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_cfb64			"IDEA-CFB"
+#define LN_idea_cfb64			"idea-cfb"
+#define NID_idea_cfb64			35
+
+#define SN_idea_ecb			"IDEA-ECB"
+#define LN_idea_ecb			"idea-ecb"
+#define NID_idea_ecb			36
+
+#define SN_rc2_cbc			"RC2-CBC"
+#define LN_rc2_cbc			"rc2-cbc"
+#define NID_rc2_cbc			37
+#define OBJ_rc2_cbc			OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb			"RC2-ECB"
+#define LN_rc2_ecb			"rc2-ecb"
+#define NID_rc2_ecb			38
+
+#define SN_rc2_cfb64			"RC2-CFB"
+#define LN_rc2_cfb64			"rc2-cfb"
+#define NID_rc2_cfb64			39
+
+#define SN_rc2_ofb64			"RC2-OFB"
+#define LN_rc2_ofb64			"rc2-ofb"
+#define NID_rc2_ofb64			40
+
+#define SN_sha				"SHA"
+#define LN_sha				"sha"
+#define NID_sha				41
+#define OBJ_sha				OBJ_algorithm,18L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption	42
+#define OBJ_shaWithRSAEncryption	OBJ_algorithm,15L
+
+#define SN_des_ede_cbc			"DES-EDE-CBC"
+#define LN_des_ede_cbc			"des-ede-cbc"
+#define NID_des_ede_cbc			43
+
+#define SN_des_ede3_cbc			"DES-EDE3-CBC"
+#define LN_des_ede3_cbc			"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_des_ofb64			"DES-OFB"
+#define LN_des_ofb64			"des-ofb"
+#define NID_des_ofb64			45
+#define OBJ_des_ofb64			OBJ_algorithm,8L
+
+#define SN_idea_ofb64			"IDEA-OFB"
+#define LN_idea_ofb64			"idea-ofb"
+#define NID_idea_ofb64			46
+
+#define LN_pkcs9			"pkcs9"
+#define NID_pkcs9			47
+#define OBJ_pkcs9			OBJ_pkcs,9L
+
+#define SN_pkcs9_emailAddress		"Email"
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName	"unstructuredName"
+#define NID_pkcs9_unstructuredName	49
+#define OBJ_pkcs9_unstructuredName	OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature	"countersignature"
+#define NID_pkcs9_countersignature	53
+#define OBJ_pkcs9_countersignature	OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword	"challengePassword"
+#define NID_pkcs9_challengePassword	54
+#define OBJ_pkcs9_challengePassword	OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress	"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress	55
+#define OBJ_pkcs9_unstructuredAddress	OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes	"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes	56
+#define OBJ_pkcs9_extCertAttributes	OBJ_pkcs9,9L
+
+#define SN_netscape			"Netscape"
+#define LN_netscape			"Netscape Communications Corp."
+#define NID_netscape			57
+#define OBJ_netscape			2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension	"nsCertExt"
+#define LN_netscape_cert_extension	"Netscape Certificate Extension"
+#define NID_netscape_cert_extension	58
+#define OBJ_netscape_cert_extension	OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+/* I'm not sure about the object ID */
+#define SN_sha1				"SHA1"
+#define LN_sha1				"sha1"
+#define NID_sha1			64
+#define OBJ_sha1			OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1			1L,3L,14L,2L,26L,05L <- wrong */
+
+#define SN_sha1WithRSAEncryption	"RSA-SHA1"
+#define LN_sha1WithRSAEncryption	"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption	65
+#define OBJ_sha1WithRSAEncryption	OBJ_pkcs,1L,5L
+
+#define SN_dsaWithSHA			"DSA-SHA"
+#define LN_dsaWithSHA			"dsaWithSHA"
+#define NID_dsaWithSHA			66
+#define OBJ_dsaWithSHA			OBJ_algorithm,13L
+
+#define SN_dsa_2			"DSA-old"
+#define LN_dsa_2			"dsaEncryption-old"
+#define NID_dsa_2			67
+#define OBJ_dsa_2			OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#define SN_pbeWithSHA1AndRC2_CBC	"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC	"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC	68
+#define OBJ_pbeWithSHA1AndRC2_CBC	OBJ_pkcs,5L,11L 
+
+/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now
+ * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something
+ * completely different.
+ */
+#define LN_id_pbkdf2			"PBKDF2"
+#define NID_id_pbkdf2			69
+#define OBJ_id_pbkdf2			OBJ_pkcs,5L,12L 
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url	"nsRevocationUrl"
+#define LN_netscape_revocation_url	"Netscape Revocation Url"
+#define NID_netscape_revocation_url	73
+#define OBJ_netscape_revocation_url	OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url	"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url	"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url	74
+#define OBJ_netscape_ca_revocation_url	OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url	75
+#define OBJ_netscape_renewal_url	OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url	"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url	"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url	76
+#define OBJ_netscape_ca_policy_url	OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name	"nsSslServerName"
+#define LN_netscape_ssl_server_name	"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name	77
+#define OBJ_netscape_ssl_server_name	OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence	"nsCertSequence"
+#define LN_netscape_cert_sequence	"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence	79
+#define OBJ_netscape_cert_sequence	OBJ_netscape_data_type,5L
+
+#define SN_desx_cbc			"DESX-CBC"
+#define LN_desx_cbc			"desx-cbc"
+#define NID_desx_cbc			80
+
+#define SN_id_ce			"id-ce"
+#define NID_id_ce			81
+#define OBJ_id_ce			2L,5L,29L
+
+#define SN_subject_key_identifier	"subjectKeyIdentifier"
+#define LN_subject_key_identifier	"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier	82
+#define OBJ_subject_key_identifier	OBJ_id_ce,14L
+
+#define SN_key_usage			"keyUsage"
+#define LN_key_usage			"X509v3 Key Usage"
+#define NID_key_usage			83
+#define OBJ_key_usage			OBJ_id_ce,15L
+
+#define SN_private_key_usage_period	"privateKeyUsagePeriod"
+#define LN_private_key_usage_period	"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period	84
+#define OBJ_private_key_usage_period	OBJ_id_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_id_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_id_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_id_ce,19L
+
+#define SN_crl_number			"crlNumber"
+#define LN_crl_number			"X509v3 CRL Number"
+#define NID_crl_number			88
+#define OBJ_crl_number			OBJ_id_ce,20L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies	89
+#define OBJ_certificate_policies	OBJ_id_ce,32L
+
+#define SN_authority_key_identifier	"authorityKeyIdentifier"
+#define LN_authority_key_identifier	"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier	90
+#define OBJ_authority_key_identifier	OBJ_id_ce,35L
+
+#define SN_bf_cbc			"BF-CBC"
+#define LN_bf_cbc			"bf-cbc"
+#define NID_bf_cbc			91
+#define OBJ_bf_cbc			1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb			"BF-ECB"
+#define LN_bf_ecb			"bf-ecb"
+#define NID_bf_ecb			92
+
+#define SN_bf_cfb64			"BF-CFB"
+#define LN_bf_cfb64			"bf-cfb"
+#define NID_bf_cfb64			93
+
+#define SN_bf_ofb64			"BF-OFB"
+#define LN_bf_ofb64			"bf-ofb"
+#define NID_bf_ofb64			94
+
+#define SN_mdc2				"MDC2"
+#define LN_mdc2				"mdc2"
+#define NID_mdc2			95
+#define OBJ_mdc2			2L,5L,8L,3L,101L
+/* An alternative?			1L,3L,14L,3L,2L,19L */
+
+#define SN_mdc2WithRSA			"RSA-MDC2"
+#define LN_mdc2WithRSA			"mdc2withRSA"
+#define NID_mdc2WithRSA			96
+#define OBJ_mdc2WithRSA			2L,5L,8L,3L,100L
+
+#define SN_rc4_40			"RC4-40"
+#define LN_rc4_40			"rc4-40"
+#define NID_rc4_40			97
+
+#define SN_rc2_40_cbc			"RC2-40-CBC"
+#define LN_rc2_40_cbc			"rc2-40-cbc"
+#define NID_rc2_40_cbc			98
+
+#define SN_givenName			"G"
+#define LN_givenName			"givenName"
+#define NID_givenName			99
+#define OBJ_givenName			OBJ_X509,42L
+
+#define SN_surname			"S"
+#define LN_surname			"surname"
+#define NID_surname			100
+#define OBJ_surname			OBJ_X509,4L
+
+#define SN_initials			"I"
+#define LN_initials			"initials"
+#define NID_initials			101
+#define OBJ_initials			OBJ_X509,43L
+
+#define SN_uniqueIdentifier		"UID"
+#define LN_uniqueIdentifier		"uniqueIdentifier"
+#define NID_uniqueIdentifier		102
+#define OBJ_uniqueIdentifier		OBJ_X509,45L
+
+#define SN_crl_distribution_points	"crlDistributionPoints"
+#define LN_crl_distribution_points	"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points	103
+#define OBJ_crl_distribution_points	OBJ_id_ce,31L
+
+#define SN_md5WithRSA			"RSA-NP-MD5"
+#define LN_md5WithRSA			"md5WithRSA"
+#define NID_md5WithRSA			104
+#define OBJ_md5WithRSA			OBJ_algorithm,3L
+
+#define SN_serialNumber			"SN"
+#define LN_serialNumber			"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_title			"T"
+#define LN_title			"title"
+#define NID_title			106
+#define OBJ_title			OBJ_X509,12L
+
+#define SN_description			"D"
+#define LN_description			"description"
+#define NID_description			107
+#define OBJ_description			OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#define SN_cast5_cbc			"CAST5-CBC"
+#define LN_cast5_cbc			"cast5-cbc"
+#define NID_cast5_cbc			108
+#define OBJ_cast5_cbc			1L,2L,840L,113533L,7L,66L,10L
+
+#define SN_cast5_ecb			"CAST5-ECB"
+#define LN_cast5_ecb			"cast5-ecb"
+#define NID_cast5_ecb			109
+
+#define SN_cast5_cfb64			"CAST5-CFB"
+#define LN_cast5_cfb64			"cast5-cfb"
+#define NID_cast5_cfb64			110
+
+#define SN_cast5_ofb64			"CAST5-OFB"
+#define LN_cast5_ofb64			"cast5-ofb"
+#define NID_cast5_ofb64			111
+
+#define LN_pbeWithMD5AndCast5_CBC	"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC	112
+#define OBJ_pbeWithMD5AndCast5_CBC	1L,2L,840L,113533L,7L,66L,12L
+
+/* This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#define SN_dsaWithSHA1			"DSA-SHA1"
+#define LN_dsaWithSHA1			"dsaWithSHA1"
+#define NID_dsaWithSHA1			113
+#define OBJ_dsaWithSHA1			1L,2L,840L,10040L,4L,3L
+
+#define NID_md5_sha1			114
+#define SN_md5_sha1			"MD5-SHA1"
+#define LN_md5_sha1			"md5-sha1"
+
+#define SN_sha1WithRSA			"RSA-SHA1-2"
+#define LN_sha1WithRSA			"sha1WithRSA"
+#define NID_sha1WithRSA			115
+#define OBJ_sha1WithRSA			OBJ_algorithm,29L
+
+#define SN_dsa				"DSA"
+#define LN_dsa				"dsaEncryption"
+#define NID_dsa				116
+#define OBJ_dsa				1L,2L,840L,10040L,4L,1L
+
+#define SN_ripemd160			"RIPEMD160"
+#define LN_ripemd160			"ripemd160"
+#define NID_ripemd160			117
+#define OBJ_ripemd160			1L,3L,36L,3L,2L,1L
+
+/* The name should actually be rsaSignatureWithripemd160, but I'm going
+ * to continue using the convention I'm using with the other ciphers */
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+/* Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *	version           INTEGER (v1_0(16)),
+ *	rounds            INTEGER (8..127),
+ *	blockSizeInBits   INTEGER (64, 128),
+ *	iv                OCTET STRING OPTIONAL
+ *	}
+ */
+#define SN_rc5_cbc			"RC5-CBC"
+#define LN_rc5_cbc			"rc5-cbc"
+#define NID_rc5_cbc			120
+#define OBJ_rc5_cbc			OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb			"RC5-ECB"
+#define LN_rc5_ecb			"rc5-ecb"
+#define NID_rc5_ecb			121
+
+#define SN_rc5_cfb64			"RC5-CFB"
+#define LN_rc5_cfb64			"rc5-cfb"
+#define NID_rc5_cfb64			122
+
+#define SN_rc5_ofb64			"RC5-OFB"
+#define LN_rc5_ofb64			"rc5-ofb"
+#define NID_rc5_ofb64			123
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_id_ce,37
+
+#define SN_id_pkix			"PKIX"
+#define NID_id_pkix			127
+#define OBJ_id_pkix			1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_kp			"id-kp"
+#define NID_id_kp			128
+#define OBJ_id_kp			OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#define SN_server_auth			"serverAuth"
+#define LN_server_auth			"TLS Web Server Authentication"
+#define NID_server_auth			129
+#define OBJ_server_auth			OBJ_id_kp,1L
+
+#define SN_client_auth			"clientAuth"
+#define LN_client_auth			"TLS Web Client Authentication"
+#define NID_client_auth			130
+#define OBJ_client_auth			OBJ_id_kp,2L
+
+#define SN_code_sign			"codeSigning"
+#define LN_code_sign			"Code Signing"
+#define NID_code_sign			131
+#define OBJ_code_sign			OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_time_stamp			"timeStamping"
+#define LN_time_stamp			"Time Stamping"
+#define NID_time_stamp			133
+#define OBJ_time_stamp			OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#define SN_ms_code_ind			"msCodeInd"
+#define LN_ms_code_ind			"Microsoft Individual Code Signing"
+#define NID_ms_code_ind			134
+#define OBJ_ms_code_ind			1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com			"msCodeCom"
+#define LN_ms_code_com			"Microsoft Commercial Code Signing"
+#define NID_ms_code_com			135
+#define OBJ_ms_code_com			1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign			"msCTLSign"
+#define LN_ms_ctl_sign			"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign			136
+#define OBJ_ms_ctl_sign			1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc			"msSGC"
+#define LN_ms_sgc			"Microsoft Server Gated Crypto"
+#define NID_ms_sgc			137
+#define OBJ_ms_sgc			1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs			"msEFS"
+#define LN_ms_efs			"Microsoft Encrypted File System"
+#define NID_ms_efs			138
+#define OBJ_ms_efs			1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#define SN_ns_sgc			"nsSGC"
+#define LN_ns_sgc			"Netscape Server Gated Crypto"
+#define NID_ns_sgc			139
+#define OBJ_ns_sgc			OBJ_netscape,4L,1L
+
+#define SN_delta_crl			"deltaCRL"
+#define LN_delta_crl			"X509v3 Delta CRL Indicator"
+#define NID_delta_crl			140
+#define OBJ_delta_crl			OBJ_id_ce,27L
+
+#define SN_crl_reason			"CRLReason"
+#define LN_crl_reason			"CRL Reason Code"
+#define NID_crl_reason			141
+#define OBJ_crl_reason			OBJ_id_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_id_ce,24L
+
+#define SN_sxnet			"SXNetID"
+#define LN_sxnet			"Strong Extranet ID"
+#define NID_sxnet			143
+#define OBJ_sxnet			1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#define OBJ_pkcs12			OBJ_pkcs,12L
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12, 1
+
+#define SN_pbe_WithSHA1And128BitRC4	"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4	"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4	144
+#define OBJ_pbe_WithSHA1And128BitRC4	OBJ_pkcs12_pbeids, 1L
+
+#define SN_pbe_WithSHA1And40BitRC4	"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4	"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4	145
+#define OBJ_pbe_WithSHA1And40BitRC4	OBJ_pkcs12_pbeids, 2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC	"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC	"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC	146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC	"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC	"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC	147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC	148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC	OBJ_pkcs12_pbeids, 5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC	"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC	"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC	149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC	OBJ_pkcs12_pbeids, 6L
+
+#define OBJ_pkcs12_Version1	OBJ_pkcs12, 10L
+
+#define OBJ_pkcs12_BagIds	OBJ_pkcs12_Version1, 1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds, 1L
+
+#define LN_pkcs8ShroudedKeyBag	"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag	151
+#define OBJ_pkcs8ShroudedKeyBag	OBJ_pkcs12_BagIds, 2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds, 3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds, 4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds, 5L
+
+#define LN_safeContentsBag	"safeContentsBag"
+#define NID_safeContentsBag	155
+#define OBJ_safeContentsBag	OBJ_pkcs12_BagIds, 6L
+
+#define LN_friendlyName		"friendlyName"
+#define	NID_friendlyName	156
+#define OBJ_friendlyName	OBJ_pkcs9, 20L
+
+#define LN_localKeyID		"localKeyID"
+#define	NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9, 21L
+
+#define OBJ_certTypes		OBJ_pkcs9, 22L
+
+#define LN_x509Certificate	"x509Certificate"
+#define	NID_x509Certificate	158
+#define OBJ_x509Certificate	OBJ_certTypes, 1L
+
+#define LN_sdsiCertificate	"sdsiCertificate"
+#define	NID_sdsiCertificate	159
+#define OBJ_sdsiCertificate	OBJ_certTypes, 2L
+
+#define OBJ_crlTypes		OBJ_pkcs9, 23L
+
+#define LN_x509Crl		"x509Crl"
+#define	NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs,5L,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs,5L,14L
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1	163
+#define OBJ_hmacWithSHA1	OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define SN_id_qt_cps		"id-qt-cps"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_pkix,2L,1L
+
+#define LN_id_qt_unotice	"Policy Qualifier User Notice"
+#define SN_id_qt_unotice	"id-qt-unotice"
+#define NID_id_qt_unotice	165
+#define OBJ_id_qt_unotice	OBJ_id_pkix,2L,2L
+
+#define SN_rc2_64_cbc			"RC2-64-CBC"
+#define LN_rc2_64_cbc			"rc2-64-cbc"
+#define NID_rc2_64_cbc			166
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC	168
+#define OBJ_pbeWithMD2AndRC2_CBC	OBJ_pkcs,5L,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC	169
+#define OBJ_pbeWithMD5AndRC2_CBC	OBJ_pkcs,5L,6L
+
+#define SN_pbeWithSHA1AndDES_CBC	"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC	"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC	170
+#define OBJ_pbeWithSHA1AndDES_CBC	OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#define LN_ms_ext_req			"Microsoft Extension Request"
+#define SN_ms_ext_req			"msExtReq"
+#define NID_ms_ext_req			171
+#define OBJ_ms_ext_req			1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define LN_ext_req			"Extension Request"
+#define SN_ext_req			"extReq"
+#define NID_ext_req			172
+#define OBJ_ext_req			OBJ_pkcs9,14L
+
+#define SN_name				"name"
+#define LN_name				"name"
+#define NID_name			173
+#define OBJ_name			OBJ_X509,41L
+
+#define SN_dnQualifier			"dnQualifier"
+#define LN_dnQualifier			"dnQualifier"
+#define NID_dnQualifier			174
+#define OBJ_dnQualifier			OBJ_X509,46L
+
+#define SN_id_pe			"id-pe"
+#define NID_id_pe			175
+#define OBJ_id_pe			OBJ_id_pkix,1L
+
+#define SN_id_ad			"id-ad"
+#define NID_id_ad			176
+#define OBJ_id_ad			OBJ_id_pkix,48L
+
+#define SN_info_access			"authorityInfoAccess"
+#define LN_info_access			"Authority Information Access"
+#define NID_info_access			177
+#define OBJ_info_access			OBJ_id_pe,1L
+
+#define SN_ad_OCSP			"OCSP"
+#define LN_ad_OCSP			"OCSP"
+#define NID_ad_OCSP			178
+#define OBJ_ad_OCSP			OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_OCSP_sign			"OCSPSigning"
+#define LN_OCSP_sign			"OCSP Signing"
+#define NID_OCSP_sign			180
+#define OBJ_OCSP_sign			OBJ_id_kp,9L
+#endif /* USE_OBJ_MAC */
+
+#include 
+#include 
+
+#define	OBJ_NAME_TYPE_UNDEF		0x00
+#define	OBJ_NAME_TYPE_MD_METH		0x01
+#define	OBJ_NAME_TYPE_CIPHER_METH	0x02
+#define	OBJ_NAME_TYPE_PKEY_METH		0x03
+#define	OBJ_NAME_TYPE_COMP_METH		0x04
+#define	OBJ_NAME_TYPE_NUM		0x05
+
+#define	OBJ_NAME_ALIAS			0x8000
+
+#define OBJ_BSEARCH_VALUE_ON_NOMATCH		0x01
+#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH	0x02
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st
+	{
+	int type;
+	int alias;
+	const char *name;
+	const char *data;
+	} OBJ_NAME;
+
+#define		OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
+		       int (*cmp_func)(const char *, const char *),
+		       void (*free_func)(const char *, int, const char *));
+const char *OBJ_NAME_get(const char *name,int type);
+int OBJ_NAME_add(const char *name,int type,const char *data);
+int OBJ_NAME_remove(const char *name,int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),
+		     void *arg);
+void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
+			    void *arg);
+
+ASN1_OBJECT *	OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_nid2obj(int n);
+const char *	OBJ_nid2ln(int n);
+const char *	OBJ_nid2sn(int n);
+int		OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_txt2obj(const char *s, int no_name);
+int	OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int		OBJ_txt2nid(const char *s);
+int		OBJ_ln2nid(const char *s);
+int		OBJ_sn2nid(const char *s);
+int		OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
+const char *	OBJ_bsearch(const char *key,const char *base,int num,int size,
+	int (*cmp)(const void *, const void *));
+const char *	OBJ_bsearch_ex(const char *key,const char *base,int num,
+	int size, int (*cmp)(const void *, const void *), int flags);
+
+int		OBJ_new_nid(int num);
+int		OBJ_add_object(const ASN1_OBJECT *obj);
+int		OBJ_create(const char *oid,const char *sn,const char *ln);
+void		OBJ_cleanup(void );
+int		OBJ_create_objects(BIO *in);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+#define OBJ_F_OBJ_ADD_OBJECT				 105
+#define OBJ_F_OBJ_CREATE				 100
+#define OBJ_F_OBJ_DUP					 101
+#define OBJ_F_OBJ_NAME_NEW_INDEX			 106
+#define OBJ_F_OBJ_NID2LN				 102
+#define OBJ_F_OBJ_NID2OBJ				 103
+#define OBJ_F_OBJ_NID2SN				 104
+
+/* Reason codes. */
+#define OBJ_R_MALLOC_FAILURE				 100
+#define OBJ_R_UNKNOWN_NID				 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/ocsp.h b/dep/include/openssl/ocsp.h
new file mode 100644
index 000000000..53f3364af
--- /dev/null
+++ b/dep/include/openssl/ocsp.h
@@ -0,0 +1,614 @@
+/* ocsp.h */
+/* Written by Tom Titchener  for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_OCSP_H
+#define HEADER_OCSP_H
+
+#include 
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Various flags and values */
+
+#define OCSP_DEFAULT_NONCE_LENGTH	16
+
+#define OCSP_NOCERTS			0x1
+#define OCSP_NOINTERN			0x2
+#define OCSP_NOSIGS			0x4
+#define OCSP_NOCHAIN			0x8
+#define OCSP_NOVERIFY			0x10
+#define OCSP_NOEXPLICIT			0x20
+#define OCSP_NOCASIGN			0x40
+#define OCSP_NODELEGATED		0x80
+#define OCSP_NOCHECKS			0x100
+#define OCSP_TRUSTOTHER			0x200
+#define OCSP_RESPID_KEY			0x400
+#define OCSP_NOTIME			0x800
+
+/*   CertID ::= SEQUENCE {
+ *       hashAlgorithm            AlgorithmIdentifier,
+ *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+ *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
+ *       serialNumber       CertificateSerialNumber }
+ */
+typedef struct ocsp_cert_id_st
+	{
+	X509_ALGOR *hashAlgorithm;
+	ASN1_OCTET_STRING *issuerNameHash;
+	ASN1_OCTET_STRING *issuerKeyHash;
+	ASN1_INTEGER *serialNumber;
+	} OCSP_CERTID;
+
+DECLARE_STACK_OF(OCSP_CERTID)
+
+/*   Request ::=     SEQUENCE {
+ *       reqCert                    CertID,
+ *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_one_request_st
+	{
+	OCSP_CERTID *reqCert;
+	STACK_OF(X509_EXTENSION) *singleRequestExtensions;
+	} OCSP_ONEREQ;
+
+DECLARE_STACK_OF(OCSP_ONEREQ)
+DECLARE_ASN1_SET_OF(OCSP_ONEREQ)
+
+
+/*   TBSRequest      ::=     SEQUENCE {
+ *       version             [0] EXPLICIT Version DEFAULT v1,
+ *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+ *       requestList             SEQUENCE OF Request,
+ *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_req_info_st
+	{
+	ASN1_INTEGER *version;
+	GENERAL_NAME *requestorName;
+	STACK_OF(OCSP_ONEREQ) *requestList;
+	STACK_OF(X509_EXTENSION) *requestExtensions;
+	} OCSP_REQINFO;
+
+/*   Signature       ::=     SEQUENCE {
+ *       signatureAlgorithm   AlgorithmIdentifier,
+ *       signature            BIT STRING,
+ *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+typedef struct ocsp_signature_st
+	{
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+	} OCSP_SIGNATURE;
+
+/*   OCSPRequest     ::=     SEQUENCE {
+ *       tbsRequest                  TBSRequest,
+ *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+ */
+typedef struct ocsp_request_st
+	{
+	OCSP_REQINFO *tbsRequest;
+	OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
+	} OCSP_REQUEST;
+
+/*   OCSPResponseStatus ::= ENUMERATED {
+ *       successful            (0),      --Response has valid confirmations
+ *       malformedRequest      (1),      --Illegal confirmation request
+ *       internalError         (2),      --Internal error in issuer
+ *       tryLater              (3),      --Try again later
+ *                                       --(4) is not used
+ *       sigRequired           (5),      --Must sign the request
+ *       unauthorized          (6)       --Request unauthorized
+ *   }
+ */
+#define OCSP_RESPONSE_STATUS_SUCCESSFUL          0
+#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
+#define OCSP_RESPONSE_STATUS_INTERNALERROR        2
+#define OCSP_RESPONSE_STATUS_TRYLATER             3
+#define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
+#define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6
+
+/*   ResponseBytes ::=       SEQUENCE {
+ *       responseType   OBJECT IDENTIFIER,
+ *       response       OCTET STRING }
+ */
+typedef struct ocsp_resp_bytes_st
+	{
+	ASN1_OBJECT *responseType;
+	ASN1_OCTET_STRING *response;
+	} OCSP_RESPBYTES;
+
+/*   OCSPResponse ::= SEQUENCE {
+ *      responseStatus         OCSPResponseStatus,
+ *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+ */
+typedef struct ocsp_response_st
+	{
+	ASN1_ENUMERATED *responseStatus;
+	OCSP_RESPBYTES  *responseBytes;
+	} OCSP_RESPONSE;
+
+/*   ResponderID ::= CHOICE {
+ *      byName   [1] Name,
+ *      byKey    [2] KeyHash }
+ */
+#define V_OCSP_RESPID_NAME 0
+#define V_OCSP_RESPID_KEY  1
+typedef struct ocsp_responder_id_st
+	{
+	int type;
+	union   {
+		X509_NAME* byName;
+        	ASN1_OCTET_STRING *byKey;
+		} value;
+	} OCSP_RESPID;
+/*   KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ *                            --(excluding the tag and length fields)
+ */
+
+/*   RevokedInfo ::= SEQUENCE {
+ *       revocationTime              GeneralizedTime,
+ *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+ */
+typedef struct ocsp_revoked_info_st
+	{
+	ASN1_GENERALIZEDTIME *revocationTime;
+	ASN1_ENUMERATED *revocationReason;
+	} OCSP_REVOKEDINFO;
+
+/*   CertStatus ::= CHOICE {
+ *       good                [0]     IMPLICIT NULL,
+ *       revoked             [1]     IMPLICIT RevokedInfo,
+ *       unknown             [2]     IMPLICIT UnknownInfo }
+ */
+#define V_OCSP_CERTSTATUS_GOOD    0
+#define V_OCSP_CERTSTATUS_REVOKED 1
+#define V_OCSP_CERTSTATUS_UNKNOWN 2
+typedef struct ocsp_cert_status_st
+	{
+	int type;
+	union	{
+		ASN1_NULL *good;
+		OCSP_REVOKEDINFO *revoked;
+		ASN1_NULL *unknown;
+		} value;
+	} OCSP_CERTSTATUS;
+
+/*   SingleResponse ::= SEQUENCE {
+ *      certID                       CertID,
+ *      certStatus                   CertStatus,
+ *      thisUpdate                   GeneralizedTime,
+ *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+ *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_single_response_st
+	{
+	OCSP_CERTID *certId;
+	OCSP_CERTSTATUS *certStatus;
+	ASN1_GENERALIZEDTIME *thisUpdate;
+	ASN1_GENERALIZEDTIME *nextUpdate;
+	STACK_OF(X509_EXTENSION) *singleExtensions;
+	} OCSP_SINGLERESP;
+
+DECLARE_STACK_OF(OCSP_SINGLERESP)
+DECLARE_ASN1_SET_OF(OCSP_SINGLERESP)
+
+/*   ResponseData ::= SEQUENCE {
+ *      version              [0] EXPLICIT Version DEFAULT v1,
+ *      responderID              ResponderID,
+ *      producedAt               GeneralizedTime,
+ *      responses                SEQUENCE OF SingleResponse,
+ *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_response_data_st
+	{
+	ASN1_INTEGER *version;
+	OCSP_RESPID  *responderId;
+	ASN1_GENERALIZEDTIME *producedAt;
+	STACK_OF(OCSP_SINGLERESP) *responses;
+	STACK_OF(X509_EXTENSION) *responseExtensions;
+	} OCSP_RESPDATA;
+
+/*   BasicOCSPResponse       ::= SEQUENCE {
+ *      tbsResponseData      ResponseData,
+ *      signatureAlgorithm   AlgorithmIdentifier,
+ *      signature            BIT STRING,
+ *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+  /* Note 1:
+     The value for "signature" is specified in the OCSP rfc2560 as follows:
+     "The value for the signature SHALL be computed on the hash of the DER
+     encoding ResponseData."  This means that you must hash the DER-encoded
+     tbsResponseData, and then run it through a crypto-signing function, which
+     will (at least w/RSA) do a hash-'n'-private-encrypt operation.  This seems
+     a bit odd, but that's the spec.  Also note that the data structures do not
+     leave anywhere to independently specify the algorithm used for the initial
+     hash. So, we look at the signature-specification algorithm, and try to do
+     something intelligent.	-- Kathy Weinhold, CertCo */
+  /* Note 2:
+     It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open
+     for interpretation.  I've done tests against another responder, and found
+     that it doesn't do the double hashing that the RFC seems to say one
+     should.  Therefore, all relevant functions take a flag saying which
+     variant should be used.	-- Richard Levitte, OpenSSL team and CeloCom */
+typedef struct ocsp_basic_response_st
+	{
+	OCSP_RESPDATA *tbsResponseData;
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+	} OCSP_BASICRESP;
+
+/*
+ *   CRLReason ::= ENUMERATED {
+ *        unspecified             (0),
+ *        keyCompromise           (1),
+ *        cACompromise            (2),
+ *        affiliationChanged      (3),
+ *        superseded              (4),
+ *        cessationOfOperation    (5),
+ *        certificateHold         (6),
+ *        removeFromCRL           (8) }
+ */
+#define OCSP_REVOKED_STATUS_NOSTATUS               -1
+#define OCSP_REVOKED_STATUS_UNSPECIFIED             0
+#define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
+#define OCSP_REVOKED_STATUS_CACOMPROMISE            2
+#define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
+#define OCSP_REVOKED_STATUS_SUPERSEDED              4
+#define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
+#define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
+#define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8
+
+/* CrlID ::= SEQUENCE {
+ *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
+ *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
+ *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
+ */
+typedef struct ocsp_crl_id_st
+        {
+	ASN1_IA5STRING *crlUrl;
+	ASN1_INTEGER *crlNum;
+	ASN1_GENERALIZEDTIME *crlTime;
+        } OCSP_CRLID;
+
+/* ServiceLocator ::= SEQUENCE {
+ *      issuer    Name,
+ *      locator   AuthorityInfoAccessSyntax OPTIONAL }
+ */
+typedef struct ocsp_service_locator_st
+        {
+	X509_NAME* issuer;
+	STACK_OF(ACCESS_DESCRIPTION) *locator;
+        } OCSP_SERVICELOC;
+ 
+#define PEM_STRING_OCSP_REQUEST	"OCSP REQUEST"
+#define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"
+
+#define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)
+
+#define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)
+
+#define	PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
+     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)
+
+#define	PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
+     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)
+
+#define PEM_write_bio_OCSP_REQUEST(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
+			bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_bio_OCSP_RESPONSE(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
+			bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)
+
+#define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)
+
+#define OCSP_REQUEST_sign(o,pkey,md) \
+	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
+		o->optionalSignature->signatureAlgorithm,NULL,\
+	        o->optionalSignature->signature,o->tbsRequest,pkey,md)
+
+#define OCSP_BASICRESP_sign(o,pkey,md,d) \
+	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\
+		o->signature,o->tbsResponseData,pkey,md)
+
+#define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
+        a->optionalSignature->signatureAlgorithm,\
+	a->optionalSignature->signature,a->tbsRequest,r)
+
+#define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
+	a->signatureAlgorithm,a->signature,a->tbsResponseData,r)
+
+#define ASN1_BIT_STRING_digest(data,type,md,len) \
+	ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
+
+#define OCSP_CERTID_dup(cid) ASN1_dup_of(OCSP_CERTID,i2d_OCSP_CERTID,d2i_OCSP_CERTID,cid)
+
+#define OCSP_CERTSTATUS_dup(cs)\
+                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
+		(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 
+			      X509_NAME *issuerName, 
+			      ASN1_BIT_STRING* issuerKey, 
+			      ASN1_INTEGER *serialNumber);
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
+
+int OCSP_request_sign(OCSP_REQUEST   *req,
+		      X509           *signer,
+		      EVP_PKEY       *key,
+		      const EVP_MD   *dgst,
+		      STACK_OF(X509) *certs,
+		      unsigned long flags);
+
+int OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
+
+int OCSP_resp_count(OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+				int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+			ASN1_GENERALIZEDTIME *nextupd,
+			long sec, long maxsec);
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags);
+
+int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl);
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req);
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+			ASN1_OCTET_STRING **pikeyHash,
+			ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+int OCSP_request_is_signed(OCSP_REQUEST *req);
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+						OCSP_CERTID *cid,
+						int status, int reason,
+						ASN1_TIME *revtime,
+					ASN1_TIME *thisupd, ASN1_TIME *nextupd);
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
+int OCSP_basic_sign(OCSP_BASICRESP *brsp, 
+			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+			STACK_OF(X509) *certs, unsigned long flags);
+
+ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
+				void *data, STACK_OF(ASN1_OBJECT) *sk);
+#define ASN1_STRING_encode_of(type,s,i2d,data,sk) \
+((ASN1_STRING *(*)(ASN1_STRING *,I2D_OF(type),type *,STACK_OF(ASN1_OBJECT) *))openssl_fcast(ASN1_STRING_encode))(s,i2d,data,sk)
+
+X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
+
+X509_EXTENSION *OCSP_accept_responses_new(char **oids);
+
+X509_EXTENSION *OCSP_archive_cutoff_new(char* tim);
+
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls);
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx);
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx);
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx);
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);
+
+DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
+DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
+DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
+
+char *OCSP_response_status_str(long s);
+char *OCSP_cert_status_str(long s);
+char *OCSP_crl_reason_str(long s);
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OCSP_strings(void);
+
+/* Error codes for the OCSP functions. */
+
+/* Function codes. */
+#define OCSP_F_ASN1_STRING_ENCODE			 100
+#define OCSP_F_D2I_OCSP_NONCE				 102
+#define OCSP_F_OCSP_BASIC_ADD1_STATUS			 103
+#define OCSP_F_OCSP_BASIC_SIGN				 104
+#define OCSP_F_OCSP_BASIC_VERIFY			 105
+#define OCSP_F_OCSP_CERT_ID_NEW				 101
+#define OCSP_F_OCSP_CHECK_DELEGATED			 106
+#define OCSP_F_OCSP_CHECK_IDS				 107
+#define OCSP_F_OCSP_CHECK_ISSUER			 108
+#define OCSP_F_OCSP_CHECK_VALIDITY			 115
+#define OCSP_F_OCSP_MATCH_ISSUERID			 109
+#define OCSP_F_OCSP_PARSE_URL				 114
+#define OCSP_F_OCSP_REQUEST_SIGN			 110
+#define OCSP_F_OCSP_REQUEST_VERIFY			 116
+#define OCSP_F_OCSP_RESPONSE_GET1_BASIC			 111
+#define OCSP_F_OCSP_SENDREQ_BIO				 112
+#define OCSP_F_REQUEST_VERIFY				 113
+
+/* Reason codes. */
+#define OCSP_R_BAD_DATA					 100
+#define OCSP_R_CERTIFICATE_VERIFY_ERROR			 101
+#define OCSP_R_DIGEST_ERR				 102
+#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD		 122
+#define OCSP_R_ERROR_IN_THISUPDATE_FIELD		 123
+#define OCSP_R_ERROR_PARSING_URL			 121
+#define OCSP_R_MISSING_OCSPSIGNING_USAGE		 103
+#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE		 124
+#define OCSP_R_NOT_BASIC_RESPONSE			 104
+#define OCSP_R_NO_CERTIFICATES_IN_CHAIN			 105
+#define OCSP_R_NO_CONTENT				 106
+#define OCSP_R_NO_PUBLIC_KEY				 107
+#define OCSP_R_NO_RESPONSE_DATA				 108
+#define OCSP_R_NO_REVOKED_TIME				 109
+#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 110
+#define OCSP_R_REQUEST_NOT_SIGNED			 128
+#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA	 111
+#define OCSP_R_ROOT_CA_NOT_TRUSTED			 112
+#define OCSP_R_SERVER_READ_ERROR			 113
+#define OCSP_R_SERVER_RESPONSE_ERROR			 114
+#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR		 115
+#define OCSP_R_SERVER_WRITE_ERROR			 116
+#define OCSP_R_SIGNATURE_FAILURE			 117
+#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND		 118
+#define OCSP_R_STATUS_EXPIRED				 125
+#define OCSP_R_STATUS_NOT_YET_VALID			 126
+#define OCSP_R_STATUS_TOO_OLD				 127
+#define OCSP_R_UNKNOWN_MESSAGE_DIGEST			 119
+#define OCSP_R_UNKNOWN_NID				 120
+#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE		 129
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/opensslconf.h b/dep/include/openssl/opensslconf.h
new file mode 100644
index 000000000..4620e0e53
--- /dev/null
+++ b/dep/include/openssl/opensslconf.h
@@ -0,0 +1,214 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD 
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned int
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#undef RC4_CHUNK
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned long
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#undef BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#undef BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#undef DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman 
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/dep/include/openssl/opensslv.h b/dep/include/openssl/opensslv.h
new file mode 100644
index 000000000..8a5b34e4f
--- /dev/null
+++ b/dep/include/openssl/opensslv.h
@@ -0,0 +1,89 @@
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev	  0x00903000
+ * 0.9.3-beta1	  0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3	  0x0090300f
+ * 0.9.3a	  0x0090301f
+ * 0.9.4	  0x0090400f
+ * 1.2.3z	  0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+#define OPENSSL_VERSION_NUMBER	0x0090805fL
+#ifdef OPENSSL_FIPS
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8e-fips 23 Feb 2007"
+#else
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8e 23 Feb 2007"
+#endif
+#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
+
+
+/* The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning.  That kind of versioning works a bit differently between
+ * operating systems.  The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time.  With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ *	libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ *	libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons.  The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time.  When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired.  However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string.  Consecutive builds would
+ * give the following versions strings:
+ *
+ *	3.0
+ *	3.0:3.1
+ *	3.0:3.1:3.2
+ *	4.0
+ *	4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+#define SHLIB_VERSION_HISTORY ""
+#define SHLIB_VERSION_NUMBER "0.9.8"
+
+
+#endif /* HEADER_OPENSSLV_H */
diff --git a/dep/include/openssl/ossl_typ.h b/dep/include/openssl/ossl_typ.h
new file mode 100644
index 000000000..9c335a181
--- /dev/null
+++ b/dep/include/openssl/ossl_typ.h
@@ -0,0 +1,174 @@
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_OPENSSL_TYPES_H
+#define HEADER_OPENSSL_TYPES_H
+
+#include 
+
+#ifdef NO_ASN1_TYPEDEFS
+#define ASN1_INTEGER		ASN1_STRING
+#define ASN1_ENUMERATED		ASN1_STRING
+#define ASN1_BIT_STRING		ASN1_STRING
+#define ASN1_OCTET_STRING	ASN1_STRING
+#define ASN1_PRINTABLESTRING	ASN1_STRING
+#define ASN1_T61STRING		ASN1_STRING
+#define ASN1_IA5STRING		ASN1_STRING
+#define ASN1_UTCTIME		ASN1_STRING
+#define ASN1_GENERALIZEDTIME	ASN1_STRING
+#define ASN1_TIME		ASN1_STRING
+#define ASN1_GENERALSTRING	ASN1_STRING
+#define ASN1_UNIVERSALSTRING	ASN1_STRING
+#define ASN1_BMPSTRING		ASN1_STRING
+#define ASN1_VISIBLESTRING	ASN1_STRING
+#define ASN1_UTF8STRING		ASN1_STRING
+#define ASN1_BOOLEAN		int
+#define ASN1_NULL		int
+#else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+#undef X509_NAME
+#undef X509_CERT_PAIR
+#undef PKCS7_ISSUER_AND_SERIAL
+#endif
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+typedef struct bignum_st BIGNUM;
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+
+typedef struct buf_mem_st BUF_MEM;
+
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+typedef struct dh_st DH;
+typedef struct dh_method DH_METHOD;
+
+typedef struct dsa_st DSA;
+typedef struct dsa_method DSA_METHOD;
+
+typedef struct rsa_st RSA;
+typedef struct rsa_meth_st RSA_METHOD;
+
+typedef struct rand_meth_st RAND_METHOD;
+
+typedef struct ecdh_method ECDH_METHOD;
+typedef struct ecdsa_method ECDSA_METHOD;
+
+typedef struct x509_st X509;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct X509_name_st X509_NAME;
+typedef struct x509_store_st X509_STORE;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct conf_st CONF;
+
+typedef struct store_st STORE;
+typedef struct store_method_st STORE_METHOD;
+
+typedef struct ui_st UI;
+typedef struct ui_method_st UI_METHOD;
+
+typedef struct st_ERR_FNS ERR_FNS;
+
+typedef struct engine_st ENGINE;
+
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+
+  /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
+#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
+#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
+
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Callback types for crypto.h */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+
+#endif /* def HEADER_OPENSSL_TYPES_H */
diff --git a/dep/include/openssl/pem.h b/dep/include/openssl/pem.h
new file mode 100644
index 000000000..c28706ddc
--- /dev/null
+++ b/dep/include/openssl/pem.h
@@ -0,0 +1,737 @@
+/* crypto/pem/pem.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PEM_H
+#define HEADER_PEM_H
+
+#include 
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#ifndef OPENSSL_NO_STACK
+#include 
+#endif
+#include 
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define PEM_BUFSIZE		1024
+
+#define PEM_OBJ_UNDEF		0
+#define PEM_OBJ_X509		1
+#define PEM_OBJ_X509_REQ	2
+#define PEM_OBJ_CRL		3
+#define PEM_OBJ_SSL_SESSION	4
+#define PEM_OBJ_PRIV_KEY	10
+#define PEM_OBJ_PRIV_RSA	11
+#define PEM_OBJ_PRIV_DSA	12
+#define PEM_OBJ_PRIV_DH		13
+#define PEM_OBJ_PUB_RSA		14
+#define PEM_OBJ_PUB_DSA		15
+#define PEM_OBJ_PUB_DH		16
+#define PEM_OBJ_DHPARAMS	17
+#define PEM_OBJ_DSAPARAMS	18
+#define PEM_OBJ_PRIV_RSA_PUBLIC	19
+#define PEM_OBJ_PRIV_ECDSA	20
+#define PEM_OBJ_PUB_ECDSA	21
+#define PEM_OBJ_ECPARAMETERS	22
+
+#define PEM_ERROR		30
+#define PEM_DEK_DES_CBC         40
+#define PEM_DEK_IDEA_CBC        45
+#define PEM_DEK_DES_EDE         50
+#define PEM_DEK_DES_ECB         60
+#define PEM_DEK_RSA             70
+#define PEM_DEK_RSA_MD2         80
+#define PEM_DEK_RSA_MD5         90
+
+#define PEM_MD_MD2		NID_md2
+#define PEM_MD_MD5		NID_md5
+#define PEM_MD_SHA		NID_sha
+#define PEM_MD_MD2_RSA		NID_md2WithRSAEncryption
+#define PEM_MD_MD5_RSA		NID_md5WithRSAEncryption
+#define PEM_MD_SHA_RSA		NID_sha1WithRSAEncryption
+
+#define PEM_STRING_X509_OLD	"X509 CERTIFICATE"
+#define PEM_STRING_X509		"CERTIFICATE"
+#define PEM_STRING_X509_PAIR	"CERTIFICATE PAIR"
+#define PEM_STRING_X509_TRUSTED	"TRUSTED CERTIFICATE"
+#define PEM_STRING_X509_REQ_OLD	"NEW CERTIFICATE REQUEST"
+#define PEM_STRING_X509_REQ	"CERTIFICATE REQUEST"
+#define PEM_STRING_X509_CRL	"X509 CRL"
+#define PEM_STRING_EVP_PKEY	"ANY PRIVATE KEY"
+#define PEM_STRING_PUBLIC	"PUBLIC KEY"
+#define PEM_STRING_RSA		"RSA PRIVATE KEY"
+#define PEM_STRING_RSA_PUBLIC	"RSA PUBLIC KEY"
+#define PEM_STRING_DSA		"DSA PRIVATE KEY"
+#define PEM_STRING_DSA_PUBLIC	"DSA PUBLIC KEY"
+#define PEM_STRING_PKCS7	"PKCS7"
+#define PEM_STRING_PKCS8	"ENCRYPTED PRIVATE KEY"
+#define PEM_STRING_PKCS8INF	"PRIVATE KEY"
+#define PEM_STRING_DHPARAMS	"DH PARAMETERS"
+#define PEM_STRING_SSL_SESSION	"SSL SESSION PARAMETERS"
+#define PEM_STRING_DSAPARAMS	"DSA PARAMETERS"
+#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
+#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
+#define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
+
+  /* Note that this structure is initialised by PEM_SealInit and cleaned up
+     by PEM_SealFinal (at least for now) */
+typedef struct PEM_Encode_Seal_st
+	{
+	EVP_ENCODE_CTX encode;
+	EVP_MD_CTX md;
+	EVP_CIPHER_CTX cipher;
+	} PEM_ENCODE_SEAL_CTX;
+
+/* enc_type is one off */
+#define PEM_TYPE_ENCRYPTED      10
+#define PEM_TYPE_MIC_ONLY       20
+#define PEM_TYPE_MIC_CLEAR      30
+#define PEM_TYPE_CLEAR		40
+
+typedef struct pem_recip_st
+	{
+	char *name;
+	X509_NAME *dn;
+
+	int cipher;
+	int key_enc;
+	/*	char iv[8]; unused and wrong size */
+	} PEM_USER;
+
+typedef struct pem_ctx_st
+	{
+	int type;		/* what type of object */
+
+	struct	{
+		int version;	
+		int mode;		
+		} proc_type;
+
+	char *domain;
+
+	struct	{
+		int cipher;
+	/* unused, and wrong size
+	   unsigned char iv[8]; */
+		} DEK_info;
+		
+	PEM_USER *originator;
+
+	int num_recipient;
+	PEM_USER **recipient;
+
+#ifndef OPENSSL_NO_STACK
+	STACK *x509_chain;	/* certificate chain */
+#else
+	char *x509_chain;	/* certificate chain */
+#endif
+	EVP_MD *md;		/* signature type */
+
+	int md_enc;		/* is the md encrypted or not? */
+	int md_len;		/* length of md_data */
+	char *md_data;		/* message digest, could be pkey encrypted */
+
+	EVP_CIPHER *dec;	/* date encryption cipher */
+	int key_len;		/* key length */
+	unsigned char *key;	/* key */
+	/* unused, and wrong size
+	   unsigned char iv[8]; */
+
+	
+	int  data_enc;		/* is the data encrypted */
+	int data_len;
+	unsigned char *data;
+	} PEM_CTX;
+
+/* These macros make the PEM_read/PEM_write functions easier to maintain and
+ * write. Now they are all implemented with either:
+ * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...)
+ */
+
+#ifdef OPENSSL_NO_FP_API
+
+#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
+
+#else
+
+#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
+type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return(((type *(*)(D2I_OF(type),char *,FILE *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read))(d2i_##asn1, str,fp,x,cb,u)); \
+} 
+
+#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x) \
+{ \
+return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, const type *x) \
+{ \
+return(((int (*)(I2D_OF_const(type),const char *,FILE *, const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, \
+		  void *u) \
+	{ \
+	return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, \
+		  void *u) \
+	{ \
+	return(((int (*)(I2D_OF_const(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#endif
+
+#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return(((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i_##asn1, str,bp,x,cb,u)); \
+}
+
+#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x) \
+{ \
+return(((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, const type *x) \
+{ \
+return(((int (*)(I2D_OF_const(type),const char *,BIO *,const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+	{ \
+	return(((int (*)(I2D_OF(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+	{ \
+	return(((int (*)(I2D_OF_const(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#define IMPLEMENT_PEM_write(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_read_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_rw(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write(name, type, str, asn1)
+
+#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_const(name, type, str, asn1)
+
+#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb(name, type, str, asn1)
+
+/* These are the same except they are for the declarations */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_NO_FP_API)
+
+#define DECLARE_PEM_read_fp(name, type) /**/
+#define DECLARE_PEM_write_fp(name, type) /**/
+#define DECLARE_PEM_write_cb_fp(name, type) /**/
+
+#else
+
+#define DECLARE_PEM_read_fp(name, type) \
+	type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
+
+#define DECLARE_PEM_write_fp(name, type) \
+	int PEM_write_##name(FILE *fp, type *x);
+
+#define DECLARE_PEM_write_fp_const(name, type) \
+	int PEM_write_##name(FILE *fp, const type *x);
+
+#define DECLARE_PEM_write_cb_fp(name, type) \
+	int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#define DECLARE_PEM_read_bio(name, type) \
+	type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
+
+#define DECLARE_PEM_write_bio(name, type) \
+	int PEM_write_bio_##name(BIO *bp, type *x);
+
+#define DECLARE_PEM_write_bio_const(name, type) \
+	int PEM_write_bio_##name(BIO *bp, const type *x);
+
+#define DECLARE_PEM_write_cb_bio(name, type) \
+	int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#else
+
+#define DECLARE_PEM_read_bio(name, type) /**/
+#define DECLARE_PEM_write_bio(name, type) /**/
+#define DECLARE_PEM_write_cb_bio(name, type) /**/
+
+#endif
+
+#define DECLARE_PEM_write(name, type) \
+	DECLARE_PEM_write_bio(name, type) \
+	DECLARE_PEM_write_fp(name, type) 
+
+#define DECLARE_PEM_write_const(name, type) \
+	DECLARE_PEM_write_bio_const(name, type) \
+	DECLARE_PEM_write_fp_const(name, type)
+
+#define DECLARE_PEM_write_cb(name, type) \
+	DECLARE_PEM_write_cb_bio(name, type) \
+	DECLARE_PEM_write_cb_fp(name, type) 
+
+#define DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_read_bio(name, type) \
+	DECLARE_PEM_read_fp(name, type)
+
+#define DECLARE_PEM_rw(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write(name, type)
+
+#define DECLARE_PEM_rw_const(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write_const(name, type)
+
+#define DECLARE_PEM_rw_cb(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write_cb(name, type)
+
+#ifdef SSLEAY_MACROS
+
+#define PEM_write_SSL_SESSION(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
+			PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_X509(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_X509_REQ(fp,x) PEM_ASN1_write( \
+		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,fp,(char *)x, \
+			NULL,NULL,0,NULL,NULL)
+#define PEM_write_X509_CRL(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL, \
+			fp,(char *)x, NULL,NULL,0,NULL,NULL)
+#define	PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,\
+			(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_RSAPublicKey(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_RSAPublicKey,\
+			PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL,NULL)
+#define	PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,\
+			(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write((int (*)())i2d_PrivateKey,\
+		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define PEM_write_PKCS7(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_DHparams(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,\
+			(char *)x,NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_NETSCAPE_CERT_SEQUENCE(fp,x) \
+                PEM_ASN1_write((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
+			PEM_STRING_X509,fp, \
+                        (char *)x, NULL,NULL,0,NULL,NULL)
+
+#define	PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
+	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
+#define	PEM_read_X509(fp,x,cb,u) (X509 *)PEM_ASN1_read( \
+	(char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb,u)
+#define	PEM_read_X509_REQ(fp,x,cb,u) (X509_REQ *)PEM_ASN1_read( \
+	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,fp,(char **)x,cb,u)
+#define	PEM_read_X509_CRL(fp,x,cb,u) (X509_CRL *)PEM_ASN1_read( \
+	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,fp,(char **)x,cb,u)
+#define	PEM_read_RSAPrivateKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
+	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char **)x,cb,u)
+#define	PEM_read_RSAPublicKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
+	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char **)x,cb,u)
+#define	PEM_read_DSAPrivateKey(fp,x,cb,u) (DSA *)PEM_ASN1_read( \
+	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,(char **)x,cb,u)
+#define	PEM_read_PrivateKey(fp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read( \
+	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,fp,(char **)x,cb,u)
+#define	PEM_read_PKCS7(fp,x,cb,u) (PKCS7 *)PEM_ASN1_read( \
+	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,(char **)x,cb,u)
+#define	PEM_read_DHparams(fp,x,cb,u) (DH *)PEM_ASN1_read( \
+	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,(char **)x,cb,u)
+
+#define PEM_read_NETSCAPE_CERT_SEQUENCE(fp,x,cb,u) \
+		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read( \
+        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,fp,\
+							(char **)x,cb,u)
+
+#define PEM_write_bio_X509(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( \
+		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, \
+			NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_X509_CRL(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,\
+			bp,(char *)x, NULL,NULL,0,NULL,NULL)
+#define	PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_bio_RSAPublicKey(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, \
+			PEM_STRING_RSA_PUBLIC,\
+			bp,(char *)x,NULL,NULL,0,NULL,NULL)
+#define	PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,\
+		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define PEM_write_bio_PKCS7(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_DHparams(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,\
+			bp,(char *)x,NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_DSAparams(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_DSAparams, \
+			PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp,x) \
+                PEM_ASN1_write_bio((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
+			PEM_STRING_X509,bp, \
+                        (char *)x, NULL,NULL,0,NULL,NULL)
+
+#define	PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u)
+#define	PEM_read_bio_X509_REQ(bp,x,cb,u) (X509_REQ *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,bp,(char **)x,cb,u)
+#define	PEM_read_bio_X509_CRL(bp,x,cb,u) (X509_CRL *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,bp,(char **)x,cb,u)
+#define	PEM_read_bio_RSAPrivateKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char **)x,cb,u)
+#define	PEM_read_bio_RSAPublicKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb,u)
+#define	PEM_read_bio_DSAPrivateKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,bp,(char **)x,cb,u)
+#define	PEM_read_bio_PrivateKey(bp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,bp,(char **)x,cb,u)
+
+#define	PEM_read_bio_PKCS7(bp,x,cb,u) (PKCS7 *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,bp,(char **)x,cb,u)
+#define	PEM_read_bio_DHparams(bp,x,cb,u) (DH *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,bp,(char **)x,cb,u)
+#define	PEM_read_bio_DSAparams(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,bp,(char **)x,cb,u)
+
+#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp,x,cb,u) \
+		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read_bio( \
+        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,bp,\
+							(char **)x,cb,u)
+
+#endif
+
+#if 1
+/* "userdata": new with OpenSSL 0.9.4 */
+typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
+#else
+/* OpenSSL 0.9.3, 0.9.3a */
+typedef int pem_password_cb(char *buf, int size, int rwflag);
+#endif
+
+int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
+int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
+	pem_password_cb *callback,void *u);
+
+#ifndef OPENSSL_NO_BIO
+int	PEM_read_bio(BIO *bp, char **name, char **header,
+		unsigned char **data,long *len);
+int	PEM_write_bio(BIO *bp,const char *name,char *hdr,unsigned char *data,
+		long len);
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
+	     pem_password_cb *cb, void *u);
+void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
+			  void **x, pem_password_cb *cb, void *u);
+#define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \
+((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i,name,bp,x,cb,u)
+int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x,
+			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
+			   pem_password_cb *cb, void *u);
+#define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \
+	((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d,name,bp,x,enc,kstr,klen,cb,u)
+
+STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
+int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
+		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
+#endif
+
+#ifndef OPENSSL_SYS_WIN16
+int	PEM_read(FILE *fp, char **name, char **header,
+		unsigned char **data,long *len);
+int	PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
+void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+		      pem_password_cb *cb, void *u);
+int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
+		       char *x,const EVP_CIPHER *enc,unsigned char *kstr,
+		       int klen,pem_password_cb *callback, void *u);
+STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+	pem_password_cb *cb, void *u);
+#endif
+
+int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
+		EVP_MD *md_type, unsigned char **ek, int *ekl,
+		unsigned char *iv, EVP_PKEY **pubk, int npubk);
+void	PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+		unsigned char *in, int inl);
+int	PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl,
+		unsigned char *out, int *outl, EVP_PKEY *priv);
+
+void    PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
+void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
+int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+		unsigned int *siglen, EVP_PKEY *pkey);
+
+int	PEM_def_callback(char *buf, int num, int w, void *key);
+void	PEM_proc_type(char *buf, int type);
+void	PEM_dek_info(char *buf, const char *type, int len, char *str);
+
+#ifndef SSLEAY_MACROS
+
+#include 
+
+DECLARE_PEM_rw(X509, X509)
+
+DECLARE_PEM_rw(X509_AUX, X509)
+
+DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
+
+DECLARE_PEM_rw(X509_REQ, X509_REQ)
+DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
+
+DECLARE_PEM_rw(X509_CRL, X509_CRL)
+
+DECLARE_PEM_rw(PKCS7, PKCS7)
+
+DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+DECLARE_PEM_rw(PKCS8, X509_SIG)
+
+DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+
+#ifndef OPENSSL_NO_RSA
+
+DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
+
+DECLARE_PEM_rw_const(RSAPublicKey, RSA)
+DECLARE_PEM_rw(RSA_PUBKEY, RSA)
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+
+DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
+
+DECLARE_PEM_rw(DSA_PUBKEY, DSA)
+
+DECLARE_PEM_rw_const(DSAparams, DSA)
+
+#endif
+
+#ifndef OPENSSL_NO_EC
+DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
+DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
+DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+DECLARE_PEM_rw_const(DHparams, DH)
+
+#endif
+
+DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
+
+DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+                                  char *, int, pem_password_cb *, void *);
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
+			      char *kstr,int klen, pem_password_cb *cd, void *u);
+
+#endif /* SSLEAY_MACROS */
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PEM_strings(void);
+
+/* Error codes for the PEM functions. */
+
+/* Function codes. */
+#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO			 120
+#define PEM_F_D2I_PKCS8PRIVATEKEY_FP			 121
+#define PEM_F_DO_PK8PKEY				 126
+#define PEM_F_DO_PK8PKEY_FP				 125
+#define PEM_F_LOAD_IV					 101
+#define PEM_F_PEM_ASN1_READ				 102
+#define PEM_F_PEM_ASN1_READ_BIO				 103
+#define PEM_F_PEM_ASN1_WRITE				 104
+#define PEM_F_PEM_ASN1_WRITE_BIO			 105
+#define PEM_F_PEM_DEF_CALLBACK				 100
+#define PEM_F_PEM_DO_HEADER				 106
+#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY		 118
+#define PEM_F_PEM_GET_EVP_CIPHER_INFO			 107
+#define PEM_F_PEM_PK8PKEY				 119
+#define PEM_F_PEM_READ					 108
+#define PEM_F_PEM_READ_BIO				 109
+#define PEM_F_PEM_READ_BIO_PRIVATEKEY			 123
+#define PEM_F_PEM_READ_PRIVATEKEY			 124
+#define PEM_F_PEM_SEALFINAL				 110
+#define PEM_F_PEM_SEALINIT				 111
+#define PEM_F_PEM_SIGNFINAL				 112
+#define PEM_F_PEM_WRITE					 113
+#define PEM_F_PEM_WRITE_BIO				 114
+#define PEM_F_PEM_X509_INFO_READ			 115
+#define PEM_F_PEM_X509_INFO_READ_BIO			 116
+#define PEM_F_PEM_X509_INFO_WRITE_BIO			 117
+
+/* Reason codes. */
+#define PEM_R_BAD_BASE64_DECODE				 100
+#define PEM_R_BAD_DECRYPT				 101
+#define PEM_R_BAD_END_LINE				 102
+#define PEM_R_BAD_IV_CHARS				 103
+#define PEM_R_BAD_PASSWORD_READ				 104
+#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY		 115
+#define PEM_R_NOT_DEK_INFO				 105
+#define PEM_R_NOT_ENCRYPTED				 106
+#define PEM_R_NOT_PROC_TYPE				 107
+#define PEM_R_NO_START_LINE				 108
+#define PEM_R_PROBLEMS_GETTING_PASSWORD			 109
+#define PEM_R_PUBLIC_KEY_NO_RSA				 110
+#define PEM_R_READ_KEY					 111
+#define PEM_R_SHORT_HEADER				 112
+#define PEM_R_UNSUPPORTED_CIPHER			 113
+#define PEM_R_UNSUPPORTED_ENCRYPTION			 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/pem2.h b/dep/include/openssl/pem2.h
new file mode 100644
index 000000000..f31790d69
--- /dev/null
+++ b/dep/include/openssl/pem2.h
@@ -0,0 +1,70 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * This header only exists to break a circular dependency between pem and err
+ * Ben 30 Jan 1999.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HEADER_PEM_H
+void ERR_load_PEM_strings(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/dep/include/openssl/pkcs12.h b/dep/include/openssl/pkcs12.h
new file mode 100644
index 000000000..a2d7e359a
--- /dev/null
+++ b/dep/include/openssl/pkcs12.h
@@ -0,0 +1,333 @@
+/* pkcs12.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PKCS12_H
+#define HEADER_PKCS12_H
+
+#include 
+#include 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PKCS12_KEY_ID	1
+#define PKCS12_IV_ID	2
+#define PKCS12_MAC_ID	3
+
+/* Default iteration count */
+#ifndef PKCS12_DEFAULT_ITER
+#define PKCS12_DEFAULT_ITER	PKCS5_DEFAULT_ITER
+#endif
+
+#define PKCS12_MAC_KEY_LENGTH 20
+
+#define PKCS12_SALT_LEN	8
+
+/* Uncomment out next line for unicode password and names, otherwise ASCII */
+
+/*#define PBE_UNICODE*/
+
+#ifdef PBE_UNICODE
+#define PKCS12_key_gen PKCS12_key_gen_uni
+#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
+#else
+#define PKCS12_key_gen PKCS12_key_gen_asc
+#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
+#endif
+
+/* MS key usage constants */
+
+#define KEY_EX	0x10
+#define KEY_SIG 0x80
+
+typedef struct {
+X509_SIG *dinfo;
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;	/* defaults to 1 */
+} PKCS12_MAC_DATA;
+
+typedef struct {
+ASN1_INTEGER *version;
+PKCS12_MAC_DATA *mac;
+PKCS7 *authsafes;
+} PKCS12;
+
+PREDECLARE_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct {
+ASN1_OBJECT *type;
+union {
+	struct pkcs12_bag_st *bag; /* secret, crl and certbag */
+	struct pkcs8_priv_key_info_st	*keybag; /* keybag */
+	X509_SIG *shkeybag; /* shrouded key bag */
+	STACK_OF(PKCS12_SAFEBAG) *safes;
+	ASN1_TYPE *other;
+}value;
+STACK_OF(X509_ATTRIBUTE) *attrib;
+} PKCS12_SAFEBAG;
+
+DECLARE_STACK_OF(PKCS12_SAFEBAG)
+DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
+DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct pkcs12_bag_st {
+ASN1_OBJECT *type;
+union {
+	ASN1_OCTET_STRING *x509cert;
+	ASN1_OCTET_STRING *x509crl;
+	ASN1_OCTET_STRING *octet;
+	ASN1_IA5STRING *sdsicert;
+	ASN1_TYPE *other; /* Secret or other bag */
+}value;
+} PKCS12_BAGS;
+
+#define PKCS12_ERROR	0
+#define PKCS12_OK	1
+
+/* Compatibility macros */
+
+#define M_PKCS12_x5092certbag PKCS12_x5092certbag
+#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag
+
+#define M_PKCS12_certbag2x509 PKCS12_certbag2x509
+#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl 
+
+#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
+#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
+#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
+#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata
+
+#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
+#define M_PKCS8_decrypt PKCS8_decrypt
+
+#define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
+#define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
+#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type
+
+#define PKCS12_get_attr(bag, attr_nid) \
+			 PKCS12_get_attr_gen(bag->attrib, attr_nid)
+
+#define PKCS8_get_attr(p8, attr_nid) \
+		PKCS12_get_attr_gen(p8->attributes, attr_nid)
+
+#define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)
+
+
+PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
+PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
+X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
+X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
+	     int nid2);
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen);
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
+								int passlen);
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, 
+			const char *pass, int passlen,
+			unsigned char *salt, int saltlen, int iter,
+			PKCS8_PRIV_KEY_INFO *p8);
+PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
+				     int passlen, unsigned char *salt,
+				     int saltlen, int iter,
+				     PKCS8_PRIV_KEY_INFO *p8);
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+			     unsigned char *salt, int saltlen, int iter,
+			     STACK_OF(PKCS12_SAFEBAG) *bags);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen);
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen);
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+				int namelen);
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
+				int namelen);
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name,
+				int namelen);
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
+ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
+unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
+				int passlen, unsigned char *in, int inlen,
+				unsigned char **data, int *datalen, int en_de);
+void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+	     const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf);
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
+				       const char *pass, int passlen,
+				       void *obj, int zbuf);
+PKCS12 *PKCS12_init(int mode);
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+		       int saltlen, int id, int iter, int n,
+		       unsigned char *out, const EVP_MD *md_type);
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type);
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md_type,
+			 int en_de);
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+			 unsigned char *mac, unsigned int *maclen);
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+		   unsigned char *salt, int saltlen, int iter,
+		   const EVP_MD *md_type);
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
+					 int saltlen, const EVP_MD *md_type);
+unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
+char *uni2asc(unsigned char *uni, int unilen);
+
+DECLARE_ASN1_FUNCTIONS(PKCS12)
+DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
+DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
+
+void PKCS12_PBE_add(void);
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+		 STACK_OF(X509) **ca);
+PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+			 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
+						 int mac_iter, int keytype);
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
+						int key_usage, int iter,
+						int key_nid, char *pass);
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+					int safe_nid, int iter, char *pass);
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PKCS12_strings(void);
+
+/* Error codes for the PKCS12 functions. */
+
+/* Function codes. */
+#define PKCS12_F_PARSE_BAG				 129
+#define PKCS12_F_PARSE_BAGS				 103
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME		 100
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC		 127
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI		 102
+#define PKCS12_F_PKCS12_ADD_LOCALKEYID			 104
+#define PKCS12_F_PKCS12_CREATE				 105
+#define PKCS12_F_PKCS12_GEN_MAC				 107
+#define PKCS12_F_PKCS12_INIT				 109
+#define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I		 106
+#define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT		 108
+#define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG		 117
+#define PKCS12_F_PKCS12_KEY_GEN_ASC			 110
+#define PKCS12_F_PKCS12_KEY_GEN_UNI			 111
+#define PKCS12_F_PKCS12_MAKE_KEYBAG			 112
+#define PKCS12_F_PKCS12_MAKE_SHKEYBAG			 113
+#define PKCS12_F_PKCS12_NEWPASS				 128
+#define PKCS12_F_PKCS12_PACK_P7DATA			 114
+#define PKCS12_F_PKCS12_PACK_P7ENCDATA			 115
+#define PKCS12_F_PKCS12_PARSE				 118
+#define PKCS12_F_PKCS12_PBE_CRYPT			 119
+#define PKCS12_F_PKCS12_PBE_KEYIVGEN			 120
+#define PKCS12_F_PKCS12_SETUP_MAC			 122
+#define PKCS12_F_PKCS12_SET_MAC				 123
+#define PKCS12_F_PKCS12_UNPACK_AUTHSAFES		 130
+#define PKCS12_F_PKCS12_UNPACK_P7DATA			 131
+#define PKCS12_F_PKCS12_VERIFY_MAC			 126
+#define PKCS12_F_PKCS8_ADD_KEYUSAGE			 124
+#define PKCS12_F_PKCS8_ENCRYPT				 125
+
+/* Reason codes. */
+#define PKCS12_R_CANT_PACK_STRUCTURE			 100
+#define PKCS12_R_CONTENT_TYPE_NOT_DATA			 121
+#define PKCS12_R_DECODE_ERROR				 101
+#define PKCS12_R_ENCODE_ERROR				 102
+#define PKCS12_R_ENCRYPT_ERROR				 103
+#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE	 120
+#define PKCS12_R_INVALID_NULL_ARGUMENT			 104
+#define PKCS12_R_INVALID_NULL_PKCS12_POINTER		 105
+#define PKCS12_R_IV_GEN_ERROR				 106
+#define PKCS12_R_KEY_GEN_ERROR				 107
+#define PKCS12_R_MAC_ABSENT				 108
+#define PKCS12_R_MAC_GENERATION_ERROR			 109
+#define PKCS12_R_MAC_SETUP_ERROR			 110
+#define PKCS12_R_MAC_STRING_SET_ERROR			 111
+#define PKCS12_R_MAC_VERIFY_ERROR			 112
+#define PKCS12_R_MAC_VERIFY_FAILURE			 113
+#define PKCS12_R_PARSE_ERROR				 114
+#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR		 115
+#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR		 116
+#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR			 117
+#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM		 118
+#define PKCS12_R_UNSUPPORTED_PKCS12_MODE		 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/pkcs7.h b/dep/include/openssl/pkcs7.h
new file mode 100644
index 000000000..cc092d262
--- /dev/null
+++ b/dep/include/openssl/pkcs7.h
@@ -0,0 +1,464 @@
+/* crypto/pkcs7/pkcs7.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PKCS7_H
+#define HEADER_PKCS7_H
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+/* Under Win32 thes are defined in wincrypt.h */
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#endif
+
+/*
+Encryption_ID		DES-CBC
+Digest_ID		MD5
+Digest_Encryption_ID	rsaEncryption
+Key_Encryption_ID	rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st
+	{
+	X509_NAME *issuer;
+	ASN1_INTEGER *serial;
+	} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st
+	{
+	ASN1_INTEGER 			*version;	/* version 1 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*digest_alg;
+	STACK_OF(X509_ATTRIBUTE)	*auth_attr;	/* [ 0 ] */
+	X509_ALGOR			*digest_enc_alg;
+	ASN1_OCTET_STRING		*enc_digest;
+	STACK_OF(X509_ATTRIBUTE)	*unauth_attr;	/* [ 1 ] */
+
+	/* The private key to sign with */
+	EVP_PKEY			*pkey;
+	} PKCS7_SIGNER_INFO;
+
+DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*key_enc_algor;
+	ASN1_OCTET_STRING		*enc_key;
+	X509				*cert; /* get the pub-key from this */
+	} PKCS7_RECIP_INFO;
+
+DECLARE_STACK_OF(PKCS7_RECIP_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	struct pkcs7_st			*contents;
+	} PKCS7_SIGNED;
+/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
+ * How about merging the two */
+
+typedef struct pkcs7_enc_content_st
+	{
+	ASN1_OBJECT			*content_type;
+	X509_ALGOR			*algorithm;
+	ASN1_OCTET_STRING		*enc_data;	/* [ 0 ] */
+	const EVP_CIPHER		*cipher;
+	} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	PKCS7_ENC_CONTENT		*enc_data;
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	X509_ALGOR			*md;		/* md used */
+	struct pkcs7_st 		*contents;
+	ASN1_OCTET_STRING		*digest;
+	} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st
+	{
+	/* The following is non NULL if it contains ASN1 encoding of
+	 * this structure */
+	unsigned char *asn1;
+	long length;
+
+#define PKCS7_S_HEADER	0
+#define PKCS7_S_BODY	1
+#define PKCS7_S_TAIL	2
+	int state; /* used during processing */
+
+	int detached;
+
+	ASN1_OBJECT *type;
+	/* content as defined by the type */
+	/* all encryption/message digests are applied to the 'contents',
+	 * leaving out the 'type' field. */
+	union	{
+		char *ptr;
+
+		/* NID_pkcs7_data */
+		ASN1_OCTET_STRING *data;
+
+		/* NID_pkcs7_signed */
+		PKCS7_SIGNED *sign;
+
+		/* NID_pkcs7_enveloped */
+		PKCS7_ENVELOPE *enveloped;
+
+		/* NID_pkcs7_signedAndEnveloped */
+		PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+
+		/* NID_pkcs7_digest */
+		PKCS7_DIGEST *digest;
+
+		/* NID_pkcs7_encrypted */
+		PKCS7_ENCRYPT *encrypted;
+
+		/* Anything else */
+		ASN1_TYPE *other;
+		} d;
+	} PKCS7;
+
+DECLARE_STACK_OF(PKCS7)
+DECLARE_ASN1_SET_OF(PKCS7)
+DECLARE_PKCS12_STACK_OF(PKCS7)
+
+#define PKCS7_OP_SET_DETACHED_SIGNATURE	1
+#define PKCS7_OP_GET_DETACHED_SIGNATURE	2
+
+#define PKCS7_get_signed_attributes(si)	((si)->auth_attr)
+#define PKCS7_get_attributes(si)	((si)->unauth_attr)
+
+#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+#define PKCS7_type_is_signedAndEnveloped(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+#define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+
+#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+
+#define PKCS7_set_detached(p,v) \
+		PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+#define PKCS7_get_detached(p) \
+		PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
+
+#ifdef SSLEAY_MACROS
+#ifndef PKCS7_ISSUER_AND_SERIAL_digest
+#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
+        ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
+	                (char *)data,md,len)
+#endif
+#endif
+
+/* S/MIME related flags */
+
+#define PKCS7_TEXT		0x1
+#define PKCS7_NOCERTS		0x2
+#define PKCS7_NOSIGS		0x4
+#define PKCS7_NOCHAIN		0x8
+#define PKCS7_NOINTERN		0x10
+#define PKCS7_NOVERIFY		0x20
+#define PKCS7_DETACHED		0x40
+#define PKCS7_BINARY		0x80
+#define PKCS7_NOATTR		0x100
+#define	PKCS7_NOSMIMECAP	0x200
+#define PKCS7_NOOLDMIMETYPE	0x400
+#define PKCS7_CRLFEOL		0x800
+#define PKCS7_STREAM		0x1000
+#define PKCS7_NOCRL		0x2000
+
+/* Flags: for compatibility with older code */
+
+#define SMIME_TEXT	PKCS7_TEXT
+#define SMIME_NOCERTS	PKCS7_NOCERTS
+#define SMIME_NOSIGS	PKCS7_NOSIGS
+#define SMIME_NOCHAIN	PKCS7_NOCHAIN
+#define SMIME_NOINTERN	PKCS7_NOINTERN
+#define SMIME_NOVERIFY	PKCS7_NOVERIFY
+#define SMIME_DETACHED	PKCS7_DETACHED
+#define SMIME_BINARY	PKCS7_BINARY
+#define SMIME_NOATTR	PKCS7_NOATTR
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+#ifndef SSLEAY_MACROS
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
+	unsigned char *md,unsigned int *len);
+#ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
+#endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
+#endif
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+DECLARE_ASN1_FUNCTIONS(PKCS7)
+
+DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
+DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
+
+DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+	const EVP_MD *dgst);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+	BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); 
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+	EVP_PKEY *pkey, const EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type,
+	void *data);
+int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+	void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+				STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
+
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+							BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+					BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+								int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+			      STACK_OF(X509_ALGOR) *cap);
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PKCS7_strings(void);
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+#define PKCS7_F_B64_READ_PKCS7				 120
+#define PKCS7_F_B64_WRITE_PKCS7				 121
+#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
+#define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
+#define PKCS7_F_PKCS7_ADD_CRL				 101
+#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
+#define PKCS7_F_PKCS7_ADD_SIGNER			 103
+#define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
+#define PKCS7_F_PKCS7_CTRL				 104
+#define PKCS7_F_PKCS7_DATADECODE			 112
+#define PKCS7_F_PKCS7_DATAFINAL				 128
+#define PKCS7_F_PKCS7_DATAINIT				 105
+#define PKCS7_F_PKCS7_DATASIGN				 106
+#define PKCS7_F_PKCS7_DATAVERIFY			 107
+#define PKCS7_F_PKCS7_DECRYPT				 114
+#define PKCS7_F_PKCS7_ENCRYPT				 115
+#define PKCS7_F_PKCS7_FIND_DIGEST			 127
+#define PKCS7_F_PKCS7_GET0_SIGNERS			 124
+#define PKCS7_F_PKCS7_SET_CIPHER			 108
+#define PKCS7_F_PKCS7_SET_CONTENT			 109
+#define PKCS7_F_PKCS7_SET_DIGEST			 126
+#define PKCS7_F_PKCS7_SET_TYPE				 110
+#define PKCS7_F_PKCS7_SIGN				 116
+#define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
+#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
+#define PKCS7_F_PKCS7_VERIFY				 117
+#define PKCS7_F_SMIME_READ_PKCS7			 122
+#define PKCS7_F_SMIME_TEXT				 123
+
+/* Reason codes. */
+#define PKCS7_R_CERTIFICATE_VERIFY_ERROR		 117
+#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
+#define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
+#define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
+#define PKCS7_R_DECODE_ERROR				 130
+#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
+#define PKCS7_R_DECRYPT_ERROR				 119
+#define PKCS7_R_DIGEST_FAILURE				 101
+#define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
+#define PKCS7_R_ERROR_SETTING_CIPHER			 121
+#define PKCS7_R_INVALID_MIME_TYPE			 131
+#define PKCS7_R_INVALID_NULL_POINTER			 143
+#define PKCS7_R_MIME_NO_CONTENT_TYPE			 132
+#define PKCS7_R_MIME_PARSE_ERROR			 133
+#define PKCS7_R_MIME_SIG_PARSE_ERROR			 134
+#define PKCS7_R_MISSING_CERIPEND_INFO			 103
+#define PKCS7_R_NO_CONTENT				 122
+#define PKCS7_R_NO_CONTENT_TYPE				 135
+#define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
+#define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
+#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
+#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY		 146
+#define PKCS7_R_NO_SIGNATURES_ON_DATA			 123
+#define PKCS7_R_NO_SIGNERS				 142
+#define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
+#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
+#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
+#define PKCS7_R_PKCS7_DATAFINAL				 126
+#define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
+#define PKCS7_R_PKCS7_DATASIGN				 145
+#define PKCS7_R_PKCS7_PARSE_ERROR			 139
+#define PKCS7_R_PKCS7_SIG_PARSE_ERROR			 140
+#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
+#define PKCS7_R_SIGNATURE_FAILURE			 105
+#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
+#define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
+#define PKCS7_R_SMIME_TEXT_ERROR			 129
+#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
+#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO			 107
+#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST		 108
+#define PKCS7_R_UNKNOWN_DIGEST_TYPE			 109
+#define PKCS7_R_UNKNOWN_OPERATION			 110
+#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE			 111
+#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE		 112
+#define PKCS7_R_WRONG_CONTENT_TYPE			 113
+#define PKCS7_R_WRONG_PKCS7_TYPE			 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/pq_compat.h b/dep/include/openssl/pq_compat.h
new file mode 100644
index 000000000..28c58a026
--- /dev/null
+++ b/dep/include/openssl/pq_compat.h
@@ -0,0 +1,147 @@
+/* crypto/pqueue/pqueue_compat.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "opensslconf.h"
+#include 
+
+/* 
+ * The purpose of this header file is for supporting 64-bit integer
+ * manipulation on 32-bit (and lower) machines.  Currently the only
+ * such environment is VMS, Utrix and those with smaller default integer
+ * sizes than 32 bits.  For all such environment, we fall back to using
+ * BIGNUM.  We may need to fine tune the conditions for systems that
+ * are incorrectly configured.
+ *
+ * The only clients of this code are (1) pqueue for priority, and
+ * (2) DTLS, for sequence number manipulation.
+ */
+
+#if (defined(THIRTY_TWO_BIT) && !defined(BN_LLONG)) || defined(SIXTEEN_BIT) || defined(EIGHT_BIT)
+
+#define PQ_64BIT_IS_INTEGER 0
+#define PQ_64BIT_IS_BIGNUM 1
+
+#define PQ_64BIT     BIGNUM
+#define PQ_64BIT_CTX BN_CTX
+
+#define pq_64bit_init(x)           BN_init(x)
+#define pq_64bit_free(x)           BN_free(x)
+
+#define pq_64bit_ctx_new(ctx)      BN_CTX_new()
+#define pq_64bit_ctx_free(x)       BN_CTX_free(x)
+
+#define pq_64bit_assign(x, y)      BN_copy(x, y)
+#define pq_64bit_assign_word(x, y) BN_set_word(x, y)
+#define pq_64bit_gt(x, y)          BN_ucmp(x, y) >= 1 ? 1 : 0
+#define pq_64bit_eq(x, y)          BN_ucmp(x, y) == 0 ? 1 : 0
+#define pq_64bit_add_word(x, w)    BN_add_word(x, w)
+#define pq_64bit_sub(r, x, y)      BN_sub(r, x, y)
+#define pq_64bit_sub_word(x, w)    BN_sub_word(x, w)
+#define pq_64bit_mod(r, x, n, ctx) BN_mod(r, x, n, ctx)
+
+#define pq_64bit_bin2num(bn, bytes, len)   BN_bin2bn(bytes, len, bn)
+#define pq_64bit_num2bin(bn, bytes)        BN_bn2bin(bn, bytes)
+#define pq_64bit_get_word(x)               BN_get_word(x)
+#define pq_64bit_is_bit_set(x, offset)     BN_is_bit_set(x, offset)
+#define pq_64bit_lshift(r, x, shift)       BN_lshift(r, x, shift)
+#define pq_64bit_set_bit(x, num)           BN_set_bit(x, num)
+#define pq_64bit_get_length(x)             BN_num_bits((x))
+
+#else
+
+#define PQ_64BIT_IS_INTEGER 1
+#define PQ_64BIT_IS_BIGNUM 0
+
+#if defined(SIXTY_FOUR_BIT)
+#define PQ_64BIT BN_ULONG
+#define PQ_64BIT_PRINT "%lld"
+#elif defined(SIXTY_FOUR_BIT_LONG)
+#define PQ_64BIT BN_ULONG
+#define PQ_64BIT_PRINT "%ld"
+#elif defined(THIRTY_TWO_BIT)
+#define PQ_64BIT BN_ULLONG
+#define PQ_64BIT_PRINT "%lld"
+#endif
+
+#define PQ_64BIT_CTX      void
+
+#define pq_64bit_init(x)
+#define pq_64bit_free(x)
+#define pq_64bit_ctx_new(ctx)        (ctx)
+#define pq_64bit_ctx_free(x)
+
+#define pq_64bit_assign(x, y)        (*(x) = *(y))
+#define pq_64bit_assign_word(x, y)   (*(x) = y)
+#define pq_64bit_gt(x, y)	         (*(x) > *(y))
+#define pq_64bit_eq(x, y)            (*(x) == *(y))
+#define pq_64bit_add_word(x, w)      (*(x) = (*(x) + (w)))
+#define pq_64bit_sub(r, x, y)        (*(r) = (*(x) - *(y)))
+#define pq_64bit_sub_word(x, w)      (*(x) = (*(x) - (w)))
+#define pq_64bit_mod(r, x, n, ctx)
+
+#define pq_64bit_bin2num(num, bytes, len) bytes_to_long_long(bytes, num)
+#define pq_64bit_num2bin(num, bytes)      long_long_to_bytes(num, bytes)
+#define pq_64bit_get_word(x)              *(x)
+#define pq_64bit_lshift(r, x, shift)      (*(r) = (*(x) << (shift)))
+#define pq_64bit_set_bit(x, num)          do { \
+                                              PQ_64BIT mask = 1; \
+                                              mask = mask << (num); \
+                                              *(x) |= mask; \
+                                          } while(0)
+#endif /* OPENSSL_SYS_VMS */
diff --git a/dep/include/openssl/pqueue.h b/dep/include/openssl/pqueue.h
new file mode 100644
index 000000000..02386d130
--- /dev/null
+++ b/dep/include/openssl/pqueue.h
@@ -0,0 +1,95 @@
+/* crypto/pqueue/pqueue.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PQUEUE_H
+#define HEADER_PQUEUE_H
+
+#include 
+#include 
+#include 
+
+#include 
+
+typedef struct _pqueue *pqueue;
+
+typedef struct _pitem
+	{
+	PQ_64BIT priority;
+	void *data;
+	struct _pitem *next;
+	} pitem;
+
+typedef struct _pitem *piterator;
+
+pitem *pitem_new(PQ_64BIT priority, void *data);
+void   pitem_free(pitem *item);
+
+pqueue pqueue_new(void);
+void   pqueue_free(pqueue pq);
+
+pitem *pqueue_insert(pqueue pq, pitem *item);
+pitem *pqueue_peek(pqueue pq);
+pitem *pqueue_pop(pqueue pq);
+pitem *pqueue_find(pqueue pq, PQ_64BIT priority);
+pitem *pqueue_iterator(pqueue pq);
+pitem *pqueue_next(piterator *iter);
+
+void   pqueue_print(pqueue pq);
+
+#endif /* ! HEADER_PQUEUE_H */
diff --git a/dep/include/openssl/rand.h b/dep/include/openssl/rand.h
new file mode 100644
index 000000000..ac6c02176
--- /dev/null
+++ b/dep/include/openssl/rand.h
@@ -0,0 +1,140 @@
+/* crypto/rand/rand.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RAND_H
+#define HEADER_RAND_H
+
+#include 
+#include 
+#include 
+
+#if defined(OPENSSL_SYS_WINDOWS)
+#include 
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_FIPS)
+#define FIPS_RAND_SIZE_T size_t
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct rand_meth_st RAND_METHOD; */
+
+struct rand_meth_st
+	{
+	void (*seed)(const void *buf, int num);
+	int (*bytes)(unsigned char *buf, int num);
+	void (*cleanup)(void);
+	void (*add)(const void *buf, int num, double entropy);
+	int (*pseudorand)(unsigned char *buf, int num);
+	int (*status)(void);
+	};
+
+#ifdef BN_DEBUG
+extern int rand_predictable;
+#endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth);
+const RAND_METHOD *RAND_get_rand_method(void);
+#ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine);
+#endif
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void );
+int  RAND_bytes(unsigned char *buf,int num);
+int  RAND_pseudo_bytes(unsigned char *buf,int num);
+void RAND_seed(const void *buf,int num);
+void RAND_add(const void *buf,int num,double entropy);
+int  RAND_load_file(const char *file,long max_bytes);
+int  RAND_write_file(const char *file);
+const char *RAND_file_name(char *file,size_t num);
+int RAND_status(void);
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+int RAND_egd(const char *path);
+int RAND_egd_bytes(const char *path,int bytes);
+int RAND_poll(void);
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+
+void RAND_screen(void);
+int RAND_event(UINT, WPARAM, LPARAM);
+
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RAND_strings(void);
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+#define RAND_F_RAND_GET_RAND_METHOD			 101
+#define RAND_F_SSLEAY_RAND_BYTES			 100
+
+/* Reason codes. */
+#define RAND_R_PRNG_NOT_SEEDED				 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/rc2.h b/dep/include/openssl/rc2.h
new file mode 100644
index 000000000..34c836231
--- /dev/null
+++ b/dep/include/openssl/rc2.h
@@ -0,0 +1,101 @@
+/* crypto/rc2/rc2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC2_H
+#define HEADER_RC2_H
+
+#include  /* OPENSSL_NO_RC2, RC2_INT */
+#ifdef OPENSSL_NO_RC2
+#error RC2 is disabled.
+#endif
+
+#define RC2_ENCRYPT	1
+#define RC2_DECRYPT	0
+
+#define RC2_BLOCK	8
+#define RC2_KEY_LENGTH	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc2_key_st
+	{
+	RC2_INT data[64];
+	} RC2_KEY;
+
+ 
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
+void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
+		     int enc);
+void RC2_encrypt(unsigned long *data,RC2_KEY *key);
+void RC2_decrypt(unsigned long *data,RC2_KEY *key);
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	RC2_KEY *ks, unsigned char *iv, int enc);
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num, int enc);
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/rc4.h b/dep/include/openssl/rc4.h
new file mode 100644
index 000000000..7aec04fe9
--- /dev/null
+++ b/dep/include/openssl/rc4.h
@@ -0,0 +1,87 @@
+/* crypto/rc4/rc4.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC4_H
+#define HEADER_RC4_H
+
+#include  /* OPENSSL_NO_RC4, RC4_INT */
+#ifdef OPENSSL_NO_RC4
+#error RC4 is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc4_key_st
+	{
+	RC4_INT x,y;
+	RC4_INT data[256];
+	} RC4_KEY;
+
+ 
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+		unsigned char *outdata);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/rc5.h b/dep/include/openssl/rc5.h
new file mode 100644
index 000000000..de61ce83f
--- /dev/null
+++ b/dep/include/openssl/rc5.h
@@ -0,0 +1,117 @@
+/* crypto/rc5/rc5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC5_H
+#define HEADER_RC5_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_RC5
+#error RC5 is disabled.
+#endif
+
+#define RC5_ENCRYPT	1
+#define RC5_DECRYPT	0
+
+/* 32 bit.  For Alpha, things may get weird */
+#define RC5_32_INT unsigned long
+
+#define RC5_32_BLOCK		8
+#define RC5_32_KEY_LENGTH	16 /* This is a default, max is 255 */
+
+/* This are the only values supported.  Tweak the code if you want more
+ * The most supported modes will be
+ * RC5-32/12/16
+ * RC5-32/16/8
+ */
+#define RC5_8_ROUNDS	8
+#define RC5_12_ROUNDS	12
+#define RC5_16_ROUNDS	16
+
+typedef struct rc5_key_st
+	{
+	/* Number of rounds */
+	int rounds;
+	RC5_32_INT data[2*(RC5_16_ROUNDS+1)];
+	} RC5_32_KEY;
+
+
+void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
+	int rounds);
+void RC5_32_ecb_encrypt(const unsigned char *in,unsigned char *out,RC5_32_KEY *key,
+	int enc);
+void RC5_32_encrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_decrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
+			long length, RC5_32_KEY *ks, unsigned char *iv,
+			int enc);
+void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num, int enc);
+void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/dep/include/openssl/ripemd.h b/dep/include/openssl/ripemd.h
new file mode 100644
index 000000000..033a5965b
--- /dev/null
+++ b/dep/include/openssl/ripemd.h
@@ -0,0 +1,104 @@
+/* crypto/ripemd/ripemd.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RIPEMD_H
+#define HEADER_RIPEMD_H
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_RIPEMD
+#error RIPEMD is disabled.
+#endif
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define RIPEMD160_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define RIPEMD160_LONG unsigned long
+#define RIPEMD160_LONG_LOG2 3
+#else
+#define RIPEMD160_LONG unsigned int
+#endif
+
+#define RIPEMD160_CBLOCK	64
+#define RIPEMD160_LBLOCK	(RIPEMD160_CBLOCK/4)
+#define RIPEMD160_DIGEST_LENGTH	20
+
+typedef struct RIPEMD160state_st
+	{
+	RIPEMD160_LONG A,B,C,D,E;
+	RIPEMD160_LONG Nl,Nh;
+	RIPEMD160_LONG data[RIPEMD160_LBLOCK];
+	unsigned int   num;
+	} RIPEMD160_CTX;
+
+int RIPEMD160_Init(RIPEMD160_CTX *c);
+int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
+int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+unsigned char *RIPEMD160(const unsigned char *d, size_t n,
+	unsigned char *md);
+void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/rsa.h b/dep/include/openssl/rsa.h
new file mode 100644
index 000000000..b19c55693
--- /dev/null
+++ b/dep/include/openssl/rsa.h
@@ -0,0 +1,441 @@
+/* crypto/rsa/rsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RSA_H
+#define HEADER_RSA_H
+
+#include 
+
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+
+#ifdef OPENSSL_NO_RSA
+#error RSA is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct rsa_st RSA; */
+/* typedef struct rsa_meth_st RSA_METHOD; */
+
+struct rsa_meth_st
+	{
+	const char *name;
+	int (*rsa_pub_enc)(int flen,const unsigned char *from,
+			   unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_pub_dec)(int flen,const unsigned char *from,
+			   unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_priv_enc)(int flen,const unsigned char *from,
+			    unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_priv_dec)(int flen,const unsigned char *from,
+			    unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa,BN_CTX *ctx); /* Can be null */
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx,
+			  BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(RSA *rsa);		/* called at new */
+	int (*finish)(RSA *rsa);	/* called at free */
+	int flags;			/* RSA_METHOD_FLAG_* things */
+	char *app_data;			/* may be needed! */
+/* New sign and verify functions: some libraries don't allow arbitrary data
+ * to be signed/verified: this allows them to be used. Note: for this to work
+ * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used
+ * RSA_sign(), RSA_verify() should be used instead. Note: for backwards
+ * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER
+ * option is set in 'flags'.
+ */
+	int (*rsa_sign)(int type,
+		const unsigned char *m, unsigned int m_length,
+		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+	int (*rsa_verify)(int dtype,
+		const unsigned char *m, unsigned int m_length,
+		unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+/* If this callback is NULL, the builtin software RSA key-gen will be used. This
+ * is for behavioural compatibility whilst the code gets rewired, but one day
+ * it would be nice to assume there are no such things as "builtin software"
+ * implementations. */
+	int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+	};
+
+struct rsa_st
+	{
+	/* The first parameter is used to pickup errors where
+	 * this is passed instead of aEVP_PKEY, it is set to 0 */
+	int pad;
+	long version;
+	const RSA_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+	BIGNUM *n;
+	BIGNUM *e;
+	BIGNUM *d;
+	BIGNUM *p;
+	BIGNUM *q;
+	BIGNUM *dmp1;
+	BIGNUM *dmq1;
+	BIGNUM *iqmp;
+	/* be careful using this if the RSA structure is shared */
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	int flags;
+
+	/* Used to cache montgomery values */
+	BN_MONT_CTX *_method_mod_n;
+	BN_MONT_CTX *_method_mod_p;
+	BN_MONT_CTX *_method_mod_q;
+
+	/* all BIGNUM values are actually in the following data, if it is not
+	 * NULL */
+	char *bignum_data;
+	BN_BLINDING *blinding;
+	BN_BLINDING *mt_blinding;
+	};
+
+#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+# define OPENSSL_RSA_MAX_MODULUS_BITS	16384
+#endif
+
+#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
+# define OPENSSL_RSA_SMALL_MODULUS_BITS	3072
+#endif
+#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
+# define OPENSSL_RSA_MAX_PUBEXP_BITS	64 /* exponent limit enforced for "large" modulus only */
+#endif
+
+#define RSA_3	0x3L
+#define RSA_F4	0x10001L
+
+#define RSA_METHOD_FLAG_NO_CHECK	0x0001 /* don't check pub/private match */
+
+#define RSA_FLAG_CACHE_PUBLIC		0x0002
+#define RSA_FLAG_CACHE_PRIVATE		0x0004
+#define RSA_FLAG_BLINDING		0x0008
+#define RSA_FLAG_THREAD_SAFE		0x0010
+/* This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag bn_mod_exp
+ * gets called when private key components are absent.
+ */
+#define RSA_FLAG_EXT_PKEY		0x0020
+
+/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
+ */
+#define RSA_FLAG_SIGN_VER		0x0040
+
+#define RSA_FLAG_NO_BLINDING		0x0080 /* new with 0.9.6j and 0.9.7b; the built-in
+                                                * RSA implementation now uses blinding by
+                                                * default (ignoring RSA_FLAG_BLINDING),
+                                                * but other engines might not need it
+                                                */
+#define RSA_FLAG_NO_EXP_CONSTTIME	0x0100 /* new with 0.9.7h; the built-in RSA
+                                                * implementation now uses constant time
+                                                * modular exponentiation for secret exponents
+                                                * by default. This flag causes the
+                                                * faster variable sliding window method to
+                                                * be used for all exponents.
+                                                */
+
+#define RSA_PKCS1_PADDING	1
+#define RSA_SSLV23_PADDING	2
+#define RSA_NO_PADDING		3
+#define RSA_PKCS1_OAEP_PADDING	4
+#define RSA_X931_PADDING	5
+
+#define RSA_PKCS1_PADDING_SIZE	11
+
+#define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+#define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *	RSA_new(void);
+RSA *	RSA_new_method(ENGINE *engine);
+int	RSA_size(const RSA *);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+RSA *	RSA_generate_key(int bits, unsigned long e,void
+		(*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+
+int	RSA_check_key(const RSA *);
+	/* next 4 return -1 on error */
+int	RSA_public_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_public_decrypt(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_decrypt(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+void	RSA_free (RSA *r);
+/* "up" the RSA object's reference count */
+int	RSA_up_ref(RSA *r);
+
+int	RSA_flags(const RSA *r);
+
+void RSA_set_default_method(const RSA_METHOD *meth);
+const RSA_METHOD *RSA_get_default_method(void);
+const RSA_METHOD *RSA_get_method(const RSA *rsa);
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+/* This function needs the memory locking malloc callbacks to be installed */
+int RSA_memory_lock(RSA *r);
+
+/* these are the actual SSLeay RSA functions */
+const RSA_METHOD *RSA_PKCS1_SSLeay(void);
+
+const RSA_METHOD *RSA_null_method(void);
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+
+#ifndef OPENSSL_NO_FP_API
+int	RSA_print_fp(FILE *fp, const RSA *r,int offset);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+int	RSA_print(BIO *bp, const RSA *r,int offset);
+#endif
+
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+		int (*cb)(char *buf, int len, const char *prompt, int verify),
+		int sgckey);
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+		 int (*cb)(char *buf, int len, const char *prompt, int verify),
+		 int sgckey);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+		     int (*cb)(char *buf, int len, const char *prompt,
+			       int verify));
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+		      int (*cb)(char *buf, int len, const char *prompt,
+				int verify));
+
+/* The following 2 functions sign and verify a X509_SIG ASN1 object
+ * inside PKCS#1 padded RSA encryption */
+int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+/* The following 2 function sign and verify a ASN1_OCTET_STRING
+ * object inside PKCS#1 padded RSA encryption */
+int RSA_sign_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_length,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_length,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int PKCS1_MGF1(unsigned char *mask, long len,
+	const unsigned char *seed, long seedlen, const EVP_MD *dgst);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,
+	const unsigned char *p,int pl);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len,
+	const unsigned char *p,int pl);
+int RSA_padding_add_SSLv23(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_SSLv23(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_none(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_none(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_X931(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_X931(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_X931_hash_id(int nid);
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+			const EVP_MD *Hash, const unsigned char *EM, int sLen);
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+			const unsigned char *mHash,
+			const EVP_MD *Hash, int sLen);
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int RSA_set_ex_data(RSA *r,int idx,void *arg);
+void *RSA_get_ex_data(const RSA *r, int idx);
+
+RSA *RSAPublicKey_dup(RSA *rsa);
+RSA *RSAPrivateKey_dup(RSA *rsa);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RSA_strings(void);
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+#define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_RSA_BUILTIN_KEYGEN			 129
+#define RSA_F_RSA_CHECK_KEY				 123
+#define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
+#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT			 102
+#define RSA_F_RSA_EAY_PUBLIC_DECRYPT			 103
+#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT			 104
+#define RSA_F_RSA_GENERATE_KEY				 105
+#define RSA_F_RSA_MEMORY_LOCK				 130
+#define RSA_F_RSA_NEW_METHOD				 106
+#define RSA_F_RSA_NULL					 124
+#define RSA_F_RSA_NULL_MOD_EXP				 131
+#define RSA_F_RSA_NULL_PRIVATE_DECRYPT			 132
+#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT			 133
+#define RSA_F_RSA_NULL_PUBLIC_DECRYPT			 134
+#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT			 135
+#define RSA_F_RSA_PADDING_ADD_NONE			 107
+#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP		 121
+#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS			 125
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1		 108
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2		 109
+#define RSA_F_RSA_PADDING_ADD_SSLV23			 110
+#define RSA_F_RSA_PADDING_ADD_X931			 127
+#define RSA_F_RSA_PADDING_CHECK_NONE			 111
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP		 122
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1		 112
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2		 113
+#define RSA_F_RSA_PADDING_CHECK_SSLV23			 114
+#define RSA_F_RSA_PADDING_CHECK_X931			 128
+#define RSA_F_RSA_PRINT					 115
+#define RSA_F_RSA_PRINT_FP				 116
+#define RSA_F_RSA_SETUP_BLINDING			 136
+#define RSA_F_RSA_SIGN					 117
+#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
+#define RSA_F_RSA_VERIFY				 119
+#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING		 120
+#define RSA_F_RSA_VERIFY_PKCS1_PSS			 126
+
+/* Reason codes. */
+#define RSA_R_ALGORITHM_MISMATCH			 100
+#define RSA_R_BAD_E_VALUE				 101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT			 102
+#define RSA_R_BAD_PAD_BYTE_COUNT			 103
+#define RSA_R_BAD_SIGNATURE				 104
+#define RSA_R_BLOCK_TYPE_IS_NOT_01			 106
+#define RSA_R_BLOCK_TYPE_IS_NOT_02			 107
+#define RSA_R_DATA_GREATER_THAN_MOD_LEN			 108
+#define RSA_R_DATA_TOO_LARGE				 109
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 110
+#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS		 132
+#define RSA_R_DATA_TOO_SMALL				 111
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE		 122
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY		 112
+#define RSA_R_DMP1_NOT_CONGRUENT_TO_D			 124
+#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
+#define RSA_R_FIRST_OCTET_INVALID			 133
+#define RSA_R_INVALID_HEADER				 137
+#define RSA_R_INVALID_MESSAGE_LENGTH			 131
+#define RSA_R_INVALID_PADDING				 138
+#define RSA_R_INVALID_TRAILER				 139
+#define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
+#define RSA_R_KEY_SIZE_TOO_SMALL			 120
+#define RSA_R_LAST_OCTET_INVALID			 134
+#define RSA_R_MODULUS_TOO_LARGE				 105
+#define RSA_R_NO_PUBLIC_EXPONENT			 140
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
+#define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
+#define RSA_R_OAEP_DECODING_ERROR			 121
+#define RSA_R_PADDING_CHECK_FAILED			 114
+#define RSA_R_P_NOT_PRIME				 128
+#define RSA_R_Q_NOT_PRIME				 129
+#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED		 130
+#define RSA_R_SLEN_CHECK_FAILED				 136
+#define RSA_R_SLEN_RECOVERY_FAILED			 135
+#define RSA_R_SSLV3_ROLLBACK_ATTACK			 115
+#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
+#define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_WRONG_SIGNATURE_LENGTH			 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/safestack.h b/dep/include/openssl/safestack.h
new file mode 100644
index 000000000..d496f365c
--- /dev/null
+++ b/dep/include/openssl/safestack.h
@@ -0,0 +1,1850 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SAFESTACK_H
+#define HEADER_SAFESTACK_H
+
+#include 
+
+typedef void (*openssl_fptr)(void);
+#define openssl_fcast(f) ((openssl_fptr)f)
+
+#ifdef DEBUG_SAFESTACK
+
+#define STACK_OF(type) struct stack_st_##type
+#define PREDECLARE_STACK_OF(type) STACK_OF(type);
+
+#define DECLARE_STACK_OF(type) \
+STACK_OF(type) \
+    { \
+    STACK stack; \
+    };
+
+#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
+
+/* SKM_sk_... stack macros are internal to safestack.h:
+ * never use them directly, use sk__... instead */
+#define SKM_sk_new(type, cmp) \
+	((STACK_OF(type) * (*)(int (*)(const type * const *, const type * const *)))openssl_fcast(sk_new))(cmp)
+#define SKM_sk_new_null(type) \
+	((STACK_OF(type) * (*)(void))openssl_fcast(sk_new_null))()
+#define SKM_sk_free(type, st) \
+	((void (*)(STACK_OF(type) *))openssl_fcast(sk_free))(st)
+#define SKM_sk_num(type, st) \
+	((int (*)(const STACK_OF(type) *))openssl_fcast(sk_num))(st)
+#define SKM_sk_value(type, st,i) \
+	((type * (*)(const STACK_OF(type) *, int))openssl_fcast(sk_value))(st, i)
+#define SKM_sk_set(type, st,i,val) \
+	((type * (*)(STACK_OF(type) *, int, type *))openssl_fcast(sk_set))(st, i, val)
+#define SKM_sk_zero(type, st) \
+	((void (*)(STACK_OF(type) *))openssl_fcast(sk_zero))(st)
+#define SKM_sk_push(type, st,val) \
+	((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_push))(st, val)
+#define SKM_sk_unshift(type, st,val) \
+	((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_unshift))(st, val)
+#define SKM_sk_find(type, st,val) \
+	((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_find))(st, val)
+#define SKM_sk_delete(type, st,i) \
+	((type * (*)(STACK_OF(type) *, int))openssl_fcast(sk_delete))(st, i)
+#define SKM_sk_delete_ptr(type, st,ptr) \
+	((type * (*)(STACK_OF(type) *, type *))openssl_fcast(sk_delete_ptr))(st, ptr)
+#define SKM_sk_insert(type, st,val,i) \
+	((int (*)(STACK_OF(type) *, type *, int))openssl_fcast(sk_insert))(st, val, i)
+#define SKM_sk_set_cmp_func(type, st,cmp) \
+	((int (*(*)(STACK_OF(type) *, int (*)(const type * const *, const type * const *))) \
+	  (const type * const *, const type * const *))openssl_fcast(sk_set_cmp_func))\
+	(st, cmp)
+#define SKM_sk_dup(type, st) \
+	((STACK_OF(type) *(*)(STACK_OF(type) *))openssl_fcast(sk_dup))(st)
+#define SKM_sk_pop_free(type, st,free_func) \
+	((void (*)(STACK_OF(type) *, void (*)(type *)))openssl_fcast(sk_pop_free))\
+	(st, free_func)
+#define SKM_sk_shift(type, st) \
+	((type * (*)(STACK_OF(type) *))openssl_fcast(sk_shift))(st)
+#define SKM_sk_pop(type, st) \
+	((type * (*)(STACK_OF(type) *))openssl_fcast(sk_pop))(st)
+#define SKM_sk_sort(type, st) \
+	((void (*)(STACK_OF(type) *))openssl_fcast(sk_sort))(st)
+#define SKM_sk_is_sorted(type, st) \
+	((int (*)(const STACK_OF(type) *))openssl_fcast(sk_is_sorted))(st)
+
+#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+((STACK_OF(type) * (*) (STACK_OF(type) **,const unsigned char **, long , \
+                         type *(*)(type **, const unsigned char **,long), \
+                                void (*)(type *), int ,int )) openssl_fcast(d2i_ASN1_SET)) \
+			(st,pp,length, d2i_func, free_func, ex_tag,ex_class)
+#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	((int (*)(STACK_OF(type) *,unsigned char **, \
+        int (*)(type *,unsigned char **), int , int , int)) openssl_fcast(i2d_ASN1_SET)) \
+						(st,pp,i2d_func,ex_tag,ex_class,is_set)
+
+#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+	((unsigned char *(*)(STACK_OF(type) *, \
+        int (*)(type *,unsigned char **), unsigned char **,int *)) openssl_fcast(ASN1_seq_pack)) \
+				(st, i2d_func, buf, len)
+#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+	((STACK_OF(type) * (*)(const unsigned char *,int, \
+                              type *(*)(type **,const unsigned char **, long), \
+                              void (*)(type *)))openssl_fcast(ASN1_seq_unpack)) \
+					(buf,len,d2i_func, free_func)
+
+#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	((STACK_OF(type) * (*)(X509_ALGOR *, \
+            		type *(*)(type **, const unsigned char **, long), \
+				void (*)(type *), \
+                                const char *, int, \
+                                ASN1_STRING *, int))PKCS12_decrypt_d2i) \
+				(algor,d2i_func,free_func,pass,passlen,oct,seq)
+
+#else
+
+#define STACK_OF(type) STACK
+#define PREDECLARE_STACK_OF(type) /* nada */
+#define DECLARE_STACK_OF(type)    /* nada */
+#define IMPLEMENT_STACK_OF(type)  /* nada */
+
+#define SKM_sk_new(type, cmp) \
+	sk_new((int (*)(const char * const *, const char * const *))(cmp))
+#define SKM_sk_new_null(type) \
+	sk_new_null()
+#define SKM_sk_free(type, st) \
+	sk_free(st)
+#define SKM_sk_num(type, st) \
+	sk_num(st)
+#define SKM_sk_value(type, st,i) \
+	((type *)sk_value(st, i))
+#define SKM_sk_set(type, st,i,val) \
+	((type *)sk_set(st, i,(char *)val))
+#define SKM_sk_zero(type, st) \
+	sk_zero(st)
+#define SKM_sk_push(type, st,val) \
+	sk_push(st, (char *)val)
+#define SKM_sk_unshift(type, st,val) \
+	sk_unshift(st, val)
+#define SKM_sk_find(type, st,val) \
+	sk_find(st, (char *)val)
+#define SKM_sk_delete(type, st,i) \
+	((type *)sk_delete(st, i))
+#define SKM_sk_delete_ptr(type, st,ptr) \
+	((type *)sk_delete_ptr(st,(char *)ptr))
+#define SKM_sk_insert(type, st,val,i) \
+	sk_insert(st, (char *)val, i)
+#define SKM_sk_set_cmp_func(type, st,cmp) \
+	((int (*)(const type * const *,const type * const *)) \
+	sk_set_cmp_func(st, (int (*)(const char * const *, const char * const *))(cmp)))
+#define SKM_sk_dup(type, st) \
+	sk_dup(st)
+#define SKM_sk_pop_free(type, st,free_func) \
+	sk_pop_free(st, (void (*)(void *))free_func)
+#define SKM_sk_shift(type, st) \
+	((type *)sk_shift(st))
+#define SKM_sk_pop(type, st) \
+	((type *)sk_pop(st))
+#define SKM_sk_sort(type, st) \
+	sk_sort(st)
+#define SKM_sk_is_sorted(type, st) \
+	sk_is_sorted(st)
+
+#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	d2i_ASN1_SET(st,pp,length, (void *(*)(void ** ,const unsigned char ** ,long))d2i_func, (void (*)(void *))free_func, ex_tag,ex_class)
+#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	i2d_ASN1_SET(st,pp,(int (*)(void *, unsigned char **))i2d_func,ex_tag,ex_class,is_set)
+
+#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+	ASN1_seq_pack(st, (int (*)(void *, unsigned char **))i2d_func, buf, len)
+#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+	ASN1_seq_unpack(buf,len,(void *(*)(void **,const unsigned char **,long))d2i_func, (void(*)(void *))free_func)
+
+#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	((STACK *)PKCS12_decrypt_d2i(algor,(char *(*)())d2i_func, (void(*)(void *))free_func,pass,passlen,oct,seq))
+
+#endif
+
+/* This block of defines is updated by util/mkstack.pl, please do not touch! */
+#define sk_ACCESS_DESCRIPTION_new(st) SKM_sk_new(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
+#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
+#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
+#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
+#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
+#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
+#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
+#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
+
+#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st))
+#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
+#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
+#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
+#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
+#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
+#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
+#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
+#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
+#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
+#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
+#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
+#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
+#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
+#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
+
+#define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
+#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
+#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
+#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
+#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
+#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
+#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
+#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
+
+#define sk_ASN1_INTEGER_new(st) SKM_sk_new(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
+#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
+#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
+#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
+#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
+#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
+#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
+#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
+
+#define sk_ASN1_OBJECT_new(st) SKM_sk_new(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
+#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
+#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
+#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
+#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
+#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
+#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
+#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
+
+#define sk_ASN1_STRING_TABLE_new(st) SKM_sk_new(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
+#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
+#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
+#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
+#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
+#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
+#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
+#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
+
+#define sk_ASN1_TYPE_new(st) SKM_sk_new(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
+#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
+#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
+#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
+#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
+#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
+#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
+#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
+
+#define sk_ASN1_VALUE_new(st) SKM_sk_new(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
+#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
+#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
+#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
+#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
+#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
+#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
+#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
+
+#define sk_BIO_new(st) SKM_sk_new(BIO, (st))
+#define sk_BIO_new_null() SKM_sk_new_null(BIO)
+#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
+#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
+#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
+#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
+#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
+#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
+#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
+#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
+#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
+#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
+#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
+#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
+#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
+#define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
+#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
+#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
+#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
+#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
+#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
+
+#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
+#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
+#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
+#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
+#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
+#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
+#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
+#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
+
+#define sk_CONF_MODULE_new(st) SKM_sk_new(CONF_MODULE, (st))
+#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
+#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
+#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
+#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
+#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
+#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
+#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
+#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
+#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
+#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
+#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
+#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
+#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
+#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
+
+#define sk_CONF_VALUE_new(st) SKM_sk_new(CONF_VALUE, (st))
+#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
+#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
+#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
+#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
+#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
+#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
+#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
+#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
+#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
+#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
+#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
+#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
+#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
+#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
+
+#define sk_CRYPTO_EX_DATA_FUNCS_new(st) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
+#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
+#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
+#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
+#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
+#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
+
+#define sk_CRYPTO_dynlock_new(st) SKM_sk_new(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
+#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
+#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
+#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
+#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
+#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
+#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
+#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
+
+#define sk_DIST_POINT_new(st) SKM_sk_new(DIST_POINT, (st))
+#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
+#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
+#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
+#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
+#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
+#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
+#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
+#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
+#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
+#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
+#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
+#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
+#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
+#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
+
+#define sk_ENGINE_new(st) SKM_sk_new(ENGINE, (st))
+#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
+#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
+#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
+#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
+#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
+#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
+#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
+#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
+#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
+#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
+#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
+#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
+#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
+#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
+#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
+#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
+#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
+#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
+#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
+#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
+
+#define sk_ENGINE_CLEANUP_ITEM_new(st) SKM_sk_new(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
+#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
+#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
+#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
+#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
+#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
+#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
+
+#define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
+#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
+#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
+#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
+#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
+#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
+#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
+#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
+
+#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
+#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
+#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
+#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
+#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
+#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
+#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
+#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
+
+#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st))
+#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
+#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
+#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
+#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
+#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
+#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
+#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
+#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
+#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
+#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
+#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
+#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
+#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
+#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
+
+#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
+#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
+#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
+#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
+#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
+#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
+#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
+#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
+
+#define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
+#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
+#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
+#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
+#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
+#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
+#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
+#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
+
+#define sk_KRB5_AUTHDATA_new(st) SKM_sk_new(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
+#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
+#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
+#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
+#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
+#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
+#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
+#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
+
+#define sk_KRB5_AUTHENTBODY_new(st) SKM_sk_new(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
+#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
+#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
+#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
+#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
+#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
+#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
+#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
+
+#define sk_KRB5_CHECKSUM_new(st) SKM_sk_new(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
+#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
+#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
+#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
+#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
+#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
+#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
+#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
+
+#define sk_KRB5_ENCDATA_new(st) SKM_sk_new(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
+#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
+#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
+#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
+#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
+#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
+#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
+#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
+
+#define sk_KRB5_ENCKEY_new(st) SKM_sk_new(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
+#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
+#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
+#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
+#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
+#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
+#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
+#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
+
+#define sk_KRB5_PRINCNAME_new(st) SKM_sk_new(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
+#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
+#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
+#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
+#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
+#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
+#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
+#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
+
+#define sk_KRB5_TKTBODY_new(st) SKM_sk_new(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
+#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
+#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
+#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
+#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
+#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
+#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
+#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
+
+#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st))
+#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+
+#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
+#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+
+#define sk_NAME_FUNCS_new(st) SKM_sk_new(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
+#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
+#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
+#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
+#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
+#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
+#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
+#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
+
+#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
+#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
+#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
+#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
+#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
+#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
+#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
+#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
+
+#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
+#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
+#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
+#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
+#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
+#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
+#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
+#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
+
+#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
+#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
+#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
+#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
+#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
+#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
+#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
+#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
+
+#define sk_PKCS12_SAFEBAG_new(st) SKM_sk_new(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
+#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
+#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
+#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
+#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
+#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
+#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
+#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
+
+#define sk_PKCS7_new(st) SKM_sk_new(PKCS7, (st))
+#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
+#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
+#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
+#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
+#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
+#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
+#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
+#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
+#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
+#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
+#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
+#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
+#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
+#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
+#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
+#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
+#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
+#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
+#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
+#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
+
+#define sk_PKCS7_RECIP_INFO_new(st) SKM_sk_new(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
+#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
+#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
+#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
+#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
+#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
+#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
+#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
+
+#define sk_PKCS7_SIGNER_INFO_new(st) SKM_sk_new(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
+#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
+#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
+#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
+#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
+#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
+#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
+#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
+
+#define sk_POLICYINFO_new(st) SKM_sk_new(POLICYINFO, (st))
+#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
+#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
+#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
+#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
+#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
+#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
+#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
+#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
+#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
+#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
+#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
+#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
+#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
+#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
+
+#define sk_POLICYQUALINFO_new(st) SKM_sk_new(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
+#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
+#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
+#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
+#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
+#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
+#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
+#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
+
+#define sk_POLICY_MAPPING_new(st) SKM_sk_new(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
+#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
+#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
+#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
+#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
+#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
+#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
+#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+
+#define sk_SSL_CIPHER_new(st) SKM_sk_new(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
+#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
+#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
+#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
+#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
+#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
+#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
+#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
+
+#define sk_SSL_COMP_new(st) SKM_sk_new(SSL_COMP, (st))
+#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
+#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
+#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
+#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
+#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
+#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
+#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
+#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
+#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
+#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
+#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
+#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
+#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
+#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
+
+#define sk_STORE_OBJECT_new(st) SKM_sk_new(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
+#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
+#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
+#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
+#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
+#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
+#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
+#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
+
+#define sk_SXNETID_new(st) SKM_sk_new(SXNETID, (st))
+#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
+#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
+#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
+#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
+#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
+#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
+#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
+#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
+#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
+#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
+#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
+#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
+#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
+#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
+#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
+#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
+#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
+#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
+#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
+#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
+
+#define sk_UI_STRING_new(st) SKM_sk_new(UI_STRING, (st))
+#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
+#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
+#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
+#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
+#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
+#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
+#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
+#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
+#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
+#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
+#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
+#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
+#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
+#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
+#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
+#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
+#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
+#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
+#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
+#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
+
+#define sk_X509_new(st) SKM_sk_new(X509, (st))
+#define sk_X509_new_null() SKM_sk_new_null(X509)
+#define sk_X509_free(st) SKM_sk_free(X509, (st))
+#define sk_X509_num(st) SKM_sk_num(X509, (st))
+#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
+#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
+#define sk_X509_zero(st) SKM_sk_zero(X509, (st))
+#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
+#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
+#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
+#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
+#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
+#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
+#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
+#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
+#define sk_X509_dup(st) SKM_sk_dup(X509, st)
+#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
+#define sk_X509_shift(st) SKM_sk_shift(X509, (st))
+#define sk_X509_pop(st) SKM_sk_pop(X509, (st))
+#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
+#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
+
+#define sk_X509V3_EXT_METHOD_new(st) SKM_sk_new(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
+#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
+#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
+#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
+#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
+#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
+#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
+#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
+
+#define sk_X509_ALGOR_new(st) SKM_sk_new(X509_ALGOR, (st))
+#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
+#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
+#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
+#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
+#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
+#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
+#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
+#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
+#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
+#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
+#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
+#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
+#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
+#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
+
+#define sk_X509_ATTRIBUTE_new(st) SKM_sk_new(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
+#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
+#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
+#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
+#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
+#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
+#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
+#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
+
+#define sk_X509_CRL_new(st) SKM_sk_new(X509_CRL, (st))
+#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
+#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
+#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
+#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
+#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
+#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
+#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
+#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
+#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
+#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
+#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
+#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
+#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
+#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
+#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
+#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
+#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
+#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
+#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
+#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
+
+#define sk_X509_EXTENSION_new(st) SKM_sk_new(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
+#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
+#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
+#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
+#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
+#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
+#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
+#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
+
+#define sk_X509_INFO_new(st) SKM_sk_new(X509_INFO, (st))
+#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
+#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
+#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
+#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
+#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
+#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
+#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
+#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
+#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
+#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
+#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
+#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
+#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
+#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
+#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
+#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
+#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
+#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
+#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
+#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
+
+#define sk_X509_LOOKUP_new(st) SKM_sk_new(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
+#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
+#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
+#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
+#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
+#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
+#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
+#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
+
+#define sk_X509_NAME_new(st) SKM_sk_new(X509_NAME, (st))
+#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
+#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
+#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
+#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
+#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
+#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
+#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
+#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
+#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
+#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
+#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
+#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
+#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
+#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
+#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
+#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
+#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
+#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
+#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
+#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
+
+#define sk_X509_NAME_ENTRY_new(st) SKM_sk_new(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
+#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
+#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
+#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
+#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
+#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
+#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
+#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
+
+#define sk_X509_OBJECT_new(st) SKM_sk_new(X509_OBJECT, (st))
+#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
+#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
+#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
+#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
+#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
+#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
+#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
+#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
+#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
+#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
+#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
+#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
+#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
+#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
+
+#define sk_X509_POLICY_DATA_new(st) SKM_sk_new(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
+#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
+#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
+#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
+#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
+#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
+#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
+#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
+
+#define sk_X509_POLICY_NODE_new(st) SKM_sk_new(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
+#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
+#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
+#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
+#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
+#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
+#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
+#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
+
+#define sk_X509_POLICY_REF_new(st) SKM_sk_new(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_new_null() SKM_sk_new_null(X509_POLICY_REF)
+#define sk_X509_POLICY_REF_free(st) SKM_sk_free(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_num(st) SKM_sk_num(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_value(st, i) SKM_sk_value(X509_POLICY_REF, (st), (i))
+#define sk_X509_POLICY_REF_set(st, i, val) SKM_sk_set(X509_POLICY_REF, (st), (i), (val))
+#define sk_X509_POLICY_REF_zero(st) SKM_sk_zero(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_push(st, val) SKM_sk_push(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_unshift(st, val) SKM_sk_unshift(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_find(st, val) SKM_sk_find(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_delete(st, i) SKM_sk_delete(X509_POLICY_REF, (st), (i))
+#define sk_X509_POLICY_REF_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_REF, (st), (ptr))
+#define sk_X509_POLICY_REF_insert(st, val, i) SKM_sk_insert(X509_POLICY_REF, (st), (val), (i))
+#define sk_X509_POLICY_REF_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_REF, (st), (cmp))
+#define sk_X509_POLICY_REF_dup(st) SKM_sk_dup(X509_POLICY_REF, st)
+#define sk_X509_POLICY_REF_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_REF, (st), (free_func))
+#define sk_X509_POLICY_REF_shift(st) SKM_sk_shift(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_pop(st) SKM_sk_pop(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_sort(st) SKM_sk_sort(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_REF, (st))
+
+#define sk_X509_PURPOSE_new(st) SKM_sk_new(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
+#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
+#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
+#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
+#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
+#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
+#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
+#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
+
+#define sk_X509_REVOKED_new(st) SKM_sk_new(X509_REVOKED, (st))
+#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
+#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
+#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
+#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
+#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
+#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
+#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
+#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
+#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
+#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
+#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
+#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
+#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
+#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
+
+#define sk_X509_TRUST_new(st) SKM_sk_new(X509_TRUST, (st))
+#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
+#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
+#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
+#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
+#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
+#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
+#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
+#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
+#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
+#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
+#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
+#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
+#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
+#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
+
+#define sk_X509_VERIFY_PARAM_new(st) SKM_sk_new(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
+#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
+#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
+#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
+#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
+#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
+#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
+#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
+
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
+
+#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+/* End of util/mkstack.pl block, you may now edit :-) */
+
+#endif /* !defined HEADER_SAFESTACK_H */
diff --git a/dep/include/openssl/sha.h b/dep/include/openssl/sha.h
new file mode 100644
index 000000000..eed44d7f9
--- /dev/null
+++ b/dep/include/openssl/sha.h
@@ -0,0 +1,200 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
+#error SHA is disabled.
+#endif
+
+#if defined(OPENSSL_FIPS)
+#define FIPS_SHA_SIZE_T size_t
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+#define SHA_LBLOCK	16
+#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+	{
+	SHA_LONG h0,h1,h2,h3,h4;
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	unsigned int num;
+	} SHA_CTX;
+
+#ifndef OPENSSL_NO_SHA0
+int SHA_Init(SHA_CTX *c);
+int SHA_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifndef OPENSSL_NO_SHA1
+int SHA1_Init(SHA_CTX *c);
+int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA256_CBLOCK	(SHA_LBLOCK*4)	/* SHA-256 treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA224_DIGEST_LENGTH	28
+#define SHA256_DIGEST_LENGTH	32
+
+typedef struct SHA256state_st
+	{
+	SHA_LONG h[8];
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	unsigned int num,md_len;
+	} SHA256_CTX;
+
+#ifndef OPENSSL_NO_SHA256
+int SHA224_Init(SHA256_CTX *c);
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA224_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md);
+int SHA256_Init(SHA256_CTX *c);
+int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA256_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md);
+void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA384_DIGEST_LENGTH	48
+#define SHA512_DIGEST_LENGTH	64
+
+#ifndef OPENSSL_NO_SHA512
+/*
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
+ * for further details.
+ */
+#define SHA512_CBLOCK	(SHA_LBLOCK*8)	/* SHA-512 treats input data as a
+					 * contiguous array of 64 bit
+					 * wide big-endian values. */
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#define SHA_LONG64 unsigned __int64
+#define U64(C)     C##UI64
+#elif defined(__arch64__)
+#define SHA_LONG64 unsigned long
+#define U64(C)     C##UL
+#else
+#define SHA_LONG64 unsigned long long
+#define U64(C)     C##ULL
+#endif
+
+typedef struct SHA512state_st
+	{
+	SHA_LONG64 h[8];
+	SHA_LONG64 Nl,Nh;
+	union {
+		SHA_LONG64	d[SHA_LBLOCK];
+		unsigned char	p[SHA512_CBLOCK];
+	} u;
+	unsigned int num,md_len;
+	} SHA512_CTX;
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+int SHA384_Init(SHA512_CTX *c);
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md);
+int SHA512_Init(SHA512_CTX *c);
+int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md);
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/ssl.h b/dep/include/openssl/ssl.h
new file mode 100644
index 000000000..2e067e7a7
--- /dev/null
+++ b/dep/include/openssl/ssl.h
@@ -0,0 +1,1960 @@
+/* ssl/ssl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL_H 
+#define HEADER_SSL_H 
+
+#include 
+
+#ifndef OPENSSL_NO_COMP
+#include 
+#endif
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#ifndef OPENSSL_NO_DEPRECATED
+#ifndef OPENSSL_NO_X509
+#include 
+#endif
+#include 
+#include 
+#include 
+#endif
+#include 
+
+#include 
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* SSLeay version number for ASN.1 encoding of the session information */
+/* Version 0 - initial version
+ * Version 1 - added the optional peer certificate
+ */
+#define SSL_SESSION_ASN1_VERSION 0x0001
+
+/* text strings for the ciphers */
+#define SSL_TXT_NULL_WITH_MD5		SSL2_TXT_NULL_WITH_MD5			
+#define SSL_TXT_RC4_128_WITH_MD5	SSL2_TXT_RC4_128_WITH_MD5		
+#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	
+#define SSL_TXT_RC2_128_CBC_WITH_MD5	SSL2_TXT_RC2_128_CBC_WITH_MD5		
+#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	
+#define SSL_TXT_IDEA_128_CBC_WITH_MD5	SSL2_TXT_IDEA_128_CBC_WITH_MD5		
+#define SSL_TXT_DES_64_CBC_WITH_MD5	SSL2_TXT_DES_64_CBC_WITH_MD5		
+#define SSL_TXT_DES_64_CBC_WITH_SHA	SSL2_TXT_DES_64_CBC_WITH_SHA		
+#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	
+#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	
+
+/*    VRS Additional Kerberos5 entries
+ */
+#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+#define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
+#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
+#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5       
+#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5       
+#define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
+#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 
+
+#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA 
+#define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA 
+#define SSL_TXT_KRB5_RC4_40_SHA	      SSL3_TXT_KRB5_RC4_40_SHA
+#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5 
+#define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5 
+#define SSL_TXT_KRB5_RC4_40_MD5	      SSL3_TXT_KRB5_RC4_40_MD5
+
+#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
+#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
+#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
+#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+#define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256
+
+#define SSL_MAX_SSL_SESSION_ID_LENGTH		32
+#define SSL_MAX_SID_CTX_LENGTH			32
+
+#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES	(512/8)
+#define SSL_MAX_KEY_ARG_LENGTH			8
+#define SSL_MAX_MASTER_KEY_LENGTH		48
+
+/* These are used to specify which ciphers to use and not to use */
+#define SSL_TXT_LOW		"LOW"
+#define SSL_TXT_MEDIUM		"MEDIUM"
+#define SSL_TXT_HIGH		"HIGH"
+#define SSL_TXT_kFZA		"kFZA"
+#define	SSL_TXT_aFZA		"aFZA"
+#define SSL_TXT_eFZA		"eFZA"
+#define SSL_TXT_FZA		"FZA"
+
+#define	SSL_TXT_aNULL		"aNULL"
+#define	SSL_TXT_eNULL		"eNULL"
+#define	SSL_TXT_NULL		"NULL"
+
+#define SSL_TXT_kKRB5     	"kKRB5"
+#define SSL_TXT_aKRB5     	"aKRB5"
+#define SSL_TXT_KRB5      	"KRB5"
+
+#define SSL_TXT_kRSA		"kRSA"
+#define SSL_TXT_kDHr		"kDHr"
+#define SSL_TXT_kDHd		"kDHd"
+#define SSL_TXT_kEDH		"kEDH"
+#define	SSL_TXT_aRSA		"aRSA"
+#define	SSL_TXT_aDSS		"aDSS"
+#define	SSL_TXT_aDH		"aDH"
+#define	SSL_TXT_DSS		"DSS"
+#define SSL_TXT_DH		"DH"
+#define SSL_TXT_EDH		"EDH"
+#define SSL_TXT_ADH		"ADH"
+#define SSL_TXT_RSA		"RSA"
+#define SSL_TXT_DES		"DES"
+#define SSL_TXT_3DES		"3DES"
+#define SSL_TXT_RC4		"RC4"
+#define SSL_TXT_RC2		"RC2"
+#define SSL_TXT_IDEA		"IDEA"
+#define SSL_TXT_AES		"AES"
+#define SSL_TXT_CAMELLIA	"CAMELLIA"
+#define SSL_TXT_MD5		"MD5"
+#define SSL_TXT_SHA1		"SHA1"
+#define SSL_TXT_SHA		"SHA"
+#define SSL_TXT_EXP		"EXP"
+#define SSL_TXT_EXPORT		"EXPORT"
+#define SSL_TXT_EXP40		"EXPORT40"
+#define SSL_TXT_EXP56		"EXPORT56"
+#define SSL_TXT_SSLV2		"SSLv2"
+#define SSL_TXT_SSLV3		"SSLv3"
+#define SSL_TXT_TLSV1		"TLSv1"
+#define SSL_TXT_ALL		"ALL"
+#define SSL_TXT_ECC		"ECCdraft" /* ECC ciphersuites are not yet official */
+
+/*
+ * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
+ * ciphers normally not being used.
+ * Example: "RC4" will activate all ciphers using RC4 including ciphers
+ * without authentication, which would normally disabled by DEFAULT (due
+ * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
+ * will make sure that it is also disabled in the specific selection.
+ * COMPLEMENTOF* identifiers are portable between version, as adjustments
+ * to the default cipher setup will also be included here.
+ *
+ * COMPLEMENTOFDEFAULT does not experience the same special treatment that
+ * DEFAULT gets, as only selection is being done and no sorting as needed
+ * for DEFAULT.
+ */
+#define SSL_TXT_CMPALL		"COMPLEMENTOFALL"
+#define SSL_TXT_CMPDEF		"COMPLEMENTOFDEFAULT"
+
+/* The following cipher list is used by default.
+ * It also is substituted when an application-defined cipher list string
+ * starts with 'DEFAULT'. */
+#ifdef OPENSSL_NO_CAMELLIA
+# define SSL_DEFAULT_CIPHER_LIST	"ALL:!ADH:+RC4:@STRENGTH" /* low priority for RC4 */
+#else
+# define SSL_DEFAULT_CIPHER_LIST	"AES:CAMELLIA:ALL:!ADH:+RC4:@STRENGTH" /* low priority for RC4 */
+#endif
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+#define SSL_SENT_SHUTDOWN	1
+#define SSL_RECEIVED_SHUTDOWN	2
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
+#define OPENSSL_NO_SSL2
+#endif
+
+#define SSL_FILETYPE_ASN1	X509_FILETYPE_ASN1
+#define SSL_FILETYPE_PEM	X509_FILETYPE_PEM
+
+/* This is needed to stop compilers complaining about the
+ * 'struct ssl_st *' function parameters used to prototype callbacks
+ * in SSL_CTX. */
+typedef struct ssl_st *ssl_crock_st;
+
+/* used to hold info on the particular ciphers used */
+typedef struct ssl_cipher_st
+	{
+	int valid;
+	const char *name;		/* text name */
+	unsigned long id;		/* id, 4 bytes, first is version */
+	unsigned long algorithms;	/* what ciphers are used */
+	unsigned long algo_strength;	/* strength and export flags */
+	unsigned long algorithm2;	/* Extra flags */
+	int strength_bits;		/* Number of bits really used */
+	int alg_bits;			/* Number of bits for algorithm */
+	unsigned long mask;		/* used for matching */
+	unsigned long mask_strength;	/* also used for matching */
+	} SSL_CIPHER;
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+
+/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
+typedef struct ssl_method_st
+	{
+	int version;
+	int (*ssl_new)(SSL *s);
+	void (*ssl_clear)(SSL *s);
+	void (*ssl_free)(SSL *s);
+	int (*ssl_accept)(SSL *s);
+	int (*ssl_connect)(SSL *s);
+	int (*ssl_read)(SSL *s,void *buf,int len);
+	int (*ssl_peek)(SSL *s,void *buf,int len);
+	int (*ssl_write)(SSL *s,const void *buf,int len);
+	int (*ssl_shutdown)(SSL *s);
+	int (*ssl_renegotiate)(SSL *s);
+	int (*ssl_renegotiate_check)(SSL *s);
+	long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
+		max, int *ok);
+	int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, 
+		int peek);
+	int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
+	int (*ssl_dispatch_alert)(SSL *s);
+	long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
+	long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
+	SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
+	int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
+	int (*ssl_pending)(const SSL *s);
+	int (*num_ciphers)(void);
+	SSL_CIPHER *(*get_cipher)(unsigned ncipher);
+	struct ssl_method_st *(*get_ssl_method)(int version);
+	long (*get_timeout)(void);
+	struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
+	int (*ssl_version)(void);
+	long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
+	long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
+	} SSL_METHOD;
+
+/* Lets make this into an ASN.1 type structure as follows
+ * SSL_SESSION_ID ::= SEQUENCE {
+ *	version 		INTEGER,	-- structure version number
+ *	SSLversion 		INTEGER,	-- SSL version number
+ *	Cipher 			OCTET_STRING,	-- the 3 byte cipher ID
+ *	Session_ID 		OCTET_STRING,	-- the Session ID
+ *	Master_key 		OCTET_STRING,	-- the master key
+ *	KRB5_principal		OCTET_STRING	-- optional Kerberos principal
+ *	Key_Arg [ 0 ] IMPLICIT	OCTET_STRING,	-- the optional Key argument
+ *	Time [ 1 ] EXPLICIT	INTEGER,	-- optional Start Time
+ *	Timeout [ 2 ] EXPLICIT	INTEGER,	-- optional Timeout ins seconds
+ *	Peer [ 3 ] EXPLICIT	X509,		-- optional Peer Certificate
+ *	Session_ID_context [ 4 ] EXPLICIT OCTET_STRING,   -- the Session ID context
+ *	Verify_result [ 5 ] EXPLICIT INTEGER    -- X509_V_... code for `Peer'
+ *	Compression [6] IMPLICIT ASN1_OBJECT	-- compression OID XXXXX
+ *	}
+ * Look in ssl/ssl_asn1.c for more details
+ * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
+ */
+typedef struct ssl_session_st
+	{
+	int ssl_version;	/* what ssl version session info is
+				 * being kept in here? */
+
+	/* only really used in SSLv2 */
+	unsigned int key_arg_length;
+	unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
+	int master_key_length;
+	unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+	/* session_id - valid? */
+	unsigned int session_id_length;
+	unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+	/* this is used to determine whether the session is being reused in
+	 * the appropriate context. It is up to the application to set this,
+	 * via SSL_new */
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+#ifndef OPENSSL_NO_KRB5
+        unsigned int krb5_client_princ_len;
+        unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
+#endif /* OPENSSL_NO_KRB5 */
+
+	int not_resumable;
+
+	/* The cert is the certificate used to establish this connection */
+	struct sess_cert_st /* SESS_CERT */ *sess_cert;
+
+	/* This is the cert for the other end.
+	 * On clients, it will be the same as sess_cert->peer_key->x509
+	 * (the latter is not enough as sess_cert is not retained
+	 * in the external representation of sessions, see ssl_asn1.c). */
+	X509 *peer;
+	/* when app_verify_callback accepts a session where the peer's certificate
+	 * is not ok, we must remember the error for session reuse: */
+	long verify_result; /* only for servers */
+
+	int references;
+	long timeout;
+	long time;
+
+	int compress_meth;		/* Need to lookup the method */
+
+	SSL_CIPHER *cipher;
+	unsigned long cipher_id;	/* when ASN.1 loaded, this
+					 * needs to be used to load
+					 * the 'cipher' structure */
+
+	STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
+
+	CRYPTO_EX_DATA ex_data; /* application specific data */
+
+	/* These are used to make removal of session-ids more
+	 * efficient and to implement a maximum cache size. */
+	struct ssl_session_st *prev,*next;
+	} SSL_SESSION;
+
+
+#define SSL_OP_MICROSOFT_SESS_ID_BUG			0x00000001L
+#define SSL_OP_NETSCAPE_CHALLENGE_BUG			0x00000002L
+#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
+#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x00000040L /* no effect since 0.9.7h and 0.9.8b */
+#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x00000080L
+#define SSL_OP_TLS_D5_BUG				0x00000100L
+#define SSL_OP_TLS_BLOCK_PADDING_BUG			0x00000200L
+
+/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
+ * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
+ * the workaround is not needed.  Unfortunately some broken SSL/TLS
+ * implementations cannot handle it at all, which is why we include
+ * it in SSL_OP_ALL. */
+#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
+
+/* SSL_OP_ALL: various bug workarounds that should be rather harmless.
+ *             This used to be 0x000FFFFFL before 0.9.7. */
+#define SSL_OP_ALL					0x00000FFFL
+
+/* DTLS options */
+#define SSL_OP_NO_QUERY_MTU                 0x00001000L
+/* Turn on Cookie Exchange (on relevant for servers) */
+#define SSL_OP_COOKIE_EXCHANGE              0x00002000L
+
+/* As server, disallow session resumption on renegotiation */
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
+/* If set, always create a new key when using tmp_ecdh parameters */
+#define SSL_OP_SINGLE_ECDH_USE				0x00080000L
+/* If set, always create a new key when using tmp_dh parameters */
+#define SSL_OP_SINGLE_DH_USE				0x00100000L
+/* Set to always use the tmp_rsa key when doing RSA operations,
+ * even when this violates protocol specs */
+#define SSL_OP_EPHEMERAL_RSA				0x00200000L
+/* Set on servers to choose the cipher according to the server's
+ * preferences */
+#define SSL_OP_CIPHER_SERVER_PREFERENCE			0x00400000L
+/* If set, a server will allow a client to issue a SSLv3.0 version number
+ * as latest version supported in the premaster secret, even when TLSv1.0
+ * (version 3.1) was announced in the client hello. Normally this is
+ * forbidden to prevent version rollback attacks. */
+#define SSL_OP_TLS_ROLLBACK_BUG				0x00800000L
+
+#define SSL_OP_NO_SSLv2					0x01000000L
+#define SSL_OP_NO_SSLv3					0x02000000L
+#define SSL_OP_NO_TLSv1					0x04000000L
+
+/* The next flag deliberately changes the ciphertest, this is a check
+ * for the PKCS#1 attack */
+#define SSL_OP_PKCS1_CHECK_1				0x08000000L
+#define SSL_OP_PKCS1_CHECK_2				0x10000000L
+#define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
+#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
+
+
+/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+ * when just a single record has been written): */
+#define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
+/* Make it possible to retry SSL_write() with changed buffer location
+ * (buffer contents must stay the same!); this is not the default to avoid
+ * the misconception that non-blocking SSL_write() behaves like
+ * non-blocking write(): */
+#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
+/* Never bother the application with retries if the transport
+ * is blocking: */
+#define SSL_MODE_AUTO_RETRY 0x00000004L
+/* Don't attempt to automatically build certificate chain */
+#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+
+
+/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+ * they cannot be used to clear bits. */
+
+#define SSL_CTX_set_options(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_CTX_get_options(ctx) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
+#define SSL_set_options(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_get_options(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
+
+#define SSL_CTX_set_mode(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+#define SSL_CTX_get_mode(ctx) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
+#define SSL_set_mode(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
+#define SSL_get_mode(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
+#define SSL_set_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+
+
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
+#else
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */
+#endif
+
+#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT	(1024*20)
+
+/* This callback type is used inside SSL_CTX, SSL, and in the functions that set
+ * them. It is used to override the generation of SSL/TLS session IDs in a
+ * server. Return value should be zero on an error, non-zero to proceed. Also,
+ * callbacks should themselves check if the id they generate is unique otherwise
+ * the SSL handshake will fail with an error - callbacks can do this using the
+ * 'ssl' value they're passed by;
+ *      SSL_has_matching_session_id(ssl, id, *id_len)
+ * The length value passed in is set at the maximum size the session ID can be.
+ * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
+ * can alter this length to be less if desired, but under SSLv2 session IDs are
+ * supposed to be fixed at 16 bytes so the id will be padded after the callback
+ * returns in this case. It is also an error for the callback to set the size to
+ * zero. */
+typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
+				unsigned int *id_len);
+
+typedef struct ssl_comp_st
+	{
+	int id;
+	const char *name;
+#ifndef OPENSSL_NO_COMP
+	COMP_METHOD *method;
+#else
+	char *method;
+#endif
+	} SSL_COMP;
+
+DECLARE_STACK_OF(SSL_COMP)
+
+struct ssl_ctx_st
+	{
+	SSL_METHOD *method;
+
+	STACK_OF(SSL_CIPHER) *cipher_list;
+	/* same as above but sorted for lookup */
+	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+	struct x509_store_st /* X509_STORE */ *cert_store;
+	struct lhash_st /* LHASH */ *sessions;	/* a set of SSL_SESSIONs */
+	/* Most session-ids that will be cached, default is
+	 * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
+	unsigned long session_cache_size;
+	struct ssl_session_st *session_cache_head;
+	struct ssl_session_st *session_cache_tail;
+
+	/* This can have one of 2 values, ored together,
+	 * SSL_SESS_CACHE_CLIENT,
+	 * SSL_SESS_CACHE_SERVER,
+	 * Default is SSL_SESSION_CACHE_SERVER, which means only
+	 * SSL_accept which cache SSL_SESSIONS. */
+	int session_cache_mode;
+
+	/* If timeout is not 0, it is the default timeout value set
+	 * when SSL_new() is called.  This has been put in to make
+	 * life easier to set things up */
+	long session_timeout;
+
+	/* If this callback is not null, it will be called each
+	 * time a session id is added to the cache.  If this function
+	 * returns 1, it means that the callback will do a
+	 * SSL_SESSION_free() when it has finished using it.  Otherwise,
+	 * on 0, it means the callback has finished with it.
+	 * If remove_session_cb is not null, it will be called when
+	 * a session-id is removed from the cache.  After the call,
+	 * OpenSSL will SSL_SESSION_free() it. */
+	int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess);
+	void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess);
+	SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl,
+		unsigned char *data,int len,int *copy);
+
+	struct
+		{
+		int sess_connect;	/* SSL new conn - started */
+		int sess_connect_renegotiate;/* SSL reneg - requested */
+		int sess_connect_good;	/* SSL new conne/reneg - finished */
+		int sess_accept;	/* SSL new accept - started */
+		int sess_accept_renegotiate;/* SSL reneg - requested */
+		int sess_accept_good;	/* SSL accept/reneg - finished */
+		int sess_miss;		/* session lookup misses  */
+		int sess_timeout;	/* reuse attempt on timeouted session */
+		int sess_cache_full;	/* session removed due to full cache */
+		int sess_hit;		/* session reuse actually done */
+		int sess_cb_hit;	/* session-id that was not
+					 * in the cache was
+					 * passed back via the callback.  This
+					 * indicates that the application is
+					 * supplying session-id's from other
+					 * processes - spooky :-) */
+		} stats;
+
+	int references;
+
+	/* if defined, these override the X509_verify_cert() calls */
+	int (*app_verify_callback)(X509_STORE_CTX *, void *);
+	void *app_verify_arg;
+	/* before OpenSSL 0.9.7, 'app_verify_arg' was ignored
+	 * ('app_verify_callback' was called with just one argument) */
+
+	/* Default password callback. */
+	pem_password_cb *default_passwd_callback;
+
+	/* Default password callback user data. */
+	void *default_passwd_callback_userdata;
+
+	/* get client cert callback */
+	int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+    /* cookie generate callback */
+    int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+        unsigned int *cookie_len);
+
+    /* verify cookie callback */
+    int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+        unsigned int cookie_len);
+
+	CRYPTO_EX_DATA ex_data;
+
+	const EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */
+	const EVP_MD *md5;	/* For SSLv3/TLSv1 'ssl3-md5' */
+	const EVP_MD *sha1;   /* For SSLv3/TLSv1 'ssl3->sha1' */
+
+	STACK_OF(X509) *extra_certs;
+	STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
+
+
+	/* Default values used when no per-SSL value is defined follow */
+
+	void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */
+
+	/* what we put in client cert requests */
+	STACK_OF(X509_NAME) *client_CA;
+
+
+	/* Default values to use in SSL structures follow (these are copied by SSL_new) */
+
+	unsigned long options;
+	unsigned long mode;
+	long max_cert_list;
+
+	struct cert_st /* CERT */ *cert;
+	int read_ahead;
+
+	/* callback that allows applications to peek at protocol messages */
+	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+	void *msg_callback_arg;
+
+	int verify_mode;
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+	int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
+
+	/* Default generate session ID callback. */
+	GEN_SESSION_CB generate_session_id;
+
+	X509_VERIFY_PARAM *param;
+
+#if 0
+	int purpose;		/* Purpose setting */
+	int trust;		/* Trust setting */
+#endif
+
+	int quiet_shutdown;
+	};
+
+#define SSL_SESS_CACHE_OFF			0x0000
+#define SSL_SESS_CACHE_CLIENT			0x0001
+#define SSL_SESS_CACHE_SERVER			0x0002
+#define SSL_SESS_CACHE_BOTH	(SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
+#define SSL_SESS_CACHE_NO_AUTO_CLEAR		0x0080
+/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
+#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP	0x0100
+#define SSL_SESS_CACHE_NO_INTERNAL_STORE	0x0200
+#define SSL_SESS_CACHE_NO_INTERNAL \
+	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+  struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
+#define SSL_CTX_sess_number(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
+#define SSL_CTX_sess_connect(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
+#define SSL_CTX_sess_connect_good(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
+#define SSL_CTX_sess_connect_renegotiate(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
+#define SSL_CTX_sess_accept(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
+#define SSL_CTX_sess_accept_renegotiate(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
+#define SSL_CTX_sess_accept_good(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
+#define SSL_CTX_sess_hits(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
+#define SSL_CTX_sess_cb_hits(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
+#define SSL_CTX_sess_misses(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
+#define SSL_CTX_sess_timeouts(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
+#define SSL_CTX_sess_cache_full(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess));
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,int len,int *copy));
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *Data, int len, int *copy);
+void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,int val));
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
+
+#define SSL_NOTHING	1
+#define SSL_WRITING	2
+#define SSL_READING	3
+#define SSL_X509_LOOKUP	4
+
+/* These will only be used when doing non-blocking IO */
+#define SSL_want_nothing(s)	(SSL_want(s) == SSL_NOTHING)
+#define SSL_want_read(s)	(SSL_want(s) == SSL_READING)
+#define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
+#define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
+
+struct ssl_st
+	{
+	/* protocol version
+	 * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION)
+	 */
+	int version;
+	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
+
+	SSL_METHOD *method; /* SSLv3 */
+
+	/* There are 2 BIO's even though they are normally both the
+	 * same.  This is so data can be read and written to different
+	 * handlers */
+
+#ifndef OPENSSL_NO_BIO
+	BIO *rbio; /* used by SSL_read */
+	BIO *wbio; /* used by SSL_write */
+	BIO *bbio; /* used during session-id reuse to concatenate
+		    * messages */
+#else
+	char *rbio; /* used by SSL_read */
+	char *wbio; /* used by SSL_write */
+	char *bbio;
+#endif
+	/* This holds a variable that indicates what we were doing
+	 * when a 0 or -1 is returned.  This is needed for
+	 * non-blocking IO so we know what request needs re-doing when
+	 * in SSL_accept or SSL_connect */
+	int rwstate;
+
+	/* true when we are actually in SSL_accept() or SSL_connect() */
+	int in_handshake;
+	int (*handshake_func)(SSL *);
+
+	/* Imagine that here's a boolean member "init" that is
+	 * switched as soon as SSL_set_{accept/connect}_state
+	 * is called for the first time, so that "state" and
+	 * "handshake_func" are properly initialized.  But as
+	 * handshake_func is == 0 until then, we use this
+	 * test instead of an "init" member.
+	 */
+
+	int server;	/* are we the server side? - mostly used by SSL_clear*/
+
+	int new_session;/* 1 if we are to use a new session.
+	                 * 2 if we are a server and are inside a handshake
+	                 *   (i.e. not just sending a HelloRequest)
+	                 * NB: For servers, the 'new' session may actually be a previously
+	                 * cached session or even the previous session unless
+	                 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
+	int quiet_shutdown;/* don't send shutdown packets */
+	int shutdown;	/* we have shut things down, 0x01 sent, 0x02
+			 * for received */
+	int state;	/* where we are */
+	int rstate;	/* where we are when reading */
+
+	BUF_MEM *init_buf;	/* buffer used during init */
+	void *init_msg;   	/* pointer to handshake message body, set by ssl3_get_message() */
+	int init_num;		/* amount read/written */
+	int init_off;		/* amount read/written */
+
+	/* used internally to point at a raw packet */
+	unsigned char *packet;
+	unsigned int packet_length;
+
+	struct ssl2_state_st *s2; /* SSLv2 variables */
+	struct ssl3_state_st *s3; /* SSLv3 variables */
+	struct dtls1_state_st *d1; /* DTLSv1 variables */
+
+	int read_ahead;		/* Read as many input bytes as possible
+	               	 	 * (for non-blocking reads) */
+
+	/* callback that allows applications to peek at protocol messages */
+	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+	void *msg_callback_arg;
+
+	int hit;		/* reusing a previous session */
+
+	X509_VERIFY_PARAM *param;
+
+#if 0
+	int purpose;		/* Purpose setting */
+	int trust;		/* Trust setting */
+#endif
+
+	/* crypto */
+	STACK_OF(SSL_CIPHER) *cipher_list;
+	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+	/* These are the ones being used, the ones in SSL_SESSION are
+	 * the ones to be 'copied' into these ones */
+
+	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
+	const EVP_MD *read_hash;		/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *expand;			/* uncompress */
+#else
+	char *expand;
+#endif
+
+	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
+	const EVP_MD *write_hash;		/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *compress;			/* compression */
+#else
+	char *compress;	
+#endif
+
+	/* session info */
+
+	/* client cert? */
+	/* This is used to hold the server certificate used */
+	struct cert_st /* CERT */ *cert;
+
+	/* the session_id_context is used to ensure sessions are only reused
+	 * in the appropriate context */
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+	/* This can also be in the session once a session is established */
+	SSL_SESSION *session;
+
+	/* Default generate session ID callback. */
+	GEN_SESSION_CB generate_session_id;
+
+	/* Used in SSL2 and SSL3 */
+	int verify_mode;	/* 0 don't care about verify failure.
+				 * 1 fail if verify fails */
+	int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */
+
+	void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */
+
+	int error;		/* error bytes to be written */
+	int error_code;		/* actual code */
+
+#ifndef OPENSSL_NO_KRB5
+	KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */
+#endif	/* OPENSSL_NO_KRB5 */
+
+	SSL_CTX *ctx;
+	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
+	 * and SSL_write() calls, good for nbio debuging :-) */
+	int debug;	
+
+	/* extra application data */
+	long verify_result;
+	CRYPTO_EX_DATA ex_data;
+
+	/* for server side, keep the list of CA_dn we can use */
+	STACK_OF(X509_NAME) *client_CA;
+
+	int references;
+	unsigned long options; /* protocol behaviour */
+	unsigned long mode; /* API behaviour */
+	long max_cert_list;
+	int first_packet;
+	int client_version;	/* what was passed, used for
+				 * SSLv3/TLS rollback check */
+	};
+
+#ifdef __cplusplus
+}
+#endif
+
+#include 
+#include 
+#include  /* This is mostly sslv3 with a few tweaks */
+#include  /* Datagram TLS */
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* compatibility */
+#define SSL_set_app_data(s,arg)		(SSL_set_ex_data(s,0,(char *)arg))
+#define SSL_get_app_data(s)		(SSL_get_ex_data(s,0))
+#define SSL_SESSION_set_app_data(s,a)	(SSL_SESSION_set_ex_data(s,0,(char *)a))
+#define SSL_SESSION_get_app_data(s)	(SSL_SESSION_get_ex_data(s,0))
+#define SSL_CTX_get_app_data(ctx)	(SSL_CTX_get_ex_data(ctx,0))
+#define SSL_CTX_set_app_data(ctx,arg)	(SSL_CTX_set_ex_data(ctx,0,(char *)arg))
+
+/* The following are the possible values for ssl->state are are
+ * used to indicate where we are up to in the SSL connection establishment.
+ * The macros that follow are about the only things you should need to use
+ * and even then, only when using non-blocking IO.
+ * It can also be useful to work out where you were when the connection
+ * failed */
+
+#define SSL_ST_CONNECT			0x1000
+#define SSL_ST_ACCEPT			0x2000
+#define SSL_ST_MASK			0x0FFF
+#define SSL_ST_INIT			(SSL_ST_CONNECT|SSL_ST_ACCEPT)
+#define SSL_ST_BEFORE			0x4000
+#define SSL_ST_OK			0x03
+#define SSL_ST_RENEGOTIATE		(0x04|SSL_ST_INIT)
+
+#define SSL_CB_LOOP			0x01
+#define SSL_CB_EXIT			0x02
+#define SSL_CB_READ			0x04
+#define SSL_CB_WRITE			0x08
+#define SSL_CB_ALERT			0x4000 /* used in callback */
+#define SSL_CB_READ_ALERT		(SSL_CB_ALERT|SSL_CB_READ)
+#define SSL_CB_WRITE_ALERT		(SSL_CB_ALERT|SSL_CB_WRITE)
+#define SSL_CB_ACCEPT_LOOP		(SSL_ST_ACCEPT|SSL_CB_LOOP)
+#define SSL_CB_ACCEPT_EXIT		(SSL_ST_ACCEPT|SSL_CB_EXIT)
+#define SSL_CB_CONNECT_LOOP		(SSL_ST_CONNECT|SSL_CB_LOOP)
+#define SSL_CB_CONNECT_EXIT		(SSL_ST_CONNECT|SSL_CB_EXIT)
+#define SSL_CB_HANDSHAKE_START		0x10
+#define SSL_CB_HANDSHAKE_DONE		0x20
+
+/* Is the SSL_connection established? */
+#define SSL_get_state(a)		SSL_state(a)
+#define SSL_is_init_finished(a)		(SSL_state(a) == SSL_ST_OK)
+#define SSL_in_init(a)			(SSL_state(a)&SSL_ST_INIT)
+#define SSL_in_before(a)		(SSL_state(a)&SSL_ST_BEFORE)
+#define SSL_in_connect_init(a)		(SSL_state(a)&SSL_ST_CONNECT)
+#define SSL_in_accept_init(a)		(SSL_state(a)&SSL_ST_ACCEPT)
+
+/* The following 2 states are kept in ssl->rstate when reads fail,
+ * you should not need these */
+#define SSL_ST_READ_HEADER			0xF0
+#define SSL_ST_READ_BODY			0xF1
+#define SSL_ST_READ_DONE			0xF2
+
+/* Obtain latest Finished message
+ *   -- that we sent (SSL_get_finished)
+ *   -- that we expected from peer (SSL_get_peer_finished).
+ * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+
+/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options
+ * are 'ored' with SSL_VERIFY_PEER if they are desired */
+#define SSL_VERIFY_NONE			0x00
+#define SSL_VERIFY_PEER			0x01
+#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT	0x02
+#define SSL_VERIFY_CLIENT_ONCE		0x04
+
+#define OpenSSL_add_ssl_algorithms()	SSL_library_init()
+#define SSLeay_add_ssl_algorithms()	SSL_library_init()
+
+/* this is for backward compatibility */
+#if 0 /* NEW_SSLEAY */
+#define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
+#define SSL_set_pref_cipher(c,n)	SSL_set_cipher_list(c,n)
+#define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
+#define SSL_remove_session(a,b)		SSL_CTX_remove_session((a),(b))
+#define SSL_flush_sessions(a,b)		SSL_CTX_flush_sessions((a),(b))
+#endif
+/* More backward compatibility */
+#define SSL_get_cipher(s) \
+		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+#define SSL_get_cipher_bits(s,np) \
+		SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
+#define SSL_get_cipher_version(s) \
+		SSL_CIPHER_get_version(SSL_get_current_cipher(s))
+#define SSL_get_cipher_name(s) \
+		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+#define SSL_get_time(a)		SSL_SESSION_get_time(a)
+#define SSL_set_time(a,b)	SSL_SESSION_set_time((a),(b))
+#define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
+#define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
+
+#if 1 /*SSLEAY_MACROS*/
+#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
+#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
+#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
+	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
+#define PEM_read_bio_SSL_SESSION(bp,x,cb,u) PEM_ASN1_read_bio_of(SSL_SESSION,d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,cb,u)
+#define PEM_write_SSL_SESSION(fp,x) \
+	PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
+		PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_SSL_SESSION(bp,x) \
+	PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
+#endif
+
+#define SSL_AD_REASON_OFFSET		1000
+/* These alert types are for SSLv3 and TLSv1 */
+#define SSL_AD_CLOSE_NOTIFY		SSL3_AD_CLOSE_NOTIFY
+#define SSL_AD_UNEXPECTED_MESSAGE	SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
+#define SSL_AD_BAD_RECORD_MAC		SSL3_AD_BAD_RECORD_MAC     /* fatal */
+#define SSL_AD_DECRYPTION_FAILED	TLS1_AD_DECRYPTION_FAILED
+#define SSL_AD_RECORD_OVERFLOW		TLS1_AD_RECORD_OVERFLOW
+#define SSL_AD_DECOMPRESSION_FAILURE	SSL3_AD_DECOMPRESSION_FAILURE/* fatal */
+#define SSL_AD_HANDSHAKE_FAILURE	SSL3_AD_HANDSHAKE_FAILURE/* fatal */
+#define SSL_AD_NO_CERTIFICATE		SSL3_AD_NO_CERTIFICATE /* Not for TLS */
+#define SSL_AD_BAD_CERTIFICATE		SSL3_AD_BAD_CERTIFICATE
+#define SSL_AD_UNSUPPORTED_CERTIFICATE	SSL3_AD_UNSUPPORTED_CERTIFICATE
+#define SSL_AD_CERTIFICATE_REVOKED	SSL3_AD_CERTIFICATE_REVOKED
+#define SSL_AD_CERTIFICATE_EXPIRED	SSL3_AD_CERTIFICATE_EXPIRED
+#define SSL_AD_CERTIFICATE_UNKNOWN	SSL3_AD_CERTIFICATE_UNKNOWN
+#define SSL_AD_ILLEGAL_PARAMETER	SSL3_AD_ILLEGAL_PARAMETER   /* fatal */
+#define SSL_AD_UNKNOWN_CA		TLS1_AD_UNKNOWN_CA	/* fatal */
+#define SSL_AD_ACCESS_DENIED		TLS1_AD_ACCESS_DENIED	/* fatal */
+#define SSL_AD_DECODE_ERROR		TLS1_AD_DECODE_ERROR	/* fatal */
+#define SSL_AD_DECRYPT_ERROR		TLS1_AD_DECRYPT_ERROR
+#define SSL_AD_EXPORT_RESTRICTION	TLS1_AD_EXPORT_RESTRICTION/* fatal */
+#define SSL_AD_PROTOCOL_VERSION		TLS1_AD_PROTOCOL_VERSION /* fatal */
+#define SSL_AD_INSUFFICIENT_SECURITY	TLS1_AD_INSUFFICIENT_SECURITY/* fatal */
+#define SSL_AD_INTERNAL_ERROR		TLS1_AD_INTERNAL_ERROR	/* fatal */
+#define SSL_AD_USER_CANCELLED		TLS1_AD_USER_CANCELLED
+#define SSL_AD_NO_RENEGOTIATION		TLS1_AD_NO_RENEGOTIATION
+
+#define SSL_ERROR_NONE			0
+#define SSL_ERROR_SSL			1
+#define SSL_ERROR_WANT_READ		2
+#define SSL_ERROR_WANT_WRITE		3
+#define SSL_ERROR_WANT_X509_LOOKUP	4
+#define SSL_ERROR_SYSCALL		5 /* look at error stack/return value/errno */
+#define SSL_ERROR_ZERO_RETURN		6
+#define SSL_ERROR_WANT_CONNECT		7
+#define SSL_ERROR_WANT_ACCEPT		8
+
+#define SSL_CTRL_NEED_TMP_RSA			1
+#define SSL_CTRL_SET_TMP_RSA			2
+#define SSL_CTRL_SET_TMP_DH			3
+#define SSL_CTRL_SET_TMP_ECDH			4
+#define SSL_CTRL_SET_TMP_RSA_CB			5
+#define SSL_CTRL_SET_TMP_DH_CB			6
+#define SSL_CTRL_SET_TMP_ECDH_CB		7
+
+#define SSL_CTRL_GET_SESSION_REUSED		8
+#define SSL_CTRL_GET_CLIENT_CERT_REQUEST	9
+#define SSL_CTRL_GET_NUM_RENEGOTIATIONS		10
+#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS	11
+#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS	12
+#define SSL_CTRL_GET_FLAGS			13
+#define SSL_CTRL_EXTRA_CHAIN_CERT		14
+
+#define SSL_CTRL_SET_MSG_CALLBACK               15
+#define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
+
+/* only applies to datagram connections */
+#define SSL_CTRL_SET_MTU                17
+/* Stats */
+#define SSL_CTRL_SESS_NUMBER			20
+#define SSL_CTRL_SESS_CONNECT			21
+#define SSL_CTRL_SESS_CONNECT_GOOD		22
+#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE	23
+#define SSL_CTRL_SESS_ACCEPT			24
+#define SSL_CTRL_SESS_ACCEPT_GOOD		25
+#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE	26
+#define SSL_CTRL_SESS_HIT			27
+#define SSL_CTRL_SESS_CB_HIT			28
+#define SSL_CTRL_SESS_MISSES			29
+#define SSL_CTRL_SESS_TIMEOUTS			30
+#define SSL_CTRL_SESS_CACHE_FULL		31
+#define SSL_CTRL_OPTIONS			32
+#define SSL_CTRL_MODE				33
+
+#define SSL_CTRL_GET_READ_AHEAD			40
+#define SSL_CTRL_SET_READ_AHEAD			41
+#define SSL_CTRL_SET_SESS_CACHE_SIZE		42
+#define SSL_CTRL_GET_SESS_CACHE_SIZE		43
+#define SSL_CTRL_SET_SESS_CACHE_MODE		44
+#define SSL_CTRL_GET_SESS_CACHE_MODE		45
+
+#define SSL_CTRL_GET_MAX_CERT_LIST		50
+#define SSL_CTRL_SET_MAX_CERT_LIST		51
+
+#define SSL_session_reused(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
+#define SSL_num_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
+#define SSL_clear_num_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
+#define SSL_total_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
+
+#define SSL_CTX_need_tmp_RSA(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+#define SSL_CTX_set_tmp_rsa(ctx,rsa) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+#define SSL_CTX_set_tmp_dh(ctx,dh) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
+#define SSL_need_tmp_RSA(ssl) \
+	SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+#define SSL_set_tmp_rsa(ssl,rsa) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+#define SSL_set_tmp_dh(ssl,dh) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+#define SSL_set_tmp_ecdh(ssl,ecdh) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
+#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_ssl(void);
+BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+int BIO_ssl_copy_session_id(BIO *to,BIO *from);
+void BIO_ssl_shutdown(BIO *ssl_bio);
+
+#endif
+
+int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
+SSL_CTX *SSL_CTX_new(SSL_METHOD *meth);
+void	SSL_CTX_free(SSL_CTX *);
+long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
+long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *);
+int SSL_want(const SSL *s);
+int	SSL_clear(SSL *s);
+
+void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
+
+SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
+char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
+const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
+
+int	SSL_get_fd(const SSL *s);
+int	SSL_get_rfd(const SSL *s);
+int	SSL_get_wfd(const SSL *s);
+const char  * SSL_get_cipher_list(const SSL *s,int n);
+char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+int	SSL_get_read_ahead(const SSL * s);
+int	SSL_pending(const SSL *s);
+#ifndef OPENSSL_NO_SOCK
+int	SSL_set_fd(SSL *s, int fd);
+int	SSL_set_rfd(SSL *s, int fd);
+int	SSL_set_wfd(SSL *s, int fd);
+#endif
+#ifndef OPENSSL_NO_BIO
+void	SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio);
+BIO *	SSL_get_rbio(const SSL *s);
+BIO *	SSL_get_wbio(const SSL *s);
+#endif
+int	SSL_set_cipher_list(SSL *s, const char *str);
+void	SSL_set_read_ahead(SSL *s, int yes);
+int	SSL_get_verify_mode(const SSL *s);
+int	SSL_get_verify_depth(const SSL *s);
+int	(*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
+void	SSL_set_verify(SSL *s, int mode,
+		       int (*callback)(int ok,X509_STORE_CTX *ctx));
+void	SSL_set_verify_depth(SSL *s, int depth);
+#ifndef OPENSSL_NO_RSA
+int	SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+#endif
+int	SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
+int	SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
+int	SSL_use_certificate(SSL *ssl, X509 *x);
+int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+
+#ifndef OPENSSL_NO_STDIO
+int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+int	SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+int	SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+int	SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+int	SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+					    const char *file);
+#ifndef OPENSSL_SYS_VMS
+#ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
+int	SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+					   const char *dir);
+#endif
+#endif
+
+#endif
+
+void	SSL_load_error_strings(void );
+const char *SSL_state_string(const SSL *s);
+const char *SSL_rstate_string(const SSL *s);
+const char *SSL_state_string_long(const SSL *s);
+const char *SSL_rstate_string_long(const SSL *s);
+long	SSL_SESSION_get_time(const SSL_SESSION *s);
+long	SSL_SESSION_set_time(SSL_SESSION *s, long t);
+long	SSL_SESSION_get_timeout(const SSL_SESSION *s);
+long	SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
+void	SSL_copy_session_id(SSL *to,const SSL *from);
+
+SSL_SESSION *SSL_SESSION_new(void);
+unsigned long SSL_SESSION_hash(const SSL_SESSION *a);
+int	SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len);
+#ifndef OPENSSL_NO_FP_API
+int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
+#endif
+#ifndef OPENSSL_NO_BIO
+int	SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
+#endif
+void	SSL_SESSION_free(SSL_SESSION *ses);
+int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
+int	SSL_set_session(SSL *to, SSL_SESSION *session);
+int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
+int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+int	SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
+int	SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+					unsigned int id_len);
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp,
+			     long length);
+
+#ifdef HEADER_X509_H
+X509 *	SSL_get_peer_certificate(const SSL *s);
+#endif
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *);
+void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
+			int (*callback)(int, X509_STORE_CTX *));
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
+#ifndef OPENSSL_NO_RSA
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+#endif
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
+	const unsigned char *d, long len);
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+
+int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+int SSL_check_private_key(const SSL *ctx);
+
+int	SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
+				       unsigned int sid_ctx_len);
+
+SSL *	SSL_new(SSL_CTX *ctx);
+int	SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
+				   unsigned int sid_ctx_len);
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
+int SSL_set_purpose(SSL *s, int purpose);
+int SSL_CTX_set_trust(SSL_CTX *s, int trust);
+int SSL_set_trust(SSL *s, int trust);
+
+void	SSL_free(SSL *ssl);
+int 	SSL_accept(SSL *ssl);
+int 	SSL_connect(SSL *ssl);
+int 	SSL_read(SSL *ssl,void *buf,int num);
+int 	SSL_peek(SSL *ssl,void *buf,int num);
+int 	SSL_write(SSL *ssl,const void *buf,int num);
+long	SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
+long	SSL_callback_ctrl(SSL *, int, void (*)(void));
+long	SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg);
+long	SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+
+int	SSL_get_error(const SSL *s,int ret_code);
+const char *SSL_get_version(const SSL *s);
+
+/* This sets the 'default' SSL version that SSL_new() will create */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth);
+
+SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
+SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
+SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+
+SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+
+SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
+SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
+SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+
+SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
+SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
+SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+
+SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
+SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
+SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
+
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+
+int SSL_do_handshake(SSL *s);
+int SSL_renegotiate(SSL *s);
+int SSL_renegotiate_pending(SSL *s);
+int SSL_shutdown(SSL *s);
+
+SSL_METHOD *SSL_get_ssl_method(SSL *s);
+int SSL_set_ssl_method(SSL *s,SSL_METHOD *method);
+const char *SSL_alert_type_string_long(int value);
+const char *SSL_alert_type_string(int value);
+const char *SSL_alert_desc_string_long(int value);
+const char *SSL_alert_desc_string(int value);
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+int SSL_add_client_CA(SSL *ssl,X509 *x);
+int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+
+void SSL_set_connect_state(SSL *s);
+void SSL_set_accept_state(SSL *s);
+
+long SSL_get_default_timeout(const SSL *s);
+
+int SSL_library_init(void );
+
+char *SSL_CIPHER_description(SSL_CIPHER *,char *buf,int size);
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+
+SSL *SSL_dup(SSL *ssl);
+
+X509 *SSL_get_certificate(const SSL *ssl);
+/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl);
+
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode);
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+void SSL_set_quiet_shutdown(SSL *ssl,int mode);
+int SSL_get_quiet_shutdown(const SSL *ssl);
+void SSL_set_shutdown(SSL *ssl,int mode);
+int SSL_get_shutdown(const SSL *ssl);
+int SSL_version(const SSL *ssl);
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+	const char *CApath);
+#define SSL_get0_session SSL_get_session /* just peek at pointer */
+SSL_SESSION *SSL_get_session(const SSL *ssl);
+SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+void SSL_set_info_callback(SSL *ssl,
+			   void (*cb)(const SSL *ssl,int type,int val));
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
+int SSL_state(const SSL *ssl);
+
+void SSL_set_verify_result(SSL *ssl,long v);
+long SSL_get_verify_result(const SSL *ssl);
+
+int SSL_set_ex_data(SSL *ssl,int idx,void *data);
+void *SSL_get_ex_data(const SSL *ssl,int idx);
+int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data);
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx);
+int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx);
+int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_get_ex_data_X509_STORE_CTX_idx(void );
+
+#define SSL_CTX_sess_set_cache_size(ctx,t) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+#define SSL_CTX_sess_get_cache_size(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
+#define SSL_CTX_set_session_cache_mode(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+#define SSL_CTX_get_session_cache_mode(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
+
+#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
+#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
+#define SSL_CTX_get_read_ahead(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
+#define SSL_CTX_set_read_ahead(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
+#define SSL_CTX_get_max_cert_list(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_CTX_set_max_cert_list(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+#define SSL_get_max_cert_list(ssl) \
+	SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_set_max_cert_list(ssl,m) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+
+     /* NB: the keylength is only applicable when is_export is true */
+#ifndef OPENSSL_NO_RSA
+void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
+				  RSA *(*cb)(SSL *ssl,int is_export,
+					     int keylength));
+
+void SSL_set_tmp_rsa_callback(SSL *ssl,
+				  RSA *(*cb)(SSL *ssl,int is_export,
+					     int keylength));
+#endif
+#ifndef OPENSSL_NO_DH
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+				 DH *(*dh)(SSL *ssl,int is_export,
+					   int keylength));
+void SSL_set_tmp_dh_callback(SSL *ssl,
+				 DH *(*dh)(SSL *ssl,int is_export,
+					   int keylength));
+#endif
+#ifndef OPENSSL_NO_ECDH
+void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
+				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+					   int keylength));
+void SSL_set_tmp_ecdh_callback(SSL *ssl,
+				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+					   int keylength));
+#endif
+
+#ifndef OPENSSL_NO_COMP
+const COMP_METHOD *SSL_get_current_compression(SSL *s);
+const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id,COMP_METHOD *cm);
+#else
+const void *SSL_get_current_compression(SSL *s);
+const void *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const void *comp);
+void *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id,void *cm);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_SSL_strings(void);
+
+/* Error codes for the SSL functions. */
+
+/* Function codes. */
+#define SSL_F_CLIENT_CERTIFICATE			 100
+#define SSL_F_CLIENT_FINISHED				 167
+#define SSL_F_CLIENT_HELLO				 101
+#define SSL_F_CLIENT_MASTER_KEY				 102
+#define SSL_F_D2I_SSL_SESSION				 103
+#define SSL_F_DO_DTLS1_WRITE				 245
+#define SSL_F_DO_SSL3_WRITE				 104
+#define SSL_F_DTLS1_ACCEPT				 246
+#define SSL_F_DTLS1_BUFFER_RECORD			 247
+#define SSL_F_DTLS1_CLIENT_HELLO			 248
+#define SSL_F_DTLS1_CONNECT				 249
+#define SSL_F_DTLS1_ENC					 250
+#define SSL_F_DTLS1_GET_HELLO_VERIFY			 251
+#define SSL_F_DTLS1_GET_MESSAGE				 252
+#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT		 253
+#define SSL_F_DTLS1_GET_RECORD				 254
+#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
+#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 256
+#define SSL_F_DTLS1_PROCESS_RECORD			 257
+#define SSL_F_DTLS1_READ_BYTES				 258
+#define SSL_F_DTLS1_READ_FAILED				 259
+#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST		 260
+#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE		 261
+#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE		 262
+#define SSL_F_DTLS1_SEND_CLIENT_VERIFY			 263
+#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST		 264
+#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE		 265
+#define SSL_F_DTLS1_SEND_SERVER_HELLO			 266
+#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE		 267
+#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES		 268
+#define SSL_F_GET_CLIENT_FINISHED			 105
+#define SSL_F_GET_CLIENT_HELLO				 106
+#define SSL_F_GET_CLIENT_MASTER_KEY			 107
+#define SSL_F_GET_SERVER_FINISHED			 108
+#define SSL_F_GET_SERVER_HELLO				 109
+#define SSL_F_GET_SERVER_VERIFY				 110
+#define SSL_F_I2D_SSL_SESSION				 111
+#define SSL_F_READ_N					 112
+#define SSL_F_REQUEST_CERTIFICATE			 113
+#define SSL_F_SERVER_FINISH				 239
+#define SSL_F_SERVER_HELLO				 114
+#define SSL_F_SERVER_VERIFY				 240
+#define SSL_F_SSL23_ACCEPT				 115
+#define SSL_F_SSL23_CLIENT_HELLO			 116
+#define SSL_F_SSL23_CONNECT				 117
+#define SSL_F_SSL23_GET_CLIENT_HELLO			 118
+#define SSL_F_SSL23_GET_SERVER_HELLO			 119
+#define SSL_F_SSL23_PEEK				 237
+#define SSL_F_SSL23_READ				 120
+#define SSL_F_SSL23_WRITE				 121
+#define SSL_F_SSL2_ACCEPT				 122
+#define SSL_F_SSL2_CONNECT				 123
+#define SSL_F_SSL2_ENC_INIT				 124
+#define SSL_F_SSL2_GENERATE_KEY_MATERIAL		 241
+#define SSL_F_SSL2_PEEK					 234
+#define SSL_F_SSL2_READ					 125
+#define SSL_F_SSL2_READ_INTERNAL			 236
+#define SSL_F_SSL2_SET_CERTIFICATE			 126
+#define SSL_F_SSL2_WRITE				 127
+#define SSL_F_SSL3_ACCEPT				 128
+#define SSL_F_SSL3_CALLBACK_CTRL			 233
+#define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
+#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
+#define SSL_F_SSL3_CLIENT_HELLO				 131
+#define SSL_F_SSL3_CONNECT				 132
+#define SSL_F_SSL3_CTRL					 213
+#define SSL_F_SSL3_CTX_CTRL				 133
+#define SSL_F_SSL3_ENC					 134
+#define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
+#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
+#define SSL_F_SSL3_GET_CERT_VERIFY			 136
+#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE		 137
+#define SSL_F_SSL3_GET_CLIENT_HELLO			 138
+#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE		 139
+#define SSL_F_SSL3_GET_FINISHED				 140
+#define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
+#define SSL_F_SSL3_GET_MESSAGE				 142
+#define SSL_F_SSL3_GET_RECORD				 143
+#define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
+#define SSL_F_SSL3_GET_SERVER_DONE			 145
+#define SSL_F_SSL3_GET_SERVER_HELLO			 146
+#define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
+#define SSL_F_SSL3_PEEK					 235
+#define SSL_F_SSL3_READ_BYTES				 148
+#define SSL_F_SSL3_READ_N				 149
+#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST		 150
+#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE		 151
+#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE		 152
+#define SSL_F_SSL3_SEND_CLIENT_VERIFY			 153
+#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE		 154
+#define SSL_F_SSL3_SEND_SERVER_HELLO			 242
+#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE		 155
+#define SSL_F_SSL3_SETUP_BUFFERS			 156
+#define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
+#define SSL_F_SSL3_WRITE_BYTES				 158
+#define SSL_F_SSL3_WRITE_PENDING			 159
+#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
+#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
+#define SSL_F_SSL_BAD_METHOD				 160
+#define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
+#define SSL_F_SSL_CERT_DUP				 221
+#define SSL_F_SSL_CERT_INST				 222
+#define SSL_F_SSL_CERT_INSTANTIATE			 214
+#define SSL_F_SSL_CERT_NEW				 162
+#define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
+#define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
+#define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
+#define SSL_F_SSL_CLEAR					 164
+#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD		 165
+#define SSL_F_SSL_CREATE_CIPHER_LIST			 166
+#define SSL_F_SSL_CTRL					 232
+#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY			 168
+#define SSL_F_SSL_CTX_NEW				 169
+#define SSL_F_SSL_CTX_SET_CIPHER_LIST			 269
+#define SSL_F_SSL_CTX_SET_PURPOSE			 226
+#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT		 219
+#define SSL_F_SSL_CTX_SET_SSL_VERSION			 170
+#define SSL_F_SSL_CTX_SET_TRUST				 229
+#define SSL_F_SSL_CTX_USE_CERTIFICATE			 171
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1		 172
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE	 220
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE		 173
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY			 174
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1		 175
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE		 176
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY			 177
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1		 178
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE		 179
+#define SSL_F_SSL_DO_HANDSHAKE				 180
+#define SSL_F_SSL_GET_NEW_SESSION			 181
+#define SSL_F_SSL_GET_PREV_SESSION			 217
+#define SSL_F_SSL_GET_SERVER_SEND_CERT			 182
+#define SSL_F_SSL_GET_SIGN_PKEY				 183
+#define SSL_F_SSL_INIT_WBIO_BUFFER			 184
+#define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
+#define SSL_F_SSL_NEW					 186
+#define SSL_F_SSL_PEEK					 270
+#define SSL_F_SSL_READ					 223
+#define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
+#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
+#define SSL_F_SSL_SESSION_NEW				 189
+#define SSL_F_SSL_SESSION_PRINT_FP			 190
+#define SSL_F_SSL_SESS_CERT_NEW				 225
+#define SSL_F_SSL_SET_CERT				 191
+#define SSL_F_SSL_SET_CIPHER_LIST			 271
+#define SSL_F_SSL_SET_FD				 192
+#define SSL_F_SSL_SET_PKEY				 193
+#define SSL_F_SSL_SET_PURPOSE				 227
+#define SSL_F_SSL_SET_RFD				 194
+#define SSL_F_SSL_SET_SESSION				 195
+#define SSL_F_SSL_SET_SESSION_ID_CONTEXT		 218
+#define SSL_F_SSL_SET_TRUST				 228
+#define SSL_F_SSL_SET_WFD				 196
+#define SSL_F_SSL_SHUTDOWN				 224
+#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION		 243
+#define SSL_F_SSL_UNDEFINED_FUNCTION			 197
+#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
+#define SSL_F_SSL_USE_CERTIFICATE			 198
+#define SSL_F_SSL_USE_CERTIFICATE_ASN1			 199
+#define SSL_F_SSL_USE_CERTIFICATE_FILE			 200
+#define SSL_F_SSL_USE_PRIVATEKEY			 201
+#define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
+#define SSL_F_SSL_USE_PRIVATEKEY_FILE			 203
+#define SSL_F_SSL_USE_RSAPRIVATEKEY			 204
+#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1		 205
+#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE		 206
+#define SSL_F_SSL_VERIFY_CERT_CHAIN			 207
+#define SSL_F_SSL_WRITE					 208
+#define SSL_F_TLS1_CHANGE_CIPHER_STATE			 209
+#define SSL_F_TLS1_ENC					 210
+#define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
+#define SSL_F_WRITE_PENDING				 212
+
+/* Reason codes. */
+#define SSL_R_APP_DATA_IN_HANDSHAKE			 100
+#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
+#define SSL_R_BAD_ALERT_RECORD				 101
+#define SSL_R_BAD_AUTHENTICATION_TYPE			 102
+#define SSL_R_BAD_CHANGE_CIPHER_SPEC			 103
+#define SSL_R_BAD_CHECKSUM				 104
+#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK		 106
+#define SSL_R_BAD_DECOMPRESSION				 107
+#define SSL_R_BAD_DH_G_LENGTH				 108
+#define SSL_R_BAD_DH_PUB_KEY_LENGTH			 109
+#define SSL_R_BAD_DH_P_LENGTH				 110
+#define SSL_R_BAD_DIGEST_LENGTH				 111
+#define SSL_R_BAD_DSA_SIGNATURE				 112
+#define SSL_R_BAD_ECC_CERT				 304
+#define SSL_R_BAD_ECDSA_SIGNATURE			 305
+#define SSL_R_BAD_ECPOINT				 306
+#define SSL_R_BAD_HELLO_REQUEST				 105
+#define SSL_R_BAD_LENGTH				 271
+#define SSL_R_BAD_MAC_DECODE				 113
+#define SSL_R_BAD_MESSAGE_TYPE				 114
+#define SSL_R_BAD_PACKET_LENGTH				 115
+#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER		 116
+#define SSL_R_BAD_RESPONSE_ARGUMENT			 117
+#define SSL_R_BAD_RSA_DECRYPT				 118
+#define SSL_R_BAD_RSA_ENCRYPT				 119
+#define SSL_R_BAD_RSA_E_LENGTH				 120
+#define SSL_R_BAD_RSA_MODULUS_LENGTH			 121
+#define SSL_R_BAD_RSA_SIGNATURE				 122
+#define SSL_R_BAD_SIGNATURE				 123
+#define SSL_R_BAD_SSL_FILETYPE				 124
+#define SSL_R_BAD_SSL_SESSION_ID_LENGTH			 125
+#define SSL_R_BAD_STATE					 126
+#define SSL_R_BAD_WRITE_RETRY				 127
+#define SSL_R_BIO_NOT_SET				 128
+#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG			 129
+#define SSL_R_BN_LIB					 130
+#define SSL_R_CA_DN_LENGTH_MISMATCH			 131
+#define SSL_R_CA_DN_TOO_LONG				 132
+#define SSL_R_CCS_RECEIVED_EARLY			 133
+#define SSL_R_CERTIFICATE_VERIFY_FAILED			 134
+#define SSL_R_CERT_LENGTH_MISMATCH			 135
+#define SSL_R_CHALLENGE_IS_DIFFERENT			 136
+#define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
+#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
+#define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
+#define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
+#define SSL_R_COMPRESSION_FAILURE			 141
+#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	 307
+#define SSL_R_COMPRESSION_LIBRARY_ERROR			 142
+#define SSL_R_CONNECTION_ID_IS_DIFFERENT		 143
+#define SSL_R_CONNECTION_TYPE_NOT_SET			 144
+#define SSL_R_COOKIE_MISMATCH				 308
+#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED		 145
+#define SSL_R_DATA_LENGTH_TOO_LONG			 146
+#define SSL_R_DECRYPTION_FAILED				 147
+#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 281
+#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
+#define SSL_R_DIGEST_CHECK_FAILED			 149
+#define SSL_R_DUPLICATE_COMPRESSION_ID			 309
+#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER		 310
+#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG			 150
+#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY		 282
+#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST		 151
+#define SSL_R_EXCESSIVE_MESSAGE_SIZE			 152
+#define SSL_R_EXTRA_DATA_IN_MESSAGE			 153
+#define SSL_R_GOT_A_FIN_BEFORE_A_CCS			 154
+#define SSL_R_HTTPS_PROXY_REQUEST			 155
+#define SSL_R_HTTP_REQUEST				 156
+#define SSL_R_ILLEGAL_PADDING				 283
+#define SSL_R_INVALID_CHALLENGE_LENGTH			 158
+#define SSL_R_INVALID_COMMAND				 280
+#define SSL_R_INVALID_PURPOSE				 278
+#define SSL_R_INVALID_TRUST				 279
+#define SSL_R_KEY_ARG_TOO_LONG				 284
+#define SSL_R_KRB5					 285
+#define SSL_R_KRB5_C_CC_PRINC				 286
+#define SSL_R_KRB5_C_GET_CRED				 287
+#define SSL_R_KRB5_C_INIT				 288
+#define SSL_R_KRB5_C_MK_REQ				 289
+#define SSL_R_KRB5_S_BAD_TICKET				 290
+#define SSL_R_KRB5_S_INIT				 291
+#define SSL_R_KRB5_S_RD_REQ				 292
+#define SSL_R_KRB5_S_TKT_EXPIRED			 293
+#define SSL_R_KRB5_S_TKT_NYV				 294
+#define SSL_R_KRB5_S_TKT_SKEW				 295
+#define SSL_R_LENGTH_MISMATCH				 159
+#define SSL_R_LENGTH_TOO_SHORT				 160
+#define SSL_R_LIBRARY_BUG				 274
+#define SSL_R_LIBRARY_HAS_NO_CIPHERS			 161
+#define SSL_R_MESSAGE_TOO_LONG				 296
+#define SSL_R_MISSING_DH_DSA_CERT			 162
+#define SSL_R_MISSING_DH_KEY				 163
+#define SSL_R_MISSING_DH_RSA_CERT			 164
+#define SSL_R_MISSING_DSA_SIGNING_CERT			 165
+#define SSL_R_MISSING_EXPORT_TMP_DH_KEY			 166
+#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY		 167
+#define SSL_R_MISSING_RSA_CERTIFICATE			 168
+#define SSL_R_MISSING_RSA_ENCRYPTING_CERT		 169
+#define SSL_R_MISSING_RSA_SIGNING_CERT			 170
+#define SSL_R_MISSING_TMP_DH_KEY			 171
+#define SSL_R_MISSING_TMP_ECDH_KEY			 311
+#define SSL_R_MISSING_TMP_RSA_KEY			 172
+#define SSL_R_MISSING_TMP_RSA_PKEY			 173
+#define SSL_R_MISSING_VERIFY_MESSAGE			 174
+#define SSL_R_NON_SSLV2_INITIAL_PACKET			 175
+#define SSL_R_NO_CERTIFICATES_RETURNED			 176
+#define SSL_R_NO_CERTIFICATE_ASSIGNED			 177
+#define SSL_R_NO_CERTIFICATE_RETURNED			 178
+#define SSL_R_NO_CERTIFICATE_SET			 179
+#define SSL_R_NO_CERTIFICATE_SPECIFIED			 180
+#define SSL_R_NO_CIPHERS_AVAILABLE			 181
+#define SSL_R_NO_CIPHERS_PASSED				 182
+#define SSL_R_NO_CIPHERS_SPECIFIED			 183
+#define SSL_R_NO_CIPHER_LIST				 184
+#define SSL_R_NO_CIPHER_MATCH				 185
+#define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
+#define SSL_R_NO_COMPRESSION_SPECIFIED			 187
+#define SSL_R_NO_METHOD_SPECIFIED			 188
+#define SSL_R_NO_PRIVATEKEY				 189
+#define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
+#define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
+#define SSL_R_NO_PUBLICKEY				 192
+#define SSL_R_NO_SHARED_CIPHER				 193
+#define SSL_R_NO_VERIFY_CALLBACK			 194
+#define SSL_R_NULL_SSL_CTX				 195
+#define SSL_R_NULL_SSL_METHOD_PASSED			 196
+#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
+#define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
+#define SSL_R_PACKET_LENGTH_TOO_LONG			 198
+#define SSL_R_PATH_TOO_LONG				 270
+#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
+#define SSL_R_PEER_ERROR				 200
+#define SSL_R_PEER_ERROR_CERTIFICATE			 201
+#define SSL_R_PEER_ERROR_NO_CERTIFICATE			 202
+#define SSL_R_PEER_ERROR_NO_CIPHER			 203
+#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE	 204
+#define SSL_R_PRE_MAC_LENGTH_TOO_LONG			 205
+#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS		 206
+#define SSL_R_PROTOCOL_IS_SHUTDOWN			 207
+#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR			 208
+#define SSL_R_PUBLIC_KEY_IS_NOT_RSA			 209
+#define SSL_R_PUBLIC_KEY_NOT_RSA			 210
+#define SSL_R_READ_BIO_NOT_SET				 211
+#define SSL_R_READ_TIMEOUT_EXPIRED			 312
+#define SSL_R_READ_WRONG_PACKET_TYPE			 212
+#define SSL_R_RECORD_LENGTH_MISMATCH			 213
+#define SSL_R_RECORD_TOO_LARGE				 214
+#define SSL_R_RECORD_TOO_SMALL				 298
+#define SSL_R_REQUIRED_CIPHER_MISSING			 215
+#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
+#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
+#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
+#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
+#define SSL_R_SHORT_READ				 219
+#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
+#define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
+#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
+#define SSL_R_SSL3_SESSION_ID_TOO_LONG			 300
+#define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
+#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
+#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC		 1020
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED		 1045
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED		 1044
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN		 1046
+#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE		 1030
+#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE		 1040
+#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER		 1047
+#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE		 1041
+#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		 1010
+#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE	 1043
+#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION	 228
+#define SSL_R_SSL_HANDSHAKE_FAILURE			 229
+#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS		 230
+#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED		 301
+#define SSL_R_SSL_SESSION_ID_CONFLICT			 302
+#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG		 273
+#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH		 303
+#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT		 231
+#define SSL_R_TLSV1_ALERT_ACCESS_DENIED			 1049
+#define SSL_R_TLSV1_ALERT_DECODE_ERROR			 1050
+#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
+#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
+#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
+#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
+#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
+#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100
+#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		 1070
+#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		 1022
+#define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
+#define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
+#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
+#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
+#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
+#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
+#define SSL_R_UNABLE_TO_DECODE_DH_CERTS			 236
+#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS		 313
+#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY		 237
+#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS		 238
+#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS		 314
+#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS	 239
+#define SSL_R_UNABLE_TO_FIND_SSL_METHOD			 240
+#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES		 241
+#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES		 242
+#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES		 243
+#define SSL_R_UNEXPECTED_MESSAGE			 244
+#define SSL_R_UNEXPECTED_RECORD				 245
+#define SSL_R_UNINITIALIZED				 276
+#define SSL_R_UNKNOWN_ALERT_TYPE			 246
+#define SSL_R_UNKNOWN_CERTIFICATE_TYPE			 247
+#define SSL_R_UNKNOWN_CIPHER_RETURNED			 248
+#define SSL_R_UNKNOWN_CIPHER_TYPE			 249
+#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE			 250
+#define SSL_R_UNKNOWN_PKEY_TYPE				 251
+#define SSL_R_UNKNOWN_PROTOCOL				 252
+#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
+#define SSL_R_UNKNOWN_SSL_VERSION			 254
+#define SSL_R_UNKNOWN_STATE				 255
+#define SSL_R_UNSUPPORTED_CIPHER			 256
+#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
+#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 315
+#define SSL_R_UNSUPPORTED_PROTOCOL			 258
+#define SSL_R_UNSUPPORTED_SSL_VERSION			 259
+#define SSL_R_WRITE_BIO_NOT_SET				 260
+#define SSL_R_WRONG_CIPHER_RETURNED			 261
+#define SSL_R_WRONG_MESSAGE_TYPE			 262
+#define SSL_R_WRONG_NUMBER_OF_KEY_BITS			 263
+#define SSL_R_WRONG_SIGNATURE_LENGTH			 264
+#define SSL_R_WRONG_SIGNATURE_SIZE			 265
+#define SSL_R_WRONG_SSL_VERSION				 266
+#define SSL_R_WRONG_VERSION_NUMBER			 267
+#define SSL_R_X509_LIB					 268
+#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS		 269
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/ssl2.h b/dep/include/openssl/ssl2.h
new file mode 100644
index 000000000..99a52ea0d
--- /dev/null
+++ b/dep/include/openssl/ssl2.h
@@ -0,0 +1,268 @@
+/* ssl/ssl2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL2_H 
+#define HEADER_SSL2_H 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Protocol Version Codes */
+#define SSL2_VERSION		0x0002
+#define SSL2_VERSION_MAJOR	0x00
+#define SSL2_VERSION_MINOR	0x02
+/* #define SSL2_CLIENT_VERSION	0x0002 */
+/* #define SSL2_SERVER_VERSION	0x0002 */
+
+/* Protocol Message Codes */
+#define SSL2_MT_ERROR			0
+#define SSL2_MT_CLIENT_HELLO		1
+#define SSL2_MT_CLIENT_MASTER_KEY	2
+#define SSL2_MT_CLIENT_FINISHED		3
+#define SSL2_MT_SERVER_HELLO		4
+#define SSL2_MT_SERVER_VERIFY		5
+#define SSL2_MT_SERVER_FINISHED		6
+#define SSL2_MT_REQUEST_CERTIFICATE	7
+#define SSL2_MT_CLIENT_CERTIFICATE	8
+
+/* Error Message Codes */
+#define SSL2_PE_UNDEFINED_ERROR		0x0000
+#define SSL2_PE_NO_CIPHER		0x0001
+#define SSL2_PE_NO_CERTIFICATE		0x0002
+#define SSL2_PE_BAD_CERTIFICATE		0x0004
+#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
+
+/* Cipher Kind Values */
+#define SSL2_CK_NULL_WITH_MD5			0x02000000 /* v3 */
+#define SSL2_CK_RC4_128_WITH_MD5		0x02010080
+#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5	0x02020080
+#define SSL2_CK_RC2_128_CBC_WITH_MD5		0x02030080
+#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5	0x02040080
+#define SSL2_CK_IDEA_128_CBC_WITH_MD5		0x02050080
+#define SSL2_CK_DES_64_CBC_WITH_MD5		0x02060040
+#define SSL2_CK_DES_64_CBC_WITH_SHA		0x02060140 /* v3 */
+#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5	0x020700c0
+#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA	0x020701c0 /* v3 */
+#define SSL2_CK_RC4_64_WITH_MD5			0x02080080 /* MS hack */
+ 
+#define SSL2_CK_DES_64_CFB64_WITH_MD5_1		0x02ff0800 /* SSLeay */
+#define SSL2_CK_NULL				0x02ff0810 /* SSLeay */
+
+#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1	"DES-CFB-M1"
+#define SSL2_TXT_NULL_WITH_MD5			"NULL-MD5"
+#define SSL2_TXT_RC4_128_WITH_MD5		"RC4-MD5"
+#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	"EXP-RC4-MD5"
+#define SSL2_TXT_RC2_128_CBC_WITH_MD5		"RC2-CBC-MD5"
+#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	"EXP-RC2-CBC-MD5"
+#define SSL2_TXT_IDEA_128_CBC_WITH_MD5		"IDEA-CBC-MD5"
+#define SSL2_TXT_DES_64_CBC_WITH_MD5		"DES-CBC-MD5"
+#define SSL2_TXT_DES_64_CBC_WITH_SHA		"DES-CBC-SHA"
+#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	"DES-CBC3-MD5"
+#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	"DES-CBC3-SHA"
+#define SSL2_TXT_RC4_64_WITH_MD5		"RC4-64-MD5"
+
+#define SSL2_TXT_NULL				"NULL"
+
+/* Flags for the SSL_CIPHER.algorithm2 field */
+#define SSL2_CF_5_BYTE_ENC			0x01
+#define SSL2_CF_8_BYTE_ENC			0x02
+
+/* Certificate Type Codes */
+#define SSL2_CT_X509_CERTIFICATE		0x01
+
+/* Authentication Type Code */
+#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION		0x01
+
+#define SSL2_MAX_SSL_SESSION_ID_LENGTH		32
+
+/* Upper/Lower Bounds */
+#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS	256
+#ifdef OPENSSL_SYS_MPE
+#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	29998u
+#else
+#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	32767u  /* 2^15-1 */
+#endif
+#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER	16383 /* 2^14-1 */
+
+#define SSL2_CHALLENGE_LENGTH	16
+/*#define SSL2_CHALLENGE_LENGTH	32 */
+#define SSL2_MIN_CHALLENGE_LENGTH	16
+#define SSL2_MAX_CHALLENGE_LENGTH	32
+#define SSL2_CONNECTION_ID_LENGTH	16
+#define SSL2_MAX_CONNECTION_ID_LENGTH	16
+#define SSL2_SSL_SESSION_ID_LENGTH	16
+#define SSL2_MAX_CERT_CHALLENGE_LENGTH	32
+#define SSL2_MIN_CERT_CHALLENGE_LENGTH	16
+#define SSL2_MAX_KEY_MATERIAL_LENGTH	24
+
+#ifndef HEADER_SSL_LOCL_H
+#define  CERT		char
+#endif
+
+typedef struct ssl2_state_st
+	{
+	int three_byte_header;
+	int clear_text;		/* clear text */
+	int escape;		/* not used in SSLv2 */
+	int ssl2_rollback;	/* used if SSLv23 rolled back to SSLv2 */
+
+	/* non-blocking io info, used to make sure the same
+	 * args were passwd */
+	unsigned int wnum;	/* number of bytes sent so far */
+	int wpend_tot;
+	const unsigned char *wpend_buf;
+
+	int wpend_off;	/* offset to data to write */
+	int wpend_len; 	/* number of bytes passwd to write */
+	int wpend_ret; 	/* number of bytes to return to caller */
+
+	/* buffer raw data */
+	int rbuf_left;
+	int rbuf_offs;
+	unsigned char *rbuf;
+	unsigned char *wbuf;
+
+	unsigned char *write_ptr;/* used to point to the start due to
+				  * 2/3 byte header. */
+
+	unsigned int padding;
+	unsigned int rlength; /* passed to ssl2_enc */
+	int ract_data_length; /* Set when things are encrypted. */
+	unsigned int wlength; /* passed to ssl2_enc */
+	int wact_data_length; /* Set when things are decrypted. */
+	unsigned char *ract_data;
+	unsigned char *wact_data;
+	unsigned char *mac_data;
+
+	unsigned char *read_key;
+	unsigned char *write_key;
+
+		/* Stuff specifically to do with this SSL session */
+	unsigned int challenge_length;
+	unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
+	unsigned int conn_id_length;
+	unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
+	unsigned int key_material_length;
+	unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2];
+
+	unsigned long read_sequence;
+	unsigned long write_sequence;
+
+	struct	{
+		unsigned int conn_id_length;
+		unsigned int cert_type;	
+		unsigned int cert_length;
+		unsigned int csl; 
+		unsigned int clear;
+		unsigned int enc; 
+		unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
+		unsigned int cipher_spec_length;
+		unsigned int session_id_length;
+		unsigned int clen;
+		unsigned int rlen;
+		} tmp;
+	} SSL2_STATE;
+
+/* SSLv2 */
+/* client */
+#define SSL2_ST_SEND_CLIENT_HELLO_A		(0x10|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_HELLO_B		(0x11|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_HELLO_A		(0x20|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_HELLO_B		(0x21|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A	(0x30|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B	(0x31|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_FINISHED_A		(0x40|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_FINISHED_B		(0x41|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A	(0x50|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B	(0x51|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C	(0x52|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D	(0x53|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_VERIFY_A		(0x60|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_VERIFY_B		(0x61|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_FINISHED_A		(0x70|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_FINISHED_B		(0x71|SSL_ST_CONNECT)
+#define SSL2_ST_CLIENT_START_ENCRYPTION		(0x80|SSL_ST_CONNECT)
+#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE	(0x90|SSL_ST_CONNECT)
+/* server */
+#define SSL2_ST_GET_CLIENT_HELLO_A		(0x10|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_HELLO_B		(0x11|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_HELLO_C		(0x12|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_HELLO_A		(0x20|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_HELLO_B		(0x21|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_MASTER_KEY_A		(0x30|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_MASTER_KEY_B		(0x31|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_A		(0x40|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_B		(0x41|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_C		(0x42|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_FINISHED_A		(0x50|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_FINISHED_B		(0x51|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_FINISHED_A		(0x60|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_FINISHED_B		(0x61|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A	(0x70|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B	(0x71|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C	(0x72|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D	(0x73|SSL_ST_ACCEPT)
+#define SSL2_ST_SERVER_START_ENCRYPTION		(0x80|SSL_ST_ACCEPT)
+#define SSL2_ST_X509_GET_SERVER_CERTIFICATE	(0x90|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/ssl23.h b/dep/include/openssl/ssl23.h
new file mode 100644
index 000000000..d3228983c
--- /dev/null
+++ b/dep/include/openssl/ssl23.h
@@ -0,0 +1,83 @@
+/* ssl/ssl23.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL23_H 
+#define HEADER_SSL23_H 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*client */
+/* write to server */
+#define SSL23_ST_CW_CLNT_HELLO_A	(0x210|SSL_ST_CONNECT)
+#define SSL23_ST_CW_CLNT_HELLO_B	(0x211|SSL_ST_CONNECT)
+/* read from server */
+#define SSL23_ST_CR_SRVR_HELLO_A	(0x220|SSL_ST_CONNECT)
+#define SSL23_ST_CR_SRVR_HELLO_B	(0x221|SSL_ST_CONNECT)
+
+/* server */
+/* read from client */
+#define SSL23_ST_SR_CLNT_HELLO_A	(0x210|SSL_ST_ACCEPT)
+#define SSL23_ST_SR_CLNT_HELLO_B	(0x211|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/ssl3.h b/dep/include/openssl/ssl3.h
new file mode 100644
index 000000000..bacaff157
--- /dev/null
+++ b/dep/include/openssl/ssl3.h
@@ -0,0 +1,555 @@
+/* ssl/ssl3.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL3_H 
+#define HEADER_SSL3_H 
+
+#ifndef OPENSSL_NO_COMP
+#include 
+#endif
+#include 
+#include 
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define SSL3_CK_RSA_NULL_MD5			0x03000001
+#define SSL3_CK_RSA_NULL_SHA			0x03000002
+#define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
+#define SSL3_CK_RSA_RC4_128_MD5			0x03000004
+#define SSL3_CK_RSA_RC4_128_SHA			0x03000005
+#define SSL3_CK_RSA_RC2_40_MD5			0x03000006
+#define SSL3_CK_RSA_IDEA_128_SHA		0x03000007
+#define SSL3_CK_RSA_DES_40_CBC_SHA		0x03000008
+#define SSL3_CK_RSA_DES_64_CBC_SHA		0x03000009
+#define SSL3_CK_RSA_DES_192_CBC3_SHA		0x0300000A
+
+#define SSL3_CK_DH_DSS_DES_40_CBC_SHA		0x0300000B
+#define SSL3_CK_DH_DSS_DES_64_CBC_SHA		0x0300000C
+#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 	0x0300000D
+#define SSL3_CK_DH_RSA_DES_40_CBC_SHA		0x0300000E
+#define SSL3_CK_DH_RSA_DES_64_CBC_SHA		0x0300000F
+#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 	0x03000010
+
+#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA		0x03000011
+#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA		0x03000012
+#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA	0x03000013
+#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA		0x03000014
+#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA		0x03000015
+#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA	0x03000016
+
+#define SSL3_CK_ADH_RC4_40_MD5			0x03000017
+#define SSL3_CK_ADH_RC4_128_MD5			0x03000018
+#define SSL3_CK_ADH_DES_40_CBC_SHA		0x03000019
+#define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
+#define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
+
+#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
+#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
+#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
+	 to remove according to David Hopwood 
+	 of the ietf-tls list */
+#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+#endif
+
+/*    VRS Additional Kerberos5 entries
+ */
+#define SSL3_CK_KRB5_DES_64_CBC_SHA		0x0300001E
+#define SSL3_CK_KRB5_DES_192_CBC3_SHA		0x0300001F
+#define SSL3_CK_KRB5_RC4_128_SHA		0x03000020
+#define SSL3_CK_KRB5_IDEA_128_CBC_SHA	       	0x03000021
+#define SSL3_CK_KRB5_DES_64_CBC_MD5       	0x03000022
+#define SSL3_CK_KRB5_DES_192_CBC3_MD5       	0x03000023
+#define SSL3_CK_KRB5_RC4_128_MD5	       	0x03000024
+#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 		0x03000025
+
+#define SSL3_CK_KRB5_DES_40_CBC_SHA 		0x03000026
+#define SSL3_CK_KRB5_RC2_40_CBC_SHA 		0x03000027
+#define SSL3_CK_KRB5_RC4_40_SHA	 		0x03000028
+#define SSL3_CK_KRB5_DES_40_CBC_MD5 		0x03000029
+#define SSL3_CK_KRB5_RC2_40_CBC_MD5 		0x0300002A
+#define SSL3_CK_KRB5_RC4_40_MD5	 		0x0300002B
+
+#define SSL3_TXT_RSA_NULL_MD5			"NULL-MD5"
+#define SSL3_TXT_RSA_NULL_SHA			"NULL-SHA"
+#define SSL3_TXT_RSA_RC4_40_MD5 		"EXP-RC4-MD5"
+#define SSL3_TXT_RSA_RC4_128_MD5		"RC4-MD5"
+#define SSL3_TXT_RSA_RC4_128_SHA		"RC4-SHA"
+#define SSL3_TXT_RSA_RC2_40_MD5			"EXP-RC2-CBC-MD5"
+#define SSL3_TXT_RSA_IDEA_128_SHA		"IDEA-CBC-SHA"
+#define SSL3_TXT_RSA_DES_40_CBC_SHA		"EXP-DES-CBC-SHA"
+#define SSL3_TXT_RSA_DES_64_CBC_SHA		"DES-CBC-SHA"
+#define SSL3_TXT_RSA_DES_192_CBC3_SHA		"DES-CBC3-SHA"
+
+#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA		"EXP-DH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA		"DH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA 	"DH-DSS-DES-CBC3-SHA"
+#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA		"EXP-DH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA		"DH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA 	"DH-RSA-DES-CBC3-SHA"
+
+#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA		"EXP-EDH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA		"EDH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA	"EDH-DSS-DES-CBC3-SHA"
+#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA		"EXP-EDH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA		"EDH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA	"EDH-RSA-DES-CBC3-SHA"
+
+#define SSL3_TXT_ADH_RC4_40_MD5			"EXP-ADH-RC4-MD5"
+#define SSL3_TXT_ADH_RC4_128_MD5		"ADH-RC4-MD5"
+#define SSL3_TXT_ADH_DES_40_CBC_SHA		"EXP-ADH-DES-CBC-SHA"
+#define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
+#define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
+
+#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
+#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
+#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+
+#define SSL3_TXT_KRB5_DES_64_CBC_SHA		"KRB5-DES-CBC-SHA"
+#define SSL3_TXT_KRB5_DES_192_CBC3_SHA		"KRB5-DES-CBC3-SHA"
+#define SSL3_TXT_KRB5_RC4_128_SHA		"KRB5-RC4-SHA"
+#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA	       	"KRB5-IDEA-CBC-SHA"
+#define SSL3_TXT_KRB5_DES_64_CBC_MD5       	"KRB5-DES-CBC-MD5"
+#define SSL3_TXT_KRB5_DES_192_CBC3_MD5       	"KRB5-DES-CBC3-MD5"
+#define SSL3_TXT_KRB5_RC4_128_MD5		"KRB5-RC4-MD5"
+#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 		"KRB5-IDEA-CBC-MD5"
+
+#define SSL3_TXT_KRB5_DES_40_CBC_SHA 		"EXP-KRB5-DES-CBC-SHA"
+#define SSL3_TXT_KRB5_RC2_40_CBC_SHA 		"EXP-KRB5-RC2-CBC-SHA"
+#define SSL3_TXT_KRB5_RC4_40_SHA	 	"EXP-KRB5-RC4-SHA"
+#define SSL3_TXT_KRB5_DES_40_CBC_MD5 		"EXP-KRB5-DES-CBC-MD5"
+#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 		"EXP-KRB5-RC2-CBC-MD5"
+#define SSL3_TXT_KRB5_RC4_40_MD5	 	"EXP-KRB5-RC4-MD5"
+
+#define SSL3_SSL_SESSION_ID_LENGTH		32
+#define SSL3_MAX_SSL_SESSION_ID_LENGTH		32
+
+#define SSL3_MASTER_SECRET_SIZE			48
+#define SSL3_RANDOM_SIZE			32
+#define SSL3_SESSION_ID_SIZE			32
+#define SSL3_RT_HEADER_LENGTH			5
+
+/* Due to MS stuffing up, this can change.... */
+#if defined(OPENSSL_SYS_WIN16) || \
+	(defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32))
+#define SSL3_RT_MAX_EXTRA			(14000)
+#else
+#define SSL3_RT_MAX_EXTRA			(16384)
+#endif
+
+#define SSL3_RT_MAX_PLAIN_LENGTH		16384
+#ifdef OPENSSL_NO_COMP
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	SSL3_RT_MAX_PLAIN_LENGTH
+#else
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	(1024+SSL3_RT_MAX_PLAIN_LENGTH)
+#endif
+#define SSL3_RT_MAX_ENCRYPTED_LENGTH	(1024+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_PACKET_SIZE		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+#define SSL3_RT_MAX_DATA_SIZE			(1024*1024)
+
+#define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
+#define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
+
+#define SSL3_VERSION			0x0300
+#define SSL3_VERSION_MAJOR		0x03
+#define SSL3_VERSION_MINOR		0x00
+
+#define SSL3_RT_CHANGE_CIPHER_SPEC	20
+#define SSL3_RT_ALERT			21
+#define SSL3_RT_HANDSHAKE		22
+#define SSL3_RT_APPLICATION_DATA	23
+
+#define SSL3_AL_WARNING			1
+#define SSL3_AL_FATAL			2
+
+#define SSL3_AD_CLOSE_NOTIFY		 0
+#define SSL3_AD_UNEXPECTED_MESSAGE	10	/* fatal */
+#define SSL3_AD_BAD_RECORD_MAC		20	/* fatal */
+#define SSL3_AD_DECOMPRESSION_FAILURE	30	/* fatal */
+#define SSL3_AD_HANDSHAKE_FAILURE	40	/* fatal */
+#define SSL3_AD_NO_CERTIFICATE		41
+#define SSL3_AD_BAD_CERTIFICATE		42
+#define SSL3_AD_UNSUPPORTED_CERTIFICATE	43
+#define SSL3_AD_CERTIFICATE_REVOKED	44
+#define SSL3_AD_CERTIFICATE_EXPIRED	45
+#define SSL3_AD_CERTIFICATE_UNKNOWN	46
+#define SSL3_AD_ILLEGAL_PARAMETER	47	/* fatal */
+
+typedef struct ssl3_record_st
+	{
+/*r */	int type;               /* type of record */
+/*rw*/	unsigned int length;    /* How many bytes available */
+/*r */	unsigned int off;       /* read/write offset into 'buf' */
+/*rw*/	unsigned char *data;    /* pointer to the record data */
+/*rw*/	unsigned char *input;   /* where the decode bytes are */
+/*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
+/*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
+/*r */  PQ_64BIT seq_num;       /* sequence number, needed by DTLS1 */
+	} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st
+	{
+	unsigned char *buf;     /* at least SSL3_RT_MAX_PACKET_SIZE bytes,
+	                         * see ssl3_setup_buffers() */
+	size_t len;             /* buffer size */
+	int offset;             /* where to 'copy from' */
+	int left;               /* how many bytes left */
+	} SSL3_BUFFER;
+
+#define SSL3_CT_RSA_SIGN			1
+#define SSL3_CT_DSS_SIGN			2
+#define SSL3_CT_RSA_FIXED_DH			3
+#define SSL3_CT_DSS_FIXED_DH			4
+#define SSL3_CT_RSA_EPHEMERAL_DH		5
+#define SSL3_CT_DSS_EPHEMERAL_DH		6
+#define SSL3_CT_FORTEZZA_DMS			20
+/* SSL3_CT_NUMBER is used to size arrays and it must be large
+ * enough to contain all of the cert types defined either for
+ * SSLv3 and TLSv1.
+ */
+#define SSL3_CT_NUMBER			7
+
+
+#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
+#define SSL3_FLAGS_DELAY_CLIENT_FINISHED	0x0002
+#define SSL3_FLAGS_POP_BUFFER			0x0004
+#define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
+
+typedef struct ssl3_state_st
+	{
+	long flags;
+	int delay_buf_pop_ret;
+
+	unsigned char read_sequence[8];
+	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+	unsigned char write_sequence[8];
+	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+
+	unsigned char server_random[SSL3_RANDOM_SIZE];
+	unsigned char client_random[SSL3_RANDOM_SIZE];
+
+	/* flags for countermeasure against known-IV weakness */
+	int need_empty_fragments;
+	int empty_fragment_done;
+
+	SSL3_BUFFER rbuf;	/* read IO goes into here */
+	SSL3_BUFFER wbuf;	/* write IO goes into here */
+
+	SSL3_RECORD rrec;	/* each decoded record goes in here */
+	SSL3_RECORD wrec;	/* goes out from here */
+
+	/* storage for Alert/Handshake protocol data received but not
+	 * yet processed by ssl3_read_bytes: */
+	unsigned char alert_fragment[2];
+	unsigned int alert_fragment_len;
+	unsigned char handshake_fragment[4];
+	unsigned int handshake_fragment_len;
+
+	/* partial write - check the numbers match */
+	unsigned int wnum;	/* number of bytes sent so far */
+	int wpend_tot;		/* number bytes written */
+	int wpend_type;
+	int wpend_ret;		/* number of bytes submitted */
+	const unsigned char *wpend_buf;
+
+	/* used during startup, digest all incoming/outgoing packets */
+	EVP_MD_CTX finish_dgst1;
+	EVP_MD_CTX finish_dgst2;
+
+	/* this is set whenerver we see a change_cipher_spec message
+	 * come in when we are not looking for one */
+	int change_cipher_spec;
+
+	int warn_alert;
+	int fatal_alert;
+	/* we allow one fatal and one warning alert to be outstanding,
+	 * send close alert via the warning alert */
+	int alert_dispatch;
+	unsigned char send_alert[2];
+
+	/* This flag is set when we should renegotiate ASAP, basically when
+	 * there is no more data in the read or write buffers */
+	int renegotiate;
+	int total_renegotiations;
+	int num_renegotiations;
+
+	int in_read_app_data;
+
+	struct	{
+		/* actually only needs to be 16+20 */
+		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
+
+		/* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+		unsigned char finish_md[EVP_MAX_MD_SIZE*2];
+		int finish_md_len;
+		unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
+		int peer_finish_md_len;
+		
+		unsigned long message_size;
+		int message_type;
+
+		/* used to hold the new cipher we are going to use */
+		SSL_CIPHER *new_cipher;
+#ifndef OPENSSL_NO_DH
+		DH *dh;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+		EC_KEY *ecdh; /* holds short lived ECDH key */
+#endif
+
+		/* used when SSL_ST_FLUSH_DATA is entered */
+		int next_state;			
+
+		int reuse_message;
+
+		/* used for certificate requests */
+		int cert_req;
+		int ctype_num;
+		char ctype[SSL3_CT_NUMBER];
+		STACK_OF(X509_NAME) *ca_names;
+
+		int use_rsa_tmp;
+
+		int key_block_length;
+		unsigned char *key_block;
+
+		const EVP_CIPHER *new_sym_enc;
+		const EVP_MD *new_hash;
+#ifndef OPENSSL_NO_COMP
+		const SSL_COMP *new_compression;
+#else
+		char *new_compression;
+#endif
+		int cert_request;
+		} tmp;
+
+	} SSL3_STATE;
+
+
+/* SSLv3 */
+/*client */
+/* extra state */
+#define SSL3_ST_CW_FLUSH		(0x100|SSL_ST_CONNECT)
+/* write to server */
+#define SSL3_ST_CW_CLNT_HELLO_A		(0x110|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CLNT_HELLO_B		(0x111|SSL_ST_CONNECT)
+/* read from server */
+#define SSL3_ST_CR_SRVR_HELLO_A		(0x120|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_HELLO_B		(0x121|SSL_ST_CONNECT)
+#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
+#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_A		(0x130|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_B		(0x131|SSL_ST_CONNECT)
+#define SSL3_ST_CR_KEY_EXCH_A		(0x140|SSL_ST_CONNECT)
+#define SSL3_ST_CR_KEY_EXCH_B		(0x141|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_REQ_A		(0x150|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_REQ_B		(0x151|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_DONE_A		(0x160|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_DONE_B		(0x161|SSL_ST_CONNECT)
+/* write to server */
+#define SSL3_ST_CW_CERT_A		(0x170|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_B		(0x171|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_C		(0x172|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_D		(0x173|SSL_ST_CONNECT)
+#define SSL3_ST_CW_KEY_EXCH_A		(0x180|SSL_ST_CONNECT)
+#define SSL3_ST_CW_KEY_EXCH_B		(0x181|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_A		(0x190|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
+#define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
+#define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
+/* read from server */
+#define SSL3_ST_CR_CHANGE_A		(0x1C0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CHANGE_B		(0x1C1|SSL_ST_CONNECT)
+#define SSL3_ST_CR_FINISHED_A		(0x1D0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_FINISHED_B		(0x1D1|SSL_ST_CONNECT)
+
+/* server */
+/* extra state */
+#define SSL3_ST_SW_FLUSH		(0x100|SSL_ST_ACCEPT)
+/* read from client */
+/* Do not change the number values, they do matter */
+#define SSL3_ST_SR_CLNT_HELLO_A		(0x110|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_HELLO_B		(0x111|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_HELLO_C		(0x112|SSL_ST_ACCEPT)
+/* write to client */
+#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
+#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_A		(0x120|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_B		(0x121|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_C		(0x122|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_HELLO_A		(0x130|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_HELLO_B		(0x131|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_A		(0x140|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_B		(0x141|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_A		(0x150|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_B		(0x151|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_REQ_A		(0x160|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_REQ_B		(0x161|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_DONE_A		(0x170|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_DONE_B		(0x171|SSL_ST_ACCEPT)
+/* read from client */
+#define SSL3_ST_SR_CERT_A		(0x180|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_B		(0x181|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_A		(0x190|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_B		(0x191|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_VRFY_A		(0x1A0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
+/* write to client */
+#define SSL3_ST_SW_CHANGE_A		(0x1D0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CHANGE_B		(0x1D1|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_FINISHED_A		(0x1E0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_FINISHED_B		(0x1E1|SSL_ST_ACCEPT)
+
+#define SSL3_MT_HELLO_REQUEST			0
+#define SSL3_MT_CLIENT_HELLO			1
+#define SSL3_MT_SERVER_HELLO			2
+#define SSL3_MT_CERTIFICATE			11
+#define SSL3_MT_SERVER_KEY_EXCHANGE		12
+#define SSL3_MT_CERTIFICATE_REQUEST		13
+#define SSL3_MT_SERVER_DONE			14
+#define SSL3_MT_CERTIFICATE_VERIFY		15
+#define SSL3_MT_CLIENT_KEY_EXCHANGE		16
+#define SSL3_MT_FINISHED			20
+#define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+
+
+#define SSL3_MT_CCS				1
+
+/* These are used when changing over to a new cipher */
+#define SSL3_CC_READ		0x01
+#define SSL3_CC_WRITE		0x02
+#define SSL3_CC_CLIENT		0x10
+#define SSL3_CC_SERVER		0x20
+#define SSL3_CHANGE_CIPHER_CLIENT_WRITE	(SSL3_CC_CLIENT|SSL3_CC_WRITE)	
+#define SSL3_CHANGE_CIPHER_SERVER_READ	(SSL3_CC_SERVER|SSL3_CC_READ)
+#define SSL3_CHANGE_CIPHER_CLIENT_READ	(SSL3_CC_CLIENT|SSL3_CC_READ)
+#define SSL3_CHANGE_CIPHER_SERVER_WRITE	(SSL3_CC_SERVER|SSL3_CC_WRITE)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/stack.h b/dep/include/openssl/stack.h
new file mode 100644
index 000000000..5cbb116a8
--- /dev/null
+++ b/dep/include/openssl/stack.h
@@ -0,0 +1,109 @@
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+#define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st
+	{
+	int num;
+	char **data;
+	int sorted;
+
+	int num_alloc;
+	int (*comp)(const char * const *, const char * const *);
+	} STACK;
+
+#define M_sk_num(sk)		((sk) ? (sk)->num:-1)
+#define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(const STACK *);
+char *sk_value(const STACK *, int);
+
+char *sk_set(STACK *, int, char *);
+
+STACK *sk_new(int (*cmp)(const char * const *, const char * const *));
+STACK *sk_new_null(void);
+void sk_free(STACK *);
+void sk_pop_free(STACK *st, void (*func)(void *));
+int sk_insert(STACK *sk,char *data,int where);
+char *sk_delete(STACK *st,int loc);
+char *sk_delete_ptr(STACK *st, char *p);
+int sk_find(STACK *st,char *data);
+int sk_find_ex(STACK *st,char *data);
+int sk_push(STACK *st,char *data);
+int sk_unshift(STACK *st,char *data);
+char *sk_shift(STACK *st);
+char *sk_pop(STACK *st);
+void sk_zero(STACK *st);
+int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,
+			const char * const *)))
+			(const char * const *, const char * const *);
+STACK *sk_dup(STACK *st);
+void sk_sort(STACK *st);
+int sk_is_sorted(const STACK *st);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/store.h b/dep/include/openssl/store.h
new file mode 100644
index 000000000..64583377a
--- /dev/null
+++ b/dep/include/openssl/store.h
@@ -0,0 +1,554 @@
+/* crypto/store/store.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_STORE_H
+#define HEADER_STORE_H
+
+#include 
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#include 
+#include 
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct store_st STORE; */
+/* typedef struct store_method_st STORE_METHOD; */
+
+
+/* All the following functions return 0, a negative number or NULL on error.
+   When everything is fine, they return a positive value or a non-NULL
+   pointer, all depending on their purpose. */
+
+/* Creators and destructor.   */
+STORE *STORE_new_method(const STORE_METHOD *method);
+STORE *STORE_new_engine(ENGINE *engine);
+void STORE_free(STORE *ui);
+
+
+/* Give a user interface parametrised control commands.  This can be used to
+   send down an integer, a data pointer or a function pointer, as well as
+   be used to get information from a STORE. */
+int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void));
+
+/* A control to set the directory with keys and certificates.  Used by the
+   built-in directory level method. */
+#define STORE_CTRL_SET_DIRECTORY	0x0001
+/* A control to set a file to load.  Used by the built-in file level method. */
+#define STORE_CTRL_SET_FILE		0x0002
+/* A control to set a configuration file to load.  Can be used by any method
+   that wishes to load a configuration file. */
+#define STORE_CTRL_SET_CONF_FILE	0x0003
+/* A control to set a the section of the loaded configuration file.  Can be
+   used by any method that wishes to load a configuration file. */
+#define STORE_CTRL_SET_CONF_SECTION	0x0004
+
+
+/* Some methods may use extra data */
+#define STORE_set_app_data(s,arg)	STORE_set_ex_data(s,0,arg)
+#define STORE_get_app_data(s)		STORE_get_ex_data(s,0)
+int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int STORE_set_ex_data(STORE *r,int idx,void *arg);
+void *STORE_get_ex_data(STORE *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+const STORE_METHOD *STORE_get_method(STORE *store);
+const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth);
+
+/* The standard OpenSSL methods. */
+/* This is the in-memory method.  It does everything except revoking and updating,
+   and is of course volatile.  It's used by other methods that have an in-memory
+   cache. */
+const STORE_METHOD *STORE_Memory(void);
+#if 0 /* Not yet implemented */
+/* This is the directory store.  It does everything except revoking and updating,
+   and uses STORE_Memory() to cache things in memory. */
+const STORE_METHOD *STORE_Directory(void);
+/* This is the file store.  It does everything except revoking and updating,
+   and uses STORE_Memory() to cache things in memory.  Certificates are added
+   to it with the store operation, and it will only get cached certificates. */
+const STORE_METHOD *STORE_File(void);
+#endif
+
+/* Store functions take a type code for the type of data they should store
+   or fetch */
+typedef enum STORE_object_types
+	{
+	STORE_OBJECT_TYPE_X509_CERTIFICATE=	0x01, /* X509 * */
+	STORE_OBJECT_TYPE_X509_CRL=		0x02, /* X509_CRL * */
+	STORE_OBJECT_TYPE_PRIVATE_KEY=		0x03, /* EVP_PKEY * */
+	STORE_OBJECT_TYPE_PUBLIC_KEY=		0x04, /* EVP_PKEY * */
+	STORE_OBJECT_TYPE_NUMBER=		0x05, /* BIGNUM * */
+	STORE_OBJECT_TYPE_ARBITRARY=		0x06, /* BUF_MEM * */
+	STORE_OBJECT_TYPE_NUM=			0x06  /* The amount of known
+							 object types */
+	} STORE_OBJECT_TYPES;
+/* List of text strings corresponding to the object types. */
+extern const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1];
+
+/* Some store functions take a parameter list.  Those parameters come with
+   one of the following codes. The comments following the codes below indicate
+   what type the value should be a pointer to. */
+typedef enum STORE_params
+	{
+	STORE_PARAM_EVP_TYPE=			0x01, /* int */
+	STORE_PARAM_BITS=			0x02, /* size_t */
+	STORE_PARAM_KEY_PARAMETERS=		0x03, /* ??? */
+	STORE_PARAM_KEY_NO_PARAMETERS=		0x04, /* N/A */
+	STORE_PARAM_AUTH_PASSPHRASE=		0x05, /* char * */
+	STORE_PARAM_AUTH_KRB5_TICKET=		0x06, /* void * */
+	STORE_PARAM_TYPE_NUM=			0x06  /* The amount of known
+							 parameter types */
+	} STORE_PARAM_TYPES;
+/* Parameter value sizes.  -1 means unknown, anything else is the required size. */
+extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1];
+
+/* Store functions take attribute lists.  Those attributes come with codes.
+   The comments following the codes below indicate what type the value should
+   be a pointer to. */
+typedef enum STORE_attribs
+	{
+	STORE_ATTR_END=				0x00,
+	STORE_ATTR_FRIENDLYNAME=		0x01, /* C string */
+	STORE_ATTR_KEYID=			0x02, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUERKEYID=			0x03, /* 160 bit string (SHA1) */
+	STORE_ATTR_SUBJECTKEYID=		0x04, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUERSERIALHASH=		0x05, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUER=			0x06, /* X509_NAME * */
+	STORE_ATTR_SERIAL=			0x07, /* BIGNUM * */
+	STORE_ATTR_SUBJECT=			0x08, /* X509_NAME * */
+	STORE_ATTR_CERTHASH=			0x09, /* 160 bit string (SHA1) */
+	STORE_ATTR_EMAIL=			0x0a, /* C string */
+	STORE_ATTR_FILENAME=			0x0b, /* C string */
+	STORE_ATTR_TYPE_NUM=			0x0b, /* The amount of known
+							 attribute types */
+	STORE_ATTR_OR=				0xff  /* This is a special
+							 separator, which
+							 expresses the OR
+							 operation.  */
+	} STORE_ATTR_TYPES;
+/* Attribute value sizes.  -1 means unknown, anything else is the required size. */
+extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1];
+
+typedef enum STORE_certificate_status
+	{
+	STORE_X509_VALID=			0x00,
+	STORE_X509_EXPIRED=			0x01,
+	STORE_X509_SUSPENDED=			0x02,
+	STORE_X509_REVOKED=			0x03
+	} STORE_CERTIFICATE_STATUS;
+
+/* Engine store functions will return a structure that contains all the necessary
+ * information, including revokation status for certificates.  This is really not
+ * needed for application authors, as the ENGINE framework functions will extract
+ * the OpenSSL-specific information when at all possible.  However, for engine
+ * authors, it's crucial to know this structure.  */
+typedef struct STORE_OBJECT_st
+	{
+	STORE_OBJECT_TYPES type;
+	union
+		{
+		struct
+			{
+			STORE_CERTIFICATE_STATUS status;
+			X509 *certificate;
+			} x509;
+		X509_CRL *crl;
+		EVP_PKEY *key;
+		BIGNUM *number;
+		BUF_MEM *arbitrary;
+		} data;
+	} STORE_OBJECT;
+DECLARE_STACK_OF(STORE_OBJECT)
+STORE_OBJECT *STORE_OBJECT_new(void);
+void STORE_OBJECT_free(STORE_OBJECT *data);
+
+
+
+/* The following functions handle the storage. They return 0, a negative number
+   or NULL on error, anything else on success. */
+X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509 *STORE_list_certificate_next(STORE *e, void *handle);
+int STORE_list_certificate_end(STORE *e, void *handle);
+int STORE_list_certificate_endp(STORE *e, void *handle);
+EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_private_key(STORE *e, EVP_PKEY *data,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle);
+int STORE_list_private_key_end(STORE *e, void *handle);
+int STORE_list_private_key_endp(STORE *e, void *handle);
+EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_public_key(STORE *e, EVP_PKEY *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle);
+int STORE_list_public_key_end(STORE *e, void *handle);
+int STORE_list_public_key_endp(STORE *e, void *handle);
+X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509_CRL *STORE_list_crl_next(STORE *e, void *handle);
+int STORE_list_crl_end(STORE *e, void *handle);
+int STORE_list_crl_endp(STORE *e, void *handle);
+int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+
+
+/* Create and manipulate methods */
+STORE_METHOD *STORE_create_method(char *name);
+void STORE_destroy_method(STORE_METHOD *store_method);
+
+/* These callback types are use for store handlers */
+typedef int (*STORE_INITIALISE_FUNC_PTR)(STORE *);
+typedef void (*STORE_CLEANUP_FUNC_PTR)(STORE *);
+typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle);
+typedef int (*STORE_END_OBJECT_FUNC_PTR)(STORE *, void *handle);
+typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_STORE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, STORE_OBJECT *data, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_GENERIC_FUNC_PTR)(STORE *, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_CTRL_FUNC_PTR)(STORE *, int cmd, long l, void *p, void (*f)(void));
+
+int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f);
+int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f);
+int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f);
+int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f);
+int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f);
+int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR store_f);
+int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f);
+int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f);
+int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f);
+int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f);
+int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f);
+int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f);
+
+STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm);
+STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm);
+STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm);
+STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm);
+STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm);
+STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm);
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm);
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm);
+STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm);
+STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm);
+STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm);
+STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm);
+
+/* Method helper structures and functions. */
+
+/* This structure is the result of parsing through the information in a list
+   of OPENSSL_ITEMs.  It stores all the necessary information in a structured
+   way.*/
+typedef struct STORE_attr_info_st STORE_ATTR_INFO;
+
+/* Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO.
+   Note that we do this in the list form, since the list of OPENSSL_ITEMs can
+   come in blocks separated with STORE_ATTR_OR.  Note that the value returned
+   by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). */
+void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes);
+STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle);
+int STORE_parse_attrs_end(void *handle);
+int STORE_parse_attrs_endp(void *handle);
+
+/* Creator and destructor */
+STORE_ATTR_INFO *STORE_ATTR_INFO_new(void);
+int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs);
+
+/* Manipulators */
+char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
+	STORE_ATTR_TYPES code);
+X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size);
+int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size);
+int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn);
+int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number);
+int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size);
+int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size);
+int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn);
+int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number);
+
+/* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
+   in each contained attribute. */
+int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Check if the set of attributes in a is within the range of attributes
+   set in b. */
+int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Check if the set of attributes in a are also set in b. */
+int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */
+int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_STORE_strings(void);
+
+/* Error codes for the STORE functions. */
+
+/* Function codes. */
+#define STORE_F_MEM_DELETE				 134
+#define STORE_F_MEM_GENERATE				 135
+#define STORE_F_MEM_LIST_END				 168
+#define STORE_F_MEM_LIST_NEXT				 136
+#define STORE_F_MEM_LIST_START				 137
+#define STORE_F_MEM_MODIFY				 169
+#define STORE_F_MEM_STORE				 138
+#define STORE_F_STORE_ATTR_INFO_GET0_CSTR		 139
+#define STORE_F_STORE_ATTR_INFO_GET0_DN			 140
+#define STORE_F_STORE_ATTR_INFO_GET0_NUMBER		 141
+#define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR		 142
+#define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR		 143
+#define STORE_F_STORE_ATTR_INFO_MODIFY_DN		 144
+#define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER		 145
+#define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR		 146
+#define STORE_F_STORE_ATTR_INFO_SET_CSTR		 147
+#define STORE_F_STORE_ATTR_INFO_SET_DN			 148
+#define STORE_F_STORE_ATTR_INFO_SET_NUMBER		 149
+#define STORE_F_STORE_ATTR_INFO_SET_SHA1STR		 150
+#define STORE_F_STORE_CERTIFICATE			 170
+#define STORE_F_STORE_CTRL				 161
+#define STORE_F_STORE_DELETE_ARBITRARY			 158
+#define STORE_F_STORE_DELETE_CERTIFICATE		 102
+#define STORE_F_STORE_DELETE_CRL			 103
+#define STORE_F_STORE_DELETE_NUMBER			 104
+#define STORE_F_STORE_DELETE_PRIVATE_KEY		 105
+#define STORE_F_STORE_DELETE_PUBLIC_KEY			 106
+#define STORE_F_STORE_GENERATE_CRL			 107
+#define STORE_F_STORE_GENERATE_KEY			 108
+#define STORE_F_STORE_GET_ARBITRARY			 159
+#define STORE_F_STORE_GET_CERTIFICATE			 109
+#define STORE_F_STORE_GET_CRL				 110
+#define STORE_F_STORE_GET_NUMBER			 111
+#define STORE_F_STORE_GET_PRIVATE_KEY			 112
+#define STORE_F_STORE_GET_PUBLIC_KEY			 113
+#define STORE_F_STORE_LIST_CERTIFICATE_END		 114
+#define STORE_F_STORE_LIST_CERTIFICATE_ENDP		 153
+#define STORE_F_STORE_LIST_CERTIFICATE_NEXT		 115
+#define STORE_F_STORE_LIST_CERTIFICATE_START		 116
+#define STORE_F_STORE_LIST_CRL_END			 117
+#define STORE_F_STORE_LIST_CRL_ENDP			 154
+#define STORE_F_STORE_LIST_CRL_NEXT			 118
+#define STORE_F_STORE_LIST_CRL_START			 119
+#define STORE_F_STORE_LIST_PRIVATE_KEY_END		 120
+#define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP		 155
+#define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT		 121
+#define STORE_F_STORE_LIST_PRIVATE_KEY_START		 122
+#define STORE_F_STORE_LIST_PUBLIC_KEY_END		 123
+#define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP		 156
+#define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT		 124
+#define STORE_F_STORE_LIST_PUBLIC_KEY_START		 125
+#define STORE_F_STORE_MODIFY_ARBITRARY			 162
+#define STORE_F_STORE_MODIFY_CERTIFICATE		 163
+#define STORE_F_STORE_MODIFY_CRL			 164
+#define STORE_F_STORE_MODIFY_NUMBER			 165
+#define STORE_F_STORE_MODIFY_PRIVATE_KEY		 166
+#define STORE_F_STORE_MODIFY_PUBLIC_KEY			 167
+#define STORE_F_STORE_NEW_ENGINE			 133
+#define STORE_F_STORE_NEW_METHOD			 132
+#define STORE_F_STORE_PARSE_ATTRS_END			 151
+#define STORE_F_STORE_PARSE_ATTRS_ENDP			 172
+#define STORE_F_STORE_PARSE_ATTRS_NEXT			 152
+#define STORE_F_STORE_PARSE_ATTRS_START			 171
+#define STORE_F_STORE_REVOKE_CERTIFICATE		 129
+#define STORE_F_STORE_REVOKE_PRIVATE_KEY		 130
+#define STORE_F_STORE_REVOKE_PUBLIC_KEY			 131
+#define STORE_F_STORE_STORE_ARBITRARY			 157
+#define STORE_F_STORE_STORE_CERTIFICATE			 100
+#define STORE_F_STORE_STORE_CRL				 101
+#define STORE_F_STORE_STORE_NUMBER			 126
+#define STORE_F_STORE_STORE_PRIVATE_KEY			 127
+#define STORE_F_STORE_STORE_PUBLIC_KEY			 128
+
+/* Reason codes. */
+#define STORE_R_ALREADY_HAS_A_VALUE			 127
+#define STORE_R_FAILED_DELETING_ARBITRARY		 132
+#define STORE_R_FAILED_DELETING_CERTIFICATE		 100
+#define STORE_R_FAILED_DELETING_KEY			 101
+#define STORE_R_FAILED_DELETING_NUMBER			 102
+#define STORE_R_FAILED_GENERATING_CRL			 103
+#define STORE_R_FAILED_GENERATING_KEY			 104
+#define STORE_R_FAILED_GETTING_ARBITRARY		 133
+#define STORE_R_FAILED_GETTING_CERTIFICATE		 105
+#define STORE_R_FAILED_GETTING_KEY			 106
+#define STORE_R_FAILED_GETTING_NUMBER			 107
+#define STORE_R_FAILED_LISTING_CERTIFICATES		 108
+#define STORE_R_FAILED_LISTING_KEYS			 109
+#define STORE_R_FAILED_MODIFYING_ARBITRARY		 138
+#define STORE_R_FAILED_MODIFYING_CERTIFICATE		 139
+#define STORE_R_FAILED_MODIFYING_CRL			 140
+#define STORE_R_FAILED_MODIFYING_NUMBER			 141
+#define STORE_R_FAILED_MODIFYING_PRIVATE_KEY		 142
+#define STORE_R_FAILED_MODIFYING_PUBLIC_KEY		 143
+#define STORE_R_FAILED_REVOKING_CERTIFICATE		 110
+#define STORE_R_FAILED_REVOKING_KEY			 111
+#define STORE_R_FAILED_STORING_ARBITRARY		 134
+#define STORE_R_FAILED_STORING_CERTIFICATE		 112
+#define STORE_R_FAILED_STORING_KEY			 113
+#define STORE_R_FAILED_STORING_NUMBER			 114
+#define STORE_R_NOT_IMPLEMENTED				 128
+#define STORE_R_NO_CONTROL_FUNCTION			 144
+#define STORE_R_NO_DELETE_ARBITRARY_FUNCTION		 135
+#define STORE_R_NO_DELETE_NUMBER_FUNCTION		 115
+#define STORE_R_NO_DELETE_OBJECT_FUNCTION		 116
+#define STORE_R_NO_GENERATE_CRL_FUNCTION		 117
+#define STORE_R_NO_GENERATE_OBJECT_FUNCTION		 118
+#define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION	 136
+#define STORE_R_NO_GET_OBJECT_FUNCTION			 119
+#define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION		 120
+#define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION		 131
+#define STORE_R_NO_LIST_OBJECT_END_FUNCTION		 121
+#define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION		 122
+#define STORE_R_NO_LIST_OBJECT_START_FUNCTION		 123
+#define STORE_R_NO_MODIFY_OBJECT_FUNCTION		 145
+#define STORE_R_NO_REVOKE_OBJECT_FUNCTION		 124
+#define STORE_R_NO_STORE				 129
+#define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION	 137
+#define STORE_R_NO_STORE_OBJECT_FUNCTION		 125
+#define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION		 126
+#define STORE_R_NO_VALUE				 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/symhacks.h b/dep/include/openssl/symhacks.h
new file mode 100644
index 000000000..7e3602d2e
--- /dev/null
+++ b/dep/include/openssl/symhacks.h
@@ -0,0 +1,383 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SYMHACKS_H
+#define HEADER_SYMHACKS_H
+
+#include 
+
+/* Hacks to solve the problem with linkers incapable of handling very long
+   symbol names.  In the case of VMS, the limit is 31 characters on VMS for
+   VAX. */
+#ifdef OPENSSL_SYS_VMS
+
+/* Hack a long name in crypto/ex_data.c */
+#undef CRYPTO_get_ex_data_implementation
+#define CRYPTO_get_ex_data_implementation	CRYPTO_get_ex_data_impl
+#undef CRYPTO_set_ex_data_implementation
+#define CRYPTO_set_ex_data_implementation	CRYPTO_set_ex_data_impl
+
+/* Hack a long name in crypto/asn1/a_mbstr.c */
+#undef ASN1_STRING_set_default_mask_asc
+#define ASN1_STRING_set_default_mask_asc	ASN1_STRING_set_def_mask_asc
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
+#undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO	i2d_ASN1_SET_OF_PKCS7_SIGINF
+#undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO	d2i_ASN1_SET_OF_PKCS7_SIGINF
+#endif
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
+#undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO	i2d_ASN1_SET_OF_PKCS7_RECINF
+#undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO	d2i_ASN1_SET_OF_PKCS7_RECINF
+#endif
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
+#undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION	i2d_ASN1_SET_OF_ACC_DESC
+#undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION	d2i_ASN1_SET_OF_ACC_DESC
+#endif
+
+/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
+#undef PEM_read_NETSCAPE_CERT_SEQUENCE
+#define PEM_read_NETSCAPE_CERT_SEQUENCE		PEM_read_NS_CERT_SEQ
+#undef PEM_write_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_NETSCAPE_CERT_SEQUENCE	PEM_write_NS_CERT_SEQ
+#undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE	PEM_read_bio_NS_CERT_SEQ
+#undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE	PEM_write_bio_NS_CERT_SEQ
+#undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE	PEM_write_cb_bio_NS_CERT_SEQ
+
+/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
+#undef PEM_read_PKCS8_PRIV_KEY_INFO
+#define PEM_read_PKCS8_PRIV_KEY_INFO		PEM_read_P8_PRIV_KEY_INFO
+#undef PEM_write_PKCS8_PRIV_KEY_INFO
+#define PEM_write_PKCS8_PRIV_KEY_INFO		PEM_write_P8_PRIV_KEY_INFO
+#undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_read_bio_PKCS8_PRIV_KEY_INFO	PEM_read_bio_P8_PRIV_KEY_INFO
+#undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_write_bio_PKCS8_PRIV_KEY_INFO	PEM_write_bio_P8_PRIV_KEY_INFO
+#undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO	PEM_wrt_cb_bio_P8_PRIV_KEY_INFO
+
+/* Hack other PEM names */
+#undef PEM_write_bio_PKCS8PrivateKey_nid
+#define PEM_write_bio_PKCS8PrivateKey_nid	PEM_write_bio_PKCS8PrivKey_nid
+
+/* Hack some long X509 names */
+#undef X509_REVOKED_get_ext_by_critical
+#define X509_REVOKED_get_ext_by_critical	X509_REVOKED_get_ext_by_critic
+#undef X509_policy_tree_get0_user_policies
+#define X509_policy_tree_get0_user_policies	X509_pcy_tree_get0_usr_policies
+#undef X509_policy_node_get0_qualifiers
+#define X509_policy_node_get0_qualifiers	X509_pcy_node_get0_qualifiers
+#undef X509_STORE_CTX_get_explicit_policy
+#define X509_STORE_CTX_get_explicit_policy	X509_STORE_CTX_get_expl_policy
+
+/* Hack some long CRYPTO names */
+#undef CRYPTO_set_dynlock_destroy_callback
+#define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
+#undef CRYPTO_set_dynlock_create_callback
+#define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
+#undef CRYPTO_set_dynlock_lock_callback
+#define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
+#undef CRYPTO_get_dynlock_lock_callback
+#define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
+#undef CRYPTO_get_dynlock_destroy_callback
+#define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
+#undef CRYPTO_get_dynlock_create_callback
+#define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
+#undef CRYPTO_set_locked_mem_ex_functions
+#define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
+#undef CRYPTO_get_locked_mem_ex_functions
+#define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs
+
+/* Hack some long SSL names */
+#undef SSL_CTX_set_default_verify_paths
+#define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
+#undef SSL_get_ex_data_X509_STORE_CTX_idx
+#define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
+#undef SSL_add_file_cert_subjects_to_stack
+#define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
+#undef SSL_add_dir_cert_subjects_to_stack
+#define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
+#undef SSL_CTX_use_certificate_chain_file
+#define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
+#undef SSL_CTX_set_cert_verify_callback
+#define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
+#undef SSL_CTX_set_default_passwd_cb_userdata
+#define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
+#undef SSL_COMP_get_compression_methods
+#define SSL_COMP_get_compression_methods	SSL_COMP_get_compress_methods
+
+/* Hack some long ENGINE names */
+#undef ENGINE_get_default_BN_mod_exp_crt
+#define ENGINE_get_default_BN_mod_exp_crt	ENGINE_get_def_BN_mod_exp_crt
+#undef ENGINE_set_default_BN_mod_exp_crt
+#define ENGINE_set_default_BN_mod_exp_crt	ENGINE_set_def_BN_mod_exp_crt
+#undef ENGINE_set_load_privkey_function
+#define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
+#undef ENGINE_get_load_privkey_function
+#define ENGINE_get_load_privkey_function        ENGINE_get_load_privkey_fn
+
+/* Hack some long OCSP names */
+#undef OCSP_REQUEST_get_ext_by_critical
+#define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
+#undef OCSP_BASICRESP_get_ext_by_critical
+#define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
+#undef OCSP_SINGLERESP_get_ext_by_critical
+#define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit
+
+/* Hack some long DES names */
+#undef _ossl_old_des_ede3_cfb64_encrypt
+#define _ossl_old_des_ede3_cfb64_encrypt	_ossl_odes_ede3_cfb64_encrypt
+#undef _ossl_old_des_ede3_ofb64_encrypt
+#define _ossl_old_des_ede3_ofb64_encrypt	_ossl_odes_ede3_ofb64_encrypt
+
+/* Hack some long EVP names */
+#undef OPENSSL_add_all_algorithms_noconf
+#define OPENSSL_add_all_algorithms_noconf	OPENSSL_add_all_algo_noconf
+#undef OPENSSL_add_all_algorithms_conf
+#define OPENSSL_add_all_algorithms_conf		OPENSSL_add_all_algo_conf
+
+/* Hack some long EC names */
+#undef EC_GROUP_set_point_conversion_form
+#define EC_GROUP_set_point_conversion_form	EC_GROUP_set_point_conv_form
+#undef EC_GROUP_get_point_conversion_form
+#define EC_GROUP_get_point_conversion_form	EC_GROUP_get_point_conv_form
+#undef EC_GROUP_clear_free_all_extra_data
+#define EC_GROUP_clear_free_all_extra_data	EC_GROUP_clr_free_all_xtra_data
+#undef EC_POINT_set_Jprojective_coordinates_GFp
+#define EC_POINT_set_Jprojective_coordinates_GFp \
+                                                EC_POINT_set_Jproj_coords_GFp
+#undef EC_POINT_get_Jprojective_coordinates_GFp
+#define EC_POINT_get_Jprojective_coordinates_GFp \
+                                                EC_POINT_get_Jproj_coords_GFp
+#undef EC_POINT_set_affine_coordinates_GFp
+#define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
+#undef EC_POINT_get_affine_coordinates_GFp
+#define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
+#undef EC_POINT_set_compressed_coordinates_GFp
+#define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
+#undef EC_POINT_set_affine_coordinates_GF2m
+#define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
+#undef EC_POINT_get_affine_coordinates_GF2m
+#define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
+#undef EC_POINT_set_compressed_coordinates_GF2m
+#define EC_POINT_set_compressed_coordinates_GF2m \
+                                                EC_POINT_set_compr_coords_GF2m
+#undef ec_GF2m_simple_group_clear_finish
+#define ec_GF2m_simple_group_clear_finish        ec_GF2m_simple_grp_clr_finish
+#undef ec_GF2m_simple_group_check_discriminant
+#define ec_GF2m_simple_group_check_discriminant	ec_GF2m_simple_grp_chk_discrim
+#undef ec_GF2m_simple_point_clear_finish
+#define ec_GF2m_simple_point_clear_finish        ec_GF2m_simple_pt_clr_finish
+#undef ec_GF2m_simple_point_set_to_infinity
+#define ec_GF2m_simple_point_set_to_infinity     ec_GF2m_simple_pt_set_to_inf
+#undef ec_GF2m_simple_points_make_affine
+#define ec_GF2m_simple_points_make_affine        ec_GF2m_simple_pts_make_affine
+#undef ec_GF2m_simple_point_set_affine_coordinates
+#define ec_GF2m_simple_point_set_affine_coordinates \
+                                                ec_GF2m_smp_pt_set_af_coords
+#undef ec_GF2m_simple_point_get_affine_coordinates
+#define ec_GF2m_simple_point_get_affine_coordinates \
+                                                ec_GF2m_smp_pt_get_af_coords
+#undef ec_GF2m_simple_set_compressed_coordinates
+#define ec_GF2m_simple_set_compressed_coordinates \
+                                                ec_GF2m_smp_set_compr_coords
+#undef ec_GFp_simple_group_set_curve_GFp
+#define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
+#undef ec_GFp_simple_group_get_curve_GFp
+#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#undef ec_GFp_simple_group_clear_finish
+#define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
+#undef ec_GFp_simple_group_set_generator
+#define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
+#undef ec_GFp_simple_group_get0_generator
+#define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
+#undef ec_GFp_simple_group_get_cofactor
+#define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
+#undef ec_GFp_simple_point_clear_finish
+#define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
+#undef ec_GFp_simple_point_set_to_infinity
+#define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
+#undef ec_GFp_simple_points_make_affine
+#define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
+#undef ec_GFp_simple_group_get_curve_GFp
+#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#undef ec_GFp_simple_set_Jprojective_coordinates_GFp
+#define ec_GFp_simple_set_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_set_Jproj_coords_GFp
+#undef ec_GFp_simple_get_Jprojective_coordinates_GFp
+#define ec_GFp_simple_get_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_get_Jproj_coords_GFp
+#undef ec_GFp_simple_point_set_affine_coordinates_GFp
+#define ec_GFp_simple_point_set_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_set_af_coords_GFp
+#undef ec_GFp_simple_point_get_affine_coordinates_GFp
+#define ec_GFp_simple_point_get_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_get_af_coords_GFp
+#undef ec_GFp_simple_set_compressed_coordinates_GFp
+#define ec_GFp_simple_set_compressed_coordinates_GFp \
+                                                ec_GFp_smp_set_compr_coords_GFp
+#undef ec_GFp_simple_point_set_affine_coordinates
+#define ec_GFp_simple_point_set_affine_coordinates \
+                                                ec_GFp_smp_pt_set_af_coords
+#undef ec_GFp_simple_point_get_affine_coordinates
+#define ec_GFp_simple_point_get_affine_coordinates \
+                                                ec_GFp_smp_pt_get_af_coords
+#undef ec_GFp_simple_set_compressed_coordinates
+#define ec_GFp_simple_set_compressed_coordinates \
+                                                ec_GFp_smp_set_compr_coords
+#undef ec_GFp_simple_group_check_discriminant
+#define ec_GFp_simple_group_check_discriminant	ec_GFp_simple_grp_chk_discrim
+
+/* Hack som long STORE names */
+#undef STORE_method_set_initialise_function
+#define STORE_method_set_initialise_function	STORE_meth_set_initialise_fn
+#undef STORE_method_set_cleanup_function
+#define STORE_method_set_cleanup_function	STORE_meth_set_cleanup_fn
+#undef STORE_method_set_generate_function
+#define STORE_method_set_generate_function	STORE_meth_set_generate_fn
+#undef STORE_method_set_modify_function
+#define STORE_method_set_modify_function	STORE_meth_set_modify_fn
+#undef STORE_method_set_revoke_function
+#define STORE_method_set_revoke_function	STORE_meth_set_revoke_fn
+#undef STORE_method_set_delete_function
+#define STORE_method_set_delete_function	STORE_meth_set_delete_fn
+#undef STORE_method_set_list_start_function
+#define STORE_method_set_list_start_function	STORE_meth_set_list_start_fn
+#undef STORE_method_set_list_next_function
+#define STORE_method_set_list_next_function	STORE_meth_set_list_next_fn
+#undef STORE_method_set_list_end_function
+#define STORE_method_set_list_end_function	STORE_meth_set_list_end_fn
+#undef STORE_method_set_update_store_function
+#define STORE_method_set_update_store_function	STORE_meth_set_update_store_fn
+#undef STORE_method_set_lock_store_function
+#define STORE_method_set_lock_store_function	STORE_meth_set_lock_store_fn
+#undef STORE_method_set_unlock_store_function
+#define STORE_method_set_unlock_store_function	STORE_meth_set_unlock_store_fn
+#undef STORE_method_get_initialise_function
+#define STORE_method_get_initialise_function	STORE_meth_get_initialise_fn
+#undef STORE_method_get_cleanup_function
+#define STORE_method_get_cleanup_function	STORE_meth_get_cleanup_fn
+#undef STORE_method_get_generate_function
+#define STORE_method_get_generate_function	STORE_meth_get_generate_fn
+#undef STORE_method_get_modify_function
+#define STORE_method_get_modify_function	STORE_meth_get_modify_fn
+#undef STORE_method_get_revoke_function
+#define STORE_method_get_revoke_function	STORE_meth_get_revoke_fn
+#undef STORE_method_get_delete_function
+#define STORE_method_get_delete_function	STORE_meth_get_delete_fn
+#undef STORE_method_get_list_start_function
+#define STORE_method_get_list_start_function	STORE_meth_get_list_start_fn
+#undef STORE_method_get_list_next_function
+#define STORE_method_get_list_next_function	STORE_meth_get_list_next_fn
+#undef STORE_method_get_list_end_function
+#define STORE_method_get_list_end_function	STORE_meth_get_list_end_fn
+#undef STORE_method_get_update_store_function
+#define STORE_method_get_update_store_function	STORE_meth_get_update_store_fn
+#undef STORE_method_get_lock_store_function
+#define STORE_method_get_lock_store_function	STORE_meth_get_lock_store_fn
+#undef STORE_method_get_unlock_store_function
+#define STORE_method_get_unlock_store_function	STORE_meth_get_unlock_store_fn
+
+#endif /* defined OPENSSL_SYS_VMS */
+
+
+/* Case insensiteve linking causes problems.... */
+#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+#undef ERR_load_CRYPTO_strings
+#define ERR_load_CRYPTO_strings			ERR_load_CRYPTOlib_strings
+#undef OCSP_crlID_new
+#define OCSP_crlID_new                          OCSP_crlID2_new
+
+#undef d2i_ECPARAMETERS
+#define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#undef i2d_ECPARAMETERS
+#define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#undef d2i_ECPKPARAMETERS
+#define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#undef i2d_ECPKPARAMETERS
+#define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+
+/* These functions do not seem to exist!  However, I'm paranoid...
+   Original command in x509v3.h:
+   These functions are being redefined in another directory,
+   and clash when the linker is case-insensitive, so let's
+   hide them a little, by giving them an extra 'o' at the
+   beginning of the name... */
+#undef X509v3_cleanup_extensions
+#define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#undef X509v3_add_extension
+#define X509v3_add_extension                    oX509v3_add_extension
+#undef X509v3_add_netscape_extensions
+#define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#undef X509v3_add_standard_extensions
+#define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+
+
+#endif
+
+
+#endif /* ! defined HEADER_VMS_IDHACKS_H */
diff --git a/dep/include/openssl/tls1.h b/dep/include/openssl/tls1.h
new file mode 100644
index 000000000..e5f9aa1ef
--- /dev/null
+++ b/dep/include/openssl/tls1.h
@@ -0,0 +1,305 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_TLS1_H 
+#define HEADER_TLS1_H 
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	0
+
+#define TLS1_VERSION			0x0301
+#define TLS1_VERSION_MAJOR		0x03
+#define TLS1_VERSION_MINOR		0x01
+
+#define TLS1_AD_DECRYPTION_FAILED	21
+#define TLS1_AD_RECORD_OVERFLOW		22
+#define TLS1_AD_UNKNOWN_CA		48	/* fatal */
+#define TLS1_AD_ACCESS_DENIED		49	/* fatal */
+#define TLS1_AD_DECODE_ERROR		50	/* fatal */
+#define TLS1_AD_DECRYPT_ERROR		51
+#define TLS1_AD_EXPORT_RESTRICTION	60	/* fatal */
+#define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
+#define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
+#define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
+#define TLS1_AD_USER_CANCELLED		90
+#define TLS1_AD_NO_RENEGOTIATION	100
+
+/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
+ * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
+ * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
+ * shouldn't. */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061
+#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA		0x03000062
+#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	0x03000063
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA		0x03000064
+#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	0x03000065
+#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA		0x03000066
+
+/* AES ciphersuites from RFC3268 */
+
+#define TLS1_CK_RSA_WITH_AES_128_SHA			0x0300002F
+#define TLS1_CK_DH_DSS_WITH_AES_128_SHA			0x03000030
+#define TLS1_CK_DH_RSA_WITH_AES_128_SHA			0x03000031
+#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA		0x03000032
+#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA		0x03000033
+#define TLS1_CK_ADH_WITH_AES_128_SHA			0x03000034
+
+#define TLS1_CK_RSA_WITH_AES_256_SHA			0x03000035
+#define TLS1_CK_DH_DSS_WITH_AES_256_SHA			0x03000036
+#define TLS1_CK_DH_RSA_WITH_AES_256_SHA			0x03000037
+#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA		0x03000038
+#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA		0x03000039
+#define TLS1_CK_ADH_WITH_AES_256_SHA			0x0300003A
+
+/* Camellia ciphersuites from RFC4132 */
+#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA		0x03000041
+#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	0x03000042
+#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA	0x03000043
+#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA	0x03000044
+#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA	0x03000045
+#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA		0x03000046
+
+#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA		0x03000084
+#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA	0x03000085
+#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA	0x03000086
+#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA	0x03000087
+#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA	0x03000088
+#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA		0x03000089
+
+/* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */
+#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
+#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
+#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005
+
+#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
+#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
+#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A
+
+#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
+#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
+#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F
+
+#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
+#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
+#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
+#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014
+
+#define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
+#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
+#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
+#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
+#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
+
+/* XXX
+ * Inconsistency alert:
+ * The OpenSSL names of ciphers with ephemeral DH here include the string
+ * "DHE", while elsewhere it has always been "EDH".
+ * (The alias for the list of all such ciphers also is "EDH".)
+ * The specifications speak of "EDH"; maybe we should allow both forms
+ * for everything. */
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5		"EXP1024-RC4-MD5"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	"EXP1024-RC2-CBC-MD5"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DES-CBC-SHA"
+#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DHE-DSS-DES-CBC-SHA"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA		"EXP1024-RC4-SHA"
+#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	"EXP1024-DHE-DSS-RC4-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA		"DHE-DSS-RC4-SHA"
+
+/* AES ciphersuites from RFC3268 */
+#define TLS1_TXT_RSA_WITH_AES_128_SHA			"AES128-SHA"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA		"DH-DSS-AES128-SHA"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA		"DH-RSA-AES128-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA		"DHE-DSS-AES128-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA		"DHE-RSA-AES128-SHA"
+#define TLS1_TXT_ADH_WITH_AES_128_SHA			"ADH-AES128-SHA"
+
+#define TLS1_TXT_RSA_WITH_AES_256_SHA			"AES256-SHA"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA		"DH-DSS-AES256-SHA"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA		"DH-RSA-AES256-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA		"DHE-DSS-AES256-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA		"DHE-RSA-AES256-SHA"
+#define TLS1_TXT_ADH_WITH_AES_256_SHA			"ADH-AES256-SHA"
+
+/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */
+#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
+
+#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"
+
+#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
+
+#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"
+
+#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
+
+/* Camellia ciphersuites form RFC4132 */
+#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA		"CAMELLIA128-SHA"
+#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	"DH-DSS-CAMELLIA128-SHA"
+#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA	"DH-RSA-CAMELLIA128-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA	"DHE-DSS-CAMELLIA128-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA	"DHE-RSA-CAMELLIA128-SHA"
+#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA		"ADH-CAMELLIA128-SHA"
+
+#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA		"CAMELLIA256-SHA"
+#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA	"DH-DSS-CAMELLIA256-SHA"
+#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA	"DH-RSA-CAMELLIA256-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA	"DHE-DSS-CAMELLIA256-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA	"DHE-RSA-CAMELLIA256-SHA"
+#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA		"ADH-CAMELLIA256-SHA"
+
+
+#define TLS_CT_RSA_SIGN			1
+#define TLS_CT_DSS_SIGN			2
+#define TLS_CT_RSA_FIXED_DH		3
+#define TLS_CT_DSS_FIXED_DH		4
+#define TLS_CT_ECDSA_SIGN		64
+#define TLS_CT_RSA_FIXED_ECDH		65
+#define TLS_CT_ECDSA_FIXED_ECDH 	66
+#define TLS_CT_NUMBER			7
+
+#define TLS1_FINISH_MAC_LENGTH		12
+
+#define TLS_MD_MAX_CONST_SIZE			20
+#define TLS_MD_CLIENT_FINISH_CONST		"client finished"
+#define TLS_MD_CLIENT_FINISH_CONST_SIZE		15
+#define TLS_MD_SERVER_FINISH_CONST		"server finished"
+#define TLS_MD_SERVER_FINISH_CONST_SIZE		15
+#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
+#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_KEY_EXPANSION_CONST		"key expansion"
+#define TLS_MD_KEY_EXPANSION_CONST_SIZE		13
+#define TLS_MD_CLIENT_WRITE_KEY_CONST		"client write key"
+#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
+#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_IV_BLOCK_CONST			"IV block"
+#define TLS_MD_IV_BLOCK_CONST_SIZE		8
+#define TLS_MD_MASTER_SECRET_CONST		"master secret"
+#define TLS_MD_MASTER_SECRET_CONST_SIZE		13
+
+#ifdef CHARSET_EBCDIC
+#undef TLS_MD_CLIENT_FINISH_CONST
+#define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*client finished*/
+#undef TLS_MD_SERVER_FINISH_CONST
+#define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*server finished*/
+#undef TLS_MD_SERVER_WRITE_KEY_CONST
+#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
+#undef TLS_MD_KEY_EXPANSION_CONST
+#define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"  /*key expansion*/
+#undef TLS_MD_CLIENT_WRITE_KEY_CONST
+#define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*client write key*/
+#undef TLS_MD_SERVER_WRITE_KEY_CONST
+#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
+#undef TLS_MD_IV_BLOCK_CONST
+#define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"  /*IV block*/
+#undef TLS_MD_MASTER_SECRET_CONST
+#define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+
+
diff --git a/dep/include/openssl/tmdiff.h b/dep/include/openssl/tmdiff.h
new file mode 100644
index 000000000..af5c41c64
--- /dev/null
+++ b/dep/include/openssl/tmdiff.h
@@ -0,0 +1,93 @@
+/* crypto/tmdiff.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+/* ... erm yeah, "dynamic hash tables" you say?
+ * 
+ * And what would dynamic hash tables have to do with any of this code *now*?
+ * AFAICS, this code is only referenced by crypto/bn/exp.c which is an unused
+ * file that I doubt compiles any more. speed.c is the only thing that could
+ * use this (and it has nothing to do with hash tables), yet it instead has its
+ * own duplication of all this stuff and looks, if anything, more complete. See
+ * the corresponding note in apps/speed.c.
+ * The Bemused - Geoff
+ */
+
+#ifndef HEADER_TMDIFF_H
+#define HEADER_TMDIFF_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct ms_tm MS_TM;
+
+MS_TM *ms_time_new(void );
+void ms_time_free(MS_TM *a);
+void ms_time_get(MS_TM *a);
+double ms_time_diff(MS_TM *start, MS_TM *end);
+int ms_time_cmp(const MS_TM *ap, const MS_TM *bp);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/dep/include/openssl/txt_db.h b/dep/include/openssl/txt_db.h
new file mode 100644
index 000000000..307e1ba23
--- /dev/null
+++ b/dep/include/openssl/txt_db.h
@@ -0,0 +1,109 @@
+/* crypto/txt_db/txt_db.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_TXT_DB_H
+#define HEADER_TXT_DB_H
+
+#include 
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+#include 
+
+#define DB_ERROR_OK			0
+#define DB_ERROR_MALLOC			1
+#define DB_ERROR_INDEX_CLASH    	2
+#define DB_ERROR_INDEX_OUT_OF_RANGE	3
+#define DB_ERROR_NO_INDEX		4
+#define DB_ERROR_INSERT_INDEX_CLASH    	5
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct txt_db_st
+	{
+	int num_fields;
+	STACK /* char ** */ *data;
+	LHASH **index;
+	int (**qual)(char **);
+	long error;
+	long arg1;
+	long arg2;
+	char **arg_row;
+	} TXT_DB;
+
+#ifndef OPENSSL_NO_BIO
+TXT_DB *TXT_DB_read(BIO *in, int num);
+long TXT_DB_write(BIO *out, TXT_DB *db);
+#else
+TXT_DB *TXT_DB_read(char *in, int num);
+long TXT_DB_write(char *out, TXT_DB *db);
+#endif
+int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **),
+		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+void TXT_DB_free(TXT_DB *db);
+char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value);
+int TXT_DB_insert(TXT_DB *db,char **value);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/dep/include/openssl/ui.h b/dep/include/openssl/ui.h
new file mode 100644
index 000000000..018296412
--- /dev/null
+++ b/dep/include/openssl/ui.h
@@ -0,0 +1,381 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_H
+#define HEADER_UI_H
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include 
+#endif
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct ui_st UI; */
+/* typedef struct ui_method_st UI_METHOD; */
+
+
+/* All the following functions return -1 or NULL on error and in some cases
+   (UI_process()) -2 if interrupted or in some other way cancelled.
+   When everything is fine, they return 0, a positive value or a non-NULL
+   pointer, all depending on their purpose. */
+
+/* Creators and destructor.   */
+UI *UI_new(void);
+UI *UI_new_method(const UI_METHOD *method);
+void UI_free(UI *ui);
+
+/* The following functions are used to add strings to be printed and prompt
+   strings to prompt for data.  The names are UI_{add,dup}__string
+   and UI_{add,dup}_input_boolean.
+
+   UI_{add,dup}__string have the following meanings:
+	add	add a text or prompt string.  The pointers given to these
+		functions are used verbatim, no copying is done.
+	dup	make a copy of the text or prompt string, then add the copy
+		to the collection of strings in the user interface.
+	
+		The function is a name for the functionality that the given
+		string shall be used for.  It can be one of:
+			input	use the string as data prompt.
+			verify	use the string as verification prompt.  This
+				is used to verify a previous input.
+			info	use the string for informational output.
+			error	use the string for error output.
+   Honestly, there's currently no difference between info and error for the
+   moment.
+
+   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
+   and are typically used when one wants to prompt for a yes/no response.
+
+
+   All of the functions in this group take a UI and a prompt string.
+   The string input and verify addition functions also take a flag argument,
+   a buffer for the result to end up with, a minimum input size and a maximum
+   input size (the result buffer MUST be large enough to be able to contain
+   the maximum number of characters).  Additionally, the verify addition
+   functions takes another buffer to compare the result against.
+   The boolean input functions take an action description string (which should
+   be safe to ignore if the expected user action is obvious, for example with
+   a dialog box with an OK button and a Cancel button), a string of acceptable
+   characters to mean OK and to mean Cancel.  The two last strings are checked
+   to make sure they don't have common characters.  Additionally, the same
+   flag argument as for the string input is taken, as well as a result buffer.
+   The result buffer is required to be at least one byte long.  Depending on
+   the answer, the first character from the OK or the Cancel character strings
+   will be stored in the first byte of the result buffer.  No NUL will be
+   added, so the result is *not* a string.
+
+   On success, the all return an index of the added information.  That index
+   is usefull when retrieving results with UI_get0_result(). */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+int UI_add_info_string(UI *ui, const char *text);
+int UI_dup_info_string(UI *ui, const char *text);
+int UI_add_error_string(UI *ui, const char *text);
+int UI_dup_error_string(UI *ui, const char *text);
+
+/* These are the possible flags.  They can be or'ed together. */
+/* Use to have echoing of input */
+#define UI_INPUT_FLAG_ECHO		0x01
+/* Use a default password.  Where that password is found is completely
+   up to the application, it might for example be in the user data set
+   with UI_add_user_data().  It is not recommended to have more than
+   one input in each UI being marked with this flag, or the application
+   might get confused. */
+#define UI_INPUT_FLAG_DEFAULT_PWD	0x02
+
+/* The user of these routines may want to define flags of their own.  The core
+   UI won't look at those, but will pass them on to the method routines.  They
+   must use higher bits so they don't get confused with the UI bits above.
+   UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
+   example of use is this:
+
+	#define MY_UI_FLAG1	(0x01 << UI_INPUT_FLAG_USER_BASE)
+
+*/
+#define UI_INPUT_FLAG_USER_BASE	16
+
+
+/* The following function helps construct a prompt.  object_desc is a
+   textual short description of the object, for example "pass phrase",
+   and object_name is the name of the object (might be a card name or
+   a file name.
+   The returned string shall always be allocated on the heap with
+   OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+
+   If the ui_method doesn't contain a pointer to a user-defined prompt
+   constructor, a default string is built, looking like this:
+
+	"Enter {object_desc} for {object_name}:"
+
+   So, if object_desc has the value "pass phrase" and object_name has
+   the value "foo.key", the resulting string is:
+
+	"Enter pass phrase for foo.key:"
+*/
+char *UI_construct_prompt(UI *ui_method,
+	const char *object_desc, const char *object_name);
+
+
+/* The following function is used to store a pointer to user-specific data.
+   Any previous such pointer will be returned and replaced.
+
+   For callback purposes, this function makes a lot more sense than using
+   ex_data, since the latter requires that different parts of OpenSSL or
+   applications share the same ex_data index.
+
+   Note that the UI_OpenSSL() method completely ignores the user data.
+   Other methods may not, however.  */
+void *UI_add_user_data(UI *ui, void *user_data);
+/* We need a user data retrieving function as well.  */
+void *UI_get0_user_data(UI *ui);
+
+/* Return the result associated with a prompt given with the index i. */
+const char *UI_get0_result(UI *ui, int i);
+
+/* When all strings have been added, process the whole thing. */
+int UI_process(UI *ui);
+
+/* Give a user interface parametrised control commands.  This can be used to
+   send down an integer, a data pointer or a function pointer, as well as
+   be used to get information from a UI. */
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void));
+
+/* The commands */
+/* Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
+   OpenSSL error stack before printing any info or added error messages and
+   before any prompting. */
+#define UI_CTRL_PRINT_ERRORS		1
+/* Check if a UI_process() is possible to do again with the same instance of
+   a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
+   if not. */
+#define UI_CTRL_IS_REDOABLE		2
+
+
+/* Some methods may use extra data */
+#define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
+#define UI_get_app_data(s)             UI_get_ex_data(s,0)
+int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int UI_set_ex_data(UI *r,int idx,void *arg);
+void *UI_get_ex_data(UI *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+void UI_set_default_method(const UI_METHOD *meth);
+const UI_METHOD *UI_get_default_method(void);
+const UI_METHOD *UI_get_method(UI *ui);
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void);
+
+
+/* ---------- For method writers ---------- */
+/* A method contains a number of functions that implement the low level
+   of the User Interface.  The functions are:
+
+	an opener	This function starts a session, maybe by opening
+			a channel to a tty, or by opening a window.
+	a writer	This function is called to write a given string,
+			maybe to the tty, maybe as a field label in a
+			window.
+	a flusher	This function is called to flush everything that
+			has been output so far.  It can be used to actually
+			display a dialog box after it has been built.
+	a reader	This function is called to read a given prompt,
+			maybe from the tty, maybe from a field in a
+			window.  Note that it's called wth all string
+			structures, not only the prompt ones, so it must
+			check such things itself.
+	a closer	This function closes the session, maybe by closing
+			the channel to the tty, or closing the window.
+
+   All these functions are expected to return:
+
+	0	on error.
+	1	on success.
+	-1	on out-of-band events, for example if some prompting has
+		been canceled (by pressing Ctrl-C, for example).  This is
+		only checked when returned by the flusher or the reader.
+
+   The way this is used, the opener is first called, then the writer for all
+   strings, then the flusher, then the reader for all strings and finally the
+   closer.  Note that if you want to prompt from a terminal or other command
+   line interface, the best is to have the reader also write the prompts
+   instead of having the writer do it.  If you want to prompt from a dialog
+   box, the writer can be used to build up the contents of the box, and the
+   flusher to actually display the box and run the event loop until all data
+   has been given, after which the reader only grabs the given data and puts
+   them back into the UI strings.
+
+   All method functions take a UI as argument.  Additionally, the writer and
+   the reader take a UI_STRING.
+*/
+
+/* The UI_STRING type is the data structure that contains all the needed info
+   about a string or a prompt, including test data for a verification prompt.
+*/
+DECLARE_STACK_OF(UI_STRING)
+typedef struct ui_string_st UI_STRING;
+
+/* The different types of strings that are currently supported.
+   This is only needed by method authors. */
+enum UI_string_types
+	{
+	UIT_NONE=0,
+	UIT_PROMPT,		/* Prompt for a string */
+	UIT_VERIFY,		/* Prompt for a string and verify */
+	UIT_BOOLEAN,		/* Prompt for a yes/no response */
+	UIT_INFO,		/* Send info to the user */
+	UIT_ERROR		/* Send an error message to the user */
+	};
+
+/* Create and manipulate methods */
+UI_METHOD *UI_create_method(char *name);
+void UI_destroy_method(UI_METHOD *ui_method);
+int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui));
+int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis));
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
+int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
+int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
+int (*UI_method_get_opener(UI_METHOD *method))(UI*);
+int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
+int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
+int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
+int (*UI_method_get_closer(UI_METHOD *method))(UI*);
+
+/* The following functions are helpers for method writers to access relevant
+   data from a UI_STRING. */
+
+/* Return type of the UI_STRING */
+enum UI_string_types UI_get_string_type(UI_STRING *uis);
+/* Return input flags of the UI_STRING */
+int UI_get_input_flags(UI_STRING *uis);
+/* Return the actual string to output (the prompt, info or error) */
+const char *UI_get0_output_string(UI_STRING *uis);
+/* Return the optional action string to output (the boolean promtp instruction) */
+const char *UI_get0_action_string(UI_STRING *uis);
+/* Return the result of a prompt */
+const char *UI_get0_result_string(UI_STRING *uis);
+/* Return the string to test the result against.  Only useful with verifies. */
+const char *UI_get0_test_string(UI_STRING *uis);
+/* Return the required minimum size of the result */
+int UI_get_result_minsize(UI_STRING *uis);
+/* Return the required maximum size of the result */
+int UI_get_result_maxsize(UI_STRING *uis);
+/* Set the result of a UI_STRING. */
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
+
+
+/* A couple of popular utility functions */
+int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_UI_strings(void);
+
+/* Error codes for the UI functions. */
+
+/* Function codes. */
+#define UI_F_GENERAL_ALLOCATE_BOOLEAN			 108
+#define UI_F_GENERAL_ALLOCATE_PROMPT			 109
+#define UI_F_GENERAL_ALLOCATE_STRING			 100
+#define UI_F_UI_CTRL					 111
+#define UI_F_UI_DUP_ERROR_STRING			 101
+#define UI_F_UI_DUP_INFO_STRING				 102
+#define UI_F_UI_DUP_INPUT_BOOLEAN			 110
+#define UI_F_UI_DUP_INPUT_STRING			 103
+#define UI_F_UI_DUP_VERIFY_STRING			 106
+#define UI_F_UI_GET0_RESULT				 107
+#define UI_F_UI_NEW_METHOD				 104
+#define UI_F_UI_SET_RESULT				 105
+
+/* Reason codes. */
+#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS		 104
+#define UI_R_INDEX_TOO_LARGE				 102
+#define UI_R_INDEX_TOO_SMALL				 103
+#define UI_R_NO_RESULT_BUFFER				 105
+#define UI_R_RESULT_TOO_LARGE				 100
+#define UI_R_RESULT_TOO_SMALL				 101
+#define UI_R_UNKNOWN_CONTROL_COMMAND			 106
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/ui_compat.h b/dep/include/openssl/ui_compat.h
new file mode 100644
index 000000000..b35c9bb7f
--- /dev/null
+++ b/dep/include/openssl/ui_compat.h
@@ -0,0 +1,83 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_COMPAT_H
+#define HEADER_UI_COMPAT_H
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* The following functions were previously part of the DES section,
+   and are provided here for backward compatibility reasons. */
+
+#define des_read_pw_string(b,l,p,v) \
+	_ossl_old_des_read_pw_string((b),(l),(p),(v))
+#define des_read_pw(b,bf,s,p,v) \
+	_ossl_old_des_read_pw((b),(bf),(s),(p),(v))
+
+int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/x509.h b/dep/include/openssl/x509.h
new file mode 100644
index 000000000..16a954f70
--- /dev/null
+++ b/dep/include/openssl/x509.h
@@ -0,0 +1,1344 @@
+/* crypto/x509/x509.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_X509_H
+#define HEADER_X509_H
+
+#include 
+#include 
+#ifndef OPENSSL_NO_BUFFER
+#include 
+#endif
+#ifndef OPENSSL_NO_EVP
+#include 
+#endif
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_EC
+#include 
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+#include 
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+#include 
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#endif
+
+#ifndef OPENSSL_NO_SHA
+#include 
+#endif
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#undef X509_NAME
+#undef X509_CERT_PAIR
+#endif
+
+#define X509_FILETYPE_PEM	1
+#define X509_FILETYPE_ASN1	2
+#define X509_FILETYPE_DEFAULT	3
+
+#define X509v3_KU_DIGITAL_SIGNATURE	0x0080
+#define X509v3_KU_NON_REPUDIATION	0x0040
+#define X509v3_KU_KEY_ENCIPHERMENT	0x0020
+#define X509v3_KU_DATA_ENCIPHERMENT	0x0010
+#define X509v3_KU_KEY_AGREEMENT		0x0008
+#define X509v3_KU_KEY_CERT_SIGN		0x0004
+#define X509v3_KU_CRL_SIGN		0x0002
+#define X509v3_KU_ENCIPHER_ONLY		0x0001
+#define X509v3_KU_DECIPHER_ONLY		0x8000
+#define X509v3_KU_UNDEF			0xffff
+
+typedef struct X509_objects_st
+	{
+	int nid;
+	int (*a2i)(void);
+	int (*i2a)(void);
+	} X509_OBJECTS;
+
+struct X509_algor_st
+	{
+	ASN1_OBJECT *algorithm;
+	ASN1_TYPE *parameter;
+	} /* X509_ALGOR */;
+
+DECLARE_STACK_OF(X509_ALGOR)
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef struct X509_val_st
+	{
+	ASN1_TIME *notBefore;
+	ASN1_TIME *notAfter;
+	} X509_VAL;
+
+typedef struct X509_pubkey_st
+	{
+	X509_ALGOR *algor;
+	ASN1_BIT_STRING *public_key;
+	EVP_PKEY *pkey;
+	} X509_PUBKEY;
+
+typedef struct X509_sig_st
+	{
+	X509_ALGOR *algor;
+	ASN1_OCTET_STRING *digest;
+	} X509_SIG;
+
+typedef struct X509_name_entry_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_STRING *value;
+	int set;
+	int size; 	/* temp variable */
+	} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+struct X509_name_st
+	{
+	STACK_OF(X509_NAME_ENTRY) *entries;
+	int modified;	/* true if 'bytes' needs to be built */
+#ifndef OPENSSL_NO_BUFFER
+	BUF_MEM *bytes;
+#else
+	char *bytes;
+#endif
+	unsigned long hash; /* Keep the hash around for lookups */
+	} /* X509_NAME */;
+
+DECLARE_STACK_OF(X509_NAME)
+
+#define X509_EX_V_NETSCAPE_HACK		0x8000
+#define X509_EX_V_INIT			0x0001
+typedef struct X509_extension_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_BOOLEAN critical;
+	ASN1_OCTET_STRING *value;
+	} X509_EXTENSION;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st
+	{
+	ASN1_OBJECT *object;
+	int single; /* 0 for a set, 1 for a single item (which is wrong) */
+	union	{
+		char		*ptr;
+/* 0 */		STACK_OF(ASN1_TYPE) *set;
+/* 1 */		ASN1_TYPE	*single;
+		} value;
+	} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+
+typedef struct X509_req_info_st
+	{
+	ASN1_ENCODING enc;
+	ASN1_INTEGER *version;
+	X509_NAME *subject;
+	X509_PUBKEY *pubkey;
+	/*  d=2 hl=2 l=  0 cons: cont: 00 */
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	} X509_REQ_INFO;
+
+typedef struct X509_req_st
+	{
+	X509_REQ_INFO *req_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} X509_REQ;
+
+typedef struct x509_cinf_st
+	{
+	ASN1_INTEGER *version;		/* [ 0 ] default of v1 */
+	ASN1_INTEGER *serialNumber;
+	X509_ALGOR *signature;
+	X509_NAME *issuer;
+	X509_VAL *validity;
+	X509_NAME *subject;
+	X509_PUBKEY *key;
+	ASN1_BIT_STRING *issuerUID;		/* [ 1 ] optional in v2 */
+	ASN1_BIT_STRING *subjectUID;		/* [ 2 ] optional in v2 */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [ 3 ] optional in v3 */
+	} X509_CINF;
+
+/* This stuff is certificate "auxiliary info"
+ * it contains details which are useful in certificate
+ * stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st
+	{
+	STACK_OF(ASN1_OBJECT) *trust;		/* trusted uses */
+	STACK_OF(ASN1_OBJECT) *reject;		/* rejected uses */
+	ASN1_UTF8STRING *alias;			/* "friendly name" */
+	ASN1_OCTET_STRING *keyid;		/* key id of private key */
+	STACK_OF(X509_ALGOR) *other;		/* other unspecified info */
+	} X509_CERT_AUX;
+
+struct x509_st
+	{
+	X509_CINF *cert_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int valid;
+	int references;
+	char *name;
+	CRYPTO_EX_DATA ex_data;
+	/* These contain copies of various extension values */
+	long ex_pathlen;
+	long ex_pcpathlen;
+	unsigned long ex_flags;
+	unsigned long ex_kusage;
+	unsigned long ex_xkusage;
+	unsigned long ex_nscert;
+	ASN1_OCTET_STRING *skid;
+	struct AUTHORITY_KEYID_st *akid;
+	X509_POLICY_CACHE *policy_cache;
+#ifndef OPENSSL_NO_RFC3779
+	STACK_OF(IPAddressFamily) *rfc3779_addr;
+	struct ASIdentifiers_st *rfc3779_asid;
+#endif
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	X509_CERT_AUX *aux;
+	} /* X509 */;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+	int trust;
+	int flags;
+	int (*check_trust)(struct x509_trust_st *, X509 *, int);
+	char *name;
+	int arg1;
+	void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+typedef struct x509_cert_pair_st {
+	X509 *forward;
+	X509 *reverse;
+} X509_CERT_PAIR;
+
+/* standard trust ids */
+
+#define X509_TRUST_DEFAULT	-1	/* Only valid in purpose settings */
+
+#define X509_TRUST_COMPAT	1
+#define X509_TRUST_SSL_CLIENT	2
+#define X509_TRUST_SSL_SERVER	3
+#define X509_TRUST_EMAIL	4
+#define X509_TRUST_OBJECT_SIGN	5
+#define X509_TRUST_OCSP_SIGN	6
+#define X509_TRUST_OCSP_REQUEST	7
+
+/* Keep these up to date! */
+#define X509_TRUST_MIN		1
+#define X509_TRUST_MAX		7
+
+
+/* trust_flags values */
+#define	X509_TRUST_DYNAMIC 	1
+#define	X509_TRUST_DYNAMIC_NAME	2
+
+/* check_trust return codes */
+
+#define X509_TRUST_TRUSTED	1
+#define X509_TRUST_REJECTED	2
+#define X509_TRUST_UNTRUSTED	3
+
+/* Flags for X509_print_ex() */
+
+#define	X509_FLAG_COMPAT		0
+#define	X509_FLAG_NO_HEADER		1L
+#define	X509_FLAG_NO_VERSION		(1L << 1)
+#define	X509_FLAG_NO_SERIAL		(1L << 2)
+#define	X509_FLAG_NO_SIGNAME		(1L << 3)
+#define	X509_FLAG_NO_ISSUER		(1L << 4)
+#define	X509_FLAG_NO_VALIDITY		(1L << 5)
+#define	X509_FLAG_NO_SUBJECT		(1L << 6)
+#define	X509_FLAG_NO_PUBKEY		(1L << 7)
+#define	X509_FLAG_NO_EXTENSIONS		(1L << 8)
+#define	X509_FLAG_NO_SIGDUMP		(1L << 9)
+#define	X509_FLAG_NO_AUX		(1L << 10)
+#define	X509_FLAG_NO_ATTRIBUTES		(1L << 11)
+
+/* Flags specific to X509_NAME_print_ex() */	
+
+/* The field separator information */
+
+#define XN_FLAG_SEP_MASK	(0xf << 16)
+
+#define XN_FLAG_COMPAT		0		/* Traditional SSLeay: use old X509_NAME_print */
+#define XN_FLAG_SEP_COMMA_PLUS	(1 << 16)	/* RFC2253 ,+ */
+#define XN_FLAG_SEP_CPLUS_SPC	(2 << 16)	/* ,+ spaced: more readable */
+#define XN_FLAG_SEP_SPLUS_SPC	(3 << 16)	/* ;+ spaced */
+#define XN_FLAG_SEP_MULTILINE	(4 << 16)	/* One line per field */
+
+#define XN_FLAG_DN_REV		(1 << 20)	/* Reverse DN order */
+
+/* How the field name is shown */
+
+#define XN_FLAG_FN_MASK		(0x3 << 21)
+
+#define XN_FLAG_FN_SN		0		/* Object short name */
+#define XN_FLAG_FN_LN		(1 << 21)	/* Object long name */
+#define XN_FLAG_FN_OID		(2 << 21)	/* Always use OIDs */
+#define XN_FLAG_FN_NONE		(3 << 21)	/* No field names */
+
+#define XN_FLAG_SPC_EQ		(1 << 23)	/* Put spaces round '=' */
+
+/* This determines if we dump fields we don't recognise:
+ * RFC2253 requires this.
+ */
+
+#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+#define XN_FLAG_FN_ALIGN	(1 << 25)	/* Align field names to 20 characters */
+
+/* Complete set of RFC2253 flags */
+
+#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+			XN_FLAG_SEP_COMMA_PLUS | \
+			XN_FLAG_DN_REV | \
+			XN_FLAG_FN_SN | \
+			XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+			ASN1_STRFLGS_ESC_QUOTE | \
+			XN_FLAG_SEP_CPLUS_SPC | \
+			XN_FLAG_SPC_EQ | \
+			XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+			ASN1_STRFLGS_ESC_MSB | \
+			XN_FLAG_SEP_MULTILINE | \
+			XN_FLAG_SPC_EQ | \
+			XN_FLAG_FN_LN | \
+			XN_FLAG_FN_ALIGN)
+
+typedef struct X509_revoked_st
+	{
+	ASN1_INTEGER *serialNumber;
+	ASN1_TIME *revocationDate;
+	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+	int sequence; /* load sequence */
+	} X509_REVOKED;
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st
+	{
+	ASN1_INTEGER *version;
+	X509_ALGOR *sig_alg;
+	X509_NAME *issuer;
+	ASN1_TIME *lastUpdate;
+	ASN1_TIME *nextUpdate;
+	STACK_OF(X509_REVOKED) *revoked;
+	STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+	ASN1_ENCODING enc;
+	} X509_CRL_INFO;
+
+struct X509_crl_st
+	{
+	/* actual signature */
+	X509_CRL_INFO *crl;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} /* X509_CRL */;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st
+	{
+	int version;
+	/* The PKCS#8 data types */
+	X509_ALGOR *enc_algor;
+	ASN1_OCTET_STRING *enc_pkey;	/* encrypted pub key */
+
+	/* When decrypted, the following will not be NULL */
+	EVP_PKEY *dec_pkey;
+
+	/* used to encrypt and decrypt */
+	int key_length;
+	char *key_data;
+	int key_free;	/* true if we should auto free key_data */
+
+	/* expanded version of 'enc_algor' */
+	EVP_CIPHER_INFO cipher;
+
+	int references;
+	} X509_PKEY;
+
+#ifndef OPENSSL_NO_EVP
+typedef struct X509_info_st
+	{
+	X509 *x509;
+	X509_CRL *crl;
+	X509_PKEY *x_pkey;
+
+	EVP_CIPHER_INFO enc_cipher;
+	int enc_len;
+	char *enc_data;
+
+	int references;
+	} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+#endif
+
+/* The next 2 structures and their 8 routines were sent to me by
+ * Pat Richard  and are used to manipulate
+ * Netscapes spki structures - useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st
+	{
+	X509_PUBKEY *pubkey;
+	ASN1_IA5STRING *challenge;	/* challenge sent in atlas >= PR2 */
+	} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st
+	{
+	NETSCAPE_SPKAC *spkac;	/* signed public key and challenge */
+	X509_ALGOR *sig_algor;
+	ASN1_BIT_STRING *signature;
+	} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence
+	{
+	ASN1_OBJECT *type;
+	STACK_OF(X509) *certs;
+	} NETSCAPE_CERT_SEQUENCE;
+
+/* Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+	{
+	unsigned char iv[8];
+	} CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+X509_ALGOR *keyfunc;
+X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+ASN1_TYPE *salt;	/* Usually OCTET STRING but could be anything */
+ASN1_INTEGER *iter;
+ASN1_INTEGER *keylength;
+X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+
+/* PKCS#8 private key info structure */
+
+typedef struct pkcs8_priv_key_info_st
+        {
+        int broken;     /* Flag for various broken formats */
+#define PKCS8_OK		0
+#define PKCS8_NO_OCTET		1
+#define PKCS8_EMBEDDED_PARAM	2
+#define PKCS8_NS_DB		3
+        ASN1_INTEGER *version;
+        X509_ALGOR *pkeyalg;
+        ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
+        STACK_OF(X509_ATTRIBUTE) *attributes;
+        } PKCS8_PRIV_KEY_INFO;
+
+#ifdef  __cplusplus
+}
+#endif
+
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef SSLEAY_MACROS
+#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\
+	a->signature,(char *)a->cert_info,r)
+#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \
+	a->sig_alg,a->signature,(char *)a->req_info,r)
+#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \
+	a->sig_alg, a->signature,(char *)a->crl,r)
+
+#define X509_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \
+		x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)
+#define X509_REQ_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \
+		x->signature, (char *)x->req_info,pkey,md)
+#define X509_CRL_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \
+		x->signature, (char *)x->crl,pkey,md)
+#define NETSCAPE_SPKI_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \
+		x->signature, (char *)x->spkac,pkey,md)
+
+#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \
+		(char *(*)())d2i_X509,(char *)x509)
+#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\
+		(int (*)())i2d_X509_ATTRIBUTE, \
+		(char *(*)())d2i_X509_ATTRIBUTE,(char *)xa)
+#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \
+		(int (*)())i2d_X509_EXTENSION, \
+		(char *(*)())d2i_X509_EXTENSION,(char *)ex)
+#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \
+		(char *(*)())d2i_X509, (fp),(unsigned char **)(x509))
+#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)
+#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \
+		(char *(*)())d2i_X509, (bp),(unsigned char **)(x509))
+#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)
+
+#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \
+		(char *(*)())d2i_X509_CRL,(char *)crl)
+#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \
+		X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\
+		(unsigned char **)(crl))
+#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\
+		(unsigned char *)crl)
+#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \
+		X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\
+		(unsigned char **)(crl))
+#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\
+		(unsigned char *)crl)
+
+#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \
+		(char *(*)())d2i_PKCS7,(char *)p7)
+#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \
+		PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\
+		(unsigned char **)(p7))
+#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\
+		(unsigned char *)p7)
+#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \
+		PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\
+		(unsigned char **)(p7))
+#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\
+		(unsigned char *)p7)
+
+#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \
+		(char *(*)())d2i_X509_REQ,(char *)req)
+#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\
+		X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\
+		(unsigned char **)(req))
+#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\
+		(unsigned char *)req)
+#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\
+		X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\
+		(unsigned char **)(req))
+#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\
+		(unsigned char *)req)
+
+#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \
+		(char *(*)())d2i_RSAPublicKey,(char *)rsa)
+#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \
+		(char *(*)())d2i_RSAPrivateKey,(char *)rsa)
+
+#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \
+		(unsigned char *)rsa)
+#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \
+		(unsigned char *)rsa)
+
+#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \
+		(unsigned char *)rsa)
+#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \
+		(unsigned char *)rsa)
+
+#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\
+		DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \
+		(unsigned char **)(dsa))
+#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \
+		(unsigned char *)dsa)
+#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\
+		DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \
+		(unsigned char **)(dsa))
+#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \
+		(unsigned char *)dsa)
+
+#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\
+		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \
+		(unsigned char **)(ecdsa))
+#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \
+		(unsigned char *)ecdsa)
+#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\
+		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \
+		(unsigned char **)(ecdsa))
+#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \
+		(unsigned char *)ecdsa)
+
+#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\
+		(char *(*)())d2i_X509_ALGOR,(char *)xn)
+
+#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \
+		(char *(*)())d2i_X509_NAME,(char *)xn)
+#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \
+		(int (*)())i2d_X509_NAME_ENTRY, \
+		(char *(*)())d2i_X509_NAME_ENTRY,\
+		(char *)ne)
+
+#define X509_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)
+#define X509_NAME_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len)
+#ifndef PKCS7_ISSUER_AND_SERIAL_digest
+#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
+		(char *)data,md,len)
+#endif
+#endif
+
+#define X509_EXT_PACK_UNKNOWN	1
+#define X509_EXT_PACK_STRING	2
+
+#define		X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define	X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+#define		X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+#define		X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+#define		X509_extract_key(x)	X509_get_pubkey(x) /*****/
+#define		X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+#define		X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+#define		X509_REQ_extract_key(a)	X509_REQ_get_pubkey(a)
+#define		X509_name_cmp(a,b)	X509_NAME_cmp((a),(b))
+#define		X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+#define		X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+#define 	X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+#define 	X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+#define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
+#define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+/* This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
+#define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+
+const char *X509_verify_cert_error_string(long n);
+
+#ifndef SSLEAY_MACROS
+#ifndef OPENSSL_NO_EVP
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp,X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int   i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int   i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+#endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+X509 *d2i_X509_bio(BIO *bp,X509 **x509);
+int i2d_X509_bio(BIO *bp,X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int   i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int   i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+#endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+#endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+#endif /* !SSLEAY_MACROS */
+
+int		X509_cmp_time(ASN1_TIME *s, time_t *t);
+int		X509_cmp_current_time(ASN1_TIME *s);
+ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *	X509_get_default_cert_area(void );
+const char *	X509_get_default_cert_dir(void );
+const char *	X509_get_default_cert_file(void );
+const char *	X509_get_default_cert_dir_env(void );
+const char *	X509_get_default_cert_file_env(void );
+const char *	X509_get_default_private_dir(void );
+
+X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
+int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
+					   STACK_OF(X509) *chain);
+int		i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp);
+EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
+			long length);
+#ifndef OPENSSL_NO_RSA
+int		i2d_RSA_PUBKEY(RSA *a,unsigned char **pp);
+RSA *		d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
+			long length);
+#endif
+#ifndef OPENSSL_NO_DSA
+int		i2d_DSA_PUBKEY(DSA *a,unsigned char **pp);
+DSA *		d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
+			long length);
+#endif
+#ifndef OPENSSL_NO_EC
+int		i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY 		*d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
+			long length);
+#endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int		i2d_X509_AUX(X509 *a,unsigned char **pp);
+X509 *		d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+unsigned char * X509_alias_get0(X509 *x, int *len);
+unsigned char * X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+
+X509_PKEY *	X509_PKEY_new(void );
+void		X509_PKEY_free(X509_PKEY *a);
+int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
+X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+#ifndef OPENSSL_NO_EVP
+X509_INFO *	X509_INFO_new(void);
+void		X509_INFO_free(X509_INFO *a);
+char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+		ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data,
+		unsigned char *md,unsigned int *len);
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+	      X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+	      char *data,EVP_PKEY *pkey, const EVP_MD *type);
+
+int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
+	unsigned char *md,unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+	ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+	ASN1_BIT_STRING *signature,
+	void *data, EVP_PKEY *pkey, const EVP_MD *type);
+#endif
+
+int 		X509_set_version(X509 *x,long version);
+int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
+int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_issuer_name(X509 *a);
+int 		X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_subject_name(X509 *a);
+int 		X509_set_notBefore(X509 *x, ASN1_TIME *tm);
+int 		X509_set_notAfter(X509 *x, ASN1_TIME *tm);
+int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
+int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
+
+int		X509_REQ_set_version(X509_REQ *x,long version);
+int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
+int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
+int		X509_REQ_extension_nid(int nid);
+int *		X509_REQ_get_extension_nids(void);
+void		X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+				int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+			  int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
+int		X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
+
+int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
+
+int		X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_issuer_and_serial_hash(X509 *a);
+
+int		X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_issuer_name_hash(X509 *a);
+
+int		X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_subject_name_hash(X509 *x);
+
+int		X509_cmp(const X509 *a, const X509 *b);
+int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long	X509_NAME_hash(X509_NAME *x);
+
+int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+#ifndef OPENSSL_NO_FP_API
+int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+int		X509_print_fp(FILE *bp,X509 *x);
+int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
+int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
+int		X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+int		X509_print(BIO *bp,X509 *x);
+int		X509_ocspid_print(BIO *bp,X509 *x);
+int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
+int		X509_CRL_print(BIO *bp,X509_CRL *x);
+int		X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
+int		X509_REQ_print(BIO *bp,X509_REQ *req);
+#endif
+
+int 		X509_NAME_entry_count(X509_NAME *name);
+int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
+			char *buf,int len);
+int		X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+			char *buf,int len);
+
+/* NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
+ * lastpos, search after that position on. */
+int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
+int 		X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj,
+			int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
+			int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len, int loc, int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+			unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+		const char *field, int type, const unsigned char *bytes, int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+			int type,unsigned char *bytes, int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+			const unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+			ASN1_OBJECT *obj, int type,const unsigned char *bytes,
+			int len);
+int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
+			ASN1_OBJECT *obj);
+int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+			const unsigned char *bytes, int len);
+ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+				      int nid, int lastpos);
+int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+				      ASN1_OBJECT *obj,int lastpos);
+int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+					   int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc);
+
+int		X509_get_ext_count(X509 *x);
+int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int		X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+int		X509_CRL_get_ext_count(X509_CRL *x);
+int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int		X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int		X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+			int nid, int crit, ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+			ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data);
+int		X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj);
+int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
+			ASN1_OCTET_STRING *data);
+ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+			  int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+					 X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+	     int atrtype, const void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+		const char *atrname, int type, const unsigned char *bytes, int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+					int atrtype, void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
+			  int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+
+int		X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
+				     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+					 unsigned char *salt, int saltlen);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST * X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
+					char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+#define X509_F_ADD_CERT_DIR				 100
+#define X509_F_BY_FILE_CTRL				 101
+#define X509_F_CHECK_POLICY				 145
+#define X509_F_DIR_CTRL					 102
+#define X509_F_GET_CERT_BY_SUBJECT			 103
+#define X509_F_NETSCAPE_SPKI_B64_DECODE			 129
+#define X509_F_NETSCAPE_SPKI_B64_ENCODE			 130
+#define X509_F_X509AT_ADD1_ATTR				 135
+#define X509_F_X509V3_ADD_EXT				 104
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID		 136
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ		 137
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT		 140
+#define X509_F_X509_ATTRIBUTE_GET0_DATA			 139
+#define X509_F_X509_ATTRIBUTE_SET1_DATA			 138
+#define X509_F_X509_CHECK_PRIVATE_KEY			 128
+#define X509_F_X509_CRL_PRINT_FP			 147
+#define X509_F_X509_EXTENSION_CREATE_BY_NID		 108
+#define X509_F_X509_EXTENSION_CREATE_BY_OBJ		 109
+#define X509_F_X509_GET_PUBKEY_PARAMETERS		 110
+#define X509_F_X509_LOAD_CERT_CRL_FILE			 132
+#define X509_F_X509_LOAD_CERT_FILE			 111
+#define X509_F_X509_LOAD_CRL_FILE			 112
+#define X509_F_X509_NAME_ADD_ENTRY			 113
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID		 114
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT		 131
+#define X509_F_X509_NAME_ENTRY_SET_OBJECT		 115
+#define X509_F_X509_NAME_ONELINE			 116
+#define X509_F_X509_NAME_PRINT				 117
+#define X509_F_X509_PRINT_EX_FP				 118
+#define X509_F_X509_PUBKEY_GET				 119
+#define X509_F_X509_PUBKEY_SET				 120
+#define X509_F_X509_REQ_CHECK_PRIVATE_KEY		 144
+#define X509_F_X509_REQ_PRINT_EX			 121
+#define X509_F_X509_REQ_PRINT_FP			 122
+#define X509_F_X509_REQ_TO_X509				 123
+#define X509_F_X509_STORE_ADD_CERT			 124
+#define X509_F_X509_STORE_ADD_CRL			 125
+#define X509_F_X509_STORE_CTX_GET1_ISSUER		 146
+#define X509_F_X509_STORE_CTX_INIT			 143
+#define X509_F_X509_STORE_CTX_NEW			 142
+#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT		 134
+#define X509_F_X509_TO_X509_REQ				 126
+#define X509_F_X509_TRUST_ADD				 133
+#define X509_F_X509_TRUST_SET				 141
+#define X509_F_X509_VERIFY_CERT				 127
+
+/* Reason codes. */
+#define X509_R_BAD_X509_FILETYPE			 100
+#define X509_R_BASE64_DECODE_ERROR			 118
+#define X509_R_CANT_CHECK_DH_KEY			 114
+#define X509_R_CERT_ALREADY_IN_HASH_TABLE		 101
+#define X509_R_ERR_ASN1_LIB				 102
+#define X509_R_INVALID_DIRECTORY			 113
+#define X509_R_INVALID_FIELD_NAME			 119
+#define X509_R_INVALID_TRUST				 123
+#define X509_R_KEY_TYPE_MISMATCH			 115
+#define X509_R_KEY_VALUES_MISMATCH			 116
+#define X509_R_LOADING_CERT_DIR				 103
+#define X509_R_LOADING_DEFAULTS				 104
+#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
+#define X509_R_SHOULD_RETRY				 106
+#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
+#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
+#define X509_R_UNKNOWN_KEY_TYPE				 117
+#define X509_R_UNKNOWN_NID				 109
+#define X509_R_UNKNOWN_PURPOSE_ID			 121
+#define X509_R_UNKNOWN_TRUST_ID				 120
+#define X509_R_UNSUPPORTED_ALGORITHM			 111
+#define X509_R_WRONG_LOOKUP_TYPE			 112
+#define X509_R_WRONG_TYPE				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/openssl/x509_vfy.h b/dep/include/openssl/x509_vfy.h
new file mode 100644
index 000000000..76c76e171
--- /dev/null
+++ b/dep/include/openssl/x509_vfy.h
@@ -0,0 +1,531 @@
+/* crypto/x509/x509_vfy.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+#include 
+/* openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment. */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+#define HEADER_X509_VFY_H
+
+#include 
+#ifndef OPENSSL_NO_LHASH
+#include 
+#endif
+#include 
+#include 
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Outer object */
+typedef struct x509_hash_dir_st
+	{
+	int num_dirs;
+	char **dirs;
+	int *dirs_type;
+	int num_dirs_alloced;
+	} X509_HASH_DIR_CTX;
+
+typedef struct x509_file_st
+	{
+	int num_paths;	/* number of paths to files or directories */
+	int num_alloced;
+	char **paths;	/* the list of paths or directories */
+	int *path_type;
+	} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*
+SSL_CTX -> X509_STORE    
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+ 
+SSL	-> X509_STORE_CTX
+		->X509_STORE    
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+#define X509_LU_RETRY		-1
+#define X509_LU_FAIL		0
+#define X509_LU_X509		1
+#define X509_LU_CRL		2
+#define X509_LU_PKEY		3
+
+typedef struct x509_object_st
+	{
+	/* one of the above types */
+	int type;
+	union	{
+		char *ptr;
+		X509 *x509;
+		X509_CRL *crl;
+		EVP_PKEY *pkey;
+		} data;
+	} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+DECLARE_STACK_OF(X509_OBJECT)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st
+	{
+	const char *name;
+	int (*new_item)(X509_LOOKUP *ctx);
+	void (*free)(X509_LOOKUP *ctx);
+	int (*init)(X509_LOOKUP *ctx);
+	int (*shutdown)(X509_LOOKUP *ctx);
+	int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl,
+			char **ret);
+	int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+			      X509_OBJECT *ret);
+	int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+				    ASN1_INTEGER *serial,X509_OBJECT *ret);
+	int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type,
+				  unsigned char *bytes,int len,
+				  X509_OBJECT *ret);
+	int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len,
+			    X509_OBJECT *ret);
+	} X509_LOOKUP_METHOD;
+
+/* This structure hold all parameters associated with a verify operation
+ * by including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+typedef struct X509_VERIFY_PARAM_st
+	{
+	char *name;
+	time_t check_time;	/* Time to use */
+	unsigned long inh_flags; /* Inheritance flags */
+	unsigned long flags;	/* Various verify flags */
+	int purpose;		/* purpose to check untrusted certificates */
+	int trust;		/* trust setting to check */
+	int depth;		/* Verify depth */
+	STACK_OF(ASN1_OBJECT) *policies;	/* Permissible policies */
+	} X509_VERIFY_PARAM;
+
+DECLARE_STACK_OF(X509_VERIFY_PARAM)
+
+/* This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify'
+ * function is then called to actually check the cert chain. */
+struct x509_store_st
+	{
+	/* The following is a cache of trusted certs */
+	int cache; 	/* if true, stash any hits */
+	STACK_OF(X509_OBJECT) *objs;	/* Cache of all objects */
+
+	/* These are external lookup methods */
+	STACK_OF(X509_LOOKUP) *get_cert_methods;
+
+	X509_VERIFY_PARAM *param;
+
+	/* Callbacks for various operations */
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);	/* error callback */
+	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
+	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
+	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
+	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
+	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
+	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	int (*cleanup)(X509_STORE_CTX *ctx);
+
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	} /* X509_STORE */;
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+#define X509_STORE_set_verify_func(ctx,func)	((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st
+	{
+	int init;			/* have we been started */
+	int skip;			/* don't use us. */
+	X509_LOOKUP_METHOD *method;	/* the functions */
+	char *method_data;		/* method data */
+
+	X509_STORE *store_ctx;	/* who owns us */
+	} /* X509_LOOKUP */;
+
+/* This is a used when verifying cert chains.  Since the
+ * gathering of the cert chain can take some time (and have to be
+ * 'retried', this needs to be kept and passed around. */
+struct x509_store_ctx_st      /* X509_STORE_CTX */
+	{
+	X509_STORE *ctx;
+	int current_method;	/* used when looking up certs */
+
+	/* The following are set by the caller */
+	X509 *cert;		/* The cert to check */
+	STACK_OF(X509) *untrusted;	/* chain of X509s - untrusted - passed in */
+	STACK_OF(X509_CRL) *crls;	/* set of CRLs passed in */
+
+	X509_VERIFY_PARAM *param;
+	void *other_ctx;	/* Other info for use with get_issuer() */
+
+	/* Callbacks for various operations */
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);		/* error callback */
+	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
+	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
+	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
+	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
+	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
+	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	int (*check_policy)(X509_STORE_CTX *ctx);
+	int (*cleanup)(X509_STORE_CTX *ctx);
+
+	/* The following is built up */
+	int valid;		/* if 0, rebuild chain */
+	int last_untrusted;	/* index of last untrusted cert */
+	STACK_OF(X509) *chain; 		/* chain of X509s - built up and trusted */
+	X509_POLICY_TREE *tree;	/* Valid policy tree */
+
+	int explicit_policy;	/* Require explicit policy value */
+
+	/* When something goes wrong, this is why */
+	int error_depth;
+	int error;
+	X509 *current_cert;
+	X509 *current_issuer;	/* cert currently being tested as valid issuer */
+	X509_CRL *current_crl;	/* current CRL */
+
+	CRYPTO_EX_DATA ex_data;
+	} /* X509_STORE_CTX */;
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+#define X509_STORE_CTX_set_app_data(ctx,data) \
+	X509_STORE_CTX_set_ex_data(ctx,0,data)
+#define X509_STORE_CTX_get_app_data(ctx) \
+	X509_STORE_CTX_get_ex_data(ctx,0)
+
+#define X509_L_FILE_LOAD	1
+#define X509_L_ADD_DIR		2
+
+#define X509_LOOKUP_load_file(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+#define X509_LOOKUP_add_dir(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+#define		X509_V_OK					0
+/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */
+
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT		2
+#define		X509_V_ERR_UNABLE_TO_GET_CRL			3
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE	4
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE	5
+#define		X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY	6
+#define		X509_V_ERR_CERT_SIGNATURE_FAILURE		7
+#define		X509_V_ERR_CRL_SIGNATURE_FAILURE		8
+#define		X509_V_ERR_CERT_NOT_YET_VALID			9
+#define		X509_V_ERR_CERT_HAS_EXPIRED			10
+#define		X509_V_ERR_CRL_NOT_YET_VALID			11
+#define		X509_V_ERR_CRL_HAS_EXPIRED			12
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD	13
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD	14
+#define		X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD	15
+#define		X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD	16
+#define		X509_V_ERR_OUT_OF_MEM				17
+#define		X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT		18
+#define		X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN		19
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY	20
+#define		X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE	21
+#define		X509_V_ERR_CERT_CHAIN_TOO_LONG			22
+#define		X509_V_ERR_CERT_REVOKED				23
+#define		X509_V_ERR_INVALID_CA				24
+#define		X509_V_ERR_PATH_LENGTH_EXCEEDED			25
+#define		X509_V_ERR_INVALID_PURPOSE			26
+#define		X509_V_ERR_CERT_UNTRUSTED			27
+#define		X509_V_ERR_CERT_REJECTED			28
+/* These are 'informational' when looking for issuer cert */
+#define		X509_V_ERR_SUBJECT_ISSUER_MISMATCH		29
+#define		X509_V_ERR_AKID_SKID_MISMATCH			30
+#define		X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH		31
+#define		X509_V_ERR_KEYUSAGE_NO_CERTSIGN			32
+
+#define		X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER		33
+#define		X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION		34
+#define		X509_V_ERR_KEYUSAGE_NO_CRL_SIGN			35
+#define		X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION	36
+#define		X509_V_ERR_INVALID_NON_CA			37
+#define		X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED		38
+#define		X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE	39
+#define		X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED	40
+
+#define		X509_V_ERR_INVALID_EXTENSION			41
+#define		X509_V_ERR_INVALID_POLICY_EXTENSION		42
+#define		X509_V_ERR_NO_EXPLICIT_POLICY			43
+
+#define		X509_V_ERR_UNNESTED_RESOURCE			44
+
+/* The application is not happy */
+#define		X509_V_ERR_APPLICATION_VERIFICATION		50
+
+/* Certificate verify flags */
+
+/* Send issuer+subject checks to verify_cb */
+#define	X509_V_FLAG_CB_ISSUER_CHECK		0x1
+/* Use check time instead of current time */
+#define	X509_V_FLAG_USE_CHECK_TIME		0x2
+/* Lookup CRLs */
+#define	X509_V_FLAG_CRL_CHECK			0x4
+/* Lookup CRLs for whole chain */
+#define	X509_V_FLAG_CRL_CHECK_ALL		0x8
+/* Ignore unhandled critical extensions */
+#define	X509_V_FLAG_IGNORE_CRITICAL		0x10
+/* Disable workarounds for broken certificates */
+#define	X509_V_FLAG_X509_STRICT			0x20
+/* Enable proxy certificate validation */
+#define	X509_V_FLAG_ALLOW_PROXY_CERTS		0x40
+/* Enable policy checking */
+#define X509_V_FLAG_POLICY_CHECK		0x80
+/* Policy variable require-explicit-policy */
+#define X509_V_FLAG_EXPLICIT_POLICY		0x100
+/* Policy variable inhibit-any-policy */
+#define	X509_V_FLAG_INHIBIT_ANY			0x200
+/* Policy variable inhibit-policy-mapping */
+#define X509_V_FLAG_INHIBIT_MAP			0x400
+/* Notify callback that policy is OK */
+#define X509_V_FLAG_NOTIFY_POLICY		0x800
+
+#define X509_VP_FLAG_DEFAULT			0x1
+#define X509_VP_FLAG_OVERWRITE			0x2
+#define X509_VP_FLAG_RESET_FLAGS		0x4
+#define X509_VP_FLAG_LOCKED			0x8
+#define X509_VP_FLAG_ONCE			0x10
+
+/* Internal use: mask of policy related options */
+#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+				| X509_V_FLAG_EXPLICIT_POLICY \
+				| X509_V_FLAG_INHIBIT_ANY \
+				| X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void );
+void X509_STORE_free(X509_STORE *v);
+
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+			 X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
+	X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+	long argl, char **ret);
+
+#ifndef OPENSSL_NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+#endif
+
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+	unsigned char *bytes, int len, X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
+	int len, X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+#ifndef OPENSSL_NO_STDIO
+int	X509_STORE_load_locations (X509_STORE *ctx,
+		const char *file, const char *dir);
+int	X509_STORE_set_default_paths(X509_STORE *ctx);
+#endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
+void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
+int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
+int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
+void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
+void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+				int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+								time_t t);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *));
+  
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+						const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 
+						const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+							unsigned long flags);
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+						ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
+					STACK_OF(ASN1_OBJECT) *policies);
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+			STACK_OF(X509) *certs,
+			STACK_OF(ASN1_OBJECT) *policy_oids,
+			unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *
+	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i);
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree);
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *
+	X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node);
+const X509_POLICY_NODE *
+	X509_policy_node_get0_parent(const X509_POLICY_NODE *node);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/dep/include/openssl/x509v3.h b/dep/include/openssl/x509v3.h
new file mode 100644
index 000000000..91d2fb5b8
--- /dev/null
+++ b/dep/include/openssl/x509v3.h
@@ -0,0 +1,919 @@
+/* x509v3.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_X509V3_H
+#define HEADER_X509V3_H
+
+#include 
+#include 
+#include 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward reference */
+struct v3_ext_method;
+struct v3_ext_ctx;
+
+/* Useful typedefs */
+
+typedef void * (*X509V3_EXT_NEW)(void);
+typedef void (*X509V3_EXT_FREE)(void *);
+typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
+typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
+typedef STACK_OF(CONF_VALUE) * (*X509V3_EXT_I2V)(struct v3_ext_method *method, void *ext, STACK_OF(CONF_VALUE) *extlist);
+typedef void * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values);
+typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, void *ext);
+typedef void * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R)(struct v3_ext_method *method, void *ext, BIO *out, int indent);
+typedef void * (*X509V3_EXT_R2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
+
+/* V3 extension structure */
+
+struct v3_ext_method {
+int ext_nid;
+int ext_flags;
+/* If this is set the following four fields are ignored */
+ASN1_ITEM_EXP *it;
+/* Old style ASN1 calls */
+X509V3_EXT_NEW ext_new;
+X509V3_EXT_FREE ext_free;
+X509V3_EXT_D2I d2i;
+X509V3_EXT_I2D i2d;
+
+/* The following pair is used for string extensions */
+X509V3_EXT_I2S i2s;
+X509V3_EXT_S2I s2i;
+
+/* The following pair is used for multi-valued extensions */
+X509V3_EXT_I2V i2v;
+X509V3_EXT_V2I v2i;
+
+/* The following are used for raw extensions */
+X509V3_EXT_I2R i2r;
+X509V3_EXT_R2I r2i;
+
+void *usr_data;	/* Any extension specific data */
+};
+
+typedef struct X509V3_CONF_METHOD_st {
+char * (*get_string)(void *db, char *section, char *value);
+STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
+void (*free_string)(void *db, char * string);
+void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
+} X509V3_CONF_METHOD;
+
+/* Context specific info */
+struct v3_ext_ctx {
+#define CTX_TEST 0x1
+int flags;
+X509 *issuer_cert;
+X509 *subject_cert;
+X509_REQ *subject_req;
+X509_CRL *crl;
+X509V3_CONF_METHOD *db_meth;
+void *db;
+/* Maybe more here */
+};
+
+typedef struct v3_ext_method X509V3_EXT_METHOD;
+
+DECLARE_STACK_OF(X509V3_EXT_METHOD)
+
+/* ext_flags values */
+#define X509V3_EXT_DYNAMIC	0x1
+#define X509V3_EXT_CTX_DEP	0x2
+#define X509V3_EXT_MULTILINE	0x4
+
+typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
+
+typedef struct BASIC_CONSTRAINTS_st {
+int ca;
+ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+
+typedef struct PKEY_USAGE_PERIOD_st {
+ASN1_GENERALIZEDTIME *notBefore;
+ASN1_GENERALIZEDTIME *notAfter;
+} PKEY_USAGE_PERIOD;
+
+typedef struct otherName_st {
+ASN1_OBJECT *type_id;
+ASN1_TYPE *value;
+} OTHERNAME;
+
+typedef struct EDIPartyName_st {
+	ASN1_STRING *nameAssigner;
+	ASN1_STRING *partyName;
+} EDIPARTYNAME;
+
+typedef struct GENERAL_NAME_st {
+
+#define GEN_OTHERNAME	0
+#define GEN_EMAIL	1
+#define GEN_DNS		2
+#define GEN_X400	3
+#define GEN_DIRNAME	4
+#define GEN_EDIPARTY	5
+#define GEN_URI		6
+#define GEN_IPADD	7
+#define GEN_RID		8
+
+int type;
+union {
+	char *ptr;
+	OTHERNAME *otherName; /* otherName */
+	ASN1_IA5STRING *rfc822Name;
+	ASN1_IA5STRING *dNSName;
+	ASN1_TYPE *x400Address;
+	X509_NAME *directoryName;
+	EDIPARTYNAME *ediPartyName;
+	ASN1_IA5STRING *uniformResourceIdentifier;
+	ASN1_OCTET_STRING *iPAddress;
+	ASN1_OBJECT *registeredID;
+
+	/* Old names */
+	ASN1_OCTET_STRING *ip; /* iPAddress */
+	X509_NAME *dirn;		/* dirn */
+	ASN1_IA5STRING *ia5;/* rfc822Name, dNSName, uniformResourceIdentifier */
+	ASN1_OBJECT *rid; /* registeredID */
+	ASN1_TYPE *other; /* x400Address */
+} d;
+} GENERAL_NAME;
+
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+
+typedef struct ACCESS_DESCRIPTION_st {
+	ASN1_OBJECT *method;
+	GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
+typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
+
+typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
+
+DECLARE_STACK_OF(GENERAL_NAME)
+DECLARE_ASN1_SET_OF(GENERAL_NAME)
+
+DECLARE_STACK_OF(ACCESS_DESCRIPTION)
+DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)
+
+typedef struct DIST_POINT_NAME_st {
+int type;
+union {
+	GENERAL_NAMES *fullname;
+	STACK_OF(X509_NAME_ENTRY) *relativename;
+} name;
+} DIST_POINT_NAME;
+
+typedef struct DIST_POINT_st {
+DIST_POINT_NAME	*distpoint;
+ASN1_BIT_STRING *reasons;
+GENERAL_NAMES *CRLissuer;
+} DIST_POINT;
+
+typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
+
+DECLARE_STACK_OF(DIST_POINT)
+DECLARE_ASN1_SET_OF(DIST_POINT)
+
+typedef struct AUTHORITY_KEYID_st {
+ASN1_OCTET_STRING *keyid;
+GENERAL_NAMES *issuer;
+ASN1_INTEGER *serial;
+} AUTHORITY_KEYID;
+
+/* Strong extranet structures */
+
+typedef struct SXNET_ID_st {
+	ASN1_INTEGER *zone;
+	ASN1_OCTET_STRING *user;
+} SXNETID;
+
+DECLARE_STACK_OF(SXNETID)
+DECLARE_ASN1_SET_OF(SXNETID)
+
+typedef struct SXNET_st {
+	ASN1_INTEGER *version;
+	STACK_OF(SXNETID) *ids;
+} SXNET;
+
+typedef struct NOTICEREF_st {
+	ASN1_STRING *organization;
+	STACK_OF(ASN1_INTEGER) *noticenos;
+} NOTICEREF;
+
+typedef struct USERNOTICE_st {
+	NOTICEREF *noticeref;
+	ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct POLICYQUALINFO_st {
+	ASN1_OBJECT *pqualid;
+	union {
+		ASN1_IA5STRING *cpsuri;
+		USERNOTICE *usernotice;
+		ASN1_TYPE *other;
+	} d;
+} POLICYQUALINFO;
+
+DECLARE_STACK_OF(POLICYQUALINFO)
+DECLARE_ASN1_SET_OF(POLICYQUALINFO)
+
+typedef struct POLICYINFO_st {
+	ASN1_OBJECT *policyid;
+	STACK_OF(POLICYQUALINFO) *qualifiers;
+} POLICYINFO;
+
+typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
+
+DECLARE_STACK_OF(POLICYINFO)
+DECLARE_ASN1_SET_OF(POLICYINFO)
+
+typedef struct POLICY_MAPPING_st {
+	ASN1_OBJECT *issuerDomainPolicy;
+	ASN1_OBJECT *subjectDomainPolicy;
+} POLICY_MAPPING;
+
+DECLARE_STACK_OF(POLICY_MAPPING)
+
+typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
+
+typedef struct GENERAL_SUBTREE_st {
+	GENERAL_NAME *base;
+	ASN1_INTEGER *minimum;
+	ASN1_INTEGER *maximum;
+} GENERAL_SUBTREE;
+
+DECLARE_STACK_OF(GENERAL_SUBTREE)
+
+typedef struct NAME_CONSTRAINTS_st {
+	STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
+	STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
+} NAME_CONSTRAINTS;
+
+typedef struct POLICY_CONSTRAINTS_st {
+	ASN1_INTEGER *requireExplicitPolicy;
+	ASN1_INTEGER *inhibitPolicyMapping;
+} POLICY_CONSTRAINTS;
+
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st
+	{
+	ASN1_OBJECT *policyLanguage;
+	ASN1_OCTET_STRING *policy;
+	} PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st
+	{
+	ASN1_INTEGER *pcPathLengthConstraint;
+	PROXY_POLICY *proxyPolicy;
+	} PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+
+#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
+",name:", val->name, ",value:", val->value);
+
+#define X509V3_set_ctx_test(ctx) \
+			X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
+#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
+
+#define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
+			0,0,0,0, \
+			0,0, \
+			(X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
+			(X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
+			NULL, NULL, \
+			table}
+
+#define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
+			0,0,0,0, \
+			(X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
+			(X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
+			0,0,0,0, \
+			NULL}
+
+#define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+
+/* X509_PURPOSE stuff */
+
+#define EXFLAG_BCONS		0x1
+#define EXFLAG_KUSAGE		0x2
+#define EXFLAG_XKUSAGE		0x4
+#define EXFLAG_NSCERT		0x8
+
+#define EXFLAG_CA		0x10
+#define EXFLAG_SS		0x20
+#define EXFLAG_V1		0x40
+#define EXFLAG_INVALID		0x80
+#define EXFLAG_SET		0x100
+#define EXFLAG_CRITICAL		0x200
+#define EXFLAG_PROXY		0x400
+
+#define EXFLAG_INVALID_POLICY	0x400
+
+#define KU_DIGITAL_SIGNATURE	0x0080
+#define KU_NON_REPUDIATION	0x0040
+#define KU_KEY_ENCIPHERMENT	0x0020
+#define KU_DATA_ENCIPHERMENT	0x0010
+#define KU_KEY_AGREEMENT	0x0008
+#define KU_KEY_CERT_SIGN	0x0004
+#define KU_CRL_SIGN		0x0002
+#define KU_ENCIPHER_ONLY	0x0001
+#define KU_DECIPHER_ONLY	0x8000
+
+#define NS_SSL_CLIENT		0x80
+#define NS_SSL_SERVER		0x40
+#define NS_SMIME		0x20
+#define NS_OBJSIGN		0x10
+#define NS_SSL_CA		0x04
+#define NS_SMIME_CA		0x02
+#define NS_OBJSIGN_CA		0x01
+#define NS_ANY_CA		(NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
+
+#define XKU_SSL_SERVER		0x1	
+#define XKU_SSL_CLIENT		0x2
+#define XKU_SMIME		0x4
+#define XKU_CODE_SIGN		0x8
+#define XKU_SGC			0x10
+#define XKU_OCSP_SIGN		0x20
+#define XKU_TIMESTAMP		0x40
+#define XKU_DVCS		0x80
+
+#define X509_PURPOSE_DYNAMIC	0x1
+#define X509_PURPOSE_DYNAMIC_NAME	0x2
+
+typedef struct x509_purpose_st {
+	int purpose;
+	int trust;		/* Default trust ID */
+	int flags;
+	int (*check_purpose)(const struct x509_purpose_st *,
+				const X509 *, int);
+	char *name;
+	char *sname;
+	void *usr_data;
+} X509_PURPOSE;
+
+#define X509_PURPOSE_SSL_CLIENT		1
+#define X509_PURPOSE_SSL_SERVER		2
+#define X509_PURPOSE_NS_SSL_SERVER	3
+#define X509_PURPOSE_SMIME_SIGN		4
+#define X509_PURPOSE_SMIME_ENCRYPT	5
+#define X509_PURPOSE_CRL_SIGN		6
+#define X509_PURPOSE_ANY		7
+#define X509_PURPOSE_OCSP_HELPER	8
+
+#define X509_PURPOSE_MIN		1
+#define X509_PURPOSE_MAX		8
+
+/* Flags for X509V3_EXT_print() */
+
+#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT		0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
+
+/* Flags for X509V3_add1_i2d */
+
+#define X509V3_ADD_OP_MASK		0xfL
+#define X509V3_ADD_DEFAULT		0L
+#define X509V3_ADD_APPEND		1L
+#define X509V3_ADD_REPLACE		2L
+#define X509V3_ADD_REPLACE_EXISTING	3L
+#define X509V3_ADD_KEEP_EXISTING	4L
+#define X509V3_ADD_DELETE		5L
+#define X509V3_ADD_SILENT		0x10
+
+DECLARE_STACK_OF(X509_PURPOSE)
+
+DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+DECLARE_ASN1_FUNCTIONS(SXNET)
+DECLARE_ASN1_FUNCTIONS(SXNETID)
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); 
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, int userlen); 
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, int userlen); 
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
+
+DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+				ASN1_BIT_STRING *bits,
+				STACK_OF(CONF_VALUE) *extlist);
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
+GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+DECLARE_ASN1_FUNCTIONS(OTHERNAME)
+DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+
+DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a);
+
+DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+DECLARE_ASN1_FUNCTIONS(POLICYINFO)
+DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
+DECLARE_ASN1_FUNCTIONS(USERNOTICE)
+DECLARE_ASN1_FUNCTIONS(NOTICEREF)
+
+DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+
+DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+DECLARE_ASN1_ITEM(POLICY_MAPPING)
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
+
+DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
+DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+
+DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
+
+#ifdef HEADER_CONF_H
+GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+							CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
+void X509V3_conf_free(CONF_VALUE *val);
+
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value);
+int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
+#endif
+
+char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+				 X509_REQ *req, X509_CRL *crl, int flags);
+
+int X509V3_add_value(const char *name, const char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+						STACK_OF(CONF_VALUE) **extlist);
+char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+void X509V3_EXT_cleanup(void);
+
+X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+int X509V3_add_standard_extensions(void);
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
+
+char *hex_to_string(unsigned char *buffer, long len);
+unsigned char *string_to_hex(char *str, long *len);
+int name_cmp(const char *name, const char *cmp);
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+								 int ml);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+
+int X509V3_extensions_print(BIO *out, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
+
+int X509_check_ca(X509 *x);
+int X509_check_purpose(X509 *x, int id, int ca);
+int X509_supported_extension(X509_EXTENSION *ex);
+int X509_PURPOSE_set(int *p, int purpose);
+int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_PURPOSE_get_count(void);
+X509_PURPOSE * X509_PURPOSE_get0(int idx);
+int X509_PURPOSE_get_by_sname(char *sname);
+int X509_PURPOSE_get_by_id(int id);
+int X509_PURPOSE_add(int id, int trust, int flags,
+			int (*ck)(const X509_PURPOSE *, const X509 *, int),
+				char *name, char *sname, void *arg);
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
+int X509_PURPOSE_get_id(X509_PURPOSE *);
+
+STACK *X509_get1_email(X509 *x);
+STACK *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK *sk);
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
+						unsigned long chtype);
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+
+#ifndef OPENSSL_NO_RFC3779
+
+typedef struct ASRange_st {
+  ASN1_INTEGER *min, *max;
+} ASRange;
+
+#define	ASIdOrRange_id		0
+#define	ASIdOrRange_range	1
+
+typedef struct ASIdOrRange_st {
+  int type;
+  union {
+    ASN1_INTEGER *id;
+    ASRange      *range;
+  } u;
+} ASIdOrRange;
+
+typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
+DECLARE_STACK_OF(ASIdOrRange)
+
+#define	ASIdentifierChoice_inherit		0
+#define	ASIdentifierChoice_asIdsOrRanges	1
+
+typedef struct ASIdentifierChoice_st {
+  int type;
+  union {
+    ASN1_NULL    *inherit;
+    ASIdOrRanges *asIdsOrRanges;
+  } u;
+} ASIdentifierChoice;
+
+typedef struct ASIdentifiers_st {
+  ASIdentifierChoice *asnum, *rdi;
+} ASIdentifiers;
+
+DECLARE_ASN1_FUNCTIONS(ASRange)
+DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
+DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
+DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
+
+
+typedef struct IPAddressRange_st {
+  ASN1_BIT_STRING	*min, *max;
+} IPAddressRange;
+
+#define	IPAddressOrRange_addressPrefix	0
+#define	IPAddressOrRange_addressRange	1
+
+typedef struct IPAddressOrRange_st {
+  int type;
+  union {
+    ASN1_BIT_STRING	*addressPrefix;
+    IPAddressRange	*addressRange;
+  } u;
+} IPAddressOrRange;
+
+typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
+DECLARE_STACK_OF(IPAddressOrRange)
+
+#define	IPAddressChoice_inherit			0
+#define	IPAddressChoice_addressesOrRanges	1
+
+typedef struct IPAddressChoice_st {
+  int type;
+  union {
+    ASN1_NULL		*inherit;
+    IPAddressOrRanges	*addressesOrRanges;
+  } u;
+} IPAddressChoice;
+
+typedef struct IPAddressFamily_st {
+  ASN1_OCTET_STRING	*addressFamily;
+  IPAddressChoice	*ipAddressChoice;
+} IPAddressFamily;
+
+typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
+DECLARE_STACK_OF(IPAddressFamily)
+
+DECLARE_ASN1_FUNCTIONS(IPAddressRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
+DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * API tag for elements of the ASIdentifer SEQUENCE.
+ */
+#define	V3_ASID_ASNUM	0
+#define	V3_ASID_RDI	1
+
+/*
+ * AFI values, assigned by IANA.  It'd be nice to make the AFI
+ * handling code totally generic, but there are too many little things
+ * that would need to be defined for other address families for it to
+ * be worth the trouble.
+ */
+#define	IANA_AFI_IPV4	1
+#define	IANA_AFI_IPV6	2
+
+/*
+ * Utilities to construct and extract values from RFC3779 extensions,
+ * since some of the encodings (particularly for IP address prefixes
+ * and ranges) are a bit tedious to work with directly.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which);
+int v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
+			    ASN1_INTEGER *min, ASN1_INTEGER *max);
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+			const unsigned afi, const unsigned *safi);
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+		       const unsigned afi, const unsigned *safi,
+		       unsigned char *a, const int prefixlen);
+int v3_addr_add_range(IPAddrBlocks *addr,
+		      const unsigned afi, const unsigned *safi,
+		      unsigned char *min, unsigned char *max);
+unsigned v3_addr_get_afi(const IPAddressFamily *f);
+int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
+		      unsigned char *min, unsigned char *max,
+		      const int length);
+
+/*
+ * Canonical forms.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid);
+int v3_addr_is_canonical(IPAddrBlocks *addr);
+int v3_asid_canonize(ASIdentifiers *asid);
+int v3_addr_canonize(IPAddrBlocks *addr);
+
+/*
+ * Tests for inheritance and containment.
+ */
+int v3_asid_inherits(ASIdentifiers *asid);
+int v3_addr_inherits(IPAddrBlocks *addr);
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
+
+/*
+ * Check whether RFC 3779 extensions nest properly in chains.
+ */
+int v3_asid_validate_path(X509_STORE_CTX *);
+int v3_addr_validate_path(X509_STORE_CTX *);
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+				  ASIdentifiers *ext,
+				  int allow_inheritance);
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+				  IPAddrBlocks *ext,
+				  int allow_inheritance);
+
+#endif /* OPENSSL_NO_RFC3779 */
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509V3_strings(void);
+
+/* Error codes for the X509V3 functions. */
+
+/* Function codes. */
+#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 156
+#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 157
+#define X509V3_F_COPY_EMAIL				 122
+#define X509V3_F_COPY_ISSUER				 123
+#define X509V3_F_DO_DIRNAME				 144
+#define X509V3_F_DO_EXT_CONF				 124
+#define X509V3_F_DO_EXT_I2D				 135
+#define X509V3_F_DO_EXT_NCONF				 151
+#define X509V3_F_DO_I2V_NAME_CONSTRAINTS		 148
+#define X509V3_F_HEX_TO_STRING				 111
+#define X509V3_F_I2S_ASN1_ENUMERATED			 121
+#define X509V3_F_I2S_ASN1_IA5STRING			 149
+#define X509V3_F_I2S_ASN1_INTEGER			 120
+#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS		 138
+#define X509V3_F_NOTICE_SECTION				 132
+#define X509V3_F_NREF_NOS				 133
+#define X509V3_F_POLICY_SECTION				 131
+#define X509V3_F_PROCESS_PCI_VALUE			 150
+#define X509V3_F_R2I_CERTPOL				 130
+#define X509V3_F_R2I_PCI				 155
+#define X509V3_F_S2I_ASN1_IA5STRING			 100
+#define X509V3_F_S2I_ASN1_INTEGER			 108
+#define X509V3_F_S2I_ASN1_OCTET_STRING			 112
+#define X509V3_F_S2I_ASN1_SKEY_ID			 114
+#define X509V3_F_S2I_SKEY_ID				 115
+#define X509V3_F_STRING_TO_HEX				 113
+#define X509V3_F_SXNET_ADD_ID_ASC			 125
+#define X509V3_F_SXNET_ADD_ID_INTEGER			 126
+#define X509V3_F_SXNET_ADD_ID_ULONG			 127
+#define X509V3_F_SXNET_GET_ID_ASC			 128
+#define X509V3_F_SXNET_GET_ID_ULONG			 129
+#define X509V3_F_V2I_ASIDENTIFIERS			 158
+#define X509V3_F_V2I_ASN1_BIT_STRING			 101
+#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
+#define X509V3_F_V2I_AUTHORITY_KEYID			 119
+#define X509V3_F_V2I_BASIC_CONSTRAINTS			 102
+#define X509V3_F_V2I_CRLD				 134
+#define X509V3_F_V2I_EXTENDED_KEY_USAGE			 103
+#define X509V3_F_V2I_GENERAL_NAMES			 118
+#define X509V3_F_V2I_GENERAL_NAME_EX			 117
+#define X509V3_F_V2I_IPADDRBLOCKS			 159
+#define X509V3_F_V2I_ISSUER_ALT				 153
+#define X509V3_F_V2I_NAME_CONSTRAINTS			 147
+#define X509V3_F_V2I_POLICY_CONSTRAINTS			 146
+#define X509V3_F_V2I_POLICY_MAPPINGS			 145
+#define X509V3_F_V2I_SUBJECT_ALT			 154
+#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL		 160
+#define X509V3_F_V3_GENERIC_EXTENSION			 116
+#define X509V3_F_X509V3_ADD1_I2D			 140
+#define X509V3_F_X509V3_ADD_VALUE			 105
+#define X509V3_F_X509V3_EXT_ADD				 104
+#define X509V3_F_X509V3_EXT_ADD_ALIAS			 106
+#define X509V3_F_X509V3_EXT_CONF			 107
+#define X509V3_F_X509V3_EXT_I2D				 136
+#define X509V3_F_X509V3_EXT_NCONF			 152
+#define X509V3_F_X509V3_GET_SECTION			 142
+#define X509V3_F_X509V3_GET_STRING			 143
+#define X509V3_F_X509V3_GET_VALUE_BOOL			 110
+#define X509V3_F_X509V3_PARSE_LIST			 109
+#define X509V3_F_X509_PURPOSE_ADD			 137
+#define X509V3_F_X509_PURPOSE_SET			 141
+
+/* Reason codes. */
+#define X509V3_R_BAD_IP_ADDRESS				 118
+#define X509V3_R_BAD_OBJECT				 119
+#define X509V3_R_BN_DEC2BN_ERROR			 100
+#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
+#define X509V3_R_DIRNAME_ERROR				 149
+#define X509V3_R_DUPLICATE_ZONE_ID			 133
+#define X509V3_R_ERROR_CONVERTING_ZONE			 131
+#define X509V3_R_ERROR_CREATING_EXTENSION		 144
+#define X509V3_R_ERROR_IN_EXTENSION			 128
+#define X509V3_R_EXPECTED_A_SECTION_NAME		 137
+#define X509V3_R_EXTENSION_EXISTS			 145
+#define X509V3_R_EXTENSION_NAME_ERROR			 115
+#define X509V3_R_EXTENSION_NOT_FOUND			 102
+#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED	 103
+#define X509V3_R_EXTENSION_VALUE_ERROR			 116
+#define X509V3_R_ILLEGAL_EMPTY_EXTENSION		 151
+#define X509V3_R_ILLEGAL_HEX_DIGIT			 113
+#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
+#define X509V3_R_INVALID_ASNUMBER			 160
+#define X509V3_R_INVALID_ASRANGE			 161
+#define X509V3_R_INVALID_BOOLEAN_STRING			 104
+#define X509V3_R_INVALID_EXTENSION_STRING		 105
+#define X509V3_R_INVALID_INHERITANCE			 162
+#define X509V3_R_INVALID_IPADDRESS			 163
+#define X509V3_R_INVALID_NAME				 106
+#define X509V3_R_INVALID_NULL_ARGUMENT			 107
+#define X509V3_R_INVALID_NULL_NAME			 108
+#define X509V3_R_INVALID_NULL_VALUE			 109
+#define X509V3_R_INVALID_NUMBER				 140
+#define X509V3_R_INVALID_NUMBERS			 141
+#define X509V3_R_INVALID_OBJECT_IDENTIFIER		 110
+#define X509V3_R_INVALID_OPTION				 138
+#define X509V3_R_INVALID_POLICY_IDENTIFIER		 134
+#define X509V3_R_INVALID_PROXY_POLICY_SETTING		 153
+#define X509V3_R_INVALID_PURPOSE			 146
+#define X509V3_R_INVALID_SAFI				 164
+#define X509V3_R_INVALID_SECTION			 135
+#define X509V3_R_INVALID_SYNTAX				 143
+#define X509V3_R_ISSUER_DECODE_ERROR			 126
+#define X509V3_R_MISSING_VALUE				 124
+#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS		 142
+#define X509V3_R_NO_CONFIG_DATABASE			 136
+#define X509V3_R_NO_ISSUER_CERTIFICATE			 121
+#define X509V3_R_NO_ISSUER_DETAILS			 127
+#define X509V3_R_NO_POLICY_IDENTIFIER			 139
+#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED	 154
+#define X509V3_R_NO_PUBLIC_KEY				 114
+#define X509V3_R_NO_SUBJECT_DETAILS			 125
+#define X509V3_R_ODD_NUMBER_OF_DIGITS			 112
+#define X509V3_R_OPERATION_NOT_DEFINED			 148
+#define X509V3_R_OTHERNAME_ERROR			 147
+#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED	 155
+#define X509V3_R_POLICY_PATH_LENGTH			 156
+#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157
+#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
+#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
+#define X509V3_R_SECTION_NOT_FOUND			 150
+#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122
+#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123
+#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT		 111
+#define X509V3_R_UNKNOWN_EXTENSION			 129
+#define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
+#define X509V3_R_UNKNOWN_OPTION				 120
+#define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_USER_TOO_LONG				 132
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/dep/include/postgre/libpq-fe.h b/dep/include/postgre/libpq-fe.h
new file mode 100644
index 000000000..f51c6b38a
--- /dev/null
+++ b/dep/include/postgre/libpq-fe.h
@@ -0,0 +1,525 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq-fe.h
+ *	  This file contains definitions for structures and
+ *	  externs for functions used by frontend postgres applications.
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.141 2008/01/01 19:46:00 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef LIBPQ_FE_H
+#define LIBPQ_FE_H
+
+#ifdef __cplusplus
+extern		"C"
+{
+#endif
+
+#include 
+
+/*
+ * postgres_ext.h defines the backend's externally visible types,
+ * such as Oid.
+ */
+#include "postgres_ext.h"
+
+/* Application-visible enum types */
+
+typedef enum
+{
+	/*
+	 * Although it is okay to add to this list, values which become unused
+	 * should never be removed, nor should constants be redefined - that would
+	 * break compatibility with existing code.
+	 */
+	CONNECTION_OK,
+	CONNECTION_BAD,
+	/* Non-blocking mode only below here */
+
+	/*
+	 * The existence of these should never be relied upon - they should only
+	 * be used for user feedback or similar purposes.
+	 */
+	CONNECTION_STARTED,			/* Waiting for connection to be made.  */
+	CONNECTION_MADE,			/* Connection OK; waiting to send.	   */
+	CONNECTION_AWAITING_RESPONSE,		/* Waiting for a response from the
+										 * postmaster.		  */
+	CONNECTION_AUTH_OK,			/* Received authentication; waiting for
+								 * backend startup. */
+	CONNECTION_SETENV,			/* Negotiating environment. */
+	CONNECTION_SSL_STARTUP,		/* Negotiating SSL. */
+	CONNECTION_NEEDED			/* Internal state: connect() needed */
+} ConnStatusType;
+
+typedef enum
+{
+	PGRES_POLLING_FAILED = 0,
+	PGRES_POLLING_READING,		/* These two indicate that one may	  */
+	PGRES_POLLING_WRITING,		/* use select before polling again.   */
+	PGRES_POLLING_OK,
+	PGRES_POLLING_ACTIVE		/* unused; keep for awhile for backwards
+								 * compatibility */
+} PostgresPollingStatusType;
+
+typedef enum
+{
+	PGRES_EMPTY_QUERY = 0,		/* empty query string was executed */
+	PGRES_COMMAND_OK,			/* a query command that doesn't return
+								 * anything was executed properly by the
+								 * backend */
+	PGRES_TUPLES_OK,			/* a query command that returns tuples was
+								 * executed properly by the backend, PGresult
+								 * contains the result tuples */
+	PGRES_COPY_OUT,				/* Copy Out data transfer in progress */
+	PGRES_COPY_IN,				/* Copy In data transfer in progress */
+	PGRES_BAD_RESPONSE,			/* an unexpected response was recv'd from the
+								 * backend */
+	PGRES_NONFATAL_ERROR,		/* notice or warning message */
+	PGRES_FATAL_ERROR			/* query failed */
+} ExecStatusType;
+
+typedef enum
+{
+	PQTRANS_IDLE,				/* connection idle */
+	PQTRANS_ACTIVE,				/* command in progress */
+	PQTRANS_INTRANS,			/* idle, within transaction block */
+	PQTRANS_INERROR,			/* idle, within failed transaction */
+	PQTRANS_UNKNOWN				/* cannot determine status */
+} PGTransactionStatusType;
+
+typedef enum
+{
+	PQERRORS_TERSE,				/* single-line error messages */
+	PQERRORS_DEFAULT,			/* recommended style */
+	PQERRORS_VERBOSE			/* all the facts, ma'am */
+} PGVerbosity;
+
+/* PGconn encapsulates a connection to the backend.
+ * The contents of this struct are not supposed to be known to applications.
+ */
+typedef struct pg_conn PGconn;
+
+/* PGresult encapsulates the result of a query (or more precisely, of a single
+ * SQL command --- a query string given to PQsendQuery can contain multiple
+ * commands and thus return multiple PGresult objects).
+ * The contents of this struct are not supposed to be known to applications.
+ */
+typedef struct pg_result PGresult;
+
+/* PGcancel encapsulates the information needed to cancel a running
+ * query on an existing connection.
+ * The contents of this struct are not supposed to be known to applications.
+ */
+typedef struct pg_cancel PGcancel;
+
+/* PGnotify represents the occurrence of a NOTIFY message.
+ * Ideally this would be an opaque typedef, but it's so simple that it's
+ * unlikely to change.
+ * NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,
+ * whereas in earlier versions it was always your own backend's PID.
+ */
+typedef struct pgNotify
+{
+	char	   *relname;		/* notification condition name */
+	int			be_pid;			/* process ID of notifying server process */
+	char	   *extra;			/* notification parameter */
+	/* Fields below here are private to libpq; apps should not use 'em */
+	struct pgNotify *next;		/* list link */
+} PGnotify;
+
+/* Function types for notice-handling callbacks */
+typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);
+typedef void (*PQnoticeProcessor) (void *arg, const char *message);
+
+/* Print options for PQprint() */
+typedef char pqbool;
+
+typedef struct _PQprintOpt
+{
+	pqbool		header;			/* print output field headings and row count */
+	pqbool		align;			/* fill align the fields */
+	pqbool		standard;		/* old brain dead format */
+	pqbool		html3;			/* output html tables */
+	pqbool		expanded;		/* expand tables */
+	pqbool		pager;			/* use pager for output if needed */
+	char	   *fieldSep;		/* field separator */
+	char	   *tableOpt;		/* insert to HTML  */
+	char	   *caption;		/* HTML 
*/ + char **fieldName; /* null terminated array of replacement field + * names */ +} PQprintOpt; + +/* ---------------- + * Structure for the conninfo parameter definitions returned by PQconndefaults + * + * All fields except "val" point at static strings which must not be altered. + * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() + * will release both the val strings and the PQconninfoOption array itself. + * ---------------- + */ +typedef struct _PQconninfoOption +{ + char *keyword; /* The keyword of the option */ + char *envvar; /* Fallback environment variable name */ + char *compiled; /* Fallback compiled in default value */ + char *val; /* Option's current value, or NULL */ + char *label; /* Label for field in connect dialog */ + char *dispchar; /* Character to display for this field in a + * connect dialog. Values are: "" Display + * entered value as is "*" Password field - + * hide value "D" Debug option - don't show + * by default */ + int dispsize; /* Field size in characters for dialog */ +} PQconninfoOption; + +/* ---------------- + * PQArgBlock -- structure for PQfn() arguments + * ---------------- + */ +typedef struct +{ + int len; + int isint; + union + { + int *ptr; /* can't use void (dec compiler barfs) */ + int integer; + } u; +} PQArgBlock; + +/* ---------------- + * Exported functions of libpq + * ---------------- + */ + +/* === in fe-connect.c === */ + +/* make a new client connection to the backend */ +/* Asynchronous (non-blocking) */ +extern PGconn *PQconnectStart(const char *conninfo); +extern PostgresPollingStatusType PQconnectPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern PGconn *PQconnectdb(const char *conninfo); +extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, + const char *pgoptions, const char *pgtty, + const char *dbName, + const char *login, const char *pwd); + +#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \ + PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL) + +/* close the current connection and free the PGconn data structure */ +extern void PQfinish(PGconn *conn); + +/* get info about connection options known to PQconnectdb */ +extern PQconninfoOption *PQconndefaults(void); + +/* free the data structure returned by PQconndefaults() */ +extern void PQconninfoFree(PQconninfoOption *connOptions); + +/* + * close the current connection and restablish a new one with the same + * parameters + */ +/* Asynchronous (non-blocking) */ +extern int PQresetStart(PGconn *conn); +extern PostgresPollingStatusType PQresetPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern void PQreset(PGconn *conn); + +/* request a cancel structure */ +extern PGcancel *PQgetCancel(PGconn *conn); + +/* free a cancel structure */ +extern void PQfreeCancel(PGcancel *cancel); + +/* issue a cancel request */ +extern int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + +/* backwards compatible version of PQcancel; not thread-safe */ +extern int PQrequestCancel(PGconn *conn); + +/* Accessor functions for PGconn objects */ +extern char *PQdb(const PGconn *conn); +extern char *PQuser(const PGconn *conn); +extern char *PQpass(const PGconn *conn); +extern char *PQhost(const PGconn *conn); +extern char *PQport(const PGconn *conn); +extern char *PQtty(const PGconn *conn); +extern char *PQoptions(const PGconn *conn); +extern ConnStatusType PQstatus(const PGconn *conn); +extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); +extern const char *PQparameterStatus(const PGconn *conn, + const char *paramName); +extern int PQprotocolVersion(const PGconn *conn); +extern int PQserverVersion(const PGconn *conn); +extern char *PQerrorMessage(const PGconn *conn); +extern int PQsocket(const PGconn *conn); +extern int PQbackendPID(const PGconn *conn); +extern int PQconnectionNeedsPassword(const PGconn *conn); +extern int PQconnectionUsedPassword(const PGconn *conn); +extern int PQclientEncoding(const PGconn *conn); +extern int PQsetClientEncoding(PGconn *conn, const char *encoding); + +/* Get the OpenSSL structure associated with a connection. Returns NULL for + * unencrypted connections or if any other TLS library is in use. */ +extern void *PQgetssl(PGconn *conn); + +/* Tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitSSL(int do_init); + +/* Set verbosity for PQerrorMessage and PQresultErrorMessage */ +extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); + +/* Enable/disable tracing */ +extern void PQtrace(PGconn *conn, FILE *debug_port); +extern void PQuntrace(PGconn *conn); + +/* Override default notice handling routines */ +extern PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, + PQnoticeReceiver proc, + void *arg); +extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, + PQnoticeProcessor proc, + void *arg); + +/* + * Used to set callback that prevents concurrent access to + * non-thread safe functions that libpq needs. + * The default implementation uses a libpq internal mutex. + * Only required for multithreaded apps that use kerberos + * both within their app and for postgresql connections. + */ +typedef void (*pgthreadlock_t) (int acquire); + +extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler); + +/* === in fe-exec.c === */ + +/* Simple synchronous query */ +extern PGresult *PQexec(PGconn *conn, const char *query); +extern PGresult *PQexecParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern PGresult *PQprepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern PGresult *PQexecPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + +/* Interface for multiple-result or asynchronous queries */ +extern int PQsendQuery(PGconn *conn, const char *query); +extern int PQsendQueryParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsendPrepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern int PQsendQueryPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern PGresult *PQgetResult(PGconn *conn); + +/* Routines for managing an asynchronous query */ +extern int PQisBusy(PGconn *conn); +extern int PQconsumeInput(PGconn *conn); + +/* LISTEN/NOTIFY support */ +extern PGnotify *PQnotifies(PGconn *conn); + +/* Routines for copy in/out */ +extern int PQputCopyData(PGconn *conn, const char *buffer, int nbytes); +extern int PQputCopyEnd(PGconn *conn, const char *errormsg); +extern int PQgetCopyData(PGconn *conn, char **buffer, int async); + +/* Deprecated routines for copy in/out */ +extern int PQgetline(PGconn *conn, char *string, int length); +extern int PQputline(PGconn *conn, const char *string); +extern int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize); +extern int PQputnbytes(PGconn *conn, const char *buffer, int nbytes); +extern int PQendcopy(PGconn *conn); + +/* Set blocking/nonblocking connection to the backend */ +extern int PQsetnonblocking(PGconn *conn, int arg); +extern int PQisnonblocking(const PGconn *conn); +extern int PQisthreadsafe(void); + +/* Force the write buffer to be written (or at least try) */ +extern int PQflush(PGconn *conn); + +/* + * "Fast path" interface --- not really recommended for application + * use + */ +extern PGresult *PQfn(PGconn *conn, + int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); + +/* Accessor functions for PGresult objects */ +extern ExecStatusType PQresultStatus(const PGresult *res); +extern char *PQresStatus(ExecStatusType status); +extern char *PQresultErrorMessage(const PGresult *res); +extern char *PQresultErrorField(const PGresult *res, int fieldcode); +extern int PQntuples(const PGresult *res); +extern int PQnfields(const PGresult *res); +extern int PQbinaryTuples(const PGresult *res); +extern char *PQfname(const PGresult *res, int field_num); +extern int PQfnumber(const PGresult *res, const char *field_name); +extern Oid PQftable(const PGresult *res, int field_num); +extern int PQftablecol(const PGresult *res, int field_num); +extern int PQfformat(const PGresult *res, int field_num); +extern Oid PQftype(const PGresult *res, int field_num); +extern int PQfsize(const PGresult *res, int field_num); +extern int PQfmod(const PGresult *res, int field_num); +extern char *PQcmdStatus(PGresult *res); +extern char *PQoidStatus(const PGresult *res); /* old and ugly */ +extern Oid PQoidValue(const PGresult *res); /* new and improved */ +extern char *PQcmdTuples(PGresult *res); +extern char *PQgetvalue(const PGresult *res, int tup_num, int field_num); +extern int PQgetlength(const PGresult *res, int tup_num, int field_num); +extern int PQgetisnull(const PGresult *res, int tup_num, int field_num); +extern int PQnparams(const PGresult *res); +extern Oid PQparamtype(const PGresult *res, int param_num); + +/* Describe prepared statements and portals */ +extern PGresult *PQdescribePrepared(PGconn *conn, const char *stmt); +extern PGresult *PQdescribePortal(PGconn *conn, const char *portal); +extern int PQsendDescribePrepared(PGconn *conn, const char *stmt); +extern int PQsendDescribePortal(PGconn *conn, const char *portal); + +/* Delete a PGresult */ +extern void PQclear(PGresult *res); + +/* For freeing other alloc'd results, such as PGnotify structs */ +extern void PQfreemem(void *ptr); + +/* Exists for backward compatibility. bjm 2003-03-24 */ +#define PQfreeNotify(ptr) PQfreemem(ptr) + +/* Error when no password was given. */ +/* Note: depending on this is deprecated; use PQconnectionNeedsPassword(). */ +#define PQnoPasswordSupplied "fe_sendauth: no password supplied\n" + +/* + * Make an empty PGresult with given status (some apps find this + * useful). If conn is not NULL and status indicates an error, the + * conn's errorMessage is copied. + */ +extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); + + +/* Quoting strings before inclusion in queries. */ +extern size_t PQescapeStringConn(PGconn *conn, + char *to, const char *from, size_t length, + int *error); +extern unsigned char *PQescapeByteaConn(PGconn *conn, + const unsigned char *from, size_t from_length, + size_t *to_length); +extern unsigned char *PQunescapeBytea(const unsigned char *strtext, + size_t *retbuflen); + +/* These forms are deprecated! */ +extern size_t PQescapeString(char *to, const char *from, size_t length); +extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, + size_t *to_length); + + + +/* === in fe-print.c === */ + +extern void +PQprint(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *ps); /* option structure */ + +/* + * really old printing routines + */ +extern void +PQdisplayTuples(const PGresult *res, + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); + +extern void +PQprintTuples(const PGresult *res, + FILE *fout, /* output stream */ + int printAttName, /* print attribute names */ + int terseOutput, /* delimiter bars */ + int width); /* width of column, if 0, use variable width */ + + +/* === in fe-lobj.c === */ + +/* Large-object access routines */ +extern int lo_open(PGconn *conn, Oid lobjId, int mode); +extern int lo_close(PGconn *conn, int fd); +extern int lo_read(PGconn *conn, int fd, char *buf, size_t len); +extern int lo_write(PGconn *conn, int fd, const char *buf, size_t len); +extern int lo_lseek(PGconn *conn, int fd, int offset, int whence); +extern Oid lo_creat(PGconn *conn, int mode); +extern Oid lo_create(PGconn *conn, Oid lobjId); +extern int lo_tell(PGconn *conn, int fd); +extern int lo_truncate(PGconn *conn, int fd, size_t len); +extern int lo_unlink(PGconn *conn, Oid lobjId); +extern Oid lo_import(PGconn *conn, const char *filename); +extern int lo_export(PGconn *conn, Oid lobjId, const char *filename); + +/* === in fe-misc.c === */ + +/* Determine length of multibyte encoded char at *s */ +extern int PQmblen(const char *s, int encoding); + +/* Determine display length of multibyte encoded char at *s */ +extern int PQdsplen(const char *s, int encoding); + +/* Get encoding id from environment variable PGCLIENTENCODING */ +extern int PQenv2encoding(void); + +/* === in fe-auth.c === */ + +extern char *PQencryptPassword(const char *passwd, const char *user); + +/* === in encnames.c === */ + +extern int pg_char_to_encoding(const char *name); +extern const char *pg_encoding_to_char(int encoding); +extern int pg_valid_server_encoding_id(int encoding); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBPQ_FE_H */ diff --git a/dep/include/postgre/pg_type.h b/dep/include/postgre/pg_type.h new file mode 100644 index 000000000..823656cb1 --- /dev/null +++ b/dep/include/postgre/pg_type.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * pg_type.h + * definition of the system "type" relation (pg_type) + * along with the relation's initial contents. + * + * + * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/pg_type.h,v 1.8 2008/01/01 19:45:59 momjian Exp $ + * + * NOTES + * the genbki.sh script reads this file and generates .bki + * information from the DATA() statements. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TYPE_H +#define PG_TYPE_H + +/* ---------------- + * initial contents of pg_type + * ---------------- + */ + +/* keep the following ordered by OID so that later changes can be made easier*/ + +/* OIDS 1 - 99 */ +#define BOOLOID 16 +#define BYTEAOID 17 +#define CHAROID 18 +#define NAMEOID 19 +#define INT8OID 20 +#define INT2OID 21 +#define INT2VECTOROID 22 +#define INT4OID 23 +#define REGPROCOID 24 +#define TEXTOID 25 +#define OIDOID 26 +#define TIDOID 27 +#define XIDOID 28 +#define CIDOID 29 +#define OIDVECTOROID 30 +#define POINTOID 600 +#define LSEGOID 601 +#define PATHOID 602 +#define BOXOID 603 +#define POLYGONOID 604 +#define LINEOID 628 +#define FLOAT4OID 700 +#define FLOAT8OID 701 +#define ABSTIMEOID 702 +#define RELTIMEOID 703 +#define TINTERVALOID 704 +#define UNKNOWNOID 705 +#define CIRCLEOID 718 +#define CASHOID 790 +#define INETOID 869 +#define CIDROID 650 +#define BPCHAROID 1042 +#define VARCHAROID 1043 +#define DATEOID 1082 +#define TIMEOID 1083 +#define TIMESTAMPOID 1114 +#define TIMESTAMPTZOID 1184 +#define INTERVALOID 1186 +#define TIMETZOID 1266 +#define ZPBITOID 1560 +#define VARBITOID 1562 +#define NUMERICOID 1700 + +#endif /* PG_TYPE_H */ diff --git a/dep/include/postgre/postgres_ext.h b/dep/include/postgre/postgres_ext.h new file mode 100644 index 000000000..51a18b7dc --- /dev/null +++ b/dep/include/postgre/postgres_ext.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * postgres_ext.h + * + * This file contains declarations of things that are visible everywhere + * in PostgreSQL *and* are visible to clients of frontend interface libraries. + * For example, the Oid type is part of the API of libpq and other libraries. + * + * Declarations which are specific to a particular interface should + * go in the header file for that interface (such as libpq-fe.h). This + * file is only for fundamental Postgres declarations. + * + * User-written C functions don't count as "external to Postgres." + * Those function much as local modifications to the backend itself, and + * use header files that are otherwise internal to Postgres to interface + * with the backend. + * + * $PostgreSQL: pgsql/src/include/postgres_ext.h,v 1.17 2007/02/06 09:16:08 petere Exp $ + * + *------------------------------------------------------------------------- + */ + +#ifndef POSTGRES_EXT_H +#define POSTGRES_EXT_H + +/* + * Object ID is a fundamental type in Postgres. + */ +typedef unsigned int Oid; + +#ifdef __cplusplus +#define InvalidOid (Oid(0)) +#else +#define InvalidOid ((Oid) 0) +#endif + +#define OID_MAX UINT_MAX +/* you will need to include to use the above #define */ + + +/* + * Identifiers of error message fields. Kept here to keep common + * between frontend and backend, and also to export them to libpq + * applications. + */ +#define PG_DIAG_SEVERITY 'S' +#define PG_DIAG_SQLSTATE 'C' +#define PG_DIAG_MESSAGE_PRIMARY 'M' +#define PG_DIAG_MESSAGE_DETAIL 'D' +#define PG_DIAG_MESSAGE_HINT 'H' +#define PG_DIAG_STATEMENT_POSITION 'P' +#define PG_DIAG_INTERNAL_POSITION 'p' +#define PG_DIAG_INTERNAL_QUERY 'q' +#define PG_DIAG_CONTEXT 'W' +#define PG_DIAG_SOURCE_FILE 'F' +#define PG_DIAG_SOURCE_LINE 'L' +#define PG_DIAG_SOURCE_FUNCTION 'R' + +#endif diff --git a/dep/include/sockets/Base64.h b/dep/include/sockets/Base64.h new file mode 100644 index 000000000..a632bbec7 --- /dev/null +++ b/dep/include/sockets/Base64.h @@ -0,0 +1,77 @@ +/** \file Base64.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Base64_H +#define _SOCKETS_Base64_H + +#include "sockets-config.h" +#ifdef _MSC_VER +#pragma warning(disable:4514) +#endif + +#include +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +/** \defgroup util Utilities */ + +/** Base64 encode/decode. + \ingroup util */ +class Base64 +{ +public: + Base64(); + + void encode(FILE *, std::string& , bool add_crlf = true); + void encode(const std::string&, std::string& , bool add_crlf = true); + void encode(const char *, size_t, std::string& , bool add_crlf = true); + void encode(const unsigned char *, size_t, std::string& , bool add_crlf = true); + + void decode(const std::string&, std::string& ); + void decode(const std::string&, unsigned char *, size_t&); + + size_t decode_length(const std::string& ); + +private: + Base64(const Base64& ) {} + Base64& operator=(const Base64& ) { return *this; } +static const char *bstr; +static const char rstr[128]; +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_Base64_H + diff --git a/dep/include/sockets/Exception.h b/dep/include/sockets/Exception.h new file mode 100644 index 000000000..81ba7373d --- /dev/null +++ b/dep/include/sockets/Exception.h @@ -0,0 +1,58 @@ +/** + ** \file Exception.h + ** \date 2007-09-28 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _Sockets_Exception_H +#define _Sockets_Exception_H + +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + + +class Exception +{ +public: + Exception(const std::string& description); + virtual ~Exception() {} + + virtual const std::string ToString() const; + + Exception(const Exception& ) {} // copy constructor + + Exception& operator=(const Exception& ) { return *this; } // assignment operator + +private: + std::string m_description; + +}; + + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif + +#endif // _Sockets_Exception_H + diff --git a/dep/include/sockets/File.h b/dep/include/sockets/File.h new file mode 100644 index 000000000..58a1b71bb --- /dev/null +++ b/dep/include/sockets/File.h @@ -0,0 +1,84 @@ +/** \file File.h + ** \date 2005-04-25 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_File_H +#define _SOCKETS_File_H + +#include "sockets-config.h" +#include "IFile.h" +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** IFile implementation of a disk file. + \ingroup file */ +class File : public IFile +{ +public: + File(); + ~File(); + + bool fopen(const std::string&, const std::string&); + void fclose(); + + size_t fread(char *, size_t, size_t) const; + size_t fwrite(const char *, size_t, size_t); + + char *fgets(char *, int) const; + void fprintf(const char *format, ...); + + off_t size() const; + bool eof() const; + + void reset_read() const; + void reset_write(); + +private: + File(const File& ) {} // copy constructor + File& operator=(const File& ) { return *this; } // assignment operator + + std::string m_path; + std::string m_mode; + FILE *m_fil; + mutable long m_rptr; + long m_wptr; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_File_H + diff --git a/dep/include/sockets/IFile.h b/dep/include/sockets/IFile.h new file mode 100644 index 000000000..aecc50f59 --- /dev/null +++ b/dep/include/sockets/IFile.h @@ -0,0 +1,71 @@ +/** \file IFile.h + ** \date 2005-04-25 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_IFile_H +#define _SOCKETS_IFile_H + +#include "sockets-config.h" +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +/** \defgroup file File handling */ +/** Pure virtual file I/O interface. + \ingroup file */ +class IFile +{ +public: + virtual ~IFile() {} + + virtual bool fopen(const std::string&, const std::string&) = 0; + virtual void fclose() = 0; + + virtual size_t fread(char *, size_t, size_t) const = 0; + virtual size_t fwrite(const char *, size_t, size_t) = 0; + + virtual char *fgets(char *, int) const = 0; + virtual void fprintf(const char *format, ...) = 0; + + virtual off_t size() const = 0; + virtual bool eof() const = 0; + + virtual void reset_read() const = 0; + virtual void reset_write() = 0; + +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_IFile_H + diff --git a/dep/include/sockets/ISocketHandler.h b/dep/include/sockets/ISocketHandler.h new file mode 100644 index 000000000..2667e2d22 --- /dev/null +++ b/dep/include/sockets/ISocketHandler.h @@ -0,0 +1,232 @@ +/** \file ISocketHandler.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_ISocketHandler_H +#define _SOCKETS_ISocketHandler_H +#include "sockets-config.h" + +#include + +#include "socket_include.h" +#include "Socket.h" +#include "StdLog.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +typedef enum { + LIST_CALLONCONNECT = 0, +#ifdef ENABLE_DETACH + LIST_DETACH, +#endif + LIST_TIMEOUT, + LIST_RETRY, + LIST_CLOSE +} list_t; + +class SocketAddress; +class Mutex; + + +/** Socket container class, event generator. + \ingroup basic */ +class ISocketHandler +{ + friend class Socket; + +public: + /** Connection pool class for internal use by the ISocketHandler. + \ingroup internal */ +#ifdef ENABLE_POOL + class PoolSocket : public Socket + { + public: + PoolSocket(ISocketHandler& h,Socket *src) : Socket(h) { + CopyConnection( src ); + SetIsClient(); + } + + void OnRead() { + Handler().LogError(this, "OnRead", 0, "data on hibernating socket", LOG_LEVEL_FATAL); + SetCloseAndDelete(); + } + void OnOptions(int,int,int,SOCKET) {} + + }; +#endif + +public: + virtual ~ISocketHandler() {} + + /** Get mutex reference for threadsafe operations. */ + virtual Mutex& GetMutex() const = 0; + + /** Register StdLog object for error callback. + \param log Pointer to log class */ + virtual void RegStdLog(StdLog *log) = 0; + + /** Log error to log class for print out / storage. */ + virtual void LogError(Socket *p,const std::string& user_text,int err,const std::string& sys_err,loglevel_t t = LOG_LEVEL_WARNING) = 0; + + // ------------------------------------------------------------------------- + // Socket stuff + // ------------------------------------------------------------------------- + /** Add socket instance to socket map. Removal is always automatic. */ + virtual void Add(Socket *) = 0; +private: + /** Remove socket from socket map, used by Socket class. */ + virtual void Remove(Socket *) = 0; +public: + /** Get status of read/write/exception file descriptor set for a socket. */ + virtual void Get(SOCKET s,bool& r,bool& w,bool& e) = 0; + /** Set read/write/exception file descriptor sets (fd_set). */ + virtual void Set(SOCKET s,bool bRead,bool bWrite,bool bException = true) = 0; + + /** Wait for events, generate callbacks. */ + virtual int Select(long sec,long usec) = 0; + /** This method will not return until an event has been detected. */ + virtual int Select() = 0; + /** Wait for events, generate callbacks. */ + virtual int Select(struct timeval *tsel) = 0; + + /** Check that a socket really is handled by this socket handler. */ + virtual bool Valid(Socket *) = 0; + /** Return number of sockets handled by this handler. */ + virtual size_t GetCount() = 0; + + /** Override and return false to deny all incoming connections. + \param p ListenSocket class pointer (use GetPort to identify which one) */ + virtual bool OkToAccept(Socket *p) = 0; + + /** Called by Socket when a socket changes state. */ + virtual void AddList(SOCKET s,list_t which_one,bool add) = 0; + + // ------------------------------------------------------------------------- + // Connection pool + // ------------------------------------------------------------------------- +#ifdef ENABLE_POOL + /** Find available open connection (used by connection pool). */ + virtual ISocketHandler::PoolSocket *FindConnection(int type,const std::string& protocol,SocketAddress&) = 0; + /** Enable connection pool (by default disabled). */ + virtual void EnablePool(bool = true) = 0; + /** Check pool status. + \return true if connection pool is enabled */ + virtual bool PoolEnabled() = 0; +#endif // ENABLE_POOL + + // ------------------------------------------------------------------------- + // Socks4 + // ------------------------------------------------------------------------- +#ifdef ENABLE_SOCKS4 + /** Set socks4 server ip that all new tcp sockets should use. */ + virtual void SetSocks4Host(ipaddr_t) = 0; + /** Set socks4 server hostname that all new tcp sockets should use. */ + virtual void SetSocks4Host(const std::string& ) = 0; + /** Set socks4 server port number that all new tcp sockets should use. */ + virtual void SetSocks4Port(port_t) = 0; + /** Set optional socks4 userid. */ + virtual void SetSocks4Userid(const std::string& ) = 0; + /** If connection to socks4 server fails, immediately try direct connection to final host. */ + virtual void SetSocks4TryDirect(bool = true) = 0; + /** Get socks4 server ip. + \return socks4 server ip */ + virtual ipaddr_t GetSocks4Host() = 0; + /** Get socks4 port number. + \return socks4 port number */ + virtual port_t GetSocks4Port() = 0; + /** Get socks4 userid (optional). + \return socks4 userid */ + virtual const std::string& GetSocks4Userid() = 0; + /** Check status of socks4 try direct flag. + \return true if direct connection should be tried if connection to socks4 server fails */ + virtual bool Socks4TryDirect() = 0; +#endif // ENABLE_SOCKS4 + + // ------------------------------------------------------------------------- + // DNS resolve server + // ------------------------------------------------------------------------- +#ifdef ENABLE_RESOLVER + /** Enable asynchronous DNS. + \param port Listen port of asynchronous dns server */ + virtual void EnableResolver(port_t = 16667) = 0; + /** Check resolver status. + \return true if resolver is enabled */ + virtual bool ResolverEnabled() = 0; + /** Queue a dns request. + \param host Hostname to be resolved + \param port Port number will be echoed in Socket::OnResolved callback */ + virtual int Resolve(Socket *,const std::string& host,port_t port) = 0; +#ifdef ENABLE_IPV6 + virtual int Resolve6(Socket *,const std::string& host,port_t port) = 0; +#endif + /** Do a reverse dns lookup. */ + virtual int Resolve(Socket *,ipaddr_t a) = 0; +#ifdef ENABLE_IPV6 + virtual int Resolve(Socket *,in6_addr& a) = 0; +#endif + /** Get listen port of asynchronous dns server. */ + virtual port_t GetResolverPort() = 0; + /** Resolver thread ready for queries. */ + virtual bool ResolverReady() = 0; + /** Returns true if socket waiting for a resolve event. */ + virtual bool Resolving(Socket *) = 0; +#endif // ENABLE_RESOLVER + +#ifdef ENABLE_TRIGGERS + /** Fetch unique trigger id. */ + virtual int TriggerID(Socket *src) = 0; + /** Subscribe socket to trigger id. */ + virtual bool Subscribe(int id, Socket *dst) = 0; + /** Unsubscribe socket from trigger id. */ + virtual bool Unsubscribe(int id, Socket *dst) = 0; + /** Execute OnTrigger for subscribed sockets. + \param id Trigger ID + \param data Data passed from source to destination + \param erase Empty trigger id source and destination maps if 'true', + Leave them in place if 'false' - if a trigger should be called many times */ + virtual void Trigger(int id, Socket::TriggerData& data, bool erase = true) = 0; +#endif // ENABLE_TRIGGERS + +#ifdef ENABLE_DETACH + /** Indicates that the handler runs under SocketThread. */ + virtual void SetSlave(bool x = true) = 0; + /** Indicates that the handler runs under SocketThread. */ + virtual bool IsSlave() = 0; +#endif // ENABLE_DETACH + +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_ISocketHandler_H + diff --git a/dep/include/sockets/Ipv4Address.h b/dep/include/sockets/Ipv4Address.h new file mode 100644 index 000000000..b58c2ce94 --- /dev/null +++ b/dep/include/sockets/Ipv4Address.h @@ -0,0 +1,98 @@ +/** + ** \file Ipv4Address.h + ** \date 2006-09-21 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Ipv4Address_H +#define _SOCKETS_Ipv4Address_H + +#include "sockets-config.h" +#include "SocketAddress.h" + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/* Ipv4 address implementation. + \ingroup basic */ +class Ipv4Address : public SocketAddress +{ +public: + /** Create empty Ipv4 address structure. + \param port Port number */ + Ipv4Address(port_t port = 0); + /** Create Ipv4 address structure. + \param a Socket address in network byte order (as returned by Utility::u2ip) + \param port Port number in host byte order */ + Ipv4Address(ipaddr_t a,port_t port); + /** Create Ipv4 address structure. + \param a Socket address in network byte order + \param port Port number in host byte order */ + Ipv4Address(struct in_addr& a,port_t port); + /** Create Ipv4 address structure. + \param host Hostname to be resolved + \param port Port number in host byte order */ + Ipv4Address(const std::string& host,port_t port); + Ipv4Address(struct sockaddr_in&); + ~Ipv4Address(); + + // SocketAddress implementation + + operator struct sockaddr *(); + operator socklen_t(); + bool operator==(SocketAddress&); + + void SetPort(port_t port); + port_t GetPort(); + + void SetAddress(struct sockaddr *sa); + int GetFamily(); + + bool IsValid(); + std::auto_ptr GetCopy(); + + /** Convert address struct to text. */ + std::string Convert(bool include_port = false); + std::string Reverse(); + + /** Resolve hostname. */ +static bool Resolve(const std::string& hostname,struct in_addr& a); + /** Reverse resolve (IP to hostname). */ +static bool Reverse(struct in_addr& a,std::string& name); + /** Convert address struct to text. */ +static std::string Convert(struct in_addr& a); + +private: + Ipv4Address(const Ipv4Address& ) {} // copy constructor + Ipv4Address& operator=(const Ipv4Address& ) { return *this; } // assignment operator + struct sockaddr_in m_addr; + bool m_valid; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif +#endif // _SOCKETS_Ipv4Address_H + diff --git a/dep/include/sockets/Ipv6Address.h b/dep/include/sockets/Ipv6Address.h new file mode 100644 index 000000000..a07114179 --- /dev/null +++ b/dep/include/sockets/Ipv6Address.h @@ -0,0 +1,107 @@ +/** + ** \file Ipv6Address.h + ** \date 2006-09-21 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Ipv6Address_H +#define _SOCKETS_Ipv6Address_H +#include "sockets-config.h" +#ifdef ENABLE_IPV6 + +#include "SocketAddress.h" +#ifdef IPPROTO_IPV6 +#if defined( _WIN32) && !defined(__CYGWIN__) +typedef unsigned __int32 uint32_t; +#endif + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** Ipv6 address implementation. + \ingroup basic */ +class Ipv6Address : public SocketAddress +{ +public: + /** Create empty Ipv6 address structure. + \param port Port number */ + Ipv6Address(port_t port = 0); + /** Create Ipv6 address structure. + \param a Socket address in network byte order + \param port Port number in host byte order */ + Ipv6Address(struct in6_addr& a,port_t port); + /** Create Ipv6 address structure. + \param host Hostname to be resolved + \param port Port number in host byte order */ + Ipv6Address(const std::string& host,port_t port); + Ipv6Address(struct sockaddr_in6&); + ~Ipv6Address(); + + // SocketAddress implementation + + operator struct sockaddr *(); + operator socklen_t(); + bool operator==(SocketAddress&); + + void SetPort(port_t port); + port_t GetPort(); + + void SetAddress(struct sockaddr *sa); + int GetFamily(); + + bool IsValid(); + std::auto_ptr GetCopy(); + + /** Convert address struct to text. */ + std::string Convert(bool include_port = false); + std::string Reverse(); + + /** Resolve hostname. */ +static bool Resolve(const std::string& hostname,struct in6_addr& a); + /** Reverse resolve (IP to hostname). */ +static bool Reverse(struct in6_addr& a,std::string& name); + /** Convert address struct to text. */ +static std::string Convert(struct in6_addr& a,bool mixed = false); + + void SetFlowinfo(uint32_t); + uint32_t GetFlowinfo(); +#ifndef _WIN32 + void SetScopeId(uint32_t); + uint32_t GetScopeId(); +#endif + +private: + Ipv6Address(const Ipv6Address& ) {} // copy constructor + Ipv6Address& operator=(const Ipv6Address& ) { return *this; } // assignment operator + struct sockaddr_in6 m_addr; + bool m_valid; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif +#endif // IPPROTO_IPV6 +#endif // ENABLE_IPV6 +#endif // _SOCKETS_Ipv6Address_H + diff --git a/dep/include/sockets/ListenSocket.h b/dep/include/sockets/ListenSocket.h new file mode 100644 index 000000000..f4edc37d6 --- /dev/null +++ b/dep/include/sockets/ListenSocket.h @@ -0,0 +1,420 @@ +/** \file ListenSocket.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_ListenSocket_H +#define _SOCKETS_ListenSocket_H +#include "sockets-config.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "ISocketHandler.h" +#include "Socket.h" +#include "Utility.h" +#include "SctpSocket.h" +#include "Ipv4Address.h" +#include "Ipv6Address.h" +#ifdef ENABLE_EXCEPTIONS +#include "Exception.h" +#endif + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** Binds incoming port number to new Socket class X. + \ingroup basic */ +template +class ListenSocket : public Socket +{ +public: + /** Constructor. + \param h ISocketHandler reference + \param use_creator Optional use of creator (default true) */ + ListenSocket(ISocketHandler& h,bool use_creator = true) : Socket(h), m_depth(0), m_creator(NULL) + ,m_bHasCreate(false) + { + if (use_creator) + { + m_creator = new X(h); + Socket *tmp = m_creator -> Create(); + if (tmp && dynamic_cast(tmp)) + { + m_bHasCreate = true; + } + if (tmp) + { + delete tmp; + } + } + } + ~ListenSocket() { + if (m_creator) + { + delete m_creator; + } + } + + /** Close file descriptor. */ + int Close() { + if (GetSocket() != INVALID_SOCKET) + { + closesocket(GetSocket()); + } + return 0; + } + + /** Bind and listen to any interface. + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(port_t port,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(port); + return Bind(ad, depth); + } + else +#endif +#endif + { + Ipv4Address ad(port); + return Bind(ad, depth); + } + } + + int Bind(SocketAddress& ad,int depth) { +#ifdef USE_SCTP + if (dynamic_cast(m_creator)) + { + return Bind(ad, "sctp", depth); + } +#endif + return Bind(ad, "tcp", depth); + } + + /** Bind and listen to any interface, with optional protocol. + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(port_t port,const std::string& protocol,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(port); + return Bind(ad, protocol, depth); + } + else +#endif +#endif + { + Ipv4Address ad(port); + return Bind(ad, protocol, depth); + } + } + + /** Bind and listen to specific interface. + \param intf Interface hostname + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(const std::string& intf,port_t port,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + else +#endif +#endif + { + Ipv4Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + } + + /** Bind and listen to specific interface. + \param intf Interface hostname + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(const std::string& intf,port_t port,const std::string& protocol,int depth = 20) { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, protocol, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + else +#endif +#endif + { + Ipv4Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, protocol, depth); + } + Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL); + return -1; + } + } + + /** Bind and listen to ipv4 interface. + \param a Ipv4 interface address + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(ipaddr_t a,port_t port,int depth = 20) { + Ipv4Address ad(a, port); +#ifdef USE_SCTP + if (dynamic_cast(m_creator)) + { + return Bind(ad, "sctp", depth); + } +#endif + return Bind(ad, "tcp", depth); + } + /** Bind and listen to ipv4 interface. + \param a Ipv4 interface address + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(ipaddr_t a,port_t port,const std::string& protocol,int depth) { + Ipv4Address ad(a, port); + return Bind(ad, protocol, depth); + } + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Bind and listen to ipv6 interface. + \param a Ipv6 interface address + \param port Port (0 is random) + \param depth Listen queue depth */ + int Bind(in6_addr a,port_t port,int depth = 20) { + Ipv6Address ad(a, port); +#ifdef USE_SCTP + if (dynamic_cast(m_creator)) + { + return Bind(ad, "sctp", depth); + } +#endif + return Bind(ad, "tcp", depth); + } + /** Bind and listen to ipv6 interface. + \param a Ipv6 interface address + \param port Port (0 is random) + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(in6_addr a,port_t port,const std::string& protocol,int depth) { + Ipv6Address ad(a, port); + return Bind(ad, protocol, depth); + } +#endif +#endif + + /** Bind and listen to network interface. + \param ad Interface address + \param protocol Network protocol + \param depth Listen queue depth */ + int Bind(SocketAddress& ad,const std::string& protocol,int depth) { + SOCKET s; + if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET) + { + return -1; + } + if (bind(s, ad, ad) == -1) + { + Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL); + closesocket(s); +#ifdef ENABLE_EXCEPTIONS + throw Exception("bind() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno)); +#endif + return -1; + } + if (listen(s, depth) == -1) + { + Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL); + closesocket(s); +#ifdef ENABLE_EXCEPTIONS + throw Exception("listen() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno)); +#endif + return -1; + } + m_depth = depth; + Attach(s); + return 0; + } + + /** Return assigned port number. */ + port_t GetPort() + { + return GetSockPort(); + } + + /** Return listen queue depth. */ + int GetDepth() + { + return m_depth; + } + + /** OnRead on a ListenSocket receives an incoming connection. */ + void OnRead() + { + struct sockaddr sa; + socklen_t sa_len = sizeof(struct sockaddr); + SOCKET a_s = accept(GetSocket(), &sa, &sa_len); + + if (a_s == INVALID_SOCKET) + { + Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR); + return; + } + if (!Handler().OkToAccept(this)) + { + Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING); + closesocket(a_s); + return; + } + if (Handler().GetCount() >= FD_SETSIZE) + { + Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler fd_set limit reached", LOG_LEVEL_FATAL); + closesocket(a_s); + return; + } + Socket *tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler()); +#ifdef ENABLE_IPV6 + tmp -> SetIpv6( IsIpv6() ); +#endif + tmp -> SetParent(this); + tmp -> Attach(a_s); + tmp -> SetNonblocking(true); + { +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (sa_len == sizeof(struct sockaddr_in6)) + { + struct sockaddr_in6 *p = (struct sockaddr_in6 *)&sa; + if (p -> sin6_family == AF_INET6) + { + Ipv6Address ad(p -> sin6_addr,ntohs(p -> sin6_port)); + ad.SetFlowinfo(p -> sin6_flowinfo); +#ifndef _WIN32 + ad.SetScopeId(p -> sin6_scope_id); +#endif + tmp -> SetRemoteAddress(ad); + } + } +#endif +#endif + if (sa_len == sizeof(struct sockaddr_in)) + { + struct sockaddr_in *p = (struct sockaddr_in *)&sa; + if (p -> sin_family == AF_INET) + { + Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port)); + tmp -> SetRemoteAddress(ad); + } + } + } + tmp -> SetConnected(true); + tmp -> Init(); + tmp -> SetDeleteByHandler(true); + Handler().Add(tmp); +#ifdef HAVE_OPENSSL + if (tmp -> IsSSL()) // SSL Enabled socket + { + // %! OnSSLAccept calls SSLNegotiate that can finish in this one call. + // %! If that happens and negotiation fails, the 'tmp' instance is + // %! still added to the list of active sockets in the sockethandler. + // %! See bugfix for this in SocketHandler::Select - don't Set rwx + // %! flags if CloseAndDelete() flag is true. + // %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids + // %! the Add problem altogether, so ignore the above. + // %! (OnSSLAccept does no longer call SSLNegotiate().) + tmp -> OnSSLAccept(); + } + else +#endif + { + tmp -> OnAccept(); + } + } + + /** Please don't use this method. + "accept()" is handled automatically in the OnRead() method. */ + virtual SOCKET Accept(SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr) + { + return accept(socket, saptr, lenptr); + } + + bool HasCreator() { return m_bHasCreate; } + + void OnOptions(int,int,int,SOCKET) { + SetSoReuseaddr(true); + } + +protected: + ListenSocket(const ListenSocket& s) : Socket(s) {} +private: + ListenSocket& operator=(const ListenSocket& ) { return *this; } + int m_depth; + X *m_creator; + bool m_bHasCreate; +}; + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_ListenSocket_H + diff --git a/dep/include/sockets/Lock.h b/dep/include/sockets/Lock.h new file mode 100644 index 000000000..71fdd5e73 --- /dev/null +++ b/dep/include/sockets/Lock.h @@ -0,0 +1,59 @@ +/** \file Lock.h + ** \date 2005-08-22 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2005,2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Lock_H +#define _SOCKETS_Lock_H + +#include "sockets-config.h" +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +class Mutex; + +/** Mutex encapsulation class. + \ingroup threading */ +class Lock +{ +public: + Lock(Mutex&); + ~Lock(); + +private: + Mutex& m_mutex; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} +#endif +#endif // _SOCKETS_Lock_H + diff --git a/dep/include/sockets/Mutex.h b/dep/include/sockets/Mutex.h new file mode 100644 index 000000000..1de27760a --- /dev/null +++ b/dep/include/sockets/Mutex.h @@ -0,0 +1,68 @@ +/** \file Mutex.h + ** \date 2004-10-30 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Mutex_H +#define _SOCKETS_Mutex_H + +#include "sockets-config.h" +#ifndef _WIN32 +#include +#else +#include +#endif + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +/** Mutex container class, used by Lock. + \ingroup threading */ +class Mutex +{ + friend class Lock; +public: + Mutex(); + ~Mutex(); + + void Lock(); + void Unlock(); +private: +#ifdef _WIN32 + HANDLE m_mutex; +#else + pthread_mutex_t m_mutex; +#endif +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif +#endif // _SOCKETS_Mutex_H + diff --git a/dep/include/sockets/Parse.h b/dep/include/sockets/Parse.h new file mode 100644 index 000000000..6961f3b1b --- /dev/null +++ b/dep/include/sockets/Parse.h @@ -0,0 +1,101 @@ +/** \file Parse.h - parse a string + ** + ** Written: 1999-Feb-10 grymse@alhem.net + **/ + +/* +Copyright (C) 1999-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef _SOCKETS_Parse_H +#define _SOCKETS_Parse_H + +#include "sockets-config.h" +#ifdef _MSC_VER +#pragma warning(disable:4514) +#endif + +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/***************************************************/ +/* interface of class Parse */ + +/** Splits a string whatever way you want. + \ingroup util */ +class Parse +{ +public: + Parse(); + Parse(const std::string&); + Parse(const std::string&,const std::string&); + Parse(const std::string&,const std::string&,short); + ~Parse(); + short issplit(const char); + void getsplit(); + void getsplit(std::string&); + std::string getword(); + void getword(std::string&); + void getword(std::string&,std::string&,int); + std::string getrest(); + void getrest(std::string&); + long getvalue(); + void setbreak(const char); + int getwordlen(); + int getrestlen(); + void enablebreak(const char c) { + pa_enable = c; + } + void disablebreak(const char c) { + pa_disable = c; + } + void getline(); + void getline(std::string&); + size_t getptr() { return pa_the_ptr; } + void EnableQuote(bool b) { pa_quote = b; } + +private: + std::string pa_the_str; + std::string pa_splits; + std::string pa_ord; + size_t pa_the_ptr; + char pa_breakchar; + char pa_enable; + char pa_disable; + short pa_nospace; + bool pa_quote; +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_Parse_H + diff --git a/dep/include/sockets/ResolvServer.h b/dep/include/sockets/ResolvServer.h new file mode 100644 index 000000000..f8f8f5aad --- /dev/null +++ b/dep/include/sockets/ResolvServer.h @@ -0,0 +1,73 @@ +/** \file ResolvServer.h + ** \date 2005-03-24 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_ResolvServer_H +#define _SOCKETS_ResolvServer_H +#include "sockets-config.h" +#ifdef ENABLE_RESOLVER +#include "socket_include.h" +#include "Thread.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +/** \defgroup async Asynchronous DNS */ +/** Async DNS resolver thread. + \ingroup async */ +class ResolvServer : public Thread +{ +public: + ResolvServer(port_t); + ~ResolvServer(); + + void Run(); + void Quit(); + + bool Ready(); + +private: + ResolvServer(const ResolvServer& ) {} // copy constructor + ResolvServer& operator=(const ResolvServer& ) { return *this; } // assignment operator + + bool m_quit; + port_t m_port; + bool m_ready; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // ENABLE_RESOLVER +#endif // _SOCKETS_ResolvServer_H + diff --git a/dep/include/sockets/ResolvSocket.h b/dep/include/sockets/ResolvSocket.h new file mode 100644 index 000000000..ff4b1a5a9 --- /dev/null +++ b/dep/include/sockets/ResolvSocket.h @@ -0,0 +1,106 @@ +/** \file ResolvSocket.h + ** \date 2005-03-24 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_ResolvSocket_H +#define _SOCKETS_ResolvSocket_H +#include "sockets-config.h" +#ifdef ENABLE_RESOLVER +#include "TcpSocket.h" +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +class Mutex; + +/** Async DNS resolver socket. + \ingroup async */ +class ResolvSocket : public TcpSocket +{ + typedef std::map > cache_t; /* host, result */ + typedef std::map > timeout_t; /* host, time */ + +public: + ResolvSocket(ISocketHandler&); + ResolvSocket(ISocketHandler&, Socket *parent, const std::string& host, port_t port, bool ipv6 = false); + ResolvSocket(ISocketHandler&, Socket *parent, ipaddr_t); +#ifdef ENABLE_IPV6 + ResolvSocket(ISocketHandler&, Socket *parent, in6_addr&); +#endif + ~ResolvSocket(); + + void OnAccept() { m_bServer = true; } + void OnLine(const std::string& line); + void OnDetached(); + void OnDelete(); + + void SetId(int x) { m_resolv_id = x; } + int GetId() { return m_resolv_id; } + + void OnConnect(); + +#ifdef ENABLE_IPV6 + void SetResolveIpv6(bool x = true) { m_resolve_ipv6 = x; } +#endif + +private: + ResolvSocket(const ResolvSocket& s) : TcpSocket(s) {} // copy constructor + ResolvSocket& operator=(const ResolvSocket& ) { return *this; } // assignment operator + + std::string m_query; + std::string m_data; + bool m_bServer; + Socket *m_parent; + int m_resolv_id; + std::string m_resolv_host; + port_t m_resolv_port; + ipaddr_t m_resolv_address; +#ifdef ENABLE_IPV6 + bool m_resolve_ipv6; + in6_addr m_resolv_address6; +#endif + static cache_t m_cache; + static timeout_t m_cache_to; + static Mutex m_cache_mutex; + bool m_cached; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // ENABLE_RESOLVER +#endif // _SOCKETS_ResolvSocket_H + diff --git a/dep/include/sockets/SctpSocket.h b/dep/include/sockets/SctpSocket.h new file mode 100644 index 000000000..d6d55f6be --- /dev/null +++ b/dep/include/sockets/SctpSocket.h @@ -0,0 +1,109 @@ +/** + ** \file SctpSocket.h + ** \date 2006-09-04 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_SctpSocket_H +#define _SOCKETS_SctpSocket_H +#include "sockets-config.h" + +#include "StreamSocket.h" +#ifdef USE_SCTP +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +#define SCTP_BUFSIZE_READ 16400 + +class SocketAddress; + + +class SctpSocket : public StreamSocket +{ +public: + /** SctpSocket constructor. + \param h Owner + \param type SCTP_STREAM or SCTP_SEQPACKET */ + SctpSocket(ISocketHandler& h,int type); + ~SctpSocket(); + + /** bind() */ + int Bind(const std::string&,port_t); + int Bind(SocketAddress&); + /** sctp_bindx() */ + int AddAddress(const std::string&,port_t); + int AddAddress(SocketAddress&); + /** sctp_bindx() */ + int RemoveAddress(const std::string&,port_t); + int RemoveAddress(SocketAddress&); + + /** connect() */ + int Open(const std::string&,port_t); + int Open(SocketAddress&); + + /** Connect timeout callback. */ + void OnConnectTimeout(); +#ifdef _WIN32 + /** Connection failed reported as exception on win32 */ + void OnException(); +#endif + +#ifndef SOLARIS + /** sctp_connectx() */ + int AddConnection(const std::string&,port_t); + int AddConnection(SocketAddress&); +#endif + + /** Get peer addresses of an association. */ + int getpaddrs(sctp_assoc_t id,std::list&); + /** Get all bound addresses of an association. */ + int getladdrs(sctp_assoc_t id,std::list&); + + /** sctp_peeloff */ + int PeelOff(sctp_assoc_t id); + + /** recvmsg callback */ + virtual void OnReceiveMessage(const char *buf,size_t sz,struct sockaddr *sa,socklen_t sa_len,struct sctp_sndrcvinfo *sinfo,int msg_flags) = 0; + + void OnOptions(int,int,int,SOCKET) {} + + virtual int Protocol(); + +protected: + SctpSocket(const SctpSocket& s) : StreamSocket(s) {} + void OnRead(); + void OnWrite(); + +private: + SctpSocket& operator=(const SctpSocket& s) { return *this; } + int m_type; ///< SCTP_STREAM or SCTP_SEQPACKET + char *m_buf; ///< Temporary receive buffer +}; + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE +#endif + +#endif // USE_SCTP +#endif // _SOCKETS_SctpSocket_H + diff --git a/dep/include/sockets/Socket.h b/dep/include/sockets/Socket.h new file mode 100644 index 000000000..bdb5fc603 --- /dev/null +++ b/dep/include/sockets/Socket.h @@ -0,0 +1,739 @@ +/** \file Socket.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This software is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Socket_H +#define _SOCKETS_Socket_H +#include "sockets-config.h" + +#include +#include +#include +#ifdef HAVE_OPENSSL +#include +#endif + +#include "socket_include.h" +#include +#include "SocketAddress.h" +#include "Thread.h" + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +class ISocketHandler; +class SocketAddress; +class IFile; + + +/** \defgroup basic Basic sockets */ +/** Socket base class. + \ingroup basic */ +class Socket +{ + friend class ISocketHandler; +#ifdef ENABLE_DETACH + /** Detached socket run thread. + \ingroup internal */ + class SocketThread : public Thread + { + public: + SocketThread(Socket *p); + ~SocketThread(); + + void Run(); + + private: + Socket *GetSocket() const { return m_socket; } + SocketThread(const SocketThread& s) : m_socket(s.GetSocket()) {} + SocketThread& operator=(const SocketThread& ) { return *this; } + Socket *m_socket; + }; +#endif // ENABLE_DETACH + +#ifdef ENABLE_TRIGGERS +public: + /** Data pass class from source to destination. */ + class TriggerData + { + public: + TriggerData() : m_src(NULL) {} + virtual ~TriggerData() {} + + Socket *GetSource() const { return m_src; } + void SetSource(Socket *x) { m_src = x; } + + private: + Socket *m_src; + }; +#endif // ENABLE_TRIGGERS + + /** Socket mode flags. */ +/* + enum { + // Socket + SOCK_DEL = 0x01, ///< Delete by handler flag + SOCK_CLOSE = 0x02, ///< Close and delete flag + SOCK_DISABLE_READ = 0x04, ///< Disable checking for read events + SOCK_CONNECTED = 0x08, ///< Socket is connected (tcp/udp) + + SOCK_ERASED_BY_HANDLER = 0x10, ///< Set by handler before delete + // HAVE_OPENSSL + SOCK_ENABLE_SSL = 0x20, ///< Enable SSL for this TcpSocket + SOCK_SSL = 0x40, ///< ssl negotiation mode (TcpSocket) + SOCK_SSL_SERVER = 0x80, ///< True if this is an incoming ssl TcpSocket connection + + // ENABLE_IPV6 + SOCK_IPV6 = 0x0100, ///< This is an ipv6 socket if this one is true + // ENABLE_POOL + SOCK_CLIENT = 0x0200, ///< only client connections are pooled + SOCK_RETAIN = 0x0400, ///< keep connection on close + SOCK_LOST = 0x0800, ///< connection lost + + // ENABLE_SOCKS4 + SOCK_SOCKS4 = 0x1000, ///< socks4 negotiation mode (TcpSocket) + // ENABLE_DETACH + SOCK_DETACH = 0x2000, ///< Socket ordered to detach flag + SOCK_DETACHED = 0x4000, ///< Socket has been detached + // StreamSocket + STREAMSOCK_CONNECTING = 0x8000, ///< Flag indicating connection in progress + + STREAMSOCK_FLUSH_BEFORE_CLOSE = 0x010000L, ///< Send all data before closing (default true) + STREAMSOCK_CALL_ON_CONNECT = 0x020000L, ///< OnConnect will be called next ISocketHandler cycle if true + STREAMSOCK_RETRY_CONNECT = 0x040000L, ///< Try another connection attempt next ISocketHandler cycle + STREAMSOCK_LINE_PROTOCOL = 0x080000L, ///< Line protocol mode flag + + }; +*/ + +public: + /** "Default" constructor */ + Socket(ISocketHandler&); + + virtual ~Socket(); + + /** Socket class instantiation method. Used when a "non-standard" constructor + * needs to be used for the socket class. Note: the socket class still needs + * the "default" constructor with one ISocketHandler& as input parameter. + */ + virtual Socket *Create() { return NULL; } + + /** Returns reference to sockethandler that owns the socket. + If the socket is detached, this is a reference to the slave sockethandler. + */ + ISocketHandler& Handler() const; + + /** Returns reference to sockethandler that owns the socket. + This one always returns the reference to the original sockethandler, + even if the socket is detached. + */ + ISocketHandler& MasterHandler() const; + + /** Called by ListenSocket after accept but before socket is added to handler. + * CTcpSocket uses this to create its ICrypt member variable. + * The ICrypt member variable is created by a virtual method, therefore + * it can't be called directly from the CTcpSocket constructor. + * Also used to determine if incoming HTTP connection is normal (port 80) + * or ssl (port 443). + */ + virtual void Init(); + + /** Create a socket file descriptor. + \param af Address family AF_INET / AF_INET6 / ... + \param type SOCK_STREAM / SOCK_DGRAM / ... + \param protocol "tcp" / "udp" / ... */ + SOCKET CreateSocket(int af,int type,const std::string& protocol = ""); + + /** Assign this socket a file descriptor created + by a call to socket() or otherwise. */ + void Attach(SOCKET s); + + /** Return file descriptor assigned to this socket. */ + SOCKET GetSocket(); + + /** Close connection immediately - internal use. + \sa SetCloseAndDelete */ + virtual int Close(); + + /** Add file descriptor to sockethandler fd_set's. */ + void Set(bool bRead,bool bWrite,bool bException = true); + + /** Returns true when socket file descriptor is valid + and socket is not about to be closed. */ + virtual bool Ready(); + + /** Returns pointer to ListenSocket that created this instance + * on an incoming connection. */ + Socket *GetParent(); + + /** Used by ListenSocket to set parent pointer of newly created + * socket instance. */ + void SetParent(Socket *); + + /** Get listening port from ListenSocket<>. */ + virtual port_t GetPort(); + + /** Set socket non-block operation. */ + bool SetNonblocking(bool); + + /** Set socket non-block operation. */ + bool SetNonblocking(bool, SOCKET); + + /** Total lifetime of instance. */ + time_t Uptime(); + + /** Set address/port of last connect() call. */ + void SetClientRemoteAddress(SocketAddress&); + + /** Get address/port of last connect() call. */ + std::auto_ptr GetClientRemoteAddress(); + + /** Common interface for SendBuf used by Tcp and Udp sockets. */ + virtual void SendBuf(const char *,size_t,int = 0); + + /** Common interface for Send used by Tcp and Udp sockets. */ + virtual void Send(const std::string&,int = 0); + + /** Outgoing traffic counter. */ + virtual uint64_t GetBytesSent(bool clear = false); + + /** Incoming traffic counter. */ + virtual uint64_t GetBytesReceived(bool clear = false); + + // LIST_TIMEOUT + + /** Enable timeout control. 0=disable timeout check. */ + void SetTimeout(time_t secs); + + /** Check timeout. \return true if time limit reached */ + bool Timeout(time_t tnow); + + /** Used by ListenSocket. ipv4 and ipv6 */ + void SetRemoteAddress(SocketAddress&); + + /** \name Event callbacks */ + //@{ + + /** Called when there is something to be read from the file descriptor. */ + virtual void OnRead(); + /** Called when there is room for another write on the file descriptor. */ + virtual void OnWrite(); + /** Called on socket exception. */ + virtual void OnException(); + /** Called before a socket class is deleted by the ISocketHandler. */ + virtual void OnDelete(); + /** Called when a connection has completed. */ + virtual void OnConnect(); + /** Called when an incoming connection has been completed. */ + virtual void OnAccept(); + /** Called when a complete line has been read and the socket is in + * line protocol mode. */ + virtual void OnLine(const std::string& ); + /** Called on connect timeout (5s). */ + virtual void OnConnectFailed(); + /** Called when a client socket is created, to set socket options. + \param family AF_INET, AF_INET6, etc + \param type SOCK_STREAM, SOCK_DGRAM, etc + \param protocol Protocol number (tcp, udp, sctp, etc) + \param s Socket file descriptor + */ + virtual void OnOptions(int family,int type,int protocol,SOCKET s) = 0; + /** Connection retry callback - return false to abort connection attempts */ + virtual bool OnConnectRetry(); +#ifdef ENABLE_RECONNECT + /** a reconnect has been made */ + virtual void OnReconnect(); +#endif + /** TcpSocket: When a disconnect has been detected (recv/SSL_read returns 0 bytes). */ + virtual void OnDisconnect(); + /** Timeout callback. */ + virtual void OnTimeout(); + /** Connection timeout. */ + virtual void OnConnectTimeout(); + //@} + + /** \name Socket mode flags, set/reset */ + //@{ + /** Set delete by handler true when you want the sockethandler to + delete the socket instance after use. */ + void SetDeleteByHandler(bool = true); + /** Check delete by handler flag. + \return true if this instance should be deleted by the sockethandler */ + bool DeleteByHandler(); + + // LIST_CLOSE - conditional event queue + + /** Set close and delete to terminate the connection. */ + void SetCloseAndDelete(bool = true); + /** Check close and delete flag. + \return true if this socket should be closed and the instance removed */ + bool CloseAndDelete(); + + /** Return number of seconds since socket was ordered to close. \sa SetCloseAndDelete */ + time_t TimeSinceClose(); + + /** Ignore read events for an output only socket. */ + void DisableRead(bool x = true); + /** Check ignore read events flag. + \return true if read events should be ignored */ + bool IsDisableRead(); + + /** Set connected status. */ + void SetConnected(bool = true); + /** Check connected status. + \return true if connected */ + bool IsConnected(); + + /** Connection lost - error while reading/writing from a socket - TcpSocket only. */ + void SetLost(); + /** Check connection lost status flag, used by TcpSocket only. + \return true if there was an error while r/w causing the socket to close */ + bool Lost(); + + /** Set flag indicating the socket is being actively deleted by the sockethandler. */ + void SetErasedByHandler(bool x = true); + /** Get value of flag indicating socket is deleted by sockethandler. */ + bool ErasedByHandler(); + + //@} + + /** \name Information about remote connection */ + //@{ + /** Returns address of remote end. */ + std::auto_ptr GetRemoteSocketAddress(); + /** Returns address of remote end: ipv4. */ + ipaddr_t GetRemoteIP4(); +#ifdef ENABLE_IPV6 + /** Returns address of remote end: ipv6. */ +#ifdef IPPROTO_IPV6 + struct in6_addr GetRemoteIP6(); +#endif +#endif + /** Returns remote port number: ipv4 and ipv6. */ + port_t GetRemotePort(); + /** Returns remote ip as string? ipv4 and ipv6. */ + std::string GetRemoteAddress(); + /** ipv4 and ipv6(not implemented) */ + std::string GetRemoteHostname(); + //@} + + /** Returns local port number for bound socket file descriptor. */ + port_t GetSockPort(); + /** Returns local ipv4 address for bound socket file descriptor. */ + ipaddr_t GetSockIP4(); + /** Returns local ipv4 address as text for bound socket file descriptor. */ + std::string GetSockAddress(); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Returns local ipv6 address for bound socket file descriptor. */ + struct in6_addr GetSockIP6(); + /** Returns local ipv6 address as text for bound socket file descriptor. */ + std::string GetSockAddress6(); +#endif +#endif + // -------------------------------------------------------------------------- + /** @name IP options + When an ip or socket option is available on all of the operating systems + I'm testing on (linux 2.4.x, _win32, macosx, solaris9 intel) they are not + checked with an #ifdef below. + This might cause a compile error on other operating systems. */ + // -------------------------------------------------------------------------- + + // IP options + //@{ + + bool SetIpOptions(const void *p, socklen_t len); + bool SetIpTOS(unsigned char tos); + unsigned char IpTOS(); + bool SetIpTTL(int ttl); + int IpTTL(); + bool SetIpHdrincl(bool x = true); + bool SetIpMulticastTTL(int); + int IpMulticastTTL(); + bool SetMulticastLoop(bool x = true); + bool IpAddMembership(struct ip_mreq&); + bool IpDropMembership(struct ip_mreq&); + +#ifdef IP_PKTINFO + bool SetIpPktinfo(bool x = true); +#endif +#ifdef IP_RECVTOS + bool SetIpRecvTOS(bool x = true); +#endif +#ifdef IP_RECVTTL + bool SetIpRecvTTL(bool x = true); +#endif +#ifdef IP_RECVOPTS + bool SetIpRecvopts(bool x = true); +#endif +#ifdef IP_RETOPTS + bool SetIpRetopts(bool x = true); +#endif +#ifdef IP_RECVERR + bool SetIpRecverr(bool x = true); +#endif +#ifdef IP_MTU_DISCOVER + bool SetIpMtudiscover(bool x = true); +#endif +#ifdef IP_MTU + int IpMtu(); +#endif +#ifdef IP_ROUTER_ALERT + bool SetIpRouterAlert(bool x = true); +#endif +#ifdef LINUX + bool IpAddMembership(struct ip_mreqn&); +#endif +#ifdef LINUX + bool IpDropMembership(struct ip_mreqn&); +#endif + //@} + + // SOCKET options + /** @name Socket Options */ + //@{ + + bool SoAcceptconn(); + bool SetSoBroadcast(bool x = true); + bool SetSoDebug(bool x = true); + int SoError(); + bool SetSoDontroute(bool x = true); + bool SetSoLinger(int onoff, int linger); + bool SetSoOobinline(bool x = true); + bool SetSoRcvlowat(int); + bool SetSoSndlowat(int); + bool SetSoRcvtimeo(struct timeval&); + bool SetSoSndtimeo(struct timeval&); + bool SetSoRcvbuf(int); + int SoRcvbuf(); + bool SetSoSndbuf(int); + int SoSndbuf(); + int SoType(); + bool SetSoReuseaddr(bool x = true); + bool SetSoKeepalive(bool x = true); + +#ifdef SO_BSDCOMPAT + bool SetSoBsdcompat(bool x = true); +#endif +#ifdef SO_BINDTODEVICE + bool SetSoBindtodevice(const std::string& intf); +#endif +#ifdef SO_PASSCRED + bool SetSoPasscred(bool x = true); +#endif +#ifdef SO_PEERCRED + bool SoPeercred(struct ucred& ); +#endif +#ifdef SO_PRIORITY + bool SetSoPriority(int); +#endif +#ifdef SO_RCVBUFFORCE + bool SetSoRcvbufforce(int); +#endif +#ifdef SO_SNDBUFFORCE + bool SetSoSndbufforce(int); +#endif +#ifdef SO_TIMESTAMP + bool SetSoTimestamp(bool x = true); +#endif +#ifdef SO_NOSIGPIPE + bool SetSoNosigpipe(bool x = true); +#endif + //@} + + // TCP options in TcpSocket.h/TcpSocket.cpp + + +#ifdef HAVE_OPENSSL + /** @name SSL Support */ + //@{ + /** SSL client/server support - internal use. \sa TcpSocket */ + virtual void OnSSLConnect(); + /** SSL client/server support - internal use. \sa TcpSocket */ + virtual void OnSSLAccept(); + /** SSL negotiation failed for client connect. */ + virtual void OnSSLConnectFailed(); + /** SSL negotiation failed for server accept. */ + virtual void OnSSLAcceptFailed(); + /** new SSL support */ + virtual bool SSLNegotiate(); + /** Check if SSL is Enabled for this TcpSocket. + \return true if this is a TcpSocket with SSL enabled */ + bool IsSSL(); + /** Enable SSL operation for a TcpSocket. */ + void EnableSSL(bool x = true); + /** Still negotiating ssl connection. + \return true if ssl negotiating is still in progress */ + bool IsSSLNegotiate(); + /** Set flag indicating ssl handshaking still in progress. */ + void SetSSLNegotiate(bool x = true); + /** OnAccept called with SSL Enabled. + \return true if this is a TcpSocket with an incoming SSL connection */ + bool IsSSLServer(); + /** Set flag indicating that this is a TcpSocket with incoming SSL connection. */ + void SetSSLServer(bool x = true); + /** SSL; Get pointer to ssl context structure. */ + virtual SSL_CTX *GetSslContext() { return NULL; } + /** SSL; Get pointer to ssl structure. */ + virtual SSL *GetSsl() { return NULL; } + //@} +#endif // HAVE_OPENSSL + +#ifdef ENABLE_IPV6 + /** Enable ipv6 for this socket. */ + void SetIpv6(bool x = true); + /** Check ipv6 socket. + \return true if this is an ipv6 socket */ + bool IsIpv6(); +#endif + +#ifdef ENABLE_POOL + /** @name Connection Pool */ + //@{ + /** Client = connecting TcpSocket. */ + void SetIsClient(); + /** Socket type from socket() call. */ + void SetSocketType(int x); + /** Socket type from socket() call. */ + int GetSocketType(); + /** Protocol type from socket() call. */ + void SetSocketProtocol(const std::string& x); + /** Protocol type from socket() call. */ + const std::string& GetSocketProtocol(); + /** Instruct a client socket to stay open in the connection pool after use. + If you have connected to a server using tcp, you can call SetRetain + to leave the connection open after your socket instance has been deleted. + The next connection you make to the same server will reuse the already + opened connection, if it is still available. + */ + void SetRetain(); + /** Check retain flag. + \return true if the socket should be moved to connection pool after use */ + bool Retain(); + /** Copy connection parameters from sock. */ + void CopyConnection(Socket *sock); + //@} +#endif // ENABLE_POOL + +#ifdef ENABLE_SOCKS4 + /** \name Socks4 support */ + //@{ + /** Socks4 client support internal use. \sa TcpSocket */ + virtual void OnSocks4Connect(); + /** Socks4 client support internal use. \sa TcpSocket */ + virtual void OnSocks4ConnectFailed(); + /** Socks4 client support internal use. \sa TcpSocket */ + virtual bool OnSocks4Read(); + /** Called when the last write caused the tcp output buffer to + * become empty. */ + /** socket still in socks4 negotiation mode */ + bool Socks4(); + /** Set flag indicating Socks4 handshaking in progress */ + void SetSocks4(bool x = true); + + /** Set socks4 server host address to use */ + void SetSocks4Host(ipaddr_t a); + /** Set socks4 server hostname to use. */ + void SetSocks4Host(const std::string& ); + /** Socks4 server port to use. */ + void SetSocks4Port(port_t p); + /** Provide a socks4 userid if required by the socks4 server. */ + void SetSocks4Userid(const std::string& x); + /** Get the ip address of socks4 server to use. + \return socks4 server host address */ + ipaddr_t GetSocks4Host(); + /** Get the socks4 server port to use. + \return socks4 server port */ + port_t GetSocks4Port(); + /** Get socks4 userid. + \return Socks4 userid */ + const std::string& GetSocks4Userid(); + //@} +#endif // ENABLE_SOCKS4 + +#ifdef ENABLE_RESOLVER + /** \name Asynchronous Resolver */ + //@{ + /** Request an asynchronous dns resolution. + \param host hostname to be resolved + \param port port number passed along for the ride + \return Resolve ID */ + int Resolve(const std::string& host,port_t port = 0); +#ifdef ENABLE_IPV6 + int Resolve6(const std::string& host, port_t port = 0); +#endif + /** Callback returning a resolved address. + \param id Resolve ID from Resolve call + \param a resolved ip address + \param port port number passed to Resolve */ + virtual void OnResolved(int id,ipaddr_t a,port_t port); +#ifdef ENABLE_IPV6 + virtual void OnResolved(int id,in6_addr& a,port_t port); +#endif + /** Request asynchronous reverse dns lookup. + \param a in_addr to be translated */ + int Resolve(ipaddr_t a); +#ifdef ENABLE_IPV6 + int Resolve(in6_addr& a); +#endif + /** Callback returning reverse resolve results. + \param id Resolve ID + \param name Resolved hostname */ + virtual void OnReverseResolved(int id,const std::string& name); + /** Callback indicating failed dns lookup. + \param id Resolve ID */ + virtual void OnResolveFailed(int id); + //@} +#endif // ENABLE_RESOLVER + +#ifdef ENABLE_DETACH + /** \name Thread Support */ + //@{ + /** Callback fires when a new socket thread has started and this + socket is ready for operation again. + \sa ResolvSocket */ + virtual void OnDetached(); + + // LIST_DETACH + + /** Internal use. */ + void SetDetach(bool x = true); + /** Check detach flag. + \return true if the socket should detach to its own thread */ + bool IsDetach(); + + /** Internal use. */ + void SetDetached(bool x = true); + /** Check detached flag. + \return true if the socket runs in its own thread. */ + const bool IsDetached() const; + /** Order this socket to start its own thread and call OnDetached + when ready for operation. */ + bool Detach(); + /** Store the slave sockethandler pointer. */ + void SetSlaveHandler(ISocketHandler *); + /** Create new thread for this socket to run detached in. */ + void DetachSocket(); + //@} +#endif // ENABLE_DETACH + + /** Write traffic to an IFile. Socket will not delete this object. */ + void SetTrafficMonitor(IFile *p) { m_traffic_monitor = p; } + +#ifdef ENABLE_TRIGGERS + /** \name Triggers */ + //@{ + /** Subscribe to trigger id. */ + void Subscribe(int id); + /** Unsubscribe from trigger id. */ + void Unsubscribe(int id); + /** Trigger callback, with data passed from source to destination. */ + virtual void OnTrigger(int id, const TriggerData& data); + /** Trigger cancelled because source has been deleted (as in delete). */ + virtual void OnCancelled(int id); + //@} +#endif + +protected: + /** default constructor not available */ + Socket() : m_handler(m_handler) {} + /** copy constructor not available */ + Socket(const Socket& s) : m_handler(s.m_handler) {} + + /** assignment operator not available. */ + Socket& operator=(const Socket& ) { return *this; } + + /** All traffic will be written to this IFile, if set. */ + IFile *GetTrafficMonitor() { return m_traffic_monitor; } + +// unsigned long m_flags; ///< boolean flags, replacing old 'bool' members + +private: + ISocketHandler& m_handler; ///< Reference of ISocketHandler in control of this socket + SOCKET m_socket; ///< File descriptor + bool m_bDel; ///< Delete by handler flag + bool m_bClose; ///< Close and delete flag + time_t m_tCreate; ///< Time in seconds when this socket was created + Socket *m_parent; ///< Pointer to ListenSocket class, valid for incoming sockets + bool m_b_disable_read; ///< Disable checking for read events + bool m_connected; ///< Socket is connected (tcp/udp) + bool m_b_erased_by_handler; ///< Set by handler before delete + time_t m_tClose; ///< Time in seconds when ordered to close + std::auto_ptr m_client_remote_address; ///< Address of last connect() + std::auto_ptr m_remote_address; ///< Remote end address + IFile *m_traffic_monitor; + time_t m_timeout_start; ///< Set by SetTimeout + time_t m_timeout_limit; ///< Defined by SetTimeout + bool m_bLost; ///< connection lost + +#ifdef _WIN32 +static WSAInitializer m_winsock_init; ///< Winsock initialization singleton class +#endif + +#ifdef HAVE_OPENSSL + bool m_b_enable_ssl; ///< Enable SSL for this TcpSocket + bool m_b_ssl; ///< ssl negotiation mode (TcpSocket) + bool m_b_ssl_server; ///< True if this is an incoming ssl TcpSocket connection +#endif + +#ifdef ENABLE_IPV6 + bool m_ipv6; ///< This is an ipv6 socket if this one is true +#endif + +#ifdef ENABLE_POOL + int m_socket_type; ///< Type of socket, from socket() call + std::string m_socket_protocol; ///< Protocol, from socket() call + bool m_bClient; ///< only client connections are pooled + bool m_bRetain; ///< keep connection on close +#endif + +#ifdef ENABLE_SOCKS4 + bool m_bSocks4; ///< socks4 negotiation mode (TcpSocket) + ipaddr_t m_socks4_host; ///< socks4 server address + port_t m_socks4_port; ///< socks4 server port number + std::string m_socks4_userid; ///< socks4 server usedid +#endif + +#ifdef ENABLE_DETACH + bool m_detach; ///< Socket ordered to detach flag + bool m_detached; ///< Socket has been detached + SocketThread *m_pThread; ///< Detach socket thread class pointer + ISocketHandler *m_slave_handler; ///< Actual sockethandler while detached +#endif +}; + +#ifdef SOCKETS_NAMESPACE +} +#endif + + +#endif // _SOCKETS_Socket_H + diff --git a/dep/include/sockets/SocketAddress.h b/dep/include/sockets/SocketAddress.h new file mode 100644 index 000000000..d5a56433b --- /dev/null +++ b/dep/include/sockets/SocketAddress.h @@ -0,0 +1,95 @@ +/** + ** \file SocketAddress.h + ** \date 2006-09-21 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_SocketAddress_H +#define _SOCKETS_SocketAddress_H + +#include "sockets-config.h" +#include +#include +#include "socket_include.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** + This class and its subclasses is intended to be used as replacement + for the internal data type 'ipaddr_t' and various implementations of + IPv6 addressing found throughout the library. + 'ipaddr_t' is an IPv4 address in network byte order. + 'port_t' is the portnumber in host byte order. + 'struct in6_addr' is an IPv6 address. + 'struct in_addr' is an IPv4 address. + \ingroup basic +*/ +class SocketAddress +{ +public: + virtual ~SocketAddress() {} + + /** Get a pointer to the address struct. */ + virtual operator struct sockaddr *() = 0; + + /** Get length of address struct. */ + virtual operator socklen_t() = 0; + + /** Compare two addresses. */ + virtual bool operator==(SocketAddress&) = 0; + + /** Set port number. + \param port Port number in host byte order */ + virtual void SetPort(port_t port) = 0; + + /** Get port number. + \return Port number in host byte order. */ + virtual port_t GetPort() = 0; + + /** Set socket address. + \param sa Pointer to either 'struct sockaddr_in' or 'struct sockaddr_in6'. */ + virtual void SetAddress(struct sockaddr *sa) = 0; + + /** Convert address to text. */ + virtual std::string Convert(bool include_port) = 0; + + /** Reverse lookup of address. */ + virtual std::string Reverse() = 0; + + /** Get address family. */ + virtual int GetFamily() = 0; + + /** Address structure is valid. */ + virtual bool IsValid() = 0; + + /** Get a copy of this SocketAddress object. */ + virtual std::auto_ptr GetCopy() = 0; +}; + + + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif +#endif // _SOCKETS_SocketAddress_H + diff --git a/dep/include/sockets/SocketHandler.h b/dep/include/sockets/SocketHandler.h new file mode 100644 index 000000000..c7e20dfde --- /dev/null +++ b/dep/include/sockets/SocketHandler.h @@ -0,0 +1,266 @@ +/** \file SocketHandler.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_SocketHandler_H +#define _SOCKETS_SocketHandler_H + +#include "sockets-config.h" +#include +#include + +#include "socket_include.h" +#include "ISocketHandler.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +class Socket; +#ifdef ENABLE_RESOLVER +class ResolvServer; +#endif +class Mutex; + +/** Socket container class, event generator. + \ingroup basic */ +class SocketHandler : public ISocketHandler +{ +protected: + /** Map type for holding file descriptors/socket object pointers. */ + typedef std::map socket_m; + +public: + /** SocketHandler constructor. + \param log Optional log class pointer */ + SocketHandler(StdLog *log = NULL); + + /** SocketHandler threadsafe constructor. + \param mutex Externally declared mutex variable + \param log Optional log class pointer */ + SocketHandler(Mutex& mutex,StdLog *log = NULL); + + ~SocketHandler(); + + /** Get mutex reference for threadsafe operations. */ + Mutex& GetMutex() const; + + /** Register StdLog object for error callback. + \param log Pointer to log class */ + void RegStdLog(StdLog *log); + + /** Log error to log class for print out / storage. */ + void LogError(Socket *p,const std::string& user_text,int err,const std::string& sys_err,loglevel_t t = LOG_LEVEL_WARNING); + + /** Add socket instance to socket map. Removal is always automatic. */ + void Add(Socket *); + + /** Get status of read/write/exception file descriptor set for a socket. */ + void Get(SOCKET s,bool& r,bool& w,bool& e); + + /** Set read/write/exception file descriptor sets (fd_set). */ + void Set(SOCKET s,bool bRead,bool bWrite,bool bException = true); + + /** Wait for events, generate callbacks. */ + int Select(long sec,long usec); + + /** This method will not return until an event has been detected. */ + int Select(); + + /** Wait for events, generate callbacks. */ + int Select(struct timeval *tsel); + + /** Check that a socket really is handled by this socket handler. */ + bool Valid(Socket *); + + /** Return number of sockets handled by this handler. */ + size_t GetCount(); + + /** Override and return false to deny all incoming connections. + \param p ListenSocket class pointer (use GetPort to identify which one) */ + bool OkToAccept(Socket *p); + + /** Called by Socket when a socket changes state. */ + void AddList(SOCKET s,list_t which_one,bool add); + + // Connection pool +#ifdef ENABLE_POOL + /** Find available open connection (used by connection pool). */ + ISocketHandler::PoolSocket *FindConnection(int type,const std::string& protocol,SocketAddress&); + /** Enable connection pool (by default disabled). */ + void EnablePool(bool x = true); + /** Check pool status. + \return true if connection pool is enabled */ + bool PoolEnabled(); +#endif // ENABLE_POOL + + // Socks4 +#ifdef ENABLE_SOCKS4 + /** Set socks4 server ip that all new tcp sockets should use. */ + void SetSocks4Host(ipaddr_t); + /** Set socks4 server hostname that all new tcp sockets should use. */ + void SetSocks4Host(const std::string& ); + /** Set socks4 server port number that all new tcp sockets should use. */ + void SetSocks4Port(port_t); + /** Set optional socks4 userid. */ + void SetSocks4Userid(const std::string& ); + /** If connection to socks4 server fails, immediately try direct connection to final host. */ + void SetSocks4TryDirect(bool x = true); + /** Get socks4 server ip. + \return socks4 server ip */ + ipaddr_t GetSocks4Host(); + /** Get socks4 port number. + \return socks4 port number */ + port_t GetSocks4Port(); + /** Get socks4 userid (optional). + \return socks4 userid */ + const std::string& GetSocks4Userid(); + /** Check status of socks4 try direct flag. + \return true if direct connection should be tried if connection to socks4 server fails */ + bool Socks4TryDirect(); +#endif // ENABLE_SOCKS4 + + // DNS resolve server +#ifdef ENABLE_RESOLVER + /** Enable asynchronous DNS. + \param port Listen port of asynchronous dns server */ + void EnableResolver(port_t port = 16667); + /** Check resolver status. + \return true if resolver is enabled */ + bool ResolverEnabled(); + /** Queue a dns request. + \param host Hostname to be resolved + \param port Port number will be echoed in Socket::OnResolved callback */ + int Resolve(Socket *,const std::string& host,port_t port); +#ifdef ENABLE_IPV6 + int Resolve6(Socket *,const std::string& host,port_t port); +#endif + /** Do a reverse dns lookup. */ + int Resolve(Socket *,ipaddr_t a); +#ifdef ENABLE_IPV6 + int Resolve(Socket *,in6_addr& a); +#endif + /** Get listen port of asynchronous dns server. */ + port_t GetResolverPort(); + /** Resolver thread ready for queries. */ + bool ResolverReady(); + /** Returns true if the socket is waiting for a resolve event. */ + bool Resolving(Socket *); +#endif // ENABLE_RESOLVER + +#ifdef ENABLE_TRIGGERS + /** Fetch unique trigger id. */ + int TriggerID(Socket *src); + /** Subscribe socket to trigger id. */ + bool Subscribe(int id, Socket *dst); + /** Unsubscribe socket from trigger id. */ + bool Unsubscribe(int id, Socket *dst); + /** Execute OnTrigger for subscribed sockets. + \param id Trigger ID + \param data Data passed from source to destination + \param erase Empty trigger id source and destination maps if 'true', + Leave them in place if 'false' - if a trigger should be called many times */ + void Trigger(int id, Socket::TriggerData& data, bool erase = true); +#endif // ENABLE_TRIGGERS + +#ifdef ENABLE_DETACH + /** Indicates that the handler runs under SocketThread. */ + void SetSlave(bool x = true); + /** Indicates that the handler runs under SocketThread. */ + bool IsSlave(); +#endif + + /** Sanity check of those accursed lists. */ + void CheckSanity(); + +protected: + socket_m m_sockets; ///< Active sockets map + socket_m m_add; ///< Sockets to be added to sockets map + std::list m_delete; ///< Sockets to be deleted (failed when Add) + +protected: + StdLog *m_stdlog; ///< Registered log class, or NULL + Mutex& m_mutex; ///< Thread safety mutex + bool m_b_use_mutex; ///< Mutex correctly initialized + +private: + void CheckList(socket_v&,const std::string&); ///< Used by CheckSanity + /** Remove socket from socket map, used by Socket class. */ + void Remove(Socket *); + SOCKET m_maxsock; ///< Highest file descriptor + 1 in active sockets list + fd_set m_rfds; ///< file descriptor set monitored for read events + fd_set m_wfds; ///< file descriptor set monitored for write events + fd_set m_efds; ///< file descriptor set monitored for exceptions + int m_preverror; ///< debug select() error + int m_errcnt; ///< debug select() error + time_t m_tlast; ///< timeout control + + // state lists + socket_v m_fds; ///< Active file descriptor list + socket_v m_fds_erase; ///< File descriptors that are to be erased from m_sockets + socket_v m_fds_callonconnect; ///< checklist CallOnConnect +#ifdef ENABLE_DETACH + socket_v m_fds_detach; ///< checklist Detach +#endif + socket_v m_fds_timeout; ///< checklist timeout + socket_v m_fds_retry; ///< checklist retry client connect + socket_v m_fds_close; ///< checklist close and delete + +#ifdef ENABLE_SOCKS4 + ipaddr_t m_socks4_host; ///< Socks4 server host ip + port_t m_socks4_port; ///< Socks4 server port number + std::string m_socks4_userid; ///< Socks4 userid + bool m_bTryDirect; ///< Try direct connection if socks4 server fails +#endif +#ifdef ENABLE_RESOLVER + int m_resolv_id; ///< Resolver id counter + ResolvServer *m_resolver; ///< Resolver thread pointer + port_t m_resolver_port; ///< Resolver listen port + std::map m_resolve_q; ///< resolve queue +#endif +#ifdef ENABLE_POOL + bool m_b_enable_pool; ///< Connection pool enabled if true +#endif +#ifdef ENABLE_TRIGGERS + int m_next_trigger_id; ///< Unique trigger id counter + std::map m_trigger_src; ///< mapping trigger id to source socket + std::map > m_trigger_dst; ///< mapping trigger id to destination sockets +#endif +#ifdef ENABLE_DETACH + bool m_slave; ///< Indicates that this is a ISocketHandler run in SocketThread +#endif +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_SocketHandler_H + diff --git a/dep/include/sockets/StdLog.h b/dep/include/sockets/StdLog.h new file mode 100644 index 000000000..c07037bbd --- /dev/null +++ b/dep/include/sockets/StdLog.h @@ -0,0 +1,74 @@ +/** \file StdLog.h + ** \date 2004-06-01 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_StdLog_H +#define _SOCKETS_StdLog_H + +#include "sockets-config.h" +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +/** error level enum. */ +typedef enum +{ + LOG_LEVEL_WARNING = 0, + LOG_LEVEL_ERROR, + LOG_LEVEL_FATAL, + LOG_LEVEL_INFO +} loglevel_t; + + +class ISocketHandler; +class Socket; + +/** \defgroup logging Log help classes */ +/** Log class interface. + \ingroup logging */ +class StdLog +{ +public: + virtual ~StdLog() {} + + virtual void error(ISocketHandler *,Socket *, + const std::string& user_text, + int err, + const std::string& sys_err, + loglevel_t = LOG_LEVEL_WARNING) = 0; +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_StdLog_H + diff --git a/dep/include/sockets/StdoutLog.h b/dep/include/sockets/StdoutLog.h new file mode 100644 index 000000000..5f96b340d --- /dev/null +++ b/dep/include/sockets/StdoutLog.h @@ -0,0 +1,57 @@ +/** \file StdoutLog.h + ** \date 2004-06-01 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_StdoutLog_H +#define _SOCKETS_StdoutLog_H + +#include "sockets-config.h" +#include "StdLog.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** StdLog implementation, logs to stdout. + \ingroup logging */ +class StdoutLog : public StdLog +{ +public: + void error(ISocketHandler *,Socket *,const std::string& call,int err,const std::string& sys_err,loglevel_t); +}; + + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_StdoutLog_H + diff --git a/dep/include/sockets/StreamSocket.h b/dep/include/sockets/StreamSocket.h new file mode 100644 index 000000000..3c248110b --- /dev/null +++ b/dep/include/sockets/StreamSocket.h @@ -0,0 +1,127 @@ +#ifndef _StreamSocket_H +#define _StreamSocket_H + +#include "Socket.h" + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/** SOCK_STREAM Socket base class. + \ingroup basic */ +class StreamSocket : public Socket +{ +public: + StreamSocket(ISocketHandler& ); + ~StreamSocket(); + + /** Socket should Check Connect on next write event from select(). */ + void SetConnecting(bool = true); + + /** Check connecting flag. + \return true if the socket is still trying to connect */ + bool Connecting(); + + /** Returns true when socket file descriptor is valid, + socket connection is established, and socket is not about to + be closed. */ + bool Ready(); + + /** Set timeout to use for connection attempt. + \param x Timeout in seconds */ + void SetConnectTimeout(int x); + + /** Return number of seconds to wait for a connection. + \return Connection timeout (seconds) */ + int GetConnectTimeout(); + + /** Set flush before close to make a tcp socket completely empty its + output buffer before closing the connection. */ + void SetFlushBeforeClose(bool = true); + + /** Check flush before status. + \return true if the socket should send all data before closing */ + bool GetFlushBeforeClose(); + + /** Define number of connection retries (tcp only). + n = 0 - no retry + n > 0 - number of retries + n = -1 - unlimited retries */ + void SetConnectionRetry(int n); + + /** Get number of maximum connection retries (tcp only). */ + int GetConnectionRetry(); + + /** Increase number of actual connection retries (tcp only). */ + void IncreaseConnectionRetries(); + + /** Get number of actual connection retries (tcp only). */ + int GetConnectionRetries(); + + /** Reset actual connection retries (tcp only). */ + void ResetConnectionRetries(); + + // LIST_CALLONCONNECT + + /** Instruct socket to call OnConnect callback next sockethandler cycle. */ + void SetCallOnConnect(bool x = true); + + /** Check call on connect flag. + \return true if OnConnect() should be called a.s.a.p */ + bool CallOnConnect(); + + // LIST_RETRY + + /** Set flag to initiate a connection attempt after a connection timeout. */ + void SetRetryClientConnect(bool x = true); + + /** Check if a connection attempt should be made. + \return true when another attempt should be made */ + bool RetryClientConnect(); + + /** Called after OnRead if socket is in line protocol mode. + \sa SetLineProtocol */ + /** Enable the OnLine callback. Do not create your own OnRead + * callback when using this. */ + virtual void SetLineProtocol(bool = true); + + /** Check line protocol mode. + \return true if socket is in line protocol mode */ + bool LineProtocol(); + + /** Set shutdown status. */ + void SetShutdown(int); + + /** Get shutdown status. */ + int GetShutdown(); + + /** Returns IPPROTO_TCP or IPPROTO_SCTP */ + virtual int Protocol() = 0; + +protected: + StreamSocket(const StreamSocket& ) {} // copy constructor + +private: + StreamSocket& operator=(const StreamSocket& ) { return *this; } // assignment operator + + bool m_bConnecting; ///< Flag indicating connection in progress + int m_connect_timeout; ///< Connection timeout (seconds) + bool m_flush_before_close; ///< Send all data before closing (default true) + int m_connection_retry; ///< Maximum connection retries (tcp) + int m_retries; ///< Actual number of connection retries (tcp) + bool m_call_on_connect; ///< OnConnect will be called next ISocketHandler cycle if true + bool m_b_retry_connect; ///< Try another connection attempt next ISocketHandler cycle + bool m_line_protocol; ///< Line protocol mode flag + int m_shutdown; ///< Shutdown status +}; + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif + + +#endif // _StreamSocket_H + diff --git a/dep/include/sockets/TcpSocket.h b/dep/include/sockets/TcpSocket.h new file mode 100644 index 000000000..515f5aa6c --- /dev/null +++ b/dep/include/sockets/TcpSocket.h @@ -0,0 +1,358 @@ +/** \file TcpSocket.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_TcpSocket_H +#define _SOCKETS_TcpSocket_H +#include "sockets-config.h" +#include "StreamSocket.h" +#ifdef HAVE_OPENSSL +#include +#include "SSLInitializer.h" +#endif + +#include + +#define TCP_BUFSIZE_READ 16400 +#define TCP_OUTPUT_CAPACITY 1024000 + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +class SocketAddress; + + +/** Socket implementation for TCP. + \ingroup basic */ +class TcpSocket : public StreamSocket +{ + /** \defgroup internal Internal utility */ +protected: + /** Buffer class containing one read/write circular buffer. + \ingroup internal */ + class CircularBuffer + { + public: + CircularBuffer(size_t size); + ~CircularBuffer(); + + /** append l bytes from p to buffer */ + bool Write(const char *p,size_t l); + /** copy l bytes from buffer to dest */ + bool Read(char *dest,size_t l); + /** copy l bytes from buffer to dest, dont touch buffer pointers */ + bool SoftRead(char *dest, size_t l); + /** skip l bytes from buffer */ + bool Remove(size_t l); + /** read l bytes from buffer, returns as string. */ + std::string ReadString(size_t l); + + /** total buffer length */ + size_t GetLength(); + /** pointer to circular buffer beginning */ + const char *GetStart(); + /** return number of bytes from circular buffer beginning to buffer physical end */ + size_t GetL(); + /** return free space in buffer, number of bytes until buffer overrun */ + size_t Space(); + + /** return total number of bytes written to this buffer, ever */ + unsigned long ByteCounter(bool clear = false); + + private: + CircularBuffer(const CircularBuffer& /*s*/) {} + CircularBuffer& operator=(const CircularBuffer& ) { return *this; } + char *buf; + size_t m_max; + size_t m_q; + size_t m_b; + size_t m_t; + unsigned long m_count; + }; + /** Output buffer struct. + \ingroup internal */ + struct OUTPUT { + OUTPUT() : _b(0), _t(0), _q(0) {} + OUTPUT(const char *buf, size_t len) : _b(0), _t(len), _q(len) { + memcpy(_buf, buf, len); + } + size_t Space() { + return TCP_OUTPUT_CAPACITY - _t; + } + void Add(const char *buf, size_t len) { + memcpy(_buf + _t, buf, len); + _t += len; + _q += len; + } + size_t Remove(size_t len) { + _b += len; + _q -= len; + return _q; + } + const char *Buf() { + return _buf + _b; + } + size_t Len() { + return _q; + } + size_t _b; + size_t _t; + size_t _q; + char _buf[TCP_OUTPUT_CAPACITY]; + }; + typedef std::list output_l; + +public: + /** Constructor with standard values on input/output buffers. */ + TcpSocket(ISocketHandler& ); + /** Constructor with custom values for i/o buffer. + \param h ISocketHandler reference + \param isize Input buffer size + \param osize Output buffer size */ + TcpSocket(ISocketHandler& h,size_t isize,size_t osize); + ~TcpSocket(); + + /** Open a connection to a remote server. + If you want your socket to connect to a server, + always call Open before Add'ing a socket to the sockethandler. + If not, the connection attempt will not be monitored by the + socket handler... + \param ip IP address + \param port Port number + \param skip_socks Do not use socks4 even if configured */ + bool Open(ipaddr_t ip,port_t port,bool skip_socks = false); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Open connection. + \param ip Ipv6 address + \param port Port number + \param skip_socks Do not use socks4 even if configured */ + bool Open(in6_addr ip,port_t port,bool skip_socks = false); +#endif +#endif + bool Open(SocketAddress&,bool skip_socks = false); + bool Open(SocketAddress&,SocketAddress& bind_address,bool skip_socks = false); + /** Open connection. + \param host Hostname + \param port Port number */ + bool Open(const std::string &host,port_t port); + + /** Connect timeout callback. */ + void OnConnectTimeout(); +#ifdef _WIN32 + /** Connection failed reported as exception on win32 */ + void OnException(); +#endif + + /** Close file descriptor - internal use only. + \sa SetCloseAndDelete */ + int Close(); + + /** Send a string. + \param s String to send + \param f Dummy flags -- not used */ + void Send(const std::string &s,int f = 0); + /** Send string using printf formatting. */ + void Sendf(const char *format, ...); + /** Send buffer of bytes. + \param buf Buffer pointer + \param len Length of data + \param f Dummy flags -- not used */ + void SendBuf(const char *buf,size_t len,int f = 0); + /** This callback is executed after a successful read from the socket. + \param buf Pointer to the data + \param len Length of the data */ + virtual void OnRawData(const char *buf,size_t len); + + /** Called when output buffer has been sent. + Note: Will only be called IF the output buffer has been used. + Send's that was successful without needing the output buffer + will not generate a call to this method. */ + virtual void OnWriteComplete(); + /** Number of bytes in input buffer. */ + size_t GetInputLength(); + /** Number of bytes in output buffer. */ + size_t GetOutputLength(); + + /** Callback fires when a socket in line protocol has read one full line. + \param line Line read */ + void OnLine(const std::string& line); + /** Get counter of number of bytes received. */ + uint64_t GetBytesReceived(bool clear = false); + /** Get counter of number of bytes sent. */ + uint64_t GetBytesSent(bool clear = false); + + /** Socks4 specific callback. */ + void OnSocks4Connect(); + /** Socks4 specific callback. */ + void OnSocks4ConnectFailed(); + /** Socks4 specific callback. + \return 'need_more' */ + bool OnSocks4Read(); + +#ifdef ENABLE_RESOLVER + /** Callback executed when resolver thread has finished a resolve request. */ + void OnResolved(int id,ipaddr_t a,port_t port); +#ifdef ENABLE_IPV6 + void OnResolved(int id,in6_addr& a,port_t port); +#endif +#endif +#ifdef HAVE_OPENSSL + /** Callback for 'New' ssl support - replaces SSLSocket. Internal use. */ + void OnSSLConnect(); + /** Callback for 'New' ssl support - replaces SSLSocket. Internal use. */ + void OnSSLAccept(); + /** This method must be implemented to initialize + the ssl context for an outgoing connection. */ + virtual void InitSSLClient(); + /** This method must be implemented to initialize + the ssl context for an incoming connection. */ + virtual void InitSSLServer(); +#endif + +#ifdef ENABLE_RECONNECT + /** Flag that says a broken connection will try to reconnect. */ + void SetReconnect(bool = true); + /** Check reconnect on lost connection flag status. */ + bool Reconnect(); + /** Flag to determine if a reconnect is in progress. */ + void SetIsReconnect(bool x = true); + /** Socket is reconnecting. */ + bool IsReconnect(); +#endif + + void DisableInputBuffer(bool = true); + + void OnOptions(int,int,int,SOCKET); + + void SetLineProtocol(bool = true); + + // TCP options + bool SetTcpNodelay(bool = true); + + virtual int Protocol(); + + /** Trigger limit for callback OnTransferLimit. */ + void SetTransferLimit(size_t sz); + /** This callback fires when the output buffer drops below the value + set by SetTransferLimit. Default: 0 (disabled). */ + virtual void OnTransferLimit(); + +protected: + TcpSocket(const TcpSocket& ); + void OnRead(); + void OnRead( char *buf, size_t n ); + void OnWrite(); +#ifdef HAVE_OPENSSL + /** SSL; Initialize ssl context for a client socket. + \param meth_in SSL method */ + void InitializeContext(const std::string& context, SSL_METHOD *meth_in = NULL); + /** SSL; Initialize ssl context for a server socket. + \param keyfile Combined private key/certificate file + \param password Password for private key + \param meth_in SSL method */ + void InitializeContext(const std::string& context, const std::string& keyfile, const std::string& password, SSL_METHOD *meth_in = NULL); + /** SSL; Initialize ssl context for a server socket. + \param certfile Separate certificate file + \param keyfile Combined private key/certificate file + \param password Password for private key + \param meth_in SSL method */ + void InitializeContext(const std::string& context, const std::string& certfile, const std::string& keyfile, const std::string& password, SSL_METHOD *meth_in = NULL); + /** SSL; Password callback method. */ +static int SSL_password_cb(char *buf,int num,int rwflag,void *userdata); + /** SSL; Get pointer to ssl context structure. */ + virtual SSL_CTX *GetSslContext(); + /** SSL; Get pointer to ssl structure. */ + virtual SSL *GetSsl(); + /** ssl; still negotiating connection. */ + bool SSLNegotiate(); + /** SSL; Get ssl password. */ + const std::string& GetPassword(); +#endif + + CircularBuffer ibuf; ///< Circular input buffer + +private: + TcpSocket& operator=(const TcpSocket& ) { return *this; } + + /** the actual send() */ + int TryWrite(const char *buf, size_t len); + /** add data to output buffer top */ + void Buffer(const char *buf, size_t len); + + // + bool m_b_input_buffer_disabled; + uint64_t m_bytes_sent; + uint64_t m_bytes_received; + bool m_skip_c; ///< Skip second char of CRLF or LFCR sequence in OnRead + char m_c; ///< First char in CRLF or LFCR sequence + std::string m_line; ///< Current line in line protocol mode +#ifdef SOCKETS_DYNAMIC_TEMP + char *m_buf; ///< temporary read buffer +#endif + output_l m_obuf; ///< output buffer + OUTPUT *m_obuf_top; ///< output buffer on top + size_t m_transfer_limit; + size_t m_output_length; + +#ifdef HAVE_OPENSSL +static SSLInitializer m_ssl_init; + SSL_CTX *m_ssl_ctx; ///< ssl context + SSL *m_ssl; ///< ssl 'socket' + BIO *m_sbio; ///< ssl bio + std::string m_password; ///< ssl password +#endif + +#ifdef ENABLE_SOCKS4 + int m_socks4_state; ///< socks4 support + char m_socks4_vn; ///< socks4 support, temporary variable + char m_socks4_cd; ///< socks4 support, temporary variable + unsigned short m_socks4_dstport; ///< socks4 support + unsigned long m_socks4_dstip; ///< socks4 support +#endif + +#ifdef ENABLE_RESOLVER + int m_resolver_id; ///< Resolver id (if any) for current Open call +#endif + +#ifdef ENABLE_RECONNECT + bool m_b_reconnect; ///< Reconnect on lost connection flag + bool m_b_is_reconnect; ///< Trying to reconnect +#endif + +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_TcpSocket_H + diff --git a/dep/include/sockets/Thread.h b/dep/include/sockets/Thread.h new file mode 100644 index 000000000..d784a1594 --- /dev/null +++ b/dep/include/sockets/Thread.h @@ -0,0 +1,100 @@ +/** \file Thread.h + ** \date 2004-10-30 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Thread_H +#define _SOCKETS_Thread_H + +#include "sockets-config.h" +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +#ifdef _WIN32 +// to be +//typedef DWORD threadfunc_t; +//typedef LPVOID threadparam_t; +//#define STDPREFIX WINAPI +typedef unsigned threadfunc_t; +typedef void * threadparam_t; +#define STDPREFIX __stdcall +#else +#include + +typedef void * threadfunc_t; +typedef void * threadparam_t; +#define STDPREFIX +#endif + +/** \defgroup threading Threading */ +/** Thread base class. +The Thread class is used by the resolver (ResolvServer) and running a detached socket (SocketThread). +When you know some processing will take a long time and will freeze up a socket, there is always the +possibility to call Detach() on that socket before starting the processing. +When the OnDetached() callback is later called the processing can continue, now in its own thread. + \ingroup threading */ +class Thread +{ +public: + Thread(bool release = true); + virtual ~Thread(); + + static threadfunc_t STDPREFIX StartThread(threadparam_t); + + virtual void Run() = 0; + + bool IsRunning(); + void SetRunning(bool x); + bool IsReleased(); + void SetRelease(bool x); + bool DeleteOnExit(); + void SetDeleteOnExit(bool x = true); + bool IsDestructor(); + +private: + Thread(const Thread& ) {} + Thread& operator=(const Thread& ) { return *this; } +#ifdef _WIN32 + HANDLE m_thread; + unsigned m_dwThreadId; +#else + pthread_t m_thread; +#endif + bool m_running; + bool m_release; + bool m_b_delete_on_exit; + bool m_b_destructor; +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_Thread_H + diff --git a/dep/include/sockets/UdpSocket.h b/dep/include/sockets/UdpSocket.h new file mode 100644 index 000000000..d32aabf67 --- /dev/null +++ b/dep/include/sockets/UdpSocket.h @@ -0,0 +1,215 @@ +/** \file UdpSocket.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_UdpSocket_H +#define _SOCKETS_UdpSocket_H + +#include "sockets-config.h" +#include "Socket.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +/** Socket implementation for UDP. + \ingroup basic */ +class UdpSocket : public Socket +{ +public: + /** Constructor. + \param h ISocketHandler reference + \param ibufsz Maximum size of receive message (extra bytes will be truncated) + \param ipv6 'true' if this is an ipv6 socket */ + UdpSocket(ISocketHandler& h,int ibufsz = 16384,bool ipv6 = false, int retries = 0); + ~UdpSocket(); + + /** Called when incoming data has been received. + \param buf Pointer to data + \param len Length of data + \param sa Pointer to sockaddr struct of sender + \param sa_len Length of sockaddr struct */ + virtual void OnRawData(const char *buf,size_t len,struct sockaddr *sa,socklen_t sa_len); + + /** Called when incoming data has been received and read timestamp is enabled. + \param buf Pointer to data + \param len Length of data + \param sa Pointer to sockaddr struct of sender + \param sa_len Length of sockaddr struct + \param ts Timestamp from message */ + virtual void OnRawData(const char *buf,size_t len,struct sockaddr *sa,socklen_t sa_len,struct timeval *ts); + + /** To receive incoming data, call Bind to setup an incoming port. + \param port Incoming port number + \param range Port range to try if ports already in use + \return 0 if bind succeeded */ + int Bind(port_t& port,int range = 1); + /** To receive data on a specific interface:port, use this. + \param intf Interface ip/hostname + \param port Port number + \param range Port range + \return 0 if bind succeeded */ + int Bind(const std::string& intf,port_t& port,int range = 1); + /** To receive data on a specific interface:port, use this. + \param a Ip address + \param port Port number + \param range Port range + \return 0 if bind succeeded */ + int Bind(ipaddr_t a,port_t& port,int range = 1); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** To receive data on a specific interface:port, use this. + \param a Ipv6 address + \param port Port number + \param range Port range + \return 0 if bind succeeded */ + int Bind(in6_addr a,port_t& port,int range = 1); +#endif +#endif + /** To receive data on a specific interface:port, use this. + \param ad Socket address + \param range Port range + \return 0 if bind succeeded */ + int Bind(SocketAddress& ad,int range = 1); + + /** Define remote host. + \param l Address of remote host + \param port Port of remote host + \return true if successful */ + bool Open(ipaddr_t l,port_t port); + /** Define remote host. + \param host Hostname + \param port Port number + \return true if successful */ + bool Open(const std::string& host,port_t port); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Define remote host. + \param a Address of remote host, ipv6 + \param port Port of remote host + \return true if successful */ + bool Open(struct in6_addr& a,port_t port); +#endif +#endif + /** Define remote host. + \param ad Socket address + \return true if successful */ + bool Open(SocketAddress& ad); + + /** Send to specified host */ + void SendToBuf(const std::string& ,port_t,const char *data,int len,int flags = 0); + /** Send to specified address */ + void SendToBuf(ipaddr_t,port_t,const char *data,int len,int flags = 0); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Send to specified ipv6 address */ + void SendToBuf(in6_addr,port_t,const char *data,int len,int flags = 0); +#endif +#endif + /** Send to specified socket address */ + void SendToBuf(SocketAddress& ad,const char *data,int len,int flags = 0); + + /** Send string to specified host */ + void SendTo(const std::string&,port_t,const std::string&,int flags = 0); + /** Send string to specified address */ + void SendTo(ipaddr_t,port_t,const std::string&,int flags = 0); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Send string to specified ipv6 address */ + void SendTo(in6_addr,port_t,const std::string&,int flags = 0); +#endif +#endif + /** Send string to specified socket address */ + void SendTo(SocketAddress& ad,const std::string&,int flags = 0); + + /** Send to connected address */ + void SendBuf(const char *data,size_t,int flags = 0); + /** Send string to connected address. */ + void Send(const std::string& ,int flags = 0); + + /** Set broadcast */ + void SetBroadcast(bool b = true); + /** Check broadcast flag. + \return true broadcast is enabled. */ + bool IsBroadcast(); + + /** multicast */ + void SetMulticastTTL(int ttl = 1); + int GetMulticastTTL(); + void SetMulticastLoop(bool = true); + bool IsMulticastLoop(); + void AddMulticastMembership(const std::string& group,const std::string& intf = "0.0.0.0",int if_index = 0); + void DropMulticastMembership(const std::string& group,const std::string& intf = "0.0.0.0",int if_index = 0); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** multicast, ipv6 only */ + void SetMulticastHops(int = -1); + /** multicast, ipv6 only */ + int GetMulticastHops(); +#endif +#endif + /** Returns true if Bind succeeded. */ + bool IsBound(); + /** Return Bind port number */ + port_t GetPort(); + + void OnOptions(int,int,int,SOCKET) {} + + int GetLastSizeWritten(); + + /** Also read timestamp information from incoming message */ + void SetTimestamp(bool = true); + +protected: + UdpSocket(const UdpSocket& s) : Socket(s) {} + void OnRead(); +#if defined(LINUX) || defined(MACOSX) + /** This method emulates socket recvfrom, but uses messages so we can get the timestamp */ + int ReadTS(char *ioBuf, int inBufSize, struct sockaddr *from, socklen_t fromlen, struct timeval *ts); +#endif + +private: + UdpSocket& operator=(const UdpSocket& ) { return *this; } + /** create before using sendto methods */ + void CreateConnection(); + char *m_ibuf; ///< Input buffer + int m_ibufsz; ///< Size of input buffer + bool m_bind_ok; ///< Bind completed successfully + port_t m_port; ///< Bind port number + int m_last_size_written; + int m_retries; + bool m_b_read_ts; +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_UdpSocket_H + diff --git a/dep/include/sockets/Utility.h b/dep/include/sockets/Utility.h new file mode 100644 index 000000000..0fbccd3df --- /dev/null +++ b/dep/include/sockets/Utility.h @@ -0,0 +1,186 @@ +/** \file Utility.h + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_Utility_H +#define _SOCKETS_Utility_H + +#include "sockets-config.h" +#include +#include +#include +#include "socket_include.h" +#include +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +#define TWIST_LEN 624 + +class SocketAddress; + +/** Conversion utilities. + \ingroup util */ +class Utility +{ + /** + The Mersenne Twister + http://www.math.keio.ac.jp/~matumoto/emt.html + */ + class Rng { + public: + Rng(unsigned long seed); + + unsigned long Get(); + + private: + int m_value; + unsigned long m_tmp[TWIST_LEN]; + }; + class ncmap_compare { + public: + bool operator()(const std::string& x, const std::string& y) const { + return strcasecmp(x.c_str(), y.c_str()) < 0; + } + }; +public: + template class ncmap : public std::map { + public: + ncmap() {} + }; +public: + static std::string base64(const std::string& str_in); + static std::string base64d(const std::string& str_in); + static std::string l2string(long l); + static std::string bigint2string(uint64_t l); + static uint64_t atoi64(const std::string& str); + static unsigned int hex2unsigned(const std::string& str); + static std::string rfc1738_encode(const std::string& src); + static std::string rfc1738_decode(const std::string& src); + + /** Checks whether a string is a valid ipv4/ipv6 ip number. */ + static bool isipv4(const std::string&); + /** Checks whether a string is a valid ipv4/ipv6 ip number. */ + static bool isipv6(const std::string&); + + /** Hostname to ip resolution ipv4, not asynchronous. */ + static bool u2ip(const std::string&, ipaddr_t&); + static bool u2ip(const std::string&, struct sockaddr_in& sa, int ai_flags = 0); + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Hostname to ip resolution ipv6, not asynchronous. */ + static bool u2ip(const std::string&, struct in6_addr&); + static bool u2ip(const std::string&, struct sockaddr_in6& sa, int ai_flags = 0); +#endif +#endif + + /** Reverse lookup of address to hostname */ + static bool reverse(struct sockaddr *sa, socklen_t sa_len, std::string&, int flags = 0); + static bool reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, std::string& service, int flags = 0); + + static bool u2service(const std::string& name, int& service, int ai_flags = 0); + + /** Convert binary ip address to string: ipv4. */ + static void l2ip(const ipaddr_t,std::string& ); + static void l2ip(const in_addr&,std::string& ); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Convert binary ip address to string: ipv6. */ + static void l2ip(const struct in6_addr&,std::string& ,bool mixed = false); + + /** ipv6 address compare. */ + static int in6_addr_compare(in6_addr,in6_addr); +#endif +#endif + /** ResolveLocal (hostname) - call once before calling any GetLocal method. */ + static void ResolveLocal(); + /** Returns local hostname, ResolveLocal must be called once before using. + \sa ResolveLocal */ + static const std::string& GetLocalHostname(); + /** Returns local ip, ResolveLocal must be called once before using. + \sa ResolveLocal */ + static ipaddr_t GetLocalIP(); + /** Returns local ip number as string. + \sa ResolveLocal */ + static const std::string& GetLocalAddress(); +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + /** Returns local ipv6 ip. + \sa ResolveLocal */ + static const struct in6_addr& GetLocalIP6(); + /** Returns local ipv6 address. + \sa ResolveLocal */ + static const std::string& GetLocalAddress6(); +#endif +#endif + /** Set environment variable. + \param var Name of variable to set + \param value Value */ + static void SetEnv(const std::string& var,const std::string& value); + /** Convert sockaddr struct to human readable string. + \param sa Ptr to sockaddr struct */ + static std::string Sa2String(struct sockaddr *sa); + + /** Get current time in sec/microseconds. */ + static void GetTime(struct timeval *); + + static std::auto_ptr CreateAddress(struct sockaddr *,socklen_t); + + static unsigned long ThreadID(); + + static std::string ToLower(const std::string& str); + static std::string ToUpper(const std::string& str); + + static std::string ToString(double d); + + /** Returns a random 32-bit integer */ + static unsigned long Rnd(); + +private: + static std::string m_host; ///< local hostname + static ipaddr_t m_ip; ///< local ip address + static std::string m_addr; ///< local ip address in string format +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + static struct in6_addr m_local_ip6; ///< local ipv6 address +#endif + static std::string m_local_addr6; ///< local ipv6 address in string format +#endif + static bool m_local_resolved; ///< ResolveLocal has been called if true +}; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // _SOCKETS_Utility_H + diff --git a/dep/include/sockets/socket_include.h b/dep/include/sockets/socket_include.h new file mode 100644 index 000000000..34e7a8ca5 --- /dev/null +++ b/dep/include/sockets/socket_include.h @@ -0,0 +1,299 @@ +/** \file socket_include.h + ** \date 2005-04-12 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_socket_include_H +#define _SOCKETS_socket_include_H +#include "sockets-config.h" + +#ifdef _MSC_VER +#pragma warning(disable:4514) +#endif + +// common defines affecting library and applications using library + +/* Define SOCKETS_DYNAMIC_TEMP to use dynamically allocated buffers + in read operations - helps on ECOS */ +#define SOCKETS_DYNAMIC_TEMP + + +// platform specific stuff +#if (defined(__unix__) || defined(unix)) && !defined(USG) +#include +#endif +#include + +// int64 +#ifdef _WIN32 +typedef unsigned __int64 uint64_t; +#else +#include +#ifdef SOLARIS +# include +#else +# include +#endif +#endif + +#ifndef _WIN32 +// ---------------------------------------- +// common unix includes / defines +#include +#include +#include +#include +#include +#include +//#include + +// all typedefs in this file will be declared outside the sockets namespace, +// because some os's will already have one or more of the type defined. +typedef int SOCKET; +#define Errno errno +#define StrError strerror + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +// WIN32 adapt +#define closesocket close +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 + +#ifndef INADDR_NONE +#define INADDR_NONE ((unsigned long) -1) +#endif // INADDR_NONE + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // !_WIN32 + + +// ---------------------------------------- +// Generic +#ifndef SOL_IP +#define SOL_IP IPPROTO_IP +#endif + + +// ---------------------------------------- +// OS specific adaptions + +#ifdef SOLARIS +// ---------------------------------------- +// Solaris +typedef unsigned short port_t; +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif +// no defs + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#define s6_addr16 _S6_un._S6_u8 +#define MSG_NOSIGNAL 0 + +#elif defined __FreeBSD__ +// ---------------------------------------- +// FreeBSD +# if __FreeBSD_version >= 400014 +# define s6_addr16 __u6_addr.__u6_addr16 +# if !defined(MSG_NOSIGNAL) +# define MSG_NOSIGNAL 0 +# endif +# include +typedef in_addr_t ipaddr_t; +typedef in_port_t port_t; +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif +// no defs + +#ifdef SOCKETS_NAMESPACE +} +#endif + +# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +# else +# error FreeBSD versions prior to 400014 does not support ipv6 +# endif + +#elif defined __NetBSD__ +# if !defined(MSG_NOSIGNAL) +# define MSG_NOSIGNAL 0 +# endif +# include +typedef in_addr_t ipaddr_t; +typedef in_port_t port_t; +#elif defined MACOSX +// ---------------------------------------- +// Mac OS X +#include +#ifdef __DARWIN_UNIX03 +typedef unsigned short port_t; +#else +#include +#endif // __DARWIN_UNIX03 +typedef unsigned long ipaddr_t; +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif +// no defs + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#define s6_addr16 __u6_addr.__u6_addr16 +#define MSG_NOSIGNAL 0 // oops - thanks Derek +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP + +#elif defined _WIN32 +// ---------------------------------------- +// Win32 +#ifdef _MSC_VER +#pragma comment(lib, "wsock32.lib") +#endif +#define strcasecmp _stricmp + +typedef unsigned long ipaddr_t; +typedef unsigned short port_t; +typedef int socklen_t; +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif +// no defs + +#ifdef SOCKETS_NAMESPACE +} +#endif + +// 1.8.6: define FD_SETSIZE to something bigger than 64 if there are a lot of +// simultaneous connections (must be done before including winsock.h) +#define FD_SETSIZE 1024 + +// windows 2000 with ipv6 preview installed: +// http://msdn.microsoft.com/downloads/sdks/platform/tpipv6.asp +// see the FAQ on how to install +#define WIN32_LEAN_AND_MEAN +#include +#include +#if _MSC_VER < 1200 +#ifndef __CYGWIN__ +#ifdef ENABLE_IPV6 +#include // For IPv6 Tech Preview. +#endif +#endif +#endif // _MSC_VER < 1200 + + +#define MSG_NOSIGNAL 0 +//#define SHUT_RDWR 2 +#define SHUT_WR 1 + +#define Errno WSAGetLastError() +const char *StrError(int x); + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +// class WSAInitializer is a part of the Socket class (on win32) +// as a static instance - so whenever an application uses a Socket, +// winsock is initialized +class WSAInitializer // Winsock Initializer +{ +public: + WSAInitializer() { + if (WSAStartup(0x101,&m_wsadata)) + { + exit(-1); + } + } + ~WSAInitializer() { + WSACleanup(); + } +private: + WSADATA m_wsadata; +}; + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#else +// ---------------------------------------- +// LINUX +typedef unsigned long ipaddr_t; +typedef unsigned short port_t; +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif +// no defs + +#ifdef SOCKETS_NAMESPACE +} +#endif + + +#endif + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + /** List type containing file descriptors. */ + typedef std::list socket_v; + + +#ifdef SOCKETS_NAMESPACE +} +#endif + + +// getaddrinfo / getnameinfo replacements +#ifdef NO_GETADDRINFO +#ifndef AI_NUMERICHOST +#define AI_NUMERICHOST 1 +#endif +#ifndef NI_NUMERICHOST +#define NI_NUMERICHOST 1 +#endif +#endif + + +#endif // _SOCKETS_socket_include_H + diff --git a/dep/include/sockets/sockets-config.h b/dep/include/sockets/sockets-config.h new file mode 100644 index 000000000..fffc2bbe7 --- /dev/null +++ b/dep/include/sockets/sockets-config.h @@ -0,0 +1,101 @@ +/** + ** \file sockets-config.h + ** \date 2007-04-14 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef _SOCKETS_CONFIG_H +#define _SOCKETS_CONFIG_H + +#ifndef _RUN_DP +/* First undefine symbols if already defined. */ +#undef HAVE_OPENSSL +#undef ENABLE_IPV6 +#undef USE_SCTP +#undef NO_GETADDRINFO +#undef ENABLE_POOL +#undef ENABLE_SOCKS4 +#undef ENABLE_RESOLVER +#undef ENABLE_RECONNECT +#undef ENABLE_DETACH +#undef ENABLE_TRIGGERS +#undef ENABLE_EXCEPTIONS +#endif // _RUN_DP + +// define MACOSX for internal socket library checks +#if defined(__APPLE__) && defined(__MACH__) && !defined(MACOSX) +#define MACOSX +#endif + +/* OpenSSL support. */ +//#define HAVE_OPENSSL + + +/* Ipv6 support. */ +//#define ENABLE_IPV6 + + +/* SCTP support. */ +//#define USE_SCTP + + +/* Define NO_GETADDRINFO if your operating system does not support + the "getaddrinfo" and "getnameinfo" function calls. */ +#define NO_GETADDRINFO + + +/* Connection pool support. */ +#define ENABLE_POOL + + +/* Socks4 client support. */ +//#define ENABLE_SOCKS4 + + +/* Asynchronous resolver. */ +#define ENABLE_RESOLVER + + +/* Enable TCP reconnect on lost connection. + Socket::OnReconnect + Socket::OnDisconnect +*/ +#define ENABLE_RECONNECT + + +/* Enable socket thread detach functionality. */ +#define ENABLE_DETACH + + +/* Enable socket to socket triggers. Not yet in use. */ +//#define ENABLE_TRIGGERS + + +/* Enabled exceptions. */ +//#define ENABLE_EXCEPTIONS + + +/* Resolver uses the detach function so either enable both or disable both. */ +#ifndef ENABLE_DETACH +#undef ENABLE_RESOLVER +#endif + + +#endif // _SOCKETS_CONFIG_H + diff --git a/dep/include/sqlite/sqlite.h b/dep/include/sqlite/sqlite.h new file mode 100644 index 000000000..f9690d058 --- /dev/null +++ b/dep/include/sqlite/sqlite.h @@ -0,0 +1,834 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. +** +** @(#) $Id: sqlite.h,v 1.3 2004/06/29 01:57:36 silent Exp $ +*/ +#ifndef _SQLITE_H_ +#define _SQLITE_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +/* +** The version of the SQLite library. +*/ +#define SQLITE_VERSION "2.8.13" + +/* +** The version string is also compiled into the library so that a program +** can check to make sure that the lib*.a file and the *.h file are from +** the same version. +*/ +extern const char sqlite_version[]; + +/* +** The SQLITE_UTF8 macro is defined if the library expects to see +** UTF-8 encoded data. The SQLITE_ISO8859 macro is defined if the +** iso8859 encoded should be used. +*/ +#define SQLITE_ISO8859 1 + +/* +** The following constant holds one of two strings, "UTF-8" or "iso8859", +** depending on which character encoding the SQLite library expects to +** see. The character encoding makes a difference for the LIKE and GLOB +** operators and for the LENGTH() and SUBSTR() functions. +*/ +extern const char sqlite_encoding[]; + +/* +** Each open sqlite database is represented by an instance of the +** following opaque structure. +*/ +typedef struct sqlite sqlite; + +/* +** A function to open a new sqlite database. +** +** If the database does not exist and mode indicates write +** permission, then a new database is created. If the database +** does not exist and mode does not indicate write permission, +** then the open fails, an error message generated (if errmsg!=0) +** and the function returns 0. +** +** If mode does not indicates user write permission, then the +** database is opened read-only. +** +** The Truth: As currently implemented, all databases are opened +** for writing all the time. Maybe someday we will provide the +** ability to open a database readonly. The mode parameters is +** provided in anticipation of that enhancement. +*/ +sqlite *sqlite_open(const char *filename, int mode, char **errmsg); + +/* +** A function to close the database. +** +** Call this function with a pointer to a structure that was previously +** returned from sqlite_open() and the corresponding database will by closed. +*/ +void sqlite_close(sqlite *); + +/* +** The type for a callback function. +*/ +typedef int (*sqlite_callback)(void*,int,char**, char**); + +/* +** A function to executes one or more statements of SQL. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite_exec() function returns the SQLITE_ABORT. +** +** The 4th parameter is an arbitrary pointer that is passed +** to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column. +** The 4th parameter to the callback is an array of strings holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from malloc() and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory that holds the error +** message. Use sqlite_freemem() for this. If errmsg==NULL, +** then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other return code if there is an error. The particular +** return value depends on the type of error. +** +** If the query could not be executed because a database file is +** locked or busy, then this function returns SQLITE_BUSY. (This +** behavior can be modified somewhat using the sqlite_busy_handler() +** and sqlite_busy_timeout() functions below.) +*/ +int sqlite_exec( + sqlite*, /* An open database */ + const char *sql, /* SQL to be executed */ + sqlite_callback, /* Callback function */ + void *, /* 1st argument to callback function */ + char **errmsg /* Error msg written here */ +); + +/* +** Return values for sqlite_exec() and sqlite_step() +*/ +#define SQLITE_OK 0 /* Successful result */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ +#define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ +#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite_step() has finished executing */ + +/* +** Each entry in an SQLite table has a unique integer key. (The key is +** the value of the INTEGER PRIMARY KEY column if there is such a column, +** otherwise the key is generated at random. The unique key is always +** available as the ROWID, OID, or _ROWID_ column.) The following routine +** returns the integer key of the most recent insert in the database. +** +** This function is similar to the mysql_insert_id() function from MySQL. +*/ +int sqlite_last_insert_rowid(sqlite*); + +/* +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent called sqlite_exec(). +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes sqlite_exec() recursively, then the changes +** in the inner, recursive call are counted together with the changes +** in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +*/ +int sqlite_changes(sqlite*); + +/* +** This function returns the number of database rows that were changed +** by the last INSERT, UPDATE, or DELETE statment executed by sqlite_exec(), +** or by the last VM to run to completion. The change count is not updated +** by SQL statements other than INSERT, UPDATE or DELETE. +** +** Changes are counted, even if they are later undone by a ROLLBACK or +** ABORT. Changes associated with trigger programs that execute as a +** result of the INSERT, UPDATE, or DELETE statement are not counted. +** +** If a callback invokes sqlite_exec() recursively, then the changes +** in the inner, recursive call are counted together with the changes +** in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite_last_statement_changes(sqlite*); + +/* If the parameter to this routine is one of the return value constants +** defined above, then this routine returns a constant text string which +** descripts (in English) the meaning of the return value. +*/ +const char *sqlite_error_string(int); +#define sqliteErrStr sqlite_error_string /* Legacy. Do not use in new code. */ + +/* This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +*/ +void sqlite_interrupt(sqlite*); + + +/* This function returns true if the given input string comprises +** one or more complete SQL statements. +** +** The algorithm is simple. If the last token other than spaces +** and comments is a semicolon, then return true. otherwise return +** false. +*/ +int sqlite_complete(const char *sql); + +/* +** This routine identifies a callback function that is invoked +** whenever an attempt is made to open a database table that is +** currently locked by another process or thread. If the busy callback +** is NULL, then sqlite_exec() returns SQLITE_BUSY immediately if +** it finds a locked table. If the busy callback is not NULL, then +** sqlite_exec() invokes the callback with three arguments. The +** second argument is the name of the locked table and the third +** argument is the number of times the table has been busy. If the +** busy callback returns 0, then sqlite_exec() immediately returns +** SQLITE_BUSY. If the callback returns non-zero, then sqlite_exec() +** tries to open the table again and the cycle repeats. +** +** The default busy callback is NULL. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a coredump. +*/ +void sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*); + +/* +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milleseconds of sleeping have been done. After +** "ms" milleseconds of sleeping, the handler returns 0 which +** causes sqlite_exec() to return SQLITE_BUSY. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +*/ +void sqlite_busy_timeout(sqlite*, int ms); + +/* +** This next routine is really just a wrapper around sqlite_exec(). +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from malloc(), then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** malloc() happens, the calling function must not try to call +** malloc() directly. Only sqlite_free_table() is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from sqlite_exec(). +*/ +int sqlite_get_table( + sqlite*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); + +/* +** Call this routine to free the memory that sqlite_get_table() allocated. +*/ +void sqlite_free_table(char **result); + +/* +** The following routines are wrappers around sqlite_exec() and +** sqlite_get_table(). The only difference between the routines that +** follow and the originals is that the second argument to the +** routines that follow is really a printf()-style format +** string describing the SQL to be executed. Arguments to the format +** string appear at the end of the argument list. +** +** All of the usual printf formatting options apply. In addition, there +** is a "%q" option. %q works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** char *zText = "It's a happy day!"; +** +** We can use this text in an SQL statement as follows: +** +** sqlite_exec_printf(db, "INSERT INTO table VALUES('%q')", +** callback1, 0, 0, zText); +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** INSERT INTO table1 VALUES('It''s a happy day!') +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** INSERT INTO table1 VALUES('It's a happy day!'); +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +*/ +int sqlite_exec_printf( + sqlite*, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + sqlite_callback, /* Callback function */ + void *, /* 1st argument to callback function */ + char **errmsg, /* Error msg written here */ + ... /* Arguments to the format string. */ +); +int sqlite_exec_vprintf( + sqlite*, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + sqlite_callback, /* Callback function */ + void *, /* 1st argument to callback function */ + char **errmsg, /* Error msg written here */ + va_list ap /* Arguments to the format string. */ +); +int sqlite_get_table_printf( + sqlite*, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg, /* Error msg written here */ + ... /* Arguments to the format string */ +); +int sqlite_get_table_vprintf( + sqlite*, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg, /* Error msg written here */ + va_list ap /* Arguments to the format string */ +); +char *sqlite_mprintf(const char*,...); +char *sqlite_vmprintf(const char*, va_list); + +/* +** Windows systems should call this routine to free memory that +** is returned in the in the errmsg parameter of sqlite_open() when +** SQLite is a DLL. For some reason, it does not work to call free() +** directly. +*/ +void sqlite_freemem(void *p); + +/* +** Windows systems need functions to call to return the sqlite_version +** and sqlite_encoding strings. +*/ +const char *sqlite_libversion(void); +const char *sqlite_libencoding(void); + +/* +** A pointer to the following structure is used to communicate with +** the implementations of user-defined functions. +*/ +typedef struct sqlite_func sqlite_func; + +/* +** Use the following routines to create new user-defined functions. See +** the documentation for details. +*/ +int sqlite_create_function( + sqlite*, /* Database where the new function is registered */ + const char *zName, /* Name of the new function */ + int nArg, /* Number of arguments. -1 means any number */ + void (*xFunc)(sqlite_func*,int,const char**), /* C code to implement */ + void *pUserData /* Available via the sqlite_user_data() call */ +); +int sqlite_create_aggregate( + sqlite*, /* Database where the new function is registered */ + const char *zName, /* Name of the function */ + int nArg, /* Number of arguments */ + void (*xStep)(sqlite_func*,int,const char**), /* Called for each row */ + void (*xFinalize)(sqlite_func*), /* Called once to get final result */ + void *pUserData /* Available via the sqlite_user_data() call */ +); + +/* +** Use the following routine to define the datatype returned by a +** user-defined function. The second argument can be one of the +** constants SQLITE_NUMERIC, SQLITE_TEXT, or SQLITE_ARGS or it +** can be an integer greater than or equal to zero. When the datatype +** parameter is non-negative, the type of the result will be the +** same as the datatype-th argument. If datatype==SQLITE_NUMERIC +** then the result is always numeric. If datatype==SQLITE_TEXT then +** the result is always text. If datatype==SQLITE_ARGS then the result +** is numeric if any argument is numeric and is text otherwise. +*/ +int sqlite_function_type( + sqlite *db, /* The database there the function is registered */ + const char *zName, /* Name of the function */ + int datatype /* The datatype for this function */ +); +#define SQLITE_NUMERIC (-1) +#define SQLITE_TEXT (-2) +#define SQLITE_ARGS (-3) + +/* +** The user function implementations call one of the following four routines +** in order to return their results. The first parameter to each of these +** routines is a copy of the first argument to xFunc() or xFinialize(). +** The second parameter to these routines is the result to be returned. +** A NULL can be passed as the second parameter to sqlite_set_result_string() +** in order to return a NULL result. +** +** The 3rd argument to _string and _error is the number of characters to +** take from the string. If this argument is negative, then all characters +** up to and including the first '\000' are used. +** +** The sqlite_set_result_string() function allocates a buffer to hold the +** result and returns a pointer to this buffer. The calling routine +** (that is, the implmentation of a user function) can alter the content +** of this buffer if desired. +*/ +char *sqlite_set_result_string(sqlite_func*,const char*,int); +void sqlite_set_result_int(sqlite_func*,int); +void sqlite_set_result_double(sqlite_func*,double); +void sqlite_set_result_error(sqlite_func*,const char*,int); + +/* +** The pUserData parameter to the sqlite_create_function() and +** sqlite_create_aggregate() routines used to register user functions +** is available to the implementation of the function using this +** call. +*/ +void *sqlite_user_data(sqlite_func*); + +/* +** Aggregate functions use the following routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically be SQLite. +*/ +void *sqlite_aggregate_context(sqlite_func*, int nBytes); + +/* +** The next routine returns the number of calls to xStep for a particular +** aggregate function instance. The current call to xStep counts so this +** routine always returns at least 1. +*/ +int sqlite_aggregate_count(sqlite_func*); + +/* +** This routine registers a callback with the SQLite library. The +** callback is invoked (at compile-time, not at run-time) for each +** attempt to access a column of a table in the database. The callback +** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire +** SQL statement should be aborted with an error and SQLITE_IGNORE +** if the column should be treated as a NULL value. +*/ +int sqlite_set_authorizer( + sqlite*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** The second parameter to the access authorization function above will +** be one of the values below. These values signify what kind of operation +** is to be authorized. The 3rd and 4th parameters to the authorization +** function will be parameters or NULL depending on which of the following +** codes is used as the second parameter. The 5th parameter is the name +** of the database ("main", "temp", etc.) if applicable. The 6th parameter +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** input SQL code. +** +** Arg-3 Arg-4 +*/ +#define SQLITE_COPY 0 /* Table Name File Name */ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ + + +/* +** The return value of the authorization function should be one of the +** following constants: +*/ +/* #define SQLITE_OK 0 // Allow access (This is actually defined above) */ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** Register a function that is called at every invocation of sqlite_exec() +** or sqlite_compile(). This function can be used (for example) to generate +** a log file of all SQL executed against a database. +*/ +void *sqlite_trace(sqlite*, void(*xTrace)(void*,const char*), void*); + +/*** The Callback-Free API +** +** The following routines implement a new way to access SQLite that does not +** involve the use of callbacks. +** +** An sqlite_vm is an opaque object that represents a single SQL statement +** that is ready to be executed. +*/ +typedef struct sqlite_vm sqlite_vm; + +/* +** To execute an SQLite query without the use of callbacks, you first have +** to compile the SQL using this routine. The 1st parameter "db" is a pointer +** to an sqlite object obtained from sqlite_open(). The 2nd parameter +** "zSql" is the text of the SQL to be compiled. The remaining parameters +** are all outputs. +** +** *pzTail is made to point to the first character past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppVm is left pointing to a "virtual machine" that can be used to execute +** the compiled statement. Or if there is an error, *ppVm may be set to NULL. +** If the input text contained no SQL (if the input is and empty string or +** a comment) then *ppVm is set to NULL. +** +** If any errors are detected during compilation, an error message is written +** into space obtained from malloc() and *pzErrMsg is made to point to that +** error message. The calling routine is responsible for freeing the text +** of this message when it has finished with it. Use sqlite_freemem() to +** free the message. pzErrMsg may be NULL in which case no error message +** will be generated. +** +** On success, SQLITE_OK is returned. Otherwise and error code is returned. +*/ +int sqlite_compile( + sqlite *db, /* The open database */ + const char *zSql, /* SQL statement to be compiled */ + const char **pzTail, /* OUT: uncompiled tail of zSql */ + sqlite_vm **ppVm, /* OUT: the virtual machine to execute zSql */ + char **pzErrmsg /* OUT: Error message. */ +); + +/* +** After an SQL statement has been compiled, it is handed to this routine +** to be executed. This routine executes the statement as far as it can +** go then returns. The return value will be one of SQLITE_DONE, +** SQLITE_ERROR, SQLITE_BUSY, SQLITE_ROW, or SQLITE_MISUSE. +** +** SQLITE_DONE means that the execute of the SQL statement is complete +** an no errors have occurred. sqlite_step() should not be called again +** for the same virtual machine. *pN is set to the number of columns in +** the result set and *pazColName is set to an array of strings that +** describe the column names and datatypes. The name of the i-th column +** is (*pazColName)[i] and the datatype of the i-th column is +** (*pazColName)[i+*pN]. *pazValue is set to NULL. +** +** SQLITE_ERROR means that the virtual machine encountered a run-time +** error. sqlite_step() should not be called again for the same +** virtual machine. *pN is set to 0 and *pazColName and *pazValue are set +** to NULL. Use sqlite_finalize() to obtain the specific error code +** and the error message text for the error. +** +** SQLITE_BUSY means that an attempt to open the database failed because +** another thread or process is holding a lock. The calling routine +** can try again to open the database by calling sqlite_step() again. +** The return code will only be SQLITE_BUSY if no busy handler is registered +** using the sqlite_busy_handler() or sqlite_busy_timeout() routines. If +** a busy handler callback has been registered but returns 0, then this +** routine will return SQLITE_ERROR and sqltie_finalize() will return +** SQLITE_BUSY when it is called. +** +** SQLITE_ROW means that a single row of the result is now available. +** The data is contained in *pazValue. The value of the i-th column is +** (*azValue)[i]. *pN and *pazColName are set as described in SQLITE_DONE. +** Invoke sqlite_step() again to advance to the next row. +** +** SQLITE_MISUSE is returned if sqlite_step() is called incorrectly. +** For example, if you call sqlite_step() after the virtual machine +** has halted (after a prior call to sqlite_step() has returned SQLITE_DONE) +** or if you call sqlite_step() with an incorrectly initialized virtual +** machine or a virtual machine that has been deleted or that is associated +** with an sqlite structure that has been closed. +*/ +int sqlite_step( + sqlite_vm *pVm, /* The virtual machine to execute */ + int *pN, /* OUT: Number of columns in result */ + const char ***pazValue, /* OUT: Column data */ + const char ***pazColName /* OUT: Column names and datatypes */ +); + +/* +** This routine is called to delete a virtual machine after it has finished +** executing. The return value is the result code. SQLITE_OK is returned +** if the statement executed successfully and some other value is returned if +** there was any kind of error. If an error occurred and pzErrMsg is not +** NULL, then an error message is written into memory obtained from malloc() +** and *pzErrMsg is made to point to that error message. The calling routine +** should use sqlite_freemem() to delete this message when it has finished +** with it. +** +** This routine can be called at any point during the execution of the +** virtual machine. If the virtual machine has not completed execution +** when this routine is called, that is like encountering an error or +** an interrupt. (See sqlite_interrupt().) Incomplete updates may be +** rolled back and transactions cancelled, depending on the circumstances, +** and the result code returned will be SQLITE_ABORT. +*/ +int sqlite_finalize(sqlite_vm*, char **pzErrMsg); + +/* +** This routine deletes the virtual machine, writes any error message to +** *pzErrMsg and returns an SQLite return code in the same way as the +** sqlite_finalize() function. +** +** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual +** machine loaded with the compiled version of the original query ready for +** execution. +** +** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite_reset(sqlite_vm*, char **pzErrMsg); + +/* +** If the SQL that was handed to sqlite_compile contains variables that +** are represeted in the SQL text by a question mark ('?'). This routine +** is used to assign values to those variables. +** +** The first parameter is a virtual machine obtained from sqlite_compile(). +** The 2nd "idx" parameter determines which variable in the SQL statement +** to bind the value to. The left most '?' is 1. The 3rd parameter is +** the value to assign to that variable. The 4th parameter is the number +** of bytes in the value, including the terminating \000 for strings. +** Finally, the 5th "copy" parameter is TRUE if SQLite should make its +** own private copy of this value, or false if the space that the 3rd +** parameter points to will be unchanging and can be used directly by +** SQLite. +** +** Unbound variables are treated as having a value of NULL. To explicitly +** set a variable to NULL, call this routine with the 3rd parameter as a +** NULL pointer. +** +** If the 4th "len" parameter is -1, then strlen() is used to find the +** length. +** +** This routine can only be called immediately after sqlite_compile() +** or sqlite_reset() and before any calls to sqlite_step(). +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy); + +/* +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to sqlite_exec(), +** sqlite_step() and sqlite_get_table(). An example use for this API is to keep +** a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to sqlite_exec(), sqlite_step() or sqlite_get_table() results +** in less than N opcodes being executed, then the progress callback is not +** invoked. +** +** Calling this routine overwrites any previously installed progress callback. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. If the +** query was part of a larger transaction, then the transaction is not rolled +** back and remains active. The sqlite_exec() call returns SQLITE_ABORT. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*); + +/* +** Register a callback function to be invoked whenever a new transaction +** is committed. The pArg argument is passed through to the callback. +** callback. If the callback function returns non-zero, then the commit +** is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +void *sqlite_commit_hook(sqlite*, int(*)(void*), void*); + +/* +** Open an encrypted SQLite database. If pKey==0 or nKey==0, this routine +** is the same as sqlite_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +sqlite *sqlite_open_encrypted( + const char *zFilename, /* Name of the encrypted database */ + const void *pKey, /* Pointer to the key */ + int nKey, /* Number of bytes in the key */ + int *pErrcode, /* Write error code here */ + char **pzErrmsg /* Write error message here */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite_rekey( + sqlite *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif + +#endif /* _SQLITE_H_ */ diff --git a/dep/include/utf8cpp/doc/ReleaseNotes b/dep/include/utf8cpp/doc/ReleaseNotes new file mode 100644 index 000000000..8541c7a60 --- /dev/null +++ b/dep/include/utf8cpp/doc/ReleaseNotes @@ -0,0 +1,9 @@ +utf8 cpp library +Release 2.1 + +This is a minor feature release - added the function peek_next. + +Changes from version 2.o +- Implemented feature request [ 1770746 ] "Provide a const version of next() (some sort of a peek() ) + +Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes diff --git a/dep/include/utf8cpp/doc/utf8cpp.html b/dep/include/utf8cpp/doc/utf8cpp.html new file mode 100644 index 000000000..4ad7e1002 --- /dev/null +++ b/dep/include/utf8cpp/doc/utf8cpp.html @@ -0,0 +1,1574 @@ + + + + + + + + + UTF8-CPP: UTF-8 with C++ in a Portable Way + + + + +

+ UTF8-CPP: UTF-8 with C++ in a Portable Way +

+

+ The Sourceforge project page +

+ +

+ Introduction +

+

+ Many C++ developers miss an easy and portable way of handling Unicode encoded + strings. C++ Standard is currently Unicode agnostic, and while some work is being + done to introduce Unicode to the next incarnation called C++0x, for the moment + nothing of the sort is available. In the meantime, developers use 3rd party + libraries like ICU, OS specific capabilities, or simply roll out their own + solutions. +

+

+ In order to easily handle UTF-8 encoded Unicode strings, I have come up with a small + generic library. For anybody used to work with STL algorithms and iterators, it should be + easy and natural to use. The code is freely available for any purpose - check out + the license at the beginning of the utf8.h file. If you run into + bugs or performance issues, please let me know and I'll do my best to address them. +

+

+ The purpose of this article is not to offer an introduction to Unicode in general, + and UTF-8 in particular. If you are not familiar with Unicode, be sure to check out + Unicode Home Page or some other source of + information for Unicode. Also, it is not my aim to advocate the use of UTF-8 + encoded strings in C++ programs; if you want to handle UTF-8 encoded strings from + C++, I am sure you have good reasons for it. +

+

+ Examples of use +

+

+ To illustrate the use of this utf8 library, we shall open a file containing UTF-8 + encoded text, check whether it starts with a byte order mark, read each line into a + std::string, check it for validity, convert the text to UTF-16, and + back to UTF-8: +

+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+#include "utf8.h"
+using namespace std;
+int main()
+{
+    if (argc != 2) {
+        cout << "\nUsage: docsample filename\n";
+        return 0;
+    }
+    const char* test_file_path = argv[1];
+    // Open the test file (must be UTF-8 encoded)
+    ifstream fs8(test_file_path);
+    if (!fs8.is_open()) {
+    cout << "Could not open " << test_file_path << endl;
+    return 0;
+    }
+    // Read the first line of the file
+    unsigned line_count = 1;
+    string line;
+    if (!getline(fs8, line)) 
+        return 0;
+    // Look for utf-8 byte-order mark at the beginning
+    if (line.size() > 2) {
+        if (utf8::is_bom(line.c_str()))
+            cout << "There is a byte order mark at the beginning of the file\n";
+    }
+    // Play with all the lines in the file
+    do {
+       // check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function)
+        string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
+        if (end_it != line.end()) {
+            cout << "Invalid UTF-8 encoding detected at line " << line_count << "\n";
+            cout << "This part is fine: " << string(line.begin(), end_it) << "\n";
+        }
+        // Get the line length (at least for the valid part)
+        int length = utf8::distance(line.begin(), end_it);
+        cout << "Length of line " << line_count << " is " << length <<  "\n";
+        // Convert it to utf-16
+        vector<unsigned short> utf16line;
+        utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
+        // And back to utf-8
+        string utf8line; 
+        utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line));
+        // Confirm that the conversion went OK:
+        if (utf8line != string(line.begin(), end_it))
+            cout << "Error in UTF-16 conversion at line: " << line_count << "\n";        
+        getline(fs8, line);
+        line_count++;
+    } while (!fs8.eof());
+    return 0;
+}
+
+

+ In the previous code sample, we have seen the use of the following functions from + utf8 namespace: first we used is_bom function to detect + UTF-8 byte order mark at the beginning of the file; then for each line we performed + a detection of invalid UTF-8 sequences with find_invalid; the number + of characters (more precisely - the number of Unicode code points) in each line was + determined with a use of utf8::distance; finally, we have converted + each line to UTF-16 encoding with utf8to16 and back to UTF-8 with + utf16to8. +

+

+ Reference +

+

+ Functions From utf8 Namespace +

+

+ utf8::append +

+

+ Available in version 1.0 and later. +

+

+ Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence + to a UTF-8 string. +

+
+template <typename octet_iterator>
+octet_iterator append(uint32_t cp, octet_iterator result);
+   
+
+

+ cp: A 32 bit integer representing a code point to append to the + sequence.
+ result: An output iterator to the place in the sequence where to + append the code point.
+ Return value: An iterator pointing to the place + after the newly appended sequence. +

+

+ Example of use: +

+
+unsigned char u[5] = {0,0,0,0,0};
+unsigned char* end = append(0x0448, u);
+assert (u[0] == 0xd1 && u[1] == 0x88 && u[2] == 0 && u[3] == 0 && u[4] == 0);
+
+

+ Note that append does not allocate any memory - it is the burden of + the caller to make sure there is enough memory allocated for the operation. To make + things more interesting, append can add anywhere between 1 and 4 + octets to the sequence. In practice, you would most often want to use + std::back_inserter to ensure that the necessary memory is allocated. +

+

+ In case of an invalid code point, a utf8::invalid_code_point exception + is thrown. +

+

+ utf8::next +

+

+ Available in version 1.0 and later. +

+

+ Given the iterator to the beginning of the UTF-8 sequence, it returns the code + point and moves the iterator to the next position. +

+
+template <typename octet_iterator> 
+uint32_t next(octet_iterator& it, octet_iterator end);
+   
+
+

+ it: a reference to an iterator pointing to the beginning of an UTF-8 + encoded code point. After the function returns, it is incremented to point to the + beginning of the next code point.
+ end: end of the UTF-8 sequence to be processed. If it + gets equal to end during the extraction of a code point, an + utf8::not_enough_room exception is thrown.
+ Return value: the 32 bit representation of the + processed UTF-8 code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = next(w, twochars + 6);
+assert (cp == 0x65e5);
+assert (w == twochars + 3);
+
+

+ This function is typically used to iterate through a UTF-8 encoded string. +

+

+ In case of an invalid UTF-8 seqence, a utf8::invalid_utf8 exception is + thrown. +

+

+ utf8::peek_next +

+

+ Available in version 2.1 and later. +

+

+ Given the iterator to the beginning of the UTF-8 sequence, it returns the code + point for the following sequence without changing the value of the iterator. +

+
+template <typename octet_iterator> 
+uint32_t peek_next(octet_iterator it, octet_iterator end);
+   
+
+

+ it: an iterator pointing to the beginning of an UTF-8 + encoded code point.
+ end: end of the UTF-8 sequence to be processed. If it + gets equal to end during the extraction of a code point, an + utf8::not_enough_room exception is thrown.
+ Return value: the 32 bit representation of the + processed UTF-8 code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = peek_next(w, twochars + 6);
+assert (cp == 0x65e5);
+assert (w == twochars);
+
+

+ In case of an invalid UTF-8 seqence, a utf8::invalid_utf8 exception is + thrown. +

+

+ utf8::prior +

+

+ Available in version 1.02 and later. +

+

+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it + decreases the iterator until it hits the beginning of the previous UTF-8 encoded + code point and returns the 32 bits representation of the code point. +

+
+template <typename octet_iterator> 
+uint32_t prior(octet_iterator& it, octet_iterator start);
+   
+
+

+ it: a reference pointing to an octet within a UTF-8 encoded string. + After the function returns, it is decremented to point to the beginning of the + previous code point.
+ start: an iterator to the beginning of the sequence where the search + for the beginning of a code point is performed. It is a + safety measure to prevent passing the beginning of the string in the search for a + UTF-8 lead octet.
+ Return value: the 32 bit representation of the + previous code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+unsigned char* w = twochars + 3;
+int cp = prior (w, twochars);
+assert (cp == 0x65e5);
+assert (w == twochars);
+
+

+ This function has two purposes: one is two iterate backwards through a UTF-8 + encoded string. Note that it is usually a better idea to iterate forward instead, + since utf8::next is faster. The second purpose is to find a beginning + of a UTF-8 sequence if we have a random position within a string. +

+

+ it will typically point to the beginning of + a code point, and start will point to the + beginning of the string to ensure we don't go backwards too far. it is + decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence + beginning with that octet is decoded to a 32 bit representation and returned. +

+

+ In case pass_end is reached before a UTF-8 lead octet is hit, or if an + invalid UTF-8 sequence is started by the lead octet, an invalid_utf8 + exception is thrown. +

+

+ utf8::previous +

+

+ Deprecated in version 1.02 and later. +

+

+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it + decreases the iterator until it hits the beginning of the previous UTF-8 encoded + code point and returns the 32 bits representation of the code point. +

+
+template <typename octet_iterator> 
+uint32_t previous(octet_iterator& it, octet_iterator pass_start);
+   
+
+

+ it: a reference pointing to an octet within a UTF-8 encoded string. + After the function returns, it is decremented to point to the beginning of the + previous code point.
+ pass_start: an iterator to the point in the sequence where the search + for the beginning of a code point is aborted if no result was reached. It is a + safety measure to prevent passing the beginning of the string in the search for a + UTF-8 lead octet.
+ Return value: the 32 bit representation of the + previous code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+unsigned char* w = twochars + 3;
+int cp = previous (w, twochars - 1);
+assert (cp == 0x65e5);
+assert (w == twochars);
+
+

+ utf8::previous is deprecated, and utf8::prior should + be used instead, although the existing code can continue using this function. + The problem is the parameter pass_start that points to the position + just before the beginning of the sequence. Standard containers don't have the + concept of "pass start" and the function can not be used with their iterators. +

+

+ it will typically point to the beginning of + a code point, and pass_start will point to the octet just before the + beginning of the string to ensure we don't go backwards too far. it is + decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence + beginning with that octet is decoded to a 32 bit representation and returned. +

+

+ In case pass_end is reached before a UTF-8 lead octet is hit, or if an + invalid UTF-8 sequence is started by the lead octet, an invalid_utf8 + exception is thrown +

+

+ utf8::advance +

+

+ Available in version 1.0 and later. +

+

+ Advances an iterator by the specified number of code points within an UTF-8 + sequence. +

+
+template <typename octet_iterator, typename distance_type> 
+void advance (octet_iterator& it, distance_type n, octet_iterator end);
+   
+
+

+ it: a reference to an iterator pointing to the beginning of an UTF-8 + encoded code point. After the function returns, it is incremented to point to the + nth following code point.
+ n: a positive integer that shows how many code points we want to + advance.
+ end: end of the UTF-8 sequence to be processed. If it + gets equal to end during the extraction of a code point, an + utf8::not_enough_room exception is thrown.
+

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+unsigned char* w = twochars;
+advance (w, 2, twochars + 6);
+assert (w == twochars + 5);
+
+

+ This function works only "forward". In case of a negative n, there is + no effect. +

+

+ In case of an invalid code point, a utf8::invalid_code_point exception + is thrown. +

+

+ utf8::distance +

+

+ Available in version 1.0 and later. +

+

+ Given the iterators to two UTF-8 encoded code points in a seqence, returns the + number of code points between them. +

+
+template <typename octet_iterator> 
+typename std::iterator_traits<octet_iterator>::difference_type distance (octet_iterator first, octet_iterator last);
+   
+
+

+ first: an iterator to a beginning of a UTF-8 encoded code point.
+ last: an iterator to a "post-end" of the last UTF-8 encoded code + point in the sequence we are trying to determine the length. It can be the + beginning of a new code point, or not.
+ Return value the distance between the iterators, + in code points. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+size_t dist = utf8::distance(twochars, twochars + 5);
+assert (dist == 2);
+
+

+ This function is used to find the length (in code points) of a UTF-8 encoded + string. The reason it is called distance, rather than, say, + length is mainly because developers are used that length is an + O(1) function. Computing the length of an UTF-8 string is a linear operation, and + it looked better to model it after std::distance algorithm. +

+

+ In case of an invalid UTF-8 seqence, a utf8::invalid_utf8 exception is + thrown. If last does not point to the past-of-end of a UTF-8 seqence, + a utf8::not_enough_room exception is thrown. +

+

+ utf8::utf16to8 +

+

+ Available in version 1.0 and later. +

+

+ Converts a UTF-16 encoded string to UTF-8. +

+
+template <typename u16bit_iterator, typename octet_iterator>
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-16 encoded + string to convert.
+ end: an iterator pointing to pass-the-end of the UTF-16 encoded + string to convert.
+ result: an output iterator to the place in the UTF-8 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-8 string. +

+

+ Example of use: +

+
+unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+vector<unsigned char> utf8result;
+utf16to8(utf16string, utf16string + 5, back_inserter(utf8result));
+assert (utf8result.size() == 10);    
+
+

+ In case of invalid UTF-16 sequence, a utf8::invalid_utf16 exception is + thrown. +

+

+ utf8::utf8to16 +

+

+ Available in version 1.0 and later. +

+

+ Converts an UTF-8 encoded string to UTF-16 +

+
+template <typename u16bit_iterator, typename octet_iterator>
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-8 encoded + string to convert. < br /> end: an iterator pointing to + pass-the-end of the UTF-8 encoded string to convert.
+ result: an output iterator to the place in the UTF-16 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-16 string. +

+

+ Example of use: +

+
+char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+vector <unsigned short> utf16result;
+utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result));
+assert (utf16result.size() == 4);
+assert (utf16result[2] == 0xd834);
+assert (utf16result[3] == 0xdd1e);
+
+

+ In case of an invalid UTF-8 seqence, a utf8::invalid_utf8 exception is + thrown. If end does not point to the past-of-end of a UTF-8 seqence, a + utf8::not_enough_room exception is thrown. +

+

+ utf8::utf32to8 +

+

+ Available in version 1.0 and later. +

+

+ Converts a UTF-32 encoded string to UTF-8. +

+
+template <typename octet_iterator, typename u32bit_iterator>
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-32 encoded + string to convert.
+ end: an iterator pointing to pass-the-end of the UTF-32 encoded + string to convert.
+ result: an output iterator to the place in the UTF-8 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-8 string. +

+

+ Example of use: +

+
+int utf32string[] = {0x448, 0x65E5, 0x10346, 0};
+vector<unsigned char> utf8result;
+utf32to8(utf32string, utf32string + 3, back_inserter(utf8result));
+assert (utf8result.size() == 9);
+
+

+ In case of invalid UTF-32 string, a utf8::invalid_code_point exception + is thrown. +

+

+ utf8::utf8to32 +

+

+ Available in version 1.0 and later. +

+

+ Converts a UTF-8 encoded string to UTF-32. +

+
+template <typename octet_iterator, typename u32bit_iterator>
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-8 encoded + string to convert.
+ end: an iterator pointing to pass-the-end of the UTF-8 encoded string + to convert.
+ result: an output iterator to the place in the UTF-32 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-32 string. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+vector<int> utf32result;
+utf8to32(twochars, twochars + 5, back_inserter(utf32result));
+assert (utf32result.size() == 2);
+
+

+ In case of an invalid UTF-8 seqence, a utf8::invalid_utf8 exception is + thrown. If end does not point to the past-of-end of a UTF-8 seqence, a + utf8::not_enough_room exception is thrown. +

+

+ utf8::find_invalid +

+

+ Available in version 1.0 and later. +

+

+ Detects an invalid sequence within a UTF-8 string. +

+
+template <typename octet_iterator> 
+octet_iterator find_invalid(octet_iterator start, octet_iterator end);
+
+

+ start: an iterator pointing to the beginning of the UTF-8 string to + test for validity.
+ end: an iterator pointing to pass-the-end of the UTF-8 string to test + for validity.
+ Return value: an iterator pointing to the first + invalid octet in the UTF-8 string. In case none were found, equals + end. +

+

+ Example of use: +

+
+char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+char* invalid = find_invalid(utf_invalid, utf_invalid + 6);
+assert (invalid == utf_invalid + 5);
+
+

+ This function is typically used to make sure a UTF-8 string is valid before + processing it with other functions. It is especially important to call it if before + doing any of the unchecked operations on it. +

+

+ utf8::is_valid +

+

+ Available in version 1.0 and later. +

+

+ Checks whether a sequence of octets is a valid UTF-8 string. +

+
+template <typename octet_iterator> 
+bool is_valid(octet_iterator start, octet_iterator end);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-8 string to + test for validity.
+ end: an iterator pointing to pass-the-end of the UTF-8 string to test + for validity.
+ Return value: true if the sequence + is a valid UTF-8 string; false if not. +

+ Example of use: +
+char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+bool bvalid = is_valid(utf_invalid, utf_invalid + 6);
+assert (bvalid == false);
+
+

+ is_valid is a shorthand for find_invalid(start, end) == + end;. You may want to use it to make sure that a byte seqence is a valid + UTF-8 string without the need to know where it fails if it is not valid. +

+

+ utf8::replace_invalid +

+

+ Available in version 2.0 and later. +

+

+ Replaces all invalid UTF-8 sequences within a string with a replacement marker. +

+
+template <typename octet_iterator, typename output_iterator>
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement);
+template <typename octet_iterator, typename output_iterator>
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-8 string to + look for invalid UTF-8 sequences.
+ end: an iterator pointing to pass-the-end of the UTF-8 string to look + for invalid UTF-8 sequences.
+ out: An output iterator to the range where the result of replacement + is stored.
+ replacement: A Unicode code point for the replacement marker. The + version without this parameter assumes the value 0xfffd
+ Return value: An iterator pointing to the place + after the UTF-8 string with replaced invalid sequences. +

+

+ Example of use: +

+
+char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+vector<char> replace_invalid_result;
+replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), '?');
+bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+assert (bvalid);
+char* fixed_invalid_sequence = "a????z";
+assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence));
+
+

+ replace_invalid does not perform in-place replacement of invalid + sequences. Rather, it produces a copy of the original string with the invalid + sequences replaced with a replacement marker. Therefore, out must not + be in the [start, end] range. +

+

+ If end does not point to the past-of-end of a UTF-8 sequence, a + utf8::not_enough_room exception is thrown. +

+

+ utf8::is_bom +

+

+ Available in version 1.0 and later. +

+

+ Checks whether a sequence of three octets is a UTF-8 byte order mark (BOM) +

+
+template <typename octet_iterator> 
+bool is_bom (octet_iterator it);
+
+

+ it: beginning of the 3-octet sequence to check
+ Return value: true if the sequence + is UTF-8 byte order mark; false if not. +

+

+ Example of use: +

+
+unsigned char byte_order_mark[] = {0xef, 0xbb, 0xbf};
+bool bbom = is_bom(byte_order_mark);
+assert (bbom == true);
+
+

+ The typical use of this function is to check the first three bytes of a file. If + they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 + encoded text. +

+

+ Types From utf8 Namespace +

+

+ utf8::iterator +

+

+ Available in version 2.0 and later. +

+

+ Adapts the underlying octet iterator to iterate over the sequence of code points, + rather than raw octets. +

+
+template <typename octet_iterator>
+class iterator;
+
+ +
Member functions
+
+
iterator();
the deafult constructor; the underlying octet_iterator is + constructed with its default constructor. +
explicit iterator (const octet_iterator& octet_it, + const octet_iterator& range_start, + const octet_iterator& range_end);
a constructor + that initializes the underlying octet_iterator with octet_it + and sets the range in which the iterator is considered valid. +
octet_iterator base () const;
returns the + underlying octet_iterator. +
uint32_t operator * () const;
decodes the utf-8 sequence + the underlying octet_iterator is pointing to and returns the code point. +
bool operator == (const iterator& rhs) + const;
returns true + if the two underlaying iterators are equal. +
bool operator != (const iterator& rhs) + const;
returns true + if the two underlaying iterators are not equal. +
iterator& operator ++ ();
the prefix increment - moves + the iterator to the next UTF-8 encoded code point. +
iterator operator ++ (int);
+ the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one. +
iterator& operator -- ();
the prefix decrement - moves + the iterator to the previous UTF-8 encoded code point. +
iterator operator -- (int);
+ the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one. +
+

+ Example of use: +

+
+char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+utf8::iterator<char*> it(threechars, threechars, threechars + 9);
+utf8::iterator<char*> it2 = it;
+assert (it2 == it);
+assert (*it == 0x10346);
+assert (*(++it) == 0x65e5);
+assert ((*it++) == 0x65e5);
+assert (*it == 0x0448);
+assert (it != it2);
+utf8::iterator<char*> endit (threechars + 9, threechars, threechars + 9);  
+assert (++it == endit);
+assert (*(--it) == 0x0448);
+assert ((*it--) == 0x0448);
+assert (*it == 0x65e5);
+assert (--it == utf8::iterator<char*>(threechars, threechars, threechars + 9));
+assert (*it == 0x10346);
+
+

+ The purpose of utf8::iterator adapter is to enable easy iteration as well as the use of STL + algorithms with UTF-8 encoded strings. Increment and decrement operators are implemented in terms of + utf8::next() and utf8::prior() functions. +

+

+ Note that utf8::iterator adapter is a checked iterator. It operates on the range specified in + the constructor; any attempt to go out of that range will result in an exception. Even the comparison operators + require both iterator object to be constructed against the same range - otherwise an exception is thrown. Typically, + the range will be determined by sequence container functions begin and end, i.e.: +

+
+std::string s = "example";
+utf8::iterator i (s.begin(), s.begin(), s.end());
+
+

+ Functions From utf8::unchecked Namespace +

+

+ utf8::unchecked::append +

+

+ Available in version 1.0 and later. +

+

+ Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence + to a UTF-8 string. +

+
+template <typename octet_iterator>
+octet_iterator append(uint32_t cp, octet_iterator result);
+   
+
+

+ cp: A 32 bit integer representing a code point to append to the + sequence.
+ result: An output iterator to the place in the sequence where to + append the code point.
+ Return value: An iterator pointing to the place + after the newly appended sequence. +

+

+ Example of use: +

+
+unsigned char u[5] = {0,0,0,0,0};
+unsigned char* end = unchecked::append(0x0448, u);
+assert (u[0] == 0xd1 && u[1] == 0x88 && u[2] == 0 && u[3] == 0 && u[4] == 0);
+
+

+ This is a faster but less safe version of utf8::append. It does not + check for validity of the supplied code point, and may produce an invalid UTF-8 + sequence. +

+

+ utf8::unchecked::next +

+

+ Available in version 1.0 and later. +

+

+ Given the iterator to the beginning of a UTF-8 sequence, it returns the code point + and moves the iterator to the next position. +

+
+template <typename octet_iterator>
+uint32_t next(octet_iterator& it);
+   
+
+

+ it: a reference to an iterator pointing to the beginning of an UTF-8 + encoded code point. After the function returns, it is incremented to point to the + beginning of the next code point.
+ Return value: the 32 bit representation of the + processed UTF-8 code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = unchecked::next(w);
+assert (cp == 0x65e5);
+assert (w == twochars + 3);
+
+

+ This is a faster but less safe version of utf8::next. It does not + check for validity of the supplied UTF-8 sequence. +

+

+ utf8::unchecked::peek_next +

+

+ Available in version 2.1 and later. +

+

+ Given the iterator to the beginning of a UTF-8 sequence, it returns the code point. +

+
+template <typename octet_iterator>
+uint32_t peek_next(octet_iterator it);
+   
+
+

+ it: an iterator pointing to the beginning of an UTF-8 + encoded code point.
+ Return value: the 32 bit representation of the + processed UTF-8 code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = unchecked::peek_next(w);
+assert (cp == 0x65e5);
+assert (w == twochars);
+
+

+ This is a faster but less safe version of utf8::peek_next. It does not + check for validity of the supplied UTF-8 sequence. +

+

+ utf8::unchecked::prior +

+

+ Available in version 1.02 and later. +

+

+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it + decreases the iterator until it hits the beginning of the previous UTF-8 encoded + code point and returns the 32 bits representation of the code point. +

+
+template <typename octet_iterator>
+uint32_t prior(octet_iterator& it);
+   
+
+

+ it: a reference pointing to an octet within a UTF-8 encoded string. + After the function returns, it is decremented to point to the beginning of the + previous code point.
+ Return value: the 32 bit representation of the + previous code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars + 3;
+int cp = unchecked::prior (w);
+assert (cp == 0x65e5);
+assert (w == twochars);
+
+

+ This is a faster but less safe version of utf8::prior. It does not + check for validity of the supplied UTF-8 sequence and offers no boundary checking. +

+

+ utf8::unchecked::previous (deprecated, see utf8::unchecked::prior) +

+

+ Deprecated in version 1.02 and later. +

+

+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it + decreases the iterator until it hits the beginning of the previous UTF-8 encoded + code point and returns the 32 bits representation of the code point. +

+
+template <typename octet_iterator>
+uint32_t previous(octet_iterator& it);
+   
+
+

+ it: a reference pointing to an octet within a UTF-8 encoded string. + After the function returns, it is decremented to point to the beginning of the + previous code point.
+ Return value: the 32 bit representation of the + previous code point. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars + 3;
+int cp = unchecked::previous (w);
+assert (cp == 0x65e5);
+assert (w == twochars);
+
+

+ The reason this function is deprecated is just the consistency with the "checked" + versions, where prior should be used instead of previous. + In fact, unchecked::previous behaves exactly the same as + unchecked::prior +

+

+ This is a faster but less safe version of utf8::previous. It does not + check for validity of the supplied UTF-8 sequence and offers no boundary checking. +

+

+ utf8::unchecked::advance +

+

+ Available in version 1.0 and later. +

+

+ Advances an iterator by the specified number of code points within an UTF-8 + sequence. +

+
+template <typename octet_iterator, typename distance_type>
+void advance (octet_iterator& it, distance_type n);
+   
+
+

+ it: a reference to an iterator pointing to the beginning of an UTF-8 + encoded code point. After the function returns, it is incremented to point to the + nth following code point.
+ n: a positive integer that shows how many code points we want to + advance.
+

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+unchecked::advance (w, 2);
+assert (w == twochars + 5);
+
+

+ This function works only "forward". In case of a negative n, there is + no effect. +

+

+ This is a faster but less safe version of utf8::advance. It does not + check for validity of the supplied UTF-8 sequence and offers no boundary checking. +

+

+ utf8::unchecked::distance +

+

+ Available in version 1.0 and later. +

+

+ Given the iterators to two UTF-8 encoded code points in a seqence, returns the + number of code points between them. +

+
+template <typename octet_iterator>
+typename std::iterator_traits<octet_iterator>::difference_type distance (octet_iterator first, octet_iterator last);
+
+

+ first: an iterator to a beginning of a UTF-8 encoded code point.
+ last: an iterator to a "post-end" of the last UTF-8 encoded code + point in the sequence we are trying to determine the length. It can be the + beginning of a new code point, or not.
+ Return value the distance between the iterators, + in code points. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+size_t dist = utf8::unchecked::distance(twochars, twochars + 5);
+assert (dist == 2);
+
+

+ This is a faster but less safe version of utf8::distance. It does not + check for validity of the supplied UTF-8 sequence. +

+

+ utf8::unchecked::utf16to8 +

+

+ Available in version 1.0 and later. +

+

+ Converts a UTF-16 encoded string to UTF-8. +

+
+template <typename u16bit_iterator, typename octet_iterator>
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-16 encoded + string to convert.
+ end: an iterator pointing to pass-the-end of the UTF-16 encoded + string to convert.
+ result: an output iterator to the place in the UTF-8 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-8 string. +

+

+ Example of use: +

+
+unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+vector<unsigned char> utf8result;
+unchecked::utf16to8(utf16string, utf16string + 5, back_inserter(utf8result));
+assert (utf8result.size() == 10);    
+
+

+ This is a faster but less safe version of utf8::utf16to8. It does not + check for validity of the supplied UTF-16 sequence. +

+

+ utf8::unchecked::utf8to16 +

+

+ Available in version 1.0 and later. +

+

+ Converts an UTF-8 encoded string to UTF-16 +

+
+template <typename u16bit_iterator, typename octet_iterator>
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-8 encoded + string to convert. < br /> end: an iterator pointing to + pass-the-end of the UTF-8 encoded string to convert.
+ result: an output iterator to the place in the UTF-16 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-16 string. +

+

+ Example of use: +

+
+char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+vector <unsigned short> utf16result;
+unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result));
+assert (utf16result.size() == 4);
+assert (utf16result[2] == 0xd834);
+assert (utf16result[3] == 0xdd1e);
+
+

+ This is a faster but less safe version of utf8::utf8to16. It does not + check for validity of the supplied UTF-8 sequence. +

+

+ utf8::unchecked::utf32to8 +

+

+ Available in version 1.0 and later. +

+

+ Converts a UTF-32 encoded string to UTF-8. +

+
+template <typename octet_iterator, typename u32bit_iterator>
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-32 encoded + string to convert.
+ end: an iterator pointing to pass-the-end of the UTF-32 encoded + string to convert.
+ result: an output iterator to the place in the UTF-8 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-8 string. +

+

+ Example of use: +

+
+int utf32string[] = {0x448, 0x65e5, 0x10346, 0};
+vector<unsigned char> utf8result;
+utf32to8(utf32string, utf32string + 3, back_inserter(utf8result));
+assert (utf8result.size() == 9);
+
+

+ This is a faster but less safe version of utf8::utf32to8. It does not + check for validity of the supplied UTF-32 sequence. +

+

+ utf8::unchecked::utf8to32 +

+

+ Available in version 1.0 and later. +

+

+ Converts a UTF-8 encoded string to UTF-32. +

+
+template <typename octet_iterator, typename u32bit_iterator>
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+   
+
+

+ start: an iterator pointing to the beginning of the UTF-8 encoded + string to convert.
+ end: an iterator pointing to pass-the-end of the UTF-8 encoded string + to convert.
+ result: an output iterator to the place in the UTF-32 string where to + append the result of conversion.
+ Return value: An iterator pointing to the place + after the appended UTF-32 string. +

+

+ Example of use: +

+
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+vector<int> utf32result;
+unchecked::utf8to32(twochars, twochars + 5, back_inserter(utf32result));
+assert (utf32result.size() == 2);
+
+

+ This is a faster but less safe version of utf8::utf8to32. It does not + check for validity of the supplied UTF-8 sequence. +

+

+ Types From utf8::unchecked Namespace +

+

+ utf8::iterator +

+

+ Available in version 2.0 and later. +

+

+ Adapts the underlying octet iterator to iterate over the sequence of code points, + rather than raw octets. +

+
+template <typename octet_iterator>
+class iterator;
+
+ +
Member functions
+
+
iterator();
the deafult constructor; the underlying octet_iterator is + constructed with its default constructor. +
explicit iterator (const octet_iterator& octet_it); +
a constructor + that initializes the underlying octet_iterator with octet_it +
octet_iterator base () const;
returns the + underlying octet_iterator. +
uint32_t operator * () const;
decodes the utf-8 sequence + the underlying octet_iterator is pointing to and returns the code point. +
bool operator == (const iterator& rhs) + const;
returns true + if the two underlaying iterators are equal. +
bool operator != (const iterator& rhs) + const;
returns true + if the two underlaying iterators are not equal. +
iterator& operator ++ ();
the prefix increment - moves + the iterator to the next UTF-8 encoded code point. +
iterator operator ++ (int);
+ the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one. +
iterator& operator -- ();
the prefix decrement - moves + the iterator to the previous UTF-8 encoded code point. +
iterator operator -- (int);
+ the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one. +
+

+ Example of use: +

+
+char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+utf8::unchecked::iterator<char*> un_it(threechars);
+utf8::unchecked::iterator<char*> un_it2 = un_it;
+assert (un_it2 == un_it);
+assert (*un_it == 0x10346);
+assert (*(++un_it) == 0x65e5);
+assert ((*un_it++) == 0x65e5);
+assert (*un_it == 0x0448);
+assert (un_it != un_it2);
+utf8::::unchecked::iterator<char*> un_endit (threechars + 9);  
+assert (++un_it == un_endit);
+assert (*(--un_it) == 0x0448);
+assert ((*un_it--) == 0x0448);
+assert (*un_it == 0x65e5);
+assert (--un_it == utf8::unchecked::iterator<char*>(threechars));
+assert (*un_it == 0x10346);
+
+

+ This is an unchecked version of utf8::iterator. It is faster in many cases, but offers + no validity or range checks. +

+

+ Points of interest +

+

+ Design goals and decisions +

+

+ The library was designed to be: +

+
    +
  1. + Generic: for better or worse, there are many C++ string classes out there, and + the library should work with as many of them as possible. +
  2. +
  3. + Portable: the library should be portable both accross different platforms and + compilers. The only non-portable code is a small section that declares unsigned + integers of different sizes: three typedefs. They can be changed by the users of + the library if they don't match their platform. The default setting should work + for Windows (both 32 and 64 bit), and most 32 bit and 64 bit Unix derivatives. +
  4. +
  5. + Lightweight: follow the "pay only for what you use" guidline. +
  6. +
  7. + Unintrusive: avoid forcing any particular design or even programming style on the + user. This is a library, not a framework. +
  8. +
+

+ Alternatives +

+

+ In case you want to look into other means of working with UTF-8 strings from C++, + here is the list of solutions I am aware of: +

+
    +
  1. + ICU Library. It is very powerful, + complete, feature-rich, mature, and widely used. Also big, intrusive, + non-generic, and doesn't play well with the Standard Library. I definitelly + recommend looking at ICU even if you don't plan to use it. +
  2. +
  3. + Glib::ustring. + A class specifically made to work with UTF-8 strings, and also feel like + std::string. If you prefer to have yet another string class in your + code, it may be worth a look. Be aware of the licensing issues, though. +
  4. +
  5. + Platform dependent solutions: Windows and POSIX have functions to convert strings + from one encoding to another. That is only a subset of what my library offers, + but if that is all you need it may be good enough, especially given the fact that + these functions are mature and tested in production. +
  6. +
+

+ Conclusion +

+

+ Until Unicode becomes officially recognized by the C++ Standard Library, we need to + use other means to work with UTF-8 strings. Template functions I describe in this + article may be a good step in this direction. +

+ +
    +
  1. + The Unicode Consortium. +
  2. +
  3. + ICU Library. +
  4. +
  5. + UTF-8 at Wikipedia +
  6. +
  7. + UTF-8 and Unicode FAQ for + Unix/Linux +
  8. +
+ + diff --git a/dep/include/utf8cpp/utf8.h b/dep/include/utf8cpp/utf8.h new file mode 100644 index 000000000..82b13f59f --- /dev/null +++ b/dep/include/utf8cpp/utf8.h @@ -0,0 +1,34 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/checked.h" +#include "utf8/unchecked.h" + +#endif // header guard diff --git a/dep/include/utf8cpp/utf8/checked.h b/dep/include/utf8cpp/utf8/checked.h new file mode 100644 index 000000000..5670c196d --- /dev/null +++ b/dep/include/utf8cpp/utf8/checked.h @@ -0,0 +1,318 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" +#include + +namespace utf8 +{ + // Exceptions that may be thrown from the library functions. + class invalid_code_point : public std::exception { + uint32_t cp; + public: + invalid_code_point(uint32_t cp) : cp(cp) {} + virtual const char* what() const throw() { return "Invalid code point"; } + uint32_t code_point() const {return cp;} + }; + + class invalid_utf8 : public std::exception { + uint8_t u8; + public: + invalid_utf8 (uint8_t u) : u8(u) {} + virtual const char* what() const throw() { return "Invalid UTF-8"; } + uint8_t utf8_octet() const {return u8;} + }; + + class invalid_utf16 : public std::exception { + uint16_t u16; + public: + invalid_utf16 (uint16_t u) : u16(u) {} + virtual const char* what() const throw() { return "Invalid UTF-16"; } + uint16_t utf16_word() const {return u16;} + }; + + class not_enough_room : public std::exception { + public: + virtual const char* what() const throw() { return "Not enough space"; } + }; + + /// The library API - functions intended to be called by the users + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = internal::validate_next(start, end); + switch (err_code) { + case internal::OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + throw not_enough_room(); + case internal::INVALID_LEAD: + append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (internal::is_trail(*start) && start != end) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const uint32_t replacement_marker = internal::mask16(0xfffd); + return replace_invalid(start, end, out, replacement_marker); + } + + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (!internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast((cp >> 6) & 0x3f | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp <= internal::CODE_POINT_MAX) { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast((cp >> 12)& 0x3f | 0x80); + *(result++) = static_cast((cp >> 6) & 0x3f | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else + throw invalid_code_point(cp); + + return result; + } + + template + uint32_t next(octet_iterator& it, octet_iterator end) + { + uint32_t cp = 0; + internal::utf_error err_code = internal::validate_next(it, end, &cp); + switch (err_code) { + case internal::OK : + break; + case internal::NOT_ENOUGH_ROOM : + throw not_enough_room(); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : + throw invalid_utf8(*it); + case internal::INVALID_CODE_POINT : + throw invalid_code_point(cp); + } + return cp; + } + + template + uint32_t peek_next(octet_iterator it, octet_iterator end) + { + return next(it, end); + } + + template + uint32_t prior(octet_iterator& it, octet_iterator start) + { + octet_iterator end = it; + while (internal::is_trail(*(--it))) + if (it < start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return next(temp, end); + } + + /// Deprecated in versions that include "prior" + template + uint32_t previous(octet_iterator& it, octet_iterator pass_start) + { + octet_iterator end = it; + while (internal::is_trail(*(--it))) + if (it == pass_start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return next(temp, end); + } + + template + void advance (octet_iterator& it, distance_type n, octet_iterator end) + { + for (distance_type i = 0; i < n; ++i) + next(it, end); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + next(first, last); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = internal::mask16(*start++); + // Take care of surrogate pairs first + if (internal::is_surrogate(cp)) { + if (start != end) { + uint32_t trail_surrogate = internal::mask16(*start++); + if (trail_surrogate >= internal::TRAIL_SURROGATE_MIN && trail_surrogate <= internal::TRAIL_SURROGATE_MAX) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else + throw invalid_utf16(static_cast(trail_surrogate)); + } + else + throw invalid_utf16(static_cast(*start)); + + } + result = append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = next(start, end); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = next(start, end); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + octet_iterator range_start; + octet_iterator range_end; + public: + iterator () {}; + explicit iterator (const octet_iterator& octet_it, + const octet_iterator& range_start, + const octet_iterator& range_end) : + it(octet_it), range_start(range_start), range_end(range_end) + { + if (it < range_start || it > range_end) + throw std::out_of_range("Invalid utf-8 iterator position"); + } + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return next(temp, range_end); + } + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) + throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + next(it, range_end); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + next(it, range_end); + return temp; + } + iterator& operator -- () + { + prior(it, range_start); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + prior(it, range_start); + return temp; + } + }; // class iterator + +} // namespace utf8 + +#endif //header guard + + diff --git a/dep/include/utf8cpp/utf8/unchecked.h b/dep/include/utf8cpp/utf8/unchecked.h new file mode 100644 index 000000000..4009cebe6 --- /dev/null +++ b/dep/include/utf8cpp/utf8/unchecked.h @@ -0,0 +1,228 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" + +namespace utf8 +{ + namespace unchecked + { + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast((cp >> 6) & 0x3f | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast((cp >> 12)& 0x3f | 0x80); + *(result++) = static_cast((cp >> 6) & 0x3f | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + uint32_t next(octet_iterator& it) + { + uint32_t cp = internal::mask8(*it); + typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); + switch (length) { + case 1: + break; + case 2: + it++; + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + break; + case 3: + ++it; + cp = ((cp << 12) & 0xffff) + ((internal::mask8(*it) << 6) & 0xfff); + ++it; + cp += (*it) & 0x3f; + break; + case 4: + ++it; + cp = ((cp << 18) & 0x1fffff) + ((internal::mask8(*it) << 12) & 0x3ffff); + ++it; + cp += (internal::mask8(*it) << 6) & 0xfff; + ++it; + cp += (*it) & 0x3f; + break; + } + ++it; + return cp; + } + + template + uint32_t peek_next(octet_iterator it) + { + return next(it); + } + + template + uint32_t prior(octet_iterator& it) + { + while (internal::is_trail(*(--it))) ; + octet_iterator temp = it; + return next(temp); + } + + // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) + template + inline uint32_t previous(octet_iterator& it) + { + return prior(it); + } + + template + void advance (octet_iterator& it, distance_type n) + { + for (distance_type i = 0; i < n; ++i) + next(it); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + next(first); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = internal::mask16(*start++); + // Take care of surrogate pairs first + if (internal::is_surrogate(cp)) { + uint32_t trail_surrogate = internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + } + result = append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = next(start); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = next(start); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + public: + iterator () {}; + explicit iterator (const octet_iterator& octet_it): it(octet_it) {} + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return next(temp); + } + bool operator == (const iterator& rhs) const + { + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + std::advance(it, internal::sequence_length(it)); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + std::advance(it, internal::sequence_length(it)); + return temp; + } + iterator& operator -- () + { + prior(it); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + prior(it); + return temp; + } + }; // class iterator + + } // namespace utf8::unchecked +} // namespace utf8 + + +#endif // header guard + diff --git a/dep/include/vld/vld.h b/dep/include/vld/vld.h new file mode 100644 index 000000000..ffe675d7d --- /dev/null +++ b/dep/include/vld/vld.h @@ -0,0 +1,104 @@ +//////////////////////////////////////////////////////////////////////////////// +// $Id: vld.h,v 1.27 2006/11/12 18:09:20 dmouldin Exp $ +// +// Visual Leak Detector (Version 1.9d) - Import Library Header +// Copyright (c) 2006 Dan Moulding +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// +// See COPYING.txt for the full terms of the GNU Lesser General Public License. +// +//////////////////////////////////////////////////////////////////////////////// + +//#pragma once +#ifndef _VLD_H_ +#define _VLD_H_ + +#ifdef _DEBUG + +#pragma comment(lib, "vld.lib") + +// Force a symbolic reference to the global VisualLeakDetector class object from +// the DLL. This enusres that the DLL is loaded and linked with the program, +// even if no code otherwise imports any of the DLL's exports. +#pragma comment(linker, "/include:__imp_?vld@@3VVisualLeakDetector@@A") + +//////////////////////////////////////////////////////////////////////////////// +// +// Visual Leak Detector APIs +// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// VLDDisable - Disables Visual Leak Detector's memory leak detection at +// runtime. If memory leak detection is already disabled, then calling this +// function has no effect. +// +// Note: In multithreaded programs, this function operates on a per-thread +// basis. In other words, if you call this function from one thread, then +// memory leak detection is only disabled for that thread. If memory leak +// detection is enabled for other threads, then it will remain enabled for +// those other threads. It was designed to work this way to insulate you, +// the programmer, from having to ensure thread synchronization when calling +// VLDEnable() and VLDDisable(). Without this, calling these two functions +// unsychronized could result in unpredictable and unintended behavior. +// But this also means that if you want to disable memory leak detection +// process-wide, then you need to call this function from every thread in +// the process. +// +// Return Value: +// +// None. +// + +__declspec(dllimport) void VLDDisable (); + +// VLDEnable - Enables Visual Leak Detector's memory leak detection at runtime. +// If memory leak detection is already enabled, which it is by default, then +// calling this function has no effect. +// +// Note: In multithreaded programs, this function operates on a per-thread +// basis. In other words, if you call this function from one thread, then +// memory leak detection is only enabled for that thread. If memory leak +// detection is disabled for other threads, then it will remain disabled for +// those other threads. It was designed to work this way to insulate you, +// the programmer, from having to ensure thread synchronization when calling +// VLDEnable() and VLDDisable(). Without this, calling these two functions +// unsychronized could result in unpredictable and unintended behavior. +// But this also means that if you want to enable memory leak detection +// process-wide, then you need to call this function from every thread in +// the process. +// +// Return Value: +// +// None. +// + +__declspec(dllimport) void VLDEnable (); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#else // !_DEBUG + +#define VLDEnable() +#define VLDDisable() + +#endif // _DEBUG + +#endif // _VLD_H_ diff --git a/dep/include/zlib/zconf.h b/dep/include/zlib/zconf.h new file mode 100644 index 000000000..03a9431c8 --- /dev/null +++ b/dep/include/zlib/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/dep/include/zlib/zlib.h b/dep/include/zlib/zlib.h new file mode 100644 index 000000000..022817927 --- /dev/null +++ b/dep/include/zlib/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/dep/include/zthread/AtomicCount.h b/dep/include/zthread/AtomicCount.h new file mode 100644 index 000000000..ea042a7fe --- /dev/null +++ b/dep/include/zthread/AtomicCount.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTATOMICCOUNT_H__ +#define __ZTATOMICCOUNT_H__ + +#include + +#include "zthread/Config.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + /** + * @class AtomicCount + * @author Eric Crahen + * @date <2003-07-16T09:41:55-0400> + * @version 2.3.0 + * + * This class provides an interface to a small integer whose value can be + * incremented or decremented atomically. It's designed to be as simple and + * lightweight as possible so that it can be used cheaply to create reference + * counts. + */ + class ZTHREAD_API AtomicCount : public NonCopyable { + + void* _value; + + public: + + //! Create a new AtomicCount, initialized to a value of 1 + AtomicCount(); + + //! Destroy a new AtomicCount + ~AtomicCount(); + + //! Postfix decrement and return the current value + size_t operator--(int); + + //! Postfix increment and return the current value + size_t operator++(int); + + //! Prefix decrement and return the current value + size_t operator--(); + + //! Prefix increment and return the current value + size_t operator++(); + + + }; /* AtomicCount */ + + +} // namespace ZThread + +#endif // __ZTATOMICCOUNT_H__ diff --git a/dep/include/zthread/Barrier.h b/dep/include/zthread/Barrier.h new file mode 100644 index 000000000..6aaafa936 --- /dev/null +++ b/dep/include/zthread/Barrier.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTBARRIER_H__ +#define __ZTBARRIER_H__ + +#include "zthread/Condition.h" +#include "zthread/Guard.h" +#include "zthread/Waitable.h" +#include "zthread/Runnable.h" + +namespace ZThread { + + /** + * @class Barrier + * @author Eric Crahen + * @date <2003-07-16T09:54:01-0400> + * @version 2.2.1 + * + * A Barrier is a Waitable object that serves as synchronization points for + * a set of threads. A Barrier is constructed for a fixed number (N) of threads. + * Threads attempting to wait() on a Barrier ( 1 - N) will block until the Nth + * thread arrives. The Nth thread will awaken all the the others. + * + * An optional Runnable command may be associated with the Barrier. This will be run() + * when the Nth thread arrives and Barrier is not broken. + * + * Error Checking + * + * A Barrier uses an all-or-nothing. All threads involved must successfully + * meet at Barrier. If any one of those threads leaves before all the threads + * have (as the result of an error or exception) then all threads present at + * the Barrier will throw BrokenBarrier_Exception. + * + * A broken Barrier will cause all threads attempting to wait() on it to + * throw a BrokenBarrier_Exception. + * + * A Barrier will remain 'broken', until it is manually reset(). + */ + template + class Barrier : public Waitable, private NonCopyable { + + //! Broken flag + bool _broken; + //! Task flag + bool _haveTask; + //! Thread count + unsigned int _count; + //! Wait generation + unsigned int _generation; + //! Serialize access + LockType _lock; + //! Signaled when all thread arrive + Condition _arrived; + //! Command to run when all the thread arrive + Task _task; + + public: + + //! Create a Barrier + Barrier() + : _broken(false), _haveTask(false), _count(Count), _generation(0), _arrived(_lock), _task(0) { } + + /** + * Create a Barrier that executes the given task when all threads arrive + * without error + * + * @param task Task to associate with this Barrier + */ + Barrier(const Task& task) + : _broken(false), _haveTask(true), _count(Count), _generation(0), _arrived(_lock), + _task(task) { } + + //! Destroy this Barrier + virtual ~Barrier() {} + + /** + * Enter barrier and wait for the other threads to arrive. This can block for an indefinite + * amount of time. + * + * @exception BrokenBarrier_Exception thrown when any thread has left a wait on this + * Barrier as a result of an error. + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending a wait + * for one thread and breaking the barrier for all threads + * + * @see Waitable::wait() + * + * @post If no exception was thrown, all threads have successfully arrived + * @post If an exception was thrown, the barrier is broken + */ + virtual void wait() { + + Guard g(_lock); + + if(_broken) + throw BrokenBarrier_Exception(); + + // Break the barrier if an arriving thread is interrupted + if(Thread::interrupted()) { + + // Release the other waiter, propagate the exception + _arrived.broadcast(); + _broken = true; + + throw Interrupted_Exception(); + + } + + if(--_count == 0) { + + // Wake the other threads if this was the last + // arriving thread + _arrived.broadcast(); + + // Try to run the associated task, if it throws then + // break the barrier and propagate the exception + try { + + if(_task) + _task->run(); + + _generation++; + + } catch(Synchronization_Exception&) { + + _broken = true; + throw; + + } catch(...) { assert(0); } + + } else { + + int myGeneration = _generation; + + try { + + // Wait for the other threads to arrive + _arrived.wait(); + + } catch(Interrupted_Exception&) { + + // Its possible for a thread to be interrupted before the + // last thread arrives. If the interrupted thread hasn't + // resumed, then just propagate the interruption + + if(myGeneration != _generation) + Thread().interrupt(); + + else _broken = true; + + } catch(Synchronization_Exception&) { + + // Break the barrier and propagate the exception + _broken = true; + throw; + + } + + // If the thread woke because it was notified by the thread + // that broke the barrier, throw. + if(_broken) + throw BrokenBarrier_Exception(); + + } + + } + + /** + * Enter barrier and wait for the other threads to arrive. This can block up to the + * amount of time specified with the timeout parameter. The barrier will not break + * if a thread leaves this function due to a timeout. + * + * @param timeout maximum amount of time, in milliseconds, to wait before + * + * @return + * - true if the set of tasks being wait for complete before + * timeout milliseconds elapse. + * - false otherwise. + * + * @exception BrokenBarrier_Exception thrown when any thread has left a wait on this + * Barrier as a result of an error. + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending a wait + * for one thread and breaking the barrier for all threads + * + * @see Waitable::wait(unsigned long timeout) + * + * @post If no exception was thrown, all threads have successfully arrived + * @post If an exception was thrown, the barrier is broken + */ + virtual bool wait(unsigned long timeout) { + + Guard g(_lock); + + if(_broken) + throw BrokenBarrier_Exception(); + + // Break the barrier if an arriving thread is interrupted + if(Thread::interrupted()) { + + // Release the other waiter, propagate the exception + _arrived.broadcast(); + _broken = true; + + throw Interrupted_Exception(); + + } + + + if(--_count == 0) { + + // Wake the other threads if this was the last + // arriving thread + _arrived.broadcast(); + + // Try to run the associated task, if it throws then + // break the barrier and propagate the exception + try { + + if(_task) + _task->run(); + + _generation++; + + } catch(Synchronization_Exception&) { + + _broken = true; + throw; + + } catch(...) { assert(0); } + + } else { + + int myGeneration = _generation; + + try { + + // Wait for the other threads to arrive + if(!_arrived.wait(timeout)) + _broken = true; + + } catch(Interrupted_Exception&) { + + // Its possible for a thread to be interrupted before the + // last thread arrives. If the interrupted thread hasn't + // resumed, then just propagate the interruption + + if(myGeneration != _generation) + Thread().interrupt(); + + else _broken = true; + + } catch(Synchronization_Exception&) { + + // Break the barrier and propagate the exception + _broken = true; + throw; + + } + + // If the thread woke because it was notified by the thread + // that broke the barrier, throw. + if(_broken) + throw BrokenBarrier_Exception(); + + } + + return true; + + } + + /** + * Break the Barrier ending the wait for any threads that were waiting on + * the barrier. + * + * @post the Barrier is broken, all waiting threads will throw the + * BrokenBarrier_Exception + */ + void shatter() { + + Guard g(_lock); + + _broken = true; + _arrived.broadcast(); + + } + + /** + * Reset the Barrier. + * + * @post the Barrier is no longer Broken and can be used again. + */ + void reset() { + + Guard g(_lock); + + _broken = false; + _generation++; + _count = Count; + + } + + }; + + +} // namespace ZThread + +#endif // __ZTBARRIER_H__ diff --git a/dep/include/zthread/BiasedReadWriteLock.h b/dep/include/zthread/BiasedReadWriteLock.h new file mode 100644 index 000000000..b1de74292 --- /dev/null +++ b/dep/include/zthread/BiasedReadWriteLock.h @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTBIASEDREADWRITELOCK_H__ +#define __ZTBIASEDREADWRITELOCK_H__ + +#include "zthread/ReadWriteLock.h" +#include "zthread/Condition.h" +#include "zthread/Guard.h" +#include "zthread/FastMutex.h" + +namespace ZThread { + + /** + * @class BiasedReadWriteLock + * + * @author Eric Crahen + * @date <2003-07-16T10:22:34-0400> + * @version 2.2.7 + * + * A BiasedReadWriteLock has a bias toward writers. It will prefer read-write access over + * read-only access when many threads are contending for access to either Lockable this + * ReadWriteLock provides. + * + * @see ReadWriteLock + */ + class BiasedReadWriteLock : public ReadWriteLock { + + FastMutex _lock; + Condition _condRead; + Condition _condWrite; + + volatile int _activeWriters; + volatile int _activeReaders; + + volatile int _waitingReaders; + volatile int _waitingWriters; + + //! @class ReadLock + class ReadLock : public Lockable { + + BiasedReadWriteLock& _rwlock; + + public: + + ReadLock(BiasedReadWriteLock& rwlock) : _rwlock(rwlock) {} + + virtual ~ReadLock() {} + + virtual void acquire() { + _rwlock.beforeRead(); + } + + virtual bool tryAcquire(unsigned long timeout) { + return _rwlock.beforeReadAttempt(timeout); + } + + virtual void release() { + _rwlock.afterRead(); + } + + }; + + //! @class WriteLock + class WriteLock : public Lockable { + + BiasedReadWriteLock& _rwlock; + + public: + + WriteLock(BiasedReadWriteLock& rwlock) : _rwlock(rwlock) {} + + virtual ~WriteLock() {} + + + virtual void acquire() { + _rwlock.beforeWrite(); + } + + virtual bool tryAcquire(unsigned long timeout) { + return _rwlock.beforeWriteAttempt(timeout); + } + + virtual void release() { + _rwlock.afterWrite(); + } + + }; + + friend class ReadLock; + friend class WriteLock; + + ReadLock _rlock; + WriteLock _wlock; + + public: + + /** + * Create a BiasedReadWriteLock + * + * @exception Initialization_Exception thrown if resources could not be + * allocated for this object. + */ + BiasedReadWriteLock() : _condRead(_lock), _condWrite(_lock), _rlock(*this), _wlock(*this) { + + _activeWriters = 0; + _activeReaders = 0; + + _waitingReaders = 0; + _waitingWriters = 0; + + } + + //! Destroy this ReadWriteLock + virtual ~BiasedReadWriteLock() {} + + /** + * @see ReadWriteLock::getReadLock() + */ + virtual Lockable& getReadLock() { return _rlock; } + + /** + * @see ReadWriteLock::getWriteLock() + */ + virtual Lockable& getWriteLock() { return _wlock; } + + + protected: + + void beforeRead() { + + Guard guard(_lock); + + ++_waitingReaders; + + while(!allowReader()) { + + try { + + // wait + _condRead.wait(); + + } catch(...) { + + --_waitingReaders; + throw; + + } + + } + + --_waitingReaders; + ++_activeReaders; + + } + + bool beforeReadAttempt(unsigned long timeout) { + + Guard guard(_lock); + bool result = false; + + ++_waitingReaders; + + while(!allowReader()) { + + try { + + result = _condRead.wait(timeout); + + } catch(...) { + + --_waitingReaders; + throw; + + } + + } + + --_waitingReaders; + ++_activeReaders; + + return result; + } + + + void afterRead() { + + bool wakeReader = false; + bool wakeWriter = false; + + { + + Guard guard(_lock); + + --_activeReaders; + + wakeReader = (_waitingReaders > 0); + wakeWriter = (_waitingWriters > 0); + + } + + if(wakeWriter) + _condWrite.signal(); + + else if(wakeReader) + _condRead.signal(); + + } + + void beforeWrite() { + + Guard guard(_lock); + + ++_waitingWriters; + + while(!allowWriter()) { + + try { + + _condWrite.wait(); + + } catch(...) { + + --_waitingWriters; + throw; + + } + + } + + --_waitingWriters; + ++_activeWriters; + + } + + bool beforeWriteAttempt(unsigned long timeout) { + + Guard guard(_lock); + bool result = false; + + ++_waitingWriters; + + while(!allowWriter()) { + + try { + + result = _condWrite.wait(timeout); + + } catch(...) { + + --_waitingWriters; + throw; + } + + } + + --_waitingWriters; + ++_activeWriters; + + return result; + + } + + void afterWrite() { + + bool wakeReader = false; + bool wakeWriter = false; + + { + + Guard guard(_lock); + + --_activeWriters; + + wakeReader = (_waitingReaders > 0); + wakeWriter = (_waitingWriters > 0); + + } + + if(wakeWriter) + _condWrite.signal(); + + else if(wakeReader) + _condRead.signal(); + + } + + bool allowReader() { + return (_activeWriters == 0); + } + + bool allowWriter() { + return (_activeWriters == 0 && _activeReaders == 0); + } + + }; + +}; // __ZTBIASEDREADWRITELOCK_H__ + +#endif diff --git a/dep/include/zthread/BlockingQueue.h b/dep/include/zthread/BlockingQueue.h new file mode 100644 index 000000000..ac17347d1 --- /dev/null +++ b/dep/include/zthread/BlockingQueue.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTBLOCKINGQUEUE_H__ +#define __ZTBLOCKINGQUEUE_H__ + +#include "zthread/Guard.h" +#include "zthread/Condition.h" +#include "zthread/Queue.h" + +#include + +namespace ZThread { + + /** + * @class BlockingQueue + * @author Eric Crahen + * @date <2003-07-16T12:01:43-0400> + * @version 2.3.0 + * + * Like a LockedQueue, a BlockingQueue is a Queue implementation that provides + * serialized access to the items added to it. It differs by causing threads + * accessing the next() methods to block until a value becomes available. + */ + template > + class BlockingQueue : public Queue, public Lockable { + + //! Serialize access + LockType _lock; + + //! Signaled when empty + Condition _notEmpty; + + //! Storage backing the queue + StorageType _queue; + + //! Cancellation flag + volatile bool _canceled; + + public: + + //! Create a new BlockingQueue + BlockingQueue() : _notEmpty(_lock), _canceled(false) {} + + //! Destroy this BlockingQueue + virtual ~BlockingQueue() { } + + /** + * @see Queue::add(const T& item) + */ + virtual void add(const T& item) { + + Guard g(_lock); + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + + _notEmpty.signal(); + + } + + /** + * @see Queue::add(const T& item, unsigned long timeout) + */ + virtual bool add(T item, unsigned long timeout) { + + try { + + Guard g(_lock, timeout); + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + + _notEmpty.signal(); + + } catch(Timeout_Exception&) { return false; } + + return true; + + } + + /** + * Get a value from this Queue. The calling thread may block indefinitely. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before a value becomes available. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + * + * @see Queue::next() + */ + virtual T next() { + + Guard g(_lock); + + while(_queue.empty() && !_canceled) + _notEmpty.wait(); + + if( _queue.empty() ) + throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + return item; + + } + + + /** + * Get a value from this Queue. The calling thread may block indefinitely. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Timeout_Exception thrown if the timeout expires before a value + * can be retrieved. + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before a value becomes available. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + * + * @see Queue::next(unsigned long timeout) + */ + virtual T next(unsigned long timeout) { + + Guard g(_lock, timeout); + + while(_queue.empty() && !_canceled) { + if(!_notEmpty.wait(timeout)) + throw Timeout_Exception(); + } + + if(_queue.empty() ) + throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + return item; + + } + + + /** + * @see Queue::cancel() + * + * @post If threads are blocked on one of the next() functions then + * they will be awakened with a Cancellation_Exception. + */ + virtual void cancel() { + + Guard g(_lock); + + _notEmpty.broadcast(); + _canceled = true; + + } + + /** + * @see Queue::isCanceled() + */ + virtual bool isCanceled() { + + // Faster check since the queue will not become un-canceled + if(_canceled) + return true; + + Guard g(_lock); + + return _canceled; + + } + + /** + * @see Queue::size() + */ + virtual size_t size() { + + Guard g(_lock); + return _queue.size(); + + } + + /** + * @see Queue::size(unsigned long timeout) + */ + virtual size_t size(unsigned long timeout) { + + Guard g(_lock, timeout); + return _queue.size(); + + } + + public: + + virtual void acquire() { + _lock.acquire(); + } + + virtual bool tryAcquire(unsigned long timeout) { + return _lock.tryAcquire(timeout); + } + + virtual void release() { + _lock.release(); + } + + }; /* BlockingQueue */ + +} // namespace ZThread + +#endif // __ZTBLOCKINGQUEUE_H__ diff --git a/dep/include/zthread/BoundedQueue.h b/dep/include/zthread/BoundedQueue.h new file mode 100644 index 000000000..2b3a616f1 --- /dev/null +++ b/dep/include/zthread/BoundedQueue.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTBOUNDEDQUEUE_H__ +#define __ZTBOUNDEDQUEUE_H__ + +#include "zthread/Condition.h" +#include "zthread/Guard.h" +#include "zthread/Queue.h" + +#include + +namespace ZThread { + + /** + * @class BoundedQueue + * + * @author Eric Crahen + * @date <2003-07-16T13:54:04-0400> + * @version 2.3.0 + * + * A BoundedQueue provides serialized access to a set of values. It differs from other + * Queues by adding a maximum capacity, giving it the following properties: + * + * - Threads calling the empty() methods will be blocked until the BoundedQueue becomes empty. + * - Threads calling the next() methods will be blocked until the BoundedQueue has a value to + * return. + * - Threads calling the add() methods will be blocked until the number of values in the + * Queue drops below the maximum capacity. + * + * @see Queue + */ + template > + class BoundedQueue : public Queue, public Lockable { + + //! Maximum capacity for the Queue + size_t _capacity; + + //! Serialize access + LockType _lock; + + //! Signaled if not full + Condition _notFull; + + //! Signaled if not empty + Condition _notEmpty; + + //! Signaled if empty + Condition _isEmpty; + + //! Storage backing the queue + StorageType _queue; + + //! Cancellation flag + volatile bool _canceled; + + public: + + /** + * Create a BoundedQueue with the given capacity. + * + * @param capacity maximum number of values to allow in the Queue at + * at any time + */ + BoundedQueue(size_t capacity) + : _notFull(_lock), _notEmpty(_lock), _isEmpty(_lock), + _capacity(capacity), _canceled(false) {} + + //! Destroy this Queue + virtual ~BoundedQueue() { } + + /** + * Get the maximum capacity of this Queue. + * + * @return size_t maximum capacity + */ + size_t capacity() { + return _capacity; + } + + /** + * Add a value to this Queue. + * + * If the number of values in the queue matches the value returned by capacity() + * then the calling thread will be blocked until at least one value is removed from + * the Queue. + * + * @param item value to be added to the Queue + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Interrupted_Exception thrown if the thread was interrupted while waiting + * to add a value + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post If no exception is thrown, a copy of item will have been added to the Queue. + * + * @see Queue::add(const T& item) + */ + virtual void add(const T& item) { + + Guard g(_lock); + + // Wait for the capacity of the Queue to drop + while ((_queue.size() == _capacity) && !_canceled) + _notFull.wait(); + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + _notEmpty.signal(); // Wake any waiters + + + } + + /** + * Add a value to this Queue. + * + * If the number of values in the queue matches the value returned by capacity() + * then the calling thread will be blocked until at least one value is removed from + * the Queue. + * + * @param item value to be added to the Queue + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return + * - true if a copy of item can be added before timeout + * milliseconds elapse. + * - false otherwise. + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Interrupted_Exception thrown if the thread was interrupted while waiting + * to add a value + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post If no exception is thrown, a copy of item will have been added to the Queue. + * + * @see Queue::add(const T& item, unsigned long timeout) + */ + virtual bool add(const T& item, unsigned long timeout) { + + try { + + Guard g(_lock, timeout); + + // Wait for the capacity of the Queue to drop + while ((_queue.size() == _capacity) && !_canceled) + if(!_notFull.wait(timeout)) + return false; + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + _notEmpty.signal(); // Wake any waiters + + } catch(Timeout_Exception&) { return false; } + + return true; + + } + + /** + * Retrieve and remove a value from this Queue. + * + * If invoked when there are no values present to return then the calling thread + * will be blocked until a value arrives in the Queue. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Interrupted_Exception thrown if the thread was interrupted while waiting + * to retrieve a value + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + */ + virtual T next() { + + Guard g(_lock); + + while ( _queue.empty() && !_canceled) + _notEmpty.wait(); + + if( _queue.empty()) // Queue canceled + throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + _notFull.signal(); // Wake any thread trying to add + + if(_queue.empty()) // Wake empty waiters + _isEmpty.broadcast(); + + return item; + + } + + /** + * Retrieve and remove a value from this Queue. + * + * If invoked when there are no values present to return then the calling thread + * will be blocked until a value arrives in the Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Timeout_Exception thrown if the timeout expires before a value + * can be retrieved. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + */ + virtual T next(unsigned long timeout) { + + Guard g(_lock, timeout); + + // Wait for items to be added + while (_queue.empty() && !_canceled) { + if(!_notEmpty.wait(timeout)) + throw Timeout_Exception(); + } + + if(_queue.empty()) // Queue canceled + throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + _notFull.signal(); // Wake add() waiters + + if(_queue.empty()) // Wake empty() waiters + _isEmpty.broadcast(); + + return item; + + } + + /** + * Cancel this queue. + * + * @post Any threads blocked by an add() function will throw a Cancellation_Exception. + * @post Any threads blocked by a next() function will throw a Cancellation_Exception. + * + * @see Queue::cancel() + */ + virtual void cancel() { + + Guard g(_lock); + + _canceled = true; + _notEmpty.broadcast(); // Wake next() waiters + + } + + /** + * @see Queue::isCanceled() + */ + virtual bool isCanceled() { + + // Faster check since the Queue will not become un-canceled + if(_canceled) + return true; + + Guard g(_lock); + + return _canceled; + + } + + /** + * @see Queue::size() + */ + virtual size_t size() { + + Guard g(_lock); + return _queue.size(); + + } + + /** + * @see Queue::size(unsigned long timeout) + */ + virtual size_t size(unsigned long timeout) { + + Guard g(_lock, timeout); + return _queue.size(); + + } + + /** + * Test whether any values are available in this Queue. + * + * The calling thread is blocked until there are no values present + * in the Queue. + * + * @return + * - true if there are no values available. + * - false if there are values available. + * + * @see Queue::empty() + */ + virtual bool empty() { + + Guard g(_lock); + + while(!_queue.empty()) // Wait for an empty signal + _isEmpty.wait(); + + return true; + + + } + + + /** + * Test whether any values are available in this Queue. + * + * The calling thread is blocked until there are no values present + * in the Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return + * - true if there are no values available. + * - false if there are values available. + * + * @exception Timeout_Exception thrown if timeout milliseconds + * expire before a value becomes available + * + * @see Queue::empty() + */ + virtual bool empty(unsigned long timeout) { + + Guard g(_lock, timeout); + + while(!_queue.empty()) // Wait for an empty signal + _isEmpty.wait(timeout); + + return true; + + } + + public: + + virtual void acquire() { + _lock.acquire(); + } + + virtual bool tryAcquire(unsigned long timeout) { + return _lock.tryAcquire(timeout); + } + + virtual void release() { + _lock.release(); + } + + }; /* BoundedQueue */ + +} // namespace ZThread + +#endif // __ZTBOUNDEDQUEUE_H__ diff --git a/dep/include/zthread/Cancelable.h b/dep/include/zthread/Cancelable.h new file mode 100644 index 000000000..9151ec8dd --- /dev/null +++ b/dep/include/zthread/Cancelable.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCANCELABLE_H__ +#define __ZTCANCELABLE_H__ + +#include "zthread/Exceptions.h" + +namespace ZThread { + + /** + * @class Cancelable + * + * @author Eric Crahen + * @date <2003-07-16T09:28:46-0400> + * @version 2.3.0 + * + * The Cancelable interface defines a common method of adding general disable-and-exit + * semantics to some object. By cancel()ing a Cancelable object, a request is + * made to disable that object. + * + * Disabling + * + * A cancel()ed object may not necessarily abort it work immediately. Often, it much more + * elegant for a cancel()ed object to complete handling whatever responsibilities have + * been assigned to it, but it will not take on any new responsibility. + * + * Exiting + * + * A cancel()ed should complete its responsibilities as soon as possible. + * Canceling is not only a request to stop taking on new responsibility, and to + * complete its current responsibility. Its also a request to complete dealing with its + * current responsibilities, quickly when possible. + */ + class Cancelable { + public: + + //! Destroy a Cancelable object. + virtual ~Cancelable() {} + + /** + * Canceling a Cancelable object makes a request to disable that object. + * This entails refusing to take on any new responsibility, and completing + * its current responsibilities quickly. + * + * Canceling an object more than once has no effect. + * + * @post The Cancelable object will have permanently transitioned to a + * disabled state; it will now refuse to accept new responsibility. + */ + virtual void cancel() = 0; + + /** + * Determine if a Cancelable object has been canceled. + * + * @return + * - true if cancel() was called prior to this function. + * - false otherwise. + */ + virtual bool isCanceled() = 0; + + }; /* Cancelable */ + + +} // namespace ZThread + +#endif // __ZTCANCELABLE_H__ diff --git a/dep/include/zthread/ClassLockable.h b/dep/include/zthread/ClassLockable.h new file mode 100644 index 000000000..a10fb4932 --- /dev/null +++ b/dep/include/zthread/ClassLockable.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCLASSLOCKABLE_H__ +#define __ZTCLASSLOCKABLE_H__ + +#include "zthread/CountedPtr.h" +#include "zthread/Mutex.h" + +namespace ZThread { + + /** + * @class ClassLockable + * + * @author Eric Crahen + * @date <2003-07-16T23:37:38-0400> + * @version 2.3.0 + * + * + */ + template + class ClassLockable : public Lockable { + + static CountedPtr _instance; + CountedPtr _lock; + + public: + + //! Create a ClassLockable + ClassLockable() + : _lock(_instance) {} + + //! acquire() the ClassLockable + virtual void acquire() { + _lock->acquire(); + } + + //! tryAcquire() the ClassLockable + virtual bool tryAcquire(unsigned long timeout) { + return _lock->tryAcquire(timeout); + } + + //! release() the ClassLockable + virtual void release() { + _lock->release(); + } + + }; + + template + CountedPtr ClassLockable::_instance(new LockType); + +} // namespace ZThread + +#endif // __ZTCLASSLOCKABLE_H__ diff --git a/dep/include/zthread/ConcurrentExecutor.h b/dep/include/zthread/ConcurrentExecutor.h new file mode 100644 index 000000000..199fe306e --- /dev/null +++ b/dep/include/zthread/ConcurrentExecutor.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCONCURRENTEXECUTOR_H__ +#define __ZTCONCURRENTEXECUTOR_H__ + +#include "zthread/PoolExecutor.h" + +namespace ZThread { + + /** + * @class ConcurrentExecutor + * + * @author Eric Crahen + * @date <2003-07-16T22:36:11-0400> + * @version 2.3.0 + * + * A ConcurrentExecutor spawns a single thread to service a series of Tasks. + * + * @see PoolExecutor. + */ + class ConcurrentExecutor : public Executor { + + PoolExecutor _executor; + + public: + + //! Create a ConcurrentExecutor + ConcurrentExecutor(); + + /** + * Interrupting a ConcurrentExecutor will cause the thread running the tasks to be + * be interrupted once during the execution of each task that has been submitted + * at the time this function is called. + * + * Tasks that are submitted after this function is called will + * not be interrupt()ed; unless this function is invoked again(). + * + * @code + * + * void aFunction() { + * + * ConcurrentExecutor executor; + * + * // Submit p Tasks + * for(size_t n = 0; n < p; n++) + * executor.execute(new aRunnable); + * + * // Tasks [m, p) may be interrupted, where m is the first task that has + * // not completed at the time the interrupt() is invoked. + * executor.interrupt(); + * + * // Submit (q - p) Tasks + * for(size_t n = p; n < q; n++) + * executor.execute(new Chore); + * + * // Tasks [p, q) are not interrupted + * + * } + * + * @endcode + */ + virtual void interrupt(); + + /** + * Submit a Task to this Executor. This will not block the current thread + * for very long. The task will be enqueued internally and eventually run + * in the context of the single thread driving all the Tasks submitted to this + * Executor. + * + * @exception Cancellation_Exception thrown if this Executor has been canceled. + * The Task being submitted will not be executed by this Executor. + * + * @exception Synchronization_Exception thrown only in the event of an error + * in the implementation of the library. + * + * @see Executor::execute(const Task&) + */ + virtual void execute(const Task&); + + /** + * @see Cancelable::cancel() + */ + virtual void cancel(); + + /** + * @see Cancelable::isCanceled() + */ + virtual bool isCanceled(); + + /** + * @see PoolExecutor::wait() + */ + virtual void wait(); + + /** + * @see PoolExecutor::wait(unsigned long timeout) + */ + virtual bool wait(unsigned long timeout); + + }; /* ConcurrentExecutor */ + +} // namespace ZThread + +#endif // __ZTCONCURRENTEXECUTOR_H__ diff --git a/dep/include/zthread/Condition.h b/dep/include/zthread/Condition.h new file mode 100644 index 000000000..eba93619b --- /dev/null +++ b/dep/include/zthread/Condition.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCONDITION_H__ +#define __ZTCONDITION_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" +#include "zthread/Waitable.h" + +namespace ZThread { + + class FifoConditionImpl; + + /** + * @class Condition + * @author Eric Crahen + * @date <2003-07-16T14:38:59-0400> + * @version 2.2.1 + * + * A Condition is a Waitable object used to block a thread until a particular + * condition is met. A Condition object is always used in conjunction with Lockable + * object. This object should be a FastMutex, Mutex, PriorityMutex or PriorityInheritanceMutex. + * + * Condition objects are reminiscent of POSIX condition variables in several ways but + * are slightly different. + * + * A Condition is not subject to spurious wakeup. + * + * Like all Waitable objects, Conditions are sensitive to Thread::interupt() which can + * be used to prematurely end a wait(). + * + * @see Thread::interupt() + * + * Before a wait() is performed on a Condition, the associated Lockable object should + * have been acquire()ed. When the wait() begins, that Lockable object is release()d + * (wait() will atomically begin the wait and unlock the Lockable). + * + * A thread blocked by wait() will remain so until an exception occurs, or until + * the thread awakened by a signal() or broadcast(). When the thread resumes execution, + * the associated Lockable is acquire()d before wait() returns. + * + * Scheduling + * + * Threads blocked on a Condition are resumed in FIFO order. + */ + class ZTHREAD_API Condition : public Waitable, private NonCopyable { + + FifoConditionImpl* _impl; + + public: + + /** + * Create a Condition associated with the given Lockable object. + * + * @param l Lockable object to associate with this Condition object. + */ + Condition(Lockable& l); + + //! Destroy Condition object + virtual ~Condition(); + + /** + * Wake one thread waiting on this Condition. + * + * The associated Lockable need not have been acquire when this function is + * invoked. + * + * @post a waiting thread, if any exists, will be awakened. + */ + void signal(); + + /** + * Wake all threads wait()ing on this Condition. + * + * The associated Lockable need not have been acquire when this function is + * invoked. + * + * @post all wait()ing threads, if any exist, will be awakened. + */ + void broadcast(); + + /** + * Wait for this Condition, blocking the calling thread until a signal or broadcast + * is received. + * + * This operation atomically releases the associated Lockable and blocks the calling thread. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @pre The thread calling this method must have first acquired the associated + * Lockable object. + * + * @post A thread that has resumed execution without exception (because of a signal(), + * broadcast() or exception) will have acquire()d the associated Lockable object + * before returning from a wait(). + * + * @see Waitable::wait() + */ + virtual void wait(); + + /** + * Wait for this Condition, blocking the calling thread until a signal or broadcast + * is received. + * + * This operation atomically releases the associated Lockable and blocks the calling thread. + * + * @param timeout maximum amount of time (milliseconds) this method could block + * + * @return + * - true if the Condition receives a signal or broadcast before + * timeout milliseconds elapse. + * - false otherwise. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @pre The thread calling this method must have first acquired the associated + * Lockable object. + * + * @post A thread that has resumed execution without exception (because of a signal(), + * broadcast() or exception) will have acquire()d the associated Lockable object + * before returning from a wait(). + * + * @see Waitable::wait(unsigned long timeout) + */ + virtual bool wait(unsigned long timeout); + + + }; + +} // namespace ZThread + +#endif // __ZTCONDITION_H__ diff --git a/dep/include/zthread/Config.h b/dep/include/zthread/Config.h new file mode 100644 index 000000000..21e08bf84 --- /dev/null +++ b/dep/include/zthread/Config.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCONFIG_H__ +#define __ZTCONFIG_H__ + +// ===================================================================================== +// The following section describes the symbols the configure program will define. +// If you are not using configure (autoconf), then you make want to set these by +// uncommenting them here, or whatever other means you'd like. +// ===================================================================================== + +// (configure) +// Uncomment to disable actually changing the operating systems real thread priority +// #define ZTHREAD_DISABLE_PRIORITY 1 + +// (configure) +// Uncomment to disable compiling the interrupt() hook mechanisms. +// #define ZTHREAD_DISABLE_INTERRUPT 1 + +// (configure) +// Uncomment to select a Win32 ThreadOps implementation that uses _beginthreadex() +// otherwise, CreateThread() will be used for a Windows compilation +// #define HAVE_BEGINTHREADEX 1 + +// (configure) +// Uncomment to select a pthreads based implementation +// #define ZT_POSIX 1 + +// (configure) +// Uncomment to select a Windows based implementation that uses features not +// supported by windows 98 and 95 +// #define ZT_WIN32 1 + +// (configure) +// Uncomment to select a Windows based implementation that does not use features not +// supported by windows 98 and 95, but may not be compatible with 64 bit or alpha systems +// #define ZT_WIN9X 1 + +// (configure) +// Uncomment to select a MacOS based implementation +// #define ZT_MACOS 1 + +// (configure) +// Uncomment to prefer vanilla implementations of primatives when possible +// #define ZT_VANILLA 1 + +// ===================================================================================== +// The following section can be customized to select the implementation that is compiled +// Eventually, the configure program will be updated to define these symbols as well. +// ===================================================================================== + +// Uncomment to select very simple spinlock based implementations +// #define ZTHREAD_USE_SPIN_LOCKS 1 + +// Uncomment to select the vannila dual mutex implementation of FastRecursiveLock +// #define ZTHREAD_DUAL_LOCKS 1 + +// Uncomment to select a POSIX implementation of FastRecursiveLock that does not +// spin, but instead sleeps on a condition variable. +// #define ZTHREAD_CONDITION_LOCKS 1 + +// Uncomment if you want to eliminate inlined code used as a part of some template classes +// #define ZTHREAD_NOINLINE + +// Uncomment if you want to compile a DLL version of the library. (Win32) +// #define ZTHREAD_EXPORTS 1 + +// Uncomment if you want to compile a client using the DLL version of the library. (Win32) +// #define ZTHREAD_IMPORTS 1 + +// =================================================================================== +// The following section will attempt to guess the best configuration for your system +// =================================================================================== + +// Select an implementation by checking out the environment, first looking for +// compilers, then by looking for other definitions that could be present + +#if !defined(ZT_POSIX) && !defined(ZT_WIN9X) && !defined(ZT_WIN32) && !defined(ZT_MACOS) + +// Check for well known compilers +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__BCPLUSPLUS__) || defined(__MINGW32__) + +# define ZT_WIN32 + +#elif defined(__CYGWIN__) + +# define ZT_POSIX + +// Check for well known platforms +#elif defined(__linux__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__hpux) || \ + defined(__sgi) || \ + defined(__sun) + +# define ZT_POSIX + +// Check for definitions from well known headers +#elif defined(_POSIX_SOURCE) || defined(_XOPEN_SOURCE) + +# define ZT_POSIX + +#elif defined(WIN32_LEAN_AND_MEAN) + +# define ZT_WIN32 + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + +# define ZT_MACOS + +#else +# error "Could not select implementation, define ZT_WIN9X, ZT_WIN32, ZT_POSIX or ZT_MACOS" +#endif + +#endif + +// Once an implementation has been selected, configure the API decorator +// for shared libraries if its needed. + +#if defined(ZTHREAD_SHARED) // Compatibility w/ past releases + +# define ZTHREAD_IMPORTS + +#elif defined(ZTHREAD_STATIC) + +# undef ZTHREAD_EXPORTS +# undef ZTHREAD_IMPORTS + +#endif + +// Windows users will get a static build by default, unless they +// define either ZTHREAD_IMPORTS or ZTHREAD_EXPORTS. Client code +// of a dll version of this library should define the first flag; +// To build the dll version of this library, define the second. + +#if defined(ZTHREAD_IMPORTS) && defined(ZTHREAD_EXPORTS) +# error "Import and export declarations are not valid" +#else + +# if defined(ZTHREAD_IMPORTS) +# define ZTHREAD_API __declspec(dllimport) +# elif defined(ZTHREAD_EXPORTS) +# define ZTHREAD_API __declspec(dllexport) +# else +# define ZTHREAD_API +# endif + +#endif + +// Once the API decorator is configured, create a macro for +// explicit template instantiation (whose need can hopefully +// be removed from the library) + +#if defined(ZTHREAD_EXPORTS) +# define EXPLICIT_TEMPLATE(X) template class __declspec( dllexport ) X; +#elif defined(ZTHREAD_IMPORTS) +# define EXPLICIT_TEMPLATE(X) template class __declspec( dllimport ) X; +#else +# define EXPLICIT_TEMPLATE(X) +#endif + +// Give libc a hint, should be defined by the user - but people tend +// to forget. + +#if !defined(REENTRANT) +# define REENTRANT +#endif + +#if !defined(_REENTRANT) +# define _REENTRANT +#endif + +#if defined(_MSC_VER) +# pragma warning(disable:4275) +# pragma warning(disable:4290) +# pragma warning(disable:4786) +# pragma warning(disable:4251) +# pragma warning(disable:4355) +#endif + +// Ensure that only one implementation is selected +#if \ +(defined(ZT_POSIX) && defined(ZT_WIN32)) \ + || (defined(ZT_POSIX) && defined(ZT_WIN9X)) \ + || (defined(ZT_WIN32) && defined(ZT_WIN9X)) + +# error "Only one implementation should be selected!" + +#endif + +#if defined(ZTHREAD_NOINLINE) +# define ZTHREAD_INLINE +#else +# define ZTHREAD_INLINE inline +#endif + +#endif // __ZTCONFIG_H__ + diff --git a/dep/include/zthread/CountedPtr.h b/dep/include/zthread/CountedPtr.h new file mode 100644 index 000000000..a4dcc6ef2 --- /dev/null +++ b/dep/include/zthread/CountedPtr.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCOUNTEDPTR_H__ +#define __ZTCOUNTEDPTR_H__ + +#include +#include + +#include "zthread/AtomicCount.h" + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4786) // warning: long template symbol name +# pragma warning(push) +# pragma warning(disable:4284) // warning: odd return type for operator-> +#endif + +namespace ZThread { + + /** + * @class CountedPtr + * + * @author Eric Crahen + * @date <2003-07-29T06:43:48-0400> + * @version 2.3.0 + * + */ + template + class CountedPtr { + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + template friend class CountedPtr; +#endif +#endif + + CountT* _count; + T* _instance; + + public: + + CountedPtr() : _count(0), _instance(0) { } + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + explicit CountedPtr(T* raw) : _count(new CountT()), _instance(raw) { + (*_count)++; + } + +#endif +#endif + + template + explicit CountedPtr(U* raw) : _count(new CountT()), _instance(raw) { + (*_count)++; + } + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + CountedPtr(const CountedPtr& ptr) : _count(ptr._count), _instance(ptr._instance) { + + if(_count) + (*_count)++; + + } + +#endif +#endif + + template + CountedPtr(const CountedPtr& ptr) : _count(ptr._count), _instance(ptr._instance) { + + if(_count) + (*_count)++; + + } + + ~CountedPtr() { + + if(_count && --(*_count) == 0) { + + if(_instance) + delete _instance; + + delete _count; + + } + + } + + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + const CountedPtr& operator=(const CountedPtr& ptr) { + + typedef CountedPtr ThisT; + + ThisT(ptr).swap(*this); + return *this; + + } + +#endif +#endif + + template + const CountedPtr& operator=(const CountedPtr& ptr) { + + typedef CountedPtr ThisT; + + ThisT(ptr).swap(*this); + return *this; + + } + + void reset() { + + typedef CountedPtr ThisT; + ThisT().swap(*this); + + } + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + void swap(CountedPtr& ptr) { + + std::swap(_count, ptr._count); + std::swap(_instance, ptr._instance); + + } + +#endif +#endif + + template + void swap(CountedPtr& ptr) { + + std::swap(_count, ptr._count); + std::swap(_instance, ptr._instance); + + } + + // Convience operators + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + bool less(const CountedPtr& ptr) const { + return _instance < ptr._instance; + } + +#endif +#endif + + template + bool less(const CountedPtr& ptr) const { + return _instance < ptr._instance; + } + + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + bool equal(const CountedPtr& ptr) const { + return _count == ptr._count; + } + +#endif +#endif + + template + bool equal(const CountedPtr& ptr) const { + return _count == ptr._count; + } + + + friend inline bool operator==(const CountedPtr& lhs, const CountedPtr& rhs) { + return lhs.equal(rhs); + } + + friend inline bool operator<(const CountedPtr& lhs, const CountedPtr& rhs) { + return lhs.less(rhs); + } + + + T& operator*() { + assert(_instance != 0); + return *_instance; + } + + T* operator->() { + assert(_instance != 0); + return _instance; + } + + const T* operator->() const { + assert(_instance != 0); + return _instance; + } + + bool operator!() const { + return _instance == 0; + } + + operator bool() const { + return _instance != 0; + } + + }; /* CountedPtr */ + + template + inline bool operator<(CountedPtr const &lhs, CountedPtr const &rhs) { + return lhs.less(rhs); + } + + template + inline bool operator==(CountedPtr const &lhs, CountedPtr const &rhs) { + return lhs.equal(rhs.get); + } + + template + inline bool operator!=(CountedPtr const &lhs, CountedPtr const &rhs) { + return !(lhs.equal(rhs.get)); + } + + template + inline void swap(CountedPtr const &lhs, CountedPtr const &rhs) { + lhs.swap(rhs); + } + +#if !defined(__MWERKS__) +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + template + inline bool operator<(CountedPtr const &lhs, CountedPtr const &rhs) { + return lhs.less(rhs); + } + + template + inline bool operator==(CountedPtr const &lhs, CountedPtr const &rhs) { + return lhs.equal(rhs.get); + } + + template + inline bool operator!=(CountedPtr const &lhs, CountedPtr const &rhs) { + return !(lhs.equal(rhs.get)); + } + + template + inline void swap(CountedPtr const &lhs, CountedPtr const &rhs) { + lhs.swap(rhs); + } + +#endif +#endif + +} // namespace ZThread + +#ifdef _MSC_VER +# pragma warning(pop) +# pragma warning(pop) +#endif + + +#endif // __ZTCOUNTEDPTR_H__ diff --git a/dep/include/zthread/CountingSemaphore.h b/dep/include/zthread/CountingSemaphore.h new file mode 100644 index 000000000..f580a65f7 --- /dev/null +++ b/dep/include/zthread/CountingSemaphore.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCOUNTINGSEMAPHORE_H__ +#define __ZTCOUNTINGSEMAPHORE_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class FifoSemaphoreImpl; + + /** + * @class CountingSemaphore + * @author Eric Crahen + * @date <2003-07-16T15:26:18-0400> + * @version 2.2.1 + * + * A CountingSemaphore is an owner-less Lockable object. + * + * It differs from a normal Semaphore in that there is no upper bound on the count + * and it will not throw an exception because a maximum value has been exceeded. + * + * @see Semaphore + * + * Threads blocked on a CountingSemaphore are resumed in FIFO order. + */ + class ZTHREAD_API CountingSemaphore : public Lockable, private NonCopyable { + + FifoSemaphoreImpl* _impl; + + public: + + /** + * Create a new CountingSemaphore. + * + * @param count - initial count + */ + CountingSemaphore(int initialCount = 0); + + //! Destroy the CountingSemaphore + virtual ~CountingSemaphore(); + + /** + * Provided to reflect the traditional Semaphore semantics + * + * @see acquire() + */ + void wait(); + + + /** + * Provided to reflect the traditional Semaphore semantics + * + * @see tryAcquire(unsigned long timeout) + */ + bool tryWait(unsigned long timeout); + + /** + * Provided to reflect the traditional Semaphore semantics + * + * @see release() + */ + void post(); + + + /** + * Get the current count of the semaphore. + * + * This value may change immediately after this function returns to the calling thread. + * + * @return int count + */ + virtual int count(); + + /** + * Decrement the count, blocking that calling thread if the count becomes 0 or + * less than 0. The calling thread will remain blocked until the count is + * raised above 0, an exception is thrown or the given amount of time expires. + * + * @param timeout maximum amount of time (milliseconds) this method could block + * + * @return + * - true if the Semaphore was acquired before timeout milliseconds elapse. + * - false otherwise. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @see Lockable::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + /** + * Decrement the count, blocking that calling thread if the count becomes 0 or + * less than 0. The calling thread will remain blocked until the count is + * raised above 0 or if an exception is thrown. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @see Lockable::acquire() + */ + virtual void acquire(); + + /** + * Increment the count, unblocking one thread if count is positive. + * + * @see Lockable::release() + */ + virtual void release(); + + }; + + +} // namespace ZThread + +#endif // __ZTCOUNTINGSEMAPHORE_H__ diff --git a/dep/include/zthread/Exceptions.h b/dep/include/zthread/Exceptions.h new file mode 100644 index 000000000..b7207932a --- /dev/null +++ b/dep/include/zthread/Exceptions.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTEXCEPTIONS_H__ +#define __ZTEXCEPTIONS_H__ + + +#include "zthread/Config.h" +#include + +namespace ZThread { + +/** + * @class Synchronization_Exception + * + * Serves as a general base class for the Exception hierarchy used within + * this package. + * + */ +class Synchronization_Exception { + + // Restrict heap allocation + static void * operator new(size_t size); + static void * operator new[](size_t size); + + std::string _msg; + +public: + + /** + * Create a new exception with a default error message 'Synchronization + * Exception' + */ + Synchronization_Exception() : _msg("Synchronization exception") { } + + /** + * Create a new exception with a given error message + * + * @param const char* - error message + */ + Synchronization_Exception(const char* msg) : _msg(msg) { } + + /** + * Get additional info about the exception + * + * @return const char* for the error message + */ + const char* what() const { + return _msg.c_str(); + } + +}; + + +/** + * @class Interrupted_Exception + * + * Used to describe an interrupted operation that would have normally + * blocked the calling thread + */ +class Interrupted_Exception : public Synchronization_Exception { + + public: + + //! Create a new exception + Interrupted_Exception() : Synchronization_Exception("Thread interrupted") { } + + //! Create a new exception + Interrupted_Exception(const char* msg) : Synchronization_Exception(msg) { } + +}; + + + +/** + * @class Deadlock_Exception + * + * Thrown when deadlock has been detected + */ +class Deadlock_Exception : public Synchronization_Exception { + public: + + //! Create a new exception + Deadlock_Exception() : Synchronization_Exception("Deadlock detected") { } + + //! Create a new exception + Deadlock_Exception(const char* msg) : Synchronization_Exception(msg) { } + +}; + + +/** + * @class InvalidOp_Exception + * + * Thrown when performing an illegal operation this object + */ +class InvalidOp_Exception : public Synchronization_Exception { + public: + + //! Create a new exception + InvalidOp_Exception() : Synchronization_Exception("Invalid operation") { } + //! Create a new exception + InvalidOp_Exception(const char* msg) : Synchronization_Exception(msg) { } + +}; + + + +/** + * @class Initialization_Exception + * + * Thrown when the system has no more resources to create new + * synchronization controls + */ +class Initialization_Exception : public Synchronization_Exception { + + public: + + //! Create a new exception + Initialization_Exception() : Synchronization_Exception("Initialization error") { } + //! Create a new exception + Initialization_Exception(const char*msg) : Synchronization_Exception(msg) { } + +}; + +/** + * @class Cancellation_Exception + * + * Cancellation_Exceptions are thrown by 'Canceled' objects. + * @see Cancelable + */ +class Cancellation_Exception : public Synchronization_Exception { + + public: + + //! Create a new Cancelltion_Exception + Cancellation_Exception() : Synchronization_Exception("Canceled") { } + //! Create a new Cancelltion_Exception + Cancellation_Exception(const char*msg) : Synchronization_Exception(msg) { } + +}; + + +/** + * @class Timeout_Exception + * + * There is no need for error messaged simply indicates the last + * operation timed out + */ +class Timeout_Exception : public Synchronization_Exception { + public: + + //! Create a new Timeout_Exception + Timeout_Exception() : Synchronization_Exception("Timeout") { } + //! Create a new + Timeout_Exception(const char*msg) : Synchronization_Exception(msg) { } + +}; + +/** + * @class NoSuchElement_Exception + * + * The last operation that was attempted on a Queue could not find + * the item that was indicated (during that last Queue method invocation) + */ +class NoSuchElement_Exception { + public: + + //! Create a new exception + NoSuchElement_Exception() {} + +}; + +/** + * @class InvalidTask_Exception + * + * Thrown when a task is not valid (e.g. null or start()ing a thread with + * no overriden run() method) + */ +class InvalidTask_Exception : public InvalidOp_Exception { + public: + + //! Create a new exception + InvalidTask_Exception() : InvalidOp_Exception("Invalid task") {} + +}; + +/** + * @class BrokenBarrier_Exception + * + * Thrown when a Barrier is broken because one of the participating threads + * has been interrupted. + */ +class BrokenBarrier_Exception : public Synchronization_Exception { + + public: + + //! Create a new exception + BrokenBarrier_Exception() : Synchronization_Exception("Barrier broken") { } + + //! Create a new exception + BrokenBarrier_Exception(const char* msg) : Synchronization_Exception(msg) { } + +}; + +/** + * @class Future_Exception + * + * Thrown when there is an error using a Future. + */ +class Future_Exception : public Synchronization_Exception { + + public: + + //! Create a new exception + Future_Exception() : Synchronization_Exception() { } + + //! Create a new exception + Future_Exception(const char* msg) : Synchronization_Exception(msg) { } + +}; + +}; + +#endif // __ZTEXCEPTIONS_H__ diff --git a/dep/include/zthread/Executor.h b/dep/include/zthread/Executor.h new file mode 100644 index 000000000..833d0d4c3 --- /dev/null +++ b/dep/include/zthread/Executor.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTEXECUTOR_H__ +#define __ZTEXECUTOR_H__ + +#include "zthread/Thread.h" +#include "zthread/Waitable.h" + +namespace ZThread { + + + /** + * @class Executor + * + * @author Eric Crahen + * @date <2003-07-16T22:39:39-0400> + * @version 2.3.0 + * + * Execeutors are an implementation of the Executor pattern. This is + * a more versatile construct than a thread pool. A paper describing can + * be found in the proceedings of the 2002 VikingPLOP conference. + * + * Executing + * + * - execute()ing task with an Executor will submit the task, scheduling + * it for execution at some future time depending on the Executor being used. + * + * Disabling + * + * - cancel()ing an Executor will cause it to stop accepting + * new tasks. + * + * Interrupting + * + * - interrupt()ing an Executor will cause the any thread running + * a task which was submitted prior to the invocation of this function to + * be interrupted during the execution of that task. + * + * Waiting + * + * - wait()ing on a PoolExecutor will block the calling thread + * until all tasks that were submitted prior to the invocation of this function + * have completed. + * + * @see Cancelable + * @see Waitable + */ + class Executor : public Cancelable, public Waitable, private NonCopyable { + public: + + /** + * If supported by the Executor, interrupt all tasks submitted prior to + * the invocation of this function. + */ + virtual void interrupt() = 0; + + /** + * Submit a task to this Executor. + * + * @param task Task to be run by a thread managed by this executor + * + * @pre The Executor should have been canceled prior to this invocation. + * @post The submitted task will be run at some point in the future by this Executor. + * + * @exception Cancellation_Exception thrown if the Executor was canceled prior to + * the invocation of this function. + */ + virtual void execute(const Task& task) = 0; + + }; + +} // namespace ZThread + +#endif // __ZTEXECUTOR_H__ diff --git a/dep/include/zthread/FairReadWriteLock.h b/dep/include/zthread/FairReadWriteLock.h new file mode 100644 index 000000000..8f183b628 --- /dev/null +++ b/dep/include/zthread/FairReadWriteLock.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFAIRREADWRITELOCK_H__ +#define __ZTFAIRREADWRITELOCK_H__ + +#include "zthread/ReadWriteLock.h" +#include "zthread/Condition.h" +#include "zthread/Guard.h" +#include "zthread/Mutex.h" + +namespace ZThread { + + /** + * @class FairReadWriteLock + * + * @author Eric Crahen + * @date <2003-07-16T10:26:25-0400> + * @version 2.2.7 + * + * A FairReadWriteLock maintains a balance between the order read-only access + * and read-write access is allowed. Threads contending for the pair of Lockable + * objects this ReadWriteLock provides will gain access to the locks in FIFO order. + * + * @see ReadWriteLock + */ + class FairReadWriteLock : public ReadWriteLock { + + Mutex _lock; + Condition _cond; + + volatile int _readers; + + //! @class ReadLock + class ReadLock : public Lockable { + + FairReadWriteLock& _rwlock; + + public: + + ReadLock(FairReadWriteLock& rwlock) : _rwlock(rwlock) {} + + virtual ~ReadLock() {} + + virtual void acquire() { + + Guard g(_rwlock._lock); + ++_rwlock._readers; + + } + + virtual bool tryAcquire(unsigned long timeout) { + + if(!_rwlock._lock.tryAcquire(timeout)) + return false; + + ++_rwlock._readers; + _rwlock._lock.release(); + + return true; + } + + virtual void release() { + + Guard g(_rwlock._lock); + --_rwlock._readers; + + if(_rwlock._readers == 0) + _rwlock._cond.signal(); + + } + + }; + + //! @class WriteLock + class WriteLock : public Lockable { + + FairReadWriteLock& _rwlock; + + public: + + WriteLock(FairReadWriteLock& rwlock) : _rwlock(rwlock) {} + + virtual ~WriteLock() {} + + virtual void acquire() { + + _rwlock._lock.acquire(); + + try { + + while(_rwlock._readers > 0) + _rwlock._cond.wait(); + + } catch(...) { + + _rwlock._lock.release(); + throw; + + } + + } + + virtual bool tryAcquire(unsigned long timeout) { + + if(!_rwlock._lock.tryAcquire(timeout)) + return false; + + try { + + while(_rwlock._readers > 0) + _rwlock._cond.wait(timeout); + + } catch(...) { + + _rwlock._lock.release(); + throw; + + } + + return true; + + } + + virtual void release() { + _rwlock._lock.release(); + } + + }; + + friend class ReadLock; + friend class WriteLock; + + ReadLock _rlock; + WriteLock _wlock; + + public: + + /** + * Create a BiasedReadWriteLock + * + * @exception Initialization_Exception thrown if resources could not be + * allocated for this object. + */ + FairReadWriteLock() : _cond(_lock), _readers(0), _rlock(*this), _wlock(*this) {} + + //! Destroy this ReadWriteLock + virtual ~FairReadWriteLock() {} + + /** + * @see ReadWriteLock::getReadLock() + */ + virtual Lockable& getReadLock() { return _rlock; } + + /** + * @see ReadWriteLock::getWriteLock() + */ + virtual Lockable& getWriteLock() { return _wlock; } + + }; + +}; // __ZTFAIRREADWRITELOCK_H__ + +#endif diff --git a/dep/include/zthread/FastMutex.h b/dep/include/zthread/FastMutex.h new file mode 100644 index 000000000..1812c3e55 --- /dev/null +++ b/dep/include/zthread/FastMutex.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTMUTEX_H__ +#define __ZTFASTMUTEX_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class FastLock; + + /** + * @class FastMutex + * @author Eric Crahen + * @date <2003-07-19T18:45:39-0400> + * @version 2.2.0 + * + * A FastMutex is a small fast implementation of a non-recursive, mutually exclusive + * Lockable object. This implementation is a bit faster than the other Mutex classes + * as it involved the least overhead. However, this slight increase in speed is + * gained by sacrificing the robustness provided by the other classes. + * + * A FastMutex has the useful property of not being interruptable; that is to say + * that acquire() and tryAcquire() will not throw Interrupted_Exceptions. + * + * @see Mutex + * + * Scheduling + * + * Scheduling is left to the operating systems and may vary. + * + * Error Checking + * + * No error checking is performed, this means there is the potential for deadlock. + */ + class ZTHREAD_API FastMutex : public Lockable, private NonCopyable { + + FastLock* _lock; + + public: + + //! Create a FastMutex + FastMutex(); + + //! Destroy a FastMutex + virtual ~FastMutex(); + + /** + * Acquire exclusive access to the mutex. The calling thread will block until the + * lock can be acquired. No safety or state checks are performed. + * + * @pre The calling thread should not have previously acquired this lock. + * Deadlock will result if the same thread attempts to acquire the mutex more + * than once. + * + * @post The calling thread obtains the lock successfully if no exception is thrown. + * @exception Interrupted_Exception never thrown + */ + virtual void acquire(); + + /** + * Release exclusive access. No safety or state checks are performed. + * + * @pre the caller should have previously acquired this lock + */ + virtual void release(); + + /** + * Try to acquire exclusive access to the mutex. The calling thread will block until the + * lock can be acquired. No safety or state checks are performed. + * + * @pre The calling thread should not have previously acquired this lock. + * Deadlock will result if the same thread attempts to acquire the mutex more + * than once. + * + * @param timeout unused + * @return + * - true if the lock was acquired + * - false if the lock was acquired + * + * @post The calling thread obtains the lock successfully if no exception is thrown. + * @exception Interrupted_Exception never thrown + */ + virtual bool tryAcquire(unsigned long timeout); + + }; /* FastMutex */ + +}; + +#endif // __ZTFASTMUTEX_H__ diff --git a/dep/include/zthread/FastRecursiveMutex.h b/dep/include/zthread/FastRecursiveMutex.h new file mode 100644 index 000000000..a30f4b53a --- /dev/null +++ b/dep/include/zthread/FastRecursiveMutex.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVEMUTEX_H__ +#define __ZTFASTRECURSIVEMUTEX_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class FastRecursiveLock; + + /** + * @class FastRecursiveMutex + * + * @author Eric Crahen + * @date <2003-07-19T19:00:25-0400> + * @version 2.2.0 + * + * A FastRecursiveMutex is a small fast implementation of a recursive, mutally exclusive + * Lockable object. This implementation is a bit faster than the other Mutex classes + * as it involved the least overhead. However, this slight increase in speed is + * gained by sacrificing the robustness provided by the other classes. + * + * A FastRecursiveMutex has the useful property of not being interruptable; that is to say + * that acquire() and tryAcquire() will not throw Interrupted_Exceptions. + * + * @see RecursiveMutex + * + * Scheduling + * + * Scheduling is left to the operating systems and may vary. + * + * Error Checking + * + * No error checking is performed, this means there is the potential for deadlock. + */ + class ZTHREAD_API FastRecursiveMutex : public Lockable, private NonCopyable { + + FastRecursiveLock* _lock; + + public: + + //! Create a new FastRecursiveMutex + FastRecursiveMutex(); + + //! Destroy this FastRecursiveMutex + virtual ~FastRecursiveMutex(); + + /** + * Acquire exclusive access to the mutex. The calling thread will block until the + * lock can be acquired. No safety or state checks are performed. The calling thread + * may acquire the mutex nore than once. + * + * @post The calling thread obtains the lock successfully if no exception is thrown. + * @exception Interrupted_Exception never thrown + */ + virtual void acquire(); + + /** + * Release access. No safety or state checks are performed. + * + * @pre the caller should have previously acquired this lock at least once. + */ + virtual void release(); + + /** + * Try to acquire exclusive access to the mutex. The calling thread will block until the + * lock can be acquired. No safety or state checks are performed. The calling thread + * may acquire the mutex more than once. + * + * @param timeout unused + * @return + * - true if the lock was acquired + * - false if the lock was acquired + * + * @post The calling thread obtains the lock successfully if no exception is thrown. + * @exception Interrupted_Exception never thrown + */ + virtual bool tryAcquire(unsigned long timeout); + + }; + +} // namespace ZThread + +#endif // __ZTFASTRECURSIVEMUTEX_H__ diff --git a/dep/include/zthread/Guard.h b/dep/include/zthread/Guard.h new file mode 100644 index 000000000..988c3cfa3 --- /dev/null +++ b/dep/include/zthread/Guard.h @@ -0,0 +1,511 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTGUARD_H__ +#define __ZTGUARD_H__ + +#include "zthread/NonCopyable.h" +#include "zthread/Exceptions.h" + +namespace ZThread { + +// +// GuardLockingPolicyContract { +// +// createScope(lock_type&) +// bool createScope(lock_type&, unsigned long) +// destroyScope(lock_type&) +// +// } +// + +/** + * @class LockHolder + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * This is a simple base class for Guards class. It allows Guards + * that have compatible targets to refer to each others targets + * allowing for the construction of Guards that share the same lock + * but have different locking policies. + */ +template +class LockHolder { + + LockType &_lock; + bool _enabled; + + public: + + template + LockHolder(T& t) : _lock(extract(t)._lock), _enabled(true) { } + + LockHolder(LockHolder& holder) : _lock(holder._lock), _enabled(true) { } + + LockHolder(LockType& lock) : _lock(lock), _enabled(true) { } + + void disable() { + _enabled = false; + } + + bool isDisabled() { + return !_enabled; + } + + LockType& getLock() { + return _lock; + } + + protected: + + template + static LockHolder& extract(T& t) { + // Design and Evolution of C++, page 328 + return (LockHolder&)(t); + } + +}; + +/** + * @class CompoundScope + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * Locking policy that aggregates two policies that share a target. + * It is not appropriate to use with any type of OverlappedScope + */ +template +class CompoundScope { + public: + + template + static void createScope(LockHolder& l) { + + Scope1::createScope(l); + Scope2::createScope(l); + + } + + template + static void createScope(LockHolder& l, unsigned long ms) { + + if(Scope1::createScope(l, ms)) + if(!Scope2::createScope(l, ms)) { + + Scope1::destroyScope(l); + return false; + + } + + return true; + + } + + template + static void destroyScope(LockHolder& l) { + + Scope1::destroyScope(l); + Scope2::destroyScope(l); + + } + +}; + + +/** + * @class LockedScope + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * Locking policy for Lockable objects. This policy acquire()s a Lockable + * when the protection scope is created, and it release()s a Lockable + * when the scope is destroyed. + */ +class LockedScope { + public: + + /** + * A new protection scope is being created by l2, using an existing scope + * created by l1. + * + * @param lock1 LockType1& is the LockHolder that holds the desired lock + * @param lock2 LockType1& is the LockHolder that wants to share + template + static void shareScope(LockHolder& l1, LockHolder& l2) { + + l2.getLock().acquire(); + + } + */ + + /** + * A new protection scope is being created. + * + * @param lock LockType& is a type of LockHolder. + */ + template + static bool createScope(LockHolder& l, unsigned long ms) { + + return l.getLock().tryAcquire(ms); + + } + + /** + * A new protection scope is being created. + * + * @param lock LockType& is a type of LockHolder. + */ + template + static void createScope(LockHolder& l) { + + l.getLock().acquire(); + + } + + /** + * A protection scope is being destroyed. + * + * @param lock LockType& is a type of LockHolder. + */ + template + static void destroyScope(LockHolder& l) { + + l.getLock().release(); + + } + +}; + + +/** + * @class UnlockedScope + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * Locking policy for Lockable objects. This policy release()s a Lockable + * when the protection scope is created, and it acquire()s a Lockable + * when the scope is destroyed. + */ +class UnlockedScope { + public: + + /** + * A new protection scope is being created by l2, using an existing scope + * created by l1. + * + * @param lock1 LockType1& is the LockHolder that holds the desired lock + * @param lock2 LockType1& is the LockHolder that wants to share + */ + template + static void shareScope(LockHolder& /*l1*/, LockHolder& l2) { + + l2.getLock().release(); + + } + + /** + * A new protection scope is being created. + * + * @param lock LockType& is a type of LockHolder. + template + static void createScope(LockHolder& l) { + + l.getLock().release(); + + } + */ + + /** + * A protection scope is being destroyed. + * + * @param lock LockType& is a type of LockHolder. + */ + template + static void destroyScope(LockHolder& l) { + + l.getLock().acquire(); + + } + +}; + + + +/** + * @class TimedLockedScope + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * Locking policy that attempts to enterScope some resource + * in a certain amount of time using an tryEnterScope-relase protocol. + */ +template +class TimedLockedScope { + public: + + /** + * Try to enterScope the given LockHolder. + * + * @param lock LockType& is a type of LockHolder. + */ + template + static void shareScope(LockHolder& l1, LockHolder& l2) { + + if(!l2.getLock().tryAcquire(TimeOut)) + throw Timeout_Exception(); + + } + + template + static void createScope(LockHolder& l) { + + if(!l.getLock().tryAcquire(TimeOut)) + throw Timeout_Exception(); + + } + + template + static void destroyScope(LockHolder& l) { + + l.getLock().release(); + + } + +}; + + +/** + * @class OverlappedScope + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * Locking policy allows the effective scope of two locks to overlap + * by releasing and disabling one lock before its Guard does so. + */ +class OverlappedScope { + public: + + template + static void transferScope(LockHolder& l1, LockHolder& l2) { + + l1.getLock().acquire(); + + l2.getLock().release(); + l2.disable(); + + } + + template + static void destroyScope(LockHolder& l) { + + l.getLock().release(); + + } + +}; + + + +/** + * @class Guard + * @author Eric Crahen + * @date <2003-07-16T17:55:42-0400> + * @version 2.2.0 + * + * Scoped locking utility. This template class can be given a Lockable + * synchronization object and can 'Guard' or serialize access to + * that method. + * + * For instance, consider a case in which a class or program have a + * Mutex object associated with it. Access can be serialized with a + * Guard as shown below. + * + * @code + * + * Mutex _mtx; + * void guarded() { + * + * Guard g(_mtx); + * + * } + * + * @endcode + * + * The Guard will lock the synchronization object when it is created and + * automatically unlock it when it goes out of scope. This eliminates + * common mistakes like forgetting to unlock your mutex. + * + * An alternative to the above example would be + * + * @code + * + * void guarded() { + * + * (Guard)(_mtx); + * + * } + * + * @endcode + * + * HOWEVER; using a Guard in this method is dangerous. Depending on your + * compiler an anonymous variable like this can go out of scope immediately + * which can result in unexpected behavior. - This is the case with MSVC + * and was the reason for introducing assertions into the Win32_MutexImpl + * to track this problem down + * + */ +template +class Guard : private LockHolder, private NonCopyable { + + friend class LockHolder; + +public: + + /** + * Create a Guard that enforces a the effective protection scope + * throughout the lifetime of the Guard object or until the protection + * scope is modified by another Guard. + * + * @param lock LockType the lock this Guard will use to enforce its + * protection scope. + * @post the protection scope may be ended prematurely + */ + Guard(LockType& lock) : LockHolder(lock) { + + LockingPolicy::createScope(*this); + + }; + + /** + * Create a Guard that enforces a the effective protection scope + * throughout the lifetime of the Guard object or until the protection + * scope is modified by another Guard. + * + * @param lock LockType the lock this Guard will use to enforce its + * protection scope. + * @post the protection scope may be ended prematurely + */ + Guard(LockType& lock, unsigned long timeout) : LockHolder(lock) { + + if(!LockingPolicy::createScope(*this, timeout)) + throw Timeout_Exception(); + + }; + + /** + * Create a Guard that shares the effective protection scope + * from the given Guard to this Guard. + * + * @param g Guard guard that is currently enabled + * @param lock LockType the lock this Guard will use to enforce its + * protection scope. + */ + template + Guard(Guard& g) : LockHolder(g) { + + LockingPolicy::shareScope(*this, extract(g)); + + } + + /** + * Create a Guard that shares the effective protection scope + * from the given Guard to this Guard. + * + * @param g Guard guard that is currently enabled + * @param lock LockType the lock this Guard will use to enforce its + * protection scope. + */ + Guard(Guard& g) : LockHolder(g) { + + LockingPolicy::shareScope(*this, g); + + } + + + /** + * Create a Guard that transfers the effective protection scope + * from the given Guard to this Guard. + * + * @param g Guard guard that is currently enabled + * @param lock LockType the lock this Guard will use to enforce its + * protection scope. + */ + template + Guard(Guard& g, LockType& lock) : LockHolder(lock) { + + LockingPolicy::transferScope(*this, extract(g)); + + } + + + /** + * Create a Guard that transfers the effective protection scope + * from the given Guard to this Guard. + * + * @param g Guard guard that is currently enabled + * @param lock LockType the lock this Guard will use to enforce its + * protection scope. + */ + Guard(Guard& g, LockType& lock) : LockHolder(lock) { + + LockingPolicy::transferScope(*this, g); + + } + + + /** + * Unlock a given Lockable object with the destruction of this Guard + */ + ~Guard() throw(); + +}; /* Guard */ + + +template +Guard::~Guard() throw() { + + try { + + if(!this->isDisabled()) + LockingPolicy::destroyScope(*this); + + } catch (...) { /* ignore */ } + +} + + +}; + +#endif // __ZTGUARD_H__ + + + + + + + diff --git a/dep/include/zthread/GuardedClass.h b/dep/include/zthread/GuardedClass.h new file mode 100644 index 000000000..4ef3879cb --- /dev/null +++ b/dep/include/zthread/GuardedClass.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __GUARDEDCLASS_H__ +#define __GUARDEDCLASS_H__ + +#include "zthread/Guard.h" +#include "zthread/Mutex.h" + +namespace ZThread { + + /** + * @class GuardedClass + * @author Eric Crahen + * @date <2003-07-20T20:17:34-0400> + * @version 2.3.0 + * + * A simple wrapper template that uses Guard's to provide + * serialized access to an objects member functions. + */ + template + class GuardedClass { + + LockType _lock; + T* _ptr; + + class TransferedScope { + public: + + template + static void shareScope(LockHolder& l1, + LockHolder& l2) { + l1.disable(); + l2.getLock().acquire(); + } + + template + static void createScope(LockHolder& l) { + // Don't acquire the lock when scope the Guard is created + } + + template + static void destroyScope(LockHolder& l) { + l.getLock().release(); + } + + }; + + class Proxy : Guard { + + T* _object; + + public: + + Proxy(LockType& lock, T* object) : + Guard(lock), _object(object) { } + + T* operator->() { + return _object; + } + + }; + + GuardedClass(); + GuardedClass& operator=(const GuardedClass&); + + public: + + GuardedClass(T* ptr) : _ptr(ptr) {} + ~GuardedClass() { + if(_ptr) + delete _ptr; + } + + Proxy operator->() { + Proxy p(_lock, _ptr); + return p; + } + + }; + +} // namespace ZThread + +#endif // __ZTGUARDEDCLASS_H__ diff --git a/dep/include/zthread/Lockable.h b/dep/include/zthread/Lockable.h new file mode 100644 index 000000000..32f7eeda9 --- /dev/null +++ b/dep/include/zthread/Lockable.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTLOCKABLE_H__ +#define __ZTLOCKABLE_H__ + +#include "zthread/Exceptions.h" + +namespace ZThread { + + /** + * @class Lockable + * @author Eric Crahen + * @date <2003-07-16T10:33:32-0400> + * @version 2.3.0 + * + * The Lockable interface defines a common method of adding general acquire-release + * semantics to an object. An acquire-release protocol does not necessarily imply + * exclusive access. + */ + class Lockable { + public: + + //! Destroy a Lockable object. + virtual ~Lockable() {} + + /** + * Acquire the Lockable object. + * + * This method may or may not block the caller for an indefinite amount + * of time. Those details are defined by specializations of this class. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted before + * the operation completes. + * + * @post The Lockable is acquired only if no exception was thrown. + */ + virtual void acquire() = 0; + + /** + * Attempt to acquire the Lockable object. + * + * This method may or may not block the caller for a definite amount + * of time. Those details are defined by specializations of this class; + * however, this method includes a timeout value that can be used to + * limit the maximum amount of time that a specialization could block. + * + * @param timeout - maximum amount of time (milliseconds) this method could block + * + * @return + * - true if the operation completes and the Lockable is acquired before + * the timeout expires. + * - false if the operation times out before the Lockable can be acquired. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted before + * the operation completes. + * + * @post The Lockable is acquired only if no exception was thrown. + */ + virtual bool tryAcquire(unsigned long timeout) = 0; + + /** + * Release the Lockable object. + * + * This method may or may not block the caller for an indefinite amount + * of time. Those details are defined by specializations of this class. + * + * @post The Lockable is released only if no exception was thrown. + */ + virtual void release() = 0; + + }; + + +} // namespace ZThread + +#endif // __ZTLOCKABLE_H__ diff --git a/dep/include/zthread/LockedQueue.h b/dep/include/zthread/LockedQueue.h new file mode 100644 index 000000000..a1f0df264 --- /dev/null +++ b/dep/include/zthread/LockedQueue.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTLOCKEDQUEUE_H__ +#define __ZTLOCKEDQUEUE_H__ + +#include "zthread/Guard.h" +#include "zthread/Queue.h" + +#include + +namespace ZThread { + + /** + * @class LockedQueue + * @author Eric Crahen + * @date <2003-07-16T11:42:33-0400> + * @version 2.3.0 + * + * A LockedQueue is the simple Queue implementation that provides + * serialized access to the values added to it. + */ + template > + class LockedQueue : public Queue { + + //! Serialize access to the Queue + LockType _lock; + + //! Storage backing the queue + StorageType _queue; + + //! Cancellation flag + volatile bool _canceled; + + public: + + //! Create a LockedQueue + LockedQueue() : _canceled(false) {} + + //! Destroy a LockedQueue + virtual ~LockedQueue() { } + + /** + * @see Queue::add(const T& item) + */ + virtual void add(const T& item) { + + Guard g(_lock); + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + + } + + /** + * @see Queue::add(const T& item, unsigned long timeout) + */ + virtual bool add(const T& item, unsigned long timeout) { + + try { + + Guard g(_lock, timeout); + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + + } catch(Timeout_Exception&) { return false; } + + return true; + + } + + /** + * @see Queue::next() + */ + virtual T next() { + + Guard g(_lock); + + if(_queue.empty() && _canceled) + throw Cancellation_Exception(); + + if(_queue.empty()) + throw NoSuchElement_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + return item; + + } + + + /** + * @see Queue::next(unsigned long timeout) + */ + virtual T next(unsigned long timeout) { + + Guard g(_lock, timeout); + + if(_queue.empty() && _canceled) + throw Cancellation_Exception(); + + if(_queue.empty()) + throw NoSuchElement_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + return item; + + } + + virtual T front() + { + Guard g(_lock); + + if(_queue.empty()) + throw NoSuchElement_Exception(); + + return _queue.front(); + } + + /** + * @see Queue::cancel() + */ + virtual void cancel() { + + Guard g(_lock); + + _canceled = true; + + } + + /** + * @see Queue::isCanceled() + */ + virtual bool isCanceled() { + + // Faster check since the queue will not become un-canceled + if(_canceled) + return true; + + Guard g(_lock); + + return _canceled; + + } + + /** + * @see Queue::size() + */ + virtual size_t size() { + + Guard g(_lock); + return _queue.size(); + + } + + /** + * @see Queue::size(unsigned long timeout) + */ + virtual size_t size(unsigned long timeout) { + + Guard g(_lock, timeout); + return _queue.size(); + + } + + }; /* LockedQueue */ + +} // namespace ZThread + +#endif // __ZTLOCKEDQUEUE_H__ diff --git a/dep/include/zthread/MonitoredQueue.h b/dep/include/zthread/MonitoredQueue.h new file mode 100644 index 000000000..8578fe62b --- /dev/null +++ b/dep/include/zthread/MonitoredQueue.h @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMONITOREDQUEUE_H__ +#define __ZTMONITOREDQUEUE_H__ + +#include "zthread/Condition.h" +#include "zthread/Guard.h" +#include "zthread/Queue.h" + +#include + +namespace ZThread { + + /** + * @class MonitoredQueue + * @author Eric Crahen + * @date <2003-07-16T20:23:28-0400> + * @version 2.3.0 + * + * A MonitoredQueue is a Queue implementation that provides serialized access to the + * items added to it. + * + * - Threads calling the empty() methods will be blocked until the BoundedQueue becomes empty. + * - Threads calling the next() methods will be blocked until the BoundedQueue has a value to + * return. + * + * @see Queue + */ + template > + class MonitoredQueue : public Queue, public Lockable { + + //! Serialize access + LockType _lock; + + //! Signaled on not empty + Condition _notEmpty; + + //! Signaled on empty + Condition _isEmpty; + + //! Storage backing the queue + StorageType _queue; + + //! Cancellation flag + volatile bool _canceled; + + public: + + //! Create a new MonitoredQueue + MonitoredQueue() + : _notEmpty(_lock), _isEmpty(_lock), _canceled(false) {} + + //! Destroy a MonitoredQueue, delete remaining items + virtual ~MonitoredQueue() { } + + /** + * Add a value to this Queue. + * + * @param item value to be added to the Queue + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Interrupted_Exception thrown if the thread was interrupted while waiting + * to add a value + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post If no exception is thrown, a copy of item will have been added to the Queue. + * + * @see Queue::add(const T& item) + */ + virtual void add(const T& item) { + + Guard g(_lock); + + // Allow no further additions in the canceled state + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back( item ); + + _notEmpty.signal(); // Wake one waiter + + } + + /** + * Add a value to this Queue. + * + * @param item value to be added to the Queue + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return + * - true if a copy of item can be added before timeout + * milliseconds elapse. + * - false otherwise. + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Interrupted_Exception thrown if the thread was interrupted while waiting + * to add a value + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post If no exception is thrown, a copy of item will have been added to the Queue. + * + * @see Queue::add(const T& item, unsigned long timeout) + */ + virtual bool add(const T& item, unsigned long timeout) { + + try { + + Guard g(_lock, timeout); + + if(_canceled) + throw Cancellation_Exception(); + + _queue.push_back(item); + + _notEmpty.signal(); + + } catch(Timeout_Exception&) { return false; } + + return true; + + } + + /** + * Retrieve and remove a value from this Queue. + * + * If invoked when there are no values present to return then the calling thread + * will be blocked until a value arrives in the Queue. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Interrupted_Exception thrown if the thread was interrupted while waiting + * to retrieve a value + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + */ + virtual T next() { + + Guard g(_lock); + + while (_queue.empty() && !_canceled) + _notEmpty.wait(); + + if(_queue.empty()) // Queue canceled + throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + if(_queue.empty()) // Wake empty waiters + _isEmpty.broadcast(); + + return item; + + } + + /** + * Retrieve and remove a value from this Queue. + * + * If invoked when there are no values present to return then the calling thread + * will be blocked until a value arrives in the Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Timeout_Exception thrown if the timeout expires before a value + * can be retrieved. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + */ + virtual T next(unsigned long timeout) { + + Guard g(_lock, timeout); + + while(_queue.empty() && !_canceled) { + if(!_notEmpty.wait(timeout)) + throw Timeout_Exception(); + } + + if( _queue.empty()) // Queue canceled + throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + if(_queue.empty()) // Wake empty waiters + _isEmpty.broadcast(); + + return item; + + } + + + /** + * Cancel this queue. + * + * @post Any threads blocked by a next() function will throw a Cancellation_Exception. + * + * @see Queue::cancel() + */ + virtual void cancel() { + + Guard g(_lock); + + _canceled = true; + _notEmpty.broadcast(); // Wake next() waiters + + } + + /** + * @see Queue::isCanceled() + */ + virtual bool isCanceled() { + + // Faster check since the queue will not become un-canceled + if(_canceled) + return true; + + Guard g(_lock); + + return _canceled; + + } + + + /** + * @see Queue::size() + */ + virtual size_t size() { + + Guard g(_lock); + return _queue.size(); + + } + + /** + * @see Queue::size(unsigned long timeout) + */ + virtual size_t size(unsigned long timeout) { + + Guard g(_lock, timeout); + return _queue.size(); + + } + + /** + * Test whether any values are available in this Queue. + * + * The calling thread is blocked until there are no values present + * in the Queue. + * + * @return + * - true if there are no values available. + * - false if there are values available. + * + * @see Queue::empty() + */ + virtual bool empty() { + + Guard g(_lock); + + while(!_queue.empty()) // Wait for an empty signal + _isEmpty.wait(); + + return true; + + } + + /** + * Test whether any values are available in this Queue. + * + * The calling thread is blocked until there are no values present + * in the Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return + * - true if there are no values available. + * - false if there are values available. + * + * @exception Timeout_Exception thrown if timeout milliseconds + * expire before a value becomes available + * + * @see Queue::empty() + */ + virtual bool empty(unsigned long timeout) { + + Guard g(_lock, timeout); + + while(!_queue.empty()) // Wait for an empty signal + _isEmpty.wait(timeout); + + return true; + + } + + public: + + virtual void acquire() { + _lock.acquire(); + } + + virtual bool tryAcquire(unsigned long timeout) { + return _lock.tryAcquire(timeout); + } + + virtual void release() { + _lock.release(); + } + + + }; /* MonitoredQueue */ + + +} // namespace ZThread + +#endif // __ZTMONITOREDQUEUE_H__ + diff --git a/dep/include/zthread/Mutex.h b/dep/include/zthread/Mutex.h new file mode 100644 index 000000000..1b521b159 --- /dev/null +++ b/dep/include/zthread/Mutex.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMUTEX_H__ +#define __ZTMUTEX_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class FifoMutexImpl; + + /** + * @class Mutex + * @author Eric Crahen + * @date <2003-07-16T19:35:28-0400> + * @version 2.2.1 + * + * A Mutex is used to provide serialized (one thread at a time) access to some portion + * of code. This is accomplished by attempting to acquire the Mutex before entering that + * piece of code, and by releasing the Mutex when leaving that region. It is a non-reentrant, + * MUTual EXclusion Lockable object. + * + * @see Guard + * + * Scheduling + * + * Threads competing to acquire() a Mutex are granted access in FIFO order. + * + * Error Checking + * + * A Mutex will throw a Deadlock_Exception if an attempt to acquire a Mutex more + * than once is made from the context of the same thread. + * + * A Mutex will throw an InvalidOp_Exception if an attempt to release a Mutex is + * made from the context of a thread that does not currently own that Mutex. + */ + class ZTHREAD_API Mutex : public Lockable, private NonCopyable { + + FifoMutexImpl* _impl; + + public: + + //! Create a new Mutex. + Mutex(); + + //! Destroy this Mutex. + virtual ~Mutex(); + + /** + * Acquire a Mutex, possibly blocking until either the current owner of the + * Mutex releases it or until an exception is thrown. + * + * Only one thread may acquire() the Mutex at any given time. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * @exception Deadlock_Exception thrown when the same thread attempts to acquire + * a Mutex more than once, without having first release()ed it. + * + * @pre the calling thread must not have already acquired Mutex + * + * @post the calling thread successfully acquired Mutex only if no exception + * was thrown. + * + * @see Lockable::acquire() + */ + virtual void acquire(); + + /** + * Acquire a Mutex, possibly blocking until the current owner of the + * Mutex releases it, until an exception is thrown or until the given amount + * of time expires. + * + * Only one thread may acquire the Mutex at any given time. + * + * @param timeout maximum amount of time (milliseconds) this method could block + * @return + * - true if the lock was acquired + * - false if the lock was acquired + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * @exception Deadlock_Exception thrown when the same thread attempts to acquire + * a Mutex more than once, without having first released it. + * + * @pre the calling thread must not have already acquired Mutex + * + * @post the calling thread successfully acquired Mutex only if no exception + * was thrown. + * + * @see Lockable::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + /** + * Release a Mutex allowing another thread to acquire it. + * + * @exception InvalidOp_Exception - thrown if there is an attempt to release is + * a Mutex that was not owner by the calling thread. + * + * @pre the calling thread must have first acquired the Mutex. + * @post the calling thread successfully released Mutex only if no exception + * was thrown. + * + * @see Lockable::release() + */ + virtual void release(); + + }; + + +} // namespace ZThread + +#endif // __ZTMUTEX_H__ diff --git a/dep/include/zthread/NonCopyable.h b/dep/include/zthread/NonCopyable.h new file mode 100644 index 000000000..5c33f345f --- /dev/null +++ b/dep/include/zthread/NonCopyable.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTNONCOPYABLE_H__ +#define __ZTNONCOPYABLE_H__ + +namespace ZThread { + + /** + * @class NonCopyable + * @author Eric Crahen + * @date <2003-07-16T19:36:00-0400> + * @version 2.2.11 + * + * Some objects kind of objects should not be copied. This is particularly true + * of objects involved in providing mutually exclusive access to something + * (e.g. Mutexes, Queues, Semaphores, etc.) + * + * Based on Dave Abrahams contribution to the Boost library. + */ + class NonCopyable { + + //! Restrict the copy constructor + NonCopyable(const NonCopyable&); + + //! Restrict the assignment operator + const NonCopyable& operator=(const NonCopyable&); + + protected: + + //! Create a NonCopyable object + NonCopyable() { } + + //! Destroy a NonCopyable object + ~NonCopyable() { } + + }; /* NonCopyable */ + +} // namespace ZThread + +#endif // __ZTNONCOPYABLE_H__ diff --git a/dep/include/zthread/PoolExecutor.h b/dep/include/zthread/PoolExecutor.h new file mode 100644 index 000000000..82f5c4f05 --- /dev/null +++ b/dep/include/zthread/PoolExecutor.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTPOOLEXECUTOR_H__ +#define __ZTPOOLEXECUTOR_H__ + +#include "zthread/Executor.h" +#include "zthread/CountedPtr.h" +#include "zthread/Thread.h" + +namespace ZThread { + + namespace { class ExecutorImpl; } + + /** + * @class PoolExecutor + * + * @author Eric Crahen + * @date <2003-07-16T22:41:07-0400> + * @version 2.3.0 + * + * A PoolExecutor spawns a set of threads that are used to run tasks + * that are submitted in parallel. A PoolExecutor supports the following + * optional operations, + * + * - cancel()ing a PoolExecutor will cause it to stop accepting + * new tasks. + * + * - interrupt()ing a PoolExecutor will cause the any thread running + * a task which was submitted prior to the invocation of this function to + * be interrupted during the execution of that task. + * + * - wait()ing on a PoolExecutor will block the calling thread + * until all tasks that were submitted prior to the invocation of this function + * have completed. + * + * @see Executor. + */ + class PoolExecutor : public Executor { + + //! Reference to the internal implementation + CountedPtr< ExecutorImpl > _impl; + + //! Cancellation task + Task _shutdown; + + public: + + /** + * Create a PoolExecutor + * + * @param n number of threads to service tasks with + */ + PoolExecutor(size_t n); + + //! Destroy a PoolExecutor + virtual ~PoolExecutor(); + + /** + * Invoking this function causes each task that had been submitted prior to + * this function to be interrupted. Tasks submitted after the invocation of + * this function are unaffected. + * + * @post Any task submitted prior to the invocation of this function will be + * run in the context of an interrupted thread. + * @post Any thread already executing a task which was submitted prior to the + * invocation of this function will be interrupted. + */ + virtual void interrupt(); + + /** + * Alter the number of threads being used to execute submitted tasks. + * + * @param n number of worker threads. + * + * @pre n must be greater than 0. + * @post n threads will be executing tasks submitted to this executor. + * + * @exception InvalidOp_Exception thrown if the new number of threads + * n is less than 1. + */ + void size(size_t n); + + /** + * Get the current number of threads being used to execute submitted tasks. + * + * @return n number of worker threads. + */ + size_t size(); + + /** + * Submit a task to this Executor. + * + * This will not block the calling thread very long. The submitted task will + * be executed at some later point by another thread. + * + * @param task Task to be run by a thread managed by this executor + * + * @pre The Executor should have been canceled prior to this invocation. + * @post The submitted task will be run at some point in the future by this Executor. + * + * @exception Cancellation_Exception thrown if the Executor was canceled prior to + * the invocation of this function. + * + * @see PoolExecutor::cancel() + * @see Executor::execute(const Task& task) + */ + virtual void execute(const Task& task); + + /** + * @see Cancelable::cancel() + */ + virtual void cancel(); + + /** + * @see Cancelable::isCanceled() + */ + virtual bool isCanceled(); + + /** + * Block the calling thread until all tasks submitted prior to this invocation + * complete. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before the set of tasks being wait for can complete. + * + * @see Waitable::wait() + */ + virtual void wait(); + + /** + * Block the calling thread until all tasks submitted prior to this invocation + * complete or until the calling thread is interrupted. + * + * @param timeout maximum amount of time, in milliseconds, to wait for the + * currently submitted set of Tasks to complete. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before the set of tasks being wait for can complete. + * + * @return + * - true if the set of tasks being wait for complete before + * timeout milliseconds elapse. + * - false otherwise. + * + * @see Waitable::wait(unsigned long timeout) + */ + virtual bool wait(unsigned long timeout); + + }; /* PoolExecutor */ + + +} // namespace ZThread + +#endif // __ZTPOOLEXECUTOR_H__ + + + + diff --git a/dep/include/zthread/Priority.h b/dep/include/zthread/Priority.h new file mode 100644 index 000000000..907d1f153 --- /dev/null +++ b/dep/include/zthread/Priority.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTPRIORITY_H__ +#define __ZTPRIORITY_H__ + +namespace ZThread { + + //! Priorities + typedef enum { + + Low, + Medium = Low + 1, + High = Low + 2 + + } Priority; + +} + +#endif // __ZTPRIORITY_H__ diff --git a/dep/include/zthread/PriorityCondition.h b/dep/include/zthread/PriorityCondition.h new file mode 100644 index 000000000..1fd86c41c --- /dev/null +++ b/dep/include/zthread/PriorityCondition.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTPRIORITYCONDITION_H__ +#define __ZTPRIORITYCONDITION_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" +#include "zthread/Waitable.h" + +namespace ZThread { + + class PriorityConditionImpl; + + /** + * @class PriorityCondition + * @author Eric Crahen + * @date <2003-07-16T17:35:28-0400> + * @version 2.2.1 + * + * A PriorityCondition is a Condition that is sensitive to thread priority. + * + * @see Condition + * + * Scheduling + * + * Threads blocked on a PriorityCondition are resumed in priority order, highest priority + * first + */ + class ZTHREAD_API PriorityCondition : public Waitable, private NonCopyable { + + PriorityConditionImpl* _impl; + + public: + + /** + * @see Condition::Condition(Lockable& l) + */ + PriorityCondition(Lockable& l); + + /** + * @see Condition::~Condition() + */ + ~PriorityCondition(); + + /** + * @see Condition::signal() + */ + void signal(); + + /** + * @see Condition::broadcast() + */ + void broadcast(); + + /** + * @see Condition::wait() + */ + virtual void wait(); + + /** + * @see Condition::wait(unsigned long timeout) + */ + virtual bool wait(unsigned long timeout); + + }; + +} // namespace ZThread + +#endif // __ZTPRIORITYCONDITION_H__ diff --git a/dep/include/zthread/PriorityInheritanceMutex.h b/dep/include/zthread/PriorityInheritanceMutex.h new file mode 100644 index 000000000..1a5f5bfd3 --- /dev/null +++ b/dep/include/zthread/PriorityInheritanceMutex.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTPRIORITYINHERITANCEMUTEX_H__ +#define __ZTPRIORITYINHERITANCEMUTEX_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class PriorityInheritanceMutexImpl; + + /** + * @class PriorityInheritanceMutex + * + * @author Eric Crahen + * @date <2003-07-16T19:37:36-0400> + * @version 2.2.1 + * + * A PriorityInheritanceMutex is similar to a PriorityMutex, it is a non-reentrant, + * priority sensitive MUTual EXclusion Lockable object. It differs only in its + * scheduling policy. + * + * @see PriorityMutex + * + * Scheduling + * + * Threads competing to acquire() a PriorityInheritanceMutex are granted access in + * order of priority. Threads with a higher priority will be given access first. + * + * When a higher priority thread tries to acquire() a PriorityInheritanceMutex and is + * about to be blocked by a lower priority thread that has already acquire()d it, the + * lower priority thread will temporarily have its effective priority raised to that + * of the higher priority thread until it release()s the mutex; at which point its + * previous priority will be restored. + */ + class ZTHREAD_API PriorityInheritanceMutex : public Lockable, private NonCopyable { + + PriorityInheritanceMutexImpl* _impl; + + public: + + /** + * @see Mutex::Mutex() + */ + PriorityInheritanceMutex(); + + /** + * @see Mutex::~Mutex() + */ + virtual ~PriorityInheritanceMutex(); + + /** + * @see Mutex::acquire() + */ + virtual void acquire(); + + /** + * @see Mutex::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + /** + * @see Mutex::release() + */ + virtual void release(); + + }; + + +} // namespace ZThread + +#endif // __ZTPRIORITYINHERITANCEMUTEX_H__ diff --git a/dep/include/zthread/PriorityMutex.h b/dep/include/zthread/PriorityMutex.h new file mode 100644 index 000000000..477c8d9fd --- /dev/null +++ b/dep/include/zthread/PriorityMutex.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTPRIORITYMUTEX_H__ +#define __ZTPRIORITYMUTEX_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class PriorityMutexImpl; + + /** + * @class PriorityMutex + * @author Eric Crahen + * @date <2003-07-16T17:35:46-0400> + * @version 2.2.1 + * + * A PriorityMutex is similar to a Mutex, with exception that a PriorityMutex + * has a difference scheduling policy. It is a non-reentrant, priority sensitive + * MUTual EXclusion Lockable object. + * + * @see Mutex + * + * Scheduling + * + * Threads competing to acquire() a Mutex are granted access in order of priority. Threads + * with a higher priority will be given access first. + */ + class ZTHREAD_API PriorityMutex : public Lockable, private NonCopyable { + + PriorityMutexImpl* _impl; + + public: + + /** + * @see Mutex::Mutex() + */ + PriorityMutex(); + + /** + * @see Mutex::~Mutex() + */ + virtual ~PriorityMutex(); + + /** + * @see Mutex::acquire() + */ + virtual void acquire(); + + /** + * @see Mutex::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + /** + * @see Mutex::release() + */ + virtual void release(); + + }; + + +} // namespace ZThread + +#endif // __ZTPRIORITYMUTEX_H__ diff --git a/dep/include/zthread/PrioritySemaphore.h b/dep/include/zthread/PrioritySemaphore.h new file mode 100644 index 000000000..54ef2c48c --- /dev/null +++ b/dep/include/zthread/PrioritySemaphore.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#ifndef __ZTPRIORITYSEMAPHORE_H__ +#define __ZTPRIORITYSEMAPHORE_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class PrioritySemaphoreImpl; + + /** + * @class PrioritySemaphore + * @author Eric Crahen + * @date <2003-07-16T15:36:07-0400> + * @version 2.2.1 + * + * A PrioritySemaphore operates in the same way as a Semaphore. Its an owner-less + * Lockable object that is sensitive to priority. + * + * Scheduling + * + * Threads blocked on a PrioritySemaphore are resumed in priority order, highest + * priority first. + * + * Error Checking + * + * An attempt to increase a PrioritySemaphore beyond its maximum value will result in + * an InvalidOp_Exception. + * + * @see Semaphore + */ + class ZTHREAD_API PrioritySemaphore : public Lockable, private NonCopyable { + + PrioritySemaphoreImpl* _impl; + + public: + + /** + * @see Semaphore::Semaphore(int count, unsigned int maxCount) + */ + PrioritySemaphore(int count = 1, unsigned int maxCount = 1); + + /** + * @see Semaphore::~Semaphore() + */ + virtual ~PrioritySemaphore(); + + /** + * @see Semaphore::wait() + */ + void wait(); + + /** + * @see Semaphore::tryWait(unsigned long) + */ + bool tryWait(unsigned long); + + /** + * @see Semaphore::post() + */ + void post(); + + /** + * @see Semaphore::count() + */ + virtual int count(); + + /** + * @see Semaphore::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + /** + * @see Semaphore::acquire() + */ + virtual void acquire(); + + /** + * @see Semaphore::release() + */ + virtual void release(); + + }; + + +} // namespace ZThread + +#endif // __ZTPRIORITYSEMAPHORE_H__ diff --git a/dep/include/zthread/Queue.h b/dep/include/zthread/Queue.h new file mode 100644 index 000000000..98b83a10c --- /dev/null +++ b/dep/include/zthread/Queue.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTQUEUE_H__ +#define __ZTQUEUE_H__ + +#include "zthread/Cancelable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + /** + * @class Queue + * @author Eric Crahen + * @date <2003-07-16T11:32:42-0400> + * @version 2.3.0 + * + * A Queue defines an interface for a value-oriented collection objects (similar to + * STL collections). + */ + template + class Queue : public Cancelable, private NonCopyable { + public: + + //! Destroy a Queue + virtual ~Queue() { } + + /** + * Add an object to this Queue. + * + * @param item value to be added to the Queue + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post If no exception is thrown, a copy of item will have been added to the Queue. + */ + virtual void add(const T& item) = 0; + + /** + * Add an object to this Queue. + * + * @param item value to be added to the Queue + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return + * - true if a copy of item can be added before timeout + * milliseconds elapse. + * - false otherwise. + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post If this function returns true a copy of item will have been added to the Queue. + */ + virtual bool add(const T& item, unsigned long timeout) = 0; + + /** + * Retrieve and remove a value from this Queue. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + */ + virtual T next() = 0; + + /** + * Retrieve and remove a value from this Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return T next available value + * + * @exception Cancellation_Exception thrown if this Queue has been canceled. + * @exception Timeout_Exception thrown if the timeout expires before a value + * can be retrieved. + * + * @pre The Queue should not have been canceled prior to the invocation of this function. + * @post The value returned will have been removed from the Queue. + */ + virtual T next(unsigned long timeout) = 0; + + /** + * Canceling a Queue disables it, disallowing further additions. Values already + * present in the Queue can still be retrieved and are still available through + * the next() methods. + * + * Canceling a Queue more than once has no effect. + * + * @post The next() methods will continue to return objects until + * the Queue has been emptied. + * @post Once emptied, the next() methods will throw a Cancellation_Exception. + * @post The add() methods will throw a Cancellation_Exceptions from this point on. + */ + virtual void cancel() = 0; + + /** + * Count the values present in this Queue. + * + * @return size_t number of elements available in the Queue. + */ + virtual size_t size() = 0; + + /** + * Count the values present in this Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return size_t number of elements available in the Queue. + * + * @exception Timeout_Exception thrown if timeout milliseconds + * expire before a value becomes available + */ + virtual size_t size(unsigned long timeout) = 0; + + /** + * Test whether any values are available in this Queue. + * + * @return + * - true if there are no values available. + * - false if there are values available. + */ + virtual bool empty() { + + try { + + return size() == 0; + + } catch(Cancellation_Exception&) { } + + return true; + + } + + /** + * Test whether any values are available in this Queue. + * + * @param timeout maximum amount of time (milliseconds) this method may block + * the calling thread. + * + * @return + * - true if there are no values available. + * - false if there are values available. + * + * @exception Timeout_Exception thrown if timeout milliseconds + * expire before a value becomes available + */ + virtual bool empty(unsigned long timeout) { + + try { + + return size(timeout) == 0; + + } catch(Cancellation_Exception&) { } + + return true; + + } + + }; /* Queue */ + +} // namespace ZThread + +#endif // __ZTQUEUE_H__ diff --git a/dep/include/zthread/ReadWriteLock.h b/dep/include/zthread/ReadWriteLock.h new file mode 100644 index 000000000..e01643f19 --- /dev/null +++ b/dep/include/zthread/ReadWriteLock.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTREADWRITELOCK_H__ +#define __ZTREADWRITELOCK_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + /** + * @class ReadWriteLock + * + * @author Eric Crahen + * @date <2003-07-16T10:17:31-0400> + * @version 2.2.7 + * + * A ReadWriteLock provides a set of coordinated Lockable objects that can be used to + * guard an object; One for read-only access, and another for read-write access. + * + * @see BiasedReadWriteLock + * @see FairReadWriteLock + */ + class ReadWriteLock : public NonCopyable { + public: + + /** + * Create a ReadWriteLock + * + * @exception Initialization_Exception thrown if resources could not be + * allocated for this object. + */ + ReadWriteLock() {} + + //! Destroy this ReadWriteLock + virtual ~ReadWriteLock() {} + + /** + * Get a reference to the read-only Lockable. + * + * @return Lockable& reference to a Lockable that provides read-only + * access. + */ + virtual Lockable& getReadLock() = 0; + + /** + * Get a reference to the read-write Lockable. + * + * @return Lockable& reference to a Lockable that provides read-write + * access. + */ + virtual Lockable& getWriteLock() = 0; + + + }; /* ReadWriteLock */ + + +}; // __ZTREADWRITELOCK_H__ + +#endif diff --git a/dep/include/zthread/RecursiveMutex.h b/dep/include/zthread/RecursiveMutex.h new file mode 100644 index 000000000..7dda9c511 --- /dev/null +++ b/dep/include/zthread/RecursiveMutex.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTRECURSIVEMUTEX_H__ +#define __ZTRECURSIVEMUTEX_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class RecursiveMutexImpl; + + /** + * @class RecursiveMutex + * + * @author Eric Crahen + * @date <2003-07-16T17:51:33-0400> + * @version 2.2.1 + * + * A RecursiveMutex is a recursive, MUTual EXclusion Lockable object. It is + * recursive because it can be acquire()d and release()d more than once + * by the same thread, instead of causing a Deadlock_Exception. + * + * @see Mutex + * @see Guard + * + * Scheduling + * + * Threads competing to acquire() a Mutex are granted access in FIFO order. + * + * Error Checking + * + * A Mutex will throw an InvalidOp_Exception if an attempt to release() a Mutex is + * made from the context of a thread that does not currently own that Mutex. + */ + class ZTHREAD_API RecursiveMutex : public Lockable, private NonCopyable { + + RecursiveMutexImpl* _impl; + + public: + + //! Create a new RecursiveMutex. + RecursiveMutex(); + + //! Destroy this RecursiveMutex. + virtual ~RecursiveMutex(); + + /** + * Acquire a RecursiveMutex, possibly blocking until the the current owner of the + * releases it or until an exception is thrown. + * + * Only one thread may acquire the RecursiveMutex at any given time. + * The same thread may acquire a RecursiveMutex multiple times. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @post the calling thread successfully acquire ed RecursiveMutex only if no exception + * was thrown. + * + * @see Lockable::acquire() + */ + virtual void acquire(); + + /** + * Acquire a RecursiveMutex, possibly blocking until the the current owner + * releases it, until an exception is thrown or until the given amount + * of time expires. + * + * Only one thread may acquire the RecursiveMutex at any given time. + * The same thread may acquire a RecursiveMutex multiple times. + * + * @param timeout maximum amount of time (milliseconds) this method could block + * @return + * - true if the lock was acquired + * - false if the lock was acquired + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @post the calling thread successfully acquired RecursiveMutex only if no exception + * was thrown. + * + * @see Lockable::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + + /** + * Release exclusive access. No safety or state checks are performed. + * + * @pre This should not be called more times than the acquire() method was + * called. + * + * @see Lockable::release() + */ + virtual void release(); + + }; + +} // namespace ZThread + +#endif // __ZTRECURSIVEMUTEX_H__ diff --git a/dep/include/zthread/Runnable.h b/dep/include/zthread/Runnable.h new file mode 100644 index 000000000..98628530a --- /dev/null +++ b/dep/include/zthread/Runnable.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#ifndef __ZTRUNNABLE_H__ +#define __ZTRUNNABLE_H__ + +#include "zthread/Config.h" + +namespace ZThread { + + /** + * @class Runnable + * + * @author Eric Crahen + * @date <2003-07-16T17:45:35-0400> + * @version 2.2.11 + * + * Encapsulates a Runnable task. + */ + class Runnable { + public: + + /** + * Runnables should never throw in their destructors + */ + virtual ~Runnable() {} + + /** + * Task to be performed in another thread of execution + */ + virtual void run() = 0; + + }; + + +} + +#endif // __ZTRUNNABLE_H__ diff --git a/dep/include/zthread/Semaphore.h b/dep/include/zthread/Semaphore.h new file mode 100644 index 000000000..2a9e4d02d --- /dev/null +++ b/dep/include/zthread/Semaphore.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTSEMAPHORE_H__ +#define __ZTSEMAPHORE_H__ + +#include "zthread/Lockable.h" +#include "zthread/NonCopyable.h" + +namespace ZThread { + + class FifoSemaphoreImpl; + + /** + * @class Semaphore + * @author Eric Crahen + * @date <2003-07-16T15:28:01-0400> + * @version 2.2.1 + * + * A Semaphore is an owner-less Lockable object. Its probably best described as + * a set of 'permits'. A Semaphore is initialized with an initial count and + * a maximum count, these would correspond to the number of 'permits' currently + * available and the number of' permits' in total. + * + * - Acquiring the Semaphore means taking a permit, but if there are none + * (the count is 0) the Semaphore will block the calling thread. + * + * - Releasing the Semaphore means returning a permit, unblocking a thread + * waiting for one. + * + * A Semaphore with an initial value of 1 and maximum value of 1 will act as + * a Mutex. + * + * Threads blocked on a Semaphore are resumed in FIFO order. + * + */ + class ZTHREAD_API Semaphore : public Lockable, private NonCopyable { + + FifoSemaphoreImpl* _impl; + + public: + + /** + * Create a new Semaphore. + * + * @param count initial count + * @param maxCount maximum count + */ + Semaphore(int count = 1, unsigned int maxCount = 1); + + //! Destroy the Semaphore + virtual ~Semaphore(); + + /** + * Provided to reflect the traditional Semaphore semantics + * + * @see acquire() + */ + void wait(); + + + /** + * Provided to reflect the traditional Semaphore semantics + * + * @see tryAcquire(unsigned long timeout) + */ + bool tryWait(unsigned long timeout); + + /** + * Provided to reflect the traditional Semaphore semantics + * + * @see release() + */ + void post(); + + + /** + * Get the current count of the semaphore. + * + * This value may change immediately after this function returns to the calling thread. + * + * @return int count + */ + virtual int count(); + + /** + * Decrement the count, blocking that calling thread if the count becomes 0 or + * less than 0. The calling thread will remain blocked until the count is + * raised above 0, an exception is thrown or the given amount of time expires. + * + * @param timeout maximum amount of time (milliseconds) this method could block + * + * @return + * - true if the Semaphore was acquired before timeout milliseconds elapse. + * - false otherwise. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @see Lockable::tryAcquire(unsigned long timeout) + */ + virtual bool tryAcquire(unsigned long timeout); + + + /** + * Decrement the count, blocking that calling thread if the count becomes 0 or + * less than 0. The calling thread will remain blocked until the count is + * raised above 0 or if an exception is thrown. + * + * @exception Interrupted_Exception thrown when the calling thread is interrupted. + * A thread may be interrupted at any time, prematurely ending any wait. + * + * @see Lockable::acquire() + */ + virtual void acquire(); + + /** + * Increment the count, unblocking one thread if count is positive. + * + * @exception InvalidOp_Exception thrown if the maximum count would be exceeded. + * + * @see Lockable::release() + */ + virtual void release(); + + }; + + +} // namespace ZThread + +#endif // __ZTSEMAPHORE_H__ diff --git a/dep/include/zthread/Singleton.h b/dep/include/zthread/Singleton.h new file mode 100644 index 000000000..b66c9d089 --- /dev/null +++ b/dep/include/zthread/Singleton.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTSINGLETON_H__ +#define __ZTSINGLETON_H__ + +#include "zthread/Guard.h" +#include "zthread/FastMutex.h" +#include + +namespace ZThread { + +// +// This policy controls how an object is instantiated +// as well as how and when its destroyed. Phoenix-style +// singletons are not supported easily with type of policy, +// this is intentional since I do not believe that is in +// the true spirit of a singleton. +// +// InstantiationPolicContract { +// +// create(pointer_type&) +// +// } + +/** + * @class LocalStaticInstantiation + * @author Eric Crahen + * @date <2003-07-16T17:57:45-0400> + * @version 2.2.0 + * + * The LocalStaticInstantiation policy allows the creation + * and lifetime of an instance of a particular type + * to be managed using static local values. This will + * abide by the standard C++ rules for static objects + * lifetimes. + */ +class LocalStaticInstantiation { +protected: + + /** + * Create an instance of an object, using a local static. The + * object will be destroyed by the system. + * + * @param ptr reference to location to receive the address + * of the allocated object + */ + template + static void create(T*& ptr) { + + static T instance; + ptr = &instance; + + } + +}; + +//! Helper class +template +class StaticInstantiationHelper { + //! Friend class + friend class StaticInstantiation; + //! Holder + static T instance; + + }; + + template + T StaticInstantiationHelper::instance; + +/** + * @class StaticInstantiation + * @author Eric Crahen + * @date <2003-07-16T17:57:45-0400> + * @version 2.2.0 + * + * The StaticInstantiation policy allows the creation + * and lifetime of an instance of a particular type + * to be managed using static instantiation. This will + * abide by the standard C++ rules for static objects + * lifetimes. + */ +class StaticInstantiation { +protected: + + /** + * Create an instance of an object using by simply allocating it statically. + * + * @param ptr reference to location to receive the address + * of the allocated object + */ + template + static void create(T*& ptr) { + ptr = &StaticInstantiationHelper::instance; + } + +}; + +//! SingletonDestroyer +template +class Destroyer { + + T* doomed; + + public: + + Destroyer(T* q) : doomed(q) { + assert(doomed); + } + + ~Destroyer(); + +}; + +template +Destroyer::~Destroyer() { + + try { + + if(doomed) + delete doomed; + + } catch(...) { } + + doomed = 0; + +} + + +/** + * @class LazyInstantiation + * @author Eric Crahen + * @date <2003-07-16T17:57:45-0400> + * @version 2.2.0 + * + * The LazyInstantiation policy allows the creation + * and lifetime of an instance of a particular type + * to be managed using dynamic allocation and a singleton + * destroyer. This will abide by the standard C++ rules + * for static objects lifetimes. + */ +class LazyInstantiation { +protected: + + /** + * Create an instance of an object, using new, that will be + * destroyed when an associated Destroyer object (allocated + * statically) goes out of scope. + * + * @param ptr reference to location to receive the address + * of the allocated object + */ + template + static void create(T*& ptr) { + + ptr = new T; + static Destroyer destroyer(ptr); + + } + +}; + + +/** + * @class Singleton + * @author Eric Crahen + * @date <2003-07-16T17:57:45-0400> + * @version 2.2.0 + * + * Based on the work of John Vlissidles in his book 'Pattern Hatching' + * an article by Douglas Schmidtt on double-checked locking and policy + * templates described by Andrei Alexandrescu. + * + * This is a thread safe wrapper for creating Singleton classes. The + * synchronization method and instantiation methods can be changed + * easily by specifying different policy implementations as the + * templates parameters. + * + * @code + * + * // Most common Singleton + * Singletion + * + * // Singleton that uses static storage + * Singletion + * + * // Single-threaded singleton that uses static storage (Meyers-like) + * Singletion + * + * @endcode + */ +template +class Singleton : private InstantiationPolicy, private NonCopyable { +public: + + /** + * Provide access to the single instance through double-checked locking + * + * @return T* single instance + */ + static T* instance(); + +}; + +template +T* Singleton::instance() { + + // Uses local static storage to avoid static construction + // sequence issues. (regaring when the lock is created) + static T* ptr = 0; + static LockType lock; + + if(!ptr) { + + Guard g(lock); + if(!ptr) + InstantiationPolicy::create(ptr); + + } + + return const_cast(ptr); + + } + + +}; + +#endif + + diff --git a/dep/include/zthread/SynchronousExecutor.h b/dep/include/zthread/SynchronousExecutor.h new file mode 100644 index 000000000..b6dbbef6a --- /dev/null +++ b/dep/include/zthread/SynchronousExecutor.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTSYNCHRONOUSEXECUTOR_H__ +#define __ZTSYNCHRONOUSEXECUTOR_H__ + +#include "zthread/Executor.h" +#include "zthread/Guard.h" +#include "zthread/Mutex.h" +#include "zthread/Thread.h" + +namespace ZThread { + + /** + * @class SynchronousExecutor + * + * @author Eric Crahen + * @date <2003-07-16T22:33:51-0400> + * @version 2.3.0 + * + * A SynchronousExecutor is an Executor which runs tasks using the thread that + * submits the task. It runs tasks serially, one at a time, in the order they + * were submitted to the executor. + * + * @see Executor. + */ + class SynchronousExecutor : public Executor { + + //! Serialize access + Mutex _lock; + + //! Cancellation flag + bool _canceled; + + public: + + //! Create a new SynchronousExecutor + SynchronousExecutor(); + + //! Destroy a SynchronousExecutor + virtual ~SynchronousExecutor(); + + /** + * This operation is not supported by this executor. + */ + virtual void interrupt(); + + /** + * Submit a task to this Executor, blocking the calling thread until the + * task is executed. + * + * @param task Task to be run by a thread managed by this executor + * + * @pre The Executor should have been canceled prior to this invocation. + * @post The submitted task will be run at some point in the future by this Executor. + * + * @exception Cancellation_Exception thrown if the Executor was canceled prior to + * the invocation of this function. + * + * @see Executor::execute(const Task& task) + */ + virtual void execute(const Task& task); + + /** + * @see Cancelable::cancel() + */ + virtual void cancel(); + + /** + * @see Cancelable::cancel() + */ + virtual bool isCanceled(); + + /** + * Block the calling thread until all tasks submitted prior to this invocation + * complete. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before the set of tasks being wait for can complete. + * + * @see Executor::wait() + */ + virtual void wait(); + + /** + * Block the calling thread until all tasks submitted prior to this invocation + * complete or until the calling thread is interrupted. + * + * @param timeout - maximum amount of time, in milliseconds, to wait for the + * currently submitted set of Tasks to complete. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before the set of tasks being wait for can complete. + * + * @return + * - true if the set of tasks being wait for complete before + * timeout milliseconds elapse. + * - false othewise. + */ + virtual bool wait(unsigned long timeout); + + + }; /* SynchronousExecutor */ + +} // namespace ZThread + +#endif // __ZTSYNCHRONOUSEXECUTOR_H__ diff --git a/dep/include/zthread/Task.h b/dep/include/zthread/Task.h new file mode 100644 index 000000000..6503be66f --- /dev/null +++ b/dep/include/zthread/Task.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTASK_H__ +#define __ZTTASK_H__ + +#include "zthread/CountedPtr.h" +#include "zthread/Runnable.h" + +namespace ZThread { + + class ThreadImpl; + + /** + * @class Task + * + * @author Eric Crahen + * @date <2003-07-20T05:22:38-0400> + * @version 2.3.0 + * + * A Task provides a CountedPtr wrapper for Runnable objects. + * This wrapper enables an implicit conversion from a + * Runnable* to a Task adding some syntactic sugar + * to the interface. + */ + class ZTHREAD_API Task : public CountedPtr { + public: + + +#if !defined(_MSC_VER) || (_MSC_VER > 1200) + + Task(Runnable* raw) + : CountedPtr(raw) { } + +#endif + + template + Task(U* raw) + : CountedPtr(raw) { } + + Task(const CountedPtr& ptr) + : CountedPtr(ptr) { } + + template + Task(const CountedPtr& ptr) + : CountedPtr(ptr) { } + + void operator()() { + (*this)->run(); + } + + }; /* Task */ + +} // namespace ZThread + +#endif // __ZTTASK_H__ + + + diff --git a/dep/include/zthread/Thread.h b/dep/include/zthread/Thread.h new file mode 100644 index 000000000..e1700c737 --- /dev/null +++ b/dep/include/zthread/Thread.h @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREAD_H__ +#define __ZTTHREAD_H__ + +#include "zthread/Cancelable.h" +#include "zthread/Priority.h" +#include "zthread/NonCopyable.h" +#include "zthread/Task.h" +#include "zthread/Waitable.h" + +namespace ZThread { + + class ThreadImpl; + + /** + * @class Thread + * @author Eric Crahen + * @date <2003-07-27T11:17:59-0400> + * @version 2.3.0 + * + * + * @see Task + * @see Executor + * + *

Examples

+ * - Launching a task + * - Waiting for a task + * - Sharing a task + * + *

Launching a task

+ * + * A thread is started simply by constructing a thread object and giving + * it a task to perform. The thread will continue to run its task, even + * after the Thread object used to launch the thread has gone out of scope. + * + * @code + * #include "zthread/Thread.h" + * #include + * + * using namespace ZThread; + * + * class aRunnable : public Runnable { + * + * void run() { + * + * Thread::sleep(1000); + * std::cout << "Hello from another thread" << std::endl; + * + * } + * + * }; + * + * int main() { + * + * try { + * + * // Implictly constructs a Task + * Thread t(new aRunnable); + * + * } catch(Synchronization_Exception& e) { + * std::cerr << e.what() << std::endl; + * } + * + * std::cout << "Hello from the main thread" << std::endl; + * + * // Output: + * + * // Hello from the main thread + * // Hello from another thread + * + * return 0; + * + * } + * + * @endcode + * + *

Waiting for a task

+ * + * A user can exercise some simple synchronization by waiting for a thread + * to complete running its task. + * + * @code + * #include "zthread/Thread.h" + * #include + * + * using namespace ZThread; + * + * class aRunnable : public Runnable { + * public: + * + * void run() { + * + * Thread::sleep(1000); + * std::cout << "Hello from another thread" << std::endl; + * + * } + * + * }; + * + * int main() { + * + * try { + * + * // Implictly constructs a Task + * Thread t(new aRunnable); + * t.wait(); + * + * } catch(Synchronization_Exception& e) { + * std::cerr << e.what() << std::endl; + * } + * + * std::cout << "Hello from the main thread" << std::endl; + * + * // Output: + * + * // Hello from another thread + * // Hello from the main thread + * + * return 0; + * + * } + * + * @endcode + * + *

Sharing a task

+ * + * The same task can be shared by more than one thread. A Task is constructed + * from a Runnable, and that Task object is copied by value and handed off to + * each thread. + * + * @code + * #include "zthread/Thread.h" + * #include + * + * using namespace ZThread; + * + * class aRunnable : public Runnable { + * + * void run() { + * + * Thread::sleep(1000); + * std::cout << "Hello from another thread" << std::endl; + * + * } + * + * }; + * + * int main() { + * + * try { + * + * // Explictly constructs a Task + * Task task(new aRunnable); + * + * // Two threads created to run the same Task + * Thread t1(task); + * Thread t2(task); + * + * } catch(Synchronization_Exception& e) { + * std::cerr << e.what() << std::endl; + * } + * + * std::cout << "Hello from the main thread" << std::endl; + * + * // Output: + * + * // Hello from the main thread + * // Hello from another thread + * // Hello from another thread + * + * return 0; + * + * } + * + * @endcode + */ + class ZTHREAD_API Thread + : public Cancelable, public Waitable, public NonCopyable { + + //! Delegate + ThreadImpl* _impl; + + public: + + /** + * Create a Thread that represents the current thread. + * Using the static members of Thread should be preferred over using this constructor + */ + Thread(); + + /** + * Create a Thread that spawns a new thread to run the given task. + * + * @param task Task to be run by a thread managed by this executor + * @param autoCancel flag to requestion automatic cancellation + * + * @post if the autoCancel flag was true, this thread will + * automatically be canceled when main() goes out of scope. + */ + Thread(const Task&, bool autoCancel = false); + + //! Destroy the Thread + ~Thread(); + + //! Comparison operator + bool operator==(const Thread& t) const; + + //! Comparison operator + inline bool operator!=(const Thread& t) const { + return !(*this == t); + } + + /** + * Wait for the thread represented by this object to complete its task. + * The calling thread is blocked until the thread represented by this + * object exits. + * + * @exception Deadlock_Exception thrown if thread attempts to join itself + * @exception InvalidOp_Exception thrown if the thread cannot be joined + * @exception Interrupted_Exception thrown if the joining thread has been interrupt()ed + */ + void wait(); + + /** + * Wait for the thread represented by this object to complete its task. + * The calling thread is blocked until the thread represented by this + * object exits, or until the timeout expires. + * + * @param timeout maximum amount of time (milliseconds) this method + * could block the calling thread. + * + * @return + * - true if the thread task complete before timeout + * milliseconds elapse. + * - false othewise. + * + * @exception Deadlock_Exception thrown if thread attempts to join itself + * @exception InvalidOp_Exception thrown if the thread cannot be joined + * @exception Interrupted_Exception thrown if the joining thread has been interrupt()ed + */ + bool wait(unsigned long timeout); + + /** + * Change the priority of this Thread. This will change the actual + * priority of the thread when the OS supports it. + * + * If there is no real priority support, it's simulated. + * + * @param p - new Priority + */ + void setPriority(Priority p); + + /** + * Get the priority of this Thread. + * + * @return Priority + */ + Priority getPriority(); + + /** + * Interrupts this thread, setting the interrupted status of the thread. + * This status is cleared by one of three methods. + * + * If this thread is blocked when this method is called, the thread will + * abort that blocking operation with an Interrupted_Exception. + * + * - The first is by attempting an operation on a synchronization object that + * would normally block the calling thread; Instead of blocking the calling + * the calling thread, the function that would normally block will thrown an + * Interrupted_Exception and clear the interrupted status of the thread. + * + * - The second is by calling Thread::interrupted(). + * + * - The third is by calling Thread::canceled(). + * + * Threads already blocked by an operation on a synchronization object will abort + * that operation with an Interrupted_Exception, clearing the threads interrupted + * status as in the first case described above. + * + * Interrupting a thread that is no longer running will have no effect. + * + * @return + * - true if the thread was interrupted while not blocked by a wait + * on a synchronization object. + * - false othewise. + */ + bool interrupt(); + + /** + * Tests whether the current Thread has been interrupt()ed, clearing + * its interruption status. + * + * @return + * - true if the Thread was interrupted. + * - false otherwise. + * + * @post The interrupted status of the current thread will be cleared, + * allowing it to perform a blocking operation on a synchronization + * object without throwing an exception. + */ + static bool interrupted(); + + /** + * Tests whether the current Thread has been canceled, and clears the + * interrupted status. + * + * @return bool true only if the Thread::cancel() has been invoked. + */ + static bool canceled(); + + /** + * Tests whether this thread has been canceled. If called from the context + * of this thread, the interrupted status is cleared. + * + * @return + * - true if the Thread was canceled. + * - false otherwise. + * + * @see Cancelable::isCanceled() + */ + virtual bool isCanceled(); + + /** + * Interrupt and cancel this thread in a single operation. The thread will + * return true whenever its cancelation status is tested in the future. + * + * @exception InvalidOp_Exception thrown if a thread attempts to cancel itself + * + * @see Thread::interrupt() + * @see Cancelable::cancel() + */ + virtual void cancel(); + + /** + * Put the currently executing thread to sleep for a given amount of + * time. + * + * @param timeout maximum amount of time (milliseconds) this method could block + * + * @exception Interrupted_Exception thrown if the threads sleep is interrupted + * before timeout milliseconds expire. + */ + static void sleep(unsigned long timeout); + + /** + * Cause the currently executing thread to yield, allowing the scheduler + * to assign some execution time to another thread. + */ + static void yield(); + + + }; /* Thread */ + + +} // namespace ZThread + +#endif // __ZTTHREAD_H__ + + + diff --git a/dep/include/zthread/ThreadLocal.h b/dep/include/zthread/ThreadLocal.h new file mode 100644 index 000000000..bb83a0fe3 --- /dev/null +++ b/dep/include/zthread/ThreadLocal.h @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADLOCAL_H__ +#define __ZTTHREADLOCAL_H__ + +#include "zthread/ThreadLocalImpl.h" + +namespace ZThread { + + /** + * @class ThreadLocal + * + * @author Eric Crahen + * @date <2003-07-27T11:18:21-0400> + * @version 2.3.0 + * + * Provides access to store and retrieve value types to and from a thread local + * storage context. A thread local storage context consists of the calling thread + * a specific ThreadLocal object. Since this context is specific to each thread + * whenever a value is stored in a ThreadLocal that is accessible from multiple + * threads, it can only be retrieved by the thread that stored it. + * + * The first time a thread accesses the value associated with a thread local storage + * context, a value is created. That value is either an initial value (determined by + * InitialValueT) or an inherited value (determined by ChildValueT). + * + * - If a threads parent had no value associated with a ThreadLocal when the thread was created, + * then the InitialValueT functor is used to create an initial value. + * + * - If a threads parent did have a value associated with a ThreadLocal when the thread was + * created, then the childValueT functor is used to create an initial value. + * + * Not all ThreadLocal's support the inheritance of values from parent threads. The default + * behavoir is to create values through the InitialValueT functor for all thread when + * they first access a thread local storage context. + * + * - Inheritance is enabled automatically when a user supplies a ChildValueT functor other + * than the default one supplied. + * + * - Inheritance can be controlled explicitly by the user through a third functor, + * InheritableValueT. + * + *

Examples

+ * + * - Default initial value + * - User-specified initial value + * - User-specified inherited value + * + *

Default initial value

+ * A ThreadLocal that does not inherit, and uses the default value + * for an int as its initial value. + * + * @code + * + * #include "zthread/ThreadLocal.h" + * #include "zthread/Thread.h" + * #include + * + * using namespace ZThread; + * + * class aRunnable : public Runnable { + * ThreadLocal localValue; + * public: + * void run() { + * std::cout << localValue.get() << std::endl; + * } + * }; + * + * int main() { + * + * // Create a shared task to display ThreadLocal values + * Task task(new aRunnable); + * + * Thread t0(task); t0.wait(); + * Thread t1(task); t1.wait(); + * Thread t2(task); t2.wait(); + * + * // Output: + * + * // 0 + * // 0 + * // 0 + * + * return 0; + * + * } + * + * @endcode + * + *

User-specified initial value

+ * A ThreadLocal that does not inherit, and uses a custom initial value. + * + * @code + * + * #include "zthread/ThreadLocal.h" + * #include "zthread/Thread.h" + * #include + * + * using namespace ZThread; + * + * struct anInitialValueFn { + * int operator()() { + * static int next = 100; + * int val = next; next += 100; + * return val; + * } + * }; + * + * class aRunnable : public Runnable { + * ThreadLocal localValue; + * public: + * void run() { + * std::cout << localValue.get() << std::endl; + * } + * }; + * + * int main() { + * + * // Create a shared task to display ThreadLocal values + * Task task(new aRunnable); + * + * Thread t0(task); t0.wait(); + * Thread t1(task); t1.wait(); + * Thread t2(task); t2.wait(); + * + * // Output: + * + * // 100 + * // 200 + * // 300 + * + * return 0; + * + * } + * + * @endcode + * + *

User-specified inherited value

+ * A ThreadLocal that does inherit and modify child values. + * (The default initial value functor is used) + * + * @code + * + * #include "zthread/ThreadLocal.h" + * #include "zthread/Thread.h" + * #include + * + * using namespace ZThread; + * + * struct anInheritedValueFn { + * int operator()(int val) { + * return val + 100; + * } + * }; + * + * // This Runnable associates no ThreadLocal value in the main thread; so + * // none of the child threads have anything to inherit. + * class aRunnable : public Runnable { + * ThreadLocal, anInheritedValueFn> localValue; + * public: + * void run() { + * std::cout << localValue.get() << std::endl; + * } + * }; + * + * // This Runnable associates a ThreadLocal value in the main thread which + * // is inherited when the child threads are created. + * class anotherRunnable : public Runnable { + * ThreadLocal, anInheritedValueFn> localValue; + * public: + * anotherRunnable() { + * localValue.set(100); + * } + * void run() { + * std::cout << localValue.get() << std::endl; + * } + * }; + * + * int main() { + * + * // Create a shared task to display ThreadLocal values + * Task task(new aRunnable); + * + * Thread t0(task); t0.wait(); + * Thread t1(task); t1.wait(); + * Thread t2(task); t2.wait(); + * + * // Output: + * + * // 0 + * // 0 + * // 0 + * + * task = Task(new anotherRunnable); + * + * Thread t10(task); t10.wait(); + * Thread t11(task); t11.wait(); + * Thread t12(task); t12.wait(); + * + * // Output: + * + * // 200 + * // 200 + * // 200 + * + * return 0; + * + * } + * + * @endcode + * + *

Parameters

+ * + * InitialValueT + * + * This template parameter should indicate the functor used to set + * the initial value. It should support the following operator: + * + * + * // required operator + * T operator() + * + * // supported expression + * InitialValueT()() + * + * + * + * ChildValueT + * + * This template parameter should indicate the functor used to set + * the value that will be inherited by thread whose parent have associated + * a value with the ThreadLocal's context at the time they are created. + * It should support the following operator: + * + * + * // required operator + * T operator(const T& parentValue) + * + * // supported expression + * ChildValueT()(parentValue) + * + * + * + * InheritableValueT + * + * This template parameter should indicate the functor, used to determine + * wheather or not this ThreadLocal will allow values from a parent threads + * context to be inherited by child threads when they are created. + * It should support the following operator: + * + * + * // required operator + * bool operator(const T& childValueFunctor) + * + * // supported expression + * InheritableValueT()( ChildValueT() ) + * + * + */ + template < + typename T, + typename InitialValueT = ThreadLocalImpl::InitialValueFn, + typename ChildValueT = ThreadLocalImpl::UniqueChildValueFn, + typename InheritableValueT = ThreadLocalImpl::InheritableValueFn + > + class ThreadLocal : private ThreadLocalImpl { + + typedef ThreadLocalImpl::ValuePtr ValuePtr; + + class Value : public ThreadLocalImpl::Value { + + T value; + + public: + + Value() : value( InitialValueT()() ) { } + + Value(const Value& v) : value( ChildValueT()(v.value) ) { } + + virtual ~Value() { } + + operator T() { return value; } + + const Value& operator=(const T& v) { value = v; } + + virtual bool isInheritable() const { + return InheritableValueT()( ChildValueT() ); + } + + virtual ValuePtr clone() const { + return ValuePtr( new Value(*this) ); + } + + }; + + static ValuePtr createValue() { + return ValuePtr( new Value ); + } + + public: + + /** + * Get the value associated with the context (this ThreadLocal and + * the calling thread) of the invoker. If no value is currently + * associated, then an intial value is created and associated; that value + * is returned. + * + * @return T associated value. + * + * @post If no value has been associated with the invoking context + * then an inital value will be associated. That value is + * created by the InitialValueT functor. + */ + T get() const { + return (T)reinterpret_cast( *value(&createValue) ); + } + + /** + * Replace the value associated with the context (this ThreadLocal and + * the calling thread) of the invoker. If no value is currently + * associated, then an intial value is first created and subsequently + * replaced by the new value. + * + * @param v value of type T to associate. + * + * @post If no value has been associated with the invoking context + * then an inital value will first be associated. That value is + * created by the InitialValueT functor and then + * replaced with the new value. + */ + void set(T v) const { + reinterpret_cast( *value(&createValue) ) = v; + } + + /** + * Remove any value current associated with this ThreadLocal. + * + * @post Upon thier next invocation the get() and set() functions will behave as + * if no value has been associated with this ThreadLocal and an + * initial value will be generated. + */ + void clear() const { + ThreadLocalImpl::clear(); + } + + /** + * Remove any value current associated with any ThreadLocal. + * + * @post Upon thier next invocation the get() and set() functions will behave as + * if no value has been associated with any ThreadLocal and new + * initial values will be generated. + */ + static void clearAll() { + ThreadLocalImpl::clearAll(); + } + + }; + + +} // namespace ZThread + +#endif // __ZTTHREADLOCAL_H__ diff --git a/dep/include/zthread/ThreadLocalImpl.h b/dep/include/zthread/ThreadLocalImpl.h new file mode 100644 index 000000000..3b4046f8f --- /dev/null +++ b/dep/include/zthread/ThreadLocalImpl.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADLOCALIMPL_H__ +#define __ZTTHREADLOCALIMPL_H__ + +#include "zthread/CountedPtr.h" + +namespace ZThread { + + /** + * @class ThreadLocalImpl + * @author Eric Crahen + * @date <2003-07-27T10:23:19-0400> + * @version 2.3.0 + * + * @see ThreadLocal + */ + class ZTHREAD_API ThreadLocalImpl : private NonCopyable { + public: + + class Value; + typedef CountedPtr ValuePtr; + + //! + class Value { + Value& operator=(const Value&); + public: + virtual ~Value() {} + virtual bool isInheritable() const = 0; + virtual ValuePtr clone() const = 0; + }; + + //! Create a ThreadLocalImpl + ThreadLocalImpl(); + + //! Destroy a ThreadLocalImpl + ~ThreadLocalImpl(); + + /** + * @class InitialValueFn + */ + template + struct InitialValueFn { + T operator()() { return T(); } + }; + + /** + * @class ChildValueFn + */ + struct ChildValueFn { + template + T operator()(const T& value) { return T(value); } + }; + + /** + * @class UniqueChildValueFn + */ + struct UniqueChildValueFn : public ChildValueFn { }; + + /** + * @class InheritableValueFn + */ + struct InheritableValueFn { + + template + bool operator()(const T&) { return true; } + + bool operator()(const UniqueChildValueFn&) { return false; } + + }; + + protected: + + //! Get the Value for the current thread + ValuePtr value( ValuePtr (*pfn)() ) const; + + //! Clear any value set for this thread + void clear() const; + + //! Clear any value set with any ThreadLocal for this thread + static void clearAll(); + + }; + +} // __ZTTHREADLOCALIMPL_H__ + +#endif + diff --git a/dep/include/zthread/ThreadedExecutor.h b/dep/include/zthread/ThreadedExecutor.h new file mode 100644 index 000000000..9bc29b3c4 --- /dev/null +++ b/dep/include/zthread/ThreadedExecutor.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADEDEXECUTOR_H__ +#define __ZTTHREADEDEXECUTOR_H__ + +#include "zthread/Executor.h" +#include "zthread/CountedPtr.h" + +namespace ZThread { + + namespace { class ExecutorImpl; } + + /** + * @class ThreadedExecutor + * + * @author Eric Crahen + * @date <2003-07-16T22:39:13-0400> + * @version 2.3.0 + * + * A ThreadedExecutor spawns a new thread to execute each task submitted. + * A ThreadedExecutor supports the following optional operations, + * + * - cancel()ing a ThreadedExecutor will cause it to stop accepting + * new tasks. + * + * - interrupt()ing a ThreadedExecutor will cause the any thread running + * a task which was submitted prior to the invocation of this function to + * be interrupted during the execution of that task. + * + * - wait()ing on a ThreadedExecutor will block the calling thread + * until all tasks that were submitted prior to the invocation of this function + * have completed. + * + * @see Executor. + */ + class ThreadedExecutor : public Executor { + + CountedPtr< ExecutorImpl > _impl; + + public: + + //! Create a new ThreadedExecutor + ThreadedExecutor(); + + //! Destroy a ThreadedExecutor + virtual ~ThreadedExecutor(); + + /** + * Interrupting a ThreadedExecutor will cause an interrupt() to be sent + * to every Task that has been submitted at the time this function is + * called. Tasks that are submitted after this function is called will + * not be interrupt()ed; unless this function is invoked again(). + */ + virtual void interrupt(); + + /** + * Submit a task to this Executor. This will not block the current thread + * for very long. A new thread will be created and the task will be run() + * within the context of that new thread. + * + * @exception Cancellation_Exception thrown if this Executor has been canceled. + * The Task being submitted will not be executed by this Executor. + * + * @see Executor::execute(const Task&) + */ + virtual void execute(const Task&); + + /** + * @see Cancelable::cancel() + */ + virtual void cancel(); + + /** + * @see Cancelable::isCanceled() + */ + virtual bool isCanceled(); + + /** + * Waiting on a ThreadedExecutor will block the current thread until all + * tasks submitted to the Executor up until the time this function was called + * have completed. + * + * Tasks submitted after this function is called will not delay a thread that + * was already waiting on the Executor any longer. In order to wait for + * those tasks to complete as well, another wait() would be needed. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupted + * before the set of tasks for which it was waiting complete. + * + * @see Waitable::wait() + */ + virtual void wait(); + + /** + * Operates the same as ThreadedExecutor::wait() but with a timeout. + * + * @param timeout maximum amount of time, in milliseconds, to wait for the + * currently submitted set of Tasks to complete. + * + * @exception Interrupted_Exception thrown if the calling thread is interrupt()ed + * while waiting for the current set of Tasks to complete. + * + * @return + * - true if the set of tasks running at the time this function is invoked complete + * before timeout milliseconds elapse. + * - false othewise. + * + * @see Waitable::wait(unsigned long timeout) + */ + virtual bool wait(unsigned long timeout); + + }; /* ThreadedExecutor */ + +} // namespace ZThread + +#endif // __ZTTHREADEDEXECUTOR_H__ diff --git a/dep/include/zthread/Time.h b/dep/include/zthread/Time.h new file mode 100644 index 000000000..374c4fd6b --- /dev/null +++ b/dep/include/zthread/Time.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTIME_H__ +#define __ZTTIME_H__ + +#include "zthread/Config.h" + +namespace ZThread { + +/** + * @class Time + * @author Eric Crahen + * @date <2003-07-16T17:52:46-0400> + * @version 2.2.11 + * + * The Time class provides access to time values relative to when the program + * was started. In other words, this class might be thought of as a timer that + * starts at 0 and counts upwards. This class offers millisecond resolution. + */ +class ZTHREAD_API Time { + + unsigned long _seconds; + unsigned long _milliseconds; + + //! Create a new Time object + Time(unsigned long secs, unsigned long millis) + : _seconds(secs), _milliseconds(millis) { } + + /** + * Set the number of milliseconds in this Time object. + * + * @param millis - new milliseconds value + * @return unsigned long old milliseconds value + */ + unsigned long milliseconds(unsigned long millis) { + + unsigned long n = _milliseconds; + _milliseconds = millis; + + return n; + + } + + /** + * Set the number of seconds in this Time object. + * + * @param secs - new seconds value + * @return unsigned long old seconds value + */ + unsigned long seconds(unsigned long secs) { + + unsigned long n = _seconds; + _seconds = secs; + + return n; + + } + + public: + + + /** + * Create a Time object with the current time relative to the + * beginning of the program. + */ + Time(); + + /** + * Create a Time object by copying another. + * + * @param t - Time object to copy. + */ + Time(const Time& t) + : _seconds(t._seconds), _milliseconds(t._milliseconds) { } + + + /** + * Get the number of milliseconds in this Time object. + * + * @return unsigned long milliseconds value + */ + unsigned long milliseconds() const { + return _milliseconds; + } + + /** + * Get the number of seconds in this Time object. + * + * @return unsigned long seconds value + */ + unsigned long seconds() const { + return _seconds; + } + + /** + * Add some number of milliseconds to this Time object. + * + * @param millis - number of milliseconds to add to this Time object + * @return const Time& this object + */ + const Time& operator+=(unsigned long millis) { + + _milliseconds += millis; + _seconds += (_milliseconds / 1000); + _milliseconds %= 1000; + + return *this; + + } + + /** + * Subtract some number of milliseconds to this Time object. + * + * @param millis - number of milliseconds to subtract from this Time object + * @return const Time& this object + */ +const Time& operator-=(unsigned long millis) { + + if(_milliseconds > millis) + _milliseconds -= millis; + + else { + + while(_seconds > 0 && _milliseconds < millis) { + + _milliseconds += 1000; + _seconds -= 1; + + } + + _milliseconds = (_milliseconds < millis) ? 0 : (_milliseconds - millis); + + } + + return *this; + +} + + + /** + * Add the value of another Time object to this one. + * + * @param t - Time object whose value should be added to this object + * @return const Time& this object + */ + const Time& operator+=(const Time& t) { + + _milliseconds += t.milliseconds(); + _seconds += (_milliseconds / 1000) + t.seconds(); + _milliseconds %= 1000; + + return *this; + + } + + /** + * Subtract the value of another Time object from this one. + * This function has a floor of 0. + * + * @param t - Time object whose value should be subtracted from this object + * @return const Time& this object + */ +const Time& operator-=(const Time& t) { + + unsigned long millis = t.milliseconds(); + unsigned long secs = t.seconds(); + + if(_seconds >= secs) { + + if(_milliseconds > millis) { + _milliseconds -= millis; + _seconds -= secs; + + } else { + + while(_seconds > 0 && _milliseconds < millis) { + + _milliseconds += 1000; + _seconds -= 1; + + } + + _milliseconds = (_milliseconds < millis) ? 0 : (_milliseconds - millis); + _seconds = (_seconds < secs) ? 0 : (_seconds - secs); + + } + + } else { + + _milliseconds = 0; + _seconds = 0; + + } + + return *this; + +} + +}; + + + +} // namespace ZThread + +#endif // __ZTTIME_H__ diff --git a/dep/include/zthread/Waitable.h b/dep/include/zthread/Waitable.h new file mode 100644 index 000000000..3d925f2a6 --- /dev/null +++ b/dep/include/zthread/Waitable.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTWAITABLE_H__ +#define __ZTWAITABLE_H__ + +#include "zthread/Exceptions.h" + +namespace ZThread { + + /** + * @class Waitable + * + * @author Eric Crahen + * @date <2003-07-16T22:16:41-0400> + * @version 2.3.0 + * + * The Waitable interface defines a common method of adding generic wait semantics + * to a class. + * + * Waiting + * + * An object implementing the Waitable interface externalizes a mechanism for testing + * some internal condition. Another object may wait()s for a Waitable object; + * in doing so, it wait()s for that condition to become true by blocking the caller + * while the condition is false. + * + * For example, a Condition is Waitable object that extends wait semantics + * so that wait()ing means a thread is blocked until some external stimulus + * specifically performs an operation on the Condition to make its internal condition true. + * (serialization aside) + * + * A Barrier extends wait semantics so that wait()ing mean waiting for other + * waiters, and may include automatically resetting the condition once a wait is complete. + * + * @see Condition + * @see Barrier + * @see Executor + */ + class Waitable { + public: + + //! Destroy a Waitable object. + virtual ~Waitable() {} + + /** + * Waiting on an object will generally cause the calling thread to be blocked + * for some indefinite period of time. The thread executing will not proceed + * any further until the Waitable object releases it unless or an exception + * is thrown. + */ + virtual void wait() = 0; + + /** + * Waiting on an object will generally cause the calling thread to be blocked + * for some indefinite period of time. The thread executing will not proceed + * any further until the Waitable object releases it unless or an exception + * is thrown. + * + * @param timeout maximum amount of time, in milliseconds, to spend waiting. + * + * @return + * - true if the set of tasks being wait for complete before + * timeout milliseconds elapse. + * - false othewise. + */ + virtual bool wait(unsigned long timeout) = 0; + + + }; /* Waitable */ + + +} // namespace ZThread + +#endif // __ZTWAITABLE_H__ diff --git a/dep/include/zthread/ZThread.h b/dep/include/zthread/ZThread.h new file mode 100644 index 000000000..1df5bb67a --- /dev/null +++ b/dep/include/zthread/ZThread.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTLIBRARY_H__ +#define __ZTLIBRARY_H__ + + +#include "zthread/Barrier.h" +#include "zthread/BiasedReadWriteLock.h" +#include "zthread/BlockingQueue.h" +#include "zthread/BoundedQueue.h" +#include "zthread/Cancelable.h" +#include "zthread/ClassLockable.h" +#include "zthread/ConcurrentExecutor.h" +#include "zthread/Condition.h" +#include "zthread/Config.h" +#include "zthread/CountedPtr.h" +#include "zthread/CountingSemaphore.h" +#include "zthread/Exceptions.h" +#include "zthread/Executor.h" +#include "zthread/FairReadWriteLock.h" +#include "zthread/FastMutex.h" +#include "zthread/FastRecursiveMutex.h" +#include "zthread/Guard.h" +#include "zthread/Lockable.h" +#include "zthread/LockedQueue.h" +#include "zthread/MonitoredQueue.h" +#include "zthread/Mutex.h" +#include "zthread/NonCopyable.h" +#include "zthread/PoolExecutor.h" +#include "zthread/Priority.h" +#include "zthread/PriorityCondition.h" +#include "zthread/PriorityInheritanceMutex.h" +#include "zthread/PriorityMutex.h" +#include "zthread/PrioritySemaphore.h" +#include "zthread/Queue.h" +#include "zthread/ReadWriteLock.h" +#include "zthread/RecursiveMutex.h" +#include "zthread/Runnable.h" +#include "zthread/Semaphore.h" +#include "zthread/Singleton.h" +#include "zthread/SynchronousExecutor.h" +#include "zthread/Thread.h" +#include "zthread/ThreadLocal.h" +#include "zthread/Time.h" +#include "zthread/Waitable.h" + +#endif diff --git a/dep/lib/Makefile.am b/dep/lib/Makefile.am new file mode 100644 index 000000000..35b272b8e --- /dev/null +++ b/dep/lib/Makefile.am @@ -0,0 +1,50 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## Additional files to include when running 'make dist' +# Debug libraries for Win32 builds. +EXTRA_DIST = \ + win32_debug/libeay32.dll \ + win32_debug/libeay32.lib \ + win32_debug/libmySQL.dll \ + win32_debug/libmySQL.lib \ + win32_debug/sqlite.lib + +# Release libraries for Win32 builds. +EXTRA_DIST += \ + win32_release/libeay32.dll \ + win32_release/libeay32.lib \ + win32_release/libmySQL.dll \ + win32_release/libmySQL.lib \ + win32_release/sqlite.lib + +# Debug libraries for Win64 builds. +EXTRA_DIST += \ + x64_Debug/libeay32.dll \ + x64_Debug/libeay32.lib \ + x64_Debug/libmySQL.dll \ + x64_Debug/libmySQL.lib + +# Release libraries for Win64 builds. +EXTRA_DIST += \ + x64_release/libeay32.dll \ + x64_release/libeay32.lib \ + x64_release/libmySQL.dll \ + x64_release/libmySQL.lib diff --git a/dep/lib/win32_debug/dbghelp.dll b/dep/lib/win32_debug/dbghelp.dll new file mode 100644 index 000000000..6f646de49 Binary files /dev/null and b/dep/lib/win32_debug/dbghelp.dll differ diff --git a/dep/lib/win32_debug/libeay32.dll b/dep/lib/win32_debug/libeay32.dll new file mode 100644 index 000000000..f62b057bb Binary files /dev/null and b/dep/lib/win32_debug/libeay32.dll differ diff --git a/dep/lib/win32_debug/libeay32.lib b/dep/lib/win32_debug/libeay32.lib new file mode 100644 index 000000000..7f89f68e4 Binary files /dev/null and b/dep/lib/win32_debug/libeay32.lib differ diff --git a/dep/lib/win32_debug/libmySQL.dll b/dep/lib/win32_debug/libmySQL.dll new file mode 100644 index 000000000..8bc44d3a4 Binary files /dev/null and b/dep/lib/win32_debug/libmySQL.dll differ diff --git a/dep/lib/win32_debug/libmySQL.lib b/dep/lib/win32_debug/libmySQL.lib new file mode 100644 index 000000000..bdf57ad35 Binary files /dev/null and b/dep/lib/win32_debug/libmySQL.lib differ diff --git a/dep/lib/win32_debug/sqlite.lib b/dep/lib/win32_debug/sqlite.lib new file mode 100644 index 000000000..aa335a68d Binary files /dev/null and b/dep/lib/win32_debug/sqlite.lib differ diff --git a/dep/lib/win32_debug/vld.dll b/dep/lib/win32_debug/vld.dll new file mode 100644 index 000000000..dee162c54 Binary files /dev/null and b/dep/lib/win32_debug/vld.dll differ diff --git a/dep/lib/win32_debug/vld.lib b/dep/lib/win32_debug/vld.lib new file mode 100644 index 000000000..0cf374670 Binary files /dev/null and b/dep/lib/win32_debug/vld.lib differ diff --git a/dep/lib/win32_release/dbghelp.dll b/dep/lib/win32_release/dbghelp.dll new file mode 100644 index 000000000..597188d77 Binary files /dev/null and b/dep/lib/win32_release/dbghelp.dll differ diff --git a/dep/lib/win32_release/libeay32.dll b/dep/lib/win32_release/libeay32.dll new file mode 100644 index 000000000..e078a3548 Binary files /dev/null and b/dep/lib/win32_release/libeay32.dll differ diff --git a/dep/lib/win32_release/libeay32.lib b/dep/lib/win32_release/libeay32.lib new file mode 100644 index 000000000..b5ad42ae2 Binary files /dev/null and b/dep/lib/win32_release/libeay32.lib differ diff --git a/dep/lib/win32_release/libmySQL.dll b/dep/lib/win32_release/libmySQL.dll new file mode 100644 index 000000000..594aaf852 Binary files /dev/null and b/dep/lib/win32_release/libmySQL.dll differ diff --git a/dep/lib/win32_release/libmySQL.lib b/dep/lib/win32_release/libmySQL.lib new file mode 100644 index 000000000..dc1e360b2 Binary files /dev/null and b/dep/lib/win32_release/libmySQL.lib differ diff --git a/dep/lib/win32_release/sqlite.lib b/dep/lib/win32_release/sqlite.lib new file mode 100644 index 000000000..aa335a68d Binary files /dev/null and b/dep/lib/win32_release/sqlite.lib differ diff --git a/dep/lib/x64_Debug/libeay32.dll b/dep/lib/x64_Debug/libeay32.dll new file mode 100644 index 000000000..75058bd0c Binary files /dev/null and b/dep/lib/x64_Debug/libeay32.dll differ diff --git a/dep/lib/x64_Debug/libeay32.lib b/dep/lib/x64_Debug/libeay32.lib new file mode 100644 index 000000000..679578e78 Binary files /dev/null and b/dep/lib/x64_Debug/libeay32.lib differ diff --git a/dep/lib/x64_Debug/libmySQL.dll b/dep/lib/x64_Debug/libmySQL.dll new file mode 100644 index 000000000..0abe00031 Binary files /dev/null and b/dep/lib/x64_Debug/libmySQL.dll differ diff --git a/dep/lib/x64_Debug/libmysql.lib b/dep/lib/x64_Debug/libmysql.lib new file mode 100644 index 000000000..60a050d8a Binary files /dev/null and b/dep/lib/x64_Debug/libmysql.lib differ diff --git a/dep/lib/x64_release/libeay32.dll b/dep/lib/x64_release/libeay32.dll new file mode 100644 index 000000000..75058bd0c Binary files /dev/null and b/dep/lib/x64_release/libeay32.dll differ diff --git a/dep/lib/x64_release/libeay32.lib b/dep/lib/x64_release/libeay32.lib new file mode 100644 index 000000000..679578e78 Binary files /dev/null and b/dep/lib/x64_release/libeay32.lib differ diff --git a/dep/lib/x64_release/libmySQL.dll b/dep/lib/x64_release/libmySQL.dll new file mode 100644 index 000000000..34ff51ad5 Binary files /dev/null and b/dep/lib/x64_release/libmySQL.dll differ diff --git a/dep/lib/x64_release/libmysql.lib b/dep/lib/x64_release/libmysql.lib new file mode 100644 index 000000000..c13543e0c Binary files /dev/null and b/dep/lib/x64_release/libmysql.lib differ diff --git a/dep/src/Makefile.am b/dep/src/Makefile.am new file mode 100644 index 000000000..f4ca23858 --- /dev/null +++ b/dep/src/Makefile.am @@ -0,0 +1,23 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = g3dlite sockets zlib zthread + +## Additional files to include when running 'make dist' +# Nothing yet. diff --git a/dep/src/g3dlite/AABox.cpp b/dep/src/g3dlite/AABox.cpp new file mode 100644 index 000000000..d147a1080 --- /dev/null +++ b/dep/src/g3dlite/AABox.cpp @@ -0,0 +1,299 @@ +/** + @file AABox.cpp + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2004-01-10 + @edited 2006-01-11 +*/ + +#include "G3D/platform.h" +# if defined(_MSC_VER) && (_MSC_VER <= 1200) + // VC6 std:: has signed/unsigned problems +# pragma warning (disable : 4018) +# endif + +#include +#include "G3D/AABox.h" +#include "G3D/Box.h" +#include "G3D/Plane.h" +#include "G3D/Sphere.h" + + +namespace G3D { + +Box AABox::toBox() const { + return Box(lo, hi); +} + + + +void AABox::split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const { + // Low, medium, and high along the chosen axis + float L = G3D::min(location, lo[axis]); + float M = G3D::min(G3D::max(location, lo[axis]), hi[axis]); + float H = G3D::max(location, hi[axis]); + + // Copy over this box. + high = low = *this; + + // Now move the split points along the special axis + low.lo[axis] = L; + low.hi[axis] = M; + high.lo[axis] = M; + high.hi[axis] = H; +} + +#if 0 +Vector3 AABox::randomSurfacePoint() const { + Vector3 extent = hi - lo; + float aXY = extent.x * extent.y; + float aYZ = extent.y * extent.z; + float aZX = extent.z * extent.x; + + float r = (float)random(0, aXY + aYZ + aZX); + + // Choose evenly between positive and negative face planes + float d = ((float)random(0, 1) < 0.5f) ? 0.0f : 1.0f; + + // The probability of choosing a given face is proportional to + // its area. + if (r < aXY) { + return + lo + + Vector3( + (float)random(0, extent.x), + (float)random(0, extent.y), + d * extent.z); + } else if (r < aYZ) { + return + lo + + Vector3( + d * extent.x, + (float)random(0, extent.y), + (float)random(0, extent.z)); + } else { + return + lo + + Vector3( + (float)random(0, extent.x), + d * extent.y, + (float)random(0, extent.z)); + } +} + + +Vector3 AABox::randomInteriorPoint() const { + return Vector3( + (float)random(lo.x, hi.x), + (float)random(lo.y, hi.y), + (float)random(lo.z, hi.z)); +} +#endif + + +bool AABox::intersects(const AABox& other) const { + // Must be overlap along all three axes. + // Try to find a separating axis. + + for (int a = 0; a < 3; ++a) { + + // |--------| + // |------| + + if ((lo[a] > other.hi[a]) || + (hi[a] < other.lo[a])) { + return false; + } + } + + return true; +} + + +bool AABox::culledBy( + const Array& plane, + int& cullingPlaneIndex, + const uint32 inMask, + uint32& outMask) const { + + return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask); +} + + +bool AABox::culledBy( + const Array& plane, + int& cullingPlaneIndex, + const uint32 inMask) const { + + return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask); +} + + +int AABox::dummy = 0; + + +bool AABox::culledBy( + const class Plane* plane, + int numPlanes, + int& cullingPlane, + const uint32 _inMask, + uint32& childMask) const { + + uint32 inMask = _inMask; + assert(numPlanes < 31); + + childMask = 0; + + const bool finite = + (abs(lo.x) < G3D::inf()) && + (abs(hi.x) < G3D::inf()) && + (abs(lo.y) < G3D::inf()) && + (abs(hi.y) < G3D::inf()) && + (abs(lo.z) < G3D::inf()) && + (abs(hi.z) < G3D::inf()); + + // See if there is one plane for which all of the + // vertices are in the negative half space. + for (int p = 0; p < numPlanes; p++) { + + // Only test planes that are not masked + if ((inMask & 1) != 0) { + + Vector3 corner; + + int numContained = 0; + int v = 0; + + // We can early-out only if we have found one point on each + // side of the plane (i.e. if we are straddling). That + // occurs when (numContained < v) && (numContained > 0) + for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) { + // Unrolling these 3 if's into a switch decreases performance + // by about 2x + corner.x = (v & 1) ? hi.x : lo.x; + corner.y = (v & 2) ? hi.y : lo.y; + corner.z = (v & 4) ? hi.z : lo.z; + + if (finite) { // this branch is highly predictable + if (plane[p].halfSpaceContainsFinite(corner)) { + ++numContained; + } + } else { + if (plane[p].halfSpaceContains(corner)) { + ++numContained; + } + } + } + + if (numContained == 0) { + // Plane p culled the box + cullingPlane = p; + + // The caller should not recurse into the children, + // since the parent is culled. If they do recurse, + // make them only test against this one plane, which + // will immediately cull the volume. + childMask = 1 << p; + return true; + + } else if (numContained < v) { + // The bounding volume straddled the plane; we have + // to keep testing against this plane + childMask |= (1 << p); + } + } + + // Move on to the next bit. + inMask = inMask >> 1; + } + + // None of the planes could cull this box + cullingPlane = -1; + return false; +} + + +bool AABox::culledBy( + const class Plane* plane, + int numPlanes, + int& cullingPlane, + const uint32 _inMask) const { + + uint32 inMask = _inMask; + assert(numPlanes < 31); + + const bool finite = + (abs(lo.x) < G3D::inf()) && + (abs(hi.x) < G3D::inf()) && + (abs(lo.y) < G3D::inf()) && + (abs(hi.y) < G3D::inf()) && + (abs(lo.z) < G3D::inf()) && + (abs(hi.z) < G3D::inf()); + + // See if there is one plane for which all of the + // vertices are in the negative half space. + for (int p = 0; p < numPlanes; p++) { + + // Only test planes that are not masked + if ((inMask & 1) != 0) { + + bool culled = true; + Vector3 corner; + + int v; + + // Assume this plane culls all points. See if there is a point + // not culled by the plane... early out when at least one point + // is in the positive half space. + for (v = 0; (v < 8) && culled; ++v) { + + // Unrolling these 3 if's into a switch decreases performance + // by about 2x + corner.x = (v & 1) ? hi.x : lo.x; + corner.y = (v & 2) ? hi.y : lo.y; + corner.z = (v & 4) ? hi.z : lo.z; + + if (finite) { // this branch is highly predictable + culled = ! plane[p].halfSpaceContainsFinite(corner); + } else { + culled = ! plane[p].halfSpaceContains(corner); + } + } + + if (culled) { + // Plane p culled the box + cullingPlane = p; + + return true; + } + } + + // Move on to the next bit. + inMask = inMask >> 1; + } + + // None of the planes could cull this box + cullingPlane = -1; + return false; +} + + +bool AABox::intersects(const class Sphere& sphere) const { + double d = 0; + + //find the square of the distance + //from the sphere to the box + for (int i = 0; i < 3; ++i) { + if (sphere.center[i] < lo[i]) { + d += square(sphere.center[i] - lo[i]); + } else if (sphere.center[i] > hi[i]) { + d += square(sphere.center[i] - hi[i]); + } + } + + return d <= square(sphere.radius); +} + + +} // namespace diff --git a/dep/src/g3dlite/Box.cpp b/dep/src/g3dlite/Box.cpp new file mode 100644 index 000000000..b99104ff2 --- /dev/null +++ b/dep/src/g3dlite/Box.cpp @@ -0,0 +1,348 @@ +/** + @file Box.cpp + Box class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-06-02 + @edited 2006-02-05 +*/ + +#include "G3D/Box.h" +#include "G3D/debug.h" +#include "G3D/Plane.h" +#include "G3D/AABox.h" +#include "G3D/CoordinateFrame.h" + +namespace G3D { + +/** + Sets a field on four vertices. Used by the constructor. + */ +#define setMany(i0, i1, i2, i3, field, extreme) \ + _corner[i0].field = _corner[i1].field = \ + _corner[i2].field = _corner[i3].field = \ + (extreme).field + +Box::Box() { +} + + +Box::Box(const AABox& b) { + init(b.low(), b.high()); +} + + +Box::Box( + const Vector3& min, + const Vector3& max) { + + init(min.min(max), min.max(max)); + +} + +void Box::init( + const Vector3& min, + const Vector3& max) { + + setMany(0, 1, 2, 3, z, max); + setMany(4, 5, 6, 7, z, min); + + setMany(1, 2, 5, 6, x, max); + setMany(0, 3, 4, 7, x, min); + + setMany(3, 2, 6, 7, y, max); + setMany(0, 1, 5, 4, y, min); + + _extent = max - min; + + _axis[0] = Vector3::unitX(); + _axis[1] = Vector3::unitY(); + _axis[2] = Vector3::unitZ(); + + _volume = _extent.x * _extent.y * _extent.z; + _area = 2 * + (_extent.x * _extent.y + + _extent.y * _extent.z + + _extent.z * _extent.x); + + _center = (max + min) / 2; +} + + +float Box::volume() const { + return _volume; +} + + +float Box::surfaceArea() const { + return _area; +} + + +void Box::getLocalFrame(CoordinateFrame& frame) const { + + frame.rotation = Matrix3( + _axis[0][0], _axis[1][0], _axis[2][0], + _axis[0][1], _axis[1][1], _axis[2][1], + _axis[0][2], _axis[1][2], _axis[2][2]); + + frame.translation = _center; +} + + +CoordinateFrame Box::localFrame() const { + CoordinateFrame out; + getLocalFrame(out); + return out; +} + + +void Box::getFaceCorners(int f, Vector3& v0, Vector3& v1, Vector3& v2, Vector3& v3) const { + switch (f) { + case 0: + v0 = _corner[0]; v1 = _corner[1]; v2 = _corner[2]; v3 = _corner[3]; + break; + + case 1: + v0 = _corner[1]; v1 = _corner[5]; v2 = _corner[6]; v3 = _corner[2]; + break; + + case 2: + v0 = _corner[7]; v1 = _corner[6]; v2 = _corner[5]; v3 = _corner[4]; + break; + + case 3: + v0 = _corner[2]; v1 = _corner[6]; v2 = _corner[7]; v3 = _corner[3]; + break; + + case 4: + v0 = _corner[3]; v1 = _corner[7]; v2 = _corner[4]; v3 = _corner[0]; + break; + + case 5: + v0 = _corner[1]; v1 = _corner[0]; v2 = _corner[4]; v3 = _corner[5]; + break; + + default: + debugAssert((f >= 0) && (f < 6)); + } +} + + +bool Box::culledBy( + const Array& plane, + int& cullingPlaneIndex, + const uint32 inMask, + uint32& outMask) const { + + return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask); +} + + +bool Box::culledBy( + const Array& plane, + int& cullingPlaneIndex, + const uint32 inMask) const { + + return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask); +} + + +int32 Box::dummy = 0; + +bool Box::culledBy( + const class Plane* plane, + int numPlanes, + int& cullingPlane, + const uint32 _inMask, + uint32& childMask) const { + + uint32 inMask = _inMask; + assert(numPlanes < 31); + + childMask = 0; + + // See if there is one plane for which all of the + // vertices are in the negative half space. + for (int p = 0; p < numPlanes; p++) { + + // Only test planes that are not masked + if ((inMask & 1) != 0) { + + Vector3 corner; + + int numContained = 0; + int v = 0; + + // We can early-out only if we have found one point on each + // side of the plane (i.e. if we are straddling). That + // occurs when (numContained < v) && (numContained > 0) + for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) { + if (plane[p].halfSpaceContains(getCorner(v))) { + ++numContained; + } + } + + if (numContained == 0) { + // Plane p culled the box + cullingPlane = p; + + // The caller should not recurse into the children, + // since the parent is culled. If they do recurse, + // make them only test against this one plane, which + // will immediately cull the volume. + childMask = 1 << p; + return true; + + } else if (numContained < v) { + // The bounding volume straddled the plane; we have + // to keep testing against this plane + childMask |= (1 << p); + } + } + + // Move on to the next bit. + inMask = inMask >> 1; + } + + // None of the planes could cull this box + cullingPlane = -1; + return false; +} + + +bool Box::culledBy( + const class Plane* plane, + int numPlanes, + int& cullingPlane, + const uint32 _inMask) const { + + uint32 inMask = _inMask; + assert(numPlanes < 31); + + // See if there is one plane for which all of the + // vertices are in the negative half space. + for (int p = 0; p < numPlanes; p++) { + + // Only test planes that are not masked + if ((inMask & 1) != 0) { + + bool culled = true; + + int v; + + // Assume this plane culls all points. See if there is a point + // not culled by the plane... early out when at least one point + // is in the positive half space. + for (v = 0; (v < 8) && culled; ++v) { + culled = ! plane[p].halfSpaceContains(getCorner(v)); + } + + if (culled) { + // Plane p culled the box + cullingPlane = p; + + return true; + } + } + + // Move on to the next bit. + inMask = inMask >> 1; + } + + // None of the planes could cull this box + cullingPlane = -1; + return false; +} + + +bool Box::contains( + const Vector3& point) const { + + // Form axes from three edges, transform the point into that + // space, and perform 3 interval tests + + Vector3 u = _corner[4] - _corner[0]; + Vector3 v = _corner[3] - _corner[0]; + Vector3 w = _corner[1] - _corner[0]; + + Matrix3 M = Matrix3(u.x, v.x, w.x, + u.y, v.y, w.y, + u.z, v.z, w.z); + + // M^-1 * (point - _corner[0]) = point in unit cube's object space + // compute the inverse of M + Vector3 osPoint = M.inverse() * (point - _corner[0]); + + return + (osPoint.x >= 0) && + (osPoint.y >= 0) && + (osPoint.z >= 0) && + (osPoint.x <= 1) && + (osPoint.y <= 1) && + (osPoint.z <= 1); +} + +#undef setMany + +#if 0 +void Box::getRandomSurfacePoint(Vector3& P, Vector3& N) const { + float aXY = _extent.x * _extent.y; + float aYZ = _extent.y * _extent.z; + float aZX = _extent.z * _extent.x; + + float r = (float)random(0, aXY + aYZ + aZX); + + // Choose evenly between positive and negative face planes + float d = (random(0, 1) < 0.5f) ? -1.0f : 1.0f; + + // The probability of choosing a given face is proportional to + // its area. + if (r < aXY) { + P = _axis[0] * (float)random(-0.5, 0.5) * _extent.x + + _axis[1] * (float)random(-0.5, 0.5) * _extent.y + + _center + _axis[2] * d * _extent.z * 0.5f; + N = _axis[2] * d; + } else if (r < aYZ) { + P = _axis[1] * (float)random(-0.5, 0.5) * _extent.y + + _axis[2] * (float)random(-0.5, 0.5) * _extent.z + + _center + _axis[0] * d * _extent.x * 0.5f; + N = _axis[0] * d; + } else { + P = _axis[2] * (float)random(-0.5, 0.5) * _extent.z + + _axis[0] *(float) random(-0.5, 0.5) * _extent.x + + _center + _axis[1] * d * _extent.y * 0.5f; + N = _axis[1] * d; + } +} + + +Vector3 Box::randomInteriorPoint() const { + Vector3 sum = _center; + + for (int a = 0; a < 3; ++a) { + sum += _axis[a] * (float)random(-0.5, 0.5) * _extent[a]; + } + + return sum; +} +#endif + + +void Box::getBounds(class AABox& aabb) const { + + Vector3 lo = _corner[0]; + Vector3 hi = lo; + + for (int v = 1; v < 8; ++v) { + const Vector3& C = _corner[v]; + lo = lo.min(C); + hi = hi.max(C); + } + + aabb = AABox(lo, hi); +} + + +} // namespace diff --git a/dep/src/g3dlite/Crypto.cpp b/dep/src/g3dlite/Crypto.cpp new file mode 100644 index 000000000..c07e5da3c --- /dev/null +++ b/dep/src/g3dlite/Crypto.cpp @@ -0,0 +1,146 @@ +/** + @file Crypto.cpp + + @author Morgan McGuire, matrix@graphics3d.com + + + @created 2006-03-28 + @edited 2006-04-06 + */ + +#include "G3D/platform.h" +#include "G3D/Crypto.h" +#include "G3D/g3dmath.h" + +namespace G3D { + + +int Crypto::smallPrime(int n) { + debugAssert(n < numSmallPrimes() && n >= 0); + + // From: + // http://primes.utm.edu/lists/small/1000.txt + + static const int table[] = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, + 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, + 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, + 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, + 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, + 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, + 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, + 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, + 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, + 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, + 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, + 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, + 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, + 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, + 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, + 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, + 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, + 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, + 1993, 1997, 1999}; + + return table[n]; +} + + +int Crypto::numSmallPrimes() { + return 303; +} + +uint32 Crypto::crc32(const void* byte, size_t numBytes) { + static const uint32 crc32Table[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, + }; + + // By definition, initialize to all binary 1's + uint32 value = 0xFFFFFFFF; + + for (size_t i = 0; i < numBytes; ++i) { + value = (value >> 8 ) ^ crc32Table[static_cast(byte)[i] ^ (value & 0xFF)]; + } + + return value; +} + +} // G3D diff --git a/dep/src/g3dlite/Makefile.am b/dep/src/g3dlite/Makefile.am new file mode 100644 index 000000000..a62a82f29 --- /dev/null +++ b/dep/src/g3dlite/Makefile.am @@ -0,0 +1,41 @@ +## Modified for MaNGOS project +## +## Permission is hereby granted, free of charge, to any person obtaining a copy +## of this software and associated documentation files (the "Software"), to deal +## in the Software without restriction, including without limitation the rights +## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +## copies of the Software, and to permit persons to whom the Software is furnished +## to do so, subject to the following conditions: +## +## The above copyright notice and this permission notice shall be included in all +## copies or substantial portions of the Software. +## +## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Process this file with automake to produce Makefile.in + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../../include -I$(srcdir)/../../include/g3dlite + +noinst_LIBRARIES = libg3dlite.a +libg3dlite_a_SOURCES = \ + AABox.cpp \ + Box.cpp \ + Crypto.cpp \ + format.cpp \ + Matrix3.cpp \ + Plane.cpp \ + System.cpp \ + Triangle.cpp \ + Vector3.cpp \ + Vector4.cpp + +EXTRA_DIST = \ + license.html + + diff --git a/dep/src/g3dlite/Matrix3.cpp b/dep/src/g3dlite/Matrix3.cpp new file mode 100644 index 000000000..1d6df3ff7 --- /dev/null +++ b/dep/src/g3dlite/Matrix3.cpp @@ -0,0 +1,1686 @@ +/** + @file Matrix3.cpp + + 3x3 matrix class + + @author Morgan McGuire, graphics3d.com + + @created 2001-06-02 + @edited 2006-04-06 +*/ + +#include "G3D/platform.h" +#include "G3D/format.h" +#include +#include +#include "G3D/Matrix3.h" +#include "G3D/g3dmath.h" +#include "G3D/Quat.h" + +namespace G3D { + +const float Matrix3::EPSILON = 1e-06f; + +const Matrix3& Matrix3::zero() { + static Matrix3 m(0, 0, 0, 0, 0, 0, 0, 0, 0); + return m; +} + +const Matrix3& Matrix3::identity() { + static Matrix3 m(1, 0, 0, 0, 1, 0, 0, 0, 1); + return m; +} + +// Deprecated. +const Matrix3 Matrix3::ZERO(0, 0, 0, 0, 0, 0, 0, 0, 0); +const Matrix3 Matrix3::IDENTITY(1, 0, 0, 0, 1, 0, 0, 0, 1); + +const float Matrix3::ms_fSvdEpsilon = 1e-04f; +const int Matrix3::ms_iSvdMaxIterations = 32; + +bool Matrix3::fuzzyEq(const Matrix3& b) const { + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + if (! G3D::fuzzyEq(elt[r][c], b[r][c])) { + return false; + } + } + } + return true; +} + + +bool Matrix3::isOrthonormal() const { + Vector3 X = getColumn(0); + Vector3 Y = getColumn(1); + Vector3 Z = getColumn(2); + + return + (G3D::fuzzyEq(X.dot(Y), 0.0f) && + G3D::fuzzyEq(Y.dot(Z), 0.0f) && + G3D::fuzzyEq(X.dot(Z), 0.0f) && + G3D::fuzzyEq(X.squaredMagnitude(), 1.0f) && + G3D::fuzzyEq(Y.squaredMagnitude(), 1.0f) && + G3D::fuzzyEq(Z.squaredMagnitude(), 1.0f)); +} + +//---------------------------------------------------------------------------- +Matrix3::Matrix3(const Quat& _q) { + // Implementation from Watt and Watt, pg 362 + // See also http://www.flipcode.com/documents/matrfaq.html#Q54 + Quat q = _q.unitize(); + float xx = 2.0f * q.x * q.x; + float xy = 2.0f * q.x * q.y; + float xz = 2.0f * q.x * q.z; + float xw = 2.0f * q.x * q.w; + + float yy = 2.0f * q.y * q.y; + float yz = 2.0f * q.y * q.z; + float yw = 2.0f * q.y * q.w; + + float zz = 2.0f * q.z * q.z; + float zw = 2.0f * q.z * q.w; + + set(1.0f - yy - zz, xy - zw, xz + yw, + xy + zw, 1.0f - xx - zz, yz - xw, + xz - yw, yz + xw, 1.0f - xx - yy); +} + +//---------------------------------------------------------------------------- + +Matrix3::Matrix3 (const float aafEntry[3][3]) { + memcpy(elt, aafEntry, 9*sizeof(float)); +} + +//---------------------------------------------------------------------------- +Matrix3::Matrix3 (const Matrix3& rkMatrix) { + memcpy(elt, rkMatrix.elt, 9*sizeof(float)); +} + +//---------------------------------------------------------------------------- +Matrix3::Matrix3( + float fEntry00, float fEntry01, float fEntry02, + float fEntry10, float fEntry11, float fEntry12, + float fEntry20, float fEntry21, float fEntry22) { + set(fEntry00, fEntry01, fEntry02, + fEntry10, fEntry11, fEntry12, + fEntry20, fEntry21, fEntry22); +} + +void Matrix3::set( + float fEntry00, float fEntry01, float fEntry02, + float fEntry10, float fEntry11, float fEntry12, + float fEntry20, float fEntry21, float fEntry22) { + + elt[0][0] = fEntry00; + elt[0][1] = fEntry01; + elt[0][2] = fEntry02; + elt[1][0] = fEntry10; + elt[1][1] = fEntry11; + elt[1][2] = fEntry12; + elt[2][0] = fEntry20; + elt[2][1] = fEntry21; + elt[2][2] = fEntry22; +} + + +//---------------------------------------------------------------------------- +Vector3 Matrix3::getColumn (int iCol) const { + assert((0 <= iCol) && (iCol < 3)); + return Vector3(elt[0][iCol], elt[1][iCol], + elt[2][iCol]); +} + +Vector3 Matrix3::getRow (int iRow) const { + return Vector3(elt[iRow][0], elt[iRow][1], elt[iRow][2]); +} + +void Matrix3::setColumn(int iCol, const Vector3 &vector) { + debugAssert((iCol >= 0) && (iCol < 3)); + elt[0][iCol] = vector.x; + elt[1][iCol] = vector.y; + elt[2][iCol] = vector.z; +} + + +void Matrix3::setRow(int iRow, const Vector3 &vector) { + debugAssert((iRow >= 0) && (iRow < 3)); + elt[iRow][0] = vector.x; + elt[iRow][1] = vector.y; + elt[iRow][2] = vector.z; +} + + +//---------------------------------------------------------------------------- +bool Matrix3::operator== (const Matrix3& rkMatrix) const { + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + if ( elt[iRow][iCol] != rkMatrix.elt[iRow][iCol] ) + return false; + } + } + + return true; +} + +//---------------------------------------------------------------------------- +bool Matrix3::operator!= (const Matrix3& rkMatrix) const { + return !operator==(rkMatrix); +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::operator+ (const Matrix3& rkMatrix) const { + Matrix3 kSum; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kSum.elt[iRow][iCol] = elt[iRow][iCol] + + rkMatrix.elt[iRow][iCol]; + } + } + + return kSum; +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::operator- (const Matrix3& rkMatrix) const { + Matrix3 kDiff; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kDiff.elt[iRow][iCol] = elt[iRow][iCol] - + rkMatrix.elt[iRow][iCol]; + } + } + + return kDiff; +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::operator* (const Matrix3& rkMatrix) const { + Matrix3 kProd; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kProd.elt[iRow][iCol] = + elt[iRow][0] * rkMatrix.elt[0][iCol] + + elt[iRow][1] * rkMatrix.elt[1][iCol] + + elt[iRow][2] * rkMatrix.elt[2][iCol]; + } + } + + return kProd; +} + +Matrix3& Matrix3::operator+= (const Matrix3& rkMatrix) { + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + elt[iRow][iCol] = elt[iRow][iCol] + rkMatrix.elt[iRow][iCol]; + } + } + + return *this; +} + +Matrix3& Matrix3::operator-= (const Matrix3& rkMatrix) { + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + elt[iRow][iCol] = elt[iRow][iCol] - rkMatrix.elt[iRow][iCol]; + } + } + + return *this; +} + +Matrix3& Matrix3::operator*= (const Matrix3& rkMatrix) { + Matrix3 mulMat; + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + mulMat.elt[iRow][iCol] = + elt[iRow][0] * rkMatrix.elt[0][iCol] + + elt[iRow][1] * rkMatrix.elt[1][iCol] + + elt[iRow][2] * rkMatrix.elt[2][iCol]; + } + } + + *this = mulMat; + return *this; +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::operator- () const { + Matrix3 kNeg; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kNeg[iRow][iCol] = -elt[iRow][iCol]; + } + } + + return kNeg; +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::operator* (float fScalar) const { + Matrix3 kProd; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kProd[iRow][iCol] = fScalar * elt[iRow][iCol]; + } + } + + return kProd; +} + +//---------------------------------------------------------------------------- +Matrix3 operator* (double fScalar, const Matrix3& rkMatrix) { + Matrix3 kProd; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kProd[iRow][iCol] = fScalar * rkMatrix.elt[iRow][iCol]; + } + } + + return kProd; +} + +Matrix3 operator* (float fScalar, const Matrix3& rkMatrix) { + return (double)fScalar * rkMatrix; +} + + +Matrix3 operator* (int fScalar, const Matrix3& rkMatrix) { + return (double)fScalar * rkMatrix; +} +//---------------------------------------------------------------------------- +Matrix3 Matrix3::transpose () const { + Matrix3 kTranspose; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + kTranspose[iRow][iCol] = elt[iCol][iRow]; + } + } + + return kTranspose; +} + +//---------------------------------------------------------------------------- +bool Matrix3::inverse (Matrix3& rkInverse, float fTolerance) const { + // Invert a 3x3 using cofactors. This is about 8 times faster than + // the Numerical Recipes code which uses Gaussian elimination. + + rkInverse[0][0] = elt[1][1] * elt[2][2] - + elt[1][2] * elt[2][1]; + rkInverse[0][1] = elt[0][2] * elt[2][1] - + elt[0][1] * elt[2][2]; + rkInverse[0][2] = elt[0][1] * elt[1][2] - + elt[0][2] * elt[1][1]; + rkInverse[1][0] = elt[1][2] * elt[2][0] - + elt[1][0] * elt[2][2]; + rkInverse[1][1] = elt[0][0] * elt[2][2] - + elt[0][2] * elt[2][0]; + rkInverse[1][2] = elt[0][2] * elt[1][0] - + elt[0][0] * elt[1][2]; + rkInverse[2][0] = elt[1][0] * elt[2][1] - + elt[1][1] * elt[2][0]; + rkInverse[2][1] = elt[0][1] * elt[2][0] - + elt[0][0] * elt[2][1]; + rkInverse[2][2] = elt[0][0] * elt[1][1] - + elt[0][1] * elt[1][0]; + + float fDet = + elt[0][0] * rkInverse[0][0] + + elt[0][1] * rkInverse[1][0] + + elt[0][2] * rkInverse[2][0]; + + if ( G3D::abs(fDet) <= fTolerance ) + return false; + + float fInvDet = 1.0 / fDet; + + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) + rkInverse[iRow][iCol] *= fInvDet; + } + + return true; +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::inverse (float fTolerance) const { + Matrix3 kInverse = Matrix3::zero(); + inverse(kInverse, fTolerance); + return kInverse; +} + +//---------------------------------------------------------------------------- +float Matrix3::determinant () const { + float fCofactor00 = elt[1][1] * elt[2][2] - + elt[1][2] * elt[2][1]; + float fCofactor10 = elt[1][2] * elt[2][0] - + elt[1][0] * elt[2][2]; + float fCofactor20 = elt[1][0] * elt[2][1] - + elt[1][1] * elt[2][0]; + + float fDet = + elt[0][0] * fCofactor00 + + elt[0][1] * fCofactor10 + + elt[0][2] * fCofactor20; + + return fDet; +} + +//---------------------------------------------------------------------------- +void Matrix3::bidiagonalize (Matrix3& kA, Matrix3& kL, + Matrix3& kR) { + float afV[3], afW[3]; + float fLength, fSign, fT1, fInvT1, fT2; + bool bIdentity; + + // map first column to (*,0,0) + fLength = sqrt(kA[0][0] * kA[0][0] + kA[1][0] * kA[1][0] + + kA[2][0] * kA[2][0]); + + if ( fLength > 0.0 ) { + fSign = (kA[0][0] > 0.0 ? 1.0 : -1.0); + fT1 = kA[0][0] + fSign * fLength; + fInvT1 = 1.0 / fT1; + afV[1] = kA[1][0] * fInvT1; + afV[2] = kA[2][0] * fInvT1; + + fT2 = -2.0 / (1.0 + afV[1] * afV[1] + afV[2] * afV[2]); + afW[0] = fT2 * (kA[0][0] + kA[1][0] * afV[1] + kA[2][0] * afV[2]); + afW[1] = fT2 * (kA[0][1] + kA[1][1] * afV[1] + kA[2][1] * afV[2]); + afW[2] = fT2 * (kA[0][2] + kA[1][2] * afV[1] + kA[2][2] * afV[2]); + kA[0][0] += afW[0]; + kA[0][1] += afW[1]; + kA[0][2] += afW[2]; + kA[1][1] += afV[1] * afW[1]; + kA[1][2] += afV[1] * afW[2]; + kA[2][1] += afV[2] * afW[1]; + kA[2][2] += afV[2] * afW[2]; + + kL[0][0] = 1.0 + fT2; + kL[0][1] = kL[1][0] = fT2 * afV[1]; + kL[0][2] = kL[2][0] = fT2 * afV[2]; + kL[1][1] = 1.0 + fT2 * afV[1] * afV[1]; + kL[1][2] = kL[2][1] = fT2 * afV[1] * afV[2]; + kL[2][2] = 1.0 + fT2 * afV[2] * afV[2]; + bIdentity = false; + } else { + kL = Matrix3::identity(); + bIdentity = true; + } + + // map first row to (*,*,0) + fLength = sqrt(kA[0][1] * kA[0][1] + kA[0][2] * kA[0][2]); + + if ( fLength > 0.0 ) { + fSign = (kA[0][1] > 0.0 ? 1.0 : -1.0); + fT1 = kA[0][1] + fSign * fLength; + afV[2] = kA[0][2] / fT1; + + fT2 = -2.0 / (1.0 + afV[2] * afV[2]); + afW[0] = fT2 * (kA[0][1] + kA[0][2] * afV[2]); + afW[1] = fT2 * (kA[1][1] + kA[1][2] * afV[2]); + afW[2] = fT2 * (kA[2][1] + kA[2][2] * afV[2]); + kA[0][1] += afW[0]; + kA[1][1] += afW[1]; + kA[1][2] += afW[1] * afV[2]; + kA[2][1] += afW[2]; + kA[2][2] += afW[2] * afV[2]; + + kR[0][0] = 1.0; + kR[0][1] = kR[1][0] = 0.0; + kR[0][2] = kR[2][0] = 0.0; + kR[1][1] = 1.0 + fT2; + kR[1][2] = kR[2][1] = fT2 * afV[2]; + kR[2][2] = 1.0 + fT2 * afV[2] * afV[2]; + } else { + kR = Matrix3::identity(); + } + + // map second column to (*,*,0) + fLength = sqrt(kA[1][1] * kA[1][1] + kA[2][1] * kA[2][1]); + + if ( fLength > 0.0 ) { + fSign = (kA[1][1] > 0.0 ? 1.0 : -1.0); + fT1 = kA[1][1] + fSign * fLength; + afV[2] = kA[2][1] / fT1; + + fT2 = -2.0 / (1.0 + afV[2] * afV[2]); + afW[1] = fT2 * (kA[1][1] + kA[2][1] * afV[2]); + afW[2] = fT2 * (kA[1][2] + kA[2][2] * afV[2]); + kA[1][1] += afW[1]; + kA[1][2] += afW[2]; + kA[2][2] += afV[2] * afW[2]; + + float fA = 1.0 + fT2; + float fB = fT2 * afV[2]; + float fC = 1.0 + fB * afV[2]; + + if ( bIdentity ) { + kL[0][0] = 1.0; + kL[0][1] = kL[1][0] = 0.0; + kL[0][2] = kL[2][0] = 0.0; + kL[1][1] = fA; + kL[1][2] = kL[2][1] = fB; + kL[2][2] = fC; + } else { + for (int iRow = 0; iRow < 3; iRow++) { + float fTmp0 = kL[iRow][1]; + float fTmp1 = kL[iRow][2]; + kL[iRow][1] = fA * fTmp0 + fB * fTmp1; + kL[iRow][2] = fB * fTmp0 + fC * fTmp1; + } + } + } +} + +//---------------------------------------------------------------------------- +void Matrix3::golubKahanStep (Matrix3& kA, Matrix3& kL, + Matrix3& kR) { + float fT11 = kA[0][1] * kA[0][1] + kA[1][1] * kA[1][1]; + float fT22 = kA[1][2] * kA[1][2] + kA[2][2] * kA[2][2]; + float fT12 = kA[1][1] * kA[1][2]; + float fTrace = fT11 + fT22; + float fDiff = fT11 - fT22; + float fDiscr = sqrt(fDiff * fDiff + 4.0 * fT12 * fT12); + float fRoot1 = 0.5 * (fTrace + fDiscr); + float fRoot2 = 0.5 * (fTrace - fDiscr); + + // adjust right + float fY = kA[0][0] - (G3D::abs(fRoot1 - fT22) <= + G3D::abs(fRoot2 - fT22) ? fRoot1 : fRoot2); + float fZ = kA[0][1]; + float fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ); + float fSin = fZ * fInvLength; + float fCos = -fY * fInvLength; + + float fTmp0 = kA[0][0]; + float fTmp1 = kA[0][1]; + kA[0][0] = fCos * fTmp0 - fSin * fTmp1; + kA[0][1] = fSin * fTmp0 + fCos * fTmp1; + kA[1][0] = -fSin * kA[1][1]; + kA[1][1] *= fCos; + + int iRow; + + for (iRow = 0; iRow < 3; iRow++) { + fTmp0 = kR[0][iRow]; + fTmp1 = kR[1][iRow]; + kR[0][iRow] = fCos * fTmp0 - fSin * fTmp1; + kR[1][iRow] = fSin * fTmp0 + fCos * fTmp1; + } + + // adjust left + fY = kA[0][0]; + + fZ = kA[1][0]; + + fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ); + + fSin = fZ * fInvLength; + + fCos = -fY * fInvLength; + + kA[0][0] = fCos * kA[0][0] - fSin * kA[1][0]; + + fTmp0 = kA[0][1]; + + fTmp1 = kA[1][1]; + + kA[0][1] = fCos * fTmp0 - fSin * fTmp1; + + kA[1][1] = fSin * fTmp0 + fCos * fTmp1; + + kA[0][2] = -fSin * kA[1][2]; + + kA[1][2] *= fCos; + + int iCol; + + for (iCol = 0; iCol < 3; iCol++) { + fTmp0 = kL[iCol][0]; + fTmp1 = kL[iCol][1]; + kL[iCol][0] = fCos * fTmp0 - fSin * fTmp1; + kL[iCol][1] = fSin * fTmp0 + fCos * fTmp1; + } + + // adjust right + fY = kA[0][1]; + + fZ = kA[0][2]; + + fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ); + + fSin = fZ * fInvLength; + + fCos = -fY * fInvLength; + + kA[0][1] = fCos * kA[0][1] - fSin * kA[0][2]; + + fTmp0 = kA[1][1]; + + fTmp1 = kA[1][2]; + + kA[1][1] = fCos * fTmp0 - fSin * fTmp1; + + kA[1][2] = fSin * fTmp0 + fCos * fTmp1; + + kA[2][1] = -fSin * kA[2][2]; + + kA[2][2] *= fCos; + + for (iRow = 0; iRow < 3; iRow++) { + fTmp0 = kR[1][iRow]; + fTmp1 = kR[2][iRow]; + kR[1][iRow] = fCos * fTmp0 - fSin * fTmp1; + kR[2][iRow] = fSin * fTmp0 + fCos * fTmp1; + } + + // adjust left + fY = kA[1][1]; + + fZ = kA[2][1]; + + fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ); + + fSin = fZ * fInvLength; + + fCos = -fY * fInvLength; + + kA[1][1] = fCos * kA[1][1] - fSin * kA[2][1]; + + fTmp0 = kA[1][2]; + + fTmp1 = kA[2][2]; + + kA[1][2] = fCos * fTmp0 - fSin * fTmp1; + + kA[2][2] = fSin * fTmp0 + fCos * fTmp1; + + for (iCol = 0; iCol < 3; iCol++) { + fTmp0 = kL[iCol][1]; + fTmp1 = kL[iCol][2]; + kL[iCol][1] = fCos * fTmp0 - fSin * fTmp1; + kL[iCol][2] = fSin * fTmp0 + fCos * fTmp1; + } +} + +//---------------------------------------------------------------------------- +void Matrix3::singularValueDecomposition (Matrix3& kL, Vector3& kS, + Matrix3& kR) const { + int iRow, iCol; + + Matrix3 kA = *this; + bidiagonalize(kA, kL, kR); + + for (int i = 0; i < ms_iSvdMaxIterations; i++) { + float fTmp, fTmp0, fTmp1; + float fSin0, fCos0, fTan0; + float fSin1, fCos1, fTan1; + + bool bTest1 = (G3D::abs(kA[0][1]) <= + ms_fSvdEpsilon * (G3D::abs(kA[0][0]) + G3D::abs(kA[1][1]))); + bool bTest2 = (G3D::abs(kA[1][2]) <= + ms_fSvdEpsilon * (G3D::abs(kA[1][1]) + G3D::abs(kA[2][2]))); + + if ( bTest1 ) { + if ( bTest2 ) { + kS[0] = kA[0][0]; + kS[1] = kA[1][1]; + kS[2] = kA[2][2]; + break; + } else { + // 2x2 closed form factorization + fTmp = (kA[1][1] * kA[1][1] - kA[2][2] * kA[2][2] + + kA[1][2] * kA[1][2]) / (kA[1][2] * kA[2][2]); + fTan0 = 0.5 * (fTmp + sqrt(fTmp * fTmp + 4.0)); + fCos0 = 1.0 / sqrt(1.0 + fTan0 * fTan0); + fSin0 = fTan0 * fCos0; + + for (iCol = 0; iCol < 3; iCol++) { + fTmp0 = kL[iCol][1]; + fTmp1 = kL[iCol][2]; + kL[iCol][1] = fCos0 * fTmp0 - fSin0 * fTmp1; + kL[iCol][2] = fSin0 * fTmp0 + fCos0 * fTmp1; + } + + fTan1 = (kA[1][2] - kA[2][2] * fTan0) / kA[1][1]; + fCos1 = 1.0 / sqrt(1.0 + fTan1 * fTan1); + fSin1 = -fTan1 * fCos1; + + for (iRow = 0; iRow < 3; iRow++) { + fTmp0 = kR[1][iRow]; + fTmp1 = kR[2][iRow]; + kR[1][iRow] = fCos1 * fTmp0 - fSin1 * fTmp1; + kR[2][iRow] = fSin1 * fTmp0 + fCos1 * fTmp1; + } + + kS[0] = kA[0][0]; + kS[1] = fCos0 * fCos1 * kA[1][1] - + fSin1 * (fCos0 * kA[1][2] - fSin0 * kA[2][2]); + kS[2] = fSin0 * fSin1 * kA[1][1] + + fCos1 * (fSin0 * kA[1][2] + fCos0 * kA[2][2]); + break; + } + } else { + if ( bTest2 ) { + // 2x2 closed form factorization + fTmp = (kA[0][0] * kA[0][0] + kA[1][1] * kA[1][1] - + kA[0][1] * kA[0][1]) / (kA[0][1] * kA[1][1]); + fTan0 = 0.5 * ( -fTmp + sqrt(fTmp * fTmp + 4.0)); + fCos0 = 1.0 / sqrt(1.0 + fTan0 * fTan0); + fSin0 = fTan0 * fCos0; + + for (iCol = 0; iCol < 3; iCol++) { + fTmp0 = kL[iCol][0]; + fTmp1 = kL[iCol][1]; + kL[iCol][0] = fCos0 * fTmp0 - fSin0 * fTmp1; + kL[iCol][1] = fSin0 * fTmp0 + fCos0 * fTmp1; + } + + fTan1 = (kA[0][1] - kA[1][1] * fTan0) / kA[0][0]; + fCos1 = 1.0 / sqrt(1.0 + fTan1 * fTan1); + fSin1 = -fTan1 * fCos1; + + for (iRow = 0; iRow < 3; iRow++) { + fTmp0 = kR[0][iRow]; + fTmp1 = kR[1][iRow]; + kR[0][iRow] = fCos1 * fTmp0 - fSin1 * fTmp1; + kR[1][iRow] = fSin1 * fTmp0 + fCos1 * fTmp1; + } + + kS[0] = fCos0 * fCos1 * kA[0][0] - + fSin1 * (fCos0 * kA[0][1] - fSin0 * kA[1][1]); + kS[1] = fSin0 * fSin1 * kA[0][0] + + fCos1 * (fSin0 * kA[0][1] + fCos0 * kA[1][1]); + kS[2] = kA[2][2]; + break; + } else { + golubKahanStep(kA, kL, kR); + } + } + } + + // positize diagonal + for (iRow = 0; iRow < 3; iRow++) { + if ( kS[iRow] < 0.0 ) { + kS[iRow] = -kS[iRow]; + + for (iCol = 0; iCol < 3; iCol++) + kR[iRow][iCol] = -kR[iRow][iCol]; + } + } +} + +//---------------------------------------------------------------------------- +void Matrix3::singularValueComposition (const Matrix3& kL, + const Vector3& kS, const Matrix3& kR) { + int iRow, iCol; + Matrix3 kTmp; + + // product S*R + for (iRow = 0; iRow < 3; iRow++) { + for (iCol = 0; iCol < 3; iCol++) + kTmp[iRow][iCol] = kS[iRow] * kR[iRow][iCol]; + } + + // product L*S*R + for (iRow = 0; iRow < 3; iRow++) { + for (iCol = 0; iCol < 3; iCol++) { + elt[iRow][iCol] = 0.0; + + for (int iMid = 0; iMid < 3; iMid++) + elt[iRow][iCol] += kL[iRow][iMid] * kTmp[iMid][iCol]; + } + } +} + +//---------------------------------------------------------------------------- +void Matrix3::orthonormalize () { + // Algorithm uses Gram-Schmidt orthogonalization. If 'this' matrix is + // M = [m0|m1|m2], then orthonormal output matrix is Q = [q0|q1|q2], + // + // q0 = m0/|m0| + // q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0| + // q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1| + // + // where |V| indicates length of vector V and A*B indicates dot + // product of vectors A and B. + + // compute q0 + float fInvLength = 1.0 / sqrt(elt[0][0] * elt[0][0] + + elt[1][0] * elt[1][0] + + elt[2][0] * elt[2][0]); + + elt[0][0] *= fInvLength; + elt[1][0] *= fInvLength; + elt[2][0] *= fInvLength; + + // compute q1 + float fDot0 = + elt[0][0] * elt[0][1] + + elt[1][0] * elt[1][1] + + elt[2][0] * elt[2][1]; + + elt[0][1] -= fDot0 * elt[0][0]; + elt[1][1] -= fDot0 * elt[1][0]; + elt[2][1] -= fDot0 * elt[2][0]; + + fInvLength = 1.0 / sqrt(elt[0][1] * elt[0][1] + + elt[1][1] * elt[1][1] + + elt[2][1] * elt[2][1]); + + elt[0][1] *= fInvLength; + elt[1][1] *= fInvLength; + elt[2][1] *= fInvLength; + + // compute q2 + float fDot1 = + elt[0][1] * elt[0][2] + + elt[1][1] * elt[1][2] + + elt[2][1] * elt[2][2]; + + fDot0 = + elt[0][0] * elt[0][2] + + elt[1][0] * elt[1][2] + + elt[2][0] * elt[2][2]; + + elt[0][2] -= fDot0 * elt[0][0] + fDot1 * elt[0][1]; + elt[1][2] -= fDot0 * elt[1][0] + fDot1 * elt[1][1]; + elt[2][2] -= fDot0 * elt[2][0] + fDot1 * elt[2][1]; + + fInvLength = 1.0 / sqrt(elt[0][2] * elt[0][2] + + elt[1][2] * elt[1][2] + + elt[2][2] * elt[2][2]); + + elt[0][2] *= fInvLength; + elt[1][2] *= fInvLength; + elt[2][2] *= fInvLength; +} + +//---------------------------------------------------------------------------- +void Matrix3::qDUDecomposition (Matrix3& kQ, + Vector3& kD, Vector3& kU) const { + // Factor M = QR = QDU where Q is orthogonal, D is diagonal, + // and U is upper triangular with ones on its diagonal. Algorithm uses + // Gram-Schmidt orthogonalization (the QR algorithm). + // + // If M = [ m0 | m1 | m2 ] and Q = [ q0 | q1 | q2 ], then + // + // q0 = m0/|m0| + // q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0| + // q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1| + // + // where |V| indicates length of vector V and A*B indicates dot + // product of vectors A and B. The matrix R has entries + // + // r00 = q0*m0 r01 = q0*m1 r02 = q0*m2 + // r10 = 0 r11 = q1*m1 r12 = q1*m2 + // r20 = 0 r21 = 0 r22 = q2*m2 + // + // so D = diag(r00,r11,r22) and U has entries u01 = r01/r00, + // u02 = r02/r00, and u12 = r12/r11. + + // Q = rotation + // D = scaling + // U = shear + + // D stores the three diagonal entries r00, r11, r22 + // U stores the entries U[0] = u01, U[1] = u02, U[2] = u12 + + // build orthogonal matrix Q + float fInvLength = 1.0 / sqrt(elt[0][0] * elt[0][0] + + elt[1][0] * elt[1][0] + + elt[2][0] * elt[2][0]); + kQ[0][0] = elt[0][0] * fInvLength; + kQ[1][0] = elt[1][0] * fInvLength; + kQ[2][0] = elt[2][0] * fInvLength; + + float fDot = kQ[0][0] * elt[0][1] + kQ[1][0] * elt[1][1] + + kQ[2][0] * elt[2][1]; + kQ[0][1] = elt[0][1] - fDot * kQ[0][0]; + kQ[1][1] = elt[1][1] - fDot * kQ[1][0]; + kQ[2][1] = elt[2][1] - fDot * kQ[2][0]; + fInvLength = 1.0 / sqrt(kQ[0][1] * kQ[0][1] + kQ[1][1] * kQ[1][1] + + kQ[2][1] * kQ[2][1]); + kQ[0][1] *= fInvLength; + kQ[1][1] *= fInvLength; + kQ[2][1] *= fInvLength; + + fDot = kQ[0][0] * elt[0][2] + kQ[1][0] * elt[1][2] + + kQ[2][0] * elt[2][2]; + kQ[0][2] = elt[0][2] - fDot * kQ[0][0]; + kQ[1][2] = elt[1][2] - fDot * kQ[1][0]; + kQ[2][2] = elt[2][2] - fDot * kQ[2][0]; + fDot = kQ[0][1] * elt[0][2] + kQ[1][1] * elt[1][2] + + kQ[2][1] * elt[2][2]; + kQ[0][2] -= fDot * kQ[0][1]; + kQ[1][2] -= fDot * kQ[1][1]; + kQ[2][2] -= fDot * kQ[2][1]; + fInvLength = 1.0 / sqrt(kQ[0][2] * kQ[0][2] + kQ[1][2] * kQ[1][2] + + kQ[2][2] * kQ[2][2]); + kQ[0][2] *= fInvLength; + kQ[1][2] *= fInvLength; + kQ[2][2] *= fInvLength; + + // guarantee that orthogonal matrix has determinant 1 (no reflections) + float fDet = kQ[0][0] * kQ[1][1] * kQ[2][2] + kQ[0][1] * kQ[1][2] * kQ[2][0] + + kQ[0][2] * kQ[1][0] * kQ[2][1] - kQ[0][2] * kQ[1][1] * kQ[2][0] - + kQ[0][1] * kQ[1][0] * kQ[2][2] - kQ[0][0] * kQ[1][2] * kQ[2][1]; + + if ( fDet < 0.0 ) { + for (int iRow = 0; iRow < 3; iRow++) + for (int iCol = 0; iCol < 3; iCol++) + kQ[iRow][iCol] = -kQ[iRow][iCol]; + } + + // build "right" matrix R + Matrix3 kR; + + kR[0][0] = kQ[0][0] * elt[0][0] + kQ[1][0] * elt[1][0] + + kQ[2][0] * elt[2][0]; + + kR[0][1] = kQ[0][0] * elt[0][1] + kQ[1][0] * elt[1][1] + + kQ[2][0] * elt[2][1]; + + kR[1][1] = kQ[0][1] * elt[0][1] + kQ[1][1] * elt[1][1] + + kQ[2][1] * elt[2][1]; + + kR[0][2] = kQ[0][0] * elt[0][2] + kQ[1][0] * elt[1][2] + + kQ[2][0] * elt[2][2]; + + kR[1][2] = kQ[0][1] * elt[0][2] + kQ[1][1] * elt[1][2] + + kQ[2][1] * elt[2][2]; + + kR[2][2] = kQ[0][2] * elt[0][2] + kQ[1][2] * elt[1][2] + + kQ[2][2] * elt[2][2]; + + // the scaling component + kD[0] = kR[0][0]; + + kD[1] = kR[1][1]; + + kD[2] = kR[2][2]; + + // the shear component + float fInvD0 = 1.0 / kD[0]; + + kU[0] = kR[0][1] * fInvD0; + + kU[1] = kR[0][2] * fInvD0; + + kU[2] = kR[1][2] / kD[1]; +} + +//---------------------------------------------------------------------------- +float Matrix3::maxCubicRoot (float afCoeff[3]) { + // Spectral norm is for A^T*A, so characteristic polynomial + // P(x) = c[0]+c[1]*x+c[2]*x^2+x^3 has three positive float roots. + // This yields the assertions c[0] < 0 and c[2]*c[2] >= 3*c[1]. + + // quick out for uniform scale (triple root) + const float fOneThird = 1.0f / 3.0f; + const float fEpsilon = 1e-06f; + float fDiscr = afCoeff[2] * afCoeff[2] - 3.0f * afCoeff[1]; + + if ( fDiscr <= fEpsilon ) + return -fOneThird*afCoeff[2]; + + // Compute an upper bound on roots of P(x). This assumes that A^T*A + // has been scaled by its largest entry. + float fX = 1.0f; + + float fPoly = afCoeff[0] + fX * (afCoeff[1] + fX * (afCoeff[2] + fX)); + + if ( fPoly < 0.0f ) { + // uses a matrix norm to find an upper bound on maximum root + fX = G3D::abs(afCoeff[0]); + float fTmp = 1.0 + G3D::abs(afCoeff[1]); + + if ( fTmp > fX ) + fX = fTmp; + + fTmp = 1.0 + G3D::abs(afCoeff[2]); + + if ( fTmp > fX ) + fX = fTmp; + } + + // Newton's method to find root + float fTwoC2 = 2.0f * afCoeff[2]; + + for (int i = 0; i < 16; i++) { + fPoly = afCoeff[0] + fX * (afCoeff[1] + fX * (afCoeff[2] + fX)); + + if ( G3D::abs(fPoly) <= fEpsilon ) + return fX; + + float fDeriv = afCoeff[1] + fX * (fTwoC2 + 3.0f * fX); + + fX -= fPoly / fDeriv; + } + + return fX; +} + +//---------------------------------------------------------------------------- +float Matrix3::spectralNorm () const { + Matrix3 kP; + int iRow, iCol; + float fPmax = 0.0; + + for (iRow = 0; iRow < 3; iRow++) { + for (iCol = 0; iCol < 3; iCol++) { + kP[iRow][iCol] = 0.0; + + for (int iMid = 0; iMid < 3; iMid++) { + kP[iRow][iCol] += + elt[iMid][iRow] * elt[iMid][iCol]; + } + + if ( kP[iRow][iCol] > fPmax ) + fPmax = kP[iRow][iCol]; + } + } + + float fInvPmax = 1.0 / fPmax; + + for (iRow = 0; iRow < 3; iRow++) { + for (iCol = 0; iCol < 3; iCol++) + kP[iRow][iCol] *= fInvPmax; + } + + float afCoeff[3]; + afCoeff[0] = -(kP[0][0] * (kP[1][1] * kP[2][2] - kP[1][2] * kP[2][1]) + + kP[0][1] * (kP[2][0] * kP[1][2] - kP[1][0] * kP[2][2]) + + kP[0][2] * (kP[1][0] * kP[2][1] - kP[2][0] * kP[1][1])); + afCoeff[1] = kP[0][0] * kP[1][1] - kP[0][1] * kP[1][0] + + kP[0][0] * kP[2][2] - kP[0][2] * kP[2][0] + + kP[1][1] * kP[2][2] - kP[1][2] * kP[2][1]; + afCoeff[2] = -(kP[0][0] + kP[1][1] + kP[2][2]); + + float fRoot = maxCubicRoot(afCoeff); + float fNorm = sqrt(fPmax * fRoot); + return fNorm; +} + +//---------------------------------------------------------------------------- +void Matrix3::toAxisAngle (Vector3& rkAxis, float& rfRadians) const { + // Let (x,y,z) be the unit-length axis and let A be an angle of rotation. + // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 where + // I is the identity and + // + // +- -+ + // P = | 0 -z +y | + // | +z 0 -x | + // | -y +x 0 | + // +- -+ + // + // If A > 0, R represents a counterclockwise rotation about the axis in + // the sense of looking from the tip of the axis vector towards the + // origin. Some algebra will show that + // + // cos(A) = (trace(R)-1)/2 and R - R^t = 2*sin(A)*P + // + // In the event that A = pi, R-R^t = 0 which prevents us from extracting + // the axis through P. Instead note that R = I+2*P^2 when A = pi, so + // P^2 = (R-I)/2. The diagonal entries of P^2 are x^2-1, y^2-1, and + // z^2-1. We can solve these for axis (x,y,z). Because the angle is pi, + // it does not matter which sign you choose on the square roots. + + float fTrace = elt[0][0] + elt[1][1] + elt[2][2]; + float fCos = 0.5 * (fTrace - 1.0); + rfRadians = G3D::aCos(fCos); // in [0,PI] + + if ( rfRadians > 0.0 ) { + if ( rfRadians < G3D_PI ) { + rkAxis.x = elt[2][1] - elt[1][2]; + rkAxis.y = elt[0][2] - elt[2][0]; + rkAxis.z = elt[1][0] - elt[0][1]; + rkAxis.unitize(); + } else { + // angle is PI + float fHalfInverse; + + if ( elt[0][0] >= elt[1][1] ) { + // r00 >= r11 + if ( elt[0][0] >= elt[2][2] ) { + // r00 is maximum diagonal term + rkAxis.x = 0.5 * sqrt(elt[0][0] - + elt[1][1] - elt[2][2] + 1.0); + fHalfInverse = 0.5 / rkAxis.x; + rkAxis.y = fHalfInverse * elt[0][1]; + rkAxis.z = fHalfInverse * elt[0][2]; + } else { + // r22 is maximum diagonal term + rkAxis.z = 0.5 * sqrt(elt[2][2] - + elt[0][0] - elt[1][1] + 1.0); + fHalfInverse = 0.5 / rkAxis.z; + rkAxis.x = fHalfInverse * elt[0][2]; + rkAxis.y = fHalfInverse * elt[1][2]; + } + } else { + // r11 > r00 + if ( elt[1][1] >= elt[2][2] ) { + // r11 is maximum diagonal term + rkAxis.y = 0.5 * sqrt(elt[1][1] - + elt[0][0] - elt[2][2] + 1.0); + fHalfInverse = 0.5 / rkAxis.y; + rkAxis.x = fHalfInverse * elt[0][1]; + rkAxis.z = fHalfInverse * elt[1][2]; + } else { + // r22 is maximum diagonal term + rkAxis.z = 0.5 * sqrt(elt[2][2] - + elt[0][0] - elt[1][1] + 1.0); + fHalfInverse = 0.5 / rkAxis.z; + rkAxis.x = fHalfInverse * elt[0][2]; + rkAxis.y = fHalfInverse * elt[1][2]; + } + } + } + } else { + // The angle is 0 and the matrix is the identity. Any axis will + // work, so just use the x-axis. + rkAxis.x = 1.0; + rkAxis.y = 0.0; + rkAxis.z = 0.0; + } +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromAxisAngle (const Vector3& rkAxis, float fRadians) { + Matrix3 m; + + float fCos = cos(fRadians); + float fSin = sin(fRadians); + float fOneMinusCos = 1.0 - fCos; + float fX2 = rkAxis.x * rkAxis.x; + float fY2 = rkAxis.y * rkAxis.y; + float fZ2 = rkAxis.z * rkAxis.z; + float fXYM = rkAxis.x * rkAxis.y * fOneMinusCos; + float fXZM = rkAxis.x * rkAxis.z * fOneMinusCos; + float fYZM = rkAxis.y * rkAxis.z * fOneMinusCos; + float fXSin = rkAxis.x * fSin; + float fYSin = rkAxis.y * fSin; + float fZSin = rkAxis.z * fSin; + + m.elt[0][0] = fX2 * fOneMinusCos + fCos; + m.elt[0][1] = fXYM - fZSin; + m.elt[0][2] = fXZM + fYSin; + m.elt[1][0] = fXYM + fZSin; + m.elt[1][1] = fY2 * fOneMinusCos + fCos; + m.elt[1][2] = fYZM - fXSin; + m.elt[2][0] = fXZM - fYSin; + m.elt[2][1] = fYZM + fXSin; + m.elt[2][2] = fZ2 * fOneMinusCos + fCos; + + return m; +} + +//---------------------------------------------------------------------------- +bool Matrix3::toEulerAnglesXYZ (float& rfXAngle, float& rfYAngle, + float& rfZAngle) const { + // rot = cy*cz -cy*sz sy + // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx + // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy + + if ( elt[0][2] < 1.0f ) { + if ( elt[0][2] > -1.0f ) { + rfXAngle = G3D::aTan2( -elt[1][2], elt[2][2]); + rfYAngle = (float) G3D::aSin(elt[0][2]); + rfZAngle = G3D::aTan2( -elt[0][1], elt[0][0]); + return true; + } else { + // WARNING. Not unique. XA - ZA = -atan2(r10,r11) + rfXAngle = -G3D::aTan2(elt[1][0], elt[1][1]); + rfYAngle = -(float)G3D_HALF_PI; + rfZAngle = 0.0f; + return false; + } + } else { + // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) + rfXAngle = G3D::aTan2(elt[1][0], elt[1][1]); + rfYAngle = (float)G3D_HALF_PI; + rfZAngle = 0.0f; + return false; + } +} + +//---------------------------------------------------------------------------- +bool Matrix3::toEulerAnglesXZY (float& rfXAngle, float& rfZAngle, + float& rfYAngle) const { + // rot = cy*cz -sz cz*sy + // sx*sy+cx*cy*sz cx*cz -cy*sx+cx*sy*sz + // -cx*sy+cy*sx*sz cz*sx cx*cy+sx*sy*sz + + if ( elt[0][1] < 1.0f ) { + if ( elt[0][1] > -1.0f ) { + rfXAngle = G3D::aTan2(elt[2][1], elt[1][1]); + rfZAngle = (float) asin( -elt[0][1]); + rfYAngle = G3D::aTan2(elt[0][2], elt[0][0]); + return true; + } else { + // WARNING. Not unique. XA - YA = atan2(r20,r22) + rfXAngle = G3D::aTan2(elt[2][0], elt[2][2]); + rfZAngle = (float)G3D_HALF_PI; + rfYAngle = 0.0; + return false; + } + } else { + // WARNING. Not unique. XA + YA = atan2(-r20,r22) + rfXAngle = G3D::aTan2( -elt[2][0], elt[2][2]); + rfZAngle = -(float)G3D_HALF_PI; + rfYAngle = 0.0f; + return false; + } +} + +//---------------------------------------------------------------------------- +bool Matrix3::toEulerAnglesYXZ (float& rfYAngle, float& rfXAngle, + float& rfZAngle) const { + // rot = cy*cz+sx*sy*sz cz*sx*sy-cy*sz cx*sy + // cx*sz cx*cz -sx + // -cz*sy+cy*sx*sz cy*cz*sx+sy*sz cx*cy + + if ( elt[1][2] < 1.0 ) { + if ( elt[1][2] > -1.0 ) { + rfYAngle = G3D::aTan2(elt[0][2], elt[2][2]); + rfXAngle = (float) asin( -elt[1][2]); + rfZAngle = G3D::aTan2(elt[1][0], elt[1][1]); + return true; + } else { + // WARNING. Not unique. YA - ZA = atan2(r01,r00) + rfYAngle = G3D::aTan2(elt[0][1], elt[0][0]); + rfXAngle = (float)G3D_HALF_PI; + rfZAngle = 0.0; + return false; + } + } else { + // WARNING. Not unique. YA + ZA = atan2(-r01,r00) + rfYAngle = G3D::aTan2( -elt[0][1], elt[0][0]); + rfXAngle = -(float)G3D_HALF_PI; + rfZAngle = 0.0f; + return false; + } +} + +//---------------------------------------------------------------------------- +bool Matrix3::toEulerAnglesYZX (float& rfYAngle, float& rfZAngle, + float& rfXAngle) const { + // rot = cy*cz sx*sy-cx*cy*sz cx*sy+cy*sx*sz + // sz cx*cz -cz*sx + // -cz*sy cy*sx+cx*sy*sz cx*cy-sx*sy*sz + + if ( elt[1][0] < 1.0 ) { + if ( elt[1][0] > -1.0 ) { + rfYAngle = G3D::aTan2( -elt[2][0], elt[0][0]); + rfZAngle = (float) asin(elt[1][0]); + rfXAngle = G3D::aTan2( -elt[1][2], elt[1][1]); + return true; + } else { + // WARNING. Not unique. YA - XA = -atan2(r21,r22); + rfYAngle = -G3D::aTan2(elt[2][1], elt[2][2]); + rfZAngle = -(float)G3D_HALF_PI; + rfXAngle = 0.0; + return false; + } + } else { + // WARNING. Not unique. YA + XA = atan2(r21,r22) + rfYAngle = G3D::aTan2(elt[2][1], elt[2][2]); + rfZAngle = (float)G3D_HALF_PI; + rfXAngle = 0.0f; + return false; + } +} + +//---------------------------------------------------------------------------- +bool Matrix3::toEulerAnglesZXY (float& rfZAngle, float& rfXAngle, + float& rfYAngle) const { + // rot = cy*cz-sx*sy*sz -cx*sz cz*sy+cy*sx*sz + // cz*sx*sy+cy*sz cx*cz -cy*cz*sx+sy*sz + // -cx*sy sx cx*cy + + if ( elt[2][1] < 1.0 ) { + if ( elt[2][1] > -1.0 ) { + rfZAngle = G3D::aTan2( -elt[0][1], elt[1][1]); + rfXAngle = (float) asin(elt[2][1]); + rfYAngle = G3D::aTan2( -elt[2][0], elt[2][2]); + return true; + } else { + // WARNING. Not unique. ZA - YA = -atan(r02,r00) + rfZAngle = -G3D::aTan2(elt[0][2], elt[0][0]); + rfXAngle = -(float)G3D_HALF_PI; + rfYAngle = 0.0f; + return false; + } + } else { + // WARNING. Not unique. ZA + YA = atan2(r02,r00) + rfZAngle = G3D::aTan2(elt[0][2], elt[0][0]); + rfXAngle = (float)G3D_HALF_PI; + rfYAngle = 0.0f; + return false; + } +} + +//---------------------------------------------------------------------------- +bool Matrix3::toEulerAnglesZYX (float& rfZAngle, float& rfYAngle, + float& rfXAngle) const { + // rot = cy*cz cz*sx*sy-cx*sz cx*cz*sy+sx*sz + // cy*sz cx*cz+sx*sy*sz -cz*sx+cx*sy*sz + // -sy cy*sx cx*cy + + if ( elt[2][0] < 1.0 ) { + if ( elt[2][0] > -1.0 ) { + rfZAngle = atan2f(elt[1][0], elt[0][0]); + rfYAngle = asinf(-(double)elt[2][1]); + rfXAngle = atan2f(elt[2][1], elt[2][2]); + return true; + } else { + // WARNING. Not unique. ZA - XA = -atan2(r01,r02) + rfZAngle = -G3D::aTan2(elt[0][1], elt[0][2]); + rfYAngle = (float)G3D_HALF_PI; + rfXAngle = 0.0f; + return false; + } + } else { + // WARNING. Not unique. ZA + XA = atan2(-r01,-r02) + rfZAngle = G3D::aTan2( -elt[0][1], -elt[0][2]); + rfYAngle = -(float)G3D_HALF_PI; + rfXAngle = 0.0f; + return false; + } +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromEulerAnglesXYZ (float fYAngle, float fPAngle, + float fRAngle) { + float fCos, fSin; + + fCos = cosf(fYAngle); + fSin = sinf(fYAngle); + Matrix3 kXMat(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0, fSin, fCos); + + fCos = cosf(fPAngle); + fSin = sinf(fPAngle); + Matrix3 kYMat(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos); + + fCos = cosf(fRAngle); + fSin = sinf(fRAngle); + Matrix3 kZMat(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f); + + return kXMat * (kYMat * kZMat); +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromEulerAnglesXZY (float fYAngle, float fPAngle, + float fRAngle) { + + float fCos, fSin; + + fCos = cosf(fYAngle); + fSin = sinf(fYAngle); + Matrix3 kXMat(1.0, 0.0, 0.0, 0.0, fCos, -fSin, 0.0, fSin, fCos); + + fCos = cosf(fPAngle); + fSin = sinf(fPAngle); + Matrix3 kZMat(fCos, -fSin, 0.0, fSin, fCos, 0.0, 0.0, 0.0, 1.0); + + fCos = cosf(fRAngle); + fSin = sinf(fRAngle); + Matrix3 kYMat(fCos, 0.0, fSin, 0.0, 1.0, 0.0, -fSin, 0.0, fCos); + + return kXMat * (kZMat * kYMat); +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromEulerAnglesYXZ( + float fYAngle, + float fPAngle, + float fRAngle) { + + float fCos, fSin; + + fCos = cos(fYAngle); + fSin = sin(fYAngle); + Matrix3 kYMat(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos); + + fCos = cos(fPAngle); + fSin = sin(fPAngle); + Matrix3 kXMat(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0f, fSin, fCos); + + fCos = cos(fRAngle); + fSin = sin(fRAngle); + Matrix3 kZMat(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f); + + return kYMat * (kXMat * kZMat); +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromEulerAnglesYZX( + float fYAngle, + float fPAngle, + float fRAngle) { + + float fCos, fSin; + + fCos = cos(fYAngle); + fSin = sin(fYAngle); + Matrix3 kYMat(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos); + + fCos = cos(fPAngle); + fSin = sin(fPAngle); + Matrix3 kZMat(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f); + + fCos = cos(fRAngle); + fSin = sin(fRAngle); + Matrix3 kXMat(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0f, fSin, fCos); + + return kYMat * (kZMat * kXMat); +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromEulerAnglesZXY (float fYAngle, float fPAngle, + float fRAngle) { + float fCos, fSin; + + fCos = cos(fYAngle); + fSin = sin(fYAngle); + Matrix3 kZMat(fCos, -fSin, 0.0, fSin, fCos, 0.0, 0.0, 0.0, 1.0); + + fCos = cos(fPAngle); + fSin = sin(fPAngle); + Matrix3 kXMat(1.0, 0.0, 0.0, 0.0, fCos, -fSin, 0.0, fSin, fCos); + + fCos = cos(fRAngle); + fSin = sin(fRAngle); + Matrix3 kYMat(fCos, 0.0, fSin, 0.0, 1.0, 0.0, -fSin, 0.0, fCos); + + return kZMat * (kXMat * kYMat); +} + +//---------------------------------------------------------------------------- +Matrix3 Matrix3::fromEulerAnglesZYX (float fYAngle, float fPAngle, + float fRAngle) { + float fCos, fSin; + + fCos = cos(fYAngle); + fSin = sin(fYAngle); + Matrix3 kZMat(fCos, -fSin, 0.0, fSin, fCos, 0.0, 0.0, 0.0, 1.0); + + fCos = cos(fPAngle); + fSin = sin(fPAngle); + Matrix3 kYMat(fCos, 0.0, fSin, 0.0, 1.0, 0.0, -fSin, 0.0, fCos); + + fCos = cos(fRAngle); + fSin = sin(fRAngle); + Matrix3 kXMat(1.0, 0.0, 0.0, 0.0, fCos, -fSin, 0.0, fSin, fCos); + + return kZMat * (kYMat * kXMat); +} + +//---------------------------------------------------------------------------- +void Matrix3::tridiagonal (float afDiag[3], float afSubDiag[3]) { + // Householder reduction T = Q^t M Q + // Input: + // mat, symmetric 3x3 matrix M + // Output: + // mat, orthogonal matrix Q + // diag, diagonal entries of T + // subd, subdiagonal entries of T (T is symmetric) + + float fA = elt[0][0]; + float fB = elt[0][1]; + float fC = elt[0][2]; + float fD = elt[1][1]; + float fE = elt[1][2]; + float fF = elt[2][2]; + + afDiag[0] = fA; + afSubDiag[2] = 0.0; + + if ( G3D::abs(fC) >= EPSILON ) { + float fLength = sqrt(fB * fB + fC * fC); + float fInvLength = 1.0 / fLength; + fB *= fInvLength; + fC *= fInvLength; + float fQ = 2.0 * fB * fE + fC * (fF - fD); + afDiag[1] = fD + fC * fQ; + afDiag[2] = fF - fC * fQ; + afSubDiag[0] = fLength; + afSubDiag[1] = fE - fB * fQ; + elt[0][0] = 1.0; + elt[0][1] = 0.0; + elt[0][2] = 0.0; + elt[1][0] = 0.0; + elt[1][1] = fB; + elt[1][2] = fC; + elt[2][0] = 0.0; + elt[2][1] = fC; + elt[2][2] = -fB; + } else { + afDiag[1] = fD; + afDiag[2] = fF; + afSubDiag[0] = fB; + afSubDiag[1] = fE; + elt[0][0] = 1.0; + elt[0][1] = 0.0; + elt[0][2] = 0.0; + elt[1][0] = 0.0; + elt[1][1] = 1.0; + elt[1][2] = 0.0; + elt[2][0] = 0.0; + elt[2][1] = 0.0; + elt[2][2] = 1.0; + } +} + +//---------------------------------------------------------------------------- +bool Matrix3::qLAlgorithm (float afDiag[3], float afSubDiag[3]) { + // QL iteration with implicit shifting to reduce matrix from tridiagonal + // to diagonal + + for (int i0 = 0; i0 < 3; i0++) { + const int iMaxIter = 32; + int iIter; + + for (iIter = 0; iIter < iMaxIter; iIter++) { + int i1; + + for (i1 = i0; i1 <= 1; i1++) { + float fSum = G3D::abs(afDiag[i1]) + + G3D::abs(afDiag[i1 + 1]); + + if ( G3D::abs(afSubDiag[i1]) + fSum == fSum ) + break; + } + + if ( i1 == i0 ) + break; + + float fTmp0 = (afDiag[i0 + 1] - afDiag[i0]) / (2.0 * afSubDiag[i0]); + + float fTmp1 = sqrt(fTmp0 * fTmp0 + 1.0); + + if ( fTmp0 < 0.0 ) + fTmp0 = afDiag[i1] - afDiag[i0] + afSubDiag[i0] / (fTmp0 - fTmp1); + else + fTmp0 = afDiag[i1] - afDiag[i0] + afSubDiag[i0] / (fTmp0 + fTmp1); + + float fSin = 1.0; + + float fCos = 1.0; + + float fTmp2 = 0.0; + + for (int i2 = i1 - 1; i2 >= i0; i2--) { + float fTmp3 = fSin * afSubDiag[i2]; + float fTmp4 = fCos * afSubDiag[i2]; + + if (G3D::abs(fTmp3) >= G3D::abs(fTmp0)) { + fCos = fTmp0 / fTmp3; + fTmp1 = sqrt(fCos * fCos + 1.0); + afSubDiag[i2 + 1] = fTmp3 * fTmp1; + fSin = 1.0 / fTmp1; + fCos *= fSin; + } else { + fSin = fTmp3 / fTmp0; + fTmp1 = sqrt(fSin * fSin + 1.0); + afSubDiag[i2 + 1] = fTmp0 * fTmp1; + fCos = 1.0 / fTmp1; + fSin *= fCos; + } + + fTmp0 = afDiag[i2 + 1] - fTmp2; + fTmp1 = (afDiag[i2] - fTmp0) * fSin + 2.0 * fTmp4 * fCos; + fTmp2 = fSin * fTmp1; + afDiag[i2 + 1] = fTmp0 + fTmp2; + fTmp0 = fCos * fTmp1 - fTmp4; + + for (int iRow = 0; iRow < 3; iRow++) { + fTmp3 = elt[iRow][i2 + 1]; + elt[iRow][i2 + 1] = fSin * elt[iRow][i2] + + fCos * fTmp3; + elt[iRow][i2] = fCos * elt[iRow][i2] - + fSin * fTmp3; + } + } + + afDiag[i0] -= fTmp2; + afSubDiag[i0] = fTmp0; + afSubDiag[i1] = 0.0; + } + + if ( iIter == iMaxIter ) { + // should not get here under normal circumstances + return false; + } + } + + return true; +} + +//---------------------------------------------------------------------------- +void Matrix3::eigenSolveSymmetric (float afEigenvalue[3], + Vector3 akEigenvector[3]) const { + Matrix3 kMatrix = *this; + float afSubDiag[3]; + kMatrix.tridiagonal(afEigenvalue, afSubDiag); + kMatrix.qLAlgorithm(afEigenvalue, afSubDiag); + + for (int i = 0; i < 3; i++) { + akEigenvector[i][0] = kMatrix[0][i]; + akEigenvector[i][1] = kMatrix[1][i]; + akEigenvector[i][2] = kMatrix[2][i]; + } + + // make eigenvectors form a right--handed system + Vector3 kCross = akEigenvector[1].cross(akEigenvector[2]); + + float fDet = akEigenvector[0].dot(kCross); + + if ( fDet < 0.0 ) { + akEigenvector[2][0] = - akEigenvector[2][0]; + akEigenvector[2][1] = - akEigenvector[2][1]; + akEigenvector[2][2] = - akEigenvector[2][2]; + } +} + +//---------------------------------------------------------------------------- +void Matrix3::tensorProduct (const Vector3& rkU, const Vector3& rkV, + Matrix3& rkProduct) { + for (int iRow = 0; iRow < 3; iRow++) { + for (int iCol = 0; iCol < 3; iCol++) { + rkProduct[iRow][iCol] = rkU[iRow] * rkV[iCol]; + } + } +} + +//---------------------------------------------------------------------------- + +// Runs in 52 cycles on AMD, 76 cycles on Intel Centrino +// +// The loop unrolling is necessary for performance. +// I was unable to improve performance further by flattening the matrices +// into float*'s instead of 2D arrays. +// +// -morgan +void Matrix3::_mul(const Matrix3& A, const Matrix3& B, Matrix3& out) { + const float* ARowPtr = A.elt[0]; + float* outRowPtr = out.elt[0]; + outRowPtr[0] = + ARowPtr[0] * B.elt[0][0] + + ARowPtr[1] * B.elt[1][0] + + ARowPtr[2] * B.elt[2][0]; + outRowPtr[1] = + ARowPtr[0] * B.elt[0][1] + + ARowPtr[1] * B.elt[1][1] + + ARowPtr[2] * B.elt[2][1]; + outRowPtr[2] = + ARowPtr[0] * B.elt[0][2] + + ARowPtr[1] * B.elt[1][2] + + ARowPtr[2] * B.elt[2][2]; + + ARowPtr = A.elt[1]; + outRowPtr = out.elt[1]; + + outRowPtr[0] = + ARowPtr[0] * B.elt[0][0] + + ARowPtr[1] * B.elt[1][0] + + ARowPtr[2] * B.elt[2][0]; + outRowPtr[1] = + ARowPtr[0] * B.elt[0][1] + + ARowPtr[1] * B.elt[1][1] + + ARowPtr[2] * B.elt[2][1]; + outRowPtr[2] = + ARowPtr[0] * B.elt[0][2] + + ARowPtr[1] * B.elt[1][2] + + ARowPtr[2] * B.elt[2][2]; + + ARowPtr = A.elt[2]; + outRowPtr = out.elt[2]; + + outRowPtr[0] = + ARowPtr[0] * B.elt[0][0] + + ARowPtr[1] * B.elt[1][0] + + ARowPtr[2] * B.elt[2][0]; + outRowPtr[1] = + ARowPtr[0] * B.elt[0][1] + + ARowPtr[1] * B.elt[1][1] + + ARowPtr[2] * B.elt[2][1]; + outRowPtr[2] = + ARowPtr[0] * B.elt[0][2] + + ARowPtr[1] * B.elt[1][2] + + ARowPtr[2] * B.elt[2][2]; +} + +//---------------------------------------------------------------------------- +void Matrix3::_transpose(const Matrix3& A, Matrix3& out) { + out[0][0] = A.elt[0][0]; + out[0][1] = A.elt[1][0]; + out[0][2] = A.elt[2][0]; + out[1][0] = A.elt[0][1]; + out[1][1] = A.elt[1][1]; + out[1][2] = A.elt[2][1]; + out[2][0] = A.elt[0][2]; + out[2][1] = A.elt[1][2]; + out[2][2] = A.elt[2][2]; +} + +//----------------------------------------------------------------------------- +std::string Matrix3::toString() const { + return G3D::format("[%g, %g, %g; %g, %g, %g; %g, %g, %g]", + elt[0][0], elt[0][1], elt[0][2], + elt[1][0], elt[1][1], elt[1][2], + elt[2][0], elt[2][1], elt[2][2]); +} + + + +} // namespace + diff --git a/dep/src/g3dlite/Plane.cpp b/dep/src/g3dlite/Plane.cpp new file mode 100644 index 000000000..c958a10a7 --- /dev/null +++ b/dep/src/g3dlite/Plane.cpp @@ -0,0 +1,131 @@ +/** + @file Plane.cpp + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2003-02-06 + @edited 2006-01-29 + */ + +#include "G3D/platform.h" +#include "G3D/format.h" +#include "G3D/Plane.h" +#include "G3D/stringutils.h" + +namespace G3D { + +Plane::Plane( + Vector4 point0, + Vector4 point1, + Vector4 point2) { + + debugAssertM( + point0.w != 0 || + point1.w != 0 || + point2.w != 0, + "At least one point must be finite."); + + // Rotate the points around so that the finite points come first. + + while ((point0.w == 0) && + ((point1.w == 0) || (point2.w != 0))) { + Vector4 temp = point0; + point0 = point1; + point1 = point2; + point2 = temp; + } + + Vector3 dir1; + Vector3 dir2; + + if (point1.w == 0) { + // 1 finite, 2 infinite points; the plane must contain + // the direction of the two direcitons + dir1 = point1.xyz(); + dir2 = point2.xyz(); + } else if (point2.w != 0) { + // 3 finite points, the plane must contain the directions + // betwseen the points. + dir1 = point1.xyz() - point0.xyz(); + dir2 = point2.xyz() - point0.xyz(); + } else { + // 2 finite, 1 infinite point; the plane must contain + // the direction between the first two points and the + // direction of the third point. + dir1 = point1.xyz() - point0.xyz(); + dir2 = point2.xyz(); + } + + _normal = dir1.cross(dir2).direction(); + _distance = _normal.dot(point0.xyz()); +} + + +Plane::Plane( + const Vector3& point0, + const Vector3& point1, + const Vector3& point2) { + + _normal = (point1 - point0).cross(point2 - point0).direction(); + _distance = _normal.dot(point0); +} + + +Plane::Plane( + const Vector3& __normal, + const Vector3& point) { + + _normal = __normal.direction(); + _distance = _normal.dot(point); +} + + +Plane Plane::fromEquation(float a, float b, float c, float d) { + Vector3 n(a, b, c); + float magnitude = n.magnitude(); + d /= magnitude; + n /= magnitude; + return Plane(n, -d); +} + + +void Plane::flip() { + _normal = -_normal; + _distance = -_distance; +} + + +void Plane::getEquation(Vector3& n, float& d) const { + double _d; + getEquation(n, _d); + d = (float)_d; +} + +void Plane::getEquation(Vector3& n, double& d) const { + n = _normal; + d = -_distance; +} + + +void Plane::getEquation(float& a, float& b, float& c, float& d) const { + double _a, _b, _c, _d; + getEquation(_a, _b, _c, _d); + a = (float)_a; + b = (float)_b; + c = (float)_c; + d = (float)_d; +} + +void Plane::getEquation(double& a, double& b, double& c, double& d) const { + a = _normal.x; + b = _normal.y; + c = _normal.z; + d = -_distance; +} + + +std::string Plane::toString() const { + return format("Plane(%g, %g, %g, %g)", _normal.x, _normal.y, _normal.z, _distance); +} + +} diff --git a/dep/src/g3dlite/System.cpp b/dep/src/g3dlite/System.cpp new file mode 100644 index 000000000..06be7cd25 --- /dev/null +++ b/dep/src/g3dlite/System.cpp @@ -0,0 +1,666 @@ +/** + @file System.cpp + + @maintainer Morgan McGuire, matrix@graphics3d.com + + Note: every routine must call init() first. + + There are two kinds of detection used in this file. At compile + time, the _MSC_VER #define is used to determine whether x86 assembly + can be used at all. At runtime, processor detection is used to + determine if we can safely call the routines that use that assembly. + + @cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm + @cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1 + @cite Michael Herf http://www.stereopsis.com/memcpy.html + + @created 2003-01-25 + @edited 2006-05-17 + */ + +#include "G3D/platform.h" +#include "G3D/System.h" +#include "G3D/debug.h" +#include "G3D/format.h" + +#ifdef G3D_WIN32 + + #include + #include + #include "G3D/RegistryUtil.h" + +#elif defined(G3D_LINUX) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + // #include + +#elif defined(G3D_OSX) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include +#endif + +#if defined(SSE) + #include +#endif + +namespace G3D { + +static char versionCstr[1024]; +System::OutOfMemoryCallback System::outOfMemoryCallback = NULL; + + +void System::init() { + // Cannot use most G3D data structures or utility functions in here because + // they are not initialized. + + static bool initialized = false; + + if (initialized) { + return; + } + + initialized = true; + + if ((G3D_VER % 100) != 0) { + sprintf(versionCstr, "G3D %d.%02d beta %d", + G3D_VER / 10000, + (G3D_VER / 100) % 100, + G3D_VER % 100); + } else { + sprintf(versionCstr, "G3D %d.%02d", + G3D_VER / 10000, + (G3D_VER / 100) % 100); + } + +} + + + +void System::memcpy(void* dst, const void* src, size_t numBytes) { + ::memcpy(dst, src, numBytes); +} + + +void System::memset(void* dst, uint8 value, size_t numBytes) { + ::memset(dst, value, numBytes); +} + + + + + +//////////////////////////////////////////////////////////////// +class BufferPool { +public: + + /** Only store buffers up to these sizes (in bytes) in each pool-> + Different pools have different management strategies. + + A large block is preallocated for tiny buffers; they are used with + tremendous frequency. Other buffers are allocated as demanded. + */ + enum {tinyBufferSize = 128, smallBufferSize = 1024, medBufferSize = 4096}; + + /** + Most buffers we're allowed to store. + 64000 * 128 = 8 MB (preallocated) + 1024 * 1024 = 1 MB (allocated on demand) + 1024 * 4096 = 4 MB (allocated on demand) + */ + enum {maxTinyBuffers = 64000, maxSmallBuffers = 1024, maxMedBuffers = 1024}; + +private: + + class MemBlock { + public: + void* ptr; + size_t bytes; + + inline MemBlock() : ptr(NULL), bytes(0) {} + inline MemBlock(void* p, size_t b) : ptr(p), bytes(b) {} + }; + + MemBlock smallPool[maxSmallBuffers]; + int smallPoolSize; + + MemBlock medPool[maxMedBuffers]; + int medPoolSize; + + /** The tiny pool is a single block of storage into which all tiny + objects are allocated. This provides better locality for + small objects and avoids the search time, since all tiny + blocks are exactly the same size. */ + void* tinyPool[maxTinyBuffers]; + int tinyPoolSize; + + /** Pointer to the data in the tiny pool */ + void* tinyHeap; + +# ifdef G3D_WIN32 + CRITICAL_SECTION mutex; +# else + pthread_mutex_t mutex; +# endif + + /** Provide synchronization between threads */ + void lock() { +# ifdef G3D_WIN32 + EnterCriticalSection(&mutex); +# else + pthread_mutex_lock(&mutex); +# endif + } + + void unlock() { +# ifdef G3D_WIN32 + LeaveCriticalSection(&mutex); +# else + pthread_mutex_unlock(&mutex); +# endif + } + + /** + Malloc out of the tiny heap. + */ + inline void* tinyMalloc(size_t bytes) { + // Note that we ignore the actual byte size + // and create a constant size block. + (void)bytes; + debugAssert(tinyBufferSize >= bytes); + + void* ptr = NULL; + + if (tinyPoolSize > 0) { + --tinyPoolSize; + // Return the last one + ptr = tinyPool[tinyPoolSize]; + } + + return ptr; + } + + /** Returns true if this is a pointer into the tiny heap. */ + bool inTinyHeap(void* ptr) { + return (ptr >= tinyHeap) && + (ptr < (uint8*)tinyHeap + maxTinyBuffers * tinyBufferSize); + } + + void tinyFree(void* ptr) { + debugAssert(tinyPoolSize < maxTinyBuffers); + + // Put the pointer back into the free list + tinyPool[tinyPoolSize] = ptr; + ++tinyPoolSize; + + } + + void flushPool(MemBlock* pool, int& poolSize) { + for (int i = 0; i < poolSize; ++i) { + ::free(pool->ptr); + pool->ptr = NULL; + pool->bytes = 0; + } + poolSize = 0; + } + + + /** Allocate out of a specific pool-> Return NULL if no suitable + memory was found. + + */ + void* malloc(MemBlock* pool, int& poolSize, size_t bytes) { + + // OPT: find the smallest block that satisfies the request. + + // See if there's something we can use in the buffer pool-> + // Search backwards since usually we'll re-use the last one. + for (int i = (int)poolSize - 1; i >= 0; --i) { + if (pool[i].bytes >= bytes) { + // We found a suitable entry in the pool-> + + // No need to offset the pointer; it is already offset + void* ptr = pool[i].ptr; + + // Remove this element from the pool + --poolSize; + pool[i] = pool[poolSize]; + + return ptr; + } + } + + return NULL; + } + +public: + + /** Count of memory allocations that have occurred. */ + int totalMallocs; + int mallocsFromTinyPool; + int mallocsFromSmallPool; + int mallocsFromMedPool; + + /** Amount of memory currently allocated (according to the application). + This does not count the memory still remaining in the buffer pool, + but does count extra memory required for rounding off to the size + of a buffer. + Primarily useful for detecting leaks.*/ + // TODO: make me an atomic int! + int bytesAllocated; + + BufferPool() { + totalMallocs = 0; + + mallocsFromTinyPool = 0; + mallocsFromSmallPool = 0; + mallocsFromMedPool = 0; + + bytesAllocated = true; + + tinyPoolSize = 0; + tinyHeap = NULL; + + smallPoolSize = 0; + + medPoolSize = 0; + + + // Initialize the tiny heap as a bunch of pointers into one + // pre-allocated buffer. + tinyHeap = ::malloc(maxTinyBuffers * tinyBufferSize); + for (int i = 0; i < maxTinyBuffers; ++i) { + tinyPool[i] = (uint8*)tinyHeap + (tinyBufferSize * i); + } + tinyPoolSize = maxTinyBuffers; + +# ifdef G3D_WIN32 + InitializeCriticalSection(&mutex); +# else + pthread_mutex_init(&mutex, NULL); +# endif + } + + + ~BufferPool() { + ::free(tinyHeap); +# ifdef G3D_WIN32 + DeleteCriticalSection(&mutex); +# else + // No destruction on pthreads +# endif + } + + + void* realloc(void* ptr, size_t bytes) { + if (ptr == NULL) { + return malloc(bytes); + } + + if (inTinyHeap(ptr)) { + if (bytes <= tinyBufferSize) { + // The old pointer actually had enough space. + return ptr; + } else { + // Free the old pointer and malloc + + void* newPtr = malloc(bytes); + System::memcpy(newPtr, ptr, tinyBufferSize); + tinyFree(ptr); + return newPtr; + + } + } else { + // In one of our heaps. + + // See how big the block really was + size_t realSize = ((uint32*)ptr)[-1]; + if (bytes <= realSize) { + // The old block was big enough. + return ptr; + } + + // Need to reallocate + void* newPtr = malloc(bytes); + System::memcpy(newPtr, ptr, realSize); + free(ptr); + return newPtr; + } + } + + + void* malloc(size_t bytes) { + lock(); + ++totalMallocs; + + if (bytes <= tinyBufferSize) { + + void* ptr = tinyMalloc(bytes); + + if (ptr) { + ++mallocsFromTinyPool; + unlock(); + return ptr; + } + + } + + // Failure to allocate a tiny buffer is allowed to flow + // through to a small buffer + if (bytes <= smallBufferSize) { + + void* ptr = malloc(smallPool, smallPoolSize, bytes); + + if (ptr) { + ++mallocsFromSmallPool; + unlock(); + return ptr; + } + + } else if (bytes <= medBufferSize) { + // Note that a small allocation failure does *not* fall + // through into a medium allocation because that would + // waste the medium buffer's resources. + + void* ptr = malloc(medPool, medPoolSize, bytes); + + if (ptr) { + ++mallocsFromMedPool; + unlock(); + return ptr; + } + } + + bytesAllocated += 4 + (int) bytes; + unlock(); + + // Heap allocate + + // Allocate 4 extra bytes for our size header (unfortunate, + // since malloc already added its own header). + void* ptr = ::malloc(bytes + 4); + + if (ptr == NULL) { + // Flush memory pools to try and recover space + flushPool(smallPool, smallPoolSize); + flushPool(medPool, medPoolSize); + ptr = ::malloc(bytes + 4); + } + + + if (ptr == NULL) { + if ((System::outOfMemoryCallback != NULL) && + (System::outOfMemoryCallback(bytes + 4, true) == true)) { + // Re-attempt the malloc + ptr = ::malloc(bytes + 4); + } + } + + if (ptr == NULL) { + if (System::outOfMemoryCallback != NULL) { + // Notify the application + System::outOfMemoryCallback(bytes + 4, false); + } + return NULL; + } + + *(uint32*)ptr = (uint32)bytes; + + return (uint8*)ptr + 4; + } + + + void free(void* ptr) { + if (ptr == NULL) { + // Free does nothing on null pointers + return; + } + + debugAssert(isValidPointer(ptr)); + + if (inTinyHeap(ptr)) { + lock(); + tinyFree(ptr); + unlock(); + return; + } + + uint32 bytes = ((uint32*)ptr)[-1]; + + lock(); + if (bytes <= smallBufferSize) { + if (smallPoolSize < maxSmallBuffers) { + smallPool[smallPoolSize] = MemBlock(ptr, bytes); + ++smallPoolSize; + unlock(); + return; + } + } else if (bytes <= medBufferSize) { + if (medPoolSize < maxMedBuffers) { + medPool[medPoolSize] = MemBlock(ptr, bytes); + ++medPoolSize; + unlock(); + return; + } + } + bytesAllocated -= bytes + 4; + unlock(); + + // Free; the buffer pools are full or this is too big to store. + ::free((uint8*)ptr - 4); + } + + std::string performance() const { + if (totalMallocs > 0) { + int pooled = mallocsFromTinyPool + + mallocsFromSmallPool + + mallocsFromMedPool; + + int total = totalMallocs; + + return format("malloc performance: %5.1f%% <= %db, %5.1f%% <= %db, " + "%5.1f%% <= %db, %5.1f%% > %db", + 100.0 * mallocsFromTinyPool / total, + BufferPool::tinyBufferSize, + 100.0 * mallocsFromSmallPool / total, + BufferPool::smallBufferSize, + 100.0 * mallocsFromMedPool / total, + BufferPool::medBufferSize, + 100.0 * (1.0 - (double)pooled / total), + BufferPool::medBufferSize); + } else { + return "No System::malloc calls made yet."; + } + } + + std::string status() const { + return format("preallocated shared buffers: %5d/%d x %db", + maxTinyBuffers - tinyPoolSize, maxTinyBuffers, tinyBufferSize); + } +}; + +// Dynamically allocated because we need to ensure that +// the buffer pool is still around when the last global variable +// is deallocated. +static BufferPool* bufferpool = NULL; + +std::string System::mallocPerformance() { +#ifndef NO_BUFFERPOOL + return bufferpool->performance(); +#else + return "NO_BUFFERPOOL"; +#endif +} + +std::string System::mallocStatus() { +#ifndef NO_BUFFERPOOL + return bufferpool->status(); +#else + return "NO_BUFFERPOOL"; +#endif +} + + +void System::resetMallocPerformanceCounters() { +#ifndef NO_BUFFERPOOL + bufferpool->totalMallocs = 0; + bufferpool->mallocsFromMedPool = 0; + bufferpool->mallocsFromSmallPool = 0; + bufferpool->mallocsFromTinyPool = 0; +#endif +} + + +#ifndef NO_BUFFERPOOL +inline void initMem() { + // Putting the test here ensures that the system is always + // initialized, even when globals are being allocated. + static bool initialized = false; + if (! initialized) { + bufferpool = new BufferPool(); + initialized = true; + } +} +#endif + + +void* System::malloc(size_t bytes) { +#ifndef NO_BUFFERPOOL + initMem(); + return bufferpool->malloc(bytes); +#else + return ::malloc(bytes); +#endif +} + +void* System::calloc(size_t n, size_t x) { +#ifndef NO_BUFFERPOOL + void* b = System::malloc(n * x); + System::memset(b, 0, n * x); + return b; +#else + return ::calloc(n, x); +#endif +} + + +void* System::realloc(void* block, size_t bytes) { +#ifndef NO_BUFFERPOOL + initMem(); + return bufferpool->realloc(block, bytes); +#else + return ::realloc(block, bytes); +#endif +} + + +void System::free(void* p) { +#ifndef NO_BUFFERPOOL + bufferpool->free(p); +#else + return ::free(p); +#endif +} + + +void* System::alignedMalloc(size_t bytes, size_t alignment) { + alwaysAssertM(isPow2(alignment), "alignment must be a power of 2"); + + // We must align to at least a word boundary. + alignment = iMax((int)alignment, sizeof(void *)); + + // Pad the allocation size with the alignment size and the + // size of the redirect pointer. + size_t totalBytes = bytes + alignment + sizeof(intptr_t); + + void* truePtr = System::malloc(totalBytes); + + if (!truePtr) { + // malloc returned NULL + return NULL; + } + + debugAssert(isValidHeapPointer(truePtr)); + #ifdef G3D_WIN32 + // The blocks we return will not be valid Win32 debug heap + // pointers because they are offset + // debugAssert(_CrtIsValidPointer(truePtr, totalBytes, TRUE) ); + #endif + + // The return pointer will be the next aligned location (we must at least + // leave space for the redirect pointer, however). + char* alignedPtr = ((char*)truePtr)+ sizeof(intptr_t); + +#if 0 + // 2^n - 1 has the form 1111... in binary. + uint32 bitMask = (alignment - 1); + + // Advance forward until we reach an aligned location. + while ((((intptr_t)alignedPtr) & bitMask) != 0) { + alignedPtr += sizeof(void*); + } +#else + alignedPtr += alignment - (((intptr_t)alignedPtr) & (alignment - 1)); + // assert((alignedPtr - truePtr) + bytes <= totalBytes); +#endif + + debugAssert((alignedPtr - truePtr) + bytes <= totalBytes); + + // Immediately before the aligned location, write the true array location + // so that we can free it correctly. + intptr_t* redirectPtr = (intptr_t*)(alignedPtr - sizeof(intptr_t)); + redirectPtr[0] = (intptr_t)truePtr; + + debugAssert(isValidHeapPointer(truePtr)); + + #ifdef G3D_WIN32 + debugAssert( _CrtIsValidPointer(alignedPtr, bytes, TRUE) ); + #endif + return (void*)alignedPtr; +} + + +void System::alignedFree(void* _ptr) { + if (_ptr == NULL) { + return; + } + + char* alignedPtr = (char*)_ptr; + + // Back up one word from the pointer the user passed in. + // We now have a pointer to a pointer to the true start + // of the memory block. + intptr_t* redirectPtr = (intptr_t*)(alignedPtr - sizeof(intptr_t)); + + // Dereference that pointer so that ptr = true start + void* truePtr = (void*)(redirectPtr[0]); + + debugAssert(isValidHeapPointer(truePtr)); + System::free(truePtr); +} + + +} // namespace diff --git a/dep/src/g3dlite/Triangle.cpp b/dep/src/g3dlite/Triangle.cpp new file mode 100644 index 000000000..adb815e16 --- /dev/null +++ b/dep/src/g3dlite/Triangle.cpp @@ -0,0 +1,112 @@ +/** + @file Triangle.cpp + + @maintainer Morgan McGuire, graphics3d.com + + @created 2001-04-06 + @edited 2006-01-20 + + Copyright 2000-2006, Morgan McGuire. + All rights reserved. + */ + +#include "G3D/platform.h" +#include "G3D/Triangle.h" +#include "G3D/Plane.h" +#include "G3D/AABox.h" + +namespace G3D { + + +void Triangle::init(const Vector3& v0, const Vector3& v1, const Vector3& v2) { + + _plane = Plane(v0, v1, v2); + _vertex[0] = v0; + _vertex[1] = v1; + _vertex[2] = v2; + + static int next[] = {1,2,0}; + + for (int i = 0; i < 3; ++i) { + const Vector3 e = _vertex[next[i]] - _vertex[i]; + edgeMagnitude[i] = e.magnitude(); + + if (edgeMagnitude[i] == 0) { + edgeDirection[i] = Vector3::zero(); + } else { + edgeDirection[i] = e / (float)edgeMagnitude[i]; + } + } + + edge01 = _vertex[1] - _vertex[0]; + edge02 = _vertex[2] - _vertex[0]; + + _primaryAxis = _plane.normal().primaryAxis(); + _area = (float)edgeDirection[0].cross(edgeDirection[2]).magnitude() * (edgeMagnitude[0] * edgeMagnitude[2]); + +} + + +Triangle::Triangle() { + init(Vector3::zero(), Vector3::zero(), Vector3::zero()); +} + + +Triangle::Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2) { + init(v0, v1, v2); +} + + +Triangle::~Triangle() { +} + + +double Triangle::area() const { + return _area; +} + + +const Vector3& Triangle::normal() const { + return _plane.normal(); +} + + +const Plane& Triangle::plane() const { + return _plane; +} + + +Vector3 Triangle::center() const { + return (_vertex[0] + _vertex[1] + _vertex[2]) / 3.0; +} + +Vector3 Triangle::randomPoint() const { + // Choose a random point in the parallelogram + + float s = uniformRandom(); + float t = uniformRandom(); + + if (t > 1.0f - s) { + // Outside the triangle; reflect about the + // diagonal of the parallelogram + t = 1.0f - t; + s = 1.0f - s; + } + + return edge01 * s + edge02 * t + _vertex[0]; +} + + +void Triangle::getBounds(AABox& out) const { + Vector3 lo = _vertex[0]; + Vector3 hi = lo; + + for (int i = 1; i < 3; ++i) { + lo = lo.min(_vertex[i]); + hi = hi.max(_vertex[i]); + } + + out = AABox(lo, hi); +} + +} // G3D diff --git a/dep/src/g3dlite/Vector3.cpp b/dep/src/g3dlite/Vector3.cpp new file mode 100644 index 000000000..57ee76d1e --- /dev/null +++ b/dep/src/g3dlite/Vector3.cpp @@ -0,0 +1,443 @@ +/** + @file Vector3.cpp + + 3D vector class + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com + + @created 2001-06-02 + @edited 2006-01-30 + */ + +#include +#include +#include "G3D/Vector3.h" +#include "G3D/g3dmath.h" +#include "G3D/format.h" +#include "G3D/stringutils.h" +#include "G3D/Vector3int16.h" +#include "G3D/Matrix3.h" +#include "G3D/Vector2.h" + +namespace G3D { + +Vector3 Vector3::dummy; + +// Deprecated. +const Vector3 Vector3::ZERO(0, 0, 0); +const Vector3 Vector3::ZERO3(0, 0, 0); +const Vector3 Vector3::UNIT_X(1, 0, 0); +const Vector3 Vector3::UNIT_Y(0, 1, 0); +const Vector3 Vector3::UNIT_Z(0, 0, 1); +const Vector3 Vector3::INF3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); +const Vector3 Vector3::NAN3((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); + +Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) { +} + +Vector3::Axis Vector3::primaryAxis() const { + + Axis a = X_AXIS; + + double nx = abs(x); + double ny = abs(y); + double nz = abs(z); + + if (nx > ny) { + if (nx > nz) { + a = X_AXIS; + } else { + a = Z_AXIS; + } + } else { + if (ny > nz) { + a = Y_AXIS; + } else { + a = Z_AXIS; + } + } + + return a; +} + + +unsigned int Vector3::hashCode() const { + unsigned int xhash = (*(int*)(void*)(&x)); + unsigned int yhash = (*(int*)(void*)(&y)); + unsigned int zhash = (*(int*)(void*)(&z)); + + return xhash + (yhash * 37) + (zhash * 101); +} + +std::ostream& operator<<(std::ostream& os, const Vector3& v) { + return os << v.toString(); +} + + +//---------------------------------------------------------------------------- + +double frand() { + return rand() / (double) RAND_MAX; +} + + +Vector3::Vector3(const class Vector3int16& v) { + x = v.x; + y = v.y; + z = v.z; +} + + +Vector3 Vector3::random() { + Vector3 result; + + do { + result = Vector3(uniformRandom(-1.0, 1.0), + uniformRandom(-1.0, 1.0), + uniformRandom(-1.0, 1.0)); + } while (result.squaredMagnitude() >= 1.0f); + + result.unitize(); + + return result; +} + +//---------------------------------------------------------------------------- +Vector3 Vector3::operator/ (float fScalar) const { + Vector3 kQuot; + + if ( fScalar != 0.0 ) { + float fInvScalar = 1.0f / fScalar; + kQuot.x = fInvScalar * x; + kQuot.y = fInvScalar * y; + kQuot.z = fInvScalar * z; + return kQuot; + } else { + return Vector3::inf(); + } +} + +//---------------------------------------------------------------------------- +Vector3& Vector3::operator/= (float fScalar) { + if (fScalar != 0.0) { + float fInvScalar = 1.0f / fScalar; + x *= fInvScalar; + y *= fInvScalar; + z *= fInvScalar; + } else { + x = (float)G3D::inf(); + y = (float)G3D::inf(); + z = (float)G3D::inf(); + } + + return *this; +} + +//---------------------------------------------------------------------------- +float Vector3::unitize (float fTolerance) { + float fMagnitude = magnitude(); + + if (fMagnitude > fTolerance) { + float fInvMagnitude = 1.0f / fMagnitude; + x *= fInvMagnitude; + y *= fInvMagnitude; + z *= fInvMagnitude; + } else { + fMagnitude = 0.0f; + } + + return fMagnitude; +} + +//---------------------------------------------------------------------------- + +Vector3 Vector3::reflectAbout(const Vector3& normal) const { + + Vector3 out; + + Vector3 N = normal.direction(); + + // 2 * normal.dot(this) * normal - this + return N * 2 * this->dot(N) - *this; +} + +//---------------------------------------------------------------------------- +#if 0 +Vector3 Vector3::cosRandom(const Vector3& normal) { + double e1 = G3D::random(0, 1); + double e2 = G3D::random(0, 1); + + // Angle from normal + double theta = acos(sqrt(e1)); + + // Angle about normal + double phi = 2 * G3D_PI * e2; + + // Make a coordinate system + Vector3 U = normal.direction(); + Vector3 V = Vector3::unitX(); + + if (abs(U.dot(V)) > .9) { + V = Vector3::unitY(); + } + + Vector3 W = U.cross(V).direction(); + V = W.cross(U); + + // Convert to rectangular form + return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W); +} +//---------------------------------------------------------------------------- + +Vector3 Vector3::hemiRandom(const Vector3& normal) { + Vector3 V = Vector3::random(); + + if (V.dot(normal) < 0) { + return -V; + } else { + return V; + } +} +#endif +//---------------------------------------------------------------------------- + +Vector3 Vector3::reflectionDirection(const Vector3& normal) const { + return -reflectAbout(normal).direction(); +} + +//---------------------------------------------------------------------------- + +Vector3 Vector3::refractionDirection( + const Vector3& normal, + float iInside, + float iOutside) const { + + // From pg. 24 of Henrik Wann Jensen. Realistic Image Synthesis + // Using Photon Mapping. AK Peters. ISBN: 1568811470. July 2001. + + // Invert the directions from Wann Jensen's formulation + // and normalize the vectors. + const Vector3 W = -direction(); + Vector3 N = normal.direction(); + + float h1 = iOutside; + float h2 = iInside; + + if (normal.dot(*this) > 0.0f) { + h1 = iInside; + h2 = iOutside; + N = -N; + } + + const float hRatio = h1 / h2; + const float WdotN = W.dot(N); + + float det = 1.0f - (float)square(hRatio) * (1.0f - (float)square(WdotN)); + + if (det < 0) { + // Total internal reflection + return Vector3::zero(); + } else { + return -hRatio * (W - WdotN * N) - N * sqrt(det); + } +} + +//---------------------------------------------------------------------------- +void Vector3::orthonormalize (Vector3 akVector[3]) { + // If the input vectors are v0, v1, and v2, then the Gram-Schmidt + // orthonormalization produces vectors u0, u1, and u2 as follows, + // + // u0 = v0/|v0| + // u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0| + // u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1| + // + // where |A| indicates length of vector A and A*B indicates dot + // product of vectors A and B. + + // compute u0 + akVector[0].unitize(); + + // compute u1 + float fDot0 = akVector[0].dot(akVector[1]); + akVector[1] -= akVector[0] * fDot0; + akVector[1].unitize(); + + // compute u2 + float fDot1 = akVector[1].dot(akVector[2]); + fDot0 = akVector[0].dot(akVector[2]); + akVector[2] -= akVector[0] * fDot0 + akVector[1] * fDot1; + akVector[2].unitize(); +} + +//---------------------------------------------------------------------------- +void Vector3::generateOrthonormalBasis (Vector3& rkU, Vector3& rkV, + Vector3& rkW, bool bUnitLengthW) { + if ( !bUnitLengthW ) + rkW.unitize(); + + if ( G3D::abs(rkW.x) >= G3D::abs(rkW.y) + && G3D::abs(rkW.x) >= G3D::abs(rkW.z) ) { + rkU.x = -rkW.y; + rkU.y = + rkW.x; + rkU.z = 0.0; + } else { + rkU.x = 0.0; + rkU.y = + rkW.z; + rkU.z = -rkW.y; + } + + rkU.unitize(); + rkV = rkW.cross(rkU); +} + +//---------------------------------------------------------------------------- + +std::string Vector3::toString() const { + return G3D::format("(%g, %g, %g)", x, y, z); +} + + +//---------------------------------------------------------------------------- + +Matrix3 Vector3::cross() const { + return Matrix3( 0, -z, y, + z, 0, -x, + -y, x, 0); +} + + +//---------------------------------------------------------------------------- +// 2-char swizzles + +Vector2 Vector3::xx() const { return Vector2 (x, x); } +Vector2 Vector3::yx() const { return Vector2 (y, x); } +Vector2 Vector3::zx() const { return Vector2 (z, x); } +Vector2 Vector3::xy() const { return Vector2 (x, y); } +Vector2 Vector3::yy() const { return Vector2 (y, y); } +Vector2 Vector3::zy() const { return Vector2 (z, y); } +Vector2 Vector3::xz() const { return Vector2 (x, z); } +Vector2 Vector3::yz() const { return Vector2 (y, z); } +Vector2 Vector3::zz() const { return Vector2 (z, z); } + +// 3-char swizzles + +Vector3 Vector3::xxx() const { return Vector3 (x, x, x); } +Vector3 Vector3::yxx() const { return Vector3 (y, x, x); } +Vector3 Vector3::zxx() const { return Vector3 (z, x, x); } +Vector3 Vector3::xyx() const { return Vector3 (x, y, x); } +Vector3 Vector3::yyx() const { return Vector3 (y, y, x); } +Vector3 Vector3::zyx() const { return Vector3 (z, y, x); } +Vector3 Vector3::xzx() const { return Vector3 (x, z, x); } +Vector3 Vector3::yzx() const { return Vector3 (y, z, x); } +Vector3 Vector3::zzx() const { return Vector3 (z, z, x); } +Vector3 Vector3::xxy() const { return Vector3 (x, x, y); } +Vector3 Vector3::yxy() const { return Vector3 (y, x, y); } +Vector3 Vector3::zxy() const { return Vector3 (z, x, y); } +Vector3 Vector3::xyy() const { return Vector3 (x, y, y); } +Vector3 Vector3::yyy() const { return Vector3 (y, y, y); } +Vector3 Vector3::zyy() const { return Vector3 (z, y, y); } +Vector3 Vector3::xzy() const { return Vector3 (x, z, y); } +Vector3 Vector3::yzy() const { return Vector3 (y, z, y); } +Vector3 Vector3::zzy() const { return Vector3 (z, z, y); } +Vector3 Vector3::xxz() const { return Vector3 (x, x, z); } +Vector3 Vector3::yxz() const { return Vector3 (y, x, z); } +Vector3 Vector3::zxz() const { return Vector3 (z, x, z); } +Vector3 Vector3::xyz() const { return Vector3 (x, y, z); } +Vector3 Vector3::yyz() const { return Vector3 (y, y, z); } +Vector3 Vector3::zyz() const { return Vector3 (z, y, z); } +Vector3 Vector3::xzz() const { return Vector3 (x, z, z); } +Vector3 Vector3::yzz() const { return Vector3 (y, z, z); } +Vector3 Vector3::zzz() const { return Vector3 (z, z, z); } + +// 4-char swizzles + +Vector4 Vector3::xxxx() const { return Vector4 (x, x, x, x); } +Vector4 Vector3::yxxx() const { return Vector4 (y, x, x, x); } +Vector4 Vector3::zxxx() const { return Vector4 (z, x, x, x); } +Vector4 Vector3::xyxx() const { return Vector4 (x, y, x, x); } +Vector4 Vector3::yyxx() const { return Vector4 (y, y, x, x); } +Vector4 Vector3::zyxx() const { return Vector4 (z, y, x, x); } +Vector4 Vector3::xzxx() const { return Vector4 (x, z, x, x); } +Vector4 Vector3::yzxx() const { return Vector4 (y, z, x, x); } +Vector4 Vector3::zzxx() const { return Vector4 (z, z, x, x); } +Vector4 Vector3::xxyx() const { return Vector4 (x, x, y, x); } +Vector4 Vector3::yxyx() const { return Vector4 (y, x, y, x); } +Vector4 Vector3::zxyx() const { return Vector4 (z, x, y, x); } +Vector4 Vector3::xyyx() const { return Vector4 (x, y, y, x); } +Vector4 Vector3::yyyx() const { return Vector4 (y, y, y, x); } +Vector4 Vector3::zyyx() const { return Vector4 (z, y, y, x); } +Vector4 Vector3::xzyx() const { return Vector4 (x, z, y, x); } +Vector4 Vector3::yzyx() const { return Vector4 (y, z, y, x); } +Vector4 Vector3::zzyx() const { return Vector4 (z, z, y, x); } +Vector4 Vector3::xxzx() const { return Vector4 (x, x, z, x); } +Vector4 Vector3::yxzx() const { return Vector4 (y, x, z, x); } +Vector4 Vector3::zxzx() const { return Vector4 (z, x, z, x); } +Vector4 Vector3::xyzx() const { return Vector4 (x, y, z, x); } +Vector4 Vector3::yyzx() const { return Vector4 (y, y, z, x); } +Vector4 Vector3::zyzx() const { return Vector4 (z, y, z, x); } +Vector4 Vector3::xzzx() const { return Vector4 (x, z, z, x); } +Vector4 Vector3::yzzx() const { return Vector4 (y, z, z, x); } +Vector4 Vector3::zzzx() const { return Vector4 (z, z, z, x); } +Vector4 Vector3::xxxy() const { return Vector4 (x, x, x, y); } +Vector4 Vector3::yxxy() const { return Vector4 (y, x, x, y); } +Vector4 Vector3::zxxy() const { return Vector4 (z, x, x, y); } +Vector4 Vector3::xyxy() const { return Vector4 (x, y, x, y); } +Vector4 Vector3::yyxy() const { return Vector4 (y, y, x, y); } +Vector4 Vector3::zyxy() const { return Vector4 (z, y, x, y); } +Vector4 Vector3::xzxy() const { return Vector4 (x, z, x, y); } +Vector4 Vector3::yzxy() const { return Vector4 (y, z, x, y); } +Vector4 Vector3::zzxy() const { return Vector4 (z, z, x, y); } +Vector4 Vector3::xxyy() const { return Vector4 (x, x, y, y); } +Vector4 Vector3::yxyy() const { return Vector4 (y, x, y, y); } +Vector4 Vector3::zxyy() const { return Vector4 (z, x, y, y); } +Vector4 Vector3::xyyy() const { return Vector4 (x, y, y, y); } +Vector4 Vector3::yyyy() const { return Vector4 (y, y, y, y); } +Vector4 Vector3::zyyy() const { return Vector4 (z, y, y, y); } +Vector4 Vector3::xzyy() const { return Vector4 (x, z, y, y); } +Vector4 Vector3::yzyy() const { return Vector4 (y, z, y, y); } +Vector4 Vector3::zzyy() const { return Vector4 (z, z, y, y); } +Vector4 Vector3::xxzy() const { return Vector4 (x, x, z, y); } +Vector4 Vector3::yxzy() const { return Vector4 (y, x, z, y); } +Vector4 Vector3::zxzy() const { return Vector4 (z, x, z, y); } +Vector4 Vector3::xyzy() const { return Vector4 (x, y, z, y); } +Vector4 Vector3::yyzy() const { return Vector4 (y, y, z, y); } +Vector4 Vector3::zyzy() const { return Vector4 (z, y, z, y); } +Vector4 Vector3::xzzy() const { return Vector4 (x, z, z, y); } +Vector4 Vector3::yzzy() const { return Vector4 (y, z, z, y); } +Vector4 Vector3::zzzy() const { return Vector4 (z, z, z, y); } +Vector4 Vector3::xxxz() const { return Vector4 (x, x, x, z); } +Vector4 Vector3::yxxz() const { return Vector4 (y, x, x, z); } +Vector4 Vector3::zxxz() const { return Vector4 (z, x, x, z); } +Vector4 Vector3::xyxz() const { return Vector4 (x, y, x, z); } +Vector4 Vector3::yyxz() const { return Vector4 (y, y, x, z); } +Vector4 Vector3::zyxz() const { return Vector4 (z, y, x, z); } +Vector4 Vector3::xzxz() const { return Vector4 (x, z, x, z); } +Vector4 Vector3::yzxz() const { return Vector4 (y, z, x, z); } +Vector4 Vector3::zzxz() const { return Vector4 (z, z, x, z); } +Vector4 Vector3::xxyz() const { return Vector4 (x, x, y, z); } +Vector4 Vector3::yxyz() const { return Vector4 (y, x, y, z); } +Vector4 Vector3::zxyz() const { return Vector4 (z, x, y, z); } +Vector4 Vector3::xyyz() const { return Vector4 (x, y, y, z); } +Vector4 Vector3::yyyz() const { return Vector4 (y, y, y, z); } +Vector4 Vector3::zyyz() const { return Vector4 (z, y, y, z); } +Vector4 Vector3::xzyz() const { return Vector4 (x, z, y, z); } +Vector4 Vector3::yzyz() const { return Vector4 (y, z, y, z); } +Vector4 Vector3::zzyz() const { return Vector4 (z, z, y, z); } +Vector4 Vector3::xxzz() const { return Vector4 (x, x, z, z); } +Vector4 Vector3::yxzz() const { return Vector4 (y, x, z, z); } +Vector4 Vector3::zxzz() const { return Vector4 (z, x, z, z); } +Vector4 Vector3::xyzz() const { return Vector4 (x, y, z, z); } +Vector4 Vector3::yyzz() const { return Vector4 (y, y, z, z); } +Vector4 Vector3::zyzz() const { return Vector4 (z, y, z, z); } +Vector4 Vector3::xzzz() const { return Vector4 (x, z, z, z); } +Vector4 Vector3::yzzz() const { return Vector4 (y, z, z, z); } +Vector4 Vector3::zzzz() const { return Vector4 (z, z, z, z); } + + + + + + +} // namespace diff --git a/dep/src/g3dlite/Vector4.cpp b/dep/src/g3dlite/Vector4.cpp new file mode 100644 index 000000000..bfea20202 --- /dev/null +++ b/dep/src/g3dlite/Vector4.cpp @@ -0,0 +1,438 @@ +/** + @file Vector4.cpp + + @maintainer Morgan McGuire, matrix@graphics3d.com + + @created 2001-07-09 + @edited 2003-09-29 + */ + +#include +#include +#include "G3D/Vector4.h" +//#include "G3D/Color4.h" +#include "G3D/g3dmath.h" +#include "G3D/format.h" +#include "G3D/stringutils.h" + +namespace G3D { + +unsigned int Vector4::hashCode() const { + unsigned int xhash = (*(int*)(void*)(&x)); + unsigned int yhash = (*(int*)(void*)(&y)); + unsigned int zhash = (*(int*)(void*)(&z)); + unsigned int whash = (*(int*)(void*)(&w)); + + return xhash + (yhash * 37) + (zhash * 101) + (whash * 241); +} + +#if 0 +Vector4::Vector4(const class Color4& c) { + x = c.r; + y = c.g; + z = c.b; + w = c.a; +} +#endif + + +Vector4::Vector4(const Vector2& v1, const Vector2& v2) { + x = v1.x; + y = v1.y; + z = v2.x; + w = v2.y; +} + + +Vector4::Vector4(const Vector2& v1, float fz, float fw) { + x = v1.x; + y = v1.y; + z = fz; + w = fw; +} + +//---------------------------------------------------------------------------- + +Vector4 Vector4::operator/ (float fScalar) const { + Vector4 kQuot; + + if ( fScalar != 0.0 ) { + float fInvScalar = 1.0f / fScalar; + kQuot.x = fInvScalar * x; + kQuot.y = fInvScalar * y; + kQuot.z = fInvScalar * z; + kQuot.w = fInvScalar * w; + return kQuot; + } else { + return Vector4::inf(); + } +} + +//---------------------------------------------------------------------------- +Vector4& Vector4::operator/= (float fScalar) { + if (fScalar != 0.0f) { + float fInvScalar = 1.0f / fScalar; + x *= fInvScalar; + y *= fInvScalar; + z *= fInvScalar; + w *= fInvScalar; + } else { + *this = Vector4::inf(); + } + + return *this; +} + + +//---------------------------------------------------------------------------- + +std::string Vector4::toString() const { + return G3D::format("(%g, %g, %g, %g)", x, y, z, w); +} +// 2-char swizzles + +Vector2 Vector4::xx() const { return Vector2 (x, x); } +Vector2 Vector4::yx() const { return Vector2 (y, x); } +Vector2 Vector4::zx() const { return Vector2 (z, x); } +Vector2 Vector4::wx() const { return Vector2 (w, x); } +Vector2 Vector4::xy() const { return Vector2 (x, y); } +Vector2 Vector4::yy() const { return Vector2 (y, y); } +Vector2 Vector4::zy() const { return Vector2 (z, y); } +Vector2 Vector4::wy() const { return Vector2 (w, y); } +Vector2 Vector4::xz() const { return Vector2 (x, z); } +Vector2 Vector4::yz() const { return Vector2 (y, z); } +Vector2 Vector4::zz() const { return Vector2 (z, z); } +Vector2 Vector4::wz() const { return Vector2 (w, z); } +Vector2 Vector4::xw() const { return Vector2 (x, w); } +Vector2 Vector4::yw() const { return Vector2 (y, w); } +Vector2 Vector4::zw() const { return Vector2 (z, w); } +Vector2 Vector4::ww() const { return Vector2 (w, w); } + +// 3-char swizzles + +Vector3 Vector4::xxx() const { return Vector3 (x, x, x); } +Vector3 Vector4::yxx() const { return Vector3 (y, x, x); } +Vector3 Vector4::zxx() const { return Vector3 (z, x, x); } +Vector3 Vector4::wxx() const { return Vector3 (w, x, x); } +Vector3 Vector4::xyx() const { return Vector3 (x, y, x); } +Vector3 Vector4::yyx() const { return Vector3 (y, y, x); } +Vector3 Vector4::zyx() const { return Vector3 (z, y, x); } +Vector3 Vector4::wyx() const { return Vector3 (w, y, x); } +Vector3 Vector4::xzx() const { return Vector3 (x, z, x); } +Vector3 Vector4::yzx() const { return Vector3 (y, z, x); } +Vector3 Vector4::zzx() const { return Vector3 (z, z, x); } +Vector3 Vector4::wzx() const { return Vector3 (w, z, x); } +Vector3 Vector4::xwx() const { return Vector3 (x, w, x); } +Vector3 Vector4::ywx() const { return Vector3 (y, w, x); } +Vector3 Vector4::zwx() const { return Vector3 (z, w, x); } +Vector3 Vector4::wwx() const { return Vector3 (w, w, x); } +Vector3 Vector4::xxy() const { return Vector3 (x, x, y); } +Vector3 Vector4::yxy() const { return Vector3 (y, x, y); } +Vector3 Vector4::zxy() const { return Vector3 (z, x, y); } +Vector3 Vector4::wxy() const { return Vector3 (w, x, y); } +Vector3 Vector4::xyy() const { return Vector3 (x, y, y); } +Vector3 Vector4::yyy() const { return Vector3 (y, y, y); } +Vector3 Vector4::zyy() const { return Vector3 (z, y, y); } +Vector3 Vector4::wyy() const { return Vector3 (w, y, y); } +Vector3 Vector4::xzy() const { return Vector3 (x, z, y); } +Vector3 Vector4::yzy() const { return Vector3 (y, z, y); } +Vector3 Vector4::zzy() const { return Vector3 (z, z, y); } +Vector3 Vector4::wzy() const { return Vector3 (w, z, y); } +Vector3 Vector4::xwy() const { return Vector3 (x, w, y); } +Vector3 Vector4::ywy() const { return Vector3 (y, w, y); } +Vector3 Vector4::zwy() const { return Vector3 (z, w, y); } +Vector3 Vector4::wwy() const { return Vector3 (w, w, y); } +Vector3 Vector4::xxz() const { return Vector3 (x, x, z); } +Vector3 Vector4::yxz() const { return Vector3 (y, x, z); } +Vector3 Vector4::zxz() const { return Vector3 (z, x, z); } +Vector3 Vector4::wxz() const { return Vector3 (w, x, z); } +Vector3 Vector4::xyz() const { return Vector3 (x, y, z); } +Vector3 Vector4::yyz() const { return Vector3 (y, y, z); } +Vector3 Vector4::zyz() const { return Vector3 (z, y, z); } +Vector3 Vector4::wyz() const { return Vector3 (w, y, z); } +Vector3 Vector4::xzz() const { return Vector3 (x, z, z); } +Vector3 Vector4::yzz() const { return Vector3 (y, z, z); } +Vector3 Vector4::zzz() const { return Vector3 (z, z, z); } +Vector3 Vector4::wzz() const { return Vector3 (w, z, z); } +Vector3 Vector4::xwz() const { return Vector3 (x, w, z); } +Vector3 Vector4::ywz() const { return Vector3 (y, w, z); } +Vector3 Vector4::zwz() const { return Vector3 (z, w, z); } +Vector3 Vector4::wwz() const { return Vector3 (w, w, z); } +Vector3 Vector4::xxw() const { return Vector3 (x, x, w); } +Vector3 Vector4::yxw() const { return Vector3 (y, x, w); } +Vector3 Vector4::zxw() const { return Vector3 (z, x, w); } +Vector3 Vector4::wxw() const { return Vector3 (w, x, w); } +Vector3 Vector4::xyw() const { return Vector3 (x, y, w); } +Vector3 Vector4::yyw() const { return Vector3 (y, y, w); } +Vector3 Vector4::zyw() const { return Vector3 (z, y, w); } +Vector3 Vector4::wyw() const { return Vector3 (w, y, w); } +Vector3 Vector4::xzw() const { return Vector3 (x, z, w); } +Vector3 Vector4::yzw() const { return Vector3 (y, z, w); } +Vector3 Vector4::zzw() const { return Vector3 (z, z, w); } +Vector3 Vector4::wzw() const { return Vector3 (w, z, w); } +Vector3 Vector4::xww() const { return Vector3 (x, w, w); } +Vector3 Vector4::yww() const { return Vector3 (y, w, w); } +Vector3 Vector4::zww() const { return Vector3 (z, w, w); } +Vector3 Vector4::www() const { return Vector3 (w, w, w); } + +// 4-char swizzles + +Vector4 Vector4::xxxx() const { return Vector4 (x, x, x, x); } +Vector4 Vector4::yxxx() const { return Vector4 (y, x, x, x); } +Vector4 Vector4::zxxx() const { return Vector4 (z, x, x, x); } +Vector4 Vector4::wxxx() const { return Vector4 (w, x, x, x); } +Vector4 Vector4::xyxx() const { return Vector4 (x, y, x, x); } +Vector4 Vector4::yyxx() const { return Vector4 (y, y, x, x); } +Vector4 Vector4::zyxx() const { return Vector4 (z, y, x, x); } +Vector4 Vector4::wyxx() const { return Vector4 (w, y, x, x); } +Vector4 Vector4::xzxx() const { return Vector4 (x, z, x, x); } +Vector4 Vector4::yzxx() const { return Vector4 (y, z, x, x); } +Vector4 Vector4::zzxx() const { return Vector4 (z, z, x, x); } +Vector4 Vector4::wzxx() const { return Vector4 (w, z, x, x); } +Vector4 Vector4::xwxx() const { return Vector4 (x, w, x, x); } +Vector4 Vector4::ywxx() const { return Vector4 (y, w, x, x); } +Vector4 Vector4::zwxx() const { return Vector4 (z, w, x, x); } +Vector4 Vector4::wwxx() const { return Vector4 (w, w, x, x); } +Vector4 Vector4::xxyx() const { return Vector4 (x, x, y, x); } +Vector4 Vector4::yxyx() const { return Vector4 (y, x, y, x); } +Vector4 Vector4::zxyx() const { return Vector4 (z, x, y, x); } +Vector4 Vector4::wxyx() const { return Vector4 (w, x, y, x); } +Vector4 Vector4::xyyx() const { return Vector4 (x, y, y, x); } +Vector4 Vector4::yyyx() const { return Vector4 (y, y, y, x); } +Vector4 Vector4::zyyx() const { return Vector4 (z, y, y, x); } +Vector4 Vector4::wyyx() const { return Vector4 (w, y, y, x); } +Vector4 Vector4::xzyx() const { return Vector4 (x, z, y, x); } +Vector4 Vector4::yzyx() const { return Vector4 (y, z, y, x); } +Vector4 Vector4::zzyx() const { return Vector4 (z, z, y, x); } +Vector4 Vector4::wzyx() const { return Vector4 (w, z, y, x); } +Vector4 Vector4::xwyx() const { return Vector4 (x, w, y, x); } +Vector4 Vector4::ywyx() const { return Vector4 (y, w, y, x); } +Vector4 Vector4::zwyx() const { return Vector4 (z, w, y, x); } +Vector4 Vector4::wwyx() const { return Vector4 (w, w, y, x); } +Vector4 Vector4::xxzx() const { return Vector4 (x, x, z, x); } +Vector4 Vector4::yxzx() const { return Vector4 (y, x, z, x); } +Vector4 Vector4::zxzx() const { return Vector4 (z, x, z, x); } +Vector4 Vector4::wxzx() const { return Vector4 (w, x, z, x); } +Vector4 Vector4::xyzx() const { return Vector4 (x, y, z, x); } +Vector4 Vector4::yyzx() const { return Vector4 (y, y, z, x); } +Vector4 Vector4::zyzx() const { return Vector4 (z, y, z, x); } +Vector4 Vector4::wyzx() const { return Vector4 (w, y, z, x); } +Vector4 Vector4::xzzx() const { return Vector4 (x, z, z, x); } +Vector4 Vector4::yzzx() const { return Vector4 (y, z, z, x); } +Vector4 Vector4::zzzx() const { return Vector4 (z, z, z, x); } +Vector4 Vector4::wzzx() const { return Vector4 (w, z, z, x); } +Vector4 Vector4::xwzx() const { return Vector4 (x, w, z, x); } +Vector4 Vector4::ywzx() const { return Vector4 (y, w, z, x); } +Vector4 Vector4::zwzx() const { return Vector4 (z, w, z, x); } +Vector4 Vector4::wwzx() const { return Vector4 (w, w, z, x); } +Vector4 Vector4::xxwx() const { return Vector4 (x, x, w, x); } +Vector4 Vector4::yxwx() const { return Vector4 (y, x, w, x); } +Vector4 Vector4::zxwx() const { return Vector4 (z, x, w, x); } +Vector4 Vector4::wxwx() const { return Vector4 (w, x, w, x); } +Vector4 Vector4::xywx() const { return Vector4 (x, y, w, x); } +Vector4 Vector4::yywx() const { return Vector4 (y, y, w, x); } +Vector4 Vector4::zywx() const { return Vector4 (z, y, w, x); } +Vector4 Vector4::wywx() const { return Vector4 (w, y, w, x); } +Vector4 Vector4::xzwx() const { return Vector4 (x, z, w, x); } +Vector4 Vector4::yzwx() const { return Vector4 (y, z, w, x); } +Vector4 Vector4::zzwx() const { return Vector4 (z, z, w, x); } +Vector4 Vector4::wzwx() const { return Vector4 (w, z, w, x); } +Vector4 Vector4::xwwx() const { return Vector4 (x, w, w, x); } +Vector4 Vector4::ywwx() const { return Vector4 (y, w, w, x); } +Vector4 Vector4::zwwx() const { return Vector4 (z, w, w, x); } +Vector4 Vector4::wwwx() const { return Vector4 (w, w, w, x); } +Vector4 Vector4::xxxy() const { return Vector4 (x, x, x, y); } +Vector4 Vector4::yxxy() const { return Vector4 (y, x, x, y); } +Vector4 Vector4::zxxy() const { return Vector4 (z, x, x, y); } +Vector4 Vector4::wxxy() const { return Vector4 (w, x, x, y); } +Vector4 Vector4::xyxy() const { return Vector4 (x, y, x, y); } +Vector4 Vector4::yyxy() const { return Vector4 (y, y, x, y); } +Vector4 Vector4::zyxy() const { return Vector4 (z, y, x, y); } +Vector4 Vector4::wyxy() const { return Vector4 (w, y, x, y); } +Vector4 Vector4::xzxy() const { return Vector4 (x, z, x, y); } +Vector4 Vector4::yzxy() const { return Vector4 (y, z, x, y); } +Vector4 Vector4::zzxy() const { return Vector4 (z, z, x, y); } +Vector4 Vector4::wzxy() const { return Vector4 (w, z, x, y); } +Vector4 Vector4::xwxy() const { return Vector4 (x, w, x, y); } +Vector4 Vector4::ywxy() const { return Vector4 (y, w, x, y); } +Vector4 Vector4::zwxy() const { return Vector4 (z, w, x, y); } +Vector4 Vector4::wwxy() const { return Vector4 (w, w, x, y); } +Vector4 Vector4::xxyy() const { return Vector4 (x, x, y, y); } +Vector4 Vector4::yxyy() const { return Vector4 (y, x, y, y); } +Vector4 Vector4::zxyy() const { return Vector4 (z, x, y, y); } +Vector4 Vector4::wxyy() const { return Vector4 (w, x, y, y); } +Vector4 Vector4::xyyy() const { return Vector4 (x, y, y, y); } +Vector4 Vector4::yyyy() const { return Vector4 (y, y, y, y); } +Vector4 Vector4::zyyy() const { return Vector4 (z, y, y, y); } +Vector4 Vector4::wyyy() const { return Vector4 (w, y, y, y); } +Vector4 Vector4::xzyy() const { return Vector4 (x, z, y, y); } +Vector4 Vector4::yzyy() const { return Vector4 (y, z, y, y); } +Vector4 Vector4::zzyy() const { return Vector4 (z, z, y, y); } +Vector4 Vector4::wzyy() const { return Vector4 (w, z, y, y); } +Vector4 Vector4::xwyy() const { return Vector4 (x, w, y, y); } +Vector4 Vector4::ywyy() const { return Vector4 (y, w, y, y); } +Vector4 Vector4::zwyy() const { return Vector4 (z, w, y, y); } +Vector4 Vector4::wwyy() const { return Vector4 (w, w, y, y); } +Vector4 Vector4::xxzy() const { return Vector4 (x, x, z, y); } +Vector4 Vector4::yxzy() const { return Vector4 (y, x, z, y); } +Vector4 Vector4::zxzy() const { return Vector4 (z, x, z, y); } +Vector4 Vector4::wxzy() const { return Vector4 (w, x, z, y); } +Vector4 Vector4::xyzy() const { return Vector4 (x, y, z, y); } +Vector4 Vector4::yyzy() const { return Vector4 (y, y, z, y); } +Vector4 Vector4::zyzy() const { return Vector4 (z, y, z, y); } +Vector4 Vector4::wyzy() const { return Vector4 (w, y, z, y); } +Vector4 Vector4::xzzy() const { return Vector4 (x, z, z, y); } +Vector4 Vector4::yzzy() const { return Vector4 (y, z, z, y); } +Vector4 Vector4::zzzy() const { return Vector4 (z, z, z, y); } +Vector4 Vector4::wzzy() const { return Vector4 (w, z, z, y); } +Vector4 Vector4::xwzy() const { return Vector4 (x, w, z, y); } +Vector4 Vector4::ywzy() const { return Vector4 (y, w, z, y); } +Vector4 Vector4::zwzy() const { return Vector4 (z, w, z, y); } +Vector4 Vector4::wwzy() const { return Vector4 (w, w, z, y); } +Vector4 Vector4::xxwy() const { return Vector4 (x, x, w, y); } +Vector4 Vector4::yxwy() const { return Vector4 (y, x, w, y); } +Vector4 Vector4::zxwy() const { return Vector4 (z, x, w, y); } +Vector4 Vector4::wxwy() const { return Vector4 (w, x, w, y); } +Vector4 Vector4::xywy() const { return Vector4 (x, y, w, y); } +Vector4 Vector4::yywy() const { return Vector4 (y, y, w, y); } +Vector4 Vector4::zywy() const { return Vector4 (z, y, w, y); } +Vector4 Vector4::wywy() const { return Vector4 (w, y, w, y); } +Vector4 Vector4::xzwy() const { return Vector4 (x, z, w, y); } +Vector4 Vector4::yzwy() const { return Vector4 (y, z, w, y); } +Vector4 Vector4::zzwy() const { return Vector4 (z, z, w, y); } +Vector4 Vector4::wzwy() const { return Vector4 (w, z, w, y); } +Vector4 Vector4::xwwy() const { return Vector4 (x, w, w, y); } +Vector4 Vector4::ywwy() const { return Vector4 (y, w, w, y); } +Vector4 Vector4::zwwy() const { return Vector4 (z, w, w, y); } +Vector4 Vector4::wwwy() const { return Vector4 (w, w, w, y); } +Vector4 Vector4::xxxz() const { return Vector4 (x, x, x, z); } +Vector4 Vector4::yxxz() const { return Vector4 (y, x, x, z); } +Vector4 Vector4::zxxz() const { return Vector4 (z, x, x, z); } +Vector4 Vector4::wxxz() const { return Vector4 (w, x, x, z); } +Vector4 Vector4::xyxz() const { return Vector4 (x, y, x, z); } +Vector4 Vector4::yyxz() const { return Vector4 (y, y, x, z); } +Vector4 Vector4::zyxz() const { return Vector4 (z, y, x, z); } +Vector4 Vector4::wyxz() const { return Vector4 (w, y, x, z); } +Vector4 Vector4::xzxz() const { return Vector4 (x, z, x, z); } +Vector4 Vector4::yzxz() const { return Vector4 (y, z, x, z); } +Vector4 Vector4::zzxz() const { return Vector4 (z, z, x, z); } +Vector4 Vector4::wzxz() const { return Vector4 (w, z, x, z); } +Vector4 Vector4::xwxz() const { return Vector4 (x, w, x, z); } +Vector4 Vector4::ywxz() const { return Vector4 (y, w, x, z); } +Vector4 Vector4::zwxz() const { return Vector4 (z, w, x, z); } +Vector4 Vector4::wwxz() const { return Vector4 (w, w, x, z); } +Vector4 Vector4::xxyz() const { return Vector4 (x, x, y, z); } +Vector4 Vector4::yxyz() const { return Vector4 (y, x, y, z); } +Vector4 Vector4::zxyz() const { return Vector4 (z, x, y, z); } +Vector4 Vector4::wxyz() const { return Vector4 (w, x, y, z); } +Vector4 Vector4::xyyz() const { return Vector4 (x, y, y, z); } +Vector4 Vector4::yyyz() const { return Vector4 (y, y, y, z); } +Vector4 Vector4::zyyz() const { return Vector4 (z, y, y, z); } +Vector4 Vector4::wyyz() const { return Vector4 (w, y, y, z); } +Vector4 Vector4::xzyz() const { return Vector4 (x, z, y, z); } +Vector4 Vector4::yzyz() const { return Vector4 (y, z, y, z); } +Vector4 Vector4::zzyz() const { return Vector4 (z, z, y, z); } +Vector4 Vector4::wzyz() const { return Vector4 (w, z, y, z); } +Vector4 Vector4::xwyz() const { return Vector4 (x, w, y, z); } +Vector4 Vector4::ywyz() const { return Vector4 (y, w, y, z); } +Vector4 Vector4::zwyz() const { return Vector4 (z, w, y, z); } +Vector4 Vector4::wwyz() const { return Vector4 (w, w, y, z); } +Vector4 Vector4::xxzz() const { return Vector4 (x, x, z, z); } +Vector4 Vector4::yxzz() const { return Vector4 (y, x, z, z); } +Vector4 Vector4::zxzz() const { return Vector4 (z, x, z, z); } +Vector4 Vector4::wxzz() const { return Vector4 (w, x, z, z); } +Vector4 Vector4::xyzz() const { return Vector4 (x, y, z, z); } +Vector4 Vector4::yyzz() const { return Vector4 (y, y, z, z); } +Vector4 Vector4::zyzz() const { return Vector4 (z, y, z, z); } +Vector4 Vector4::wyzz() const { return Vector4 (w, y, z, z); } +Vector4 Vector4::xzzz() const { return Vector4 (x, z, z, z); } +Vector4 Vector4::yzzz() const { return Vector4 (y, z, z, z); } +Vector4 Vector4::zzzz() const { return Vector4 (z, z, z, z); } +Vector4 Vector4::wzzz() const { return Vector4 (w, z, z, z); } +Vector4 Vector4::xwzz() const { return Vector4 (x, w, z, z); } +Vector4 Vector4::ywzz() const { return Vector4 (y, w, z, z); } +Vector4 Vector4::zwzz() const { return Vector4 (z, w, z, z); } +Vector4 Vector4::wwzz() const { return Vector4 (w, w, z, z); } +Vector4 Vector4::xxwz() const { return Vector4 (x, x, w, z); } +Vector4 Vector4::yxwz() const { return Vector4 (y, x, w, z); } +Vector4 Vector4::zxwz() const { return Vector4 (z, x, w, z); } +Vector4 Vector4::wxwz() const { return Vector4 (w, x, w, z); } +Vector4 Vector4::xywz() const { return Vector4 (x, y, w, z); } +Vector4 Vector4::yywz() const { return Vector4 (y, y, w, z); } +Vector4 Vector4::zywz() const { return Vector4 (z, y, w, z); } +Vector4 Vector4::wywz() const { return Vector4 (w, y, w, z); } +Vector4 Vector4::xzwz() const { return Vector4 (x, z, w, z); } +Vector4 Vector4::yzwz() const { return Vector4 (y, z, w, z); } +Vector4 Vector4::zzwz() const { return Vector4 (z, z, w, z); } +Vector4 Vector4::wzwz() const { return Vector4 (w, z, w, z); } +Vector4 Vector4::xwwz() const { return Vector4 (x, w, w, z); } +Vector4 Vector4::ywwz() const { return Vector4 (y, w, w, z); } +Vector4 Vector4::zwwz() const { return Vector4 (z, w, w, z); } +Vector4 Vector4::wwwz() const { return Vector4 (w, w, w, z); } +Vector4 Vector4::xxxw() const { return Vector4 (x, x, x, w); } +Vector4 Vector4::yxxw() const { return Vector4 (y, x, x, w); } +Vector4 Vector4::zxxw() const { return Vector4 (z, x, x, w); } +Vector4 Vector4::wxxw() const { return Vector4 (w, x, x, w); } +Vector4 Vector4::xyxw() const { return Vector4 (x, y, x, w); } +Vector4 Vector4::yyxw() const { return Vector4 (y, y, x, w); } +Vector4 Vector4::zyxw() const { return Vector4 (z, y, x, w); } +Vector4 Vector4::wyxw() const { return Vector4 (w, y, x, w); } +Vector4 Vector4::xzxw() const { return Vector4 (x, z, x, w); } +Vector4 Vector4::yzxw() const { return Vector4 (y, z, x, w); } +Vector4 Vector4::zzxw() const { return Vector4 (z, z, x, w); } +Vector4 Vector4::wzxw() const { return Vector4 (w, z, x, w); } +Vector4 Vector4::xwxw() const { return Vector4 (x, w, x, w); } +Vector4 Vector4::ywxw() const { return Vector4 (y, w, x, w); } +Vector4 Vector4::zwxw() const { return Vector4 (z, w, x, w); } +Vector4 Vector4::wwxw() const { return Vector4 (w, w, x, w); } +Vector4 Vector4::xxyw() const { return Vector4 (x, x, y, w); } +Vector4 Vector4::yxyw() const { return Vector4 (y, x, y, w); } +Vector4 Vector4::zxyw() const { return Vector4 (z, x, y, w); } +Vector4 Vector4::wxyw() const { return Vector4 (w, x, y, w); } +Vector4 Vector4::xyyw() const { return Vector4 (x, y, y, w); } +Vector4 Vector4::yyyw() const { return Vector4 (y, y, y, w); } +Vector4 Vector4::zyyw() const { return Vector4 (z, y, y, w); } +Vector4 Vector4::wyyw() const { return Vector4 (w, y, y, w); } +Vector4 Vector4::xzyw() const { return Vector4 (x, z, y, w); } +Vector4 Vector4::yzyw() const { return Vector4 (y, z, y, w); } +Vector4 Vector4::zzyw() const { return Vector4 (z, z, y, w); } +Vector4 Vector4::wzyw() const { return Vector4 (w, z, y, w); } +Vector4 Vector4::xwyw() const { return Vector4 (x, w, y, w); } +Vector4 Vector4::ywyw() const { return Vector4 (y, w, y, w); } +Vector4 Vector4::zwyw() const { return Vector4 (z, w, y, w); } +Vector4 Vector4::wwyw() const { return Vector4 (w, w, y, w); } +Vector4 Vector4::xxzw() const { return Vector4 (x, x, z, w); } +Vector4 Vector4::yxzw() const { return Vector4 (y, x, z, w); } +Vector4 Vector4::zxzw() const { return Vector4 (z, x, z, w); } +Vector4 Vector4::wxzw() const { return Vector4 (w, x, z, w); } +Vector4 Vector4::xyzw() const { return Vector4 (x, y, z, w); } +Vector4 Vector4::yyzw() const { return Vector4 (y, y, z, w); } +Vector4 Vector4::zyzw() const { return Vector4 (z, y, z, w); } +Vector4 Vector4::wyzw() const { return Vector4 (w, y, z, w); } +Vector4 Vector4::xzzw() const { return Vector4 (x, z, z, w); } +Vector4 Vector4::yzzw() const { return Vector4 (y, z, z, w); } +Vector4 Vector4::zzzw() const { return Vector4 (z, z, z, w); } +Vector4 Vector4::wzzw() const { return Vector4 (w, z, z, w); } +Vector4 Vector4::xwzw() const { return Vector4 (x, w, z, w); } +Vector4 Vector4::ywzw() const { return Vector4 (y, w, z, w); } +Vector4 Vector4::zwzw() const { return Vector4 (z, w, z, w); } +Vector4 Vector4::wwzw() const { return Vector4 (w, w, z, w); } +Vector4 Vector4::xxww() const { return Vector4 (x, x, w, w); } +Vector4 Vector4::yxww() const { return Vector4 (y, x, w, w); } +Vector4 Vector4::zxww() const { return Vector4 (z, x, w, w); } +Vector4 Vector4::wxww() const { return Vector4 (w, x, w, w); } +Vector4 Vector4::xyww() const { return Vector4 (x, y, w, w); } +Vector4 Vector4::yyww() const { return Vector4 (y, y, w, w); } +Vector4 Vector4::zyww() const { return Vector4 (z, y, w, w); } +Vector4 Vector4::wyww() const { return Vector4 (w, y, w, w); } +Vector4 Vector4::xzww() const { return Vector4 (x, z, w, w); } +Vector4 Vector4::yzww() const { return Vector4 (y, z, w, w); } +Vector4 Vector4::zzww() const { return Vector4 (z, z, w, w); } +Vector4 Vector4::wzww() const { return Vector4 (w, z, w, w); } +Vector4 Vector4::xwww() const { return Vector4 (x, w, w, w); } +Vector4 Vector4::ywww() const { return Vector4 (y, w, w, w); } +Vector4 Vector4::zwww() const { return Vector4 (z, w, w, w); } +Vector4 Vector4::wwww() const { return Vector4 (w, w, w, w); } + + +}; // namespace diff --git a/dep/src/g3dlite/format.cpp b/dep/src/g3dlite/format.cpp new file mode 100644 index 000000000..6def987c2 --- /dev/null +++ b/dep/src/g3dlite/format.cpp @@ -0,0 +1,171 @@ +/** + @file format.cpp + + @author Morgan McGuire, graphics3d.com + + @created 2000-09-09 + @edited 2006-04-30 +*/ + +#include "G3D/format.h" +#include "G3D/platform.h" +#include "G3D/System.h" + +#ifdef G3D_WIN32 + #include + #define vsnprintf _vsnprintf + #define NEWLINE "\r\n" +#else + #include + #define NEWLINE "\n" +#endif + +#ifdef _MSC_VER + // disable: "C++ exception handler used" +# pragma warning (push) +# pragma warning (disable : 4530) +#endif // _MSC_VER + +// If your platform does not have vsnprintf, you can find a +// implementation at http://www.ijs.si/software/snprintf/ + +namespace G3D { + +std::string format(const char* fmt,...) { + va_list argList; + va_start(argList,fmt); + std::string result = vformat(fmt, argList); + va_end(argList); + + return result; +} + +#if defined(G3D_WIN32) && (_MSC_VER >= 1300) +// Both MSVC6 and 7 seem to use the non-standard vsnprintf +// so we are using vscprintf to determine buffer size, however +// only MSVC7 headers include vscprintf for some reason. +std::string vformat(const char *fmt, va_list argPtr) { + // We draw the line at a 1MB string. + const int maxSize = 1000000; + + // If the string is less than 161 characters, + // allocate it on the stack because this saves + // the malloc/free time. + const int bufSize = 161; + char stackBuffer[bufSize]; + + int actualSize = _vscprintf(fmt, argPtr) + 1; + + if (actualSize > bufSize) { + + // Now use the heap. + char* heapBuffer = NULL; + + if (actualSize < maxSize) { + + heapBuffer = (char*)System::malloc(maxSize + 1); + vsnprintf(heapBuffer, maxSize, fmt, argPtr); + heapBuffer[maxSize] = '\0'; + } else { + heapBuffer = (char*)System::malloc(actualSize); + vsprintf(heapBuffer, fmt, argPtr); + } + + std::string formattedString(heapBuffer); + System::free(heapBuffer); + return formattedString; + } else { + + vsprintf(stackBuffer, fmt, argPtr); + return std::string(stackBuffer); + } +} + +#elif defined(G3D_WIN32) && (_MSC_VER < 1300) + +std::string vformat(const char *fmt, va_list argPtr) { + // We draw the line at a 1MB string. + const int maxSize = 1000000; + + // If the string is less than 161 characters, + // allocate it on the stack because this saves + // the malloc/free time. + const int bufSize = 161; + char stackBuffer[bufSize]; + + int actualWritten = vsnprintf(stackBuffer, bufSize, fmt, argPtr); + + // Not a big enough buffer, bufSize characters written + if (actualWritten == -1) { + + int heapSize = 512; + double powSize = 1.0; + char* heapBuffer = (char*)System::malloc(heapSize); + + while ((vsnprintf(heapBuffer, heapSize, fmt, argPtr) == -1) && + (heapSize < maxSize)) { + + heapSize = iCeil(heapSize * ::pow((double)2.0, powSize++)); + heapBuffer = (char*)System::realloc(heapBuffer, heapSize); + } + + heapBuffer[heapSize-1] = '\0'; + + std::string heapString(heapBuffer); + System::free(heapBuffer); + + return heapString; + } else { + + return std::string(stackBuffer); + } +} + +#else + +// glibc 2.1 has been updated to the C99 standard +std::string vformat(const char* fmt, va_list argPtr) { + // If the string is less than 161 characters, + // allocate it on the stack because this saves + // the malloc/free time. The number 161 is chosen + // to support two lines of text on an 80 character + // console (plus the null terminator). + const int bufSize = 161; + char stackBuffer[bufSize]; + + int numChars = vsnprintf(stackBuffer, bufSize, fmt, argPtr); + + if (numChars >= bufSize) { + // We didn't allocate a big enough string. + char* heapBuffer = (char*)System::malloc((numChars + 1) * sizeof(char)); + + assert(heapBuffer); + int numChars2 = vsnprintf(heapBuffer, numChars + 1, fmt, argPtr); + assert(numChars2 == numChars); + + std::string result(heapBuffer); + + System::free(heapBuffer); + + return result; + + } else { + + return std::string(stackBuffer); + + } +} + +#endif + +} // namespace + +#ifdef G3D_WIN32 +# undef vsnprintf +#endif + +#ifdef _MSC_VER +# pragma warning (pop) +#endif + +#undef NEWLINE diff --git a/dep/src/g3dlite/license.html b/dep/src/g3dlite/license.html new file mode 100644 index 000000000..9bbb2ad5f --- /dev/null +++ b/dep/src/g3dlite/license.html @@ -0,0 +1,109 @@ + + + + + + G3D: License + + + + + +
+ + + + +
+ + Contents + Functions + Classes + Topics + User Forum + CVS +
+ + +
+ + + +

License

+
+ +Introduction + +Installation
+

+Intent of License

+(This section is informal and not legally binding.)

+
+ This library is free code-- you can use it without charge and it is minimally legally encumbered. Unlike some other free libraries, we <u>do not</u> require you to release your source code or make your own program open source.

+I intend the license (below) to protect me and the other contributors from liability and allow you to use the source however you want. You can make your own closed or open-source programs, sell them, give them away, whatever.

+You have an obligation to say "this software is based in part on the work of the Independent JPEG Group" in your documentation or application help if you use the G3D::GImage class because it is based on the IJG library. The OpenGL headers and ZLib headers included may be freely distributed provided their copyright notices remain intact.

+For convenience, G3D::license is a function that returns the license string you must put in your documentation. G3D::GApp will automatically write a file (g3d-license.txt) to disk with the contents of this license unless you tell it not to.

+Most of the data resources have either entered the public domain and have been in several published papers or are data that I have explicitly received permission to distribute with G3D. The G3D fonts are actually font images, not TrueType font descriptions and may be freely distributed. As a rule of thumb, you can freely use and distribute anything you find in the data directory but may need permission to use it in a commercial product. Check the various copyright.txt files in the data directories for specific information.

+You are required by the BSD license to acknowledge G3D in your documentation. This can be as minimal as a note buried in the fine print at the end of a manual or a text file accompanying your program. I appreciate it if you acknowledged the library more publicly but you aren't required to.

+Likewise, you are encouraged but not required to submit patches to improve the library for the benefit of all. E-mail me with bugs, patches, and questions.

+-Morgan McGuire <matrix@graphics3d.com>

+


+

+License

+G3D is licensed under the BSD license, with portions controlled by the IJG license and PNG Reference Library license

+

+osi-certified-120x100.gif +
+

+This product uses software from the G3D project (http://g3d-cpp.sf.net)

+Copyright © 2000-2006, Morgan McGuire

+All rights reserved.

+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

+ Neither the name of Morgan McGuire, Williams College, Brown University, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+You must also agree to be bound by the terms of the Independent JPEG Group license for the portions of this library that are based on the work of the Independent JPEG Group, if you use those portions. Note: if you do not use the G3D::GImage class, this clause does not apply to you because the linker will strip that code from your project. The IJG-README.TXT file contains the Independent JPEG Group license. +


+Generated on Tue Jul 18 12:05:54 2006 for G3D by +doxygen + 1.4.6-NO
+Hosted by SourceForge.net Logo + + diff --git a/dep/src/sockets/Base64.cpp b/dep/src/sockets/Base64.cpp new file mode 100644 index 000000000..b8cf12371 --- /dev/null +++ b/dep/src/sockets/Base64.cpp @@ -0,0 +1,272 @@ +/** \file Base64.cpp + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Base64.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +const char *Base64::bstr = + "ABCDEFGHIJKLMNOPQ" + "RSTUVWXYZabcdefgh" + "ijklmnopqrstuvwxy" + "z0123456789+/"; + +const char Base64::rstr[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0}; + + +Base64::Base64() +{ +} + + +void Base64::encode(FILE *fil, std::string& output, bool add_crlf) +{ + size_t remain; + size_t i = 0; + size_t o = 0; + char input[4]; + + output = ""; + remain = fread(input,1,3,fil); + while (remain > 0) + { + if (add_crlf && o && o % 76 == 0) + output += "\n"; + switch (remain) + { + case 1: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) ]; + output += "=="; + break; + case 2: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ]; + output += bstr[ ((input[i + 1] << 2) & 0x3c) ]; + output += "="; + break; + default: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ]; + output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ]; + output += bstr[ (input[i + 2] & 0x3f) ]; + } + o += 4; + // + remain = fread(input,1,3,fil); + } +} + + +void Base64::encode(const std::string& str_in, std::string& str_out, bool add_crlf) +{ + encode(str_in.c_str(), str_in.size(), str_out, add_crlf); +} + + +void Base64::encode(const char* input,size_t l,std::string& output, bool add_crlf) +{ + size_t i = 0; + size_t o = 0; + + output = ""; + while (i < l) + { + size_t remain = l - i; + if (add_crlf && o && o % 76 == 0) + output += "\n"; + switch (remain) + { + case 1: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) ]; + output += "=="; + break; + case 2: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ]; + output += bstr[ ((input[i + 1] << 2) & 0x3c) ]; + output += "="; + break; + default: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ]; + output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ]; + output += bstr[ (input[i + 2] & 0x3f) ]; + } + o += 4; + i += 3; + } +} + + +void Base64::encode(const unsigned char* input,size_t l,std::string& output,bool add_crlf) +{ + size_t i = 0; + size_t o = 0; + + output = ""; + while (i < l) + { + size_t remain = l - i; + if (add_crlf && o && o % 76 == 0) + output += "\n"; + switch (remain) + { + case 1: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) ]; + output += "=="; + break; + case 2: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ]; + output += bstr[ ((input[i + 1] << 2) & 0x3c) ]; + output += "="; + break; + default: + output += bstr[ ((input[i] >> 2) & 0x3f) ]; + output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ]; + output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ]; + output += bstr[ (input[i + 2] & 0x3f) ]; + } + o += 4; + i += 3; + } +} + + +void Base64::decode(const std::string& input,std::string& output) +{ + size_t i = 0; + size_t l = input.size(); + + output = ""; + while (i < l) + { + while (i < l && (input[i] == 13 || input[i] == 10)) + i++; + if (i < l) + { + char b1 = (char)((rstr[(int)input[i]] << 2 & 0xfc) + + (rstr[(int)input[i + 1]] >> 4 & 0x03)); + output += b1; + if (input[i + 2] != '=') + { + char b2 = (char)((rstr[(int)input[i + 1]] << 4 & 0xf0) + + (rstr[(int)input[i + 2]] >> 2 & 0x0f)); + output += b2; + } + if (input[i + 3] != '=') + { + char b3 = (char)((rstr[(int)input[i + 2]] << 6 & 0xc0) + + rstr[(int)input[i + 3]]); + output += b3; + } + i += 4; + } + } +} + + +void Base64::decode(const std::string& input, unsigned char *output, size_t& sz) +{ + size_t i = 0; + size_t l = input.size(); + size_t j = 0; + + while (i < l) + { + while (i < l && (input[i] == 13 || input[i] == 10)) + i++; + if (i < l) + { + unsigned char b1 = (unsigned char)((rstr[(int)input[i]] << 2 & 0xfc) + + (rstr[(int)input[i + 1]] >> 4 & 0x03)); + if (output) + { + output[j] = b1; + } + j++; + if (input[i + 2] != '=') + { + unsigned char b2 = (unsigned char)((rstr[(int)input[i + 1]] << 4 & 0xf0) + + (rstr[(int)input[i + 2]] >> 2 & 0x0f)); + if (output) + { + output[j] = b2; + } + j++; + } + if (input[i + 3] != '=') + { + unsigned char b3 = (unsigned char)((rstr[(int)input[i + 2]] << 6 & 0xc0) + + rstr[(int)input[i + 3]]); + if (output) + { + output[j] = b3; + } + j++; + } + i += 4; + } + } + sz = j; +} + + +size_t Base64::decode_length(const std::string& str64) +{ + if (str64.empty() || str64.size() % 4) + return 0; + size_t l = 3 * (str64.size() / 4 - 1) + 1; + if (str64[str64.size() - 2] != '=') + l++; + if (str64[str64.size() - 1] != '=') + l++; + return l; +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + + diff --git a/dep/src/sockets/Exception.cpp b/dep/src/sockets/Exception.cpp new file mode 100644 index 000000000..a005669e4 --- /dev/null +++ b/dep/src/sockets/Exception.cpp @@ -0,0 +1,48 @@ +/** + ** \file Exception.cpp + ** \date 2007-09-28 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif +#include "Exception.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + + +Exception::Exception(const std::string& description) : m_description(description) +{ +} + + +const std::string Exception::ToString() const +{ + return m_description; +} + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif + diff --git a/dep/src/sockets/Ipv4Address.cpp b/dep/src/sockets/Ipv4Address.cpp new file mode 100644 index 000000000..58f25e53b --- /dev/null +++ b/dep/src/sockets/Ipv4Address.cpp @@ -0,0 +1,214 @@ +/** + ** \file Ipv4Address.cpp + ** \date 2006-09-21 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Ipv4Address.h" +#include "Utility.h" +#include "Parse.h" +#ifndef _WIN32 +#include +#endif + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + + +Ipv4Address::Ipv4Address(port_t port) : m_valid(true) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin_family = AF_INET; + m_addr.sin_port = htons( port ); +} + + +Ipv4Address::Ipv4Address(ipaddr_t a,port_t port) : m_valid(true) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin_family = AF_INET; + m_addr.sin_port = htons( port ); + memcpy(&m_addr.sin_addr, &a, sizeof(struct in_addr)); +} + + +Ipv4Address::Ipv4Address(struct in_addr& a,port_t port) : m_valid(true) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin_family = AF_INET; + m_addr.sin_port = htons( port ); + m_addr.sin_addr = a; +} + + +Ipv4Address::Ipv4Address(const std::string& host,port_t port) : m_valid(false) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin_family = AF_INET; + m_addr.sin_port = htons( port ); + { + ipaddr_t a; + if (Utility::u2ip(host, a)) + { + memcpy(&m_addr.sin_addr, &a, sizeof(struct in_addr)); + m_valid = true; + } + } +} + + +Ipv4Address::Ipv4Address(struct sockaddr_in& sa) +{ + m_addr = sa; + m_valid = sa.sin_family == AF_INET; +} + + +Ipv4Address::~Ipv4Address() +{ +} + + +Ipv4Address::operator struct sockaddr *() +{ + return (struct sockaddr *)&m_addr; +} + + +Ipv4Address::operator socklen_t() +{ + return sizeof(struct sockaddr_in); +} + + +void Ipv4Address::SetPort(port_t port) +{ + m_addr.sin_port = htons( port ); +} + + +port_t Ipv4Address::GetPort() +{ + return ntohs( m_addr.sin_port ); +} + + +bool Ipv4Address::Resolve(const std::string& hostname,struct in_addr& a) +{ + struct sockaddr_in sa; + memset(&a, 0, sizeof(a)); + if (Utility::isipv4(hostname)) + { + if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST)) + return false; + a = sa.sin_addr; + return true; + } + if (!Utility::u2ip(hostname, sa)) + return false; + a = sa.sin_addr; + return true; +} + + +bool Ipv4Address::Reverse(struct in_addr& a,std::string& name) +{ + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr = a; + return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name); +} + + +std::string Ipv4Address::Convert(bool include_port) +{ + if (include_port) + return Convert(m_addr.sin_addr) + ":" + Utility::l2string(GetPort()); + return Convert(m_addr.sin_addr); +} + + +std::string Ipv4Address::Convert(struct in_addr& a) +{ + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr = a; + std::string name; + Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST); + return name; +} + + +void Ipv4Address::SetAddress(struct sockaddr *sa) +{ + memcpy(&m_addr, sa, sizeof(struct sockaddr_in)); +} + + +int Ipv4Address::GetFamily() +{ + return m_addr.sin_family; +} + + +bool Ipv4Address::IsValid() +{ + return m_valid; +} + + +bool Ipv4Address::operator==(SocketAddress& a) +{ + if (a.GetFamily() != GetFamily()) + return false; + if ((socklen_t)a != sizeof(m_addr)) + return false; + struct sockaddr *sa = a; + struct sockaddr_in *p = (struct sockaddr_in *)sa; + if (p -> sin_port != m_addr.sin_port) + return false; + if (memcmp(&p -> sin_addr, &m_addr.sin_addr, 4)) + return false; + return true; +} + + +std::auto_ptr Ipv4Address::GetCopy() +{ + return std::auto_ptr(new Ipv4Address(m_addr)); +} + + +std::string Ipv4Address::Reverse() +{ + std::string tmp; + Reverse(m_addr.sin_addr, tmp); + return tmp; +} + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif + diff --git a/dep/src/sockets/Ipv6Address.cpp b/dep/src/sockets/Ipv6Address.cpp new file mode 100644 index 000000000..2e0f1e9ac --- /dev/null +++ b/dep/src/sockets/Ipv6Address.cpp @@ -0,0 +1,270 @@ +/** + ** \file Ipv6Address.cpp + ** \date 2006-09-21 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2007 Anders Hedstrom + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Ipv6Address.h" +#ifdef ENABLE_IPV6 + +#include "Utility.h" +#include "Parse.h" +#ifndef _WIN32 +#include +#endif +#ifdef IPPROTO_IPV6 + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +Ipv6Address::Ipv6Address(port_t port) : m_valid(true) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin6_family = AF_INET6; + m_addr.sin6_port = htons( port ); +} + + +Ipv6Address::Ipv6Address(struct in6_addr& a,port_t port) : m_valid(true) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin6_family = AF_INET6; + m_addr.sin6_port = htons( port ); + m_addr.sin6_addr = a; +} + + +Ipv6Address::Ipv6Address(const std::string& host,port_t port) : m_valid(false) +{ + memset(&m_addr, 0, sizeof(m_addr)); + m_addr.sin6_family = AF_INET6; + m_addr.sin6_port = htons( port ); + { + struct in6_addr a; + if (Utility::u2ip(host, a)) + { + m_addr.sin6_addr = a; + m_valid = true; + } + } +} + + +Ipv6Address::Ipv6Address(struct sockaddr_in6& sa) +{ + m_addr = sa; + m_valid = sa.sin6_family == AF_INET6; +} + + +Ipv6Address::~Ipv6Address() +{ +} + + +Ipv6Address::operator struct sockaddr *() +{ + return (struct sockaddr *)&m_addr; +} + + +Ipv6Address::operator socklen_t() +{ + return sizeof(struct sockaddr_in6); +} + + +void Ipv6Address::SetPort(port_t port) +{ + m_addr.sin6_port = htons( port ); +} + + +port_t Ipv6Address::GetPort() +{ + return ntohs( m_addr.sin6_port ); +} + + +bool Ipv6Address::Resolve(const std::string& hostname,struct in6_addr& a) +{ + struct sockaddr_in6 sa; + memset(&a, 0, sizeof(a)); + if (Utility::isipv6(hostname)) + { + if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST)) + return false; + a = sa.sin6_addr; + return true; + } + if (!Utility::u2ip(hostname, sa)) + return false; + a = sa.sin6_addr; + return true; +} + + +bool Ipv6Address::Reverse(struct in6_addr& a,std::string& name) +{ + struct sockaddr_in6 sa; + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET6; + sa.sin6_addr = a; + return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name); +} + + +std::string Ipv6Address::Convert(bool include_port) +{ + if (include_port) + return Convert(m_addr.sin6_addr) + ":" + Utility::l2string(GetPort()); + return Convert(m_addr.sin6_addr); +} + + +std::string Ipv6Address::Convert(struct in6_addr& a,bool mixed) +{ + char slask[100]; // l2ip temporary + *slask = 0; + unsigned int prev = 0; + bool skipped = false; + bool ok_to_skip = true; + if (mixed) + { + unsigned short x; + unsigned short addr16[8]; + memcpy(addr16, &a, sizeof(addr16)); + for (size_t i = 0; i < 6; i++) + { + x = ntohs(addr16[i]); + if (*slask && (x || !ok_to_skip || prev)) + strcat(slask,":"); + if (x || !ok_to_skip) + { + sprintf(slask + strlen(slask),"%x", x); + if (x && skipped) + ok_to_skip = false; + } + else + { + skipped = true; + } + prev = x; + } + x = ntohs(addr16[6]); + sprintf(slask + strlen(slask),":%u.%u",x / 256,x & 255); + x = ntohs(addr16[7]); + sprintf(slask + strlen(slask),".%u.%u",x / 256,x & 255); + } + else + { + struct sockaddr_in6 sa; + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET6; + sa.sin6_addr = a; + std::string name; + Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST); + return name; + } + return slask; +} + + +void Ipv6Address::SetAddress(struct sockaddr *sa) +{ + memcpy(&m_addr, sa, sizeof(struct sockaddr_in6)); +} + + +int Ipv6Address::GetFamily() +{ + return m_addr.sin6_family; +} + + +void Ipv6Address::SetFlowinfo(uint32_t x) +{ + m_addr.sin6_flowinfo = x; +} + + +uint32_t Ipv6Address::GetFlowinfo() +{ + return m_addr.sin6_flowinfo; +} + + +#ifndef _WIN32 +void Ipv6Address::SetScopeId(uint32_t x) +{ + m_addr.sin6_scope_id = x; +} + + +uint32_t Ipv6Address::GetScopeId() +{ + return m_addr.sin6_scope_id; +} +#endif + + +bool Ipv6Address::IsValid() +{ + return m_valid; +} + + +bool Ipv6Address::operator==(SocketAddress& a) +{ + if (a.GetFamily() != GetFamily()) + return false; + if ((socklen_t)a != sizeof(m_addr)) + return false; + struct sockaddr *sa = a; + struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa; + if (p -> sin6_port != m_addr.sin6_port) + return false; + if (memcmp(&p -> sin6_addr, &m_addr.sin6_addr, sizeof(struct in6_addr))) + return false; + return true; +} + + +std::auto_ptr Ipv6Address::GetCopy() +{ + return std::auto_ptr(new Ipv6Address(m_addr)); +} + + +std::string Ipv6Address::Reverse() +{ + std::string tmp; + Reverse(m_addr.sin6_addr, tmp); + return tmp; +} + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif +#endif // IPPROTO_IPV6 +#endif // ENABLE_IPV6 + diff --git a/dep/src/sockets/Lock.cpp b/dep/src/sockets/Lock.cpp new file mode 100644 index 000000000..3f7902e23 --- /dev/null +++ b/dep/src/sockets/Lock.cpp @@ -0,0 +1,55 @@ +/** \file Lock.cpp + ** \date 2005-08-22 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2005,2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Mutex.h" +#include "Lock.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +Lock::Lock(Mutex& m) : m_mutex(m) +{ + m_mutex.Lock(); +} + + +Lock::~Lock() +{ + m_mutex.Unlock(); +} + + + + +#ifdef SOCKETS_NAMESPACE +} +#endif + diff --git a/dep/src/sockets/Makefile.am b/dep/src/sockets/Makefile.am new file mode 100644 index 000000000..f8abd3177 --- /dev/null +++ b/dep/src/sockets/Makefile.am @@ -0,0 +1,47 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../../include/sockets + +## Build MaNGOS shared library and its parts as convenience library. +# All libraries will be convenience libraries. Might be changed to shared +# later. +noinst_LIBRARIES = libmangossockets.a + +libmangossockets_a_SOURCES = \ + Base64.cpp \ + Exception.cpp \ + Ipv4Address.cpp \ + Ipv6Address.cpp \ + Lock.cpp \ + Mutex.cpp \ + Parse.cpp \ + ResolvServer.cpp \ + ResolvSocket.cpp \ + Socket.cpp \ + SocketHandler.cpp \ + StdoutLog.cpp \ + StreamSocket.cpp \ + TcpSocket.cpp \ + Thread.cpp \ + UdpSocket.cpp \ + Utility.cpp \ + socket_include.cpp diff --git a/dep/src/sockets/Mutex.cpp b/dep/src/sockets/Mutex.cpp new file mode 100644 index 000000000..f7a03c7d9 --- /dev/null +++ b/dep/src/sockets/Mutex.cpp @@ -0,0 +1,81 @@ +/** \file Mutex.cpp + ** \date 2004-10-30 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Mutex.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +Mutex::Mutex() +{ +#ifdef _WIN32 + m_mutex = ::CreateMutex(NULL, FALSE, NULL); +#else + pthread_mutex_init(&m_mutex, NULL); +#endif +} + + +Mutex::~Mutex() +{ +#ifdef _WIN32 + ::CloseHandle(m_mutex); +#else + pthread_mutex_destroy(&m_mutex); +#endif +} + + +void Mutex::Lock() +{ +#ifdef _WIN32 + /*DWORD d =*/ WaitForSingleObject(m_mutex, INFINITE); + /// \todo check 'd' for result +#else + pthread_mutex_lock(&m_mutex); +#endif +} + + +void Mutex::Unlock() +{ +#ifdef _WIN32 + ::ReleaseMutex(m_mutex); +#else + pthread_mutex_unlock(&m_mutex); +#endif +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + diff --git a/dep/src/sockets/Parse.cpp b/dep/src/sockets/Parse.cpp new file mode 100644 index 000000000..58122c0c9 --- /dev/null +++ b/dep/src/sockets/Parse.cpp @@ -0,0 +1,321 @@ +/** \file Parse.cpp - parse a string + ** + ** Written: 1999-Feb-10 grymse@alhem.net + **/ + +/* +Copyright (C) 1999-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include +#include + +#include "Parse.h" + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +/* implementation of class Parse */ + +Parse::Parse() +:pa_the_str("") +,pa_splits("") +,pa_ord("") +,pa_the_ptr(0) +,pa_breakchar(0) +,pa_enable(0) +,pa_disable(0) +,pa_nospace(0) +,pa_quote(false) +{ +} + +Parse::Parse(const std::string&s) +:pa_the_str(s) +,pa_splits("") +,pa_ord("") +,pa_the_ptr(0) +,pa_breakchar(0) +,pa_enable(0) +,pa_disable(0) +,pa_nospace(0) +,pa_quote(false) +{ +} + +Parse::Parse(const std::string&s,const std::string&sp) +:pa_the_str(s) +,pa_splits(sp) +,pa_ord("") +,pa_the_ptr(0) +,pa_breakchar(0) +,pa_enable(0) +,pa_disable(0) +,pa_nospace(0) +,pa_quote(false) +{ +} + +Parse::Parse(const std::string&s,const std::string&sp,short /*nospace*/) +:pa_the_str(s) +,pa_splits(sp) +,pa_ord("") +,pa_the_ptr(0) +,pa_breakchar(0) +,pa_enable(0) +,pa_disable(0) +,pa_nospace(1) +,pa_quote(false) +{ +} + + +Parse::~Parse() +{ +} + +#define C ((pa_the_ptr l(h); + + if (l.Bind("127.0.0.1", m_port)) + { + return; + } + h.Add(&l); + + m_ready = true; + while (!m_quit && IsRunning() ) + { + h.Select(0, 500000); + } + SetRunning(false); +} + + +void ResolvServer::Quit() +{ + m_quit = true; +} + + +bool ResolvServer::Ready() +{ + return m_ready; +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // ENABLE_RESOLVER + diff --git a/dep/src/sockets/ResolvSocket.cpp b/dep/src/sockets/ResolvSocket.cpp new file mode 100644 index 000000000..2d9d31d5a --- /dev/null +++ b/dep/src/sockets/ResolvSocket.cpp @@ -0,0 +1,436 @@ +/** \file ResolvSocket.cpp + ** \date 2005-03-24 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef _WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif +#else +#include +#endif +#include "ResolvSocket.h" +#ifdef ENABLE_RESOLVER +#include "Utility.h" +#include "Parse.h" +#include "ISocketHandler.h" +#include "Lock.h" +#include "Mutex.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + +//#ifdef _DEBUG +//#define DEB(x) x +//#else +#define DEB(x) +//#endif + + +// static +ResolvSocket::cache_t ResolvSocket::m_cache; +ResolvSocket::timeout_t ResolvSocket::m_cache_to; +Mutex ResolvSocket::m_cache_mutex; + + +ResolvSocket::ResolvSocket(ISocketHandler& h) +:TcpSocket(h) +,m_bServer(false) +,m_parent(NULL) +#ifdef ENABLE_IPV6 +,m_resolve_ipv6(false) +#endif +,m_cached(false) +{ + SetLineProtocol(); +} + + +ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, const std::string& host, port_t port, bool ipv6) +:TcpSocket(h) +,m_bServer(false) +,m_parent(parent) +,m_resolv_host(host) +,m_resolv_port(port) +#ifdef ENABLE_IPV6 +,m_resolve_ipv6(ipv6) +#endif +,m_cached(false) +{ + SetLineProtocol(); +} + + +ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, ipaddr_t a) +:TcpSocket(h) +,m_bServer(false) +,m_parent(parent) +,m_resolv_port(0) +,m_resolv_address(a) +#ifdef ENABLE_IPV6 +,m_resolve_ipv6(false) +#endif +,m_cached(false) +{ + SetLineProtocol(); +} + + +#ifdef ENABLE_IPV6 +ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, in6_addr& a) +:TcpSocket(h) +,m_bServer(false) +,m_parent(parent) +,m_resolv_port(0) +,m_resolve_ipv6(true) +,m_resolv_address6(a) +,m_cached(false) +{ + SetLineProtocol(); +} +#endif + + +ResolvSocket::~ResolvSocket() +{ +} + + +void ResolvSocket::OnLine(const std::string& line) +{ + Parse pa(line, ":"); + if (m_bServer) + { + m_query = pa.getword(); + m_data = pa.getrest(); +DEB( fprintf(stderr, " *** ResolvSocket server; query=%s, data=%s\n", m_query.c_str(), m_data.c_str());) + // %! check cache + { + Lock lock(m_cache_mutex); + if (m_cache[m_query].find(m_data) != m_cache[m_query].end()) + { + if (time(NULL) - m_cache_to[m_query][m_data] < 3600) // ttl + { + std::string result = m_cache[m_query][m_data]; +DEB(fprintf(stderr, " *** Returning cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), result.c_str());) + Send("Cached\n"); + if (!result.size()) /* failed */ + { + Send("Failed\n\n"); + SetCloseAndDelete(); + return; + } + else + if (m_query == "gethostbyname") + { + Send("A: " + result + "\n\n"); + SetCloseAndDelete(); + return; + } + else +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (m_query == "gethostbyname2") + { + Send("AAAA: " + result + "\n\n"); + SetCloseAndDelete(); + return; + } + else +#endif +#endif + if (m_query == "gethostbyaddr") + { + Send("Name: " + result + "\n\n"); + SetCloseAndDelete(); + return; + } + } + } + } + if (!Detach()) // detach failed? + { + SetCloseAndDelete(); + } + return; + } + std::string key = pa.getword(); + std::string value = pa.getrest(); +DEB( fprintf(stderr, " *** ResolvSocket response; %s: %s\n", key.c_str(), value.c_str());) + + if (key == "Cached") + { + m_cached = true; + } + else + if (key == "Failed" && m_parent) + { +DEB( fprintf(stderr, " ************ Resolve failed\n");) + if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) + { + m_parent -> OnResolveFailed(m_resolv_id); + } + // update cache + if (!m_cached) + { + Lock lock(m_cache_mutex); +DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) + m_cache[m_query][m_data] = value; + m_cache_to[m_query][m_data] = time(NULL); + } + m_parent = NULL; + } + else + if (key == "Name" && !m_resolv_host.size() && m_parent) + { + if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) + { + m_parent -> OnReverseResolved(m_resolv_id, value); + } + // update cache + if (!m_cached) + { + Lock lock(m_cache_mutex); +DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) + m_cache[m_query][m_data] = value; + m_cache_to[m_query][m_data] = time(NULL); + } + m_parent = NULL; + } + else + if (key == "A" && m_parent) + { + if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) + { + ipaddr_t l; + Utility::u2ip(value, l); // ip2ipaddr_t + m_parent -> OnResolved(m_resolv_id, l, m_resolv_port); + } + // update cache + if (!m_cached) + { + Lock lock(m_cache_mutex); +DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) + m_cache[m_query][m_data] = value; + m_cache_to[m_query][m_data] = time(NULL); + } + m_parent = NULL; // always use first ip in case there are several + } +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + else + if (key == "AAAA" && m_parent) + { + if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) + { + in6_addr a; + Utility::u2ip(value, a); + m_parent -> OnResolved(m_resolv_id, a, m_resolv_port); + } + // update cache + if (!m_cached) + { + Lock lock(m_cache_mutex); +DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) + m_cache[m_query][m_data] = value; + m_cache_to[m_query][m_data] = time(NULL); + } + m_parent = NULL; + } +#endif +#endif +} + + +void ResolvSocket::OnDetached() +{ +DEB( fprintf(stderr, " *** ResolvSocket::OnDetached(); query=%s, data=%s\n", m_query.c_str(), m_data.c_str());) + if (m_query == "gethostbyname") + { + struct sockaddr_in sa; + if (Utility::u2ip(m_data, sa)) + { + std::string ip; + Utility::l2ip(sa.sin_addr, ip); + Send("A: " + ip + "\n"); + } + else + { + Send("Failed\n"); + } + Send("\n"); + } + else +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (m_query == "gethostbyname2") + { + struct sockaddr_in6 sa; + if (Utility::u2ip(m_data, sa)) + { + std::string ip; + Utility::l2ip(sa.sin6_addr, ip); + Send("AAAA: " + ip + "\n"); + } + else + { + Send("Failed\n"); + } + Send("\n"); + } + else +#endif +#endif + if (m_query == "gethostbyaddr") + { + if (Utility::isipv4( m_data )) + { + struct sockaddr_in sa; + if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST)) + { + Send("Failed: convert to sockaddr_in failed\n"); + } + else + { + std::string name; + if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name)) + { + Send("Failed: ipv4 reverse lookup of " + m_data + "\n"); + } + else + { + Send("Name: " + name + "\n"); + } + } + } + else +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (Utility::isipv6( m_data )) + { + struct sockaddr_in6 sa; + if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST)) + { + Send("Failed: convert to sockaddr_in6 failed\n"); + } + else + { + std::string name; + if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name)) + { + Send("Failed: ipv6 reverse lookup of " + m_data + "\n"); + } + else + { + Send("Name: " + name + "\n"); + } + } + } + else +#endif +#endif + { + Send("Failed: malformed address\n"); + } + Send("\n"); + } + else + { + std::string msg = "Unknown query type: " + m_query; + Handler().LogError(this, "OnDetached", 0, msg); + Send("Unknown\n\n"); + } + SetCloseAndDelete(); +} + + +void ResolvSocket::OnConnect() +{ + if (!m_resolv_host.empty()) + { +#ifdef ENABLE_IPV6 + std::string msg = (m_resolve_ipv6 ? "gethostbyname2 " : "gethostbyname ") + m_resolv_host + "\n"; + m_query = m_resolve_ipv6 ? "gethostbyname2" : "gethostbyname"; +#else + std::string msg = "gethostbyname " + m_resolv_host + "\n"; + m_query = "gethostbyname"; +#endif + m_data = m_resolv_host; + Send( msg ); + return; + } +#ifdef ENABLE_IPV6 + if (m_resolve_ipv6) + { + std::string tmp; + Utility::l2ip(m_resolv_address6, tmp); + m_query = "gethostbyaddr"; + m_data = tmp; + std::string msg = "gethostbyaddr " + tmp + "\n"; + Send( msg ); + } +#endif + std::string tmp; + Utility::l2ip(m_resolv_address, tmp); + m_query = "gethostbyaddr"; + m_data = tmp; + std::string msg = "gethostbyaddr " + tmp + "\n"; + Send( msg ); +} + + +void ResolvSocket::OnDelete() +{ + if (m_parent) + { + if (Handler().Resolving(m_parent) || Handler().Valid(m_parent)) + { + m_parent -> OnResolveFailed(m_resolv_id); + } + // update cache + if (!m_cached) + { + Lock lock(m_cache_mutex); + std::string value; +DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());) + m_cache[m_query][m_data] = value; + m_cache_to[m_query][m_data] = time(NULL); + } + m_parent = NULL; + } +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + +#endif // ENABLE_RESOLVER + diff --git a/dep/src/sockets/Socket.cpp b/dep/src/sockets/Socket.cpp new file mode 100644 index 000000000..883363eb1 --- /dev/null +++ b/dep/src/sockets/Socket.cpp @@ -0,0 +1,1898 @@ +/** \file Socket.cpp + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Socket.h" +#ifdef _WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif +#include +#else +#include +#include +#endif +#include +#include + +#include "ISocketHandler.h" +#include "Utility.h" + +#include "SocketAddress.h" +#include "SocketHandler.h" +#ifdef ENABLE_EXCEPTIONS +#include "Exception.h" +#endif +#include "Ipv4Address.h" + +//#ifdef _DEBUG +//#define DEB(x) x; fflush(stderr); +//#else +#define DEB(x) +//#endif + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +// statics +#ifdef _WIN32 +WSAInitializer Socket::m_winsock_init; +#endif + + +Socket::Socket(ISocketHandler& h) +//:m_flags(0) +:m_handler(h) +,m_socket( INVALID_SOCKET ) +,m_bDel(false) +,m_bClose(false) +,m_tCreate(time(NULL)) +,m_parent(NULL) +,m_b_disable_read(false) +,m_connected(false) +,m_b_erased_by_handler(false) +,m_tClose(0) +,m_client_remote_address(NULL) +,m_remote_address(NULL) +,m_traffic_monitor(NULL) +,m_bLost(false) +#ifdef HAVE_OPENSSL +,m_b_enable_ssl(false) +,m_b_ssl(false) +,m_b_ssl_server(false) +#endif +#ifdef ENABLE_IPV6 +,m_ipv6(false) +#endif +#ifdef ENABLE_POOL +,m_socket_type(0) +,m_bClient(false) +,m_bRetain(false) +#endif +#ifdef ENABLE_SOCKS4 +,m_bSocks4(false) +,m_socks4_host(h.GetSocks4Host()) +,m_socks4_port(h.GetSocks4Port()) +,m_socks4_userid(h.GetSocks4Userid()) +#endif +#ifdef ENABLE_DETACH +,m_detach(false) +,m_detached(false) +,m_pThread(NULL) +,m_slave_handler(NULL) +#endif +{ +} + + +Socket::~Socket() +{ + Handler().Remove(this); + if (m_socket != INVALID_SOCKET +#ifdef ENABLE_POOL + && !m_bRetain +#endif + ) + { + Close(); + } +} + + +void Socket::Init() +{ +} + + +void Socket::OnRead() +{ +} + + +void Socket::OnWrite() +{ +} + + +void Socket::OnException() +{ + // %! exception doesn't always mean something bad happened, this code should be reworked + // errno valid here? + int err = SoError(); + Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL); + SetCloseAndDelete(); +} + + +void Socket::OnDelete() +{ +} + + +void Socket::OnConnect() +{ +} + + +void Socket::OnAccept() +{ +} + + +int Socket::Close() +{ + if (m_socket == INVALID_SOCKET) // this could happen + { + Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING); + return 0; + } + int n; + if ((n = closesocket(m_socket)) == -1) + { + // failed... + Handler().LogError(this, "close", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + Handler().Set(m_socket, false, false, false); // remove from fd_set's + Handler().AddList(m_socket, LIST_CALLONCONNECT, false); +#ifdef ENABLE_DETACH + Handler().AddList(m_socket, LIST_DETACH, false); +#endif + Handler().AddList(m_socket, LIST_TIMEOUT, false); + Handler().AddList(m_socket, LIST_RETRY, false); + Handler().AddList(m_socket, LIST_CLOSE, false); + m_socket = INVALID_SOCKET; + return n; +} + + +SOCKET Socket::CreateSocket(int af,int type, const std::string& protocol) +{ + struct protoent *p = NULL; + SOCKET s; + +#ifdef ENABLE_POOL + m_socket_type = type; + m_socket_protocol = protocol; +#endif + if (!protocol.empty()) + { + p = getprotobyname( protocol.c_str() ); + if (!p) + { + Handler().LogError(this, "getprotobyname", Errno, StrError(Errno), LOG_LEVEL_FATAL); + SetCloseAndDelete(); +#ifdef ENABLE_EXCEPTIONS + throw Exception(std::string("getprotobyname() failed: ") + StrError(Errno)); +#endif + return INVALID_SOCKET; + } + } + int protno = p ? p -> p_proto : 0; + + s = socket(af, type, protno); + if (s == INVALID_SOCKET) + { + Handler().LogError(this, "socket", Errno, StrError(Errno), LOG_LEVEL_FATAL); + SetCloseAndDelete(); +#ifdef ENABLE_EXCEPTIONS + throw Exception(std::string("socket() failed: ") + StrError(Errno)); +#endif + return INVALID_SOCKET; + } + Attach(s); + OnOptions(af, type, protno, s); + Attach(INVALID_SOCKET); + return s; +} + + +void Socket::Attach(SOCKET s) +{ + m_socket = s; +} + + +SOCKET Socket::GetSocket() +{ + return m_socket; +} + + +void Socket::SetDeleteByHandler(bool x) +{ + m_bDel = x; +} + + +bool Socket::DeleteByHandler() +{ + return m_bDel; +} + + +void Socket::SetCloseAndDelete(bool x) +{ + if (x != m_bClose) + { + Handler().AddList(m_socket, LIST_CLOSE, x); + m_bClose = x; + if (x) + { + m_tClose = time(NULL); + } + } +} + + +bool Socket::CloseAndDelete() +{ + return m_bClose; +} + + +void Socket::SetRemoteAddress(SocketAddress& ad) //struct sockaddr* sa, socklen_t l) +{ + m_remote_address = ad.GetCopy(); +} + + +std::auto_ptr Socket::GetRemoteSocketAddress() +{ + return m_remote_address -> GetCopy(); +} + + +ISocketHandler& Socket::Handler() const +{ +#ifdef ENABLE_DETACH + if (IsDetached()) + return *m_slave_handler; +#endif + return m_handler; +} + + +ISocketHandler& Socket::MasterHandler() const +{ + return m_handler; +} + + +ipaddr_t Socket::GetRemoteIP4() +{ + ipaddr_t l = 0; +#ifdef ENABLE_IPV6 + if (m_ipv6) + { + Handler().LogError(this, "GetRemoteIP4", 0, "get ipv4 address for ipv6 socket", LOG_LEVEL_WARNING); + } +#endif + if (m_remote_address.get() != NULL) + { + struct sockaddr *p = *m_remote_address; + struct sockaddr_in *sa = (struct sockaddr_in *)p; + memcpy(&l, &sa -> sin_addr, sizeof(struct in_addr)); + } + return l; +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +struct in6_addr Socket::GetRemoteIP6() +{ + if (!m_ipv6) + { + Handler().LogError(this, "GetRemoteIP6", 0, "get ipv6 address for ipv4 socket", LOG_LEVEL_WARNING); + } + struct sockaddr_in6 fail; + if (m_remote_address.get() != NULL) + { + struct sockaddr *p = *m_remote_address; + memcpy(&fail, p, sizeof(struct sockaddr_in6)); + } + else + { + memset(&fail, 0, sizeof(struct sockaddr_in6)); + } + return fail.sin6_addr; +} +#endif +#endif + + +port_t Socket::GetRemotePort() +{ + if (!m_remote_address.get()) + { + return 0; + } + return m_remote_address -> GetPort(); +} + + +std::string Socket::GetRemoteAddress() +{ + if (!m_remote_address.get()) + { + return ""; + } + return m_remote_address -> Convert(false); +} + + +std::string Socket::GetRemoteHostname() +{ + if (!m_remote_address.get()) + { + return ""; + } + return m_remote_address -> Reverse(); +} + + +bool Socket::SetNonblocking(bool bNb) +{ +#ifdef _WIN32 + unsigned long l = bNb ? 1 : 0; + int n = ioctlsocket(m_socket, FIONBIO, &l); + if (n != 0) + { + Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno, ""); + return false; + } + return true; +#else + if (bNb) + { + if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1) + { + Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno, StrError(Errno), LOG_LEVEL_ERROR); + return false; + } + } + else + { + if (fcntl(m_socket, F_SETFL, 0) == -1) + { + Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno, StrError(Errno), LOG_LEVEL_ERROR); + return false; + } + } + return true; +#endif +} + + +bool Socket::SetNonblocking(bool bNb, SOCKET s) +{ +#ifdef _WIN32 + unsigned long l = bNb ? 1 : 0; + int n = ioctlsocket(s, FIONBIO, &l); + if (n != 0) + { + Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno, ""); + return false; + } + return true; +#else + if (bNb) + { + if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) + { + Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno, StrError(Errno), LOG_LEVEL_ERROR); + return false; + } + } + else + { + if (fcntl(s, F_SETFL, 0) == -1) + { + Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno, StrError(Errno), LOG_LEVEL_ERROR); + return false; + } + } + return true; +#endif +} + + +void Socket::Set(bool bRead, bool bWrite, bool bException) +{ + Handler().Set(m_socket, bRead, bWrite, bException); +} + + +bool Socket::Ready() +{ + if (m_socket != INVALID_SOCKET && !CloseAndDelete()) + return true; + return false; +} + + +void Socket::OnLine(const std::string& ) +{ +} + + +void Socket::OnConnectFailed() +{ +} + + +Socket *Socket::GetParent() +{ + return m_parent; +} + + +void Socket::SetParent(Socket *x) +{ + m_parent = x; +} + + +port_t Socket::GetPort() +{ + Handler().LogError(this, "GetPort", 0, "GetPort only implemented for ListenSocket", LOG_LEVEL_WARNING); + return 0; +} + + +bool Socket::OnConnectRetry() +{ + return true; +} + + +#ifdef ENABLE_RECONNECT +void Socket::OnReconnect() +{ +} +#endif + + +time_t Socket::Uptime() +{ + return time(NULL) - m_tCreate; +} + + +#ifdef ENABLE_IPV6 +void Socket::SetIpv6(bool x) +{ + m_ipv6 = x; +} + + +bool Socket::IsIpv6() +{ + return m_ipv6; +} +#endif + + +void Socket::DisableRead(bool x) +{ + m_b_disable_read = x; +} + + +bool Socket::IsDisableRead() +{ + return m_b_disable_read; +} + + +void Socket::SendBuf(const char *,size_t,int) +{ +} + + +void Socket::Send(const std::string&,int) +{ +} + + +void Socket::SetConnected(bool x) +{ + m_connected = x; +} + + +bool Socket::IsConnected() +{ + return m_connected; +} + + +void Socket::OnDisconnect() +{ +} + + +void Socket::SetLost() +{ + m_bLost = true; +} + + +bool Socket::Lost() +{ + return m_bLost; +} + + +void Socket::SetErasedByHandler(bool x) +{ + m_b_erased_by_handler = x; +} + + +bool Socket::ErasedByHandler() +{ + return m_b_erased_by_handler; +} + + +time_t Socket::TimeSinceClose() +{ + return time(NULL) - m_tClose; +} + + +void Socket::SetClientRemoteAddress(SocketAddress& ad) +{ + if (!ad.IsValid()) + { + Handler().LogError(this, "SetClientRemoteAddress", 0, "remote address not valid", LOG_LEVEL_ERROR); + } + m_client_remote_address = ad.GetCopy(); +} + + +std::auto_ptr Socket::GetClientRemoteAddress() +{ + if (!m_client_remote_address.get()) + { + Handler().LogError(this, "GetClientRemoteAddress", 0, "remote address not yet set", LOG_LEVEL_ERROR); + } + return m_client_remote_address -> GetCopy(); +} + + +uint64_t Socket::GetBytesSent(bool) +{ + return 0; +} + + +uint64_t Socket::GetBytesReceived(bool) +{ + return 0; +} + + +#ifdef HAVE_OPENSSL +void Socket::OnSSLConnect() +{ +} + + +void Socket::OnSSLAccept() +{ +} + + +bool Socket::SSLNegotiate() +{ + return false; +} + + +bool Socket::IsSSL() +{ + return m_b_enable_ssl; +} + + +void Socket::EnableSSL(bool x) +{ + m_b_enable_ssl = x; +} + + +bool Socket::IsSSLNegotiate() +{ + return m_b_ssl; +} + + +void Socket::SetSSLNegotiate(bool x) +{ + m_b_ssl = x; +} + + +bool Socket::IsSSLServer() +{ + return m_b_ssl_server; +} + + +void Socket::SetSSLServer(bool x) +{ + m_b_ssl_server = x; +} + + +void Socket::OnSSLConnectFailed() +{ +} + + +void Socket::OnSSLAcceptFailed() +{ +} +#endif // HAVE_OPENSSL + + +#ifdef ENABLE_POOL +void Socket::CopyConnection(Socket *sock) +{ + Attach( sock -> GetSocket() ); +#ifdef ENABLE_IPV6 + SetIpv6( sock -> IsIpv6() ); +#endif + SetSocketType( sock -> GetSocketType() ); + SetSocketProtocol( sock -> GetSocketProtocol() ); + + SetClientRemoteAddress( *sock -> GetClientRemoteAddress() ); + SetRemoteAddress( *sock -> GetRemoteSocketAddress() ); +} + + +void Socket::SetIsClient() +{ + m_bClient = true; +} + + +void Socket::SetSocketType(int x) +{ + m_socket_type = x; +} + + +int Socket::GetSocketType() +{ + return m_socket_type; +} + + +void Socket::SetSocketProtocol(const std::string& x) +{ + m_socket_protocol = x; +} + + +const std::string& Socket::GetSocketProtocol() +{ + return m_socket_protocol; +} + + +void Socket::SetRetain() +{ + if (m_bClient) m_bRetain = true; +} + + +bool Socket::Retain() +{ + return m_bRetain; +} + + +#endif // ENABLE_POOL + + +#ifdef ENABLE_SOCKS4 +void Socket::OnSocks4Connect() +{ + Handler().LogError(this, "OnSocks4Connect", 0, "Use with TcpSocket only"); +} + + +void Socket::OnSocks4ConnectFailed() +{ + Handler().LogError(this, "OnSocks4ConnectFailed", 0, "Use with TcpSocket only"); +} + + +bool Socket::OnSocks4Read() +{ + Handler().LogError(this, "OnSocks4Read", 0, "Use with TcpSocket only"); + return true; +} + + +void Socket::SetSocks4Host(const std::string& host) +{ + Utility::u2ip(host, m_socks4_host); +} + + +bool Socket::Socks4() +{ + return m_bSocks4; +} + + +void Socket::SetSocks4(bool x) +{ + m_bSocks4 = x; +} + + +void Socket::SetSocks4Host(ipaddr_t a) +{ + m_socks4_host = a; +} + + +void Socket::SetSocks4Port(port_t p) +{ + m_socks4_port = p; +} + + +void Socket::SetSocks4Userid(const std::string& x) +{ + m_socks4_userid = x; +} + + +ipaddr_t Socket::GetSocks4Host() +{ + return m_socks4_host; +} + + +port_t Socket::GetSocks4Port() +{ + return m_socks4_port; +} + + +const std::string& Socket::GetSocks4Userid() +{ + return m_socks4_userid; +} +#endif // ENABLE_SOCKS4 + + +#ifdef ENABLE_DETACH +bool Socket::Detach() +{ + if (!DeleteByHandler()) + return false; + if (m_pThread) + return false; + if (m_detached) + return false; + SetDetach(); + return true; +} + + +void Socket::DetachSocket() +{ + SetDetached(); + m_pThread = new SocketThread(this); + m_pThread -> SetRelease(true); +} + + +void Socket::OnDetached() +{ +} + + +void Socket::SetDetach(bool x) +{ + Handler().AddList(m_socket, LIST_DETACH, x); + m_detach = x; +} + + +bool Socket::IsDetach() +{ + return m_detach; +} + + +void Socket::SetDetached(bool x) +{ + m_detached = x; +} + + +const bool Socket::IsDetached() const +{ + return m_detached; +} + + +void Socket::SetSlaveHandler(ISocketHandler *p) +{ + m_slave_handler = p; +} + + +Socket::SocketThread::SocketThread(Socket *p) +:Thread(false) +,m_socket(p) +{ + // Creator will release +} + + +Socket::SocketThread::~SocketThread() +{ + if (IsRunning()) + { + SetRelease(true); + SetRunning(false); +#ifdef _WIN32 + Sleep(1000); +#else + sleep(1); +#endif + } +} + + +void Socket::SocketThread::Run() +{ + SocketHandler h; + h.SetSlave(); + h.Add(m_socket); + m_socket -> SetSlaveHandler(&h); + m_socket -> OnDetached(); + while (h.GetCount() && IsRunning()) + { + h.Select(0, 500000); + } + // m_socket now deleted oops + // yeah oops m_socket delete its socket thread, that means this + // so Socket will no longer delete its socket thread, instead we do this: + SetDeleteOnExit(); +} +#endif // ENABLE_DETACH + + +#ifdef ENABLE_RESOLVER +int Socket::Resolve(const std::string& host,port_t port) +{ + return Handler().Resolve(this, host, port); +} + + +#ifdef ENABLE_IPV6 +int Socket::Resolve6(const std::string& host,port_t port) +{ + return Handler().Resolve6(this, host, port); +} +#endif + + +int Socket::Resolve(ipaddr_t a) +{ + return Handler().Resolve(this, a); +} + + +#ifdef ENABLE_IPV6 +int Socket::Resolve(in6_addr& a) +{ + return Handler().Resolve(this, a); +} +#endif + + +void Socket::OnResolved(int,ipaddr_t,port_t) +{ +} + + +#ifdef ENABLE_IPV6 +void Socket::OnResolved(int,in6_addr&,port_t) +{ +} +#endif + + +void Socket::OnReverseResolved(int,const std::string&) +{ +} + + +void Socket::OnResolveFailed(int) +{ +} +#endif // ENABLE_RESOLVER + + +/* IP options */ + + +bool Socket::SetIpOptions(const void *p, socklen_t len) +{ +#ifdef IP_OPTIONS + if (setsockopt(GetSocket(), IPPROTO_IP, IP_OPTIONS, (char *)p, len) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_OPTIONS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_OPTIONS", LOG_LEVEL_INFO); + return false; +#endif +} + + +#ifdef IP_PKTINFO +bool Socket::SetIpPktinfo(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_PKTINFO, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_PKTINFO)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef IP_RECVTOS +bool Socket::SetIpRecvTOS(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVTOS, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef IP_RECVTTL +bool Socket::SetIpRecvTTL(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVTTL, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef IP_RECVOPTS +bool Socket::SetIpRecvopts(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVOPTS, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVOPTS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef IP_RETOPTS +bool Socket::SetIpRetopts(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_RETOPTS, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RETOPTS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +bool Socket::SetIpTOS(unsigned char tos) +{ +#ifdef IP_TOS + if (setsockopt(GetSocket(), IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO); + return false; +#endif +} + + +unsigned char Socket::IpTOS() +{ + unsigned char tos = 0; +#ifdef IP_TOS + socklen_t len = sizeof(tos); + if (getsockopt(GetSocket(), IPPROTO_IP, IP_TOS, (char *)&tos, &len) == -1) + { + Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO); +#endif + return tos; +} + + +bool Socket::SetIpTTL(int ttl) +{ +#ifdef IP_TTL + if (setsockopt(GetSocket(), IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO); + return false; +#endif +} + + +int Socket::IpTTL() +{ + int ttl = 0; +#ifdef IP_TTL + socklen_t len = sizeof(ttl); + if (getsockopt(GetSocket(), IPPROTO_IP, IP_TTL, (char *)&ttl, &len) == -1) + { + Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO); +#endif + return ttl; +} + + +bool Socket::SetIpHdrincl(bool x) +{ +#ifdef IP_HDRINCL + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_HDRINCL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_HDRINCL", LOG_LEVEL_INFO); + return false; +#endif +} + + +#ifdef IP_RECVERR +bool Socket::SetIpRecverr(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVERR, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVERR)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef IP_MTU_DISCOVER +bool Socket::SetIpMtudiscover(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_MTU_DISCOVER, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MTU_DISCOVER)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef IP_MTU +int Socket::IpMtu() +{ + int mtu = 0; + socklen_t len = sizeof(mtu); + if (getsockopt(GetSocket(), IPPROTO_IP, IP_MTU, (char *)&mtu, &len) == -1) + { + Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MTU)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } + return mtu; +} +#endif + + +#ifdef IP_ROUTER_ALERT +bool Socket::SetIpRouterAlert(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_ROUTER_ALERT, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ROUTER_ALERT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +bool Socket::SetIpMulticastTTL(int ttl) +{ +#ifdef IP_MULTICAST_TTL + if (setsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO); + return false; +#endif +} + + +int Socket::IpMulticastTTL() +{ + int ttl = 0; +#ifdef IP_MULTICAST_TTL + socklen_t len = sizeof(ttl); + if (getsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, &len) == -1) + { + Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO); +#endif + return ttl; +} + + +bool Socket::SetMulticastLoop(bool x) +{ +#ifdef IP_MULTICAST_LOOP + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_LOOP", LOG_LEVEL_INFO); + return false; +#endif +} + + +#ifdef LINUX +bool Socket::IpAddMembership(struct ip_mreqn& ref) +{ +#ifdef IP_ADD_MEMBERSHIP + if (setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreqn)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO); + return false; +#endif +} +#endif + + +bool Socket::IpAddMembership(struct ip_mreq& ref) +{ +#ifdef IP_ADD_MEMBERSHIP + if (setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreq)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO); + return false; +#endif +} + + +#ifdef LINUX +bool Socket::IpDropMembership(struct ip_mreqn& ref) +{ +#ifdef IP_DROP_MEMBERSHIP + if (setsockopt(GetSocket(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreqn)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO); + return false; +#endif +} +#endif + + +bool Socket::IpDropMembership(struct ip_mreq& ref) +{ +#ifdef IP_DROP_MEMBERSHIP + if (setsockopt(GetSocket(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreq)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO); + return false; +#endif +} + + +/* SOCKET options */ + + +bool Socket::SetSoReuseaddr(bool x) +{ +#ifdef SO_REUSEADDR + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_REUSEADDR)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_REUSEADDR", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoKeepalive(bool x) +{ +#ifdef SO_KEEPALIVE + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_KEEPALIVE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_KEEPALIVE", LOG_LEVEL_INFO); + return false; +#endif +} + + +#ifdef SO_NOSIGPIPE +bool Socket::SetSoNosigpipe(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_NOSIGPIPE, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +bool Socket::SoAcceptconn() +{ + int value = 0; +#ifdef SO_ACCEPTCONN + socklen_t len = sizeof(value); + if (getsockopt(GetSocket(), SOL_SOCKET, SO_ACCEPTCONN, (char *)&value, &len) == -1) + { + Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ACCEPTCONN)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "socket option not available", 0, "SO_ACCEPTCONN", LOG_LEVEL_INFO); +#endif + return value ? true : false; +} + + +#ifdef SO_BSDCOMPAT +bool Socket::SetSoBsdcompat(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_BSDCOMPAT, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BSDCOMPAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef SO_BINDTODEVICE +bool Socket::SetSoBindtodevice(const std::string& intf) +{ + if (setsockopt(GetSocket(), SOL_SOCKET, SO_BINDTODEVICE, (char *)intf.c_str(), intf.size()) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BINDTODEVICE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +bool Socket::SetSoBroadcast(bool x) +{ +#ifdef SO_BROADCAST + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BROADCAST)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_BROADCAST", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoDebug(bool x) +{ +#ifdef SO_DEBUG + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_DEBUG, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DEBUG)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_DEBUG", LOG_LEVEL_INFO); + return false; +#endif +} + + +int Socket::SoError() +{ + int value = 0; +#ifdef SO_ERROR + socklen_t len = sizeof(value); + if (getsockopt(GetSocket(), SOL_SOCKET, SO_ERROR, (char *)&value, &len) == -1) + { + Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ERROR)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "socket option not available", 0, "SO_ERROR", LOG_LEVEL_INFO); +#endif + return value; +} + + +bool Socket::SetSoDontroute(bool x) +{ +#ifdef SO_DONTROUTE + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_DONTROUTE, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DONTROUTE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_DONTROUTE", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoLinger(int onoff, int linger) +{ +#ifdef SO_LINGER + struct linger stl; + stl.l_onoff = onoff; + stl.l_linger = linger; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_LINGER, (char *)&stl, sizeof(stl)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_LINGER)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_LINGER", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoOobinline(bool x) +{ +#ifdef SO_OOBINLINE + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_OOBINLINE, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_OOBINLINE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_OOBINLINE", LOG_LEVEL_INFO); + return false; +#endif +} + + +#ifdef SO_PASSCRED +bool Socket::SetSoPasscred(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_PASSCRED, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PASSCRED)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef SO_PEERCRED +bool Socket::SoPeercred(struct ucred& ucr) +{ + if (setsockopt(GetSocket(), SOL_SOCKET, SO_PEERCRED, (char *)&ucr, sizeof(ucr)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PEERCRED)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef SO_PRIORITY +bool Socket::SetSoPriority(int x) +{ + if (setsockopt(GetSocket(), SOL_SOCKET, SO_PRIORITY, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PRIORITY)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +bool Socket::SetSoRcvlowat(int x) +{ +#ifdef SO_RCVLOWAT + if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVLOWAT, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVLOWAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_RCVLOWAT", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoSndlowat(int x) +{ +#ifdef SO_SNDLOWAT + if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDLOWAT, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDLOWAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_SNDLOWAT", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoRcvtimeo(struct timeval& tv) +{ +#ifdef SO_RCVTIMEO + if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVTIMEO)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_RCVTIMEO", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoSndtimeo(struct timeval& tv) +{ +#ifdef SO_SNDTIMEO + if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDTIMEO)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_SNDTIMEO", LOG_LEVEL_INFO); + return false; +#endif +} + + +bool Socket::SetSoRcvbuf(int x) +{ +#ifdef SO_RCVBUF + if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUF, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO); + return false; +#endif +} + + +int Socket::SoRcvbuf() +{ + int value = 0; +#ifdef SO_RCVBUF + socklen_t len = sizeof(value); + if (getsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUF, (char *)&value, &len) == -1) + { + Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_RCVBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO); +#endif + return value; +} + + +#ifdef SO_RCVBUFFORCE +bool Socket::SetSoRcvbufforce(int x) +{ + if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUFFORCE, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUFFORCE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +bool Socket::SetSoSndbuf(int x) +{ +#ifdef SO_SNDBUF + if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUF, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO); + return false; +#endif +} + + +int Socket::SoSndbuf() +{ + int value = 0; +#ifdef SO_SNDBUF + socklen_t len = sizeof(value); + if (getsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUF, (char *)&value, &len) == -1) + { + Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_SNDBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO); +#endif + return value; +} + + +#ifdef SO_SNDBUFFORCE +bool Socket::SetSoSndbufforce(int x) +{ + if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUFFORCE, (char *)&x, sizeof(x)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUFFORCE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +#ifdef SO_TIMESTAMP +bool Socket::SetSoTimestamp(bool x) +{ + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_SOCKET, SO_TIMESTAMP, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_TIMESTAMP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +} +#endif + + +int Socket::SoType() +{ + int value = 0; +#ifdef SO_TYPE + socklen_t len = sizeof(value); + if (getsockopt(GetSocket(), SOL_SOCKET, SO_TYPE, (char *)&value, &len) == -1) + { + Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_TYPE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + } +#else + Handler().LogError(this, "socket option not available", 0, "SO_TYPE", LOG_LEVEL_INFO); +#endif + return value; +} + + +#ifdef ENABLE_TRIGGERS +void Socket::Subscribe(int id) +{ + Handler().Subscribe(id, this); +} + + +void Socket::Unsubscribe(int id) +{ + Handler().Unsubscribe(id, this); +} + + +void Socket::OnTrigger(int, const TriggerData&) +{ +} + + +void Socket::OnCancelled(int) +{ +} +#endif + + +void Socket::SetTimeout(time_t secs) +{ + if (!secs) + { + Handler().AddList(m_socket, LIST_TIMEOUT, false); + return; + } + Handler().AddList(m_socket, LIST_TIMEOUT, true); + m_timeout_start = time(NULL); + m_timeout_limit = secs; +} + + +void Socket::OnTimeout() +{ +} + + +void Socket::OnConnectTimeout() +{ +} + + +bool Socket::Timeout(time_t tnow) +{ + if (tnow - m_timeout_start > m_timeout_limit) + return true; + return false; +} + + +/** Returns local port number for bound socket file descriptor. */ +port_t Socket::GetSockPort() +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + struct sockaddr_in6 sa; + socklen_t sockaddr_length = sizeof(struct sockaddr_in6); + if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) + memset(&sa, 0, sizeof(sa)); + return ntohs(sa.sin6_port); + } +#endif +#endif + struct sockaddr_in sa; + socklen_t sockaddr_length = sizeof(struct sockaddr_in); + if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) + memset(&sa, 0, sizeof(sa)); + return ntohs(sa.sin_port); +} + + +/** Returns local ipv4 address for bound socket file descriptor. */ +ipaddr_t Socket::GetSockIP4() +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + return 0; + } +#endif +#endif + struct sockaddr_in sa; + socklen_t sockaddr_length = sizeof(struct sockaddr_in); + if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) + memset(&sa, 0, sizeof(sa)); + ipaddr_t a; + memcpy(&a, &sa.sin_addr, 4); + return a; +} + + +/** Returns local ipv4 address as text for bound socket file descriptor. */ +std::string Socket::GetSockAddress() +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + return ""; + } +#endif +#endif + struct sockaddr_in sa; + socklen_t sockaddr_length = sizeof(struct sockaddr_in); + if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) + memset(&sa, 0, sizeof(sa)); + Ipv4Address addr( sa ); + return addr.Convert(); +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +/** Returns local ipv6 address for bound socket file descriptor. */ +struct in6_addr Socket::GetSockIP6() +{ + if (IsIpv6()) + { + struct sockaddr_in6 sa; + socklen_t sockaddr_length = sizeof(struct sockaddr_in6); + if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) + memset(&sa, 0, sizeof(sa)); + return sa.sin6_addr; + } + struct in6_addr a; + memset(&a, 0, sizeof(a)); + return a; +} + + +/** Returns local ipv6 address as text for bound socket file descriptor. */ +std::string Socket::GetSockAddress6() +{ + if (IsIpv6()) + { + struct sockaddr_in6 sa; + socklen_t sockaddr_length = sizeof(struct sockaddr_in6); + if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) + memset(&sa, 0, sizeof(sa)); + Ipv6Address addr( sa ); + return addr.Convert(); + } + return ""; +} +#endif +#endif + + +#ifdef SOCKETS_NAMESPACE +} +#endif + diff --git a/dep/src/sockets/SocketHandler.cpp b/dep/src/sockets/SocketHandler.cpp new file mode 100644 index 000000000..9ec5412af --- /dev/null +++ b/dep/src/sockets/SocketHandler.cpp @@ -0,0 +1,1422 @@ +/** \file SocketHandler.cpp + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef _WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif +#endif +#include +#include + +#include "SocketHandler.h" +#include "UdpSocket.h" +#include "ResolvSocket.h" +#include "ResolvServer.h" +#include "TcpSocket.h" +#include "Mutex.h" +#include "Utility.h" +#include "SocketAddress.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +//#ifdef _DEBUG +//#define DEB(x) x; fflush(stderr); +//#else +#define DEB(x) +//#endif + + +SocketHandler::SocketHandler(StdLog *p) +:m_stdlog(p) +,m_mutex(m_mutex) +,m_b_use_mutex(false) +,m_maxsock(0) +,m_preverror(-1) +,m_errcnt(0) +,m_tlast(0) +#ifdef ENABLE_SOCKS4 +,m_socks4_host(0) +,m_socks4_port(0) +,m_bTryDirect(false) +#endif +#ifdef ENABLE_RESOLVER +,m_resolv_id(0) +,m_resolver(NULL) +#endif +#ifdef ENABLE_POOL +,m_b_enable_pool(false) +#endif +#ifdef ENABLE_TRIGGERS +,m_next_trigger_id(0) +#endif +#ifdef ENABLE_DETACH +,m_slave(false) +#endif +{ + FD_ZERO(&m_rfds); + FD_ZERO(&m_wfds); + FD_ZERO(&m_efds); +} + + +SocketHandler::SocketHandler(Mutex& mutex,StdLog *p) +:m_stdlog(p) +,m_mutex(mutex) +,m_b_use_mutex(true) +,m_maxsock(0) +,m_preverror(-1) +,m_errcnt(0) +,m_tlast(0) +#ifdef ENABLE_SOCKS4 +,m_socks4_host(0) +,m_socks4_port(0) +,m_bTryDirect(false) +#endif +#ifdef ENABLE_RESOLVER +,m_resolv_id(0) +,m_resolver(NULL) +#endif +#ifdef ENABLE_POOL +,m_b_enable_pool(false) +#endif +#ifdef ENABLE_TRIGGERS +,m_next_trigger_id(0) +#endif +#ifdef ENABLE_DETACH +,m_slave(false) +#endif +{ + m_mutex.Lock(); + FD_ZERO(&m_rfds); + FD_ZERO(&m_wfds); + FD_ZERO(&m_efds); +} + + +SocketHandler::~SocketHandler() +{ +#ifdef ENABLE_RESOLVER + if (m_resolver) + { + m_resolver -> Quit(); + } +#endif + { + while (m_sockets.size()) + { +DEB( fprintf(stderr, "Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) + socket_m::iterator it = m_sockets.begin(); + Socket *p = it -> second; + if (p) + { +DEB( fprintf(stderr, " fd %d\n", p -> GetSocket());) + p -> Close(); +DEB( fprintf(stderr, " fd closed %d\n", p -> GetSocket());) +// p -> OnDelete(); // hey, I turn this back on. what's the worst that could happen??!! + // MinionSocket breaks, calling MinderHandler methods in OnDelete - + // MinderHandler is already gone when that happens... + + // only delete socket when controlled + // ie master sockethandler can delete non-detached sockets + // and a slave sockethandler can only delete a detach socket + if (p -> DeleteByHandler() +#ifdef ENABLE_DETACH + && !(m_slave ^ p -> IsDetached()) +#endif + ) + { + p -> SetErasedByHandler(); + delete p; + } + m_sockets.erase(it); + } + else + { + m_sockets.erase(it); + } +DEB( fprintf(stderr, "next\n");) + } +DEB( fprintf(stderr, "/Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) + } +#ifdef ENABLE_RESOLVER + if (m_resolver) + { + delete m_resolver; + } +#endif + if (m_b_use_mutex) + { + m_mutex.Unlock(); + } +} + + +Mutex& SocketHandler::GetMutex() const +{ + return m_mutex; +} + + +#ifdef ENABLE_DETACH +void SocketHandler::SetSlave(bool x) +{ + m_slave = x; +} + + +bool SocketHandler::IsSlave() +{ + return m_slave; +} +#endif + + +void SocketHandler::RegStdLog(StdLog *log) +{ + m_stdlog = log; +} + + +void SocketHandler::LogError(Socket *p,const std::string& user_text,int err,const std::string& sys_err,loglevel_t t) +{ + if (m_stdlog) + { + m_stdlog -> error(this, p, user_text, err, sys_err, t); + } +} + + +void SocketHandler::Add(Socket *p) +{ + if (p -> GetSocket() == INVALID_SOCKET) + { + LogError(p, "Add", -1, "Invalid socket", LOG_LEVEL_WARNING); + if (p -> CloseAndDelete()) + { + m_delete.push_back(p); + } + return; + } + if (m_add.find(p -> GetSocket()) != m_add.end()) + { + LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in add queue", LOG_LEVEL_FATAL); + m_delete.push_back(p); + return; + } + m_add[p -> GetSocket()] = p; +} + + +void SocketHandler::Get(SOCKET s,bool& r,bool& w,bool& e) +{ + if (s >= 0) + { + r = FD_ISSET(s, &m_rfds) ? true : false; + w = FD_ISSET(s, &m_wfds) ? true : false; + e = FD_ISSET(s, &m_efds) ? true : false; + } +} + + +void SocketHandler::Set(SOCKET s,bool bRead,bool bWrite,bool bException) +{ +DEB( fprintf(stderr, "Set(%d, %s, %s, %s)\n", s, bRead ? "true" : "false", bWrite ? "true" : "false", bException ? "true" : "false");) + if (s >= 0) + { + if (bRead) + { + if (!FD_ISSET(s, &m_rfds)) + { + FD_SET(s, &m_rfds); + } + } + else + { + FD_CLR(s, &m_rfds); + } + if (bWrite) + { + if (!FD_ISSET(s, &m_wfds)) + { + FD_SET(s, &m_wfds); + } + } + else + { + FD_CLR(s, &m_wfds); + } + if (bException) + { + if (!FD_ISSET(s, &m_efds)) + { + FD_SET(s, &m_efds); + } + } + else + { + FD_CLR(s, &m_efds); + } + } +} + + +int SocketHandler::Select(long sec,long usec) +{ + struct timeval tv; + tv.tv_sec = sec; + tv.tv_usec = usec; + return Select(&tv); +} + + +int SocketHandler::Select() +{ + if (!m_fds_callonconnect.empty() || +#ifdef ENABLE_DETACH + (!m_slave && !m_fds_detach.empty()) || +#endif + !m_fds_timeout.empty() || + !m_fds_retry.empty() || + !m_fds_close.empty() || + !m_fds_erase.empty()) + { + return Select(0, 200000); + } + return Select(NULL); +} + + +int SocketHandler::Select(struct timeval *tsel) +{ + size_t ignore = 0; + while (m_add.size() > ignore) + { + if (m_sockets.size() >= FD_SETSIZE) + { + LogError(NULL, "Select", (int)m_sockets.size(), "FD_SETSIZE reached", LOG_LEVEL_WARNING); + break; + } + socket_m::iterator it = m_add.begin(); + SOCKET s = it -> first; + Socket *p = it -> second; +DEB( fprintf(stderr, "Trying to add fd %d, m_add.size() %d, ignore %d\n", (int)s, (int)m_add.size(), (int)ignore);) + // + if (m_sockets.find(p -> GetSocket()) != m_sockets.end()) + { + LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in controlled queue", LOG_LEVEL_FATAL); + // %! it's a dup, don't add to delete queue, just ignore it + m_delete.push_back(p); + m_add.erase(it); +// ignore++; + continue; + } + if (!p -> CloseAndDelete()) + { + StreamSocket *scp = dynamic_cast(p); + if (scp && scp -> Connecting()) // 'Open' called before adding socket + { + Set(s,false,true); + } + else + { + TcpSocket *tcp = dynamic_cast(p); + bool bWrite = tcp ? tcp -> GetOutputLength() != 0 : false; + if (p -> IsDisableRead()) + { + Set(s, false, bWrite); + } + else + { + Set(s, true, bWrite); + } + } + m_maxsock = (s > m_maxsock) ? s : m_maxsock; + } + else + { + LogError(p, "Add", (int)p -> GetSocket(), "Trying to add socket with SetCloseAndDelete() true", LOG_LEVEL_WARNING); + } + // only add to m_fds (process fd_set events) if + // slave handler and detached/detaching socket + // master handler and non-detached socket +#ifdef ENABLE_DETACH + if (!(m_slave ^ p -> IsDetach())) +#endif + { + m_fds.push_back(s); + } + m_sockets[s] = p; + // + m_add.erase(it); + } +#ifdef MACOSX + fd_set rfds; + fd_set wfds; + fd_set efds; + FD_COPY(&m_rfds, &rfds); + FD_COPY(&m_wfds, &wfds); + FD_COPY(&m_efds, &efds); +#else + fd_set rfds = m_rfds; + fd_set wfds = m_wfds; + fd_set efds = m_efds; +#endif + int n; + if (m_b_use_mutex) + { + m_mutex.Unlock(); + n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); + m_mutex.Lock(); + } + else + { + n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); + } + if (n == -1) + { + /* + EBADF An invalid file descriptor was given in one of the sets. + EINTR A non blocked signal was caught. + EINVAL n is negative. Or struct timeval contains bad time values (<0). + ENOMEM select was unable to allocate memory for internal tables. + */ + if (Errno != m_preverror || m_errcnt++ % 10000 == 0) + { + LogError(NULL, "select", Errno, StrError(Errno)); +DEB( fprintf(stderr, "m_maxsock: %d\n", m_maxsock); + fprintf(stderr, "%s\n", Errno == EINVAL ? "EINVAL" : + Errno == EINTR ? "EINTR" : + Errno == EBADF ? "EBADF" : + Errno == ENOMEM ? "ENOMEM" : ""); + // test bad fd + for (SOCKET i = 0; i <= m_maxsock; i++) + { + bool t = false; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + if (FD_ISSET(i, &m_rfds)) + { + FD_SET(i, &rfds); + t = true; + } + if (FD_ISSET(i, &m_wfds)) + { + FD_SET(i, &wfds); + t = true; + } + if (FD_ISSET(i, &m_efds)) + { + FD_SET(i, &efds); + t = true; + } + if (t && m_sockets.find(i) == m_sockets.end()) + { + fprintf(stderr, "Bad fd in fd_set: %d\n", i); + } + } +) // DEB + m_preverror = Errno; + } + /// \todo rebuild fd_set's from active sockets list (m_sockets) here + } + else + if (!n) + { + m_preverror = -1; + } + else + if (n > 0) + { + for (socket_v::iterator it2 = m_fds.begin(); it2 != m_fds.end() && n; it2++) + { + SOCKET i = *it2; + if (FD_ISSET(i, &rfds)) + { + socket_m::iterator itmp = m_sockets.find(i); + if (itmp != m_sockets.end()) // found + { + Socket *p = itmp -> second; + // new SSL negotiate method +#ifdef HAVE_OPENSSL + if (p -> IsSSLNegotiate()) + { + p -> SSLNegotiate(); + } + else +#endif + { + p -> OnRead(); + } + } + else + { + LogError(NULL, "GetSocket/handler/1", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + n--; + } + if (FD_ISSET(i, &wfds)) + { + socket_m::iterator itmp = m_sockets.find(i); + if (itmp != m_sockets.end()) // found + { + Socket *p = itmp -> second; + // new SSL negotiate method +#ifdef HAVE_OPENSSL + if (p -> IsSSLNegotiate()) + { + p -> SSLNegotiate(); + } + else +#endif + { + p -> OnWrite(); + } + } + else + { + LogError(NULL, "GetSocket/handler/2", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + n--; + } + if (FD_ISSET(i, &efds)) + { + socket_m::iterator itmp = m_sockets.find(i); + if (itmp != m_sockets.end()) // found + { + Socket *p = itmp -> second; + p -> OnException(); + } + else + { + LogError(NULL, "GetSocket/handler/3", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + n--; + } + } // m_fds loop + m_preverror = -1; + } // if (n > 0) + + // check CallOnConnect - EVENT + if (!m_fds_callonconnect.empty()) + { + socket_v tmp = m_fds_callonconnect; + for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) + { + Socket *p = NULL; + { + socket_m::iterator itmp = m_sockets.find(*it); + if (itmp != m_sockets.end()) // found + { + p = itmp -> second; + } + else + { + LogError(NULL, "GetSocket/handler/4", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + } + if (p) + { +// if (p -> CallOnConnect() && p -> Ready() ) + { + p -> SetConnected(); // moved here from inside if (tcp) check below +#ifdef HAVE_OPENSSL + if (p -> IsSSL()) // SSL Enabled socket + p -> OnSSLConnect(); + else +#endif +#ifdef ENABLE_SOCKS4 + if (p -> Socks4()) + p -> OnSocks4Connect(); + else +#endif + { + TcpSocket *tcp = dynamic_cast(p); + if (tcp) + { + if (tcp -> GetOutputLength()) + { + p -> OnWrite(); + } + } +#ifdef ENABLE_RECONNECT + if (tcp && tcp -> IsReconnect()) + p -> OnReconnect(); + else +#endif + { +// LogError(p, "Calling OnConnect", 0, "Because CallOnConnect", LOG_LEVEL_INFO); + p -> OnConnect(); + } + } +// p -> SetCallOnConnect( false ); + AddList(p -> GetSocket(), LIST_CALLONCONNECT, false); + } + } + } + } +#ifdef ENABLE_DETACH + // check detach of socket if master handler - EVENT + if (!m_slave && !m_fds_detach.empty()) + { + // %! why not using tmp list here??!? + for (socket_v::iterator it = m_fds_detach.begin(); it != m_fds_detach.end(); it++) + { + Socket *p = NULL; + { + socket_m::iterator itmp = m_sockets.find(*it); + if (itmp != m_sockets.end()) // found + { + p = itmp -> second; + } + else + { + LogError(NULL, "GetSocket/handler/5", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + } + if (p) + { +// if (p -> IsDetach()) + { + Set(p -> GetSocket(), false, false, false); + // After DetachSocket(), all calls to Handler() will return a reference + // to the new slave SocketHandler running in the new thread. + p -> DetachSocket(); + // Adding the file descriptor to m_fds_erase will now also remove the + // socket from the detach queue - tnx knightmad + m_fds_erase.push_back(p -> GetSocket()); + } + } + } + } +#endif + // check Connecting - connection timeout - conditional event + if (m_fds_timeout.size()) + { + time_t tnow = time(NULL); + if (tnow != m_tlast) + { + socket_v tmp = m_fds_timeout; +DEB( fprintf(stderr, "Checking %d socket(s) for timeout\n", tmp.size());) + for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) + { + Socket *p = NULL; + { + socket_m::iterator itmp = m_sockets.find(*it); + if (itmp != m_sockets.end()) // found + { + p = itmp -> second; + } + else + { + itmp = m_add.find(*it); + if (itmp != m_add.end()) + { + p = itmp -> second; + } + else + { + LogError(NULL, "GetSocket/handler/6", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + } + } + if (p) + { + if (p -> Timeout(tnow)) + { + StreamSocket *scp = dynamic_cast(p); + if (scp && scp -> Connecting()) + p -> OnConnectTimeout(); + else + p -> OnTimeout(); + p -> SetTimeout(0); + } + } + } + m_tlast = tnow; + } // tnow != tlast + } + // check retry client connect - EVENT + if (!m_fds_retry.empty()) + { + socket_v tmp = m_fds_retry; + for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) + { + Socket *p = NULL; + { + socket_m::iterator itmp = m_sockets.find(*it); + if (itmp != m_sockets.end()) // found + { + p = itmp -> second; + } + else + { + LogError(NULL, "GetSocket/handler/7", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + } + if (p) + { +// if (p -> RetryClientConnect()) + { + TcpSocket *tcp = dynamic_cast(p); + SOCKET nn = *it; //(*it3).first; + tcp -> SetRetryClientConnect(false); +DEB( fprintf(stderr, "Close() before retry client connect\n");) + p -> Close(); // removes from m_fds_retry + std::auto_ptr ad = p -> GetClientRemoteAddress(); + if (ad.get()) + { + tcp -> Open(*ad); + } + else + { + LogError(p, "RetryClientConnect", 0, "no address", LOG_LEVEL_ERROR); + } + Add(p); + m_fds_erase.push_back(nn); + } + } + } + } + // check close and delete - conditional event + if (!m_fds_close.empty()) + { + socket_v tmp = m_fds_close; +DEB( fprintf(stderr, "m_fds_close.size() == %d\n", (int)m_fds_close.size());) + for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) + { + Socket *p = NULL; + { + socket_m::iterator itmp = m_sockets.find(*it); + if (itmp != m_sockets.end()) // found + { + p = itmp -> second; + } + else + { + itmp = m_add.find(*it); + if (itmp != m_add.end()) + { + p = itmp -> second; + } + else + { + LogError(NULL, "GetSocket/handler/8", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); + } + } + } + if (p) + { +// if (p -> CloseAndDelete() ) + { + TcpSocket *tcp = dynamic_cast(p); + // new graceful tcp - flush and close timeout 5s + if (tcp && p -> IsConnected() && tcp -> GetFlushBeforeClose() && +#ifdef HAVE_OPENSSL + !tcp -> IsSSL() && +#endif + p -> TimeSinceClose() < 5) + { +DEB( fprintf(stderr, " close(1)\n");) + if (tcp -> GetOutputLength()) + { + LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Sending all data before closing", LOG_LEVEL_INFO); + } + else // shutdown write when output buffer is empty + if (!(tcp -> GetShutdown() & SHUT_WR)) + { + SOCKET nn = *it; + if (nn != INVALID_SOCKET && shutdown(nn, SHUT_WR) == -1) + { + LogError(p, "graceful shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + tcp -> SetShutdown(SHUT_WR); + } + } + else +#ifdef ENABLE_RECONNECT + if (tcp && p -> IsConnected() && tcp -> Reconnect()) + { + SOCKET nn = *it; //(*it3).first; +DEB( fprintf(stderr, " close(2) fd %d\n", nn);) + p -> SetCloseAndDelete(false); + tcp -> SetIsReconnect(); + p -> SetConnected(false); +DEB( fprintf(stderr, "Close() before reconnect\n");) + p -> Close(); // dispose of old file descriptor (Open creates a new) + p -> OnDisconnect(); + std::auto_ptr ad = p -> GetClientRemoteAddress(); + if (ad.get()) + { + tcp -> Open(*ad); + } + else + { + LogError(p, "Reconnect", 0, "no address", LOG_LEVEL_ERROR); + } + tcp -> ResetConnectionRetries(); + Add(p); + m_fds_erase.push_back(nn); + } + else +#endif + { + SOCKET nn = *it; //(*it3).first; +DEB( fprintf(stderr, " close(3) fd %d GetSocket() %d\n", nn, p -> GetSocket());) + if (tcp && p -> IsConnected() && tcp -> GetOutputLength()) + { + LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Closing socket while data still left to send", LOG_LEVEL_WARNING); + } +#ifdef ENABLE_POOL + if (p -> Retain() && !p -> Lost()) + { + PoolSocket *p2 = new PoolSocket(*this, p); + p2 -> SetDeleteByHandler(); + Add(p2); + // + p -> SetCloseAndDelete(false); // added - remove from m_fds_close + } + else +#endif // ENABLE_POOL + { + Set(p -> GetSocket(),false,false,false); +DEB( fprintf(stderr, "Close() before OnDelete\n");) + p -> Close(); + } + p -> OnDelete(); + if (p -> DeleteByHandler()) + { + p -> SetErasedByHandler(); + } + m_fds_erase.push_back(nn); + } + } + } + } + } + + // check erased sockets + bool check_max_fd = false; + while (!m_fds_erase.empty()) + { + socket_v::iterator it = m_fds_erase.begin(); + SOCKET nn = *it; +#ifdef ENABLE_DETACH + { + for (socket_v::iterator it = m_fds_detach.begin(); it != m_fds_detach.end(); it++) + { + if (*it == nn) + { + m_fds_detach.erase(it); + break; + } + } + } +#endif + { + for (socket_v::iterator it = m_fds.begin(); it != m_fds.end(); it++) + { + if (*it == nn) + { + m_fds.erase(it); + break; + } + } + } + { + socket_m::iterator it = m_sockets.find(nn); + if (it != m_sockets.end()) + { + Socket *p = it -> second; + /* Sometimes a SocketThread class can finish its run before the master + sockethandler gets here. In that case, the SocketThread has set the + 'ErasedByHandler' flag on the socket which will make us end up with a + double delete on the socket instance. + The fix is to make sure that the master sockethandler only can delete + non-detached sockets, and a slave sockethandler only can delete + detach sockets. */ + if (p -> ErasedByHandler() +#ifdef ENABLE_DETACH + && !(m_slave ^ p -> IsDetached()) +#endif + ) + { +#ifdef ENABLE_TRIGGERS + bool again = false; + do + { + again = false; + for (std::map::iterator it = m_trigger_src.begin(); it != m_trigger_src.end(); it++) + { + int id = it -> first; + Socket *src = it -> second; + if (src == p) + { + for (std::map::iterator it = m_trigger_dst[id].begin(); it != m_trigger_dst[id].end(); it++) + { + Socket *dst = it -> first; + if (Valid(dst)) + { + dst -> OnCancelled(id); + } + } + m_trigger_src.erase(m_trigger_src.find(id)); + m_trigger_dst.erase(m_trigger_dst.find(id)); + again = true; + break; + } + } + } while (again); +#endif + delete p; + } + m_sockets.erase(it); + } + } + m_fds_erase.erase(it); + check_max_fd = true; + } + // calculate max file descriptor for select() call + if (check_max_fd) + { + m_maxsock = 0; + for (socket_v::iterator it = m_fds.begin(); it != m_fds.end(); it++) + { + SOCKET s = *it; + m_maxsock = s > m_maxsock ? s : m_maxsock; + } + } + // remove Add's that fizzed + while (!m_delete.empty()) + { + std::list::iterator it = m_delete.begin(); + Socket *p = *it; + p -> OnDelete(); + m_delete.erase(it); + if (p -> DeleteByHandler() +#ifdef ENABLE_DETACH + && !(m_slave ^ p -> IsDetached()) +#endif + ) + { + p -> SetErasedByHandler(); +#ifdef ENABLE_TRIGGERS + bool again = false; + do + { + again = false; + for (std::map::iterator it = m_trigger_src.begin(); it != m_trigger_src.end(); it++) + { + int id = it -> first; + Socket *src = it -> second; + if (src == p) + { + for (std::map::iterator it = m_trigger_dst[id].begin(); it != m_trigger_dst[id].end(); it++) + { + Socket *dst = it -> first; + if (Valid(dst)) + { + dst -> OnCancelled(id); + } + } + m_trigger_src.erase(m_trigger_src.find(id)); + m_trigger_dst.erase(m_trigger_dst.find(id)); + again = true; + break; + } + } + } while (again); +#endif + delete p; + } + } + return n; +} + + +#ifdef ENABLE_RESOLVER +bool SocketHandler::Resolving(Socket *p0) +{ + std::map::iterator it = m_resolve_q.find(p0); + return it != m_resolve_q.end(); +} +#endif + + +bool SocketHandler::Valid(Socket *p0) +{ + for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++) + { + Socket *p = it -> second; + if (p0 == p) + return true; + } + return false; +} + + +bool SocketHandler::OkToAccept(Socket *) +{ + return true; +} + + +size_t SocketHandler::GetCount() +{ +/* +printf(" m_sockets : %d\n", m_sockets.size()); +printf(" m_add : %d\n", m_add.size()); +printf(" m_delete : %d\n", m_delete.size()); +*/ + return m_sockets.size() + m_add.size() + m_delete.size(); +} + + +#ifdef ENABLE_SOCKS4 +void SocketHandler::SetSocks4Host(ipaddr_t a) +{ + m_socks4_host = a; +} + + +void SocketHandler::SetSocks4Host(const std::string& host) +{ + Utility::u2ip(host, m_socks4_host); +} + + +void SocketHandler::SetSocks4Port(port_t port) +{ + m_socks4_port = port; +} + + +void SocketHandler::SetSocks4Userid(const std::string& id) +{ + m_socks4_userid = id; +} +#endif + + +#ifdef ENABLE_RESOLVER +int SocketHandler::Resolve(Socket *p,const std::string& host,port_t port) +{ + // check cache + ResolvSocket *resolv = new ResolvSocket(*this, p, host, port); + resolv -> SetId(++m_resolv_id); + resolv -> SetDeleteByHandler(); + ipaddr_t local; + Utility::u2ip("127.0.0.1", local); + if (!resolv -> Open(local, m_resolver_port)) + { + LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); + } + Add(resolv); + m_resolve_q[p] = true; +DEB( fprintf(stderr, " *** Resolve '%s:%d' id#%d m_resolve_q size: %d p: %p\n", host.c_str(), port, resolv -> GetId(), m_resolve_q.size(), p);) + return resolv -> GetId(); +} + + +#ifdef ENABLE_IPV6 +int SocketHandler::Resolve6(Socket *p,const std::string& host,port_t port) +{ + // check cache + ResolvSocket *resolv = new ResolvSocket(*this, p, host, port, true); + resolv -> SetId(++m_resolv_id); + resolv -> SetDeleteByHandler(); + ipaddr_t local; + Utility::u2ip("127.0.0.1", local); + if (!resolv -> Open(local, m_resolver_port)) + { + LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); + } + Add(resolv); + m_resolve_q[p] = true; + return resolv -> GetId(); +} +#endif + + +int SocketHandler::Resolve(Socket *p,ipaddr_t a) +{ + // check cache + ResolvSocket *resolv = new ResolvSocket(*this, p, a); + resolv -> SetId(++m_resolv_id); + resolv -> SetDeleteByHandler(); + ipaddr_t local; + Utility::u2ip("127.0.0.1", local); + if (!resolv -> Open(local, m_resolver_port)) + { + LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); + } + Add(resolv); + m_resolve_q[p] = true; + return resolv -> GetId(); +} + + +#ifdef ENABLE_IPV6 +int SocketHandler::Resolve(Socket *p,in6_addr& a) +{ + // check cache + ResolvSocket *resolv = new ResolvSocket(*this, p, a); + resolv -> SetId(++m_resolv_id); + resolv -> SetDeleteByHandler(); + ipaddr_t local; + Utility::u2ip("127.0.0.1", local); + if (!resolv -> Open(local, m_resolver_port)) + { + LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); + } + Add(resolv); + m_resolve_q[p] = true; + return resolv -> GetId(); +} +#endif + + +void SocketHandler::EnableResolver(port_t port) +{ + if (!m_resolver) + { + m_resolver_port = port; + m_resolver = new ResolvServer(port); + } +} + + +bool SocketHandler::ResolverReady() +{ + return m_resolver ? m_resolver -> Ready() : false; +} +#endif // ENABLE_RESOLVER + + +#ifdef ENABLE_SOCKS4 +void SocketHandler::SetSocks4TryDirect(bool x) +{ + m_bTryDirect = x; +} + + +ipaddr_t SocketHandler::GetSocks4Host() +{ + return m_socks4_host; +} + + +port_t SocketHandler::GetSocks4Port() +{ + return m_socks4_port; +} + + +const std::string& SocketHandler::GetSocks4Userid() +{ + return m_socks4_userid; +} + + +bool SocketHandler::Socks4TryDirect() +{ + return m_bTryDirect; +} +#endif + + +#ifdef ENABLE_RESOLVER +bool SocketHandler::ResolverEnabled() +{ + return m_resolver ? true : false; +} + + +port_t SocketHandler::GetResolverPort() +{ + return m_resolver_port; +} +#endif // ENABLE_RESOLVER + + +#ifdef ENABLE_POOL +ISocketHandler::PoolSocket *SocketHandler::FindConnection(int type,const std::string& protocol,SocketAddress& ad) +{ + for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end() && !m_sockets.empty(); it++) + { + PoolSocket *pools = dynamic_cast(it -> second); + if (pools) + { + if (pools -> GetSocketType() == type && + pools -> GetSocketProtocol() == protocol && +// %! pools -> GetClientRemoteAddress() && + *pools -> GetClientRemoteAddress() == ad) + { + m_sockets.erase(it); + pools -> SetRetain(); // avoid Close in Socket destructor + return pools; // Caller is responsible that this socket is deleted + } + } + } + return NULL; +} + + +void SocketHandler::EnablePool(bool x) +{ + m_b_enable_pool = x; +} + + +bool SocketHandler::PoolEnabled() +{ + return m_b_enable_pool; +} +#endif + + +void SocketHandler::Remove(Socket *p) +{ +#ifdef ENABLE_RESOLVER + std::map::iterator it4 = m_resolve_q.find(p); + if (it4 != m_resolve_q.end()) + m_resolve_q.erase(it4); +#endif + if (p -> ErasedByHandler()) + { + return; + } + for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++) + { + if (it -> second == p) + { + LogError(p, "Remove", -1, "Socket destructor called while still in use", LOG_LEVEL_WARNING); + m_sockets.erase(it); + return; + } + } + for (socket_m::iterator it2 = m_add.begin(); it2 != m_add.end(); it2++) + { + if ((*it2).second == p) + { + LogError(p, "Remove", -2, "Socket destructor called while still in use", LOG_LEVEL_WARNING); + m_add.erase(it2); + return; + } + } + for (std::list::iterator it3 = m_delete.begin(); it3 != m_delete.end(); it3++) + { + if (*it3 == p) + { + LogError(p, "Remove", -3, "Socket destructor called while still in use", LOG_LEVEL_WARNING); + m_delete.erase(it3); + return; + } + } +} + + +void SocketHandler::CheckSanity() +{ + CheckList(m_fds, "active sockets"); // active sockets + CheckList(m_fds_erase, "sockets to be erased"); // should always be empty anyway + CheckList(m_fds_callonconnect, "checklist CallOnConnect"); +#ifdef ENABLE_DETACH + CheckList(m_fds_detach, "checklist Detach"); +#endif + CheckList(m_fds_timeout, "checklist Timeout"); + CheckList(m_fds_retry, "checklist retry client connect"); + CheckList(m_fds_close, "checklist close and delete"); +} + + +void SocketHandler::CheckList(socket_v& ref,const std::string& listname) +{ + for (socket_v::iterator it = ref.begin(); it != ref.end(); it++) + { + SOCKET s = *it; + if (m_sockets.find(s) != m_sockets.end()) + continue; + if (m_add.find(s) != m_add.end()) + continue; + bool found = false; + for (std::list::iterator it = m_delete.begin(); it != m_delete.end(); it++) + { + Socket *p = *it; + if (p -> GetSocket() == s) + { + found = true; + break; + } + } + if (!found) + { + fprintf(stderr, "CheckList failed for \"%s\": fd %d\n", listname.c_str(), s); + } + } +} + + +void SocketHandler::AddList(SOCKET s,list_t which_one,bool add) +{ + if (s == INVALID_SOCKET) + { +DEB( fprintf(stderr, "AddList: invalid_socket\n");) + return; + } + socket_v& ref = + (which_one == LIST_CALLONCONNECT) ? m_fds_callonconnect : +#ifdef ENABLE_DETACH + (which_one == LIST_DETACH) ? m_fds_detach : +#endif + (which_one == LIST_TIMEOUT) ? m_fds_timeout : + (which_one == LIST_RETRY) ? m_fds_retry : + (which_one == LIST_CLOSE) ? m_fds_close : m_fds_close; + if (add) + { +#ifdef ENABLE_DETACH +DEB( fprintf(stderr, "AddList; %5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" : + (which_one == LIST_DETACH) ? "Detach" : + (which_one == LIST_TIMEOUT) ? "Timeout" : + (which_one == LIST_RETRY) ? "Retry" : + (which_one == LIST_CLOSE) ? "Close" : "", + add ? "Add" : "Remove");) +#else +DEB( fprintf(stderr, "AddList; %5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" : + (which_one == LIST_TIMEOUT) ? "Timeout" : + (which_one == LIST_RETRY) ? "Retry" : + (which_one == LIST_CLOSE) ? "Close" : "", + add ? "Add" : "Remove");) +#endif + } + if (add) + { + for (socket_v::iterator it = ref.begin(); it != ref.end(); it++) + { + if (*it == s) // already there + { + return; + } + } + ref.push_back(s); + return; + } + // remove + for (socket_v::iterator it = ref.begin(); it != ref.end(); it++) + { + if (*it == s) + { + ref.erase(it); + break; + } + } +//DEB( fprintf(stderr, "/AddList\n");) +} + + +#ifdef ENABLE_TRIGGERS +int SocketHandler::TriggerID(Socket *src) +{ + int id = m_next_trigger_id++; + m_trigger_src[id] = src; + return id; +} + + +bool SocketHandler::Subscribe(int id, Socket *dst) +{ + if (m_trigger_src.find(id) != m_trigger_src.end()) + { + std::map::iterator it = m_trigger_dst[id].find(dst); + if (it != m_trigger_dst[id].end()) + { + m_trigger_dst[id][dst] = true; + return true; + } + LogError(dst, "Subscribe", id, "Already subscribed", LOG_LEVEL_INFO); + return false; + } + LogError(dst, "Subscribe", id, "Trigger id not found", LOG_LEVEL_INFO); + return false; +} + + +bool SocketHandler::Unsubscribe(int id, Socket *dst) +{ + if (m_trigger_src.find(id) != m_trigger_src.end()) + { + std::map::iterator it = m_trigger_dst[id].find(dst); + if (it != m_trigger_dst[id].end()) + { + m_trigger_dst[id].erase(it); + return true; + } + LogError(dst, "Unsubscribe", id, "Not subscribed", LOG_LEVEL_INFO); + return false; + } + LogError(dst, "Unsubscribe", id, "Trigger id not found", LOG_LEVEL_INFO); + return false; +} + + +void SocketHandler::Trigger(int id, Socket::TriggerData& data, bool erase) +{ + if (m_trigger_src.find(id) != m_trigger_src.end()) + { + data.SetSource( m_trigger_src[id] ); + for (std::map::iterator it = m_trigger_dst[id].begin(); it != m_trigger_dst[id].end(); it++) + { + Socket *dst = it -> first; + if (Valid(dst)) + { + dst -> OnTrigger(id, data); + } + } + if (erase) + { + m_trigger_src.erase(m_trigger_src.find(id)); + m_trigger_dst.erase(m_trigger_dst.find(id)); + } + } + else + { + LogError(NULL, "Trigger", id, "Trigger id not found", LOG_LEVEL_INFO); + } +} +#endif // ENABLE_TRIGGERS + + +#ifdef SOCKETS_NAMESPACE +} +#endif + diff --git a/dep/src/sockets/StdoutLog.cpp b/dep/src/sockets/StdoutLog.cpp new file mode 100644 index 000000000..c01d8b8c2 --- /dev/null +++ b/dep/src/sockets/StdoutLog.cpp @@ -0,0 +1,96 @@ +/** \file StdoutLog.cpp + ** \date 2004-06-01 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif +#include "ISocketHandler.h" +#include "Socket.h" +#include "StdoutLog.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + + + +void StdoutLog::error(ISocketHandler *,Socket *sock,const std::string& call,int err,const std::string& sys_err,loglevel_t lvl) +{ + time_t t = time(NULL); + struct tm tp; +#ifdef _WIN32 + memcpy(&tp, localtime(&t), sizeof(tp)); +#else + localtime_r(&t, &tp); +#endif + std::string level; + + switch (lvl) + { + case LOG_LEVEL_WARNING: + level = "Warning"; + break; + case LOG_LEVEL_ERROR: + level = "Error"; + break; + case LOG_LEVEL_FATAL: + level = "Fatal"; + break; + case LOG_LEVEL_INFO: + level = "Info"; + break; + } + if (sock) + { + printf("%d-%02d-%02d %02d:%02d:%02d :: fd %d :: %s: %d %s (%s)\n", + tp.tm_year + 1900, + tp.tm_mon + 1, + tp.tm_mday, + tp.tm_hour,tp.tm_min,tp.tm_sec, + sock -> GetSocket(), + call.c_str(),err,sys_err.c_str(),level.c_str()); + } + else + { + printf("%d-%02d-%02d %02d:%02d:%02d :: %s: %d %s (%s)\n", + tp.tm_year + 1900, + tp.tm_mon + 1, + tp.tm_mday, + tp.tm_hour,tp.tm_min,tp.tm_sec, + call.c_str(),err,sys_err.c_str(),level.c_str()); + } +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + + diff --git a/dep/src/sockets/StreamSocket.cpp b/dep/src/sockets/StreamSocket.cpp new file mode 100644 index 000000000..5c5780e30 --- /dev/null +++ b/dep/src/sockets/StreamSocket.cpp @@ -0,0 +1,169 @@ +#include "StreamSocket.h" +#include "ISocketHandler.h" + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +StreamSocket::StreamSocket(ISocketHandler& h) : Socket(h) +,m_bConnecting(false) +,m_connect_timeout(5) +,m_flush_before_close(true) +,m_connection_retry(0) +,m_retries(0) +,m_call_on_connect(false) +,m_b_retry_connect(false) +,m_line_protocol(false) +,m_shutdown(0) +{ +} + + +StreamSocket::~StreamSocket() +{ +} + + +void StreamSocket::SetConnecting(bool x) +{ + if (x != m_bConnecting) + { + m_bConnecting = x; + if (x) + { + SetTimeout( GetConnectTimeout() ); + } + else + { + SetTimeout( 0 ); + } + } +} + + +bool StreamSocket::Connecting() +{ + return m_bConnecting; +} + + +bool StreamSocket::Ready() +{ + if (GetSocket() != INVALID_SOCKET && !Connecting() && !CloseAndDelete()) + return true; + return false; +} + + +void StreamSocket::SetConnectTimeout(int x) +{ + m_connect_timeout = x; +} + + +int StreamSocket::GetConnectTimeout() +{ + return m_connect_timeout; +} + + +void StreamSocket::SetFlushBeforeClose(bool x) +{ + m_flush_before_close = x; +} + + +bool StreamSocket::GetFlushBeforeClose() +{ + return m_flush_before_close; +} + + +int StreamSocket::GetConnectionRetry() +{ + return m_connection_retry; +} + + +void StreamSocket::SetConnectionRetry(int x) +{ + m_connection_retry = x; +} + + +int StreamSocket::GetConnectionRetries() +{ + return m_retries; +} + + +void StreamSocket::IncreaseConnectionRetries() +{ + m_retries++; +} + + +void StreamSocket::ResetConnectionRetries() +{ + m_retries = 0; +} + + +void StreamSocket::SetCallOnConnect(bool x) +{ + Handler().AddList(GetSocket(), LIST_CALLONCONNECT, x); + m_call_on_connect = x; +} + + +bool StreamSocket::CallOnConnect() +{ + return m_call_on_connect; +} + + +void StreamSocket::SetRetryClientConnect(bool x) +{ + Handler().AddList(GetSocket(), LIST_RETRY, x); + m_b_retry_connect = x; +} + + +bool StreamSocket::RetryClientConnect() +{ + return m_b_retry_connect; +} + + +void StreamSocket::SetLineProtocol(bool x) +{ + m_line_protocol = x; +} + + +bool StreamSocket::LineProtocol() +{ + return m_line_protocol; +} + + +void StreamSocket::SetShutdown(int x) +{ + m_shutdown = x; +} + + +int StreamSocket::GetShutdown() +{ + return m_shutdown; +} + + + + +#ifdef SOCKETS_NAMESPACE +} // namespace SOCKETS_NAMESPACE { +#endif + diff --git a/dep/src/sockets/TcpSocket.cpp b/dep/src/sockets/TcpSocket.cpp new file mode 100644 index 000000000..36df37d58 --- /dev/null +++ b/dep/src/sockets/TcpSocket.cpp @@ -0,0 +1,1745 @@ +/** \file TcpSocket.cpp + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef _WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif +#include +#else +#include +#endif +#include "ISocketHandler.h" +#include +#include +#include +#ifdef HAVE_OPENSSL +#include +#include +#endif +#include + +#include "TcpSocket.h" +#include "Utility.h" +#include "Ipv4Address.h" +#include "Ipv6Address.h" +#include "Mutex.h" +#include "IFile.h" + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +//#ifdef _DEBUG +//#define DEB(x) x +//#else +#define DEB(x) +//#endif + + +// statics +#ifdef HAVE_OPENSSL +SSLInitializer TcpSocket::m_ssl_init; +#endif + + +// thanks, q +#ifdef _MSC_VER +#pragma warning(disable:4355) +#endif +TcpSocket::TcpSocket(ISocketHandler& h) : StreamSocket(h) +,ibuf(TCP_BUFSIZE_READ) +,m_b_input_buffer_disabled(false) +,m_bytes_sent(0) +,m_bytes_received(0) +,m_skip_c(false) +#ifdef SOCKETS_DYNAMIC_TEMP +,m_buf(new char[TCP_BUFSIZE_READ + 1]) +#endif +,m_obuf_top(NULL) +,m_transfer_limit(0) +,m_output_length(0) +#ifdef HAVE_OPENSSL +,m_ssl_ctx(NULL) +,m_ssl(NULL) +,m_sbio(NULL) +#endif +#ifdef ENABLE_SOCKS4 +,m_socks4_state(0) +#endif +#ifdef ENABLE_RESOLVER +,m_resolver_id(0) +#endif +#ifdef ENABLE_RECONNECT +,m_b_reconnect(false) +,m_b_is_reconnect(false) +#endif +{ +} +#ifdef _MSC_VER +#pragma warning(default:4355) +#endif + + +#ifdef _MSC_VER +#pragma warning(disable:4355) +#endif +TcpSocket::TcpSocket(ISocketHandler& h,size_t isize,size_t osize) : StreamSocket(h) +,ibuf(isize) +,m_b_input_buffer_disabled(false) +,m_bytes_sent(0) +,m_bytes_received(0) +,m_skip_c(false) +#ifdef SOCKETS_DYNAMIC_TEMP +,m_buf(new char[TCP_BUFSIZE_READ + 1]) +#endif +,m_obuf_top(NULL) +,m_transfer_limit(0) +,m_output_length(0) +#ifdef HAVE_OPENSSL +,m_ssl_ctx(NULL) +,m_ssl(NULL) +,m_sbio(NULL) +#endif +#ifdef ENABLE_SOCKS4 +,m_socks4_state(0) +#endif +#ifdef ENABLE_RESOLVER +,m_resolver_id(0) +#endif +#ifdef ENABLE_RECONNECT +,m_b_reconnect(false) +,m_b_is_reconnect(false) +#endif +{ +} +#ifdef _MSC_VER +#pragma warning(default:4355) +#endif + + +TcpSocket::~TcpSocket() +{ +#ifdef SOCKETS_DYNAMIC_TEMP + delete[] m_buf; +#endif + // %! empty m_obuf + while (m_obuf.size()) + { + output_l::iterator it = m_obuf.begin(); + OUTPUT *p = *it; + delete p; + m_obuf.erase(it); + } +#ifdef HAVE_OPENSSL + if (m_ssl) + { + SSL_free(m_ssl); + } +#endif +} + + +bool TcpSocket::Open(ipaddr_t ip,port_t port,bool skip_socks) +{ + Ipv4Address ad(ip, port); + Ipv4Address local; + return Open(ad, local, skip_socks); +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +bool TcpSocket::Open(in6_addr ip,port_t port,bool skip_socks) +{ + Ipv6Address ad(ip, port); + return Open(ad, skip_socks); +} +#endif +#endif + + +bool TcpSocket::Open(SocketAddress& ad,bool skip_socks) +{ + Ipv4Address bind_ad("0.0.0.0", 0); + return Open(ad, bind_ad, skip_socks); +} + + +bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks) +{ + if (!ad.IsValid()) + { + Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); + SetCloseAndDelete(); + return false; + } + if (Handler().GetCount() >= FD_SETSIZE) + { + Handler().LogError(this, "Open", 0, "no space left in fd_set", LOG_LEVEL_FATAL); + SetCloseAndDelete(); + return false; + } + SetConnecting(false); +#ifdef ENABLE_SOCKS4 + SetSocks4(false); +#endif + // check for pooling +#ifdef ENABLE_POOL + if (Handler().PoolEnabled()) + { + ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); + if (pools) + { + CopyConnection( pools ); + delete pools; + + SetIsClient(); + SetCallOnConnect(); // ISocketHandler must call OnConnect + Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); + return true; + } + } +#endif + // if not, create new connection + SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); + if (s == INVALID_SOCKET) + { + return false; + } + // socket must be nonblocking for async connect + if (!SetNonblocking(true, s)) + { + SetCloseAndDelete(); + closesocket(s); + return false; + } +#ifdef ENABLE_POOL + SetIsClient(); // client because we connect +#endif + SetClientRemoteAddress(ad); + int n = 0; + if (bind_ad.GetPort() != 0) + { + bind(s, bind_ad, bind_ad); + } +#ifdef ENABLE_SOCKS4 + if (!skip_socks && GetSocks4Host() && GetSocks4Port()) + { + Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); + { + std::string sockshost; + Utility::l2ip(GetSocks4Host(), sockshost); + Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + + Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); + } + SetSocks4(); + n = connect(s, sa, sa); + SetRemoteAddress(sa); + } + else +#endif + { + n = connect(s, ad, ad); + SetRemoteAddress(ad); + } + if (n == -1) + { + // check error code that means a connect is in progress +#ifdef _WIN32 + if (Errno == WSAEWOULDBLOCK) +#else + if (Errno == EINPROGRESS) +#endif + { + Attach(s); + SetConnecting( true ); // this flag will control fd_set's + } + else +#ifdef ENABLE_SOCKS4 + if (Socks4() && Handler().Socks4TryDirect() ) // retry + { + closesocket(s); + return Open(ad, true); + } + else +#endif +#ifdef ENABLE_RECONNECT + if (Reconnect()) + { + Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); + Attach(s); + SetConnecting( true ); // this flag will control fd_set's + } + else +#endif + { + Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); + SetCloseAndDelete(); + closesocket(s); + return false; + } + } + else + { + Attach(s); + SetCallOnConnect(); // ISocketHandler must call OnConnect + } + + // 'true' means connected or connecting(not yet connected) + // 'false' means something failed + return true; //!Connecting(); +} + + +bool TcpSocket::Open(const std::string &host,port_t port) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { +#ifdef ENABLE_RESOLVER + if (!Handler().ResolverEnabled() || Utility::isipv6(host) ) + { +#endif + in6_addr a; + if (!Utility::u2ip(host, a)) + { + SetCloseAndDelete(); + return false; + } + Ipv6Address ad(a, port); + Ipv6Address local; + return Open(ad, local); +#ifdef ENABLE_RESOLVER + } + m_resolver_id = Resolve6(host, port); + return true; +#endif + } +#endif +#endif +#ifdef ENABLE_RESOLVER + if (!Handler().ResolverEnabled() || Utility::isipv4(host) ) + { +#endif + ipaddr_t l; + if (!Utility::u2ip(host,l)) + { + SetCloseAndDelete(); + return false; + } + Ipv4Address ad(l, port); + Ipv4Address local; + return Open(ad, local); +#ifdef ENABLE_RESOLVER + } + // resolve using async resolver thread + m_resolver_id = Resolve(host, port); + return true; +#endif +} + + +#ifdef ENABLE_RESOLVER +void TcpSocket::OnResolved(int id,ipaddr_t a,port_t port) +{ +DEB( fprintf(stderr, "TcpSocket::OnResolved id %d addr %x port %d\n", id, a, port);) + if (id == m_resolver_id) + { + if (a && port) + { + Ipv4Address ad(a, port); + Ipv4Address local; + if (Open(ad, local)) + { + if (!Handler().Valid(this)) + { + Handler().Add(this); + } + } + } + else + { + Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL); + SetCloseAndDelete(); + } + } + else + { + Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL); + SetCloseAndDelete(); + } +} + + +#ifdef ENABLE_IPV6 +void TcpSocket::OnResolved(int id,in6_addr& a,port_t port) +{ + if (id == m_resolver_id) + { + Ipv6Address ad(a, port); + if (ad.IsValid()) + { + Ipv6Address local; + if (Open(ad, local)) + { + if (!Handler().Valid(this)) + { + Handler().Add(this); + } + } + } + } + else + { + Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL); + SetCloseAndDelete(); + } +} +#endif +#endif + + +void TcpSocket::OnRead() +{ + int n = 0; +#ifdef SOCKETS_DYNAMIC_TEMP + char *buf = m_buf; +#else + char buf[TCP_BUFSIZE_READ]; +#endif +#ifdef HAVE_OPENSSL + if (IsSSL()) + { + if (!Ready()) + return; + n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ); + if (n == -1) + { + n = SSL_get_error(m_ssl, n); + switch (n) + { + case SSL_ERROR_NONE: + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + break; + case SSL_ERROR_ZERO_RETURN: +DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");) + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + break; + default: +DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);) + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + } + return; + } + else + if (!n) + { + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + SetShutdown(SHUT_WR); + return; + } + else + if (n > 0 && n <= TCP_BUFSIZE_READ) + { + m_bytes_received += n; + if (GetTrafficMonitor()) + { + GetTrafficMonitor() -> fwrite(buf, 1, n); + } + if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) + { + Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING); + } + } + else + { + Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR); + } + } + else +#endif // HAVE_OPENSSL + { + n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL); + if (n == -1) + { + Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL); + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + return; + } + else + if (!n) + { + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + SetShutdown(SHUT_WR); + return; + } + else + if (n > 0 && n <= TCP_BUFSIZE_READ) + { + m_bytes_received += n; + if (GetTrafficMonitor()) + { + GetTrafficMonitor() -> fwrite(buf, 1, n); + } + if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) + { + Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING); + } + } + else + { + Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR); + } + } + // + OnRead( buf, n ); +} + + +void TcpSocket::OnRead( char *buf, size_t n ) +{ + // unbuffered + if (n > 0 && n <= TCP_BUFSIZE_READ) + { + if (LineProtocol()) + { + buf[n] = 0; + size_t i = 0; + if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c) + { + m_skip_c = false; + i++; + } + size_t x = i; + for (; i < n && LineProtocol(); i++) + { + while ((buf[i] == 13 || buf[i] == 10) && LineProtocol()) + { + char c = buf[i]; + buf[i] = 0; + if (buf[x]) + { + m_line += (buf + x); + } + OnLine( m_line ); + i++; + m_skip_c = true; + m_c = c; + if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c) + { + m_skip_c = false; + i++; + } + x = i; + m_line = ""; + } + if (!LineProtocol()) + { + break; + } + } + if (!LineProtocol()) + { + if (i < n) + { + OnRawData(buf + i, n - i); + } + } + else + if (buf[x]) + { + m_line += (buf + x); + } + } + else + { + OnRawData(buf, n); + } + } + if (m_b_input_buffer_disabled) + { + return; + } + // further processing: socks4 +#ifdef ENABLE_SOCKS4 + if (Socks4()) + { + bool need_more = false; + while (GetInputLength() && !need_more && !CloseAndDelete()) + { + need_more = OnSocks4Read(); + } + } +#endif +} + + +void TcpSocket::OnWriteComplete() +{ +} + + +void TcpSocket::OnWrite() +{ + if (Connecting()) + { + int err = SoError(); + + // don't reset connecting flag on error here, we want the OnConnectFailed timeout later on + if (!err) // ok + { + Set(!IsDisableRead(), false); + SetConnecting(false); + SetCallOnConnect(); + return; + } + Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL); + Set(false, false); // no more monitoring because connection failed + + // failed +#ifdef ENABLE_SOCKS4 + if (Socks4()) + { + // %! leave 'Connecting' flag set? + OnSocks4ConnectFailed(); + return; + } +#endif + if (GetConnectionRetry() == -1 || + (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) + { + // even though the connection failed at once, only retry after + // the connection timeout. + // should we even try to connect again, when CheckConnect returns + // false it's because of a connection error - not a timeout... + return; + } + SetConnecting(false); + SetCloseAndDelete( true ); + /// \todo state reason why connect failed + OnConnectFailed(); + return; + } + // try send next block in buffer + // if full block is sent, repeat + // if all blocks are sent, reset m_wfds + + bool repeat = false; + size_t sz = m_transfer_limit ? GetOutputLength() : 0; + do + { + output_l::iterator it = m_obuf.begin(); + OUTPUT *p = *it; + repeat = false; + int n = TryWrite(p -> Buf(), p -> Len()); + if (n > 0) + { + size_t left = p -> Remove(n); + m_output_length -= n; + if (!left) + { + delete p; + m_obuf.erase(it); + if (!m_obuf.size()) + { + m_obuf_top = NULL; + OnWriteComplete(); + } + else + { + repeat = true; + } + } + } + } while (repeat); + + if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit) + { + OnTransferLimit(); + } + + // check output buffer set, set/reset m_wfds accordingly + { + bool br; + bool bw; + bool bx; + Handler().Get(GetSocket(), br, bw, bx); + if (m_obuf.size()) + Set(br, true); + else + Set(br, false); + } +} + + +int TcpSocket::TryWrite(const char *buf, size_t len) +{ + int n = 0; +#ifdef HAVE_OPENSSL + if (IsSSL()) + { + n = SSL_write(m_ssl, buf, (int)len); + if (n == -1) + { + int errnr = SSL_get_error(m_ssl, n); + if ( errnr != SSL_ERROR_WANT_READ && errnr != SSL_ERROR_WANT_WRITE ) + { + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + const char *errbuf = ERR_error_string(errnr, NULL); + Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL); + } + return 0; + } + else + if (!n) + { + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); +DEB( int errnr = SSL_get_error(m_ssl, n); + const char *errbuf = ERR_error_string(errnr, NULL); + fprintf(stderr, "SSL_write() returns 0: %d : %s\n",errnr, errbuf);) + } + } + else +#endif // HAVE_OPENSSL + { + n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL); + if (n == -1) + { + // normal error codes: + // WSAEWOULDBLOCK + // EAGAIN or EWOULDBLOCK +#ifdef _WIN32 + if (Errno != WSAEWOULDBLOCK) +#else + if (Errno != EWOULDBLOCK) +#endif + { + Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL); + OnDisconnect(); + SetCloseAndDelete(true); + SetFlushBeforeClose(false); + SetLost(); + } + return 0; + } + } + if (n > 0) + { + m_bytes_sent += n; + if (GetTrafficMonitor()) + { + GetTrafficMonitor() -> fwrite(buf, 1, n); + } + } + return n; +} + + +void TcpSocket::Buffer(const char *buf, size_t len) +{ + size_t ptr = 0; + m_output_length += len; + while (ptr < len) + { + // buf/len => pbuf/sz + size_t space = 0; + if (m_obuf_top && (space = m_obuf_top -> Space()) > 0) + { + const char *pbuf = buf + ptr; + size_t sz = len - ptr; + if (space >= sz) + { + m_obuf_top -> Add(pbuf, sz); + ptr += sz; + } + else + { + m_obuf_top -> Add(pbuf, space); + ptr += space; + } + } + else + { + m_obuf_top = new OUTPUT; + m_obuf.push_back( m_obuf_top ); + } + } +} + + +void TcpSocket::Send(const std::string &str,int i) +{ + SendBuf(str.c_str(),str.size(),i); +} + + +void TcpSocket::SendBuf(const char *buf,size_t len,int) +{ + if (!Ready() && !Connecting()) + { + Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning + if (GetSocket() == INVALID_SOCKET) + Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO); + if (Connecting()) + Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO); + if (CloseAndDelete()) + Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO); + return; + } + if (!IsConnected()) + { + Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning + Buffer(buf, len); + return; + } + if (m_obuf_top) + { + Buffer(buf, len); + return; + } + int n = TryWrite(buf, len); + if (n >= 0 && n < (int)len) + { + Buffer(buf + n, len - n); + } + // if ( data in buffer || !IsConnected ) + // { + // add to buffer + // } + // else + // try_send + // if any data is unsent, buffer it and set m_wfds + + // check output buffer set, set/reset m_wfds accordingly + { + bool br; + bool bw; + bool bx; + Handler().Get(GetSocket(), br, bw, bx); + if (m_obuf.size()) + Set(br, true); + else + Set(br, false); + } +} + + +void TcpSocket::OnLine(const std::string& ) +{ +} + + +#ifdef _MSC_VER +#pragma warning(disable:4355) +#endif +TcpSocket::TcpSocket(const TcpSocket& s) +:StreamSocket(s) +,ibuf(0) +{ +} +#ifdef _MSC_VER +#pragma warning(default:4355) +#endif + + +#ifdef ENABLE_SOCKS4 +void TcpSocket::OnSocks4Connect() +{ + char request[1000]; + memset(request, 0, sizeof(request)); + request[0] = 4; // socks v4 + request[1] = 1; // command code: CONNECT + { + std::auto_ptr ad = GetClientRemoteAddress(); + if (ad.get()) + { + struct sockaddr *p0 = (struct sockaddr *)*ad; + struct sockaddr_in *p = (struct sockaddr_in *)p0; + if (p -> sin_family == AF_INET) + { + memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here + memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr)); + } + else + { + /// \todo warn + } + } + else + { + /// \todo warn + } + } + strcpy(request + 8, GetSocks4Userid().c_str()); + size_t length = GetSocks4Userid().size() + 8 + 1; + SendBuf(request, length); + m_socks4_state = 0; +} + + +void TcpSocket::OnSocks4ConnectFailed() +{ + Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING); + if (!Handler().Socks4TryDirect()) + { + SetConnecting(false); + SetCloseAndDelete(); + OnConnectFailed(); // just in case + } + else + { + SetRetryClientConnect(); + } +} + + +bool TcpSocket::OnSocks4Read() +{ + switch (m_socks4_state) + { + case 0: + ibuf.Read(&m_socks4_vn, 1); + m_socks4_state = 1; + break; + case 1: + ibuf.Read(&m_socks4_cd, 1); + m_socks4_state = 2; + break; + case 2: + if (GetInputLength() > 1) + { + ibuf.Read( (char *)&m_socks4_dstport, 2); + m_socks4_state = 3; + } + else + { + return true; + } + break; + case 3: + if (GetInputLength() > 3) + { + ibuf.Read( (char *)&m_socks4_dstip, 4); + SetSocks4(false); + + switch (m_socks4_cd) + { + case 90: + OnConnect(); + Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO); + break; + case 91: + case 92: + case 93: + Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL); + SetConnecting(false); + SetCloseAndDelete(); + OnConnectFailed(); + break; + default: + Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL); + SetCloseAndDelete(); + break; + } + } + else + { + return true; + } + break; + } + return false; +} +#endif + + +void TcpSocket::Sendf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + char slask[5000]; // vsprintf / vsnprintf temporary +#ifdef _WIN32 + vsprintf(slask, format, ap); +#else + vsnprintf(slask, 5000, format, ap); +#endif + va_end(ap); + Send( slask ); +} + + +#ifdef HAVE_OPENSSL +void TcpSocket::OnSSLConnect() +{ + SetNonblocking(true); + { + if (m_ssl_ctx) + { +DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) + SetCloseAndDelete(true); + return; + } + InitSSLClient(); + } + if (m_ssl_ctx) + { + /* Connect the SSL socket */ + m_ssl = SSL_new(m_ssl_ctx); + if (!m_ssl) + { +DEB( fprintf(stderr, " m_ssl is NULL\n");) + SetCloseAndDelete(true); + return; + } + SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); + m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); + if (!m_sbio) + { +DEB( fprintf(stderr, " m_sbio is NULL\n");) + SetCloseAndDelete(true); + return; + } + SSL_set_bio(m_ssl, m_sbio, m_sbio); + if (!SSLNegotiate()) + { + SetSSLNegotiate(); + } + } + else + { + SetCloseAndDelete(); + } +} + + +void TcpSocket::OnSSLAccept() +{ + SetNonblocking(true); + { + if (m_ssl_ctx) + { +DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) + SetCloseAndDelete(true); + return; + } + InitSSLServer(); + SetSSLServer(); + } + if (m_ssl_ctx) + { + m_ssl = SSL_new(m_ssl_ctx); + if (!m_ssl) + { +DEB( fprintf(stderr, " m_ssl is NULL\n");) + SetCloseAndDelete(true); + return; + } + SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); + m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); + if (!m_sbio) + { +DEB( fprintf(stderr, " m_sbio is NULL\n");) + SetCloseAndDelete(true); + return; + } + SSL_set_bio(m_ssl, m_sbio, m_sbio); +// if (!SSLNegotiate()) + { + SetSSLNegotiate(); + } + } +} + + +bool TcpSocket::SSLNegotiate() +{ + if (!IsSSLServer()) // client + { + int r = SSL_connect(m_ssl); + if (r > 0) + { + SetSSLNegotiate(false); + /// \todo: resurrect certificate check... client +// CheckCertificateChain( "");//ServerHOST); + SetNonblocking(false); + // + { + SetConnected(); + if (GetOutputLength()) + { + OnWrite(); + } + } +#ifdef ENABLE_RECONNECT + if (IsReconnect()) + OnReconnect(); + else +#endif + { + OnConnect(); + } + Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO); + return true; + } + else + if (!r) + { + Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO); + SetSSLNegotiate(false); + SetCloseAndDelete(); + OnSSLConnectFailed(); + } + else + { + r = SSL_get_error(m_ssl, r); + if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) + { + Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO); +DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);) + SetSSLNegotiate(false); + SetCloseAndDelete(true); + OnSSLConnectFailed(); + } + } + } + else // server + { + int r = SSL_accept(m_ssl); + if (r > 0) + { + SetSSLNegotiate(false); + /// \todo: resurrect certificate check... server +// CheckCertificateChain( "");//ClientHOST); + SetNonblocking(false); + // + { + SetConnected(); + if (GetOutputLength()) + { + OnWrite(); + } + } + OnAccept(); + Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO); + return true; + } + else + if (!r) + { + Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO); + SetSSLNegotiate(false); + SetCloseAndDelete(); + OnSSLAcceptFailed(); + } + else + { + r = SSL_get_error(m_ssl, r); + if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) + { + Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO); +DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);) + SetSSLNegotiate(false); + SetCloseAndDelete(true); + OnSSLAcceptFailed(); + } + } + } + return false; +} + + +void TcpSocket::InitSSLClient() +{ + InitializeContext("", SSLv23_method()); +} + + +void TcpSocket::InitSSLServer() +{ + Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL); + SetCloseAndDelete(); +} + + +void TcpSocket::InitializeContext(const std::string& context, SSL_METHOD *meth_in) +{ + /* Create our context*/ + static std::map client_contexts; + if (client_contexts.find(context) == client_contexts.end()) + { + SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); + m_ssl_ctx = client_contexts[context] = SSL_CTX_new(meth); + SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); + } + else + { + m_ssl_ctx = client_contexts[context]; + } +} + + +void TcpSocket::InitializeContext(const std::string& context,const std::string& keyfile,const std::string& password,SSL_METHOD *meth_in) +{ + /* Create our context*/ + static std::map server_contexts; + if (server_contexts.find(context) == server_contexts.end()) + { + SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); + m_ssl_ctx = server_contexts[context] = SSL_CTX_new(meth); + SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); + // session id + if (!context.empty()) + SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size()); + else + SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9); + } + else + { + m_ssl_ctx = server_contexts[context]; + } + + /* Load our keys and certificates*/ + if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) + { + Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL); + } + + m_password = password; + SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb); + SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this); + if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) + { + Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL); + } +} + + +void TcpSocket::InitializeContext(const std::string& context,const std::string& certfile,const std::string& keyfile,const std::string& password,SSL_METHOD *meth_in) +{ + /* Create our context*/ + static std::map server_contexts; + if (server_contexts.find(context) == server_contexts.end()) + { + SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); + m_ssl_ctx = server_contexts[context] = SSL_CTX_new(meth); + SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); + // session id + if (context.size()) + SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size()); + else + SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9); + } + else + { + m_ssl_ctx = server_contexts[context]; + } + + /* Load our keys and certificates*/ + if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, certfile.c_str(), SSL_FILETYPE_PEM))) + { + Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL); + } + + m_password = password; + SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb); + SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this); + if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) + { + Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL); + } +} + + +int TcpSocket::SSL_password_cb(char *buf,int num,int rwflag,void *userdata) +{ + Socket *p0 = static_cast(userdata); + TcpSocket *p = dynamic_cast(p0); + std::string pw = p ? p -> GetPassword() : ""; + if ( (size_t)num < pw.size() + 1) + { + return 0; + } + strcpy(buf,pw.c_str()); + return (int)pw.size(); +} +#endif // HAVE_OPENSSL + + +int TcpSocket::Close() +{ + if (GetSocket() == INVALID_SOCKET) // this could happen + { + Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING); + return 0; + } + int n; + SetNonblocking(true); + if (!Lost() && IsConnected() && !(GetShutdown() & SHUT_WR)) + { + if (shutdown(GetSocket(), SHUT_WR) == -1) + { + // failed... + Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + } + // + char tmp[1000]; + if (!Lost() && (n = recv(GetSocket(),tmp,1000,0)) >= 0) + { + if (n) + { + Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING); + } + } +#ifdef HAVE_OPENSSL + if (IsSSL() && m_ssl) + SSL_shutdown(m_ssl); + if (m_ssl) + { + SSL_free(m_ssl); + m_ssl = NULL; + } +#endif + return Socket::Close(); +} + + +#ifdef HAVE_OPENSSL +SSL_CTX *TcpSocket::GetSslContext() +{ + if (!m_ssl_ctx) + Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); + return m_ssl_ctx; +} + +SSL *TcpSocket::GetSsl() +{ + if (!m_ssl) + Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); + return m_ssl; +} +#endif + + +#ifdef ENABLE_RECONNECT +void TcpSocket::SetReconnect(bool x) +{ + m_b_reconnect = x; +} +#endif + + +void TcpSocket::OnRawData(const char *buf_in,size_t len) +{ +} + + +size_t TcpSocket::GetInputLength() +{ + return ibuf.GetLength(); +} + + +size_t TcpSocket::GetOutputLength() +{ + return m_output_length; +} + + +uint64_t TcpSocket::GetBytesReceived(bool clear) +{ + uint64_t z = m_bytes_received; + if (clear) + m_bytes_received = 0; + return z; +} + + +uint64_t TcpSocket::GetBytesSent(bool clear) +{ + uint64_t z = m_bytes_sent; + if (clear) + m_bytes_sent = 0; + return z; +} + + +#ifdef ENABLE_RECONNECT +bool TcpSocket::Reconnect() +{ + return m_b_reconnect; +} + + +void TcpSocket::SetIsReconnect(bool x) +{ + m_b_is_reconnect = x; +} + + +bool TcpSocket::IsReconnect() +{ + return m_b_is_reconnect; +} +#endif + + +#ifdef HAVE_OPENSSL +const std::string& TcpSocket::GetPassword() +{ + return m_password; +} +#endif + + +void TcpSocket::DisableInputBuffer(bool x) +{ + m_b_input_buffer_disabled = x; +} + + +void TcpSocket::OnOptions(int family,int type,int protocol,SOCKET s) +{ +DEB( fprintf(stderr, "Socket::OnOptions()\n");) +#ifdef SO_NOSIGPIPE + SetSoNosigpipe(true); +#endif + SetSoReuseaddr(true); + SetSoKeepalive(true); +} + + +void TcpSocket::SetLineProtocol(bool x) +{ + StreamSocket::SetLineProtocol(x); + DisableInputBuffer(x); +} + + +bool TcpSocket::SetTcpNodelay(bool x) +{ +#ifdef TCP_NODELAY + int optval = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1) + { + Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL); + return false; + } + return true; +#else + Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO); + return false; +#endif +} + + +TcpSocket::CircularBuffer::CircularBuffer(size_t size) +:buf(new char[2 * size]) +,m_max(size) +,m_q(0) +,m_b(0) +,m_t(0) +,m_count(0) +{ +} + + +TcpSocket::CircularBuffer::~CircularBuffer() +{ + delete[] buf; +} + + +bool TcpSocket::CircularBuffer::Write(const char *s,size_t l) +{ + if (m_q + l > m_max) + { + return false; // overflow + } + m_count += (unsigned long)l; + if (m_t + l > m_max) // block crosses circular border + { + size_t l1 = m_max - m_t; // size left until circular border crossing + // always copy full block to buffer(buf) + top pointer(m_t) + // because we have doubled the buffer size for performance reasons + memcpy(buf + m_t, s, l); + memcpy(buf, s + l1, l - l1); + m_t = l - l1; + m_q += l; + } + else + { + memcpy(buf + m_t, s, l); + memcpy(buf + m_max + m_t, s, l); + m_t += l; + if (m_t >= m_max) + m_t -= m_max; + m_q += l; + } + return true; +} + + +bool TcpSocket::CircularBuffer::Read(char *s,size_t l) +{ + if (l > m_q) + { + return false; // not enough chars + } + if (m_b + l > m_max) // block crosses circular border + { + size_t l1 = m_max - m_b; + if (s) + { + memcpy(s, buf + m_b, l1); + memcpy(s + l1, buf, l - l1); + } + m_b = l - l1; + m_q -= l; + } + else + { + if (s) + { + memcpy(s, buf + m_b, l); + } + m_b += l; + if (m_b >= m_max) + m_b -= m_max; + m_q -= l; + } + if (!m_q) + { + m_b = m_t = 0; + } + return true; +} + +bool TcpSocket::CircularBuffer::SoftRead(char *s, size_t l) +{ + if (l > m_q) + { + return false; + } + if (m_b + l > m_max) // block crosses circular border + { + size_t l1 = m_max - m_b; + if (s) + { + memcpy(s, buf + m_b, l1); + memcpy(s + l1, buf, l - l1); + } + } + else + { + if (s) + { + memcpy(s, buf + m_b, l); + } + } + return true; +} + +bool TcpSocket::CircularBuffer::Remove(size_t l) +{ + return Read(NULL, l); +} + + +size_t TcpSocket::CircularBuffer::GetLength() +{ + return m_q; +} + + +const char *TcpSocket::CircularBuffer::GetStart() +{ + return buf + m_b; +} + + +size_t TcpSocket::CircularBuffer::GetL() +{ + return (m_b + m_q > m_max) ? m_max - m_b : m_q; +} + + +size_t TcpSocket::CircularBuffer::Space() +{ + return m_max - m_q; +} + + +unsigned long TcpSocket::CircularBuffer::ByteCounter(bool clear) +{ + if (clear) + { + unsigned long x = m_count; + m_count = 0; + return x; + } + return m_count; +} + + +std::string TcpSocket::CircularBuffer::ReadString(size_t l) +{ + char *sz = new char[l + 1]; + if (!Read(sz, l)) // failed, debug printout in Read() method + { + delete[] sz; + return ""; + } + sz[l] = 0; + std::string tmp = sz; + delete[] sz; + return tmp; +} + + +void TcpSocket::OnConnectTimeout() +{ + Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL); +#ifdef ENABLE_SOCKS4 + if (Socks4()) + { + OnSocks4ConnectFailed(); + // retry direct connection + } + else +#endif + if (GetConnectionRetry() == -1 || + (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) + { + IncreaseConnectionRetries(); + // ask socket via OnConnectRetry callback if we should continue trying + if (OnConnectRetry()) + { + SetRetryClientConnect(); + } + else + { + SetCloseAndDelete( true ); + /// \todo state reason why connect failed + OnConnectFailed(); + } + } + else + { + SetCloseAndDelete(true); + /// \todo state reason why connect failed + OnConnectFailed(); + } + // + SetConnecting(false); +} + + +#ifdef _WIN32 +void TcpSocket::OnException() +{ + if (Connecting()) + { +#ifdef ENABLE_SOCKS4 + if (Socks4()) + OnSocks4ConnectFailed(); + else +#endif + if (GetConnectionRetry() == -1 || + (GetConnectionRetry() && + GetConnectionRetries() < GetConnectionRetry() )) + { + // even though the connection failed at once, only retry after + // the connection timeout + // should we even try to connect again, when CheckConnect returns + // false it's because of a connection error - not a timeout... + } + else + { + SetConnecting(false); // tnx snibbe + SetCloseAndDelete(); + OnConnectFailed(); + } + return; + } + // %! exception doesn't always mean something bad happened, this code should be reworked + // errno valid here? + int err = SoError(); + Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL); + SetCloseAndDelete(); +} +#endif // _WIN32 + + +int TcpSocket::Protocol() +{ + return IPPROTO_TCP; +} + + +void TcpSocket::SetTransferLimit(size_t sz) +{ + m_transfer_limit = sz; +} + + +void TcpSocket::OnTransferLimit() +{ +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + diff --git a/dep/src/sockets/Thread.cpp b/dep/src/sockets/Thread.cpp new file mode 100644 index 000000000..2717e32d0 --- /dev/null +++ b/dep/src/sockets/Thread.cpp @@ -0,0 +1,166 @@ +/** \file Thread.cpp + ** \date 2004-10-30 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include +#ifdef _WIN32 +#include +#include "socket_include.h" +#else +#include +#endif + +#include "Thread.h" + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +Thread::Thread(bool release) +:m_thread(0) +,m_running(true) +,m_release(false) +,m_b_delete_on_exit(false) +,m_b_destructor(false) +{ +#ifdef _WIN32 +// m_thread = ::CreateThread(NULL, 0, StartThread, this, 0, &m_dwThreadId); + m_thread = (HANDLE)_beginthreadex(NULL, 0, &StartThread, this, 0, &m_dwThreadId); +#else + pthread_attr_t attr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); + if (pthread_create(&m_thread,&attr, StartThread,this) == -1) + { + perror("Thread: create failed"); + SetRunning(false); + } +// pthread_attr_destroy(&attr); +#endif + m_release = release; +} + + +Thread::~Thread() +{ + m_b_destructor = true; + if (m_running) + { + SetRelease(true); + SetRunning(false); +#ifdef _WIN32 + Sleep(1000); +#else + sleep(1); +#endif + } +#ifdef _WIN32 + if (m_thread) + ::CloseHandle(m_thread); +#endif +} + + +threadfunc_t STDPREFIX Thread::StartThread(threadparam_t zz) +{ + Thread *p = (Thread *)zz; + + while (p -> m_running && !p -> m_release) + { +#ifdef _WIN32 + Sleep(1000); +#else + sleep(1); +#endif + } + if (p -> m_running) + { + p -> Run(); + } + p -> SetRunning(false); // if return + if (p -> DeleteOnExit() && !p -> IsDestructor()) + { + delete p; + } +#ifdef _WIN32 + _endthreadex(0); +#endif + return (threadfunc_t)NULL; +} + + +bool Thread::IsRunning() +{ + return m_running; +} + + +void Thread::SetRunning(bool x) +{ + m_running = x; +} + + +bool Thread::IsReleased() +{ + return m_release; +} + + +void Thread::SetRelease(bool x) +{ + m_release = x; +} + + +bool Thread::DeleteOnExit() +{ + return m_b_delete_on_exit; +} + + +void Thread::SetDeleteOnExit(bool x) +{ + m_b_delete_on_exit = x; +} + + +bool Thread::IsDestructor() +{ + return m_b_destructor; +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + + diff --git a/dep/src/sockets/UdpSocket.cpp b/dep/src/sockets/UdpSocket.cpp new file mode 100644 index 000000000..5d949496b --- /dev/null +++ b/dep/src/sockets/UdpSocket.cpp @@ -0,0 +1,852 @@ +/** \file UdpSocket.cpp + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifdef _WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif +#include +#else +#include +#endif + +#include "ISocketHandler.h" +#include "UdpSocket.h" +#include "Utility.h" +#include "Ipv4Address.h" +#include "Ipv6Address.h" +#ifdef ENABLE_EXCEPTIONS +#include "Exception.h" +#endif +// include this to see strange sights +//#include + + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +UdpSocket::UdpSocket(ISocketHandler& h, int ibufsz, bool ipv6, int retries) : Socket(h) +, m_ibuf(new char[ibufsz]) +, m_ibufsz(ibufsz) +, m_bind_ok(false) +, m_port(0) +, m_last_size_written(-1) +, m_retries(retries) +, m_b_read_ts(false) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + SetIpv6(ipv6); +#endif +#endif +} + + +UdpSocket::~UdpSocket() +{ + Close(); + delete[] m_ibuf; +} + + +int UdpSocket::Bind(port_t &port, int range) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(port); + return Bind(ad, range); + } +#endif +#endif + Ipv4Address ad(port); + return Bind(ad, range); +} + + +int UdpSocket::Bind(const std::string& intf, port_t &port, int range) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, range); + } + SetCloseAndDelete(); + return -1; + } +#endif +#endif + Ipv4Address ad(intf, port); + if (ad.IsValid()) + { + return Bind(ad, range); + } + SetCloseAndDelete(); + return -1; +} + + +int UdpSocket::Bind(ipaddr_t a, port_t &port, int range) +{ + Ipv4Address ad(a, port); + return Bind(ad, range); +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +int UdpSocket::Bind(in6_addr a, port_t &port, int range) +{ + Ipv6Address ad(a, port); + return Bind(ad, range); +} +#endif +#endif + + +int UdpSocket::Bind(SocketAddress& ad, int range) +{ + if (GetSocket() == INVALID_SOCKET) + { + Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); + } + if (GetSocket() != INVALID_SOCKET) + { + SetNonblocking(true); + int n = bind(GetSocket(), ad, ad); + int tries = range; + while (n == -1 && tries--) + { + ad.SetPort(ad.GetPort() + 1); + n = bind(GetSocket(), ad, ad); + } + if (n == -1) + { + Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL); + SetCloseAndDelete(); +#ifdef ENABLE_EXCEPTIONS + throw Exception("bind() failed for UdpSocket, port:range: " + Utility::l2string(ad.GetPort()) + ":" + Utility::l2string(range)); +#endif + return -1; + } + m_bind_ok = true; + m_port = ad.GetPort(); + return 0; + } + return -1; +} + + +/** if you wish to use Send, first Open a connection */ +bool UdpSocket::Open(ipaddr_t l, port_t port) +{ + Ipv4Address ad(l, port); + return Open(ad); +} + + +bool UdpSocket::Open(const std::string& host, port_t port) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(host, port); + if (ad.IsValid()) + { + return Open(ad); + } + return false; + } +#endif +#endif + Ipv4Address ad(host, port); + if (ad.IsValid()) + { + return Open(ad); + } + return false; +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +bool UdpSocket::Open(struct in6_addr& a, port_t port) +{ + Ipv6Address ad(a, port); + return Open(ad); +} +#endif +#endif + + +bool UdpSocket::Open(SocketAddress& ad) +{ + if (GetSocket() == INVALID_SOCKET) + { + Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); + } + if (GetSocket() != INVALID_SOCKET) + { + SetNonblocking(true); + if (connect(GetSocket(), ad, ad) == -1) + { + Handler().LogError(this, "connect", Errno, StrError(Errno), LOG_LEVEL_FATAL); + SetCloseAndDelete(); + return false; + } + SetConnected(); + return true; + } + return false; +} + + +void UdpSocket::CreateConnection() +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + if (GetSocket() == INVALID_SOCKET) + { + SOCKET s = CreateSocket(AF_INET6, SOCK_DGRAM, "udp"); + if (s == INVALID_SOCKET) + { + return; + } + SetNonblocking(true, s); + Attach(s); + } + return; + } +#endif +#endif + if (GetSocket() == INVALID_SOCKET) + { + SOCKET s = CreateSocket(AF_INET, SOCK_DGRAM, "udp"); + if (s == INVALID_SOCKET) + { + return; + } + SetNonblocking(true, s); + Attach(s); + } +} + + +/** send to specified address */ +void UdpSocket::SendToBuf(const std::string& h, port_t p, const char *data, int len, int flags) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + Ipv6Address ad(h, p); + if (ad.IsValid()) + { + SendToBuf(ad, data, len, flags); + } + return; + } +#endif +#endif + Ipv4Address ad(h, p); + if (ad.IsValid()) + { + SendToBuf(ad, data, len, flags); + } +} + + +/** send to specified address */ +void UdpSocket::SendToBuf(ipaddr_t a, port_t p, const char *data, int len, int flags) +{ + Ipv4Address ad(a, p); + SendToBuf(ad, data, len, flags); +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +void UdpSocket::SendToBuf(in6_addr a, port_t p, const char *data, int len, int flags) +{ + Ipv6Address ad(a, p); + SendToBuf(ad, data, len, flags); +} +#endif +#endif + + +void UdpSocket::SendToBuf(SocketAddress& ad, const char *data, int len, int flags) +{ + if (GetSocket() == INVALID_SOCKET) + { + Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); + } + if (GetSocket() != INVALID_SOCKET) + { + SetNonblocking(true); + if ((m_last_size_written = sendto(GetSocket(), data, len, flags, ad, ad)) == -1) + { + Handler().LogError(this, "sendto", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + } +} + + +void UdpSocket::SendTo(const std::string& a, port_t p, const std::string& str, int flags) +{ + SendToBuf(a, p, str.c_str(), (int)str.size(), flags); +} + + +void UdpSocket::SendTo(ipaddr_t a, port_t p, const std::string& str, int flags) +{ + SendToBuf(a, p, str.c_str(), (int)str.size(), flags); +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +void UdpSocket::SendTo(in6_addr a, port_t p, const std::string& str, int flags) +{ + SendToBuf(a, p, str.c_str(), (int)str.size(), flags); +} +#endif +#endif + + +void UdpSocket::SendTo(SocketAddress& ad, const std::string& str, int flags) +{ + SendToBuf(ad, str.c_str(), (int)str.size(), flags); +} + + +/** send to connected address */ +void UdpSocket::SendBuf(const char *data, size_t len, int flags) +{ + if (!IsConnected()) + { + Handler().LogError(this, "SendBuf", 0, "not connected", LOG_LEVEL_ERROR); + return; + } + if ((m_last_size_written = send(GetSocket(), data, (int)len, flags)) == -1) + { + Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } +} + + +void UdpSocket::Send(const std::string& str, int flags) +{ + SendBuf(str.c_str(), (int)str.size(), flags); +} + + +#if defined(LINUX) || defined(MACOSX) +int UdpSocket::ReadTS(char *ioBuf, int inBufSize, struct sockaddr *from, socklen_t fromlen, struct timeval *ts) +{ + struct msghdr msg; + struct iovec vec[1]; + union { + struct cmsghdr cm; +#ifdef MACOSX +#ifdef __DARWIN_UNIX03 +#define ALIGNBYTES __DARWIN_ALIGNBYTES +#endif +#define myALIGN(p) (((unsigned int)(p) + ALIGNBYTES) &~ ALIGNBYTES) +#define myCMSG_SPACE(l) (myALIGN(sizeof(struct cmsghdr)) + myALIGN(l)) + char data[ myCMSG_SPACE(sizeof(struct timeval)) ]; +#else + char data[ CMSG_SPACE(sizeof(struct timeval)) ]; +#endif + } cmsg_un; + struct cmsghdr *cmsg; + struct timeval *tv; + + vec[0].iov_base = ioBuf; + vec[0].iov_len = inBufSize; + + memset(&msg, 0, sizeof(msg)); + memset(from, 0, fromlen); + memset(ioBuf, 0, inBufSize); + memset(&cmsg_un, 0, sizeof(cmsg_un)); + + msg.msg_name = (caddr_t)from; + msg.msg_namelen = fromlen; + msg.msg_iov = vec; + msg.msg_iovlen = 1; + msg.msg_control = cmsg_un.data; + msg.msg_controllen = sizeof(cmsg_un.data); + msg.msg_flags = 0; + + // Original version - for reference only + //int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); + + int n = recvmsg(GetSocket(), &msg, MSG_DONTWAIT); + + // now ioBuf will contain the data, as if we used recvfrom + + // Now get the time + if(n != -1 && msg.msg_controllen >= sizeof(struct cmsghdr) && !(msg.msg_flags & MSG_CTRUNC)) + { + tv = 0; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) + { + tv = (struct timeval *)CMSG_DATA(cmsg); + } + } + if (tv) + { + memcpy(ts, tv, sizeof(struct timeval)); + } + } + // The address is in network order, but that's OK right now + return n; +} +#endif + + +void UdpSocket::OnRead() +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + struct sockaddr_in6 sa; + socklen_t sa_len = sizeof(sa); + if (m_b_read_ts) + { + struct timeval ts; + Utility::GetTime(&ts); +#if !defined(LINUX) && !defined(MACOSX) + int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); +#else + int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts); +#endif + if (n > 0) + { + this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts); + } + else + if (n == -1) + { +#ifdef _WIN32 + if (Errno != WSAEWOULDBLOCK) +#else + if (Errno != EWOULDBLOCK) +#endif + Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + return; + } + int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); + int q = m_retries; // receive max 10 at one cycle + while (n > 0) + { + if (sa_len != sizeof(sa)) + { + Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING); + } + this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len); + if (!q--) + break; + // + n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); + } + if (n == -1) + { +#ifdef _WIN32 + if (Errno != WSAEWOULDBLOCK) +#else + if (Errno != EWOULDBLOCK) +#endif + Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + return; + } +#endif +#endif + struct sockaddr_in sa; + socklen_t sa_len = sizeof(sa); + if (m_b_read_ts) + { + struct timeval ts; + Utility::GetTime(&ts); +#if !defined(LINUX) && !defined(MACOSX) + int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); +#else + int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts); +#endif + if (n > 0) + { + this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts); + } + else + if (n == -1) + { +#ifdef _WIN32 + if (Errno != WSAEWOULDBLOCK) +#else + if (Errno != EWOULDBLOCK) +#endif + Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } + return; + } + int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); + int q = m_retries; + while (n > 0) + { + if (sa_len != sizeof(sa)) + { + Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING); + } + this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len); + if (!q--) + break; + // + n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); + } + if (n == -1) + { +#ifdef _WIN32 + if (Errno != WSAEWOULDBLOCK) +#else + if (Errno != EWOULDBLOCK) +#endif + Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); + } +} + + +void UdpSocket::SetBroadcast(bool b) +{ + int one = 1; + int zero = 0; + + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } + if (b) + { + if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof(one)) == -1) + { + Handler().LogError(this, "SetBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + } + else + { + if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *) &zero, sizeof(zero)) == -1) + { + Handler().LogError(this, "SetBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + } +} + + +bool UdpSocket::IsBroadcast() +{ + int is_broadcast = 0; + socklen_t size; + + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } + if (getsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, &size) == -1) + { + Handler().LogError(this, "IsBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + return is_broadcast != 0; +} + + +void UdpSocket::SetMulticastTTL(int ttl) +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } + if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(int)) == -1) + { + Handler().LogError(this, "SetMulticastTTL", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } +} + + +int UdpSocket::GetMulticastTTL() +{ + int ttl = 0; + socklen_t size = sizeof(int); + + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } + if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_TTL, (char *)&ttl, &size) == -1) + { + Handler().LogError(this, "GetMulticastTTL", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + return ttl; +} + + +void UdpSocket::SetMulticastLoop(bool x) +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + int val = x ? 1 : 0; + if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1) + { + Handler().LogError(this, "SetMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + return; + } +#endif +#endif + int val = x ? 1 : 0; + if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1) + { + Handler().LogError(this, "SetMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } +} + + +bool UdpSocket::IsMulticastLoop() +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + int is_loop = 0; + socklen_t size = sizeof(int); + if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&is_loop, &size) == -1) + { + Handler().LogError(this, "IsMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + return is_loop ? true : false; + } +#endif +#endif + int is_loop = 0; + socklen_t size = sizeof(int); + if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&is_loop, &size) == -1) + { + Handler().LogError(this, "IsMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + return is_loop ? true : false; +} + + +void UdpSocket::AddMulticastMembership(const std::string& group, const std::string& local_if, int if_index) +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + struct ipv6_mreq x; + struct in6_addr addr; + if (Utility::u2ip( group, addr )) + { + x.ipv6mr_multiaddr = addr; + x.ipv6mr_interface = if_index; + if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1) + { + Handler().LogError(this, "AddMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + } + return; + } +#endif +#endif + struct ip_mreq x; // ip_mreqn + ipaddr_t addr; + if (Utility::u2ip( group, addr )) + { + memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr)); + Utility::u2ip( local_if, addr); + memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr)); +// x.imr_ifindex = if_index; + if (setsockopt(GetSocket(), SOL_IP, IP_ADD_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1) + { + Handler().LogError(this, "AddMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + } +} + + +void UdpSocket::DropMulticastMembership(const std::string& group, const std::string& local_if, int if_index) +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (IsIpv6()) + { + struct ipv6_mreq x; + struct in6_addr addr; + if (Utility::u2ip( group, addr )) + { + x.ipv6mr_multiaddr = addr; + x.ipv6mr_interface = if_index; + if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1) + { + Handler().LogError(this, "DropMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + } + return; + } +#endif +#endif + struct ip_mreq x; // ip_mreqn + ipaddr_t addr; + if (Utility::u2ip( group, addr )) + { + memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr)); + Utility::u2ip( local_if, addr); + memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr)); +// x.imr_ifindex = if_index; + if (setsockopt(GetSocket(), SOL_IP, IP_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1) + { + Handler().LogError(this, "DropMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + } +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +void UdpSocket::SetMulticastHops(int hops) +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } + if (!IsIpv6()) + { + Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR); + return; + } + if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, sizeof(int)) == -1) + { + Handler().LogError(this, "SetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } +} + + +int UdpSocket::GetMulticastHops() +{ + if (GetSocket() == INVALID_SOCKET) + { + CreateConnection(); + } + if (!IsIpv6()) + { + Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR); + return -1; + } + int hops = 0; + socklen_t size = sizeof(int); + if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, &size) == -1) + { + Handler().LogError(this, "GetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING); + } + return hops; +} +#endif // IPPROTO_IPV6 +#endif + + +bool UdpSocket::IsBound() +{ + return m_bind_ok; +} + + +void UdpSocket::OnRawData(const char *buf, size_t len, struct sockaddr *sa, socklen_t sa_len) +{ +} + + +void UdpSocket::OnRawData(const char *buf, size_t len, struct sockaddr *sa, socklen_t sa_len, struct timeval *ts) +{ +} + + +port_t UdpSocket::GetPort() +{ + return m_port; +} + + +int UdpSocket::GetLastSizeWritten() +{ + return m_last_size_written; +} + + +void UdpSocket::SetTimestamp(bool x) +{ + m_b_read_ts = x; +} + + +#ifdef SOCKETS_NAMESPACE +} +#endif + + diff --git a/dep/src/sockets/Utility.cpp b/dep/src/sockets/Utility.cpp new file mode 100644 index 000000000..c1327035d --- /dev/null +++ b/dep/src/sockets/Utility.cpp @@ -0,0 +1,999 @@ +/** \file Utility.cpp + ** \date 2004-02-13 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "Utility.h" +#include "Parse.h" +#include "Ipv4Address.h" +#include "Ipv6Address.h" +#include "Base64.h" +#include +#ifdef _WIN32 +#include +#else +#include +#include +#endif +#include + +#ifdef SOCKETS_NAMESPACE +namespace SOCKETS_NAMESPACE { +#endif + + +// defines for the random number generator +#define TWIST_IA 397 +#define TWIST_IB (TWIST_LEN - TWIST_IA) +#define UMASK 0x80000000 +#define LMASK 0x7FFFFFFF +#define MATRIX_A 0x9908B0DF +#define TWIST(b,i,j) ((b)[i] & UMASK) | ((b)[j] & LMASK) +#define MAGIC_TWIST(s) (((s) & 1) * MATRIX_A) + + +// statics +std::string Utility::m_host; +bool Utility::m_local_resolved = false; +ipaddr_t Utility::m_ip = 0; +std::string Utility::m_addr; +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +struct in6_addr Utility::m_local_ip6; +std::string Utility::m_local_addr6; +#endif +#endif + + +std::string Utility::base64(const std::string& str_in) +{ + std::string str; + Base64 m_b; + m_b.encode(str_in, str, false); // , false == do not add cr/lf + return str; +} + + +std::string Utility::base64d(const std::string& str_in) +{ + std::string str; + Base64 m_b; + m_b.decode(str_in, str); + return str; +} + + +std::string Utility::l2string(long l) +{ + std::string str; + char tmp[100]; + sprintf(tmp,"%ld",l); + str = tmp; + return str; +} + + +std::string Utility::bigint2string(uint64_t l) +{ + std::string str; + uint64_t tmp = l; + while (tmp) + { + uint64_t a = tmp % 10; + str = (char)(a + 48) + str; + tmp /= 10; + } + if (str.empty()) + { + str = "0"; + } + return str; +} + + +uint64_t Utility::atoi64(const std::string& str) +{ + uint64_t l = 0; + for (size_t i = 0; i < str.size(); i++) + { + l = l * 10 + str[i] - 48; + } + return l; +} + + +unsigned int Utility::hex2unsigned(const std::string& str) +{ + unsigned int r = 0; + for (size_t i = 0; i < str.size(); i++) + { + r = r * 16 + str[i] - 48 - ((str[i] >= 'A') ? 7 : 0) - ((str[i] >= 'a') ? 32 : 0); + } + return r; +} + + +/* +* Encode string per RFC1738 URL encoding rules +* tnx rstaveley +*/ +std::string Utility::rfc1738_encode(const std::string& src) +{ +static char hex[] = "0123456789ABCDEF"; + std::string dst; + for (size_t i = 0; i < src.size(); i++) + { + if (isalnum(src[i])) + { + dst += src[i]; + } + else + if (src[i] == ' ') + { + dst += '+'; + } + else + { + unsigned char c = static_cast(src[i]); + dst += '%'; + dst += hex[c / 16]; + dst += hex[c % 16]; + } + } + return dst; +} // rfc1738_encode + + +/* +* Decode string per RFC1738 URL encoding rules +* tnx rstaveley +*/ +std::string Utility::rfc1738_decode(const std::string& src) +{ + std::string dst; + for (size_t i = 0; i < src.size(); i++) + { + if (src[i] == '%' && isxdigit(src[i + 1]) && isxdigit(src[i + 2])) + { + char c1 = src[++i]; + char c2 = src[++i]; + c1 = c1 - 48 - ((c1 >= 'A') ? 7 : 0) - ((c1 >= 'a') ? 32 : 0); + c2 = c2 - 48 - ((c2 >= 'A') ? 7 : 0) - ((c2 >= 'a') ? 32 : 0); + dst += (char)(c1 * 16 + c2); + } + else + if (src[i] == '+') + { + dst += ' '; + } + else + { + dst += src[i]; + } + } + return dst; +} // rfc1738_decode + + +bool Utility::isipv4(const std::string& str) +{ + int dots = 0; + // %! ignore :port? + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] == '.') + dots++; + else + if (!isdigit(str[i])) + return false; + } + if (dots != 3) + return false; + return true; +} + + +bool Utility::isipv6(const std::string& str) +{ + size_t qc = 0; + size_t qd = 0; + for (size_t i = 0; i < str.size(); i++) + { + qc += (str[i] == ':') ? 1 : 0; + qd += (str[i] == '.') ? 1 : 0; + } + if (qc > 7) + { + return false; + } + if (qd && qd != 3) + { + return false; + } + Parse pa(str,":."); + std::string tmp = pa.getword(); + while (!tmp.empty()) + { + if (tmp.size() > 4) + { + return false; + } + for (size_t i = 0; i < tmp.size(); i++) + { + if (tmp[i] < '0' || (tmp[i] > '9' && tmp[i] < 'A') || + (tmp[i] > 'F' && tmp[i] < 'a') || tmp[i] > 'f') + { + return false; + } + } + // + tmp = pa.getword(); + } + return true; +} + + +bool Utility::u2ip(const std::string& str, ipaddr_t& l) +{ + struct sockaddr_in sa; + bool r = Utility::u2ip(str, sa); + memcpy(&l, &sa.sin_addr, sizeof(l)); + return r; +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +bool Utility::u2ip(const std::string& str, struct in6_addr& l) +{ + struct sockaddr_in6 sa; + bool r = Utility::u2ip(str, sa); + l = sa.sin6_addr; + return r; +} +#endif +#endif + + +void Utility::l2ip(const ipaddr_t ip, std::string& str) +{ + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + memcpy(&sa.sin_addr, &ip, sizeof(sa.sin_addr)); + Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST); +} + + +void Utility::l2ip(const in_addr& ip, std::string& str) +{ + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr = ip; + Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST); +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +void Utility::l2ip(const struct in6_addr& ip, std::string& str,bool mixed) +{ + char slask[100]; // l2ip temporary + *slask = 0; + unsigned int prev = 0; + bool skipped = false; + bool ok_to_skip = true; + if (mixed) + { + unsigned short x; + unsigned short addr16[8]; + memcpy(addr16, &ip, sizeof(addr16)); + for (size_t i = 0; i < 6; i++) + { + x = ntohs(addr16[i]); + if (*slask && (x || !ok_to_skip || prev)) + strcat(slask,":"); + if (x || !ok_to_skip) + { + sprintf(slask + strlen(slask),"%x", x); + if (x && skipped) + ok_to_skip = false; + } + else + { + skipped = true; + } + prev = x; + } + x = ntohs(addr16[6]); + sprintf(slask + strlen(slask),":%u.%u",x / 256,x & 255); + x = ntohs(addr16[7]); + sprintf(slask + strlen(slask),".%u.%u",x / 256,x & 255); + } + else + { + struct sockaddr_in6 sa; + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET6; + sa.sin6_addr = ip; + Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), str, NI_NUMERICHOST); + return; + } + str = slask; +} + + +int Utility::in6_addr_compare(in6_addr a,in6_addr b) +{ + for (size_t i = 0; i < 16; i++) + { + if (a.s6_addr[i] < b.s6_addr[i]) + return -1; + if (a.s6_addr[i] > b.s6_addr[i]) + return 1; + } + return 0; +} +#endif +#endif + + +void Utility::ResolveLocal() +{ + char h[256]; + + // get local hostname and translate into ip-address + *h = 0; + gethostname(h,255); + { + if (Utility::u2ip(h, m_ip)) + { + Utility::l2ip(m_ip, m_addr); + } + } +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + memset(&m_local_ip6, 0, sizeof(m_local_ip6)); + { + if (Utility::u2ip(h, m_local_ip6)) + { + Utility::l2ip(m_local_ip6, m_local_addr6); + } + } +#endif +#endif + m_host = h; + m_local_resolved = true; +} + + +const std::string& Utility::GetLocalHostname() +{ + if (!m_local_resolved) + { + ResolveLocal(); + } + return m_host; +} + + +ipaddr_t Utility::GetLocalIP() +{ + if (!m_local_resolved) + { + ResolveLocal(); + } + return m_ip; +} + + +const std::string& Utility::GetLocalAddress() +{ + if (!m_local_resolved) + { + ResolveLocal(); + } + return m_addr; +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +const struct in6_addr& Utility::GetLocalIP6() +{ + if (!m_local_resolved) + { + ResolveLocal(); + } + return m_local_ip6; +} + + +const std::string& Utility::GetLocalAddress6() +{ + if (!m_local_resolved) + { + ResolveLocal(); + } + return m_local_addr6; +} +#endif +#endif + + +void Utility::SetEnv(const std::string& var,const std::string& value) +{ +#if (defined(SOLARIS8) || defined(SOLARIS)) + { + static std::map vmap; + if (vmap.find(var) != vmap.end()) + { + delete[] vmap[var]; + } + vmap[var] = new char[var.size() + 1 + value.size() + 1]; + sprintf(vmap[var], "%s=%s", var.c_str(), value.c_str()); + putenv( vmap[var] ); + } +#elif defined _WIN32 + { + std::string slask = var + "=" + value; + _putenv( (char *)slask.c_str()); + } +#else + setenv(var.c_str(), value.c_str(), 1); +#endif +} + + +std::string Utility::Sa2String(struct sockaddr *sa) +{ +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + if (sa -> sa_family == AF_INET6) + { + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; + std::string tmp; + Utility::l2ip(sa6 -> sin6_addr, tmp); + return tmp + ":" + Utility::l2string(ntohs(sa6 -> sin6_port)); + } +#endif +#endif + if (sa -> sa_family == AF_INET) + { + struct sockaddr_in *sa4 = (struct sockaddr_in *)sa; + ipaddr_t a; + memcpy(&a, &sa4 -> sin_addr, 4); + std::string tmp; + Utility::l2ip(a, tmp); + return tmp + ":" + Utility::l2string(ntohs(sa4 -> sin_port)); + } + return ""; +} + + +void Utility::GetTime(struct timeval *p) +{ +#ifdef _WIN32 + FILETIME ft; // Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). + GetSystemTimeAsFileTime(&ft); + uint64_t tt; + memcpy(&tt, &ft, sizeof(tt)); + tt /= 10; // make it usecs + p->tv_sec = (long)tt / 1000000; + p->tv_usec = (long)tt % 1000000; +#else + gettimeofday(p, NULL); +#endif +} + + +std::auto_ptr Utility::CreateAddress(struct sockaddr *sa,socklen_t sa_len) +{ + switch (sa -> sa_family) + { + case AF_INET: + if (sa_len == sizeof(struct sockaddr_in)) + { + struct sockaddr_in *p = (struct sockaddr_in *)sa; + return std::auto_ptr(new Ipv4Address(*p)); + } + break; +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 + case AF_INET6: + if (sa_len == sizeof(struct sockaddr_in6)) + { + struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa; + return std::auto_ptr(new Ipv6Address(*p)); + } + break; +#endif +#endif + } + return std::auto_ptr(NULL); +} + + +bool Utility::u2ip(const std::string& host, struct sockaddr_in& sa, int ai_flags) +{ + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; +#ifdef NO_GETADDRINFO + if ((ai_flags & AI_NUMERICHOST) != 0 || isipv4(host)) + { + Parse pa((char *)host.c_str(), "."); + union { + struct { + unsigned char b1; + unsigned char b2; + unsigned char b3; + unsigned char b4; + } a; + ipaddr_t l; + } u; + u.a.b1 = static_cast(pa.getvalue()); + u.a.b2 = static_cast(pa.getvalue()); + u.a.b3 = static_cast(pa.getvalue()); + u.a.b4 = static_cast(pa.getvalue()); + memcpy(&sa.sin_addr, &u.l, sizeof(sa.sin_addr)); + return true; + } +#ifndef LINUX + struct hostent *he = gethostbyname( host.c_str() ); + if (!he) + { + return false; + } + memcpy(&sa.sin_addr, he -> h_addr, sizeof(sa.sin_addr)); +#else + struct hostent he; + struct hostent *result = NULL; + int myerrno = 0; + char buf[2000]; + int n = gethostbyname_r(host.c_str(), &he, buf, sizeof(buf), &result, &myerrno); + if (n || !result) + { + return false; + } + if (he.h_addr_list && he.h_addr_list[0]) + memcpy(&sa.sin_addr, he.h_addr, 4); + else + return false; +#endif + return true; +#else + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + // AI_NUMERICHOST + // AI_CANONNAME + // AI_PASSIVE - server + // AI_ADDRCONFIG + // AI_V4MAPPED + // AI_ALL + // AI_NUMERICSERV + hints.ai_flags = ai_flags; + hints.ai_family = AF_INET; + hints.ai_socktype = 0; + hints.ai_protocol = 0; + struct addrinfo *res; + if (Utility::isipv4(host)) + hints.ai_flags |= AI_NUMERICHOST; + int n = getaddrinfo(host.c_str(), NULL, &hints, &res); + if (!n) + { + std::vector vec; + struct addrinfo *ai = res; + while (ai) + { + if (ai -> ai_addrlen == sizeof(sa)) + vec.push_back( ai ); + ai = ai -> ai_next; + } + if (vec.empty()) + return false; + ai = vec[Utility::Rnd() % vec.size()]; + { + memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen); + } + freeaddrinfo(res); + return true; + } + std::string error = "Error: "; +#ifndef __CYGWIN__ + error += gai_strerror(n); +#endif + return false; +#endif // NO_GETADDRINFO +} + + +#ifdef ENABLE_IPV6 +#ifdef IPPROTO_IPV6 +bool Utility::u2ip(const std::string& host, struct sockaddr_in6& sa, int ai_flags) +{ + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET6; +#ifdef NO_GETADDRINFO + if ((ai_flags & AI_NUMERICHOST) != 0 || isipv6(host)) + { + std::list vec; + size_t x = 0; + for (size_t i = 0; i <= host.size(); i++) + { + if (i == host.size() || host[i] == ':') + { + std::string s = host.substr(x, i - x); + // + if (strstr(s.c_str(),".")) // x.x.x.x + { + Parse pa(s,"."); + char slask[100]; // u2ip temporary hex2string conversion + unsigned long b0 = static_cast(pa.getvalue()); + unsigned long b1 = static_cast(pa.getvalue()); + unsigned long b2 = static_cast(pa.getvalue()); + unsigned long b3 = static_cast(pa.getvalue()); + sprintf(slask,"%lx",b0 * 256 + b1); + vec.push_back(slask); + sprintf(slask,"%lx",b2 * 256 + b3); + vec.push_back(slask); + } + else + { + vec.push_back(s); + } + // + x = i + 1; + } + } + size_t sz = vec.size(); // number of byte pairs + size_t i = 0; // index in in6_addr.in6_u.u6_addr16[] ( 0 .. 7 ) + unsigned short addr16[8]; + for (std::list::iterator it = vec.begin(); it != vec.end(); it++) + { + std::string bytepair = *it; + if (!bytepair.empty()) + { + addr16[i++] = htons(Utility::hex2unsigned(bytepair)); + } + else + { + addr16[i++] = 0; + while (sz++ < 8) + { + addr16[i++] = 0; + } + } + } + memcpy(&sa.sin6_addr, addr16, sizeof(addr16)); + return true; + } +#ifdef SOLARIS + int errnum = 0; + struct hostent *he = getipnodebyname( host.c_str(), AF_INET6, 0, &errnum ); +#else + struct hostent *he = gethostbyname2( host.c_str(), AF_INET6 ); +#endif + if (!he) + { + return false; + } + memcpy(&sa.sin6_addr,he -> h_addr_list[0],he -> h_length); +#ifdef SOLARIS + free(he); +#endif + return true; +#else + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = ai_flags; + hints.ai_family = AF_INET6; + hints.ai_socktype = 0; + hints.ai_protocol = 0; + struct addrinfo *res; + if (Utility::isipv6(host)) + hints.ai_flags |= AI_NUMERICHOST; + int n = getaddrinfo(host.c_str(), NULL, &hints, &res); + if (!n) + { + std::vector vec; + struct addrinfo *ai = res; + while (ai) + { + if (ai -> ai_addrlen == sizeof(sa)) + vec.push_back( ai ); + ai = ai -> ai_next; + } + if (vec.empty()) + return false; + ai = vec[Utility::Rnd() % vec.size()]; + { + memcpy(&sa, ai -> ai_addr, ai -> ai_addrlen); + } + freeaddrinfo(res); + return true; + } + std::string error = "Error: "; +#ifndef __CYGWIN__ + error += gai_strerror(n); +#endif + return false; +#endif // NO_GETADDRINFO +} +#endif // IPPROTO_IPV6 +#endif // ENABLE_IPV6 + + +bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, int flags) +{ + std::string service; + return Utility::reverse(sa, sa_len, hostname, service, flags); +} + + +bool Utility::reverse(struct sockaddr *sa, socklen_t sa_len, std::string& hostname, std::string& service, int flags) +{ + hostname = ""; + service = ""; +#ifdef NO_GETADDRINFO + switch (sa -> sa_family) + { + case AF_INET: + if (flags & NI_NUMERICHOST) + { + union { + struct { + unsigned char b1; + unsigned char b2; + unsigned char b3; + unsigned char b4; + } a; + ipaddr_t l; + } u; + struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; + memcpy(&u.l, &sa_in -> sin_addr, sizeof(u.l)); + char tmp[100]; + sprintf(tmp, "%u.%u.%u.%u", u.a.b1, u.a.b2, u.a.b3, u.a.b4); + hostname = tmp; + return true; + } + else + { + struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; + struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin_addr, sizeof(sa_in -> sin_addr), AF_INET); + if (h) + { + hostname = h -> h_name; + return true; + } + } + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + if (flags & NI_NUMERICHOST) + { + char slask[100]; // l2ip temporary + *slask = 0; + unsigned int prev = 0; + bool skipped = false; + bool ok_to_skip = true; + { + unsigned short addr16[8]; + struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa; + memcpy(addr16, &sa_in6 -> sin6_addr, sizeof(addr16)); + for (size_t i = 0; i < 8; i++) + { + unsigned short x = ntohs(addr16[i]); + if (*slask && (x || !ok_to_skip || prev)) + strcat(slask,":"); + if (x || !ok_to_skip) + { + sprintf(slask + strlen(slask),"%x", x); + if (x && skipped) + ok_to_skip = false; + } + else + { + skipped = true; + } + prev = x; + } + } + if (!*slask) + strcpy(slask, "::"); + hostname = slask; + return true; + } + else + { + // %! TODO: ipv6 reverse lookup + struct sockaddr_in6 *sa_in = (struct sockaddr_in6 *)sa; + struct hostent *h = gethostbyaddr( (const char *)&sa_in -> sin6_addr, sizeof(sa_in -> sin6_addr), AF_INET6); + if (h) + { + hostname = h -> h_name; + return true; + } + } + break; +#endif + } + return false; +#else + char host[NI_MAXHOST]; + char serv[NI_MAXSERV]; + // NI_NOFQDN + // NI_NUMERICHOST + // NI_NAMEREQD + // NI_NUMERICSERV + // NI_DGRAM + int n = getnameinfo(sa, sa_len, host, sizeof(host), serv, sizeof(serv), flags); + if (n) + { + // EAI_AGAIN + // EAI_BADFLAGS + // EAI_FAIL + // EAI_FAMILY + // EAI_MEMORY + // EAI_NONAME + // EAI_OVERFLOW + // EAI_SYSTEM + return false; + } + hostname = host; + service = serv; + return true; +#endif // NO_GETADDRINFO +} + + +bool Utility::u2service(const std::string& name, int& service, int ai_flags) +{ +#ifdef NO_GETADDRINFO + // %! + return false; +#else + struct addrinfo hints; + service = 0; + memset(&hints, 0, sizeof(hints)); + // AI_NUMERICHOST + // AI_CANONNAME + // AI_PASSIVE - server + // AI_ADDRCONFIG + // AI_V4MAPPED + // AI_ALL + // AI_NUMERICSERV + hints.ai_flags = ai_flags; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = 0; + hints.ai_protocol = 0; + struct addrinfo *res; + int n = getaddrinfo(NULL, name.c_str(), &hints, &res); + if (!n) + { + service = res -> ai_protocol; + freeaddrinfo(res); + return true; + } + return false; +#endif // NO_GETADDRINFO +} + + +unsigned long Utility::ThreadID() +{ +#ifdef _WIN32 + return GetCurrentThreadId(); +#else + return (unsigned long)pthread_self(); +#endif +} + + +std::string Utility::ToLower(const std::string& str) +{ + std::string r; + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] >= 'A' && str[i] <= 'Z') + r += str[i] | 32; + else + r += str[i]; + } + return r; +} + + +std::string Utility::ToUpper(const std::string& str) +{ + std::string r; + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] >= 'a' && str[i] <= 'z') + r += (char)(str[i] - 32); + else + r += str[i]; + } + return r; +} + + +std::string Utility::ToString(double d) +{ + char tmp[100]; + sprintf(tmp, "%f", d); + return tmp; +} + + +unsigned long Utility::Rnd() +{ +static Utility::Rng generator( (unsigned long)time(NULL) ); + return generator.Get(); +} + + +Utility::Rng::Rng(unsigned long seed) : m_value( 0 ) +{ + m_tmp[0]= seed & 0xffffffffUL; + for (int i = 1; i < TWIST_LEN; i++) + { + m_tmp[i] = (1812433253UL * (m_tmp[i - 1] ^ (m_tmp[i - 1] >> 30)) + i); + } +} + + +unsigned long Utility::Rng::Get() +{ + unsigned long val = m_tmp[m_value]; + ++m_value; + if (m_value == TWIST_LEN) + { + for (int i = 0; i < TWIST_IB; ++i) + { + unsigned long s = TWIST(m_tmp, i, i + 1); + m_tmp[i] = m_tmp[i + TWIST_IA] ^ (s >> 1) ^ MAGIC_TWIST(s); + } + { + for (int i = 0; i < TWIST_LEN - 1; ++i) + { + unsigned long s = TWIST(m_tmp, i, i + 1); + m_tmp[i] = m_tmp[i - TWIST_IB] ^ (s >> 1) ^ MAGIC_TWIST(s); + } + } + unsigned long s = TWIST(m_tmp, TWIST_LEN - 1, 0); + m_tmp[TWIST_LEN - 1] = m_tmp[TWIST_IA - 1] ^ (s >> 1) ^ MAGIC_TWIST(s); + + m_value = 0; + } + return val; +} + +#ifdef SOCKETS_NAMESPACE +} +#endif + diff --git a/dep/src/sockets/network_kist.txt b/dep/src/sockets/network_kist.txt new file mode 100644 index 000000000..f6597bf9c --- /dev/null +++ b/dep/src/sockets/network_kist.txt @@ -0,0 +1,20 @@ +The following are the only .cpp files used from the new network library (v2.2.8) This file is just for future reference. + +Base64.cpp +Exception.cpp +Ipv4Address.cpp +Ipv6Address.cpp +Lock.cpp +Mutex.cpp +Parse.cpp +ResolvServer.cpp +ResolvSocket.cpp +Socket.cpp +SocketHandler.cpp +socket_include.cpp +StdoutLog.cpp +StreamSocket.cpp +TcpSocket.cpp +Thread.cpp +UdpSocket.cpp +Utility.cpp diff --git a/dep/src/sockets/socket_include.cpp b/dep/src/sockets/socket_include.cpp new file mode 100644 index 000000000..07b986b02 --- /dev/null +++ b/dep/src/sockets/socket_include.cpp @@ -0,0 +1,90 @@ +/** \file socket_include.cpp + ** \date 2004-11-28 + ** \author grymse@alhem.net +**/ +/* +Copyright (C) 2004-2007 Anders Hedstrom + +This library is made available under the terms of the GNU GPL. + +If you would like to use this library in a closed-source application, +a separate license agreement is available. For information about +the closed-source license agreement for the C++ sockets library, +please visit http://www.alhem.net/Sockets/license.html and/or +email license@alhem.net. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include + +// only to be included in win32 projects +const char *StrError(int x) +{ +static char tmp[100]; + switch (x) + { + case 10004: return "Interrupted function call."; + case 10013: return "Permission denied."; + case 10014: return "Bad address."; + case 10022: return "Invalid argument."; + case 10024: return "Too many open files."; + case 10035: return "Resource temporarily unavailable."; + case 10036: return "Operation now in progress."; + case 10037: return "Operation already in progress."; + case 10038: return "Socket operation on nonsocket."; + case 10039: return "Destination address required."; + case 10040: return "Message too long."; + case 10041: return "Protocol wrong type for socket."; + case 10042: return "Bad protocol option."; + case 10043: return "Protocol not supported."; + case 10044: return "Socket type not supported."; + case 10045: return "Operation not supported."; + case 10046: return "Protocol family not supported."; + case 10047: return "Address family not supported by protocol family."; + case 10048: return "Address already in use."; + case 10049: return "Cannot assign requested address."; + case 10050: return "Network is down."; + case 10051: return "Network is unreachable."; + case 10052: return "Network dropped connection on reset."; + case 10053: return "Software caused connection abort."; + case 10054: return "Connection reset by peer."; + case 10055: return "No buffer space available."; + case 10056: return "Socket is already connected."; + case 10057: return "Socket is not connected."; + case 10058: return "Cannot send after socket shutdown."; + case 10060: return "Connection timed out."; + case 10061: return "Connection refused."; + case 10064: return "Host is down."; + case 10065: return "No route to host."; + case 10067: return "Too many processes."; + case 10091: return "Network subsystem is unavailable."; + case 10092: return "Winsock.dll version out of range."; + case 10093: return "Successful WSAStartup not yet performed."; + case 10101: return "Graceful shutdown in progress."; + case 10109: return "Class type not found."; + case 11001: return "Host not found."; + case 11002: return "Nonauthoritative host not found."; + case 11003: return "This is a nonrecoverable error."; + case 11004: return "Valid name, no data record of requested type."; + + default: + break; + } + sprintf(tmp, "Winsock error code: %d", x); + return tmp; +} + + + diff --git a/dep/src/zlib/Makefile.am b/dep/src/zlib/Makefile.am new file mode 100644 index 000000000..70eafcf76 --- /dev/null +++ b/dep/src/zlib/Makefile.am @@ -0,0 +1,56 @@ +## Modified for MaNGOS project +## +## Permission is hereby granted, free of charge, to any person obtaining a copy +## of this software and associated documentation files (the "Software"), to deal +## in the Software without restriction, including without limitation the rights +## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +## copies of the Software, and to permit persons to whom the Software is furnished +## to do so, subject to the following conditions: +## +## The above copyright notice and this permission notice shall be included in all +## copies or substantial portions of the Software. +## +## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Process this file with automake to produce Makefile.in + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../../include -I$(srcdir)/../../include/zlib + +## Build zlib as convenience library. +# libzlib conveniece library will later be reused by ... +noinst_LIBRARIES = libzlib.a +libzlib_a_SOURCES = \ + adler32.c \ + compress.c \ + crc32.c \ + deflate.c \ + example.c \ + gzio.c \ + infback.c \ + inffast.c \ + inflate.c \ + inftrees.c \ + trees.c \ + uncompr.c \ + zutil.c + +## Additional files to include when running 'make dist' +# Nothing yet. +EXTRA_DIST = \ + crc32.h \ + deflate.h \ + inffast.h \ + inffixed.h \ + inflate.h \ + inftrees.h \ + trees.h \ + zconf.h \ + zlib.h \ + zutil.h + diff --git a/dep/src/zlib/adler32.c b/dep/src/zlib/adler32.c new file mode 100644 index 000000000..007ba2627 --- /dev/null +++ b/dep/src/zlib/adler32.c @@ -0,0 +1,149 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/dep/src/zlib/compress.c b/dep/src/zlib/compress.c new file mode 100644 index 000000000..df04f0148 --- /dev/null +++ b/dep/src/zlib/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/dep/src/zlib/crc32.c b/dep/src/zlib/crc32.c new file mode 100644 index 000000000..f658a9ef5 --- /dev/null +++ b/dep/src/zlib/crc32.c @@ -0,0 +1,423 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/dep/src/zlib/crc32.h b/dep/src/zlib/crc32.h new file mode 100644 index 000000000..8053b6117 --- /dev/null +++ b/dep/src/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/dep/src/zlib/deflate.c b/dep/src/zlib/deflate.c new file mode 100644 index 000000000..29ce1f64a --- /dev/null +++ b/dep/src/zlib/deflate.c @@ -0,0 +1,1736 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/dep/src/zlib/deflate.h b/dep/src/zlib/deflate.h new file mode 100644 index 000000000..05a5ab3a2 --- /dev/null +++ b/dep/src/zlib/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/dep/src/zlib/example.c b/dep/src/zlib/example.c new file mode 100644 index 000000000..6c8a0ee76 --- /dev/null +++ b/dep/src/zlib/example.c @@ -0,0 +1,565 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2004 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include +#include "zlib.h" + +#ifdef STDC +# include +# include +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *fname, + Byte *uncompr, uLong uncomprLen)); +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = (uLong)strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(fname, uncompr, uncomprLen) + const char *fname; /* compressed file name */ + Byte *uncompr; + uLong uncomprLen; +{ +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + int len = (int)strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(fname, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(fname, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + strcpy((char*)uncompr, "garbage"); + + if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char*)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + if (gzungetc(' ', file) != ' ') { + fprintf(stderr, "gzungetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) { /* " hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello + 6)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + } + + gzclose(file); +#endif +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uLong len = (uLong)strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uInt len = (uInt)strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", + ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/dep/src/zlib/gzio.c b/dep/src/zlib/gzio.c new file mode 100644 index 000000000..7e90f4928 --- /dev/null +++ b/dep/src/zlib/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id$ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/dep/src/zlib/infback.c b/dep/src/zlib/infback.c new file mode 100644 index 000000000..455dbc9ee --- /dev/null +++ b/dep/src/zlib/infback.c @@ -0,0 +1,623 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->write = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + + /* process literal */ + if (this.op == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/dep/src/zlib/inffast.c b/dep/src/zlib/inffast.c new file mode 100644 index 000000000..bbee92ed1 --- /dev/null +++ b/dep/src/zlib/inffast.c @@ -0,0 +1,318 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/dep/src/zlib/inffast.h b/dep/src/zlib/inffast.h new file mode 100644 index 000000000..1e88d2d97 --- /dev/null +++ b/dep/src/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/dep/src/zlib/inffixed.h b/dep/src/zlib/inffixed.h new file mode 100644 index 000000000..75ed4b597 --- /dev/null +++ b/dep/src/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/dep/src/zlib/inflate.c b/dep/src/zlib/inflate.c new file mode 100644 index 000000000..792fdee8e --- /dev/null +++ b/dep/src/zlib/inflate.c @@ -0,0 +1,1368 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/dep/src/zlib/inflate.h b/dep/src/zlib/inflate.h new file mode 100644 index 000000000..07bd3e78a --- /dev/null +++ b/dep/src/zlib/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/dep/src/zlib/inftrees.c b/dep/src/zlib/inftrees.c new file mode 100644 index 000000000..8a9c13ff0 --- /dev/null +++ b/dep/src/zlib/inftrees.c @@ -0,0 +1,329 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)1; + this.val = (unsigned short)0; + *(*table)++ = this; /* make a table to force an error */ + *(*table)++ = this; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/dep/src/zlib/inftrees.h b/dep/src/zlib/inftrees.h new file mode 100644 index 000000000..b1104c87e --- /dev/null +++ b/dep/src/zlib/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/dep/src/zlib/trees.c b/dep/src/zlib/trees.c new file mode 100644 index 000000000..395e4e168 --- /dev/null +++ b/dep/src/zlib/trees.c @@ -0,0 +1,1219 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) + deflate_state *s; +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/dep/src/zlib/trees.h b/dep/src/zlib/trees.h new file mode 100644 index 000000000..72facf900 --- /dev/null +++ b/dep/src/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/dep/src/zlib/uncompr.c b/dep/src/zlib/uncompr.c new file mode 100644 index 000000000..b59e3d0de --- /dev/null +++ b/dep/src/zlib/uncompr.c @@ -0,0 +1,61 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/dep/src/zlib/zconf.h b/dep/src/zlib/zconf.h new file mode 100644 index 000000000..03a9431c8 --- /dev/null +++ b/dep/src/zlib/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/dep/src/zlib/zlib.h b/dep/src/zlib/zlib.h new file mode 100644 index 000000000..022817927 --- /dev/null +++ b/dep/src/zlib/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/dep/src/zlib/zutil.c b/dep/src/zlib/zutil.c new file mode 100644 index 000000000..d55f5948a --- /dev/null +++ b/dep/src/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/dep/src/zlib/zutil.h b/dep/src/zlib/zutil.h new file mode 100644 index 000000000..b7d5eff81 --- /dev/null +++ b/dep/src/zlib/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/dep/src/zthread/AtomicCount.cxx b/dep/src/zthread/AtomicCount.cxx new file mode 100644 index 000000000..ac0d0773b --- /dev/null +++ b/dep/src/zthread/AtomicCount.cxx @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTATOMICCOUNTSELECT_H__ +#define __ZTATOMICCOUNTSELECT_H__ + +#include "zthread/AtomicCount.h" +#include "zthread/Config.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* +// Select the correct AtomicCount implementation based on +// what the compilation environment has defined + +#ifndef ZT_VANILLA + +#if defined(HAVE_ATOMIC_LINUX) +# include "linux/AtomicCount.cxx" +#elif defined(ZT_WIN32) +# include "win32/AtomicCount.cxx" +#elif defined(ZT_WIN9X) +# include "win9x/AtomicCount.cxx" +#endif + +#endif + +// Default to an AtomicCount that just uses a FastLock +#ifndef __ZTATOMICCOUNTIMPL_H__ +# include "vanilla/SimpleAtomicCount.cxx" +#endif +*/ + +# include "vanilla/SimpleAtomicCount.cxx" + +#endif // __ZTATOMICCOUNTSELECT_H__ diff --git a/dep/src/zthread/ConcurrentExecutor.cxx b/dep/src/zthread/ConcurrentExecutor.cxx new file mode 100644 index 000000000..a65e9c5e9 --- /dev/null +++ b/dep/src/zthread/ConcurrentExecutor.cxx @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/ConcurrentExecutor.h" + +namespace ZThread { + + ConcurrentExecutor::ConcurrentExecutor() + : _executor(1) {} + + void ConcurrentExecutor::interrupt() { + _executor.interrupt(); + } + + void ConcurrentExecutor::execute(const Task& task) { + _executor.execute(task); + } + + void ConcurrentExecutor::cancel() { + _executor.cancel(); + } + + bool ConcurrentExecutor::isCanceled() { + return _executor.isCanceled(); + } + + void ConcurrentExecutor::wait() { + _executor.wait(); + } + + bool ConcurrentExecutor::wait(unsigned long timeout) { + return _executor.wait(timeout); + } + +} diff --git a/dep/src/zthread/Condition.cxx b/dep/src/zthread/Condition.cxx new file mode 100644 index 000000000..39485fb5c --- /dev/null +++ b/dep/src/zthread/Condition.cxx @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/Condition.h" +#include "ConditionImpl.h" + +namespace ZThread { + + class FifoConditionImpl : public ConditionImpl { + public: + FifoConditionImpl(Lockable& l) : ConditionImpl(l) {} + + }; + + Condition::Condition(Lockable& lock) { + + _impl = new FifoConditionImpl(lock); + + } + + + Condition::~Condition() { + + if(_impl != 0) + delete _impl; + + } + + + + void Condition::wait() { + + _impl->wait(); + + } + + + + bool Condition::wait(unsigned long ms) { + + return _impl->wait(ms); + + } + + + + void Condition::signal() { + + _impl->signal(); + + } + + + void Condition::broadcast() { + + _impl->broadcast(); + + } + +} // namespace ZThread + diff --git a/dep/src/zthread/ConditionImpl.h b/dep/src/zthread/ConditionImpl.h new file mode 100644 index 000000000..eeeaba10b --- /dev/null +++ b/dep/src/zthread/ConditionImpl.h @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTCONDITIONIMPL_H__ +#define __ZTCONDITIONIMPL_H__ + +#include "zthread/Guard.h" + +#include "Debug.h" +#include "Scheduling.h" +#include "DeferredInterruptionScope.h" + +namespace ZThread { + +/** + * @class ConditionImpl + * @author Eric Crahen + * @date <2003-07-18T08:15:37-0400> + * @version 2.2.11 + * + * The ConditionImpl template allows how waiter lists are sorted + * to be parameteized + */ +template +class ConditionImpl { + + //! Waiters currently blocked + List _waiters; + + //! Serialize access to this object + FastLock _lock; + + //! External lock + Lockable& _predicateLock; + + public: + + /** + * Create a new ConditionImpl. + * + * @exception Initialization_Exception thrown if resources could not be + * allocated + */ + ConditionImpl(Lockable& predicateLock) : _predicateLock(predicateLock) { + + } + + /** + * Destroy this ConditionImpl, release its resources + */ + ~ConditionImpl(); + + void signal(); + + void broadcast(); + + void wait(); + + bool wait(unsigned long timeout); + +}; + + +template +ConditionImpl::~ConditionImpl() { + +#ifndef NDEBUG + + // It is an error to destroy a condition with threads waiting on it. + if(!_waiters.empty()) { + + ZTDEBUG("** You are destroying a condition variable which still has waiting threads. **\n"); + assert(0); + + } + +#endif + + } + + +/** + * Signal the condition variable, waking one thread if any. + */ +template +void ConditionImpl::signal() { + + Guard g1(_lock); + + // Try to find a waiter with a backoff & retry scheme + for(;;) { + + // Go through the list, attempt to notify() a waiter. + for(typename List::iterator i = _waiters.begin(); i != _waiters.end();) { + + // Try the monitor lock, if it cant be locked skip to the next waiter + ThreadImpl* impl = *i; + Monitor& m = impl->getMonitor(); + + if(m.tryAcquire()) { + + // Notify the monitor & remove from the waiter list so time isn't + // wasted checking it again. + i = _waiters.erase(i); + + // If notify() is not sucessful, it is because the wait() has already + // been ended (killed/interrupted/notify'd) + bool woke = m.notify(); + + m.release(); + + // Once notify() succeeds, return + if(woke) + return; + + } else ++i; + + } + + if(_waiters.empty()) + return; + + { // Backoff and try again + + Guard g2(g1); + ThreadImpl::yield(); + + } + + } + + } + +/** + * Broadcast to the condition variable, waking all threads waiting at the time of + * the broadcast. + */ +template +void ConditionImpl::broadcast() { + + Guard g1(_lock); + + // Try to find a waiter with a backoff & retry scheme + for(;;) { + + // Go through the list, attempt to notify() a waiter. + for(typename List::iterator i = _waiters.begin(); i != _waiters.end();) { + + // Try the monitor lock, if it cant be locked skip to the next waiter + ThreadImpl* impl = *i; + Monitor& m = impl->getMonitor(); + + if(m.tryAcquire()) { + + // Notify the monitor & remove from the waiter list so time isn't + // wasted checking it again. + i = _waiters.erase(i); + + // Try to wake the waiter, it doesn't matter if this is successful + // or not (only fails when the monitor is already going to stop waiting). + m.notify(); + + m.release(); + + } else ++i; + + } + + if(_waiters.empty()) + return; + + { // Backoff and try again + + Guard g2(g1); + ThreadImpl::yield(); + + } + + } + + } + +/** + * Cause the currently executing thread to block until this ConditionImpl has + * been signaled, the threads state changes. + * + * @param predicate Lockable& + * + * @exception Interrupted_Exception thrown when the caller status is interrupted + * @exception Synchronization_Exception thrown if there is some other error. + */ +template +void ConditionImpl::wait() { + + // Get the monitor for the current thread + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Monitor::STATE state; + + { + + Guard g1(_lock); + + // Release the _predicateLock + _predicateLock.release(); + + // Stuff the waiter into the list + _waiters.insert(self); + + // Move to the monitor's lock + m.acquire(); + + { + + Guard g2(g1); + state = m.wait(); + + } + + // Move back to the Condition's lock + m.release(); + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + typename List::iterator i = std::find(_waiters.begin(), _waiters.end(), self); + if(i != _waiters.end()) + _waiters.erase(i); + + } + + // Defer interruption until the external lock is acquire()d + Guard g3(m); + { + +#if !defined(NDEBUG) + try { +#endif + _predicateLock.acquire(); // Should not throw +#if !defined(NDEBUG) + } catch(...) { assert(0); } +#endif + + } + + switch(state) { + + case Monitor::SIGNALED: + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + default: + throw Synchronization_Exception(); + } + + } + + +/** + * Cause the currently executing thread to block until this ConditionImpl has + * been signaled, or the timeout expires or the threads state changes. + * + * @param _predicateLock Lockable& + * @param timeout maximum milliseconds to block. + * + * @return bool + * + * @exception Interrupted_Exception thrown when the caller status is interrupted + * @exception Synchronization_Exception thrown if there is some other error. + */ +template +bool ConditionImpl::wait(unsigned long timeout) { + + // Get the monitor for the current thread + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Monitor::STATE state; + + { + + Guard g1(_lock); + + // Release the _predicateLock + _predicateLock.release(); + + // Stuff the waiter into the list + _waiters.insert(self); + + state = Monitor::TIMEDOUT; + + // Don't bother waiting if the timeout is 0 + if(timeout) { + + m.acquire(); + + { + + Guard g2(g1); + state = m.wait(timeout); + + } + + m.release(); + + } + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + typename List::iterator i = std::find(_waiters.begin(), _waiters.end(), self); + if(i != _waiters.end()) + _waiters.erase(i); + + } + + + // Defer interruption until the external lock is acquire()d + Guard g3(m); + { + +#if !defined(NDEBUG) + try { +#endif + _predicateLock.acquire(); // Should not throw +#if !defined(NDEBUG) + } catch(...) { assert(0); } +#endif + + } + + switch(state) { + + case Monitor::SIGNALED: + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + case Monitor::TIMEDOUT: + return false; + + default: + throw Synchronization_Exception(); + } + + return true; + + } + +} // namespace ZThread + +#endif // __ZTCONDITIONIMPL_H__ diff --git a/dep/src/zthread/CountingSemaphore.cxx b/dep/src/zthread/CountingSemaphore.cxx new file mode 100644 index 000000000..43e8b8cfb --- /dev/null +++ b/dep/src/zthread/CountingSemaphore.cxx @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/CountingSemaphore.h" +#include "SemaphoreImpl.h" + +using namespace ZThread; + +namespace ZThread { + + + CountingSemaphore::CountingSemaphore(int initialCount) { + + _impl = new FifoSemaphoreImpl(initialCount, 0 , false); + + } + + + CountingSemaphore::~CountingSemaphore() { + + try { + + if(_impl != 0) + delete _impl; + + } catch(...) { } + + } + + + void CountingSemaphore::wait() { + _impl->acquire(); + } + + + bool CountingSemaphore::tryWait(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + + void CountingSemaphore::post() { + + _impl->release(); + + } + + int CountingSemaphore::count() { + + return _impl->count(); + + } + + void CountingSemaphore::acquire() { + + _impl->acquire(); + + } + + bool CountingSemaphore::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + void CountingSemaphore::release() { + + _impl->release(); + + } + +} // namespace ZThread diff --git a/dep/src/zthread/Debug.h b/dep/src/zthread/Debug.h new file mode 100644 index 000000000..484b37f7d --- /dev/null +++ b/dep/src/zthread/Debug.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef ZTDEBUG + +#ifndef NDEBUG +# include +# define ZTDEBUG printf +#else +# define ZTDEBUG(x) +#endif + +#endif diff --git a/dep/src/zthread/DeferredInterruptionScope.h b/dep/src/zthread/DeferredInterruptionScope.h new file mode 100644 index 000000000..041d1e427 --- /dev/null +++ b/dep/src/zthread/DeferredInterruptionScope.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTDEFERREDINTERRUPTIONSCOPE_H__ +#define __ZTDEFERREDINTERRUPTIONSCOPE_H__ + +#include "ThreadImpl.h" +#include + +namespace ZThread { + +/** + * @class DeferredInterruptionScope + * @author Eric Crahen + * @date <2003-07-16T19:45:18-0400> + * @version 2.3.0 + * + * Locking policy for a Guard that will defer any state reported + * for the reported Status of a thread except SIGNALED until the + * scope has ended. This allows a Guard to be used to create an + * uninterruptible region in code. + */ +class DeferredInterruptionScope { + public: + + template + static void createScope(LockHolder& l) { + + l.getLock().interest(Monitor::SIGNALED); + + } + + template + static void destroyScope(LockHolder& l) { + + l.getLock().interest(Monitor::ANYTHING); + + } + +}; + +} + +#endif // __ZTDEFERREDINTERRUPTIONSCOPE_H__ diff --git a/dep/src/zthread/FastLock.h b/dep/src/zthread/FastLock.h new file mode 100644 index 000000000..4d7f34a08 --- /dev/null +++ b/dep/src/zthread/FastLock.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCKSELECT_H__ +#define __ZTFASTLOCKSELECT_H__ + +#include "zthread/Config.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// Select the correct FastLock implementation based on +// what the compilation environment has defined + +#if defined(ZT_POSIX) + +# if defined(HAVE_ATOMIC_LINUX) + +# if defined(ZTHREAD_USE_SPIN_LOCKS) +# include "linux/AtomicFastLock.h" +# endif + +# endif + +# include "posix/FastLock.h" + +// Use spin locks +#elif defined(ZTHREAD_USE_SPIN_LOCKS) + +# if defined(ZT_WIN9X) +# include "win9x/AtomicFastLock.h" +# elif defined(ZT_WIN32) +# include "win32/AtomicFastLock.h" +# endif + +// Use normal Mutex objects +#elif defined(ZT_WIN9X) || defined(ZT_WIN32) + +# include "win32/FastLock.h" + +#elif defined(ZT_MACOS) + +# include "macos/FastLock.h" + +#endif + +#ifndef __ZTFASTLOCK_H__ +#error "No FastLock implementation could be selected" +#endif + +#endif // __ZTFASTLOCKSELECT_H__ diff --git a/dep/src/zthread/FastMutex.cxx b/dep/src/zthread/FastMutex.cxx new file mode 100644 index 000000000..464dd83e5 --- /dev/null +++ b/dep/src/zthread/FastMutex.cxx @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/FastMutex.h" +#include "FastLock.h" + +namespace ZThread { + + FastMutex::FastMutex() : _lock(new FastLock) { } + + FastMutex::~FastMutex() { + delete _lock; + } + + + void FastMutex::acquire() { + + _lock->acquire(); + + } + + bool FastMutex::tryAcquire(unsigned long timeout) { + + return _lock->tryAcquire(timeout); + + } + + void FastMutex::release() { + + _lock->release(); + + } + +} // namespace ZThread diff --git a/dep/src/zthread/FastRecursiveLock.h b/dep/src/zthread/FastRecursiveLock.h new file mode 100644 index 000000000..0a36f62d5 --- /dev/null +++ b/dep/src/zthread/FastRecursiveLock.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCKSELECT_H__ +#define __ZTFASTRECURSIVELOCKSELECT_H__ + +#include "zthread/Config.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +// Select the correct FastRecusriveLock implementation based on +// what the compilation environment has defined + +#if defined(ZTHREAD_DUAL_LOCKS) +# include "vanilla/DualMutexRecursiveLock.h" +#else + +# ifndef ZT_VANILLA + +# if defined(ZT_POSIX) + +// Linux and Solaris have working pthreads recursive locks. These +// are created differently, and there are some system don't seem to +// include recursive locks at all. Several recursive implementations +// are provided + +# if defined(__linux__) +# include "linux/FastRecursiveLock.h" +# elif defined(HAVE_MUTEXATTR_SETTYPE) +# include "solaris/FastRecursiveLock.h" +# elif defined(ZTHREAD_CONDITION_LOCKS) +# include "posix/ConditionRecursiveLock.h" +# endif + +// Use spin locks +# elif defined(ZT_WIN32) && defined(ZTHREAD_USE_SPIN_LOCKS) +# include "win32/AtomicFastRecursiveLock.h" + +// Use normal Mutex objects +# elif defined(ZT_WIN32) || defined(ZT_WIN9X) +# include "win32/FastRecursiveLock.h" +# endif + +# endif + +#endif + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#include "vanilla/SimpleRecursiveLock.h" +#endif + +#endif // __ZTFASTRECURSIVELOCKSELECT_H__ diff --git a/dep/src/zthread/FastRecursiveMutex.cxx b/dep/src/zthread/FastRecursiveMutex.cxx new file mode 100644 index 000000000..5ca677a65 --- /dev/null +++ b/dep/src/zthread/FastRecursiveMutex.cxx @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/FastRecursiveMutex.h" +#include "FastRecursiveLock.h" + +namespace ZThread { + + FastRecursiveMutex::FastRecursiveMutex() + : _lock(new FastRecursiveLock) { } + + FastRecursiveMutex::~FastRecursiveMutex() + { delete _lock; } + + + void FastRecursiveMutex::acquire() { + + _lock->acquire(); + + } + + bool FastRecursiveMutex::tryAcquire(unsigned long timeout) { + + return _lock->tryAcquire(timeout); + + } + + void FastRecursiveMutex::release() { + + _lock->release(); + + } + +} // namespace ZThread diff --git a/dep/src/zthread/IntrusivePtr.h b/dep/src/zthread/IntrusivePtr.h new file mode 100644 index 000000000..47d5afbfc --- /dev/null +++ b/dep/src/zthread/IntrusivePtr.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTINTRUSIVEPTR_H__ +#define __ZTINTRUSIVEPTR_H__ + +#include "zthread/Guard.h" +#include + +namespace ZThread { + +/** + * @class IntrusivePtr + * @author Eric Crahen + * @date <2003-07-16T17:54:23-0400> + * @version 2.2.0 + * + * This template creates an intrusively reference counted object + * an IntrusivePtr starts out with a 1 count, which is updated as references are + * added and removed. When the reference count drops to 0, the + * IntrusivePtr will delete itself. + */ +template +class IntrusivePtr : NonCopyable { + + //! Intrusive reference count + size_t _count; + + //! Synchornization object + LockType _lock; + +public: + + /** + * Create an IntrusivePtr with a count. + */ + IntrusivePtr(size_t InitialCount=1) : _count(InitialCount) { } + + /** + * Destroy an IntrusivePtr + */ + virtual ~IntrusivePtr() {} + + /** + * Add a reference to this object, it will take one more + * call to delReference() for it to be deleted. + */ + void addReference() { + + Guard g(_lock); + _count++; + + } + + /** + * Remove a reference from this object, if the reference count + * drops to 0 as a result, the object deletes itself. + */ + void delReference() { + + bool result = false; + + { + + Guard g(_lock); + result = (--_count == 0); + + } + + if(result) + delete this; + + } + +}; + + +}; + +#endif diff --git a/dep/src/zthread/Makefile.am b/dep/src/zthread/Makefile.am new file mode 100644 index 000000000..8946471e3 --- /dev/null +++ b/dep/src/zthread/Makefile.am @@ -0,0 +1,132 @@ +## Copyright (c) 2005, Eric Crahen +## Modified for MaNGOS project +## +## Permission is hereby granted, free of charge, to any person obtaining a copy +## of this software and associated documentation files (the "Software"), to deal +## in the Software without restriction, including without limitation the rights +## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +## copies of the Software, and to permit persons to whom the Software is furnished +## to do so, subject to the following conditions: +## +## The above copyright notice and this permission notice shall be included in all +## copies or substantial portions of the Software. +## +## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Process this file with automake to produce Makefile.in + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../include/zthread + +## Build ZThread as shared library. +# libZThread shared library will later be reused by realm list daemon +# and world server daemon. +lib_LTLIBRARIES = libZThread.la +libZThread_la_SOURCES = \ + AtomicCount.cxx \ + Condition.cxx \ + ConcurrentExecutor.cxx \ + CountingSemaphore.cxx \ + FastMutex.cxx \ + FastRecursiveMutex.cxx \ + Mutex.cxx \ + RecursiveMutexImpl.cxx \ + RecursiveMutex.cxx \ + Monitor.cxx \ + PoolExecutor.cxx \ + PriorityCondition.cxx \ + PriorityInheritanceMutex.cxx \ + PriorityMutex.cxx \ + PrioritySemaphore.cxx \ + Semaphore.cxx \ + SynchronousExecutor.cxx \ + Thread.cxx \ + ThreadedExecutor.cxx \ + ThreadImpl.cxx \ + ThreadLocalImpl.cxx \ + ThreadQueue.cxx \ + Time.cxx \ + ThreadOps.cxx + +## libtool settings +# API versioning +# Link against dependencies +# How to increase version info: +# - only bug fixes implemented: +# bump the version to LTZTHREAD_CURRENT:LTZTHREAD_REVISION+1:LTZTHREAD_AGE +# - augmented the interface: +# bump the version to LTZTHREAD_CURRENT+1:0:LTZTHREAD_AGE+1 +# - broken old interface: +# bump the version to LTZTHREAD_CURRENT+1:0:0 +LTZTHREAD_CURRENT = 2 +LTZTHREAD_REVISION = 3 +LTZTHREAD_AGE = 2 +libZThread_la_LDFLAGS = -version-info $(LTZTHREAD_CURRENT):$(LTZTHREAD_REVISION):$(LTZTHREAD_AGE) + +## Additional files to include when running 'make dist' +# Header files. +EXTRA_DIST = \ + ConditionImpl.h \ + Debug.h \ + DeferredInterruptionScope.h \ + FastLock.h \ + FastRecursiveLock.h \ + IntrusivePtr.h \ + Monitor.h \ + MutexImpl.h \ + RecursiveMutexImpl.h \ + Scheduling.h \ + SemaphoreImpl.h \ + State.h \ + Status.h \ + TSS.h \ + ThreadImpl.h \ + ThreadOps.h \ + ThreadQueue.h \ + TimeStrategy.h \ + config.h + +# Implementation specific files. +EXTRA_DIST += \ + linux/AtomicCount.cxx \ + linux/AtomicFastLock.h \ + linux/FastRecursiveLock.h \ + macos/FastLock.h \ + macos/Monitor.cxx \ + macos/Monitor.h \ + macos/TSS.h \ + macos/ThreadOps.cxx \ + macos/ThreadOps.h \ + macos/UpTimeStrategy.h \ + posix/ConditionRecursiveLock.h \ + posix/FastLock.h \ + posix/FtimeStrategy.h \ + posix/GetTimeOfDayStrategy.h \ + posix/Monitor.cxx \ + posix/Monitor.h \ + posix/PriorityOps.h \ + posix/TSS.h \ + posix/ThreadOps.cxx \ + posix/ThreadOps.h \ + solaris/FastRecursiveLock.h \ + vanilla/DualMutexRecursiveLock.h \ + vanilla/SimpleAtomicCount.cxx \ + vanilla/SimpleRecursiveLock.h \ + win32/AtomicCount.cxx \ + win32/AtomicFastLock.h \ + win32/AtomicFastRecursiveLock.h \ + win32/FastLock.h \ + win32/FastRecursiveLock.h \ + win32/Monitor.cxx \ + win32/Monitor.h \ + win32/PerformanceCounterStrategy.h \ + win32/TSS.h \ + win32/ThreadOps.cxx \ + win32/ThreadOps.h \ + win9x/AtomicCount.cxx \ + win9x/AtomicFastLock.h diff --git a/dep/src/zthread/Monitor.cxx b/dep/src/zthread/Monitor.cxx new file mode 100644 index 000000000..9a578e796 --- /dev/null +++ b/dep/src/zthread/Monitor.cxx @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMONITORIMPLSELECT_CXX__ +#define __ZTMONITORIMPLSELECT_CXX__ + +#include "Monitor.h" + +// This file will select an implementation for a Monitor based on +// what Monitor.h selects. This method is for selecting the +// source files, to improve portability. Currently, the project is +// based on the autoconf tool-set, which doesn't support conditional +// compilation well. Additionally, this should make the library +// easier to port since its working around conditional compilation +// by using C++ features and people won't have to fiddle around with +// their make tool as much to compile the source + +#include ZT_MONITOR_IMPLEMENTATION + +#endif diff --git a/dep/src/zthread/Monitor.h b/dep/src/zthread/Monitor.h new file mode 100644 index 000000000..6f9492fe3 --- /dev/null +++ b/dep/src/zthread/Monitor.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMONITORSELECT_H__ +#define __ZTMONITORSELECT_H__ + +#include "zthread/Config.h" + +#if defined(ZT_MONITOR_IMPLEMENTATION) +# error "Reserved symbol defined" +#endif + +// Include the dependencies for a Montior +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +// Select the correct Monitor implementation based on +// what the compilation environment has defined +#if defined(ZT_POSIX) + +# include "posix/Monitor.h" +# define ZT_MONITOR_IMPLEMENTATION "posix/Monitor.cxx" + +#elif defined(ZT_WIN32) || defined(ZT_WIN9X) + +# include "win32/Monitor.h" +# define ZT_MONITOR_IMPLEMENTATION "win32/Monitor.cxx" + +#elif defined(ZT_MACOS) + +# include "macos/Monitor.h" +# define ZT_MONITOR_IMPLEMENTATION "macos/Monitor.cxx" + +#endif + +#ifndef __ZTMONITOR_H__ +#error "No Monitor implementation could be selected" +#endif + +#endif // __ZTMONITORSELECT_H__ diff --git a/dep/src/zthread/Mutex.cxx b/dep/src/zthread/Mutex.cxx new file mode 100644 index 000000000..eca38ba89 --- /dev/null +++ b/dep/src/zthread/Mutex.cxx @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/Mutex.h" +#include "MutexImpl.h" + +namespace ZThread { + + class FifoMutexImpl : public MutexImpl { }; + + + Mutex::Mutex() { + + _impl = new FifoMutexImpl(); + + } + + Mutex::~Mutex() { + + if(_impl != 0) + delete _impl; + } + + // P + void Mutex::acquire() { + + _impl->acquire(); + + } + + + // P + bool Mutex::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + // V + void Mutex::release() { + + _impl->release(); + + } + + + +} // namespace ZThread + diff --git a/dep/src/zthread/MutexImpl.h b/dep/src/zthread/MutexImpl.h new file mode 100644 index 000000000..10a9160ce --- /dev/null +++ b/dep/src/zthread/MutexImpl.h @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/Exceptions.h" +#include "zthread/Guard.h" + +#include "Debug.h" +#include "FastLock.h" +#include "Scheduling.h" + +#include +#include + +namespace ZThread { + + +/** + * @author Eric Crahen + * @date <2003-07-16T19:52:12-0400> + * @version 2.2.11 + * @class NullBehavior + */ +class NullBehavior { +protected: + + inline void waiterArrived(ThreadImpl*) { } + + inline void waiterDeparted(ThreadImpl*) { } + + inline void ownerAcquired(ThreadImpl*) { } + + inline void ownerReleased(ThreadImpl*) { } + +}; + +/** + * @author Eric Crahen + * @date <2003-07-16T19:52:12-0400> + * @version 2.2.11 + * @class MutexImpl + * + * The MutexImpl template allows how waiter lists are sorted, and + * what actions are taken when a thread interacts with the mutex + * to be parametized. + */ +template +class MutexImpl : Behavior { + + //! List of Events that are waiting for notification + List _waiters; + + //! Serialize access to this Mutex + FastLock _lock; + + //! Current owner + volatile ThreadImpl* _owner; + + public: + + + /** + * Create a new MutexImpl + * + * @exception Initialization_Exception thrown if resources could not be + * properly allocated + */ + MutexImpl() : _owner(0) { } + + ~MutexImpl(); + + void acquire(); + + void release(); + + bool tryAcquire(unsigned long timeout); + +}; + + /** + * Destroy this MutexImpl and release its resources + */ +template +MutexImpl::~MutexImpl() { + +#ifndef NDEBUG + + // It is an error to destroy a mutex that has not been released + if(_owner != 0) { + + ZTDEBUG("** You are destroying a mutex which was never released. **\n"); + assert(0); // Destroyed mutex while in use + + } + + if(!_waiters.empty()) { + + ZTDEBUG("** You are destroying a mutex which is blocking %d threads. **\n", _waiters.size()); + assert(0); // Destroyed mutex while in use + + } + +#endif + + } + + + /** + * Acquire a lock on the mutex. If this operation succeeds the calling + * thread holds an exclusive lock on this mutex, otherwise it is blocked + * until the lock can be acquired. + * + * @exception Deadlock_Exception thrown when the caller attempts to acquire() more + * than once, If the checking flag is set. + * @exception Interrupted_Exception thrown when the caller status is interrupted + * @exception Synchronization_Exception thrown if there is some other error. + */ +template +void MutexImpl::acquire() { + + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Monitor::STATE state; + + Guard g1(_lock); + + // Deadlock will occur if the current thread is the owner + // and there is no entry count. + if(_owner == self) + throw Deadlock_Exception(); + + // Acquire the lock if it is free and there are no waiting threads + if(_owner == 0 && _waiters.empty()) { + + _owner = self; + + this->ownerAcquired(self); + + } + + // Otherwise, wait for a signal from a thread releasing its + // ownership of the lock + else { + + _waiters.insert(self); + m.acquire(); + + this->waiterArrived(self); + + { + + Guard g2(g1); + state = m.wait(); + + } + + this->waiterDeparted(self); + + m.release(); + + // Remove from waiter list, regardless of wether release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called (e.g. interrupted) + typename List::iterator i = std::find(_waiters.begin(), _waiters.end(), self); + if(i != _waiters.end()) + _waiters.erase(i); + + // If awoke due to a notify(), take ownership. + switch(state) { + case Monitor::SIGNALED: + + assert(_owner == 0); + _owner = self; + + this->ownerAcquired(self); + + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + default: + throw Synchronization_Exception(); + } + + } + + } + + + /** + * Acquire a lock on the mutex. If this operation succeeds the calling + * thread holds an exclusive lock on this mutex. If the lock cannot be + * obtained before the timeout expires, the caller returns false. + * + * @exception Deadlock_Exception thrown when the caller attempts to acquire() more + * than once, If the checking flag is set. + * @exception Interrupted_Exception thrown when the caller status is interrupted + * @exception Synchronization_Exception thrown if there is some other error. + */ +template +bool MutexImpl::tryAcquire(unsigned long timeout) { + + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Guard g1(_lock); + + // Deadlock will occur if the current thread is the owner + // and there is no entry count. + if(_owner == self) + throw Deadlock_Exception(); + + // Acquire the lock if it is free and there are no waiting threads + if(_owner == 0 && _waiters.empty()) { + + _owner = self; + + this->ownerAcquired(self); + + } + + // Otherwise, wait for a signal from a thread releasing its + // ownership of the lock + else { + + _waiters.insert(self); + + Monitor::STATE state = Monitor::TIMEDOUT; + + // Don't bother waiting if the timeout is 0 + if(timeout) { + + m.acquire(); + + this->waiterArrived(self); + + { + + Guard g2(g1); + state = m.wait(timeout); + + } + + this->waiterDeparted(self); + + m.release(); + + } + + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + typename List::iterator i = std::find(_waiters.begin(), _waiters.end(), self); + if(i != _waiters.end()) + _waiters.erase(i); + + // If awoke due to a notify(), take ownership. + switch(state) { + case Monitor::SIGNALED: + + assert(0 == _owner); + _owner = self; + + this->ownerAcquired(self); + + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + case Monitor::TIMEDOUT: + return false; + + default: + throw Synchronization_Exception(); + } + + } + + return true; + + } + + /** + * Release a lock on the mutex. If this operation succeeds the calling + * thread no longer holds an exclusive lock on this mutex. If there are + * waiting threads, one will be selected, assigned ownership and specifically + * awakened. + * + * @exception InvalidOp_Exception - thrown if an attempt is made to + * release a mutex not owned by the calling thread. + */ +template +void MutexImpl::release() { + + ThreadImpl* impl = ThreadImpl::current(); + + Guard g1(_lock); + + // Make sure the operation is valid + if(_owner != impl) + throw InvalidOp_Exception(); + + _owner = 0; + + this->ownerReleased(impl); + + // Try to find a waiter with a backoff & retry scheme + for(;;) { + + // Go through the list, attempt to notify() a waiter. + for(typename List::iterator i = _waiters.begin(); i != _waiters.end();) { + + // Try the monitor lock, if it cant be locked skip to the next waiter + impl = *i; + Monitor& m = impl->getMonitor(); + + if(m.tryAcquire()) { + + // If notify() is not sucessful, it is because the wait() has already + // been ended (killed/interrupted/notify'd) + bool woke = m.notify(); + + m.release(); + + // Once notify() succeeds, return + if(woke) + return; + + } else ++i; + + } + + if(_waiters.empty()) + return; + + { // Backoff and try again + + Guard g2(g1); + ThreadImpl::yield(); + + } + + } + + } + +} // namespace ZThread + + + + + + diff --git a/dep/src/zthread/PoolExecutor.cxx b/dep/src/zthread/PoolExecutor.cxx new file mode 100644 index 000000000..cf84e1454 --- /dev/null +++ b/dep/src/zthread/PoolExecutor.cxx @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "ThreadImpl.h" +#include "zthread/PoolExecutor.h" +#include "zthread/MonitoredQueue.h" +#include "zthread/FastMutex.h" +#include "ThreadImpl.h" +#include "ThreadQueue.h" + +#include +#include +#include + +using namespace ZThread; + +namespace ZThread { + + namespace { + + /** + */ + class WaiterQueue { + + typedef std::deque ThreadList; + + typedef struct group_t { + size_t id; + size_t count; + ThreadList waiters; + group_t(size_t n) : id(n), count(0) {} + } Group; + + typedef std::deque GroupList; + + //! Predicate to find a specific group + struct by_id : public std::unary_function { + size_t id; + by_id(size_t n) : id(n) {} + bool operator()(const Group& grp) { + return grp.id == id; + } + }; + + //! Functor to count groups + struct counter : public std::unary_function { + size_t count; + counter() : count(0) {} + void operator()(const Group& grp) { count += grp.count; } + operator size_t() { return count; } + }; + + FastMutex _lock; + GroupList _list; + size_t _id; + size_t _generation; + + public: + + WaiterQueue() : _id(0), _generation(0) { + // At least one empty-group exists + _list.push_back( Group(_id++) ); + } + + /** + * Insert the current thread into the current waiter list + * + * @pre At least one empty group exists + * @post At least one empty group exists + */ + bool wait(unsigned long timeout) { + + ThreadImpl* current = ThreadImpl::current(); + Monitor& m = current->getMonitor(); + + Monitor::STATE state; + + Guard g1(_lock); + + // At least one empty-group exists + assert(!_list.empty()); + + // Return w/o waiting if there are no executing tasks + if((size_t)std::for_each(_list.begin(), _list.end(), counter()) < 1) + return true; + + // Update the waiter list for the active group + _list.back().waiters.push_back(current); + size_t n = _list.back().id; + + m.acquire(); + + { + + Guard g2(g1); + state = timeout == 0 ? m.wait() : m.wait(timeout); + + } + + m.release(); + + // If awoke due to a reason other than the last task in the group 'n' completing, + // then then find the group 'current' is waiting in + GroupList::iterator i = std::find_if(_list.begin(), _list.end(), by_id(n)); + if(i != _list.end()) { + + // Remove 'current' from that list if it is still a member + ThreadList::iterator j = std::find(i->waiters.begin(), i->waiters.end(), current); + if(j != i->waiters.end()) + i->waiters.erase(j); + + } + + // At least one empty-group exists + assert(!_list.empty()); + + switch(state) { + case Monitor::SIGNALED: + break; + case Monitor::TIMEDOUT: + return false; + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + default: + throw Synchronization_Exception(); + } + + return true; + + } + + /** + * Increment the active group count + * + * @pre at least 1 empty group exists + * @post at least 1 non-empty group exists + */ + std::pair increment() { + + Guard g(_lock); + + // At least one empty-group exists + assert(!_list.empty()); + + GroupList::iterator i = --_list.end(); + size_t n = i->id; + + if(i == _list.end()) { + + // A group should never have been removed until + // the final task in that group completed + assert(0); + + } + + i->count++; + + // When the active group is being incremented, insert a new active group + // to replace it if there were waiting threads + if(i == --_list.end() && !i->waiters.empty()) + _list.push_back(Group(_id++)); + + // At least 1 non-empty group exists + assert((size_t)std::for_each(_list.begin(), _list.end(), counter()) > 0); + + return std::make_pair(n, _generation); + + } + + + /** + * Decrease the count for the group with the given id. + * + * @param n group id + * + * @pre At least 1 non-empty group exists + * @post At least 1 empty group exists + */ + void decrement(size_t n) { + + Guard g1(_lock); + + // At least 1 non-empty group exists + assert((size_t)std::for_each(_list.begin(), _list.end(), counter()) > 0); + + // Find the requested group + GroupList::iterator i = std::find_if(_list.begin(), _list.end(), by_id(n)); + if(i == _list.end()) { + + // A group should never have been removed until + // the final task in that group completed + assert(0); + + } + + // Decrease the count for tasks in this group, + if(--i->count == 0 && i == _list.begin()) { + + do { + + // When the first group completes, wake all waiters for every + // group, starting from the first until a group that is not + // complete is reached + + /* + // Don't remove the empty active group + if(i == --_list.end() && i->waiters.empty()) + break; + */ + + if( awaken(*i) ) { + + // If all waiters were awakened, remove the group + i = _list.erase(i); + + } else { + + { + + // Otherwise, unlock and yield allowing the waiter + // lists to be updated if other threads are busy + Guard g2(g1); + ThreadImpl::yield(); + + } + + i = _list.begin(); + + } + + } while(i != _list.end() && i->count == 0); + + // Ensure that an active group exists + if(_list.empty()) + _list.push_back( Group(++_id) ); + + } + + // At least one group exists + assert(!_list.empty()); + + } + + /** + */ + size_t generation(bool next = false) { + + Guard g(_lock); + return next ? _generation++ : _generation; + + } + + private: + + /** + * Awaken all the waiters remaining in the given group + * + * @return + * - true if all the waiting threads were successfully awakened. + * - false if there were one or more threads that could not be awakened. + */ + bool awaken(Group& grp) { + + // Go through the waiter list in the given group; + for(ThreadList::iterator i = grp.waiters.begin(); i != grp.waiters.end();) { + + ThreadImpl* impl = *i; + Monitor& m = impl->getMonitor(); + + // Try the monitor lock, if it cant be locked skip to the next waiter + if(m.tryAcquire()) { + + // Notify the monitor & remove from the waiter list so time isn't + // wasted checking it again. + i = grp.waiters.erase(i); + + // Try to wake the waiter, it doesn't matter if this is successful + // or not (only fails when the monitor is already going to stop waiting). + m.notify(); + m.release(); + + } else ++i; + + } + + return grp.waiters.empty(); + + } + + }; + + /** + * @class GroupedRunnable + * + * Wrap a task with group and generation information. + * + * - 'group' allows tasks to be grouped together so that lists of waiting + * threads can be managed. + * + * - 'generation' allows tasks to be interrupted + */ + class GroupedRunnable : public Runnable { + + Task _task; + WaiterQueue& _queue; + + size_t _group; + size_t _generation; + + public: + + GroupedRunnable(const Task& task, WaiterQueue& queue) + : _task(task), _queue(queue) { + + std::pair pr( _queue.increment() ); + + _group = pr.first; + _generation = pr.second; + + } + + size_t group() const { + return _group; + } + + size_t generation() const { + return _generation; + } + + void run() { + + try { + + _task->run(); + + } catch(...) { + + } + + _queue.decrement( group() ); + + } + + }; + + typedef CountedPtr ExecutorTask; + + /** + * + */ + class ExecutorImpl { + + typedef MonitoredQueue TaskQueue; + typedef std::deque ThreadList; + + TaskQueue _taskQueue; + WaiterQueue _waitingQueue; + + ThreadList _threads; + volatile size_t _size; + + + public: + + ExecutorImpl() : _size(0) {} + + + void registerThread() { + + Guard g(_taskQueue); + + ThreadImpl* impl = ThreadImpl::current(); + _threads.push_back(impl); + + // current cancel if too many threads are being created + if(_threads.size() > _size) + impl->cancel(); + + } + + void unregisterThread() { + + Guard g(_taskQueue); + std::remove(_threads.begin(), _threads.end(), ThreadImpl::current()); + + } + + void execute(const Task& task) { + + // Wrap the task with a grouped task + GroupedRunnable* runnable = new GroupedRunnable(task, _waitingQueue); + + try { + + _taskQueue.add( ExecutorTask(runnable) ); + + } catch(...) { + + // Incase the queue is canceled between the time the WaiterQueue is + // updated and the task is added to the TaskQueue + _waitingQueue.decrement( runnable->group() ); + throw; + + } + + } + + void interrupt() { + + // Bump the generation number + _waitingQueue.generation(true); + + Guard g(_taskQueue); + + // Interrupt all threads currently running, thier tasks would be + // from an older generation + for(ThreadList::iterator i = _threads.begin(); i != _threads.end(); ++i) + (*i)->interrupt(); + + } + + //! Adjust the number of desired workers and return the number of Threads needed + size_t workers(size_t n) { + + Guard g(_taskQueue); + + size_t m = (_size < n) ? (n - _size) : 0; + _size = n; + + return m; + + } + + size_t workers() { + + Guard g(_taskQueue); + return _size; + + } + + ExecutorTask next() { + + ExecutorTask task; + + // Draw the task from the queue + for(;;) { + + try { + + task = _taskQueue.next(); + break; + + } catch(Interrupted_Exception&) { + + // Ignore interruption here, it can only come from + // another thread interrupt()ing the executor. The + // thread was interrupted in the hopes it was busy + // with a task + + } + + } + + // Interrupt the thread running the tasks when the generation + // does not match the current generation + if( task->generation() != _waitingQueue.generation() ) + ThreadImpl::current()->interrupt(); + + // Otherwise, clear the interrupted status for the thread and + // give it a clean slate to start with + else + ThreadImpl::current()->isInterrupted(); + + return task; + + } + + bool isCanceled() { + return _taskQueue.isCanceled(); + } + + void cancel() { + _taskQueue.cancel(); + } + + bool wait(unsigned long timeout) { + return _waitingQueue.wait(timeout); + } + + }; + + //! Executor job + class Worker : public Runnable { + + CountedPtr< ExecutorImpl > _impl; + + public: + + //! Create a Worker that draws upon the given Queue + Worker(const CountedPtr< ExecutorImpl >& impl) + : _impl(impl) { } + + //! Run until Thread or Queue are canceled + void run() { + + _impl->registerThread(); + + // Run until the Queue is canceled + while(!Thread::canceled()) { + + // Draw tasks from the queue + ExecutorTask task( _impl->next() ); + task->run(); + + } + + _impl->unregisterThread(); + + } + + }; /* Worker */ + + + //! Helper + class Shutdown : public Runnable { + + CountedPtr< ExecutorImpl > _impl; + + public: + + Shutdown(const CountedPtr< ExecutorImpl >& impl) + : _impl(impl) { } + + void run() { + _impl->cancel(); + } + + }; /* Shutdown */ + + } + + PoolExecutor::PoolExecutor(size_t n) + : _impl( new ExecutorImpl() ), _shutdown( new Shutdown(_impl) ) { + + size(n); + + // Request cancelation when main() exits + ThreadQueue::instance()->insertShutdownTask(_shutdown); + + } + + PoolExecutor::~PoolExecutor() { + + try { + + /** + * If the shutdown task for this executor has not already been + * selected to run, then run it locally + */ + if(ThreadQueue::instance()->removeShutdownTask(_shutdown)) + _shutdown->run(); + + } catch(...) { } + + } + + void PoolExecutor::interrupt() { + _impl->interrupt(); + } + + void PoolExecutor::size(size_t n) { + + if(n < 1) + throw InvalidOp_Exception(); + + for(size_t m = _impl->workers(n); m > 0; --m) + Thread t(new Worker(_impl)); + + } + + size_t PoolExecutor::size() { + return _impl->workers(); + } + + + void PoolExecutor::execute(const Task& task) { + + // Enqueue the task, the Queue will reject it with a + // Cancelation_Exception if the Executor has been canceled + _impl->execute(task); + + } + + void PoolExecutor::cancel() { + _impl->cancel(); + } + + bool PoolExecutor::isCanceled() { + return _impl->isCanceled(); + } + + void PoolExecutor::wait() { + _impl->wait(0); + } + + bool PoolExecutor::wait(unsigned long timeout) { + return _impl->wait(timeout == 0 ? 1 : timeout); + } + +} diff --git a/dep/src/zthread/PriorityCondition.cxx b/dep/src/zthread/PriorityCondition.cxx new file mode 100644 index 000000000..c43953ff7 --- /dev/null +++ b/dep/src/zthread/PriorityCondition.cxx @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/PriorityCondition.h" +#include "ConditionImpl.h" + +namespace ZThread { + + class PriorityConditionImpl : public ConditionImpl { + public: + PriorityConditionImpl(Lockable& l) : ConditionImpl(l) {} + + }; + + PriorityCondition::PriorityCondition(Lockable& lock) { + + _impl = new PriorityConditionImpl(lock); + + } + + + PriorityCondition::~PriorityCondition() { + + if(_impl != 0) + delete _impl; + + } + + + + void PriorityCondition::wait() { + + _impl->wait(); + + } + + + + bool PriorityCondition::wait(unsigned long ms) { + + return _impl->wait(ms); + + } + + + + void PriorityCondition::signal() { + + _impl->signal(); + + } + + + void PriorityCondition::broadcast() { + + _impl->broadcast(); + + } + +} // namespace ZThread + diff --git a/dep/src/zthread/PriorityInheritanceMutex.cxx b/dep/src/zthread/PriorityInheritanceMutex.cxx new file mode 100644 index 000000000..108e4a743 --- /dev/null +++ b/dep/src/zthread/PriorityInheritanceMutex.cxx @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/PriorityInheritanceMutex.h" +#include "MutexImpl.h" +#include "ThreadOps.h" + + +namespace ZThread { + + class InheritPriorityBehavior : public NullBehavior { + + ThreadImpl* owner; + Priority p; + + protected: + + // Temporarily raise the effective priority of the owner + inline void waiterArrived(ThreadImpl* impl) { + + Priority q = impl->getPriority(); + if((int)q > (int)p) { + + ThreadOps::setPriority(impl, p); + p = q; + + } + + } + + + // Note the owners priority + inline void ownerAcquired(ThreadImpl* impl) { + + p = impl->getPriority(); + owner = impl; + + } + + // Restore its original priority + inline void ownerReleased(ThreadImpl* impl) { + + if(p > owner->getPriority()) + ThreadOps::setPriority(impl, impl->getPriority()); + + } + + }; + + class PriorityInheritanceMutexImpl : + public MutexImpl { }; + + PriorityInheritanceMutex::PriorityInheritanceMutex() { + + _impl = new PriorityInheritanceMutexImpl(); + + } + + PriorityInheritanceMutex::~PriorityInheritanceMutex() { + + if(_impl != 0) + delete _impl; + + } + + // P + void PriorityInheritanceMutex::acquire() { + + _impl->acquire(); + + } + + + // P + bool PriorityInheritanceMutex::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + // V + void PriorityInheritanceMutex::release() { + + _impl->release(); + + } + + +} // namespace ZThread + diff --git a/dep/src/zthread/PriorityMutex.cxx b/dep/src/zthread/PriorityMutex.cxx new file mode 100644 index 000000000..c25eaebc4 --- /dev/null +++ b/dep/src/zthread/PriorityMutex.cxx @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/PriorityMutex.h" +#include "MutexImpl.h" +#include "ThreadOps.h" + + +namespace ZThread { + + class PriorityMutexImpl : public MutexImpl { }; + + PriorityMutex::PriorityMutex() { + + _impl = new PriorityMutexImpl(); + + } + + PriorityMutex::~PriorityMutex() { + + if(_impl != 0) + delete _impl; + + } + + // P + void PriorityMutex::acquire() { + + _impl->acquire(); + + } + + + // P + bool PriorityMutex::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + // V + void PriorityMutex::release() { + + _impl->release(); + + } + + +} // namespace ZThread + diff --git a/dep/src/zthread/PrioritySemaphore.cxx b/dep/src/zthread/PrioritySemaphore.cxx new file mode 100644 index 000000000..15138b5f4 --- /dev/null +++ b/dep/src/zthread/PrioritySemaphore.cxx @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "Debug.h" +#include "zthread/PrioritySemaphore.h" +#include "SemaphoreImpl.h" + +namespace ZThread { + + class PrioritySemaphoreImpl : public SemaphoreImpl { + public: + + PrioritySemaphoreImpl(int count, unsigned int maxCount) + : SemaphoreImpl(count, maxCount, true) { } + + }; + + /** + * Create a new semaphore of a given size with a given count + * + * @param initialCount initial count to assign this semaphore + * @param maxCount maximum size of the semaphore count + */ + PrioritySemaphore::PrioritySemaphore(int count, unsigned int maxCount) { + + _impl = new PrioritySemaphoreImpl(count, maxCount); + + } + + PrioritySemaphore::~PrioritySemaphore() { + + if(_impl != 0) + delete _impl; + + } + + void PrioritySemaphore::wait() { + + _impl->acquire(); + + } + + + bool PrioritySemaphore::tryWait(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + void PrioritySemaphore::post() { + + _impl->release(); + + } + + int PrioritySemaphore::count() { + + return _impl->count(); + + } + + /////////////////////////////////////////////////////////////////////////////// + // Locakable compatibility + // + + void PrioritySemaphore::acquire() { + + _impl->acquire(); + + } + + bool PrioritySemaphore::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + + } + + void PrioritySemaphore::release() { + + _impl->release(); + + } + +} // namespace ZThread diff --git a/dep/src/zthread/RecursiveMutex.cxx b/dep/src/zthread/RecursiveMutex.cxx new file mode 100644 index 000000000..57994f55b --- /dev/null +++ b/dep/src/zthread/RecursiveMutex.cxx @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/RecursiveMutex.h" +#include "RecursiveMutexImpl.h" + +namespace ZThread { + + RecursiveMutex::RecursiveMutex() { + + _impl = new RecursiveMutexImpl(); + + } + + RecursiveMutex::~RecursiveMutex() { + + if(_impl != (RecursiveMutexImpl*)0 ) + delete _impl; + + } + + + void RecursiveMutex::acquire() { + + _impl->acquire(); + + } + + + bool RecursiveMutex::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + void RecursiveMutex::release() { + + _impl->release(); + + } + +} // namespace ZThread diff --git a/dep/src/zthread/RecursiveMutexImpl.cxx b/dep/src/zthread/RecursiveMutexImpl.cxx new file mode 100644 index 000000000..41ca03547 --- /dev/null +++ b/dep/src/zthread/RecursiveMutexImpl.cxx @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "Debug.h" + +#include "RecursiveMutexImpl.h" +#include "ThreadImpl.h" + +#include "zthread/Guard.h" + +#include +#include +#include + +namespace ZThread { + + /** + * Create a new RecursiveMutexImpl + * + * @exception Initialization_Exception thrown if resources could not be + * properly allocated + */ + RecursiveMutexImpl::RecursiveMutexImpl() + : _owner(0), _count(0) { + + } + + /** + * Destroy this RecursiveMutexImpl and release its resources + */ + RecursiveMutexImpl::~RecursiveMutexImpl() { + +#ifndef NDEBUG + + // It is an error to destroy a mutex that has not been released + if(_owner != 0) { + + ZTDEBUG("** You are destroying a mutex which was never released. **\n"); + assert(0); // Destroyed mutex while in use + + } + + if(!_waiters.empty()) { + + ZTDEBUG("** You are destroying a mutex which is blocking %d threads. **\n", _waiters.size()); + assert(0); // Destroyed mutex while in use + + } + +#endif + + } + + + void RecursiveMutexImpl::acquire() { + + // Get the monitor for the current thread + Monitor& m = ThreadImpl::current()->getMonitor(); + Monitor::STATE state; + + Guard g1(_lock); + + // If there is an entry count and the current thread is + // the owner, increment the count and continue. + if(_owner == &m) + _count++; + + else { + + // Acquire the lock if it is free and there are no waiting threads + if(_owner == 0 && _waiters.empty()) { + + assert(_count == 0); + + _owner = &m; + _count++; + + } else { // Otherwise, wait() + + _waiters.push_back(&m); + + m.acquire(); + + { + + Guard g2(g1); + state = m.wait(); + + } + + m.release(); + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + List::iterator i = std::find(_waiters.begin(), _waiters.end(), &m); + if(i != _waiters.end()) + _waiters.erase(i); + + // If awoke due to a notify(), take ownership. + switch(state) { + case Monitor::SIGNALED: + + assert(_owner == 0); + assert(_count == 0); + + _owner = &m; + _count++; + + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + default: + throw Synchronization_Exception(); + } + + } + + } + + } + + bool RecursiveMutexImpl::tryAcquire(unsigned long timeout) { + + // Get the monitor for the current thread + Monitor& m = ThreadImpl::current()->getMonitor(); + + Guard g1(_lock); + + // If there is an entry count and the current thread is + // the owner, increment the count and continue. + if(_owner == &m) + _count++; + + else { + + // Acquire the lock if it is free and there are no waiting threads + if(_owner == 0 && _waiters.empty()) { + + assert(_count == 0); + + _owner = &m; + _count++; + + } else { // Otherwise, wait() + + _waiters.push_back(&m); + + Monitor::STATE state = Monitor::TIMEDOUT; + + // Don't bother waiting if the timeout is 0 + if(timeout) { + + m.acquire(); + + { + + Guard g2(g1); + state = m.wait(timeout); + + } + + m.release(); + + } + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + List::iterator i = std::find(_waiters.begin(), _waiters.end(), &m); + if(i != _waiters.end()) + _waiters.erase(i); + + // If awoke due to a notify(), take ownership. + switch(state) { + case Monitor::SIGNALED: + + assert(_count == 0); + assert(_owner == 0); + + _owner = &m; + _count++; + + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + case Monitor::TIMEDOUT: + return false; + + default: + throw Synchronization_Exception(); + } + + } + + } + + return true; + + } + + void RecursiveMutexImpl::release() { + + // Get the monitor for the current thread + Monitor& m = ThreadImpl::current()->getMonitor(); + + Guard g1(_lock); + + // Make sure the operation is valid + if(!(_owner == &m)) + throw InvalidOp_Exception(); + + // Update the count, if it has reached 0, wake another waiter. + if(--_count == 0) { + + _owner = 0; + + // Try to find a waiter with a backoff & retry scheme + for(;;) { + + // Go through the list, attempt to notify() a waiter. + for(List::iterator i = _waiters.begin(); i != _waiters.end();) { + + // Try the monitor lock, if it cant be locked skip to the next waiter + Monitor* n = *i; + if(n->tryAcquire()) { + + // If notify() is not sucessful, it is because the wait() has already + // been ended (killed/interrupted/notify'd) + bool woke = n->notify(); + n->release(); + + // Once notify() succeeds, return + if(woke) + return; + + } else ++i; + + } + + if(_waiters.empty()) + return; + + { // Backoff and try again + + Guard g2(g1); + ThreadImpl::yield(); + + } + + } + + } + + } + +} // namespace ZThread + + + + diff --git a/dep/src/zthread/RecursiveMutexImpl.h b/dep/src/zthread/RecursiveMutexImpl.h new file mode 100644 index 000000000..9e1ae050c --- /dev/null +++ b/dep/src/zthread/RecursiveMutexImpl.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTRECURSIVEMUTEXIMPL_H__ +#define __ZTRECURSIVEMUTEXIMPL_H__ + +#include "zthread/Exceptions.h" + +#include "FastLock.h" + +#include + +namespace ZThread { + + class Monitor; + + /** + * @class RecursiveMutexImpl + * @author Eric Crahen + * @date <2003-07-16T19:58:26-0400> + * @version 2.1.6 + * + * This synchronization object provides serialized access + * through an acquire/release protocol. + */ + class ZTHREAD_API RecursiveMutexImpl { + + typedef std::vector List; + + //! List of Events that are waiting for notification + List _waiters; + + //! Serialize access to this Mutex + FastLock _lock; + + //! Current owning Event object + Monitor* _owner; + + //! Entry count + size_t _count; + + public: + + RecursiveMutexImpl(); + + virtual ~RecursiveMutexImpl(); + + void acquire(); + + bool tryAcquire(unsigned long); + + void release(); + + }; /* RecursiveMutexImpl */ + + +}; + +#endif diff --git a/dep/src/zthread/Scheduling.h b/dep/src/zthread/Scheduling.h new file mode 100644 index 000000000..b12f7fff0 --- /dev/null +++ b/dep/src/zthread/Scheduling.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTSCHEDULING_H__ +#define __ZTSCHEDULING_H__ + +#include "ThreadImpl.h" + +#include +#include +#include +#include + +namespace ZThread { + + /** + * @author Eric Crahen + * @date <2003-07-16T20:01:18-0400> + * @version 2.2.0 + * @class fifo_list + */ + class fifo_list : public std::deque { + public: + + void insert(const value_type& val) { push_back(val); } + + }; + + /** + * @author Eric Crahen + * @date <2003-07-16T20:01:18-0400> + * @version 2.2.0 + * @struct priority_order + */ + struct priority_order : public std::binary_function { + + std::less id; + + bool operator()(const ThreadImpl* t0, const ThreadImpl* t1) const { + + if(t0->getPriority() > t1->getPriority()) + return true; + + else if (t0->getPriority() < t1->getPriority()) + return false; + + return id(t0, t1); + + } + + }; + + + /** + * @author Eric Crahen + * @date <2003-07-16T20:01:18-0400> + * @version 2.2.0 + * @class priority_list + */ + class priority_list : public std::deque { + + priority_order comp; + + public: + + void insert(const value_type& val) { + + push_back(val); + std::sort(begin(), end(), comp); + + } + + }; + +} // namespace ZThread + +#endif // __ZTSCHEDULING_H__ diff --git a/dep/src/zthread/Semaphore.cxx b/dep/src/zthread/Semaphore.cxx new file mode 100644 index 000000000..b9fb8d0f6 --- /dev/null +++ b/dep/src/zthread/Semaphore.cxx @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/Semaphore.h" +#include "SemaphoreImpl.h" + +namespace ZThread { + + /** + * Create a new semaphore of a given size with a given count + * + * @param initialCount initial count to assign this semaphore + * @param maxCount maximum size of the semaphore count + */ + Semaphore::Semaphore(int count, unsigned int maxCount) { + + _impl = new FifoSemaphoreImpl(count, maxCount, true); + + } + + Semaphore::~Semaphore() { + + if(_impl != 0) + delete _impl; + + } + + void Semaphore::wait() { + + _impl->acquire(); + + } + + + bool Semaphore::tryWait(unsigned long ms) { + + return _impl->tryAcquire(ms); + + } + + void Semaphore::post() { + + _impl->release(); + + } + + int Semaphore::count() { + + return _impl->count(); + + } + + /////////////////////////////////////////////////////////////////////////////// + // Locakable compatibility + // + + void Semaphore::acquire() { + + _impl->acquire(); + + } + + bool Semaphore::tryAcquire(unsigned long ms) { + + return _impl->tryAcquire(ms); + + + } + + void Semaphore::release() { + + _impl->release(); + + } + +} // namespace ZThread + + + + + + diff --git a/dep/src/zthread/SemaphoreImpl.h b/dep/src/zthread/SemaphoreImpl.h new file mode 100644 index 000000000..086c4333f --- /dev/null +++ b/dep/src/zthread/SemaphoreImpl.h @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTSEMAPHOREIMPL_H__ +#define __ZTSEMAPHOREIMPL_H__ + +#include "zthread/Guard.h" + +#include "Debug.h" +#include "FastLock.h" +#include "Scheduling.h" + +#include + +namespace ZThread { + + class Monitor; + + /** + * @class SemaphoreImpl + * @author Eric Crahen + * @date <2003-07-16T20:03:20-0400> + * @version 2.2.11 + * + * The SemaphoreImpl template allows how waiter lists are sorted + * to be parameteized + */ + template + class SemaphoreImpl { + + //! List of waiting events + List _waiters; + + //! Serialize access to this object + FastLock _lock; + + //! Current count + volatile int _count; + + //! Maximum count if any + volatile int _maxCount; + + //! Flag for bounded or unbounded count + volatile bool _checked; + + //! Entry count + volatile int _entryCount; + + public: + + + /** + * Create a new SemaphoreImpl. Initialzes one pthreads mutex for + * internal use. + * + * @exception Initialization_Exception thrown if resources could not be + * properly allocated + */ + SemaphoreImpl(int count, unsigned int maxCount, bool checked) + : _count(count), _maxCount(maxCount), _checked(checked), _entryCount(0) { } + + + ~SemaphoreImpl(); + + void acquire(); + + void release(); + + bool tryAcquire(unsigned long timeout); + + int count(); + + }; + + + /** + * Destroy this SemaphoreImpl and release its resources. + */ + template + SemaphoreImpl::~SemaphoreImpl() { + +#ifndef NDEBUG + + if(!_waiters.empty()) { + + ZTDEBUG("** You are destroying a semaphore which is blocking %d threads. **\n", _waiters.size()); + assert(0); // Destroyed semaphore while in use + + } + +#endif + + } + + + /** + * Get the count for the Semaphore + * + * @return int + */ + template + int SemaphoreImpl::count() { + + Guard g(_lock); + return _count; + + } + + /** + * Decrement the count, blocking when that count becomes 0 or less. + * + * @exception Interrupted_Exception thrown when the caller status is interrupted + * @exception Synchronization_Exception thrown if there is some other error. + */ + template + void SemaphoreImpl::acquire() { + + // Get the monitor for the current thread + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Monitor::STATE state; + + Guard g1(_lock); + + // Update the count without waiting if possible. + if(_count > 0 && _entryCount == 0) + _count--; + + // Otherwise, wait() for the lock by placing the waiter in the list + else { + + ++_entryCount; + _waiters.insert(self); + + m.acquire(); + + { + + Guard g2(g1); + state = m.wait(); + + } + + m.release(); + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + typename List::iterator i = std::find(_waiters.begin(), _waiters.end(), self); + if(i != _waiters.end()) + _waiters.erase(i); + + --_entryCount; + + switch(state) { + // If awoke due to a notify(), update the count + case Monitor::SIGNALED: + + _count--; + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + default: + throw Synchronization_Exception(); + } + + } + + } + + /** + * Decrement the count, blocking when it that count is 0 or less. If the timeout + * expires before the count is raise above 0, the thread will stop blocking + * and return. + * + * @exception Interrupted_Exception thrown when the caller status is interrupted + * @exception Synchronization_Exception thrown if there is some other error. + */ + template + bool SemaphoreImpl::tryAcquire(unsigned long timeout) { + + // Get the monitor for the current thread + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Guard g1(_lock); + + // Update the count without waiting if possible. + if(_count > 0 && _entryCount == 0) + _count--; + + // Otherwise, wait() for the lock by placing the waiter in the list + else { + + ++_entryCount; + _waiters.push_back(self); + + Monitor::STATE state = Monitor::TIMEDOUT; + + // Don't bother waiting if the timeout is 0 + if(timeout) { + + m.acquire(); + + { + + Guard g2(g1); + state = m.wait(timeout); + + } + + m.release(); + + } + + // Remove from waiter list, regarless of weather release() is called or + // not. The monitor is sticky, so its possible a state 'stuck' from a + // previous operation and will leave the wait() w/o release() having + // been called. + typename List::iterator i = std::find(_waiters.begin(), _waiters.end(), self); + if(i != _waiters.end()) + _waiters.erase(i); + + --_entryCount; + + switch(state) { + // If awoke due to a notify(), update the count + case Monitor::SIGNALED: + + _count--; + break; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + case Monitor::TIMEDOUT: + return false; + + default: + throw Synchronization_Exception(); + } + + } + + return true; + + } + + /** + * Increment the count and release a waiter if there are any. If the semaphore + * is checked, then an exception will be raised if the maximum count is about to + * be exceeded. + * + * @exception InvalidOp_Exception thrown if the maximum count is exceeded while + * the checked flag is set. + */ + template + void SemaphoreImpl::release() { + + Guard g1(_lock); + + // Make sure the operation is valid + if(_checked && _count == _maxCount) + throw InvalidOp_Exception(); + + // Increment the count + _count++; + + // Try to find a waiter with a backoff & retry scheme + for(;;) { + + // Go through the list, attempt to notify() a waiter. + for(typename List::iterator i = _waiters.begin(); i != _waiters.end();) { + + // Try the monitor lock, if it cant be locked skip to the next waiter + ThreadImpl* impl = *i; + Monitor& m = impl->getMonitor(); + + if(m.tryAcquire()) { + + // Notify the monitor & remove from the waiter list so time isn't + // wasted checking it again. + i = _waiters.erase(i); + + // If notify() is not sucessful, it is because the wait() has already + // been ended (killed/interrupted/notify'd) + bool woke = m.notify(); + + m.release(); + + // Once notify() succeeds, return + if(woke) + return; + + } else ++i; + + } + + if(_waiters.empty()) + return; + + { // Backoff and try again + + Guard g2(g1); + ThreadImpl::yield(); + + } + + } + + } + + class FifoSemaphoreImpl : public SemaphoreImpl { + public: + + FifoSemaphoreImpl(int count, unsigned int maxCount, bool checked) + /* throw(Synchronization_Exception) */ + : SemaphoreImpl(count, maxCount, checked) { } + + }; + + +} // namespace ZThread + +#endif // __ZTSEMAPHOREIMPL_H__ diff --git a/dep/src/zthread/State.h b/dep/src/zthread/State.h new file mode 100644 index 000000000..85279f4bd --- /dev/null +++ b/dep/src/zthread/State.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTSTATE_H__ +#define __ZTSTATE_H__ + +namespace ZThread { + +/** + * @class State + * @author Eric Crahen + * @date <2003-07-16T20:04:01-0400> + * @version 2.2.1 + * + * Class to encapsulate the current state of the threads life-cycle. + */ +class State { + public: + + //! Various states + typedef enum { REFERENCE, IDLE, RUNNING, JOINED } STATE; + + /** + * Create State with the given flag set. + */ + State(STATE initialState) : _state(initialState) {} + + /** + * Test for the IDLE state. No task has yet run. + */ + bool isIdle() const { + return _state == IDLE; + } + + /** + * Test for the JOINED state. A task has completed and + * the thread is join()ed. + * + * @return bool + */ + bool isJoined() const { + return _state == JOINED; + } + + /** + * Test for the RUNNING state. A task is in progress. + * + * @return bool + */ + bool isRunning() const { + return _state == RUNNING; + } + + /** + * Test for the REFERENCE state. A task is in progress but not + * under control of this library. + * + * @return bool + */ + bool isReference() const { + return _state == REFERENCE; + } + + /** + * Transition to the IDLE state. + * + * @return bool true if successful + */ + bool setIdle() { + + if(_state != RUNNING) + return false; + + _state = IDLE; + return true; + + } + + /** + * Transition to the RUNNING state. + * + * @return bool true if successful + */ + bool setRunning() { + + if(_state != IDLE) + return false; + + _state = RUNNING; + return true; + + } + + /** + * Transition to the REFERENCE state. + * + * @return bool true if successful + */ + bool setReference() { + + if(_state != IDLE) + return false; + + _state = REFERENCE; + return true; + + } + + + /** + * Transition to the JOINED state. + * + * @return bool true if successful + */ + bool setJoined() { + + _state = JOINED; + return true; + + } + + private: + + //! Current state + STATE _state; + +}; + + +}; + +#endif diff --git a/dep/src/zthread/Status.h b/dep/src/zthread/Status.h new file mode 100644 index 000000000..4735e3528 --- /dev/null +++ b/dep/src/zthread/Status.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTBLOCKINGSTATE_H__ +#define __ZTBLOCKINGSTATE_H__ + +#include + +namespace ZThread { + + /** + * @class Status + * @version 2.3.0 + * + * A Status is associated with each Thread's Monitor. Monitors rely on a + * Status object for providing information that will affect a blocking operations. + */ + class Status { + public: + //! Aggregate of pending status changes + volatile unsigned short _pending; + + //! Interest mask + volatile unsigned short _mask; + + public: + + //! State for the monitor + typedef enum { + + // Default + INVALID = 0x00, + + // Valid states + SIGNALED = 0x01, + INTERRUPTED = 0x02, + TIMEDOUT = 0x04, + CANCELED = 0x08, + + // Mask + ANYTHING = (~INVALID & ~CANCELED) + + } STATE; + + Status() : _pending((unsigned short)INVALID), _mask((unsigned short)ANYTHING) { } + + /** + * Set the mask for the STATE's that next() will report. + * STATE's not covered by the interest mask can still be + * set, they just aren't reported until the mask is changed + * to cover that STATE. + * + * @param STATE + * @pre accessed ONLY by the owning thread. + */ + void interest(STATE mask) { + _mask = static_cast(mask); + } + + bool masked(STATE mask) { + return (_mask & static_cast(mask)) == 0; + } + + /** + * Return true if next() will return a STATE covered + * by the current interest mask and by the mask given + * to this function. + * + * @param unsigned short + * @pre accessed ONLY by the owning thread. + */ + bool pending(unsigned short mask) { + + assert(mask != INVALID); + return ((_pending & _mask) & mask) != INVALID; + + } + + /** + * Check the state without the interest mask. + * + * @param state + * @return true if the flag is set + * @pre access must be serial + */ + bool examine(STATE state) { + return (_pending & static_cast(state)) != INVALID; + } + + /** + * Add the flags to the current state. + * + * @param interest - the flags to add to the current state. + * @pre access must be serial + */ + void push(STATE interest) { + _pending |= interest; + } + + /** + * Clear the flags from the current state + * + * @param interest - the flags to clear from the current state. + * @pre access must be serial + */ + void clear(STATE interest) { + + assert(interest != INVALID); + assert(interest != ANYTHING); + assert(interest != CANCELED); + + _pending &= ~interest; + + } + + /** + * Get the next state from set that has accumulated. The order STATES are + * reported in is SIGNALED, TIMEOUT, or INTERRUPTED. Setting the + * intrest mask allows certain state to be selectively ignored for + * a time - but not lost. The states will become visible again as soon + * as the interest mask is changed appropriately. The interest mask is + * generally used to create uninterruptable waits (waiting for threads + * to start, reacquiring a conditions predicate lock, etc) + * + * @return STATE + * @pre access must be serial + */ + STATE next() { + + STATE state = INVALID; + + if(((_pending & _mask) & SIGNALED) != 0) { + + // Absorb the timeout if it happens when a signal + // is available at the same time + _pending &= ~(SIGNALED|TIMEDOUT); + state = SIGNALED; + + } else if(((_pending & _mask) & TIMEDOUT) != 0) { + + _pending &= ~TIMEDOUT; + state = TIMEDOUT; + + } else if(((_pending & _mask) & INTERRUPTED) != 0) { + + _pending &= ~INTERRUPTED; + state = INTERRUPTED; + + } + + assert(state != INVALID); + return state; + + } + + }; + +}; // namespace ZThread + +#endif diff --git a/dep/src/zthread/SynchronousExecutor.cxx b/dep/src/zthread/SynchronousExecutor.cxx new file mode 100644 index 000000000..0dc75b5f6 --- /dev/null +++ b/dep/src/zthread/SynchronousExecutor.cxx @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/SynchronousExecutor.h" + +namespace ZThread { + + SynchronousExecutor::SynchronousExecutor() + : _canceled(false) {} + + SynchronousExecutor::~SynchronousExecutor() { + } + + void SynchronousExecutor::cancel() { + + Guard g(_lock); + _canceled = true; + + } + + bool SynchronousExecutor::isCanceled() { + + Guard g(_lock); + return _canceled; + + } + + void SynchronousExecutor::interrupt() { + } + + void SynchronousExecutor::execute(const Task& task) { + + // Canceled Executors will not accept new tasks, quick + // check to avoid excessive locking in the canceled state + if(_canceled) + throw Cancellation_Exception(); + + Guard g(_lock); + + if(_canceled) // Double check + throw Cancellation_Exception(); + + // Run the task. + Task(task)->run(); + + } + + void SynchronousExecutor::wait() { + + if(Thread::interrupted()) + throw Interrupted_Exception(); + + Guard g(_lock); + + } + + /** + * @see Executor::wait(unsigned long) + */ + bool SynchronousExecutor::wait(unsigned long) { + + if(Thread::interrupted()) + throw Interrupted_Exception(); + + Guard g(_lock); + return true; + + } + + +} diff --git a/dep/src/zthread/TSS.h b/dep/src/zthread/TSS.h new file mode 100644 index 000000000..ed29230ec --- /dev/null +++ b/dep/src/zthread/TSS.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTSSSELECT_H__ +#define __ZTTSSSELECT_H__ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// Select the correct TSS implementation based on +// what the compilation environment has defined + +#if defined(ZT_POSIX) + +#include "posix/TSS.h" + +#elif defined(ZT_WIN32) || defined(ZT_WIN9X) + +#include "win32/TSS.h" + +#elif defined(ZT_MACOS) + +#include "macos/TSS.h" + +#endif + + +#ifndef __ZTTSS_H__ +#error "No TSS implementation could be selected" +#endif + +#endif // __ZTTSSSELECT_H__ diff --git a/dep/src/zthread/Thread.cxx b/dep/src/zthread/Thread.cxx new file mode 100644 index 000000000..25cde7996 --- /dev/null +++ b/dep/src/zthread/Thread.cxx @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/Runnable.h" +#include "zthread/Thread.h" +#include "ThreadImpl.h" + +namespace ZThread { + + + Thread::Thread() + : _impl( ThreadImpl::current() ) { + + // ThreadImpl's start out life with a reference count + // of one, and the they are added to the ThreadQueue. + _impl->addReference(); + + } + + Thread::Thread(const Task& task, bool autoCancel) + : _impl( new ThreadImpl(task, autoCancel) ) { + + _impl->addReference(); + + } + + bool Thread::operator==(const Thread& t) const { + return (t._impl == _impl); + } + + Thread::~Thread() { + + _impl->delReference(); + + } + + void Thread::wait() { + _impl->join(0); + } + + bool Thread::wait(unsigned long timeout) { + + return _impl->join(timeout == 0 ? 1 : timeout); + + } + + bool Thread::interrupted() { + + return ThreadImpl::current()->isInterrupted(); + + } + + + bool Thread::canceled() { + + return ThreadImpl::current()->isCanceled(); + + } + + void Thread::setPriority(Priority n) { + + _impl->setPriority(n); + + } + + + Priority Thread::getPriority() { + + return _impl->getPriority(); + + } + + bool Thread::interrupt() { + + return _impl->interrupt(); + + } + + void Thread::cancel() { + + if(ThreadImpl::current() == _impl) + throw InvalidOp_Exception(); + + _impl->cancel(); + + } + + bool Thread::isCanceled() { + + return _impl->isCanceled(); + + } + + + void Thread::sleep(unsigned long ms) { + + ThreadImpl::sleep(ms); + + } + + + void Thread::yield() { + + ThreadImpl::yield(); + + } + +} // namespace ZThread diff --git a/dep/src/zthread/ThreadImpl.cxx b/dep/src/zthread/ThreadImpl.cxx new file mode 100644 index 000000000..c7c22883b --- /dev/null +++ b/dep/src/zthread/ThreadImpl.cxx @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "Debug.h" + +#include "zthread/Runnable.h" +#include "ThreadImpl.h" +#include "ThreadQueue.h" +#include "DeferredInterruptionScope.h" + +#include + +namespace ZThread { + + TSS ThreadImpl::_threadMap; + + namespace { + + class Launcher : public Runnable { + + ThreadImpl* x; + ThreadImpl* y; + Task z; + + public: + + Launcher(ThreadImpl* a, ThreadImpl* b, const Task& c) : x(a), y(b), z(c) {} + + void run() { + y->dispatch(x,y,z); + } + + }; + + } + + ThreadImpl::ThreadImpl() + : _state(State::REFERENCE), _priority(Medium), _autoCancel(false) { + + ZTDEBUG("Reference thread created.\n"); + + } + + ThreadImpl::ThreadImpl(const Task& task, bool autoCancel) + : _state(State::IDLE), _priority(Medium), _autoCancel(autoCancel) { + + ZTDEBUG("User thread created.\n"); + + start(task); + + } + + + ThreadImpl::~ThreadImpl() { + + _tls.clear(); + + if(isActive()) { + + ZTDEBUG("You are destroying an executing thread!\n"); + abort(); + + } + + ZTDEBUG("Thread destroyed.\n"); + + } + + Monitor& ThreadImpl::getMonitor() { + return _monitor; + } + + void ThreadImpl::cancel(bool autoCancel) { + if(!autoCancel || _autoCancel) + _monitor.cancel(); + } + + bool ThreadImpl::interrupt() { + return _monitor.interrupt(); + } + + bool ThreadImpl::isInterrupted() { + return _monitor.isInterrupted(); + } + + bool ThreadImpl::isCanceled() { + return _monitor.isCanceled(); + } + + Priority ThreadImpl::getPriority() const { + return _priority; + } + + + + bool ThreadImpl::isReference() { + return _state.isReference(); + } + + /** + * Join the thread, blocking the caller until it is interrupted or until + * the thread represented by this object exits. + * + * Reference threads are not under the control of ZThreads and cannot be + * joined. + */ + bool ThreadImpl::join(unsigned long timeout) { + + // Serial access to this ThreadImpl's state + Guard g1(_monitor); + + // Make sure a thread is not trying to join() itself. + if(ThreadOps::isCurrent(this)) + throw Deadlock_Exception("Cannot join self."); + + // Reference threads can't be joined. + if(_state.isReference()) + throw InvalidOp_Exception("Can not join this thread."); + + /* + + TODO: Insert cyclic join check. + + */ + + // If the task has not completed yet, wait for completion + if(!_state.isJoined()) { + + // Add the current thread to the joiner list + ThreadImpl* impl = current(); + _joiners.push_back(impl); + + Monitor::STATE result; + + { // Release this ThreadImpl's lock while the joiner sleeps + + _monitor.release(); + Guard g3(impl->getMonitor()); + + result = impl->_monitor.wait(timeout); + + _monitor.acquire(); + + } + + // Update the joiner list + List::iterator i = std::find(_joiners.begin(), _joiners.end(), impl); + if(i != _joiners.end()) + _joiners.erase(i); + + + switch(result) { + + case Monitor::TIMEDOUT: + return false; + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + default: + break; + + } + + } + + return true; + + } + + + /** + * Translate the priority into a pthread value, and update the thread priority. + * + * This is not available on all platforms, and probably works differently + * the platforms that do support it. Pthreads does not have very portable + * priority support as far I am aware. + * + * If SCHED_OTHER is not supported priority values are still set but + * dont not actually in affect anything. + * + * @param prio PRIORITY value + * + * @exception Killed_Exception thrown by KILLED threads. + * @exception InvalidOp_Exception thrown by IDLE, JOINING or JOINED threads. + */ + void ThreadImpl::setPriority(Priority p) { + + Guard g(_monitor); + + // Only set the native priority when the thread is running + if(_state.isRunning()) + ThreadOps::setPriority(this, p); + + _priority = p; + + } + + + /** + * Test the state Monitor of this thread to determine if the thread + * is an active thread created by zthreads. + * + * @return bool indicating the activity of the thread. + */ + bool ThreadImpl::isActive() { + + Guard g(_monitor); + return _state.isRunning(); + + } + + + /** + * Get a reference to an implmenetation that maps to the current thread. + * Accomplished by checking the TLS map. This will always return a valid + * ThreadImpl instance. + * + * @return ThreadImpl* current implementation that maps to the + * executing thread. + */ + ThreadImpl* ThreadImpl::current() { + + // Get the ThreadImpl previously mapped onto the executing thread. + ThreadImpl* impl = _threadMap.get(); + + // Create a reference thread for any threads that have been 'discovered' + // because they are not created by ZThreads. + if(impl == 0) { + + // Create a ThreadImpl to represent this thread. + impl = new ThreadImpl(); + impl->_state.setReference(); + + ThreadOps::activate(impl); + + // Map a reference thread and insert it into the queue + _threadMap.set(impl); + + ThreadQueue::instance()->insertReferenceThread(impl); + + } + + assert(impl != 0); + return impl; + + } + + /** + * Make current thread sleep for the given number of milliseconds. + * This sleep can be interrupt()ed. + * + * @param ms timeout for the sleep. + * + * @post the calling thread is blocked by waiting on the internal condition + * variable. This can be signaled in the monitor of an interrupt + */ + void ThreadImpl::sleep(unsigned long ms) { + + // Make sleep()ing for 0 milliseconds equivalent to a yield. + if(ms == 0) { + + yield(); + return; + + } + + // Get the monitor for the current thread + Monitor& monitor = current()->getMonitor(); + + // Acquire that threads Monitor with a Guard + Guard g(monitor); + + for(;;) { + + switch(monitor.wait(ms)) { + + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + + default: + return; + + } + + } + + } + + + /** + * Yield the current timeslice to another thread. + * If sched_yield() is available it is used. + * Otherwise, the state Monitor for this thread is used to simiulate a + * yield by blocking for 1 millisecond, which should give the + * scheduler a chance to schedule another thread. + */ + void ThreadImpl::yield() { + + // Try to yield with the native operation. If it fails, then + // simulate with a short wait() on the monitor. + if(!ThreadOps::yield()) { + + // Get the monitor for the current thread + Monitor& monitor = current()->getMonitor(); + + // Attempt a wait(). + Guard g(monitor); + monitor.wait(1); + + } + + } + + void ThreadImpl::start(const Task& task) { + + Guard g1(_monitor); + + // A Thread must be idle in order to be eligable to run a task. + if(!_state.isIdle()) + throw InvalidOp_Exception("Thread is not idle."); + + _state.setRunning(); + + // Spawn a new thread, blocking the parent (current) thread until + // the child starts. + + ThreadImpl* parent = current(); + Launcher launch(parent, this, task); + + // Attempt to start the child thread + Guard g2(parent->_monitor); + + if(!spawn(&launch)) { + + // Return to the idle state & report the error if it doesn't work out. + _state.setIdle(); + throw Synchronization_Exception(); + + + } + + // Wait, uninterruptably, for the child's signal. The parent thread + // still can be interrupted and killed; it just won't take effect + // until the child has started. + + Guard g3(parent->_monitor); + + if(parent->_monitor.wait() != Monitor::SIGNALED) { + assert(0); + } + + + } + + + void ThreadImpl::dispatch(ThreadImpl* parent, ThreadImpl* impl, Task task) { + + // Map the implementation object onto the running thread. + _threadMap.set(impl); + + // Update the reference count on a ThreadImpl before the 'Thread' + // that owns it can go out of scope (by signaling the parent) + impl->addReference(); + + // Update the priority of the thread + if(parent->_state.isReference()) + ThreadOps::setPriority(impl, + parent->_state.isReference() ? impl->_priority : parent->_priority); + + // Inherit ThreadLocal values from the parent + typedef ThreadLocalMap::const_iterator It; + + for(It i = parent->getThreadLocalMap().begin(); i != parent->getThreadLocalMap().end(); ++i) + if( (i->second)->isInheritable() ) + impl->getThreadLocalMap()[ i->first ] = (i->second)->clone(); + + // Insert a user-thread mapping + ThreadQueue::instance()->insertUserThread(impl); + // Wake the parent once the thread is setup + parent->_monitor.notify(); + + ZTDEBUG("Thread starting...\n"); + + // not catch exceptions, let program terminate + //try { + + task->run(); + + //} catch(...) { + + // Result of running a task that threw an exception. + // ZTDEBUG("The task has thrown an unhandled exception\n"); + //assert(0); // UQ1: Go to debugger... + + //} + + ZTDEBUG("Thread joining...\n"); + + { // Update the state of the thread + + Guard g(impl->_monitor); + impl->_state.setJoined(); + + // Wake the joiners that will be easy to join first + for(List::iterator i = impl->_joiners.begin(); i != impl->_joiners.end();) { + + ThreadImpl* joiner = *i; + Monitor& m = joiner->getMonitor(); + + if(m.tryAcquire()) { + + m.notify(); + m.release(); + + i = impl->_joiners.erase(i); + + } else + ++i; + + } + + // Wake the joiners that might take a while next + for(List::iterator i = impl->_joiners.begin(); i != impl->_joiners.end(); ++i) { + + ThreadImpl* joiner = *i; + Monitor& m = joiner->getMonitor(); + + m.acquire(); + m.notify(); + m.release(); + + } + + } + + ZTDEBUG("Thread exiting...\n"); + + // Insert a pending-thread mapping, allowing the resources to be reclaimed + ThreadQueue::instance()->insertPendingThread(impl); + + // Cleanup ThreadLocal values + impl->getThreadLocalMap().clear(); + + // Update the reference count allowing it to be destroyed + impl->delReference(); + + } + + +} // namespace ZThread diff --git a/dep/src/zthread/ThreadImpl.h b/dep/src/zthread/ThreadImpl.h new file mode 100644 index 000000000..ae2c8f239 --- /dev/null +++ b/dep/src/zthread/ThreadImpl.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADIMPL_H__ +#define __ZTTHREADIMPL_H__ + +#include "zthread/ThreadLocalImpl.h" +#include "zthread/Thread.h" +#include "zthread/Exceptions.h" +#include "IntrusivePtr.h" + +#include "Monitor.h" +#include "TSS.h" +#include "ThreadOps.h" +#include "State.h" + +#include +#include + +namespace ZThread { + +/** + * @class ThreadImpl + * @author Eric Crahen + * @date <2003-07-27T13:39:03-0400> + * @version 2.3.0 + */ +class ThreadImpl : public IntrusivePtr, public ThreadOps { + + typedef std::deque List; + + //! TSS to store implementation to current thread mapping. + static TSS _threadMap; + + //! The Monitor for controlling this thread + Monitor _monitor; + + //! Current state for the thread + State _state; + + //! Joining threads + List _joiners; + + public: + + typedef std::map ThreadLocalMap; + + private: + + ThreadLocalMap _tls; + + //! Cached thread priority + Priority _priority; + + //! Request cancel() when main() goes out of scope + bool _autoCancel; + + void start(const Task& task); + + public: + + ThreadImpl(); + + ThreadImpl(const Task&, bool); + + ~ThreadImpl(); + + Monitor& getMonitor(); + + void cancel(bool autoCancel = false); + + bool interrupt(); + + bool isInterrupted(); + + bool isCanceled(); + + Priority getPriority() const; + + // ThreadLocalMap& getThreadLocalMap(); + ThreadLocalMap& getThreadLocalMap() { return _tls; } + + bool join(unsigned long); + + void setPriority(Priority); + + bool isActive(); + + bool isReference(); + + static void sleep(unsigned long); + + static void yield(); + + static ThreadImpl* current(); + + static void dispatch(ThreadImpl*, ThreadImpl*, Task); + +}; + +} // namespace ZThread + +#endif // __ZTTHREADIMPL_H__ diff --git a/dep/src/zthread/ThreadLocalImpl.cxx b/dep/src/zthread/ThreadLocalImpl.cxx new file mode 100644 index 000000000..25682e663 --- /dev/null +++ b/dep/src/zthread/ThreadLocalImpl.cxx @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/ThreadLocalImpl.h" +#include "ThreadImpl.h" + +namespace ZThread { + + ThreadLocalImpl::ThreadLocalImpl() {} + + ThreadLocalImpl::~ThreadLocalImpl() {} + + void ThreadLocalImpl::clearAll() { + + typedef ThreadImpl::ThreadLocalMap Map; + Map& m = ThreadImpl::current()->getThreadLocalMap(); + + m.clear(); + + } + + void ThreadLocalImpl::clear() const { + + typedef ThreadImpl::ThreadLocalMap Map; + Map& m = ThreadImpl::current()->getThreadLocalMap(); + + Map::iterator i = m.find(this); + if(i != m.end()) + m.erase(i); + + } + + ThreadLocalImpl::ValuePtr ThreadLocalImpl::value( ValuePtr(*pfn)() ) const { + + typedef ThreadImpl::ThreadLocalMap Map; + Map& m = ThreadImpl::current()->getThreadLocalMap(); + + Map::iterator i = m.find(this); + if(i != m.end()) + return i->second; + + m[ this ] = ValuePtr( pfn() ); + return m[ this ]; + + } + +} // namespace ZThread diff --git a/dep/src/zthread/ThreadOps.cxx b/dep/src/zthread/ThreadOps.cxx new file mode 100644 index 000000000..53a3e4457 --- /dev/null +++ b/dep/src/zthread/ThreadOps.cxx @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADOPSIMPLSELECT_CXX__ +#define __ZTTHREADOPSIMPLSELECT_CXX__ + +#include "ThreadOps.h" + +// This file will select an implementation for a ThreadOps based on +// what ThreadOps.h selects. This method is for selecting the +// source files, to improve portability. Currently, the project is +// based on the autoconf tool-set, which doesn't support conditional +// compilation well. Additionally, this should make the library +// easier to port since its working around conditional compilation +// by using C++ features and people won't have to fiddle around with +// their make tool as much to compile the source + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +// Check for sched_yield() + +#if !defined(HAVE_SCHED_YIELD) +# if defined(HAVE_UNISTD_H) +# include +# if defined(_POSIX_PRIORITY_SCHEDULING) +# define HAVE_SCHED_YIELD 1 +# endif +# endif +#endif + +#include ZT_THREADOPS_IMPLEMENTATION + +#endif diff --git a/dep/src/zthread/ThreadOps.h b/dep/src/zthread/ThreadOps.h new file mode 100644 index 000000000..eef9f3c6e --- /dev/null +++ b/dep/src/zthread/ThreadOps.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADOPSSELECT_H__ +#define __ZTTHREADOPSSELECT_H__ + +#include "zthread/Config.h" + +#if defined(ZT_THREADOPS_IMPLEMENTATION) +# error "Reserved symbol defined" +#endif + + +// Select the correct implementation +#if defined(ZT_POSIX) + +# include "posix/ThreadOps.h" +# define ZT_THREADOPS_IMPLEMENTATION "posix/ThreadOps.cxx" + +#elif defined(ZT_WIN32) || defined(ZT_WIN9X) + +// Visual C provides the _beginthreadex function, other compilers +// might not have this if they don't use Microsoft's C runtime. +// _beginthreadex is similar to in effect defining REENTRANT on a +// POSIX system. CreateThreadEx doesn't use reentrant parts of the +// Microsfot C runtime, but if your not using that runtime, no problem. + +# if !defined(HAVE_BEGINTHREADEX) +# if defined(_MSC_VER) +# define HAVE_BEGINTHREADEX +# endif +# endif + +# include "win32/ThreadOps.h" +# define ZT_THREADOPS_IMPLEMENTATION "win32/ThreadOps.cxx" + +#elif defined(ZT_MACOS) + +# include "macos/ThreadOps.h" +# define ZT_THREADOPS_IMPLEMENTATION "macos/ThreadOps.cxx" + +#endif + +#ifndef __ZTTHREADOPS_H__ +#error "No ThreadOps implementation could be selected" +#endif + +#endif // __ZTTHREADOPSSELECT_H__ diff --git a/dep/src/zthread/ThreadQueue.cxx b/dep/src/zthread/ThreadQueue.cxx new file mode 100644 index 000000000..023495046 --- /dev/null +++ b/dep/src/zthread/ThreadQueue.cxx @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "DeferredInterruptionScope.h" +#include "Debug.h" +#include "ThreadImpl.h" +#include "ThreadQueue.h" + +#include +#include + +namespace ZThread { + + ThreadQueue::ThreadQueue() + : _waiter(0) { + + ZTDEBUG("ThreadQueue created\n"); + + } + + ThreadQueue::~ThreadQueue() { + + ZTDEBUG("ThreadQueue waiting on remaining threads...\n"); + + // Ensure the current thread is mapped. + ThreadImpl* impl = ThreadImpl::current(); + + bool threadsWaiting = false; + bool waitRequired = false; + + { + + TaskList shutdownTasks; + + { // Check the queue to for pending user threads + + Guard g(_lock); + + waitRequired = (_waiter != (ThreadImpl*)1); + _waiter = impl; + + threadsWaiting = !_userThreads.empty() || !_pendingThreads.empty(); + + //ZTDEBUG("Wait required: %d\n", waitRequired); + //ZTDEBUG("Threads waiting: %d\n", threadsWaiting); + + // Auto-cancel any active threads at the time main() goes out of scope + // "force" a gentle exit from the executing tasks; eventually the user- + // threads will transition into pending-threads + pollUserThreads(); + + // Remove all the tasks about to be run from the task list so an indication + // can be given to threads calling removeShutdownTask() too late. + std::remove_copy(_shutdownTasks.begin(), + _shutdownTasks.end(), + std::back_inserter(shutdownTasks), + Task((Runnable*)0)); + + //ZTDEBUG("Threads waiting: %d\n", threadsWaiting); + + } + + // Execute the shutdown tasks + for(TaskList::iterator i = shutdownTasks.begin(); i != shutdownTasks.end(); ++i) { + try { + (*i)->run(); + } catch(...) { } + } + + } + + // Wait for all the users threads to get into the appropriate state + if(threadsWaiting) { + + + Monitor& m = _waiter->getMonitor(); + + // Defer interruption while this thread waits for a signal from + // the last pending user thread + Guard > g(m); + //ZTDEBUG("Threads waiting: %d %d\n", _userThreads.size(), _pendingThreads.size()); + + // Avoid race-condition where the last threads are done with thier tasks, but + // only begin the final part of the clean up phase after this destructor begins + // to run. Takes advantage of the fact that if all remaining threads have transitioned + // into a pending state by the time execution reaches this point, then there is no + // need to wait. + waitRequired = waitRequired && !(_userThreads.empty() && !_pendingThreads.empty()); + + // Reference threads can't be interrupted or otherwise + // manipulated. The only signal this monitor will receive + // at this point will be from the last pending thread. + if(waitRequired && m.wait() != Monitor::SIGNALED) { + assert(0); + } + + // Join those pending threads + pollPendingThreads(); + + } + + // Clean up the reference threads + pollReferenceThreads(); + + ZTDEBUG("ThreadQueue destroyed\n"); + + } + + + void ThreadQueue::insertPendingThread(ThreadImpl* impl) { + ZTDEBUG("insertPendingThread()\n"); + Guard g(_lock); + + // Move from the user-thread list to the pending-thread list + ThreadList::iterator i = std::find(_userThreads.begin(), _userThreads.end(), impl); + if(i != _userThreads.end()) + _userThreads.erase(i); + + _pendingThreads.push_back(impl); + + // Wake the main thread,if its waiting, when the last pending-thread becomes available; + // Otherwise, take note that no wait for pending threads to finish is needed + if(_userThreads.empty()) + if(_waiter && _waiter != (ThreadImpl*)1) + _waiter->getMonitor().notify(); + else + _waiter = (ThreadImpl*)!_waiter; + + ZTDEBUG("1 pending-thread added.\n"); + + } + + void ThreadQueue::insertReferenceThread(ThreadImpl* impl) { + + Guard g(_lock); + _referenceThreads.push_back(impl); + + ZTDEBUG("1 reference-thread added.\n"); + + } + + void ThreadQueue::insertUserThread(ThreadImpl* impl) { + + Guard g(_lock); + _userThreads.push_back(impl); + + // Reclaim pending-threads + pollPendingThreads(); + + // Auto-cancel threads that are started when main() is out of scope + if(_waiter) + impl->cancel(true); + + ZTDEBUG("1 user-thread added.\n"); + + } + + + void ThreadQueue::pollPendingThreads() { + + ZTDEBUG("pollPendingThreads()\n"); + + for(ThreadList::iterator i = _pendingThreads.begin(); i != _pendingThreads.end();) { + + ThreadImpl* impl = (ThreadImpl*)*i; + ThreadOps::join(impl); + + impl->delReference(); + + i = _pendingThreads.erase(i); + + ZTDEBUG("1 pending-thread reclaimed.\n"); + + } + + } + + void ThreadQueue::pollReferenceThreads() { + + ZTDEBUG("pollReferenceThreads()\n"); + + for(ThreadList::iterator i = _referenceThreads.begin(); i != _referenceThreads.end(); ++i) { + + ThreadImpl* impl = (ThreadImpl*)*i; + impl->delReference(); + + ZTDEBUG("1 reference-thread reclaimed.\n"); + + } + + } + + void ThreadQueue::pollUserThreads() { + + ZTDEBUG("pollUserThreads()\n"); + + for(ThreadList::iterator i = _userThreads.begin(); i != _userThreads.end(); ++i) { + + ThreadImpl* impl = *i; + impl->cancel(true); + + ZTDEBUG("1 user-thread reclaimed.\n"); + + } + + } + + void ThreadQueue::insertShutdownTask(Task& task) { + + bool hasWaiter = false; + + { + + Guard g(_lock); + + // Execute later when the ThreadQueue is destroyed + if( !(hasWaiter = (_waiter != 0)) ) { + + _shutdownTasks.push_back(task); + //ZTDEBUG("1 shutdown task added. %d\n", _shutdownTasks.size()); + + } + + } + + // Execute immediately if things are shutting down + if(hasWaiter) + task->run(); + + } + + bool ThreadQueue::removeShutdownTask(const Task& task) { + + Guard g(_lock); + + TaskList::iterator i = std::find(_shutdownTasks.begin(), _shutdownTasks.end(), task); + bool removed = (i != _shutdownTasks.end()); + if(removed) + _shutdownTasks.erase(i); + + //ZTDEBUG("1 shutdown task removed (%d)-%d\n", removed, _shutdownTasks.size()); + + return removed; + + } + +}; diff --git a/dep/src/zthread/ThreadQueue.h b/dep/src/zthread/ThreadQueue.h new file mode 100644 index 000000000..044f82630 --- /dev/null +++ b/dep/src/zthread/ThreadQueue.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADQUEUE_H__ +#define __ZTTHREADQUEUE_H__ + +#include "zthread/Singleton.h" +#include "zthread/Guard.h" +#include "FastLock.h" + + +namespace ZThread { + + class ThreadImpl; + + /** + * @class ThreadQueue + * @version 2.3.0 + * @author Eric Crahen + * @date <2003-07-27T20:52:05-0400> + * + * A ThreadQueue accumulates references to user and reference threads. + * These are threads that are running outside the scope of the Thread + * object that created them. ZThreads doesn't have a central manager for + * all threads (partly why I renamed the ThreadManager to someting more + * appropriate). Instead, ZThreads will discover threads it did not create + * and create a reference thread that allows ZThreads to interact with it. + * Non user threads that are created by the user never have to touch the + * ThreadQueue. + */ + class ThreadQueue : public Singleton { + + typedef std::deque ThreadList; + typedef std::deque TaskList; + + //! Managed thread lists + ThreadList _pendingThreads; + ThreadList _referenceThreads; + ThreadList _userThreads; + + //! Shutdown handlers + TaskList _shutdownTasks; + + //! Serilize access to the thread list + FastLock _lock; + + //! Reference thread waiting to cleanup any user & reference threads + ThreadImpl* _waiter; + + public: + + ThreadQueue(); + + /** + * The thread destroys a ThreadQueue will be a reference thread, + * probably the main thread; but it could be another thread that + * started and loaded the library. + */ + ~ThreadQueue(); + + /** + * Insert a user-thread into the queue. User-threads are inserted as they + * begin thier task. Once that task completes, user-threads are automatically + * transitioned to pending-threads via insertPendingThread(). + * + * User-threads are known to be executing thier tasks and will be cancel()ed + * as the ThreadQueue is destroyed when main() goes out of scope. This sends + * a request to the task to complete soon. Once the task exits, the thread is + * transitioned to pending-thread status. + */ + void insertUserThread(ThreadImpl*); + + /** + * Insert a pending-thread into the queue. + * + * Pending-threads are known to have completed thier tasks and thier + * resources are reclaimed (lazily) as more threads are started or as the + * ThreadQueue is destroyed. + */ + void insertPendingThread(ThreadImpl*); + + + /** + * Insert reference thread. Reference threads are not removed until + * the ThreadQueue goes out of scope. + */ + void insertReferenceThread(ThreadImpl*); + + /** + * Insert a task to be run before threads are joined. + * Any items inserted after the ThreadQueue desctructor has begun to + * execute will be run() immediately. + */ + void insertShutdownTask(Task&); + + /** + * Remove an existing shutdown task. + */ + bool removeShutdownTask(const Task&); + + private: + + void pollPendingThreads(); + + void pollUserThreads(); + + void pollReferenceThreads(); + + }; + + +} // namespace ZThread + + +#endif // __ZTTHREADQUEUE_H__ diff --git a/dep/src/zthread/ThreadedExecutor.cxx b/dep/src/zthread/ThreadedExecutor.cxx new file mode 100644 index 000000000..44a213e8d --- /dev/null +++ b/dep/src/zthread/ThreadedExecutor.cxx @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/ThreadedExecutor.h" +#include "zthread/Guard.h" +#include "zthread/FastMutex.h" +#include "zthread/Time.h" + +#include "ThreadImpl.h" + +namespace ZThread { + + namespace { + + //! + class WaiterQueue { + + typedef std::deque ThreadList; + + typedef struct group_t { + size_t id; + size_t count; + ThreadList waiters; + group_t(size_t n) : id(n), count(0) {} + } Group; + + typedef std::deque GroupList; + + //! Predicate to find a specific group + struct by_id : public std::unary_function { + size_t id; + by_id(size_t n) : id(n) {} + bool operator()(const Group& grp) { + return grp.id == id; + } + }; + + //! Functor to count groups + struct counter : public std::unary_function { + size_t count; + counter() : count(0) {} + void operator()(const Group& grp) { count += grp.count; } + operator size_t() { return count; } + }; + + FastMutex _lock; + GroupList _list; + size_t _id; + size_t _generation; + + public: + + WaiterQueue() : _id(0), _generation(0) { + // At least one empty-group exists + _list.push_back( Group(_id++) ); + } + + /** + * Insert the current thread into the current waiter list + * + * @pre At least one empty group exists + * @post At least one empty group exists + */ + bool wait(unsigned long timeout) { + + ThreadImpl* self = ThreadImpl::current(); + Monitor& m = self->getMonitor(); + + Monitor::STATE state; + + Guard g1(_lock); + + // At least one empty-group exists + assert(!_list.empty()); + + // Return w/o waiting if there are no executing tasks + if((size_t)std::for_each(_list.begin(), _list.end(), counter()) < 1) + return true; + + // Update the waiter list for the active group + _list.back().waiters.push_back(self); + size_t n = _list.back().id; + + m.acquire(); + + { + + Guard g2(g1); + state = timeout == 0 ? m.wait() : m.wait(timeout); + + } + + m.release(); + + // If awoke due to a reason other than the last task in the group 'n' completing, + // then then find the group 'self' is waiting in + GroupList::iterator i = std::find_if(_list.begin(), _list.end(), by_id(n)); + if(i != _list.end()) { + + // Remove 'self' from that list if it is still a member + ThreadList::iterator j = std::find(i->waiters.begin(), i->waiters.end(), self); + if(j != i->waiters.end()) + i->waiters.erase(j); + + } + + // At least one empty-group exists + assert(!_list.empty()); + + switch(state) { + case Monitor::SIGNALED: + break; + case Monitor::TIMEDOUT: + return false; + case Monitor::INTERRUPTED: + throw Interrupted_Exception(); + default: + throw Synchronization_Exception(); + } + + return true; + + } + + /** + * Increment the active group count + * + * @pre at least 1 empty group exists + * @post at least 1 non-empty group exists + */ + std::pair increment() { + + Guard g(_lock); + + // At least one empty-group exists + assert(!_list.empty()); + + GroupList::iterator i = --_list.end(); + size_t n = i->id; + + if(i == _list.end()) { + + // A group should never have been removed until + // the final task in that group completed + assert(0); + + } + + i->count++; + + // When the active group is being incremented, insert a new active group + // to replace it if there were waiting threads + if(i == --_list.end() && !i->waiters.empty()) + _list.push_back(Group(_id++)); + + // At least 1 non-empty group exists + assert((size_t)std::for_each(_list.begin(), _list.end(), counter()) > 0); + + return std::make_pair(n, _generation); + + } + + + /** + * Decrease the count for the group with the given id. + * + * @param n group id + * + * @pre At least 1 non-empty group exists + * @post At least 1 empty group exists + */ + void decrement(size_t n) { + + Guard g1(_lock); + + // At least 1 non-empty group exists + assert((size_t)std::for_each(_list.begin(), _list.end(), counter()) > 0); + + // Find the requested group + GroupList::iterator i = std::find_if(_list.begin(), _list.end(), by_id(n)); + if(i == _list.end()) { + + // A group should never have been removed until + // the final task in that group completed + assert(0); + + } + + // Decrease the count for tasks in this group, + if(--i->count == 0 && i == _list.begin()) { + + do { + + // When the first group completes, wake all waiters for every + // group, starting from the first until a group that is not + // complete is reached + + /* + // Don't remove the empty active group + if(i == --_list.end() && i->waiters.empty()) + break; + */ + + if( awaken(*i) ) { + + // If all waiters were awakened, remove the group + i = _list.erase(i); + + } else { + + { + + // Otherwise, unlock and yield allowing the waiter + // lists to be updated if other threads are busy + Guard g2(g1); + ThreadImpl::yield(); + + } + + i = _list.begin(); + + } + + } while(i != _list.end() && i->count == 0); + + // Ensure that an active group exists + if(_list.empty()) + _list.push_back( Group(++_id) ); + + } + + // At least one group exists + assert(!_list.empty()); + + } + + /** + */ + size_t generation(bool next = false) { + + Guard g(_lock); + return next ? _generation++ : _generation; + + } + + private: + + /** + * Awaken all the waiters remaining in the given group + * + * @return + * - true if all the waiting threads were successfully awakened. + * - false if there were one or more threads that could not be awakened. + */ + bool awaken(Group& grp) { + + // Go through the waiter list in the given group; + for(ThreadList::iterator i = grp.waiters.begin(); i != grp.waiters.end();) { + + ThreadImpl* impl = *i; + Monitor& m = impl->getMonitor(); + + // Try the monitor lock, if it cant be locked skip to the next waiter + if(m.tryAcquire()) { + + // Notify the monitor & remove from the waiter list so time isn't + // wasted checking it again. + i = grp.waiters.erase(i); + + // Try to wake the waiter, it doesn't matter if this is successful + // or not (only fails when the monitor is already going to stop waiting). + m.notify(); + m.release(); + + } else ++i; + + } + + return grp.waiters.empty(); + + } + + }; + + //! Synchronization point for the Executor + class ExecutorImpl { + + typedef std::deque ThreadList; + + bool _canceled; + FastMutex _lock; + + //! Worker threads + ThreadList _threads; + + WaiterQueue _queue; + + public: + + ExecutorImpl() : _canceled(false) {} + + WaiterQueue& getWaiterQueue() { + return _queue; + } + + void registerThread(size_t generation) { + + // Interrupt slow starting threads + if(getWaiterQueue().generation() != generation) + ThreadImpl::current()->interrupt(); + + // Enqueue for possible future interrupt() + else { + + Guard g(_lock); + _threads.push_back( ThreadImpl::current() ); + + } + + } + + void unregisterThread() { + + Guard g(_lock); + std::remove(_threads.begin(), _threads.end(), ThreadImpl::current() ); + + } + + void cancel() { + + Guard g(_lock); + _canceled = true; + + } + + bool isCanceled() { + + if(_canceled) + return true; + + Guard g(_lock); + return _canceled; + + } + + void interrupt() { + + Guard g(_lock); + + // Interrupt all the registered threads + for(ThreadList::iterator i = _threads.begin(); i != _threads.end(); ++i) + (*i)->interrupt(); + + // Bump the generation up, ensuring slow starting threads get this interrupt + getWaiterQueue().generation( true ); + + } + + }; /* ExecutorImpl */ + + //! Wrap a generation and a group around a task + class Worker : public Runnable { + + CountedPtr< ExecutorImpl > _impl; + Task _task; + + size_t _generation; + size_t _group; + + public: + + Worker(const CountedPtr< ExecutorImpl >& impl, const Task& task) + : _impl(impl), _task(task) { + + std::pair pr( _impl->getWaiterQueue().increment() ); + + _group = pr.first; + _generation = pr.second; + + } + + size_t group() const { + return _group; + } + + size_t generation() const { + return _generation; + } + + void run() { + + // Register this thread once its begun; the generation is used to ensure + // threads that are slow starting are properly interrupted + + _impl->registerThread( generation() ); + + try { + _task->run(); + } catch(...) { + /* consume the exceptions the work propogates */ + } + + _impl->getWaiterQueue().decrement( group() ); + + // Unregister this thread + + _impl->unregisterThread(); + + } + + }; /* Worker */ + + } + + ThreadedExecutor::ThreadedExecutor() : _impl(new ExecutorImpl) {} + + ThreadedExecutor::~ThreadedExecutor() {} + + void ThreadedExecutor::execute(const Task& task) { + + Thread t( new Worker(_impl, task) ); + + } + + void ThreadedExecutor::interrupt() { + _impl->interrupt(); + } + + void ThreadedExecutor::cancel() { + _impl->cancel(); + } + + bool ThreadedExecutor::isCanceled() { + return _impl->isCanceled(); + } + + void ThreadedExecutor::wait() { + _impl->getWaiterQueue().wait(0); + } + + bool ThreadedExecutor::wait(unsigned long timeout) { + return _impl->getWaiterQueue().wait(timeout == 0 ? 1 : timeout); + } + +} diff --git a/dep/src/zthread/Time.cxx b/dep/src/zthread/Time.cxx new file mode 100644 index 000000000..2409d93cb --- /dev/null +++ b/dep/src/zthread/Time.cxx @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "zthread/Time.h" +#include "TimeStrategy.h" + + +using namespace ZThread; + +Time::Time() { + + // System startup time + static TimeStrategy firstHelper; + TimeStrategy helper; + + Time then(firstHelper.seconds(), firstHelper.milliseconds()); + Time now(helper.seconds(), helper.milliseconds()); + + now -= then; + + _seconds = now.seconds(); + _milliseconds = now.milliseconds(); + +} + + diff --git a/dep/src/zthread/TimeStrategy.h b/dep/src/zthread/TimeStrategy.h new file mode 100644 index 000000000..0b9ad1e22 --- /dev/null +++ b/dep/src/zthread/TimeStrategy.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTIMESELECT_H__ +#define __ZTTIMESELECT_H__ + +#include "zthread/Config.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +// Select the correct TimeOps implementation based on +// what the complilation environment has defined + +#ifndef HAVE_FTIME + +# if defined(ZT_WIN32) || defined(ZT_WIN9X) + +# if !defined(__MWERKS__) + +# ifndef HAVE_FTIME +# define HAVE_FTIME +# endif + +# elif defined(__MWERKS__) + +# ifndef HAVE_PERFORMANCECOUNTER +# define HAVE_PERFORMANCECOUNTER +# endif + +# endif + +# endif + +#endif + +// Some systems require this to complete the definition of timespec +// which is needed by pthreads. +#if defined(HAVE_SYS_TYPES_H) +# include +#endif + +#if defined(ZT_MACOS) + +# include "macos/UpTimeStrategy.h" + +#elif defined(HAVE_PERFORMANCECOUNTER) + +# include "win32/PerformanceCounterStrategy.h" + +#elif defined(HAVE_FTIME) + +# include "posix/FtimeStrategy.h" + +#else + +# include "posix/GetTimeOfDayStrategy.h" + +#endif + + +#ifndef __ZTTIMESTRATEGY_H__ +#error "No TimeStrategy implementation could be selected" +#endif + +#endif // __ZTTIMESELECT_H__ diff --git a/dep/src/zthread/linux/AtomicCount.cxx b/dep/src/zthread/linux/AtomicCount.cxx new file mode 100644 index 000000000..28c2381c3 --- /dev/null +++ b/dep/src/zthread/linux/AtomicCount.cxx @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTATOMICCOUNTIMPL_H__ +#define __ZTATOMICCOUNTIMPL_H__ + +#include +#include + +namespace ZThread { + +typedef struct atomic_count_t { + + atomic_t count; + + atomic_count_t() { + atomic_t init = ATOMIC_INIT(0); + count = init; + } + + ~atomic_count_t() { + assert(atomic_read(&count) == 0); + } + +} ATOMIC_COUNT; + + +AtomicCount::AtomicCount() { + + _value = reinterpret_cast(new ATOMIC_COUNT); + +} + +AtomicCount::~AtomicCount() { + + delete reinterpret_cast(_value); + +} + +void AtomicCount::increment() { + + atomic_inc(&reinterpret_cast(_value)->count); + +} + +bool AtomicCount::decrement() { + + return atomic_dec_and_test(&reinterpret_cast(_value)->count); + +} + +}; + +#endif // __ZTATOMICCOUNTIMPL_H__ diff --git a/dep/src/zthread/linux/AtomicFastLock.h b/dep/src/zthread/linux/AtomicFastLock.h new file mode 100644 index 000000000..b9aa1babc --- /dev/null +++ b/dep/src/zthread/linux/AtomicFastLock.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCK_H__ +#define __ZTFASTLOCK_H__ + +#include "zthread/NonCopyable.h" +#include "../ThreadOps.h" +#include +#include + +#if !defined(NDEBUG) +# include +#endif + +namespace ZThread { + +/** + * @class FastLock + * + * @author Eric Crahen + * @date <2003-07-16T23:27:03-0400> + * @version 2.2.0 + * + * This implementation of a FastLock uses the atomic operations that + * linux provides with its kernel sources. This demonstrates how to implement + * a spinlock with a decrement and test primative. + */ +class FastLock : private NonCopyable { + + atomic_t _value; + +#if !defined(NDEBUG) + pthread_t _owner; +#endif + +public: + + inline FastLock() { + + atomic_t tmp = ATOMIC_INIT(1); + _value = tmp; + + } + + inline ~FastLock() { + + assert(atomic_read(&_value) == 1); + assert(_owner == 0); + + } + + inline void acquire() { + + while(!atomic_dec_and_test(&_value)) { + + atomic_inc(&_value); + ThreadOps::yield(); + + } + +#if !defined(NDEBUG) + _owner = pthread_self(); +#endif + } + + inline void release() { + +#if !defined(NDEBUG) + assert(pthread_equal(_owner, pthread_self()) != 0); +#endif + + atomic_inc(&_value); + _owner = 0; + + } + + inline bool tryAcquire(unsigned long timeout=0) { + + bool wasLocked = atomic_dec_and_test(&_value); + if(!wasLocked) + atomic_inc(&_value); + +#if !defined(NDEBUG) + if(wasLocked) + _owner = pthread_self(); +#endif + + return wasLocked; + + } + +}; /* FastLock */ + + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/linux/FastRecursiveLock.h b/dep/src/zthread/linux/FastRecursiveLock.h new file mode 100644 index 000000000..d253652cb --- /dev/null +++ b/dep/src/zthread/linux/FastRecursiveLock.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "zthread/NonCopyable.h" +#include + +namespace ZThread { + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:27:14-0400> + * @version 2.2.0 + * + * This implementation of a FastRecursiveLock uses the recursive mutex + * that linux pthreads provides. + */ +class FastRecursiveLock : private NonCopyable { + + pthread_mutex_t _mtx; + +public: + + inline FastRecursiveLock() { + + static const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP }; + pthread_mutex_init(&_mtx, &attr); + + } + + inline ~FastRecursiveLock() { + + pthread_mutex_destroy(&_mtx); + + } + + inline void acquire() { + + pthread_mutex_lock(&_mtx); + + } + + inline void release() { + + pthread_mutex_unlock(&_mtx); + + } + + inline bool tryAcquire(unsigned long timeout=0) { + + return (pthread_mutex_trylock(&_mtx) == 0); + + } + +}; /* FastRecursiveLock */ + + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/macos/FastLock.h b/dep/src/zthread/macos/FastLock.h new file mode 100644 index 000000000..bae5c4829 --- /dev/null +++ b/dep/src/zthread/macos/FastLock.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCK_H__ +#define __ZTFASTLOCK_H__ + +#include "zthread/NonCopyable.h" +#include "zthread/Exceptions.h" + +#include +#include +//#include + +namespace ZThread { + +/** + * @class FastLock + * + * @author Eric Crahen + * @date <2003-07-16T23:25:31-0400> + * @version 2.1.6 + * + */ +class FastLock : private NonCopyable { + + MPCriticalRegionID _mtx; + + public: + + /** + * Create a new FastLock. No safety or state checks are performed. + * + * @exception Initialization_Exception - not thrown + */ + inline FastLock() { + + // Apple TN1071 + static bool init = MPLibraryIsLoaded(); + + if(!init || MPCreateCriticalRegion(&_mtx) != noErr) { + assert(0); + throw Initialization_Exception(); + } + + } + + /** + * Destroy a FastLock. No safety or state checks are performed. + */ + inline ~FastLock() throw () { + + OSStatus status = MPDeleteCriticalRegion(_mtx); + if(status != noErr) + assert(false); + + } + + /** + * Acquire an exclusive lock. No safety or state checks are performed. + * + * @exception Synchronization_Exception - not thrown + */ + inline void acquire() { + + if(MPEnterCriticalRegion(_mtx, kDurationForever) != noErr) + throw Synchronization_Exception(); + + } + + /** + * Try to acquire an exclusive lock. No safety or state checks are performed. + * This function returns immediately regardless of the value of the timeout + * + * @param timeout Unused + * @return bool + * @exception Synchronization_Exception - not thrown + */ + inline bool tryAcquire(unsigned long timeout=0) { + + OSStatus status = + MPEnterCriticalRegion(_mtx, kDurationMillisecond * timeout); + + switch(status) { + case kMPTimeoutErr: + return false; + + case noErr: + return true; + + } + + assert(0); + throw Synchronization_Exception(); + + } + + /** + * Release an exclusive lock. No safety or state checks are performed. + * The caller should have already acquired the lock, and release it + * only once. + * + * @exception Synchronization_Exception - not thrown + */ + inline void release() { + + if(MPExitCriticalRegion(_mtx) != noErr) + throw Synchronization_Exception(); + + } + + +}; /* FastLock */ + + +}; + +#endif + + + diff --git a/dep/src/zthread/macos/Monitor.cxx b/dep/src/zthread/macos/Monitor.cxx new file mode 100644 index 000000000..ab7806b13 --- /dev/null +++ b/dep/src/zthread/macos/Monitor.cxx @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "Monitor.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +using namespace ZThread; + +Monitor::Monitor() : _owner(0), _waiting(false), _pending(false) { + + if(MPCreateSemaphore(1, 0, &_sema) != noErr) { + assert(0); + throw Initialization_Exception(); + } + +} + +Monitor::~Monitor() throw() { + + assert(!_waiting); + + OSStatus status = MPDeleteSemaphore(_sema); + if(status != noErr) + assert(false); + +} + +Monitor::STATE Monitor::wait(unsigned long timeout) { + + // Calcuate the time, taking into account Intertask Signaling Time + // http://developer.apple.com/techpubs/macosx/Carbon/oss/MultiPServices/Multiprocessing_Services/index.html?http://developer.apple.com/techpubs/macosx/Carbon/oss/MultiPServices/Multiprocessing_Services/Functions/Creating_and_ssage_Queues.html + + AbsoluteTime tTarget; + Duration waitDuration = + (timeout == 0) ? kDurationForever : (kDurationMillisecond * timeout); + + if(waitDuration != kDurationForever) + tTarget = AddDurationToAbsolute(waitDuration, UpTime()); + + // Update the owner on first use. The owner will not change, each + // thread waits only on a single Monitor and a Monitor is never + // shared + if(_owner == 0) + _owner = MPCurrentTaskID(); + + STATE state(INVALID); + + // Serialize access to the state of the Monitor + // and test the state to determine if a wait is needed. + _waitLock.acquire(); + + if(pending(ANYTHING)) { + + // Return without waiting when possible + state = next(); + + _waitLock.release(); + return state; + + } + // Unlock the external lock if a wait() is probably needed. + // Access to the state is still serial. + _lock.release(); + + // Wait for a transition in the state that is of interest, this + // allows waits to exclude certain flags (e.g. INTERRUPTED) + // for a single wait() w/o actually discarding those flags - + // they will remain set until a wait interested in those flags + // occurs. + + // Wait, ignoring signals + _waiting = true; + + _waitLock.release(); + + // Update the wait time + if(waitDuration != kDurationForever) + waitDuration = AbsoluteDeltaToDuration(tTarget, UpTime()); + + // Sleep until a signal arrives or a timeout occurs + OSStatus status = MPWaitOnSemaphore(_sema, waitDuration); + + // Reacquire serialized access to the state + _waitLock.acquire(); + + // Awaken only when the event is set or the timeout expired + assert(status == kMPTimeoutErr || status == noErr); + + if(status == kMPTimeoutErr) + push(TIMEDOUT); + + // Get the next available STATE + state = next(); + + _waiting = false; + + // Its possible that a timeout will wake the thread before a signal is + // delivered. Absorb that leftover so the next wait isn't aborted right away + if(status == kMPTimeoutErr && _pending) { + + status = MPWaitOnSemaphore(_sema, kDurationForever); + assert(status == noErr); + + } + + _pending = false; + + // Acquire the internal lock & release the external lock + _waitLock.release(); + + // Reaquire the external lock, keep from deadlocking threads calling + // notify(), interrupt(), etc. + _lock.acquire(); + + return state; + +} + + +bool Monitor::interrupt() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasInterruptable = !pending(INTERRUPTED); + bool hasWaiter = false; + + // Update the state & wake the waiter if there is one + if(wasInterruptable) { + + push(INTERRUPTED); + + wasInterruptable = false; + + if(_waiting && !_pending) { + + _pending = true; + hasWaiter = true; + + } else + wasInterruptable = !(_owner == MPCurrentTaskID()); + + } + + _waitLock.release(); + + if(hasWaiter && !masked(Monitor::INTERRUPTED)) + MPSignalSemaphore(_sema); + + return wasInterruptable; + +} + +bool Monitor::isInterrupted() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasInterrupted = pending(INTERRUPTED); + clear(INTERRUPTED); + + _waitLock.release(); + + return wasInterrupted; + +} + + +bool Monitor::notify() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasNotifyable = !pending(INTERRUPTED); + bool hasWaiter = false; + + // Set the flag if theres a waiter + if(wasNotifyable) { + + push(SIGNALED); + + if(_waiting && !_pending) { + + _pending = true; + hasWaiter = true; + + } + + } + + _waitLock.release(); + + if(hasWaiter) + MPSignalSemaphore(_sema); + + return wasNotifyable; + +} + + +bool Monitor::cancel() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasInterrupted = !pending(INTERRUPTED); + bool hasWaiter = false; + + push(CANCELED); + + // Update the state if theres a waiter + if(wasInterrupted) { + + push(INTERRUPTED); + + if(_waiting && !_pending) { + + _pending = true; + hasWaiter = true; + + } + + } + + _waitLock.release(); + + if(hasWaiter && !masked(Monitor::INTERRUPTED)) + MPSignalSemaphore(_sema); + + return wasInterrupted; + +} + +bool Monitor::isCanceled() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasCanceled = Status::examine(CANCELED); + + if(_owner == MPCurrentTaskID()) + clear(INTERRUPTED); + + _waitLock.release(); + + return wasCanceled; + +} + + + + + + + + + + diff --git a/dep/src/zthread/macos/Monitor.h b/dep/src/zthread/macos/Monitor.h new file mode 100644 index 000000000..f4312d7b7 --- /dev/null +++ b/dep/src/zthread/macos/Monitor.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMONITOR_H__ +#define __ZTMONITOR_H__ + +#include "../Status.h" +#include "../FastLock.h" + +namespace ZThread { + +/** + * @class Monitor + * @author Eric Crahen + * @date <2003-07-29T11:24:58-0400> + * @version 2.2.1 + */ +class Monitor : public Status, private NonCopyable { + + //! Serialize access to external objects + FastLock _lock; + + //! Serialize access to internal state + FastLock _waitLock; + + //! Semaphore to control the owning thread + MPSemaphoreID _sema; + + //! Owning thread + MPTaskID _owner; + + //! Waiting flag, to avoid uneccessary signals + volatile bool _waiting; + + //! Waiting flag, to avoid too many signals + volatile bool _pending; + + //! State of the monitor + volatile int _state; + + public: + + //! Create a new monitor. + Monitor(); + + //! Destroy the monitor. + ~Monitor() throw(); + + //! Acquire the external lock for this monitor. + inline void acquire() { + _lock.acquire(); + } + + //! Try to acquire the external lock for this monitor. + inline bool tryAcquire() { + return _lock.tryAcquire(); + } + + //! Release the external lock for this monitor. + inline void release() { + _lock.release(); + } + + /** + * Wait for a state change and atomically unlock the external lock. + * Blocks for an indefinent amount of time. + * + * @return INTERRUPTED if the wait was ended by a interrupt() + * or SIGNALED if the wait was ended by a notify() + * + * @post the external lock is always acquired before this function returns + */ + inline STATE wait() { + return wait(0); + } + + /** + * Wait for a state change and atomically unlock the external lock. + * May blocks for an indefinent amount of time. + * + * @param timeout - maximum time to block (milliseconds) or 0 to + * block indefinently + * + * @return INTERRUPTED if the wait was ended by a interrupt() + * or TIMEDOUT if the maximum wait time expired. + * or SIGNALED if the wait was ended by a notify() + * + * @post the external lock is always acquired before this function returns + */ + STATE wait(unsigned long timeout); + + /** + * Interrupt this monitor. If there is a thread blocked on this monitor object + * it will be signaled and released. If there is no waiter, a flag is set and + * the next attempt to wait() will return INTERRUPTED w/o blocking. + * + * @return false if the thread was previously INTERRUPTED. + */ + bool interrupt(); + + /** + * Notify this monitor. If there is a thread blocked on this monitor object + * it will be signaled and released. If there is no waiter, a flag is set and + * the next attempt to wait() will return SIGNALED w/o blocking, if no other + * flag is set. + * + * @return false if the thread was previously INTERRUPTED. + */ + bool notify(); + + /** + * Check the state of this monitor, clearing the INTERRUPTED status if set. + * + * @return bool true if the monitor was INTERRUPTED. + * @post INTERRUPTED flag cleared if the calling thread owns the monitor. + */ + bool isInterrupted(); + + /** + * Mark the Status CANCELED, and INTERRUPT the montor. + * + * @see interrupt() + */ + bool cancel(); + + /** + * Test the CANCELED Status, clearing the INTERRUPTED status if set. + * + * @return bool + */ + bool isCanceled(); + +}; + +}; + +#endif diff --git a/dep/src/zthread/macos/TSS.h b/dep/src/zthread/macos/TSS.h new file mode 100644 index 000000000..3f9805d0f --- /dev/null +++ b/dep/src/zthread/macos/TSS.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTSS_H__ +#define __ZTTSS_H__ + +#include "zthread/NonCopyable.h" +#include "zthread/Exceptions.h" + +#include +#include +//#include + +namespace ZThread { + + /** + * @class TSS + * @author Eric Crahen + * @date <2003-07-27T14:19:10-0400> + * @version 2.1.6 + * + * An abstraction for dealing with POSIX thread specific storage (tss). + * Provides get/set and creation/destruction. + */ + template + class TSS : private NonCopyable { + + TaskStorageIndex _key; + + public: + + /** + * Create a new object for accessing tss. + */ + TSS() { + + // Apple TN1071 + static bool init = MPLibraryIsLoaded(); + + if(!init || MPAllocateTaskStorageIndex(&_key) != noErr) { + assert(0); + throw Initialization_Exception(); + } + + } + + /** + * Destroy the underlying supoprt for accessing tss with this + * object. + */ + ~TSS() { + + OSStatus status = MPDeallocateTaskStorageIndex(_key); + if(status != noErr) + assert(0); + + } + + /** + * Get the value stored in tss. + * + * @return T + * + * @exception InvalidOp_exception thrown when the tss is not properly initialized + */ + T get() const { + return reinterpret_cast(MPGetTaskStorageValue(_key)); + } + + + /** + * Store a value in tss. + * + * @param value T + * @return T old value + * + * @exception InvalidOp_exception thrown when the tss is not properly initialized + */ + T set(T value) const { + + T oldValue = get(); + + OSStatus status = + MPSetTaskStorageValue(_key, reinterpret_cast(value)); + + if(status != noErr) { + assert(0); + throw Synchronization_Exception(); + } + + return oldValue; + + } + + }; + +} + +#endif + + diff --git a/dep/src/zthread/macos/ThreadOps.cxx b/dep/src/zthread/macos/ThreadOps.cxx new file mode 100644 index 000000000..6a1a41068 --- /dev/null +++ b/dep/src/zthread/macos/ThreadOps.cxx @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#include "ThreadOps.h" +#include "zthread/Exceptions.h" +#include "zthread/Runnable.h" + +namespace ZThread { + +const ThreadOps ThreadOps::INVALID(0); + +ThreadOps::ThreadOps() : _queue(0), _tid(0) { + + if(MPCreateQueue(&_queue) != noErr) + throw Initialization_Exception(); + +} + +ThreadOps::~ThreadOps() throw() { + + if(_queue != 0) { + + OSStatus status = MPDeleteQueue(_queue); + if(status != noErr) + assert(0); + + } + +} + +bool ThreadOps::join(ThreadOps* ops) { + + assert(ops); + assert(ops->_tid != 0); + + OSStatus status = MPWaitOnQueue(ops->_queue, NULL, NULL, NULL, kDurationForever); + + return status == noErr; + +} + +bool ThreadOps::yield() { + + MPYield(); + return true; + +} + +bool ThreadOps::setPriority(ThreadOps* impl, Priority p) { + return true; +} + +bool ThreadOps::getPriority(ThreadOps* impl, Priority& p) { + return true; +} + + +bool ThreadOps::spawn(Runnable* task) { + + OSStatus status = + MPCreateTask(&_dispatch, task, 0UL, _queue, NULL, NULL, 0UL, &_tid); + + return status == noErr; + +} + +OSStatus ThreadOps::_dispatch(void *arg) { + + Runnable* task = reinterpret_cast(arg); + assert(task); + + // Run the task from the correct context + task->run(); + + // Exit the thread + MPExit(noErr); + return noErr; + +} + +} // namespace ZThread + + diff --git a/dep/src/zthread/macos/ThreadOps.h b/dep/src/zthread/macos/ThreadOps.h new file mode 100644 index 000000000..c100fcfef --- /dev/null +++ b/dep/src/zthread/macos/ThreadOps.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADOPS_H__ +#define __ZTTHREADOPS_H__ + +#include "zthread/Priority.h" + +#include +#include +//#include +//#include + +namespace ZThread { + +class Runnable; + +/** + * @class ThreadOps + * @author Eric Crahen + * @date <2003-07-16T23:26:01-0400> + * @version 2.2.0 + * + * This class is an abstraction used to perform various operations on a + * native POSIX thread. + */ +class ThreadOps { + + //! Keep track of the pthreads handle for the native thread + MPQueueID _queue; + MPTaskID _tid; + + ThreadOps(MPTaskID tid) : _queue(0), _tid(tid) { } + + static OSStatus _dispatch(void*); + +public: + + const static ThreadOps INVALID; + + /** + * Create a new ThreadOps to manipulate a native thread. + */ + ThreadOps(); + + ThreadOps(const ThreadOps& ops) : _queue(0), _tid(ops._tid) {} + + ~ThreadOps() throw(); + + inline bool operator==(const ThreadOps& ops) const { + return ops._tid == _tid; + } + + const ThreadOps& operator=(const ThreadOps& ops) { + + assert(_queue == 0); + _tid = ops._tid; + + return *this; + + } + + static ThreadOps self() { + return ThreadOps(MPCurrentTaskID()); + } + + /** + * Activating an instance of ThreadOps will map it onto the currently + * executing thread. + */ + static void activate(ThreadOps* ops) { + + assert(ops); + assert(ops->_tid == 0); + + ops->_tid = MPCurrentTaskID(); + + } + + /** + * Test if this object represents the currently executing + * native thread. + * + * @return bool true if successful + */ + + static bool isCurrent(ThreadOps* ops) { + + assert(ops); + + return MPCurrentTaskID() == ops->_tid; + + } + + /** + * Join a native thread. + * + * @return bool true if successful + */ + static bool join(ThreadOps*); + + /** + * Force the current native thread to yield, letting the scheduler + * give the CPU time to another thread. + * + * @return bool true if successful, false if the operation can't + * be supported. + */ + static bool yield(); + + /** + * Set the priority for the native thread if supported by the + * system. + * + * @param PRIORITY requested priority + * @return bool false if unsuccessful + */ + static bool setPriority(ThreadOps*, Priority); + + /** + * Set the priority for the native thread if supported by the + * system. + * + * @param Thread::PRIORITY& current priority + * @return bool false if unsuccessful + */ + static bool getPriority(ThreadOps*, Priority&); + +protected: + + /** + * Spawn a native thread. + * + * @param ThreadImpl* parent thread + * @param ThreadImpl* child thread being started. + * @param Runnable* task being executed. + * + * @return bool true if successful + */ + bool spawn(Runnable*); + +}; + + +} + +#endif // __ZTTHREADOPS_H__ + diff --git a/dep/src/zthread/macos/UpTimeStrategy.h b/dep/src/zthread/macos/UpTimeStrategy.h new file mode 100644 index 000000000..f2056e14c --- /dev/null +++ b/dep/src/zthread/macos/UpTimeStrategy.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTIMESTRATEGY_H__ +#define __ZTTIMESTRATEGY_H__ + +#include +//#include + +namespace ZThread { + + +/** + * @class TimeStrategy + * + * Implement a strategy for time operatons based on UpTime + */ +class TimeStrategy { + + unsigned long _ms; + unsigned long _s; + + public: + + TimeStrategy() { + + // Get the absolute time in milliseconds relative to the program startup + static AbsoluteTime sysUpTime(UpTime()); + AbsoluteTime delta = AbsoluteDeltaToNanoseconds(UpTime(), sysUpTime); + + uint64_t now = *reinterpret_cast(&delta) / 1000000; + + _s = now / 1000; + _ms = now % 1000; + + } + + inline unsigned long seconds() const { + return _s; + } + + inline unsigned long milliseconds() const { + return _ms; + } + + unsigned long seconds(unsigned long s) { + + unsigned long z = seconds(); + _s = s; + return z; + + } + + unsigned long milliseconds(unsigned long ms) { + + unsigned long z = milliseconds(); + _ms = ms; + + return z; + + } + +}; + +}; + +#endif // __ZTTIMESTRATEGY_H__ diff --git a/dep/src/zthread/posix/ConditionRecursiveLock.h b/dep/src/zthread/posix/ConditionRecursiveLock.h new file mode 100644 index 000000000..a46ed3554 --- /dev/null +++ b/dep/src/zthread/posix/ConditionRecursiveLock.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "zthread/NonCopyable.h" +#include +#include +#include + +namespace ZThread { + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:28:37-0400> + * @version 2.2.0 + * + * This is an implementation of a FastRecursiveLock for any vannila + * POSIX system. It is based on a condition variable and a mutex; + * because of this it is important to not that its waiting properties + * are not the same as other mutex implementations that generally + * based on spin locks. Under high contention, this implementation may + * be preferable to a spin lock, although refactoring the design of + * code that puts a mutex under alot of preasure may be worth investigating. + */ +class FastRecursiveLock : private NonCopyable { + + //! Serialize state + pthread_mutex_t _mtx; + + //! Wait for lock + pthread_cond_t _cond; + + //! Owner + pthread_t _owner; + + //! Count + volatile unsigned int _count; + +public: + + inline FastRecursiveLock() : _owner(0), _count(0) { + + pthread_mutex_init(&_mtx, 0); + if(pthread_cond_init(&_cond, 0) != 0) { + assert(0); + } + + } + + inline ~FastRecursiveLock() { + + pthread_mutex_destroy(&_mtx); + if(pthread_cond_destroy(&_cond) != 0) { + assert(0); + } + + } + + inline void acquire() { + + pthread_t self = pthread_self(); + pthread_mutex_lock(&_mtx); + + // If the caller does not own the lock, wait until there is no owner + if(_owner != 0 && !pthread_equal(_owner, self)) { + + int status = 0; + do { // ignore signals + status = pthread_cond_wait(&_cond, &_mtx); + } while(status == EINTR && _owner == 0); + + } + + _owner = self; + _count++; + + pthread_mutex_unlock(&_mtx); + + } + + inline bool tryAcquire(unsigned long timeout=0) { + + pthread_t self = pthread_self(); + pthread_mutex_lock(&_mtx); + + // If the caller owns the lock, or there is no owner update the count + bool success = (_owner == 0 || pthread_equal(_owner, self)); + if(success) { + + _owner = self; + _count++; + + } + + pthread_mutex_unlock(&_mtx); + + return success; + + } + + inline void release() { + + assert(pthread_equal(_owner, pthread_self())); + + pthread_mutex_lock(&_mtx); + if(--_count == 0) { + + _owner = 0; + pthread_cond_signal(&_cond); + + } + + pthread_mutex_unlock(&_mtx); + + } + + +}; /* FastRecursiveLock */ + + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/posix/FastLock.h b/dep/src/zthread/posix/FastLock.h new file mode 100644 index 000000000..87faf34d4 --- /dev/null +++ b/dep/src/zthread/posix/FastLock.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCK_H__ +#define __ZTFASTLOCK_H__ + +#include "zthread/Exceptions.h" +#include "zthread/NonCopyable.h" +#include +#include + +namespace ZThread { + +/** + * @class FastLock + * + * @author Eric Crahen + * @date <2003-07-16T23:28:07-0400> + * @version 2.2.8 + * + * This is the smallest and fastest synchronization object in the library. + * It is an implementation of fast mutex, an all or nothing exclusive + * lock. It should be used only where you need speed and are willing + * to sacrifice all the state & safety checking provided by the framework + * for speed. + */ +class FastLock : private NonCopyable { + + pthread_mutex_t _mtx; + + public: + + /** + * Create a new FastLock. No safety or state checks are performed. + * + * @exception Initialization_Exception - not thrown + */ + inline FastLock() { + + if(pthread_mutex_init(&_mtx, 0) != 0) + throw Initialization_Exception(); + + } + + /** + * Destroy a FastLock. No safety or state checks are performed. + */ + inline ~FastLock() { + + if(pthread_mutex_destroy(&_mtx) != 0) { + assert(0); + } + + } + + /** + * Acquire an exclusive lock. No safety or state checks are performed. + * + * @exception Synchronization_Exception - not thrown + */ + inline void acquire() { + + if(pthread_mutex_lock(&_mtx) != 0) + throw Synchronization_Exception(); + + } + + /** + * Try to acquire an exclusive lock. No safety or state checks are performed. + * This function returns immediately regardless of the value of the timeout + * + * @param timeout Unused + * @return bool + * @exception Synchronization_Exception - not thrown + */ + inline bool tryAcquire(unsigned long /*timeout*/=0) { + + return (pthread_mutex_trylock(&_mtx) == 0); + + } + + /** + * Release an exclusive lock. No safety or state checks are performed. + * The caller should have already acquired the lock, and release it + * only once. + * + * @exception Synchronization_Exception - not thrown + */ + inline void release() { + + if(pthread_mutex_unlock(&_mtx) != 0) + throw Synchronization_Exception(); + + } + + +}; /* FastLock */ + + +}; + +#endif diff --git a/dep/src/zthread/posix/FtimeStrategy.h b/dep/src/zthread/posix/FtimeStrategy.h new file mode 100644 index 000000000..5e703970c --- /dev/null +++ b/dep/src/zthread/posix/FtimeStrategy.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTIMESTRATEGY_H__ +#define __ZTTIMESTRATEGY_H__ + +#include + +#if defined(_MSC_VER) + +# include + +# define timeb _timeb +# define ftime _ftime + +#endif + +namespace ZThread { + +/** + * @class TimeStrategy + * + * Implement a strategy for time operatons based on ftime + */ +class TimeStrategy { + + struct timeb _value; + +public: + + TimeStrategy() { + ftime(&_value); + } + + inline unsigned long seconds() const { + return (unsigned long)_value.time; + } + + inline unsigned long milliseconds() const { + return _value.millitm; + } + + unsigned long seconds(unsigned long s) { + + unsigned long z = seconds(); + _value.time = s; + + return z; + + } + + unsigned long milliseconds(unsigned long ms) { + + unsigned long z = milliseconds(); + _value.millitm = (unsigned short)ms; + + return z; + + } + +}; + +}; + +#endif // __ZTTIMESTRATEGY_H__ diff --git a/dep/src/zthread/posix/GetTimeOfDayStrategy.h b/dep/src/zthread/posix/GetTimeOfDayStrategy.h new file mode 100644 index 000000000..8588807f4 --- /dev/null +++ b/dep/src/zthread/posix/GetTimeOfDayStrategy.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTIMESTRATEGY_H__ +#define __ZTTIMESTRATEGY_H__ + +#include + +namespace ZThread { + +/** + * @class TimeStrategy + * + * Implement a strategy for time operatons based on gettimeofday + */ +class TimeStrategy { + + struct timeval _value; + +public: + + TimeStrategy() { + gettimeofday(&_value, 0); + } + + inline unsigned long seconds() const { + return _value.tv_sec; + } + + inline unsigned long milliseconds() const { + return _value.tv_usec/1000; + } + + unsigned long seconds(unsigned long s) { + + unsigned long z = seconds(); + _value.tv_sec = s; + + return z; + + } + + unsigned long milliseconds(unsigned long ms) { + + unsigned long z = milliseconds(); + _value.tv_usec = ms*1000; + + return z; + + } + +}; + +}; + +#endif // __ZTTIMESTRATEGY_H__ diff --git a/dep/src/zthread/posix/Monitor.cxx b/dep/src/zthread/posix/Monitor.cxx new file mode 100644 index 000000000..bb157dae0 --- /dev/null +++ b/dep/src/zthread/posix/Monitor.cxx @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "Monitor.h" +#include "../Debug.h" +#include "../TimeStrategy.h" + +#include +#include +#include + +namespace ZThread { + +Monitor::Monitor() : _owner(0), _waiting(false) { + + pthread_cond_init(&_waitCond, 0); + pthread_mutex_init(&_waitLock, 0); + +} + +Monitor::~Monitor() { + + assert(!_waiting); + + pthread_cond_destroy(&_waitCond); + pthread_mutex_destroy(&_waitLock); + +} + +Monitor::STATE Monitor::wait(unsigned long ms) { + + // Update the owner on first use. The owner will not change, each + // thread waits only on a single Monitor and a Monitor is never + // shared + if(_owner == 0) + _owner = pthread_self(); + + STATE state(INVALID); + + // Serialize access to the state of the Monitor + // and test the state to determine if a wait is needed. + + pthread_mutex_lock(&_waitLock); + + if(pending(ANYTHING)) { + + // Return without waiting when possible + state = next(); + + pthread_mutex_unlock(&_waitLock); + return state; + + } + + // Unlock the external lock if a wait() is probably needed. + // Access to the state is still serial. + _lock.release(); + + // Wait for a transition in the state that is of interest, this + // allows waits to exclude certain flags (e.g. INTERRUPTED) + // for a single wait() w/o actually discarding those flags - + // they will remain set until a wait interested in those flags + // occurs. + // if(!currentState(interest)) { + + // Wait, ignoring signals + _waiting = true; + int status = 0; + + if(ms == 0) { // Wait forever + + do { // ignore signals unless the state is interesting + status = pthread_cond_wait(&_waitCond, &_waitLock); + } while(status == EINTR && !pending(ANYTHING)); + + // Akwaken only when a state is pending + assert(status == 0); + + } else { + + // Find the target time + TimeStrategy t; + + ms += t.milliseconds(); + + unsigned long s = t.seconds() + (ms / 1000); + ms %= 1000; + + // Convert to a timespec + struct ::timespec timeout; + + timeout.tv_sec = s; + timeout.tv_nsec = ms*1000000; + + // Wait ignoring signals until the state is interesting + do { + + // When a timeout occurs, update the state to reflect that. + status = pthread_cond_timedwait(&_waitCond, &_waitLock, &timeout); + + } while(status == EINTR && !pending(ANYTHING)); + + // Akwaken only when a state is pending or when the timeout expired + assert(status == 0 || status == ETIMEDOUT); + + if(status == ETIMEDOUT) + push(TIMEDOUT); + + } + + // Get the next available STATE + state = next(); + _waiting = false; + + pthread_mutex_unlock(&_waitLock); + + // Reaquire the external lock, keep from deadlocking threads calling + // notify(), interrupt(), etc. + + _lock.acquire(); + + return state; + +} + + +bool Monitor::interrupt() { + + // Serialize access to the state + pthread_mutex_lock(&_waitLock); + + bool wasInterruptable = !pending(INTERRUPTED); + bool hadWaiter = _waiting; + + if(wasInterruptable) { + + // Update the state & wake the waiter if there is one + push(INTERRUPTED); + + wasInterruptable = false; + + if(hadWaiter && !masked(Monitor::INTERRUPTED)) + pthread_cond_signal(&_waitCond); + else + wasInterruptable = !pthread_equal(_owner, pthread_self()); + + } + + pthread_mutex_unlock(&_waitLock); + + // Only returns true when an interrupted thread is not currently blocked + return wasInterruptable; + +} + +bool Monitor::isInterrupted() { + + // Serialize access to the state + pthread_mutex_lock(&_waitLock); + + bool wasInterrupted = pending(INTERRUPTED); + + clear(INTERRUPTED); + + pthread_mutex_unlock(&_waitLock); + + return wasInterrupted; + +} + +bool Monitor::isCanceled() { + + // Serialize access to the state + pthread_mutex_lock(&_waitLock); + + bool wasCanceled = examine(CANCELED); + + if(pthread_equal(_owner, pthread_self())) + clear(INTERRUPTED); + + pthread_mutex_unlock(&_waitLock); + + return wasCanceled; + +} + +bool Monitor::cancel() { + + // Serialize access to the state + pthread_mutex_lock(&_waitLock); + + bool wasInterrupted = !pending(INTERRUPTED); + bool hadWaiter = _waiting; + + push(CANCELED); + + if(wasInterrupted) { + + // Update the state & wake the waiter if there is one + push(INTERRUPTED); + + if(hadWaiter && !masked(Monitor::INTERRUPTED)) + pthread_cond_signal(&_waitCond); + + } + + pthread_mutex_unlock(&_waitLock); + + return wasInterrupted; + +} + +bool Monitor::notify() { + + // Serialize access to the state + pthread_mutex_lock(&_waitLock); + + bool wasNotifyable = !pending(INTERRUPTED); + + if(wasNotifyable) { + + // Set the flag and wake the waiter if there + // is one + push(SIGNALED); + + if(_waiting) + pthread_cond_signal(&_waitCond); + + } + + pthread_mutex_unlock(&_waitLock); + + return wasNotifyable; + +} + +} // namespace ZThread + diff --git a/dep/src/zthread/posix/Monitor.h b/dep/src/zthread/posix/Monitor.h new file mode 100644 index 000000000..945c879f4 --- /dev/null +++ b/dep/src/zthread/posix/Monitor.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMONITOR_H__ +#define __ZTMONITOR_H__ + +#include "../Status.h" +#include "../FastLock.h" + +namespace ZThread { + +/** + * @class Monitor + * @author Eric Crahen + * @date <2003-07-18T08:16:09-0400> + * @version 2.2.8 + */ +class Monitor : public Status, private NonCopyable { + private: + + //! Serialize access to external objects + FastLock _lock; + + //! Condition variable used to block a thread. + pthread_cond_t _waitCond; + + //! Serialize access to the internal state of the monitor + pthread_mutex_t _waitLock; + + //! Owning thread + pthread_t _owner; + + //! Waiting flag, to avoid uneccessary signals + volatile bool _waiting; + + public: + + typedef Status::STATE STATE; + + //! Create a new monitor. + Monitor(); + + //! Destroy the monitor. + ~Monitor(); + + //! Acquire the lock for this monitor. + inline void acquire() { + _lock.acquire(); + } + + //! Acquire the lock for this monitor. + inline bool tryAcquire() { + return _lock.tryAcquire(); + } + + //! Release the lock for this monitor + inline void release() { + _lock.release(); + } + + /** + * Wait for a state change and atomically unlock the external lock. + * Blocks for an indefinent amount of time. + * + * @return INTERRUPTED if the wait was ended by a interrupt() + * or SIGNALED if the wait was ended by a notify() + * + * @post the external lock is always acquired before this function returns + */ + inline STATE wait() { + return wait(0); + } + + /** + * Wait for a state change and atomically unlock the external lock. + * May blocks for an indefinent amount of time. + * + * @param timeout - maximum time to block (milliseconds) or 0 to + * block indefinently + * + * @return INTERRUPTED if the wait was ended by a interrupt() + * or TIMEDOUT if the maximum wait time expired. + * or SIGNALED if the wait was ended by a notify() + * + * @post the external lock is always acquired before this function returns + */ + STATE wait(unsigned long timeout); + + /** + * Interrupt this monitor. If there is a thread blocked on this monitor object + * it will be signaled and released. If there is no waiter, a flag is set and + * the next attempt to wait() will return INTERRUPTED w/o blocking. + * + * @return false if the thread was previously INTERRUPTED. + */ + bool interrupt(); + + /** + * Notify this monitor. If there is a thread blocked on this monitor object + * it will be signaled and released. If there is no waiter, a flag is set and + * the next attempt to wait() will return SIGNALED w/o blocking, if no other + * flag is set. + * + * @return false if the thread was previously INTERRUPTED. + */ + bool notify(); + + /** + * Check the state of this monitor, clearing the INTERRUPTED status if set. + * + * @return bool true if the monitor was INTERRUPTED. + * @post INTERRUPTED flag cleared if the calling thread owns the monitor. + */ + bool isInterrupted(); + + /** + * Mark the Status CANCELED, and INTERRUPT the montor. + * + * @see interrupt() + */ + bool cancel(); + + /** + * Test the CANCELED Status, clearing the INTERRUPTED status if set. + * + * @return bool + */ + bool isCanceled(); + +}; + +}; + +#endif diff --git a/dep/src/zthread/posix/PriorityOps.h b/dep/src/zthread/posix/PriorityOps.h new file mode 100644 index 000000000..92da66a9c --- /dev/null +++ b/dep/src/zthread/posix/PriorityOps.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTPRIORITYOPS_H__ +#define __ZTPRIORITYOPS_H__ + +#include "zthread/Priority.h" +#include "../ThreadOps.h" + +namespace ZThread { + +/** + * @class PriorityOps + * @author Eric Crahen + * @date <2003-07-16T23:30:00-0400> + * @version 2.2.0 + * + * This class is an abstraction used to perform various operations on a + * native POSIX thread. + */ +class PriorityOps { + + +public: + + +}; + + +} // namespace ZThread + +#endif // __ZTPRIORITYOPS_H__ diff --git a/dep/src/zthread/posix/TSS.h b/dep/src/zthread/posix/TSS.h new file mode 100644 index 000000000..931ff348b --- /dev/null +++ b/dep/src/zthread/posix/TSS.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTSS_H__ +#define __ZTTSS_H__ + +#include "zthread/NonCopyable.h" +#include +#include + +namespace ZThread { + + /** + * @class TSS + * @author Eric Crahen + * @date <2003-07-27T14:18:37-0400> + * @version 2.3.0 + * + * An abstraction for dealing with POSIX thread specific storage (tss). + * Provides get/set and creation/destruction. + */ + template + class TSS : private NonCopyable { + + pthread_key_t _key; + + public: + + /** + * Create a new object for accessing tss. + */ + TSS() { + + if(pthread_key_create(&_key, 0) != 0) { + assert(0); // Key creation failed + } + + } + + /** + * Destroy the underlying supoprt for accessing tss with this + * object. + */ + ~TSS() { + + pthread_key_delete(_key); + + } + + /** + * Get the value stored in tss. + * + * @return T + * + * @exception InvalidOp_exception thrown when the tss is not properly initialized + */ + T get() const { + return reinterpret_cast(pthread_getspecific(_key)); + } + + + /** + * Store a value in tss. + * + * @param value T + * @return T old value + * + * @exception InvalidOp_exception thrown when the tss is not properly initialized + */ + T set(T value) const { + + T oldValue = get(); + pthread_setspecific(_key, value); + + return oldValue; + + } + + }; + +} + +#endif + + diff --git a/dep/src/zthread/posix/ThreadOps.cxx b/dep/src/zthread/posix/ThreadOps.cxx new file mode 100644 index 000000000..e72ef78ad --- /dev/null +++ b/dep/src/zthread/posix/ThreadOps.cxx @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "ThreadOps.h" +#include "zthread/Guard.h" +#include "zthread/Runnable.h" +#include + +#if defined(HAVE_SCHED_YIELD) +# include +#endif + +namespace ZThread { + +const ThreadOps ThreadOps::INVALID(0); + +bool ThreadOps::join(ThreadOps* ops) { + + assert(ops); + assert(ops->_tid != 0); + + int err = 0; + + do { + + err = pthread_join(ops->_tid, NULL); + + } while(err == EINTR); + + return err == 0; + +} + +bool ThreadOps::yield() { + + bool result = false; + +#if defined(HAVE_SCHED_YIELD) + result = sched_yield() == 0; +#endif + + return result; + +} + +bool ThreadOps::setPriority(ThreadOps* impl, Priority p) { + + assert(impl); + + bool result = true; + +#if !defined(ZTHREAD_DISABLE_PRIORITY) + + struct sched_param param; + + switch(p) { + case Low: + param.sched_priority = 0; + break; + case High: + param.sched_priority = 10; + break; + case Medium: + default: + param.sched_priority = 5; + } + + result = pthread_setschedparam(impl->_tid, SCHED_OTHER, ¶m) == 0; + +#endif + + return result; + +} + +bool ThreadOps::getPriority(ThreadOps* impl, Priority& p) { + + assert(impl); + + bool result = true; + +#if !defined(ZTHREAD_DISABLE_PRIORITY) + + struct sched_param param; + int policy = SCHED_OTHER; + + if(result = (pthread_getschedparam(impl->_tid, &policy, ¶m) == 0)) { + + // Convert to one of the PRIORITY values + if(param.sched_priority < 10) + p = Low; + else if(param.sched_priority == 10) + p = Medium; + else + p = High; + + } + +#endif + + return result; + +} + + +bool ThreadOps::spawn(Runnable* task) { + return pthread_create(&_tid, 0, _dispatch, task) == 0; +} + + + +extern "C" void *_dispatch(void *arg) { + + Runnable* task = reinterpret_cast(arg); + assert(task); + + // Run the task from the correct context + task->run(); + + // Exit the thread + pthread_exit((void**)0); + return (void*)0; + +} + +} // namespace ZThread + + diff --git a/dep/src/zthread/posix/ThreadOps.h b/dep/src/zthread/posix/ThreadOps.h new file mode 100644 index 000000000..be754c2d6 --- /dev/null +++ b/dep/src/zthread/posix/ThreadOps.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADOPS_H__ +#define __ZTTHREADOPS_H__ + + +#include "zthread/Priority.h" +#include +#include + +namespace ZThread { + +class Runnable; + +//! Dispatch function for native pthreads required extern C +//! linkage. +extern "C" void* _dispatch(void*); + +/** + * @class ThreadOps + * @author Eric Crahen + * @date <2003-07-16T23:30:25-0400> + * @version 2.2.8 + * + * This class is an abstraction used to perform various operations on a + * native POSIX thread. + */ +class ThreadOps { + + //! Keep track of the pthreads handle for the native thread + pthread_t _tid; + + ThreadOps(pthread_t tid) : _tid(tid) { } + +public: + + const static ThreadOps INVALID; + + /** + * Create a new ThreadOps to manipulate a native thread. + */ + ThreadOps() : _tid(0) { } + + + inline bool operator==(const ThreadOps& ops) const { + return pthread_equal(_tid, ops._tid); + } + + + static ThreadOps self() { + return ThreadOps(pthread_self()); + } + + /** + * Activating an instance of ThreadOps will map it onto the currently + * executing thread. + */ + static void activate(ThreadOps* ops) { + + assert(ops); + assert(ops->_tid == 0); + + ops->_tid = pthread_self(); + + } + + /** + * Test if this object represents the currently executing + * native thread. + * + * @return bool true if successful + */ + + static bool isCurrent(ThreadOps* ops) { + + assert(ops); + + return pthread_equal(pthread_self(), ops->_tid); + + } + + /** + * Join a native thread. + * + * @return bool true if successful + */ + static bool join(ThreadOps*); + + /** + * Force the current native thread to yield, letting the scheduler + * give the CPU time to another thread. + * + * @return bool true if successful, false if the operation can't + * be supported. + */ + static bool yield(); + + /** + * Set the priority for the native thread if supported by the + * system. + * + * @param PRIORITY requested priority + * @return bool false if unsuccessful + */ + static bool setPriority(ThreadOps*, Priority); + + /** + * Set the priority for the native thread if supported by the + * system. + * + * @param Thread::PRIORITY& current priority + * @return bool false if unsuccessful + */ + static bool getPriority(ThreadOps*, Priority&); + +protected: + + /** + * Spawn a native thread. + * + * @param ThreadImpl* parent thread + * @param ThreadImpl* child thread being started. + * @param Runnable* task being executed. + * + * @return bool true if successful + */ + bool spawn(Runnable*); + +}; + + +} + +#endif // __ZTTHREADOPS_H__ diff --git a/dep/src/zthread/solaris/FastRecursiveLock.h b/dep/src/zthread/solaris/FastRecursiveLock.h new file mode 100644 index 000000000..956e1dbd3 --- /dev/null +++ b/dep/src/zthread/solaris/FastRecursiveLock.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "zthread/NonCopyable.h" +#include + +namespace ZThread { + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:31:23-0400> + * @version 2.2.0 + * + * This FastRecursiveLock implementation uses pthreads mutex attribute + * functions to create a recursive lock. This implementation is not + * specific to solaris and will work on any system that supports + * pthread_mutexattr_settype(). + */ +class FastRecursiveLock : private NonCopyable { + + pthread_mutex_t _mtx; + + /** + * @class Attribute + * + * Utility class to maintain the attribute as long as it is needed. + */ + class Attribute { + + pthread_mutexattr_t _attr; + + public: + + Attribute() { + + if(pthread_mutexattr_init(&_attr) != 0) { + assert(0); + } + + if(pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE) != 0) { + assert(0); + } + + } + + ~Attribute() { + + if(pthread_mutexattr_destroy(&_attr) != 0) { + assert(0); + } + + } + + operator pthread_mutexattr_t*() { + return &_attr; + } + + }; + +public: + + inline FastRecursiveLock() { + + static Attribute attr; + pthread_mutex_init(&_mtx, (pthread_mutexattr_t*)attr); + + } + + inline ~FastRecursiveLock() { + + pthread_mutex_destroy(&_mtx); + + } + + inline void acquire() { + + pthread_mutex_lock(&_mtx); + + } + + inline void release() { + + pthread_mutex_unlock(&_mtx); + + } + + inline bool tryAcquire(unsigned long timeout=0) { + + return (pthread_mutex_trylock(&_mtx) == 0); + + } + +}; /* FastRecursiveLock */ + + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/vanilla/DualMutexRecursiveLock.h b/dep/src/zthread/vanilla/DualMutexRecursiveLock.h new file mode 100644 index 000000000..ddce7a3cd --- /dev/null +++ b/dep/src/zthread/vanilla/DualMutexRecursiveLock.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "../FastLock.h" +#include "../ThreadOps.h" +#include + +namespace ZThread { + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:31:09-0400> + * @version 2.2.8 + * + * This is a vanilla FastRecursiveLock implementation for a + * system that doesn't provide recurisve locks. This implementation + * is based on using a pair of mutexes, because of this, it performs + * roughly the same as a spin lock would. + */ +class FastRecursiveLock : private NonCopyable { + + //! Lock for blocking + FastLock _blockingLock; + + //! Serialize state + FastLock _stateLock; + + //! Owner + ThreadOps _owner; + + //! Count + volatile unsigned int _count; + + public: + + inline FastRecursiveLock() : _owner(ThreadOps::INVALID), _count(0) { } + + inline ~FastRecursiveLock() { + + assert(_owner == ThreadOps::INVALID); + assert(_count == 0); + + } + + void acquire() { + + ThreadOps self(ThreadOps::self()); + + // Try to lock the blocking mutex first + bool wasLocked = _blockingLock.tryAcquire(); + if(!wasLocked) { + + // Otherwise, grab the lock for the state + _stateLock.acquire(); + + wasLocked = (_owner == self); + if(wasLocked) + _count++; + + _stateLock.release(); + + if(wasLocked) + return; + + // Try to be cooperative + ThreadOps::yield(); + _blockingLock.acquire(); + + } + + // Serialze access to the state + _stateLock.acquire(); + + // Take ownership + assert(_owner == ThreadOps::INVALID || _owner == self); + + _owner = self; + _count++; + + _stateLock.release(); + + } + + + bool tryAcquire(unsigned long timeout = 0) { + + ThreadOps self(ThreadOps::self()); + + // Try to lock the blocking mutex first + bool wasLocked = _blockingLock.tryAcquire(); + if(!wasLocked) { + + // Otherwise, grab the lock for the state + _stateLock.acquire(); + + wasLocked = (_owner == self); + if(wasLocked) + _count++; + + _stateLock.release(); + + return wasLocked; + + } + + // Serialze access to the state + _stateLock.acquire(); + + // Take ownership + assert(_owner == ThreadOps::INVALID || _owner == self); + + _owner = self; + _count++; + + _stateLock.release(); + + return true; + + } + + + void release() { + + // Assume that release is only used by the owning thread, as it + // should be. + assert(_count != 0); + assert(_owner == ThreadOps::self()); + + _stateLock.acquire(); + + // If the lock was owned and the count has reached 0, give up + // ownership and release the blocking lock + if(--_count == 0) { + + _owner = ThreadOps::INVALID; + _blockingLock.release(); + + } + + _stateLock.release(); + + } + + +}; /* FastRecursiveLock */ + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/vanilla/SimpleAtomicCount.cxx b/dep/src/zthread/vanilla/SimpleAtomicCount.cxx new file mode 100644 index 000000000..fc63d141d --- /dev/null +++ b/dep/src/zthread/vanilla/SimpleAtomicCount.cxx @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTATOMICCOUNTIMPL_H__ +#define __ZTATOMICCOUNTIMPL_H__ + +#include "zthread/Guard.h" +#include "../FastLock.h" + +#include + +namespace ZThread { + +typedef struct atomic_count_t { + + FastLock lock; + unsigned long count; + + atomic_count_t() : count(0) {} + +} ATOMIC_COUNT; + +AtomicCount::AtomicCount() { + + ATOMIC_COUNT* c = new ATOMIC_COUNT; + _value = reinterpret_cast(c); + +} + +AtomicCount::~AtomicCount() { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + assert(c->count == 0); + + delete c; + +} + +//! Postfix decrement and return the current value +size_t AtomicCount::operator--(int) { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + + Guard g(c->lock); + return c->count--; + +} + +//! Postfix increment and return the current value +size_t AtomicCount::operator++(int) { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + + Guard g(c->lock); + return c->count++; + +} + +//! Prefix decrement and return the current value +size_t AtomicCount::operator--() { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + + Guard g(c->lock); + return --c->count; + +} + +//! Prefix increment and return the current value +size_t AtomicCount::operator++() { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + + Guard g(c->lock); + return ++c->count; + +} + +}; + +#endif // __ZTATOMICCOUNTIMPL_H__ diff --git a/dep/src/zthread/vanilla/SimpleRecursiveLock.h b/dep/src/zthread/vanilla/SimpleRecursiveLock.h new file mode 100644 index 000000000..f4f309218 --- /dev/null +++ b/dep/src/zthread/vanilla/SimpleRecursiveLock.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "../FastLock.h" +#include "../ThreadOps.h" +#include + +namespace ZThread { + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:30:59-0400> + * @version 2.2.8 + * + * This implementation of a FastRecursiveLock uses the which ever FastLock + * that is selected to create a recursive spin lock. + */ +class FastRecursiveLock : private NonCopyable { + + FastLock _lock; + + ThreadOps _owner; + + volatile unsigned int _count; + +public: + + inline FastRecursiveLock() : _owner(ThreadOps::INVALID), _count(0) {} + + inline ~FastRecursiveLock() { + + assert(_owner == ThreadOps::INVALID); + assert(_count == 0); + + } + + inline void acquire() { + + ThreadOps self(ThreadOps::self()); + bool wasLocked = false; + + do { + + _lock.acquire(); + + // If there is no owner, or the owner is the caller + // update the count + if(_owner == ThreadOps::INVALID || _owner == self) { + + _owner = self; + _count++; + + wasLocked = true; + + } + + _lock.release(); + + } while(!wasLocked); + + assert(_owner == ThreadOps::self()); + + } + + inline void release() { + + assert(_owner == ThreadOps::self()); + + _lock.acquire(); + + if(--_count == 0) + _owner = ThreadOps::INVALID; + + _lock.release(); + + } + + inline bool tryAcquire(unsigned long timeout=0) { + + ThreadOps self(ThreadOps::self()); + bool wasLocked = false; + + _lock.acquire(); + + if(_owner == ThreadOps::INVALID || _owner == self) { + + _owner = self; + _count++; + + wasLocked = true; + + } + + _lock.release(); + + assert(!wasLocked || _owner == ThreadOps::self()); + return wasLocked; + + } + +}; /* FastRecursiveLock */ + + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/win32/AtomicCount.cxx b/dep/src/zthread/win32/AtomicCount.cxx new file mode 100644 index 000000000..84cbf8c3d --- /dev/null +++ b/dep/src/zthread/win32/AtomicCount.cxx @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTATOMICCOUNTIMPL_H__ +#define __ZTATOMICCOUNTIMPL_H__ + +#include +#include + +namespace ZThread { + + +AtomicCount::AtomicCount() { + + _value = reinterpret_cast(new LONG(0)); + +} + +AtomicCount::~AtomicCount() { + + assert(*reinterpret_cast(_value) == 0); + delete reinterpret_cast(_value); + +} + +void AtomicCount::increment() { + + ::InterlockedIncrement(reinterpret_cast(_value)); + +} + +bool AtomicCount::decrement() { + + LONG v = ::InterlockedDecrement(reinterpret_cast(_value)); + return static_cast(v) == 0; + +} + +}; + +#endif // __ZTATOMICCOUNTIMPL_H__ diff --git a/dep/src/zthread/win32/AtomicFastLock.h b/dep/src/zthread/win32/AtomicFastLock.h new file mode 100644 index 000000000..a714c0378 --- /dev/null +++ b/dep/src/zthread/win32/AtomicFastLock.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCK_H__ +#define __ZTFASTLOCK_H__ + +#include "zthread/NonCopyable.h" +#include +#include + +namespace ZThread { + + +/** + * @class FastLock + * + * @author Eric Crahen + * @date <2003-07-16T23:32:20-0400> + * @version 2.1.6 + * + * This is the smallest and fastest synchronization object in the library. + * It is an implementation of fast mutex, an all or nothing exclusive + * lock. It should be used only where you need speed and are willing + * to sacrifice all the state & safety checking provided by the framework + * for speed. + * + * The current Platform SDK defines: + * + * LONG InterlockedExchange(LPLONG, LONG) + * LONG InterlockedCompareExchange(LPLONG, LONG, LONG, LONG) + * + * If your compiler complains about LPLONG not being implicitly casted to + * a PVOID, then you should get the SDK update from microsoft or use the + * WIN9X implementation of this class. + * + * ---- + * Because Windows 95 and earlier can run on processors prior to the 486, they + * don't all support the CMPXCHG function, and so Windows 95 an earlier dont support + * InterlockedCompareExchange. For this, you should use the win9x implementation + * of this class + */ +class FastLock : private NonCopyable { + +#pragma pack(push, 8) + LONG volatile _lock; +#pragma pack(pop) + + public: + + /** + * Create a new FastLock + */ + inline FastLock() : _lock(0) { } + + + /** + * Destroy FastLock + */ + inline ~FastLock() { assert(_lock == 0); } + + /** + * Lock the fast Lock, no error check. + * + * @exception None + */ + inline void acquire() { + + while (::InterlockedCompareExchange(const_cast(&_lock), 1, 0) != 0) + ::Sleep(0); + + } + + + /** + * Release the fast Lock, no error check. + * + * @exception None + */ + inline void release() { + + ::InterlockedExchange(const_cast(&_lock), (LONG)0); + + } + + /** + * Try to acquire an exclusive lock. No safety or state checks are performed. + * This function returns immediately regardless of the value of the timeout + * + * @param timeout Unused + * @return bool + * @exception Synchronization_Exception - not thrown + */ + inline bool tryAcquire(unsigned long timeout=0) { + + return ::InterlockedCompareExchange(const_cast(&_lock), 1, 0) == 0; + + } + +}; /* FastLock */ + + +}; +#endif diff --git a/dep/src/zthread/win32/AtomicFastRecursiveLock.h b/dep/src/zthread/win32/AtomicFastRecursiveLock.h new file mode 100644 index 000000000..c6a61b03b --- /dev/null +++ b/dep/src/zthread/win32/AtomicFastRecursiveLock.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "zthread/NonCopyable.h" +#include +#include + +namespace ZThread { + + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:32:34-0400> + * @version 2.1.6 + * + * This is the smaller and faster implementation of a RecursiveLock. + * A single thread can acquire the mutex any number of times, but it + * must perform a release for each acquire(). Other threads are blocked + * until a thread has released all of its locks on the mutex. + * + * This particular implementation performs fewer safety checks. Like + * the FastLock implementation, any waiting caused by an acquire() request + * is not interruptable. This is so that the mutex can have the fastest + * response time for a time critical application while still having a good + * degree of reliability. + * + * TryEnterCriticalSection() does not work at all on some systems, so its + * not used. + * + * + * The current Platform SDK defines: + * + * LONG InterlockedExchange(LPLONG, LONG) + * LONG InterlockedCompareExchange(LPLONG, LONG, LONG, LONG) + * + * If your compiler complains about LPLONG not being implicitly casted to + * a PVOID, then you should get the SDK update from microsoft or use the + * WIN9X implementation of this class. + * + * ---- + * Because Windows 95 and earlier can run on processors prior to the 486, they + * don't all support the CMPXCHG function, and so Windows 95 an earlier dont support + * InterlockedCompareExchange. If you define ZT_WIN9X, you'll get a version of the + * FastLock that uses the XCHG instruction + */ +class FastRecursiveLock : private NonCopyable { + +// Add def for mingw32 or other non-ms compiler to align on 64-bit +// boundary +#pragma pack(push, 8) + LONG volatile _lock; +#pragma pack(pop) + LONG _count; + + public: + + /** + * Create a new FastRecursiveLock + */ + inline FastRecursiveLock() : _lock(0), _count(0) { } + + + /** + * Destroy FastLock + */ + inline ~FastRecursiveLock() { + assert(_lock == 0); + } + + /** + * Lock the fast Lock, no error check. + * + * @exception None + */ + inline void acquire() { + + DWORD id = ::GetCurrentThreadId(); + + // Take ownership if the lock is free or owned by the calling thread + do { + + DWORD owner = (DWORD)::InterlockedCompareExchange(const_cast(&_lock), id, 0); + if(owner == 0 || owner == id) + break; + + ::Sleep(0); + + } while(1); + + _count++; + + } + + + /** + * Release the fast Lock, no error check. + * + * @exception None + */ + inline void release() { + + if(--_count == 0) + ::InterlockedExchange(const_cast(&_lock), 0); + + } + + /** + * Try to acquire an exclusive lock. No safety or state checks are performed. + * This function returns immediately regardless of the value of the timeout + * + * @param timeout Unused + * @return bool + * @exception Synchronization_Exception - not thrown + */ + inline bool tryAcquire(unsigned long timeout=0) { + + DWORD id = ::GetCurrentThreadId(); + DWORD owner = (DWORD)::InterlockedCompareExchange(const_cast(&_lock), id, 0); + + if(owner == 0 || owner == id) { + _count++; + return true; + } + + return false; + + } + + +}; /* FastRecursiveLock */ + + +}; +#endif diff --git a/dep/src/zthread/win32/FastLock.h b/dep/src/zthread/win32/FastLock.h new file mode 100644 index 000000000..2e9fe829a --- /dev/null +++ b/dep/src/zthread/win32/FastLock.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCK_H__ +#define __ZTFASTLOCK_H__ + +#include "zthread/Exceptions.h" +#include "zthread/NonCopyable.h" +#include "../ThreadOps.h" +#include +#include + +namespace ZThread { + + /** + * @class FastLock + * + * @author Eric Crahen + * @date <2003-07-16T23:32:44-0400> + * @version 2.2.11 + * + * This FastLock implementation is based on a Win32 Mutex + * object. This will perform better under high contention, + * but will not be as fast as the spin lock under reasonable + * circumstances. + */ + class FastLock : private NonCopyable { + + HANDLE _hMutex; +#ifndef NDEBUG + volatile bool _locked; +#endif + + public: + + /** + * Create a new FastLock + */ + FastLock() { + +#ifndef NDEBUG + _locked = false; +#endif + + _hMutex = ::CreateMutex(0, 0, 0); + assert(_hMutex != NULL); + if(_hMutex == NULL) + throw Initialization_Exception(); + + } + + + ~FastLock() { + ::CloseHandle(_hMutex); + } + + void acquire() { + + if(::WaitForSingleObject(_hMutex, INFINITE) != WAIT_OBJECT_0) { + assert(0); + throw Synchronization_Exception(); + } + +#ifndef NDEBUG + + // Simulate deadlock to provide consistent behavior. This + // will help avoid errors when porting. Avoiding situations + // where a FastMutex mistakenly behaves as a recursive lock. + + while(_locked) + ThreadOps::yield(); + + _locked = true; + +#endif + + } + + void release() { + +#ifndef NDEBUG + _locked = false; +#endif + + if(::ReleaseMutex(_hMutex) == 0) { + assert(0); + throw Synchronization_Exception(); + } + + } + + + bool tryAcquire(unsigned long timeout = 0) { + + switch(::WaitForSingleObject(_hMutex, timeout)) { + case WAIT_OBJECT_0: + +#ifndef NDEBUG + + // Simulate deadlock to provide consistent behavior. This + // will help avoid errors when porting. Avoiding situations + // where a FastMutex mistakenly behaves as a recursive lock. + + while(_locked) + ThreadOps::yield(); + + _locked = true; + +#endif + + return true; + case WAIT_TIMEOUT: + return false; + default: + break; + } + + assert(0); + throw Synchronization_Exception(); + + } + + }; + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/win32/FastRecursiveLock.h b/dep/src/zthread/win32/FastRecursiveLock.h new file mode 100644 index 000000000..e1a6e7cd6 --- /dev/null +++ b/dep/src/zthread/win32/FastRecursiveLock.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTRECURSIVELOCK_H__ +#define __ZTFASTRECURSIVELOCK_H__ + +#include "zthread/Exceptions.h" +#include "zthread/NonCopyable.h" +#include +#include + +namespace ZThread { + + +/** + * @class FastRecursiveLock + * + * @author Eric Crahen + * @date <2003-07-16T23:32:56-0400> + * @version 2.2.11 + * + * This FastRecursiveLock implementation is based on a Win32 Mutex + * object. This will perform better under high contention, + * but will not be as fast as the spin lock under reasonable + * circumstances. + */ +class FastRecursiveLock : private NonCopyable { + + HANDLE _hMutex; + volatile unsigned int _count; + + public: + + /** + * Create a new FastRecursiveLock + */ + FastRecursiveLock() : _count(0) { + + _hMutex = ::CreateMutex(0, 0, 0); + assert(_hMutex != NULL); + if(_hMutex == NULL) + throw Initialization_Exception(); + + } + + + ~FastRecursiveLock() { + ::CloseHandle(_hMutex); + } + + + void acquire() { + + if(::WaitForSingleObject(_hMutex, INFINITE) != WAIT_OBJECT_0) { + assert(0); + throw Synchronization_Exception(); + } + + } + + void release() { + + if(::ReleaseMutex(_hMutex) == 0) { + assert(0); + throw Synchronization_Exception(); + } + + } + + bool tryAcquire(unsigned long) { + + switch(::WaitForSingleObject(_hMutex, 0)) { + case WAIT_OBJECT_0: + return true; + case WAIT_TIMEOUT: + return false; + default: + break; + } + + assert(0); + throw Synchronization_Exception(); + + } + +}; /* FastRecursiveLock */ + +} // namespace ZThread + +#endif diff --git a/dep/src/zthread/win32/Monitor.cxx b/dep/src/zthread/win32/Monitor.cxx new file mode 100644 index 000000000..6e69487c0 --- /dev/null +++ b/dep/src/zthread/win32/Monitor.cxx @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "Monitor.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +using namespace ZThread; + +Monitor::Monitor() : _owner(0), _waiting(false) { + + _handle = ::CreateEvent(0, TRUE, FALSE, 0); + if(_handle == NULL) { + assert(0); + } + +} + +Monitor::~Monitor() { + + assert(!_waiting); + + ::CloseHandle(_handle); + +} + +Monitor::STATE Monitor::wait(unsigned long ms) { + + // Update the owner on first use. The owner will not change, each + // thread waits only on a single Monitor and a Monitor is never + // shared + if(_owner == 0) + _owner = ::GetCurrentThreadId(); + + STATE state; //(INVALID); + + // Serialize access to the state of the Monitor + // and test the state to determine if a wait is needed. + _waitLock.acquire(); + + if(pending(ANYTHING)) { + + // Return without waiting when possible + state = next(); + + _waitLock.release(); + return state; + + } + // Unlock the external lock if a wait() is probably needed. + // Access to the state is still serial. + _lock.release(); + + // Wait for a transition in the state that is of interest, this + // allows waits to exclude certain flags (e.g. INTERRUPTED) + // for a single wait() w/o actually discarding those flags - + // they will remain set until a wait interested in those flags + // occurs. + // if(!currentState(interest)) { + + // Wait, ignoring signals + _waiting = true; + + // Block until the event is set. + _waitLock.release(); + + // The event is manual reset so this lack of atmoicity will not + // be an issue + + DWORD dwResult = + ::WaitForSingleObject(_handle, ((ms == 0) ? INFINITE : (DWORD)ms)); + + // Reacquire serialized access to the state + _waitLock.acquire(); + + // Awaken only when the event is set or the timeout expired + assert(dwResult == WAIT_OBJECT_0 || dwResult == WAIT_TIMEOUT); + + if(dwResult == WAIT_TIMEOUT) + push(TIMEDOUT); + + // Get the next available STATE + state = next(); + _waiting = false; + + ::ResetEvent(_handle); + + // Acquire the internal lock & release the external lock + _waitLock.release(); + + // Reaquire the external lock, keep from deadlocking threads calling + // notify(), interrupt(), etc. + _lock.acquire(); + + return state; + +} + + +bool Monitor::interrupt() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasInterruptable = !pending(INTERRUPTED); + bool hadWaiter = _waiting; + + if(wasInterruptable) { + + // Update the state & wake the waiter if there is one + push(INTERRUPTED); + + wasInterruptable = false; + + if(hadWaiter && !masked(Monitor::INTERRUPTED)) { + + // Blocked on a synchronization object + if(::SetEvent(_handle) == FALSE) { + assert(0); + } + + } else + wasInterruptable = !(_owner == ::GetCurrentThreadId()); + + } + + _waitLock.release(); + + // Only returns true when an interrupted thread is not currently blocked + return wasInterruptable; + +} + +bool Monitor::isInterrupted() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasInterrupted = pending(INTERRUPTED); + clear(INTERRUPTED); + + _waitLock.release(); + + return wasInterrupted; + +} + + +bool Monitor::notify() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasNotifyable = !pending(INTERRUPTED); + + if(wasNotifyable) { + + // Set the flag and wake the waiter if there + // is one + push(SIGNALED); + + // If there is a waiter then send the signal. + if(_waiting) + if(::SetEvent(_handle) == FALSE) { + assert(0); + } + + } + + _waitLock.release(); + + return wasNotifyable; + +} + + +bool Monitor::cancel() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasInterrupted = !pending(INTERRUPTED); + bool hadWaiter = _waiting; + + push(CANCELED); + + if(wasInterrupted) { + + // Update the state & wake the waiter if there is one + push(INTERRUPTED); + + // If there is a waiter then send the signal. + if(hadWaiter && !masked(Monitor::INTERRUPTED)) + if(::SetEvent(_handle) == FALSE) { + assert(0); + } + + } + + _waitLock.release(); + + return wasInterrupted; + +} + +bool Monitor::isCanceled() { + + // Serialize access to the state + _waitLock.acquire(); + + bool wasCanceled = examine(CANCELED); + + if(_owner == ::GetCurrentThreadId()) + clear(INTERRUPTED); + + _waitLock.release(); + + return wasCanceled; + +} + diff --git a/dep/src/zthread/win32/Monitor.h b/dep/src/zthread/win32/Monitor.h new file mode 100644 index 000000000..7073343b7 --- /dev/null +++ b/dep/src/zthread/win32/Monitor.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTMONITOR_H__ +#define __ZTMONITOR_H__ + +#include "../Status.h" +#include "../FastLock.h" + +namespace ZThread { + +/** + * @class Monitor + * @author Eric Crahen + * @date <2003-07-16T23:33:10-0400> + * @version 2.2.11 + */ +class Monitor : public Status, private NonCopyable { + + //! Serialize access to external objects + FastLock _lock; + + //! Event used to block thread + HANDLE _handle; + + //! Serialize access to the internal state of the monitor + FastLock _waitLock; + + //! Owning thread + DWORD _owner; + + //! Waiting flag, to avoid uneccessary signals + volatile bool _waiting; + + //! State of the monitor + volatile int _state; + + public: + + //! Create a new monitor. + Monitor(); + + //! Destroy the monitor. + ~Monitor(); + + //! Acquire the external lock for this monitor. + inline void acquire() { + _lock.acquire(); + } + + //! Try to acquire the external lock for this monitor. + inline bool tryAcquire() { + return _lock.tryAcquire(); + } + + //! Release the external lock for this monitor. + inline void release() { + _lock.release(); + } + + /** + * Wait for a state change and atomically unlock the external lock. + * Blocks for an indefinent amount of time. + * + * @return INTERRUPTED if the wait was ended by a interrupt() + * or SIGNALED if the wait was ended by a notify() + * + * @post the external lock is always acquired before this function returns + */ + inline STATE wait() { + return wait(0); + } + + /** + * Wait for a state change and atomically unlock the external lock. + * May blocks for an indefinent amount of time. + * + * @param timeout - maximum time to block (milliseconds) or 0 to + * block indefinently + * + * @return INTERRUPTED if the wait was ended by a interrupt() + * or TIMEDOUT if the maximum wait time expired. + * or SIGNALED if the wait was ended by a notify() + * + * @post the external lock is always acquired before this function returns + */ + STATE wait(unsigned long timeout); + + /** + * Interrupt this monitor. If there is a thread blocked on this monitor object + * it will be signaled and released. If there is no waiter, a flag is set and + * the next attempt to wait() will return INTERRUPTED w/o blocking. + * + * @return false if the thread was previously INTERRUPTED. + */ + bool interrupt(); + + /** + * Notify this monitor. If there is a thread blocked on this monitor object + * it will be signaled and released. If there is no waiter, a flag is set and + * the next attempt to wait() will return SIGNALED w/o blocking, if no other + * flag is set. + * + * @return false if the thread was previously INTERRUPTED. + */ + bool notify(); + + /** + * Check the state of this monitor, clearing the INTERRUPTED status if set. + * + * @return bool true if the monitor was INTERRUPTED. + * @post INTERRUPTED flag cleared if the calling thread owns the monitor. + */ + bool isInterrupted(); + + /** + * Mark the Status CANCELED, and INTERRUPT the montor. + * + * @see interrupt() + */ + bool cancel(); + + /** + * Test the CANCELED Status, clearing the INTERRUPTED status if set. + * + * @return bool + */ + bool isCanceled(); + +}; + +}; + +#endif diff --git a/dep/src/zthread/win32/PerformanceCounterStrategy.h b/dep/src/zthread/win32/PerformanceCounterStrategy.h new file mode 100644 index 000000000..95b526830 --- /dev/null +++ b/dep/src/zthread/win32/PerformanceCounterStrategy.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTIMESTRATEGY_H__ +#define __ZTTIMESTRATEGY_H__ + +#include +#include + +namespace ZThread { + +/** + * @class PerformanceCounterStrategy + * + * Implement a strategy for time operatons based on + * Windows QueryPerformanceXXX() functions. + * This only (erroneously) considers the lower 32 bits. + */ +class TimeStrategy { + + unsigned long _secs; + unsigned long _millis; + +public: + + TimeStrategy() { + + // Keep track of the relative time the program started + static LARGE_INTEGER i; + static BOOL valid(::QueryPerformanceCounter(&i)); + + assert(valid == TRUE); + + LARGE_INTEGER j; + ::QueryPerformanceCounter(&j); + + j.LowPart -= i.LowPart; + j.LowPart /= frequency(); + + // Mask off the high bits + _millis = (unsigned long)j.LowPart / 1000; + _secs = (unsigned long)j.LowPart - _millis; + + } + + unsigned long seconds() const { + return _secs; + } + + unsigned long milliseconds() const { + return _millis; + } + + unsigned long seconds(unsigned long s) { + + unsigned long z = seconds(); + + _secs = s; + return z; + + } + + unsigned long milliseconds(unsigned long ms) { + + unsigned long z = milliseconds(); + + _millis = ms; + return z; + + } + +private: + + // Get the frequency + static DWORD frequency() { + + static LARGE_INTEGER i; + static BOOL valid(::QueryPerformanceFrequency(&i)); + + assert(valid == TRUE); + return i.LowPart; + + } + +}; + +}; + +#endif // __ZTTIMESTRATEGY_H__ diff --git a/dep/src/zthread/win32/TSS.h b/dep/src/zthread/win32/TSS.h new file mode 100644 index 000000000..2400830f0 --- /dev/null +++ b/dep/src/zthread/win32/TSS.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTSS_H__ +#define __ZTTSS_H__ + +#include + +namespace ZThread { + + /** + * @class TSS + * @author Eric Crahen + * @date <2003-07-27T14:18:43-0400> + * @version 2.3.0 + * + * An abstraction for dealing with WIN32 thread specific storage (tss). + * Provides get/set and creation/destruction. + */ + template + class TSS { + + DWORD _key; + bool _valid; + + public: + + /** + * Create a new object for accessing tss. The def + */ + TSS() { + + _key = ::TlsAlloc(); + _valid = (_key != 0xFFFFFFFF); + + } + + /** + * Destroy the underlying supoprt for accessing tss with this + * object. + */ + virtual ~TSS() { + + if(_valid) + ::TlsFree(_key); + + } + + /** + * Get the value stored in tss. + * + * @return T + * + * @exception InvalidOp_exception thrown when the tss is not properly initialized + */ + inline T get() const { + + if(!_valid) + throw InvalidOp_Exception(); + + return static_cast(::TlsGetValue(_key)); + + } + + /** + * Store a value in tss. + * + * @param value T + * @return T old value + * + * @exception InvalidOp_exception thrown when the tss is not properly initialized + */ + inline T set(T value) const { + + T oldValue = get(); + ::TlsSetValue(_key, value); + + return oldValue; + + } + + + }; + +} + +#endif + + diff --git a/dep/src/zthread/win32/ThreadOps.cxx b/dep/src/zthread/win32/ThreadOps.cxx new file mode 100644 index 000000000..6e8fb8d3b --- /dev/null +++ b/dep/src/zthread/win32/ThreadOps.cxx @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "ThreadOps.h" +#include "zthread/Runnable.h" +#include + +namespace ZThread { + +const ThreadOps ThreadOps::INVALID(0); + +/** + * Detect OS at runtime and attempt to locate the SwitchToThread + * function, which will assist in making the spin lock implementation + * which use ThreadOps::yield() a bit fairer. + */ +class YieldOps { + + typedef BOOL (*Yield)(void); + Yield _fnYield; + +public: + + YieldOps() : _fnYield(NULL) { + + OSVERSIONINFO v; + v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if(::GetVersionEx(&v) && (v.dwPlatformId == VER_PLATFORM_WIN32_NT)) { + + // Uses GetModuleHandle() so the reference count on the dll is + // not affected. There is a warning about race conditions involving + // this function being called as FreeLibrary() completes; however + // nearly all win32 applications load this particular and will keep it + // in memory until the process exits. + HINSTANCE hInst = ::GetModuleHandle("Kernel32.dll"); + if(hInst != NULL) + _fnYield = (Yield)::GetProcAddress(hInst, "SwitchToThread"); + + // REMIND: possibly need to use _T() macro for these strings + } + + } + + bool operator()() { + + // Attempt to yield using the best function available + if(!_fnYield || !_fnYield()) + ::Sleep(0); + + return true; + + } + +}; + +bool ThreadOps::join(ThreadOps* ops) { + + assert(ops); + assert(ops->_tid != 0); + assert(ops->_hThread != NULL); + + if(::WaitForSingleObjectEx(ops->_hThread, INFINITE, FALSE) != WAIT_OBJECT_0) + return false; + + ::CloseHandle(ops->_hThread); + ops->_hThread = NULL; + + return true; + +} + +bool ThreadOps::yield() { + + static YieldOps yielder; + + yielder(); + + return true; + +} + +bool ThreadOps::setPriority(ThreadOps* impl, Priority p) { + + assert(impl); + +#if !defined(ZTHREAD_DISABLE_PRIORITY) + + bool result; + + // Convert + int n; + switch(p) { + case Low: + n = THREAD_PRIORITY_BELOW_NORMAL; + break; + case High: + n = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case Medium: + default: + n = THREAD_PRIORITY_NORMAL; + } + + + result = (::SetThreadPriority(impl->_hThread, n) != THREAD_PRIORITY_ERROR_RETURN); + return result; + +#else + + return true; + +#endif + +} + +bool ThreadOps::getPriority(ThreadOps* impl, Priority& p) { + + assert(impl); + bool result = true; + +#if !defined(ZTHREAD_DISABLE_PRIORITY) + + // Convert to one of the PRIORITY values + switch(::GetThreadPriority(impl->_hThread)) { + case THREAD_PRIORITY_ERROR_RETURN: + result = false; + case THREAD_PRIORITY_BELOW_NORMAL: + p = Low; + break; + case THREAD_PRIORITY_ABOVE_NORMAL: + p = High; + break; + case THREAD_PRIORITY_NORMAL: + default: + p = Medium; + } + +#endif + + return result; + +} + + +bool ThreadOps::spawn(Runnable* task) { + +// Start the thread. +#if defined(HAVE_BEGINTHREADEX) + _hThread = (HANDLE)::_beginthreadex(0, 0, &_dispatch, task, 0, (unsigned int*)&_tid); +#else + _hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&_dispatch, task, 0, (DWORD*)&_tid); +#endif + + return _hThread != NULL; + +} + +unsigned int __stdcall ThreadOps::_dispatch(void *arg) { + + Runnable* task = reinterpret_cast(arg); + assert(task); + + // Run the task from the correct context + task->run(); + + // Exit the thread +#if defined(HAVE_BEGINTHREADEX) + ::_endthreadex(0); +#else + ExitThread(0); +#endif + + return 0; + +} + +} diff --git a/dep/src/zthread/win32/ThreadOps.h b/dep/src/zthread/win32/ThreadOps.h new file mode 100644 index 000000000..4a3eeac2e --- /dev/null +++ b/dep/src/zthread/win32/ThreadOps.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTTHREADOPS_H__ +#define __ZTTHREADOPS_H__ + +#include "zthread/Priority.h" +#include +#include + +namespace ZThread { + +class Runnable; + +/** + * @class ThreadOps + * @author Eric Crahen + * @date <2003-07-16T23:33:59-0400> + * @version 2.2.8 + * + * This class is an abstraction used to perform various operations on a + * native WIN32 thread. + */ +class ThreadOps { + + //! Dispatch function for native thread + static unsigned int __stdcall _dispatch(void*); + + //! TID while the thread is executing. + HANDLE _hThread; + DWORD _tid; + + ThreadOps(DWORD tid) : _tid(tid) { } + + public: + + const static ThreadOps INVALID; + + /** + * Create a new ThreadOps to represent a native thread. + */ + ThreadOps() : _tid(0), _hThread(NULL) {} + + + inline bool operator==(const ThreadOps& ops) const { + return _tid == ops._tid; + } + + + static ThreadOps self() { + return ThreadOps(::GetCurrentThreadId()); + } + + /** + * Update the native tid for this thread so it matches the current + * thread. + */ + static void activate(ThreadOps* ops) { + + assert(ops); + assert(ops->_tid == 0); + + ops->_tid = ::GetCurrentThreadId(); + + } + + /** + * Test if this object representative of the currently executing + * native thread. + * + * @return bool true if successful + */ + static bool isCurrent(ThreadOps* ops) { + + assert(ops); + + return ops->_tid == ::GetCurrentThreadId(); + + } + + /** + * Join a native thread. + * + * @return bool true if successful + */ + static bool join(ThreadOps*); + + /** + * Force the current native thread to yield, letting the scheduler + * give the CPU time to another thread. + * + * @return bool true if successful + */ + static bool yield(); + + /** + * Set the priority for the native thread if supported by the + * system. + * + * @param PRIORITY requested priority + * @return bool false if unsuccessful + */ + static bool setPriority(ThreadOps*, Priority); + + /** + * Set the priority for the native thread if supported by the + * system. + * + * @param Thread::PRIORITY& current priority + * @return bool false if unsuccessful + */ + static bool getPriority(ThreadOps*, Priority&); + +protected: + + /** + * Spawn a native thread. + * + * @param ThreadImpl* parent thread + * @param ThreadImpl* child thread being started. + * @param Runnable* task being executed. + * + * @return bool true if successful + */ + bool spawn(Runnable*); + + +}; + + +} + +#endif diff --git a/dep/src/zthread/win9x/AtomicCount.cxx b/dep/src/zthread/win9x/AtomicCount.cxx new file mode 100644 index 000000000..2bf07dcd2 --- /dev/null +++ b/dep/src/zthread/win9x/AtomicCount.cxx @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTATOMICCOUNTIMPL_H__ +#define __ZTATOMICCOUNTIMPL_H__ + +#include +#include + +namespace ZThread { + +typedef struct atomic_count_t { + + CRITICAL_SECTION cs; + size_t count; + + atomic_count_t() : count(0) {} + +} ATOMIC_COUNT; + +AtomicCount::AtomicCount() { + + ATOMIC_COUNT* c = new ATOMIC_COUNT; + _value = reinterpret_cast(c); + ::InitializeCriticalSection(&c->cs); + +} + +AtomicCount::~AtomicCount() { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + assert(c->count == 0); + ::DeleteCriticalSection(&c->cs); + delete c; + +} + +//! Postfix decrement and return the current value +size_t AtomicCount::operator--(int) { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + size_t value; + + ::EnterCriticalSection(&c->cs); + value = c->count--; + ::LeaveCriticalSection(&c->cs); + + return value; + +} + +//! Postfix increment and return the current value +size_t AtomicCount::operator++(int) { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + size_t value; + + ::EnterCriticalSection(&c->cs); + value = c->count++; + ::LeaveCriticalSection(&c->cs); + + return value; + +} + +//! Prefix decrement and return the current value +size_t AtomicCount::operator--() { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + size_t value; + + ::EnterCriticalSection(&c->cs); + value = --c->count; + ::LeaveCriticalSection(&c->cs); + + return value; + +} + +//! Prefix increment and return the current value +size_t AtomicCount::operator++() { + + ATOMIC_COUNT* c = reinterpret_cast(_value); + size_t value; + + ::EnterCriticalSection(&c->cs); + value = ++c->count; + ::LeaveCriticalSection(&c->cs); + + return value; + +} + +}; + +#endif // __ZTATOMICCOUNTIMPL_H__ diff --git a/dep/src/zthread/win9x/AtomicFastLock.h b/dep/src/zthread/win9x/AtomicFastLock.h new file mode 100644 index 000000000..5b50a9c73 --- /dev/null +++ b/dep/src/zthread/win9x/AtomicFastLock.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2005, Eric Crahen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __ZTFASTLOCK_H__ +#define __ZTFASTLOCK_H__ + +#include "zthread/NonCopyable.h" +#include +#include + +namespace ZThread { + + +/** + * @class FastLock + * + * @author Eric Crahen + * @date <2003-07-16T23:31:51-0400> + * @version 2.2.0 + * + * This uses a custom spin lock based on the older swap & compare approach + * using the XCHG instruction. You should only use this is you *absolutely* need + * to use an older system, like Windows 95. If you can, use the Win32 version. + * + * Because Windows 95 and earlier can run on processors prior to the 486, they + * don't all support the CMPXCHG function, and so Windows 95 an earlier dont support + * InterlockedCompareExchange. + * + * This is asm inlined for microsoft visual c, it needs to be changed in order to + * compile with gcc, or another win32 compiler - but more likely than not you'll + * be using the Win32 version on those compilers and this won't be a problem. + */ +class FastLock : private NonCopyable { + +// Add def for mingw32 or other non-ms compiler to align on 32-bit boundary +#pragma pack(push, 4) + unsigned char volatile _lock; +#pragma pack(pop) + + public: + + /** + * Create a new FastLock + */ + inline FastLock() : _lock(0) { } + + + inline ~FastLock() { + assert(_lock == 0); + } + + inline void acquire() { + + DWORD dw = (DWORD)&_lock; + + _asm { // swap & compare + spin_lock: + + mov al, 1 + mov esi, dw + xchg [esi], al + and al,al + jz spin_locked + } + + ::Sleep(0); + + _asm { + jmp spin_lock + spin_locked: + } + + } + + inline void release() { + + DWORD dw = (DWORD)&_lock; + + _asm { + mov al, 0 + mov esi, dw + xchg [esi], al + } + + + } + + inline bool tryAcquire(unsigned long timeout=0) { + + volatile DWORD dw = (DWORD)&_lock; + volatile DWORD result; + + _asm { + + mov al, 1 + mov esi, dw + xchg [esi], al + and al,al + mov esi, result + xchg [esi], al + } + + return result == 0; + + } + +}; /* Fast Lock */ + +} // namespace ZThread + +#endif diff --git a/doc/DocStructure.dox b/doc/DocStructure.dox new file mode 100644 index 000000000..597b76d65 --- /dev/null +++ b/doc/DocStructure.dox @@ -0,0 +1,31 @@ +/*! \mainpage + * + * \section intro_sec Introduction and links + * This is the source documentation for the \b %MaNGOS (Massive Network Game %Object Server) project.\n + * %MaNGOS is an object-oriented Massively Multiplayer Online Role-Playing Game Server (MMORPGS).\n + * The project documentation and the bug tracker can be found on the %MaNGOS wiki. + * + * \section begin Where to begin? + * If you are interested in understanding the source code of this project you can begin + * - On the wiki to get an overview of the different modules of the server + * - In this source doumentation, starting at the module hierarchy + */ + +/*! \defgroup realmd Realm Daemon + */ + +/*! \defgroup mangos Mangos Deamon + */ + +/*! \defgroup mangosd Daemon starter + \ingroup mangos + */ + +/*! \defgroup u2w User Connections + \ingroup mangos + */ + +/*! \defgroup world The World + \ingroup mangos + */ + diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in new file mode 100644 index 000000000..989359375 --- /dev/null +++ b/doc/Doxyfile.in @@ -0,0 +1,1314 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = @PACKAGE@ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = @top_srcdir@/ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = "memo=\par Note:\n " \ + "draft=\xrefitem draft \"Draft\" \"Draft List\" This API may be changed in the future versions and was introduced in " \ + "stable=\xrefitem stable \"Stable\" \"Stable List\" " \ + "deprecated=\xrefitem deprecated \"Deprecated\" \"Deprecated List\" " \ + "obsolete=\xrefitem obsolete \"Obsolete\" \"Obsolete List\" " \ + "system=\xrefitem system \"System\" \"System List\" \n Do not use unless you know what you are doing. " \ + "internal=\xrefitem internal \"Internal\" \"Internal List\" Do not use. This API is for interal use only. " + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @top_srcdir@/src/shared/ \ + @top_srcdir@/src/shared/Auth/ \ + @top_srcdir@/src/shared/Database/ \ + @top_srcdir@/src/game/ \ + @top_srcdir@/src/realmd/ \ + @top_srcdir@/src/mangosd/ \ + DocStructure.dox + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.cpp \ + *.h \ + *.hpp + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = config*.h + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = YES + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = U_EXPORT2 \ + U_STABLE \ + U_DRAFT \ + U_INTERNAL \ + U_SYSTEM \ + U_DEPRECATED \ + U_OBSOLETE + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = "@srcdir@/html/mangos-ng-docs.tag " + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = YES diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..c9a59115e --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,49 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## Additional files to include when running 'make dist' +# Nothing yet. +# Doxygen configuration files. +EXTRA_DIST = \ + DocStructure.dox \ + Doxyfile + +DOC_DIR = . +DOXYFILE = $(DOC_DIR)/Doxyfile +DOC_HTML = $(DOC_OUT)/index.html +DOC_OUT_HTML = $(DOC_DIR)/html +DOXYGEN = @DOXYGEN@ + +if DOXYGEN_ENABLED +doc: $(DOC_HTML) + @echo "" + @echo "Type \"firefox $(DOC_OUT_HTML)/index.html\" to see the html document." + @echo "" + +$(DOC_HTML): $(DOXYFILE) + $(DOXYGEN) $(DOXYFILE) +else +.PHONY: doc +doc: + @echo "You must enable at configure time: ./configure --enable-doxygen" +endif + +clean-local: + rm -rf $(DOC_OUT_HTML) diff --git a/sql/Makefile.am b/sql/Makefile.am new file mode 100644 index 000000000..b3d95a853 --- /dev/null +++ b/sql/Makefile.am @@ -0,0 +1,42 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = updates tools + +## Change installation location +# datadir = mangos/sql +pkgdatadir = $(datadir)/mangos/sql + +## Files to be installed +# Install basic SQL files to datadir +pkgdata_DATA = \ + mangos.sql \ + realmd.sql \ + characters.sql \ + create_mysql.sql \ + drop_mysql.sql + +## Additional files to include when running 'make dist' +# SQL files for MaNGOS database +EXTRA_DIST = \ + create_mysql.sql \ + drop_mysql.sql \ + characters.sql \ + mangos.sql \ + realmd.sql diff --git a/sql/characters.sql b/sql/characters.sql new file mode 100644 index 000000000..a2b2437fb --- /dev/null +++ b/sql/characters.sql @@ -0,0 +1,1221 @@ +-- MySQL dump 10.11 +-- +-- Host: localhost Database: characters +-- ------------------------------------------------------ +-- Server version 5.0.45-Debian_1ubuntu3.1-log + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `arena_team` +-- + +DROP TABLE IF EXISTS `arena_team`; +CREATE TABLE `arena_team` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `name` char(255) NOT NULL, + `captainguid` int(10) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `BackgroundColor` int(10) unsigned NOT NULL default '0', + `EmblemStyle` int(10) unsigned NOT NULL default '0', + `EmblemColor` int(10) unsigned NOT NULL default '0', + `BorderStyle` int(10) unsigned NOT NULL default '0', + `BorderColor` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`arenateamid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `arena_team` +-- + +LOCK TABLES `arena_team` WRITE; +/*!40000 ALTER TABLE `arena_team` DISABLE KEYS */; +/*!40000 ALTER TABLE `arena_team` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `arena_team_member` +-- + +DROP TABLE IF EXISTS `arena_team_member`; +CREATE TABLE `arena_team_member` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `guid` int(10) unsigned NOT NULL default '0', + `played_week` int(10) unsigned NOT NULL default '0', + `wons_week` int(10) unsigned NOT NULL default '0', + `played_season` int(10) unsigned NOT NULL default '0', + `wons_season` int(10) unsigned NOT NULL default '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `arena_team_member` +-- + +LOCK TABLES `arena_team_member` WRITE; +/*!40000 ALTER TABLE `arena_team_member` DISABLE KEYS */; +/*!40000 ALTER TABLE `arena_team_member` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `arena_team_stats` +-- + +DROP TABLE IF EXISTS `arena_team_stats`; +CREATE TABLE `arena_team_stats` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `rating` int(10) unsigned NOT NULL default '0', + `games` int(10) unsigned NOT NULL default '0', + `wins` int(10) unsigned NOT NULL default '0', + `played` int(10) unsigned NOT NULL default '0', + `wins2` int(10) unsigned NOT NULL default '0', + `rank` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`arenateamid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `arena_team_stats` +-- + +LOCK TABLES `arena_team_stats` WRITE; +/*!40000 ALTER TABLE `arena_team_stats` DISABLE KEYS */; +/*!40000 ALTER TABLE `arena_team_stats` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `auctionhouse` +-- + +DROP TABLE IF EXISTS `auctionhouse`; +CREATE TABLE `auctionhouse` ( + `id` int(11) unsigned NOT NULL default '0', + `auctioneerguid` int(11) unsigned NOT NULL default '0', + `itemguid` int(11) unsigned NOT NULL default '0', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `itemowner` int(11) unsigned NOT NULL default '0', + `buyoutprice` int(11) NOT NULL default '0', + `time` bigint(40) NOT NULL default '0', + `buyguid` int(11) unsigned NOT NULL default '0', + `lastbid` int(11) NOT NULL default '0', + `startbid` int(11) NOT NULL default '0', + `deposit` int(11) NOT NULL default '0', + `location` tinyint(3) unsigned NOT NULL default '3', + PRIMARY KEY (`id`), + UNIQUE KEY `item_guid` (`itemguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `auctionhouse` +-- + +LOCK TABLES `auctionhouse` WRITE; +/*!40000 ALTER TABLE `auctionhouse` DISABLE KEYS */; +/*!40000 ALTER TABLE `auctionhouse` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `bugreport` +-- + +DROP TABLE IF EXISTS `bugreport`; +CREATE TABLE `bugreport` ( + `id` int(11) NOT NULL auto_increment COMMENT 'Identifier', + `type` varchar(255) NOT NULL default '', + `content` varchar(255) NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Debug System'; + +-- +-- Dumping data for table `bugreport` +-- + +LOCK TABLES `bugreport` WRITE; +/*!40000 ALTER TABLE `bugreport` DISABLE KEYS */; +/*!40000 ALTER TABLE `bugreport` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `characters` +-- + +DROP TABLE IF EXISTS `characters`; +CREATE TABLE `characters` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `account` int(11) unsigned NOT NULL default '0' COMMENT 'Account Identifier', + `data` longtext, + `name` varchar(12) NOT NULL default '', + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `dungeon_difficulty` tinyint(1) unsigned NOT NULL DEFAULT '0', + `orientation` float NOT NULL default '0', + `taximask` longtext, + `online` tinyint(3) unsigned NOT NULL default '0', + `cinematic` tinyint(3) unsigned NOT NULL default '0', + `totaltime` int(11) unsigned NOT NULL default '0', + `leveltime` int(11) unsigned NOT NULL default '0', + `logout_time` bigint(20) unsigned NOT NULL default '0', + `is_logout_resting` tinyint(3) unsigned NOT NULL default '0', + `rest_bonus` float NOT NULL default '0', + `resettalents_cost` int(11) unsigned NOT NULL default '0', + `resettalents_time` bigint(20) unsigned NOT NULL default '0', + `trans_x` float NOT NULL default '0', + `trans_y` float NOT NULL default '0', + `trans_z` float NOT NULL default '0', + `trans_o` float NOT NULL default '0', + `transguid` bigint(20) unsigned NOT NULL default '0', + `gmstate` int(11) unsigned NOT NULL default '0', + `stable_slots` tinyint(1) unsigned NOT NULL default '0', + `at_login` int(11) unsigned NOT NULL default '0', + `zone` int(11) unsigned NOT NULL default '0', + `death_expire_time` bigint(20) unsigned NOT NULL default '0', + `taxi_path` text, + PRIMARY KEY (`guid`), + KEY `idx_account` (`account`), + KEY `idx_online` (`online`), + KEY `idx_name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `characters` +-- + +LOCK TABLES `characters` WRITE; +/*!40000 ALTER TABLE `characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_action` +-- + +DROP TABLE IF EXISTS `character_action`; +CREATE TABLE `character_action` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `button` tinyint(3) unsigned NOT NULL default '0', + `action` smallint(5) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `misc` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`button`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_action` +-- + +LOCK TABLES `character_action` WRITE; +/*!40000 ALTER TABLE `character_action` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_action` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_aura` +-- + +DROP TABLE IF EXISTS `character_aura`; +CREATE TABLE `character_aura` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `amount` int(11) NOT NULL default '0', + `maxduration` int(11) NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + `remaincharges` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`,`effect_index`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_aura` +-- + +LOCK TABLES `character_aura` WRITE; +/*!40000 ALTER TABLE `character_aura` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_aura` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_declinedname` +-- + +DROP TABLE IF EXISTS `character_declinedname`; +CREATE TABLE `character_declinedname` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `genitive` varchar(15) NOT NULL default '', + `dative` varchar(15) NOT NULL default '', + `accusative` varchar(15) NOT NULL default '', + `instrumental` varchar(15) NOT NULL default '', + `prepositional` varchar(15) NOT NULL default '', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- +-- Dumping data for table `character_declinedname` +-- + +LOCK TABLES `character_declinedname` WRITE; +/*!40000 ALTER TABLE `character_declinedname` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_declinedname` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_gifts` +-- + +DROP TABLE IF EXISTS `character_gifts`; +CREATE TABLE `character_gifts` ( + `guid` int(20) unsigned NOT NULL default '0', + `item_guid` int(11) unsigned NOT NULL default '0', + `entry` int(20) unsigned NOT NULL default '0', + `flags` int(20) unsigned NOT NULL default '0', + PRIMARY KEY (`item_guid`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `character_gifts` +-- + +LOCK TABLES `character_gifts` WRITE; +/*!40000 ALTER TABLE `character_gifts` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_gifts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_homebind` +-- + +DROP TABLE IF EXISTS `character_homebind`; +CREATE TABLE `character_homebind` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `zone` int(11) unsigned NOT NULL default '0' COMMENT 'Zone Identifier', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_homebind` +-- + +LOCK TABLES `character_homebind` WRITE; +/*!40000 ALTER TABLE `character_homebind` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_homebind` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_instance` +-- + +DROP TABLE IF EXISTS `character_instance`; +CREATE TABLE `character_instance` ( + `guid` int(11) unsigned NOT NULL default '0', + `instance` int(11) unsigned NOT NULL default '0', + `permanent` tinyint(1) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`instance`), + KEY `instance` (`instance`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `character_instance` +-- + +LOCK TABLES `character_instance` WRITE; +/*!40000 ALTER TABLE `character_instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_instance` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_inventory` +-- + +DROP TABLE IF EXISTS `character_inventory`; +CREATE TABLE `character_inventory` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `bag` int(11) unsigned NOT NULL default '0', + `slot` tinyint(3) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0' COMMENT 'Item Global Unique Identifier', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + PRIMARY KEY (`item`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_inventory` +-- + +LOCK TABLES `character_inventory` WRITE; +/*!40000 ALTER TABLE `character_inventory` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_inventory` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_pet` +-- + +DROP TABLE IF EXISTS `character_pet`; +CREATE TABLE `character_pet` ( + `id` int(11) unsigned NOT NULL default '0', + `entry` int(11) unsigned NOT NULL default '0', + `owner` int(11) unsigned NOT NULL default '0', + `modelid` int(11) unsigned default '0', + `CreatedBySpell` int(11) unsigned NOT NULL default '0', + `PetType` tinyint(3) unsigned NOT NULL default '0', + `level` int(11) unsigned NOT NULL default '1', + `exp` int(11) unsigned NOT NULL default '0', + `Reactstate` tinyint(1) unsigned NOT NULL default '0', + `loyaltypoints` int(11) NOT NULL default '0', + `loyalty` int(11) unsigned NOT NULL default '0', + `trainpoint` int(11) NOT NULL default '0', + `name` varchar(100) default 'Pet', + `renamed` tinyint(1) unsigned NOT NULL default '0', + `slot` int(11) unsigned NOT NULL default '0', + `curhealth` int(11) unsigned NOT NULL default '1', + `curmana` int(11) unsigned NOT NULL default '0', + `curhappiness` int(11) unsigned NOT NULL default '0', + `savetime` bigint(20) unsigned NOT NULL default '0', + `resettalents_cost` int(11) unsigned NOT NULL default '0', + `resettalents_time` bigint(20) unsigned NOT NULL default '0', + `abdata` longtext, + `teachspelldata` longtext, + PRIMARY KEY (`id`), + KEY `owner` (`owner`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- +-- Dumping data for table `character_pet` +-- + +LOCK TABLES `character_pet` WRITE; +/*!40000 ALTER TABLE `character_pet` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_pet` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_pet_declinedname` +-- + +DROP TABLE IF EXISTS `character_pet_declinedname`; +CREATE TABLE `character_pet_declinedname` ( + `id` int(11) unsigned NOT NULL default '0', + `owner` int(11) unsigned NOT NULL default '0', + `genitive` varchar(12) NOT NULL default '', + `dative` varchar(12) NOT NULL default '', + `accusative` varchar(12) NOT NULL default '', + `instrumental` varchar(12) NOT NULL default '', + `prepositional` varchar(12) NOT NULL default '', + PRIMARY KEY (`id`), + KEY owner_key (`owner`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- +-- Dumping data for table `character_pet_declinedname` +-- + +LOCK TABLES `character_pet_declinedname` WRITE; +/*!40000 ALTER TABLE `character_pet_declinedname` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_pet_declinedname` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_queststatus` +-- + +DROP TABLE IF EXISTS `character_queststatus`; +CREATE TABLE `character_queststatus` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + `status` int(11) unsigned NOT NULL default '0', + `rewarded` tinyint(1) unsigned NOT NULL default '0', + `explored` tinyint(1) unsigned NOT NULL default '0', + `timer` bigint(20) unsigned NOT NULL default '0', + `mobcount1` int(11) unsigned NOT NULL default '0', + `mobcount2` int(11) unsigned NOT NULL default '0', + `mobcount3` int(11) unsigned NOT NULL default '0', + `mobcount4` int(11) unsigned NOT NULL default '0', + `itemcount1` int(11) unsigned NOT NULL default '0', + `itemcount2` int(11) unsigned NOT NULL default '0', + `itemcount3` int(11) unsigned NOT NULL default '0', + `itemcount4` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`quest`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_queststatus` +-- + +LOCK TABLES `character_queststatus` WRITE; +/*!40000 ALTER TABLE `character_queststatus` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_queststatus_daily` +-- + +DROP TABLE IF EXISTS `character_queststatus_daily`; +CREATE TABLE `character_queststatus_daily` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`quest`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_queststatus_daily` +-- + +LOCK TABLES `character_queststatus_daily` WRITE; +/*!40000 ALTER TABLE `character_queststatus_daily` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus_daily` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_reputation` +-- + +DROP TABLE IF EXISTS `character_reputation`; +CREATE TABLE `character_reputation` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `faction` int(11) unsigned NOT NULL default '0', + `standing` int(11) NOT NULL default '0', + `flags` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`faction`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_reputation` +-- + +LOCK TABLES `character_reputation` WRITE; +/*!40000 ALTER TABLE `character_reputation` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_reputation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_social` +-- + +DROP TABLE IF EXISTS `character_social`; +CREATE TABLE `character_social` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `friend` int(11) unsigned NOT NULL default '0' COMMENT 'Friend Global Unique Identifier', + `flags` tinyint(1) unsigned NOT NULL default '0' COMMENT 'Friend Flags', + `note` varchar(48) NOT NULL DEFAULT '' COMMENT 'Friend Note', + PRIMARY KEY (`guid`,`friend`,`flags`), + KEY `guid` (`guid`), + KEY `friend` (`friend`), + KEY `guid_flags` (`guid`,`flags`), + KEY `friend_flags` (`friend`,`flags`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_social` +-- + +LOCK TABLES `character_social` WRITE; +/*!40000 ALTER TABLE `character_social` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_social` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_spell` +-- + +DROP TABLE IF EXISTS `character_spell`; +CREATE TABLE `character_spell` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `slot` int(11) unsigned NOT NULL default '0', + `active` tinyint(3) unsigned NOT NULL default '1', + `disabled` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_spell` +-- + +LOCK TABLES `character_spell` WRITE; +/*!40000 ALTER TABLE `character_spell` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_spell` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_spell_cooldown` +-- + +DROP TABLE IF EXISTS `character_spell_cooldown`; +CREATE TABLE `character_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `item` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `character_spell_cooldown` +-- + +LOCK TABLES `character_spell_cooldown` WRITE; +/*!40000 ALTER TABLE `character_spell_cooldown` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_spell_cooldown` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_ticket` +-- + +DROP TABLE IF EXISTS `character_ticket`; +CREATE TABLE `character_ticket` ( + `ticket_id` int(11) unsigned NOT NULL auto_increment, + `guid` int(11) unsigned NOT NULL default '0', + `ticket_text` text, + `ticket_lastchange` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ticket_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_ticket` +-- + +LOCK TABLES `character_ticket` WRITE; +/*!40000 ALTER TABLE `character_ticket` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_ticket` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_tutorial` +-- + +DROP TABLE IF EXISTS `character_tutorial`; +CREATE TABLE `character_tutorial` ( + `account` bigint(20) unsigned NOT NULL auto_increment COMMENT 'Account Identifier', + `realmid` int(11) unsigned NOT NULL default '0' COMMENT 'Realm Identifier', + `tut0` int(11) unsigned NOT NULL default '0', + `tut1` int(11) unsigned NOT NULL default '0', + `tut2` int(11) unsigned NOT NULL default '0', + `tut3` int(11) unsigned NOT NULL default '0', + `tut4` int(11) unsigned NOT NULL default '0', + `tut5` int(11) unsigned NOT NULL default '0', + `tut6` int(11) unsigned NOT NULL default '0', + `tut7` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`account`,`realmid`), + KEY acc_key (`account`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_tutorial` +-- + +LOCK TABLES `character_tutorial` WRITE; +/*!40000 ALTER TABLE `character_tutorial` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_tutorial` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `corpse` +-- + +DROP TABLE IF EXISTS `corpse`; +CREATE TABLE `corpse` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `player` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `orientation` float NOT NULL default '0', + `zone` int(11) unsigned NOT NULL default '38' COMMENT 'Zone Identifier', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `data` longtext, + `time` bigint(20) unsigned NOT NULL default '0', + `corpse_type` tinyint(3) unsigned NOT NULL default '0', + `instance` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`), + KEY `idx_type` (`corpse_type`), + KEY `instance` (`instance`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Death System'; + +-- +-- Dumping data for table `corpse` +-- + +LOCK TABLES `corpse` WRITE; +/*!40000 ALTER TABLE `corpse` DISABLE KEYS */; +/*!40000 ALTER TABLE `corpse` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `groups` +-- + +DROP TABLE IF EXISTS `groups`; +CREATE TABLE `groups` ( + `leaderGuid` int(11) unsigned NOT NULL, + `mainTank` int(11) unsigned NOT NULL, + `mainAssistant` int(11) unsigned NOT NULL, + `lootMethod` tinyint(4) unsigned NOT NULL, + `looterGuid` int(11) unsigned NOT NULL, + `lootThreshold` tinyint(4) unsigned NOT NULL, + `icon1` int(11) unsigned NOT NULL, + `icon2` int(11) unsigned NOT NULL, + `icon3` int(11) unsigned NOT NULL, + `icon4` int(11) unsigned NOT NULL, + `icon5` int(11) unsigned NOT NULL, + `icon6` int(11) unsigned NOT NULL, + `icon7` int(11) unsigned NOT NULL, + `icon8` int(11) unsigned NOT NULL, + `isRaid` tinyint(1) unsigned NOT NULL, + `difficulty` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`leaderGuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Groups'; + +-- +-- Dumping data for table `groups` +-- + +LOCK TABLES `groups` WRITE; +/*!40000 ALTER TABLE `groups` DISABLE KEYS */; +/*!40000 ALTER TABLE `groups` ENABLE KEYS */; +UNLOCK TABLES; + +-- ---------------------------- +-- Table structure for group_instance +-- ---------------------------- +DROP TABLE IF EXISTS `group_instance`; +CREATE TABLE `group_instance` ( + `leaderGuid` int(11) unsigned NOT NULL default '0', + `instance` int(11) unsigned NOT NULL default '0', + `permanent` tinyint(1) unsigned NOT NULL default '0', + PRIMARY KEY (`leaderGuid`,`instance`), + KEY `instance` (`instance`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `group_instance` +-- + +LOCK TABLES `group_instance` WRITE; +/*!40000 ALTER TABLE `group_instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_instance` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `group_member` +-- + +DROP TABLE IF EXISTS `group_member`; +CREATE TABLE `group_member` ( + `leaderGuid` int(11) unsigned NOT NULL, + `memberGuid` int(11) unsigned NOT NULL, + `assistant` tinyint(1) unsigned NOT NULL, + `subgroup` smallint(6) unsigned NOT NULL, + PRIMARY KEY (`leaderGuid`,`memberGuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Groups'; + +-- +-- Dumping data for table `group_member` +-- + +LOCK TABLES `group_member` WRITE; +/*!40000 ALTER TABLE `group_member` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_member` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild` +-- + +DROP TABLE IF EXISTS `guild`; +CREATE TABLE `guild` ( + `guildid` int(6) unsigned NOT NULL default '0', + `name` varchar(255) NOT NULL default '', + `leaderguid` int(6) unsigned NOT NULL default '0', + `EmblemStyle` int(5) NOT NULL default '0', + `EmblemColor` int(5) NOT NULL default '0', + `BorderStyle` int(5) NOT NULL default '0', + `BorderColor` int(5) NOT NULL default '0', + `BackgroundColor` int(5) NOT NULL default '0', + `info` text NOT NULL, + `motd` varchar(255) NOT NULL default '', + `createdate` datetime default NULL, + `BankMoney` bigint(20) NOT NULL default '0', + PRIMARY KEY (`guildid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +-- +-- Dumping data for table `guild` +-- + +LOCK TABLES `guild` WRITE; +/*!40000 ALTER TABLE `guild` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_bank_eventlog` +-- + +DROP TABLE IF EXISTS `guild_bank_eventlog`; +CREATE TABLE `guild_bank_eventlog` ( + `guildid` int(11) unsigned NOT NULL default '0', + `LogGuid` int(11) unsigned NOT NULL default '0', + `LogEntry` tinyint(1) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `PlayerGuid` int(11) unsigned NOT NULL default '0', + `ItemOrMoney` int(11) unsigned NOT NULL default '0', + `ItemStackCount` tinyint(3) unsigned NOT NULL default '0', + `DestTabId` tinyint(1) unsigned NOT NULL default '0', + `TimeStamp` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`LogGuid`), + KEY `guildid_key` (`guildid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `guild_bank_eventlog` +-- + +LOCK TABLES `guild_bank_eventlog` WRITE; +/*!40000 ALTER TABLE `guild_bank_eventlog` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_bank_eventlog` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_bank_item` +-- + +DROP TABLE IF EXISTS `guild_bank_item`; +CREATE TABLE `guild_bank_item` ( + `guildid` int(11) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `SlotId` tinyint(3) unsigned NOT NULL default '0', + `item_guid` int(11) unsigned NOT NULL default '0', + `item_entry` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`tabid`,`slotid`), + KEY `guildid_key` (`guildid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `guild_bank_item` +-- + +LOCK TABLES `guild_bank_item` WRITE; +/*!40000 ALTER TABLE `guild_bank_item` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_bank_item` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_bank_right` +-- + +DROP TABLE IF EXISTS `guild_bank_right`; +CREATE TABLE `guild_bank_right` ( + `guildid` int(11) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `rid` int(11) unsigned NOT NULL default '0', + `gbright` tinyint(3) unsigned NOT NULL default '0', + `SlotPerDay` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`TabId`,`rid`), + KEY `guildid_key` (`guildid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `guild_bank_right` +-- + +LOCK TABLES `guild_bank_right` WRITE; +/*!40000 ALTER TABLE `guild_bank_right` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_bank_right` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_bank_tab` +-- + +DROP TABLE IF EXISTS `guild_bank_tab`; +CREATE TABLE `guild_bank_tab` ( + `guildid` int(11) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `TabName` varchar(100) NOT NULL default '', + `TabIcon` varchar(100) NOT NULL default '', + `TabText` varchar(500) NOT NULL default '', + PRIMARY KEY (`guildid`,`TabId`), + KEY `guildid_key` (`guildid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `guild_bank_tab` +-- + +LOCK TABLES `guild_bank_tab` WRITE; +/*!40000 ALTER TABLE `guild_bank_tab` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_bank_tab` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_eventlog` +-- + +DROP TABLE IF EXISTS `guild_eventlog`; +CREATE TABLE `guild_eventlog` ( + `guildid` int(11) NOT NULL COMMENT 'Guild Identificator', + `LogGuid` int(11) NOT NULL COMMENT 'Log entry identificator', + `EventType` tinyint(1) NOT NULL COMMENT 'Event type', + `PlayerGuid1` int(11) NOT NULL COMMENT 'Player 1', + `PlayerGuid2` int(11) NOT NULL COMMENT 'Player 2', + `NewRank` tinyint(2) NOT NULL COMMENT 'New rank(in case promotion/demotion)', + `TimeStamp` bigint(20) NOT NULL COMMENT 'Event UNIX time' +) ENGINE = InnoDB DEFAULT CHARSET = latin1 COMMENT 'Guild Eventlog'; + +-- +-- Dumping data for table `guild_eventlog` +-- + +LOCK TABLES `guild_eventlog` WRITE; +/*!40000 ALTER TABLE `guild_eventlog` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_eventlog` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_member` +-- + +DROP TABLE IF EXISTS `guild_member`; +CREATE TABLE `guild_member` ( + `guildid` int(6) unsigned NOT NULL default '0', + `guid` int(11) unsigned NOT NULL default '0', + `rank` tinyint(2) unsigned NOT NULL default '0', + `pnote` varchar(255) NOT NULL default '', + `offnote` varchar(255) NOT NULL default '', + `BankResetTimeMoney` int(11) unsigned NOT NULL default '0', + `BankRemMoney` int(11) unsigned NOT NULL default '0', + `BankResetTimeTab0` int(11) unsigned NOT NULL default '0', + `BankRemSlotsTab0` int(11) unsigned NOT NULL default '0', + `BankResetTimeTab1` int(11) unsigned NOT NULL default '0', + `BankRemSlotsTab1` int(11) unsigned NOT NULL default '0', + `BankResetTimeTab2` int(11) unsigned NOT NULL default '0', + `BankRemSlotsTab2` int(11) unsigned NOT NULL default '0', + `BankResetTimeTab3` int(11) unsigned NOT NULL default '0', + `BankRemSlotsTab3` int(11) unsigned NOT NULL default '0', + `BankResetTimeTab4` int(11) unsigned NOT NULL default '0', + `BankRemSlotsTab4` int(11) unsigned NOT NULL default '0', + `BankResetTimeTab5` int(11) unsigned NOT NULL default '0', + `BankRemSlotsTab5` int(11) unsigned NOT NULL default '0', + KEY `guildid_key` (`guildid`), + KEY `guildid_rank_key` (`guildid`,`rank`), + KEY `guid_key` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Guild System'; + +-- +-- Dumping data for table `guild_member` +-- + +LOCK TABLES `guild_member` WRITE; +/*!40000 ALTER TABLE `guild_member` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_member` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guild_rank` +-- + +DROP TABLE IF EXISTS `guild_rank`; +CREATE TABLE `guild_rank` ( + `guildid` int(6) unsigned NOT NULL default '0', + `rid` int(11) unsigned NOT NULL, + `rname` varchar(255) NOT NULL default '', + `rights` int(3) unsigned NOT NULL default '0', + `BankMoneyPerDay` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`rid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +-- +-- Dumping data for table `guild_rank` +-- + +LOCK TABLES `guild_rank` WRITE; +/*!40000 ALTER TABLE `guild_rank` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_rank` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `instance` +-- + +DROP TABLE IF EXISTS `instance`; +CREATE TABLE `instance` ( + `id` int(11) unsigned NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0', + `resettime` bigint(40) NOT NULL default '0', + `difficulty` tinyint(1) unsigned NOT NULL default '0', + `data` longtext, + PRIMARY KEY (`id`), + KEY `map` (`map`), + KEY `resettime` (`resettime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `instance` +-- + +LOCK TABLES `instance` WRITE; +/*!40000 ALTER TABLE `instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `instance` ENABLE KEYS */; +UNLOCK TABLES; + +-- ---------------------------- +-- Table structure for instance_reset +-- ---------------------------- +DROP TABLE IF EXISTS `instance_reset`; +CREATE TABLE `instance_reset` ( + `mapid` int(11) unsigned NOT NULL default '0', + `resettime` bigint(40) NOT NULL default '0', + PRIMARY KEY (`mapid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `instance_reset` +-- + +LOCK TABLES `instance_reset` WRITE; +/*!40000 ALTER TABLE `instance_reset` DISABLE KEYS */; +/*!40000 ALTER TABLE `instance_reset` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `item_instance` +-- + +DROP TABLE IF EXISTS `item_instance`; +CREATE TABLE `item_instance` ( + `guid` int(11) unsigned NOT NULL default '0', + `owner_guid` int(11) unsigned NOT NULL default '0', + `data` longtext, + PRIMARY KEY (`guid`), + KEY `idx_owner_guid` (`owner_guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Item System'; + +-- +-- Dumping data for table `item_instance` +-- + +LOCK TABLES `item_instance` WRITE; +/*!40000 ALTER TABLE `item_instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_instance` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `item_text` +-- + +DROP TABLE IF EXISTS `item_text`; +CREATE TABLE `item_text` ( + `id` int(11) unsigned NOT NULL default '0', + `text` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +-- +-- Dumping data for table `item_text` +-- + +LOCK TABLES `item_text` WRITE; +/*!40000 ALTER TABLE `item_text` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_text` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `mail` +-- + +DROP TABLE IF EXISTS `mail`; +CREATE TABLE `mail` ( + `id` int(11) unsigned NOT NULL default '0' COMMENT 'Identifier', + `messageType` tinyint(3) unsigned NOT NULL default '0', + `stationery` tinyint(3) NOT NULL default '41', + `mailTemplateId` mediumint(8) unsigned NOT NULL default '0', + `sender` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `receiver` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `subject` longtext, + `itemTextId` int(11) unsigned NOT NULL default '0', + `has_items` tinyint(3) unsigned NOT NULL default '0', + `expire_time` bigint(40) NOT NULL default '0', + `deliver_time` bigint(40) NOT NULL default '0', + `money` int(11) unsigned NOT NULL default '0', + `cod` int(11) unsigned NOT NULL default '0', + `checked` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + KEY `idx_receiver` (`receiver`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Mail System'; + +-- +-- Dumping data for table `mail` +-- + +LOCK TABLES `mail` WRITE; +/*!40000 ALTER TABLE `mail` DISABLE KEYS */; +/*!40000 ALTER TABLE `mail` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `mail_items` +-- + +DROP TABLE IF EXISTS `mail_items`; +CREATE TABLE `mail_items` ( + `mail_id` int(11) NOT NULL default '0', + `item_guid` int(11) NOT NULL default '0', + `item_template` int(11) NOT NULL default '0', + `receiver` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + PRIMARY KEY (`mail_id`,`item_guid`), + KEY `idx_receiver` (`receiver`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- +-- Dumping data for table `mail_items` +-- + +LOCK TABLES `mail_items` WRITE; +/*!40000 ALTER TABLE `mail_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `mail_items` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `pet_aura` +-- + +DROP TABLE IF EXISTS `pet_aura`; +CREATE TABLE `pet_aura` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `amount` int(11) NOT NULL default '0', + `maxduration` int(11) NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + `remaincharges` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`,`effect_index`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- +-- Dumping data for table `pet_aura` +-- + +LOCK TABLES `pet_aura` WRITE; +/*!40000 ALTER TABLE `pet_aura` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_aura` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `pet_spell` +-- + +DROP TABLE IF EXISTS `pet_spell`; +CREATE TABLE `pet_spell` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `slot` int(11) unsigned NOT NULL default '0', + `active` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- +-- Dumping data for table `pet_spell` +-- + +LOCK TABLES `pet_spell` WRITE; +/*!40000 ALTER TABLE `pet_spell` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_spell` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `pet_spell_cooldown` +-- + +DROP TABLE IF EXISTS `pet_spell_cooldown`; +CREATE TABLE `pet_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `pet_spell_cooldown` +-- + +LOCK TABLES `pet_spell_cooldown` WRITE; +/*!40000 ALTER TABLE `pet_spell_cooldown` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_spell_cooldown` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `petition` +-- + +DROP TABLE IF EXISTS `petition`; +CREATE TABLE `petition` ( + `ownerguid` int(10) unsigned NOT NULL, + `petitionguid` int(10) unsigned default '0', + `name` varchar(255) NOT NULL default '', + `type` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`ownerguid`,`type`), + UNIQUE KEY `index_ownerguid_petitionguid` (`ownerguid`,`petitionguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +-- +-- Dumping data for table `petition` +-- + +LOCK TABLES `petition` WRITE; +/*!40000 ALTER TABLE `petition` DISABLE KEYS */; +/*!40000 ALTER TABLE `petition` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `petition_sign` +-- + +DROP TABLE IF EXISTS `petition_sign`; +CREATE TABLE `petition_sign` ( + `ownerguid` int(10) unsigned NOT NULL, + `petitionguid` int(11) unsigned NOT NULL default '0', + `playerguid` int(11) unsigned NOT NULL default '0', + `player_account` int(11) unsigned NOT NULL default '0', + `type` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`petitionguid`,`playerguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; +-- +-- Dumping data for table `petition_sign` +-- + +LOCK TABLES `petition_sign` WRITE; +/*!40000 ALTER TABLE `petition_sign` DISABLE KEYS */; +/*!40000 ALTER TABLE `petition_sign` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2008-01-10 11:37:06 diff --git a/sql/create_mysql.sql b/sql/create_mysql.sql new file mode 100644 index 000000000..5a39665d7 --- /dev/null +++ b/sql/create_mysql.sql @@ -0,0 +1,14 @@ +GRANT USAGE ON * . * TO 'mangos'@'localhost' IDENTIFIED BY 'mangos' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 ; + +CREATE DATABASE `mangos` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE DATABASE `characters` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE DATABASE `realmd` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; + +GRANT ALL PRIVILEGES ON `mangos` . * TO 'mangos'@'localhost' WITH GRANT OPTION; + +GRANT ALL PRIVILEGES ON `characters` . * TO 'mangos'@'localhost' WITH GRANT OPTION; + +GRANT ALL PRIVILEGES ON `realmd` . * TO 'mangos'@'localhost' WITH GRANT OPTION; + diff --git a/sql/drop_mysql.sql b/sql/drop_mysql.sql new file mode 100644 index 000000000..4ed3f5547 --- /dev/null +++ b/sql/drop_mysql.sql @@ -0,0 +1,21 @@ +REVOKE ALL PRIVILEGES ON * . * FROM 'mangos'@'localhost'; + +REVOKE ALL PRIVILEGES ON `mangos` . * FROM 'mangos'@'localhost'; + +REVOKE GRANT OPTION ON `mangos` . * FROM 'mangos'@'localhost'; + +REVOKE ALL PRIVILEGES ON `characters` . * FROM 'mangos'@'localhost'; + +REVOKE GRANT OPTION ON `characters` . * FROM 'mangos'@'localhost'; + +REVOKE ALL PRIVILEGES ON `realmd` . * FROM 'mangos'@'localhost'; + +REVOKE GRANT OPTION ON `realmd` . * FROM 'mangos'@'localhost'; + +DELETE FROM `user` WHERE CONVERT( User USING utf8 ) = CONVERT( 'mangos' USING utf8 ) AND CONVERT( Host USING utf8 ) = CONVERT( 'localhost' USING utf8 ) ; + +DROP DATABASE IF EXISTS `mangos` ; + +DROP DATABASE IF EXISTS `characters` ; + +DROP DATABASE IF EXISTS `realmd` ; diff --git a/sql/mangos.sql b/sql/mangos.sql new file mode 100644 index 000000000..940039533 --- /dev/null +++ b/sql/mangos.sql @@ -0,0 +1,15347 @@ +-- MySQL dump 10.11 +-- +-- Host: localhost Database: mangos +-- ------------------------------------------------------ +-- Server version 5.0.56-nt + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `areatrigger_involvedrelation` +-- + +DROP TABLE IF EXISTS `areatrigger_involvedrelation`; +CREATE TABLE `areatrigger_involvedrelation` ( + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Identifier', + `quest` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Trigger System'; + +-- +-- Dumping data for table `areatrigger_involvedrelation` +-- + +LOCK TABLES `areatrigger_involvedrelation` WRITE; +/*!40000 ALTER TABLE `areatrigger_involvedrelation` DISABLE KEYS */; +/*!40000 ALTER TABLE `areatrigger_involvedrelation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `areatrigger_scripts` +-- + +DROP TABLE IF EXISTS `areatrigger_scripts`; +CREATE TABLE `areatrigger_scripts` ( + `entry` MEDIUMINT( 8 ) NOT NULL , + `ScriptName` CHAR( 64 ) NOT NULL , + PRIMARY KEY ( `entry` ) +) ENGINE = MYISAM DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `areatrigger_tavern` +-- + +DROP TABLE IF EXISTS `areatrigger_tavern`; +CREATE TABLE `areatrigger_tavern` ( + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Identifier', + `name` text, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Trigger System'; + +-- +-- Dumping data for table `areatrigger_tavern` +-- + +LOCK TABLES `areatrigger_tavern` WRITE; +/*!40000 ALTER TABLE `areatrigger_tavern` DISABLE KEYS */; +/*!40000 ALTER TABLE `areatrigger_tavern` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `areatrigger_teleport` +-- + +DROP TABLE IF EXISTS `areatrigger_teleport`; +CREATE TABLE `areatrigger_teleport` ( + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Identifier', + `name` text, + `required_level` tinyint(3) unsigned NOT NULL default '0', + `required_item` mediumint(8) unsigned NOT NULL default '0', + `required_item2` mediumint(8) unsigned NOT NULL default '0', + `heroic_key` mediumint(8) unsigned NOT NULL default '0', + `heroic_key2` mediumint(8) unsigned NOT NULL default '0', + `required_quest_done` int(11) unsigned NOT NULL default '0', + `required_failed_text` text, + `target_map` smallint(5) unsigned NOT NULL default '0', + `target_position_x` float NOT NULL default '0', + `target_position_y` float NOT NULL default '0', + `target_position_z` float NOT NULL default '0', + `target_orientation` float NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Trigger System'; + +-- +-- Dumping data for table `areatrigger_teleport` +-- + +LOCK TABLES `areatrigger_teleport` WRITE; +/*!40000 ALTER TABLE `areatrigger_teleport` DISABLE KEYS */; +/*!40000 ALTER TABLE `areatrigger_teleport` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `battleground_template` +-- + +DROP TABLE IF EXISTS `battleground_template`; +CREATE TABLE `battleground_template` ( + `id` mediumint(8) unsigned NOT NULL, + `MinPlayersPerTeam` smallint(5) unsigned NOT NULL default '0', + `MaxPlayersPerTeam` smallint(5) unsigned NOT NULL default '0', + `MinLvl` tinyint(3) unsigned NOT NULL default '0', + `MaxLvl` tinyint(3) unsigned NOT NULL default '0', + `AllianceStartLoc` mediumint(8) unsigned NOT NULL, + `AllianceStartO` float NOT NULL, + `HordeStartLoc` mediumint(8) unsigned NOT NULL, + `HordeStartO` float NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `battleground_template` +-- + +LOCK TABLES `battleground_template` WRITE; +/*!40000 ALTER TABLE `battleground_template` DISABLE KEYS */; +INSERT INTO `battleground_template` VALUES +(1,0,0,0,0,611,2.72532,610,2.27452), +(2,0,0,0,0,769,3.14159,770,3.14159), +(4,0,2,10,70,929,0,936,3.14159), +(3,0,0,0,0,890,3.40156,889,0.263892), +(5,0,2,10,70,939,0,940,3.14159), +(6,0,2,10,70,0,0,0,0), +(7,0,0,0,0,1103,3.40156,1104,0.263892), +(8,0,2,10,70,1258,0,1259,3.14159); +/*!40000 ALTER TABLE `battleground_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `battlemaster_entry` +-- + +DROP TABLE IF EXISTS `battlemaster_entry`; +CREATE TABLE `battlemaster_entry` ( + `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Entry of a creature', + `bg_template` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Battleground template id', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `battlemaster_entry` +-- + +LOCK TABLES `battlemaster_entry` WRITE; +/*!40000 ALTER TABLE `battlemaster_entry` DISABLE KEYS */; +/*!40000 ALTER TABLE `battlemaster_entry` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `command` +-- + +DROP TABLE IF EXISTS `command`; +CREATE TABLE `command` ( + `name` varchar(50) NOT NULL default '', + `security` tinyint(3) unsigned NOT NULL default '0', + `help` longtext, + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Chat System'; + +-- +-- Dumping data for table `command` +-- + +LOCK TABLES `command` WRITE; +/*!40000 ALTER TABLE `command` DISABLE KEYS */; +INSERT INTO `command` VALUES +('acct',0,'Syntax: .acct\r\n\r\nDisplay the access level of your account.'), +('additem',3,'Syntax: .additem #itemid/[#itemname]/#shift-click-item-link #itemcount\r\n\r\nAdds the specified number of items of id #itemid (or exact (!) name $itemname in brackets, or link created by shift-click at item in inventory or recipe) to your or selected character inventory. If #itemcount is omitted, only one item will be added.\r\n.'), +('additemset',3,'Syntax: .additemset #itemsetid\r\n\r\nAdd items from itemset of id #itemsetid to your or selected character inventory. Will add by one example each item from itemset.'), +('addmove',2,'Syntax: .addmove #creature_guid [#waittime]\r\n\r\nAdd your current location as a waypoint for creature with guid #creature_guid. And optional add wait time.'), +('announce',1,'Syntax: .announce $MessageToBroadcast\r\n\r\nSend a global message to all players online in chat log.'), +('aura',3,'Syntax: .aura #spellid\r\n\r\nAdd the aura from spell #spellid to the selected Unit.'), +('ban',3,'Syntax is: ban $NameOrIp $bantime $reason\r\nBan account or IP and kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), +('baninfo',3,'Syntax is: baninfo \r\nWatch full information about a specific ban.'), +('bank',3,'Syntax: .bank\r\n\r\nShow your bank inventory.'), +('banlist',3,'Syntax is: banlist $NameOrIp\r\nsearches the banlist for a pattern.'), +('cast',3,'Syntax: .cast #spellid [triggered]\r\n Cast #spellid to selected target. If no target selected cast to self. If \'trigered\' or part provided then spell casted with triggered flag.'), +('cast back',3,'Syntax: .cast back #spellid [triggered]\r\n Selected target will cast #spellid to your character. If \'trigered\' or part provided then spell casted with triggered flag.'), +('cast dist',3,'Syntax: .cast dist #spellid [#dist [triggered]]\r\n You will cast spell to pint at distance #dist. If \'trigered\' or part provided then spell casted with triggered flag. Not all spells can be casted as area spells.'), +('cast self',3,'Syntax: .cast self #spellid [triggered]\r\nCast #spellid by target at target itself. If \'trigered\' or part provided then spell casted with triggered flag.'), +('cast target',3,'Syntax: .cast target #spellid [triggered]\r\n Selected target will cast #spellid to his victim. If \'trigered\' or part provided then spell casted with triggered flag.'), +('combatstop',2,'Syntax: .combatstop [$playername]\r\nStop combat for selected character. If selected non-player then command applied to self. If $playername provided then attempt applied to online player $playername.'), +('commands',0,'Syntax: .commands\r\n\r\nDisplay a list of available commands for your account level.'), +('cooldown',3,'Syntax: .cooldown [#spell_id]\r\n\r\nRemove all (if spell_id not provided) or #spel_id spell cooldown from selected character or you (if no selection).'), +('damage',3,'Syntax: .damage $damage_amount [$school [$spellid]]\r\n\r\nApply $damage to target. If not $school and $spellid provided then this flat clean melee damage without any modifiers. If $school provided then damage modified by armor reduction (if school physical), and target absorbing modifiers and result applied as melee damage to target. If spell provided then damage modified and applied as spell damage. $spellid can be shift-link.'), +('debug anim',2,'Syntax: .debug anim #emoteid\r\n\r\nPlay emote #emoteid for your character.'), +('debug getvalue',3,'Syntax: .debug getvalue #field #isInt\r\n\r\nGet the field #field of the selected creature. If no creature is selected, get the content of your field.\r\n\r\nUse a #isInt of value 1 if the expected field content is an integer.'), +('debug playsound',1,'Syntax: .debug playsound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...'), +('debug setvalue',3,'Syntax: .debug setvalue #field #value #isInt\r\n\r\nSet the field #field of the selected creature with value #value. If no creature is selected, set the content of your field.\r\n\r\nUse a #isInt of value 1 if #value is an integer.'), +('debug standstate',2,'Syntax: .debug standstate #emoteid\r\n\r\nChange the emote of your character while standing to #emoteid.'), +('debug update',3,'Syntax: .debug update #field #value\r\n\r\nUpdate the field #field of the selected character or creature with value #value.\r\n\r\nIf no #value is provided, display the content of field #field.'), +('delticket',2,'Syntax: .delticket all\r\n .delticket #num\r\n .delticket $character_name\r\n\rall to dalete all tickets at server, $character_name to delete ticket of this character, #num to delete ticket #num.'), +('demorph',2,'Syntax: .demorph\r\n\r\nDemorph the selected player.'), +('die',3,'Syntax: .die\r\n\r\nKill the selected player. If no player is selected, it will kill you.'), +('dismount',0,'Syntax: .dismount\r\n\r\nDismount you, if you are mounted.'), +('distance',3,'Syntax: .distance\r\n\r\nDisplay the distance from your character to the selected creature.'), +('event',2,'Syntax: .event #event_id\r\nShow details about event with #event_id.'), +('event activelist',2,'Syntax: .event activelist\r\nShow list of currently active events.'), +('event start',2,'Syntax: .event start #event_id\r\nStart event #event_id. Set start time for event to current moment (change not saved in DB).'), +('event stop',2,'Syntax: .event stop #event_id\r\nStop event #event_id. Set start time for event to time in past that make current moment is event stop time (change not saved in DB).'), +('explorecheat',3,'Syntax: .explorecheat #flag\r\n\r\nReveal or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\n\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'), +('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'), +('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'), +('gm fly',3,'Syntax: .gm fly on/off\r\nEnable/disable gm fly mode.'), +('gm list',0,'Syntax: .gm list\r\n\r\nDisplay a list of available Game Masters.'), +('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'), +('go creature',2,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'), +('go graveyard',2,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'), +('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'), +('go object',1,'Syntax: .go object #object_guid\r\nTeleport your character to gameobject with guid #object_guid'), +('go trigger',2,'Syntax: .go trigger #trigger_id\r\n\r\nTeleport your character to areatrigger with id #trigger_id. Character will be teleported to trigger target if selected areatrigger is telporting trigger.'), +('go xy',1,'Syntax: .go xy #x #y [#mapid]\r\n\r\nTeleport player to point with (#x,#y) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), +('go xyz',1,'Syntax: .go xyz #x #y #z [#mapid]\r\n\r\nTeleport player to point with (#x,#y,#z) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), +('go zonexy',1,'Syntax: .go zonexy #x #y [#zone]\r\n\r\nTeleport player to point with (#x,#y) client coordinates at ground(water) level in zone #zoneid or current zone if #zoneid not provided. You can look up zone using .lookup area $namepart'), +('gobject add',2,'Syntax: .gobject add #id \r\n\r\nAdd a game object from game object templates to the world at your current location using the #id.\r\nspawntimesecs sets the spawntime, it is optional.\r\n\r\nNote: this is a copy of .gameobject.'), +('gobject delete',2,'Syntax: .gobject delete #go_guid\r\nDelete gameobject with guid #go_guid.'), +('gobject move',2,'Syntax: .gobject move #goguid [#x #y #z]\r\n\r\nMove gameobject #goguid to character coordinates (or to (#x,#y,#z) coordinates if its provide).'), +('gobject near ',3,'Syntax: .gobject near [#distance]\r\n\r\nOutput gameobjects at distance #distance from player. Output gameobject guids and coordinates sorted by distance from character. If #distance not provided use 10 as default value.'), +('gobject turn',2,'Syntax: .gobject turn #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'), +('gobject target',2,'Syntax: .gobject target [#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'), +('goname',1,'Syntax: .goname $charactername\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group.'), +('gps',1,'Syntax: .gps\r\n\r\nDisplay the position information for a selected character or creature. Position information includes X, Y, Z, and orientation, map Id and zone Id'), +('groupgo',1,'Syntax: .groupgo $charactername\r\n\r\nTeleport the given character and his group to you.'), +('guid',2,'Syntax: .guid\r\n\r\nDisplay the GUID for the selected character.'), +('guild create',2,'Syntax: .guild create $GuildLeaderName $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName as leader.'), +('guild delete',2,'Syntax: .guild delete $GuildName\r\n\r\nDelete guild $GuildName.'), +('guild invite',2,'Syntax: .guild invite $CharacterName $GuildName\r\n\r\nAdd $CharacterName into a guild $GuildName.'), +('guild rank',2,'Syntax: .guild rank $CharacterName #Rank\r\n\r\nSet for $CharacterName rank #Rank in a guild.'), +('guild uninvite',2,'Syntax: .guild uninvite $CharacterName\r\n\r\nRemove $CharacterName from a guild.'), +('help',0,'Syntax: .help $command\r\n\r\nDisplay usage instructions for the given $command.'), +('hidearea',3,'Syntax: .hidearea #areaid\r\n\r\nHide the area of #areaid to the selected character. If no character is selected, hide this area to you.'), +('honor add',2,'Syntax: .honor add $amount\r\n\r\nAdd a certain amount of honor (gained today) to the selected player.'), +('honor addkill',2,'Syntax: .honor addkikll\r\n\r\nAdd the targeted unit as one of your pvp kills today (you only get honor if it\'s a racial leader or a player)'), +('honor update',2,'Syntax: .honor update\r\n\r\nForce the yesterday\'s honor fields to be updated with today\'s data, which will get reset for the selected player.'), +('hover',3,'Syntax: .hover #flag\r\n\r\nEnable or disable hover mode for your character.\r\n\r\nUse a #flag of value 1 to enable, use a #flag value of 0 to disable hover.'), +('instance unbind',3,'Syntax: .instance unbind all\r\n All of the selected player\'s binds will be cleared.'), +('instance listbinds',3,'Syntax: .instance listbinds\r\n Lists the binds of the selected player.'), +('instance stats',3,'Syntax: .instance stats\r\n Shows statistics about instances.'), +('instance savedata',3,'Syntax: .instance savedata\r\n Save the InstanceData for the current player\'s map to the DB.'), +('itemmove',2,'Syntax: .itemmove #sourceslotid #destinationslotid\r\n\r\nMove an item from slots #sourceslotid to #destinationslotid in your inventory\r\n\r\nNot yet implemented'), +('kick',2,'Syntax: .kick [$charactername]\r\n\r\nKick the given character name from the world. If no character name is provided then the selected player (except for yourself) will be kicked.'), +('learn',3,'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter.'), +('learn all',3,'Syntax: .learn all\r\n\r\nLearn all big set different spell maybe useful for Administaror.'), +('learn all_crafts',2,'Syntax: .learn crafts\r\n\r\nLearn all professions and recipes.'), +('learn all_default',1,'Syntax: .learn all_default [$playername]\r\n\r\nLearn for selected/$playername player all default spells for his race/class and spells rewarded by completed quests.'), +('learn all_gm',2,'Syntax: .learn all_gm\r\n\r\nLearn all default spells for Game Masters.'), +('learn all_lang',1,'Syntax: .learn all_lang\r\n\r\nLearn all languages'), +('learn all_myclass',3,'Syntax: .learn all_myclass\r\n\r\nLearn all spells and talents available for his class.'), +('learn all_myspells',3,'Syntax: .learn all_myspells\r\n\r\nLearn all spells (except talents and spells with first rank learned as talent) available for his class.'), +('learn all_mytalents',3,'Syntax: .learn all_mytalents\r\n\r\nLearn all talents (and spells with first rank learned as talent) available for his class.'), +('learn all_recipes',2,'Syntax: .learn all_recipes [$profession]\r\rLearns all recipes of specified profession and sets skill level to max.\rExample: .learn all_recipes enchanting'), +('levelup',3,'Syntax: .levelup [$playername] [#numberoflevels]\r\n\r\nIncrease/decrease the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent VALUESrecalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.'), +('linkgrave',3,'Syntax: .linkgrave #graveyard_id [alliance|horde]\r\n\r\nLink current zone to graveyard for any (or alliance/horde faction ghosts). This let character ghost from zone teleport to graveyard after die if graveyard is nearest from linked to zone and accept ghost of this faction. Add only single graveyard at another map and only if no graveyards linked (or planned linked at same map).'), +('list creature',3,'Syntax: .list creature #creature_id [#max_count]\r\n\r\nOutput creatures with creature id #creature_id found in world. Output creature guids and coordinates sorted by distance from character. Will be output maximum #max_count creatures. If #max_count not provided use 10 as default value.'), +('list item',3,'Syntax: .list item #item_id [#max_count]\r\n\r\nOutput items with item id #item_id found in all character inventories, mails and auctions. Output item guids, item owner guid, owner account and owner name. Will be output maximum #max_count items. If #max_count not provided use 10 as default value.'), +('list object',3,'Syntax: .list object #gameobject_id [#max_count]\r\n\r\nOutput gameobjects with gameobject id #gameobject_id found in world. Output gameobject guids and coordinates sorted by distance from character. Will be output maximum #max_count gameobject. If #max_count not provided use 10 as default value.'), +('loadscripts',3,'Syntax: .loadscripts $scriptlibraryname\r\n\r\nUnload current and load the script library $scriptlibraryname or reload current if $scriptlibraryname omitted, in case you changed it while the server was running.'), +('lockaccount',0,'Syntax: .lockaccount [on|off]\r\n\r\nAllow login from account only from current used IP or remove this requirement.'), +('lookup area',1,'Syntax: .lookup area $namepart\r\n\r\nLooks up an area by $namepart, and returns all matches with their area ID\'s.'), +('lookup creature',3,'Syntax: .lookup creature $namepart\r\n\r\nLooks up a creature by $namepart, and returns all matches with their creature ID\'s.'), +('lookup event',2,'Syntax: .lookup event $name\r\nAttempts to find the ID of the event with the provided $name.'), +('lookup faction',3,'Syntax: .lookup faction $name\r\nAttempts to find the ID of the faction with the provided $name.'), +('lookup item',3,'Syntax: .lookup item $itemname\r\n\r\nLooks up an item by $itemname, and returns all matches with their Item ID\'s.'), +('lookup itemset',3,'Syntax: .lookup itemset $itemname\r\n\r\nLooks up an item set by $itemname, and returns all matches with their Item set ID\'s.'), +('lookup object',3,'Syntax: .lookup object $objname\r\n\r\nLooks up an gameobject by $objname, and returns all matches with their Gameobject ID\'s.'), +('lookup player account',2,'Syntax : .lookup player account $account ($limit) \r\n\r\n Searchs players, which account username is $account with optional parametr $limit of results.'), +('lookup player ip',2,'Syntax : .lookup player ip $ip ($limit) \r\n\r\n Searchs players, which account ast_ip is $ip with optional parametr $limit of results.'), +('lookup player email',2,'Syntax : .lookup player email $email ($limit) \r\n\r\n Searchs players, which account email is $email with optional parametr $limit of results.'), +('lookup quest',3,'Syntax: .lookup quest $namepart\r\n\r\nLooks up a quest by $namepart, and returns all matches with their quest ID\'s.'), +('lookup skill',3,'Syntax: .lookup skill $$namepart\r\n\r\nLooks up a skill by $namepart, and returns all matches with their skill ID\'s.'), +('lookup spell',3,'Syntax: .lookup spell $namepart\r\n\r\nLooks up a spell by $namepart, and returns all matches with their spell ID\'s.'), +('lookup tele',1,'Syntax: .lookup tele $substring\r\n\r\nSearch and output all .tele command locations with provide $substring in name.'), +('maxskill',3,'Syntax: .maxskill\r\nSets all skills of the targeted player to their maximum VALUESfor its current level.'), +('Mod32Value',3,'Syntax: .Mod32Value #field #value\r\n\r\nAdd #value to field #field of your character.'), +('modify arena',3,'Syntax: .modify arena #value\r\nAdd $amount arena points to the selected player.'), +('modify aspeed',1,'Syntax: .modify aspeed #rate\r\n\r\nModify all speeds -run,swim,run back,swim back- of the selected player to \"normalbase speed for this move type\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'), +('modify bit',1,'Syntax: .modify bit #field #bit\r\n\r\nToggle the #bit bit of the #field field for the selected player. If no player is selected, modify your character.'), +('modify bwalk',1,'Syntax: .modify bwalk #rate\r\n\r\nModify the speed of the selected player while running backwards to \"normal walk back speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'), +('modify drunk',1,'Syntax: .modify drunk #value\r\n Set drunk level to #value (0..100). Value 0 remove drunk state, 100 is max drunked state.'), +('modify energy',1,'Syntax: .modify energy #energy\r\n\r\nModify the energy of the selected player. If no player is selected, modify your energy.'), +('modify faction',1,'Syntax: .modify faction #factionid #flagid #npcflagid #dynamicflagid\r\n\r\nModify the faction and flags of the selected creature. Without arguments, display the faction and flags of the selected creature.'), +('modify honor',1,'Syntax: .modify honor $amount\r\n\r\nAdd $amount honor points to the selected player.'), +('modify hp',1,'Syntax: .modify hp #newhp\r\n\r\nModify the hp of the selected player. If no player is selected, modify your hp.'), +('modify mana',1,'Syntax: .modify mana #newmana\r\n\r\nModify the mana of the selected player. If no player is selected, modify your mana.'), +('modify money',1,'Syntax:\r\n.modify money #money\r\n.money #money\r\n\r\nAdd or remove money to the selected player. If no player is selected, modify your money.\r\n\r\n #gold can be negative to remove money.'), +('modify morph',2,'Syntax: .modify morph #displayid\r\n\r\nChange your current model id to #displayid.'), +('modify mount',1,'Syntax:\r\n.modify mount #id #speed\r\nDisplay selected player as mounted at #id creature and set speed to #speed value.'), +('modify rage',1,'Syntax: .modify rage #newrage\r\n\r\nModify the rage of the selected player. If no player is selected, modify your rage.'), +('modify rep',2,'Syntax: .modify rep #repId (#repvalue | $rankname [#delta])\r\nSets the selected players reputation with faction #repId to #repvalue or to $reprank.\r\nIf the reputation rank name is provided, the resulting reputation will be the lowest reputation for that rank plus the delta amount, if specified.\r\nYou can use \'.pinfo rep\' to list all known reputation ids, or use \'.lookup faction $name\' to locate a specific faction id.'), +('modify scale',1,''), +('modify speed',1,'Syntax:\r\n.modify speed #rate\r\n.speed #rate\r\n\r\nModify the running speed of the selected player to \"normal base run speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'), +('modify spell',1,''), +('modify swim',1,'Syntax: .modify swim #rate\r\n\r\nModify the swim speed of the selected player to \"normal swim speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'), +('modify titles',1,'Syntax:\r\n.modify titles #mask\r\n\r\nAllows user to use all titles from #mask.\r\n\r\n #mask=0 disables the title-choose-field'), +('movegens',3,'Syntax: .movegens\r\n Show movement generators stack for selected creature or player.'), +('mute',1,'Syntax: .mute $playerName $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName at $timeInMinutes minutes.'), +('namego',1,'Syntax: .namego $charactername\r\n\r\nTeleport the given character to you.'), +('neargrave',3,'Syntax: .neargrave [alliance|horde]\r\n\r\nFind nearest graveyard linked to zone (or only nearest from accepts alliance or horde faction ghosts).'), +('notify',1,'Syntax: .notify $MessageToBroadcast\r\n\r\nSend a global message to all players online in screen.'), +('npc add',2,'Syntax: .npc add #creatureid\r\n\r\nSpawn a creature by the given template id of #creatureid.'), +('npc additem',2,'Syntax: .npc additem #itemId <#maxcount><#incrtime><#extendedcost>r\r\n\r\nAdd item #itemid to item list of selected vendor. Also optionally set max count item in vendor item list and time to item count restoring and items ExtendedCost.'), +('npc addweapon',3,'Not yet implemented.'), +('npc allowmove',3,'Syntax: .npc allowmove\r\n\r\nEnable or disable movement for the selected creature.'), +('npc changelevel',2,'Syntax: .npc changelevel #level\r\n\r\nChange the level of the selected creature to #level.\r\n\r\n#level may range from 1 to 63.'), +('npc delete',2,'Syntax: .npc delete [#guid]\r\n\r\nDelete creature with guid #guid (or the selected if no guid is provided)'), +('npc delitem',2,'Syntax: .npc delitem #itemId\r\n\r\nRemove item #itemid from item list of selected vendor.'), +('npc factionid',2,'Syntax: .npc factionid #factionid\r\n\r\nSet the faction of the selected creature to #factionid.'), +('npc flag',2,'Syntax: .npc flag #npcflag\r\n\r\nSet the NPC flags of creature template of the selected creature and selected creature to #npcflag. NPC flags will applied to all creatures of selected creature template after server restart or grid unload/load.'), +('npc info',3,'Syntax: .npc info\r\n\r\nDisplay a list of details for the selected creature.\r\n\r\nThe list includes:\r\n- GUID, Faction, NPC flags, Entry ID, Model ID,\r\n- Level,\r\n- Health (current/maximum),\r\n\r\n- Field flags, dynamic flags, faction template, \r\n- Position information,\r\n- and the creature type, e.g. if the creature is a vendor.'), +('npc move',2,'Syntax: .npc move [#creature_guid]\r\n\r\nMove the targeted creature spawn point to your coordinates.'), +('npc name',2,'Syntax: .npc name $name\r\n\r\nChange the name of the selected creature or character to $name.\r\n\r\nCommand disabled.'), +('npc playemote',3,'Syntax: .npc playemote #emoteid\r\n\r\nMake the selected creature emote with an emote of id #emoteid.'), +('npc setmodel',2,'Syntax: .npc setmodel #displayid\r\n\r\nChange the model id of the selected creature to #displayid.'), +('npc setmovetype',2,'Syntax: .npc setmovetype [#creature_guid] stay/random/way [NODEL]\r\n\r\nSet for creature pointed by #creature_guid (or selected if #creature_guid not provided) movement type and move it to respawn position (if creature alive). Any existing waypoints for creature will be removed from the database if you do not use NODEL. If the creature is dead then movement type will applied at creature respawn.\r\nMake sure you use NODEL, if you want to keep the waypoints.'), +('npc spawndist',2,'Syntax: .npc spawndist #dist\r\n\r\nAdjust spawndistance of selected creature to dist.'), +('npc spawntime',2,'Syntax: .npc spawntime #time \r\n\r\nAdjust spawntime of selected creature to time.'), +('npc subname',2,'Syntax: .npc subname $Name\r\n\r\nChange the subname of the selected creature or player to $Name.\r\n\r\nCommand disabled.'), +('npc textemote',3,'Syntax: .npc textemote #emoteid\r\n\r\nMake the selected creature to do textemote with an emote of id #emoteid.'), +('npc whisper',1,'Syntax: .npc whisper #playerguid #text\r\nMake the selected npc whisper #text to #playerguid.'), +('password',0,'Syntax: .password $old_password $new_password $new_password\r\n\r\nChange your account password.'), +('pinfo',2,'Syntax: .pinfo [$player_name] [rep]\r\n\r\nOutput account information for selected player or player find by $player_name. If \"rep\" parameter provided show reputation information for player.'), +('plimit',3,'Syntax: .plimit [#num|-1|-2|-3|reset|player|moderator|gamemaster|administrator]\r\n\r\nWithout arg show current player amount and security level limitations for login to server, with arg set player linit ($num > 0) or securiti limitation ($num < 0 or security leme name. With `reset` sets player limit to the one in the config file'), +('quest add',3,'Syntax: .quest add #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'), +('quest complete',3,'Syntax: .quest complete #questid\r\nMark all quest objectives as completed for target character active quest. After this target character can go and get quest reward.'), +('quest remove',3,'Syntax: .quest remove #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'), +('recall',1,'Syntax: .recall [$playername]\r\n\r\nTeleport $playername or selected player to the place where he has been before last use of a teleportation command. If no $playername is entered and no player is selected, it will teleport you.'), +('reload',3,'Syntax: .reload table_name\r\n\r\nReload table `table_name` if reload support added for this table and this table can be _safe_ reloaded.'), +('reload all',3,'Syntax: .reload all\r\n\r\nReload all tables with reload support added and that can be _safe_ reloaded.'), +('reload all_area',3,'Syntax: .reload all_area\r\n\r\nReload all `areatrigger_*` tables if reload support added for this table and this table can be _safe_ reloaded.'), +('reload all_loot',3,'Syntax: .reload all_loot\r\n\r\nReload all `*_loot_template` tables. This can be slow operation with lags for server run.'), +('reload all_quest',3,'Syntax: .reload all_quest\r\n\r\nReload all quest related tables if reload support added for this table and this table can be _safe_ reloaded.'), +('reload all_spell',3,'Syntax: .reload all_spell\r\n\r\nReload all `spell_*` tables with reload support added and that can be _safe_ reloaded.'), +('reload all_locales',3,'Syntax: .reload all_locales\r\n\r\nReload all `locales_*` tables with reload support added and that can be _safe_ reloaded.'), +('reload config',3,'Syntax: .reload config\r\n\r\nReload config settings (by default stored in mangosd.conf). Not all settings can be change at reload: some new setting values will be ignored until restart, some values will applied with delay or only to new objects/maps, some values will explicitly rejected to change at reload.'), +('reset all',3,'Syntax: .reset all spells\r\n\r\nSyntax: .reset all talents\r\n\r\nRequest reset spells or talents at next login each existed character.'), +('reset honor',3,'Syntax:\r\n.reset honor [Playername]\r\n Reset all honor data for targeted character.'), +('reset level',3,'Syntax:\r\n.reset level [Playername]\r\n Reset level to 1 including reset stats and talents. Equipped items with greater level requirement can be lost.'), +('reset spells',3,'Syntax:\r\n.reset spells [Playername]\r\n Removes all non-original spells from spellbook.\r\n. Playername can be name of offline character.'), +('reset stats',3,'Syntax:\r\n.reset stats [Playername]\r\n Resets(recalculate) all stats of the targeted player to their original VALUESat current level.'), +('reset talents',3,'Syntax:\r\n.reset talents [Playername]\r\n Removes all talents of the targeted player. Playername can be name of offline character.'), +('respawn',3,'Syntax: .respawn\r\n\r\nRespawn all nearest creatures and GO without waiting respawn time expiration.'), +('revive',3,'Syntax: .revive\r\n\r\nRevive the selected player. If no player is selected, it will revive you.'), +('save',0,'Syntax: .save\r\n\r\nSaves your character.'), +('saveall',1,'Syntax: .saveall\r\n\r\nSave all characters in game.'), +('security',3,'Syntax: .security $name #level\r\n\r\nSet the security level of player $name to a level of #level.\r\n\r\n#level may range from 0 to 5.'), +('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'), +('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'), +('server idleshutdown',3,'Syntax: .server idleshutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'), +('server idlerestart',3,'Syntax: .server idlerestart #delay|cancel\r\n\r\nRestart the server after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'), +('server restart',3,'Syntax: .server restart seconds\r\n\r\nRestart the server after given seconds and show "Restart server in X" or cancel the restart/shutdown if cancel value is used.'), +('server shutdown',3,'Syntax: .server shutdown seconds\r\n\r\nShut the server down after given seconds and show "Off server in X" or cancel the restart/shutdown if cancel value is used.'), +('setskill',3,'Syntax: .setskill #skill #level [#max]\r\n\r\nSet a skill of id #skill with a current skill value of #level and a maximum value of #max (or equal current maximum if not provide) for the selected character. If no character is selected, you learn the skill.'), +('showarea',3,'Syntax: .showarea #areaid\r\n\r\nReveal the area of #areaid to the selected character. If no character is selected, reveal this area to you.'), +('start',0,'Syntax: .start\r\n\r\nTeleport you to the starting area of your character.'), +('taxicheat',1,'Syntax: .taxicheat on/off\r\n\r\nTemporary grant access or remove to all taxi routes for the selected character. If no character is selected, hide or reveal all routes to you.\r\n\r\nVisited taxi nodes sill accessible after removing access.'), +('tele',1,'Syntax: .tele #location\r\n\r\nTeleport player to a given location.'), +('tele add',3,'Syntax: .tele add $name\r\n\r\nAdd current your position to .tele command target locations list with name $name.'), +('tele del',3,'Syntax: .tele del $name\r\n\r\nRemove location with name $name for .tele command locations list.'), +('tele group',1,'Syntax: .tele group#location\r\n\r\nTeleport a selected player and his group members to a given location.'), +('tele name',1,'Syntax: .tele name #playername #location\r\n\r\nTeleport a player to a given location.'), +('ticket',2,'Syntax: .ticket on\r\n .ticket off\r\n .ticket #num\r\n .ticket $character_name\r\n\r\non/off for GMs to show or not a new ticket directly, $character_name to show ticket of this character, #num to show ticket #num.'), +('transport',3,'Not yet implemented.'), +('unaura',3,'Syntax: .unaura #spellid\r\n\r\nRemove aura due to spell #spellid from the selected Unit.'), +('unban',3,'Syntax is: unban $NameOrIp\r\nUnban account or IP.'), +('unlearn',3,'Syntax: .unlearn #startspell #endspell\r\n\r\nUnlearn for selected player the range of spells between id #startspell and #endspell. If no #endspell is provided, just unlearn spell of id #startspell.'), +('unmute',1,'Syntax: .unmute $playerName\r\n\r\nRestore chat messaging for any character from account of character $playerName.'), +('wchange',3,'Syntax: .wchange #weathertype #status\r\n\r\nSet current weather to #weathertype with an intensity of #status.\r\n\r\n#weathertype can be 1 for rain, 2 for snow, and 3 for sand. #status can be 0 for disabled, and 1 for enabled.'), +('whispers',1,'Syntax: .whispers on|off\r\nEnable/disable accepting whispers by GM from players. By default use mangosd.conf setting.'), +('wp',2,'Using WP Command:\r\nEach Waypoint Command has it\'s own description!'), +('wp add',2,'Syntax: .wp add [#creature_guid or Select a Creature]'), +('wp export',3,'Syntax: .wp export [#creature_guid or Select a Creature] $filename'), +('wp import',3,'Syntax: .wp import $filename'), +('wp modify',2,'Syntax: .wp modify [#creature_guid or Select a Creature]\r\nadd - Add a waypoint after the selected visual\r\nwaittime $time\r\nemote ID\r\nspell ID\r\ntext1| text2| text3| text4| text5 \r\nmodel1 ID\r\nmodel2 ID\r\nmove(moves wp to player pos)\r\ndel (deletes the wp)\r\n\r\nOnly one parameter per time!'), +('wp show',2,'Syntax: .wp show [#creature_guid or Select a Creature]\r\non\r\nfirst\r\nlast\r\noff\r\ninfo\r\n\r\nFor using info you have to do first show on and than select a Visual-Waypoint and do the show info!'); +/*!40000 ALTER TABLE `command` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature` +-- + +DROP TABLE IF EXISTS `creature`; +CREATE TABLE `creature` ( + `guid` int(10) unsigned NOT NULL auto_increment COMMENT 'Global Unique Identifier', + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Creature Identifier', + `map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `spawnMask` tinyint(3) unsigned NOT NULL default '1', + `modelid` mediumint(8) unsigned NOT NULL default '0', + `equipment_id` mediumint(9) NOT NULL default '0', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `orientation` float NOT NULL default '0', + `spawntimesecs` int(10) unsigned NOT NULL default '120', + `spawndist` float NOT NULL default '5', + `currentwaypoint` mediumint(8) unsigned NOT NULL default '0', + `curhealth` int(10) unsigned NOT NULL default '1', + `curmana` int(10) unsigned NOT NULL default '0', + `DeathState` tinyint(3) unsigned NOT NULL default '0', + `MovementType` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`), + KEY `idx_map` (`map`), + KEY `index_id` (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Creature System'; + +-- +-- Dumping data for table `creature` +-- + +LOCK TABLES `creature` WRITE; +/*!40000 ALTER TABLE `creature` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_addon` +-- + +DROP TABLE IF EXISTS `creature_addon`; +CREATE TABLE `creature_addon` ( + `guid` int(11) NOT NULL default '0', + `mount` mediumint(8) unsigned NOT NULL default '0', + `bytes0` int(10) unsigned NOT NULL default '0', + `bytes1` int(10) unsigned NOT NULL default '0', + `bytes2` int(10) unsigned NOT NULL default '0', + `emote` int(10) unsigned NOT NULL default '0', + `moveflags` int(10) unsigned NOT NULL default '0', + `auras` text, + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `creature_addon` +-- + +LOCK TABLES `creature_addon` WRITE; +/*!40000 ALTER TABLE `creature_addon` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_addon` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_equip_template` +-- + +DROP TABLE IF EXISTS `creature_equip_template`; +CREATE TABLE `creature_equip_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Unique entry', + `equipmodel1` mediumint(8) unsigned NOT NULL default '0', + `equipmodel2` mediumint(8) unsigned NOT NULL default '0', + `equipmodel3` mediumint(8) unsigned NOT NULL default '0', + `equipinfo1` int(10) unsigned NOT NULL default '0', + `equipinfo2` int(10) unsigned NOT NULL default '0', + `equipinfo3` int(10) unsigned NOT NULL default '0', + `equipslot1` int(11) NOT NULL default '0', + `equipslot2` int(11) NOT NULL default '0', + `equipslot3` int(11) NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Creature System (Equipment)'; + +-- +-- Dumping data for table `creature_equip_template` +-- + +LOCK TABLES `creature_equip_template` WRITE; +/*!40000 ALTER TABLE `creature_equip_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_equip_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_involvedrelation` +-- + +DROP TABLE IF EXISTS `creature_involvedrelation`; +CREATE TABLE `creature_involvedrelation` ( + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Identifier', + `quest` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + PRIMARY KEY (`id`,`quest`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature System'; + +-- +-- Dumping data for table `creature_involvedrelation` +-- + +LOCK TABLES `creature_involvedrelation` WRITE; +/*!40000 ALTER TABLE `creature_involvedrelation` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_involvedrelation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_loot_template` +-- + +DROP TABLE IF EXISTS `creature_loot_template`; +CREATE TABLE `creature_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `creature_loot_template` +-- + +LOCK TABLES `creature_loot_template` WRITE; +/*!40000 ALTER TABLE `creature_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_model_info` +-- + +DROP TABLE IF EXISTS `creature_model_info`; +CREATE TABLE `creature_model_info` ( + `modelid` mediumint(8) unsigned NOT NULL default '0', + `bounding_radius` float NOT NULL default '0', + `combat_reach` float NOT NULL default '0', + `gender` tinyint(3) unsigned NOT NULL default '2', + `modelid_other_gender` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`modelid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Creature System (Model related info)'; + +-- +-- Dumping data for table `creature_model_info` +-- + +LOCK TABLES `creature_model_info` WRITE; +/*!40000 ALTER TABLE `creature_model_info` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_model_info` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_movement` +-- + +DROP TABLE IF EXISTS `creature_movement`; +CREATE TABLE `creature_movement` ( + `id` int(10) unsigned NOT NULL COMMENT 'Creature GUID', + `point` mediumint(8) unsigned NOT NULL default '0', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `waittime` int(10) unsigned NOT NULL default '0', + `text1` text, + `text2` text, + `text3` text, + `text4` text, + `text5` text, + `emote` mediumint(8) unsigned NOT NULL default '0', + `spell` mediumint(8) unsigned NOT NULL default '0', + `wpguid` int(11) NOT NULL default '0', + `orientation` float NOT NULL default '0', + `model1` mediumint(9) NOT NULL default '0', + `model2` mediumint(9) NOT NULL default '0', + PRIMARY KEY (`id`,`point`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature System'; + +-- +-- Dumping data for table `creature_movement` +-- + +LOCK TABLES `creature_movement` WRITE; +/*!40000 ALTER TABLE `creature_movement` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_movement` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_onkill_reputation` +-- + +DROP TABLE IF EXISTS `creature_onkill_reputation`; +CREATE TABLE `creature_onkill_reputation` ( + `creature_id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Creature Identifier', + `RewOnKillRepFaction1` smallint(6) NOT NULL default '0', + `RewOnKillRepFaction2` smallint(6) NOT NULL default '0', + `MaxStanding1` tinyint(4) NOT NULL default '0', + `IsTeamAward1` tinyint(4) NOT NULL default '0', + `RewOnKillRepValue1` mediumint(9) NOT NULL default '0', + `MaxStanding2` tinyint(4) NOT NULL default '0', + `IsTeamAward2` tinyint(4) NOT NULL default '0', + `RewOnKillRepValue2` mediumint(9) NOT NULL default '0', + `TeamDependent` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`creature_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Creature OnKill Reputation gain'; + +-- +-- Dumping data for table `creature_onkill_reputation` +-- + +LOCK TABLES `creature_onkill_reputation` WRITE; +/*!40000 ALTER TABLE `creature_onkill_reputation` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_onkill_reputation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_questrelation` +-- + +DROP TABLE IF EXISTS `creature_questrelation`; +CREATE TABLE `creature_questrelation` ( + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Identifier', + `quest` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + PRIMARY KEY (`id`,`quest`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature System'; + +-- +-- Dumping data for table `creature_questrelation` +-- + +LOCK TABLES `creature_questrelation` WRITE; +/*!40000 ALTER TABLE `creature_questrelation` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_questrelation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_respawn` +-- + +DROP TABLE IF EXISTS `creature_respawn`; +CREATE TABLE `creature_respawn` ( + `guid` int(10) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `respawntime` bigint(20) NOT NULL default '0', + `instance` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`instance`), + KEY `instance` (`instance`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Grid Loading System'; + +-- +-- Dumping data for table `creature_respawn` +-- + +LOCK TABLES `creature_respawn` WRITE; +/*!40000 ALTER TABLE `creature_respawn` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_respawn` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_template` +-- + +DROP TABLE IF EXISTS `creature_template`; +CREATE TABLE `creature_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `heroic_entry` mediumint(8) unsigned NOT NULL default '0', + `modelid_A` mediumint(8) unsigned NOT NULL default '0', + `modelid_A2` mediumint(8) unsigned NOT NULL default '0', + `modelid_H` mediumint(8) unsigned NOT NULL default '0', + `modelid_H2` mediumint(8) unsigned NOT NULL default '0', + `name` char(100) NOT NULL default '0', + `subname` char(100) default NULL, + `IconName` char(100) default NULL, + `minlevel` tinyint(3) unsigned NOT NULL default '1', + `maxlevel` tinyint(3) unsigned NOT NULL default '1', + `minhealth` int(10) unsigned NOT NULL default '0', + `maxhealth` int(10) unsigned NOT NULL default '0', + `minmana` int(10) unsigned NOT NULL default '0', + `maxmana` int(10) unsigned NOT NULL default '0', + `armor` mediumint(8) unsigned NOT NULL default '0', + `faction_A` smallint(5) unsigned NOT NULL default '0', + `faction_H` smallint(5) unsigned NOT NULL default '0', + `npcflag` int(10) unsigned NOT NULL default '0', + `speed` float NOT NULL default '1', + `scale` float NOT NULL default '1', + `rank` tinyint(3) unsigned NOT NULL default '0', + `mindmg` float NOT NULL default '0', + `maxdmg` float NOT NULL default '0', + `dmgschool` tinyint(4) NOT NULL default '0', + `attackpower` int(10) unsigned NOT NULL default '0', + `baseattacktime` int(10) unsigned NOT NULL default '0', + `rangeattacktime` int(10) unsigned NOT NULL default '0', + `flags` int(10) unsigned NOT NULL default '0', + `dynamicflags` int(10) unsigned NOT NULL default '0', + `family` tinyint(4) NOT NULL default '0', + `trainer_type` tinyint(4) NOT NULL default '0', + `trainer_spell` mediumint(8) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `race` tinyint(3) unsigned NOT NULL default '0', + `minrangedmg` float NOT NULL default '0', + `maxrangedmg` float NOT NULL default '0', + `rangedattackpower` smallint(5) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `flag1` int(10) unsigned NOT NULL default '0', + `lootid` mediumint(8) unsigned NOT NULL default '0', + `pickpocketloot` mediumint(8) unsigned NOT NULL default '0', + `skinloot` mediumint(8) unsigned NOT NULL default '0', + `resistance1` smallint(5) NOT NULL default '0', + `resistance2` smallint(5) NOT NULL default '0', + `resistance3` smallint(5) NOT NULL default '0', + `resistance4` smallint(5) NOT NULL default '0', + `resistance5` smallint(5) NOT NULL default '0', + `resistance6` smallint(5) NOT NULL default '0', + `spell1` mediumint(8) unsigned NOT NULL default '0', + `spell2` mediumint(8) unsigned NOT NULL default '0', + `spell3` mediumint(8) unsigned NOT NULL default '0', + `spell4` mediumint(8) unsigned NOT NULL default '0', + `PetSpellDataId` mediumint(8) unsigned NOT NULL default '0', + `mingold` mediumint(8) unsigned NOT NULL default '0', + `maxgold` mediumint(8) unsigned NOT NULL default '0', + `AIName` char(64) NOT NULL default '', + `MovementType` tinyint(3) unsigned NOT NULL default '0', + `InhabitType` tinyint(3) unsigned NOT NULL default '3', + `RacialLeader` tinyint(3) unsigned NOT NULL default '0', + `RegenHealth` tinyint(3) unsigned NOT NULL default '1', + `equipment_id` mediumint(8) unsigned NOT NULL default '0', + `mechanic_immune_mask` int(10) unsigned NOT NULL default '0', + `flags_extra` int(10) unsigned NOT NULL default '0', + `ScriptName` char(64) NOT NULL default '', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature System'; + +-- +-- Dumping data for table `creature_template` +-- + +LOCK TABLES `creature_template` WRITE; +/*!40000 ALTER TABLE `creature_template` DISABLE KEYS */; +INSERT INTO `creature_template` VALUES +(1,1,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,2000,2200,4096,0,8,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,0,1,0,0,0x82,''); +/*!40000 ALTER TABLE `creature_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `creature_template_addon` +-- + +DROP TABLE IF EXISTS `creature_template_addon`; +CREATE TABLE `creature_template_addon` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `mount` mediumint(8) unsigned NOT NULL default '0', + `bytes0` int(10) unsigned NOT NULL default '0', + `bytes1` int(10) unsigned NOT NULL default '0', + `bytes2` int(10) unsigned NOT NULL default '0', + `emote` mediumint(8) unsigned NOT NULL default '0', + `moveflags` int(10) unsigned NOT NULL default '0', + `auras` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `creature_template_addon` +-- + +LOCK TABLES `creature_template_addon` WRITE; +/*!40000 ALTER TABLE `creature_template_addon` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_template_addon` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `db_version` +-- + +DROP TABLE IF EXISTS `db_version`; +CREATE TABLE `db_version` ( + `version` varchar(120) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; + +-- +-- Dumping data for table `db_version` +-- + +LOCK TABLES `db_version` WRITE; +/*!40000 ALTER TABLE `db_version` DISABLE KEYS */; +INSERT INTO `db_version` VALUES +('Mangos default database.'); +/*!40000 ALTER TABLE `db_version` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `disenchant_loot_template` +-- + +DROP TABLE IF EXISTS `disenchant_loot_template`; +CREATE TABLE `disenchant_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Recommended id selection: item_level*100 + item_quality', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `disenchant_loot_template` +-- + +LOCK TABLES `disenchant_loot_template` WRITE; +/*!40000 ALTER TABLE `disenchant_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `disenchant_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `event_scripts` +-- + +DROP TABLE IF EXISTS `event_scripts`; +CREATE TABLE `event_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `event_scripts` +-- + +LOCK TABLES `event_scripts` WRITE; +/*!40000 ALTER TABLE `event_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `event_scripts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `exploration_basexp` +-- + +DROP TABLE IF EXISTS `exploration_basexp`; +CREATE TABLE `exploration_basexp` ( + `level` tinyint(4) NOT NULL default '0', + `basexp` mediumint(9) NOT NULL default '0', + PRIMARY KEY (`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Exploration System'; + +-- +-- Dumping data for table `exploration_basexp` +-- + +LOCK TABLES `exploration_basexp` WRITE; +/*!40000 ALTER TABLE `exploration_basexp` DISABLE KEYS */; +INSERT INTO `exploration_basexp` VALUES +(0,0), +(1,5), +(2,15), +(3,25), +(4,35), +(5,45), +(6,55), +(7,65), +(8,70), +(9,80), +(10,85), +(11,90), +(12,90), +(13,90), +(14,100), +(15,105), +(16,115), +(17,125), +(18,135), +(19,145), +(20,155), +(21,165), +(22,175), +(23,185), +(24,195), +(25,200), +(26,210), +(27,220), +(28,230), +(29,240), +(30,245), +(31,250), +(32,255), +(33,265), +(34,270), +(35,275), +(36,280), +(37,285), +(38,285), +(39,300), +(40,315), +(41,330), +(42,345), +(43,360), +(44,375), +(45,390), +(46,405), +(47,420), +(48,440), +(49,455), +(50,470), +(51,490), +(52,510), +(53,530), +(54,540), +(55,560), +(56,580), +(57,600), +(58,620), +(59,640), +(60,660), +(61,970), +(62,1000), +(63,1050), +(64,1080), +(65,1100), +(66,1130), +(67,1160), +(68,1200), +(69,1230), +(70,1250); +/*!40000 ALTER TABLE `exploration_basexp` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `fishing_loot_template` +-- + +DROP TABLE IF EXISTS `fishing_loot_template`; +CREATE TABLE `fishing_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `fishing_loot_template` +-- + +LOCK TABLES `fishing_loot_template` WRITE; +/*!40000 ALTER TABLE `fishing_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `fishing_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_event` +-- + +DROP TABLE IF EXISTS `game_event`; +CREATE TABLE `game_event` ( + `entry` mediumint(8) unsigned NOT NULL COMMENT 'Entry of the game event', + `start_time` timestamp NOT NULL default '0000-00-00 00:00:00' COMMENT 'Absolute start date, the event will never start before', + `end_time` timestamp NOT NULL default '0000-00-00 00:00:00' COMMENT 'Absolute end date, the event will never start afler', + `occurence` bigint(20) unsigned NOT NULL default '86400' COMMENT 'Delay in hours between occurences of the event', + `length` bigint(20) unsigned NOT NULL default '43200' COMMENT 'Length in hours of the event', + `description` varchar(255) default NULL COMMENT 'Description of the event displayed in console', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `game_event` +-- + +LOCK TABLES `game_event` WRITE; +/*!40000 ALTER TABLE `game_event` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_event_creature` +-- + +DROP TABLE IF EXISTS `game_event_creature`; +CREATE TABLE `game_event_creature` ( + `guid` int(10) unsigned NOT NULL, + `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `game_event_creature` +-- + +LOCK TABLES `game_event_creature` WRITE; +/*!40000 ALTER TABLE `game_event_creature` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event_creature` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_event_creature_quest` +-- + +DROP TABLE IF EXISTS `game_event_creature_quest`; +CREATE TABLE `game_event_creature_quest` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `quest` mediumint(8) unsigned NOT NULL default '0', + `event` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`id`,`quest`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `game_event_creature_quest` +-- + +LOCK TABLES `game_event_creature_quest` WRITE; +/*!40000 ALTER TABLE `game_event_creature_quest` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event_creature_quest` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_event_gameobject` +-- + +DROP TABLE IF EXISTS `game_event_gameobject`; +CREATE TABLE `game_event_gameobject` ( + `guid` int(10) unsigned NOT NULL, + `event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `game_event_gameobject` +-- + +LOCK TABLES `game_event_gameobject` WRITE; +/*!40000 ALTER TABLE `game_event_gameobject` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event_gameobject` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_event_model_equip` +-- + +DROP TABLE IF EXISTS `game_event_model_equip`; +CREATE TABLE `game_event_model_equip` ( + `guid` int(10) unsigned NOT NULL default '0', + `modelid` mediumint(8) unsigned NOT NULL default '0', + `equipment_id` mediumint(8) unsigned NOT NULL default '0', + `event` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `game_event_model_equip` +-- + +LOCK TABLES `game_event_model_equip` WRITE; +/*!40000 ALTER TABLE `game_event_model_equip` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event_model_equip` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_graveyard_zone` +-- + +DROP TABLE IF EXISTS `game_graveyard_zone`; +CREATE TABLE `game_graveyard_zone` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `ghost_zone` mediumint(8) unsigned NOT NULL default '0', + `faction` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`id`,`ghost_zone`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Trigger System'; + +-- +-- Dumping data for table `game_graveyard_zone` +-- + +LOCK TABLES `game_graveyard_zone` WRITE; +/*!40000 ALTER TABLE `game_graveyard_zone` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_graveyard_zone` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_tele` +-- + +DROP TABLE IF EXISTS `game_tele`; +CREATE TABLE `game_tele` ( + `id` mediumint(8) unsigned NOT NULL auto_increment, + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `orientation` float NOT NULL default '0', + `map` smallint(5) unsigned NOT NULL default '0', + `name` varchar(100) NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Tele Command'; + +-- +-- Dumping data for table `game_tele` +-- + +LOCK TABLES `game_tele` WRITE; +/*!40000 ALTER TABLE `game_tele` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_tele` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `game_weather` +-- + +DROP TABLE IF EXISTS `game_weather`; +CREATE TABLE `game_weather` ( + `zone` mediumint(8) unsigned NOT NULL default '0', + `spring_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `spring_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `spring_storm_chance` tinyint(3) unsigned NOT NULL default '25', + `summer_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `summer_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `summer_storm_chance` tinyint(3) unsigned NOT NULL default '25', + `fall_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `fall_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `fall_storm_chance` tinyint(3) unsigned NOT NULL default '25', + `winter_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `winter_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `winter_storm_chance` tinyint(3) unsigned NOT NULL default '25', + PRIMARY KEY (`zone`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Weather System'; + +-- +-- Dumping data for table `game_weather` +-- + +LOCK TABLES `game_weather` WRITE; +/*!40000 ALTER TABLE `game_weather` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_weather` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject` +-- + +DROP TABLE IF EXISTS `gameobject`; +CREATE TABLE `gameobject` ( + `guid` int(10) unsigned NOT NULL auto_increment COMMENT 'Global Unique Identifier', + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Gameobject Identifier', + `map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `spawnMask` tinyint(3) unsigned NOT NULL default '1', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `orientation` float NOT NULL default '0', + `rotation0` float NOT NULL default '0', + `rotation1` float NOT NULL default '0', + `rotation2` float NOT NULL default '0', + `rotation3` float NOT NULL default '0', + `spawntimesecs` int(11) NOT NULL default '0', + `animprogress` tinyint(3) unsigned NOT NULL default '0', + `state` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Gameobject System'; + +-- +-- Dumping data for table `gameobject` +-- + +LOCK TABLES `gameobject` WRITE; +/*!40000 ALTER TABLE `gameobject` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject_involvedrelation` +-- + +DROP TABLE IF EXISTS `gameobject_involvedrelation`; +CREATE TABLE `gameobject_involvedrelation` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `quest` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + PRIMARY KEY (`id`,`quest`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gameobject_involvedrelation` +-- + +LOCK TABLES `gameobject_involvedrelation` WRITE; +/*!40000 ALTER TABLE `gameobject_involvedrelation` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject_involvedrelation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject_loot_template` +-- + +DROP TABLE IF EXISTS `gameobject_loot_template`; +CREATE TABLE `gameobject_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `gameobject_loot_template` +-- + +LOCK TABLES `gameobject_loot_template` WRITE; +/*!40000 ALTER TABLE `gameobject_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject_questrelation` +-- + +DROP TABLE IF EXISTS `gameobject_questrelation`; +CREATE TABLE `gameobject_questrelation` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `quest` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + PRIMARY KEY (`id`,`quest`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gameobject_questrelation` +-- + +LOCK TABLES `gameobject_questrelation` WRITE; +/*!40000 ALTER TABLE `gameobject_questrelation` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject_questrelation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject_respawn` +-- + +DROP TABLE IF EXISTS `gameobject_respawn`; +CREATE TABLE `gameobject_respawn` ( + `guid` int(10) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `respawntime` bigint(20) NOT NULL default '0', + `instance` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`instance`), + KEY `instance` (`instance`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Grid Loading System'; + +-- +-- Dumping data for table `gameobject_respawn` +-- + +LOCK TABLES `gameobject_respawn` WRITE; +/*!40000 ALTER TABLE `gameobject_respawn` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject_respawn` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject_scripts` +-- + +DROP TABLE IF EXISTS `gameobject_scripts`; +CREATE TABLE `gameobject_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gameobject_scripts` +-- + +LOCK TABLES `gameobject_scripts` WRITE; +/*!40000 ALTER TABLE `gameobject_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject_scripts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gameobject_template` +-- + +DROP TABLE IF EXISTS `gameobject_template`; +CREATE TABLE `gameobject_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `displayId` mediumint(8) unsigned NOT NULL default '0', + `name` varchar(100) NOT NULL default '', + `castBarCaption` varchar(100) NOT NULL default '', + `faction` smallint(5) unsigned NOT NULL default '0', + `flags` int(10) unsigned NOT NULL default '0', + `size` float NOT NULL default '1', + `data0` int(10) unsigned NOT NULL default '0', + `data1` int(10) unsigned NOT NULL default '0', + `data2` int(10) unsigned NOT NULL default '0', + `data3` int(10) unsigned NOT NULL default '0', + `data4` int(10) unsigned NOT NULL default '0', + `data5` int(10) unsigned NOT NULL default '0', + `data6` int(10) unsigned NOT NULL default '0', + `data7` int(10) unsigned NOT NULL default '0', + `data8` int(10) unsigned NOT NULL default '0', + `data9` int(10) unsigned NOT NULL default '0', + `data10` int(10) unsigned NOT NULL default '0', + `data11` int(10) unsigned NOT NULL default '0', + `data12` int(10) unsigned NOT NULL default '0', + `data13` int(10) unsigned NOT NULL default '0', + `data14` int(10) unsigned NOT NULL default '0', + `data15` int(10) unsigned NOT NULL default '0', + `data16` int(10) unsigned NOT NULL default '0', + `data17` int(10) unsigned NOT NULL default '0', + `data18` int(10) unsigned NOT NULL default '0', + `data19` int(10) unsigned NOT NULL default '0', + `data20` int(10) unsigned NOT NULL default '0', + `data21` int(10) unsigned NOT NULL default '0', + `data22` int(10) unsigned NOT NULL default '0', + `data23` int(10) unsigned NOT NULL default '0', + `ScriptName` varchar(64) NOT NULL default '', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Gameobject System'; + +-- +-- Dumping data for table `gameobject_template` +-- + +LOCK TABLES `gameobject_template` WRITE; +/*!40000 ALTER TABLE `gameobject_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `gameobject_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `instance_template` +-- + +DROP TABLE IF EXISTS `instance_template`; +CREATE TABLE `instance_template` ( + `map` smallint(5) unsigned NOT NULL, + `parent` int(10) unsigned NOT NULL, + `levelMin` tinyint(3) unsigned NOT NULL default '0', + `levelMax` tinyint(3) unsigned NOT NULL default '0', + `maxPlayers` tinyint(3) unsigned NOT NULL default '0', + `reset_delay` int(10) unsigned NOT NULL default '0', + `startLocX` float default NULL, + `startLocY` float default NULL, + `startLocZ` float default NULL, + `startLocO` float default NULL, + `script` varchar(128) NOT NULL default '', + PRIMARY KEY (`map`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `instance_template` +-- + +LOCK TABLES `instance_template` WRITE; +/*!40000 ALTER TABLE `instance_template` DISABLE KEYS */; +INSERT INTO `instance_template` VALUES +(33,0,22,30,10,7200,NULL,NULL,NULL,NULL,''), +(34,0,24,32,10,7200,NULL,NULL,NULL,NULL,''), +(36,0,15,20,10,7200,NULL,NULL,NULL,NULL,''), +(43,0,15,21,10,7200,NULL,NULL,NULL,NULL,''), +(47,0,29,38,10,7200,NULL,NULL,NULL,NULL,''), +(48,0,24,32,10,7200,NULL,NULL,NULL,NULL,''), +(70,0,35,47,10,7200,NULL,NULL,NULL,NULL,''), +(90,0,29,38,10,7200,NULL,NULL,NULL,NULL,''), +(109,0,45,55,10,7200,NULL,NULL,NULL,NULL,''), +(129,0,37,46,10,7200,NULL,NULL,NULL,NULL,''), +(189,0,34,45,10,7200,NULL,NULL,NULL,NULL,''), +(209,0,44,54,10,7200,NULL,NULL,NULL,NULL,''), +(229,0,58,0,10,120000,78.5083,-225.044,49.839,5.1,''), +(230,0,52,0,5,7200,NULL,NULL,NULL,NULL,''), +(249,0,60,0,40,432000,NULL,NULL,NULL,NULL,''), +(289,0,57,0,5,7200,NULL,NULL,NULL,NULL,''), +(309,0,60,0,20,259200,NULL,NULL,NULL,NULL,''), +(329,0,58,60,5,7200,NULL,NULL,NULL,NULL,''), +(349,0,46,55,10,7200,NULL,NULL,NULL,NULL,''), +(389,0,13,18,10,7200,NULL,NULL,NULL,NULL,''), +(409,0,60,0,40,604800,NULL,NULL,NULL,NULL,''), +(429,0,55,60,5,7200,NULL,NULL,NULL,NULL,''), +(469,0,60,0,40,604800,NULL,NULL,NULL,NULL,''), +(509,0,60,0,20,259200,NULL,NULL,NULL,NULL,''), +(531,0,60,0,40,604800,NULL,NULL,NULL,NULL,''), +(533,0,60,0,40,604800,NULL,NULL,NULL,NULL,''); +/*!40000 ALTER TABLE `instance_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `item_enchantment_template` +-- + +DROP TABLE IF EXISTS `item_enchantment_template`; +CREATE TABLE `item_enchantment_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `ench` mediumint(8) unsigned NOT NULL default '0', + `chance` float unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`ench`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item Random Enchantment System'; + +-- +-- Dumping data for table `item_enchantment_template` +-- + +LOCK TABLES `item_enchantment_template` WRITE; +/*!40000 ALTER TABLE `item_enchantment_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_enchantment_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `item_loot_template` +-- + +DROP TABLE IF EXISTS `item_loot_template`; +CREATE TABLE `item_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `item_loot_template` +-- + +LOCK TABLES `item_loot_template` WRITE; +/*!40000 ALTER TABLE `item_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `item_template` +-- + +DROP TABLE IF EXISTS `item_template`; +CREATE TABLE `item_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `subclass` tinyint(3) unsigned NOT NULL default '0', + `unk0` int(11) NOT NULL default '-1', + `name` varchar(255) NOT NULL default '', + `displayid` mediumint(8) unsigned NOT NULL default '0', + `Quality` tinyint(3) unsigned NOT NULL default '0', + `Flags` int(10) unsigned NOT NULL default '0', + `BuyCount` tinyint(3) unsigned NOT NULL default '1', + `BuyPrice` int(10) unsigned NOT NULL default '0', + `SellPrice` int(10) unsigned NOT NULL default '0', + `InventoryType` tinyint(3) unsigned NOT NULL default '0', + `AllowableClass` mediumint(9) NOT NULL default '-1', + `AllowableRace` mediumint(9) NOT NULL default '-1', + `ItemLevel` tinyint(3) unsigned NOT NULL default '0', + `RequiredLevel` tinyint(3) unsigned NOT NULL default '0', + `RequiredSkill` smallint(5) unsigned NOT NULL default '0', + `RequiredSkillRank` smallint(5) unsigned NOT NULL default '0', + `requiredspell` mediumint(8) unsigned NOT NULL default '0', + `requiredhonorrank` mediumint(8) unsigned NOT NULL default '0', + `RequiredCityRank` mediumint(8) unsigned NOT NULL default '0', + `RequiredReputationFaction` smallint(5) unsigned NOT NULL default '0', + `RequiredReputationRank` smallint(5) unsigned NOT NULL default '0', + `maxcount` smallint(5) unsigned NOT NULL default '0', + `stackable` smallint(5) unsigned NOT NULL default '1', + `ContainerSlots` tinyint(3) unsigned NOT NULL default '0', + `stat_type1` tinyint(3) unsigned NOT NULL default '0', + `stat_value1` smallint(6) NOT NULL default '0', + `stat_type2` tinyint(3) unsigned NOT NULL default '0', + `stat_value2` smallint(6) NOT NULL default '0', + `stat_type3` tinyint(3) unsigned NOT NULL default '0', + `stat_value3` smallint(6) NOT NULL default '0', + `stat_type4` tinyint(3) unsigned NOT NULL default '0', + `stat_value4` smallint(6) NOT NULL default '0', + `stat_type5` tinyint(3) unsigned NOT NULL default '0', + `stat_value5` smallint(6) NOT NULL default '0', + `stat_type6` tinyint(3) unsigned NOT NULL default '0', + `stat_value6` smallint(6) NOT NULL default '0', + `stat_type7` tinyint(3) unsigned NOT NULL default '0', + `stat_value7` smallint(6) NOT NULL default '0', + `stat_type8` tinyint(3) unsigned NOT NULL default '0', + `stat_value8` smallint(6) NOT NULL default '0', + `stat_type9` tinyint(3) unsigned NOT NULL default '0', + `stat_value9` smallint(6) NOT NULL default '0', + `stat_type10` tinyint(3) unsigned NOT NULL default '0', + `stat_value10` smallint(6) NOT NULL default '0', + `dmg_min1` float NOT NULL default '0', + `dmg_max1` float NOT NULL default '0', + `dmg_type1` tinyint(3) unsigned NOT NULL default '0', + `dmg_min2` float NOT NULL default '0', + `dmg_max2` float NOT NULL default '0', + `dmg_type2` tinyint(3) unsigned NOT NULL default '0', + `dmg_min3` float NOT NULL default '0', + `dmg_max3` float NOT NULL default '0', + `dmg_type3` tinyint(3) unsigned NOT NULL default '0', + `dmg_min4` float NOT NULL default '0', + `dmg_max4` float NOT NULL default '0', + `dmg_type4` tinyint(3) unsigned NOT NULL default '0', + `dmg_min5` float NOT NULL default '0', + `dmg_max5` float NOT NULL default '0', + `dmg_type5` tinyint(3) unsigned NOT NULL default '0', + `armor` smallint(5) unsigned NOT NULL default '0', + `holy_res` tinyint(3) unsigned NOT NULL default '0', + `fire_res` tinyint(3) unsigned NOT NULL default '0', + `nature_res` tinyint(3) unsigned NOT NULL default '0', + `frost_res` tinyint(3) unsigned NOT NULL default '0', + `shadow_res` tinyint(3) unsigned NOT NULL default '0', + `arcane_res` tinyint(3) unsigned NOT NULL default '0', + `delay` smallint(5) unsigned NOT NULL default '1000', + `ammo_type` tinyint(3) unsigned NOT NULL default '0', + `RangedModRange` float NOT NULL default '0', + `spellid_1` mediumint(8) unsigned NOT NULL default '0', + `spelltrigger_1` tinyint(3) unsigned NOT NULL default '0', + `spellcharges_1` tinyint(4) NOT NULL default '0', + `spellppmRate_1` float NOT NULL default '0', + `spellcooldown_1` int(11) NOT NULL default '-1', + `spellcategory_1` smallint(5) unsigned NOT NULL default '0', + `spellcategorycooldown_1` int(11) NOT NULL default '-1', + `spellid_2` mediumint(8) unsigned NOT NULL default '0', + `spelltrigger_2` tinyint(3) unsigned NOT NULL default '0', + `spellcharges_2` tinyint(4) NOT NULL default '0', + `spellppmRate_2` float NOT NULL default '0', + `spellcooldown_2` int(11) NOT NULL default '-1', + `spellcategory_2` smallint(5) unsigned NOT NULL default '0', + `spellcategorycooldown_2` int(11) NOT NULL default '-1', + `spellid_3` mediumint(8) unsigned NOT NULL default '0', + `spelltrigger_3` tinyint(3) unsigned NOT NULL default '0', + `spellcharges_3` tinyint(4) NOT NULL default '0', + `spellppmRate_3` float NOT NULL default '0', + `spellcooldown_3` int(11) NOT NULL default '-1', + `spellcategory_3` smallint(5) unsigned NOT NULL default '0', + `spellcategorycooldown_3` int(11) NOT NULL default '-1', + `spellid_4` mediumint(8) unsigned NOT NULL default '0', + `spelltrigger_4` tinyint(3) unsigned NOT NULL default '0', + `spellcharges_4` tinyint(4) NOT NULL default '0', + `spellppmRate_4` float NOT NULL default '0', + `spellcooldown_4` int(11) NOT NULL default '-1', + `spellcategory_4` smallint(5) unsigned NOT NULL default '0', + `spellcategorycooldown_4` int(11) NOT NULL default '-1', + `spellid_5` mediumint(8) unsigned NOT NULL default '0', + `spelltrigger_5` tinyint(3) unsigned NOT NULL default '0', + `spellcharges_5` tinyint(4) NOT NULL default '0', + `spellppmRate_5` float NOT NULL default '0', + `spellcooldown_5` int(11) NOT NULL default '-1', + `spellcategory_5` smallint(5) unsigned NOT NULL default '0', + `spellcategorycooldown_5` int(11) NOT NULL default '-1', + `bonding` tinyint(3) unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL default '', + `PageText` mediumint(8) unsigned NOT NULL default '0', + `LanguageID` tinyint(3) unsigned NOT NULL default '0', + `PageMaterial` tinyint(3) unsigned NOT NULL default '0', + `startquest` mediumint(8) unsigned NOT NULL default '0', + `lockid` mediumint(8) unsigned NOT NULL default '0', + `Material` tinyint(4) NOT NULL default '0', + `sheath` tinyint(3) unsigned NOT NULL default '0', + `RandomProperty` mediumint(8) unsigned NOT NULL default '0', + `RandomSuffix` mediumint(8) unsigned NOT NULL default '0', + `block` mediumint(8) unsigned NOT NULL default '0', + `itemset` mediumint(8) unsigned NOT NULL default '0', + `MaxDurability` smallint(5) unsigned NOT NULL default '0', + `area` mediumint(8) unsigned NOT NULL default '0', + `Map` smallint(6) NOT NULL default '0', + `BagFamily` mediumint(9) NOT NULL default '0', + `TotemCategory` tinyint(4) NOT NULL default '0', + `socketColor_1` tinyint(4) NOT NULL default '0', + `socketContent_1` mediumint(9) NOT NULL default '0', + `socketColor_2` tinyint(4) NOT NULL default '0', + `socketContent_2` mediumint(9) NOT NULL default '0', + `socketColor_3` tinyint(4) NOT NULL default '0', + `socketContent_3` mediumint(9) NOT NULL default '0', + `socketBonus` mediumint(9) NOT NULL default '0', + `GemProperties` mediumint(9) NOT NULL default '0', + `RequiredDisenchantSkill` smallint(6) NOT NULL default '-1', + `ArmorDamageModifier` float NOT NULL default '0', + `ScriptName` varchar(64) NOT NULL default '', + `DisenchantID` mediumint(8) unsigned NOT NULL default '0', + `FoodType` tinyint(3) unsigned NOT NULL default '0', + `minMoneyLoot` int(10) unsigned NOT NULL default '0', + `maxMoneyLoot` int(10) unsigned NOT NULL default '0', + `Duration` int(11) NOT NULL default '0' COMMENT 'Duration in seconds. Negative value means realtime, postive value ingame time', + PRIMARY KEY (`entry`), + KEY `items_index` (`class`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +-- +-- Dumping data for table `item_template` +-- + +LOCK TABLES `item_template` WRITE; +/*!40000 ALTER TABLE `item_template` DISABLE KEYS */; +INSERT INTO `item_template` VALUES +(25,2,7,-1,'Worn Shortsword',1542,1,0,1,35,7,21,32767,511,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1900,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,1,0,0,0,1,3,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(35,2,10,-1,'Bent Staff',472,1,0,1,47,9,17,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2900,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,2,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(36,2,4,-1,'Worn Mace',5194,1,0,1,38,7,21,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1900,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,3,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(37,2,0,-1,'Worn Axe',14029,1,0,1,38,7,21,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,3,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(38,4,0,-1,'Recruit\'s Shirt',9891,1,0,1,1,1,4,-1,-1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(39,4,1,-1,'Recruit\'s Pants',9892,0,0,1,5,1,7,32767,511,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(40,4,0,-1,'Recruit\'s Boots',10141,1,0,1,4,1,8,32767,511,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(43,4,0,-1,'Squire\'s Boots',9938,1,0,1,4,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(44,4,1,-1,'Squire\'s Pants',9937,0,0,1,4,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(45,4,0,-1,'Squire\'s Shirt',3265,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(47,4,0,-1,'Footpad\'s Shoes',9915,1,0,1,4,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(48,4,1,-1,'Footpad\'s Pants',9913,0,0,1,4,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(49,4,0,-1,'Footpad\'s Shirt',9906,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(51,4,0,-1,'Neophyte\'s Boots',9946,1,0,1,5,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(52,4,1,-1,'Neophyte\'s Pants',9945,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(53,4,0,-1,'Neophyte\'s Shirt',9944,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(55,4,0,-1,'Apprentice\'s Boots',9929,1,0,1,5,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(56,4,1,-1,'Apprentice\'s Robe',12647,0,0,1,5,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(57,4,1,-1,'Acolyte\'s Robe',12645,0,0,1,5,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(59,4,0,-1,'Acolyte\'s Shoes',3261,1,0,1,5,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(117,0,0,-1,'Tough Jerky',2473,1,0,6,25,1,0,2047,255,5,1,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,433,0,-1,0,-1,11,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(120,4,1,-1,'Thug Pants',10006,0,0,1,4,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(121,4,0,-1,'Thug Boots',10008,1,0,1,4,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(127,4,0,-1,'Trapper\'s Shirt',9996,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(139,4,1,-1,'Brawler\'s Pants',9988,0,0,1,4,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(140,4,0,-1,'Brawler\'s Boots',9992,1,0,1,4,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(147,4,1,-1,'Rugged Trapper\'s Pants',9975,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(148,4,0,-1,'Rugged Trapper\'s Shirt',9976,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(153,4,2,-1,'Primitive Kilt',10050,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,8,0,0,0,0,0,30,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(154,4,0,-1,'Primitive Mantle',10058,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(159,0,0,-1,'Refreshing Spring Water',18084,1,0,6,25,1,0,2047,255,5,1,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,430,0,-1,0,-1,59,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(1395,4,1,-1,'Apprentice\'s Pants',9924,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(1396,4,1,-1,'Acolyte\'s Pants',3260,0,0,1,4,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2070,0,0,-1,'Darnassian Bleu',6353,1,0,6,25,1,0,2047,255,5,1,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,433,0,-1,0,-1,11,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2092,2,15,-1,'Worn Dagger',6442,1,0,1,35,7,13,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1600,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,3,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2101,1,2,-1,'Light Quiver',21328,1,0,1,4,1,18,2047,255,1,1,0,0,0,0,0,0,0,0,1,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,14824,1,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2102,1,3,-1,'Small Ammo Pouch',1816,1,0,1,4,1,18,2047,255,1,1,0,0,0,0,0,0,0,0,1,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,14824,1,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2105,4,0,-1,'Thug Shirt',10005,1,0,1,5,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2361,2,5,-1,'Battleworn Hammer',8690,1,0,1,45,9,17,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2900,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,1,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2362,4,6,-1,'Worn Wooden Shield',18730,0,0,1,7,1,14,32767,511,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,4,0,0,1,0,20,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2504,2,2,-1,'Worn Shortbow',8106,1,0,1,29,5,15,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2300,2,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2508,2,3,-1,'Old Blunderbuss',6606,1,0,1,27,5,26,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2300,3,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2512,6,2,-1,'Rough Arrow',5996,1,0,1,10,0,24,2047,255,5,1,0,0,0,0,0,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2516,6,3,-1,'Light Shot',5998,1,0,1,10,0,24,2047,255,5,1,0,0,0,0,0,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(2947,2,16,-1,'Small Throwing Knife',16754,1,0,1,15,0,25,2047,255,3,1,0,0,0,0,0,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2000,4,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(3661,2,10,-1,'Handcrafted Staff',18530,1,0,1,45,9,17,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2900,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,2,2,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(4536,0,0,-1,'Shiny Red Apple',6410,1,0,6,25,1,0,2047,255,5,1,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,433,0,-1,0,-1,11,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(4540,0,0,-1,'Tough Hunk of Bread',6399,1,0,6,25,1,0,2047,255,5,1,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,433,0,-1,0,-1,11,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(4604,0,0,-1,'Forest Mushroom Cap',15852,1,0,6,25,1,0,2047,255,5,1,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,433,0,-1,0,-1,11,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6096,4,0,-1,'Apprentice\'s Shirt',2163,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6097,4,0,-1,'Acolyte\'s Shirt',2470,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6098,4,1,-1,'Neophyte\'s Robe',12679,0,0,1,4,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6119,4,1,-1,'Neophyte\'s Robe',12681,0,0,1,4,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6123,4,1,-1,'Novice\'s Robe',12683,0,0,1,4,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6124,4,1,-1,'Novice\'s Pants',9987,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6125,4,0,-1,'Brawler\'s Harness',9995,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6126,4,1,-1,'Trapper\'s Pants',10002,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6127,4,0,-1,'Trapper\'s Boots',10003,1,0,1,5,1,8,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6129,4,1,-1,'Acolyte\'s Robe',12646,0,0,1,5,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6134,4,0,-1,'Primitive Mantle',10108,1,0,1,1,1,4,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6135,4,2,-1,'Primitive Kilt',10109,0,0,1,5,1,7,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,8,0,0,0,0,0,30,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6139,4,1,-1,'Novice\'s Robe',12684,0,0,1,4,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6140,4,1,-1,'Apprentice\'s Robe',12649,0,0,1,4,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6144,4,1,-1,'Neophyte\'s Robe',12680,0,0,1,5,1,20,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,7,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(6948,15,0,-1,'Hearthstone',6418,1,64,1,0,0,0,32767,511,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8690,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,'',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(12282,2,1,-1,'Worn Battleaxe',22291,1,0,1,43,8,17,2047,255,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2900,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,1,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(14646,12,0,-1,'Northshire Gift Voucher',18499,1,0,1,0,0,0,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,'',0,0,0,5805,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(14647,12,0,-1,'Coldridge Valley Gift Voucher',18499,1,0,1,0,0,0,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,'',0,0,0,5841,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(14648,12,0,-1,'Shadowglen Gift Voucher',18499,1,0,1,0,0,0,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,'',0,0,0,5842,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(14649,12,0,-1,'Valley of Trials Gift Voucher',18499,1,0,1,0,0,0,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,'',0,0,0,5843,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(14650,12,0,-1,'Camp Narache Gift Voucher',18499,1,0,1,0,0,0,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,'',0,0,0,5844,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(14651,12,0,-1,'Deathknell Gift Voucher',18499,1,0,1,0,0,0,2047,255,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,'',0,0,0,5847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0), +(25861,2,16,-1,'Crude Throwing Axe',20777,1,0,1,15,0,25,2047,255,3,1,0,0,0,0,0,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2000,4,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,'internalItemHandler',0,0,0,0,0); +/*!40000 ALTER TABLE `item_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `locales_creature` +-- + +DROP TABLE IF EXISTS `locales_creature`; +CREATE TABLE `locales_creature` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `name_loc1` varchar(100) NOT NULL default '', + `name_loc2` varchar(100) NOT NULL default '', + `name_loc3` varchar(100) NOT NULL default '', + `name_loc4` varchar(100) NOT NULL default '', + `name_loc5` varchar(100) NOT NULL default '', + `name_loc6` varchar(100) NOT NULL default '', + `name_loc7` varchar(100) NOT NULL default '', + `name_loc8` varchar(100) NOT NULL default '', + `subname_loc1` varchar(100) default NULL, + `subname_loc2` varchar(100) default NULL, + `subname_loc3` varchar(100) default NULL, + `subname_loc4` varchar(100) default NULL, + `subname_loc5` varchar(100) default NULL, + `subname_loc6` varchar(100) default NULL, + `subname_loc7` varchar(100) default NULL, + `subname_loc8` varchar(100) default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_creature` +-- + +LOCK TABLES `locales_creature` WRITE; +/*!40000 ALTER TABLE `locales_creature` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_creature` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `locales_gameobject` +-- + +DROP TABLE IF EXISTS `locales_gameobject`; +CREATE TABLE `locales_gameobject` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `name_loc1` varchar(100) NOT NULL default '', + `name_loc2` varchar(100) NOT NULL default '', + `name_loc3` varchar(100) NOT NULL default '', + `name_loc4` varchar(100) NOT NULL default '', + `name_loc5` varchar(100) NOT NULL default '', + `name_loc6` varchar(100) NOT NULL default '', + `name_loc7` varchar(100) NOT NULL default '', + `name_loc8` varchar(100) NOT NULL default '', + `castbarcaption_loc1` varchar(100) NOT NULL default '', + `castbarcaption_loc2` varchar(100) NOT NULL default '', + `castbarcaption_loc3` varchar(100) NOT NULL default '', + `castbarcaption_loc4` varchar(100) NOT NULL default '', + `castbarcaption_loc5` varchar(100) NOT NULL default '', + `castbarcaption_loc6` varchar(100) NOT NULL default '', + `castbarcaption_loc7` varchar(100) NOT NULL default '', + `castbarcaption_loc8` varchar(100) NOT NULL default '', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_gameobject` +-- + +LOCK TABLES `locales_gameobject` WRITE; +/*!40000 ALTER TABLE `locales_gameobject` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_gameobject` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `locales_item` +-- + +DROP TABLE IF EXISTS `locales_item`; +CREATE TABLE `locales_item` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `name_loc1` varchar(100) NOT NULL default '', + `name_loc2` varchar(100) NOT NULL default '', + `name_loc3` varchar(100) NOT NULL default '', + `name_loc4` varchar(100) NOT NULL default '', + `name_loc5` varchar(100) NOT NULL default '', + `name_loc6` varchar(100) NOT NULL default '', + `name_loc7` varchar(100) NOT NULL default '', + `name_loc8` varchar(100) NOT NULL default '', + `description_loc1` varchar(255) default NULL, + `description_loc2` varchar(255) default NULL, + `description_loc3` varchar(255) default NULL, + `description_loc4` varchar(255) default NULL, + `description_loc5` varchar(255) default NULL, + `description_loc6` varchar(255) default NULL, + `description_loc7` varchar(255) default NULL, + `description_loc8` varchar(255) default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_item` +-- + +LOCK TABLES `locales_item` WRITE; +/*!40000 ALTER TABLE `locales_item` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_item` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `locales_npc_text` +-- + +DROP TABLE IF EXISTS `locales_npc_text`; +CREATE TABLE `locales_npc_text` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `Text0_0_loc1` longtext, + `Text0_0_loc2` longtext, + `Text0_0_loc3` longtext, + `Text0_0_loc4` longtext, + `Text0_0_loc5` longtext, + `Text0_0_loc6` longtext, + `Text0_0_loc7` longtext, + `Text0_0_loc8` longtext, + `Text0_1_loc1` longtext, + `Text0_1_loc2` longtext, + `Text0_1_loc3` longtext, + `Text0_1_loc4` longtext, + `Text0_1_loc5` longtext, + `Text0_1_loc6` longtext, + `Text0_1_loc7` longtext, + `Text0_1_loc8` longtext, + `Text1_0_loc1` longtext, + `Text1_0_loc2` longtext, + `Text1_0_loc3` longtext, + `Text1_0_loc4` longtext, + `Text1_0_loc5` longtext, + `Text1_0_loc6` longtext, + `Text1_0_loc7` longtext, + `Text1_0_loc8` longtext, + `Text1_1_loc1` longtext, + `Text1_1_loc2` longtext, + `Text1_1_loc3` longtext, + `Text1_1_loc4` longtext, + `Text1_1_loc5` longtext, + `Text1_1_loc6` longtext, + `Text1_1_loc7` longtext, + `Text1_1_loc8` longtext, + `Text2_0_loc1` longtext, + `Text2_0_loc2` longtext, + `Text2_0_loc3` longtext, + `Text2_0_loc4` longtext, + `Text2_0_loc5` longtext, + `Text2_0_loc6` longtext, + `Text2_0_loc7` longtext, + `Text2_0_loc8` longtext, + `Text2_1_loc1` longtext, + `Text2_1_loc2` longtext, + `Text2_1_loc3` longtext, + `Text2_1_loc4` longtext, + `Text2_1_loc5` longtext, + `Text2_1_loc6` longtext, + `Text2_1_loc7` longtext, + `Text2_1_loc8` longtext, + `Text3_0_loc1` longtext, + `Text3_0_loc2` longtext, + `Text3_0_loc3` longtext, + `Text3_0_loc4` longtext, + `Text3_0_loc5` longtext, + `Text3_0_loc6` longtext, + `Text3_0_loc7` longtext, + `Text3_0_loc8` longtext, + `Text3_1_loc1` longtext, + `Text3_1_loc2` longtext, + `Text3_1_loc3` longtext, + `Text3_1_loc4` longtext, + `Text3_1_loc5` longtext, + `Text3_1_loc6` longtext, + `Text3_1_loc7` longtext, + `Text3_1_loc8` longtext, + `Text4_0_loc1` longtext, + `Text4_0_loc2` longtext, + `Text4_0_loc3` longtext, + `Text4_0_loc4` longtext, + `Text4_0_loc5` longtext, + `Text4_0_loc6` longtext, + `Text4_0_loc7` longtext, + `Text4_0_loc8` longtext, + `Text4_1_loc1` longtext, + `Text4_1_loc2` longtext, + `Text4_1_loc3` longtext, + `Text4_1_loc4` longtext, + `Text4_1_loc5` longtext, + `Text4_1_loc6` longtext, + `Text4_1_loc7` longtext, + `Text4_1_loc8` longtext, + `Text5_0_loc1` longtext, + `Text5_0_loc2` longtext, + `Text5_0_loc3` longtext, + `Text5_0_loc4` longtext, + `Text5_0_loc5` longtext, + `Text5_0_loc6` longtext, + `Text5_0_loc7` longtext, + `Text5_0_loc8` longtext, + `Text5_1_loc1` longtext, + `Text5_1_loc2` longtext, + `Text5_1_loc3` longtext, + `Text5_1_loc4` longtext, + `Text5_1_loc5` longtext, + `Text5_1_loc6` longtext, + `Text5_1_loc7` longtext, + `Text5_1_loc8` longtext, + `Text6_0_loc1` longtext, + `Text6_0_loc2` longtext, + `Text6_0_loc3` longtext, + `Text6_0_loc4` longtext, + `Text6_0_loc5` longtext, + `Text6_0_loc6` longtext, + `Text6_0_loc7` longtext, + `Text6_0_loc8` longtext, + `Text6_1_loc1` longtext, + `Text6_1_loc2` longtext, + `Text6_1_loc3` longtext, + `Text6_1_loc4` longtext, + `Text6_1_loc5` longtext, + `Text6_1_loc6` longtext, + `Text6_1_loc7` longtext, + `Text6_1_loc8` longtext, + `Text7_0_loc1` longtext, + `Text7_0_loc2` longtext, + `Text7_0_loc3` longtext, + `Text7_0_loc4` longtext, + `Text7_0_loc5` longtext, + `Text7_0_loc6` longtext, + `Text7_0_loc7` longtext, + `Text7_0_loc8` longtext, + `Text7_1_loc1` longtext, + `Text7_1_loc2` longtext, + `Text7_1_loc3` longtext, + `Text7_1_loc4` longtext, + `Text7_1_loc5` longtext, + `Text7_1_loc6` longtext, + `Text7_1_loc7` longtext, + `Text7_1_loc8` longtext, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_npc_text` +-- + +LOCK TABLES `locales_npc_text` WRITE; +/*!40000 ALTER TABLE `locales_npc_text` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_npc_text` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `locales_page_text` +-- + +DROP TABLE IF EXISTS `locales_page_text`; +CREATE TABLE `locales_page_text` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `Text_loc1` longtext, + `Text_loc2` longtext, + `Text_loc3` longtext, + `Text_loc4` longtext, + `Text_loc5` longtext, + `Text_loc6` longtext, + `Text_loc7` longtext, + `Text_loc8` longtext, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_page_text` +-- + +LOCK TABLES `locales_page_text` WRITE; +/*!40000 ALTER TABLE `locales_page_text` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_page_text` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `locales_quest` +-- + +DROP TABLE IF EXISTS `locales_quest`; +CREATE TABLE `locales_quest` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `Title_loc1` text, + `Title_loc2` text, + `Title_loc3` text, + `Title_loc4` text, + `Title_loc5` text, + `Title_loc6` text, + `Title_loc7` text, + `Title_loc8` text, + `Details_loc1` text, + `Details_loc2` text, + `Details_loc3` text, + `Details_loc4` text, + `Details_loc5` text, + `Details_loc6` text, + `Details_loc7` text, + `Details_loc8` text, + `Objectives_loc1` text, + `Objectives_loc2` text, + `Objectives_loc3` text, + `Objectives_loc4` text, + `Objectives_loc5` text, + `Objectives_loc6` text, + `Objectives_loc7` text, + `Objectives_loc8` text, + `OfferRewardText_loc1` text, + `OfferRewardText_loc2` text, + `OfferRewardText_loc3` text, + `OfferRewardText_loc4` text, + `OfferRewardText_loc5` text, + `OfferRewardText_loc6` text, + `OfferRewardText_loc7` text, + `OfferRewardText_loc8` text, + `RequestItemsText_loc1` text, + `RequestItemsText_loc2` text, + `RequestItemsText_loc3` text, + `RequestItemsText_loc4` text, + `RequestItemsText_loc5` text, + `RequestItemsText_loc6` text, + `RequestItemsText_loc7` text, + `RequestItemsText_loc8` text, + `EndText_loc1` text, + `EndText_loc2` text, + `EndText_loc3` text, + `EndText_loc4` text, + `EndText_loc5` text, + `EndText_loc6` text, + `EndText_loc7` text, + `EndText_loc8` text, + `ObjectiveText1_loc1` text, + `ObjectiveText1_loc2` text, + `ObjectiveText1_loc3` text, + `ObjectiveText1_loc4` text, + `ObjectiveText1_loc5` text, + `ObjectiveText1_loc6` text, + `ObjectiveText1_loc7` text, + `ObjectiveText1_loc8` text, + `ObjectiveText2_loc1` text, + `ObjectiveText2_loc2` text, + `ObjectiveText2_loc3` text, + `ObjectiveText2_loc4` text, + `ObjectiveText2_loc5` text, + `ObjectiveText2_loc6` text, + `ObjectiveText2_loc7` text, + `ObjectiveText2_loc8` text, + `ObjectiveText3_loc1` text, + `ObjectiveText3_loc2` text, + `ObjectiveText3_loc3` text, + `ObjectiveText3_loc4` text, + `ObjectiveText3_loc5` text, + `ObjectiveText3_loc6` text, + `ObjectiveText3_loc7` text, + `ObjectiveText3_loc8` text, + `ObjectiveText4_loc1` text, + `ObjectiveText4_loc2` text, + `ObjectiveText4_loc3` text, + `ObjectiveText4_loc4` text, + `ObjectiveText4_loc5` text, + `ObjectiveText4_loc6` text, + `ObjectiveText4_loc7` text, + `ObjectiveText4_loc8` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_quest` +-- + +LOCK TABLES `locales_quest` WRITE; +/*!40000 ALTER TABLE `locales_quest` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_quest` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `mangos_string` +-- + +DROP TABLE IF EXISTS `mangos_string`; +CREATE TABLE `mangos_string` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `content_default` text NOT NULL, + `content_loc1` text, + `content_loc2` text, + `content_loc3` text, + `content_loc4` text, + `content_loc5` text, + `content_loc6` text, + `content_loc7` text, + `content_loc8` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `mangos_string` +-- + +LOCK TABLES `mangos_string` WRITE; +/*!40000 ALTER TABLE `mangos_string` DISABLE KEYS */; +INSERT INTO `mangos_string` VALUES +(1,'You should select a character or a creature.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(2,'You should select a creature.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(3,'|cffff0000[System Message]: %s|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(4,'|cffff0000[Event Message]: %s|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(5,'There is no help for that command',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(6,'There is no such command',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(7,'There is no such subcommand',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(8,'Command %s have subcommands:%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(9,'Commands available to you:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(10,'Incorrect syntax.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(11,'Your account level is: %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(12,'Online players: %u (max: %u) Queued players: %u (max: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(13,'Server uptime: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(14,'Player saved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(15,'All players saved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(16,'There are the following active GMs on this server:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(17,'There are no GMs currently logged in on this server.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(18,'Cannot do that while flying.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(19,'Cannot do that in Battlegrounds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(20,'Target is flying you can\'t do that.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(21,'%s is flying command failed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(22,'You are not mounted so you can\'t dismount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(23,'Cannot do that while fighting.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(24,'You used it recently.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(25,'Your password can\'t be longer than 16 characters (client limit), password not changed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(26,'The password was changed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(27,'The new passwords do not match or the old password is wrong',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(28,'Your account is now locked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(29,'Your account is now unlocked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(30,', rank ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(31,' [known]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(32,' [learn]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(33,' [passive]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(34,' [talent]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(35,' [active]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(36,' [complete]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(37,' (offline)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(38,'on',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(39,'off',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(40,'You are: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(41,'visible',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(42,'invisible',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(43,'done',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(44,'You',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(45,' ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(46,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(47,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(48,'UNKNOWN',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(49,'You must be at least level %u to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(50,'You must be at least level %u and have item %s to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(51,'Hello! Ready for some training?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(52,'Invaid item count (%u) for item %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(53,'Mail can\'t have more %u item stacks',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(100,'Global notify: ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f\ngrid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(102,'%s is already being teleported.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(103,'You can summon a player to your instance only if he is in your party with you as leader.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(104,'You cannot go to the player\'s instance because you are in a party now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(105,'You can go to the player\'s instance while not being in his party only if your GM mode is on.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(106,'You can not go to player %s from instance to instance.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(107,'You can not summon player %s from instance to instance.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(108,'You are summoning %s%s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(109,'You are being summoned by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(110,'You are teleporting %s%s to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(111,'You are being teleported by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(112,'Player (%s) does not exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(113,'Appearing at %s\'s location.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(114,'%s is appearing to your location.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(115,'Incorrect values.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(116,'No character selected.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(117,'%s is not in a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(118,'You changed HP of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(119,'%s changed your HP to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(120,'You changed MANA of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(121,'%s changed your MANA to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(122,'You changed ENERGY of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(123,'%s changed your ENERGY to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(124,'Current energy: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(125,'You changed rage of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(126,'%s changed your rage to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(127,'You changed level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(128,'GUID %i, faction is %i, flags is %i, npcflag is %i, DY flag is %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(129,'Wrong faction: %u (not found in factiontemplate.dbc).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(130,'You changed GUID=%i \'s Faction to %i, flags to %i, npcflag to %i, dyflag to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(131,'You changed the spellflatid=%i, val= %i, mark =%i to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(132,'%s changed your spellflatid=%i, val= %i, mark =%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(133,'%s has access to all taxi nodes now (until logout).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(134,'%s has no more access to all taxi nodes now (only visited accessible).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(135,'%s has given you access to all taxi nodes (until logout).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(136,'%s has removed access to all taxi nodes (only visited still accessible).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(137,'You set all speeds to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(138,'%s set all your speeds to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(139,'You set the speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(140,'%s set your speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(141,'You set the swim speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(142,'%s set your swim speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(143,'You set the backwards run speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(144,'%s set your backwards run speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(145,'You set the fly speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(146,'%s set your fly speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(147,'You set the size %2.2f of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(148,'%s set your size to %2.2f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(149,'There is no such mount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(150,'You give a mount to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(151,'%s gave you a mount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(152,'USER1: %i, ADD: %i, DIF: %i\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(153,'You take all copper of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(154,'%s took you all of your copper.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(155,'You take %i copper from %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(156,'%s took %i copper from you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(157,'You give %i copper to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(158,'%s gave you %i copper.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(159,'You hear sound %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(160,'USER2: %i, ADD: %i, RESULT: %i\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(161,'Removed bit %i in field %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(162,'Set bit %i in field %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(163,'Teleport location table is empty!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(164,'Teleport location not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(165,'Requires search parameter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(166,'There are no teleport locations matching your request.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(168,'Locations found are:\n %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(169,'Mail sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(170,'You try to hear sound %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(200,'No selection.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(201,'Object GUID is: lowpart %u highpart %X',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(202,'The name was too long by %i characters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(203,'Error, name can only contain characters A-Z and a-z.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(204,'The subname was too long by %i characters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(205,'Not yet implemented',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(206,'Item \'%i\' \'%s\' added to list with maxcount \'%i\' and incrtime \'%i\' and extendedcost \'%i\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(207,'Item \'%i\' not found in database.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(208,'Item \'%i\' \'%s\' deleted from vendor list',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(209,'Item \'%i\' not found in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(210,'Item \'%i\' already in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(211,'Spells of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(212,'Spells of %s will reset at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(213,'Talents of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(214,'Talents of %s will reset at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(215,'Your spells have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(216,'Your talents have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(217,'Unknown case \'%s\' for .resetall command. Type full correct case name.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(218,'Spells will reset for all players at login. Strongly recommend re-login!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(219,'Talents will reset for all players at login. Strongly recommend re-login!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(220,'Creature (GUID: %u) No waypoint found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(221,'Creature (GUID: %u) Last waypoint not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(222,'Creature (GUID: %u) No waypoint found - used \'wpguid\'. Now trying to find it by its position...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(223,'Creature (GUID: %u) No waypoints found - This is a MaNGOS db problem (single float).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(224,'Selected creature is ignored - provided GUID is used',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(225,'Creature (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(226,'You must select a visual waypoint.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(227,'No visual waypoints found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(228,'Could not create visual waypoint with creatureID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(229,'All visual waypoints removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(230,'Could not create waypoint-creature with ID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(231,'No GUID provided.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(232,'No waypoint number provided.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(233,'Argument required for \'%s\'.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(234,'Waypoint %i added to GUID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(235,'Waypoint %d added.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(236,'Waypoint changed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(237,'Waypoint %s modified.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(238,'WP export successfull.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(239,'No waypoints found inside the database.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(240,'File imported.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(241,'Waypoint removed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(242,'Warning: Could not delete WP from the world with ID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(243,'This happens if the waypoint is too far away from your char.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(244,'The WP is deleted from the database, but not from the world here.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(245,'They will disappear after a server restart.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(246,'Waypoint %d: Info for creature: %s, GUID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(247,'Waittime: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(248,'Model %d: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(249,'Emote: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(250,'Spell: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(251,'Text %d: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(252,'AIScript: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(253,'Forced rename for player %s will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(254,'Forced rename for player %s (GUID #%u) will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(255,'Waypoint-Creature (GUID: %u) Not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(256,'Could not find NPC...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(257,'Creature movement type set to \'%s\', waypoints removed (if any).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(258,'Creature movement type set to \'%s\', waypoints were not removed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(259,'Incorrect value, use on or off',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(260,'Value saved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(261,'Value saved, you may need to rejoin or clean your client cache.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(262,'Areatrigger ID %u not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(263,'Target map or coordinates is invalid (X: %f Y: %f MapId: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(264,'Zone coordinates is invalid (X: %f Y: %f AreaId: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(265,'Zone %u (%s) is part of instanceable map %u (%s)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(266,'Nothing found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(267,'Object not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(268,'Creature not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(269,'Warning: Mob found more than once - you will be teleported to the first one found in DB.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(270,'Creature Removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(271,'Creature moved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(272,'Creature (GUID:%u) must be on the same map as player!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(273,'Game Object (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(274,'Game Object (GUID: %u) has references in not found creature %u GO list, can\'t be deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(275,'Game Object (GUID: %u) removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(276,'Game Object (GUID: %u) turned',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(277,'Game Object (GUID: %u) moved',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(278,'You must select a vendor',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(279,'You must send id for item',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(283,'Player %s not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(287,'Creature (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(288,'Tickets count: %i show new tickets: %s\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(289,'New ticket from %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(290,'Ticket of %s (Last updated: %s):\n%s ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(291,'New ticket show: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(292,'New ticket show: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(293,'Ticket %i doesn\'t exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(294,'All tickets deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(295,'Character %s ticket deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(296,'Ticket deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(297,'Spawn distance changed to: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(298,'Spawn time changed to: %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(299,'The honor of %s was set to %u!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(300,'Your chat has been disabled for %u minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(301,'You have disabled %s\'s chat for %u minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(302,'Player\'s chat is already enabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(303,'Your chat has been enabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(304,'You have enabled %s\'s chat.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(305, 'Faction %s (%u) reputation of %s was set to %5d!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(306, 'The arena points of %s was set to %u!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(307, 'No faction found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(308, 'Faction %i unknown!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(309, 'Invalid parameter %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(310, 'delta must be between 0 and %d (inclusive)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(311, '%d - |cffffffff|Hfaction:%d|h[%s]|h|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(312, ' [visible]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(313, ' [at war]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(314, ' [peace forced]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(315, ' [hidden]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(316, ' [invisible forced]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(317, ' [inactive]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(318, 'Hated',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(319, 'Hostile',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(320, 'Unfriendly',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(321, 'Neutral',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(322, 'Friendly',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(323, 'Honored',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(324, 'Revered',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(325, 'Exalted',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(326, 'Faction %s (%u) can\'not have reputation.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(327, ' [no reputation]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(328,'Characters at account %s (Id: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(329,' %s (GUID %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(330,'No players found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(331,'Extended item cost %u not exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(332,'GM mode is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(333,'GM mode is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(334,'GM Chat Badge is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(335,'GM Chat Badge is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(401,'You change security level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(403,'You have low security level for this.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(404,'Creature movement disabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(405,'Creature movement enabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(406,'Weather can\'t be changed for this zone.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(407,'Weather system disabled at server.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(408,'%s is banned for %s. Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(409,'%s is banned permanently for %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(410,'%s %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(411,'%s unbanned.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(412,'There was an error removing the ban on %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(413,'There is no such account.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(414,'There is no such character.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(415,'There is no such IP in banlist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(416,'Account %s has never been banned',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(417,'Ban history for account %s:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(418,'Ban Date: %s Bantime: %s Still active: %s Reason: %s Set by: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(419,'Inf.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(420,'Never',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(421,'Yes',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(422,'No',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(423,'IP: %s\nBan Date: %s\nUnban Date: %s\nRemaining: %s\nReason: %s\nSet by: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(424,'There is no matching IPban.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(425,'There is no matching account.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(426,'There is no banned account owning a character matching this part.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(427,'The following IPs match your pattern:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(428,'The following accounts match your query:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(429,'You learned many spells/skills.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(430,'You learned all spells for class.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(431,'You learned all talents for class.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(432,'You learned all languages.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(433,'You learned all craft skills and recipes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(434,'Could not find \'%s\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(435,'Invalid item id: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(436,'No items found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(437,'Invalid gameobject id: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(438,'Found items %u: %u ( inventory %u mail %u auction %u )',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(439,'Found gameobjects %u: %u ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(440,'Invalid creature id: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(441,'Found creatures %u: %u ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(442,'No area found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(443,'No item sets found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(444,'No skills found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(445,'No spells found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(446,'No quests found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(447,'No creatures found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(448,'No gameobjects found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(449,'Graveyard #%u doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(450,'Graveyard #%u already linked to zone #%u (current).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(451,'Graveyard #%u linked to zone #%u (current).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(452,'Graveyard #%u can\'t be linked to subzone or not existed zone #%u (internal error).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(453,'Graveyard can be linked to zone at another map only for all factions (no faction value).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(454,'No faction in Graveyard with id= #%u , fix your DB',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(455,'invalid team, please fix database',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(456,'any',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(457,'alliance',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(458,'horde',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(459,'Graveyard #%u (faction: %s) is nearest from linked to zone #%u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(460,'Zone #%u doesn\'t have linked graveyards.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(461,'Zone #%u doesn\'t have linked graveyards for faction: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(462,'Teleport location already exists!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(463,'Teleport location added.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(464,'Teleport location NOT added: database error.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(465,'Teleport location deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(467,'Target unit has %d auras:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(468,'id: %d eff: %d type: %d duration: %d maxduration: %d name: %s%s%s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(469,'Target unit has %d auras of type %d:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(470,'id: %d eff: %d name: %s%s%s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(471,'Quest %u not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(472,'Quest %u started from item. For correct work, please, add item to inventory and start quest in normal way: .additem %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(473,'Quest removed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(474,' [rewarded]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(475,' [complete]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(476,' [active]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(477,'%s\'s Fly Mode %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(478,'Opcode %u sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(479,'Character loaded successfully!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(480,'Failed to load the character!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(481,'Character dumped successfully!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(482,'Character dump failed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(483,'Spell %u broken and not allowed to cast or learn!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(484,'Skill %u (%s) for player %s set to %u and current maximum set to %u (without permanent (talent) bonuses).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(485,'Player %s must have skill %u (%s) before using this command.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(486,'Invalid skill id (%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(487,'You learned default GM spells/skills.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(488,'You already know that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(489,'Target(%s) already know that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(490,'%s doesn\'t know that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(491,'You already forgot that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(492,'All spell cooldowns removed for %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(493,'Spell %u cooldown removed for %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(494,'Command : Additem, itemId = %i, amount = %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(495,'Command : Additemset, itemsetId = %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(496,'Removed itemID = %i, amount = %i from %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(497,'Cannot create item \'%i\' (amount: %i)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(498,'You need to provide a guild name!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(499,'Player not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(500,'Player already has a guild!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(501,'Guild not created! (already exists?)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(502,'No items from itemset \'%u\' found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(503,'The distance is: (3D) %f (2D) %f yards.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(504,'Item \'%i\' \'%s\' Item Slot %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(505,'Item \'%i\' doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(506,'Item \'%i\' \'%s\' Added to Slot %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(507,'Item save failed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(508,'%d - owner: %s (guid: %u account: %u ) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(509,'%d - sender: %s (guid: %u account: %u ) receiver: %s (guid: %u account: %u ) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(510,'%d - owner: %s (guid: %u account: %u ) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(511,'Wrong link type!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(512,'%d - |cffffffff|Hitem:%d:0:0:0:0:0:0:0|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(513,'%d - |cffffffff|Hquest:%d|h[%s]|h|r %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(514,'%d - |cffffffff|Hcreature_entry:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(515,'%d - |cffffffff|Hcreature:%d|h[%s X:%f Y:%f Z:%f MapId:%d]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(516,'%d - |cffffffff|Hgameobject_entry:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(517,'%d - |cffffffff|Hgameobject:%d|h[%s X:%f Y:%f Z:%f MapId:%d]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(518,'%d - |cffffffff|Hitemset:%d|h[%s %s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(519,'|cffffffff|Htele:%s|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(520,'%d - |cffffffff|Hspell:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(521,'%d - |cffffffff|Hskill:%d|h[%s %s]|h|r %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(522,'Game Object (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(523,'>> Game Object %s (GUID: %u) at %f %f %f. Orientation %f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(524,'Selected object:\n|cffffffff|Hitemset:%d|h[%s]|h|r\nGUID: %u ID: %u\nX: %f Y: %f Z: %f MapId: %u\nOrientation: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(525,'>> Add Game Object \'%i\' (%s) (GUID: %i) added at \'%f %f %f\'.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(526,'%s (lowguid: %u) movement generators stack:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(527,' Idle',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(528,' Random',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(529,' Waypoint',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(530,' Animal random',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(531,' Confused',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(532,' Targeted to player %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(533,' Targeted to creature %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(534,' Targeted to ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(535,' Home movement to (X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(536,' Home movement used for player?!?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(537,' Taxi flight',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(538,' Unknown movement generator (%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(539,'Player selected NPC\nGUID: %u.\nFaction: %u.\nnpcFlags: %u.\nEntry: %u.\nDisplayID: %u (Native: %u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(540,'Level: %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(541,'Health (base): %u. (max): %u. (current): %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(542,'Field Flags: %u.\nDynamic Flags: %u.\nFaction Template: %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(543,'Loot: %u Pickpocket: %u Skinning: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(544,'Position: %f %f %f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(545,'*** Is a vendor!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(546,'*** Is a trainer!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(547,'InstanceID: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(548,'Player%s %s (guid: %u) Account: %s (id: %u) GMLevel: %u Last IP: %s Last login: %s Latency: %ums',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(549,'Played time: %s Level: %u Money: %ug%us%uc',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(550,'Command .pinfo doesn\'t support \'rep\' option for offline players.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(551,'%s has explored all zones now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(552,'%s has no more explored zones.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(553,'%s has explored all zones for you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(554,'%s has hidden all zones from you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(555,'Hover enabled',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(556,'Hover disabled',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(557,'You have been leveled up (%i)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(558,'You have been leveled down (%i)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(559,'Your level progress has been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(560,'The area has been set as explored.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(561,'The area has been set as not explored.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(562,'GUID=%i \'s updateIndex: %i, value: %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(563,'You change GUID=%i \'s UpdateIndex: %i value to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(564,'The value index %u is too big to %u(count: %u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(565,'Set %u uint32 Value:[OPCODE]:%u [VALUE]:%u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(566,'You Set %u Field:%u to uint32 Value: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(567,'Set %u float Value:[OPCODE]:%u [VALUE]:%f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(568,'You Set %u Field:%i to float Value: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(569,'Get %u uint32 Value:[OPCODE]:%u [VALUE]:%u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(570,'The uint32 value of %u in %u is: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(571,'Get %u float Value:[OPCODE]:%u [VALUE]:%f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(572,'The float of %u value in %u is: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(573,'.Set32Bit:[OPCODE]:%u [VALUE]:%u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(574,'You set Bit of Field:%u to Value: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(575,'.Mod32Value:[OPCODE]:%u [VALUE]:%i',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(576,'You modified the value of Field:%u to Value: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(577,'You are now invisible.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(578,'You are now visible.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(579,'Selected player or creature not have victim.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(580,'You learned all default spells for race/class and completed quests rewarded spells.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(581,'Found near gameobjects (distance %f): %u ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(582,'SpawnTime: Full:%s Remain:%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(583,'%d - |cffffffff|Hgameevent:%d|h[%s]|h|r%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(584,'No event found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(585,'Event not exist!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(586,'Event %u: %s%s\nStart: %s End: %s Occurence: %s Length: %s\nNext state change: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(587,'Event %u already active!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(588,'Event %u not active!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(589,' Point movement to (X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(590,' Fear movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(591,' Distract movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(592,'You have learned all spells in craft: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(600,'The Alliance wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(601,'The Horde wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(602,'The battle for Warsong Gulch begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(603,'The battle for Warsong Gulch begins in 30 seconds. Prepare yourselves!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(604,'Let the battle for Warsong Gulch begin!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(605,'$n captured the Horde flag!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(606,'$n captured the Alliance flag!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(607,'The Horde flag was dropped by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(608,'The Alliance Flag was dropped by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(609,'The Alliance Flag was returned to its base by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(610,'The Horde flag was returned to its base by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(611,'The Horde flag was picked up by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(612,'The Alliance Flag was picked up by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(613,'The flags are now placed at their bases.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(636,'The Battle for Eye of the Storm begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(637,'The Battle for Eye of the Storm begins in 30 seconds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(638,'The Battle for Eye of the Storm has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(650,'Alliance',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(651,'Horde',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(652,'stables',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(653,'blacksmith',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(654,'farm',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(655,'lumber mill',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(656,'mine',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(657,'The %s has taken the %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(658,'$n has defended the %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(659,'$n has assaulted the %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(660,'$n claims the %s! If left unchallenged, the %s will control it in 1 minute!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(661,'The Battle for Arathi Basin begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(662,'The Battle for Arathi Basin begins in 30 seconds. Prepare yourselves!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(663,'The Battle for Arathi Basin has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(664,'The Alliance has gathered $1776W resources, and is near victory!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(665,'The Horde has gathered $1777W resources, and is near victory!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(666,'After your recent battle in %s our best attempts to award you a Mark of Honor failed. Enclosed you will find the Mark of Honor we were not able to deliver to you at the time. Thanks for fighting in %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(700,'You must be level %u to form an arena team',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(701,'One minute until the Arena battle begins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(702,'Thirty seconds until the Arena battle begins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(703,'Fifteen seconds until the Arena battle begins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(704,'The Arena battle has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(705,'You must wait %s before speaking again.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(706,'This item(s) have problems with equipping/storing in inventory.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(707,'%s wishes to not be disturbed and cannot receive whisper messages: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(708,'%s is Away from Keyboard: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(709,'Do not Disturb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(710,'Away from Keyboard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(711,'Queue status for %s (Lvl: %u to %u)\nQueued alliances: %u (Need at least %u more)\nQueued hordes: %u (Need at least %u more)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(712,'|cffff0000[BG Queue Announcer]:|r %s -- [%u-%u] A: %u (Need: %u), H: %u (Needs %u)|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(713,'You must be level %u to join an arena team!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(714,'%s is not high enough level to join your team',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(715,'You don\'t meet Battleground level requirements',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(716,'Your arena team is full, %s cannot join it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(801,'You do not have enough gold',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(802,'You do not have enough free slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(803,'Your partner does not have enough free bag slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(804,'You do not have permission to perform that function',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(805,'Unknown language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(806,'You don\'t know that language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(807,'Please provide character name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(808,'Player %s not found or offline',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `npc_gossip` +-- + +DROP TABLE IF EXISTS `npc_gossip`; +CREATE TABLE `npc_gossip` ( + `npc_guid` int(10) unsigned NOT NULL default '0', + `textid` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`npc_guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `npc_gossip` +-- + +LOCK TABLES `npc_gossip` WRITE; +/*!40000 ALTER TABLE `npc_gossip` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_gossip` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `npc_gossip_textid` +-- + +DROP TABLE IF EXISTS `npc_gossip_textid`; +CREATE TABLE `npc_gossip_textid` ( + `zoneid` smallint(5) unsigned NOT NULL default '0', + `action` smallint(5) unsigned NOT NULL default '0', + `textid` mediumint(8) unsigned NOT NULL default '0', + KEY `zoneid` (`zoneid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `npc_gossip_textid` +-- + +LOCK TABLES `npc_gossip_textid` WRITE; +/*!40000 ALTER TABLE `npc_gossip_textid` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_gossip_textid` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `npc_option` +-- + +DROP TABLE IF EXISTS `npc_option`; +CREATE TABLE `npc_option` ( + `id` tinyint(3) unsigned NOT NULL default '0', + `gossip_id` tinyint(3) unsigned NOT NULL default '0', + `npcflag` int(10) unsigned NOT NULL default '0', + `icon` tinyint(3) unsigned NOT NULL default '0', + `action` tinyint(3) unsigned NOT NULL default '0', + `option_text` text, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `npc_option` +-- + +LOCK TABLES `npc_option` WRITE; +/*!40000 ALTER TABLE `npc_option` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_option` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `npc_text` +-- + +DROP TABLE IF EXISTS `npc_text`; +CREATE TABLE `npc_text` ( + `ID` mediumint(8) unsigned NOT NULL default '0', + `text0_0` longtext, + `text0_1` longtext, + `lang0` tinyint(3) unsigned NOT NULL default '0', + `prob0` float NOT NULL default '0', + `em0_0` smallint(5) unsigned NOT NULL default '0', + `em0_1` smallint(5) unsigned NOT NULL default '0', + `em0_2` smallint(5) unsigned NOT NULL default '0', + `em0_3` smallint(5) unsigned NOT NULL default '0', + `em0_4` smallint(5) unsigned NOT NULL default '0', + `em0_5` smallint(5) unsigned NOT NULL default '0', + `text1_0` longtext, + `text1_1` longtext, + `lang1` tinyint(3) unsigned NOT NULL default '0', + `prob1` float NOT NULL default '0', + `em1_0` smallint(5) unsigned NOT NULL default '0', + `em1_1` smallint(5) unsigned NOT NULL default '0', + `em1_2` smallint(5) unsigned NOT NULL default '0', + `em1_3` smallint(5) unsigned NOT NULL default '0', + `em1_4` smallint(5) unsigned NOT NULL default '0', + `em1_5` smallint(5) unsigned NOT NULL default '0', + `text2_0` longtext, + `text2_1` longtext, + `lang2` tinyint(3) unsigned NOT NULL default '0', + `prob2` float NOT NULL default '0', + `em2_0` smallint(5) unsigned NOT NULL default '0', + `em2_1` smallint(5) unsigned NOT NULL default '0', + `em2_2` smallint(5) unsigned NOT NULL default '0', + `em2_3` smallint(5) unsigned NOT NULL default '0', + `em2_4` smallint(5) unsigned NOT NULL default '0', + `em2_5` smallint(5) unsigned NOT NULL default '0', + `text3_0` longtext, + `text3_1` longtext, + `lang3` tinyint(3) unsigned NOT NULL default '0', + `prob3` float NOT NULL default '0', + `em3_0` smallint(5) unsigned NOT NULL default '0', + `em3_1` smallint(5) unsigned NOT NULL default '0', + `em3_2` smallint(5) unsigned NOT NULL default '0', + `em3_3` smallint(5) unsigned NOT NULL default '0', + `em3_4` smallint(5) unsigned NOT NULL default '0', + `em3_5` smallint(5) unsigned NOT NULL default '0', + `text4_0` longtext, + `text4_1` longtext, + `lang4` tinyint(3) unsigned NOT NULL default '0', + `prob4` float NOT NULL default '0', + `em4_0` smallint(5) unsigned NOT NULL default '0', + `em4_1` smallint(5) unsigned NOT NULL default '0', + `em4_2` smallint(5) unsigned NOT NULL default '0', + `em4_3` smallint(5) unsigned NOT NULL default '0', + `em4_4` smallint(5) unsigned NOT NULL default '0', + `em4_5` smallint(5) unsigned NOT NULL default '0', + `text5_0` longtext, + `text5_1` longtext, + `lang5` tinyint(3) unsigned NOT NULL default '0', + `prob5` float NOT NULL default '0', + `em5_0` smallint(5) unsigned NOT NULL default '0', + `em5_1` smallint(5) unsigned NOT NULL default '0', + `em5_2` smallint(5) unsigned NOT NULL default '0', + `em5_3` smallint(5) unsigned NOT NULL default '0', + `em5_4` smallint(5) unsigned NOT NULL default '0', + `em5_5` smallint(5) unsigned NOT NULL default '0', + `text6_0` longtext, + `text6_1` longtext, + `lang6` tinyint(3) unsigned NOT NULL default '0', + `prob6` float NOT NULL default '0', + `em6_0` smallint(5) unsigned NOT NULL default '0', + `em6_1` smallint(5) unsigned NOT NULL default '0', + `em6_2` smallint(5) unsigned NOT NULL default '0', + `em6_3` smallint(5) unsigned NOT NULL default '0', + `em6_4` smallint(5) unsigned NOT NULL default '0', + `em6_5` smallint(5) unsigned NOT NULL default '0', + `text7_0` longtext, + `text7_1` longtext, + `lang7` tinyint(3) unsigned NOT NULL default '0', + `prob7` float NOT NULL default '0', + `em7_0` smallint(5) unsigned NOT NULL default '0', + `em7_1` smallint(5) unsigned NOT NULL default '0', + `em7_2` smallint(5) unsigned NOT NULL default '0', + `em7_3` smallint(5) unsigned NOT NULL default '0', + `em7_4` smallint(5) unsigned NOT NULL default '0', + `em7_5` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `npc_text` +-- + +LOCK TABLES `npc_text` WRITE; +/*!40000 ALTER TABLE `npc_text` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_text` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `npc_trainer` +-- + +DROP TABLE IF EXISTS `npc_trainer`; +CREATE TABLE `npc_trainer` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `spell` mediumint(8) unsigned NOT NULL default '0', + `spellcost` int(10) unsigned NOT NULL default '0', + `reqskill` smallint(5) unsigned NOT NULL default '0', + `reqskillvalue` smallint(5) unsigned NOT NULL default '0', + `reqlevel` tinyint(3) unsigned NOT NULL default '0', + UNIQUE KEY `entry_spell` (`entry`,`spell`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `npc_trainer` +-- + +LOCK TABLES `npc_trainer` WRITE; +/*!40000 ALTER TABLE `npc_trainer` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_trainer` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `npc_vendor` +-- + +DROP TABLE IF EXISTS `npc_vendor`; +CREATE TABLE `npc_vendor` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `maxcount` tinyint(3) unsigned NOT NULL default '0', + `incrtime` int(10) unsigned NOT NULL default '0', + `ExtendedCost` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Npc System'; + +-- +-- Dumping data for table `npc_vendor` +-- + +LOCK TABLES `npc_vendor` WRITE; +/*!40000 ALTER TABLE `npc_vendor` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_vendor` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `page_text` +-- + +DROP TABLE IF EXISTS `page_text`; +CREATE TABLE `page_text` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `text` longtext NOT NULL, + `next_page` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +-- +-- Dumping data for table `page_text` +-- + +LOCK TABLES `page_text` WRITE; +/*!40000 ALTER TABLE `page_text` DISABLE KEYS */; +/*!40000 ALTER TABLE `page_text` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `pet_levelstats` +-- + +DROP TABLE IF EXISTS `pet_levelstats`; +CREATE TABLE `pet_levelstats` ( + `creature_entry` mediumint(8) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `hp` smallint(5) unsigned NOT NULL, + `mana` smallint(5) unsigned NOT NULL, + `armor` int(10) unsigned NOT NULL default '0', + `str` smallint(5) unsigned NOT NULL, + `agi` smallint(5) unsigned NOT NULL, + `sta` smallint(5) unsigned NOT NULL, + `inte` smallint(5) unsigned NOT NULL, + `spi` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`creature_entry`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores pet levels stats.'; + +-- +-- Dumping data for table `pet_levelstats` +-- + +LOCK TABLES `pet_levelstats` WRITE; +/*!40000 ALTER TABLE `pet_levelstats` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_levelstats` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `pet_name_generation` +-- + +DROP TABLE IF EXISTS `pet_name_generation`; +CREATE TABLE `pet_name_generation` ( + `id` mediumint(8) unsigned NOT NULL auto_increment, + `word` tinytext NOT NULL, + `entry` mediumint(8) unsigned NOT NULL default '0', + `half` tinyint(4) NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `pet_name_generation` +-- + +LOCK TABLES `pet_name_generation` WRITE; +/*!40000 ALTER TABLE `pet_name_generation` DISABLE KEYS */; +INSERT INTO `pet_name_generation` (`word`,`entry`,`half`) VALUES +('Aba',416,0), +('Az',416,0), +('Bel',416,0), +('Biz',416,0), +('Cho',416,0), +('Dag',416,0), +('Gak',416,0), +('Gar',416,0), +('Gel',416,0), +('Gho',416,0), +('Gob',416,0), +('Gra',416,0), +('Jak',416,0), +('Jub',416,0), +('Kar',416,0), +('Kup',416,0), +('Laz',416,0), +('Nal',416,0), +('Nok',416,0), +('Pag',416,0), +('Pig',416,0), +('Pip',416,0), +('Piz',416,0), +('Quz',416,0), +('Rui',416,0), +('Rul',416,0), +('Rup',416,0), +('Tar',416,0), +('Vol',416,0), +('Yaz',416,0), +('Zep',416,0), +('Zig',416,0), +('Zil',416,0), +('Zor',416,0), +('bis',416,1), +('fip',416,1), +('gup',416,1), +('ham',416,1), +('jub',416,1), +('kin',416,1), +('kol',416,1), +('lop',416,1), +('loz',416,1), +('mat',416,1), +('mir',416,1), +('nam',416,1), +('nar',416,1), +('nik',416,1), +('nip',416,1), +('pad',416,1), +('pep',416,1), +('pit',416,1), +('qua',416,1), +('rai',416,1), +('rin',416,1), +('rot',416,1), +('tai',416,1), +('tal',416,1), +('tik',416,1), +('tip',416,1), +('tog',416,1), +('tuk',416,1), +('uri',416,1), +('yal',416,1), +('yap',416,1), +('Bhee',417,0), +('Bruu',417,0), +('Czaa',417,0), +('Droo',417,0), +('Flaa',417,0), +('Fzuu',417,0), +('Ghaa',417,0), +('Gree',417,0), +('Gzaa',417,0), +('Haa',417,0), +('Haad',417,0), +('Haag',417,0), +('Haap',417,0), +('Jhaa',417,0), +('Jhuu',417,0), +('Khaa',417,0), +('Khii',417,0), +('Khuu',417,0), +('Kree',417,0), +('Luu',417,0), +('Maa',417,0), +('Nhee',417,0), +('Phuu',417,0), +('Pryy',417,0), +('Rhuu',417,0), +('Shaa',417,0), +('Sloo',417,0), +('Sruu',417,0), +('Thoo',417,0), +('Traa',417,0), +('Wraa',417,0), +('Zhaa',417,0), +('dhon',417,1), +('dhum',417,1), +('dhun',417,1), +('dom',417,1), +('don',417,1), +('drom',417,1), +('dym',417,1), +('fenn',417,1), +('fum',417,1), +('fun',417,1), +('ghon',417,1), +('ghun',417,1), +('grom',417,1), +('grym',417,1), +('hom',417,1), +('hon',417,1), +('hun',417,1), +('jhom',417,1), +('kun',417,1), +('lum',417,1), +('mmon',417,1), +('mon',417,1), +('myn',417,1), +('nam',417,1), +('nem',417,1), +('nhym',417,1), +('nom',417,1), +('num',417,1), +('phom',417,1), +('roon',417,1), +('rym',417,1), +('shon',417,1), +('thun',417,1), +('tom',417,1), +('zhem',417,1), +('zhum',417,1), +('zun',417,1), +('Bar',1860,0), +('Bel',1860,0), +('Char',1860,0), +('Grak\'',1860,0), +('Graz\'',1860,0), +('Grim',1860,0), +('Hath',1860,0), +('Hel',1860,0), +('Hok',1860,0), +('Huk',1860,0), +('Jhaz',1860,0), +('Jhom',1860,0), +('Juk\'',1860,0), +('Kal\'',1860,0), +('Klath',1860,0), +('Kon',1860,0), +('Krag',1860,0), +('Krak',1860,0), +('Mak',1860,0), +('Mezz',1860,0), +('Orm',1860,0), +('Phan',1860,0), +('Sar',1860,0), +('Tang',1860,0), +('Than',1860,0), +('Thog',1860,0), +('Thok',1860,0), +('Thul',1860,0), +('Zag\'',1860,0), +('Zang',1860,0), +('Zhar\'',1860,0), +('kath',1860,1), +('doc',1860,1), +('dok',1860,1), +('gak',1860,1), +('garth',1860,1), +('gore',1860,1), +('gorg',1860,1), +('grave',1860,1), +('gron',1860,1), +('juk',1860,1), +('krast',1860,1), +('kresh',1860,1), +('krit',1860,1), +('los',1860,1), +('mon',1860,1), +('mos',1860,1), +('moth',1860,1), +('nagma',1860,1), +('nak',1860,1), +('nar',1860,1), +('nos',1860,1), +('nuz',1860,1), +('phog',1860,1), +('rath',1860,1), +('tast',1860,1), +('taz',1860,1), +('thak',1860,1), +('thang',1860,1), +('thyk',1860,1), +('vhug',1860,1), +('zazt',1860,1), +('Ael',1863,0), +('Aez',1863,0), +('Ang',1863,0), +('Ban',1863,0), +('Bet',1863,0), +('Bro',1863,0), +('Bry',1863,0), +('Cat',1863,0), +('Dir',1863,0), +('Dis',1863,0), +('Dom',1863,0), +('Drus',1863,0), +('Fie',1863,0), +('Fier',1863,0), +('Gly',1863,0), +('Hel',1863,0), +('Hes',1863,0), +('Kal',1863,0), +('Lyn',1863,0), +('Mir',1863,0), +('Nim',1863,0), +('Sar',1863,0), +('Sel',1863,0), +('Vil',1863,0), +('Zah',1863,0), +('aith',1863,1), +('anda',1863,1), +('antia',1863,1), +('evere',1863,1), +('lia',1863,1), +('lissa',1863,1), +('neri',1863,1), +('neth',1863,1), +('nia',1863,1), +('nlissa',1863,1), +('nora',1863,1), +('nva',1863,1), +('nys',1863,1), +('ola',1863,1), +('ona',1863,1), +('ora',1863,1), +('rah',1863,1), +('riana',1863,1), +('riel',1863,1), +('rona',1863,1), +('tai',1863,1), +('tevere',1863,1), +('thea',1863,1), +('vina',1863,1), +('wena',1863,1), +('wyn',1863,1), +('xia',1863,1), +('yla',1863,1), +('yssa',1863,1), +('Flaa',17252,0), +('Haa',17252,0), +('Jhuu',17252,0), +('Shaa',17252,0), +('Thoo',17252,0), +('dhun',17252,1), +('ghun',17252,1), +('roon',17252,1), +('thun',17252,1), +('tom',17252,1); + +/*!40000 ALTER TABLE `pet_name_generation` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `petcreateinfo_spell` +-- + +DROP TABLE IF EXISTS `petcreateinfo_spell`; +CREATE TABLE `petcreateinfo_spell` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `Spell1` mediumint(8) unsigned NOT NULL default '0', + `Spell2` mediumint(8) unsigned NOT NULL default '0', + `Spell3` mediumint(8) unsigned NOT NULL default '0', + `Spell4` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet Create Spells'; + +-- +-- Dumping data for table `petcreateinfo_spell` +-- + +LOCK TABLES `petcreateinfo_spell` WRITE; +/*!40000 ALTER TABLE `petcreateinfo_spell` DISABLE KEYS */; +/*!40000 ALTER TABLE `petcreateinfo_spell` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `pickpocketing_loot_template` +-- + +DROP TABLE IF EXISTS `pickpocketing_loot_template`; +CREATE TABLE `pickpocketing_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `pickpocketing_loot_template` +-- + +LOCK TABLES `pickpocketing_loot_template` WRITE; +/*!40000 ALTER TABLE `pickpocketing_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `pickpocketing_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `player_classlevelstats` +-- + +DROP TABLE IF EXISTS `player_classlevelstats`; +CREATE TABLE `player_classlevelstats` ( + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `basehp` smallint(5) unsigned NOT NULL, + `basemana` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +-- +-- Dumping data for table `player_classlevelstats` +-- + +LOCK TABLES `player_classlevelstats` WRITE; +/*!40000 ALTER TABLE `player_classlevelstats` DISABLE KEYS */; +INSERT INTO `player_classlevelstats` VALUES +(1,1,20,0), +(1,2,29,0), +(1,3,38,0), +(1,4,47,0), +(1,5,56,0), +(1,6,65,0), +(1,7,74,0), +(1,8,83,0), +(1,9,92,0), +(1,10,101,0), +(1,11,100,0), +(1,12,109,0), +(1,13,118,0), +(1,14,128,0), +(1,15,139,0), +(1,16,151,0), +(1,17,154,0), +(1,18,168,0), +(1,19,183,0), +(1,20,199,0), +(1,21,206,0), +(1,22,224,0), +(1,23,243,0), +(1,24,253,0), +(1,25,274,0), +(1,26,296,0), +(1,27,309,0), +(1,28,333,0), +(1,29,348,0), +(1,30,374,0), +(1,31,401,0), +(1,32,419,0), +(1,33,448,0), +(1,34,468,0), +(1,35,499,0), +(1,36,521,0), +(1,37,545,0), +(1,38,581,0), +(1,39,609,0), +(1,40,649,0), +(1,41,681,0), +(1,42,715,0), +(1,43,761,0), +(1,44,799,0), +(1,45,839,0), +(1,46,881,0), +(1,47,935,0), +(1,48,981,0), +(1,49,1029,0), +(1,50,1079,0), +(1,51,1131,0), +(1,52,1185,0), +(1,53,1241,0), +(1,54,1299,0), +(1,55,1359,0), +(1,56,1421,0), +(1,57,1485,0), +(1,58,1551,0), +(1,59,1619,0), +(1,60,1689,0), +(1,61,1902,0), +(1,62,2129,0), +(1,63,2357,0), +(1,64,2612,0), +(1,65,2883,0), +(1,66,3169,0), +(1,67,3455,0), +(1,68,3774,0), +(1,69,4109,0), +(1,70,4444,0), +(2,1,28,60), +(2,2,36,78), +(2,3,44,98), +(2,4,52,104), +(2,5,60,111), +(2,6,68,134), +(2,7,76,143), +(2,8,84,153), +(2,9,92,179), +(2,10,100,192), +(2,11,108,205), +(2,12,116,219), +(2,13,124,249), +(2,14,132,265), +(2,15,131,282), +(2,16,141,315), +(2,17,152,334), +(2,18,164,354), +(2,19,177,390), +(2,20,191,412), +(2,21,206,435), +(2,22,222,459), +(2,23,239,499), +(2,24,247,525), +(2,25,266,552), +(2,26,286,579), +(2,27,307,621), +(2,28,329,648), +(2,29,342,675), +(2,30,366,702), +(2,31,391,729), +(2,32,407,756), +(2,33,434,798), +(2,34,462,825), +(2,35,481,852), +(2,36,511,879), +(2,37,542,906), +(2,38,564,933), +(2,39,597,960), +(2,40,621,987), +(2,41,656,1014), +(2,42,682,1041), +(2,43,719,1068), +(2,44,747,1110), +(2,45,786,1137), +(2,46,816,1164), +(2,47,857,1176), +(2,48,889,1203), +(2,49,922,1230), +(2,50,966,1257), +(2,51,1001,1284), +(2,52,1037,1311), +(2,53,1084,1338), +(2,54,1122,1365), +(2,55,1161,1392), +(2,56,1201,1419), +(2,57,1252,1446), +(2,58,1294,1458), +(2,59,1337,1485), +(2,60,1381,1512), +(2,61,1540,1656), +(2,62,1708,1800), +(2,63,1884,1944), +(2,64,2068,2088), +(2,65,2262,2232), +(2,66,2466,2377), +(2,67,2679,2521), +(2,68,2901,2665), +(2,69,3134,2809), +(2,70,3377,2953), +(3,1,46,65), +(3,2,53,70), +(3,3,60,76), +(3,4,67,98), +(3,5,74,106), +(3,6,81,130), +(3,7,88,140), +(3,8,95,166), +(3,9,102,193), +(3,10,109,206), +(3,11,116,235), +(3,12,123,250), +(3,13,130,266), +(3,14,138,298), +(3,15,147,316), +(3,16,157,350), +(3,17,168,370), +(3,18,180,391), +(3,19,193,428), +(3,20,207,451), +(3,21,222,475), +(3,22,238,515), +(3,23,255,541), +(3,24,273,568), +(3,25,292,611), +(3,26,312,640), +(3,27,333,670), +(3,28,355,715), +(3,29,378,745), +(3,30,402,775), +(3,31,417,805), +(3,32,443,850), +(3,33,470,880), +(3,34,498,910), +(3,35,527,940), +(3,36,547,970), +(3,37,578,1015), +(3,38,610,1045), +(3,39,643,1075), +(3,40,667,1105), +(3,41,702,1135), +(3,42,738,1180), +(3,43,775,1210), +(3,44,803,1240), +(3,45,842,1270), +(3,46,872,1300), +(3,47,913,1330), +(3,48,955,1360), +(3,49,994,1390), +(3,50,1047,1420), +(3,51,1067,1450), +(3,52,1113,1480), +(3,53,1150,1510), +(3,54,1198,1540), +(3,55,1237,1570), +(3,56,1287,1600), +(3,57,1328,1630), +(3,58,1370,1660), +(3,59,1423,1690), +(3,60,1467,1720), +(3,61,1633,1886), +(3,62,1819,2053), +(3,63,2003,2219), +(3,64,2195,2385), +(3,65,2397,2552), +(3,66,2623,2718), +(3,67,2844,2884), +(3,68,3075,3050), +(3,69,3316,3217), +(3,70,3568,3383), +(4,1,25,0), +(4,2,32,0), +(4,3,49,0), +(4,4,56,0), +(4,5,63,0), +(4,6,70,0), +(4,7,87,0), +(4,8,94,0), +(4,9,101,0), +(4,10,118,0), +(4,11,125,0), +(4,12,142,0), +(4,13,149,0), +(4,14,156,0), +(4,15,173,0), +(4,16,181,0), +(4,17,190,0), +(4,18,200,0), +(4,19,221,0), +(4,20,233,0), +(4,21,246,0), +(4,22,260,0), +(4,23,275,0), +(4,24,301,0), +(4,25,318,0), +(4,26,336,0), +(4,27,355,0), +(4,28,375,0), +(4,29,396,0), +(4,30,428,0), +(4,31,451,0), +(4,32,475,0), +(4,33,500,0), +(4,34,526,0), +(4,35,553,0), +(4,36,581,0), +(4,37,610,0), +(4,38,640,0), +(4,39,671,0), +(4,40,703,0), +(4,41,736,0), +(4,42,770,0), +(4,43,805,0), +(4,44,841,0), +(4,45,878,0), +(4,46,916,0), +(4,47,955,0), +(4,48,995,0), +(4,49,1026,0), +(4,50,1068,0), +(4,51,1111,0), +(4,52,1155,0), +(4,53,1200,0), +(4,54,1246,0), +(4,55,1283,0), +(4,56,1331,0), +(4,57,1380,0), +(4,58,1430,0), +(4,59,1471,0), +(4,60,1523,0), +(4,61,1702,0), +(4,62,1879,0), +(4,63,2077,0), +(4,64,2285,0), +(4,65,2489,0), +(4,66,2717,0), +(4,67,2941,0), +(4,68,3190,0), +(4,69,3450,0), +(4,70,3704,0), +(5,1,52,73), +(5,2,57,76), +(5,3,72,95), +(5,4,77,114), +(5,5,92,133), +(5,6,97,152), +(5,7,112,171), +(5,8,117,190), +(5,9,132,209), +(5,10,137,212), +(5,11,142,215), +(5,12,157,234), +(5,13,172,254), +(5,14,177,260), +(5,15,192,282), +(5,16,197,305), +(5,17,212,329), +(5,18,227,339), +(5,19,232,365), +(5,20,247,377), +(5,21,252,405), +(5,22,268,434), +(5,23,275,449), +(5,24,293,480), +(5,25,302,497), +(5,26,322,530), +(5,27,343,549), +(5,28,355,584), +(5,29,378,605), +(5,30,392,627), +(5,31,417,665), +(5,32,433,689), +(5,33,460,728), +(5,34,478,752), +(5,35,507,776), +(5,36,527,800), +(5,37,548,839), +(5,38,580,863), +(5,39,603,887), +(5,40,637,911), +(5,41,662,950), +(5,42,698,974), +(5,43,725,998), +(5,44,763,1022), +(5,45,792,1046), +(5,46,822,1070), +(5,47,863,1094), +(5,48,895,1118), +(5,49,928,1142), +(5,50,972,1166), +(5,51,1007,1190), +(5,52,1053,1214), +(5,53,1090,1238), +(5,54,1128,1262), +(5,55,1177,1271), +(5,56,1217,1295), +(5,57,1258,1319), +(5,58,1300,1343), +(5,59,1353,1352), +(5,60,1397,1376), +(5,61,1557,1500), +(5,62,1738,1625), +(5,63,1916,1749), +(5,64,2101,1873), +(5,65,2295,1998), +(5,66,2495,2122), +(5,67,2719,2247), +(5,68,2936,2371), +(5,69,3160,2495), +(5,70,3391,2620), +(7,1,37,85), +(7,2,44,91), +(7,3,51,98), +(7,4,58,106), +(7,5,65,115), +(7,6,72,125), +(7,7,79,136), +(7,8,86,148), +(7,9,93,161), +(7,10,100,175), +(7,11,107,190), +(7,12,114,206), +(7,13,121,223), +(7,14,128,241), +(7,15,135,260), +(7,16,142,280), +(7,17,150,301), +(7,18,159,323), +(7,19,169,346), +(7,20,180,370), +(7,21,192,395), +(7,22,205,421), +(7,23,219,448), +(7,24,234,476), +(7,25,240,505), +(7,26,257,535), +(7,27,275,566), +(7,28,294,598), +(7,29,314,631), +(7,30,335,665), +(7,31,347,699), +(7,32,370,733), +(7,33,394,767), +(7,34,419,786), +(7,35,435,820), +(7,36,462,854), +(7,37,490,888), +(7,38,509,922), +(7,39,539,941), +(7,40,570,975), +(7,41,592,1009), +(7,42,625,1028), +(7,43,649,1062), +(7,44,684,1096), +(7,45,710,1115), +(7,46,747,1149), +(7,47,775,1183), +(7,48,814,1202), +(7,49,844,1236), +(7,50,885,1255), +(7,51,917,1289), +(7,52,960,1323), +(7,53,994,1342), +(7,54,1029,1376), +(7,55,1075,1395), +(7,56,1112,1414), +(7,57,1150,1448), +(7,58,1199,1467), +(7,59,1239,1501), +(7,60,1330,1520), +(7,61,1428,1664), +(7,62,1583,1808), +(7,63,1760,1951), +(7,64,1932,2095), +(7,65,2114,2239), +(7,66,2304,2383), +(7,67,2504,2527), +(7,68,2713,2670), +(7,69,2931,2814), +(7,70,3159,2958), +(8,1,32,100), +(8,2,47,110), +(8,3,52,106), +(8,4,67,118), +(8,5,82,131), +(8,6,97,130), +(8,7,102,145), +(8,8,117,146), +(8,9,132,163), +(8,10,137,196), +(8,11,152,215), +(8,12,167,220), +(8,13,172,241), +(8,14,187,263), +(8,15,202,271), +(8,16,207,295), +(8,17,222,305), +(8,18,237,331), +(8,19,242,343), +(8,20,257,371), +(8,21,272,385), +(8,22,277,415), +(8,23,292,431), +(8,24,298,463), +(8,25,315,481), +(8,26,333,515), +(8,27,342,535), +(8,28,362,556), +(8,29,373,592), +(8,30,395,613), +(8,31,418,634), +(8,32,432,670), +(8,33,457,691), +(8,34,473,712), +(8,35,500,733), +(8,36,518,754), +(8,37,547,790), +(8,38,577,811), +(8,39,598,832), +(8,40,630,853), +(8,41,653,874), +(8,42,687,895), +(8,43,712,916), +(8,44,748,937), +(8,45,775,958), +(8,46,813,979), +(8,47,842,1000), +(8,48,882,1021), +(8,49,913,1042), +(8,50,955,1048), +(8,51,988,1069), +(8,52,1032,1090), +(8,53,1067,1111), +(8,54,1103,1117), +(8,55,1150,1138), +(8,56,1188,1159), +(8,57,1237,1165), +(8,58,1277,1186), +(8,59,1328,1192), +(8,60,1370,1213), +(8,61,1526,1316), +(8,62,1702,1419), +(8,63,1875,1521), +(8,64,2070,1624), +(8,65,2261,1727), +(8,66,2461,1830), +(8,67,2686,1932), +(8,68,2906,2035), +(8,69,3136,2138), +(8,70,3393,2241), +(9,1,23,90), +(9,2,28,98), +(9,3,43,107), +(9,4,48,102), +(9,5,63,113), +(9,6,68,126), +(9,7,83,144), +(9,8,88,162), +(9,9,93,180), +(9,10,108,198), +(9,11,123,200), +(9,12,128,218), +(9,13,143,237), +(9,14,148,257), +(9,15,153,278), +(9,16,168,300), +(9,17,173,308), +(9,18,189,332), +(9,19,196,357), +(9,20,204,383), +(9,21,223,395), +(9,22,233,423), +(9,23,244,452), +(9,24,266,467), +(9,25,279,498), +(9,26,293,530), +(9,27,318,548), +(9,28,334,582), +(9,29,351,602), +(9,30,379,638), +(9,31,398,674), +(9,32,418,695), +(9,33,439,731), +(9,34,471,752), +(9,35,494,788), +(9,36,518,809), +(9,37,543,830), +(9,38,569,866), +(9,39,606,887), +(9,40,634,923), +(9,41,663,944), +(9,42,693,965), +(9,43,724,1001), +(9,44,756,1022), +(9,45,799,1043), +(9,46,832,1064), +(9,47,868,1100), +(9,48,904,1121), +(9,49,941,1142), +(9,50,979,1163), +(9,51,1018,1184), +(9,52,1058,1205), +(9,53,1099,1226), +(9,54,1141,1247), +(9,55,1184,1268), +(9,56,1228,1289), +(9,57,1273,1310), +(9,58,1319,1331), +(9,59,1366,1352), +(9,60,1414,1373), +(9,61,1580,1497), +(9,62,1755,1621), +(9,63,1939,1745), +(9,64,2133,1870), +(9,65,2323,1994), +(9,66,2535,2118), +(9,67,2758,2242), +(9,68,2991,2366), +(9,69,3235,2490), +(9,70,3490,2615), +(11,1,44,60), +(11,2,51,66), +(11,3,58,73), +(11,4,75,81), +(11,5,82,90), +(11,6,89,100), +(11,7,106,111), +(11,8,113,123), +(11,9,120,136), +(11,10,137,150), +(11,11,144,165), +(11,12,151,182), +(11,13,168,200), +(11,14,175,219), +(11,15,182,239), +(11,16,199,260), +(11,17,206,282), +(11,18,214,305), +(11,19,233,329), +(11,20,243,354), +(11,21,254,380), +(11,22,266,392), +(11,23,289,420), +(11,24,303,449), +(11,25,318,479), +(11,26,334,509), +(11,27,361,524), +(11,28,379,554), +(11,29,398,584), +(11,30,418,614), +(11,31,439,629), +(11,32,461,659), +(11,33,494,689), +(11,34,518,704), +(11,35,543,734), +(11,36,569,749), +(11,37,596,779), +(11,38,624,809), +(11,39,653,824), +(11,40,683,854), +(11,41,714,869), +(11,42,746,899), +(11,43,779,914), +(11,44,823,944), +(11,45,858,959), +(11,46,894,989), +(11,47,921,1004), +(11,48,959,1019), +(11,49,998,1049), +(11,50,1038,1064), +(11,51,1079,1079), +(11,52,1121,1109), +(11,53,1164,1124), +(11,54,1208,1139), +(11,55,1253,1154), +(11,56,1299,1169), +(11,57,1346,1199), +(11,58,1384,1214), +(11,59,1433,1229), +(11,60,1483,1244), +(11,61,1657,1357), +(11,62,1840,1469), +(11,63,2020,1582), +(11,64,2222,1694), +(11,65,2433,1807), +(11,66,2640,1919), +(11,67,2872,2032), +(11,68,3114,2145), +(11,69,3351,2257), +(11,70,3614,2370); +/*!40000 ALTER TABLE `player_classlevelstats` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `player_levelstats` +-- + +DROP TABLE IF EXISTS `player_levelstats`; +CREATE TABLE `player_levelstats` ( + `race` tinyint(3) unsigned NOT NULL, + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `str` tinyint(3) unsigned NOT NULL, + `agi` tinyint(3) unsigned NOT NULL, + `sta` tinyint(3) unsigned NOT NULL, + `inte` tinyint(3) unsigned NOT NULL, + `spi` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`race`,`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +-- +-- Dumping data for table `player_levelstats` +-- + +LOCK TABLES `player_levelstats` WRITE; +/*!40000 ALTER TABLE `player_levelstats` DISABLE KEYS */; +INSERT INTO `player_levelstats` VALUES +(1,1,1,23,20,22,20,20), +(1,1,2,24,21,23,20,20), +(1,1,3,26,22,24,20,21), +(1,1,4,27,22,26,20,21), +(1,1,5,28,23,27,20,21), +(1,1,6,30,24,28,20,21), +(1,1,7,31,25,29,21,22), +(1,1,8,32,26,30,21,22), +(1,1,9,34,26,32,21,22), +(1,1,10,35,27,33,21,23), +(1,1,11,36,28,34,21,23), +(1,1,12,38,29,35,21,23), +(1,1,13,39,30,37,21,24), +(1,1,14,41,31,38,21,24), +(1,1,15,42,32,39,21,24), +(1,1,16,44,33,41,21,25), +(1,1,17,45,34,42,22,25), +(1,1,18,47,34,43,22,25), +(1,1,19,48,35,45,22,26), +(1,1,20,50,36,46,22,26), +(1,1,21,51,37,48,22,26), +(1,1,22,53,38,49,22,27), +(1,1,23,54,39,51,22,27), +(1,1,24,56,40,52,23,28), +(1,1,25,58,41,53,23,28), +(1,1,26,59,42,55,23,28), +(1,1,27,61,43,56,23,29), +(1,1,28,63,44,58,23,29), +(1,1,29,64,45,59,23,30), +(1,1,30,66,46,61,24,30), +(1,1,31,68,47,62,24,30), +(1,1,32,69,48,64,24,31), +(1,1,33,71,50,66,24,31), +(1,1,34,73,51,67,24,32), +(1,1,35,74,52,69,24,32), +(1,1,36,76,53,70,25,33), +(1,1,37,78,54,72,25,33), +(1,1,38,80,55,74,25,34), +(1,1,39,82,56,75,25,34), +(1,1,40,83,57,77,25,35), +(1,1,41,85,58,79,26,35), +(1,1,42,87,60,80,26,35), +(1,1,43,89,61,82,26,36), +(1,1,44,91,62,84,26,36), +(1,1,45,93,63,85,26,37), +(1,1,46,95,64,87,27,37), +(1,1,47,97,66,89,27,38), +(1,1,48,99,67,91,27,38), +(1,1,49,101,68,93,27,39), +(1,1,50,103,69,94,28,40), +(1,1,51,105,71,96,28,40), +(1,1,52,107,72,98,28,41), +(1,1,53,109,73,100,28,41), +(1,1,54,111,74,102,29,42), +(1,1,55,113,76,103,29,42), +(1,1,56,115,77,105,29,43), +(1,1,57,117,78,107,29,43), +(1,1,58,119,79,109,30,44), +(1,1,59,121,81,111,30,44), +(1,1,60,123,82,113,30,45), +(1,1,61,125,83,115,30,46), +(1,1,62,127,85,117,31,46), +(1,1,63,129,86,119,31,47), +(1,1,64,132,88,121,31,47), +(1,1,65,134,89,123,32,48), +(1,1,66,136,90,125,32,49), +(1,1,67,138,92,127,32,49), +(1,1,68,140,93,129,32,50), +(1,1,69,143,95,131,33,50), +(1,1,70,145,96,133,33,51), +(1,2,1,22,20,22,20,21), +(1,2,2,23,21,23,21,22), +(1,2,3,24,21,24,21,22), +(1,2,4,25,22,25,22,23), +(1,2,5,26,22,26,23,24), +(1,2,6,28,23,27,23,25), +(1,2,7,29,24,28,24,25), +(1,2,8,30,24,29,25,26), +(1,2,9,31,25,30,25,27), +(1,2,10,32,25,32,26,27), +(1,2,11,33,26,33,27,28), +(1,2,12,35,27,34,27,29), +(1,2,13,36,27,35,28,30), +(1,2,14,37,28,36,29,31), +(1,2,15,38,29,37,30,31), +(1,2,16,40,29,38,30,32), +(1,2,17,41,30,40,31,33), +(1,2,18,42,31,41,32,34), +(1,2,19,43,31,42,33,35), +(1,2,20,45,32,43,33,35), +(1,2,21,46,33,45,34,36), +(1,2,22,47,33,46,35,37), +(1,2,23,49,34,47,36,38), +(1,2,24,50,35,48,37,39), +(1,2,25,51,36,50,37,40), +(1,2,26,53,36,51,38,41), +(1,2,27,54,37,52,39,42), +(1,2,28,56,38,54,40,43), +(1,2,29,57,39,55,41,43), +(1,2,30,58,39,56,42,44), +(1,2,31,60,40,58,43,45), +(1,2,32,61,41,59,43,46), +(1,2,33,63,42,60,44,47), +(1,2,34,64,43,62,45,48), +(1,2,35,66,44,63,46,49), +(1,2,36,67,44,65,47,50), +(1,2,37,69,45,66,48,51), +(1,2,38,70,46,67,49,52), +(1,2,39,72,47,69,50,53), +(1,2,40,73,48,70,51,54), +(1,2,41,75,49,72,52,55), +(1,2,42,77,49,73,53,56), +(1,2,43,78,50,75,54,57), +(1,2,44,80,51,76,55,58), +(1,2,45,81,52,78,56,59), +(1,2,46,83,53,79,57,61), +(1,2,47,85,54,81,58,62), +(1,2,48,86,55,83,59,63), +(1,2,49,88,56,84,60,64), +(1,2,50,90,57,86,61,65), +(1,2,51,91,58,87,62,66), +(1,2,52,93,59,89,63,67), +(1,2,53,95,60,91,64,68), +(1,2,54,97,61,92,65,69), +(1,2,55,98,61,94,66,71), +(1,2,56,100,62,95,67,72), +(1,2,57,102,63,97,68,73), +(1,2,58,104,64,99,69,74), +(1,2,59,105,65,101,70,75), +(1,2,60,107,66,102,71,77), +(1,2,61,109,67,104,73,78), +(1,2,62,111,69,106,74,79), +(1,2,63,113,70,107,75,80), +(1,2,64,115,71,109,76,81), +(1,2,65,116,72,111,77,83), +(1,2,66,118,73,113,78,84), +(1,2,67,120,74,115,79,85), +(1,2,68,122,75,116,81,86), +(1,2,69,124,76,118,82,88), +(1,2,70,126,77,120,83,89), +(1,4,1,21,23,21,20,20), +(1,4,2,22,24,22,20,20), +(1,4,3,23,26,22,20,21), +(1,4,4,23,27,23,20,21), +(1,4,5,24,29,24,21,21), +(1,4,6,25,30,25,21,22), +(1,4,7,26,32,25,21,22), +(1,4,8,26,33,26,21,23), +(1,4,9,27,35,27,21,23), +(1,4,10,28,36,27,21,23), +(1,4,11,29,38,28,22,24), +(1,4,12,30,39,29,22,24), +(1,4,13,31,41,30,22,25), +(1,4,14,31,43,31,22,25), +(1,4,15,32,44,31,22,25), +(1,4,16,33,46,32,23,26), +(1,4,17,34,48,33,23,26), +(1,4,18,35,49,34,23,27), +(1,4,19,36,51,35,23,27), +(1,4,20,37,53,35,23,28), +(1,4,21,38,54,36,24,28), +(1,4,22,39,56,37,24,29), +(1,4,23,40,58,38,24,29), +(1,4,24,41,60,39,24,30), +(1,4,25,42,61,40,25,30), +(1,4,26,43,63,41,25,31), +(1,4,27,44,65,42,25,31), +(1,4,28,45,67,43,25,32), +(1,4,29,46,69,43,25,32), +(1,4,30,47,71,44,26,33), +(1,4,31,48,72,45,26,33), +(1,4,32,49,74,46,26,34), +(1,4,33,50,76,47,27,34), +(1,4,34,51,78,48,27,35), +(1,4,35,52,80,49,27,35), +(1,4,36,53,82,50,27,36), +(1,4,37,54,84,51,28,36), +(1,4,38,55,86,52,28,37), +(1,4,39,56,88,53,28,38), +(1,4,40,57,90,54,28,38), +(1,4,41,58,92,55,29,39), +(1,4,42,60,94,56,29,39), +(1,4,43,61,96,57,29,40), +(1,4,44,62,98,58,30,40), +(1,4,45,63,100,59,30,41), +(1,4,46,64,103,61,30,42), +(1,4,47,65,105,62,31,42), +(1,4,48,66,107,63,31,43), +(1,4,49,68,109,64,31,44), +(1,4,50,69,111,65,32,44), +(1,4,51,70,113,66,32,45), +(1,4,52,71,116,67,32,45), +(1,4,53,73,118,68,33,46), +(1,4,54,74,120,69,33,47), +(1,4,55,75,122,71,33,47), +(1,4,56,76,125,72,34,48), +(1,4,57,78,127,73,34,49), +(1,4,58,79,129,74,34,49), +(1,4,59,80,131,75,35,50), +(1,4,60,81,134,77,35,51), +(1,4,61,83,136,78,35,51), +(1,4,62,84,138,79,36,52), +(1,4,63,85,141,80,36,53), +(1,4,64,87,143,81,37,54), +(1,4,65,88,146,83,37,54), +(1,4,66,89,148,84,37,55), +(1,4,67,91,151,85,38,56), +(1,4,68,92,153,86,38,57), +(1,4,69,94,156,88,39,57), +(1,4,70,95,158,89,39,58), +(1,5,1,20,20,20,22,23), +(1,5,2,20,20,20,23,24), +(1,5,3,20,20,21,25,26), +(1,5,4,20,21,21,26,27), +(1,5,5,21,21,21,27,28), +(1,5,6,21,21,22,29,30), +(1,5,7,21,21,22,30,31), +(1,5,8,21,22,23,31,33), +(1,5,9,21,22,23,33,34), +(1,5,10,21,22,23,34,36), +(1,5,11,22,22,24,36,37), +(1,5,12,22,23,24,37,39), +(1,5,13,22,23,25,38,40), +(1,5,14,22,23,25,40,42), +(1,5,15,22,23,25,41,43), +(1,5,16,23,24,26,43,45), +(1,5,17,23,24,26,44,46), +(1,5,18,23,24,27,46,48), +(1,5,19,23,24,27,47,49), +(1,5,20,23,25,28,49,51), +(1,5,21,24,25,28,51,53), +(1,5,22,24,25,29,52,54), +(1,5,23,24,26,29,54,56), +(1,5,24,24,26,30,55,58), +(1,5,25,25,26,30,57,59), +(1,5,26,25,27,31,59,61), +(1,5,27,25,27,31,60,63), +(1,5,28,25,27,32,62,65), +(1,5,29,25,28,32,64,66), +(1,5,30,26,28,33,65,68), +(1,5,31,26,28,33,67,70), +(1,5,32,26,29,34,69,72), +(1,5,33,27,29,34,70,73), +(1,5,34,27,29,35,72,75), +(1,5,35,27,30,35,74,77), +(1,5,36,27,30,36,76,79), +(1,5,37,28,30,36,78,81), +(1,5,38,28,31,37,79,83), +(1,5,39,28,31,38,81,85), +(1,5,40,28,31,38,83,87), +(1,5,41,29,32,39,85,88), +(1,5,42,29,32,39,87,90), +(1,5,43,29,33,40,89,92), +(1,5,44,30,33,40,91,94), +(1,5,45,30,33,41,92,96), +(1,5,46,30,34,42,94,98), +(1,5,47,31,34,42,96,100), +(1,5,48,31,35,43,98,102), +(1,5,49,31,35,44,100,104), +(1,5,50,32,36,44,102,106), +(1,5,51,32,36,45,104,109), +(1,5,52,32,36,45,106,111), +(1,5,53,33,37,46,108,113), +(1,5,54,33,37,47,110,115), +(1,5,55,33,38,47,112,117), +(1,5,56,34,38,48,114,119), +(1,5,57,34,39,49,117,121), +(1,5,58,34,39,49,119,124), +(1,5,59,35,40,50,121,126), +(1,5,60,35,40,51,123,128), +(1,5,61,35,41,51,125,130), +(1,5,62,36,41,52,127,132), +(1,5,63,36,41,53,129,135), +(1,5,64,37,42,54,132,137), +(1,5,65,37,42,54,134,139), +(1,5,66,37,43,55,136,142), +(1,5,67,38,43,56,138,144), +(1,5,68,38,44,57,140,146), +(1,5,69,39,44,57,143,149), +(1,5,70,39,45,58,145,151), +(1,8,1,20,20,20,23,22), +(1,8,2,20,20,20,24,23), +(1,8,3,20,20,21,26,25), +(1,8,4,20,20,21,27,26), +(1,8,5,20,21,21,28,27), +(1,8,6,20,21,21,30,29), +(1,8,7,21,21,22,31,30), +(1,8,8,21,21,22,33,31), +(1,8,9,21,21,22,34,33), +(1,8,10,21,21,23,36,34), +(1,8,11,21,22,23,37,36), +(1,8,12,21,22,23,39,37), +(1,8,13,21,22,24,40,38), +(1,8,14,21,22,24,42,40), +(1,8,15,21,22,24,43,41), +(1,8,16,21,23,25,45,43), +(1,8,17,22,23,25,46,44), +(1,8,18,22,23,25,48,46), +(1,8,19,22,23,26,49,47), +(1,8,20,22,23,26,51,49), +(1,8,21,22,24,26,53,51), +(1,8,22,22,24,27,54,52), +(1,8,23,22,24,27,56,54), +(1,8,24,23,24,28,58,55), +(1,8,25,23,25,28,59,57), +(1,8,26,23,25,28,61,59), +(1,8,27,23,25,29,63,60), +(1,8,28,23,25,29,65,62), +(1,8,29,23,25,30,66,64), +(1,8,30,24,26,30,68,65), +(1,8,31,24,26,30,70,67), +(1,8,32,24,26,31,72,69), +(1,8,33,24,27,31,73,70), +(1,8,34,24,27,32,75,72), +(1,8,35,24,27,32,77,74), +(1,8,36,25,27,33,79,76), +(1,8,37,25,28,33,81,78), +(1,8,38,25,28,34,83,79), +(1,8,39,25,28,34,85,81), +(1,8,40,25,28,35,87,83), +(1,8,41,26,29,35,88,85), +(1,8,42,26,29,35,90,87), +(1,8,43,26,29,36,92,89), +(1,8,44,26,30,36,94,91), +(1,8,45,26,30,37,96,92), +(1,8,46,27,30,37,98,94), +(1,8,47,27,31,38,100,96), +(1,8,48,27,31,38,102,98), +(1,8,49,27,31,39,104,100), +(1,8,50,28,32,40,106,102), +(1,8,51,28,32,40,109,104), +(1,8,52,28,32,41,111,106), +(1,8,53,28,33,41,113,108), +(1,8,54,29,33,42,115,110), +(1,8,55,29,33,42,117,112), +(1,8,56,29,34,43,119,114), +(1,8,57,29,34,43,121,117), +(1,8,58,30,34,44,124,119), +(1,8,59,30,35,44,126,121), +(1,8,60,30,35,45,128,123), +(1,8,61,30,35,46,130,125), +(1,8,62,31,36,46,132,127), +(1,8,63,31,36,47,135,129), +(1,8,64,31,37,47,137,132), +(1,8,65,32,37,48,139,134), +(1,8,66,32,37,49,142,136), +(1,8,67,32,38,49,144,138), +(1,8,68,32,38,50,146,140), +(1,8,69,33,39,50,149,143), +(1,8,70,33,39,51,151,145), +(1,9,1,20,20,21,22,22), +(1,9,2,20,20,22,23,23), +(1,9,3,21,21,22,24,24), +(1,9,4,21,21,23,26,25), +(1,9,5,21,21,23,27,27), +(1,9,6,21,22,24,28,28), +(1,9,7,22,22,24,29,29), +(1,9,8,22,23,25,30,30), +(1,9,9,22,23,26,32,31), +(1,9,10,23,23,26,33,33), +(1,9,11,23,24,27,34,34), +(1,9,12,23,24,27,35,35), +(1,9,13,24,25,28,37,36), +(1,9,14,24,25,29,38,38), +(1,9,15,24,25,29,39,39), +(1,9,16,25,26,30,41,40), +(1,9,17,25,26,31,42,42), +(1,9,18,25,27,31,43,43), +(1,9,19,26,27,32,45,44), +(1,9,20,26,28,33,46,46), +(1,9,21,26,28,33,48,47), +(1,9,22,27,29,34,49,49), +(1,9,23,27,29,35,51,50), +(1,9,24,28,30,35,52,51), +(1,9,25,28,30,36,53,53), +(1,9,26,28,31,37,55,54), +(1,9,27,29,31,37,56,56), +(1,9,28,29,32,38,58,57), +(1,9,29,30,32,39,59,59), +(1,9,30,30,33,40,61,60), +(1,9,31,30,33,40,62,62), +(1,9,32,31,34,41,64,63), +(1,9,33,31,34,42,66,65), +(1,9,34,32,35,43,67,66), +(1,9,35,32,35,44,69,68), +(1,9,36,33,36,44,70,69), +(1,9,37,33,36,45,72,71), +(1,9,38,34,37,46,74,73), +(1,9,39,34,38,47,75,74), +(1,9,40,35,38,48,77,76), +(1,9,41,35,39,48,79,78), +(1,9,42,35,39,49,80,79), +(1,9,43,36,40,50,82,81), +(1,9,44,36,40,51,84,83), +(1,9,45,37,41,52,85,84), +(1,9,46,37,42,53,87,86), +(1,9,47,38,42,54,89,88), +(1,9,48,38,43,55,91,89), +(1,9,49,39,44,55,93,91), +(1,9,50,40,44,56,94,93), +(1,9,51,40,45,57,96,95), +(1,9,52,41,45,58,98,97), +(1,9,53,41,46,59,100,98), +(1,9,54,42,47,60,102,100), +(1,9,55,42,47,61,103,102), +(1,9,56,43,48,62,105,104), +(1,9,57,43,49,63,107,106), +(1,9,58,44,49,64,109,108), +(1,9,59,44,50,65,111,109), +(1,9,60,45,51,66,113,111), +(1,9,61,46,51,67,115,113), +(1,9,62,46,52,68,117,115), +(1,9,63,47,53,69,119,117), +(1,9,64,47,54,70,121,119), +(1,9,65,48,54,71,123,121), +(1,9,66,49,55,72,125,123), +(1,9,67,49,56,73,127,125), +(1,9,68,50,57,74,129,127), +(1,9,69,50,57,75,131,129), +(1,9,70,51,58,76,133,131), +(2,1,1,26,17,24,17,23), +(2,1,2,27,18,25,17,23), +(2,1,3,29,19,26,17,24), +(2,1,4,30,19,27,17,24), +(2,1,5,31,20,29,17,24), +(2,1,6,32,21,30,17,24), +(2,1,7,34,22,31,18,25), +(2,1,8,35,23,32,18,25), +(2,1,9,37,24,34,18,25), +(2,1,10,38,24,35,18,26), +(2,1,11,39,25,36,18,26), +(2,1,12,41,26,37,18,26), +(2,1,13,42,27,39,18,27), +(2,1,14,44,28,40,18,27), +(2,1,15,45,29,41,18,27), +(2,1,16,47,30,43,19,28), +(2,1,17,48,31,44,19,28), +(2,1,18,50,32,45,19,28), +(2,1,19,51,33,47,19,29), +(2,1,20,53,34,48,19,29), +(2,1,21,54,34,50,19,29), +(2,1,22,56,35,51,19,30), +(2,1,23,57,36,52,20,30), +(2,1,24,59,37,54,20,30), +(2,1,25,60,38,55,20,31), +(2,1,26,62,39,57,20,31), +(2,1,27,64,40,58,20,32), +(2,1,28,65,41,60,20,32), +(2,1,29,67,43,61,21,32), +(2,1,30,69,44,63,21,33), +(2,1,31,70,45,64,21,33), +(2,1,32,72,46,66,21,34), +(2,1,33,74,47,67,21,34), +(2,1,34,76,48,69,21,35), +(2,1,35,77,49,71,22,35), +(2,1,36,79,50,72,22,36), +(2,1,37,81,51,74,22,36), +(2,1,38,83,52,76,22,36), +(2,1,39,84,53,77,22,37), +(2,1,40,86,55,79,23,37), +(2,1,41,88,56,81,23,38), +(2,1,42,90,57,82,23,38), +(2,1,43,92,58,84,23,39), +(2,1,44,94,59,86,23,39), +(2,1,45,96,60,87,24,40), +(2,1,46,98,62,89,24,40), +(2,1,47,100,63,91,24,41), +(2,1,48,101,64,93,24,41), +(2,1,49,103,65,94,25,42), +(2,1,50,105,66,96,25,42), +(2,1,51,107,68,98,25,43), +(2,1,52,109,69,100,25,43), +(2,1,53,111,70,102,25,44), +(2,1,54,113,71,104,26,45), +(2,1,55,115,73,105,26,45), +(2,1,56,118,74,107,26,46), +(2,1,57,120,75,109,26,46), +(2,1,58,122,77,111,27,47), +(2,1,59,124,78,113,27,47), +(2,1,60,126,79,115,27,48), +(2,1,61,128,81,117,27,48), +(2,1,62,130,82,119,28,49), +(2,1,63,132,83,121,28,50), +(2,1,64,135,85,123,28,50), +(2,1,65,137,86,125,29,51), +(2,1,66,139,87,127,29,52), +(2,1,67,141,89,129,29,52), +(2,1,68,143,90,131,29,53), +(2,1,69,146,92,133,30,53), +(2,1,70,148,93,135,30,54), +(2,3,1,23,20,23,17,24), +(2,3,2,23,21,24,18,25), +(2,3,3,24,23,25,18,25), +(2,3,4,24,24,26,19,26), +(2,3,5,25,25,27,19,26), +(2,3,6,25,27,28,20,27), +(2,3,7,26,28,28,21,28), +(2,3,8,26,30,29,21,28), +(2,3,9,26,31,30,22,29), +(2,3,10,27,33,31,22,30), +(2,3,11,27,34,32,23,30), +(2,3,12,28,36,33,24,31), +(2,3,13,28,37,34,24,32), +(2,3,14,29,39,35,25,33), +(2,3,15,29,40,36,26,33), +(2,3,16,30,42,37,26,34), +(2,3,17,30,43,39,27,35), +(2,3,18,31,45,40,28,35), +(2,3,19,31,47,41,28,36), +(2,3,20,32,48,42,29,37), +(2,3,21,32,50,43,30,38), +(2,3,22,33,51,44,31,39), +(2,3,23,34,53,45,31,39), +(2,3,24,34,55,46,32,40), +(2,3,25,35,57,47,33,41), +(2,3,26,35,58,48,34,42), +(2,3,27,36,60,50,34,43), +(2,3,28,36,62,51,35,43), +(2,3,29,37,63,52,36,44), +(2,3,30,38,65,53,37,45), +(2,3,31,38,67,54,37,46), +(2,3,32,39,69,56,38,47), +(2,3,33,39,71,57,39,48), +(2,3,34,40,72,58,40,49), +(2,3,35,41,74,59,41,49), +(2,3,36,41,76,61,42,50), +(2,3,37,42,78,62,42,51), +(2,3,38,43,80,63,43,52), +(2,3,39,43,82,64,44,53), +(2,3,40,44,84,66,45,54), +(2,3,41,45,86,67,46,55), +(2,3,42,45,88,68,47,56), +(2,3,43,46,90,70,47,57), +(2,3,44,47,91,71,48,58), +(2,3,45,47,93,72,49,59), +(2,3,46,48,95,74,50,60), +(2,3,47,49,98,75,51,61), +(2,3,48,50,100,77,52,62), +(2,3,49,50,102,78,53,63), +(2,3,50,51,104,79,54,64), +(2,3,51,52,106,81,55,65), +(2,3,52,52,108,82,56,66), +(2,3,53,53,110,84,57,67), +(2,3,54,54,112,85,58,68), +(2,3,55,55,114,87,59,69), +(2,3,56,55,116,88,60,70), +(2,3,57,56,118,90,61,71), +(2,3,58,57,121,91,62,72), +(2,3,59,58,123,93,63,73), +(2,3,60,59,125,94,64,74), +(2,3,61,59,127,96,65,76), +(2,3,62,60,130,97,66,77), +(2,3,63,61,132,99,67,78), +(2,3,64,62,134,100,68,79), +(2,3,65,63,136,102,69,80), +(2,3,66,64,139,104,70,81), +(2,3,67,64,141,105,71,82), +(2,3,68,65,143,107,72,84), +(2,3,69,66,146,108,73,85), +(2,3,70,67,148,110,74,86), +(2,4,1,24,20,23,17,23), +(2,4,2,25,21,24,17,23), +(2,4,3,25,23,24,17,24), +(2,4,4,26,24,25,17,24), +(2,4,5,27,26,26,18,24), +(2,4,6,28,27,26,18,25), +(2,4,7,29,29,27,18,25), +(2,4,8,29,30,28,18,26), +(2,4,9,30,32,29,18,26), +(2,4,10,31,33,29,19,26), +(2,4,11,32,35,30,19,27), +(2,4,12,33,37,31,19,27), +(2,4,13,34,38,32,19,28), +(2,4,14,34,40,32,19,28), +(2,4,15,35,41,33,19,28), +(2,4,16,36,43,34,20,29), +(2,4,17,37,45,35,20,29), +(2,4,18,38,46,36,20,30), +(2,4,19,39,48,37,20,30), +(2,4,20,40,50,37,21,31), +(2,4,21,41,52,38,21,31), +(2,4,22,42,53,39,21,31), +(2,4,23,43,55,40,21,32), +(2,4,24,43,57,41,21,32), +(2,4,25,44,59,42,22,33), +(2,4,26,45,60,43,22,33), +(2,4,27,46,62,44,22,34), +(2,4,28,47,64,44,22,34), +(2,4,29,48,66,45,23,35), +(2,4,30,49,68,46,23,35), +(2,4,31,50,70,47,23,36), +(2,4,32,51,72,48,23,36), +(2,4,33,53,73,49,24,37), +(2,4,34,54,75,50,24,38), +(2,4,35,55,77,51,24,38), +(2,4,36,56,79,52,24,39), +(2,4,37,57,81,53,25,39), +(2,4,38,58,83,54,25,40), +(2,4,39,59,85,55,25,40), +(2,4,40,60,87,56,26,41), +(2,4,41,61,89,57,26,41), +(2,4,42,62,91,58,26,42), +(2,4,43,63,93,59,27,43), +(2,4,44,65,95,60,27,43), +(2,4,45,66,98,61,27,44), +(2,4,46,67,100,62,27,44), +(2,4,47,68,102,64,28,45), +(2,4,48,69,104,65,28,46), +(2,4,49,71,106,66,28,46), +(2,4,50,72,108,67,29,47), +(2,4,51,73,110,68,29,48), +(2,4,52,74,113,69,29,48), +(2,4,53,75,115,70,30,49), +(2,4,54,77,117,71,30,50), +(2,4,55,78,119,73,30,50), +(2,4,56,79,122,74,31,51), +(2,4,57,80,124,75,31,52), +(2,4,58,82,126,76,31,52), +(2,4,59,83,129,77,32,53), +(2,4,60,84,131,78,32,54), +(2,4,61,86,133,80,33,54), +(2,4,62,87,136,81,33,55), +(2,4,63,88,138,82,33,56), +(2,4,64,90,140,83,34,57), +(2,4,65,91,143,85,34,57), +(2,4,66,92,145,86,34,58), +(2,4,67,94,148,87,35,59), +(2,4,68,95,150,88,35,59), +(2,4,69,97,153,90,36,60), +(2,4,70,98,155,91,36,61), +(2,7,1,24,17,23,18,25), +(2,7,2,25,17,24,19,26), +(2,7,3,26,18,25,20,27), +(2,7,4,26,18,26,21,28), +(2,7,5,27,19,27,22,29), +(2,7,6,28,19,28,23,30), +(2,7,7,29,20,29,24,31), +(2,7,8,30,20,30,25,32), +(2,7,9,31,21,31,26,33), +(2,7,10,32,21,32,27,34), +(2,7,11,33,22,33,28,36), +(2,7,12,34,22,34,29,37), +(2,7,13,34,23,35,30,38), +(2,7,14,35,23,36,31,39), +(2,7,15,36,24,37,32,40), +(2,7,16,37,24,39,33,41), +(2,7,17,38,25,40,34,43), +(2,7,18,39,25,41,35,44), +(2,7,19,40,26,42,36,45), +(2,7,20,41,26,43,37,46), +(2,7,21,42,27,44,38,47), +(2,7,22,43,27,45,39,49), +(2,7,23,44,28,47,40,50), +(2,7,24,45,28,48,41,51), +(2,7,25,47,29,49,43,52), +(2,7,26,48,30,50,44,54), +(2,7,27,49,30,52,45,55), +(2,7,28,50,31,53,46,56), +(2,7,29,51,31,54,47,58), +(2,7,30,52,32,55,48,59), +(2,7,31,53,33,57,50,60), +(2,7,32,54,33,58,51,62), +(2,7,33,55,34,59,52,63), +(2,7,34,57,34,61,53,65), +(2,7,35,58,35,62,55,66), +(2,7,36,59,36,63,56,67), +(2,7,37,60,36,65,57,69), +(2,7,38,61,37,66,58,70), +(2,7,39,62,38,67,60,72), +(2,7,40,64,38,69,61,73), +(2,7,41,65,39,70,62,75), +(2,7,42,66,40,72,64,76), +(2,7,43,67,40,73,65,78), +(2,7,44,69,41,74,66,79), +(2,7,45,70,42,76,68,81), +(2,7,46,71,42,77,69,82), +(2,7,47,72,43,79,70,84), +(2,7,48,74,44,80,72,85), +(2,7,49,75,45,82,73,87), +(2,7,50,76,45,83,75,89), +(2,7,51,78,46,85,76,90), +(2,7,52,79,47,86,77,92), +(2,7,53,80,47,88,79,93), +(2,7,54,82,48,90,80,95), +(2,7,55,83,49,91,82,97), +(2,7,56,85,50,93,83,98), +(2,7,57,86,50,94,85,100), +(2,7,58,87,51,96,86,102), +(2,7,59,89,52,97,88,103), +(2,7,60,90,53,99,89,105), +(2,7,61,92,54,101,91,107), +(2,7,62,93,54,102,92,109), +(2,7,63,95,55,104,94,110), +(2,7,64,96,56,106,95,112), +(2,7,65,97,57,107,97,114), +(2,7,66,99,58,109,99,116), +(2,7,67,100,58,111,100,118), +(2,7,68,102,59,113,102,119), +(2,7,69,103,60,114,103,121), +(2,7,70,105,61,116,105,123), +(2,9,1,23,17,23,19,25), +(2,9,2,23,17,24,20,26), +(2,9,3,24,18,24,21,27), +(2,9,4,24,18,25,23,28), +(2,9,5,24,18,25,24,30), +(2,9,6,24,19,26,25,31), +(2,9,7,25,19,26,26,32), +(2,9,8,25,20,27,27,33), +(2,9,9,25,20,27,29,34), +(2,9,10,26,20,28,30,36), +(2,9,11,26,21,29,31,37), +(2,9,12,26,21,29,33,38), +(2,9,13,27,22,30,34,39), +(2,9,14,27,22,31,35,41), +(2,9,15,27,23,31,37,42), +(2,9,16,28,23,32,38,43), +(2,9,17,28,23,32,39,45), +(2,9,18,28,24,33,41,46), +(2,9,19,29,24,34,42,47), +(2,9,20,29,25,34,43,49), +(2,9,21,29,25,35,45,50), +(2,9,22,30,26,36,46,51), +(2,9,23,30,26,37,48,53), +(2,9,24,30,27,37,49,54), +(2,9,25,31,27,38,51,56), +(2,9,26,31,28,39,52,57), +(2,9,27,32,28,39,54,59), +(2,9,28,32,29,40,55,60), +(2,9,29,32,29,41,57,62), +(2,9,30,33,30,42,58,63), +(2,9,31,33,30,42,60,65), +(2,9,32,34,31,43,61,66), +(2,9,33,34,31,44,63,68), +(2,9,34,35,32,45,64,69), +(2,9,35,35,32,45,66,71), +(2,9,36,36,33,46,68,72), +(2,9,37,36,34,47,69,74), +(2,9,38,36,34,48,71,76), +(2,9,39,37,35,49,72,77), +(2,9,40,37,35,50,74,79), +(2,9,41,38,36,50,76,80), +(2,9,42,38,36,51,77,82), +(2,9,43,39,37,52,79,84), +(2,9,44,39,38,53,81,85), +(2,9,45,40,38,54,83,87), +(2,9,46,40,39,55,84,89), +(2,9,47,41,39,56,86,91), +(2,9,48,41,40,56,88,92), +(2,9,49,42,41,57,90,94), +(2,9,50,42,41,58,91,96), +(2,9,51,43,42,59,93,98), +(2,9,52,43,43,60,95,99), +(2,9,53,44,43,61,97,101), +(2,9,54,45,44,62,99,103), +(2,9,55,45,45,63,101,105), +(2,9,56,46,45,64,102,107), +(2,9,57,46,46,65,104,109), +(2,9,58,47,47,66,106,110), +(2,9,59,47,47,67,108,112), +(2,9,60,48,48,68,110,114), +(2,9,61,48,49,69,112,116), +(2,9,62,49,49,70,114,118), +(2,9,63,50,50,71,116,120), +(2,9,64,50,51,72,118,122), +(2,9,65,51,51,73,120,124), +(2,9,66,52,52,74,122,126), +(2,9,67,52,53,75,124,128), +(2,9,68,53,54,76,126,130), +(2,9,69,53,54,77,128,132), +(2,9,70,54,55,78,130,134), +(3,1,1,25,16,25,19,19), +(3,1,2,26,17,26,19,19), +(3,1,3,28,18,27,19,20), +(3,1,4,29,18,28,19,20), +(3,1,5,30,19,30,19,20), +(3,1,6,31,20,31,19,20), +(3,1,7,33,21,32,20,21), +(3,1,8,34,22,33,20,21), +(3,1,9,36,23,35,20,21), +(3,1,10,37,23,36,20,22), +(3,1,11,38,24,37,20,22), +(3,1,12,40,25,38,20,22), +(3,1,13,41,26,40,20,23), +(3,1,14,43,27,41,20,23), +(3,1,15,44,28,42,20,23), +(3,1,16,46,29,44,21,24), +(3,1,17,47,30,45,21,24), +(3,1,18,49,31,46,21,24), +(3,1,19,50,32,48,21,25), +(3,1,20,52,33,49,21,25), +(3,1,21,53,34,51,21,26), +(3,1,22,55,34,52,21,26), +(3,1,23,56,35,53,21,26), +(3,1,24,58,36,55,22,27), +(3,1,25,59,37,56,22,27), +(3,1,26,61,38,58,22,27), +(3,1,27,63,39,59,22,28), +(3,1,28,64,41,61,22,28), +(3,1,29,66,42,62,22,29), +(3,1,30,68,43,64,23,29), +(3,1,31,69,44,65,23,30), +(3,1,32,71,45,67,23,30), +(3,1,33,73,46,68,23,30), +(3,1,34,75,47,70,23,31), +(3,1,35,76,48,72,24,31), +(3,1,36,78,49,73,24,32), +(3,1,37,80,50,75,24,32), +(3,1,38,82,51,76,24,33), +(3,1,39,84,52,78,24,33), +(3,1,40,85,54,80,24,34), +(3,1,41,87,55,81,25,34), +(3,1,42,89,56,83,25,35), +(3,1,43,91,57,85,25,35), +(3,1,44,93,58,87,25,36), +(3,1,45,95,59,88,26,36), +(3,1,46,97,61,90,26,37), +(3,1,47,99,62,92,26,37), +(3,1,48,101,63,94,26,38), +(3,1,49,102,64,95,26,38), +(3,1,50,104,65,97,27,39), +(3,1,51,106,67,99,27,39), +(3,1,52,108,68,101,27,40), +(3,1,53,110,69,103,27,40), +(3,1,54,112,70,104,28,41), +(3,1,55,115,72,106,28,41), +(3,1,56,117,73,108,28,42), +(3,1,57,119,74,110,28,42), +(3,1,58,121,76,112,29,43), +(3,1,59,123,77,114,29,43), +(3,1,60,125,78,116,29,44), +(3,1,61,127,80,118,29,45), +(3,1,62,129,81,120,30,45), +(3,1,63,131,82,122,30,46), +(3,1,64,134,84,124,30,46), +(3,1,65,136,85,126,31,47), +(3,1,66,138,86,128,31,48), +(3,1,67,140,88,130,31,48), +(3,1,68,142,89,132,31,49), +(3,1,69,145,91,134,32,49), +(3,1,70,147,92,136,32,50), +(3,2,1,24,16,25,19,20), +(3,2,2,25,17,26,20,21), +(3,2,3,26,17,27,20,21), +(3,2,4,27,18,28,21,22), +(3,2,5,28,18,29,22,23), +(3,2,6,29,19,30,22,24), +(3,2,7,31,20,31,23,24), +(3,2,8,32,20,32,24,25), +(3,2,9,33,21,33,24,26), +(3,2,10,34,21,34,25,26), +(3,2,11,35,22,36,26,27), +(3,2,12,36,23,37,26,28), +(3,2,13,38,23,38,27,29), +(3,2,14,39,24,39,28,30), +(3,2,15,40,25,40,29,30), +(3,2,16,41,25,41,29,31), +(3,2,17,43,26,43,30,32), +(3,2,18,44,27,44,31,33), +(3,2,19,45,28,45,32,34), +(3,2,20,47,28,46,32,35), +(3,2,21,48,29,47,33,35), +(3,2,22,49,30,49,34,36), +(3,2,23,51,30,50,35,37), +(3,2,24,52,31,51,36,38), +(3,2,25,53,32,52,36,39), +(3,2,26,55,33,54,37,40), +(3,2,27,56,33,55,38,41), +(3,2,28,57,34,56,39,42), +(3,2,29,59,35,58,40,43), +(3,2,30,60,36,59,41,43), +(3,2,31,62,37,60,42,44), +(3,2,32,63,37,62,42,45), +(3,2,33,65,38,63,43,46), +(3,2,34,66,39,65,44,47), +(3,2,35,68,40,66,45,48), +(3,2,36,69,41,67,46,49), +(3,2,37,71,41,69,47,50), +(3,2,38,72,42,70,48,51), +(3,2,39,74,43,72,49,52), +(3,2,40,75,44,73,50,53), +(3,2,41,77,45,75,51,54), +(3,2,42,78,46,76,52,55), +(3,2,43,80,47,78,53,56), +(3,2,44,82,47,79,54,57), +(3,2,45,83,48,81,55,59), +(3,2,46,85,49,82,56,60), +(3,2,47,87,50,84,57,61), +(3,2,48,88,51,85,58,62), +(3,2,49,90,52,87,59,63), +(3,2,50,92,53,89,60,64), +(3,2,51,93,54,90,61,65), +(3,2,52,95,55,92,62,66), +(3,2,53,97,56,93,63,67), +(3,2,54,98,57,95,64,69), +(3,2,55,100,58,97,65,70), +(3,2,56,102,59,98,66,71), +(3,2,57,104,60,100,67,72), +(3,2,58,106,61,102,68,73), +(3,2,59,107,62,103,69,74), +(3,2,60,109,63,105,70,76), +(3,2,61,111,64,107,72,77), +(3,2,62,113,65,109,73,78), +(3,2,63,115,66,110,74,79), +(3,2,64,117,67,112,75,80), +(3,2,65,118,68,114,76,82), +(3,2,66,120,69,116,77,83), +(3,2,67,122,70,118,78,84), +(3,2,68,124,71,119,80,85), +(3,2,69,126,72,121,81,87), +(3,2,70,128,73,123,82,88), +(3,3,1,22,19,24,19,20), +(3,3,2,22,20,25,20,21), +(3,3,3,23,22,26,20,21), +(3,3,4,23,23,27,21,22), +(3,3,5,24,25,28,21,23), +(3,3,6,24,26,29,22,23), +(3,3,7,25,27,29,23,24), +(3,3,8,25,29,30,23,25), +(3,3,9,25,30,31,24,25), +(3,3,10,26,32,32,24,26), +(3,3,11,26,33,33,25,27), +(3,3,12,27,35,34,26,27), +(3,3,13,27,36,35,26,28), +(3,3,14,28,38,36,27,29), +(3,3,15,28,39,37,28,29), +(3,3,16,29,41,38,28,30), +(3,3,17,29,42,39,29,31), +(3,3,18,30,44,41,30,32), +(3,3,19,30,46,42,30,32), +(3,3,20,31,47,43,31,33), +(3,3,21,32,49,44,32,34), +(3,3,22,32,51,45,33,35), +(3,3,23,33,52,46,33,36), +(3,3,24,33,54,47,34,36), +(3,3,25,34,56,48,35,37), +(3,3,26,34,57,49,35,38), +(3,3,27,35,59,51,36,39), +(3,3,28,35,61,52,37,40), +(3,3,29,36,63,53,38,40), +(3,3,30,37,64,54,39,41), +(3,3,31,37,66,55,39,42), +(3,3,32,38,68,57,40,43), +(3,3,33,38,70,58,41,44), +(3,3,34,39,71,59,42,45), +(3,3,35,40,73,60,43,46), +(3,3,36,40,75,62,43,47), +(3,3,37,41,77,63,44,47), +(3,3,38,42,79,64,45,48), +(3,3,39,42,81,65,46,49), +(3,3,40,43,83,67,47,50), +(3,3,41,44,85,68,48,51), +(3,3,42,44,87,69,49,52), +(3,3,43,45,89,71,49,53), +(3,3,44,46,91,72,50,54), +(3,3,45,46,93,73,51,55), +(3,3,46,47,95,75,52,56), +(3,3,47,48,97,76,53,57), +(3,3,48,49,99,78,54,58), +(3,3,49,49,101,79,55,59), +(3,3,50,50,103,80,56,60), +(3,3,51,51,105,82,57,61), +(3,3,52,51,107,83,58,62), +(3,3,53,52,109,85,59,63), +(3,3,54,53,111,86,60,64), +(3,3,55,54,113,88,61,65), +(3,3,56,55,115,89,62,66), +(3,3,57,55,118,91,62,67), +(3,3,58,56,120,92,63,68), +(3,3,59,57,122,94,64,70), +(3,3,60,58,124,95,65,71), +(3,3,61,58,126,97,67,72), +(3,3,62,59,129,98,68,73), +(3,3,63,60,131,100,69,74), +(3,3,64,61,133,101,70,75), +(3,3,65,62,135,103,71,76), +(3,3,66,63,138,105,72,77), +(3,3,67,63,140,106,73,78), +(3,3,68,64,142,108,74,80), +(3,3,69,65,145,109,75,81), +(3,3,70,66,147,111,76,82), +(3,4,1,23,19,24,19,19), +(3,4,2,24,20,25,19,19), +(3,4,3,24,22,25,19,20), +(3,4,4,25,23,26,19,20), +(3,4,5,26,25,27,20,20), +(3,4,6,27,26,27,20,21), +(3,4,7,28,28,28,20,21), +(3,4,8,28,29,29,20,22), +(3,4,9,29,31,30,20,22), +(3,4,10,30,32,30,20,22), +(3,4,11,31,34,31,21,23), +(3,4,12,32,36,32,21,23), +(3,4,13,33,37,33,21,24), +(3,4,14,33,39,33,21,24), +(3,4,15,34,40,34,21,25), +(3,4,16,35,42,35,22,25), +(3,4,17,36,44,36,22,25), +(3,4,18,37,45,37,22,26), +(3,4,19,38,47,38,22,26), +(3,4,20,39,49,38,22,27), +(3,4,21,40,51,39,23,27), +(3,4,22,41,52,40,23,28), +(3,4,23,42,54,41,23,28), +(3,4,24,43,56,42,23,29), +(3,4,25,44,58,43,24,29), +(3,4,26,44,59,44,24,30), +(3,4,27,45,61,44,24,30), +(3,4,28,46,63,45,24,31), +(3,4,29,47,65,46,25,31), +(3,4,30,48,67,47,25,32), +(3,4,31,49,69,48,25,32), +(3,4,32,51,71,49,25,33), +(3,4,33,52,72,50,26,33), +(3,4,34,53,74,51,26,34), +(3,4,35,54,76,52,26,34), +(3,4,36,55,78,53,26,35), +(3,4,37,56,80,54,27,35), +(3,4,38,57,82,55,27,36), +(3,4,39,58,84,56,27,37), +(3,4,40,59,86,57,28,37), +(3,4,41,60,88,58,28,38), +(3,4,42,61,90,59,28,38), +(3,4,43,63,92,60,28,39), +(3,4,44,64,95,61,29,39), +(3,4,45,65,97,62,29,40), +(3,4,46,66,99,63,29,41), +(3,4,47,67,101,64,30,41), +(3,4,48,68,103,66,30,42), +(3,4,49,70,105,67,30,43), +(3,4,50,71,107,68,31,43), +(3,4,51,72,110,69,31,44), +(3,4,52,73,112,70,31,44), +(3,4,53,74,114,71,32,45), +(3,4,54,76,116,72,32,46), +(3,4,55,77,118,73,32,46), +(3,4,56,78,121,75,33,47), +(3,4,57,80,123,76,33,48), +(3,4,58,81,125,77,33,48), +(3,4,59,82,128,78,34,49), +(3,4,60,83,130,79,34,50), +(3,4,61,85,132,81,34,51), +(3,4,62,86,135,82,35,51), +(3,4,63,87,137,83,35,52), +(3,4,64,89,139,84,36,53), +(3,4,65,90,142,86,36,53), +(3,4,66,91,144,87,36,54), +(3,4,67,93,147,88,37,55), +(3,4,68,94,149,89,37,56), +(3,4,69,96,152,91,38,56), +(3,4,70,97,154,92,38,57), +(3,5,1,22,16,23,21,22), +(3,5,2,22,16,23,22,23), +(3,5,3,22,16,24,24,25), +(3,5,4,22,17,24,25,26), +(3,5,5,23,17,24,26,27), +(3,5,6,23,17,25,28,29), +(3,5,7,23,17,25,29,30), +(3,5,8,23,18,26,30,32), +(3,5,9,23,18,26,32,33), +(3,5,10,23,18,26,33,35), +(3,5,11,24,18,27,35,36), +(3,5,12,24,19,27,36,38), +(3,5,13,24,19,28,37,39), +(3,5,14,24,19,28,39,41), +(3,5,15,24,19,28,40,42), +(3,5,16,24,20,29,42,44), +(3,5,17,25,20,29,43,45), +(3,5,18,25,20,30,45,47), +(3,5,19,25,21,30,46,49), +(3,5,20,25,21,31,48,50), +(3,5,21,25,21,31,50,52), +(3,5,22,26,22,31,51,53), +(3,5,23,26,22,32,53,55), +(3,5,24,26,22,32,54,57), +(3,5,25,26,22,33,56,58), +(3,5,26,27,23,33,58,60), +(3,5,27,27,23,34,59,62), +(3,5,28,27,23,34,61,64), +(3,5,29,27,24,35,63,65), +(3,5,30,28,24,35,64,67), +(3,5,31,28,24,36,66,69), +(3,5,32,28,25,36,68,71), +(3,5,33,28,25,37,70,72), +(3,5,34,29,26,38,71,74), +(3,5,35,29,26,38,73,76), +(3,5,36,29,26,39,75,78), +(3,5,37,29,27,39,77,80), +(3,5,38,30,27,40,78,82), +(3,5,39,30,27,40,80,84), +(3,5,40,30,28,41,82,86), +(3,5,41,31,28,41,84,88), +(3,5,42,31,29,42,86,89), +(3,5,43,31,29,43,88,91), +(3,5,44,32,29,43,90,93), +(3,5,45,32,30,44,92,95), +(3,5,46,32,30,44,93,97), +(3,5,47,32,30,45,95,99), +(3,5,48,33,31,46,97,101), +(3,5,49,33,31,46,99,103), +(3,5,50,33,32,47,101,106), +(3,5,51,34,32,48,103,108), +(3,5,52,34,33,48,105,110), +(3,5,53,35,33,49,107,112), +(3,5,54,35,33,50,109,114), +(3,5,55,35,34,50,111,116), +(3,5,56,36,34,51,113,118), +(3,5,57,36,35,52,116,120), +(3,5,58,36,35,52,118,123), +(3,5,59,37,36,53,120,125), +(3,5,60,37,36,54,122,127), +(3,5,61,37,37,54,124,129), +(3,5,62,38,37,55,126,131), +(3,5,63,38,38,56,128,134), +(3,5,64,39,38,57,131,136), +(3,5,65,39,39,57,133,138), +(3,5,66,39,39,58,135,141), +(3,5,67,40,40,59,137,143), +(3,5,68,40,40,59,139,145), +(3,5,69,41,40,60,142,148), +(3,5,70,41,41,61,144,150), +(4,1,1,20,25,21,20,20), +(4,1,2,21,26,22,20,20), +(4,1,3,23,27,23,20,21), +(4,1,4,24,27,25,20,21), +(4,1,5,25,28,26,20,21), +(4,1,6,27,29,27,20,21), +(4,1,7,28,30,28,21,22), +(4,1,8,29,31,29,21,22), +(4,1,9,31,31,31,21,22), +(4,1,10,32,32,32,21,23), +(4,1,11,33,33,33,21,23), +(4,1,12,35,34,34,21,23), +(4,1,13,36,35,36,21,24), +(4,1,14,38,36,37,21,24), +(4,1,15,39,37,38,21,24), +(4,1,16,41,37,40,21,25), +(4,1,17,42,38,41,22,25), +(4,1,18,44,39,43,22,25), +(4,1,19,45,40,44,22,26), +(4,1,20,47,41,45,22,26), +(4,1,21,48,42,47,22,26), +(4,1,22,50,43,48,22,27), +(4,1,23,52,44,50,22,27), +(4,1,24,53,45,51,23,28), +(4,1,25,55,46,52,23,28), +(4,1,26,56,47,54,23,28), +(4,1,27,58,48,55,23,29), +(4,1,28,60,49,57,23,29), +(4,1,29,61,50,58,23,30), +(4,1,30,63,51,60,24,30), +(4,1,31,65,52,62,24,30), +(4,1,32,66,53,63,24,31), +(4,1,33,68,54,65,24,31), +(4,1,34,70,55,66,24,32), +(4,1,35,72,56,68,24,32), +(4,1,36,73,58,69,25,33), +(4,1,37,75,59,71,25,33), +(4,1,38,77,60,73,25,34), +(4,1,39,79,61,74,25,34), +(4,1,40,81,62,76,25,35), +(4,1,41,82,63,78,26,35), +(4,1,42,84,64,79,26,35), +(4,1,43,86,66,81,26,36), +(4,1,44,88,67,83,26,36), +(4,1,45,90,68,85,26,37), +(4,1,46,92,69,86,27,37), +(4,1,47,94,70,88,27,38), +(4,1,48,96,72,90,27,38), +(4,1,49,98,73,92,27,39), +(4,1,50,100,74,93,28,40), +(4,1,51,102,75,95,28,40), +(4,1,52,104,77,97,28,41), +(4,1,53,106,78,99,28,41), +(4,1,54,108,79,101,29,42), +(4,1,55,110,80,103,29,42), +(4,1,56,112,82,104,29,43), +(4,1,57,114,83,106,29,43), +(4,1,58,116,84,108,30,44), +(4,1,59,118,86,110,30,44), +(4,1,60,120,87,112,30,45), +(4,1,61,122,88,114,30,46), +(4,1,62,124,90,116,31,46), +(4,1,63,127,91,118,31,47), +(4,1,64,129,92,120,31,47), +(4,1,65,131,94,122,32,48), +(4,1,66,133,95,124,32,49), +(4,1,67,135,97,126,32,49), +(4,1,68,138,98,128,32,50), +(4,1,69,140,100,130,33,50), +(4,1,70,142,101,132,33,51), +(4,3,1,17,28,20,20,21), +(4,3,2,17,29,21,21,22), +(4,3,3,18,31,22,21,22), +(4,3,4,18,32,23,22,23), +(4,3,5,19,33,24,22,24), +(4,3,6,19,35,25,23,24), +(4,3,7,20,36,26,24,25), +(4,3,8,20,38,27,24,25), +(4,3,9,21,39,27,25,26), +(4,3,10,21,40,28,25,27), +(4,3,11,22,42,29,26,28), +(4,3,12,22,43,30,27,28), +(4,3,13,23,45,31,27,29), +(4,3,14,23,46,32,28,30), +(4,3,15,24,48,34,29,30), +(4,3,16,24,50,35,29,31), +(4,3,17,25,51,36,30,32), +(4,3,18,25,53,37,31,33), +(4,3,19,26,54,38,31,33), +(4,3,20,26,56,39,32,34), +(4,3,21,27,57,40,33,35), +(4,3,22,27,59,41,33,36), +(4,3,23,28,61,42,34,36), +(4,3,24,28,62,43,35,37), +(4,3,25,29,64,44,36,38), +(4,3,26,30,66,46,36,39), +(4,3,27,30,68,47,37,40), +(4,3,28,31,69,48,38,41), +(4,3,29,31,71,49,39,41), +(4,3,30,32,73,50,39,42), +(4,3,31,33,75,52,40,43), +(4,3,32,33,76,53,41,44), +(4,3,33,34,78,54,42,45), +(4,3,34,34,80,55,43,46), +(4,3,35,35,82,57,44,47), +(4,3,36,36,84,58,44,48), +(4,3,37,36,86,59,45,48), +(4,3,38,37,87,60,46,49), +(4,3,39,38,89,62,47,50), +(4,3,40,38,91,63,48,51), +(4,3,41,39,93,64,49,52), +(4,3,42,40,95,66,49,53), +(4,3,43,40,97,67,50,54), +(4,3,44,41,99,68,51,55), +(4,3,45,42,101,70,52,56), +(4,3,46,42,103,71,53,57), +(4,3,47,43,105,72,54,58), +(4,3,48,44,107,74,55,59), +(4,3,49,45,109,75,56,60), +(4,3,50,45,111,77,57,61), +(4,3,51,46,113,78,58,62), +(4,3,52,47,115,79,59,63), +(4,3,53,47,118,81,60,64), +(4,3,54,48,120,82,61,65), +(4,3,55,49,122,84,61,66), +(4,3,56,50,124,85,62,67), +(4,3,57,50,126,87,63,68), +(4,3,58,51,128,88,64,69), +(4,3,59,52,131,90,65,70), +(4,3,60,53,133,91,66,72), +(4,3,61,54,135,93,67,73), +(4,3,62,54,137,94,69,74), +(4,3,63,55,140,96,70,75), +(4,3,64,56,142,97,71,76), +(4,3,65,57,144,99,72,77), +(4,3,66,58,147,101,73,78), +(4,3,67,58,149,102,74,79), +(4,3,68,59,151,104,75,81), +(4,3,69,60,154,105,76,82), +(4,3,70,61,156,107,77,83), +(4,4,1,18,28,20,20,20), +(4,4,2,19,29,21,20,20), +(4,4,3,20,31,21,20,21), +(4,4,4,20,32,22,20,21), +(4,4,5,21,34,23,21,21), +(4,4,6,22,35,24,21,22), +(4,4,7,23,37,24,21,22), +(4,4,8,24,38,25,21,23), +(4,4,9,24,40,26,21,23), +(4,4,10,25,41,26,21,23), +(4,4,11,26,43,27,22,24), +(4,4,12,27,44,28,22,24), +(4,4,13,28,46,29,22,25), +(4,4,14,29,48,30,22,25), +(4,4,15,29,49,30,22,25), +(4,4,16,30,51,31,23,26), +(4,4,17,31,52,32,23,26), +(4,4,18,32,54,33,23,27), +(4,4,19,33,56,34,23,27), +(4,4,20,34,57,35,23,28), +(4,4,21,35,59,35,24,28), +(4,4,22,36,61,36,24,29), +(4,4,23,37,63,37,24,29), +(4,4,24,38,64,38,24,30), +(4,4,25,39,66,39,25,30), +(4,4,26,40,68,40,25,31), +(4,4,27,41,70,41,25,31), +(4,4,28,42,72,42,25,32), +(4,4,29,43,73,43,25,32), +(4,4,30,44,75,43,26,33), +(4,4,31,45,77,44,26,33), +(4,4,32,46,79,45,26,34), +(4,4,33,47,81,46,27,34), +(4,4,34,48,83,47,27,35), +(4,4,35,49,85,48,27,35), +(4,4,36,50,87,49,27,36), +(4,4,37,51,89,50,28,36), +(4,4,38,52,91,51,28,37), +(4,4,39,53,93,52,28,38), +(4,4,40,54,95,53,28,38), +(4,4,41,56,97,54,29,39), +(4,4,42,57,99,55,29,39), +(4,4,43,58,101,56,29,40), +(4,4,44,59,103,57,30,40), +(4,4,45,60,105,59,30,41), +(4,4,46,61,107,60,30,42), +(4,4,47,62,109,61,31,42), +(4,4,48,64,112,62,31,43), +(4,4,49,65,114,63,31,44), +(4,4,50,66,116,64,32,44), +(4,4,51,67,118,65,32,45), +(4,4,52,68,120,66,32,45), +(4,4,53,70,123,67,33,46), +(4,4,54,71,125,69,33,47), +(4,4,55,72,127,70,33,47), +(4,4,56,73,129,71,34,48), +(4,4,57,75,132,72,34,49), +(4,4,58,76,134,73,34,49), +(4,4,59,77,136,74,35,50), +(4,4,60,79,139,76,35,51), +(4,4,61,80,141,77,35,51), +(4,4,62,81,143,78,36,52), +(4,4,63,82,146,79,36,53), +(4,4,64,84,148,80,37,54), +(4,4,65,85,151,82,37,54), +(4,4,66,87,153,83,37,55), +(4,4,67,88,156,84,38,56), +(4,4,68,89,158,85,38,57), +(4,4,69,91,160,87,39,57), +(4,4,70,92,163,88,39,58), +(4,5,1,17,25,19,22,23), +(4,5,2,17,25,19,23,24), +(4,5,3,17,25,20,25,26), +(4,5,4,17,26,20,26,27), +(4,5,5,18,26,20,27,28), +(4,5,6,18,26,21,29,30), +(4,5,7,18,26,21,30,31), +(4,5,8,18,26,22,31,33), +(4,5,9,18,27,22,33,34), +(4,5,10,19,27,22,34,36), +(4,5,11,19,27,23,36,37), +(4,5,12,19,27,23,37,39), +(4,5,13,19,28,24,38,40), +(4,5,14,19,28,24,40,42), +(4,5,15,19,28,25,41,43), +(4,5,16,20,28,25,43,45), +(4,5,17,20,29,25,44,46), +(4,5,18,20,29,26,46,48), +(4,5,19,20,29,26,47,49), +(4,5,20,21,30,27,49,51), +(4,5,21,21,30,27,51,53), +(4,5,22,21,30,28,52,54), +(4,5,23,21,30,28,54,56), +(4,5,24,21,31,29,55,58), +(4,5,25,22,31,29,57,59), +(4,5,26,22,31,30,59,61), +(4,5,27,22,32,30,60,63), +(4,5,28,22,32,31,62,65), +(4,5,29,23,32,31,64,66), +(4,5,30,23,33,32,65,68), +(4,5,31,23,33,32,67,70), +(4,5,32,23,33,33,69,72), +(4,5,33,24,34,33,70,73), +(4,5,34,24,34,34,72,75), +(4,5,35,24,34,34,74,77), +(4,5,36,24,35,35,76,79), +(4,5,37,25,35,35,78,81), +(4,5,38,25,35,36,79,83), +(4,5,39,25,36,37,81,85), +(4,5,40,26,36,37,83,87), +(4,5,41,26,37,38,85,88), +(4,5,42,26,37,38,87,90), +(4,5,43,27,37,39,89,92), +(4,5,44,27,38,39,91,94), +(4,5,45,27,38,40,92,96), +(4,5,46,27,39,41,94,98), +(4,5,47,28,39,41,96,100), +(4,5,48,28,39,42,98,102), +(4,5,49,28,40,43,100,104), +(4,5,50,29,40,43,102,106), +(4,5,51,29,41,44,104,109), +(4,5,52,29,41,44,106,111), +(4,5,53,30,42,45,108,113), +(4,5,54,30,42,46,110,115), +(4,5,55,30,43,46,112,117), +(4,5,56,31,43,47,114,119), +(4,5,57,31,43,48,117,121), +(4,5,58,31,44,48,119,124), +(4,5,59,32,44,49,121,126), +(4,5,60,32,45,50,123,128), +(4,5,61,33,45,51,125,130), +(4,5,62,33,46,51,127,132), +(4,5,63,33,46,52,129,135), +(4,5,64,34,47,53,132,137), +(4,5,65,34,47,53,134,139), +(4,5,66,34,48,54,136,142), +(4,5,67,35,48,55,138,144), +(4,5,68,35,49,56,140,146), +(4,5,69,36,49,56,143,149), +(4,5,70,36,50,57,145,151), +(4,11,1,18,25,19,22,22), +(4,11,2,19,25,20,23,23), +(4,11,3,19,26,20,24,24), +(4,11,4,20,26,21,25,26), +(4,11,5,20,27,22,26,27), +(4,11,6,21,27,22,27,28), +(4,11,7,21,28,23,28,29), +(4,11,8,22,28,24,29,30), +(4,11,9,23,29,24,30,32), +(4,11,10,23,29,25,32,33), +(4,11,11,24,30,26,33,34), +(4,11,12,24,31,26,34,35), +(4,11,13,25,31,27,35,37), +(4,11,14,26,32,28,36,38), +(4,11,15,26,32,29,37,39), +(4,11,16,27,33,29,38,41), +(4,11,17,28,33,30,40,42), +(4,11,18,28,34,31,41,43), +(4,11,19,29,35,32,42,45), +(4,11,20,30,35,32,43,46), +(4,11,21,30,36,33,45,48), +(4,11,22,31,36,34,46,49), +(4,11,23,32,37,35,47,51), +(4,11,24,32,38,36,48,52), +(4,11,25,33,38,36,50,53), +(4,11,26,34,39,37,51,55), +(4,11,27,35,40,38,52,56), +(4,11,28,35,40,39,54,58), +(4,11,29,36,41,40,55,59), +(4,11,30,37,42,41,56,61), +(4,11,31,38,42,42,58,62), +(4,11,32,38,43,42,59,64), +(4,11,33,39,44,43,60,66), +(4,11,34,40,44,44,62,67), +(4,11,35,41,45,45,63,69), +(4,11,36,42,46,46,65,70), +(4,11,37,42,47,47,66,72), +(4,11,38,43,47,48,67,74), +(4,11,39,44,48,49,69,75), +(4,11,40,45,49,50,70,77), +(4,11,41,46,50,51,72,79), +(4,11,42,46,50,52,73,80), +(4,11,43,47,51,53,75,82), +(4,11,44,48,52,54,76,84), +(4,11,45,49,53,55,78,85), +(4,11,46,50,54,56,79,87), +(4,11,47,51,54,57,81,89), +(4,11,48,52,55,58,83,91), +(4,11,49,53,56,59,84,93), +(4,11,50,53,57,60,86,94), +(4,11,51,54,58,61,87,96), +(4,11,52,55,59,62,89,98), +(4,11,53,56,59,63,91,100), +(4,11,54,57,60,64,92,102), +(4,11,55,58,61,65,94,103), +(4,11,56,59,62,66,95,105), +(4,11,57,60,63,67,97,107), +(4,11,58,61,64,68,99,109), +(4,11,59,62,65,69,101,111), +(4,11,60,63,66,70,102,113), +(4,11,61,64,66,72,104,115), +(4,11,62,65,67,73,106,117), +(4,11,63,66,68,74,107,119), +(4,11,64,67,69,75,109,121), +(4,11,65,68,70,76,111,123), +(4,11,66,69,71,77,113,125), +(4,11,67,70,72,78,115,127), +(4,11,68,71,73,80,116,129), +(4,11,69,72,74,81,118,131), +(4,11,70,73,75,82,120,133), +(5,1,1,22,18,23,18,25), +(5,1,2,23,19,24,18,25), +(5,1,3,25,20,25,18,26), +(5,1,4,26,20,26,18,26), +(5,1,5,27,21,28,18,26), +(5,1,6,29,22,29,18,26), +(5,1,7,30,23,30,19,27), +(5,1,8,31,24,31,19,27), +(5,1,9,33,25,33,19,27), +(5,1,10,34,25,34,19,28), +(5,1,11,35,26,35,19,28), +(5,1,12,37,27,36,19,28), +(5,1,13,38,28,38,19,28), +(5,1,14,40,29,39,19,29), +(5,1,15,41,30,40,19,29), +(5,1,16,43,31,42,20,29), +(5,1,17,44,32,43,20,30), +(5,1,18,46,33,44,20,30), +(5,1,19,47,34,46,20,31), +(5,1,20,49,34,47,20,31), +(5,1,21,50,35,49,20,31), +(5,1,22,52,36,50,20,32), +(5,1,23,53,37,51,21,32), +(5,1,24,55,38,53,21,32), +(5,1,25,57,39,54,21,33), +(5,1,26,58,40,56,21,33), +(5,1,27,60,41,57,21,34), +(5,1,28,62,42,59,21,34), +(5,1,29,63,43,60,21,34), +(5,1,30,65,44,62,22,35), +(5,1,31,67,46,63,22,35), +(5,1,32,68,47,65,22,36), +(5,1,33,70,48,67,22,36), +(5,1,34,72,49,68,22,36), +(5,1,35,74,50,70,23,37), +(5,1,36,75,51,71,23,37), +(5,1,37,77,52,73,23,38), +(5,1,38,79,53,75,23,38), +(5,1,39,81,54,76,23,39), +(5,1,40,83,55,78,24,39), +(5,1,41,84,57,80,24,40), +(5,1,42,86,58,81,24,40), +(5,1,43,88,59,83,24,41), +(5,1,44,90,60,85,24,41), +(5,1,45,92,61,86,25,42), +(5,1,46,94,62,88,25,42), +(5,1,47,96,64,90,25,43), +(5,1,48,98,65,92,25,43), +(5,1,49,100,66,93,25,44), +(5,1,50,102,67,95,26,44), +(5,1,51,104,69,97,26,45), +(5,1,52,106,70,99,26,45), +(5,1,53,108,71,101,26,46), +(5,1,54,110,72,103,27,46), +(5,1,55,112,74,104,27,47), +(5,1,56,114,75,106,27,48), +(5,1,57,116,76,108,27,48), +(5,1,58,118,78,110,28,49), +(5,1,59,120,79,112,28,49), +(5,1,60,122,80,114,28,50), +(5,1,61,124,82,116,28,50), +(5,1,62,126,83,118,29,51), +(5,1,63,128,84,120,29,52), +(5,1,64,131,86,122,29,52), +(5,1,65,133,87,124,30,53), +(5,1,66,135,88,126,30,53), +(5,1,67,137,90,128,30,54), +(5,1,68,139,91,130,30,55), +(5,1,69,142,93,132,31,55), +(5,1,70,144,94,134,31,56), +(5,4,1,20,21,22,18,25), +(5,4,2,21,22,23,18,25), +(5,4,3,22,24,23,18,26), +(5,4,4,22,25,24,18,26), +(5,4,5,23,27,25,19,26), +(5,4,6,24,28,25,19,27), +(5,4,7,25,30,26,19,27), +(5,4,8,25,31,27,19,27), +(5,4,9,26,33,28,19,28), +(5,4,10,27,34,28,19,28), +(5,4,11,28,36,29,20,29), +(5,4,12,29,38,30,20,29), +(5,4,13,30,39,31,20,29), +(5,4,14,31,41,32,20,30), +(5,4,15,31,42,32,20,30), +(5,4,16,32,44,33,21,31), +(5,4,17,33,46,34,21,31), +(5,4,18,34,47,35,21,32), +(5,4,19,35,49,36,21,32), +(5,4,20,36,51,36,21,32), +(5,4,21,37,52,37,22,33), +(5,4,22,38,54,38,22,33), +(5,4,23,39,56,39,22,34), +(5,4,24,40,58,40,22,34), +(5,4,25,41,60,41,23,35), +(5,4,26,42,61,42,23,35), +(5,4,27,43,63,43,23,36), +(5,4,28,44,65,44,23,36), +(5,4,29,45,67,44,24,37), +(5,4,30,46,69,45,24,37), +(5,4,31,47,71,46,24,38), +(5,4,32,48,72,47,24,38), +(5,4,33,49,74,48,25,39), +(5,4,34,50,76,49,25,39), +(5,4,35,51,78,50,25,40), +(5,4,36,52,80,51,25,41), +(5,4,37,53,82,52,26,41), +(5,4,38,54,84,53,26,42), +(5,4,39,55,86,54,26,42), +(5,4,40,56,88,55,27,43), +(5,4,41,57,90,56,27,43), +(5,4,42,59,92,57,27,44), +(5,4,43,60,94,58,27,45), +(5,4,44,61,96,59,28,45), +(5,4,45,62,99,60,28,46), +(5,4,46,63,101,61,28,46), +(5,4,47,64,103,63,29,47), +(5,4,48,66,105,64,29,48), +(5,4,49,67,107,65,29,48), +(5,4,50,68,109,66,30,49), +(5,4,51,69,111,67,30,50), +(5,4,52,70,114,68,30,50), +(5,4,53,72,116,69,31,51), +(5,4,54,73,118,70,31,52), +(5,4,55,74,120,72,31,52), +(5,4,56,75,123,73,32,53), +(5,4,57,77,125,74,32,54), +(5,4,58,78,127,75,32,54), +(5,4,59,79,130,76,33,55), +(5,4,60,81,132,77,33,56), +(5,4,61,82,134,79,34,56), +(5,4,62,83,137,80,34,57), +(5,4,63,84,139,81,34,58), +(5,4,64,86,141,82,35,59), +(5,4,65,87,144,84,35,59), +(5,4,66,88,146,85,35,60), +(5,4,67,90,149,86,36,61), +(5,4,68,91,151,87,36,61), +(5,4,69,93,154,89,37,62), +(5,4,70,94,156,90,37,63), +(5,5,1,19,18,21,20,28), +(5,5,2,19,18,21,21,29), +(5,5,3,19,18,22,23,31), +(5,5,4,19,19,22,24,32), +(5,5,5,20,19,22,25,33), +(5,5,6,20,19,23,27,35), +(5,5,7,20,19,23,28,36), +(5,5,8,20,20,24,29,38), +(5,5,9,20,20,24,31,39), +(5,5,10,20,20,24,32,40), +(5,5,11,21,20,25,34,42), +(5,5,12,21,21,25,35,43), +(5,5,13,21,21,26,37,45), +(5,5,14,21,21,26,38,46), +(5,5,15,21,21,26,39,48), +(5,5,16,22,22,27,41,50), +(5,5,17,22,22,27,42,51), +(5,5,18,22,22,28,44,53), +(5,5,19,22,23,28,46,54), +(5,5,20,22,23,29,47,56), +(5,5,21,23,23,29,49,57), +(5,5,22,23,23,30,50,59), +(5,5,23,23,24,30,52,61), +(5,5,24,23,24,31,53,62), +(5,5,25,24,24,31,55,64), +(5,5,26,24,25,32,57,66), +(5,5,27,24,25,32,58,68), +(5,5,28,24,25,33,60,69), +(5,5,29,25,26,33,62,71), +(5,5,30,25,26,34,63,73), +(5,5,31,25,26,34,65,75), +(5,5,32,25,27,35,67,76), +(5,5,33,26,27,35,69,78), +(5,5,34,26,27,36,70,80), +(5,5,35,26,28,36,72,82), +(5,5,36,26,28,37,74,84), +(5,5,37,27,28,37,76,86), +(5,5,38,27,29,38,77,87), +(5,5,39,27,29,38,79,89), +(5,5,40,28,30,39,81,91), +(5,5,41,28,30,40,83,93), +(5,5,42,28,30,40,85,95), +(5,5,43,28,31,41,87,97), +(5,5,44,29,31,41,89,99), +(5,5,45,29,32,42,91,101), +(5,5,46,29,32,43,92,103), +(5,5,47,30,32,43,94,105), +(5,5,48,30,33,44,96,107), +(5,5,49,30,33,44,98,109), +(5,5,50,31,34,45,100,111), +(5,5,51,31,34,46,102,113), +(5,5,52,31,35,46,104,115), +(5,5,53,32,35,47,106,118), +(5,5,54,32,35,48,108,120), +(5,5,55,32,36,48,110,122), +(5,5,56,33,36,49,113,124), +(5,5,57,33,37,50,115,126), +(5,5,58,33,37,50,117,128), +(5,5,59,34,38,51,119,131), +(5,5,60,34,38,52,121,133), +(5,5,61,34,39,52,123,135), +(5,5,62,35,39,53,125,137), +(5,5,63,35,40,54,127,140), +(5,5,64,36,40,55,130,142), +(5,5,65,36,41,55,132,144), +(5,5,66,36,41,56,134,147), +(5,5,67,37,41,57,136,149), +(5,5,68,37,42,58,138,151), +(5,5,69,38,42,58,141,154), +(5,5,70,38,43,59,143,156), +(5,8,1,19,18,21,21,27), +(5,8,2,19,18,21,22,28), +(5,8,3,19,18,22,24,30), +(5,8,4,19,18,22,25,31), +(5,8,5,19,19,22,26,32), +(5,8,6,19,19,22,28,34), +(5,8,7,20,19,23,29,35), +(5,8,8,20,19,23,31,36), +(5,8,9,20,19,23,32,38), +(5,8,10,20,19,24,34,39), +(5,8,11,20,20,24,35,40), +(5,8,12,20,20,24,37,42), +(5,8,13,20,20,25,38,43), +(5,8,14,20,20,25,40,45), +(5,8,15,20,20,25,41,46), +(5,8,16,21,21,26,43,48), +(5,8,17,21,21,26,44,49), +(5,8,18,21,21,26,46,51), +(5,8,19,21,21,27,48,52), +(5,8,20,21,21,27,49,54), +(5,8,21,21,22,27,51,55), +(5,8,22,21,22,28,52,57), +(5,8,23,21,22,28,54,58), +(5,8,24,22,22,29,56,60), +(5,8,25,22,23,29,57,62), +(5,8,26,22,23,29,59,63), +(5,8,27,22,23,30,61,65), +(5,8,28,22,23,30,63,67), +(5,8,29,22,24,31,64,68), +(5,8,30,23,24,31,66,70), +(5,8,31,23,24,31,68,72), +(5,8,32,23,24,32,70,73), +(5,8,33,23,25,32,72,75), +(5,8,34,23,25,33,73,77), +(5,8,35,24,25,33,75,79), +(5,8,36,24,25,34,77,80), +(5,8,37,24,26,34,79,82), +(5,8,38,24,26,35,81,84), +(5,8,39,24,26,35,83,86), +(5,8,40,24,27,35,85,88), +(5,8,41,25,27,36,87,90), +(5,8,42,25,27,36,89,91), +(5,8,43,25,27,37,90,93), +(5,8,44,25,28,37,92,95), +(5,8,45,26,28,38,94,97), +(5,8,46,26,28,38,96,99), +(5,8,47,26,29,39,98,101), +(5,8,48,26,29,39,100,103), +(5,8,49,26,29,40,103,105), +(5,8,50,27,30,40,105,107), +(5,8,51,27,30,41,107,109), +(5,8,52,27,30,42,109,111), +(5,8,53,27,31,42,111,113), +(5,8,54,28,31,43,113,115), +(5,8,55,28,31,43,115,117), +(5,8,56,28,32,44,117,119), +(5,8,57,28,32,44,119,121), +(5,8,58,29,32,45,122,123), +(5,8,59,29,33,45,124,126), +(5,8,60,29,33,46,126,128), +(5,8,61,29,34,47,128,130), +(5,8,62,30,34,47,131,132), +(5,8,63,30,34,48,133,134), +(5,8,64,30,35,48,135,136), +(5,8,65,31,35,49,137,139), +(5,8,66,31,35,50,140,141), +(5,8,67,31,36,50,142,143), +(5,8,68,31,36,51,144,145), +(5,8,69,32,37,51,147,148), +(5,8,70,32,37,52,149,150), +(5,9,1,19,18,22,20,27), +(5,9,2,19,18,23,21,28), +(5,9,3,20,19,23,22,29), +(5,9,4,20,19,24,24,30), +(5,9,5,20,19,24,25,32), +(5,9,6,20,20,25,26,33), +(5,9,7,21,20,25,27,34), +(5,9,8,21,21,26,28,35), +(5,9,9,21,21,26,30,36), +(5,9,10,22,21,27,31,38), +(5,9,11,22,22,28,32,39), +(5,9,12,22,22,28,34,40), +(5,9,13,23,23,29,35,41), +(5,9,14,23,23,30,36,43), +(5,9,15,23,24,30,37,44), +(5,9,16,24,24,31,39,45), +(5,9,17,24,24,31,40,47), +(5,9,18,24,25,32,42,48), +(5,9,19,25,25,33,43,49), +(5,9,20,25,26,33,44,51), +(5,9,21,26,26,34,46,52), +(5,9,22,26,27,35,47,53), +(5,9,23,26,27,36,49,55), +(5,9,24,27,28,36,50,56), +(5,9,25,27,28,37,52,58), +(5,9,26,27,29,38,53,59), +(5,9,27,28,29,38,55,60), +(5,9,28,28,30,39,56,62), +(5,9,29,29,30,40,58,63), +(5,9,30,29,31,41,59,65), +(5,9,31,30,31,41,61,66), +(5,9,32,30,32,42,62,68), +(5,9,33,30,32,43,64,69), +(5,9,34,31,33,44,65,71), +(5,9,35,31,33,45,67,73), +(5,9,36,32,34,45,69,74), +(5,9,37,32,34,46,70,76), +(5,9,38,33,35,47,72,77), +(5,9,39,33,36,48,73,79), +(5,9,40,34,36,49,75,81), +(5,9,41,34,37,49,77,82), +(5,9,42,35,37,50,78,84), +(5,9,43,35,38,51,80,86), +(5,9,44,36,39,52,82,87), +(5,9,45,36,39,53,84,89), +(5,9,46,37,40,54,85,91), +(5,9,47,37,40,55,87,92), +(5,9,48,38,41,55,89,94), +(5,9,49,38,42,56,91,96), +(5,9,50,39,42,57,92,98), +(5,9,51,39,43,58,94,100), +(5,9,52,40,44,59,96,101), +(5,9,53,40,44,60,98,103), +(5,9,54,41,45,61,100,105), +(5,9,55,41,45,62,102,107), +(5,9,56,42,46,63,103,109), +(5,9,57,42,47,64,105,111), +(5,9,58,43,47,65,107,112), +(5,9,59,43,48,66,109,114), +(5,9,60,44,49,67,111,116), +(5,9,61,45,50,68,113,118), +(5,9,62,45,50,69,115,120), +(5,9,63,46,51,70,117,122), +(5,9,64,46,52,71,119,124), +(5,9,65,47,52,72,121,126), +(5,9,66,48,53,73,123,128), +(5,9,67,48,54,74,125,130), +(5,9,68,49,55,75,127,132), +(5,9,69,49,55,76,129,134), +(5,9,70,50,56,77,131,136), +(6,1,1,28,15,24,15,22), +(6,1,2,29,16,25,15,22), +(6,1,3,31,17,26,15,23), +(6,1,4,32,17,27,15,23), +(6,1,5,33,18,29,15,23), +(6,1,6,34,19,30,15,23), +(6,1,7,36,20,31,16,24), +(6,1,8,37,21,32,16,24), +(6,1,9,38,22,34,16,24), +(6,1,10,40,22,35,16,25), +(6,1,11,41,23,36,16,25), +(6,1,12,43,24,37,16,25), +(6,1,13,44,25,39,16,26), +(6,1,14,46,26,40,16,26), +(6,1,15,47,27,41,17,26), +(6,1,16,48,28,43,17,27), +(6,1,17,50,29,44,17,27), +(6,1,18,51,30,45,17,27), +(6,1,19,53,31,47,17,28), +(6,1,20,54,32,48,17,28), +(6,1,21,56,33,50,17,28), +(6,1,22,58,34,51,18,29), +(6,1,23,59,35,52,18,29), +(6,1,24,61,36,54,18,30), +(6,1,25,62,37,55,18,30), +(6,1,26,64,38,57,18,30), +(6,1,27,66,39,58,18,31), +(6,1,28,67,40,60,18,31), +(6,1,29,69,41,61,19,32), +(6,1,30,71,42,63,19,32), +(6,1,31,72,43,64,19,32), +(6,1,32,74,44,66,19,33), +(6,1,33,76,45,67,19,33), +(6,1,34,77,46,69,20,34), +(6,1,35,79,47,71,20,34), +(6,1,36,81,48,72,20,35), +(6,1,37,83,49,74,20,35), +(6,1,38,85,50,76,20,35), +(6,1,39,86,51,77,21,36), +(6,1,40,88,53,79,21,36), +(6,1,41,90,54,81,21,37), +(6,1,42,92,55,82,21,37), +(6,1,43,94,56,84,21,38), +(6,1,44,96,57,86,22,38), +(6,1,45,98,58,87,22,39), +(6,1,46,99,60,89,22,39), +(6,1,47,101,61,91,22,40), +(6,1,48,103,62,93,22,40), +(6,1,49,105,63,94,23,41), +(6,1,50,107,65,96,23,41), +(6,1,51,109,66,98,23,42), +(6,1,52,111,67,100,23,42), +(6,1,53,113,68,102,24,43), +(6,1,54,115,70,104,24,44), +(6,1,55,117,71,105,24,44), +(6,1,56,119,72,107,24,45), +(6,1,57,122,73,109,25,45), +(6,1,58,124,75,111,25,46), +(6,1,59,126,76,113,25,46), +(6,1,60,128,77,115,25,47), +(6,1,61,130,79,117,26,48), +(6,1,62,132,80,119,26,48), +(6,1,63,134,81,121,26,49), +(6,1,64,137,83,123,26,49), +(6,1,65,139,84,125,27,50), +(6,1,66,141,85,127,27,51), +(6,1,67,143,87,129,27,51), +(6,1,68,145,88,131,27,52), +(6,1,69,148,90,133,28,52), +(6,1,70,150,91,135,28,53), +(6,3,1,25,18,23,15,23), +(6,3,2,25,19,24,16,24), +(6,3,3,26,21,25,16,24), +(6,3,4,26,22,26,17,25), +(6,3,5,27,24,27,17,25), +(6,3,6,27,25,28,18,26), +(6,3,7,28,26,28,19,27), +(6,3,8,28,28,29,19,27), +(6,3,9,28,29,30,20,28), +(6,3,10,29,31,31,20,29), +(6,3,11,29,32,32,21,29), +(6,3,12,30,34,33,22,30), +(6,3,13,30,35,34,22,31), +(6,3,14,31,37,35,23,32), +(6,3,15,31,38,36,24,32), +(6,3,16,32,40,37,24,33), +(6,3,17,32,41,39,25,34), +(6,3,18,33,43,40,26,35), +(6,3,19,33,45,41,27,35), +(6,3,20,34,46,42,27,36), +(6,3,21,34,48,43,28,37), +(6,3,22,35,50,44,29,38), +(6,3,23,35,51,45,29,38), +(6,3,24,36,53,46,30,39), +(6,3,25,37,55,47,31,40), +(6,3,26,37,56,48,32,41), +(6,3,27,38,58,50,32,42), +(6,3,28,38,60,51,33,42), +(6,3,29,39,62,52,34,43), +(6,3,30,39,63,53,35,44), +(6,3,31,40,65,54,36,45), +(6,3,32,41,67,56,36,46), +(6,3,33,41,69,57,37,47), +(6,3,34,42,71,58,38,48), +(6,3,35,43,72,59,39,48), +(6,3,36,43,74,61,40,49), +(6,3,37,44,76,62,40,50), +(6,3,38,45,78,63,41,51), +(6,3,39,45,80,64,42,52), +(6,3,40,46,82,66,43,53), +(6,3,41,47,84,67,44,54), +(6,3,42,47,86,68,45,55), +(6,3,43,48,88,70,46,56), +(6,3,44,49,90,71,46,57), +(6,3,45,49,92,72,47,58), +(6,3,46,50,94,74,48,59), +(6,3,47,51,96,75,49,60), +(6,3,48,51,98,77,50,61), +(6,3,49,52,100,78,51,62), +(6,3,50,53,102,79,52,63), +(6,3,51,54,104,81,53,64), +(6,3,52,54,106,82,54,65), +(6,3,53,55,108,84,55,66), +(6,3,54,56,110,85,56,67), +(6,3,55,57,112,87,57,68), +(6,3,56,57,114,88,58,69), +(6,3,57,58,117,90,59,70), +(6,3,58,59,119,91,60,71), +(6,3,59,60,121,93,61,72), +(6,3,60,61,123,94,62,74), +(6,3,61,61,125,96,63,75), +(6,3,62,62,128,97,64,76), +(6,3,63,63,130,99,65,77), +(6,3,64,64,132,100,66,78), +(6,3,65,65,134,102,67,79), +(6,3,66,66,137,104,68,80), +(6,3,67,66,139,105,69,81), +(6,3,68,67,141,107,70,83), +(6,3,69,68,144,108,71,84), +(6,3,70,69,146,110,72,85), +(6,7,1,26,15,23,16,24), +(6,7,2,27,15,24,17,25), +(6,7,3,28,16,25,18,26), +(6,7,4,28,16,26,19,27), +(6,7,5,29,17,27,20,28), +(6,7,6,30,17,28,21,29), +(6,7,7,31,18,29,22,30), +(6,7,8,32,18,30,23,31), +(6,7,9,33,19,31,24,32), +(6,7,10,34,19,32,25,33), +(6,7,11,35,20,33,26,35), +(6,7,12,35,20,34,27,36), +(6,7,13,36,21,35,28,37), +(6,7,14,37,21,36,29,38), +(6,7,15,38,22,37,30,39), +(6,7,16,39,22,39,31,40), +(6,7,17,40,23,40,32,42), +(6,7,18,41,23,41,33,43), +(6,7,19,42,24,42,34,44), +(6,7,20,43,24,43,35,45), +(6,7,21,44,25,44,36,46), +(6,7,22,45,25,45,37,48), +(6,7,23,46,26,47,38,49), +(6,7,24,47,27,48,40,50), +(6,7,25,48,27,49,41,51), +(6,7,26,49,28,50,42,53), +(6,7,27,51,28,52,43,54), +(6,7,28,52,29,53,44,55), +(6,7,29,53,29,54,45,57), +(6,7,30,54,30,55,47,58), +(6,7,31,55,31,57,48,59), +(6,7,32,56,31,58,49,61), +(6,7,33,57,32,59,50,62), +(6,7,34,58,33,61,51,64), +(6,7,35,60,33,62,53,65), +(6,7,36,61,34,63,54,66), +(6,7,37,62,34,65,55,68), +(6,7,38,63,35,66,57,69), +(6,7,39,64,36,67,58,71), +(6,7,40,66,36,69,59,72), +(6,7,41,67,37,70,60,74), +(6,7,42,68,38,72,62,75), +(6,7,43,69,38,73,63,77), +(6,7,44,70,39,74,64,78), +(6,7,45,72,40,76,66,80), +(6,7,46,73,41,77,67,81), +(6,7,47,74,41,79,69,83), +(6,7,48,76,42,80,70,84), +(6,7,49,77,43,82,71,86), +(6,7,50,78,43,83,73,88), +(6,7,51,80,44,85,74,89), +(6,7,52,81,45,86,76,91), +(6,7,53,82,46,88,77,92), +(6,7,54,84,46,90,78,94), +(6,7,55,85,47,91,80,96), +(6,7,56,86,48,93,81,97), +(6,7,57,88,49,94,83,99), +(6,7,58,89,49,96,84,101), +(6,7,59,91,50,97,86,102), +(6,7,60,92,51,99,87,104), +(6,7,61,94,52,101,89,106), +(6,7,62,95,52,102,90,108), +(6,7,63,96,53,104,92,109), +(6,7,64,98,54,106,93,111), +(6,7,65,99,55,107,95,113), +(6,7,66,101,56,109,97,115), +(6,7,67,102,57,111,98,117), +(6,7,68,104,57,113,100,118), +(6,7,69,105,58,114,101,120), +(6,7,70,107,59,116,103,122), +(6,11,1,26,15,22,17,24), +(6,11,2,27,16,23,18,25), +(6,11,3,27,16,23,19,26), +(6,11,4,28,17,24,20,27), +(6,11,5,28,17,25,21,29), +(6,11,6,29,18,25,22,30), +(6,11,7,29,18,26,23,31), +(6,11,8,30,19,27,24,32), +(6,11,9,30,19,27,26,34), +(6,11,10,31,20,28,27,35), +(6,11,11,32,20,29,28,36), +(6,11,12,32,21,29,29,37), +(6,11,13,33,21,30,30,39), +(6,11,14,33,22,31,31,40), +(6,11,15,34,23,32,32,41), +(6,11,16,35,23,32,34,43), +(6,11,17,35,24,33,35,44), +(6,11,18,36,24,34,36,45), +(6,11,19,37,25,35,37,47), +(6,11,20,37,26,35,39,48), +(6,11,21,38,26,36,40,50), +(6,11,22,39,27,37,41,51), +(6,11,23,39,28,38,42,52), +(6,11,24,40,28,39,44,54), +(6,11,25,41,29,39,45,55), +(6,11,26,41,30,40,46,57), +(6,11,27,42,30,41,47,58), +(6,11,28,43,31,42,49,60), +(6,11,29,44,32,43,50,61), +(6,11,30,44,32,44,52,63), +(6,11,31,45,33,44,53,64), +(6,11,32,46,34,45,54,66), +(6,11,33,47,34,46,56,67), +(6,11,34,47,35,47,57,69), +(6,11,35,48,36,48,58,71), +(6,11,36,49,36,49,60,72), +(6,11,37,50,37,50,61,74), +(6,11,38,51,38,51,63,76), +(6,11,39,52,39,52,64,77), +(6,11,40,52,39,53,66,79), +(6,11,41,53,40,54,67,81), +(6,11,42,54,41,55,69,82), +(6,11,43,55,42,56,70,84), +(6,11,44,56,43,57,72,86), +(6,11,45,57,43,57,73,87), +(6,11,46,57,44,58,75,89), +(6,11,47,58,45,60,76,91), +(6,11,48,59,46,61,78,93), +(6,11,49,60,47,62,79,94), +(6,11,50,61,47,63,81,96), +(6,11,51,62,48,64,83,98), +(6,11,52,63,49,65,84,100), +(6,11,53,64,50,66,86,102), +(6,11,54,65,51,67,87,104), +(6,11,55,66,51,68,89,105), +(6,11,56,67,52,69,91,107), +(6,11,57,68,53,70,92,109), +(6,11,58,69,54,71,94,111), +(6,11,59,70,55,72,96,113), +(6,11,60,71,56,73,97,115), +(6,11,61,72,57,74,99,117), +(6,11,62,73,58,76,101,119), +(6,11,63,74,59,77,103,121), +(6,11,64,75,59,78,104,123), +(6,11,65,76,60,79,106,125), +(6,11,66,77,61,80,108,127), +(6,11,67,78,62,81,110,129), +(6,11,68,79,63,83,111,131), +(6,11,69,80,64,84,113,133), +(6,11,70,81,65,85,115,135), +(7,1,1,18,23,21,24,20), +(7,1,2,19,24,22,24,20), +(7,1,3,21,25,23,24,21), +(7,1,4,22,25,25,24,21), +(7,1,5,23,26,26,24,21), +(7,1,6,25,27,27,24,21), +(7,1,7,26,28,28,24,22), +(7,1,8,27,29,29,25,22), +(7,1,9,29,29,31,25,22), +(7,1,10,30,30,32,25,23), +(7,1,11,32,31,33,25,23), +(7,1,12,33,32,34,25,23), +(7,1,13,34,33,36,25,24), +(7,1,14,36,34,37,25,24), +(7,1,15,37,35,38,25,24), +(7,1,16,39,36,40,25,25), +(7,1,17,40,36,41,25,25), +(7,1,18,42,37,43,26,25), +(7,1,19,43,38,44,26,26), +(7,1,20,45,39,45,26,26), +(7,1,21,47,40,47,26,26), +(7,1,22,48,41,48,26,27), +(7,1,23,50,42,50,26,27), +(7,1,24,51,43,51,26,28), +(7,1,25,53,44,52,27,28), +(7,1,26,55,45,54,27,28), +(7,1,27,56,46,55,27,29), +(7,1,28,58,47,57,27,29), +(7,1,29,59,48,58,27,30), +(7,1,30,61,49,60,27,30), +(7,1,31,63,50,62,27,30), +(7,1,32,65,51,63,28,31), +(7,1,33,66,52,65,28,31), +(7,1,34,68,53,66,28,32), +(7,1,35,70,55,68,28,32), +(7,1,36,72,56,69,28,33), +(7,1,37,73,57,71,29,33), +(7,1,38,75,58,73,29,34), +(7,1,39,77,59,74,29,34), +(7,1,40,79,60,76,29,35), +(7,1,41,81,61,78,29,35), +(7,1,42,82,62,79,30,35), +(7,1,43,84,64,81,30,36), +(7,1,44,86,65,83,30,36), +(7,1,45,88,66,85,30,37), +(7,1,46,90,67,86,30,37), +(7,1,47,92,68,88,31,38), +(7,1,48,94,70,90,31,38), +(7,1,49,96,71,92,31,39), +(7,1,50,98,72,93,31,40), +(7,1,51,100,73,95,32,40), +(7,1,52,102,75,97,32,41), +(7,1,53,104,76,99,32,41), +(7,1,54,106,77,101,32,42), +(7,1,55,108,78,103,33,42), +(7,1,56,110,80,104,33,43), +(7,1,57,112,81,106,33,43), +(7,1,58,114,82,108,33,44), +(7,1,59,116,84,110,34,44), +(7,1,60,118,85,112,34,45), +(7,1,61,120,86,114,34,46), +(7,1,62,122,88,116,35,46), +(7,1,63,125,89,118,35,47), +(7,1,64,127,91,120,35,47), +(7,1,65,129,92,122,35,48), +(7,1,66,131,93,124,36,49), +(7,1,67,133,95,126,36,49), +(7,1,68,136,96,128,36,50), +(7,1,69,138,98,130,37,50), +(7,1,70,140,99,132,37,51), +(7,4,1,16,26,20,24,20), +(7,4,2,17,27,21,24,20), +(7,4,3,18,29,21,24,21), +(7,4,4,18,30,22,24,21), +(7,4,5,19,32,23,25,21), +(7,4,6,20,33,24,25,22), +(7,4,7,21,35,24,25,22), +(7,4,8,22,36,25,25,23), +(7,4,9,22,38,26,25,23), +(7,4,10,23,39,26,25,23), +(7,4,11,24,41,27,25,24), +(7,4,12,25,42,28,26,24), +(7,4,13,26,44,29,26,25), +(7,4,14,27,46,30,26,25), +(7,4,15,28,47,30,26,25), +(7,4,16,28,49,31,26,26), +(7,4,17,29,50,32,27,26), +(7,4,18,30,52,33,27,27), +(7,4,19,31,54,34,27,27), +(7,4,20,32,56,35,27,28), +(7,4,21,33,57,35,27,28), +(7,4,22,34,59,36,28,29), +(7,4,23,35,61,37,28,29), +(7,4,24,36,62,38,28,30), +(7,4,25,37,64,39,28,30), +(7,4,26,38,66,40,29,31), +(7,4,27,39,68,41,29,31), +(7,4,28,40,70,42,29,32), +(7,4,29,41,72,43,29,32), +(7,4,30,42,73,43,29,33), +(7,4,31,43,75,44,30,33), +(7,4,32,44,77,45,30,34), +(7,4,33,45,79,46,30,34), +(7,4,34,46,81,47,31,35), +(7,4,35,47,83,48,31,35), +(7,4,36,48,85,49,31,36), +(7,4,37,49,87,50,31,36), +(7,4,38,50,89,51,32,37), +(7,4,39,51,91,52,32,38), +(7,4,40,53,93,53,32,38), +(7,4,41,54,95,54,33,39), +(7,4,42,55,97,55,33,39), +(7,4,43,56,99,56,33,40), +(7,4,44,57,101,57,33,40), +(7,4,45,58,103,59,34,41), +(7,4,46,59,105,60,34,42), +(7,4,47,61,107,61,34,42), +(7,4,48,62,110,62,35,43), +(7,4,49,63,112,63,35,44), +(7,4,50,64,114,64,35,44), +(7,4,51,65,116,65,36,45), +(7,4,52,67,118,66,36,45), +(7,4,53,68,121,67,36,46), +(7,4,54,69,123,69,37,47), +(7,4,55,70,125,70,37,47), +(7,4,56,72,127,71,37,48), +(7,4,57,73,130,72,38,49), +(7,4,58,74,132,73,38,49), +(7,4,59,75,134,74,39,50), +(7,4,60,77,137,76,39,51), +(7,4,61,78,139,77,39,51), +(7,4,62,79,141,78,40,52), +(7,4,63,81,144,79,40,53), +(7,4,64,82,146,80,41,54), +(7,4,65,83,149,82,41,54), +(7,4,66,85,151,83,41,55), +(7,4,67,86,154,84,42,56), +(7,4,68,87,156,85,42,57), +(7,4,69,89,158,87,43,57), +(7,4,70,90,161,88,43,58), +(7,8,1,15,23,19,27,22), +(7,8,2,15,23,19,28,23), +(7,8,3,15,23,20,30,25), +(7,8,4,15,23,20,31,26), +(7,8,5,15,24,20,32,27), +(7,8,6,15,24,20,34,29), +(7,8,7,16,24,21,35,30), +(7,8,8,16,24,21,37,31), +(7,8,9,16,24,21,38,33), +(7,8,10,16,24,22,40,34), +(7,8,11,16,25,22,41,36), +(7,8,12,16,25,22,42,37), +(7,8,13,16,25,23,44,38), +(7,8,14,16,25,23,45,40), +(7,8,15,17,25,23,47,41), +(7,8,16,17,25,24,49,43), +(7,8,17,17,26,24,50,44), +(7,8,18,17,26,24,52,46), +(7,8,19,17,26,25,53,47), +(7,8,20,17,26,25,55,49), +(7,8,21,17,26,26,57,51), +(7,8,22,18,27,26,58,52), +(7,8,23,18,27,26,60,54), +(7,8,24,18,27,27,61,55), +(7,8,25,18,27,27,63,57), +(7,8,26,18,28,27,65,59), +(7,8,27,18,28,28,67,60), +(7,8,28,18,28,28,68,62), +(7,8,29,19,28,29,70,64), +(7,8,30,19,29,29,72,65), +(7,8,31,19,29,30,74,67), +(7,8,32,19,29,30,75,69), +(7,8,33,19,29,30,77,70), +(7,8,34,20,30,31,79,72), +(7,8,35,20,30,31,81,74), +(7,8,36,20,30,32,83,76), +(7,8,37,20,30,32,85,78), +(7,8,38,20,31,33,86,79), +(7,8,39,21,31,33,88,81), +(7,8,40,21,31,34,90,83), +(7,8,41,21,32,34,92,85), +(7,8,42,21,32,35,94,87), +(7,8,43,21,32,35,96,89), +(7,8,44,22,32,36,98,91), +(7,8,45,22,33,36,100,92), +(7,8,46,22,33,37,102,94), +(7,8,47,22,33,37,104,96), +(7,8,48,22,34,38,106,98), +(7,8,49,23,34,38,108,100), +(7,8,50,23,34,39,110,102), +(7,8,51,23,35,39,112,104), +(7,8,52,23,35,40,114,106), +(7,8,53,24,35,40,117,108), +(7,8,54,24,36,41,119,110), +(7,8,55,24,36,41,121,112), +(7,8,56,24,37,42,123,114), +(7,8,57,25,37,42,125,117), +(7,8,58,25,37,43,127,119), +(7,8,59,25,38,43,130,121), +(7,8,60,25,38,44,132,123), +(7,8,61,26,38,45,134,125), +(7,8,62,26,39,45,136,127), +(7,8,63,26,39,46,139,129), +(7,8,64,26,40,46,141,132), +(7,8,65,27,40,47,143,134), +(7,8,66,27,40,48,146,136), +(7,8,67,27,41,48,148,138), +(7,8,68,27,41,49,150,140), +(7,8,69,28,42,49,153,143), +(7,8,70,28,42,50,155,145), +(7,9,1,15,23,20,26,22), +(7,9,2,15,23,21,27,23), +(7,9,3,16,24,21,28,24), +(7,9,4,16,24,22,29,25), +(7,9,5,16,24,22,31,27), +(7,9,6,17,25,23,32,28), +(7,9,7,17,25,23,33,29), +(7,9,8,17,26,24,34,30), +(7,9,9,17,26,25,36,31), +(7,9,10,18,26,25,37,33), +(7,9,11,18,27,26,38,34), +(7,9,12,18,27,26,39,35), +(7,9,13,19,28,27,41,36), +(7,9,14,19,28,28,42,38), +(7,9,15,20,28,28,43,39), +(7,9,16,20,29,29,45,40), +(7,9,17,20,29,30,46,42), +(7,9,18,21,30,30,47,43), +(7,9,19,21,30,31,49,44), +(7,9,20,21,31,32,50,46), +(7,9,21,22,31,32,51,47), +(7,9,22,22,31,33,53,49), +(7,9,23,23,32,34,54,50), +(7,9,24,23,32,34,56,51), +(7,9,25,23,33,35,57,53), +(7,9,26,24,33,36,59,54), +(7,9,27,24,34,37,60,56), +(7,9,28,25,34,37,62,57), +(7,9,29,25,35,38,63,59), +(7,9,30,25,35,39,65,60), +(7,9,31,26,36,40,66,62), +(7,9,32,26,36,40,68,63), +(7,9,33,27,37,41,69,65), +(7,9,34,27,38,42,71,66), +(7,9,35,28,38,43,73,68), +(7,9,36,28,39,43,74,69), +(7,9,37,28,39,44,76,71), +(7,9,38,29,40,45,77,73), +(7,9,39,29,40,46,79,74), +(7,9,40,30,41,47,81,76), +(7,9,41,30,41,48,82,78), +(7,9,42,31,42,48,84,79), +(7,9,43,31,43,49,86,81), +(7,9,44,32,43,50,88,83), +(7,9,45,32,44,51,89,84), +(7,9,46,33,44,52,91,86), +(7,9,47,33,45,53,93,88), +(7,9,48,34,46,54,95,89), +(7,9,49,34,46,54,96,91), +(7,9,50,35,47,55,98,93), +(7,9,51,35,48,56,100,95), +(7,9,52,36,48,57,102,97), +(7,9,53,36,49,58,104,98), +(7,9,54,37,50,59,105,100), +(7,9,55,37,50,60,107,102), +(7,9,56,38,51,61,109,104), +(7,9,57,38,52,62,111,106), +(7,9,58,39,52,63,113,108), +(7,9,59,40,53,64,115,109), +(7,9,60,40,54,65,117,111), +(7,9,61,41,54,66,119,113), +(7,9,62,41,55,67,121,115), +(7,9,63,42,56,68,123,117), +(7,9,64,42,57,69,125,119), +(7,9,65,43,57,70,127,121), +(7,9,66,44,58,71,129,123), +(7,9,67,44,59,72,131,125), +(7,9,68,45,59,73,133,127), +(7,9,69,45,60,74,135,129), +(7,9,70,46,61,75,137,131), +(8,1,1,24,22,23,16,21), +(8,1,2,25,23,24,16,21), +(8,1,3,27,24,25,16,22), +(8,1,4,28,24,26,16,22), +(8,1,5,29,25,28,16,22), +(8,1,6,31,26,29,16,22), +(8,1,7,32,27,30,17,23), +(8,1,8,33,28,31,17,23), +(8,1,9,35,28,33,17,23), +(8,1,10,36,29,34,17,24), +(8,1,11,37,30,35,17,24), +(8,1,12,39,31,36,17,24), +(8,1,13,40,32,38,17,25), +(8,1,14,42,33,39,17,25), +(8,1,15,43,34,40,18,25), +(8,1,16,45,35,42,18,26), +(8,1,17,46,35,43,18,26), +(8,1,18,48,36,44,18,26), +(8,1,19,49,37,46,18,27), +(8,1,20,51,38,47,18,27), +(8,1,21,52,39,49,18,27), +(8,1,22,54,40,50,18,28), +(8,1,23,55,41,51,19,28), +(8,1,24,57,42,53,19,29), +(8,1,25,59,43,54,19,29), +(8,1,26,60,44,56,19,29), +(8,1,27,62,45,57,19,30), +(8,1,28,63,46,59,19,30), +(8,1,29,65,47,60,20,31), +(8,1,30,67,48,62,20,31), +(8,1,31,69,49,63,20,31), +(8,1,32,70,50,65,20,32), +(8,1,33,72,51,67,20,32), +(8,1,34,74,53,68,20,33), +(8,1,35,75,54,70,21,33), +(8,1,36,77,55,71,21,34), +(8,1,37,79,56,73,21,34), +(8,1,38,81,57,75,21,35), +(8,1,39,83,58,76,21,35), +(8,1,40,84,59,78,22,35), +(8,1,41,86,60,80,22,36), +(8,1,42,88,62,81,22,36), +(8,1,43,90,63,83,22,37), +(8,1,44,92,64,85,22,37), +(8,1,45,94,65,86,23,38), +(8,1,46,96,66,88,23,38), +(8,1,47,98,67,90,23,39), +(8,1,48,100,69,92,23,39), +(8,1,49,102,70,93,24,40), +(8,1,50,103,71,95,24,40), +(8,1,51,105,72,97,24,41), +(8,1,52,107,74,99,24,42), +(8,1,53,109,75,101,25,42), +(8,1,54,112,76,103,25,43), +(8,1,55,114,78,104,25,43), +(8,1,56,116,79,106,25,44), +(8,1,57,118,80,108,25,44), +(8,1,58,120,81,110,26,45), +(8,1,59,122,83,112,26,45), +(8,1,60,124,84,114,26,46), +(8,1,61,126,85,116,27,47), +(8,1,62,128,87,118,27,47), +(8,1,63,130,88,120,27,48), +(8,1,64,133,90,122,27,48), +(8,1,65,135,91,124,28,49), +(8,1,66,137,92,126,28,50), +(8,1,67,139,94,128,28,50), +(8,1,68,141,95,130,28,51), +(8,1,69,144,97,132,29,51), +(8,1,70,146,98,134,29,52), +(8,3,1,21,25,22,16,22), +(8,3,2,21,26,23,17,23), +(8,3,3,22,28,24,17,23), +(8,3,4,22,29,25,18,24), +(8,3,5,23,30,26,18,25), +(8,3,6,23,32,27,19,25), +(8,3,7,24,33,28,20,26), +(8,3,8,24,35,28,20,26), +(8,3,9,25,36,29,21,27), +(8,3,10,25,38,30,21,28), +(8,3,11,25,39,31,22,29), +(8,3,12,26,41,32,23,29), +(8,3,13,26,42,33,23,30), +(8,3,14,27,44,34,24,31), +(8,3,15,27,45,35,25,31), +(8,3,16,28,47,36,25,32), +(8,3,17,28,48,38,26,33), +(8,3,18,29,50,39,27,34), +(8,3,19,29,51,40,28,34), +(8,3,20,30,53,41,28,35), +(8,3,21,31,55,42,29,36), +(8,3,22,31,56,43,30,37), +(8,3,23,32,58,44,30,37), +(8,3,24,32,60,45,31,38), +(8,3,25,33,61,46,32,39), +(8,3,26,33,63,48,33,40), +(8,3,27,34,65,49,33,41), +(8,3,28,35,66,50,34,41), +(8,3,29,35,68,51,35,42), +(8,3,30,36,70,52,36,43), +(8,3,31,36,72,53,37,44), +(8,3,32,37,73,55,37,45), +(8,3,33,38,75,56,38,46), +(8,3,34,38,77,57,39,47), +(8,3,35,39,79,58,40,48), +(8,3,36,39,81,60,41,48), +(8,3,37,40,83,61,41,49), +(8,3,38,41,85,62,42,50), +(8,3,39,41,86,63,43,51), +(8,3,40,42,88,65,44,52), +(8,3,41,43,90,66,45,53), +(8,3,42,43,92,67,46,54), +(8,3,43,44,94,69,47,55), +(8,3,44,45,96,70,47,56), +(8,3,45,45,98,71,48,57), +(8,3,46,46,100,73,49,58), +(8,3,47,47,102,74,50,59), +(8,3,48,48,104,76,51,60), +(8,3,49,48,106,77,52,61), +(8,3,50,49,108,78,53,62), +(8,3,51,50,110,80,54,63), +(8,3,52,51,113,81,55,64), +(8,3,53,51,115,83,56,65), +(8,3,54,52,117,84,57,66), +(8,3,55,53,119,86,58,67), +(8,3,56,54,121,87,59,68), +(8,3,57,54,123,89,60,69), +(8,3,58,55,126,90,61,70), +(8,3,59,56,128,92,62,71), +(8,3,60,57,130,93,63,73), +(8,3,61,58,132,95,64,74), +(8,3,62,58,134,96,65,75), +(8,3,63,59,137,98,66,76), +(8,3,64,60,139,99,67,77), +(8,3,65,61,141,101,68,78), +(8,3,66,62,144,103,69,79), +(8,3,67,62,146,104,70,80), +(8,3,68,63,148,106,71,82), +(8,3,69,64,151,107,72,83), +(8,3,70,65,153,109,73,84), +(8,4,1,22,25,22,16,21), +(8,4,2,23,26,23,16,21), +(8,4,3,24,28,23,16,22), +(8,4,4,24,29,24,16,22), +(8,4,5,25,31,25,17,22), +(8,4,6,26,32,25,17,23), +(8,4,7,27,34,26,17,23), +(8,4,8,27,35,27,17,24), +(8,4,9,28,37,28,17,24), +(8,4,10,29,38,28,18,24), +(8,4,11,30,40,29,18,25), +(8,4,12,31,41,30,18,25), +(8,4,13,32,43,31,18,26), +(8,4,14,32,45,32,18,26), +(8,4,15,33,46,32,19,26), +(8,4,16,34,48,33,19,27), +(8,4,17,35,50,34,19,27), +(8,4,18,36,51,35,19,28), +(8,4,19,37,53,36,19,28), +(8,4,20,38,55,36,20,29), +(8,4,21,39,56,37,20,29), +(8,4,22,40,58,38,20,30), +(8,4,23,41,60,39,20,30), +(8,4,24,42,62,40,20,31), +(8,4,25,43,63,41,21,31), +(8,4,26,44,65,42,21,32), +(8,4,27,45,67,43,21,32), +(8,4,28,46,69,44,21,33), +(8,4,29,47,71,44,22,33), +(8,4,30,48,72,45,22,34), +(8,4,31,49,74,46,22,34), +(8,4,32,50,76,47,22,35), +(8,4,33,51,78,48,23,35), +(8,4,34,52,80,49,23,36), +(8,4,35,53,82,50,23,36), +(8,4,36,54,84,51,24,37), +(8,4,37,55,86,52,24,37), +(8,4,38,56,88,53,24,38), +(8,4,39,57,90,54,24,38), +(8,4,40,58,92,55,25,39), +(8,4,41,59,94,56,25,40), +(8,4,42,60,96,57,25,40), +(8,4,43,62,98,58,26,41), +(8,4,44,63,100,59,26,41), +(8,4,45,64,102,60,26,42), +(8,4,46,65,104,61,27,43), +(8,4,47,66,107,63,27,43), +(8,4,48,67,109,64,27,44), +(8,4,49,69,111,65,27,44), +(8,4,50,70,113,66,28,45), +(8,4,51,71,115,67,28,46), +(8,4,52,72,117,68,28,46), +(8,4,53,74,120,69,29,47), +(8,4,54,75,122,70,29,48), +(8,4,55,76,124,72,29,48), +(8,4,56,77,126,73,30,49), +(8,4,57,79,129,74,30,50), +(8,4,58,80,131,75,30,50), +(8,4,59,81,133,76,31,51), +(8,4,60,82,136,77,31,52), +(8,4,61,84,138,79,32,52), +(8,4,62,85,140,80,32,53), +(8,4,63,86,143,81,32,54), +(8,4,64,88,145,82,33,55), +(8,4,65,89,148,84,33,55), +(8,4,66,90,150,85,33,56), +(8,4,67,92,153,86,34,57), +(8,4,68,93,155,87,34,58), +(8,4,69,95,157,89,35,58), +(8,4,70,96,160,90,35,59), +(8,5,1,21,22,21,18,24), +(8,5,2,21,22,21,19,25), +(8,5,3,21,22,22,21,27), +(8,5,4,21,23,22,22,28), +(8,5,5,22,23,22,23,29), +(8,5,6,22,23,23,25,31), +(8,5,7,22,23,23,26,32), +(8,5,8,22,24,24,27,34), +(8,5,9,22,24,24,29,35), +(8,5,10,22,24,24,30,37), +(8,5,11,23,24,25,32,38), +(8,5,12,23,24,25,33,40), +(8,5,13,23,25,26,35,41), +(8,5,14,23,25,26,36,43), +(8,5,15,23,25,26,38,44), +(8,5,16,24,26,27,39,46), +(8,5,17,24,26,27,41,47), +(8,5,18,24,26,28,42,49), +(8,5,19,24,26,28,44,50), +(8,5,20,24,27,29,45,52), +(8,5,21,25,27,29,47,54), +(8,5,22,25,27,30,48,55), +(8,5,23,25,28,30,50,57), +(8,5,24,25,28,31,52,59), +(8,5,25,25,28,31,53,60), +(8,5,26,26,28,32,55,62), +(8,5,27,26,29,32,56,64), +(8,5,28,26,29,33,58,65), +(8,5,29,26,29,33,60,67), +(8,5,30,27,30,34,62,69), +(8,5,31,27,30,34,63,71), +(8,5,32,27,30,35,65,73), +(8,5,33,27,31,35,67,74), +(8,5,34,28,31,36,68,76), +(8,5,35,28,32,36,70,78), +(8,5,36,28,32,37,72,80), +(8,5,37,29,32,37,74,82), +(8,5,38,29,33,38,76,84), +(8,5,39,29,33,38,77,86), +(8,5,40,29,33,39,79,87), +(8,5,41,30,34,40,81,89), +(8,5,42,30,34,40,83,91), +(8,5,43,30,35,41,85,93), +(8,5,44,31,35,41,87,95), +(8,5,45,31,35,42,89,97), +(8,5,46,31,36,43,91,99), +(8,5,47,32,36,43,93,101), +(8,5,48,32,37,44,94,103), +(8,5,49,32,37,44,96,105), +(8,5,50,33,37,45,98,107), +(8,5,51,33,38,46,100,110), +(8,5,52,33,38,46,102,112), +(8,5,53,34,39,47,104,114), +(8,5,54,34,39,48,106,116), +(8,5,55,34,40,48,109,118), +(8,5,56,35,40,49,111,120), +(8,5,57,35,41,50,113,122), +(8,5,58,35,41,50,115,125), +(8,5,59,36,42,51,117,127), +(8,5,60,36,42,52,119,129), +(8,5,61,36,42,52,121,131), +(8,5,62,37,43,53,123,133), +(8,5,63,37,43,54,125,136), +(8,5,64,38,44,55,128,138), +(8,5,65,38,44,55,130,140), +(8,5,66,38,45,56,132,143), +(8,5,67,39,45,57,134,145), +(8,5,68,39,46,58,136,147), +(8,5,69,40,46,58,139,150), +(8,5,70,40,47,59,141,152), +(8,7,1,22,22,22,17,23), +(8,7,2,23,22,23,18,24), +(8,7,3,24,23,24,19,25), +(8,7,4,25,23,25,20,26), +(8,7,5,25,24,26,21,27), +(8,7,6,26,24,27,22,28), +(8,7,7,27,25,28,23,29), +(8,7,8,28,25,29,24,30), +(8,7,9,29,25,30,25,31), +(8,7,10,30,26,31,26,33), +(8,7,11,31,26,32,27,34), +(8,7,12,32,27,33,28,35), +(8,7,13,33,27,34,29,36), +(8,7,14,34,28,35,30,37), +(8,7,15,34,28,36,31,38), +(8,7,16,35,29,38,32,39), +(8,7,17,36,29,39,33,41), +(8,7,18,37,30,40,34,42), +(8,7,19,38,30,41,35,43), +(8,7,20,39,31,42,36,44), +(8,7,21,40,32,43,37,45), +(8,7,22,41,32,45,38,47), +(8,7,23,43,33,46,39,48), +(8,7,24,44,33,47,40,49), +(8,7,25,45,34,48,42,51), +(8,7,26,46,34,49,43,52), +(8,7,27,47,35,51,44,53), +(8,7,28,48,35,52,45,54), +(8,7,29,49,36,53,46,56), +(8,7,30,50,37,54,48,57), +(8,7,31,51,37,56,49,59), +(8,7,32,52,38,57,50,60), +(8,7,33,53,38,58,51,61), +(8,7,34,55,39,60,52,63), +(8,7,35,56,40,61,54,64), +(8,7,36,57,40,62,55,66), +(8,7,37,58,41,64,56,67), +(8,7,38,59,42,65,57,68), +(8,7,39,61,42,66,59,70), +(8,7,40,62,43,68,60,71), +(8,7,41,63,44,69,61,73), +(8,7,42,64,44,71,63,74), +(8,7,43,65,45,72,64,76), +(8,7,44,67,46,74,65,77), +(8,7,45,68,46,75,67,79), +(8,7,46,69,47,76,68,80), +(8,7,47,71,48,78,69,82), +(8,7,48,72,49,79,71,83), +(8,7,49,73,49,81,72,85), +(8,7,50,74,50,82,74,87), +(8,7,51,76,51,84,75,88), +(8,7,52,77,51,85,77,90), +(8,7,53,78,52,87,78,92), +(8,7,54,80,53,89,79,93), +(8,7,55,81,54,90,81,95), +(8,7,56,83,55,92,82,96), +(8,7,57,84,55,93,84,98), +(8,7,58,85,56,95,85,100), +(8,7,59,87,57,97,87,102), +(8,7,60,88,58,98,88,103), +(8,7,61,90,58,100,90,105), +(8,7,62,91,59,101,91,107), +(8,7,63,93,60,103,93,108), +(8,7,64,94,61,105,94,110), +(8,7,65,95,62,106,96,112), +(8,7,66,97,63,108,98,114), +(8,7,67,98,63,110,99,116), +(8,7,68,100,64,112,101,117), +(8,7,69,101,65,113,102,119), +(8,7,70,103,66,115,104,121), +(8,8,1,21,22,21,19,23), +(8,8,2,21,22,21,20,24), +(8,8,3,21,22,22,22,26), +(8,8,4,21,22,22,23,27), +(8,8,5,21,23,22,25,28), +(8,8,6,21,23,22,26,30), +(8,8,7,21,23,23,27,31), +(8,8,8,22,23,23,29,32), +(8,8,9,22,23,23,30,34), +(8,8,10,22,23,24,32,35), +(8,8,11,22,24,24,33,37), +(8,8,12,22,24,24,35,38), +(8,8,13,22,24,25,36,39), +(8,8,14,22,24,25,38,41), +(8,8,15,22,24,25,39,42), +(8,8,16,22,24,26,41,44), +(8,8,17,23,25,26,42,45), +(8,8,18,23,25,26,44,47), +(8,8,19,23,25,27,46,48), +(8,8,20,23,25,27,47,50), +(8,8,21,23,25,27,49,51), +(8,8,22,23,26,28,51,53), +(8,8,23,23,26,28,52,55), +(8,8,24,24,26,29,54,56), +(8,8,25,24,26,29,56,58), +(8,8,26,24,27,29,57,60), +(8,8,27,24,27,30,59,61), +(8,8,28,24,27,30,61,63), +(8,8,29,24,27,31,63,65), +(8,8,30,24,28,31,64,66), +(8,8,31,25,28,31,66,68), +(8,8,32,25,28,32,68,70), +(8,8,33,25,28,32,70,71), +(8,8,34,25,29,33,71,73), +(8,8,35,25,29,33,73,75), +(8,8,36,26,29,34,75,77), +(8,8,37,26,29,34,77,79), +(8,8,38,26,30,35,79,80), +(8,8,39,26,30,35,81,82), +(8,8,40,26,30,35,83,84), +(8,8,41,27,31,36,85,86), +(8,8,42,27,31,36,87,88), +(8,8,43,27,31,37,89,90), +(8,8,44,27,32,37,91,91), +(8,8,45,27,32,38,93,93), +(8,8,46,28,32,38,95,95), +(8,8,47,28,32,39,97,97), +(8,8,48,28,33,39,99,99), +(8,8,49,28,33,40,101,101), +(8,8,50,29,33,40,103,103), +(8,8,51,29,34,41,105,105), +(8,8,52,29,34,42,107,107), +(8,8,53,29,35,42,109,109), +(8,8,54,30,35,43,111,111), +(8,8,55,30,35,43,113,113), +(8,8,56,30,36,44,115,115), +(8,8,57,30,36,44,118,118), +(8,8,58,31,36,45,120,120), +(8,8,59,31,37,45,122,122), +(8,8,60,31,37,46,124,124), +(8,8,61,31,37,47,126,126), +(8,8,62,32,38,47,129,128), +(8,8,63,32,38,48,131,130), +(8,8,64,32,39,48,133,133), +(8,8,65,33,39,49,135,135), +(8,8,66,33,39,50,138,137), +(8,8,67,33,40,50,140,139), +(8,8,68,33,40,51,142,141), +(8,8,69,34,41,51,145,144), +(8,8,70,34,41,52,147,146), +(10,2,1,19,22,21,24,20), +(10,2,2,20,23,22,25,21), +(10,2,3,21,23,23,25,21), +(10,2,4,22,24,24,26,22), +(10,2,5,23,24,25,27,23), +(10,2,6,25,25,26,27,24), +(10,2,7,26,25,27,28,24), +(10,2,8,27,26,28,29,25), +(10,2,9,28,27,29,29,26), +(10,2,10,29,27,31,30,26), +(10,2,11,30,28,32,31,27), +(10,2,12,32,29,33,31,28), +(10,2,13,33,29,34,32,29), +(10,2,14,34,30,35,33,30), +(10,2,15,35,31,36,33,30), +(10,2,16,37,31,37,34,31), +(10,2,17,38,32,39,35,32), +(10,2,18,39,33,40,36,33), +(10,2,19,40,33,41,36,34), +(10,2,20,42,34,42,37,35), +(10,2,21,43,35,44,38,35), +(10,2,22,44,35,45,39,36), +(10,2,23,46,36,46,40,37), +(10,2,24,47,37,47,40,38), +(10,2,25,49,38,49,41,39), +(10,2,26,50,38,50,42,40), +(10,2,27,51,39,51,43,41), +(10,2,28,53,40,53,44,42), +(10,2,29,54,41,54,45,43), +(10,2,30,56,41,55,45,43), +(10,2,31,57,42,57,46,44), +(10,2,32,58,43,58,47,45), +(10,2,33,60,44,59,48,46), +(10,2,34,61,45,61,49,47), +(10,2,35,63,45,62,50,48), +(10,2,36,64,46,64,51,49), +(10,2,37,66,47,65,52,50), +(10,2,38,67,48,67,53,51), +(10,2,39,69,49,68,54,52), +(10,2,40,71,50,69,55,53), +(10,2,41,72,50,71,55,54), +(10,2,42,74,51,72,56,55), +(10,2,43,75,52,74,57,56), +(10,2,44,77,53,75,58,57), +(10,2,45,79,54,77,59,59), +(10,2,46,80,55,78,60,60), +(10,2,47,82,56,80,61,61), +(10,2,48,83,57,82,62,62), +(10,2,49,85,58,83,63,63), +(10,2,50,87,59,85,64,64), +(10,2,51,89,60,86,66,65), +(10,2,52,90,61,88,67,66), +(10,2,53,92,61,90,68,67), +(10,2,54,94,62,91,69,69), +(10,2,55,95,63,93,70,70), +(10,2,56,97,64,95,71,71), +(10,2,57,99,65,96,72,72), +(10,2,58,101,66,98,73,73), +(10,2,59,102,67,100,74,74), +(10,2,60,104,68,101,75,76), +(10,2,61,106,69,103,76,77), +(10,2,62,108,70,105,78,78), +(10,2,63,110,72,106,79,79), +(10,2,64,112,73,108,80,80), +(10,2,65,113,74,110,81,82), +(10,2,66,115,75,112,82,83), +(10,2,67,117,76,114,83,84), +(10,2,68,119,77,115,85,85), +(10,2,69,121,78,117,86,87), +(10,2,70,123,79,119,87,88), +(10,3,1,17,25,20,24,20), +(10,3,2,17,26,21,25,21), +(10,3,3,18,28,22,25,21), +(10,3,4,18,29,23,26,22), +(10,3,5,19,30,24,26,23), +(10,3,6,19,32,25,27,23), +(10,3,7,20,33,26,27,24), +(10,3,8,20,35,27,28,25), +(10,3,9,21,36,27,29,25), +(10,3,10,21,38,28,29,26), +(10,3,11,22,39,29,30,27), +(10,3,12,22,41,30,31,27), +(10,3,13,23,42,31,31,28), +(10,3,14,23,44,32,32,29), +(10,3,15,24,45,34,32,29), +(10,3,16,24,47,35,33,30), +(10,3,17,25,48,36,34,31), +(10,3,18,25,50,37,34,32), +(10,3,19,26,51,38,35,32), +(10,3,20,26,53,39,36,33), +(10,3,21,27,55,40,37,34), +(10,3,22,27,56,41,37,35), +(10,3,23,28,58,42,38,36), +(10,3,24,28,60,43,39,36), +(10,3,25,29,61,44,39,37), +(10,3,26,30,63,46,40,38), +(10,3,27,30,65,47,41,39), +(10,3,28,31,66,48,42,40), +(10,3,29,31,68,49,42,40), +(10,3,30,32,70,50,43,41), +(10,3,31,33,72,52,44,42), +(10,3,32,33,73,53,45,43), +(10,3,33,34,75,54,46,44), +(10,3,34,34,77,55,46,45), +(10,3,35,35,79,57,47,46), +(10,3,36,36,81,58,48,47), +(10,3,37,36,83,59,49,47), +(10,3,38,37,85,60,50,48), +(10,3,39,38,86,62,51,49), +(10,3,40,38,88,63,51,50), +(10,3,41,39,90,64,52,51), +(10,3,42,40,92,66,53,52), +(10,3,43,40,94,67,54,53), +(10,3,44,41,96,68,55,54), +(10,3,45,42,98,70,56,55), +(10,3,46,42,100,71,57,56), +(10,3,47,43,102,72,58,57), +(10,3,48,44,104,74,59,58), +(10,3,49,45,106,75,60,59), +(10,3,50,45,108,77,61,60), +(10,3,51,46,110,78,61,61), +(10,3,52,47,113,79,62,62), +(10,3,53,47,115,81,63,63), +(10,3,54,48,117,82,64,64), +(10,3,55,49,119,84,65,65), +(10,3,56,50,121,85,66,66), +(10,3,57,50,123,87,67,67), +(10,3,58,51,126,88,68,68), +(10,3,59,52,128,90,69,70), +(10,3,60,53,130,91,70,71), +(10,3,61,54,132,93,71,72), +(10,3,62,54,134,94,72,73), +(10,3,63,55,137,96,73,74), +(10,3,64,56,139,97,75,75), +(10,3,65,57,141,99,76,76), +(10,3,66,58,144,101,77,77), +(10,3,67,58,146,102,78,78), +(10,3,68,59,148,104,79,80), +(10,3,69,60,151,105,80,81), +(10,3,70,61,153,107,81,82), +(10,4,1,18,25,20,24,19), +(10,4,2,19,26,21,24,19), +(10,4,3,20,28,21,24,20), +(10,4,4,20,29,22,24,20), +(10,4,5,21,31,23,25,20), +(10,4,6,22,32,24,25,21), +(10,4,7,23,34,24,25,21), +(10,4,8,24,35,25,25,22), +(10,4,9,24,37,26,25,22), +(10,4,10,25,38,26,25,22), +(10,4,11,26,40,27,25,23), +(10,4,12,27,41,28,26,23), +(10,4,13,28,43,29,26,24), +(10,4,14,29,45,30,26,24), +(10,4,15,29,46,30,26,25), +(10,4,16,30,48,31,26,25), +(10,4,17,31,50,32,27,25), +(10,4,18,32,51,33,27,26), +(10,4,19,33,53,34,27,26), +(10,4,20,34,55,35,27,27), +(10,4,21,35,56,35,27,27), +(10,4,22,36,58,36,28,28), +(10,4,23,37,60,37,28,28), +(10,4,24,38,62,38,28,29), +(10,4,25,39,63,39,28,29), +(10,4,26,40,65,40,29,30), +(10,4,27,41,67,41,29,30), +(10,4,28,42,69,42,29,31), +(10,4,29,43,71,43,29,31), +(10,4,30,44,72,43,29,32), +(10,4,31,45,74,44,30,32), +(10,4,32,46,76,45,30,33), +(10,4,33,47,78,46,30,33), +(10,4,34,48,80,47,31,34), +(10,4,35,49,82,48,31,34), +(10,4,36,50,84,49,31,35), +(10,4,37,51,86,50,31,35), +(10,4,38,52,88,51,32,36), +(10,4,39,53,90,52,32,37), +(10,4,40,54,92,53,32,37), +(10,4,41,56,94,54,33,38), +(10,4,42,57,96,55,33,38), +(10,4,43,58,98,56,33,39), +(10,4,44,59,100,57,33,39), +(10,4,45,60,102,59,34,40), +(10,4,46,61,104,60,34,41), +(10,4,47,62,107,61,34,41), +(10,4,48,64,109,62,35,42), +(10,4,49,65,111,63,35,43), +(10,4,50,66,113,64,35,43), +(10,4,51,67,115,65,36,44), +(10,4,52,68,117,66,36,44), +(10,4,53,70,120,67,36,45), +(10,4,54,71,122,69,37,46), +(10,4,55,72,124,70,37,46), +(10,4,56,73,126,71,37,47), +(10,4,57,75,129,72,38,48), +(10,4,58,76,131,73,38,48), +(10,4,59,77,133,74,39,49), +(10,4,60,79,136,76,39,50), +(10,4,61,80,138,77,39,51), +(10,4,62,81,140,78,40,51), +(10,4,63,82,143,79,40,52), +(10,4,64,84,145,80,41,53), +(10,4,65,85,148,82,41,53), +(10,4,66,87,150,83,41,54), +(10,4,67,88,153,84,42,55), +(10,4,68,89,155,85,42,56), +(10,4,69,91,157,87,43,56), +(10,4,70,92,160,88,43,57), +(10,5,1,17,22,19,26,22), +(10,5,2,17,22,19,27,23), +(10,5,3,17,22,20,29,25), +(10,5,4,17,23,20,30,26), +(10,5,5,18,23,20,31,27), +(10,5,6,18,23,21,33,29), +(10,5,7,18,23,21,34,30), +(10,5,8,18,24,22,35,32), +(10,5,9,18,24,22,37,33), +(10,5,10,19,24,22,38,35), +(10,5,11,19,24,23,39,36), +(10,5,12,19,24,23,41,38), +(10,5,13,19,25,24,42,39), +(10,5,14,19,25,24,44,41), +(10,5,15,19,25,25,45,42), +(10,5,16,20,26,25,47,44), +(10,5,17,20,26,25,48,45), +(10,5,18,20,26,26,50,47), +(10,5,19,20,26,26,51,49), +(10,5,20,21,27,27,53,50), +(10,5,21,21,27,27,54,52), +(10,5,22,21,27,28,56,53), +(10,5,23,21,28,28,58,55), +(10,5,24,21,28,29,59,57), +(10,5,25,22,28,29,61,58), +(10,5,26,22,28,30,62,60), +(10,5,27,22,29,30,64,62), +(10,5,28,22,29,31,66,64), +(10,5,29,23,29,31,67,65), +(10,5,30,23,30,32,69,67), +(10,5,31,23,30,32,71,69), +(10,5,32,23,30,33,72,71), +(10,5,33,24,31,33,74,72), +(10,5,34,24,31,34,76,74), +(10,5,35,24,32,34,78,76), +(10,5,36,24,32,35,80,78), +(10,5,37,25,32,35,81,80), +(10,5,38,25,33,36,83,82), +(10,5,39,25,33,37,85,84), +(10,5,40,26,33,37,87,86), +(10,5,41,26,34,38,89,88), +(10,5,42,26,34,38,91,89), +(10,5,43,27,35,39,92,91), +(10,5,44,27,35,39,94,93), +(10,5,45,27,35,40,96,95), +(10,5,46,27,36,41,98,97), +(10,5,47,28,36,41,100,99), +(10,5,48,28,37,42,102,101), +(10,5,49,28,37,43,104,103), +(10,5,50,29,37,43,106,106), +(10,5,51,29,38,44,108,108), +(10,5,52,29,38,44,110,110), +(10,5,53,30,39,45,112,112), +(10,5,54,30,39,46,114,114), +(10,5,55,30,40,46,116,116), +(10,5,56,31,40,47,118,118), +(10,5,57,31,41,48,120,120), +(10,5,58,31,41,48,123,123), +(10,5,59,32,42,49,125,125), +(10,5,60,32,42,50,127,127), +(10,5,61,33,42,51,129,129), +(10,5,62,33,43,51,131,131), +(10,5,63,33,43,52,133,134), +(10,5,64,34,44,53,135,136), +(10,5,65,34,44,53,138,138), +(10,5,66,34,45,54,140,141), +(10,5,67,35,45,55,142,143), +(10,5,68,35,46,56,144,145), +(10,5,69,36,46,56,147,148), +(10,5,70,36,47,57,149,150), +(10,8,1,17,22,19,27,21), +(10,8,2,17,22,19,28,22), +(10,8,3,17,22,20,30,24), +(10,8,4,17,22,20,31,25), +(10,8,5,17,23,20,32,26), +(10,8,6,17,23,20,34,28), +(10,8,7,18,23,21,35,29), +(10,8,8,18,23,21,37,30), +(10,8,9,18,23,21,38,32), +(10,8,10,18,23,22,40,33), +(10,8,11,18,24,22,41,35), +(10,8,12,18,24,22,42,36), +(10,8,13,18,24,23,44,37), +(10,8,14,18,24,23,45,39), +(10,8,15,18,24,23,47,40), +(10,8,16,19,24,24,49,42), +(10,8,17,19,25,24,50,43), +(10,8,18,19,25,24,52,45), +(10,8,19,19,25,25,53,46), +(10,8,20,19,25,25,55,48), +(10,8,21,19,25,26,57,50), +(10,8,22,19,26,26,58,51), +(10,8,23,20,26,26,60,53), +(10,8,24,20,26,27,61,54), +(10,8,25,20,26,27,63,56), +(10,8,26,20,27,27,65,58), +(10,8,27,20,27,28,67,59), +(10,8,28,20,27,28,68,61), +(10,8,29,21,27,29,70,63), +(10,8,30,21,28,29,72,64), +(10,8,31,21,28,30,74,66), +(10,8,32,21,28,30,75,68), +(10,8,33,21,28,30,77,70), +(10,8,34,21,29,31,79,71), +(10,8,35,22,29,31,81,73), +(10,8,36,22,29,32,83,75), +(10,8,37,22,29,32,85,77), +(10,8,38,22,30,33,86,78), +(10,8,39,22,30,33,88,80), +(10,8,40,23,30,34,90,82), +(10,8,41,23,31,34,92,84), +(10,8,42,23,31,35,94,86), +(10,8,43,23,31,35,96,88), +(10,8,44,23,32,36,98,90), +(10,8,45,24,32,36,100,92), +(10,8,46,24,32,37,102,93), +(10,8,47,24,32,37,104,95), +(10,8,48,24,33,38,106,97), +(10,8,49,25,33,38,108,99), +(10,8,50,25,33,39,110,101), +(10,8,51,25,34,39,112,103), +(10,8,52,25,34,40,114,105), +(10,8,53,25,35,40,117,107), +(10,8,54,26,35,41,119,109), +(10,8,55,26,35,41,121,111), +(10,8,56,26,36,42,123,113), +(10,8,57,26,36,42,125,116), +(10,8,58,27,36,43,127,118), +(10,8,59,27,37,43,130,120), +(10,8,60,27,37,44,132,122), +(10,8,61,27,37,45,134,124), +(10,8,62,28,38,45,136,126), +(10,8,63,28,38,46,139,128), +(10,8,64,28,39,46,141,131), +(10,8,65,29,39,47,143,133), +(10,8,66,29,39,48,146,135), +(10,8,67,29,40,48,148,137), +(10,8,68,29,40,49,150,139), +(10,8,69,30,41,49,153,142), +(10,8,70,30,41,50,155,144), +(10,9,1,17,22,20,26,21), +(10,9,2,17,22,21,27,22), +(10,9,3,18,23,21,28,23), +(10,9,4,18,23,22,29,24), +(10,9,5,18,23,22,31,26), +(10,9,6,18,24,23,32,27), +(10,9,7,19,24,23,33,28), +(10,9,8,19,25,24,34,29), +(10,9,9,19,25,25,36,30), +(10,9,10,20,25,25,37,32), +(10,9,11,20,26,26,38,33), +(10,9,12,20,26,26,39,34), +(10,9,13,21,27,27,41,36), +(10,9,14,21,27,28,42,37), +(10,9,15,21,27,28,43,38), +(10,9,16,22,28,29,45,39), +(10,9,17,22,28,30,46,41), +(10,9,18,23,29,30,47,42), +(10,9,19,23,29,31,49,43), +(10,9,20,23,30,32,50,45), +(10,9,21,24,30,32,51,46), +(10,9,22,24,31,33,53,48), +(10,9,23,24,31,34,54,49), +(10,9,24,25,31,34,56,50), +(10,9,25,25,32,35,57,52), +(10,9,26,26,32,36,59,53), +(10,9,27,26,33,37,60,55), +(10,9,28,26,33,37,62,56), +(10,9,29,27,34,38,63,58), +(10,9,30,27,34,39,65,59), +(10,9,31,28,35,40,66,61), +(10,9,32,28,36,40,68,62), +(10,9,33,29,36,41,69,64), +(10,9,34,29,37,42,71,65), +(10,9,35,29,37,43,73,67), +(10,9,36,30,38,43,74,69), +(10,9,37,30,38,44,76,70), +(10,9,38,31,39,45,77,72), +(10,9,39,31,39,46,79,73), +(10,9,40,32,40,47,81,75), +(10,9,41,32,41,48,82,77), +(10,9,42,33,41,48,84,78), +(10,9,43,33,42,49,86,80), +(10,9,44,34,42,50,88,82), +(10,9,45,34,43,51,89,83), +(10,9,46,35,44,52,91,85), +(10,9,47,35,44,53,93,87), +(10,9,48,36,45,54,95,89), +(10,9,49,36,45,54,96,90), +(10,9,50,37,46,55,98,92), +(10,9,51,37,47,56,100,94), +(10,9,52,38,47,57,102,96), +(10,9,53,38,48,58,104,97), +(10,9,54,39,49,59,105,99), +(10,9,55,39,49,60,107,101), +(10,9,56,40,50,61,109,103), +(10,9,57,40,51,62,111,105), +(10,9,58,41,51,63,113,107), +(10,9,59,42,52,64,115,108), +(10,9,60,42,53,65,117,110), +(10,9,61,43,53,66,119,112), +(10,9,62,43,54,67,121,114), +(10,9,63,44,55,68,123,116), +(10,9,64,44,56,69,125,118), +(10,9,65,45,56,70,127,120), +(10,9,66,46,57,71,129,122), +(10,9,67,46,58,72,131,124), +(10,9,68,47,58,73,133,126), +(10,9,69,47,59,74,135,128), +(10,9,70,48,60,75,137,130), +(11,1,1,24,17,21,21,22), +(11,1,2,25,18,22,21,22), +(11,1,3,27,19,23,21,23), +(11,1,4,28,19,25,21,23), +(11,1,5,29,20,26,21,23), +(11,1,6,31,21,27,21,23), +(11,1,7,32,22,28,21,24), +(11,1,8,33,23,29,22,24), +(11,1,9,35,24,31,22,24), +(11,1,10,36,24,32,22,25), +(11,1,11,37,25,33,22,25), +(11,1,12,39,26,34,22,25), +(11,1,13,40,27,36,22,26), +(11,1,14,42,28,37,22,26), +(11,1,15,43,29,38,22,26), +(11,1,16,45,30,40,22,27), +(11,1,17,46,31,41,23,27), +(11,1,18,48,32,43,23,27), +(11,1,19,49,33,44,23,28), +(11,1,20,51,34,45,23,28), +(11,1,21,52,34,47,23,28), +(11,1,22,54,35,48,23,29), +(11,1,23,55,36,50,23,29), +(11,1,24,57,37,51,24,30), +(11,1,25,59,38,52,24,30), +(11,1,26,60,39,54,24,30), +(11,1,27,62,40,55,24,31), +(11,1,28,63,41,57,24,31), +(11,1,29,65,43,58,24,32), +(11,1,30,67,44,60,24,32), +(11,1,31,69,45,62,25,32), +(11,1,32,70,46,63,25,33), +(11,1,33,72,47,65,25,33), +(11,1,34,74,48,66,25,34), +(11,1,35,75,49,68,25,34), +(11,1,36,77,50,69,26,35), +(11,1,37,79,51,71,26,35), +(11,1,38,81,52,73,26,35), +(11,1,39,83,53,74,26,36), +(11,1,40,84,55,76,26,36), +(11,1,41,86,56,78,27,37), +(11,1,42,88,57,79,27,37), +(11,1,43,90,58,81,27,38), +(11,1,44,92,59,83,27,38), +(11,1,45,94,60,85,27,39), +(11,1,46,96,62,86,28,39), +(11,1,47,98,63,88,28,40), +(11,1,48,100,64,90,28,40), +(11,1,49,102,65,92,28,41), +(11,1,50,103,66,93,29,41), +(11,1,51,105,68,95,29,42), +(11,1,52,107,69,97,29,42), +(11,1,53,109,70,99,29,43), +(11,1,54,112,71,101,30,44), +(11,1,55,114,73,103,30,44), +(11,1,56,116,74,104,30,45), +(11,1,57,118,75,106,30,45), +(11,1,58,120,77,108,31,46), +(11,1,59,122,78,110,31,46), +(11,1,60,124,79,112,31,47), +(11,1,61,126,81,114,31,48), +(11,1,62,128,82,116,32,48), +(11,1,63,130,83,118,32,49), +(11,1,64,133,85,120,32,49), +(11,1,65,135,86,122,33,50), +(11,1,66,137,87,124,33,51), +(11,1,67,139,89,126,33,51), +(11,1,68,141,90,128,33,52), +(11,1,69,144,92,130,34,52), +(11,1,70,146,93,132,34,53), +(11,2,1,23,17,21,21,23), +(11,2,2,24,18,22,22,24), +(11,2,3,25,18,23,22,24), +(11,2,4,26,19,24,23,25), +(11,2,5,27,19,25,24,26), +(11,2,6,29,20,26,24,26), +(11,2,7,30,21,27,25,27), +(11,2,8,31,21,28,26,28), +(11,2,9,32,22,29,26,29), +(11,2,10,33,22,31,27,29), +(11,2,11,34,23,32,28,30), +(11,2,12,36,24,33,28,31), +(11,2,13,37,24,34,29,32), +(11,2,14,38,25,35,30,32), +(11,2,15,39,26,36,31,33), +(11,2,16,40,26,37,31,34), +(11,2,17,42,27,39,32,35), +(11,2,18,43,28,40,33,36), +(11,2,19,44,28,41,34,37), +(11,2,20,46,29,42,34,37), +(11,2,21,47,30,44,35,38), +(11,2,22,48,31,45,36,39), +(11,2,23,50,31,46,37,40), +(11,2,24,51,32,47,38,41), +(11,2,25,52,33,49,38,42), +(11,2,26,54,34,50,39,43), +(11,2,27,55,34,51,40,44), +(11,2,28,56,35,53,41,44), +(11,2,29,58,36,54,42,45), +(11,2,30,59,37,55,43,46), +(11,2,31,61,37,57,43,47), +(11,2,32,62,38,58,44,48), +(11,2,33,64,39,59,45,49), +(11,2,34,65,40,61,46,50), +(11,2,35,67,41,62,47,51), +(11,2,36,68,42,64,48,52), +(11,2,37,70,42,65,49,53), +(11,2,38,71,43,67,50,54), +(11,2,39,73,44,68,51,55), +(11,2,40,74,45,69,52,56), +(11,2,41,76,46,71,53,57), +(11,2,42,78,47,72,54,58), +(11,2,43,79,47,74,55,59), +(11,2,44,81,48,75,56,60), +(11,2,45,82,49,77,57,61), +(11,2,46,84,50,78,58,62), +(11,2,47,86,51,80,59,64), +(11,2,48,87,52,82,60,65), +(11,2,49,89,53,83,61,66), +(11,2,50,91,54,85,62,67), +(11,2,51,92,55,86,63,68), +(11,2,52,94,56,88,64,69), +(11,2,53,96,57,90,65,70), +(11,2,54,97,58,91,66,71), +(11,2,55,99,59,93,67,73), +(11,2,56,101,60,95,68,74), +(11,2,57,103,61,96,69,75), +(11,2,58,105,62,98,70,76), +(11,2,59,106,63,100,71,77), +(11,2,60,108,64,101,72,78), +(11,2,61,110,65,103,74,80), +(11,2,62,112,66,105,75,81), +(11,2,63,114,67,106,76,82), +(11,2,64,116,68,108,77,83), +(11,2,65,117,69,110,78,85), +(11,2,66,119,70,112,79,86), +(11,2,67,121,71,114,80,87), +(11,2,68,123,72,115,82,88), +(11,2,69,125,73,117,83,90), +(11,2,70,127,74,119,84,91), +(11,3,1,21,20,20,21,23), +(11,3,2,21,21,21,22,24), +(11,3,3,22,23,22,22,24), +(11,3,4,22,24,23,23,25), +(11,3,5,23,25,24,23,25), +(11,3,6,23,27,25,24,26), +(11,3,7,24,28,26,24,27), +(11,3,8,24,30,27,25,27), +(11,3,9,25,31,27,26,28), +(11,3,10,25,33,28,26,29), +(11,3,11,25,34,29,27,29), +(11,3,12,26,36,30,28,30), +(11,3,13,26,37,31,28,31), +(11,3,14,27,39,32,29,32), +(11,3,15,27,40,34,30,32), +(11,3,16,28,42,35,30,33), +(11,3,17,28,43,36,31,34), +(11,3,18,29,45,37,32,35), +(11,3,19,29,47,38,32,35), +(11,3,20,30,48,39,33,36), +(11,3,21,31,50,40,34,37), +(11,3,22,31,51,41,34,38), +(11,3,23,32,53,42,35,38), +(11,3,24,32,55,43,36,39), +(11,3,25,33,57,44,37,40), +(11,3,26,33,58,46,37,41), +(11,3,27,34,60,47,38,42), +(11,3,28,35,62,48,39,42), +(11,3,29,35,63,49,40,43), +(11,3,30,36,65,50,40,44), +(11,3,31,36,67,52,41,45), +(11,3,32,37,69,53,42,46), +(11,3,33,38,71,54,43,47), +(11,3,34,38,72,55,44,48), +(11,3,35,39,74,57,44,48), +(11,3,36,39,76,58,45,49), +(11,3,37,40,78,59,46,50), +(11,3,38,41,80,60,47,51), +(11,3,39,41,82,62,48,52), +(11,3,40,42,84,63,49,53), +(11,3,41,43,86,64,50,54), +(11,3,42,43,88,66,50,55), +(11,3,43,44,90,67,51,56), +(11,3,44,45,91,68,52,57), +(11,3,45,45,93,70,53,58), +(11,3,46,46,95,71,54,59), +(11,3,47,47,98,72,55,60), +(11,3,48,48,100,74,56,61), +(11,3,49,48,102,75,57,62), +(11,3,50,49,104,77,58,63), +(11,3,51,50,106,78,59,64), +(11,3,52,51,108,79,60,65), +(11,3,53,51,110,81,61,66), +(11,3,54,52,112,82,61,67), +(11,3,55,53,114,84,62,68), +(11,3,56,54,116,85,63,69), +(11,3,57,54,118,87,64,70), +(11,3,58,55,121,88,65,71), +(11,3,59,56,123,90,66,72), +(11,3,60,57,125,91,67,74), +(11,3,61,58,127,93,68,75), +(11,3,62,58,130,94,69,76), +(11,3,63,59,132,96,71,77), +(11,3,64,60,134,97,72,78), +(11,3,65,61,136,99,73,79), +(11,3,66,62,139,101,74,80), +(11,3,67,62,141,102,75,81), +(11,3,68,63,143,104,76,83), +(11,3,69,64,146,105,77,84), +(11,3,70,65,148,107,78,85), +(11,5,1,21,17,19,23,25), +(11,5,2,21,17,19,24,26), +(11,5,3,21,17,20,26,28), +(11,5,4,21,18,20,27,29), +(11,5,5,22,18,20,28,30), +(11,5,6,22,18,21,30,32), +(11,5,7,22,18,21,31,33), +(11,5,8,22,19,22,32,35), +(11,5,9,22,19,22,34,36), +(11,5,10,22,19,22,35,38), +(11,5,11,23,19,23,37,39), +(11,5,12,23,20,23,38,41), +(11,5,13,23,20,24,39,42), +(11,5,14,23,20,24,41,44), +(11,5,15,23,20,25,42,45), +(11,5,16,24,21,25,44,47), +(11,5,17,24,21,25,45,48), +(11,5,18,24,21,26,47,50), +(11,5,19,24,22,26,48,51), +(11,5,20,24,22,27,50,53), +(11,5,21,25,22,27,51,55), +(11,5,22,25,22,28,53,56), +(11,5,23,25,23,28,55,58), +(11,5,24,25,23,29,56,60), +(11,5,25,25,23,29,58,61), +(11,5,26,26,24,30,60,63), +(11,5,27,26,24,30,61,65), +(11,5,28,26,24,31,63,66), +(11,5,29,26,25,31,65,68), +(11,5,30,27,25,32,66,70), +(11,5,31,27,25,32,68,72), +(11,5,32,27,26,33,70,73), +(11,5,33,27,26,33,71,75), +(11,5,34,28,26,34,73,77), +(11,5,35,28,27,34,75,79), +(11,5,36,28,27,35,77,81), +(11,5,37,29,28,35,79,83), +(11,5,38,29,28,36,80,85), +(11,5,39,29,28,37,82,86), +(11,5,40,29,29,37,84,88), +(11,5,41,30,29,38,86,90), +(11,5,42,30,29,38,88,92), +(11,5,43,30,30,39,90,94), +(11,5,44,31,30,39,91,96), +(11,5,45,31,31,40,93,98), +(11,5,46,31,31,41,95,100), +(11,5,47,32,31,41,97,102), +(11,5,48,32,32,42,99,104), +(11,5,49,32,32,43,101,106), +(11,5,50,33,33,43,103,108), +(11,5,51,33,33,44,105,110), +(11,5,52,33,34,44,107,113), +(11,5,53,34,34,45,109,115), +(11,5,54,34,34,46,111,117), +(11,5,55,34,35,46,113,119), +(11,5,56,35,35,47,115,121), +(11,5,57,35,36,48,118,123), +(11,5,58,35,36,48,120,126), +(11,5,59,36,37,49,122,128), +(11,5,60,36,37,50,124,130), +(11,5,61,36,38,51,126,132), +(11,5,62,37,38,51,128,134), +(11,5,63,37,39,52,130,137), +(11,5,64,38,39,53,133,139), +(11,5,65,38,40,53,135,141), +(11,5,66,38,40,54,137,144), +(11,5,67,39,40,55,139,146), +(11,5,68,39,41,56,141,148), +(11,5,69,40,41,56,144,151), +(11,5,70,40,42,57,146,153), +(11,7,1,22,17,20,22,24), +(11,7,2,23,17,21,23,25), +(11,7,3,24,18,22,24,26), +(11,7,4,25,18,23,25,27), +(11,7,5,25,19,24,26,28), +(11,7,6,26,19,25,27,29), +(11,7,7,27,20,26,28,30), +(11,7,8,28,20,27,28,31), +(11,7,9,29,21,28,29,32), +(11,7,10,30,21,29,30,33), +(11,7,11,31,22,30,31,35), +(11,7,12,32,22,31,32,36), +(11,7,13,33,23,32,33,37), +(11,7,14,34,23,33,34,38), +(11,7,15,34,24,35,35,39), +(11,7,16,35,24,36,36,40), +(11,7,17,36,25,37,38,42), +(11,7,18,37,25,38,39,43), +(11,7,19,38,26,39,40,44), +(11,7,20,39,26,40,41,45), +(11,7,21,40,27,41,42,46), +(11,7,22,41,27,43,43,48), +(11,7,23,43,28,44,44,49), +(11,7,24,44,28,45,45,50), +(11,7,25,45,29,46,46,51), +(11,7,26,46,30,47,48,53), +(11,7,27,47,30,49,49,54), +(11,7,28,48,31,50,50,55), +(11,7,29,49,31,51,51,57), +(11,7,30,50,32,53,52,58), +(11,7,31,51,33,54,53,59), +(11,7,32,52,33,55,55,61), +(11,7,33,53,34,56,56,62), +(11,7,34,55,34,58,57,64), +(11,7,35,56,35,59,58,65), +(11,7,36,57,36,60,60,66), +(11,7,37,58,36,62,61,68), +(11,7,38,59,37,63,62,69), +(11,7,39,61,38,65,63,71), +(11,7,40,62,38,66,65,72), +(11,7,41,63,39,67,66,74), +(11,7,42,64,40,69,67,75), +(11,7,43,65,40,70,69,77), +(11,7,44,67,41,72,70,78), +(11,7,45,68,42,73,71,80), +(11,7,46,69,42,75,73,81), +(11,7,47,71,43,76,74,83), +(11,7,48,72,44,78,76,84), +(11,7,49,73,45,79,77,86), +(11,7,50,74,45,81,78,88), +(11,7,51,76,46,82,80,89), +(11,7,52,77,47,84,81,91), +(11,7,53,78,47,85,83,92), +(11,7,54,80,48,87,84,94), +(11,7,55,81,49,88,86,96), +(11,7,56,83,50,90,87,97), +(11,7,57,84,50,91,89,99), +(11,7,58,85,51,93,90,101), +(11,7,59,87,52,95,92,102), +(11,7,60,88,53,96,93,104), +(11,7,61,90,54,98,95,106), +(11,7,62,91,54,99,96,108), +(11,7,63,93,55,101,98,109), +(11,7,64,94,56,103,99,111), +(11,7,65,95,57,104,101,113), +(11,7,66,97,58,106,103,115), +(11,7,67,98,58,108,104,117), +(11,7,68,100,59,110,106,118), +(11,7,69,101,60,111,107,120), +(11,7,70,103,61,113,109,122), +(11,8,1,21,17,19,24,24), +(11,8,2,21,17,19,25,25), +(11,8,3,21,17,20,27,27), +(11,8,4,21,17,20,28,28), +(11,8,5,21,18,20,29,29), +(11,8,6,21,18,20,31,31), +(11,8,7,21,18,21,32,32), +(11,8,8,22,18,21,34,33), +(11,8,9,22,18,21,35,35), +(11,8,10,22,19,22,37,36), +(11,8,11,22,19,22,38,37), +(11,8,12,22,19,22,40,39), +(11,8,13,22,19,23,41,40), +(11,8,14,22,19,23,43,42), +(11,8,15,22,19,23,44,43), +(11,8,16,22,20,24,46,45), +(11,8,17,23,20,24,47,46), +(11,8,18,23,20,24,49,48), +(11,8,19,23,20,25,50,49), +(11,8,20,23,21,25,52,51), +(11,8,21,23,21,26,54,52), +(11,8,22,23,21,26,55,54), +(11,8,23,23,21,26,57,56), +(11,8,24,24,21,27,59,57), +(11,8,25,24,22,27,60,59), +(11,8,26,24,22,27,62,60), +(11,8,27,24,22,28,64,62), +(11,8,28,24,22,28,65,64), +(11,8,29,24,23,29,67,65), +(11,8,30,24,23,29,69,67), +(11,8,31,25,23,30,71,69), +(11,8,32,25,23,30,73,71), +(11,8,33,25,24,30,74,72), +(11,8,34,25,24,31,76,74), +(11,8,35,25,24,31,78,76), +(11,8,36,26,24,32,80,78), +(11,8,37,26,25,32,82,79), +(11,8,38,26,25,33,84,81), +(11,8,39,26,25,33,86,83), +(11,8,40,26,26,34,87,85), +(11,8,41,27,26,34,89,87), +(11,8,42,27,26,35,91,89), +(11,8,43,27,27,35,93,91), +(11,8,44,27,27,36,95,92), +(11,8,45,27,27,36,97,94), +(11,8,46,28,27,37,99,96), +(11,8,47,28,28,37,101,98), +(11,8,48,28,28,38,103,100), +(11,8,49,28,28,38,105,102), +(11,8,50,29,29,39,107,104), +(11,8,51,29,29,39,110,106), +(11,8,52,29,29,40,112,108), +(11,8,53,29,30,40,114,110), +(11,8,54,30,30,41,116,112), +(11,8,55,30,30,41,118,114), +(11,8,56,30,31,42,120,116), +(11,8,57,30,31,42,122,118), +(11,8,58,31,31,43,125,121), +(11,8,59,31,32,43,127,123), +(11,8,60,31,32,44,129,125), +(11,8,61,31,33,45,131,127), +(11,8,62,32,33,45,133,129), +(11,8,63,32,33,46,136,131), +(11,8,64,32,34,46,138,134), +(11,8,65,33,34,47,140,136), +(11,8,66,33,34,48,143,138), +(11,8,67,33,35,48,145,140), +(11,8,68,33,35,49,147,142), +(11,8,69,34,36,49,150,145), +(11,8,70,34,36,50,152,147); +/*!40000 ALTER TABLE `player_levelstats` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `playercreateinfo` +-- + +DROP TABLE IF EXISTS `playercreateinfo`; +CREATE TABLE `playercreateinfo` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `map` smallint(5) unsigned NOT NULL default '0', + `zone` mediumint(8) unsigned NOT NULL default '0', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + PRIMARY KEY (`race`,`class`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `playercreateinfo` +-- + +LOCK TABLES `playercreateinfo` WRITE; +/*!40000 ALTER TABLE `playercreateinfo` DISABLE KEYS */; +INSERT INTO `playercreateinfo` VALUES +(1,1,0,12,-8949,-132,84), +(1,2,0,12,-8949,-132,84), +(1,4,0,12,-8949,-132,84), +(1,5,0,12,-8949,-132,84), +(1,8,0,12,-8949,-132,84), +(1,9,0,12,-8949,-132,84), +(2,1,1,14,-618,-4251,39), +(2,3,1,14,-618,-4251,39), +(2,4,1,14,-618,-4251,39), +(2,7,1,14,-618,-4251,39), +(2,9,1,14,-618,-4251,39), +(3,1,0,1,-6240,331,383), +(3,2,0,1,-6240,331,383), +(3,3,0,1,-6240,331,383), +(3,4,0,1,-6240,331,383), +(3,5,0,1,-6240,331,383), +(4,1,1,141,10311,832,1327), +(4,3,1,141,10311,832,1327), +(4,4,1,141,10311,832,1327), +(4,5,1,141,10311,832,1327), +(4,11,1,141,10311,832,1327), +(5,1,0,85,1676,1677,122), +(5,4,0,85,1676,1677,122), +(5,5,0,85,1676,1677,122), +(5,8,0,85,1676,1677,122), +(5,9,0,85,1676,1677,122), +(6,1,1,215,-2917,-257,53), +(6,3,1,215,-2917,-257,53), +(6,7,1,215,-2917,-257,53), +(6,11,1,215,-2917,-257,53), +(7,1,0,1,-6240,331,383), +(7,4,0,1,-6340,331,383), +(7,8,0,1,-6340,331,383), +(7,9,0,1,-6340,331,383), +(8,1,1,14,-618,-4251,39), +(8,3,1,14,-618,-4251,39), +(8,4,1,14,-618,-4251,39), +(8,5,1,14,-618,-4251,39), +(8,7,1,14,-618,-4251,39), +(8,8,1,14,-618,-4251,39), +(10,2,530,3431,10349.6,-6357.29,33.4026), +(10,3,530,3431,10349.6,-6357.29,33.4026), +(10,4,530,3431,10349.6,-6357.29,33.4026), +(10,5,530,3431,10349.6,-6357.29,33.4026), +(10,8,530,3431,10349.6,-6357.29,33.4026), +(10,9,530,3431,10349.6,-6357.29,33.4026), +(11,1,530,3526,-3961.64,-13931.2,100.615), +(11,2,530,3526,-3961.64,-13931.2,100.615), +(11,3,530,3526,-3961.64,-13931.2,100.615), +(11,5,530,3526,-3961.64,-13931.2,100.615), +(11,7,530,3526,-3961.64,-13931.2,100.615), +(11,8,530,3526,-3961.64,-13931.2,100.615); +/*!40000 ALTER TABLE `playercreateinfo` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `playercreateinfo_action` +-- + +DROP TABLE IF EXISTS `playercreateinfo_action`; +CREATE TABLE `playercreateinfo_action` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `button` smallint(5) unsigned NOT NULL default '0', + `action` smallint(5) unsigned NOT NULL default '0', + `type` smallint(5) unsigned NOT NULL default '0', + `misc` smallint(5) unsigned NOT NULL default '0', + KEY `playercreateinfo_race_class_index` (`race`,`class`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `playercreateinfo_action` +-- + +LOCK TABLES `playercreateinfo_action` WRITE; +/*!40000 ALTER TABLE `playercreateinfo_action` DISABLE KEYS */; +INSERT INTO `playercreateinfo_action` VALUES +(1,1,1,78,0,0), +(1,1,0,6603,0,0), +(1,1,11,117,128,0), +(1,2,2,635,0,0), +(1,2,0,6603,0,0), +(1,2,1,21084,0,0), +(1,2,10,159,128,0), +(1,2,11,2070,128,0), +(1,4,1,1752,0,0), +(1,4,2,2098,0,0), +(1,4,3,2764,0,0), +(1,4,0,6603,0,0), +(1,4,11,2070,128,0), +(1,5,1,585,0,0), +(1,5,2,2050,0,0), +(1,5,0,6603,0,0), +(1,5,10,159,128,0), +(1,5,11,2070,128,0), +(1,8,1,133,0,0), +(1,8,2,168,0,0), +(1,8,0,6603,0,0), +(1,8,10,159,128,0), +(1,8,11,2070,128,0), +(1,9,1,686,0,0), +(1,9,2,687,0,0), +(1,9,0,6603,0,0), +(1,9,10,159,128,0), +(1,9,11,4604,128,0), +(2,1,1,78,0,0), +(2,1,0,6603,0,0), +(2,1,11,117,128,0), +(2,3,2,75,0,0), +(2,3,1,2973,0,0), +(2,3,0,6603,0,0), +(2,3,11,117,128,0), +(2,3,10,159,128,0), +(2,4,10,0,128,0), +(2,4,1,1752,0,0), +(2,4,2,2098,0,0), +(2,4,0,6603,0,0), +(2,4,11,117,128,0), +(2,7,2,331,0,0), +(2,7,1,403,0,0), +(2,7,0,6603,0,0), +(2,7,11,117,128,0), +(2,7,10,159,128,0), +(2,9,1,686,0,0), +(2,9,2,687,0,0), +(2,9,0,6603,0,0), +(2,9,11,117,128,0), +(2,9,10,159,128,0), +(3,1,1,78,0,0), +(3,1,0,6603,0,0), +(3,1,11,117,128,0), +(3,2,2,635,0,0), +(3,2,0,6603,0,0), +(3,2,1,21084,0,0), +(3,2,10,159,128,0), +(3,2,11,4540,128,0), +(3,3,2,75,0,0), +(3,3,1,2973,0,0), +(3,3,0,6603,0,0), +(3,3,11,117,128,0), +(3,3,10,159,128,0), +(3,4,1,1752,0,0), +(3,4,2,2098,0,0), +(3,4,3,2764,0,0), +(3,4,0,6603,0,0), +(3,4,11,4540,128,0), +(3,5,1,585,0,0), +(3,5,2,2050,0,0), +(3,5,0,6603,0,0), +(3,5,10,159,128,0), +(3,5,11,4540,128,0), +(4,1,1,78,0,0), +(4,1,0,6603,0,0), +(4,1,11,117,128,0), +(4,3,2,75,0,0), +(4,3,1,2973,0,0), +(4,3,0,6603,0,0), +(4,3,11,117,128,0), +(4,3,10,159,128,0), +(4,4,1,1752,0,0), +(4,4,2,2098,0,0), +(4,4,3,2764,0,0), +(4,4,0,6603,0,0), +(4,4,11,4540,128,0), +(4,5,1,585,0,0), +(4,5,2,2050,0,0), +(4,5,0,6603,0,0), +(4,5,10,159,128,0), +(4,5,11,2070,128,0), +(4,11,1,5176,0,0), +(4,11,2,5185,0,0), +(4,11,0,6603,0,0), +(4,11,10,159,128,0), +(4,11,11,4536,128,0), +(5,1,11,4604,128,0), +(5,1,0,6603,0,0), +(5,1,1,78,0,0), +(5,4,11,4604,128,0), +(5,4,3,2764,0,0), +(5,4,2,2098,0,0), +(5,4,1,1752,0,0), +(5,4,0,6603,0,0), +(5,5,10,159,128,0), +(5,5,2,2050,0,0), +(5,5,1,585,0,0), +(5,5,11,4604,128,0), +(5,5,0,6603,0,0), +(5,8,11,4604,128,0), +(5,8,10,159,128,0), +(5,8,2,168,0,0), +(5,8,1,133,0,0), +(5,8,0,6603,0,0), +(5,9,1,686,0,0), +(5,9,10,159,128,0), +(5,9,2,687,0,0), +(5,9,11,4604,128,0), +(5,9,0,6603,0,0), +(6,1,1,78,0,0), +(6,1,2,20549,0,0), +(6,1,11,4540,128,0), +(6,1,0,6603,0,0), +(6,3,1,2973,0,0), +(6,3,10,159,128,0), +(6,3,2,75,0,0), +(6,3,3,20549,0,0), +(6,3,11,117,128,0), +(6,3,0,6603,0,0), +(6,7,1,403,0,0), +(6,7,10,159,128,0), +(6,7,2,331,0,0), +(6,7,3,20549,0,0), +(6,7,11,4604,128,0), +(6,7,0,6603,0,0), +(6,11,1,5176,0,0), +(6,11,10,159,128,0), +(6,11,2,5185,0,0), +(6,11,3,20549,0,0), +(6,11,11,4536,128,0), +(6,11,0,6603,0,0), +(7,1,11,117,128,0), +(7,1,1,78,0,0), +(7,1,0,6603,0,0), +(7,4,11,117,128,0), +(7,4,3,2764,0,0), +(7,4,1,1752,0,0), +(7,4,2,2098,0,0), +(7,4,0,6603,0,0), +(7,8,11,4536,128,0), +(7,8,1,133,0,0), +(7,8,2,168,0,0), +(7,8,10,159,128,0), +(7,8,0,6603,0,0), +(7,9,11,4604,128,0), +(7,9,1,686,0,0), +(7,9,2,687,0,0), +(7,9,10,159,128,0), +(7,9,0,6603,0,0), +(8,1,11,117,128,0), +(8,1,1,78,0,0), +(8,1,3,2764,0,0), +(8,1,0,6603,0,0), +(8,3,10,159,128,0), +(8,3,11,4604,128,0), +(8,3,1,2973,0,0), +(8,3,2,75,0,0), +(8,3,0,6603,0,0), +(8,4,1,1752,0,0), +(8,4,3,2764,0,0), +(8,4,2,2098,0,0), +(8,4,11,117,128,0), +(8,4,0,6603,0,0), +(8,5,1,585,0,0), +(8,5,10,159,128,0), +(8,5,2,2050,0,0), +(8,5,11,4540,128,0), +(8,5,0,6603,0,0), +(8,7,1,403,0,0), +(8,7,10,159,128,0), +(8,7,2,331,0,0), +(8,7,11,117,128,0), +(8,7,0,6603,0,0), +(8,8,1,133,0,0), +(8,8,10,159,128,0), +(8,8,2,168,0,0), +(8,8,11,117,128,0), +(8,8,0,6603,0,0), +(10,2,0,6603,0,0), +(10,2,1,21084,0,0), +(10,2,2,635,0,0), +(10,2,3,28734,0,0), +(10,2,4,28730,0,0), +(10,2,10,159,128,0), +(10,2,11,20857,128,0), +(10,3,0,6603,0,0), +(10,3,1,2973,0,0), +(10,3,2,75,0,0), +(10,3,3,28734,0,0), +(10,3,4,28730,0,0), +(10,3,10,159,128,0), +(10,3,11,20857,128,0), +(10,4,0,6603,0,0), +(10,4,1,1752,0,0), +(10,4,2,2098,0,0), +(10,4,3,2764,0,0), +(10,4,4,28734,0,0), +(10,4,5,25046,0,0), +(10,4,11,20857,128,0), +(10,5,0,6603,0,0), +(10,5,1,585,0,0), +(10,5,2,2050,0,0), +(10,5,3,28734,0,0), +(10,5,4,28730,0,0), +(10,5,10,159,128,0), +(10,5,11,20857,128,0), +(10,8,0,6603,0,0), +(10,8,1,133,0,0), +(10,8,2,168,0,0), +(10,8,3,28734,0,0), +(10,8,4,28730,0,0), +(10,8,10,159,128,0), +(10,8,11,20857,128,0), +(10,9,11,20857,128,0), +(10,9,10,159,128,0), +(10,9,4,28730,0,0), +(10,9,3,28734,0,0), +(10,9,2,687,0,0), +(10,9,1,686,0,0), +(10,9,0,6603,0,0), +(11,1,0,6603,0,0), +(11,1,72,6603,0,0), +(11,1,73,78,0,0), +(11,1,74,28880,0,0), +(11,1,83,4540,128,0), +(11,1,84,6603,0,0), +(11,1,96,6603,0,0), +(11,1,108,6603,0,0), +(11,2,0,6603,0,0), +(11,2,1,21084,0,0), +(11,2,2,635,0,0), +(11,2,3,28880,0,0), +(11,2,10,159,128,0), +(11,2,11,4540,128,0), +(11,2,83,4540,128,0), +(11,3,0,6603,0,0), +(11,3,1,2973,0,0), +(11,3,2,75,0,0), +(11,3,3,28880,0,0), +(11,3,10,159,128,0), +(11,3,11,4540,128,0), +(11,3,72,6603,0,0), +(11,3,73,2973,0,0), +(11,3,74,75,0,0), +(11,3,82,159,128,0), +(11,3,83,4540,128,0), +(11,5,0,6603,0,0), +(11,5,1,585,0,0), +(11,5,2,2050,0,0), +(11,5,3,28880,0,0), +(11,5,10,159,128,0), +(11,5,11,4540,128,0), +(11,5,83,4540,128,0), +(11,7,0,6603,0,0), +(11,7,1,403,0,0), +(11,7,2,331,0,0), +(11,7,3,28880,0,0), +(11,7,10,159,128,0), +(11,7,11,4540,128,0), +(11,8,0,6603,0,0), +(11,8,1,133,0,0), +(11,8,2,168,0,0), +(11,8,3,28880,0,0), +(11,8,10,159,128,0), +(11,8,11,4540,128,0), +(11,8,83,4540,128,0); +/*!40000 ALTER TABLE `playercreateinfo_action` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `playercreateinfo_item` +-- + +DROP TABLE IF EXISTS `playercreateinfo_item`; +CREATE TABLE `playercreateinfo_item` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `itemid` mediumint(8) unsigned NOT NULL default '0', + `amount` tinyint(3) unsigned NOT NULL default '1', + KEY `playercreateinfo_race_class_index` (`race`,`class`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `playercreateinfo_item` +-- + +LOCK TABLES `playercreateinfo_item` WRITE; +/*!40000 ALTER TABLE `playercreateinfo_item` DISABLE KEYS */; +INSERT INTO `playercreateinfo_item` VALUES +(1,1,38,1), +(1,1,39,1), +(1,1,40,1), +(1,1,25,1), +(1,1,2362,1), +(1,1,117,4), +(1,1,6948,1), +(1,1,14646,1), +(1,2,45,1), +(1,2,44,1), +(1,2,43,1), +(1,2,2361,1), +(1,2,6948,1), +(1,2,159,2), +(1,2,2070,4), +(1,2,14646,1), +(1,4,49,1), +(1,4,48,1), +(1,4,47,1), +(1,4,2092,1), +(1,4,2947,100), +(1,4,2070,4), +(1,4,6948,1), +(1,4,14646,1), +(1,5,53,1), +(1,5,6098,1), +(1,5,52,1), +(1,5,51,1), +(1,5,36,1), +(1,5,159,2), +(1,5,2070,4), +(1,5,6948,1), +(1,5,14646,1), +(1,8,6096,1), +(1,8,56,1), +(1,8,1395,1), +(1,8,55,1), +(1,8,35,1), +(1,8,2070,4), +(1,8,159,2), +(1,8,6948,1), +(1,8,14646,1), +(1,9,6097,1), +(1,9,57,1), +(1,9,1396,1), +(1,9,59,1), +(1,9,2092,1), +(1,9,4604,4), +(1,9,159,2), +(1,9,6948,1), +(1,9,14646,1), +(2,1,6125,1), +(2,1,139,1), +(2,1,140,1), +(2,1,12282,1), +(2,1,6948,1), +(2,1,117,4), +(2,1,14649,1), +(2,3,127,1), +(2,3,6126,1), +(2,3,6127,1), +(2,3,37,1), +(2,3,2504,1), +(2,3,159,2), +(2,3,117,4), +(2,3,6948,1), +(2,3,14649,1), +(2,3,2512,200), +(2,3,2101,1), +(2,4,2105,1), +(2,4,120,1), +(2,4,121,1), +(2,4,2092,1), +(2,4,25861,100), +(2,4,117,4), +(2,4,6948,1), +(2,4,14649,1), +(2,7,154,1), +(2,7,153,1), +(2,7,36,1), +(2,7,6948,1), +(2,7,117,4), +(2,7,159,2), +(2,7,14649,1), +(2,9,6129,1), +(2,9,1396,1), +(2,9,59,1), +(2,9,2092,1), +(2,9,6948,1), +(2,9,117,4), +(2,9,159,2), +(2,9,14649,1), +(3,1,38,1), +(3,1,39,1), +(3,1,40,1), +(3,1,12282,1), +(3,1,6948,1), +(3,1,117,4), +(3,1,14647,1), +(3,2,45,1), +(3,2,44,1), +(3,2,43,1), +(3,2,2361,1), +(3,2,4540,4), +(3,2,159,2), +(3,2,6948,1), +(3,2,14647,1), +(3,3,148,1), +(3,3,147,1), +(3,3,129,1), +(3,3,37,1), +(3,3,2508,1), +(3,3,159,2), +(3,3,117,4), +(3,3,6948,1), +(3,3,14647,1), +(3,3,2516,200), +(3,3,2102,1), +(3,4,49,1), +(3,4,48,1), +(3,4,47,1), +(3,4,2092,1), +(3,4,25861,100), +(3,4,4540,4), +(3,4,6948,1), +(3,4,14647,1), +(3,5,53,1), +(3,5,6098,1), +(3,5,52,1), +(3,5,51,1), +(3,5,36,1), +(3,5,159,2), +(3,5,4540,4), +(3,5,6948,1), +(3,5,14647,1), +(4,1,38,1), +(4,1,39,1), +(4,1,40,1), +(4,1,25,1), +(4,1,2362,1), +(4,1,117,4), +(4,1,6948,1), +(4,1,14648,1), +(4,3,148,1), +(4,3,147,1), +(4,3,129,1), +(4,3,2092,1), +(4,3,2504,1), +(4,3,159,2), +(4,3,117,4), +(4,3,6948,1), +(4,3,14648,1), +(4,3,2512,200), +(4,3,2101,1), +(4,4,49,1), +(4,4,48,1), +(4,4,47,1), +(4,4,2092,1), +(4,4,2947,100), +(4,4,4540,4), +(4,4,6948,1), +(4,4,14648,1), +(4,5,53,1), +(4,5,6119,1), +(4,5,52,1), +(4,5,51,1), +(4,5,36,1), +(4,5,2070,4), +(4,5,159,2), +(4,5,6948,1), +(4,5,14648,1), +(4,11,6123,1), +(4,11,44,1), +(4,11,3661,1), +(4,11,159,2), +(4,11,4536,4), +(4,11,6948,1), +(4,11,14648,1), +(5,1,6125,1), +(5,1,139,1), +(5,1,140,1), +(5,1,25,1), +(5,1,2362,1), +(5,1,4604,4), +(5,1,6948,1), +(5,1,14651,1), +(5,4,2105,1), +(5,4,120,1), +(5,4,121,1), +(5,4,2092,1), +(5,4,2947,100), +(5,4,4604,4), +(5,4,6948,1), +(5,4,14651,1), +(5,5,53,1), +(5,5,6144,1), +(5,5,52,1), +(5,5,51,1), +(5,5,36,1), +(5,5,4604,4), +(5,5,159,2), +(5,5,6948,1), +(5,5,14651,1), +(5,8,6096,1), +(5,8,6140,1), +(5,8,1395,1), +(5,8,55,1), +(5,8,35,1), +(5,8,4604,4), +(5,8,159,2), +(5,8,6948,1), +(5,8,14651,1), +(5,9,6129,1), +(5,9,1396,1), +(5,9,59,1), +(5,9,2092,1), +(5,9,4604,4), +(5,9,159,2), +(5,9,6948,1), +(5,9,14651,1), +(6,1,6125,1), +(6,1,139,1), +(6,1,2361,1), +(6,1,6948,1), +(6,1,4540,4), +(6,1,14650,1), +(6,3,127,1), +(6,3,6126,1), +(6,3,37,1), +(6,3,2508,1), +(6,3,159,2), +(6,3,117,4), +(6,3,6948,1), +(6,3,14650,1), +(6,3,2516,200), +(6,3,2102,1), +(6,7,154,1), +(6,7,153,1), +(6,7,36,1), +(6,7,6948,1), +(6,7,4604,4), +(6,7,159,2), +(6,7,14650,1), +(6,11,6139,1), +(6,11,6124,1), +(6,11,35,1), +(6,11,159,2), +(6,11,4536,4), +(6,11,6948,1), +(6,11,14650,1), +(7,1,38,1), +(7,1,39,1), +(7,1,40,1), +(7,1,25,1), +(7,1,2362,1), +(7,1,117,4), +(7,1,6948,1), +(7,1,14647,1), +(7,4,49,1), +(7,4,48,1), +(7,4,47,1), +(7,4,2092,1), +(7,4,2947,100), +(7,4,117,4), +(7,4,6948,1), +(7,4,14647,1), +(7,8,6096,1), +(7,8,56,1), +(7,8,1395,1), +(7,8,55,1), +(7,8,35,1), +(7,8,4536,4), +(7,8,159,2), +(7,8,6948,1), +(7,8,14647,1), +(7,9,6097,1), +(7,9,57,1), +(7,9,1396,1), +(7,9,59,1), +(7,9,2092,1), +(7,9,159,2), +(7,9,4604,4), +(7,9,6948,1), +(7,9,14647,1), +(8,1,6125,1), +(8,1,139,1), +(8,1,140,1), +(8,1,37,1), +(8,1,2362,1), +(8,1,25861,100), +(8,1,117,4), +(8,1,6948,1), +(8,1,14649,1), +(8,3,127,1), +(8,3,6126,1), +(8,3,6127,1), +(8,3,37,1), +(8,3,2504,1), +(8,3,4604,4), +(8,3,159,2), +(8,3,2512,200), +(8,3,2101,1), +(8,3,14649,1), +(8,3,6948,1), +(8,4,2105,1), +(8,4,120,1), +(8,4,121,1), +(8,4,2092,1), +(8,4,25861,100), +(8,4,117,4), +(8,4,6948,1), +(8,4,14649,1), +(8,5,53,1), +(8,5,6144,1), +(8,5,52,1), +(8,5,36,1), +(8,5,4540,4), +(8,5,159,2), +(8,5,6948,1), +(8,5,14649,1), +(8,7,6134,1), +(8,7,6135,1), +(8,7,36,1), +(8,7,117,4), +(8,7,159,2), +(8,7,6948,1), +(8,7,14649,1), +(8,8,6096,1), +(8,8,6140,1), +(8,8,1395,1), +(8,8,55,1), +(8,8,35,1), +(8,8,117,4), +(8,8,159,2), +(8,8,6948,1), +(8,8,14649,1), +(10,2,159,5), +(10,2,2070,5), +(10,2,6948,1), +(10,2,23346,1), +(10,2,24143,1), +(10,2,24145,1), +(10,2,24146,1), +(10,3,159,5), +(10,3,2101,1), +(10,3,2512,200), +(10,3,6948,1), +(10,3,20857,5), +(10,3,20899,1), +(10,3,20900,1), +(10,3,20901,1), +(10,3,20980,1), +(10,3,20982,1), +(10,4,3111,100), +(10,4,6948,1), +(10,4,20857,10), +(10,4,20896,1), +(10,4,20897,1), +(10,4,20898,1), +(10,4,20982,1), +(10,5,51,1), +(10,5,52,1), +(10,5,53,1), +(10,5,159,5), +(10,5,6948,1), +(10,5,20891,1), +(10,5,20981,5), +(10,8,35,1), +(10,8,159,5), +(10,8,6096,1), +(10,8,6948,1), +(10,8,20857,5), +(10,8,20893,1), +(10,8,20894,1), +(10,8,20895,1), +(10,9,59,1), +(10,9,159,5), +(10,9,1396,1), +(10,9,6948,1), +(10,9,20857,5), +(10,9,20892,1), +(10,9,20983,1), +(11,1,4540,5), +(11,1,6948,1), +(11,1,23346,1), +(11,1,23473,1), +(11,1,23474,1), +(11,1,23475,1), +(11,2,159,5), +(11,2,2361,1), +(11,2,4540,5), +(11,2,6948,1), +(11,2,23476,1), +(11,2,23476,1), +(11,2,23477,1), +(11,3,25,1), +(11,3,159,5), +(11,3,2101,1), +(11,3,2504,1), +(11,3,2512,200), +(11,3,4540,5), +(11,3,6948,1), +(11,3,23344,1), +(11,3,23345,1), +(11,3,23348,1), +(11,5,36,1), +(11,5,59,1), +(11,5,159,5), +(11,5,1396,1), +(11,5,4540,5), +(11,5,6097,1), +(11,5,6948,1), +(11,5,23322,1), +(11,7,36,1), +(11,7,159,5), +(11,7,4540,5), +(11,7,6948,1), +(11,7,23344,1), +(11,7,23345,1), +(11,7,23348,1), +(11,8,35,1), +(11,8,159,5), +(11,8,4540,5), +(11,8,6948,1), +(11,8,23473,1), +(11,8,23475,1), +(11,8,23478,1), +(11,8,23479,1); +/*!40000 ALTER TABLE `playercreateinfo_item` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `playercreateinfo_spell` +-- + +DROP TABLE IF EXISTS `playercreateinfo_spell`; +CREATE TABLE `playercreateinfo_spell` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `Spell` mediumint(8) unsigned NOT NULL default '0', + `Note` varchar(255) default NULL, + `Active` tinyint(3) unsigned NOT NULL default '1', + PRIMARY KEY (`race`,`class`,`Spell`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `playercreateinfo_spell` +-- + +LOCK TABLES `playercreateinfo_spell` WRITE; +/*!40000 ALTER TABLE `playercreateinfo_spell` DISABLE KEYS */; +INSERT INTO `playercreateinfo_spell` VALUES +(1,1,78,'Heroic Strike',1), +(1,1,81,'Dodge',1), +(1,1,107,'Block',1), +(1,1,196,'One-Handed Axes',1), +(1,1,198,'One-Handed Maces',1), +(1,1,201,'One-Handed Swords',1), +(1,1,203,'Unarmed',1), +(1,1,204,'Defense',1), +(1,1,522,'SPELLDEFENSE(DND)',1), +(1,1,668,'Language Common',1), +(1,1,2382,'Generic',1), +(1,1,2457,'Battle Stance',1), +(1,1,2479,'Honorless Target',1), +(1,1,3050,'Detect',1), +(1,1,3365,'Opening',1), +(1,1,5301,'Defensive State(DND)',1), +(1,1,6233,'Closing',1), +(1,1,6246,'Closing',1), +(1,1,6247,'Opening',1), +(1,1,6477,'Opening',1), +(1,1,6478,'Opening',1), +(1,1,6603,'Attack',1), +(1,1,7266,'Duel',1), +(1,1,7267,'Grovel',1), +(1,1,7355,'Stuck',1), +(1,1,7376,'Defensive Stance Passive',0), +(1,1,7381,'Berserker Stance Passive',0), +(1,1,8386,'Attacking',1), +(1,1,8737,'Mail',1), +(1,1,9077,'Leather',1), +(1,1,9078,'Cloth',1), +(1,1,9116,'Shield',1), +(1,1,9125,'Generic',1), +(1,1,20597,'Sword Specialization',1), +(1,1,20598,'The Human Spirit',1), +(1,1,20599,'Diplomacy',1), +(1,1,20600,'Perception',1), +(1,1,20864,'Mace Specialization',1), +(1,1,21156,'Battle Stance Passive',0), +(1,1,21651,'Opening',1), +(1,1,21652,'Closing',1), +(1,1,22027,'Remove Insignia',1), +(1,1,22810,'Opening - No Text',1), +(1,1,32215,'Victorious State',1), +(1,2,81,'Dodge',1), +(1,2,107,'Block',1), +(1,2,198,'One-Handed Maces',1), +(1,2,199,'Two-Handed Maces',1), +(1,2,203,'Unarmed',1), +(1,2,204,'Defense',1), +(1,2,522,'SPELLDEFENSE(DND)',1), +(1,2,635,'Holy Light',1), +(1,2,668,'Language Common',1), +(1,2,2382,'Generic',1), +(1,2,2479,'Honorless Target',1), +(1,2,3050,'Detect',1), +(1,2,3365,'Opening',1), +(1,2,6233,'Closing',1), +(1,2,6246,'Closing',1), +(1,2,6247,'Opening',1), +(1,2,6477,'Opening',1), +(1,2,6478,'Opening',1), +(1,2,6603,'Attack',1), +(1,2,7266,'Duel',1), +(1,2,7267,'Grovel',1), +(1,2,7355,'Stuck',1), +(1,2,8386,'Attacking',1), +(1,2,8737,'Mail',1), +(1,2,9077,'Leather',1), +(1,2,9078,'Cloth',1), +(1,2,9116,'Shield',1), +(1,2,9125,'Generic',1), +(1,2,21084,'Seal of Righteousness',1), +(1,2,20597,'Sword Specialization',1), +(1,2,20598,'The Human Spirit',1), +(1,2,20599,'Diplomacy',1), +(1,2,20600,'Perception',1), +(1,2,20864,'Mace Specialization',1), +(1,2,21651,'Opening',1), +(1,2,21652,'Closing',1), +(1,2,22027,'Remove Insignia',1), +(1,2,22810,'Opening - No Text',1), +(1,2,27762,'Libram',1), +(1,4,81,'Dodge',1), +(1,4,203,'Unarmed',1), +(1,4,204,'Defense',1), +(1,4,522,'SPELLDEFENSE(DND)',1), +(1,4,668,'Language Common',1), +(1,4,1180,'Daggers',1), +(1,4,1752,'Sinister Strike',1), +(1,4,2098,'Eviscerate',1), +(1,4,2382,'Generic',1), +(1,4,2479,'Honorless Target',1), +(1,4,2567,'Thrown',1), +(1,4,2764,'Throw',1), +(1,4,3050,'Detect',1), +(1,4,3365,'Opening',1), +(1,4,6233,'Closing',1), +(1,4,6246,'Closing',1), +(1,4,6247,'Opening',1), +(1,4,6477,'Opening',1), +(1,4,6478,'Opening',1), +(1,4,6603,'Attack',1), +(1,4,7266,'Duel',1), +(1,4,7267,'Grovel',1), +(1,4,7355,'Stuck',1), +(1,4,8386,'Attacking',1), +(1,4,9077,'Leather',1), +(1,4,9078,'Cloth',1), +(1,4,9125,'Generic',1), +(1,4,16092,'Defensive State(DND)',1), +(1,4,20597,'Sword Specialization',1), +(1,4,20598,'The Human Spirit',1), +(1,4,20599,'Diplomacy',1), +(1,4,20600,'Perception',1), +(1,4,20864,'Mace Specialization',1), +(1,4,21184,'Rogue Passive(DND)',1), +(1,4,21651,'Opening',1), +(1,4,21652,'Closing',1), +(1,4,22027,'Remove Insignia',1), +(1,4,22810,'Opening - No Text',1), +(1,5,81,'Dodge',1), +(1,5,198,'One-Handed Maces',1), +(1,5,203,'Unarmed',1), +(1,5,204,'Defense',1), +(1,5,522,'SPELLDEFENSE(DND)',1), +(1,5,585,'Smite',1), +(1,5,668,'Language Common',1), +(1,5,2050,'Lesser Heal',1), +(1,5,2382,'Generic',1), +(1,5,2479,'Honorless Target',1), +(1,5,3050,'Detect',1), +(1,5,3365,'Opening',1), +(1,5,5009,'Wands',1), +(1,5,5019,'Shoot',1), +(1,5,6233,'Closing',1), +(1,5,6246,'Closing',1), +(1,5,6247,'Opening',1), +(1,5,6477,'Opening',1), +(1,5,6478,'Opening',1), +(1,5,6603,'Attack',1), +(1,5,7266,'Duel',1), +(1,5,7267,'Grovel',1), +(1,5,7355,'Stuck',1), +(1,5,8386,'Attacking',1), +(1,5,9078,'Cloth',1), +(1,5,9125,'Generic',1), +(1,5,20597,'Sword Specialization',1), +(1,5,20598,'The Human Spirit',1), +(1,5,20599,'Diplomacy',1), +(1,5,20600,'Perception',1), +(1,5,20864,'Mace Specialization',1), +(1,5,21651,'Opening',1), +(1,5,21652,'Closing',1), +(1,5,22027,'Remove Insignia',1), +(1,5,22810,'Opening - No Text',1), +(1,8,81,'Dodge',1), +(1,8,133,'Fireball',1), +(1,8,168,'Frost Armor',1), +(1,8,203,'Unarmed',1), +(1,8,204,'Defense',1), +(1,8,227,'Staves',1), +(1,8,522,'SPELLDEFENSE(DND)',1), +(1,8,668,'Language Common',1), +(1,8,2382,'Generic',1), +(1,8,2479,'Honorless Target',1), +(1,8,3050,'Detect',1), +(1,8,3365,'Opening',1), +(1,8,5009,'Wands',1), +(1,8,5019,'Shoot',1), +(1,8,6233,'Closing',1), +(1,8,6246,'Closing',1), +(1,8,6247,'Opening',1), +(1,8,6477,'Opening',1), +(1,8,6478,'Opening',1), +(1,8,6603,'Attack',1), +(1,8,7266,'Duel',1), +(1,8,7267,'Grovel',1), +(1,8,7355,'Stuck',1), +(1,8,8386,'Attacking',1), +(1,8,9078,'Cloth',1), +(1,8,9125,'Generic',1), +(1,8,20597,'Sword Specialization',1), +(1,8,20598,'The Human Spirit',1), +(1,8,20599,'Diplomacy',1), +(1,8,20600,'Perception',1), +(1,8,20864,'Mace Specialization',1), +(1,8,21651,'Opening',1), +(1,8,21652,'Closing',1), +(1,8,22027,'Remove Insignia',1), +(1,8,22810,'Opening - No Text',1), +(1,9,81,'Dodge',1), +(1,9,203,'Unarmed',1), +(1,9,204,'Defense',1), +(1,9,522,'SPELLDEFENSE(DND)',1), +(1,9,668,'Language Common',1), +(1,9,686,'Shadow Bolt',1), +(1,9,687,'Demon Skin',1), +(1,9,1180,'Daggers',1), +(1,9,2382,'Generic',1), +(1,9,2479,'Honorless Target',1), +(1,9,3050,'Detect',1), +(1,9,3365,'Opening',1), +(1,9,5009,'Wands',1), +(1,9,5019,'Shoot',1), +(1,9,6233,'Closing',1), +(1,9,6246,'Closing',1), +(1,9,6247,'Opening',1), +(1,9,6477,'Opening',1), +(1,9,6478,'Opening',1), +(1,9,6603,'Attack',1), +(1,9,7266,'Duel',1), +(1,9,7267,'Grovel',1), +(1,9,7355,'Stuck',1), +(1,9,8386,'Attacking',1), +(1,9,9078,'Cloth',1), +(1,9,9125,'Generic',1), +(1,9,20597,'Sword Specialization',1), +(1,9,20598,'The Human Spirit',1), +(1,9,20599,'Diplomacy',1), +(1,9,20600,'Perception',1), +(1,9,20864,'Mace Specialization',1), +(1,9,21651,'Opening',1), +(1,9,21652,'Closing',1), +(1,9,22027,'Remove Insignia',1), +(1,9,22810,'Opening - No Text',1), +(2,1,78,'Heroic Strike',1), +(2,1,81,'Dodge',1), +(2,1,107,'Block',1), +(2,1,196,'One-Handed Axes',1), +(2,1,197,'Two-Handed Axes',1), +(2,1,201,'One-Handed Swords',1), +(2,1,203,'Unarmed',1), +(2,1,204,'Defense',1), +(2,1,522,'SPELLDEFENSE(DND)',1), +(2,1,669,'Language Orcish',1), +(2,1,2382,'Generic',1), +(2,1,2457,'Battle Stance',1), +(2,1,2479,'Honorless Target',1), +(2,1,3050,'Detect',1), +(2,1,3365,'Opening',1), +(2,1,5301,'Defensive State(DND)',1), +(2,1,6233,'Closing',1), +(2,1,6246,'Closing',1), +(2,1,6247,'Opening',1), +(2,1,6477,'Opening',1), +(2,1,6478,'Opening',1), +(2,1,6603,'Attack',1), +(2,1,7266,'Duel',1), +(2,1,7267,'Grovel',1), +(2,1,7355,'Stuck',1), +(2,1,7376,'Defensive Stance Passive',0), +(2,1,7381,'Berserker Stance Passive',0), +(2,1,8386,'Attacking',1), +(2,1,8737,'Mail',1), +(2,1,9077,'Leather',1), +(2,1,9078,'Cloth',1), +(2,1,9116,'Shield',1), +(2,1,9125,'Generic',1), +(2,1,20572,'Blood Fury',1), +(2,1,20573,'Hardiness',1), +(2,1,20574,'Axe Specialization',1), +(2,1,21156,'Battle Stance Passive',0), +(2,1,21563,'Command',1), +(2,1,21651,'Opening',1), +(2,1,21652,'Closing',1), +(2,1,22027,'Remove Insignia',1), +(2,1,22810,'Opening - No Text',1), +(2,1,32215,'Victorious State',1), +(2,3,75,'Auto Shot',1), +(2,3,81,'Dodge',1), +(2,3,196,'One-Handed Axes',1), +(2,3,203,'Unarmed',1), +(2,3,204,'Defense',1), +(2,3,264,'Bows',1), +(2,3,522,'SPELLDEFENSE(DND)',1), +(2,3,669,'Language Orcish',1), +(2,3,2382,'Generic',1), +(2,3,2479,'Honorless Target',1), +(2,3,2973,'Raptor Strike',1), +(2,3,3050,'Detect',1), +(2,3,3365,'Opening',1), +(2,3,6233,'Closing',1), +(2,3,6246,'Closing',1), +(2,3,6247,'Opening',1), +(2,3,6477,'Opening',1), +(2,3,6478,'Opening',1), +(2,3,6603,'Attack',1), +(2,3,7266,'Duel',1), +(2,3,7267,'Grovel',1), +(2,3,7355,'Stuck',1), +(2,3,8386,'Attacking',1), +(2,3,9077,'Leather',1), +(2,3,9078,'Cloth',1), +(2,3,9125,'Generic',1), +(2,3,13358,'Defensive State(DND)',1), +(2,3,20572,'Blood Fury',1), +(2,3,20573,'Hardiness',1), +(2,3,20574,'Axe Specialization',1), +(2,3,20576,'Command',1), +(2,3,21651,'Opening',1), +(2,3,21652,'Closing',1), +(2,3,22027,'Remove Insignia',1), +(2,3,22810,'Opening - No Text',1), +(2,3,24949,'Defensive State 2(DND)',1), +(2,3,34082,'Advantaged State(DND)',1), +(2,4,81,'Dodge',1), +(2,4,203,'Unarmed',1), +(2,4,204,'Defense',1), +(2,4,522,'SPELLDEFENSE(DND)',1), +(2,4,669,'Language Orcish',1), +(2,4,1180,'Daggers',1), +(2,4,1752,'Sinister Strike',1), +(2,4,2098,'Eviscerate',1), +(2,4,2382,'Generic',1), +(2,4,2479,'Honorless Target',1), +(2,4,2567,'Thrown',1), +(2,4,2764,'Throw',1), +(2,4,3050,'Detect',1), +(2,4,3365,'Opening',1), +(2,4,6233,'Closing',1), +(2,4,6246,'Closing',1), +(2,4,6247,'Opening',1), +(2,4,6477,'Opening',1), +(2,4,6478,'Opening',1), +(2,4,6603,'Attack',1), +(2,4,7266,'Duel',1), +(2,4,7267,'Grovel',1), +(2,4,7355,'Stuck',1), +(2,4,8386,'Attacking',1), +(2,4,9077,'Leather',1), +(2,4,9078,'Cloth',1), +(2,4,9125,'Generic',1), +(2,4,16092,'Defensive State(DND)',1), +(2,4,20572,'Blood Fury',1), +(2,4,20573,'Hardiness',1), +(2,4,20574,'Axe Specialization',1), +(2,4,21184,'Rogue Passive(DND)',1), +(2,4,21563,'Command',1), +(2,4,21651,'Opening',1), +(2,4,21652,'Closing',1), +(2,4,22027,'Remove Insignia',1), +(2,4,22810,'Opening - No Text',1), +(2,7,81,'Dodge',1), +(2,7,107,'Block',1), +(2,7,198,'One-Handed Maces',1), +(2,7,203,'Unarmed',1), +(2,7,204,'Defense',1), +(2,7,227,'Staves',1), +(2,7,331,'Healing Wave',1), +(2,7,403,'Lightning Bolt',1), +(2,7,522,'SPELLDEFENSE(DND)',1), +(2,7,669,'Language Orcish',1), +(2,7,2382,'Generic',1), +(2,7,2479,'Honorless Target',1), +(2,7,3050,'Detect',1), +(2,7,3365,'Opening',1), +(2,7,6233,'Closing',1), +(2,7,6246,'Closing',1), +(2,7,6247,'Opening',1), +(2,7,6477,'Opening',1), +(2,7,6478,'Opening',1), +(2,7,6603,'Attack',1), +(2,7,7266,'Duel',1), +(2,7,7267,'Grovel',1), +(2,7,7355,'Stuck',1), +(2,7,8386,'Attacking',1), +(2,7,9077,'Leather',1), +(2,7,9078,'Cloth',1), +(2,7,9116,'Shield',1), +(2,7,9125,'Generic',1), +(2,7,20573,'Hardiness',1), +(2,7,20574,'Axe Specialization',1), +(2,7,21563,'Command',1), +(2,7,21651,'Opening',1), +(2,7,21652,'Closing',1), +(2,7,22027,'Remove Insignia',1), +(2,7,22810,'Opening - No Text',1), +(2,7,27763,'Totem',1), +(2,7,33697,'Blood Fury',1), +(2,9,81,'Dodge',1), +(2,9,203,'Unarmed',1), +(2,9,204,'Defense',1), +(2,9,522,'SPELLDEFENSE(DND)',1), +(2,9,669,'Language Orcish',1), +(2,9,686,'Shadow Bolt',1), +(2,9,687,'Demon Skin',1), +(2,9,1180,'Daggers',1), +(2,9,2382,'Generic',1), +(2,9,2479,'Honorless Target',1), +(2,9,3050,'Detect',1), +(2,9,3365,'Opening',1), +(2,9,5009,'Wands',1), +(2,9,5019,'Shoot',1), +(2,9,6233,'Closing',1), +(2,9,6246,'Closing',1), +(2,9,6247,'Opening',1), +(2,9,6477,'Opening',1), +(2,9,6478,'Opening',1), +(2,9,6603,'Attack',1), +(2,9,7266,'Duel',1), +(2,9,7267,'Grovel',1), +(2,9,7355,'Stuck',1), +(2,9,8386,'Attacking',1), +(2,9,9078,'Cloth',1), +(2,9,9125,'Generic',1), +(2,9,20573,'Hardiness',1), +(2,9,20574,'Axe Specialization',1), +(2,9,20575,'Command',1), +(2,9,21651,'Opening',1), +(2,9,21652,'Closing',1), +(2,9,22027,'Remove Insignia',1), +(2,9,22810,'Opening - No Text',1), +(2,9,33702,'Blood Fury',1), +(3,1,78,'Heroic Strike',1), +(3,1,81,'Dodge',1), +(3,1,107,'Block',1), +(3,1,196,'One-Handed Axes',1), +(3,1,197,'Two-Handed Axes',1), +(3,1,198,'One-Handed Maces',1), +(3,1,203,'Unarmed',1), +(3,1,204,'Defense',1), +(3,1,522,'SPELLDEFENSE(DND)',1), +(3,1,668,'Language Common',1), +(3,1,672,'Language Dwarven',1), +(3,1,2382,'Generic',1), +(3,1,2457,'Battle Stance',1), +(3,1,2479,'Honorless Target',1), +(3,1,2481,'Find Treasure',1), +(3,1,3050,'Detect',1), +(3,1,3365,'Opening',1), +(3,1,5301,'Defensive State(DND)',1), +(3,1,6233,'Closing',1), +(3,1,6246,'Closing',1), +(3,1,6247,'Opening',1), +(3,1,6477,'Opening',1), +(3,1,6478,'Opening',1), +(3,1,6603,'Attack',1), +(3,1,7266,'Duel',1), +(3,1,7267,'Grovel',1), +(3,1,7355,'Stuck',1), +(3,1,7376,'Defensive Stance Passive',0), +(3,1,7381,'Berserker Stance Passive',0), +(3,1,8386,'Attacking',1), +(3,1,8737,'Mail',1), +(3,1,9077,'Leather',1), +(3,1,9078,'Cloth',1), +(3,1,9116,'Shield',1), +(3,1,9125,'Generic',1), +(3,1,20594,'Stoneform',1), +(3,1,20595,'Gun Specialization',1), +(3,1,20596,'Frost Resistance',1), +(3,1,21156,'Battle Stance Passive',0), +(3,1,21651,'Opening',1), +(3,1,21652,'Closing',1), +(3,1,22027,'Remove Insignia',1), +(3,1,22810,'Opening - No Text',1), +(3,1,32215,'Victorious State',1), +(3,2,81,'Dodge',1), +(3,2,107,'Block',1), +(3,2,198,'One-Handed Maces',1), +(3,2,199,'Two-Handed Maces',1), +(3,2,203,'Unarmed',1), +(3,2,204,'Defense',1), +(3,2,522,'SPELLDEFENSE(DND)',1), +(3,2,635,'Holy Light',1), +(3,2,668,'Language Common',1), +(3,2,672,'Language Dwarven',1), +(3,2,2382,'Generic',1), +(3,2,2479,'Honorless Target',1), +(3,2,2481,'Find Treasure',1), +(3,2,3050,'Detect',1), +(3,2,3365,'Opening',1), +(3,2,6233,'Closing',1), +(3,2,6246,'Closing',1), +(3,2,6247,'Opening',1), +(3,2,6477,'Opening',1), +(3,2,6478,'Opening',1), +(3,2,6603,'Attack',1), +(3,2,7266,'Duel',1), +(3,2,7267,'Grovel',1), +(3,2,7355,'Stuck',1), +(3,2,8386,'Attacking',1), +(3,2,8737,'Mail',1), +(3,2,9077,'Leather',1), +(3,2,9078,'Cloth',1), +(3,2,9116,'Shield',1), +(3,2,9125,'Generic',1), +(3,2,21084,'Seal of Righteousness',1), +(3,2,20594,'Stoneform',1), +(3,2,20595,'Gun Specialization',1), +(3,2,20596,'Frost Resistance',1), +(3,2,21651,'Opening',1), +(3,2,21652,'Closing',1), +(3,2,22027,'Remove Insignia',1), +(3,2,22810,'Opening - No Text',1), +(3,2,27762,'Libram',1), +(3,3,75,'Auto Shot',1), +(3,3,81,'Dodge',1), +(3,3,196,'One-Handed Axes',1), +(3,3,203,'Unarmed',1), +(3,3,204,'Defense',1), +(3,3,266,'Guns',1), +(3,3,522,'SPELLDEFENSE(DND)',1), +(3,3,668,'Language Common',1), +(3,3,672,'Language Dwarven',1), +(3,3,2382,'Generic',1), +(3,3,2479,'Honorless Target',1), +(3,3,2481,'Find Treasure',1), +(3,3,2973,'Raptor Strike',1), +(3,3,3050,'Detect',1), +(3,3,3365,'Opening',1), +(3,3,6233,'Closing',1), +(3,3,6246,'Closing',1), +(3,3,6247,'Opening',1), +(3,3,6477,'Opening',1), +(3,3,6478,'Opening',1), +(3,3,6603,'Attack',1), +(3,3,7266,'Duel',1), +(3,3,7267,'Grovel',1), +(3,3,7355,'Stuck',1), +(3,3,8386,'Attacking',1), +(3,3,9077,'Leather',1), +(3,3,9078,'Cloth',1), +(3,3,9125,'Generic',1), +(3,3,13358,'Defensive State(DND)',1), +(3,3,20594,'Stoneform',1), +(3,3,20595,'Gun Specialization',1), +(3,3,20596,'Frost Resistance',1), +(3,3,21651,'Opening',1), +(3,3,21652,'Closing',1), +(3,3,22027,'Remove Insignia',1), +(3,3,22810,'Opening - No Text',1), +(3,3,24949,'Defensive State 2(DND)',1), +(3,3,34082,'Advantaged State(DND)',1), +(3,4,81,'Dodge',1), +(3,4,203,'Unarmed',1), +(3,4,204,'Defense',1), +(3,4,522,'SPELLDEFENSE(DND)',1), +(3,4,668,'Language Common',1), +(3,4,672,'Language Dwarven',1), +(3,4,1180,'Daggers',1), +(3,4,1752,'Sinister Strike',1), +(3,4,2098,'Eviscerate',1), +(3,4,2382,'Generic',1), +(3,4,2479,'Honorless Target',1), +(3,4,2481,'Find Treasure',1), +(3,4,2567,'Thrown',1), +(3,4,2764,'Throw',1), +(3,4,3050,'Detect',1), +(3,4,3365,'Opening',1), +(3,4,6233,'Closing',1), +(3,4,6246,'Closing',1), +(3,4,6247,'Opening',1), +(3,4,6477,'Opening',1), +(3,4,6478,'Opening',1), +(3,4,6603,'Attack',1), +(3,4,7266,'Duel',1), +(3,4,7267,'Grovel',1), +(3,4,7355,'Stuck',1), +(3,4,8386,'Attacking',1), +(3,4,9077,'Leather',1), +(3,4,9078,'Cloth',1), +(3,4,9125,'Generic',1), +(3,4,16092,'Defensive State(DND)',1), +(3,4,20594,'Stoneform',1), +(3,4,20595,'Gun Specialization',1), +(3,4,20596,'Frost Resistance',1), +(3,4,21184,'Rogue Passive(DND)',1), +(3,4,21651,'Opening',1), +(3,4,21652,'Closing',1), +(3,4,22027,'Remove Insignia',1), +(3,4,22810,'Opening - No Text',1), +(3,5,81,'Dodge',1), +(3,5,198,'One-Handed Maces',1), +(3,5,203,'Unarmed',1), +(3,5,204,'Defense',1), +(3,5,522,'SPELLDEFENSE(DND)',1), +(3,5,585,'Smite',1), +(3,5,668,'Language Common',1), +(3,5,672,'Language Dwarven',1), +(3,5,2050,'Lesser Heal',1), +(3,5,2382,'Generic',1), +(3,5,2479,'Honorless Target',1), +(3,5,2481,'Find Treasure',1), +(3,5,3050,'Detect',1), +(3,5,3365,'Opening',1), +(3,5,5009,'Wands',1), +(3,5,5019,'Shoot',1), +(3,5,6233,'Closing',1), +(3,5,6246,'Closing',1), +(3,5,6247,'Opening',1), +(3,5,6477,'Opening',1), +(3,5,6478,'Opening',1), +(3,5,6603,'Attack',1), +(3,5,7266,'Duel',1), +(3,5,7267,'Grovel',1), +(3,5,7355,'Stuck',1), +(3,5,8386,'Attacking',1), +(3,5,9078,'Cloth',1), +(3,5,9125,'Generic',1), +(3,5,20594,'Stoneform',1), +(3,5,20595,'Gun Specialization',1), +(3,5,20596,'Frost Resistance',1), +(3,5,21651,'Opening',1), +(3,5,21652,'Closing',1), +(3,5,22027,'Remove Insignia',1), +(3,5,22810,'Opening - No Text',1), +(4,1,78,'Heroic Strike',1), +(4,1,81,'Dodge',1), +(4,1,107,'Block',1), +(4,1,198,'One-Handed Maces',1), +(4,1,201,'One-Handed Swords',1), +(4,1,203,'Unarmed',1), +(4,1,204,'Defense',1), +(4,1,522,'SPELLDEFENSE(DND)',1), +(4,1,668,'Language Common',1), +(4,1,671,'Language Darnassian',1), +(4,1,1180,'Daggers',1), +(4,1,2382,'Generic',1), +(4,1,2457,'Battle Stance',1), +(4,1,2479,'Honorless Target',1), +(4,1,3050,'Detect',1), +(4,1,3365,'Opening',1), +(4,1,5301,'Defensive State(DND)',1), +(4,1,6233,'Closing',1), +(4,1,6246,'Closing',1), +(4,1,6247,'Opening',1), +(4,1,6477,'Opening',1), +(4,1,6478,'Opening',1), +(4,1,6603,'Attack',1), +(4,1,7266,'Duel',1), +(4,1,7267,'Grovel',1), +(4,1,7355,'Stuck',1), +(4,1,7376,'Defensive Stance Passive',0), +(4,1,7381,'Berserker Stance Passive',0), +(4,1,8386,'Attacking',1), +(4,1,8737,'Mail',1), +(4,1,9077,'Leather',1), +(4,1,9078,'Cloth',1), +(4,1,9116,'Shield',1), +(4,1,9125,'Generic',1), +(4,1,20580,'Shadowmeld',1), +(4,1,20582,'Quickness',1), +(4,1,20583,'Nature Resistance',1), +(4,1,20585,'Wisp Spirit',1), +(4,1,21009,'Shadowmeld Passive',1), +(4,1,21156,'Battle Stance Passive',0), +(4,1,21651,'Opening',1), +(4,1,21652,'Closing',1), +(4,1,22027,'Remove Insignia',1), +(4,1,22810,'Opening - No Text',1), +(4,1,32215,'Victorious State',1), +(4,3,75,'Auto Shot',1), +(4,3,81,'Dodge',1), +(4,3,203,'Unarmed',1), +(4,3,204,'Defense',1), +(4,3,264,'Bows',1), +(4,3,522,'SPELLDEFENSE(DND)',1), +(4,3,668,'Language Common',1), +(4,3,671,'Language Darnassian',1), +(4,3,1180,'Daggers',1), +(4,3,2382,'Generic',1), +(4,3,2479,'Honorless Target',1), +(4,3,2973,'Raptor Strike',1), +(4,3,3050,'Detect',1), +(4,3,3365,'Opening',1), +(4,3,6233,'Closing',1), +(4,3,6246,'Closing',1), +(4,3,6247,'Opening',1), +(4,3,6477,'Opening',1), +(4,3,6478,'Opening',1), +(4,3,6603,'Attack',1), +(4,3,7266,'Duel',1), +(4,3,7267,'Grovel',1), +(4,3,7355,'Stuck',1), +(4,3,8386,'Attacking',1), +(4,3,9077,'Leather',1), +(4,3,9078,'Cloth',1), +(4,3,9125,'Generic',1), +(4,3,13358,'Defensive State(DND)',1), +(4,3,20580,'Shadowmeld',1), +(4,3,20582,'Quickness',1), +(4,3,20583,'Nature Resistance',1), +(4,3,20585,'Wisp Spirit',1), +(4,3,21009,'Shadowmeld Passive',1), +(4,3,21651,'Opening',1), +(4,3,21652,'Closing',1), +(4,3,22027,'Remove Insignia',1), +(4,3,22810,'Opening - No Text',1), +(4,3,24949,'Defensive State 2(DND)',1), +(4,3,34082,'Advantaged State(DND)',1), +(4,4,81,'Dodge',1), +(4,4,203,'Unarmed',1), +(4,4,204,'Defense',1), +(4,4,522,'SPELLDEFENSE(DND)',1), +(4,4,668,'Language Common',1), +(4,4,671,'Language Darnassian',1), +(4,4,1180,'Daggers',1), +(4,4,1752,'Sinister Strike',1), +(4,4,2098,'Eviscerate',1), +(4,4,2382,'Generic',1), +(4,4,2479,'Honorless Target',1), +(4,4,2567,'Thrown',1), +(4,4,2764,'Throw',1), +(4,4,3050,'Detect',1), +(4,4,3365,'Opening',1), +(4,4,6233,'Closing',1), +(4,4,6246,'Closing',1), +(4,4,6247,'Opening',1), +(4,4,6477,'Opening',1), +(4,4,6478,'Opening',1), +(4,4,6603,'Attack',1), +(4,4,7266,'Duel',1), +(4,4,7267,'Grovel',1), +(4,4,7355,'Stuck',1), +(4,4,8386,'Attacking',1), +(4,4,9077,'Leather',1), +(4,4,9078,'Cloth',1), +(4,4,9125,'Generic',1), +(4,4,16092,'Defensive State(DND)',1), +(4,4,20580,'Shadowmeld',1), +(4,4,20582,'Quickness',1), +(4,4,20583,'Nature Resistance',1), +(4,4,20585,'Wisp Spirit',1), +(4,4,21009,'Shadowmeld Passive',1), +(4,4,21184,'Rogue Passive(DND)',1), +(4,4,21651,'Opening',1), +(4,4,21652,'Closing',1), +(4,4,22027,'Remove Insignia',1), +(4,4,22810,'Opening - No Text',1), +(4,5,81,'Dodge',1), +(4,5,198,'One-Handed Maces',1), +(4,5,203,'Unarmed',1), +(4,5,204,'Defense',1), +(4,5,522,'SPELLDEFENSE(DND)',1), +(4,5,585,'Smite',1), +(4,5,668,'Language Common',1), +(4,5,671,'Language Darnassian',1), +(4,5,2050,'Lesser Heal',1), +(4,5,2382,'Generic',1), +(4,5,2479,'Honorless Target',1), +(4,5,3050,'Detect',1), +(4,5,3365,'Opening',1), +(4,5,5009,'Wands',1), +(4,5,5019,'Shoot',1), +(4,5,6233,'Closing',1), +(4,5,6246,'Closing',1), +(4,5,6247,'Opening',1), +(4,5,6477,'Opening',1), +(4,5,6478,'Opening',1), +(4,5,6603,'Attack',1), +(4,5,7266,'Duel',1), +(4,5,7267,'Grovel',1), +(4,5,7355,'Stuck',1), +(4,5,8386,'Attacking',1), +(4,5,9078,'Cloth',1), +(4,5,9125,'Generic',1), +(4,5,20580,'Shadowmeld',1), +(4,5,20582,'Quickness',1), +(4,5,20583,'Nature Resistance',1), +(4,5,20585,'Wisp Spirit',1), +(4,5,21009,'Shadowmeld Passive',1), +(4,5,21651,'Opening',1), +(4,5,21652,'Closing',1), +(4,5,22027,'Remove Insignia',1), +(4,5,22810,'Opening - No Text',1), +(4,11,81,'Dodge',1), +(4,11,203,'Unarmed',1), +(4,11,204,'Defense',1), +(4,11,227,'Staves',1), +(4,11,522,'SPELLDEFENSE(DND)',1), +(4,11,668,'Language Common',1), +(4,11,671,'Language Darnassian',1), +(4,11,1178,'Bear Form(Passive)',0), +(4,11,1180,'Daggers',1), +(4,11,2382,'Generic',1), +(4,11,2479,'Honorless Target',1), +(4,11,3025,'Cat Form(Passive)',0), +(4,11,3050,'Detect',1), +(4,11,3365,'Opening',1), +(4,11,5176,'Wrath',1), +(4,11,5185,'Healing Touch',1), +(4,11,5419,'Travel Form(Passive)',0), +(4,11,5420,'Tree of Life',0), +(4,11,5421,'Aquatic Form(Passive)',0), +(4,11,6233,'Closing',1), +(4,11,6246,'Closing',1), +(4,11,6247,'Opening',1), +(4,11,6477,'Opening',1), +(4,11,6478,'Opening',1), +(4,11,6603,'Attack',1), +(4,11,7266,'Duel',1), +(4,11,7267,'Grovel',1), +(4,11,7355,'Stuck',1), +(4,11,8386,'Attacking',1), +(4,11,9077,'Leather',1), +(4,11,9078,'Cloth',1), +(4,11,9125,'Generic',1), +(4,11,9635,'Dire Bear Form(Passive)',0), +(4,11,20580,'Shadowmeld',1), +(4,11,20582,'Quickness',1), +(4,11,20583,'Nature Resistance',1), +(4,11,20585,'Wisp Spirit',1), +(4,11,21009,'Shadowmeld Passive',1), +(4,11,21178,'Bear Form(Passive2)',0), +(4,11,21651,'Opening',1), +(4,11,21652,'Closing',1), +(4,11,22027,'Remove Insignia',1), +(4,11,22810,'Opening - No Text',1), +(4,11,24905,'Moonkin Form(Passive)',0), +(4,11,27764,'Fetish',1), +(4,11,33948,'Flight Form(Passive)',0), +(4,11,34123,'Tree of Life(Passive)',0), +(4,11,40121,'Swift Flight Form(Passive)',0), +(5,1,78,'Heroic Strike',1), +(5,1,81,'Dodge',1), +(5,1,107,'Block',1), +(5,1,201,'One-Handed Swords',1), +(5,1,202,'Two-Handed Swords',1), +(5,1,203,'Unarmed',1), +(5,1,204,'Defense',1), +(5,1,522,'SPELLDEFENSE(DND)',1), +(5,1,669,'Language Orcish',1), +(5,1,1180,'Daggers',1), +(5,1,2382,'Generic',1), +(5,1,2457,'Battle Stance',1), +(5,1,2479,'Honorless Target',1), +(5,1,3050,'Detect',1), +(5,1,3365,'Opening',1), +(5,1,5227,'Underwater Breathing',1), +(5,1,5301,'Defensive State(DND)',1), +(5,1,6233,'Closing',1), +(5,1,6246,'Closing',1), +(5,1,6247,'Opening',1), +(5,1,6477,'Opening',1), +(5,1,6478,'Opening',1), +(5,1,6603,'Attack',1), +(5,1,7266,'Duel',1), +(5,1,7267,'Grovel',1), +(5,1,7355,'Stuck',1), +(5,1,7376,'Defensive Stance Passive',0), +(5,1,7381,'Berserker Stance Passive',0), +(5,1,7744,'Will of the Forsaken',1), +(5,1,8386,'Attacking',1), +(5,1,8737,'Mail',1), +(5,1,9077,'Leather',1), +(5,1,9078,'Cloth',1), +(5,1,9116,'Shield',1), +(5,1,9125,'Generic',1), +(5,1,17737,'Language Gutterspeak',1), +(5,1,20577,'Cannibalize',1), +(5,1,20579,'Shadow Resistance',1), +(5,1,21156,'Battle Stance Passive',0), +(5,1,21651,'Opening',1), +(5,1,21652,'Closing',1), +(5,1,22027,'Remove Insignia',1), +(5,1,22810,'Opening - No Text',1), +(5,1,32215,'Victorious State',1), +(5,4,81,'Dodge',1), +(5,4,203,'Unarmed',1), +(5,4,204,'Defense',1), +(5,4,522,'SPELLDEFENSE(DND)',1), +(5,4,669,'Language Orcish',1), +(5,4,1180,'Daggers',1), +(5,4,1752,'Sinister Strike',1), +(5,4,2098,'Eviscerate',1), +(5,4,2382,'Generic',1), +(5,4,2479,'Honorless Target',1), +(5,4,2567,'Thrown',1), +(5,4,2764,'Throw',1), +(5,4,3050,'Detect',1), +(5,4,3365,'Opening',1), +(5,4,5227,'Underwater Breathing',1), +(5,4,6233,'Closing',1), +(5,4,6246,'Closing',1), +(5,4,6247,'Opening',1), +(5,4,6477,'Opening',1), +(5,4,6478,'Opening',1), +(5,4,6603,'Attack',1), +(5,4,7266,'Duel',1), +(5,4,7267,'Grovel',1), +(5,4,7355,'Stuck',1), +(5,4,7744,'Will of the Forsaken',1), +(5,4,8386,'Attacking',1), +(5,4,9077,'Leather',1), +(5,4,9078,'Cloth',1), +(5,4,9125,'Generic',1), +(5,4,16092,'Defensive State(DND)',1), +(5,4,17737,'Language Gutterspeak',1), +(5,4,20577,'Cannibalize',1), +(5,4,20579,'Shadow Resistance',1), +(5,4,21184,'Rogue Passive(DND)',1), +(5,4,21651,'Opening',1), +(5,4,21652,'Closing',1), +(5,4,22027,'Remove Insignia',1), +(5,4,22810,'Opening - No Text',1), +(5,5,81,'Dodge',1), +(5,5,198,'One-Handed Maces',1), +(5,5,203,'Unarmed',1), +(5,5,204,'Defense',1), +(5,5,522,'SPELLDEFENSE(DND)',1), +(5,5,585,'Smite',1), +(5,5,669,'Language Orcish',1), +(5,5,2050,'Lesser Heal',1), +(5,5,2382,'Generic',1), +(5,5,2479,'Honorless Target',1), +(5,5,3050,'Detect',1), +(5,5,3365,'Opening',1), +(5,5,5009,'Wands',1), +(5,5,5019,'Shoot',1), +(5,5,5227,'Underwater Breathing',1), +(5,5,6233,'Closing',1), +(5,5,6246,'Closing',1), +(5,5,6247,'Opening',1), +(5,5,6477,'Opening',1), +(5,5,6478,'Opening',1), +(5,5,6603,'Attack',1), +(5,5,7266,'Duel',1), +(5,5,7267,'Grovel',1), +(5,5,7355,'Stuck',1), +(5,5,7744,'Will of the Forsaken',1), +(5,5,8386,'Attacking',1), +(5,5,9078,'Cloth',1), +(5,5,9125,'Generic',1), +(5,5,17737,'Language Gutterspeak',1), +(5,5,20577,'Cannibalize',1), +(5,5,20579,'Shadow Resistance',1), +(5,5,21651,'Opening',1), +(5,5,21652,'Closing',1), +(5,5,22027,'Remove Insignia',1), +(5,5,22810,'Opening - No Text',1), +(5,8,81,'Dodge',1), +(5,8,133,'Fireball',1), +(5,8,168,'Frost Armor',1), +(5,8,203,'Unarmed',1), +(5,8,204,'Defense',1), +(5,8,227,'Staves',1), +(5,8,522,'SPELLDEFENSE(DND)',1), +(5,8,669,'Language Orcish',1), +(5,8,2382,'Generic',1), +(5,8,2479,'Honorless Target',1), +(5,8,3050,'Detect',1), +(5,8,3365,'Opening',1), +(5,8,5009,'Wands',1), +(5,8,5019,'Shoot',1), +(5,8,5227,'Underwater Breathing',1), +(5,8,6233,'Closing',1), +(5,8,6246,'Closing',1), +(5,8,6247,'Opening',1), +(5,8,6477,'Opening',1), +(5,8,6478,'Opening',1), +(5,8,6603,'Attack',1), +(5,8,7266,'Duel',1), +(5,8,7267,'Grovel',1), +(5,8,7355,'Stuck',1), +(5,8,7744,'Will of the Forsaken',1), +(5,8,8386,'Attacking',1), +(5,8,9078,'Cloth',1), +(5,8,9125,'Generic',1), +(5,8,17737,'Language Gutterspeak',1), +(5,8,20577,'Cannibalize',1), +(5,8,20579,'Shadow Resistance',1), +(5,8,21651,'Opening',1), +(5,8,21652,'Closing',1), +(5,8,22027,'Remove Insignia',1), +(5,8,22810,'Opening - No Text',1), +(5,9,81,'Dodge',1), +(5,9,203,'Unarmed',1), +(5,9,204,'Defense',1), +(5,9,522,'SPELLDEFENSE(DND)',1), +(5,9,669,'Language Orcish',1), +(5,9,686,'Shadow Bolt',1), +(5,9,687,'Demon Skin',1), +(5,9,1180,'Daggers',1), +(5,9,2382,'Generic',1), +(5,9,2479,'Honorless Target',1), +(5,9,3050,'Detect',1), +(5,9,3365,'Opening',1), +(5,9,5009,'Wands',1), +(5,9,5019,'Shoot',1), +(5,9,5227,'Underwater Breathing',1), +(5,9,6233,'Closing',1), +(5,9,6246,'Closing',1), +(5,9,6247,'Opening',1), +(5,9,6477,'Opening',1), +(5,9,6478,'Opening',1), +(5,9,6603,'Attack',1), +(5,9,7266,'Duel',1), +(5,9,7267,'Grovel',1), +(5,9,7355,'Stuck',1), +(5,9,7744,'Will of the Forsaken',1), +(5,9,8386,'Attacking',1), +(5,9,9078,'Cloth',1), +(5,9,9125,'Generic',1), +(5,9,17737,'Language Gutterspeak',1), +(5,9,20577,'Cannibalize',1), +(5,9,20579,'Shadow Resistance',1), +(5,9,21651,'Opening',1), +(5,9,21652,'Closing',1), +(5,9,22027,'Remove Insignia',1), +(5,9,22810,'Opening - No Text',1), +(6,1,78,'Heroic Strike',1), +(6,1,81,'Dodge',1), +(6,1,107,'Block',1), +(6,1,196,'One-Handed Axes',1), +(6,1,198,'One-Handed Maces',1), +(6,1,199,'Two-Handed Maces',1), +(6,1,203,'Unarmed',1), +(6,1,204,'Defense',1), +(6,1,522,'SPELLDEFENSE(DND)',1), +(6,1,669,'Language Orcish',1), +(6,1,670,'Language Taurahe',1), +(6,1,2382,'Generic',1), +(6,1,2457,'Battle Stance',1), +(6,1,2479,'Honorless Target',1), +(6,1,3050,'Detect',1), +(6,1,3365,'Opening',1), +(6,1,5301,'Defensive State(DND)',1), +(6,1,6233,'Closing',1), +(6,1,6246,'Closing',1), +(6,1,6247,'Opening',1), +(6,1,6477,'Opening',1), +(6,1,6478,'Opening',1), +(6,1,6603,'Attack',1), +(6,1,7266,'Duel',1), +(6,1,7267,'Grovel',1), +(6,1,7355,'Stuck',1), +(6,1,7376,'Defensive Stance Passive',0), +(6,1,7381,'Berserker Stance Passive',0), +(6,1,8386,'Attacking',1), +(6,1,8737,'Mail',1), +(6,1,9077,'Leather',1), +(6,1,9078,'Cloth',1), +(6,1,9116,'Shield',1), +(6,1,9125,'Generic',1), +(6,1,20549,'War Stomp',1), +(6,1,20550,'Endurance',1), +(6,1,20551,'Nature Resistance',1), +(6,1,20552,'Cultivation',1), +(6,1,21156,'Battle Stance Passive',0), +(6,1,21651,'Opening',1), +(6,1,21652,'Closing',1), +(6,1,22027,'Remove Insignia',1), +(6,1,22810,'Opening - No Text',1), +(6,1,32215,'Victorious State',1), +(6,3,75,'Auto Shot',1), +(6,3,81,'Dodge',1), +(6,3,196,'One-Handed Axes',1), +(6,3,203,'Unarmed',1), +(6,3,204,'Defense',1), +(6,3,266,'Guns',1), +(6,3,522,'SPELLDEFENSE(DND)',1), +(6,3,669,'Language Orcish',1), +(6,3,670,'Language Taurahe',1), +(6,3,2382,'Generic',1), +(6,3,2479,'Honorless Target',1), +(6,3,2973,'Raptor Strike',1), +(6,3,3050,'Detect',1), +(6,3,3365,'Opening',1), +(6,3,6233,'Closing',1), +(6,3,6246,'Closing',1), +(6,3,6247,'Opening',1), +(6,3,6477,'Opening',1), +(6,3,6478,'Opening',1), +(6,3,6603,'Attack',1), +(6,3,7266,'Duel',1), +(6,3,7267,'Grovel',1), +(6,3,7355,'Stuck',1), +(6,3,8386,'Attacking',1), +(6,3,9077,'Leather',1), +(6,3,9078,'Cloth',1), +(6,3,9125,'Generic',1), +(6,3,13358,'Defensive State(DND)',1), +(6,3,20549,'War Stomp',1), +(6,3,20550,'Endurance',1), +(6,3,20551,'Nature Resistance',1), +(6,3,20552,'Cultivation',1), +(6,3,21651,'Opening',1), +(6,3,21652,'Closing',1), +(6,3,22027,'Remove Insignia',1), +(6,3,22810,'Opening - No Text',1), +(6,3,24949,'Defensive State 2(DND)',1), +(6,3,34082,'Advantaged State(DND)',1), +(6,7,81,'Dodge',1), +(6,7,107,'Block',1), +(6,7,198,'One-Handed Maces',1), +(6,7,203,'Unarmed',1), +(6,7,204,'Defense',1), +(6,7,227,'Staves',1), +(6,7,331,'Healing Wave',1), +(6,7,403,'Lightning Bolt',1), +(6,7,522,'SPELLDEFENSE(DND)',1), +(6,7,669,'Language Orcish',1), +(6,7,670,'Language Taurahe',1), +(6,7,2382,'Generic',1), +(6,7,2479,'Honorless Target',1), +(6,7,3050,'Detect',1), +(6,7,3365,'Opening',1), +(6,7,6233,'Closing',1), +(6,7,6246,'Closing',1), +(6,7,6247,'Opening',1), +(6,7,6477,'Opening',1), +(6,7,6478,'Opening',1), +(6,7,6603,'Attack',1), +(6,7,7266,'Duel',1), +(6,7,7267,'Grovel',1), +(6,7,7355,'Stuck',1), +(6,7,8386,'Attacking',1), +(6,7,9077,'Leather',1), +(6,7,9078,'Cloth',1), +(6,7,9116,'Shield',1), +(6,7,9125,'Generic',1), +(6,7,20549,'War Stomp',1), +(6,7,20550,'Endurance',1), +(6,7,20551,'Nature Resistance',1), +(6,7,20552,'Cultivation',1), +(6,7,21651,'Opening',1), +(6,7,21652,'Closing',1), +(6,7,22027,'Remove Insignia',1), +(6,7,22810,'Opening - No Text',1), +(6,7,27763,'Totem',1), +(6,11,81,'Dodge',1), +(6,11,198,'One-Handed Maces',1), +(6,11,203,'Unarmed',1), +(6,11,204,'Defense',1), +(6,11,227,'Staves',1), +(6,11,522,'SPELLDEFENSE(DND)',1), +(6,11,669,'Language Orcish',1), +(6,11,670,'Language Taurahe',1), +(6,11,1178,'Bear Form(Passive)',0), +(6,11,2382,'Generic',1), +(6,11,2479,'Honorless Target',1), +(6,11,3025,'Cat Form(Passive)',0), +(6,11,3050,'Detect',1), +(6,11,3365,'Opening',1), +(6,11,5176,'Wrath',1), +(6,11,5185,'Healing Touch',1), +(6,11,5419,'Travel Form(Passive)',0), +(6,11,5420,'Tree of Life',0), +(6,11,5421,'Aquatic Form(Passive)',0), +(6,11,6233,'Closing',1), +(6,11,6246,'Closing',1), +(6,11,6247,'Opening',1), +(6,11,6477,'Opening',1), +(6,11,6478,'Opening',1), +(6,11,6603,'Attack',1), +(6,11,7266,'Duel',1), +(6,11,7267,'Grovel',1), +(6,11,7355,'Stuck',1), +(6,11,8386,'Attacking',1), +(6,11,9077,'Leather',1), +(6,11,9078,'Cloth',1), +(6,11,9125,'Generic',1), +(6,11,9635,'Dire Bear Form(Passive)',0), +(6,11,20549,'War Stomp',1), +(6,11,20550,'Endurance',1), +(6,11,20551,'Nature Resistance',1), +(6,11,20552,'Cultivation',1), +(6,11,21178,'Bear Form(Passive2)',0), +(6,11,21651,'Opening',1), +(6,11,21652,'Closing',1), +(6,11,22027,'Remove Insignia',1), +(6,11,22810,'Opening - No Text',1), +(6,11,24905,'Moonkin Form(Passive)',0), +(6,11,27764,'Fetish',1), +(6,11,33948,'Flight Form(Passive)',0), +(6,11,34123,'Tree of Life(Passive)',0), +(6,11,40121,'Swift Flight Form(Passive)',0), +(7,1,78,'Heroic Strike',1), +(7,1,81,'Dodge',1), +(7,1,107,'Block',1), +(7,1,198,'One-Handed Maces',1), +(7,1,201,'One-Handed Swords',1), +(7,1,203,'Unarmed',1), +(7,1,204,'Defense',1), +(7,1,522,'SPELLDEFENSE(DND)',1), +(7,1,668,'Language Common',1), +(7,1,1180,'Daggers',1), +(7,1,2382,'Generic',1), +(7,1,2457,'Battle Stance',1), +(7,1,2479,'Honorless Target',1), +(7,1,3050,'Detect',1), +(7,1,3365,'Opening',1), +(7,1,5301,'Defensive State(DND)',1), +(7,1,6233,'Closing',1), +(7,1,6246,'Closing',1), +(7,1,6247,'Opening',1), +(7,1,6477,'Opening',1), +(7,1,6478,'Opening',1), +(7,1,6603,'Attack',1), +(7,1,7266,'Duel',1), +(7,1,7267,'Grovel',1), +(7,1,7340,'Language Gnomish',1), +(7,1,7355,'Stuck',1), +(7,1,7376,'Defensive Stance Passive',0), +(7,1,7381,'Berserker Stance Passive',0), +(7,1,8386,'Attacking',1), +(7,1,8737,'Mail',1), +(7,1,9077,'Leather',1), +(7,1,9078,'Cloth',1), +(7,1,9116,'Shield',1), +(7,1,9125,'Generic',1), +(7,1,20589,'Escape Artist',1), +(7,1,20591,'Expansive Mind',1), +(7,1,20592,'Arcane Resistance',1), +(7,1,20593,'Engineering Specialization',1), +(7,1,21156,'Battle Stance Passive',0), +(7,1,21651,'Opening',1), +(7,1,21652,'Closing',1), +(7,1,22027,'Remove Insignia',1), +(7,1,22810,'Opening - No Text',1), +(7,1,32215,'Victorious State',1), +(7,4,81,'Dodge',1), +(7,4,203,'Unarmed',1), +(7,4,204,'Defense',1), +(7,4,522,'SPELLDEFENSE(DND)',1), +(7,4,668,'Language Common',1), +(7,4,1180,'Daggers',1), +(7,4,1752,'Sinister Strike',1), +(7,4,2098,'Eviscerate',1), +(7,4,2382,'Generic',1), +(7,4,2479,'Honorless Target',1), +(7,4,2567,'Thrown',1), +(7,4,2764,'Throw',1), +(7,4,3050,'Detect',1), +(7,4,3365,'Opening',1), +(7,4,6233,'Closing',1), +(7,4,6246,'Closing',1), +(7,4,6247,'Opening',1), +(7,4,6477,'Opening',1), +(7,4,6478,'Opening',1), +(7,4,6603,'Attack',1), +(7,4,7266,'Duel',1), +(7,4,7267,'Grovel',1), +(7,4,7340,'Language Gnomish',1), +(7,4,7355,'Stuck',1), +(7,4,8386,'Attacking',1), +(7,4,9077,'Leather',1), +(7,4,9078,'Cloth',1), +(7,4,9125,'Generic',1), +(7,4,16092,'Defensive State(DND)',1), +(7,4,20589,'Escape Artist',1), +(7,4,20591,'Expansive Mind',1), +(7,4,20592,'Arcane Resistance',1), +(7,4,20593,'Engineering Specialization',1), +(7,4,21184,'Rogue Passive(DND)',1), +(7,4,21651,'Opening',1), +(7,4,21652,'Closing',1), +(7,4,22027,'Remove Insignia',1), +(7,4,22810,'Opening - No Text',1), +(7,8,81,'Dodge',1), +(7,8,133,'Fireball',1), +(7,8,168,'Frost Armor',1), +(7,8,203,'Unarmed',1), +(7,8,204,'Defense',1), +(7,8,227,'Staves',1), +(7,8,522,'SPELLDEFENSE(DND)',1), +(7,8,668,'Language Common',1), +(7,8,2382,'Generic',1), +(7,8,2479,'Honorless Target',1), +(7,8,3050,'Detect',1), +(7,8,3365,'Opening',1), +(7,8,5009,'Wands',1), +(7,8,5019,'Shoot',1), +(7,8,6233,'Closing',1), +(7,8,6246,'Closing',1), +(7,8,6247,'Opening',1), +(7,8,6477,'Opening',1), +(7,8,6478,'Opening',1), +(7,8,6603,'Attack',1), +(7,8,7266,'Duel',1), +(7,8,7267,'Grovel',1), +(7,8,7340,'Language Gnomish',1), +(7,8,7355,'Stuck',1), +(7,8,8386,'Attacking',1), +(7,8,9078,'Cloth',1), +(7,8,9125,'Generic',1), +(7,8,20589,'Escape Artist',1), +(7,8,20591,'Expansive Mind',1), +(7,8,20592,'Arcane Resistance',1), +(7,8,20593,'Engineering Specialization',1), +(7,8,21651,'Opening',1), +(7,8,21652,'Closing',1), +(7,8,22027,'Remove Insignia',1), +(7,8,22810,'Opening - No Text',1), +(7,9,81,'Dodge',1), +(7,9,203,'Unarmed',1), +(7,9,204,'Defense',1), +(7,9,522,'SPELLDEFENSE(DND)',1), +(7,9,668,'Language Common',1), +(7,9,686,'Shadow Bolt',1), +(7,9,687,'Demon Skin',1), +(7,9,1180,'Daggers',1), +(7,9,2382,'Generic',1), +(7,9,2479,'Honorless Target',1), +(7,9,3050,'Detect',1), +(7,9,3365,'Opening',1), +(7,9,5009,'Wands',1), +(7,9,5019,'Shoot',1), +(7,9,6233,'Closing',1), +(7,9,6246,'Closing',1), +(7,9,6247,'Opening',1), +(7,9,6477,'Opening',1), +(7,9,6478,'Opening',1), +(7,9,6603,'Attack',1), +(7,9,7266,'Duel',1), +(7,9,7267,'Grovel',1), +(7,9,7340,'Language Gnomish',1), +(7,9,7355,'Stuck',1), +(7,9,8386,'Attacking',1), +(7,9,9078,'Cloth',1), +(7,9,9125,'Generic',1), +(7,9,20589,'Escape Artist',1), +(7,9,20591,'Expansive Mind',1), +(7,9,20592,'Arcane Resistance',1), +(7,9,20593,'Engineering Specialization',1), +(7,9,21651,'Opening',1), +(7,9,21652,'Closing',1), +(7,9,22027,'Remove Insignia',1), +(7,9,22810,'Opening - No Text',1), +(8,1,78,'Heroic Strike',1), +(8,1,81,'Dodge',1), +(8,1,107,'Block',1), +(8,1,196,'One-Handed Axes',1), +(8,1,203,'Unarmed',1), +(8,1,204,'Defense',1), +(8,1,522,'SPELLDEFENSE(DND)',1), +(8,1,669,'Language Orcish',1), +(8,1,1180,'Daggers',1), +(8,1,2382,'Generic',1), +(8,1,2457,'Battle Stance',1), +(8,1,2479,'Honorless Target',1), +(8,1,2567,'Thrown',1), +(8,1,2764,'Throw',1), +(8,1,3050,'Detect',1), +(8,1,3365,'Opening',1), +(8,1,5301,'Defensive State(DND)',1), +(8,1,6233,'Closing',1), +(8,1,6246,'Closing',1), +(8,1,6247,'Opening',1), +(8,1,6477,'Opening',1), +(8,1,6478,'Opening',1), +(8,1,6603,'Attack',1), +(8,1,7266,'Duel',1), +(8,1,7267,'Grovel',1), +(8,1,7341,'Language Troll',1), +(8,1,7355,'Stuck',1), +(8,1,7376,'Defensive Stance Passive',0), +(8,1,7381,'Berserker Stance Passive',0), +(8,1,8386,'Attacking',1), +(8,1,8737,'Mail',1), +(8,1,9077,'Leather',1), +(8,1,9078,'Cloth',1), +(8,1,9116,'Shield',1), +(8,1,9125,'Generic',1), +(8,1,20555,'Regeneration',1), +(8,1,20557,'Beast Slaying',1), +(8,1,20558,'Throwing Specialization',1), +(8,1,21156,'Battle Stance Passive',0), +(8,1,21651,'Opening',1), +(8,1,21652,'Closing',1), +(8,1,22027,'Remove Insignia',1), +(8,1,22810,'Opening - No Text',1), +(8,1,26290,'Bow Specialization',1), +(8,1,26296,'Berserking',1), +(8,1,32215,'Victorious State',1), +(8,3,75,'Auto Shot',1), +(8,3,81,'Dodge',1), +(8,3,196,'One-Handed Axes',1), +(8,3,203,'Unarmed',1), +(8,3,204,'Defense',1), +(8,3,264,'Bows',1), +(8,3,522,'SPELLDEFENSE(DND)',1), +(8,3,669,'Language Orcish',1), +(8,3,2382,'Generic',1), +(8,3,2479,'Honorless Target',1), +(8,3,2973,'Raptor Strike',1), +(8,3,3050,'Detect',1), +(8,3,3365,'Opening',1), +(8,3,6233,'Closing',1), +(8,3,6246,'Closing',1), +(8,3,6247,'Opening',1), +(8,3,6477,'Opening',1), +(8,3,6478,'Opening',1), +(8,3,6603,'Attack',1), +(8,3,7266,'Duel',1), +(8,3,7267,'Grovel',1), +(8,3,7341,'Language Troll',1), +(8,3,7355,'Stuck',1), +(8,3,8386,'Attacking',1), +(8,3,9077,'Leather',1), +(8,3,9078,'Cloth',1), +(8,3,9125,'Generic',1), +(8,3,13358,'Defensive State(DND)',1), +(8,3,20554,'Berserking',1), +(8,3,20555,'Regeneration',1), +(8,3,20557,'Beast Slaying',1), +(8,3,20558,'Throwing Specialization',1), +(8,3,21651,'Opening',1), +(8,3,21652,'Closing',1), +(8,3,22027,'Remove Insignia',1), +(8,3,22810,'Opening - No Text',1), +(8,3,24949,'Defensive State 2(DND)',1), +(8,3,26290,'Bow Specialization',1), +(8,3,34082,'Advantaged State(DND)',1), +(8,4,81,'Dodge',1), +(8,4,203,'Unarmed',1), +(8,4,204,'Defense',1), +(8,4,522,'SPELLDEFENSE(DND)',1), +(8,4,669,'Language Orcish',1), +(8,4,1180,'Daggers',1), +(8,4,1752,'Sinister Strike',1), +(8,4,2098,'Eviscerate',1), +(8,4,2382,'Generic',1), +(8,4,2479,'Honorless Target',1), +(8,4,2567,'Thrown',1), +(8,4,2764,'Throw',1), +(8,4,3050,'Detect',1), +(8,4,3365,'Opening',1), +(8,4,6233,'Closing',1), +(8,4,6246,'Closing',1), +(8,4,6247,'Opening',1), +(8,4,6477,'Opening',1), +(8,4,6478,'Opening',1), +(8,4,6603,'Attack',1), +(8,4,7266,'Duel',1), +(8,4,7267,'Grovel',1), +(8,4,7341,'Language Troll',1), +(8,4,7355,'Stuck',1), +(8,4,8386,'Attacking',1), +(8,4,9077,'Leather',1), +(8,4,9078,'Cloth',1), +(8,4,9125,'Generic',1), +(8,4,16092,'Defensive State(DND)',1), +(8,4,20555,'Regeneration',1), +(8,4,20557,'Beast Slaying',1), +(8,4,20558,'Throwing Specialization',1), +(8,4,21184,'Rogue Passive(DND)',1), +(8,4,21651,'Opening',1), +(8,4,21652,'Closing',1), +(8,4,22027,'Remove Insignia',1), +(8,4,22810,'Opening - No Text',1), +(8,4,26290,'Bow Specialization',1), +(8,4,26297,'Berserking',1), +(8,5,81,'Dodge',1), +(8,5,198,'One-Handed Maces',1), +(8,5,203,'Unarmed',1), +(8,5,204,'Defense',1), +(8,5,522,'SPELLDEFENSE(DND)',1), +(8,5,585,'Smite',1), +(8,5,669,'Language Orcish',1), +(8,5,2050,'Lesser Heal',1), +(8,5,2382,'Generic',1), +(8,5,2479,'Honorless Target',1), +(8,5,3050,'Detect',1), +(8,5,3365,'Opening',1), +(8,5,5009,'Wands',1), +(8,5,5019,'Shoot',1), +(8,5,6233,'Closing',1), +(8,5,6246,'Closing',1), +(8,5,6247,'Opening',1), +(8,5,6477,'Opening',1), +(8,5,6478,'Opening',1), +(8,5,6603,'Attack',1), +(8,5,7266,'Duel',1), +(8,5,7267,'Grovel',1), +(8,5,7341,'Language Troll',1), +(8,5,7355,'Stuck',1), +(8,5,8386,'Attacking',1), +(8,5,9078,'Cloth',1), +(8,5,9125,'Generic',1), +(8,5,20554,'Berserking',1), +(8,5,20555,'Regeneration',1), +(8,5,20557,'Beast Slaying',1), +(8,5,20558,'Throwing Specialization',1), +(8,5,21651,'Opening',1), +(8,5,21652,'Closing',1), +(8,5,22027,'Remove Insignia',1), +(8,5,22810,'Opening - No Text',1), +(8,5,26290,'Bow Specialization',1), +(8,7,81,'Dodge',1), +(8,7,107,'Block',1), +(8,7,198,'One-Handed Maces',1), +(8,7,203,'Unarmed',1), +(8,7,204,'Defense',1), +(8,7,227,'Staves',1), +(8,7,331,'Healing Wave',1), +(8,7,403,'Lightning Bolt',1), +(8,7,522,'SPELLDEFENSE(DND)',1), +(8,7,669,'Language Orcish',1), +(8,7,2382,'Generic',1), +(8,7,2479,'Honorless Target',1), +(8,7,3050,'Detect',1), +(8,7,3365,'Opening',1), +(8,7,6233,'Closing',1), +(8,7,6246,'Closing',1), +(8,7,6247,'Opening',1), +(8,7,6477,'Opening',1), +(8,7,6478,'Opening',1), +(8,7,6603,'Attack',1), +(8,7,7266,'Duel',1), +(8,7,7267,'Grovel',1), +(8,7,7341,'Language Troll',1), +(8,7,7355,'Stuck',1), +(8,7,8386,'Attacking',1), +(8,7,9077,'Leather',1), +(8,7,9078,'Cloth',1), +(8,7,9116,'Shield',1), +(8,7,9125,'Generic',1), +(8,7,20554,'Berserking',1), +(8,7,20555,'Regeneration',1), +(8,7,20557,'Beast Slaying',1), +(8,7,20558,'Throwing Specialization',1), +(8,7,21651,'Opening',1), +(8,7,21652,'Closing',1), +(8,7,22027,'Remove Insignia',1), +(8,7,22810,'Opening - No Text',1), +(8,7,26290,'Bow Specialization',1), +(8,7,27763,'Totem',1), +(8,8,81,'Dodge',1), +(8,8,133,'Fireball',1), +(8,8,168,'Frost Armor',1), +(8,8,203,'Unarmed',1), +(8,8,204,'Defense',1), +(8,8,227,'Staves',1), +(8,8,522,'SPELLDEFENSE(DND)',1), +(8,8,669,'Language Orcish',1), +(8,8,2382,'Generic',1), +(8,8,2479,'Honorless Target',1), +(8,8,3050,'Detect',1), +(8,8,3365,'Opening',1), +(8,8,5009,'Wands',1), +(8,8,5019,'Shoot',1), +(8,8,6233,'Closing',1), +(8,8,6246,'Closing',1), +(8,8,6247,'Opening',1), +(8,8,6477,'Opening',1), +(8,8,6478,'Opening',1), +(8,8,6603,'Attack',1), +(8,8,7266,'Duel',1), +(8,8,7267,'Grovel',1), +(8,8,7341,'Language Troll',1), +(8,8,7355,'Stuck',1), +(8,8,8386,'Attacking',1), +(8,8,9078,'Cloth',1), +(8,8,9125,'Generic',1), +(8,8,20554,'Berserking',1), +(8,8,20555,'Regeneration',1), +(8,8,20557,'Beast Slaying',1), +(8,8,20558,'Throwing Specialization',1), +(8,8,21651,'Opening',1), +(8,8,21652,'Closing',1), +(8,8,22027,'Remove Insignia',1), +(8,8,22810,'Opening - No Text',1), +(8,8,26290,'Bow Specialization',1), +(10,2,81,'Dodge',1), +(10,2,107,'Block',1), +(10,2,201,'One-Handed Swords',1), +(10,2,202,'Two-Handed Swords',1), +(10,2,203,'Unarmed',1), +(10,2,204,'Defense',1), +(10,2,522,'SPELLDEFENSE(DND)',1), +(10,2,635,'Holy Light',1), +(10,2,669,'Language Orcish',1), +(10,2,813,'Language Thalassian',1), +(10,2,822,'Magic Resistance',1), +(10,2,2382,'Generic',1), +(10,2,2479,'Honorless Target',1), +(10,2,3050,'Detect',1), +(10,2,3365,'Opening',1), +(10,2,6233,'Closing',1), +(10,2,6246,'Closing',1), +(10,2,6247,'Opening',1), +(10,2,6477,'Opening',1), +(10,2,6478,'Opening',1), +(10,2,6603,'Attack',1), +(10,2,7266,'Duel',1), +(10,2,7267,'Grovel',1), +(10,2,7355,'Stuck',1), +(10,2,8386,'Attacking',1), +(10,2,8737,'Mail',1), +(10,2,9077,'Leather',1), +(10,2,9078,'Cloth',1), +(10,2,9116,'Shield',1), +(10,2,9125,'Generic',1), +(10,2,21084,'Seal of Righteousness',1), +(10,2,21651,'Opening',1), +(10,2,21652,'Closing',1), +(10,2,22027,'Remove Insignia',1), +(10,2,22810,'Opening - No Text',1), +(10,2,27762,'Libram',1), +(10,2,28730,'Arcane Torrent',1), +(10,2,28734,'Mana Tap',1), +(10,2,28877,'Arcane Affinity',1), +(10,3,75,'Auto Shot',1), +(10,3,81,'Dodge',1), +(10,3,203,'Unarmed',1), +(10,3,204,'Defense',1), +(10,3,264,'Bows',1), +(10,3,522,'SPELLDEFENSE(DND)',1), +(10,3,669,'Language Orcish',1), +(10,3,813,'Language Thalassian',1), +(10,3,822,'Magic Resistance',1), +(10,3,1180,'Daggers',1), +(10,3,2382,'Generic',1), +(10,3,2479,'Honorless Target',1), +(10,3,2973,'Raptor Strike',1), +(10,3,3050,'Detect',1), +(10,3,3365,'Opening',1), +(10,3,6233,'Closing',1), +(10,3,6246,'Closing',1), +(10,3,6247,'Opening',1), +(10,3,6477,'Opening',1), +(10,3,6478,'Opening',1), +(10,3,6603,'Attack',1), +(10,3,7266,'Duel',1), +(10,3,7267,'Grovel',1), +(10,3,7355,'Stuck',1), +(10,3,8386,'Attacking',1), +(10,3,9077,'Leather',1), +(10,3,9078,'Cloth',1), +(10,3,9125,'Generic',1), +(10,3,13358,'Defensive State(DND)',1), +(10,3,21651,'Opening',1), +(10,3,21652,'Closing',1), +(10,3,22027,'Remove Insignia',1), +(10,3,22810,'Opening - No Text',1), +(10,3,24949,'Defensive State 2(DND)',1), +(10,3,28730,'Arcane Torrent',1), +(10,3,28734,'Mana Tap',1), +(10,3,28877,'Arcane Affinity',1), +(10,3,34082,'Advantaged State(DND)',1), +(10,4,81,'Dodge',1), +(10,4,203,'Unarmed',1), +(10,4,204,'Defense',1), +(10,4,522,'SPELLDEFENSE(DND)',1), +(10,4,669,'Language Orcish',1), +(10,4,813,'Language Thalassian',1), +(10,4,822,'Magic Resistance',1), +(10,4,1180,'Daggers',1), +(10,4,1752,'Sinister Strike',1), +(10,4,2098,'Eviscerate',1), +(10,4,2382,'Generic',1), +(10,4,2479,'Honorless Target',1), +(10,4,2567,'Thrown',1), +(10,4,2764,'Throw',1), +(10,4,3050,'Detect',1), +(10,4,3365,'Opening',1), +(10,4,6233,'Closing',1), +(10,4,6246,'Closing',1), +(10,4,6247,'Opening',1), +(10,4,6477,'Opening',1), +(10,4,6478,'Opening',1), +(10,4,6603,'Attack',1), +(10,4,7266,'Duel',1), +(10,4,7267,'Grovel',1), +(10,4,7355,'Stuck',1), +(10,4,8386,'Attacking',1), +(10,4,9077,'Leather',1), +(10,4,9078,'Cloth',1), +(10,4,9125,'Generic',1), +(10,4,16092,'Defensive State(DND)',1), +(10,4,21184,'Rogue Passive(DND)',1), +(10,4,21651,'Opening',1), +(10,4,21652,'Closing',1), +(10,4,22027,'Remove Insignia',1), +(10,4,22810,'Opening - No Text',1), +(10,4,25046,'Arcane Torrent',1), +(10,4,28734,'Mana Tap',1), +(10,4,28877,'Arcane Affinity',1), +(10,5,81,'Dodge',1), +(10,5,198,'One-Handed Maces',1), +(10,5,203,'Unarmed',1), +(10,5,204,'Defense',1), +(10,5,522,'SPELLDEFENSE(DND)',1), +(10,5,585,'Smite',1), +(10,5,669,'Language Orcish',1), +(10,5,813,'Language Thalassian',1), +(10,5,822,'Magic Resistance',1), +(10,5,2050,'Lesser Heal',1), +(10,5,2382,'Generic',1), +(10,5,2479,'Honorless Target',1), +(10,5,3050,'Detect',1), +(10,5,3365,'Opening',1), +(10,5,5009,'Wands',1), +(10,5,5019,'Shoot',1), +(10,5,6233,'Closing',1), +(10,5,6246,'Closing',1), +(10,5,6247,'Opening',1), +(10,5,6477,'Opening',1), +(10,5,6478,'Opening',1), +(10,5,6603,'Attack',1), +(10,5,7266,'Duel',1), +(10,5,7267,'Grovel',1), +(10,5,7355,'Stuck',1), +(10,5,8386,'Attacking',1), +(10,5,9078,'Cloth',1), +(10,5,9125,'Generic',1), +(10,5,21651,'Opening',1), +(10,5,21652,'Closing',1), +(10,5,22027,'Remove Insignia',1), +(10,5,22810,'Opening - No Text',1), +(10,5,28730,'Arcane Torrent',1), +(10,5,28734,'Mana Tap',1), +(10,5,28877,'Arcane Affinity',1), +(10,8,81,'Dodge',1), +(10,8,133,'Fireball',1), +(10,8,168,'Frost Armor',1), +(10,8,203,'Unarmed',1), +(10,8,204,'Defense',1), +(10,8,227,'Staves',1), +(10,8,522,'SPELLDEFENSE(DND)',1), +(10,8,669,'Language Orcish',1), +(10,8,813,'Language Thalassian',1), +(10,8,822,'Magic Resistance',1), +(10,8,2382,'Generic',1), +(10,8,2479,'Honorless Target',1), +(10,8,3050,'Detect',1), +(10,8,3365,'Opening',1), +(10,8,5009,'Wands',1), +(10,8,5019,'Shoot',1), +(10,8,6233,'Closing',1), +(10,8,6246,'Closing',1), +(10,8,6247,'Opening',1), +(10,8,6477,'Opening',1), +(10,8,6478,'Opening',1), +(10,8,6603,'Attack',1), +(10,8,7266,'Duel',1), +(10,8,7267,'Grovel',1), +(10,8,7355,'Stuck',1), +(10,8,8386,'Attacking',1), +(10,8,9078,'Cloth',1), +(10,8,9125,'Generic',1), +(10,8,21651,'Opening',1), +(10,8,21652,'Closing',1), +(10,8,22027,'Remove Insignia',1), +(10,8,22810,'Opening - No Text',1), +(10,8,28730,'Arcane Torrent',1), +(10,8,28734,'Mana Tap',1), +(10,8,28877,'Arcane Affinity',1), +(10,9,81,'Dodge',1), +(10,9,203,'Unarmed',1), +(10,9,204,'Defense',1), +(10,9,522,'SPELLDEFENSE(DND)',1), +(10,9,669,'Language Orcish',1), +(10,9,686,'Shadow Bolt',1), +(10,9,687,'Demon Skin',1), +(10,9,813,'Language Thalassian',1), +(10,9,822,'Magic Resistance',1), +(10,9,1180,'Daggers',1), +(10,9,2382,'Generic',1), +(10,9,2479,'Honorless Target',1), +(10,9,3050,'Detect',1), +(10,9,3365,'Opening',1), +(10,9,5009,'Wands',1), +(10,9,5019,'Shoot',1), +(10,9,6233,'Closing',1), +(10,9,6246,'Closing',1), +(10,9,6247,'Opening',1), +(10,9,6477,'Opening',1), +(10,9,6478,'Opening',1), +(10,9,6603,'Attack',1), +(10,9,7266,'Duel',1), +(10,9,7267,'Grovel',1), +(10,9,7355,'Stuck',1), +(10,9,8386,'Attacking',1), +(10,9,9078,'Cloth',1), +(10,9,9125,'Generic',1), +(10,9,21651,'Opening',1), +(10,9,21652,'Closing',1), +(10,9,22027,'Remove Insignia',1), +(10,9,22810,'Opening - No Text',1), +(10,9,28730,'Arcane Torrent',1), +(10,9,28734,'Mana Tap',1), +(10,9,28877,'Arcane Affinity',1), +(11,1,78,'Heroic Strike',1), +(11,1,81,'Dodge',1), +(11,1,107,'Block',1), +(11,1,198,'One-Handed Maces',1), +(11,1,201,'One-Handed Swords',1), +(11,1,202,'Two-Handed Swords',1), +(11,1,203,'Unarmed',1), +(11,1,204,'Defense',1), +(11,1,522,'SPELLDEFENSE(DND)',1), +(11,1,668,'Language Common',1), +(11,1,2382,'Generic',1), +(11,1,2457,'Battle Stance',1), +(11,1,2479,'Honorless Target',1), +(11,1,3050,'Detect',1), +(11,1,3365,'Opening',1), +(11,1,5301,'Defensive State(DND)',1), +(11,1,6233,'Closing',1), +(11,1,6246,'Closing',1), +(11,1,6247,'Opening',1), +(11,1,6477,'Opening',1), +(11,1,6478,'Opening',1), +(11,1,6562,'Heroic Presence',1), +(11,1,6603,'Attack',1), +(11,1,7266,'Duel',1), +(11,1,7267,'Grovel',1), +(11,1,7355,'Stuck',1), +(11,1,7376,'Defensive Stance Passive',0), +(11,1,7381,'Berserker Stance Passive',0), +(11,1,8386,'Attacking',1), +(11,1,8737,'Mail',1), +(11,1,9077,'Leather',1), +(11,1,9078,'Cloth',1), +(11,1,9116,'Shield',1), +(11,1,9125,'Generic',1), +(11,1,20579,'Shadow Resistance',1), +(11,1,21156,'Battle Stance Passive',0), +(11,1,21651,'Opening',1), +(11,1,21652,'Closing',1), +(11,1,22027,'Remove Insignia',1), +(11,1,22810,'Opening - No Text',1), +(11,1,28875,'Gemcutting',1), +(11,1,28880,'Gift of the Naaru',1), +(11,1,29932,'Language Draenei',1), +(11,1,32215,'Victorious State',1), +(11,2,81,'Dodge',1), +(11,2,107,'Block',1), +(11,2,198,'One-Handed Maces',1), +(11,2,199,'Two-Handed Maces',1), +(11,2,203,'Unarmed',1), +(11,2,204,'Defense',1), +(11,2,522,'SPELLDEFENSE(DND)',1), +(11,2,635,'Holy Light',1), +(11,2,668,'Language Common',1), +(11,2,2382,'Generic',1), +(11,2,2479,'Honorless Target',1), +(11,2,3050,'Detect',1), +(11,2,3365,'Opening',1), +(11,2,6233,'Closing',1), +(11,2,6246,'Closing',1), +(11,2,6247,'Opening',1), +(11,2,6477,'Opening',1), +(11,2,6478,'Opening',1), +(11,2,6562,'Heroic Presence',1), +(11,2,6603,'Attack',1), +(11,2,7266,'Duel',1), +(11,2,7267,'Grovel',1), +(11,2,7355,'Stuck',1), +(11,2,8386,'Attacking',1), +(11,2,8737,'Mail',1), +(11,2,9077,'Leather',1), +(11,2,9078,'Cloth',1), +(11,2,9116,'Shield',1), +(11,2,9125,'Generic',1), +(11,2,21084,'Seal of Righteousness',1), +(11,2,20579,'Shadow Resistance',1), +(11,2,21651,'Opening',1), +(11,2,21652,'Closing',1), +(11,2,22027,'Remove Insignia',1), +(11,2,22810,'Opening - No Text',1), +(11,2,27762,'Libram',1), +(11,2,28875,'Gemcutting',1), +(11,2,28880,'Gift of the Naaru',1), +(11,2,29932,'Language Draenei',1), +(11,3,75,'Auto Shot',1), +(11,3,81,'Dodge',1), +(11,3,201,'One-Handed Swords',1), +(11,3,203,'Unarmed',1), +(11,3,204,'Defense',1), +(11,3,522,'SPELLDEFENSE(DND)',1), +(11,3,668,'Language Common',1), +(11,3,2382,'Generic',1), +(11,3,2479,'Honorless Target',1), +(11,3,2973,'Raptor Strike',1), +(11,3,3050,'Detect',1), +(11,3,3365,'Opening',1), +(11,3,5011,'Crossbows',1), +(11,3,6233,'Closing',1), +(11,3,6246,'Closing',1), +(11,3,6247,'Opening',1), +(11,3,6477,'Opening',1), +(11,3,6478,'Opening',1), +(11,3,6562,'Heroic Presence',1), +(11,3,6603,'Attack',1), +(11,3,7266,'Duel',1), +(11,3,7267,'Grovel',1), +(11,3,7355,'Stuck',1), +(11,3,8386,'Attacking',1), +(11,3,9077,'Leather',1), +(11,3,9078,'Cloth',1), +(11,3,9125,'Generic',1), +(11,3,13358,'Defensive State(DND)',1), +(11,3,20579,'Shadow Resistance',1), +(11,3,21651,'Opening',1), +(11,3,21652,'Closing',1), +(11,3,22027,'Remove Insignia',1), +(11,3,22810,'Opening - No Text',1), +(11,3,24949,'Defensive State 2(DND)',1), +(11,3,28875,'Gemcutting',1), +(11,3,28880,'Gift of the Naaru',1), +(11,3,29932,'Language Draenei',1), +(11,3,34082,'Advantaged State(DND)',1), +(11,5,81,'Dodge',1), +(11,5,198,'One-Handed Maces',1), +(11,5,203,'Unarmed',1), +(11,5,204,'Defense',1), +(11,5,522,'SPELLDEFENSE(DND)',1), +(11,5,585,'Smite',1), +(11,5,668,'Language Common',1), +(11,5,2050,'Lesser Heal',1), +(11,5,2382,'Generic',1), +(11,5,2479,'Honorless Target',1), +(11,5,3050,'Detect',1), +(11,5,3365,'Opening',1), +(11,5,5009,'Wands',1), +(11,5,5019,'Shoot',1), +(11,5,6233,'Closing',1), +(11,5,6246,'Closing',1), +(11,5,6247,'Opening',1), +(11,5,6477,'Opening',1), +(11,5,6478,'Opening',1), +(11,5,6603,'Attack',1), +(11,5,7266,'Duel',1), +(11,5,7267,'Grovel',1), +(11,5,7355,'Stuck',1), +(11,5,8386,'Attacking',1), +(11,5,9078,'Cloth',1), +(11,5,9125,'Generic',1), +(11,5,20579,'Shadow Resistance',1), +(11,5,21651,'Opening',1), +(11,5,21652,'Closing',1), +(11,5,22027,'Remove Insignia',1), +(11,5,22810,'Opening - No Text',1), +(11,5,28875,'Gemcutting',1), +(11,5,28878,'Inspiring Presence',1), +(11,5,28880,'Gift of the Naaru',1), +(11,5,29932,'Language Draenei',1), +(11,7,81,'Dodge',1), +(11,7,107,'Block',1), +(11,7,198,'One-Handed Maces',1), +(11,7,203,'Unarmed',1), +(11,7,204,'Defense',1), +(11,7,227,'Staves',1), +(11,7,331,'Healing Wave',1), +(11,7,403,'Lightning Bolt',1), +(11,7,522,'SPELLDEFENSE(DND)',1), +(11,7,668,'Language Common',1), +(11,7,2382,'Generic',1), +(11,7,2479,'Honorless Target',1), +(11,7,3050,'Detect',1), +(11,7,3365,'Opening',1), +(11,7,6233,'Closing',1), +(11,7,6246,'Closing',1), +(11,7,6247,'Opening',1), +(11,7,6477,'Opening',1), +(11,7,6478,'Opening',1), +(11,7,6603,'Attack',1), +(11,7,7266,'Duel',1), +(11,7,7267,'Grovel',1), +(11,7,7355,'Stuck',1), +(11,7,8386,'Attacking',1), +(11,7,9077,'Leather',1), +(11,7,9078,'Cloth',1), +(11,7,9116,'Shield',1), +(11,7,9125,'Generic',1), +(11,7,20579,'Shadow Resistance',1), +(11,7,21651,'Opening',1), +(11,7,21652,'Closing',1), +(11,7,22027,'Remove Insignia',1), +(11,7,22810,'Opening - No Text',1), +(11,7,27763,'Totem',1), +(11,7,28875,'Gemcutting',1), +(11,7,28878,'Inspiring Presence',1), +(11,7,28880,'Gift of the Naaru',1), +(11,7,29932,'Language Draenei',1), +(11,8,81,'Dodge',1), +(11,8,133,'Fireball',1), +(11,8,168,'Frost Armor',1), +(11,8,203,'Unarmed',1), +(11,8,204,'Defense',1), +(11,8,227,'Staves',1), +(11,8,522,'SPELLDEFENSE(DND)',1), +(11,8,668,'Language Common',1), +(11,8,2382,'Generic',1), +(11,8,2479,'Honorless Target',1), +(11,8,3050,'Detect',1), +(11,8,3365,'Opening',1), +(11,8,5009,'Wands',1), +(11,8,5019,'Shoot',1), +(11,8,6233,'Closing',1), +(11,8,6246,'Closing',1), +(11,8,6247,'Opening',1), +(11,8,6477,'Opening',1), +(11,8,6478,'Opening',1), +(11,8,6603,'Attack',1), +(11,8,7266,'Duel',1), +(11,8,7267,'Grovel',1), +(11,8,7355,'Stuck',1), +(11,8,8386,'Attacking',1), +(11,8,9078,'Cloth',1), +(11,8,9125,'Generic',1), +(11,8,20579,'Shadow Resistance',1), +(11,8,21651,'Opening',1), +(11,8,21652,'Closing',1), +(11,8,22027,'Remove Insignia',1), +(11,8,22810,'Opening - No Text',1), +(11,8,28875,'Gemcutting',1), +(11,8,28878,'Inspiring Presence',1), +(11,8,28880,'Gift of the Naaru',1), +(11,8,29932,'Language Draenei',1); +/*!40000 ALTER TABLE `playercreateinfo_spell` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `prospecting_loot_template` +-- + +DROP TABLE IF EXISTS `prospecting_loot_template`; +CREATE TABLE `prospecting_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `prospecting_loot_template` +-- + +LOCK TABLES `prospecting_loot_template` WRITE; +/*!40000 ALTER TABLE `prospecting_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `prospecting_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `quest_end_scripts` +-- + +DROP TABLE IF EXISTS `quest_end_scripts`; +CREATE TABLE `quest_end_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `quest_end_scripts` +-- + +LOCK TABLES `quest_end_scripts` WRITE; +/*!40000 ALTER TABLE `quest_end_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `quest_end_scripts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `quest_start_scripts` +-- + +DROP TABLE IF EXISTS `quest_start_scripts`; +CREATE TABLE `quest_start_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `quest_start_scripts` +-- + +LOCK TABLES `quest_start_scripts` WRITE; +/*!40000 ALTER TABLE `quest_start_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `quest_start_scripts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `quest_mail_loot_template` +-- + +DROP TABLE IF EXISTS `quest_mail_loot_template`; +CREATE TABLE `quest_mail_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `quest_mail_loot_template` +-- + +LOCK TABLES `quest_mail_loot_template` WRITE; +/*!40000 ALTER TABLE `quest_mail_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `quest_mail_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `quest_template` +-- + +DROP TABLE IF EXISTS `quest_template`; +CREATE TABLE `quest_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `Method` tinyint(3) unsigned NOT NULL default '2', + `ZoneOrSort` smallint(6) NOT NULL default '0', + `SkillOrClass` smallint(6) NOT NULL default '0', + `MinLevel` tinyint(3) unsigned NOT NULL default '0', + `QuestLevel` tinyint(3) unsigned NOT NULL default '0', + `Type` smallint(5) unsigned NOT NULL default '0', + `RequiredRaces` smallint(5) unsigned NOT NULL default '0', + `RequiredSkillValue` smallint(5) unsigned NOT NULL default '0', + `RepObjectiveFaction` smallint(5) unsigned NOT NULL default '0', + `RepObjectiveValue` mediumint(9) NOT NULL default '0', + `RequiredMinRepFaction` smallint(5) unsigned NOT NULL default '0', + `RequiredMinRepValue` mediumint(9) NOT NULL default '0', + `RequiredMaxRepFaction` smallint(5) unsigned NOT NULL default '0', + `RequiredMaxRepValue` mediumint(9) NOT NULL default '0', + `SuggestedPlayers` tinyint(3) unsigned NOT NULL default '0', + `LimitTime` int(10) unsigned NOT NULL default '0', + `QuestFlags` smallint(5) unsigned NOT NULL default '0', + `SpecialFlags` tinyint(3) unsigned NOT NULL default '0', + `CharTitleId` tinyint(3) unsigned NOT NULL default '0', + `PrevQuestId` mediumint(9) NOT NULL default '0', + `NextQuestId` mediumint(9) NOT NULL default '0', + `ExclusiveGroup` mediumint(9) NOT NULL default '0', + `NextQuestInChain` mediumint(8) unsigned NOT NULL default '0', + `SrcItemId` mediumint(8) unsigned NOT NULL default '0', + `SrcItemCount` tinyint(3) unsigned NOT NULL default '0', + `SrcSpell` mediumint(8) unsigned NOT NULL default '0', + `Title` text, + `Details` text, + `Objectives` text, + `OfferRewardText` text, + `RequestItemsText` text, + `EndText` text, + `ObjectiveText1` text, + `ObjectiveText2` text, + `ObjectiveText3` text, + `ObjectiveText4` text, + `ReqItemId1` mediumint(8) unsigned NOT NULL default '0', + `ReqItemId2` mediumint(8) unsigned NOT NULL default '0', + `ReqItemId3` mediumint(8) unsigned NOT NULL default '0', + `ReqItemId4` mediumint(8) unsigned NOT NULL default '0', + `ReqItemCount1` smallint(5) unsigned NOT NULL default '0', + `ReqItemCount2` smallint(5) unsigned NOT NULL default '0', + `ReqItemCount3` smallint(5) unsigned NOT NULL default '0', + `ReqItemCount4` smallint(5) unsigned NOT NULL default '0', + `ReqSourceId1` mediumint(8) unsigned NOT NULL default '0', + `ReqSourceId2` mediumint(8) unsigned NOT NULL default '0', + `ReqSourceId3` mediumint(8) unsigned NOT NULL default '0', + `ReqSourceId4` mediumint(8) unsigned NOT NULL default '0', + `ReqSourceCount1` smallint(5) unsigned NOT NULL default '0', + `ReqSourceCount2` smallint(5) unsigned NOT NULL default '0', + `ReqSourceCount3` smallint(5) unsigned NOT NULL default '0', + `ReqSourceCount4` smallint(5) unsigned NOT NULL default '0', + `ReqSourceRef1` tinyint(3) unsigned NOT NULL default '0', + `ReqSourceRef2` tinyint(3) unsigned NOT NULL default '0', + `ReqSourceRef3` tinyint(3) unsigned NOT NULL default '0', + `ReqSourceRef4` tinyint(3) unsigned NOT NULL default '0', + `ReqCreatureOrGOId1` mediumint(9) NOT NULL default '0', + `ReqCreatureOrGOId2` mediumint(9) NOT NULL default '0', + `ReqCreatureOrGOId3` mediumint(9) NOT NULL default '0', + `ReqCreatureOrGOId4` mediumint(9) NOT NULL default '0', + `ReqCreatureOrGOCount1` smallint(5) unsigned NOT NULL default '0', + `ReqCreatureOrGOCount2` smallint(5) unsigned NOT NULL default '0', + `ReqCreatureOrGOCount3` smallint(5) unsigned NOT NULL default '0', + `ReqCreatureOrGOCount4` smallint(5) unsigned NOT NULL default '0', + `ReqSpellCast1` mediumint(8) unsigned NOT NULL default '0', + `ReqSpellCast2` mediumint(8) unsigned NOT NULL default '0', + `ReqSpellCast3` mediumint(8) unsigned NOT NULL default '0', + `ReqSpellCast4` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemId1` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemId2` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemId3` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemId4` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemId5` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemId6` mediumint(8) unsigned NOT NULL default '0', + `RewChoiceItemCount1` smallint(5) unsigned NOT NULL default '0', + `RewChoiceItemCount2` smallint(5) unsigned NOT NULL default '0', + `RewChoiceItemCount3` smallint(5) unsigned NOT NULL default '0', + `RewChoiceItemCount4` smallint(5) unsigned NOT NULL default '0', + `RewChoiceItemCount5` smallint(5) unsigned NOT NULL default '0', + `RewChoiceItemCount6` smallint(5) unsigned NOT NULL default '0', + `RewItemId1` mediumint(8) unsigned NOT NULL default '0', + `RewItemId2` mediumint(8) unsigned NOT NULL default '0', + `RewItemId3` mediumint(8) unsigned NOT NULL default '0', + `RewItemId4` mediumint(8) unsigned NOT NULL default '0', + `RewItemCount1` smallint(5) unsigned NOT NULL default '0', + `RewItemCount2` smallint(5) unsigned NOT NULL default '0', + `RewItemCount3` smallint(5) unsigned NOT NULL default '0', + `RewItemCount4` smallint(5) unsigned NOT NULL default '0', + `RewRepFaction1` smallint(5) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + `RewRepFaction2` smallint(5) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + `RewRepFaction3` smallint(5) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + `RewRepFaction4` smallint(5) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + `RewRepFaction5` smallint(5) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + `RewRepValue1` mediumint(9) NOT NULL default '0', + `RewRepValue2` mediumint(9) NOT NULL default '0', + `RewRepValue3` mediumint(9) NOT NULL default '0', + `RewRepValue4` mediumint(9) NOT NULL default '0', + `RewRepValue5` mediumint(9) NOT NULL default '0', + `RewOrReqMoney` int(11) NOT NULL default '0', + `RewMoneyMaxLevel` int(10) unsigned NOT NULL default '0', + `RewSpell` mediumint(8) unsigned NOT NULL default '0', + `RewSpellCast` mediumint(8) unsigned NOT NULL default '0', + `RewMailTemplateId` mediumint(8) unsigned NOT NULL default '0', + `RewMailDelaySecs` int(11) unsigned NOT NULL default '0', + `PointMapId` smallint(5) unsigned NOT NULL default '0', + `PointX` float NOT NULL default '0', + `PointY` float NOT NULL default '0', + `PointOpt` mediumint(8) unsigned NOT NULL default '0', + `DetailsEmote1` smallint(5) unsigned NOT NULL default '0', + `DetailsEmote2` smallint(5) unsigned NOT NULL default '0', + `DetailsEmote3` smallint(5) unsigned NOT NULL default '0', + `DetailsEmote4` smallint(5) unsigned NOT NULL default '0', + `IncompleteEmote` smallint(5) unsigned NOT NULL default '0', + `CompleteEmote` smallint(5) unsigned NOT NULL default '0', + `OfferRewardEmote1` smallint(5) unsigned NOT NULL default '0', + `OfferRewardEmote2` smallint(5) unsigned NOT NULL default '0', + `OfferRewardEmote3` smallint(5) unsigned NOT NULL default '0', + `OfferRewardEmote4` smallint(5) unsigned NOT NULL default '0', + `StartScript` mediumint(8) unsigned NOT NULL default '0', + `CompleteScript` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Quest System'; + +-- +-- Dumping data for table `quest_template` +-- + +LOCK TABLES `quest_template` WRITE; +/*!40000 ALTER TABLE `quest_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `quest_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `reference_loot_template` +-- + +DROP TABLE IF EXISTS `reference_loot_template`; +CREATE TABLE `reference_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `reference_loot_template` +-- + +LOCK TABLES `reference_loot_template` WRITE; +/*!40000 ALTER TABLE `reference_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `reference_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `reserved_name` +-- + +DROP TABLE IF EXISTS `reserved_name`; +CREATE TABLE `reserved_name` ( + `name` varchar(12) NOT NULL default '', + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player Reserved Names'; + +-- +-- Dumping data for table `reserved_name` +-- + +LOCK TABLES `reserved_name` WRITE; +/*!40000 ALTER TABLE `reserved_name` DISABLE KEYS */; +/*!40000 ALTER TABLE `reserved_name` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `skill_discovery_template` +-- + +DROP TABLE IF EXISTS `skill_discovery_template`; +CREATE TABLE `skill_discovery_template` ( + `spellId` mediumint(8) unsigned NOT NULL default '0' COMMENT 'SpellId of the discoverable spell', + `reqSpell` mediumint(8) unsigned NOT NULL default '0' COMMENT 'spell requirement', + `chance` float NOT NULL default '0' COMMENT 'chance to discover', + PRIMARY KEY (`spellId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Discovery System'; + +-- +-- Dumping data for table `skill_discovery_template` +-- + +LOCK TABLES `skill_discovery_template` WRITE; +/*!40000 ALTER TABLE `skill_discovery_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `skill_discovery_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `skill_extra_item_template` +-- + +DROP TABLE IF EXISTS `skill_extra_item_template`; +CREATE TABLE `skill_extra_item_template` ( + `spellId` mediumint(8) unsigned NOT NULL default '0' COMMENT 'SpellId of the item creation spell', + `requiredSpecialization` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Specialization spell id', + `additionalCreateChance` float NOT NULL default '0' COMMENT 'chance to create add', + `additionalMaxNum` tinyint(3) unsigned NOT NULL default '0' COMMENT 'max num of adds', + PRIMARY KEY (`spellId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Specialization System'; + +-- +-- Dumping data for table `skill_extra_item_template` +-- + +LOCK TABLES `skill_extra_item_template` WRITE; +/*!40000 ALTER TABLE `skill_extra_item_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `skill_extra_item_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `skill_fishing_base_level` +-- + +DROP TABLE IF EXISTS `skill_fishing_base_level`; +CREATE TABLE `skill_fishing_base_level` ( + `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Area identifier', + `skill` smallint(6) NOT NULL default '0' COMMENT 'Base skill level requirement', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Fishing system'; + +-- +-- Dumping data for table `skill_fishing_base_level` +-- + +LOCK TABLES `skill_fishing_base_level` WRITE; +/*!40000 ALTER TABLE `skill_fishing_base_level` DISABLE KEYS */; +/*!40000 ALTER TABLE `skill_fishing_base_level` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `skinning_loot_template` +-- + +DROP TABLE IF EXISTS `skinning_loot_template`; +CREATE TABLE `skinning_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `skinning_loot_template` +-- + +LOCK TABLES `skinning_loot_template` WRITE; +/*!40000 ALTER TABLE `skinning_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `skinning_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_affect` +-- + +DROP TABLE IF EXISTS `spell_affect`; +CREATE TABLE `spell_affect` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `effectId` tinyint(3) unsigned NOT NULL default '0', + `SpellFamilyMask` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`effectId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `spell_affect` +-- + +LOCK TABLES `spell_affect` WRITE; +/*!40000 ALTER TABLE `spell_affect` DISABLE KEYS */; +INSERT INTO `spell_affect` VALUES +(5420,2,0x00001012100000D0), +(8875,1,0x0000040000000000), +(11069,0,0x0000000000000001), +(11070,0,0x0000000000000020), +(11071,0,0x0000000000100000), +(11083,0,0x0000000000C20017), +(11124,0,0x0000000008C20017), +(11151,0,0x00000000000202E0), +(11160,0,0x00000001020203E0), +(11175,1,0x0000000000100000), +(11207,0,0x00000000000202E0), +(11222,0,0x0000000020001800), +(11242,0,0x0000000020001000), +(11247,0,0x0000000000002000), +(12042,0,0x0000000020E01AF7), +(12042,1,0x0000000020E01AF7), +(12042,2,0x0000000020E01AF7), +(12043,0,0x0000000021400035), +(12285,0,0x0000000000000001), +(12286,0,0x0000000000000020), +(12287,1,0x0000000000000080), +(12295,1,0x0000000002000000), +(12295,2,0x0000040000000000), +(12301,0,0x0000000000000100), +(12303,1,0x0000100000000000), +(12308,0,0x0000000000004000), +(12318,0,0x0000008000010000), +(12321,0,0x0000008000030000), +(12321,1,0x0000008000030000), +(12330,0,0x0000000000200000), +(12338,0,0x0000000000000001), +(12339,0,0x0000000000000001), +(12340,0,0x0000000000000001), +(12341,0,0x0000000000000001), +(12351,0,0x0000000000C20017), +(12378,0,0x0000000008C20017), +(12398,0,0x0000000008C20017), +(12399,0,0x0000000008C20017), +(12400,0,0x0000000008C20017), +(12467,0,0x0000000020001000), +(12469,0,0x0000000020001000), +(12472,1,0x00000000E44008A5), +(12473,0,0x0000000000000020), +(12496,0,0x0000000000100000), +(12497,0,0x0000000000100000), +(12518,0,0x00000001020203E0), +(12519,0,0x00000001020203E0), +(12536,0,0x0000000020C01AF7), +(12569,1,0x0000000000100000), +(12571,1,0x0000000000100000), +(12658,0,0x0000000000000020), +(12659,0,0x0000000000000020), +(12665,1,0x0000000000000080), +(12666,1,0x0000000000000080), +(12672,0,0x00000000000202E0), +(12676,1,0x0000000002000000), +(12676,2,0x0000040000000000), +(12677,1,0x0000000002000000), +(12677,2,0x0000040000000000), +(12697,0,0x0000000000000001), +(12788,1,0x0000100000000000), +(12789,1,0x0000100000000000), +(12810,0,0x0000000000004000), +(12811,0,0x0000000000004000), +(12818,0,0x0000000000000100), +(12835,0,0x0000008000030000), +(12835,1,0x0000008000030000), +(12836,0,0x0000008000030000), +(12836,1,0x0000008000030000), +(12837,0,0x0000008000030000), +(12837,1,0x0000008000030000), +(12838,0,0x0000008000030000), +(12838,1,0x0000008000030000), +(12839,0,0x0000000020001800), +(12840,0,0x0000000020001800), +(12841,0,0x0000000020001800), +(12842,0,0x0000000020001800), +(12857,0,0x0000008000010000), +(12858,0,0x0000008000010000), +(12860,0,0x0000008000010000), +(12861,0,0x0000008000010000), +(12862,0,0x0000000000200000), +(12945,1,0x0000000000001000), +(12952,0,0x00000000000202E0), +(12953,0,0x00000000000202E0), +(12954,0,0x00000000000202E0), +(12957,0,0x00000000000202E0), +(13733,0,0x0000000000000004), +(13733,1,0x0000000400000000), +(13742,0,0x0000000000000060), +(13743,0,0x0000000000000040), +(13865,0,0x0000000000000004), +(13865,1,0x0000000400000000), +(13866,0,0x0000000000000004), +(13866,1,0x0000000400000000), +(13872,0,0x0000000000000060), +(13875,0,0x0000000000000040), +(13975,0,0x0000000000400000), +(13975,1,0x0000000000400000), +(13976,0,0x0000000000000700), +(13979,0,0x0000000000000700), +(13980,0,0x0000000000000700), +(13981,0,0x0000000001000000), +(13981,1,0x0000000000000800), +(14057,0,0x0000000600000304), +(14062,0,0x0000000000400000), +(14062,1,0x0000000000400000), +(14063,0,0x0000000000400000), +(14063,1,0x0000000000400000), +(14064,0,0x0000000000400000), +(14064,1,0x0000000000400000), +(14065,0,0x0000000000400000), +(14065,1,0x0000000000400000), +(14066,0,0x0000000001000000), +(14066,1,0x0000000000000800), +(14072,0,0x0000000600000304), +(14073,0,0x0000000600000304), +(14074,0,0x0000000600000304), +(14075,0,0x0000000600000304), +(14076,0,0x0000000001000080), +(14076,1,0x0000000001000080), +(14082,0,0x0000000000000500), +(14083,0,0x0000000000000500), +(14094,0,0x0000000001000080), +(14094,1,0x0000000001000080), +(14113,0,0x000000000001E000), +(14114,0,0x000000000001E000), +(14115,0,0x000000000001E000), +(14116,0,0x000000000001E000), +(14117,0,0x000000000001E000), +(14128,0,0x000000062600000E), +(14132,0,0x000000062600000E), +(14135,0,0x000000062600000E), +(14136,0,0x000000062600000E), +(14137,0,0x000000062600000E), +(14143,0,0x0000000004000206), +(14149,0,0x0000000004000206), +(14162,0,0x0000000000020000), +(14163,0,0x0000000000020000), +(14164,0,0x0000000000020000), +(14168,0,0x0000000000080000), +(14169,0,0x0000000000080000), +(14174,0,0x0000000000200000), +(14175,0,0x0000000000200000), +(14176,0,0x0000000000200000), +(14177,0,0x0000000C6012031E), +(14179,0,0x00000009003E0000), +(14520,0,0x00000963BF61C16F), +(14523,1,0x000000208030016B), +(14523,2,0x000000208030016B), +(14743,0,0x0000049440963E90), +(14747,0,0x0000000000000002), +(14750,0,0x0000000000000010), +(14751,0,0xFFFFFFFFFFFFFFFF), +(14751,1,0xFFFFFFFFFFFFFFFF), +(14770,0,0x0000000000000002), +(14771,0,0x0000000000000002), +(14772,0,0x0000000000000010), +(14780,0,0x00000963BF61C16F), +(14781,0,0x00000963BF61C16F), +(14782,0,0x00000963BF61C16F), +(14783,0,0x00000963BF61C16F), +(14784,1,0x000000208030016B), +(14784,2,0x000000208030016B), +(14785,1,0x000000208030016B), +(14785,2,0x000000208030016B), +(14786,1,0x000000208030016B), +(14786,2,0x000000208030016B), +(14787,1,0x000000208030016B), +(14787,2,0x000000208030016B), +(14908,0,0x0000000000000040), +(14909,1,0x0000000000100080), +(14911,0,0x0000002000000200), +(14912,0,0x0000000000041400), +(14913,0,0x0000000400041E00), +(15012,0,0x0000000400041E00), +(15013,0,0x0000000000041400), +(15014,0,0x0000000000041400), +(15017,1,0x0000000000100080), +(15018,0,0x0000002000000200), +(15020,0,0x0000000000000040), +(15047,0,0x00000000000202E0), +(15052,0,0x00000000000202E0), +(15053,0,0x00000000000202E0), +(15257,0,0x000004020288A010), +(15259,0,0x0000000202002000), +(15259,1,0x0000040000808000), +(15260,0,0x00000442068BA000), +(15272,0,0x00000D4A068BE104), +(15307,0,0x0000000202002000), +(15307,1,0x0000040000808000), +(15308,0,0x0000000202002000), +(15308,1,0x0000040000808000), +(15309,0,0x0000000202002000), +(15309,1,0x0000040000808000), +(15310,0,0x0000000202002000), +(15310,1,0x0000040000808000), +(15318,0,0x00000D4A068BE104), +(15320,0,0x00000D4A068BE104), +(15327,0,0x00000442068BA000), +(15328,0,0x00000442068BA000), +(15329,0,0x00000442068BA000), +(15330,0,0x00000442068BA000), +(15331,0,0x000004020288A010), +(15332,0,0x000004020288A010), +(15333,0,0x000004020288A010), +(15334,0,0x000004020288A010), +(16035,0,0x0000000090100003), +(16038,0,0x0000000040000000), +(16039,0,0x0000000090100003), +(16041,0,0x0000000000000003), +(16043,0,0x0000000000000008), +(16043,1,0x0000000100000000), +(16086,0,0x0000000000000020), +(16086,1,0x0000000000000020), +(16086,2,0x0000000000000004), +(16089,0,0x00000004D3300407), +(16105,0,0x0000000090100003), +(16106,0,0x0000000090100003), +(16106,1,0x0000000090100003), +(16107,0,0x0000000090100003), +(16108,0,0x0000000090100003), +(16109,0,0x0000000090100003), +(16110,0,0x0000000090100003), +(16111,0,0x0000000090100003), +(16112,0,0x0000000090100003), +(16117,0,0x0000000000000003), +(16118,0,0x0000000000000003), +(16119,0,0x0000000000000003), +(16120,0,0x0000000000000003), +(16130,0,0x0000000000000008), +(16130,1,0x0000000100000000), +(16160,0,0x0000000040000000), +(16161,0,0x0000000040000000), +(16166,0,0x0000000090100003), +(16166,1,0x0000000090100003), +(16173,0,0x0000000020081018), +(16179,0,0x00000000000000C0), +(16181,0,0x00000000000001C0), +(16184,0,0x0000000000000200), +(16184,1,0x0000000000000200), +(16187,0,0x0000000000006000), +(16187,1,0x0000000000006000), +(16188,0,0x00000000000009C3), +(16189,0,0x000001000403E000), +(16205,0,0x0000000000006000), +(16205,1,0x0000000000006000), +(16206,0,0x0000000000006000), +(16206,1,0x0000000000006000), +(16207,0,0x0000000000006000), +(16207,1,0x0000000000006000), +(16208,0,0x0000000000006000), +(16208,1,0x0000000000006000), +(16209,1,0x0000000000000200), +(16214,0,0x00000000000000C0), +(16215,0,0x00000000000000C0), +(16216,0,0x00000000000000C0), +(16217,0,0x00000000000000C0), +(16222,0,0x0000000020081018), +(16223,0,0x0000000020081018), +(16224,0,0x0000000020081018), +(16225,0,0x0000000020081018), +(16230,0,0x00000000000001C0), +(16232,0,0x00000000000001C0), +(16233,0,0x00000000000001C0), +(16234,0,0x00000000000001C0), +(16246,0,0x0000000090100003), +(16258,0,0x0000000000008000), +(16258,1,0x0000000000040000), +(16259,0,0x0000000000010000), +(16259,1,0x0000000000020000), +(16261,0,0x0000000000000400), +(16266,0,0x0000000000400000), +(16266,1,0x0000000001000000), +(16266,2,0x0000000000800000), +(16290,0,0x0000000000000400), +(16291,0,0x0000000000000400), +(16293,0,0x0000000000008000), +(16293,1,0x0000000000040000), +(16295,0,0x0000000000010000), +(16295,1,0x0000000000020000), +(16493,0,0x0000014D2A600CEF), +(16494,0,0x0000014D2A600CEF), +(16513,0,0x000000080001E000), +(16513,1,0x000000000001E000), +(16513,2,0x000000000001E000), +(16514,0,0x000000080001E000), +(16514,1,0x000000000001E000), +(16514,2,0x000000000001E000), +(16515,0,0x000000080001E000), +(16515,1,0x000000000001E000), +(16515,2,0x000000000001E000), +(16544,2,0x0000000000000004), +(16578,0,0x0000000000000003), +(16579,0,0x0000000000000003), +(16580,0,0x0000000000000003), +(16581,0,0x0000000000000003), +(16582,0,0x0000000000000003), +(16719,0,0x000000080001E000), +(16719,1,0x000000000001E000), +(16719,2,0x000000000001E000), +(16720,0,0x000000080001E000), +(16720,1,0x000000000001E000), +(16720,2,0x000000000001E000), +(16757,0,0x00000000000200A0), +(16757,1,0x0000000000000240), +(16758,0,0x00000000000200A0), +(16758,1,0x0000000000000240), +(16763,0,0x0000000000000020), +(16765,0,0x0000000000000020), +(16766,0,0x0000000000000020), +(16814,0,0x0000000000000005), +(16815,0,0x0000000000000005), +(16816,0,0x0000000000000005), +(16817,0,0x0000000000000005), +(16818,0,0x0000000000000005), +(16819,0,0x0002122000600707), +(16820,0,0x0002122000600707), +(16821,0,0x0000000000000002), +(16821,1,0x0000000000000002), +(16821,2,0x0000000000000002), +(16822,0,0x0000000000000002), +(16822,1,0x0000000000000002), +(16822,2,0x0000000000000002), +(16833,0,0x0000E000E2000000), +(16834,0,0x0000E000E2000000), +(16835,0,0x0000E000E2000000), +(16836,1,0x0000000000000300), +(16839,1,0x0000000000000300), +(16840,1,0x0000000000000300), +(16850,1,0x0000000000000001), +(16870,0,0x001007F100E3FEFF), +(16886,0,0x0000000001000265), +(16896,0,0x0000000000000007), +(16896,1,0x0000000000000007), +(16897,0,0x0000000000000007), +(16897,1,0x0000000000000007), +(16899,0,0x0000000000000007), +(16899,1,0x0000000000000007), +(16900,0,0x0000000000000007), +(16900,1,0x0000000000000007), +(16901,0,0x0000000000000007), +(16901,1,0x0000000000000007), +(16918,0,0x0000002000000200), +(16919,0,0x0000002000000200), +(16920,0,0x0000002000000200), +(16923,1,0x0000000000000001), +(16924,1,0x0000000000000001), +(16934,0,0x0010004000000800), +(16934,1,0x0000040000001000), +(16935,0,0x0010004000000800), +(16935,1,0x0000040000001000), +(16936,0,0x0010004000000800), +(16936,1,0x0000040000001000), +(16937,0,0x0010004000000800), +(16937,1,0x0000040000001000), +(16938,0,0x0010004000000800), +(16938,1,0x0000040000001000), +(16947,1,0x0000000002000000), +(16948,1,0x0000000002000000), +(16949,1,0x0000000002000000), +(16966,0,0x0000000000008000), +(16966,1,0x0000010000000000), +(16968,0,0x0000000000008000), +(16968,1,0x0000010000000000), +(16998,0,0x0000000000001000), +(16998,2,0x0000000000001000), +(16999,0,0x0000000000001000), +(16999,2,0x0000000000001000), +(17104,0,0x00000010000000F0), +(17104,1,0x00000010000000F0), +(17111,0,0x0000000000000010), +(17112,0,0x0000000000000010), +(17113,0,0x0000000000000010), +(17114,0,0x0000000000000010), +(17115,0,0x0000000000000010), +(17116,0,0x0002002010000261), +(17118,0,0x001005D000E193F7), +(17118,1,0x0004103000340750), +(17119,0,0x001005D000E193F7), +(17119,1,0x0004103000340750), +(17120,0,0x001005D000E193F7), +(17120,1,0x0004103000340750), +(17121,0,0x001005D000E193F7), +(17121,1,0x0004103000340750), +(17122,0,0x001005D000E193F7), +(17122,1,0x0004103000340750), +(17123,0,0x0000000000000080), +(17124,0,0x0000000000000080), +(17191,0,0x0000000000000040), +(17322,0,0x00000542068AA004), +(17323,0,0x00000542068AA004), +(17768,0,0x0000000040000000), +(17768,1,0x0000000080000000), +(17778,0,0x000010C0000003E5), +(17779,0,0x000010C0000003E5), +(17780,0,0x000010C0000003E5), +(17781,0,0x000010C0000003E5), +(17782,0,0x000010C0000003E5), +(17788,1,0x0000008000000000), +(17789,1,0x0000008000000000), +(17790,1,0x0000008000000000), +(17791,1,0x0000008000000000), +(17792,1,0x0000008000000000), +(17904,0,0x0000000000000000), +(17912,0,0x0000000000000000), +(17913,0,0x0000000000000000), +(17914,0,0x0000000000000000), +(17915,0,0x0000000000000000), +(17916,0,0x0000000000000000), +(17917,0,0x000010C0000003A5), +(17917,1,0x000010C0000003E5), +(17918,0,0x000010C0000003A5), +(17918,1,0x000010C0000003E5), +(17927,0,0x0000000000000100), +(17929,0,0x0000000000000100), +(17930,0,0x0000000000000100), +(17941,0,0x0000000000000001), +(17954,0,0x000000C000001364), +(17954,1,0x000000C000001364), +(17954,2,0x0000004000000000), +(17955,0,0x000000C000001364), +(17955,1,0x000000C000001364), +(17955,2,0x0000004000000000), +(17956,0,0x000000C000001364), +(17956,1,0x000000C000001364), +(17956,2,0x0000004000000000), +(17957,0,0x000000C000001364), +(17957,1,0x000000C000001364), +(17957,2,0x0000004000000000), +(17958,0,0x000000C000001364), +(17958,1,0x000000C000001364), +(17958,2,0x0000004000000000), +(17959,0,0x000010C0000003E5), +(18126,0,0x0000000000001000), +(18127,0,0x0000000000001000), +(18130,0,0x000010C0000003E5), +(18131,0,0x000010C0000003E5), +(18132,0,0x000010C0000003E5), +(18133,0,0x000010C0000003E5), +(18134,0,0x000010C0000003E5), +(18135,0,0x000010C0000003E5), +(18136,0,0x000010C0000003E5), +(18174,0,0x0000071B804CC41A), +(18175,0,0x0000071B804CC41A), +(18176,0,0x0000071B804CC41A), +(18177,0,0x0000071B804CC41A), +(18178,0,0x0000071B804CC41A), +(18179,0,0x0000000000008000), +(18180,0,0x0000000000008000), +(18213,0,0x0000000000004000), +(18213,1,0x0000871B804CC41A), +(18218,0,0x000007138048C41A), +(18219,0,0x000007138048C41A), +(18271,0,0x000011130008A48B), +(18271,1,0x000011130008A48B), +(18272,0,0x000011130008A48B), +(18272,1,0x000011130008A48B), +(18273,0,0x000011130008A48B), +(18273,1,0x000011130008A48B), +(18274,0,0x000011130008A48B), +(18274,1,0x000011130008A48B), +(18275,0,0x000011130008A48B), +(18275,1,0x000011130008A48B), +(18288,0,0x0000000200000400), +(18288,1,0x0000000000400000), +(18372,1,0x0000871B804CC41A), +(18427,0,0x0000000000020006), +(18428,0,0x0000000000020006), +(18429,0,0x0000000000020006), +(18544,0,0x0000041202F8A090), +(18544,1,0x0000001202582090), +(18544,2,0x0000040000A08000), +(18547,0,0x0000041202F8A090), +(18547,1,0x0000001202582090), +(18547,2,0x0000040000A08000), +(18548,0,0x0000041202F8A090), +(18548,1,0x0000001202582090), +(18548,2,0x0000040000A08000), +(18549,0,0x0000041202F8A090), +(18549,1,0x0000001202582090), +(18549,2,0x0000040000A08000), +(18550,0,0x0000041202F8A090), +(18550,1,0x0000001202582090), +(18550,2,0x0000040000A08000), +(18703,1,0x0000000001000000), +(18704,1,0x0000000001000000), +(18731,0,0x0000000010000000), +(18743,0,0x0000000010000000), +(18744,0,0x0000000010000000), +(18748,0,0x0000000008000000), +(18749,0,0x0000000008000000), +(18750,0,0x0000000008000000), +(18767,1,0x0000000000020000), +(18768,1,0x0000000000020000), +(18821,0,0x0000000000000800), +(18821,1,0x0000000000000800), +(18821,2,0x0000000000000800), +(18822,0,0x0000000000000800), +(18822,1,0x0000000000000800), +(18822,2,0x0000000000000800), +(18827,0,0x0000000000000400), +(18829,0,0x0000000000000400), +(19239,0,0x0000000000000018), +(19239,1,0x0000000000000004), +(19245,0,0x0000000000000018), +(19245,1,0x0000200000000004), +(19416,0,0x000210810007FA00), +(19417,0,0x000210810007FA00), +(19418,0,0x000210810007FA00), +(19419,0,0x000210810007FA00), +(19420,0,0x000210810007FA00), +(19461,0,0x0000000000003000), +(19461,1,0x0000000000003000), +(19462,0,0x0000000000003000), +(19462,1,0x0000000000003000), +(19464,0,0x0000010000004000), +(19464,1,0x0000008000000000), +(19464,2,0x000011800000C000), +(19465,0,0x0000010000004000), +(19465,1,0x0000008000000000), +(19465,2,0x000011800000C000), +(19466,0,0x0000010000004000), +(19466,1,0x0000008000000000), +(19466,2,0x000011800000C000), +(19467,0,0x0000010000004000), +(19467,1,0x0000008000000000), +(19467,2,0x000011800000C000), +(19468,0,0x0000010000004000), +(19468,1,0x0000008000000000), +(19468,2,0x000011800000C000), +(19485,0,0x0000000100061801), +(19487,0,0x0000000100061801), +(19488,0,0x0000000100061801), +(19489,0,0x0000000100061801), +(19490,0,0x0000000100061801), +(19498,0,0x000210810007FA01), +(19499,0,0x000210810007FA01), +(19500,0,0x000210810007FA01), +(19549,0,0x0000000000080000), +(19550,0,0x0000000000080000), +(19551,0,0x0000000000080000), +(19552,0,0x0000000000100000), +(19552,1,0x0000020000000000), +(19553,0,0x0000000000100000), +(19553,1,0x0000020000000000), +(19554,0,0x0000000000100000), +(19554,1,0x0000020000000000), +(19555,0,0x0000000000100000), +(19555,1,0x0000020000000000), +(19556,0,0x0000000000100000), +(19556,1,0x0000020000000000), +(19559,0,0x0000000000200000), +(19560,0,0x0000000000200000), +(19572,1,0x0000000000800000), +(19573,1,0x0000000000800000), +(19583,0,0x0000000008000000), +(19584,0,0x0000000008000000), +(19585,0,0x0000000008000000), +(19586,0,0x0000000008000000), +(19587,0,0x0000000008000000), +(19590,0,0x0000000020000000), +(19592,0,0x0000000020000000), +(19598,0,0x0000000040000000), +(19599,0,0x0000000040000000), +(19600,0,0x0000000040000000), +(19601,0,0x0000000040000000), +(19602,0,0x0000000040000000), +(19609,0,0x0000000004000000), +(19610,0,0x0000000004000000), +(19612,0,0x0000000004000000), +(20101,0,0x000004000A000200), +(20102,0,0x000004000A000200), +(20103,0,0x000004000A000200), +(20104,0,0x000004000A000200), +(20105,0,0x000004000A000200), +(20138,0,0x0000000000000040), +(20139,0,0x0000000000000040), +(20140,0,0x0000000000000040), +(20141,0,0x0000000000000040), +(20142,0,0x0000000000000040), +(20174,0,0x0000000000000080), +(20174,1,0x0000000000000010), +(20175,0,0x0000000000000080), +(20175,1,0x0000000000000010), +(20216,0,0x00010000C0200000), +(20224,0,0x0000000008000400), +(20225,0,0x0000000008000400), +(20237,0,0x00000000C0000000), +(20238,0,0x00000000C0000000), +(20239,0,0x00000000C0000000), +(20249,0,0x0000000040000000), +(20250,0,0x0000000040000000), +(20251,0,0x0000000040000000), +(20254,0,0x0000000000020000), +(20254,1,0x0000000000020000), +(20254,2,0x0000000000020000), +(20255,0,0x0000000000020000), +(20255,1,0x0000000000020000), +(20255,2,0x0000000000020000), +(20256,0,0x0000000000020000), +(20256,1,0x0000000000020000), +(20256,2,0x0000000000020000), +(20330,0,0x0000000008000400), +(20331,0,0x0000000008000400), +(20332,0,0x0000000008000400), +(20335,0,0x0000000020000000), +(20336,0,0x0000000020000000), +(20337,0,0x0000000020000000), +(20359,0,0x0000000080000000), +(20360,0,0x0000000080000000), +(20361,0,0x0000000080000000), +(20468,1,0x0000000000000001), +(20469,1,0x0000000000000001), +(20470,1,0x0000000000000001), +(20575,0,0x0000000004000000), +(20575,1,0x0000000004000000), +(20576,0,0x0000000002000000), +(21873,0,0x0000E000E2000000), +(21881,0,0x000000000001E000), +(21887,0,0x0000036C2A764EEF), +(21895,0,0x000000000403E000), +(21899,0,0x0000000000000100), +(21942,1,0x0000000008000000), +(22008,0,0x0000000021400035), +(23025,0,0x0000000000010000), +(23047,0,0x0000040000000000), +(23047,1,0x0000040000000000), +(23158,0,0x0000000000000200), +(23300,0,0x0000000020000000), +(23555,0,0x000010C0000003E5), +(23561,0,0x0000000000004000), +(23566,0,0x0000000000001000), +(23724,0,0x0000E000E2000000), +(23726,0,0x0000000000002000), +(23726,1,0x0000000000010000), +(24348,0,0x0000000000200000), +(24429,0,0x0000000000004000), +(24431,0,0x0000000400000000), +(24460,0,0x0000000010000180), +(24469,0,0x0000000001000000), +(24499,0,0x0000000000000400), +(24542,1,0x00000000000000F0), +(24546,1,0x0000000400041E00), +(24691,0,0x0000000000003000), +(24691,1,0x0000000000003000), +(24943,0,0x00000010000000F0), +(24943,1,0x00000010000000F0), +(24944,0,0x00000010000000F0), +(24944,1,0x00000010000000F0), +(24945,0,0x00000010000000F0), +(24945,1,0x00000010000000F0), +(24946,0,0x00000010000000F0), +(24946,1,0x00000010000000F0), +(26106,0,0x0000000010000000), +(26109,0,0x00000080000F0000), +(26112,0,0x0000000000000020), +(26118,0,0x0000000004000000), +(26118,1,0x0000000004000000), +(26174,0,0x0000000000000020), +(27789,1,0x0000000010400200), +(27790,1,0x0000000010400200), +(27828,0,0x0000049440963E90), +(27846,0,0x0000000000000020), +(27850,0,0x0000000000000040), +(27851,0,0x0000000000001000), +(28088,0,0x000000000001E000), +(28107,0,0x0000000000040000), +(28539,0,0x0000000000001000), +(28682,0,0x0000004008C20017), +(28743,0,0x00000000000000F0), +(28746,1,0x0000000100000406), +(28751,0,0x0000000000021000), +(28755,0,0x0000000000000020), +(28763,0,0x0000000004000000), +(28774,0,0x0000000000008000), +(28775,0,0x0000000100000000), +(28787,0,0x0000000000001000), +(28807,0,0x0000000000000040), +(28808,0,0x0000000411041E40), +(28811,0,0x0000000002020006), +(28814,0,0x0000000000020000), +(28815,0,0x0000000002000006), +(28818,0,0x0000000020081018), +(28821,0,0x0000000000000400), +(28829,0,0x0000000000000002), +(28831,0,0x0000000000000001), +(28842,0,0x0000000100004440), +(28843,0,0x0000000000088000), +(28844,0,0x0000000000000400), +(28852,0,0x0000000000000200), +(28852,1,0x0000000020000000), +(28855,0,0x0000000000000800), +(28855,1,0x0010000000000000), +(28999,0,0x0000000000000003), +(29000,0,0x0000000000000003), +(29005,0,0x0000000090100003), +(29063,0,0x00000000000009C3), +(29079,0,0x0000000000400000), +(29079,1,0x0000000001000000), +(29079,2,0x0000000000800000), +(29080,0,0x0000000000400000), +(29080,1,0x0000000001000000), +(29080,2,0x0000000000800000), +(29171,0,0x0000000000004000), +(29187,0,0x00000000000001C0), +(29187,1,0x0004103000340750), +(29189,0,0x00000000000001C0), +(29189,1,0x0004103000340750), +(29191,0,0x00000000000001C0), +(29191,1,0x0004103000340750), +(29202,0,0x0000000000000040), +(29205,0,0x0000000000000040), +(29206,0,0x0000000000000040), +(29438,0,0x0000000000D000D7), +(29439,0,0x0000000000D000D7), +(29440,0,0x0000000000D000D7), +(29721,0,0x0000000400000000), +(29723,0,0x0000000800002010), +(29723,1,0x0000000800002010), +(29724,0,0x0000000800002010), +(29724,1,0x0000000800002010), +(29725,0,0x0000000800002010), +(29725,1,0x0000000800002010), +(29759,1,0x0000075D6E6ECEEF), +(29760,1,0x0000075D6E6ECEEF), +(29761,1,0x0000075D6E6ECEEF), +(29762,1,0x0000075D6E6ECEEF), +(29763,1,0x0000075D6E6ECEEF), +(29776,0,0x0000000400000000), +(29787,0,0x0000036C2A764EEF), +(29790,0,0x0000036C2A764EEF), +(29792,0,0x0000036C2A764EEF), +(29836,0,0x0000001000000020), +(29859,0,0x0000001000000020), +(29888,0,0x0000000040000000), +(29889,0,0x0000000040000000), +(29976,0,0x0000000021400035), +(30049,0,0x0000000000080000), +(30051,0,0x0000000000080000), +(30052,0,0x0000000000080000), +(30054,0,0x0000000800000000), +(30057,0,0x0000000800000000), +(30060,0,0x0000001000000402), +(30060,1,0x0000001000000402), +(30060,2,0x0000871B804CC41A), +(30061,0,0x0000001000000402), +(30061,1,0x0000001000000402), +(30061,2,0x0000871B804CC41A), +(30062,0,0x0000001000000402), +(30062,1,0x0000001000000402), +(30062,2,0x0000871B804CC41A), +(30063,0,0x0000001000000402), +(30063,1,0x0000001000000402), +(30063,2,0x0000871B804CC41A), +(30064,0,0x0000001000000402), +(30064,1,0x0000001000000402), +(30064,2,0x0000871B804CC41A), +(30085,0,0x0000071B804CC41A), +(30085,1,0x0000000000000400), +(30085,2,0x0000000000000002), +(30086,0,0x0000071B804CC41A), +(30086,1,0x0000000000000400), +(30086,2,0x0000000000000002), +(30143,0,0x0000002000000000), +(30144,0,0x0000002000000000), +(30145,0,0x0000002000000000), +(30242,0,0x0000200000000000), +(30245,0,0x0000200000000000), +(30246,0,0x0000200000000000), +(30247,0,0x0000200000000000), +(30248,0,0x0000200000000000), +(30251,0,0x000010C000000125), +(30256,0,0x000010C000000125), +(30288,0,0x0000004000000001), +(30289,0,0x0000004000000001), +(30290,0,0x0000004000000001), +(30291,0,0x0000004000000001), +(30292,0,0x0000004000000001), +(30319,1,0x0000400000000000), +(30320,1,0x0000400000000000), +(30321,1,0x0000400000000000), +(30326,0,0x0000000000040010), +(30327,0,0x0000000000040010), +(30328,0,0x0000000000040010), +(30812,0,0x00000C78B018141B), +(30813,0,0x00000C78B018141B), +(30814,0,0x00000C78B018141B), +(30872,0,0x0000000000000100), +(30873,0,0x0000000000000100), +(30892,0,0x0000000008000000), +(30893,0,0x0000000008000000), +(31216,1,0x0000000002000004), +(31217,1,0x0000000002000004), +(31218,1,0x0000000002000004), +(31219,1,0x0000000002000004), +(31220,1,0x0000000002000004), +(31226,0,0x000000000001E000), +(31227,0,0x000000000001E000), +(31234,0,0x000001002612030F), +(31234,1,0x0000000000100100), +(31235,0,0x000001002612030F), +(31235,1,0x0000000000100100), +(31236,0,0x000001002612030F), +(31236,1,0x0000000000100100), +(31237,0,0x000001002612030F), +(31237,1,0x0000000000100100), +(31238,0,0x000001002612030F), +(31238,1,0x0000000000100100), +(31571,0,0x0000000200000000), +(31572,0,0x0000000200000000), +(31573,0,0x0000000200000000), +(31579,0,0x0000000000200000), +(31579,1,0x0000000000000800), +(31582,0,0x0000000000200000), +(31582,1,0x0000000000000800), +(31583,0,0x0000000000200000), +(31583,1,0x0000000000000800), +(31656,0,0x0000000000000001), +(31657,0,0x0000000000000001), +(31658,0,0x0000000000000001), +(31659,0,0x0000000000000001), +(31660,0,0x0000000000000001), +(31670,0,0x0000000500000200), +(31672,0,0x0000000500000200), +(31682,0,0x0000000000000020), +(31682,1,0x0000000000000020), +(31683,0,0x0000000000000020), +(31683,1,0x0000000000000020), +(31684,0,0x0000000000000020), +(31684,1,0x0000000000000020), +(31685,0,0x0000000000000020), +(31685,1,0x0000000000000020), +(31686,0,0x0000000000000020), +(31686,1,0x0000000000000020), +(31821,0,0x0000000004020048), +(31825,0,0x0000000000001020), +(31825,1,0x0000000200000000), +(31826,0,0x0000000000001020), +(31826,1,0x0000000200000000), +(31834,0,0x0000000080000000), +(31844,1,0x000005401A00038C), +(31845,1,0x000005401A00038C), +(31848,0,0x0000000000400000), +(31848,1,0x0000000000400000), +(31849,0,0x0000000000400000), +(31849,1,0x0000000000400000), +(31869,0,0x0000002000000000), +(31870,0,0x0000002000000000), +(31879,0,0x0000000800000400), +(31880,0,0x0000000800000400), +(31881,0,0x0000000800000400), +(31882,0,0x0000000800000400), +(31883,0,0x0000000800000400), +(32043,1,0x000004000A000000), +(32203,1,0x0001100001C22000), +(32381,0,0x0000000000000002), +(32382,0,0x0000000000000002), +(32383,0,0x0000000000000002), +(32412,0,0x0000000000000400), +(32477,0,0x0000020000000000), +(32483,0,0x0000020000000000), +(32484,0,0x0000020000000000), +(32601,1,0x0000000020800008), +(32743,0,0x0000000000000800), +(32973,0,0x0000000090100000), +(33018,0,0x0000001000000000), +(33020,0,0x0000000000000400), +(33063,0,0x0000040000000000), +(33066,0,0x0000000000000002), +(33151,0,0x0000000000000080), +(33151,1,0x0000000000000080), +(33151,2,0x0000000000000080), +(33158,0,0x0000000000001000), +(33158,1,0x0000000000000800), +(33159,0,0x0000000000001000), +(33159,1,0x0000000000000800), +(33160,0,0x0000000000001000), +(33160,1,0x0000000000000800), +(33161,0,0x0000000000001000), +(33161,1,0x0000000000000800), +(33162,0,0x0000000000001000), +(33162,1,0x0000000000000800), +(33167,0,0x0000008100000000), +(33171,0,0x0000008100000000), +(33172,0,0x0000008100000000), +(33174,0,0x0000000000000020), +(33174,1,0x0000000000000020), +(33182,0,0x0000000000000020), +(33182,1,0x0000000000000020), +(33186,0,0x0000008000000000), +(33186,1,0x0000008000002080), +(33190,0,0x0000008000000000), +(33190,1,0x0000008000002080), +(33213,0,0x0000000000822000), +(33214,0,0x0000000000822000), +(33215,0,0x0000000000822000), +(33221,0,0x0000000200002000), +(33222,0,0x0000000200002000), +(33223,0,0x0000000200002000), +(33224,0,0x0000000200002000), +(33225,0,0x0000000200002000), +(33333,0,0x0000000020000000), +(33421,0,0x0000000200000000), +(33557,0,0x0000000000000200), +(33557,1,0x0000000020000000), +(33565,0,0x0000000000001000), +(33600,0,0x0000000000000400), +(33600,1,0x0000000000000400), +(33601,0,0x0000000000000400), +(33601,1,0x0000000000000400), +(33602,0,0x0000000000000400), +(33602,1,0x0000000000000400), +(33603,0,0x0000000000000004), +(33603,1,0x0000000000000001), +(33604,0,0x0000000000000004), +(33604,1,0x0000000000000001), +(33605,0,0x0000000000000004), +(33605,1,0x0000000000000001), +(33606,0,0x0000000000000004), +(33606,1,0x0000000000000001), +(33607,0,0x0000000000000004), +(33607,1,0x0000000000000001), +(33693,0,0x0000000000008000), +(33696,0,0x0000000000000001), +(33713,0,0x0000000200000000), +(33714,0,0x0000000200000000), +(33830,0,0x0000002000000000), +(33830,1,0x0000002000000000), +(33877,0,0x0000000000000002), +(33879,0,0x0000000000000020), +(33880,0,0x0000000000000020), +(33886,0,0x00000010000000D0), +(33887,0,0x00000010000000D0), +(33888,0,0x00000010000000D0), +(33889,0,0x00000010000000D0), +(33890,0,0x00000010000000D0), +(34128,0,0x0000001000000000), +(34129,0,0x0000000040000000), +(34129,1,0x0000000040000000), +(34131,0,0x0000000000000080), +(34131,1,0x0000000000000080), +(34253,0,0x0000010000000000), +(34297,0,0x0000080000000000), +(34300,0,0x0000080000000000), +(34318,0,0x0000000000000400), +(34318,1,0x0000002000000000), +(34323,0,0x0000008000800000), +(34453,1,0x0000000400000000), +(34454,1,0x0000000400000000), +(34455,0,0x0000002000000000), +(34455,1,0x0000004000000000), +(34459,0,0x0000002000000000), +(34459,1,0x0000004000000000), +(34460,0,0x0000002000000000), +(34460,1,0x0000004000000000), +(34462,1,0x0000000800000000), +(34464,1,0x0000000800000000), +(34465,1,0x0000000800000000), +(34466,1,0x0000001000000000), +(34467,1,0x0000001000000000), +(34468,1,0x0000001000000000), +(34469,1,0x0000001000000000), +(34470,1,0x0000001000000000), +(34491,0,0x00004000000000C2), +(34491,1,0x0000000000000080), +(34492,0,0x00004000000000C2), +(34492,1,0x0000000000000080), +(34493,0,0x00004000000000C2), +(34493,1,0x0000000000000080), +(34754,0,0x0000000400001800), +(34936,0,0x0000004000000001), +(34948,1,0x0000000000000020), +(34949,1,0x0000000000000020), +(35029,1,0x0000080000000000), +(35030,1,0x0000080000000000), +(35098,0,0x0000000000020801), +(35099,0,0x0000000000020801), +(35104,0,0x0000000000001000), +(35104,1,0x0000000000002000), +(35110,0,0x0000000000001000), +(35110,1,0x0000000000002000), +(35111,0,0x0000000000001000), +(35111,1,0x0000000000002000), +(35363,0,0x0000000000000005), +(35364,0,0x0000000000000005), +(35396,1,0x000004000A000000), +(35397,1,0x000004000A000000), +(35446,0,0x0000000002000000), +(35446,1,0x0000000002000000), +(35448,0,0x0000000002000000), +(35448,1,0x0000000002000000), +(35449,0,0x0000000002000000), +(35449,1,0x0000000002000000), +(35450,0,0x0000000002000000), +(35450,1,0x0000000002000000), +(35451,0,0x0000000002000000), +(35451,1,0x0000000002000000), +(35578,0,0x0000000028E212F7), +(35581,0,0x0000000028E212F7), +(36032,0,0x0000000020000000), +(36032,1,0x0000000020000000), +(36413,0,0x0000000000000001), +(36563,1,0x0000000000000204), +(36563,2,0x0000000000000100), +(37166,0,0x0000000000800000), +(37167,0,0x0000000000040000), +(37171,0,0x00000009003E0000), +(37180,0,0x0000000000000020), +(37181,0,0x0000000400000000), +(37183,0,0x0000010000000000), +(37184,0,0x0000040008000000), +(37184,1,0x0000040008000000), +(37185,0,0x0000004000000000), +(37186,0,0x0000000020000000), +(37187,0,0x0000020000000000), +(37190,0,0x0000000000000008), +(37191,0,0x0000004000000000), +(37194,0,0x0000000000800000), +(37207,0,0x0000000000000002), +(37209,0,0x0000000000000400), +(37209,1,0x0000002000000000), +(37210,0,0x0000000000004000), +(37211,0,0x0000008000000000), +(37212,0,0x0000010000000000), +(37223,0,0x0000000000010000), +(37224,0,0x0000001000000000), +(37225,0,0x0000000000000080), +(37234,0,0x0000000000000080), +(37240,0,0x0000000000000080), +(37241,0,0x0000020000000000), +(37286,0,0x0000000000000010), +(37287,0,0x0000E000E2000000), +(37292,0,0x0008000000000000), +(37297,0,0x0000100000000000), +(37313,0,0x0000000000000040), +(37314,0,0x0000001000000000), +(37316,0,0x0000000000000040), +(37325,0,0x0000000000000040), +(37333,0,0x0000000000008000), +(37333,1,0x0000010000000000), +(37376,0,0x0000001000000000), +(37380,0,0x0000000000000006), +(37423,0,0x0000000000000004), +(37424,0,0x0000000000008000), +(37438,0,0x0000000000000021), +(37439,0,0x0000002000000000), +(37439,1,0x0000004000000000), +(37439,2,0x0000008000000000), +(37441,0,0x0000000020000000), +(37441,1,0x0000000020000000), +(37447,0,0x0000010000000000), +(37481,0,0x0000000000000080), +(37484,0,0x0000000000000100), +(37485,0,0x0000000000001000), +(37505,0,0x0000000100000000), +(37507,0,0x0000000000000800), +(37508,0,0x0000000100061800), +(37512,0,0x00000080000F0000), +(37513,0,0x0000000000000001), +(37517,0,0x0000014D2A600CEF), +(37518,0,0x0000000400000000), +(37522,0,0x0000000000001000), +(37535,0,0x0000000002000000), +(37536,0,0x0000000000010000), +(37556,0,0x0000000400000000), +(37564,0,0x0000000000000200), +(37565,0,0x0000000000001000), +(37570,1,0x0000010000000000), +(37571,0,0x0000000000000080), +(37571,1,0x0000000000800000), +(37593,0,0x0000000000000040), +(37706,0,0x0000000411041E40), +(37721,0,0x00000010000000F0), +(37722,0,0x00000000000001C0), +(37723,0,0x00000000C0000000), +(37736,0,0x0000040000000000), +(37736,1,0x0000004000000000), +(37737,0,0x0000000000000040), +(37738,0,0x0000000000000040), +(37739,0,0x0000000080000000), +(37740,0,0x0000000000000001), +(37742,0,0x0000004000000000), +(37760,0,0x0000000000000001), +(37762,0,0x0000001000000000), +(37763,0,0x0000800000000000), +(37878,0,0x00000010000000F0), +(37879,0,0x00000000C0000000), +(37880,0,0x0000000411041E40), +(37881,0,0x00000000000001C0), +(38314,0,0x0000E000E2000000), +(38321,0,0x0000000000000020), +(38322,0,0x0000000000000100), +(38388,0,0x0000000000040000), +(38389,0,0x0000000E00000006), +(38392,0,0x0000000100000000), +(38393,0,0x0000000000000001), +(38396,0,0x0000000004000000), +(38397,0,0x0000000000000821), +(38398,0,0x0000000020000000), +(38399,0,0x0000000002000000), +(38407,0,0x0000000100000000), +(38408,0,0x0000008000000000), +(38410,0,0x0000000000000200), +(38411,0,0x0000000000001000), +(38412,0,0x0000000000002000), +(38413,0,0x0000000000008000), +(38414,0,0x0000000000000002), +(38415,0,0x0000000000000004), +(38416,0,0x0010000000800000), +(38416,1,0x0010000000800000), +(38417,0,0x0000000200000000), +(38420,0,0x0000000000000020), +(38421,0,0x0000100000000000), +(38422,0,0x0000000000000020), +(38424,0,0x0000008000000000), +(38425,0,0x0000000040000000), +(38426,0,0x0000000080000000), +(38429,0,0x0000000090100000), +(38434,0,0x0000000000000100), +(38435,0,0x0000000000000080), +(38436,0,0x0000000000000001), +(38447,0,0x0000040000000000), +(38447,1,0x0000004000000000), +(38466,0,0x0008000000000000), +(38499,0,0x0000008000000000), +(38501,0,0x0000000000000080), +(38522,0,0x0000000040000000), +(39805,0,0x0000000000000003), +(39805,1,0x0000000000000003), +(39926,1,0x0000080000000000), +(39926,2,0x0000200000000000), +(39950,0,0x0000000000000040), +(40389,0,0x0000800000000000), +(40460,0,0x00000009003E0000), +(41021,0,0x0000004000000000), +(41021,1,0x0000004000000000), +(41026,0,0x0000004000000000), +(41026,1,0x0000004000000000), +(41037,0,0x0000044000000000), +(41042,0,0x0000000000800000), +(42367,0,0x0000001000000000), +(43339,0,0x0000000090100000), +(43725,0,0x0000001000000000), +(43736,0,0x0000000000000010), +(43743,1,0x0000000008000400), +(43752,0,0x0000000000000100), +(43837,0,0x0000000080000000), +(43840,0,0x0000044000000000), +(43841,0,0x0000000000000002), +(43842,0,0x0000044000000000), +(43843,0,0x0000044000000000), +(43844,0,0x0000000000000002), +(43845,0,0x0000000000000002), +(43850,0,0x0000000000800000), +(43851,0,0x0000000000800000), +(43852,0,0x0000000000800000), +(43854,0,0x0000004000000000), +(43855,0,0x0000004000000000), +(43856,0,0x0000004000000000), +(43857,0,0x0000001000000000), +(43858,0,0x0000001000000000), +(43859,0,0x0000001000000000), +(43860,0,0x0000000090100000), +(43861,0,0x0000000090100000), +(43862,0,0x0000000090100000), +(44292,0,0x0000000000001000), +(44293,0,0x0000000000000200), +(44295,0,0x0000000090100000), +(44296,0,0x0000000000000001), +(44297,0,0x0000000000010000), +(44299,0,0x0000000000040000), +(44300,0,0x0000800000000000), +(44301,0,0x0000000001000000), +(44302,0,0x0000000001000000), +(46088,0,0x0000044000000000), +(46090,0,0x0000000000000002), +(46091,0,0x0000000000800000), +(46095,0,0x0000004000000000), +(46096,0,0x0000001000000000), +(46097,0,0x0000000090100000), +(46100,0,0x0000001000000000), +(46833,0,0x0000000000000004), +(46834,0,0x0000000000000040), +(46851,0,0x0001000000000000); + +/*!40000 ALTER TABLE `spell_affect` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_chain` +-- + +DROP TABLE IF EXISTS `spell_chain`; +CREATE TABLE `spell_chain` ( + `spell_id` mediumint(9) NOT NULL default '0', + `prev_spell` mediumint(9) NOT NULL default '0', + `first_spell` mediumint(9) NOT NULL default '0', + `rank` tinyint(4) NOT NULL default '0', + `req_spell` mediumint(9) NOT NULL default '0', + PRIMARY KEY (`spell_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell Additinal Data'; + +-- +-- Dumping data for table `spell_chain` +-- + +LOCK TABLES `spell_chain` WRITE; +/*!40000 ALTER TABLE `spell_chain` DISABLE KEYS */; +INSERT INTO `spell_chain` VALUES +(10,0,10,1,0), +(17,0,17,1,0), +(53,0,53,1,0), +(72,0,72,1,0), +(78,0,78,1,0), +(99,0,99,1,0), +(100,0,100,1,0), +(116,0,116,1,0), +(118,0,118,1,0), +(120,0,120,1,0), +(122,0,122,1,0), +(133,0,133,1,0), +(136,0,136,1,0), +(139,0,139,1,0), +(143,133,133,2,0), +(145,143,133,3,0), +(168,0,168,1,0), +(172,0,172,1,0), +(205,116,116,2,0), +(284,78,78,2,0), +(285,284,78,3,0), +(324,0,324,1,0), +(325,324,324,2,0), +(331,0,331,1,0), +(332,331,331,2,0), +(339,0,339,1,0), +(348,0,348,1,0), +(370,0,370,1,0), +(403,0,403,1,0), +(408,0,408,1,0), +(421,0,421,1,0), +(453,0,453,1,0), +(465,0,465,1,0), +(467,0,467,1,0), +(469,0,469,1,0), +(498,0,498,1,0), +(527,0,527,1,0), +(529,403,403,2,0), +(543,0,543,1,0), +(547,332,331,3,0), +(548,529,403,3,0), +(585,0,585,1,0), +(586,0,586,1,0), +(587,0,587,1,0), +(588,0,588,1,0), +(589,0,589,1,0), +(591,585,585,2,0), +(592,17,17,2,0), +(594,589,589,2,0), +(596,0,596,1,0), +(597,587,587,2,0), +(598,591,585,3,0), +(600,592,17,3,0), +(602,7128,588,3,0), +(603,0,603,1,0), +(604,0,604,1,0), +(605,0,605,1,0), +(633,0,633,1,0), +(635,0,635,1,0), +(639,635,635,2,0), +(642,0,642,1,0), +(643,10290,465,3,0), +(647,639,635,3,0), +(686,0,686,1,0), +(687,0,687,1,0), +(688,0,688,1,0), +(689,0,689,1,0), +(693,0,693,1,0), +(694,0,694,1,0), +(695,686,686,2,0), +(696,687,687,2,0), +(699,689,689,2,0), +(702,0,702,1,0), +(703,0,703,1,0), +(704,0,704,1,0), +(705,695,686,3,0), +(706,0,706,1,0), +(707,348,348,2,0), +(709,699,689,3,0), +(710,0,710,1,0), +(724,0,724,1,0), +(740,0,740,1,0), +(755,0,755,1,0), +(769,780,779,3,0), +(770,0,770,1,0), +(772,0,772,1,0), +(774,0,774,1,0), +(778,770,770,2,0), +(779,0,779,1,0), +(780,779,779,2,0), +(781,0,781,1,0), +(782,467,467,2,0), +(837,205,116,3,0), +(845,0,845,1,0), +(853,0,853,1,0), +(865,122,122,2,0), +(879,0,879,1,0), +(905,325,324,3,0), +(913,547,331,4,0), +(915,548,403,4,0), +(930,421,421,2,0), +(939,913,331,5,0), +(943,915,403,5,0), +(945,905,324,4,0), +(959,939,331,6,0), +(970,594,589,3,0), +(974,0,974,1,0), +(976,0,976,1,0), +(980,0,980,1,0), +(984,598,585,4,0), +(988,527,527,2,0), +(990,597,587,3,0), +(992,970,589,4,0), +(996,596,596,2,0), +(1004,984,585,5,0), +(1006,602,588,4,0), +(1008,0,1008,1,0), +(1014,980,980,2,0), +(1020,642,642,2,0), +(1022,0,1022,1,0), +(1026,647,635,4,0), +(1032,10291,465,5,0), +(1038,0,1038,1,0), +(1042,1026,635,5,0), +(1058,774,774,2,0), +(1062,339,339,2,0), +(1064,0,1064,1,0), +(1075,782,467,3,0), +(1079,0,1079,1,0), +(1082,0,1082,1,0), +(1086,706,706,2,0), +(1088,705,686,4,0), +(1094,707,348,3,0), +(1098,0,1098,1,0), +(1106,1088,686,5,0), +(1108,702,702,2,0), +(1120,0,1120,1,0), +(1126,0,1126,1,0), +(1130,0,1130,1,0), +(1160,0,1160,1,0), +(1243,0,1243,1,0), +(1244,1243,1243,2,0), +(1245,1244,1243,3,0), +(1329,0,1329,1,0), +(1430,1058,774,3,0), +(1449,0,1449,1,0), +(1454,0,1454,1,0), +(1455,1454,1454,2,0), +(1456,1455,1454,3,0), +(1459,0,1459,1,0), +(1460,1459,1459,2,0), +(1461,1460,1459,3,0), +(1463,0,1463,1,0), +(1464,0,1464,1,0), +(1490,0,1490,1,0), +(1495,0,1495,1,0), +(1499,0,1499,1,0), +(1510,0,1510,1,0), +(1513,0,1513,1,0), +(1535,0,1535,1,0), +(1608,285,78,4,0), +(1671,72,72,2,0), +(1672,1671,72,3,0), +(1714,0,1714,1,0), +(1715,0,1715,1,0), +(1735,99,99,2,0), +(1742,0,1742,1,0), +(1752,0,1752,1,0), +(1753,1742,1742,2,0), +(1754,1753,1742,3,0), +(1755,1754,1742,4,0), +(1756,1755,1742,5,0), +(1757,1752,1752,2,0), +(1758,1757,1752,3,0), +(1759,1758,1752,4,0), +(1760,1759,1752,5,0), +(1766,0,1766,1,0), +(1767,1766,1766,2,0), +(1768,1767,1766,3,0), +(1769,1768,1766,4,0), +(1776,0,1776,1,0), +(1777,1776,1776,2,0), +(1784,0,1784,1,0), +(1785,1784,1784,2,0), +(1786,1785,1784,3,0), +(1787,1786,1784,4,0), +(1804,0,1804,1,0), +(1822,0,1822,1,0), +(1823,1822,1822,2,0), +(1824,1823,1822,3,0), +(1850,0,1850,1,0), +(1856,0,1856,1,0), +(1857,1856,1856,2,0), +(1943,0,1943,1,0), +(1949,0,1949,1,0), +(1966,0,1966,1,0), +(1978,0,1978,1,0), +(2006,0,2006,1,0), +(2008,0,2008,1,0), +(2010,2006,2006,2,0), +(2018,0,2018,1,0), +(2048,25289,6673,8,0), +(2050,0,2050,1,0), +(2052,2050,2050,2,0), +(2053,2052,2050,3,0), +(2054,0,2054,1,0), +(2055,2054,2054,2,0), +(2060,0,2060,1,0), +(2061,0,2061,1,0), +(2062,0,2062,1,0), +(2070,6770,6770,2,0), +(2090,1430,774,4,0), +(2091,2090,774,5,0), +(2096,0,2096,1,0), +(2098,0,2098,1,0), +(2108,0,2108,1,0), +(2120,0,2120,1,0), +(2121,2120,2120,2,0), +(2136,0,2136,1,0), +(2137,2136,2136,2,0), +(2138,2137,2136,3,0), +(2259,0,2259,1,0), +(2362,0,2362,1,0), +(2366,0,2366,1,0), +(2368,2366,2366,2,0), +(2550,0,2550,1,0), +(2575,0,2575,1,0), +(2576,2575,2575,2,0), +(2589,53,53,2,0), +(2590,2589,53,3,0), +(2591,2590,53,4,0), +(2637,0,2637,1,0), +(2643,0,2643,1,0), +(2649,0,2649,1,0), +(2651,0,2651,1,0), +(2652,0,2652,1,0), +(2767,992,589,5,0), +(2791,1245,1243,4,0), +(2800,633,633,2,0), +(2812,0,2812,1,0), +(2825,0,2825,1,0), +(2835,0,2835,1,0), +(2837,2835,2835,2,0), +(2860,930,421,3,0), +(2878,0,2878,1,0), +(2894,0,2894,1,0), +(2908,0,2908,1,0), +(2912,0,2912,1,0), +(2941,1094,348,4,0), +(2944,0,2944,1,0), +(2947,0,2947,1,0), +(2948,0,2948,1,0), +(2973,0,2973,1,0), +(2974,0,2974,1,0), +(2983,0,2983,1,0), +(3009,3010,16827,8,0), +(3010,16832,16827,7,0), +(3029,1082,1082,2,0), +(3034,0,3034,1,0), +(3044,0,3044,1,0), +(3100,2018,2018,2,0), +(3101,2259,2259,2,0), +(3102,2550,2550,2,0), +(3104,2108,2108,2,0), +(3110,0,3110,1,0), +(3111,136,136,2,0), +(3140,145,133,4,0), +(3273,0,3273,1,0), +(3274,3273,3273,2,0), +(3413,3102,2550,3,0), +(3420,0,3420,1,0), +(3421,3420,3420,2,0), +(3464,3101,2259,3,0), +(3472,1042,635,6,0), +(3538,3100,2018,3,0), +(3564,2576,2575,3,0), +(3570,2368,2366,3,0), +(3599,0,3599,1,0), +(3627,2091,774,6,0), +(3661,3111,136,3,0), +(3662,3661,136,4,0), +(3698,755,755,2,0), +(3699,3698,755,3,0), +(3700,3699,755,4,0), +(3716,0,3716,1,0), +(3738,0,3738,1,0), +(3747,600,17,4,0), +(3811,3104,2108,3,0), +(3908,0,3908,1,0), +(3909,3908,3908,2,0), +(3910,3909,3908,3,0), +(4036,0,4036,1,0), +(4037,4036,4036,2,0), +(4038,4037,4036,3,0), +(4187,0,4187,1,0), +(4188,4187,4187,2,0), +(4189,4188,4187,3,0), +(4190,4189,4187,4,0), +(4191,4190,4187,5,0), +(4192,4191,4187,6,0), +(4193,4192,4187,7,0), +(4194,4193,4187,8,0), +(5041,4194,4187,9,0), +(5042,5041,4187,10,0), +(5138,0,5138,1,0), +(5143,0,5143,1,0), +(5144,5143,5143,2,0), +(5145,5144,5143,3,0), +(5171,0,5171,1,0), +(5176,0,5176,1,0), +(5177,5176,5176,2,0), +(5178,5177,5176,3,0), +(5179,5178,5176,4,0), +(5180,5179,5176,5,0), +(5185,0,5185,1,0), +(5186,5185,5185,2,0), +(5187,5186,5185,3,0), +(5188,5187,5185,4,0), +(5189,5188,5185,5,0), +(5195,1062,339,3,0), +(5196,5195,339,4,0), +(5201,3029,1082,3,0), +(5211,0,5211,1,0), +(5215,0,5215,1,0), +(5217,0,5217,1,0), +(5221,0,5221,1,0), +(5232,1126,1126,2,0), +(5234,6756,1126,4,0), +(5242,6673,6673,2,0), +(5277,0,5277,1,0), +(5308,0,5308,1,0), +(5394,0,5394,1,0), +(5484,0,5484,1,0), +(5487,0,5487,1,0), +(5504,0,5504,1,0), +(5505,5504,5504,2,0), +(5506,5505,5504,3,0), +(5570,0,5570,1,0), +(5573,498,498,2,0), +(5588,853,853,2,0), +(5589,5588,853,3,0), +(5599,1022,1022,2,0), +(5614,879,879,2,0), +(5615,5614,879,3,0), +(5627,2878,2878,2,0), +(5675,0,5675,1,0), +(5676,0,5676,1,0), +(5699,6202,6201,3,0), +(5730,0,5730,1,0), +(5740,0,5740,1,0), +(5763,0,5763,1,0), +(5782,0,5782,1,0), +(5938,0,5938,1,0), +(6041,943,403,6,0), +(6060,1004,585,6,0), +(6063,2055,2054,3,0), +(6064,6063,2054,4,0), +(6065,3747,17,5,0), +(6066,6065,17,6,0), +(6074,139,139,2,0), +(6075,6074,139,3,0), +(6076,6075,139,4,0), +(6077,6076,139,5,0), +(6078,6077,139,6,0), +(6117,0,6117,1,0), +(6127,5506,5504,4,0), +(6129,990,587,4,0), +(6131,865,122,3,0), +(6141,10,10,2,0), +(6143,0,6143,1,0), +(6178,100,100,2,0), +(6190,1160,1160,2,0), +(6192,5242,6673,3,0), +(6201,0,6201,1,0), +(6202,6201,6201,2,0), +(6205,1108,702,3,0), +(6213,5782,5782,2,0), +(6215,6213,5782,3,0), +(6217,1014,980,3,0), +(6219,5740,5740,2,0), +(6222,172,172,2,0), +(6223,6222,172,3,0), +(6226,5138,5138,2,0), +(6229,0,6229,1,0), +(6307,0,6307,1,0), +(6343,0,6343,1,0), +(6353,0,6353,1,0), +(6360,0,6360,1,0), +(6363,3599,3599,2,0), +(6364,6363,3599,3,0), +(6365,6364,3599,4,0), +(6366,0,6366,1,0), +(6375,5394,5394,2,0), +(6377,6375,5394,3,0), +(6390,5730,5730,2,0), +(6391,6390,5730,3,0), +(6392,6391,5730,4,0), +(6542,0,6542,1,0), +(6546,772,772,2,0), +(6547,6546,772,3,0), +(6548,6547,772,4,0), +(6552,0,6552,1,0), +(6554,6552,6552,2,0), +(6572,0,6572,1,0), +(6574,6572,6572,2,0), +(6673,0,6673,1,0), +(6756,5232,1126,3,0), +(6760,2098,2098,2,0), +(6761,6760,2098,3,0), +(6762,6761,2098,4,0), +(6768,1966,1966,2,0), +(6770,0,6770,1,0), +(6774,5171,5171,2,0), +(6778,5189,5185,6,0), +(6780,5180,5176,6,0), +(6783,5215,5215,2,0), +(6785,0,6785,1,0), +(6787,6785,6785,2,0), +(6789,0,6789,1,0), +(6793,5217,5217,2,0), +(6798,5211,5211,2,0), +(6800,5221,5221,2,0), +(6807,0,6807,1,0), +(6808,6807,6807,2,0), +(6809,6808,6807,3,0), +(6940,0,6940,1,0), +(7128,588,588,2,0), +(7294,0,7294,1,0), +(7300,168,168,2,0), +(7301,7300,168,3,0), +(7302,0,7302,1,0), +(7320,7302,7302,2,0), +(7322,837,116,4,0), +(7328,0,7328,1,0), +(7369,845,845,2,0), +(7371,0,7371,1,0), +(7372,1715,1715,2,0), +(7373,7372,1715,3,0), +(7379,6574,6572,3,0), +(7384,0,7384,1,0), +(7386,0,7386,1,0), +(7400,694,694,2,0), +(7402,7400,694,3,0), +(7405,7386,7386,2,0), +(7411,0,7411,1,0), +(7412,7411,7411,2,0), +(7413,7412,7411,3,0), +(7620,0,7620,1,0), +(7641,1106,686,6,0), +(7646,6205,702,4,0), +(7648,6223,172,4,0), +(7651,709,689,4,0), +(7658,704,704,2,0), +(7659,7658,704,3,0), +(7731,7620,7620,2,0), +(7732,7731,7620,3,0), +(7799,3110,3110,2,0), +(7800,7799,3110,3,0), +(7801,7800,3110,4,0), +(7802,7801,3110,5,0), +(7804,6307,6307,2,0), +(7805,7804,6307,3,0), +(7809,3716,3716,2,0), +(7810,7809,3716,3,0), +(7811,7810,3716,4,0), +(7812,0,7812,1,0), +(7813,6360,6360,2,0), +(7814,0,7814,1,0), +(7815,7814,7814,2,0), +(7816,7815,7814,3,0), +(7887,7384,7384,2,0), +(7924,3274,3273,3,0), +(8004,0,8004,1,0), +(8005,959,331,7,0), +(8008,8004,8004,2,0), +(8010,8008,8004,3,0), +(8012,370,370,2,0), +(8017,0,8017,1,0), +(8018,8017,8017,2,0), +(8019,8018,8017,3,0), +(8024,0,8024,1,0), +(8027,8024,8024,2,0), +(8030,8027,8024,3,0), +(8033,0,8033,1,0), +(8038,8033,8033,2,0), +(8042,0,8042,1,0), +(8044,8042,8042,2,0), +(8045,8044,8042,3,0), +(8046,8045,8042,4,0), +(8050,0,8050,1,0), +(8052,8050,8050,2,0), +(8053,8052,8050,3,0), +(8056,0,8056,1,0), +(8058,8056,8056,2,0), +(8071,0,8071,1,0), +(8075,0,8075,1,0), +(8092,0,8092,1,0), +(8102,8092,8092,2,0), +(8103,8102,8092,3,0), +(8104,8103,8092,4,0), +(8105,8104,8092,5,0), +(8106,8105,8092,6,0), +(8122,0,8122,1,0), +(8124,8122,8122,2,0), +(8129,0,8129,1,0), +(8131,8129,8129,2,0), +(8134,945,324,5,0), +(8154,8071,8071,2,0), +(8155,8154,8071,3,0), +(8160,8075,8075,2,0), +(8161,8160,8075,3,0), +(8181,0,8181,1,0), +(8184,0,8184,1,0), +(8190,0,8190,1,0), +(8192,453,453,2,0), +(8198,6343,6343,2,0), +(8204,8198,6343,3,0), +(8205,8204,6343,4,0), +(8227,0,8227,1,0), +(8232,0,8232,1,0), +(8235,8232,8232,2,0), +(8249,8227,8227,2,0), +(8288,1120,1120,2,0), +(8289,8288,1120,3,0), +(8316,2947,2947,2,0), +(8317,8316,2947,3,0), +(8380,7405,7386,3,0), +(8400,3140,133,5,0), +(8401,8400,133,6,0), +(8402,8401,133,7,0), +(8406,7322,116,5,0), +(8407,8406,116,6,0), +(8408,8407,116,7,0), +(8412,2138,2136,4,0), +(8413,8412,2136,5,0), +(8416,5145,5143,4,0), +(8417,8416,5143,5,0), +(8422,2121,2120,3,0), +(8423,8422,2120,4,0), +(8427,6141,10,3,0), +(8437,1449,1449,2,0), +(8438,8437,1449,3,0), +(8439,8438,1449,4,0), +(8444,2948,2948,2,0), +(8445,8444,2948,3,0), +(8446,8445,2948,4,0), +(8450,604,604,2,0), +(8451,8450,604,3,0), +(8455,1008,1008,2,0), +(8457,543,543,2,0), +(8458,8457,543,3,0), +(8461,6143,6143,2,0), +(8462,8461,6143,3,0), +(8492,120,120,2,0), +(8494,1463,1463,2,0), +(8495,8494,1463,3,0), +(8498,1535,1535,2,0), +(8499,8498,1535,3,0), +(8512,0,8512,1,0), +(8613,0,8613,1,0), +(8617,8613,8613,2,0), +(8618,8617,8613,3,0), +(8621,1760,1752,6,0), +(8623,6762,2098,5,0), +(8624,8623,2098,6,0), +(8629,1777,1776,3,0), +(8631,703,703,2,0), +(8632,8631,703,3,0), +(8633,8632,703,4,0), +(8637,6768,1966,3,0), +(8639,1943,1943,2,0), +(8640,8639,1943,3,0), +(8643,408,408,2,0), +(8647,0,8647,1,0), +(8649,8647,8647,2,0), +(8650,8649,8647,3,0), +(8676,0,8676,1,0), +(8681,0,8681,1,0), +(8687,8681,8681,2,0), +(8691,8687,8681,3,0), +(8694,5763,5763,2,0), +(8696,2983,2983,2,0), +(8721,2591,53,5,0), +(8724,8676,8676,2,0), +(8725,8724,8676,3,0), +(8820,1464,1464,2,0), +(8835,0,8835,1,0), +(8903,6778,5185,7,0), +(8905,6780,5176,7,0), +(8907,5234,1126,5,0), +(8910,3627,774,7,0), +(8914,1075,467,4,0), +(8918,740,740,2,0), +(8921,0,8921,1,0), +(8924,8921,8921,2,0), +(8925,8924,8921,3,0), +(8926,8925,8921,4,0), +(8927,8926,8921,5,0), +(8928,8927,8921,6,0), +(8929,8928,8921,7,0), +(8936,0,8936,1,0), +(8938,8936,8936,2,0), +(8939,8938,8936,3,0), +(8940,8939,8936,4,0), +(8941,8940,8936,5,0), +(8949,2912,2912,2,0), +(8950,8949,2912,3,0), +(8951,8950,2912,4,0), +(8955,2908,2908,2,0), +(8972,6809,6807,4,0), +(8983,6798,5211,3,0), +(8992,6800,5221,3,0), +(8998,0,8998,1,0), +(9000,8998,8998,2,0), +(9005,0,9005,1,0), +(9035,0,9035,1,0), +(9472,2061,2061,2,0), +(9473,9472,2061,3,0), +(9474,9473,2061,4,0), +(9484,0,9484,1,0), +(9485,9484,9484,2,0), +(9490,1735,99,3,0), +(9492,1079,1079,2,0), +(9493,9492,1079,3,0), +(9578,586,586,2,0), +(9579,9578,586,3,0), +(9592,9579,586,4,0), +(9634,5487,5487,2,0), +(9745,8972,6807,5,0), +(9747,9490,99,4,0), +(9749,778,770,3,0), +(9750,8941,8936,6,0), +(9752,9493,1079,4,0), +(9754,769,779,4,0), +(9756,8914,467,5,0), +(9758,8903,5185,8,0), +(9785,3538,2018,4,0), +(9787,9785,2018,5,0), +(9788,9785,2018,5,0), +(9821,1850,1850,2,0), +(9823,9005,9005,2,0), +(9827,9823,9005,3,0), +(9829,8992,5221,4,0), +(9830,9829,5221,5,0), +(9833,8929,8921,8,0), +(9834,9833,8921,9,0), +(9835,9834,8921,10,0), +(9839,8910,774,8,0), +(9840,9839,774,9,0), +(9841,9840,774,10,0), +(9845,6793,5217,3,0), +(9846,9845,5217,4,0), +(9849,5201,1082,4,0), +(9850,9849,1082,5,0), +(9852,5196,339,5,0), +(9853,9852,339,6,0), +(9856,9750,8936,7,0), +(9857,9856,8936,8,0), +(9858,9857,8936,9,0), +(9862,8918,740,3,0), +(9863,9862,740,4,0), +(9866,6787,6785,3,0), +(9867,9866,6785,4,0), +(9875,8951,2912,5,0), +(9876,9875,2912,6,0), +(9880,9745,6807,6,0), +(9881,9880,6807,7,0), +(9884,8907,1126,6,0), +(9885,9884,1126,7,0), +(9888,9758,5185,9,0), +(9889,9888,5185,10,0), +(9892,9000,8998,3,0), +(9894,9752,1079,5,0), +(9896,9894,1079,6,0), +(9898,9747,99,5,0), +(9901,8955,2908,3,0), +(9904,1824,1822,4,0), +(9907,9749,770,4,0), +(9908,9754,779,5,0), +(9910,9756,467,6,0), +(9912,8905,5176,8,0), +(9913,6783,5215,3,0), +(10138,6127,5504,5,0), +(10139,10138,5504,6,0), +(10140,10139,5504,7,0), +(10144,6129,587,5,0), +(10145,10144,587,6,0), +(10148,8402,133,8,0), +(10149,10148,133,9,0), +(10150,10149,133,10,0), +(10151,10150,133,11,0), +(10156,1461,1459,4,0), +(10157,10156,1459,5,0), +(10159,8492,120,3,0), +(10160,10159,120,4,0), +(10161,10160,120,5,0), +(10169,8455,1008,3,0), +(10170,10169,1008,4,0), +(10173,8451,604,4,0), +(10174,10173,604,5,0), +(10177,8462,6143,4,0), +(10179,8408,116,8,0), +(10180,10179,116,9,0), +(10181,10180,116,10,0), +(10185,8427,10,4,0), +(10186,10185,10,5,0), +(10187,10186,10,6,0), +(10191,8495,1463,4,0), +(10192,10191,1463,5,0), +(10193,10192,1463,6,0), +(10197,8413,2136,6,0), +(10199,10197,2136,7,0), +(10201,8439,1449,5,0), +(10202,10201,1449,6,0), +(10205,8446,2948,5,0), +(10206,10205,2948,6,0), +(10207,10206,2948,7,0), +(10211,8417,5143,6,0), +(10212,10211,5143,7,0), +(10215,8423,2120,5,0), +(10216,10215,2120,6,0), +(10219,7320,7302,3,0), +(10220,10219,7302,4,0), +(10223,8458,543,4,0), +(10225,10223,543,5,0), +(10230,6131,122,4,0), +(10248,3564,2575,4,0), +(10278,5599,1022,3,0), +(10290,465,465,2,0), +(10291,643,465,4,0), +(10292,1032,465,6,0), +(10293,10292,465,7,0), +(10298,7294,7294,2,0), +(10299,10298,7294,3,0), +(10300,10299,7294,4,0), +(10301,10300,7294,5,0), +(10308,5589,853,4,0), +(10310,2800,633,3,0), +(10312,5615,879,4,0), +(10313,10312,879,5,0), +(10314,10313,879,6,0), +(10318,2812,2812,2,0), +(10322,7328,7328,2,0), +(10324,10322,7328,3,0), +(10326,5627,2878,3,0), +(10328,3472,635,7,0), +(10329,10328,635,8,0), +(10391,6041,403,7,0), +(10392,10391,403,8,0), +(10395,8005,331,8,0), +(10396,10395,331,9,0), +(10399,8019,8017,4,0), +(10406,8155,8071,4,0), +(10407,10406,8071,5,0), +(10408,10407,8071,6,0), +(10412,8046,8042,5,0), +(10413,10412,8042,6,0), +(10414,10413,8042,7,0), +(10427,6392,5730,5,0), +(10428,10427,5730,6,0), +(10431,8134,324,6,0), +(10432,10431,324,7,0), +(10437,6365,3599,5,0), +(10438,10437,3599,6,0), +(10442,8161,8075,4,0), +(10447,8053,8050,4,0), +(10448,10447,8050,5,0), +(10456,8038,8033,3,0), +(10462,6377,5394,4,0), +(10463,10462,5394,5,0), +(10466,8010,8004,4,0), +(10467,10466,8004,5,0), +(10468,10467,8004,6,0), +(10472,8058,8056,3,0), +(10473,10472,8056,4,0), +(10478,8181,8181,2,0), +(10479,10478,8181,3,0), +(10486,8235,8232,3,0), +(10495,5675,5675,2,0), +(10496,10495,5675,3,0), +(10497,10496,5675,4,0), +(10526,8249,8227,3,0), +(10537,8184,8184,2,0), +(10538,10537,8184,3,0), +(10585,8190,8190,2,0), +(10586,10585,8190,3,0), +(10587,10586,8190,4,0), +(10595,0,10595,1,0), +(10600,10595,10595,2,0), +(10601,10600,10595,3,0), +(10605,2860,421,4,0), +(10613,8512,8512,2,0), +(10614,10613,8512,3,0), +(10622,1064,1064,2,0), +(10623,10622,1064,3,0), +(10627,8835,8835,2,0), +(10656,10662,2108,5,0), +(10658,10662,2108,5,0), +(10660,10662,2108,5,0), +(10662,3811,2108,4,0), +(10768,8618,8613,4,0), +(10797,0,10797,1,0), +(10846,7924,3273,4,0), +(10874,8131,8129,3,0), +(10875,10874,8129,4,0), +(10876,10875,8129,5,0), +(10880,2010,2006,3,0), +(10881,10880,2006,4,0), +(10888,8124,8122,3,0), +(10890,10888,8122,4,0), +(10892,2767,589,6,0), +(10893,10892,589,7,0), +(10894,10893,589,8,0), +(10898,6066,17,7,0), +(10899,10898,17,8,0), +(10900,10899,17,9,0), +(10901,10900,17,10,0), +(10909,2096,2096,2,0), +(10911,605,605,2,0), +(10912,10911,605,3,0), +(10915,9474,2061,5,0), +(10916,10915,2061,6,0), +(10917,10916,2061,7,0), +(10927,6078,139,7,0), +(10928,10927,139,8,0), +(10929,10928,139,9,0), +(10933,6060,585,7,0), +(10934,10933,585,8,0), +(10937,2791,1243,5,0), +(10938,10937,1243,6,0), +(10941,9592,586,5,0), +(10942,10941,586,6,0), +(10945,8106,8092,7,0), +(10946,10945,8092,8,0), +(10947,10946,8092,9,0), +(10951,1006,588,5,0), +(10952,10951,588,6,0), +(10953,8192,453,3,0), +(10955,9485,9484,3,0), +(10957,976,976,2,0), +(10958,10957,976,3,0), +(10960,996,596,3,0), +(10961,10960,596,4,0), +(10963,2060,2060,2,0), +(10964,10963,2060,3,0), +(10965,10964,2060,4,0), +(11113,0,11113,1,0), +(11197,8650,8647,4,0), +(11198,11197,8647,5,0), +(11267,8725,8676,4,0), +(11268,11267,8676,5,0), +(11269,11268,8676,6,0), +(11273,8640,1943,4,0), +(11274,11273,1943,5,0), +(11275,11274,1943,6,0), +(11279,8721,53,6,0), +(11280,11279,53,7,0), +(11281,11280,53,8,0), +(11285,8629,1776,4,0), +(11286,11285,1776,5,0), +(11289,8633,703,5,0), +(11290,11289,703,6,0), +(11293,8621,1752,7,0), +(11294,11293,1752,8,0), +(11297,2070,6770,3,0), +(11299,8624,2098,7,0), +(11300,11299,2098,8,0), +(11303,8637,1966,4,0), +(11305,8696,2983,3,0), +(11314,8499,1535,4,0), +(11315,11314,1535,5,0), +(11341,8691,8681,4,0), +(11342,11341,8681,5,0), +(11343,11342,8681,6,0), +(11357,2837,2835,3,0), +(11358,11357,2835,4,0), +(11366,0,11366,1,0), +(11400,8694,5763,3,0), +(11426,0,11426,1,0), +(11549,6192,6673,4,0), +(11550,11549,6673,5,0), +(11551,11550,6673,6,0), +(11554,6190,1160,3,0), +(11555,11554,1160,4,0), +(11556,11555,1160,5,0), +(11564,1608,78,5,0), +(11565,11564,78,6,0), +(11566,11565,78,7,0), +(11567,11566,78,8,0), +(11572,6548,772,5,0), +(11573,11572,772,6,0), +(11574,11573,772,7,0), +(11578,6178,100,3,0), +(11580,8205,6343,5,0), +(11581,11580,6343,6,0), +(11584,7887,7384,3,0), +(11585,11584,7384,4,0), +(11596,8380,7386,4,0), +(11597,11596,7386,5,0), +(11600,7379,6572,4,0), +(11601,11600,6572,5,0), +(11604,8820,1464,3,0), +(11605,11604,1464,4,0), +(11608,7369,845,3,0), +(11609,11608,845,4,0), +(11611,3464,2259,4,0), +(11659,7641,686,7,0), +(11660,11659,686,8,0), +(11661,11660,686,9,0), +(11665,2941,348,5,0), +(11667,11665,348,6,0), +(11668,11667,348,7,0), +(11671,7648,172,5,0), +(11672,11671,172,6,0), +(11675,8289,1120,4,0), +(11677,6219,5740,3,0), +(11678,11677,5740,4,0), +(11683,1949,1949,2,0), +(11684,11683,1949,3,0), +(11687,1456,1454,4,0), +(11688,11687,1454,5,0), +(11689,11688,1454,6,0), +(11693,3700,755,5,0), +(11694,11693,755,6,0), +(11695,11694,755,7,0), +(11699,7651,689,5,0), +(11700,11699,689,6,0), +(11703,6226,5138,3,0), +(11704,11703,5138,4,0), +(11707,7646,702,5,0), +(11708,11707,702,6,0), +(11711,6217,980,4,0), +(11712,11711,980,5,0), +(11713,11712,980,6,0), +(11717,7659,704,4,0), +(11719,1714,1714,2,0), +(11721,1490,1490,2,0), +(11722,11721,1490,3,0), +(11725,1098,1098,2,0), +(11726,11725,1098,3,0), +(11729,5699,6201,4,0), +(11730,11729,6201,5,0), +(11733,1086,706,3,0), +(11734,11733,706,4,0), +(11735,11734,706,5,0), +(11739,6229,6229,2,0), +(11740,11739,6229,3,0), +(11762,7802,3110,6,0), +(11763,11762,3110,7,0), +(11766,7805,6307,4,0), +(11767,11766,6307,5,0), +(11770,8317,2947,4,0), +(11771,11770,2947,5,0), +(11774,7811,3716,5,0), +(11775,11774,3716,6,0), +(11778,7816,7814,4,0), +(11779,11778,7814,5,0), +(11780,11779,7814,6,0), +(11784,7813,6360,3,0), +(11785,11784,6360,4,0), +(11993,3570,2366,4,0), +(12180,3910,3908,4,0), +(12656,4038,4036,4,0), +(12294,0,12294,1,0), +(12505,11366,11366,2,0), +(12522,12505,11366,3,0), +(12523,12522,11366,4,0), +(12524,12523,11366,5,0), +(12525,12524,11366,6,0), +(12526,12525,11366,7,0), +(12824,118,118,2,0), +(12825,12824,118,3,0), +(12826,12825,118,4,0), +(13018,11113,11113,2,0), +(13019,13018,11113,3,0), +(13020,13019,11113,4,0), +(13021,13020,11113,5,0), +(13031,11426,11426,2,0), +(13032,13031,11426,3,0), +(13033,13032,11426,4,0), +(13165,0,13165,1,0), +(13220,0,13220,1,0), +(13228,13220,13220,2,0), +(13229,13228,13220,3,0), +(13230,13229,13220,4,0), +(13542,3662,136,5,0), +(13543,13542,136,6,0), +(13544,13543,136,7,0), +(13549,1978,1978,2,0), +(13550,13549,1978,3,0), +(13551,13550,1978,4,0), +(13552,13551,1978,5,0), +(13553,13552,1978,6,0), +(13554,13553,1978,7,0), +(13555,13554,1978,8,0), +(13795,0,13795,1,0), +(13813,0,13813,1,0), +(13896,0,13896,1,0), +(13908,0,13908,1,0), +(13920,7413,7411,4,0), +(14260,2973,2973,2,0), +(14261,14260,2973,3,0), +(14262,14261,2973,4,0), +(14263,14262,2973,5,0), +(14264,14263,2973,6,0), +(14265,14264,2973,7,0), +(14266,14265,2973,8,0), +(14267,2974,2974,2,0), +(14268,14267,2974,3,0), +(14269,1495,1495,2,0), +(14270,14269,1495,3,0), +(14271,14270,1495,4,0), +(14272,781,781,2,0), +(14273,14272,781,3,0), +(14274,20736,20736,2,0), +(14279,3034,3034,2,0), +(14280,14279,3034,3,0), +(14281,3044,3044,2,0), +(14282,14281,3044,3,0), +(14283,14282,3044,4,0), +(14284,14283,3044,5,0), +(14285,14284,3044,6,0), +(14286,14285,3044,7,0), +(14287,14286,3044,8,0), +(14288,2643,2643,2,0), +(14289,14288,2643,3,0), +(14290,14289,2643,4,0), +(14294,1510,1510,2,0), +(14295,14294,1510,3,0), +(14302,13795,13795,2,0), +(14303,14302,13795,3,0), +(14304,14303,13795,4,0), +(14305,14304,13795,5,0), +(14310,1499,1499,2,0), +(14311,14310,1499,3,0), +(14316,13813,13813,2,0), +(14317,14316,13813,3,0), +(14318,13165,13165,2,0), +(14319,14318,13165,3,0), +(14320,14319,13165,4,0), +(14321,14320,13165,5,0), +(14322,14321,13165,6,0), +(14323,1130,1130,2,0), +(14324,14323,1130,3,0), +(14325,14324,1130,4,0), +(14326,1513,1513,2,0), +(14327,14326,1513,3,0), +(14752,0,14752,1,0), +(14818,14752,14752,2,0), +(14819,14818,14752,3,0), +(14914,0,14914,1,0), +(14916,2649,2649,2,0), +(14917,14916,2649,3,0), +(14918,14917,2649,4,0), +(14919,14918,2649,5,0), +(14920,14919,2649,6,0), +(14921,14920,2649,7,0), +(15107,0,15107,1,0), +(15111,15107,15107,2,0), +(15112,15111,15107,3,0), +(15207,10392,403,9,0), +(15208,15207,403,10,0), +(15237,0,15237,1,0), +(15261,15267,14914,8,0), +(15262,14914,14914,2,0), +(15263,15262,14914,3,0), +(15264,15263,14914,4,0), +(15265,15264,14914,5,0), +(15266,15265,14914,6,0), +(15267,15266,14914,7,0), +(15407,0,15407,1,0), +(15430,15237,15237,2,0), +(15431,15430,15237,3,0), +(15629,14274,20736,3,0), +(15630,15629,20736,4,0), +(15631,15630,20736,5,0), +(15632,15631,20736,6,0), +(16314,10399,8017,5,0), +(16315,16314,8017,6,0), +(16316,16315,8017,7,0), +(16339,8030,8024,4,0), +(16341,16339,8024,5,0), +(16342,16341,8024,6,0), +(16355,10456,8033,4,0), +(16356,16355,8033,5,0), +(16362,10486,8232,4,0), +(16387,10526,8227,4,0), +(16511,0,16511,1,0), +(16689,0,16689,1,339), +(16697,1756,1742,6,0), +(16810,16689,16689,2,1062), +(16811,16810,16689,3,5195), +(16812,16811,16689,4,5196), +(16813,16812,16689,5,9852), +(16827,0,16827,1,0), +(16828,16827,16827,2,0), +(16829,16828,16827,3,0), +(16830,16829,16827,4,0), +(16831,16830,16827,5,0), +(16832,16831,16827,6,0), +(16857,0,16857,1,0), +(16914,0,16914,1,0), +(17039,9787,2018,6,0), +(17040,9787,2018,6,0), +(17041,9787,2018,6,0), +(17253,0,17253,1,0), +(17255,17253,17253,2,0), +(17256,17255,17253,3,0), +(17257,17256,17253,4,0), +(17258,17257,17253,5,0), +(17259,17258,17253,6,0), +(17260,17259,17253,7,0), +(17261,17260,17253,8,0), +(17311,15407,15407,2,0), +(17312,17311,15407,3,0), +(17313,17312,15407,4,0), +(17314,17313,15407,5,0), +(17329,16813,16689,6,9853), +(17347,16511,16511,2,0), +(17348,17347,16511,3,0), +(17390,16857,16857,2,0), +(17391,17390,16857,3,0), +(17392,17391,16857,4,0), +(17401,16914,16914,2,0), +(17402,17401,16914,3,0), +(17727,2362,2362,2,0), +(17728,17727,2362,3,0), +(17735,0,17735,1,0), +(17750,17735,17735,2,0), +(17751,17750,17735,3,0), +(17752,17751,17735,4,0), +(17767,0,17767,1,0), +(17850,17767,17767,2,0), +(17851,17850,17767,3,0), +(17852,17851,17767,4,0), +(17853,17852,17767,5,0), +(17854,17853,17767,6,0), +(17862,0,17862,1,0), +(17877,0,17877,1,0), +(17919,5676,5676,2,0), +(17920,17919,5676,3,0), +(17921,17920,5676,4,0), +(17922,17921,5676,5,0), +(17923,17922,5676,6,0), +(17924,6353,6353,2,0), +(17925,6789,6789,2,0), +(17926,17925,6789,3,0), +(17928,5484,5484,2,0), +(17937,17862,17862,2,0), +(17951,6366,6366,2,0), +(17952,17951,6366,3,0), +(17953,17952,6366,4,0), +(17962,0,17962,1,0), +(18137,0,18137,1,0), +(18220,0,18220,1,0), +(18248,7732,7620,4,0), +(18260,3413,2550,4,0), +(18265,0,18265,1,0), +(18647,710,710,2,0), +(18657,2637,2637,2,0), +(18658,18657,2637,3,0), +(18807,17314,15407,6,0), +(18809,12526,11366,8,0), +(18867,17877,17877,2,0), +(18868,18867,17877,3,0), +(18869,18868,17877,4,0), +(18870,18869,17877,5,0), +(18871,18870,17877,6,0), +(18879,18265,18265,2,0), +(18880,18879,18265,3,0), +(18881,18880,18265,4,0), +(18930,17962,17962,2,0), +(18931,18930,17962,3,0), +(18932,18931,17962,4,0), +(18937,18220,18220,2,0), +(18938,18937,18220,3,0), +(19236,13908,13908,2,0), +(19238,19236,13908,3,0), +(19240,19238,13908,4,0), +(19241,19240,13908,5,0), +(19242,19241,13908,6,0), +(19243,19242,13908,7,0), +(19261,2652,2652,2,0), +(19262,19261,2652,3,0), +(19264,19262,2652,4,0), +(19265,19264,2652,5,0), +(19266,19265,2652,6,0), +(19271,13896,13896,2,0), +(19273,19271,13896,3,0), +(19274,19273,13896,4,0), +(19275,19274,13896,5,0), +(19276,2944,2944,2,0), +(19277,19276,2944,3,0), +(19278,19277,2944,4,0), +(19279,19278,2944,5,0), +(19280,19279,2944,6,0), +(19281,9035,9035,2,0), +(19282,19281,9035,3,0), +(19283,19282,9035,4,0), +(19284,19283,9035,5,0), +(19285,19284,9035,6,0), +(19296,10797,10797,2,0), +(19299,19296,10797,3,0), +(19302,19299,10797,4,0), +(19303,19302,10797,5,0), +(19304,19303,10797,6,0), +(19305,19304,10797,7,0), +(19306,0,19306,1,0), +(19308,18137,18137,2,0), +(19309,19308,18137,3,0), +(19310,19309,18137,4,0), +(19311,19310,18137,5,0), +(19312,19311,18137,6,0), +(19386,0,19386,1,0), +(19434,0,19434,1,0), +(19438,7812,7812,2,0), +(19440,19438,7812,3,0), +(19441,19440,7812,4,0), +(19442,19441,7812,5,0), +(19443,19442,7812,6,0), +(19244,0,19244,1,0), +(19478,0,19478,1,0), +(19505,0,19505,1,0), +(19506,0,19506,1,0), +(19647,19244,19244,2,0), +(19655,19478,19478,2,0), +(19656,19655,19478,3,0), +(19660,19656,19478,4,0), +(19731,19505,19505,2,0), +(19734,19731,19505,3,0), +(19736,19734,19505,4,0), +(19740,0,19740,1,0), +(19742,0,19742,1,0), +(19750,0,19750,1,0), +(19834,19740,19740,2,0), +(19835,19834,19740,3,0), +(19836,19835,19740,4,0), +(19837,19836,19740,5,0), +(19838,19837,19740,6,0), +(19850,19742,19742,2,0), +(19852,19850,19742,3,0), +(19853,19852,19742,4,0), +(19854,19853,19742,5,0), +(19876,0,19876,1,0), +(19888,0,19888,1,0), +(19891,0,19891,1,0), +(19895,19876,19876,2,0), +(19896,19895,19876,3,0), +(19897,19888,19888,2,0), +(19898,19897,19888,3,0), +(19899,19891,19891,2,0), +(19900,19899,19891,3,0), +(19939,19750,19750,2,0), +(19940,19939,19750,3,0), +(19941,19940,19750,4,0), +(19942,19941,19750,5,0), +(19943,19942,19750,6,0), +(19977,0,19977,1,0), +(19978,19977,19977,2,0), +(19979,19978,19977,3,0), +(20043,0,20043,1,0), +(20116,26573,26573,2,0), +(20162,21082,21082,2,0), +(20164,0,20164,1,0), +(20165,0,20165,1,0), +(20166,0,20166,1,0), +(20190,20043,20043,2,0), +(20217,0,20217,1,0), +(20219,12656,4036,5,0), +(20222,12656,4036,5,0), +(20243,0,20243,1,0), +(20252,0,20252,1,0), +(20287,21084,21084,2,0), +(20288,20287,21084,3,0), +(20289,20288,21084,4,0), +(20290,20289,21084,5,0), +(20291,20290,21084,6,0), +(20292,20291,21084,7,0), +(20293,20292,21084,8,0), +(20305,20162,21082,3,0), +(20306,20305,21082,4,0), +(20307,20306,21082,5,0), +(20308,20307,21082,6,0), +(20347,20165,20165,2,0), +(20348,20347,20165,3,0), +(20349,20348,20165,4,0), +(20356,20166,20166,2,0), +(20357,20356,20166,3,0), +(20375,0,20375,1,0), +(20473,0,20473,1,0), +(20484,0,20484,1,0), +(20559,7402,694,4,0), +(20560,20559,694,5,0), +(20569,11609,845,5,0), +(20609,2008,2008,2,0), +(20610,20609,2008,3,0), +(20616,20252,20252,2,0), +(20617,20616,20252,3,0), +(20658,5308,5308,2,0), +(20660,20658,5308,3,0), +(20661,20660,5308,4,0), +(20662,20661,5308,5,0), +(20729,6940,6940,2,0), +(20736,0,20736,1,0), +(20739,20484,20484,2,0), +(20742,20739,20484,3,0), +(20747,20742,20484,4,0), +(20748,20747,20484,5,0), +(20752,693,693,2,0), +(20755,20752,693,3,0), +(20756,20755,693,4,0), +(20757,20756,693,5,0), +(20770,10881,2006,5,0), +(20772,10324,7328,4,0), +(20773,20772,7328,5,0), +(20776,20610,2008,4,0), +(20777,20776,2008,5,0), +(20900,19434,19434,2,0), +(20901,20900,19434,3,0), +(20902,20901,19434,4,0), +(20903,20902,19434,5,0), +(20904,20903,19434,6,0), +(20905,19506,19506,2,0), +(20906,20905,19506,3,0), +(20909,19306,19306,2,0), +(20910,20909,19306,3,0), +(20911,0,20911,1,0), +(20912,20911,20911,2,0), +(20913,20912,20911,3,0), +(20914,20913,20911,4,0), +(20915,20375,20375,2,0), +(20918,20915,20375,3,0), +(20919,20918,20375,4,0), +(20920,20919,20375,5,0), +(20922,20116,26573,3,0), +(20923,20922,26573,4,0), +(20924,20923,26573,5,0), +(20925,0,20925,1,0), +(20927,20925,20925,2,0), +(20928,20927,20925,3,0), +(20929,20473,20473,2,0), +(20930,20929,20473,3,0), +(21082,0,21082,1,0), +(21084,0,21084,1,0), +(21551,12294,12294,2,0), +(21552,21551,12294,3,0), +(21553,21552,12294,4,0), +(21562,0,21562,1,0), +(21564,21562,21562,2,0), +(21849,0,21849,1,0), +(21850,21849,21849,2,0), +(22568,0,22568,1,0), +(22782,6117,6117,2,0), +(22783,22782,6117,3,0), +(22827,22568,22568,2,0), +(22828,22827,22568,3,0), +(22829,22828,22568,4,0), +(22842,0,22842,1,0), +(22895,22842,22842,2,0), +(22896,22895,22842,3,0), +(23028,0,23028,1,0), +(23099,0,23099,1,0), +(23109,23099,23099,2,0), +(23110,23109,23099,3,0), +(23145,0,23145,1,0), +(23147,23145,23145,2,0), +(23148,23147,23145,3,0), +(23881,0,23881,1,0), +(23892,23881,23881,2,0), +(23893,23892,23881,3,0), +(23894,23893,23881,4,0), +(23922,0,23922,1,0), +(23923,23922,23922,2,0), +(23924,23923,23922,3,0), +(23925,23924,23922,4,0), +(23992,0,23992,1,0), +(24132,19386,19386,2,0), +(24133,24132,19386,3,0), +(24224,0,24224,1,0), +(24239,24274,24275,3,0), +(24248,31018,22568,6,0), +(24274,24275,24275,2,0), +(24275,0,24275,1,0), +(24398,0,24398,1,0), +(24423,0,24423,1,0), +(24439,23992,23992,2,0), +(24444,24439,23992,3,0), +(24445,24444,23992,4,0), +(24446,0,24446,1,0), +(24447,24446,24446,2,0), +(24448,24447,24446,3,0), +(24449,24448,24446,4,0), +(24450,0,24450,1,0), +(24452,24450,24450,2,0), +(24453,24452,24450,3,0), +(24488,0,24488,1,0), +(24492,0,24492,1,0), +(24493,0,24493,1,0), +(24497,24493,24493,2,0), +(24500,24497,24493,3,0), +(24501,24500,24493,4,0), +(24502,24492,24492,2,0), +(24503,24502,24492,3,0), +(24504,24503,24492,4,0), +(24505,24488,24488,2,0), +(24506,24505,24488,3,0), +(24507,24506,24488,4,0), +(24545,0,24545,1,0), +(24549,24545,24545,2,0), +(24550,24549,24545,3,0), +(24551,24550,24545,4,0), +(24552,24551,24545,5,0), +(24553,24552,24545,6,0), +(24554,24553,24545,7,0), +(24555,24554,24545,8,0), +(24577,24423,24423,2,0), +(24578,24577,24423,3,0), +(24579,24578,24423,4,0), +(24583,24640,24640,2,0), +(24586,24583,24640,3,0), +(24587,24586,24640,4,0), +(24597,24603,24604,4,0), +(24604,0,24604,1,0), +(24605,24604,24604,2,0), +(24603,24605,24604,3,0), +(24629,24555,24545,9,0), +(24630,24629,24545,10,0), +(24640,0,24640,1,0), +(24844,0,24844,1,0), +(24974,5570,5570,2,0), +(24975,24974,5570,3,0), +(24976,24975,5570,4,0), +(24977,24976,5570,5,0), +(25008,24844,24844,2,0), +(25009,25008,24844,3,0), +(25010,25009,24844,4,0), +(25011,25010,24844,5,0), +(25012,25011,24844,6,0), +(25076,0,25076,1,0), +(25202,11556,1160,6,0), +(25203,25202,1160,7,0), +(25208,11574,772,8,0), +(25210,25314,2060,6,0), +(25212,7373,1715,4,0), +(25213,25210,2060,7,0), +(25217,10901,17,11,0), +(25218,25217,17,12,0), +(25221,25315,139,11,0), +(25222,25221,139,12,0), +(25225,11597,7386,6,0), +(25229,0,25229,1,0), +(25230,25229,25229,2,0), +(25231,20569,845,6,0), +(25233,10917,2061,8,0), +(25234,20662,5308,6,0), +(25235,25233,2061,9,0), +(25236,25234,5308,7,0), +(25241,11605,1464,5,0), +(25242,25241,1464,6,0), +(25248,21553,12294,5,0), +(25251,23894,23881,5,0), +(25258,23925,23922,5,0), +(25264,11581,6343,7,0), +(25266,20560,694,6,0), +(25269,25288,6572,7,0), +(25272,20617,20252,4,0), +(25275,25272,20252,5,0), +(25286,11567,78,9,0), +(25288,11601,6572,6,0), +(25289,11551,6673,7,0), +(25290,19854,19742,6,0), +(25291,19838,19740,7,0), +(25292,10329,635,9,0), +(25294,14290,2643,5,0), +(25295,13555,1978,9,0), +(25296,14322,13165,7,0), +(25297,9889,5185,11,0), +(25298,9876,2912,7,0), +(25299,9841,774,11,0), +(25300,11281,53,9,0), +(25302,11303,1966,5,0), +(25304,10181,116,11,0), +(25306,10151,133,12,0), +(25307,11661,686,10,0), +(25308,25316,596,6,0), +(25309,11668,348,8,0), +(25311,11672,172,7,0), +(25312,27841,14752,5,0), +(25314,10965,2060,5,0), +(25315,10929,139,10,0), +(25316,10961,596,5,0), +(25331,27801,15237,7,0), +(25345,10212,5143,8,0), +(25347,11358,2835,5,0), +(25357,10396,331,10,0), +(25359,10627,8835,3,0), +(25361,10442,8075,5,0), +(25363,10934,585,9,0), +(25364,25363,585,10,0), +(25367,10894,589,9,0), +(25368,25367,589,10,0), +(25372,10947,8092,10,0), +(25375,25372,8092,11,0), +(25379,10876,8129,6,0), +(25380,25379,8129,7,0), +(25384,15261,14914,9,0), +(25387,18807,15407,7,0), +(25389,10938,1243,7,0), +(25391,25357,331,11,0), +(25396,25391,331,12,0), +(25420,10468,8004,7,0), +(25422,10623,1064,4,0), +(25423,25422,1064,5,0), +(25429,10942,586,7,0), +(25431,10952,588,7,0), +(25433,10958,976,4,0), +(25435,20770,2006,6,0), +(25437,19243,13908,8,0), +(25439,10605,421,5,0), +(25441,19275,13896,6,0), +(25442,25439,421,6,0), +(25446,19305,10797,8,0), +(25448,15208,403,11,0), +(25449,25448,403,12,0), +(25454,10414,8042,8,0), +(25457,29228,8050,7,0), +(25464,10473,8056,5,0), +(25467,19280,2944,7,0), +(25469,10432,324,8,0), +(25470,19285,9035,7,0), +(25472,25469,324,9,0), +(25477,19312,18137,7,0), +(25479,16316,8017,8,0), +(25485,25479,8017,9,0), +(25489,16342,8024,7,0), +(25500,16356,8033,6,0), +(25505,16362,8232,5,0), +(25508,10408,8071,7,0), +(25509,25508,8071,8,0), +(25525,10428,5730,7,0), +(25528,25361,8075,6,0), +(25533,10438,3599,7,0), +(25546,11315,1535,6,0), +(25547,25546,1535,7,0), +(25552,10587,8190,5,0), +(25557,16387,8227,5,0), +(25560,10479,8181,4,0), +(25563,10538,8184,4,0), +(25567,10463,5394,6,0), +(25570,10497,5675,5,0), +(25574,10601,10595,4,0), +(25577,15112,15107,4,0), +(25585,10614,8512,4,0), +(25587,25585,8512,5,0), +(25596,10953,453,4,0), +(25782,0,25782,1,19838), +(25890,0,25890,1,19979), +(25894,0,25894,1,19854), +(25895,0,25895,1,1038), +(25898,0,25898,1,20217), +(25899,0,25899,1,20914), +(25916,25782,25782,2,25291), +(25918,25894,25894,2,25290), +(26064,0,26064,1,0), +(26090,0,26090,1,0), +(26177,7371,7371,2,0), +(26178,26177,7371,3,0), +(26179,26178,7371,4,0), +(26187,26090,26090,2,0), +(26188,26187,26090,3,0), +(26201,26179,7371,5,0), +(26573,0,26573,1,0), +(26790,12180,3908,5,0), +(26797,12180,3908,5,0), +(26798,12180,3908,5,0), +(26801,12180,3908,5,0), +(26839,11290,703,7,0), +(26861,11294,1752,9,0), +(26862,26861,1752,10,0), +(26863,25300,53,10,0), +(26864,17348,16511,4,0), +(26865,31016,2098,10,0), +(26866,11198,8647,6,0), +(26867,11275,1943,7,0), +(26884,26839,703,8,0), +(26889,1857,1856,3,0), +(26892,11343,8681,7,0), +(26969,25347,2835,6,0), +(26978,25297,5185,12,0), +(26979,26978,5185,13,0), +(26980,9858,8936,10,0), +(26981,25299,774,12,0), +(26982,26981,774,13,0), +(26983,9863,740,5,0), +(26984,9912,5176,9,0), +(26985,26984,5176,10,0), +(26986,25298,2912,8,0), +(26987,9835,8921,11,0), +(26988,26987,8921,12,0), +(26989,9853,339,7,0), +(26990,9885,1126,8,0), +(26992,9910,467,7,0), +(26993,9907,770,5,0), +(26994,20748,20484,6,0), +(26995,9901,2908,4,0), +(26996,9881,6807,8,0), +(26997,9908,779,6,0), +(26998,9898,99,6,0), +(26999,22896,22842,4,0), +(27001,9830,5221,6,0), +(27002,27001,5221,7,0), +(27003,9904,1822,5,0), +(27005,9867,6785,5,0), +(27006,9827,9005,4,0), +(27008,9896,1079,7,0), +(27009,17329,16689,7,26989), +(27011,17392,16857,5,0), +(27012,17402,16914,4,0), +(27013,24977,5570,6,0), +(27014,14266,2973,9,0), +(27015,14273,781,4,0), +(27016,25295,1978,10,0), +(27018,14280,3034,4,0), +(27019,14287,3044,9,0), +(27020,15632,20736,7,0), +(27021,25294,2643,6,0), +(27022,14295,1510,4,0), +(27023,14305,13795,6,0), +(27025,14317,13813,4,0), +(27028,10846,3273,5,0), +(27044,25296,13165,8,0), +(27045,20190,20043,3,0), +(27046,13544,136,8,0), +(27047,14921,2649,8,0), +(27048,16697,1742,7,0), +(27049,3009,16827,9,0), +(27050,17261,17253,9,0), +(27051,24579,24423,5,0), +(27052,24501,24493,5,0), +(27053,24445,23992,5,0), +(27054,24449,24446,5,0), +(27055,24504,24492,5,0), +(27056,24507,24488,5,0), +(27060,24587,24640,5,0), +(27061,24630,24545,11,0), +(27062,5042,4187,11,0), +(27063,26188,26090,4,0), +(27065,20904,19434,7,0), +(27066,20906,19506,4,0), +(27067,20910,19306,4,0), +(27068,24133,19386,4,0), +(27070,25306,133,13,0), +(27071,25304,116,12,0), +(27072,27071,116,13,0), +(27073,10207,2948,8,0), +(27074,27073,2948,9,0), +(27075,25345,5143,9,0), +(27078,10199,2136,8,0), +(27079,27078,2136,9,0), +(27080,10202,1449,7,0), +(27082,27080,1449,8,0), +(27085,10187,10,7,0), +(27086,10216,2120,7,0), +(27087,10161,120,6,0), +(27088,10230,122,5,0), +(27090,37420,5504,9,0), +(27124,10220,7302,5,0), +(27125,22783,6117,4,0), +(27126,10157,1459,6,0), +(27128,10225,543,6,0), +(27130,10170,1008,5,0), +(27131,10193,1463,7,0), +(27132,18809,11366,9,0), +(27133,13021,11113,6,0), +(27134,13033,11426,5,0), +(27135,25292,635,10,0), +(27136,27135,635,11,0), +(27137,19943,19750,7,0), +(27138,10314,879,7,0), +(27139,10318,2812,3,0), +(27140,25291,19740,8,0), +(27141,25916,25782,3,27140), +(27142,25290,19742,7,0), +(27143,25918,25894,3,27142), +(27144,19979,19977,4,0), +(27145,25890,25890,2,27144), +(27147,20729,6940,3,0), +(27148,27147,6940,4,0), +(27149,10293,465,8,0), +(27150,10301,7294,6,0), +(27151,19896,19876,4,0), +(27152,19898,19888,4,0), +(27153,19900,19891,4,0), +(27154,10310,633,4,0), +(27155,20293,21084,9,0), +(27158,20308,21082,7,0), +(27166,20357,20166,4,0), +(27168,20914,20911,5,0), +(27169,25899,25899,2,27168), +(27170,20920,20375,6,0), +(27173,20924,26573,6,0), +(27174,20930,20473,4,0), +(27179,20928,20925,4,0), +(27180,24239,24275,4,0), +(27209,25307,686,11,0), +(27210,17923,5676,7,0), +(27211,17924,6353,3,0), +(27212,11678,5740,5,0), +(27213,11684,1949,4,0), +(27215,25309,348,9,0), +(27216,25311,172,8,0), +(27217,11675,1120,5,0), +(27218,11713,980,7,0), +(27219,11700,689,7,0), +(27220,27219,689,8,0), +(27221,11704,5138,5,0), +(27222,11689,1454,7,0), +(27223,17926,6789,4,0), +(27224,11708,702,7,0), +(27226,11717,704,5,0), +(27228,11722,1490,4,0), +(27229,17937,17862,3,0), +(27230,11730,6201,6,0), +(27238,20757,693,6,0), +(27250,17953,6366,5,0), +(27259,11695,755,8,0), +(27260,11735,706,6,0), +(27263,18871,17877,7,0), +(27264,18881,18265,5,0), +(27265,18938,18220,4,0), +(27266,18932,17962,5,0), +(27267,11763,3110,8,0), +(27268,11767,6307,6,0), +(27269,11771,2947,6,0), +(27270,11775,3716,7,0), +(27271,17752,17735,5,0), +(27272,17854,17767,7,0), +(27273,19443,7812,7,0), +(27274,11780,7814,7,0), +(27275,11785,6360,5,0), +(27276,19736,19505,5,0), +(27277,27276,19505,6,0), +(27280,19660,19478,5,0), +(27282,26969,2835,7,0), +(27283,13230,13220,5,0), +(27441,11269,8676,7,0), +(27448,25302,1966,6,0), +(27681,14752,14752,2,0), +(27683,0,27683,1,0), +(27685,26201,7371,6,0), +(27799,15431,15237,4,0), +(27800,27799,15237,5,0), +(27801,27800,15237,6,0), +(27841,14819,14752,4,0), +(27870,724,724,2,0), +(27871,27870,724,3,0), +(28029,13920,7411,5,0), +(28172,17728,2362,4,0), +(28176,0,28176,1,0), +(28189,28176,28176,2,0), +(28275,27871,724,4,0), +(28596,11611,2259,5,0), +(28609,10177,6143,5,0), +(28610,11740,6229,4,0), +(28612,10145,587,7,0), +(28672,11611,2259,5,0), +(28675,11611,2259,5,0), +(28677,11611,2259,5,0), +(28695,11993,2366,5,0), +(28894,25230,25229,3,0), +(28895,28894,25229,4,0), +(28897,28895,25229,5,0), +(29228,10448,8050,6,0), +(29354,10248,2575,5,0), +(29704,1672,72,4,0), +(29707,25286,78,10,0), +(29722,0,29722,1,0), +(29801,0,29801,1,0), +(29844,9785,2018,5,0), +(30016,20243,20243,2,0), +(30022,30016,20243,3,0), +(30030,29801,29801,2,0), +(30033,30030,29801,3,0), +(30108,0,30108,1,0), +(30151,0,30151,1,0), +(30194,30151,30151,2,0), +(30198,30194,30151,3,0), +(30213,0,30213,1,0), +(30219,30213,30213,2,0), +(30223,30219,30213,3,0), +(30283,0,30283,1,0), +(30324,29707,78,11,0), +(30330,25248,12294,6,0), +(30335,25251,23881,6,0), +(30350,12656,4036,5,0), +(30356,25258,23922,6,0), +(30357,25269,6572,8,0), +(30404,30108,30108,2,0), +(30405,30404,30108,3,0), +(30413,30283,30283,2,0), +(30414,30413,30283,3,0), +(30459,27210,5676,8,0), +(30545,27211,6353,4,0), +(30546,27263,17877,8,0), +(30908,27221,5138,6,0), +(30909,27224,702,8,0), +(30910,603,603,2,0), +(30911,27264,18265,6,0), +(30912,27266,17962,6,0), +(31016,11300,2098,9,0), +(31018,22829,22568,5,0), +(31661,0,31661,1,0), +(31785,0,31785,1,0), +(31895,20164,20164,2,0), +(31935,0,31935,1,0), +(32231,29722,29722,2,0), +(32379,0,32379,1,0), +(32549,10662,2108,5,0), +(32593,974,974,2,0), +(32594,32593,974,3,0), +(32645,0,32645,1,0), +(32678,10768,8613,5,0), +(32684,32645,32645,2,0), +(32699,31935,31935,2,0), +(32700,32699,31935,3,0), +(32796,28609,6143,6,0), +(32996,32379,32379,2,0), +(32999,27681,14752,3,0), +(33041,31661,31661,2,0), +(33042,33041,31661,3,0), +(33043,33042,31661,4,0), +(33072,27174,20473,5,0), +(33095,18248,7620,5,0), +(33142,0,33142,1,0), +(33145,33142,33142,2,0), +(33146,33145,33142,3,0), +(33359,18260,2550,5,0), +(33388,0,33388,1,0), +(33391,33388,33388,2,0), +(33405,27134,11426,6,0), +(33698,0,33698,1,0), +(33699,33698,33698,2,0), +(33700,33699,33698,3,0), +(33701,27271,17735,6,0), +(33717,28612,587,8,0), +(33736,24398,24398,2,0), +(33776,31785,31785,2,0), +(33876,0,33876,1,0), +(33878,0,33878,1,0), +(33933,27133,11113,7,0), +(33938,27132,11366,10,0), +(33943,0,33943,1,0), +(33944,10174,604,6,0), +(33946,27130,1008,6,0), +(33982,33876,33876,2,0), +(33983,33982,33876,3,0), +(33986,33878,33878,2,0), +(33987,33986,33878,3,0), +(34411,1329,1329,2,0), +(34412,34411,1329,3,0), +(34413,34412,1329,4,0), +(34506,0,34506,1,0), +(34507,34506,34506,2,0), +(34508,34507,34506,3,0), +(34838,34508,34506,4,0), +(34839,34838,34506,5,0), +(34861,0,34861,1,0), +(34863,34861,34861,2,0), +(34864,34863,34861,3,0), +(34865,34864,34861,4,0), +(34866,34865,34861,5,0), +(34889,0,34889,1,0), +(34914,0,34914,1,0), +(34916,34914,34914,2,0), +(34917,34916,34914,3,0), +(34950,0,34950,1,0), +(34954,34950,34950,2,0), +(35323,34889,34889,2,0), +(35290,0,35290,1,0), +(35291,35290,35290,2,0), +(35292,35291,35290,3,0), +(35293,35292,35290,4,0), +(35294,35293,35290,5,0), +(35295,35294,35290,6,0), +(35296,35295,35290,7,0), +(35297,35296,35290,8,0), +(35298,35297,35290,9,0), +(35387,0,35387,1,0), +(35389,35387,35387,2,0), +(35392,35389,35387,3,0), +(35346,0,35346,1,0), +(35694,0,35694,1,0), +(35698,35694,35694,2,0), +(36916,14271,1495,5,0), +(37420,10140,5504,8,0), +(38692,27070,133,14,0), +(38697,27072,116,14,0), +(38699,27075,5143,10,0), +(38704,38699,5143,11,0), +(38764,11286,1776,6,0), +(38768,1769,1766,5,0), +(40120,33943,33943,2,0); +/*!40000 ALTER TABLE `spell_chain` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_elixir` +-- + +DROP TABLE IF EXISTS `spell_elixir`; +CREATE TABLE `spell_elixir` ( + `entry` int(11) unsigned NOT NULL default '0' COMMENT 'SpellId of potion', + `mask` tinyint(1) unsigned NOT NULL default '0' COMMENT 'Mask 0x1 battle 0x2 guardian 0x3 flask 0x7 unstable flasks 0xB shattrath flasks', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System'; + +-- +-- Dumping data for table `spell_elixir` +-- + +LOCK TABLES `spell_elixir` WRITE; +/*!40000 ALTER TABLE `spell_elixir` DISABLE KEYS */; +INSERT INTO `spell_elixir` VALUES +( 673,0x2), +( 2367,0x1), +( 2374,0x1), +( 2378,0x2), +( 2380,0x2), +( 3160,0x1), +( 3164,0x1), +( 3166,0x2), +( 3219,0x2), +( 3220,0x2), +( 3222,0x2), +( 3223,0x2), +( 3593,0x2), +( 7844,0x1), +( 8212,0x1), +(10667,0x1), +(10668,0x2), +(10669,0x1), +(10692,0x2), +(10693,0x2), +(11319,0x2), +(11328,0x1), +(11334,0x1), +(11348,0x2), +(11349,0x2), +(11364,0x2), +(11371,0x2), +(11390,0x1), +(11396,0x2), +(11405,0x1), +(11406,0x1), +(11474,0x1), +(15231,0x2), +(15233,0x2), +(16321,0x2), +(16322,0x1), +(16323,0x1), +(16325,0x2), +(16326,0x2), +(16327,0x2), +(16329,0x1), +(17038,0x1), +(17535,0x2), +(17537,0x1), +(17538,0x1), +(17539,0x1), +(17624,0x3), +(17626,0x3), +(17627,0x3), +(17629,0x3), +(17628,0x3), +(21920,0x1), +(24361,0x2), +(24363,0x2), +(24382,0x2), +(24383,0x2), +(24417,0x2), +(26276,0x1), +(27652,0x2), +(27653,0x2), +(28486,0x1), +(28488,0x1), +(28490,0x1), +(28491,0x1), +(28493,0x1), +(28497,0x1), +(28501,0x1), +(28502,0x2), +(28503,0x1), +(28509,0x2), +(28514,0x2), +(28518,0x3), +(28519,0x3), +(28520,0x3), +(28521,0x3), +(28540,0x3), +(29348,0x2), +(33720,0x1), +(33721,0x1), +(33726,0x1), +(38954,0x1), +(39625,0x2), +(39626,0x2), +(39627,0x2), +(39628,0x2), +(40567,0x7), +(40568,0x7), +(40572,0x7), +(40573,0x7), +(40575,0x7), +(40576,0x7), +(41608,0xB), +(41609,0xB), +(41610,0xB), +(41611,0xB), +(42735,0x3), +(46837,0xB), +(46839,0xB); +/*!40000 ALTER TABLE `spell_elixir` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_learn_spell` +-- + +DROP TABLE IF EXISTS `spell_learn_spell`; +CREATE TABLE `spell_learn_spell` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `SpellID` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`SpellID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +-- +-- Dumping data for table `spell_learn_spell` +-- + +LOCK TABLES `spell_learn_spell` WRITE; +/*!40000 ALTER TABLE `spell_learn_spell` DISABLE KEYS */; +INSERT INTO `spell_learn_spell` VALUES +(2842,8681), +(5784,33388), +(13819,33388), +(17002,24867), +(23161,33391), +(23214,33391), +(24866,24864), +(33872,47179), +(33873,47180), +(33943,34090), +(34767,33391), +(34769,33388); + +/*!40000 ALTER TABLE `spell_learn_spell` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_pet_auras` +-- + +DROP TABLE IF EXISTS `spell_pet_auras`; +CREATE TABLE `spell_pet_auras` ( + `spell` mediumint(8) unsigned NOT NULL COMMENT 'dummy spell id', + `pet` mediumint(8) unsigned NOT NULL default '0' COMMENT 'pet id; 0 = all', + `aura` mediumint(8) unsigned NOT NULL COMMENT 'pet aura id', + PRIMARY KEY (`spell`,`pet`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `spell_pet_auras` +-- + +LOCK TABLES `spell_pet_auras` WRITE; +/*!40000 ALTER TABLE `spell_pet_auras` DISABLE KEYS */; +INSERT INTO `spell_pet_auras` VALUES +(19028, 0, 25228), +(19578, 0, 19579), +(20895, 0, 24529), +(28757, 0, 28758), +(35029, 0, 35060), +(35030, 0, 35061), +(35691, 0, 35696), +(35692, 0, 35696), +(35693, 0, 35696), +(23785, 416, 23759), +(23822, 416, 23826), +(23823, 416, 23827), +(23824, 416, 23828), +(23825, 416, 23829), +(23785, 417, 23762), +(23822, 417, 23837), +(23823, 417, 23838), +(23824, 417, 23839), +(23825, 417, 23840), +(23785, 1860, 23760), +(23822, 1860, 23841), +(23823, 1860, 23842), +(23824, 1860, 23843), +(23825, 1860, 23844), +(23785, 1863, 23761), +(23822, 1863, 23833), +(23823, 1863, 23834), +(23824, 1863, 23835), +(23825, 1863, 23836), +(23785, 17252, 35702), +(23822, 17252, 35703), +(23823, 17252, 35704), +(23824, 17252, 35705), +(23825, 17252, 35706); + +/*!40000 ALTER TABLE `spell_pet_auras` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_proc_event` +-- + +DROP TABLE IF EXISTS `spell_proc_event`; +CREATE TABLE `spell_proc_event` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `SchoolMask` tinyint(4) NOT NULL default '0', + `Category` smallint(6) NOT NULL default '0', + `SkillID` smallint(6) NOT NULL default '0', + `SpellFamilyName` smallint(5) unsigned NOT NULL default '0', + `SpellFamilyMask` bigint(20) unsigned NOT NULL default '0', + `procFlags` int(10) unsigned NOT NULL default '0', + `ppmRate` float NOT NULL default '0', + `cooldown` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `spell_proc_event` +-- + +LOCK TABLES `spell_proc_event` WRITE; +/*!40000 ALTER TABLE `spell_proc_event` DISABLE KEYS */; +INSERT INTO `spell_proc_event` VALUES +(168,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(324,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(325,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(588,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(602,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(742,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(905,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(945,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(974,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(1006,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(1120,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(2565,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(2652,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3235,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3284,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3338,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3394,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3417,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3418,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3424,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3436,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3439,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(3440,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3509,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3512,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3582,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3616,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(3637,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4070,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4112,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4113,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4114,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4115,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4133,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4136,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4138,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4140,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4142,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(4144,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4241,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4242,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4245,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4279,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4283,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4284,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4315,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4317,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4493,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(4525,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4932,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(4951,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(5104,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(5118,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(5202,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(5205,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(5262,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(5301,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(5364,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(5368,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(5369,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(5370,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(5377,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(5427,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(5680,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(5728,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(5811,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(6268,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6397,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(6398,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(6399,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(6433,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(6645,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6750,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6752,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6866,0,0,0,0,0x0000000000000000,0x00000072,0,0), +(6867,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6870,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(6871,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6909,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6921,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6923,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6947,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(6961,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7095,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7098,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7102,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7103,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7128,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(7131,0,0,0,0,0x0000000000000000,0x000A22A8,0,0), +(7137,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7276,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7300,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7301,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7302,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7320,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7445,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7446,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7486,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7617,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(7619,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(7711,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7721,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7722,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7723,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7724,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7725,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7726,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7806,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7807,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7808,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(7849,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(7999,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(8134,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(8224,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(8247,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(8260,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(8288,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(8289,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(8397,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(8601,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(8612,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(8788,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(8852,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(8876,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(8981,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(9084,0,0,0,0,0x0000000000000000,0x00000008,0,0), +(9160,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(9233,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(9276,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(9452,0,0,0,0,0x0000000000000000,0x00000014,3,0), +(9460,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(9463,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(9778,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(9782,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(9784,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(9799,0,0,0,0,0x0000000000000000,0x00040000,0,0), +(10022,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(10092,0,0,0,0,0x0000000000000000,0x00000080,0,0), +(10219,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(10220,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(10425,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(10426,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(10431,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(10432,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(10951,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(10952,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(11103,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(11119,4,0,0,0,0x0000000000000000,0x00010000,0,0), +(11120,4,0,0,0,0x0000000000000000,0x00010000,0,0), +(11129,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(11180,16,0,0,0,0x0000000000000000,0x00020000,0,0), +(11185,0,0,0,3,0x0000000000000080,0x00020000,0,0), +(11213,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(11255,0,0,0,3,0x0000000000004000,0x00004000,0,0), +(11371,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(11441,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(11675,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(11919,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(11959,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(11964,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(11984,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12099,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12169,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12246,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(12254,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12281,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12284,0,0,0,0,0x0000000000000000,0x00000001,0.33252,0), +(12289,0,0,26,0,0x0000000000000002,0x00020000,0,0), +(12292,0,0,0,0,0x0000000000000000,0x00000080,0,0), +(12298,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12311,0,0,0,4,0x0000000000000800,0x00020000,0,0), +(12317,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(12319,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12322,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(12328,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(12357,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(12358,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(12359,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(12360,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(12487,0,0,0,3,0x0000000000000080,0x00020000,0,0), +(12488,0,0,0,3,0x0000000000000080,0x00020000,0,0), +(12529,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(12539,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12544,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(12550,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(12556,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(12574,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(12575,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(12576,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(12577,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(12598,0,0,0,3,0x0000000000004000,0x00004000,0,0), +(12668,0,0,26,0,0x0000000000000002,0x00020000,0,0), +(12701,0,0,0,0,0x0000000000000000,0x00000001,0.66504,0), +(12702,0,0,0,0,0x0000000000000000,0x00000001,0.99756,0), +(12703,0,0,0,0,0x0000000000000000,0x00000001,1.33008,0), +(12704,0,0,0,0,0x0000000000000000,0x00000001,1.6626,0), +(12724,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12725,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12726,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12727,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12782,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(12787,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12797,0,0,0,0,0x0000000000000400,0x00020000,0,0), +(12799,0,0,0,0,0x0000000000000400,0x00020000,0,0), +(12800,0,0,0,0,0x0000000000000400,0x00020000,0,0), +(12812,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12813,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12814,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12815,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12834,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12846,4,0,0,0,0x0000000000000000,0x00010000,0,0), +(12847,4,0,0,0,0x0000000000000000,0x00010000,0,0), +(12848,4,0,0,0,0x0000000000000000,0x00010000,0,0), +(12849,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12867,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12947,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(12958,0,0,0,4,0x0000000000000800,0x00020000,0,0), +(12966,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(12967,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(12968,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(12969,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(12970,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(12971,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12972,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12973,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12974,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(12999,0,0,0,0,0x0000000000000000,0x00000001,4,0), +(13000,0,0,0,0,0x0000000000000000,0x00000001,6,0), +(13001,0,0,0,0,0x0000000000000000,0x00000001,8,0), +(13002,0,0,0,0,0x0000000000000000,0x00000001,10,0), +(13045,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(13046,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(13047,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(13048,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(13159,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(13165,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(13299,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13358,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(13585,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(13616,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13709,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13716,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(13754,0,0,0,0,0x0000000000000010,0x00020000,0,0), +(13800,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13801,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13802,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13803,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13867,0,0,0,0,0x0000000000000010,0x00020000,0,0), +(13877,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(13879,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(13886,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13896,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(13959,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(13960,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13961,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13962,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13963,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13964,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(13983,0,0,0,0,0x0000000000000000,0x01000010,0,0), +(14070,0,0,0,0,0x0000000000000000,0x01000010,0,0), +(14071,0,0,0,0,0x0000000000000000,0x01000010,0,0), +(14108,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(14111,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(14133,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(14144,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(14148,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(14156,0,0,0,0,0x00000000003E0000,0x00020000,0,0), +(14160,0,0,0,0,0x00000000003E0000,0x00020000,0,0), +(14161,0,0,0,0,0x00000000003E0000,0x00020000,0,0), +(14178,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(14186,0,0,0,8,0x0000000040800508,0x00010000,0,0), +(14190,0,0,0,8,0x0000000040800508,0x00010000,0,0), +(14193,0,0,0,8,0x0000000040800508,0x00010000,0,0), +(14194,0,0,0,8,0x0000000040800508,0x00010000,0,0), +(14195,0,0,0,8,0x0000000040800508,0x00010000,0,0), +(14318,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(14319,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(14320,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(14321,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(14322,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(14531,0,0,0,0,0x0000000000000000,0x00002000,0,0), +(14774,0,0,0,0,0x0000000000000000,0x00002000,0,0), +(14796,0,0,0,0,0x0000000000000000,0x00000800,0,0), +(14869,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(14892,0,0,0,6,0x0000000410001E00,0x10000000,0,0), +(15088,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(15097,0,0,0,0,0x0000000000000000,0x00002000,0,0), +(15268,32,0,0,0,0x0000000000000000,0x00020000,0,0), +(15270,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(15277,0,0,0,0,0x0000000000000000,0x00000001,6,0), +(15286,32,0,0,0,0x0000000000000000,0x00008000,0,0), +(15323,32,0,0,0,0x0000000000000000,0x00020000,0,0), +(15324,32,0,0,0,0x0000000000000000,0x00020000,0,0), +(15325,32,0,0,0,0x0000000000000000,0x00020000,0,0), +(15326,32,0,0,0,0x0000000000000000,0x00020000,0,0), +(15335,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(15336,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(15337,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(15338,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(15346,0,0,0,0,0x0000000000000000,0x00000001,6,0), +(15362,0,0,0,6,0x0000000410001E00,0x10000000,0,0), +(15363,0,0,0,6,0x0000000410001E00,0x10000000,0,0), +(15506,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15507,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(15573,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15594,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(15599,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15600,0,0,0,0,0x0000000000000000,0x00000001,0.6,0), +(15603,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(15636,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15641,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15730,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15733,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15784,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(15849,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15852,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(15876,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(15978,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16092,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(16142,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16146,0,0,0,0,0x0000000000000000,0x00000800,0,0), +(16164,28,0,0,0,0x0000000000000000,0x00010000,0,0), +(16176,0,0,0,0,0x0000000000000000,0x10000000,0,0), +(16235,0,0,0,0,0x0000000000000000,0x10000000,0,0), +(16240,0,0,0,0,0x0000000000000000,0x10000000,0,0), +(16247,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16256,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(16257,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(16277,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(16278,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(16279,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(16280,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(16281,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(16282,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(16283,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(16284,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(16428,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16487,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(16489,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(16492,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(16550,0,0,0,0,0x0000000000000000,0x00002000,0,0), +(16574,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16575,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16611,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(16615,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16620,0,0,0,0,0x0000000000000000,0x00100402,0,30), +(16624,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(16689,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(16792,0,0,0,0,0x0000000000000000,0x00002000,0,0), +(16800,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16810,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(16811,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(16812,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(16813,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(16843,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(16850,0,0,0,0,0x0000000000000004,0x00020000,0,0), +(16864,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(16880,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(16923,0,0,0,0,0x0000000000000004,0x00020000,0,0), +(16924,0,0,0,0,0x0000000000000004,0x00020000,0,0), +(16952,0,0,0,0,0x0000040000039000,0x00010000,0,0), +(16954,0,0,0,0,0x0000040000039000,0x00010000,0,0), +(16958,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(16961,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(16982,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(17010,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(17106,0,0,0,7,0x0000000000080000,0x00004000,0,0), +(17107,0,0,0,7,0x0000000000080000,0x00004000,0,0), +(17108,0,0,0,7,0x0000000000080000,0x00004000,0,0), +(17329,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(17332,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(17350,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(17364,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(17495,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(17670,0,0,0,0,0x0000000000000000,0x00000008,0,0), +(17687,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(17688,0,0,0,0,0x0000000000000000,0x00000080,0,0), +(17690,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(17793,0,0,0,5,0x0000000000000001,0x00010000,0,0), +(17794,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(17796,0,0,0,5,0x0000000000000001,0x00010000,0,0), +(17797,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(17798,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(17799,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(17800,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(17801,0,0,0,5,0x0000000000000001,0x00010000,0,0), +(17802,0,0,0,5,0x0000000000000001,0x00010000,0,0), +(17803,0,0,0,5,0x0000000000000001,0x00010000,0,0), +(18073,0,0,0,0,0x0000008000000060,0x00020000,0,0), +(18094,0,0,0,5,0x000000000000000A,0x00020000,0,0), +(18095,0,0,0,5,0x000000000000000A,0x00020000,0,0), +(18096,0,0,0,0,0x0000008000000060,0x00020000,0,0), +(18097,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(18100,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(18119,0,0,593,0,0x0000000000000000,0x00020000,0,0), +(18120,0,0,593,0,0x0000000000000000,0x00020000,0,0), +(18121,0,0,593,0,0x0000000000000000,0x00020000,0,0), +(18122,0,0,593,0,0x0000000000000000,0x00020000,0,0), +(18123,0,0,593,0,0x0000000000000000,0x00020000,0,0), +(18137,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(18146,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(18167,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(18186,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(18189,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(18542,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(18765,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(18799,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(18800,0,0,0,0,0x0000000000000000,0x00000008,0,0), +(18803,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(18815,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(18816,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(18847,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(18943,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(18979,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(18983,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(19184,0,0,0,0,0x0000000000000000,0x00200000,0,0), +(19194,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(19228,0,0,0,0,0x0000000000000040,0x00020000,0,0), +(19232,0,0,0,0,0x0000000000000040,0x00020000,0,0), +(19233,0,0,0,0,0x0000000000000040,0x00020000,0,0), +(19261,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19262,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19264,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19265,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19266,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19271,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(19273,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(19274,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(19275,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(19308,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19309,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19310,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19311,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19312,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19387,0,0,0,0,0x0000000000000000,0x00200000,0,0), +(19388,0,0,0,0,0x0000000000000000,0x00200000,0,0), +(19407,0,0,0,0,0x0000000000000200,0x00020000,0,0), +(19409,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(19412,0,0,0,0,0x0000000000000200,0x00020000,0,0), +(19413,0,0,0,0,0x0000000000000200,0x00020000,0,0), +(19414,0,0,0,0,0x0000000000000200,0x00020000,0,0), +(19415,0,0,0,0,0x0000000000000200,0x00020000,0,0), +(19449,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19478,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19514,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(19572,0,0,0,9,0x0000000000800000,0x08000000,0,0), +(19573,0,0,0,9,0x0000000000800000,0x08000000,0,0), +(19577,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(19655,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19656,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19660,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(19817,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(19818,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20049,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(20056,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(20057,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(20058,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(20059,0,0,0,0,0x0000000000000000,0x00011000,0,0), +(20127,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(20128,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20130,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(20131,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20132,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20133,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20134,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20135,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(20136,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(20137,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(20154,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20164,0,0,0,0,0x0000000000000000,0x00000001,5,0), +(20165,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20166,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20177,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20178,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20179,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20180,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20181,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20182,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20185,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(20186,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20210,0,0,0,10,0x00010000C0000000,0x10000000,0,0), +(20212,0,0,0,10,0x00010000C0000000,0x10000000,0,0), +(20213,0,0,0,10,0x00010000C0000000,0x10000000,0,0), +(20214,0,0,0,10,0x00010000C0000000,0x10000000,0,0), +(20215,0,0,0,10,0x00010000C0000000,0x10000000,0,0), +(20230,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(20234,0,0,0,0,0x0000000000008000,0x00020000,0,0), +(20235,0,0,0,0,0x0000000000008000,0x00020000,0,0), +(20287,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20288,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20289,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20290,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20291,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20292,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20293,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20344,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(20345,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(20346,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(20347,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20348,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20349,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20354,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20355,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(20356,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20357,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(20375,0,0,0,0,0x0000000000000000,0x00000001,7,0), +(20500,0,0,0,4,0x0000000010000000,0x00004000,0,0), +(20501,0,0,0,4,0x0000000010000000,0x00004000,0,0), +(20545,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(20705,0,0,0,0,0x0000000000000000,0x00002000,0,0), +(20725,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(20784,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(20847,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(20884,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(20891,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(20911,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20912,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20913,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20914,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20915,0,0,0,0,0x0000000000000000,0x00000001,7,0), +(20918,0,0,0,0,0x0000000000000000,0x00000001,7,0), +(20919,0,0,0,0,0x0000000000000000,0x00000001,7,0), +(20920,0,0,0,0,0x0000000000000000,0x00000001,7,0), +(20925,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20927,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(20928,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(21053,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(21061,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21063,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(21080,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21084,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21185,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(21334,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(21645,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21747,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21788,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21838,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(21841,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21853,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(21882,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(21890,0,0,0,4,0x0000036C2A764EEF,0x00082001,0,0), +(21893,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(21897,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(21911,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(21969,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(21978,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(22007,0,0,0,0,0x0000000000200821,0x00004000,0,0), +(22413,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(22438,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(22618,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(22620,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(22648,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(22835,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(22857,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(23340,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(23378,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(23547,0,0,0,0,0x0000000000000000,0x00000020,0,0), +(23548,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(23551,0,0,0,0,0x00000000000000C0,0x00004000,0,0), +(23552,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(23572,0,0,0,0,0x00000000000000C0,0x00004000,0,0), +(23578,0,0,0,0,0x0000000000000000,0x00080000,2,0), +(23581,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(23686,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(23688,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(23689,0,0,0,0,0x0000000000000000,0x00000001,4,0), +(23695,0,0,0,0,0x0000000000000002,0x00020000,0,0), +(23721,0,0,0,0,0x0000000000000800,0x00020000,0,0), +(23771,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(23780,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(23863,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(23867,0,0,0,0,0x0000000000000000,0x00000081,0,0), +(23885,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(23886,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(23887,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(23888,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(24051,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(24256,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(24389,4,0,0,0,0x0000000000000000,0x00020000,0,0), +(24398,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(24574,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(24596,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(24597,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(24603,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(24604,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(24605,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(24658,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(24661,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(24905,0,0,0,0,0x0000000000000000,0x00000001,15,0), +(24932,0,0,0,0,0x0000000000000000,0x00001000,0,6), +(24949,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(25020,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(25023,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(25296,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(25431,0,0,0,0,0x0000000000000000,0x00000402,0,0), +(25441,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(25461,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(25469,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(25472,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(25477,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(25513,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(25669,0,0,0,0,0x0000000000000000,0x00000001,1,0), +(25759,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(25760,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(25761,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(25762,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(25767,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(25820,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(25899,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(25906,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(25937,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(25988,0,0,0,0,0x0000000000000000,0x00040000,0,0), +(26016,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(26021,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(26107,0,0,0,7,0x0000008000800000,0xC4000000,0,0), +(26119,0,0,0,11,0x0000000090100003,0x00004000,0,0), +(26128,0,0,0,0,0x0000000000000000,0x02000000,0,0), +(26135,0,0,0,0,0x0000000000800000,0x00004000,0,0), +(26169,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(26376,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(26463,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(26467,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(26480,0,0,0,0,0x0000000000000000,0x00080001,3,0), +(27009,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27044,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(27124,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27155,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(27160,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(27162,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27164,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(27166,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(27168,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(27169,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(27170,0,0,0,0,0x0000000000000000,0x00000001,7,0), +(27179,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(27200,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(27217,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(27243,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(27280,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27419,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(27420,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(27498,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(27521,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(27522,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(27539,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(27561,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(27656,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(27688,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(27774,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(27776,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27778,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27780,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27781,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(27785,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(27787,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(27811,0,0,0,0,0x0000000000000000,0x00802000,0,0), +(27815,0,0,0,0,0x0000000000000000,0x00802000,0,0), +(27816,0,0,0,0,0x0000000000000000,0x00802000,0,0), +(27852,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(27861,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(27863,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(27864,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(27865,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(27867,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(28200,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(28305,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(28429,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(28458,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(28460,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(28592,16,0,0,0,0x0000000000000000,0x00020000,0,0), +(28593,16,0,0,0,0x0000000000000000,0x00020000,0,0), +(28594,16,0,0,0,0x0000000000000000,0x00020000,0,0), +(28595,16,0,0,0,0x0000000000000000,0x00020000,0,0), +(28716,0,0,0,7,0x0000000000000010,0x08000000,0,0), +(28719,0,0,0,7,0x0000000000000020,0x10000000,0,0), +(28744,0,0,0,7,0x0000000000000040,0x08000000,0,0), +(28752,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(28761,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(28764,0,0,0,0,0x0000000000000000,0x00100000,0,0), +(28771,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(28780,0,0,0,0,0x0000000000000000,0x08020000,0,0), +(28789,0,0,0,10,0x0000000000006000,0x20000000,0,0), +(28802,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(28809,0,0,0,0,0x0000000000001000,0x10000000,0,0), +(28812,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(28816,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(28823,0,0,0,0,0x00000000000000C0,0x08000000,0,0), +(28845,0,0,0,0,0x0000000000000000,0x00000200,0,0), +(28847,0,0,0,7,0x0000000000000020,0x00004000,0,0), +(28849,0,0,0,11,0x0000000000000080,0x00004000,0,0), +(29062,0,0,0,0,0x0000000000000000,0x00802000,0,0), +(29064,0,0,0,0,0x0000000000000000,0x00802000,0,0), +(29065,0,0,0,0,0x0000000000000000,0x00802000,0,0), +(29074,20,0,0,0,0x0000000000000000,0x00010000,0,0), +(29075,20,0,0,0,0x0000000000000000,0x00010000,0,0), +(29076,20,0,0,0,0x0000000000000000,0x00010000,0,0), +(29150,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(29162,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(29179,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(29180,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(29185,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(29194,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(29196,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(29198,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(29220,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(29307,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(29441,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29444,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29445,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29446,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29447,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29448,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(29501,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29601,0,0,0,7,0x0000000000000000,0x00004000,0,0), +(29624,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29625,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29626,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29632,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29633,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29634,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29635,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29636,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29637,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(29801,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(30030,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(30033,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(30079,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(30080,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(30081,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(30160,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(30293,0,0,0,5,0x000000C000000381,0x00020000,0,0), +(30295,0,0,0,5,0x000000C000000381,0x00020000,0,0), +(30296,0,0,0,5,0x000000C000000381,0x00020000,0,0), +(30299,36,0,0,0,0x0000000000000000,0x00100000,0,0), +(30301,36,0,0,0,0x0000000000000000,0x00100000,0,0), +(30302,36,0,0,0,0x0000000000000000,0x00100000,0,0), +(30339,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(30482,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(30636,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(30675,0,0,0,11,0x0000000000000003,0x00004000,0,0), +(30678,0,0,0,11,0x0000000000000003,0x00004000,0,0), +(30679,0,0,0,11,0x0000000000000003,0x00004000,0,0), +(30680,0,0,0,11,0x0000000000000003,0x00004000,0,0), +(30681,0,0,0,11,0x0000000000000003,0x00004000,0,0), +(30802,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(30808,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(30809,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(30810,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(30811,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(30823,0,0,0,0,0x0000000000000000,0x00000001,10.5,0), +(30881,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30883,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30884,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30885,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30886,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(31233,0,0,0,8,0x00000009003E0000,0x00020000,0,0), +(31239,0,0,0,8,0x00000009003E0000,0x00020000,0,0), +(31240,0,0,0,8,0x00000009003E0000,0x00020000,0,0), +(31241,0,0,0,8,0x00000009003E0000,0x00020000,0,0), +(31242,0,0,0,8,0x00000009003E0000,0x00020000,0,0), +(31244,0,0,0,0,0x0000000000000000,0x80000000,0,0), +(31245,0,0,0,0,0x0000000000000000,0x80000000,0,0), +(31255,0,0,0,0,0x0000000000000000,0x00000100,0,0), +(31316,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(31569,0,0,0,3,0x0000000000010000,0x00004000,0,0), +(31570,0,0,0,3,0x0000000000010000,0x00004000,0,0), +(31641,0,0,0,0,0x0000000000000000,0x00080002,0,0), +(31642,0,0,0,0,0x0000000000000000,0x00080002,0,0), +(31785,0,0,0,0,0x0000000000000000,0x20000000,0,0), +(31794,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(31801,0,0,0,0,0x0000000000000000,0x00000001,20,0), +(31828,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(31829,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(31830,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(31833,0,0,0,10,0x0000000080000000,0x00004000,0,0), +(31835,0,0,0,10,0x0000000080000000,0x00004000,0,0), +(31836,0,0,0,10,0x0000000080000000,0x00004000,0,0), +(31892,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(31895,0,0,0,0,0x0000000000000000,0x00000001,5,0), +(31896,0,0,0,0,0x0000000000000000,0x00000001,2,0), +(32215,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(32385,0,0,0,5,0x0000001100000402,0x00020000,0,0), +(32387,0,0,0,5,0x0000001100000402,0x00020000,0,0), +(32392,0,0,0,5,0x0000001100000402,0x00020000,0,0), +(32393,0,0,0,5,0x0000001100000402,0x00020000,0,0), +(32394,0,0,0,5,0x0000001100000402,0x00020000,0,0), +(32587,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(32593,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(32594,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(32642,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(32734,0,0,0,0,0x0000000000000000,0x00000002,0,3), +(32748,0,0,0,8,0x0000000100000000,0x00080000,0,0), +(32776,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(32777,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(32837,0,0,0,0,0x0000000000000000,0x00004000,0,45), +(32850,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(32863,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(33012,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(33014,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(33089,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(33142,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(33145,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(33146,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(33150,0,0,0,0,0x0000000000000000,0x10010000,0,0), +(33154,0,0,0,0,0x0000000000000000,0x10010000,0,0), +(33191,0,0,0,6,0x0000040000808000,0x00020000,0,0), +(33192,0,0,0,6,0x0000040000808000,0x00020000,0,0), +(33193,0,0,0,6,0x0000040000808000,0x00020000,0,0), +(33194,0,0,0,6,0x0000040000808000,0x00020000,0,0), +(33195,0,0,0,6,0x0000040000808000,0x00020000,0,0), +(33297,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(33299,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(33493,0,0,0,0,0x0000000000000000,0x00000002,0,0), +(33510,0,0,0,0,0x0000000000000000,0x00080001,5,0), +(33511,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(33522,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(33648,0,0,0,0,0x0000000000000000,0x00401000,0,0), +(33727,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(33735,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(33736,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(33746,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(33754,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(33755,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(33756,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(33757,0,0,0,0,0x0000000000000000,0x00000001,0,3), +(33759,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(33776,0,0,0,0,0x0000000000000000,0x20000000,0,0), +(33881,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(33882,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(33883,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(33953,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(34082,0,0,0,0,0x0000000000000000,0x00000000,0,0), +(34138,0,0,0,11,0x0000000000000080,0x08000000,0,0), +(34303,0,0,0,0,0x0000000000000000,0x00000080,0,0), +(34320,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(34355,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(34457,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(34497,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34498,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34499,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34500,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34502,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34503,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34506,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(34507,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(34508,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(34586,0,0,0,0,0x0000000000000000,0x00080001,1.5,0), +(34749,0,0,0,0,0x0000000000000000,0x02000000,0,0), +(34753,0,0,0,6,0x0000000000001800,0x08000000,0,0), +(34774,0,0,0,0,0x0000000000000000,0x00080001,1.5,20), +(34827,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(34838,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(34839,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(34859,0,0,0,6,0x0000000000001800,0x08000000,0,0), +(34860,0,0,0,6,0x0000000000001800,0x08000000,0,0), +(34914,32,0,0,0,0x0000000000000000,0x00008000,0,0), +(34916,32,0,0,0,0x0000000000000000,0x00008000,0,0), +(34917,32,0,0,0,0x0000000000000000,0x00008000,0,0), +(34935,0,0,0,0,0x0000000000000000,0x00000002,0,8), +(34938,0,0,0,0,0x0000000000000000,0x00000002,0,8), +(34939,0,0,0,0,0x0000000000000000,0x00000002,0,8), +(34948,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(34949,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(34950,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(34954,0,0,0,0,0x0000000000000000,0x00400000,0,0), +(35077,0,0,0,0,0x0000000000000000,0x00008000,0,60), +(35080,0,0,0,0,0x0000000000000000,0x00000001,0,60), +(35083,0,0,0,0,0x0000000000000000,0x00020000,0,60), +(35086,0,0,0,0,0x0000000000000000,0x08020000,0,60), +(35100,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(35102,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(35103,0,0,0,0,0x0000000000000000,0x00080000,0,0), +(35205,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(35541,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(35550,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(35551,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(35552,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(35553,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(35942,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(36111,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(36123,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(36576,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(37168,0,0,0,8,0x00000009003E0000,0x00020000,0,0), +(37169,0,0,0,8,0x0000000000020000,0x00000000,0,0), +(37170,0,0,0,0,0x0000000000000000,0x00000001,1,0), +(37173,0,0,0,8,0x000001062CBC0598,0x000A0001,0,30), +(37188,0,0,0,10,0x0000000000800000,0x00004000,0,0), +(37189,0,0,0,10,0x0000000000006000,0x10000000,0,60), +(37195,0,0,0,10,0x0000000000800000,0x00004000,0,0), +(37197,0,0,0,0,0x0000000000000000,0x00004000,0,45), +(37213,0,0,0,11,0x0000000090100007,0x00010000,0,0), +(37227,0,0,0,11,0x00000000000001C0,0x10000000,0,60), +(37228,0,0,0,11,0x0000000090100007,0x00020000,0,0), +(37237,0,0,0,11,0x0000000000000001,0x00010000,0,0), +(37239,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(37247,8,0,0,0,0x0000000000000000,0x00004000,0,45), +(37288,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(37295,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(37306,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(37311,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(37336,0,0,0,0,0x0000000000000000,0x00084001,0,0), +(37377,32,0,0,0,0x0000000000000000,0x00004000,0,0), +(37381,0,0,0,0,0x0000000000000000,0x000A0001,0,0), +(37443,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(37447,0,0,0,3,0x0000010000000000,0x00004000,0,0), +(37514,0,0,0,0,0x0000000000000000,0x00000020,0,0), +(37519,0,0,0,0,0x0000000000000000,0x04000000,0,0), +(37525,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(37528,0,0,0,4,0x0000000000000004,0x00000001,0,0), +(37604,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(37617,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(37655,0,0,0,0,0x0000000000000000,0x00004000,0,60), +(37657,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(37705,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(37982,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(38031,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(38196,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(38252,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(38290,0,0,0,0,0x0000000000000000,0x00080000,3,0), +(38299,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(38319,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(38332,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(38334,0,0,0,0,0x0000000000000000,0x00004000,0,60), +(38347,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(38350,0,0,0,0,0x0000000000000000,0x00401000,0,0), +(38394,0,0,0,5,0x0000000000000006,0x00020000,0,0), +(38427,0,0,0,0,0x0000000000000000,0x00000001,0,0), +(39027,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(39367,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(39372,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(39437,4,0,0,0,0x0000000000000000,0x00004000,0,0), +(39438,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(39440,0,0,0,0,0x0000000000000000,0x00020000,0,0), +(39442,0,0,0,0,0x0000000000000000,0x00020001,0,0), +(39443,0,0,0,0,0x0000000000000000,0x00401000,0,0), +(39444,0,0,0,0,0x0000000000000000,0x00100002,0,0), +(39446,0,0,0,0,0x0000000000000000,0x00000004,0,0), +(39530,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(39958,0,0,0,0,0x0000000000000000,0x00000001,0.7,40), +(40353,0,0,0,0,0x0000000000000000,0xC4000001,0,0), +(40407,0,0,0,0,0x0000000000000000,0x00000402,6,0), +(40438,0,0,0,6,0x0000000000008010,0x08020000,0,0), +(40442,0,0,0,7,0x0000044000000014,0x00004001,0,0), +(40444,0,0,0,0,0x0000000000000000,0x00000040,0,0), +(40458,0,0,0,4,0x0000060102000000,0x00000001,0,0), +(40463,0,0,0,11,0x0000001000000081,0x00004001,0,0), +(40470,0,0,0,10,0x00000000C0800000,0x00004000,0,0), +(40475,0,0,0,0,0x0000000000000000,0x00080001,3,0), +(40482,0,0,0,0,0x0000000000000000,0x00010000,0,0), +(40485,0,0,0,9,0x0000000100000000,0x00080000,0,0), +(40478,0,0,0,5,0x0000000000000002,0x00020000,0,0), +(40971,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(41260,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(41262,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(41434,0,0,0,0,0x0000000000000000,0x00000001,2,45), +(41635,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(41989,0,0,0,0,0x0000000000000000,0x00000001,3,0), +(42083,0,0,0,0,0x0000000000000000,0x00401000,0,0), +(42135,0,0,0,0,0x0000000000000000,0x00100402,0,90), +(42136,0,0,0,0,0x0000000000000000,0x00100402,0,90), +(42370,0,0,0,11,0x0000000000000080,0x08000000,0,0), +(43338,0,0,0,0,0x0000000000000000,0x00001000,0,0), +(43728,0,0,0,11,0x0000000000000080,0x08000000,0,0), +(43737,0,0,0,7,0x0000044000000000,0x00000001,0,10), +(43739,0,0,0,7,0x0000000000000002,0x00020000,0,0), +(43745,0,0,0,10,0x0000020000000000,0x00020000,0,0), +(43748,0,0,0,11,0x0000000090100000,0x00004000,0,0), +(43750,0,0,0,11,0x0000000000000001,0x00004000,0,0), +(43823,0,0,0,0,0x0000000000000000,0x00008000,0,0), +(44604,0,0,0,0,0x0000000000000000,0x00004000,0,0), +(44599,0,0,0,0,0x0000000000000000,0x00000001,0,5), +(44835,0,0,0,7,0x0000008000000000,0x00000001,0,0), +(45040,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(45054,0,0,0,0,0x0000000000000000,0x00020000,0,15), +(45057,0,0,0,0,0x0000000000000000,0x00000002,0,30), +(45059,0,0,0,0,0x0000000000000000,0x08000000,0,0), +(45234,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(45243,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(45244,0,0,0,0,0x0000000000000000,0x00842000,0,0), +(45354,0,0,0,0,0x0000000000000000,0x00000001,0,45), +(45355,0,0,0,0,0x0000000000000000,0x00080001,0,0), +(45444,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(45481,0,0,0,0,0x0000000000000000,0x08020000,0,45), +(45482,0,0,0,0,0x0000000000000000,0x00080001,0,45), +(45483,0,0,0,0,0x0000000000000000,0x00080001,0,45), +(45484,0,0,0,0,0x0000000000000000,0x08000000,0,45), +(46046,0,0,0,0,0x0000000000000000,0x00000001,0,5), +(46098,0,0,0,11,0x0000000000000080,0x08000000,0,0), +(46364,0,0,0,0,0x0000000000000000,0x00100402,0,0), +(46569,0,0,0,0,0x0000000000000000,0x00004000,0,45), +(46832,0,0,0,7,0x0000000000000001,0x00004000,0,0); +/*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_script_target` +-- + +DROP TABLE IF EXISTS `spell_script_target`; +CREATE TABLE `spell_script_target` ( + `entry` mediumint(8) unsigned NOT NULL, + `type` tinyint(3) unsigned NOT NULL default '0', + `targetEntry` mediumint(8) unsigned NOT NULL default '0', + UNIQUE KEY `entry_type_target` (`entry`,`type`,`targetEntry`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Spell System'; + +-- +-- Dumping data for table `spell_script_target` +-- + +LOCK TABLES `spell_script_target` WRITE; +/*!40000 ALTER TABLE `spell_script_target` DISABLE KEYS */; +/*!40000 ALTER TABLE `spell_script_target` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_scripts` +-- + +DROP TABLE IF EXISTS `spell_scripts`; +CREATE TABLE `spell_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `spell_scripts` +-- + +LOCK TABLES `spell_scripts` WRITE; +/*!40000 ALTER TABLE `spell_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `spell_scripts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_target_position` +-- + +DROP TABLE IF EXISTS `spell_target_position`; +CREATE TABLE `spell_target_position` ( + `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Identifier', + `target_map` smallint(5) unsigned NOT NULL default '0', + `target_position_x` float NOT NULL default '0', + `target_position_y` float NOT NULL default '0', + `target_position_z` float NOT NULL default '0', + `target_orientation` float NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System'; + +-- +-- Dumping data for table `spell_target_position` +-- + +LOCK TABLES `spell_target_position` WRITE; +/*!40000 ALTER TABLE `spell_target_position` DISABLE KEYS */; +/*!40000 ALTER TABLE `spell_target_position` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `spell_threat` +-- + +DROP TABLE IF EXISTS `spell_threat`; +CREATE TABLE `spell_threat` ( + `entry` mediumint(8) unsigned NOT NULL, + `Threat` smallint(6) NOT NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED; + +-- +-- Dumping data for table `spell_threat` +-- + +LOCK TABLES `spell_threat` WRITE; +/*!40000 ALTER TABLE `spell_threat` DISABLE KEYS */; +INSERT INTO `spell_threat` VALUES +(78,20), +(284,39), +(285,59), +(770,108), +(778,108), +(1608,78), +(1672,180), +(1715,61), +(2139,300), +(6343,17), +(6572,155), +(6574,195), +(6809,89), +(7372,101), +(7373,141), +(7379,235), +(7386,100), +(7405,140), +(8198,40), +(8204,64), +(8205,96), +(8380,180), +(8972,118), +(9745,148), +(9749,108), +(9880,178), +(9881,207), +(9907,108), +(11556,43), +(11564,98), +(11565,118), +(11566,137), +(11567,145), +(11580,143), +(11581,180), +(11596,220), +(11597,261), +(11600,275), +(11601,315), +(11775,395), +(14274,200), +(14921,415), +(15629,300), +(15630,400), +(15631,500), +(15632,600), +(16857,108), +(17735,200), +(17750,300), +(17751,450), +(17752,600), +(17390,108), +(17391,108), +(17392,108), +(20569,100), +(20736,100), +(20925,20), +(20927,30), +(20928,40), +(23922,160), +(23923,190), +(23924,220), +(23925,250), +(24394,580), +(24583,5), +(25225,300), +(25231,130), +(25258,286), +(25264,215), +(25269,400), +(25286,175), +(25288,355), +(25289,60), +(26993,127), +(26996,176), +(27011,127), +(27179,54), +(29704,230), +(29707,196), +(30324,220), +(30356,323), +(30357,483), +(33745,285), +(33878,129), +(33986,180), +(33987,232); +/*!40000 ALTER TABLE `spell_threat` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `transports` +-- + +DROP TABLE IF EXISTS `transports`; +CREATE TABLE `transports` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `name` text, + `period` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Transports'; + +-- +-- Dumping data for table `transports` +-- + +LOCK TABLES `transports` WRITE; +/*!40000 ALTER TABLE `transports` DISABLE KEYS */; +/*!40000 ALTER TABLE `transports` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `uptime` +-- + +DROP TABLE IF EXISTS `uptime`; +CREATE TABLE `uptime` ( + `starttime` bigint(20) unsigned NOT NULL default '0', + `startstring` varchar(64) NOT NULL default '', + `uptime` bigint(20) unsigned NOT NULL default '0', + `maxplayers` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`starttime`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Uptime system'; + +-- +-- Dumping data for table `uptime` +-- + +LOCK TABLES `uptime` WRITE; +/*!40000 ALTER TABLE `uptime` DISABLE KEYS */; +/*!40000 ALTER TABLE `uptime` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2008-03-30 15:34:54 diff --git a/sql/realmd.sql b/sql/realmd.sql new file mode 100644 index 000000000..40faf349c --- /dev/null +++ b/sql/realmd.sql @@ -0,0 +1,167 @@ +-- MySQL dump 10.11 +-- +-- Host: localhost Database: realmd +-- ------------------------------------------------------ +-- Server version 5.0.45-Debian_1ubuntu3.1-log + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `account` +-- + +DROP TABLE IF EXISTS `account`; +CREATE TABLE `account` ( + `id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'Identifier', + `username` varchar(32) NOT NULL default '', + `sha_pass_hash` varchar(40) NOT NULL default '', + `gmlevel` tinyint(3) unsigned NOT NULL default '0', + `sessionkey` longtext, + `v` longtext, + `s` longtext, + `email` varchar(320) NOT NULL default '', + `joindate` timestamp NOT NULL default CURRENT_TIMESTAMP, + `last_ip` varchar(30) NOT NULL default '127.0.0.1', + `failed_logins` int(11) unsigned NOT NULL default '0', + `locked` tinyint(3) unsigned NOT NULL default '0', + `last_login` timestamp NOT NULL default '0000-00-00 00:00:00', + `online` tinyint(4) NOT NULL default '0', + `expansion` tinyint(3) unsigned NOT NULL default '0', + `mutetime` bigint(40) unsigned NOT NULL default '0', + `locale` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + UNIQUE KEY `idx_username` (`username`), + KEY `idx_gmlevel` (`gmlevel`) +) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC COMMENT='Account System'; + +-- +-- Dumping data for table `account` +-- + +LOCK TABLES `account` WRITE; +/*!40000 ALTER TABLE `account` DISABLE KEYS */; +INSERT INTO `account` VALUES +(1,'ADMINISTRATOR','a34b29541b87b7e4823683ce6c7bf6ae68beaaac',3,'','0','0','','2006-04-25 10:18:56','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0), +(2,'GAMEMASTER','7841e21831d7c6bc0b57fbe7151eb82bd65ea1f9',2,'','0','0','','2006-04-25 10:18:56','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0), +(3,'MODERATOR','a7f5fbff0b4eec2d6b6e78e38e8312e64d700008',1,'','0','0','','2006-04-25 10:19:35','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0), +(4,'PLAYER','3ce8a96d17c5ae88a30681024e86279f1a38c041',0,'','0','0','','2006-04-25 10:19:35','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0); +/*!40000 ALTER TABLE `account` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `account_banned` +-- + +DROP TABLE IF EXISTS `account_banned`; +CREATE TABLE `account_banned` ( + `id` int(11) NOT NULL default '0' COMMENT 'Account id', + `bandate` bigint(40) NOT NULL default '0', + `unbandate` bigint(40) NOT NULL default '0', + `bannedby` varchar(50) NOT NULL, + `banreason` varchar(255) NOT NULL, + `active` tinyint(4) NOT NULL default '1', + PRIMARY KEY (`id`,`bandate`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Ban List'; + +-- +-- Dumping data for table `account_banned` +-- + +LOCK TABLES `account_banned` WRITE; +/*!40000 ALTER TABLE `account_banned` DISABLE KEYS */; +/*!40000 ALTER TABLE `account_banned` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ip_banned` +-- + +DROP TABLE IF EXISTS `ip_banned`; +CREATE TABLE `ip_banned` ( + `ip` varchar(32) NOT NULL default '127.0.0.1', + `bandate` bigint(40) NOT NULL, + `unbandate` bigint(40) NOT NULL, + `bannedby` varchar(50) NOT NULL default '[Console]', + `banreason` varchar(255) NOT NULL default 'no reason', + PRIMARY KEY (`ip`,`bandate`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Banned IPs'; + +-- +-- Dumping data for table `ip_banned` +-- + +LOCK TABLES `ip_banned` WRITE; +/*!40000 ALTER TABLE `ip_banned` DISABLE KEYS */; +/*!40000 ALTER TABLE `ip_banned` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `realmcharacters` +-- + +DROP TABLE IF EXISTS `realmcharacters`; +CREATE TABLE `realmcharacters` ( + `realmid` int(11) unsigned NOT NULL default '0', + `acctid` bigint(20) unsigned NOT NULL, + `numchars` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`realmid`,`acctid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Realm Character Tracker'; + +-- +-- Dumping data for table `realmcharacters` +-- + +LOCK TABLES `realmcharacters` WRITE; +/*!40000 ALTER TABLE `realmcharacters` DISABLE KEYS */; +/*!40000 ALTER TABLE `realmcharacters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `realmlist` +-- + +DROP TABLE IF EXISTS `realmlist`; +CREATE TABLE `realmlist` ( + `id` int(11) unsigned NOT NULL auto_increment, + `name` varchar(32) NOT NULL default '', + `address` varchar(32) NOT NULL default '127.0.0.1', + `port` int(11) NOT NULL default '8085', + `icon` tinyint(3) unsigned NOT NULL default '0', + `color` tinyint(3) unsigned NOT NULL default '2', + `timezone` tinyint(3) unsigned NOT NULL default '0', + `allowedSecurityLevel` tinyint(3) unsigned NOT NULL default '0', + `population` float unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + UNIQUE KEY `idx_name` (`name`) +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Realm System'; + +-- +-- Dumping data for table `realmlist` +-- + +LOCK TABLES `realmlist` WRITE; +/*!40000 ALTER TABLE `realmlist` DISABLE KEYS */; +INSERT INTO `realmlist` VALUES +(1,'MaNGOS','127.0.0.1',8085,1,0,1,0,0); +/*!40000 ALTER TABLE `realmlist` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2008-01-10 11:37:06 diff --git a/sql/tools/Makefile.am b/sql/tools/Makefile.am new file mode 100644 index 000000000..dabcc67cd --- /dev/null +++ b/sql/tools/Makefile.am @@ -0,0 +1,36 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## Change installation location +# datadir = mangos/sql/tools +pkgdatadir = $(datadir)/mangos/sql/tools + +## Files to be installed +# Install basic SQL files to datadir +pkgdata_DATA = \ + characters_item_duplicates_remove.sql \ + characters_pet_data_cleanup.sql \ + README + +## Additional files to include when running 'make dist' +EXTRA_DIST = \ + characters_item_duplicates_remove.sql \ + characters_pet_data_cleanup.sql \ + README diff --git a/sql/tools/README b/sql/tools/README new file mode 100644 index 000000000..f5953acef --- /dev/null +++ b/sql/tools/README @@ -0,0 +1,10 @@ += MaNGOS -- README = + +Copyright (c) 2005-2008 MaNGOS + +See the COPYING file for copying conditions. + +== Database tools == +This folder contains SQL files which can be used for cleanup DB from corrupted or outdated data in safe way. +This tools must be used _only_ when mangos server stopped. +But you can safely use its any times while server shutdown. diff --git a/sql/tools/characters_item_duplicates_remove.sql b/sql/tools/characters_item_duplicates_remove.sql new file mode 100644 index 000000000..9cdd8738e --- /dev/null +++ b/sql/tools/characters_item_duplicates_remove.sql @@ -0,0 +1,22 @@ +DROP TABLE IF EXISTS item_test; +CREATE TABLE item_test +SELECT w.`item_guid`,w.`source`,w.`count` FROM + (SELECT u.`item_guid`,u.`source`,COUNT(u.`item_guid`) as `count` FROM + ((SELECT c.`item` as `item_guid`, 'i' as `source` FROM character_inventory c) UNION + (SELECT a.`itemguid` as `item_guid`, 'a' as `source` FROM auctionhouse a) UNION + (SELECT m.`item_guid` as `item_guid`, 'm' as `source` FROM mail_items m) UNION + (SELECT g.`item_guid` as `item_guid`, 'g' as `source` FROM guild_bank_item g) + ) as u + GROUP BY u.`item_guid` + ) as w + WHERE w.`count` > 1; + +DELETE FROM auctionhouse WHERE itemguid IN (SELECT item_guid FROM item_test WHERE `source`='i'); +DELETE FROM mail_items WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='i'); +DELETE FROM guild_bank_item WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='i'); + +DELETE FROM mail_items WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='a'); +DELETE FROM guild_bank_item WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='a'); + +DELETE FROM guild_bank_item WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='m'); +DROP TABLE IF EXISTS item_test; diff --git a/sql/tools/characters_pet_data_cleanup.sql b/sql/tools/characters_pet_data_cleanup.sql new file mode 100644 index 000000000..f4454ca85 --- /dev/null +++ b/sql/tools/characters_pet_data_cleanup.sql @@ -0,0 +1,3 @@ +DELETE FROM pet_aura WHERE guid NOT IN (SELECT id FROM character_pet); +DELETE FROM pet_spell WHERE guid NOT IN (SELECT id FROM character_pet); +DELETE FROM pet_spell_cooldown WHERE guid NOT IN (SELECT id FROM character_pet); diff --git a/sql/updates/0.10/4846_characters.sql b/sql/updates/0.10/4846_characters.sql new file mode 100644 index 000000000..6e8ac96c6 --- /dev/null +++ b/sql/updates/0.10/4846_characters.sql @@ -0,0 +1,20 @@ +ALTER TABLE `mail` + ADD COLUMN `has_items` tinyint(3) unsigned NOT NULL default '0' AFTER `itemTextId`; + +UPDATE `mail` SET `has_items` = '1' WHERE `item_guid`<>'0'; + +DROP TABLE IF EXISTS `mail_items`; +CREATE TABLE `mail_items` ( + `mail_id` int(11) NOT NULL default '0', + `item_guid` int(11) NOT NULL default '0', + `item_template` int(11) NOT NULL default '0', + PRIMARY KEY (`mail_id`,`item_guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +INSERT INTO `mail_items` SELECT `id`,`item_guid`,`item_template` FROM `mail` WHERE `mail`.`has_items`>0; + +ALTER TABLE `mail` + DROP COLUMN `item_guid`, + DROP COLUMN `item_template`; + +UPDATE `character` SET data = CONCAT(SUBSTRING(data, 1, length(SUBSTRING_INDEX(data, ' ', 48))), " ", "0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ","0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 140))+2, length(SUBSTRING_INDEX(data, ' ', 225))- length(SUBSTRING_INDEX(data, ' ', 140)) - 1), " ", SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 226))+2, length(SUBSTRING_INDEX(data, ' ', 1249))- length(SUBSTRING_INDEX(data, ' ', 226)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1249))+2, length(SUBSTRING_INDEX(data, ' ', 1259))- length(SUBSTRING_INDEX(data, ' ', 1249)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1259))+2, length(SUBSTRING_INDEX(data, ' ', 1379))- length(SUBSTRING_INDEX(data, ' ', 1259)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1380))+2, length(SUBSTRING_INDEX(data, ' ', 1405))- length(SUBSTRING_INDEX(data, ' ', 1380)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1405))+2, length(SUBSTRING_INDEX(data, ' ', 1410))- length(SUBSTRING_INDEX(data, ' ', 1405)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1410))+2, length(SUBSTRING_INDEX(data, ' ', 1415))- length(SUBSTRING_INDEX(data, ' ', 1410)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1415))+2, length(SUBSTRING_INDEX(data, ' ', 1420))- length(SUBSTRING_INDEX(data, ' ', 1415)) - 1), " ", "0 ",SUBSTRING(data, length(SUBSTRING_INDEX(data, ' ', 1420))+2, length(SUBSTRING_INDEX(data, ' ', 1436))- length(SUBSTRING_INDEX(data, ' ', 1420)) - 1)) WHERE length(SUBSTRING_INDEX(data, ' ', 1436)) < length(data) and length(SUBSTRING_INDEX(data, ' ', 1437)) >= length(data); diff --git a/sql/updates/0.10/4846_mangos_creature_template.sql b/sql/updates/0.10/4846_mangos_creature_template.sql new file mode 100644 index 000000000..d97bf56c7 --- /dev/null +++ b/sql/updates/0.10/4846_mangos_creature_template.sql @@ -0,0 +1,52 @@ +-- custom +-- UNIT_NPC_FLAG_GUARD = 0x00010000, old +-- UNIT_NPC_FLAG_GUARD = 0x10000000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x10000000) & ~0x00010000 WHERE `npcflag` & 0x00010000; + +-- UNIT_NPC_FLAG_STABLEMASTER = 0x00002000, old +-- UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00400000) & ~0x00002000 WHERE `npcflag` & 0x00002000; + +-- UNIT_NPC_FLAG_AUCTIONEER = 0x00001000, old +-- UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00200000) & ~0x00001000 WHERE `npcflag` & 0x00001000; + +-- UNIT_NPC_FLAG_BATTLEFIELDPERSON = 0x00000800, old +-- UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00100000) & ~0x00000800 WHERE `npcflag` & 0x00000800; + +-- UNIT_NPC_FLAG_ARMORER = 0x00004000, old +-- UNIT_NPC_FLAG_REPAIR = 0x00001000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00001000) & ~0x00004000 WHERE `npcflag` & 0x00004000; + +-- UNIT_NPC_FLAG_TABARDDESIGNER = 0x00000400, old +-- UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00080000) & ~0x00000400 WHERE `npcflag` & 0x00000400; + +-- UNIT_NPC_FLAG_PETITIONER = 0x00000200, old +-- UNIT_NPC_FLAG_PETITIONER = 0x00040000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00040000) & ~0x00000200 WHERE `npcflag` & 0x00000200; + +-- UNIT_NPC_FLAG_BANKER = 0x00000100, old +-- UNIT_NPC_FLAG_BANKER = 0x00020000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00020000) & ~0x00000100 WHERE `npcflag` & 0x00000100; + +-- UNIT_NPC_FLAG_INNKEEPER = 0x00000080, old +-- UNIT_NPC_FLAG_INNKEEPER = 0x00010000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00010000) & ~0x00000080 WHERE `npcflag` & 0x00000080; + +-- UNIT_NPC_FLAG_SPIRITGUIDE = 0x00000040, old +-- UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00008000) & ~0x00000040 WHERE `npcflag` & 0x00000040; + +-- UNIT_NPC_FLAG_SPIRITHEALER = 0x00000020, old +-- UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00004000) & ~0x00000020 WHERE `npcflag` & 0x00000020; + +-- UNIT_NPC_FLAG_TAXIVENDOR = 0x00000008, old +-- UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00002000) & ~0x00000008 WHERE `npcflag` & 0x00000008; + +-- UNIT_NPC_FLAG_VENDOR = 0x00000004, old +-- UNIT_NPC_FLAG_VENDOR = 0x00000080, new +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x00000080) & ~0x00000004 WHERE `npcflag` & 0x00000004; diff --git a/sql/updates/0.10/4846_mangos_item_template.sql b/sql/updates/0.10/4846_mangos_item_template.sql new file mode 100644 index 000000000..4c2aac575 --- /dev/null +++ b/sql/updates/0.10/4846_mangos_item_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `item_template` + ADD COLUMN `RequiredArenaRank` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `ExtendedCost`; \ No newline at end of file diff --git a/sql/updates/0.10/4846_mangos_npc_option.sql b/sql/updates/0.10/4846_mangos_npc_option.sql new file mode 100644 index 000000000..9b205447e --- /dev/null +++ b/sql/updates/0.10/4846_mangos_npc_option.sql @@ -0,0 +1,13 @@ +update `npc_option` set `npcflag`=0x00000010 where `id` in('5','49','50'); +update `npc_option` set `npcflag`=0x00000080 where `id` = '3'; +update `npc_option` set `npcflag`=0x00002000 where `id` = '4'; +update `npc_option` set `npcflag`=0x00004000 where `id` = '6'; +update `npc_option` set `npcflag`=0x00008000 where `id` = '7'; +update `npc_option` set `npcflag`=0x00010000 where `id` = '8'; +update `npc_option` set `npcflag`=0x00020000 where `id` = '9'; +update `npc_option` set `npcflag`=0x00040000 where `id` = '10'; +update `npc_option` set `npcflag`=0x00080000 where `id` = '11'; +update `npc_option` set `npcflag`=0x00100000 where `id` = '12'; +update `npc_option` set `npcflag`=0x00200000 where `id` = '13'; +update `npc_option` set `npcflag`=0x00400000 where `id` = '14'; +update `npc_option` set `npcflag`=0x00001000 where `id` = '15'; diff --git a/sql/updates/0.10/4875_mangos_quest_template.sql b/sql/updates/0.10/4875_mangos_quest_template.sql new file mode 100644 index 000000000..d46e16989 --- /dev/null +++ b/sql/updates/0.10/4875_mangos_quest_template.sql @@ -0,0 +1 @@ +ALTER TABLE `quest_template` CHANGE COLUMN `RewXpOrMoney` `RewMoneyMaxLevel` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.10/4890_mangos_item_template.sql b/sql/updates/0.10/4890_mangos_item_template.sql new file mode 100644 index 000000000..63f2a748b --- /dev/null +++ b/sql/updates/0.10/4890_mangos_item_template.sql @@ -0,0 +1,8 @@ +UPDATE `item_template` SET `BagFamily` = 0x00000400 WHERE `BagFamily` =11; +UPDATE `item_template` SET `BagFamily` = 0x00000200 WHERE `BagFamily` =10; +UPDATE `item_template` SET `BagFamily` = 0x00000100 WHERE `BagFamily` = 9; +UPDATE `item_template` SET `BagFamily` = 0x00000080 WHERE `BagFamily` = 8; +UPDATE `item_template` SET `BagFamily` = 0x00000040 WHERE `BagFamily` = 7; +UPDATE `item_template` SET `BagFamily` = 0x00000020 WHERE `BagFamily` = 6; +UPDATE `item_template` SET `BagFamily` = 0x00000008 WHERE `BagFamily` = 4; +UPDATE `item_template` SET `BagFamily` = 0x00000004 WHERE `BagFamily` = 3; diff --git a/sql/updates/0.10/4895_mangos_command.sql b/sql/updates/0.10/4895_mangos_command.sql new file mode 100644 index 000000000..ed7b45a06 --- /dev/null +++ b/sql/updates/0.10/4895_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('tele'); + +INSERT INTO `command` VALUES +('tele',1,'Syntax: .tele #location\r\n\r\nTeleport player to a given location.'); diff --git a/sql/updates/0.10/4896_characters_mail.sql b/sql/updates/0.10/4896_characters_mail.sql new file mode 100644 index 000000000..94ecebcc8 --- /dev/null +++ b/sql/updates/0.10/4896_characters_mail.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mail` + ADD COLUMN `stationery` tinyint(3) NOT NULL DEFAULT '41' AFTER `messageType`; \ No newline at end of file diff --git a/sql/updates/0.10/4898_mangos_playercreateinfo_item.sql b/sql/updates/0.10/4898_mangos_playercreateinfo_item.sql new file mode 100644 index 000000000..f54742472 --- /dev/null +++ b/sql/updates/0.10/4898_mangos_playercreateinfo_item.sql @@ -0,0 +1 @@ +INSERT IGNORE INTO `playercreateinfo_item` VALUES (11, 8, 6948, 1); \ No newline at end of file diff --git a/sql/updates/0.10/4904_mangos_item_template.sql b/sql/updates/0.10/4904_mangos_item_template.sql new file mode 100644 index 000000000..976782abe --- /dev/null +++ b/sql/updates/0.10/4904_mangos_item_template.sql @@ -0,0 +1,10 @@ +UPDATE `item_template` SET `spellcooldown_1` = -1 WHERE `spellcooldown_1` = 0; +UPDATE `item_template` SET `spellcategorycooldown_1` = -1 WHERE `spellcategorycooldown_1` = 0; +UPDATE `item_template` SET `spellcooldown_2` = -1 WHERE `spellcooldown_2` = 0; +UPDATE `item_template` SET `spellcategorycooldown_2` = -1 WHERE `spellcategorycooldown_2` = 0; +UPDATE `item_template` SET `spellcooldown_3` = -1 WHERE `spellcooldown_3` = 0; +UPDATE `item_template` SET `spellcategorycooldown_3` = -1 WHERE `spellcategorycooldown_3` = 0; +UPDATE `item_template` SET `spellcooldown_4` = -1 WHERE `spellcooldown_4` = 0; +UPDATE `item_template` SET `spellcategorycooldown_4` = -1 WHERE `spellcategorycooldown_4` = 0; +UPDATE `item_template` SET `spellcooldown_5` = -1 WHERE `spellcooldown_5` = 0; +UPDATE `item_template` SET `spellcategorycooldown_5` = -1 WHERE `spellcategorycooldown_5` = 0; diff --git a/sql/updates/0.10/4908_mangos_spell_proc_event.sql b/sql/updates/0.10/4908_mangos_spell_proc_event.sql new file mode 100644 index 000000000..7b29b0d8e --- /dev/null +++ b/sql/updates/0.10/4908_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (38394); +INSERT INTO `spell_proc_event` VALUES +(38394,36,0,0,5,6,131072,0); diff --git a/sql/updates/0.10/4916_mangos_spell_affect.sql b/sql/updates/0.10/4916_mangos_spell_affect.sql new file mode 100644 index 000000000..ef3c0b6ba --- /dev/null +++ b/sql/updates/0.10/4916_mangos_spell_affect.sql @@ -0,0 +1,60 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (43857,43858,43859); +INSERT INTO `spell_affect` VALUES +(43857,0,0,0,0,0,0,0x0000001000000000,0), +(43858,0,0,0,0,0,0,0x0000001000000000,0), +(43859,0,0,0,0,0,0,0x0000001000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43860,43861,43862); +INSERT INTO `spell_affect` VALUES +(43860,0,0,0,0,0,0,0x0000000090100000,0), +(43861,0,0,0,0,0,0,0x0000000090100000,0), +(43862,0,0,0,0,0,0,0x0000000090100000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28787); +INSERT INTO `spell_affect` VALUES +(28787,0,0,0,0,0,0,0x0000000000001000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (41042,43850,43851,43852); +INSERT INTO `spell_affect` VALUES +(41042,0,0,0,0,0,0,0x0000000000800000,0), +(43850,0,0,0,0,0,0,0x0000000000800000,0), +(43851,0,0,0,0,0,0,0x0000000000800000,0), +(43852,0,0,0,0,0,0,0x0000000000800000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43854,43855,43856); +INSERT INTO `spell_affect` VALUES +(43854,0,0,0,0,0,0,0x0000004000000000,0), +(43855,0,0,0,0,0,0,0x0000004000000000,0), +(43856,0,0,0,0,0,0,0x0000004000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (41037,43840,43842,43843); +INSERT INTO `spell_affect` VALUES +(41037,0,0,0,0,0,0,0x0000044000000000,0), +(43840,0,0,0,0,0,0,0x0000044000000000,0), +(43842,0,0,0,0,0,0,0x0000044000000000,0), +(43843,0,0,0,0,0,0,0x0000044000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43841,43844,43845); +INSERT INTO `spell_affect` VALUES +(43841,0,0,0,0,0,0,0x0000000000000002,0), +(43844,0,0,0,0,0,0,0x0000000000000002,0), +(43845,0,0,0,0,0,0,0x0000000000000002,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (40460); +INSERT INTO `spell_affect` VALUES +(40460,0,0,0,0,0,0,0x00000009003E0000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28814); +INSERT INTO `spell_affect` VALUES +(28814,0,0,0,0,0,0,0x0000000000020000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17768); +INSERT INTO `spell_affect` VALUES +(17768,0,0,0,0,0,0,0x0000000040000000,0), +(17768,1,0,0,0,0,0,0x0000000080000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (29836,29859); +INSERT INTO `spell_affect` VALUES +(29836,0,0,0,0,0,0,0x0000001000000020,0), +(29859,0,0,0,0,0,0,0x0000001000000020,0); + diff --git a/sql/updates/0.10/4921_mangos_gameobject.sql b/sql/updates/0.10/4921_mangos_gameobject.sql new file mode 100644 index 000000000..f678eae2f --- /dev/null +++ b/sql/updates/0.10/4921_mangos_gameobject.sql @@ -0,0 +1,2 @@ +ALTER TABLE `gameobject` CHANGE COLUMN `dynflags` `state` int(11) unsigned NOT NULL default '1'; +UPDATE `gameobject` SET `state` = 1; diff --git a/sql/updates/0.10/4926_mangos_spell_proc_event.sql b/sql/updates/0.10/4926_mangos_spell_proc_event.sql new file mode 100644 index 000000000..42fddf7ed --- /dev/null +++ b/sql/updates/0.10/4926_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (40458); +INSERT INTO `spell_proc_event` VALUES +(40458,0,971,0,4,0x60102000000,1,0); diff --git a/sql/updates/0.10/4937_mangos_spell_affect.sql b/sql/updates/0.10/4937_mangos_spell_affect.sql new file mode 100644 index 000000000..ec3922919 --- /dev/null +++ b/sql/updates/0.10/4937_mangos_spell_affect.sql @@ -0,0 +1,56 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (11069,12338,12339,12340,12341); +INSERT INTO `spell_affect` VALUES + (11069,0,0,0,0,0,0,0x0000000000000001,0), + (12338,0,0,0,0,0,0,0x0000000000000001,0), + (12339,0,0,0,0,0,0,0x0000000000000001,0), + (12340,0,0,0,0,0,0,0x0000000000000001,0), + (12341,0,0,0,0,0,0,0x0000000000000001,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11070,12473,16763,16765,16766); +INSERT INTO `spell_affect` VALUES + (11070,0,0,0,0,0,0,0x0000000000000020,0), + (12473,0,0,0,0,0,0,0x0000000000000020,0), + (16763,0,0,0,0,0,0,0x0000000000000020,0), + (16765,0,0,0,0,0,0,0x0000000000000020,0), + (16766,0,0,0,0,0,0,0x0000000000000020,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17941); +INSERT INTO `spell_affect` VALUES + (17941,0,0,0,0,0,0,0x0000000000000001,1); + +DELETE FROM `spell_affect` WHERE `entry` IN (20335,20336,20337); +INSERT INTO `spell_affect` VALUES + (20335,0,0,0,0,0,0,0x0000000020000000,0), + (20336,0,0,0,0,0,0,0x0000000020000000,0), + (20337,0,0,0,0,0,0,0x0000000020000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (32043,35396,35397); +INSERT INTO `spell_affect` VALUES + (32043,1,0,0,0,0,0,0x0000040008000000,0), + (35396,1,0,0,0,0,0,0x0000040008000000,0), + (35397,1,0,0,0,0,0,0x0000040008000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (36591); + +DELETE FROM `spell_affect` WHERE `entry` IN (28176); + +DELETE FROM `spell_affect` WHERE `entry` IN (28189); + +DELETE FROM `spell_affect` WHERE `entry` IN (31842); + +DELETE FROM `spell_affect` WHERE `entry` IN (38390); + +DELETE FROM `spell_affect` WHERE `entry` IN (37188); +DELETE FROM `spell_affect` WHERE `entry` IN (37189); +DELETE FROM `spell_affect` WHERE `entry` IN (37227); + +DELETE FROM `spell_affect` WHERE `entry` IN (43837); +INSERT INTO `spell_affect` VALUES + (43837,0,0,0,0,0,0,0x0000000080000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (39950); +INSERT INTO `spell_affect` VALUES + (39950,0,0,0,0,0,0,0x0000000000000040,0); + + + diff --git a/sql/updates/0.10/4937_mangos_spell_proc_event.sql b/sql/updates/0.10/4937_mangos_spell_proc_event.sql new file mode 100644 index 000000000..178838331 --- /dev/null +++ b/sql/updates/0.10/4937_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (37188,37189,37227); +INSERT INTO `spell_proc_event` VALUES + (37188,0,0,0,10,0x0000000000800000,0x00004000,0), + (37189,0,0,0,10,0x00000000C0000000,0x10000000,0), + (37227,0,0,0,11,0x00000000000001C0,0x10000000,0); diff --git a/sql/updates/0.10/4948_mangos_spell_affect.sql b/sql/updates/0.10/4948_mangos_spell_affect.sql new file mode 100644 index 000000000..897fab395 --- /dev/null +++ b/sql/updates/0.10/4948_mangos_spell_affect.sql @@ -0,0 +1,147 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (11095,12872,12873); +INSERT INTO `spell_affect` VALUES + (11095,0,0,0,0,0,0,0x0000000000000010,0), + (12872,0,0,0,0,0,0,0x0000000000000010,0), + (12873,0,0,0,0,0,0,0x0000000000000010,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31821); +INSERT INTO `spell_affect` VALUES + (31821,0,0,0,0,0,0,0x0000000004020048,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23565); +INSERT INTO `spell_affect` VALUES + (23565,0,0,0,0,0,0,0x0000000004020048,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (26130); +INSERT INTO `spell_affect` VALUES + (26130,0,0,0,0,0,0,0x0000000820180000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20101,20102,20103,20104,20105); +INSERT INTO `spell_affect` VALUES + (20101,0,0,0,0,0,0,0x000004000A000200,0), + (20102,0,0,0,0,0,0,0x000004000A000200,0), + (20103,0,0,0,0,0,0,0x000004000A000200,0), + (20104,0,0,0,0,0,0,0x000004000A000200,0), + (20105,0,0,0,0,0,0,0x000004000A000200,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (27848); +INSERT INTO `spell_affect` VALUES + (27848,0,0,0,0,0,0,0x000004000A000200,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33695); +INSERT INTO `spell_affect` VALUES + (33695,0,0,0,0,0,0,0x0000000200000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31879,31880,31881,31882,31883); +INSERT INTO `spell_affect` VALUES + (31879,0,0,0,0,0,0,0x0000000800000400,0), + (31880,0,0,0,0,0,0,0x0000000800000400,0), + (31881,0,0,0,0,0,0,0x0000000800000400,0), + (31882,0,0,0,0,0,0,0x0000000800000400,0), + (31883,0,0,0,0,0,0,0x0000000800000400,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38426); +INSERT INTO `spell_affect` VALUES + (38426,0,0,0,0,0,0,0x0000000080000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37189); + +DELETE FROM `spell_affect` WHERE `entry` IN (37739); +INSERT INTO `spell_affect` VALUES + (37739,0,0,0,0,0,0,0x0000000080000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20359,20360,20361); +INSERT INTO `spell_affect` VALUES + (20359,0,0,0,0,0,0,0x0000000080000000,0), + (20360,0,0,0,0,0,0,0x0000000080000000,0), + (20361,0,0,0,0,0,0,0x0000000080000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20237,20238,20239); +INSERT INTO `spell_affect` VALUES + (20237,0,0,0,0,0,0,0x00000000C0000000,0), + (20238,0,0,0,0,0,0,0x00000000C0000000,0), + (20239,0,0,0,0,0,0,0x00000000C0000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37723); +INSERT INTO `spell_affect` VALUES + (37723,0,0,0,0,0,0,0x00000000C0000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38425,20249,20250,20251); +INSERT INTO `spell_affect` VALUES + (38425,0,0,0,0,0,0,0x0000000040000000,0), + (20249,0,0,0,0,0,0,0x0000000040000000,0), + (20250,0,0,0,0,0,0,0x0000000040000000,0), + (20251,0,0,0,0,0,0,0x0000000040000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38522); +INSERT INTO `spell_affect` VALUES + (38522,0,0,0,0,0,0,0x0000000040000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (34129); +INSERT INTO `spell_affect` VALUES + (34129,0,0,0,0,0,0,0x0000000040000000,0), + (34129,1,0,0,0,0,0,0x0000000040000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (24460); +INSERT INTO `spell_affect` VALUES + (24460,0,0,0,0,0,0,0x0000000010000180,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (21744); +INSERT INTO `spell_affect` VALUES + (21744,0,0,0,0,0,0,0x0000000010000180,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20254,20255,20256); +INSERT INTO `spell_affect` VALUES + (20254,0,0,0,0,0,0,0x0000000000020000,0), + (20254,1,0,0,0,0,0,0x0000000000020000,0), + (20254,2,0,0,0,0,0,0x0000000000020000,0), + (20255,0,0,0,0,0,0,0x0000000000020000,0), + (20255,1,0,0,0,0,0,0x0000000000020000,0), + (20255,2,0,0,0,0,0,0x0000000000020000,0), + (20256,0,0,0,0,0,0,0x0000000000020000,0), + (20256,1,0,0,0,0,0,0x0000000000020000,0), + (20256,2,0,0,0,0,0,0x0000000000020000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38424); +INSERT INTO `spell_affect` VALUES + (38424,0,0,0,0,0,0,0x0000008000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (41021,41026); +INSERT INTO `spell_affect` VALUES + (41021,0,0,0,0,0,0,0x0000004000000000,0), + (41021,1,0,0,0,0,0,0x0000004000000000,0), + (41026,0,0,0,0,0,0,0x0000004000000000,0), + (41026,1,0,0,0,0,0,0x0000004000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38421); +INSERT INTO `spell_affect` VALUES + (38421,0,0,0,0,0,0,0x0000100000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37187); +INSERT INTO `spell_affect` VALUES + (37187,0,0,0,0,0,0,0x0000020000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37182); +INSERT INTO `spell_affect` VALUES + (37182,0,0,0,0,0,0,0x0000000100000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28775); +INSERT INTO `spell_affect` VALUES + (28775,0,0,0,0,0,0,0x0000000100000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37184); +INSERT INTO `spell_affect` VALUES + (37184,0,0,0,0,0,0,0x0000040008000000,0), + (37184,1,0,0,0,0,0,0x0000040008000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31825,31826); +INSERT INTO `spell_affect` VALUES + (31825,0,0,0,0,0,0,0x0000000000001020,0), + (31825,1,0,0,0,0,0,0x0000000200000000,0), + (31826,0,0,0,0,0,0,0x0000000000001020,0), + (31826,1,0,0,0,0,0,0x0000000200000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31844,31845); +INSERT INTO `spell_affect` VALUES + (31844,1,0,0,0,0,0,0x000005401A00038C,0), + (31845,1,0,0,0,0,0,0x000005401A00038C,0); diff --git a/sql/updates/0.10/4951_mangos_spell_affect.sql b/sql/updates/0.10/4951_mangos_spell_affect.sql new file mode 100644 index 000000000..85a9bb0d0 --- /dev/null +++ b/sql/updates/0.10/4951_mangos_spell_affect.sql @@ -0,0 +1,21 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (19498,19499,19500); +INSERT INTO `spell_affect` VALUES + (19498,0,0,0,0,0,0,0x00210810007FA01,0), + (19499,0,0,0,0,0,0,0x00210810007FA01,0), + (19500,0,0,0,0,0,0,0x00210810007FA01,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19416,19417,19418,19419,19420); +INSERT INTO `spell_affect` VALUES + (19416,0,0,0,0,0,0,0x00210810007FA00,0), + (19417,0,0,0,0,0,0,0x00210810007FA00,0), + (19418,0,0,0,0,0,0,0x00210810007FA00,0), + (19419,0,0,0,0,0,0,0x00210810007FA00,0), + (19420,0,0,0,0,0,0,0x00210810007FA00,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19485,19487,19488,19489,19490); +INSERT INTO `spell_affect` VALUES + (19485,0,0,0,0,0,0,0x000000100061801,0), + (19487,0,0,0,0,0,0,0x000000100061801,0), + (19488,0,0,0,0,0,0,0x000000100061801,0), + (19489,0,0,0,0,0,0,0x000000100061801,0), + (19490,0,0,0,0,0,0,0x000000100061801,0); diff --git a/sql/updates/0.10/4952_mangos_spell_proc_event.sql b/sql/updates/0.10/4952_mangos_spell_proc_event.sql new file mode 100644 index 000000000..0d45e5c8e --- /dev/null +++ b/sql/updates/0.10/4952_mangos_spell_proc_event.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (13165,14318,14319,14320,14321,14322,25296,27044); +INSERT INTO `spell_proc_event` VALUES + (13165,0,0,0,0,0,0x00080000,0), + (14318,0,0,0,0,0,0x00080000,0), + (14319,0,0,0,0,0,0x00080000,0), + (14320,0,0,0,0,0,0x00080000,0), + (14321,0,0,0,0,0,0x00080000,0), + (14322,0,0,0,0,0,0x00080000,0), + (25296,0,0,0,0,0,0x00080000,0), + (27044,0,0,0,0,0,0x00080000,0); diff --git a/sql/updates/0.10/4971_characters_character_social.sql b/sql/updates/0.10/4971_characters_character_social.sql new file mode 100644 index 000000000..76f10eee7 --- /dev/null +++ b/sql/updates/0.10/4971_characters_character_social.sql @@ -0,0 +1,15 @@ +ALTER TABLE `character_social` + ADD COLUMN `new_flags` tinyint(1) unsigned NOT NULL default '0'; + +UPDATE `character_social` SET `new_flags` = 1 WHERE `flags`='IGNORE'; + +ALTER TABLE `character_social` + DROP PRIMARY KEY, + DROP COLUMN `flags`, + CHANGE COLUMN `new_flags` `flags` tinyint(1) unsigned NOT NULL default '0', + ADD PRIMARY KEY (`guid`,`friend`,`flags`), + ADD KEY (`guid`), + ADD KEY (`friend`), + ADD KEY `guid_flags` (`guid`,`flags`), + ADD KEY `friend_flags` (`friend`,`flags`); + diff --git a/sql/updates/0.10/4975_mangos_spell_affect.sql b/sql/updates/0.10/4975_mangos_spell_affect.sql new file mode 100644 index 000000000..7a251973b --- /dev/null +++ b/sql/updates/0.10/4975_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (20216); +INSERT INTO `spell_affect` VALUES + (20216,0,0,0,0,0,0,0x0000000000206000,0); diff --git a/sql/updates/0.10/4975_mangos_spell_proc_event.sql b/sql/updates/0.10/4975_mangos_spell_proc_event.sql new file mode 100644 index 000000000..8a175bc8a --- /dev/null +++ b/sql/updates/0.10/4975_mangos_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (20210,20212,20213,20214,20215,37189); +INSERT INTO `spell_proc_event` VALUES + (20210,0,0,0,10,0x0000000000206000,0x10000000,0), + (20212,0,0,0,10,0x0000000000206000,0x10000000,0), + (20213,0,0,0,10,0x0000000000206000,0x10000000,0), + (20214,0,0,0,10,0x0000000000206000,0x10000000,0), + (20215,0,0,0,10,0x0000000000206000,0x10000000,0), + (37189,0,0,0,10,0x0000000000006000,0x10000000,0); diff --git a/sql/updates/0.10/4984_mangos_spell_proc_event.sql b/sql/updates/0.10/4984_mangos_spell_proc_event.sql new file mode 100644 index 000000000..2e1ce21ad --- /dev/null +++ b/sql/updates/0.10/4984_mangos_spell_proc_event.sql @@ -0,0 +1,20 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (12169,20128,20131,20132,20133,20134,32587,32776,32777,38031); +INSERT INTO `spell_proc_event` VALUES + (12169,0,0,0,0,0,0x00000040,0), + (20128,0,0,0,0,0,0x00000040,0), + (20131,0,0,0,0,0,0x00000040,0), + (20132,0,0,0,0,0,0x00000040,0), + (20133,0,0,0,0,0,0x00000040,0), + (20134,0,0,0,0,0,0x00000040,0), + (32587,0,0,0,0,0,0x00000040,0), + (32776,0,0,0,0,0,0x00000040,0), + (32777,0,0,0,0,0,0x00000040,0), + (38031,0,0,0,0,0,0x00000040,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (18803,33299,39530); +INSERT INTO `spell_proc_event` VALUES + (18803,0,0,0,0,0,0x00004000,0), + (33299,0,0,0,0,0,0x00004000,0), + (39530,0,0,0,0,0,0x00004000,0); + diff --git a/sql/updates/0.10/5019_mangos_spell_proc_event.sql b/sql/updates/0.10/5019_mangos_spell_proc_event.sql new file mode 100644 index 000000000..542359e14 --- /dev/null +++ b/sql/updates/0.10/5019_mangos_spell_proc_event.sql @@ -0,0 +1,26 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (6268,7137,8260); +INSERT INTO `spell_proc_event` VALUES + (6268,0,0,0,0,0,0x00000001,0), + (8260,0,0,0,0,0,0x00000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (24597,24603,24604,24605,30636,35942); +INSERT INTO `spell_proc_event` VALUES + (24597,0,0,0,0,0,0x00080001,0), + (24603,0,0,0,0,0,0x00080001,0), + (24604,0,0,0,0,0,0x00080001,0), + (24605,0,0,0,0,0,0x00080001,0), + (30636,0,0,0,0,0,0x00080001,0), + (35942,0,0,0,0,0,0x00080001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37604); +INSERT INTO `spell_proc_event` VALUES + (37604,0,0,0,0,0,0x00004000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (24389); +INSERT INTO `spell_proc_event` VALUES + (24389,0x04,0,0,0,0,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (28780); +INSERT INTO `spell_proc_event` VALUES + (28780,0,0,0,0,0,0x08020000,0); + diff --git a/sql/updates/0.10/5030_mangos_item_template.sql b/sql/updates/0.10/5030_mangos_item_template.sql new file mode 100644 index 000000000..883fa5d82 --- /dev/null +++ b/sql/updates/0.10/5030_mangos_item_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE `item_template` CHANGE `AllowableClass` `AllowableClass` mediumint(9) not null default '-1'; +ALTER TABLE `item_template` CHANGE `AllowableRace` `AllowableRace` mediumint(9) not null default '-1'; + +UPDATE `item_template` SET `AllowableClass` = -1 WHERE `AllowableClass` = 0; +UPDATE `item_template` SET `AllowableRace` = -1 WHERE `AllowableRace` = 0; diff --git a/sql/updates/0.10/5036_mangos_spell_affect.sql b/sql/updates/0.10/5036_mangos_spell_affect.sql new file mode 100644 index 000000000..07c99926e --- /dev/null +++ b/sql/updates/0.10/5036_mangos_spell_affect.sql @@ -0,0 +1,52 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (12945); +INSERT INTO `spell_affect` VALUES + (12945,0,0,0,0,0,0,0x0000000000001000,0), + (12945,1,0,0,0,0,0,0x0000000000001000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (29787,29790,29792); +INSERT INTO `spell_affect` VALUES + (29787,0,0,0,0,0,0,0x0000036C2A764EEF,0), + (29790,0,0,0,0,0,0,0x0000036C2A764EEF,0), + (29792,0,0,0,0,0,0,0x0000036C2A764EEF,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (21887); +INSERT INTO `spell_affect` VALUES + (21887,0,0,0,0,0,0,0x0000036C2A764EEF,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16493,16494); +INSERT INTO `spell_affect` VALUES + (16493,0,0,0,0,0,0,0x0000014D2A600CEF,0), + (16494,0,0,0,0,0,0,0x0000014D2A600CEF,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37517); +INSERT INTO `spell_affect` VALUES + (37517,0,0,0,0,0,0,0x0000014D2A600CEF,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12866,12865,12864,12863,12325); +INSERT INTO `spell_affect` VALUES + (12866,0,0,0,0,0,0,0x0000000000000000,0), + (12865,0,0,0,0,0,0,0x0000000000000000,0), + (12864,0,0,0,0,0,0,0x0000000000000000,0), + (12863,0,0,0,0,0,0,0x0000000000000000,0), + (12325,0,0,0,0,0,0,0x0000000000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (35446,35448,35449,35450,35451); +INSERT INTO `spell_affect` VALUES + (35446,0,0,0,0,0,0,0x0000000002000000,0), + (35446,1,0,0,0,0,0,0x0000000002000000,0), + (35448,0,0,0,0,0,0,0x0000000002000000,0), + (35448,1,0,0,0,0,0,0x0000000002000000,0), + (35449,0,0,0,0,0,0,0x0000000002000000,0), + (35449,1,0,0,0,0,0,0x0000000002000000,0), + (35450,0,0,0,0,0,0,0x0000000002000000,0), + (35450,1,0,0,0,0,0,0x0000000002000000,0), + (35451,0,0,0,0,0,0,0x0000000002000000,0), + (35451,1,0,0,0,0,0,0x0000000002000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38407); +INSERT INTO `spell_affect` VALUES + (38407,0,0,0,0,0,0,0x0000000100000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28842); +INSERT INTO `spell_affect` VALUES + (28842,0,0,0,0,0,0,0x0000000100004440,0); diff --git a/sql/updates/0.10/5039_mangos_spell_proc_event.sql b/sql/updates/0.10/5039_mangos_spell_proc_event.sql new file mode 100644 index 000000000..785d9deab --- /dev/null +++ b/sql/updates/0.10/5039_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (21890); +INSERT INTO `spell_proc_event` VALUES + (21890,0,0,0,4,0x0000036C2A764EEF,0x00004001,0); diff --git a/sql/updates/0.10/5064_mangos_spell_proc_event.sql b/sql/updates/0.10/5064_mangos_spell_proc_event.sql new file mode 100644 index 000000000..67e395a3e --- /dev/null +++ b/sql/updates/0.10/5064_mangos_spell_proc_event.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (31233,31239,31240,31241,31242); +INSERT INTO `spell_proc_event` VALUES + (31233,0,0,0,8,0x00000009003E0000,0x00020000,0), + (31239,0,0,0,8,0x00000009003E0000,0x00020000,0), + (31240,0,0,0,8,0x00000009003E0000,0x00020000,0), + (31241,0,0,0,8,0x00000009003E0000,0x00020000,0), + (31242,0,0,0,8,0x00000009003E0000,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37168); +INSERT INTO `spell_proc_event` VALUES + (37168,0,0,0,8,0x00000009003E0000,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (26107); +INSERT INTO `spell_proc_event` VALUES + (26107,0,0,0,7,0x0000008000800000,0xC4000000,0); diff --git a/sql/updates/0.10/5070_mangos_spell_proc_event.sql b/sql/updates/0.10/5070_mangos_spell_proc_event.sql new file mode 100644 index 000000000..312fdac44 --- /dev/null +++ b/sql/updates/0.10/5070_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (5301,13358,16092); +INSERT INTO `spell_proc_event` VALUES + ( 5301,0,0,0,0,0x0000000000000000,0x00000000,0), + (13358,0,0,0,0,0x0000000000000000,0x00000000,0), + (16092,0,0,0,0,0x0000000000000000,0x00000000,0); diff --git a/sql/updates/0.10/5072_mangos_spell_proc_event.sql b/sql/updates/0.10/5072_mangos_spell_proc_event.sql new file mode 100644 index 000000000..522c451ba --- /dev/null +++ b/sql/updates/0.10/5072_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (12328,18765); +INSERT INTO `spell_proc_event` VALUES + (12328,0,0,0,0,0x0000000000000000,0xC4000001,0), + (18765,0,0,0,0,0x0000000000000000,0xC4000001,0); diff --git a/sql/updates/0.10/5075_mangos_spell_proc_event.sql b/sql/updates/0.10/5075_mangos_spell_proc_event.sql new file mode 100644 index 000000000..680b08c01 --- /dev/null +++ b/sql/updates/0.10/5075_mangos_spell_proc_event.sql @@ -0,0 +1,34 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (13877,33735); +INSERT INTO `spell_proc_event` VALUES + (13877,0,0,0,0,0x0000000000000000,0xC4000001,0), + (33735,0,0,0,0,0x0000000000000000,0xC4000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (12966,12967,12968,12969,12970,16257,16277,16278,16279,16280,17687); +INSERT INTO `spell_proc_event` VALUES + (12966,0,0,0,0,0x0000000000000000,0xC4000001,0), + (12967,0,0,0,0,0x0000000000000000,0xC4000001,0), + (12968,0,0,0,0,0x0000000000000000,0xC4000001,0), + (12969,0,0,0,0,0x0000000000000000,0xC4000001,0), + (12970,0,0,0,0,0x0000000000000000,0xC4000001,0), + (16257,0,0,0,0,0x0000000000000000,0xC4000001,0), + (16277,0,0,0,0,0x0000000000000000,0xC4000001,0), + (16278,0,0,0,0,0x0000000000000000,0xC4000001,0), + (16279,0,0,0,0,0x0000000000000000,0xC4000001,0), + (16280,0,0,0,0,0x0000000000000000,0xC4000001,0), + (17687,0,0,0,0,0x0000000000000000,0xC4000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (40353); +INSERT INTO `spell_proc_event` VALUES + (40353,0,0,0,0,0x0000000000000000,0xC4000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (29448,35205); +INSERT INTO `spell_proc_event` VALUES + (29448,0,0,0,0,0x0000000000000000,0xC4000001,0), + (35205,0,0,0,0,0x0000000000000000,0xC4000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (1328); +INSERT INTO `spell_proc_event` VALUES + (1328,0,0,0,0,0x0000000000000000,0xC4000001,0); + + + diff --git a/sql/updates/0.10/5084_mangos_command.sql b/sql/updates/0.10/5084_mangos_command.sql new file mode 100644 index 000000000..7c280620e --- /dev/null +++ b/sql/updates/0.10/5084_mangos_command.sql @@ -0,0 +1,8 @@ +DELETE FROM command WHERE name IN ('createguild','guild create','guild delete','guild invite','guild rank','guild uninvite'); + +INSERT INTO `command` VALUES +('guild create',2,'Syntax: .guild create $GuildLeaderName $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName as leader.'), +('guild delete',2,'Syntax: .guild delete $GuildName\r\n\r\nDelete guild $GuildName.'), +('guild invite',2,'Syntax: .guild invite $CharacterName $GuildName\r\n\r\nAdd $CharacterName into a guild $GuildName.'), +('guild rank',2,'Syntax: .guild rank $CharacterName #Rank\r\n\r\nSet for $CharacterName rank #Rank in a guild.'), +('guild uninvite',2,'Syntax: .guild uninvite $CharacterName\r\n\r\nRemove $CharacterName from a guild.'); diff --git a/sql/updates/0.10/5085_mangos_spell_affect.sql b/sql/updates/0.10/5085_mangos_spell_affect.sql new file mode 100644 index 000000000..f81ddc515 --- /dev/null +++ b/sql/updates/0.10/5085_mangos_spell_affect.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (16179,16214,16215,16216,16217); +INSERT INTO `spell_affect` VALUES +(16179,0,0,0,0,0,0,0x00000000000000C0,0), +(16214,0,0,0,0,0,0,0x00000000000000C0,0), +(16215,0,0,0,0,0,0,0x00000000000000C0,0), +(16216,0,0,0,0,0,0,0x00000000000000C0,0), +(16217,0,0,0,0,0,0,0x00000000000000C0,0); diff --git a/sql/updates/0.10/5087_mangos_spell_affect.sql b/sql/updates/0.10/5087_mangos_spell_affect.sql new file mode 100644 index 000000000..c39869832 --- /dev/null +++ b/sql/updates/0.10/5087_mangos_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (20175); +INSERT INTO `spell_affect` VALUES + (20175,0,0,0,0,0,0,0x0000000000000080,0), + (20175,1,0,0,0,0,0,0x0000000000000010,0); diff --git a/sql/updates/0.10/5088_mangos_spell_proc_event.sql b/sql/updates/0.10/5088_mangos_spell_proc_event.sql new file mode 100644 index 000000000..b5c03ceb0 --- /dev/null +++ b/sql/updates/0.10/5088_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (17106,17107,17108); +INSERT INTO `spell_proc_event` VALUES + (17106,0,0,0,7,0x0000000000080000,0x00004000,0), + (17107,0,0,0,7,0x0000000000080000,0x00004000,0), + (17108,0,0,0,7,0x0000000000080000,0x00004000,0); diff --git a/sql/updates/0.10/5092_mangos_item_template.sql b/sql/updates/0.10/5092_mangos_item_template.sql new file mode 100644 index 000000000..91bf982dc --- /dev/null +++ b/sql/updates/0.10/5092_mangos_item_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `item_template` + ADD `Duration` int(11) NOT NULL DEFAULT '0' COMMENT 'Duration in seconds. Negative value means realtime, postive value ingame time'; diff --git a/sql/updates/0.10/5097_mangos_skill_extra_item_template.sql b/sql/updates/0.10/5097_mangos_skill_extra_item_template.sql new file mode 100644 index 000000000..ef417ff60 --- /dev/null +++ b/sql/updates/0.10/5097_mangos_skill_extra_item_template.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS `skill_extra_item_template`; +CREATE TABLE `skill_extra_item_template` ( + `spellId` int(11) unsigned NOT NULL default '0' COMMENT 'SpellId of the item creation spell', + `requiredSpecialization` int(11) unsigned NOT NULL default '0' COMMENT 'Specialization spell id', + `additionalCreateChance` float NOT NULL default '0' COMMENT 'chance to create add', + `additionalMaxNum` int(11) unsigned NOT NULL default '0' COMMENT 'max num of adds', + + PRIMARY KEY (`spellId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Specialization System'; diff --git a/sql/updates/0.10/5106_mangos_spell_chain.sql b/sql/updates/0.10/5106_mangos_spell_chain.sql new file mode 100644 index 000000000..2ce95bc05 --- /dev/null +++ b/sql/updates/0.10/5106_mangos_spell_chain.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (26790,27028,28029,28596,28695,28897,29354,29844,30350,32549,32678,33095,33359); +INSERT INTO `spell_chain` (`spell_id`, `prev_spell`, `first_spell`, `rank`) VALUES +(26790,12180,3908,5), +(27028,10846,3273,5), +(28029,13920,7411,5), +(28596,11611,2259,5), +(28695,11993,2366,5), +(28897,28895,25229,5), +(29354,10248,2575,5), +(29844,9785,2018,5), +(30350,12656,4036,5), +(32549,10662,2108,5), +(32678,10768,8613,5), +(33095,18248,7620,5), +(33359,18260,2550,5); diff --git a/sql/updates/0.10/5108_characters.sql b/sql/updates/0.10/5108_characters.sql new file mode 100644 index 000000000..d679d7790 --- /dev/null +++ b/sql/updates/0.10/5108_characters.sql @@ -0,0 +1,58 @@ +ALTER TABLE `guild` ADD COLUMN `BankMoney` bigint(20) NOT NULL DEFAULT 0 AFTER `createdate`; +ALTER TABLE `guild_rank` ADD COLUMN `BankMoneyPerDay` int(11) unsigned NOT NULL default '0' AFTER `rights`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeMoney` int(11) unsigned NOT NULL DEFAULT '0' AFTER `OFFnote`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemMoney` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeMoney`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeTab0` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankRemMoney`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemSlotsTab0` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeTab0`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeTab1` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankRemSlotsTab0`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemSlotsTab1` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeTab1`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeTab2` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankRemSlotsTab1`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemSlotsTab2` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeTab2`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeTab3` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankRemSlotsTab2`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemSlotsTab3` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeTab3`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeTab4` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankRemSlotsTab3`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemSlotsTab4` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeTab4`; +ALTER TABLE `guild_member` ADD COLUMN `BankResetTimeTab5` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankRemSlotsTab4`; +ALTER TABLE `guild_member` ADD COLUMN `BankRemSlotsTab5` int(11) unsigned NOT NULL DEFAULT '0' AFTER `BankResetTimeTab5`; + +DROP TABLE IF EXISTS `guild_bank_item`; +CREATE TABLE `guild_bank_item` ( + `guildid` int(11) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `SlotId` tinyint(3) unsigned NOT NULL default '0', + `item_guid` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`tabid`,`slotid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `guild_bank_tab`; +CREATE TABLE `guild_bank_tab` ( + `guildid` int(11) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `TabName` varchar(100) NOT NULL default '', + `TabIcon` varchar(100) NOT NULL default '', + PRIMARY KEY (`guildid`,`TabId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `guild_bank_right`; +CREATE TABLE `guild_bank_right` ( + `guildid` int(11) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `rid` int(11) unsigned NOT NULL default '0', + `Right` tinyint(3) unsigned NOT NULL default '0', + `SlotPerDay` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`TabId`,`rid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `guild_bank_eventlog`; +CREATE TABLE `guild_bank_eventlog` ( + `guildid` int(11) unsigned NOT NULL default '0', + `LogGuid` int(11) unsigned NOT NULL default '0', + `LogEntry` tinyint(1) unsigned NOT NULL default '0', + `TabId` tinyint(1) unsigned NOT NULL default '0', + `PlayerGuid` int(11) unsigned NOT NULL default '0', + `ItemOrMoney` int(11) unsigned NOT NULL default '0', + `ItemStackCount` tinyint(3) unsigned NOT NULL default '0', + `DestTabId` tinyint(1) unsigned NOT NULL default '0', + `TimeStamp` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`LogGuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.10/5119_mangos_quest_template.sql b/sql/updates/0.10/5119_mangos_quest_template.sql new file mode 100644 index 000000000..5769f7719 --- /dev/null +++ b/sql/updates/0.10/5119_mangos_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` + ADD `RepObjectiveFaction` int(10) unsigned NOT NULL default '0' AFTER `RequiredSkillValue`, + ADD `RepObjectiveValue` int(10) NOT NULL default '0' AFTER `RepObjectiveFaction`; \ No newline at end of file diff --git a/sql/updates/0.10/5120_mangos_spell_chain.sql b/sql/updates/0.10/5120_mangos_spell_chain.sql new file mode 100644 index 000000000..c0bef0f2f --- /dev/null +++ b/sql/updates/0.10/5120_mangos_spell_chain.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (9787,9788,17039,17040,17041,10656,10658,10660,20219,20222,26797,26798,26801); +INSERT INTO `spell_chain` (`spell_id`, `prev_spell`, `first_spell`, `rank`) VALUES +(9787,29844,2018,6), +(9788,29844,2018,6), +(17039,9787,2018,7), +(17040,9787,2018,7), +(17041,9787,2018,7), +(10656,32549,2108,6), +(10658,32549,2108,6), +(10660,32549,2108,6), +(20219,30350,4036,6), +(20222,30350,4036,6), +(26797,26790,3908,6), +(26798,26790,3908,6), +(26801,26790,3908,6); diff --git a/sql/updates/0.10/5121_mangos_spell_affect.sql b/sql/updates/0.10/5121_mangos_spell_affect.sql new file mode 100644 index 000000000..7f79fe199 --- /dev/null +++ b/sql/updates/0.10/5121_mangos_spell_affect.sql @@ -0,0 +1,33 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (11071,12496); +INSERT INTO `spell_affect` VALUES + (11071,0,0,0,0,0,0,0x0000000000100000,0), + (12496,0,0,0,0,0,0,0x0000000000100000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16578,16579,16580,16581,16582); +INSERT INTO `spell_affect` VALUES + (16578,0,0,0,0,0,0,0x0000000000000003,0), + (16579,0,0,0,0,0,0,0x0000000000000003,0), + (16580,0,0,0,0,0,0,0x0000000000000003,0), + (16581,0,0,0,0,0,0,0x0000000000000003,0), + (16582,0,0,0,0,0,0,0x0000000000000003,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16194,16218,16219,16220,16221); +INSERT INTO `spell_affect` VALUES + (16194,0,0,0,0,0,0,0x00000000000001C3,0), + (16218,0,0,0,0,0,0,0x00000000000001C3,0), + (16219,0,0,0,0,0,0,0x00000000000001C3,0), + (16220,0,0,0,0,0,0,0x00000000000001C3,0), + (16221,0,0,0,0,0,0,0x00000000000001C3,0); + +DELETE FROM spell_affect WHERE entry IN (16934,16935,16936,16937,16938); +INSERT INTO `spell_affect` VALUES + (16934,0,0,0,0,0,0,0x0010004000000800,0), + (16934,1,0,0,0,0,0,0x0000040000001000,0), + (16935,0,0,0,0,0,0,0x0010004000000800,0), + (16935,1,0,0,0,0,0,0x0000040000001000,0), + (16936,0,0,0,0,0,0,0x0010004000000800,0), + (16936,1,0,0,0,0,0,0x0000040000001000,0), + (16937,0,0,0,0,0,0,0x0010004000000800,0), + (16937,1,0,0,0,0,0,0x0000040000001000,0), + (16938,0,0,0,0,0,0,0x0010004000000800,0), + (16938,1,0,0,0,0,0,0x0000040000001000,0); diff --git a/sql/updates/0.10/5123_mangos_spell_proc_event.sql b/sql/updates/0.10/5123_mangos_spell_proc_event.sql new file mode 100644 index 000000000..df839fcd1 --- /dev/null +++ b/sql/updates/0.10/5123_mangos_spell_proc_event.sql @@ -0,0 +1,27 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34860,34859,34753); +INSERT INTO `spell_proc_event` VALUES + (34860,0,0,0,6,0x0000000000001800,0x08000000,0), + (34859,0,0,0,6,0x0000000000001800,0x08000000,0), + (34753,0,0,0,6,0x0000000000001800,0x08000000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (45244,45243,45234); +INSERT INTO `spell_proc_event` VALUES + (45244,0,0,0,0,0x0000000000000000,0x00842000,0), + (45243,0,0,0,0,0x0000000000000000,0x00842000,0), + (45234,0,0,0,0,0x0000000000000000,0x00842000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (35083); +INSERT INTO `spell_proc_event` VALUES + (35083,0,0,0,0,0x0000000000000000,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (35086); +INSERT INTO `spell_proc_event` VALUES + (35086,0,0,0,0,0x0000000000000000,0x08020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (35080); +INSERT INTO `spell_proc_event` VALUES + (35080,0,0,0,0,0x0000000000000000,0x00000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (35077); +INSERT INTO `spell_proc_event` VALUES + (35077,0,0,0,0,0x0000000000000000,0x00008000,0); diff --git a/sql/updates/0.10/5128_mangos_spell_proc_event.sql b/sql/updates/0.10/5128_mangos_spell_proc_event.sql new file mode 100644 index 000000000..fa48a51d0 --- /dev/null +++ b/sql/updates/0.10/5128_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (24949,34082); +INSERT INTO `spell_proc_event` VALUES + (24949,0,0,0,0,0x0000000000000000,0x00000000,0), + (34082,0,0,0,0,0x0000000000000000,0x00000000,0); diff --git a/sql/updates/0.10/5130_mangos_spell_proc_event.sql b/sql/updates/0.10/5130_mangos_spell_proc_event.sql new file mode 100644 index 000000000..73c1bc5e2 --- /dev/null +++ b/sql/updates/0.10/5130_mangos_spell_proc_event.sql @@ -0,0 +1,53 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (21063,27539,28764,33493,38196); +INSERT INTO `spell_proc_event` VALUES + (21063,0,0,0,0,0x0000000000000000,0x00008000,0), + (27539,0,0,0,0,0x0000000000000000,0x00100000,0), + (28764,0,0,0,0,0x0000000000000000,0x00100000,0), + (33493,0,0,0,0,0x0000000000000000,0x00000002,0), + (38196,0,0,0,0,0x0000000000000000,0x00000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (29441,29444,29445,29446,29447); +INSERT INTO `spell_proc_event` VALUES + (29441,0,0,0,0,0x0000000000000000,0x01000000,0), + (29444,0,0,0,0,0x0000000000000000,0x01000000,0), + (29445,0,0,0,0,0x0000000000000000,0x01000000,0), + (29446,0,0,0,0,0x0000000000000000,0x01000000,0), + (29447,0,0,0,0,0x0000000000000000,0x01000000,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (27243); +INSERT INTO `spell_proc_event` VALUES + (27243,0,0,0,0,0x0000000000000000,0x00008000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (40438); +INSERT INTO `spell_proc_event` VALUES + (40438,0,0,0,6,0x0000000000008010,0x08020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (26169); +INSERT INTO `spell_proc_event` VALUES + (26169,0,0,0,0,0x0000000000000000,0x08000000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (40442); +INSERT INTO `spell_proc_event` VALUES + (40442,0,0,0,7,0x0000044000000014,0x00004000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (28719); +INSERT INTO `spell_proc_event` VALUES + (28719,0,0,0,7,0x0000000000000020,0x10000000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (28847); +INSERT INTO `spell_proc_event` VALUES + (28847,0,0,0,7,0x0000000000000020,0x00004000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37288,37295); +INSERT INTO `spell_proc_event` VALUES + (37288,0,0,0,0,0x0000000000000000,0x08000000,0), + (37295,0,0,0,0,0x0000000000000000,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (31892); +INSERT INTO `spell_proc_event` VALUES + (31892,0,0,0,0,0x0000000000000000,0x00000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (40470); +INSERT INTO `spell_proc_event` VALUES + (40470,0,0,0,10,0x0000000000806000,0x00004000,0); diff --git a/sql/updates/0.10/5146_mangos_spell_proc_event.sql b/sql/updates/0.10/5146_mangos_spell_proc_event.sql new file mode 100644 index 000000000..638d22c71 --- /dev/null +++ b/sql/updates/0.10/5146_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (37169,43745); +INSERT INTO `spell_proc_event` VALUES + (37169,0,0,0,8,0x0000000000020000,0x00000000,0), + (43745,0,0,0,10,0x0000020000000000,0x00020000,0); + diff --git a/sql/updates/0.10/5147_mangos_spell_learn_spell.sql b/sql/updates/0.10/5147_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..0d3708df7 --- /dev/null +++ b/sql/updates/0.10/5147_mangos_spell_learn_spell.sql @@ -0,0 +1,3 @@ +INSERT INTO `spell_learn_spell` ( `entry` , `SpellID` , `IfNoSpell` ) VALUES +('17002', '24867', '0'), +('24866', '24864', '0'); diff --git a/sql/updates/0.10/5156_mangos_spell_affect.sql b/sql/updates/0.10/5156_mangos_spell_affect.sql new file mode 100644 index 000000000..f4560987c --- /dev/null +++ b/sql/updates/0.10/5156_mangos_spell_affect.sql @@ -0,0 +1,85 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (43339); +INSERT INTO `spell_affect` VALUES + (43339,0,0,0,0,0,0,0x0000000090100000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16246); +INSERT INTO `spell_affect` VALUES + (16246,0,0,0,0,0,0,0x0000000090100003,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38434); +INSERT INTO `spell_affect` VALUES + (38434,0,0,0,0,0,0,0x0000000000000100,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16089); +INSERT INTO `spell_affect` VALUES + (16089,0,0,0,0,0,0,0x00000004D33005C7,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16166); +INSERT INTO `spell_affect` VALUES + (16166,0,0,0,0,0,0,0x00000000901001C3,0), + (16166,1,0,0,0,0,0,0x00000000901001C3,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (29063); +INSERT INTO `spell_affect` VALUES + (29063,0,0,0,0,0,0,0x00000000000009C3,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37241); +INSERT INTO `spell_affect` VALUES + (37241,0,0,0,0,0,0,0x0000020000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38435); +INSERT INTO `spell_affect` VALUES + (38435,0,0,0,0,0,0,0x0000000000000080,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38436); +INSERT INTO `spell_affect` VALUES + (38436,0,0,0,0,0,0,0x0000000000000001,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (34318,37209); +INSERT INTO `spell_affect` VALUES + (34318,0,0,0,0,0,0,0x0000002000000000,0), + (37209,0,0,0,0,0,0,0x0000002000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (21895); +INSERT INTO `spell_affect` VALUES + (21895,0,0,0,0,0,0,0x000000000403E000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (39805); +INSERT INTO `spell_affect` VALUES + (39805,0,0,0,0,0,0,0x0000000000000003,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30812,30813,30814); +INSERT INTO `spell_affect` VALUES + (30812,0,0,0,0,0,0,0x00000C78B018141B,0), + (30813,0,0,0,0,0,0,0x00000C78B018141B,0), + (30814,0,0,0,0,0,0,0x00000C78B018141B,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38501); +INSERT INTO `spell_affect` VALUES + (38501,0,0,0,0,0,0,0x0000000000000080,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (36591); +INSERT INTO `spell_affect` VALUES + (36591,1,0,0,0,0,0,0x00000410901005C3,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28818); +INSERT INTO `spell_affect` VALUES + (28818,0,0,0,0,0,0,0x0000000020081018,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16173,16222,16223,16224,16225); +INSERT INTO `spell_affect` VALUES + (16173,0,0,0,0,0,0,0x0000000020081018,0), + (16222,0,0,0,0,0,0,0x0000000020081018,0), + (16223,0,0,0,0,0,0,0x0000000020081018,0), + (16224,0,0,0,0,0,0,0x0000000020081018,0), + (16225,0,0,0,0,0,0,0x0000000020081018,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16189); +INSERT INTO `spell_affect` VALUES + (16189,0,0,0,0,0,0,0x000001000403E000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (39950); +INSERT INTO `spell_affect` VALUES + (39950,0,0,0,0,0,0,0x0000000000000040,0); + + diff --git a/sql/updates/0.10/5156_mangos_spell_proc_event.sql b/sql/updates/0.10/5156_mangos_spell_proc_event.sql new file mode 100644 index 000000000..0941e5464 --- /dev/null +++ b/sql/updates/0.10/5156_mangos_spell_proc_event.sql @@ -0,0 +1,9 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (33746,40463); +INSERT INTO `spell_proc_event` VALUES + (33746,0,0,0,0,0x0000000000000000,0x00000004,0), + (40463,0,0,0,11,0x0000001000000081,0x00004001,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (43338); +INSERT INTO `spell_proc_event` VALUES + (43338,0,0,0,0,0x0000000000000000,0x00001000,0); diff --git a/sql/updates/0.10/5158_mangos_spell_affect.sql b/sql/updates/0.10/5158_mangos_spell_affect.sql new file mode 100644 index 000000000..94867e6a4 --- /dev/null +++ b/sql/updates/0.10/5158_mangos_spell_affect.sql @@ -0,0 +1 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (36591); diff --git a/sql/updates/0.10/5159_characters_guild_bank_eventlog.sql b/sql/updates/0.10/5159_characters_guild_bank_eventlog.sql new file mode 100644 index 000000000..e098bd9d9 --- /dev/null +++ b/sql/updates/0.10/5159_characters_guild_bank_eventlog.sql @@ -0,0 +1,3 @@ +ALTER TABLE `guild_bank_eventlog` + ADD KEY `guildid_key` (`guildid`); + diff --git a/sql/updates/0.10/5159_characters_guild_bank_item.sql b/sql/updates/0.10/5159_characters_guild_bank_item.sql new file mode 100644 index 000000000..364c6ea2d --- /dev/null +++ b/sql/updates/0.10/5159_characters_guild_bank_item.sql @@ -0,0 +1,9 @@ +ALTER TABLE `guild_bank_item` + ADD COLUMN `item_entry` int(11) unsigned NOT NULL default '0', + ADD KEY `item_guid_key` (`item_guid`), + ADD KEY `guildid_key` (`guildid`); + +UPDATE `guild_bank_item` ,`item_instance` + SET `guild_bank_item`.`item_entry` = SUBSTRING_INDEX(SUBSTRING_INDEX(`item_instance`.`data`, ' ', 4), ' ', -1) + WHERE `guild_bank_item`.`item_guid` = `item_instance`.`guid`; + diff --git a/sql/updates/0.10/5159_characters_guild_bank_right.sql b/sql/updates/0.10/5159_characters_guild_bank_right.sql new file mode 100644 index 000000000..6d64b1599 --- /dev/null +++ b/sql/updates/0.10/5159_characters_guild_bank_right.sql @@ -0,0 +1,3 @@ +ALTER TABLE `guild_bank_right` + ADD KEY `guildid_key` (`guildid`); + diff --git a/sql/updates/0.10/5159_characters_guild_bank_tab.sql b/sql/updates/0.10/5159_characters_guild_bank_tab.sql new file mode 100644 index 000000000..6ab0de6f4 --- /dev/null +++ b/sql/updates/0.10/5159_characters_guild_bank_tab.sql @@ -0,0 +1,3 @@ +ALTER TABLE `guild_bank_tab` + ADD KEY `guildid_key` (`guildid`); + diff --git a/sql/updates/0.10/5159_characters_guild_memeber.sql b/sql/updates/0.10/5159_characters_guild_memeber.sql new file mode 100644 index 000000000..396f2417d --- /dev/null +++ b/sql/updates/0.10/5159_characters_guild_memeber.sql @@ -0,0 +1,5 @@ +ALTER TABLE `guild_member` + ADD KEY `guildid_key` (`guildid`), + ADD KEY `guildid_rank_key` (`guildid`,`rank`), + ADD KEY `guid_key` (`guid`); + diff --git a/sql/updates/0.10/5160_mangos_command.sql b/sql/updates/0.10/5160_mangos_command.sql new file mode 100644 index 000000000..807d969ee --- /dev/null +++ b/sql/updates/0.10/5160_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('info'); + +INSERT INTO `command` VALUES +('info',0,'Syntax: .info\r\n\r\nDisplay server version and the number of connected players.'); diff --git a/sql/updates/0.10/5163_mangos_spell_affect.sql b/sql/updates/0.10/5163_mangos_spell_affect.sql new file mode 100644 index 000000000..69676ce31 --- /dev/null +++ b/sql/updates/0.10/5163_mangos_spell_affect.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (16113,16114,16115,16116,16040,22804); +INSERT INTO `spell_affect` VALUES + (16113,0,0,0,0,0,0,0x0000000090100000,0), + (16114,0,0,0,0,0,0,0x0000000090100000,0), + (16115,0,0,0,0,0,0,0x0000000090100000,0), + (16116,0,0,0,0,0,0,0x0000000090100000,0), + (16040,0,0,0,0,0,0,0x0000000090100000,0), + (22804,0,0,0,0,0,0,0x0000000090100000,0); diff --git a/sql/updates/0.10/5163_mangos_spell_proc_event.sql b/sql/updates/0.10/5163_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d85b34446 --- /dev/null +++ b/sql/updates/0.10/5163_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (26119,43748); +INSERT INTO `spell_proc_event` VALUES + (26119,0,0,0,11,0x0000000090100003,0x00004000,0), + (43748,0,0,0,11,0x0000000090100000,0x00004000,0); diff --git a/sql/updates/0.10/5164_mangos_creature_movement.sql b/sql/updates/0.10/5164_mangos_creature_movement.sql new file mode 100644 index 000000000..d01d1cda4 --- /dev/null +++ b/sql/updates/0.10/5164_mangos_creature_movement.sql @@ -0,0 +1,5 @@ +ALTER TABLE `creature_movement` CHANGE COLUMN `text1` `text1` text; +ALTER TABLE `creature_movement` CHANGE COLUMN `text2` `text2` text; +ALTER TABLE `creature_movement` CHANGE COLUMN `text3` `text3` text; +ALTER TABLE `creature_movement` CHANGE COLUMN `text4` `text4` text; +ALTER TABLE `creature_movement` CHANGE COLUMN `text5` `text5` text; diff --git a/sql/updates/0.10/5165_mangos_mangos_string.sql b/sql/updates/0.10/5165_mangos_mangos_string.sql new file mode 100644 index 000000000..ceba771c8 --- /dev/null +++ b/sql/updates/0.10/5165_mangos_mangos_string.sql @@ -0,0 +1,468 @@ +-- +-- Table structure for table `mangos_string` +-- + +DROP TABLE IF EXISTS `mangos_string`; +CREATE TABLE `mangos_string` ( + `entry` int(11) unsigned NOT NULL default '0', + `content_default` text, + `content_loc1` text, + `content_loc2` text, + `content_loc3` text, + `content_loc4` text, + `content_loc5` text, + `content_loc6` text, + `content_loc7` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `mangos_string` +-- + +LOCK TABLES `mangos_string` WRITE; +/*!40000 ALTER TABLE `mangos_string` DISABLE KEYS */; +INSERT INTO `mangos_string` VALUES +(1,'You should select a character or a creature.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(2,'You should select a creature.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(5,'There is no help for that command',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(6,'There is no such command',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(7,'There is no such subcommand',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(8,'Command %s have subcommands:%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(9,'Commands available to you:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(10,'Incorrect syntax.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(11,'Your account level is: %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(12,'Number of users connected: %u (max since last restart: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(13,'Server uptime: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(14,'Player saved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(15,'All players saved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(16,'There are the following active GMs on this server:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(17,'There are no GMs currently logged in on this server.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(18,'Cannot do that while flying.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(19,'Cannot do that in Battlegrounds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(20,'Target is flying you can\'t do that.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(21,'%s is flying command failed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(22,'You are not mounted so you can\'t dismount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(23,'Cannot do that while fighting.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(24,'You used it recently.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(25,'Your password can\'t be longer than 16 characters (client limit), password not changed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(26,'The password was changed',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(27,'The new passwords do not match or the old password is wrong',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(28,'Your account is now locked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(29,'Your account is now unlocked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(30,', rank ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(31,' [known]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(3,'|cffff0000[System Message]:|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(4,'|cffff0000[Event Message]: %s|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(32,' [learn]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(33,' [passive]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(34,' [talent]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(35,' [active]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(36,' [complete]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(37,' (offline)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(38,'on',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(39,'off',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(40,'You are: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(41,'visible',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(42,'invisible',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(43,'done',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(44,'You',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(45,' ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(46,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(47,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(48,'UNKNOWN',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(49,'You must be at least level %u to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(50,'You must be at least level %u and have item %s to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(51,'Hello! Ready for some training?',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(100,'Global notify: ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\\nX: %f Y: %f Z: %f Orientation: %f\\ngrid[%u,%u]cell[%u,%u] InstanceID: %u\\n ZoneX: %f ZoneY: %f\\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(102,'%s is already being teleported.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(103,'You can summon a player to your instance only if he is in your party with you as leader.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(104,'You cannot go to the player\'s instance because you are in a party now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(105,'You can go to the player\'s instance while not being in his party only if your GM mode is on.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(106,'You can not go to player %s from instance to instance.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(107,'You can not summon player %s from instance to instance.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(108,'You are summoning %s%s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(109,'You are being summoned by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(110,'You are teleporting %s%s to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(111,'You are being teleported by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(112,'Player (%s) does not exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(113,'Appearing at %s\'s location.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(114,'%s is appearing to your location.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(115,'Incorrect values.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(116,'No character selected.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(117,'%s is not in a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(118,'You changed HP of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(119,'%s changed your HP to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(120,'You changed MANA of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(121,'%s changed your MANA to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(122,'You changed ENERGY of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(123,'%s changed your ENERGY to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(124,'Current energy: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(125,'You changed rage of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(126,'%s changed your rage to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(127,'You changed level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(128,'GUID %i, faction is %i, flags is %i, npcflag is %i, DY flag is %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(129,'Wrong faction: %u (not found in factiontemplate.dbc).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(130,'You changed GUID=%i \'s Faction to %i, flags to %i, npcflag to %i, dyflag to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(131,'You changed the spellflatid=%i, val= %i, mark =%i to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(132,'%s changed your spellflatid=%i, val= %i, mark =%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(133,'%s has access to all taxi nodes now (until logout).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(134,'%s has no more access to all taxi nodes now (only visited accessible).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(135,'%s has given you access to all taxi nodes (until logout).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(136,'%s has removed access to all taxi nodes (only visited still accessible).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(137,'You set all speeds to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(138,'%s set all your speeds to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(139,'You set the speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(140,'%s set your speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(141,'You set the swim speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(142,'%s set your swim speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(143,'You set the backwards run speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(144,'%s set your backwards run speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(145,'You set the fly speed to %2.2f from normal of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(146,'%s set your fly speed to %2.2f from normal.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(147,'You set the size %2.2f of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(148,'%s set your size to %2.2f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(149,'There is no such mount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(150,'You give a mount to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(151,'%s gave you a mount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(152,'USER1: %i, ADD: %i, DIF: %i\\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(153,'You take all copper of %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(154,'%s took you all of your copper.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(155,'You take %i copper from %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(156,'%s took %i copper from you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(157,'You give %i copper to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(158,'%s gave you %i copper.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(159,'You hear sound %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(160,'USER2: %i, ADD: %i, RESULT: %i\\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(161,'Removed bit %i in field %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(162,'Set bit %i in field %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(163,'Teleport location table is empty!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(164,'Teleport location not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(165,'Requires search parameter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(166,'There are no teleport locations matching your request.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(167,'No locations found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(168,'Locations found are:\\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(169,'Mail sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(200,'No selection.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(201,'Object GUID is: lowpart %u highpart %X',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(202,'The name was too long by %i characters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(203,'Error, name can only contain characters A-Z and a-z.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(204,'The subname was too long by %i characters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(205,'Not yet implemented',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(206,'Item \'%i\' \'%s\' added to list with maxcount \'%i\' and incrtime \'%i\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(207,'Item \'%i\' not found in database.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(208,'Item \'%i\' \'%s\' deleted from vendor list',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(209,'Item \'%i\' not found in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(210,'Item \'%i\' already in vendor list.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(211,'Spells of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(212,'Spells of %s will reset at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(213,'Talents of %s reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(214,'Talents of %s will reset at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(215,'Your spells have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(216,'Your talents have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(217,'Unknown case \'%s\' for .resetall command. Type full correct case name.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(218,'Spells will reset for all players at login. Strongly recommend re-login!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(219,'Talents will reset for all players at login. Strongly recommend re-login!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(220,'Creature (GUID: %u) No waypoint found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(221,'Creature (GUID: %u) Last waypoint not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(222,'Creature (GUID: %u) No waypoint found - used \'wpguid\'. Now trying to find it by its position...',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(223,'Creature (GUID: %u) No waypoints found - This is a MaNGOS db problem (single float).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(224,'Selected creature is ignored - provided GUID is used',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(225,'Creature (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(226,'You must select a visual waypoint.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(227,'No visual waypoints found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(228,'Could not create visual waypoint with creatureID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(229,'All visual waypoints removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(230,'Could not create waypoint-creature with ID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(231,'No GUID provided.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(232,'No waypoint number provided.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(233,'Argument required for \'%s\'.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(234,'Waypoint %i added to GUID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(235,'Waypoint %d added.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(236,'Waypoint changed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(237,'Waypoint %s modified.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(238,'WP export successfull.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(239,'No waypoints found inside the database.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(240,'File imported.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(241,'Waypoint removed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(242,'Warning: Could not delete WP from the world with ID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(243,'This happens if the waypoint is too far away from your char.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(244,'The WP is deleted from the database, but not from the world here.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(245,'They will disappear after a server restart.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(246,'Waypoint %d: Info for creature: %s, GUID: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(247,'Waittime: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(248,'Model %d: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(249,'Emote: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(250,'Spell: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(251,'Text %d: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(252,'AIScript: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(253,'Forced rename for player %s will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(254,'Forced rename for player %s (GUID #%u) will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(255,'Waypoint-Creature (GUID: %u) Not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(256,'Could not find NPC...',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(257,'Creature movement type set to \'%s\', waypoints removed (if any).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(258,'Creature movement type set to \'%s\', waypoints were not removed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(259,'Incorrect value, use on or off',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(260,'Value saved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(261,'Value saved, you may need to rejoin or clean your client cache.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(262,'Areatrigger ID %u not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(263,'Target map or coordinates is invalid (X: %f Y: %f MapId: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(264,'Zone coordinates is invalid (X: %f Y: %f AreaId: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(265,'Zone %u (%s) is part of instanceable map %u (%s)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(266,'Nothing found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(267,'Object not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(268,'Creature not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(269,'Warning: Mob found more than once - you will be teleported to the first one found in DB.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(270,'Creature Removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(271,'Creature moved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(272,'Creature (GUID:%u) must be on the same map as player!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(273,'Game Object (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(274,'Game Object (GUID: %u) has references in not found creature %u GO list, can\'t be deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(275,'Game Object (GUID: %u) removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(276,'Game Object (GUID: %u) turned',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(277,'Game Object (GUID: %u) moved',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(278,'You must select a vendor',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(279,'You must send id for item',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(283,'Player %s not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(287,'Creature (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(288,'Tickets count: %i show new tickets: %s\\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(289,'New ticket from %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(290,'Ticket of %s (Category: %i):\\n%s\\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(291,'New ticket show: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(292,'New ticket show: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(293,'Ticket %i doesn\'t exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(294,'All tickets deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(295,'Character %s ticket deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(296,'Ticket deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(297,'Spawn distance changed to: %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(298,'Spawn time changed to: %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(299,'The honor of %s was set to %u!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(300,'Your chat has been disabled for %u minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(301,'You have disabled %s\'s chat for %u minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(302,'Player\'s chat is already enabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(303,'Your chat has been enabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(304,'You have enabled %s\'s chat.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(401,'You change security level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(403,'You have low security level for this.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(404,'Creature movement disabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(405,'Creature movement enabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(406,'Weather can\'t be changed for this zone.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(407,'Weather system disabled at server.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(408,'%s is banned for %s. Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(409,'%s is banned permanently for %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(410,'%s %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(411,'%s unbanned.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(412,'There was an error removing the ban on %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(413,'There is no such account.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(414,'There is no such character.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(415,'There is no such IP in banlist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(416,'Account %s has never been banned',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(417,'Ban history for account %s:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(418,'Ban Date: %s Bantime: %s Still active: %s Reason: %s Set by: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(419,'Inf.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(420,'Never',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(421,'Yes',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(422,'No',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(423,'IP: %s\\nBan Date: %s\\nUnban Date: %s\\nRemaining: %s\\nReason: %s\\nSet by: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(424,'There is no matching IPban.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(425,'There is no matching account.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(426,'There is no banned account owning a character matching this part.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(427,'The following IPs match your pattern:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(428,'The following accounts match your query:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(429,'You learned many spells/skills.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(430,'You learned all spells for class.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(431,'You learned all talents for class.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(432,'You learned all languages.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(433,'You learned all craft skills and recipes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(434,'Could not find \'%s\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(435,'Invalid item id: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(436,'No items found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(437,'Invalid gameobject id: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(438,'Found items %u: %u ( inventory %u mail %u auction %u )',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(439,'Found gameobjects %u: %u ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(440,'Invalid creature id: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(441,'Found creatures %u: %u ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(442,'No area found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(443,'No item sets found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(444,'No skills found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(445,'No spells found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(446,'No quests found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(447,'No creatures found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(448,'No gameobjects found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(449,'Graveyard #%u doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(450,'Graveyard #%u already linked to zone #%u (current).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(451,'Graveyard #%u linked to zone #%u (current).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(452,'Graveyard #%u can\'t be linked to subzone or not existed zone #%u (internal error).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(453,'Graveyard can be linked to zone at another map only for all factions (no faction value).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(454,'No faction in Graveyard with id= #%u , fix your DB',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(455,'invalid team, please fix database',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(456,'any',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(457,'alliance',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(458,'horde',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(459,'Graveyard #%u (faction: %s) is nearest from linked to zone #%u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(460,'Zone #%u doesn\'t have linked graveyards.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(461,'Zone #%u doesn\'t have linked graveyards for faction: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(462,'Teleport location already exists!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(463,'Teleport location added.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(464,'Teleport location NOT added: database error.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(465,'Teleport location deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(466,'Teleport location NOT deleted: database error.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(467,'Target unit has %d auras:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(468,'id: %d eff: %d type: %d duration: %d maxduration: %d name: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(469,'Target unit has %d auras of type %d:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(470,'id: %d eff: %d name: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(471,'Quest %u not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(472,'Quest %u started from item. For correct work, please, add item to inventory and start quest in normal way: .additem %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(473,'Quest removed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(474,' [rewarded]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(475,' [complete]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(476,' [active]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(477,'%s\'s Fly Mode %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(478,'Opcode %u sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(479,'Character loaded successfully!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(480,'Failed to load the character!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(481,'Character dumped successfully!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(482,'Character dump failed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(483,'Spell %u broken and not allowed to cast or learn!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(484,'Skill %u (%s) for player %s set to %u and current maximum set to %u (without permanent (talent) bonuses).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(485,'Player %s must have skill %u (%s) before using this command.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(486,'Invalid skill id (%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(487,'You learned default GM spells/skills.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(488,'You already know that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(489,'Target(%s) already know that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(490,'%s doesn\'t know that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(491,'You already forgot that spell.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(492,'All spell cooldowns removed for %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(493,'Spell %u cooldown removed for %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(494,'Command : Additem, itemId = %i, amount = %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(495,'Command : Additemset, itemsetId = %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(496,'Removed itemID = %i, amount = %i from %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(497,'Cannot create item \'%i\' (amount: %i)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(498,'You need to provide a guild name!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(499,'Player not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(500,'Player already has a guild!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(501,'Guild not created! (already exists?)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(502,'No items from itemset \'%u\' found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(503,'The distance is: (3D) %f (2D) %f yards.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(504,'Item \'%i\' \'%s\' Item Slot %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(505,'Item \'%i\' doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(506,'Item \'%i\' \'%s\' Added to Slot %i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(507,'Item save failed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(508,'%d - owner: %s (guid: %u account: %u ) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(509,'%d - sender: %s (guid: %u account: %u ) receiver: %s (guid: %u account: %u ) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(510,'%d - owner: %s (guid: %u account: %u ) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(511,'Wrong link type!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(512,'%d - |cffffffff|Hitem:%d:0:0:0:0:0:0:0|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(513,'%d - |cffffffff|Hquest:%d|h[%s]|h|r %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(514,'%d - |cffffffff|Hcreature_entry:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(515,'%d - |cffffffff|Hcreature:%d|h[%s X:%f Y:%f Z:%f MapId:%d]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(516,'%d - |cffffffff|Hgameobject_entry:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(517,'%d - |cffffffff|Hgameobject:%d|h[%s X:%f Y:%f Z:%f MapId:%d]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(518,'%d - |cffffffff|Hitemset:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(519,'|cffffffff|Htele:%s|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(520,'%d - |cffffffff|Hspell:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(521,'%d - |cffffffff|Hskill:%d|h[%s]|h|r %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(522,'Game Object (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(523,'>> Game Object %s (GUID: %u) at %f %f %f. Orientation %f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(524,'Selected object:\\n%s\\nGUID: %u ID: %u\\nX: %f Y: %f Z: %f MapId: %u\\nOrientation: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(525,'>> Add Game Object \'%i\' (%s) (GUID: %i) added at \'%f %f %f\'.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(526,'%s (lowguid: %u) movement generators stack:',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(527,' Idle',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(528,' Random',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(529,' Waypoint',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(530,' Animal random',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(531,' Confused',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(532,' Targeted to player %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(533,' Targeted to creature %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(534,' Targeted to ',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(535,' Home movement to (X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(536,' Home movement used for player?!?',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(537,' Taxi flight',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(538,' Unknown movement generator (%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(539,'Player selected NPC\\nGUID: %u.\\nFaction: %u.\\nnpcFlags: %u.\\nEntry: %u.\\nDisplayID: %u (Native: %u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(540,'Level: %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(541,'Health (base): %u. (max): %u. (current): %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(542,'Field Flags: %u.\\nDynamic Flags: %u.\\nFaction Template: %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(543,'Loot: %u Pickpocket: %u Skinning: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(544,'Position: %f %f %f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(545,'*** Is a vendor!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(546,'*** Is a trainer!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(547,'InstanceID: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(548,'Player%s %s (guid: %u) Account: %s (id: %u) GMLevel: %u Last IP: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(549,'Played time: %s Level: %u Money: %ug%us%uc',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(550,'Command .pinfo doesn\'t support \'rep\' option for offline players.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(551,'%s has explored all zones now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(552,'%s has no more explored zones.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(553,'%s has explored all zones for you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(554,'%s has hidden all zones from you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(555,'Hover enabled',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(556,'Hover disabled',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(557,'You have been leveled up (%i)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(558,'You have been leveled down (%i)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(559,'Your level progress has been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(560,'The area has been set as explored.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(561,'The area has been set as not explored.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(562,'GUID=%i \'s updateIndex: %i, value: %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(563,'You change GUID=%i \'s UpdateIndex: %i value to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(564,'The value index %u is too big to %u(count: %u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(565,'Set %u uint32 Value:[OPCODE]:%u [VALUE]:%u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(566,'You Set %u Field:%u to uint32 Value: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(567,'Set %u float Value:[OPCODE]:%u [VALUE]:%f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(568,'You Set %u Field:%i to float Value: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(569,'Get %u uint32 Value:[OPCODE]:%u [VALUE]:%u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(570,'The uint32 value of %u in %u is: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(571,'Get %u float Value:[OPCODE]:%u [VALUE]:%f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(572,'The float of %u value in %u is: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(573,'.Set32Bit:[OPCODE]:%u [VALUE]:%u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(574,'You set Bit of Field:%u to Value: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(575,'.Mod32Value:[OPCODE]:%u [VALUE]:%i',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(576,'You modified the value of Field:%u to Value: %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(577,'You are now invisible.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(578,'You are now visible.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(600,'The Alliance wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(601,'The Horde wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(602,'The battle for Warsong Gulch begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(603,'The battle for Warsong Gulch begins in 30 seconds. Prepare yourselves!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(604,'Let the battle for Warsong Gulch begin!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(605,'$n captured the Horde flag!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(606,'$n captured the Alliance flag!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(607,'The Horde flag was dropped by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(608,'The Alliance Flag was dropped by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(609,'The Alliance Flag was returned to its base by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(610,'The Horde flag was returned to its base by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(611,'The Horde flag was picked up by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(612,'The Alliance Flag was picked up by $n!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(613,'The flags are now placed at their bases.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(650,'Alliance',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(651,'Horde',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(652,'stables',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(653,'blacksmith',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(654,'farm',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(655,'lumber mill',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(656,'mine',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(657,'The %s has taken the %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(658,'$n has defended the %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(659,'$n has assaulted the %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(660,'$n claims the %s! If left unchallenged, the %s will control it in 1 minute!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(661,'The Battle for Arathi Basin begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(662,'The Battle for Arathi Basin begins in 30 seconds. Prepare yourselves!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(663,'The Battle for Arathi Basin has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(664,'The Alliance has gathered $1776W resources, and is near victory!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(665,'The Horde has gathered $1777W resources, and is near victory!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(700,'You must be level %u to form an arena team',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(701,'One minute until the Arena battle begins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(702,'Thirty seconds until the Arena battle begins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(703,'Fifteen seconds until the Arena battle begins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(704,'The Arena battle has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(705,'You must wait %s before speaking again.',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; +UNLOCK TABLES; diff --git a/sql/updates/0.10/5166_mangos_mangos_string.sql b/sql/updates/0.10/5166_mangos_mangos_string.sql new file mode 100644 index 000000000..f50f89830 --- /dev/null +++ b/sql/updates/0.10/5166_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM `mangos_string` WHERE `entry`= 706; +INSERT INTO `mangos_string` VALUES +(706,'This item(s) have problems with equipping/storing in inventory.',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5172_mangos_mangos_string.sql b/sql/updates/0.10/5172_mangos_mangos_string.sql new file mode 100644 index 000000000..a9423d997 --- /dev/null +++ b/sql/updates/0.10/5172_mangos_mangos_string.sql @@ -0,0 +1,12 @@ +DELETE FROM `mangos_string` WHERE `entry` in (101,152,160,168,288,290,423,524,539,542); +INSERT INTO `mangos_string` VALUES +(101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f\ngrid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(152,'USER1: %i, ADD: %i, DIF: %i\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(160,'USER2: %i, ADD: %i, RESULT: %i\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(168,'Locations found are:\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(288,'Tickets count: %i show new tickets: %s\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(290,'Ticket of %s (Category: %i):\n%s\n',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(423,'IP: %s\nBan Date: %s\nUnban Date: %s\nRemaining: %s\nReason: %s\nSet by: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(524,'Selected object:\n%s\nGUID: %u ID: %u\nX: %f Y: %f Z: %f MapId: %u\nOrientation: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(539,'Player selected NPC\nGUID: %u.\nFaction: %u.\nnpcFlags: %u.\nEntry: %u.\nDisplayID: %u (Native: %u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(542,'Field Flags: %u.\nDynamic Flags: %u.\nFaction Template: %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5180_mangos_spell_affect.sql b/sql/updates/0.10/5180_mangos_spell_affect.sql new file mode 100644 index 000000000..c4016284c --- /dev/null +++ b/sql/updates/0.10/5180_mangos_spell_affect.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (12303,12788,12789); +INSERT INTO `spell_affect` VALUES + (12303,1,0,0,0,0,0,0x0000100000000000,0), + (12788,1,0,0,0,0,0,0x0000100000000000,0), + (12789,1,0,0,0,0,0,0x0000100000000000,0); + diff --git a/sql/updates/0.10/5181_mangos_mangos_string.sql b/sql/updates/0.10/5181_mangos_mangos_string.sql new file mode 100644 index 000000000..492533f85 --- /dev/null +++ b/sql/updates/0.10/5181_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM `mangos_string` WHERE `entry` = 548; +INSERT INTO `mangos_string` VALUES + (548,'Player%s %s (guid: %u) Account: %s (id: %u) GMLevel: %u Last IP: %s Latency: %ums',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5185_mangos_spell_proc_event.sql b/sql/updates/0.10/5185_mangos_spell_proc_event.sql new file mode 100644 index 000000000..79c506857 --- /dev/null +++ b/sql/updates/0.10/5185_mangos_spell_proc_event.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (20185,20344,20345,20346,27162); +INSERT INTO `spell_proc_event` VALUES + (20185,0,0,0,0,0x0000000000000000,0x00000002,0), + (20344,0,0,0,0,0x0000000000000000,0x00000002,0), + (20345,0,0,0,0,0x0000000000000000,0x00000002,0), + (20346,0,0,0,0,0x0000000000000000,0x00000002,0), + (27162,0,0,0,0,0x0000000000000000,0x00000002,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (20186,20354,20355,27164); +INSERT INTO `spell_proc_event` VALUES + (20186,0,0,0,0,0x0000000000000000,0x00100402,0), + (20354,0,0,0,0,0x0000000000000000,0x00100402,0), + (20355,0,0,0,0,0x0000000000000000,0x00100402,0), + (27164,0,0,0,0,0x0000000000000000,0x00100402,0); diff --git a/sql/updates/0.10/5191_mangos_spell_threat.sql b/sql/updates/0.10/5191_mangos_spell_threat.sql new file mode 100644 index 000000000..c7afd1738 --- /dev/null +++ b/sql/updates/0.10/5191_mangos_spell_threat.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_threat` WHERE `entry` = 2139; +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES +(2139, 300); \ No newline at end of file diff --git a/sql/updates/0.10/5197_mangos_spell_affect.sql b/sql/updates/0.10/5197_mangos_spell_affect.sql new file mode 100644 index 000000000..55bf7151c --- /dev/null +++ b/sql/updates/0.10/5197_mangos_spell_affect.sql @@ -0,0 +1,175 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (33167); +INSERT INTO `spell_affect` VALUES (33167, 0, 0, 0x00, 0, 0, 0, 0x0000000100000000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33171); +INSERT INTO `spell_affect` VALUES (33171, 0, 0, 0x00, 0, 0, 0, 0x0000000100000000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33172); +INSERT INTO `spell_affect` VALUES (33172, 0, 0, 0x00, 0, 0, 0, 0x0000000100000000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23236); +INSERT INTO `spell_affect` VALUES (23236, 0, 0, 0x00, 0, 0, 0, 0x0000003419541EC0, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37880); +INSERT INTO `spell_affect` VALUES (37880, 0, 0, 0x00, 0, 0, 0, 0x0000000411041E40, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15259); +INSERT INTO `spell_affect` VALUES (15259, 0, 0, 0x00, 0, 0, 0, 0x0000000202002000, 0); +INSERT INTO `spell_affect` VALUES (15259, 1, 0, 0x00, 0, 0, 0, 0x0000040000808000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15307); +INSERT INTO `spell_affect` VALUES (15307, 0, 0, 0x00, 0, 0, 0, 0x0000000202002000, 0); +INSERT INTO `spell_affect` VALUES (15307, 1, 0, 0x00, 0, 0, 0, 0x0000040000808000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15308); +INSERT INTO `spell_affect` VALUES (15308, 0, 0, 0x00, 0, 0, 0, 0x0000000202002000, 0); +INSERT INTO `spell_affect` VALUES (15308, 1, 0, 0x00, 0, 0, 0, 0x0000040000808000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15309); +INSERT INTO `spell_affect` VALUES (15309, 0, 0, 0x00, 0, 0, 0, 0x0000000202002000, 0); +INSERT INTO `spell_affect` VALUES (15309, 1, 0, 0x00, 0, 0, 0, 0x0000040000808000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15310); +INSERT INTO `spell_affect` VALUES (15310, 0, 0, 0x00, 0, 0, 0, 0x0000000202002000, 0); +INSERT INTO `spell_affect` VALUES (15310, 1, 0, 0x00, 0, 0, 0, 0x0000040000808000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14743); +INSERT INTO `spell_affect` VALUES (14743, 0, 0, 0x00, 0, 0, 0, 0x0000049440963E90, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (27828); +INSERT INTO `spell_affect` VALUES (27828, 0, 0, 0x00, 0, 0, 0, 0x0000049440963E90, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33186); +INSERT INTO `spell_affect` VALUES (33186, 0, 0, 0x00, 0, 0, 0, 0x0000008000000000, 0); +INSERT INTO `spell_affect` VALUES (33186, 1, 0, 0x00, 0, 0, 0, 0x0000008000002080, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33190); +INSERT INTO `spell_affect` VALUES (33190, 0, 0, 0x00, 0, 0, 0, 0x0000008000000000, 0); +INSERT INTO `spell_affect` VALUES (33190, 1, 0, 0x00, 0, 0, 0, 0x0000008000002080, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18544); +INSERT INTO `spell_affect` VALUES (18544, 0, 0, 0x00, 0, 0, 0, 0x0000041202F8A090, 0); +INSERT INTO `spell_affect` VALUES (18544, 1, 0, 0x00, 0, 0, 0, 0x0000001202582090, 0); +INSERT INTO `spell_affect` VALUES (18544, 2, 0, 0x00, 0, 0, 0, 0x0000040000A08000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18547); +INSERT INTO `spell_affect` VALUES (18547, 0, 0, 0x00, 0, 0, 0, 0x0000041202F8A090, 0); +INSERT INTO `spell_affect` VALUES (18547, 1, 0, 0x00, 0, 0, 0, 0x0000001202582090, 0); +INSERT INTO `spell_affect` VALUES (18547, 2, 0, 0x00, 0, 0, 0, 0x0000040000A08000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18548); +INSERT INTO `spell_affect` VALUES (18548, 0, 0, 0x00, 0, 0, 0, 0x0000041202F8A090, 0); +INSERT INTO `spell_affect` VALUES (18548, 1, 0, 0x00, 0, 0, 0, 0x0000001202582090, 0); +INSERT INTO `spell_affect` VALUES (18548, 2, 0, 0x00, 0, 0, 0, 0x0000040000A08000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18549); +INSERT INTO `spell_affect` VALUES (18549, 0, 0, 0x00, 0, 0, 0, 0x0000041202F8A090, 0); +INSERT INTO `spell_affect` VALUES (18549, 1, 0, 0x00, 0, 0, 0, 0x0000001202582090, 0); +INSERT INTO `spell_affect` VALUES (18549, 2, 0, 0x00, 0, 0, 0, 0x0000040000A08000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18550); +INSERT INTO `spell_affect` VALUES (18550, 0, 0, 0x00, 0, 0, 0, 0x0000041202F8A090, 0); +INSERT INTO `spell_affect` VALUES (18550, 1, 0, 0x00, 0, 0, 0, 0x0000001202582090, 0); +INSERT INTO `spell_affect` VALUES (18550, 2, 0, 0x00, 0, 0, 0, 0x0000040000A08000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14913); +INSERT INTO `spell_affect` VALUES (14913, 0, 0, 0x00, 0, 0, 0, 0x0000000400041E00, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15012); +INSERT INTO `spell_affect` VALUES (15012, 0, 0, 0x00, 0, 0, 0, 0x0000000400041E00, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37706); +INSERT INTO `spell_affect` VALUES (37706, 0, 0, 0x00, 0, 0, 0, 0x0000000411041E40, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37571); +INSERT INTO `spell_affect` VALUES (37571, 0, 0, 0x00, 0, 0, 0, 0x0000000000000080, 0); +INSERT INTO `spell_affect` VALUES (37571, 1, 0, 0x00, 0, 0, 0, 0x0000000000800000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14751); +INSERT INTO `spell_affect` VALUES (14751, 0, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); +INSERT INTO `spell_affect` VALUES (14751, 1, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14520); +INSERT INTO `spell_affect` VALUES (14520, 0, 0, 0x00, 0, 0, 0, 0x00000963BF61C16F, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14780); +INSERT INTO `spell_affect` VALUES (14780, 0, 0, 0x00, 0, 0, 0, 0x00000963BF61C16F, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14781); +INSERT INTO `spell_affect` VALUES (14781, 0, 0, 0x00, 0, 0, 0, 0x00000963BF61C16F, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14782); +INSERT INTO `spell_affect` VALUES (14782, 0, 0, 0x00, 0, 0, 0, 0x00000963BF61C16F, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14783); +INSERT INTO `spell_affect` VALUES (14783, 0, 0, 0x00, 0, 0, 0, 0x00000963BF61C16F, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28808); +INSERT INTO `spell_affect` VALUES (28808, 0, 0, 0x00, 0, 0, 0, 0x0000000411041E40, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15318); +INSERT INTO `spell_affect` VALUES (15318, 0, 0, 0x00, 0, 0, 0, 0x00000D4A068BE104, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15272); +INSERT INTO `spell_affect` VALUES (15272, 0, 0, 0x00, 0, 0, 0, 0x00000D4A068BE104, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15320); +INSERT INTO `spell_affect` VALUES (15320, 0, 0, 0x00, 0, 0, 0, 0x00000D4A068BE104, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15260); +INSERT INTO `spell_affect` VALUES (15260, 0, 0, 0x00, 0, 0, 0, 0x00000442068BA000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15327); +INSERT INTO `spell_affect` VALUES (15327, 0, 0, 0x00, 0, 0, 0, 0x00000442068BA000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15328); +INSERT INTO `spell_affect` VALUES (15328, 0, 0, 0x00, 0, 0, 0, 0x00000442068BA000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15329); +INSERT INTO `spell_affect` VALUES (15329, 0, 0, 0x00, 0, 0, 0, 0x00000442068BA000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15330); +INSERT INTO `spell_affect` VALUES (15330, 0, 0, 0x00, 0, 0, 0, 0x00000442068BA000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17322); +INSERT INTO `spell_affect` VALUES (17322, 0, 0, 0x00, 0, 0, 0, 0x00000542068AA004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17323); +INSERT INTO `spell_affect` VALUES (17323, 0, 0, 0x00, 0, 0, 0, 0x00000542068AA004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14523); +INSERT INTO `spell_affect` VALUES (14523, 1, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14784); +INSERT INTO `spell_affect` VALUES (14784, 1, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14785); +INSERT INTO `spell_affect` VALUES (14785, 1, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14786); +INSERT INTO `spell_affect` VALUES (14786, 1, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14787); +INSERT INTO `spell_affect` VALUES (14787, 1, 0, 0x00, 0, 0, 0, 0xFFFFFFFFFFFFFFFF, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14912); +INSERT INTO `spell_affect` VALUES (14912, 0, 0, 0x00, 0, 0, 0, 0x0000000000041400, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15013); +INSERT INTO `spell_affect` VALUES (15013, 0, 0, 0x00, 0, 0, 0, 0x0000000000041400, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (15014); +INSERT INTO `spell_affect` VALUES (15014, 0, 0, 0x00, 0, 0, 0, 0x0000000000041400, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14747); +INSERT INTO `spell_affect` VALUES (14747, 0, 0, 0x00, 0, 0, 0, 0x0000000000000002, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14770); +INSERT INTO `spell_affect` VALUES (14770, 0, 0, 0x00, 0, 0, 0, 0x0000000000000002, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14771); +INSERT INTO `spell_affect` VALUES (14771, 0, 0, 0x00, 0, 0, 0, 0x0000000000000002, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44297); +INSERT INTO `spell_affect` VALUES (44297, 0, 0, 0x00, 0, 0, 0, 0x0000000000010000, 0); + diff --git a/sql/updates/0.10/5199_characters_guild_bank_eventlog.sql b/sql/updates/0.10/5199_characters_guild_bank_eventlog.sql new file mode 100644 index 000000000..650e5e889 --- /dev/null +++ b/sql/updates/0.10/5199_characters_guild_bank_eventlog.sql @@ -0,0 +1 @@ +DELETE FROM `guild_bank_eventlog` WHERE `LogGuid`=0; diff --git a/sql/updates/0.10/5201_mangos_spell_affect.sql b/sql/updates/0.10/5201_mangos_spell_affect.sql new file mode 100644 index 000000000..8c43572cc --- /dev/null +++ b/sql/updates/0.10/5201_mangos_spell_affect.sql @@ -0,0 +1,53 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (30288); +INSERT INTO `spell_affect` VALUES (30288, 0, 0, 0x00, 0, 0, 0, 0x0000004000000001, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30289); +INSERT INTO `spell_affect` VALUES (30289, 0, 0, 0x00, 0, 0, 0, 0x0000004000000001, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30290); +INSERT INTO `spell_affect` VALUES (30290, 0, 0, 0x00, 0, 0, 0, 0x0000004000000001, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30291); +INSERT INTO `spell_affect` VALUES (30291, 0, 0, 0x00, 0, 0, 0, 0x0000004000000001, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30292); +INSERT INTO `spell_affect` VALUES (30292, 0, 0, 0x00, 0, 0, 0, 0x0000004000000001, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18427); +INSERT INTO `spell_affect` VALUES (18427, 0, 0, 0x00, 0, 0, 0, 0x0000000000020006, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18428); +INSERT INTO `spell_affect` VALUES (18428, 0, 0, 0x00, 0, 0, 0, 0x0000000000020006, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18429); +INSERT INTO `spell_affect` VALUES (18429, 0, 0, 0x00, 0, 0, 0, 0x0000000000020006, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31216); +INSERT INTO `spell_affect` VALUES (31216, 1, 0, 0x00, 0, 0, 0, 0x0000000002000004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31217); +INSERT INTO `spell_affect` VALUES (31217, 1, 0, 0x00, 0, 0, 0, 0x0000000002000004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31218); +INSERT INTO `spell_affect` VALUES (31218, 1, 0, 0x00, 0, 0, 0, 0x0000000002000004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31219); +INSERT INTO `spell_affect` VALUES (31219, 1, 0, 0x00, 0, 0, 0, 0x0000000002000004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31220); +INSERT INTO `spell_affect` VALUES (31220, 1, 0, 0x00, 0, 0, 0, 0x0000000002000004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14171); +INSERT INTO `spell_affect` VALUES (14171, 0, 0, 0x00, 0, 0, 0, 0x0000000000100000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14172); +INSERT INTO `spell_affect` VALUES (14172, 0, 0, 0x00, 0, 0, 0, 0x0000000000100000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14173); +INSERT INTO `spell_affect` VALUES (14173, 0, 0, 0x00, 0, 0, 0, 0x0000000000100000, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12290); +INSERT INTO `spell_affect` VALUES (12290, 0, 0, 0x00, 0, 0, 0, 0x0000000000000004, 0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12963); +INSERT INTO `spell_affect` VALUES (12963, 0, 0, 0x00, 0, 0, 0, 0x0000000000000004, 0); \ No newline at end of file diff --git a/sql/updates/0.10/5212_mangos_command.sql b/sql/updates/0.10/5212_mangos_command.sql new file mode 100644 index 000000000..51f5948ed --- /dev/null +++ b/sql/updates/0.10/5212_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('.casttarget'); + +INSERT INTO `command` VALUES +('casttarget',3,'Syntax: .casttarget #spellid\r\n Selected target will cast #spellid to his victim.'); diff --git a/sql/updates/0.10/5212_mangos_mangos_string.sql b/sql/updates/0.10/5212_mangos_mangos_string.sql new file mode 100644 index 000000000..b84f7d594 --- /dev/null +++ b/sql/updates/0.10/5212_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM `mangos_string` WHERE `entry` = 579; +INSERT INTO `mangos_string` VALUES + (579,'Selected player or creature not have victim.',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5217_characters_character.sql b/sql/updates/0.10/5217_characters_character.sql new file mode 100644 index 000000000..61d6e105c --- /dev/null +++ b/sql/updates/0.10/5217_characters_character.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character` + ADD COLUMN `taxi_path` text; diff --git a/sql/updates/0.10/5228_mangos_gameobject_scripts.sql b/sql/updates/0.10/5228_mangos_gameobject_scripts.sql new file mode 100644 index 000000000..bc29c6f4e --- /dev/null +++ b/sql/updates/0.10/5228_mangos_gameobject_scripts.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS `gameobject_scripts`; +CREATE TABLE `gameobject_scripts` ( +`id` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0', +`delay` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0', +`command` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0', +`datalong` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0', +`datalong2` INT( 11 ) UNSIGNED NOT NULL DEFAULT '0', +`datatext` TEXT NOT NULL , +`x` FLOAT NOT NULL DEFAULT '0', +`y` FLOAT NOT NULL DEFAULT '0', +`z` FLOAT NOT NULL DEFAULT '0', +`o` FLOAT NOT NULL DEFAULT '0' +) ENGINE = MYISAM DEFAULT CHARSET = utf8; diff --git a/sql/updates/0.10/5233_mangos_event_scripts.sql b/sql/updates/0.10/5233_mangos_event_scripts.sql new file mode 100644 index 000000000..1ab97a526 --- /dev/null +++ b/sql/updates/0.10/5233_mangos_event_scripts.sql @@ -0,0 +1 @@ +ALTER TABLE `gameobject_scripts` RENAME TO `event_scripts`; diff --git a/sql/updates/0.10/5234_mangos_spell_proc_event.sql b/sql/updates/0.10/5234_mangos_spell_proc_event.sql new file mode 100644 index 000000000..9ed803db8 --- /dev/null +++ b/sql/updates/0.10/5234_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (29601); +INSERT INTO `spell_proc_event` VALUES +(29601,0,0,0,7,0x0000000000000000,0x00004000,0); diff --git a/sql/updates/0.10/5238_mangos_spell_proc_event.sql b/sql/updates/0.10/5238_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d6515853e --- /dev/null +++ b/sql/updates/0.10/5238_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (33727,33754,33755,33756,33757); +INSERT INTO `spell_proc_event` VALUES +(33727,0,0,0,0,0x0000000000000000,0x00000000,0), /* not used*/ +(33754,0,0,0,0,0x0000000000000000,0x00000000,0), /* not used*/ +(33755,0,0,0,0,0x0000000000000000,0x00000000,0), /* not used*/ +(33756,0,0,0,0,0x0000000000000000,0x00000000,0), /* not used*/ +(33757,0,0,0,0,0x0000000000000000,0x00000001,0); diff --git a/sql/updates/0.10/5242_mangos_instance_template.sql b/sql/updates/0.10/5242_mangos_instance_template.sql new file mode 100644 index 000000000..e0229a66c --- /dev/null +++ b/sql/updates/0.10/5242_mangos_instance_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `instance_template` + ADD `parent` int(11) unsigned NOT NULL AFTER `map`; diff --git a/sql/updates/0.10/5243_mangos_spell_affect.sql b/sql/updates/0.10/5243_mangos_spell_affect.sql new file mode 100644 index 000000000..21e9a0bea --- /dev/null +++ b/sql/updates/0.10/5243_mangos_spell_affect.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (33886,33887,33888,33889,33890); +INSERT INTO `spell_affect` VALUES +(33886,0,0,0,0,0,0,0x00000010000000d0, 0), +(33887,0,0,0,0,0,0,0x00000010000000d0, 0), +(33888,0,0,0,0,0,0,0x00000010000000d0, 0), +(33889,0,0,0,0,0,0,0x00000010000000d0, 0), +(33890,0,0,0,0,0,0,0x00000010000000d0, 0); + diff --git a/sql/updates/0.10/5249_mangos_spell_learn_skill.sql b/sql/updates/0.10/5249_mangos_spell_learn_skill.sql new file mode 100644 index 000000000..37d52b21e --- /dev/null +++ b/sql/updates/0.10/5249_mangos_spell_learn_skill.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_learn_skill` WHERE `entry` IN (29932); +INSERT INTO `spell_learn_skill` (`entry`, `SkillID`, `Value`, `MaxValue`) VALUE +(29932,759,-1,-1); diff --git a/sql/updates/0.10/5254_mangos_spell_affect.sql b/sql/updates/0.10/5254_mangos_spell_affect.sql new file mode 100644 index 000000000..152251418 --- /dev/null +++ b/sql/updates/0.10/5254_mangos_spell_affect.sql @@ -0,0 +1,11 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (31579,31582,31583) AND `effectId`=0; +INSERT INTO `spell_affect` VALUES + (31579,0,0,0,0,0,0,0x0000000000200000,0), + (31582,0,0,0,0,0,0,0x0000000000200000,0), + (31583,0,0,0,0,0,0,0x0000000000200000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20237,20238,20239); +INSERT INTO `spell_affect` VALUES + (20237,0,0,0,0,0,0,0x0000000000006000,0), + (20238,0,0,0,0,0,0,0x0000000000006000,0), + (20239,0,0,0,0,0,0,0x0000000000006000,0); diff --git a/sql/updates/0.10/5254_mangos_spell_proc_event.sql b/sql/updates/0.10/5254_mangos_spell_proc_event.sql new file mode 100644 index 000000000..c7d27f41d --- /dev/null +++ b/sql/updates/0.10/5254_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (43750); +INSERT INTO `spell_proc_event` VALUES +(43750,0,0,0,11,0x0000000000000001,0x00004000,0); diff --git a/sql/updates/0.10/5258_characters_character.sql b/sql/updates/0.10/5258_characters_character.sql new file mode 100644 index 000000000..a40b01fd0 --- /dev/null +++ b/sql/updates/0.10/5258_characters_character.sql @@ -0,0 +1 @@ +ALTER TABLE `character` ADD KEY `idx_name` (`name`); \ No newline at end of file diff --git a/sql/updates/0.10/5265_mangos_spell_proc_event.sql b/sql/updates/0.10/5265_mangos_spell_proc_event.sql new file mode 100644 index 000000000..9329b06b7 --- /dev/null +++ b/sql/updates/0.10/5265_mangos_spell_proc_event.sql @@ -0,0 +1,31 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (39446); +INSERT INTO `spell_proc_event` VALUES +(39446,0,0,0,0,0x0000000000000000,0x00000004,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (32863,36123,38252,39367); +INSERT INTO `spell_proc_event` VALUES +(32863,0,0,0,0,0x0000000000000000,0x00008000,0), +(36123,0,0,0,0,0x0000000000000000,0x00008000,0), +(38252,0,0,0,0,0x0000000000000000,0x00008000,0), +(39367,0,0,0,0,0x0000000000000000,0x00008000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37381); +INSERT INTO `spell_proc_event` VALUES +(37381,0,0,0,0,0x0000000000000000,0x000a0001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (39372); +INSERT INTO `spell_proc_event` VALUES +(39372,0,0,0,0,0x0000000000000000,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (28789); +INSERT INTO `spell_proc_event` VALUES +(28789,0,0,0,10,0x0000000000006000,0x20000000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (28849); +INSERT INTO `spell_proc_event` VALUES +(28849,0,0,0,11,0x0000000000000080,0x00004000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37655,38334); +INSERT INTO `spell_proc_event` VALUES +(37655,0,0,0,0,0x0000000000000000,0x00004000,0), +(38334,0,0,0,0,0x0000000000000000,0x00004000,0); diff --git a/sql/updates/0.10/5269_mangos_uptime.sql b/sql/updates/0.10/5269_mangos_uptime.sql new file mode 100644 index 000000000..289da45ef --- /dev/null +++ b/sql/updates/0.10/5269_mangos_uptime.sql @@ -0,0 +1,2 @@ +ALTER TABLE `uptime` + ADD COLUMN `maxplayers` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.10/5270_mangos_gameobject_scripts.sql b/sql/updates/0.10/5270_mangos_gameobject_scripts.sql new file mode 100644 index 000000000..52f523aeb --- /dev/null +++ b/sql/updates/0.10/5270_mangos_gameobject_scripts.sql @@ -0,0 +1 @@ +ALTER TABLE `button_scripts` RENAME TO `gameobject_scripts`; diff --git a/sql/updates/0.10/5272_mangos_mangos_string.sql b/sql/updates/0.10/5272_mangos_mangos_string.sql new file mode 100644 index 000000000..699ea9d00 --- /dev/null +++ b/sql/updates/0.10/5272_mangos_mangos_string.sql @@ -0,0 +1,6 @@ +DELETE FROM `mangos_string` WHERE `entry` in (707,708,709,710); +INSERT INTO `mangos_string` VALUES +(707,'%s wishes to not be disturbed and cannot receive whisper messages: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(708,'%s is Away from Keyboard: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(709,'Do not Disturb',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(710,'Away from Keyboard',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5286_characters_character_pet.sql b/sql/updates/0.10/5286_characters_character_pet.sql new file mode 100644 index 000000000..37747b319 --- /dev/null +++ b/sql/updates/0.10/5286_characters_character_pet.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_pet` + DROP `nextlvlexp`; diff --git a/sql/updates/0.10/5292_mangos_spell_proc_event.sql b/sql/updates/0.10/5292_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d1277c895 --- /dev/null +++ b/sql/updates/0.10/5292_mangos_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (13743,13875); +INSERT INTO `spell_proc_event` VALUES +(13743,0,0,0,8,0x0000000000000040,0x00004000,0), +(13875,0,0,0,8,0x0000000000000040,0x00004000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (16864); +INSERT INTO `spell_proc_event` VALUES +(16864,0,0,0,0,0x0000000000000000,0x00000001,2); diff --git a/sql/updates/0.10/5295_mangos_creature_template.sql b/sql/updates/0.10/5295_mangos_creature_template.sql new file mode 100644 index 000000000..08ec884e9 --- /dev/null +++ b/sql/updates/0.10/5295_mangos_creature_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_template` +ADD `mechanic_immune_mask` int(11) signed NOT NULL default '0' AFTER `equipment_id` ; \ No newline at end of file diff --git a/sql/updates/0.10/5297_characters.sql b/sql/updates/0.10/5297_characters.sql new file mode 100644 index 000000000..39f3e3ac2 --- /dev/null +++ b/sql/updates/0.10/5297_characters.sql @@ -0,0 +1,16 @@ +ALTER TABLE `character` RENAME TO `characters`; +ALTER TABLE `group` RENAME TO `groups`; + +ALTER TABLE `character_pet` + CHANGE COLUMN `ABData` `abdata` longtext, + CHANGE COLUMN `TeachSpelldata` `teachspelldata` longtext; + +ALTER TABLE `guild` + CHANGE COLUMN `MOTD` `motd` varchar(255) NOT NULL default ''; + +ALTER TABLE `guild_member` + CHANGE COLUMN `Pnote` `pnote` varchar(255) NOT NULL default '', + CHANGE COLUMN `OFFnote` `offnote` varchar(255) NOT NULL default ''; + +ALTER TABLE `guild_bank_right` + CHANGE COLUMN `Right` `gbright` tinyint(3) unsigned NOT NULL default '0'; \ No newline at end of file diff --git a/sql/updates/0.10/5297_mangos.sql b/sql/updates/0.10/5297_mangos.sql new file mode 100644 index 000000000..058ccfbcd --- /dev/null +++ b/sql/updates/0.10/5297_mangos.sql @@ -0,0 +1,12 @@ +ALTER TABLE `game_event` + CHANGE COLUMN `start` `start_time` timestamp NOT NULL default '0000-00-00 00:00:00' COMMENT 'Absolute start date, the event will never start before', + CHANGE COLUMN `end` `end_time` timestamp NOT NULL default '0000-00-00 00:00:00' COMMENT 'Absolute end date, the event will never start afler'; + +ALTER TABLE `pet_levelstats` + CHANGE COLUMN `int` `inte` smallint(5) unsigned NOT NULL; + +ALTER TABLE `player_levelstats` + CHANGE COLUMN `int` `inte` smallint(5) unsigned NOT NULL; + +ALTER TABLE `npc_option` + CHANGE COLUMN `option` `option_text` text; \ No newline at end of file diff --git a/sql/updates/0.10/5297_realmd_account.sql b/sql/updates/0.10/5297_realmd_account.sql new file mode 100644 index 000000000..7118b94f8 --- /dev/null +++ b/sql/updates/0.10/5297_realmd_account.sql @@ -0,0 +1,2 @@ +ALTER TABLE `account` + CHANGE COLUMN `I` `sha_pass_hash` VARCHAR(40) NOT NULL default ''; \ No newline at end of file diff --git a/sql/updates/0.10/5302_mangos_player_levelstats.sql b/sql/updates/0.10/5302_mangos_player_levelstats.sql new file mode 100644 index 000000000..55f768f78 --- /dev/null +++ b/sql/updates/0.10/5302_mangos_player_levelstats.sql @@ -0,0 +1,13 @@ +ALTER TABLE player_levelstats + ADD COLUMN basehp smallint(5) unsigned NOT NULL AFTER level, + ADD COLUMN basemana smallint(5) unsigned NOT NULL AFTER basehp; + +UPDATE player_levelstats SET basehp = hp - sta WHERE sta <= 20; +UPDATE player_levelstats SET basehp = hp - 20 - (sta-20)*10 WHERE sta > 20; + +UPDATE player_levelstats SET basemana = mana - inte WHERE mana > 0 and inte <= 20; +UPDATE player_levelstats SET basemana = mana - 20 - (inte-20)*15 WHERE mana > 0 and inte > 20; + +ALTER TABLE player_levelstats + DROP COLUMN hp, + DROP COLUMN mana; diff --git a/sql/updates/0.10/5311_mangos_spell_affect.sql b/sql/updates/0.10/5311_mangos_spell_affect.sql new file mode 100644 index 000000000..7ef960819 --- /dev/null +++ b/sql/updates/0.10/5311_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_affect WHERE entry IN (28746); +INSERT INTO spell_affect VALUES + (28746,1,0,0,0,0,0,0x0000000100000406,0); diff --git a/sql/updates/0.10/5326_mangos_spell_affect.sql b/sql/updates/0.10/5326_mangos_spell_affect.sql new file mode 100644 index 000000000..5f42e5409 --- /dev/null +++ b/sql/updates/0.10/5326_mangos_spell_affect.sql @@ -0,0 +1,8 @@ +DELETE FROM spell_affect WHERE entry IN (16858,16859,16860); +INSERT INTO spell_affect VALUES + (16858,0,0,0,0,0,0,0x0000000000000008,0), + (16858,1,0,0,0,0,0,0x0000000000800000,0), + (16859,0,0,0,0,0,0,0x0000000000000008,0), + (16859,1,0,0,0,0,0,0x0000000000800000,0), + (16860,0,0,0,0,0,0,0x0000000000000008,0), + (16860,1,0,0,0,0,0,0x0000000000800000,0); diff --git a/sql/updates/0.10/5335_mangos_mangos_string.sql b/sql/updates/0.10/5335_mangos_mangos_string.sql new file mode 100644 index 000000000..f3f459267 --- /dev/null +++ b/sql/updates/0.10/5335_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry in (12); +INSERT INTO mangos_string VALUES +(12,'Online players: %u (max: %u) Queued players: %u (max: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5343_mangos_spell_proc_event.sql b/sql/updates/0.10/5343_mangos_spell_proc_event.sql new file mode 100644 index 000000000..21d73c6da --- /dev/null +++ b/sql/updates/0.10/5343_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM spell_proc_event WHERE entry IN (39958); +INSERT INTO spell_proc_event VALUES +(39958,0,0,0,0,0x0000000000000000,0x00000001,0.7); + +DELETE FROM spell_proc_event WHERE entry IN (33759); +INSERT INTO `spell_proc_event` VALUES +(33759,0,0,0,0,0x0000000000000000,0x00000004,0); diff --git a/sql/updates/0.10/5347_mangos_spell_affect.sql b/sql/updates/0.10/5347_mangos_spell_affect.sql new file mode 100644 index 000000000..8ba845e9d --- /dev/null +++ b/sql/updates/0.10/5347_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_affect WHERE entry IN (5420); +INSERT INTO spell_affect VALUES + (5420,2,0,0,0,0,0,0x00000010000000F0,0); diff --git a/sql/updates/0.10/5350_mangos_spell_affect.sql b/sql/updates/0.10/5350_mangos_spell_affect.sql new file mode 100644 index 000000000..e712c3123 --- /dev/null +++ b/sql/updates/0.10/5350_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_affect WHERE entry IN (5420); +INSERT INTO spell_affect VALUES + (5420,2,0,0,0,0,0,0x00001012100000D0,0); \ No newline at end of file diff --git a/sql/updates/0.10/5351_mangos_spell_proc_event.sql b/sql/updates/0.10/5351_mangos_spell_proc_event.sql new file mode 100644 index 000000000..22b96f63e --- /dev/null +++ b/sql/updates/0.10/5351_mangos_spell_proc_event.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (14892,15362,15363); +INSERT INTO `spell_proc_event` VALUES +(14892,0,0,0,6,0x0000000410001E00,0x10000000,0), +(15362,0,0,0,6,0x0000000410001E00,0x10000000,0), +(15363,0,0,0,6,0x0000000410001E00,0x10000000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33150,33154); +INSERT INTO `spell_proc_event` VALUES +(33150,0,0,0,0,0x0000000000000000,0x10010000,0), +(33154,0,0,0,0,0x0000000000000000,0x10010000,0); diff --git a/sql/updates/0.10/5363_mangos_creature_template.sql b/sql/updates/0.10/5363_mangos_creature_template.sql new file mode 100644 index 000000000..6e238f432 --- /dev/null +++ b/sql/updates/0.10/5363_mangos_creature_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_template` + ADD `scale` float default '0' AFTER `speed`; \ No newline at end of file diff --git a/sql/updates/0.10/5366_mangos_spell_proc_event.sql b/sql/updates/0.10/5366_mangos_spell_proc_event.sql new file mode 100644 index 000000000..5993a0023 --- /dev/null +++ b/sql/updates/0.10/5366_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (35541,35550,35551,35552,35553); +INSERT INTO `spell_proc_event` VALUES +(35541,0,0,0,0,0x0000000000000000,0x00000001,0), +(35550,0,0,0,0,0x0000000000000000,0x00000001,0), +(35551,0,0,0,0,0x0000000000000000,0x00000001,0), +(35552,0,0,0,0,0x0000000000000000,0x00000001,0), +(35553,0,0,0,0,0x0000000000000000,0x00000001,0); diff --git a/sql/updates/0.10/5367_mangos_spell_affect.sql b/sql/updates/0.10/5367_mangos_spell_affect.sql new file mode 100644 index 000000000..19c081ca9 --- /dev/null +++ b/sql/updates/0.10/5367_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_affect WHERE entry IN (32601); +INSERT INTO spell_affect VALUES + (32601,1,0,0,0,0,0,0x0000000020800008,0); diff --git a/sql/updates/0.10/5370_mangos_spell_affect.sql b/sql/updates/0.10/5370_mangos_spell_affect.sql new file mode 100644 index 000000000..2adb3f1ad --- /dev/null +++ b/sql/updates/0.10/5370_mangos_spell_affect.sql @@ -0,0 +1,87 @@ +DELETE FROM spell_affect WHERE entry IN (14177); +INSERT INTO spell_affect VALUES + (14177,0,0,0,0,0,0,0x000000086012031E,0); + +DELETE FROM spell_affect WHERE entry IN (14082,14083); +INSERT INTO spell_affect VALUES + (14082,0,0,0,0,0,0,0x0000000000000500,0), + (14083,0,0,0,0,0,0,0x0000000000000500,0); + +DELETE FROM spell_affect WHERE entry IN (14076,14094); +INSERT INTO spell_affect VALUES + (14076,0,0,0,0,0,0,0x0000000001000080,0), + (14076,1,0,0,0,0,0,0x0000000001000080,0), + (14094,0,0,0,0,0,0,0x0000000001000080,0), + (14094,1,0,0,0,0,0,0x0000000001000080,0); + +DELETE FROM spell_affect WHERE entry IN (37166); +INSERT INTO spell_affect VALUES + (37166,0,0,0,0,0,0,0x0000000000800000,0); + +DELETE FROM spell_affect WHERE entry IN (31234,31235,31236,31237,31238); +INSERT INTO spell_affect VALUES + (31234,0,0,0,0,0,0,0x000001002612030F,0), + (31234,1,0,0,0,0,0,0x0000000000100100,0), + (31235,0,0,0,0,0,0,0x000001002612030F,0), + (31235,1,0,0,0,0,0,0x0000000000100100,0), + (31236,0,0,0,0,0,0,0x000001002612030F,0), + (31236,1,0,0,0,0,0,0x0000000000100100,0), + (31237,0,0,0,0,0,0,0x000001002612030F,0), + (31237,1,0,0,0,0,0,0x0000000000100100,0), + (31238,0,0,0,0,0,0,0x000001002612030F,0), + (31238,1,0,0,0,0,0,0x0000000000100100,0); + +DELETE FROM spell_affect WHERE entry IN (14128,14132,14135,14136,14137); +INSERT INTO spell_affect VALUES + (14128,0,0,0,0,0,0,0x000000062600000E,0), + (14132,0,0,0,0,0,0,0x000000062600000E,0), + (14135,0,0,0,0,0,0,0x000000062600000E,0), + (14136,0,0,0,0,0,0,0x000000062600000E,0), + (14137,0,0,0,0,0,0,0x000000062600000E,0); + +DELETE FROM spell_affect WHERE entry IN (14057,14072,14073,14074,14075); +INSERT INTO spell_affect VALUES + (14057,0,0,0,0,0,0,0x0000000600000304,0), + (14057,1,0,0,0,0,0,0x0000000000000100,0), + (14072,0,0,0,0,0,0,0x0000000600000304,0), + (14072,1,0,0,0,0,0,0x0000000000000100,0), + (14073,0,0,0,0,0,0,0x0000000600000304,0), + (14073,1,0,0,0,0,0,0x0000000000000100,0), + (14074,0,0,0,0,0,0,0x0000000600000304,0), + (14074,1,0,0,0,0,0,0x0000000000000100,0), + (14075,0,0,0,0,0,0,0x0000000600000304,0), + (14075,1,0,0,0,0,0,0x0000000000000100,0); + +DELETE FROM spell_affect WHERE entry IN (14143,14149,14151); +INSERT INTO spell_affect VALUES + (14143,0,0,0,0,0,0,0x0000000606000206,0), + (14149,0,0,0,0,0,0,0x0000000606000206,0), + (14151,0,0,0,0,0,0,0x0000000606000206,0); + +DELETE FROM spell_affect WHERE entry IN (28815); +INSERT INTO spell_affect VALUES + (28815,0,0,0,0,0,0,0x0000000002000006,0); + +DELETE FROM spell_affect WHERE entry IN (36563); +INSERT INTO spell_affect VALUES + (36563,1,0,0,0,0,0,0x0000000000000204,0), + (36563,2,0,0,0,0,0,0x0000000000000100,0); + +DELETE FROM spell_affect WHERE entry IN (16513,16514,16515,16719,16720); +INSERT INTO spell_affect VALUES + (16513,0,0,0,0,0,0,0x000000080001E000,0), + (16513,1,0,0,0,0,0,0x000000000001E000,0), + (16513,2,0,0,0,0,0,0x000000000001E000,0), + (16514,0,0,0,0,0,0,0x000000080001E000,0), + (16514,1,0,0,0,0,0,0x000000000001E000,0), + (16514,2,0,0,0,0,0,0x000000000001E000,0), + (16515,0,0,0,0,0,0,0x000000080001E000,0), + (16515,1,0,0,0,0,0,0x000000000001E000,0), + (16515,2,0,0,0,0,0,0x000000000001E000,0), + (16719,0,0,0,0,0,0,0x000000080001E000,0), + (16719,1,0,0,0,0,0,0x000000000001E000,0), + (16719,2,0,0,0,0,0,0x000000000001E000,0), + (16720,0,0,0,0,0,0,0x000000080001E000,0), + (16720,1,0,0,0,0,0,0x000000000001E000,0), + (16720,2,0,0,0,0,0,0x000000000001E000,0); + diff --git a/sql/updates/0.10/5374_mangos_spell_affect.sql b/sql/updates/0.10/5374_mangos_spell_affect.sql new file mode 100644 index 000000000..77bb74fca --- /dev/null +++ b/sql/updates/0.10/5374_mangos_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM spell_affect WHERE entry IN (29888,29889); +INSERT INTO spell_affect VALUES + (29888,0,0,0,0,0,0,0x0000000040000000,0), + (29889,0,0,0,0,0,0,0x0000000040000000,0); diff --git a/sql/updates/0.10/5378_mangos_spell_proc_event.sql b/sql/updates/0.10/5378_mangos_spell_proc_event.sql new file mode 100644 index 000000000..abf12d984 --- /dev/null +++ b/sql/updates/0.10/5378_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34580); +INSERT INTO `spell_proc_event` VALUES +(34580,0,0,0,0,0x0000000000000000,0x00000001,2); diff --git a/sql/updates/0.10/5379_mangos_spell_proc_event.sql b/sql/updates/0.10/5379_mangos_spell_proc_event.sql new file mode 100644 index 000000000..16aa74f8c --- /dev/null +++ b/sql/updates/0.10/5379_mangos_spell_proc_event.sql @@ -0,0 +1 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34580); diff --git a/sql/updates/0.10/5402_mangos_spell_proc_event.sql b/sql/updates/0.10/5402_mangos_spell_proc_event.sql new file mode 100644 index 000000000..fa48e291b --- /dev/null +++ b/sql/updates/0.10/5402_mangos_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (41635,33280,35092,35093,35094); +INSERT INTO `spell_proc_event`VALUES +(41635,0,0,0,0,0x0000000000000000,0x00008000,0), +(33280,0,0,0,0,0x0000000000000000,0x00008000,0), +(35092,0,0,0,0,0x0000000000000000,0x00008000,0), +(35093,0,0,0,0,0x0000000000000000,0x00008000,0), +(35094,0,0,0,0,0x0000000000000000,0x00008000,0); + diff --git a/sql/updates/0.10/5408_characters_mail_items.sql b/sql/updates/0.10/5408_characters_mail_items.sql new file mode 100644 index 000000000..cd0867c73 --- /dev/null +++ b/sql/updates/0.10/5408_characters_mail_items.sql @@ -0,0 +1,8 @@ +ALTER TABLE mail_items + ADD COLUMN receiver int(11) unsigned NOT NULL default 0 COMMENT 'Character Global Unique Identifier' AFTER item_template; + +UPDATE mail_items, mail + SET mail_items.receiver = mail.receiver WHERE mail_items.mail_id = mail.id; + +DELETE FROM item_instance WHERE guid IN (SELECT item_guid FROM mail_items WHERE mail_items.receiver = 0); +DELETE FROM mail_items WHERE mail_items.receiver = 0; diff --git a/sql/updates/0.10/5411_mangos_spell_affect.sql b/sql/updates/0.10/5411_mangos_spell_affect.sql new file mode 100644 index 000000000..71409d0ee --- /dev/null +++ b/sql/updates/0.10/5411_mangos_spell_affect.sql @@ -0,0 +1,5 @@ +DELETE FROM spell_affect WHERE `entry` IN (33167, 33171, 33172); +INSERT INTO spell_affect VALUES + (33167,0,0,0,0,0,0,0x0000008100000000,0), + (33171,0,0,0,0,0,0,0x0000008100000000,0), + (33172,0,0,0,0,0,0,0x0000008100000000,0); diff --git a/sql/updates/0.10/5419_mangos_spell_affect.sql b/sql/updates/0.10/5419_mangos_spell_affect.sql new file mode 100644 index 000000000..942e4a5f2 --- /dev/null +++ b/sql/updates/0.10/5419_mangos_spell_affect.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (29723,29724,29725); +INSERT INTO `spell_affect` VALUES + (29723,0,0,0,0,0,0,0x0000000800002010,0), + (29723,1,0,0,0,0,0,0x0000000800002010,0), + (29724,0,0,0,0,0,0,0x0000000800002010,0), + (29724,1,0,0,0,0,0,0x0000000800002010,0), + (29725,0,0,0,0,0,0,0x0000000800002010,0), + (29725,1,0,0,0,0,0,0x0000000800002010,0); diff --git a/sql/updates/0.10/5420_characters_mail_items.sql b/sql/updates/0.10/5420_characters_mail_items.sql new file mode 100644 index 000000000..f4df8f2a3 --- /dev/null +++ b/sql/updates/0.10/5420_characters_mail_items.sql @@ -0,0 +1 @@ +ALTER TABLE `mail_items` ADD KEY `idx_receiver` (`receiver`); \ No newline at end of file diff --git a/sql/updates/0.10/5422_mangos_spell_proc_event.sql b/sql/updates/0.10/5422_mangos_spell_proc_event.sql new file mode 100644 index 000000000..8a1789358 --- /dev/null +++ b/sql/updates/0.10/5422_mangos_spell_proc_event.sql @@ -0,0 +1,9 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 15600 ); +INSERT INTO `spell_proc_event` VALUES +(15600,0,0,0,0,0x0000000000000000,0x00000001,0.6); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33881,33882,33883); +INSERT INTO `spell_proc_event` VALUES +(33881,0,0,0,0,0x0000000000000000,0x00842000,0), +(33882,0,0,0,0,0x0000000000000000,0x00842000,0), +(33883,0,0,0,0,0x0000000000000000,0x00842000,0); diff --git a/sql/updates/0.10/5441_characters_petition_petition_sign.sql b/sql/updates/0.10/5441_characters_petition_petition_sign.sql new file mode 100644 index 000000000..214e3b7a3 --- /dev/null +++ b/sql/updates/0.10/5441_characters_petition_petition_sign.sql @@ -0,0 +1,5 @@ +ALTER TABLE `petition` +DROP PRIMARY KEY, +ADD PRIMARY KEY (`ownerguid`, `type`); + +ALTER TABLE `petition_sign` ADD COLUMN `type` int(10) UNSIGNED NOT NULL DEFAULT 0; diff --git a/sql/updates/0.10/5443_mangos_item_template.sql b/sql/updates/0.10/5443_mangos_item_template.sql new file mode 100644 index 000000000..22502afb2 --- /dev/null +++ b/sql/updates/0.10/5443_mangos_item_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE item_template + CHANGE COLUMN RequiredArenaRank CondExtendedCost int(10) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.10/5445_mangos_spell_affect.sql b/sql/updates/0.10/5445_mangos_spell_affect.sql new file mode 100644 index 000000000..83bef662b --- /dev/null +++ b/sql/updates/0.10/5445_mangos_spell_affect.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (17815,17833,17834,17835,17836); +INSERT INTO `spell_affect` VALUES + (17815,0,0,0,0,0,0,0x0000000000000004,0), + (17833,0,0,0,0,0,0,0x0000000000000004,0), + (17834,0,0,0,0,0,0,0x0000000000000004,0), + (17835,0,0,0,0,0,0,0x0000000000000004,0), + (17836,0,0,0,0,0,0,0x0000000000000004,0); diff --git a/sql/updates/0.10/5446_mangos_creature_template.sql b/sql/updates/0.10/5446_mangos_creature_template.sql new file mode 100644 index 000000000..1fff19e64 --- /dev/null +++ b/sql/updates/0.10/5446_mangos_creature_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_template` + ADD COLUMN IconName char(100) default NULL AFTER subname; diff --git a/sql/updates/0.10/5451_characters_petition_petition_sign.sql b/sql/updates/0.10/5451_characters_petition_petition_sign.sql new file mode 100644 index 000000000..f16b07cd0 --- /dev/null +++ b/sql/updates/0.10/5451_characters_petition_petition_sign.sql @@ -0,0 +1,2 @@ +ALTER TABLE `petition` ENGINE = InnoDB; +ALTER TABLE `petition_sign` ENGINE = InnoDB; diff --git a/sql/updates/0.10/5457_realmd_account.sql b/sql/updates/0.10/5457_realmd_account.sql new file mode 100644 index 000000000..9841ea54e --- /dev/null +++ b/sql/updates/0.10/5457_realmd_account.sql @@ -0,0 +1 @@ +UPDATE account SET username = UPPER(username); \ No newline at end of file diff --git a/sql/updates/0.10/5460_mangos_spell_proc_event.sql b/sql/updates/0.10/5460_mangos_spell_proc_event.sql new file mode 100644 index 000000000..2482ab292 --- /dev/null +++ b/sql/updates/0.10/5460_mangos_spell_proc_event.sql @@ -0,0 +1,11 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37239 ); +INSERT INTO `spell_proc_event` VALUES +(37239,0,0,0,0,0x0000000000000000,0x00000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 43737 ); +INSERT INTO `spell_proc_event` VALUES +(43737,0,0,0,7,0x0000044000000000,0x00000001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 43739 ); +INSERT INTO `spell_proc_event` VALUES +(43739,0,0,0,7,0x0000000000000002,0x00020000,0); diff --git a/sql/updates/0.10/5462_mangos_spell_affect.sql b/sql/updates/0.10/5462_mangos_spell_affect.sql new file mode 100644 index 000000000..a0395be57 --- /dev/null +++ b/sql/updates/0.10/5462_mangos_spell_affect.sql @@ -0,0 +1,144 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (17778,17779,17780,17781,17782); +INSERT INTO `spell_affect` VALUES + (17778,0,0,0,0,0,0,0x000010C0000003E5,0), + (17779,0,0,0,0,0,0,0x000010C0000003E5,0), + (17780,0,0,0,0,0,0,0x000010C0000003E5,0), + (17781,0,0,0,0,0,0,0x000010C0000003E5,0), + (17782,0,0,0,0,0,0,0x000010C0000003E5,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23555); +INSERT INTO `spell_affect` VALUES + (23555,0,0,0,0,0,0,0x000010C0000003E5,0); + + +DELETE FROM `spell_affect` WHERE `entry` IN (18130,18131,18132,18133,18134); +INSERT INTO `spell_affect` VALUES + (18130,0,0,0,0,0,0,0x000010C0000003E5,0), + (18131,0,0,0,0,0,0,0x000010C0000003E5,0), + (18132,0,0,0,0,0,0,0x000010C0000003E5,0), + (18133,0,0,0,0,0,0,0x000010C0000003E5,0), + (18134,0,0,0,0,0,0,0x000010C0000003E5,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18135,18136); +INSERT INTO `spell_affect` VALUES + (18135,0,0,0,0,0,0,0x000010C0000003E5,0), + (18136,0,0,0,0,0,0,0x000010C0000003E5,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17959); +INSERT INTO `spell_affect` VALUES + (17959,0,0,0,0,0,0,0x000010C0000003E5,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17917,17918); +INSERT INTO `spell_affect` VALUES + (17917,0,0,0,0,0,0,0x000010C0000003A5,0), + (17917,1,0,0,0,0,0,0x000010C0000003E5,0), + (17918,0,0,0,0,0,0,0x000010C0000003A5,0), + (17918,1,0,0,0,0,0,0x000010C0000003E5,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30060,30061,30062,30063,30064); +INSERT INTO `spell_affect` VALUES + (30060,0,0,0,0,0,0,0x0000001000000402,0), + (30060,1,0,0,0,0,0,0x0000001000000402,0), + (30060,2,0,0,0,0,0,0x0000871B804CC41A,0), + (30061,0,0,0,0,0,0,0x0000001000000402,0), + (30061,1,0,0,0,0,0,0x0000001000000402,0), + (30061,2,0,0,0,0,0,0x0000871B804CC41A,0), + (30062,0,0,0,0,0,0,0x0000001000000402,0), + (30062,1,0,0,0,0,0,0x0000001000000402,0), + (30062,2,0,0,0,0,0,0x0000871B804CC41A,0), + (30063,0,0,0,0,0,0,0x0000001000000402,0), + (30063,1,0,0,0,0,0,0x0000001000000402,0), + (30063,2,0,0,0,0,0,0x0000871B804CC41A,0), + (30064,0,0,0,0,0,0,0x0000001000000402,0), + (30064,1,0,0,0,0,0,0x0000001000000402,0), + (30064,2,0,0,0,0,0,0x0000871B804CC41A,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18218,18219); +INSERT INTO `spell_affect` VALUES + (18218,0,0,0,0,0,0,0x000007138048C41A,0), + (18219,0,0,0,0,0,0,0x000007138048C41A,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30085,30086); +INSERT INTO `spell_affect` VALUES + (30085,0,0,0,0,0,0,0x0000071B804CC41A,0), + (30085,1,0,0,0,0,0,0x0000000000000400,0), + (30085,2,0,0,0,0,0,0x0000000000000002,0), + (30086,0,0,0,0,0,0,0x0000071B804CC41A,0), + (30086,1,0,0,0,0,0,0x0000000000000400,0), + (30086,2,0,0,0,0,0,0x0000000000000002,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18174,18175,18176,18177,18178); +INSERT INTO `spell_affect` VALUES + (18174,0,0,0,0,0,0,0x0000071B804CC41A,0), + (18175,0,0,0,0,0,0,0x0000071B804CC41A,0), + (18176,0,0,0,0,0,0,0x0000071B804CC41A,0), + (18177,0,0,0,0,0,0,0x0000071B804CC41A,0), + (18178,0,0,0,0,0,0,0x0000071B804CC41A,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30143,30144,30145); +INSERT INTO `spell_affect` VALUES + (30143,0,0,0,0,0,0,0x0000002000000000,0), + (30144,0,0,0,0,0,0,0x0000002000000000,0), + (30145,0,0,0,0,0,0,0x0000002000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30319,30320,30321); +INSERT INTO `spell_affect` VALUES + (30319,1,0,0,0,0,0,0x0000400000000000,0), + (30320,1,0,0,0,0,0,0x0000400000000000,0), + (30321,1,0,0,0,0,0,0x0000400000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33063); +INSERT INTO `spell_affect` VALUES + (33063,0,0,0,0,0,0,0x0000040000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30242,30245,30246,30247,30248); +INSERT INTO `spell_affect` VALUES + (30242,0,0,0,0,0,0,0x0000200000000000,0), + (30245,0,0,0,0,0,0,0x0000200000000000,0), + (30246,0,0,0,0,0,0,0x0000200000000000,0), + (30247,0,0,0,0,0,0,0x0000200000000000,0), + (30248,0,0,0,0,0,0,0x0000200000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (32477,32483,32484); +INSERT INTO `spell_affect` VALUES + (32477,0,0,0,0,0,0,0x0000020000000000,0), + (32483,0,0,0,0,0,0,0x0000020000000000,0), + (32484,0,0,0,0,0,0,0x0000020000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (30251,30256); +INSERT INTO `spell_affect` VALUES + (30251,0,0,0,0,0,0,0x000010C000000125,0), + (30256,0,0,0,0,0,0,0x000010C000000125,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17954,17955,17956,17957,17958); +INSERT INTO `spell_affect` VALUES + (17954,0,0,0,0,0,0,0x000000C000001364,0), + (17954,1,0,0,0,0,0,0x000000C000001364,0), + (17955,0,0,0,0,0,0,0x000000C000001364,0), + (17955,1,0,0,0,0,0,0x000000C000001364,0), + (17956,0,0,0,0,0,0,0x000000C000001364,0), + (17956,1,0,0,0,0,0,0x000000C000001364,0), + (17957,0,0,0,0,0,0,0x000000C000001364,0), + (17957,1,0,0,0,0,0,0x000000C000001364,0), + (17958,0,0,0,0,0,0,0x000000C000001364,0), + (17958,1,0,0,0,0,0,0x000000C000001364,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18213,18372); +INSERT INTO `spell_affect` VALUES + (18213,0,0,0,0,0,0,0x0000000000004000,0), + (18213,1,0,0,0,0,0,0x0000871B804CC41A,0), + (18372,0,0,0,0,0,0,0x0000000000004000,0), + (18372,1,0,0,0,0,0,0x0000871B804CC41A,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (18271,18272,18273,18274,18275); +INSERT INTO `spell_affect` VALUES + (18271,0,0,0,0,0,0,0x000011130008A48B,0), + (18271,1,0,0,0,0,0,0x000011130008A48B,0), + (18272,0,0,0,0,0,0,0x000011130008A48B,0), + (18272,1,0,0,0,0,0,0x000011130008A48B,0), + (18273,0,0,0,0,0,0,0x000011130008A48B,0), + (18273,1,0,0,0,0,0,0x000011130008A48B,0), + (18274,0,0,0,0,0,0,0x000011130008A48B,0), + (18274,1,0,0,0,0,0,0x000011130008A48B,0), + (18275,0,0,0,0,0,0,0x000011130008A48B,0), + (18275,1,0,0,0,0,0,0x000011130008A48B,0); diff --git a/sql/updates/0.10/5463_mangos_command.sql b/sql/updates/0.10/5463_mangos_command.sql new file mode 100644 index 000000000..66ce5617e --- /dev/null +++ b/sql/updates/0.10/5463_mangos_command.sql @@ -0,0 +1,2 @@ +DELETE FROM `command` WHERE `name` = 'cshutdown'; +UPDATE `command` SET `help`='Syntax: .shutdown seconds\r\n\r\nShut the server down after given seconds or cancel the shutdown if cancel value is used.' WHERE `name` = 'shutdown'; diff --git a/sql/updates/0.10/5466_mangos_spell_affect.sql b/sql/updates/0.10/5466_mangos_spell_affect.sql new file mode 100644 index 000000000..f23e27289 --- /dev/null +++ b/sql/updates/0.10/5466_mangos_spell_affect.sql @@ -0,0 +1,67 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (12295,12676,12677); +INSERT INTO `spell_affect` VALUES + (12295,1,0,0,0,0,0,0x0000000002000000,0), + (12295,2,0,0,0,0,0,0x0000040000000000,0), + (12676,1,0,0,0,0,0,0x0000000002000000,0), + (12676,2,0,0,0,0,0,0x0000040000000000,0), + (12677,1,0,0,0,0,0,0x0000000002000000,0), + (12677,2,0,0,0,0,0,0x0000040000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12308,12810,12811); +INSERT INTO `spell_affect` VALUES + (12308,0,0,0,0,0,0,0x0000000000004000,0), + (12810,0,0,0,0,0,0,0x0000000000004000,0), + (12811,0,0,0,0,0,0,0x0000000000004000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (13981,14066); +INSERT INTO `spell_affect` VALUES + (13981,0,0,0,0,0,0,0x0000000001000000,0), + (13981,1,0,0,0,0,0,0x0000000000000800,0), + (14066,0,0,0,0,0,0,0x0000000001000000,0), + (14066,1,0,0,0,0,0,0x0000000000000800,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (14523,14784,14785,14786,14787); +INSERT INTO `spell_affect` VALUES + (14523,1,0,0,0,0,0,0x000000208030016B,0), + (14523,2,0,0,0,0,0,0x000000208030016B,0), + (14784,1,0,0,0,0,0,0x000000208030016B,0), + (14784,2,0,0,0,0,0,0x000000208030016B,0), + (14785,1,0,0,0,0,0,0x000000208030016B,0), + (14785,2,0,0,0,0,0,0x000000208030016B,0), + (14786,1,0,0,0,0,0,0x000000208030016B,0), + (14786,2,0,0,0,0,0,0x000000208030016B,0), + (14787,1,0,0,0,0,0,0x000000208030016B,0), + (14787,2,0,0,0,0,0,0x000000208030016B,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (29759,29760,29761,29762,29763); +INSERT INTO `spell_affect` VALUES + (29759,1,0,0,0,0,0,0x0000075D6E6ECEEF,0), + (29760,1,0,0,0,0,0,0x0000075D6E6ECEEF,0), + (29761,1,0,0,0,0,0,0x0000075D6E6ECEEF,0), + (29762,1,0,0,0,0,0,0x0000075D6E6ECEEF,0), + (29763,1,0,0,0,0,0,0x0000075D6E6ECEEF,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (34466,34467,34468,34469,34470); +INSERT INTO `spell_affect` VALUES + (34466,1,0,0,0,0,0,0x0000001000000000,0), + (34467,1,0,0,0,0,0,0x0000001000000000,0), + (34468,1,0,0,0,0,0,0x0000001000000000,0), + (34469,1,0,0,0,0,0,0x0000001000000000,0), + (34470,1,0,0,0,0,0,0x0000001000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (34318,37209); +INSERT INTO `spell_affect` VALUES + (34318,0,0,0,0,0,0,0x0000000000000400,0), + (34318,1,0,0,0,0,0,0x0000002000000000,0), + (37209,0,0,0,0,0,0,0x0000000000000400,0), + (37209,1,0,0,0,0,0,0x0000002000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44301,44302); +INSERT INTO `spell_affect` VALUES + (44301,0,0,0,0,0,0,0x0000000001000000,0), + (44302,0,0,0,0,0,0,0x0000000001000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37424); +INSERT INTO `spell_affect` VALUES + (37424,0,0,0,0,0,0,0x0000000000008000,0); + diff --git a/sql/updates/0.10/5471_mangos_spell_affect.sql b/sql/updates/0.10/5471_mangos_spell_affect.sql new file mode 100644 index 000000000..ae3d5275c --- /dev/null +++ b/sql/updates/0.10/5471_mangos_spell_affect.sql @@ -0,0 +1,70 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (35578,35581); +INSERT INTO `spell_affect` VALUES + (35578,0,0,0,0,0,0,0x0000000028E212F7,0), + (35581,0,0,0,0,0,0,0x0000000028E212F7,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23047); +INSERT INTO `spell_affect` VALUES + (23047,0,0,0,0,0,0,0x0000040000000000,0), + (23047,1,0,0,0,0,0,0x0000040000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23158); +INSERT INTO `spell_affect` VALUES + (23158,0,0,0,0,0,0,0x0000000000000200,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23561); +INSERT INTO `spell_affect` VALUES + (23561,0,0,0,0,0,0,0x0000000000004000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23566); +INSERT INTO `spell_affect` VALUES + (23566,0,0,0,0,0,0,0x0000000000001000,0), + (23566,1,0,0,0,0,0,0x0000000000002000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (24469); +INSERT INTO `spell_affect` VALUES + (24469,0,0,0,0,0,0,0x0000000001000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (26106); +INSERT INTO `spell_affect` VALUES + (26106,0,0,0,0,0,0,0x0000000010000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (26112); +INSERT INTO `spell_affect` VALUES + (26112,0,0,0,0,0,0,0x0000000000000020,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44300); +INSERT INTO `spell_affect` VALUES + (44300,0,0,0,0,0,0,0x0000800000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37763); +INSERT INTO `spell_affect` VALUES + (37763,0,0,0,0,0,0,0x0000800000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43725); +INSERT INTO `spell_affect` VALUES + (43725,0,0,0,0,0,0,0x0000001000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43736); +INSERT INTO `spell_affect` VALUES + (43736,0,0,0,0,0,0,0x0000000000000010,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43752); +INSERT INTO `spell_affect` VALUES + (43752,0,0,0,0,0,0,0x0000000000000100,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44292); +INSERT INTO `spell_affect` VALUES + (44292,0,0,0,0,0,0,0x0000000000001000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44295); +INSERT INTO `spell_affect` VALUES + (44295,0,0,0,0,0,0,0x0000000090100000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44296); +INSERT INTO `spell_affect` VALUES + (44296,0,0,0,0,0,0,0x0000000000000001,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (44299); +INSERT INTO `spell_affect` VALUES + (44299,0,0,0,0,0,0,0x0000000000040000,0); diff --git a/sql/updates/0.10/5482_mangos_spell_affect.sql b/sql/updates/0.10/5482_mangos_spell_affect.sql new file mode 100644 index 000000000..f6a476ad5 --- /dev/null +++ b/sql/updates/0.10/5482_mangos_spell_affect.sql @@ -0,0 +1,5 @@ +ALTER TABLE spell_affect + DROP SpellId, + DROP SchoolMask, + DROP Category, + DROP SkillID; diff --git a/sql/updates/0.10/5491_mangos_player_levelstats.sql b/sql/updates/0.10/5491_mangos_player_levelstats.sql new file mode 100644 index 000000000..6cf36e5e2 --- /dev/null +++ b/sql/updates/0.10/5491_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 20 WHERE `class` = 1 AND `level`=1; +UPDATE `player_levelstats` SET `basehp` = 29 WHERE `class` = 1 AND `level`=2; +UPDATE `player_levelstats` SET `basehp` = 38 WHERE `class` = 1 AND `level`=3; +UPDATE `player_levelstats` SET `basehp` = 47 WHERE `class` = 1 AND `level`=4; +UPDATE `player_levelstats` SET `basehp` = 56 WHERE `class` = 1 AND `level`=5; +UPDATE `player_levelstats` SET `basehp` = 65 WHERE `class` = 1 AND `level`=6; +UPDATE `player_levelstats` SET `basehp` = 74 WHERE `class` = 1 AND `level`=7; +UPDATE `player_levelstats` SET `basehp` = 83 WHERE `class` = 1 AND `level`=8; +UPDATE `player_levelstats` SET `basehp` = 92 WHERE `class` = 1 AND `level`=9; +UPDATE `player_levelstats` SET `basehp` = 101 WHERE `class` = 1 AND `level`=10; +UPDATE `player_levelstats` SET `basehp` = 100 WHERE `class` = 1 AND `level`=11; +UPDATE `player_levelstats` SET `basehp` = 109 WHERE `class` = 1 AND `level`=12; +UPDATE `player_levelstats` SET `basehp` = 118 WHERE `class` = 1 AND `level`=13; +UPDATE `player_levelstats` SET `basehp` = 128 WHERE `class` = 1 AND `level`=14; +UPDATE `player_levelstats` SET `basehp` = 139 WHERE `class` = 1 AND `level`=15; +UPDATE `player_levelstats` SET `basehp` = 151 WHERE `class` = 1 AND `level`=16; +UPDATE `player_levelstats` SET `basehp` = 154 WHERE `class` = 1 AND `level`=17; +UPDATE `player_levelstats` SET `basehp` = 168 WHERE `class` = 1 AND `level`=18; +UPDATE `player_levelstats` SET `basehp` = 183 WHERE `class` = 1 AND `level`=19; +UPDATE `player_levelstats` SET `basehp` = 199 WHERE `class` = 1 AND `level`=20; +UPDATE `player_levelstats` SET `basehp` = 206 WHERE `class` = 1 AND `level`=21; +UPDATE `player_levelstats` SET `basehp` = 224 WHERE `class` = 1 AND `level`=22; +UPDATE `player_levelstats` SET `basehp` = 243 WHERE `class` = 1 AND `level`=23; +UPDATE `player_levelstats` SET `basehp` = 253 WHERE `class` = 1 AND `level`=24; +UPDATE `player_levelstats` SET `basehp` = 274 WHERE `class` = 1 AND `level`=25; +UPDATE `player_levelstats` SET `basehp` = 296 WHERE `class` = 1 AND `level`=26; +UPDATE `player_levelstats` SET `basehp` = 309 WHERE `class` = 1 AND `level`=27; +UPDATE `player_levelstats` SET `basehp` = 333 WHERE `class` = 1 AND `level`=28; +UPDATE `player_levelstats` SET `basehp` = 348 WHERE `class` = 1 AND `level`=29; +UPDATE `player_levelstats` SET `basehp` = 374 WHERE `class` = 1 AND `level`=30; +UPDATE `player_levelstats` SET `basehp` = 401 WHERE `class` = 1 AND `level`=31; +UPDATE `player_levelstats` SET `basehp` = 419 WHERE `class` = 1 AND `level`=32; +UPDATE `player_levelstats` SET `basehp` = 448 WHERE `class` = 1 AND `level`=33; +UPDATE `player_levelstats` SET `basehp` = 468 WHERE `class` = 1 AND `level`=34; +UPDATE `player_levelstats` SET `basehp` = 499 WHERE `class` = 1 AND `level`=35; +UPDATE `player_levelstats` SET `basehp` = 521 WHERE `class` = 1 AND `level`=36; +UPDATE `player_levelstats` SET `basehp` = 545 WHERE `class` = 1 AND `level`=37; +UPDATE `player_levelstats` SET `basehp` = 581 WHERE `class` = 1 AND `level`=38; +UPDATE `player_levelstats` SET `basehp` = 609 WHERE `class` = 1 AND `level`=39; +UPDATE `player_levelstats` SET `basehp` = 649 WHERE `class` = 1 AND `level`=40; +UPDATE `player_levelstats` SET `basehp` = 681 WHERE `class` = 1 AND `level`=41; +UPDATE `player_levelstats` SET `basehp` = 715 WHERE `class` = 1 AND `level`=42; +UPDATE `player_levelstats` SET `basehp` = 761 WHERE `class` = 1 AND `level`=43; +UPDATE `player_levelstats` SET `basehp` = 799 WHERE `class` = 1 AND `level`=44; +UPDATE `player_levelstats` SET `basehp` = 839 WHERE `class` = 1 AND `level`=45; +UPDATE `player_levelstats` SET `basehp` = 881 WHERE `class` = 1 AND `level`=46; +UPDATE `player_levelstats` SET `basehp` = 935 WHERE `class` = 1 AND `level`=47; +UPDATE `player_levelstats` SET `basehp` = 981 WHERE `class` = 1 AND `level`=48; +UPDATE `player_levelstats` SET `basehp` = 1029 WHERE `class` = 1 AND `level`=49; +UPDATE `player_levelstats` SET `basehp` = 1079 WHERE `class` = 1 AND `level`=50; +UPDATE `player_levelstats` SET `basehp` = 1131 WHERE `class` = 1 AND `level`=51; +UPDATE `player_levelstats` SET `basehp` = 1185 WHERE `class` = 1 AND `level`=52; +UPDATE `player_levelstats` SET `basehp` = 1241 WHERE `class` = 1 AND `level`=53; +UPDATE `player_levelstats` SET `basehp` = 1299 WHERE `class` = 1 AND `level`=54; +UPDATE `player_levelstats` SET `basehp` = 1359 WHERE `class` = 1 AND `level`=55; +UPDATE `player_levelstats` SET `basehp` = 1421 WHERE `class` = 1 AND `level`=56; +UPDATE `player_levelstats` SET `basehp` = 1485 WHERE `class` = 1 AND `level`=57; +UPDATE `player_levelstats` SET `basehp` = 1551 WHERE `class` = 1 AND `level`=58; +UPDATE `player_levelstats` SET `basehp` = 1619 WHERE `class` = 1 AND `level`=59; +UPDATE `player_levelstats` SET `basehp` = 1689 WHERE `class` = 1 AND `level`=60; +UPDATE `player_levelstats` SET `basehp` = 1902 WHERE `class` = 1 AND `level`=61; +UPDATE `player_levelstats` SET `basehp` = 2129 WHERE `class` = 1 AND `level`=62; +UPDATE `player_levelstats` SET `basehp` = 2357 WHERE `class` = 1 AND `level`=63; +UPDATE `player_levelstats` SET `basehp` = 2612 WHERE `class` = 1 AND `level`=64; +UPDATE `player_levelstats` SET `basehp` = 2883 WHERE `class` = 1 AND `level`=65; +UPDATE `player_levelstats` SET `basehp` = 3169 WHERE `class` = 1 AND `level`=66; +UPDATE `player_levelstats` SET `basehp` = 3455 WHERE `class` = 1 AND `level`=67; +UPDATE `player_levelstats` SET `basehp` = 3774 WHERE `class` = 1 AND `level`=68; +UPDATE `player_levelstats` SET `basehp` = 4109 WHERE `class` = 1 AND `level`=69; +UPDATE `player_levelstats` SET `basehp` = 4444 WHERE `class` = 1 AND `level`=70; diff --git a/sql/updates/0.10/5492_mangos_player_levelstats.sql b/sql/updates/0.10/5492_mangos_player_levelstats.sql new file mode 100644 index 000000000..273445341 --- /dev/null +++ b/sql/updates/0.10/5492_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 28, `basemana` = 60 WHERE `class` = 2 AND `level`=1; +UPDATE `player_levelstats` SET `basehp` = 36, `basemana` = 78 WHERE `class` = 2 AND `level`=2; +UPDATE `player_levelstats` SET `basehp` = 44, `basemana` = 98 WHERE `class` = 2 AND `level`=3; +UPDATE `player_levelstats` SET `basehp` = 52, `basemana` = 104 WHERE `class` = 2 AND `level`=4; +UPDATE `player_levelstats` SET `basehp` = 60, `basemana` = 111 WHERE `class` = 2 AND `level`=5; +UPDATE `player_levelstats` SET `basehp` = 68, `basemana` = 134 WHERE `class` = 2 AND `level`=6; +UPDATE `player_levelstats` SET `basehp` = 76, `basemana` = 143 WHERE `class` = 2 AND `level`=7; +UPDATE `player_levelstats` SET `basehp` = 84, `basemana` = 153 WHERE `class` = 2 AND `level`=8; +UPDATE `player_levelstats` SET `basehp` = 92, `basemana` = 179 WHERE `class` = 2 AND `level`=9; +UPDATE `player_levelstats` SET `basehp` = 100, `basemana` = 192 WHERE `class` = 2 AND `level`=10; +UPDATE `player_levelstats` SET `basehp` = 108, `basemana` = 205 WHERE `class` = 2 AND `level`=11; +UPDATE `player_levelstats` SET `basehp` = 116, `basemana` = 219 WHERE `class` = 2 AND `level`=12; +UPDATE `player_levelstats` SET `basehp` = 124, `basemana` = 249 WHERE `class` = 2 AND `level`=13; +UPDATE `player_levelstats` SET `basehp` = 132, `basemana` = 265 WHERE `class` = 2 AND `level`=14; +UPDATE `player_levelstats` SET `basehp` = 131, `basemana` = 282 WHERE `class` = 2 AND `level`=15; +UPDATE `player_levelstats` SET `basehp` = 141, `basemana` = 315 WHERE `class` = 2 AND `level`=16; +UPDATE `player_levelstats` SET `basehp` = 152, `basemana` = 334 WHERE `class` = 2 AND `level`=17; +UPDATE `player_levelstats` SET `basehp` = 164, `basemana` = 354 WHERE `class` = 2 AND `level`=18; +UPDATE `player_levelstats` SET `basehp` = 177, `basemana` = 390 WHERE `class` = 2 AND `level`=19; +UPDATE `player_levelstats` SET `basehp` = 191, `basemana` = 412 WHERE `class` = 2 AND `level`=20; +UPDATE `player_levelstats` SET `basehp` = 206, `basemana` = 435 WHERE `class` = 2 AND `level`=21; +UPDATE `player_levelstats` SET `basehp` = 222, `basemana` = 459 WHERE `class` = 2 AND `level`=22; +UPDATE `player_levelstats` SET `basehp` = 239, `basemana` = 499 WHERE `class` = 2 AND `level`=23; +UPDATE `player_levelstats` SET `basehp` = 247, `basemana` = 525 WHERE `class` = 2 AND `level`=24; +UPDATE `player_levelstats` SET `basehp` = 266, `basemana` = 552 WHERE `class` = 2 AND `level`=25; +UPDATE `player_levelstats` SET `basehp` = 286, `basemana` = 579 WHERE `class` = 2 AND `level`=26; +UPDATE `player_levelstats` SET `basehp` = 307, `basemana` = 621 WHERE `class` = 2 AND `level`=27; +UPDATE `player_levelstats` SET `basehp` = 329, `basemana` = 648 WHERE `class` = 2 AND `level`=28; +UPDATE `player_levelstats` SET `basehp` = 342, `basemana` = 675 WHERE `class` = 2 AND `level`=29; +UPDATE `player_levelstats` SET `basehp` = 366, `basemana` = 702 WHERE `class` = 2 AND `level`=30; +UPDATE `player_levelstats` SET `basehp` = 391, `basemana` = 729 WHERE `class` = 2 AND `level`=31; +UPDATE `player_levelstats` SET `basehp` = 407, `basemana` = 756 WHERE `class` = 2 AND `level`=32; +UPDATE `player_levelstats` SET `basehp` = 434, `basemana` = 798 WHERE `class` = 2 AND `level`=33; +UPDATE `player_levelstats` SET `basehp` = 462, `basemana` = 825 WHERE `class` = 2 AND `level`=34; +UPDATE `player_levelstats` SET `basehp` = 481, `basemana` = 852 WHERE `class` = 2 AND `level`=35; +UPDATE `player_levelstats` SET `basehp` = 511, `basemana` = 879 WHERE `class` = 2 AND `level`=36; +UPDATE `player_levelstats` SET `basehp` = 542, `basemana` = 906 WHERE `class` = 2 AND `level`=37; +UPDATE `player_levelstats` SET `basehp` = 564, `basemana` = 933 WHERE `class` = 2 AND `level`=38; +UPDATE `player_levelstats` SET `basehp` = 597, `basemana` = 960 WHERE `class` = 2 AND `level`=39; +UPDATE `player_levelstats` SET `basehp` = 621, `basemana` = 987 WHERE `class` = 2 AND `level`=40; +UPDATE `player_levelstats` SET `basehp` = 656, `basemana` =1014 WHERE `class` = 2 AND `level`=41; +UPDATE `player_levelstats` SET `basehp` = 682, `basemana` =1041 WHERE `class` = 2 AND `level`=42; +UPDATE `player_levelstats` SET `basehp` = 719, `basemana` =1068 WHERE `class` = 2 AND `level`=43; +UPDATE `player_levelstats` SET `basehp` = 747, `basemana` =1110 WHERE `class` = 2 AND `level`=44; +UPDATE `player_levelstats` SET `basehp` = 786, `basemana` =1137 WHERE `class` = 2 AND `level`=45; +UPDATE `player_levelstats` SET `basehp` = 816, `basemana` =1164 WHERE `class` = 2 AND `level`=46; +UPDATE `player_levelstats` SET `basehp` = 857, `basemana` =1176 WHERE `class` = 2 AND `level`=47; +UPDATE `player_levelstats` SET `basehp` = 889, `basemana` =1203 WHERE `class` = 2 AND `level`=48; +UPDATE `player_levelstats` SET `basehp` = 922, `basemana` =1230 WHERE `class` = 2 AND `level`=49; +UPDATE `player_levelstats` SET `basehp` = 966, `basemana` =1257 WHERE `class` = 2 AND `level`=50; +UPDATE `player_levelstats` SET `basehp` =1001, `basemana` =1284 WHERE `class` = 2 AND `level`=51; +UPDATE `player_levelstats` SET `basehp` =1037, `basemana` =1311 WHERE `class` = 2 AND `level`=52; +UPDATE `player_levelstats` SET `basehp` =1084, `basemana` =1338 WHERE `class` = 2 AND `level`=53; +UPDATE `player_levelstats` SET `basehp` =1122, `basemana` =1365 WHERE `class` = 2 AND `level`=54; +UPDATE `player_levelstats` SET `basehp` =1161, `basemana` =1392 WHERE `class` = 2 AND `level`=55; +UPDATE `player_levelstats` SET `basehp` =1201, `basemana` =1419 WHERE `class` = 2 AND `level`=56; +UPDATE `player_levelstats` SET `basehp` =1252, `basemana` =1446 WHERE `class` = 2 AND `level`=57; +UPDATE `player_levelstats` SET `basehp` =1294, `basemana` =1458 WHERE `class` = 2 AND `level`=58; +UPDATE `player_levelstats` SET `basehp` =1337, `basemana` =1485 WHERE `class` = 2 AND `level`=59; +UPDATE `player_levelstats` SET `basehp` =1381, `basemana` =1512 WHERE `class` = 2 AND `level`=60; +UPDATE `player_levelstats` SET `basehp` =1540, `basemana` =1656 WHERE `class` = 2 AND `level`=61; +UPDATE `player_levelstats` SET `basehp` =1708, `basemana` =1800 WHERE `class` = 2 AND `level`=62; +UPDATE `player_levelstats` SET `basehp` =1884, `basemana` =1944 WHERE `class` = 2 AND `level`=63; +UPDATE `player_levelstats` SET `basehp` =2068, `basemana` =2088 WHERE `class` = 2 AND `level`=64; +UPDATE `player_levelstats` SET `basehp` =2262, `basemana` =2232 WHERE `class` = 2 AND `level`=65; +UPDATE `player_levelstats` SET `basehp` =2466, `basemana` =2377 WHERE `class` = 2 AND `level`=66; +UPDATE `player_levelstats` SET `basehp` =2679, `basemana` =2521 WHERE `class` = 2 AND `level`=67; +UPDATE `player_levelstats` SET `basehp` =2901, `basemana` =2665 WHERE `class` = 2 AND `level`=68; +UPDATE `player_levelstats` SET `basehp` =3134, `basemana` =2809 WHERE `class` = 2 AND `level`=69; +UPDATE `player_levelstats` SET `basehp` =3377, `basemana` =2953 WHERE `class` = 2 AND `level`=70; diff --git a/sql/updates/0.10/5498_mangos_spell_affect.sql b/sql/updates/0.10/5498_mangos_spell_affect.sql new file mode 100644 index 000000000..f2f62fb56 --- /dev/null +++ b/sql/updates/0.10/5498_mangos_spell_affect.sql @@ -0,0 +1,8 @@ +-- Ice Shards +UPDATE spell_affect SET SpellFamilyMask = SpellFamilyMask | 0x20000 WHERE (entry = 11207) OR (entry = 12672) OR (entry = 15047) OR (entry = 15052) OR (entry = 15053); +-- Piercing Ice +UPDATE spell_affect SET SpellFamilyMask = SpellFamilyMask | 0x20000 WHERE ((entry = 11151) OR (entry = 12952) OR (entry = 12953) OR (entry = 12954) OR (entry = 12957)) AND (effectId = 0); +-- Arctic Reach +UPDATE spell_affect SET SpellFamilyMask = SpellFamilyMask | 0x20000 WHERE ((entry = 16757) OR (entry = 16758)) AND (effectId = 0); +-- Frost Channeling +UPDATE spell_affect SET SpellFamilyMask = SpellFamilyMask | 0x20000 WHERE ((entry = 11160) OR (entry = 12518) OR (entry = 12519)) AND (effectId = 0); \ No newline at end of file diff --git a/sql/updates/0.10/5505_mangos.sql b/sql/updates/0.10/5505_mangos.sql new file mode 100644 index 000000000..72cc66e56 --- /dev/null +++ b/sql/updates/0.10/5505_mangos.sql @@ -0,0 +1,801 @@ +-- Then update all tables +ALTER TABLE `areatrigger_involvedrelation` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier', + CHANGE COLUMN `quest` `quest` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Quest Identifier'; +ALTER TABLE `areatrigger_tavern` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier'; +ALTER TABLE `areatrigger_teleport` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier', + CHANGE COLUMN `required_level` `required_level` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `required_item` `required_item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `target_map` `target_map` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `battleground_template` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL, + CHANGE COLUMN `MinPlayersPerTeam` `MinPlayersPerTeam` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `MaxPlayersPerTeam` `MaxPlayersPerTeam` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `MinLvl` `MinLvl` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `MaxLvl` `MaxLvl` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `AllianceStartLoc` `AllianceStartLoc` mediumint unsigned NOT NULL, + CHANGE COLUMN `HordeStartLoc` `HordeStartLoc` mediumint unsigned NOT NULL; +ALTER TABLE `battlemaster_entry` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Entry of a creature', + CHANGE COLUMN `bg_template` `bg_template` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Battleground template id'; +ALTER TABLE `command` + CHANGE COLUMN `security` `security` tinyint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `creature` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL auto_increment COMMENT 'Global Unique Identifier', + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Creature Identifier', + CHANGE COLUMN `map` `map` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'Map Identifier', + CHANGE COLUMN `modelid` `modelid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipment_id` `equipment_id` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `spawntimesecs` `spawntimesecs` integer unsigned NOT NULL DEFAULT 120, + CHANGE COLUMN `currentwaypoint` `currentwaypoint` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `curhealth` `curhealth` integer unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `curmana` `curmana` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `DeathState` `DeathState` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `MovementType` `MovementType` tinyint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `creature_addon` + CHANGE COLUMN `guid` `guid` integer NOT NULL DEFAULT 0, + CHANGE COLUMN `mount` `mount` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `bytes0` `bytes0` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `bytes1` `bytes1` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `bytes2` `bytes2` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `emote` `emote` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `creature_equip_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Unique entry', + CHANGE COLUMN `equipmodel1` `equipmodel1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipmodel2` `equipmodel2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipmodel3` `equipmodel3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipinfo1` `equipinfo1` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipinfo2` `equipinfo2` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipinfo3` `equipinfo3` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipslot1` `equipslot1` integer NOT NULL DEFAULT 0, + CHANGE COLUMN `equipslot2` `equipslot2` integer NOT NULL DEFAULT 0, + CHANGE COLUMN `equipslot3` `equipslot3` integer NOT NULL DEFAULT 0; +ALTER TABLE `creature_involvedrelation` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier', + CHANGE COLUMN `quest` `quest` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Quest Identifier'; +ALTER TABLE `creature_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `creature_model_info` + CHANGE COLUMN `modelid` `modelid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `gender` `gender` tinyint unsigned NOT NULL DEFAULT 2, + CHANGE COLUMN `modelid_other_gender` `modelid_other_gender` mediumint unsigned NOT NULL DEFAULT 0; +UPDATE `creature_movement` SET `orientation`=0 WHERE `orientation` IS NULL; +UPDATE `creature_movement` SET `model1`=0 WHERE `model1` IS NULL; +UPDATE `creature_movement` SET `model2`=0 WHERE `model2` IS NULL; +ALTER TABLE `creature_movement` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier', + CHANGE COLUMN `point` `point` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `waittime` `waittime` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `aiscript` `aiscript` varchar(128), + CHANGE COLUMN `emote` `emote` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spell` `spell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `wpguid` `wpguid` integer NOT NULL DEFAULT 0, + CHANGE COLUMN `orientation` `orientation` float NOT NULL DEFAULT 0, + CHANGE COLUMN `model1` `model1` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `model2` `model2` mediumint NOT NULL DEFAULT 0; +ALTER TABLE `creature_onkill_reputation` + CHANGE COLUMN `creature_id` `creature_id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Creature Identifier', + CHANGE COLUMN `RewOnKillRepFaction1` `RewOnKillRepFaction1` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewOnKillRepFaction2` `RewOnKillRepFaction2` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `MaxStanding1` `MaxStanding1` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `IsTeamAward1` `IsTeamAward1` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewOnKillRepValue1` `RewOnKillRepValue1` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `MaxStanding2` `MaxStanding2` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `IsTeamAward2` `IsTeamAward2` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewOnKillRepValue2` `RewOnKillRepValue2` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `TeamDependent` `TeamDependent` tinyint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `creature_questrelation` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier', + CHANGE COLUMN `quest` `quest` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Quest Identifier'; +ALTER TABLE `creature_respawn` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL DEFAULT 0 COMMENT 'Global Unique Identifier', + CHANGE COLUMN `respawntime` `respawntime` bigint NOT NULL DEFAULT 0, + CHANGE COLUMN `instance` `instance` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `creature_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `modelid_A` `modelid_A` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `modelid_A2` `modelid_A2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `modelid_H` `modelid_H` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `modelid_H2` `modelid_H2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `minlevel` `minlevel` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxlevel` `maxlevel` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `minhealth` `minhealth` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxhealth` `maxhealth` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `minmana` `minmana` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxmana` `maxmana` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `armor` `armor` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `faction_A` `faction_A` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `faction_H` `faction_H` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `npcflag` `npcflag` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `speed` `speed` float NOT NULL DEFAULT 1.0, + CHANGE COLUMN `scale` `scale` float NOT NULL DEFAULT 0, + CHANGE COLUMN `rank` `rank` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `mindmg` `mindmg` float NOT NULL DEFAULT 0, + CHANGE COLUMN `maxdmg` `maxdmg` float NOT NULL DEFAULT 0, + CHANGE COLUMN `dmgschool` `dmgschool` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `attackpower` `attackpower` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `baseattacktime` `baseattacktime` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `rangeattacktime` `rangeattacktime` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `flags` `flags` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `dynamicflags` `dynamicflags` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `family` `family` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `trainer_type` `trainer_type` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `trainer_spell` `trainer_spell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `race` `race` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `rangedattackpower` `rangedattackpower` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `type` `type` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `civilian` `civilian` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `flag1` `flag1` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootid` `lootid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `pickpocketloot` `pickpocketloot` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `skinloot` `skinloot` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `resistance1` `resistance1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `resistance2` `resistance2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `resistance3` `resistance3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `resistance4` `resistance4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `resistance5` `resistance5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `resistance6` `resistance6` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spell1` `spell1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spell2` `spell2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spell3` `spell3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spell4` `spell4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `mingold` `mingold` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxgold` `maxgold` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `AIName` `AIName` char(64) NOT NULL DEFAULT '', + CHANGE COLUMN `MovementType` `MovementType` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `InhabitType` `InhabitType` tinyint unsigned NOT NULL DEFAULT 3, + CHANGE COLUMN `RacialLeader` `RacialLeader` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RegenHealth` `RegenHealth` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `equipment_id` `equipment_id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `mechanic_immune_mask` `mechanic_immune_mask` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ScriptName` `ScriptName` char(64) NOT NULL DEFAULT ''; +ALTER TABLE `creature_template_addon` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `mount` `mount` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `bytes0` `bytes0` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `bytes1` `bytes1` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `bytes2` `bytes2` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `emote` `emote` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `disenchant_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Recommended id selection: item_level*100 + item_quality', + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `event_scripts` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `delay` `delay` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `command` `command` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong` `datalong` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong2` `datalong2` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `exploration_basexp` + CHANGE COLUMN `level` `level` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `basexp` `basexp` mediumint NOT NULL DEFAULT 0; +ALTER TABLE `fishing_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `game_event_creature` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL, + CHANGE COLUMN `event` `event` smallint NOT NULL DEFAULT 0 COMMENT 'Put negatives values to remove during event'; +ALTER TABLE `game_event_creature_quest` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `quest` `quest` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `event` `event` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `game_event_gameobject` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL, + CHANGE COLUMN `event` `event` smallint NOT NULL DEFAULT 0 COMMENT 'Put negatives values to remove during event'; +ALTER TABLE `game_event_model_equip` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `modelid` `modelid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `equipment_id` `equipment_id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `event` `event` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `game_graveyard_zone` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ghost_zone` `ghost_zone` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `faction` `faction` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `game_tele` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL auto_increment, + CHANGE COLUMN `map` `map` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `game_weather` + CHANGE COLUMN `zone` `zone` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spring_rain_chance` `spring_rain_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `spring_snow_chance` `spring_snow_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `spring_storm_chance` `spring_storm_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `summer_rain_chance` `summer_rain_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `summer_snow_chance` `summer_snow_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `summer_storm_chance` `summer_storm_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `fall_rain_chance` `fall_rain_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `fall_snow_chance` `fall_snow_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `fall_storm_chance` `fall_storm_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `winter_rain_chance` `winter_rain_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `winter_snow_chance` `winter_snow_chance` tinyint unsigned NOT NULL DEFAULT 25, + CHANGE COLUMN `winter_storm_chance` `winter_storm_chance` tinyint unsigned NOT NULL DEFAULT 25; +ALTER TABLE `gameobject` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL auto_increment COMMENT 'Global Unique Identifier', + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Gameobject Identifier', + CHANGE COLUMN `map` `map` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'Map Identifier', + CHANGE COLUMN `spawntimesecs` `spawntimesecs` integer NOT NULL DEFAULT 0, + CHANGE COLUMN `animprogress` `animprogress` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `state` `state` tinyint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `gameobject_involvedrelation` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `quest` `quest` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Quest Identifier'; +ALTER TABLE `gameobject_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `gameobject_questrelation` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `quest` `quest` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Quest Identifier'; +ALTER TABLE `gameobject_respawn` + CHANGE COLUMN `guid` `guid` integer unsigned NOT NULL DEFAULT 0 COMMENT 'Global Unique Identifier', + CHANGE COLUMN `respawntime` `respawntime` bigint NOT NULL DEFAULT 0, + CHANGE COLUMN `instance` `instance` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `gameobject_scripts` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `delay` `delay` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `command` `command` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong` `datalong` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong2` `datalong2` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `gameobject_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `type` `type` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `displayId` `displayId` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `name` `name` varchar(100) NOT NULL DEFAULT '', + CHANGE COLUMN `faction` `faction` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `flags` `flags` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data0` `data0` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data1` `data1` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data2` `data2` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data3` `data3` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data4` `data4` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data5` `data5` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data6` `data6` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data7` `data7` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data8` `data8` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data9` `data9` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data10` `data10` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data11` `data11` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data12` `data12` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data13` `data13` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data14` `data14` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data15` `data15` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data16` `data16` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data17` `data17` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data18` `data18` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data19` `data19` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data20` `data20` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data21` `data21` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data22` `data22` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `data23` `data23` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ScriptName` `ScriptName` varchar(64) NOT NULL DEFAULT ''; +ALTER TABLE `instance_template` + CHANGE COLUMN `map` `map` smallint unsigned NOT NULL, + CHANGE COLUMN `parent` `parent` integer unsigned NOT NULL, + CHANGE COLUMN `levelMin` `levelMin` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `levelMax` `levelMax` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxPlayers` `maxPlayers` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `reset_delay` `reset_delay` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `script` `script` varchar(128) NOT NULL DEFAULT ''; +ALTER TABLE `item_enchantment_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ench` `ench` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `item_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` smallint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` smallint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `item_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `subclass` `subclass` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `unk0` `unk0` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `name` `name` varchar(255) NOT NULL DEFAULT '', + CHANGE COLUMN `displayid` `displayid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Quality` `Quality` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Flags` `Flags` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `BuyCount` `BuyCount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `BuyPrice` `BuyPrice` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SellPrice` `SellPrice` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `InventoryType` `InventoryType` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `AllowableClass` `AllowableClass` mediumint NOT NULL DEFAULT -1, + CHANGE COLUMN `AllowableRace` `AllowableRace` mediumint NOT NULL DEFAULT -1, + CHANGE COLUMN `ItemLevel` `ItemLevel` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredLevel` `RequiredLevel` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredSkill` `RequiredSkill` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredSkillRank` `RequiredSkillRank` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `requiredspell` `requiredspell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `requiredhonorrank` `requiredhonorrank` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredCityRank` `RequiredCityRank` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredReputationFaction` `RequiredReputationFaction` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredReputationRank` `RequiredReputationRank` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxcount` `maxcount` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stackable` `stackable` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ContainerSlots` `ContainerSlots` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type1` `stat_type1` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value1` `stat_value1` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type2` `stat_type2` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value2` `stat_value2` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type3` `stat_type3` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value3` `stat_value3` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type4` `stat_type4` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value4` `stat_value4` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type5` `stat_type5` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value5` `stat_value5` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type6` `stat_type6` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value6` `stat_value6` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type7` `stat_type7` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value7` `stat_value7` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type8` `stat_type8` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value8` `stat_value8` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type9` `stat_type9` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value9` `stat_value9` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_type10` `stat_type10` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `stat_value10` `stat_value10` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `dmg_type1` `dmg_type1` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `dmg_type2` `dmg_type2` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `dmg_type3` `dmg_type3` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `dmg_type4` `dmg_type4` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `dmg_type5` `dmg_type5` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `armor` `armor` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `holy_res` `holy_res` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `fire_res` `fire_res` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `nature_res` `nature_res` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `frost_res` `frost_res` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `shadow_res` `shadow_res` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `arcane_res` `arcane_res` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `delay` `delay` smallint unsigned NOT NULL DEFAULT 1000, + CHANGE COLUMN `ammo_type` `ammo_type` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellid_1` `spellid_1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spelltrigger_1` `spelltrigger_1` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcharges_1` `spellcharges_1` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcooldown_1` `spellcooldown_1` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellcategory_1` `spellcategory_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcategorycooldown_1` `spellcategorycooldown_1` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellid_2` `spellid_2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spelltrigger_2` `spelltrigger_2` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcharges_2` `spellcharges_2` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcooldown_2` `spellcooldown_2` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellcategory_2` `spellcategory_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcategorycooldown_2` `spellcategorycooldown_2` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellid_3` `spellid_3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spelltrigger_3` `spelltrigger_3` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcharges_3` `spellcharges_3` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcooldown_3` `spellcooldown_3` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellcategory_3` `spellcategory_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcategorycooldown_3` `spellcategorycooldown_3` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellid_4` `spellid_4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spelltrigger_4` `spelltrigger_4` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcharges_4` `spellcharges_4` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcooldown_4` `spellcooldown_4` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellcategory_4` `spellcategory_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcategorycooldown_4` `spellcategorycooldown_4` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellid_5` `spellid_5` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spelltrigger_5` `spelltrigger_5` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcharges_5` `spellcharges_5` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcooldown_5` `spellcooldown_5` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `spellcategory_5` `spellcategory_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcategorycooldown_5` `spellcategorycooldown_5` integer NOT NULL DEFAULT -1, + CHANGE COLUMN `bonding` `bonding` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `PageText` `PageText` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `LanguageID` `LanguageID` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `PageMaterial` `PageMaterial` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `startquest` `startquest` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lockid` `lockid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Material` `Material` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `sheath` `sheath` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RandomProperty` `RandomProperty` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RandomSuffix` `RandomSuffix` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `block` `block` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `itemset` `itemset` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `MaxDurability` `MaxDurability` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `area` `area` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Map` `Map` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `BagFamily` `BagFamily` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `TotemCategory` `TotemCategory` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketColor_1` `socketColor_1` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketContent_1` `socketContent_1` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketColor_2` `socketColor_2` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketContent_2` `socketContent_2` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketColor_3` `socketColor_3` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketContent_3` `socketContent_3` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `socketBonus` `socketBonus` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `GemProperties` `GemProperties` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `ExtendedCost` `ExtendedCost` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `CondExtendedCost` `CondExtendedCost` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredDisenchantSkill` `RequiredDisenchantSkill` smallint NOT NULL DEFAULT -1, + CHANGE COLUMN `ScriptName` `ScriptName` varchar(64) NOT NULL DEFAULT '', + CHANGE COLUMN `DisenchantID` `DisenchantID` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `FoodType` `FoodType` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `minMoneyLoot` `minMoneyLoot` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxMoneyLoot` `maxMoneyLoot` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Duration` `Duration` integer NOT NULL DEFAULT 0 COMMENT 'Duration in seconds. Negative value means realtime, postive value ingame time'; +ALTER TABLE `locales_creature` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `locales_gameobject` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `locales_item` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `locales_npc_text` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `locales_page_text` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `locales_quest` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `mangos_string` + CHANGE COLUMN `content_default` `content_default` text NOT NULL, + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `npc_gossip` + CHANGE COLUMN `npc_guid` `npc_guid` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `textid` `textid` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `npc_gossip_textid` + CHANGE COLUMN `zoneid` `zoneid` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `action` `action` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `textid` `textid` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `npc_option` + CHANGE COLUMN `id` `id` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `gossip_id` `gossip_id` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `npcflag` `npcflag` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `icon` `icon` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `action` `action` tinyint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `npc_text` + CHANGE COLUMN `ID` `ID` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang0` `lang0` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em0_0` `em0_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em0_1` `em0_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em0_2` `em0_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em0_3` `em0_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em0_4` `em0_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em0_5` `em0_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang1` `lang1` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em1_0` `em1_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em1_1` `em1_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em1_2` `em1_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em1_3` `em1_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em1_4` `em1_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em1_5` `em1_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang2` `lang2` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em2_0` `em2_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em2_1` `em2_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em2_2` `em2_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em2_3` `em2_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em2_4` `em2_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em2_5` `em2_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang3` `lang3` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em3_0` `em3_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em3_1` `em3_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em3_2` `em3_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em3_3` `em3_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em3_4` `em3_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em3_5` `em3_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang4` `lang4` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em4_0` `em4_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em4_1` `em4_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em4_2` `em4_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em4_3` `em4_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em4_4` `em4_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em4_5` `em4_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang5` `lang5` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em5_0` `em5_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em5_1` `em5_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em5_2` `em5_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em5_3` `em5_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em5_4` `em5_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em5_5` `em5_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang6` `lang6` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em6_0` `em6_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em6_1` `em6_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em6_2` `em6_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em6_3` `em6_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em6_4` `em6_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em6_5` `em6_5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lang7` `lang7` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em7_0` `em7_0` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em7_1` `em7_1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em7_2` `em7_2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em7_3` `em7_3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em7_4` `em7_4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `em7_5` `em7_5` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `npc_trainer` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spell` `spell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `spellcost` `spellcost` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `reqskill` `reqskill` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `reqskillvalue` `reqskillvalue` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `reqlevel` `reqlevel` tinyint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `npc_vendor` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `incrtime` `incrtime` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `page_text` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `text` `text` longtext NOT NULL, + CHANGE COLUMN `next_page` `next_page` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `pet_levelstats` + CHANGE COLUMN `creature_entry` `creature_entry` mediumint unsigned NOT NULL, + CHANGE COLUMN `level` `level` tinyint unsigned NOT NULL, + CHANGE COLUMN `hp` `hp` smallint unsigned NOT NULL, + CHANGE COLUMN `mana` `mana` smallint unsigned NOT NULL, + CHANGE COLUMN `armor` `armor` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `str` `str` smallint unsigned NOT NULL, + CHANGE COLUMN `agi` `agi` smallint unsigned NOT NULL, + CHANGE COLUMN `sta` `sta` smallint unsigned NOT NULL, + CHANGE COLUMN `inte` `inte` smallint unsigned NOT NULL, + CHANGE COLUMN `spi` `spi` smallint unsigned NOT NULL; +ALTER TABLE `pet_name_generation` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL auto_increment, + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `half` `half` tinyint NOT NULL DEFAULT 0; +ALTER TABLE `petcreateinfo_spell` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Spell1` `Spell1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Spell2` `Spell2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Spell3` `Spell3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Spell4` `Spell4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `FamilyPassive` `FamilyPassive` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `pickpocketing_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `playercreateinfo` + CHANGE COLUMN `race` `race` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `map` `map` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `zone` `zone` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `playercreateinfo_action` + CHANGE COLUMN `race` `race` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `button` `button` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `action` `action` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `type` `type` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `misc` `misc` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `playercreateinfo_item` + CHANGE COLUMN `race` `race` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `itemid` `itemid` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `amount` `amount` tinyint unsigned NOT NULL DEFAULT 1; +ALTER TABLE `playercreateinfo_skill` + CHANGE COLUMN `race` `race` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Skill` `Skill` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `playercreateinfo_spell` + CHANGE COLUMN `race` `race` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `class` `class` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Spell` `Spell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Active` `Active` tinyint unsigned NOT NULL DEFAULT 1; +-- here posted +ALTER TABLE `prospecting_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `quest_end_scripts` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `delay` `delay` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `command` `command` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong` `datalong` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong2` `datalong2` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `quest_start_scripts` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `delay` `delay` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `command` `command` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong` `datalong` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong2` `datalong2` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `quest_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ZoneOrSort` `ZoneOrSort` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `MinLevel` `MinLevel` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestLevel` `QuestLevel` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Type` `Type` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredRaces` `RequiredRaces` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredSkillValue` `RequiredSkillValue` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RepObjectiveFaction` `RepObjectiveFaction` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RepObjectiveValue` `RepObjectiveValue` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredMinRepFaction` `RequiredMinRepFaction` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredMinRepValue` `RequiredMinRepValue` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredMaxRepFaction` `RequiredMaxRepFaction` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RequiredMaxRepValue` `RequiredMaxRepValue` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `SuggestedPlayers` `SuggestedPlayers` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `LimitTime` `LimitTime` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestFlags` `QuestFlags` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SpecialFlags` `SpecialFlags` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `PrevQuestId` `PrevQuestId` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `NextQuestId` `NextQuestId` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `ExclusiveGroup` `ExclusiveGroup` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `NextQuestInChain` `NextQuestInChain` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SrcItemId` `SrcItemId` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SrcItemCount` `SrcItemCount` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SrcSpell` `SrcSpell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemId1` `ReqItemId1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemId2` `ReqItemId2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemId3` `ReqItemId3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemId4` `ReqItemId4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemCount1` `ReqItemCount1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemCount2` `ReqItemCount2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemCount3` `ReqItemCount3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqItemCount4` `ReqItemCount4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceId1` `ReqSourceId1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceId2` `ReqSourceId2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceId3` `ReqSourceId3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceId4` `ReqSourceId4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceCount1` `ReqSourceCount1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceCount2` `ReqSourceCount2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceCount3` `ReqSourceCount3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceCount4` `ReqSourceCount4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceRef1` `ReqSourceRef1` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceRef2` `ReqSourceRef2` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceRef3` `ReqSourceRef3` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSourceRef4` `ReqSourceRef4` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOId1` `ReqCreatureOrGOId1` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOId2` `ReqCreatureOrGOId2` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOId3` `ReqCreatureOrGOId3` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOId4` `ReqCreatureOrGOId4` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOCount1` `ReqCreatureOrGOCount1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOCount2` `ReqCreatureOrGOCount2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOCount3` `ReqCreatureOrGOCount3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqCreatureOrGOCount4` `ReqCreatureOrGOCount4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSpellCast1` `ReqSpellCast1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSpellCast2` `ReqSpellCast2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSpellCast3` `ReqSpellCast3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `ReqSpellCast4` `ReqSpellCast4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemId1` `RewChoiceItemId1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemId2` `RewChoiceItemId2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemId3` `RewChoiceItemId3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemId4` `RewChoiceItemId4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemId5` `RewChoiceItemId5` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemId6` `RewChoiceItemId6` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemCount1` `RewChoiceItemCount1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemCount2` `RewChoiceItemCount2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemCount3` `RewChoiceItemCount3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemCount4` `RewChoiceItemCount4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemCount5` `RewChoiceItemCount5` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewChoiceItemCount6` `RewChoiceItemCount6` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemId1` `RewItemId1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemId2` `RewItemId2` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemId3` `RewItemId3` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemId4` `RewItemId4` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemCount1` `RewItemCount1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemCount2` `RewItemCount2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemCount3` `RewItemCount3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewItemCount4` `RewItemCount4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewRepFaction1` `RewRepFaction1` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'faction id from Faction.dbc in this case', + CHANGE COLUMN `RewRepFaction2` `RewRepFaction2` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'faction id from Faction.dbc in this case', + CHANGE COLUMN `RewRepFaction3` `RewRepFaction3` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'faction id from Faction.dbc in this case', + CHANGE COLUMN `RewRepFaction4` `RewRepFaction4` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'faction id from Faction.dbc in this case', + CHANGE COLUMN `RewRepFaction5` `RewRepFaction5` smallint unsigned NOT NULL DEFAULT 0 COMMENT 'faction id from Faction.dbc in this case', + CHANGE COLUMN `RewRepValue1` `RewRepValue1` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewRepValue2` `RewRepValue2` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewRepValue3` `RewRepValue3` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewRepValue4` `RewRepValue4` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewRepValue5` `RewRepValue5` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `RewOrReqMoney` `RewOrReqMoney` integer NOT NULL DEFAULT 0, + CHANGE COLUMN `RewMoneyMaxLevel` `RewMoneyMaxLevel` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `RewSpell` `RewSpell` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `PointMapId` `PointMapId` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `PointOpt` `PointOpt` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `DetailsEmote1` `DetailsEmote1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `DetailsEmote2` `DetailsEmote2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `DetailsEmote3` `DetailsEmote3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `DetailsEmote4` `DetailsEmote4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `IncompleteEmote` `IncompleteEmote` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `CompleteEmote` `CompleteEmote` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `OfferRewardEmote1` `OfferRewardEmote1` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `OfferRewardEmote2` `OfferRewardEmote2` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `OfferRewardEmote3` `OfferRewardEmote3` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `OfferRewardEmote4` `OfferRewardEmote4` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `StartScript` `StartScript` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `CompleteScript` `CompleteScript` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `skill_discovery_template` + CHANGE COLUMN `spellId` `spellId` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'SpellId of the discoverable spell', + CHANGE COLUMN `reqSpell` `reqSpell` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'spell requirement'; +ALTER TABLE `skill_extra_item_template` + CHANGE COLUMN `spellId` `spellId` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'SpellId of the item creation spell', + CHANGE COLUMN `requiredSpecialization` `requiredSpecialization` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Specialization spell id', + CHANGE COLUMN `additionalMaxNum` `additionalMaxNum` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'max num of adds'; +ALTER TABLE `skinning_loot_template` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `item` `item` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `QuestChanceOrGroup` `QuestChanceOrGroup` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `mincount` `mincount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `maxcount` `maxcount` tinyint unsigned NOT NULL DEFAULT 1, + CHANGE COLUMN `freeforall` `freeforall` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `lootcondition` `lootcondition` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value1` `condition_value1` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `condition_value2` `condition_value2` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_affect` + CHANGE COLUMN `entry` `entry` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `effectId` `effectId` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SpellFamily` `SpellFamily` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SpellFamilyMask` `SpellFamilyMask` bigint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `Charges` `Charges` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_chain` + CHANGE COLUMN `spell_id` `spell_id` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `prev_spell` `prev_spell` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `first_spell` `first_spell` mediumint NOT NULL DEFAULT 0, + CHANGE COLUMN `rank` `rank` tinyint NOT NULL DEFAULT 0; +ALTER TABLE `spell_learn_skill` + CHANGE COLUMN `entry` `entry` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SkillID` `SkillID` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `Value` `Value` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `MaxValue` `MaxValue` smallint NOT NULL DEFAULT 0; +ALTER TABLE `spell_learn_spell` + CHANGE COLUMN `entry` `entry` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SpellID` `SpellID` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `IfNoSpell` `IfNoSpell` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_proc_event` + CHANGE COLUMN `entry` `entry` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SchoolMask` `SchoolMask` tinyint NOT NULL DEFAULT 0, + CHANGE COLUMN `Category` `Category` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `SkillID` `SkillID` smallint NOT NULL DEFAULT 0, + CHANGE COLUMN `SpellFamilyName` `SpellFamilyName` smallint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `SpellFamilyMask` `SpellFamilyMask` bigint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `procFlags` `procFlags` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_script_target` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL, + CHANGE COLUMN `type` `type` tinyint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `targetEntry` `targetEntry` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_scripts` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `delay` `delay` integer unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `command` `command` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong` `datalong` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `datalong2` `datalong2` integer unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_teleport` + CHANGE COLUMN `id` `id` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Identifier', + CHANGE COLUMN `target_map` `target_map` smallint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `spell_threat` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL, + CHANGE COLUMN `Threat` `Threat` smallint NOT NULL; +ALTER TABLE `transports` + CHANGE COLUMN `entry` `entry` mediumint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `period` `period` mediumint unsigned NOT NULL DEFAULT 0; +ALTER TABLE `uptime` + CHANGE COLUMN `starttime` `starttime` bigint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `startstring` `startstring` varchar(64) NOT NULL DEFAULT '', + CHANGE COLUMN `uptime` `uptime` bigint unsigned NOT NULL DEFAULT 0, + CHANGE COLUMN `maxplayers` `maxplayers` smallint unsigned NOT NULL DEFAULT 0; diff --git a/sql/updates/0.10/5505_mangos_npc_gossip.sql b/sql/updates/0.10/5505_mangos_npc_gossip.sql new file mode 100644 index 000000000..b8935e936 --- /dev/null +++ b/sql/updates/0.10/5505_mangos_npc_gossip.sql @@ -0,0 +1,8 @@ +-- Some unused columns left + +ALTER TABLE `npc_gossip` + DROP COLUMN `id`; +ALTER TABLE `npc_gossip` + DROP COLUMN `gossip_type`; +ALTER TABLE `npc_gossip` + DROP COLUMN `option_count`; diff --git a/sql/updates/0.10/5526_mangos_player_levelstats.sql b/sql/updates/0.10/5526_mangos_player_levelstats.sql new file mode 100644 index 000000000..4a8c6a780 --- /dev/null +++ b/sql/updates/0.10/5526_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 37, `basemana` = 85 WHERE `class` = 11 AND `level`= 1; +UPDATE `player_levelstats` SET `basehp` = 44, `basemana` = 91 WHERE `class` = 11 AND `level`= 2; +UPDATE `player_levelstats` SET `basehp` = 51, `basemana` = 98 WHERE `class` = 11 AND `level`= 3; +UPDATE `player_levelstats` SET `basehp` = 58, `basemana` = 106 WHERE `class` = 11 AND `level`= 4; +UPDATE `player_levelstats` SET `basehp` = 65, `basemana` = 115 WHERE `class` = 11 AND `level`= 5; +UPDATE `player_levelstats` SET `basehp` = 72, `basemana` = 125 WHERE `class` = 11 AND `level`= 6; +UPDATE `player_levelstats` SET `basehp` = 79, `basemana` = 136 WHERE `class` = 11 AND `level`= 7; +UPDATE `player_levelstats` SET `basehp` = 86, `basemana` = 148 WHERE `class` = 11 AND `level`= 8; +UPDATE `player_levelstats` SET `basehp` = 93, `basemana` = 161 WHERE `class` = 11 AND `level`= 9; +UPDATE `player_levelstats` SET `basehp` = 100, `basemana` = 175 WHERE `class` = 11 AND `level`= 10; +UPDATE `player_levelstats` SET `basehp` = 107, `basemana` = 190 WHERE `class` = 11 AND `level`= 11; +UPDATE `player_levelstats` SET `basehp` = 114, `basemana` = 206 WHERE `class` = 11 AND `level`= 12; +UPDATE `player_levelstats` SET `basehp` = 121, `basemana` = 223 WHERE `class` = 11 AND `level`= 13; +UPDATE `player_levelstats` SET `basehp` = 128, `basemana` = 241 WHERE `class` = 11 AND `level`= 14; +UPDATE `player_levelstats` SET `basehp` = 135, `basemana` = 260 WHERE `class` = 11 AND `level`= 15; +UPDATE `player_levelstats` SET `basehp` = 142, `basemana` = 280 WHERE `class` = 11 AND `level`= 16; +UPDATE `player_levelstats` SET `basehp` = 150, `basemana` = 301 WHERE `class` = 11 AND `level`= 17; +UPDATE `player_levelstats` SET `basehp` = 159, `basemana` = 323 WHERE `class` = 11 AND `level`= 18; +UPDATE `player_levelstats` SET `basehp` = 169, `basemana` = 346 WHERE `class` = 11 AND `level`= 19; +UPDATE `player_levelstats` SET `basehp` = 180, `basemana` = 370 WHERE `class` = 11 AND `level`= 20; +UPDATE `player_levelstats` SET `basehp` = 192, `basemana` = 395 WHERE `class` = 11 AND `level`= 21; +UPDATE `player_levelstats` SET `basehp` = 205, `basemana` = 421 WHERE `class` = 11 AND `level`= 22; +UPDATE `player_levelstats` SET `basehp` = 219, `basemana` = 448 WHERE `class` = 11 AND `level`= 23; +UPDATE `player_levelstats` SET `basehp` = 234, `basemana` = 476 WHERE `class` = 11 AND `level`= 24; +UPDATE `player_levelstats` SET `basehp` = 240, `basemana` = 505 WHERE `class` = 11 AND `level`= 25; +UPDATE `player_levelstats` SET `basehp` = 257, `basemana` = 535 WHERE `class` = 11 AND `level`= 26; +UPDATE `player_levelstats` SET `basehp` = 275, `basemana` = 566 WHERE `class` = 11 AND `level`= 27; +UPDATE `player_levelstats` SET `basehp` = 294, `basemana` = 598 WHERE `class` = 11 AND `level`= 28; +UPDATE `player_levelstats` SET `basehp` = 314, `basemana` = 631 WHERE `class` = 11 AND `level`= 29; +UPDATE `player_levelstats` SET `basehp` = 335, `basemana` = 665 WHERE `class` = 11 AND `level`= 30; +UPDATE `player_levelstats` SET `basehp` = 347, `basemana` = 699 WHERE `class` = 11 AND `level`= 31; +UPDATE `player_levelstats` SET `basehp` = 370, `basemana` = 733 WHERE `class` = 11 AND `level`= 32; +UPDATE `player_levelstats` SET `basehp` = 394, `basemana` = 767 WHERE `class` = 11 AND `level`= 33; +UPDATE `player_levelstats` SET `basehp` = 419, `basemana` = 786 WHERE `class` = 11 AND `level`= 34; +UPDATE `player_levelstats` SET `basehp` = 435, `basemana` = 820 WHERE `class` = 11 AND `level`= 35; +UPDATE `player_levelstats` SET `basehp` = 462, `basemana` = 854 WHERE `class` = 11 AND `level`= 36; +UPDATE `player_levelstats` SET `basehp` = 490, `basemana` = 888 WHERE `class` = 11 AND `level`= 37; +UPDATE `player_levelstats` SET `basehp` = 509, `basemana` = 922 WHERE `class` = 11 AND `level`= 38; +UPDATE `player_levelstats` SET `basehp` = 539, `basemana` = 941 WHERE `class` = 11 AND `level`= 39; +UPDATE `player_levelstats` SET `basehp` = 570, `basemana` = 975 WHERE `class` = 11 AND `level`= 40; +UPDATE `player_levelstats` SET `basehp` = 592, `basemana` = 1009 WHERE `class` = 11 AND `level`= 41; +UPDATE `player_levelstats` SET `basehp` = 625, `basemana` = 1028 WHERE `class` = 11 AND `level`= 42; +UPDATE `player_levelstats` SET `basehp` = 649, `basemana` = 1062 WHERE `class` = 11 AND `level`= 43; +UPDATE `player_levelstats` SET `basehp` = 684, `basemana` = 1096 WHERE `class` = 11 AND `level`= 44; +UPDATE `player_levelstats` SET `basehp` = 710, `basemana` = 1115 WHERE `class` = 11 AND `level`= 45; +UPDATE `player_levelstats` SET `basehp` = 747, `basemana` = 1149 WHERE `class` = 11 AND `level`= 46; +UPDATE `player_levelstats` SET `basehp` = 775, `basemana` = 1183 WHERE `class` = 11 AND `level`= 47; +UPDATE `player_levelstats` SET `basehp` = 814, `basemana` = 1202 WHERE `class` = 11 AND `level`= 48; +UPDATE `player_levelstats` SET `basehp` = 844, `basemana` = 1236 WHERE `class` = 11 AND `level`= 49; +UPDATE `player_levelstats` SET `basehp` = 885, `basemana` = 1255 WHERE `class` = 11 AND `level`= 50; +UPDATE `player_levelstats` SET `basehp` = 917, `basemana` = 1289 WHERE `class` = 11 AND `level`= 51; +UPDATE `player_levelstats` SET `basehp` = 960, `basemana` = 1323 WHERE `class` = 11 AND `level`= 52; +UPDATE `player_levelstats` SET `basehp` = 994, `basemana` = 1342 WHERE `class` = 11 AND `level`= 53; +UPDATE `player_levelstats` SET `basehp` = 1029, `basemana` = 1376 WHERE `class` = 11 AND `level`= 54; +UPDATE `player_levelstats` SET `basehp` = 1075, `basemana` = 1395 WHERE `class` = 11 AND `level`= 55; +UPDATE `player_levelstats` SET `basehp` = 1112, `basemana` = 1414 WHERE `class` = 11 AND `level`= 56; +UPDATE `player_levelstats` SET `basehp` = 1150, `basemana` = 1448 WHERE `class` = 11 AND `level`= 57; +UPDATE `player_levelstats` SET `basehp` = 1199, `basemana` = 1467 WHERE `class` = 11 AND `level`= 58; +UPDATE `player_levelstats` SET `basehp` = 1239, `basemana` = 1501 WHERE `class` = 11 AND `level`= 59; +UPDATE `player_levelstats` SET `basehp` = 1330, `basemana` = 1520 WHERE `class` = 11 AND `level`= 60; +UPDATE `player_levelstats` SET `basehp` = 1428, `basemana` = 1664 WHERE `class` = 11 AND `level`= 61; +UPDATE `player_levelstats` SET `basehp` = 1583, `basemana` = 1808 WHERE `class` = 11 AND `level`= 62; +UPDATE `player_levelstats` SET `basehp` = 1760, `basemana` = 1951 WHERE `class` = 11 AND `level`= 63; +UPDATE `player_levelstats` SET `basehp` = 1932, `basemana` = 2095 WHERE `class` = 11 AND `level`= 64; +UPDATE `player_levelstats` SET `basehp` = 2114, `basemana` = 2239 WHERE `class` = 11 AND `level`= 65; +UPDATE `player_levelstats` SET `basehp` = 2304, `basemana` = 2383 WHERE `class` = 11 AND `level`= 66; +UPDATE `player_levelstats` SET `basehp` = 2504, `basemana` = 2527 WHERE `class` = 11 AND `level`= 67; +UPDATE `player_levelstats` SET `basehp` = 2713, `basemana` = 2670 WHERE `class` = 11 AND `level`= 68; +UPDATE `player_levelstats` SET `basehp` = 2931, `basemana` = 2814 WHERE `class` = 11 AND `level`= 69; +UPDATE `player_levelstats` SET `basehp` = 3159, `basemana` = 2958 WHERE `class` = 11 AND `level`= 70; diff --git a/sql/updates/0.10/5529_mangos_spell_chain.sql b/sql/updates/0.10/5529_mangos_spell_chain.sql new file mode 100644 index 000000000..c0acd8815 --- /dev/null +++ b/sql/updates/0.10/5529_mangos_spell_chain.sql @@ -0,0 +1,30 @@ +DELETE FROM spell_chain WHERE spell_id IN (9787,9788,17039,17040,17041); +INSERT INTO spell_chain VALUES +(9787, 9785,2018,5), +(9788, 9785,2018,5), +(17039,9787,2018,6), +(17040,9787,2018,6), +(17041,9787,2018,6); + +DELETE FROM spell_chain WHERE spell_id IN (28672,28675,28677); +INSERT INTO spell_chain VALUES +(28672,11611,2259,5), +(28675,11611,2259,5), +(28677,11611,2259,5); + +DELETE FROM spell_chain WHERE spell_id IN (10656,10658,10660); +INSERT INTO spell_chain VALUES +(10656,10662,2108,5), +(10658,10662,2108,5), +(10660,10662,2108,5); + +DELETE FROM spell_chain WHERE spell_id IN (20219,20222); +INSERT INTO spell_chain VALUES +(20219,12656,4036,5), +(20222,12656,4036,5); + +DELETE FROM spell_chain WHERE spell_id IN (26797,26798,26801); +INSERT INTO spell_chain VALUES +(26797,12180,3908,5), +(26798,12180,3908,5), +(26801,12180,3908,5); diff --git a/sql/updates/0.10/5530_mangos_spell_learn_spell.sql b/sql/updates/0.10/5530_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..0fedce3f4 --- /dev/null +++ b/sql/updates/0.10/5530_mangos_spell_learn_spell.sql @@ -0,0 +1,2 @@ +DELETE FROM spell_learn_spell WHERE entry IN (33943); +INSERT INTO spell_learn_spell VALUES (33943,34090,0); diff --git a/sql/updates/0.10/5531_mangos_creature_movement.sql b/sql/updates/0.10/5531_mangos_creature_movement.sql new file mode 100644 index 000000000..27c814ab8 --- /dev/null +++ b/sql/updates/0.10/5531_mangos_creature_movement.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_movement` + CHANGE COLUMN `id` `id` int(10) unsigned NOT NULL auto_increment COMMENT 'Creature GUID'; diff --git a/sql/updates/0.10/5534_mangos_player_levelstats.sql b/sql/updates/0.10/5534_mangos_player_levelstats.sql new file mode 100644 index 000000000..440100428 --- /dev/null +++ b/sql/updates/0.10/5534_mangos_player_levelstats.sql @@ -0,0 +1,144 @@ +-- Druid update + +UPDATE `player_levelstats` SET `basehp` = 44, `basemana` = 60 WHERE `class` = 11 AND `level`= 1; +UPDATE `player_levelstats` SET `basehp` = 51, `basemana` = 66 WHERE `class` = 11 AND `level`= 2; +UPDATE `player_levelstats` SET `basehp` = 58, `basemana` = 73 WHERE `class` = 11 AND `level`= 3; +UPDATE `player_levelstats` SET `basehp` = 75, `basemana` = 81 WHERE `class` = 11 AND `level`= 4; +UPDATE `player_levelstats` SET `basehp` = 82, `basemana` = 90 WHERE `class` = 11 AND `level`= 5; +UPDATE `player_levelstats` SET `basehp` = 89, `basemana` = 100 WHERE `class` = 11 AND `level`= 6; +UPDATE `player_levelstats` SET `basehp` = 106, `basemana` = 111 WHERE `class` = 11 AND `level`= 7; +UPDATE `player_levelstats` SET `basehp` = 113, `basemana` = 123 WHERE `class` = 11 AND `level`= 8; +UPDATE `player_levelstats` SET `basehp` = 120, `basemana` = 136 WHERE `class` = 11 AND `level`= 9; +UPDATE `player_levelstats` SET `basehp` = 137, `basemana` = 150 WHERE `class` = 11 AND `level`= 10; +UPDATE `player_levelstats` SET `basehp` = 144, `basemana` = 165 WHERE `class` = 11 AND `level`= 11; +UPDATE `player_levelstats` SET `basehp` = 151, `basemana` = 182 WHERE `class` = 11 AND `level`= 12; +UPDATE `player_levelstats` SET `basehp` = 168, `basemana` = 200 WHERE `class` = 11 AND `level`= 13; +UPDATE `player_levelstats` SET `basehp` = 175, `basemana` = 219 WHERE `class` = 11 AND `level`= 14; +UPDATE `player_levelstats` SET `basehp` = 182, `basemana` = 239 WHERE `class` = 11 AND `level`= 15; +UPDATE `player_levelstats` SET `basehp` = 199, `basemana` = 260 WHERE `class` = 11 AND `level`= 16; +UPDATE `player_levelstats` SET `basehp` = 206, `basemana` = 282 WHERE `class` = 11 AND `level`= 17; +UPDATE `player_levelstats` SET `basehp` = 214, `basemana` = 305 WHERE `class` = 11 AND `level`= 18; +UPDATE `player_levelstats` SET `basehp` = 233, `basemana` = 329 WHERE `class` = 11 AND `level`= 19; +UPDATE `player_levelstats` SET `basehp` = 243, `basemana` = 354 WHERE `class` = 11 AND `level`= 20; +UPDATE `player_levelstats` SET `basehp` = 254, `basemana` = 380 WHERE `class` = 11 AND `level`= 21; +UPDATE `player_levelstats` SET `basehp` = 266, `basemana` = 392 WHERE `class` = 11 AND `level`= 22; +UPDATE `player_levelstats` SET `basehp` = 289, `basemana` = 420 WHERE `class` = 11 AND `level`= 23; +UPDATE `player_levelstats` SET `basehp` = 303, `basemana` = 449 WHERE `class` = 11 AND `level`= 24; +UPDATE `player_levelstats` SET `basehp` = 318, `basemana` = 479 WHERE `class` = 11 AND `level`= 25; +UPDATE `player_levelstats` SET `basehp` = 334, `basemana` = 509 WHERE `class` = 11 AND `level`= 26; +UPDATE `player_levelstats` SET `basehp` = 361, `basemana` = 524 WHERE `class` = 11 AND `level`= 27; +UPDATE `player_levelstats` SET `basehp` = 379, `basemana` = 554 WHERE `class` = 11 AND `level`= 28; +UPDATE `player_levelstats` SET `basehp` = 398, `basemana` = 584 WHERE `class` = 11 AND `level`= 29; +UPDATE `player_levelstats` SET `basehp` = 418, `basemana` = 614 WHERE `class` = 11 AND `level`= 30; +UPDATE `player_levelstats` SET `basehp` = 439, `basemana` = 629 WHERE `class` = 11 AND `level`= 31; +UPDATE `player_levelstats` SET `basehp` = 461, `basemana` = 659 WHERE `class` = 11 AND `level`= 32; +UPDATE `player_levelstats` SET `basehp` = 494, `basemana` = 689 WHERE `class` = 11 AND `level`= 33; +UPDATE `player_levelstats` SET `basehp` = 518, `basemana` = 704 WHERE `class` = 11 AND `level`= 34; +UPDATE `player_levelstats` SET `basehp` = 543, `basemana` = 734 WHERE `class` = 11 AND `level`= 35; +UPDATE `player_levelstats` SET `basehp` = 569, `basemana` = 749 WHERE `class` = 11 AND `level`= 36; +UPDATE `player_levelstats` SET `basehp` = 596, `basemana` = 779 WHERE `class` = 11 AND `level`= 37; +UPDATE `player_levelstats` SET `basehp` = 624, `basemana` = 809 WHERE `class` = 11 AND `level`= 38; +UPDATE `player_levelstats` SET `basehp` = 653, `basemana` = 824 WHERE `class` = 11 AND `level`= 39; +UPDATE `player_levelstats` SET `basehp` = 683, `basemana` = 854 WHERE `class` = 11 AND `level`= 40; +UPDATE `player_levelstats` SET `basehp` = 714, `basemana` = 869 WHERE `class` = 11 AND `level`= 41; +UPDATE `player_levelstats` SET `basehp` = 746, `basemana` = 899 WHERE `class` = 11 AND `level`= 42; +UPDATE `player_levelstats` SET `basehp` = 779, `basemana` = 914 WHERE `class` = 11 AND `level`= 43; +UPDATE `player_levelstats` SET `basehp` = 823, `basemana` = 944 WHERE `class` = 11 AND `level`= 44; +UPDATE `player_levelstats` SET `basehp` = 858, `basemana` = 959 WHERE `class` = 11 AND `level`= 45; +UPDATE `player_levelstats` SET `basehp` = 894, `basemana` = 989 WHERE `class` = 11 AND `level`= 46; +UPDATE `player_levelstats` SET `basehp` = 921, `basemana` = 1004 WHERE `class` = 11 AND `level`= 47; +UPDATE `player_levelstats` SET `basehp` = 959, `basemana` = 1019 WHERE `class` = 11 AND `level`= 48; +UPDATE `player_levelstats` SET `basehp` = 998, `basemana` = 1049 WHERE `class` = 11 AND `level`= 49; +UPDATE `player_levelstats` SET `basehp` = 1038, `basemana` = 1064 WHERE `class` = 11 AND `level`= 50; +UPDATE `player_levelstats` SET `basehp` = 1079, `basemana` = 1079 WHERE `class` = 11 AND `level`= 51; +UPDATE `player_levelstats` SET `basehp` = 1121, `basemana` = 1109 WHERE `class` = 11 AND `level`= 52; +UPDATE `player_levelstats` SET `basehp` = 1164, `basemana` = 1124 WHERE `class` = 11 AND `level`= 53; +UPDATE `player_levelstats` SET `basehp` = 1208, `basemana` = 1139 WHERE `class` = 11 AND `level`= 54; +UPDATE `player_levelstats` SET `basehp` = 1253, `basemana` = 1154 WHERE `class` = 11 AND `level`= 55; +UPDATE `player_levelstats` SET `basehp` = 1299, `basemana` = 1169 WHERE `class` = 11 AND `level`= 56; +UPDATE `player_levelstats` SET `basehp` = 1346, `basemana` = 1199 WHERE `class` = 11 AND `level`= 57; +UPDATE `player_levelstats` SET `basehp` = 1384, `basemana` = 1214 WHERE `class` = 11 AND `level`= 58; +UPDATE `player_levelstats` SET `basehp` = 1433, `basemana` = 1229 WHERE `class` = 11 AND `level`= 59; +UPDATE `player_levelstats` SET `basehp` = 1483, `basemana` = 1244 WHERE `class` = 11 AND `level`= 60; +UPDATE `player_levelstats` SET `basehp` = 1657, `basemana` = 1357 WHERE `class` = 11 AND `level`= 61; +UPDATE `player_levelstats` SET `basehp` = 1840, `basemana` = 1469 WHERE `class` = 11 AND `level`= 62; +UPDATE `player_levelstats` SET `basehp` = 2020, `basemana` = 1582 WHERE `class` = 11 AND `level`= 63; +UPDATE `player_levelstats` SET `basehp` = 2222, `basemana` = 1694 WHERE `class` = 11 AND `level`= 64; +UPDATE `player_levelstats` SET `basehp` = 2433, `basemana` = 1807 WHERE `class` = 11 AND `level`= 65; +UPDATE `player_levelstats` SET `basehp` = 2640, `basemana` = 1919 WHERE `class` = 11 AND `level`= 66; +UPDATE `player_levelstats` SET `basehp` = 2872, `basemana` = 2032 WHERE `class` = 11 AND `level`= 67; +UPDATE `player_levelstats` SET `basehp` = 3114, `basemana` = 2145 WHERE `class` = 11 AND `level`= 68; +UPDATE `player_levelstats` SET `basehp` = 3351, `basemana` = 2257 WHERE `class` = 11 AND `level`= 69; +UPDATE `player_levelstats` SET `basehp` = 3614, `basemana` = 2370 WHERE `class` = 11 AND `level`= 70; + +-- Shaman update +UPDATE `player_levelstats` SET `basehp` = 37, `basemana` = 85 WHERE `class` = 7 AND `level`= 1; +UPDATE `player_levelstats` SET `basehp` = 44, `basemana` = 91 WHERE `class` = 7 AND `level`= 2; +UPDATE `player_levelstats` SET `basehp` = 51, `basemana` = 98 WHERE `class` = 7 AND `level`= 3; +UPDATE `player_levelstats` SET `basehp` = 58, `basemana` = 106 WHERE `class` = 7 AND `level`= 4; +UPDATE `player_levelstats` SET `basehp` = 65, `basemana` = 115 WHERE `class` = 7 AND `level`= 5; +UPDATE `player_levelstats` SET `basehp` = 72, `basemana` = 125 WHERE `class` = 7 AND `level`= 6; +UPDATE `player_levelstats` SET `basehp` = 79, `basemana` = 136 WHERE `class` = 7 AND `level`= 7; +UPDATE `player_levelstats` SET `basehp` = 86, `basemana` = 148 WHERE `class` = 7 AND `level`= 8; +UPDATE `player_levelstats` SET `basehp` = 93, `basemana` = 161 WHERE `class` = 7 AND `level`= 9; +UPDATE `player_levelstats` SET `basehp` = 100, `basemana` = 175 WHERE `class` = 7 AND `level`= 10; +UPDATE `player_levelstats` SET `basehp` = 107, `basemana` = 190 WHERE `class` = 7 AND `level`= 11; +UPDATE `player_levelstats` SET `basehp` = 114, `basemana` = 206 WHERE `class` = 7 AND `level`= 12; +UPDATE `player_levelstats` SET `basehp` = 121, `basemana` = 223 WHERE `class` = 7 AND `level`= 13; +UPDATE `player_levelstats` SET `basehp` = 128, `basemana` = 241 WHERE `class` = 7 AND `level`= 14; +UPDATE `player_levelstats` SET `basehp` = 135, `basemana` = 260 WHERE `class` = 7 AND `level`= 15; +UPDATE `player_levelstats` SET `basehp` = 142, `basemana` = 280 WHERE `class` = 7 AND `level`= 16; +UPDATE `player_levelstats` SET `basehp` = 150, `basemana` = 301 WHERE `class` = 7 AND `level`= 17; +UPDATE `player_levelstats` SET `basehp` = 159, `basemana` = 323 WHERE `class` = 7 AND `level`= 18; +UPDATE `player_levelstats` SET `basehp` = 169, `basemana` = 346 WHERE `class` = 7 AND `level`= 19; +UPDATE `player_levelstats` SET `basehp` = 180, `basemana` = 370 WHERE `class` = 7 AND `level`= 20; +UPDATE `player_levelstats` SET `basehp` = 192, `basemana` = 395 WHERE `class` = 7 AND `level`= 21; +UPDATE `player_levelstats` SET `basehp` = 205, `basemana` = 421 WHERE `class` = 7 AND `level`= 22; +UPDATE `player_levelstats` SET `basehp` = 219, `basemana` = 448 WHERE `class` = 7 AND `level`= 23; +UPDATE `player_levelstats` SET `basehp` = 234, `basemana` = 476 WHERE `class` = 7 AND `level`= 24; +UPDATE `player_levelstats` SET `basehp` = 240, `basemana` = 505 WHERE `class` = 7 AND `level`= 25; +UPDATE `player_levelstats` SET `basehp` = 257, `basemana` = 535 WHERE `class` = 7 AND `level`= 26; +UPDATE `player_levelstats` SET `basehp` = 275, `basemana` = 566 WHERE `class` = 7 AND `level`= 27; +UPDATE `player_levelstats` SET `basehp` = 294, `basemana` = 598 WHERE `class` = 7 AND `level`= 28; +UPDATE `player_levelstats` SET `basehp` = 314, `basemana` = 631 WHERE `class` = 7 AND `level`= 29; +UPDATE `player_levelstats` SET `basehp` = 335, `basemana` = 665 WHERE `class` = 7 AND `level`= 30; +UPDATE `player_levelstats` SET `basehp` = 347, `basemana` = 699 WHERE `class` = 7 AND `level`= 31; +UPDATE `player_levelstats` SET `basehp` = 370, `basemana` = 733 WHERE `class` = 7 AND `level`= 32; +UPDATE `player_levelstats` SET `basehp` = 394, `basemana` = 767 WHERE `class` = 7 AND `level`= 33; +UPDATE `player_levelstats` SET `basehp` = 419, `basemana` = 786 WHERE `class` = 7 AND `level`= 34; +UPDATE `player_levelstats` SET `basehp` = 435, `basemana` = 820 WHERE `class` = 7 AND `level`= 35; +UPDATE `player_levelstats` SET `basehp` = 462, `basemana` = 854 WHERE `class` = 7 AND `level`= 36; +UPDATE `player_levelstats` SET `basehp` = 490, `basemana` = 888 WHERE `class` = 7 AND `level`= 37; +UPDATE `player_levelstats` SET `basehp` = 509, `basemana` = 922 WHERE `class` = 7 AND `level`= 38; +UPDATE `player_levelstats` SET `basehp` = 539, `basemana` = 941 WHERE `class` = 7 AND `level`= 39; +UPDATE `player_levelstats` SET `basehp` = 570, `basemana` = 975 WHERE `class` = 7 AND `level`= 40; +UPDATE `player_levelstats` SET `basehp` = 592, `basemana` = 1009 WHERE `class` = 7 AND `level`= 41; +UPDATE `player_levelstats` SET `basehp` = 625, `basemana` = 1028 WHERE `class` = 7 AND `level`= 42; +UPDATE `player_levelstats` SET `basehp` = 649, `basemana` = 1062 WHERE `class` = 7 AND `level`= 43; +UPDATE `player_levelstats` SET `basehp` = 684, `basemana` = 1096 WHERE `class` = 7 AND `level`= 44; +UPDATE `player_levelstats` SET `basehp` = 710, `basemana` = 1115 WHERE `class` = 7 AND `level`= 45; +UPDATE `player_levelstats` SET `basehp` = 747, `basemana` = 1149 WHERE `class` = 7 AND `level`= 46; +UPDATE `player_levelstats` SET `basehp` = 775, `basemana` = 1183 WHERE `class` = 7 AND `level`= 47; +UPDATE `player_levelstats` SET `basehp` = 814, `basemana` = 1202 WHERE `class` = 7 AND `level`= 48; +UPDATE `player_levelstats` SET `basehp` = 844, `basemana` = 1236 WHERE `class` = 7 AND `level`= 49; +UPDATE `player_levelstats` SET `basehp` = 885, `basemana` = 1255 WHERE `class` = 7 AND `level`= 50; +UPDATE `player_levelstats` SET `basehp` = 917, `basemana` = 1289 WHERE `class` = 7 AND `level`= 51; +UPDATE `player_levelstats` SET `basehp` = 960, `basemana` = 1323 WHERE `class` = 7 AND `level`= 52; +UPDATE `player_levelstats` SET `basehp` = 994, `basemana` = 1342 WHERE `class` = 7 AND `level`= 53; +UPDATE `player_levelstats` SET `basehp` = 1029, `basemana` = 1376 WHERE `class` = 7 AND `level`= 54; +UPDATE `player_levelstats` SET `basehp` = 1075, `basemana` = 1395 WHERE `class` = 7 AND `level`= 55; +UPDATE `player_levelstats` SET `basehp` = 1112, `basemana` = 1414 WHERE `class` = 7 AND `level`= 56; +UPDATE `player_levelstats` SET `basehp` = 1150, `basemana` = 1448 WHERE `class` = 7 AND `level`= 57; +UPDATE `player_levelstats` SET `basehp` = 1199, `basemana` = 1467 WHERE `class` = 7 AND `level`= 58; +UPDATE `player_levelstats` SET `basehp` = 1239, `basemana` = 1501 WHERE `class` = 7 AND `level`= 59; +UPDATE `player_levelstats` SET `basehp` = 1330, `basemana` = 1520 WHERE `class` = 7 AND `level`= 60; +UPDATE `player_levelstats` SET `basehp` = 1428, `basemana` = 1664 WHERE `class` = 7 AND `level`= 61; +UPDATE `player_levelstats` SET `basehp` = 1583, `basemana` = 1808 WHERE `class` = 7 AND `level`= 62; +UPDATE `player_levelstats` SET `basehp` = 1760, `basemana` = 1951 WHERE `class` = 7 AND `level`= 63; +UPDATE `player_levelstats` SET `basehp` = 1932, `basemana` = 2095 WHERE `class` = 7 AND `level`= 64; +UPDATE `player_levelstats` SET `basehp` = 2114, `basemana` = 2239 WHERE `class` = 7 AND `level`= 65; +UPDATE `player_levelstats` SET `basehp` = 2304, `basemana` = 2383 WHERE `class` = 7 AND `level`= 66; +UPDATE `player_levelstats` SET `basehp` = 2504, `basemana` = 2527 WHERE `class` = 7 AND `level`= 67; +UPDATE `player_levelstats` SET `basehp` = 2713, `basemana` = 2670 WHERE `class` = 7 AND `level`= 68; +UPDATE `player_levelstats` SET `basehp` = 2931, `basemana` = 2814 WHERE `class` = 7 AND `level`= 69; +UPDATE `player_levelstats` SET `basehp` = 3159, `basemana` = 2958 WHERE `class` = 7 AND `level`= 70; diff --git a/sql/updates/0.10/5541_mangos_command.sql b/sql/updates/0.10/5541_mangos_command.sql new file mode 100644 index 000000000..bf248479b --- /dev/null +++ b/sql/updates/0.10/5541_mangos_command.sql @@ -0,0 +1,5 @@ +DELETE FROM `command` WHERE `name` = 'learn all_default'; + +INSERT INTO `command` VALUES +('learn all_default',1,'Syntax: .learn all_default [$playername]\r\n\r\nLearn for selected/$playername player all default spells for his race/class and spells rewarded by completed quests.'); + diff --git a/sql/updates/0.10/5541_mangos_mangos_string.sql b/sql/updates/0.10/5541_mangos_mangos_string.sql new file mode 100644 index 000000000..ee5a13044 --- /dev/null +++ b/sql/updates/0.10/5541_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry in (580); +INSERT INTO mangos_string VALUES +(580,'Player %s learned all default spells for race/class and completed quests rewarded spells.',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5547_characters_character_ticket.sql b/sql/updates/0.10/5547_characters_character_ticket.sql new file mode 100644 index 000000000..3c6cb2160 --- /dev/null +++ b/sql/updates/0.10/5547_characters_character_ticket.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_ticket` + ADD `ticket_lastchange` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ; diff --git a/sql/updates/0.10/5547_mangos_mangos_string.sql b/sql/updates/0.10/5547_mangos_mangos_string.sql new file mode 100644 index 000000000..88e2849e4 --- /dev/null +++ b/sql/updates/0.10/5547_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM mangos_string WHERE entry in (290); +INSERT INTO mangos_string VALUES +(290,'Ticket of %s (Last updated: %s) (Category: %i):\n%s ',NULL,NULL,NULL,NULL,NULL,NULL,NULL); + diff --git a/sql/updates/0.10/5554_mangos_locales_creature.sql b/sql/updates/0.10/5554_mangos_locales_creature.sql new file mode 100644 index 000000000..f88e05178 --- /dev/null +++ b/sql/updates/0.10/5554_mangos_locales_creature.sql @@ -0,0 +1,2 @@ +ALTER TABLE locales_creature + DROP subname_loc8; diff --git a/sql/updates/0.10/5558_mangos_player_levelstats.sql b/sql/updates/0.10/5558_mangos_player_levelstats.sql new file mode 100644 index 000000000..70d231082 --- /dev/null +++ b/sql/updates/0.10/5558_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 52, `basemana` = 73 WHERE `class` = 5 AND `level`= 1; +UPDATE `player_levelstats` SET `basehp` = 57, `basemana` = 76 WHERE `class` = 5 AND `level`= 2; +UPDATE `player_levelstats` SET `basehp` = 72, `basemana` = 95 WHERE `class` = 5 AND `level`= 3; +UPDATE `player_levelstats` SET `basehp` = 77, `basemana` = 114 WHERE `class` = 5 AND `level`= 4; +UPDATE `player_levelstats` SET `basehp` = 92, `basemana` = 133 WHERE `class` = 5 AND `level`= 5; +UPDATE `player_levelstats` SET `basehp` = 97, `basemana` = 152 WHERE `class` = 5 AND `level`= 6; +UPDATE `player_levelstats` SET `basehp` = 112, `basemana` = 171 WHERE `class` = 5 AND `level`= 7; +UPDATE `player_levelstats` SET `basehp` = 117, `basemana` = 190 WHERE `class` = 5 AND `level`= 8; +UPDATE `player_levelstats` SET `basehp` = 132, `basemana` = 209 WHERE `class` = 5 AND `level`= 9; +UPDATE `player_levelstats` SET `basehp` = 137, `basemana` = 212 WHERE `class` = 5 AND `level`= 10; +UPDATE `player_levelstats` SET `basehp` = 142, `basemana` = 215 WHERE `class` = 5 AND `level`= 11; +UPDATE `player_levelstats` SET `basehp` = 157, `basemana` = 234 WHERE `class` = 5 AND `level`= 12; +UPDATE `player_levelstats` SET `basehp` = 172, `basemana` = 254 WHERE `class` = 5 AND `level`= 13; +UPDATE `player_levelstats` SET `basehp` = 177, `basemana` = 260 WHERE `class` = 5 AND `level`= 14; +UPDATE `player_levelstats` SET `basehp` = 192, `basemana` = 282 WHERE `class` = 5 AND `level`= 15; +UPDATE `player_levelstats` SET `basehp` = 197, `basemana` = 305 WHERE `class` = 5 AND `level`= 16; +UPDATE `player_levelstats` SET `basehp` = 212, `basemana` = 329 WHERE `class` = 5 AND `level`= 17; +UPDATE `player_levelstats` SET `basehp` = 227, `basemana` = 339 WHERE `class` = 5 AND `level`= 18; +UPDATE `player_levelstats` SET `basehp` = 232, `basemana` = 365 WHERE `class` = 5 AND `level`= 19; +UPDATE `player_levelstats` SET `basehp` = 247, `basemana` = 377 WHERE `class` = 5 AND `level`= 20; +UPDATE `player_levelstats` SET `basehp` = 252, `basemana` = 405 WHERE `class` = 5 AND `level`= 21; +UPDATE `player_levelstats` SET `basehp` = 268, `basemana` = 434 WHERE `class` = 5 AND `level`= 22; +UPDATE `player_levelstats` SET `basehp` = 275, `basemana` = 449 WHERE `class` = 5 AND `level`= 23; +UPDATE `player_levelstats` SET `basehp` = 293, `basemana` = 480 WHERE `class` = 5 AND `level`= 24; +UPDATE `player_levelstats` SET `basehp` = 302, `basemana` = 497 WHERE `class` = 5 AND `level`= 25; +UPDATE `player_levelstats` SET `basehp` = 322, `basemana` = 530 WHERE `class` = 5 AND `level`= 26; +UPDATE `player_levelstats` SET `basehp` = 343, `basemana` = 549 WHERE `class` = 5 AND `level`= 27; +UPDATE `player_levelstats` SET `basehp` = 355, `basemana` = 584 WHERE `class` = 5 AND `level`= 28; +UPDATE `player_levelstats` SET `basehp` = 378, `basemana` = 605 WHERE `class` = 5 AND `level`= 29; +UPDATE `player_levelstats` SET `basehp` = 392, `basemana` = 627 WHERE `class` = 5 AND `level`= 30; +UPDATE `player_levelstats` SET `basehp` = 417, `basemana` = 665 WHERE `class` = 5 AND `level`= 31; +UPDATE `player_levelstats` SET `basehp` = 433, `basemana` = 689 WHERE `class` = 5 AND `level`= 32; +UPDATE `player_levelstats` SET `basehp` = 460, `basemana` = 728 WHERE `class` = 5 AND `level`= 33; +UPDATE `player_levelstats` SET `basehp` = 478, `basemana` = 752 WHERE `class` = 5 AND `level`= 34; +UPDATE `player_levelstats` SET `basehp` = 507, `basemana` = 776 WHERE `class` = 5 AND `level`= 35; +UPDATE `player_levelstats` SET `basehp` = 527, `basemana` = 800 WHERE `class` = 5 AND `level`= 36; +UPDATE `player_levelstats` SET `basehp` = 548, `basemana` = 839 WHERE `class` = 5 AND `level`= 37; +UPDATE `player_levelstats` SET `basehp` = 580, `basemana` = 863 WHERE `class` = 5 AND `level`= 38; +UPDATE `player_levelstats` SET `basehp` = 603, `basemana` = 887 WHERE `class` = 5 AND `level`= 39; +UPDATE `player_levelstats` SET `basehp` = 637, `basemana` = 911 WHERE `class` = 5 AND `level`= 40; +UPDATE `player_levelstats` SET `basehp` = 662, `basemana` = 950 WHERE `class` = 5 AND `level`= 41; +UPDATE `player_levelstats` SET `basehp` = 698, `basemana` = 974 WHERE `class` = 5 AND `level`= 42; +UPDATE `player_levelstats` SET `basehp` = 725, `basemana` = 998 WHERE `class` = 5 AND `level`= 43; +UPDATE `player_levelstats` SET `basehp` = 763, `basemana` = 1022 WHERE `class` = 5 AND `level`= 44; +UPDATE `player_levelstats` SET `basehp` = 792, `basemana` = 1046 WHERE `class` = 5 AND `level`= 45; +UPDATE `player_levelstats` SET `basehp` = 822, `basemana` = 1070 WHERE `class` = 5 AND `level`= 46; +UPDATE `player_levelstats` SET `basehp` = 863, `basemana` = 1094 WHERE `class` = 5 AND `level`= 47; +UPDATE `player_levelstats` SET `basehp` = 895, `basemana` = 1118 WHERE `class` = 5 AND `level`= 48; +UPDATE `player_levelstats` SET `basehp` = 928, `basemana` = 1142 WHERE `class` = 5 AND `level`= 49; +UPDATE `player_levelstats` SET `basehp` = 972, `basemana` = 1166 WHERE `class` = 5 AND `level`= 50; +UPDATE `player_levelstats` SET `basehp` = 1007, `basemana` = 1190 WHERE `class` = 5 AND `level`= 51; +UPDATE `player_levelstats` SET `basehp` = 1053, `basemana` = 1214 WHERE `class` = 5 AND `level`= 52; +UPDATE `player_levelstats` SET `basehp` = 1090, `basemana` = 1238 WHERE `class` = 5 AND `level`= 53; +UPDATE `player_levelstats` SET `basehp` = 1128, `basemana` = 1262 WHERE `class` = 5 AND `level`= 54; +UPDATE `player_levelstats` SET `basehp` = 1177, `basemana` = 1271 WHERE `class` = 5 AND `level`= 55; +UPDATE `player_levelstats` SET `basehp` = 1217, `basemana` = 1295 WHERE `class` = 5 AND `level`= 56; +UPDATE `player_levelstats` SET `basehp` = 1258, `basemana` = 1319 WHERE `class` = 5 AND `level`= 57; +UPDATE `player_levelstats` SET `basehp` = 1300, `basemana` = 1343 WHERE `class` = 5 AND `level`= 58; +UPDATE `player_levelstats` SET `basehp` = 1353, `basemana` = 1352 WHERE `class` = 5 AND `level`= 59; +UPDATE `player_levelstats` SET `basehp` = 1397, `basemana` = 1376 WHERE `class` = 5 AND `level`= 60; +UPDATE `player_levelstats` SET `basehp` = 1557, `basemana` = 1500 WHERE `class` = 5 AND `level`= 61; +UPDATE `player_levelstats` SET `basehp` = 1738, `basemana` = 1625 WHERE `class` = 5 AND `level`= 62; +UPDATE `player_levelstats` SET `basehp` = 1916, `basemana` = 1749 WHERE `class` = 5 AND `level`= 63; +UPDATE `player_levelstats` SET `basehp` = 2101, `basemana` = 1873 WHERE `class` = 5 AND `level`= 64; +UPDATE `player_levelstats` SET `basehp` = 2295, `basemana` = 1998 WHERE `class` = 5 AND `level`= 65; +UPDATE `player_levelstats` SET `basehp` = 2495, `basemana` = 2122 WHERE `class` = 5 AND `level`= 66; +UPDATE `player_levelstats` SET `basehp` = 2719, `basemana` = 2247 WHERE `class` = 5 AND `level`= 67; +UPDATE `player_levelstats` SET `basehp` = 2936, `basemana` = 2371 WHERE `class` = 5 AND `level`= 68; +UPDATE `player_levelstats` SET `basehp` = 3160, `basemana` = 2495 WHERE `class` = 5 AND `level`= 69; +UPDATE `player_levelstats` SET `basehp` = 3391, `basemana` = 2620 WHERE `class` = 5 AND `level`= 70; diff --git a/sql/updates/0.10/5570_mangos_spell_elixir.sql b/sql/updates/0.10/5570_mangos_spell_elixir.sql new file mode 100644 index 000000000..ce79ef170 --- /dev/null +++ b/sql/updates/0.10/5570_mangos_spell_elixir.sql @@ -0,0 +1,118 @@ +DROP TABLE IF EXISTS `spell_elixir`; +CREATE TABLE `spell_elixir` ( + `entry` int(11) unsigned NOT NULL default '0' COMMENT 'SpellId of potion', + `mask` tinyint(1) unsigned NOT NULL default '0' COMMENT 'Mask 0x1 battle 0x2 guardian 0x3 flask 0x7 unstable flasks 0xB shattrath flasks', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System'; + + +/* shattrath */ +INSERT INTO `spell_elixir` VALUES +(41608,0xB), +(41609,0xB), +(41610,0xB), +(41611,0xB); +/* 2.4.0 +(46837,0xB), +(46839,0xB); +*/ +/* unstable */ +INSERT INTO `spell_elixir` VALUES +(40567,0x7), +(40568,0x7), +(40572,0x7), +(40573,0x7), +(40575,0x7), +(40576,0x7); +/* Normal Flask */ +INSERT INTO `spell_elixir` VALUES +(17624,0x3), +(17626,0x3), +(17627,0x3), +(17629,0x3), +(17628,0x3), +(28518,0x3), +(28519,0x3), +(28520,0x3), +(28521,0x3), +(28540,0x3), +(42735,0x3); +/* Battle Elixirs */ +INSERT INTO `spell_elixir` VALUES +( 2367,0x1), +( 2374,0x1), +( 3160,0x1), +( 3164,0x1), +( 7844,0x1), +( 8212,0x1), +(10667,0x1), +(10669,0x1), +(11328,0x1), +(11334,0x1), +(11390,0x1), +(11405,0x1), +(11406,0x1), +(11474,0x1), +(16322,0x1), +(16323,0x1), +(16329,0x1), +(17038,0x1), +(17537,0x1), +(17538,0x1), +(17539,0x1), +(21920,0x1),/**/ +(26276,0x1), +(28486,0x1), +(28488,0x1), +(28490,0x1), +(28491,0x1), +(28493,0x1), +(28497,0x1), +(28501,0x1), +(28503,0x1), +(33720,0x1), +(33721,0x1), +(33726,0x1), +(38954,0x1); +/* Guardian Elixirs */ +INSERT INTO `spell_elixir` VALUES +( 673,0x2), +( 2378,0x2), +( 2380,0x2), +( 3166,0x2), +( 3219,0x2), +( 3220,0x2), +( 3222,0x2), +( 3223,0x2), +( 3593,0x2), +(10668,0x2), +(10692,0x2), +(10693,0x2), +(11319,0x2), +(11348,0x2), +(11349,0x2), +(16321,0x2), +(11364,0x2), +(11371,0x2), +(11396,0x2), +(15231,0x2), +(15233,0x2), +(16325,0x2), +(16326,0x2), +(16327,0x2), +(17535,0x2), +(24361,0x2), +(24363,0x2), +(24382,0x2), +(24383,0x2), +(24417,0x2), +(27652,0x2), +(27653,0x2), +(28502,0x2), +(28509,0x2), +(28514,0x2), +(29348,0x2), +(39625,0x2), +(39626,0x2), +(39627,0x2), +(39628,0x2); diff --git a/sql/updates/0.10/5571_mangos_player_levelstats.sql b/sql/updates/0.10/5571_mangos_player_levelstats.sql new file mode 100644 index 000000000..6962e0a12 --- /dev/null +++ b/sql/updates/0.10/5571_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 46, `basemana` = 65 WHERE `class` = 3 AND `level`= 1; +UPDATE `player_levelstats` SET `basehp` = 53, `basemana` = 70 WHERE `class` = 3 AND `level`= 2; +UPDATE `player_levelstats` SET `basehp` = 60, `basemana` = 76 WHERE `class` = 3 AND `level`= 3; +UPDATE `player_levelstats` SET `basehp` = 67, `basemana` = 98 WHERE `class` = 3 AND `level`= 4; +UPDATE `player_levelstats` SET `basehp` = 74, `basemana` = 106 WHERE `class` = 3 AND `level`= 5; +UPDATE `player_levelstats` SET `basehp` = 81, `basemana` = 130 WHERE `class` = 3 AND `level`= 6; +UPDATE `player_levelstats` SET `basehp` = 88, `basemana` = 140 WHERE `class` = 3 AND `level`= 7; +UPDATE `player_levelstats` SET `basehp` = 95, `basemana` = 166 WHERE `class` = 3 AND `level`= 8; +UPDATE `player_levelstats` SET `basehp` = 102, `basemana` = 193 WHERE `class` = 3 AND `level`= 9; +UPDATE `player_levelstats` SET `basehp` = 109, `basemana` = 206 WHERE `class` = 3 AND `level`= 10; +UPDATE `player_levelstats` SET `basehp` = 116, `basemana` = 235 WHERE `class` = 3 AND `level`= 11; +UPDATE `player_levelstats` SET `basehp` = 123, `basemana` = 250 WHERE `class` = 3 AND `level`= 12; +UPDATE `player_levelstats` SET `basehp` = 130, `basemana` = 266 WHERE `class` = 3 AND `level`= 13; +UPDATE `player_levelstats` SET `basehp` = 138, `basemana` = 298 WHERE `class` = 3 AND `level`= 14; +UPDATE `player_levelstats` SET `basehp` = 147, `basemana` = 316 WHERE `class` = 3 AND `level`= 15; +UPDATE `player_levelstats` SET `basehp` = 157, `basemana` = 350 WHERE `class` = 3 AND `level`= 16; +UPDATE `player_levelstats` SET `basehp` = 168, `basemana` = 370 WHERE `class` = 3 AND `level`= 17; +UPDATE `player_levelstats` SET `basehp` = 180, `basemana` = 391 WHERE `class` = 3 AND `level`= 18; +UPDATE `player_levelstats` SET `basehp` = 193, `basemana` = 428 WHERE `class` = 3 AND `level`= 19; +UPDATE `player_levelstats` SET `basehp` = 207, `basemana` = 451 WHERE `class` = 3 AND `level`= 20; +UPDATE `player_levelstats` SET `basehp` = 222, `basemana` = 475 WHERE `class` = 3 AND `level`= 21; +UPDATE `player_levelstats` SET `basehp` = 238, `basemana` = 515 WHERE `class` = 3 AND `level`= 22; +UPDATE `player_levelstats` SET `basehp` = 255, `basemana` = 541 WHERE `class` = 3 AND `level`= 23; +UPDATE `player_levelstats` SET `basehp` = 273, `basemana` = 568 WHERE `class` = 3 AND `level`= 24; +UPDATE `player_levelstats` SET `basehp` = 292, `basemana` = 611 WHERE `class` = 3 AND `level`= 25; +UPDATE `player_levelstats` SET `basehp` = 312, `basemana` = 640 WHERE `class` = 3 AND `level`= 26; +UPDATE `player_levelstats` SET `basehp` = 333, `basemana` = 670 WHERE `class` = 3 AND `level`= 27; +UPDATE `player_levelstats` SET `basehp` = 355, `basemana` = 715 WHERE `class` = 3 AND `level`= 28; +UPDATE `player_levelstats` SET `basehp` = 378, `basemana` = 745 WHERE `class` = 3 AND `level`= 29; +UPDATE `player_levelstats` SET `basehp` = 402, `basemana` = 775 WHERE `class` = 3 AND `level`= 30; +UPDATE `player_levelstats` SET `basehp` = 417, `basemana` = 805 WHERE `class` = 3 AND `level`= 31; +UPDATE `player_levelstats` SET `basehp` = 443, `basemana` = 850 WHERE `class` = 3 AND `level`= 32; +UPDATE `player_levelstats` SET `basehp` = 470, `basemana` = 880 WHERE `class` = 3 AND `level`= 33; +UPDATE `player_levelstats` SET `basehp` = 498, `basemana` = 910 WHERE `class` = 3 AND `level`= 34; +UPDATE `player_levelstats` SET `basehp` = 527, `basemana` = 940 WHERE `class` = 3 AND `level`= 35; +UPDATE `player_levelstats` SET `basehp` = 547, `basemana` = 970 WHERE `class` = 3 AND `level`= 36; +UPDATE `player_levelstats` SET `basehp` = 578, `basemana` = 1015 WHERE `class` = 3 AND `level`= 37; +UPDATE `player_levelstats` SET `basehp` = 610, `basemana` = 1045 WHERE `class` = 3 AND `level`= 38; +UPDATE `player_levelstats` SET `basehp` = 643, `basemana` = 1075 WHERE `class` = 3 AND `level`= 39; +UPDATE `player_levelstats` SET `basehp` = 667, `basemana` = 1105 WHERE `class` = 3 AND `level`= 40; +UPDATE `player_levelstats` SET `basehp` = 702, `basemana` = 1135 WHERE `class` = 3 AND `level`= 41; +UPDATE `player_levelstats` SET `basehp` = 738, `basemana` = 1180 WHERE `class` = 3 AND `level`= 42; +UPDATE `player_levelstats` SET `basehp` = 775, `basemana` = 1210 WHERE `class` = 3 AND `level`= 43; +UPDATE `player_levelstats` SET `basehp` = 803, `basemana` = 1240 WHERE `class` = 3 AND `level`= 44; +UPDATE `player_levelstats` SET `basehp` = 842, `basemana` = 1270 WHERE `class` = 3 AND `level`= 45; +UPDATE `player_levelstats` SET `basehp` = 872, `basemana` = 1300 WHERE `class` = 3 AND `level`= 46; +UPDATE `player_levelstats` SET `basehp` = 913, `basemana` = 1330 WHERE `class` = 3 AND `level`= 47; +UPDATE `player_levelstats` SET `basehp` = 955, `basemana` = 1360 WHERE `class` = 3 AND `level`= 48; +UPDATE `player_levelstats` SET `basehp` = 994, `basemana` = 1390 WHERE `class` = 3 AND `level`= 49; +UPDATE `player_levelstats` SET `basehp` = 1047, `basemana` = 1420 WHERE `class` = 3 AND `level`= 50; +UPDATE `player_levelstats` SET `basehp` = 1067, `basemana` = 1450 WHERE `class` = 3 AND `level`= 51; +UPDATE `player_levelstats` SET `basehp` = 1113, `basemana` = 1480 WHERE `class` = 3 AND `level`= 52; +UPDATE `player_levelstats` SET `basehp` = 1150, `basemana` = 1510 WHERE `class` = 3 AND `level`= 53; +UPDATE `player_levelstats` SET `basehp` = 1198, `basemana` = 1540 WHERE `class` = 3 AND `level`= 54; +UPDATE `player_levelstats` SET `basehp` = 1237, `basemana` = 1570 WHERE `class` = 3 AND `level`= 55; +UPDATE `player_levelstats` SET `basehp` = 1287, `basemana` = 1600 WHERE `class` = 3 AND `level`= 56; +UPDATE `player_levelstats` SET `basehp` = 1328, `basemana` = 1630 WHERE `class` = 3 AND `level`= 57; +UPDATE `player_levelstats` SET `basehp` = 1370, `basemana` = 1660 WHERE `class` = 3 AND `level`= 58; +UPDATE `player_levelstats` SET `basehp` = 1423, `basemana` = 1690 WHERE `class` = 3 AND `level`= 59; +UPDATE `player_levelstats` SET `basehp` = 1467, `basemana` = 1720 WHERE `class` = 3 AND `level`= 60; +UPDATE `player_levelstats` SET `basehp` = 1633, `basemana` = 1886 WHERE `class` = 3 AND `level`= 61; +UPDATE `player_levelstats` SET `basehp` = 1819, `basemana` = 2053 WHERE `class` = 3 AND `level`= 62; +UPDATE `player_levelstats` SET `basehp` = 2003, `basemana` = 2219 WHERE `class` = 3 AND `level`= 63; +UPDATE `player_levelstats` SET `basehp` = 2195, `basemana` = 2385 WHERE `class` = 3 AND `level`= 64; +UPDATE `player_levelstats` SET `basehp` = 2397, `basemana` = 2552 WHERE `class` = 3 AND `level`= 65; +UPDATE `player_levelstats` SET `basehp` = 2623, `basemana` = 2718 WHERE `class` = 3 AND `level`= 66; +UPDATE `player_levelstats` SET `basehp` = 2844, `basemana` = 2884 WHERE `class` = 3 AND `level`= 67; +UPDATE `player_levelstats` SET `basehp` = 3075, `basemana` = 3050 WHERE `class` = 3 AND `level`= 68; +UPDATE `player_levelstats` SET `basehp` = 3316, `basemana` = 3217 WHERE `class` = 3 AND `level`= 69; +UPDATE `player_levelstats` SET `basehp` = 3568, `basemana` = 3383 WHERE `class` = 3 AND `level`= 70; diff --git a/sql/updates/0.10/5574_mangos_mangos_string.sql b/sql/updates/0.10/5574_mangos_mangos_string.sql new file mode 100644 index 000000000..1775837cc --- /dev/null +++ b/sql/updates/0.10/5574_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM mangos_string WHERE entry in (468,470); +INSERT INTO mangos_string VALUES +(468,'id: %d eff: %d type: %d duration: %d maxduration: %d name: %s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(470,'id: %d eff: %d name: %s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5574_mangos_spell_learn_spell.sql b/sql/updates/0.10/5574_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..a701f24a1 --- /dev/null +++ b/sql/updates/0.10/5574_mangos_spell_learn_spell.sql @@ -0,0 +1 @@ +DELETE FROM `spell_learn_spell` WHERE `entry` IN (264,266,5011,2018,2108,2259,2366,2550,2567,2575,3273,2842,3908,4036,7411,7620,25229); diff --git a/sql/updates/0.10/5576_mangos_spell_affect.sql b/sql/updates/0.10/5576_mangos_spell_affect.sql new file mode 100644 index 000000000..4fe35128b --- /dev/null +++ b/sql/updates/0.10/5576_mangos_spell_affect.sql @@ -0,0 +1,10 @@ +DELETE FROM spell_affect WHERE entry = 16089; +INSERT INTO spell_affect (entry,effectId,SpellFamily,SpellFamilyMask,Charges) VALUES +(16089,0,0,0x00000004D3300407,0); + +DELETE FROM spell_affect WHERE entry = 16166; +INSERT INTO spell_affect (entry,effectId,SpellFamily,SpellFamilyMask,Charges) VALUES +(16166,0,0,0x0000000090100003,0), +(16166,1,0,0x0000000090100003,0); + + diff --git a/sql/updates/0.10/5576_mangos_spell_proc_event.sql b/sql/updates/0.10/5576_mangos_spell_proc_event.sql new file mode 100644 index 000000000..2a5daf635 --- /dev/null +++ b/sql/updates/0.10/5576_mangos_spell_proc_event.sql @@ -0,0 +1 @@ +UPDATE spell_proc_event SET ppmRate = '10.5' WHERE entry = 30823; \ No newline at end of file diff --git a/sql/updates/0.10/5585_mangos_gameobject_template.sql b/sql/updates/0.10/5585_mangos_gameobject_template.sql new file mode 100644 index 000000000..9a22e2f7e --- /dev/null +++ b/sql/updates/0.10/5585_mangos_gameobject_template.sql @@ -0,0 +1 @@ +ALTER TABLE `gameobject_template` ADD COLUMN `castBarCaption` varchar(100) NOT NULL default '' AFTER name; diff --git a/sql/updates/0.10/5585_mangos_locales_gameobject.sql b/sql/updates/0.10/5585_mangos_locales_gameobject.sql new file mode 100644 index 000000000..d0137e81a --- /dev/null +++ b/sql/updates/0.10/5585_mangos_locales_gameobject.sql @@ -0,0 +1,7 @@ +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc1` varchar(100) NOT NULL default '' AFTER name_loc7; +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc2` varchar(100) NOT NULL default '' AFTER castbarcaption_loc1; +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc3` varchar(100) NOT NULL default '' AFTER castbarcaption_loc2; +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc4` varchar(100) NOT NULL default '' AFTER castbarcaption_loc3; +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc5` varchar(100) NOT NULL default '' AFTER castbarcaption_loc4; +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc6` varchar(100) NOT NULL default '' AFTER castbarcaption_loc5; +ALTER TABLE `locales_gameobject` ADD COLUMN `castbarcaption_loc7` varchar(100) NOT NULL default '' AFTER castbarcaption_loc6; \ No newline at end of file diff --git a/sql/updates/0.10/5586_mangos_spell_proc_event.sql b/sql/updates/0.10/5586_mangos_spell_proc_event.sql new file mode 100644 index 000000000..f6be26460 --- /dev/null +++ b/sql/updates/0.10/5586_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry`=28305; +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `Category`, `SkillID`, `SpellFamilyName`, `SpellFamilyMask`, `procFlags`, `ppmRate`) VALUE +(28305,0,0,0,0,0x0000000000000000,0x00000001,0); diff --git a/sql/updates/0.10/5589_mangos_spell_proc_event.sql b/sql/updates/0.10/5589_mangos_spell_proc_event.sql new file mode 100644 index 000000000..32b6041ef --- /dev/null +++ b/sql/updates/0.10/5589_mangos_spell_proc_event.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (16952,16954); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `Category`, `SkillID`, `SpellFamilyName`, `SpellFamilyMask`, `procFlags`, `ppmRate`) VALUE +(16952,0,0,0,0,0x0000040000039000,0x00010000,0), +(16954,0,0,0,0,0x0000040000039000,0x00010000,0); + + diff --git a/sql/updates/0.10/5593_mangos_spell_proc_event.sql b/sql/updates/0.10/5593_mangos_spell_proc_event.sql new file mode 100644 index 000000000..f45979dc2 --- /dev/null +++ b/sql/updates/0.10/5593_mangos_spell_proc_event.sql @@ -0,0 +1,2 @@ +UPDATE spell_proc_event SET ppmRate = 20 WHERE entry IN (20166,20356,20357,27166); +UPDATE spell_proc_event SET ppmRate = 20 WHERE entry IN (20165,20347,20348,20349,27160); diff --git a/sql/updates/0.10/5628_mangos_creature_movement.sql b/sql/updates/0.10/5628_mangos_creature_movement.sql new file mode 100644 index 000000000..2837aedaf --- /dev/null +++ b/sql/updates/0.10/5628_mangos_creature_movement.sql @@ -0,0 +1,2 @@ +ALTER TABLE creature_movement + DROP aiscript; diff --git a/sql/updates/0.10/5632_characters.sql b/sql/updates/0.10/5632_characters.sql new file mode 100755 index 000000000..1ea31f7e7 --- /dev/null +++ b/sql/updates/0.10/5632_characters.sql @@ -0,0 +1,22 @@ +DROP TABLE IF EXISTS item_test; +CREATE TABLE item_test +SELECT w.`item_guid`,w.`source`,w.`count` FROM + (SELECT u.`item_guid`,u.`source`,COUNT(u.`item_guid`) as `count` FROM + ((SELECT c.`item` as `item_guid`, 'i' as `source` FROM character_inventory c) UNION + (SELECT a.`itemguid` as `item_guid`, 'a' as `source` FROM auctionhouse a) UNION + (SELECT m.`item_guid` as `item_guid`, 'm' as `source` FROM mail_items m) UNION + (SELECT g.`item_guid` as `item_guid`, 'g' as `source` FROM guild_bank_item g) + ) as u + GROUP BY u.`item_guid` + ) as w + WHERE w.`count` > 1; + +DELETE FROM auctionhouse WHERE itemguid IN (SELECT item_guid FROM item_test WHERE `source`='i'); +DELETE FROM mail_items WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='i'); +DELETE FROM guild_bank_item WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='i'); + +DELETE FROM mail_items WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='a'); +DELETE FROM guild_bank_item WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='a'); + +DELETE FROM guild_bank_item WHERE item_guid IN (SELECT item_guid FROM item_test WHERE `source`='m'); +DROP TABLE IF EXISTS item_test; diff --git a/sql/updates/0.10/5634_mangos_mangos_string.sql b/sql/updates/0.10/5634_mangos_mangos_string.sql new file mode 100644 index 000000000..8542cd081 --- /dev/null +++ b/sql/updates/0.10/5634_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry in (666); +INSERT INTO mangos_string VALUES +(666,'After your recent battle in %s our best attempts to award you a Mark of Honor failed. Enclosed you will find the Mark of Honor we were not able to deliver to you at the time. Thanks for fighting in %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.10/5636_mangos_loot_template.sql b/sql/updates/0.10/5636_mangos_loot_template.sql new file mode 100644 index 000000000..987d33dae --- /dev/null +++ b/sql/updates/0.10/5636_mangos_loot_template.sql @@ -0,0 +1,134 @@ +ALTER TABLE `creature_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `creature_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `creature_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `disenchant_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `disenchant_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `disenchant_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `fishing_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `fishing_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `fishing_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `gameobject_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `gameobject_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `gameobject_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `item_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `item_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `item_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `pickpocketing_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `pickpocketing_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `pickpocketing_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `prospecting_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `prospecting_loot_template`SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `prospecting_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; + + +ALTER TABLE `skinning_loot_template` + ADD `ChanceOrQuestChance` FLOAT NOT NULL default '100' AFTER `ChanceOrRef`, + ADD `group` tinyint unsigned NOT NULL default '0' AFTER `QuestChanceOrGroup`, + ADD `mincountOrRef` mediumint NOT NULL default '1' AFTER `mincount`; + +UPDATE `skinning_loot_template` SET + `ChanceOrQuestChance` = if(`QuestChanceOrGroup` > 0, -`QuestChanceOrGroup`, if(`ChanceOrRef` < 0, 100, `ChanceOrRef`)), + `group` = if(`QuestChanceOrGroup` > 0, 0, -`QuestChanceOrGroup`), + `mincountOrRef` = if(`ChanceOrRef` < 0, `ChanceOrRef`, `mincount`), + `maxcount` = if(`ChanceOrRef` < 0, 1, `maxcount`); + +ALTER TABLE `skinning_loot_template` + DROP `ChanceOrRef`, + DROP `QuestChanceOrGroup`, + DROP `mincount`; diff --git a/sql/updates/0.10/5640_mangos_spell_proc_event.sql b/sql/updates/0.10/5640_mangos_spell_proc_event.sql new file mode 100644 index 000000000..a2f639cf0 --- /dev/null +++ b/sql/updates/0.10/5640_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry`=24905; +INSERT INTO `spell_proc_event` ( `entry` , `SchoolMask` , `Category` , `SkillID` , `SpellFamilyName` , `SpellFamilyMask` , `procFlags` , `ppmRate` ) VALUES +('24905', '0', '0', '0', '0', '0', '1', '15'); \ No newline at end of file diff --git a/sql/updates/0.10/5642_mangos_mangos_string.sql b/sql/updates/0.10/5642_mangos_mangos_string.sql new file mode 100644 index 000000000..77c05b720 --- /dev/null +++ b/sql/updates/0.10/5642_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry in (548); +INSERT INTO mangos_string VALUES +(548,'Player%s %s (guid: %u) Account: %s (id: %u) GMLevel: %u Last IP: %s Last login: %s Latency: %ums',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/0.5/1150_character_aura.sql b/sql/updates/0.5/1150_character_aura.sql new file mode 100644 index 000000000..c12e074c5 --- /dev/null +++ b/sql/updates/0.5/1150_character_aura.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `character_aura`; +CREATE TABLE `character_aura` ( + `guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + KEY (`guid`,`spell`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; diff --git a/sql/updates/0.5/1155_commands.sql b/sql/updates/0.5/1155_commands.sql new file mode 100644 index 000000000..83295c1ea --- /dev/null +++ b/sql/updates/0.5/1155_commands.sql @@ -0,0 +1 @@ +ALTER TABLE `command` CHANGE `help` `help` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ; diff --git a/sql/updates/0.5/1155_npc_option.sql b/sql/updates/0.5/1155_npc_option.sql new file mode 100644 index 000000000..58f6ebb8f --- /dev/null +++ b/sql/updates/0.5/1155_npc_option.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS `npc_option`; +CREATE TABLE `npc_option` ( +`id` int(11) unsigned NOT NULL default '0', +`gossip_id` int(11) unsigned NOT NULL default '0', +`npcflag` int(11) unsigned NOT NULL default '0', +`icon` int(11) unsigned NOT NULL default '0', +`action` int(11) unsigned NOT NULL default '0', +`option` text NOT NULL, +PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.5/1158_character_inventory.sql b/sql/updates/0.5/1158_character_inventory.sql new file mode 100644 index 000000000..174a3dd3d --- /dev/null +++ b/sql/updates/0.5/1158_character_inventory.sql @@ -0,0 +1,4 @@ +ALTER TABLE `character_inventory` ADD `bag` TINYINT( 3 ) DEFAULT '0' NOT NULL AFTER `guid` ; + +ALTER TABLE `character_inventory` DROP PRIMARY KEY , +ADD INDEX `idx_guid` ( `guid` , `bag` ) ; diff --git a/sql/updates/0.5/1186_game_weather.sql b/sql/updates/0.5/1186_game_weather.sql new file mode 100644 index 000000000..2d634416e --- /dev/null +++ b/sql/updates/0.5/1186_game_weather.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS `game_weather`; +CREATE TABLE `game_weather` ( + `zone` int(11) unsigned NOT NULL default '0', + `spring_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `spring_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `spring_storm_chance` tinyint(3) unsigned NOT NULL default '25', + `summer_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `summer_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `summer_storm_chance` tinyint(3) unsigned NOT NULL default '25', + `fall_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `fall_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `fall_storm_chance` tinyint(3) unsigned NOT NULL default '25', + `winter_rain_chance` tinyint(3) unsigned NOT NULL default '25', + `winter_snow_chance` tinyint(3) unsigned NOT NULL default '25', + `winter_storm_chance` tinyint(3) unsigned NOT NULL default '25', + PRIMARY KEY (`zone`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Game System'; \ No newline at end of file diff --git a/sql/updates/0.5/1208_npc_trainer.sql b/sql/updates/0.5/1208_npc_trainer.sql new file mode 100644 index 000000000..ac9692ff1 --- /dev/null +++ b/sql/updates/0.5/1208_npc_trainer.sql @@ -0,0 +1,6 @@ +ALTER TABLE `npc_trainer` CHANGE `guid` `entry` INT( 11 ) NOT NULL DEFAULT '0' ; + +ALTER TABLE `npc_trainer` +ADD `reqskill` INT( 11 ) DEFAULT '0' NOT NULL , +ADD `reqskillvalue` INT( 11 ) DEFAULT '0' NOT NULL ; + diff --git a/sql/updates/0.5/1250_item_template.sql b/sql/updates/0.5/1250_item_template.sql new file mode 100644 index 000000000..f3c848d82 --- /dev/null +++ b/sql/updates/0.5/1250_item_template.sql @@ -0,0 +1 @@ +ALTER TABLE `item_template` CHANGE `RequiredRaputationRank` `RequiredReputationRank` INT( 30 ) unsigned NOT NULL DEFAULT '0' ; diff --git a/sql/updates/0.5/1262_areatrigger_tavern.sql b/sql/updates/0.5/1262_areatrigger_tavern.sql new file mode 100644 index 000000000..bc50ddff8 --- /dev/null +++ b/sql/updates/0.5/1262_areatrigger_tavern.sql @@ -0,0 +1,6 @@ +ALTER TABLE `areatrigger_tavern` + CHANGE `triggerid` `id` int(11) unsigned NOT NULL default '0' , + CHANGE `Triggername` `name` text , + DROP KEY `acct`, + DROP PRIMARY KEY , + ADD PRIMARY KEY (`id`) ; diff --git a/sql/updates/0.5/1262_game_graveyard.sql b/sql/updates/0.5/1262_game_graveyard.sql new file mode 100644 index 000000000..6b8321194 --- /dev/null +++ b/sql/updates/0.5/1262_game_graveyard.sql @@ -0,0 +1 @@ +ALTER TABLE `game_graveyard` RENAME TO `areatrigger_graveyard`; diff --git a/sql/updates/0.5/1282_playercreateinfo.sql b/sql/updates/0.5/1282_playercreateinfo.sql new file mode 100644 index 000000000..d32ee218a --- /dev/null +++ b/sql/updates/0.5/1282_playercreateinfo.sql @@ -0,0 +1,8 @@ +TRUNCATE `playercreateinfo` ; + +LOCK TABLES `playercreateinfo` WRITE; +INSERT INTO `playercreateinfo` VALUES (1,1,1,0,12,-8949,-132,84,49,23,20,22,20,21,40,60,0,1000,0,0,29,5,6,0,0),(2,1,2,0,12,-8949,-132,84,49,22,20,22,20,22,40,68,79,0,0,0,27,4,5,0,0),(3,1,4,0,12,-8949,-132,84,49,21,23,21,20,20,40,55,0,0,0,100,27,10,13,0,0),(4,1,5,0,12,-8949,-132,84,49,20,20,20,22,24,40,61,128,0,0,0,30,4,4,0,0),(5,1,8,0,12,-8949,-132,84,49,20,20,20,23,22,40,61,119,0,0,0,30,4,4,0,0),(6,1,9,0,12,-8949,-132,84,49,20,20,21,22,22,40,53,109,0,0,0,30,4,4,0,0),(7,2,1,1,14,-618,-4251,39,51,26,17,24,17,23,0,80,0,1000,0,0,35,6,6,0,0),(8,2,3,1,14,-618,-4251,39,51,23,20,23,17,24,0,76,80,0,0,0,25,4,5,0,0),(9,2,4,1,14,-618,-4251,39,51,24,20,23,17,23,0,75,0,0,0,100,30,4,4,0,0),(10,2,7,1,14,-618,-4251,39,51,24,17,23,18,25,0,97,71,0,0,0,30,4,4,0,0),(11,2,9,1,14,-618,-4251,39,51,23,17,23,19,25,0,73,109,0,0,0,30,4,4,0,0),(12,3,1,0,1,-6240,331,383,53,25,16,25,19,19,0,90,0,1000,0,0,33,5,6,0,0),(13,3,2,0,1,-6240,331,383,53,24,16,25,19,20,0,88,79,0,0,0,31,5,6,0,0),(14,3,3,0,1,-6240,331,383,53,22,19,24,19,20,0,86,80,0,0,0,24,4,5,0,0),(15,3,4,0,1,-6240,331,383,53,23,19,24,19,19,0,85,0,0,0,100,30,4,4,0,0),(16,3,5,0,1,-6240,331,383,53,22,16,23,21,22,0,91,128,0,0,0,30,4,4,0,0),(17,4,1,1,141,10311,832,1327,55,20,25,21,20,20,0,50,0,1000,0,0,21,4,4,0,0),(18,4,3,1,141,10311,832,1327,55,17,28,20,20,21,0,46,80,0,0,0,26,4,5,0,0),(19,4,4,1,141,10311,832,1327,55,18,28,20,20,20,0,45,0,0,0,100,30,4,4,0,0),(20,4,5,1,141,10311,832,1327,55,17,25,19,22,23,0,51,128,0,0,0,30,4,4,0,0),(21,4,11,1,141,10311,832,1327,55,18,25,19,22,22,0,53,67,0,0,0,30,4,4,0,0),(22,5,1,0,85,1676,1677,122,57,22,18,23,18,25,0,70,0,1000,0,0,27,4,5,0,0),(23,5,4,0,85,1676,1677,122,57,20,21,22,18,25,0,65,0,0,0,100,30,4,4,0,0),(24,5,5,0,85,1676,1677,122,57,19,18,21,20,28,0,71,128,0,0,0,30,4,4,0,0),(25,5,8,0,85,1676,1677,122,57,19,18,21,21,27,0,71,119,0,0,0,30,4,4,0,0),(26,5,9,0,85,1676,1677,122,57,19,18,22,20,27,0,63,109,0,0,0,30,4,4,0,0),(27,6,1,1,215,-2917,-257,53,59,28,15,24,15,22,0,80,0,1000,0,0,39,6,7,0,0),(28,6,3,1,215,-2917,-257,53,59,25,18,23,15,23,0,76,80,0,0,0,16,5,7,0,0),(29,6,7,1,215,-2917,-257,53,59,26,15,23,16,24,0,97,71,0,0,0,30,4,4,0,0),(30,6,11,1,215,-2917,-257,53,59,26,15,22,17,24,0,97,67,0,0,0,30,4,4,0,0),(31,7,1,0,1,-6240,331,383,1563,18,23,21,23,20,0,50,0,1000,0,0,10,3,4,0,0),(32,7,4,0,1,-6340,331,383,1563,16,26,20,23,20,0,45,0,0,0,100,30,4,4,0,0),(33,7,8,0,1,-6340,331,383,1563,15,23,19,26,22,0,51,119,0,0,0,30,4,4,0,0),(34,7,9,0,1,-6340,331,383,1563,15,23,20,25,22,0,43,109,0,0,0,30,4,4,0,0),(35,8,1,1,14,-618,-4251,39,1478,24,22,23,16,21,0,70,0,1000,0,0,29,5,7,0,0),(36,8,3,1,14,-618,-4251,39,1478,21,25,22,16,22,0,66,80,0,0,0,16,5,7,0,0),(37,8,4,1,14,-618,-4251,39,1478,22,25,22,16,21,0,65,0,0,0,100,30,4,4,0,0),(38,8,5,1,14,-618,-4251,39,1478,21,22,21,18,24,0,71,128,0,0,0,30,4,4,0,0),(39,8,7,1,14,-618,-4251,39,1478,22,22,22,17,23,0,87,71,0,0,0,30,4,4,0,0),(40,8,8,1,14,-618,-4251,39,1478,21,22,21,19,23,0,71,119,0,0,0,30,4,4,0,0); +UNLOCK TABLES; + + + diff --git a/sql/updates/0.5/1282_playercreateinfo_item.sql b/sql/updates/0.5/1282_playercreateinfo_item.sql new file mode 100644 index 000000000..73b2a516a --- /dev/null +++ b/sql/updates/0.5/1282_playercreateinfo_item.sql @@ -0,0 +1,10 @@ +TRUNCATE `playercreateinfo_item` ; + +LOCK TABLES `playercreateinfo_item` WRITE; +INSERT INTO `playercreateinfo_item` VALUES (1,38,255,3,1),(1,39,255,6,1),(1,40,255,7,1),(1,25,255,15,1),(1,2362,255,16,1),(1,65020,255,23,4),(1,6948,255,24,1),(1,14646,255,25,1),(2,45,255,3,1),(2,44,255,6,1),(2,43,255,7,1),(2,2361,255,15,1),(2,6948,255,23,1),(2,65021,255,24,2),(2,65022,255,25,4),(2,14646,255,26,1),(3,49,255,3,1),(3,48,255,6,1),(3,47,255,7,1),(3,2092,255,15,1),(3,65023,255,17,100),(3,65022,255,23,4),(3,6948,255,24,1),(3,14646,255,25,1),(4,53,255,3,1),(4,6098,255,4,1),(4,52,255,6,1),(4,51,255,7,1),(4,36,255,15,1),(4,65021,255,23,2),(4,65022,255,24,4),(4,6948,255,25,1),(4,14646,255,26,1),(5,6096,255,3,1),(5,56,255,4,1),(5,1395,255,6,1),(5,55,255,7,1),(5,35,255,15,1),(5,65022,255,23,4),(5,65021,255,24,2),(5,6948,255,25,1),(5,14646,255,26,1),(6,6097,255,3,1),(6,57,255,4,1),(6,1396,255,6,1),(6,59,255,7,1),(6,2092,255,15,1),(6,65027,255,23,4),(6,65021,255,24,2),(6,6948,255,25,1),(6,14646,255,26,1),(7,6125,255,3,1),(7,139,255,6,1),(7,140,255,7,1),(7,12282,255,15,1),(7,6948,255,23,1),(7,65020,255,24,4),(7,14649,255,25,1),(8,127,255,3,1),(8,6126,255,6,1),(8,6127,255,7,1),(8,37,255,15,1),(8,2504,255,17,1),(8,65021,255,23,2),(8,65020,255,24,4),(8,6948,255,25,1),(8,14649,255,26,1),(8,2512,255,27,200),(8,2101,255,28,1),(9,2105,255,3,1),(9,120,255,6,1),(9,121,255,7,1),(9,2092,255,15,1),(9,65024,255,17,100),(9,65020,255,23,4),(9,6948,255,24,1),(9,14649,255,25,1),(10,154,255,3,1),(10,153,255,6,1),(10,36,255,15,1),(10,6948,255,23,1),(10,65020,255,24,4),(10,65021,255,25,2),(10,14649,255,26,1),(11,6129,255,4,1),(11,1396,255,6,1),(11,59,255,7,1),(11,2092,255,15,1),(11,6948,255,23,1),(11,65020,255,24,4),(11,65021,255,25,2),(11,14649,255,26,1),(12,38,255,3,1),(12,39,255,6,1),(12,40,255,7,1),(12,12282,255,15,1),(12,6948,255,23,1),(12,65020,255,24,4),(12,14647,255,25,1),(13,45,255,3,1),(13,44,255,6,1),(13,43,255,7,1),(13,2361,255,15,1),(13,65026,255,23,4),(13,65021,255,24,2),(13,6948,255,25,1),(13,14647,255,26,1),(14,148,255,3,1),(14,147,255,6,1),(14,129,255,7,1),(14,37,255,15,1),(14,2508,255,17,1),(14,65021,255,23,2),(14,65020,255,24,4),(14,6948,255,25,1),(14,14647,255,26,1),(14,2516,255,27,200),(14,2102,255,28,1),(15,49,255,3,1),(15,48,255,6,1),(15,47,255,7,1),(15,2092,255,15,1),(15,65024,255,17,100),(15,65026,255,23,4),(15,6948,255,24,1),(15,14647,255,25,1),(16,53,255,3,1),(16,6098,255,4,1),(16,52,255,6,1),(16,51,255,7,1),(16,36,255,15,1),(16,65021,255,23,2),(16,65026,255,24,4),(16,6948,255,25,1),(16,14647,255,26,1),(17,38,255,3,1),(17,39,255,6,1),(17,40,255,7,1),(17,25,255,15,1),(17,2362,255,16,1),(17,65020,255,23,4),(17,6948,255,24,1),(17,14648,255,25,1),(18,148,255,3,1),(18,147,255,6,1),(18,129,255,7,1),(18,2092,255,15,1),(18,2504,255,17,1),(18,65021,255,23,2),(18,65020,255,24,4),(18,6948,255,25,1),(18,14648,255,26,1),(18,2512,255,27,200),(18,2101,255,28,1),(19,49,255,3,1),(19,48,255,6,1),(19,47,255,7,1),(19,2092,255,15,1),(19,65023,255,17,100),(19,65026,255,23,4),(19,6948,255,24,1),(19,14648,255,25,1),(20,53,255,3,1),(20,6119,255,4,1),(20,52,255,6,1),(20,51,255,7,1),(20,36,255,15,1),(20,65022,255,23,4),(20,65021,255,24,2),(20,6948,255,25,1),(20,14648,255,26,1),(21,6123,255,4,1),(21,44,255,6,1),(21,3661,255,15,1),(21,65021,255,23,2),(21,65025,255,24,4),(21,6948,255,25,1),(21,14648,255,26,1),(22,6125,255,3,1),(22,139,255,6,1),(22,140,255,7,1),(22,25,255,15,1),(22,2362,255,16,1),(22,65027,255,23,4),(22,6948,255,24,1),(22,14651,255,25,1),(23,2105,255,3,1),(23,120,255,6,1),(23,121,255,7,1),(23,2092,255,15,1),(23,65023,255,17,100),(23,65027,255,23,4),(23,6948,255,24,1),(23,14651,255,25,1),(24,53,255,3,1),(24,6144,255,4,1),(24,52,255,6,1),(24,51,255,7,1),(24,36,255,15,1),(24,65027,255,23,4),(24,65021,255,24,2),(24,6948,255,25,1),(24,14651,255,26,1),(25,6096,255,3,1),(25,6140,255,4,1),(25,1395,255,6,1),(25,55,255,7,1),(25,35,255,15,1),(25,65027,255,23,4),(25,65021,255,24,2),(25,6948,255,25,1),(25,14651,255,26,1),(26,6129,255,4,1),(26,1396,255,6,1),(26,59,255,7,1),(26,2092,255,15,1),(26,65027,255,23,4),(26,65021,255,24,2),(26,6948,255,25,1),(26,14651,255,26,1),(27,6125,255,3,1),(27,139,255,6,1),(27,2361,255,15,1),(27,6948,255,23,1),(27,65026,255,24,4),(27,14650,255,25,1),(28,127,255,3,1),(28,6126,255,6,1),(28,37,255,15,1),(28,2508,255,17,1),(28,65021,255,23,2),(28,65020,255,24,4),(28,6948,255,25,1),(28,14650,255,26,1),(28,2516,255,27,200),(28,2102,255,28,1),(29,154,255,3,1),(29,153,255,6,1),(29,36,255,15,1),(29,6948,255,23,1),(29,65027,255,24,4),(29,65021,255,25,2),(29,14650,255,26,1),(30,6139,255,4,1),(30,6124,255,6,1),(30,35,255,15,1),(30,65021,255,23,2),(30,65025,255,24,4),(30,6948,255,25,1),(30,14650,255,26,1),(31,38,255,4,1),(31,39,255,6,1),(31,40,255,7,1),(31,25,255,15,1),(31,2362,255,16,1),(31,65020,255,23,4),(31,6948,255,24,1),(31,14647,255,25,1),(32,49,255,3,1),(32,48,255,6,1),(32,47,255,7,1),(32,2092,255,15,1),(32,65023,255,17,100),(32,65020,255,23,4),(32,6948,255,24,1),(32,14647,255,25,1),(33,6096,255,3,1),(33,56,255,4,1),(33,1395,255,6,1),(33,55,255,7,1),(33,35,255,15,1),(33,65025,255,23,4),(33,65021,255,24,2),(33,6948,255,25,1),(33,14647,255,26,1),(34,6097,255,3,1),(34,57,255,4,1),(34,1396,255,6,1),(34,59,255,7,1),(34,2092,255,15,1),(34,65021,255,23,2),(34,65027,255,24,4),(34,6948,255,25,1),(34,14647,255,26,1),(35,6125,255,3,1),(35,139,255,6,1),(35,140,255,7,1),(35,37,255,15,1),(35,2362,255,16,1),(35,65024,255,17,100),(35,65020,255,23,4),(35,6948,255,24,1),(35,14649,255,25,1),(36,127,255,3,1),(36,6126,255,6,1),(36,6127,255,7,1),(36,37,255,15,1),(36,2504,255,17,1),(36,65027,255,23,4),(36,65021,255,24,2),(36,2512,255,27,200),(36,2101,255,28,1),(36,14649,255,26,1),(36,6948,255,25,1),(37,2105,255,3,1),(37,120,255,6,1),(37,121,255,7,1),(37,2092,255,15,1),(37,65024,255,17,100),(37,65020,255,23,4),(37,6948,255,24,1),(37,14649,255,25,1),(38,53,255,3,1),(38,6144,255,4,1),(38,52,255,6,1),(38,36,255,15,1),(38,65026,255,23,4),(38,65021,255,24,2),(38,6948,255,25,1),(38,14649,255,26,1),(39,6134,255,3,1),(39,6135,255,6,1),(39,36,255,15,1),(39,65020,255,23,4),(39,65021,255,24,2),(39,6948,255,25,1),(39,14649,255,26,1),(40,6096,255,3,1),(40,6140,255,4,1),(40,1395,255,6,1),(40,55,255,7,1),(40,35,255,15,1),(40,65020,255,23,4),(40,65021,255,24,2),(40,6948,255,25,1),(40,14649,255,26,1); +UNLOCK TABLES; + + + + + diff --git a/sql/updates/0.5/1292_loot_template.sql b/sql/updates/0.5/1292_loot_template.sql new file mode 100644 index 000000000..97d180783 --- /dev/null +++ b/sql/updates/0.5/1292_loot_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE `loot_template` + CHANGE `itemid` `item` int(11) unsigned NOT NULL default '0' , + CHANGE `percentchance` `chance` float NOT NULL default '100' , + DROP KEY `i_creature_loot_creatureid` , + DROP KEY `creatureloot_index` , + ADD PRIMARY KEY (`entry`,`item`) ; diff --git a/sql/updates/0.5/1332_character_queststatus.sql b/sql/updates/0.5/1332_character_queststatus.sql new file mode 100644 index 000000000..1a32a7854 --- /dev/null +++ b/sql/updates/0.5/1332_character_queststatus.sql @@ -0,0 +1,18 @@ +ALTER TABLE `character_queststatus` + CHANGE `playerid` `guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + CHANGE `questid` `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + CHANGE `status` `status` int(11) unsigned NOT NULL default '0', + CHANGE `rewarded` `rewarded` int(11) unsigned NOT NULL default '0', + CHANGE `explored` `explored` int(11) unsigned NOT NULL default '0' AFTER `rewarded` , + CHANGE `timer` `timer` bigint(20) unsigned NOT NULL default '0' AFTER `explored` , + CHANGE `questMobCount1` `mobcount1` int(11) unsigned NOT NULL default '0', + CHANGE `questMobCount2` `mobcount2` int(11) unsigned NOT NULL default '0', + CHANGE `questMobCount3` `mobcount3` int(11) unsigned NOT NULL default '0', + CHANGE `questMobCount4` `mobcount4` int(11) unsigned NOT NULL default '0', + CHANGE `questItemCount1` `itemcount1` int(11) unsigned NOT NULL default '0', + CHANGE `questItemCount2` `itemcount2` int(11) unsigned NOT NULL default '0', + CHANGE `questItemCount3` `itemcount3` int(11) unsigned NOT NULL default '0', + CHANGE `questItemCount4` `itemcount4` int(11) unsigned NOT NULL default '0', + DROP `id` , + DROP PRIMARY KEY , + ADD PRIMARY KEY (`guid`,`quest`) ; diff --git a/sql/updates/0.5/1336_item_template.sql b/sql/updates/0.5/1336_item_template.sql new file mode 100644 index 000000000..f200674af --- /dev/null +++ b/sql/updates/0.5/1336_item_template.sql @@ -0,0 +1 @@ +ALTER TABLE `item_template` ADD `RangedModRange` float NOT NULL default '0' AFTER `ammo_type` ; diff --git a/sql/updates/0.5/1339_areatrigger_city.sql b/sql/updates/0.5/1339_areatrigger_city.sql new file mode 100644 index 000000000..4ca9eb0d8 --- /dev/null +++ b/sql/updates/0.5/1339_areatrigger_city.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS `areatrigger_city`; +CREATE TABLE `areatrigger_city` ( + `id` int(11) unsigned NOT NULL default '0' COMMENT 'Identifier', + `name` text, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Trigger System'; diff --git a/sql/updates/0.5/1349_areatrigger_involvedrelation.sql b/sql/updates/0.5/1349_areatrigger_involvedrelation.sql new file mode 100644 index 000000000..69d713c14 --- /dev/null +++ b/sql/updates/0.5/1349_areatrigger_involvedrelation.sql @@ -0,0 +1 @@ +ALTER TABLE `areatrigger_involvedrelation` DROP `creature` ; diff --git a/sql/updates/0.5/1349_character_aura.sql b/sql/updates/0.5/1349_character_aura.sql new file mode 100644 index 000000000..2290782d2 --- /dev/null +++ b/sql/updates/0.5/1349_character_aura.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character_aura` + DROP KEY `guid` , + ADD PRIMARY KEY (`guid`,`spell`) ; diff --git a/sql/updates/0.5/1349_character_inventory.sql b/sql/updates/0.5/1349_character_inventory.sql new file mode 100644 index 000000000..8e0f1c5a6 --- /dev/null +++ b/sql/updates/0.5/1349_character_inventory.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character_inventory` + DROP KEY `idx_guid` , + ADD PRIMARY KEY (`guid`,`bag`,`slot`) ; diff --git a/sql/updates/0.5/1349_creature_template.sql b/sql/updates/0.5/1349_creature_template.sql new file mode 100644 index 000000000..5f5584895 --- /dev/null +++ b/sql/updates/0.5/1349_creature_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template` + DROP KEY `entry` , + ADD PRIMARY KEY (`entry`) ; diff --git a/sql/updates/0.5/1349_gameobject_template.sql b/sql/updates/0.5/1349_gameobject_template.sql new file mode 100644 index 000000000..f440fe362 --- /dev/null +++ b/sql/updates/0.5/1349_gameobject_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `gameobject_template` + DROP KEY `id` , + ADD PRIMARY KEY (`entry`) ; diff --git a/sql/updates/0.5/1356_item_template.sql b/sql/updates/0.5/1356_item_template.sql new file mode 100644 index 000000000..49cc91e7a --- /dev/null +++ b/sql/updates/0.5/1356_item_template.sql @@ -0,0 +1,11 @@ +ALTER TABLE `item_template` + CHANGE `dmg_min1` `dmg_min1` float NOT NULL default '0', + CHANGE `dmg_max1` `dmg_max1` float NOT NULL default '0', + CHANGE `dmg_min2` `dmg_min2` float NOT NULL default '0', + CHANGE `dmg_max2` `dmg_max2` float NOT NULL default '0', + CHANGE `dmg_min3` `dmg_min3` float NOT NULL default '0', + CHANGE `dmg_max3` `dmg_max3` float NOT NULL default '0', + CHANGE `dmg_min4` `dmg_min4` float NOT NULL default '0', + CHANGE `dmg_max4` `dmg_max4` float NOT NULL default '0', + CHANGE `dmg_min5` `dmg_min5` float NOT NULL default '0', + CHANGE `dmg_max5` `dmg_max5` float NOT NULL default '0'; diff --git a/sql/updates/0.5/1411_item_template.sql b/sql/updates/0.5/1411_item_template.sql new file mode 100644 index 000000000..eb9399fe0 --- /dev/null +++ b/sql/updates/0.5/1411_item_template.sql @@ -0,0 +1 @@ +ALTER TABLE `item_template` ADD `Unknown1` int(30) unsigned NOT NULL default '0' AFTER `area` ; diff --git a/sql/updates/0.5/1447_quest_template.sql b/sql/updates/0.5/1447_quest_template.sql new file mode 100644 index 000000000..e3f8a9b7c --- /dev/null +++ b/sql/updates/0.5/1447_quest_template.sql @@ -0,0 +1,11 @@ +ALTER TABLE `quest_template` + CHANGE `Title` `Title` text, + CHANGE `Details` `Details` text, + CHANGE `Objectives` `Objectives` text, + CHANGE `CompletionText` `CompletionText` text, + CHANGE `IncompleteText` `IncompleteText` text, + CHANGE `EndText` `EndText` text, + CHANGE `ObjectiveText1` `ObjectiveText1` text, + CHANGE `ObjectiveText2` `ObjectiveText2` text, + CHANGE `ObjectiveText3` `ObjectiveText3` text, + CHANGE `ObjectiveText4` `ObjectiveText4` text; diff --git a/sql/updates/0.5/1465_build_realmd_db.sql b/sql/updates/0.5/1465_build_realmd_db.sql new file mode 100644 index 000000000..1b52a8c6f --- /dev/null +++ b/sql/updates/0.5/1465_build_realmd_db.sql @@ -0,0 +1,92 @@ +-- MySQL dump 10.10 +-- +-- Host: localhost Database: realmd +-- ------------------------------------------------------ +-- Server version 5.0.21 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `account` +-- + +DROP TABLE IF EXISTS `account`; +CREATE TABLE `account` ( + `id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'Identifier', + `username` varchar(16) NOT NULL default '', + `password` varchar(28) NOT NULL default '', + `gmlevel` tinyint(3) unsigned NOT NULL default '0', + `sessionkey` longtext, + `email` varchar(50) NOT NULL default '', + `joindate` timestamp NOT NULL default CURRENT_TIMESTAMP, + `banned` tinyint(3) unsigned NOT NULL default '0', + `last_ip` varchar(30) NOT NULL default '127.0.0.1', + `failed_logins` int(11) unsigned NOT NULL default '0', + `locked` tinyint(3) unsigned NOT NULL default '0', + `last_login` timestamp NOT NULL default '0000-00-00 00:00:00', + `online` tinyint NOT NULL default 0, + PRIMARY KEY (`id`), + UNIQUE KEY `idx_username` (`username`), + KEY `idx_banned` (`banned`), + KEY `idx_gmlevel` (`gmlevel`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Account System'; + +-- +-- Table structure for table `realmcharacters` +-- + +DROP TABLE IF EXISTS `realmcharacters`; +CREATE TABLE `realmcharacters` ( + `realmid` integer(11) unsigned NOT NULL default '0', + `acctid` bigint(20) unsigned NOT NULL, + `numchars` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`realmid`, `acctid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Realm Character Tracker'; + + +-- +-- Table structure for table `ip_banned` +-- + +DROP TABLE IF EXISTS `ip_banned`; +CREATE TABLE `ip_banned` ( + `ip` varchar(32) NOT NULL default '127.0.0.1', + PRIMARY KEY (`ip`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Banned IPs'; + +-- +-- Dumping data for table `ip_banned` +-- + + +/*!40000 ALTER TABLE `ip_banned` DISABLE KEYS */; +LOCK TABLES `ip_banned` WRITE; +UNLOCK TABLES; +/*!40000 ALTER TABLE `ip_banned` ENABLE KEYS */; + + +-- +-- Table structure for table `realmlist` +-- + +DROP TABLE IF EXISTS `realmlist`; +CREATE TABLE `realmlist` ( + `id` int(11) unsigned NOT NULL auto_increment, + `name` varchar(32) NOT NULL default '', + `address` varchar(32) NOT NULL default '127.0.0.1', + `icon` tinyint(3) unsigned NOT NULL default '0', + `color` tinyint(3) unsigned NOT NULL default '0', + `timezone` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + UNIQUE KEY `idx_name` (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Realm System'; + diff --git a/sql/updates/0.5/1465_create_realmd_db.sql b/sql/updates/0.5/1465_create_realmd_db.sql new file mode 100644 index 000000000..8411114b2 --- /dev/null +++ b/sql/updates/0.5/1465_create_realmd_db.sql @@ -0,0 +1,4 @@ +GRANT USAGE ON * . * TO 'mangos'@'localhost' IDENTIFIED BY 'mangos' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 ; +CREATE DATABASE `realmd` ; +GRANT ALL PRIVILEGES ON `realmd` . * TO 'mangos'@'localhost' WITH GRANT OPTION ; + diff --git a/sql/updates/0.5/1465_populate_realmd_db.sql b/sql/updates/0.5/1465_populate_realmd_db.sql new file mode 100644 index 000000000..0aa78a7fb --- /dev/null +++ b/sql/updates/0.5/1465_populate_realmd_db.sql @@ -0,0 +1,17 @@ +truncate realmd.realmlist; +insert into realmd.realmlist +select `id`, `name`, `address`, `icon`, `color`, `timezone` from mangos.realmlist; +drop table mangos.realmlist; + +truncate realmd.account; +insert into realmd.account +select *,0 from mangos.account; +drop table mangos.account; + +INSERT INTO RealmCharacters +SELECT realmlist.id, account.id, 0 from realmlist, account; + +truncate realmd.ip_banned; +insert into realmd.ip_banned +select * from mangos.ip_banned; +drop table mangos.ip_banned; diff --git a/sql/updates/0.5/1475_character_aura.sql b/sql/updates/0.5/1475_character_aura.sql new file mode 100644 index 000000000..6a4c49dbe --- /dev/null +++ b/sql/updates/0.5/1475_character_aura.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character_aura` + DROP PRIMARY KEY , + ADD PRIMARY KEY (`guid`,`spell`,`effect_index`) ; diff --git a/sql/updates/0.5/1511_object_involvedrelation.sql b/sql/updates/0.5/1511_object_involvedrelation.sql new file mode 100644 index 000000000..05839658a --- /dev/null +++ b/sql/updates/0.5/1511_object_involvedrelation.sql @@ -0,0 +1,7 @@ +ALTER TABLE `object_involvedrelation` + RENAME TO `gameobject_involvedrelation`, + DROP PRIMARY KEY, + DROP `Id`, + CHANGE `objectId` `id` int(11) unsigned NOT NULL default '0', + CHANGE `questId` `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier' AFTER `id`, + ADD PRIMARY KEY (`id`,`quest`); diff --git a/sql/updates/0.5/1511_object_questrelation.sql b/sql/updates/0.5/1511_object_questrelation.sql new file mode 100644 index 000000000..aac0e5679 --- /dev/null +++ b/sql/updates/0.5/1511_object_questrelation.sql @@ -0,0 +1,7 @@ +ALTER TABLE `object_questrelation` + RENAME TO `gameobject_questrelation`, + DROP PRIMARY KEY, + DROP `Id`, + CHANGE `objectId` `id` int(11) unsigned NOT NULL default '0', + CHANGE `questId` `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier' AFTER `id`, + ADD PRIMARY KEY (`id`,`quest`); diff --git a/sql/updates/0.5/1526_npc_vendor.sql b/sql/updates/0.5/1526_npc_vendor.sql new file mode 100644 index 000000000..36a331b75 --- /dev/null +++ b/sql/updates/0.5/1526_npc_vendor.sql @@ -0,0 +1,9 @@ +ALTER TABLE `npc_vendor` + DROP PRIMARY KEY, + DROP KEY `vendor_id` , + DROP `index_id`, + CHANGE `entry` `entry` int(11) unsigned NOT NULL default '0', + CHANGE `itemguid` `item` int(11) unsigned NOT NULL default '0', + CHANGE `amount` `buycount` int(11) unsigned NOT NULL default '1', + ADD `maxcount` int(11) unsigned NOT NULL default '0', + ADD `incrtime` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.5/1562_creature_template.sql b/sql/updates/0.5/1562_creature_template.sql new file mode 100644 index 000000000..529e027da --- /dev/null +++ b/sql/updates/0.5/1562_creature_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template` + ADD `mingold` int(30) unsigned NOT NULL default '0' AFTER `spell4` , + ADD `maxgold` int(30) unsigned NOT NULL default '0' AFTER `mingold`; \ No newline at end of file diff --git a/sql/updates/0.5/1576_command.sql b/sql/updates/0.5/1576_command.sql new file mode 100644 index 000000000..5c3237946 --- /dev/null +++ b/sql/updates/0.5/1576_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES ('additemset',3,'Syntax: .additemset #itemsetid\r\n\r\nAdd items from itemset of id #itemsetid to your inventory. Will add by one example each item from itemset.'); diff --git a/sql/updates/0.5/1595_area_graveyard.sql b/sql/updates/0.5/1595_area_graveyard.sql new file mode 100644 index 000000000..512762f46 --- /dev/null +++ b/sql/updates/0.5/1595_area_graveyard.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS `areatrigger_graveyard_zone`; + +CREATE TABLE `areatrigger_graveyard_zone` AS SELECT + `areatrigger_graveyard`.`id` AS `id`, + `areatrigger_graveyard`.`map` AS `ghost_map`, + `areatrigger_graveyard`.`zone` AS `ghost_zone` +FROM `areatrigger_graveyard` ; + +ALTER TABLE `areatrigger_graveyard` + DROP `zone`; + diff --git a/sql/updates/0.5/1601_game_addons.sql b/sql/updates/0.5/1601_game_addons.sql new file mode 100644 index 000000000..c9dbeb251 --- /dev/null +++ b/sql/updates/0.5/1601_game_addons.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `game_addons`; +CREATE TABLE `game_addons` ( + `addonname` char(255) NOT NULL default '', + `crc` bigint(20) NOT NULL default '0', + `enabled` tinyint(4) NOT NULL default '0', + PRIMARY KEY (`addonname`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Addons System'; diff --git a/sql/updates/0.5/1615_areatrigger_graveyard.sql b/sql/updates/0.5/1615_areatrigger_graveyard.sql new file mode 100644 index 000000000..abe329b9c --- /dev/null +++ b/sql/updates/0.5/1615_areatrigger_graveyard.sql @@ -0,0 +1,3 @@ +ALTER TABLE `areatrigger_graveyard` + CHANGE `id` `id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier'; + diff --git a/sql/updates/0.5/1635_character.sql b/sql/updates/0.5/1635_character.sql new file mode 100644 index 000000000..c70fc62d8 --- /dev/null +++ b/sql/updates/0.5/1635_character.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character` CHANGE `honor` `highest_rank` INT( 11 ) DEFAULT '0' NOT NULL , +CHANGE `last_week_honor` `standing` INT( 11 ) DEFAULT '0' NOT NULL ; +ALTER TABLE `character` ADD `rating` FLOAT( 11 ) DEFAULT '0' NOT NULL AFTER `standing` ; \ No newline at end of file diff --git a/sql/updates/0.5/1669_character_spell.sql b/sql/updates/0.5/1669_character_spell.sql new file mode 100644 index 000000000..0bd65b34b --- /dev/null +++ b/sql/updates/0.5/1669_character_spell.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_spell` + ADD `active` int(11) unsigned NOT NULL default '1'; diff --git a/sql/updates/0.5/1676_game_graveyard.sql b/sql/updates/0.5/1676_game_graveyard.sql new file mode 100644 index 000000000..c83496882 --- /dev/null +++ b/sql/updates/0.5/1676_game_graveyard.sql @@ -0,0 +1,5 @@ +ALTER TABLE `areatrigger_graveyard` + RENAME TO `game_graveyard`; + +ALTER TABLE `areatrigger_graveyard_zone` + RENAME TO `game_graveyard_zone`; diff --git a/sql/updates/0.5/1676_game_tele.sql b/sql/updates/0.5/1676_game_tele.sql new file mode 100644 index 000000000..73a5d448a --- /dev/null +++ b/sql/updates/0.5/1676_game_tele.sql @@ -0,0 +1,10 @@ +CREATE TABLE `game_tele` ( + `id` int(11) unsigned NOT NULL auto_increment, + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `orientation` float NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0', + `name` varchar(100) NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Tele Command'; diff --git a/sql/updates/0.5/1687_loot_template.sql b/sql/updates/0.5/1687_loot_template.sql new file mode 100644 index 000000000..a9f8eb233 --- /dev/null +++ b/sql/updates/0.5/1687_loot_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE `loot_template` + ADD `questchance` float NOT NULL default '0'; + +UPDATE `loot_template` SET `questchance` = 100 WHERE `chance` = 0; diff --git a/sql/updates/0.5/1704_item_template.sql b/sql/updates/0.5/1704_item_template.sql new file mode 100644 index 000000000..96079a6e4 --- /dev/null +++ b/sql/updates/0.5/1704_item_template.sql @@ -0,0 +1,9 @@ +ALTER TABLE `item_template` ADD COLUMN `BuyCount` TINYINT(3) UNSIGNED NOT NULL DEFAULT 1 AFTER `Flags`; +ALTER TABLE `npc_vendor` DROP COLUMN `buycount`; + +UPDATE `item_template` + SET `BuyCount` = (`BuyPrice` DIV (`SellPrice` * 4)) WHERE `SellPrice` > 0; + +UPDATE `item_template` + SET `BuyCount` = 1 WHERE `BuyCount` = 0; + diff --git a/sql/updates/0.5/1799_quest_template.sql b/sql/updates/0.5/1799_quest_template.sql new file mode 100644 index 000000000..05a3ebd7f --- /dev/null +++ b/sql/updates/0.5/1799_quest_template.sql @@ -0,0 +1,11 @@ +ALTER TABLE `quest_template` + ADD COLUMN `RequiredRepFaction` int(11) unsigned NOT NULL default '0' AFTER `RequiredTradeskill`, + ADD COLUMN `RequiredRepValue` int(11) unsigned NOT NULL default '0' AFTER `RequiredRepFaction`, + CHANGE `ReqKillMobId1` `ReqKillMobOrGOId1` int(11) NOT NULL default '0', + CHANGE `ReqKillMobId2` `ReqKillMobOrGOId2` int(11) NOT NULL default '0', + CHANGE `ReqKillMobId3` `ReqKillMobOrGOId3` int(11) NOT NULL default '0', + CHANGE `ReqKillMobId4` `ReqKillMobOrGOId4` int(11) NOT NULL default '0', + CHANGE `ReqKillMobCount1` `ReqKillMobOrGOCount1` int(11) unsigned NOT NULL default '0', + CHANGE `ReqKillMobCount2` `ReqKillMobOrGOCount2` int(11) unsigned NOT NULL default '0', + CHANGE `ReqKillMobCount3` `ReqKillMobOrGOCount3` int(11) unsigned NOT NULL default '0', + CHANGE `ReqKillMobCount4` `ReqKillMobOrGOCount4` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.5/1825_game_corpse.sql b/sql/updates/0.5/1825_game_corpse.sql new file mode 100644 index 000000000..eabad471e --- /dev/null +++ b/sql/updates/0.5/1825_game_corpse.sql @@ -0,0 +1 @@ +ALTER TABLE `game_corpse` DROP INDEX `idx_player`; diff --git a/sql/updates/0.5/1856_command.sql b/sql/updates/0.5/1856_command.sql new file mode 100644 index 000000000..b644a0cfc --- /dev/null +++ b/sql/updates/0.5/1856_command.sql @@ -0,0 +1,3 @@ +insert into command values('shutdown','3','Syntax: .shutdown seconds'); +insert into command values('cshutdown','3','Syntax: .cshutdown Cancels shuttdown'); + diff --git a/sql/updates/0.5/1865_command.sql b/sql/updates/0.5/1865_command.sql new file mode 100644 index 000000000..baa577318 --- /dev/null +++ b/sql/updates/0.5/1865_command.sql @@ -0,0 +1,2 @@ +insert into command values('reset','3','Usage: .reset stats\r\nResets all stats of the targeted player to their original values at level 1.\r\nPlease unequip all items and debuff all auras from the player before using.'); + diff --git a/sql/updates/0.5/1880_command.sql b/sql/updates/0.5/1880_command.sql new file mode 100644 index 000000000..e28e57483 --- /dev/null +++ b/sql/updates/0.5/1880_command.sql @@ -0,0 +1,3 @@ +insert into command values('maxskill','3','Usage: .maxskill\r\nSets all skills of the targeted player to their maximum values for its current level.'); +UPDATE `command` SET `help` = 'Usage:\r\n.reset stats\r\n Resets all stats of the targeted player to their original values at level 1.\r\n Please unequip all items and debuff all auras from the player before using.\r\n.reset talents\r\n Removes all talents of the targeted player.' WHERE `name` = 'reset'; + diff --git a/sql/updates/0.5/1883_quest_template.sql b/sql/updates/0.5/1883_quest_template.sql new file mode 100644 index 000000000..8c650cb06 --- /dev/null +++ b/sql/updates/0.5/1883_quest_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `quest_template` + ADD COLUMN `QuestSort` int(11) unsigned NOT NULL default '0' AFTER `ZoneId`; diff --git a/sql/updates/0.5/1915_loot_template.sql b/sql/updates/0.5/1915_loot_template.sql new file mode 100644 index 000000000..d2893b61c --- /dev/null +++ b/sql/updates/0.5/1915_loot_template.sql @@ -0,0 +1,30 @@ +CREATE TABLE `creature_loot_template` AS SELECT DISTINCT + `loot_template`.`entry` AS `entry`, + `loot_template`.`item` AS `item`, + `loot_template`.`chance` AS `chance`, + `loot_template`.`questchance` AS `questchance` +FROM `loot_template`, `creature_template` WHERE `loot_template`.`entry` = `creature_template`.`lootid`; + +CREATE TABLE `gameobject_loot_template` AS SELECT DISTINCT + `loot_template`.`entry` AS `entry`, + `loot_template`.`item` AS `item`, + `loot_template`.`chance` AS `chance`, + `loot_template`.`questchance` AS `questchance` +FROM `loot_template`, `gameobject` WHERE `loot_template`.`entry` = `gameobject`.`loot`; + +CREATE TABLE `fishing_loot_template` AS SELECT + (`loot_template`.`entry` - 30000) AS `entry`, + `loot_template`.`item` AS `item`, + `loot_template`.`chance` AS `chance`, + `loot_template`.`questchance` AS `questchance` +FROM `loot_template` WHERE `loot_template`.`entry` > 30000 AND `loot_template`.`entry` < 33000; + +CREATE TABLE `pickpocketing_loot_template` ( + `entry` int(11) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0', + `chance` float NOT NULL default '100', + `questchance` float NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +DROP TABLE `loot_template`; diff --git a/sql/updates/0.5/1935_command.sql b/sql/updates/0.5/1935_command.sql new file mode 100644 index 000000000..a766fc34c --- /dev/null +++ b/sql/updates/0.5/1935_command.sql @@ -0,0 +1,2 @@ +INSERT INTO command VALUES('whispers','1','Usage: .whispers on|off\r\nEnable/disable accepting whispers by GM from players. By default use mangosd.conf setting.'); + diff --git a/sql/updates/0.5/1949_corpse.sql b/sql/updates/0.5/1949_corpse.sql new file mode 100644 index 000000000..4e5e37c63 --- /dev/null +++ b/sql/updates/0.5/1949_corpse.sql @@ -0,0 +1,14 @@ +ALTER TABLE `game_corpse` + RENAME TO `corpse`; + +CREATE TABLE `corpse_grid` ( + `guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `position_x` int(11) NOT NULL default '0', + `position_y` int(11) NOT NULL default '0', + `cell_position_x` int(11) NOT NULL default '0', + `cell_position_y` int(11) NOT NULL default '0', + `grid` int(11) unsigned NOT NULL default '0' COMMENT 'Grid Identifier', + `cell` int(11) unsigned NOT NULL default '0' COMMENT 'Cell Identifier', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + UNIQUE KEY `idx_search` (`grid`,`cell`,`map`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Grid System'; \ No newline at end of file diff --git a/sql/updates/0.5/1953_playercreateinfo_skill.sql b/sql/updates/0.5/1953_playercreateinfo_skill.sql new file mode 100644 index 000000000..88a654ad4 --- /dev/null +++ b/sql/updates/0.5/1953_playercreateinfo_skill.sql @@ -0,0 +1,3 @@ +ALTER IGNORE TABLE `playercreateinfo_skill` + ADD PRIMARY KEY (`createid`,`Skill`); + diff --git a/sql/updates/0.5/1953_playercreateinfo_spell.sql b/sql/updates/0.5/1953_playercreateinfo_spell.sql new file mode 100644 index 000000000..a7da2fc1f --- /dev/null +++ b/sql/updates/0.5/1953_playercreateinfo_spell.sql @@ -0,0 +1,3 @@ +ALTER IGNORE TABLE `playercreateinfo_spell` + ADD PRIMARY KEY (`createid`,`Spell`); + diff --git a/sql/updates/0.5/1956_command.sql b/sql/updates/0.5/1956_command.sql new file mode 100644 index 000000000..5320edb54 --- /dev/null +++ b/sql/updates/0.5/1956_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'modify level'; + +UPDATE `command` SET `help` = 'Syntax: .die\r\n\r\nKill the selected player or creature. If no player or creature selected, it will kill you.' WHERE `name` = 'die'; + diff --git a/sql/updates/0.5/2017_quest_template.sql b/sql/updates/0.5/2017_quest_template.sql new file mode 100644 index 000000000..24bf660eb --- /dev/null +++ b/sql/updates/0.5/2017_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` + CHANGE `MaxLevel` `QuestLevel` int(11) unsigned NOT NULL default '0', + CHANGE `RewMoney` `RewOrReqMoney` int(11) NOT NULL default '0'; diff --git a/sql/updates/0.5/2033_command.sql b/sql/updates/0.5/2033_command.sql new file mode 100644 index 000000000..9310abacb --- /dev/null +++ b/sql/updates/0.5/2033_command.sql @@ -0,0 +1,2 @@ +UPDATE command SET `help` = 'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter. If GM want to learn all default spells for Game Masters, use the syntax .learn all Character selection in this case ignored.' WHERE `name` = 'learn'; +UPDATE command SET `help` = 'Syntax: .unlearn #startspell #endspell\r\n\r\nUnlearn for selected player the range of spells between id #startspell and #endspell. If no #endspell is provided, just unlearn spell of id #startspell.' WHERE `name` = 'unlearn'; diff --git a/sql/updates/0.5/2041_auctionhouse_bid.sql b/sql/updates/0.5/2041_auctionhouse_bid.sql new file mode 100644 index 000000000..98a4a67c3 --- /dev/null +++ b/sql/updates/0.5/2041_auctionhouse_bid.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `auctionhouse_bid`; diff --git a/sql/updates/0.5/2041_game_spell.sql b/sql/updates/0.5/2041_game_spell.sql new file mode 100644 index 000000000..a7033cf74 --- /dev/null +++ b/sql/updates/0.5/2041_game_spell.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `game_spell`; diff --git a/sql/updates/0.5/2041_game_talent.sql b/sql/updates/0.5/2041_game_talent.sql new file mode 100644 index 000000000..de619644a --- /dev/null +++ b/sql/updates/0.5/2041_game_talent.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `game_talent`; diff --git a/sql/updates/0.5/2047_quest_template.sql b/sql/updates/0.5/2047_quest_template.sql new file mode 100644 index 000000000..910c4fc53 --- /dev/null +++ b/sql/updates/0.5/2047_quest_template.sql @@ -0,0 +1,5 @@ +UPDATE `quest_template` + SET `SpecialFlags` = `SpecialFlags` | `QuestFlags`; + +ALTER TABLE `quest_template` + DROP `QuestFlags`; diff --git a/sql/updates/0.5/2054_command.sql b/sql/updates/0.5/2054_command.sql new file mode 100644 index 000000000..b99c2822d --- /dev/null +++ b/sql/updates/0.5/2054_command.sql @@ -0,0 +1,2 @@ +UPDATE command SET `help` = 'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter. A GM can use .learn all if he wants to learn all default spells for Game Masters, and .learn all_myclass to learn all spells available for his class (Character selection in these cases ignored).' WHERE `name` = 'learn'; +UPDATE command SET `help` = 'Syntax: .additem #itemid [#itemcount] or .additem 0 #itemcount $itemname\r\n\r\nAdds the specified number of items of id #itemid to your inventory. If #itemcount is omitted, only one item will be added.\r\nWith the second syntax you can add an item with exact (!) name $itemname.' WHERE `name` = 'additem'; \ No newline at end of file diff --git a/sql/updates/0.5/2058_command.sql b/sql/updates/0.5/2058_command.sql new file mode 100644 index 000000000..ff9ec86da --- /dev/null +++ b/sql/updates/0.5/2058_command.sql @@ -0,0 +1,2 @@ +UPDATE command SET `help` = 'Syntax: .additem #itemid [#itemcount] or .additem 0 #itemcount $itemname\r\n\r\nAdds the specified number of items of id #itemid to your or selected character inventory. If #itemcount is omitted, only one item will be added.\r\nWith the second syntax you can add an item with exact (!) name $itemname.' WHERE `name` = 'additem'; +UPDATE command SET `help` = 'Syntax: .additemset #itemsetid\r\n\r\nAdd items from itemset of id #itemsetid to your or selected character inventory. Will add by one example each item from itemset.' WHERE `name` = 'additemset'; \ No newline at end of file diff --git a/sql/updates/0.5/2066_creature_template.sql b/sql/updates/0.5/2066_creature_template.sql new file mode 100644 index 000000000..0dd3ba833 --- /dev/null +++ b/sql/updates/0.5/2066_creature_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template` + ADD `trainer_spell` int(11) unsigned default '0' AFTER `trainer_type`, + ADD `race` int(11) unsigned default '0' AFTER `class`; diff --git a/sql/updates/0.5/2069_quest_template.sql b/sql/updates/0.5/2069_quest_template.sql new file mode 100644 index 000000000..f06edb9b3 --- /dev/null +++ b/sql/updates/0.5/2069_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` + CHANGE `RequiredTradeskill` `RequiredSkill` int(11) unsigned NOT NULL default '0', + ADD COLUMN `RequiredSkillValue` int(11) unsigned NOT NULL default '1' AFTER `RequiredSkill`; diff --git a/sql/updates/0.5/2079_command.sql b/sql/updates/0.5/2079_command.sql new file mode 100644 index 000000000..5b5ad9d4c --- /dev/null +++ b/sql/updates/0.5/2079_command.sql @@ -0,0 +1,2 @@ +INSERT INTO command VALUES('gocreature','2','Usage: .gocreature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.'); +INSERT INTO command VALUES('goobject','1','Usage: .goobject #object_guid\r\nTeleport your character to gameobject with guid #object_guid'); \ No newline at end of file diff --git a/sql/updates/0.5/2099_npc_trainer.sql b/sql/updates/0.5/2099_npc_trainer.sql new file mode 100644 index 000000000..29421cb1f --- /dev/null +++ b/sql/updates/0.5/2099_npc_trainer.sql @@ -0,0 +1,5 @@ +ALTER TABLE `npc_trainer` + CHANGE `reqspell` `reqspell` int(11) unsigned default '0', + CHANGE `reqskill` `reqskill` int(11) unsigned default '0', + CHANGE `reqskillvalue` `reqskillvalue` int(11) unsigned default '0', + ADD COLUMN `reqlevel` int(11) unsigned default '0'; diff --git a/sql/updates/0.5/2107_command.sql b/sql/updates/0.5/2107_command.sql new file mode 100644 index 000000000..32bdf7cd7 --- /dev/null +++ b/sql/updates/0.5/2107_command.sql @@ -0,0 +1 @@ +INSERT INTO command VALUES('targetobject','2','Usage: .targetobject [#go_id|#go_name_part]\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'); diff --git a/sql/updates/0.5/2113_command.sql b/sql/updates/0.5/2113_command.sql new file mode 100644 index 000000000..857cd724b --- /dev/null +++ b/sql/updates/0.5/2113_command.sql @@ -0,0 +1 @@ +INSERT INTO command VALUES('delobject','2','Usage: .delobject #go_guid\r\nDelete gameobject with guid #go_guid.'); diff --git a/sql/updates/0.5/2118_playercreateinfo_spell.sql b/sql/updates/0.5/2118_playercreateinfo_spell.sql new file mode 100644 index 000000000..60e389432 --- /dev/null +++ b/sql/updates/0.5/2118_playercreateinfo_spell.sql @@ -0,0 +1,31 @@ +ALTER TABLE `playercreateinfo_spell` ADD COLUMN `Active` tinyint(3) unsigned NOT NULL default '1'; +INSERT INTO `playercreateinfo_spell` VALUES ('21', '3025', 'Cat Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('21', '3122', 'Tree Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('21', '5419', 'Travel Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('21', '5421', 'Aqua Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('21', '1178', 'Bear Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('21', '9635', 'Dire Bear Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('21', '24905', 'Moonkin Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '3025', 'Cat Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '3122', 'Tree Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '5419', 'Travel Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '5421', 'Aqua Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '1178', 'Bear Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '9635', 'Dire Bear Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('30', '24905', 'Moonkin Form Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('1', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('1', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('7', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('7', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('12', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('12', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('17', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('17', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('22', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('22', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('27', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('27', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('31', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('31', '7381', 'Berserker Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('35', '7376', 'Defensive Stance Passive', '0'); +INSERT INTO `playercreateinfo_spell` VALUES ('35', '7381', 'Berserker Stance Passive', '0'); \ No newline at end of file diff --git a/sql/updates/0.5/2119_command.sql b/sql/updates/0.5/2119_command.sql new file mode 100644 index 000000000..d9c9747ba --- /dev/null +++ b/sql/updates/0.5/2119_command.sql @@ -0,0 +1 @@ +UPDATE command SET `help` = 'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter. A GM can use .learn all if he wants to learn all default spells for Game Masters, .learn all_lang to learn all languages, and .learn all_myclass to learn all spells available for his class (Character selection in these cases ignored).' WHERE `name` = 'learn'; diff --git a/sql/updates/0.5/2130_quest_template.sql b/sql/updates/0.5/2130_quest_template.sql new file mode 100644 index 000000000..46ff557cc --- /dev/null +++ b/sql/updates/0.5/2130_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` + CHANGE `RewRepValue1` `RewRepValue1` int(11) NOT NULL default '0', + CHANGE `RewRepValue2` `RewRepValue2` int(11) NOT NULL default '0'; diff --git a/sql/updates/0.5/2131_command.sql b/sql/updates/0.5/2131_command.sql new file mode 100644 index 000000000..7def5be83 --- /dev/null +++ b/sql/updates/0.5/2131_command.sql @@ -0,0 +1 @@ +UPDATE command SET `help` = 'Syntax: .addmove [#waittime]\r\n\r\nAdd your current location as a waypoint for the selected creature. And optional add wait time.' WHERE `name` = 'addmove'; diff --git a/sql/updates/0.5/2156_character.sql b/sql/updates/0.5/2156_character.sql new file mode 100644 index 000000000..ffb5e76a8 --- /dev/null +++ b/sql/updates/0.5/2156_character.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character` + ADD `totaltime` int(11) unsigned NOT NULL default '0', + ADD `leveltime` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.5/2164_command.sql b/sql/updates/0.5/2164_command.sql new file mode 100644 index 000000000..d04c38e0f --- /dev/null +++ b/sql/updates/0.5/2164_command.sql @@ -0,0 +1 @@ +INSERT INTO command VALUES('searchtele','1','Syntax: .searchtele $substring\r\n\r\nSearch and output all .tele command locations with provide $substring in name.'); diff --git a/sql/updates/0.5/2191_npc_trainer.sql b/sql/updates/0.5/2191_npc_trainer.sql new file mode 100644 index 000000000..6e76442d8 --- /dev/null +++ b/sql/updates/0.5/2191_npc_trainer.sql @@ -0,0 +1,4 @@ +ALTER TABLE `npc_trainer` + DROP PRIMARY KEY, + DROP `rowid`, + ADD UNIQUE KEY `entry_spell` (`entry`,`spell`); diff --git a/sql/updates/0.5/2191_playercreateinfo.sql b/sql/updates/0.5/2191_playercreateinfo.sql new file mode 100644 index 000000000..cee1f2bee --- /dev/null +++ b/sql/updates/0.5/2191_playercreateinfo.sql @@ -0,0 +1,6 @@ +ALTER TABLE `playercreateinfo` + DROP `attackpower`, + DROP `mindmg`, + DROP `maxdmg`, + DROP `ranmindmg`, + DROP `ranmaxdmg`; diff --git a/sql/updates/0.5/2220_command.sql b/sql/updates/0.5/2220_command.sql new file mode 100644 index 000000000..d8c3b0244 --- /dev/null +++ b/sql/updates/0.5/2220_command.sql @@ -0,0 +1 @@ +UPDATE command SET `help` = 'Syntax: .addmove #creature_guid [#waittime]\r\n\r\nAdd your current location as a waypoint for creature with guid #creature_guid. And optional add wait time.' WHERE `name` = 'addmove'; diff --git a/sql/updates/0.6/2297_character_stable.sql b/sql/updates/0.6/2297_character_stable.sql new file mode 100644 index 000000000..5df6b4d94 --- /dev/null +++ b/sql/updates/0.6/2297_character_stable.sql @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS `character_stable`; +CREATE TABLE `character_stable` ( + `owner` int(11) unsigned NOT NULL default '0', + `slot` int(11) unsigned NOT NULL default '0', + `petnumber` int(11) unsigned NOT NULL default '0', + `entry` int(11) unsigned NOT NULL default '0', + `level` int(11) unsigned NOT NULL default '0', + `loyalty` int(11) unsigned NOT NULL default '1', + `trainpoint` int(11) unsigned NOT NULL default '0', + KEY `petnumber` (`petnumber`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_stable` +-- + +/*!40000 ALTER TABLE `character_stable` DISABLE KEYS */; +LOCK TABLES `character_stable` WRITE; +UNLOCK TABLES; +/*!40000 ALTER TABLE character_stable ENABLE KEYS */; \ No newline at end of file diff --git a/sql/updates/0.6/2302_player_levelupgains.sql b/sql/updates/0.6/2302_player_levelupgains.sql new file mode 100644 index 000000000..cc336a6ea --- /dev/null +++ b/sql/updates/0.6/2302_player_levelupgains.sql @@ -0,0 +1,2397 @@ +-- phpMyAdmin SQL Dump +-- version 2.7.0-pl2 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Sep 04, 2006 at 05:27 AM +-- Server version: 5.0.22 +-- PHP Version: 5.2.0-dev +-- +-- Database: `mangos` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `player_levelupgains` +-- + +CREATE TABLE `player_levelupgains` ( + `entry` smallint(5) unsigned NOT NULL auto_increment, + `race` tinyint(3) unsigned NOT NULL, + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `hp` smallint(5) unsigned NOT NULL, + `mana` smallint(5) unsigned NOT NULL, + `str` smallint(5) unsigned NOT NULL, + `agi` smallint(5) unsigned NOT NULL, + `sta` smallint(5) unsigned NOT NULL, + `int` smallint(5) unsigned NOT NULL, + `spi` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores level up stat gains.' AUTO_INCREMENT=2401 ; + +-- +-- Dumping data for table `player_levelupgains` +-- + +INSERT INTO `player_levelupgains` VALUES (2, 3, 3, 1, 17, 6, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (3, 3, 3, 2, 17, 21, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (4, 3, 3, 3, 17, 22, 0, 2, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (5, 3, 3, 4, 17, 23, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (6, 3, 3, 5, 17, 24, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (7, 3, 3, 6, 17, 25, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (8, 3, 3, 7, 17, 26, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (9, 3, 3, 8, 17, 27, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (10, 3, 3, 9, 17, 28, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (11, 3, 3, 10, 17, 29, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (12, 3, 3, 11, 17, 30, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (13, 3, 3, 12, 17, 31, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (14, 3, 3, 13, 18, 32, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (15, 3, 3, 14, 19, 33, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (16, 3, 3, 15, 20, 34, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (17, 3, 3, 16, 21, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (18, 3, 3, 17, 22, 36, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (19, 3, 3, 18, 23, 37, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (20, 3, 3, 19, 24, 38, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (21, 3, 3, 20, 25, 39, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (22, 3, 3, 21, 26, 40, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (23, 3, 3, 22, 27, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (24, 3, 3, 23, 28, 42, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (25, 3, 3, 24, 29, 43, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (26, 3, 3, 25, 30, 44, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (27, 3, 3, 26, 31, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (28, 3, 3, 27, 32, 45, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (29, 3, 3, 28, 33, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (30, 3, 3, 29, 34, 45, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (31, 3, 3, 30, 35, 45, 0, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (32, 3, 3, 31, 36, 45, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (33, 3, 3, 32, 37, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (34, 3, 3, 33, 38, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (35, 3, 3, 34, 39, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (36, 3, 3, 35, 40, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (37, 3, 3, 36, 41, 45, 0, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (38, 3, 3, 37, 42, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (39, 3, 3, 38, 43, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (40, 3, 3, 39, 44, 45, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (41, 3, 3, 40, 45, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (42, 3, 3, 41, 46, 45, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (43, 3, 3, 42, 47, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (44, 3, 3, 43, 48, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (45, 3, 3, 44, 49, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (46, 3, 3, 45, 50, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (47, 3, 3, 46, 51, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (48, 3, 3, 47, 52, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (49, 3, 3, 48, 53, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (50, 3, 3, 49, 54, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (51, 3, 3, 50, 55, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (52, 3, 3, 51, 56, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (53, 3, 3, 52, 57, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (54, 3, 3, 53, 58, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (55, 3, 3, 54, 59, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (56, 3, 3, 55, 60, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (57, 3, 3, 56, 61, 45, 1, 3, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (58, 3, 3, 57, 62, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (59, 3, 3, 58, 63, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (60, 3, 3, 59, 64, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (62, 3, 2, 1, 18, 5, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (63, 3, 2, 2, 18, 20, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (64, 3, 2, 3, 18, 21, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (65, 3, 2, 4, 18, 22, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (66, 3, 2, 5, 18, 23, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (67, 3, 2, 6, 18, 24, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (68, 3, 2, 7, 18, 25, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (69, 3, 2, 8, 18, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (70, 3, 2, 9, 18, 27, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (71, 3, 2, 10, 18, 28, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (72, 3, 2, 11, 18, 29, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (73, 3, 2, 12, 18, 30, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (74, 3, 2, 13, 18, 31, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (75, 3, 2, 14, 19, 32, 1, 1, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (76, 3, 2, 15, 20, 33, 2, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (77, 3, 2, 16, 21, 34, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (78, 3, 2, 17, 22, 35, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (79, 3, 2, 18, 23, 36, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (80, 3, 2, 19, 24, 37, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (81, 3, 2, 20, 25, 38, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (82, 3, 2, 21, 26, 39, 2, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (83, 3, 2, 22, 27, 40, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (84, 3, 2, 23, 28, 41, 1, 1, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (85, 3, 2, 24, 29, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (86, 3, 2, 25, 30, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (87, 3, 2, 26, 31, 42, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (88, 3, 2, 27, 32, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (89, 3, 2, 28, 33, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (90, 3, 2, 29, 34, 42, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (91, 3, 2, 30, 35, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (92, 3, 2, 31, 36, 42, 2, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (93, 3, 2, 32, 37, 42, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (94, 3, 2, 33, 38, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (95, 3, 2, 34, 39, 42, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (96, 3, 2, 35, 40, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (97, 3, 2, 36, 41, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (98, 3, 2, 37, 42, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (99, 3, 2, 38, 43, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (100, 3, 2, 39, 44, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (101, 3, 2, 40, 45, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (102, 3, 2, 41, 46, 42, 2, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (103, 3, 2, 42, 47, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (104, 3, 2, 43, 48, 42, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (105, 3, 2, 44, 49, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (106, 3, 2, 45, 50, 42, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (107, 3, 2, 46, 51, 42, 2, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (108, 3, 2, 47, 52, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (109, 3, 2, 48, 53, 42, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (110, 3, 2, 49, 54, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (111, 3, 2, 50, 55, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (112, 3, 2, 51, 56, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (113, 3, 2, 52, 57, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (114, 3, 2, 53, 58, 42, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (115, 3, 2, 54, 59, 42, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (116, 3, 2, 55, 60, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (117, 3, 2, 56, 61, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (118, 3, 2, 57, 62, 42, 2, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (119, 3, 2, 58, 63, 42, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (120, 3, 2, 59, 64, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (122, 3, 5, 1, 15, 24, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (123, 3, 5, 2, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (124, 3, 5, 3, 15, 26, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (125, 3, 5, 4, 15, 27, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (126, 3, 5, 5, 15, 28, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (127, 3, 5, 6, 15, 29, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (128, 3, 5, 7, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (129, 3, 5, 8, 15, 31, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (130, 3, 5, 9, 15, 47, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (131, 3, 5, 10, 15, 18, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (132, 3, 5, 11, 15, 34, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (133, 3, 5, 12, 15, 35, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (134, 3, 5, 13, 15, 36, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (135, 3, 5, 14, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (136, 3, 5, 15, 15, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (137, 3, 5, 16, 15, 54, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (138, 3, 5, 17, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (139, 3, 5, 18, 15, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (140, 3, 5, 19, 15, 42, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (141, 3, 5, 20, 15, 43, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (142, 3, 5, 21, 16, 59, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (143, 3, 5, 22, 17, 30, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (144, 3, 5, 23, 18, 61, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (145, 3, 5, 24, 19, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (146, 3, 5, 25, 20, 63, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (147, 3, 5, 26, 21, 34, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (148, 3, 5, 27, 22, 65, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (149, 3, 5, 28, 23, 36, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (150, 3, 5, 29, 24, 52, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (151, 3, 5, 30, 25, 68, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (152, 3, 5, 31, 26, 39, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (153, 3, 5, 32, 27, 69, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (154, 3, 5, 33, 28, 54, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (155, 3, 5, 34, 29, 39, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (156, 3, 5, 35, 30, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (157, 3, 5, 36, 31, 69, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (158, 3, 5, 37, 32, 54, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (159, 3, 5, 38, 33, 39, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (160, 3, 5, 39, 34, 54, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (161, 3, 5, 40, 35, 69, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (162, 3, 5, 41, 36, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (163, 3, 5, 42, 37, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (164, 3, 5, 43, 38, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (165, 3, 5, 44, 39, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (166, 3, 5, 45, 40, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (167, 3, 5, 46, 41, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (168, 3, 5, 47, 42, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (169, 3, 5, 48, 43, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (170, 3, 5, 49, 44, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (171, 3, 5, 50, 45, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (172, 3, 5, 51, 46, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (173, 3, 5, 52, 47, 54, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (174, 3, 5, 53, 48, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (175, 3, 5, 54, 49, 54, 0, 1, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (176, 3, 5, 55, 50, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (177, 3, 5, 56, 51, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (178, 3, 5, 57, 52, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (179, 3, 5, 58, 53, 54, 1, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (180, 3, 5, 59, 54, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (182, 3, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (183, 3, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (184, 3, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (185, 3, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (186, 3, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (187, 3, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (188, 3, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (189, 3, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (190, 3, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (191, 3, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (192, 3, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (193, 3, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (194, 3, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (195, 3, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (196, 3, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (197, 3, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (198, 3, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (199, 3, 4, 18, 21, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (200, 3, 4, 19, 22, 0, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (201, 3, 4, 20, 23, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (202, 3, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (203, 3, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (204, 3, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (205, 3, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (206, 3, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (207, 3, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (208, 3, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (209, 3, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (210, 3, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (211, 3, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (212, 3, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (213, 3, 4, 32, 35, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (214, 3, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (215, 3, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (216, 3, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (217, 3, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (218, 3, 4, 37, 40, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (219, 3, 4, 38, 41, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (220, 3, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (221, 3, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (222, 3, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (223, 3, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (224, 3, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (225, 3, 4, 44, 47, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (226, 3, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (227, 3, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (228, 3, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (229, 3, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (230, 3, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (231, 3, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (232, 3, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (233, 3, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (234, 3, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (235, 3, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (236, 3, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (237, 3, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (238, 3, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (239, 3, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (240, 3, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (242, 3, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (243, 3, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (244, 3, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (245, 3, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (246, 3, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (247, 3, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (248, 3, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (249, 3, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (250, 3, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (251, 3, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (252, 3, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (253, 3, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (254, 3, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (255, 3, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (256, 3, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (257, 3, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (258, 3, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (259, 3, 1, 18, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (260, 3, 1, 19, 26, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (261, 3, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (262, 3, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (263, 3, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (264, 3, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (265, 3, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (266, 3, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (267, 3, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (268, 3, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (269, 3, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (270, 3, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (271, 3, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (272, 3, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (273, 3, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (274, 3, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (275, 3, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (276, 3, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (277, 3, 1, 36, 44, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (278, 3, 1, 37, 46, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (279, 3, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (280, 3, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (281, 3, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (282, 3, 1, 41, 54, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (283, 3, 1, 42, 56, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (284, 3, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (285, 3, 1, 44, 60, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (286, 3, 1, 45, 62, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (287, 3, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (288, 3, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (289, 3, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (290, 3, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (291, 3, 1, 50, 72, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (292, 3, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (293, 3, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (294, 3, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (295, 3, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (296, 3, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (297, 3, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (298, 3, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (299, 3, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (300, 3, 1, 59, 90, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (302, 7, 8, 1, 15, 25, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (303, 7, 8, 2, 6, 26, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (304, 7, 8, 3, 15, 27, 0, 1, 0, 3, 1); +INSERT INTO `player_levelupgains` VALUES (305, 7, 8, 4, 15, 58, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (306, 7, 8, 5, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (307, 7, 8, 6, 15, 30, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (308, 7, 8, 7, 15, 16, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (309, 7, 8, 8, 15, 47, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (310, 7, 8, 9, 15, 33, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (311, 7, 8, 10, 15, 34, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (312, 7, 8, 11, 15, 35, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (313, 7, 8, 12, 15, 21, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (314, 7, 8, 13, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (315, 7, 8, 14, 15, 38, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (316, 7, 8, 15, 15, 39, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (317, 7, 8, 16, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (318, 7, 8, 17, 15, 56, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (319, 7, 8, 18, 15, 27, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (320, 7, 8, 19, 15, 88, 0, 1, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (321, 7, 8, 20, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (322, 7, 8, 21, 15, 60, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (323, 7, 8, 22, 15, 31, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (324, 7, 8, 23, 16, 62, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (325, 7, 8, 24, 17, 33, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (326, 7, 8, 25, 18, 64, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (327, 7, 8, 26, 19, 35, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (328, 7, 8, 27, 20, 36, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (329, 7, 8, 28, 21, 66, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (330, 7, 8, 29, 22, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (331, 7, 8, 30, 23, 36, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (332, 7, 8, 31, 24, 66, 0, 0, 1, 3, 1); +INSERT INTO `player_levelupgains` VALUES (333, 7, 8, 32, 25, 81, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (334, 7, 8, 33, 26, 36, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (335, 7, 8, 34, 27, 51, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (336, 7, 8, 35, 28, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (337, 7, 8, 36, 29, 66, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (338, 7, 8, 37, 30, 36, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (339, 7, 8, 38, 31, 51, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (340, 7, 8, 39, 32, 36, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (341, 7, 8, 40, 33, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (342, 7, 8, 41, 34, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (343, 7, 8, 42, 35, 51, 0, 0, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (344, 7, 8, 43, 36, 81, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (345, 7, 8, 44, 37, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (346, 7, 8, 45, 38, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (347, 7, 8, 46, 39, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (348, 7, 8, 47, 40, 51, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (349, 7, 8, 48, 41, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (350, 7, 8, 49, 42, 36, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (351, 7, 8, 50, 43, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (352, 7, 8, 51, 44, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (353, 7, 8, 52, 45, 81, 0, 1, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (354, 7, 8, 53, 46, 51, 1, 0, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (355, 7, 8, 54, 47, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (356, 7, 8, 55, 48, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (357, 7, 8, 56, 49, 36, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (358, 7, 8, 57, 50, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (359, 7, 8, 58, 51, 51, 0, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (360, 7, 8, 59, 52, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (362, 7, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (363, 7, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (364, 7, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (365, 7, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (366, 7, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (367, 7, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (368, 7, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (369, 7, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (370, 7, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (371, 7, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (372, 7, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (373, 7, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (374, 7, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (375, 7, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (376, 7, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (377, 7, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (378, 7, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (379, 7, 4, 18, 21, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (380, 7, 4, 19, 22, 0, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (381, 7, 4, 20, 23, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (382, 7, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (383, 7, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (384, 7, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (385, 7, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (386, 7, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (387, 7, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (388, 7, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (389, 7, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (390, 7, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (391, 7, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (392, 7, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (393, 7, 4, 32, 35, 0, 1, 2, 1, 2, 0); +INSERT INTO `player_levelupgains` VALUES (394, 7, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (395, 7, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (396, 7, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (397, 7, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (398, 7, 4, 37, 40, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (399, 7, 4, 38, 41, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (400, 7, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (401, 7, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (402, 7, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (403, 7, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (404, 7, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (405, 7, 4, 44, 47, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (406, 7, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (407, 7, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (408, 7, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (409, 7, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (410, 7, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (411, 7, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (412, 7, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (413, 7, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (414, 7, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (415, 7, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (416, 7, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (417, 7, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (418, 7, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (419, 7, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (420, 7, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (422, 7, 9, 1, 15, 23, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (423, 7, 9, 2, 15, 24, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (424, 7, 9, 3, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (425, 7, 9, 4, 15, 26, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (426, 7, 9, 5, 15, 27, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (427, 7, 9, 6, 15, 58, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (428, 7, 9, 7, 15, 29, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (429, 7, 9, 8, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (430, 7, 9, 9, 15, 31, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (431, 7, 9, 10, 15, 32, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (432, 7, 9, 11, 15, 33, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (433, 7, 9, 12, 15, 34, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (434, 7, 9, 13, 15, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (435, 7, 9, 14, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (436, 7, 9, 15, 15, 22, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (437, 7, 9, 16, 15, 38, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (438, 7, 9, 17, 16, 39, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (439, 7, 9, 18, 17, 40, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (440, 7, 9, 19, 18, 41, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (441, 7, 9, 20, 19, 42, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (442, 7, 9, 21, 20, 43, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (443, 7, 9, 22, 21, 44, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (444, 7, 9, 23, 22, 75, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (445, 7, 9, 24, 23, 46, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (446, 7, 9, 25, 24, 47, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (447, 7, 9, 26, 25, 48, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (448, 7, 9, 27, 26, 49, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (449, 7, 9, 28, 27, 50, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (450, 7, 9, 29, 28, 51, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (451, 7, 9, 30, 19, 36, 0, 0, 0, 1, 3); +INSERT INTO `player_levelupgains` VALUES (452, 7, 9, 31, 40, 51, 1, 1, 2, 2, 0); +INSERT INTO `player_levelupgains` VALUES (453, 7, 9, 32, 31, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (454, 7, 9, 33, 32, 51, 1, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (455, 7, 9, 34, 33, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (456, 7, 9, 35, 34, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (457, 7, 9, 36, 35, 81, 0, 1, 1, 3, 0); +INSERT INTO `player_levelupgains` VALUES (458, 7, 9, 37, 36, 51, 0, 0, 1, 1, 3); +INSERT INTO `player_levelupgains` VALUES (459, 7, 9, 38, 37, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (460, 7, 9, 39, 38, 51, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (461, 7, 9, 40, 39, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (462, 7, 9, 41, 40, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (463, 7, 9, 42, 41, 51, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (464, 7, 9, 43, 42, 36, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (465, 7, 9, 44, 43, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (466, 7, 9, 45, 44, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (467, 7, 9, 46, 45, 51, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (468, 7, 9, 47, 36, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (469, 7, 9, 48, 47, 81, 1, 1, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (470, 7, 9, 49, 58, 51, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (471, 7, 9, 50, 49, 51, 1, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (472, 7, 9, 51, 30, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (473, 7, 9, 52, 71, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (474, 7, 9, 53, 52, 36, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (475, 7, 9, 54, 43, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (476, 7, 9, 55, 64, 51, 1, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (477, 7, 9, 56, 35, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (478, 7, 9, 57, 76, 51, 1, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (479, 7, 9, 58, 57, 81, 0, 0, 1, 3, 0); +INSERT INTO `player_levelupgains` VALUES (480, 7, 9, 59, 58, 51, 1, 1, 1, 2, 4); +INSERT INTO `player_levelupgains` VALUES (482, 7, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (483, 7, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (484, 7, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (485, 7, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (486, 7, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (487, 7, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (488, 7, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (489, 7, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (490, 7, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (491, 7, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (492, 7, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (493, 7, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (494, 7, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (495, 7, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (496, 7, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (497, 7, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (498, 7, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (499, 7, 1, 18, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (500, 7, 1, 19, 26, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (501, 7, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (502, 7, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (503, 7, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (504, 7, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (505, 7, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (506, 7, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (507, 7, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (508, 7, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (509, 7, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (510, 7, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (511, 7, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (512, 7, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (513, 7, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (514, 7, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (515, 7, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (516, 7, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (517, 7, 1, 36, 79, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (518, 7, 1, 37, 11, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (519, 7, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (520, 7, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (521, 7, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (522, 7, 1, 41, 54, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (523, 7, 1, 42, 56, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (524, 7, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (525, 7, 1, 44, 60, 0, 2, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (526, 7, 1, 45, 62, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (527, 7, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (528, 7, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (529, 7, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (530, 7, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (531, 7, 1, 50, 72, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (532, 7, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (533, 7, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (534, 7, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (535, 7, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (536, 7, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (537, 7, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (538, 7, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (539, 7, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (540, 7, 1, 59, 90, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (542, 1, 8, 1, 15, 25, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (543, 1, 8, 2, 15, 26, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (544, 1, 8, 3, 15, 27, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (545, 1, 8, 4, 15, 28, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (546, 1, 8, 5, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (547, 1, 8, 6, 15, 30, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (548, 1, 8, 7, 15, 16, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (549, 1, 8, 8, 15, 47, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (550, 1, 8, 9, 15, 33, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (551, 1, 8, 10, 15, 34, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (552, 1, 8, 11, 15, 35, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (553, 1, 8, 12, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (554, 1, 8, 13, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (555, 1, 8, 14, 15, 38, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (556, 1, 8, 15, 15, 39, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (557, 1, 8, 16, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (558, 1, 8, 17, 15, 56, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (559, 1, 8, 18, 15, 27, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (560, 1, 8, 19, 15, 58, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (561, 1, 8, 20, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (562, 1, 8, 21, 15, 60, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (563, 1, 8, 22, 15, 31, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (564, 1, 8, 23, 16, 62, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (565, 1, 8, 24, 17, 33, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (566, 1, 8, 25, 18, 64, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (567, 1, 8, 26, 19, 50, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (568, 1, 8, 27, 20, 36, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (569, 1, 8, 28, 21, 66, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (570, 1, 8, 29, 22, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (571, 1, 8, 30, 23, 36, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (572, 1, 8, 31, 24, 66, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (573, 1, 8, 32, 25, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (574, 1, 8, 33, 26, 36, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (575, 1, 8, 34, 27, 51, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (576, 1, 8, 35, 28, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (577, 1, 8, 36, 29, 66, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (578, 1, 8, 37, 30, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (579, 1, 8, 38, 31, 51, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (580, 1, 8, 39, 32, 36, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (581, 1, 8, 40, 33, 51, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (582, 1, 8, 41, 34, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (583, 1, 8, 42, 35, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (584, 1, 8, 43, 36, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (585, 1, 8, 44, 37, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (586, 1, 8, 45, 38, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (587, 1, 8, 46, 39, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (588, 1, 8, 47, 40, 66, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (589, 1, 8, 48, 41, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (590, 1, 8, 49, 42, 36, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (591, 1, 8, 50, 43, 51, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (592, 1, 8, 51, 44, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (593, 1, 8, 52, 45, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (594, 1, 8, 53, 46, 51, 1, 0, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (595, 1, 8, 54, 47, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (596, 1, 8, 55, 48, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (597, 1, 8, 56, 49, 51, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (598, 1, 8, 57, 50, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (599, 1, 8, 58, 51, 51, 0, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (600, 1, 8, 59, 52, 51, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (602, 1, 2, 1, 18, 19, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (603, 1, 2, 2, 18, 20, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (604, 1, 2, 3, 18, 21, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (605, 1, 2, 4, 18, 22, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (606, 1, 2, 5, 18, 23, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (607, 1, 2, 6, 18, 24, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (608, 1, 2, 7, 18, 25, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (609, 1, 2, 8, 18, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (610, 1, 2, 9, 18, 27, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (611, 1, 2, 10, 18, 28, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (612, 1, 2, 11, 18, 29, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (613, 1, 2, 12, 18, 30, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (614, 1, 2, 13, 18, 31, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (615, 1, 2, 14, 19, 32, 1, 1, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (616, 1, 2, 15, 20, 33, 2, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (617, 1, 2, 16, 21, 34, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (618, 1, 2, 17, 22, 35, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (619, 1, 2, 18, 23, 36, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (620, 1, 2, 19, 24, 37, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (621, 1, 2, 20, 25, 38, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (622, 1, 2, 21, 26, 39, 2, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (623, 1, 2, 22, 27, 40, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (624, 1, 2, 23, 28, 41, 1, 1, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (625, 1, 2, 24, 29, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (626, 1, 2, 25, 30, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (627, 1, 2, 26, 31, 42, 1, 1, 1, 0, 2); +INSERT INTO `player_levelupgains` VALUES (628, 1, 2, 27, 32, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (629, 1, 2, 28, 33, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (630, 1, 2, 29, 34, 42, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (631, 1, 2, 30, 35, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (632, 1, 2, 31, 36, 42, 2, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (633, 1, 2, 32, 37, 42, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (634, 1, 2, 33, 38, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (635, 1, 2, 34, 39, 42, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (636, 1, 2, 35, 40, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (637, 1, 2, 36, 41, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (638, 1, 2, 37, 42, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (639, 1, 2, 38, 43, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (640, 1, 2, 39, 44, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (641, 1, 2, 40, 45, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (642, 1, 2, 41, 46, 42, 2, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (643, 1, 2, 42, 47, 42, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (644, 1, 2, 43, 48, 42, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (645, 1, 2, 44, 49, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (646, 1, 2, 45, 50, 42, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (647, 1, 2, 46, 51, 42, 2, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (648, 1, 2, 47, 52, 42, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (649, 1, 2, 48, 53, 42, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (650, 1, 2, 49, 54, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (651, 1, 2, 50, 55, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (652, 1, 2, 51, 56, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (653, 1, 2, 52, 57, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (654, 1, 2, 53, 58, 42, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (655, 1, 2, 54, 59, 42, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (656, 1, 2, 55, 60, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (657, 1, 2, 56, 61, 42, 2, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (658, 1, 2, 57, 62, 42, 2, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (659, 1, 2, 58, 63, 42, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (660, 1, 2, 59, 64, 42, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (662, 1, 5, 1, 15, 24, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (663, 1, 5, 2, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (664, 1, 5, 3, 15, 26, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (665, 1, 5, 4, 15, 27, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (666, 1, 5, 5, 15, 28, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (667, 1, 5, 6, 15, 29, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (668, 1, 5, 7, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (669, 1, 5, 8, 15, 31, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (670, 1, 5, 9, 15, 47, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (671, 1, 5, 10, 15, 18, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (672, 1, 5, 11, 15, 34, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (673, 1, 5, 12, 15, 35, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (674, 1, 5, 13, 15, 36, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (675, 1, 5, 14, 15, 37, 1, 0, 0, 1, 3); +INSERT INTO `player_levelupgains` VALUES (676, 1, 5, 15, 15, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (677, 1, 5, 16, 15, 54, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (678, 1, 5, 17, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (679, 1, 5, 18, 15, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (680, 1, 5, 19, 15, 42, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (681, 1, 5, 20, 15, 43, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (682, 1, 5, 21, 16, 59, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (683, 1, 5, 22, 17, 30, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (684, 1, 5, 23, 18, 61, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (685, 1, 5, 24, 19, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (686, 1, 5, 25, 20, 63, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (687, 1, 5, 26, 21, 34, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (688, 1, 5, 27, 22, 65, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (689, 1, 5, 28, 23, 36, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (690, 1, 5, 29, 24, 52, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (691, 1, 5, 30, 25, 68, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (692, 1, 5, 31, 26, 39, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (693, 1, 5, 32, 27, 69, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (694, 1, 5, 33, 28, 54, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (695, 1, 5, 34, 29, 39, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (696, 1, 5, 35, 30, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (697, 1, 5, 36, 31, 69, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (698, 1, 5, 37, 32, 54, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (699, 1, 5, 38, 33, 39, 0, 0, 1, 1, 3); +INSERT INTO `player_levelupgains` VALUES (700, 1, 5, 39, 34, 54, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (701, 1, 5, 40, 35, 69, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (702, 1, 5, 41, 36, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (703, 1, 5, 42, 37, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (704, 1, 5, 43, 38, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (705, 1, 5, 44, 39, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (706, 1, 5, 45, 40, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (707, 1, 5, 46, 41, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (708, 1, 5, 47, 42, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (709, 1, 5, 48, 43, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (710, 1, 5, 49, 44, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (711, 1, 5, 50, 45, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (712, 1, 5, 51, 46, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (713, 1, 5, 52, 47, 54, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (714, 1, 5, 53, 48, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (715, 1, 5, 54, 49, 54, 0, 1, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (716, 1, 5, 55, 50, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (717, 1, 5, 56, 51, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (718, 1, 5, 57, 52, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (719, 1, 5, 58, 53, 54, 1, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (720, 1, 5, 59, 54, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (722, 1, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (723, 1, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (724, 1, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (725, 1, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (726, 1, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (727, 1, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (728, 1, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (729, 1, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (730, 1, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (731, 1, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (732, 1, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (733, 1, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (734, 1, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (735, 1, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (736, 1, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (737, 1, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (738, 1, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (739, 1, 4, 18, 21, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (740, 1, 4, 19, 22, 0, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (741, 1, 4, 20, 23, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (742, 1, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (743, 1, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (744, 1, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (745, 1, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (746, 1, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (747, 1, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (748, 1, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (749, 1, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (750, 1, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (751, 1, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (752, 1, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (753, 1, 4, 32, 35, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (754, 1, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (755, 1, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (756, 1, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (757, 1, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (758, 1, 4, 37, 40, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (759, 1, 4, 38, 41, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (760, 1, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (761, 1, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (762, 1, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (763, 1, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (764, 1, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (765, 1, 4, 44, 47, 0, 2, 2, 1, 0, 2); +INSERT INTO `player_levelupgains` VALUES (766, 1, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (767, 1, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (768, 1, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (769, 1, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (770, 1, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (771, 1, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (772, 1, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (773, 1, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (774, 1, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (775, 1, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (776, 1, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (777, 1, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (778, 1, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (779, 1, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (780, 1, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (782, 1, 9, 1, 15, 23, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (783, 1, 9, 2, 15, 24, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (784, 1, 9, 3, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (785, 1, 9, 4, 15, 26, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (786, 1, 9, 5, 15, 27, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (787, 1, 9, 6, 15, 28, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (788, 1, 9, 7, 15, 29, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (789, 1, 9, 8, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (790, 1, 9, 9, 15, 31, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (791, 1, 9, 10, 15, 32, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (792, 1, 9, 11, 15, 33, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (793, 1, 9, 12, 15, 34, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (794, 1, 9, 13, 15, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (795, 1, 9, 14, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (796, 1, 9, 15, 15, 37, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (797, 1, 9, 16, 15, 38, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (798, 1, 9, 17, 16, 39, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (799, 1, 9, 18, 17, 40, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (800, 1, 9, 19, 18, 41, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (801, 1, 9, 20, 19, 42, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (802, 1, 9, 21, 20, 43, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (803, 1, 9, 22, 21, 44, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (804, 1, 9, 23, 22, 45, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (805, 1, 9, 24, 23, 46, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (806, 1, 9, 25, 24, 47, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (807, 1, 9, 26, 25, 48, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (808, 1, 9, 27, 26, 49, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (809, 1, 9, 28, 27, 50, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (810, 1, 9, 29, 28, 51, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (811, 1, 9, 30, 29, 51, 0, 0, 1, 1, 3); +INSERT INTO `player_levelupgains` VALUES (812, 1, 9, 31, 30, 51, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (813, 1, 9, 32, 31, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (814, 1, 9, 33, 32, 51, 1, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (815, 1, 9, 34, 33, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (816, 1, 9, 35, 34, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (817, 1, 9, 36, 35, 51, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (818, 1, 9, 37, 36, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (819, 1, 9, 38, 37, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (820, 1, 9, 39, 38, 51, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (821, 1, 9, 40, 39, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (822, 1, 9, 41, 40, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (823, 1, 9, 42, 31, 51, 1, 1, 0, 1, 4); +INSERT INTO `player_levelupgains` VALUES (824, 1, 9, 43, 52, 51, 0, 0, 2, 2, 0); +INSERT INTO `player_levelupgains` VALUES (825, 1, 9, 44, 43, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (826, 1, 9, 45, 34, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (827, 1, 9, 46, 55, 51, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (828, 1, 9, 47, 46, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (829, 1, 9, 48, 47, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (830, 1, 9, 49, 48, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (831, 1, 9, 50, 49, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (832, 1, 9, 51, 50, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (833, 1, 9, 52, 41, 51, 1, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (834, 1, 9, 53, 52, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (835, 1, 9, 54, 63, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (836, 1, 9, 55, 54, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (837, 1, 9, 56, 55, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (838, 1, 9, 57, 56, 51, 1, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (839, 1, 9, 58, 57, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (840, 1, 9, 59, 58, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (842, 1, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (843, 1, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (844, 1, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (845, 1, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (846, 1, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (847, 1, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (848, 1, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (849, 1, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (850, 1, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (851, 1, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (852, 1, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (853, 1, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (854, 1, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (855, 1, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (856, 1, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (857, 1, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (858, 1, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (859, 1, 1, 18, 0, 0, 0, 0, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (860, 1, 1, 19, 51, 0, 3, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (861, 1, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (862, 1, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (863, 1, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (864, 1, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (865, 1, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (866, 1, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (867, 1, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (868, 1, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (869, 1, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (870, 1, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (871, 1, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (872, 1, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (873, 1, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (874, 1, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (875, 1, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (876, 1, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (877, 1, 1, 36, 44, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (878, 1, 1, 37, 46, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (879, 1, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (880, 1, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (881, 1, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (882, 1, 1, 41, 54, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (883, 1, 1, 42, 56, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (884, 1, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (885, 1, 1, 44, 60, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (886, 1, 1, 45, 62, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (887, 1, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (888, 1, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (889, 1, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (890, 1, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (891, 1, 1, 50, 72, 0, 2, 2, 2, 0, 2); +INSERT INTO `player_levelupgains` VALUES (892, 1, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (893, 1, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (894, 1, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (895, 1, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (896, 1, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (897, 1, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (898, 1, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (899, 1, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (900, 1, 1, 59, 90, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (902, 4, 11, 1, 8, 22, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (903, 4, 11, 2, 17, 23, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (904, 4, 11, 3, 17, 24, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (905, 4, 11, 4, 17, 25, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (906, 4, 11, 5, 17, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (907, 4, 11, 6, 17, 27, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (908, 4, 11, 7, 17, 13, 1, 0, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (909, 4, 11, 8, 17, 29, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (910, 4, 11, 9, 17, 30, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (911, 4, 11, 10, 17, 31, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (912, 4, 11, 11, 17, 32, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (913, 4, 11, 12, 17, 33, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (914, 4, 11, 13, 17, 34, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (915, 4, 11, 14, 17, 50, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (916, 4, 11, 15, 17, 36, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (917, 4, 11, 16, 17, 37, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (918, 4, 11, 17, 18, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (919, 4, 11, 18, 19, 39, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (920, 4, 11, 19, 20, 40, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (921, 4, 11, 20, 21, 41, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (922, 4, 11, 21, 22, 27, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (923, 4, 11, 22, 23, 43, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (924, 4, 11, 23, 24, 59, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (925, 4, 11, 24, 25, 45, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (926, 4, 11, 25, 26, 45, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (927, 4, 11, 26, 27, 30, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (928, 4, 11, 27, 28, 45, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (929, 4, 11, 28, 29, 60, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (930, 4, 11, 29, 30, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (931, 4, 11, 30, 31, 30, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (932, 4, 11, 31, 32, 60, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (933, 4, 11, 32, 33, 45, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (934, 4, 11, 33, 34, 30, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (935, 4, 11, 34, 35, 60, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (936, 4, 11, 35, 36, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (937, 4, 11, 36, 37, 45, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (938, 4, 11, 37, 38, 60, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (939, 4, 11, 38, 39, 30, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (940, 4, 11, 39, 40, 60, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (941, 4, 11, 40, 41, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (942, 4, 11, 41, 42, 60, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (943, 4, 11, 42, 43, 30, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (944, 4, 11, 43, 44, 60, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (945, 4, 11, 44, 45, 30, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (946, 4, 11, 45, 46, 60, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (947, 4, 11, 46, 47, 30, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (948, 4, 11, 47, 48, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (949, 4, 11, 48, 49, 60, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (950, 4, 11, 49, 50, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (951, 4, 11, 50, 51, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (952, 4, 11, 51, 52, 60, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (953, 4, 11, 52, 53, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (954, 4, 11, 53, 54, 45, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (955, 4, 11, 54, 55, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (956, 4, 11, 55, 56, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (957, 4, 11, 56, 57, 45, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (958, 4, 11, 57, 58, 45, 1, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (959, 4, 11, 58, 59, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (960, 4, 11, 59, 60, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (962, 4, 3, 1, 17, 20, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (963, 4, 3, 2, 17, 21, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (964, 4, 3, 3, 17, 22, 0, 2, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (965, 4, 3, 4, 17, 23, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (966, 4, 3, 5, 17, 24, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (967, 4, 3, 6, 17, 25, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (968, 4, 3, 7, 17, 26, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (969, 4, 3, 8, 17, 27, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (970, 4, 3, 9, 17, 28, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (971, 4, 3, 10, 17, 29, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (972, 4, 3, 11, 17, 30, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (973, 4, 3, 12, 17, 31, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (974, 4, 3, 13, 18, 32, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (975, 4, 3, 14, 19, 33, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (976, 4, 3, 15, 20, 34, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (977, 4, 3, 16, 21, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (978, 4, 3, 17, 22, 36, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (979, 4, 3, 18, 23, 37, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (980, 4, 3, 19, 24, 38, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (981, 4, 3, 20, 25, 39, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (982, 4, 3, 21, 26, 40, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (983, 4, 3, 22, 27, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (984, 4, 3, 23, 28, 42, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (985, 4, 3, 24, 29, 43, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (986, 4, 3, 25, 30, 44, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (987, 4, 3, 26, 31, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (988, 4, 3, 27, 32, 45, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (989, 4, 3, 28, 33, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (990, 4, 3, 29, 34, 45, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (991, 4, 3, 30, 35, 45, 0, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (992, 4, 3, 31, 36, 45, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (993, 4, 3, 32, 37, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (994, 4, 3, 33, 38, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (995, 4, 3, 34, 39, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (996, 4, 3, 35, 40, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (997, 4, 3, 36, 41, 45, 0, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (998, 4, 3, 37, 42, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (999, 4, 3, 38, 43, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1000, 4, 3, 39, 44, 45, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1001, 4, 3, 40, 45, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1002, 4, 3, 41, 46, 45, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1003, 4, 3, 42, 47, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1004, 4, 3, 43, 48, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1005, 4, 3, 44, 49, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1006, 4, 3, 45, 50, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1007, 4, 3, 46, 51, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1008, 4, 3, 47, 52, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1009, 4, 3, 48, 53, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1010, 4, 3, 49, 54, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1011, 4, 3, 50, 55, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1012, 4, 3, 51, 56, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1013, 4, 3, 52, 57, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1014, 4, 3, 53, 58, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1015, 4, 3, 54, 59, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1016, 4, 3, 55, 60, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1017, 4, 3, 56, 61, 45, 1, 3, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1018, 4, 3, 57, 62, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1019, 4, 3, 58, 63, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1020, 4, 3, 59, 64, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1022, 4, 5, 1, 15, 24, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1023, 4, 5, 2, 6, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1024, 4, 5, 3, 15, 26, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1025, 4, 5, 4, 15, 27, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1026, 4, 5, 5, 15, 28, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1027, 4, 5, 6, 15, 29, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1028, 4, 5, 7, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1029, 4, 5, 8, 15, 31, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1030, 4, 5, 9, 15, 47, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1031, 4, 5, 10, 15, 18, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1032, 4, 5, 11, 15, 34, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1033, 4, 5, 12, 15, 35, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1034, 4, 5, 13, 15, 36, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1035, 4, 5, 14, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1036, 4, 5, 15, 15, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1037, 4, 5, 16, 15, 54, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1038, 4, 5, 17, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1039, 4, 5, 18, 15, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1040, 4, 5, 19, 15, 42, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1041, 4, 5, 20, 15, 43, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1042, 4, 5, 21, 16, 59, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1043, 4, 5, 22, 17, 30, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1044, 4, 5, 23, 18, 61, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1045, 4, 5, 24, 19, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1046, 4, 5, 25, 20, 63, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1047, 4, 5, 26, 21, 34, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1048, 4, 5, 27, 22, 65, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1049, 4, 5, 28, 23, 36, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1050, 4, 5, 29, 24, 52, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1051, 4, 5, 30, 25, 68, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1052, 4, 5, 31, 26, 39, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1053, 4, 5, 32, 27, 69, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1054, 4, 5, 33, 28, 54, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1055, 4, 5, 34, 29, 39, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1056, 4, 5, 35, 30, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1057, 4, 5, 36, 31, 69, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1058, 4, 5, 37, 32, 54, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1059, 4, 5, 38, 33, 39, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1060, 4, 5, 39, 34, 54, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1061, 4, 5, 40, 35, 69, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1062, 4, 5, 41, 36, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1063, 4, 5, 42, 37, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1064, 4, 5, 43, 38, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1065, 4, 5, 44, 39, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1066, 4, 5, 45, 40, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1067, 4, 5, 46, 41, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1068, 4, 5, 47, 42, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1069, 4, 5, 48, 43, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1070, 4, 5, 49, 44, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1071, 4, 5, 50, 45, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1072, 4, 5, 51, 46, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1073, 4, 5, 52, 47, 54, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1074, 4, 5, 53, 48, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1075, 4, 5, 54, 49, 54, 0, 1, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (1076, 4, 5, 55, 50, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1077, 4, 5, 56, 51, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1078, 4, 5, 57, 52, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1079, 4, 5, 58, 53, 54, 1, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (1080, 4, 5, 59, 54, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1082, 4, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1083, 4, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1084, 4, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1085, 4, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1086, 4, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1087, 4, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1088, 4, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1089, 4, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1090, 4, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1091, 4, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1092, 4, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1093, 4, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1094, 4, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1095, 4, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1096, 4, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1097, 4, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1098, 4, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1099, 4, 4, 18, 21, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1100, 4, 4, 19, 22, 0, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1101, 4, 4, 20, 23, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1102, 4, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1103, 4, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1104, 4, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1105, 4, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1106, 4, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1107, 4, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1108, 4, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1109, 4, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1110, 4, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1111, 4, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1112, 4, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1113, 4, 4, 32, 35, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1114, 4, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1115, 4, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1116, 4, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1117, 4, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1118, 4, 4, 37, 40, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1119, 4, 4, 38, 41, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1120, 4, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1121, 4, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1122, 4, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1123, 4, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1124, 4, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1125, 4, 4, 44, 47, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1126, 4, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1127, 4, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1128, 4, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1129, 4, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1130, 4, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1131, 4, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1132, 4, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1133, 4, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1134, 4, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1135, 4, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1136, 4, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1137, 4, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1138, 4, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1139, 4, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1140, 4, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1142, 4, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1143, 4, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1144, 4, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1145, 4, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1146, 4, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1147, 4, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1148, 4, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1149, 4, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1150, 4, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1151, 4, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1152, 4, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1153, 4, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1154, 4, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1155, 4, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1156, 4, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1157, 4, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1158, 4, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1159, 4, 1, 18, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1160, 4, 1, 19, 26, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1161, 4, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1162, 4, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1163, 4, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1164, 4, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1165, 4, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1166, 4, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1167, 4, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1168, 4, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1169, 4, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1170, 4, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1171, 4, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1172, 4, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1173, 4, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1174, 4, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1175, 4, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1176, 4, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1177, 4, 1, 36, 44, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1178, 4, 1, 37, 46, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1179, 4, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1180, 4, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1181, 4, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1182, 4, 1, 41, 54, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1183, 4, 1, 42, 56, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1184, 4, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1185, 4, 1, 44, 60, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1186, 4, 1, 45, 62, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1187, 4, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1188, 4, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1189, 4, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1190, 4, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1191, 4, 1, 50, 72, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1192, 4, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1193, 4, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1194, 4, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1195, 4, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1196, 4, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1197, 4, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1198, 4, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1199, 4, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1200, 4, 1, 59, 90, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1202, 2, 3, 1, 17, 6, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1203, 2, 3, 2, 17, 21, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1204, 2, 3, 3, 17, 8, 0, 2, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1205, 2, 3, 4, 17, 23, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1206, 2, 3, 5, 17, 10, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1207, 2, 3, 6, 17, 25, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1208, 2, 3, 7, 17, 26, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1209, 2, 3, 8, 17, 27, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1210, 2, 3, 9, 17, 28, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1211, 2, 3, 10, 17, 29, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1212, 2, 3, 11, 17, 30, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1213, 2, 3, 12, 17, 31, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1214, 2, 3, 13, 18, 32, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1215, 2, 3, 14, 19, 33, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1216, 2, 3, 15, 20, 34, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1217, 2, 3, 16, 21, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1218, 2, 3, 17, 22, 36, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1219, 2, 3, 18, 23, 37, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1220, 2, 3, 19, 24, 38, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1221, 2, 3, 20, 25, 39, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1222, 2, 3, 21, 26, 40, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1223, 2, 3, 22, 27, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1224, 2, 3, 23, 28, 42, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1225, 2, 3, 24, 29, 43, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1226, 2, 3, 25, 30, 44, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1227, 2, 3, 26, 31, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1228, 2, 3, 27, 32, 45, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1229, 2, 3, 28, 33, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1230, 2, 3, 29, 34, 45, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1231, 2, 3, 30, 35, 45, 0, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1232, 2, 3, 31, 36, 45, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1233, 2, 3, 32, 37, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1234, 2, 3, 33, 38, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1235, 2, 3, 34, 39, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1236, 2, 3, 35, 40, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1237, 2, 3, 36, 41, 45, 0, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1238, 2, 3, 37, 42, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1239, 2, 3, 38, 43, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1240, 2, 3, 39, 44, 45, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1241, 2, 3, 40, 45, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1242, 2, 3, 41, 46, 45, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1243, 2, 3, 42, 47, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1244, 2, 3, 43, 48, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1245, 2, 3, 44, 49, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1246, 2, 3, 45, 50, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1247, 2, 3, 46, 51, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1248, 2, 3, 47, 52, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1249, 2, 3, 48, 53, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1250, 2, 3, 49, 54, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1251, 2, 3, 50, 55, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1252, 2, 3, 51, 56, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1253, 2, 3, 52, 57, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1254, 2, 3, 53, 58, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1255, 2, 3, 54, 59, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1256, 2, 3, 55, 60, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1257, 2, 3, 56, 61, 45, 1, 3, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1258, 2, 3, 57, 62, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1259, 2, 3, 58, 63, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1260, 2, 3, 59, 64, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1262, 2, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1263, 2, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1264, 2, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1265, 2, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1266, 2, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1267, 2, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1268, 2, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1269, 2, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1270, 2, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1271, 2, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1272, 2, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1273, 2, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1274, 2, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1275, 2, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1276, 2, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1277, 2, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1278, 2, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1279, 2, 4, 18, 0, 0, 0, 0, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1280, 2, 4, 19, 0, 0, 0, 0, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1281, 2, 4, 20, 66, 0, 2, 5, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1282, 2, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1283, 2, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1284, 2, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1285, 2, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1286, 2, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1287, 2, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1288, 2, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1289, 2, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1290, 2, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1291, 2, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1292, 2, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1293, 2, 4, 32, 35, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1294, 2, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1295, 2, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1296, 2, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1297, 2, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1298, 2, 4, 37, 45, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1299, 2, 4, 38, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1300, 2, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1301, 2, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1302, 2, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1303, 2, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1304, 2, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1305, 2, 4, 44, 47, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1306, 2, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1307, 2, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1308, 2, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1309, 2, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1310, 2, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1311, 2, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1312, 2, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1313, 2, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1314, 2, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1315, 2, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1316, 2, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1317, 2, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1318, 2, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1319, 2, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1320, 2, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1322, 2, 7, 1, 17, 7, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1323, 2, 7, 2, 17, 8, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1324, 2, 7, 3, 17, 23, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1325, 2, 7, 4, 17, 24, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1326, 2, 7, 5, 17, 25, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1327, 2, 7, 6, 17, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1328, 2, 7, 7, 17, 27, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1329, 2, 7, 8, 17, 43, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1330, 2, 7, 9, 17, 14, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1331, 2, 7, 10, 17, 30, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1332, 2, 7, 11, 17, 31, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1333, 2, 7, 12, 17, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1334, 2, 7, 13, 17, 33, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1335, 2, 7, 14, 17, 34, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1336, 2, 7, 15, 17, 35, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1337, 2, 7, 16, 18, 36, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1338, 2, 7, 17, 19, 37, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1339, 2, 7, 18, 20, 38, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1340, 2, 7, 19, 21, 39, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1341, 2, 7, 20, 22, 40, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1342, 2, 7, 21, 23, 76, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1343, 2, 7, 22, 24, 7, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1344, 2, 7, 23, 25, 43, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1345, 2, 7, 24, 26, 44, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1346, 2, 7, 25, 27, 89, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1347, 2, 7, 26, 28, 2, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1348, 2, 7, 27, 29, 47, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1349, 2, 7, 28, 30, 48, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1350, 2, 7, 29, 31, 102, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1351, 2, 7, 30, 32, 11, 2, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1352, 2, 7, 31, 33, 108, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1353, 2, 7, 32, 34, 51, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1354, 2, 7, 33, 35, 36, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1355, 2, 7, 34, 36, 51, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1356, 2, 7, 35, 37, 68, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1357, 2, 7, 36, 38, 51, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1358, 2, 7, 37, 39, 52, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1359, 2, 7, 38, 40, 52, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1360, 2, 7, 39, 41, 50, 2, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1361, 2, 7, 40, 42, 32, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1362, 2, 7, 41, 43, 22, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1363, 2, 7, 42, 44, 13, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1364, 2, 7, 43, 45, 51, 2, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1365, 2, 7, 44, 46, 124, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1366, 2, 7, 45, 47, 67, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1367, 2, 7, 46, 48, 52, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1368, 2, 7, 47, 49, 51, 2, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1369, 2, 7, 48, 50, 51, 1, 0, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1370, 2, 7, 49, 51, 36, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1371, 2, 7, 50, 52, 68, 2, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1372, 2, 7, 51, 53, 51, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1373, 2, 7, 52, 54, 51, 2, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1374, 2, 7, 53, 55, 22, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1375, 2, 7, 54, 56, 30, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1376, 2, 7, 55, 57, 51, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1377, 2, 7, 56, 58, 103, 1, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1378, 2, 7, 57, 59, 52, 2, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1379, 2, 7, 58, 60, 51, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1380, 2, 7, 59, 61, 79, 2, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1382, 2, 9, 1, 15, 9, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1383, 2, 9, 2, 15, 24, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1384, 2, 9, 3, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1385, 2, 9, 4, 15, 26, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1386, 2, 9, 5, 15, 27, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1387, 2, 9, 6, 15, 28, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1388, 2, 9, 7, 15, 29, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1389, 2, 9, 8, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1390, 2, 9, 9, 15, 31, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1391, 2, 9, 10, 15, 32, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1392, 2, 9, 11, 15, 33, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1393, 2, 9, 12, 15, 34, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1394, 2, 9, 13, 15, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1395, 2, 9, 14, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1396, 2, 9, 15, 15, 37, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1397, 2, 9, 16, 15, 38, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1398, 2, 9, 17, 16, 39, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1399, 2, 9, 18, 35, 40, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1400, 2, 9, 19, 12, 41, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1401, 2, 9, 20, 32, 42, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1402, 2, 9, 21, 0, 43, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1403, 2, 9, 22, 16, 44, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1404, 2, 9, 23, 22, 45, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1405, 2, 9, 24, 23, 46, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1406, 2, 9, 25, 24, 47, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1407, 2, 9, 26, 25, 48, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1408, 2, 9, 27, 26, 49, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1409, 2, 9, 28, 27, 50, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1410, 2, 9, 29, 28, 51, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1411, 2, 9, 30, 29, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1412, 2, 9, 31, 30, 51, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1413, 2, 9, 32, 21, 51, 0, 0, 0, 1, 3); +INSERT INTO `player_levelupgains` VALUES (1414, 2, 9, 33, 42, 51, 1, 1, 1, 2, 0); +INSERT INTO `player_levelupgains` VALUES (1415, 2, 9, 34, 33, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1416, 2, 9, 35, 34, 51, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1417, 2, 9, 36, 35, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1418, 2, 9, 37, 36, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1419, 2, 9, 38, 37, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1420, 2, 9, 39, 38, 51, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1421, 2, 9, 40, 39, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1422, 2, 9, 41, 20, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1423, 2, 9, 42, 61, 51, 1, 1, 3, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1424, 2, 9, 43, 42, 51, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1425, 2, 9, 44, 43, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1426, 2, 9, 45, 44, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1427, 2, 9, 46, 45, 51, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1428, 2, 9, 47, 46, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1429, 2, 9, 48, 47, 51, 1, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1430, 2, 9, 49, 48, 51, 0, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1431, 2, 9, 50, 39, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1432, 2, 9, 51, 60, 51, 0, 0, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1433, 2, 9, 52, 51, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1434, 2, 9, 53, 32, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1435, 2, 9, 54, 73, 51, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1436, 2, 9, 55, 54, 51, 1, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1437, 2, 9, 56, 49, 51, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1438, 2, 9, 57, 52, 51, 1, 1, 2, 2, 4); +INSERT INTO `player_levelupgains` VALUES (1439, 2, 9, 58, 57, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1440, 2, 9, 59, 68, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1442, 2, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1443, 2, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1444, 2, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1445, 2, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1446, 2, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1447, 2, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1448, 2, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1449, 2, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1450, 2, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1451, 2, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1452, 2, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1453, 2, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1454, 2, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1455, 2, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1456, 2, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1457, 2, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1458, 2, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1459, 2, 1, 18, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1460, 2, 1, 19, 26, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1461, 2, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1462, 2, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1463, 2, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1464, 2, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1465, 2, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1466, 2, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1467, 2, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1468, 2, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1469, 2, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1470, 2, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1471, 2, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1472, 2, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1473, 2, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1474, 2, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1475, 2, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1476, 2, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1477, 2, 1, 36, 44, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1478, 2, 1, 37, 46, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1479, 2, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1480, 2, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1481, 2, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1482, 2, 1, 41, 54, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1483, 2, 1, 42, 56, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1484, 2, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1485, 2, 1, 44, 60, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1486, 2, 1, 45, 62, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1487, 2, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1488, 2, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1489, 2, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1490, 2, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1491, 2, 1, 50, 72, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1492, 2, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1493, 2, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1494, 2, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1495, 2, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1496, 2, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1497, 2, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1498, 2, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1499, 2, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1500, 2, 1, 59, 90, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1502, 6, 11, 1, 19, 8, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1503, 6, 11, 2, 16, 9, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1504, 6, 11, 3, 19, 10, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1505, 6, 11, 4, 18, 25, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1506, 6, 11, 5, 18, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1507, 6, 11, 6, 17, 27, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1508, 6, 11, 7, 18, 13, 1, 0, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1509, 6, 11, 8, 18, 29, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1510, 6, 11, 9, 18, 30, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1511, 6, 11, 10, 18, 31, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1512, 6, 11, 11, 17, 32, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1513, 6, 11, 12, 18, 33, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1514, 6, 11, 13, 18, 34, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1515, 6, 11, 14, 19, 50, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1516, 6, 11, 15, 18, 36, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1517, 6, 11, 16, 18, 37, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1518, 6, 11, 17, 18, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1519, 6, 11, 18, 19, 39, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1520, 6, 11, 19, 23, 40, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1521, 6, 11, 20, 22, 41, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1522, 6, 11, 21, 23, 27, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1523, 6, 11, 22, 24, 43, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1524, 6, 11, 23, 24, 59, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1525, 6, 11, 24, 26, 45, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1526, 6, 11, 25, 29, 45, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1527, 6, 11, 26, 28, 30, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1528, 6, 11, 27, 29, 45, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1529, 6, 11, 28, 29, 60, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1530, 6, 11, 29, 32, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1531, 6, 11, 30, 32, 30, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1532, 6, 11, 31, 34, 60, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1533, 6, 11, 32, 36, 45, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1534, 6, 11, 33, 34, 30, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1535, 6, 11, 34, 37, 60, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1536, 6, 11, 35, 39, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1537, 6, 11, 36, 38, 45, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1538, 6, 11, 37, 41, 60, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1539, 6, 11, 38, 40, 30, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1540, 6, 11, 39, 42, 60, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1541, 6, 11, 40, 44, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1542, 6, 11, 41, 43, 60, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1543, 6, 11, 42, 46, 30, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1544, 6, 11, 43, 46, 60, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1545, 6, 11, 44, 47, 30, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1546, 6, 11, 45, 49, 60, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1547, 6, 11, 46, 49, 30, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1548, 6, 11, 47, 49, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1549, 6, 11, 48, 53, 60, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1550, 6, 11, 49, 52, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1551, 6, 11, 50, 54, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1552, 6, 11, 51, 55, 60, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1553, 6, 11, 52, 55, 30, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1554, 6, 11, 53, 57, 45, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1555, 6, 11, 54, 57, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1556, 6, 11, 55, 59, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1557, 6, 11, 56, 61, 45, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1558, 6, 11, 57, 60, 45, 1, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1559, 6, 11, 58, 63, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1560, 6, 11, 59, 62, 45, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1562, 6, 3, 1, 17, 6, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1563, 6, 3, 2, 18, 21, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1564, 6, 3, 3, 18, 8, 0, 2, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1565, 6, 3, 4, 18, 23, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1566, 6, 3, 5, 17, 10, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1567, 6, 3, 6, 18, 25, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1568, 6, 3, 7, 18, 12, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1569, 6, 3, 8, 19, 27, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1570, 6, 3, 9, 16, 14, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1571, 6, 3, 10, 18, 29, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1572, 6, 3, 11, 18, 30, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1573, 6, 3, 12, 19, 31, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1574, 6, 3, 13, 18, 32, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1575, 6, 3, 14, 21, 33, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1576, 6, 3, 15, 21, 34, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1577, 6, 3, 16, 21, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1578, 6, 3, 17, 24, 36, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1579, 6, 3, 18, 25, 37, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1580, 6, 3, 19, 24, 38, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1581, 6, 3, 20, 27, 39, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1582, 6, 3, 21, 26, 40, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1583, 6, 3, 22, 29, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1584, 6, 3, 23, 29, 42, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1585, 6, 3, 24, 31, 43, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1586, 6, 3, 25, 32, 44, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1587, 6, 3, 26, 31, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1588, 6, 3, 27, 34, 45, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1589, 6, 3, 28, 35, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1590, 6, 3, 29, 36, 45, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1591, 6, 3, 30, 37, 45, 0, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1592, 6, 3, 31, 37, 45, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1593, 6, 3, 32, 39, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1594, 6, 3, 33, 39, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1595, 6, 3, 34, 42, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1596, 6, 3, 35, 42, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1597, 6, 3, 36, 42, 45, 0, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1598, 6, 3, 37, 46, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1599, 6, 3, 38, 44, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1600, 6, 3, 39, 46, 45, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1601, 6, 3, 40, 49, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1602, 6, 3, 41, 47, 45, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1603, 6, 3, 42, 50, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1604, 6, 3, 43, 50, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1605, 6, 3, 44, 51, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1606, 6, 3, 45, 54, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1607, 6, 3, 46, 52, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1608, 6, 3, 47, 55, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1609, 6, 3, 48, 56, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1610, 6, 3, 49, 56, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1611, 6, 3, 50, 58, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1612, 6, 3, 51, 59, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1613, 6, 3, 52, 60, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1614, 6, 3, 53, 61, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1615, 6, 3, 54, 61, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1616, 6, 3, 55, 63, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1617, 6, 3, 56, 65, 45, 1, 3, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1618, 6, 3, 57, 65, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1619, 6, 3, 58, 66, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1620, 6, 3, 59, 68, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1622, 6, 7, 1, 17, 7, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1623, 6, 7, 2, 19, 8, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1624, 6, 7, 3, 16, 23, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1625, 6, 7, 4, 19, 10, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1626, 6, 7, 5, 18, 11, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1627, 6, 7, 6, 18, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1628, 6, 7, 7, 17, 27, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1629, 6, 7, 8, 18, 43, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1630, 6, 7, 9, 18, 14, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1631, 6, 7, 10, 18, 30, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1632, 6, 7, 11, 18, 31, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1633, 6, 7, 12, 17, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1634, 6, 7, 13, 18, 33, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1635, 6, 7, 14, 18, 34, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1636, 6, 7, 15, 19, 35, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1637, 6, 7, 16, 18, 36, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1638, 6, 7, 17, 21, 37, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1639, 6, 7, 18, 21, 38, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1640, 6, 7, 19, 21, 39, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1641, 6, 7, 20, 24, 40, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1642, 6, 7, 21, 23, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1643, 6, 7, 22, 26, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1644, 6, 7, 23, 27, 81, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1645, 6, 7, 24, 26, 6, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1646, 6, 7, 25, 29, 45, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1647, 6, 7, 26, 29, 46, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1648, 6, 7, 27, 31, 47, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1649, 6, 7, 28, 32, 48, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1650, 6, 7, 29, 31, 49, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1651, 6, 7, 30, 34, 119, 2, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1652, 6, 7, 31, 35, 52, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1653, 6, 7, 32, 36, 49, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1654, 6, 7, 33, 35, 40, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1655, 6, 7, 34, 39, 49, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1656, 6, 7, 35, 39, 0, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1657, 6, 7, 36, 40, 119, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1658, 6, 7, 37, 41, 13, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1659, 6, 7, 38, 42, 38, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1660, 6, 7, 39, 43, 103, 2, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1661, 6, 7, 40, 45, 51, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1662, 6, 7, 41, 44, 37, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1663, 6, 7, 42, 45, 51, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1664, 6, 7, 43, 49, 67, 2, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1665, 6, 7, 44, 48, 36, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1666, 6, 7, 45, 50, 67, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1667, 6, 7, 46, 50, 51, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1668, 6, 7, 47, 51, 36, 2, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1669, 6, 7, 48, 53, 67, 1, 0, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1670, 6, 7, 49, 52, 36, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1671, 6, 7, 50, 55, 67, 2, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1672, 6, 7, 51, 57, 52, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1673, 6, 7, 52, 56, 51, 2, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1674, 6, 7, 53, 58, 23, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1675, 6, 7, 54, 59, 29, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1676, 6, 7, 55, 59, 51, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1677, 6, 7, 56, 60, 103, 1, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1678, 6, 7, 57, 62, 51, 2, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1679, 6, 7, 58, 64, 27, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1680, 6, 7, 59, 65, 25, 2, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1682, 6, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1683, 6, 1, 2, 20, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1684, 6, 1, 3, 21, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1685, 6, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1686, 6, 1, 5, 20, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1687, 6, 1, 6, 21, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1688, 6, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1689, 6, 1, 8, 21, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1690, 6, 1, 9, 20, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1691, 6, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1692, 6, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1693, 6, 1, 12, 20, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1694, 6, 1, 13, 22, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1695, 6, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1696, 6, 1, 15, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1697, 6, 1, 16, 24, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1698, 6, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1699, 6, 1, 18, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1700, 6, 1, 19, 25, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1701, 6, 1, 20, 29, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1702, 6, 1, 21, 30, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1703, 6, 1, 22, 30, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1704, 6, 1, 23, 31, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1705, 6, 1, 24, 34, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1706, 6, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1707, 6, 1, 26, 36, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1708, 6, 1, 27, 35, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1709, 6, 1, 28, 37, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1710, 6, 1, 29, 39, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1711, 6, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1712, 6, 1, 31, 41, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1713, 6, 1, 32, 40, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1714, 6, 1, 33, 42, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1715, 6, 1, 34, 44, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1716, 6, 1, 35, 43, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1717, 6, 1, 36, 46, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1718, 6, 1, 37, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1719, 6, 1, 38, 50, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1720, 6, 1, 39, 51, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1721, 6, 1, 40, 56, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1722, 6, 1, 41, 57, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1723, 6, 1, 42, 59, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1724, 6, 1, 43, 60, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1725, 6, 1, 44, 63, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1726, 6, 1, 45, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1727, 6, 1, 46, 67, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1728, 6, 1, 47, 68, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1729, 6, 1, 48, 72, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1730, 6, 1, 49, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1731, 6, 1, 50, 76, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1732, 6, 1, 51, 76, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1733, 6, 1, 52, 80, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1734, 6, 1, 53, 83, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1735, 6, 1, 54, 84, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1736, 6, 1, 55, 86, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1737, 6, 1, 56, 88, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1738, 6, 1, 57, 91, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1739, 6, 1, 58, 92, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1740, 6, 1, 59, 94, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1742, 8, 3, 1, 17, 6, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1743, 8, 3, 2, 17, 21, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1744, 8, 3, 3, 17, 8, 0, 2, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1745, 8, 3, 4, 17, 23, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1746, 8, 3, 5, 17, 10, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1747, 8, 3, 6, 17, 25, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1748, 8, 3, 7, 17, 12, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1749, 8, 3, 8, 17, 27, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1750, 8, 3, 9, 17, 28, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1751, 8, 3, 10, 17, 29, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1752, 8, 3, 11, 17, 30, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1753, 8, 3, 12, 17, 31, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1754, 8, 3, 13, 18, 32, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1755, 8, 3, 14, 19, 33, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1756, 8, 3, 15, 20, 34, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1757, 8, 3, 16, 21, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1758, 8, 3, 17, 22, 36, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1759, 8, 3, 18, 23, 37, 0, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1760, 8, 3, 19, 24, 38, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1761, 8, 3, 20, 25, 39, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1762, 8, 3, 21, 26, 40, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1763, 8, 3, 22, 27, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1764, 8, 3, 23, 28, 42, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1765, 8, 3, 24, 29, 43, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1766, 8, 3, 25, 30, 44, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1767, 8, 3, 26, 31, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1768, 8, 3, 27, 32, 45, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1769, 8, 3, 28, 33, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1770, 8, 3, 29, 34, 45, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1771, 8, 3, 30, 35, 45, 0, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1772, 8, 3, 31, 36, 45, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1773, 8, 3, 32, 37, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1774, 8, 3, 33, 38, 45, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1775, 8, 3, 34, 39, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1776, 8, 3, 35, 40, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1777, 8, 3, 36, 41, 45, 0, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1778, 8, 3, 37, 42, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1779, 8, 3, 38, 43, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1780, 8, 3, 39, 44, 45, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1781, 8, 3, 40, 45, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1782, 8, 3, 41, 46, 45, 0, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1783, 8, 3, 42, 47, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1784, 8, 3, 43, 48, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1785, 8, 3, 44, 49, 45, 0, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1786, 8, 3, 45, 50, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1787, 8, 3, 46, 51, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1788, 8, 3, 47, 52, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1789, 8, 3, 48, 53, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1790, 8, 3, 49, 54, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1791, 8, 3, 50, 55, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1792, 8, 3, 51, 56, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1793, 8, 3, 52, 57, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1794, 8, 3, 53, 58, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1795, 8, 3, 54, 59, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1796, 8, 3, 55, 60, 45, 1, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1797, 8, 3, 56, 61, 45, 1, 3, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1798, 8, 3, 57, 62, 45, 0, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1799, 8, 3, 58, 63, 45, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1800, 8, 3, 59, 64, 45, 1, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1802, 8, 8, 1, 15, 11, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1803, 8, 8, 2, 15, 26, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1804, 8, 8, 3, 15, 27, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1805, 8, 8, 4, 15, 28, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1806, 8, 8, 5, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1807, 8, 8, 6, 15, 30, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1808, 8, 8, 7, 15, 16, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1809, 8, 8, 8, 15, 47, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1810, 8, 8, 9, 15, 33, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1811, 8, 8, 10, 15, 34, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1812, 8, 8, 11, 15, 35, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1813, 8, 8, 12, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1814, 8, 8, 13, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1815, 8, 8, 14, 15, 38, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1816, 8, 8, 15, 15, 39, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1817, 8, 8, 16, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1818, 8, 8, 17, 15, 56, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1819, 8, 8, 18, 15, 27, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1820, 8, 8, 19, 15, 58, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1821, 8, 8, 20, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1822, 8, 8, 21, 15, 60, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1823, 8, 8, 22, 15, 31, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1824, 8, 8, 23, 16, 62, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1825, 8, 8, 24, 17, 33, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1826, 8, 8, 25, 18, 64, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1827, 8, 8, 26, 19, 50, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1828, 8, 8, 27, 20, 36, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1829, 8, 8, 28, 21, 66, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1830, 8, 8, 29, 22, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1831, 8, 8, 30, 23, 36, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1832, 8, 8, 31, 24, 66, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1833, 8, 8, 32, 25, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1834, 8, 8, 33, 26, 36, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1835, 8, 8, 34, 27, 51, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1836, 8, 8, 35, 28, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1837, 8, 8, 36, 29, 66, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1838, 8, 8, 37, 30, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1839, 8, 8, 38, 31, 51, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1840, 8, 8, 39, 32, 36, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1841, 8, 8, 40, 33, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1842, 8, 8, 41, 34, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1843, 8, 8, 42, 35, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1844, 8, 8, 43, 36, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1845, 8, 8, 44, 37, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1846, 8, 8, 45, 38, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1847, 8, 8, 46, 79, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1848, 8, 8, 47, 10, 66, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (1849, 8, 8, 48, 31, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1850, 8, 8, 49, 42, 36, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1851, 8, 8, 50, 43, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1852, 8, 8, 51, 44, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1853, 8, 8, 52, 45, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1854, 8, 8, 53, 46, 51, 1, 0, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (1855, 8, 8, 54, 47, 66, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1856, 8, 8, 55, 48, 39, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1857, 8, 8, 56, 49, 48, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (1858, 8, 8, 57, 50, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1859, 8, 8, 58, 42, 51, 0, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (1860, 8, 8, 59, 61, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1862, 8, 5, 1, 15, 10, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1863, 8, 5, 2, 15, 11, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1864, 8, 5, 3, 15, 26, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1865, 8, 5, 4, 15, 27, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1866, 8, 5, 5, 15, 28, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1867, 8, 5, 6, 15, 29, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1868, 8, 5, 7, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1869, 8, 5, 8, 15, 31, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1870, 8, 5, 9, 15, 47, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1871, 8, 5, 10, 15, 18, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1872, 8, 5, 11, 15, 34, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1873, 8, 5, 12, 15, 35, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1874, 8, 5, 13, 15, 36, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1875, 8, 5, 14, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1876, 8, 5, 15, 15, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1877, 8, 5, 16, 15, 54, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1878, 8, 5, 17, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1879, 8, 5, 18, 15, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1880, 8, 5, 19, 15, 42, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1881, 8, 5, 20, 15, 43, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1882, 8, 5, 21, 16, 59, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1883, 8, 5, 22, 17, 30, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1884, 8, 5, 23, 18, 61, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1885, 8, 5, 24, 19, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1886, 8, 5, 25, 20, 63, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1887, 8, 5, 26, 21, 34, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1888, 8, 5, 27, 22, 65, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1889, 8, 5, 28, 23, 36, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1890, 8, 5, 29, 24, 52, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1891, 8, 5, 30, 25, 68, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1892, 8, 5, 31, 26, 39, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1893, 8, 5, 32, 27, 69, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1894, 8, 5, 33, 28, 54, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1895, 8, 5, 34, 29, 39, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1896, 8, 5, 35, 30, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1897, 8, 5, 36, 31, 69, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1898, 8, 5, 37, 32, 54, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1899, 8, 5, 38, 33, 39, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1900, 8, 5, 39, 34, 54, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (1901, 8, 5, 40, 35, 69, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1902, 8, 5, 41, 36, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1903, 8, 5, 42, 37, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1904, 8, 5, 43, 38, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1905, 8, 5, 44, 39, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1906, 8, 5, 45, 40, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1907, 8, 5, 46, 41, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1908, 8, 5, 47, 42, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1909, 8, 5, 48, 93, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1910, 8, 5, 49, 14, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1911, 8, 5, 50, 25, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1912, 8, 5, 51, 46, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1913, 8, 5, 52, 47, 54, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1914, 8, 5, 53, 48, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1915, 8, 5, 54, 49, 54, 0, 1, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (1916, 8, 5, 55, 50, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1917, 8, 5, 56, 51, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (1918, 8, 5, 57, 52, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1919, 8, 5, 58, 53, 54, 1, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (1920, 8, 5, 59, 54, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (1922, 8, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1923, 8, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1924, 8, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1925, 8, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1926, 8, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1927, 8, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1928, 8, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1929, 8, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1930, 8, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1931, 8, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1932, 8, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1933, 8, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1934, 8, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1935, 8, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1936, 8, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1937, 8, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1938, 8, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1939, 8, 4, 18, 21, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1940, 8, 4, 19, 22, 0, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1941, 8, 4, 20, 23, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1942, 8, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1943, 8, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1944, 8, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1945, 8, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1946, 8, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1947, 8, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1948, 8, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1949, 8, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1950, 8, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1951, 8, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1952, 8, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1953, 8, 4, 32, 35, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1954, 8, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1955, 8, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1956, 8, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1957, 8, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1958, 8, 4, 37, 40, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1959, 8, 4, 38, 41, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1960, 8, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1961, 8, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1962, 8, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1963, 8, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1964, 8, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1965, 8, 4, 44, 47, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1966, 8, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1967, 8, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1968, 8, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1969, 8, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1970, 8, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1971, 8, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1972, 8, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1973, 8, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1974, 8, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1975, 8, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (1976, 8, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1977, 8, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1978, 8, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1979, 8, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1980, 8, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1982, 8, 7, 1, 17, 7, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1983, 8, 7, 2, 17, 8, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1984, 8, 7, 3, 17, 23, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1985, 8, 7, 4, 17, 10, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1986, 8, 7, 5, 17, 25, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1987, 8, 7, 6, 17, 26, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1988, 8, 7, 7, 17, 27, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (1989, 8, 7, 8, 17, 43, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1990, 8, 7, 9, 17, 14, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (1991, 8, 7, 10, 17, 30, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1992, 8, 7, 11, 17, 31, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1993, 8, 7, 12, 17, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1994, 8, 7, 13, 17, 33, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1995, 8, 7, 14, 17, 34, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (1996, 8, 7, 15, 17, 35, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1997, 8, 7, 16, 18, 36, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1998, 8, 7, 17, 19, 37, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (1999, 8, 7, 18, 20, 66, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2000, 8, 7, 19, 21, 11, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2001, 8, 7, 20, 22, 40, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2002, 8, 7, 21, 23, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2003, 8, 7, 22, 24, 42, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2004, 8, 7, 23, 25, 43, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2005, 8, 7, 24, 26, 44, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2006, 8, 7, 25, 27, 88, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2007, 8, 7, 26, 28, 49, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2008, 8, 7, 27, 29, 49, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2009, 8, 7, 28, 30, 0, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2010, 8, 7, 29, 31, 49, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2011, 8, 7, 30, 32, 120, 2, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2012, 8, 7, 31, 33, 51, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2013, 8, 7, 32, 34, 61, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2014, 8, 7, 33, 35, 27, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2015, 8, 7, 34, 36, 51, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2016, 8, 7, 35, 37, 57, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2017, 8, 7, 36, 38, 61, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2018, 8, 7, 37, 39, 52, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2019, 8, 7, 38, 40, 36, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2020, 8, 7, 39, 41, 38, 2, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2021, 8, 7, 40, 42, 28, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2022, 8, 7, 41, 43, 56, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2023, 8, 7, 42, 44, 33, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2024, 8, 7, 43, 45, 30, 2, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2025, 8, 7, 44, 46, 34, 1, 0, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2026, 8, 7, 45, 47, 64, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2027, 8, 7, 46, 48, 144, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2028, 8, 7, 47, 49, 36, 2, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2029, 8, 7, 48, 50, 53, 1, 0, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2030, 8, 7, 49, 51, 50, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2031, 8, 7, 50, 52, 50, 2, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2032, 8, 7, 51, 53, 27, 1, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2033, 8, 7, 52, 54, 31, 2, 0, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2034, 8, 7, 53, 55, 21, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2035, 8, 7, 54, 56, 30, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2036, 8, 7, 55, 57, 33, 2, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2037, 8, 7, 56, 58, 65, 1, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2038, 8, 7, 57, 59, 48, 2, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2039, 8, 7, 58, 60, 49, 1, 1, 2, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2040, 8, 7, 59, 61, 49, 2, 1, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2042, 8, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2043, 8, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2044, 8, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2045, 8, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2046, 8, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2047, 8, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2048, 8, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2049, 8, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2050, 8, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2051, 8, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2052, 8, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2053, 8, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2054, 8, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2055, 8, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2056, 8, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2057, 8, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2058, 8, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2059, 8, 1, 18, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2060, 8, 1, 19, 26, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2061, 8, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2062, 8, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2063, 8, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2064, 8, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2065, 8, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2066, 8, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2067, 8, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2068, 8, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2069, 8, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2070, 8, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2071, 8, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2072, 8, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2073, 8, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2074, 8, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2075, 8, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2076, 8, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2077, 8, 1, 36, 44, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2078, 8, 1, 37, 46, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2079, 8, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2080, 8, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2081, 8, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2082, 8, 1, 41, 59, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2083, 8, 1, 42, 51, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2084, 8, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2085, 8, 1, 44, 110, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2086, 8, 1, 45, 12, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2087, 8, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2088, 8, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2089, 8, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2090, 8, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2091, 8, 1, 50, 72, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2092, 8, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2093, 8, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2094, 8, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2095, 8, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2096, 8, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2097, 8, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2098, 8, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2099, 8, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2100, 8, 1, 59, 90, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2102, 5, 8, 1, 15, 25, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2103, 5, 8, 2, 15, 26, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2104, 5, 8, 3, 15, 27, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2105, 5, 8, 4, 15, 28, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2106, 5, 8, 5, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2107, 5, 8, 6, 15, 30, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2108, 5, 8, 7, 15, 16, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2109, 5, 8, 8, 15, 47, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2110, 5, 8, 9, 15, 33, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2111, 5, 8, 10, 15, 34, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2112, 5, 8, 11, 15, 35, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2113, 5, 8, 12, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2114, 5, 8, 13, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2115, 5, 8, 14, 15, 38, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2116, 5, 8, 15, 15, 39, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2117, 5, 8, 16, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2118, 5, 8, 17, 15, 56, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2119, 5, 8, 18, 15, 27, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2120, 5, 8, 19, 15, 58, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2121, 5, 8, 20, 15, 29, 1, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2122, 5, 8, 21, 15, 60, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2123, 5, 8, 22, 15, 31, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2124, 5, 8, 23, 16, 62, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2125, 5, 8, 24, 17, 33, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2126, 5, 8, 25, 18, 64, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2127, 5, 8, 26, 19, 50, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2128, 5, 8, 27, 20, 36, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2129, 5, 8, 28, 21, 66, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2130, 5, 8, 29, 22, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2131, 5, 8, 30, 23, 36, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2132, 5, 8, 31, 24, 66, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2133, 5, 8, 32, 25, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2134, 5, 8, 33, 26, 36, 1, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2135, 5, 8, 34, 27, 51, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2136, 5, 8, 35, 28, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2137, 5, 8, 36, 29, 66, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2138, 5, 8, 37, 30, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2139, 5, 8, 38, 31, 51, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2140, 5, 8, 39, 32, 36, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2141, 5, 8, 40, 33, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2142, 5, 8, 41, 34, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2143, 5, 8, 42, 35, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2144, 5, 8, 43, 36, 51, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2145, 5, 8, 44, 37, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2146, 5, 8, 45, 38, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2147, 5, 8, 46, 39, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2148, 5, 8, 47, 40, 66, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (2149, 5, 8, 48, 41, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2150, 5, 8, 49, 42, 36, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2151, 5, 8, 50, 43, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2152, 5, 8, 51, 44, 51, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2153, 5, 8, 52, 45, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2154, 5, 8, 53, 46, 51, 1, 0, 1, 3, 2); +INSERT INTO `player_levelupgains` VALUES (2155, 5, 8, 54, 47, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2156, 5, 8, 55, 48, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2157, 5, 8, 56, 49, 51, 0, 0, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (2158, 5, 8, 57, 50, 51, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2159, 5, 8, 58, 51, 51, 0, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (2160, 5, 8, 59, 52, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2162, 5, 5, 1, 15, 24, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2163, 5, 5, 2, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2164, 5, 5, 3, 15, 26, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2165, 5, 5, 4, 15, 27, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2166, 5, 5, 5, 15, 28, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2167, 5, 5, 6, 15, 29, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2168, 5, 5, 7, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2169, 5, 5, 8, 15, 31, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2170, 5, 5, 9, 15, 47, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2171, 5, 5, 10, 15, 18, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2172, 5, 5, 11, 15, 34, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2173, 5, 5, 12, 15, 35, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2174, 5, 5, 13, 15, 36, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2175, 5, 5, 14, 15, 37, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2176, 5, 5, 15, 15, 38, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2177, 5, 5, 16, 15, 54, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2178, 5, 5, 17, 15, 25, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2179, 5, 5, 18, 15, 41, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2180, 5, 5, 19, 15, 42, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2181, 5, 5, 20, 15, 43, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2182, 5, 5, 21, 16, 59, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2183, 5, 5, 22, 17, 30, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2184, 5, 5, 23, 18, 61, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2185, 5, 5, 24, 19, 32, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2186, 5, 5, 25, 20, 63, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2187, 5, 5, 26, 21, 34, 0, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2188, 5, 5, 27, 22, 65, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2189, 5, 5, 28, 23, 36, 1, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2190, 5, 5, 29, 24, 52, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2191, 5, 5, 30, 25, 68, 0, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2192, 5, 5, 31, 26, 39, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2193, 5, 5, 32, 27, 69, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2194, 5, 5, 33, 28, 54, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2195, 5, 5, 34, 29, 39, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2196, 5, 5, 35, 30, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2197, 5, 5, 36, 31, 69, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2198, 5, 5, 37, 32, 54, 0, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2199, 5, 5, 38, 33, 39, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2200, 5, 5, 39, 34, 54, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2201, 5, 5, 40, 35, 69, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2202, 5, 5, 41, 36, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2203, 5, 5, 42, 37, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2204, 5, 5, 43, 38, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2205, 5, 5, 44, 39, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2206, 5, 5, 45, 40, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2207, 5, 5, 46, 41, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2208, 5, 5, 47, 42, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2209, 5, 5, 48, 43, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2210, 5, 5, 49, 44, 54, 1, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2211, 5, 5, 50, 45, 54, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2212, 5, 5, 51, 46, 54, 0, 0, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2213, 5, 5, 52, 47, 54, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2214, 5, 5, 53, 48, 54, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2215, 5, 5, 54, 49, 54, 0, 1, 0, 3, 2); +INSERT INTO `player_levelupgains` VALUES (2216, 5, 5, 55, 50, 54, 1, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2217, 5, 5, 56, 51, 54, 0, 1, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2218, 5, 5, 57, 52, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2219, 5, 5, 58, 53, 54, 1, 1, 0, 3, 3); +INSERT INTO `player_levelupgains` VALUES (2220, 5, 5, 59, 54, 54, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2222, 5, 4, 1, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2223, 5, 4, 2, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2224, 5, 4, 3, 17, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2225, 5, 4, 4, 17, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2226, 5, 4, 5, 17, 0, 0, 1, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2227, 5, 4, 6, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2228, 5, 4, 7, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2229, 5, 4, 8, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2230, 5, 4, 9, 17, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2231, 5, 4, 10, 17, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2232, 5, 4, 11, 17, 0, 1, 1, 0, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2233, 5, 4, 12, 17, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2234, 5, 4, 13, 17, 0, 0, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2235, 5, 4, 14, 17, 0, 1, 2, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2236, 5, 4, 15, 18, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2237, 5, 4, 16, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2238, 5, 4, 17, 20, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2239, 5, 4, 18, 21, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2240, 5, 4, 19, 22, 0, 0, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2241, 5, 4, 20, 23, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2242, 5, 4, 21, 24, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2243, 5, 4, 22, 25, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2244, 5, 4, 23, 26, 0, 1, 1, 0, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2245, 5, 4, 24, 27, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2246, 5, 4, 25, 28, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2247, 5, 4, 26, 29, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2248, 5, 4, 27, 30, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2249, 5, 4, 28, 31, 0, 0, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2250, 5, 4, 29, 32, 0, 1, 2, 0, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2251, 5, 4, 30, 33, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2252, 5, 4, 31, 34, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2253, 5, 4, 32, 35, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2254, 5, 4, 33, 36, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2255, 5, 4, 34, 37, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2256, 5, 4, 35, 38, 0, 2, 2, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2257, 5, 4, 36, 39, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2258, 5, 4, 37, 40, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2259, 5, 4, 38, 41, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2260, 5, 4, 39, 42, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2261, 5, 4, 40, 43, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2262, 5, 4, 41, 44, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2263, 5, 4, 42, 45, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2264, 5, 4, 43, 46, 0, 1, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2265, 5, 4, 44, 47, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2266, 5, 4, 45, 48, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2267, 5, 4, 46, 49, 0, 1, 2, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2268, 5, 4, 47, 50, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2269, 5, 4, 48, 51, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2270, 5, 4, 49, 52, 0, 2, 3, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2271, 5, 4, 50, 53, 0, 1, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2272, 5, 4, 51, 54, 0, 1, 2, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2273, 5, 4, 52, 55, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2274, 5, 4, 53, 56, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2275, 5, 4, 54, 57, 0, 1, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2276, 5, 4, 55, 58, 0, 1, 3, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2277, 5, 4, 56, 59, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2278, 5, 4, 57, 60, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2279, 5, 4, 58, 61, 0, 2, 2, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2280, 5, 4, 59, 62, 0, 1, 3, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2282, 5, 9, 1, 15, 23, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2283, 5, 9, 2, 15, 24, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2284, 5, 9, 3, 15, 25, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2285, 5, 9, 4, 15, 26, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2286, 5, 9, 5, 15, 27, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2287, 5, 9, 6, 15, 28, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2288, 5, 9, 7, 15, 29, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2289, 5, 9, 8, 15, 30, 0, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2290, 5, 9, 9, 15, 31, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2291, 5, 9, 10, 15, 32, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2292, 5, 9, 11, 15, 33, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2293, 5, 9, 12, 15, 34, 1, 0, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2294, 5, 9, 13, 15, 35, 0, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2295, 5, 9, 14, 15, 36, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2296, 5, 9, 15, 15, 37, 1, 1, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2297, 5, 9, 16, 15, 38, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2298, 5, 9, 17, 16, 39, 0, 0, 0, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2299, 5, 9, 18, 17, 40, 1, 1, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2300, 5, 9, 19, 18, 41, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2301, 5, 9, 20, 19, 42, 0, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2302, 5, 9, 21, 20, 43, 1, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2303, 5, 9, 22, 21, 44, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2304, 5, 9, 23, 22, 45, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2305, 5, 9, 24, 23, 46, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2306, 5, 9, 25, 24, 47, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2307, 5, 9, 26, 25, 48, 1, 0, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2308, 5, 9, 27, 26, 49, 0, 1, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2309, 5, 9, 28, 27, 50, 1, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2310, 5, 9, 29, 28, 51, 0, 1, 0, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2311, 5, 9, 30, 29, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2312, 5, 9, 31, 30, 51, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2313, 5, 9, 32, 31, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2314, 5, 9, 33, 32, 51, 1, 1, 0, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2315, 5, 9, 34, 33, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2316, 5, 9, 35, 24, 51, 1, 1, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2317, 5, 9, 36, 45, 51, 0, 1, 2, 2, 0); +INSERT INTO `player_levelupgains` VALUES (2318, 5, 9, 37, 36, 51, 0, 0, 1, 1, 2); +INSERT INTO `player_levelupgains` VALUES (2319, 5, 9, 38, 37, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2320, 5, 9, 39, 38, 51, 0, 0, 1, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2321, 5, 9, 40, 39, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2322, 5, 9, 41, 30, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2323, 5, 9, 42, 51, 51, 1, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2324, 5, 9, 43, 42, 51, 0, 0, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2325, 5, 9, 44, 43, 51, 1, 1, 0, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2326, 5, 9, 45, 44, 51, 0, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2327, 5, 9, 46, 45, 51, 1, 0, 1, 1, 3); +INSERT INTO `player_levelupgains` VALUES (2328, 5, 9, 47, 46, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2329, 5, 9, 48, 47, 51, 1, 1, 1, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2330, 5, 9, 49, 28, 51, 0, 0, 1, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2331, 5, 9, 50, 59, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2332, 5, 9, 51, 60, 51, 0, 0, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2333, 5, 9, 52, 51, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2334, 5, 9, 53, 42, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2335, 5, 9, 54, 43, 51, 0, 0, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2336, 5, 9, 55, 74, 51, 1, 1, 2, 2, 1); +INSERT INTO `player_levelupgains` VALUES (2337, 5, 9, 56, 55, 51, 0, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2338, 5, 9, 57, 46, 51, 1, 1, 0, 2, 3); +INSERT INTO `player_levelupgains` VALUES (2339, 5, 9, 58, 67, 51, 0, 0, 2, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2340, 5, 9, 59, 58, 51, 1, 1, 1, 2, 2); +INSERT INTO `player_levelupgains` VALUES (2342, 5, 1, 1, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2343, 5, 1, 2, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2344, 5, 1, 3, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2345, 5, 1, 4, 19, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2346, 5, 1, 5, 19, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2347, 5, 1, 6, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2348, 5, 1, 7, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2349, 5, 1, 8, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2350, 5, 1, 9, 19, 0, 1, 0, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2351, 5, 1, 10, 19, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2352, 5, 1, 11, 19, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2353, 5, 1, 12, 19, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2354, 5, 1, 13, 20, 0, 2, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2355, 5, 1, 14, 21, 0, 1, 0, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2356, 5, 1, 15, 22, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2357, 5, 1, 16, 23, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2358, 5, 1, 17, 24, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2359, 5, 1, 18, 25, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2360, 5, 1, 19, 26, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2361, 5, 1, 20, 27, 0, 1, 0, 2, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2362, 5, 1, 21, 28, 0, 1, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2363, 5, 1, 22, 29, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2364, 5, 1, 23, 30, 0, 1, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2365, 5, 1, 24, 31, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2366, 5, 1, 25, 32, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2367, 5, 1, 26, 33, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2368, 5, 1, 27, 34, 0, 1, 1, 1, 1, 0); +INSERT INTO `player_levelupgains` VALUES (2369, 5, 1, 28, 35, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2370, 5, 1, 29, 36, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2371, 5, 1, 30, 37, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2372, 5, 1, 31, 38, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2373, 5, 1, 32, 39, 0, 1, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2374, 5, 1, 33, 40, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2375, 5, 1, 34, 41, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2376, 5, 1, 35, 42, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2377, 5, 1, 36, 44, 0, 1, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2378, 5, 1, 37, 46, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2379, 5, 1, 38, 48, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2380, 5, 1, 39, 50, 0, 2, 1, 1, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2381, 5, 1, 40, 52, 0, 1, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2382, 5, 1, 41, 54, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2383, 5, 1, 42, 56, 0, 2, 1, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2384, 5, 1, 43, 58, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2385, 5, 1, 44, 60, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2386, 5, 1, 45, 62, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2387, 5, 1, 46, 64, 0, 2, 2, 1, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2388, 5, 1, 47, 66, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2389, 5, 1, 48, 68, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2390, 5, 1, 49, 70, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2391, 5, 1, 50, 72, 0, 2, 2, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2392, 5, 1, 51, 74, 0, 2, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2393, 5, 1, 52, 76, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2394, 5, 1, 53, 78, 0, 2, 2, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2395, 5, 1, 54, 80, 0, 3, 1, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2396, 5, 1, 55, 82, 0, 2, 1, 2, 0, 1); +INSERT INTO `player_levelupgains` VALUES (2397, 5, 1, 56, 84, 0, 2, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2398, 5, 1, 57, 86, 0, 2, 1, 2, 1, 1); +INSERT INTO `player_levelupgains` VALUES (2399, 5, 1, 58, 88, 0, 3, 2, 2, 0, 0); +INSERT INTO `player_levelupgains` VALUES (2400, 5, 1, 59, 90, 0, 2, 1, 2, 0, 1); diff --git a/sql/updates/0.6/2308_character_pet.sql b/sql/updates/0.6/2308_character_pet.sql new file mode 100644 index 000000000..ceabb5db1 --- /dev/null +++ b/sql/updates/0.6/2308_character_pet.sql @@ -0,0 +1,4 @@ +ALTER TABLE `character_pet` + DROP `name`, + ADD `loyalty` int(11) unsigned NOT NULL default '1', + ADD `trainpoint` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2330_realmlist.sql b/sql/updates/0.6/2330_realmlist.sql new file mode 100644 index 000000000..093e9ec72 --- /dev/null +++ b/sql/updates/0.6/2330_realmlist.sql @@ -0,0 +1,2 @@ +ALTER TABLE `realmd`.`realmlist` + ADD `port` int(11) NOT NULL default '8085' AFTER `address`; diff --git a/sql/updates/0.6/2343_areatrigger_template.sql b/sql/updates/0.6/2343_areatrigger_template.sql new file mode 100644 index 000000000..7aa606fe4 --- /dev/null +++ b/sql/updates/0.6/2343_areatrigger_template.sql @@ -0,0 +1,14 @@ +ALTER TABLE `character` + ADD `logout_time` int(11) NOT NULL DEFAULT '0', + ADD `is_logout_resting` int(11) NOT NULL DEFAULT '0', + ADD `rest_bonus` FLOAT NOT NULL DEFAULT '0'; + +DROP TABLE IF EXISTS `areatrigger_city`; + +ALTER TABLE `areatrigger_template` + CHANGE `name` `name` text AFTER `id`, + ADD `trigger_map` int(11) unsigned NOT NULL DEFAULT '0' AFTER `name`, + ADD `trigger_postion_x` FLOAT NOT NULL DEFAULT '0' AFTER `trigger_map`, + ADD `trigger_position_y` FLOAT NOT NULL DEFAULT '0' AFTER `trigger_postion_x`, + ADD `trigger_position_z` FLOAT NOT NULL DEFAULT '0' AFTER `trigger_position_y`, + CHANGE `target_map` `target_map` int(11) unsigned NOT NULL DEFAULT '0' AFTER `trigger_position_z`; \ No newline at end of file diff --git a/sql/updates/0.6/2352_quest_template.sql b/sql/updates/0.6/2352_quest_template.sql new file mode 100644 index 000000000..a44b92cc0 --- /dev/null +++ b/sql/updates/0.6/2352_quest_template.sql @@ -0,0 +1,13 @@ +ALTER TABLE `quest_template` + CHANGE `ReqKillMobOrGOId1` `ReqCreatureOrGOId1` int(11) NOT NULL default '0', + CHANGE `ReqKillMobOrGOId2` `ReqCreatureOrGOId2` int(11) NOT NULL default '0', + CHANGE `ReqKillMobOrGOId3` `ReqCreatureOrGOId3` int(11) NOT NULL default '0', + CHANGE `ReqKillMobOrGOId4` `ReqCreatureOrGOId4` int(11) NOT NULL default '0', + CHANGE `ReqKillMobOrGOCount1` `ReqCreatureOrGOCount1` int(11) unsigned NOT NULL default '0', + CHANGE `ReqKillMobOrGOCount2` `ReqCreatureOrGOCount2` int(11) unsigned NOT NULL default '0', + CHANGE `ReqKillMobOrGOCount3` `ReqCreatureOrGOCount3` int(11) unsigned NOT NULL default '0', + CHANGE `ReqKillMobOrGOCount4` `ReqCreatureOrGOCount4` int(11) unsigned NOT NULL default '0', + ADD COLUMN `ReqSpellCast1` int(11) unsigned NOT NULL default '0' AFTER `ReqCreatureOrGOCount4`, + ADD COLUMN `ReqSpellCast2` int(11) unsigned NOT NULL default '0' AFTER `ReqSpellCast1`, + ADD COLUMN `ReqSpellCast3` int(11) unsigned NOT NULL default '0' AFTER `ReqSpellCast2`, + ADD COLUMN `ReqSpellCast4` int(11) unsigned NOT NULL default '0' AFTER `ReqSpellCast3`; diff --git a/sql/updates/0.6/2357_playercreateinfo_action.sql b/sql/updates/0.6/2357_playercreateinfo_action.sql new file mode 100644 index 000000000..5e0f59e73 --- /dev/null +++ b/sql/updates/0.6/2357_playercreateinfo_action.sql @@ -0,0 +1,13 @@ +ALTER TABLE `playercreateinfo_action` + DROP KEY `playercreateinfo_actions_index`, + ADD KEY `playercreateinfo_actions_index` (`createid`,`button`); + +UPDATE `playercreateinfo_action` + SET `type` = `misc`; +UPDATE `playercreateinfo_action` + SET `misc` = '0'; + +UPDATE `character_action` + SET `type` = `misc`; +UPDATE `character_action` + SET `misc` = '0'; diff --git a/sql/updates/0.6/2359_command.sql b/sql/updates/0.6/2359_command.sql new file mode 100644 index 000000000..f6705a385 --- /dev/null +++ b/sql/updates/0.6/2359_command.sql @@ -0,0 +1 @@ +INSERT INTO command VALUES('shutdown','3','Syntax: .shutdown #delay|stop\r\n\r\nShutting down server after #delay seconds or stop shutting down if stop value used.'); diff --git a/sql/updates/0.6/2360_creature_template.sql b/sql/updates/0.6/2360_creature_template.sql new file mode 100644 index 000000000..342f4d7ca --- /dev/null +++ b/sql/updates/0.6/2360_creature_template.sql @@ -0,0 +1,16 @@ +ALTER TABLE `creature_template` + ADD COLUMN `MovementType` int(11) unsigned NOT NULL default '0' AFTER `MoveName`; + +UPDATE `creature_template` + SET `MovementType` = '1' WHERE `MoveName` = 'Random'; +UPDATE `creature_template` + SET `MovementType` = '2' WHERE `MoveName` = 'Waypoint'; + +ALTER TABLE `creature_template` + DROP `MoveName`; + +ALTER TABLE `creature` + ADD COLUMN `MovementType` int(11) unsigned NOT NULL default '0' AFTER `faction`; + +UPDATE `creature`, `creature_template` + SET `creature`.`MovementType` = `creature_template`.`MovementType` WHERE `creature`.`id` = `creature_template`.`entry`; diff --git a/sql/updates/0.6/2362_areatrigger_template.sql b/sql/updates/0.6/2362_areatrigger_template.sql new file mode 100644 index 000000000..e46de1fdd --- /dev/null +++ b/sql/updates/0.6/2362_areatrigger_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `areatrigger_template` + CHANGE `trigger_postion_x` `trigger_position_x` FLOAT NOT NULL DEFAULT '0'; diff --git a/sql/updates/0.6/2367_command.sql b/sql/updates/0.6/2367_command.sql new file mode 100644 index 000000000..dbd325f6f --- /dev/null +++ b/sql/updates/0.6/2367_command.sql @@ -0,0 +1,2 @@ +INSERT INTO command VALUES('goxy','3','Syntax: .goxy #x #y [#mapid]\r\n\r\nTeleport player to point with (#x,#y) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'); +UPDATE command SET `help` = 'Syntax: .taxicheat #flag\r\n\r\nTemporary grant access or remove to all taxi routes for the selected character. If no character is selected, hide or reveal all routes to you.\r\n\r\nUse a #flag of value 1 to add access, use a #flag value of 0 to remove access. Visited taxi nodes sill accessible after removing access.' WHERE `name` = 'taxicheat'; diff --git a/sql/updates/0.6/2369_creature_template.sql b/sql/updates/0.6/2369_creature_template.sql new file mode 100644 index 000000000..eea90e12f --- /dev/null +++ b/sql/updates/0.6/2369_creature_template.sql @@ -0,0 +1,12 @@ +ALTER TABLE `creature_template` + CHANGE `level` `minlevel` int(3) unsigned default '1', + CHANGE `level_max` `maxlevel` int(3) unsigned default '1' AFTER `minlevel`, + ADD COLUMN `minhealth` int(5) unsigned default '0' AFTER `maxlevel`, + CHANGE `maxhealth` `maxhealth` int(5) unsigned default '0' AFTER `minhealth`, + ADD COLUMN `minmana` int(5) unsigned default '0' AFTER `maxhealth`, + CHANGE `maxmana` `maxmana` int(5) unsigned default '0' AFTER `minmana`; + +UPDATE `creature_template` + SET `maxlevel` = `minlevel` WHERE `maxlevel` < `minlevel`; +UPDATE `creature_template` + SET `minhealth` = `maxhealth`, `minmana` = `maxmana`; diff --git a/sql/updates/0.6/2370_character_queststatus.sql b/sql/updates/0.6/2370_character_queststatus.sql new file mode 100644 index 000000000..df10601cc --- /dev/null +++ b/sql/updates/0.6/2370_character_queststatus.sql @@ -0,0 +1,4 @@ +ALTER TABLE `character_queststatus` + CHANGE `rewarded` `rewarded` tinyint(1) unsigned NOT NULL default '0', + CHANGE `explored` `explored` tinyint(1) unsigned NOT NULL default '0', + ADD COLUMN `completed_once` tinyint(1) unsigned NOT NULL default '0' AFTER `explored`; diff --git a/sql/updates/0.6/2372_creature_template.sql b/sql/updates/0.6/2372_creature_template.sql new file mode 100644 index 000000000..38a5dbf42 --- /dev/null +++ b/sql/updates/0.6/2372_creature_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE `creature_template` + CHANGE `maxlevel` `maxlevel` int(3) unsigned default '1' AFTER `minlevel`, + CHANGE `minhealth` `minhealth` int(5) unsigned default '0' AFTER `maxlevel`, + CHANGE `maxhealth` `maxhealth` int(5) unsigned default '0' AFTER `minhealth`, + CHANGE `minmana` `minmana` int(5) unsigned default '0' AFTER `maxhealth`, + CHANGE `maxmana` `maxmana` int(5) unsigned default '0' AFTER `minmana`; diff --git a/sql/updates/0.6/2382_mail_item.sql b/sql/updates/0.6/2382_mail_item.sql new file mode 100644 index 000000000..a67d9b2a7 --- /dev/null +++ b/sql/updates/0.6/2382_mail_item.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `mail_item`; diff --git a/sql/updates/0.6/2383_auctionhouse_item.sql b/sql/updates/0.6/2383_auctionhouse_item.sql new file mode 100644 index 000000000..8b4e52a4e --- /dev/null +++ b/sql/updates/0.6/2383_auctionhouse_item.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `auctionhouse_item`; diff --git a/sql/updates/0.6/2418_quest_template.sql b/sql/updates/0.6/2418_quest_template.sql new file mode 100644 index 000000000..618a920ac --- /dev/null +++ b/sql/updates/0.6/2418_quest_template.sql @@ -0,0 +1,9 @@ +ALTER TABLE `quest_template` + ADD `ReqSourceId1` int(11) unsigned NOT NULL default '0' AFTER `ReqItemCount4` , + ADD `ReqSourceId2` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceId1` , + ADD `ReqSourceId3` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceId2` , + ADD `ReqSourceId4` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceId3` , + ADD `ReqSourceRef1` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceId4` , + ADD `ReqSourceRef2` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceRef1` , + ADD `ReqSourceRef3` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceRef2` , + ADD `ReqSourceRef4` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceRef3` ; diff --git a/sql/updates/0.6/2421_quest_template.sql b/sql/updates/0.6/2421_quest_template.sql new file mode 100644 index 000000000..68966b7fc --- /dev/null +++ b/sql/updates/0.6/2421_quest_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE `quest_template` + ADD `DetailsEmote` int(11) NOT NULL default '0', + ADD `IncompleteEmote` int(11) NOT NULL default '0', + ADD `CompleteEmote` int(11) NOT NULL default '0'; diff --git a/sql/updates/0.6/2424_gameobject_template.sql b/sql/updates/0.6/2424_gameobject_template.sql new file mode 100644 index 000000000..fa117ab1d --- /dev/null +++ b/sql/updates/0.6/2424_gameobject_template.sql @@ -0,0 +1 @@ +ALTER TABLE `gameobject_template` ADD COLUMN `castsSpell` int(11) NOT NULL default '0' AFTER `ScriptName`; \ No newline at end of file diff --git a/sql/updates/0.6/2429_taxi.sql b/sql/updates/0.6/2429_taxi.sql new file mode 100644 index 000000000..055562ef7 --- /dev/null +++ b/sql/updates/0.6/2429_taxi.sql @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS `taxi_node`; +DROP TABLE IF EXISTS `taxi_path`; +DROP TABLE IF EXISTS `taxi_pathnode`; diff --git a/sql/updates/0.6/2445_command.sql b/sql/updates/0.6/2445_command.sql new file mode 100644 index 000000000..799fd2644 --- /dev/null +++ b/sql/updates/0.6/2445_command.sql @@ -0,0 +1 @@ +INSERT INTO command VALUES('pinfo','2','Syntax: .pinfo [$player_name]\r\n\r\nOutput account information for selected player or player find by $player_name.'); diff --git a/sql/updates/0.6/2448_command.sql b/sql/updates/0.6/2448_command.sql new file mode 100644 index 000000000..89e491758 --- /dev/null +++ b/sql/updates/0.6/2448_command.sql @@ -0,0 +1,3 @@ +DELETE FROM command WHERE `name` = 'addgrave'; +UPDATE command SET `help` = 'Syntax: .neargrave [alliance|horde]\r\n\r\nFind nearest graveyard linked to zone (or only nearest from accepts alliance or horde faction ghosts).' WHERE `name` = 'neargrave'; +UPDATE command SET `help` = 'Syntax: .linkgrave #graveyard_id [alliance|horde]\r\n\r\nLink current zone to graveyard for any (or alliance/horde faction ghosts). This let character ghost from zone teleport to graveyard after die if graveyard is nearest from linked to zone and accept ghost of this faction. Add only single graveyard at another map and only if no graveyards linked (or planned linked at same map).' WHERE `name` = 'linkgrave'; diff --git a/sql/updates/0.6/2448_game_graveyard.sql b/sql/updates/0.6/2448_game_graveyard.sql new file mode 100644 index 000000000..3a500c2bf --- /dev/null +++ b/sql/updates/0.6/2448_game_graveyard.sql @@ -0,0 +1,9 @@ +ALTER TABLE `game_graveyard_zone` + ADD COLUMN `faction` int(11) unsigned NOT NULL default '0' AFTER `ghost_zone`; + +UPDATE `game_graveyard_zone`,`game_graveyard` + SET `game_graveyard_zone`.`faction` = `game_graveyard`.`faction` + WHERE `game_graveyard_zone`.`id` = `game_graveyard`.`id`; + + +DROP TABLE IF EXISTS `game_graveyard`; diff --git a/sql/updates/0.6/2454_command.sql b/sql/updates/0.6/2454_command.sql new file mode 100644 index 000000000..e5a7764ed --- /dev/null +++ b/sql/updates/0.6/2454_command.sql @@ -0,0 +1 @@ +INSERT INTO command VALUES('visible','1','Syntax: .visible [0||1]\r\n\r\nOutput current visibility state or make GM visible(1) and invisible(0) for other players.'); diff --git a/sql/updates/0.6/2467_quest_template.sql b/sql/updates/0.6/2467_quest_template.sql new file mode 100644 index 000000000..ecc129eca --- /dev/null +++ b/sql/updates/0.6/2467_quest_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `quest_template` + ADD `ExclusiveGroup` int(11) unsigned NOT NULL default '0' AFTER `NextQuestId`; diff --git a/sql/updates/0.6/2468_command.sql b/sql/updates/0.6/2468_command.sql new file mode 100644 index 000000000..7c19940ad --- /dev/null +++ b/sql/updates/0.6/2468_command.sql @@ -0,0 +1,3 @@ +INSERT INTO command VALUES('moveobject','2','Syntax: .moveobject #goguid [#x #y #z]\r\n\r\nMove gameobject #goguid to character coordinates (or to (#x,#y,#z) coordinates if its provide).'); +INSERT INTO command VALUES('turnobject','2','Syntax: .turnobject #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'); + diff --git a/sql/updates/0.6/2469_skinning_loot_template.sql b/sql/updates/0.6/2469_skinning_loot_template.sql new file mode 100644 index 000000000..9597c7866 --- /dev/null +++ b/sql/updates/0.6/2469_skinning_loot_template.sql @@ -0,0 +1,50 @@ +DROP TABLE IF EXISTS `skinning_loot_template`; +CREATE TABLE `skinning_loot_template` ( + `entry` int(11) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0', + `chance` float NOT NULL default '100', + `questchance` float NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +DROP TABLE IF EXISTS `skinning_loot_template_alternative`; +CREATE TABLE `skinning_loot_template_alternative` ( + `item` int(11) unsigned NOT NULL default '0', + `item2` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +update `creature_template` set `skinloot` = +case `type` + when 2 then 100001 #CREATURE_TYPE_DRAGON + when 1 then #CREATURE_TYPE_BEAST + case `family` + when 7 then 0 #CREATURE_FAMILY_CARRION_BIRD + when 26 then 0 #CREATURE_FAMILY_OWL + when 21 then 100002 #CREATURE_FAMILY_TURTLE + else if (`minlevel` > 48, 100003, + if (`minlevel` > 36, 100004, + if (`minlevel` > 25, 100005, + if (`minlevel` > 15, 100006, + if (`minlevel` > 3, 100007, + 100008 ))))) + end + else 0 +end; + +insert into `skinning_loot_template` values + (100001, 8165,100, 0), + (100002, 8167,100, 0), + (100003, 8170,100, 0), + (100004, 4304,100, 0), + (100005, 4234,100, 0), + (100006, 2319,100, 0), + (100007, 2318,100, 0), + (100008, 2934,100, 0); + +insert into `skinning_loot_template_alternative` values + (8170,8171), + (4304,8169), + (4234,8235), + (2319,4232), + (2318, 783); diff --git a/sql/updates/0.6/2479_loot_template.sql b/sql/updates/0.6/2479_loot_template.sql new file mode 100644 index 000000000..a02e5f6bd --- /dev/null +++ b/sql/updates/0.6/2479_loot_template.sql @@ -0,0 +1,15 @@ +ALTER TABLE `creature_loot_template` + ADD `maxcount` int(11) unsigned NOT NULL default '1'; + +ALTER TABLE `fishing_loot_template` + ADD `maxcount` int(11) unsigned NOT NULL default '1'; + +ALTER TABLE `gameobject_loot_template` + ADD `maxcount` int(11) unsigned NOT NULL default '1'; + +ALTER TABLE `pickpocketing_loot_template` + ADD `maxcount` int(11) unsigned NOT NULL default '1'; + +ALTER TABLE `skinning_loot_template` + ADD `maxcount` int(11) unsigned NOT NULL default '1'; + diff --git a/sql/updates/0.6/2494_command.sql b/sql/updates/0.6/2494_command.sql new file mode 100644 index 000000000..3476cc8ca --- /dev/null +++ b/sql/updates/0.6/2494_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES ('playsound',1,'Syntax: .playsound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...'); diff --git a/sql/updates/0.6/2495_item_loot_template.sql b/sql/updates/0.6/2495_item_loot_template.sql new file mode 100644 index 000000000..2c9af1cd7 --- /dev/null +++ b/sql/updates/0.6/2495_item_loot_template.sql @@ -0,0 +1,8 @@ +CREATE TABLE `item_loot_template` ( + `entry` int(11) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0', + `chance` float NOT NULL default '100', + `questchance` float NOT NULL default '0', + `maxcount` int(11) unsigned NOT NULL default '1', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; diff --git a/sql/updates/0.6/2500_command.sql b/sql/updates/0.6/2500_command.sql new file mode 100644 index 000000000..38b3b8af6 --- /dev/null +++ b/sql/updates/0.6/2500_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('lookupitem',3,'Syntax: .lookupitem $itemname\r\n\r\nLooks up an item by $itemname, and returns all matches with their Item ID\'s.'); diff --git a/sql/updates/0.6/2513_guild_rank.sql b/sql/updates/0.6/2513_guild_rank.sql new file mode 100644 index 000000000..39c0ce748 --- /dev/null +++ b/sql/updates/0.6/2513_guild_rank.sql @@ -0,0 +1,3 @@ +ALTER TABLE `guild_rank` + ADD `rid` int(11) unsigned NOT NULL AFTER `guildid`, + ADD PRIMARY KEY (`guildid`,`rid`); \ No newline at end of file diff --git a/sql/updates/0.6/2516_auctionhouse.sql b/sql/updates/0.6/2516_auctionhouse.sql new file mode 100644 index 000000000..fe9e30a91 --- /dev/null +++ b/sql/updates/0.6/2516_auctionhouse.sql @@ -0,0 +1,5 @@ +DELETE FROM `auctionhouse`; +ALTER TABLE `auctionhouse` + DROP `id`, + ADD `id` bigint(20) unsigned NOT NULL default '0' FIRST, + ADD `location` tinyint(3) unsigned NOT NULL default '3'; diff --git a/sql/updates/0.6/2517_guild_charters.sql b/sql/updates/0.6/2517_guild_charters.sql new file mode 100644 index 000000000..249842569 --- /dev/null +++ b/sql/updates/0.6/2517_guild_charters.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS `guild_charter`; +CREATE TABLE `guild_charter` ( + `ownerguid` int(10) unsigned NOT NULL, + `charterguid` int(10) unsigned default '0', + `guildname` varchar(255) NOT NULL default '', + PRIMARY KEY (`ownerguid`), + UNIQUE KEY `index_ownerguid_charterguid` (`ownerguid`,`charterguid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +DROP TABLE IF EXISTS `guild_charter_sign`; +CREATE TABLE `guild_charter_sign` ( + `ownerguid` int(10) unsigned NOT NULL, + `charterguid` int(11) unsigned default '0', + `playerguid` int(11) unsigned default '0', + PRIMARY KEY (`charterguid`,`playerguid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; diff --git a/sql/updates/0.6/2518_guild.sql b/sql/updates/0.6/2518_guild.sql new file mode 100644 index 000000000..04b84e3eb --- /dev/null +++ b/sql/updates/0.6/2518_guild.sql @@ -0,0 +1,2 @@ +ALTER TABLE `guild` + ADD `info` TEXT NOT NULL AFTER `BackgroundColor` ; diff --git a/sql/updates/0.6/2530_loot_template.sql b/sql/updates/0.6/2530_loot_template.sql new file mode 100644 index 000000000..5e21bcc29 --- /dev/null +++ b/sql/updates/0.6/2530_loot_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE creature_loot_template ADD COLUMN quest_freeforall int(1) unsigned NOT NULL default '1' AFTER `maxcount`; +ALTER TABLE gameobject_loot_template ADD COLUMN quest_freeforall int(1) unsigned NOT NULL default '1' AFTER `maxcount`; +ALTER TABLE fishing_loot_template ADD COLUMN quest_freeforall int(1) unsigned NOT NULL default '1' AFTER `maxcount`; +ALTER TABLE item_loot_template ADD COLUMN quest_freeforall int(1) unsigned NOT NULL default '1' AFTER `maxcount`; +ALTER TABLE pickpocketing_loot_template ADD COLUMN quest_freeforall int(1) unsigned NOT NULL default '1' AFTER `maxcount`; +ALTER TABLE skinning_loot_template ADD COLUMN quest_freeforall int(1) unsigned NOT NULL default '1' AFTER `maxcount`; \ No newline at end of file diff --git a/sql/updates/0.6/2549_character.sql b/sql/updates/0.6/2549_character.sql new file mode 100644 index 000000000..f9acf66e6 --- /dev/null +++ b/sql/updates/0.6/2549_character.sql @@ -0,0 +1 @@ +UPDATE `character` SET `name` = CONCAT(UCASE(SUBSTRING(`name`,1,1)),LCASE(SUBSTRING(`name`,2))); diff --git a/sql/updates/0.6/2571_quest_template.sql b/sql/updates/0.6/2571_quest_template.sql new file mode 100644 index 000000000..afcbec1a0 --- /dev/null +++ b/sql/updates/0.6/2571_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` + CHANGE `srcItem` `SrcItemId` int(11) unsigned NOT NULL default '0', + ADD `SrcSpell` int(11) unsigned NOT NULL default '0' AFTER `SrcItemCount`; diff --git a/sql/updates/0.6/2572_creature_template.sql b/sql/updates/0.6/2572_creature_template.sql new file mode 100644 index 000000000..dee36d658 --- /dev/null +++ b/sql/updates/0.6/2572_creature_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template` + CHANGE `modelid` `modelid_m` int(11) unsigned default '0', + ADD `modelid_f` int(11) unsigned default '0' AFTER `modelid_m`; diff --git a/sql/updates/0.6/2578_character.sql b/sql/updates/0.6/2578_character.sql new file mode 100644 index 000000000..d5501c91e --- /dev/null +++ b/sql/updates/0.6/2578_character.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character` + ADD `resettalents_cost` int(11) unsigned NOT NULL default '0', + ADD `resettalents_time` bigint(20) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2580_character.sql b/sql/updates/0.6/2580_character.sql new file mode 100644 index 000000000..23103a407 --- /dev/null +++ b/sql/updates/0.6/2580_character.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character` + ADD `instanceid` int(11) unsigned NOT NULL default '0' AFTER `map`; diff --git a/sql/updates/0.6/2580_insatne.sql b/sql/updates/0.6/2580_insatne.sql new file mode 100644 index 000000000..966f04a2a --- /dev/null +++ b/sql/updates/0.6/2580_insatne.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS `instance`; +CREATE TABLE `instance` ( + `id` int(11) unsigned NOT NULL default '0' COMMENT 'instance id', + `mapid` int(11) unsigned NOT NULL default '0' COMMENT 'real mapid', + `state` int(11) NOT NULL default '0' COMMENT 'this instance state', + `players` int(11) NOT NULL COMMENT 'map creater guid who in this instance', + `lefttime` int(11) NOT NULL default '0' COMMENT 'this instance left time', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + diff --git a/sql/updates/0.6/2584_character.sql b/sql/updates/0.6/2584_character.sql new file mode 100644 index 000000000..7b534c44e --- /dev/null +++ b/sql/updates/0.6/2584_character.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character` + DROP `instanceid`; diff --git a/sql/updates/0.6/2584_instance.sql b/sql/updates/0.6/2584_instance.sql new file mode 100644 index 000000000..1625876dd --- /dev/null +++ b/sql/updates/0.6/2584_instance.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `instance`; \ No newline at end of file diff --git a/sql/updates/0.6/2597_playercreateinfo_action.sql b/sql/updates/0.6/2597_playercreateinfo_action.sql new file mode 100644 index 000000000..7af5626fd --- /dev/null +++ b/sql/updates/0.6/2597_playercreateinfo_action.sql @@ -0,0 +1,13 @@ +ALTER TABLE `playercreateinfo_action` + ADD `race` tinyint(3) unsigned NOT NULL default '0' FIRST, + ADD `class` tinyint(3) unsigned NOT NULL default '0' AFTER `race`; + +UPDATE `playercreateinfo_action`,`playercreateinfo` + SET `playercreateinfo_action`.`race` = `playercreateinfo`.`race`, + `playercreateinfo_action`.`class` = `playercreateinfo`.`class` + WHERE `playercreateinfo_action`.`createid` = `playercreateinfo`.`createid`; + +ALTER TABLE `playercreateinfo_action` + DROP KEY `playercreateinfo_actions_index`, + DROP `createid`, + ADD KEY `playercreateinfo_race_class_index` (`race`,`class`); diff --git a/sql/updates/0.6/2597_playercreateinfo_item.sql b/sql/updates/0.6/2597_playercreateinfo_item.sql new file mode 100644 index 000000000..9530deb85 --- /dev/null +++ b/sql/updates/0.6/2597_playercreateinfo_item.sql @@ -0,0 +1,16 @@ +ALTER TABLE `playercreateinfo_item` + ADD `race` tinyint(3) unsigned NOT NULL default '0' FIRST, + ADD `class` tinyint(3) unsigned NOT NULL default '0' AFTER `race`; + +UPDATE `playercreateinfo_item`,`playercreateinfo` + SET `playercreateinfo_item`.`race` = `playercreateinfo`.`race`, + `playercreateinfo_item`.`class` = `playercreateinfo`.`class` + WHERE `playercreateinfo_item`.`createid` = `playercreateinfo`.`createid`; + +ALTER TABLE `playercreateinfo_item` + DROP KEY `playercreateinfo_items_index`, + DROP `createid`, + DROP `bagIndex`, + DROP `slot`, + ADD KEY `playercreateinfo_race_class_index` (`race`,`class`); + \ No newline at end of file diff --git a/sql/updates/0.6/2597_playercreateinfo_reputation.sql b/sql/updates/0.6/2597_playercreateinfo_reputation.sql new file mode 100644 index 000000000..0368bb593 --- /dev/null +++ b/sql/updates/0.6/2597_playercreateinfo_reputation.sql @@ -0,0 +1,14 @@ +ALTER TABLE `playercreateinfo_reputation` + ADD `race` tinyint(3) unsigned NOT NULL default '0' FIRST, + ADD `class` tinyint(3) unsigned NOT NULL default '0' AFTER `race`; + +UPDATE `playercreateinfo_reputation`,`playercreateinfo` + SET `playercreateinfo_reputation`.`race` = `playercreateinfo`.`race`, + `playercreateinfo_reputation`.`class` = `playercreateinfo`.`class` + WHERE `playercreateinfo_reputation`.`createid` = `playercreateinfo`.`createid`; + +ALTER TABLE `playercreateinfo_reputation` + DROP KEY `playercreateinfo_reputation_index`, + DROP `createid`, + ADD KEY `playercreateinfo_race_class_index` (`race`,`class`); + \ No newline at end of file diff --git a/sql/updates/0.6/2597_playercreateinfo_skill.sql b/sql/updates/0.6/2597_playercreateinfo_skill.sql new file mode 100644 index 000000000..7d68bc9eb --- /dev/null +++ b/sql/updates/0.6/2597_playercreateinfo_skill.sql @@ -0,0 +1,14 @@ +ALTER TABLE `playercreateinfo_skill` + ADD `race` tinyint(3) unsigned NOT NULL default '0' FIRST, + ADD `class` tinyint(3) unsigned NOT NULL default '0' AFTER `race`; + +UPDATE `playercreateinfo_skill`,`playercreateinfo` + SET `playercreateinfo_skill`.`race` = `playercreateinfo`.`race`, + `playercreateinfo_skill`.`class` = `playercreateinfo`.`class` + WHERE `playercreateinfo_skill`.`createid` = `playercreateinfo`.`createid`; + +ALTER TABLE `playercreateinfo_skill` + DROP PRIMARY KEY, + DROP `createid`, + ADD PRIMARY KEY (`race`,`class`,`Skill`); + \ No newline at end of file diff --git a/sql/updates/0.6/2597_playercreateinfo_spell.sql b/sql/updates/0.6/2597_playercreateinfo_spell.sql new file mode 100644 index 000000000..44e20d49f --- /dev/null +++ b/sql/updates/0.6/2597_playercreateinfo_spell.sql @@ -0,0 +1,14 @@ +ALTER TABLE `playercreateinfo_spell` + ADD `race` tinyint(3) unsigned NOT NULL default '0' FIRST, + ADD `class` tinyint(3) unsigned NOT NULL default '0' AFTER `race`; + +UPDATE `playercreateinfo_spell`,`playercreateinfo` + SET `playercreateinfo_spell`.`race` = `playercreateinfo`.`race`, + `playercreateinfo_spell`.`class` = `playercreateinfo`.`class` + WHERE `playercreateinfo_spell`.`createid` = `playercreateinfo`.`createid`; + +ALTER TABLE `playercreateinfo_spell` + DROP PRIMARY KEY, + DROP `createid`, + ADD PRIMARY KEY (`race`,`class`,`Spell`); + \ No newline at end of file diff --git a/sql/updates/0.6/2598_playercreateinfo.sql b/sql/updates/0.6/2598_playercreateinfo.sql new file mode 100644 index 000000000..fd4d81d03 --- /dev/null +++ b/sql/updates/0.6/2598_playercreateinfo.sql @@ -0,0 +1,6 @@ +ALTER TABLE `playercreateinfo` + DROP KEY `playercreateinfo_index`, + DROP PRIMARY KEY , + DROP `createId` , + ADD PRIMARY KEY `playercreateinfo_race_class_index` (`race`,`class`) ; + \ No newline at end of file diff --git a/sql/updates/0.6/2605_realmd_account.sql b/sql/updates/0.6/2605_realmd_account.sql new file mode 100644 index 000000000..426fc2bb6 --- /dev/null +++ b/sql/updates/0.6/2605_realmd_account.sql @@ -0,0 +1,3 @@ +ALTER TABLE `realmd`.`account` + ADD `v` longtext AFTER `sessionkey`, + ADD `s` longtext AFTER `v`; \ No newline at end of file diff --git a/sql/updates/0.6/2610_character.sql b/sql/updates/0.6/2610_character.sql new file mode 100644 index 000000000..c894767eb --- /dev/null +++ b/sql/updates/0.6/2610_character.sql @@ -0,0 +1 @@ +UPDATE `character` SET `logout_time` = '0', `rest_bonus` = '0'; diff --git a/sql/updates/0.6/2617_character_spell_cooldown.sql b/sql/updates/0.6/2617_character_spell_cooldown.sql new file mode 100644 index 000000000..e41333ac9 --- /dev/null +++ b/sql/updates/0.6/2617_character_spell_cooldown.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS `character_spell_cooldown`; +CREATE TABLE `character_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `time` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + diff --git a/sql/updates/0.6/2622_character.sql b/sql/updates/0.6/2622_character.sql new file mode 100644 index 000000000..a46604807 --- /dev/null +++ b/sql/updates/0.6/2622_character.sql @@ -0,0 +1,5 @@ +ALTER TABLE `character` ADD COLUMN `trans_x` float NOT NULL default '0'; +ALTER TABLE `character` ADD COLUMN `trans_y` float NOT NULL default '0'; +ALTER TABLE `character` ADD COLUMN `trans_z` float NOT NULL default '0'; +ALTER TABLE `character` ADD COLUMN `trans_o` float NOT NULL default '0'; +ALTER TABLE `character` ADD COLUMN `transguid` bigint(20) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2622_gameobject.sql b/sql/updates/0.6/2622_gameobject.sql new file mode 100644 index 000000000..38822afd6 --- /dev/null +++ b/sql/updates/0.6/2622_gameobject.sql @@ -0,0 +1 @@ +ALTER TABLE gameobject ADD COLUMN `animprogress` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2622_transports.sql b/sql/updates/0.6/2622_transports.sql new file mode 100644 index 000000000..471c7e2d9 --- /dev/null +++ b/sql/updates/0.6/2622_transports.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `transports`; +CREATE TABLE `transports` ( + `entry` int(11) unsigned NOT NULL default '0', + `name` text, + `period` int(11) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Transports'; + diff --git a/sql/updates/0.6/2630_command.sql b/sql/updates/0.6/2630_command.sql new file mode 100644 index 000000000..c87fb2720 --- /dev/null +++ b/sql/updates/0.6/2630_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help` = 'Syntax: .revive [$playername]\r\n\r\n Revive specified or selected player. If no player is selected, it will revive you.' WHERE `name` = 'revive'; diff --git a/sql/updates/0.6/2633_character_spell_cooldown.sql b/sql/updates/0.6/2633_character_spell_cooldown.sql new file mode 100644 index 000000000..45a4e9632 --- /dev/null +++ b/sql/updates/0.6/2633_character_spell_cooldown.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_spell_cooldown` + CHANGE `time` `time` bigint(20) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2637_auctionhouse.sql b/sql/updates/0.6/2637_auctionhouse.sql new file mode 100644 index 000000000..01b5c09ea --- /dev/null +++ b/sql/updates/0.6/2637_auctionhouse.sql @@ -0,0 +1,6 @@ +ALTER TABLE `auctionhouse` + ADD `item_template` int(11) unsigned NOT NULL default '0' AFTER `itemguid`; + +UPDATE `auctionhouse`,`item_instance` + SET `item_template` = SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',4),' ',-1) + WHERE `auctionhouse`.`itemguid` = `item_instance`.`guid`; diff --git a/sql/updates/0.6/2637_mail.sql b/sql/updates/0.6/2637_mail.sql new file mode 100644 index 000000000..3727fc138 --- /dev/null +++ b/sql/updates/0.6/2637_mail.sql @@ -0,0 +1,7 @@ +ALTER TABLE `mail` + ADD `item_template` int(11) unsigned NOT NULL default '0' AFTER `item`; + +UPDATE `mail`,`item_instance` + SET `item_template` = SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',4),' ',-1) + WHERE `mail`.`item` = `item_instance`.`guid`; + diff --git a/sql/updates/0.6/2641_command.sql b/sql/updates/0.6/2641_command.sql new file mode 100644 index 000000000..09cc11e2c --- /dev/null +++ b/sql/updates/0.6/2641_command.sql @@ -0,0 +1,2 @@ +INSERT INTO `command` VALUES('lookupmob',3,'Syntax: .lookupmob $namepart\r\n\r\nLooks up a creature by $namepart, and returns all matches with their creature ID\'s.'); +INSERT INTO `command` VALUES('lookupskill',3,'Syntax: .lookupskill $$namepart\r\n\r\nLooks up a skill by $namepart, and returns all matches with their skill ID\'s.'); diff --git a/sql/updates/0.6/2642_loot_template.sql b/sql/updates/0.6/2642_loot_template.sql new file mode 100644 index 000000000..74dfb12a9 --- /dev/null +++ b/sql/updates/0.6/2642_loot_template.sql @@ -0,0 +1,34 @@ +ALTER TABLE `creature_loot_template` + CHANGE `chance` `ChanceOrRef` float NOT NULL default '100', + CHANGE `questchance` `QuestChanceOrGroup` tinyint(3) NOT NULL default '0'; + +ALTER TABLE `fishing_loot_template` + CHANGE `chance` `ChanceOrRef` float NOT NULL default '100', + CHANGE `questchance` `QuestChanceOrGroup` tinyint(3) NOT NULL default '0'; + +ALTER TABLE `gameobject_loot_template` + CHANGE `chance` `ChanceOrRef` float NOT NULL default '100', + CHANGE `questchance` `QuestChanceOrGroup` tinyint(3) NOT NULL default '0'; + +ALTER TABLE `item_loot_template` + CHANGE `chance` `ChanceOrRef` float NOT NULL default '100', + CHANGE `questchance` `QuestChanceOrGroup` tinyint(3) NOT NULL default '0'; + +ALTER TABLE `pickpocketing_loot_template` + CHANGE `chance` `ChanceOrRef` float NOT NULL default '100', + CHANGE `questchance` `QuestChanceOrGroup` tinyint(3) NOT NULL default '0'; + +ALTER TABLE `skinning_loot_template` + CHANGE `chance` `ChanceOrRef` float NOT NULL default '100', + CHANGE `questchance` `QuestChanceOrGroup` tinyint(3) NOT NULL default '0'; + +UPDATE `skinning_loot_template`,`skinning_loot_template_alternative` + SET `QuestChanceOrGroup` = '-1',`ChanceOrRef` = '80' + WHERE `skinning_loot_template`.`item` = `skinning_loot_template_alternative`.`item`; + +INSERT INTO `skinning_loot_template` + SELECT `skinning_loot_template`.`entry`, `skinning_loot_template_alternative`.`item2`, '20', '-1', `skinning_loot_template`.`maxcount`, '1' + FROM `skinning_loot_template`,`skinning_loot_template_alternative` + WHERE `skinning_loot_template`.`item` = `skinning_loot_template_alternative`.`item`; + +DROP TABLE `skinning_loot_template_alternative`; diff --git a/sql/updates/0.6/2649_command.sql b/sql/updates/0.6/2649_command.sql new file mode 100644 index 000000000..08e2425d0 --- /dev/null +++ b/sql/updates/0.6/2649_command.sql @@ -0,0 +1,2 @@ +INSERT INTO `command` VALUES('saveall',1,'Syntax: .saveallr\n\r\nSave all characters in game.'); + diff --git a/sql/updates/0.6/2660_command.sql b/sql/updates/0.6/2660_command.sql new file mode 100644 index 000000000..9a6b1281c --- /dev/null +++ b/sql/updates/0.6/2660_command.sql @@ -0,0 +1,5 @@ +UPDATE `command` SET `help` = 'Syntax: .saveall\r\n\r\nSave all characters in game.' WHERE `name` = 'saveall'; +UPDATE `command` SET `help` = 'Syntax: .recall $place\r\n\r\nTeleport you to various towns around the world. $place defines the target location. Available places include sunr, thun, cross, orgr, neth, thel, storm, iron, under, and darn.' WHERE `name` = 'recall'; +UPDATE `command` SET `help` = 'Syntax: .createguild $GuildName $GuildLeaderName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName as leader.' WHERE `name` = 'createguild'; + + diff --git a/sql/updates/0.6/2663_command.sql b/sql/updates/0.6/2663_command.sql new file mode 100644 index 000000000..3458a4ad7 --- /dev/null +++ b/sql/updates/0.6/2663_command.sql @@ -0,0 +1,2 @@ +UPDATE command SET help=replace(help,"Usage:","Syntax:") WHERE left(help,6)="Usage:"; + diff --git a/sql/updates/0.6/2670_command.sql b/sql/updates/0.6/2670_command.sql new file mode 100644 index 000000000..a63b72533 --- /dev/null +++ b/sql/updates/0.6/2670_command.sql @@ -0,0 +1,8 @@ +DELETE FROM `command` WHERE `name` = 'modify gold'; +INSERT INTO `command` VALUES('modify money',1,'Syntax:\r\n.modify money #money\r\n.money #money\r\n\r\nAdd or remove money to the selected player. If no player is selected, modify your money.\r\n\r\n #gold can be negative to remove money.'); +INSERT INTO `command` VALUES('money',1,'Syntax:\r\n.modify money #money\r\n.money #money\r\n\r\nAdd or remove money to the selected player. If no player is selected, modify your money.\r\n\r\n #gold can be negative to remove money.'); +UPDATE `command` SET `help` = 'Syntax:\r\n.modify speed #speed\r\n.speed #speed\r\n\r\nModify the running speed of the selected player. If no player is selected, modify your speed.\r\n\r\n #speed may range from 0 to 50.' WHERE `name` = 'modify speed'; +INSERT INTO `command` VALUES('speed',1,'Syntax:\r\n.modify speed #speed\r\n.speed #speed\r\n\r\nModify the running speed of the selected player. If no player is selected, modify your speed.\r\n\r\n #speed may range from 0 to 50.'); +DELETE FROM `command` WHERE `name` = 'lookupmob'; +INSERT INTO `command` VALUES('lookupcreature',3,'Syntax: .lookupcreature $namepart\r\n\r\nLooks up a creature by $namepart, and returns all matches with their creature ID\'s.'); + diff --git a/sql/updates/0.6/2674_quest_template.sql b/sql/updates/0.6/2674_quest_template.sql new file mode 100644 index 000000000..402dc8cb5 --- /dev/null +++ b/sql/updates/0.6/2674_quest_template.sql @@ -0,0 +1,11 @@ +alter table quest_template +add column + `OfferRewardEmote` int(11) unsigned NOT NULL default '0'; + +alter table quest_template +add column + `RequestItemsEmote` int(11) unsigned NOT NULL default '1'; + +alter table quest_template +add column + `CompleteScript` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2674_scripts.sql b/sql/updates/0.6/2674_scripts.sql new file mode 100644 index 000000000..d5fa11d29 --- /dev/null +++ b/sql/updates/0.6/2674_scripts.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS `scripts`; +CREATE TABLE `scripts` ( + `id` int(11) unsigned NOT NULL default '0', + `delay` int(11) unsigned NOT NULL default '0', + `command` int(11) unsigned NOT NULL default '0', + `datalong` int(11) unsigned NOT NULL default '0', + `datalong2` int(11) unsigned NOT NULL default '0', + `datatext` text NOT NULL default "", + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +); diff --git a/sql/updates/0.6/2680_game_addons.sql b/sql/updates/0.6/2680_game_addons.sql new file mode 100644 index 000000000..6a5452764 --- /dev/null +++ b/sql/updates/0.6/2680_game_addons.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `game_addons`; diff --git a/sql/updates/0.6/2684_gameobject.sql b/sql/updates/0.6/2684_gameobject.sql new file mode 100644 index 000000000..e5ce705d5 --- /dev/null +++ b/sql/updates/0.6/2684_gameobject.sql @@ -0,0 +1,4 @@ +alter table gameobject + add column + `dynflags` int(11) unsigned NOT NULL default '0'; + \ No newline at end of file diff --git a/sql/updates/0.6/2684_quest_template.sql b/sql/updates/0.6/2684_quest_template.sql new file mode 100644 index 000000000..bf2c18522 --- /dev/null +++ b/sql/updates/0.6/2684_quest_template.sql @@ -0,0 +1,13 @@ +alter table quest_template + add column + `HaveQuestId` int(11) unsigned NOT NULL default '0'; + +alter table quest_template + change column `IncompleteText` `RequestItemsText` text; + +alter table quest_template + change column `CompletionText` `OfferRewardText` text; + +alter table quest_template + add column + `Repeatable` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2688_command.sql b/sql/updates/0.6/2688_command.sql new file mode 100644 index 000000000..3f61c8795 --- /dev/null +++ b/sql/updates/0.6/2688_command.sql @@ -0,0 +1,2 @@ +UPDATE `command` SET `help` = 'Syntax: .levelup #numberoflevels\r\n\r\nIncrease/decrease the level of the selected character by #numberoflevels. If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected, increase your level. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.' WHERE `name` = 'levelup'; +UPDATE `command` SET `help` = 'Syntax:\r\n.reset level\r\n Reset level to 1 including reset stats and talents. Equipped items with greater level requirement can be lost.\r\n.reset spells\r\n Removes all non-original spells from spellbook.\r\n.reset stats\r\n Resets(recalculate) all stats of the targeted player to their original values at current level.\r\n.reset talents\r\n Removes all talents of the targeted player.' WHERE `name` = 'reset'; diff --git a/sql/updates/0.6/2688_player_levelstats.sql b/sql/updates/0.6/2688_player_levelstats.sql new file mode 100644 index 000000000..0e5049686 --- /dev/null +++ b/sql/updates/0.6/2688_player_levelstats.sql @@ -0,0 +1,2422 @@ +-- ---------------------------- +-- Table structure for player_levelstats +-- ---------------------------- +DROP TABLE IF EXISTS `player_levelstats`; +CREATE TABLE `player_levelstats` ( + `race` tinyint(3) unsigned NOT NULL, + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `hp` smallint(5) unsigned NOT NULL, + `mana` smallint(5) unsigned NOT NULL, + `str` tinyint(3) unsigned NOT NULL, + `agi` tinyint(3) unsigned NOT NULL, + `sta` tinyint(3) unsigned NOT NULL, + `int` tinyint(3) unsigned NOT NULL, + `spi` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`race`,`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +-- ---------------------------- +-- Records +-- ---------------------------- +INSERT INTO `player_levelstats` VALUES +('1', '1', '1', '60', '0', '23', '20', '22', '21', '20'), +('1', '1', '2', '79', '0', '24', '21', '23', '20', '21'), +('1', '1', '3', '98', '0', '25', '21', '24', '20', '22'), +('1', '1', '4', '117', '0', '26', '22', '25', '20', '22'), +('1', '1', '5', '136', '0', '28', '23', '26', '20', '22'), +('1', '1', '6', '155', '0', '29', '24', '27', '21', '22'), +('1', '1', '7', '174', '0', '30', '24', '28', '21', '23'), +('1', '1', '8', '193', '0', '31', '25', '29', '21', '23'), +('1', '1', '9', '212', '0', '32', '26', '30', '21', '23'), +('1', '1', '10', '231', '0', '33', '26', '31', '21', '24'), +('1', '1', '11', '250', '0', '35', '27', '33', '21', '24'), +('1', '1', '12', '269', '0', '36', '28', '34', '21', '24'), +('1', '1', '13', '288', '0', '37', '29', '35', '21', '25'), +('1', '1', '14', '308', '0', '39', '30', '36', '22', '25'), +('1', '1', '15', '329', '0', '40', '30', '37', '22', '25'), +('1', '1', '16', '351', '0', '41', '31', '38', '22', '26'), +('1', '1', '17', '374', '0', '42', '32', '40', '22', '26'), +('1', '1', '18', '398', '0', '44', '33', '41', '22', '26'), +('1', '1', '19', '398', '0', '44', '33', '41', '22', '26'), +('1', '1', '20', '449', '0', '47', '35', '43', '22', '27'), +('1', '1', '21', '476', '0', '48', '35', '45', '23', '27'), +('1', '1', '22', '504', '0', '49', '36', '46', '23', '28'), +('1', '1', '23', '533', '0', '51', '37', '47', '23', '28'), +('1', '1', '24', '563', '0', '52', '38', '49', '23', '29'), +('1', '1', '25', '594', '0', '54', '39', '50', '23', '29'), +('1', '1', '26', '626', '0', '55', '40', '51', '23', '29'), +('1', '1', '27', '659', '0', '57', '41', '53', '23', '30'), +('1', '1', '28', '693', '0', '58', '42', '54', '24', '30'), +('1', '1', '29', '728', '0', '60', '43', '56', '24', '31'), +('1', '1', '30', '764', '0', '62', '44', '57', '24', '31'), +('1', '1', '31', '801', '0', '63', '45', '58', '24', '31'), +('1', '1', '32', '839', '0', '65', '46', '60', '24', '32'), +('1', '1', '33', '878', '0', '66', '47', '61', '24', '32'), +('1', '1', '34', '918', '0', '68', '48', '63', '25', '33'), +('1', '1', '35', '959', '0', '70', '49', '64', '25', '33'), +('1', '1', '36', '1001', '0', '72', '50', '66', '25', '34'), +('1', '1', '37', '1045', '0', '73', '51', '68', '25', '34'), +('1', '1', '38', '1091', '0', '75', '52', '69', '25', '34'), +('1', '1', '39', '1139', '0', '77', '53', '71', '26', '35'), +('1', '1', '40', '1189', '0', '79', '54', '72', '26', '35'), +('1', '1', '41', '1241', '0', '80', '56', '74', '26', '36'), +('1', '1', '42', '1295', '0', '82', '57', '76', '26', '36'), +('1', '1', '43', '1351', '0', '84', '58', '77', '26', '37'), +('1', '1', '44', '1409', '0', '86', '59', '79', '26', '37'), +('1', '1', '45', '1469', '0', '88', '60', '81', '27', '38'), +('1', '1', '46', '1531', '0', '90', '61', '83', '27', '38'), +('1', '1', '47', '1595', '0', '92', '63', '84', '27', '39'), +('1', '1', '48', '1661', '0', '94', '64', '86', '27', '39'), +('1', '1', '49', '1729', '0', '96', '65', '88', '28', '40'), +('1', '1', '50', '1799', '0', '98', '66', '90', '28', '40'), +('1', '1', '51', '1871', '0', '100', '68', '92', '28', '42'), +('1', '1', '52', '1945', '0', '102', '69', '94', '28', '42'), +('1', '1', '53', '2021', '0', '104', '70', '96', '28', '43'), +('1', '1', '54', '2099', '0', '106', '72', '98', '29', '44'), +('1', '1', '55', '2179', '0', '109', '73', '100', '29', '44'), +('1', '1', '56', '2261', '0', '111', '74', '102', '29', '45'), +('1', '1', '57', '2345', '0', '113', '76', '104', '29', '45'), +('1', '1', '58', '2431', '0', '115', '77', '106', '30', '46'), +('1', '1', '59', '2519', '0', '118', '79', '108', '30', '46'), +('1', '1', '60', '2609', '0', '120', '80', '110', '30', '47'), +('1', '2', '1', '58', '80', '22', '20', '22', '22', '20'), +('1', '2', '2', '76', '99', '23', '21', '23', '21', '23'), +('1', '2', '3', '94', '119', '24', '21', '24', '21', '23'), +('1', '2', '4', '112', '140', '25', '22', '25', '22', '24'), +('1', '2', '5', '130', '162', '26', '22', '26', '22', '25'), +('1', '2', '6', '148', '185', '27', '23', '27', '23', '25'), +('1', '2', '7', '166', '209', '28', '23', '28', '24', '26'), +('1', '2', '8', '184', '234', '29', '24', '28', '24', '26'), +('1', '2', '9', '202', '260', '30', '24', '29', '25', '27'), +('1', '2', '10', '220', '287', '31', '25', '30', '25', '28'), +('1', '2', '11', '238', '315', '32', '25', '31', '26', '29'), +('1', '2', '12', '256', '344', '33', '26', '32', '27', '29'), +('1', '2', '13', '274', '374', '34', '27', '33', '27', '30'), +('1', '2', '14', '292', '405', '35', '27', '34', '28', '31'), +('1', '2', '15', '311', '437', '36', '28', '36', '29', '31'), +('1', '2', '16', '331', '470', '38', '28', '37', '29', '32'), +('1', '2', '17', '352', '504', '39', '29', '38', '30', '33'), +('1', '2', '18', '374', '539', '40', '30', '39', '31', '34'), +('1', '2', '19', '397', '575', '41', '30', '40', '31', '34'), +('1', '2', '20', '421', '612', '42', '31', '41', '32', '35'), +('1', '2', '21', '446', '650', '43', '32', '42', '33', '36'), +('1', '2', '22', '472', '689', '45', '32', '43', '34', '37'), +('1', '2', '23', '499', '729', '46', '33', '44', '34', '38'), +('1', '2', '24', '527', '770', '47', '34', '46', '35', '38'), +('1', '2', '25', '556', '812', '48', '34', '47', '36', '39'), +('1', '2', '26', '586', '854', '50', '35', '48', '37', '40'), +('1', '2', '27', '617', '896', '51', '36', '49', '37', '42'), +('1', '2', '28', '649', '938', '52', '36', '50', '38', '43'), +('1', '2', '29', '682', '980', '54', '37', '52', '39', '44'), +('1', '2', '30', '716', '1022', '55', '38', '53', '40', '44'), +('1', '2', '31', '751', '1064', '56', '39', '54', '41', '45'), +('1', '2', '32', '787', '1106', '58', '39', '56', '42', '46'), +('1', '2', '33', '824', '1148', '59', '40', '57', '42', '47'), +('1', '2', '34', '862', '1190', '61', '41', '58', '43', '48'), +('1', '2', '35', '901', '1232', '62', '42', '60', '44', '49'), +('1', '2', '36', '941', '1274', '64', '43', '61', '45', '50'), +('1', '2', '37', '982', '1316', '65', '43', '62', '46', '51'), +('1', '2', '38', '1024', '1358', '67', '44', '64', '47', '52'), +('1', '2', '39', '1067', '1400', '68', '45', '65', '48', '53'), +('1', '2', '40', '1111', '1442', '70', '46', '67', '49', '54'), +('1', '2', '41', '1156', '1484', '71', '47', '68', '50', '55'), +('1', '2', '42', '1202', '1526', '73', '47', '70', '51', '56'), +('1', '2', '43', '1249', '1568', '74', '48', '71', '52', '57'), +('1', '2', '44', '1297', '1610', '76', '49', '73', '52', '58'), +('1', '2', '45', '1346', '1652', '78', '50', '74', '53', '59'), +('1', '2', '46', '1396', '1694', '79', '51', '76', '54', '60'), +('1', '2', '47', '1447', '1736', '81', '52', '77', '56', '61'), +('1', '2', '48', '1499', '1778', '83', '53', '79', '57', '63'), +('1', '2', '49', '1552', '1820', '84', '54', '81', '58', '65'), +('1', '2', '50', '1606', '1862', '86', '55', '82', '59', '66'), +('1', '2', '51', '1661', '1904', '88', '56', '84', '60', '67'), +('1', '2', '52', '1717', '1946', '90', '57', '86', '61', '68'), +('1', '2', '53', '1774', '1988', '92', '58', '87', '62', '69'), +('1', '2', '54', '1832', '2030', '93', '59', '89', '63', '70'), +('1', '2', '55', '1891', '2072', '95', '60', '91', '64', '72'), +('1', '2', '56', '1951', '2114', '97', '61', '93', '65', '73'), +('1', '2', '57', '2012', '2156', '99', '62', '94', '66', '74'), +('1', '2', '58', '2074', '2198', '101', '63', '96', '68', '75'), +('1', '2', '59', '2137', '2240', '103', '64', '98', '69', '77'), +('1', '2', '60', '2201', '2282', '105', '65', '100', '70', '78'), +('1', '4', '1', '55', '0', '21', '23', '21', '21', '20'), +('1', '4', '2', '72', '0', '22', '24', '22', '20', '21'), +('1', '4', '3', '89', '0', '22', '25', '22', '20', '22'), +('1', '4', '4', '106', '0', '23', '27', '23', '21', '22'), +('1', '4', '5', '123', '0', '24', '28', '24', '21', '22'), +('1', '4', '6', '140', '0', '24', '29', '24', '21', '23'), +('1', '4', '7', '157', '0', '25', '31', '25', '21', '23'), +('1', '4', '8', '174', '0', '26', '32', '25', '21', '23'), +('1', '4', '9', '191', '0', '27', '33', '26', '21', '24'), +('1', '4', '10', '208', '0', '27', '35', '27', '22', '24'), +('1', '4', '11', '225', '0', '28', '36', '28', '22', '25'), +('1', '4', '12', '242', '0', '29', '37', '28', '22', '25'), +('1', '4', '13', '259', '0', '30', '39', '29', '22', '25'), +('1', '4', '14', '276', '0', '30', '40', '30', '22', '26'), +('1', '4', '15', '293', '0', '31', '42', '30', '23', '26'), +('1', '4', '16', '311', '0', '32', '43', '31', '23', '27'), +('1', '4', '17', '330', '0', '33', '44', '32', '23', '27'), +('1', '4', '18', '350', '0', '34', '46', '33', '23', '27'), +('1', '4', '19', '371', '0', '35', '48', '33', '23', '28'), +('1', '4', '20', '393', '0', '35', '49', '34', '24', '28'), +('1', '4', '21', '416', '0', '36', '51', '35', '24', '29'), +('1', '4', '22', '440', '0', '37', '52', '36', '24', '29'), +('1', '4', '23', '465', '0', '38', '54', '37', '24', '30'), +('1', '4', '24', '491', '0', '39', '55', '37', '25', '30'), +('1', '4', '25', '518', '0', '40', '57', '38', '25', '31'), +('1', '4', '26', '546', '0', '41', '59', '39', '25', '31'), +('1', '4', '27', '575', '0', '42', '60', '40', '25', '31'), +('1', '4', '28', '605', '0', '43', '62', '41', '25', '32'), +('1', '4', '29', '636', '0', '43', '64', '42', '26', '32'), +('1', '4', '30', '668', '0', '44', '66', '42', '26', '33'), +('1', '4', '31', '701', '0', '45', '67', '43', '26', '33'), +('1', '4', '32', '735', '0', '46', '69', '44', '26', '34'), +('1', '4', '33', '770', '0', '47', '71', '45', '27', '34'), +('1', '4', '34', '806', '0', '48', '73', '46', '27', '35'), +('1', '4', '35', '843', '0', '49', '75', '47', '27', '35'), +('1', '4', '36', '881', '0', '51', '77', '48', '28', '36'), +('1', '4', '37', '920', '0', '52', '78', '49', '28', '37'), +('1', '4', '38', '960', '0', '53', '80', '50', '28', '37'), +('1', '4', '39', '1001', '0', '54', '82', '51', '28', '38'), +('1', '4', '40', '1043', '0', '55', '84', '52', '29', '38'), +('1', '4', '41', '1086', '0', '56', '86', '53', '29', '39'), +('1', '4', '42', '1130', '0', '57', '88', '54', '29', '39'), +('1', '4', '43', '1175', '0', '58', '90', '55', '29', '40'), +('1', '4', '44', '1221', '0', '59', '93', '56', '30', '40'), +('1', '4', '45', '1268', '0', '61', '95', '57', '30', '42'), +('1', '4', '46', '1316', '0', '62', '97', '58', '30', '43'), +('1', '4', '47', '1365', '0', '63', '99', '59', '31', '43'), +('1', '4', '48', '1415', '0', '64', '101', '60', '31', '44'), +('1', '4', '49', '1466', '0', '65', '103', '62', '31', '45'), +('1', '4', '50', '1518', '0', '67', '106', '63', '32', '45'), +('1', '4', '51', '1571', '0', '68', '108', '64', '32', '46'), +('1', '4', '52', '1625', '0', '69', '110', '65', '32', '46'), +('1', '4', '53', '1680', '0', '70', '113', '66', '33', '47'), +('1', '4', '54', '1736', '0', '72', '115', '67', '33', '48'), +('1', '4', '55', '1793', '0', '73', '117', '69', '33', '48'), +('1', '4', '56', '1851', '0', '74', '120', '70', '34', '49'), +('1', '4', '57', '1910', '0', '76', '122', '71', '34', '50'), +('1', '4', '58', '1970', '0', '77', '125', '72', '34', '51'), +('1', '4', '59', '2031', '0', '79', '127', '74', '35', '51'), +('1', '4', '60', '2093', '0', '80', '130', '75', '35', '52'), +('1', '5', '1', '52', '160', '20', '20', '20', '24', '22'), +('1', '5', '2', '67', '184', '20', '20', '20', '23', '25'), +('1', '5', '3', '82', '209', '20', '20', '21', '24', '26'), +('1', '5', '4', '97', '235', '21', '21', '21', '25', '28'), +('1', '5', '5', '112', '262', '21', '21', '21', '27', '29'), +('1', '5', '6', '127', '290', '21', '21', '22', '28', '30'), +('1', '5', '7', '142', '319', '21', '21', '22', '29', '31'), +('1', '5', '8', '157', '349', '21', '22', '22', '30', '32'), +('1', '5', '9', '172', '380', '21', '22', '23', '31', '34'), +('1', '5', '10', '187', '427', '22', '22', '23', '33', '35'), +('1', '5', '11', '202', '445', '22', '22', '24', '34', '36'), +('1', '5', '12', '217', '479', '22', '23', '24', '35', '38'), +('1', '5', '13', '232', '514', '22', '23', '24', '36', '39'), +('1', '5', '14', '247', '550', '22', '23', '25', '38', '40'), +('1', '5', '15', '262', '587', '23', '23', '25', '39', '43'), +('1', '5', '16', '277', '625', '23', '24', '26', '40', '44'), +('1', '5', '17', '292', '679', '23', '24', '26', '42', '45'), +('1', '5', '18', '307', '704', '23', '24', '26', '43', '47'), +('1', '5', '19', '322', '745', '23', '25', '27', '44', '48'), +('1', '5', '20', '337', '787', '24', '25', '27', '46', '50'), +('1', '5', '21', '352', '830', '24', '25', '28', '47', '51'), +('1', '5', '22', '368', '889', '24', '25', '28', '49', '53'), +('1', '5', '23', '385', '919', '24', '26', '29', '50', '54'), +('1', '5', '24', '403', '980', '25', '26', '29', '52', '56'), +('1', '5', '25', '422', '1012', '25', '26', '30', '53', '57'), +('1', '5', '26', '442', '1075', '25', '27', '30', '55', '59'), +('1', '5', '27', '463', '1109', '25', '27', '30', '56', '61'), +('1', '5', '28', '485', '1174', '25', '27', '31', '58', '63'), +('1', '5', '29', '508', '1210', '26', '28', '31', '59', '65'), +('1', '5', '30', '532', '1262', '26', '28', '32', '61', '67'), +('1', '5', '31', '557', '1330', '26', '28', '32', '63', '68'), +('1', '5', '32', '583', '1369', '26', '29', '33', '64', '70'), +('1', '5', '33', '610', '1438', '27', '29', '33', '66', '72'), +('1', '5', '34', '638', '1492', '27', '29', '34', '68', '73'), +('1', '5', '35', '667', '1531', '27', '30', '34', '69', '75'), +('1', '5', '36', '697', '1585', '28', '30', '35', '71', '77'), +('1', '5', '37', '728', '1654', '28', '30', '36', '73', '79'), +('1', '5', '38', '760', '1708', '28', '31', '36', '75', '81'), +('1', '5', '39', '793', '1747', '28', '31', '37', '76', '84'), +('1', '5', '40', '827', '1801', '29', '31', '37', '78', '85'), +('1', '5', '41', '862', '1870', '29', '32', '38', '80', '87'), +('1', '5', '42', '898', '1924', '29', '32', '38', '82', '89'), +('1', '5', '43', '935', '1978', '29', '33', '39', '84', '91'), +('1', '5', '44', '973', '2032', '30', '33', '39', '86', '93'), +('1', '5', '45', '1012', '2086', '30', '33', '40', '88', '95'), +('1', '5', '46', '1052', '2140', '30', '34', '41', '90', '97'), +('1', '5', '47', '1093', '2194', '31', '34', '41', '92', '99'), +('1', '5', '48', '1135', '2248', '31', '35', '42', '94', '102'), +('1', '5', '49', '1178', '2302', '31', '35', '43', '96', '105'), +('1', '5', '50', '1222', '2356', '32', '35', '43', '98', '107'), +('1', '5', '51', '1267', '2410', '32', '36', '44', '100', '109'), +('1', '5', '52', '1313', '2464', '32', '36', '44', '102', '111'), +('1', '5', '53', '1360', '2518', '33', '37', '45', '104', '113'), +('1', '5', '54', '1408', '2572', '33', '37', '46', '106', '116'), +('1', '5', '55', '1457', '2626', '33', '38', '46', '109', '118'), +('1', '5', '56', '1507', '2680', '34', '38', '47', '111', '120'), +('1', '5', '57', '1558', '2734', '34', '39', '48', '113', '123'), +('1', '5', '58', '1610', '2788', '34', '39', '49', '115', '126'), +('1', '5', '59', '1663', '2842', '35', '40', '49', '118', '129'), +('1', '5', '60', '1717', '2896', '35', '40', '50', '120', '131'), +('1', '8', '1', '52', '165', '20', '20', '20', '23', '23'), +('1', '8', '2', '67', '190', '20', '20', '20', '24', '24'), +('1', '8', '3', '82', '216', '20', '20', '21', '25', '25'), +('1', '8', '4', '97', '243', '20', '21', '21', '27', '26'), +('1', '8', '5', '112', '271', '20', '21', '21', '28', '28'), +('1', '8', '6', '127', '300', '21', '21', '21', '29', '29'), +('1', '8', '7', '142', '330', '21', '21', '22', '30', '30'), +('1', '8', '8', '157', '346', '21', '21', '22', '31', '31'), +('1', '8', '9', '172', '393', '21', '21', '22', '33', '32'), +('1', '8', '10', '187', '426', '21', '22', '23', '34', '34'), +('1', '8', '11', '202', '460', '21', '22', '23', '35', '35'), +('1', '8', '12', '217', '495', '21', '22', '23', '37', '36'), +('1', '8', '13', '232', '531', '21', '22', '24', '38', '37'), +('1', '8', '14', '247', '568', '22', '22', '24', '39', '39'), +('1', '8', '15', '262', '606', '22', '23', '24', '41', '40'), +('1', '8', '16', '277', '645', '22', '23', '25', '42', '42'), +('1', '8', '17', '292', '670', '22', '23', '25', '43', '44'), +('1', '8', '18', '307', '726', '22', '23', '25', '45', '45'), +('1', '8', '19', '322', '753', '22', '23', '26', '46', '46'), +('1', '8', '20', '337', '811', '22', '24', '26', '48', '48'), +('1', '8', '21', '352', '840', '23', '24', '26', '49', '49'), +('1', '8', '22', '367', '900', '23', '24', '27', '51', '51'), +('1', '8', '23', '382', '931', '23', '24', '27', '52', '52'), +('1', '8', '24', '398', '993', '23', '25', '28', '54', '54'), +('1', '8', '25', '415', '1026', '23', '25', '28', '55', '55'), +('1', '8', '26', '433', '1090', '23', '25', '28', '57', '57'), +('1', '8', '27', '452', '1140', '23', '25', '29', '59', '58'), +('1', '8', '28', '472', '1176', '24', '25', '29', '60', '60'), +('1', '8', '29', '493', '1242', '24', '26', '30', '62', '61'), +('1', '8', '30', '515', '1293', '24', '26', '30', '64', '64'), +('1', '8', '31', '538', '1329', '24', '26', '30', '65', '66'), +('1', '8', '32', '562', '1395', '24', '26', '31', '67', '67'), +('1', '8', '33', '587', '1446', '24', '27', '31', '69', '69'), +('1', '8', '34', '613', '1482', '25', '27', '32', '70', '71'), +('1', '8', '35', '640', '1533', '25', '27', '32', '72', '72'), +('1', '8', '36', '668', '1584', '25', '28', '33', '74', '74'), +('1', '8', '37', '697', '1650', '25', '28', '33', '76', '76'), +('1', '8', '38', '727', '1701', '25', '28', '33', '78', '78'), +('1', '8', '39', '758', '1752', '26', '28', '34', '80', '79'), +('1', '8', '40', '790', '1788', '26', '29', '34', '81', '81'), +('1', '8', '41', '823', '1839', '26', '29', '35', '83', '84'), +('1', '8', '42', '857', '1890', '26', '29', '35', '85', '86'), +('1', '8', '43', '892', '1941', '26', '29', '36', '87', '88'), +('1', '8', '44', '928', '1992', '26', '30', '36', '89', '90'), +('1', '8', '45', '965', '2043', '27', '30', '37', '91', '92'), +('1', '8', '46', '1003', '2094', '27', '30', '37', '93', '94'), +('1', '8', '47', '1042', '2145', '27', '31', '38', '95', '96'), +('1', '8', '48', '1082', '2211', '27', '31', '38', '98', '98'), +('1', '8', '49', '1123', '2262', '28', '31', '39', '100', '100'), +('1', '8', '50', '1165', '2298', '28', '32', '39', '102', '102'), +('1', '8', '51', '1208', '2349', '28', '32', '40', '104', '105'), +('1', '8', '52', '1252', '2400', '28', '32', '40', '106', '107'), +('1', '8', '53', '1297', '2451', '28', '33', '41', '108', '109'), +('1', '8', '54', '1343', '2502', '29', '33', '42', '111', '111'), +('1', '8', '55', '1390', '2553', '29', '33', '42', '113', '114'), +('1', '8', '56', '1438', '2604', '29', '34', '43', '115', '116'), +('1', '8', '57', '1487', '2655', '29', '34', '43', '118', '118'), +('1', '8', '58', '1537', '2706', '30', '34', '44', '120', '120'), +('1', '8', '59', '1588', '2757', '30', '35', '44', '123', '123'), +('1', '8', '60', '1640', '2808', '30', '35', '45', '125', '126'), +('1', '9', '1', '53', '140', '20', '20', '21', '23', '22'), +('1', '9', '2', '68', '163', '20', '20', '22', '23', '24'), +('1', '9', '3', '83', '187', '21', '21', '22', '24', '25'), +('1', '9', '4', '98', '212', '21', '21', '23', '25', '26'), +('1', '9', '5', '113', '238', '21', '21', '23', '26', '27'), +('1', '9', '6', '128', '265', '21', '22', '24', '27', '28'), +('1', '9', '7', '143', '293', '22', '22', '24', '28', '30'), +('1', '9', '8', '158', '322', '22', '22', '25', '29', '31'), +('1', '9', '9', '173', '352', '22', '23', '25', '30', '32'), +('1', '9', '10', '188', '383', '23', '23', '26', '31', '33'), +('1', '9', '11', '203', '415', '23', '24', '26', '33', '34'), +('1', '9', '12', '218', '448', '23', '24', '27', '34', '35'), +('1', '9', '13', '233', '482', '24', '24', '27', '35', '37'), +('1', '9', '14', '248', '517', '24', '25', '28', '36', '38'), +('1', '9', '15', '263', '553', '24', '25', '29', '37', '39'), +('1', '9', '16', '278', '590', '25', '26', '29', '38', '40'), +('1', '9', '17', '293', '628', '25', '26', '30', '40', '43'), +('1', '9', '18', '309', '667', '25', '26', '30', '41', '44'), +('1', '9', '19', '326', '707', '26', '27', '31', '42', '45'), +('1', '9', '20', '344', '748', '26', '27', '32', '43', '47'), +('1', '9', '21', '363', '790', '26', '28', '32', '45', '48'), +('1', '9', '22', '383', '833', '27', '28', '33', '46', '49'), +('1', '9', '23', '404', '877', '27', '29', '34', '47', '51'), +('1', '9', '24', '426', '922', '28', '29', '34', '49', '52'), +('1', '9', '25', '449', '968', '28', '30', '35', '50', '54'), +('1', '9', '26', '473', '1015', '28', '30', '36', '51', '55'), +('1', '9', '27', '498', '1063', '29', '30', '36', '53', '56'), +('1', '9', '28', '524', '1112', '29', '31', '37', '54', '58'), +('1', '9', '29', '551', '1162', '30', '31', '38', '56', '59'), +('1', '9', '30', '579', '1213', '30', '32', '38', '57', '61'), +('1', '9', '31', '608', '1264', '30', '32', '39', '58', '64'), +('1', '9', '32', '638', '1315', '31', '33', '40', '60', '65'), +('1', '9', '33', '669', '1366', '31', '33', '41', '61', '67'), +('1', '9', '34', '701', '1417', '32', '34', '41', '63', '68'), +('1', '9', '35', '734', '1468', '32', '34', '42', '64', '70'), +('1', '9', '36', '768', '1519', '33', '35', '43', '66', '72'), +('1', '9', '37', '803', '1570', '33', '36', '44', '68', '73'), +('1', '9', '38', '839', '1621', '33', '36', '45', '69', '75'), +('1', '9', '39', '876', '1672', '34', '37', '45', '71', '77'), +('1', '9', '40', '914', '1723', '34', '37', '46', '72', '78'), +('1', '9', '41', '953', '1774', '35', '38', '47', '74', '80'), +('1', '9', '42', '993', '1825', '35', '38', '48', '76', '82'), +('1', '9', '43', '1024', '1876', '36', '39', '48', '77', '86'), +('1', '9', '44', '1076', '1927', '36', '39', '50', '79', '86'), +('1', '9', '45', '1119', '1978', '37', '40', '50', '81', '88'), +('1', '9', '46', '1153', '2029', '37', '41', '51', '83', '90'), +('1', '9', '47', '1208', '2080', '38', '41', '52', '84', '92'), +('1', '9', '48', '1254', '2131', '38', '42', '53', '86', '94'), +('1', '9', '49', '1301', '2182', '39', '43', '54', '88', '96'), +('1', '9', '50', '1349', '2233', '39', '43', '55', '90', '98'), +('1', '9', '51', '1398', '2284', '40', '44', '56', '92', '100'), +('1', '9', '52', '1448', '2335', '40', '44', '57', '94', '102'), +('1', '9', '53', '1489', '2386', '41', '45', '58', '96', '105'), +('1', '9', '54', '1541', '2437', '42', '46', '59', '98', '107'), +('1', '9', '55', '1604', '2488', '42', '46', '60', '100', '109'), +('1', '9', '56', '1658', '2539', '43', '47', '61', '102', '111'), +('1', '9', '57', '1713', '2590', '43', '48', '62', '104', '113'), +('1', '9', '58', '1769', '2641', '44', '49', '63', '106', '116'), +('1', '9', '59', '1826', '2692', '44', '49', '64', '108', '118'), +('1', '9', '60', '1884', '2743', '45', '50', '65', '110', '120'), +('2', '1', '1', '80', '0', '26', '17', '24', '23', '17'), +('2', '1', '2', '99', '0', '27', '18', '25', '17', '23'), +('2', '1', '3', '118', '0', '28', '18', '26', '17', '24'), +('2', '1', '4', '137', '0', '29', '19', '27', '17', '24'), +('2', '1', '5', '156', '0', '31', '20', '28', '17', '24'), +('2', '1', '6', '175', '0', '32', '21', '29', '18', '24'), +('2', '1', '7', '194', '0', '33', '21', '30', '18', '25'), +('2', '1', '8', '213', '0', '34', '22', '31', '18', '25'), +('2', '1', '9', '232', '0', '35', '23', '32', '18', '25'), +('2', '1', '10', '251', '0', '36', '23', '33', '18', '26'), +('2', '1', '11', '270', '0', '38', '24', '35', '18', '26'), +('2', '1', '12', '289', '0', '39', '25', '36', '18', '26'), +('2', '1', '13', '308', '0', '40', '26', '37', '18', '27'), +('2', '1', '14', '328', '0', '42', '27', '38', '19', '27'), +('2', '1', '15', '349', '0', '43', '27', '39', '19', '27'), +('2', '1', '16', '371', '0', '44', '28', '40', '19', '28'), +('2', '1', '17', '394', '0', '45', '29', '42', '19', '28'), +('2', '1', '18', '418', '0', '47', '30', '43', '19', '28'), +('2', '1', '19', '443', '0', '48', '31', '44', '19', '29'), +('2', '1', '20', '469', '0', '50', '32', '45', '19', '29'), +('2', '1', '21', '496', '0', '51', '32', '47', '20', '29'), +('2', '1', '22', '524', '0', '52', '33', '48', '20', '30'), +('2', '1', '23', '553', '0', '54', '34', '49', '20', '30'), +('2', '1', '24', '583', '0', '55', '35', '51', '20', '31'), +('2', '1', '25', '614', '0', '57', '36', '52', '20', '31'), +('2', '1', '26', '646', '0', '58', '37', '53', '20', '31'), +('2', '1', '27', '679', '0', '60', '38', '55', '20', '32'), +('2', '1', '28', '713', '0', '61', '39', '56', '21', '32'), +('2', '1', '29', '748', '0', '63', '40', '58', '21', '33'), +('2', '1', '30', '784', '0', '65', '41', '59', '21', '33'), +('2', '1', '31', '821', '0', '66', '42', '60', '21', '33'), +('2', '1', '32', '859', '0', '68', '43', '62', '21', '34'), +('2', '1', '33', '898', '0', '69', '44', '63', '21', '34'), +('2', '1', '34', '938', '0', '71', '45', '65', '22', '35'), +('2', '1', '35', '979', '0', '73', '46', '66', '22', '35'), +('2', '1', '36', '1021', '0', '75', '47', '68', '22', '36'), +('2', '1', '37', '1065', '0', '76', '48', '70', '22', '36'), +('2', '1', '38', '1111', '0', '78', '49', '71', '22', '36'), +('2', '1', '39', '1159', '0', '80', '50', '73', '23', '37'), +('2', '1', '40', '1209', '0', '82', '51', '74', '23', '37'), +('2', '1', '41', '1261', '0', '83', '53', '76', '23', '38'), +('2', '1', '42', '1315', '0', '85', '54', '78', '23', '38'), +('2', '1', '43', '1371', '0', '87', '55', '79', '23', '39'), +('2', '1', '44', '1429', '0', '89', '56', '81', '23', '39'), +('2', '1', '45', '1489', '0', '91', '57', '83', '24', '40'), +('2', '1', '46', '1551', '0', '93', '58', '85', '24', '40'), +('2', '1', '47', '1615', '0', '95', '60', '86', '24', '41'), +('2', '1', '48', '1681', '0', '97', '61', '88', '24', '41'), +('2', '1', '49', '1749', '0', '99', '62', '90', '25', '42'), +('2', '1', '50', '1819', '0', '101', '63', '92', '25', '42'), +('2', '1', '51', '1891', '0', '103', '65', '94', '25', '43'), +('2', '1', '52', '1965', '0', '105', '66', '96', '25', '43'), +('2', '1', '53', '2041', '0', '107', '67', '98', '25', '44'), +('2', '1', '54', '2119', '0', '109', '69', '100', '26', '45'), +('2', '1', '55', '2199', '0', '112', '70', '102', '26', '45'), +('2', '1', '56', '2281', '0', '114', '71', '104', '26', '46'), +('2', '1', '57', '2365', '0', '116', '73', '106', '26', '46'), +('2', '1', '58', '2451', '0', '118', '74', '108', '27', '47'), +('2', '1', '59', '2539', '0', '121', '76', '110', '27', '47'), +('2', '1', '60', '2629', '0', '123', '77', '112', '27', '48'), +('2', '3', '1', '76', '82', '23', '20', '23', '24', '17'), +('2', '3', '2', '93', '88', '23', '21', '24', '18', '25'), +('2', '3', '3', '110', '109', '24', '22', '25', '18', '25'), +('2', '3', '4', '127', '117', '24', '24', '25', '19', '26'), +('2', '3', '5', '144', '140', '25', '25', '26', '19', '26'), +('2', '3', '6', '161', '150', '25', '26', '27', '20', '27'), +('2', '3', '7', '178', '175', '25', '27', '28', '20', '27'), +('2', '3', '8', '195', '201', '26', '28', '29', '21', '28'), +('2', '3', '9', '212', '228', '26', '30', '30', '21', '29'), +('2', '3', '10', '229', '256', '27', '31', '30', '22', '29'), +('2', '3', '11', '246', '285', '27', '32', '31', '22', '30'), +('2', '3', '12', '263', '315', '28', '34', '32', '23', '31'), +('2', '3', '13', '280', '346', '28', '35', '33', '24', '31'), +('2', '3', '14', '298', '378', '29', '36', '34', '24', '32'), +('2', '3', '15', '317', '411', '29', '38', '35', '25', '32'), +('2', '3', '16', '337', '445', '30', '39', '36', '25', '33'), +('2', '3', '17', '358', '480', '30', '40', '37', '26', '34'), +('2', '3', '18', '380', '516', '31', '42', '38', '27', '35'), +('2', '3', '19', '403', '553', '31', '43', '39', '27', '35'), +('2', '3', '20', '427', '591', '32', '45', '40', '28', '36'), +('2', '3', '21', '452', '630', '32', '46', '41', '29', '37'), +('2', '3', '22', '478', '670', '33', '48', '42', '29', '37'), +('2', '3', '23', '505', '711', '33', '49', '43', '30', '38'), +('2', '3', '24', '533', '753', '34', '51', '44', '31', '39'), +('2', '3', '25', '562', '796', '34', '52', '45', '31', '40'), +('2', '3', '26', '592', '840', '35', '54', '46', '32', '40'), +('2', '3', '27', '623', '885', '35', '56', '47', '33', '41'), +('2', '3', '28', '655', '930', '36', '57', '48', '33', '42'), +('2', '3', '29', '688', '975', '36', '59', '49', '34', '43'), +('2', '3', '30', '722', '1020', '37', '61', '50', '35', '43'), +('2', '3', '31', '757', '1065', '37', '62', '52', '36', '44'), +('2', '3', '32', '793', '1110', '38', '64', '53', '36', '45'), +('2', '3', '33', '830', '1155', '39', '66', '54', '37', '46'), +('2', '3', '34', '868', '1200', '39', '67', '55', '38', '47'), +('2', '3', '35', '907', '1245', '40', '69', '56', '39', '48'), +('2', '3', '36', '947', '1290', '41', '71', '58', '40', '49'), +('2', '3', '37', '988', '1335', '41', '73', '59', '40', '49'), +('2', '3', '38', '1030', '1380', '42', '75', '60', '41', '50'), +('2', '3', '39', '1073', '1425', '42', '77', '61', '42', '51'), +('2', '3', '40', '1117', '1470', '43', '78', '63', '43', '52'), +('2', '3', '41', '1162', '1515', '44', '80', '64', '44', '53'), +('2', '3', '42', '1208', '1560', '44', '82', '65', '44', '54'), +('2', '3', '43', '1255', '1605', '45', '84', '66', '45', '55'), +('2', '3', '44', '1303', '1650', '46', '86', '68', '46', '56'), +('2', '3', '45', '1352', '1695', '46', '88', '69', '47', '57'), +('2', '3', '46', '1402', '1740', '47', '90', '71', '48', '58'), +('2', '3', '47', '1453', '1785', '48', '92', '72', '49', '59'), +('2', '3', '48', '1505', '1830', '49', '95', '73', '50', '60'), +('2', '3', '49', '1558', '1875', '49', '97', '75', '51', '61'), +('2', '3', '50', '1612', '1920', '50', '99', '76', '52', '62'), +('2', '3', '51', '1667', '1965', '51', '101', '78', '53', '63'), +('2', '3', '52', '1723', '2010', '52', '103', '79', '54', '64'), +('2', '3', '53', '1780', '2055', '52', '105', '81', '55', '65'), +('2', '3', '54', '1838', '2100', '53', '108', '82', '56', '66'), +('2', '3', '55', '1897', '2145', '54', '110', '84', '57', '67'), +('2', '3', '56', '1957', '2190', '55', '112', '85', '58', '68'), +('2', '3', '57', '2018', '2235', '56', '115', '87', '59', '70'), +('2', '3', '58', '2080', '2280', '56', '117', '89', '60', '71'), +('2', '3', '59', '2143', '2325', '57', '120', '90', '61', '72'), +('2', '3', '60', '2207', '2370', '58', '122', '92', '62', '73'), +('2', '4', '1', '75', '0', '24', '20', '23', '23', '17'), +('2', '4', '2', '92', '0', '25', '21', '24', '17', '23'), +('2', '4', '3', '109', '0', '25', '22', '24', '17', '24'), +('2', '4', '4', '126', '0', '26', '24', '25', '18', '24'), +('2', '4', '5', '143', '0', '27', '25', '26', '18', '24'), +('2', '4', '6', '160', '0', '27', '26', '26', '18', '25'), +('2', '4', '7', '177', '0', '28', '28', '27', '18', '25'), +('2', '4', '8', '194', '0', '29', '29', '27', '18', '25'), +('2', '4', '9', '211', '0', '30', '30', '28', '18', '26'), +('2', '4', '10', '228', '0', '30', '32', '29', '19', '26'), +('2', '4', '11', '245', '0', '31', '33', '30', '19', '27'), +('2', '4', '12', '262', '0', '32', '34', '30', '19', '27'), +('2', '4', '13', '279', '0', '33', '36', '31', '19', '27'), +('2', '4', '14', '296', '0', '33', '37', '32', '19', '28'), +('2', '4', '15', '313', '0', '34', '39', '32', '20', '28'), +('2', '4', '16', '331', '0', '35', '40', '33', '20', '29'), +('2', '4', '17', '350', '0', '36', '41', '34', '20', '29'), +('2', '4', '18', '370', '0', '37', '43', '35', '20', '29'), +('2', '4', '19', '370', '0', '37', '43', '35', '20', '29'), +('2', '4', '20', '370', '0', '37', '43', '35', '20', '29'), +('2', '4', '21', '436', '0', '39', '48', '37', '21', '31'), +('2', '4', '22', '460', '0', '40', '49', '38', '21', '31'), +('2', '4', '23', '485', '0', '41', '51', '39', '21', '32'), +('2', '4', '24', '511', '0', '42', '52', '39', '22', '32'), +('2', '4', '25', '538', '0', '43', '54', '40', '22', '33'), +('2', '4', '26', '566', '0', '44', '56', '41', '22', '33'), +('2', '4', '27', '595', '0', '45', '57', '42', '22', '33'), +('2', '4', '28', '625', '0', '46', '59', '43', '22', '34'), +('2', '4', '29', '656', '0', '46', '61', '44', '23', '34'), +('2', '4', '30', '688', '0', '47', '63', '44', '23', '35'), +('2', '4', '31', '721', '0', '48', '64', '45', '23', '35'), +('2', '4', '32', '755', '0', '49', '66', '46', '23', '36'), +('2', '4', '33', '790', '0', '50', '68', '47', '24', '36'), +('2', '4', '34', '826', '0', '51', '70', '48', '24', '37'), +('2', '4', '35', '863', '0', '52', '72', '49', '24', '37'), +('2', '4', '36', '901', '0', '54', '74', '50', '25', '38'), +('2', '4', '37', '940', '0', '55', '75', '51', '25', '39'), +('2', '4', '38', '985', '0', '56', '77', '52', '25', '39'), +('2', '4', '39', '1021', '0', '57', '79', '53', '25', '40'), +('2', '4', '40', '1063', '0', '58', '81', '54', '26', '40'), +('2', '4', '41', '1106', '0', '59', '83', '55', '26', '41'), +('2', '4', '42', '1150', '0', '60', '85', '56', '26', '41'), +('2', '4', '43', '1195', '0', '61', '87', '57', '26', '42'), +('2', '4', '44', '1241', '0', '62', '90', '58', '27', '42'), +('2', '4', '45', '1288', '0', '64', '92', '59', '27', '43'), +('2', '4', '46', '1336', '0', '65', '94', '60', '27', '44'), +('2', '4', '47', '1385', '0', '66', '96', '61', '28', '44'), +('2', '4', '48', '1435', '0', '67', '98', '62', '28', '45'), +('2', '4', '49', '1486', '0', '68', '100', '64', '28', '46'), +('2', '4', '50', '1538', '0', '70', '103', '65', '29', '46'), +('2', '4', '51', '1591', '0', '71', '105', '66', '29', '47'), +('2', '4', '52', '1645', '0', '72', '107', '67', '29', '47'), +('2', '4', '53', '1700', '0', '73', '110', '68', '30', '48'), +('2', '4', '54', '1756', '0', '75', '112', '69', '30', '49'), +('2', '4', '55', '1813', '0', '76', '114', '71', '30', '49'), +('2', '4', '56', '1871', '0', '77', '117', '72', '31', '50'), +('2', '4', '57', '1930', '0', '79', '119', '73', '31', '51'), +('2', '4', '58', '1990', '0', '80', '122', '74', '31', '52'), +('2', '4', '59', '2051', '0', '82', '124', '76', '32', '52'), +('2', '4', '60', '2113', '0', '83', '127', '77', '32', '53'), +('2', '7', '1', '77', '73', '24', '17', '23', '25', '18'), +('2', '7', '2', '94', '80', '25', '17', '24', '19', '26'), +('2', '7', '3', '111', '88', '25', '18', '25', '20', '27'), +('2', '7', '4', '128', '111', '26', '18', '26', '20', '28'), +('2', '7', '5', '145', '135', '27', '19', '26', '21', '29'), +('2', '7', '6', '162', '160', '28', '19', '27', '22', '30'), +('2', '7', '7', '179', '186', '29', '19', '28', '23', '31'), +('2', '7', '8', '196', '213', '29', '20', '29', '24', '31'), +('2', '7', '9', '213', '256', '30', '20', '30', '25', '32'), +('2', '7', '10', '230', '270', '31', '21', '31', '25', '33'), +('2', '7', '11', '247', '300', '32', '21', '32', '26', '34'), +('2', '7', '12', '264', '331', '33', '22', '33', '27', '35'), +('2', '7', '13', '281', '363', '33', '22', '34', '28', '36'), +('2', '7', '14', '298', '396', '34', '23', '35', '29', '37'), +('2', '7', '15', '315', '430', '35', '23', '36', '30', '39'), +('2', '7', '16', '332', '465', '36', '24', '37', '31', '40'), +('2', '7', '17', '350', '501', '37', '24', '38', '32', '41'), +('2', '7', '18', '369', '538', '38', '25', '39', '33', '42'), +('2', '7', '19', '389', '576', '39', '25', '40', '34', '43'), +('2', '7', '20', '410', '615', '40', '26', '41', '35', '44'), +('2', '7', '21', '432', '655', '41', '26', '42', '36', '45'), +('2', '7', '22', '455', '731', '41', '27', '43', '37', '46'), +('2', '7', '23', '479', '738', '42', '27', '44', '38', '47'), +('2', '7', '24', '504', '781', '43', '28', '45', '39', '49'), +('2', '7', '25', '530', '825', '44', '28', '47', '40', '50'), +('2', '7', '26', '557', '914', '45', '29', '48', '41', '51'), +('2', '7', '27', '585', '916', '46', '29', '49', '42', '52'), +('2', '7', '28', '614', '963', '47', '30', '50', '43', '53'), +('2', '7', '29', '644', '1011', '48', '30', '51', '44', '55'), +('2', '7', '30', '675', '1113', '49', '31', '52', '45', '56'), +('2', '7', '31', '707', '1124', '51', '31', '54', '47', '57'), +('2', '7', '32', '740', '1232', '52', '32', '55', '48', '59'), +('2', '7', '33', '774', '1283', '53', '33', '56', '49', '60'), +('2', '7', '34', '809', '1319', '54', '33', '57', '50', '61'), +('2', '7', '35', '845', '1370', '55', '34', '59', '51', '63'), +('2', '7', '36', '882', '1438', '56', '35', '60', '53', '64'), +('2', '7', '37', '920', '1489', '57', '35', '61', '54', '65'), +('2', '7', '38', '959', '1541', '58', '36', '63', '55', '67'), +('2', '7', '39', '999', '1593', '59', '36', '64', '56', '68'), +('2', '7', '40', '1040', '1643', '61', '37', '65', '58', '70'), +('2', '7', '41', '1082', '1675', '62', '38', '67', '59', '71'), +('2', '7', '42', '1125', '1697', '63', '38', '68', '60', '73'), +('2', '7', '43', '1169', '1710', '64', '39', '70', '61', '74'), +('2', '7', '44', '1214', '1761', '66', '40', '71', '63', '76'), +('2', '7', '45', '1260', '1885', '67', '40', '73', '64', '77'), +('2', '7', '46', '1307', '1952', '68', '41', '74', '66', '79'), +('2', '7', '47', '1355', '2004', '69', '42', '76', '67', '80'), +('2', '7', '48', '1404', '2055', '71', '43', '77', '68', '82'), +('2', '7', '49', '1454', '2106', '72', '43', '79', '70', '84'), +('2', '7', '50', '1505', '2142', '73', '44', '80', '71', '85'), +('2', '7', '51', '1557', '2210', '75', '45', '82', '73', '87'), +('2', '7', '52', '1610', '2261', '76', '46', '83', '74', '89'), +('2', '7', '53', '1664', '2312', '78', '46', '85', '76', '90'), +('2', '7', '54', '1719', '2334', '79', '47', '87', '77', '92'), +('2', '7', '55', '1775', '2364', '80', '48', '88', '79', '94'), +('2', '7', '56', '1832', '2415', '82', '49', '90', '80', '96'), +('2', '7', '57', '1890', '2518', '83', '50', '92', '82', '97'), +('2', '7', '58', '1949', '2570', '85', '50', '93', '84', '99'), +('2', '7', '59', '2009', '2621', '86', '51', '95', '85', '101'), +('2', '7', '60', '2070', '2700', '88', '52', '97', '87', '103'), +('2', '9', '1', '73', '109', '23', '17', '23', '25', '19'), +('2', '9', '2', '88', '118', '23', '17', '24', '20', '26'), +('2', '9', '3', '103', '142', '24', '18', '24', '21', '27'), +('2', '9', '4', '118', '167', '24', '18', '25', '22', '28'), +('2', '9', '5', '133', '193', '24', '18', '25', '23', '29'), +('2', '9', '6', '148', '220', '24', '19', '26', '24', '30'), +('2', '9', '7', '163', '248', '25', '19', '26', '25', '32'), +('2', '9', '8', '178', '277', '25', '19', '27', '26', '33'), +('2', '9', '9', '193', '307', '25', '20', '27', '27', '34'), +('2', '9', '10', '208', '338', '26', '20', '28', '28', '35'), +('2', '9', '11', '223', '370', '26', '21', '28', '30', '36'), +('2', '9', '12', '238', '403', '26', '21', '29', '31', '37'), +('2', '9', '13', '253', '437', '27', '21', '29', '32', '39'), +('2', '9', '14', '268', '472', '27', '22', '30', '33', '40'), +('2', '9', '15', '283', '508', '27', '22', '31', '34', '41'), +('2', '9', '16', '298', '545', '28', '23', '31', '35', '42'), +('2', '9', '17', '313', '583', '28', '23', '32', '37', '44'), +('2', '9', '18', '329', '622', '28', '23', '32', '38', '45'), +('2', '9', '19', '364', '662', '29', '24', '33', '39', '46'), +('2', '9', '20', '376', '703', '29', '24', '34', '40', '48'), +('2', '9', '21', '408', '745', '29', '25', '34', '42', '49'), +('2', '9', '22', '408', '788', '30', '25', '34', '43', '50'), +('2', '9', '23', '424', '832', '30', '26', '35', '44', '52'), +('2', '9', '24', '446', '877', '31', '26', '35', '46', '53'), +('2', '9', '25', '469', '923', '31', '27', '36', '47', '55'), +('2', '9', '26', '493', '970', '31', '27', '37', '48', '56'), +('2', '9', '27', '518', '1018', '32', '27', '37', '50', '57'), +('2', '9', '28', '544', '1067', '32', '28', '38', '51', '59'), +('2', '9', '29', '571', '1117', '33', '28', '39', '53', '60'), +('2', '9', '30', '599', '1168', '33', '29', '39', '54', '62'), +('2', '9', '31', '628', '1219', '33', '29', '40', '55', '64'), +('2', '9', '32', '658', '1270', '34', '30', '41', '57', '65'), +('2', '9', '33', '679', '1321', '34', '30', '41', '58', '68'), +('2', '9', '34', '721', '1372', '35', '31', '42', '60', '68'), +('2', '9', '35', '754', '1423', '35', '31', '43', '61', '70'), +('2', '9', '36', '788', '1474', '36', '32', '44', '63', '71'), +('2', '9', '37', '823', '1525', '36', '33', '45', '65', '73'), +('2', '9', '38', '859', '1576', '36', '33', '46', '66', '75'), +('2', '9', '39', '896', '1627', '37', '34', '46', '68', '77'), +('2', '9', '40', '934', '1678', '37', '34', '47', '69', '78'), +('2', '9', '41', '973', '1729', '38', '35', '47', '71', '80'), +('2', '9', '42', '993', '1780', '38', '35', '47', '73', '83'), +('2', '9', '43', '1054', '1831', '39', '36', '50', '74', '84'), +('2', '9', '44', '1096', '1882', '39', '36', '51', '76', '85'), +('2', '9', '45', '1139', '1933', '40', '37', '51', '78', '87'), +('2', '9', '46', '1183', '1984', '40', '38', '52', '80', '89'), +('2', '9', '47', '1228', '2035', '41', '38', '53', '81', '91'), +('2', '9', '48', '1274', '2086', '41', '39', '53', '83', '93'), +('2', '9', '49', '1321', '2137', '42', '40', '54', '85', '96'), +('2', '9', '50', '1369', '2188', '42', '40', '56', '87', '97'), +('2', '9', '51', '1408', '2239', '43', '41', '56', '89', '99'), +('2', '9', '52', '1468', '2290', '43', '41', '58', '91', '101'), +('2', '9', '53', '1519', '2341', '44', '42', '59', '93', '103'), +('2', '9', '54', '1551', '2392', '45', '43', '60', '95', '105'), +('2', '9', '55', '1624', '2443', '45', '43', '61', '97', '106'), +('2', '9', '56', '1678', '2494', '46', '44', '62', '99', '109'), +('2', '9', '57', '1727', '2545', '46', '45', '62', '101', '110'), +('2', '9', '58', '1779', '2596', '47', '46', '64', '103', '114'), +('2', '9', '59', '1836', '2647', '47', '46', '65', '105', '116'), +('2', '9', '60', '1904', '2698', '48', '47', '66', '107', '118'), +('3', '1', '1', '90', '0', '25', '16', '25', '19', '19'), +('3', '1', '2', '109', '0', '26', '17', '26', '19', '19'), +('3', '1', '3', '128', '0', '27', '17', '27', '19', '20'), +('3', '1', '4', '147', '0', '28', '18', '28', '19', '20'), +('3', '1', '5', '166', '0', '30', '19', '29', '19', '20'), +('3', '1', '6', '185', '0', '31', '20', '30', '20', '20'), +('3', '1', '7', '204', '0', '32', '20', '31', '20', '21'), +('3', '1', '8', '223', '0', '33', '21', '32', '20', '21'), +('3', '1', '9', '242', '0', '34', '22', '33', '20', '21'), +('3', '1', '10', '261', '0', '35', '22', '34', '20', '22'), +('3', '1', '11', '280', '0', '37', '23', '36', '20', '22'), +('3', '1', '12', '299', '0', '38', '24', '37', '20', '22'), +('3', '1', '13', '318', '0', '39', '25', '38', '20', '23'), +('3', '1', '14', '338', '0', '41', '26', '39', '21', '23'), +('3', '1', '15', '359', '0', '42', '26', '40', '21', '23'), +('3', '1', '16', '381', '0', '43', '27', '41', '21', '24'), +('3', '1', '17', '404', '0', '44', '28', '43', '21', '24'), +('3', '1', '18', '428', '0', '46', '29', '44', '21', '24'), +('3', '1', '19', '453', '0', '47', '30', '45', '21', '25'), +('3', '1', '20', '479', '0', '49', '31', '46', '21', '25'), +('3', '1', '21', '506', '0', '50', '31', '48', '22', '25'), +('3', '1', '22', '534', '0', '51', '32', '49', '22', '26'), +('3', '1', '23', '563', '0', '53', '33', '50', '22', '26'), +('3', '1', '24', '593', '0', '54', '34', '52', '22', '27'), +('3', '1', '25', '624', '0', '56', '35', '53', '22', '27'), +('3', '1', '26', '656', '0', '57', '36', '54', '22', '27'), +('3', '1', '27', '689', '0', '59', '37', '56', '22', '28'), +('3', '1', '28', '723', '0', '60', '38', '57', '23', '28'), +('3', '1', '29', '758', '0', '62', '39', '59', '23', '29'), +('3', '1', '30', '794', '0', '64', '40', '60', '23', '29'), +('3', '1', '31', '831', '0', '65', '41', '61', '23', '29'), +('3', '1', '32', '869', '0', '67', '42', '63', '23', '30'), +('3', '1', '33', '908', '0', '68', '43', '64', '23', '30'), +('3', '1', '34', '948', '0', '70', '44', '66', '24', '31'), +('3', '1', '35', '989', '0', '72', '45', '67', '24', '31'), +('3', '1', '36', '1031', '0', '74', '46', '69', '24', '32'), +('3', '1', '37', '1075', '0', '75', '47', '71', '24', '32'), +('3', '1', '38', '1121', '0', '77', '48', '72', '24', '32'), +('3', '1', '39', '1169', '0', '79', '49', '74', '25', '33'), +('3', '1', '40', '1219', '0', '81', '50', '75', '25', '33'), +('3', '1', '41', '1271', '0', '82', '52', '77', '25', '34'), +('3', '1', '42', '1325', '0', '84', '53', '79', '25', '34'), +('3', '1', '43', '1381', '0', '86', '54', '80', '25', '35'), +('3', '1', '44', '1439', '0', '88', '55', '82', '25', '35'), +('3', '1', '45', '1499', '0', '90', '56', '84', '26', '36'), +('3', '1', '46', '1561', '0', '92', '57', '86', '26', '36'), +('3', '1', '47', '1625', '0', '94', '59', '87', '26', '37'), +('3', '1', '48', '1691', '0', '96', '60', '89', '26', '37'), +('3', '1', '49', '1759', '0', '98', '61', '91', '27', '38'), +('3', '1', '50', '1829', '0', '100', '62', '93', '27', '38'), +('3', '1', '51', '1901', '0', '102', '64', '95', '27', '39'), +('3', '1', '52', '1975', '0', '104', '65', '97', '27', '39'), +('3', '1', '53', '2051', '0', '106', '66', '99', '27', '40'), +('3', '1', '54', '2129', '0', '108', '68', '101', '28', '41'), +('3', '1', '55', '2209', '0', '111', '69', '103', '28', '41'), +('3', '1', '56', '2291', '0', '113', '70', '105', '28', '42'), +('3', '1', '57', '2375', '0', '115', '72', '107', '28', '42'), +('3', '1', '58', '2461', '0', '117', '73', '109', '29', '43'), +('3', '1', '59', '2549', '0', '120', '75', '111', '29', '43'), +('3', '1', '60', '2639', '0', '122', '76', '113', '29', '44'), +('3', '2', '1', '88', '79', '24', '16', '25', '20', '19'), +('3', '2', '2', '106', '84', '25', '17', '26', '20', '21'), +('3', '2', '3', '124', '104', '26', '17', '27', '20', '21'), +('3', '2', '4', '142', '125', '27', '18', '28', '21', '22'), +('3', '2', '5', '160', '147', '28', '18', '29', '21', '23'), +('3', '2', '6', '178', '170', '29', '19', '30', '22', '23'), +('3', '2', '7', '196', '194', '30', '19', '31', '23', '24'), +('3', '2', '8', '214', '219', '31', '20', '31', '23', '24'), +('3', '2', '9', '232', '245', '32', '20', '32', '24', '25'), +('3', '2', '10', '250', '272', '33', '21', '33', '24', '26'), +('3', '2', '11', '268', '300', '34', '21', '34', '25', '27'), +('3', '2', '12', '286', '329', '35', '22', '35', '26', '27'), +('3', '2', '13', '304', '359', '36', '23', '36', '26', '28'), +('3', '2', '14', '322', '390', '37', '23', '37', '27', '29'), +('3', '2', '15', '341', '422', '38', '24', '39', '28', '29'), +('3', '2', '16', '361', '455', '40', '24', '40', '28', '30'), +('3', '2', '17', '382', '489', '41', '25', '41', '29', '31'), +('3', '2', '18', '404', '524', '42', '26', '42', '30', '32'), +('3', '2', '19', '427', '560', '43', '26', '43', '30', '32'), +('3', '2', '20', '451', '597', '44', '27', '44', '31', '33'), +('3', '2', '21', '476', '635', '45', '28', '45', '32', '34'), +('3', '2', '22', '502', '674', '47', '28', '46', '33', '35'), +('3', '2', '23', '529', '714', '48', '29', '47', '33', '36'), +('3', '2', '24', '557', '755', '49', '30', '49', '34', '36'), +('3', '2', '25', '586', '797', '50', '30', '50', '35', '37'), +('3', '2', '26', '616', '839', '52', '31', '51', '36', '38'), +('3', '2', '27', '647', '881', '53', '32', '52', '36', '39'), +('3', '2', '28', '679', '923', '54', '32', '53', '37', '40'), +('3', '2', '29', '712', '965', '56', '33', '55', '38', '41'), +('3', '2', '30', '746', '1007', '57', '34', '56', '39', '41'), +('3', '2', '31', '781', '1049', '58', '35', '57', '40', '42'), +('3', '2', '32', '817', '1091', '60', '35', '59', '41', '43'), +('3', '2', '33', '854', '1133', '61', '36', '60', '41', '44'), +('3', '2', '34', '892', '1175', '63', '37', '61', '42', '45'), +('3', '2', '35', '931', '1217', '64', '38', '63', '43', '46'), +('3', '2', '36', '971', '1259', '66', '39', '64', '44', '47'), +('3', '2', '37', '1012', '1301', '67', '39', '65', '45', '48'), +('3', '2', '38', '1054', '1343', '69', '40', '67', '46', '49'), +('3', '2', '39', '1097', '1385', '70', '41', '68', '47', '50'), +('3', '2', '40', '1141', '1427', '72', '42', '70', '48', '51'), +('3', '2', '41', '1186', '1469', '73', '43', '71', '49', '52'), +('3', '2', '42', '1232', '1511', '75', '43', '73', '50', '53'), +('3', '2', '43', '1279', '1553', '76', '44', '74', '51', '54'), +('3', '2', '44', '1327', '1595', '78', '45', '76', '51', '55'), +('3', '2', '45', '1376', '1637', '80', '46', '77', '52', '56'), +('3', '2', '46', '1426', '1679', '81', '47', '79', '53', '57'), +('3', '2', '47', '1477', '1721', '83', '48', '80', '55', '58'), +('3', '2', '48', '1529', '1763', '85', '49', '82', '56', '59'), +('3', '2', '49', '1582', '1805', '86', '50', '84', '57', '61'), +('3', '2', '50', '1636', '1847', '88', '51', '85', '58', '62'), +('3', '2', '51', '1691', '1889', '90', '52', '87', '59', '63'), +('3', '2', '52', '1747', '1931', '92', '53', '89', '60', '64'), +('3', '2', '53', '1804', '1973', '94', '54', '90', '61', '65'), +('3', '2', '54', '1862', '2015', '95', '55', '92', '62', '66'), +('3', '2', '55', '1921', '2057', '97', '56', '94', '63', '68'), +('3', '2', '56', '1981', '2099', '99', '57', '96', '64', '69'), +('3', '2', '57', '2042', '2141', '101', '58', '97', '65', '70'), +('3', '2', '58', '2104', '2183', '103', '59', '99', '67', '71'), +('3', '2', '59', '2167', '2225', '105', '60', '101', '68', '73'), +('3', '2', '60', '2231', '2267', '107', '61', '103', '69', '74'), +('3', '3', '1', '86', '84', '22', '19', '24', '20', '19'), +('3', '3', '2', '103', '90', '22', '20', '25', '20', '21'), +('3', '3', '3', '120', '111', '23', '21', '26', '20', '21'), +('3', '3', '4', '137', '133', '23', '23', '26', '21', '22'), +('3', '3', '5', '154', '156', '24', '24', '27', '21', '22'), +('3', '3', '6', '171', '180', '24', '25', '28', '22', '23'), +('3', '3', '7', '188', '205', '24', '26', '29', '22', '23'), +('3', '3', '8', '205', '231', '25', '27', '30', '23', '24'), +('3', '3', '9', '222', '258', '25', '29', '31', '23', '25'), +('3', '3', '10', '239', '286', '26', '30', '31', '24', '25'), +('3', '3', '11', '256', '315', '26', '31', '32', '24', '26'), +('3', '3', '12', '273', '345', '27', '33', '33', '25', '27'), +('3', '3', '13', '290', '376', '27', '34', '34', '26', '27'), +('3', '3', '14', '308', '408', '28', '35', '35', '26', '28'), +('3', '3', '15', '327', '441', '28', '37', '36', '27', '28'), +('3', '3', '16', '347', '475', '29', '38', '37', '27', '29'), +('3', '3', '17', '368', '510', '29', '39', '38', '28', '30'), +('3', '3', '18', '390', '546', '30', '41', '39', '29', '31'), +('3', '3', '19', '413', '583', '30', '42', '40', '29', '31'), +('3', '3', '20', '437', '621', '31', '44', '41', '30', '32'), +('3', '3', '21', '462', '660', '31', '45', '42', '31', '33'), +('3', '3', '22', '488', '700', '32', '47', '43', '31', '33'), +('3', '3', '23', '515', '741', '32', '48', '44', '32', '34'), +('3', '3', '24', '543', '783', '33', '50', '45', '33', '35'), +('3', '3', '25', '572', '826', '33', '51', '46', '33', '36'), +('3', '3', '26', '602', '870', '34', '53', '47', '34', '36'), +('3', '3', '27', '633', '915', '34', '55', '48', '35', '37'), +('3', '3', '28', '665', '960', '35', '56', '49', '35', '38'), +('3', '3', '29', '698', '1005', '35', '58', '50', '36', '39'), +('3', '3', '30', '732', '1050', '36', '60', '51', '37', '39'), +('3', '3', '31', '767', '1095', '36', '61', '53', '38', '40'), +('3', '3', '32', '803', '1140', '37', '63', '54', '38', '41'), +('3', '3', '33', '840', '1185', '38', '65', '55', '39', '42'), +('3', '3', '34', '878', '1230', '38', '66', '56', '40', '43'), +('3', '3', '35', '917', '1275', '39', '68', '57', '41', '44'), +('3', '3', '36', '957', '1320', '40', '70', '59', '42', '45'), +('3', '3', '37', '998', '1365', '40', '72', '60', '42', '45'), +('3', '3', '38', '1040', '1410', '41', '74', '61', '43', '46'), +('3', '3', '39', '1083', '1455', '41', '76', '62', '44', '47'), +('3', '3', '40', '1127', '1500', '42', '77', '64', '45', '48'), +('3', '3', '41', '1172', '1545', '43', '79', '65', '46', '49'), +('3', '3', '42', '1218', '1590', '43', '81', '66', '46', '50'), +('3', '3', '43', '1265', '1635', '44', '83', '67', '47', '51'), +('3', '3', '44', '1313', '1680', '45', '85', '69', '48', '52'), +('3', '3', '45', '1362', '1725', '45', '87', '70', '49', '53'), +('3', '3', '46', '1412', '1770', '46', '89', '72', '50', '54'), +('3', '3', '47', '1463', '1815', '47', '91', '73', '51', '55'), +('3', '3', '48', '1515', '1860', '48', '94', '74', '52', '56'), +('3', '3', '49', '1568', '1905', '48', '96', '76', '53', '57'), +('3', '3', '50', '1622', '1950', '49', '98', '77', '54', '58'), +('3', '3', '51', '1677', '1995', '50', '100', '79', '55', '59'), +('3', '3', '52', '1733', '2040', '51', '102', '80', '56', '60'), +('3', '3', '53', '1790', '2085', '51', '104', '82', '57', '61'), +('3', '3', '54', '1848', '2130', '52', '107', '83', '58', '62'), +('3', '3', '55', '1907', '2175', '53', '109', '85', '59', '63'), +('3', '3', '56', '1967', '2220', '54', '111', '86', '60', '64'), +('3', '3', '57', '2028', '2265', '55', '114', '88', '61', '66'), +('3', '3', '58', '2090', '2310', '55', '116', '90', '62', '67'), +('3', '3', '59', '2153', '2355', '56', '119', '91', '63', '68'), +('3', '3', '60', '2217', '2400', '57', '121', '93', '64', '69'), +('3', '4', '1', '85', '0', '23', '19', '24', '19', '19'), +('3', '4', '2', '102', '0', '24', '20', '25', '19', '19'), +('3', '4', '3', '119', '0', '24', '21', '25', '19', '20'), +('3', '4', '4', '136', '0', '25', '23', '26', '20', '20'), +('3', '4', '5', '153', '0', '26', '24', '27', '20', '20'), +('3', '4', '6', '170', '0', '26', '25', '27', '20', '21'), +('3', '4', '7', '187', '0', '27', '27', '28', '20', '21'), +('3', '4', '8', '204', '0', '28', '28', '28', '20', '21'), +('3', '4', '9', '221', '0', '29', '29', '29', '20', '22'), +('3', '4', '10', '238', '0', '29', '31', '30', '21', '22'), +('3', '4', '11', '255', '0', '30', '32', '31', '21', '23'), +('3', '4', '12', '272', '0', '31', '33', '31', '21', '23'), +('3', '4', '13', '289', '0', '32', '35', '32', '21', '23'), +('3', '4', '14', '306', '0', '32', '36', '33', '21', '24'), +('3', '4', '15', '323', '0', '33', '38', '33', '22', '24'), +('3', '4', '16', '341', '0', '34', '39', '34', '22', '25'), +('3', '4', '17', '360', '0', '35', '40', '35', '22', '25'), +('3', '4', '18', '380', '0', '36', '42', '36', '22', '25'), +('3', '4', '19', '401', '0', '37', '44', '36', '22', '26'), +('3', '4', '20', '423', '0', '37', '45', '37', '23', '26'), +('3', '4', '21', '446', '0', '38', '47', '38', '23', '27'), +('3', '4', '22', '470', '0', '39', '48', '39', '23', '27'), +('3', '4', '23', '495', '0', '40', '50', '40', '23', '28'), +('3', '4', '24', '521', '0', '41', '51', '40', '24', '28'), +('3', '4', '25', '548', '0', '42', '53', '41', '24', '29'), +('3', '4', '26', '576', '0', '43', '55', '42', '24', '29'), +('3', '4', '27', '605', '0', '44', '56', '43', '24', '29'), +('3', '4', '28', '635', '0', '45', '58', '44', '24', '30'), +('3', '4', '29', '666', '0', '45', '60', '45', '25', '30'), +('3', '4', '30', '698', '0', '46', '62', '45', '25', '31'), +('3', '4', '31', '731', '0', '47', '63', '46', '25', '31'), +('3', '4', '32', '765', '0', '48', '65', '47', '25', '32'), +('3', '4', '33', '800', '0', '49', '67', '48', '26', '32'), +('3', '4', '34', '836', '0', '50', '69', '49', '26', '33'), +('3', '4', '35', '873', '0', '51', '71', '50', '26', '33'), +('3', '4', '36', '911', '0', '53', '73', '51', '27', '34'), +('3', '4', '37', '950', '0', '54', '74', '52', '27', '35'), +('3', '4', '38', '990', '0', '55', '76', '53', '27', '35'), +('3', '4', '39', '1031', '0', '56', '78', '54', '27', '36'), +('3', '4', '40', '1073', '0', '57', '80', '55', '28', '36'), +('3', '4', '41', '1116', '0', '58', '82', '56', '28', '37'), +('3', '4', '42', '1160', '0', '59', '84', '57', '28', '37'), +('3', '4', '43', '1205', '0', '60', '86', '58', '28', '38'), +('3', '4', '44', '1251', '0', '61', '89', '59', '29', '38'), +('3', '4', '45', '1298', '0', '63', '91', '60', '29', '39'), +('3', '4', '46', '1346', '0', '64', '93', '61', '29', '40'), +('3', '4', '47', '1395', '0', '65', '95', '62', '30', '40'), +('3', '4', '48', '1445', '0', '66', '97', '63', '30', '41'), +('3', '4', '49', '1496', '0', '67', '99', '65', '30', '42'), +('3', '4', '50', '1548', '0', '69', '102', '66', '31', '42'), +('3', '4', '51', '1601', '0', '70', '104', '67', '31', '43'), +('3', '4', '52', '1655', '0', '71', '106', '68', '31', '43'), +('3', '4', '53', '1710', '0', '72', '109', '69', '32', '44'), +('3', '4', '54', '1766', '0', '74', '111', '70', '32', '45'), +('3', '4', '55', '1823', '0', '75', '113', '72', '32', '45'), +('3', '4', '56', '1881', '0', '76', '116', '73', '33', '46'), +('3', '4', '57', '1940', '0', '78', '118', '74', '33', '47'), +('3', '4', '58', '2000', '0', '79', '121', '75', '33', '48'), +('3', '4', '59', '2061', '0', '81', '123', '77', '34', '48'), +('3', '4', '60', '2123', '0', '82', '126', '78', '34', '49'), +('3', '5', '1', '82', '145', '22', '16', '23', '22', '21'), +('3', '5', '2', '97', '169', '22', '16', '23', '22', '23'), +('3', '5', '3', '112', '194', '22', '16', '24', '23', '24'), +('3', '5', '4', '127', '220', '23', '17', '24', '24', '26'), +('3', '5', '5', '142', '247', '23', '17', '24', '26', '27'), +('3', '5', '6', '157', '275', '23', '17', '25', '27', '28'), +('3', '5', '7', '172', '304', '23', '17', '25', '28', '29'), +('3', '5', '8', '187', '334', '23', '18', '25', '29', '30'), +('3', '5', '9', '202', '365', '23', '18', '26', '30', '32'), +('3', '5', '10', '217', '412', '24', '18', '26', '32', '33'), +('3', '5', '11', '232', '430', '24', '18', '27', '33', '34'), +('3', '5', '12', '247', '464', '24', '19', '27', '34', '36'), +('3', '5', '13', '262', '499', '24', '19', '27', '35', '37'), +('3', '5', '14', '277', '535', '24', '19', '28', '37', '38'), +('3', '5', '15', '292', '572', '25', '19', '28', '38', '40'), +('3', '5', '16', '307', '610', '25', '20', '29', '39', '41'), +('3', '5', '17', '322', '664', '25', '20', '29', '41', '42'), +('3', '5', '18', '337', '689', '25', '20', '29', '42', '44'), +('3', '5', '19', '352', '730', '25', '21', '30', '43', '45'), +('3', '5', '20', '367', '772', '26', '21', '30', '45', '47'), +('3', '5', '21', '382', '815', '26', '21', '31', '46', '48'), +('3', '5', '22', '398', '874', '26', '21', '31', '48', '50'), +('3', '5', '23', '415', '904', '26', '22', '32', '49', '51'), +('3', '5', '24', '433', '965', '27', '22', '32', '51', '53'), +('3', '5', '25', '452', '997', '27', '22', '33', '52', '54'), +('3', '5', '26', '472', '1060', '27', '23', '33', '54', '56'), +('3', '5', '27', '493', '1094', '27', '23', '33', '55', '58'), +('3', '5', '28', '515', '1159', '27', '23', '34', '57', '59'), +('3', '5', '29', '538', '1195', '28', '24', '34', '58', '61'), +('3', '5', '30', '562', '1247', '28', '24', '35', '60', '63'), +('3', '5', '31', '587', '1315', '28', '24', '35', '62', '64'), +('3', '5', '32', '613', '1354', '28', '25', '36', '63', '66'), +('3', '5', '33', '640', '1423', '29', '25', '36', '65', '68'), +('3', '5', '34', '668', '1477', '29', '25', '37', '67', '69'), +('3', '5', '35', '697', '1516', '29', '26', '37', '68', '71'), +('3', '5', '36', '727', '1570', '30', '26', '38', '70', '73'), +('3', '5', '37', '758', '1639', '30', '26', '39', '72', '75'), +('3', '5', '38', '790', '1693', '30', '27', '39', '74', '77'), +('3', '5', '39', '823', '1732', '30', '27', '40', '75', '79'), +('3', '5', '40', '857', '1786', '31', '27', '40', '77', '80'), +('3', '5', '41', '892', '1855', '31', '28', '41', '79', '82'), +('3', '5', '42', '928', '1909', '31', '28', '41', '81', '84'), +('3', '5', '43', '965', '1963', '31', '29', '42', '83', '86'), +('3', '5', '44', '1003', '2017', '32', '29', '42', '85', '88'), +('3', '5', '45', '1042', '2071', '32', '29', '43', '87', '90'), +('3', '5', '46', '1082', '2125', '32', '30', '44', '89', '92'), +('3', '5', '47', '1123', '2179', '33', '30', '44', '91', '94'), +('3', '5', '48', '1165', '2233', '33', '31', '45', '93', '97'), +('3', '5', '49', '1208', '2287', '33', '31', '46', '95', '99'), +('3', '5', '50', '1252', '2341', '34', '31', '46', '97', '101'), +('3', '5', '51', '1297', '2395', '34', '32', '47', '99', '103'), +('3', '5', '52', '1343', '2449', '34', '32', '47', '101', '105'), +('3', '5', '53', '1390', '2503', '35', '33', '48', '103', '107'), +('3', '5', '54', '1438', '2557', '35', '33', '49', '105', '110'), +('3', '5', '55', '1487', '2611', '35', '34', '49', '108', '112'), +('3', '5', '56', '1537', '2665', '36', '34', '50', '110', '114'), +('3', '5', '57', '1588', '2719', '36', '35', '51', '112', '117'), +('3', '5', '58', '1640', '2773', '36', '35', '52', '114', '119'), +('3', '5', '59', '1693', '2827', '37', '36', '52', '117', '122'), +('3', '5', '60', '1747', '2881', '37', '36', '53', '119', '124'), +('4', '1', '1', '50', '0', '20', '25', '21', '20', '20'), +('4', '1', '2', '69', '0', '21', '26', '22', '20', '20'), +('4', '1', '3', '88', '0', '22', '26', '23', '20', '21'), +('4', '1', '4', '107', '0', '23', '27', '24', '20', '21'), +('4', '1', '5', '126', '0', '25', '28', '25', '20', '21'), +('4', '1', '6', '145', '0', '26', '29', '26', '21', '21'), +('4', '1', '7', '164', '0', '27', '29', '27', '21', '22'), +('4', '1', '8', '183', '0', '28', '30', '28', '21', '22'), +('4', '1', '9', '202', '0', '29', '31', '29', '21', '22'), +('4', '1', '10', '221', '0', '30', '31', '30', '21', '23'), +('4', '1', '11', '240', '0', '32', '32', '32', '21', '23'), +('4', '1', '12', '259', '0', '33', '33', '33', '21', '23'), +('4', '1', '13', '278', '0', '34', '34', '34', '21', '24'), +('4', '1', '14', '298', '0', '36', '35', '35', '22', '24'), +('4', '1', '15', '319', '0', '37', '35', '36', '22', '24'), +('4', '1', '16', '341', '0', '38', '36', '37', '22', '25'), +('4', '1', '17', '364', '0', '39', '37', '39', '22', '25'), +('4', '1', '18', '388', '0', '41', '38', '40', '22', '25'), +('4', '1', '19', '413', '0', '42', '39', '41', '22', '26'), +('4', '1', '20', '439', '0', '44', '40', '42', '22', '26'), +('4', '1', '21', '466', '0', '45', '40', '44', '23', '26'), +('4', '1', '22', '494', '0', '46', '41', '45', '23', '27'), +('4', '1', '23', '523', '0', '48', '42', '46', '23', '27'), +('4', '1', '24', '553', '0', '49', '43', '48', '23', '28'), +('4', '1', '25', '584', '0', '51', '44', '49', '23', '28'), +('4', '1', '26', '616', '0', '52', '45', '50', '23', '28'), +('4', '1', '27', '649', '0', '54', '46', '52', '23', '29'), +('4', '1', '28', '683', '0', '55', '47', '53', '24', '29'), +('4', '1', '29', '718', '0', '57', '48', '55', '24', '30'), +('4', '1', '30', '754', '0', '59', '49', '56', '24', '30'), +('4', '1', '31', '791', '0', '60', '50', '57', '24', '30'), +('4', '1', '32', '829', '0', '62', '51', '59', '24', '31'), +('4', '1', '33', '868', '0', '63', '52', '60', '24', '31'), +('4', '1', '34', '908', '0', '65', '53', '62', '25', '32'), +('4', '1', '35', '949', '0', '67', '54', '63', '25', '32'), +('4', '1', '36', '991', '0', '69', '55', '65', '25', '33'), +('4', '1', '37', '1035', '0', '70', '56', '67', '25', '33'), +('4', '1', '38', '1081', '0', '72', '57', '68', '25', '33'), +('4', '1', '39', '1129', '0', '74', '58', '70', '26', '34'), +('4', '1', '40', '1179', '0', '76', '59', '71', '26', '34'), +('4', '1', '41', '1231', '0', '77', '61', '73', '26', '35'), +('4', '1', '42', '1285', '0', '79', '62', '75', '26', '35'), +('4', '1', '43', '1341', '0', '81', '63', '76', '26', '36'), +('4', '1', '44', '1399', '0', '83', '64', '78', '26', '36'), +('4', '1', '45', '1459', '0', '85', '65', '80', '27', '37'), +('4', '1', '46', '1521', '0', '87', '66', '82', '27', '37'), +('4', '1', '47', '1585', '0', '89', '68', '83', '27', '38'), +('4', '1', '48', '1651', '0', '91', '69', '85', '27', '38'), +('4', '1', '49', '1719', '0', '93', '70', '87', '28', '39'), +('4', '1', '50', '1789', '0', '95', '71', '89', '28', '39'), +('4', '1', '51', '1861', '0', '97', '73', '91', '28', '40'), +('4', '1', '52', '1935', '0', '99', '74', '93', '28', '40'), +('4', '1', '53', '2011', '0', '101', '75', '95', '28', '41'), +('4', '1', '54', '2089', '0', '103', '77', '97', '29', '42'), +('4', '1', '55', '2169', '0', '106', '78', '99', '29', '42'), +('4', '1', '56', '2251', '0', '108', '79', '101', '29', '43'), +('4', '1', '57', '2335', '0', '110', '81', '103', '29', '43'), +('4', '1', '58', '2421', '0', '112', '82', '105', '30', '44'), +('4', '1', '59', '2509', '0', '115', '84', '107', '30', '44'), +('4', '1', '60', '2599', '0', '117', '85', '109', '30', '45'), +('4', '3', '1', '46', '85', '17', '28', '20', '21', '20'), +('4', '3', '2', '63', '105', '17', '29', '21', '21', '22'), +('4', '3', '3', '80', '126', '18', '30', '22', '21', '22'), +('4', '3', '4', '97', '148', '18', '32', '22', '22', '23'), +('4', '3', '5', '114', '171', '19', '33', '23', '22', '23'), +('4', '3', '6', '131', '195', '19', '34', '24', '23', '24'), +('4', '3', '7', '148', '220', '19', '35', '25', '23', '24'), +('4', '3', '8', '165', '246', '20', '36', '26', '24', '25'), +('4', '3', '9', '182', '273', '20', '38', '27', '24', '26'), +('4', '3', '10', '199', '301', '21', '39', '27', '25', '26'), +('4', '3', '11', '216', '330', '21', '40', '28', '25', '27'), +('4', '3', '12', '233', '360', '22', '42', '29', '26', '28'), +('4', '3', '13', '250', '391', '22', '43', '30', '27', '28'), +('4', '3', '14', '268', '423', '23', '44', '31', '27', '29'), +('4', '3', '15', '287', '456', '23', '46', '32', '28', '29'), +('4', '3', '16', '307', '490', '24', '47', '33', '28', '30'), +('4', '3', '17', '328', '525', '24', '48', '34', '29', '31'), +('4', '3', '18', '350', '561', '25', '50', '35', '30', '32'), +('4', '3', '19', '373', '598', '25', '51', '36', '30', '32'), +('4', '3', '20', '397', '636', '26', '53', '37', '31', '33'), +('4', '3', '21', '422', '675', '26', '54', '38', '32', '34'), +('4', '3', '22', '448', '715', '27', '56', '39', '32', '34'), +('4', '3', '23', '475', '756', '27', '57', '40', '33', '35'), +('4', '3', '24', '503', '798', '28', '59', '41', '34', '36'), +('4', '3', '25', '532', '841', '28', '60', '42', '34', '37'), +('4', '3', '26', '562', '885', '29', '62', '43', '35', '37'), +('4', '3', '27', '593', '930', '29', '64', '44', '36', '38'), +('4', '3', '28', '625', '975', '30', '65', '45', '36', '39'), +('4', '3', '29', '658', '1020', '30', '67', '46', '37', '40'), +('4', '3', '30', '692', '1065', '31', '69', '47', '38', '40'), +('4', '3', '31', '727', '1110', '31', '70', '49', '39', '41'), +('4', '3', '32', '763', '1155', '32', '72', '50', '39', '42'), +('4', '3', '33', '800', '1200', '33', '74', '51', '40', '43'), +('4', '3', '34', '838', '1245', '33', '75', '52', '41', '44'), +('4', '3', '35', '877', '1290', '34', '77', '53', '42', '45'), +('4', '3', '36', '917', '1335', '35', '79', '55', '43', '46'), +('4', '3', '37', '958', '1380', '35', '81', '56', '43', '46'), +('4', '3', '38', '1000', '1425', '36', '83', '57', '44', '47'), +('4', '3', '39', '1043', '1470', '36', '85', '58', '45', '48'), +('4', '3', '40', '1087', '1515', '37', '86', '60', '46', '49'), +('4', '3', '41', '1132', '1560', '38', '88', '61', '47', '50'), +('4', '3', '42', '1178', '1605', '38', '90', '62', '47', '51'), +('4', '3', '43', '1225', '1650', '39', '92', '63', '48', '52'), +('4', '3', '44', '1273', '1695', '40', '94', '65', '49', '53'), +('4', '3', '45', '1322', '1740', '40', '96', '66', '50', '54'), +('4', '3', '46', '1372', '1785', '41', '98', '68', '51', '55'), +('4', '3', '47', '1423', '1830', '42', '100', '69', '52', '56'), +('4', '3', '48', '1475', '1875', '43', '103', '70', '53', '57'), +('4', '3', '49', '1528', '1920', '43', '105', '72', '54', '58'), +('4', '3', '50', '1582', '1965', '44', '107', '73', '55', '59'), +('4', '3', '51', '1637', '2010', '45', '109', '75', '56', '60'), +('4', '3', '52', '1693', '2055', '46', '111', '76', '57', '61'), +('4', '3', '53', '1750', '2100', '46', '113', '78', '58', '62'), +('4', '3', '54', '1808', '2145', '47', '116', '79', '59', '63'), +('4', '3', '55', '1867', '2190', '48', '118', '81', '60', '64'), +('4', '3', '56', '1927', '2235', '49', '120', '82', '61', '65'), +('4', '3', '57', '1988', '2280', '50', '123', '84', '62', '67'), +('4', '3', '58', '2050', '2325', '50', '125', '86', '63', '68'), +('4', '3', '59', '2113', '2370', '51', '128', '87', '64', '69'), +('4', '3', '60', '2177', '2415', '52', '130', '89', '65', '70'), +('4', '4', '1', '45', '0', '18', '28', '20', '20', '20'), +('4', '4', '2', '62', '0', '19', '29', '21', '20', '20'), +('4', '4', '3', '79', '0', '19', '30', '21', '20', '21'), +('4', '4', '4', '96', '0', '20', '32', '22', '21', '21'), +('4', '4', '5', '113', '0', '21', '33', '23', '21', '21'), +('4', '4', '6', '130', '0', '21', '34', '23', '21', '22'), +('4', '4', '7', '147', '0', '22', '36', '24', '21', '22'), +('4', '4', '8', '164', '0', '23', '37', '24', '21', '22'), +('4', '4', '9', '181', '0', '24', '38', '25', '21', '23'), +('4', '4', '10', '198', '0', '24', '40', '26', '22', '23'), +('4', '4', '11', '215', '0', '25', '41', '27', '22', '24'), +('4', '4', '12', '232', '0', '26', '42', '27', '22', '24'), +('4', '4', '13', '249', '0', '27', '44', '28', '22', '24'), +('4', '4', '14', '266', '0', '27', '45', '29', '22', '25'), +('4', '4', '15', '283', '0', '28', '47', '29', '23', '25'), +('4', '4', '16', '301', '0', '29', '48', '30', '23', '26'), +('4', '4', '17', '320', '0', '30', '49', '31', '23', '26'), +('4', '4', '18', '340', '0', '31', '51', '32', '23', '26'), +('4', '4', '19', '361', '0', '32', '53', '32', '23', '27'), +('4', '4', '20', '383', '0', '32', '54', '33', '24', '27'), +('4', '4', '21', '406', '0', '33', '56', '34', '24', '28'), +('4', '4', '22', '430', '0', '34', '57', '35', '24', '28'), +('4', '4', '23', '455', '0', '35', '59', '36', '24', '29'), +('4', '4', '24', '481', '0', '36', '60', '36', '25', '29'), +('4', '4', '25', '508', '0', '37', '62', '37', '25', '30'), +('4', '4', '26', '536', '0', '38', '64', '38', '25', '30'), +('4', '4', '27', '565', '0', '39', '65', '39', '25', '30'), +('4', '4', '28', '595', '0', '40', '67', '40', '25', '31'), +('4', '4', '29', '626', '0', '40', '69', '41', '26', '31'), +('4', '4', '30', '658', '0', '41', '71', '41', '26', '32'), +('4', '4', '31', '691', '0', '42', '72', '42', '26', '32'), +('4', '4', '32', '725', '0', '43', '74', '43', '26', '33'), +('4', '4', '33', '760', '0', '44', '76', '44', '27', '33'), +('4', '4', '34', '796', '0', '45', '78', '45', '27', '34'), +('4', '4', '35', '833', '0', '46', '80', '46', '27', '34'), +('4', '4', '36', '871', '0', '48', '82', '47', '28', '35'), +('4', '4', '37', '910', '0', '49', '83', '48', '28', '36'), +('4', '4', '38', '950', '0', '50', '85', '49', '28', '36'), +('4', '4', '39', '991', '0', '51', '87', '50', '28', '37'), +('4', '4', '40', '1033', '0', '52', '89', '51', '29', '37'), +('4', '4', '41', '1076', '0', '53', '91', '52', '29', '38'), +('4', '4', '42', '1120', '0', '54', '93', '53', '29', '38'), +('4', '4', '43', '1165', '0', '55', '95', '54', '29', '39'), +('4', '4', '44', '1211', '0', '56', '98', '55', '30', '39'), +('4', '4', '45', '1258', '0', '58', '100', '56', '30', '40'), +('4', '4', '46', '1306', '0', '59', '102', '57', '30', '41'), +('4', '4', '47', '1355', '0', '60', '104', '58', '31', '41'), +('4', '4', '48', '1405', '0', '61', '106', '59', '31', '42'), +('4', '4', '49', '1456', '0', '62', '108', '61', '31', '43'), +('4', '4', '50', '1508', '0', '64', '111', '62', '32', '43'), +('4', '4', '51', '1561', '0', '65', '113', '63', '32', '44'), +('4', '4', '52', '1615', '0', '66', '115', '64', '32', '44'), +('4', '4', '53', '1670', '0', '67', '118', '65', '33', '45'), +('4', '4', '54', '1726', '0', '69', '120', '66', '33', '46'), +('4', '4', '55', '1783', '0', '70', '122', '68', '33', '46'), +('4', '4', '56', '1841', '0', '71', '125', '69', '34', '47'), +('4', '4', '57', '1900', '0', '73', '127', '70', '34', '48'), +('4', '4', '58', '1960', '0', '74', '130', '71', '34', '49'), +('4', '4', '59', '2021', '0', '76', '132', '73', '35', '49'), +('4', '4', '60', '2083', '0', '77', '135', '74', '35', '50'), +('4', '5', '1', '51', '160', '17', '25', '19', '23', '22'), +('4', '5', '2', '66', '184', '17', '25', '19', '23', '24'), +('4', '5', '3', '72', '209', '17', '25', '20', '24', '25'), +('4', '5', '4', '87', '235', '18', '26', '20', '25', '27'), +('4', '5', '5', '102', '262', '18', '26', '20', '27', '28'), +('4', '5', '6', '117', '290', '18', '26', '21', '28', '29'), +('4', '5', '7', '132', '319', '18', '26', '21', '29', '30'), +('4', '5', '8', '147', '349', '18', '27', '21', '30', '31'), +('4', '5', '9', '162', '380', '18', '27', '22', '31', '33'), +('4', '5', '10', '177', '427', '19', '27', '22', '33', '34'), +('4', '5', '11', '192', '445', '19', '27', '23', '34', '35'), +('4', '5', '12', '207', '479', '19', '28', '23', '35', '37'), +('4', '5', '13', '222', '514', '19', '28', '23', '36', '38'), +('4', '5', '14', '237', '550', '19', '28', '24', '38', '39'), +('4', '5', '15', '252', '587', '20', '28', '24', '39', '41'), +('4', '5', '16', '267', '625', '20', '29', '25', '40', '42'), +('4', '5', '17', '282', '679', '20', '29', '25', '42', '43'), +('4', '5', '18', '297', '704', '20', '29', '25', '43', '45'), +('4', '5', '19', '312', '745', '20', '30', '26', '44', '46'), +('4', '5', '20', '327', '787', '21', '30', '26', '46', '48'), +('4', '5', '21', '342', '830', '21', '30', '27', '47', '49'), +('4', '5', '22', '358', '889', '21', '30', '27', '49', '51'), +('4', '5', '23', '375', '919', '21', '31', '28', '50', '52'), +('4', '5', '24', '393', '980', '22', '31', '28', '52', '54'), +('4', '5', '25', '412', '1012', '22', '31', '29', '53', '55'), +('4', '5', '26', '432', '1075', '22', '32', '29', '55', '57'), +('4', '5', '27', '453', '1109', '22', '32', '29', '56', '59'), +('4', '5', '28', '475', '1174', '22', '32', '30', '58', '60'), +('4', '5', '29', '498', '1210', '23', '33', '30', '59', '62'), +('4', '5', '30', '522', '1262', '23', '33', '31', '61', '64'), +('4', '5', '31', '547', '1330', '23', '33', '31', '63', '65'), +('4', '5', '32', '573', '1369', '23', '34', '32', '64', '67'), +('4', '5', '33', '600', '1438', '24', '34', '32', '66', '69'), +('4', '5', '34', '628', '1492', '24', '34', '33', '68', '70'), +('4', '5', '35', '657', '1531', '24', '35', '33', '69', '72'), +('4', '5', '36', '687', '1585', '25', '35', '34', '71', '74'), +('4', '5', '37', '718', '1654', '25', '35', '35', '73', '76'), +('4', '5', '38', '750', '1708', '25', '36', '35', '75', '78'), +('4', '5', '39', '783', '1747', '25', '36', '36', '76', '80'), +('4', '5', '40', '817', '1801', '26', '36', '36', '78', '81'), +('4', '5', '41', '852', '1870', '26', '37', '37', '80', '83'), +('4', '5', '42', '888', '1924', '26', '37', '37', '82', '85'), +('4', '5', '43', '925', '1978', '26', '38', '38', '84', '87'), +('4', '5', '44', '963', '2032', '27', '38', '38', '86', '89'), +('4', '5', '45', '1002', '2086', '27', '38', '39', '88', '91'), +('4', '5', '46', '1042', '2140', '27', '39', '40', '90', '93'), +('4', '5', '47', '1083', '2194', '28', '39', '40', '92', '95'), +('4', '5', '48', '1125', '2248', '28', '40', '41', '94', '98'), +('4', '5', '49', '1168', '2302', '28', '40', '42', '96', '100'), +('4', '5', '50', '1212', '2356', '29', '40', '42', '98', '102'), +('4', '5', '51', '1257', '2410', '29', '41', '43', '100', '104'), +('4', '5', '52', '1303', '2464', '29', '41', '43', '102', '106'), +('4', '5', '53', '1350', '2518', '30', '42', '44', '104', '108'), +('4', '5', '54', '1398', '2572', '30', '42', '45', '106', '111'), +('4', '5', '55', '1447', '2626', '30', '43', '45', '109', '113'), +('4', '5', '56', '1497', '2680', '31', '43', '46', '111', '115'), +('4', '5', '57', '1548', '2734', '31', '44', '47', '113', '118'), +('4', '5', '58', '1600', '2788', '31', '44', '48', '115', '120'), +('4', '5', '59', '1653', '2842', '32', '45', '48', '118', '123'), +('4', '5', '60', '1707', '2896', '32', '45', '49', '120', '125'), +('4', '11', '1', '53', '100', '18', '25', '19', '22', '22'), +('4', '11', '2', '61', '122', '19', '25', '20', '23', '23'), +('4', '11', '3', '78', '145', '19', '26', '20', '24', '24'), +('4', '11', '4', '95', '169', '20', '26', '21', '25', '25'), +('4', '11', '5', '112', '194', '20', '27', '21', '26', '26'), +('4', '11', '6', '129', '220', '21', '27', '22', '27', '27'), +('4', '11', '7', '146', '247', '21', '28', '23', '28', '28'), +('4', '11', '8', '163', '260', '22', '28', '23', '28', '29'), +('4', '11', '9', '180', '289', '22', '29', '24', '29', '30'), +('4', '11', '10', '197', '319', '23', '29', '24', '30', '31'), +('4', '11', '11', '214', '350', '23', '30', '25', '31', '33'), +('4', '11', '12', '231', '382', '24', '30', '26', '32', '34'), +('4', '11', '13', '248', '415', '24', '31', '26', '33', '35'), +('4', '11', '14', '265', '449', '25', '31', '27', '34', '36'), +('4', '11', '15', '282', '499', '26', '32', '28', '36', '37'), +('4', '11', '16', '299', '535', '26', '32', '28', '37', '38'), +('4', '11', '17', '316', '572', '27', '33', '29', '38', '40'), +('4', '11', '18', '334', '610', '27', '34', '30', '39', '41'), +('4', '11', '19', '353', '649', '28', '34', '30', '40', '42'), +('4', '11', '20', '373', '689', '29', '35', '31', '41', '43'), +('4', '11', '21', '394', '730', '29', '35', '32', '42', '45'), +('4', '11', '22', '416', '757', '30', '36', '33', '43', '46'), +('4', '11', '23', '439', '800', '31', '37', '33', '44', '47'), +('4', '11', '24', '463', '859', '31', '37', '34', '46', '49'), +('4', '11', '25', '488', '904', '32', '38', '35', '47', '50'), +('4', '11', '26', '514', '949', '33', '38', '36', '48', '51'), +('4', '11', '27', '541', '979', '33', '39', '36', '49', '53'), +('4', '11', '28', '569', '1024', '34', '40', '37', '50', '54'), +('4', '11', '29', '598', '1084', '35', '40', '38', '52', '56'), +('4', '11', '30', '628', '1129', '35', '41', '39', '53', '57'), +('4', '11', '31', '659', '1159', '36', '42', '40', '54', '58'), +('4', '11', '32', '691', '1219', '37', '42', '41', '56', '60'), +('4', '11', '33', '724', '1264', '38', '43', '41', '57', '61'), +('4', '11', '34', '758', '1294', '38', '44', '42', '58', '63'), +('4', '11', '35', '793', '1354', '39', '44', '43', '60', '64'), +('4', '11', '36', '829', '1384', '40', '45', '44', '61', '66'), +('4', '11', '37', '866', '1429', '41', '46', '45', '62', '68'), +('4', '11', '38', '904', '1489', '42', '46', '46', '64', '69'), +('4', '11', '39', '943', '1519', '42', '47', '47', '65', '71'), +('4', '11', '40', '983', '1579', '43', '48', '48', '67', '72'), +('4', '11', '41', '1024', '1609', '44', '49', '49', '68', '74'), +('4', '11', '42', '1066', '1669', '45', '49', '50', '70', '76'), +('4', '11', '43', '1109', '1699', '46', '50', '51', '71', '77'), +('4', '11', '44', '1153', '1759', '47', '51', '51', '73', '79'), +('4', '11', '45', '1198', '1789', '47', '52', '52', '74', '81'), +('4', '11', '46', '1244', '1849', '48', '53', '53', '76', '83'), +('4', '11', '47', '1291', '1879', '49', '53', '55', '77', '84'), +('4', '11', '48', '1339', '1924', '50', '54', '56', '79', '86'), +('4', '11', '49', '1388', '1984', '51', '55', '57', '81', '88'), +('4', '11', '50', '1438', '2014', '52', '56', '58', '82', '90'), +('4', '11', '51', '1489', '2059', '53', '57', '59', '84', '92'), +('4', '11', '52', '1541', '2119', '54', '58', '60', '86', '94'), +('4', '11', '53', '1594', '2149', '55', '59', '61', '87', '96'), +('4', '11', '54', '1648', '2194', '56', '59', '62', '89', '98'), +('4', '11', '55', '1703', '2239', '57', '60', '63', '91', '100'), +('4', '11', '56', '1759', '2284', '58', '61', '64', '93', '102'), +('4', '11', '57', '1816', '2329', '59', '62', '65', '94', '104'), +('4', '11', '58', '1874', '2374', '60', '63', '67', '96', '106'), +('4', '11', '59', '1933', '2419', '61', '64', '68', '98', '108'), +('4', '11', '60', '1993', '2464', '62', '65', '69', '100', '110'), +('5', '1', '1', '70', '0', '22', '18', '23', '25', '18'), +('5', '1', '2', '89', '0', '23', '19', '24', '18', '25'), +('5', '1', '3', '108', '0', '24', '19', '25', '18', '26'), +('5', '1', '4', '127', '0', '25', '20', '26', '18', '26'), +('5', '1', '5', '146', '0', '27', '21', '27', '18', '26'), +('5', '1', '6', '165', '0', '28', '22', '28', '19', '26'), +('5', '1', '7', '184', '0', '29', '22', '29', '19', '27'), +('5', '1', '8', '203', '0', '30', '23', '30', '19', '27'), +('5', '1', '9', '222', '0', '31', '24', '31', '19', '27'), +('5', '1', '10', '241', '0', '32', '24', '32', '19', '28'), +('5', '1', '11', '260', '0', '34', '25', '34', '19', '28'), +('5', '1', '12', '279', '0', '35', '26', '35', '19', '28'), +('5', '1', '13', '298', '0', '36', '27', '36', '19', '29'), +('5', '1', '14', '318', '0', '38', '28', '37', '20', '29'), +('5', '1', '15', '339', '0', '39', '28', '38', '20', '29'), +('5', '1', '16', '361', '0', '40', '29', '39', '20', '30'), +('5', '1', '17', '384', '0', '41', '30', '41', '20', '30'), +('5', '1', '18', '408', '0', '43', '31', '42', '20', '30'), +('5', '1', '19', '433', '0', '44', '32', '43', '20', '31'), +('5', '1', '20', '459', '0', '46', '33', '44', '20', '31'), +('5', '1', '21', '486', '0', '47', '33', '46', '21', '31'), +('5', '1', '22', '514', '0', '48', '34', '47', '21', '32'), +('5', '1', '23', '543', '0', '50', '35', '48', '21', '32'), +('5', '1', '24', '573', '0', '51', '36', '50', '21', '33'), +('5', '1', '25', '604', '0', '53', '37', '51', '21', '33'), +('5', '1', '26', '636', '0', '54', '38', '52', '21', '33'), +('5', '1', '27', '669', '0', '56', '39', '54', '21', '34'), +('5', '1', '28', '703', '0', '57', '40', '55', '22', '34'), +('5', '1', '29', '738', '0', '59', '41', '57', '22', '35'), +('5', '1', '30', '774', '0', '61', '42', '58', '22', '35'), +('5', '1', '31', '811', '0', '62', '43', '59', '22', '35'), +('5', '1', '32', '849', '0', '64', '44', '61', '22', '36'), +('5', '1', '33', '888', '0', '65', '45', '62', '22', '36'), +('5', '1', '34', '928', '0', '67', '46', '64', '23', '37'), +('5', '1', '35', '969', '0', '69', '47', '65', '23', '37'), +('5', '1', '36', '1011', '0', '71', '48', '67', '23', '38'), +('5', '1', '37', '1055', '0', '72', '49', '69', '23', '38'), +('5', '1', '38', '1101', '0', '74', '50', '70', '23', '38'), +('5', '1', '39', '1149', '0', '76', '51', '72', '24', '39'), +('5', '1', '40', '1199', '0', '78', '52', '73', '24', '39'), +('5', '1', '41', '1251', '0', '79', '54', '75', '24', '40'), +('5', '1', '42', '1305', '0', '81', '55', '77', '24', '40'), +('5', '1', '43', '1361', '0', '83', '56', '78', '24', '41'), +('5', '1', '44', '1419', '0', '85', '57', '80', '24', '41'), +('5', '1', '45', '1479', '0', '87', '58', '82', '25', '42'), +('5', '1', '46', '1541', '0', '89', '59', '84', '25', '42'), +('5', '1', '47', '1605', '0', '91', '61', '85', '25', '43'), +('5', '1', '48', '1671', '0', '93', '62', '87', '25', '43'), +('5', '1', '49', '1739', '0', '95', '63', '89', '26', '44'), +('5', '1', '50', '1809', '0', '97', '64', '91', '26', '44'), +('5', '1', '51', '1881', '0', '99', '66', '93', '26', '45'), +('5', '1', '52', '1955', '0', '101', '67', '95', '26', '45'), +('5', '1', '53', '2031', '0', '103', '68', '97', '26', '46'), +('5', '1', '54', '2109', '0', '105', '70', '99', '27', '47'), +('5', '1', '55', '2189', '0', '108', '71', '101', '27', '47'), +('5', '1', '56', '2271', '0', '110', '72', '103', '27', '48'), +('5', '1', '57', '2355', '0', '112', '74', '105', '27', '48'), +('5', '1', '58', '2441', '0', '114', '75', '107', '28', '49'), +('5', '1', '59', '2529', '0', '117', '77', '109', '28', '49'), +('5', '1', '60', '2619', '0', '119', '78', '111', '28', '50'), +('5', '4', '1', '65', '0', '20', '21', '22', '25', '18'), +('5', '4', '2', '82', '0', '21', '22', '23', '18', '25'), +('5', '4', '3', '99', '0', '21', '23', '23', '18', '26'), +('5', '4', '4', '116', '0', '22', '25', '24', '19', '26'), +('5', '4', '5', '133', '0', '23', '26', '25', '19', '26'), +('5', '4', '6', '150', '0', '23', '27', '25', '19', '27'), +('5', '4', '7', '167', '0', '24', '29', '26', '19', '27'), +('5', '4', '8', '184', '0', '25', '30', '26', '19', '27'), +('5', '4', '9', '201', '0', '26', '31', '27', '19', '28'), +('5', '4', '10', '218', '0', '26', '33', '28', '20', '28'), +('5', '4', '11', '235', '0', '27', '34', '29', '20', '29'), +('5', '4', '12', '252', '0', '28', '35', '29', '20', '29'), +('5', '4', '13', '269', '0', '29', '37', '30', '20', '29'), +('5', '4', '14', '286', '0', '29', '38', '31', '20', '30'), +('5', '4', '15', '303', '0', '30', '40', '31', '21', '30'), +('5', '4', '16', '321', '0', '31', '41', '32', '21', '31'), +('5', '4', '17', '340', '0', '32', '42', '33', '21', '31'), +('5', '4', '18', '360', '0', '33', '44', '34', '21', '31'), +('5', '4', '19', '381', '0', '34', '46', '34', '21', '32'), +('5', '4', '20', '403', '0', '34', '47', '35', '22', '32'), +('5', '4', '21', '426', '0', '35', '49', '36', '22', '33'), +('5', '4', '22', '450', '0', '36', '50', '37', '22', '33'), +('5', '4', '23', '475', '0', '37', '52', '38', '22', '34'), +('5', '4', '24', '501', '0', '38', '53', '38', '23', '34'), +('5', '4', '25', '528', '0', '39', '55', '39', '23', '35'), +('5', '4', '26', '556', '0', '40', '57', '40', '23', '35'), +('5', '4', '27', '585', '0', '41', '58', '41', '23', '35'), +('5', '4', '28', '615', '0', '42', '60', '42', '23', '36'), +('5', '4', '29', '646', '0', '42', '62', '43', '24', '36'), +('5', '4', '30', '678', '0', '43', '64', '43', '24', '37'), +('5', '4', '31', '711', '0', '44', '65', '44', '24', '37'), +('5', '4', '32', '745', '0', '45', '67', '45', '24', '38'), +('5', '4', '33', '780', '0', '46', '69', '46', '25', '38'), +('5', '4', '34', '816', '0', '47', '71', '47', '25', '39'), +('5', '4', '35', '853', '0', '48', '73', '48', '25', '39'), +('5', '4', '36', '891', '0', '50', '75', '49', '26', '40'), +('5', '4', '37', '930', '0', '51', '76', '50', '26', '41'), +('5', '4', '38', '970', '0', '52', '78', '51', '26', '41'), +('5', '4', '39', '1011', '0', '53', '80', '52', '26', '42'), +('5', '4', '40', '1053', '0', '54', '82', '53', '27', '42'), +('5', '4', '41', '1096', '0', '55', '84', '54', '27', '43'), +('5', '4', '42', '1140', '0', '56', '86', '55', '27', '43'), +('5', '4', '43', '1185', '0', '57', '88', '56', '27', '44'), +('5', '4', '44', '1231', '0', '58', '91', '57', '28', '44'), +('5', '4', '45', '1278', '0', '60', '93', '58', '28', '45'), +('5', '4', '46', '1326', '0', '61', '95', '59', '28', '46'), +('5', '4', '47', '1375', '0', '62', '97', '60', '29', '46'), +('5', '4', '48', '1425', '0', '63', '99', '61', '29', '47'), +('5', '4', '49', '1476', '0', '64', '101', '63', '29', '48'), +('5', '4', '50', '1528', '0', '66', '104', '64', '30', '48'), +('5', '4', '51', '1581', '0', '67', '106', '65', '30', '49'), +('5', '4', '52', '1635', '0', '68', '108', '66', '30', '49'), +('5', '4', '53', '1690', '0', '69', '111', '67', '31', '50'), +('5', '4', '54', '1746', '0', '71', '113', '68', '31', '51'), +('5', '4', '55', '1803', '0', '72', '115', '70', '31', '51'), +('5', '4', '56', '1861', '0', '73', '118', '71', '32', '52'), +('5', '4', '57', '1920', '0', '75', '120', '72', '32', '53'), +('5', '4', '58', '1980', '0', '76', '123', '73', '32', '54'), +('5', '4', '59', '2041', '0', '78', '125', '75', '33', '54'), +('5', '4', '60', '2103', '0', '79', '128', '76', '33', '55'), +('5', '5', '1', '62', '130', '19', '18', '21', '28', '20'), +('5', '5', '2', '77', '154', '19', '18', '21', '21', '29'), +('5', '5', '3', '92', '179', '19', '18', '22', '22', '30'), +('5', '5', '4', '107', '205', '20', '19', '22', '23', '32'), +('5', '5', '5', '122', '232', '20', '19', '22', '25', '33'), +('5', '5', '6', '137', '260', '20', '19', '23', '26', '34'), +('5', '5', '7', '152', '289', '20', '19', '23', '27', '35'), +('5', '5', '8', '167', '319', '20', '20', '23', '28', '36'), +('5', '5', '9', '182', '350', '20', '20', '24', '29', '38'), +('5', '5', '10', '197', '397', '21', '20', '24', '31', '39'), +('5', '5', '11', '212', '415', '21', '20', '25', '32', '40'), +('5', '5', '12', '227', '449', '21', '21', '25', '33', '42'), +('5', '5', '13', '242', '484', '21', '21', '25', '34', '43'), +('5', '5', '14', '257', '520', '21', '21', '26', '36', '44'), +('5', '5', '15', '272', '557', '22', '21', '26', '37', '46'), +('5', '5', '16', '287', '595', '22', '22', '27', '38', '47'), +('5', '5', '17', '302', '649', '22', '22', '27', '40', '48'), +('5', '5', '18', '317', '674', '22', '22', '27', '41', '50'), +('5', '5', '19', '332', '715', '22', '23', '28', '42', '51'), +('5', '5', '20', '347', '757', '23', '23', '28', '44', '53'), +('5', '5', '21', '362', '800', '23', '23', '29', '45', '54'), +('5', '5', '22', '378', '859', '23', '23', '29', '47', '56'), +('5', '5', '23', '395', '889', '23', '24', '30', '48', '57'), +('5', '5', '24', '413', '950', '24', '24', '30', '50', '59'), +('5', '5', '25', '432', '982', '24', '24', '31', '51', '60'), +('5', '5', '26', '452', '1045', '24', '25', '31', '53', '62'), +('5', '5', '27', '473', '1079', '24', '25', '31', '54', '64'), +('5', '5', '28', '495', '1144', '24', '25', '32', '56', '65'), +('5', '5', '29', '518', '1180', '25', '26', '32', '57', '67'), +('5', '5', '30', '542', '1232', '25', '26', '33', '59', '69'), +('5', '5', '31', '567', '1300', '25', '26', '33', '61', '70'), +('5', '5', '32', '593', '1339', '25', '27', '34', '62', '72'), +('5', '5', '33', '620', '1408', '26', '27', '34', '64', '74'), +('5', '5', '34', '648', '1462', '26', '27', '35', '66', '75'), +('5', '5', '35', '677', '1501', '26', '28', '35', '67', '77'), +('5', '5', '36', '707', '1555', '27', '28', '36', '69', '79'), +('5', '5', '37', '738', '1624', '27', '28', '37', '71', '81'), +('5', '5', '38', '770', '1678', '27', '29', '37', '73', '83'), +('5', '5', '39', '803', '1717', '27', '29', '38', '74', '85'), +('5', '5', '40', '837', '1771', '28', '29', '38', '76', '86'), +('5', '5', '41', '872', '1840', '28', '30', '39', '78', '88'), +('5', '5', '42', '908', '1894', '28', '30', '39', '80', '90'), +('5', '5', '43', '945', '1948', '28', '31', '40', '82', '92'), +('5', '5', '44', '983', '2002', '29', '31', '40', '84', '94'), +('5', '5', '45', '1022', '2056', '29', '31', '41', '86', '96'), +('5', '5', '46', '1062', '2110', '29', '32', '42', '88', '98'), +('5', '5', '47', '1103', '2164', '30', '32', '42', '90', '100'), +('5', '5', '48', '1145', '2218', '30', '33', '43', '92', '103'), +('5', '5', '49', '1188', '2272', '30', '33', '44', '94', '105'), +('5', '5', '50', '1232', '2326', '31', '33', '44', '96', '107'), +('5', '5', '51', '1277', '2380', '31', '34', '45', '98', '109'), +('5', '5', '52', '1323', '2434', '31', '34', '45', '100', '111'), +('5', '5', '53', '1370', '2488', '32', '35', '46', '102', '113'), +('5', '5', '54', '1418', '2542', '32', '35', '47', '104', '116'), +('5', '5', '55', '1467', '2596', '32', '36', '47', '107', '118'), +('5', '5', '56', '1517', '2650', '33', '36', '48', '109', '120'), +('5', '5', '57', '1568', '2704', '33', '37', '49', '111', '123'), +('5', '5', '58', '1620', '2758', '33', '37', '50', '113', '125'), +('5', '5', '59', '1673', '2812', '34', '38', '50', '116', '128'), +('5', '5', '60', '1727', '2866', '34', '38', '51', '118', '130'), +('5', '8', '1', '62', '135', '19', '18', '21', '27', '21'), +('5', '8', '2', '77', '160', '19', '18', '21', '22', '28'), +('5', '8', '3', '92', '186', '19', '18', '22', '23', '29'), +('5', '8', '4', '107', '213', '19', '19', '22', '25', '30'), +('5', '8', '5', '122', '241', '19', '19', '22', '26', '32'), +('5', '8', '6', '137', '270', '20', '19', '22', '27', '33'), +('5', '8', '7', '152', '300', '20', '19', '23', '28', '34'), +('5', '8', '8', '167', '316', '20', '19', '23', '29', '35'), +('5', '8', '9', '182', '363', '20', '19', '23', '31', '36'), +('5', '8', '10', '197', '396', '20', '20', '24', '32', '38'), +('5', '8', '11', '212', '430', '20', '20', '24', '33', '39'), +('5', '8', '12', '227', '465', '20', '20', '24', '35', '40'), +('5', '8', '13', '242', '501', '20', '20', '25', '36', '41'), +('5', '8', '14', '257', '538', '21', '20', '25', '37', '43'), +('5', '8', '15', '272', '576', '21', '21', '25', '39', '44'), +('5', '8', '16', '287', '615', '21', '21', '26', '40', '45'), +('5', '8', '17', '302', '640', '21', '21', '26', '41', '47'), +('5', '8', '18', '317', '696', '21', '21', '26', '43', '48'), +('5', '8', '19', '332', '723', '21', '21', '27', '44', '49'), +('5', '8', '20', '347', '781', '21', '22', '27', '46', '51'), +('5', '8', '21', '362', '810', '22', '22', '27', '47', '52'), +('5', '8', '22', '377', '870', '22', '22', '28', '49', '54'), +('5', '8', '23', '392', '901', '22', '22', '28', '50', '55'), +('5', '8', '24', '408', '963', '22', '23', '29', '52', '57'), +('5', '8', '25', '425', '996', '22', '23', '29', '53', '58'), +('5', '8', '26', '443', '1060', '22', '23', '29', '55', '60'), +('5', '8', '27', '462', '1110', '22', '23', '30', '57', '61'), +('5', '8', '28', '482', '1146', '23', '23', '30', '58', '63'), +('5', '8', '29', '503', '1212', '23', '24', '31', '60', '64'), +('5', '8', '30', '525', '1263', '23', '24', '31', '62', '66'), +('5', '8', '31', '548', '1299', '23', '24', '31', '63', '68'), +('5', '8', '32', '572', '1365', '23', '24', '32', '65', '69'), +('5', '8', '33', '597', '1416', '23', '25', '32', '67', '71'), +('5', '8', '34', '623', '1452', '24', '25', '33', '68', '73'), +('5', '8', '35', '650', '1503', '24', '25', '33', '70', '74'), +('5', '8', '36', '678', '1554', '24', '26', '34', '72', '76'), +('5', '8', '37', '707', '1620', '24', '26', '34', '74', '78'), +('5', '8', '38', '737', '1671', '24', '26', '34', '76', '80'), +('5', '8', '39', '768', '1722', '25', '26', '35', '78', '81'), +('5', '8', '40', '800', '1758', '25', '27', '35', '79', '83'), +('5', '8', '41', '833', '1809', '25', '27', '36', '81', '85'), +('5', '8', '42', '867', '1860', '25', '27', '36', '83', '87'), +('5', '8', '43', '902', '1911', '25', '27', '37', '85', '89'), +('5', '8', '44', '938', '1962', '25', '28', '37', '87', '91'), +('5', '8', '45', '975', '2013', '26', '28', '38', '89', '93'), +('5', '8', '46', '1013', '2064', '26', '28', '38', '91', '95'), +('5', '8', '47', '1052', '2115', '26', '29', '39', '93', '97'), +('5', '8', '48', '1092', '2181', '26', '29', '39', '96', '99'), +('5', '8', '49', '1133', '2232', '27', '29', '40', '98', '101'), +('5', '8', '50', '1175', '2268', '27', '30', '40', '100', '103'), +('5', '8', '51', '1218', '2319', '27', '30', '41', '102', '105'), +('5', '8', '52', '1262', '2370', '27', '30', '41', '104', '107'), +('5', '8', '53', '1307', '2421', '27', '31', '42', '106', '109'), +('5', '8', '54', '1353', '2472', '28', '31', '43', '109', '111'), +('5', '8', '55', '1400', '2523', '28', '31', '43', '111', '114'), +('5', '8', '56', '1448', '2574', '28', '32', '44', '113', '116'), +('5', '8', '57', '1497', '2625', '28', '32', '44', '116', '118'), +('5', '8', '58', '1547', '2676', '29', '32', '45', '118', '120'), +('5', '8', '59', '1598', '2727', '29', '33', '45', '121', '123'), +('5', '8', '60', '1650', '2778', '29', '33', '46', '123', '125'), +('5', '9', '1', '63', '110', '19', '18', '22', '27', '20'), +('5', '9', '2', '78', '133', '19', '18', '23', '21', '28'), +('5', '9', '3', '93', '157', '20', '19', '23', '22', '29'), +('5', '9', '4', '108', '182', '20', '19', '24', '23', '30'), +('5', '9', '5', '123', '208', '20', '19', '24', '24', '31'), +('5', '9', '6', '138', '235', '20', '20', '25', '25', '32'), +('5', '9', '7', '153', '263', '21', '20', '25', '26', '34'), +('5', '9', '8', '168', '292', '21', '20', '26', '27', '35'), +('5', '9', '9', '183', '322', '21', '21', '26', '28', '36'), +('5', '9', '10', '198', '353', '22', '21', '27', '29', '37'), +('5', '9', '11', '213', '385', '22', '22', '27', '31', '38'), +('5', '9', '12', '228', '418', '22', '22', '28', '32', '39'), +('5', '9', '13', '243', '452', '23', '22', '28', '33', '41'), +('5', '9', '14', '258', '487', '23', '23', '29', '34', '42'), +('5', '9', '15', '273', '523', '23', '23', '30', '35', '43'), +('5', '9', '16', '288', '560', '24', '24', '30', '36', '44'), +('5', '9', '17', '303', '598', '24', '24', '31', '38', '46'), +('5', '9', '18', '319', '637', '24', '24', '31', '39', '47'), +('5', '9', '19', '336', '677', '25', '25', '32', '40', '48'), +('5', '9', '20', '354', '718', '25', '25', '33', '41', '50'), +('5', '9', '21', '373', '760', '25', '26', '33', '43', '51'), +('5', '9', '22', '393', '803', '26', '26', '34', '44', '52'), +('5', '9', '23', '414', '847', '26', '27', '35', '45', '54'), +('5', '9', '24', '436', '892', '27', '27', '35', '47', '55'), +('5', '9', '25', '459', '938', '27', '28', '36', '48', '57'), +('5', '9', '26', '483', '985', '27', '28', '37', '49', '58'), +('5', '9', '27', '508', '1033', '28', '28', '37', '51', '59'), +('5', '9', '28', '534', '1082', '28', '29', '38', '52', '61'), +('5', '9', '29', '561', '1132', '29', '29', '39', '54', '62'), +('5', '9', '30', '589', '1183', '29', '30', '39', '55', '64'), +('5', '9', '31', '618', '1234', '29', '30', '40', '56', '66'), +('5', '9', '32', '648', '1285', '30', '31', '41', '58', '67'), +('5', '9', '33', '679', '1336', '30', '31', '42', '59', '69'), +('5', '9', '34', '711', '1387', '31', '32', '42', '61', '70'), +('5', '9', '35', '744', '1438', '31', '32', '43', '62', '72'), +('5', '9', '36', '768', '1489', '32', '33', '43', '64', '75'), +('5', '9', '37', '813', '1540', '32', '34', '45', '66', '75'), +('5', '9', '38', '849', '1591', '32', '34', '46', '67', '77'), +('5', '9', '39', '886', '1642', '33', '35', '46', '69', '79'), +('5', '9', '40', '924', '1693', '33', '35', '47', '70', '80'), +('5', '9', '41', '963', '1744', '34', '36', '48', '72', '82'), +('5', '9', '42', '993', '1795', '34', '36', '48', '74', '85'), +('5', '9', '43', '1044', '1846', '35', '37', '50', '75', '86'), +('5', '9', '44', '1086', '1897', '35', '37', '51', '77', '87'), +('5', '9', '45', '1129', '1948', '36', '38', '51', '79', '89'), +('5', '9', '46', '1173', '1999', '36', '39', '52', '81', '90'), +('5', '9', '47', '1218', '2050', '37', '39', '53', '82', '93'), +('5', '9', '48', '1264', '2101', '37', '40', '54', '84', '95'), +('5', '9', '49', '1311', '2152', '38', '41', '55', '86', '96'), +('5', '9', '50', '1339', '2203', '38', '41', '56', '88', '99'), +('5', '9', '51', '1398', '2254', '39', '42', '57', '90', '101'), +('5', '9', '52', '1458', '2305', '39', '42', '58', '92', '103'), +('5', '9', '53', '1509', '2356', '40', '43', '59', '94', '105'), +('5', '9', '54', '1551', '2407', '41', '44', '60', '96', '107'), +('5', '9', '55', '1594', '2458', '41', '44', '60', '98', '110'), +('5', '9', '56', '1668', '2509', '42', '45', '62', '100', '111'), +('5', '9', '57', '1723', '2560', '42', '46', '63', '102', '113'), +('5', '9', '58', '1769', '2611', '43', '47', '63', '104', '116'), +('5', '9', '59', '1836', '2662', '43', '47', '65', '106', '118'), +('5', '9', '60', '1894', '2713', '44', '48', '66', '108', '120'), +('6', '1', '1', '84', '0', '28', '15', '24', '22', '15'), +('6', '1', '2', '103', '0', '29', '16', '25', '15', '22'), +('6', '1', '3', '123', '0', '30', '16', '26', '15', '23'), +('6', '1', '4', '144', '0', '31', '17', '27', '15', '23'), +('6', '1', '5', '163', '0', '33', '18', '28', '15', '23'), +('6', '1', '6', '183', '0', '34', '19', '29', '16', '23'), +('6', '1', '7', '204', '0', '35', '19', '30', '16', '24'), +('6', '1', '8', '223', '0', '36', '20', '31', '16', '24'), +('6', '1', '9', '244', '0', '37', '21', '32', '16', '24'), +('6', '1', '10', '264', '0', '38', '21', '33', '16', '25'), +('6', '1', '11', '283', '0', '40', '22', '35', '16', '25'), +('6', '1', '12', '302', '0', '41', '23', '36', '16', '25'), +('6', '1', '13', '322', '0', '42', '24', '37', '16', '26'), +('6', '1', '14', '344', '0', '44', '25', '38', '17', '26'), +('6', '1', '15', '365', '0', '45', '25', '39', '17', '26'), +('6', '1', '16', '390', '0', '46', '26', '40', '17', '27'), +('6', '1', '17', '414', '0', '47', '27', '42', '17', '27'), +('6', '1', '18', '438', '0', '49', '28', '43', '17', '27'), +('6', '1', '19', '466', '0', '50', '29', '44', '17', '28'), +('6', '1', '20', '491', '0', '52', '30', '45', '17', '28'), +('6', '1', '21', '520', '0', '53', '30', '47', '18', '28'), +('6', '1', '22', '550', '0', '54', '31', '48', '18', '29'), +('6', '1', '23', '580', '0', '56', '32', '49', '18', '29'), +('6', '1', '24', '611', '0', '57', '33', '51', '18', '30'), +('6', '1', '25', '645', '0', '59', '34', '52', '18', '30'), +('6', '1', '26', '677', '0', '60', '35', '53', '18', '30'), +('6', '1', '27', '713', '0', '62', '36', '55', '18', '31'), +('6', '1', '28', '748', '0', '63', '37', '56', '19', '31'), +('6', '1', '29', '785', '0', '65', '38', '58', '19', '32'), +('6', '1', '30', '824', '0', '67', '39', '59', '19', '32'), +('6', '1', '31', '861', '0', '68', '40', '60', '19', '32'), +('6', '1', '32', '902', '0', '70', '41', '62', '19', '33'), +('6', '1', '33', '942', '0', '71', '42', '63', '19', '33'), +('6', '1', '34', '984', '0', '73', '43', '65', '20', '34'), +('6', '1', '35', '1028', '0', '75', '44', '66', '20', '34'), +('6', '1', '36', '1071', '0', '77', '45', '68', '20', '35'), +('6', '1', '37', '1117', '0', '78', '46', '70', '20', '35'), +('6', '1', '38', '1167', '0', '80', '47', '71', '20', '35'), +('6', '1', '39', '1217', '0', '82', '48', '73', '21', '36'), +('6', '1', '40', '1268', '0', '84', '49', '74', '21', '36'), +('6', '1', '41', '1324', '0', '85', '51', '76', '21', '37'), +('6', '1', '42', '1381', '0', '87', '52', '78', '21', '37'), +('6', '1', '43', '1440', '0', '89', '53', '79', '21', '38'), +('6', '1', '44', '1500', '0', '91', '54', '81', '21', '38'), +('6', '1', '45', '1563', '0', '93', '55', '83', '22', '39'), +('6', '1', '46', '1629', '0', '95', '56', '85', '22', '39'), +('6', '1', '47', '1696', '0', '97', '58', '86', '22', '40'), +('6', '1', '48', '1764', '0', '99', '59', '88', '22', '40'), +('6', '1', '49', '1836', '0', '101', '60', '90', '23', '41'), +('6', '1', '50', '1910', '0', '103', '61', '92', '23', '41'), +('6', '1', '51', '1986', '0', '105', '63', '94', '23', '42'), +('6', '1', '52', '2062', '0', '107', '64', '96', '23', '42'), +('6', '1', '53', '2142', '0', '109', '65', '98', '23', '43'), +('6', '1', '54', '2225', '0', '111', '67', '100', '24', '44'), +('6', '1', '55', '2309', '0', '114', '68', '102', '24', '44'), +('6', '1', '56', '2395', '0', '116', '69', '104', '24', '45'), +('6', '1', '57', '2483', '0', '118', '71', '106', '24', '45'), +('6', '1', '58', '2574', '0', '120', '72', '108', '25', '46'), +('6', '1', '59', '2666', '0', '123', '74', '110', '25', '46'), +('6', '1', '60', '2760', '0', '125', '75', '112', '25', '47'), +('6', '3', '1', '80', '80', '25', '18', '23', '23', '15'), +('6', '3', '2', '97', '86', '25', '19', '24', '16', '24'), +('6', '3', '3', '115', '107', '26', '20', '25', '16', '24'), +('6', '3', '4', '133', '115', '26', '22', '25', '17', '25'), +('6', '3', '5', '151', '138', '27', '23', '26', '17', '25'), +('6', '3', '6', '168', '148', '27', '24', '27', '18', '26'), +('6', '3', '7', '186', '173', '27', '25', '28', '18', '26'), +('6', '3', '8', '204', '185', '28', '26', '29', '19', '27'), +('6', '3', '9', '223', '212', '28', '28', '30', '19', '28'), +('6', '3', '10', '239', '226', '29', '29', '30', '20', '28'), +('6', '3', '11', '257', '255', '29', '30', '31', '20', '29'), +('6', '3', '12', '275', '285', '30', '32', '32', '21', '30'), +('6', '3', '13', '294', '316', '30', '33', '33', '22', '30'), +('6', '3', '14', '312', '348', '31', '34', '34', '22', '31'), +('6', '3', '15', '333', '381', '31', '36', '35', '23', '31'), +('6', '3', '16', '354', '415', '32', '37', '36', '23', '32'), +('6', '3', '17', '375', '450', '32', '38', '37', '24', '33'), +('6', '3', '18', '399', '486', '33', '40', '38', '25', '34'), +('6', '3', '19', '424', '523', '33', '41', '39', '25', '34'), +('6', '3', '20', '448', '561', '34', '43', '40', '26', '35'), +('6', '3', '21', '475', '600', '34', '44', '41', '27', '36'), +('6', '3', '22', '501', '640', '35', '46', '42', '27', '36'), +('6', '3', '23', '530', '681', '35', '47', '43', '28', '37'), +('6', '3', '24', '559', '723', '36', '49', '44', '29', '38'), +('6', '3', '25', '590', '766', '36', '50', '45', '29', '39'), +('6', '3', '26', '622', '810', '37', '52', '46', '30', '39'), +('6', '3', '27', '653', '855', '37', '54', '47', '31', '40'), +('6', '3', '28', '687', '900', '38', '55', '48', '31', '41'), +('6', '3', '29', '722', '945', '38', '57', '49', '32', '42'), +('6', '3', '30', '758', '990', '39', '59', '50', '33', '42'), +('6', '3', '31', '795', '1035', '39', '60', '52', '34', '43'), +('6', '3', '32', '832', '1080', '40', '62', '53', '34', '44'), +('6', '3', '33', '871', '1125', '41', '64', '54', '35', '45'), +('6', '3', '34', '910', '1170', '41', '65', '55', '36', '46'), +('6', '3', '35', '952', '1215', '42', '67', '56', '37', '47'), +('6', '3', '36', '994', '1260', '43', '69', '58', '38', '48'), +('6', '3', '37', '1036', '1305', '43', '71', '59', '38', '48'), +('6', '3', '38', '1082', '1350', '44', '73', '60', '39', '49'), +('6', '3', '39', '1126', '1395', '44', '75', '61', '40', '50'), +('6', '3', '40', '1172', '1440', '45', '76', '63', '41', '51'), +('6', '3', '41', '1221', '1485', '46', '78', '64', '42', '52'), +('6', '3', '42', '1268', '1530', '46', '80', '65', '42', '53'), +('6', '3', '43', '1318', '1575', '47', '82', '66', '43', '54'), +('6', '3', '44', '1368', '1620', '48', '84', '68', '44', '55'), +('6', '3', '45', '1419', '1665', '48', '86', '69', '45', '56'), +('6', '3', '46', '1473', '1710', '49', '88', '71', '46', '57'), +('6', '3', '47', '1525', '1755', '50', '90', '72', '47', '58'), +('6', '3', '48', '1580', '1800', '51', '93', '73', '48', '59'), +('6', '3', '49', '1636', '1845', '51', '95', '75', '49', '60'), +('6', '3', '50', '1692', '1890', '52', '97', '76', '50', '61'), +('6', '3', '51', '1750', '1935', '53', '99', '78', '51', '62'), +('6', '3', '52', '1809', '1980', '54', '101', '79', '52', '63'), +('6', '3', '53', '1869', '2025', '54', '103', '81', '53', '64'), +('6', '3', '54', '1930', '2070', '55', '106', '82', '54', '65'), +('6', '3', '55', '1991', '2115', '56', '108', '84', '55', '66'), +('6', '3', '56', '2054', '2160', '57', '110', '85', '56', '67'), +('6', '3', '57', '2119', '2205', '58', '113', '87', '57', '69'), +('6', '3', '58', '2184', '2250', '58', '115', '89', '58', '70'), +('6', '3', '59', '2250', '2295', '59', '118', '90', '59', '71'), +('6', '3', '60', '2318', '2340', '60', '120', '92', '60', '72'), +('6', '7', '1', '81', '71', '26', '15', '23', '24', '16'), +('6', '7', '2', '98', '78', '27', '15', '24', '17', '25'), +('6', '7', '3', '117', '86', '27', '16', '25', '18', '26'), +('6', '7', '4', '133', '109', '28', '16', '26', '18', '27'), +('6', '7', '5', '152', '119', '29', '17', '26', '19', '28'), +('6', '7', '6', '170', '130', '30', '17', '27', '20', '29'), +('6', '7', '7', '188', '156', '31', '17', '28', '21', '30'), +('6', '7', '8', '205', '183', '31', '18', '29', '22', '30'), +('6', '7', '9', '223', '226', '32', '18', '30', '23', '31'), +('6', '7', '10', '241', '240', '33', '19', '31', '23', '32'), +('6', '7', '11', '259', '270', '34', '19', '32', '24', '33'), +('6', '7', '12', '277', '301', '35', '20', '33', '25', '34'), +('6', '7', '13', '294', '333', '35', '20', '34', '26', '35'), +('6', '7', '14', '312', '366', '36', '21', '35', '27', '36'), +('6', '7', '15', '330', '400', '37', '21', '36', '28', '38'), +('6', '7', '16', '349', '435', '38', '22', '37', '29', '39'), +('6', '7', '17', '367', '471', '39', '22', '38', '30', '40'), +('6', '7', '18', '388', '508', '40', '23', '39', '31', '41'), +('6', '7', '19', '409', '546', '41', '23', '40', '32', '42'), +('6', '7', '20', '430', '585', '42', '24', '41', '33', '43'), +('6', '7', '21', '454', '625', '43', '24', '42', '34', '44'), +('6', '7', '22', '477', '666', '43', '25', '43', '35', '45'), +('6', '7', '23', '503', '708', '44', '25', '44', '36', '46'), +('6', '7', '24', '530', '789', '45', '26', '45', '37', '48'), +('6', '7', '25', '556', '795', '46', '26', '47', '38', '49'), +('6', '7', '26', '585', '840', '47', '27', '48', '39', '50'), +('6', '7', '27', '614', '886', '48', '27', '49', '40', '51'), +('6', '7', '28', '645', '933', '49', '28', '50', '41', '52'), +('6', '7', '29', '677', '981', '50', '28', '51', '42', '54'), +('6', '7', '30', '708', '1030', '51', '29', '52', '43', '55'), +('6', '7', '31', '742', '1149', '53', '29', '54', '45', '56'), +('6', '7', '32', '777', '1201', '54', '30', '55', '46', '58'), +('6', '7', '33', '813', '1250', '55', '31', '56', '47', '59'), +('6', '7', '34', '848', '1290', '56', '31', '57', '48', '60'), +('6', '7', '35', '887', '1339', '57', '32', '59', '49', '62'), +('6', '7', '36', '926', '1339', '58', '33', '60', '51', '63'), +('6', '7', '37', '966', '1458', '59', '33', '61', '52', '64'), +('6', '7', '38', '1007', '1471', '60', '34', '63', '53', '66'), +('6', '7', '39', '1049', '1509', '61', '34', '64', '54', '67'), +('6', '7', '40', '1092', '1612', '63', '35', '65', '56', '69'), +('6', '7', '41', '1137', '1663', '64', '36', '67', '57', '70'), +('6', '7', '42', '1181', '1700', '65', '36', '68', '58', '72'), +('6', '7', '43', '1226', '1751', '66', '37', '70', '59', '73'), +('6', '7', '44', '1275', '1818', '68', '38', '71', '61', '75'), +('6', '7', '45', '1323', '1854', '69', '38', '73', '62', '76'), +('6', '7', '46', '1373', '1921', '70', '39', '74', '64', '78'), +('6', '7', '47', '1423', '1972', '71', '40', '76', '65', '79'), +('6', '7', '48', '1474', '2008', '73', '41', '77', '66', '81'), +('6', '7', '49', '1527', '2075', '74', '41', '79', '68', '83'), +('6', '7', '50', '1579', '2111', '75', '42', '80', '69', '84'), +('6', '7', '51', '1634', '2178', '77', '43', '82', '71', '86'), +('6', '7', '52', '1691', '2230', '78', '44', '83', '72', '88'), +('6', '7', '53', '1747', '2281', '80', '44', '85', '74', '89'), +('6', '7', '54', '1805', '2304', '81', '45', '87', '75', '91'), +('6', '7', '55', '1864', '2333', '82', '46', '88', '77', '93'), +('6', '7', '56', '1923', '2384', '84', '47', '90', '78', '95'), +('6', '7', '57', '1983', '2487', '85', '48', '92', '80', '96'), +('6', '7', '58', '2045', '2538', '87', '48', '93', '82', '98'), +('6', '7', '59', '2109', '2565', '88', '49', '95', '83', '100'), +('6', '7', '60', '2174', '2590', '90', '50', '97', '85', '102'), +('6', '11', '1', '78', '67', '26', '15', '22', '24', '17'), +('6', '11', '2', '97', '75', '27', '15', '23', '18', '25'), +('6', '11', '3', '113', '84', '27', '16', '23', '19', '26'), +('6', '11', '4', '132', '94', '28', '16', '24', '20', '27'), +('6', '11', '5', '150', '119', '28', '17', '24', '21', '28'), +('6', '11', '6', '168', '145', '29', '17', '25', '22', '29'), +('6', '11', '7', '185', '172', '29', '18', '26', '23', '30'), +('6', '11', '8', '203', '185', '30', '18', '26', '23', '31'), +('6', '11', '9', '221', '214', '30', '19', '27', '24', '32'), +('6', '11', '10', '239', '244', '31', '19', '27', '25', '33'), +('6', '11', '11', '257', '275', '31', '20', '28', '26', '35'), +('6', '11', '12', '274', '307', '32', '20', '29', '27', '36'), +('6', '11', '13', '292', '340', '32', '21', '29', '28', '37'), +('6', '11', '14', '310', '374', '33', '21', '30', '29', '38'), +('6', '11', '15', '329', '424', '34', '22', '31', '31', '39'), +('6', '11', '16', '347', '460', '34', '22', '31', '32', '40'), +('6', '11', '17', '365', '497', '35', '23', '32', '33', '42'), +('6', '11', '18', '383', '535', '35', '24', '33', '34', '43'), +('6', '11', '19', '402', '574', '36', '24', '33', '35', '44'), +('6', '11', '20', '425', '614', '37', '25', '34', '36', '45'), +('6', '11', '21', '447', '655', '37', '25', '35', '37', '47'), +('6', '11', '22', '470', '682', '38', '26', '36', '38', '48'), +('6', '11', '23', '494', '725', '39', '27', '36', '39', '49'), +('6', '11', '24', '518', '784', '39', '27', '37', '41', '51'), +('6', '11', '25', '544', '829', '40', '28', '38', '42', '52'), +('6', '11', '26', '573', '874', '41', '28', '39', '43', '53'), +('6', '11', '27', '601', '904', '41', '29', '39', '44', '55'), +('6', '11', '28', '630', '949', '42', '30', '40', '45', '56'), +('6', '11', '29', '659', '1009', '43', '30', '41', '47', '58'), +('6', '11', '30', '691', '1054', '43', '31', '42', '48', '59'), +('6', '11', '31', '723', '1084', '44', '32', '43', '49', '60'), +('6', '11', '32', '757', '1144', '45', '32', '44', '51', '62'), +('6', '11', '33', '793', '1189', '46', '33', '44', '52', '63'), +('6', '11', '34', '827', '1219', '46', '34', '45', '53', '65'), +('6', '11', '35', '864', '1279', '47', '34', '46', '55', '66'), +('6', '11', '36', '903', '1309', '48', '35', '47', '56', '68'), +('6', '11', '37', '941', '1354', '49', '36', '48', '57', '70'), +('6', '11', '38', '982', '1414', '50', '36', '49', '59', '71'), +('6', '11', '39', '1022', '1444', '50', '37', '50', '60', '73'), +('6', '11', '40', '1064', '1504', '51', '38', '51', '62', '74'), +('6', '11', '41', '1108', '1534', '52', '39', '52', '63', '76'), +('6', '11', '42', '1151', '1594', '53', '39', '53', '65', '78'), +('6', '11', '43', '1197', '1624', '54', '40', '54', '66', '79'), +('6', '11', '44', '1243', '1684', '55', '41', '54', '68', '81'), +('6', '11', '45', '1290', '1714', '55', '42', '55', '69', '83'), +('6', '11', '46', '1339', '1774', '56', '43', '56', '71', '85'), +('6', '11', '47', '1388', '1804', '57', '43', '58', '72', '86'), +('6', '11', '48', '1437', '1849', '58', '44', '59', '74', '88'), +('6', '11', '49', '1490', '1909', '59', '45', '60', '76', '90'), +('6', '11', '50', '1542', '1939', '60', '46', '61', '77', '92'), +('6', '11', '51', '1596', '1984', '61', '47', '62', '79', '94'), +('6', '11', '52', '1651', '2044', '62', '48', '63', '81', '96'), +('6', '11', '53', '1706', '2074', '63', '49', '64', '82', '98'), +('6', '11', '54', '1763', '2119', '64', '49', '65', '84', '100'), +('6', '11', '55', '1820', '2164', '65', '50', '66', '86', '102'), +('6', '11', '56', '1879', '2209', '66', '51', '67', '88', '104'), +('6', '11', '57', '1940', '2254', '67', '52', '68', '89', '106'), +('6', '11', '58', '2000', '2299', '68', '53', '70', '91', '108'), +('6', '11', '59', '2063', '2344', '69', '54', '71', '93', '110'), +('6', '11', '60', '2125', '2389', '70', '55', '72', '95', '112'), +('7', '1', '1', '50', '0', '18', '23', '21', '20', '24'), +('7', '1', '2', '69', '0', '19', '24', '22', '24', '20'), +('7', '1', '3', '88', '0', '20', '24', '23', '24', '21'), +('7', '1', '4', '107', '0', '21', '25', '24', '24', '21'), +('7', '1', '5', '126', '0', '23', '26', '25', '24', '21'), +('7', '1', '6', '145', '0', '24', '27', '26', '25', '21'), +('7', '1', '7', '164', '0', '25', '27', '27', '25', '22'), +('7', '1', '8', '183', '0', '26', '28', '28', '25', '22'), +('7', '1', '9', '202', '0', '27', '29', '29', '25', '22'), +('7', '1', '10', '221', '0', '28', '29', '30', '25', '23'), +('7', '1', '11', '240', '0', '30', '30', '32', '25', '23'), +('7', '1', '12', '259', '0', '31', '31', '33', '25', '23'), +('7', '1', '13', '278', '0', '32', '32', '34', '25', '24'), +('7', '1', '14', '298', '0', '34', '33', '35', '26', '24'), +('7', '1', '15', '319', '0', '35', '33', '36', '26', '24'), +('7', '1', '16', '341', '0', '36', '34', '37', '26', '25'), +('7', '1', '17', '364', '0', '37', '35', '39', '26', '25'), +('7', '1', '18', '388', '0', '39', '36', '40', '26', '25'), +('7', '1', '19', '413', '0', '40', '37', '41', '26', '26'), +('7', '1', '20', '439', '0', '42', '38', '42', '26', '26'), +('7', '1', '21', '466', '0', '43', '38', '44', '27', '26'), +('7', '1', '22', '494', '0', '44', '39', '45', '27', '27'), +('7', '1', '23', '523', '0', '46', '40', '46', '27', '27'), +('7', '1', '24', '553', '0', '47', '41', '48', '27', '28'), +('7', '1', '25', '584', '0', '49', '42', '49', '27', '28'), +('7', '1', '26', '616', '0', '50', '43', '50', '27', '28'), +('7', '1', '27', '649', '0', '52', '44', '52', '27', '29'), +('7', '1', '28', '683', '0', '53', '45', '53', '28', '29'), +('7', '1', '29', '718', '0', '55', '46', '55', '28', '30'), +('7', '1', '30', '754', '0', '57', '47', '56', '28', '30'), +('7', '1', '31', '791', '0', '58', '48', '57', '28', '30'), +('7', '1', '32', '829', '0', '60', '49', '59', '28', '31'), +('7', '1', '33', '868', '0', '61', '50', '60', '28', '31'), +('7', '1', '34', '908', '0', '63', '51', '62', '29', '32'), +('7', '1', '35', '949', '0', '65', '52', '63', '29', '32'), +('7', '1', '36', '991', '0', '67', '53', '65', '29', '33'), +('7', '1', '37', '1070', '0', '68', '54', '67', '29', '33'), +('7', '1', '38', '1081', '0', '70', '55', '68', '29', '33'), +('7', '1', '39', '1129', '0', '72', '56', '70', '30', '34'), +('7', '1', '40', '1179', '0', '74', '57', '71', '30', '34'), +('7', '1', '41', '1231', '0', '75', '59', '73', '30', '35'), +('7', '1', '42', '1285', '0', '77', '60', '75', '30', '35'), +('7', '1', '43', '1341', '0', '79', '61', '76', '30', '36'), +('7', '1', '44', '1399', '0', '81', '62', '78', '30', '36'), +('7', '1', '45', '1459', '0', '83', '63', '80', '32', '37'), +('7', '1', '46', '1521', '0', '85', '64', '82', '32', '37'), +('7', '1', '47', '1585', '0', '87', '66', '83', '32', '38'), +('7', '1', '48', '1651', '0', '89', '67', '85', '32', '38'), +('7', '1', '49', '1719', '0', '91', '68', '87', '33', '39'), +('7', '1', '50', '1789', '0', '93', '69', '89', '33', '39'), +('7', '1', '51', '1861', '0', '95', '71', '91', '33', '40'), +('7', '1', '52', '1935', '0', '97', '72', '93', '33', '40'), +('7', '1', '53', '2011', '0', '99', '73', '95', '33', '41'), +('7', '1', '54', '2089', '0', '101', '75', '97', '34', '42'), +('7', '1', '55', '2169', '0', '104', '76', '99', '34', '42'), +('7', '1', '56', '2251', '0', '106', '77', '101', '34', '43'), +('7', '1', '57', '2335', '0', '108', '79', '103', '34', '43'), +('7', '1', '58', '2421', '0', '110', '80', '105', '35', '44'), +('7', '1', '59', '2509', '0', '113', '82', '107', '35', '44'), +('7', '1', '60', '2599', '0', '115', '83', '109', '35', '45'), +('7', '4', '1', '45', '0', '16', '26', '20', '20', '24'), +('7', '4', '2', '62', '0', '17', '27', '21', '24', '20'), +('7', '4', '3', '79', '0', '17', '28', '21', '24', '21'), +('7', '4', '4', '96', '0', '18', '30', '22', '25', '21'), +('7', '4', '5', '113', '0', '19', '31', '23', '25', '21'), +('7', '4', '6', '130', '0', '19', '32', '23', '25', '22'), +('7', '4', '7', '147', '0', '20', '34', '24', '25', '22'), +('7', '4', '8', '164', '0', '21', '35', '24', '25', '22'), +('7', '4', '9', '181', '0', '22', '36', '25', '25', '23'), +('7', '4', '10', '198', '0', '22', '38', '26', '26', '23'), +('7', '4', '11', '215', '0', '23', '39', '27', '26', '24'), +('7', '4', '12', '232', '0', '24', '40', '27', '26', '24'), +('7', '4', '13', '249', '0', '25', '42', '28', '26', '24'), +('7', '4', '14', '266', '0', '25', '43', '29', '26', '25'), +('7', '4', '15', '283', '0', '26', '45', '29', '27', '25'), +('7', '4', '16', '301', '0', '27', '46', '30', '27', '26'), +('7', '4', '17', '320', '0', '28', '47', '31', '27', '26'), +('7', '4', '18', '340', '0', '29', '49', '32', '27', '26'), +('7', '4', '19', '361', '0', '30', '51', '32', '27', '27'), +('7', '4', '20', '383', '0', '30', '52', '33', '28', '27'), +('7', '4', '21', '406', '0', '31', '54', '34', '28', '28'), +('7', '4', '22', '430', '0', '32', '55', '35', '28', '28'), +('7', '4', '23', '455', '0', '33', '57', '36', '28', '29'), +('7', '4', '24', '481', '0', '34', '58', '36', '29', '29'), +('7', '4', '25', '508', '0', '35', '60', '37', '29', '30'), +('7', '4', '26', '536', '0', '36', '62', '38', '29', '30'), +('7', '4', '27', '565', '0', '37', '63', '39', '29', '30'), +('7', '4', '28', '595', '0', '38', '65', '40', '29', '31'), +('7', '4', '29', '626', '0', '38', '67', '41', '30', '31'), +('7', '4', '30', '658', '0', '39', '69', '41', '30', '32'), +('7', '4', '31', '691', '0', '40', '70', '42', '30', '32'), +('7', '4', '32', '725', '0', '41', '72', '43', '30', '33'), +('7', '4', '33', '760', '0', '42', '74', '44', '32', '33'), +('7', '4', '34', '796', '0', '43', '76', '45', '32', '34'), +('7', '4', '35', '833', '0', '44', '78', '46', '32', '34'), +('7', '4', '36', '871', '0', '46', '80', '47', '33', '35'), +('7', '4', '37', '910', '0', '47', '81', '48', '33', '36'), +('7', '4', '38', '950', '0', '48', '83', '49', '33', '36'), +('7', '4', '39', '991', '0', '49', '85', '50', '33', '37'), +('7', '4', '40', '1033', '0', '50', '87', '51', '34', '37'), +('7', '4', '41', '1076', '0', '51', '89', '52', '34', '38'), +('7', '4', '42', '1120', '0', '52', '91', '53', '34', '38'), +('7', '4', '43', '1165', '0', '53', '93', '54', '34', '39'), +('7', '4', '44', '1211', '0', '54', '96', '55', '35', '39'), +('7', '4', '45', '1258', '0', '56', '98', '56', '35', '40'), +('7', '4', '46', '1306', '0', '57', '100', '57', '35', '41'), +('7', '4', '47', '1355', '0', '58', '102', '58', '36', '41'), +('7', '4', '48', '1405', '0', '59', '104', '59', '36', '42'), +('7', '4', '49', '1456', '0', '60', '106', '61', '36', '43'), +('7', '4', '50', '1508', '0', '62', '109', '62', '37', '43'), +('7', '4', '51', '1561', '0', '63', '111', '63', '37', '44'), +('7', '4', '52', '1615', '0', '64', '113', '64', '37', '44'), +('7', '4', '53', '1670', '0', '65', '116', '65', '38', '45'), +('7', '4', '54', '1726', '0', '67', '118', '66', '38', '46'), +('7', '4', '55', '1783', '0', '68', '120', '68', '38', '46'), +('7', '4', '56', '1841', '0', '69', '123', '69', '39', '47'), +('7', '4', '57', '1900', '0', '71', '125', '70', '39', '48'), +('7', '4', '58', '1960', '0', '72', '128', '71', '39', '49'), +('7', '4', '59', '2021', '0', '74', '130', '73', '40', '49'), +('7', '4', '60', '2083', '0', '75', '133', '74', '40', '50'), +('7', '8', '1', '51', '255', '15', '23', '19', '22', '27'), +('7', '8', '2', '66', '280', '15', '23', '19', '28', '23'), +('7', '8', '3', '72', '306', '15', '23', '20', '29', '24'), +('7', '8', '4', '87', '333', '15', '24', '20', '32', '25'), +('7', '8', '5', '102', '391', '15', '24', '20', '33', '27'), +('7', '8', '6', '117', '420', '16', '24', '20', '34', '28'), +('7', '8', '7', '132', '450', '16', '24', '21', '35', '29'), +('7', '8', '8', '147', '466', '16', '24', '21', '36', '30'), +('7', '8', '9', '162', '513', '16', '24', '21', '38', '31'), +('7', '8', '10', '177', '546', '16', '25', '22', '39', '33'), +('7', '8', '11', '192', '580', '16', '25', '22', '40', '34'), +('7', '8', '12', '207', '615', '16', '25', '22', '42', '35'), +('7', '8', '13', '222', '636', '16', '25', '23', '43', '36'), +('7', '8', '14', '237', '673', '17', '25', '23', '44', '38'), +('7', '8', '15', '252', '711', '17', '26', '23', '46', '39'), +('7', '8', '16', '267', '750', '17', '26', '24', '47', '40'), +('7', '8', '17', '282', '775', '17', '26', '24', '48', '42'), +('7', '8', '18', '297', '831', '17', '26', '24', '50', '43'), +('7', '8', '19', '312', '858', '17', '26', '25', '51', '44'), +('7', '8', '20', '327', '946', '17', '27', '25', '54', '46'), +('7', '8', '21', '342', '975', '18', '27', '25', '55', '47'), +('7', '8', '22', '357', '1035', '18', '27', '26', '57', '49'), +('7', '8', '23', '372', '1066', '18', '27', '26', '58', '50'), +('7', '8', '24', '388', '1128', '18', '28', '27', '60', '52'), +('7', '8', '25', '405', '1161', '18', '28', '27', '61', '53'), +('7', '8', '26', '423', '1225', '18', '28', '27', '63', '55'), +('7', '8', '27', '442', '1260', '18', '28', '28', '65', '56'), +('7', '8', '28', '462', '1296', '19', '28', '28', '66', '58'), +('7', '8', '29', '483', '1362', '19', '29', '29', '68', '59'), +('7', '8', '30', '505', '1413', '19', '29', '29', '70', '61'), +('7', '8', '31', '528', '1449', '19', '29', '29', '71', '63'), +('7', '8', '32', '552', '1515', '19', '29', '30', '74', '64'), +('7', '8', '33', '577', '1596', '19', '30', '30', '76', '66'), +('7', '8', '34', '603', '1632', '20', '30', '31', '77', '68'), +('7', '8', '35', '630', '1683', '20', '30', '31', '79', '69'), +('7', '8', '36', '658', '1734', '20', '31', '32', '81', '71'), +('7', '8', '37', '687', '1800', '20', '31', '32', '83', '73'), +('7', '8', '38', '717', '1836', '20', '31', '32', '85', '75'), +('7', '8', '39', '748', '1887', '21', '31', '33', '87', '76'), +('7', '8', '40', '780', '1923', '21', '32', '33', '88', '78'), +('7', '8', '41', '813', '1974', '21', '32', '34', '90', '80'), +('7', '8', '42', '847', '2025', '21', '32', '34', '92', '82'), +('7', '8', '43', '882', '2076', '21', '32', '35', '95', '84'), +('7', '8', '44', '918', '2157', '21', '33', '35', '97', '86'), +('7', '8', '45', '955', '2208', '22', '33', '36', '99', '88'), +('7', '8', '46', '993', '2259', '22', '33', '36', '101', '90'), +('7', '8', '47', '1032', '2310', '22', '34', '37', '103', '92'), +('7', '8', '48', '1072', '2361', '22', '34', '37', '106', '94'), +('7', '8', '49', '1113', '2412', '23', '34', '38', '108', '96'), +('7', '8', '50', '1155', '2448', '23', '35', '38', '110', '98'), +('7', '8', '51', '1198', '2499', '23', '35', '39', '112', '100'), +('7', '8', '52', '1242', '2550', '23', '35', '39', '114', '102'), +('7', '8', '53', '1287', '2631', '23', '36', '40', '117', '104'), +('7', '8', '54', '1333', '2682', '24', '36', '41', '120', '106'), +('7', '8', '55', '1380', '2733', '24', '36', '41', '122', '109'), +('7', '8', '56', '1428', '2784', '24', '37', '42', '124', '111'), +('7', '8', '57', '1477', '2820', '24', '37', '42', '127', '113'), +('7', '8', '58', '1527', '2871', '25', '37', '43', '129', '115'), +('7', '8', '59', '1578', '2922', '25', '38', '43', '132', '118'), +('7', '8', '60', '1630', '2973', '25', '38', '44', '133', '120'), +('7', '9', '1', '43', '200', '15', '23', '20', '22', '26'), +('7', '9', '2', '58', '223', '15', '23', '21', '27', '23'), +('7', '9', '3', '73', '247', '16', '24', '21', '28', '24'), +('7', '9', '4', '88', '272', '16', '24', '22', '29', '25'), +('7', '9', '5', '103', '298', '16', '24', '22', '30', '26'), +('7', '9', '6', '118', '325', '16', '25', '23', '32', '27'), +('7', '9', '7', '133', '383', '17', '25', '23', '33', '29'), +('7', '9', '8', '148', '412', '17', '25', '24', '34', '30'), +('7', '9', '9', '163', '442', '17', '26', '24', '35', '31'), +('7', '9', '10', '178', '473', '18', '26', '25', '36', '32'), +('7', '9', '11', '193', '505', '18', '27', '25', '38', '33'), +('7', '9', '12', '208', '538', '18', '27', '26', '39', '34'), +('7', '9', '13', '223', '572', '19', '27', '26', '40', '36'), +('7', '9', '14', '238', '607', '19', '28', '27', '41', '37'), +('7', '9', '15', '253', '643', '19', '28', '28', '42', '38'), +('7', '9', '16', '268', '665', '20', '29', '28', '43', '39'), +('7', '9', '17', '283', '703', '20', '29', '29', '45', '41'), +('7', '9', '18', '299', '742', '20', '29', '29', '46', '42'), +('7', '9', '19', '316', '782', '21', '30', '30', '47', '43'), +('7', '9', '20', '334', '823', '21', '30', '31', '48', '45'), +('7', '9', '21', '353', '865', '21', '31', '31', '50', '46'), +('7', '9', '22', '373', '908', '22', '31', '32', '51', '47'), +('7', '9', '23', '394', '952', '22', '32', '33', '53', '49'), +('7', '9', '24', '416', '1027', '23', '32', '33', '55', '50'), +('7', '9', '25', '439', '1073', '23', '33', '34', '56', '52'), +('7', '9', '26', '463', '1120', '23', '33', '35', '57', '53'), +('7', '9', '27', '488', '1168', '24', '33', '35', '59', '54'), +('7', '9', '28', '514', '1217', '24', '34', '36', '60', '56'), +('7', '9', '29', '541', '1267', '25', '34', '37', '62', '57'), +('7', '9', '30', '569', '1318', '25', '35', '37', '63', '59'), +('7', '9', '31', '588', '1354', '25', '35', '37', '64', '62'), +('7', '9', '32', '628', '1405', '26', '36', '39', '66', '62'), +('7', '9', '33', '659', '1456', '26', '36', '40', '67', '64'), +('7', '9', '34', '691', '1507', '27', '37', '40', '69', '65'), +('7', '9', '35', '724', '1558', '27', '37', '41', '70', '67'), +('7', '9', '36', '758', '1609', '28', '38', '42', '72', '69'), +('7', '9', '37', '793', '1690', '28', '39', '43', '75', '69'), +('7', '9', '38', '829', '1741', '28', '39', '44', '76', '72'), +('7', '9', '39', '866', '1792', '29', '40', '44', '78', '74'), +('7', '9', '40', '904', '1843', '29', '40', '45', '79', '75'), +('7', '9', '41', '943', '1894', '30', '41', '46', '81', '77'), +('7', '9', '42', '983', '1945', '30', '41', '47', '83', '79'), +('7', '9', '43', '1024', '1996', '31', '42', '48', '84', '81'), +('7', '9', '44', '1066', '2032', '31', '42', '49', '86', '82'), +('7', '9', '45', '1109', '2083', '32', '43', '49', '88', '84'), +('7', '9', '46', '1153', '2134', '32', '44', '50', '90', '86'), +('7', '9', '47', '1198', '2185', '33', '44', '51', '91', '88'), +('7', '9', '48', '1234', '2236', '33', '45', '52', '93', '90'), +('7', '9', '49', '1281', '2317', '34', '46', '53', '96', '92'), +('7', '9', '50', '1339', '2368', '34', '46', '54', '98', '93'), +('7', '9', '51', '1388', '2419', '35', '47', '55', '100', '96'), +('7', '9', '52', '1418', '2470', '35', '47', '56', '102', '98'), +('7', '9', '53', '1489', '2521', '36', '48', '57', '104', '100'), +('7', '9', '54', '1541', '2557', '37', '49', '58', '106', '102'), +('7', '9', '55', '1584', '2608', '37', '49', '58', '108', '104'), +('7', '9', '56', '1648', '2659', '38', '50', '60', '110', '106'), +('7', '9', '57', '1683', '2710', '38', '51', '61', '112', '108'), +('7', '9', '58', '1759', '2761', '39', '52', '62', '114', '111'), +('7', '9', '59', '1816', '2842', '39', '52', '63', '117', '111'), +('7', '9', '60', '1874', '2893', '40', '53', '64', '119', '115'), +('8', '1', '1', '70', '0', '24', '22', '23', '21', '16'), +('8', '1', '2', '89', '0', '25', '23', '24', '16', '21'), +('8', '1', '3', '108', '0', '26', '23', '25', '16', '22'), +('8', '1', '4', '127', '0', '27', '24', '26', '16', '22'), +('8', '1', '5', '146', '0', '29', '25', '27', '16', '22'), +('8', '1', '6', '165', '0', '30', '26', '28', '17', '22'), +('8', '1', '7', '184', '0', '31', '26', '29', '17', '23'), +('8', '1', '8', '203', '0', '32', '27', '30', '17', '23'), +('8', '1', '9', '222', '0', '33', '28', '31', '17', '23'), +('8', '1', '10', '241', '0', '34', '28', '32', '17', '24'), +('8', '1', '11', '260', '0', '36', '29', '34', '17', '24'), +('8', '1', '12', '279', '0', '37', '30', '35', '17', '24'), +('8', '1', '13', '298', '0', '38', '31', '36', '17', '25'), +('8', '1', '14', '318', '0', '40', '32', '37', '18', '25'), +('8', '1', '15', '339', '0', '41', '32', '38', '18', '25'), +('8', '1', '16', '361', '0', '42', '33', '39', '18', '26'), +('8', '1', '17', '384', '0', '43', '34', '41', '18', '26'), +('8', '1', '18', '408', '0', '45', '35', '42', '18', '26'), +('8', '1', '19', '433', '0', '46', '36', '43', '18', '27'), +('8', '1', '20', '459', '0', '48', '37', '44', '18', '27'), +('8', '1', '21', '486', '0', '49', '37', '46', '19', '27'), +('8', '1', '22', '514', '0', '50', '38', '47', '19', '28'), +('8', '1', '23', '543', '0', '52', '39', '48', '19', '28'), +('8', '1', '24', '573', '0', '53', '40', '50', '19', '29'), +('8', '1', '25', '604', '0', '55', '41', '51', '19', '29'), +('8', '1', '26', '636', '0', '56', '42', '52', '19', '29'), +('8', '1', '27', '669', '0', '58', '43', '54', '19', '30'), +('8', '1', '28', '703', '0', '59', '44', '55', '20', '30'), +('8', '1', '29', '738', '0', '61', '45', '57', '20', '31'), +('8', '1', '30', '774', '0', '63', '46', '58', '20', '31'), +('8', '1', '31', '811', '0', '64', '47', '59', '20', '31'), +('8', '1', '32', '849', '0', '66', '48', '61', '20', '32'), +('8', '1', '33', '888', '0', '67', '49', '62', '20', '32'), +('8', '1', '34', '928', '0', '69', '50', '64', '21', '33'), +('8', '1', '35', '969', '0', '71', '51', '65', '21', '33'), +('8', '1', '36', '1011', '0', '73', '52', '67', '21', '34'), +('8', '1', '37', '1055', '0', '74', '53', '69', '21', '34'), +('8', '1', '38', '1101', '0', '76', '54', '70', '21', '34'), +('8', '1', '39', '1149', '0', '78', '55', '72', '22', '35'), +('8', '1', '40', '1199', '0', '80', '56', '73', '22', '35'), +('8', '1', '41', '1251', '0', '81', '58', '75', '22', '36'), +('8', '1', '42', '1310', '0', '83', '59', '77', '22', '36'), +('8', '1', '43', '1361', '0', '85', '60', '78', '22', '37'), +('8', '1', '44', '1419', '0', '87', '61', '80', '22', '37'), +('8', '1', '45', '1529', '0', '89', '62', '82', '23', '38'), +('8', '1', '46', '1541', '0', '91', '63', '84', '23', '38'), +('8', '1', '47', '1605', '0', '93', '65', '85', '23', '39'), +('8', '1', '48', '1671', '0', '95', '66', '87', '23', '39'), +('8', '1', '49', '1739', '0', '97', '67', '89', '24', '40'), +('8', '1', '50', '1809', '0', '99', '68', '91', '24', '40'), +('8', '1', '51', '1881', '0', '101', '70', '93', '24', '41'), +('8', '1', '52', '1955', '0', '103', '71', '95', '24', '41'), +('8', '1', '53', '2031', '0', '105', '72', '97', '24', '42'), +('8', '1', '54', '2109', '0', '107', '74', '99', '25', '43'), +('8', '1', '55', '2189', '0', '110', '75', '101', '25', '43'), +('8', '1', '56', '2271', '0', '112', '76', '103', '25', '44'), +('8', '1', '57', '2355', '0', '114', '78', '105', '25', '44'), +('8', '1', '58', '2441', '0', '116', '79', '107', '26', '45'), +('8', '1', '59', '2529', '0', '119', '81', '109', '26', '45'), +('8', '1', '60', '2619', '0', '121', '82', '111', '26', '46'), +('8', '3', '1', '66', '81', '21', '25', '22', '22', '16'), +('8', '3', '2', '83', '87', '21', '26', '23', '17', '23'), +('8', '3', '3', '100', '108', '22', '27', '24', '17', '23'), +('8', '3', '4', '117', '116', '22', '29', '24', '18', '24'), +('8', '3', '5', '134', '139', '23', '30', '25', '18', '24'), +('8', '3', '6', '151', '149', '23', '31', '26', '19', '25'), +('8', '3', '7', '168', '174', '23', '32', '27', '19', '25'), +('8', '3', '8', '185', '186', '24', '33', '28', '20', '26'), +('8', '3', '9', '202', '213', '24', '35', '29', '20', '27'), +('8', '3', '10', '219', '241', '25', '36', '29', '21', '27'), +('8', '3', '11', '236', '270', '25', '37', '30', '21', '28'), +('8', '3', '12', '253', '300', '26', '39', '31', '22', '29'), +('8', '3', '13', '270', '331', '26', '40', '32', '23', '29'), +('8', '3', '14', '288', '363', '27', '41', '33', '23', '30'), +('8', '3', '15', '307', '396', '27', '43', '34', '24', '30'), +('8', '3', '16', '327', '430', '28', '44', '35', '24', '31'), +('8', '3', '17', '348', '465', '28', '45', '36', '25', '32'), +('8', '3', '18', '370', '501', '29', '47', '37', '26', '33'), +('8', '3', '19', '393', '538', '29', '48', '38', '26', '33'), +('8', '3', '20', '417', '576', '30', '50', '39', '27', '34'), +('8', '3', '21', '442', '615', '30', '51', '40', '28', '35'), +('8', '3', '22', '468', '655', '31', '53', '41', '28', '35'), +('8', '3', '23', '495', '696', '31', '54', '42', '29', '36'), +('8', '3', '24', '523', '738', '32', '56', '43', '30', '37'), +('8', '3', '25', '552', '781', '32', '57', '44', '30', '38'), +('8', '3', '26', '582', '825', '33', '59', '45', '31', '38'), +('8', '3', '27', '613', '870', '33', '61', '46', '32', '39'), +('8', '3', '28', '645', '915', '34', '62', '47', '32', '40'), +('8', '3', '29', '678', '960', '34', '64', '48', '33', '41'), +('8', '3', '30', '712', '1005', '35', '66', '49', '34', '41'), +('8', '3', '31', '747', '1050', '35', '67', '51', '35', '42'), +('8', '3', '32', '783', '1095', '36', '69', '52', '35', '43'), +('8', '3', '33', '820', '1140', '37', '71', '53', '36', '44'), +('8', '3', '34', '858', '1185', '37', '72', '54', '37', '45'), +('8', '3', '35', '897', '1230', '38', '74', '55', '38', '46'), +('8', '3', '36', '937', '1275', '39', '76', '57', '39', '47'), +('8', '3', '37', '978', '1320', '39', '78', '58', '39', '47'), +('8', '3', '38', '1020', '1365', '40', '80', '59', '40', '48'), +('8', '3', '39', '1063', '1410', '40', '82', '60', '41', '49'), +('8', '3', '40', '1107', '1455', '41', '83', '62', '42', '50'), +('8', '3', '41', '1152', '1500', '42', '85', '63', '43', '51'), +('8', '3', '42', '1198', '1545', '42', '87', '64', '43', '52'), +('8', '3', '43', '1245', '1590', '43', '89', '65', '44', '53'), +('8', '3', '44', '1293', '1635', '44', '91', '67', '45', '54'), +('8', '3', '45', '1342', '1680', '44', '93', '68', '46', '55'), +('8', '3', '46', '1392', '1725', '45', '95', '70', '47', '56'), +('8', '3', '47', '1443', '1770', '46', '97', '71', '48', '57'), +('8', '3', '48', '1495', '1815', '47', '100', '72', '49', '58'), +('8', '3', '49', '1548', '1860', '47', '102', '74', '50', '59'), +('8', '3', '50', '1602', '1905', '48', '104', '75', '51', '60'), +('8', '3', '51', '1657', '1950', '49', '106', '77', '52', '61'), +('8', '3', '52', '1713', '1995', '50', '108', '78', '53', '62'), +('8', '3', '53', '1770', '2040', '50', '110', '80', '54', '63'), +('8', '3', '54', '1828', '2085', '51', '113', '81', '55', '64'), +('8', '3', '55', '1887', '2130', '52', '115', '83', '56', '65'), +('8', '3', '56', '1947', '2175', '53', '117', '84', '57', '66'), +('8', '3', '57', '2008', '2220', '54', '120', '86', '58', '68'), +('8', '3', '58', '2070', '2265', '54', '122', '88', '59', '69'), +('8', '3', '59', '2133', '2310', '55', '125', '89', '60', '70'), +('8', '3', '60', '2197', '2355', '56', '127', '91', '61', '71'), +('8', '4', '1', '65', '0', '22', '25', '22', '21', '16'), +('8', '4', '2', '82', '0', '23', '26', '23', '16', '21'), +('8', '4', '3', '99', '0', '23', '27', '23', '16', '22'), +('8', '4', '4', '116', '0', '24', '29', '24', '17', '22'), +('8', '4', '5', '133', '0', '25', '30', '25', '17', '22'), +('8', '4', '6', '150', '0', '25', '31', '25', '17', '23'), +('8', '4', '7', '167', '0', '26', '33', '26', '17', '23'), +('8', '4', '8', '184', '0', '27', '34', '26', '17', '23'), +('8', '4', '9', '201', '0', '28', '35', '27', '17', '24'), +('8', '4', '10', '218', '0', '28', '37', '28', '18', '24'), +('8', '4', '11', '235', '0', '29', '38', '29', '18', '25'), +('8', '4', '12', '252', '0', '30', '39', '29', '18', '25'), +('8', '4', '13', '269', '0', '31', '41', '30', '18', '25'), +('8', '4', '14', '286', '0', '31', '42', '31', '18', '26'), +('8', '4', '15', '303', '0', '32', '44', '31', '19', '26'), +('8', '4', '16', '321', '0', '33', '45', '32', '19', '27'), +('8', '4', '17', '340', '0', '34', '46', '33', '19', '27'), +('8', '4', '18', '360', '0', '35', '48', '34', '19', '27'), +('8', '4', '19', '381', '0', '36', '50', '34', '19', '28'), +('8', '4', '20', '403', '0', '36', '51', '35', '20', '28'), +('8', '4', '21', '426', '0', '37', '53', '36', '20', '29'), +('8', '4', '22', '450', '0', '38', '54', '37', '20', '29'), +('8', '4', '23', '475', '0', '39', '56', '38', '20', '30'), +('8', '4', '24', '501', '0', '40', '57', '38', '21', '30'), +('8', '4', '25', '528', '0', '41', '59', '39', '21', '31'), +('8', '4', '26', '556', '0', '42', '61', '40', '21', '31'), +('8', '4', '27', '585', '0', '43', '62', '41', '21', '31'), +('8', '4', '28', '615', '0', '44', '64', '42', '21', '32'), +('8', '4', '29', '646', '0', '44', '66', '43', '22', '32'), +('8', '4', '30', '678', '0', '45', '68', '43', '22', '33'), +('8', '4', '31', '711', '0', '46', '69', '44', '22', '33'), +('8', '4', '32', '745', '0', '47', '71', '45', '22', '34'), +('8', '4', '33', '780', '0', '48', '73', '46', '23', '34'), +('8', '4', '34', '816', '0', '49', '75', '47', '23', '35'), +('8', '4', '35', '853', '0', '50', '77', '48', '23', '35'), +('8', '4', '36', '891', '0', '52', '79', '49', '24', '36'), +('8', '4', '37', '930', '0', '53', '80', '50', '24', '37'), +('8', '4', '38', '970', '0', '54', '82', '51', '24', '37'), +('8', '4', '39', '1011', '0', '55', '84', '52', '24', '38'), +('8', '4', '40', '1053', '0', '56', '86', '53', '25', '38'), +('8', '4', '41', '1096', '0', '57', '88', '54', '25', '39'), +('8', '4', '42', '1140', '0', '58', '90', '55', '25', '39'), +('8', '4', '43', '1185', '0', '59', '92', '56', '25', '40'), +('8', '4', '44', '1231', '0', '60', '95', '57', '26', '40'), +('8', '4', '45', '1278', '0', '62', '97', '58', '26', '41'), +('8', '4', '46', '1326', '0', '63', '99', '59', '26', '42'), +('8', '4', '47', '1375', '0', '64', '101', '60', '27', '42'), +('8', '4', '48', '1425', '0', '65', '103', '61', '27', '43'), +('8', '4', '49', '1476', '0', '66', '105', '63', '27', '44'), +('8', '4', '50', '1528', '0', '68', '108', '64', '28', '44'), +('8', '4', '51', '1581', '0', '69', '110', '65', '28', '45'), +('8', '4', '52', '1635', '0', '70', '112', '66', '28', '45'), +('8', '4', '53', '1690', '0', '71', '115', '67', '29', '46'), +('8', '4', '54', '1746', '0', '73', '117', '68', '29', '47'), +('8', '4', '55', '1803', '0', '74', '119', '70', '29', '47'), +('8', '4', '56', '1861', '0', '75', '122', '71', '30', '48'), +('8', '4', '57', '1920', '0', '77', '124', '72', '30', '49'), +('8', '4', '58', '1980', '0', '78', '127', '73', '30', '50'), +('8', '4', '59', '2041', '0', '80', '129', '75', '31', '50'), +('8', '4', '60', '2103', '0', '81', '132', '76', '31', '51'), +('8', '5', '1', '62', '128', '21', '22', '21', '24', '18'), +('8', '5', '2', '77', '138', '21', '22', '21', '19', '25'), +('8', '5', '3', '92', '149', '21', '22', '22', '20', '26'), +('8', '5', '4', '107', '175', '22', '23', '22', '21', '28'), +('8', '5', '5', '122', '202', '22', '23', '22', '23', '29'), +('8', '5', '6', '137', '230', '22', '23', '23', '24', '30'), +('8', '5', '7', '152', '259', '22', '23', '23', '25', '31'), +('8', '5', '8', '167', '289', '22', '24', '23', '26', '32'), +('8', '5', '9', '182', '320', '22', '24', '24', '27', '34'), +('8', '5', '10', '197', '367', '23', '24', '24', '29', '35'), +('8', '5', '11', '212', '385', '23', '24', '25', '30', '36'), +('8', '5', '12', '227', '419', '23', '25', '25', '31', '38'), +('8', '5', '13', '242', '454', '23', '25', '25', '32', '39'), +('8', '5', '14', '257', '490', '23', '25', '26', '34', '40'), +('8', '5', '15', '272', '527', '24', '25', '26', '35', '42'), +('8', '5', '16', '287', '565', '24', '26', '27', '36', '43'), +('8', '5', '17', '302', '619', '24', '26', '27', '38', '44'), +('8', '5', '18', '317', '644', '24', '26', '27', '39', '46'), +('8', '5', '19', '332', '685', '24', '27', '28', '40', '47'), +('8', '5', '20', '347', '727', '25', '27', '28', '42', '49'), +('8', '5', '21', '362', '770', '25', '27', '29', '43', '50'), +('8', '5', '22', '378', '829', '25', '27', '29', '45', '52'), +('8', '5', '23', '395', '859', '25', '28', '30', '46', '53'), +('8', '5', '24', '413', '920', '26', '28', '30', '48', '55'), +('8', '5', '25', '432', '952', '26', '28', '31', '49', '56'), +('8', '5', '26', '452', '1015', '26', '29', '31', '51', '58'), +('8', '5', '27', '473', '1049', '26', '29', '31', '52', '60'), +('8', '5', '28', '495', '1114', '26', '29', '32', '54', '61'), +('8', '5', '29', '518', '1150', '27', '30', '32', '55', '63'), +('8', '5', '30', '542', '1202', '27', '30', '33', '57', '65'), +('8', '5', '31', '567', '1270', '27', '30', '33', '59', '66'), +('8', '5', '32', '593', '1309', '27', '31', '34', '60', '68'), +('8', '5', '33', '620', '1378', '28', '31', '34', '62', '70'), +('8', '5', '34', '648', '1432', '28', '31', '35', '64', '71'), +('8', '5', '35', '677', '1471', '28', '32', '35', '65', '73'), +('8', '5', '36', '707', '1525', '29', '32', '36', '67', '75'), +('8', '5', '37', '738', '1594', '29', '32', '37', '69', '77'), +('8', '5', '38', '770', '1648', '29', '33', '37', '71', '79'), +('8', '5', '39', '803', '1687', '29', '33', '38', '72', '81'), +('8', '5', '40', '837', '1741', '30', '33', '38', '74', '82'), +('8', '5', '41', '872', '1810', '30', '34', '39', '76', '84'), +('8', '5', '42', '908', '1864', '30', '34', '39', '78', '86'), +('8', '5', '43', '945', '1918', '30', '35', '40', '80', '88'), +('8', '5', '44', '983', '1972', '31', '35', '40', '82', '90'), +('8', '5', '45', '1022', '2026', '31', '35', '41', '84', '92'), +('8', '5', '46', '1062', '2080', '31', '36', '42', '86', '94'), +('8', '5', '47', '1103', '2134', '32', '36', '42', '88', '96'), +('8', '5', '48', '1145', '2188', '32', '37', '43', '90', '99'), +('8', '5', '49', '1238', '2242', '32', '37', '44', '92', '101'), +('8', '5', '50', '1252', '2296', '33', '37', '44', '94', '103'), +('8', '5', '51', '1277', '2350', '33', '38', '45', '96', '105'), +('8', '5', '52', '1323', '2404', '33', '38', '45', '98', '107'), +('8', '5', '53', '1370', '2458', '34', '39', '46', '100', '109'), +('8', '5', '54', '1418', '2512', '34', '39', '47', '102', '112'), +('8', '5', '55', '1467', '2566', '34', '40', '47', '105', '114'), +('8', '5', '56', '1517', '2620', '35', '40', '48', '107', '116'), +('8', '5', '57', '1568', '2674', '35', '41', '49', '109', '119'), +('8', '5', '58', '1620', '2728', '35', '41', '50', '111', '121'), +('8', '5', '59', '1673', '2782', '36', '42', '50', '114', '124'), +('8', '5', '60', '1727', '2836', '36', '42', '51', '116', '126'), +('8', '7', '1', '67', '72', '22', '22', '22', '23', '17'), +('8', '7', '2', '84', '79', '23', '22', '23', '18', '24'), +('8', '7', '3', '101', '87', '23', '23', '24', '19', '25'), +('8', '7', '4', '118', '110', '24', '23', '25', '19', '26'), +('8', '7', '5', '135', '120', '25', '24', '25', '20', '27'), +('8', '7', '6', '152', '145', '26', '24', '26', '21', '28'), +('8', '7', '7', '169', '171', '27', '24', '27', '22', '29'), +('8', '7', '8', '186', '198', '27', '25', '28', '23', '29'), +('8', '7', '9', '203', '241', '28', '25', '29', '24', '30'), +('8', '7', '10', '220', '255', '29', '26', '30', '24', '31'), +('8', '7', '11', '237', '285', '30', '26', '31', '25', '32'), +('8', '7', '12', '254', '316', '31', '27', '32', '26', '33'), +('8', '7', '13', '271', '348', '31', '27', '33', '27', '34'), +('8', '7', '14', '288', '381', '32', '28', '34', '28', '35'), +('8', '7', '15', '305', '415', '33', '28', '35', '29', '37'), +('8', '7', '16', '322', '450', '34', '29', '36', '30', '38'), +('8', '7', '17', '340', '486', '35', '29', '37', '31', '39'), +('8', '7', '18', '359', '523', '36', '30', '38', '32', '40'), +('8', '7', '19', '379', '589', '37', '30', '39', '33', '41'), +('8', '7', '20', '400', '600', '38', '31', '40', '34', '42'), +('8', '7', '21', '422', '640', '39', '31', '41', '35', '43'), +('8', '7', '22', '445', '681', '39', '32', '42', '36', '44'), +('8', '7', '23', '469', '723', '40', '32', '43', '37', '45'), +('8', '7', '24', '494', '766', '41', '33', '44', '38', '47'), +('8', '7', '25', '520', '810', '42', '33', '46', '39', '48'), +('8', '7', '26', '547', '898', '43', '34', '47', '40', '49'), +('8', '7', '27', '575', '947', '44', '34', '48', '41', '50'), +('8', '7', '28', '604', '996', '45', '35', '49', '42', '51'), +('8', '7', '29', '634', '996', '46', '35', '50', '43', '53'), +('8', '7', '30', '665', '1045', '47', '36', '51', '44', '54'), +('8', '7', '31', '697', '1165', '49', '36', '53', '46', '55'), +('8', '7', '32', '730', '1216', '50', '37', '54', '47', '57'), +('8', '7', '33', '764', '1277', '51', '38', '55', '48', '58'), +('8', '7', '34', '799', '1304', '52', '38', '56', '49', '59'), +('8', '7', '35', '835', '1355', '53', '39', '58', '50', '61'), +('8', '7', '36', '872', '1412', '54', '40', '59', '52', '62'), +('8', '7', '37', '910', '1473', '55', '40', '60', '53', '63'), +('8', '7', '38', '949', '1525', '56', '41', '62', '54', '65'), +('8', '7', '39', '989', '1561', '57', '41', '63', '55', '66'), +('8', '7', '40', '1030', '1599', '59', '42', '64', '57', '68'), +('8', '7', '41', '1072', '1627', '60', '43', '66', '58', '69'), +('8', '7', '42', '1115', '1683', '61', '43', '67', '59', '71'), +('8', '7', '43', '1159', '1716', '62', '44', '69', '60', '72'), +('8', '7', '44', '1204', '1746', '64', '45', '70', '62', '74'), +('8', '7', '45', '1250', '1780', '65', '45', '72', '63', '75'), +('8', '7', '46', '1297', '1844', '66', '46', '73', '65', '77'), +('8', '7', '47', '1345', '1988', '67', '47', '75', '66', '78'), +('8', '7', '48', '1394', '2024', '69', '48', '76', '67', '80'), +('8', '7', '49', '1444', '2077', '70', '48', '78', '69', '82'), +('8', '7', '50', '1495', '2127', '71', '49', '79', '70', '83'), +('8', '7', '51', '1547', '2177', '73', '50', '81', '72', '85'), +('8', '7', '52', '1600', '2204', '74', '51', '82', '73', '87'), +('8', '7', '53', '1654', '2235', '76', '51', '84', '75', '88'), +('8', '7', '54', '1709', '2256', '77', '52', '86', '76', '90'), +('8', '7', '55', '1765', '2286', '78', '53', '87', '78', '92'), +('8', '7', '56', '1822', '2319', '80', '54', '89', '79', '94'), +('8', '7', '57', '1880', '2384', '81', '55', '91', '81', '95'), +('8', '7', '58', '1939', '2432', '83', '55', '92', '83', '97'), +('8', '7', '59', '1999', '2481', '84', '56', '94', '84', '99'), +('8', '7', '60', '2060', '2530', '86', '57', '96', '86', '101'), +('8', '8', '1', '62', '119', '21', '22', '21', '23', '19'), +('8', '8', '2', '77', '130', '21', '22', '21', '20', '24'), +('8', '8', '3', '92', '156', '21', '22', '22', '21', '25'), +('8', '8', '4', '107', '183', '21', '23', '22', '23', '26'), +('8', '8', '5', '122', '211', '21', '23', '22', '24', '28'), +('8', '8', '6', '137', '240', '22', '23', '22', '25', '29'), +('8', '8', '7', '152', '270', '22', '23', '23', '26', '30'), +('8', '8', '8', '167', '286', '22', '23', '23', '27', '31'), +('8', '8', '9', '182', '333', '22', '23', '23', '29', '32'), +('8', '8', '10', '197', '366', '22', '24', '24', '30', '34'), +('8', '8', '11', '212', '400', '22', '24', '24', '31', '35'), +('8', '8', '12', '227', '435', '22', '24', '24', '33', '36'), +('8', '8', '13', '242', '471', '22', '24', '25', '34', '37'), +('8', '8', '14', '257', '508', '23', '24', '25', '35', '39'), +('8', '8', '15', '272', '546', '23', '25', '25', '37', '40'), +('8', '8', '16', '287', '585', '23', '25', '26', '38', '41'), +('8', '8', '17', '302', '610', '23', '25', '26', '39', '43'), +('8', '8', '18', '317', '666', '23', '25', '26', '41', '44'), +('8', '8', '19', '332', '693', '23', '25', '27', '42', '45'), +('8', '8', '20', '347', '751', '23', '26', '27', '44', '47'), +('8', '8', '21', '362', '780', '24', '26', '27', '45', '48'), +('8', '8', '22', '377', '840', '24', '26', '28', '47', '50'), +('8', '8', '23', '392', '871', '24', '26', '28', '48', '51'), +('8', '8', '24', '408', '933', '24', '27', '29', '50', '53'), +('8', '8', '25', '425', '966', '24', '27', '29', '51', '54'), +('8', '8', '26', '443', '1030', '24', '27', '29', '53', '56'), +('8', '8', '27', '462', '1080', '24', '27', '30', '55', '57'), +('8', '8', '28', '482', '1116', '25', '27', '30', '56', '59'), +('8', '8', '29', '503', '1182', '25', '28', '31', '58', '60'), +('8', '8', '30', '525', '1233', '25', '28', '31', '60', '62'), +('8', '8', '31', '548', '1269', '25', '28', '31', '61', '64'), +('8', '8', '32', '572', '1335', '25', '28', '32', '63', '65'), +('8', '8', '33', '597', '1386', '25', '29', '32', '65', '67'), +('8', '8', '34', '623', '1422', '26', '29', '33', '66', '69'), +('8', '8', '35', '650', '1473', '26', '29', '33', '68', '70'), +('8', '8', '36', '678', '1524', '26', '30', '34', '70', '72'), +('8', '8', '37', '707', '1590', '26', '30', '34', '72', '74'), +('8', '8', '38', '737', '1641', '26', '30', '34', '74', '76'), +('8', '8', '39', '768', '1692', '27', '30', '35', '76', '77'), +('8', '8', '40', '800', '1728', '27', '31', '35', '77', '79'), +('8', '8', '41', '833', '1779', '27', '31', '36', '79', '81'), +('8', '8', '42', '867', '1830', '27', '31', '36', '81', '83'), +('8', '8', '43', '902', '1881', '27', '31', '37', '83', '85'), +('8', '8', '44', '938', '1932', '27', '32', '37', '85', '87'), +('8', '8', '45', '975', '1983', '28', '32', '38', '87', '89'), +('8', '8', '46', '1013', '2034', '28', '32', '38', '89', '91'), +('8', '8', '47', '1092', '2085', '28', '33', '39', '91', '93'), +('8', '8', '48', '1102', '2151', '28', '33', '39', '94', '95'), +('8', '8', '49', '1133', '2202', '29', '33', '40', '96', '97'), +('8', '8', '50', '1175', '2238', '29', '34', '40', '98', '99'), +('8', '8', '51', '1218', '2289', '29', '34', '41', '100', '101'), +('8', '8', '52', '1262', '2340', '29', '34', '41', '102', '103'), +('8', '8', '53', '1307', '2391', '29', '35', '42', '104', '105'), +('8', '8', '54', '1353', '2442', '30', '35', '43', '107', '107'), +('8', '8', '55', '1400', '2508', '30', '35', '43', '109', '110'), +('8', '8', '56', '1448', '2547', '30', '36', '44', '111', '112'), +('8', '8', '57', '1497', '2595', '30', '36', '44', '114', '114'), +('8', '8', '58', '1547', '2646', '31', '36', '45', '116', '116'), +('8', '8', '59', '1589', '2697', '31', '37', '45', '119', '119'), +('8', '8', '60', '1650', '2748', '31', '37', '46', '121', '121'); diff --git a/sql/updates/0.6/2688_playercreateinfo.sql b/sql/updates/0.6/2688_playercreateinfo.sql new file mode 100644 index 000000000..766e92b01 --- /dev/null +++ b/sql/updates/0.6/2688_playercreateinfo.sql @@ -0,0 +1,13 @@ +ALTER TABLE `playercreateinfo` + DROP `BaseStrength`, + DROP `BaseAgility`, + DROP `BaseStamina`, + DROP `BaseIntellect`, + DROP `BaseSpirit`, + DROP `BaseArmor`, + DROP `BaseHealth`, + DROP `BaseMana`, + DROP `BaseRage`, + DROP `BaseFocus`, + DROP `BaseEnergy`; + \ No newline at end of file diff --git a/sql/updates/0.6/2689_player_levelstats.sql b/sql/updates/0.6/2689_player_levelstats.sql new file mode 100644 index 000000000..110f43327 --- /dev/null +++ b/sql/updates/0.6/2689_player_levelstats.sql @@ -0,0 +1,2422 @@ +-- ---------------------------- +-- Table structure for player_levelstats +-- ---------------------------- +DROP TABLE IF EXISTS `player_levelstats`; +CREATE TABLE `player_levelstats` ( + `race` tinyint(3) unsigned NOT NULL, + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `hp` smallint(5) unsigned NOT NULL, + `mana` smallint(5) unsigned NOT NULL, + `str` tinyint(3) unsigned NOT NULL, + `agi` tinyint(3) unsigned NOT NULL, + `sta` tinyint(3) unsigned NOT NULL, + `int` tinyint(3) unsigned NOT NULL, + `spi` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`race`,`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +-- ---------------------------- +-- Records +-- ---------------------------- +INSERT INTO `player_levelstats` VALUES +('1', '1', '1', '60', '0', '23', '20', '22', '20', '21'), +('1', '1', '2', '79', '0', '24', '21', '23', '20', '21'), +('1', '1', '3', '98', '0', '25', '21', '24', '20', '22'), +('1', '1', '4', '117', '0', '26', '22', '25', '20', '22'), +('1', '1', '5', '136', '0', '28', '23', '26', '20', '22'), +('1', '1', '6', '155', '0', '29', '24', '27', '21', '22'), +('1', '1', '7', '174', '0', '30', '24', '28', '21', '23'), +('1', '1', '8', '193', '0', '31', '25', '29', '21', '23'), +('1', '1', '9', '212', '0', '32', '26', '30', '21', '23'), +('1', '1', '10', '231', '0', '33', '26', '31', '21', '24'), +('1', '1', '11', '250', '0', '35', '27', '33', '21', '24'), +('1', '1', '12', '269', '0', '36', '28', '34', '21', '24'), +('1', '1', '13', '288', '0', '37', '29', '35', '21', '25'), +('1', '1', '14', '308', '0', '39', '30', '36', '22', '25'), +('1', '1', '15', '329', '0', '40', '30', '37', '22', '25'), +('1', '1', '16', '351', '0', '41', '31', '38', '22', '26'), +('1', '1', '17', '374', '0', '42', '32', '40', '22', '26'), +('1', '1', '18', '398', '0', '44', '33', '41', '22', '26'), +('1', '1', '19', '398', '0', '44', '33', '41', '22', '26'), +('1', '1', '20', '449', '0', '47', '35', '43', '22', '27'), +('1', '1', '21', '476', '0', '48', '35', '45', '23', '27'), +('1', '1', '22', '504', '0', '49', '36', '46', '23', '28'), +('1', '1', '23', '533', '0', '51', '37', '47', '23', '28'), +('1', '1', '24', '563', '0', '52', '38', '49', '23', '29'), +('1', '1', '25', '594', '0', '54', '39', '50', '23', '29'), +('1', '1', '26', '626', '0', '55', '40', '51', '23', '29'), +('1', '1', '27', '659', '0', '57', '41', '53', '23', '30'), +('1', '1', '28', '693', '0', '58', '42', '54', '24', '30'), +('1', '1', '29', '728', '0', '60', '43', '56', '24', '31'), +('1', '1', '30', '764', '0', '62', '44', '57', '24', '31'), +('1', '1', '31', '801', '0', '63', '45', '58', '24', '31'), +('1', '1', '32', '839', '0', '65', '46', '60', '24', '32'), +('1', '1', '33', '878', '0', '66', '47', '61', '24', '32'), +('1', '1', '34', '918', '0', '68', '48', '63', '25', '33'), +('1', '1', '35', '959', '0', '70', '49', '64', '25', '33'), +('1', '1', '36', '1001', '0', '72', '50', '66', '25', '34'), +('1', '1', '37', '1045', '0', '73', '51', '68', '25', '34'), +('1', '1', '38', '1091', '0', '75', '52', '69', '25', '34'), +('1', '1', '39', '1139', '0', '77', '53', '71', '26', '35'), +('1', '1', '40', '1189', '0', '79', '54', '72', '26', '35'), +('1', '1', '41', '1241', '0', '80', '56', '74', '26', '36'), +('1', '1', '42', '1295', '0', '82', '57', '76', '26', '36'), +('1', '1', '43', '1351', '0', '84', '58', '77', '26', '37'), +('1', '1', '44', '1409', '0', '86', '59', '79', '26', '37'), +('1', '1', '45', '1469', '0', '88', '60', '81', '27', '38'), +('1', '1', '46', '1531', '0', '90', '61', '83', '27', '38'), +('1', '1', '47', '1595', '0', '92', '63', '84', '27', '39'), +('1', '1', '48', '1661', '0', '94', '64', '86', '27', '39'), +('1', '1', '49', '1729', '0', '96', '65', '88', '28', '40'), +('1', '1', '50', '1799', '0', '98', '66', '90', '28', '40'), +('1', '1', '51', '1871', '0', '100', '68', '92', '28', '42'), +('1', '1', '52', '1945', '0', '102', '69', '94', '28', '42'), +('1', '1', '53', '2021', '0', '104', '70', '96', '28', '43'), +('1', '1', '54', '2099', '0', '106', '72', '98', '29', '44'), +('1', '1', '55', '2179', '0', '109', '73', '100', '29', '44'), +('1', '1', '56', '2261', '0', '111', '74', '102', '29', '45'), +('1', '1', '57', '2345', '0', '113', '76', '104', '29', '45'), +('1', '1', '58', '2431', '0', '115', '77', '106', '30', '46'), +('1', '1', '59', '2519', '0', '118', '79', '108', '30', '46'), +('1', '1', '60', '2609', '0', '120', '80', '110', '30', '47'), +('1', '2', '1', '68', '79', '22', '20', '22', '20', '22'), +('1', '2', '2', '76', '99', '23', '21', '23', '21', '23'), +('1', '2', '3', '94', '119', '24', '21', '24', '21', '23'), +('1', '2', '4', '112', '140', '25', '22', '25', '22', '24'), +('1', '2', '5', '130', '162', '26', '22', '26', '22', '25'), +('1', '2', '6', '148', '185', '27', '23', '27', '23', '25'), +('1', '2', '7', '166', '209', '28', '23', '28', '24', '26'), +('1', '2', '8', '184', '234', '29', '24', '28', '24', '26'), +('1', '2', '9', '202', '260', '30', '24', '29', '25', '27'), +('1', '2', '10', '220', '287', '31', '25', '30', '25', '28'), +('1', '2', '11', '238', '315', '32', '25', '31', '26', '29'), +('1', '2', '12', '256', '344', '33', '26', '32', '27', '29'), +('1', '2', '13', '274', '374', '34', '27', '33', '27', '30'), +('1', '2', '14', '292', '405', '35', '27', '34', '28', '31'), +('1', '2', '15', '311', '437', '36', '28', '36', '29', '31'), +('1', '2', '16', '331', '470', '38', '28', '37', '29', '32'), +('1', '2', '17', '352', '504', '39', '29', '38', '30', '33'), +('1', '2', '18', '374', '539', '40', '30', '39', '31', '34'), +('1', '2', '19', '397', '575', '41', '30', '40', '31', '34'), +('1', '2', '20', '421', '612', '42', '31', '41', '32', '35'), +('1', '2', '21', '446', '650', '43', '32', '42', '33', '36'), +('1', '2', '22', '472', '689', '45', '32', '43', '34', '37'), +('1', '2', '23', '499', '729', '46', '33', '44', '34', '38'), +('1', '2', '24', '527', '770', '47', '34', '46', '35', '38'), +('1', '2', '25', '556', '812', '48', '34', '47', '36', '39'), +('1', '2', '26', '586', '854', '50', '35', '48', '37', '40'), +('1', '2', '27', '617', '896', '51', '36', '49', '37', '42'), +('1', '2', '28', '649', '938', '52', '36', '50', '38', '43'), +('1', '2', '29', '682', '980', '54', '37', '52', '39', '44'), +('1', '2', '30', '716', '1022', '55', '38', '53', '40', '44'), +('1', '2', '31', '751', '1064', '56', '39', '54', '41', '45'), +('1', '2', '32', '787', '1106', '58', '39', '56', '42', '46'), +('1', '2', '33', '824', '1148', '59', '40', '57', '42', '47'), +('1', '2', '34', '862', '1190', '61', '41', '58', '43', '48'), +('1', '2', '35', '901', '1232', '62', '42', '60', '44', '49'), +('1', '2', '36', '941', '1274', '64', '43', '61', '45', '50'), +('1', '2', '37', '982', '1316', '65', '43', '62', '46', '51'), +('1', '2', '38', '1024', '1358', '67', '44', '64', '47', '52'), +('1', '2', '39', '1067', '1400', '68', '45', '65', '48', '53'), +('1', '2', '40', '1111', '1442', '70', '46', '67', '49', '54'), +('1', '2', '41', '1156', '1484', '71', '47', '68', '50', '55'), +('1', '2', '42', '1202', '1526', '73', '47', '70', '51', '56'), +('1', '2', '43', '1249', '1568', '74', '48', '71', '52', '57'), +('1', '2', '44', '1297', '1610', '76', '49', '73', '52', '58'), +('1', '2', '45', '1346', '1652', '78', '50', '74', '53', '59'), +('1', '2', '46', '1396', '1694', '79', '51', '76', '54', '60'), +('1', '2', '47', '1447', '1736', '81', '52', '77', '56', '61'), +('1', '2', '48', '1499', '1778', '83', '53', '79', '57', '63'), +('1', '2', '49', '1552', '1820', '84', '54', '81', '58', '65'), +('1', '2', '50', '1606', '1862', '86', '55', '82', '59', '66'), +('1', '2', '51', '1661', '1904', '88', '56', '84', '60', '67'), +('1', '2', '52', '1717', '1946', '90', '57', '86', '61', '68'), +('1', '2', '53', '1774', '1988', '92', '58', '87', '62', '69'), +('1', '2', '54', '1832', '2030', '93', '59', '89', '63', '70'), +('1', '2', '55', '1891', '2072', '95', '60', '91', '64', '72'), +('1', '2', '56', '1951', '2114', '97', '61', '93', '65', '73'), +('1', '2', '57', '2012', '2156', '99', '62', '94', '66', '74'), +('1', '2', '58', '2074', '2198', '101', '63', '96', '68', '75'), +('1', '2', '59', '2137', '2240', '103', '64', '98', '69', '77'), +('1', '2', '60', '2201', '2282', '105', '65', '100', '70', '78'), +('1', '4', '1', '55', '0', '21', '23', '21', '20', '20'), +('1', '4', '2', '72', '0', '22', '24', '22', '20', '21'), +('1', '4', '3', '89', '0', '22', '25', '22', '20', '22'), +('1', '4', '4', '106', '0', '23', '27', '23', '21', '22'), +('1', '4', '5', '123', '0', '24', '28', '24', '21', '22'), +('1', '4', '6', '140', '0', '24', '29', '24', '21', '23'), +('1', '4', '7', '157', '0', '25', '31', '25', '21', '23'), +('1', '4', '8', '174', '0', '26', '32', '25', '21', '23'), +('1', '4', '9', '191', '0', '27', '33', '26', '21', '24'), +('1', '4', '10', '208', '0', '27', '35', '27', '22', '24'), +('1', '4', '11', '225', '0', '28', '36', '28', '22', '25'), +('1', '4', '12', '242', '0', '29', '37', '28', '22', '25'), +('1', '4', '13', '259', '0', '30', '39', '29', '22', '25'), +('1', '4', '14', '276', '0', '30', '40', '30', '22', '26'), +('1', '4', '15', '293', '0', '31', '42', '30', '23', '26'), +('1', '4', '16', '311', '0', '32', '43', '31', '23', '27'), +('1', '4', '17', '330', '0', '33', '44', '32', '23', '27'), +('1', '4', '18', '350', '0', '34', '46', '33', '23', '27'), +('1', '4', '19', '371', '0', '35', '48', '33', '23', '28'), +('1', '4', '20', '393', '0', '35', '49', '34', '24', '28'), +('1', '4', '21', '416', '0', '36', '51', '35', '24', '29'), +('1', '4', '22', '440', '0', '37', '52', '36', '24', '29'), +('1', '4', '23', '465', '0', '38', '54', '37', '24', '30'), +('1', '4', '24', '491', '0', '39', '55', '37', '25', '30'), +('1', '4', '25', '518', '0', '40', '57', '38', '25', '31'), +('1', '4', '26', '546', '0', '41', '59', '39', '25', '31'), +('1', '4', '27', '575', '0', '42', '60', '40', '25', '31'), +('1', '4', '28', '605', '0', '43', '62', '41', '25', '32'), +('1', '4', '29', '636', '0', '43', '64', '42', '26', '32'), +('1', '4', '30', '668', '0', '44', '66', '42', '26', '33'), +('1', '4', '31', '701', '0', '45', '67', '43', '26', '33'), +('1', '4', '32', '735', '0', '46', '69', '44', '26', '34'), +('1', '4', '33', '770', '0', '47', '71', '45', '27', '34'), +('1', '4', '34', '806', '0', '48', '73', '46', '27', '35'), +('1', '4', '35', '843', '0', '49', '75', '47', '27', '35'), +('1', '4', '36', '881', '0', '51', '77', '48', '28', '36'), +('1', '4', '37', '920', '0', '52', '78', '49', '28', '37'), +('1', '4', '38', '960', '0', '53', '80', '50', '28', '37'), +('1', '4', '39', '1001', '0', '54', '82', '51', '28', '38'), +('1', '4', '40', '1043', '0', '55', '84', '52', '29', '38'), +('1', '4', '41', '1086', '0', '56', '86', '53', '29', '39'), +('1', '4', '42', '1130', '0', '57', '88', '54', '29', '39'), +('1', '4', '43', '1175', '0', '58', '90', '55', '29', '40'), +('1', '4', '44', '1221', '0', '59', '93', '56', '30', '40'), +('1', '4', '45', '1268', '0', '61', '95', '57', '30', '42'), +('1', '4', '46', '1316', '0', '62', '97', '58', '30', '43'), +('1', '4', '47', '1365', '0', '63', '99', '59', '31', '43'), +('1', '4', '48', '1415', '0', '64', '101', '60', '31', '44'), +('1', '4', '49', '1466', '0', '65', '103', '62', '31', '45'), +('1', '4', '50', '1518', '0', '67', '106', '63', '32', '45'), +('1', '4', '51', '1571', '0', '68', '108', '64', '32', '46'), +('1', '4', '52', '1625', '0', '69', '110', '65', '32', '46'), +('1', '4', '53', '1680', '0', '70', '113', '66', '33', '47'), +('1', '4', '54', '1736', '0', '72', '115', '67', '33', '48'), +('1', '4', '55', '1793', '0', '73', '117', '69', '33', '48'), +('1', '4', '56', '1851', '0', '74', '120', '70', '34', '49'), +('1', '4', '57', '1910', '0', '76', '122', '71', '34', '50'), +('1', '4', '58', '1970', '0', '77', '125', '72', '34', '51'), +('1', '4', '59', '2031', '0', '79', '127', '74', '35', '51'), +('1', '4', '60', '2093', '0', '80', '130', '75', '35', '52'), +('1', '5', '1', '61', '128', '20', '20', '20', '22', '24'), +('1', '5', '2', '67', '184', '20', '20', '20', '23', '25'), +('1', '5', '3', '82', '209', '20', '20', '21', '24', '26'), +('1', '5', '4', '97', '235', '21', '21', '21', '25', '28'), +('1', '5', '5', '112', '262', '21', '21', '21', '27', '29'), +('1', '5', '6', '127', '290', '21', '21', '22', '28', '30'), +('1', '5', '7', '142', '319', '21', '21', '22', '29', '31'), +('1', '5', '8', '157', '349', '21', '22', '22', '30', '32'), +('1', '5', '9', '172', '380', '21', '22', '23', '31', '34'), +('1', '5', '10', '187', '427', '22', '22', '23', '33', '35'), +('1', '5', '11', '202', '445', '22', '22', '24', '34', '36'), +('1', '5', '12', '217', '479', '22', '23', '24', '35', '38'), +('1', '5', '13', '232', '514', '22', '23', '24', '36', '39'), +('1', '5', '14', '247', '550', '22', '23', '25', '38', '40'), +('1', '5', '15', '262', '587', '23', '23', '25', '39', '43'), +('1', '5', '16', '277', '625', '23', '24', '26', '40', '44'), +('1', '5', '17', '292', '679', '23', '24', '26', '42', '45'), +('1', '5', '18', '307', '704', '23', '24', '26', '43', '47'), +('1', '5', '19', '322', '745', '23', '25', '27', '44', '48'), +('1', '5', '20', '337', '787', '24', '25', '27', '46', '50'), +('1', '5', '21', '352', '830', '24', '25', '28', '47', '51'), +('1', '5', '22', '368', '889', '24', '25', '28', '49', '53'), +('1', '5', '23', '385', '919', '24', '26', '29', '50', '54'), +('1', '5', '24', '403', '980', '25', '26', '29', '52', '56'), +('1', '5', '25', '422', '1012', '25', '26', '30', '53', '57'), +('1', '5', '26', '442', '1075', '25', '27', '30', '55', '59'), +('1', '5', '27', '463', '1109', '25', '27', '30', '56', '61'), +('1', '5', '28', '485', '1174', '25', '27', '31', '58', '63'), +('1', '5', '29', '508', '1210', '26', '28', '31', '59', '65'), +('1', '5', '30', '532', '1262', '26', '28', '32', '61', '67'), +('1', '5', '31', '557', '1330', '26', '28', '32', '63', '68'), +('1', '5', '32', '583', '1369', '26', '29', '33', '64', '70'), +('1', '5', '33', '610', '1438', '27', '29', '33', '66', '72'), +('1', '5', '34', '638', '1492', '27', '29', '34', '68', '73'), +('1', '5', '35', '667', '1531', '27', '30', '34', '69', '75'), +('1', '5', '36', '697', '1585', '28', '30', '35', '71', '77'), +('1', '5', '37', '728', '1654', '28', '30', '36', '73', '79'), +('1', '5', '38', '760', '1708', '28', '31', '36', '75', '81'), +('1', '5', '39', '793', '1747', '28', '31', '37', '76', '84'), +('1', '5', '40', '827', '1801', '29', '31', '37', '78', '85'), +('1', '5', '41', '862', '1870', '29', '32', '38', '80', '87'), +('1', '5', '42', '898', '1924', '29', '32', '38', '82', '89'), +('1', '5', '43', '935', '1978', '29', '33', '39', '84', '91'), +('1', '5', '44', '973', '2032', '30', '33', '39', '86', '93'), +('1', '5', '45', '1012', '2086', '30', '33', '40', '88', '95'), +('1', '5', '46', '1052', '2140', '30', '34', '41', '90', '97'), +('1', '5', '47', '1093', '2194', '31', '34', '41', '92', '99'), +('1', '5', '48', '1135', '2248', '31', '35', '42', '94', '102'), +('1', '5', '49', '1178', '2302', '31', '35', '43', '96', '105'), +('1', '5', '50', '1222', '2356', '32', '35', '43', '98', '107'), +('1', '5', '51', '1267', '2410', '32', '36', '44', '100', '109'), +('1', '5', '52', '1313', '2464', '32', '36', '44', '102', '111'), +('1', '5', '53', '1360', '2518', '33', '37', '45', '104', '113'), +('1', '5', '54', '1408', '2572', '33', '37', '46', '106', '116'), +('1', '5', '55', '1457', '2626', '33', '38', '46', '109', '118'), +('1', '5', '56', '1507', '2680', '34', '38', '47', '111', '120'), +('1', '5', '57', '1558', '2734', '34', '39', '48', '113', '123'), +('1', '5', '58', '1610', '2788', '34', '39', '49', '115', '126'), +('1', '5', '59', '1663', '2842', '35', '40', '49', '118', '129'), +('1', '5', '60', '1717', '2896', '35', '40', '50', '120', '131'), +('1', '8', '1', '61', '119', '20', '20', '20', '23', '22'), +('1', '8', '2', '67', '190', '20', '20', '20', '24', '24'), +('1', '8', '3', '82', '216', '20', '20', '21', '25', '25'), +('1', '8', '4', '97', '243', '20', '21', '21', '27', '26'), +('1', '8', '5', '112', '271', '20', '21', '21', '28', '28'), +('1', '8', '6', '127', '300', '21', '21', '21', '29', '29'), +('1', '8', '7', '142', '330', '21', '21', '22', '30', '30'), +('1', '8', '8', '157', '346', '21', '21', '22', '31', '31'), +('1', '8', '9', '172', '393', '21', '21', '22', '33', '32'), +('1', '8', '10', '187', '426', '21', '22', '23', '34', '34'), +('1', '8', '11', '202', '460', '21', '22', '23', '35', '35'), +('1', '8', '12', '217', '495', '21', '22', '23', '37', '36'), +('1', '8', '13', '232', '531', '21', '22', '24', '38', '37'), +('1', '8', '14', '247', '568', '22', '22', '24', '39', '39'), +('1', '8', '15', '262', '606', '22', '23', '24', '41', '40'), +('1', '8', '16', '277', '645', '22', '23', '25', '42', '42'), +('1', '8', '17', '292', '670', '22', '23', '25', '43', '44'), +('1', '8', '18', '307', '726', '22', '23', '25', '45', '45'), +('1', '8', '19', '322', '753', '22', '23', '26', '46', '46'), +('1', '8', '20', '337', '811', '22', '24', '26', '48', '48'), +('1', '8', '21', '352', '840', '23', '24', '26', '49', '49'), +('1', '8', '22', '367', '900', '23', '24', '27', '51', '51'), +('1', '8', '23', '382', '931', '23', '24', '27', '52', '52'), +('1', '8', '24', '398', '993', '23', '25', '28', '54', '54'), +('1', '8', '25', '415', '1026', '23', '25', '28', '55', '55'), +('1', '8', '26', '433', '1090', '23', '25', '28', '57', '57'), +('1', '8', '27', '452', '1140', '23', '25', '29', '59', '58'), +('1', '8', '28', '472', '1176', '24', '25', '29', '60', '60'), +('1', '8', '29', '493', '1242', '24', '26', '30', '62', '61'), +('1', '8', '30', '515', '1293', '24', '26', '30', '64', '64'), +('1', '8', '31', '538', '1329', '24', '26', '30', '65', '66'), +('1', '8', '32', '562', '1395', '24', '26', '31', '67', '67'), +('1', '8', '33', '587', '1446', '24', '27', '31', '69', '69'), +('1', '8', '34', '613', '1482', '25', '27', '32', '70', '71'), +('1', '8', '35', '640', '1533', '25', '27', '32', '72', '72'), +('1', '8', '36', '668', '1584', '25', '28', '33', '74', '74'), +('1', '8', '37', '697', '1650', '25', '28', '33', '76', '76'), +('1', '8', '38', '727', '1701', '25', '28', '33', '78', '78'), +('1', '8', '39', '758', '1752', '26', '28', '34', '80', '79'), +('1', '8', '40', '790', '1788', '26', '29', '34', '81', '81'), +('1', '8', '41', '823', '1839', '26', '29', '35', '83', '84'), +('1', '8', '42', '857', '1890', '26', '29', '35', '85', '86'), +('1', '8', '43', '892', '1941', '26', '29', '36', '87', '88'), +('1', '8', '44', '928', '1992', '26', '30', '36', '89', '90'), +('1', '8', '45', '965', '2043', '27', '30', '37', '91', '92'), +('1', '8', '46', '1003', '2094', '27', '30', '37', '93', '94'), +('1', '8', '47', '1042', '2145', '27', '31', '38', '95', '96'), +('1', '8', '48', '1082', '2211', '27', '31', '38', '98', '98'), +('1', '8', '49', '1123', '2262', '28', '31', '39', '100', '100'), +('1', '8', '50', '1165', '2298', '28', '32', '39', '102', '102'), +('1', '8', '51', '1208', '2349', '28', '32', '40', '104', '105'), +('1', '8', '52', '1252', '2400', '28', '32', '40', '106', '107'), +('1', '8', '53', '1297', '2451', '28', '33', '41', '108', '109'), +('1', '8', '54', '1343', '2502', '29', '33', '42', '111', '111'), +('1', '8', '55', '1390', '2553', '29', '33', '42', '113', '114'), +('1', '8', '56', '1438', '2604', '29', '34', '43', '115', '116'), +('1', '8', '57', '1487', '2655', '29', '34', '43', '118', '118'), +('1', '8', '58', '1537', '2706', '30', '34', '44', '120', '120'), +('1', '8', '59', '1588', '2757', '30', '35', '44', '123', '123'), +('1', '8', '60', '1640', '2808', '30', '35', '45', '125', '126'), +('1', '9', '1', '53', '109', '20', '20', '21', '22', '22'), +('1', '9', '2', '68', '163', '20', '20', '22', '23', '24'), +('1', '9', '3', '83', '187', '21', '21', '22', '24', '25'), +('1', '9', '4', '98', '212', '21', '21', '23', '25', '26'), +('1', '9', '5', '113', '238', '21', '21', '23', '26', '27'), +('1', '9', '6', '128', '265', '21', '22', '24', '27', '28'), +('1', '9', '7', '143', '293', '22', '22', '24', '28', '30'), +('1', '9', '8', '158', '322', '22', '22', '25', '29', '31'), +('1', '9', '9', '173', '352', '22', '23', '25', '30', '32'), +('1', '9', '10', '188', '383', '23', '23', '26', '31', '33'), +('1', '9', '11', '203', '415', '23', '24', '26', '33', '34'), +('1', '9', '12', '218', '448', '23', '24', '27', '34', '35'), +('1', '9', '13', '233', '482', '24', '24', '27', '35', '37'), +('1', '9', '14', '248', '517', '24', '25', '28', '36', '38'), +('1', '9', '15', '263', '553', '24', '25', '29', '37', '39'), +('1', '9', '16', '278', '590', '25', '26', '29', '38', '40'), +('1', '9', '17', '293', '628', '25', '26', '30', '40', '43'), +('1', '9', '18', '309', '667', '25', '26', '30', '41', '44'), +('1', '9', '19', '326', '707', '26', '27', '31', '42', '45'), +('1', '9', '20', '344', '748', '26', '27', '32', '43', '47'), +('1', '9', '21', '363', '790', '26', '28', '32', '45', '48'), +('1', '9', '22', '383', '833', '27', '28', '33', '46', '49'), +('1', '9', '23', '404', '877', '27', '29', '34', '47', '51'), +('1', '9', '24', '426', '922', '28', '29', '34', '49', '52'), +('1', '9', '25', '449', '968', '28', '30', '35', '50', '54'), +('1', '9', '26', '473', '1015', '28', '30', '36', '51', '55'), +('1', '9', '27', '498', '1063', '29', '30', '36', '53', '56'), +('1', '9', '28', '524', '1112', '29', '31', '37', '54', '58'), +('1', '9', '29', '551', '1162', '30', '31', '38', '56', '59'), +('1', '9', '30', '579', '1213', '30', '32', '38', '57', '61'), +('1', '9', '31', '608', '1264', '30', '32', '39', '58', '64'), +('1', '9', '32', '638', '1315', '31', '33', '40', '60', '65'), +('1', '9', '33', '669', '1366', '31', '33', '41', '61', '67'), +('1', '9', '34', '701', '1417', '32', '34', '41', '63', '68'), +('1', '9', '35', '734', '1468', '32', '34', '42', '64', '70'), +('1', '9', '36', '768', '1519', '33', '35', '43', '66', '72'), +('1', '9', '37', '803', '1570', '33', '36', '44', '68', '73'), +('1', '9', '38', '839', '1621', '33', '36', '45', '69', '75'), +('1', '9', '39', '876', '1672', '34', '37', '45', '71', '77'), +('1', '9', '40', '914', '1723', '34', '37', '46', '72', '78'), +('1', '9', '41', '953', '1774', '35', '38', '47', '74', '80'), +('1', '9', '42', '993', '1825', '35', '38', '48', '76', '82'), +('1', '9', '43', '1024', '1876', '36', '39', '48', '77', '86'), +('1', '9', '44', '1076', '1927', '36', '39', '50', '79', '86'), +('1', '9', '45', '1119', '1978', '37', '40', '50', '81', '88'), +('1', '9', '46', '1153', '2029', '37', '41', '51', '83', '90'), +('1', '9', '47', '1208', '2080', '38', '41', '52', '84', '92'), +('1', '9', '48', '1254', '2131', '38', '42', '53', '86', '94'), +('1', '9', '49', '1301', '2182', '39', '43', '54', '88', '96'), +('1', '9', '50', '1349', '2233', '39', '43', '55', '90', '98'), +('1', '9', '51', '1398', '2284', '40', '44', '56', '92', '100'), +('1', '9', '52', '1448', '2335', '40', '44', '57', '94', '102'), +('1', '9', '53', '1489', '2386', '41', '45', '58', '96', '105'), +('1', '9', '54', '1541', '2437', '42', '46', '59', '98', '107'), +('1', '9', '55', '1604', '2488', '42', '46', '60', '100', '109'), +('1', '9', '56', '1658', '2539', '43', '47', '61', '102', '111'), +('1', '9', '57', '1713', '2590', '43', '48', '62', '104', '113'), +('1', '9', '58', '1769', '2641', '44', '49', '63', '106', '116'), +('1', '9', '59', '1826', '2692', '44', '49', '64', '108', '118'), +('1', '9', '60', '1884', '2743', '45', '50', '65', '110', '120'), +('2', '1', '1', '80', '0', '26', '17', '24', '17', '23'), +('2', '1', '2', '99', '0', '27', '18', '25', '17', '23'), +('2', '1', '3', '118', '0', '28', '18', '26', '17', '24'), +('2', '1', '4', '137', '0', '29', '19', '27', '17', '24'), +('2', '1', '5', '156', '0', '31', '20', '28', '17', '24'), +('2', '1', '6', '175', '0', '32', '21', '29', '18', '24'), +('2', '1', '7', '194', '0', '33', '21', '30', '18', '25'), +('2', '1', '8', '213', '0', '34', '22', '31', '18', '25'), +('2', '1', '9', '232', '0', '35', '23', '32', '18', '25'), +('2', '1', '10', '251', '0', '36', '23', '33', '18', '26'), +('2', '1', '11', '270', '0', '38', '24', '35', '18', '26'), +('2', '1', '12', '289', '0', '39', '25', '36', '18', '26'), +('2', '1', '13', '308', '0', '40', '26', '37', '18', '27'), +('2', '1', '14', '328', '0', '42', '27', '38', '19', '27'), +('2', '1', '15', '349', '0', '43', '27', '39', '19', '27'), +('2', '1', '16', '371', '0', '44', '28', '40', '19', '28'), +('2', '1', '17', '394', '0', '45', '29', '42', '19', '28'), +('2', '1', '18', '418', '0', '47', '30', '43', '19', '28'), +('2', '1', '19', '443', '0', '48', '31', '44', '19', '29'), +('2', '1', '20', '469', '0', '50', '32', '45', '19', '29'), +('2', '1', '21', '496', '0', '51', '32', '47', '20', '29'), +('2', '1', '22', '524', '0', '52', '33', '48', '20', '30'), +('2', '1', '23', '553', '0', '54', '34', '49', '20', '30'), +('2', '1', '24', '583', '0', '55', '35', '51', '20', '31'), +('2', '1', '25', '614', '0', '57', '36', '52', '20', '31'), +('2', '1', '26', '646', '0', '58', '37', '53', '20', '31'), +('2', '1', '27', '679', '0', '60', '38', '55', '20', '32'), +('2', '1', '28', '713', '0', '61', '39', '56', '21', '32'), +('2', '1', '29', '748', '0', '63', '40', '58', '21', '33'), +('2', '1', '30', '784', '0', '65', '41', '59', '21', '33'), +('2', '1', '31', '821', '0', '66', '42', '60', '21', '33'), +('2', '1', '32', '859', '0', '68', '43', '62', '21', '34'), +('2', '1', '33', '898', '0', '69', '44', '63', '21', '34'), +('2', '1', '34', '938', '0', '71', '45', '65', '22', '35'), +('2', '1', '35', '979', '0', '73', '46', '66', '22', '35'), +('2', '1', '36', '1021', '0', '75', '47', '68', '22', '36'), +('2', '1', '37', '1065', '0', '76', '48', '70', '22', '36'), +('2', '1', '38', '1111', '0', '78', '49', '71', '22', '36'), +('2', '1', '39', '1159', '0', '80', '50', '73', '23', '37'), +('2', '1', '40', '1209', '0', '82', '51', '74', '23', '37'), +('2', '1', '41', '1261', '0', '83', '53', '76', '23', '38'), +('2', '1', '42', '1315', '0', '85', '54', '78', '23', '38'), +('2', '1', '43', '1371', '0', '87', '55', '79', '23', '39'), +('2', '1', '44', '1429', '0', '89', '56', '81', '23', '39'), +('2', '1', '45', '1489', '0', '91', '57', '83', '24', '40'), +('2', '1', '46', '1551', '0', '93', '58', '85', '24', '40'), +('2', '1', '47', '1615', '0', '95', '60', '86', '24', '41'), +('2', '1', '48', '1681', '0', '97', '61', '88', '24', '41'), +('2', '1', '49', '1749', '0', '99', '62', '90', '25', '42'), +('2', '1', '50', '1819', '0', '101', '63', '92', '25', '42'), +('2', '1', '51', '1891', '0', '103', '65', '94', '25', '43'), +('2', '1', '52', '1965', '0', '105', '66', '96', '25', '43'), +('2', '1', '53', '2041', '0', '107', '67', '98', '25', '44'), +('2', '1', '54', '2119', '0', '109', '69', '100', '26', '45'), +('2', '1', '55', '2199', '0', '112', '70', '102', '26', '45'), +('2', '1', '56', '2281', '0', '114', '71', '104', '26', '46'), +('2', '1', '57', '2365', '0', '116', '73', '106', '26', '46'), +('2', '1', '58', '2451', '0', '118', '74', '108', '27', '47'), +('2', '1', '59', '2539', '0', '121', '76', '110', '27', '47'), +('2', '1', '60', '2629', '0', '123', '77', '112', '27', '48'), +('2', '3', '1', '76', '80', '23', '20', '23', '17', '24'), +('2', '3', '2', '93', '88', '23', '21', '24', '18', '25'), +('2', '3', '3', '110', '109', '24', '22', '25', '18', '25'), +('2', '3', '4', '127', '117', '24', '24', '25', '19', '26'), +('2', '3', '5', '144', '140', '25', '25', '26', '19', '26'), +('2', '3', '6', '161', '150', '25', '26', '27', '20', '27'), +('2', '3', '7', '178', '175', '25', '27', '28', '20', '27'), +('2', '3', '8', '195', '201', '26', '28', '29', '21', '28'), +('2', '3', '9', '212', '228', '26', '30', '30', '21', '29'), +('2', '3', '10', '229', '256', '27', '31', '30', '22', '29'), +('2', '3', '11', '246', '285', '27', '32', '31', '22', '30'), +('2', '3', '12', '263', '315', '28', '34', '32', '23', '31'), +('2', '3', '13', '280', '346', '28', '35', '33', '24', '31'), +('2', '3', '14', '298', '378', '29', '36', '34', '24', '32'), +('2', '3', '15', '317', '411', '29', '38', '35', '25', '32'), +('2', '3', '16', '337', '445', '30', '39', '36', '25', '33'), +('2', '3', '17', '358', '480', '30', '40', '37', '26', '34'), +('2', '3', '18', '380', '516', '31', '42', '38', '27', '35'), +('2', '3', '19', '403', '553', '31', '43', '39', '27', '35'), +('2', '3', '20', '427', '591', '32', '45', '40', '28', '36'), +('2', '3', '21', '452', '630', '32', '46', '41', '29', '37'), +('2', '3', '22', '478', '670', '33', '48', '42', '29', '37'), +('2', '3', '23', '505', '711', '33', '49', '43', '30', '38'), +('2', '3', '24', '533', '753', '34', '51', '44', '31', '39'), +('2', '3', '25', '562', '796', '34', '52', '45', '31', '40'), +('2', '3', '26', '592', '840', '35', '54', '46', '32', '40'), +('2', '3', '27', '623', '885', '35', '56', '47', '33', '41'), +('2', '3', '28', '655', '930', '36', '57', '48', '33', '42'), +('2', '3', '29', '688', '975', '36', '59', '49', '34', '43'), +('2', '3', '30', '722', '1020', '37', '61', '50', '35', '43'), +('2', '3', '31', '757', '1065', '37', '62', '52', '36', '44'), +('2', '3', '32', '793', '1110', '38', '64', '53', '36', '45'), +('2', '3', '33', '830', '1155', '39', '66', '54', '37', '46'), +('2', '3', '34', '868', '1200', '39', '67', '55', '38', '47'), +('2', '3', '35', '907', '1245', '40', '69', '56', '39', '48'), +('2', '3', '36', '947', '1290', '41', '71', '58', '40', '49'), +('2', '3', '37', '988', '1335', '41', '73', '59', '40', '49'), +('2', '3', '38', '1030', '1380', '42', '75', '60', '41', '50'), +('2', '3', '39', '1073', '1425', '42', '77', '61', '42', '51'), +('2', '3', '40', '1117', '1470', '43', '78', '63', '43', '52'), +('2', '3', '41', '1162', '1515', '44', '80', '64', '44', '53'), +('2', '3', '42', '1208', '1560', '44', '82', '65', '44', '54'), +('2', '3', '43', '1255', '1605', '45', '84', '66', '45', '55'), +('2', '3', '44', '1303', '1650', '46', '86', '68', '46', '56'), +('2', '3', '45', '1352', '1695', '46', '88', '69', '47', '57'), +('2', '3', '46', '1402', '1740', '47', '90', '71', '48', '58'), +('2', '3', '47', '1453', '1785', '48', '92', '72', '49', '59'), +('2', '3', '48', '1505', '1830', '49', '95', '73', '50', '60'), +('2', '3', '49', '1558', '1875', '49', '97', '75', '51', '61'), +('2', '3', '50', '1612', '1920', '50', '99', '76', '52', '62'), +('2', '3', '51', '1667', '1965', '51', '101', '78', '53', '63'), +('2', '3', '52', '1723', '2010', '52', '103', '79', '54', '64'), +('2', '3', '53', '1780', '2055', '52', '105', '81', '55', '65'), +('2', '3', '54', '1838', '2100', '53', '108', '82', '56', '66'), +('2', '3', '55', '1897', '2145', '54', '110', '84', '57', '67'), +('2', '3', '56', '1957', '2190', '55', '112', '85', '58', '68'), +('2', '3', '57', '2018', '2235', '56', '115', '87', '59', '70'), +('2', '3', '58', '2080', '2280', '56', '117', '89', '60', '71'), +('2', '3', '59', '2143', '2325', '57', '120', '90', '61', '72'), +('2', '3', '60', '2207', '2370', '58', '122', '92', '62', '73'), +('2', '4', '1', '75', '0', '24', '20', '23', '17', '23'), +('2', '4', '2', '92', '0', '25', '21', '24', '17', '23'), +('2', '4', '3', '109', '0', '25', '22', '24', '17', '24'), +('2', '4', '4', '126', '0', '26', '24', '25', '18', '24'), +('2', '4', '5', '143', '0', '27', '25', '26', '18', '24'), +('2', '4', '6', '160', '0', '27', '26', '26', '18', '25'), +('2', '4', '7', '177', '0', '28', '28', '27', '18', '25'), +('2', '4', '8', '194', '0', '29', '29', '27', '18', '25'), +('2', '4', '9', '211', '0', '30', '30', '28', '18', '26'), +('2', '4', '10', '228', '0', '30', '32', '29', '19', '26'), +('2', '4', '11', '245', '0', '31', '33', '30', '19', '27'), +('2', '4', '12', '262', '0', '32', '34', '30', '19', '27'), +('2', '4', '13', '279', '0', '33', '36', '31', '19', '27'), +('2', '4', '14', '296', '0', '33', '37', '32', '19', '28'), +('2', '4', '15', '313', '0', '34', '39', '32', '20', '28'), +('2', '4', '16', '331', '0', '35', '40', '33', '20', '29'), +('2', '4', '17', '350', '0', '36', '41', '34', '20', '29'), +('2', '4', '18', '370', '0', '37', '43', '35', '20', '29'), +('2', '4', '19', '370', '0', '37', '43', '35', '20', '29'), +('2', '4', '20', '370', '0', '37', '43', '35', '20', '29'), +('2', '4', '21', '436', '0', '39', '48', '37', '21', '31'), +('2', '4', '22', '460', '0', '40', '49', '38', '21', '31'), +('2', '4', '23', '485', '0', '41', '51', '39', '21', '32'), +('2', '4', '24', '511', '0', '42', '52', '39', '22', '32'), +('2', '4', '25', '538', '0', '43', '54', '40', '22', '33'), +('2', '4', '26', '566', '0', '44', '56', '41', '22', '33'), +('2', '4', '27', '595', '0', '45', '57', '42', '22', '33'), +('2', '4', '28', '625', '0', '46', '59', '43', '22', '34'), +('2', '4', '29', '656', '0', '46', '61', '44', '23', '34'), +('2', '4', '30', '688', '0', '47', '63', '44', '23', '35'), +('2', '4', '31', '721', '0', '48', '64', '45', '23', '35'), +('2', '4', '32', '755', '0', '49', '66', '46', '23', '36'), +('2', '4', '33', '790', '0', '50', '68', '47', '24', '36'), +('2', '4', '34', '826', '0', '51', '70', '48', '24', '37'), +('2', '4', '35', '863', '0', '52', '72', '49', '24', '37'), +('2', '4', '36', '901', '0', '54', '74', '50', '25', '38'), +('2', '4', '37', '940', '0', '55', '75', '51', '25', '39'), +('2', '4', '38', '985', '0', '56', '77', '52', '25', '39'), +('2', '4', '39', '1021', '0', '57', '79', '53', '25', '40'), +('2', '4', '40', '1063', '0', '58', '81', '54', '26', '40'), +('2', '4', '41', '1106', '0', '59', '83', '55', '26', '41'), +('2', '4', '42', '1150', '0', '60', '85', '56', '26', '41'), +('2', '4', '43', '1195', '0', '61', '87', '57', '26', '42'), +('2', '4', '44', '1241', '0', '62', '90', '58', '27', '42'), +('2', '4', '45', '1288', '0', '64', '92', '59', '27', '43'), +('2', '4', '46', '1336', '0', '65', '94', '60', '27', '44'), +('2', '4', '47', '1385', '0', '66', '96', '61', '28', '44'), +('2', '4', '48', '1435', '0', '67', '98', '62', '28', '45'), +('2', '4', '49', '1486', '0', '68', '100', '64', '28', '46'), +('2', '4', '50', '1538', '0', '70', '103', '65', '29', '46'), +('2', '4', '51', '1591', '0', '71', '105', '66', '29', '47'), +('2', '4', '52', '1645', '0', '72', '107', '67', '29', '47'), +('2', '4', '53', '1700', '0', '73', '110', '68', '30', '48'), +('2', '4', '54', '1756', '0', '75', '112', '69', '30', '49'), +('2', '4', '55', '1813', '0', '76', '114', '71', '30', '49'), +('2', '4', '56', '1871', '0', '77', '117', '72', '31', '50'), +('2', '4', '57', '1930', '0', '79', '119', '73', '31', '51'), +('2', '4', '58', '1990', '0', '80', '122', '74', '31', '52'), +('2', '4', '59', '2051', '0', '82', '124', '76', '32', '52'), +('2', '4', '60', '2113', '0', '83', '127', '77', '32', '53'), +('2', '7', '1', '97', '71', '24', '17', '23', '18', '25'), +('2', '7', '2', '94', '80', '25', '17', '24', '19', '26'), +('2', '7', '3', '111', '88', '25', '18', '25', '20', '27'), +('2', '7', '4', '128', '111', '26', '18', '26', '20', '28'), +('2', '7', '5', '145', '135', '27', '19', '26', '21', '29'), +('2', '7', '6', '162', '160', '28', '19', '27', '22', '30'), +('2', '7', '7', '179', '186', '29', '19', '28', '23', '31'), +('2', '7', '8', '196', '213', '29', '20', '29', '24', '31'), +('2', '7', '9', '213', '256', '30', '20', '30', '25', '32'), +('2', '7', '10', '230', '270', '31', '21', '31', '25', '33'), +('2', '7', '11', '247', '300', '32', '21', '32', '26', '34'), +('2', '7', '12', '264', '331', '33', '22', '33', '27', '35'), +('2', '7', '13', '281', '363', '33', '22', '34', '28', '36'), +('2', '7', '14', '298', '396', '34', '23', '35', '29', '37'), +('2', '7', '15', '315', '430', '35', '23', '36', '30', '39'), +('2', '7', '16', '332', '465', '36', '24', '37', '31', '40'), +('2', '7', '17', '350', '501', '37', '24', '38', '32', '41'), +('2', '7', '18', '369', '538', '38', '25', '39', '33', '42'), +('2', '7', '19', '389', '576', '39', '25', '40', '34', '43'), +('2', '7', '20', '410', '615', '40', '26', '41', '35', '44'), +('2', '7', '21', '432', '655', '41', '26', '42', '36', '45'), +('2', '7', '22', '455', '731', '41', '27', '43', '37', '46'), +('2', '7', '23', '479', '738', '42', '27', '44', '38', '47'), +('2', '7', '24', '504', '781', '43', '28', '45', '39', '49'), +('2', '7', '25', '530', '825', '44', '28', '47', '40', '50'), +('2', '7', '26', '557', '914', '45', '29', '48', '41', '51'), +('2', '7', '27', '585', '916', '46', '29', '49', '42', '52'), +('2', '7', '28', '614', '963', '47', '30', '50', '43', '53'), +('2', '7', '29', '644', '1011', '48', '30', '51', '44', '55'), +('2', '7', '30', '675', '1113', '49', '31', '52', '45', '56'), +('2', '7', '31', '707', '1124', '51', '31', '54', '47', '57'), +('2', '7', '32', '740', '1232', '52', '32', '55', '48', '59'), +('2', '7', '33', '774', '1283', '53', '33', '56', '49', '60'), +('2', '7', '34', '809', '1319', '54', '33', '57', '50', '61'), +('2', '7', '35', '845', '1370', '55', '34', '59', '51', '63'), +('2', '7', '36', '882', '1438', '56', '35', '60', '53', '64'), +('2', '7', '37', '920', '1489', '57', '35', '61', '54', '65'), +('2', '7', '38', '959', '1541', '58', '36', '63', '55', '67'), +('2', '7', '39', '999', '1593', '59', '36', '64', '56', '68'), +('2', '7', '40', '1040', '1643', '61', '37', '65', '58', '70'), +('2', '7', '41', '1082', '1675', '62', '38', '67', '59', '71'), +('2', '7', '42', '1125', '1697', '63', '38', '68', '60', '73'), +('2', '7', '43', '1169', '1710', '64', '39', '70', '61', '74'), +('2', '7', '44', '1214', '1761', '66', '40', '71', '63', '76'), +('2', '7', '45', '1260', '1885', '67', '40', '73', '64', '77'), +('2', '7', '46', '1307', '1952', '68', '41', '74', '66', '79'), +('2', '7', '47', '1355', '2004', '69', '42', '76', '67', '80'), +('2', '7', '48', '1404', '2055', '71', '43', '77', '68', '82'), +('2', '7', '49', '1454', '2106', '72', '43', '79', '70', '84'), +('2', '7', '50', '1505', '2142', '73', '44', '80', '71', '85'), +('2', '7', '51', '1557', '2210', '75', '45', '82', '73', '87'), +('2', '7', '52', '1610', '2261', '76', '46', '83', '74', '89'), +('2', '7', '53', '1664', '2312', '78', '46', '85', '76', '90'), +('2', '7', '54', '1719', '2334', '79', '47', '87', '77', '92'), +('2', '7', '55', '1775', '2364', '80', '48', '88', '79', '94'), +('2', '7', '56', '1832', '2415', '82', '49', '90', '80', '96'), +('2', '7', '57', '1890', '2518', '83', '50', '92', '82', '97'), +('2', '7', '58', '1949', '2570', '85', '50', '93', '84', '99'), +('2', '7', '59', '2009', '2621', '86', '51', '95', '85', '101'), +('2', '7', '60', '2070', '2700', '88', '52', '97', '87', '103'), +('2', '9', '1', '73', '109', '23', '17', '23', '19', '25'), +('2', '9', '2', '88', '118', '23', '17', '24', '20', '26'), +('2', '9', '3', '103', '142', '24', '18', '24', '21', '27'), +('2', '9', '4', '118', '167', '24', '18', '25', '22', '28'), +('2', '9', '5', '133', '193', '24', '18', '25', '23', '29'), +('2', '9', '6', '148', '220', '24', '19', '26', '24', '30'), +('2', '9', '7', '163', '248', '25', '19', '26', '25', '32'), +('2', '9', '8', '178', '277', '25', '19', '27', '26', '33'), +('2', '9', '9', '193', '307', '25', '20', '27', '27', '34'), +('2', '9', '10', '208', '338', '26', '20', '28', '28', '35'), +('2', '9', '11', '223', '370', '26', '21', '28', '30', '36'), +('2', '9', '12', '238', '403', '26', '21', '29', '31', '37'), +('2', '9', '13', '253', '437', '27', '21', '29', '32', '39'), +('2', '9', '14', '268', '472', '27', '22', '30', '33', '40'), +('2', '9', '15', '283', '508', '27', '22', '31', '34', '41'), +('2', '9', '16', '298', '545', '28', '23', '31', '35', '42'), +('2', '9', '17', '313', '583', '28', '23', '32', '37', '44'), +('2', '9', '18', '329', '622', '28', '23', '32', '38', '45'), +('2', '9', '19', '364', '662', '29', '24', '33', '39', '46'), +('2', '9', '20', '376', '703', '29', '24', '34', '40', '48'), +('2', '9', '21', '408', '745', '29', '25', '34', '42', '49'), +('2', '9', '22', '408', '788', '30', '25', '34', '43', '50'), +('2', '9', '23', '424', '832', '30', '26', '35', '44', '52'), +('2', '9', '24', '446', '877', '31', '26', '35', '46', '53'), +('2', '9', '25', '469', '923', '31', '27', '36', '47', '55'), +('2', '9', '26', '493', '970', '31', '27', '37', '48', '56'), +('2', '9', '27', '518', '1018', '32', '27', '37', '50', '57'), +('2', '9', '28', '544', '1067', '32', '28', '38', '51', '59'), +('2', '9', '29', '571', '1117', '33', '28', '39', '53', '60'), +('2', '9', '30', '599', '1168', '33', '29', '39', '54', '62'), +('2', '9', '31', '628', '1219', '33', '29', '40', '55', '64'), +('2', '9', '32', '658', '1270', '34', '30', '41', '57', '65'), +('2', '9', '33', '679', '1321', '34', '30', '41', '58', '68'), +('2', '9', '34', '721', '1372', '35', '31', '42', '60', '68'), +('2', '9', '35', '754', '1423', '35', '31', '43', '61', '70'), +('2', '9', '36', '788', '1474', '36', '32', '44', '63', '71'), +('2', '9', '37', '823', '1525', '36', '33', '45', '65', '73'), +('2', '9', '38', '859', '1576', '36', '33', '46', '66', '75'), +('2', '9', '39', '896', '1627', '37', '34', '46', '68', '77'), +('2', '9', '40', '934', '1678', '37', '34', '47', '69', '78'), +('2', '9', '41', '973', '1729', '38', '35', '47', '71', '80'), +('2', '9', '42', '993', '1780', '38', '35', '47', '73', '83'), +('2', '9', '43', '1054', '1831', '39', '36', '50', '74', '84'), +('2', '9', '44', '1096', '1882', '39', '36', '51', '76', '85'), +('2', '9', '45', '1139', '1933', '40', '37', '51', '78', '87'), +('2', '9', '46', '1183', '1984', '40', '38', '52', '80', '89'), +('2', '9', '47', '1228', '2035', '41', '38', '53', '81', '91'), +('2', '9', '48', '1274', '2086', '41', '39', '53', '83', '93'), +('2', '9', '49', '1321', '2137', '42', '40', '54', '85', '96'), +('2', '9', '50', '1369', '2188', '42', '40', '56', '87', '97'), +('2', '9', '51', '1408', '2239', '43', '41', '56', '89', '99'), +('2', '9', '52', '1468', '2290', '43', '41', '58', '91', '101'), +('2', '9', '53', '1519', '2341', '44', '42', '59', '93', '103'), +('2', '9', '54', '1551', '2392', '45', '43', '60', '95', '105'), +('2', '9', '55', '1624', '2443', '45', '43', '61', '97', '106'), +('2', '9', '56', '1678', '2494', '46', '44', '62', '99', '109'), +('2', '9', '57', '1727', '2545', '46', '45', '62', '101', '110'), +('2', '9', '58', '1779', '2596', '47', '46', '64', '103', '114'), +('2', '9', '59', '1836', '2647', '47', '46', '65', '105', '116'), +('2', '9', '60', '1904', '2698', '48', '47', '66', '107', '118'), +('3', '1', '1', '90', '0', '25', '16', '25', '19', '19'), +('3', '1', '2', '109', '0', '26', '17', '26', '19', '19'), +('3', '1', '3', '128', '0', '27', '17', '27', '19', '20'), +('3', '1', '4', '147', '0', '28', '18', '28', '19', '20'), +('3', '1', '5', '166', '0', '30', '19', '29', '19', '20'), +('3', '1', '6', '185', '0', '31', '20', '30', '20', '20'), +('3', '1', '7', '204', '0', '32', '20', '31', '20', '21'), +('3', '1', '8', '223', '0', '33', '21', '32', '20', '21'), +('3', '1', '9', '242', '0', '34', '22', '33', '20', '21'), +('3', '1', '10', '261', '0', '35', '22', '34', '20', '22'), +('3', '1', '11', '280', '0', '37', '23', '36', '20', '22'), +('3', '1', '12', '299', '0', '38', '24', '37', '20', '22'), +('3', '1', '13', '318', '0', '39', '25', '38', '20', '23'), +('3', '1', '14', '338', '0', '41', '26', '39', '21', '23'), +('3', '1', '15', '359', '0', '42', '26', '40', '21', '23'), +('3', '1', '16', '381', '0', '43', '27', '41', '21', '24'), +('3', '1', '17', '404', '0', '44', '28', '43', '21', '24'), +('3', '1', '18', '428', '0', '46', '29', '44', '21', '24'), +('3', '1', '19', '453', '0', '47', '30', '45', '21', '25'), +('3', '1', '20', '479', '0', '49', '31', '46', '21', '25'), +('3', '1', '21', '506', '0', '50', '31', '48', '22', '25'), +('3', '1', '22', '534', '0', '51', '32', '49', '22', '26'), +('3', '1', '23', '563', '0', '53', '33', '50', '22', '26'), +('3', '1', '24', '593', '0', '54', '34', '52', '22', '27'), +('3', '1', '25', '624', '0', '56', '35', '53', '22', '27'), +('3', '1', '26', '656', '0', '57', '36', '54', '22', '27'), +('3', '1', '27', '689', '0', '59', '37', '56', '22', '28'), +('3', '1', '28', '723', '0', '60', '38', '57', '23', '28'), +('3', '1', '29', '758', '0', '62', '39', '59', '23', '29'), +('3', '1', '30', '794', '0', '64', '40', '60', '23', '29'), +('3', '1', '31', '831', '0', '65', '41', '61', '23', '29'), +('3', '1', '32', '869', '0', '67', '42', '63', '23', '30'), +('3', '1', '33', '908', '0', '68', '43', '64', '23', '30'), +('3', '1', '34', '948', '0', '70', '44', '66', '24', '31'), +('3', '1', '35', '989', '0', '72', '45', '67', '24', '31'), +('3', '1', '36', '1031', '0', '74', '46', '69', '24', '32'), +('3', '1', '37', '1075', '0', '75', '47', '71', '24', '32'), +('3', '1', '38', '1121', '0', '77', '48', '72', '24', '32'), +('3', '1', '39', '1169', '0', '79', '49', '74', '25', '33'), +('3', '1', '40', '1219', '0', '81', '50', '75', '25', '33'), +('3', '1', '41', '1271', '0', '82', '52', '77', '25', '34'), +('3', '1', '42', '1325', '0', '84', '53', '79', '25', '34'), +('3', '1', '43', '1381', '0', '86', '54', '80', '25', '35'), +('3', '1', '44', '1439', '0', '88', '55', '82', '25', '35'), +('3', '1', '45', '1499', '0', '90', '56', '84', '26', '36'), +('3', '1', '46', '1561', '0', '92', '57', '86', '26', '36'), +('3', '1', '47', '1625', '0', '94', '59', '87', '26', '37'), +('3', '1', '48', '1691', '0', '96', '60', '89', '26', '37'), +('3', '1', '49', '1759', '0', '98', '61', '91', '27', '38'), +('3', '1', '50', '1829', '0', '100', '62', '93', '27', '38'), +('3', '1', '51', '1901', '0', '102', '64', '95', '27', '39'), +('3', '1', '52', '1975', '0', '104', '65', '97', '27', '39'), +('3', '1', '53', '2051', '0', '106', '66', '99', '27', '40'), +('3', '1', '54', '2129', '0', '108', '68', '101', '28', '41'), +('3', '1', '55', '2209', '0', '111', '69', '103', '28', '41'), +('3', '1', '56', '2291', '0', '113', '70', '105', '28', '42'), +('3', '1', '57', '2375', '0', '115', '72', '107', '28', '42'), +('3', '1', '58', '2461', '0', '117', '73', '109', '29', '43'), +('3', '1', '59', '2549', '0', '120', '75', '111', '29', '43'), +('3', '1', '60', '2639', '0', '122', '76', '113', '29', '44'), +('3', '2', '1', '88', '79', '24', '16', '25', '19', '20'), +('3', '2', '2', '106', '84', '25', '17', '26', '20', '21'), +('3', '2', '3', '124', '104', '26', '17', '27', '20', '21'), +('3', '2', '4', '142', '125', '27', '18', '28', '21', '22'), +('3', '2', '5', '160', '147', '28', '18', '29', '21', '23'), +('3', '2', '6', '178', '170', '29', '19', '30', '22', '23'), +('3', '2', '7', '196', '194', '30', '19', '31', '23', '24'), +('3', '2', '8', '214', '219', '31', '20', '31', '23', '24'), +('3', '2', '9', '232', '245', '32', '20', '32', '24', '25'), +('3', '2', '10', '250', '272', '33', '21', '33', '24', '26'), +('3', '2', '11', '268', '300', '34', '21', '34', '25', '27'), +('3', '2', '12', '286', '329', '35', '22', '35', '26', '27'), +('3', '2', '13', '304', '359', '36', '23', '36', '26', '28'), +('3', '2', '14', '322', '390', '37', '23', '37', '27', '29'), +('3', '2', '15', '341', '422', '38', '24', '39', '28', '29'), +('3', '2', '16', '361', '455', '40', '24', '40', '28', '30'), +('3', '2', '17', '382', '489', '41', '25', '41', '29', '31'), +('3', '2', '18', '404', '524', '42', '26', '42', '30', '32'), +('3', '2', '19', '427', '560', '43', '26', '43', '30', '32'), +('3', '2', '20', '451', '597', '44', '27', '44', '31', '33'), +('3', '2', '21', '476', '635', '45', '28', '45', '32', '34'), +('3', '2', '22', '502', '674', '47', '28', '46', '33', '35'), +('3', '2', '23', '529', '714', '48', '29', '47', '33', '36'), +('3', '2', '24', '557', '755', '49', '30', '49', '34', '36'), +('3', '2', '25', '586', '797', '50', '30', '50', '35', '37'), +('3', '2', '26', '616', '839', '52', '31', '51', '36', '38'), +('3', '2', '27', '647', '881', '53', '32', '52', '36', '39'), +('3', '2', '28', '679', '923', '54', '32', '53', '37', '40'), +('3', '2', '29', '712', '965', '56', '33', '55', '38', '41'), +('3', '2', '30', '746', '1007', '57', '34', '56', '39', '41'), +('3', '2', '31', '781', '1049', '58', '35', '57', '40', '42'), +('3', '2', '32', '817', '1091', '60', '35', '59', '41', '43'), +('3', '2', '33', '854', '1133', '61', '36', '60', '41', '44'), +('3', '2', '34', '892', '1175', '63', '37', '61', '42', '45'), +('3', '2', '35', '931', '1217', '64', '38', '63', '43', '46'), +('3', '2', '36', '971', '1259', '66', '39', '64', '44', '47'), +('3', '2', '37', '1012', '1301', '67', '39', '65', '45', '48'), +('3', '2', '38', '1054', '1343', '69', '40', '67', '46', '49'), +('3', '2', '39', '1097', '1385', '70', '41', '68', '47', '50'), +('3', '2', '40', '1141', '1427', '72', '42', '70', '48', '51'), +('3', '2', '41', '1186', '1469', '73', '43', '71', '49', '52'), +('3', '2', '42', '1232', '1511', '75', '43', '73', '50', '53'), +('3', '2', '43', '1279', '1553', '76', '44', '74', '51', '54'), +('3', '2', '44', '1327', '1595', '78', '45', '76', '51', '55'), +('3', '2', '45', '1376', '1637', '80', '46', '77', '52', '56'), +('3', '2', '46', '1426', '1679', '81', '47', '79', '53', '57'), +('3', '2', '47', '1477', '1721', '83', '48', '80', '55', '58'), +('3', '2', '48', '1529', '1763', '85', '49', '82', '56', '59'), +('3', '2', '49', '1582', '1805', '86', '50', '84', '57', '61'), +('3', '2', '50', '1636', '1847', '88', '51', '85', '58', '62'), +('3', '2', '51', '1691', '1889', '90', '52', '87', '59', '63'), +('3', '2', '52', '1747', '1931', '92', '53', '89', '60', '64'), +('3', '2', '53', '1804', '1973', '94', '54', '90', '61', '65'), +('3', '2', '54', '1862', '2015', '95', '55', '92', '62', '66'), +('3', '2', '55', '1921', '2057', '97', '56', '94', '63', '68'), +('3', '2', '56', '1981', '2099', '99', '57', '96', '64', '69'), +('3', '2', '57', '2042', '2141', '101', '58', '97', '65', '70'), +('3', '2', '58', '2104', '2183', '103', '59', '99', '67', '71'), +('3', '2', '59', '2167', '2225', '105', '60', '101', '68', '73'), +('3', '2', '60', '2231', '2267', '107', '61', '103', '69', '74'), +('3', '3', '1', '86', '80', '22', '19', '24', '19', '20'), +('3', '3', '2', '103', '90', '22', '20', '25', '20', '21'), +('3', '3', '3', '120', '111', '23', '21', '26', '20', '21'), +('3', '3', '4', '137', '133', '23', '23', '26', '21', '22'), +('3', '3', '5', '154', '156', '24', '24', '27', '21', '22'), +('3', '3', '6', '171', '180', '24', '25', '28', '22', '23'), +('3', '3', '7', '188', '205', '24', '26', '29', '22', '23'), +('3', '3', '8', '205', '231', '25', '27', '30', '23', '24'), +('3', '3', '9', '222', '258', '25', '29', '31', '23', '25'), +('3', '3', '10', '239', '286', '26', '30', '31', '24', '25'), +('3', '3', '11', '256', '315', '26', '31', '32', '24', '26'), +('3', '3', '12', '273', '345', '27', '33', '33', '25', '27'), +('3', '3', '13', '290', '376', '27', '34', '34', '26', '27'), +('3', '3', '14', '308', '408', '28', '35', '35', '26', '28'), +('3', '3', '15', '327', '441', '28', '37', '36', '27', '28'), +('3', '3', '16', '347', '475', '29', '38', '37', '27', '29'), +('3', '3', '17', '368', '510', '29', '39', '38', '28', '30'), +('3', '3', '18', '390', '546', '30', '41', '39', '29', '31'), +('3', '3', '19', '413', '583', '30', '42', '40', '29', '31'), +('3', '3', '20', '437', '621', '31', '44', '41', '30', '32'), +('3', '3', '21', '462', '660', '31', '45', '42', '31', '33'), +('3', '3', '22', '488', '700', '32', '47', '43', '31', '33'), +('3', '3', '23', '515', '741', '32', '48', '44', '32', '34'), +('3', '3', '24', '543', '783', '33', '50', '45', '33', '35'), +('3', '3', '25', '572', '826', '33', '51', '46', '33', '36'), +('3', '3', '26', '602', '870', '34', '53', '47', '34', '36'), +('3', '3', '27', '633', '915', '34', '55', '48', '35', '37'), +('3', '3', '28', '665', '960', '35', '56', '49', '35', '38'), +('3', '3', '29', '698', '1005', '35', '58', '50', '36', '39'), +('3', '3', '30', '732', '1050', '36', '60', '51', '37', '39'), +('3', '3', '31', '767', '1095', '36', '61', '53', '38', '40'), +('3', '3', '32', '803', '1140', '37', '63', '54', '38', '41'), +('3', '3', '33', '840', '1185', '38', '65', '55', '39', '42'), +('3', '3', '34', '878', '1230', '38', '66', '56', '40', '43'), +('3', '3', '35', '917', '1275', '39', '68', '57', '41', '44'), +('3', '3', '36', '957', '1320', '40', '70', '59', '42', '45'), +('3', '3', '37', '998', '1365', '40', '72', '60', '42', '45'), +('3', '3', '38', '1040', '1410', '41', '74', '61', '43', '46'), +('3', '3', '39', '1083', '1455', '41', '76', '62', '44', '47'), +('3', '3', '40', '1127', '1500', '42', '77', '64', '45', '48'), +('3', '3', '41', '1172', '1545', '43', '79', '65', '46', '49'), +('3', '3', '42', '1218', '1590', '43', '81', '66', '46', '50'), +('3', '3', '43', '1265', '1635', '44', '83', '67', '47', '51'), +('3', '3', '44', '1313', '1680', '45', '85', '69', '48', '52'), +('3', '3', '45', '1362', '1725', '45', '87', '70', '49', '53'), +('3', '3', '46', '1412', '1770', '46', '89', '72', '50', '54'), +('3', '3', '47', '1463', '1815', '47', '91', '73', '51', '55'), +('3', '3', '48', '1515', '1860', '48', '94', '74', '52', '56'), +('3', '3', '49', '1568', '1905', '48', '96', '76', '53', '57'), +('3', '3', '50', '1622', '1950', '49', '98', '77', '54', '58'), +('3', '3', '51', '1677', '1995', '50', '100', '79', '55', '59'), +('3', '3', '52', '1733', '2040', '51', '102', '80', '56', '60'), +('3', '3', '53', '1790', '2085', '51', '104', '82', '57', '61'), +('3', '3', '54', '1848', '2130', '52', '107', '83', '58', '62'), +('3', '3', '55', '1907', '2175', '53', '109', '85', '59', '63'), +('3', '3', '56', '1967', '2220', '54', '111', '86', '60', '64'), +('3', '3', '57', '2028', '2265', '55', '114', '88', '61', '66'), +('3', '3', '58', '2090', '2310', '55', '116', '90', '62', '67'), +('3', '3', '59', '2153', '2355', '56', '119', '91', '63', '68'), +('3', '3', '60', '2217', '2400', '57', '121', '93', '64', '69'), +('3', '4', '1', '85', '0', '23', '19', '24', '19', '19'), +('3', '4', '2', '102', '0', '24', '20', '25', '19', '19'), +('3', '4', '3', '119', '0', '24', '21', '25', '19', '20'), +('3', '4', '4', '136', '0', '25', '23', '26', '20', '20'), +('3', '4', '5', '153', '0', '26', '24', '27', '20', '20'), +('3', '4', '6', '170', '0', '26', '25', '27', '20', '21'), +('3', '4', '7', '187', '0', '27', '27', '28', '20', '21'), +('3', '4', '8', '204', '0', '28', '28', '28', '20', '21'), +('3', '4', '9', '221', '0', '29', '29', '29', '20', '22'), +('3', '4', '10', '238', '0', '29', '31', '30', '21', '22'), +('3', '4', '11', '255', '0', '30', '32', '31', '21', '23'), +('3', '4', '12', '272', '0', '31', '33', '31', '21', '23'), +('3', '4', '13', '289', '0', '32', '35', '32', '21', '23'), +('3', '4', '14', '306', '0', '32', '36', '33', '21', '24'), +('3', '4', '15', '323', '0', '33', '38', '33', '22', '24'), +('3', '4', '16', '341', '0', '34', '39', '34', '22', '25'), +('3', '4', '17', '360', '0', '35', '40', '35', '22', '25'), +('3', '4', '18', '380', '0', '36', '42', '36', '22', '25'), +('3', '4', '19', '401', '0', '37', '44', '36', '22', '26'), +('3', '4', '20', '423', '0', '37', '45', '37', '23', '26'), +('3', '4', '21', '446', '0', '38', '47', '38', '23', '27'), +('3', '4', '22', '470', '0', '39', '48', '39', '23', '27'), +('3', '4', '23', '495', '0', '40', '50', '40', '23', '28'), +('3', '4', '24', '521', '0', '41', '51', '40', '24', '28'), +('3', '4', '25', '548', '0', '42', '53', '41', '24', '29'), +('3', '4', '26', '576', '0', '43', '55', '42', '24', '29'), +('3', '4', '27', '605', '0', '44', '56', '43', '24', '29'), +('3', '4', '28', '635', '0', '45', '58', '44', '24', '30'), +('3', '4', '29', '666', '0', '45', '60', '45', '25', '30'), +('3', '4', '30', '698', '0', '46', '62', '45', '25', '31'), +('3', '4', '31', '731', '0', '47', '63', '46', '25', '31'), +('3', '4', '32', '765', '0', '48', '65', '47', '25', '32'), +('3', '4', '33', '800', '0', '49', '67', '48', '26', '32'), +('3', '4', '34', '836', '0', '50', '69', '49', '26', '33'), +('3', '4', '35', '873', '0', '51', '71', '50', '26', '33'), +('3', '4', '36', '911', '0', '53', '73', '51', '27', '34'), +('3', '4', '37', '950', '0', '54', '74', '52', '27', '35'), +('3', '4', '38', '990', '0', '55', '76', '53', '27', '35'), +('3', '4', '39', '1031', '0', '56', '78', '54', '27', '36'), +('3', '4', '40', '1073', '0', '57', '80', '55', '28', '36'), +('3', '4', '41', '1116', '0', '58', '82', '56', '28', '37'), +('3', '4', '42', '1160', '0', '59', '84', '57', '28', '37'), +('3', '4', '43', '1205', '0', '60', '86', '58', '28', '38'), +('3', '4', '44', '1251', '0', '61', '89', '59', '29', '38'), +('3', '4', '45', '1298', '0', '63', '91', '60', '29', '39'), +('3', '4', '46', '1346', '0', '64', '93', '61', '29', '40'), +('3', '4', '47', '1395', '0', '65', '95', '62', '30', '40'), +('3', '4', '48', '1445', '0', '66', '97', '63', '30', '41'), +('3', '4', '49', '1496', '0', '67', '99', '65', '30', '42'), +('3', '4', '50', '1548', '0', '69', '102', '66', '31', '42'), +('3', '4', '51', '1601', '0', '70', '104', '67', '31', '43'), +('3', '4', '52', '1655', '0', '71', '106', '68', '31', '43'), +('3', '4', '53', '1710', '0', '72', '109', '69', '32', '44'), +('3', '4', '54', '1766', '0', '74', '111', '70', '32', '45'), +('3', '4', '55', '1823', '0', '75', '113', '72', '32', '45'), +('3', '4', '56', '1881', '0', '76', '116', '73', '33', '46'), +('3', '4', '57', '1940', '0', '78', '118', '74', '33', '47'), +('3', '4', '58', '2000', '0', '79', '121', '75', '33', '48'), +('3', '4', '59', '2061', '0', '81', '123', '77', '34', '48'), +('3', '4', '60', '2123', '0', '82', '126', '78', '34', '49'), +('3', '5', '1', '91', '128', '22', '16', '23', '21', '22'), +('3', '5', '2', '97', '169', '22', '16', '23', '22', '23'), +('3', '5', '3', '112', '194', '22', '16', '24', '23', '24'), +('3', '5', '4', '127', '220', '23', '17', '24', '24', '26'), +('3', '5', '5', '142', '247', '23', '17', '24', '26', '27'), +('3', '5', '6', '157', '275', '23', '17', '25', '27', '28'), +('3', '5', '7', '172', '304', '23', '17', '25', '28', '29'), +('3', '5', '8', '187', '334', '23', '18', '25', '29', '30'), +('3', '5', '9', '202', '365', '23', '18', '26', '30', '32'), +('3', '5', '10', '217', '412', '24', '18', '26', '32', '33'), +('3', '5', '11', '232', '430', '24', '18', '27', '33', '34'), +('3', '5', '12', '247', '464', '24', '19', '27', '34', '36'), +('3', '5', '13', '262', '499', '24', '19', '27', '35', '37'), +('3', '5', '14', '277', '535', '24', '19', '28', '37', '38'), +('3', '5', '15', '292', '572', '25', '19', '28', '38', '40'), +('3', '5', '16', '307', '610', '25', '20', '29', '39', '41'), +('3', '5', '17', '322', '664', '25', '20', '29', '41', '42'), +('3', '5', '18', '337', '689', '25', '20', '29', '42', '44'), +('3', '5', '19', '352', '730', '25', '21', '30', '43', '45'), +('3', '5', '20', '367', '772', '26', '21', '30', '45', '47'), +('3', '5', '21', '382', '815', '26', '21', '31', '46', '48'), +('3', '5', '22', '398', '874', '26', '21', '31', '48', '50'), +('3', '5', '23', '415', '904', '26', '22', '32', '49', '51'), +('3', '5', '24', '433', '965', '27', '22', '32', '51', '53'), +('3', '5', '25', '452', '997', '27', '22', '33', '52', '54'), +('3', '5', '26', '472', '1060', '27', '23', '33', '54', '56'), +('3', '5', '27', '493', '1094', '27', '23', '33', '55', '58'), +('3', '5', '28', '515', '1159', '27', '23', '34', '57', '59'), +('3', '5', '29', '538', '1195', '28', '24', '34', '58', '61'), +('3', '5', '30', '562', '1247', '28', '24', '35', '60', '63'), +('3', '5', '31', '587', '1315', '28', '24', '35', '62', '64'), +('3', '5', '32', '613', '1354', '28', '25', '36', '63', '66'), +('3', '5', '33', '640', '1423', '29', '25', '36', '65', '68'), +('3', '5', '34', '668', '1477', '29', '25', '37', '67', '69'), +('3', '5', '35', '697', '1516', '29', '26', '37', '68', '71'), +('3', '5', '36', '727', '1570', '30', '26', '38', '70', '73'), +('3', '5', '37', '758', '1639', '30', '26', '39', '72', '75'), +('3', '5', '38', '790', '1693', '30', '27', '39', '74', '77'), +('3', '5', '39', '823', '1732', '30', '27', '40', '75', '79'), +('3', '5', '40', '857', '1786', '31', '27', '40', '77', '80'), +('3', '5', '41', '892', '1855', '31', '28', '41', '79', '82'), +('3', '5', '42', '928', '1909', '31', '28', '41', '81', '84'), +('3', '5', '43', '965', '1963', '31', '29', '42', '83', '86'), +('3', '5', '44', '1003', '2017', '32', '29', '42', '85', '88'), +('3', '5', '45', '1042', '2071', '32', '29', '43', '87', '90'), +('3', '5', '46', '1082', '2125', '32', '30', '44', '89', '92'), +('3', '5', '47', '1123', '2179', '33', '30', '44', '91', '94'), +('3', '5', '48', '1165', '2233', '33', '31', '45', '93', '97'), +('3', '5', '49', '1208', '2287', '33', '31', '46', '95', '99'), +('3', '5', '50', '1252', '2341', '34', '31', '46', '97', '101'), +('3', '5', '51', '1297', '2395', '34', '32', '47', '99', '103'), +('3', '5', '52', '1343', '2449', '34', '32', '47', '101', '105'), +('3', '5', '53', '1390', '2503', '35', '33', '48', '103', '107'), +('3', '5', '54', '1438', '2557', '35', '33', '49', '105', '110'), +('3', '5', '55', '1487', '2611', '35', '34', '49', '108', '112'), +('3', '5', '56', '1537', '2665', '36', '34', '50', '110', '114'), +('3', '5', '57', '1588', '2719', '36', '35', '51', '112', '117'), +('3', '5', '58', '1640', '2773', '36', '35', '52', '114', '119'), +('3', '5', '59', '1693', '2827', '37', '36', '52', '117', '122'), +('3', '5', '60', '1747', '2881', '37', '36', '53', '119', '124'), +('4', '1', '1', '50', '0', '20', '25', '21', '20', '20'), +('4', '1', '2', '69', '0', '21', '26', '22', '20', '20'), +('4', '1', '3', '88', '0', '22', '26', '23', '20', '21'), +('4', '1', '4', '107', '0', '23', '27', '24', '20', '21'), +('4', '1', '5', '126', '0', '25', '28', '25', '20', '21'), +('4', '1', '6', '145', '0', '26', '29', '26', '21', '21'), +('4', '1', '7', '164', '0', '27', '29', '27', '21', '22'), +('4', '1', '8', '183', '0', '28', '30', '28', '21', '22'), +('4', '1', '9', '202', '0', '29', '31', '29', '21', '22'), +('4', '1', '10', '221', '0', '30', '31', '30', '21', '23'), +('4', '1', '11', '240', '0', '32', '32', '32', '21', '23'), +('4', '1', '12', '259', '0', '33', '33', '33', '21', '23'), +('4', '1', '13', '278', '0', '34', '34', '34', '21', '24'), +('4', '1', '14', '298', '0', '36', '35', '35', '22', '24'), +('4', '1', '15', '319', '0', '37', '35', '36', '22', '24'), +('4', '1', '16', '341', '0', '38', '36', '37', '22', '25'), +('4', '1', '17', '364', '0', '39', '37', '39', '22', '25'), +('4', '1', '18', '388', '0', '41', '38', '40', '22', '25'), +('4', '1', '19', '413', '0', '42', '39', '41', '22', '26'), +('4', '1', '20', '439', '0', '44', '40', '42', '22', '26'), +('4', '1', '21', '466', '0', '45', '40', '44', '23', '26'), +('4', '1', '22', '494', '0', '46', '41', '45', '23', '27'), +('4', '1', '23', '523', '0', '48', '42', '46', '23', '27'), +('4', '1', '24', '553', '0', '49', '43', '48', '23', '28'), +('4', '1', '25', '584', '0', '51', '44', '49', '23', '28'), +('4', '1', '26', '616', '0', '52', '45', '50', '23', '28'), +('4', '1', '27', '649', '0', '54', '46', '52', '23', '29'), +('4', '1', '28', '683', '0', '55', '47', '53', '24', '29'), +('4', '1', '29', '718', '0', '57', '48', '55', '24', '30'), +('4', '1', '30', '754', '0', '59', '49', '56', '24', '30'), +('4', '1', '31', '791', '0', '60', '50', '57', '24', '30'), +('4', '1', '32', '829', '0', '62', '51', '59', '24', '31'), +('4', '1', '33', '868', '0', '63', '52', '60', '24', '31'), +('4', '1', '34', '908', '0', '65', '53', '62', '25', '32'), +('4', '1', '35', '949', '0', '67', '54', '63', '25', '32'), +('4', '1', '36', '991', '0', '69', '55', '65', '25', '33'), +('4', '1', '37', '1035', '0', '70', '56', '67', '25', '33'), +('4', '1', '38', '1081', '0', '72', '57', '68', '25', '33'), +('4', '1', '39', '1129', '0', '74', '58', '70', '26', '34'), +('4', '1', '40', '1179', '0', '76', '59', '71', '26', '34'), +('4', '1', '41', '1231', '0', '77', '61', '73', '26', '35'), +('4', '1', '42', '1285', '0', '79', '62', '75', '26', '35'), +('4', '1', '43', '1341', '0', '81', '63', '76', '26', '36'), +('4', '1', '44', '1399', '0', '83', '64', '78', '26', '36'), +('4', '1', '45', '1459', '0', '85', '65', '80', '27', '37'), +('4', '1', '46', '1521', '0', '87', '66', '82', '27', '37'), +('4', '1', '47', '1585', '0', '89', '68', '83', '27', '38'), +('4', '1', '48', '1651', '0', '91', '69', '85', '27', '38'), +('4', '1', '49', '1719', '0', '93', '70', '87', '28', '39'), +('4', '1', '50', '1789', '0', '95', '71', '89', '28', '39'), +('4', '1', '51', '1861', '0', '97', '73', '91', '28', '40'), +('4', '1', '52', '1935', '0', '99', '74', '93', '28', '40'), +('4', '1', '53', '2011', '0', '101', '75', '95', '28', '41'), +('4', '1', '54', '2089', '0', '103', '77', '97', '29', '42'), +('4', '1', '55', '2169', '0', '106', '78', '99', '29', '42'), +('4', '1', '56', '2251', '0', '108', '79', '101', '29', '43'), +('4', '1', '57', '2335', '0', '110', '81', '103', '29', '43'), +('4', '1', '58', '2421', '0', '112', '82', '105', '30', '44'), +('4', '1', '59', '2509', '0', '115', '84', '107', '30', '44'), +('4', '1', '60', '2599', '0', '117', '85', '109', '30', '45'), +('4', '3', '1', '46', '80', '17', '28', '20', '20', '21'), +('4', '3', '2', '63', '105', '17', '29', '21', '21', '22'), +('4', '3', '3', '80', '126', '18', '30', '22', '21', '22'), +('4', '3', '4', '97', '148', '18', '32', '22', '22', '23'), +('4', '3', '5', '114', '171', '19', '33', '23', '22', '23'), +('4', '3', '6', '131', '195', '19', '34', '24', '23', '24'), +('4', '3', '7', '148', '220', '19', '35', '25', '23', '24'), +('4', '3', '8', '165', '246', '20', '36', '26', '24', '25'), +('4', '3', '9', '182', '273', '20', '38', '27', '24', '26'), +('4', '3', '10', '199', '301', '21', '39', '27', '25', '26'), +('4', '3', '11', '216', '330', '21', '40', '28', '25', '27'), +('4', '3', '12', '233', '360', '22', '42', '29', '26', '28'), +('4', '3', '13', '250', '391', '22', '43', '30', '27', '28'), +('4', '3', '14', '268', '423', '23', '44', '31', '27', '29'), +('4', '3', '15', '287', '456', '23', '46', '32', '28', '29'), +('4', '3', '16', '307', '490', '24', '47', '33', '28', '30'), +('4', '3', '17', '328', '525', '24', '48', '34', '29', '31'), +('4', '3', '18', '350', '561', '25', '50', '35', '30', '32'), +('4', '3', '19', '373', '598', '25', '51', '36', '30', '32'), +('4', '3', '20', '397', '636', '26', '53', '37', '31', '33'), +('4', '3', '21', '422', '675', '26', '54', '38', '32', '34'), +('4', '3', '22', '448', '715', '27', '56', '39', '32', '34'), +('4', '3', '23', '475', '756', '27', '57', '40', '33', '35'), +('4', '3', '24', '503', '798', '28', '59', '41', '34', '36'), +('4', '3', '25', '532', '841', '28', '60', '42', '34', '37'), +('4', '3', '26', '562', '885', '29', '62', '43', '35', '37'), +('4', '3', '27', '593', '930', '29', '64', '44', '36', '38'), +('4', '3', '28', '625', '975', '30', '65', '45', '36', '39'), +('4', '3', '29', '658', '1020', '30', '67', '46', '37', '40'), +('4', '3', '30', '692', '1065', '31', '69', '47', '38', '40'), +('4', '3', '31', '727', '1110', '31', '70', '49', '39', '41'), +('4', '3', '32', '763', '1155', '32', '72', '50', '39', '42'), +('4', '3', '33', '800', '1200', '33', '74', '51', '40', '43'), +('4', '3', '34', '838', '1245', '33', '75', '52', '41', '44'), +('4', '3', '35', '877', '1290', '34', '77', '53', '42', '45'), +('4', '3', '36', '917', '1335', '35', '79', '55', '43', '46'), +('4', '3', '37', '958', '1380', '35', '81', '56', '43', '46'), +('4', '3', '38', '1000', '1425', '36', '83', '57', '44', '47'), +('4', '3', '39', '1043', '1470', '36', '85', '58', '45', '48'), +('4', '3', '40', '1087', '1515', '37', '86', '60', '46', '49'), +('4', '3', '41', '1132', '1560', '38', '88', '61', '47', '50'), +('4', '3', '42', '1178', '1605', '38', '90', '62', '47', '51'), +('4', '3', '43', '1225', '1650', '39', '92', '63', '48', '52'), +('4', '3', '44', '1273', '1695', '40', '94', '65', '49', '53'), +('4', '3', '45', '1322', '1740', '40', '96', '66', '50', '54'), +('4', '3', '46', '1372', '1785', '41', '98', '68', '51', '55'), +('4', '3', '47', '1423', '1830', '42', '100', '69', '52', '56'), +('4', '3', '48', '1475', '1875', '43', '103', '70', '53', '57'), +('4', '3', '49', '1528', '1920', '43', '105', '72', '54', '58'), +('4', '3', '50', '1582', '1965', '44', '107', '73', '55', '59'), +('4', '3', '51', '1637', '2010', '45', '109', '75', '56', '60'), +('4', '3', '52', '1693', '2055', '46', '111', '76', '57', '61'), +('4', '3', '53', '1750', '2100', '46', '113', '78', '58', '62'), +('4', '3', '54', '1808', '2145', '47', '116', '79', '59', '63'), +('4', '3', '55', '1867', '2190', '48', '118', '81', '60', '64'), +('4', '3', '56', '1927', '2235', '49', '120', '82', '61', '65'), +('4', '3', '57', '1988', '2280', '50', '123', '84', '62', '67'), +('4', '3', '58', '2050', '2325', '50', '125', '86', '63', '68'), +('4', '3', '59', '2113', '2370', '51', '128', '87', '64', '69'), +('4', '3', '60', '2177', '2415', '52', '130', '89', '65', '70'), +('4', '4', '1', '45', '0', '18', '28', '20', '20', '20'), +('4', '4', '2', '62', '0', '19', '29', '21', '20', '20'), +('4', '4', '3', '79', '0', '19', '30', '21', '20', '21'), +('4', '4', '4', '96', '0', '20', '32', '22', '21', '21'), +('4', '4', '5', '113', '0', '21', '33', '23', '21', '21'), +('4', '4', '6', '130', '0', '21', '34', '23', '21', '22'), +('4', '4', '7', '147', '0', '22', '36', '24', '21', '22'), +('4', '4', '8', '164', '0', '23', '37', '24', '21', '22'), +('4', '4', '9', '181', '0', '24', '38', '25', '21', '23'), +('4', '4', '10', '198', '0', '24', '40', '26', '22', '23'), +('4', '4', '11', '215', '0', '25', '41', '27', '22', '24'), +('4', '4', '12', '232', '0', '26', '42', '27', '22', '24'), +('4', '4', '13', '249', '0', '27', '44', '28', '22', '24'), +('4', '4', '14', '266', '0', '27', '45', '29', '22', '25'), +('4', '4', '15', '283', '0', '28', '47', '29', '23', '25'), +('4', '4', '16', '301', '0', '29', '48', '30', '23', '26'), +('4', '4', '17', '320', '0', '30', '49', '31', '23', '26'), +('4', '4', '18', '340', '0', '31', '51', '32', '23', '26'), +('4', '4', '19', '361', '0', '32', '53', '32', '23', '27'), +('4', '4', '20', '383', '0', '32', '54', '33', '24', '27'), +('4', '4', '21', '406', '0', '33', '56', '34', '24', '28'), +('4', '4', '22', '430', '0', '34', '57', '35', '24', '28'), +('4', '4', '23', '455', '0', '35', '59', '36', '24', '29'), +('4', '4', '24', '481', '0', '36', '60', '36', '25', '29'), +('4', '4', '25', '508', '0', '37', '62', '37', '25', '30'), +('4', '4', '26', '536', '0', '38', '64', '38', '25', '30'), +('4', '4', '27', '565', '0', '39', '65', '39', '25', '30'), +('4', '4', '28', '595', '0', '40', '67', '40', '25', '31'), +('4', '4', '29', '626', '0', '40', '69', '41', '26', '31'), +('4', '4', '30', '658', '0', '41', '71', '41', '26', '32'), +('4', '4', '31', '691', '0', '42', '72', '42', '26', '32'), +('4', '4', '32', '725', '0', '43', '74', '43', '26', '33'), +('4', '4', '33', '760', '0', '44', '76', '44', '27', '33'), +('4', '4', '34', '796', '0', '45', '78', '45', '27', '34'), +('4', '4', '35', '833', '0', '46', '80', '46', '27', '34'), +('4', '4', '36', '871', '0', '48', '82', '47', '28', '35'), +('4', '4', '37', '910', '0', '49', '83', '48', '28', '36'), +('4', '4', '38', '950', '0', '50', '85', '49', '28', '36'), +('4', '4', '39', '991', '0', '51', '87', '50', '28', '37'), +('4', '4', '40', '1033', '0', '52', '89', '51', '29', '37'), +('4', '4', '41', '1076', '0', '53', '91', '52', '29', '38'), +('4', '4', '42', '1120', '0', '54', '93', '53', '29', '38'), +('4', '4', '43', '1165', '0', '55', '95', '54', '29', '39'), +('4', '4', '44', '1211', '0', '56', '98', '55', '30', '39'), +('4', '4', '45', '1258', '0', '58', '100', '56', '30', '40'), +('4', '4', '46', '1306', '0', '59', '102', '57', '30', '41'), +('4', '4', '47', '1355', '0', '60', '104', '58', '31', '41'), +('4', '4', '48', '1405', '0', '61', '106', '59', '31', '42'), +('4', '4', '49', '1456', '0', '62', '108', '61', '31', '43'), +('4', '4', '50', '1508', '0', '64', '111', '62', '32', '43'), +('4', '4', '51', '1561', '0', '65', '113', '63', '32', '44'), +('4', '4', '52', '1615', '0', '66', '115', '64', '32', '44'), +('4', '4', '53', '1670', '0', '67', '118', '65', '33', '45'), +('4', '4', '54', '1726', '0', '69', '120', '66', '33', '46'), +('4', '4', '55', '1783', '0', '70', '122', '68', '33', '46'), +('4', '4', '56', '1841', '0', '71', '125', '69', '34', '47'), +('4', '4', '57', '1900', '0', '73', '127', '70', '34', '48'), +('4', '4', '58', '1960', '0', '74', '130', '71', '34', '49'), +('4', '4', '59', '2021', '0', '76', '132', '73', '35', '49'), +('4', '4', '60', '2083', '0', '77', '135', '74', '35', '50'), +('4', '5', '1', '51', '128', '17', '25', '19', '22', '23'), +('4', '5', '2', '66', '184', '17', '25', '19', '23', '24'), +('4', '5', '3', '72', '209', '17', '25', '20', '24', '25'), +('4', '5', '4', '87', '235', '18', '26', '20', '25', '27'), +('4', '5', '5', '102', '262', '18', '26', '20', '27', '28'), +('4', '5', '6', '117', '290', '18', '26', '21', '28', '29'), +('4', '5', '7', '132', '319', '18', '26', '21', '29', '30'), +('4', '5', '8', '147', '349', '18', '27', '21', '30', '31'), +('4', '5', '9', '162', '380', '18', '27', '22', '31', '33'), +('4', '5', '10', '177', '427', '19', '27', '22', '33', '34'), +('4', '5', '11', '192', '445', '19', '27', '23', '34', '35'), +('4', '5', '12', '207', '479', '19', '28', '23', '35', '37'), +('4', '5', '13', '222', '514', '19', '28', '23', '36', '38'), +('4', '5', '14', '237', '550', '19', '28', '24', '38', '39'), +('4', '5', '15', '252', '587', '20', '28', '24', '39', '41'), +('4', '5', '16', '267', '625', '20', '29', '25', '40', '42'), +('4', '5', '17', '282', '679', '20', '29', '25', '42', '43'), +('4', '5', '18', '297', '704', '20', '29', '25', '43', '45'), +('4', '5', '19', '312', '745', '20', '30', '26', '44', '46'), +('4', '5', '20', '327', '787', '21', '30', '26', '46', '48'), +('4', '5', '21', '342', '830', '21', '30', '27', '47', '49'), +('4', '5', '22', '358', '889', '21', '30', '27', '49', '51'), +('4', '5', '23', '375', '919', '21', '31', '28', '50', '52'), +('4', '5', '24', '393', '980', '22', '31', '28', '52', '54'), +('4', '5', '25', '412', '1012', '22', '31', '29', '53', '55'), +('4', '5', '26', '432', '1075', '22', '32', '29', '55', '57'), +('4', '5', '27', '453', '1109', '22', '32', '29', '56', '59'), +('4', '5', '28', '475', '1174', '22', '32', '30', '58', '60'), +('4', '5', '29', '498', '1210', '23', '33', '30', '59', '62'), +('4', '5', '30', '522', '1262', '23', '33', '31', '61', '64'), +('4', '5', '31', '547', '1330', '23', '33', '31', '63', '65'), +('4', '5', '32', '573', '1369', '23', '34', '32', '64', '67'), +('4', '5', '33', '600', '1438', '24', '34', '32', '66', '69'), +('4', '5', '34', '628', '1492', '24', '34', '33', '68', '70'), +('4', '5', '35', '657', '1531', '24', '35', '33', '69', '72'), +('4', '5', '36', '687', '1585', '25', '35', '34', '71', '74'), +('4', '5', '37', '718', '1654', '25', '35', '35', '73', '76'), +('4', '5', '38', '750', '1708', '25', '36', '35', '75', '78'), +('4', '5', '39', '783', '1747', '25', '36', '36', '76', '80'), +('4', '5', '40', '817', '1801', '26', '36', '36', '78', '81'), +('4', '5', '41', '852', '1870', '26', '37', '37', '80', '83'), +('4', '5', '42', '888', '1924', '26', '37', '37', '82', '85'), +('4', '5', '43', '925', '1978', '26', '38', '38', '84', '87'), +('4', '5', '44', '963', '2032', '27', '38', '38', '86', '89'), +('4', '5', '45', '1002', '2086', '27', '38', '39', '88', '91'), +('4', '5', '46', '1042', '2140', '27', '39', '40', '90', '93'), +('4', '5', '47', '1083', '2194', '28', '39', '40', '92', '95'), +('4', '5', '48', '1125', '2248', '28', '40', '41', '94', '98'), +('4', '5', '49', '1168', '2302', '28', '40', '42', '96', '100'), +('4', '5', '50', '1212', '2356', '29', '40', '42', '98', '102'), +('4', '5', '51', '1257', '2410', '29', '41', '43', '100', '104'), +('4', '5', '52', '1303', '2464', '29', '41', '43', '102', '106'), +('4', '5', '53', '1350', '2518', '30', '42', '44', '104', '108'), +('4', '5', '54', '1398', '2572', '30', '42', '45', '106', '111'), +('4', '5', '55', '1447', '2626', '30', '43', '45', '109', '113'), +('4', '5', '56', '1497', '2680', '31', '43', '46', '111', '115'), +('4', '5', '57', '1548', '2734', '31', '44', '47', '113', '118'), +('4', '5', '58', '1600', '2788', '31', '44', '48', '115', '120'), +('4', '5', '59', '1653', '2842', '32', '45', '48', '118', '123'), +('4', '5', '60', '1707', '2896', '32', '45', '49', '120', '125'), +('4', '11', '1', '53', '67', '18', '25', '19', '22', '22'), +('4', '11', '2', '61', '122', '19', '25', '20', '23', '23'), +('4', '11', '3', '78', '145', '19', '26', '20', '24', '24'), +('4', '11', '4', '95', '169', '20', '26', '21', '25', '25'), +('4', '11', '5', '112', '194', '20', '27', '21', '26', '26'), +('4', '11', '6', '129', '220', '21', '27', '22', '27', '27'), +('4', '11', '7', '146', '247', '21', '28', '23', '28', '28'), +('4', '11', '8', '163', '260', '22', '28', '23', '28', '29'), +('4', '11', '9', '180', '289', '22', '29', '24', '29', '30'), +('4', '11', '10', '197', '319', '23', '29', '24', '30', '31'), +('4', '11', '11', '214', '350', '23', '30', '25', '31', '33'), +('4', '11', '12', '231', '382', '24', '30', '26', '32', '34'), +('4', '11', '13', '248', '415', '24', '31', '26', '33', '35'), +('4', '11', '14', '265', '449', '25', '31', '27', '34', '36'), +('4', '11', '15', '282', '499', '26', '32', '28', '36', '37'), +('4', '11', '16', '299', '535', '26', '32', '28', '37', '38'), +('4', '11', '17', '316', '572', '27', '33', '29', '38', '40'), +('4', '11', '18', '334', '610', '27', '34', '30', '39', '41'), +('4', '11', '19', '353', '649', '28', '34', '30', '40', '42'), +('4', '11', '20', '373', '689', '29', '35', '31', '41', '43'), +('4', '11', '21', '394', '730', '29', '35', '32', '42', '45'), +('4', '11', '22', '416', '757', '30', '36', '33', '43', '46'), +('4', '11', '23', '439', '800', '31', '37', '33', '44', '47'), +('4', '11', '24', '463', '859', '31', '37', '34', '46', '49'), +('4', '11', '25', '488', '904', '32', '38', '35', '47', '50'), +('4', '11', '26', '514', '949', '33', '38', '36', '48', '51'), +('4', '11', '27', '541', '979', '33', '39', '36', '49', '53'), +('4', '11', '28', '569', '1024', '34', '40', '37', '50', '54'), +('4', '11', '29', '598', '1084', '35', '40', '38', '52', '56'), +('4', '11', '30', '628', '1129', '35', '41', '39', '53', '57'), +('4', '11', '31', '659', '1159', '36', '42', '40', '54', '58'), +('4', '11', '32', '691', '1219', '37', '42', '41', '56', '60'), +('4', '11', '33', '724', '1264', '38', '43', '41', '57', '61'), +('4', '11', '34', '758', '1294', '38', '44', '42', '58', '63'), +('4', '11', '35', '793', '1354', '39', '44', '43', '60', '64'), +('4', '11', '36', '829', '1384', '40', '45', '44', '61', '66'), +('4', '11', '37', '866', '1429', '41', '46', '45', '62', '68'), +('4', '11', '38', '904', '1489', '42', '46', '46', '64', '69'), +('4', '11', '39', '943', '1519', '42', '47', '47', '65', '71'), +('4', '11', '40', '983', '1579', '43', '48', '48', '67', '72'), +('4', '11', '41', '1024', '1609', '44', '49', '49', '68', '74'), +('4', '11', '42', '1066', '1669', '45', '49', '50', '70', '76'), +('4', '11', '43', '1109', '1699', '46', '50', '51', '71', '77'), +('4', '11', '44', '1153', '1759', '47', '51', '51', '73', '79'), +('4', '11', '45', '1198', '1789', '47', '52', '52', '74', '81'), +('4', '11', '46', '1244', '1849', '48', '53', '53', '76', '83'), +('4', '11', '47', '1291', '1879', '49', '53', '55', '77', '84'), +('4', '11', '48', '1339', '1924', '50', '54', '56', '79', '86'), +('4', '11', '49', '1388', '1984', '51', '55', '57', '81', '88'), +('4', '11', '50', '1438', '2014', '52', '56', '58', '82', '90'), +('4', '11', '51', '1489', '2059', '53', '57', '59', '84', '92'), +('4', '11', '52', '1541', '2119', '54', '58', '60', '86', '94'), +('4', '11', '53', '1594', '2149', '55', '59', '61', '87', '96'), +('4', '11', '54', '1648', '2194', '56', '59', '62', '89', '98'), +('4', '11', '55', '1703', '2239', '57', '60', '63', '91', '100'), +('4', '11', '56', '1759', '2284', '58', '61', '64', '93', '102'), +('4', '11', '57', '1816', '2329', '59', '62', '65', '94', '104'), +('4', '11', '58', '1874', '2374', '60', '63', '67', '96', '106'), +('4', '11', '59', '1933', '2419', '61', '64', '68', '98', '108'), +('4', '11', '60', '1993', '2464', '62', '65', '69', '100', '110'), +('5', '1', '1', '70', '0', '22', '18', '23', '18', '25'), +('5', '1', '2', '89', '0', '23', '19', '24', '18', '25'), +('5', '1', '3', '108', '0', '24', '19', '25', '18', '26'), +('5', '1', '4', '127', '0', '25', '20', '26', '18', '26'), +('5', '1', '5', '146', '0', '27', '21', '27', '18', '26'), +('5', '1', '6', '165', '0', '28', '22', '28', '19', '26'), +('5', '1', '7', '184', '0', '29', '22', '29', '19', '27'), +('5', '1', '8', '203', '0', '30', '23', '30', '19', '27'), +('5', '1', '9', '222', '0', '31', '24', '31', '19', '27'), +('5', '1', '10', '241', '0', '32', '24', '32', '19', '28'), +('5', '1', '11', '260', '0', '34', '25', '34', '19', '28'), +('5', '1', '12', '279', '0', '35', '26', '35', '19', '28'), +('5', '1', '13', '298', '0', '36', '27', '36', '19', '29'), +('5', '1', '14', '318', '0', '38', '28', '37', '20', '29'), +('5', '1', '15', '339', '0', '39', '28', '38', '20', '29'), +('5', '1', '16', '361', '0', '40', '29', '39', '20', '30'), +('5', '1', '17', '384', '0', '41', '30', '41', '20', '30'), +('5', '1', '18', '408', '0', '43', '31', '42', '20', '30'), +('5', '1', '19', '433', '0', '44', '32', '43', '20', '31'), +('5', '1', '20', '459', '0', '46', '33', '44', '20', '31'), +('5', '1', '21', '486', '0', '47', '33', '46', '21', '31'), +('5', '1', '22', '514', '0', '48', '34', '47', '21', '32'), +('5', '1', '23', '543', '0', '50', '35', '48', '21', '32'), +('5', '1', '24', '573', '0', '51', '36', '50', '21', '33'), +('5', '1', '25', '604', '0', '53', '37', '51', '21', '33'), +('5', '1', '26', '636', '0', '54', '38', '52', '21', '33'), +('5', '1', '27', '669', '0', '56', '39', '54', '21', '34'), +('5', '1', '28', '703', '0', '57', '40', '55', '22', '34'), +('5', '1', '29', '738', '0', '59', '41', '57', '22', '35'), +('5', '1', '30', '774', '0', '61', '42', '58', '22', '35'), +('5', '1', '31', '811', '0', '62', '43', '59', '22', '35'), +('5', '1', '32', '849', '0', '64', '44', '61', '22', '36'), +('5', '1', '33', '888', '0', '65', '45', '62', '22', '36'), +('5', '1', '34', '928', '0', '67', '46', '64', '23', '37'), +('5', '1', '35', '969', '0', '69', '47', '65', '23', '37'), +('5', '1', '36', '1011', '0', '71', '48', '67', '23', '38'), +('5', '1', '37', '1055', '0', '72', '49', '69', '23', '38'), +('5', '1', '38', '1101', '0', '74', '50', '70', '23', '38'), +('5', '1', '39', '1149', '0', '76', '51', '72', '24', '39'), +('5', '1', '40', '1199', '0', '78', '52', '73', '24', '39'), +('5', '1', '41', '1251', '0', '79', '54', '75', '24', '40'), +('5', '1', '42', '1305', '0', '81', '55', '77', '24', '40'), +('5', '1', '43', '1361', '0', '83', '56', '78', '24', '41'), +('5', '1', '44', '1419', '0', '85', '57', '80', '24', '41'), +('5', '1', '45', '1479', '0', '87', '58', '82', '25', '42'), +('5', '1', '46', '1541', '0', '89', '59', '84', '25', '42'), +('5', '1', '47', '1605', '0', '91', '61', '85', '25', '43'), +('5', '1', '48', '1671', '0', '93', '62', '87', '25', '43'), +('5', '1', '49', '1739', '0', '95', '63', '89', '26', '44'), +('5', '1', '50', '1809', '0', '97', '64', '91', '26', '44'), +('5', '1', '51', '1881', '0', '99', '66', '93', '26', '45'), +('5', '1', '52', '1955', '0', '101', '67', '95', '26', '45'), +('5', '1', '53', '2031', '0', '103', '68', '97', '26', '46'), +('5', '1', '54', '2109', '0', '105', '70', '99', '27', '47'), +('5', '1', '55', '2189', '0', '108', '71', '101', '27', '47'), +('5', '1', '56', '2271', '0', '110', '72', '103', '27', '48'), +('5', '1', '57', '2355', '0', '112', '74', '105', '27', '48'), +('5', '1', '58', '2441', '0', '114', '75', '107', '28', '49'), +('5', '1', '59', '2529', '0', '117', '77', '109', '28', '49'), +('5', '1', '60', '2619', '0', '119', '78', '111', '28', '50'), +('5', '4', '1', '65', '0', '20', '21', '22', '18', '25'), +('5', '4', '2', '82', '0', '21', '22', '23', '18', '25'), +('5', '4', '3', '99', '0', '21', '23', '23', '18', '26'), +('5', '4', '4', '116', '0', '22', '25', '24', '19', '26'), +('5', '4', '5', '133', '0', '23', '26', '25', '19', '26'), +('5', '4', '6', '150', '0', '23', '27', '25', '19', '27'), +('5', '4', '7', '167', '0', '24', '29', '26', '19', '27'), +('5', '4', '8', '184', '0', '25', '30', '26', '19', '27'), +('5', '4', '9', '201', '0', '26', '31', '27', '19', '28'), +('5', '4', '10', '218', '0', '26', '33', '28', '20', '28'), +('5', '4', '11', '235', '0', '27', '34', '29', '20', '29'), +('5', '4', '12', '252', '0', '28', '35', '29', '20', '29'), +('5', '4', '13', '269', '0', '29', '37', '30', '20', '29'), +('5', '4', '14', '286', '0', '29', '38', '31', '20', '30'), +('5', '4', '15', '303', '0', '30', '40', '31', '21', '30'), +('5', '4', '16', '321', '0', '31', '41', '32', '21', '31'), +('5', '4', '17', '340', '0', '32', '42', '33', '21', '31'), +('5', '4', '18', '360', '0', '33', '44', '34', '21', '31'), +('5', '4', '19', '381', '0', '34', '46', '34', '21', '32'), +('5', '4', '20', '403', '0', '34', '47', '35', '22', '32'), +('5', '4', '21', '426', '0', '35', '49', '36', '22', '33'), +('5', '4', '22', '450', '0', '36', '50', '37', '22', '33'), +('5', '4', '23', '475', '0', '37', '52', '38', '22', '34'), +('5', '4', '24', '501', '0', '38', '53', '38', '23', '34'), +('5', '4', '25', '528', '0', '39', '55', '39', '23', '35'), +('5', '4', '26', '556', '0', '40', '57', '40', '23', '35'), +('5', '4', '27', '585', '0', '41', '58', '41', '23', '35'), +('5', '4', '28', '615', '0', '42', '60', '42', '23', '36'), +('5', '4', '29', '646', '0', '42', '62', '43', '24', '36'), +('5', '4', '30', '678', '0', '43', '64', '43', '24', '37'), +('5', '4', '31', '711', '0', '44', '65', '44', '24', '37'), +('5', '4', '32', '745', '0', '45', '67', '45', '24', '38'), +('5', '4', '33', '780', '0', '46', '69', '46', '25', '38'), +('5', '4', '34', '816', '0', '47', '71', '47', '25', '39'), +('5', '4', '35', '853', '0', '48', '73', '48', '25', '39'), +('5', '4', '36', '891', '0', '50', '75', '49', '26', '40'), +('5', '4', '37', '930', '0', '51', '76', '50', '26', '41'), +('5', '4', '38', '970', '0', '52', '78', '51', '26', '41'), +('5', '4', '39', '1011', '0', '53', '80', '52', '26', '42'), +('5', '4', '40', '1053', '0', '54', '82', '53', '27', '42'), +('5', '4', '41', '1096', '0', '55', '84', '54', '27', '43'), +('5', '4', '42', '1140', '0', '56', '86', '55', '27', '43'), +('5', '4', '43', '1185', '0', '57', '88', '56', '27', '44'), +('5', '4', '44', '1231', '0', '58', '91', '57', '28', '44'), +('5', '4', '45', '1278', '0', '60', '93', '58', '28', '45'), +('5', '4', '46', '1326', '0', '61', '95', '59', '28', '46'), +('5', '4', '47', '1375', '0', '62', '97', '60', '29', '46'), +('5', '4', '48', '1425', '0', '63', '99', '61', '29', '47'), +('5', '4', '49', '1476', '0', '64', '101', '63', '29', '48'), +('5', '4', '50', '1528', '0', '66', '104', '64', '30', '48'), +('5', '4', '51', '1581', '0', '67', '106', '65', '30', '49'), +('5', '4', '52', '1635', '0', '68', '108', '66', '30', '49'), +('5', '4', '53', '1690', '0', '69', '111', '67', '31', '50'), +('5', '4', '54', '1746', '0', '71', '113', '68', '31', '51'), +('5', '4', '55', '1803', '0', '72', '115', '70', '31', '51'), +('5', '4', '56', '1861', '0', '73', '118', '71', '32', '52'), +('5', '4', '57', '1920', '0', '75', '120', '72', '32', '53'), +('5', '4', '58', '1980', '0', '76', '123', '73', '32', '54'), +('5', '4', '59', '2041', '0', '78', '125', '75', '33', '54'), +('5', '4', '60', '2103', '0', '79', '128', '76', '33', '55'), +('5', '5', '1', '71', '128', '19', '18', '21', '20', '28'), +('5', '5', '2', '77', '154', '19', '18', '21', '21', '29'), +('5', '5', '3', '92', '179', '19', '18', '22', '22', '30'), +('5', '5', '4', '107', '205', '20', '19', '22', '23', '32'), +('5', '5', '5', '122', '232', '20', '19', '22', '25', '33'), +('5', '5', '6', '137', '260', '20', '19', '23', '26', '34'), +('5', '5', '7', '152', '289', '20', '19', '23', '27', '35'), +('5', '5', '8', '167', '319', '20', '20', '23', '28', '36'), +('5', '5', '9', '182', '350', '20', '20', '24', '29', '38'), +('5', '5', '10', '197', '397', '21', '20', '24', '31', '39'), +('5', '5', '11', '212', '415', '21', '20', '25', '32', '40'), +('5', '5', '12', '227', '449', '21', '21', '25', '33', '42'), +('5', '5', '13', '242', '484', '21', '21', '25', '34', '43'), +('5', '5', '14', '257', '520', '21', '21', '26', '36', '44'), +('5', '5', '15', '272', '557', '22', '21', '26', '37', '46'), +('5', '5', '16', '287', '595', '22', '22', '27', '38', '47'), +('5', '5', '17', '302', '649', '22', '22', '27', '40', '48'), +('5', '5', '18', '317', '674', '22', '22', '27', '41', '50'), +('5', '5', '19', '332', '715', '22', '23', '28', '42', '51'), +('5', '5', '20', '347', '757', '23', '23', '28', '44', '53'), +('5', '5', '21', '362', '800', '23', '23', '29', '45', '54'), +('5', '5', '22', '378', '859', '23', '23', '29', '47', '56'), +('5', '5', '23', '395', '889', '23', '24', '30', '48', '57'), +('5', '5', '24', '413', '950', '24', '24', '30', '50', '59'), +('5', '5', '25', '432', '982', '24', '24', '31', '51', '60'), +('5', '5', '26', '452', '1045', '24', '25', '31', '53', '62'), +('5', '5', '27', '473', '1079', '24', '25', '31', '54', '64'), +('5', '5', '28', '495', '1144', '24', '25', '32', '56', '65'), +('5', '5', '29', '518', '1180', '25', '26', '32', '57', '67'), +('5', '5', '30', '542', '1232', '25', '26', '33', '59', '69'), +('5', '5', '31', '567', '1300', '25', '26', '33', '61', '70'), +('5', '5', '32', '593', '1339', '25', '27', '34', '62', '72'), +('5', '5', '33', '620', '1408', '26', '27', '34', '64', '74'), +('5', '5', '34', '648', '1462', '26', '27', '35', '66', '75'), +('5', '5', '35', '677', '1501', '26', '28', '35', '67', '77'), +('5', '5', '36', '707', '1555', '27', '28', '36', '69', '79'), +('5', '5', '37', '738', '1624', '27', '28', '37', '71', '81'), +('5', '5', '38', '770', '1678', '27', '29', '37', '73', '83'), +('5', '5', '39', '803', '1717', '27', '29', '38', '74', '85'), +('5', '5', '40', '837', '1771', '28', '29', '38', '76', '86'), +('5', '5', '41', '872', '1840', '28', '30', '39', '78', '88'), +('5', '5', '42', '908', '1894', '28', '30', '39', '80', '90'), +('5', '5', '43', '945', '1948', '28', '31', '40', '82', '92'), +('5', '5', '44', '983', '2002', '29', '31', '40', '84', '94'), +('5', '5', '45', '1022', '2056', '29', '31', '41', '86', '96'), +('5', '5', '46', '1062', '2110', '29', '32', '42', '88', '98'), +('5', '5', '47', '1103', '2164', '30', '32', '42', '90', '100'), +('5', '5', '48', '1145', '2218', '30', '33', '43', '92', '103'), +('5', '5', '49', '1188', '2272', '30', '33', '44', '94', '105'), +('5', '5', '50', '1232', '2326', '31', '33', '44', '96', '107'), +('5', '5', '51', '1277', '2380', '31', '34', '45', '98', '109'), +('5', '5', '52', '1323', '2434', '31', '34', '45', '100', '111'), +('5', '5', '53', '1370', '2488', '32', '35', '46', '102', '113'), +('5', '5', '54', '1418', '2542', '32', '35', '47', '104', '116'), +('5', '5', '55', '1467', '2596', '32', '36', '47', '107', '118'), +('5', '5', '56', '1517', '2650', '33', '36', '48', '109', '120'), +('5', '5', '57', '1568', '2704', '33', '37', '49', '111', '123'), +('5', '5', '58', '1620', '2758', '33', '37', '50', '113', '125'), +('5', '5', '59', '1673', '2812', '34', '38', '50', '116', '128'), +('5', '5', '60', '1727', '2866', '34', '38', '51', '118', '130'), +('5', '8', '1', '62', '135', '19', '18', '21', '27', '21'), +('5', '8', '2', '77', '160', '19', '18', '21', '22', '28'), +('5', '8', '3', '92', '186', '19', '18', '22', '23', '29'), +('5', '8', '4', '107', '213', '19', '19', '22', '25', '30'), +('5', '8', '5', '122', '241', '19', '19', '22', '26', '32'), +('5', '8', '6', '137', '270', '20', '19', '22', '27', '33'), +('5', '8', '7', '152', '300', '20', '19', '23', '28', '34'), +('5', '8', '8', '167', '316', '20', '19', '23', '29', '35'), +('5', '8', '9', '182', '363', '20', '19', '23', '31', '36'), +('5', '8', '10', '197', '396', '20', '20', '24', '32', '38'), +('5', '8', '11', '212', '430', '20', '20', '24', '33', '39'), +('5', '8', '12', '227', '465', '20', '20', '24', '35', '40'), +('5', '8', '13', '242', '501', '20', '20', '25', '36', '41'), +('5', '8', '14', '257', '538', '21', '20', '25', '37', '43'), +('5', '8', '15', '272', '576', '21', '21', '25', '39', '44'), +('5', '8', '16', '287', '615', '21', '21', '26', '40', '45'), +('5', '8', '17', '302', '640', '21', '21', '26', '41', '47'), +('5', '8', '18', '317', '696', '21', '21', '26', '43', '48'), +('5', '8', '19', '332', '723', '21', '21', '27', '44', '49'), +('5', '8', '20', '347', '781', '21', '22', '27', '46', '51'), +('5', '8', '21', '362', '810', '22', '22', '27', '47', '52'), +('5', '8', '22', '377', '870', '22', '22', '28', '49', '54'), +('5', '8', '23', '392', '901', '22', '22', '28', '50', '55'), +('5', '8', '24', '408', '963', '22', '23', '29', '52', '57'), +('5', '8', '25', '425', '996', '22', '23', '29', '53', '58'), +('5', '8', '26', '443', '1060', '22', '23', '29', '55', '60'), +('5', '8', '27', '462', '1110', '22', '23', '30', '57', '61'), +('5', '8', '28', '482', '1146', '23', '23', '30', '58', '63'), +('5', '8', '29', '503', '1212', '23', '24', '31', '60', '64'), +('5', '8', '30', '525', '1263', '23', '24', '31', '62', '66'), +('5', '8', '31', '548', '1299', '23', '24', '31', '63', '68'), +('5', '8', '32', '572', '1365', '23', '24', '32', '65', '69'), +('5', '8', '33', '597', '1416', '23', '25', '32', '67', '71'), +('5', '8', '34', '623', '1452', '24', '25', '33', '68', '73'), +('5', '8', '35', '650', '1503', '24', '25', '33', '70', '74'), +('5', '8', '36', '678', '1554', '24', '26', '34', '72', '76'), +('5', '8', '37', '707', '1620', '24', '26', '34', '74', '78'), +('5', '8', '38', '737', '1671', '24', '26', '34', '76', '80'), +('5', '8', '39', '768', '1722', '25', '26', '35', '78', '81'), +('5', '8', '40', '800', '1758', '25', '27', '35', '79', '83'), +('5', '8', '41', '833', '1809', '25', '27', '36', '81', '85'), +('5', '8', '42', '867', '1860', '25', '27', '36', '83', '87'), +('5', '8', '43', '902', '1911', '25', '27', '37', '85', '89'), +('5', '8', '44', '938', '1962', '25', '28', '37', '87', '91'), +('5', '8', '45', '975', '2013', '26', '28', '38', '89', '93'), +('5', '8', '46', '1013', '2064', '26', '28', '38', '91', '95'), +('5', '8', '47', '1052', '2115', '26', '29', '39', '93', '97'), +('5', '8', '48', '1092', '2181', '26', '29', '39', '96', '99'), +('5', '8', '49', '1133', '2232', '27', '29', '40', '98', '101'), +('5', '8', '50', '1175', '2268', '27', '30', '40', '100', '103'), +('5', '8', '51', '1218', '2319', '27', '30', '41', '102', '105'), +('5', '8', '52', '1262', '2370', '27', '30', '41', '104', '107'), +('5', '8', '53', '1307', '2421', '27', '31', '42', '106', '109'), +('5', '8', '54', '1353', '2472', '28', '31', '43', '109', '111'), +('5', '8', '55', '1400', '2523', '28', '31', '43', '111', '114'), +('5', '8', '56', '1448', '2574', '28', '32', '44', '113', '116'), +('5', '8', '57', '1497', '2625', '28', '32', '44', '116', '118'), +('5', '8', '58', '1547', '2676', '29', '32', '45', '118', '120'), +('5', '8', '59', '1598', '2727', '29', '33', '45', '121', '123'), +('5', '8', '60', '1650', '2778', '29', '33', '46', '123', '125'), +('5', '9', '1', '63', '109', '19', '18', '22', '20', '27'), +('5', '9', '2', '78', '133', '19', '18', '23', '21', '28'), +('5', '9', '3', '93', '157', '20', '19', '23', '22', '29'), +('5', '9', '4', '108', '182', '20', '19', '24', '23', '30'), +('5', '9', '5', '123', '208', '20', '19', '24', '24', '31'), +('5', '9', '6', '138', '235', '20', '20', '25', '25', '32'), +('5', '9', '7', '153', '263', '21', '20', '25', '26', '34'), +('5', '9', '8', '168', '292', '21', '20', '26', '27', '35'), +('5', '9', '9', '183', '322', '21', '21', '26', '28', '36'), +('5', '9', '10', '198', '353', '22', '21', '27', '29', '37'), +('5', '9', '11', '213', '385', '22', '22', '27', '31', '38'), +('5', '9', '12', '228', '418', '22', '22', '28', '32', '39'), +('5', '9', '13', '243', '452', '23', '22', '28', '33', '41'), +('5', '9', '14', '258', '487', '23', '23', '29', '34', '42'), +('5', '9', '15', '273', '523', '23', '23', '30', '35', '43'), +('5', '9', '16', '288', '560', '24', '24', '30', '36', '44'), +('5', '9', '17', '303', '598', '24', '24', '31', '38', '46'), +('5', '9', '18', '319', '637', '24', '24', '31', '39', '47'), +('5', '9', '19', '336', '677', '25', '25', '32', '40', '48'), +('5', '9', '20', '354', '718', '25', '25', '33', '41', '50'), +('5', '9', '21', '373', '760', '25', '26', '33', '43', '51'), +('5', '9', '22', '393', '803', '26', '26', '34', '44', '52'), +('5', '9', '23', '414', '847', '26', '27', '35', '45', '54'), +('5', '9', '24', '436', '892', '27', '27', '35', '47', '55'), +('5', '9', '25', '459', '938', '27', '28', '36', '48', '57'), +('5', '9', '26', '483', '985', '27', '28', '37', '49', '58'), +('5', '9', '27', '508', '1033', '28', '28', '37', '51', '59'), +('5', '9', '28', '534', '1082', '28', '29', '38', '52', '61'), +('5', '9', '29', '561', '1132', '29', '29', '39', '54', '62'), +('5', '9', '30', '589', '1183', '29', '30', '39', '55', '64'), +('5', '9', '31', '618', '1234', '29', '30', '40', '56', '66'), +('5', '9', '32', '648', '1285', '30', '31', '41', '58', '67'), +('5', '9', '33', '679', '1336', '30', '31', '42', '59', '69'), +('5', '9', '34', '711', '1387', '31', '32', '42', '61', '70'), +('5', '9', '35', '744', '1438', '31', '32', '43', '62', '72'), +('5', '9', '36', '768', '1489', '32', '33', '43', '64', '75'), +('5', '9', '37', '813', '1540', '32', '34', '45', '66', '75'), +('5', '9', '38', '849', '1591', '32', '34', '46', '67', '77'), +('5', '9', '39', '886', '1642', '33', '35', '46', '69', '79'), +('5', '9', '40', '924', '1693', '33', '35', '47', '70', '80'), +('5', '9', '41', '963', '1744', '34', '36', '48', '72', '82'), +('5', '9', '42', '993', '1795', '34', '36', '48', '74', '85'), +('5', '9', '43', '1044', '1846', '35', '37', '50', '75', '86'), +('5', '9', '44', '1086', '1897', '35', '37', '51', '77', '87'), +('5', '9', '45', '1129', '1948', '36', '38', '51', '79', '89'), +('5', '9', '46', '1173', '1999', '36', '39', '52', '81', '90'), +('5', '9', '47', '1218', '2050', '37', '39', '53', '82', '93'), +('5', '9', '48', '1264', '2101', '37', '40', '54', '84', '95'), +('5', '9', '49', '1311', '2152', '38', '41', '55', '86', '96'), +('5', '9', '50', '1339', '2203', '38', '41', '56', '88', '99'), +('5', '9', '51', '1398', '2254', '39', '42', '57', '90', '101'), +('5', '9', '52', '1458', '2305', '39', '42', '58', '92', '103'), +('5', '9', '53', '1509', '2356', '40', '43', '59', '94', '105'), +('5', '9', '54', '1551', '2407', '41', '44', '60', '96', '107'), +('5', '9', '55', '1594', '2458', '41', '44', '60', '98', '110'), +('5', '9', '56', '1668', '2509', '42', '45', '62', '100', '111'), +('5', '9', '57', '1723', '2560', '42', '46', '63', '102', '113'), +('5', '9', '58', '1769', '2611', '43', '47', '63', '104', '116'), +('5', '9', '59', '1836', '2662', '43', '47', '65', '106', '118'), +('5', '9', '60', '1894', '2713', '44', '48', '66', '108', '120'), +('6', '1', '1', '80', '0', '28', '15', '24', '15', '22'), +('6', '1', '2', '103', '0', '29', '16', '25', '15', '22'), +('6', '1', '3', '123', '0', '30', '16', '26', '15', '23'), +('6', '1', '4', '144', '0', '31', '17', '27', '15', '23'), +('6', '1', '5', '163', '0', '33', '18', '28', '15', '23'), +('6', '1', '6', '183', '0', '34', '19', '29', '16', '23'), +('6', '1', '7', '204', '0', '35', '19', '30', '16', '24'), +('6', '1', '8', '223', '0', '36', '20', '31', '16', '24'), +('6', '1', '9', '244', '0', '37', '21', '32', '16', '24'), +('6', '1', '10', '264', '0', '38', '21', '33', '16', '25'), +('6', '1', '11', '283', '0', '40', '22', '35', '16', '25'), +('6', '1', '12', '302', '0', '41', '23', '36', '16', '25'), +('6', '1', '13', '322', '0', '42', '24', '37', '16', '26'), +('6', '1', '14', '344', '0', '44', '25', '38', '17', '26'), +('6', '1', '15', '365', '0', '45', '25', '39', '17', '26'), +('6', '1', '16', '390', '0', '46', '26', '40', '17', '27'), +('6', '1', '17', '414', '0', '47', '27', '42', '17', '27'), +('6', '1', '18', '438', '0', '49', '28', '43', '17', '27'), +('6', '1', '19', '466', '0', '50', '29', '44', '17', '28'), +('6', '1', '20', '491', '0', '52', '30', '45', '17', '28'), +('6', '1', '21', '520', '0', '53', '30', '47', '18', '28'), +('6', '1', '22', '550', '0', '54', '31', '48', '18', '29'), +('6', '1', '23', '580', '0', '56', '32', '49', '18', '29'), +('6', '1', '24', '611', '0', '57', '33', '51', '18', '30'), +('6', '1', '25', '645', '0', '59', '34', '52', '18', '30'), +('6', '1', '26', '677', '0', '60', '35', '53', '18', '30'), +('6', '1', '27', '713', '0', '62', '36', '55', '18', '31'), +('6', '1', '28', '748', '0', '63', '37', '56', '19', '31'), +('6', '1', '29', '785', '0', '65', '38', '58', '19', '32'), +('6', '1', '30', '824', '0', '67', '39', '59', '19', '32'), +('6', '1', '31', '861', '0', '68', '40', '60', '19', '32'), +('6', '1', '32', '902', '0', '70', '41', '62', '19', '33'), +('6', '1', '33', '942', '0', '71', '42', '63', '19', '33'), +('6', '1', '34', '984', '0', '73', '43', '65', '20', '34'), +('6', '1', '35', '1028', '0', '75', '44', '66', '20', '34'), +('6', '1', '36', '1071', '0', '77', '45', '68', '20', '35'), +('6', '1', '37', '1117', '0', '78', '46', '70', '20', '35'), +('6', '1', '38', '1167', '0', '80', '47', '71', '20', '35'), +('6', '1', '39', '1217', '0', '82', '48', '73', '21', '36'), +('6', '1', '40', '1268', '0', '84', '49', '74', '21', '36'), +('6', '1', '41', '1324', '0', '85', '51', '76', '21', '37'), +('6', '1', '42', '1381', '0', '87', '52', '78', '21', '37'), +('6', '1', '43', '1440', '0', '89', '53', '79', '21', '38'), +('6', '1', '44', '1500', '0', '91', '54', '81', '21', '38'), +('6', '1', '45', '1563', '0', '93', '55', '83', '22', '39'), +('6', '1', '46', '1629', '0', '95', '56', '85', '22', '39'), +('6', '1', '47', '1696', '0', '97', '58', '86', '22', '40'), +('6', '1', '48', '1764', '0', '99', '59', '88', '22', '40'), +('6', '1', '49', '1836', '0', '101', '60', '90', '23', '41'), +('6', '1', '50', '1910', '0', '103', '61', '92', '23', '41'), +('6', '1', '51', '1986', '0', '105', '63', '94', '23', '42'), +('6', '1', '52', '2062', '0', '107', '64', '96', '23', '42'), +('6', '1', '53', '2142', '0', '109', '65', '98', '23', '43'), +('6', '1', '54', '2225', '0', '111', '67', '100', '24', '44'), +('6', '1', '55', '2309', '0', '114', '68', '102', '24', '44'), +('6', '1', '56', '2395', '0', '116', '69', '104', '24', '45'), +('6', '1', '57', '2483', '0', '118', '71', '106', '24', '45'), +('6', '1', '58', '2574', '0', '120', '72', '108', '25', '46'), +('6', '1', '59', '2666', '0', '123', '74', '110', '25', '46'), +('6', '1', '60', '2760', '0', '125', '75', '112', '25', '47'), +('6', '3', '1', '76', '80', '25', '18', '23', '15', '23'), +('6', '3', '2', '97', '86', '25', '19', '24', '16', '24'), +('6', '3', '3', '115', '107', '26', '20', '25', '16', '24'), +('6', '3', '4', '133', '115', '26', '22', '25', '17', '25'), +('6', '3', '5', '151', '138', '27', '23', '26', '17', '25'), +('6', '3', '6', '168', '148', '27', '24', '27', '18', '26'), +('6', '3', '7', '186', '173', '27', '25', '28', '18', '26'), +('6', '3', '8', '204', '185', '28', '26', '29', '19', '27'), +('6', '3', '9', '223', '212', '28', '28', '30', '19', '28'), +('6', '3', '10', '239', '226', '29', '29', '30', '20', '28'), +('6', '3', '11', '257', '255', '29', '30', '31', '20', '29'), +('6', '3', '12', '275', '285', '30', '32', '32', '21', '30'), +('6', '3', '13', '294', '316', '30', '33', '33', '22', '30'), +('6', '3', '14', '312', '348', '31', '34', '34', '22', '31'), +('6', '3', '15', '333', '381', '31', '36', '35', '23', '31'), +('6', '3', '16', '354', '415', '32', '37', '36', '23', '32'), +('6', '3', '17', '375', '450', '32', '38', '37', '24', '33'), +('6', '3', '18', '399', '486', '33', '40', '38', '25', '34'), +('6', '3', '19', '424', '523', '33', '41', '39', '25', '34'), +('6', '3', '20', '448', '561', '34', '43', '40', '26', '35'), +('6', '3', '21', '475', '600', '34', '44', '41', '27', '36'), +('6', '3', '22', '501', '640', '35', '46', '42', '27', '36'), +('6', '3', '23', '530', '681', '35', '47', '43', '28', '37'), +('6', '3', '24', '559', '723', '36', '49', '44', '29', '38'), +('6', '3', '25', '590', '766', '36', '50', '45', '29', '39'), +('6', '3', '26', '622', '810', '37', '52', '46', '30', '39'), +('6', '3', '27', '653', '855', '37', '54', '47', '31', '40'), +('6', '3', '28', '687', '900', '38', '55', '48', '31', '41'), +('6', '3', '29', '722', '945', '38', '57', '49', '32', '42'), +('6', '3', '30', '758', '990', '39', '59', '50', '33', '42'), +('6', '3', '31', '795', '1035', '39', '60', '52', '34', '43'), +('6', '3', '32', '832', '1080', '40', '62', '53', '34', '44'), +('6', '3', '33', '871', '1125', '41', '64', '54', '35', '45'), +('6', '3', '34', '910', '1170', '41', '65', '55', '36', '46'), +('6', '3', '35', '952', '1215', '42', '67', '56', '37', '47'), +('6', '3', '36', '994', '1260', '43', '69', '58', '38', '48'), +('6', '3', '37', '1036', '1305', '43', '71', '59', '38', '48'), +('6', '3', '38', '1082', '1350', '44', '73', '60', '39', '49'), +('6', '3', '39', '1126', '1395', '44', '75', '61', '40', '50'), +('6', '3', '40', '1172', '1440', '45', '76', '63', '41', '51'), +('6', '3', '41', '1221', '1485', '46', '78', '64', '42', '52'), +('6', '3', '42', '1268', '1530', '46', '80', '65', '42', '53'), +('6', '3', '43', '1318', '1575', '47', '82', '66', '43', '54'), +('6', '3', '44', '1368', '1620', '48', '84', '68', '44', '55'), +('6', '3', '45', '1419', '1665', '48', '86', '69', '45', '56'), +('6', '3', '46', '1473', '1710', '49', '88', '71', '46', '57'), +('6', '3', '47', '1525', '1755', '50', '90', '72', '47', '58'), +('6', '3', '48', '1580', '1800', '51', '93', '73', '48', '59'), +('6', '3', '49', '1636', '1845', '51', '95', '75', '49', '60'), +('6', '3', '50', '1692', '1890', '52', '97', '76', '50', '61'), +('6', '3', '51', '1750', '1935', '53', '99', '78', '51', '62'), +('6', '3', '52', '1809', '1980', '54', '101', '79', '52', '63'), +('6', '3', '53', '1869', '2025', '54', '103', '81', '53', '64'), +('6', '3', '54', '1930', '2070', '55', '106', '82', '54', '65'), +('6', '3', '55', '1991', '2115', '56', '108', '84', '55', '66'), +('6', '3', '56', '2054', '2160', '57', '110', '85', '56', '67'), +('6', '3', '57', '2119', '2205', '58', '113', '87', '57', '69'), +('6', '3', '58', '2184', '2250', '58', '115', '89', '58', '70'), +('6', '3', '59', '2250', '2295', '59', '118', '90', '59', '71'), +('6', '3', '60', '2318', '2340', '60', '120', '92', '60', '72'), +('6', '7', '1', '97', '71', '26', '15', '23', '16', '24'), +('6', '7', '2', '98', '78', '27', '15', '24', '17', '25'), +('6', '7', '3', '117', '86', '27', '16', '25', '18', '26'), +('6', '7', '4', '133', '109', '28', '16', '26', '18', '27'), +('6', '7', '5', '152', '119', '29', '17', '26', '19', '28'), +('6', '7', '6', '170', '130', '30', '17', '27', '20', '29'), +('6', '7', '7', '188', '156', '31', '17', '28', '21', '30'), +('6', '7', '8', '205', '183', '31', '18', '29', '22', '30'), +('6', '7', '9', '223', '226', '32', '18', '30', '23', '31'), +('6', '7', '10', '241', '240', '33', '19', '31', '23', '32'), +('6', '7', '11', '259', '270', '34', '19', '32', '24', '33'), +('6', '7', '12', '277', '301', '35', '20', '33', '25', '34'), +('6', '7', '13', '294', '333', '35', '20', '34', '26', '35'), +('6', '7', '14', '312', '366', '36', '21', '35', '27', '36'), +('6', '7', '15', '330', '400', '37', '21', '36', '28', '38'), +('6', '7', '16', '349', '435', '38', '22', '37', '29', '39'), +('6', '7', '17', '367', '471', '39', '22', '38', '30', '40'), +('6', '7', '18', '388', '508', '40', '23', '39', '31', '41'), +('6', '7', '19', '409', '546', '41', '23', '40', '32', '42'), +('6', '7', '20', '430', '585', '42', '24', '41', '33', '43'), +('6', '7', '21', '454', '625', '43', '24', '42', '34', '44'), +('6', '7', '22', '477', '666', '43', '25', '43', '35', '45'), +('6', '7', '23', '503', '708', '44', '25', '44', '36', '46'), +('6', '7', '24', '530', '789', '45', '26', '45', '37', '48'), +('6', '7', '25', '556', '795', '46', '26', '47', '38', '49'), +('6', '7', '26', '585', '840', '47', '27', '48', '39', '50'), +('6', '7', '27', '614', '886', '48', '27', '49', '40', '51'), +('6', '7', '28', '645', '933', '49', '28', '50', '41', '52'), +('6', '7', '29', '677', '981', '50', '28', '51', '42', '54'), +('6', '7', '30', '708', '1030', '51', '29', '52', '43', '55'), +('6', '7', '31', '742', '1149', '53', '29', '54', '45', '56'), +('6', '7', '32', '777', '1201', '54', '30', '55', '46', '58'), +('6', '7', '33', '813', '1250', '55', '31', '56', '47', '59'), +('6', '7', '34', '848', '1290', '56', '31', '57', '48', '60'), +('6', '7', '35', '887', '1339', '57', '32', '59', '49', '62'), +('6', '7', '36', '926', '1339', '58', '33', '60', '51', '63'), +('6', '7', '37', '966', '1458', '59', '33', '61', '52', '64'), +('6', '7', '38', '1007', '1471', '60', '34', '63', '53', '66'), +('6', '7', '39', '1049', '1509', '61', '34', '64', '54', '67'), +('6', '7', '40', '1092', '1612', '63', '35', '65', '56', '69'), +('6', '7', '41', '1137', '1663', '64', '36', '67', '57', '70'), +('6', '7', '42', '1181', '1700', '65', '36', '68', '58', '72'), +('6', '7', '43', '1226', '1751', '66', '37', '70', '59', '73'), +('6', '7', '44', '1275', '1818', '68', '38', '71', '61', '75'), +('6', '7', '45', '1323', '1854', '69', '38', '73', '62', '76'), +('6', '7', '46', '1373', '1921', '70', '39', '74', '64', '78'), +('6', '7', '47', '1423', '1972', '71', '40', '76', '65', '79'), +('6', '7', '48', '1474', '2008', '73', '41', '77', '66', '81'), +('6', '7', '49', '1527', '2075', '74', '41', '79', '68', '83'), +('6', '7', '50', '1579', '2111', '75', '42', '80', '69', '84'), +('6', '7', '51', '1634', '2178', '77', '43', '82', '71', '86'), +('6', '7', '52', '1691', '2230', '78', '44', '83', '72', '88'), +('6', '7', '53', '1747', '2281', '80', '44', '85', '74', '89'), +('6', '7', '54', '1805', '2304', '81', '45', '87', '75', '91'), +('6', '7', '55', '1864', '2333', '82', '46', '88', '77', '93'), +('6', '7', '56', '1923', '2384', '84', '47', '90', '78', '95'), +('6', '7', '57', '1983', '2487', '85', '48', '92', '80', '96'), +('6', '7', '58', '2045', '2538', '87', '48', '93', '82', '98'), +('6', '7', '59', '2109', '2565', '88', '49', '95', '83', '100'), +('6', '7', '60', '2174', '2590', '90', '50', '97', '85', '102'), +('6', '11', '1', '97', '67', '26', '15', '22', '17', '24'), +('6', '11', '2', '97', '75', '27', '15', '23', '18', '25'), +('6', '11', '3', '113', '84', '27', '16', '23', '19', '26'), +('6', '11', '4', '132', '94', '28', '16', '24', '20', '27'), +('6', '11', '5', '150', '119', '28', '17', '24', '21', '28'), +('6', '11', '6', '168', '145', '29', '17', '25', '22', '29'), +('6', '11', '7', '185', '172', '29', '18', '26', '23', '30'), +('6', '11', '8', '203', '185', '30', '18', '26', '23', '31'), +('6', '11', '9', '221', '214', '30', '19', '27', '24', '32'), +('6', '11', '10', '239', '244', '31', '19', '27', '25', '33'), +('6', '11', '11', '257', '275', '31', '20', '28', '26', '35'), +('6', '11', '12', '274', '307', '32', '20', '29', '27', '36'), +('6', '11', '13', '292', '340', '32', '21', '29', '28', '37'), +('6', '11', '14', '310', '374', '33', '21', '30', '29', '38'), +('6', '11', '15', '329', '424', '34', '22', '31', '31', '39'), +('6', '11', '16', '347', '460', '34', '22', '31', '32', '40'), +('6', '11', '17', '365', '497', '35', '23', '32', '33', '42'), +('6', '11', '18', '383', '535', '35', '24', '33', '34', '43'), +('6', '11', '19', '402', '574', '36', '24', '33', '35', '44'), +('6', '11', '20', '425', '614', '37', '25', '34', '36', '45'), +('6', '11', '21', '447', '655', '37', '25', '35', '37', '47'), +('6', '11', '22', '470', '682', '38', '26', '36', '38', '48'), +('6', '11', '23', '494', '725', '39', '27', '36', '39', '49'), +('6', '11', '24', '518', '784', '39', '27', '37', '41', '51'), +('6', '11', '25', '544', '829', '40', '28', '38', '42', '52'), +('6', '11', '26', '573', '874', '41', '28', '39', '43', '53'), +('6', '11', '27', '601', '904', '41', '29', '39', '44', '55'), +('6', '11', '28', '630', '949', '42', '30', '40', '45', '56'), +('6', '11', '29', '659', '1009', '43', '30', '41', '47', '58'), +('6', '11', '30', '691', '1054', '43', '31', '42', '48', '59'), +('6', '11', '31', '723', '1084', '44', '32', '43', '49', '60'), +('6', '11', '32', '757', '1144', '45', '32', '44', '51', '62'), +('6', '11', '33', '793', '1189', '46', '33', '44', '52', '63'), +('6', '11', '34', '827', '1219', '46', '34', '45', '53', '65'), +('6', '11', '35', '864', '1279', '47', '34', '46', '55', '66'), +('6', '11', '36', '903', '1309', '48', '35', '47', '56', '68'), +('6', '11', '37', '941', '1354', '49', '36', '48', '57', '70'), +('6', '11', '38', '982', '1414', '50', '36', '49', '59', '71'), +('6', '11', '39', '1022', '1444', '50', '37', '50', '60', '73'), +('6', '11', '40', '1064', '1504', '51', '38', '51', '62', '74'), +('6', '11', '41', '1108', '1534', '52', '39', '52', '63', '76'), +('6', '11', '42', '1151', '1594', '53', '39', '53', '65', '78'), +('6', '11', '43', '1197', '1624', '54', '40', '54', '66', '79'), +('6', '11', '44', '1243', '1684', '55', '41', '54', '68', '81'), +('6', '11', '45', '1290', '1714', '55', '42', '55', '69', '83'), +('6', '11', '46', '1339', '1774', '56', '43', '56', '71', '85'), +('6', '11', '47', '1388', '1804', '57', '43', '58', '72', '86'), +('6', '11', '48', '1437', '1849', '58', '44', '59', '74', '88'), +('6', '11', '49', '1490', '1909', '59', '45', '60', '76', '90'), +('6', '11', '50', '1542', '1939', '60', '46', '61', '77', '92'), +('6', '11', '51', '1596', '1984', '61', '47', '62', '79', '94'), +('6', '11', '52', '1651', '2044', '62', '48', '63', '81', '96'), +('6', '11', '53', '1706', '2074', '63', '49', '64', '82', '98'), +('6', '11', '54', '1763', '2119', '64', '49', '65', '84', '100'), +('6', '11', '55', '1820', '2164', '65', '50', '66', '86', '102'), +('6', '11', '56', '1879', '2209', '66', '51', '67', '88', '104'), +('6', '11', '57', '1940', '2254', '67', '52', '68', '89', '106'), +('6', '11', '58', '2000', '2299', '68', '53', '70', '91', '108'), +('6', '11', '59', '2063', '2344', '69', '54', '71', '93', '110'), +('6', '11', '60', '2125', '2389', '70', '55', '72', '95', '112'), +('7', '1', '1', '50', '0', '18', '23', '21', '23', '20'), +('7', '1', '2', '69', '0', '19', '24', '22', '24', '20'), +('7', '1', '3', '88', '0', '20', '24', '23', '24', '21'), +('7', '1', '4', '107', '0', '21', '25', '24', '24', '21'), +('7', '1', '5', '126', '0', '23', '26', '25', '24', '21'), +('7', '1', '6', '145', '0', '24', '27', '26', '25', '21'), +('7', '1', '7', '164', '0', '25', '27', '27', '25', '22'), +('7', '1', '8', '183', '0', '26', '28', '28', '25', '22'), +('7', '1', '9', '202', '0', '27', '29', '29', '25', '22'), +('7', '1', '10', '221', '0', '28', '29', '30', '25', '23'), +('7', '1', '11', '240', '0', '30', '30', '32', '25', '23'), +('7', '1', '12', '259', '0', '31', '31', '33', '25', '23'), +('7', '1', '13', '278', '0', '32', '32', '34', '25', '24'), +('7', '1', '14', '298', '0', '34', '33', '35', '26', '24'), +('7', '1', '15', '319', '0', '35', '33', '36', '26', '24'), +('7', '1', '16', '341', '0', '36', '34', '37', '26', '25'), +('7', '1', '17', '364', '0', '37', '35', '39', '26', '25'), +('7', '1', '18', '388', '0', '39', '36', '40', '26', '25'), +('7', '1', '19', '413', '0', '40', '37', '41', '26', '26'), +('7', '1', '20', '439', '0', '42', '38', '42', '26', '26'), +('7', '1', '21', '466', '0', '43', '38', '44', '27', '26'), +('7', '1', '22', '494', '0', '44', '39', '45', '27', '27'), +('7', '1', '23', '523', '0', '46', '40', '46', '27', '27'), +('7', '1', '24', '553', '0', '47', '41', '48', '27', '28'), +('7', '1', '25', '584', '0', '49', '42', '49', '27', '28'), +('7', '1', '26', '616', '0', '50', '43', '50', '27', '28'), +('7', '1', '27', '649', '0', '52', '44', '52', '27', '29'), +('7', '1', '28', '683', '0', '53', '45', '53', '28', '29'), +('7', '1', '29', '718', '0', '55', '46', '55', '28', '30'), +('7', '1', '30', '754', '0', '57', '47', '56', '28', '30'), +('7', '1', '31', '791', '0', '58', '48', '57', '28', '30'), +('7', '1', '32', '829', '0', '60', '49', '59', '28', '31'), +('7', '1', '33', '868', '0', '61', '50', '60', '28', '31'), +('7', '1', '34', '908', '0', '63', '51', '62', '29', '32'), +('7', '1', '35', '949', '0', '65', '52', '63', '29', '32'), +('7', '1', '36', '991', '0', '67', '53', '65', '29', '33'), +('7', '1', '37', '1070', '0', '68', '54', '67', '29', '33'), +('7', '1', '38', '1081', '0', '70', '55', '68', '29', '33'), +('7', '1', '39', '1129', '0', '72', '56', '70', '30', '34'), +('7', '1', '40', '1179', '0', '74', '57', '71', '30', '34'), +('7', '1', '41', '1231', '0', '75', '59', '73', '30', '35'), +('7', '1', '42', '1285', '0', '77', '60', '75', '30', '35'), +('7', '1', '43', '1341', '0', '79', '61', '76', '30', '36'), +('7', '1', '44', '1399', '0', '81', '62', '78', '30', '36'), +('7', '1', '45', '1459', '0', '83', '63', '80', '32', '37'), +('7', '1', '46', '1521', '0', '85', '64', '82', '32', '37'), +('7', '1', '47', '1585', '0', '87', '66', '83', '32', '38'), +('7', '1', '48', '1651', '0', '89', '67', '85', '32', '38'), +('7', '1', '49', '1719', '0', '91', '68', '87', '33', '39'), +('7', '1', '50', '1789', '0', '93', '69', '89', '33', '39'), +('7', '1', '51', '1861', '0', '95', '71', '91', '33', '40'), +('7', '1', '52', '1935', '0', '97', '72', '93', '33', '40'), +('7', '1', '53', '2011', '0', '99', '73', '95', '33', '41'), +('7', '1', '54', '2089', '0', '101', '75', '97', '34', '42'), +('7', '1', '55', '2169', '0', '104', '76', '99', '34', '42'), +('7', '1', '56', '2251', '0', '106', '77', '101', '34', '43'), +('7', '1', '57', '2335', '0', '108', '79', '103', '34', '43'), +('7', '1', '58', '2421', '0', '110', '80', '105', '35', '44'), +('7', '1', '59', '2509', '0', '113', '82', '107', '35', '44'), +('7', '1', '60', '2599', '0', '115', '83', '109', '35', '45'), +('7', '4', '1', '45', '0', '16', '26', '20', '23', '20'), +('7', '4', '2', '62', '0', '17', '27', '21', '24', '20'), +('7', '4', '3', '79', '0', '17', '28', '21', '24', '21'), +('7', '4', '4', '96', '0', '18', '30', '22', '25', '21'), +('7', '4', '5', '113', '0', '19', '31', '23', '25', '21'), +('7', '4', '6', '130', '0', '19', '32', '23', '25', '22'), +('7', '4', '7', '147', '0', '20', '34', '24', '25', '22'), +('7', '4', '8', '164', '0', '21', '35', '24', '25', '22'), +('7', '4', '9', '181', '0', '22', '36', '25', '25', '23'), +('7', '4', '10', '198', '0', '22', '38', '26', '26', '23'), +('7', '4', '11', '215', '0', '23', '39', '27', '26', '24'), +('7', '4', '12', '232', '0', '24', '40', '27', '26', '24'), +('7', '4', '13', '249', '0', '25', '42', '28', '26', '24'), +('7', '4', '14', '266', '0', '25', '43', '29', '26', '25'), +('7', '4', '15', '283', '0', '26', '45', '29', '27', '25'), +('7', '4', '16', '301', '0', '27', '46', '30', '27', '26'), +('7', '4', '17', '320', '0', '28', '47', '31', '27', '26'), +('7', '4', '18', '340', '0', '29', '49', '32', '27', '26'), +('7', '4', '19', '361', '0', '30', '51', '32', '27', '27'), +('7', '4', '20', '383', '0', '30', '52', '33', '28', '27'), +('7', '4', '21', '406', '0', '31', '54', '34', '28', '28'), +('7', '4', '22', '430', '0', '32', '55', '35', '28', '28'), +('7', '4', '23', '455', '0', '33', '57', '36', '28', '29'), +('7', '4', '24', '481', '0', '34', '58', '36', '29', '29'), +('7', '4', '25', '508', '0', '35', '60', '37', '29', '30'), +('7', '4', '26', '536', '0', '36', '62', '38', '29', '30'), +('7', '4', '27', '565', '0', '37', '63', '39', '29', '30'), +('7', '4', '28', '595', '0', '38', '65', '40', '29', '31'), +('7', '4', '29', '626', '0', '38', '67', '41', '30', '31'), +('7', '4', '30', '658', '0', '39', '69', '41', '30', '32'), +('7', '4', '31', '691', '0', '40', '70', '42', '30', '32'), +('7', '4', '32', '725', '0', '41', '72', '43', '30', '33'), +('7', '4', '33', '760', '0', '42', '74', '44', '32', '33'), +('7', '4', '34', '796', '0', '43', '76', '45', '32', '34'), +('7', '4', '35', '833', '0', '44', '78', '46', '32', '34'), +('7', '4', '36', '871', '0', '46', '80', '47', '33', '35'), +('7', '4', '37', '910', '0', '47', '81', '48', '33', '36'), +('7', '4', '38', '950', '0', '48', '83', '49', '33', '36'), +('7', '4', '39', '991', '0', '49', '85', '50', '33', '37'), +('7', '4', '40', '1033', '0', '50', '87', '51', '34', '37'), +('7', '4', '41', '1076', '0', '51', '89', '52', '34', '38'), +('7', '4', '42', '1120', '0', '52', '91', '53', '34', '38'), +('7', '4', '43', '1165', '0', '53', '93', '54', '34', '39'), +('7', '4', '44', '1211', '0', '54', '96', '55', '35', '39'), +('7', '4', '45', '1258', '0', '56', '98', '56', '35', '40'), +('7', '4', '46', '1306', '0', '57', '100', '57', '35', '41'), +('7', '4', '47', '1355', '0', '58', '102', '58', '36', '41'), +('7', '4', '48', '1405', '0', '59', '104', '59', '36', '42'), +('7', '4', '49', '1456', '0', '60', '106', '61', '36', '43'), +('7', '4', '50', '1508', '0', '62', '109', '62', '37', '43'), +('7', '4', '51', '1561', '0', '63', '111', '63', '37', '44'), +('7', '4', '52', '1615', '0', '64', '113', '64', '37', '44'), +('7', '4', '53', '1670', '0', '65', '116', '65', '38', '45'), +('7', '4', '54', '1726', '0', '67', '118', '66', '38', '46'), +('7', '4', '55', '1783', '0', '68', '120', '68', '38', '46'), +('7', '4', '56', '1841', '0', '69', '123', '69', '39', '47'), +('7', '4', '57', '1900', '0', '71', '125', '70', '39', '48'), +('7', '4', '58', '1960', '0', '72', '128', '71', '39', '49'), +('7', '4', '59', '2021', '0', '74', '130', '73', '40', '49'), +('7', '4', '60', '2083', '0', '75', '133', '74', '40', '50'), +('7', '8', '1', '51', '119', '15', '23', '19', '26', '22'), +('7', '8', '2', '66', '280', '15', '23', '19', '28', '23'), +('7', '8', '3', '72', '306', '15', '23', '20', '29', '24'), +('7', '8', '4', '87', '333', '15', '24', '20', '32', '25'), +('7', '8', '5', '102', '391', '15', '24', '20', '33', '27'), +('7', '8', '6', '117', '420', '16', '24', '20', '34', '28'), +('7', '8', '7', '132', '450', '16', '24', '21', '35', '29'), +('7', '8', '8', '147', '466', '16', '24', '21', '36', '30'), +('7', '8', '9', '162', '513', '16', '24', '21', '38', '31'), +('7', '8', '10', '177', '546', '16', '25', '22', '39', '33'), +('7', '8', '11', '192', '580', '16', '25', '22', '40', '34'), +('7', '8', '12', '207', '615', '16', '25', '22', '42', '35'), +('7', '8', '13', '222', '636', '16', '25', '23', '43', '36'), +('7', '8', '14', '237', '673', '17', '25', '23', '44', '38'), +('7', '8', '15', '252', '711', '17', '26', '23', '46', '39'), +('7', '8', '16', '267', '750', '17', '26', '24', '47', '40'), +('7', '8', '17', '282', '775', '17', '26', '24', '48', '42'), +('7', '8', '18', '297', '831', '17', '26', '24', '50', '43'), +('7', '8', '19', '312', '858', '17', '26', '25', '51', '44'), +('7', '8', '20', '327', '946', '17', '27', '25', '54', '46'), +('7', '8', '21', '342', '975', '18', '27', '25', '55', '47'), +('7', '8', '22', '357', '1035', '18', '27', '26', '57', '49'), +('7', '8', '23', '372', '1066', '18', '27', '26', '58', '50'), +('7', '8', '24', '388', '1128', '18', '28', '27', '60', '52'), +('7', '8', '25', '405', '1161', '18', '28', '27', '61', '53'), +('7', '8', '26', '423', '1225', '18', '28', '27', '63', '55'), +('7', '8', '27', '442', '1260', '18', '28', '28', '65', '56'), +('7', '8', '28', '462', '1296', '19', '28', '28', '66', '58'), +('7', '8', '29', '483', '1362', '19', '29', '29', '68', '59'), +('7', '8', '30', '505', '1413', '19', '29', '29', '70', '61'), +('7', '8', '31', '528', '1449', '19', '29', '29', '71', '63'), +('7', '8', '32', '552', '1515', '19', '29', '30', '74', '64'), +('7', '8', '33', '577', '1596', '19', '30', '30', '76', '66'), +('7', '8', '34', '603', '1632', '20', '30', '31', '77', '68'), +('7', '8', '35', '630', '1683', '20', '30', '31', '79', '69'), +('7', '8', '36', '658', '1734', '20', '31', '32', '81', '71'), +('7', '8', '37', '687', '1800', '20', '31', '32', '83', '73'), +('7', '8', '38', '717', '1836', '20', '31', '32', '85', '75'), +('7', '8', '39', '748', '1887', '21', '31', '33', '87', '76'), +('7', '8', '40', '780', '1923', '21', '32', '33', '88', '78'), +('7', '8', '41', '813', '1974', '21', '32', '34', '90', '80'), +('7', '8', '42', '847', '2025', '21', '32', '34', '92', '82'), +('7', '8', '43', '882', '2076', '21', '32', '35', '95', '84'), +('7', '8', '44', '918', '2157', '21', '33', '35', '97', '86'), +('7', '8', '45', '955', '2208', '22', '33', '36', '99', '88'), +('7', '8', '46', '993', '2259', '22', '33', '36', '101', '90'), +('7', '8', '47', '1032', '2310', '22', '34', '37', '103', '92'), +('7', '8', '48', '1072', '2361', '22', '34', '37', '106', '94'), +('7', '8', '49', '1113', '2412', '23', '34', '38', '108', '96'), +('7', '8', '50', '1155', '2448', '23', '35', '38', '110', '98'), +('7', '8', '51', '1198', '2499', '23', '35', '39', '112', '100'), +('7', '8', '52', '1242', '2550', '23', '35', '39', '114', '102'), +('7', '8', '53', '1287', '2631', '23', '36', '40', '117', '104'), +('7', '8', '54', '1333', '2682', '24', '36', '41', '120', '106'), +('7', '8', '55', '1380', '2733', '24', '36', '41', '122', '109'), +('7', '8', '56', '1428', '2784', '24', '37', '42', '124', '111'), +('7', '8', '57', '1477', '2820', '24', '37', '42', '127', '113'), +('7', '8', '58', '1527', '2871', '25', '37', '43', '129', '115'), +('7', '8', '59', '1578', '2922', '25', '38', '43', '132', '118'), +('7', '8', '60', '1630', '2973', '25', '38', '44', '133', '120'), +('7', '9', '1', '43', '109', '15', '23', '20', '25', '22'), +('7', '9', '2', '58', '223', '15', '23', '21', '27', '23'), +('7', '9', '3', '73', '247', '16', '24', '21', '28', '24'), +('7', '9', '4', '88', '272', '16', '24', '22', '29', '25'), +('7', '9', '5', '103', '298', '16', '24', '22', '30', '26'), +('7', '9', '6', '118', '325', '16', '25', '23', '32', '27'), +('7', '9', '7', '133', '383', '17', '25', '23', '33', '29'), +('7', '9', '8', '148', '412', '17', '25', '24', '34', '30'), +('7', '9', '9', '163', '442', '17', '26', '24', '35', '31'), +('7', '9', '10', '178', '473', '18', '26', '25', '36', '32'), +('7', '9', '11', '193', '505', '18', '27', '25', '38', '33'), +('7', '9', '12', '208', '538', '18', '27', '26', '39', '34'), +('7', '9', '13', '223', '572', '19', '27', '26', '40', '36'), +('7', '9', '14', '238', '607', '19', '28', '27', '41', '37'), +('7', '9', '15', '253', '643', '19', '28', '28', '42', '38'), +('7', '9', '16', '268', '665', '20', '29', '28', '43', '39'), +('7', '9', '17', '283', '703', '20', '29', '29', '45', '41'), +('7', '9', '18', '299', '742', '20', '29', '29', '46', '42'), +('7', '9', '19', '316', '782', '21', '30', '30', '47', '43'), +('7', '9', '20', '334', '823', '21', '30', '31', '48', '45'), +('7', '9', '21', '353', '865', '21', '31', '31', '50', '46'), +('7', '9', '22', '373', '908', '22', '31', '32', '51', '47'), +('7', '9', '23', '394', '952', '22', '32', '33', '53', '49'), +('7', '9', '24', '416', '1027', '23', '32', '33', '55', '50'), +('7', '9', '25', '439', '1073', '23', '33', '34', '56', '52'), +('7', '9', '26', '463', '1120', '23', '33', '35', '57', '53'), +('7', '9', '27', '488', '1168', '24', '33', '35', '59', '54'), +('7', '9', '28', '514', '1217', '24', '34', '36', '60', '56'), +('7', '9', '29', '541', '1267', '25', '34', '37', '62', '57'), +('7', '9', '30', '569', '1318', '25', '35', '37', '63', '59'), +('7', '9', '31', '588', '1354', '25', '35', '37', '64', '62'), +('7', '9', '32', '628', '1405', '26', '36', '39', '66', '62'), +('7', '9', '33', '659', '1456', '26', '36', '40', '67', '64'), +('7', '9', '34', '691', '1507', '27', '37', '40', '69', '65'), +('7', '9', '35', '724', '1558', '27', '37', '41', '70', '67'), +('7', '9', '36', '758', '1609', '28', '38', '42', '72', '69'), +('7', '9', '37', '793', '1690', '28', '39', '43', '75', '69'), +('7', '9', '38', '829', '1741', '28', '39', '44', '76', '72'), +('7', '9', '39', '866', '1792', '29', '40', '44', '78', '74'), +('7', '9', '40', '904', '1843', '29', '40', '45', '79', '75'), +('7', '9', '41', '943', '1894', '30', '41', '46', '81', '77'), +('7', '9', '42', '983', '1945', '30', '41', '47', '83', '79'), +('7', '9', '43', '1024', '1996', '31', '42', '48', '84', '81'), +('7', '9', '44', '1066', '2032', '31', '42', '49', '86', '82'), +('7', '9', '45', '1109', '2083', '32', '43', '49', '88', '84'), +('7', '9', '46', '1153', '2134', '32', '44', '50', '90', '86'), +('7', '9', '47', '1198', '2185', '33', '44', '51', '91', '88'), +('7', '9', '48', '1234', '2236', '33', '45', '52', '93', '90'), +('7', '9', '49', '1281', '2317', '34', '46', '53', '96', '92'), +('7', '9', '50', '1339', '2368', '34', '46', '54', '98', '93'), +('7', '9', '51', '1388', '2419', '35', '47', '55', '100', '96'), +('7', '9', '52', '1418', '2470', '35', '47', '56', '102', '98'), +('7', '9', '53', '1489', '2521', '36', '48', '57', '104', '100'), +('7', '9', '54', '1541', '2557', '37', '49', '58', '106', '102'), +('7', '9', '55', '1584', '2608', '37', '49', '58', '108', '104'), +('7', '9', '56', '1648', '2659', '38', '50', '60', '110', '106'), +('7', '9', '57', '1683', '2710', '38', '51', '61', '112', '108'), +('7', '9', '58', '1759', '2761', '39', '52', '62', '114', '111'), +('7', '9', '59', '1816', '2842', '39', '52', '63', '117', '111'), +('7', '9', '60', '1874', '2893', '40', '53', '64', '119', '115'), +('8', '1', '1', '70', '0', '24', '22', '23', '16', '21'), +('8', '1', '2', '89', '0', '25', '23', '24', '16', '21'), +('8', '1', '3', '108', '0', '26', '23', '25', '16', '22'), +('8', '1', '4', '127', '0', '27', '24', '26', '16', '22'), +('8', '1', '5', '146', '0', '29', '25', '27', '16', '22'), +('8', '1', '6', '165', '0', '30', '26', '28', '17', '22'), +('8', '1', '7', '184', '0', '31', '26', '29', '17', '23'), +('8', '1', '8', '203', '0', '32', '27', '30', '17', '23'), +('8', '1', '9', '222', '0', '33', '28', '31', '17', '23'), +('8', '1', '10', '241', '0', '34', '28', '32', '17', '24'), +('8', '1', '11', '260', '0', '36', '29', '34', '17', '24'), +('8', '1', '12', '279', '0', '37', '30', '35', '17', '24'), +('8', '1', '13', '298', '0', '38', '31', '36', '17', '25'), +('8', '1', '14', '318', '0', '40', '32', '37', '18', '25'), +('8', '1', '15', '339', '0', '41', '32', '38', '18', '25'), +('8', '1', '16', '361', '0', '42', '33', '39', '18', '26'), +('8', '1', '17', '384', '0', '43', '34', '41', '18', '26'), +('8', '1', '18', '408', '0', '45', '35', '42', '18', '26'), +('8', '1', '19', '433', '0', '46', '36', '43', '18', '27'), +('8', '1', '20', '459', '0', '48', '37', '44', '18', '27'), +('8', '1', '21', '486', '0', '49', '37', '46', '19', '27'), +('8', '1', '22', '514', '0', '50', '38', '47', '19', '28'), +('8', '1', '23', '543', '0', '52', '39', '48', '19', '28'), +('8', '1', '24', '573', '0', '53', '40', '50', '19', '29'), +('8', '1', '25', '604', '0', '55', '41', '51', '19', '29'), +('8', '1', '26', '636', '0', '56', '42', '52', '19', '29'), +('8', '1', '27', '669', '0', '58', '43', '54', '19', '30'), +('8', '1', '28', '703', '0', '59', '44', '55', '20', '30'), +('8', '1', '29', '738', '0', '61', '45', '57', '20', '31'), +('8', '1', '30', '774', '0', '63', '46', '58', '20', '31'), +('8', '1', '31', '811', '0', '64', '47', '59', '20', '31'), +('8', '1', '32', '849', '0', '66', '48', '61', '20', '32'), +('8', '1', '33', '888', '0', '67', '49', '62', '20', '32'), +('8', '1', '34', '928', '0', '69', '50', '64', '21', '33'), +('8', '1', '35', '969', '0', '71', '51', '65', '21', '33'), +('8', '1', '36', '1011', '0', '73', '52', '67', '21', '34'), +('8', '1', '37', '1055', '0', '74', '53', '69', '21', '34'), +('8', '1', '38', '1101', '0', '76', '54', '70', '21', '34'), +('8', '1', '39', '1149', '0', '78', '55', '72', '22', '35'), +('8', '1', '40', '1199', '0', '80', '56', '73', '22', '35'), +('8', '1', '41', '1251', '0', '81', '58', '75', '22', '36'), +('8', '1', '42', '1310', '0', '83', '59', '77', '22', '36'), +('8', '1', '43', '1361', '0', '85', '60', '78', '22', '37'), +('8', '1', '44', '1419', '0', '87', '61', '80', '22', '37'), +('8', '1', '45', '1529', '0', '89', '62', '82', '23', '38'), +('8', '1', '46', '1541', '0', '91', '63', '84', '23', '38'), +('8', '1', '47', '1605', '0', '93', '65', '85', '23', '39'), +('8', '1', '48', '1671', '0', '95', '66', '87', '23', '39'), +('8', '1', '49', '1739', '0', '97', '67', '89', '24', '40'), +('8', '1', '50', '1809', '0', '99', '68', '91', '24', '40'), +('8', '1', '51', '1881', '0', '101', '70', '93', '24', '41'), +('8', '1', '52', '1955', '0', '103', '71', '95', '24', '41'), +('8', '1', '53', '2031', '0', '105', '72', '97', '24', '42'), +('8', '1', '54', '2109', '0', '107', '74', '99', '25', '43'), +('8', '1', '55', '2189', '0', '110', '75', '101', '25', '43'), +('8', '1', '56', '2271', '0', '112', '76', '103', '25', '44'), +('8', '1', '57', '2355', '0', '114', '78', '105', '25', '44'), +('8', '1', '58', '2441', '0', '116', '79', '107', '26', '45'), +('8', '1', '59', '2529', '0', '119', '81', '109', '26', '45'), +('8', '1', '60', '2619', '0', '121', '82', '111', '26', '46'), +('8', '3', '1', '66', '80', '21', '25', '22', '16', '22'), +('8', '3', '2', '83', '87', '21', '26', '23', '17', '23'), +('8', '3', '3', '100', '108', '22', '27', '24', '17', '23'), +('8', '3', '4', '117', '116', '22', '29', '24', '18', '24'), +('8', '3', '5', '134', '139', '23', '30', '25', '18', '24'), +('8', '3', '6', '151', '149', '23', '31', '26', '19', '25'), +('8', '3', '7', '168', '174', '23', '32', '27', '19', '25'), +('8', '3', '8', '185', '186', '24', '33', '28', '20', '26'), +('8', '3', '9', '202', '213', '24', '35', '29', '20', '27'), +('8', '3', '10', '219', '241', '25', '36', '29', '21', '27'), +('8', '3', '11', '236', '270', '25', '37', '30', '21', '28'), +('8', '3', '12', '253', '300', '26', '39', '31', '22', '29'), +('8', '3', '13', '270', '331', '26', '40', '32', '23', '29'), +('8', '3', '14', '288', '363', '27', '41', '33', '23', '30'), +('8', '3', '15', '307', '396', '27', '43', '34', '24', '30'), +('8', '3', '16', '327', '430', '28', '44', '35', '24', '31'), +('8', '3', '17', '348', '465', '28', '45', '36', '25', '32'), +('8', '3', '18', '370', '501', '29', '47', '37', '26', '33'), +('8', '3', '19', '393', '538', '29', '48', '38', '26', '33'), +('8', '3', '20', '417', '576', '30', '50', '39', '27', '34'), +('8', '3', '21', '442', '615', '30', '51', '40', '28', '35'), +('8', '3', '22', '468', '655', '31', '53', '41', '28', '35'), +('8', '3', '23', '495', '696', '31', '54', '42', '29', '36'), +('8', '3', '24', '523', '738', '32', '56', '43', '30', '37'), +('8', '3', '25', '552', '781', '32', '57', '44', '30', '38'), +('8', '3', '26', '582', '825', '33', '59', '45', '31', '38'), +('8', '3', '27', '613', '870', '33', '61', '46', '32', '39'), +('8', '3', '28', '645', '915', '34', '62', '47', '32', '40'), +('8', '3', '29', '678', '960', '34', '64', '48', '33', '41'), +('8', '3', '30', '712', '1005', '35', '66', '49', '34', '41'), +('8', '3', '31', '747', '1050', '35', '67', '51', '35', '42'), +('8', '3', '32', '783', '1095', '36', '69', '52', '35', '43'), +('8', '3', '33', '820', '1140', '37', '71', '53', '36', '44'), +('8', '3', '34', '858', '1185', '37', '72', '54', '37', '45'), +('8', '3', '35', '897', '1230', '38', '74', '55', '38', '46'), +('8', '3', '36', '937', '1275', '39', '76', '57', '39', '47'), +('8', '3', '37', '978', '1320', '39', '78', '58', '39', '47'), +('8', '3', '38', '1020', '1365', '40', '80', '59', '40', '48'), +('8', '3', '39', '1063', '1410', '40', '82', '60', '41', '49'), +('8', '3', '40', '1107', '1455', '41', '83', '62', '42', '50'), +('8', '3', '41', '1152', '1500', '42', '85', '63', '43', '51'), +('8', '3', '42', '1198', '1545', '42', '87', '64', '43', '52'), +('8', '3', '43', '1245', '1590', '43', '89', '65', '44', '53'), +('8', '3', '44', '1293', '1635', '44', '91', '67', '45', '54'), +('8', '3', '45', '1342', '1680', '44', '93', '68', '46', '55'), +('8', '3', '46', '1392', '1725', '45', '95', '70', '47', '56'), +('8', '3', '47', '1443', '1770', '46', '97', '71', '48', '57'), +('8', '3', '48', '1495', '1815', '47', '100', '72', '49', '58'), +('8', '3', '49', '1548', '1860', '47', '102', '74', '50', '59'), +('8', '3', '50', '1602', '1905', '48', '104', '75', '51', '60'), +('8', '3', '51', '1657', '1950', '49', '106', '77', '52', '61'), +('8', '3', '52', '1713', '1995', '50', '108', '78', '53', '62'), +('8', '3', '53', '1770', '2040', '50', '110', '80', '54', '63'), +('8', '3', '54', '1828', '2085', '51', '113', '81', '55', '64'), +('8', '3', '55', '1887', '2130', '52', '115', '83', '56', '65'), +('8', '3', '56', '1947', '2175', '53', '117', '84', '57', '66'), +('8', '3', '57', '2008', '2220', '54', '120', '86', '58', '68'), +('8', '3', '58', '2070', '2265', '54', '122', '88', '59', '69'), +('8', '3', '59', '2133', '2310', '55', '125', '89', '60', '70'), +('8', '3', '60', '2197', '2355', '56', '127', '91', '61', '71'), +('8', '4', '1', '65', '0', '22', '25', '22', '16', '21'), +('8', '4', '2', '82', '0', '23', '26', '23', '16', '21'), +('8', '4', '3', '99', '0', '23', '27', '23', '16', '22'), +('8', '4', '4', '116', '0', '24', '29', '24', '17', '22'), +('8', '4', '5', '133', '0', '25', '30', '25', '17', '22'), +('8', '4', '6', '150', '0', '25', '31', '25', '17', '23'), +('8', '4', '7', '167', '0', '26', '33', '26', '17', '23'), +('8', '4', '8', '184', '0', '27', '34', '26', '17', '23'), +('8', '4', '9', '201', '0', '28', '35', '27', '17', '24'), +('8', '4', '10', '218', '0', '28', '37', '28', '18', '24'), +('8', '4', '11', '235', '0', '29', '38', '29', '18', '25'), +('8', '4', '12', '252', '0', '30', '39', '29', '18', '25'), +('8', '4', '13', '269', '0', '31', '41', '30', '18', '25'), +('8', '4', '14', '286', '0', '31', '42', '31', '18', '26'), +('8', '4', '15', '303', '0', '32', '44', '31', '19', '26'), +('8', '4', '16', '321', '0', '33', '45', '32', '19', '27'), +('8', '4', '17', '340', '0', '34', '46', '33', '19', '27'), +('8', '4', '18', '360', '0', '35', '48', '34', '19', '27'), +('8', '4', '19', '381', '0', '36', '50', '34', '19', '28'), +('8', '4', '20', '403', '0', '36', '51', '35', '20', '28'), +('8', '4', '21', '426', '0', '37', '53', '36', '20', '29'), +('8', '4', '22', '450', '0', '38', '54', '37', '20', '29'), +('8', '4', '23', '475', '0', '39', '56', '38', '20', '30'), +('8', '4', '24', '501', '0', '40', '57', '38', '21', '30'), +('8', '4', '25', '528', '0', '41', '59', '39', '21', '31'), +('8', '4', '26', '556', '0', '42', '61', '40', '21', '31'), +('8', '4', '27', '585', '0', '43', '62', '41', '21', '31'), +('8', '4', '28', '615', '0', '44', '64', '42', '21', '32'), +('8', '4', '29', '646', '0', '44', '66', '43', '22', '32'), +('8', '4', '30', '678', '0', '45', '68', '43', '22', '33'), +('8', '4', '31', '711', '0', '46', '69', '44', '22', '33'), +('8', '4', '32', '745', '0', '47', '71', '45', '22', '34'), +('8', '4', '33', '780', '0', '48', '73', '46', '23', '34'), +('8', '4', '34', '816', '0', '49', '75', '47', '23', '35'), +('8', '4', '35', '853', '0', '50', '77', '48', '23', '35'), +('8', '4', '36', '891', '0', '52', '79', '49', '24', '36'), +('8', '4', '37', '930', '0', '53', '80', '50', '24', '37'), +('8', '4', '38', '970', '0', '54', '82', '51', '24', '37'), +('8', '4', '39', '1011', '0', '55', '84', '52', '24', '38'), +('8', '4', '40', '1053', '0', '56', '86', '53', '25', '38'), +('8', '4', '41', '1096', '0', '57', '88', '54', '25', '39'), +('8', '4', '42', '1140', '0', '58', '90', '55', '25', '39'), +('8', '4', '43', '1185', '0', '59', '92', '56', '25', '40'), +('8', '4', '44', '1231', '0', '60', '95', '57', '26', '40'), +('8', '4', '45', '1278', '0', '62', '97', '58', '26', '41'), +('8', '4', '46', '1326', '0', '63', '99', '59', '26', '42'), +('8', '4', '47', '1375', '0', '64', '101', '60', '27', '42'), +('8', '4', '48', '1425', '0', '65', '103', '61', '27', '43'), +('8', '4', '49', '1476', '0', '66', '105', '63', '27', '44'), +('8', '4', '50', '1528', '0', '68', '108', '64', '28', '44'), +('8', '4', '51', '1581', '0', '69', '110', '65', '28', '45'), +('8', '4', '52', '1635', '0', '70', '112', '66', '28', '45'), +('8', '4', '53', '1690', '0', '71', '115', '67', '29', '46'), +('8', '4', '54', '1746', '0', '73', '117', '68', '29', '47'), +('8', '4', '55', '1803', '0', '74', '119', '70', '29', '47'), +('8', '4', '56', '1861', '0', '75', '122', '71', '30', '48'), +('8', '4', '57', '1920', '0', '77', '124', '72', '30', '49'), +('8', '4', '58', '1980', '0', '78', '127', '73', '30', '50'), +('8', '4', '59', '2041', '0', '80', '129', '75', '31', '50'), +('8', '4', '60', '2103', '0', '81', '132', '76', '31', '51'), +('8', '5', '1', '71', '128', '21', '22', '21', '18', '24'), +('8', '5', '2', '77', '138', '21', '22', '21', '19', '25'), +('8', '5', '3', '92', '149', '21', '22', '22', '20', '26'), +('8', '5', '4', '107', '175', '22', '23', '22', '21', '28'), +('8', '5', '5', '122', '202', '22', '23', '22', '23', '29'), +('8', '5', '6', '137', '230', '22', '23', '23', '24', '30'), +('8', '5', '7', '152', '259', '22', '23', '23', '25', '31'), +('8', '5', '8', '167', '289', '22', '24', '23', '26', '32'), +('8', '5', '9', '182', '320', '22', '24', '24', '27', '34'), +('8', '5', '10', '197', '367', '23', '24', '24', '29', '35'), +('8', '5', '11', '212', '385', '23', '24', '25', '30', '36'), +('8', '5', '12', '227', '419', '23', '25', '25', '31', '38'), +('8', '5', '13', '242', '454', '23', '25', '25', '32', '39'), +('8', '5', '14', '257', '490', '23', '25', '26', '34', '40'), +('8', '5', '15', '272', '527', '24', '25', '26', '35', '42'), +('8', '5', '16', '287', '565', '24', '26', '27', '36', '43'), +('8', '5', '17', '302', '619', '24', '26', '27', '38', '44'), +('8', '5', '18', '317', '644', '24', '26', '27', '39', '46'), +('8', '5', '19', '332', '685', '24', '27', '28', '40', '47'), +('8', '5', '20', '347', '727', '25', '27', '28', '42', '49'), +('8', '5', '21', '362', '770', '25', '27', '29', '43', '50'), +('8', '5', '22', '378', '829', '25', '27', '29', '45', '52'), +('8', '5', '23', '395', '859', '25', '28', '30', '46', '53'), +('8', '5', '24', '413', '920', '26', '28', '30', '48', '55'), +('8', '5', '25', '432', '952', '26', '28', '31', '49', '56'), +('8', '5', '26', '452', '1015', '26', '29', '31', '51', '58'), +('8', '5', '27', '473', '1049', '26', '29', '31', '52', '60'), +('8', '5', '28', '495', '1114', '26', '29', '32', '54', '61'), +('8', '5', '29', '518', '1150', '27', '30', '32', '55', '63'), +('8', '5', '30', '542', '1202', '27', '30', '33', '57', '65'), +('8', '5', '31', '567', '1270', '27', '30', '33', '59', '66'), +('8', '5', '32', '593', '1309', '27', '31', '34', '60', '68'), +('8', '5', '33', '620', '1378', '28', '31', '34', '62', '70'), +('8', '5', '34', '648', '1432', '28', '31', '35', '64', '71'), +('8', '5', '35', '677', '1471', '28', '32', '35', '65', '73'), +('8', '5', '36', '707', '1525', '29', '32', '36', '67', '75'), +('8', '5', '37', '738', '1594', '29', '32', '37', '69', '77'), +('8', '5', '38', '770', '1648', '29', '33', '37', '71', '79'), +('8', '5', '39', '803', '1687', '29', '33', '38', '72', '81'), +('8', '5', '40', '837', '1741', '30', '33', '38', '74', '82'), +('8', '5', '41', '872', '1810', '30', '34', '39', '76', '84'), +('8', '5', '42', '908', '1864', '30', '34', '39', '78', '86'), +('8', '5', '43', '945', '1918', '30', '35', '40', '80', '88'), +('8', '5', '44', '983', '1972', '31', '35', '40', '82', '90'), +('8', '5', '45', '1022', '2026', '31', '35', '41', '84', '92'), +('8', '5', '46', '1062', '2080', '31', '36', '42', '86', '94'), +('8', '5', '47', '1103', '2134', '32', '36', '42', '88', '96'), +('8', '5', '48', '1145', '2188', '32', '37', '43', '90', '99'), +('8', '5', '49', '1238', '2242', '32', '37', '44', '92', '101'), +('8', '5', '50', '1252', '2296', '33', '37', '44', '94', '103'), +('8', '5', '51', '1277', '2350', '33', '38', '45', '96', '105'), +('8', '5', '52', '1323', '2404', '33', '38', '45', '98', '107'), +('8', '5', '53', '1370', '2458', '34', '39', '46', '100', '109'), +('8', '5', '54', '1418', '2512', '34', '39', '47', '102', '112'), +('8', '5', '55', '1467', '2566', '34', '40', '47', '105', '114'), +('8', '5', '56', '1517', '2620', '35', '40', '48', '107', '116'), +('8', '5', '57', '1568', '2674', '35', '41', '49', '109', '119'), +('8', '5', '58', '1620', '2728', '35', '41', '50', '111', '121'), +('8', '5', '59', '1673', '2782', '36', '42', '50', '114', '124'), +('8', '5', '60', '1727', '2836', '36', '42', '51', '116', '126'), +('8', '7', '1', '87', '71', '22', '22', '22', '17', '23'), +('8', '7', '2', '84', '79', '23', '22', '23', '18', '24'), +('8', '7', '3', '101', '87', '23', '23', '24', '19', '25'), +('8', '7', '4', '118', '110', '24', '23', '25', '19', '26'), +('8', '7', '5', '135', '120', '25', '24', '25', '20', '27'), +('8', '7', '6', '152', '145', '26', '24', '26', '21', '28'), +('8', '7', '7', '169', '171', '27', '24', '27', '22', '29'), +('8', '7', '8', '186', '198', '27', '25', '28', '23', '29'), +('8', '7', '9', '203', '241', '28', '25', '29', '24', '30'), +('8', '7', '10', '220', '255', '29', '26', '30', '24', '31'), +('8', '7', '11', '237', '285', '30', '26', '31', '25', '32'), +('8', '7', '12', '254', '316', '31', '27', '32', '26', '33'), +('8', '7', '13', '271', '348', '31', '27', '33', '27', '34'), +('8', '7', '14', '288', '381', '32', '28', '34', '28', '35'), +('8', '7', '15', '305', '415', '33', '28', '35', '29', '37'), +('8', '7', '16', '322', '450', '34', '29', '36', '30', '38'), +('8', '7', '17', '340', '486', '35', '29', '37', '31', '39'), +('8', '7', '18', '359', '523', '36', '30', '38', '32', '40'), +('8', '7', '19', '379', '589', '37', '30', '39', '33', '41'), +('8', '7', '20', '400', '600', '38', '31', '40', '34', '42'), +('8', '7', '21', '422', '640', '39', '31', '41', '35', '43'), +('8', '7', '22', '445', '681', '39', '32', '42', '36', '44'), +('8', '7', '23', '469', '723', '40', '32', '43', '37', '45'), +('8', '7', '24', '494', '766', '41', '33', '44', '38', '47'), +('8', '7', '25', '520', '810', '42', '33', '46', '39', '48'), +('8', '7', '26', '547', '898', '43', '34', '47', '40', '49'), +('8', '7', '27', '575', '947', '44', '34', '48', '41', '50'), +('8', '7', '28', '604', '996', '45', '35', '49', '42', '51'), +('8', '7', '29', '634', '996', '46', '35', '50', '43', '53'), +('8', '7', '30', '665', '1045', '47', '36', '51', '44', '54'), +('8', '7', '31', '697', '1165', '49', '36', '53', '46', '55'), +('8', '7', '32', '730', '1216', '50', '37', '54', '47', '57'), +('8', '7', '33', '764', '1277', '51', '38', '55', '48', '58'), +('8', '7', '34', '799', '1304', '52', '38', '56', '49', '59'), +('8', '7', '35', '835', '1355', '53', '39', '58', '50', '61'), +('8', '7', '36', '872', '1412', '54', '40', '59', '52', '62'), +('8', '7', '37', '910', '1473', '55', '40', '60', '53', '63'), +('8', '7', '38', '949', '1525', '56', '41', '62', '54', '65'), +('8', '7', '39', '989', '1561', '57', '41', '63', '55', '66'), +('8', '7', '40', '1030', '1599', '59', '42', '64', '57', '68'), +('8', '7', '41', '1072', '1627', '60', '43', '66', '58', '69'), +('8', '7', '42', '1115', '1683', '61', '43', '67', '59', '71'), +('8', '7', '43', '1159', '1716', '62', '44', '69', '60', '72'), +('8', '7', '44', '1204', '1746', '64', '45', '70', '62', '74'), +('8', '7', '45', '1250', '1780', '65', '45', '72', '63', '75'), +('8', '7', '46', '1297', '1844', '66', '46', '73', '65', '77'), +('8', '7', '47', '1345', '1988', '67', '47', '75', '66', '78'), +('8', '7', '48', '1394', '2024', '69', '48', '76', '67', '80'), +('8', '7', '49', '1444', '2077', '70', '48', '78', '69', '82'), +('8', '7', '50', '1495', '2127', '71', '49', '79', '70', '83'), +('8', '7', '51', '1547', '2177', '73', '50', '81', '72', '85'), +('8', '7', '52', '1600', '2204', '74', '51', '82', '73', '87'), +('8', '7', '53', '1654', '2235', '76', '51', '84', '75', '88'), +('8', '7', '54', '1709', '2256', '77', '52', '86', '76', '90'), +('8', '7', '55', '1765', '2286', '78', '53', '87', '78', '92'), +('8', '7', '56', '1822', '2319', '80', '54', '89', '79', '94'), +('8', '7', '57', '1880', '2384', '81', '55', '91', '81', '95'), +('8', '7', '58', '1939', '2432', '83', '55', '92', '83', '97'), +('8', '7', '59', '1999', '2481', '84', '56', '94', '84', '99'), +('8', '7', '60', '2060', '2530', '86', '57', '96', '86', '101'), +('8', '8', '1', '71', '119', '21', '22', '21', '19', '23'), +('8', '8', '2', '77', '130', '21', '22', '21', '20', '24'), +('8', '8', '3', '92', '156', '21', '22', '22', '21', '25'), +('8', '8', '4', '107', '183', '21', '23', '22', '23', '26'), +('8', '8', '5', '122', '211', '21', '23', '22', '24', '28'), +('8', '8', '6', '137', '240', '22', '23', '22', '25', '29'), +('8', '8', '7', '152', '270', '22', '23', '23', '26', '30'), +('8', '8', '8', '167', '286', '22', '23', '23', '27', '31'), +('8', '8', '9', '182', '333', '22', '23', '23', '29', '32'), +('8', '8', '10', '197', '366', '22', '24', '24', '30', '34'), +('8', '8', '11', '212', '400', '22', '24', '24', '31', '35'), +('8', '8', '12', '227', '435', '22', '24', '24', '33', '36'), +('8', '8', '13', '242', '471', '22', '24', '25', '34', '37'), +('8', '8', '14', '257', '508', '23', '24', '25', '35', '39'), +('8', '8', '15', '272', '546', '23', '25', '25', '37', '40'), +('8', '8', '16', '287', '585', '23', '25', '26', '38', '41'), +('8', '8', '17', '302', '610', '23', '25', '26', '39', '43'), +('8', '8', '18', '317', '666', '23', '25', '26', '41', '44'), +('8', '8', '19', '332', '693', '23', '25', '27', '42', '45'), +('8', '8', '20', '347', '751', '23', '26', '27', '44', '47'), +('8', '8', '21', '362', '780', '24', '26', '27', '45', '48'), +('8', '8', '22', '377', '840', '24', '26', '28', '47', '50'), +('8', '8', '23', '392', '871', '24', '26', '28', '48', '51'), +('8', '8', '24', '408', '933', '24', '27', '29', '50', '53'), +('8', '8', '25', '425', '966', '24', '27', '29', '51', '54'), +('8', '8', '26', '443', '1030', '24', '27', '29', '53', '56'), +('8', '8', '27', '462', '1080', '24', '27', '30', '55', '57'), +('8', '8', '28', '482', '1116', '25', '27', '30', '56', '59'), +('8', '8', '29', '503', '1182', '25', '28', '31', '58', '60'), +('8', '8', '30', '525', '1233', '25', '28', '31', '60', '62'), +('8', '8', '31', '548', '1269', '25', '28', '31', '61', '64'), +('8', '8', '32', '572', '1335', '25', '28', '32', '63', '65'), +('8', '8', '33', '597', '1386', '25', '29', '32', '65', '67'), +('8', '8', '34', '623', '1422', '26', '29', '33', '66', '69'), +('8', '8', '35', '650', '1473', '26', '29', '33', '68', '70'), +('8', '8', '36', '678', '1524', '26', '30', '34', '70', '72'), +('8', '8', '37', '707', '1590', '26', '30', '34', '72', '74'), +('8', '8', '38', '737', '1641', '26', '30', '34', '74', '76'), +('8', '8', '39', '768', '1692', '27', '30', '35', '76', '77'), +('8', '8', '40', '800', '1728', '27', '31', '35', '77', '79'), +('8', '8', '41', '833', '1779', '27', '31', '36', '79', '81'), +('8', '8', '42', '867', '1830', '27', '31', '36', '81', '83'), +('8', '8', '43', '902', '1881', '27', '31', '37', '83', '85'), +('8', '8', '44', '938', '1932', '27', '32', '37', '85', '87'), +('8', '8', '45', '975', '1983', '28', '32', '38', '87', '89'), +('8', '8', '46', '1013', '2034', '28', '32', '38', '89', '91'), +('8', '8', '47', '1092', '2085', '28', '33', '39', '91', '93'), +('8', '8', '48', '1102', '2151', '28', '33', '39', '94', '95'), +('8', '8', '49', '1133', '2202', '29', '33', '40', '96', '97'), +('8', '8', '50', '1175', '2238', '29', '34', '40', '98', '99'), +('8', '8', '51', '1218', '2289', '29', '34', '41', '100', '101'), +('8', '8', '52', '1262', '2340', '29', '34', '41', '102', '103'), +('8', '8', '53', '1307', '2391', '29', '35', '42', '104', '105'), +('8', '8', '54', '1353', '2442', '30', '35', '43', '107', '107'), +('8', '8', '55', '1400', '2508', '30', '35', '43', '109', '110'), +('8', '8', '56', '1448', '2547', '30', '36', '44', '111', '112'), +('8', '8', '57', '1497', '2595', '30', '36', '44', '114', '114'), +('8', '8', '58', '1547', '2646', '31', '36', '45', '116', '116'), +('8', '8', '59', '1589', '2697', '31', '37', '45', '119', '119'), +('8', '8', '60', '1650', '2748', '31', '37', '46', '121', '121'); diff --git a/sql/updates/0.6/2691_player_levelupgains.sql b/sql/updates/0.6/2691_player_levelupgains.sql new file mode 100644 index 000000000..aef481763 --- /dev/null +++ b/sql/updates/0.6/2691_player_levelupgains.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `player_levelupgains`; diff --git a/sql/updates/0.6/2699_character_inventory.sql b/sql/updates/0.6/2699_character_inventory.sql new file mode 100644 index 000000000..5abfe5958 --- /dev/null +++ b/sql/updates/0.6/2699_character_inventory.sql @@ -0,0 +1,9 @@ +UPDATE character_inventory SET bag = 0 WHERE bag = 255; +CREATE TABLE character_bags SELECT guid, slot, item FROM character_inventory LEFT JOIN item_template ON character_inventory.item_template = item_template.entry WHERE ContainerSlots > 0 AND bag = 0; +CREATE INDEX idx_gs ON character_bags (`guid`,`slot`); +ALTER TABLE character_inventory CHANGE COLUMN `bag` `bag` bigint(20) unsigned NOT NULL default '0'; +UPDATE character_inventory As ci SET bag = (SELECT item FROM character_bags As cb WHERE ci.guid = cb.guid AND cb.slot = ci.bag LIMIT 1) WHERE bag != 0; +DROP TABLE character_bags; +ALTER TABLE character_inventory DROP PRIMARY KEY; +ALTER TABLE character_inventory ADD PRIMARY KEY (`item`); +CREATE INDEX idx_gb ON character_inventory (`guid`,`bag`); \ No newline at end of file diff --git a/sql/updates/0.6/2703_command.sql b/sql/updates/0.6/2703_command.sql new file mode 100644 index 000000000..ec0f7c1e2 --- /dev/null +++ b/sql/updates/0.6/2703_command.sql @@ -0,0 +1,6 @@ +INSERT INTO `command` VALUES('idleshutdown','3','Syntax: .idleshutdown #delay\r\n\r\nShutting down server after #delay seconds if no active connections present (no players).'); +INSERT INTO `command` VALUES('banaccount','3','Syntax: .banaccount $name\r\n\r\nBan account $name (can be view for player using .pinfo command) and kick affected player if he loginned at server.'); +INSERT INTO `command` VALUES('banip','3','Syntax: .banip #ip\r\n\r\nBan loggining to server from computer with provide IP address and kick all affected players with equal last IP.'); +INSERT INTO `command` VALUES('unbanaccount','3','Syntax: .unbanaccount $name\r\n\r\nUnban account $name.'); +INSERT INTO `command` VALUES('unbanip','3','Syntax: .unbanip #ip\r\n\r\nUnban provide IP address.'); +UPDATE `command` SET `help` = 'Syntax: .kick [$charactername]\r\n\r\nKick the given character from the world. If no character name provide then selected player (except self) will be kicked.' WHERE `name` = 'kick'; diff --git a/sql/updates/0.6/2713_quest_template.sql b/sql/updates/0.6/2713_quest_template.sql new file mode 100644 index 000000000..116632c83 --- /dev/null +++ b/sql/updates/0.6/2713_quest_template.sql @@ -0,0 +1,6 @@ +alter table quest_template + drop column detailsemote; +alter table quest_template + drop column completeemote; +alter table quest_template + drop column incompleteemote; \ No newline at end of file diff --git a/sql/updates/0.6/2746_command.sql b/sql/updates/0.6/2746_command.sql new file mode 100644 index 000000000..6946726f9 --- /dev/null +++ b/sql/updates/0.6/2746_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help` = 'Syntax: .npcflag #npcflag\r\n\r\nSet the NPC flags of creature template of the selected creature and selected creature to #npcflag. NPC flags will applied to all creatures of selected creature template after server restart or grid unload/load.' WHERE `name` = 'npcflag'; diff --git a/sql/updates/0.6/2746_creature.sql b/sql/updates/0.6/2746_creature.sql new file mode 100644 index 000000000..4304f728c --- /dev/null +++ b/sql/updates/0.6/2746_creature.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature` + DROP `npcflags`, + DROP `faction`; diff --git a/sql/updates/0.6/2754_realmd.sql b/sql/updates/0.6/2754_realmd.sql new file mode 100644 index 000000000..b7f6970a8 --- /dev/null +++ b/sql/updates/0.6/2754_realmd.sql @@ -0,0 +1 @@ +ALTER TABLE account CHANGE COLUMN `email` `email` varchar(255) NOT NULL default ''; diff --git a/sql/updates/0.6/2762_command.sql b/sql/updates/0.6/2762_command.sql new file mode 100644 index 000000000..99fe7f646 --- /dev/null +++ b/sql/updates/0.6/2762_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('addquest','3','Syntax: .addquest #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'); diff --git a/sql/updates/0.6/2765_auctionHouse.sql b/sql/updates/0.6/2765_auctionHouse.sql new file mode 100644 index 000000000..7b9b56ab0 --- /dev/null +++ b/sql/updates/0.6/2765_auctionHouse.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS `auctionhouse`; +CREATE TABLE `auctionhouse` ( + `id` bigint(20) unsigned NOT NULL default '0', + `auctioneerguid` int(32) NOT NULL default '0', + `itemguid` int(32) NOT NULL default '0', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `itemowner` int(32) NOT NULL default '0', + `buyoutprice` int(32) NOT NULL default '0', + `time` bigint(40) NOT NULL default '0', + `buyguid` int(32) NOT NULL default '0', + `lastbid` int(32) NOT NULL default '0', + `startbid` int(32) NOT NULL default '0', + `deposit` int(11) NOT NULL default '0', + `location` tinyint(3) unsigned NOT NULL default '3', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + diff --git a/sql/updates/0.6/2765_mail.sql b/sql/updates/0.6/2765_mail.sql new file mode 100644 index 000000000..78e6dbdde --- /dev/null +++ b/sql/updates/0.6/2765_mail.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS `mail`; +CREATE TABLE `mail` ( + `id` bigint(20) unsigned NOT NULL default '0' COMMENT 'Identifier', + `messageType` int(11) unsigned NOT NULL default '0', + `sender` bigint(20) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `receiver` bigint(20) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `subject` longtext, + `itemPageId` int(11) unsigned NOT NULL default '0', + `item_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Mail Item Global Unique Identifier', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `time` int(11) unsigned NOT NULL default '0', + `money` int(11) unsigned NOT NULL default '0', + `cod` bigint(11) unsigned NOT NULL default '0', + `checked` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + KEY `idx_receiver` (`receiver`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Mail System'; \ No newline at end of file diff --git a/sql/updates/0.6/2778_command.sql b/sql/updates/0.6/2778_command.sql new file mode 100644 index 000000000..d70b558d4 --- /dev/null +++ b/sql/updates/0.6/2778_command.sql @@ -0,0 +1,2 @@ +UPDATE `command` SET `help` = 'Syntax: .idleshutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players) or cancel the shutdown if cancel value is used.' WHERE `name` = 'idleshutdown'; +UPDATE `command` SET `help` = 'Syntax: .shutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds or cancel the shutdown if cancel value is used.' WHERE `name` = 'shutdown'; diff --git a/sql/updates/0.6/2787_item_instance.sql b/sql/updates/0.6/2787_item_instance.sql new file mode 100644 index 000000000..b6d97a87d --- /dev/null +++ b/sql/updates/0.6/2787_item_instance.sql @@ -0,0 +1,3 @@ +UPDATE `item_instance` + SET `data` = CONCAT(`data`,' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ') + WHERE SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',3),' ',-1) = 7 AND SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',91),' ',-1) = ''; diff --git a/sql/updates/0.6/2798_command.sql b/sql/updates/0.6/2798_command.sql new file mode 100644 index 000000000..03a7c16cd --- /dev/null +++ b/sql/updates/0.6/2798_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help` = 'Syntax: .levelup [$playername] [#numberoflevels]\r\n\r\nIncrease/decrease the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.' WHERE `name` = 'levelup'; diff --git a/sql/updates/0.6/2803_command.sql b/sql/updates/0.6/2803_command.sql new file mode 100644 index 000000000..6e36bcc40 --- /dev/null +++ b/sql/updates/0.6/2803_command.sql @@ -0,0 +1,11 @@ +DELETE FROM `command` WHERE `name` = 'setskill'; + +INSERT INTO command (name, security, help) VALUES ('setskill', 3,'Syntax: .setskill #skill #level [#max]\r\n\r\nSet a skill of id #skill with a current skill value of #level and a maximum value of #max (or equal current maximum if not provide) for the selected character. If no character is selected, you learn the skill.'); + +DELETE FROM `command` WHERE `name` = 'learnsk'; + +INSERT INTO command (name, security, help) VALUES ('learnskill', 3,'Syntax: .learnskill #skillId [#level [#max]]\r\n\r\nLearn a skill of id #skill with a current skill value of #level (or 1 if not provide) and a maximum value of #max (or equal #level or 1 if not provide) for the selected character. If no character is selected, you learn the skill.'); + +DELETE FROM `command` WHERE `name` = 'unlearnsk'; + +INSERT INTO command (name, security, help) VALUES ('unlearnskill',3,'Syntax: .unlearnskill #skill\r\n\r\nUnlearn a skill of id #skill for the selected character. If no character is selected, you unlearn the skill.'); diff --git a/sql/updates/0.6/2808_command.sql b/sql/updates/0.6/2808_command.sql new file mode 100644 index 000000000..48ea2fa40 --- /dev/null +++ b/sql/updates/0.6/2808_command.sql @@ -0,0 +1,2 @@ +DELETE FROM `command` WHERE `name` = 'password'; +INSERT INTO command (name, security, help) VALUES ('password', 0,'Syntax: .password $newpassword\r\n\r\nSet for your account $newpassword as new password.'); diff --git a/sql/updates/0.6/2812_character_pet.sql b/sql/updates/0.6/2812_character_pet.sql new file mode 100644 index 000000000..1881a7311 --- /dev/null +++ b/sql/updates/0.6/2812_character_pet.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_pet` + ADD `name` varchar(12) default 'Pet' AFTER `trainpoint`; diff --git a/sql/updates/0.6/2812_pet_name_generation.sql b/sql/updates/0.6/2812_pet_name_generation.sql new file mode 100644 index 000000000..8131cec00 --- /dev/null +++ b/sql/updates/0.6/2812_pet_name_generation.sql @@ -0,0 +1,211 @@ +DROP TABLE IF EXISTS `pet_name_generation`; +CREATE TABLE `pet_name_generation` ( + `id` int(11) NOT NULL auto_increment, + `word` tinytext NOT NULL, + `entry` int(11) NOT NULL default '0', + `half` int(11) NOT NULL default '0', + PRIMARY KEY (`id`) +); + +/*!40000 ALTER TABLE `pet_name_generation` DISABLE KEYS */; +LOCK TABLES `pet_name_generation` WRITE; +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Aba',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Az',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Bel',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Biz',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Cho',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Dag',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Gak',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Gar',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Gho',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Gob',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Gra',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Jak',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Jub',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Kar',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Laz',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Nal',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Nok',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Pag',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Pig',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Pip',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Piz',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Quz',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Rui',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Rul',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Rup',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Tar',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Vol',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Yaz',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zep',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zig',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zil',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zor',416,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('bis',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('gup',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('ham',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('jub',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('kin',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('kol',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('lop',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('loz',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('mat',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('mir',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nam',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nar',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nik',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nip',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('pad',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('pep',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('pit',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('qua',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('rai',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('rin',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('rot',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tai',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tal',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tik',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tip',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tog',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tuk',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('uri',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('yal',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('yap',416,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Bar',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Bel',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Char',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Grak\'',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Graz\'',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Grim',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Hath',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Hel',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Hok',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Jhaz',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Jhom',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Kal\'',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Klath',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Krag',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Krak',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Mak',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Mezz',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Orm',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Phan',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Sar',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Tang',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Than',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Thog',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Thok',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zang',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zhar\'',1860,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('doc',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('dok',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('garth',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('gore',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('gorg',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('grave',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('gron',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('juk',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('kath',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('kresh',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('krit',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('los',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('mon',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('mos',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('moth',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nagma',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nak',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nar',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nos',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nuz',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('phog',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('rath',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tast',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('taz',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('thak',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('thang',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('thyk',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('vhug',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('zazt',1860,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Ael',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Aez',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Ang',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Ban',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Bet',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Bro',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Bry',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Dir',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Dom',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Drus',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Fier',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Hel',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Kal',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Lyn',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Mir',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Nim',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Sar',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Sel',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Vil',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zah',1863,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('aith',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('anda',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('antia',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('lissa',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('neri',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('neth',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nia',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nva',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('ola',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('ona',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('ora',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('riana',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('riel',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tai',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('vina',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('wena',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('wyn',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('yla',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('yssa',1863,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Flaa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Fzuu',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Ghaa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Gree',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Haa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Jhaa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Jhuu',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Khaa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Khii',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Khuu',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Kree',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Maa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Nhee',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Phuu',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Pryy',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Sloo',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Sruu',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Traa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('Zhaa',417,0); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('dhon',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('dhum',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('don',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('dym',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('fun',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('ghon',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('ghun',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('grom',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('grym',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('jhom',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('kun',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('mmon',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('mon',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nam',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nem',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nhym',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('nom',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('phom',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('roon',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('tom',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('zhem',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('zhum',417,1); +INSERT INTO `pet_name_generation` (`word`, `entry`, `half`) VALUES ('zun',417,1); +UNLOCK TABLES; +/*!40000 ALTER TABLE `pet_name_generation` ENABLE KEYS */; diff --git a/sql/updates/0.6/2815_character_pet.sql b/sql/updates/0.6/2815_character_pet.sql new file mode 100644 index 000000000..db834b55f --- /dev/null +++ b/sql/updates/0.6/2815_character_pet.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_pet` + CHANGE COLUMN `name` `name` varchar(100) NULL DEFAULT 'Pet'; diff --git a/sql/updates/0.6/2821_raidgroups.sql b/sql/updates/0.6/2821_raidgroups.sql new file mode 100644 index 000000000..0507a17d2 --- /dev/null +++ b/sql/updates/0.6/2821_raidgroups.sql @@ -0,0 +1,24 @@ +DROP TABLE IF EXISTS `raidgroup`; +CREATE TABLE `raidgroup` ( + `leaderGuid` bigint(20) NOT NULL, + `lootMethod` int(11) NOT NULL, + `looterGuid` bigint(20) NOT NULL, + `icon1` bigint(20) NOT NULL, + `icon2` bigint(20) NOT NULL, + `icon3` bigint(20) NOT NULL, + `icon4` bigint(20) NOT NULL, + `icon5` bigint(20) NOT NULL, + `icon6` bigint(20) NOT NULL, + `icon7` bigint(20) NOT NULL, + `icon8` bigint(20) NOT NULL, + PRIMARY KEY (`leaderGuid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='RaidGroups'; + +DROP TABLE IF EXISTS `raidgroup_member`; +CREATE TABLE `raidgroup_member` ( + `leaderGuid` bigint(20) NOT NULL, + `memberGuid` bigint(20) NOT NULL, + `assistant` tinyint(1) NOT NULL, + `subgroup` smallint(6) NOT NULL, + PRIMARY KEY (`leaderGuid`,`memberGuid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='RaidGroups'; \ No newline at end of file diff --git a/sql/updates/0.6/2828_character.sql b/sql/updates/0.6/2828_character.sql new file mode 100644 index 000000000..434a8d5d3 --- /dev/null +++ b/sql/updates/0.6/2828_character.sql @@ -0,0 +1,27 @@ +ALTER TABLE `auctionhouse` ENGINE = InnoDB; +ALTER TABLE `character` DROP KEY `idx_name`, ENGINE = InnoDB; +ALTER TABLE `character_action` ENGINE = InnoDB; +ALTER TABLE `character_aura` ENGINE = InnoDB; +ALTER TABLE `character_homebind` ENGINE = InnoDB; +ALTER TABLE `character_inventory` ENGINE = InnoDB; +ALTER TABLE `character_kill` ENGINE = InnoDB; +ALTER TABLE `character_pet` ENGINE = InnoDB; +ALTER TABLE `character_queststatus` ENGINE = InnoDB; +ALTER TABLE `character_reputation` ENGINE = InnoDB; +ALTER TABLE `character_social` ENGINE = InnoDB; +ALTER TABLE `character_spell` ENGINE = InnoDB; +ALTER TABLE `character_spell_cooldown` ENGINE = InnoDB; +ALTER TABLE `character_stable` ENGINE = InnoDB; +ALTER TABLE `character_ticket` ENGINE = InnoDB; +ALTER TABLE `character_tutorial` ENGINE = InnoDB; +ALTER TABLE `corpse` ENGINE = InnoDB; +ALTER TABLE `guild` ENGINE = InnoDB; +ALTER TABLE `guild_charter` ENGINE = InnoDB; +ALTER TABLE `guild_charter_sign` ENGINE = InnoDB; +ALTER TABLE `guild_member` ENGINE = InnoDB; +ALTER TABLE `guild_rank` ENGINE = InnoDB; +ALTER TABLE `item_instance` ENGINE = InnoDB; +ALTER TABLE `item_page` ENGINE = InnoDB; +ALTER TABLE `mail` ENGINE = InnoDB; +ALTER TABLE `raidgroup` ENGINE = InnoDB; +ALTER TABLE `raidgroup_member` ENGINE = InnoDB; diff --git a/sql/updates/0.6/2838_corpse_grid.sql b/sql/updates/0.6/2838_corpse_grid.sql new file mode 100644 index 000000000..c7dee0d0d --- /dev/null +++ b/sql/updates/0.6/2838_corpse_grid.sql @@ -0,0 +1 @@ +ALTER TABLE `corpse_grid` ENGINE = MEMORY; diff --git a/sql/updates/0.6/2838_creature_grid.sql b/sql/updates/0.6/2838_creature_grid.sql new file mode 100644 index 000000000..381934e5b --- /dev/null +++ b/sql/updates/0.6/2838_creature_grid.sql @@ -0,0 +1 @@ +ALTER TABLE `creature_grid` ENGINE = MEMORY; diff --git a/sql/updates/0.6/2838_gameobject_grid.sql b/sql/updates/0.6/2838_gameobject_grid.sql new file mode 100644 index 000000000..099f1e567 --- /dev/null +++ b/sql/updates/0.6/2838_gameobject_grid.sql @@ -0,0 +1 @@ +ALTER TABLE `gameobject_grid` ENGINE = MEMORY; diff --git a/sql/updates/0.6/2842_character_pet.sql b/sql/updates/0.6/2842_character_pet.sql new file mode 100644 index 000000000..f30604900 --- /dev/null +++ b/sql/updates/0.6/2842_character_pet.sql @@ -0,0 +1,10 @@ +ALTER TABLE `character_pet` + ADD COLUMN `modelid` int(11) unsigned default '0' after `owner`; + +UPDATE `character_pet`,`creature_template` + SET `character_pet`.`modelid` = `creature_template`.`modelid_m` + WHERE `character_pet`.`modelid` = 0 AND `character_pet`.`entry` = `creature_template`.`entry`; + +UPDATE `character_pet`,`creature_template` + SET `character_pet`.`modelid` = `creature_template`.`modelid_f` + WHERE `character_pet`.`modelid` = 0 AND `character_pet`.`entry` = `creature_template`.`entry`; diff --git a/sql/updates/0.6/2843_character_pet.sql b/sql/updates/0.6/2843_character_pet.sql new file mode 100644 index 000000000..9202f337f --- /dev/null +++ b/sql/updates/0.6/2843_character_pet.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_pet` + ADD COLUMN `renamed` tinyint(1) unsigned NOT NULL default '0' after `name`; diff --git a/sql/updates/0.6/2850_command.sql b/sql/updates/0.6/2850_command.sql new file mode 100644 index 000000000..1b6f152ed --- /dev/null +++ b/sql/updates/0.6/2850_command.sql @@ -0,0 +1,5 @@ +UPDATE `command` SET `help` = 'Syntax:\r\n.modify speed #rate\r\n.speed #rate\r\n\r\nModify the running speed of the selected player to "normal base run speed"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.' WHERE `name` = 'speed'; +UPDATE `command` SET `help` = 'Syntax:\r\n.modify speed #rate\r\n.speed #rate\r\n\r\nModify the running speed of the selected player to "normal base run speed"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.' WHERE `name` = 'modify speed'; +UPDATE `command` SET `help` = 'Syntax: .modify swim #rate\r\n\r\nModify the swim speed of the selected player to "normal swim speed"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.' WHERE `name` = 'modify swim'; +UPDATE `command` SET `help` = 'Syntax: .modify aspeed #rate\r\n\r\nModify all speeds -run,swim,run back,swim back- of the selected player to "normalbase speed for this move type"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.' WHERE `name` = 'modify aspeed'; +UPDATE `command` SET `help` = 'Syntax: .modify bwalk #rate\r\n\r\nModify the speed of the selected player while running backwards to "normal walk back speed"*rate. If no player is selected, modify your speed.\r\n\r\n #speed may range from 0.1 to 10.' WHERE `name` = 'modify bwalk'; diff --git a/sql/updates/0.6/2869_command.sql b/sql/updates/0.6/2869_command.sql new file mode 100644 index 000000000..5cc6ff5d0 --- /dev/null +++ b/sql/updates/0.6/2869_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help` = 'Syntax: .pinfo [$player_name] [rep]\r\n\r\nOutput account information for selected player or player find by $player_name. If "rep" parameter provided show reputation information for player.' WHERE `name` = 'pinfo'; diff --git a/sql/updates/0.6/2875_npc_trainer.sql b/sql/updates/0.6/2875_npc_trainer.sql new file mode 100644 index 000000000..ed90471d1 --- /dev/null +++ b/sql/updates/0.6/2875_npc_trainer.sql @@ -0,0 +1,2 @@ +ALTER TABLE `npc_trainer` + DROP `reqspell`; diff --git a/sql/updates/0.6/2875_spell_chain.sql b/sql/updates/0.6/2875_spell_chain.sql new file mode 100644 index 000000000..0535fd5e4 --- /dev/null +++ b/sql/updates/0.6/2875_spell_chain.sql @@ -0,0 +1,1359 @@ +-- ---------------------------- +-- Table structure for spell_chain +-- ---------------------------- +DROP TABLE IF EXISTS `spell_chain`; +CREATE TABLE `spell_chain` ( + `spell_id` int(5) NOT NULL default '0', + `prev_spell` int(5) NOT NULL default '0', + `first_spell` int(5) NOT NULL default '0', + `rank` int(2) NOT NULL default '0', + PRIMARY KEY (`spell_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell Additinal Data'; + +-- ---------------------------- +-- Records (Proff. spells) +-- ---------------------------- +INSERT INTO `spell_chain` VALUES +('8613', '0', '8613', '1'), +('8617', '8613', '8613', '2'), +('8618', '8617', '8613', '3'), +('10768', '8618', '8613', '4'), + +('4036', '0', '4036', '1'), +('4037', '4036', '4036', '2'), +('4038', '4037', '4036', '3'), +('12656', '4038', '4036', '4'), + +('2259', '0', '2259', '1'), +('3101', '2259', '2259', '2'), +('3464', '3101', '2259', '3'), +('11611', '3464', '2259', '4'), + +('7411', '0', '7411', '1'), +('7412', '7411', '7411', '2'), +('7413', '7412', '7411', '3'), +('13920', '7413', '7411', '4'), + +('3908', '0', '3908', '1'), +('3909', '3908', '3908', '2'), +('3910', '3909', '3908', '3'), +('12180', '3910', '3908', '4'), + +('2108', '0', '2108', '1'), +('3104', '2108', '2108', '2'), +('3811', '3104', '2108', '3'), +('10662', '3811', '2108', '4'), + +('7620', '0', '7620', '1'), +('7731', '7620', '7620', '2'), +('7732', '7731', '7620', '3'), +('18248', '7732', '7620', '4'), + +('2575', '0', '2575', '1'), +('2576', '2575', '2575', '2'), +('3564', '2576', '2575', '3'), +('10248', '3564', '2575', '4'), + +('3273', '0', '3273', '1'), +('3274', '3273', '3273', '2'), +('7924', '3274', '3273', '3'), +('10846', '7924', '3273', '4'), + +('2018', '0', '2018', '1'), +('3100', '2018', '2018', '2'), +('3538', '3100', '2018', '3'), +('9785', '3538', '2018', '4'), +('9787', '9785', '2018', '5'), +('9788', '9785', '2018', '5'), + +('1804', '0', '1804', '1'), +('6461', '1804', '1804', '2'), +('6463', '6461', '1804', '3'), + +('2550', '0', '2550', '1'), +('3102', '2550', '2550', '2'), +('3413', '3102', '2550', '3'), +('18260', '3413', '2550', '4'), + +('2366', '0', '2366', '1'), +('2368', '2366', '2366', '2'), +('3570', '2368', '2366', '3'), +('11993', '3570', '2366', '4'), + +('33388', '0', '33388', '1'), +('33391', '33388', '33388', '2'); + +-- ---------------------------- +-- Records (Ranked spells) +-- ---------------------------- +INSERT INTO `spell_chain` VALUES ('10', '0', '10', '1'), +('17', '0', '17', '1'), +('53', '0', '53', '1'), +('72', '0', '72', '1'), +('78', '0', '78', '1'), +('99', '0', '99', '1'), +('100', '0', '100', '1'), +('116', '0', '116', '1'), +('118', '0', '118', '1'), +('120', '0', '120', '1'), +('122', '0', '122', '1'), +('133', '0', '133', '1'), +('136', '0', '136', '1'), +('139', '0', '139', '1'), +('143', '133', '133', '2'), +('145', '143', '133', '3'), +('168', '0', '168', '1'), +('172', '0', '172', '1'), +('205', '116', '116', '2'), +('284', '78', '78', '2'), +('285', '284', '78', '3'), +('324', '0', '324', '1'), +('325', '324', '324', '2'), +('331', '0', '331', '1'), +('332', '331', '331', '2'), +('339', '0', '339', '1'), +('348', '0', '348', '1'), +('370', '0', '370', '1'), +('403', '0', '403', '1'), +('408', '0', '408', '1'), +('421', '0', '421', '1'), +('453', '0', '453', '1'), +('465', '0', '465', '1'), +('467', '0', '467', '1'), +('469', '0', '469', '1'), +('498', '0', '498', '1'), +('527', '0', '527', '1'), +('529', '403', '403', '2'), +('543', '0', '543', '1'), +('547', '332', '331', '3'), +('548', '529', '403', '3'), +('585', '0', '585', '1'), +('586', '0', '586', '1'), +('587', '0', '587', '1'), +('588', '0', '588', '1'), +('589', '0', '589', '1'), +('591', '585', '585', '2'), +('592', '17', '17', '2'), +('594', '589', '589', '2'), +('596', '0', '596', '1'), +('597', '587', '587', '2'), +('598', '591', '585', '3'), +('600', '592', '17', '3'), +('602', '7128', '588', '3'), +('603', '0', '603', '1'), +('604', '0', '604', '1'), +('605', '0', '605', '1'), +('633', '0', '633', '1'), +('635', '0', '635', '1'), +('639', '635', '635', '2'), +('642', '0', '642', '1'), +('643', '10290', '465', '3'), +('647', '639', '635', '3'), +('686', '0', '686', '1'), +('687', '0', '687', '1'), +('688', '0', '688', '1'), +('689', '0', '689', '1'), +('693', '0', '693', '1'), +('694', '0', '694', '1'), +('695', '686', '686', '2'), +('696', '687', '687', '2'), +('699', '689', '689', '2'), +('702', '0', '702', '1'), +('703', '0', '703', '1'), +('704', '0', '704', '1'), +('705', '695', '686', '3'), +('706', '0', '706', '1'), +('707', '348', '348', '2'), +('709', '699', '689', '3'), +('710', '0', '710', '1'), +('724', '0', '724', '1'), +('740', '0', '740', '1'), +('755', '0', '755', '1'), +('769', '780', '779', '3'), +('770', '0', '770', '1'), +('772', '0', '772', '1'), +('774', '0', '774', '1'), +('778', '770', '770', '2'), +('779', '0', '779', '1'), +('780', '779', '779', '2'), +('781', '0', '781', '1'), +('782', '467', '467', '2'), +('837', '205', '116', '3'), +('845', '0', '845', '1'), +('853', '0', '853', '1'), +('865', '122', '122', '2'), +('879', '0', '879', '1'), +('905', '325', '324', '3'), +('913', '547', '331', '4'), +('915', '548', '403', '4'), +('930', '421', '421', '2'), +('939', '913', '331', '5'), +('943', '915', '403', '5'), +('945', '905', '324', '4'), +('959', '939', '331', '6'), +('970', '594', '589', '3'), +('974', '0', '974', '1'), +('976', '0', '976', '1'), +('980', '0', '980', '1'), +('984', '598', '585', '4'), +('988', '527', '527', '2'), +('990', '597', '587', '3'), +('992', '970', '589', '4'), +('996', '596', '596', '2'), +('1004', '984', '585', '5'), +('1006', '602', '588', '4'), +('1008', '0', '1008', '1'), +('1014', '980', '980', '2'), +('1020', '642', '642', '2'), +('1022', '0', '1022', '1'), +('1026', '647', '635', '4'), +('1032', '10291', '465', '5'), +('1042', '1026', '635', '5'), +('1058', '774', '774', '2'), +('1062', '339', '339', '2'), +('1064', '0', '1064', '1'), +('1075', '782', '467', '3'), +('1079', '0', '1079', '1'), +('1082', '0', '1082', '1'), +('1086', '706', '706', '2'), +('1088', '705', '686', '4'), +('1094', '707', '348', '3'), +('1098', '0', '1098', '1'), +('1106', '1088', '686', '5'), +('1108', '702', '702', '2'), +('1120', '0', '1120', '1'), +('1126', '0', '1126', '1'), +('1130', '0', '1130', '1'), +('1160', '0', '1160', '1'), +('1243', '0', '1243', '1'), +('1244', '1243', '1243', '2'), +('1245', '1244', '1243', '3'), +('1329', '0', '1329', '1'), +('1430', '1058', '774', '3'), +('1449', '0', '1449', '1'), +('1454', '0', '1454', '1'), +('1455', '1454', '1454', '2'), +('1456', '1455', '1454', '3'), +('1459', '0', '1459', '1'), +('1460', '1459', '1459', '2'), +('1461', '1460', '1459', '3'), +('1463', '0', '1463', '1'), +('1464', '0', '1464', '1'), +('1490', '0', '1490', '1'), +('1495', '0', '1495', '1'), +('1499', '0', '1499', '1'), +('1510', '0', '1510', '1'), +('1513', '0', '1513', '1'), +('1535', '0', '1535', '1'), +('1608', '285', '78', '4'), +('1671', '72', '72', '2'), +('1672', '1671', '72', '3'), +('1714', '0', '1714', '1'), +('1715', '0', '1715', '1'), +('1735', '99', '99', '2'), +('1752', '0', '1752', '1'), +('1757', '1752', '1752', '2'), +('1758', '1757', '1752', '3'), +('1759', '1758', '1752', '4'), +('1760', '1759', '1752', '5'), +('1766', '0', '1766', '1'), +('1767', '1766', '1766', '2'), +('1768', '1767', '1766', '3'), +('1769', '1768', '1766', '4'), +('1776', '0', '1776', '1'), +('1777', '1776', '1776', '2'), +('1784', '0', '1784', '1'), +('1785', '1784', '1784', '2'), +('1786', '1785', '1784', '3'), +('1787', '1786', '1784', '4'), +('1822', '0', '1822', '1'), +('1823', '1822', '1822', '2'), +('1824', '1823', '1822', '3'), +('1850', '0', '1850', '1'), +('1856', '0', '1856', '1'), +('1857', '1856', '1856', '2'), +('1943', '0', '1943', '1'), +('1949', '0', '1949', '1'), +('1966', '0', '1966', '1'), +('1978', '0', '1978', '1'), +('2006', '0', '2006', '1'), +('2008', '0', '2008', '1'), +('2010', '2006', '2006', '2'), +('2048', '25289', '6673', '8'), +('2050', '0', '2050', '1'), +('2052', '2050', '2050', '2'), +('2053', '2052', '2050', '3'), +('2054', '0', '2054', '1'), +('2055', '2054', '2054', '2'), +('2060', '0', '2060', '1'), +('2061', '0', '2061', '1'), +('2062', '0', '2062', '1'), +('2070', '6770', '6770', '2'), +('2090', '1430', '774', '4'), +('2091', '2090', '774', '5'), +('2096', '0', '2096', '1'), +('2098', '0', '2098', '1'), +('2120', '0', '2120', '1'), +('2121', '2120', '2120', '2'), +('2136', '0', '2136', '1'), +('2137', '2136', '2136', '2'), +('2138', '2137', '2136', '3'), +('2362', '0', '2362', '1'), +('2589', '53', '53', '2'), +('2590', '2589', '53', '3'), +('2591', '2590', '53', '4'), +('2637', '0', '2637', '1'), +('2643', '0', '2643', '1'), +('2651', '0', '2651', '1'), +('2652', '0', '2652', '1'), +('2767', '992', '589', '5'), +('2791', '1245', '1243', '4'), +('2800', '633', '633', '2'), +('2812', '0', '2812', '1'), +('2825', '0', '2825', '1'), +('2835', '0', '2835', '1'), +('2837', '2835', '2835', '2'), +('2860', '930', '421', '3'), +('2878', '0', '2878', '1'), +('2894', '0', '2894', '1'), +('2908', '0', '2908', '1'), +('2912', '0', '2912', '1'), +('2941', '1094', '348', '4'), +('2944', '0', '2944', '1'), +('2948', '0', '2948', '1'), +('2973', '0', '2973', '1'), +('2974', '0', '2974', '1'), +('2983', '0', '2983', '1'), +('3029', '1082', '1082', '2'), +('3034', '0', '3034', '1'), +('3044', '0', '3044', '1'), +('3111', '136', '136', '2'), +('3140', '145', '133', '4'), +('3420', '0', '3420', '1'), +('3421', '3420', '3420', '2'), +('3472', '1042', '635', '6'), +('3599', '0', '3599', '1'), +('3627', '2091', '774', '6'), +('3661', '3111', '136', '3'), +('3662', '3661', '136', '4'), +('3698', '755', '755', '2'), +('3699', '3698', '755', '3'), +('3700', '3699', '755', '4'), +('3738', '0', '3738', '1'), +('3747', '600', '17', '4'), +('5138', '0', '5138', '1'), +('5143', '0', '5143', '1'), +('5144', '5143', '5143', '2'), +('5145', '5144', '5143', '3'), +('5159', '1062', '339', '3'), +('5171', '0', '5171', '1'), +('5176', '0', '5176', '1'), +('5177', '5176', '5176', '2'), +('5178', '5177', '5176', '3'), +('5179', '5178', '5176', '4'), +('5180', '5179', '5176', '5'), +('5185', '0', '5185', '1'), +('5186', '5185', '5185', '2'), +('5187', '5186', '5185', '3'), +('5188', '5187', '5185', '4'), +('5189', '5188', '5185', '5'), +('5196', '5159', '339', '4'), +('5201', '3029', '1082', '3'), +('5211', '0', '5211', '1'), +('5215', '0', '5215', '1'), +('5217', '0', '5217', '1'), +('5221', '0', '5221', '1'), +('5232', '1126', '1126', '2'), +('5234', '6756', '1126', '4'), +('5242', '6673', '6673', '2'), +('5277', '0', '5277', '1'), +('5308', '0', '5308', '1'), +('5394', '0', '5394', '1'), +('5484', '0', '5484', '1'), +('5504', '0', '5504', '1'), +('5505', '5504', '5504', '2'), +('5506', '5505', '5504', '3'), +('5570', '0', '5570', '1'), +('5573', '498', '498', '2'), +('5588', '853', '853', '2'), +('5589', '5588', '853', '3'), +('5599', '1022', '1022', '2'), +('5614', '879', '879', '2'), +('5615', '5614', '879', '3'), +('5627', '2878', '2878', '2'), +('5675', '0', '5675', '1'), +('5676', '0', '5676', '1'), +('5699', '6202', '6201', '3'), +('5730', '0', '5730', '1'), +('5740', '0', '5740', '1'), +('5763', '0', '5763', '1'), +('5782', '0', '5782', '1'), +('5938', '0', '5938', '1'), +('6041', '943', '403', '6'), +('6060', '1004', '585', '6'), +('6063', '2055', '2054', '3'), +('6064', '6063', '2054', '4'), +('6065', '3747', '17', '5'), +('6066', '6065', '17', '6'), +('6074', '139', '139', '2'), +('6075', '6074', '139', '3'), +('6076', '6075', '139', '4'), +('6077', '6076', '139', '5'), +('6078', '6077', '139', '6'), +('6117', '0', '6117', '1'), +('6127', '5506', '5504', '4'), +('6129', '990', '587', '4'), +('6131', '865', '122', '3'), +('6141', '10', '10', '2'), +('6143', '0', '6143', '1'), +('6178', '100', '100', '2'), +('6190', '1160', '1160', '2'), +('6192', '5242', '6673', '3'), +('6201', '0', '6201', '1'), +('6202', '6201', '6201', '2'), +('6205', '1108', '702', '3'), +('6213', '5782', '5782', '2'), +('6215', '6213', '5782', '3'), +('6217', '1014', '980', '3'), +('6219', '5740', '5740', '2'), +('6222', '172', '172', '2'), +('6223', '6222', '172', '3'), +('6226', '5138', '5138', '2'), +('6229', '0', '6229', '1'), +('6343', '0', '6343', '1'), +('6353', '0', '6353', '1'), +('6363', '3599', '3599', '2'), +('6364', '6363', '3599', '3'), +('6365', '6364', '3599', '4'), +('6366', '0', '6366', '1'), +('6375', '5394', '5394', '2'), +('6377', '6375', '5394', '3'), +('6390', '5730', '5730', '2'), +('6391', '6390', '5730', '3'), +('6392', '6391', '5730', '4'), +('6542', '0', '6542', '1'), +('6546', '772', '772', '2'), +('6547', '6546', '772', '3'), +('6548', '6547', '772', '4'), +('6552', '0', '6552', '1'), +('6554', '6552', '6552', '2'), +('6572', '0', '6572', '1'), +('6574', '6572', '6572', '2'), +('6673', '0', '6673', '1'), +('6756', '5232', '1126', '3'), +('6760', '2098', '2098', '2'), +('6761', '6760', '2098', '3'), +('6762', '6761', '2098', '4'), +('6768', '1966', '1966', '2'), +('6770', '0', '6770', '1'), +('6774', '5171', '5171', '2'), +('6778', '5189', '5185', '6'), +('6780', '5180', '5176', '6'), +('6783', '5215', '5215', '2'), +('6785', '0', '6785', '1'), +('6787', '6785', '6785', '2'), +('6789', '0', '6789', '1'), +('6793', '5217', '5217', '2'), +('6798', '5211', '5211', '2'), +('6800', '5221', '5221', '2'), +('6807', '0', '6807', '1'), +('6808', '6807', '6807', '2'), +('6809', '6808', '6807', '3'), +('6940', '0', '6940', '1'), +('7128', '588', '588', '2'), +('7294', '0', '7294', '1'), +('7300', '168', '168', '2'), +('7301', '7300', '168', '3'), +('7302', '0', '7302', '1'), +('7320', '7302', '7302', '2'), +('7322', '837', '116', '4'), +('7328', '0', '7328', '1'), +('7369', '845', '845', '2'), +('7372', '1715', '1715', '2'), +('7373', '7372', '1715', '3'), +('7379', '6574', '6572', '3'), +('7384', '0', '7384', '1'), +('7386', '0', '7386', '1'), +('7400', '694', '694', '2'), +('7402', '7400', '694', '3'), +('7405', '7386', '7386', '2'), +('7641', '1106', '686', '6'), +('7646', '6205', '702', '4'), +('7648', '6223', '172', '4'), +('7651', '709', '689', '4'), +('7658', '704', '704', '2'), +('7659', '7658', '704', '3'), +('7887', '7384', '7384', '2'), +('8004', '0', '8004', '1'), +('8005', '959', '331', '7'), +('8008', '8004', '8004', '2'), +('8010', '8008', '8004', '3'), +('8012', '370', '370', '2'), +('8017', '0', '8017', '1'), +('8018', '8017', '8017', '2'), +('8019', '8018', '8017', '3'), +('8024', '0', '8024', '1'), +('8027', '8024', '8024', '2'), +('8030', '8027', '8024', '3'), +('8033', '0', '8033', '1'), +('8038', '8033', '8033', '2'), +('8042', '0', '8042', '1'), +('8044', '8042', '8042', '2'), +('8045', '8044', '8042', '3'), +('8046', '8045', '8042', '4'), +('8050', '0', '8050', '1'), +('8052', '8050', '8050', '2'), +('8053', '8052', '8050', '3'), +('8056', '0', '8056', '1'), +('8058', '8056', '8056', '2'), +('8071', '0', '8071', '1'), +('8075', '0', '8075', '1'), +('8092', '0', '8092', '1'), +('8102', '8092', '8092', '2'), +('8103', '8102', '8092', '3'), +('8104', '8103', '8092', '4'), +('8105', '8104', '8092', '5'), +('8106', '8105', '8092', '6'), +('8122', '0', '8122', '1'), +('8124', '8122', '8122', '2'), +('8129', '0', '8129', '1'), +('8131', '8129', '8129', '2'), +('8134', '945', '324', '5'), +('8154', '8071', '8071', '2'), +('8155', '8154', '8071', '3'), +('8160', '8075', '8075', '2'), +('8161', '8160', '8075', '3'), +('8181', '0', '8181', '1'), +('8184', '0', '8184', '1'), +('8190', '0', '8190', '1'), +('8192', '453', '453', '2'), +('8198', '6343', '6343', '2'), +('8204', '8198', '6343', '3'), +('8205', '8204', '6343', '4'), +('8227', '0', '8227', '1'), +('8232', '0', '8232', '1'), +('8235', '8232', '8232', '2'), +('8249', '8227', '8227', '2'), +('8288', '1120', '1120', '2'), +('8289', '8288', '1120', '3'), +('8380', '7405', '7386', '3'), +('8400', '3140', '133', '5'), +('8401', '8400', '133', '6'), +('8402', '8401', '133', '7'), +('8406', '7322', '116', '5'), +('8407', '8406', '116', '6'), +('8408', '8407', '116', '7'), +('8412', '2138', '2136', '4'), +('8413', '8412', '2136', '5'), +('8416', '5145', '5143', '4'), +('8417', '8416', '5143', '5'), +('8422', '2121', '2120', '3'), +('8423', '8422', '2120', '4'), +('8427', '6141', '10', '3'), +('8437', '1449', '1449', '2'), +('8438', '8437', '1449', '3'), +('8439', '8438', '1449', '4'), +('8444', '2948', '2948', '2'), +('8445', '8444', '2948', '3'), +('8446', '8445', '2948', '4'), +('8450', '604', '604', '2'), +('8451', '8450', '604', '3'), +('8455', '1008', '1008', '2'), +('8457', '543', '543', '2'), +('8458', '8457', '543', '3'), +('8461', '6143', '6143', '2'), +('8462', '8461', '6143', '3'), +('8492', '120', '120', '2'), +('8494', '1463', '1463', '2'), +('8495', '8494', '1463', '3'), +('8498', '1535', '1535', '2'), +('8499', '8498', '1535', '3'), +('8512', '0', '8512', '1'), +('8621', '1760', '1752', '6'), +('8623', '6762', '2098', '5'), +('8624', '8623', '2098', '6'), +('8629', '1777', '1776', '3'), +('8631', '703', '703', '2'), +('8632', '8631', '703', '3'), +('8633', '8632', '703', '4'), +('8637', '6768', '1966', '3'), +('8639', '1943', '1943', '2'), +('8640', '8639', '1943', '3'), +('8643', '408', '408', '2'), +('8647', '0', '8647', '1'), +('8649', '8647', '8647', '2'), +('8650', '8649', '8647', '3'), +('8676', '0', '8676', '1'), +('8681', '0', '8681', '1'), +('8687', '8681', '8681', '2'), +('8691', '8687', '8681', '3'), +('8694', '5763', '5763', '2'), +('8696', '2983', '2983', '2'), +('8721', '2591', '53', '5'), +('8724', '8676', '8676', '2'), +('8725', '8724', '8676', '3'), +('8820', '1464', '1464', '2'), +('8835', '0', '8835', '1'), +('8903', '6778', '5185', '7'), +('8905', '6780', '5176', '7'), +('8907', '5234', '1126', '5'), +('8910', '3627', '774', '7'), +('8914', '1075', '467', '4'), +('8918', '740', '740', '2'), +('8921', '0', '8921', '1'), +('8924', '8921', '8921', '2'), +('8925', '8924', '8921', '3'), +('8926', '8925', '8921', '4'), +('8927', '8926', '8921', '5'), +('8928', '8927', '8921', '6'), +('8929', '8928', '8921', '7'), +('8936', '0', '8936', '1'), +('8938', '8936', '8936', '2'), +('8939', '8938', '8936', '3'), +('8940', '8939', '8936', '4'), +('8941', '8940', '8936', '5'), +('8949', '2912', '2912', '2'), +('8950', '8949', '2912', '3'), +('8951', '8950', '2912', '4'), +('8955', '2908', '2908', '2'), +('8972', '6809', '6807', '4'), +('8983', '6798', '5211', '3'), +('8992', '6800', '5221', '3'), +('8998', '0', '8998', '1'), +('9000', '8998', '8998', '2'), +('9005', '0', '9005', '1'), +('9035', '0', '9035', '1'), +('9472', '2061', '2061', '2'), +('9473', '9472', '2061', '3'), +('9474', '9473', '2061', '4'), +('9484', '0', '9484', '1'), +('9485', '9484', '9484', '2'), +('9490', '1735', '99', '3'), +('9492', '1079', '1079', '2'), +('9493', '9492', '1079', '3'), +('9578', '586', '586', '2'), +('9579', '9578', '586', '3'), +('9592', '9579', '586', '4'), +('9745', '8972', '6807', '5'), +('9747', '9490', '99', '4'), +('9749', '778', '770', '3'), +('9750', '8941', '8936', '6'), +('9752', '9493', '1079', '4'), +('9754', '769', '779', '4'), +('9756', '8914', '467', '5'), +('9758', '8903', '5185', '8'), +('9821', '1850', '1850', '2'), +('9823', '9005', '9005', '2'), +('9827', '9823', '9005', '3'), +('9829', '8992', '5221', '4'), +('9830', '9829', '5221', '5'), +('9833', '8929', '8921', '8'), +('9834', '9833', '8921', '9'), +('9835', '9834', '8921', '10'), +('9839', '8910', '774', '8'), +('9840', '9839', '774', '9'), +('9841', '9840', '774', '10'), +('9845', '6793', '5217', '3'), +('9846', '9845', '5217', '4'), +('9849', '5201', '1082', '4'), +('9850', '9849', '1082', '5'), +('9852', '5196', '339', '5'), +('9853', '9852', '339', '6'), +('9856', '9750', '8936', '7'), +('9857', '9856', '8936', '8'), +('9858', '9857', '8936', '9'), +('9862', '8918', '740', '3'), +('9863', '9862', '740', '4'), +('9866', '6787', '6785', '3'), +('9867', '9866', '6785', '4'), +('9875', '8951', '2912', '5'), +('9876', '9875', '2912', '6'), +('9880', '9745', '6807', '6'), +('9881', '9880', '6807', '7'), +('9884', '8907', '1126', '6'), +('9885', '9884', '1126', '7'), +('9888', '9758', '5185', '9'), +('9889', '9888', '5185', '10'), +('9892', '9000', '8998', '3'), +('9894', '9752', '1079', '5'), +('9896', '9894', '1079', '6'), +('9898', '9747', '99', '5'), +('9901', '8955', '2908', '3'), +('9904', '1824', '1822', '4'), +('9907', '9749', '770', '4'), +('9908', '9754', '779', '5'), +('9910', '9756', '467', '6'), +('9912', '8905', '5176', '8'), +('9913', '6783', '5215', '3'), +('10138', '6127', '5504', '5'), +('10139', '10138', '5504', '6'), +('10140', '10139', '5504', '7'), +('10144', '6129', '587', '5'), +('10145', '10144', '587', '6'), +('10148', '8402', '133', '8'), +('10149', '10148', '133', '9'), +('10150', '10149', '133', '10'), +('10151', '10150', '133', '11'), +('10156', '1461', '1459', '4'), +('10157', '10156', '1459', '5'), +('10159', '8492', '120', '3'), +('10160', '10159', '120', '4'), +('10161', '10160', '120', '5'), +('10169', '8455', '1008', '3'), +('10170', '10169', '1008', '4'), +('10173', '8451', '604', '4'), +('10174', '10173', '604', '5'), +('10177', '8462', '6143', '4'), +('10179', '8408', '116', '8'), +('10180', '10179', '116', '9'), +('10181', '10180', '116', '10'), +('10185', '8427', '10', '4'), +('10186', '10185', '10', '5'), +('10187', '10186', '10', '6'), +('10191', '8495', '1463', '4'), +('10192', '10191', '1463', '5'), +('10193', '10192', '1463', '6'), +('10197', '8413', '2136', '6'), +('10199', '10197', '2136', '7'), +('10201', '8439', '1449', '5'), +('10202', '10201', '1449', '6'), +('10205', '8446', '2948', '5'), +('10206', '10205', '2948', '6'), +('10207', '10206', '2948', '7'), +('10211', '8417', '5143', '6'), +('10212', '10211', '5143', '7'), +('10215', '8423', '2120', '5'), +('10216', '10215', '2120', '6'), +('10219', '7320', '7302', '3'), +('10220', '10219', '7302', '4'), +('10223', '8458', '543', '4'), +('10225', '10223', '543', '5'), +('10230', '6131', '122', '4'), +('10278', '5599', '1022', '3'), +('10290', '465', '465', '2'), +('10291', '643', '465', '4'), +('10292', '1032', '465', '6'), +('10293', '10292', '465', '7'), +('10298', '7294', '7294', '2'), +('10299', '10298', '7294', '3'), +('10300', '10299', '7294', '4'), +('10301', '10300', '7294', '5'), +('10308', '5589', '853', '4'), +('10310', '2800', '633', '3'), +('10312', '5615', '879', '4'), +('10313', '10312', '879', '5'), +('10314', '10313', '879', '6'), +('10318', '2812', '2812', '2'), +('10322', '7328', '7328', '2'), +('10324', '10322', '7328', '3'), +('10326', '5627', '2878', '3'), +('10328', '3472', '635', '7'), +('10329', '10328', '635', '8'), +('10391', '6041', '403', '7'), +('10392', '10391', '403', '8'), +('10395', '8005', '331', '8'), +('10396', '10395', '331', '9'), +('10399', '8019', '8017', '4'), +('10406', '8155', '8071', '4'), +('10407', '10406', '8071', '5'), +('10408', '10407', '8071', '6'), +('10412', '8046', '8042', '5'), +('10413', '10412', '8042', '6'), +('10414', '10413', '8042', '7'), +('10427', '6392', '5730', '5'), +('10428', '10427', '5730', '6'), +('10431', '8134', '324', '6'), +('10432', '10431', '324', '7'), +('10437', '6365', '3599', '5'), +('10438', '10437', '3599', '6'), +('10442', '8161', '8075', '4'), +('10447', '8053', '8050', '4'), +('10448', '10447', '8050', '5'), +('10456', '8038', '8033', '3'), +('10462', '6377', '5394', '4'), +('10463', '10462', '5394', '5'), +('10466', '8010', '8004', '4'), +('10467', '10466', '8004', '5'), +('10468', '10467', '8004', '6'), +('10472', '8058', '8056', '3'), +('10473', '10472', '8056', '4'), +('10478', '8181', '8181', '2'), +('10479', '10478', '8181', '3'), +('10486', '8235', '8232', '3'), +('10495', '5675', '5675', '2'), +('10496', '10495', '5675', '3'), +('10497', '10496', '5675', '4'), +('10526', '8249', '8227', '3'), +('10537', '8184', '8184', '2'), +('10538', '10537', '8184', '3'), +('10585', '8190', '8190', '2'), +('10586', '10585', '8190', '3'), +('10587', '10586', '8190', '4'), +('10595', '0', '10595', '1'), +('10600', '10595', '10595', '2'), +('10601', '10600', '10595', '3'), +('10605', '2860', '421', '4'), +('10613', '8512', '8512', '2'), +('10614', '10613', '8512', '3'), +('10622', '1064', '1064', '2'), +('10623', '10622', '1064', '3'), +('10627', '8835', '8835', '2'), +('10797', '0', '10797', '1'), +('10874', '8131', '8129', '3'), +('10875', '10874', '8129', '4'), +('10876', '10875', '8129', '5'), +('10880', '2010', '2006', '3'), +('10881', '10880', '2006', '4'), +('10888', '8124', '8122', '3'), +('10890', '10888', '8122', '4'), +('10892', '2767', '589', '6'), +('10893', '10892', '589', '7'), +('10894', '10893', '589', '8'), +('10898', '6066', '17', '7'), +('10899', '10898', '17', '8'), +('10900', '10899', '17', '9'), +('10901', '10900', '17', '10'), +('10909', '2096', '2096', '2'), +('10911', '605', '605', '2'), +('10912', '10911', '605', '3'), +('10915', '9474', '2061', '5'), +('10916', '10915', '2061', '6'), +('10917', '10916', '2061', '7'), +('10927', '6078', '139', '7'), +('10928', '10927', '139', '8'), +('10929', '10928', '139', '9'), +('10933', '6060', '585', '7'), +('10934', '10933', '585', '8'), +('10937', '2791', '1243', '5'), +('10938', '10937', '1243', '6'), +('10941', '9592', '586', '5'), +('10942', '10941', '586', '6'), +('10945', '8106', '8092', '7'), +('10946', '10945', '8092', '8'), +('10947', '10946', '8092', '9'), +('10951', '1006', '588', '5'), +('10952', '10951', '588', '6'), +('10953', '8192', '453', '3'), +('10955', '9485', '9484', '3'), +('10957', '976', '976', '2'), +('10958', '10957', '976', '3'), +('10960', '996', '596', '3'), +('10961', '10960', '596', '4'), +('10963', '2060', '2060', '2'), +('10964', '10963', '2060', '3'), +('10965', '10964', '2060', '4'), +('11113', '0', '11113', '1'), +('11197', '8650', '8647', '4'), +('11198', '11197', '8647', '5'), +('11267', '8725', '8676', '4'), +('11268', '11267', '8676', '5'), +('11269', '11268', '8676', '6'), +('11273', '8640', '1943', '4'), +('11274', '11273', '1943', '5'), +('11275', '11274', '1943', '6'), +('11279', '8721', '53', '6'), +('11280', '11279', '53', '7'), +('11281', '11280', '53', '8'), +('11285', '8629', '1776', '4'), +('11286', '11285', '1776', '5'), +('11289', '8633', '703', '5'), +('11290', '11289', '703', '6'), +('11293', '8621', '1752', '7'), +('11294', '11293', '1752', '8'), +('11297', '2070', '6770', '3'), +('11299', '8624', '2098', '7'), +('11300', '11299', '2098', '8'), +('11303', '8637', '1966', '4'), +('11305', '8696', '2983', '3'), +('11314', '8499', '1535', '4'), +('11315', '11314', '1535', '5'), +('11341', '8691', '8681', '4'), +('11342', '11341', '8681', '5'), +('11343', '11342', '8681', '6'), +('11357', '2837', '2835', '3'), +('11358', '11357', '2835', '4'), +('11366', '0', '11366', '1'), +('11400', '8694', '5763', '3'), +('11426', '0', '11426', '1'), +('11549', '6192', '6673', '4'), +('11550', '11549', '6673', '5'), +('11551', '11550', '6673', '6'), +('11554', '6190', '1160', '3'), +('11555', '11554', '1160', '4'), +('11556', '11555', '1160', '5'), +('11564', '1608', '78', '5'), +('11565', '11564', '78', '6'), +('11566', '11565', '78', '7'), +('11567', '11566', '78', '8'), +('11572', '6548', '772', '5'), +('11573', '11572', '772', '6'), +('11574', '11573', '772', '7'), +('11578', '6178', '100', '3'), +('11580', '8205', '6343', '5'), +('11581', '11580', '6343', '6'), +('11584', '7887', '7384', '3'), +('11585', '11584', '7384', '4'), +('11596', '8380', '7386', '4'), +('11597', '11596', '7386', '5'), +('11600', '7379', '6572', '4'), +('11601', '11600', '6572', '5'), +('11604', '8820', '1464', '3'), +('11605', '11604', '1464', '4'), +('11608', '7369', '845', '3'), +('11609', '11608', '845', '4'), +('11659', '7641', '686', '7'), +('11660', '11659', '686', '8'), +('11661', '11660', '686', '9'), +('11665', '2941', '348', '5'), +('11667', '11665', '348', '6'), +('11668', '11667', '348', '7'), +('11671', '7648', '172', '5'), +('11672', '11671', '172', '6'), +('11675', '8289', '1120', '4'), +('11677', '6219', '5740', '3'), +('11678', '11677', '5740', '4'), +('11683', '1949', '1949', '2'), +('11684', '11683', '1949', '3'), +('11687', '1456', '1454', '4'), +('11688', '11687', '1454', '5'), +('11689', '11688', '1454', '6'), +('11693', '3700', '755', '5'), +('11694', '11693', '755', '6'), +('11695', '11694', '755', '7'), +('11699', '7651', '689', '5'), +('11700', '11699', '689', '6'), +('11703', '6226', '5138', '3'), +('11704', '11703', '5138', '4'), +('11707', '7646', '702', '5'), +('11708', '11707', '702', '6'), +('11711', '6217', '980', '4'), +('11712', '11711', '980', '5'), +('11713', '11712', '980', '6'), +('11717', '7659', '704', '4'), +('11719', '1714', '1714', '2'), +('11721', '1490', '1490', '2'), +('11722', '11721', '1490', '3'), +('11725', '1098', '1098', '2'), +('11726', '11725', '1098', '3'), +('11729', '5699', '6201', '4'), +('11730', '11729', '6201', '5'), +('11733', '1086', '706', '3'), +('11734', '11733', '706', '4'), +('11735', '11734', '706', '5'), +('11739', '6229', '6229', '2'), +('11740', '11739', '6229', '3'), +('12294', '0', '12294', '1'), +('12505', '11366', '11366', '2'), +('12522', '12505', '11366', '3'), +('12523', '12522', '11366', '4'), +('12524', '12523', '11366', '5'), +('12525', '12524', '11366', '6'), +('12526', '12525', '11366', '7'), +('12824', '118', '118', '2'), +('12825', '12824', '118', '3'), +('12826', '12825', '118', '4'), +('13018', '11113', '11113', '2'), +('13019', '13018', '11113', '3'), +('13020', '13019', '11113', '4'), +('13021', '13020', '11113', '5'), +('13031', '11426', '11426', '2'), +('13032', '13031', '11426', '3'), +('13033', '13032', '11426', '4'), +('13165', '0', '13165', '1'), +('13220', '0', '13220', '1'), +('13228', '13220', '13220', '2'), +('13229', '13228', '13220', '3'), +('13230', '13229', '13220', '4'), +('13542', '3662', '136', '5'), +('13543', '13542', '136', '6'), +('13544', '13543', '136', '7'), +('13549', '1978', '1978', '2'), +('13550', '13549', '1978', '3'), +('13551', '13550', '1978', '4'), +('13552', '13551', '1978', '5'), +('13553', '13552', '1978', '6'), +('13554', '13553', '1978', '7'), +('13555', '13554', '1978', '8'), +('13795', '0', '13795', '1'), +('13813', '0', '13813', '1'), +('13896', '0', '13896', '1'), +('13908', '0', '13908', '1'), +('14260', '2973', '2973', '2'), +('14261', '14260', '2973', '3'), +('14262', '14261', '2973', '4'), +('14263', '14262', '2973', '5'), +('14264', '14263', '2973', '6'), +('14265', '14264', '2973', '7'), +('14266', '14265', '2973', '8'), +('14267', '2974', '2974', '2'), +('14268', '14267', '2974', '3'), +('14269', '1495', '1495', '2'), +('14270', '14269', '1495', '3'), +('14271', '14270', '1495', '4'), +('14272', '781', '781', '2'), +('14273', '14272', '781', '3'), +('14274', '20736', '20736', '2'), +('14279', '3034', '3034', '2'), +('14280', '14279', '3034', '3'), +('14281', '3044', '3044', '2'), +('14282', '14281', '3044', '3'), +('14283', '14282', '3044', '4'), +('14284', '14283', '3044', '5'), +('14285', '14284', '3044', '6'), +('14286', '14285', '3044', '7'), +('14287', '14286', '3044', '8'), +('14288', '2643', '2643', '2'), +('14289', '14288', '2643', '3'), +('14290', '14289', '2643', '4'), +('14294', '1510', '1510', '2'), +('14295', '14294', '1510', '3'), +('14302', '13795', '13795', '2'), +('14303', '14302', '13795', '3'), +('14304', '14303', '13795', '4'), +('14305', '14304', '13795', '5'), +('14310', '1499', '1499', '2'), +('14311', '14310', '1499', '3'), +('14316', '13813', '13813', '2'), +('14317', '14316', '13813', '3'), +('14318', '13165', '13165', '2'), +('14319', '14318', '13165', '3'), +('14320', '14319', '13165', '4'), +('14321', '14320', '13165', '5'), +('14322', '14321', '13165', '6'), +('14323', '1130', '1130', '2'), +('14324', '14323', '1130', '3'), +('14325', '14324', '1130', '4'), +('14326', '1513', '1513', '2'), +('14327', '14326', '1513', '3'), +('14752', '0', '14752', '1'), +('14818', '14752', '14752', '2'), +('14819', '14818', '14752', '3'), +('14914', '0', '14914', '1'), +('15107', '0', '15107', '1'), +('15111', '15107', '15107', '2'), +('15112', '15111', '15107', '3'), +('15207', '10392', '403', '9'), +('15208', '15207', '403', '10'), +('15237', '0', '15237', '1'), +('15261', '15267', '14914', '8'), +('15262', '14914', '14914', '2'), +('15263', '15262', '14914', '3'), +('15264', '15263', '14914', '4'), +('15265', '15264', '14914', '5'), +('15266', '15265', '14914', '6'), +('15267', '15266', '14914', '7'), +('15407', '0', '15407', '1'), +('15430', '15237', '15237', '2'), +('15431', '15430', '15237', '3'), +('15629', '14274', '20736', '3'), +('15630', '15629', '20736', '4'), +('15631', '15630', '20736', '5'), +('15632', '15631', '20736', '6'), +('16314', '10399', '8017', '5'), +('16315', '16314', '8017', '6'), +('16316', '16315', '8017', '7'), +('16339', '8030', '8024', '4'), +('16341', '16339', '8024', '5'), +('16342', '16341', '8024', '6'), +('16355', '10456', '8033', '4'), +('16356', '16355', '8033', '5'), +('16362', '10486', '8232', '4'), +('16387', '10526', '8227', '4'), +('16511', '0', '16511', '1'), +('16689', '0', '16689', '1'), +('16810', '16689', '16689', '2'), +('16811', '16810', '16689', '3'), +('16812', '16811', '16689', '4'), +('16813', '16812', '16689', '5'), +('16857', '0', '16857', '1'), +('16914', '0', '16914', '1'), +('17311', '15407', '15407', '2'), +('17312', '17311', '15407', '3'), +('17313', '17312', '15407', '4'), +('17314', '17313', '15407', '5'), +('17329', '16813', '16689', '6'), +('17347', '16511', '16511', '2'), +('17348', '17347', '16511', '3'), +('17390', '16857', '16857', '2'), +('17391', '17390', '16857', '3'), +('17392', '17391', '16857', '4'), +('17401', '16914', '16914', '2'), +('17402', '17401', '16914', '3'), +('17727', '2362', '2362', '2'), +('17728', '17727', '2362', '3'), +('17862', '0', '17862', '1'), +('17877', '0', '17877', '1'), +('17919', '5676', '5676', '2'), +('17920', '17919', '5676', '3'), +('17921', '17920', '5676', '4'), +('17922', '17921', '5676', '5'), +('17923', '17922', '5676', '6'), +('17924', '6353', '6353', '2'), +('17925', '6789', '6789', '2'), +('17926', '17925', '6789', '3'), +('17928', '5484', '5484', '2'), +('17937', '17862', '17862', '2'), +('17951', '6366', '6366', '2'), +('17952', '17951', '6366', '3'), +('17953', '17952', '6366', '4'), +('17962', '0', '17962', '1'), +('18137', '0', '18137', '1'), +('18220', '0', '18220', '1'), +('18265', '0', '18265', '1'), +('18647', '710', '710', '2'), +('18657', '2637', '2637', '2'), +('18658', '18657', '2637', '3'), +('18807', '17314', '15407', '6'), +('18809', '12526', '11366', '8'), +('18867', '17877', '17877', '2'), +('18868', '18867', '17877', '3'), +('18869', '18868', '17877', '4'), +('18870', '18869', '17877', '5'), +('18871', '18870', '17877', '6'), +('18879', '18265', '18265', '2'), +('18880', '18879', '18265', '3'), +('18881', '18880', '18265', '4'), +('18930', '17962', '17962', '2'), +('18931', '18930', '17962', '3'), +('18932', '18931', '17962', '4'), +('18937', '18220', '18220', '2'), +('18938', '18937', '18220', '3'), +('19236', '13908', '13908', '2'), +('19238', '19236', '13908', '3'), +('19240', '19238', '13908', '4'), +('19241', '19240', '13908', '5'), +('19242', '19241', '13908', '6'), +('19243', '19242', '13908', '7'), +('19261', '2652', '2652', '2'), +('19262', '19261', '2652', '3'), +('19264', '19262', '2652', '4'), +('19265', '19264', '2652', '5'), +('19266', '19265', '2652', '6'), +('19271', '13896', '13896', '2'), +('19273', '19271', '13896', '3'), +('19274', '19273', '13896', '4'), +('19275', '19274', '13896', '5'), +('19276', '2944', '2944', '2'), +('19277', '19276', '2944', '3'), +('19278', '19277', '2944', '4'), +('19279', '19278', '2944', '5'), +('19280', '19279', '2944', '6'), +('19281', '9035', '9035', '2'), +('19282', '19281', '9035', '3'), +('19283', '19282', '9035', '4'), +('19284', '19283', '9035', '5'), +('19285', '19284', '9035', '6'), +('19289', '2651', '2651', '2'), +('19291', '19289', '2651', '3'), +('19292', '19291', '2651', '4'), +('19293', '19292', '2651', '5'), +('19296', '10797', '10797', '2'), +('19299', '19296', '10797', '3'), +('19302', '19299', '10797', '4'), +('19303', '19302', '10797', '5'), +('19304', '19303', '10797', '6'), +('19305', '19304', '10797', '7'), +('19306', '0', '19306', '1'), +('19308', '18137', '18137', '2'), +('19309', '19308', '18137', '3'), +('19310', '19309', '18137', '4'), +('19311', '19310', '18137', '5'), +('19312', '19311', '18137', '6'), +('19386', '0', '19386', '1'), +('19434', '0', '19434', '1'), +('19506', '0', '19506', '1'), +('19740', '0', '19740', '1'), +('19742', '0', '19742', '1'), +('19750', '0', '19750', '1'), +('19834', '19740', '19740', '2'), +('19835', '19834', '19740', '3'), +('19836', '19835', '19740', '4'), +('19837', '19836', '19740', '5'), +('19838', '19837', '19740', '6'), +('19850', '19742', '19742', '2'), +('19852', '19850', '19742', '3'), +('19853', '19852', '19742', '4'), +('19854', '19853', '19742', '5'), +('19876', '0', '19876', '1'), +('19888', '0', '19888', '1'), +('19891', '0', '19891', '1'), +('19895', '19876', '19876', '2'), +('19896', '19895', '19876', '3'), +('19897', '19888', '19888', '2'), +('19898', '19897', '19888', '3'), +('19899', '19891', '19891', '2'), +('19900', '19899', '19891', '3'), +('19939', '19750', '19750', '2'), +('19940', '19939', '19750', '3'), +('19941', '19940', '19750', '4'), +('19942', '19941', '19750', '5'), +('19943', '19942', '19750', '6'), +('19977', '0', '19977', '1'), +('19978', '19977', '19977', '2'), +('19979', '19978', '19977', '3'), +('20043', '0', '20043', '1'), +('20116', '26573', '26573', '2'), +('20162', '21082', '21082', '2'), +('20164', '0', '20164', '1'), +('20165', '0', '20165', '1'), +('20166', '0', '20166', '1'), +('20190', '20043', '20043', '2'), +('20243', '0', '20243', '1'), +('20252', '0', '20252', '1'), +('20287', '21084', '21084', '2'), +('20288', '20287', '21084', '3'), +('20289', '20288', '21084', '4'), +('20290', '20289', '21084', '5'), +('20291', '20290', '21084', '6'), +('20292', '20291', '21084', '7'), +('20293', '20292', '21084', '8'), +('20305', '20162', '21082', '3'), +('20306', '20305', '21082', '4'), +('20307', '20306', '21082', '5'), +('20308', '20307', '21082', '6'), +('20347', '20165', '20165', '2'), +('20348', '20347', '20165', '3'), +('20349', '20348', '20165', '4'), +('20356', '20166', '20166', '2'), +('20357', '20356', '20166', '3'), +('20375', '0', '20375', '1'), +('20473', '0', '20473', '1'), +('20484', '0', '20484', '1'), +('20559', '7402', '694', '4'), +('20560', '20559', '694', '5'), +('20569', '11609', '845', '5'), +('20609', '2008', '2008', '2'), +('20610', '20609', '2008', '3'), +('20616', '20252', '20252', '2'), +('20617', '20616', '20252', '3'), +('20658', '5308', '5308', '2'), +('20660', '20658', '5308', '3'), +('20661', '20660', '5308', '4'), +('20662', '20661', '5308', '5'), +('20729', '6940', '6940', '2'), +('20736', '0', '20736', '1'), +('20739', '20484', '20484', '2'), +('20742', '20739', '20484', '3'), +('20747', '20742', '20484', '4'), +('20748', '20747', '20484', '5'), +('20752', '693', '693', '2'), +('20755', '20752', '693', '3'), +('20756', '20755', '693', '4'), +('20757', '20756', '693', '5'), +('20770', '10881', '2006', '5'), +('20772', '10324', '7328', '4'), +('20773', '20772', '7328', '5'), +('20776', '20610', '2008', '4'), +('20777', '20776', '2008', '5'), +('20900', '19434', '19434', '2'), +('20901', '20900', '19434', '3'), +('20902', '20901', '19434', '4'), +('20903', '20902', '19434', '5'), +('20904', '20903', '19434', '6'), +('20905', '19506', '19506', '2'), +('20906', '20905', '19506', '3'), +('20909', '19306', '19306', '2'), +('20910', '20909', '19306', '3'), +('20911', '0', '20911', '1'), +('20912', '20911', '20911', '2'), +('20913', '20912', '20911', '3'), +('20914', '20913', '20911', '4'), +('20915', '20375', '20375', '2'), +('20918', '20915', '20375', '3'), +('20919', '20918', '20375', '4'), +('20920', '20919', '20375', '5'), +('20922', '20116', '26573', '3'), +('20923', '20922', '26573', '4'), +('20924', '20923', '26573', '5'), +('20925', '0', '20925', '1'), +('20927', '20925', '20925', '2'), +('20928', '20927', '20925', '3'), +('20929', '20473', '20473', '2'), +('20930', '20929', '20473', '3'), +('21082', '0', '21082', '1'), +('21084', '0', '21084', '1'), +('21551', '12294', '12294', '2'), +('21552', '21551', '12294', '3'), +('21553', '21552', '12294', '4'), +('21562', '0', '21562', '1'), +('21564', '21562', '21562', '2'), +('21849', '0', '21849', '1'), +('21850', '21849', '21849', '2'), +('22568', '0', '22568', '1'), +('22782', '6117', '6117', '2'), +('22783', '22782', '6117', '3'), +('22827', '22568', '22568', '2'), +('22828', '22827', '22568', '3'), +('22829', '22828', '22568', '4'), +('22842', '0', '22842', '1'), +('22895', '22842', '22842', '2'), +('22896', '22895', '22842', '3'), +('23028', '0', '23028', '1'), +('23881', '0', '23881', '1'), +('23892', '23881', '23881', '2'), +('23893', '23892', '23881', '3'), +('23894', '23893', '23881', '4'), +('23922', '0', '23922', '1'), +('23923', '23922', '23922', '2'), +('23924', '23923', '23922', '3'), +('23925', '23924', '23922', '4'), +('24132', '19386', '19386', '2'), +('24133', '24132', '19386', '3'), +('24224', '0', '24224', '1'), +('24239', '24274', '24275', '3'), +('24248', '31018', '22568', '6'), +('24274', '24275', '24275', '2'), +('24275', '0', '24275', '1'), +('24398', '0', '24398', '1'), +('24974', '5570', '5570', '2'), +('24975', '24974', '5570', '3'), +('24976', '24975', '5570', '4'), +('24977', '24976', '5570', '5'), +('25286', '11567', '78', '9'), +('25288', '11601', '6572', '6'), +('25289', '11551', '6673', '7'), +('25290', '19854', '19742', '6'), +('25291', '19838', '19740', '7'), +('25292', '10329', '635', '9'), +('25294', '14290', '2643', '5'), +('25295', '13555', '1978', '9'), +('25296', '14322', '13165', '7'), +('25297', '9889', '5185', '11'), +('25298', '9876', '2912', '7'), +('25299', '9841', '774', '11'), +('25300', '11281', '53', '9'), +('25302', '11303', '1966', '5'), +('25304', '10181', '116', '11'), +('25306', '10151', '133', '12'), +('25307', '11661', '686', '10'), +('25309', '11668', '348', '8'), +('25311', '11672', '172', '7'), +('25314', '10965', '2060', '5'), +('25315', '10929', '139', '10'), +('25316', '10961', '596', '5'), +('25345', '10212', '5143', '8'), +('25347', '11358', '2835', '5'), +('25357', '10396', '331', '10'), +('25359', '10627', '8835', '3'), +('25361', '10442', '8075', '5'), +('25782', '0', '25782', '1'), +('25890', '0', '25890', '1'), +('25894', '0', '25894', '1'), +('25899', '0', '25899', '1'), +('25916', '25782', '25782', '2'), +('25918', '25894', '25894', '2'), +('26573', '0', '26573', '1'), +('27681', '0', '27681', '1'), +('27683', '0', '27683', '1'), +('27799', '15431', '15237', '4'), +('27800', '27799', '15237', '5'), +('27801', '27800', '15237', '6'), +('27841', '14819', '14752', '4'), +('27870', '724', '724', '2'), +('27871', '27870', '724', '3'), +('28609', '10177', '6143', '5'), +('28610', '11740', '6229', '4'), +('28612', '10145', '587', '7'), +('29228', '10448', '8050', '6'), +('31016', '11300', '2098', '9'), +('31018', '22829', '22568', '5'); diff --git a/sql/updates/0.6/2881_spell_chain.sql b/sql/updates/0.6/2881_spell_chain.sql new file mode 100644 index 000000000..215708c0a --- /dev/null +++ b/sql/updates/0.6/2881_spell_chain.sql @@ -0,0 +1,7 @@ +-- ---------------------------- +-- Records (Proff. spells) +-- ---------------------------- +INSERT INTO `spell_chain` VALUES +('10660', '10662', '2108', '5'), +('10658', '10662', '2108', '5'), +('10656', '10662', '2108', '5'); diff --git a/sql/updates/0.6/2885_character.sql b/sql/updates/0.6/2885_character.sql new file mode 100644 index 000000000..c5e63e73e --- /dev/null +++ b/sql/updates/0.6/2885_character.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character` + DROP `realm`; diff --git a/sql/updates/0.6/2912_areatrigger_template.sql b/sql/updates/0.6/2912_areatrigger_template.sql new file mode 100644 index 000000000..e28b86389 --- /dev/null +++ b/sql/updates/0.6/2912_areatrigger_template.sql @@ -0,0 +1 @@ +ALTER TABLE `areatrigger_template` ADD `required_level` SMALLINT NOT NULL DEFAULT '0' AFTER `name` ; \ No newline at end of file diff --git a/sql/updates/0.6/2916_character.sql b/sql/updates/0.6/2916_character.sql new file mode 100644 index 000000000..e1b36178b --- /dev/null +++ b/sql/updates/0.6/2916_character.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character` + ADD `gmstate` tinyint(3) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/2938_spell_scripts.sql b/sql/updates/0.6/2938_spell_scripts.sql new file mode 100644 index 000000000..d4c376b1c --- /dev/null +++ b/sql/updates/0.6/2938_spell_scripts.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS `spell_scripts`; +CREATE TABLE `spell_scripts` ( + `id` int(11) unsigned NOT NULL default '0', + `delay` int(11) unsigned NOT NULL default '0', + `command` int(11) unsigned NOT NULL default '0', + `datalong` int(11) unsigned NOT NULL default '0', + `datalong2` int(11) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +); diff --git a/sql/updates/0.6/2940_playercreateinfo_skill.sql b/sql/updates/0.6/2940_playercreateinfo_skill.sql new file mode 100644 index 000000000..fc403eede --- /dev/null +++ b/sql/updates/0.6/2940_playercreateinfo_skill.sql @@ -0,0 +1 @@ +DELETE FROM `playercreateinfo_skill` WHERE `Skill` = 633; diff --git a/sql/updates/0.6/2958_command.sql b/sql/updates/0.6/2958_command.sql new file mode 100644 index 000000000..5ed78bac0 --- /dev/null +++ b/sql/updates/0.6/2958_command.sql @@ -0,0 +1,2 @@ +DELETE FROM `command` WHERE `name` = 'lockaccount'; +INSERT INTO command (name, security, help) VALUES ('lockaccount', 0,'Syntax: .lockaccount [on|off]\r\n\r\nAllow login from account only from current used IP or remove this requirement.'); diff --git a/sql/updates/0.6/2958_scripts.sql b/sql/updates/0.6/2958_scripts.sql new file mode 100644 index 000000000..c0cf92433 --- /dev/null +++ b/sql/updates/0.6/2958_scripts.sql @@ -0,0 +1,2 @@ +ALTER TABLE `scripts` + CHANGE COLUMN `datatext` `datatext` text NOT NULL; diff --git a/sql/updates/0.6/2958_spell_scripts.sql b/sql/updates/0.6/2958_spell_scripts.sql new file mode 100644 index 000000000..2a36c43a9 --- /dev/null +++ b/sql/updates/0.6/2958_spell_scripts.sql @@ -0,0 +1,2 @@ +ALTER TABLE `spell_scripts` + CHANGE COLUMN `datatext` `datatext` text NOT NULL; diff --git a/sql/updates/0.6/2982_command.sql b/sql/updates/0.6/2982_command.sql new file mode 100644 index 000000000..8a4b8fbd4 --- /dev/null +++ b/sql/updates/0.6/2982_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help` = 'Syntax: .additem #itemid/[#itemname]/#shift-click-item-link #itemcount\r\n\r\nAdds the specified number of items of id #itemid (or exact (!) name $itemname in brackets, or link created by shift-click at item in inventory or recipe) to your or selected character inventory. If #itemcount is omitted, only one item will be added.\r\n.' WHERE `name` = 'additem'; diff --git a/sql/updates/0.6/2993_command.sql b/sql/updates/0.6/2993_command.sql new file mode 100644 index 000000000..3b184b492 --- /dev/null +++ b/sql/updates/0.6/2993_command.sql @@ -0,0 +1,20 @@ +delete from command where `name` = 'shuttdown'; +delete from command where `name` = 'cshuttdown'; +delete from command where `name` = 'shutdown'; +delete from command where `name` = 'cshutdown'; +insert into command values('shutdown','3','Syntax: .shutdown seconds'); +insert into command values('cshutdown','3','Syntax: .cshutdown Cancels shuttdown'); + +UPDATE `command` SET `help` = 'Syntax: .goobject #object_guid\r\nTeleport your character to gameobject with guid #object_guid' WHERE `name` = 'goobject'; +UPDATE `command` SET `help` = 'Syntax: .targetobject [#go_id|#go_name_part]\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.' WHERE `name` = 'targetobject'; +UPDATE `command` SET `help` = 'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter. A GM can use .learn all if he wants to learn all default spells for Game Masters, .learn all_lang to learn all languages, and .learn all_myclass to learn all spells available for his class (Character selection in these cases ignored).' WHERE `name` = 'learn'; +UPDATE `command` SET `help` = 'Syntax: .taxicheat #flag\r\n\r\nTemporary grant access or remove to all taxi routes for the selected character. If no character is selected, hide or reveal all routes to you.\r\n\r\nUse a #flag of value 1 to add access, use a #flag value of 0 to remove access. Visited taxi nodes sill accessible after removing access.' WHERE `name` = 'taxicheat'; +UPDATE `command` SET `help` = 'Syntax: .visible [0||1]\r\n\r\nOutput current visibility state or make GM visible(1) and invisible(0) for other players.' WHERE `name` = 'visible'; +UPDATE `command` SET `help` = 'Syntax: .moveobject #goguid [#x #y #z]\r\n\r\nMove gameobject #goguid to character coordinates (or to (#x,#y,#z) coordinates if its provide).' WHERE `name` = 'moveobject'; +UPDATE `command` SET `help` = 'Syntax: .playsound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...' WHERE `name` = 'playsound'; +UPDATE `command` SET `help` = 'Syntax:\r\n.reset level\r\n Reset level to 1 including reset stats and talents. Equipped items with greater level requirement can be lost.\r\n.reset spells\r\n Removes all non-original spells from spellbook.\r\n.reset stats\r\n Resets(recalculate) all stats of the targeted player to their original values at current level.\r\n.reset talents\r\n Removes all talents of the targeted player.' WHERE `name` = 'reset'; +UPDATE `command` SET `help` = 'Syntax: .unbanip #ip\r\n\r\nUnban provide IP address.' WHERE `name` = 'unbanip'; +UPDATE `command` SET `help` = 'Syntax: .kick [$charactername]\r\n\r\nKick the given character from the world. If no character name provide then selected player (except self) will be kicked.' WHERE `name` = 'kick'; +UPDATE `command` SET `help` = 'Syntax: .levelup [$playername] [#numberoflevels]\r\n\r\nIncrease/decrease the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.' WHERE `name` = 'levelup'; +UPDATE `command` SET `help` = 'Syntax: .setskill #skill #level [#max]\r\n\r\nSet a skill of id #skill with a current skill value of #level and a maximum value of #max (or equal current maximum if not provide) for the selected character. If no character is selected, you learn the skill.' WHERE `name` = 'setskill'; +UPDATE `command` SET `help` = 'Syntax: .learnskill #skillId [#level [#max]]\r\n\r\nLearn a skill of id #skill with a current skill value of #level (or 1 if not provide) and a maximum value of #max (or equal #level or 1 if not provide) for the selected character. If no character is selected, you learn the skill.' WHERE `name` = 'learnskill'; diff --git a/sql/updates/0.6/3005.sql b/sql/updates/0.6/3005.sql new file mode 100644 index 000000000..55ae8f4a8 --- /dev/null +++ b/sql/updates/0.6/3005.sql @@ -0,0 +1,166 @@ + +ALTER TABLE `auctionhouse` MODIFY COLUMN `id` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `auctionhouse` MODIFY COLUMN `auctioneerguid` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `auctionhouse` MODIFY COLUMN `itemguid` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `auctionhouse` MODIFY COLUMN `buyoutprice` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `auctionhouse` MODIFY COLUMN `buyguid` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `auctionhouse` MODIFY COLUMN `lastbid` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `auctionhouse` MODIFY COLUMN `startbid` int(11) NOT NULL DEFAULT '0'; + +ALTER TABLE `character` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character` MODIFY COLUMN `account` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Account Identifier'; +ALTER TABLE `character` MODIFY COLUMN `is_logout_resting` tinyint(3) NOT NULL DEFAULT '0'; + +ALTER TABLE `character_action` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character_action` MODIFY COLUMN `button` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `character_action` MODIFY COLUMN `action` smallint(5) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `character_action` MODIFY COLUMN `type` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `character_action` MODIFY COLUMN `misc` tinyint(3) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `character_aura` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `character_homebind` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `character_inventory` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character_inventory` MODIFY COLUMN `bag` int(11) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `character_inventory` MODIFY COLUMN `item` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Item Global Unique Identifier'; + +ALTER TABLE `character_kill` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character_kill` MODIFY COLUMN `type` tinyint(3) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `character_queststatus` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `character_reputation` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `character_social` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character_social` MODIFY COLUMN `friend` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Character Global Unique Identifier'; + +ALTER TABLE `character_spell` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character_spell` MODIFY COLUMN `active` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `character_ticket` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `character_tutorial` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut0` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut1` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut2` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut3` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut4` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut5` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut6` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character_tutorial` MODIFY COLUMN `tut7` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `command` MODIFY COLUMN `name` varchar(50) NOT NULL default ''; +ALTER TABLE `command` MODIFY COLUMN `security` tinyint(3) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `corpse` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; +ALTER TABLE `corpse` MODIFY COLUMN `player` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Character Global Unique Identifier'; + +ALTER TABLE `corpse_grid` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `creature` MODIFY COLUMN `guid` int(11) unsigned NOT NULL auto_increment COMMENT 'Global Unique Identifier'; +ALTER TABLE `creature` MODIFY COLUMN `state` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature` MODIFY COLUMN `MovementType` tinyint(3) unsigned NOT NULL DEFAULT '0'; + + +ALTER TABLE `creature_grid` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `creature_loot_template` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `creature_loot_template` MODIFY COLUMN `quest_freeforall` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `creature_template` MODIFY COLUMN `minlevel` tinyint(3) unsigned DEFAULT '1'; +ALTER TABLE `creature_template` MODIFY COLUMN `maxlevel` tinyint(3) unsigned DEFAULT '1'; +ALTER TABLE `creature_template` MODIFY COLUMN `rank` tinyint(3) unsigned DEFAULT '0'; +ALTER TABLE `creature_template` MODIFY COLUMN `trainer_type` tinyint(3) DEFAULT '0'; +ALTER TABLE `creature_template` MODIFY COLUMN `class` tinyint(3) unsigned DEFAULT '0'; +ALTER TABLE `creature_template` MODIFY COLUMN `race` tinyint(3) unsigned DEFAULT '0'; + +ALTER TABLE `creature_template` MODIFY COLUMN `rangedattackpower` smallint(5) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` MODIFY COLUMN `type` tinyint(3) unsigned DEFAULT '0'; +ALTER TABLE `creature_template` MODIFY COLUMN `civilian` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` MODIFY COLUMN `MovementType` tinyint(3) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `fishing_loot_template` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `fishing_loot_template` MODIFY COLUMN `quest_freeforall` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `gameobject` MODIFY COLUMN `guid` int(11) unsigned NOT NULL auto_increment COMMENT 'Global Unique Identifier'; + +ALTER TABLE `gameobject_grid` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier'; + +ALTER TABLE `gameobject_loot_template` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `gameobject_loot_template` MODIFY COLUMN `quest_freeforall` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `item_instance` MODIFY COLUMN `guid` int(11) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_instance` ADD COLUMN `owner_guid` int(11) unsigned NOT NULL DEFAULT '0' AFTER `guid`; + + +UPDATE `item_instance` + SET `owner_guid` = SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',7),' ',-1); + +ALTER TABLE `item_loot_template` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `item_loot_template` MODIFY COLUMN `quest_freeforall` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `item_template` MODIFY COLUMN `class` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `subclass` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `displayid` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `item_template` MODIFY COLUMN `Quality` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `InventoryType` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `AllowableClass` mediumint(9) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `RequiredLevel` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `maxcount` smallint(5) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stackable` smallint(5) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `ContainerSlots` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type1` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value1` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type2` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value2` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type3` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value3` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type4` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value4` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type5` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value5` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type6` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value6` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type7` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value7` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type8` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value8` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type9` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value9` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_type10` tinyint(4) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `stat_value10` smallint(6) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `dmg_type1` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `dmg_type2` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `dmg_type3` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `dmg_type4` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `dmg_type5` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` MODIFY COLUMN `bonding` tinyint(3) unsigned NOT NULL DEFAULT '0'; + + +ALTER TABLE `mail` MODIFY COLUMN `id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Identifier'; +ALTER TABLE `mail` MODIFY COLUMN `messageType` tinyint(3) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `mail` MODIFY COLUMN `sender` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Character Global Unique Identifier'; +ALTER TABLE `mail` MODIFY COLUMN `receiver` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Character Global Unique Identifier'; +ALTER TABLE `mail` MODIFY COLUMN `item_guid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Mail Item Global Unique Identifier'; +ALTER TABLE `mail` MODIFY COLUMN `cod` int(11) unsigned NOT NULL DEFAULT '0'; + +DROP TABLE IF EXISTS `npc_spirithealer`; +DELETE FROM `command` WHERE `name` = 'addspirit'; +DELETE FROM `command` WHERE `name` = 'addsh'; + +ALTER TABLE `npc_vendor` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `pickpocketing_loot_template` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `pickpocketing_loot_template` MODIFY COLUMN `quest_freeforall` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `raidgroup` MODIFY COLUMN `leaderGuid` int(11) NOT NULL; +ALTER TABLE `raidgroup` MODIFY COLUMN `lootMethod` tinyint(4) NOT NULL; +ALTER TABLE `raidgroup` MODIFY COLUMN `looterGuid` int(11) NOT NULL; + +ALTER TABLE `raidgroup_member` MODIFY COLUMN `leaderGuid` int(11) NOT NULL; +ALTER TABLE `raidgroup_member` MODIFY COLUMN `memberGuid` int(11) NOT NULL; + +ALTER TABLE `skinning_loot_template` MODIFY COLUMN `maxcount` tinyint(3) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `skinning_loot_template` MODIFY COLUMN `quest_freeforall` tinyint(3) unsigned NOT NULL DEFAULT '1'; + +ALTER TABLE `spell_chain` MODIFY COLUMN `rank` tinyint(4) NOT NULL DEFAULT '0'; diff --git a/sql/updates/0.6/3010_item_template.sql b/sql/updates/0.6/3010_item_template.sql new file mode 100644 index 000000000..9fe8bf949 --- /dev/null +++ b/sql/updates/0.6/3010_item_template.sql @@ -0,0 +1 @@ +ALTER TABLE `item_template` ADD COLUMN `BagFamily` tinyint(3) unsigned NOT NULL default '0' AFTER `area`; diff --git a/sql/updates/0.6/3017_auctionhouse.sql b/sql/updates/0.6/3017_auctionhouse.sql new file mode 100644 index 000000000..0125fc622 --- /dev/null +++ b/sql/updates/0.6/3017_auctionhouse.sql @@ -0,0 +1,5 @@ +ALTER TABLE `auctionhouse` + MODIFY COLUMN `auctioneerguid` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `itemguid` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `itemowner` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `buyguid` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.6/3020_command.sql b/sql/updates/0.6/3020_command.sql new file mode 100644 index 000000000..5e27a86d4 --- /dev/null +++ b/sql/updates/0.6/3020_command.sql @@ -0,0 +1,2 @@ +DELETE FROM `command` WHERE `name` = 'cooldown'; +INSERT INTO command (name, security, help) VALUES ('cooldown', 3,'Syntax: .cooldown [#spell_id]\r\n\r\nRemove all (if spell_id not provided) or #spel_id spell cooldown from selected character or you (if no selection).'); diff --git a/sql/updates/0.6/3032_creature.sql b/sql/updates/0.6/3032_creature.sql new file mode 100644 index 000000000..7acf35788 --- /dev/null +++ b/sql/updates/0.6/3032_creature.sql @@ -0,0 +1,7 @@ +/*delete redundant column from creature table*/ +ALTER TABLE `creature` ADD COLUMN `spawntimesecs` int(11) unsigned NOT NULL default '120' AFTER `spawntimemin`; + +UPDATE creature SET `spawntimesecs`= (spawntimemin + spawntimemax) /2; + +ALTER TABLE creature DROP COLUMN spawntimemax; +ALTER TABLE creature DROP COLUMN spawntimemin; \ No newline at end of file diff --git a/sql/updates/0.6/3044_gameobject_template.sql b/sql/updates/0.6/3044_gameobject_template.sql new file mode 100644 index 000000000..aad97b09d --- /dev/null +++ b/sql/updates/0.6/3044_gameobject_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `gameobject_template` + DROP `castsSpell`; diff --git a/sql/updates/0.6/3054_command.sql b/sql/updates/0.6/3054_command.sql new file mode 100644 index 000000000..347924f65 --- /dev/null +++ b/sql/updates/0.6/3054_command.sql @@ -0,0 +1,5 @@ +DELETE FROM `command` WHERE `name` = 'searchtele'; +INSERT INTO `command` VALUES('lookuptele',1,'Syntax: .lookuptele $substring\r\n\r\nSearch and output all .tele command locations with provide $substring in name.'); +INSERT INTO `command` VALUES('lookupquest',3,'Syntax: .lookupquest $namepart\r\n\r\nLooks up a quest by $namepart, and returns all matches with their quest ID\'s.'); +INSERT INTO `command` VALUES('lookupspell',3,'Syntax: .lookupspell $namepart\r\n\r\nLooks up a spell by $namepart, and returns all matches with their spell ID\'s.'); + diff --git a/sql/updates/0.6/3059_pet_levelstats.sql b/sql/updates/0.6/3059_pet_levelstats.sql new file mode 100644 index 000000000..e69e440cd --- /dev/null +++ b/sql/updates/0.6/3059_pet_levelstats.sql @@ -0,0 +1,12 @@ +CREATE TABLE `pet_levelstats` ( + `creature_entry` int(11) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `hp` smallint(5) unsigned NOT NULL, + `mana` smallint(5) unsigned NOT NULL, + `str` smallint(5) unsigned NOT NULL, + `agi` smallint(5) unsigned NOT NULL, + `sta` smallint(5) unsigned NOT NULL, + `int` smallint(5) unsigned NOT NULL, + `spi` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`creature_entry`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores pet levels stats.'; diff --git a/sql/updates/0.6/3068_command.sql b/sql/updates/0.6/3068_command.sql new file mode 100644 index 000000000..56cbfbd76 --- /dev/null +++ b/sql/updates/0.6/3068_command.sql @@ -0,0 +1,2 @@ +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('spawndist',2,'Syntax: .spawndist #dist\r\n\r\nAdjust spawndistance of selected creature to dist.'); +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('spawntime',2,'Syntax: .spawntime #time \r\n\r\nAdjust spawntime of selected creature to time.'); \ No newline at end of file diff --git a/sql/updates/0.6/3075_creature.sql b/sql/updates/0.6/3075_creature.sql new file mode 100644 index 000000000..74f1dbd35 --- /dev/null +++ b/sql/updates/0.6/3075_creature.sql @@ -0,0 +1,8 @@ +ALTER TABLE creature DROP COLUMN respawntimer; + +DROP TABLE IF EXISTS `creature_respawn`; +CREATE TABLE `creature_respawn` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `respawntime` bigint(40) NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Grid Loading System'; diff --git a/sql/updates/0.6/3075_gameobject.sql b/sql/updates/0.6/3075_gameobject.sql new file mode 100644 index 000000000..9a576787d --- /dev/null +++ b/sql/updates/0.6/3075_gameobject.sql @@ -0,0 +1,12 @@ +ALTER TABLE `gameobject` + CHANGE `respawntimer` `spawntimesecs` int(11) unsigned NOT NULL default '0'; + +UPDATE `gameobject` SET `spawntimesecs` = `spawntimesecs` / 1000; + +DROP TABLE IF EXISTS `gameobject_respawn`; +CREATE TABLE `gameobject_respawn` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `respawntime` bigint(40) NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Grid Loading System'; + diff --git a/sql/updates/0.6/3090_command.sql b/sql/updates/0.6/3090_command.sql new file mode 100644 index 000000000..29bb8b07a --- /dev/null +++ b/sql/updates/0.6/3090_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('respawn',3,'Syntax: .respawn\r\n\r\nRespawn all nearest creatures and GO without waiting respawn time expiration.'); diff --git a/sql/updates/0.6/3090_creature_template.sql b/sql/updates/0.6/3090_creature_template.sql new file mode 100644 index 000000000..64bb0e610 --- /dev/null +++ b/sql/updates/0.6/3090_creature_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE `creature_template` + ADD COLUMN `pickpocketloot` int(10) unsigned NOT NULL default '0' AFTER `lootid`; + +UPDATE `creature_template`,`pickpocketing_loot_template` + SET `creature_template`.`pickpocketloot` = `creature_template`.`lootid` + WHERE `creature_template`.`lootid` = `pickpocketing_loot_template`.`entry`; diff --git a/sql/updates/0.6/3090_loot_template.sql b/sql/updates/0.6/3090_loot_template.sql new file mode 100644 index 000000000..ccfc7fa62 --- /dev/null +++ b/sql/updates/0.6/3090_loot_template.sql @@ -0,0 +1,17 @@ +ALTER TABLE `creature_loot_template` + ADD COLUMN `mincount` tinyint(3) unsigned NOT NULL default '1' AFTER `QuestChanceOrGroup`; + +ALTER TABLE `fishing_loot_template` + ADD COLUMN `mincount` tinyint(3) unsigned NOT NULL default '1' AFTER `QuestChanceOrGroup`; + +ALTER TABLE `gameobject_loot_template` + ADD COLUMN `mincount` tinyint(3) unsigned NOT NULL default '1' AFTER `QuestChanceOrGroup`; + +ALTER TABLE `item_loot_template` + ADD COLUMN `mincount` tinyint(3) unsigned NOT NULL default '1' AFTER `QuestChanceOrGroup`; + +ALTER TABLE `pickpocketing_loot_template` + ADD COLUMN `mincount` tinyint(3) unsigned NOT NULL default '1' AFTER `QuestChanceOrGroup`; + +ALTER TABLE `skinning_loot_template` + ADD COLUMN `mincount` tinyint(3) unsigned NOT NULL default '1' AFTER `QuestChanceOrGroup`; diff --git a/sql/updates/0.6/3091_spell_proc_event.sql b/sql/updates/0.6/3091_spell_proc_event.sql new file mode 100644 index 000000000..298bab0f3 --- /dev/null +++ b/sql/updates/0.6/3091_spell_proc_event.sql @@ -0,0 +1,831 @@ +DROP TABLE IF EXISTS `spell_proc_event`; + +CREATE TABLE `spell_proc_event` ( + `entry` smallint(6) NOT NULL default '0', + `SchoolMask` tinyint(4) NOT NULL default '0', + `Category` smallint(6) NOT NULL default '0', + `SkillID` smallint(6) NOT NULL default '0', + `SpellFamilyMask` int(11) NOT NULL default '0', + `procFlags` int(11) NOT NULL default '0', + `ppmRate` float NOT NULL default '0', + PRIMARY KEY (`entry`) +); + +INSERT INTO `spell_proc_event` VALUES ('6866', '4', '0', '0', '0', '20564', '0'); +INSERT INTO `spell_proc_event` VALUES ('6870', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('7131', '0', '0', '0', '0', '664232', '0'); +INSERT INTO `spell_proc_event` VALUES ('9452', '0', '0', '0', '0', '20', '3'); +INSERT INTO `spell_proc_event` VALUES ('9799', '0', '0', '0', '0', '262144', '0'); +INSERT INTO `spell_proc_event` VALUES ('11119', '2', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('11120', '2', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('11129', '2', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('11180', '8', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12846', '2', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('12847', '2', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('12848', '2', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('13896', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('14076', '0', '0', '39', '128', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('14094', '0', '0', '39', '128', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('14095', '0', '0', '39', '128', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('15286', '16', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18073', '2', '0', '0', '96', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18096', '2', '0', '0', '96', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19271', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('19273', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('19274', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('19275', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('20183', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('20204', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('20411', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('20412', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('20413', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('20414', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('20911', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20912', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20913', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20914', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('21063', '0', '0', '0', '0', '32768', '0'); +INSERT INTO `spell_proc_event` VALUES ('21893', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('21978', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('22007', '0', '0', '0', '2099233', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('22697', '32', '0', '0', '0', '664232', '0'); +INSERT INTO `spell_proc_event` VALUES ('23551', '4', '0', '0', '192', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('23552', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('23572', '4', '0', '0', '192', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('24596', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25592', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25669', '0', '0', '0', '0', '1', '1'); +INSERT INTO `spell_proc_event` VALUES ('25715', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25727', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25728', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25729', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25730', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25731', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25732', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25733', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25734', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25745', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25751', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25752', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('25757', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('25759', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25760', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25761', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25762', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25767', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('25820', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('25899', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('25906', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('25926', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25937', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('25942', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('25945', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('25988', '0', '0', '0', '0', '4263936', '0'); +INSERT INTO `spell_proc_event` VALUES ('26016', '0', '0', '0', '0', '1', '2'); +INSERT INTO `spell_proc_event` VALUES ('26021', '0', '0', '0', '0', '1', '2'); +INSERT INTO `spell_proc_event` VALUES ('26107', '0', '0', '0', '4063232', '67108864', '0'); +INSERT INTO `spell_proc_event` VALUES ('26119', '0', '0', '0', '-1877999613', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('26128', '0', '0', '0', '0', '33554432', '0'); +INSERT INTO `spell_proc_event` VALUES ('26135', '0', '0', '0', '8388608', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('26169', '0', '0', '0', '0', '134217728', '0'); +INSERT INTO `spell_proc_event` VALUES ('26341', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('26376', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('26463', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('26467', '0', '0', '0', '0', '134217728', '0'); +INSERT INTO `spell_proc_event` VALUES ('26480', '0', '0', '0', '0', '524289', '3'); +INSERT INTO `spell_proc_event` VALUES ('27200', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27419', '0', '0', '0', '0', '1', '3'); +INSERT INTO `spell_proc_event` VALUES ('27420', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27498', '0', '0', '0', '0', '1', '3'); +INSERT INTO `spell_proc_event` VALUES ('27521', '0', '0', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('27522', '0', '0', '0', '0', '524289', '0'); +INSERT INTO `spell_proc_event` VALUES ('27539', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('27561', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('27656', '0', '0', '0', '0', '1', '3'); +INSERT INTO `spell_proc_event` VALUES ('27688', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('27774', '0', '0', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('27776', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('27778', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('27780', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('27781', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('27785', '0', '0', '0', '0', '524288', '0'); +INSERT INTO `spell_proc_event` VALUES ('27787', '0', '0', '0', '0', '1', '3'); +INSERT INTO `spell_proc_event` VALUES ('27811', '0', '0', '0', '0', '8396800', '0'); +INSERT INTO `spell_proc_event` VALUES ('27815', '0', '0', '0', '0', '8396800', '0'); +INSERT INTO `spell_proc_event` VALUES ('27816', '0', '0', '0', '0', '8396800', '0'); +INSERT INTO `spell_proc_event` VALUES ('27852', '0', '0', '0', '0', '32768', '0'); +INSERT INTO `spell_proc_event` VALUES ('27857', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27861', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27863', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27864', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27865', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('27867', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('28130', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('28200', '0', '0', '0', '0', '134217728', '0'); +INSERT INTO `spell_proc_event` VALUES ('28429', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('28458', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('28460', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('28592', '8', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('28593', '8', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('28594', '8', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('28595', '8', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('28719', '4', '0', '0', '32', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('28752', '0', '0', '0', '0', '4194304', '0'); +INSERT INTO `spell_proc_event` VALUES ('28761', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('28764', '0', '0', '0', '0', '1048576', '0'); +INSERT INTO `spell_proc_event` VALUES ('28771', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('28789', '0', '0', '0', '-1073717248', '134217728', '0'); +INSERT INTO `spell_proc_event` VALUES ('28802', '0', '0', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('28809', '1', '0', '56', '4096', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('28812', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('28816', '0', '0', '0', '0', '1', '3'); +INSERT INTO `spell_proc_event` VALUES ('28823', '4', '0', '374', '192', '134217728', '0'); +INSERT INTO `spell_proc_event` VALUES ('28845', '0', '0', '0', '0', '512', '0'); +INSERT INTO `spell_proc_event` VALUES ('28847', '4', '0', '573', '32', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('28849', '4', '0', '374', '128', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('28881', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('29062', '0', '0', '0', '0', '8396800', '0'); +INSERT INTO `spell_proc_event` VALUES ('29064', '0', '0', '0', '0', '8396800', '0'); +INSERT INTO `spell_proc_event` VALUES ('29065', '0', '0', '0', '0', '8396800', '0'); +INSERT INTO `spell_proc_event` VALUES ('29074', '10', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('29075', '10', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('29076', '10', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('29150', '0', '0', '0', '0', '1', '3'); +INSERT INTO `spell_proc_event` VALUES ('29162', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('29179', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('29180', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('29185', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('29194', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('29196', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('29198', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('29220', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('29307', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('29441', '0', '0', '0', '0', '16777216', '0'); +INSERT INTO `spell_proc_event` VALUES ('29444', '0', '0', '0', '0', '16777216', '0'); +INSERT INTO `spell_proc_event` VALUES ('29445', '0', '0', '0', '0', '16777216', '0'); +INSERT INTO `spell_proc_event` VALUES ('29446', '0', '0', '0', '0', '16777216', '0'); +INSERT INTO `spell_proc_event` VALUES ('29447', '0', '0', '0', '0', '16777216', '0'); +INSERT INTO `spell_proc_event` VALUES ('29501', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29526', '0', '0', '0', '0', '0', '0'); +INSERT INTO `spell_proc_event` VALUES ('29624', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29625', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29626', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29632', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29633', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29634', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29635', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29636', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('29637', '0', '0', '0', '0', '524288', '3'); +INSERT INTO `spell_proc_event` VALUES ('30079', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('30080', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('30081', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('30160', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('30802', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('30808', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('30809', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('30810', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('30811', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('31255', '0', '0', '0', '0', '256', '0'); +INSERT INTO `spell_proc_event` VALUES ('31316', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('25020', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('25023', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('24949', '0', '0', '0', '0', '32', '0'); +INSERT INTO `spell_proc_event` VALUES ('24658', '0', '0', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('24661', '0', '0', '0', '0', '524289', '0'); +INSERT INTO `spell_proc_event` VALUES ('24574', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('24256', '0', '0', '0', '0', '524289', '0'); +INSERT INTO `spell_proc_event` VALUES ('24051', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23888', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23863', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23867', '0', '0', '0', '0', '129', '0'); +INSERT INTO `spell_proc_event` VALUES ('23885', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23886', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23887', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23771', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('23780', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('23721', '32', '0', '163', '2048', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('23686', '0', '0', '0', '0', '1', '2'); +INSERT INTO `spell_proc_event` VALUES ('23688', '0', '0', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('23689', '0', '0', '0', '0', '1', '4'); +INSERT INTO `spell_proc_event` VALUES ('23695', '0', '0', '26', '2', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('23578', '0', '0', '0', '0', '524288', '2'); +INSERT INTO `spell_proc_event` VALUES ('23581', '0', '0', '0', '0', '1', '2'); +INSERT INTO `spell_proc_event` VALUES ('23548', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('23378', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('23305', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('23340', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('23255', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('23301', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('23303', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('23306', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('22835', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22857', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('22716', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22618', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('22620', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('22648', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('22438', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('22413', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22283', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22285', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22286', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22287', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('22288', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21969', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('21911', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21853', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('21882', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('21890', '0', '0', '0', '-362127634', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('21788', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21789', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21897', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('21838', '0', '0', '0', '0', '32768', '0'); +INSERT INTO `spell_proc_event` VALUES ('21841', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21645', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21747', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21387', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('21329', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('21334', '0', '0', '0', '0', '32768', '0'); +INSERT INTO `spell_proc_event` VALUES ('21185', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('21061', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21080', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21084', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('21053', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('20915', '0', '0', '0', '0', '1', '7'); +INSERT INTO `spell_proc_event` VALUES ('20918', '0', '0', '0', '0', '1', '7'); +INSERT INTO `spell_proc_event` VALUES ('20919', '0', '0', '0', '0', '1', '7'); +INSERT INTO `spell_proc_event` VALUES ('20920', '0', '0', '0', '0', '1', '7'); +INSERT INTO `spell_proc_event` VALUES ('20925', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20927', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20928', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20884', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20891', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('20896', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20847', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('20809', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20705', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('20725', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('20563', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20545', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('20500', '0', '0', '0', '268435456', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('20501', '0', '0', '0', '268435456', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('20423', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20422', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20344', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('20345', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('20347', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20348', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20346', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('20349', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20356', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20357', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20375', '0', '0', '0', '0', '1', '7'); +INSERT INTO `spell_proc_event` VALUES ('20354', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('20355', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('20419', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20421', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20287', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20288', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20289', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20290', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20291', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20292', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20293', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20210', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('20212', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('20213', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('20214', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('20215', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('20179', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20180', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20181', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20182', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20185', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('20186', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('20230', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('20234', '1', '0', '0', '32768', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('20235', '0', '0', '0', '32768', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('20135', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20136', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20137', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20154', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20163', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('20164', '0', '0', '0', '0', '1', '2'); +INSERT INTO `spell_proc_event` VALUES ('20165', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20166', '0', '0', '0', '0', '1', '5'); +INSERT INTO `spell_proc_event` VALUES ('20169', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('20127', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20130', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('20049', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('20056', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('20057', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('20058', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('20059', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('20177', '0', '0', '0', '0', '270336', '0'); +INSERT INTO `spell_proc_event` VALUES ('19817', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19818', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19640', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19655', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('19656', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('19660', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('19577', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19514', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('19449', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('19396', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19407', '32', '0', '0', '512', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19409', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('19412', '32', '0', '0', '512', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19413', '32', '0', '0', '512', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19414', '32', '0', '0', '512', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19415', '32', '0', '0', '512', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19478', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('19387', '0', '0', '0', '0', '2097152', '0'); +INSERT INTO `spell_proc_event` VALUES ('19388', '0', '0', '0', '0', '2097152', '0'); +INSERT INTO `spell_proc_event` VALUES ('19389', '0', '0', '0', '0', '2097152', '0'); +INSERT INTO `spell_proc_event` VALUES ('19390', '0', '0', '0', '0', '2097152', '0'); +INSERT INTO `spell_proc_event` VALUES ('19308', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('19309', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('19310', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('19311', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('19312', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('19261', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19262', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19264', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19265', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19266', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19194', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19195', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('19233', '0', '0', '0', '64', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19234', '0', '0', '0', '64', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19235', '0', '0', '0', '64', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19228', '0', '0', '0', '64', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19232', '0', '0', '0', '64', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('19184', '0', '0', '0', '0', '2097152', '0'); +INSERT INTO `spell_proc_event` VALUES ('18979', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('18983', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('18943', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('18799', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('18800', '0', '0', '0', '0', '8', '0'); +INSERT INTO `spell_proc_event` VALUES ('18815', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('18816', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('18847', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('18765', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('18542', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('18186', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('18189', '6', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18121', '0', '0', '593', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18122', '0', '0', '593', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18123', '0', '0', '593', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18137', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('18146', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('18167', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('18119', '0', '0', '593', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18120', '0', '0', '593', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('18097', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('18100', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('17793', '16', '0', '593', '1', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('17796', '16', '0', '593', '1', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('17801', '16', '0', '593', '1', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('17802', '16', '0', '593', '1', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('17803', '16', '0', '593', '1', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('17688', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('17690', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('17670', '0', '0', '0', '0', '8', '0'); +INSERT INTO `spell_proc_event` VALUES ('17495', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('17329', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('17332', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('17350', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('17082', '0', '0', '0', '524288', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('17079', '0', '0', '0', '524288', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('17000', '0', '0', '0', '131072', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('17001', '0', '0', '0', '131072', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('17010', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16956', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('16957', '0', '0', '0', '0', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('16958', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('16961', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('16962', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('16963', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('16964', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('16982', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16923', '0', '0', '574', '4', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('16924', '0', '0', '574', '4', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('16925', '0', '0', '574', '4', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('16926', '0', '0', '574', '4', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('16952', '0', '0', '0', '233472', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('16954', '0', '0', '0', '233472', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('16955', '0', '0', '0', '233472', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('16880', '0', '0', '0', '0', '268500992', '0'); +INSERT INTO `spell_proc_event` VALUES ('16850', '0', '0', '574', '4', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('16864', '0', '0', '0', '0', '1', '6'); +INSERT INTO `spell_proc_event` VALUES ('16800', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16810', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16811', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16812', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16813', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16792', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('16843', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16689', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16624', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('16611', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16615', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16620', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('16550', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('16563', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16574', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16575', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16487', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('16489', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('16492', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('16423', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('16428', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16281', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('16282', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('16283', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('16284', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('16311', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16312', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16313', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16235', '0', '0', '0', '0', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('16240', '0', '0', '0', '0', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('16241', '0', '0', '0', '0', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('16242', '0', '0', '0', '0', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('16247', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16256', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('16164', '14', '0', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('16176', '0', '0', '0', '0', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('16140', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('16142', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('16146', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('16092', '0', '0', '0', '0', '32', '0'); +INSERT INTO `spell_proc_event` VALUES ('15978', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15876', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('15852', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15784', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('15730', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15733', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15849', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15636', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15641', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15644', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('15650', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15567', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15568', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15569', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15573', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15594', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('15599', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15600', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15506', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('15507', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('15603', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('15362', '1', '0', '56', '7680', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('15363', '1', '0', '56', '7680', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('15364', '1', '0', '56', '7680', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('15365', '1', '0', '56', '7680', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('15323', '16', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('15324', '16', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('15325', '16', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('15326', '16', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('15335', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('15336', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('15337', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('15338', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('15346', '0', '0', '0', '0', '1', '6'); +INSERT INTO `spell_proc_event` VALUES ('15268', '16', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('15270', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('15277', '0', '0', '0', '0', '1', '6'); +INSERT INTO `spell_proc_event` VALUES ('15088', '0', '0', '0', '0', '4096', '0'); +INSERT INTO `spell_proc_event` VALUES ('15097', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('14892', '1', '0', '56', '7680', '268435456', '0'); +INSERT INTO `spell_proc_event` VALUES ('14796', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('14869', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('14774', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('14531', '0', '0', '0', '0', '8192', '0'); +INSERT INTO `spell_proc_event` VALUES ('14186', '0', '0', '0', '1082131720', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('14190', '0', '0', '0', '1082131720', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('14193', '0', '0', '0', '1082131720', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('14194', '0', '0', '0', '1082131720', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('14195', '0', '0', '0', '1082131720', '65536', '0'); +INSERT INTO `spell_proc_event` VALUES ('14144', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('14148', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('14150', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('14152', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('14154', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('14156', '0', '0', '0', '4063232', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('14160', '0', '0', '0', '4063232', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('14161', '0', '0', '0', '4063232', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('14178', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('14108', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('14111', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('14133', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('14070', '0', '0', '0', '0', '16', '0'); +INSERT INTO `spell_proc_event` VALUES ('14071', '0', '0', '0', '0', '16', '0'); +INSERT INTO `spell_proc_event` VALUES ('13983', '0', '0', '0', '0', '16', '0'); +INSERT INTO `spell_proc_event` VALUES ('13987', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('13959', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('13960', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13961', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13962', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13963', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13964', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13867', '0', '88', '0', '16', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('13879', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('13886', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13754', '0', '88', '0', '16', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('13767', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13800', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13801', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13802', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13803', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13709', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13716', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('13616', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13585', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('13483', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('13358', '0', '0', '0', '0', '16', '0'); +INSERT INTO `spell_proc_event` VALUES ('13260', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('13299', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13320', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('13045', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('13046', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('13047', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('13048', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('13078', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('13159', '0', '0', '0', '0', '32768', '0'); +INSERT INTO `spell_proc_event` VALUES ('12999', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13000', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13001', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('13002', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12947', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12958', '0', '88', '257', '2048', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12971', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12972', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12973', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12974', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12849', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12787', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12799', '0', '65', '257', '1024', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12800', '0', '65', '257', '1024', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12812', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12813', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12814', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12815', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12834', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12782', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('12724', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('12725', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('12726', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('12727', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('12797', '0', '65', '257', '1024', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12867', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12701', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12702', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12703', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12704', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12668', '0', '0', '26', '2', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12598', '0', '88', '237', '16384', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12544', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('12546', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12550', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('12552', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12556', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('12574', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12575', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12576', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12577', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12529', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('12539', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12357', '2', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12358', '2', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12359', '2', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12360', '2', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12311', '0', '88', '257', '2048', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12317', '0', '0', '0', '0', '8658944', '0'); +INSERT INTO `spell_proc_event` VALUES ('12319', '0', '0', '0', '0', '69632', '0'); +INSERT INTO `spell_proc_event` VALUES ('12322', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12246', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('12254', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12281', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12284', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12289', '0', '0', '26', '2', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('12292', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('12298', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('12094', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11984', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12099', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('11919', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11959', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11961', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11964', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('12002', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('12038', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11830', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('11838', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11441', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('11371', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('11255', '0', '0', '237', '16384', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('11213', '0', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('11103', '2', '0', '0', '0', '131072', '0'); +INSERT INTO `spell_proc_event` VALUES ('10868', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('10727', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('10431', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('10432', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('10400', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('10219', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('10220', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('10092', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('10095', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('10022', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9793', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9778', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('9782', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('9784', '0', '0', '0', '0', '64', '0'); +INSERT INTO `spell_proc_event` VALUES ('9797', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9801', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9808', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9460', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('9463', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('9276', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9205', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9233', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('9160', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('9084', '0', '0', '0', '0', '8', '0'); +INSERT INTO `spell_proc_event` VALUES ('8981', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('8852', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('8876', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('8788', '0', '0', '0', '0', '1026', '0'); +INSERT INTO `spell_proc_event` VALUES ('8612', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('8601', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('8397', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('8247', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('8224', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('8134', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('7999', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7849', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7806', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7807', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7808', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7721', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7722', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7723', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7724', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7725', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7726', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7711', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7601', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7614', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7615', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7616', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7617', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('7618', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7619', '0', '0', '0', '0', '1048578', '0'); +INSERT INTO `spell_proc_event` VALUES ('7445', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7446', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7276', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7300', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7301', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7302', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7320', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7486', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7095', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7098', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7102', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('7103', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('7137', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6909', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6921', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6923', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6947', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6961', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6867', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6871', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6750', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6752', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6645', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6592', '0', '0', '0', '0', '1138', '0'); +INSERT INTO `spell_proc_event` VALUES ('6593', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('6433', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('6134', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('6135', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5976', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5977', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5979', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5811', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5751', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5752', '0', '0', '0', '0', '2049', '0'); +INSERT INTO `spell_proc_event` VALUES ('5753', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5754', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5755', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5756', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5680', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5638', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5639', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5640', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5641', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5642', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5643', '0', '0', '0', '0', '2048', '0'); +INSERT INTO `spell_proc_event` VALUES ('5549', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5550', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5551', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5552', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5553', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5554', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5575', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5580', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5513', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5429', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5430', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5431', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5432', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5433', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5352', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5353', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5354', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5364', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5368', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5369', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5427', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5370', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5377', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5301', '0', '0', '0', '0', '112', '0'); +INSERT INTO `spell_proc_event` VALUES ('5341', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5342', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5343', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5344', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5345', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5346', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5349', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5350', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5351', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5262', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5202', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5205', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('5104', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('5118', '0', '0', '0', '0', '32768', '0'); +INSERT INTO `spell_proc_event` VALUES ('4932', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4951', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4525', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4495', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4496', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4512', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4387', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4388', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4389', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4390', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4315', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4317', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4493', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4494', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4279', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4283', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4284', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4241', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4242', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4245', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4144', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('4161', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4112', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4113', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4114', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4115', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4133', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4136', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4138', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4140', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4142', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('4070', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('4051', '0', '0', '0', '0', '128', '0'); +INSERT INTO `spell_proc_event` VALUES ('3637', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('3582', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3616', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3509', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3512', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3424', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3440', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3436', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('3439', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('3394', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3417', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('3418', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('3338', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('3284', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('3235', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('114', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('168', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('324', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('325', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('637', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('646', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('648', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('742', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('905', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('945', '0', '0', '0', '0', '1049602', '0'); +INSERT INTO `spell_proc_event` VALUES ('1028', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('1034', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('1048', '0', '0', '0', '0', '2', '0'); +INSERT INTO `spell_proc_event` VALUES ('1707', '5', '99', '0', '0', '16384', '0'); +INSERT INTO `spell_proc_event` VALUES ('2095', '0', '0', '0', '0', '1139', '0'); +INSERT INTO `spell_proc_event` VALUES ('2652', '0', '0', '0', '0', '1', '0'); +INSERT INTO `spell_proc_event` VALUES ('2689', '0', '0', '0', '0', '4', '0'); +INSERT INTO `spell_proc_event` VALUES ('2852', '0', '0', '0', '0', '2', '0'); diff --git a/sql/updates/0.6/3092_quest_template.sql b/sql/updates/0.6/3092_quest_template.sql new file mode 100644 index 000000000..fb547e804 --- /dev/null +++ b/sql/updates/0.6/3092_quest_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `quest_template` CHANGE `PrevQuestId` `PrevQuestId` int(11) NOT NULL default '0'; +ALTER TABLE `quest_template` CHANGE `NextQuestId` `NextQuestId` int(11) NOT NULL default '0'; \ No newline at end of file diff --git a/sql/updates/0.6/3096_spell_proc_event.sql b/sql/updates/0.6/3096_spell_proc_event.sql new file mode 100644 index 000000000..3ee8d4f66 --- /dev/null +++ b/sql/updates/0.6/3096_spell_proc_event.sql @@ -0,0 +1 @@ +UPDATE `spell_proc_event` set `procFlags`=524288 where `entry` in (5638, 5639, 5640, 5641, 5642, 5643, 5751, 5752, 5753, 5754, 5755, 5756); diff --git a/sql/updates/0.6/3106_command.sql b/sql/updates/0.6/3106_command.sql new file mode 100644 index 000000000..1f48ab806 --- /dev/null +++ b/sql/updates/0.6/3106_command.sql @@ -0,0 +1,5 @@ +UPDATE `command` SET `help` = 'Syntax: .banaccount $name\r\n\r\nBan account $name (can be viewed by players by using the .pinfo command) and kick affected players currently logged in.' WHERE `name` = 'banaccount'; +UPDATE `command` SET `help` = 'Syntax: .banip #ip\r\n\r\nBans logging into the server from computers with the provided IP address, and kicks all affected players.' WHERE `name` = 'banip'; +UPDATE `command` SET `help` = 'Syntax: .unbanaccount $name\r\n\r\nUnban account $name.' WHERE `name` = 'unbanaccount'; +UPDATE `command` SET `help` = 'Syntax: .unbanip #ip\r\n\r\nUnban the provided IP address from the server.' WHERE `name` = 'unbanip'; +UPDATE `command` SET `help` = 'Syntax: .kick [$charactername]\r\n\r\nKick the given character name from the world. If no character name is provided then the selected player (except for yourself) will be kicked.' WHERE `name` = 'kick'; diff --git a/sql/updates/0.6/3107_playercreateinfo_skill.sql b/sql/updates/0.6/3107_playercreateinfo_skill.sql new file mode 100644 index 000000000..9d2978ce3 --- /dev/null +++ b/sql/updates/0.6/3107_playercreateinfo_skill.sql @@ -0,0 +1,6 @@ +ALTER TABLE `playercreateinfo_skill` + MODIFY COLUMN `SkillMin` smallint(5) NOT NULL default '0', + MODIFY COLUMN `SkillMax` smallint(5) NOT NULL default '0'; + +UPDATE `playercreateinfo_skill` SET `SkillMin` = '-1' WHERE `SkillMin` = 300; +UPDATE `playercreateinfo_skill` SET `SkillMax` = '-1' WHERE `SkillMax` = 300; diff --git a/sql/updates/0.6/3108_quest_template.sql b/sql/updates/0.6/3108_quest_template.sql new file mode 100644 index 000000000..1ab760fd6 --- /dev/null +++ b/sql/updates/0.6/3108_quest_template.sql @@ -0,0 +1,5 @@ +UPDATE `quest_template` SET `PrevQuestId`=`HaveQuestId` * '-1' WHERE `HaveQuestId`!='0' AND `PrevQuestId`='0'; +ALTER TABLE `quest_template` DROP `HaveQuestId`; + +ALTER TABLE `quest_template` ADD COLUMN `NextQuestInChain` int(11) unsigned NOT NULL default '0' AFTER `ExclusiveGroup`; +UPDATE `quest_template` SET `NextQuestInChain`=`NextQuestId` WHERE `NextQuestId`>'0'; \ No newline at end of file diff --git a/sql/updates/0.6/3110_quest_template.sql b/sql/updates/0.6/3110_quest_template.sql new file mode 100644 index 000000000..c7cc4d7a2 --- /dev/null +++ b/sql/updates/0.6/3110_quest_template.sql @@ -0,0 +1,98 @@ +update `quest_template` set `RewRepFaction1` = +case `RewRepFaction1` + when 0 then 0 + when 11 then 72 + when 12 then 72 + when 23 then 54 + when 29 then 76 + when 55 then 47 + when 64 then 54 + when 68 then 68 + when 69 then 470 + when 79 then 69 + when 80 then 69 + when 83 then 67 + when 85 then 76 + when 104 then 81 + when 105 then 81 + when 118 then 68 + when 119 then 87 + when 120 then 21 + when 121 then 21 + when 126 then 530 + when 132 then 92 + when 133 then 93 + when 414 then 576 + when 471 then 349 + when 474 then 369 + when 534 then 469 + when 635 then 609 + when 694 then 471 + when 776 then 910 + when 794 then 529 + when 854 then 577 + when 874 then 589 + when 994 then 609 + when 1214 then 729 + when 1216 then 730 + when 1514 then 890 + when 1515 then 889 + when 1555 then 909 + when 1574 then 270 + when 1577 then 509 + when 1598 then 510 + when 1601 then 910 + when 1635 then 169 + + else `RewRepFaction1`*'-1' +end; + +update `quest_template` set `RewRepFaction2` = +case `RewRepFaction2` + when 0 then 0 + when 11 then 72 + when 12 then 72 + when 23 then 54 + when 29 then 76 + when 55 then 47 + when 64 then 54 + when 68 then 68 + when 69 then 470 + when 79 then 69 + when 80 then 69 + when 83 then 67 + when 85 then 76 + when 104 then 81 + when 105 then 81 + when 118 then 68 + when 119 then 87 + when 120 then 21 + when 121 then 21 + when 126 then 530 + when 132 then 92 + when 133 then 93 + when 414 then 576 + when 471 then 349 + when 474 then 369 + when 534 then 469 + when 635 then 609 + when 694 then 471 + when 776 then 910 + when 794 then 529 + when 854 then 577 + when 874 then 589 + when 994 then 609 + when 1214 then 729 + when 1216 then 730 + when 1514 then 890 + when 1515 then 889 + when 1555 then 909 + when 1574 then 270 + when 1577 then 509 + when 1598 then 510 + when 1601 then 910 + when 1635 then 169 + + else `RewRepFaction2`*'-1' +end; + diff --git a/sql/updates/0.6/3115_quest_template.sql b/sql/updates/0.6/3115_quest_template.sql new file mode 100644 index 000000000..13afbd322 --- /dev/null +++ b/sql/updates/0.6/3115_quest_template.sql @@ -0,0 +1,7 @@ +ALTER TABLE `quest_template` + ADD COLUMN `RewRepFaction3` int(11) unsigned NOT NULL default '0' AFTER `RewRepFaction2`, + ADD COLUMN `RewRepFaction4` int(11) unsigned NOT NULL default '0' AFTER `RewRepFaction3`, + ADD COLUMN `RewRepFaction5` int(11) unsigned NOT NULL default '0' AFTER `RewRepFaction4`, + ADD COLUMN `RewRepValue3` int(11) NOT NULL default '0' AFTER `RewRepValue2`, + ADD COLUMN `RewRepValue4` int(11) NOT NULL default '0' AFTER `RewRepValue3`, + ADD COLUMN `RewRepValue5` int(11) NOT NULL default '0' AFTER `RewRepValue4`; diff --git a/sql/updates/0.7/3138_character_inventory.sql b/sql/updates/0.7/3138_character_inventory.sql new file mode 100644 index 000000000..bd4bbc47d --- /dev/null +++ b/sql/updates/0.7/3138_character_inventory.sql @@ -0,0 +1,2 @@ +ALTER TABLE character_inventory + ADD UNIQUE KEY `idx_item` (`item`); diff --git a/sql/updates/0.7/3138_disenchaning_loot_template.sql b/sql/updates/0.7/3138_disenchaning_loot_template.sql new file mode 100644 index 000000000..2145e913a --- /dev/null +++ b/sql/updates/0.7/3138_disenchaning_loot_template.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS `disenchant_loot_template`; +CREATE TABLE `disenchant_loot_template` ( + `entry` int(11) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0', + `ChanceOrRef` float NOT NULL default '100', + `QuestChanceOrGroup` tinyint(3) NOT NULL default '0', + `mincount` tinyint(3) unsigned NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `quest_freeforall` tinyint(3) unsigned NOT NULL default '1', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; diff --git a/sql/updates/0.7/3138_item_template.sql b/sql/updates/0.7/3138_item_template.sql new file mode 100644 index 000000000..a32dc187a --- /dev/null +++ b/sql/updates/0.7/3138_item_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `item_template` + ADD `DisenchantID` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.7/3141_spell_threat.sql b/sql/updates/0.7/3141_spell_threat.sql new file mode 100644 index 000000000..0f9737ccf --- /dev/null +++ b/sql/updates/0.7/3141_spell_threat.sql @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS `spell_threat`; +CREATE TABLE `spell_threat` ( + `entry` int(10) unsigned NOT NULL, + `Threat` int(11) NOT NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED; + +-- +-- Dumping data for table `spell_threat` +-- + +/*!40000 ALTER TABLE `spell_threat` DISABLE KEYS */; +INSERT INTO `spell_threat` (`entry`,`Threat`) VALUES + (1672,180),(9881,207),(11556,43),(11567,145),(11597,261),(11601,315),(11775,395),(14921,415),(24394,580),(24583,5), + (25286,175),(25288,355),(25289,60),(78,20),(284,39),(285,59),(1608,78),(11564,98),(11565,118),(11566,137),(7386,100),(7405,140), + (8380,180),(11596,220),(1715,61),(7372,101),(7373,141),(6572,155),(6574,195),(7379,235),(11600,275),(23922,160),(23923,190), + (23924,220),(23925,250),(6809,89),(8972,118),(9745,148),(9880,178),(770,108),(778,108),(9749,108),(9907,108), + (17735,200),(17750,300),(17751,450),(17752,600),(20736,100),(14274,200),(15629,300),(15630,400),(15631,500),(15632,600); +/*!40000 ALTER TABLE `spell_threat` ENABLE KEYS */; diff --git a/sql/updates/0.7/3144_command.sql b/sql/updates/0.7/3144_command.sql new file mode 100644 index 000000000..cf333ff6b --- /dev/null +++ b/sql/updates/0.7/3144_command.sql @@ -0,0 +1,5 @@ +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.lookupobject',3,'Syntax: .lookupobject $objname\r\n\r\nLooks up an gameobject by $objname, and returns all matches with their Gameobject ID\'s.'); +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.listcreature',3,'Syntax: .listcreature #creature_id [#max_count]\r\n\r\nOutput creatures with creature id #creature_id found in world. Output creature guids and coordinates sorted by distance from character. Will be output maximum #max_count creatures. If #max_count not provided use 10 as default value.'); +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.listobject',3,'Syntax: .listobject #gameobject_id [#max_count]\r\n\r\nOutput gameobjects with gameobject id #gameobject_id found in world. Output gameobject guids and coordinates sorted by distance from character. Will be output maximum #max_count gameobject. If #max_count not provided use 10 as default value.'); +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.listitem',3,'Syntax: .listitem #item_id [#max_count]\r\n\r\nOutput items with item id #item_id found in all character inventories, mails and auctions. Output item guids, item owner guid, owner account and owner name. Will be output maximum #max_count items. If #max_count not provided use 10 as default value.'); + diff --git a/sql/updates/0.7/3150_command.sql b/sql/updates/0.7/3150_command.sql new file mode 100644 index 000000000..991744885 --- /dev/null +++ b/sql/updates/0.7/3150_command.sql @@ -0,0 +1,3 @@ +DELETE FROM `command` WHERE `name` = 'random'; +DELETE FROM `command` WHERE `name` = 'setmovetype'; +INSERT INTO `command` (`name`,`security`,`help`) VALUES ('setmovetype',2,'Syntax: .setmovetype [#creature_guid] stay/random/way\r\n\r\nSet for creature pointed by #creature_guid (or selected if #creature_guid not provided) movement type and move it to respawn position (if creature alive). Any existed waypoints for creature will be removed from database. If creature is dead then movement type will aplied at creature respawm.'); diff --git a/sql/updates/0.7/3162_character_queststatus.sql b/sql/updates/0.7/3162_character_queststatus.sql new file mode 100644 index 000000000..6590539de --- /dev/null +++ b/sql/updates/0.7/3162_character_queststatus.sql @@ -0,0 +1,2 @@ +UPDATE `character_queststatus` SET `rewarded`='1' WHERE `completed_once`='1'; +ALTER TABLE `character_queststatus` DROP `completed_once`; \ No newline at end of file diff --git a/sql/updates/0.7/3162_command.sql b/sql/updates/0.7/3162_command.sql new file mode 100644 index 000000000..052fb1f4c --- /dev/null +++ b/sql/updates/0.7/3162_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help`='Syntax: .recall\r\n\r\nTeleport you to the place where you have been before using the .tele command.' WHERE `name`='recall'; \ No newline at end of file diff --git a/sql/updates/0.7/3162_quest_template.sql b/sql/updates/0.7/3162_quest_template.sql new file mode 100644 index 000000000..dfc9fc138 --- /dev/null +++ b/sql/updates/0.7/3162_quest_template.sql @@ -0,0 +1,2 @@ +UPDATE `quest_template` SET `SpecialFlags`=`SpecialFlags`|'32' WHERE `Repeatable`='1'; +ALTER TABLE `quest_template` DROP `Repeatable`; \ No newline at end of file diff --git a/sql/updates/0.7/3174_command.sql b/sql/updates/0.7/3174_command.sql new file mode 100644 index 000000000..c42c9b487 --- /dev/null +++ b/sql/updates/0.7/3174_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help`='Syntax: .recall [$playername]\r\n\r\nTeleport $playername or selected player to the place where he has been before last use of a teleportation command. If no $playername is entered and no player is selected, it will teleport you.' WHERE `name`='recall'; \ No newline at end of file diff --git a/sql/updates/0.7/3179_quest_template.sql b/sql/updates/0.7/3179_quest_template.sql new file mode 100644 index 000000000..9dcc96bcd --- /dev/null +++ b/sql/updates/0.7/3179_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` ADD COLUMN `Repeatable` tinyint(1) unsigned NOT NULL default '0'; + +UPDATE `quest_template` SET `Repeatable`='1' WHERE `SpecialFlags`&'32'='32'; \ No newline at end of file diff --git a/sql/updates/0.7/3180_spell_proc_event.sql b/sql/updates/0.7/3180_spell_proc_event.sql new file mode 100644 index 000000000..2058c1044 --- /dev/null +++ b/sql/updates/0.7/3180_spell_proc_event.sql @@ -0,0 +1,2 @@ +delete from `spell_proc_event` where `entry` = 23547; +insert into `spell_proc_event` values(23547,0,0,0,0,32,0); diff --git a/sql/updates/0.7/3183_command.sql b/sql/updates/0.7/3183_command.sql new file mode 100644 index 000000000..434aac667 --- /dev/null +++ b/sql/updates/0.7/3183_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('lookupitemset',3,'Syntax: .lookupitemset $itemname\r\n\r\nLooks up an item set by $itemname, and returns all matches with their Item set ID\'s.'); diff --git a/sql/updates/0.7/3186_command.sql b/sql/updates/0.7/3186_command.sql new file mode 100644 index 000000000..c5cc1d798 --- /dev/null +++ b/sql/updates/0.7/3186_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('removequest',3,'Syntax: .removequest #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'); diff --git a/sql/updates/0.7/3202_character_gifts.sql b/sql/updates/0.7/3202_character_gifts.sql new file mode 100644 index 000000000..cdbbf97b0 --- /dev/null +++ b/sql/updates/0.7/3202_character_gifts.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS `character_gifts`; + +CREATE TABLE `character_gifts` ( + `guid` int(20) unsigned NOT NULL default '0', + `item_guid` int(11) unsigned NOT NULL default '0', + `entry` int(20) unsigned NOT NULL default '0', + `flags` int(20) unsigned NOT NULL default '0', + KEY `idx_guid` (`guid`), + PRIMARY KEY (`item_guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.7/3205_character_inventory.sql b/sql/updates/0.7/3205_character_inventory.sql new file mode 100644 index 000000000..4672fc447 --- /dev/null +++ b/sql/updates/0.7/3205_character_inventory.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character_inventory` DROP PRIMARY KEY, DROP KEY `idx_item`; + +ALTER TABLE `character_inventory` ADD PRIMARY KEY (`item`); diff --git a/sql/updates/0.7/3231_quest_template.sql b/sql/updates/0.7/3231_quest_template.sql new file mode 100644 index 000000000..5090b0db0 --- /dev/null +++ b/sql/updates/0.7/3231_quest_template.sql @@ -0,0 +1,9 @@ +ALTER TABLE `quest_template` ADD COLUMN `ReqSourceCount1` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceId4`; +ALTER TABLE `quest_template` ADD COLUMN `ReqSourceCount2` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceCount1`; +ALTER TABLE `quest_template` ADD COLUMN `ReqSourceCount3` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceCount2`; +ALTER TABLE `quest_template` ADD COLUMN `ReqSourceCount4` int(11) unsigned NOT NULL default '0' AFTER `ReqSourceCount3`; + +UPDATE `quest_template` SET `ReqSourceCount1`='1' WHERE `ReqSourceId1`!='0'; +UPDATE `quest_template` SET `ReqSourceCount2`='1' WHERE `ReqSourceId2`!='0'; +UPDATE `quest_template` SET `ReqSourceCount3`='1' WHERE `ReqSourceId3`!='0'; +UPDATE `quest_template` SET `ReqSourceCount4`='1' WHERE `ReqSourceId4`!='0'; \ No newline at end of file diff --git a/sql/updates/0.7/3245_item_text.sql b/sql/updates/0.7/3245_item_text.sql new file mode 100644 index 000000000..f24390f5f --- /dev/null +++ b/sql/updates/0.7/3245_item_text.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS `item_text`; +CREATE TABLE `item_text` ( + `id` int(11) NOT NULL default '0', + `text` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; diff --git a/sql/updates/0.7/3245_mail.sql b/sql/updates/0.7/3245_mail.sql new file mode 100644 index 000000000..ed7342232 --- /dev/null +++ b/sql/updates/0.7/3245_mail.sql @@ -0,0 +1,3 @@ +ALTER TABLE `mail` + CHANGE COLUMN `itemPageId` `itemTextId` int(11) unsigned NOT NULL default '0'; + diff --git a/sql/updates/0.7/3245_page_text.sql b/sql/updates/0.7/3245_page_text.sql new file mode 100644 index 000000000..93045d1e0 --- /dev/null +++ b/sql/updates/0.7/3245_page_text.sql @@ -0,0 +1,7 @@ +ALTER TABLE `item_page` RENAME TO `page_text`; +ALTER TABLE `page_text` ENGINE = MyISAM; + +ALTER TABLE `page_text` + DROP PRIMARY KEY, + CHANGE COLUMN `id` `entry` int(11) NOT NULL default '0', + ADD PRIMARY KEY (`entry`); diff --git a/sql/updates/0.7/3246_character_reputation.sql b/sql/updates/0.7/3246_character_reputation.sql new file mode 100644 index 000000000..806e5424b --- /dev/null +++ b/sql/updates/0.7/3246_character_reputation.sql @@ -0,0 +1,24 @@ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 47 , 20, '0', '1' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 47 , 20, '0', '2' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 54 , 18, '0', '1' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 54 , 18, '0', '2' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 68 , 17, '0', '2' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 68 , 17, '0', '1' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 69 , 21, '0', '1' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 69 , 21, '0', '2' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 72 , 19, '0', '1' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 72 , 19, '0', '2' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 76 , 14, '0', '2' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 76 , 14, '0', '1' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 81 , 16, '0', '2' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 81 , 16, '0', '1' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 530, 15, '0', '2' FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 530, 15, '0', '1' FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8; + diff --git a/sql/updates/0.7/3251_commands.sql b/sql/updates/0.7/3251_commands.sql new file mode 100644 index 000000000..b5d2f029f --- /dev/null +++ b/sql/updates/0.7/3251_commands.sql @@ -0,0 +1,2 @@ +DELETE FROM `command` WHERE `name` = 'password'; +INSERT INTO `command` VALUES ('password',0,'Syntax: .password $old_password $new_password $new_password\r\n\r\nChange your account password.'); diff --git a/sql/updates/0.7/3252.sql b/sql/updates/0.7/3252.sql new file mode 100644 index 000000000..09e01de67 --- /dev/null +++ b/sql/updates/0.7/3252.sql @@ -0,0 +1,74 @@ +ALTER TABLE `areatrigger_template` MODIFY COLUMN `required_level` tinyint(3) unsigned NOT NULL default '0'; +ALTER TABLE `item_template` MODIFY COLUMN `DisenchantID` int(11) unsigned NOT NULL default '0'; + +ALTER TABLE `auctionhouse` MODIFY COLUMN `id` int(11) unsigned NOT NULL default '0'; + +ALTER TABLE `corpse` MODIFY COLUMN `player` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier'; + +ALTER TABLE `creature_template` + MODIFY COLUMN `rangedattackpower` smallint(5) unsigned NOT NULL default '0', + MODIFY COLUMN `type` tinyint(3) unsigned default '0'; + +ALTER TABLE `disenchant_loot_template` MODIFY COLUMN `entry` int(11) unsigned NOT NULL default '0' COMMENT 'Recommended id selection: item_level*100 + item_quality'; + +UPDATE `item_template` SET `stat_type1`='0' WHERE `stat_type1`<'0'; +UPDATE `item_template` SET `stat_type2`='0' WHERE `stat_type2`<'0'; +UPDATE `item_template` SET `stat_type3`='0' WHERE `stat_type3`<'0'; +UPDATE `item_template` SET `stat_type4`='0' WHERE `stat_type4`<'0'; +UPDATE `item_template` SET `stat_type5`='0' WHERE `stat_type5`<'0'; +UPDATE `item_template` SET `stat_type6`='0' WHERE `stat_type6`<'0'; +UPDATE `item_template` SET `stat_type7`='0' WHERE `stat_type7`<'0'; +UPDATE `item_template` SET `stat_type8`='0' WHERE `stat_type8`<'0'; +UPDATE `item_template` SET `stat_type9`='0' WHERE `stat_type9`<'0'; +UPDATE `item_template` SET `stat_type10`='0' WHERE `stat_type10`<'0'; + +ALTER TABLE `item_template` + MODIFY COLUMN `AllowableClass` mediumint(9) NOT NULL default '0', + MODIFY COLUMN `AllowableRace` mediumint(9) NOT NULL default '0', + MODIFY COLUMN `stat_type1` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value1` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type2` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value2` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type3` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value3` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type4` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value4` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type5` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value5` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type6` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value6` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type7` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value7` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type8` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value8` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type9` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value9` smallint(6) NOT NULL default '0', + MODIFY COLUMN `stat_type10` tinyint(4) unsigned NOT NULL default '0', + MODIFY COLUMN `stat_value10` smallint(6) NOT NULL default '0', + MODIFY COLUMN `dmg_type1` tinyint(3) unsigned NOT NULL default '0', + MODIFY COLUMN `dmg_type2` tinyint(3) unsigned NOT NULL default '0', + MODIFY COLUMN `dmg_type3` tinyint(3) unsigned NOT NULL default '0', + MODIFY COLUMN `dmg_type4` tinyint(3) unsigned NOT NULL default '0', + MODIFY COLUMN `dmg_type5` tinyint(3) unsigned NOT NULL default '0', + MODIFY COLUMN `Material` int(30) NOT NULL default '0'; + +ALTER TABLE `pet_name_generation` ENGINE=MyISAM, DEFAULT CHARSET=utf8; +ALTER TABLE `pet_name_generation` MODIFY COLUMN `word` tinytext NOT NULL; + +ALTER TABLE `quest_template` + MODIFY COLUMN `ReqSourceId1` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `ReqSourceId2` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `ReqSourceId3` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `ReqSourceId4` int(11) unsigned NOT NULL default '0', + MODIFY COLUMN `RewRepFaction1` int(11) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + MODIFY COLUMN `RewRepFaction2` int(11) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + MODIFY COLUMN `RewRepFaction3` int(11) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + MODIFY COLUMN `RewRepFaction4` int(11) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case', + MODIFY COLUMN `RewRepFaction5` int(11) unsigned NOT NULL default '0' COMMENT 'faction id from Faction.dbc in this case'; + +ALTER TABLE `scripts` ENGINE=MyISAM, DEFAULT CHARSET=utf8; +ALTER TABLE `scripts` MODIFY COLUMN `datatext` text NOT NULL; + +ALTER TABLE `spell_proc_event` ENGINE=MyISAM, DEFAULT CHARSET=utf8; + +ALTER TABLE `spell_scripts` ENGINE=MyISAM, DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/sql/updates/0.7/3296_commands.sql b/sql/updates/0.7/3296_commands.sql new file mode 100644 index 000000000..344d99b31 --- /dev/null +++ b/sql/updates/0.7/3296_commands.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'learnskill'; +DELETE FROM `command` WHERE `name` = 'unlearnskill'; +DELETE FROM `command` WHERE `name` = 'fixunlearn'; + diff --git a/sql/updates/0.7/3296_playercreateinfo_skill.sql b/sql/updates/0.7/3296_playercreateinfo_skill.sql new file mode 100644 index 000000000..788b89243 --- /dev/null +++ b/sql/updates/0.7/3296_playercreateinfo_skill.sql @@ -0,0 +1,32 @@ +DROP TABLE IF EXISTS `playercreateinfo_skill`; +CREATE TABLE `playercreateinfo_skill` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `Skill` mediumint(8) unsigned NOT NULL default '0', + `Note` varchar(255) default NULL, + PRIMARY KEY (`race`,`class`,`Skill`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `playercreateinfo_skill` VALUES +(1,1,183,'GENERIC (DND)'),(1,2,183,'GENERIC (DND)'),(1,4,183,'GENERIC (DND)'),(1,5,183,'GENERIC (DND)'),(1,8,183,'GENERIC (DND)'),(1,9,183,'GENERIC (DND)'),(2,1,183,'GENERIC (DND)'),(2,3,183,'GENERIC (DND)'),(2,4,183,'GENERIC (DND)'),(2,7,183,'GENERIC (DND)'),(2,9,183,'GENERIC (DND)'),(3,1,183,'GENERIC (DND)'),(3,2,183,'GENERIC (DND)'),(3,3,183,'GENERIC (DND)'),(3,4,183,'GENERIC (DND)'),(3,5,183,'GENERIC (DND)'),(4,1,183,'GENERIC (DND)'),(4,3,183,'GENERIC (DND)'),(4,4,183,'GENERIC (DND)'),(4,5,183,'GENERIC (DND)'),(4,11,183,'GENERIC (DND)'),(5,1,183,'GENERIC (DND)'),(5,4,183,'GENERIC (DND)'),(5,5,183,'GENERIC (DND)'),(5,8,183,'GENERIC (DND)'),(5,9,183,'GENERIC (DND)'),(6,1,183,'GENERIC (DND)'),(6,3,183,'GENERIC (DND)'),(6,7,183,'GENERIC (DND)'),(6,11,183,'GENERIC (DND)'),(7,1,183,'GENERIC (DND)'),(7,4,183,'GENERIC (DND)'),(7,8,183,'GENERIC (DND)'),(7,9,183,'GENERIC (DND)'),(8,1,183,'GENERIC (DND)'),(8,3,183,'GENERIC (DND)'),(8,4,183,'GENERIC (DND)'),(8,5,183,'GENERIC (DND)'),(8,7,183,'GENERIC (DND)'),(8,8,183,'GENERIC (DND)'), +(1,8,6,'Frost'),(5,8,6,'Frost'),(7,8,6,'Frost'),(8,8,6,'Frost'), +(1,8,8,'Fire'),(5,8,8,'Fire'),(7,8,8,'Fire'),(8,8,8,'Fire'), +(1,1,26,'Arms'),(2,1,26,'Arms'),(3,1,26,'Arms'),(4,1,26,'Arms'),(5,1,26,'Arms'),(6,1,26,'Arms'),(7,1,26,'Arms'),(8,1,26,'Arms'), +(1,4,38,'Combat'),(2,4,38,'Combat'),(3,4,38,'Combat'),(4,4,38,'Combat'),(5,4,38,'Combat'),(7,4,38,'Combat'),(8,4,38,'Combat'), +(2,3,51,'Survival'),(3,3,51,'Survival'),(4,3,51,'Survival'),(6,3,51,'Survival'),(8,3,51,'Survival'), +(1,5,56,'Holy'),(3,5,56,'Holy'),(4,5,56,'Holy'),(5,5,56,'Holy'),(8,5,56,'Holy'),(1,2,594,'Holy'),(3,2,594,'Holy'), +(3,1,101,'Dwarven Racial'),(3,2,101,'Dwarven Racial'),(3,3,101,'Dwarven Racial'),(3,4,101,'Dwarven Racial'),(3,5,101,'Dwarven Racial'), +(6,1,124,'Tauren Racial'),(6,3,124,'Tauren Racial'),(6,7,124,'Tauren Racial'),(6,11,124,'Tauren Racial'), +(2,1,125,'Orc Racial'),(2,3,125,'Orc Racial'),(2,4,125,'Orc Racial'),(2,7,125,'Orc Racial'),(2,9,125,'Orc Racial'), +(4,1,126,'Night Elf Racial'),(4,3,126,'Night Elf Racial'),(4,4,126,'Night Elf Racial'),(4,5,126,'Night Elf Racial'),(4,11,126,'Night Elf Racial'), +(2,3,163,'Marksmanship'),(3,3,163,'Marksmanship'),(4,3,163,'Marksmanship'),(6,3,163,'Marksmanship'),(8,3,163,'Marksmanship'), +(5,1,220,'Racial - Undead'),(5,4,220,'Racial - Undead'),(5,5,220,'Racial - Undead'),(5,8,220,'Racial - Undead'),(5,9,220,'Racial - Undead'), +(1,4,253,'Assassination'),(2,4,253,'Assassination'),(3,4,253,'Assassination'),(4,4,253,'Assassination'),(5,4,253,'Assassination'),(7,4,253,'Assassination'),(8,4,253,'Assassination'), +(1,9,354,'Demonology'),(2,9,354,'Demonology'),(5,9,354,'Demonology'),(7,9,354,'Demonology'),(2,7,374,'Restoration'), +(6,7,374,'Restoration'),(8,7,374,'Restoration'),(4,11,573,'Restoration'),(6,11,573,'Restoration'), +(2,7,375,'Elemental Combat'),(6,7,375,'Elemental Combat'),(8,7,375,'Elemental Combat'), +(4,11,574,'Balance'),(6,11,574,'Balance'), +(1,9,593,'Destruction'),(2,9,593,'Destruction'),(5,9,593,'Destruction'),(7,9,593,'Destruction'), +(8,1,733,'Racial - Troll'),(8,3,733,'Racial - Troll'),(8,4,733,'Racial - Troll'),(8,5,733,'Racial - Troll'),(8,7,733,'Racial - Troll'),(8,8,733,'Racial - Troll'), +(7,1,753,'Racial - Gnome'),(7,4,753,'Racial - Gnome'),(7,8,753,'Racial - Gnome'),(7,9,753,'Racial - Gnome'), +(1,1,754,'Racial - Human'),(1,2,754,'Racial - Human'),(1,4,754,'Racial - Human'),(1,5,754,'Racial - Human'),(1,8,754,'Racial - Human'),(1,9,754,'Racial - Human'); diff --git a/sql/updates/0.7/3296_spell_learn_skill.sql b/sql/updates/0.7/3296_spell_learn_skill.sql new file mode 100644 index 000000000..aafd633db --- /dev/null +++ b/sql/updates/0.7/3296_spell_learn_skill.sql @@ -0,0 +1,57 @@ +DROP TABLE IF EXISTS `spell_learn_skill`; +CREATE TABLE `spell_learn_skill` ( + `entry` smallint(6) unsigned NOT NULL default '0', + `SkillID` smallint(6) NOT NULL default '0', + `Value` int(11) default '0', + `MaxValue` int(11) default '0', + PRIMARY KEY (`entry`), + UNIQUE KEY spell_skill(`entry`,`SkillID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +INSERT INTO `spell_learn_skill` VALUES +/*================== Armor ============*/ +/*Cloth */( 9078,415, 1, 1), +/*Leather */( 9077,414, 1, 1), +/*Mail */( 8737,413, 1, 1), +/*Plate Mail */( 750,293, 1, 1), +/*Shield */( 9116,433, 1, 1), +/*================== Melee Weapons ====*/ +/*Axes */( 196, 44, 1, 0), +/*Two-Handed Axes */( 197,172, 1, 0), +/*Staves */( 227,136, 1, 0), +/*Maces */( 198, 54, 1, 0), +/*Two-Handed Maces */( 199,160, 1, 0), +/*Swords */( 201, 43, 1, 0), +/*Two-Handed Swords*/( 202, 55, 1, 0), +/*Daggers */( 1180,173, 1, 0), +/*Fist Weapons */(15590,473, 1, 0), +/*Polearms */( 200,229, 1, 0), +/*Spears (Polearms)*/( 3386,229, 1, 0), +/*================== Range Weapons ====*/ +/*Bows */( 264, 45, 1, 0), +/*Crossbows */( 5011,226, 1, 0), +/*Guns */( 266, 46, 1, 0), +/*Thrown */( 2567,176, 1, 0), +/*Wands */( 5009,228, 1, 0), +/*================== Others ===========*/ +/*Poisons */( 2842, 40, 1, 0), +/*Min riding */(33388,762, 75, 75), +/*Mid riding */(33391,762,150,150), +/*Pick Lock(Rogue) */( 1804,633, 1, 0), +/*================== Languages ========*/ + ( 668, 98, -1, -1), + ( 669,109, -1, -1), + ( 670,115, -1, -1), + ( 671,113, -1, -1), + ( 672,111, -1, -1), + ( 813,137, -1, -1), + ( 814,138, -1, -1), + ( 815,139, -1, -1), + ( 816,140, -1, -1), + ( 817,141, -1, -1), + ( 7340,313, -1, -1), + ( 7341,315, -1, -1), + (17737,673, -1, -1), +/*================== Generic Skills ===*/ +/*Defense */( 204, 95, 1, 0), +/*Unarmed */( 203,162, 1, 0); diff --git a/sql/updates/0.7/3310_spell_learn_spell.sql b/sql/updates/0.7/3310_spell_learn_spell.sql new file mode 100644 index 000000000..28bb02e29 --- /dev/null +++ b/sql/updates/0.7/3310_spell_learn_spell.sql @@ -0,0 +1,61 @@ +DROP TABLE IF EXISTS `spell_learn_spell`; +CREATE TABLE `spell_learn_spell` ( + `entry` smallint(6) unsigned NOT NULL default '0', + `SpellID` smallint(6) unsigned NOT NULL default '0', + `IfNoSpell` smallint(6) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`SpellID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +INSERT INTO `spell_learn_spell` VALUES +/*SKILL_ENGINERING*/ +(4036,3918,0), +(4036,3919,0), +(4036,3920,0), +/*SKILL_TAILORING*/ +(3908,2387,0), +(3908,2963,0), +/*SKILL_ENCHANTING*/ +(7411,7418,0), +(7411,7421,0), +(7411,13262,0), +/*SKILL_ALCHEMY*/ +(2259,2329,0), +(2259,7183,0), +(2259,2330,0), +/*SKILL_BLACKSMITHING*/ +(2018,2663,0), +(2018,12260,0), +(2018,2660,0), +(2018,3115,0), +/*SKILL_LEATHERWORKING*/ +(2108,2152,0), +(2108,9058,0), +(2108,9059,0), +(2108,2149,0), +(2108,7126,0), +(2108,2881,0), +/*SKILL_COOKING*/ +(2550,818,0), +(2550,2540,0), +(2550,2538,0), +(2550,8604,0), +/*SKILL_FIRST_AID*/ +(3273,3275,0), +/*SKILL_FISHING*/ +(7620,7738,0), +/*SKILL_MINING*/ +(2575,2580,0), +(2575,2656,0), +(2575,2657,0), +/*SKILL_HERBALISM*/ +(2366,2383,0), +/*SKILL_BOWS*/ +(264,2480,75), +/*SKILL_GUNS*/ +(266,7918,75), +/*SKILL_CROSSBOWS*/ +(5011,7919,75), +/*SKILL_THROWN*/ +(2567,2764,0), +/*SKILL_POISONS*/ +(2842,8681,0); diff --git a/sql/updates/0.7/3316_playercreateinfo_reputation.sql b/sql/updates/0.7/3316_playercreateinfo_reputation.sql new file mode 100644 index 000000000..6ca054e39 --- /dev/null +++ b/sql/updates/0.7/3316_playercreateinfo_reputation.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `playercreateinfo_reputation`; diff --git a/sql/updates/0.7/3323.sql b/sql/updates/0.7/3323.sql new file mode 100644 index 000000000..d0ea3e6c4 --- /dev/null +++ b/sql/updates/0.7/3323.sql @@ -0,0 +1,31 @@ +ALTER TABLE `character_pet` + ADD COLUMN `slot` tinyint(1) unsigned NOT NULL default '0', + CHANGE COLUMN `id` `id` int(11) unsigned NOT NULL default '0'; + +UPDATE `character_pet` + SET `slot` = 0 WHERE `current` = 1; + +/* slot 3 = for storing warlock and another not stabled pets */ +UPDATE `character_pet` + SET `slot` = 3 WHERE `current` = 0; + +/* current = (`slot`==0) */ +ALTER TABLE `character_pet` + DROP COLUMN `current`; + +UPDATE `character_pet`, `character_stable` + SET `character_pet`.`slot` =`character_stable`.`slot` + WHERE `character_pet`.`id`=`character_stable`.`petnumber` + AND `character_pet`.`owner`=`character_stable`.`owner` AND `character_pet`.`id`=`character_stable`.`petnumber`; + +ALTER TABLE `character` + ADD COLUMN `stable_slots` tinyint(1) unsigned NOT NULL default '0'; + +UPDATE `character`, ( + SELECT `character_stable`.`owner` as `owner_slots`, MAX(`character_stable`.`slot`) as `slots` FROM `character_stable` GROUP BY `character_stable`.`owner` + ) as `stable_slots` + SET `character`.`stable_slots`= `stable_slots`.`slots` + WHERE `character`.`guid` = `stable_slots`.`owner_slots`; + + +DROP TABLE IF EXISTS `character_stable`; diff --git a/sql/updates/0.7/3344_playercreateinfo_spell.sql b/sql/updates/0.7/3344_playercreateinfo_spell.sql new file mode 100644 index 000000000..a43a903ac --- /dev/null +++ b/sql/updates/0.7/3344_playercreateinfo_spell.sql @@ -0,0 +1,13 @@ +INSERT INTO `playercreateinfo_spell` VALUES ('1','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('2','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('3','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('4','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('5','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('6','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('7','1','21156','Battle Stance Passive',0); +INSERT INTO `playercreateinfo_spell` VALUES ('8','1','21156','Battle Stance Passive',0); + +INSERT IGNORE INTO `character_spell` +SELECT `character`.`guid`,`playercreateinfo_spell`.`spell` AS `spell`, '65535' AS `slot`,`playercreateinfo_spell`.`Active` AS `active` +FROM `character`,`playercreateinfo_spell` +WHERE `character`.`class`=`playercreateinfo_spell`.`class` AND `character`.`race`=`playercreateinfo_spell`.`race`; \ No newline at end of file diff --git a/sql/updates/0.7/3346_command.sql b/sql/updates/0.7/3346_command.sql new file mode 100644 index 000000000..39ae5e182 --- /dev/null +++ b/sql/updates/0.7/3346_command.sql @@ -0,0 +1,4 @@ +UPDATE `command` SET `name`='lookupobject' WHERE `name`='.lookupobject'; +UPDATE `command` SET `name`='listcreature' WHERE `name`='.listcreature'; +UPDATE `command` SET `name`='listobject' WHERE `name`='.listobject'; +UPDATE `command` SET `name`='listitem' WHERE `name`='.listitem'; diff --git a/sql/updates/0.7/3348_playercreateinfo_spell.sql b/sql/updates/0.7/3348_playercreateinfo_spell.sql new file mode 100644 index 000000000..d0f541002 --- /dev/null +++ b/sql/updates/0.7/3348_playercreateinfo_spell.sql @@ -0,0 +1,7 @@ +INSERT INTO `playercreateinfo_spell` VALUES ('4','11','21178','Bear Form (Passive2)',0); +INSERT INTO `playercreateinfo_spell` VALUES ('6','11','21178','Bear Form (Passive2)',0); + +INSERT IGNORE INTO `character_spell` +SELECT `character`.`guid`,`playercreateinfo_spell`.`spell` AS `spell`, '65535' AS `slot`,`playercreateinfo_spell`.`Active` AS `active` +FROM `character`,`playercreateinfo_spell` +WHERE `character`.`class`=`playercreateinfo_spell`.`class` AND `character`.`race`=`playercreateinfo_spell`.`race`; \ No newline at end of file diff --git a/sql/updates/0.7/3350_command.sql b/sql/updates/0.7/3350_command.sql new file mode 100644 index 000000000..eecf98014 --- /dev/null +++ b/sql/updates/0.7/3350_command.sql @@ -0,0 +1,7 @@ +DELETE FROM `command` WHERE `name` = 'item'; +DELETE FROM `command` WHERE `name` = 'itemrmv'; +DELETE FROM `command` WHERE `name` = 'addvendoritem'; +DELETE FROM `command` WHERE `name` = 'delvendoritem'; + +INSERT INTO `command` VALUES('addvendoritem',2,'Syntax: .addvendoritem #itemId <#maxcount><#incrtime>\r\n\r\nAdd item #itemid to item list of selected vendor. Also optionally set max count item in vendor item list and time to item count restoring.'); +INSERT INTO `command` VALUES('delvendoritem',2,'Syntax: .delvendoritem #itemId\r\n\r\nRemove item #itemid from item list of selected vendor.'); diff --git a/sql/updates/0.7/3351_character_pet.sql b/sql/updates/0.7/3351_character_pet.sql new file mode 100644 index 000000000..2b7f4e634 --- /dev/null +++ b/sql/updates/0.7/3351_character_pet.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character_pet` + ADD COLUMN `curhealth` int(11) unsigned NOT NULL default '1', + ADD COLUMN `curmana` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.7/3397_creature_template.sql b/sql/updates/0.7/3397_creature_template.sql new file mode 100644 index 000000000..4363e6bb2 --- /dev/null +++ b/sql/updates/0.7/3397_creature_template.sql @@ -0,0 +1,12 @@ +ALTER TABLE `creature_template` + ADD COLUMN `InhabitType` tinyint(1) unsigned NOT NULL default '3' AFTER `MovementType`; + +/* +0 - not used +1 - can walk (or fly above ground) +2 - can swim (or fly above water) +3 (= 1 | 2) - can walk and swim (and fly) +*/ + +UPDATE `creature_template` + SET `InhabitType` = 1 WHERE `family` > 0 AND `family` < 6 OR `family` = 8 OR `family` = 11 OR `family` > 14 AND `family` < 20 OR `family` = 25 OR `family` = 27; diff --git a/sql/updates/0.7/3400.sql b/sql/updates/0.7/3400.sql new file mode 100644 index 000000000..3ef216430 --- /dev/null +++ b/sql/updates/0.7/3400.sql @@ -0,0 +1,75 @@ +TRUNCATE TABLE `corpse`; +TRUNCATE TABLE `creature_respawn`; +TRUNCATE TABLE `gameobject_respawn`; + +DROP TABLE IF EXISTS `instance`; +CREATE TABLE `instance` ( + `id` int(11) unsigned NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0', + `resettime` bigint(40) NOT NULL default '0', + PRIMARY KEY (`id`), + KEY `map` (`map`), + KEY `resettime` (`resettime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `character_instance`; +CREATE TABLE `character_instance` ( + `guid` int(11) unsigned NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0', + `instance` bigint(40) NOT NULL default '0', + `leader` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`map`), + KEY `instance` (`instance`), + KEY `leader` (`leader`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `creature_respawn` ADD `instance` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `creature_respawn` DROP PRIMARY KEY; +ALTER TABLE `creature_respawn` ADD PRIMARY KEY (`guid`, `instance`); + +ALTER TABLE `gameobject_respawn` ADD `instance` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `gameobject_respawn` DROP PRIMARY KEY; +ALTER TABLE `gameobject_respawn` ADD PRIMARY KEY (`guid`, `instance`); + +ALTER TABLE `corpse` ADD `instance` int(11) unsigned NOT NULL default '0'; + +DROP TABLE IF EXISTS `instance_template`; +CREATE TABLE `instance_template` ( + `map` int(11) unsigned NOT NULL, + `levelMin` int(11) unsigned NOT NULL default '0', + `levelMax` int(11) unsigned NOT NULL default '0', + `maxPlayers` int(11) unsigned NOT NULL default '0', + `reset_delay` int(20) unsigned NOT NULL default '0', + `startLocX` float default NULL, + `startLocY` float default NULL, + `startLocZ` float default NULL, + `startLocO` float default NULL, + PRIMARY KEY (`map`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `instance_template` VALUES (33, 22, 30, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (34, 24, 32, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (36, 15, 20, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (43, 15, 21, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (47, 29, 38, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (48, 24, 32, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (70, 35, 47, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (90, 29, 38, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (109, 45, 55, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (129, 37, 46, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (189, 34, 45, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (209, 44, 54, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (229, 58, 0, 10, 120000, 78.5083, -225.044, 49.839, 5.1); +INSERT INTO `instance_template` VALUES (230, 52, 0, 5, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (249, 60, 0, 40, 432000, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (289, 57, 0, 5, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (309, 60, 0, 20, 259200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (329, 58, 60, 5, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (349, 46, 55, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (389, 13, 18, 10, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (409, 60, 0, 40, 604800, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (429, 55, 60, 5, 7200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (469, 60, 0, 40, 604800, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (509, 60, 0, 20, 259200, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (531, 60, 0, 40, 604800, NULL, NULL, NULL, NULL); +INSERT INTO `instance_template` VALUES (533, 60, 0, 40, 604800, NULL, NULL, NULL, NULL); diff --git a/sql/updates/0.7/3402_creature_onkill_reputation.sql b/sql/updates/0.7/3402_creature_onkill_reputation.sql new file mode 100644 index 000000000..0fa7b80cd --- /dev/null +++ b/sql/updates/0.7/3402_creature_onkill_reputation.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS `creature_onkill_reputation`; +CREATE TABLE `creature_onkill_reputation` ( + `creature_id` int(10) unsigned NOT NULL default '0' COMMENT 'Creature Identifier', + `RewOnKillRepFaction1` int(10) default '0', + `RewOnKillRepFaction2` int(10) default '0', + `MaxStanding1` int(1) default '0', + `IsTeamAward1` int(1) default '0', + `RewOnKillRepValue1` int(10) default '0', + `MaxStanding2` int(1) default '0', + `IsTeamAward2` int(1) default '0', + `RewOnKillRepValue2` int(10) default '0', + PRIMARY KEY (`creature_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Creature OnKill Reputation gain'; diff --git a/sql/updates/0.7/3410_group.sql b/sql/updates/0.7/3410_group.sql new file mode 100644 index 000000000..c217cc965 --- /dev/null +++ b/sql/updates/0.7/3410_group.sql @@ -0,0 +1,7 @@ +RENAME TABLE `raidgroup` TO `group` ; +ALTER TABLE `group` COMMENT = 'Groups'; +ALTER TABLE `group` ADD `isRaid` TINYINT( 1 ) NOT NULL; +UPDATE `group` SET `isRaid` = 1; + +RENAME TABLE `raidgroup_member` TO `group_member`; +ALTER TABLE `group_member` COMMENT = 'Groups'; diff --git a/sql/updates/0.7/3424_command.sql b/sql/updates/0.7/3424_command.sql new file mode 100644 index 000000000..8bbab6311 --- /dev/null +++ b/sql/updates/0.7/3424_command.sql @@ -0,0 +1,11 @@ +UPDATE `command` + SET `help` = 'Syntax: .modify $parameter $value Modify the value of various parameters. Use .help modify $parameter to get help on specific parameter usage. Supported parameters include hp, mana, rage, energy, money, speed, swim, scale, bit, bwalk, aspeed, faction, spell and tp.' + WHERE `name` = 'modify' LIMIT 1 ; + +UPDATE `command` + SET `help` = 'Syntax: .aura #spellid Add the aura from spell #spellid to the selected Unit.' + WHERE `name` = 'aura' LIMIT 1 ; + +UPDATE `command` + SET `help` = 'Syntax: .unaura #spellid Remove aura due to spell #spellid from the selected Unit.' + WHERE `name` = 'unaura' LIMIT 1 ; diff --git a/sql/updates/0.7/3463_mangos.sql b/sql/updates/0.7/3463_mangos.sql new file mode 100644 index 000000000..119650fc7 --- /dev/null +++ b/sql/updates/0.7/3463_mangos.sql @@ -0,0 +1,116 @@ +ALTER TABLE `guild` CHANGE `EmblemStyle` `EmblemStyle` INT( 5 ) NOT NULL DEFAULT '0', +CHANGE `EmblemColor` `EmblemColor` INT( 5 ) NOT NULL DEFAULT '0', +CHANGE `BorderStyle` `BorderStyle` INT( 5 ) NOT NULL DEFAULT '0', +CHANGE `BorderColor` `BorderColor` INT( 5 ) NOT NULL DEFAULT '0', +CHANGE `BackgroundColor` `BackgroundColor` INT( 5 ) NOT NULL DEFAULT '0'; + +ALTER TABLE `item_template` ADD `unk_203` INT(10) NOT NULL default '0' AFTER `sheath`; +ALTER TABLE `item_template` CHANGE `Unknown1` `Map` INT( 10 ) NOT NULL DEFAULT '0'; +ALTER TABLE `item_template` CHANGE `BagFamily` `BagFamily` INT( 10 ) NOT NULL DEFAULT '0' AFTER `Map`; +ALTER TABLE `item_template` ADD `TotemCategory` INT( 10 ) NOT NULL DEFAULT '0' AFTER `BagFamily`, +ADD `socketColor_1` INT( 10 ) NOT NULL DEFAULT '0' AFTER `TotemCategory`, +ADD `socketContent_1` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketColor_1`, +ADD `socketColor_2` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketContent_1`, +ADD `socketContent_2` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketColor_2`, +ADD `socketColor_3` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketContent_2`, +ADD `socketContent_3` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketColor_3`, +ADD `socketBonus` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketContent_3`, +ADD `GemProperties` INT( 10 ) NOT NULL DEFAULT '0' AFTER `socketBonus`, +ADD `ExtendedCost` INT( 10 ) NOT NULL DEFAULT '0' AFTER `GemProperties`, +ADD `RequiredDisenchantSkill` INT( 10 ) NOT NULL DEFAULT '-1' AFTER `ExtendedCost`; + +UPDATE `item_template` SET `TotemCategory` = '11' WHERE `entry` = '2901'; +UPDATE `item_template` SET `TotemCategory` = '1' WHERE `entry` = '7005'; +UPDATE `item_template` SET `TotemCategory` = '1' WHERE `entry` = '12709'; +UPDATE `item_template` SET `TotemCategory` = '2' WHERE `entry` = '5175'; +UPDATE `item_template` SET `TotemCategory` = '4' WHERE `entry` = '5176'; +UPDATE `item_template` SET `TotemCategory` = '5' WHERE `entry` = '5177'; +UPDATE `item_template` SET `TotemCategory` = '3' WHERE `entry` = '5178'; + +ALTER TABLE `character_kill` CHANGE `guid` `guid` SMALLINT( 4 ) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier' ; +ALTER TABLE `character_kill` DROP `type` ; +ALTER TABLE `character` DROP `highest_rank` , DROP `standing` , DROP `rating` ; + +insert into `playercreateinfo_spell` values +(10,2,7355,'Stuck',1), +(10,3,7355,'Stuck',1), +(10,4,7355,'Stuck',1), +(10,5,7355,'Stuck',1), +(10,8,7355,'Stuck',1), +(10,9,7355,'Stuck',1), +(11,1,7355,'Stuck',1), +(11,2,7355,'Stuck',1), +(11,3,7355,'Stuck',1), +(11,5,7355,'Stuck',1), +(11,7,7355,'Stuck',1), +(11,8,7355,'Stuck',1); + +ALTER TABLE `group` CHANGE `leaderGuid` `leaderGuid` INT( 20 ) NOT NULL , +CHANGE `looterGuid` `looterGuid` INT( 20 ) NOT NULL ; +ALTER TABLE `group_member` CHANGE `leaderGuid` `leaderGuid` INT( 20 ) NOT NULL , +CHANGE `memberGuid` `memberGuid` INT( 20 ) NOT NULL ; +ALTER TABLE `group` ADD `mainTank` INT(20) NOT NULL AFTER `leaderGuid` , +ADD `mainAssistant` INT(20) NOT NULL AFTER `mainTank` ; + +CREATE TABLE `looking_for_group` ( + `guid` int(12) unsigned NOT NULL default '0', + `slot` smallint(2) unsigned NOT NULL default '0', + `entry` int(12) unsigned NOT NULL default '0', + `type` smallint(2) unsigned NOT NULL default '0', + `lfg_type` smallint(2) unsigned NOT NULL default '0', + `comment` text NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +UPDATE `creature_template` SET `npcflag`='33' WHERE `name`='Spirit Healer'; + +ALTER TABLE `playercreateinfo` DROP `displayID`; + +ALTER TABLE `quest_template` +CHANGE `OfferRewardEmote` `IncompleteEmote` int(11) unsigned NOT NULL default '0', +CHANGE `RequestItemsEmote` `CompleteEmote` int(11) unsigned NOT NULL default '1'; +ALTER TABLE `quest_template` +ADD `DetailsEmote1` int(11) NOT NULL default '0' AFTER `PointOpt`, +ADD `DetailsEmote2` int(11) NOT NULL default '0' AFTER `DetailsEmote1`, +ADD `DetailsEmote3` int(11) NOT NULL default '0' AFTER `DetailsEmote2`, +ADD `DetailsEmote4` int(11) NOT NULL default '0' AFTER `DetailsEmote3`, +ADD `OfferRewardEmote1` int(11) NOT NULL default '0' AFTER `CompleteEmote`, +ADD `OfferRewardEmote2` int(11) NOT NULL default '0' AFTER `OfferRewardEmote1`, +ADD `OfferRewardEmote3` int(11) NOT NULL default '0' AFTER `OfferRewardEmote2`, +ADD `OfferRewardEmote4` int(11) NOT NULL default '0' AFTER `OfferRewardEmote3`; + +ALTER TABLE `item_template` ADD `unk0` INT( 10 ) NOT NULL DEFAULT '-1' AFTER `subclass`; + +ALTER TABLE `group` ADD `lootThreshold` tinyint(4) NOT NULL AFTER `looterGuid`; + +ALTER TABLE `creature_template` CHANGE `equipslot1` `equipslot1` INTEGER NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `equipslot2` `equipslot2` INTEGER NOT NULL DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE `equipslot3` `equipslot3` INTEGER NOT NULL DEFAULT '0'; + +CREATE TABLE `arena_team` ( + `guid` int(10) unsigned NOT NULL default '0', + `slot` tinyint(3) unsigned NOT NULL default '0', + `name` char(255) NOT NULL, + `type` tinyint(3) unsigned NOT NULL default '0', + `rank` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `arena_team_member` ( + `guid` int(10) unsigned NOT NULL default '0', + `teamslot` tinyint(3) unsigned NOT NULL default '0', + `teamguid` int(10) unsigned NOT NULL default '0', + `rating` int(10) unsigned NOT NULL default '0', + `games` int(10) unsigned NOT NULL default '0', + `wins` int(10) unsigned NOT NULL default '0', + `played` int(10) unsigned NOT NULL default '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DELETE FROM `gameobject` WHERE `map`='489'; +UPDATE `gameobject_template` SET `flags` = '0', `type` = '26' WHERE `entry` IN (179785, 179786); +UPDATE `gameobject_template` SET `flags` = '0' WHERE `entry` IN (179830, 179831); + +alter table `creature` change `state` `DeathState` tinyint(3) unsigned not null default '0'; + +alter table `creature_template` drop `mount`; + +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES ('modify titles', '1', 'Syntax:\n.modify titles #mask\n.titles #mask\n\nAllows user to use all titles from #mask.\n\n #mask=0 disables the title-choose-field'); +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES ('titles', '1', 'Syntax:\n.modify titles #mask\n.titles #mask\n\nAllows user to use all titles from #mask.\n\n #mask=0 disables the title-choose-field'); diff --git a/sql/updates/0.7/3463_realm.sql b/sql/updates/0.7/3463_realm.sql new file mode 100644 index 000000000..b33b92d67 --- /dev/null +++ b/sql/updates/0.7/3463_realm.sql @@ -0,0 +1 @@ +ALTER TABLE `account` ADD `tbc` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `online`; diff --git a/sql/updates/0.7/3474_creature_addon.sql b/sql/updates/0.7/3474_creature_addon.sql new file mode 100644 index 000000000..d03b65a53 --- /dev/null +++ b/sql/updates/0.7/3474_creature_addon.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS `creature_addon`; +CREATE TABLE `creature_addon` ( + `entry` int(11) NOT NULL default '0', + `RefId` int(11) NOT NULL default '0', + `mount` int(11) unsigned NOT NULL default '0', + `bytes0` int(11) unsigned NOT NULL default '0', + `bytes1` int(11) unsigned NOT NULL default '0', + `bytes2` int(11) unsigned NOT NULL default '0', + `emote` int(11) unsigned NOT NULL default '0', + `aura` int(11) unsigned NOT NULL default '0', + `auraflags` int(11) unsigned NOT NULL default '0', + `auralevels` int(11) unsigned NOT NULL default '0', + `auraapplications` int(11) unsigned NOT NULL default '0', + `aurastate` int(11) unsigned NOT NULL default '0', + UNIQUE KEY `guid` (`Entry`), + KEY `emote` (`emote`,`RefId`,`mount`,`aura`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/sql/updates/0.7/3501.sql b/sql/updates/0.7/3501.sql new file mode 100644 index 000000000..6b88153e0 --- /dev/null +++ b/sql/updates/0.7/3501.sql @@ -0,0 +1,37 @@ +-- +-- Enhancements to the waypoint system +-- +-- text1..tex5 -> Mob can say up to five texts (one is choosen) +-- aiscript -> An AI script can be executed, when the mob reaches a waypoint, see wpAI.h +-- emote -> a mob can do an emote, eg cutting wood, laughing, etc (make sure you set a waittime, otherwise emote may be omitted) +-- spell -> mob can cast a spell, when he reaches a waypoint +-- wpguid -> if the GM wants to see the waypoints, whisps are spawned, which can only be seen by a GM +-- The GUID of the whisp is stored here +ALTER TABLE `creature_movement` ADD COLUMN `text1` varchar(255) default NULL AFTER `waittime`, +ADD COLUMN `text2` varchar(255) default NULL AFTER `text1`, +ADD COLUMN `text3` varchar(255) default NULL AFTER `text2`, +ADD COLUMN `text4` varchar(255) default NULL AFTER `text3`, +ADD COLUMN `text5` varchar(255) default NULL AFTER `text4`, +ADD COLUMN `aiscript` varchar(255) default NULL AFTER `text5`, +ADD COLUMN `emote` int(10) unsigned default '0' AFTER `aiscript`, +ADD COLUMN `spell` int(5) unsigned default '0' AFTER `emote`, +ADD COLUMN `wpguid` int(11) default '0' AFTER `spell`; + +-- The visual waypoint +DELETE FROM creature_template WHERE entry='1'; +INSERT INTO creature_template + (entry, modelid_m, modelid_f, name, subname, minlevel, maxlevel, minhealth, maxhealth, minmana, maxmana, armor, faction, npcflag, speed, rank, mindmg, maxdmg, attackpower, baseattacktime, rangeattacktime, flags, dynamicflags, size, family, bounding_radius, trainer_type, trainer_spell, class, race, minrangedmg, maxrangedmg, rangedattackpower, combat_reach, type, civilian, flag1, equipmodel1, equipmodel2, equipmodel3, equipinfo1, equipinfo2, equipinfo3, equipslot1, equipslot2, equipslot3, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, mingold, maxgold, AIName, MovementType, ScriptName) +VALUES + (1, 10045, 0, 'Waypoint (Only GM can see it)', 'Visual', 1, 1, 64, 64, 0, 0, 0, 35, 0, '0.91', 0, 14, 15, 100, 2000, 2200, 4096, 0, '0.5', 8, 2, 0, 0, 0, 0, '1.76', '2.42', 100, '2.56', 8, 1, 5242886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, ''); + +-- New commands +DELETE FROM `command` where `name` = 'wp' and `security` = '2'; +DELETE FROM `command` where `name` = 'wp add' and `security` = '2'; +DELETE FROM `command` where `name` = 'wp modify' and `security` = '2'; +DELETE FROM `command` where `name` = 'wp show' and `security` = '2'; + +INSERT INTO command (name, security, help) VALUES +("wp", 2, "Using WP Command:\r\nEach Waypoint Command has it's own description!"), +("wp add", 2, "Syntax: .wp add [#creature_guid or Select a Creature]"), +("wp modify", 2, "Syntax: .wp modify [#creature_guid or Select a Creature]\r\nadd - Add a waypoint after the selected visual\r\nimport $filename for selected npc\r\nexport $filename for selected npc\r\nwaittime $time\r\nemote ID\r\nspell ID\r\ntext1| text2| text3| text4| text5 \r\nmodel1 ID\r\nmodel2 ID\r\naiscript $Name\r\nmove(moves wp to player pos)\r\ndel (deletes the wp)\r\n\r\nOnly one parameter per time!"), +("wp show", 2, "Syntax: .wp show [#creature_guid or Select a Creature]\r\non\r\nfirst\r\nlast\r\noff\r\ninfo\r\n\r\nFor using info you have to do first show on and than select a Visual-Waypoint and do the show info!"); diff --git a/sql/updates/0.7/3503_creature_movement.sql b/sql/updates/0.7/3503_creature_movement.sql new file mode 100644 index 000000000..b92a54746 --- /dev/null +++ b/sql/updates/0.7/3503_creature_movement.sql @@ -0,0 +1,7 @@ +-- +-- Enhancements to the waypoint system +-- +-- Sorry for having forgotten to add this to the svn. +ALTER TABLE `creature_movement` ADD COLUMN `orientation` float default 0 AFTER `wpguid`; +ALTER TABLE `creature_movement` ADD COLUMN `model1` int (11) default 0 AFTER `orientation`; +ALTER TABLE `creature_movement` ADD COLUMN `model2` int (11) default 0 AFTER `model1`; diff --git a/sql/updates/0.7/3512_character_spell_cooldown.sql b/sql/updates/0.7/3512_character_spell_cooldown.sql new file mode 100644 index 000000000..8fc95b3da --- /dev/null +++ b/sql/updates/0.7/3512_character_spell_cooldown.sql @@ -0,0 +1 @@ +ALTER TABLE `character_spell_cooldown` ADD COLUMN `item` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier' AFTER `spell`; diff --git a/sql/updates/0.7/3514_mail.sql b/sql/updates/0.7/3514_mail.sql new file mode 100644 index 000000000..f3ebf9744 --- /dev/null +++ b/sql/updates/0.7/3514_mail.sql @@ -0,0 +1,3 @@ +ALTER TABLE `mail` + CHANGE COLUMN `time` `expire_time` bigint(40) NOT NULL default '0', + ADD `deliver_time` bigint(40) NOT NULL default '0' AFTER `expire_time`; diff --git a/sql/updates/0.7/3516_spell_learn_spell.sql b/sql/updates/0.7/3516_spell_learn_spell.sql new file mode 100644 index 000000000..872be29cd --- /dev/null +++ b/sql/updates/0.7/3516_spell_learn_spell.sql @@ -0,0 +1,4 @@ +insert into `spell_learn_spell`(`entry`,`SpellID`,`IfNoSpell`) values (25229,25255,0); +insert into `spell_learn_spell`(`entry`,`SpellID`,`IfNoSpell`) values (25229,25493,0); +insert into `spell_learn_spell`(`entry`,`SpellID`,`IfNoSpell`) values (25229,26925,0); +insert into `spell_learn_spell`(`entry`,`SpellID`,`IfNoSpell`) values (25229,32259,0); diff --git a/sql/updates/0.7/3533_command.sql b/sql/updates/0.7/3533_command.sql new file mode 100644 index 000000000..321c834e2 --- /dev/null +++ b/sql/updates/0.7/3533_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET `help` = 'Syntax: .createguild $GuildLeaderName $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName as leader.' WHERE `name` ='createguild'; diff --git a/sql/updates/0.7/3538_guild_charter_sign.sql b/sql/updates/0.7/3538_guild_charter_sign.sql new file mode 100644 index 000000000..ad2c482d3 --- /dev/null +++ b/sql/updates/0.7/3538_guild_charter_sign.sql @@ -0,0 +1,6 @@ +ALTER TABLE `guild_charter_sign` + ADD `player_account` int(11) unsigned NOT NULL default '0' AFTER `playerguid`; + +UPDATE `guild_charter_sign`,`character` + SET `guild_charter_sign`.`player_account` = `character`.`account` + WHERE `guild_charter_sign`.`playerguid` = `character`.`guid`; diff --git a/sql/updates/0.7/3539_item_template.sql b/sql/updates/0.7/3539_item_template.sql new file mode 100644 index 000000000..c2e3c4880 --- /dev/null +++ b/sql/updates/0.7/3539_item_template.sql @@ -0,0 +1,12 @@ +ALTER TABLE `item_template` + CHANGE `spellcooldown_1` `spellcooldown_1` int(30) NOT NULL default '-1', + CHANGE `spellcategorycooldown_1` `spellcategorycooldown_1` int(30) NOT NULL default '-1', + CHANGE `spellcooldown_2` `spellcooldown_2` int(30) NOT NULL default '-1', + CHANGE `spellcategorycooldown_2` `spellcategorycooldown_2` int(30) NOT NULL default '-1', + CHANGE `spellcooldown_3` `spellcooldown_3` int(30) NOT NULL default '-1', + CHANGE `spellcategorycooldown_3` `spellcategorycooldown_3` int(30) NOT NULL default '-1', + CHANGE `spellcooldown_4` `spellcooldown_4` int(30) NOT NULL default '-1', + CHANGE `spellcategorycooldown_4` `spellcategorycooldown_4` int(30) NOT NULL default '-1', + CHANGE `spellcooldown_5` `spellcooldown_5` int(30) NOT NULL default '-1', + CHANGE `spellcategorycooldown_5` `spellcategorycooldown_5` int(30) NOT NULL default '-1', + CHANGE `unk_203` `unk_203` int(10) NOT NULL default '0' AFTER `Extra`; diff --git a/sql/updates/0.7/3545_creature_movement.sql b/sql/updates/0.7/3545_creature_movement.sql new file mode 100644 index 000000000..93733295f --- /dev/null +++ b/sql/updates/0.7/3545_creature_movement.sql @@ -0,0 +1,2 @@ +-- tinyint can only hold values up to 255 - too small for a waittime in milliseconds +ALTER TABLE `creature_movement` CHANGE COLUMN `waittime` `waittime` int(5) unsigned NOT NULL default '0'; \ No newline at end of file diff --git a/sql/updates/0.7/3547_character_reputation.sql b/sql/updates/0.7/3547_character_reputation.sql new file mode 100644 index 000000000..9bdaa8603 --- /dev/null +++ b/sql/updates/0.7/3547_character_reputation.sql @@ -0,0 +1,72 @@ +/* alliance */ +UPDATE `character_reputation`,`character` SET `character_reputation`.`flags` = 17 +WHERE `character_reputation`.`guid` = `character`.`guid` + AND (`character_reputation`.`faction` = 47 or `character_reputation`.`faction` = 54 or `character_reputation`.`faction` = 69 or `character_reputation`.`faction` = 72 or `character_reputation`.`faction` = 930 ) + AND (`character`.`race` = 1 OR `character`.`race` = 3 OR `character`.`race` = 4 OR `character`.`race` = 7 OR `character`.`race` = 11 ); + +/* horde */ +UPDATE `character_reputation`,`character` SET `character_reputation`.`flags` = 17 +WHERE `character_reputation`.`guid` = `character`.`guid` + AND (`character_reputation`.`faction` = 68 or `character_reputation`.`faction` = 76 or `character_reputation`.`faction` = 81 or `character_reputation`.`faction` = 530 or `character_reputation`.`faction` = 911 ) + AND (`character`.`race` = 2 OR `character`.`race` = 5 OR `character`.`race` = 6 OR `character`.`race` = 8 OR `character`.`race` = 10 ); + +/* faction 47 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 47 , 20, '0', '17' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 47 , 20, '0', '2' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 54 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 54 , 18, '0', '17' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 54 , 18, '0', '2' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 68 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 68 , 17, '0', '2' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 68 , 17, '0', '17' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 69 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 69 , 21, '0', '17' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 69 , 21, '0', '2' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 72 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 72 , 19, '0', '17' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 72 , 19, '0', '2' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 76 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 76 , 14, '0', '2' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 76 , 14, '0', '17' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 81 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 81 , 16, '0', '2' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 81 , 16, '0', '17' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 530 */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 530, 15, '0', '2' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 530, 15, '0', '17' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 911 (B.Elf) */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 911, 15, '0', '2' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 911, 15, '0', '17' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + +/* faction 930 (Dra) */ +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 930 , 19, '0', '17' +FROM `character` WHERE `race` = 1 OR `race` = 3 OR `race` = 4 OR `race` = 7 OR `race` = 11; +INSERT IGNORE INTO `character_reputation` SELECT `character`.`guid`, 930 , 19, '0', '2' +FROM `character` WHERE `race` = 2 OR `race` = 5 OR `race` = 6 OR `race` = 8 OR `race` = 10; + diff --git a/sql/updates/0.7/3553_creature_onkill_reputation.sql b/sql/updates/0.7/3553_creature_onkill_reputation.sql new file mode 100644 index 000000000..5d674ba26 --- /dev/null +++ b/sql/updates/0.7/3553_creature_onkill_reputation.sql @@ -0,0 +1,6 @@ +ALTER TABLE `creature_onkill_reputation` + CHANGE COLUMN `MaxStanding1` `MaxStanding1` tinyint(1) default '0', + CHANGE COLUMN `IsTeamAward1` `IsTeamAward1` tinyint(1) default '0', + CHANGE COLUMN `MaxStanding2` `MaxStanding2` tinyint(1) default '0', + CHANGE COLUMN `IsTeamAward2` `IsTeamAward2` tinyint(1) default '0', + ADD COLUMN `TeamDependent` tinyint(1) unsigned NOT NULL default '0' AFTER `RewOnKillRepValue2`; diff --git a/sql/updates/0.7/3562_player_levelstats.sql b/sql/updates/0.7/3562_player_levelstats.sql new file mode 100644 index 000000000..473b9b082 --- /dev/null +++ b/sql/updates/0.7/3562_player_levelstats.sql @@ -0,0 +1,5 @@ +DELETE FROM player_levelstats WHERE race=2 and class=4 and level=19; +DELETE FROM player_levelstats WHERE race=2 and class=4 and level=20; +INSERT INTO player_levelstats VALUES +('2', '4', '19', '391', '0', '38', '44', '35', '20', '30'), +('2', '4', '20', '414', '0', '38', '46', '36', '20', '30'); \ No newline at end of file diff --git a/sql/updates/0.7/3605_creature_addon.sql b/sql/updates/0.7/3605_creature_addon.sql new file mode 100644 index 000000000..09389ec90 --- /dev/null +++ b/sql/updates/0.7/3605_creature_addon.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_addon` + CHANGE COLUMN `entry` `guid` int(11) NOT NULL default '0'; diff --git a/sql/updates/0.7/3605_grid.sql b/sql/updates/0.7/3605_grid.sql new file mode 100644 index 000000000..0b4bd425f --- /dev/null +++ b/sql/updates/0.7/3605_grid.sql @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS `corpse_grid`; +DROP TABLE IF EXISTS `creature_grid`; +DROP TABLE IF EXISTS `gameobject_grid`; diff --git a/sql/updates/0.7/3611_spell_learn_skill.sql b/sql/updates/0.7/3611_spell_learn_skill.sql new file mode 100644 index 000000000..fd929a874 --- /dev/null +++ b/sql/updates/0.7/3611_spell_learn_skill.sql @@ -0,0 +1,5 @@ +-- Add spell_skill for riding 225 and 300 skill +DELETE FROM `spell_learn_skill` WHERE `entry` IN ('34091', '34090'); +INSERT INTO `spell_learn_skill` VALUES ('34091', '762', '300', '300'); +INSERT INTO `spell_learn_skill` VALUES ('34090', '762', '225', '225'); + diff --git a/sql/updates/0.7/3616_commands.sql b/sql/updates/0.7/3616_commands.sql new file mode 100644 index 000000000..f1c34fa54 --- /dev/null +++ b/sql/updates/0.7/3616_commands.sql @@ -0,0 +1,6 @@ +-- Enhanced .addgo / .gameobject command +-- Now the user can also specify and +DELETE FROM `command` WHERE `name` = 'addgo'; +DELETE FROM `command` WHERE `name` = 'gameobject'; +insert into `command` values ('gameobject',3,'Syntax: .gameobject #id \r\n\r\nAdd a game object from game object templates to the world at your current location using the #id.\r\nlootID specifies the loot-template to be used and spawntimeSecs sets the spawntime, both are optional.'); +insert into `command` values ('addgo',3,'Syntax: .addgo #id \r\n\r\nAdd a game object from game object templates to the world at your current location using the #id.\r\nlootID specifies the loot-template to be used and spawntimesecs sets the spawntime, both are optional.\r\n\r\nNote: this is a copy of .gameobject.'); diff --git a/sql/updates/0.7/3627_quest_template.sql b/sql/updates/0.7/3627_quest_template.sql new file mode 100644 index 000000000..790b680d3 --- /dev/null +++ b/sql/updates/0.7/3627_quest_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE `quest_template` ADD COLUMN `ZoneOrSort` int(11) NOT NULL default '0' AFTER `entry` ; +UPDATE `quest_template` SET `ZoneOrSort` = `ZoneId` WHERE `ZoneId` < 2147483647 ; +UPDATE `quest_template` SET `ZoneOrSort` = -(4294967295 - `ZoneId` + 1 ) WHERE `ZoneId` >= 2147483647 ; +UPDATE `quest_template` SET `ZoneOrSort` = -`questsort` WHERE `questsort` > 0 ; +ALTER TABLE `quest_template` DROP `questsort`, DROP `ZoneId`; \ No newline at end of file diff --git a/sql/updates/0.7/3631_gameobject_template.sql b/sql/updates/0.7/3631_gameobject_template.sql new file mode 100644 index 000000000..66f758d6f --- /dev/null +++ b/sql/updates/0.7/3631_gameobject_template.sql @@ -0,0 +1,15 @@ +ALTER TABLE `gameobject_template` +ADD COLUMN `sound10` int(11) unsigned NOT NULL default '0' AFTER `sound9`, +ADD COLUMN `sound11` int(11) unsigned NOT NULL default '0' AFTER `sound10`, +ADD COLUMN `sound12` int(11) unsigned NOT NULL default '0' AFTER `sound11`, +ADD COLUMN `sound13` int(11) unsigned NOT NULL default '0' AFTER `sound12`, +ADD COLUMN `sound14` int(11) unsigned NOT NULL default '0' AFTER `sound13`, +ADD COLUMN `sound15` int(11) unsigned NOT NULL default '0' AFTER `sound14`, +ADD COLUMN `sound16` int(11) unsigned NOT NULL default '0' AFTER `sound15`, +ADD COLUMN `sound17` int(11) unsigned NOT NULL default '0' AFTER `sound16`, +ADD COLUMN `sound18` int(11) unsigned NOT NULL default '0' AFTER `sound17`, +ADD COLUMN `sound19` int(11) unsigned NOT NULL default '0' AFTER `sound18`, +ADD COLUMN `sound20` int(11) unsigned NOT NULL default '0' AFTER `sound19`, +ADD COLUMN `sound21` int(11) unsigned NOT NULL default '0' AFTER `sound20`, +ADD COLUMN `sound22` int(11) unsigned NOT NULL default '0' AFTER `sound21`, +ADD COLUMN `sound23` int(11) unsigned NOT NULL default '0' AFTER `sound22`; diff --git a/sql/updates/0.7/3636_character_spell.sql b/sql/updates/0.7/3636_character_spell.sql new file mode 100644 index 000000000..945180b29 --- /dev/null +++ b/sql/updates/0.7/3636_character_spell.sql @@ -0,0 +1,2 @@ +UPDATE `character_spell` + SET `spell` = 5420 WHERE `spell` = 3122; diff --git a/sql/updates/0.7/3636_playercreateinfo_spell.sql b/sql/updates/0.7/3636_playercreateinfo_spell.sql new file mode 100644 index 000000000..5116fdd28 --- /dev/null +++ b/sql/updates/0.7/3636_playercreateinfo_spell.sql @@ -0,0 +1,2 @@ +UPDATE `playercreateinfo_spell` + SET `Spell` = 5420 WHERE `Spell` = 3122; diff --git a/sql/updates/0.7/3646_spell_chain.sql b/sql/updates/0.7/3646_spell_chain.sql new file mode 100644 index 000000000..5dfa78ffe --- /dev/null +++ b/sql/updates/0.7/3646_spell_chain.sql @@ -0,0 +1,6 @@ +INSERT INTO `spell_chain` VALUES +(25245, 0, 25245, 1), +(25246, 25245, 25245, 2), +(28896, 25246, 25245, 3), +(28899, 28896, 25245, 4), +(28901, 28899, 25245, 5); diff --git a/sql/updates/0.7/3648_command.sql b/sql/updates/0.7/3648_command.sql new file mode 100644 index 000000000..080757574 --- /dev/null +++ b/sql/updates/0.7/3648_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('sendmail',1,'Syntax: .sendmail #playername #subject #text\r\n\r\nSend a mail to a player. Note: subject may not contain spaces.'); \ No newline at end of file diff --git a/sql/updates/0.7/3649_spell_chain.sql b/sql/updates/0.7/3649_spell_chain.sql new file mode 100644 index 000000000..fbb73a028 --- /dev/null +++ b/sql/updates/0.7/3649_spell_chain.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (25245,25246,28896,28899,28901); + +INSERT INTO `spell_chain` VALUES +(25229, 0, 25229, 1), +(25230, 25229, 25229, 2), +(28894, 25230, 25229, 3), +(28895, 28894, 25229, 4), +(28897, 28895, 25229, 5); diff --git a/sql/updates/0.7/3653_spell.sql b/sql/updates/0.7/3653_spell.sql new file mode 100644 index 000000000..87f5a1f4d --- /dev/null +++ b/sql/updates/0.7/3653_spell.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_chain` WHERE `spell_id` = 27170; +INSERT INTO `spell_chain` VALUES (27170,20920,20375,6); +DELETE FROM `spell_proc_event` WHERE `entry` = 27170; +INSERT INTO `spell_proc_event` VALUES (27170, 0, 0, 0, 0, 1, 7); diff --git a/sql/updates/0.7/3655_quest_template.sql b/sql/updates/0.7/3655_quest_template.sql new file mode 100644 index 000000000..8882fca15 --- /dev/null +++ b/sql/updates/0.7/3655_quest_template.sql @@ -0,0 +1,24 @@ +UPDATE `quest_template` SET `ZoneOrSort` = -61 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 9; +UPDATE `quest_template` SET `ZoneOrSort` = -81 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 1; +UPDATE `quest_template` SET `ZoneOrSort` = -82 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 7; +UPDATE `quest_template` SET `ZoneOrSort` = -141 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 2; +UPDATE `quest_template` SET `ZoneOrSort` = -161 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 8; +UPDATE `quest_template` SET `ZoneOrSort` = -162 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 4; +UPDATE `quest_template` SET `ZoneOrSort` = -261 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 3; +UPDATE `quest_template` SET `ZoneOrSort` = -262 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 5; +UPDATE `quest_template` SET `ZoneOrSort` = -263 WHERE `ZoneOrSort` = 0 AND `RequiredClass` = 11; + +UPDATE `quest_template` SET `ZoneOrSort` = -24 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 182; +UPDATE `quest_template` SET `ZoneOrSort` = -101 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 356; +UPDATE `quest_template` SET `ZoneOrSort` = -121 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 164; +UPDATE `quest_template` SET `ZoneOrSort` = -181 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 171; +UPDATE `quest_template` SET `ZoneOrSort` = -182 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 165; +UPDATE `quest_template` SET `ZoneOrSort` = -201 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 202; +UPDATE `quest_template` SET `ZoneOrSort` = -264 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 197; +UPDATE `quest_template` SET `ZoneOrSort` = -304 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 185; +UPDATE `quest_template` SET `ZoneOrSort` = -324 WHERE `ZoneOrSort` = 0 AND `RequiredSkill` = 129; + +ALTER TABLE `quest_template` + ADD COLUMN `SuggestedPlayers` int(11) unsigned NOT NULL DEFAULT 0 AFTER `RequiredRepValue`, + DROP COLUMN `RequiredClass`, + DROP COLUMN `RequiredSkill`; diff --git a/sql/updates/0.7/3657_command.sql b/sql/updates/0.7/3657_command.sql new file mode 100644 index 000000000..10a69f6d2 --- /dev/null +++ b/sql/updates/0.7/3657_command.sql @@ -0,0 +1 @@ +DELETE FROM `command` WHERE `name` = 'NewMail' OR `name` = 'QNM'; diff --git a/sql/updates/0.7/3660_character_kill.sql b/sql/updates/0.7/3660_character_kill.sql new file mode 100644 index 000000000..3ec00bde8 --- /dev/null +++ b/sql/updates/0.7/3660_character_kill.sql @@ -0,0 +1 @@ +ALTER TABLE `character_kill` MODIFY COLUMN `guid` INT(11); \ No newline at end of file diff --git a/sql/updates/0.7/3700_character.sql b/sql/updates/0.7/3700_character.sql new file mode 100644 index 000000000..db01e501e --- /dev/null +++ b/sql/updates/0.7/3700_character.sql @@ -0,0 +1 @@ +alter table `character` add column `rename` tinyint (3) UNSIGNED DEFAULT '0' NOT NULL after `stable_slots`; diff --git a/sql/updates/0.7/3728_spell_proc_event.sql b/sql/updates/0.7/3728_spell_proc_event.sql new file mode 100644 index 000000000..789ac7e1f --- /dev/null +++ b/sql/updates/0.7/3728_spell_proc_event.sql @@ -0,0 +1,3 @@ +ALTER TABLE `spell_proc_event` + CHANGE COLUMN `entry` `entry` smallint(6) unsigned NOT NULL default '0'; + \ No newline at end of file diff --git a/sql/updates/0.7/3730_command.sql b/sql/updates/0.7/3730_command.sql new file mode 100644 index 000000000..ac85abaa8 --- /dev/null +++ b/sql/updates/0.7/3730_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('nametele',1,'Syntax: .nametele #playername #location\r\n\r\nTeleport a player to a given location.'); diff --git a/sql/updates/0.7/3732_spell_affect.sql b/sql/updates/0.7/3732_spell_affect.sql new file mode 100644 index 000000000..1ce212f5a --- /dev/null +++ b/sql/updates/0.7/3732_spell_affect.sql @@ -0,0 +1,113 @@ +DROP TABLE IF EXISTS `spell_affect`; +CREATE TABLE `spell_affect` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `effectId` tinyint(3) unsigned NOT NULL default '0', + `SpellId` smallint(5) unsigned NOT NULL default '0', + `SchoolMask` tinyint(3) unsigned NOT NULL default '0', + `Category` smallint(5) unsigned NOT NULL default '0', + `SkillID` smallint(5) unsigned NOT NULL default '0', + `SpellFamily` tinyint(3) unsigned NOT NULL default '0', + `SpellFamilyMask` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`effectId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `spell_affect` VALUES +(11070, 1, 0, 0, 0, 0, 0, 32), +(11069, 1, 0, 0, 0, 0, 0, 1), +(11083, 0, 0, 0, 0, 8, 0, 0), +(11124, 0, 0, 0, 0, 8, 0, 0), +(11151, 0, 0, 0, 0, 6, 0, 0), +(11160, 0, 0, 0, 0, 6, 0, 0), +(11175, 1, 0, 0, 0, 0, 0, 1048576), +(11207, 0, 0, 0, 0, 6, 0, 0), +(11222, 0, 0, 0, 0, 237, 0, 0), +(11242, 0, 0, 0, 0, 0, 0, 536872960), +(11247, 0, 0, 0, 0, 0, 0, 8192), +(11370, 0, 0, 0, 0, 8, 0, 0), +(12042, 0, 0, 0, 0, 0, 3, 0), +(12042, 1, 0, 0, 0, 0, 3, 0), +(12042, 2, 0, 0, 0, 0, 3, 0), +(12043, 0, 0, 0, 0, 0, 3, 0), +(12338, 1, 0, 0, 0, 0, 0, 1), +(12339, 1, 0, 0, 0, 0, 0, 1), +(12340, 1, 0, 0, 0, 0, 0, 1), +(12341, 1, 0, 0, 0, 0, 0, 1), +(12351, 0, 0, 0, 0, 8, 0, 0), +(12378, 0, 0, 0, 0, 8, 0, 0), +(12398, 0, 0, 0, 0, 8, 0, 0), +(12399, 0, 0, 0, 0, 8, 0, 0), +(12400, 0, 0, 0, 0, 8, 0, 0), +(12467, 0, 0, 0, 0, 0, 0, 536872960), +(12469, 0, 0, 0, 0, 0, 0, 536872960), +(12473, 1, 0, 0, 0, 0, 0, 32), +(12497, 0, 0, 0, 0, 0, 0, 1048576), +(12518, 0, 0, 0, 0, 6, 0, 0), +(12519, 0, 0, 0, 0, 6, 0, 0), +(12536, 0, 0, 0, 0, 0, 3, 0), +(12569, 1, 0, 0, 0, 0, 0, 1048576), +(12571, 1, 0, 0, 0, 0, 0, 1048576), +(12672, 0, 0, 0, 0, 6, 0, 0), +(12839, 0, 0, 0, 0, 237, 0, 0), +(12840, 0, 0, 0, 0, 237, 0, 0), +(12841, 0, 0, 0, 0, 237, 0, 0), +(12842, 0, 0, 0, 0, 237, 0, 0), +(12952, 0, 0, 0, 0, 6, 0, 0), +(12953, 0, 0, 0, 0, 6, 0, 0), +(12954, 0, 0, 0, 0, 6, 0, 0), +(12957, 0, 0, 0, 0, 6, 0, 0), +(15047, 0, 0, 0, 0, 6, 0, 0), +(15052, 0, 0, 0, 0, 6, 0, 0), +(15053, 0, 0, 0, 0, 6, 0, 0), +(16757, 0, 0, 0, 0, 0, 0, 160), +(16758, 0, 0, 0, 0, 0, 0, 160), +(16763, 1, 0, 0, 0, 0, 0, 32), +(16765, 1, 0, 0, 0, 0, 0, 32), +(16766, 1, 0, 0, 0, 0, 0, 32), +(22008, 0, 0, 0, 0, 0, 3, 0), +(23025, 0, 0, 0, 0, 0, 0, 65536), +(28682, 0, 0, 0, 0, 8, 0, 0), +(28763, 0, 0, 0, 0, 0, 0, 67108864), +(29438, 0, 0, 20, 0, 0, 0, 0), +(29439, 0, 0, 20, 0, 0, 0, 0), +(29440, 0, 0, 20, 0, 0, 0, 0), +(29976, 0, 0, 0, 0, 0, 3, 0), +(31569, 0, 0, 0, 0, 0, 0, 65536), +(31570, 0, 0, 0, 0, 0, 0, 65536), +(31571, 0, 12536, 0, 0, 0, 0, 0), +(31572, 0, 12536, 0, 0, 0, 0, 0), +(31573, 0, 12536, 0, 0, 0, 0, 0), +(31579, 0, 0, 0, 0, 0, 0, 2048), +(31579, 1, 0, 0, 0, 0, 0, 2048), +(31582, 0, 0, 0, 0, 0, 0, 2048), +(31582, 1, 0, 0, 0, 0, 0, 2048), +(31583, 0, 0, 0, 0, 0, 0, 2048), +(31583, 1, 0, 0, 0, 0, 0, 2048), +(31656, 0, 0, 0, 0, 0, 0, 1), +(31657, 0, 0, 0, 0, 0, 0, 1), +(31658, 0, 0, 0, 0, 0, 0, 1), +(31659, 0, 0, 0, 0, 0, 0, 1), +(31660, 0, 0, 0, 0, 0, 0, 1), +(31682, 0, 0, 0, 0, 0, 0, 32), +(31682, 1, 0, 0, 0, 0, 0, 32), +(31683, 0, 0, 0, 0, 0, 0, 32), +(31683, 1, 0, 0, 0, 0, 0, 32), +(31684, 0, 0, 0, 0, 0, 0, 32), +(31684, 1, 0, 0, 0, 0, 0, 32), +(31685, 1, 0, 0, 0, 0, 0, 32), +(31686, 0, 0, 0, 0, 0, 0, 32), +(31686, 1, 0, 0, 0, 0, 0, 32), +(33066, 0, 0, 0, 0, 0, 0, 2), +(35578, 0, 0, 0, 0, 0, 3, 0), +(35581, 0, 0, 0, 0, 0, 3, 0), +(36032, 0, 0, 0, 0, 0, 0, 536870912), +(36032, 1, 0, 0, 0, 0, 0, 536870912), +(37423, 0, 0, 0, 0, 0, 0, 4), +(37438, 0, 0, 0, 0, 0, 0, 33), +(37439, 0, 12043, 0, 0, 0, 0, 0), +(37439, 1, 0, 0, 0, 0, 0, 8388608), +(37439, 2, 11958, 0, 0, 0, 0, 0), +(37441, 0, 0, 0, 0, 0, 0, 4096), +(37441, 1, 0, 0, 0, 0, 0, 4096), +(37447, 0, 0, 0, 30, 0, 0, 0), +(38396, 0, 0, 0, 0, 0, 0, 67108864), +(38397, 0, 0, 0, 0, 0, 0, 2081); diff --git a/sql/updates/0.7/3739_looking_for_group.sql b/sql/updates/0.7/3739_looking_for_group.sql new file mode 100644 index 000000000..fc05c1fb5 --- /dev/null +++ b/sql/updates/0.7/3739_looking_for_group.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `looking_for_group`; diff --git a/sql/updates/0.7/3746_spell_proc_event.sql b/sql/updates/0.7/3746_spell_proc_event.sql new file mode 100644 index 000000000..3d7a91342 --- /dev/null +++ b/sql/updates/0.7/3746_spell_proc_event.sql @@ -0,0 +1,2 @@ +INSERT INTO `spell_proc_event` (`entry` ,`SchoolMask` ,`Category` ,`SkillID` ,`SpellFamilyMask` ,`procFlags` ,`ppmRate`) +VALUES ('27155', '0', '0', '0', '0', '1', '0'); \ No newline at end of file diff --git a/sql/updates/0.7/3747_command.sql b/sql/updates/0.7/3747_command.sql new file mode 100644 index 000000000..730f80804 --- /dev/null +++ b/sql/updates/0.7/3747_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES('modify mount',1,'Syntax:\r\n.modify mount #id #speed\r\nDisplay selected player as mounted at #id creature and set speed to #speed value.'); diff --git a/sql/updates/0.7/3748_command.sql b/sql/updates/0.7/3748_command.sql new file mode 100644 index 000000000..15b722c4c --- /dev/null +++ b/sql/updates/0.7/3748_command.sql @@ -0,0 +1,3 @@ +-- Enhanced .gocreature command +DELETE FROM `command` WHERE `name` = 'gocreature'; +INSERT INTO `command` VALUES('gocreature',2,'Syntax: .gocreature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'); diff --git a/sql/updates/0.7/3753_battleground_template.sql b/sql/updates/0.7/3753_battleground_template.sql new file mode 100644 index 000000000..40c5b2d35 --- /dev/null +++ b/sql/updates/0.7/3753_battleground_template.sql @@ -0,0 +1,24 @@ +-- ---------------------------- +-- Table structure for bg_template +-- ---------------------------- +DROP TABLE IF EXISTS `battleground_template`; +CREATE TABLE `battleground_template` ( + `id` int(11) unsigned NOT NULL, + `MaxPlayersPerTeam` int(11) NOT NULL, + `MinLvl` int(11) NOT NULL, + `MaxLvl` int(11) NOT NULL, + `AllianceStartLoc` int(11) unsigned NOT NULL, + `AllianceStartO` float NOT NULL, + `HordeStartLoc` int(11) unsigned NOT NULL, + `HordeStartO` float NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records +-- ---------------------------- + +INSERT INTO `battleground_template` VALUES ('1', '0', '0', '0', '611', '2.72532', '610','2.27452'); +INSERT INTO `battleground_template` VALUES ('2', '0', '0', '0', '769', '3.14159', '770','3.14159'); +INSERT INTO `battleground_template` VALUES ('3', '0', '0', '0', '890', '3.40156', '889','0.263892'); +INSERT INTO `battleground_template` VALUES ('7', '0', '0', '0', '1103', '3.40156', '1104','0.263892'); diff --git a/sql/updates/0.7/3763_spell_affect.sql b/sql/updates/0.7/3763_spell_affect.sql new file mode 100644 index 000000000..2bc10ee14 --- /dev/null +++ b/sql/updates/0.7/3763_spell_affect.sql @@ -0,0 +1,935 @@ +DROP TABLE IF EXISTS `spell_affect`; +CREATE TABLE `spell_affect` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `effectId` tinyint(3) unsigned NOT NULL default '0', + `SpellId` smallint(5) unsigned NOT NULL default '0', + `SchoolMask` tinyint(3) unsigned NOT NULL default '0', + `Category` smallint(5) unsigned NOT NULL default '0', + `SkillID` smallint(5) unsigned NOT NULL default '0', + `SpellFamily` tinyint(3) unsigned NOT NULL default '0', + `SpellFamilyMask` int(10) unsigned NOT NULL default '0', + `Charges` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`effectId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `spell_affect` VALUES +(11069, 1, 0, 0, 0, 0, 0, 1, 0), +(11070, 1, 0, 0, 0, 0, 0, 32, 0), +(11083, 0, 0, 0, 0, 8, 0, 0, 0), +(11124, 0, 0, 0, 0, 8, 0, 0, 0), +(11151, 0, 0, 0, 0, 6, 0, 0, 0), +(11160, 0, 0, 0, 0, 6, 0, 0, 0), +(11175, 1, 0, 0, 0, 0, 0, 1048576, 0), +(11207, 0, 0, 0, 0, 6, 0, 0, 0), +(11222, 0, 0, 0, 0, 237, 0, 0, 0), +(11242, 0, 0, 0, 0, 0, 0, 536872960, 0), +(11247, 0, 0, 0, 0, 0, 0, 8192, 0), +(11370, 0, 0, 0, 0, 8, 0, 0, 0), +(12042, 0, 0, 0, 0, 0, 3, 0, 0), +(12042, 1, 0, 0, 0, 0, 3, 0, 0), +(12042, 2, 0, 0, 0, 0, 3, 0, 0), +(12043, 0, 0, 0, 0, 0, 3, 0, 0), +(12285, 0, 0, 0, 0, 0, 0, 1, 0), +(12286, 0, 0, 0, 0, 0, 0, 32, 0), +(12287, 1, 0, 0, 0, 0, 0, 128, 0), +(12288, 0, 0, 0, 0, 0, 0, 8, 0), +(12288, 1, 0, 0, 0, 0, 0, 8, 0), +(12301, 0, 0, 0, 0, 0, 0, 256, 0), +(12318, 0, 469, 0, 0, 0, 0, 65536, 0), +(12321, 0, 469, 0, 0, 0, 0, 196608, 0), +(12321, 1, 469, 0, 0, 0, 0, 196608, 0), +(12330, 0, 0, 0, 0, 0, 0, 2097152, 0), +(12338, 1, 0, 0, 0, 0, 0, 1, 0), +(12339, 1, 0, 0, 0, 0, 0, 1, 0), +(12340, 1, 0, 0, 0, 0, 0, 1, 0), +(12341, 1, 0, 0, 0, 0, 0, 1, 0), +(12351, 0, 0, 0, 0, 8, 0, 0, 0), +(12378, 0, 0, 0, 0, 8, 0, 0, 0), +(12398, 0, 0, 0, 0, 8, 0, 0, 0), +(12399, 0, 0, 0, 0, 8, 0, 0, 0), +(12400, 0, 0, 0, 0, 8, 0, 0, 0), +(12467, 0, 0, 0, 0, 0, 0, 536872960, 0), +(12469, 0, 0, 0, 0, 0, 0, 536872960, 0), +(12473, 1, 0, 0, 0, 0, 0, 32, 0), +(12497, 0, 0, 0, 0, 0, 0, 1048576, 0), +(12518, 0, 0, 0, 0, 6, 0, 0, 0), +(12519, 0, 0, 0, 0, 6, 0, 0, 0), +(12536, 0, 0, 0, 0, 0, 3, 0, 0), +(12569, 1, 0, 0, 0, 0, 0, 1048576, 0), +(12571, 1, 0, 0, 0, 0, 0, 1048576, 0), +(12658, 0, 0, 0, 0, 0, 0, 32, 0), +(12659, 0, 0, 0, 0, 0, 0, 32, 0), +(12665, 1, 0, 0, 0, 0, 0, 128, 0), +(12666, 1, 0, 0, 0, 0, 0, 128, 0), +(12672, 0, 0, 0, 0, 6, 0, 0, 0), +(12697, 0, 0, 0, 0, 0, 0, 1, 0), +(12707, 0, 0, 0, 0, 0, 0, 8, 0), +(12707, 1, 0, 0, 0, 0, 0, 8, 0), +(12818, 0, 0, 0, 0, 0, 0, 256, 0), +(12835, 0, 469, 0, 0, 0, 0, 196608, 0), +(12835, 1, 469, 0, 0, 0, 0, 196608, 0), +(12836, 0, 469, 0, 0, 0, 0, 196608, 0), +(12836, 1, 469, 0, 0, 0, 0, 196608, 0), +(12837, 0, 469, 0, 0, 0, 0, 196608, 0), +(12837, 1, 469, 0, 0, 0, 0, 196608, 0), +(12838, 0, 469, 0, 0, 0, 0, 196608, 0), +(12838, 1, 469, 0, 0, 0, 0, 196608, 0), +(12839, 0, 0, 0, 0, 237, 0, 0, 0), +(12840, 0, 0, 0, 0, 237, 0, 0, 0), +(12841, 0, 0, 0, 0, 237, 0, 0, 0), +(12842, 0, 0, 0, 0, 237, 0, 0, 0), +(12857, 0, 469, 0, 0, 0, 0, 65536, 0), +(12858, 0, 469, 0, 0, 0, 0, 65536, 0), +(12860, 0, 469, 0, 0, 0, 0, 65536, 0), +(12861, 0, 469, 0, 0, 0, 0, 65536, 0), +(12862, 0, 0, 0, 0, 0, 0, 2097152, 0), +(12945, 1, 0, 0, 0, 0, 0, 4096, 0), +(12952, 0, 0, 0, 0, 6, 0, 0, 0), +(12953, 0, 0, 0, 0, 6, 0, 0, 0), +(12954, 0, 0, 0, 0, 6, 0, 0, 0), +(12957, 0, 0, 0, 0, 6, 0, 0, 0), +(13742, 0, 0, 0, 0, 0, 0, 96, 0), +(13743, 0, 0, 0, 0, 0, 0, 64, 0), +(13872, 0, 0, 0, 0, 0, 0, 96, 0), +(13875, 0, 0, 0, 0, 0, 0, 64, 0), +(13975, 0, 0, 0, 0, 0, 0, 4194304, 0), +(13975, 1, 0, 0, 0, 0, 0, 4194304, 0), +(13976, 0, 0, 0, 0, 0, 0, 1792, 0), +(13979, 0, 0, 0, 0, 0, 0, 1792, 0), +(13980, 0, 0, 0, 0, 0, 0, 1792, 0), +(13981, 0, 0, 0, 0, 0, 0, 16779264, 0), +(14057, 0, 0, 0, 0, 0, 0, 772, 0), +(14062, 0, 0, 0, 0, 0, 0, 4194304, 0), +(14062, 1, 0, 0, 0, 0, 0, 4194304, 0), +(14063, 0, 0, 0, 0, 0, 0, 4194304, 0), +(14063, 1, 0, 0, 0, 0, 0, 4194304, 0), +(14064, 0, 0, 0, 0, 0, 0, 4194304, 0), +(14064, 1, 0, 0, 0, 0, 0, 4194304, 0), +(14065, 0, 0, 0, 0, 0, 0, 4194304, 0), +(14065, 1, 0, 0, 0, 0, 0, 4194304, 0), +(14066, 0, 0, 0, 0, 0, 0, 16779264, 0), +(14067, 0, 0, 0, 0, 0, 0, 16779264, 0), +(14072, 0, 0, 0, 0, 0, 0, 772, 0), +(14073, 0, 0, 0, 0, 0, 0, 772, 0), +(14074, 0, 0, 0, 0, 0, 0, 772, 0), +(14075, 0, 0, 0, 0, 0, 0, 772, 0), +(14082, 0, 0, 0, 0, 0, 0, 258, 0), +(14083, 0, 0, 0, 0, 0, 0, 258, 0), +(14113, 0, 0, 0, 0, 0, 0, 122880, 0), +(14114, 0, 0, 0, 0, 0, 0, 122880, 0), +(14115, 0, 0, 0, 0, 0, 0, 122880, 0), +(14116, 0, 0, 0, 0, 0, 0, 122880, 0), +(14117, 0, 0, 0, 0, 0, 0, 122880, 0), +(14128, 0, 0, 0, 0, 0, 0, 603979790, 0), +(14132, 0, 0, 0, 0, 0, 0, 603979790, 0), +(14135, 0, 0, 0, 0, 0, 0, 603979790, 0), +(14136, 0, 0, 0, 0, 0, 0, 603979790, 0), +(14137, 0, 0, 0, 0, 0, 0, 603979790, 0), +(14143, 0, 0, 0, 0, 0, 0, 100663814, 0), +(14149, 0, 0, 0, 0, 0, 0, 100663814, 0), +(14162, 0, 0, 0, 0, 0, 0, 131072, 0), +(14163, 0, 0, 0, 0, 0, 0, 131072, 0), +(14164, 0, 0, 0, 0, 0, 0, 131072, 0), +(14168, 0, 0, 0, 0, 0, 0, 524288, 0), +(14169, 0, 0, 0, 0, 0, 0, 524288, 0), +(14174, 0, 0, 0, 0, 0, 0, 2097152, 0), +(14175, 0, 0, 0, 0, 0, 0, 2097152, 0), +(14176, 0, 0, 0, 0, 0, 0, 2097152, 0), +(14177, 0, 0, 0, 0, 0, 8, 0, 0), +(14179, 0, 0, 0, 0, 0, 0, 4063232, 0), +(14523, 1, 0, 66, 0, 0, 0, 0, 0), +(14743, 0, 0, 0, 0, 0, 6, 0, 0), +(14750, 0, 0, 0, 0, 0, 0, 16, 0), +(14751, 0, 0, 0, 0, 0, 6, 0, 0), +(14751, 1, 0, 0, 0, 0, 6, 0, 0), +(14772, 0, 0, 0, 0, 0, 0, 16, 0), +(14784, 1, 0, 66, 0, 0, 0, 0, 0), +(14785, 1, 0, 66, 0, 0, 0, 0, 0), +(14786, 1, 0, 66, 0, 0, 0, 0, 0), +(14787, 1, 0, 66, 0, 0, 0, 0, 0), +(14908, 0, 0, 0, 0, 0, 0, 64, 0), +(14909, 1, 0, 0, 0, 0, 0, 1048704, 0), +(14911, 0, 33076, 0, 0, 0, 0, 512, 0), +(15017, 1, 0, 0, 0, 0, 0, 1048704, 0), +(15018, 0, 33076, 0, 0, 0, 0, 512, 0), +(15019, 0, 33076, 0, 0, 0, 0, 512, 0), +(15020, 0, 0, 0, 0, 0, 0, 64, 0), +(15047, 0, 0, 0, 0, 6, 0, 0, 0), +(15052, 0, 0, 0, 0, 6, 0, 0, 0), +(15053, 0, 0, 0, 0, 6, 0, 0, 0), +(15257, 0, 0, 0, 0, 78, 0, 0, 0), +(15259, 0, 0, 0, 0, 78, 0, 0, 0), +(15259, 1, 0, 0, 0, 78, 0, 0, 0), +(15260, 0, 0, 0, 0, 78, 0, 0, 0), +(15272, 0, 0, 0, 0, 78, 0, 0, 0), +(15307, 0, 0, 0, 0, 78, 0, 0, 0), +(15307, 1, 0, 0, 0, 78, 0, 0, 0), +(15308, 0, 0, 0, 0, 78, 0, 0, 0), +(15308, 1, 0, 0, 0, 78, 0, 0, 0), +(15309, 0, 0, 0, 0, 78, 0, 0, 0), +(15309, 1, 0, 0, 0, 78, 0, 0, 0), +(15310, 0, 0, 0, 0, 78, 0, 0, 0), +(15310, 1, 0, 0, 0, 78, 0, 0, 0), +(15318, 0, 0, 0, 0, 78, 0, 0, 0), +(15320, 0, 0, 0, 0, 78, 0, 0, 0), +(15327, 0, 0, 0, 0, 78, 0, 0, 0), +(15328, 0, 0, 0, 0, 78, 0, 0, 0), +(15329, 0, 0, 0, 0, 78, 0, 0, 0), +(15330, 0, 0, 0, 0, 78, 0, 0, 0), +(15331, 0, 0, 0, 0, 78, 0, 0, 0), +(15332, 0, 0, 0, 0, 78, 0, 0, 0), +(15333, 0, 0, 0, 0, 78, 0, 0, 0), +(15334, 0, 0, 0, 0, 78, 0, 0, 0), +(16035, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16038, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(16039, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16041, 0, 0, 0, 0, 0, 0, 3, 0), +(16043, 0, 0, 0, 0, 0, 0, 8, 0), +(16043, 1, 3600, 0, 0, 0, 0, 0, 0), +(16086, 0, 0, 0, 0, 0, 0, 134217728, 0), +(16086, 1, 0, 0, 0, 0, 0, 134217728, 0), +(16086, 2, 0, 0, 0, 0, 0, 4, 0), +(16089, 0, 0, 28, 0, 0, 0, 0, 0), +(16105, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16106, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16106, 1, 0, 0, 0, 0, 0, 2416967683, 0), +(16107, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16108, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16109, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16110, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16111, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16112, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(16117, 0, 0, 0, 0, 0, 0, 3, 0), +(16118, 0, 0, 0, 0, 0, 0, 3, 0), +(16119, 0, 0, 0, 0, 0, 0, 3, 0), +(16120, 0, 0, 0, 0, 0, 0, 3, 0), +(16130, 0, 0, 0, 0, 0, 0, 8, 0), +(16130, 1, 3600, 0, 0, 0, 0, 0, 0), +(16160, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(16161, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(16166, 0, 0, 28, 0, 0, 0, 0, 0), +(16166, 1, 0, 28, 0, 0, 0, 0, 0), +(16173, 0, 0, 1, 0, 0, 0, 0, 0), +(16181, 0, 0, 0, 0, 0, 0, 448, 0), +(16183, 0, 0, 0, 0, 0, 0, 256, 0), +(16184, 0, 0, 0, 0, 0, 0, 512, 0), +(16184, 1, 0, 0, 0, 0, 0, 512, 0), +(16187, 0, 0, 0, 0, 0, 0, 24576, 0), +(16187, 1, 0, 0, 0, 0, 0, 24576, 0), +(16189, 0, 0, 0, 0, 0, 0, 67108864, 0), +(16205, 0, 0, 0, 0, 0, 0, 24576, 0), +(16205, 1, 0, 0, 0, 0, 0, 24576, 0), +(16206, 0, 0, 0, 0, 0, 0, 24576, 0), +(16206, 1, 0, 0, 0, 0, 0, 24576, 0), +(16207, 0, 0, 0, 0, 0, 0, 24576, 0), +(16207, 1, 0, 0, 0, 0, 0, 24576, 0), +(16208, 0, 0, 0, 0, 0, 0, 24576, 0), +(16208, 1, 0, 0, 0, 0, 0, 24576, 0), +(16209, 1, 0, 0, 0, 0, 0, 512, 0), +(16222, 0, 0, 0, 0, 0, 0, 536870912, 0), +(16223, 0, 0, 0, 0, 0, 0, 536870912, 0), +(16224, 0, 0, 0, 0, 0, 0, 536870912, 0), +(16225, 0, 0, 0, 0, 0, 0, 536870912, 0), +(16230, 0, 0, 0, 0, 0, 0, 448, 0), +(16232, 0, 0, 0, 0, 0, 0, 448, 0), +(16233, 0, 0, 0, 0, 0, 0, 448, 0), +(16234, 0, 0, 0, 0, 0, 0, 448, 0), +(16258, 0, 0, 0, 0, 0, 0, 32768, 0), +(16258, 1, 0, 0, 0, 0, 0, 262144, 0), +(16259, 0, 0, 0, 0, 0, 0, 65536, 0), +(16259, 1, 0, 0, 0, 0, 0, 131072, 0), +(16261, 0, 0, 0, 0, 0, 0, 1024, 0), +(16266, 0, 0, 0, 0, 0, 0, 4194304, 0), +(16266, 1, 0, 0, 0, 0, 0, 16777216, 0), +(16266, 2, 0, 0, 0, 0, 0, 8388608, 0), +(16290, 0, 0, 0, 0, 0, 0, 1024, 0), +(16291, 0, 0, 0, 0, 0, 0, 1024, 0), +(16293, 0, 0, 0, 0, 0, 0, 32768, 0), +(16293, 1, 0, 0, 0, 0, 0, 262144, 0), +(16295, 0, 0, 0, 0, 0, 0, 65536, 0), +(16295, 1, 0, 0, 0, 0, 0, 131072, 0), +(16493, 0, 0, 0, 0, 0, 4, 0, 0), +(16494, 0, 0, 0, 0, 0, 4, 0, 0), +(16513, 0, 0, 0, 0, 0, 0, 122880, 0), +(16513, 1, 0, 0, 0, 0, 0, 122880, 0), +(16513, 2, 0, 0, 0, 0, 0, 122880, 0), +(16514, 0, 0, 0, 0, 0, 0, 122880, 0), +(16514, 1, 0, 0, 0, 0, 0, 122880, 0), +(16514, 2, 0, 0, 0, 0, 0, 122880, 0), +(16515, 0, 0, 0, 0, 0, 0, 122880, 0), +(16515, 1, 0, 0, 0, 0, 0, 122880, 0), +(16515, 2, 0, 0, 0, 0, 0, 122880, 0), +(16544, 2, 0, 0, 0, 0, 0, 4, 0), +(16719, 0, 0, 0, 0, 0, 0, 122880, 0), +(16719, 1, 0, 0, 0, 0, 0, 122880, 0), +(16719, 2, 0, 0, 0, 0, 0, 122880, 0), +(16720, 0, 0, 0, 0, 0, 0, 122880, 0), +(16720, 1, 0, 0, 0, 0, 0, 122880, 0), +(16720, 2, 0, 0, 0, 0, 0, 122880, 0), +(16757, 0, 0, 0, 0, 0, 0, 160, 0), +(16758, 0, 0, 0, 0, 0, 0, 160, 0), +(16763, 1, 0, 0, 0, 0, 0, 32, 0), +(16765, 1, 0, 0, 0, 0, 0, 32, 0), +(16766, 1, 0, 0, 0, 0, 0, 32, 0), +(16814, 0, 0, 0, 0, 0, 0, 5, 0), +(16815, 0, 0, 0, 0, 0, 0, 5, 0), +(16816, 0, 0, 0, 0, 0, 0, 5, 0), +(16817, 0, 0, 0, 0, 0, 0, 5, 0), +(16818, 0, 0, 0, 0, 0, 0, 5, 0), +(16819, 0, 0, 0, 0, 574, 0, 1024, 0), +(16820, 0, 0, 0, 0, 574, 0, 1024, 0), +(16821, 0, 0, 0, 0, 0, 0, 2, 0), +(16821, 1, 0, 0, 0, 0, 0, 2, 0), +(16821, 2, 0, 0, 0, 0, 0, 2, 0), +(16822, 0, 0, 0, 0, 0, 0, 2, 0), +(16822, 1, 0, 0, 0, 0, 0, 2, 0), +(16822, 2, 0, 0, 0, 0, 0, 2, 0), +(16823, 1, 0, 0, 0, 0, 0, 2, 0), +(16823, 2, 0, 0, 0, 0, 0, 2, 0), +(16824, 1, 0, 0, 0, 0, 0, 2, 0), +(16824, 2, 0, 0, 0, 0, 0, 2, 0), +(16825, 1, 0, 0, 0, 0, 0, 2, 0), +(16825, 2, 0, 0, 0, 0, 0, 2, 0), +(16833, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(16834, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(16835, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(16836, 1, 0, 0, 0, 0, 0, 768, 0), +(16839, 1, 0, 0, 0, 0, 0, 768, 0), +(16840, 1, 0, 0, 0, 0, 0, 768, 0), +(16850, 1, 0, 0, 0, 0, 0, 1, 0), +(16870, 0, 0, 0, 0, 0, 7, 0, 0), +(16896, 0, 0, 0, 0, 0, 0, 7, 0), +(16896, 1, 0, 0, 0, 0, 0, 7, 0), +(16897, 0, 0, 0, 0, 0, 0, 7, 0), +(16897, 1, 0, 0, 0, 0, 0, 7, 0), +(16899, 0, 0, 0, 0, 0, 0, 7, 0), +(16899, 1, 0, 0, 0, 0, 0, 7, 0), +(16900, 0, 0, 0, 0, 0, 0, 7, 0), +(16900, 1, 0, 0, 0, 0, 0, 7, 0), +(16901, 0, 0, 0, 0, 0, 0, 7, 0), +(16901, 1, 0, 0, 0, 0, 0, 7, 0), +(16918, 0, 33786, 0, 0, 0, 0, 512, 0), +(16919, 0, 33786, 0, 0, 0, 0, 512, 0), +(16920, 0, 33786, 0, 0, 0, 0, 512, 0), +(16923, 1, 0, 0, 0, 0, 0, 1, 0), +(16924, 1, 0, 0, 0, 0, 0, 1, 0), +(16934, 0, 0, 0, 0, 0, 0, 2048, 0), +(16934, 1, 0, 0, 0, 0, 0, 4096, 0), +(16935, 0, 0, 0, 0, 0, 0, 2048, 0), +(16935, 1, 0, 0, 0, 0, 0, 4096, 0), +(16936, 0, 0, 0, 0, 0, 0, 2048, 0), +(16936, 1, 0, 0, 0, 0, 0, 4096, 0), +(16937, 0, 0, 0, 0, 0, 0, 2048, 0), +(16937, 1, 0, 0, 0, 0, 0, 4096, 0), +(16938, 0, 0, 0, 0, 0, 0, 2048, 0), +(16938, 1, 0, 0, 0, 0, 0, 4096, 0), +(16966, 0, 0, 0, 0, 0, 0, 32768, 0), +(16966, 1, 33745, 0, 0, 0, 0, 0, 0), +(16968, 0, 0, 0, 0, 0, 0, 32768, 0), +(16968, 1, 33745, 0, 0, 0, 0, 0, 0), +(16998, 0, 0, 0, 0, 0, 0, 4096, 0), +(16998, 2, 0, 0, 0, 0, 0, 4096, 0), +(16999, 0, 0, 0, 0, 0, 0, 4096, 0), +(16999, 2, 0, 0, 0, 0, 0, 4096, 0), +(17111, 0, 0, 0, 0, 0, 0, 16, 0), +(17112, 0, 0, 0, 0, 0, 0, 16, 0), +(17113, 0, 0, 0, 0, 0, 0, 16, 0), +(17114, 0, 0, 0, 0, 0, 0, 16, 0), +(17115, 0, 0, 0, 0, 0, 0, 16, 0), +(17116, 0, 0, 8, 0, 0, 0, 0, 0), +(17118, 0, 0, 0, 0, 0, 7, 0, 0), +(17118, 1, 0, 0, 0, 0, 7, 0, 0), +(17119, 0, 0, 0, 0, 0, 7, 0, 0), +(17119, 1, 0, 0, 0, 0, 7, 0, 0), +(17120, 0, 0, 0, 0, 0, 7, 0, 0), +(17120, 1, 0, 0, 0, 0, 7, 0, 0), +(17121, 0, 0, 0, 0, 0, 7, 0, 0), +(17121, 1, 0, 0, 0, 0, 7, 0, 0), +(17122, 0, 0, 0, 0, 0, 7, 0, 0), +(17122, 1, 0, 0, 0, 0, 7, 0, 0), +(17123, 0, 0, 0, 0, 0, 0, 128, 0), +(17124, 0, 0, 0, 0, 0, 0, 128, 0), +(17191, 0, 0, 0, 0, 0, 0, 64, 0), +(17322, 0, 0, 0, 0, 78, 0, 0, 0), +(17323, 0, 0, 0, 0, 78, 0, 0, 0), +(17325, 0, 0, 0, 0, 78, 0, 0, 0), +(17778, 0, 0, 0, 0, 593, 0, 0, 0), +(17779, 0, 0, 0, 0, 593, 0, 0, 0), +(17780, 0, 0, 0, 0, 593, 0, 0, 0), +(17781, 0, 0, 0, 0, 593, 0, 0, 0), +(17782, 0, 0, 0, 0, 593, 0, 0, 0), +(17788, 1, 0, 0, 631, 0, 0, 0, 0), +(17789, 1, 0, 0, 631, 0, 0, 0, 0), +(17790, 1, 0, 0, 631, 0, 0, 0, 0), +(17791, 1, 0, 0, 631, 0, 0, 0, 0), +(17792, 1, 0, 0, 631, 0, 0, 0, 0), +(17917, 0, 0, 0, 0, 593, 0, 0, 0), +(17917, 1, 0, 0, 0, 593, 0, 0, 0), +(17918, 0, 0, 0, 0, 593, 0, 0, 0), +(17918, 1, 0, 0, 0, 593, 0, 0, 0), +(17927, 0, 0, 0, 0, 0, 0, 256, 0), +(17929, 0, 0, 0, 0, 0, 0, 256, 0), +(17930, 0, 0, 0, 0, 0, 0, 256, 0), +(17941, 255, 0, 0, 0, 0, 0, 1, 1), +(17954, 0, 0, 4, 0, 0, 0, 0, 0), +(17954, 1, 0, 4, 0, 0, 0, 0, 0), +(17955, 0, 0, 4, 0, 0, 0, 0, 0), +(17955, 1, 0, 4, 0, 0, 0, 0, 0), +(17956, 0, 0, 4, 0, 0, 0, 0, 0), +(17956, 1, 0, 4, 0, 0, 0, 0, 0), +(17957, 0, 0, 4, 0, 0, 0, 0, 0), +(17957, 1, 0, 4, 0, 0, 0, 0, 0), +(17958, 0, 0, 4, 0, 0, 0, 0, 0), +(17958, 1, 0, 4, 0, 0, 0, 0, 0), +(17959, 0, 0, 0, 0, 593, 0, 0, 0), +(18126, 0, 0, 0, 0, 0, 0, 4096, 0), +(18127, 0, 0, 0, 0, 0, 0, 4096, 0), +(18130, 0, 0, 0, 0, 593, 0, 0, 0), +(18131, 0, 0, 0, 0, 593, 0, 0, 0), +(18132, 0, 0, 0, 0, 593, 0, 0, 0), +(18133, 0, 0, 0, 0, 593, 0, 0, 0), +(18134, 0, 0, 0, 0, 593, 0, 0, 0), +(18135, 0, 0, 0, 0, 593, 0, 0, 0), +(18136, 0, 0, 0, 0, 593, 0, 0, 0), +(18174, 0, 0, 0, 0, 355, 0, 0, 0), +(18175, 0, 0, 0, 0, 355, 0, 0, 0), +(18176, 0, 0, 0, 0, 355, 0, 0, 0), +(18177, 0, 0, 0, 0, 355, 0, 0, 0), +(18178, 0, 0, 0, 0, 355, 0, 0, 0), +(18179, 0, 0, 0, 0, 0, 0, 32768, 0), +(18180, 0, 0, 0, 0, 0, 0, 32768, 0), +(18213, 0, 0, 0, 0, 0, 0, 16384, 0), +(18213, 1, 0, 0, 0, 355, 0, 0, 0), +(18218, 0, 0, 0, 0, 355, 0, 0, 0), +(18219, 0, 0, 0, 0, 355, 0, 0, 0), +(18271, 0, 0, 32, 0, 0, 0, 0, 0), +(18271, 1, 0, 32, 0, 0, 0, 0, 0), +(18272, 0, 0, 32, 0, 0, 0, 0, 0), +(18272, 1, 0, 32, 0, 0, 0, 0, 0), +(18273, 0, 0, 32, 0, 0, 0, 0, 0), +(18273, 1, 0, 32, 0, 0, 0, 0, 0), +(18274, 0, 0, 32, 0, 0, 0, 0, 0), +(18274, 1, 0, 32, 0, 0, 0, 0, 0), +(18275, 0, 0, 32, 0, 0, 0, 0, 0), +(18275, 1, 0, 32, 0, 0, 0, 0, 0), +(18288, 0, 0, 0, 1179, 0, 0, 1024, 0), +(18288, 1, 18223, 0, 0, 0, 0, 0, 0), +(18310, 0, 18223, 0, 0, 0, 0, 0, 0), +(18311, 0, 18223, 0, 0, 0, 0, 0, 0), +(18312, 0, 18223, 0, 0, 0, 0, 0, 0), +(18313, 0, 18223, 0, 0, 0, 0, 0, 0), +(18372, 1, 0, 0, 0, 355, 0, 0, 0), +(18544, 0, 0, 0, 0, 0, 6, 0, 0), +(18544, 1, 0, 0, 0, 0, 6, 0, 0), +(18544, 2, 0, 0, 0, 0, 6, 0, 0), +(18547, 0, 0, 0, 0, 0, 6, 0, 0), +(18547, 1, 0, 0, 0, 0, 6, 0, 0), +(18547, 2, 0, 0, 0, 0, 6, 0, 0), +(18548, 0, 0, 0, 0, 0, 6, 0, 0), +(18548, 1, 0, 0, 0, 0, 6, 0, 0), +(18548, 2, 0, 0, 0, 0, 6, 0, 0), +(18549, 0, 0, 0, 0, 0, 6, 0, 0), +(18549, 1, 0, 0, 0, 0, 6, 0, 0), +(18549, 2, 0, 0, 0, 0, 6, 0, 0), +(18550, 0, 0, 0, 0, 0, 6, 0, 0), +(18550, 1, 0, 0, 0, 0, 6, 0, 0), +(18550, 2, 0, 0, 0, 0, 6, 0, 0), +(18703, 1, 0, 0, 0, 0, 0, 16777216, 0), +(18704, 1, 0, 0, 0, 0, 0, 16777216, 0), +(18731, 0, 0, 0, 0, 0, 0, 268435456, 0), +(18743, 0, 0, 0, 0, 0, 0, 268435456, 0), +(18744, 0, 0, 0, 0, 0, 0, 268435456, 0), +(18748, 0, 0, 0, 0, 0, 0, 134217728, 0), +(18749, 0, 0, 0, 0, 0, 0, 134217728, 0), +(18750, 0, 0, 0, 0, 0, 0, 134217728, 0), +(18767, 1, 0, 0, 0, 0, 0, 131072, 0), +(18768, 1, 0, 0, 0, 0, 0, 131072, 0), +(18821, 0, 0, 0, 0, 0, 0, 2048, 0), +(18821, 1, 0, 0, 0, 0, 0, 2048, 0), +(18821, 2, 0, 0, 0, 0, 0, 2048, 0), +(18822, 0, 0, 0, 0, 0, 0, 2048, 0), +(18822, 1, 0, 0, 0, 0, 0, 2048, 0), +(18822, 2, 0, 0, 0, 0, 0, 2048, 0), +(18827, 0, 0, 0, 0, 0, 0, 1024, 0), +(18829, 0, 0, 0, 0, 0, 0, 1024, 0), +(19416, 0, 0, 0, 0, 0, 0, 252416, 0), +(19417, 0, 0, 0, 0, 0, 0, 252416, 0), +(19418, 0, 0, 0, 0, 0, 0, 252416, 0), +(19419, 0, 0, 0, 0, 0, 0, 252416, 0), +(19420, 0, 0, 0, 0, 0, 0, 252416, 0), +(19461, 0, 0, 0, 0, 0, 0, 12288, 0), +(19461, 1, 0, 0, 0, 0, 0, 12288, 0), +(19462, 0, 0, 0, 0, 0, 0, 12288, 0), +(19462, 1, 0, 0, 0, 0, 0, 12288, 0), +(19464, 0, 0, 0, 0, 0, 0, 16384, 0), +(19464, 1, 0, 0, 1175, 0, 0, 0, 0), +(19464, 2, 0, 0, 0, 0, 0, 252416, 0), +(19465, 0, 0, 0, 0, 0, 0, 16384, 0), +(19465, 1, 0, 0, 1175, 0, 0, 0, 0), +(19465, 2, 0, 0, 0, 0, 0, 252416, 0), +(19466, 0, 0, 0, 0, 0, 0, 16384, 0), +(19466, 1, 0, 0, 1175, 0, 0, 0, 0), +(19466, 2, 0, 0, 0, 0, 0, 252416, 0), +(19467, 0, 0, 0, 0, 0, 0, 16384, 0), +(19467, 1, 0, 0, 1175, 0, 0, 0, 0), +(19467, 2, 0, 0, 0, 0, 0, 252416, 0), +(19468, 0, 0, 0, 0, 0, 0, 16384, 0), +(19468, 1, 0, 0, 1175, 0, 0, 0, 0), +(19468, 2, 0, 0, 0, 0, 0, 252416, 0), +(19498, 0, 0, 0, 0, 0, 0, 1, 0), +(19499, 0, 0, 0, 0, 0, 0, 1, 0), +(19500, 0, 0, 0, 0, 0, 0, 1, 0), +(19549, 0, 0, 0, 0, 0, 0, 524288, 0), +(19550, 0, 0, 0, 0, 0, 0, 524288, 0), +(19551, 0, 0, 0, 0, 0, 0, 524288, 0), +(19552, 0, 0, 0, 0, 0, 0, 1048576, 0), +(19552, 1, 6150, 0, 0, 0, 0, 0, 0), +(19553, 0, 0, 0, 0, 0, 0, 1048576, 0), +(19553, 1, 6150, 0, 0, 0, 0, 0, 0), +(19554, 0, 0, 0, 0, 0, 0, 1048576, 0), +(19554, 1, 6150, 0, 0, 0, 0, 0, 0), +(19555, 0, 0, 0, 0, 0, 0, 1048576, 0), +(19555, 1, 6150, 0, 0, 0, 0, 0, 0), +(19556, 0, 0, 0, 0, 0, 0, 1048576, 0), +(19556, 1, 6150, 0, 0, 0, 0, 0, 0), +(19559, 0, 0, 0, 0, 0, 0, 2097152, 0), +(19560, 0, 0, 0, 0, 0, 0, 2097152, 0), +(19583, 0, 0, 0, 0, 0, 0, 134217728, 0), +(19584, 0, 0, 0, 0, 0, 0, 134217728, 0), +(19585, 0, 0, 0, 0, 0, 0, 134217728, 0), +(19586, 0, 0, 0, 0, 0, 0, 134217728, 0), +(19587, 0, 0, 0, 0, 0, 0, 134217728, 0), +(19590, 0, 0, 0, 0, 0, 0, 536870912, 0), +(19592, 0, 0, 0, 0, 0, 0, 536870912, 0), +(19598, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(19599, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(19600, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(19601, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(19602, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(19609, 0, 0, 0, 0, 0, 0, 67108864, 0), +(19610, 0, 0, 0, 0, 0, 0, 67108864, 0), +(19612, 0, 0, 0, 0, 0, 0, 67108864, 0), +(20101, 0, 0, 0, 0, 0, 0, 402653184, 0), +(20102, 0, 0, 0, 0, 0, 0, 402653184, 0), +(20103, 0, 0, 0, 0, 0, 0, 402653184, 0), +(20104, 0, 0, 0, 0, 0, 0, 402653184, 0), +(20105, 0, 0, 0, 0, 0, 0, 402653184, 0), +(20138, 0, 0, 0, 0, 0, 0, 64, 0), +(20139, 0, 0, 0, 0, 0, 0, 64, 0), +(20140, 0, 0, 0, 0, 0, 0, 64, 0), +(20141, 0, 0, 0, 0, 0, 0, 64, 0), +(20142, 0, 0, 0, 0, 0, 0, 64, 0), +(20174, 0, 0, 0, 0, 0, 0, 128, 0), +(20174, 1, 0, 0, 0, 0, 0, 16, 0), +(20237, 0, 0, 0, 0, 0, 0, 3221225472, 0), +(20238, 0, 0, 0, 0, 0, 0, 3221225472, 0), +(20239, 0, 0, 0, 0, 0, 0, 3221225472, 0), +(20335, 1, 0, 0, 0, 0, 0, 536870912, 0), +(20336, 1, 0, 0, 0, 0, 0, 536870912, 0), +(20337, 1, 0, 0, 0, 0, 0, 536870912, 0), +(20359, 0, 0, 0, 0, 0, 0, 2147483648, 0), +(20360, 0, 0, 0, 0, 0, 0, 2147483648, 0), +(20361, 0, 0, 0, 0, 0, 0, 2147483648, 0), +(20468, 1, 0, 0, 0, 0, 0, 1, 0), +(20469, 1, 0, 0, 0, 0, 0, 1, 0), +(20470, 1, 0, 0, 0, 0, 0, 1, 0), +(20575, 0, 0, 0, 0, 0, 0, 67108864, 0), +(20575, 1, 0, 0, 0, 0, 0, 67108864, 0), +(20576, 0, 0, 0, 0, 0, 0, 33554432, 0), +(21873, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(21881, 0, 0, 0, 0, 0, 0, 122880, 0), +(21887, 0, 0, 0, 0, 0, 4, 0, 0), +(21942, 1, 0, 0, 0, 0, 0, 134217728, 0), +(22008, 0, 0, 0, 0, 0, 3, 0, 1), +(23025, 0, 0, 0, 0, 0, 0, 65536, 0), +(23300, 0, 0, 0, 0, 0, 0, 536870912, 0), +(23555, 0, 0, 0, 0, 593, 0, 0, 0), +(23724, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(23726, 0, 0, 0, 0, 0, 0, 8192, 0), +(23726, 1, 0, 0, 0, 0, 0, 65536, 0), +(24348, 0, 5118, 0, 0, 0, 0, 0, 0), +(24431, 0, 1680, 0, 0, 0, 0, 0, 0), +(24499, 0, 0, 0, 0, 0, 0, 1024, 0), +(24691, 0, 0, 0, 0, 0, 0, 12288, 0), +(24691, 1, 0, 0, 0, 0, 0, 12288, 0), +(26109, 0, 469, 0, 0, 0, 0, 983040, 0), +(26118, 0, 0, 0, 0, 0, 0, 67108864, 0), +(26118, 1, 0, 0, 0, 0, 0, 67108864, 0), +(26174, 0, 0, 0, 0, 0, 0, 32, 0), +(27789, 1, 0, 0, 0, 0, 0, 272630272, 0), +(27790, 1, 0, 0, 0, 0, 0, 272630272, 0), +(27828, 0, 0, 0, 0, 0, 6, 0, 0), +(27846, 0, 0, 0, 0, 0, 0, 32, 0), +(27850, 0, 0, 0, 0, 0, 0, 64, 0), +(27851, 0, 0, 0, 0, 0, 0, 4096, 0), +(28088, 0, 0, 0, 0, 0, 0, 122880, 0), +(28107, 0, 0, 0, 0, 0, 0, 262144, 0), +(28539, 0, 0, 0, 0, 0, 0, 4096, 0), +(28682, 0, 0, 0, 0, 8, 0, 0, 0), +(28743, 0, 0, 0, 0, 0, 0, 240, 0), +(28751, 0, 0, 0, 0, 0, 0, 135168, 0), +(28755, 0, 0, 0, 0, 0, 0, 32, 0), +(28763, 0, 0, 0, 0, 0, 0, 67108864, 0), +(28774, 0, 0, 0, 0, 0, 0, 32768, 0), +(28775, 0, 0, 0, 0, 0, 0, 524288, 0), +(28787, 0, 4987, 0, 0, 0, 0, 0, 0), +(28807, 0, 0, 0, 0, 0, 0, 64, 0), +(28811, 0, 0, 0, 0, 0, 0, 33685510, 0), +(28818, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(28821, 0, 0, 0, 0, 0, 0, 1024, 0), +(28829, 0, 0, 0, 0, 0, 0, 2, 0), +(28830, 0, 0, 0, 0, 0, 0, 262144, 0), +(28831, 0, 0, 0, 0, 0, 0, 1, 0), +(28843, 0, 0, 0, 0, 0, 0, 557056, 0), +(28844, 0, 0, 0, 0, 0, 0, 1024, 0), +(28852, 0, 0, 0, 0, 0, 0, 512, 0), +(28852, 1, 0, 0, 0, 0, 0, 536870912, 0), +(28999, 0, 0, 0, 0, 0, 0, 3, 0), +(29000, 0, 0, 0, 0, 0, 0, 3, 0), +(29005, 0, 0, 0, 0, 0, 0, 2416967683, 0), +(29063, 0, 0, 0, 0, 0, 11, 0, 0), +(29079, 0, 0, 0, 0, 0, 0, 4194304, 0), +(29079, 1, 0, 0, 0, 0, 0, 16777216, 0), +(29079, 2, 0, 0, 0, 0, 0, 8388608, 0), +(29080, 0, 0, 0, 0, 0, 0, 4194304, 0), +(29080, 1, 0, 0, 0, 0, 0, 16777216, 0), +(29080, 2, 0, 0, 0, 0, 0, 8388608, 0), +(29171, 0, 0, 0, 0, 0, 0, 16384, 0), +(29187, 0, 0, 0, 0, 0, 0, 448, 0), +(29189, 0, 0, 0, 0, 0, 0, 448, 0), +(29191, 0, 0, 0, 0, 0, 0, 448, 0), +(29202, 0, 0, 0, 0, 0, 0, 64, 0), +(29205, 0, 0, 0, 0, 0, 0, 64, 0), +(29206, 0, 0, 0, 0, 0, 0, 64, 0), +(29438, 0, 0, 20, 0, 0, 0, 0, 0), +(29439, 0, 0, 20, 0, 0, 0, 0, 0), +(29440, 0, 0, 20, 0, 0, 0, 0, 0), +(29721, 0, 1680, 0, 0, 0, 0, 0, 0), +(29723, 0, 0, 0, 0, 0, 0, 2147491856, 0), +(29723, 1, 0, 0, 0, 0, 0, 2147491856, 0), +(29724, 0, 0, 0, 0, 0, 0, 2147491856, 0), +(29724, 1, 0, 0, 0, 0, 0, 2147491856, 0), +(29725, 0, 0, 0, 0, 0, 0, 2147491856, 0), +(29725, 1, 0, 0, 0, 0, 0, 2147491856, 0), +(29776, 0, 1680, 0, 0, 0, 0, 0, 0), +(29787, 0, 0, 0, 0, 0, 4, 0, 0), +(29790, 0, 0, 0, 0, 0, 4, 0, 0), +(29792, 0, 0, 0, 0, 0, 4, 0, 0), +(29836, 0, 0, 0, 0, 0, 0, 32, 0), +(29859, 0, 0, 0, 0, 0, 0, 32, 0), +(29860, 0, 0, 0, 0, 0, 0, 32, 0), +(29861, 0, 0, 0, 0, 0, 0, 32, 0), +(29862, 0, 0, 0, 0, 0, 0, 32, 0), +(29976, 0, 0, 0, 0, 0, 3, 0, 0), +(30049, 0, 0, 0, 0, 0, 0, 524288, 0), +(30051, 0, 0, 0, 0, 0, 0, 524288, 0), +(30052, 0, 0, 0, 0, 0, 0, 524288, 0), +(30054, 0, 0, 0, 634, 0, 0, 0, 0), +(30057, 0, 0, 0, 634, 0, 0, 0, 0), +(30060, 0, 27243, 0, 0, 0, 0, 1026, 0), +(30060, 1, 27243, 0, 0, 0, 0, 1026, 0), +(30060, 2, 0, 0, 0, 355, 0, 0, 0), +(30061, 0, 27243, 0, 0, 0, 0, 1026, 0), +(30061, 1, 27243, 0, 0, 0, 0, 1026, 0), +(30061, 2, 0, 0, 0, 355, 0, 0, 0), +(30062, 0, 27243, 0, 0, 0, 0, 1026, 0), +(30062, 1, 27243, 0, 0, 0, 0, 1026, 0), +(30062, 2, 0, 0, 0, 355, 0, 0, 0), +(30063, 0, 27243, 0, 0, 0, 0, 1026, 0), +(30063, 1, 27243, 0, 0, 0, 0, 1026, 0), +(30063, 2, 0, 0, 0, 355, 0, 0, 0), +(30064, 0, 27243, 0, 0, 0, 0, 1026, 0), +(30064, 1, 27243, 0, 0, 0, 0, 1026, 0), +(30064, 2, 0, 0, 0, 355, 0, 0, 0), +(30085, 0, 0, 0, 0, 355, 0, 0, 0), +(30085, 1, 0, 0, 0, 0, 0, 1024, 0), +(30085, 2, 0, 0, 0, 0, 0, 2, 0), +(30086, 0, 0, 0, 0, 355, 0, 0, 0), +(30086, 1, 0, 0, 0, 0, 0, 1024, 0), +(30086, 2, 0, 0, 0, 0, 0, 2, 0), +(30251, 0, 0, 0, 0, 593, 0, 0, 0), +(30256, 0, 0, 0, 0, 593, 0, 0, 0), +(30288, 0, 0, 0, 0, 0, 0, 1, 0), +(30289, 0, 0, 0, 0, 0, 0, 1, 0), +(30290, 0, 0, 0, 0, 0, 0, 1, 0), +(30291, 0, 0, 0, 0, 0, 0, 1, 0), +(30292, 0, 0, 0, 0, 0, 0, 1, 0), +(30326, 0, 0, 0, 0, 0, 0, 262160, 0), +(30327, 0, 0, 0, 0, 0, 0, 262160, 0), +(30328, 0, 0, 0, 0, 0, 0, 262160, 0), +(30440, 0, 0, 0, 0, 0, 0, 557056, 0), +(30640, 0, 0, 0, 0, 0, 0, 256, 0), +(30649, 0, 0, 0, 0, 0, 0, 256, 0), +(30872, 0, 0, 0, 0, 0, 0, 256, 0), +(30873, 0, 0, 0, 0, 0, 0, 256, 0), +(30892, 0, 0, 0, 0, 0, 0, 134217728, 0), +(30893, 0, 0, 0, 0, 0, 0, 134217728, 0), +(31226, 0, 0, 0, 0, 0, 0, 122880, 0), +(31227, 0, 0, 0, 0, 0, 0, 122880, 0), +(31234, 0, 0, 0, 0, 0, 8, 0, 0), +(31234, 1, 0, 0, 0, 0, 8, 0, 0), +(31235, 0, 0, 0, 0, 0, 8, 0, 0), +(31235, 1, 0, 0, 0, 0, 8, 0, 0), +(31236, 0, 0, 0, 0, 0, 8, 0, 0), +(31236, 1, 0, 0, 0, 0, 8, 0, 0), +(31237, 0, 0, 0, 0, 0, 8, 0, 0), +(31237, 1, 0, 0, 0, 0, 8, 0, 0), +(31238, 0, 0, 0, 0, 0, 8, 0, 0), +(31238, 1, 0, 0, 0, 0, 8, 0, 0), +(31569, 0, 0, 0, 0, 0, 0, 65536, 0), +(31570, 0, 0, 0, 0, 0, 0, 65536, 0), +(31571, 0, 12536, 0, 0, 0, 0, 0, 0), +(31572, 0, 12536, 0, 0, 0, 0, 0, 0), +(31573, 0, 12536, 0, 0, 0, 0, 0, 0), +(31579, 0, 0, 0, 0, 0, 0, 2048, 0), +(31579, 1, 0, 0, 0, 0, 0, 2048, 0), +(31582, 0, 0, 0, 0, 0, 0, 2048, 0), +(31582, 1, 0, 0, 0, 0, 0, 2048, 0), +(31583, 0, 0, 0, 0, 0, 0, 2048, 0), +(31583, 1, 0, 0, 0, 0, 0, 2048, 0), +(31656, 0, 0, 0, 0, 0, 0, 1, 0), +(31657, 0, 0, 0, 0, 0, 0, 1, 0), +(31658, 0, 0, 0, 0, 0, 0, 1, 0), +(31659, 0, 0, 0, 0, 0, 0, 1, 0), +(31660, 0, 0, 0, 0, 0, 0, 1, 0), +(31682, 0, 0, 0, 0, 0, 0, 32, 0), +(31682, 1, 0, 0, 0, 0, 0, 32, 0), +(31683, 0, 0, 0, 0, 0, 0, 32, 0), +(31683, 1, 0, 0, 0, 0, 0, 32, 0), +(31684, 0, 0, 0, 0, 0, 0, 32, 0), +(31684, 1, 0, 0, 0, 0, 0, 32, 0), +(31685, 1, 0, 0, 0, 0, 0, 32, 0), +(31686, 0, 0, 0, 0, 0, 0, 32, 0), +(31686, 1, 0, 0, 0, 0, 0, 32, 0), +(31821, 0, 0, 0, 0, 0, 0, 67108864, 0), +(31825, 0, 4987, 0, 0, 0, 0, 32, 0), +(31826, 0, 4987, 0, 0, 0, 0, 32, 0), +(31834, 0, 0, 0, 0, 0, 0, 16384, 0), +(31844, 1, 0, 0, 0, 0, 10, 0, 0), +(31845, 1, 0, 0, 0, 0, 10, 0, 0), +(31848, 0, 0, 0, 0, 0, 0, 4194304, 0), +(31848, 1, 0, 0, 0, 0, 0, 4194304, 0), +(31849, 0, 0, 0, 0, 0, 0, 4194304, 0), +(31849, 1, 0, 0, 0, 0, 0, 4194304, 0), +(31869, 0, 20218, 0, 0, 0, 0, 0, 0), +(31870, 0, 20218, 0, 0, 0, 0, 0, 0), +(31879, 0, 0, 0, 0, 0, 0, 8388608, 0), +(31880, 0, 0, 0, 0, 0, 0, 8388608, 0), +(31881, 0, 0, 0, 0, 0, 0, 8388608, 0), +(31882, 0, 0, 0, 0, 0, 0, 8388608, 0), +(31883, 0, 0, 0, 0, 0, 0, 8388608, 0), +(32043, 0, 0, 0, 0, 0, 0, 536870912, 0), +(32203, 1, 0, 0, 0, 0, 9, 0, 0), +(32381, 0, 0, 0, 0, 0, 0, 2, 0), +(32382, 0, 0, 0, 0, 0, 0, 2, 0), +(32383, 0, 0, 0, 0, 0, 0, 2, 0), +(32412, 0, 0, 0, 0, 0, 0, 1024, 0), +(32743, 0, 0, 0, 0, 0, 0, 2048, 0), +(32973, 0, 0, 0, 0, 0, 0, 2416967680, 0), +(33018, 0, 17364, 0, 0, 0, 0, 0, 0), +(33020, 0, 0, 0, 0, 0, 0, 1024, 0), +(33066, 0, 0, 0, 0, 0, 0, 2, 0), +(33151, 0, 0, 0, 0, 0, 0, 128, 1), +(33151, 1, 0, 0, 0, 0, 0, 128, 1), +(33151, 2, 0, 0, 0, 0, 0, 128, 1), +(33158, 0, 0, 0, 0, 0, 0, 4096, 0), +(33158, 1, 0, 0, 0, 0, 0, 2048, 0), +(33159, 0, 0, 0, 0, 0, 0, 4096, 0), +(33159, 1, 0, 0, 0, 0, 0, 2048, 0), +(33160, 0, 0, 0, 0, 0, 0, 4096, 0), +(33160, 1, 0, 0, 0, 0, 0, 2048, 0), +(33161, 0, 0, 0, 0, 0, 0, 4096, 0), +(33161, 1, 0, 0, 0, 0, 0, 2048, 0), +(33162, 0, 0, 0, 0, 0, 0, 4096, 0), +(33162, 1, 0, 0, 0, 0, 0, 2048, 0), +(33174, 0, 0, 0, 0, 0, 0, 32, 0), +(33174, 1, 0, 0, 0, 0, 0, 32, 0), +(33182, 0, 0, 0, 0, 0, 0, 32, 0), +(33182, 1, 0, 0, 0, 0, 0, 32, 0), +(33213, 0, 0, 0, 0, 0, 0, 8527872, 0), +(33214, 0, 0, 0, 0, 0, 0, 8527872, 0), +(33215, 0, 0, 0, 0, 0, 0, 8527872, 0), +(33216, 0, 0, 0, 0, 0, 0, 8527872, 0), +(33217, 0, 0, 0, 0, 0, 0, 8527872, 0), +(33221, 0, 0, 0, 1169, 0, 0, 8192, 0), +(33222, 0, 0, 0, 1169, 0, 0, 8192, 0), +(33223, 0, 0, 0, 1169, 0, 0, 8192, 0), +(33224, 0, 0, 0, 1169, 0, 0, 8192, 0), +(33225, 0, 0, 0, 1169, 0, 0, 8192, 0), +(33333, 0, 0, 0, 0, 0, 0, 536870912, 0), +(33557, 0, 0, 0, 0, 0, 0, 512, 0), +(33557, 1, 0, 0, 0, 0, 0, 536870912, 0), +(33565, 0, 0, 0, 0, 0, 0, 4096, 0), +(33600, 0, 0, 0, 0, 0, 0, 1024, 0), +(33600, 1, 0, 0, 0, 0, 0, 1024, 0), +(33601, 0, 0, 0, 0, 0, 0, 1024, 0), +(33601, 1, 0, 0, 0, 0, 0, 1024, 0), +(33602, 0, 0, 0, 0, 0, 0, 1024, 0), +(33602, 1, 0, 0, 0, 0, 0, 1024, 0), +(33603, 0, 0, 0, 0, 0, 0, 4, 0), +(33603, 1, 0, 0, 0, 0, 0, 1, 0), +(33604, 0, 0, 0, 0, 0, 0, 4, 0), +(33604, 1, 0, 0, 0, 0, 0, 1, 0), +(33605, 0, 0, 0, 0, 0, 0, 4, 0), +(33605, 1, 0, 0, 0, 0, 0, 1, 0), +(33606, 0, 0, 0, 0, 0, 0, 4, 0), +(33606, 1, 0, 0, 0, 0, 0, 1, 0), +(33607, 0, 0, 0, 0, 0, 0, 4, 0), +(33607, 1, 0, 0, 0, 0, 0, 1, 0), +(33693, 0, 0, 0, 0, 0, 0, 32768, 0), +(33696, 0, 0, 0, 0, 0, 0, 1, 0), +(33830, 0, 33786, 0, 0, 0, 0, 0, 0), +(33830, 1, 33786, 0, 0, 0, 0, 0, 0), +(33877, 0, 0, 0, 0, 0, 0, 2, 0), +(33879, 0, 0, 0, 0, 0, 0, 32, 0), +(33880, 0, 0, 0, 0, 0, 0, 32, 0), +(33886, 0, 0, 0, 0, 0, 0, 16, 0), +(33887, 0, 0, 0, 0, 0, 0, 16, 0), +(33888, 0, 0, 0, 0, 0, 0, 16, 0), +(33889, 0, 0, 0, 0, 0, 0, 16, 0), +(33890, 0, 0, 0, 0, 0, 0, 16, 0), +(34128, 0, 33763, 0, 0, 0, 0, 0, 0), +(34129, 0, 0, 0, 0, 0, 0, 8192, 0), +(34129, 1, 0, 0, 0, 0, 0, 8192, 0), +(34131, 0, 0, 0, 0, 0, 0, 128, 0), +(34131, 1, 0, 0, 0, 0, 0, 128, 0), +(34253, 0, 33745, 0, 0, 0, 0, 0, 0), +(34297, 0, 24932, 0, 0, 0, 0, 0, 0), +(34300, 0, 24932, 0, 0, 0, 0, 0, 0), +(34301, 0, 24932, 0, 0, 0, 0, 0, 0), +(34323, 0, 0, 0, 0, 0, 0, 8388608, 0), +(34491, 0, 0, 0, 0, 0, 0, 194, 0), +(34491, 1, 0, 0, 0, 0, 0, 128, 0), +(34492, 0, 0, 0, 0, 0, 0, 194, 0), +(34492, 1, 0, 0, 0, 0, 0, 128, 0), +(34493, 0, 0, 0, 0, 0, 0, 194, 0), +(34493, 1, 0, 0, 0, 0, 0, 128, 0), +(34754, 0, 32546, 0, 0, 0, 0, 6144, 0), +(34936, 0, 0, 0, 0, 0, 0, 1, 0), +(34948, 1, 0, 0, 0, 0, 0, 32, 0), +(34949, 1, 0, 0, 0, 0, 0, 32, 0), +(35098, 0, 0, 0, 0, 0, 0, 133121, 0), +(35099, 0, 0, 0, 0, 0, 0, 133121, 0), +(35104, 0, 0, 0, 0, 0, 0, 4096, 0), +(35104, 1, 0, 0, 0, 0, 0, 8192, 0), +(35110, 0, 0, 0, 0, 0, 0, 4096, 0), +(35110, 1, 0, 0, 0, 0, 0, 8192, 0), +(35111, 0, 0, 0, 0, 0, 0, 4096, 0), +(35111, 1, 0, 0, 0, 0, 0, 8192, 0), +(35363, 0, 0, 0, 0, 0, 0, 5, 0), +(35364, 0, 0, 0, 0, 0, 0, 5, 0), +(35396, 0, 0, 0, 0, 0, 0, 536870912, 0), +(35397, 0, 0, 0, 0, 0, 0, 536870912, 0), +(35578, 0, 0, 0, 0, 0, 3, 0, 0), +(35581, 0, 0, 0, 0, 0, 3, 0, 0), +(36032, 0, 0, 0, 0, 0, 0, 536870912, 0), +(36032, 1, 0, 0, 0, 0, 0, 536870912, 0), +(36413, 0, 0, 0, 0, 0, 0, 1, 0), +(36591, 2, 0, 0, 0, 0, 11, 0, 0), +(37166, 0, 0, 0, 0, 0, 0, 131072, 0), +(37167, 0, 0, 0, 0, 0, 0, 262144, 0), +(37171, 0, 0, 0, 0, 0, 0, 4063232, 0), +(37180, 0, 0, 0, 0, 0, 0, 32, 0), +(37181, 0, 31789, 0, 0, 0, 0, 0, 0), +(37182, 0, 0, 0, 0, 0, 0, 0, 0), +(37183, 0, 20216, 0, 0, 0, 0, 0, 0), +(37185, 0, 0, 0, 931, 0, 0, 0, 0), +(37186, 0, 0, 0, 0, 0, 0, 536870912, 0), +(37188, 0, 0, 0, 0, 0, 0, 64, 0), +(37189, 0, 0, 0, 0, 0, 0, 16384, 0), +(37190, 0, 0, 0, 0, 0, 0, 8, 0), +(37191, 0, 0, 0, 931, 0, 0, 0, 0), +(37194, 0, 0, 0, 0, 0, 0, 8388608, 0), +(37207, 0, 0, 0, 0, 0, 0, 2, 0), +(37210, 0, 0, 0, 0, 0, 0, 16384, 0), +(37211, 0, 16188, 0, 0, 0, 0, 0, 0), +(37212, 0, 2895, 0, 0, 0, 0, 0, 0), +(37223, 0, 0, 0, 0, 0, 0, 65536, 0), +(37224, 0, 32175, 0, 0, 0, 0, 0, 0), +(37225, 0, 0, 0, 0, 0, 0, 128, 0), +(37227, 0, 0, 0, 0, 0, 0, 64, 0), +(37234, 0, 0, 0, 0, 0, 0, 128, 0), +(37240, 0, 0, 0, 0, 0, 0, 128, 0), +(37286, 0, 0, 0, 0, 0, 0, 16, 0), +(37287, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(37292, 0, 16188, 0, 0, 0, 0, 0, 0), +(37297, 0, 29166, 0, 0, 0, 0, 0, 0), +(37313, 0, 0, 0, 0, 0, 0, 64, 0), +(37314, 0, 33763, 0, 0, 0, 0, 0, 0), +(37316, 0, 0, 0, 0, 0, 0, 64, 0), +(37325, 0, 0, 0, 0, 0, 0, 64, 0), +(37333, 0, 0, 0, 0, 0, 0, 32768, 0), +(37333, 1, 33745, 0, 0, 0, 0, 0, 0), +(37376, 0, 27243, 0, 0, 0, 0, 0, 0), +(37380, 0, 0, 0, 0, 0, 0, 6, 0), +(37423, 0, 0, 0, 0, 0, 0, 4, 0), +(37438, 0, 0, 0, 0, 0, 0, 33, 0), +(37439, 0, 12043, 0, 0, 0, 0, 0, 0), +(37439, 1, 0, 0, 0, 0, 0, 8388608, 0), +(37439, 2, 11958, 0, 0, 0, 0, 0, 0), +(37441, 0, 0, 0, 0, 0, 0, 4096, 0), +(37441, 1, 0, 0, 0, 0, 0, 4096, 0), +(37447, 0, 0, 0, 30, 0, 0, 0, 0), +(37481, 0, 0, 0, 0, 0, 0, 128, 0), +(37484, 0, 0, 0, 0, 0, 0, 256, 0), +(37485, 0, 0, 0, 0, 0, 0, 4096, 0), +(37505, 0, 34120, 0, 0, 0, 0, 0, 0), +(37507, 0, 0, 0, 0, 0, 0, 2048, 0), +(37512, 0, 469, 0, 0, 0, 0, 983040, 0), +(37513, 0, 0, 0, 0, 0, 0, 1, 0), +(37517, 0, 0, 0, 0, 0, 4, 0, 0), +(37518, 0, 1680, 0, 0, 0, 0, 0, 0), +(37522, 0, 0, 0, 0, 0, 0, 4096, 0), +(37535, 0, 0, 0, 0, 0, 0, 33554432, 0), +(37536, 0, 0, 0, 0, 0, 0, 65536, 0), +(37556, 0, 32546, 0, 0, 0, 0, 0, 0), +(37564, 0, 0, 0, 0, 0, 0, 512, 0), +(37565, 0, 0, 0, 0, 0, 0, 4096, 0), +(37570, 1, 34433, 0, 0, 0, 0, 0, 0), +(37571, 0, 0, 0, 0, 0, 0, 8388736, 0), +(37593, 0, 0, 0, 0, 0, 0, 64, 0), +(37722, 0, 0, 0, 0, 0, 0, 448, 0), +(37723, 0, 0, 0, 0, 0, 0, 24576, 0), +(37737, 0, 0, 0, 0, 0, 0, 64, 0), +(37738, 0, 0, 0, 0, 0, 0, 64, 0), +(37739, 0, 0, 0, 0, 0, 0, 16384, 0), +(37740, 0, 0, 0, 0, 0, 0, 1, 0), +(37742, 0, 0, 0, 931, 0, 0, 0, 0), +(37760, 0, 0, 0, 0, 0, 0, 1, 0), +(37762, 0, 17364, 0, 0, 0, 0, 0, 0), +(37879, 0, 0, 0, 0, 0, 0, 24576, 0), +(37881, 0, 0, 0, 0, 0, 0, 448, 0), +(38314, 0, 0, 0, 0, 0, 0, 3791650816, 0), +(38321, 0, 0, 0, 0, 0, 0, 32, 0), +(38322, 0, 0, 0, 0, 0, 0, 256, 0), +(38388, 0, 0, 0, 0, 0, 0, 262144, 0), +(38389, 0, 0, 0, 0, 0, 0, 6, 0), +(38390, 0, 34074, 0, 0, 0, 0, 0, 0), +(38392, 0, 34120, 0, 0, 0, 0, 0, 0), +(38393, 0, 0, 0, 0, 0, 0, 1, 0), +(38396, 0, 0, 0, 0, 0, 0, 67108864, 0), +(38397, 0, 0, 0, 0, 0, 0, 2081, 0), +(38398, 0, 0, 0, 0, 0, 0, 4194304, 0), +(38399, 0, 0, 0, 0, 0, 0, 33554432, 0), +(38408, 0, 469, 0, 0, 0, 0, 0, 0), +(38410, 0, 0, 0, 0, 0, 0, 512, 0), +(38411, 0, 0, 0, 0, 0, 0, 4096, 0), +(38412, 0, 0, 0, 0, 0, 0, 8192, 0), +(38413, 0, 0, 0, 0, 0, 0, 32768, 0), +(38414, 0, 0, 0, 0, 0, 0, 2, 0), +(38415, 0, 0, 0, 0, 0, 0, 4, 0), +(38416, 0, 0, 0, 0, 0, 0, 8388608, 0), +(38416, 1, 0, 0, 0, 0, 0, 8388608, 0), +(38417, 0, 5375, 0, 0, 0, 0, 0, 0), +(38420, 0, 0, 0, 0, 0, 0, 32, 0), +(38422, 0, 0, 0, 0, 0, 0, 32, 0), +(38425, 0, 0, 0, 0, 0, 0, 1073741824, 0), +(38426, 0, 0, 0, 0, 0, 0, 2147483648, 0), +(38429, 0, 0, 0, 0, 0, 0, 2416967680, 0), +(38434, 0, 0, 0, 0, 0, 0, 1048832, 0), +(38435, 0, 0, 0, 0, 0, 0, 1048704, 0), +(38436, 0, 0, 0, 0, 0, 0, 1048577, 0), +(38466, 0, 16188, 0, 0, 0, 0, 0, 0), +(38499, 0, 16188, 0, 0, 0, 0, 0, 0), +(38501, 0, 0, 0, 0, 0, 0, 1048704, 0), +(38522, 0, 0, 0, 0, 0, 0, 1073741824, 0); diff --git a/sql/updates/0.7/3766_spell_proc_event.sql b/sql/updates/0.7/3766_spell_proc_event.sql new file mode 100644 index 000000000..b045b7af4 --- /dev/null +++ b/sql/updates/0.7/3766_spell_proc_event.sql @@ -0,0 +1,4 @@ +REPLACE INTO `spell_proc_event` VALUES (15286, 16, 0, 0, 0, 32768, 0); +REPLACE INTO `spell_proc_event` VALUES (34914, 16, 0, 0, 0, 32768, 0); +REPLACE INTO `spell_proc_event` VALUES (34916, 16, 0, 0, 0, 32768, 0); +REPLACE INTO `spell_proc_event` VALUES (34917, 16, 0, 0, 0, 32768, 0); \ No newline at end of file diff --git a/sql/updates/0.7/3771_creature_template.sql b/sql/updates/0.7/3771_creature_template.sql new file mode 100644 index 000000000..4240c80f5 --- /dev/null +++ b/sql/updates/0.7/3771_creature_template.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `npcflag` = (`npcflag` | 0x10000) & ~0x40 WHERE `npcflag` & 0x40 = 0x40 AND `name` NOT LIKE '%spirit guide%'; diff --git a/sql/updates/0.7/3773.sql b/sql/updates/0.7/3773.sql new file mode 100644 index 000000000..6aa0b34b0 --- /dev/null +++ b/sql/updates/0.7/3773.sql @@ -0,0 +1,3 @@ +ALTER TABLE `corpse` ADD INDEX (`instance`); +ALTER TABLE `creature_respawn` ADD INDEX (`instance`); +ALTER TABLE `gameobject_respawn` ADD INDEX (`instance`); diff --git a/sql/updates/0.7/3774_playercreateinfo_spell.sql b/sql/updates/0.7/3774_playercreateinfo_spell.sql new file mode 100644 index 000000000..aa658850f --- /dev/null +++ b/sql/updates/0.7/3774_playercreateinfo_spell.sql @@ -0,0 +1,7 @@ +INSERT INTO `playercreateinfo_spell` VALUES ('4','11','33948','Flight Form (Passive)',0); +INSERT INTO `playercreateinfo_spell` VALUES ('6','11','33948','Flight Form (Passive)',0); + +INSERT IGNORE INTO `character_spell` +SELECT `character`.`guid`,`playercreateinfo_spell`.`spell` AS `spell`, '65535' AS `slot`,`playercreateinfo_spell`.`Active` AS `active` +FROM `character`,`playercreateinfo_spell` +WHERE `character`.`class`=`playercreateinfo_spell`.`class` AND `character`.`race`=`playercreateinfo_spell`.`race`; \ No newline at end of file diff --git a/sql/updates/0.7/3782_command.sql b/sql/updates/0.7/3782_command.sql new file mode 100644 index 000000000..afacab3e7 --- /dev/null +++ b/sql/updates/0.7/3782_command.sql @@ -0,0 +1 @@ +UPDATE `command` SET help='Syntax:\r\n.reset level [Playername]\r\n Reset level to 1 including reset stats and talents. Equipped items with greater level requirement can be lost.\r\n.reset spells [Playername]\r\n Removes all non-original spells from spellbook.\r\n.reset stats [Playername]\r\n Resets(recalculate) all stats of the targeted player to their original values at current level.\r\n.reset talents [Playername]\r\n Removes all talents of the targeted player.' WHERE name='reset'; diff --git a/sql/updates/0.7/3784_command.sql b/sql/updates/0.7/3784_command.sql new file mode 100644 index 000000000..840071d6c --- /dev/null +++ b/sql/updates/0.7/3784_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'notify'; +INSERT INTO `command` VALUES('notify',1,'Syntax: .notify $MessageToBroadcast\r\n\r\nSend a global message to all players online in screen.'); +UPDATE `command` SET help='Syntax: .announce $MessageToBroadcast\r\n\r\nSend a global message to all players online in chat log.' WHERE name='announce'; + diff --git a/sql/updates/0.7/3787_spell_proc_event.sql b/sql/updates/0.7/3787_spell_proc_event.sql new file mode 100644 index 000000000..4ab289923 --- /dev/null +++ b/sql/updates/0.7/3787_spell_proc_event.sql @@ -0,0 +1,8 @@ +REPLACE INTO `spell_proc_event` VALUES (1120, 0, 0, 0, 0, 4, 0); +REPLACE INTO `spell_proc_event` VALUES (8288, 0, 0, 0, 0, 4, 0); +REPLACE INTO `spell_proc_event` VALUES (8289, 0, 0, 0, 0, 4, 0); +REPLACE INTO `spell_proc_event` VALUES (11675, 0, 0, 0, 0, 4, 0); +REPLACE INTO `spell_proc_event` VALUES (27217, 0, 0, 0, 0, 4, 0); +REPLACE INTO `spell_proc_event` VALUES (24932, 0, 0, 0, 0, 4096, 0); +REPLACE INTO `spell_proc_event` VALUES (31641, 0, 0, 0, 0, 524290, 0); +REPLACE INTO `spell_proc_event` VALUES (31642, 0, 0, 0, 0, 524290, 0); diff --git a/sql/updates/0.7/3801_banAccount.sql b/sql/updates/0.7/3801_banAccount.sql new file mode 100644 index 000000000..5ae903542 --- /dev/null +++ b/sql/updates/0.7/3801_banAccount.sql @@ -0,0 +1,33 @@ +ALTER TABLE `realmd`.`ip_banned` + ADD COLUMN `bandate` INT NOT NULL AFTER `ip`, + ADD COLUMN `unbandate` INT NOT NULL AFTER `bandate`, + ADD COLUMN `bannedby` VARCHAR(50) NOT NULL DEFAULT '[Console]' AFTER `unbandate`, + ADD COLUMN `banreason` VARCHAR(50) NOT NULL DEFAULT 'no reason' AFTER `bannedby`; + +ALTER TABLE `realmd`.`account` + DROP KEY `idx_banned`, + DROP COLUMN `banned`; + +-- +-- Table structure for table `account_banned` +-- + +DROP TABLE IF EXISTS `realmd`.`account_banned`; +CREATE TABLE `realmd`.`account_banned` ( + `id` int(11) NOT NULL COMMENT 'Account id' default '0', + `bandate` bigint(40) NOT NULL default '0', + `unbandate` bigint(40) NOT NULL default '0', + `bannedby` VARCHAR(50) NOT NULL, + `banreason` VARCHAR(255) NOT NULL, + `active` TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (`id`,`bandate`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Ban List'; + +-- +-- Dumping data for table `account_banned` +-- + +LOCK TABLES `realmd`.`account_banned` WRITE; +/*!40000 ALTER TABLE `realmd`.`account_banned` DISABLE KEYS */; +/*!40000 ALTER TABLE `realmd`.`account_banned` ENABLE KEYS */; +UNLOCK TABLES; diff --git a/sql/updates/0.7/3801_command.sql b/sql/updates/0.7/3801_command.sql new file mode 100644 index 000000000..0cf5fefb2 --- /dev/null +++ b/sql/updates/0.7/3801_command.sql @@ -0,0 +1,6 @@ +DELETE FROM `command` WHERE name in ('banaccount', 'banip', 'unbanaccount', 'unbanip'); + +INSERT INTO `command` VALUES ('ban','3','Syntax is: ban $NameOrIp $bantime $reason\r\nBan account or IP and kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like "4d20h3s".'); +INSERT INTO `command` VALUES ('unban','3','Syntax is: unban $NameOrIp\r\nUnban account or IP.'); +INSERT INTO `command` VALUES ('baninfo','3','Syntax is: baninfo \r\nWatch full information about a specific ban.'); +INSERT INTO `command` VALUES ('banlist','3','Syntax is: banlist $NameOrIp\r\nsearches the banlist for a pattern.'); \ No newline at end of file diff --git a/sql/updates/0.7/3802_arena_teams.sql b/sql/updates/0.7/3802_arena_teams.sql new file mode 100644 index 000000000..def91e339 --- /dev/null +++ b/sql/updates/0.7/3802_arena_teams.sql @@ -0,0 +1,44 @@ +/*Table structure for table `arena_team` */ + +DROP TABLE IF EXISTS `arena_team`; + +CREATE TABLE `arena_team` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `name` char(255) NOT NULL, + `captainguid` int(10) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `EmblemStyle` int(10) unsigned NOT NULL default '0', + `EmblemColor` int(10) unsigned NOT NULL default '0', + `BorderStyle` int(10) unsigned NOT NULL default '0', + `BorderColor` int(10) unsigned NOT NULL default '0', + `BackgroundColor` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`arenateamid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Table structure for table `arena_team_member` */ + +DROP TABLE IF EXISTS `arena_team_member`; + +CREATE TABLE `arena_team_member` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `guid` int(10) unsigned NOT NULL default '0', + `played_week` int(10) unsigned NOT NULL default '0', + `wons_week` int(10) unsigned NOT NULL default '0', + `played_season` int(10) unsigned NOT NULL default '0', + `wons_season` int(10) unsigned NOT NULL default '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Table structure for table `arena_team_stats` */ + +DROP TABLE IF EXISTS `arena_team_stats`; + +CREATE TABLE `arena_team_stats` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `rating` int(10) unsigned NOT NULL default '0', + `games` int(10) unsigned NOT NULL default '0', + `wins` int(10) unsigned NOT NULL default '0', + `played` int(10) unsigned NOT NULL default '0', + `wins2` int(10) unsigned NOT NULL default '0', + `rank` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`arenateamid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.7/3802_petitions.sql b/sql/updates/0.7/3802_petitions.sql new file mode 100644 index 000000000..7b4e9b8f2 --- /dev/null +++ b/sql/updates/0.7/3802_petitions.sql @@ -0,0 +1,6 @@ +RENAME TABLE `guild_charter` TO `petition`; +RENAME TABLE `guild_charter_sign` TO `petition_sign`; +ALTER TABLE `petition` + CHANGE COLUMN `guildname` `name` varchar(255) NOT NULL default '', + ADD `type` int(10) unsigned NOT NULL default '0' AFTER `name`; +UPDATE `petition` SET `type`='9'; diff --git a/sql/updates/0.7/3805_spell_proc_event.sql b/sql/updates/0.7/3805_spell_proc_event.sql new file mode 100644 index 000000000..93347648d --- /dev/null +++ b/sql/updates/0.7/3805_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( '27155','27160','27166'); +INSERT INTO `spell_proc_event` VALUES +('27155', '0', '0', '0', '0', '1', '0'), +('27160', '0', '0', '0', '0', '1', '5'), +('27166', '0', '0', '0', '0', '1', '5'); diff --git a/sql/updates/0.7/3806_petitions.sql b/sql/updates/0.7/3806_petitions.sql new file mode 100644 index 000000000..5763635fa --- /dev/null +++ b/sql/updates/0.7/3806_petitions.sql @@ -0,0 +1,8 @@ +ALTER TABLE `petition` + DROP KEY `index_ownerguid_charterguid`, + CHANGE COLUMN `charterguid` `petitionguid` int(10) unsigned default '0', + ADD UNIQUE KEY `index_ownerguid_petitionguid` (`ownerguid`,`petitionguid`); +ALTER TABLE `petition_sign` + DROP PRIMARY KEY, + CHANGE COLUMN `charterguid` `petitionguid` int(10) unsigned default '0', + ADD PRIMARY KEY (`petitionguid`,`playerguid`); diff --git a/sql/updates/0.7/3833_quest_template.sql b/sql/updates/0.7/3833_quest_template.sql new file mode 100644 index 000000000..4d373c853 --- /dev/null +++ b/sql/updates/0.7/3833_quest_template.sql @@ -0,0 +1 @@ +ALTER TABLE `quest_template` CHANGE COLUMN `RewXP` `RewXpOrMoney` int(11) unsigned not null default '0'; \ No newline at end of file diff --git a/sql/updates/0.7/3845_account.sql b/sql/updates/0.7/3845_account.sql new file mode 100644 index 000000000..c014746ee --- /dev/null +++ b/sql/updates/0.7/3845_account.sql @@ -0,0 +1,2 @@ +ALTER TABLE `realmd`.`account` + ADD COLUMN `mutetime` bigint(40) unsigned NOT NULL default '0' AFTER `tbc`; diff --git a/sql/updates/0.7/3845_command.sql b/sql/updates/0.7/3845_command.sql new file mode 100644 index 000000000..0eb5d32c7 --- /dev/null +++ b/sql/updates/0.7/3845_command.sql @@ -0,0 +1,3 @@ +INSERT INTO `command` VALUES('mute',1,'Syntax: .mute $playerName $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName at $timeInMinutes minutes.'); +INSERT INTO `command` VALUES('unmute',1,'Syntax: .unmute $playerName\r\n\r\nRestore chat messaging for any character from account of character $playerName.'); + diff --git a/sql/updates/0.7/3859_spell_affect.sql b/sql/updates/0.7/3859_spell_affect.sql new file mode 100644 index 000000000..6b510b82f --- /dev/null +++ b/sql/updates/0.7/3859_spell_affect.sql @@ -0,0 +1,79 @@ +ALTER TABLE `spell_affect` CHANGE `SpellFamilyMask` `SpellFamilyMask` BIGINT( 20 ) UNSIGNED NOT NULL DEFAULT '0'; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 549755813888 WHERE `SpellId` = 469; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 469; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 17179869184 WHERE `SpellId` = 1680; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 1680; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 1099511627776 WHERE `SpellId` = 2895; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 2895; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 4294967296 WHERE `SpellId` = 3600; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 3600; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 2199023255552 WHERE `SpellId` = 6150; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 6150; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 549755813888 WHERE `SpellId` = 11958; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 11958; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 137438953472 WHERE `SpellId` = 12043; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 12043; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 8589934592 WHERE `SpellId` = 12536; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 12536; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 549755813888 WHERE `SpellId` = 16188; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 16188; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 68719476736 WHERE `SpellId` = 17364; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 17364; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 4194304 WHERE `SpellId` = 18223; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 18223; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 1099511627776 WHERE `SpellId` = 20216; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 20216; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 137438953472 WHERE `SpellId` = 20218; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 20218; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 8796093022208 WHERE `SpellId` = 24932; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 24932; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 68719476736 WHERE `SpellId` = 27243; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 27243; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 17592186044416 WHERE `SpellId` = 29166; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 29166; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 17179869184 WHERE `SpellId` = 31789; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 31789; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 68719476736 WHERE `SpellId` = 32175; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 32175; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 17179869184 WHERE `SpellId` = 32546; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 32546; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 137438953472 WHERE `SpellId` = 33076; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 33076; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 1099511627776 WHERE `SpellId` = 33745; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 33745; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 68719476736 WHERE `SpellId` = 33763; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 33763; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 137438953472 WHERE `SpellId` = 33786; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 33786; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 1125899906842624 WHERE `SpellId` = 34074; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 34074; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 4294967296 WHERE `SpellId` = 34120; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 34120; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` + 1099511627776 WHERE `SpellId` = 34433; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 34433; diff --git a/sql/updates/0.7/3860_creature_template.sql b/sql/updates/0.7/3860_creature_template.sql new file mode 100644 index 000000000..d30c075f7 --- /dev/null +++ b/sql/updates/0.7/3860_creature_template.sql @@ -0,0 +1,2 @@ +UPDATE `creature_template` SET `npcflag`=`npcflag`|1 WHERE `npcflag`&1024 and `npcflag`&512; +UPDATE `creature_template` SET `npcflag`=`npcflag`& ~1024 WHERE `npcflag`&1024 and (`npcflag`&512)=0; \ No newline at end of file diff --git a/sql/updates/0.7/3862_prospecting_loot_template.sql b/sql/updates/0.7/3862_prospecting_loot_template.sql new file mode 100644 index 000000000..9d9fd9251 --- /dev/null +++ b/sql/updates/0.7/3862_prospecting_loot_template.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS `prospecting_loot_template`; +CREATE TABLE `prospecting_loot_template` ( + `entry` int(11) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0', + `ChanceOrRef` float NOT NULL default '100', + `QuestChanceOrGroup` tinyint(3) NOT NULL default '0', + `mincount` tinyint(3) unsigned NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `quest_freeforall` tinyint(3) unsigned NOT NULL default '1', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; diff --git a/sql/updates/0.7/3874_spell_scripts.sql b/sql/updates/0.7/3874_spell_scripts.sql new file mode 100644 index 000000000..085a6848a --- /dev/null +++ b/sql/updates/0.7/3874_spell_scripts.sql @@ -0,0 +1 @@ +INSERT INTO `spell_scripts` VALUES ('25650', '0', '6', '530', '0', '', '-589.9764', '4078.306', '143.258', '4.483047'); \ No newline at end of file diff --git a/sql/updates/0.7/3875_item_template.sql b/sql/updates/0.7/3875_item_template.sql new file mode 100644 index 000000000..1d57fc43f --- /dev/null +++ b/sql/updates/0.7/3875_item_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `item_template` + CHANGE COLUMN `Extra` `RandomProperty_1` int(30) unsigned NOT NULL default '0', + CHANGE COLUMN `unk_203` `RandomProperty_2` int(30) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.7/3876_character_ticket.sql b/sql/updates/0.7/3876_character_ticket.sql new file mode 100644 index 000000000..9fa78a1fc --- /dev/null +++ b/sql/updates/0.7/3876_character_ticket.sql @@ -0,0 +1 @@ +ALTER TABLE `character_ticket` CHANGE `ticket_text` `ticket_text` text; diff --git a/sql/updates/0.7/3884_quest_scripts.sql b/sql/updates/0.7/3884_quest_scripts.sql new file mode 100644 index 000000000..d563dd569 --- /dev/null +++ b/sql/updates/0.7/3884_quest_scripts.sql @@ -0,0 +1,2 @@ +ALTER TABLE `quest_template` ADD `StartScript` int(11) unsigned NOT NULL default '0' AFTER `OfferRewardEmote4`; +ALTER TABLE `scripts` ADD `StartOrFinish` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.7/3891_quest_scripts.sql b/sql/updates/0.7/3891_quest_scripts.sql new file mode 100644 index 000000000..4811d8114 --- /dev/null +++ b/sql/updates/0.7/3891_quest_scripts.sql @@ -0,0 +1,38 @@ +DROP TABLE IF EXISTS `quest_end_scripts`; +CREATE TABLE `quest_end_scripts` ( + `id` int(11) unsigned NOT NULL default '0', + `delay` int(11) unsigned NOT NULL default '0', + `command` int(11) unsigned NOT NULL default '0', + `datalong` int(11) unsigned NOT NULL default '0', + `datalong2` int(11) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `quest_start_scripts`; +CREATE TABLE `quest_start_scripts` ( + `id` int(11) unsigned NOT NULL default '0', + `delay` int(11) unsigned NOT NULL default '0', + `command` int(11) unsigned NOT NULL default '0', + `datalong` int(11) unsigned NOT NULL default '0', + `datalong2` int(11) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + +INSERT INTO `quest_end_scripts` +SELECT `id`,`delay`,`command`,`datalong`,`datalong2`,`datatext`,`x`,`y`,`z`,`o` +FROM `scripts` WHERE `StartOrFinish` = 0; + +INSERT INTO `quest_start_scripts` +SELECT `id`,`delay`,`command`,`datalong`,`datalong2`,`datatext`,`x`,`y`,`z`,`o` +FROM `scripts` WHERE `StartOrFinish` = 1; + +DROP TABLE IF EXISTS `scripts`; diff --git a/sql/updates/0.7/3906_areatrigger_template.sql b/sql/updates/0.7/3906_areatrigger_template.sql new file mode 100644 index 000000000..2a20b349d --- /dev/null +++ b/sql/updates/0.7/3906_areatrigger_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `areatrigger_template` + ADD COLUMN `required_item` int(11) unsigned NOT NULL default '0' AFTER `required_level`; diff --git a/sql/updates/0.7/3929_spell_affect.sql b/sql/updates/0.7/3929_spell_affect.sql new file mode 100644 index 000000000..4b5f9b40c --- /dev/null +++ b/sql/updates/0.7/3929_spell_affect.sql @@ -0,0 +1,38 @@ +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 549755813888 WHERE `Category` = 631; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 631; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 549755813888 WHERE `Category` = 1175; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 1175; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 8589934592 WHERE `Category` = 1169; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 1169; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 8589934592 WHERE `Category` = 1179; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 1179; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 34359738368 WHERE `Category` = 634; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 634; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 274877906944 WHERE `Category` = 931; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 931; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 1099511627776 WHERE `Category` = 30; +UPDATE `spell_affect` SET `Category` = 0 WHERE `Category` = 30; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 8589934592 WHERE `SpellId` = 5375; +UPDATE `spell_affect` SET `SpellId` = '0' WHERE `SpellId` = 5375; + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 68719476736 WHERE (entry=29836 OR entry=29859 OR entry=29860 OR entry=29861 OR entry=29862); + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 25769803776 WHERE (entry=14057 OR entry=14128 OR entry=14132 OR entry=14135 OR entry=14136 OR entry=14137 OR entry=14143 OR entry=14149 OR entry=38389); + +UPDATE `spell_affect` SET `SpellFamilyMask` = `SpellFamilyMask` | 34359738368 WHERE (entry=14057 OR entry=14128 OR entry=14132 OR entry=14135 OR entry=14136 OR entry=14137 OR entry=14143 OR entry=14149 OR entry=38389); + +UPDATE `spell_affect` SET `SpellFamilyMask` = '549764202496' WHERE `entry` =34323 AND `effectId` =0 LIMIT 1; + +UPDATE `spell_affect` SET `SpellFamilyMask` = 38658768896 WHERE (entry=14179 OR entry=37171); + +UPDATE `spell_affect` SET `SpellFamilyMask` = 4406678954000 WHERE (entry=15257 OR entry=15331 OR entry=15332 OR entry=15333 OR entry=15334); +UPDATE `spell_affect` SET `SkillID` = 0 WHERE (entry=15257 OR entry=15331 OR entry=15332 OR entry=15333 OR entry=15334); + +UPDATE `spell_affect` SET `SpellFamilyMask` = 0 WHERE (entry=29836 OR entry=29859); \ No newline at end of file diff --git a/sql/updates/0.7/3932_item_enchantment_template.sql b/sql/updates/0.7/3932_item_enchantment_template.sql new file mode 100644 index 000000000..22970e2d4 --- /dev/null +++ b/sql/updates/0.7/3932_item_enchantment_template.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `item_enchantment_template`; +CREATE TABLE `item_enchantment_template` ( + `entry` int(11) unsigned NOT NULL DEFAULT '0', + `ench` int(10) unsigned NOT NULL DEFAULT '0', + `chance` float unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`,`ench`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item Random Enchantment System'; diff --git a/sql/updates/0.7/3932_item_template.sql b/sql/updates/0.7/3932_item_template.sql new file mode 100644 index 000000000..a2ea7b81b --- /dev/null +++ b/sql/updates/0.7/3932_item_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `item_template` + CHANGE COLUMN `RandomProperty_1` `RandomProperty` int(30) unsigned NOT NULL default '0', + CHANGE COLUMN `RandomProperty_2` `RandomSuffix` int(30) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.7/3939_realmd_account.sql b/sql/updates/0.7/3939_realmd_account.sql new file mode 100644 index 000000000..f39240afa --- /dev/null +++ b/sql/updates/0.7/3939_realmd_account.sql @@ -0,0 +1,2 @@ +ALTER TABLE `realmd`.`account` CHANGE `password` `I` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'authentification hash'; +UPDATE `realmd`.`account` SET `I`=SHA1(CONCAT(UPPER(`username`),':',UPPER(`I`))); diff --git a/sql/updates/0.7/3948_realmd_account.sql b/sql/updates/0.7/3948_realmd_account.sql new file mode 100644 index 000000000..2af4b4d05 --- /dev/null +++ b/sql/updates/0.7/3948_realmd_account.sql @@ -0,0 +1 @@ +ALTER TABLE `realmd`.`account` CHANGE `username` `username` VARCHAR( 32 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; diff --git a/sql/updates/0.7/3951_exploration_basexp.sql b/sql/updates/0.7/3951_exploration_basexp.sql new file mode 100644 index 000000000..0b063249b --- /dev/null +++ b/sql/updates/0.7/3951_exploration_basexp.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `exploration_basexp`; +CREATE TABLE `exploration_basexp` ( + `level` tinyint(2) NOT NULL default '0', + `basexp` int(11) NOT NULL default '0', + PRIMARY KEY (`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Exploration System'; + +INSERT INTO `exploration_basexp` VALUES (0,0),(1,5),(2,15),(3,25),(4,35),(5,45),(6,55),(7,65),(8,70),(9,80),(10,85),(11,90),(12,90),(13,90),(14,100),(15,105),(16,115),(17,125),(18,135),(19,145),(20,155),(21,165),(22,175),(23,185),(24,195),(25,200),(26,210),(27,220),(28,230),(29,240),(30,245),(31,250),(32,255),(33,265),(34,270),(35,275),(36,280),(37,285),(38,285),(39,300),(40,315),(41,330),(42,345),(43,360),(44,375),(45,390),(46,405),(47,420),(48,440),(49,455),(50,470),(51,490),(52,510),(53,530),(54,540),(55,560),(56,580),(57,600),(58,620),(59,640),(60,660),(61,970),(62,1000),(63,1050),(64,1080),(65,1100),(66,1130),(67,1160),(68,1200),(69,1230),(70,1300); \ No newline at end of file diff --git a/sql/updates/0.7/3961_uptime.sql b/sql/updates/0.7/3961_uptime.sql new file mode 100644 index 000000000..aa04d1b6b --- /dev/null +++ b/sql/updates/0.7/3961_uptime.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `uptime`; +CREATE TABLE `uptime` ( + `starttime` bigint(11) unsigned NOT NULL default '0', + `startstring` varchar(64) NOT NULL default '', + `uptime` bigint(11) unsigned NOT NULL default '0', + PRIMARY KEY (`starttime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Uptime system'; diff --git a/sql/updates/0.7/3964_command.sql b/sql/updates/0.7/3964_command.sql new file mode 100644 index 000000000..bf4f73ef0 --- /dev/null +++ b/sql/updates/0.7/3964_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` VALUES ('movecreature',2,'Syntax: .movecreature [#creature_guid]\r\n\r\nMove the targeted creature spawn point to your coordinates.'); diff --git a/sql/updates/0.7/4010_spell_proc_event.sql b/sql/updates/0.7/4010_spell_proc_event.sql new file mode 100644 index 000000000..d289b3bf8 --- /dev/null +++ b/sql/updates/0.7/4010_spell_proc_event.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( '31830','31829','31828'); +INSERT INTO `spell_proc_event` VALUES +('31828', '0', '0', '0', '0', '32768', '0'), +('31829', '0', '0', '0', '0', '32768', '0'), +('31830', '0', '0', '0', '0', '32768', '0'); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( '33776','31785'); +INSERT INTO `spell_proc_event` VALUES +('31785', '0', '0', '0', '0', '536870912', '0'), +('33776', '0', '0', '0', '0', '536870912', '0'); diff --git a/sql/updates/0.7/4012_spell_proc_event.sql b/sql/updates/0.7/4012_spell_proc_event.sql new file mode 100644 index 000000000..6ec8225dd --- /dev/null +++ b/sql/updates/0.7/4012_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 9799, 25988 ); +INSERT INTO `spell_proc_event` VALUES +( 9799,0,0,0,0, 262144,0), +(25988,0,0,0,0, 262144,0); diff --git a/sql/updates/0.7/4018_spell_proc_event.sql b/sql/updates/0.7/4018_spell_proc_event.sql new file mode 100644 index 000000000..2485ad241 --- /dev/null +++ b/sql/updates/0.7/4018_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 20210, 20212, 20213, 20214, 20215 ); +INSERT INTO `spell_proc_event` VALUES +(20210,0,0,0,0,268435456,0), +(20212,0,0,0,0,268435456,0), +(20213,0,0,0,0,268435456,0), +(20214,0,0,0,0,268435456,0), +(20215,0,0,0,0,268435456,0); diff --git a/sql/updates/0.7/4019_spell_chain.sql b/sql/updates/0.7/4019_spell_chain.sql new file mode 100644 index 000000000..c12ef4c6a --- /dev/null +++ b/sql/updates/0.7/4019_spell_chain.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (33776,31785); + +INSERT INTO `spell_chain` VALUES +(31785, 0, 31785, 1), +(33776, 31785, 31785, 2); diff --git a/sql/updates/0.7/4019_spell_proc_event.sql b/sql/updates/0.7/4019_spell_proc_event.sql new file mode 100644 index 000000000..b462a1c9f --- /dev/null +++ b/sql/updates/0.7/4019_spell_proc_event.sql @@ -0,0 +1,9 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 17106, 17107, 17108 ); +INSERT INTO `spell_proc_event` VALUES +(17106,0,0,0,0,16384,0), +(17107,0,0,0,0,16384,0), +(17108,0,0,0,0,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34303 ); +INSERT INTO `spell_proc_event` VALUES +(34303,0,0,0,0,128,0); diff --git a/sql/updates/0.7/4020_spell_chain.sql b/sql/updates/0.7/4020_spell_chain.sql new file mode 100644 index 000000000..a9732bae4 --- /dev/null +++ b/sql/updates/0.7/4020_spell_chain.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (33736); + +INSERT INTO `spell_chain` VALUES +(33736,24398,24398,2); \ No newline at end of file diff --git a/sql/updates/0.7/4020_spell_proc_event.sql b/sql/updates/0.7/4020_spell_proc_event.sql new file mode 100644 index 000000000..ce3239adc --- /dev/null +++ b/sql/updates/0.7/4020_spell_proc_event.sql @@ -0,0 +1,21 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34082 ); +INSERT INTO `spell_proc_event` VALUES +(34082,0,0,0,0,8192,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 24398, 33736 ); +INSERT INTO `spell_proc_event` VALUES +(24398,0,0,0,0,1049602,0), +(33736,0,0,0,0,1049602,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 324, 325, 905, 945, 8134, 10431, 10432, 25469, 25472 ); +INSERT INTO `spell_proc_event` VALUES +(324,0,0,0,0,1049602,0), +(325,0,0,0,0,1049602,0), +(905,0,0,0,0,1049602,0), +(945,0,0,0,0,1049602,0), +(8134,0,0,0,0,1049602,0), +(10431,0,0,0,0,1049602,0), +(10432,0,0,0,0,1049602,0), + +(25469,0,0,0,0,1049602,0), +(25472,0,0,0,0,1049602,0); diff --git a/sql/updates/0.7/4021_spell_chain.sql b/sql/updates/0.7/4021_spell_chain.sql new file mode 100644 index 000000000..91c887a31 --- /dev/null +++ b/sql/updates/0.7/4021_spell_chain.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (25251, 30335); + +INSERT INTO `spell_chain` VALUES +(25251,23894,23881,5), +(30335,25251,23881,6); diff --git a/sql/updates/0.7/4021_spell_proc_event.sql b/sql/updates/0.7/4021_spell_proc_event.sql new file mode 100644 index 000000000..c12c054b7 --- /dev/null +++ b/sql/updates/0.7/4021_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 25252, 30339 ); +INSERT INTO `spell_proc_event` VALUES +(25252,0,0,0,0,1,0), +(30339,0,0,0,0,1,0); diff --git a/sql/updates/0.7/4023_spell_proc_event.sql b/sql/updates/0.7/4023_spell_proc_event.sql new file mode 100644 index 000000000..a56d1b9ab --- /dev/null +++ b/sql/updates/0.7/4023_spell_proc_event.sql @@ -0,0 +1,11 @@ +ALTER TABLE `spell_proc_event` + CHANGE COLUMN `procFlags` `procFlags` int(11) unsigned NOT NULL default '0'; + +/* on attack miss,dodge,parry and block */ +UPDATE `spell_proc_event` + SET `procFlags` = 3288334336 WHERE `entry` = 26107; + +/* on attack dodge,parry */ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37519 ); +INSERT INTO `spell_proc_event` VALUES +(37519,0,0,0,0,67108864,0); diff --git a/sql/updates/0.7/4026_spell_proc_event.sql b/sql/updates/0.7/4026_spell_proc_event.sql new file mode 100644 index 000000000..f4e4c3243 --- /dev/null +++ b/sql/updates/0.7/4026_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 20177, 20179, 20181, 20180, 20182, 20178 ); +INSERT INTO `spell_proc_event` VALUES +(20177,0,0,0,0,1049602,0), +(20179,0,0,0,0,1049602,0), +(20180,0,0,0,0,1049602,0), +(20181,0,0,0,0,1049602,0), +(20182,0,0,0,0,1049602,0), +(20178,0,0,0,0,1,0); \ No newline at end of file diff --git a/sql/updates/0.7/4028_spell_chain.sql b/sql/updates/0.7/4028_spell_chain.sql new file mode 100644 index 000000000..508bcb2aa --- /dev/null +++ b/sql/updates/0.7/4028_spell_chain.sql @@ -0,0 +1,18 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (33142, 33145, 33146); +INSERT INTO `spell_chain` VALUES +(33142,0,33142,1), +(33145,33142,33142,2), +(33146,33145,33142,3); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (34950, 34594); +INSERT INTO `spell_chain` VALUES +(34950,0,34950,1), +(34594,34950,34950,2); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (34506, 34507, 34508, 34838, 34839); +INSERT INTO `spell_chain` VALUES +(34506,0,34506,1), +(34507,34506,34506,2), +(34508,34507,34506,3), +(34838,34508,34506,4), +(34839,34838,34506,5); \ No newline at end of file diff --git a/sql/updates/0.7/4028_spell_proc_event.sql b/sql/updates/0.7/4028_spell_proc_event.sql new file mode 100644 index 000000000..daa9c491f --- /dev/null +++ b/sql/updates/0.7/4028_spell_proc_event.sql @@ -0,0 +1,35 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 15600 ); +INSERT INTO `spell_proc_event` VALUES +(15600,0,0,0,0,1,3); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33142, 33145, 33146 ); +INSERT INTO `spell_proc_event` VALUES +(33142,0,0,0,0,8658944,0), +(33145,0,0,0,0,8658944,0), +(33146,0,0,0,0,8658944,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 27179 ); +INSERT INTO `spell_proc_event` VALUES +(27179,0,0,0,0,64,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37443 ); +INSERT INTO `spell_proc_event` VALUES +(37443,0,0,0,0,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34774 ); +INSERT INTO `spell_proc_event` VALUES +(34774,0,0,0,0,524289,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34950, 34954 ); +INSERT INTO `spell_proc_event` VALUES +(34950,0,0,0,0,4194304,0), +(34954,0,0,0,0,4194304,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34506, 34507, 34508, 34838, 34839 ); +INSERT INTO `spell_proc_event` VALUES +(34506,0,0,0,0,524288,0), +(34507,0,0,0,0,524288,0), +(34508,0,0,0,0,524288,0), +(34838,0,0,0,0,524288,0), +(34839,0,0,0,0,524288,0); diff --git a/sql/updates/0.7/4031_spell_chain.sql b/sql/updates/0.7/4031_spell_chain.sql new file mode 100644 index 000000000..14a4cf23e --- /dev/null +++ b/sql/updates/0.7/4031_spell_chain.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (34594, 34954); +INSERT INTO `spell_chain` VALUES +(34954,34950,34950,2); + +DELETE FROM `spell_chain` WHERE `spell_id` IN ( 31833, 31835, 31836 ); +INSERT INTO `spell_chain` VALUES +(31833,0,31833,1), +(31835,31833,31833,2), +(31836,31835,31833,3); + diff --git a/sql/updates/0.7/4031_spell_proc_event.sql b/sql/updates/0.7/4031_spell_proc_event.sql new file mode 100644 index 000000000..10e470e06 --- /dev/null +++ b/sql/updates/0.7/4031_spell_proc_event.sql @@ -0,0 +1,45 @@ +ALTER TABLE `spell_proc_event` + ADD COLUMN `SpellFamilyName` smallint(6) unsigned NOT NULL default '0' AFTER `SkillID`, + ADD COLUMN `SpellFamilyMaskNew` bigint(11) unsigned NOT NULL default '0' AFTER `SpellFamilyMask`; + +UPDATE `spell_proc_event` + SET `SpellFamilyMaskNew` = `SpellFamilyMask` WHERE `SpellFamilyMask` > 0; + +UPDATE `spell_proc_event` + SET `SpellFamilyMaskNew` = 4294967295 + `SpellFamilyMask` + 1 WHERE `SpellFamilyMask` < 0; + +ALTER TABLE `spell_proc_event` + DROP COLUMN `SpellFamilyMask`, + CHANGE COLUMN `SpellFamilyMaskNew` `SpellFamilyMask` bigint(40) unsigned NOT NULL default '0'; + + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 31833, 31835, 31836 ); +INSERT INTO `spell_proc_event` VALUES +(31833,0,0,0,10,2147483648,16384,0), +(31835,0,0,0,10,2147483648,16384,0), +(31836,0,0,0,10,2147483648,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33648 ); +INSERT INTO `spell_proc_event` VALUES +(33648,0,0,0,0,0,4096,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34749 ); +INSERT INTO `spell_proc_event` VALUES +(34749,0,0,0,0,0,33554432,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 28789 ); +INSERT INTO `spell_proc_event` VALUES +(28789,0,0,0,10,3221225472,16384,0); /* HL FoL */ + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 26119 ); +INSERT INTO `spell_proc_event` VALUES +(26119,0,0,0,10,2416967683,16384,0); /* LB CL and shaman shocks */ + +UPDATE `spell_proc_event` SET `spellFamilyName`=8 WHERE `entry` IN ( 14195,14194,14190,14193,14186 ); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 20501, 20500 ); +INSERT INTO `spell_proc_event` VALUES +(20500,0,0,0,4,268435456,16384,0), /* BR */ +(20501,0,0,0,4,268435456,16384,0); /* BR */ + diff --git a/sql/updates/0.7/4035_spell_proc_event.sql b/sql/updates/0.7/4035_spell_proc_event.sql new file mode 100644 index 000000000..b88a406bd --- /dev/null +++ b/sql/updates/0.7/4035_spell_proc_event.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 21329, 27857 ); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33191, 33192, 33193, 33194, 33195 ); +INSERT INTO `spell_proc_event` VALUES +(33191,0,0,0,6,4398054932480,16384,0), +(33192,0,0,0,6,4398054932480,16384,0), +(33193,0,0,0,6,4398054932480,16384,0), +(33194,0,0,0,6,4398054932480,16384,0), +(33195,0,0,0,6,4398054932480,16384,0); + diff --git a/sql/updates/0.7/4036_spell_proc_event.sql b/sql/updates/0.7/4036_spell_proc_event.sql new file mode 100644 index 000000000..b48b88112 --- /dev/null +++ b/sql/updates/0.7/4036_spell_proc_event.sql @@ -0,0 +1 @@ +UPDATE spell_proc_event SET procflags=65536 where entry=16164; \ No newline at end of file diff --git a/sql/updates/0.7/4037_spell_proc_event.sql b/sql/updates/0.7/4037_spell_proc_event.sql new file mode 100644 index 000000000..c977f74bc --- /dev/null +++ b/sql/updates/0.7/4037_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 32385, 32387, 32392, 32393, 32394 ); +INSERT INTO `spell_proc_event` VALUES +(32385,0,0,0,6,73014445058,16384,0), +(32387,0,0,0,6,73014445058,16384,0), +(32392,0,0,0,6,73014445058,16384,0), +(32393,0,0,0,6,73014445058,16384,0), +(32394,0,0,0,6,73014445058,16384,0); + diff --git a/sql/updates/0.7/4096_pet.sql b/sql/updates/0.7/4096_pet.sql new file mode 100644 index 000000000..6bf6536ce --- /dev/null +++ b/sql/updates/0.7/4096_pet.sql @@ -0,0 +1,290 @@ +DROP TABLE IF EXISTS `character_pet`; +CREATE TABLE `character_pet` ( + `id` int(11) unsigned NOT NULL default '0', + `entry` int(11) unsigned NOT NULL default '0', + `owner` int(11) unsigned NOT NULL default '0', + `modelid` int(11) unsigned default '0', + `level` int(11) unsigned NOT NULL default '1', + `exp` int(11) unsigned NOT NULL default '0', + `nextlvlexp` int(11) unsigned NOT NULL default '100', + `Reactstate` tinyint(1) unsigned NOT NULL default '0', + `Commandstate` tinyint(1) unsigned NOT NULL default '1', + `loyaltypoints` int(11) NOT NULL default '0', + `loyalty` int(11) unsigned NOT NULL default '0', + `trainpoint` int(11) NOT NULL default '0', + `name` varchar(100) default 'Pet', + `renamed` tinyint(1) unsigned NOT NULL default '0', + `slot` int(11) unsigned NOT NULL default '0', + `curhealth` int(11) unsigned NOT NULL default '1', + `curmana` int(11) unsigned NOT NULL default '0', + `curhappiness` int(11) unsigned NOT NULL default '0', + `savetime` bigint(20) unsigned NOT NULL default '0', + `resettalents_cost` int(11) unsigned NOT NULL default '0', + `resettalents_time` bigint(20) unsigned NOT NULL default '0', + `ABData` longtext, + `TeachSpelldata` longtext, + PRIMARY KEY (`id`), + KEY `owner` (`owner`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +DROP TABLE IF EXISTS `pet_spell`; +CREATE TABLE `pet_spell` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `slot` int(11) unsigned NOT NULL default '0', + `active` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +DROP TABLE IF EXISTS `pet_spell_cooldown`; +CREATE TABLE `pet_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `pet_aura`; +CREATE TABLE `pet_aura` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`,`effect_index`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- ---------------------------- +-- Table structure for petcreateinfo_spell +-- ---------------------------- +DROP TABLE IF EXISTS `petcreateinfo_spell`; +CREATE TABLE `petcreateinfo_spell` ( + `entry` int(11) unsigned NOT NULL DEFAULT '0', + `Spell1` int(11) unsigned NOT NULL DEFAULT '0', + `Spell2` int(11) unsigned NOT NULL DEFAULT '0', + `Spell3` int(11) unsigned NOT NULL DEFAULT '0', + `Spell4` int(11) unsigned NOT NULL DEFAULT '0', + `FamilyPassive` int(11) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet Create Spells'; + +ALTER TABLE `pet_levelstats` ADD `armor` int(10) unsigned NOT NULL default '0' AFTER `mana`; + +INSERT INTO `spell_chain` VALUES ('17253', '0', '17253', '1'); +INSERT INTO `spell_chain` VALUES ('17255', '17253', '17253', '2'); +INSERT INTO `spell_chain` VALUES ('17256', '17255', '17253', '3'); +INSERT INTO `spell_chain` VALUES ('17257', '17256', '17253', '4'); +INSERT INTO `spell_chain` VALUES ('17258', '17257', '17253', '5'); +INSERT INTO `spell_chain` VALUES ('17259', '17258', '17253', '6'); +INSERT INTO `spell_chain` VALUES ('17260', '17259', '17253', '7'); +INSERT INTO `spell_chain` VALUES ('17261', '17260', '17253', '8'); +INSERT INTO `spell_chain` VALUES ('27050', '17261', '17253', '9'); +INSERT INTO `spell_chain` VALUES ('16827', '0', '16827', '1'); +INSERT INTO `spell_chain` VALUES ('16828', '16827', '16827', '2'); +INSERT INTO `spell_chain` VALUES ('16829', '16828', '16827', '3'); +INSERT INTO `spell_chain` VALUES ('16830', '16829', '16827', '4'); +INSERT INTO `spell_chain` VALUES ('16831', '16830', '16827', '5'); +INSERT INTO `spell_chain` VALUES ('16832', '16831', '16827', '6'); +INSERT INTO `spell_chain` VALUES ('3010', '16832', '16827', '7'); +INSERT INTO `spell_chain` VALUES ('3009', '3010', '16827', '8'); +INSERT INTO `spell_chain` VALUES ('27049', '3009', '16827', '9'); +INSERT INTO `spell_chain` VALUES ('1742', '0', '1742', '1'); +INSERT INTO `spell_chain` VALUES ('1753', '1742', '1742', '2'); +INSERT INTO `spell_chain` VALUES ('1754', '1753', '1742', '3'); +INSERT INTO `spell_chain` VALUES ('1755', '1754', '1742', '4'); +INSERT INTO `spell_chain` VALUES ('1756', '1755', '1742', '5'); +INSERT INTO `spell_chain` VALUES ('16697', '1756', '1742', '6'); +INSERT INTO `spell_chain` VALUES ('27048', '16697', '1742', '7'); +INSERT INTO `spell_chain` VALUES ('23099', '0', '23099', '1'); +INSERT INTO `spell_chain` VALUES ('23109', '23099', '23099', '2'); +INSERT INTO `spell_chain` VALUES ('23110', '23109', '23099', '3'); +INSERT INTO `spell_chain` VALUES ('23145', '0', '23145', '1'); +INSERT INTO `spell_chain` VALUES ('23147', '23145', '23145', '2'); +INSERT INTO `spell_chain` VALUES ('23148', '23147', '23145', '3'); +INSERT INTO `spell_chain` VALUES ('2649', '0', '2649', '1'); +INSERT INTO `spell_chain` VALUES ('14916', '2649', '2649', '2'); +INSERT INTO `spell_chain` VALUES ('14917', '14916', '2649', '3'); +INSERT INTO `spell_chain` VALUES ('14918', '14917', '2649', '4'); +INSERT INTO `spell_chain` VALUES ('14919', '14918', '2649', '5'); +INSERT INTO `spell_chain` VALUES ('14920', '14919', '2649', '6'); +INSERT INTO `spell_chain` VALUES ('14921', '14920', '2649', '7'); +INSERT INTO `spell_chain` VALUES ('27047', '14921', '2649', '8'); +INSERT INTO `spell_chain` VALUES ('7371', '0', '7371', '1'); +INSERT INTO `spell_chain` VALUES ('26177', '7371', '7371', '2'); +INSERT INTO `spell_chain` VALUES ('26178', '26177', '7371', '3'); +INSERT INTO `spell_chain` VALUES ('26179', '26178', '7371', '4'); +INSERT INTO `spell_chain` VALUES ('26201', '26179', '7371', '5'); +INSERT INTO `spell_chain` VALUES ('27685', '26201', '7371', '6'); +INSERT INTO `spell_chain` VALUES ('24604', '0', '24604', '1'); +INSERT INTO `spell_chain` VALUES ('24605', '24604', '24604', '2'); +INSERT INTO `spell_chain` VALUES ('24603', '24605', '24604', '3'); +INSERT INTO `spell_chain` VALUES ('24597', '24603', '24604', '4'); +INSERT INTO `spell_chain` VALUES ('24844', '0', '24844', '1'); +INSERT INTO `spell_chain` VALUES ('25008', '24844', '24844', '2'); +INSERT INTO `spell_chain` VALUES ('25009', '25008', '24844', '3'); +INSERT INTO `spell_chain` VALUES ('25010', '25009', '24844', '4'); +INSERT INTO `spell_chain` VALUES ('25011', '25010', '24844', '5'); +INSERT INTO `spell_chain` VALUES ('25012', '25011', '24844', '6'); +INSERT INTO `spell_chain` VALUES ('24450', '0', '24450', '1'); +INSERT INTO `spell_chain` VALUES ('24452', '24450', '24450', '2'); +INSERT INTO `spell_chain` VALUES ('24453', '24452', '24450', '3'); +INSERT INTO `spell_chain` VALUES ('24640', '0', '24640', '1'); +INSERT INTO `spell_chain` VALUES ('24583', '24640', '24640', '2'); +INSERT INTO `spell_chain` VALUES ('24586', '24583', '24640', '3'); +INSERT INTO `spell_chain` VALUES ('24587', '24586', '24640', '4'); +INSERT INTO `spell_chain` VALUES ('27060', '24587', '24640', '5'); +INSERT INTO `spell_chain` VALUES ('24423', '0', '24423', '1'); +INSERT INTO `spell_chain` VALUES ('24577', '24423', '24423', '2'); +INSERT INTO `spell_chain` VALUES ('24578', '24577', '24423', '3'); +INSERT INTO `spell_chain` VALUES ('24579', '24578', '24423', '4'); +INSERT INTO `spell_chain` VALUES ('27051', '24579', '24423', '5'); +INSERT INTO `spell_chain` VALUES ('26064', '0', '26064', '1'); +INSERT INTO `spell_chain` VALUES ('26090', '0', '26090', '1'); +INSERT INTO `spell_chain` VALUES ('26187', '26090', '26090', '2'); +INSERT INTO `spell_chain` VALUES ('26188', '26187', '26090', '3'); +INSERT INTO `spell_chain` VALUES ('27063', '26188', '26090', '4'); +INSERT INTO `spell_chain` VALUES ('34889', '0', '34889', '1'); +INSERT INTO `spell_chain` VALUES ('35323', '34889', '34889', '2'); +INSERT INTO `spell_chain` VALUES ('35290', '0', '35290', '1'); +INSERT INTO `spell_chain` VALUES ('35291', '35290', '35290', '2'); +INSERT INTO `spell_chain` VALUES ('35292', '35291', '35290', '3'); +INSERT INTO `spell_chain` VALUES ('35293', '35292', '35290', '4'); +INSERT INTO `spell_chain` VALUES ('35294', '35293', '35290', '5'); +INSERT INTO `spell_chain` VALUES ('35295', '35294', '35290', '6'); +INSERT INTO `spell_chain` VALUES ('35296', '35295', '35290', '7'); +INSERT INTO `spell_chain` VALUES ('35297', '35296', '35290', '8'); +INSERT INTO `spell_chain` VALUES ('35298', '35297', '35290', '9'); +INSERT INTO `spell_chain` VALUES ('35387', '0', '35387', '1'); +INSERT INTO `spell_chain` VALUES ('35389', '35387', '35387', '2'); +INSERT INTO `spell_chain` VALUES ('35392', '35389', '35387', '3'); +INSERT INTO `spell_chain` VALUES ('35346', '0', '35346', '1'); +INSERT INTO `spell_chain` VALUES ('25076', '0', '25076', '1'); +INSERT INTO `spell_chain` VALUES ('35694', '0', '35694', '1'); +INSERT INTO `spell_chain` VALUES ('35698', '35694', '35694', '2'); +INSERT INTO `spell_chain` VALUES ('4187', '0', '4187', '1'); +INSERT INTO `spell_chain` VALUES ('4188', '4187', '4187', '2'); +INSERT INTO `spell_chain` VALUES ('4189', '4188', '4187', '3'); +INSERT INTO `spell_chain` VALUES ('4190', '4189', '4187', '4'); +INSERT INTO `spell_chain` VALUES ('4191', '4190', '4187', '5'); +INSERT INTO `spell_chain` VALUES ('4192', '4191', '4187', '6'); +INSERT INTO `spell_chain` VALUES ('4193', '4192', '4187', '7'); +INSERT INTO `spell_chain` VALUES ('4194', '4193', '4187', '8'); +INSERT INTO `spell_chain` VALUES ('5041', '4194', '4187', '9'); +INSERT INTO `spell_chain` VALUES ('5042', '5041', '4187', '10'); +INSERT INTO `spell_chain` VALUES ('27062', '5042', '4187', '11'); +INSERT INTO `spell_chain` VALUES ('24545', '0', '24545', '1'); +INSERT INTO `spell_chain` VALUES ('24549', '24545', '24545', '2'); +INSERT INTO `spell_chain` VALUES ('24550', '24549', '24545', '3'); +INSERT INTO `spell_chain` VALUES ('24551', '24550', '24545', '4'); +INSERT INTO `spell_chain` VALUES ('24552', '24551', '24545', '5'); +INSERT INTO `spell_chain` VALUES ('24553', '24552', '24545', '6'); +INSERT INTO `spell_chain` VALUES ('24554', '24553', '24545', '7'); +INSERT INTO `spell_chain` VALUES ('24555', '24554', '24545', '8'); +INSERT INTO `spell_chain` VALUES ('24629', '24555', '24545', '9'); +INSERT INTO `spell_chain` VALUES ('24630', '24629', '24545', '10'); +INSERT INTO `spell_chain` VALUES ('27061', '24630', '24545', '11'); +INSERT INTO `spell_chain` VALUES ('24493', '0', '24493', '1'); +INSERT INTO `spell_chain` VALUES ('24497', '24493', '24493', '2'); +INSERT INTO `spell_chain` VALUES ('24500', '24497', '24493', '3'); +INSERT INTO `spell_chain` VALUES ('24501', '24500', '24493', '4'); +INSERT INTO `spell_chain` VALUES ('27052', '24501', '24493', '5'); +INSERT INTO `spell_chain` VALUES ('23992', '0', '23992', '1'); +INSERT INTO `spell_chain` VALUES ('24439', '23992', '23992', '2'); +INSERT INTO `spell_chain` VALUES ('24444', '24439', '23992', '3'); +INSERT INTO `spell_chain` VALUES ('24445', '24444', '23992', '4'); +INSERT INTO `spell_chain` VALUES ('27053', '24445', '23992', '5'); +INSERT INTO `spell_chain` VALUES ('24446', '0', '24446', '1'); +INSERT INTO `spell_chain` VALUES ('24447', '24446', '24446', '2'); +INSERT INTO `spell_chain` VALUES ('24448', '24447', '24446', '3'); +INSERT INTO `spell_chain` VALUES ('24449', '24448', '24446', '4'); +INSERT INTO `spell_chain` VALUES ('27054', '24449', '24446', '5'); +INSERT INTO `spell_chain` VALUES ('24492', '0', '24492', '1'); +INSERT INTO `spell_chain` VALUES ('24502', '24492', '24492', '2'); +INSERT INTO `spell_chain` VALUES ('24503', '24502', '24492', '3'); +INSERT INTO `spell_chain` VALUES ('24504', '24503', '24492', '4'); +INSERT INTO `spell_chain` VALUES ('27055', '24504', '24492', '5'); +INSERT INTO `spell_chain` VALUES ('24488', '0', '24488', '1'); +INSERT INTO `spell_chain` VALUES ('24505', '24488', '24488', '2'); +INSERT INTO `spell_chain` VALUES ('24506', '24505', '24488', '3'); +INSERT INTO `spell_chain` VALUES ('24507', '24506', '24488', '4'); +INSERT INTO `spell_chain` VALUES ('27056', '24507', '24488', '5'); +INSERT INTO `spell_chain` VALUES ('6307', '0', '6307', '1'); +INSERT INTO `spell_chain` VALUES ('7804', '6307', '6307', '2'); +INSERT INTO `spell_chain` VALUES ('7805', '7804', '6307', '3'); +INSERT INTO `spell_chain` VALUES ('11766', '7805', '6307', '4'); +INSERT INTO `spell_chain` VALUES ('11767', '11766', '6307', '5'); +INSERT INTO `spell_chain` VALUES ('27268', '11767', '6307', '6'); +INSERT INTO `spell_chain` VALUES ('2947', '0', '2947', '1'); +INSERT INTO `spell_chain` VALUES ('8316', '2947', '2947', '2'); +INSERT INTO `spell_chain` VALUES ('8317', '8316', '2947', '3'); +INSERT INTO `spell_chain` VALUES ('11770', '8317', '2947', '4'); +INSERT INTO `spell_chain` VALUES ('11771', '11770', '2947', '5'); +INSERT INTO `spell_chain` VALUES ('27269', '11771', '2947', '6'); +INSERT INTO `spell_chain` VALUES ('3110', '0', '3110', '1'); +INSERT INTO `spell_chain` VALUES ('7799', '3110', '3110', '2'); +INSERT INTO `spell_chain` VALUES ('7800', '7799', '3110', '3'); +INSERT INTO `spell_chain` VALUES ('7801', '7800', '3110', '4'); +INSERT INTO `spell_chain` VALUES ('7802', '7801', '3110', '5'); +INSERT INTO `spell_chain` VALUES ('11762', '7802', '3110', '6'); +INSERT INTO `spell_chain` VALUES ('11763', '11762', '3110', '7'); +INSERT INTO `spell_chain` VALUES ('27267', '11763', '3110', '8'); +INSERT INTO `spell_chain` VALUES ('17767', '0', '17767', '1'); +INSERT INTO `spell_chain` VALUES ('17850', '17767', '17767', '2'); +INSERT INTO `spell_chain` VALUES ('17851', '17850', '17767', '3'); +INSERT INTO `spell_chain` VALUES ('17852', '17851', '17767', '4'); +INSERT INTO `spell_chain` VALUES ('17853', '17852', '17767', '5'); +INSERT INTO `spell_chain` VALUES ('17854', '17853', '17767', '6'); +INSERT INTO `spell_chain` VALUES ('27272', '17854', '17767', '7'); +INSERT INTO `spell_chain` VALUES ('7812', '0', '7812', '1'); +INSERT INTO `spell_chain` VALUES ('19438', '7812', '7812', '2'); +INSERT INTO `spell_chain` VALUES ('19440', '19438', '7812', '3'); +INSERT INTO `spell_chain` VALUES ('19441', '19440', '7812', '4'); +INSERT INTO `spell_chain` VALUES ('19442', '19441', '7812', '5'); +INSERT INTO `spell_chain` VALUES ('19443', '19442', '7812', '6'); +INSERT INTO `spell_chain` VALUES ('27273', '19443', '7812', '7'); +INSERT INTO `spell_chain` VALUES ('17735', '0', '17735', '1'); +INSERT INTO `spell_chain` VALUES ('17750', '17735', '17735', '2'); +INSERT INTO `spell_chain` VALUES ('17751', '17750', '17735', '3'); +INSERT INTO `spell_chain` VALUES ('17752', '17751', '17735', '4'); +INSERT INTO `spell_chain` VALUES ('27271', '17752', '17735', '5'); +INSERT INTO `spell_chain` VALUES ('33701', '27271', '17735', '6'); +INSERT INTO `spell_chain` VALUES ('3716', '0', '3716', '1'); +INSERT INTO `spell_chain` VALUES ('7809', '3716', '3716', '2'); +INSERT INTO `spell_chain` VALUES ('7810', '7809', '3716', '3'); +INSERT INTO `spell_chain` VALUES ('7811', '7810', '3716', '4'); +INSERT INTO `spell_chain` VALUES ('11774', '7811', '3716', '5'); +INSERT INTO `spell_chain` VALUES ('11775', '11774', '3716', '6'); +INSERT INTO `spell_chain` VALUES ('27270', '11775', '3716', '7'); +INSERT INTO `spell_chain` VALUES ('7814', '0', '7814', '1'); +INSERT INTO `spell_chain` VALUES ('7815', '7814', '7814', '2'); +INSERT INTO `spell_chain` VALUES ('7816', '7815', '7814', '3'); +INSERT INTO `spell_chain` VALUES ('11778', '7816', '7814', '4'); +INSERT INTO `spell_chain` VALUES ('11779', '11778', '7814', '5'); +INSERT INTO `spell_chain` VALUES ('11780', '11779', '7814', '6'); +INSERT INTO `spell_chain` VALUES ('27274', '11780', '7814', '7'); +INSERT INTO `spell_chain` VALUES ('6360', '0', '6360', '1'); +INSERT INTO `spell_chain` VALUES ('7813', '6360', '6360', '2'); +INSERT INTO `spell_chain` VALUES ('11784', '7813', '6360', '3'); +INSERT INTO `spell_chain` VALUES ('11785', '11784', '6360', '4'); +INSERT INTO `spell_chain` VALUES ('27275', '11785', '6360', '5'); +INSERT INTO `spell_chain` VALUES ('19505', '0', '19505', '1'); +INSERT INTO `spell_chain` VALUES ('19731', '19505', '19505', '2'); +INSERT INTO `spell_chain` VALUES ('19734', '19731', '19505', '3'); +INSERT INTO `spell_chain` VALUES ('19736', '19734', '19505', '4'); +INSERT INTO `spell_chain` VALUES ('27276', '19736', '19505', '5'); +INSERT INTO `spell_chain` VALUES ('27277', '27276', '19505', '6'); +INSERT INTO `spell_chain` VALUES ('19244', '0', '19244', '1'); +INSERT INTO `spell_chain` VALUES ('19647', '19244', '19244', '2'); +INSERT INTO `spell_chain` VALUES ('19478', '0', '19478', '1'); +INSERT INTO `spell_chain` VALUES ('19655', '19478', '19478', '2'); +INSERT INTO `spell_chain` VALUES ('19656', '19655', '19478', '3'); +INSERT INTO `spell_chain` VALUES ('19660', '19656', '19478', '4'); +INSERT INTO `spell_chain` VALUES ('27280', '19660', '19478', '5'); +INSERT INTO `spell_chain` VALUES ('33698', '0', '33698', '1'); +INSERT INTO `spell_chain` VALUES ('33699', '33698', '33698', '2'); +INSERT INTO `spell_chain` VALUES ('33700', '33699', '33698', '3'); +INSERT INTO `spell_chain` VALUES ('30213', '0', '30213', '1'); +INSERT INTO `spell_chain` VALUES ('30219', '30213', '30213', '2'); +INSERT INTO `spell_chain` VALUES ('30223', '30219', '30213', '3'); +INSERT INTO `spell_chain` VALUES ('30151', '0', '30151', '1'); +INSERT INTO `spell_chain` VALUES ('30194', '30151', '30151', '2'); +INSERT INTO `spell_chain` VALUES ('30198', '30194', '30151', '3'); diff --git a/sql/updates/0.8/4058.sql b/sql/updates/0.8/4058.sql new file mode 100644 index 000000000..e73798a03 --- /dev/null +++ b/sql/updates/0.8/4058.sql @@ -0,0 +1,4 @@ +ALTER TABLE `item_template` ADD COLUMN `ArmorDamageModifier` float NOT NULL default '0' AFTER `RequiredDisenchantSkill`; +ALTER TABLE `item_template` DROP COLUMN `name2`, DROP COLUMN `name3`, DROP COLUMN `name4`; +DELETE FROM `spell_affect` WHERE `entry` in(11370,12288,12288,12707,12707,14067,15019,16183,16823,16823,16825,16825,17325,18310,18311,18312,18313,29860,29861,29862,30440,30640,30649,33216,33217,34301); +DELETE FROM `spell_proc_event` WHERE `entry` in(114,637,646,648,1028,1034,1048,1707,2095,2852,4051,4161,4512,5575,5580,6134,6135,6592,6593,7601,7614,7615,7616,7618,9205,9793,9797,9801,9808,10095,10400,10727,10868,11830,11838,11961,12002,12038,12094,12546,12552,13078,13260,13320,13767,13987,14095,14150,14152,14154,15364,15365,15567,15568,15569,15644,15650,16140,16241,16242,16311,16312,16313,16423,16563,16925,16926,16955,16956,16957,16962,16963,16964,17000,17001,17079,17082,19195,19234,19235,19389,19390,19396,19640,20163,20169,20183,20204,20411,20412,20413,20414,20419,20421,20422,20423,20563,20809,20896,21387,21789,22283,22285,22286,22287,22288,22697,22716,23255,23301,23303,23305,23306,25592,25715,25727,25728,25729,25730,25731,25732,25733,25734,25745,25751,25752,25757,25926,25942,25945,26341,28130,28881,29526); \ No newline at end of file diff --git a/sql/updates/0.8/4059_spell_learn_skill.sql b/sql/updates/0.8/4059_spell_learn_skill.sql new file mode 100644 index 000000000..55b5b8936 --- /dev/null +++ b/sql/updates/0.8/4059_spell_learn_skill.sql @@ -0,0 +1 @@ +DELETE FROM `spell_learn_skill` WHERE `entry` IN ( 3386 ); diff --git a/sql/updates/0.8/4059_spell_learn_spell.sql b/sql/updates/0.8/4059_spell_learn_spell.sql new file mode 100644 index 000000000..b89ef4b15 --- /dev/null +++ b/sql/updates/0.8/4059_spell_learn_spell.sql @@ -0,0 +1 @@ +DELETE FROM `spell_learn_spell` WHERE `SpellID` IN ( 2480, 7918, 7919 ); diff --git a/sql/updates/0.8/4076_character_spell.sql b/sql/updates/0.8/4076_character_spell.sql new file mode 100644 index 000000000..eb11e0291 --- /dev/null +++ b/sql/updates/0.8/4076_character_spell.sql @@ -0,0 +1,6 @@ +DELETE FROM `character_spell` WHERE `spell` = '23301'; + +INSERT IGNORE INTO `character_spell` +SELECT `character`.`guid`,`playercreateinfo_spell`.`spell` AS `spell`, '65535' AS `slot`,`playercreateinfo_spell`.`Active` AS `active` +FROM `character`,`playercreateinfo_spell` +WHERE `character`.`class`=`playercreateinfo_spell`.`class` AND `character`.`race`=`playercreateinfo_spell`.`race`; \ No newline at end of file diff --git a/sql/updates/0.8/4076_playercreateinfo_spell.sql b/sql/updates/0.8/4076_playercreateinfo_spell.sql new file mode 100644 index 000000000..168a7b580 --- /dev/null +++ b/sql/updates/0.8/4076_playercreateinfo_spell.sql @@ -0,0 +1,2016 @@ +DROP TABLE IF EXISTS `playercreateinfo_spell`; +CREATE TABLE `playercreateinfo_spell` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `Spell` bigint(20) unsigned NOT NULL default '0', + `Note` varchar(255) default NULL, + `Active` tinyint(3) unsigned NOT NULL default '1', + PRIMARY KEY (`race`,`class`,`Spell`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `playercreateinfo_spell` VALUES +(1,1,78,'Heroic Strike',1), +(1,1,81,'Dodge',1), +(1,1,107,'Block',1), +(1,1,196,'One-Handed Axes',1), +(1,1,198,'One-Handed Maces',1), +(1,1,201,'One-Handed Swords',1), +(1,1,203,'Unarmed',1), +(1,1,204,'Defense',1), +(1,1,522,'SPELLDEFENSE(DND)',1), +(1,1,668,'Language Common',1), +(1,1,2382,'Generic',1), +(1,1,2457,'Battle Stance',1), +(1,1,2479,'Honorless Target',1), +(1,1,3050,'Detect',1), +(1,1,3365,'Opening',1), +(1,1,5301,'Defensive State(DND)',1), +(1,1,6233,'Closing',1), +(1,1,6246,'Closing',1), +(1,1,6247,'Opening',1), +(1,1,6477,'Opening',1), +(1,1,6478,'Opening',1), +(1,1,6603,'Attack',1), +(1,1,7266,'Duel',1), +(1,1,7267,'Grovel',1), +(1,1,7355,'Stuck',1), +(1,1,7376,'Defensive Stance Passive',0), +(1,1,7381,'Berserker Stance Passive',0), +(1,1,8386,'Attacking',1), +(1,1,8737,'Mail',1), +(1,1,9077,'Leather',1), +(1,1,9078,'Cloth',1), +(1,1,9116,'Shield',1), +(1,1,9125,'Generic',1), +(1,1,20597,'Sword Specialization',1), +(1,1,20598,'The Human Spirit',1), +(1,1,20599,'Diplomacy',1), +(1,1,20600,'Perception',1), +(1,1,20864,'Mace Specialization',1), +(1,1,21156,'Battle Stance Passive',0), +(1,1,21651,'Opening',1), +(1,1,21652,'Closing',1), +(1,1,22027,'Remove Insignia',1), +(1,1,22810,'Opening - No Text',1), +(1,1,32215,'Victorious State',1), +(1,2,81,'Dodge',1), +(1,2,107,'Block',1), +(1,2,198,'One-Handed Maces',1), +(1,2,199,'Two-Handed Maces',1), +(1,2,203,'Unarmed',1), +(1,2,204,'Defense',1), +(1,2,522,'SPELLDEFENSE(DND)',1), +(1,2,635,'Holy Light',1), +(1,2,668,'Language Common',1), +(1,2,2382,'Generic',1), +(1,2,2479,'Honorless Target',1), +(1,2,3050,'Detect',1), +(1,2,3365,'Opening',1), +(1,2,6233,'Closing',1), +(1,2,6246,'Closing',1), +(1,2,6247,'Opening',1), +(1,2,6477,'Opening',1), +(1,2,6478,'Opening',1), +(1,2,6603,'Attack',1), +(1,2,7266,'Duel',1), +(1,2,7267,'Grovel',1), +(1,2,7355,'Stuck',1), +(1,2,8386,'Attacking',1), +(1,2,8737,'Mail',1), +(1,2,9077,'Leather',1), +(1,2,9078,'Cloth',1), +(1,2,9116,'Shield',1), +(1,2,9125,'Generic',1), +(1,2,20154,'Seal of Righteousness',1), +(1,2,20597,'Sword Specialization',1), +(1,2,20598,'The Human Spirit',1), +(1,2,20599,'Diplomacy',1), +(1,2,20600,'Perception',1), +(1,2,20864,'Mace Specialization',1), +(1,2,21651,'Opening',1), +(1,2,21652,'Closing',1), +(1,2,22027,'Remove Insignia',1), +(1,2,22810,'Opening - No Text',1), +(1,2,27762,'Libram',1), +(1,4,81,'Dodge',1), +(1,4,203,'Unarmed',1), +(1,4,204,'Defense',1), +(1,4,522,'SPELLDEFENSE(DND)',1), +(1,4,668,'Language Common',1), +(1,4,1180,'Daggers',1), +(1,4,1752,'Sinister Strike',1), +(1,4,2098,'Eviscerate',1), +(1,4,2382,'Generic',1), +(1,4,2479,'Honorless Target',1), +(1,4,2567,'Thrown',1), +(1,4,2764,'Throw',1), +(1,4,3050,'Detect',1), +(1,4,3365,'Opening',1), +(1,4,6233,'Closing',1), +(1,4,6246,'Closing',1), +(1,4,6247,'Opening',1), +(1,4,6477,'Opening',1), +(1,4,6478,'Opening',1), +(1,4,6603,'Attack',1), +(1,4,7266,'Duel',1), +(1,4,7267,'Grovel',1), +(1,4,7355,'Stuck',1), +(1,4,8386,'Attacking',1), +(1,4,9077,'Leather',1), +(1,4,9078,'Cloth',1), +(1,4,9125,'Generic',1), +(1,4,16092,'Defensive State(DND)',1), +(1,4,20597,'Sword Specialization',1), +(1,4,20598,'The Human Spirit',1), +(1,4,20599,'Diplomacy',1), +(1,4,20600,'Perception',1), +(1,4,20864,'Mace Specialization',1), +(1,4,21184,'Rogue Passive(DND)',1), +(1,4,21651,'Opening',1), +(1,4,21652,'Closing',1), +(1,4,22027,'Remove Insignia',1), +(1,4,22810,'Opening - No Text',1), +(1,5,81,'Dodge',1), +(1,5,198,'One-Handed Maces',1), +(1,5,203,'Unarmed',1), +(1,5,204,'Defense',1), +(1,5,522,'SPELLDEFENSE(DND)',1), +(1,5,585,'Smite',1), +(1,5,668,'Language Common',1), +(1,5,2050,'Lesser Heal',1), +(1,5,2382,'Generic',1), +(1,5,2479,'Honorless Target',1), +(1,5,3050,'Detect',1), +(1,5,3365,'Opening',1), +(1,5,5009,'Wands',1), +(1,5,5019,'Shoot',1), +(1,5,6233,'Closing',1), +(1,5,6246,'Closing',1), +(1,5,6247,'Opening',1), +(1,5,6477,'Opening',1), +(1,5,6478,'Opening',1), +(1,5,6603,'Attack',1), +(1,5,7266,'Duel',1), +(1,5,7267,'Grovel',1), +(1,5,7355,'Stuck',1), +(1,5,8386,'Attacking',1), +(1,5,9078,'Cloth',1), +(1,5,9125,'Generic',1), +(1,5,20597,'Sword Specialization',1), +(1,5,20598,'The Human Spirit',1), +(1,5,20599,'Diplomacy',1), +(1,5,20600,'Perception',1), +(1,5,20864,'Mace Specialization',1), +(1,5,21651,'Opening',1), +(1,5,21652,'Closing',1), +(1,5,22027,'Remove Insignia',1), +(1,5,22810,'Opening - No Text',1), +(1,8,81,'Dodge',1), +(1,8,133,'Fireball',1), +(1,8,168,'Frost Armor',1), +(1,8,203,'Unarmed',1), +(1,8,204,'Defense',1), +(1,8,227,'Staves',1), +(1,8,522,'SPELLDEFENSE(DND)',1), +(1,8,668,'Language Common',1), +(1,8,2382,'Generic',1), +(1,8,2479,'Honorless Target',1), +(1,8,3050,'Detect',1), +(1,8,3365,'Opening',1), +(1,8,5009,'Wands',1), +(1,8,5019,'Shoot',1), +(1,8,6233,'Closing',1), +(1,8,6246,'Closing',1), +(1,8,6247,'Opening',1), +(1,8,6477,'Opening',1), +(1,8,6478,'Opening',1), +(1,8,6603,'Attack',1), +(1,8,7266,'Duel',1), +(1,8,7267,'Grovel',1), +(1,8,7355,'Stuck',1), +(1,8,8386,'Attacking',1), +(1,8,9078,'Cloth',1), +(1,8,9125,'Generic',1), +(1,8,20597,'Sword Specialization',1), +(1,8,20598,'The Human Spirit',1), +(1,8,20599,'Diplomacy',1), +(1,8,20600,'Perception',1), +(1,8,20864,'Mace Specialization',1), +(1,8,21651,'Opening',1), +(1,8,21652,'Closing',1), +(1,8,22027,'Remove Insignia',1), +(1,8,22810,'Opening - No Text',1), +(1,9,81,'Dodge',1), +(1,9,203,'Unarmed',1), +(1,9,204,'Defense',1), +(1,9,522,'SPELLDEFENSE(DND)',1), +(1,9,668,'Language Common',1), +(1,9,686,'Shadow Bolt',1), +(1,9,687,'Demon Skin',1), +(1,9,1180,'Daggers',1), +(1,9,2382,'Generic',1), +(1,9,2479,'Honorless Target',1), +(1,9,3050,'Detect',1), +(1,9,3365,'Opening',1), +(1,9,5009,'Wands',1), +(1,9,5019,'Shoot',1), +(1,9,6233,'Closing',1), +(1,9,6246,'Closing',1), +(1,9,6247,'Opening',1), +(1,9,6477,'Opening',1), +(1,9,6478,'Opening',1), +(1,9,6603,'Attack',1), +(1,9,7266,'Duel',1), +(1,9,7267,'Grovel',1), +(1,9,7355,'Stuck',1), +(1,9,8386,'Attacking',1), +(1,9,9078,'Cloth',1), +(1,9,9125,'Generic',1), +(1,9,20597,'Sword Specialization',1), +(1,9,20598,'The Human Spirit',1), +(1,9,20599,'Diplomacy',1), +(1,9,20600,'Perception',1), +(1,9,20864,'Mace Specialization',1), +(1,9,21651,'Opening',1), +(1,9,21652,'Closing',1), +(1,9,22027,'Remove Insignia',1), +(1,9,22810,'Opening - No Text',1), +(2,1,78,'Heroic Strike',1), +(2,1,81,'Dodge',1), +(2,1,107,'Block',1), +(2,1,196,'One-Handed Axes',1), +(2,1,197,'Two-Handed Axes',1), +(2,1,201,'One-Handed Swords',1), +(2,1,203,'Unarmed',1), +(2,1,204,'Defense',1), +(2,1,522,'SPELLDEFENSE(DND)',1), +(2,1,669,'Language Orcish',1), +(2,1,2382,'Generic',1), +(2,1,2457,'Battle Stance',1), +(2,1,2479,'Honorless Target',1), +(2,1,3050,'Detect',1), +(2,1,3365,'Opening',1), +(2,1,5301,'Defensive State(DND)',1), +(2,1,6233,'Closing',1), +(2,1,6246,'Closing',1), +(2,1,6247,'Opening',1), +(2,1,6477,'Opening',1), +(2,1,6478,'Opening',1), +(2,1,6603,'Attack',1), +(2,1,7266,'Duel',1), +(2,1,7267,'Grovel',1), +(2,1,7355,'Stuck',1), +(2,1,7376,'Defensive Stance Passive',0), +(2,1,7381,'Berserker Stance Passive',0), +(2,1,8386,'Attacking',1), +(2,1,8737,'Mail',1), +(2,1,9077,'Leather',1), +(2,1,9078,'Cloth',1), +(2,1,9116,'Shield',1), +(2,1,9125,'Generic',1), +(2,1,20572,'Blood Fury',1), +(2,1,20573,'Hardiness',1), +(2,1,20574,'Axe Specialization',1), +(2,1,21156,'Battle Stance Passive',0), +(2,1,21563,'Command',1), +(2,1,21651,'Opening',1), +(2,1,21652,'Closing',1), +(2,1,22027,'Remove Insignia',1), +(2,1,22810,'Opening - No Text',1), +(2,1,32215,'Victorious State',1), +(2,3,75,'Auto Shot',1), +(2,3,81,'Dodge',1), +(2,3,196,'One-Handed Axes',1), +(2,3,203,'Unarmed',1), +(2,3,204,'Defense',1), +(2,3,264,'Bows',1), +(2,3,522,'SPELLDEFENSE(DND)',1), +(2,3,669,'Language Orcish',1), +(2,3,2382,'Generic',1), +(2,3,2479,'Honorless Target',1), +(2,3,2973,'Raptor Strike',1), +(2,3,3050,'Detect',1), +(2,3,3365,'Opening',1), +(2,3,6233,'Closing',1), +(2,3,6246,'Closing',1), +(2,3,6247,'Opening',1), +(2,3,6477,'Opening',1), +(2,3,6478,'Opening',1), +(2,3,6603,'Attack',1), +(2,3,7266,'Duel',1), +(2,3,7267,'Grovel',1), +(2,3,7355,'Stuck',1), +(2,3,8386,'Attacking',1), +(2,3,9077,'Leather',1), +(2,3,9078,'Cloth',1), +(2,3,9125,'Generic',1), +(2,3,13358,'Defensive State(DND)',1), +(2,3,20572,'Blood Fury',1), +(2,3,20573,'Hardiness',1), +(2,3,20574,'Axe Specialization',1), +(2,3,20576,'Command',1), +(2,3,21651,'Opening',1), +(2,3,21652,'Closing',1), +(2,3,22027,'Remove Insignia',1), +(2,3,22810,'Opening - No Text',1), +(2,3,24949,'Defensive State 2(DND)',1), +(2,3,34082,'Advantaged State(DND)',1), +(2,4,81,'Dodge',1), +(2,4,203,'Unarmed',1), +(2,4,204,'Defense',1), +(2,4,522,'SPELLDEFENSE(DND)',1), +(2,4,669,'Language Orcish',1), +(2,4,1180,'Daggers',1), +(2,4,1752,'Sinister Strike',1), +(2,4,2098,'Eviscerate',1), +(2,4,2382,'Generic',1), +(2,4,2479,'Honorless Target',1), +(2,4,2567,'Thrown',1), +(2,4,2764,'Throw',1), +(2,4,3050,'Detect',1), +(2,4,3365,'Opening',1), +(2,4,6233,'Closing',1), +(2,4,6246,'Closing',1), +(2,4,6247,'Opening',1), +(2,4,6477,'Opening',1), +(2,4,6478,'Opening',1), +(2,4,6603,'Attack',1), +(2,4,7266,'Duel',1), +(2,4,7267,'Grovel',1), +(2,4,7355,'Stuck',1), +(2,4,8386,'Attacking',1), +(2,4,9077,'Leather',1), +(2,4,9078,'Cloth',1), +(2,4,9125,'Generic',1), +(2,4,16092,'Defensive State(DND)',1), +(2,4,20572,'Blood Fury',1), +(2,4,20573,'Hardiness',1), +(2,4,20574,'Axe Specialization',1), +(2,4,21184,'Rogue Passive(DND)',1), +(2,4,21563,'Command',1), +(2,4,21651,'Opening',1), +(2,4,21652,'Closing',1), +(2,4,22027,'Remove Insignia',1), +(2,4,22810,'Opening - No Text',1), +(2,7,81,'Dodge',1), +(2,7,107,'Block',1), +(2,7,198,'One-Handed Maces',1), +(2,7,203,'Unarmed',1), +(2,7,204,'Defense',1), +(2,7,227,'Staves',1), +(2,7,331,'Healing Wave',1), +(2,7,403,'Lightning Bolt',1), +(2,7,522,'SPELLDEFENSE(DND)',1), +(2,7,669,'Language Orcish',1), +(2,7,2382,'Generic',1), +(2,7,2479,'Honorless Target',1), +(2,7,3050,'Detect',1), +(2,7,3365,'Opening',1), +(2,7,6233,'Closing',1), +(2,7,6246,'Closing',1), +(2,7,6247,'Opening',1), +(2,7,6477,'Opening',1), +(2,7,6478,'Opening',1), +(2,7,6603,'Attack',1), +(2,7,7266,'Duel',1), +(2,7,7267,'Grovel',1), +(2,7,7355,'Stuck',1), +(2,7,8386,'Attacking',1), +(2,7,9077,'Leather',1), +(2,7,9078,'Cloth',1), +(2,7,9116,'Shield',1), +(2,7,9125,'Generic',1), +(2,7,20573,'Hardiness',1), +(2,7,20574,'Axe Specialization',1), +(2,7,21563,'Command',1), +(2,7,21651,'Opening',1), +(2,7,21652,'Closing',1), +(2,7,22027,'Remove Insignia',1), +(2,7,22810,'Opening - No Text',1), +(2,7,27763,'Totem',1), +(2,7,33697,'Blood Fury',1), +(2,9,81,'Dodge',1), +(2,9,203,'Unarmed',1), +(2,9,204,'Defense',1), +(2,9,522,'SPELLDEFENSE(DND)',1), +(2,9,669,'Language Orcish',1), +(2,9,686,'Shadow Bolt',1), +(2,9,687,'Demon Skin',1), +(2,9,1180,'Daggers',1), +(2,9,2382,'Generic',1), +(2,9,2479,'Honorless Target',1), +(2,9,3050,'Detect',1), +(2,9,3365,'Opening',1), +(2,9,5009,'Wands',1), +(2,9,5019,'Shoot',1), +(2,9,6233,'Closing',1), +(2,9,6246,'Closing',1), +(2,9,6247,'Opening',1), +(2,9,6477,'Opening',1), +(2,9,6478,'Opening',1), +(2,9,6603,'Attack',1), +(2,9,7266,'Duel',1), +(2,9,7267,'Grovel',1), +(2,9,7355,'Stuck',1), +(2,9,8386,'Attacking',1), +(2,9,9078,'Cloth',1), +(2,9,9125,'Generic',1), +(2,9,20573,'Hardiness',1), +(2,9,20574,'Axe Specialization',1), +(2,9,20575,'Command',1), +(2,9,21651,'Opening',1), +(2,9,21652,'Closing',1), +(2,9,22027,'Remove Insignia',1), +(2,9,22810,'Opening - No Text',1), +(2,9,33702,'Blood Fury',1), +(3,1,78,'Heroic Strike',1), +(3,1,81,'Dodge',1), +(3,1,107,'Block',1), +(3,1,196,'One-Handed Axes',1), +(3,1,197,'Two-Handed Axes',1), +(3,1,198,'One-Handed Maces',1), +(3,1,203,'Unarmed',1), +(3,1,204,'Defense',1), +(3,1,522,'SPELLDEFENSE(DND)',1), +(3,1,668,'Language Common',1), +(3,1,672,'Language Dwarven',1), +(3,1,2382,'Generic',1), +(3,1,2457,'Battle Stance',1), +(3,1,2479,'Honorless Target',1), +(3,1,2481,'Find Treasure',1), +(3,1,3050,'Detect',1), +(3,1,3365,'Opening',1), +(3,1,5301,'Defensive State(DND)',1), +(3,1,6233,'Closing',1), +(3,1,6246,'Closing',1), +(3,1,6247,'Opening',1), +(3,1,6477,'Opening',1), +(3,1,6478,'Opening',1), +(3,1,6603,'Attack',1), +(3,1,7266,'Duel',1), +(3,1,7267,'Grovel',1), +(3,1,7355,'Stuck',1), +(3,1,7376,'Defensive Stance Passive',0), +(3,1,7381,'Berserker Stance Passive',0), +(3,1,8386,'Attacking',1), +(3,1,8737,'Mail',1), +(3,1,9077,'Leather',1), +(3,1,9078,'Cloth',1), +(3,1,9116,'Shield',1), +(3,1,9125,'Generic',1), +(3,1,20594,'Stoneform',1), +(3,1,20595,'Gun Specialization',1), +(3,1,20596,'Frost Resistance',1), +(3,1,21156,'Battle Stance Passive',0), +(3,1,21651,'Opening',1), +(3,1,21652,'Closing',1), +(3,1,22027,'Remove Insignia',1), +(3,1,22810,'Opening - No Text',1), +(3,1,32215,'Victorious State',1), +(3,2,81,'Dodge',1), +(3,2,107,'Block',1), +(3,2,198,'One-Handed Maces',1), +(3,2,199,'Two-Handed Maces',1), +(3,2,203,'Unarmed',1), +(3,2,204,'Defense',1), +(3,2,522,'SPELLDEFENSE(DND)',1), +(3,2,635,'Holy Light',1), +(3,2,668,'Language Common',1), +(3,2,672,'Language Dwarven',1), +(3,2,2382,'Generic',1), +(3,2,2479,'Honorless Target',1), +(3,2,2481,'Find Treasure',1), +(3,2,3050,'Detect',1), +(3,2,3365,'Opening',1), +(3,2,6233,'Closing',1), +(3,2,6246,'Closing',1), +(3,2,6247,'Opening',1), +(3,2,6477,'Opening',1), +(3,2,6478,'Opening',1), +(3,2,6603,'Attack',1), +(3,2,7266,'Duel',1), +(3,2,7267,'Grovel',1), +(3,2,7355,'Stuck',1), +(3,2,8386,'Attacking',1), +(3,2,8737,'Mail',1), +(3,2,9077,'Leather',1), +(3,2,9078,'Cloth',1), +(3,2,9116,'Shield',1), +(3,2,9125,'Generic',1), +(3,2,20154,'Seal of Righteousness',1), +(3,2,20594,'Stoneform',1), +(3,2,20595,'Gun Specialization',1), +(3,2,20596,'Frost Resistance',1), +(3,2,21651,'Opening',1), +(3,2,21652,'Closing',1), +(3,2,22027,'Remove Insignia',1), +(3,2,22810,'Opening - No Text',1), +(3,2,27762,'Libram',1), +(3,3,75,'Auto Shot',1), +(3,3,81,'Dodge',1), +(3,3,196,'One-Handed Axes',1), +(3,3,203,'Unarmed',1), +(3,3,204,'Defense',1), +(3,3,266,'Guns',1), +(3,3,522,'SPELLDEFENSE(DND)',1), +(3,3,668,'Language Common',1), +(3,3,672,'Language Dwarven',1), +(3,3,2382,'Generic',1), +(3,3,2479,'Honorless Target',1), +(3,3,2481,'Find Treasure',1), +(3,3,2973,'Raptor Strike',1), +(3,3,3050,'Detect',1), +(3,3,3365,'Opening',1), +(3,3,6233,'Closing',1), +(3,3,6246,'Closing',1), +(3,3,6247,'Opening',1), +(3,3,6477,'Opening',1), +(3,3,6478,'Opening',1), +(3,3,6603,'Attack',1), +(3,3,7266,'Duel',1), +(3,3,7267,'Grovel',1), +(3,3,7355,'Stuck',1), +(3,3,8386,'Attacking',1), +(3,3,9077,'Leather',1), +(3,3,9078,'Cloth',1), +(3,3,9125,'Generic',1), +(3,3,13358,'Defensive State(DND)',1), +(3,3,20594,'Stoneform',1), +(3,3,20595,'Gun Specialization',1), +(3,3,20596,'Frost Resistance',1), +(3,3,21651,'Opening',1), +(3,3,21652,'Closing',1), +(3,3,22027,'Remove Insignia',1), +(3,3,22810,'Opening - No Text',1), +(3,3,24949,'Defensive State 2(DND)',1), +(3,3,34082,'Advantaged State(DND)',1), +(3,4,81,'Dodge',1), +(3,4,203,'Unarmed',1), +(3,4,204,'Defense',1), +(3,4,522,'SPELLDEFENSE(DND)',1), +(3,4,668,'Language Common',1), +(3,4,672,'Language Dwarven',1), +(3,4,1180,'Daggers',1), +(3,4,1752,'Sinister Strike',1), +(3,4,2098,'Eviscerate',1), +(3,4,2382,'Generic',1), +(3,4,2479,'Honorless Target',1), +(3,4,2481,'Find Treasure',1), +(3,4,2567,'Thrown',1), +(3,4,2764,'Throw',1), +(3,4,3050,'Detect',1), +(3,4,3365,'Opening',1), +(3,4,6233,'Closing',1), +(3,4,6246,'Closing',1), +(3,4,6247,'Opening',1), +(3,4,6477,'Opening',1), +(3,4,6478,'Opening',1), +(3,4,6603,'Attack',1), +(3,4,7266,'Duel',1), +(3,4,7267,'Grovel',1), +(3,4,7355,'Stuck',1), +(3,4,8386,'Attacking',1), +(3,4,9077,'Leather',1), +(3,4,9078,'Cloth',1), +(3,4,9125,'Generic',1), +(3,4,16092,'Defensive State(DND)',1), +(3,4,20594,'Stoneform',1), +(3,4,20595,'Gun Specialization',1), +(3,4,20596,'Frost Resistance',1), +(3,4,21184,'Rogue Passive(DND)',1), +(3,4,21651,'Opening',1), +(3,4,21652,'Closing',1), +(3,4,22027,'Remove Insignia',1), +(3,4,22810,'Opening - No Text',1), +(3,5,81,'Dodge',1), +(3,5,198,'One-Handed Maces',1), +(3,5,203,'Unarmed',1), +(3,5,204,'Defense',1), +(3,5,522,'SPELLDEFENSE(DND)',1), +(3,5,585,'Smite',1), +(3,5,668,'Language Common',1), +(3,5,672,'Language Dwarven',1), +(3,5,2050,'Lesser Heal',1), +(3,5,2382,'Generic',1), +(3,5,2479,'Honorless Target',1), +(3,5,2481,'Find Treasure',1), +(3,5,3050,'Detect',1), +(3,5,3365,'Opening',1), +(3,5,5009,'Wands',1), +(3,5,5019,'Shoot',1), +(3,5,6233,'Closing',1), +(3,5,6246,'Closing',1), +(3,5,6247,'Opening',1), +(3,5,6477,'Opening',1), +(3,5,6478,'Opening',1), +(3,5,6603,'Attack',1), +(3,5,7266,'Duel',1), +(3,5,7267,'Grovel',1), +(3,5,7355,'Stuck',1), +(3,5,8386,'Attacking',1), +(3,5,9078,'Cloth',1), +(3,5,9125,'Generic',1), +(3,5,20594,'Stoneform',1), +(3,5,20595,'Gun Specialization',1), +(3,5,20596,'Frost Resistance',1), +(3,5,21651,'Opening',1), +(3,5,21652,'Closing',1), +(3,5,22027,'Remove Insignia',1), +(3,5,22810,'Opening - No Text',1), +(4,1,78,'Heroic Strike',1), +(4,1,81,'Dodge',1), +(4,1,107,'Block',1), +(4,1,198,'One-Handed Maces',1), +(4,1,201,'One-Handed Swords',1), +(4,1,203,'Unarmed',1), +(4,1,204,'Defense',1), +(4,1,522,'SPELLDEFENSE(DND)',1), +(4,1,668,'Language Common',1), +(4,1,671,'Language Darnassian',1), +(4,1,1180,'Daggers',1), +(4,1,2382,'Generic',1), +(4,1,2457,'Battle Stance',1), +(4,1,2479,'Honorless Target',1), +(4,1,3050,'Detect',1), +(4,1,3365,'Opening',1), +(4,1,5301,'Defensive State(DND)',1), +(4,1,6233,'Closing',1), +(4,1,6246,'Closing',1), +(4,1,6247,'Opening',1), +(4,1,6477,'Opening',1), +(4,1,6478,'Opening',1), +(4,1,6603,'Attack',1), +(4,1,7266,'Duel',1), +(4,1,7267,'Grovel',1), +(4,1,7355,'Stuck',1), +(4,1,7376,'Defensive Stance Passive',0), +(4,1,7381,'Berserker Stance Passive',0), +(4,1,8386,'Attacking',1), +(4,1,8737,'Mail',1), +(4,1,9077,'Leather',1), +(4,1,9078,'Cloth',1), +(4,1,9116,'Shield',1), +(4,1,9125,'Generic',1), +(4,1,20580,'Shadowmeld',1), +(4,1,20582,'Quickness',1), +(4,1,20583,'Nature Resistance',1), +(4,1,20585,'Wisp Spirit',1), +(4,1,21009,'Shadowmeld Passive',1), +(4,1,21156,'Battle Stance Passive',0), +(4,1,21651,'Opening',1), +(4,1,21652,'Closing',1), +(4,1,22027,'Remove Insignia',1), +(4,1,22810,'Opening - No Text',1), +(4,1,32215,'Victorious State',1), +(4,3,75,'Auto Shot',1), +(4,3,81,'Dodge',1), +(4,3,203,'Unarmed',1), +(4,3,204,'Defense',1), +(4,3,264,'Bows',1), +(4,3,522,'SPELLDEFENSE(DND)',1), +(4,3,668,'Language Common',1), +(4,3,671,'Language Darnassian',1), +(4,3,1180,'Daggers',1), +(4,3,2382,'Generic',1), +(4,3,2479,'Honorless Target',1), +(4,3,2973,'Raptor Strike',1), +(4,3,3050,'Detect',1), +(4,3,3365,'Opening',1), +(4,3,6233,'Closing',1), +(4,3,6246,'Closing',1), +(4,3,6247,'Opening',1), +(4,3,6477,'Opening',1), +(4,3,6478,'Opening',1), +(4,3,6603,'Attack',1), +(4,3,7266,'Duel',1), +(4,3,7267,'Grovel',1), +(4,3,7355,'Stuck',1), +(4,3,8386,'Attacking',1), +(4,3,9077,'Leather',1), +(4,3,9078,'Cloth',1), +(4,3,9125,'Generic',1), +(4,3,13358,'Defensive State(DND)',1), +(4,3,20580,'Shadowmeld',1), +(4,3,20582,'Quickness',1), +(4,3,20583,'Nature Resistance',1), +(4,3,20585,'Wisp Spirit',1), +(4,3,21009,'Shadowmeld Passive',1), +(4,3,21651,'Opening',1), +(4,3,21652,'Closing',1), +(4,3,22027,'Remove Insignia',1), +(4,3,22810,'Opening - No Text',1), +(4,3,24949,'Defensive State 2(DND)',1), +(4,3,34082,'Advantaged State(DND)',1), +(4,4,81,'Dodge',1), +(4,4,203,'Unarmed',1), +(4,4,204,'Defense',1), +(4,4,522,'SPELLDEFENSE(DND)',1), +(4,4,668,'Language Common',1), +(4,4,671,'Language Darnassian',1), +(4,4,1180,'Daggers',1), +(4,4,1752,'Sinister Strike',1), +(4,4,2098,'Eviscerate',1), +(4,4,2382,'Generic',1), +(4,4,2479,'Honorless Target',1), +(4,4,2567,'Thrown',1), +(4,4,2764,'Throw',1), +(4,4,3050,'Detect',1), +(4,4,3365,'Opening',1), +(4,4,6233,'Closing',1), +(4,4,6246,'Closing',1), +(4,4,6247,'Opening',1), +(4,4,6477,'Opening',1), +(4,4,6478,'Opening',1), +(4,4,6603,'Attack',1), +(4,4,7266,'Duel',1), +(4,4,7267,'Grovel',1), +(4,4,7355,'Stuck',1), +(4,4,8386,'Attacking',1), +(4,4,9077,'Leather',1), +(4,4,9078,'Cloth',1), +(4,4,9125,'Generic',1), +(4,4,16092,'Defensive State(DND)',1), +(4,4,20580,'Shadowmeld',1), +(4,4,20582,'Quickness',1), +(4,4,20583,'Nature Resistance',1), +(4,4,20585,'Wisp Spirit',1), +(4,4,21009,'Shadowmeld Passive',1), +(4,4,21184,'Rogue Passive(DND)',1), +(4,4,21651,'Opening',1), +(4,4,21652,'Closing',1), +(4,4,22027,'Remove Insignia',1), +(4,4,22810,'Opening - No Text',1), +(4,5,81,'Dodge',1), +(4,5,198,'One-Handed Maces',1), +(4,5,203,'Unarmed',1), +(4,5,204,'Defense',1), +(4,5,522,'SPELLDEFENSE(DND)',1), +(4,5,585,'Smite',1), +(4,5,668,'Language Common',1), +(4,5,671,'Language Darnassian',1), +(4,5,2050,'Lesser Heal',1), +(4,5,2382,'Generic',1), +(4,5,2479,'Honorless Target',1), +(4,5,3050,'Detect',1), +(4,5,3365,'Opening',1), +(4,5,5009,'Wands',1), +(4,5,5019,'Shoot',1), +(4,5,6233,'Closing',1), +(4,5,6246,'Closing',1), +(4,5,6247,'Opening',1), +(4,5,6477,'Opening',1), +(4,5,6478,'Opening',1), +(4,5,6603,'Attack',1), +(4,5,7266,'Duel',1), +(4,5,7267,'Grovel',1), +(4,5,7355,'Stuck',1), +(4,5,8386,'Attacking',1), +(4,5,9078,'Cloth',1), +(4,5,9125,'Generic',1), +(4,5,20580,'Shadowmeld',1), +(4,5,20582,'Quickness',1), +(4,5,20583,'Nature Resistance',1), +(4,5,20585,'Wisp Spirit',1), +(4,5,21009,'Shadowmeld Passive',1), +(4,5,21651,'Opening',1), +(4,5,21652,'Closing',1), +(4,5,22027,'Remove Insignia',1), +(4,5,22810,'Opening - No Text',1), +(4,11,81,'Dodge',1), +(4,11,203,'Unarmed',1), +(4,11,204,'Defense',1), +(4,11,227,'Staves',1), +(4,11,522,'SPELLDEFENSE(DND)',1), +(4,11,668,'Language Common',1), +(4,11,671,'Language Darnassian',1), +(4,11,1178,'Bear Form(Passive)',0), +(4,11,1180,'Daggers',1), +(4,11,2382,'Generic',1), +(4,11,2479,'Honorless Target',1), +(4,11,3025,'Cat Form(Passive)',0), +(4,11,3050,'Detect',1), +(4,11,3365,'Opening',1), +(4,11,5176,'Wrath',1), +(4,11,5185,'Healing Touch',1), +(4,11,5419,'Travel Form(Passive)',0), +(4,11,5420,'Tree of Life',0), +(4,11,5421,'Aquatic Form(Passive)',0), +(4,11,6233,'Closing',1), +(4,11,6246,'Closing',1), +(4,11,6247,'Opening',1), +(4,11,6477,'Opening',1), +(4,11,6478,'Opening',1), +(4,11,6603,'Attack',1), +(4,11,7266,'Duel',1), +(4,11,7267,'Grovel',1), +(4,11,7355,'Stuck',1), +(4,11,8386,'Attacking',1), +(4,11,9077,'Leather',1), +(4,11,9078,'Cloth',1), +(4,11,9125,'Generic',1), +(4,11,9635,'Dire Bear Form(Passive)',0), +(4,11,20580,'Shadowmeld',1), +(4,11,20582,'Quickness',1), +(4,11,20583,'Nature Resistance',1), +(4,11,20585,'Wisp Spirit',1), +(4,11,21009,'Shadowmeld Passive',1), +(4,11,21178,'Bear Form(Passive2)',0), +(4,11,21651,'Opening',1), +(4,11,21652,'Closing',1), +(4,11,22027,'Remove Insignia',1), +(4,11,22810,'Opening - No Text',1), +(4,11,24905,'Moonkin Form(Passive)',0), +(4,11,27764,'Fetish',1), +(4,11,33948,'Flight Form(Passive)',0), +(4,11,34123,'Tree of Life(Passive)',0), +(4,11,40121,'Swift Flight Form(Passive)',0), +(5,1,78,'Heroic Strike',1), +(5,1,81,'Dodge',1), +(5,1,107,'Block',1), +(5,1,201,'One-Handed Swords',1), +(5,1,202,'Two-Handed Swords',1), +(5,1,203,'Unarmed',1), +(5,1,204,'Defense',1), +(5,1,522,'SPELLDEFENSE(DND)',1), +(5,1,669,'Language Orcish',1), +(5,1,1180,'Daggers',1), +(5,1,2382,'Generic',1), +(5,1,2457,'Battle Stance',1), +(5,1,2479,'Honorless Target',1), +(5,1,3050,'Detect',1), +(5,1,3365,'Opening',1), +(5,1,5227,'Underwater Breathing',1), +(5,1,5301,'Defensive State(DND)',1), +(5,1,6233,'Closing',1), +(5,1,6246,'Closing',1), +(5,1,6247,'Opening',1), +(5,1,6477,'Opening',1), +(5,1,6478,'Opening',1), +(5,1,6603,'Attack',1), +(5,1,7266,'Duel',1), +(5,1,7267,'Grovel',1), +(5,1,7355,'Stuck',1), +(5,1,7376,'Defensive Stance Passive',0), +(5,1,7381,'Berserker Stance Passive',0), +(5,1,7744,'Will of the Forsaken',1), +(5,1,8386,'Attacking',1), +(5,1,8737,'Mail',1), +(5,1,9077,'Leather',1), +(5,1,9078,'Cloth',1), +(5,1,9116,'Shield',1), +(5,1,9125,'Generic',1), +(5,1,17737,'Language Gutterspeak',1), +(5,1,20577,'Cannibalize',1), +(5,1,20579,'Shadow Resistance',1), +(5,1,21156,'Battle Stance Passive',0), +(5,1,21651,'Opening',1), +(5,1,21652,'Closing',1), +(5,1,22027,'Remove Insignia',1), +(5,1,22810,'Opening - No Text',1), +(5,1,32215,'Victorious State',1), +(5,4,81,'Dodge',1), +(5,4,203,'Unarmed',1), +(5,4,204,'Defense',1), +(5,4,522,'SPELLDEFENSE(DND)',1), +(5,4,669,'Language Orcish',1), +(5,4,1180,'Daggers',1), +(5,4,1752,'Sinister Strike',1), +(5,4,2098,'Eviscerate',1), +(5,4,2382,'Generic',1), +(5,4,2479,'Honorless Target',1), +(5,4,2567,'Thrown',1), +(5,4,2764,'Throw',1), +(5,4,3050,'Detect',1), +(5,4,3365,'Opening',1), +(5,4,5227,'Underwater Breathing',1), +(5,4,6233,'Closing',1), +(5,4,6246,'Closing',1), +(5,4,6247,'Opening',1), +(5,4,6477,'Opening',1), +(5,4,6478,'Opening',1), +(5,4,6603,'Attack',1), +(5,4,7266,'Duel',1), +(5,4,7267,'Grovel',1), +(5,4,7355,'Stuck',1), +(5,4,7744,'Will of the Forsaken',1), +(5,4,8386,'Attacking',1), +(5,4,9077,'Leather',1), +(5,4,9078,'Cloth',1), +(5,4,9125,'Generic',1), +(5,4,16092,'Defensive State(DND)',1), +(5,4,17737,'Language Gutterspeak',1), +(5,4,20577,'Cannibalize',1), +(5,4,20579,'Shadow Resistance',1), +(5,4,21184,'Rogue Passive(DND)',1), +(5,4,21651,'Opening',1), +(5,4,21652,'Closing',1), +(5,4,22027,'Remove Insignia',1), +(5,4,22810,'Opening - No Text',1), +(5,5,81,'Dodge',1), +(5,5,198,'One-Handed Maces',1), +(5,5,203,'Unarmed',1), +(5,5,204,'Defense',1), +(5,5,522,'SPELLDEFENSE(DND)',1), +(5,5,585,'Smite',1), +(5,5,669,'Language Orcish',1), +(5,5,2050,'Lesser Heal',1), +(5,5,2382,'Generic',1), +(5,5,2479,'Honorless Target',1), +(5,5,3050,'Detect',1), +(5,5,3365,'Opening',1), +(5,5,5009,'Wands',1), +(5,5,5019,'Shoot',1), +(5,5,5227,'Underwater Breathing',1), +(5,5,6233,'Closing',1), +(5,5,6246,'Closing',1), +(5,5,6247,'Opening',1), +(5,5,6477,'Opening',1), +(5,5,6478,'Opening',1), +(5,5,6603,'Attack',1), +(5,5,7266,'Duel',1), +(5,5,7267,'Grovel',1), +(5,5,7355,'Stuck',1), +(5,5,7744,'Will of the Forsaken',1), +(5,5,8386,'Attacking',1), +(5,5,9078,'Cloth',1), +(5,5,9125,'Generic',1), +(5,5,17737,'Language Gutterspeak',1), +(5,5,20577,'Cannibalize',1), +(5,5,20579,'Shadow Resistance',1), +(5,5,21651,'Opening',1), +(5,5,21652,'Closing',1), +(5,5,22027,'Remove Insignia',1), +(5,5,22810,'Opening - No Text',1), +(5,8,81,'Dodge',1), +(5,8,133,'Fireball',1), +(5,8,168,'Frost Armor',1), +(5,8,203,'Unarmed',1), +(5,8,204,'Defense',1), +(5,8,227,'Staves',1), +(5,8,522,'SPELLDEFENSE(DND)',1), +(5,8,669,'Language Orcish',1), +(5,8,2382,'Generic',1), +(5,8,2479,'Honorless Target',1), +(5,8,3050,'Detect',1), +(5,8,3365,'Opening',1), +(5,8,5009,'Wands',1), +(5,8,5019,'Shoot',1), +(5,8,5227,'Underwater Breathing',1), +(5,8,6233,'Closing',1), +(5,8,6246,'Closing',1), +(5,8,6247,'Opening',1), +(5,8,6477,'Opening',1), +(5,8,6478,'Opening',1), +(5,8,6603,'Attack',1), +(5,8,7266,'Duel',1), +(5,8,7267,'Grovel',1), +(5,8,7355,'Stuck',1), +(5,8,7744,'Will of the Forsaken',1), +(5,8,8386,'Attacking',1), +(5,8,9078,'Cloth',1), +(5,8,9125,'Generic',1), +(5,8,17737,'Language Gutterspeak',1), +(5,8,20577,'Cannibalize',1), +(5,8,20579,'Shadow Resistance',1), +(5,8,21651,'Opening',1), +(5,8,21652,'Closing',1), +(5,8,22027,'Remove Insignia',1), +(5,8,22810,'Opening - No Text',1), +(5,9,81,'Dodge',1), +(5,9,203,'Unarmed',1), +(5,9,204,'Defense',1), +(5,9,522,'SPELLDEFENSE(DND)',1), +(5,9,669,'Language Orcish',1), +(5,9,686,'Shadow Bolt',1), +(5,9,687,'Demon Skin',1), +(5,9,1180,'Daggers',1), +(5,9,2382,'Generic',1), +(5,9,2479,'Honorless Target',1), +(5,9,3050,'Detect',1), +(5,9,3365,'Opening',1), +(5,9,5009,'Wands',1), +(5,9,5019,'Shoot',1), +(5,9,5227,'Underwater Breathing',1), +(5,9,6233,'Closing',1), +(5,9,6246,'Closing',1), +(5,9,6247,'Opening',1), +(5,9,6477,'Opening',1), +(5,9,6478,'Opening',1), +(5,9,6603,'Attack',1), +(5,9,7266,'Duel',1), +(5,9,7267,'Grovel',1), +(5,9,7355,'Stuck',1), +(5,9,7744,'Will of the Forsaken',1), +(5,9,8386,'Attacking',1), +(5,9,9078,'Cloth',1), +(5,9,9125,'Generic',1), +(5,9,17737,'Language Gutterspeak',1), +(5,9,20577,'Cannibalize',1), +(5,9,20579,'Shadow Resistance',1), +(5,9,21651,'Opening',1), +(5,9,21652,'Closing',1), +(5,9,22027,'Remove Insignia',1), +(5,9,22810,'Opening - No Text',1), +(6,1,78,'Heroic Strike',1), +(6,1,81,'Dodge',1), +(6,1,107,'Block',1), +(6,1,196,'One-Handed Axes',1), +(6,1,198,'One-Handed Maces',1), +(6,1,199,'Two-Handed Maces',1), +(6,1,203,'Unarmed',1), +(6,1,204,'Defense',1), +(6,1,522,'SPELLDEFENSE(DND)',1), +(6,1,669,'Language Orcish',1), +(6,1,670,'Language Taurahe',1), +(6,1,2382,'Generic',1), +(6,1,2457,'Battle Stance',1), +(6,1,2479,'Honorless Target',1), +(6,1,3050,'Detect',1), +(6,1,3365,'Opening',1), +(6,1,5301,'Defensive State(DND)',1), +(6,1,6233,'Closing',1), +(6,1,6246,'Closing',1), +(6,1,6247,'Opening',1), +(6,1,6477,'Opening',1), +(6,1,6478,'Opening',1), +(6,1,6603,'Attack',1), +(6,1,7266,'Duel',1), +(6,1,7267,'Grovel',1), +(6,1,7355,'Stuck',1), +(6,1,7376,'Defensive Stance Passive',0), +(6,1,7381,'Berserker Stance Passive',0), +(6,1,8386,'Attacking',1), +(6,1,8737,'Mail',1), +(6,1,9077,'Leather',1), +(6,1,9078,'Cloth',1), +(6,1,9116,'Shield',1), +(6,1,9125,'Generic',1), +(6,1,20549,'War Stomp',1), +(6,1,20550,'Endurance',1), +(6,1,20551,'Nature Resistance',1), +(6,1,20552,'Cultivation',1), +(6,1,21156,'Battle Stance Passive',0), +(6,1,21651,'Opening',1), +(6,1,21652,'Closing',1), +(6,1,22027,'Remove Insignia',1), +(6,1,22810,'Opening - No Text',1), +(6,1,32215,'Victorious State',1), +(6,3,75,'Auto Shot',1), +(6,3,81,'Dodge',1), +(6,3,196,'One-Handed Axes',1), +(6,3,203,'Unarmed',1), +(6,3,204,'Defense',1), +(6,3,266,'Guns',1), +(6,3,522,'SPELLDEFENSE(DND)',1), +(6,3,669,'Language Orcish',1), +(6,3,670,'Language Taurahe',1), +(6,3,2382,'Generic',1), +(6,3,2479,'Honorless Target',1), +(6,3,2973,'Raptor Strike',1), +(6,3,3050,'Detect',1), +(6,3,3365,'Opening',1), +(6,3,6233,'Closing',1), +(6,3,6246,'Closing',1), +(6,3,6247,'Opening',1), +(6,3,6477,'Opening',1), +(6,3,6478,'Opening',1), +(6,3,6603,'Attack',1), +(6,3,7266,'Duel',1), +(6,3,7267,'Grovel',1), +(6,3,7355,'Stuck',1), +(6,3,8386,'Attacking',1), +(6,3,9077,'Leather',1), +(6,3,9078,'Cloth',1), +(6,3,9125,'Generic',1), +(6,3,13358,'Defensive State(DND)',1), +(6,3,20549,'War Stomp',1), +(6,3,20550,'Endurance',1), +(6,3,20551,'Nature Resistance',1), +(6,3,20552,'Cultivation',1), +(6,3,21651,'Opening',1), +(6,3,21652,'Closing',1), +(6,3,22027,'Remove Insignia',1), +(6,3,22810,'Opening - No Text',1), +(6,3,24949,'Defensive State 2(DND)',1), +(6,3,34082,'Advantaged State(DND)',1), +(6,7,81,'Dodge',1), +(6,7,107,'Block',1), +(6,7,198,'One-Handed Maces',1), +(6,7,203,'Unarmed',1), +(6,7,204,'Defense',1), +(6,7,227,'Staves',1), +(6,7,331,'Healing Wave',1), +(6,7,403,'Lightning Bolt',1), +(6,7,522,'SPELLDEFENSE(DND)',1), +(6,7,669,'Language Orcish',1), +(6,7,670,'Language Taurahe',1), +(6,7,2382,'Generic',1), +(6,7,2479,'Honorless Target',1), +(6,7,3050,'Detect',1), +(6,7,3365,'Opening',1), +(6,7,6233,'Closing',1), +(6,7,6246,'Closing',1), +(6,7,6247,'Opening',1), +(6,7,6477,'Opening',1), +(6,7,6478,'Opening',1), +(6,7,6603,'Attack',1), +(6,7,7266,'Duel',1), +(6,7,7267,'Grovel',1), +(6,7,7355,'Stuck',1), +(6,7,8386,'Attacking',1), +(6,7,9077,'Leather',1), +(6,7,9078,'Cloth',1), +(6,7,9116,'Shield',1), +(6,7,9125,'Generic',1), +(6,7,20549,'War Stomp',1), +(6,7,20550,'Endurance',1), +(6,7,20551,'Nature Resistance',1), +(6,7,20552,'Cultivation',1), +(6,7,21651,'Opening',1), +(6,7,21652,'Closing',1), +(6,7,22027,'Remove Insignia',1), +(6,7,22810,'Opening - No Text',1), +(6,7,27763,'Totem',1), +(6,11,81,'Dodge',1), +(6,11,198,'One-Handed Maces',1), +(6,11,203,'Unarmed',1), +(6,11,204,'Defense',1), +(6,11,227,'Staves',1), +(6,11,522,'SPELLDEFENSE(DND)',1), +(6,11,669,'Language Orcish',1), +(6,11,670,'Language Taurahe',1), +(6,11,1178,'Bear Form(Passive)',0), +(6,11,2382,'Generic',1), +(6,11,2479,'Honorless Target',1), +(6,11,3025,'Cat Form(Passive)',0), +(6,11,3050,'Detect',1), +(6,11,3365,'Opening',1), +(6,11,5176,'Wrath',1), +(6,11,5185,'Healing Touch',1), +(6,11,5419,'Travel Form(Passive)',0), +(6,11,5420,'Tree of Life',0), +(6,11,5421,'Aquatic Form(Passive)',0), +(6,11,6233,'Closing',1), +(6,11,6246,'Closing',1), +(6,11,6247,'Opening',1), +(6,11,6477,'Opening',1), +(6,11,6478,'Opening',1), +(6,11,6603,'Attack',1), +(6,11,7266,'Duel',1), +(6,11,7267,'Grovel',1), +(6,11,7355,'Stuck',1), +(6,11,8386,'Attacking',1), +(6,11,9077,'Leather',1), +(6,11,9078,'Cloth',1), +(6,11,9125,'Generic',1), +(6,11,9635,'Dire Bear Form(Passive)',0), +(6,11,20549,'War Stomp',1), +(6,11,20550,'Endurance',1), +(6,11,20551,'Nature Resistance',1), +(6,11,20552,'Cultivation',1), +(6,11,21178,'Bear Form(Passive2)',0), +(6,11,21651,'Opening',1), +(6,11,21652,'Closing',1), +(6,11,22027,'Remove Insignia',1), +(6,11,22810,'Opening - No Text',1), +(6,11,24905,'Moonkin Form(Passive)',0), +(6,11,27764,'Fetish',1), +(6,11,33948,'Flight Form(Passive)',0), +(6,11,34123,'Tree of Life(Passive)',0), +(6,11,40121,'Swift Flight Form(Passive)',0), +(7,1,78,'Heroic Strike',1), +(7,1,81,'Dodge',1), +(7,1,107,'Block',1), +(7,1,198,'One-Handed Maces',1), +(7,1,201,'One-Handed Swords',1), +(7,1,203,'Unarmed',1), +(7,1,204,'Defense',1), +(7,1,522,'SPELLDEFENSE(DND)',1), +(7,1,668,'Language Common',1), +(7,1,1180,'Daggers',1), +(7,1,2382,'Generic',1), +(7,1,2457,'Battle Stance',1), +(7,1,2479,'Honorless Target',1), +(7,1,3050,'Detect',1), +(7,1,3365,'Opening',1), +(7,1,5301,'Defensive State(DND)',1), +(7,1,6233,'Closing',1), +(7,1,6246,'Closing',1), +(7,1,6247,'Opening',1), +(7,1,6477,'Opening',1), +(7,1,6478,'Opening',1), +(7,1,6603,'Attack',1), +(7,1,7266,'Duel',1), +(7,1,7267,'Grovel',1), +(7,1,7340,'Language Gnomish',1), +(7,1,7355,'Stuck',1), +(7,1,7376,'Defensive Stance Passive',0), +(7,1,7381,'Berserker Stance Passive',0), +(7,1,8386,'Attacking',1), +(7,1,8737,'Mail',1), +(7,1,9077,'Leather',1), +(7,1,9078,'Cloth',1), +(7,1,9116,'Shield',1), +(7,1,9125,'Generic',1), +(7,1,20589,'Escape Artist',1), +(7,1,20591,'Expansive Mind',1), +(7,1,20592,'Arcane Resistance',1), +(7,1,20593,'Engineering Specialization',1), +(7,1,21156,'Battle Stance Passive',0), +(7,1,21651,'Opening',1), +(7,1,21652,'Closing',1), +(7,1,22027,'Remove Insignia',1), +(7,1,22810,'Opening - No Text',1), +(7,1,32215,'Victorious State',1), +(7,4,81,'Dodge',1), +(7,4,203,'Unarmed',1), +(7,4,204,'Defense',1), +(7,4,522,'SPELLDEFENSE(DND)',1), +(7,4,668,'Language Common',1), +(7,4,1180,'Daggers',1), +(7,4,1752,'Sinister Strike',1), +(7,4,2098,'Eviscerate',1), +(7,4,2382,'Generic',1), +(7,4,2479,'Honorless Target',1), +(7,4,2567,'Thrown',1), +(7,4,2764,'Throw',1), +(7,4,3050,'Detect',1), +(7,4,3365,'Opening',1), +(7,4,6233,'Closing',1), +(7,4,6246,'Closing',1), +(7,4,6247,'Opening',1), +(7,4,6477,'Opening',1), +(7,4,6478,'Opening',1), +(7,4,6603,'Attack',1), +(7,4,7266,'Duel',1), +(7,4,7267,'Grovel',1), +(7,4,7340,'Language Gnomish',1), +(7,4,7355,'Stuck',1), +(7,4,8386,'Attacking',1), +(7,4,9077,'Leather',1), +(7,4,9078,'Cloth',1), +(7,4,9125,'Generic',1), +(7,4,16092,'Defensive State(DND)',1), +(7,4,20589,'Escape Artist',1), +(7,4,20591,'Expansive Mind',1), +(7,4,20592,'Arcane Resistance',1), +(7,4,20593,'Engineering Specialization',1), +(7,4,21184,'Rogue Passive(DND)',1), +(7,4,21651,'Opening',1), +(7,4,21652,'Closing',1), +(7,4,22027,'Remove Insignia',1), +(7,4,22810,'Opening - No Text',1), +(7,8,81,'Dodge',1), +(7,8,133,'Fireball',1), +(7,8,168,'Frost Armor',1), +(7,8,203,'Unarmed',1), +(7,8,204,'Defense',1), +(7,8,227,'Staves',1), +(7,8,522,'SPELLDEFENSE(DND)',1), +(7,8,668,'Language Common',1), +(7,8,2382,'Generic',1), +(7,8,2479,'Honorless Target',1), +(7,8,3050,'Detect',1), +(7,8,3365,'Opening',1), +(7,8,5009,'Wands',1), +(7,8,5019,'Shoot',1), +(7,8,6233,'Closing',1), +(7,8,6246,'Closing',1), +(7,8,6247,'Opening',1), +(7,8,6477,'Opening',1), +(7,8,6478,'Opening',1), +(7,8,6603,'Attack',1), +(7,8,7266,'Duel',1), +(7,8,7267,'Grovel',1), +(7,8,7340,'Language Gnomish',1), +(7,8,7355,'Stuck',1), +(7,8,8386,'Attacking',1), +(7,8,9078,'Cloth',1), +(7,8,9125,'Generic',1), +(7,8,20589,'Escape Artist',1), +(7,8,20591,'Expansive Mind',1), +(7,8,20592,'Arcane Resistance',1), +(7,8,20593,'Engineering Specialization',1), +(7,8,21651,'Opening',1), +(7,8,21652,'Closing',1), +(7,8,22027,'Remove Insignia',1), +(7,8,22810,'Opening - No Text',1), +(7,9,81,'Dodge',1), +(7,9,203,'Unarmed',1), +(7,9,204,'Defense',1), +(7,9,522,'SPELLDEFENSE(DND)',1), +(7,9,668,'Language Common',1), +(7,9,686,'Shadow Bolt',1), +(7,9,687,'Demon Skin',1), +(7,9,1180,'Daggers',1), +(7,9,2382,'Generic',1), +(7,9,2479,'Honorless Target',1), +(7,9,3050,'Detect',1), +(7,9,3365,'Opening',1), +(7,9,5009,'Wands',1), +(7,9,5019,'Shoot',1), +(7,9,6233,'Closing',1), +(7,9,6246,'Closing',1), +(7,9,6247,'Opening',1), +(7,9,6477,'Opening',1), +(7,9,6478,'Opening',1), +(7,9,6603,'Attack',1), +(7,9,7266,'Duel',1), +(7,9,7267,'Grovel',1), +(7,9,7340,'Language Gnomish',1), +(7,9,7355,'Stuck',1), +(7,9,8386,'Attacking',1), +(7,9,9078,'Cloth',1), +(7,9,9125,'Generic',1), +(7,9,20589,'Escape Artist',1), +(7,9,20591,'Expansive Mind',1), +(7,9,20592,'Arcane Resistance',1), +(7,9,20593,'Engineering Specialization',1), +(7,9,21651,'Opening',1), +(7,9,21652,'Closing',1), +(7,9,22027,'Remove Insignia',1), +(7,9,22810,'Opening - No Text',1), +(8,1,78,'Heroic Strike',1), +(8,1,81,'Dodge',1), +(8,1,107,'Block',1), +(8,1,196,'One-Handed Axes',1), +(8,1,203,'Unarmed',1), +(8,1,204,'Defense',1), +(8,1,522,'SPELLDEFENSE(DND)',1), +(8,1,669,'Language Orcish',1), +(8,1,1180,'Daggers',1), +(8,1,2382,'Generic',1), +(8,1,2457,'Battle Stance',1), +(8,1,2479,'Honorless Target',1), +(8,1,2567,'Thrown',1), +(8,1,2764,'Throw',1), +(8,1,3050,'Detect',1), +(8,1,3365,'Opening',1), +(8,1,5301,'Defensive State(DND)',1), +(8,1,6233,'Closing',1), +(8,1,6246,'Closing',1), +(8,1,6247,'Opening',1), +(8,1,6477,'Opening',1), +(8,1,6478,'Opening',1), +(8,1,6603,'Attack',1), +(8,1,7266,'Duel',1), +(8,1,7267,'Grovel',1), +(8,1,7341,'Language Troll',1), +(8,1,7355,'Stuck',1), +(8,1,7376,'Defensive Stance Passive',0), +(8,1,7381,'Berserker Stance Passive',0), +(8,1,8386,'Attacking',1), +(8,1,8737,'Mail',1), +(8,1,9077,'Leather',1), +(8,1,9078,'Cloth',1), +(8,1,9116,'Shield',1), +(8,1,9125,'Generic',1), +(8,1,20555,'Regeneration',1), +(8,1,20557,'Beast Slaying',1), +(8,1,20558,'Throwing Specialization',1), +(8,1,21156,'Battle Stance Passive',0), +(8,1,21651,'Opening',1), +(8,1,21652,'Closing',1), +(8,1,22027,'Remove Insignia',1), +(8,1,22810,'Opening - No Text',1), +(8,1,26290,'Bow Specialization',1), +(8,1,26296,'Berserking',1), +(8,1,32215,'Victorious State',1), +(8,3,75,'Auto Shot',1), +(8,3,81,'Dodge',1), +(8,3,196,'One-Handed Axes',1), +(8,3,203,'Unarmed',1), +(8,3,204,'Defense',1), +(8,3,264,'Bows',1), +(8,3,522,'SPELLDEFENSE(DND)',1), +(8,3,669,'Language Orcish',1), +(8,3,2382,'Generic',1), +(8,3,2479,'Honorless Target',1), +(8,3,2973,'Raptor Strike',1), +(8,3,3050,'Detect',1), +(8,3,3365,'Opening',1), +(8,3,6233,'Closing',1), +(8,3,6246,'Closing',1), +(8,3,6247,'Opening',1), +(8,3,6477,'Opening',1), +(8,3,6478,'Opening',1), +(8,3,6603,'Attack',1), +(8,3,7266,'Duel',1), +(8,3,7267,'Grovel',1), +(8,3,7341,'Language Troll',1), +(8,3,7355,'Stuck',1), +(8,3,8386,'Attacking',1), +(8,3,9077,'Leather',1), +(8,3,9078,'Cloth',1), +(8,3,9125,'Generic',1), +(8,3,13358,'Defensive State(DND)',1), +(8,3,20554,'Berserking',1), +(8,3,20555,'Regeneration',1), +(8,3,20557,'Beast Slaying',1), +(8,3,20558,'Throwing Specialization',1), +(8,3,21651,'Opening',1), +(8,3,21652,'Closing',1), +(8,3,22027,'Remove Insignia',1), +(8,3,22810,'Opening - No Text',1), +(8,3,24949,'Defensive State 2(DND)',1), +(8,3,26290,'Bow Specialization',1), +(8,3,34082,'Advantaged State(DND)',1), +(8,4,81,'Dodge',1), +(8,4,203,'Unarmed',1), +(8,4,204,'Defense',1), +(8,4,522,'SPELLDEFENSE(DND)',1), +(8,4,669,'Language Orcish',1), +(8,4,1180,'Daggers',1), +(8,4,1752,'Sinister Strike',1), +(8,4,2098,'Eviscerate',1), +(8,4,2382,'Generic',1), +(8,4,2479,'Honorless Target',1), +(8,4,2567,'Thrown',1), +(8,4,2764,'Throw',1), +(8,4,3050,'Detect',1), +(8,4,3365,'Opening',1), +(8,4,6233,'Closing',1), +(8,4,6246,'Closing',1), +(8,4,6247,'Opening',1), +(8,4,6477,'Opening',1), +(8,4,6478,'Opening',1), +(8,4,6603,'Attack',1), +(8,4,7266,'Duel',1), +(8,4,7267,'Grovel',1), +(8,4,7341,'Language Troll',1), +(8,4,7355,'Stuck',1), +(8,4,8386,'Attacking',1), +(8,4,9077,'Leather',1), +(8,4,9078,'Cloth',1), +(8,4,9125,'Generic',1), +(8,4,16092,'Defensive State(DND)',1), +(8,4,20555,'Regeneration',1), +(8,4,20557,'Beast Slaying',1), +(8,4,20558,'Throwing Specialization',1), +(8,4,21184,'Rogue Passive(DND)',1), +(8,4,21651,'Opening',1), +(8,4,21652,'Closing',1), +(8,4,22027,'Remove Insignia',1), +(8,4,22810,'Opening - No Text',1), +(8,4,26290,'Bow Specialization',1), +(8,4,26297,'Berserking',1), +(8,5,81,'Dodge',1), +(8,5,198,'One-Handed Maces',1), +(8,5,203,'Unarmed',1), +(8,5,204,'Defense',1), +(8,5,522,'SPELLDEFENSE(DND)',1), +(8,5,585,'Smite',1), +(8,5,669,'Language Orcish',1), +(8,5,2050,'Lesser Heal',1), +(8,5,2382,'Generic',1), +(8,5,2479,'Honorless Target',1), +(8,5,3050,'Detect',1), +(8,5,3365,'Opening',1), +(8,5,5009,'Wands',1), +(8,5,5019,'Shoot',1), +(8,5,6233,'Closing',1), +(8,5,6246,'Closing',1), +(8,5,6247,'Opening',1), +(8,5,6477,'Opening',1), +(8,5,6478,'Opening',1), +(8,5,6603,'Attack',1), +(8,5,7266,'Duel',1), +(8,5,7267,'Grovel',1), +(8,5,7341,'Language Troll',1), +(8,5,7355,'Stuck',1), +(8,5,8386,'Attacking',1), +(8,5,9078,'Cloth',1), +(8,5,9125,'Generic',1), +(8,5,20554,'Berserking',1), +(8,5,20555,'Regeneration',1), +(8,5,20557,'Beast Slaying',1), +(8,5,20558,'Throwing Specialization',1), +(8,5,21651,'Opening',1), +(8,5,21652,'Closing',1), +(8,5,22027,'Remove Insignia',1), +(8,5,22810,'Opening - No Text',1), +(8,5,26290,'Bow Specialization',1), +(8,7,81,'Dodge',1), +(8,7,107,'Block',1), +(8,7,198,'One-Handed Maces',1), +(8,7,203,'Unarmed',1), +(8,7,204,'Defense',1), +(8,7,227,'Staves',1), +(8,7,331,'Healing Wave',1), +(8,7,403,'Lightning Bolt',1), +(8,7,522,'SPELLDEFENSE(DND)',1), +(8,7,669,'Language Orcish',1), +(8,7,2382,'Generic',1), +(8,7,2479,'Honorless Target',1), +(8,7,3050,'Detect',1), +(8,7,3365,'Opening',1), +(8,7,6233,'Closing',1), +(8,7,6246,'Closing',1), +(8,7,6247,'Opening',1), +(8,7,6477,'Opening',1), +(8,7,6478,'Opening',1), +(8,7,6603,'Attack',1), +(8,7,7266,'Duel',1), +(8,7,7267,'Grovel',1), +(8,7,7341,'Language Troll',1), +(8,7,7355,'Stuck',1), +(8,7,8386,'Attacking',1), +(8,7,9077,'Leather',1), +(8,7,9078,'Cloth',1), +(8,7,9116,'Shield',1), +(8,7,9125,'Generic',1), +(8,7,20554,'Berserking',1), +(8,7,20555,'Regeneration',1), +(8,7,20557,'Beast Slaying',1), +(8,7,20558,'Throwing Specialization',1), +(8,7,21651,'Opening',1), +(8,7,21652,'Closing',1), +(8,7,22027,'Remove Insignia',1), +(8,7,22810,'Opening - No Text',1), +(8,7,26290,'Bow Specialization',1), +(8,7,27763,'Totem',1), +(8,8,81,'Dodge',1), +(8,8,133,'Fireball',1), +(8,8,168,'Frost Armor',1), +(8,8,203,'Unarmed',1), +(8,8,204,'Defense',1), +(8,8,227,'Staves',1), +(8,8,522,'SPELLDEFENSE(DND)',1), +(8,8,669,'Language Orcish',1), +(8,8,2382,'Generic',1), +(8,8,2479,'Honorless Target',1), +(8,8,3050,'Detect',1), +(8,8,3365,'Opening',1), +(8,8,5009,'Wands',1), +(8,8,5019,'Shoot',1), +(8,8,6233,'Closing',1), +(8,8,6246,'Closing',1), +(8,8,6247,'Opening',1), +(8,8,6477,'Opening',1), +(8,8,6478,'Opening',1), +(8,8,6603,'Attack',1), +(8,8,7266,'Duel',1), +(8,8,7267,'Grovel',1), +(8,8,7341,'Language Troll',1), +(8,8,7355,'Stuck',1), +(8,8,8386,'Attacking',1), +(8,8,9078,'Cloth',1), +(8,8,9125,'Generic',1), +(8,8,20554,'Berserking',1), +(8,8,20555,'Regeneration',1), +(8,8,20557,'Beast Slaying',1), +(8,8,20558,'Throwing Specialization',1), +(8,8,21651,'Opening',1), +(8,8,21652,'Closing',1), +(8,8,22027,'Remove Insignia',1), +(8,8,22810,'Opening - No Text',1), +(8,8,26290,'Bow Specialization',1), +(10,2,81,'Dodge',1), +(10,2,107,'Block',1), +(10,2,201,'One-Handed Swords',1), +(10,2,202,'Two-Handed Swords',1), +(10,2,203,'Unarmed',1), +(10,2,204,'Defense',1), +(10,2,522,'SPELLDEFENSE(DND)',1), +(10,2,635,'Holy Light',1), +(10,2,669,'Language Orcish',1), +(10,2,813,'Language Thalassian',1), +(10,2,822,'Magic Resistance',1), +(10,2,2382,'Generic',1), +(10,2,2479,'Honorless Target',1), +(10,2,3050,'Detect',1), +(10,2,3365,'Opening',1), +(10,2,6233,'Closing',1), +(10,2,6246,'Closing',1), +(10,2,6247,'Opening',1), +(10,2,6477,'Opening',1), +(10,2,6478,'Opening',1), +(10,2,6603,'Attack',1), +(10,2,7266,'Duel',1), +(10,2,7267,'Grovel',1), +(10,2,7355,'Stuck',1), +(10,2,8386,'Attacking',1), +(10,2,8737,'Mail',1), +(10,2,9077,'Leather',1), +(10,2,9078,'Cloth',1), +(10,2,9116,'Shield',1), +(10,2,9125,'Generic',1), +(10,2,20154,'Seal of Righteousness',1), +(10,2,21651,'Opening',1), +(10,2,21652,'Closing',1), +(10,2,22027,'Remove Insignia',1), +(10,2,22810,'Opening - No Text',1), +(10,2,27762,'Libram',1), +(10,2,28730,'Arcane Torrent',1), +(10,2,28734,'Mana Tap',1), +(10,2,28877,'Arcane Affinity',1), +(10,3,75,'Auto Shot',1), +(10,3,81,'Dodge',1), +(10,3,203,'Unarmed',1), +(10,3,204,'Defense',1), +(10,3,264,'Bows',1), +(10,3,522,'SPELLDEFENSE(DND)',1), +(10,3,669,'Language Orcish',1), +(10,3,813,'Language Thalassian',1), +(10,3,822,'Magic Resistance',1), +(10,3,1180,'Daggers',1), +(10,3,2382,'Generic',1), +(10,3,2479,'Honorless Target',1), +(10,3,2973,'Raptor Strike',1), +(10,3,3050,'Detect',1), +(10,3,3365,'Opening',1), +(10,3,6233,'Closing',1), +(10,3,6246,'Closing',1), +(10,3,6247,'Opening',1), +(10,3,6477,'Opening',1), +(10,3,6478,'Opening',1), +(10,3,6603,'Attack',1), +(10,3,7266,'Duel',1), +(10,3,7267,'Grovel',1), +(10,3,7355,'Stuck',1), +(10,3,8386,'Attacking',1), +(10,3,9077,'Leather',1), +(10,3,9078,'Cloth',1), +(10,3,9125,'Generic',1), +(10,3,13358,'Defensive State(DND)',1), +(10,3,21651,'Opening',1), +(10,3,21652,'Closing',1), +(10,3,22027,'Remove Insignia',1), +(10,3,22810,'Opening - No Text',1), +(10,3,24949,'Defensive State 2(DND)',1), +(10,3,28730,'Arcane Torrent',1), +(10,3,28734,'Mana Tap',1), +(10,3,28877,'Arcane Affinity',1), +(10,3,34082,'Advantaged State(DND)',1), +(10,4,81,'Dodge',1), +(10,4,203,'Unarmed',1), +(10,4,204,'Defense',1), +(10,4,522,'SPELLDEFENSE(DND)',1), +(10,4,669,'Language Orcish',1), +(10,4,813,'Language Thalassian',1), +(10,4,822,'Magic Resistance',1), +(10,4,1180,'Daggers',1), +(10,4,1752,'Sinister Strike',1), +(10,4,2098,'Eviscerate',1), +(10,4,2382,'Generic',1), +(10,4,2479,'Honorless Target',1), +(10,4,2567,'Thrown',1), +(10,4,2764,'Throw',1), +(10,4,3050,'Detect',1), +(10,4,3365,'Opening',1), +(10,4,6233,'Closing',1), +(10,4,6246,'Closing',1), +(10,4,6247,'Opening',1), +(10,4,6477,'Opening',1), +(10,4,6478,'Opening',1), +(10,4,6603,'Attack',1), +(10,4,7266,'Duel',1), +(10,4,7267,'Grovel',1), +(10,4,7355,'Stuck',1), +(10,4,8386,'Attacking',1), +(10,4,9077,'Leather',1), +(10,4,9078,'Cloth',1), +(10,4,9125,'Generic',1), +(10,4,16092,'Defensive State(DND)',1), +(10,4,21184,'Rogue Passive(DND)',1), +(10,4,21651,'Opening',1), +(10,4,21652,'Closing',1), +(10,4,22027,'Remove Insignia',1), +(10,4,22810,'Opening - No Text',1), +(10,4,25046,'Arcane Torrent',1), +(10,4,28734,'Mana Tap',1), +(10,4,28877,'Arcane Affinity',1), +(10,5,81,'Dodge',1), +(10,5,198,'One-Handed Maces',1), +(10,5,203,'Unarmed',1), +(10,5,204,'Defense',1), +(10,5,522,'SPELLDEFENSE(DND)',1), +(10,5,585,'Smite',1), +(10,5,669,'Language Orcish',1), +(10,5,813,'Language Thalassian',1), +(10,5,822,'Magic Resistance',1), +(10,5,2050,'Lesser Heal',1), +(10,5,2382,'Generic',1), +(10,5,2479,'Honorless Target',1), +(10,5,3050,'Detect',1), +(10,5,3365,'Opening',1), +(10,5,5009,'Wands',1), +(10,5,5019,'Shoot',1), +(10,5,6233,'Closing',1), +(10,5,6246,'Closing',1), +(10,5,6247,'Opening',1), +(10,5,6477,'Opening',1), +(10,5,6478,'Opening',1), +(10,5,6603,'Attack',1), +(10,5,7266,'Duel',1), +(10,5,7267,'Grovel',1), +(10,5,7355,'Stuck',1), +(10,5,8386,'Attacking',1), +(10,5,9078,'Cloth',1), +(10,5,9125,'Generic',1), +(10,5,21651,'Opening',1), +(10,5,21652,'Closing',1), +(10,5,22027,'Remove Insignia',1), +(10,5,22810,'Opening - No Text',1), +(10,5,28730,'Arcane Torrent',1), +(10,5,28734,'Mana Tap',1), +(10,5,28877,'Arcane Affinity',1), +(10,8,81,'Dodge',1), +(10,8,133,'Fireball',1), +(10,8,168,'Frost Armor',1), +(10,8,203,'Unarmed',1), +(10,8,204,'Defense',1), +(10,8,227,'Staves',1), +(10,8,522,'SPELLDEFENSE(DND)',1), +(10,8,669,'Language Orcish',1), +(10,8,813,'Language Thalassian',1), +(10,8,822,'Magic Resistance',1), +(10,8,2382,'Generic',1), +(10,8,2479,'Honorless Target',1), +(10,8,3050,'Detect',1), +(10,8,3365,'Opening',1), +(10,8,5009,'Wands',1), +(10,8,5019,'Shoot',1), +(10,8,6233,'Closing',1), +(10,8,6246,'Closing',1), +(10,8,6247,'Opening',1), +(10,8,6477,'Opening',1), +(10,8,6478,'Opening',1), +(10,8,6603,'Attack',1), +(10,8,7266,'Duel',1), +(10,8,7267,'Grovel',1), +(10,8,7355,'Stuck',1), +(10,8,8386,'Attacking',1), +(10,8,9078,'Cloth',1), +(10,8,9125,'Generic',1), +(10,8,21651,'Opening',1), +(10,8,21652,'Closing',1), +(10,8,22027,'Remove Insignia',1), +(10,8,22810,'Opening - No Text',1), +(10,8,28730,'Arcane Torrent',1), +(10,8,28734,'Mana Tap',1), +(10,8,28877,'Arcane Affinity',1), +(10,9,81,'Dodge',1), +(10,9,203,'Unarmed',1), +(10,9,204,'Defense',1), +(10,9,522,'SPELLDEFENSE(DND)',1), +(10,9,669,'Language Orcish',1), +(10,9,686,'Shadow Bolt',1), +(10,9,687,'Demon Skin',1), +(10,9,813,'Language Thalassian',1), +(10,9,822,'Magic Resistance',1), +(10,9,1180,'Daggers',1), +(10,9,2382,'Generic',1), +(10,9,2479,'Honorless Target',1), +(10,9,3050,'Detect',1), +(10,9,3365,'Opening',1), +(10,9,5009,'Wands',1), +(10,9,5019,'Shoot',1), +(10,9,6233,'Closing',1), +(10,9,6246,'Closing',1), +(10,9,6247,'Opening',1), +(10,9,6477,'Opening',1), +(10,9,6478,'Opening',1), +(10,9,6603,'Attack',1), +(10,9,7266,'Duel',1), +(10,9,7267,'Grovel',1), +(10,9,7355,'Stuck',1), +(10,9,8386,'Attacking',1), +(10,9,9078,'Cloth',1), +(10,9,9125,'Generic',1), +(10,9,21651,'Opening',1), +(10,9,21652,'Closing',1), +(10,9,22027,'Remove Insignia',1), +(10,9,22810,'Opening - No Text',1), +(10,9,28730,'Arcane Torrent',1), +(10,9,28734,'Mana Tap',1), +(10,9,28877,'Arcane Affinity',1), +(11,1,78,'Heroic Strike',1), +(11,1,81,'Dodge',1), +(11,1,107,'Block',1), +(11,1,198,'One-Handed Maces',1), +(11,1,201,'One-Handed Swords',1), +(11,1,202,'Two-Handed Swords',1), +(11,1,203,'Unarmed',1), +(11,1,204,'Defense',1), +(11,1,522,'SPELLDEFENSE(DND)',1), +(11,1,668,'Language Common',1), +(11,1,2382,'Generic',1), +(11,1,2457,'Battle Stance',1), +(11,1,2479,'Honorless Target',1), +(11,1,3050,'Detect',1), +(11,1,3365,'Opening',1), +(11,1,5301,'Defensive State(DND)',1), +(11,1,6233,'Closing',1), +(11,1,6246,'Closing',1), +(11,1,6247,'Opening',1), +(11,1,6477,'Opening',1), +(11,1,6478,'Opening',1), +(11,1,6562,'Heroic Presence',1), +(11,1,6603,'Attack',1), +(11,1,7266,'Duel',1), +(11,1,7267,'Grovel',1), +(11,1,7355,'Stuck',1), +(11,1,7376,'Defensive Stance Passive',0), +(11,1,7381,'Berserker Stance Passive',0), +(11,1,8386,'Attacking',1), +(11,1,8737,'Mail',1), +(11,1,9077,'Leather',1), +(11,1,9078,'Cloth',1), +(11,1,9116,'Shield',1), +(11,1,9125,'Generic',1), +(11,1,20579,'Shadow Resistance',1), +(11,1,21156,'Battle Stance Passive',0), +(11,1,21651,'Opening',1), +(11,1,21652,'Closing',1), +(11,1,22027,'Remove Insignia',1), +(11,1,22810,'Opening - No Text',1), +(11,1,28875,'Gemcutting',1), +(11,1,28880,'Gift of the Naaru',1), +(11,1,29932,'Language Draenei',1), +(11,1,32215,'Victorious State',1), +(11,2,81,'Dodge',1), +(11,2,107,'Block',1), +(11,2,198,'One-Handed Maces',1), +(11,2,199,'Two-Handed Maces',1), +(11,2,203,'Unarmed',1), +(11,2,204,'Defense',1), +(11,2,522,'SPELLDEFENSE(DND)',1), +(11,2,635,'Holy Light',1), +(11,2,668,'Language Common',1), +(11,2,2382,'Generic',1), +(11,2,2479,'Honorless Target',1), +(11,2,3050,'Detect',1), +(11,2,3365,'Opening',1), +(11,2,6233,'Closing',1), +(11,2,6246,'Closing',1), +(11,2,6247,'Opening',1), +(11,2,6477,'Opening',1), +(11,2,6478,'Opening',1), +(11,2,6562,'Heroic Presence',1), +(11,2,6603,'Attack',1), +(11,2,7266,'Duel',1), +(11,2,7267,'Grovel',1), +(11,2,7355,'Stuck',1), +(11,2,8386,'Attacking',1), +(11,2,8737,'Mail',1), +(11,2,9077,'Leather',1), +(11,2,9078,'Cloth',1), +(11,2,9116,'Shield',1), +(11,2,9125,'Generic',1), +(11,2,20154,'Seal of Righteousness',1), +(11,2,20579,'Shadow Resistance',1), +(11,2,21651,'Opening',1), +(11,2,21652,'Closing',1), +(11,2,22027,'Remove Insignia',1), +(11,2,22810,'Opening - No Text',1), +(11,2,27762,'Libram',1), +(11,2,28875,'Gemcutting',1), +(11,2,28880,'Gift of the Naaru',1), +(11,2,29932,'Language Draenei',1), +(11,3,75,'Auto Shot',1), +(11,3,81,'Dodge',1), +(11,3,201,'One-Handed Swords',1), +(11,3,203,'Unarmed',1), +(11,3,204,'Defense',1), +(11,3,522,'SPELLDEFENSE(DND)',1), +(11,3,668,'Language Common',1), +(11,3,2382,'Generic',1), +(11,3,2479,'Honorless Target',1), +(11,3,2973,'Raptor Strike',1), +(11,3,3050,'Detect',1), +(11,3,3365,'Opening',1), +(11,3,5011,'Crossbows',1), +(11,3,6233,'Closing',1), +(11,3,6246,'Closing',1), +(11,3,6247,'Opening',1), +(11,3,6477,'Opening',1), +(11,3,6478,'Opening',1), +(11,3,6562,'Heroic Presence',1), +(11,3,6603,'Attack',1), +(11,3,7266,'Duel',1), +(11,3,7267,'Grovel',1), +(11,3,7355,'Stuck',1), +(11,3,8386,'Attacking',1), +(11,3,9077,'Leather',1), +(11,3,9078,'Cloth',1), +(11,3,9125,'Generic',1), +(11,3,13358,'Defensive State(DND)',1), +(11,3,20579,'Shadow Resistance',1), +(11,3,21651,'Opening',1), +(11,3,21652,'Closing',1), +(11,3,22027,'Remove Insignia',1), +(11,3,22810,'Opening - No Text',1), +(11,3,24949,'Defensive State 2(DND)',1), +(11,3,28875,'Gemcutting',1), +(11,3,28880,'Gift of the Naaru',1), +(11,3,29932,'Language Draenei',1), +(11,3,34082,'Advantaged State(DND)',1), +(11,5,81,'Dodge',1), +(11,5,198,'One-Handed Maces',1), +(11,5,203,'Unarmed',1), +(11,5,204,'Defense',1), +(11,5,522,'SPELLDEFENSE(DND)',1), +(11,5,585,'Smite',1), +(11,5,668,'Language Common',1), +(11,5,2050,'Lesser Heal',1), +(11,5,2382,'Generic',1), +(11,5,2479,'Honorless Target',1), +(11,5,3050,'Detect',1), +(11,5,3365,'Opening',1), +(11,5,5009,'Wands',1), +(11,5,5019,'Shoot',1), +(11,5,6233,'Closing',1), +(11,5,6246,'Closing',1), +(11,5,6247,'Opening',1), +(11,5,6477,'Opening',1), +(11,5,6478,'Opening',1), +(11,5,6603,'Attack',1), +(11,5,7266,'Duel',1), +(11,5,7267,'Grovel',1), +(11,5,7355,'Stuck',1), +(11,5,8386,'Attacking',1), +(11,5,9078,'Cloth',1), +(11,5,9125,'Generic',1), +(11,5,20579,'Shadow Resistance',1), +(11,5,21651,'Opening',1), +(11,5,21652,'Closing',1), +(11,5,22027,'Remove Insignia',1), +(11,5,22810,'Opening - No Text',1), +(11,5,28875,'Gemcutting',1), +(11,5,28878,'Inspiring Presence',1), +(11,5,28880,'Gift of the Naaru',1), +(11,5,29932,'Language Draenei',1), +(11,7,81,'Dodge',1), +(11,7,107,'Block',1), +(11,7,198,'One-Handed Maces',1), +(11,7,203,'Unarmed',1), +(11,7,204,'Defense',1), +(11,7,227,'Staves',1), +(11,7,331,'Healing Wave',1), +(11,7,403,'Lightning Bolt',1), +(11,7,522,'SPELLDEFENSE(DND)',1), +(11,7,668,'Language Common',1), +(11,7,2382,'Generic',1), +(11,7,2479,'Honorless Target',1), +(11,7,3050,'Detect',1), +(11,7,3365,'Opening',1), +(11,7,6233,'Closing',1), +(11,7,6246,'Closing',1), +(11,7,6247,'Opening',1), +(11,7,6477,'Opening',1), +(11,7,6478,'Opening',1), +(11,7,6603,'Attack',1), +(11,7,7266,'Duel',1), +(11,7,7267,'Grovel',1), +(11,7,7355,'Stuck',1), +(11,7,8386,'Attacking',1), +(11,7,9077,'Leather',1), +(11,7,9078,'Cloth',1), +(11,7,9116,'Shield',1), +(11,7,9125,'Generic',1), +(11,7,20579,'Shadow Resistance',1), +(11,7,21651,'Opening',1), +(11,7,21652,'Closing',1), +(11,7,22027,'Remove Insignia',1), +(11,7,22810,'Opening - No Text',1), +(11,7,27763,'Totem',1), +(11,7,28875,'Gemcutting',1), +(11,7,28878,'Inspiring Presence',1), +(11,7,28880,'Gift of the Naaru',1), +(11,7,29932,'Language Draenei',1), +(11,8,81,'Dodge',1), +(11,8,133,'Fireball',1), +(11,8,168,'Frost Armor',1), +(11,8,203,'Unarmed',1), +(11,8,204,'Defense',1), +(11,8,227,'Staves',1), +(11,8,522,'SPELLDEFENSE(DND)',1), +(11,8,668,'Language Common',1), +(11,8,2382,'Generic',1), +(11,8,2479,'Honorless Target',1), +(11,8,3050,'Detect',1), +(11,8,3365,'Opening',1), +(11,8,5009,'Wands',1), +(11,8,5019,'Shoot',1), +(11,8,6233,'Closing',1), +(11,8,6246,'Closing',1), +(11,8,6247,'Opening',1), +(11,8,6477,'Opening',1), +(11,8,6478,'Opening',1), +(11,8,6603,'Attack',1), +(11,8,7266,'Duel',1), +(11,8,7267,'Grovel',1), +(11,8,7355,'Stuck',1), +(11,8,8386,'Attacking',1), +(11,8,9078,'Cloth',1), +(11,8,9125,'Generic',1), +(11,8,20579,'Shadow Resistance',1), +(11,8,21651,'Opening',1), +(11,8,21652,'Closing',1), +(11,8,22027,'Remove Insignia',1), +(11,8,22810,'Opening - No Text',1), +(11,8,28875,'Gemcutting',1), +(11,8,28878,'Inspiring Presence',1), +(11,8,28880,'Gift of the Naaru',1), +(11,8,29932,'Language Draenei',1); \ No newline at end of file diff --git a/sql/updates/0.8/4081_command.sql b/sql/updates/0.8/4081_command.sql new file mode 100644 index 000000000..b266bf326 --- /dev/null +++ b/sql/updates/0.8/4081_command.sql @@ -0,0 +1,8 @@ +DELETE FROM `command` WHERE `name`='learn'; +INSERT INTO `command` VALUES +('learn',3,'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter.'), +('learn all',3,'Syntax: .learn all\r\n\r\nLearn all big set different spell maybe useful for Administaror.'), +('learn all_crafts',2,'Syntax: .learn crafts\r\n\r\nLearn all professions and recipes.'), +('learn all_gm',2,'Syntax: .learn all_gm\r\n\r\nLearn all default spells for Game Masters.'), +('learn all_lang',1,'Syntax: .learn all_lang\r\n\r\nLearn all languages'), +('learn all_myclass',3,'Syntax: .learn all_myclass\r\n\r\nLearn all spells available for his class.'); diff --git a/sql/updates/0.8/4096_pet.sql b/sql/updates/0.8/4096_pet.sql new file mode 100644 index 000000000..6bf6536ce --- /dev/null +++ b/sql/updates/0.8/4096_pet.sql @@ -0,0 +1,290 @@ +DROP TABLE IF EXISTS `character_pet`; +CREATE TABLE `character_pet` ( + `id` int(11) unsigned NOT NULL default '0', + `entry` int(11) unsigned NOT NULL default '0', + `owner` int(11) unsigned NOT NULL default '0', + `modelid` int(11) unsigned default '0', + `level` int(11) unsigned NOT NULL default '1', + `exp` int(11) unsigned NOT NULL default '0', + `nextlvlexp` int(11) unsigned NOT NULL default '100', + `Reactstate` tinyint(1) unsigned NOT NULL default '0', + `Commandstate` tinyint(1) unsigned NOT NULL default '1', + `loyaltypoints` int(11) NOT NULL default '0', + `loyalty` int(11) unsigned NOT NULL default '0', + `trainpoint` int(11) NOT NULL default '0', + `name` varchar(100) default 'Pet', + `renamed` tinyint(1) unsigned NOT NULL default '0', + `slot` int(11) unsigned NOT NULL default '0', + `curhealth` int(11) unsigned NOT NULL default '1', + `curmana` int(11) unsigned NOT NULL default '0', + `curhappiness` int(11) unsigned NOT NULL default '0', + `savetime` bigint(20) unsigned NOT NULL default '0', + `resettalents_cost` int(11) unsigned NOT NULL default '0', + `resettalents_time` bigint(20) unsigned NOT NULL default '0', + `ABData` longtext, + `TeachSpelldata` longtext, + PRIMARY KEY (`id`), + KEY `owner` (`owner`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +DROP TABLE IF EXISTS `pet_spell`; +CREATE TABLE `pet_spell` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `slot` int(11) unsigned NOT NULL default '0', + `active` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +DROP TABLE IF EXISTS `pet_spell_cooldown`; +CREATE TABLE `pet_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `pet_aura`; +CREATE TABLE `pet_aura` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`,`effect_index`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- ---------------------------- +-- Table structure for petcreateinfo_spell +-- ---------------------------- +DROP TABLE IF EXISTS `petcreateinfo_spell`; +CREATE TABLE `petcreateinfo_spell` ( + `entry` int(11) unsigned NOT NULL DEFAULT '0', + `Spell1` int(11) unsigned NOT NULL DEFAULT '0', + `Spell2` int(11) unsigned NOT NULL DEFAULT '0', + `Spell3` int(11) unsigned NOT NULL DEFAULT '0', + `Spell4` int(11) unsigned NOT NULL DEFAULT '0', + `FamilyPassive` int(11) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet Create Spells'; + +ALTER TABLE `pet_levelstats` ADD `armor` int(10) unsigned NOT NULL default '0' AFTER `mana`; + +INSERT INTO `spell_chain` VALUES ('17253', '0', '17253', '1'); +INSERT INTO `spell_chain` VALUES ('17255', '17253', '17253', '2'); +INSERT INTO `spell_chain` VALUES ('17256', '17255', '17253', '3'); +INSERT INTO `spell_chain` VALUES ('17257', '17256', '17253', '4'); +INSERT INTO `spell_chain` VALUES ('17258', '17257', '17253', '5'); +INSERT INTO `spell_chain` VALUES ('17259', '17258', '17253', '6'); +INSERT INTO `spell_chain` VALUES ('17260', '17259', '17253', '7'); +INSERT INTO `spell_chain` VALUES ('17261', '17260', '17253', '8'); +INSERT INTO `spell_chain` VALUES ('27050', '17261', '17253', '9'); +INSERT INTO `spell_chain` VALUES ('16827', '0', '16827', '1'); +INSERT INTO `spell_chain` VALUES ('16828', '16827', '16827', '2'); +INSERT INTO `spell_chain` VALUES ('16829', '16828', '16827', '3'); +INSERT INTO `spell_chain` VALUES ('16830', '16829', '16827', '4'); +INSERT INTO `spell_chain` VALUES ('16831', '16830', '16827', '5'); +INSERT INTO `spell_chain` VALUES ('16832', '16831', '16827', '6'); +INSERT INTO `spell_chain` VALUES ('3010', '16832', '16827', '7'); +INSERT INTO `spell_chain` VALUES ('3009', '3010', '16827', '8'); +INSERT INTO `spell_chain` VALUES ('27049', '3009', '16827', '9'); +INSERT INTO `spell_chain` VALUES ('1742', '0', '1742', '1'); +INSERT INTO `spell_chain` VALUES ('1753', '1742', '1742', '2'); +INSERT INTO `spell_chain` VALUES ('1754', '1753', '1742', '3'); +INSERT INTO `spell_chain` VALUES ('1755', '1754', '1742', '4'); +INSERT INTO `spell_chain` VALUES ('1756', '1755', '1742', '5'); +INSERT INTO `spell_chain` VALUES ('16697', '1756', '1742', '6'); +INSERT INTO `spell_chain` VALUES ('27048', '16697', '1742', '7'); +INSERT INTO `spell_chain` VALUES ('23099', '0', '23099', '1'); +INSERT INTO `spell_chain` VALUES ('23109', '23099', '23099', '2'); +INSERT INTO `spell_chain` VALUES ('23110', '23109', '23099', '3'); +INSERT INTO `spell_chain` VALUES ('23145', '0', '23145', '1'); +INSERT INTO `spell_chain` VALUES ('23147', '23145', '23145', '2'); +INSERT INTO `spell_chain` VALUES ('23148', '23147', '23145', '3'); +INSERT INTO `spell_chain` VALUES ('2649', '0', '2649', '1'); +INSERT INTO `spell_chain` VALUES ('14916', '2649', '2649', '2'); +INSERT INTO `spell_chain` VALUES ('14917', '14916', '2649', '3'); +INSERT INTO `spell_chain` VALUES ('14918', '14917', '2649', '4'); +INSERT INTO `spell_chain` VALUES ('14919', '14918', '2649', '5'); +INSERT INTO `spell_chain` VALUES ('14920', '14919', '2649', '6'); +INSERT INTO `spell_chain` VALUES ('14921', '14920', '2649', '7'); +INSERT INTO `spell_chain` VALUES ('27047', '14921', '2649', '8'); +INSERT INTO `spell_chain` VALUES ('7371', '0', '7371', '1'); +INSERT INTO `spell_chain` VALUES ('26177', '7371', '7371', '2'); +INSERT INTO `spell_chain` VALUES ('26178', '26177', '7371', '3'); +INSERT INTO `spell_chain` VALUES ('26179', '26178', '7371', '4'); +INSERT INTO `spell_chain` VALUES ('26201', '26179', '7371', '5'); +INSERT INTO `spell_chain` VALUES ('27685', '26201', '7371', '6'); +INSERT INTO `spell_chain` VALUES ('24604', '0', '24604', '1'); +INSERT INTO `spell_chain` VALUES ('24605', '24604', '24604', '2'); +INSERT INTO `spell_chain` VALUES ('24603', '24605', '24604', '3'); +INSERT INTO `spell_chain` VALUES ('24597', '24603', '24604', '4'); +INSERT INTO `spell_chain` VALUES ('24844', '0', '24844', '1'); +INSERT INTO `spell_chain` VALUES ('25008', '24844', '24844', '2'); +INSERT INTO `spell_chain` VALUES ('25009', '25008', '24844', '3'); +INSERT INTO `spell_chain` VALUES ('25010', '25009', '24844', '4'); +INSERT INTO `spell_chain` VALUES ('25011', '25010', '24844', '5'); +INSERT INTO `spell_chain` VALUES ('25012', '25011', '24844', '6'); +INSERT INTO `spell_chain` VALUES ('24450', '0', '24450', '1'); +INSERT INTO `spell_chain` VALUES ('24452', '24450', '24450', '2'); +INSERT INTO `spell_chain` VALUES ('24453', '24452', '24450', '3'); +INSERT INTO `spell_chain` VALUES ('24640', '0', '24640', '1'); +INSERT INTO `spell_chain` VALUES ('24583', '24640', '24640', '2'); +INSERT INTO `spell_chain` VALUES ('24586', '24583', '24640', '3'); +INSERT INTO `spell_chain` VALUES ('24587', '24586', '24640', '4'); +INSERT INTO `spell_chain` VALUES ('27060', '24587', '24640', '5'); +INSERT INTO `spell_chain` VALUES ('24423', '0', '24423', '1'); +INSERT INTO `spell_chain` VALUES ('24577', '24423', '24423', '2'); +INSERT INTO `spell_chain` VALUES ('24578', '24577', '24423', '3'); +INSERT INTO `spell_chain` VALUES ('24579', '24578', '24423', '4'); +INSERT INTO `spell_chain` VALUES ('27051', '24579', '24423', '5'); +INSERT INTO `spell_chain` VALUES ('26064', '0', '26064', '1'); +INSERT INTO `spell_chain` VALUES ('26090', '0', '26090', '1'); +INSERT INTO `spell_chain` VALUES ('26187', '26090', '26090', '2'); +INSERT INTO `spell_chain` VALUES ('26188', '26187', '26090', '3'); +INSERT INTO `spell_chain` VALUES ('27063', '26188', '26090', '4'); +INSERT INTO `spell_chain` VALUES ('34889', '0', '34889', '1'); +INSERT INTO `spell_chain` VALUES ('35323', '34889', '34889', '2'); +INSERT INTO `spell_chain` VALUES ('35290', '0', '35290', '1'); +INSERT INTO `spell_chain` VALUES ('35291', '35290', '35290', '2'); +INSERT INTO `spell_chain` VALUES ('35292', '35291', '35290', '3'); +INSERT INTO `spell_chain` VALUES ('35293', '35292', '35290', '4'); +INSERT INTO `spell_chain` VALUES ('35294', '35293', '35290', '5'); +INSERT INTO `spell_chain` VALUES ('35295', '35294', '35290', '6'); +INSERT INTO `spell_chain` VALUES ('35296', '35295', '35290', '7'); +INSERT INTO `spell_chain` VALUES ('35297', '35296', '35290', '8'); +INSERT INTO `spell_chain` VALUES ('35298', '35297', '35290', '9'); +INSERT INTO `spell_chain` VALUES ('35387', '0', '35387', '1'); +INSERT INTO `spell_chain` VALUES ('35389', '35387', '35387', '2'); +INSERT INTO `spell_chain` VALUES ('35392', '35389', '35387', '3'); +INSERT INTO `spell_chain` VALUES ('35346', '0', '35346', '1'); +INSERT INTO `spell_chain` VALUES ('25076', '0', '25076', '1'); +INSERT INTO `spell_chain` VALUES ('35694', '0', '35694', '1'); +INSERT INTO `spell_chain` VALUES ('35698', '35694', '35694', '2'); +INSERT INTO `spell_chain` VALUES ('4187', '0', '4187', '1'); +INSERT INTO `spell_chain` VALUES ('4188', '4187', '4187', '2'); +INSERT INTO `spell_chain` VALUES ('4189', '4188', '4187', '3'); +INSERT INTO `spell_chain` VALUES ('4190', '4189', '4187', '4'); +INSERT INTO `spell_chain` VALUES ('4191', '4190', '4187', '5'); +INSERT INTO `spell_chain` VALUES ('4192', '4191', '4187', '6'); +INSERT INTO `spell_chain` VALUES ('4193', '4192', '4187', '7'); +INSERT INTO `spell_chain` VALUES ('4194', '4193', '4187', '8'); +INSERT INTO `spell_chain` VALUES ('5041', '4194', '4187', '9'); +INSERT INTO `spell_chain` VALUES ('5042', '5041', '4187', '10'); +INSERT INTO `spell_chain` VALUES ('27062', '5042', '4187', '11'); +INSERT INTO `spell_chain` VALUES ('24545', '0', '24545', '1'); +INSERT INTO `spell_chain` VALUES ('24549', '24545', '24545', '2'); +INSERT INTO `spell_chain` VALUES ('24550', '24549', '24545', '3'); +INSERT INTO `spell_chain` VALUES ('24551', '24550', '24545', '4'); +INSERT INTO `spell_chain` VALUES ('24552', '24551', '24545', '5'); +INSERT INTO `spell_chain` VALUES ('24553', '24552', '24545', '6'); +INSERT INTO `spell_chain` VALUES ('24554', '24553', '24545', '7'); +INSERT INTO `spell_chain` VALUES ('24555', '24554', '24545', '8'); +INSERT INTO `spell_chain` VALUES ('24629', '24555', '24545', '9'); +INSERT INTO `spell_chain` VALUES ('24630', '24629', '24545', '10'); +INSERT INTO `spell_chain` VALUES ('27061', '24630', '24545', '11'); +INSERT INTO `spell_chain` VALUES ('24493', '0', '24493', '1'); +INSERT INTO `spell_chain` VALUES ('24497', '24493', '24493', '2'); +INSERT INTO `spell_chain` VALUES ('24500', '24497', '24493', '3'); +INSERT INTO `spell_chain` VALUES ('24501', '24500', '24493', '4'); +INSERT INTO `spell_chain` VALUES ('27052', '24501', '24493', '5'); +INSERT INTO `spell_chain` VALUES ('23992', '0', '23992', '1'); +INSERT INTO `spell_chain` VALUES ('24439', '23992', '23992', '2'); +INSERT INTO `spell_chain` VALUES ('24444', '24439', '23992', '3'); +INSERT INTO `spell_chain` VALUES ('24445', '24444', '23992', '4'); +INSERT INTO `spell_chain` VALUES ('27053', '24445', '23992', '5'); +INSERT INTO `spell_chain` VALUES ('24446', '0', '24446', '1'); +INSERT INTO `spell_chain` VALUES ('24447', '24446', '24446', '2'); +INSERT INTO `spell_chain` VALUES ('24448', '24447', '24446', '3'); +INSERT INTO `spell_chain` VALUES ('24449', '24448', '24446', '4'); +INSERT INTO `spell_chain` VALUES ('27054', '24449', '24446', '5'); +INSERT INTO `spell_chain` VALUES ('24492', '0', '24492', '1'); +INSERT INTO `spell_chain` VALUES ('24502', '24492', '24492', '2'); +INSERT INTO `spell_chain` VALUES ('24503', '24502', '24492', '3'); +INSERT INTO `spell_chain` VALUES ('24504', '24503', '24492', '4'); +INSERT INTO `spell_chain` VALUES ('27055', '24504', '24492', '5'); +INSERT INTO `spell_chain` VALUES ('24488', '0', '24488', '1'); +INSERT INTO `spell_chain` VALUES ('24505', '24488', '24488', '2'); +INSERT INTO `spell_chain` VALUES ('24506', '24505', '24488', '3'); +INSERT INTO `spell_chain` VALUES ('24507', '24506', '24488', '4'); +INSERT INTO `spell_chain` VALUES ('27056', '24507', '24488', '5'); +INSERT INTO `spell_chain` VALUES ('6307', '0', '6307', '1'); +INSERT INTO `spell_chain` VALUES ('7804', '6307', '6307', '2'); +INSERT INTO `spell_chain` VALUES ('7805', '7804', '6307', '3'); +INSERT INTO `spell_chain` VALUES ('11766', '7805', '6307', '4'); +INSERT INTO `spell_chain` VALUES ('11767', '11766', '6307', '5'); +INSERT INTO `spell_chain` VALUES ('27268', '11767', '6307', '6'); +INSERT INTO `spell_chain` VALUES ('2947', '0', '2947', '1'); +INSERT INTO `spell_chain` VALUES ('8316', '2947', '2947', '2'); +INSERT INTO `spell_chain` VALUES ('8317', '8316', '2947', '3'); +INSERT INTO `spell_chain` VALUES ('11770', '8317', '2947', '4'); +INSERT INTO `spell_chain` VALUES ('11771', '11770', '2947', '5'); +INSERT INTO `spell_chain` VALUES ('27269', '11771', '2947', '6'); +INSERT INTO `spell_chain` VALUES ('3110', '0', '3110', '1'); +INSERT INTO `spell_chain` VALUES ('7799', '3110', '3110', '2'); +INSERT INTO `spell_chain` VALUES ('7800', '7799', '3110', '3'); +INSERT INTO `spell_chain` VALUES ('7801', '7800', '3110', '4'); +INSERT INTO `spell_chain` VALUES ('7802', '7801', '3110', '5'); +INSERT INTO `spell_chain` VALUES ('11762', '7802', '3110', '6'); +INSERT INTO `spell_chain` VALUES ('11763', '11762', '3110', '7'); +INSERT INTO `spell_chain` VALUES ('27267', '11763', '3110', '8'); +INSERT INTO `spell_chain` VALUES ('17767', '0', '17767', '1'); +INSERT INTO `spell_chain` VALUES ('17850', '17767', '17767', '2'); +INSERT INTO `spell_chain` VALUES ('17851', '17850', '17767', '3'); +INSERT INTO `spell_chain` VALUES ('17852', '17851', '17767', '4'); +INSERT INTO `spell_chain` VALUES ('17853', '17852', '17767', '5'); +INSERT INTO `spell_chain` VALUES ('17854', '17853', '17767', '6'); +INSERT INTO `spell_chain` VALUES ('27272', '17854', '17767', '7'); +INSERT INTO `spell_chain` VALUES ('7812', '0', '7812', '1'); +INSERT INTO `spell_chain` VALUES ('19438', '7812', '7812', '2'); +INSERT INTO `spell_chain` VALUES ('19440', '19438', '7812', '3'); +INSERT INTO `spell_chain` VALUES ('19441', '19440', '7812', '4'); +INSERT INTO `spell_chain` VALUES ('19442', '19441', '7812', '5'); +INSERT INTO `spell_chain` VALUES ('19443', '19442', '7812', '6'); +INSERT INTO `spell_chain` VALUES ('27273', '19443', '7812', '7'); +INSERT INTO `spell_chain` VALUES ('17735', '0', '17735', '1'); +INSERT INTO `spell_chain` VALUES ('17750', '17735', '17735', '2'); +INSERT INTO `spell_chain` VALUES ('17751', '17750', '17735', '3'); +INSERT INTO `spell_chain` VALUES ('17752', '17751', '17735', '4'); +INSERT INTO `spell_chain` VALUES ('27271', '17752', '17735', '5'); +INSERT INTO `spell_chain` VALUES ('33701', '27271', '17735', '6'); +INSERT INTO `spell_chain` VALUES ('3716', '0', '3716', '1'); +INSERT INTO `spell_chain` VALUES ('7809', '3716', '3716', '2'); +INSERT INTO `spell_chain` VALUES ('7810', '7809', '3716', '3'); +INSERT INTO `spell_chain` VALUES ('7811', '7810', '3716', '4'); +INSERT INTO `spell_chain` VALUES ('11774', '7811', '3716', '5'); +INSERT INTO `spell_chain` VALUES ('11775', '11774', '3716', '6'); +INSERT INTO `spell_chain` VALUES ('27270', '11775', '3716', '7'); +INSERT INTO `spell_chain` VALUES ('7814', '0', '7814', '1'); +INSERT INTO `spell_chain` VALUES ('7815', '7814', '7814', '2'); +INSERT INTO `spell_chain` VALUES ('7816', '7815', '7814', '3'); +INSERT INTO `spell_chain` VALUES ('11778', '7816', '7814', '4'); +INSERT INTO `spell_chain` VALUES ('11779', '11778', '7814', '5'); +INSERT INTO `spell_chain` VALUES ('11780', '11779', '7814', '6'); +INSERT INTO `spell_chain` VALUES ('27274', '11780', '7814', '7'); +INSERT INTO `spell_chain` VALUES ('6360', '0', '6360', '1'); +INSERT INTO `spell_chain` VALUES ('7813', '6360', '6360', '2'); +INSERT INTO `spell_chain` VALUES ('11784', '7813', '6360', '3'); +INSERT INTO `spell_chain` VALUES ('11785', '11784', '6360', '4'); +INSERT INTO `spell_chain` VALUES ('27275', '11785', '6360', '5'); +INSERT INTO `spell_chain` VALUES ('19505', '0', '19505', '1'); +INSERT INTO `spell_chain` VALUES ('19731', '19505', '19505', '2'); +INSERT INTO `spell_chain` VALUES ('19734', '19731', '19505', '3'); +INSERT INTO `spell_chain` VALUES ('19736', '19734', '19505', '4'); +INSERT INTO `spell_chain` VALUES ('27276', '19736', '19505', '5'); +INSERT INTO `spell_chain` VALUES ('27277', '27276', '19505', '6'); +INSERT INTO `spell_chain` VALUES ('19244', '0', '19244', '1'); +INSERT INTO `spell_chain` VALUES ('19647', '19244', '19244', '2'); +INSERT INTO `spell_chain` VALUES ('19478', '0', '19478', '1'); +INSERT INTO `spell_chain` VALUES ('19655', '19478', '19478', '2'); +INSERT INTO `spell_chain` VALUES ('19656', '19655', '19478', '3'); +INSERT INTO `spell_chain` VALUES ('19660', '19656', '19478', '4'); +INSERT INTO `spell_chain` VALUES ('27280', '19660', '19478', '5'); +INSERT INTO `spell_chain` VALUES ('33698', '0', '33698', '1'); +INSERT INTO `spell_chain` VALUES ('33699', '33698', '33698', '2'); +INSERT INTO `spell_chain` VALUES ('33700', '33699', '33698', '3'); +INSERT INTO `spell_chain` VALUES ('30213', '0', '30213', '1'); +INSERT INTO `spell_chain` VALUES ('30219', '30213', '30213', '2'); +INSERT INTO `spell_chain` VALUES ('30223', '30219', '30213', '3'); +INSERT INTO `spell_chain` VALUES ('30151', '0', '30151', '1'); +INSERT INTO `spell_chain` VALUES ('30194', '30151', '30151', '2'); +INSERT INTO `spell_chain` VALUES ('30198', '30194', '30151', '3'); diff --git a/sql/updates/0.8/4116_creature_template.sql b/sql/updates/0.8/4116_creature_template.sql new file mode 100644 index 000000000..dfd710f85 --- /dev/null +++ b/sql/updates/0.8/4116_creature_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_template` +ADD COLUMN `RacialLeader` tinyint(1) unsigned NOT NULL default '0' AFTER `InhabitType`; diff --git a/sql/updates/0.8/4133_command.sql b/sql/updates/0.8/4133_command.sql new file mode 100644 index 000000000..b50d320ac --- /dev/null +++ b/sql/updates/0.8/4133_command.sql @@ -0,0 +1,6 @@ +DELETE FROM `command` WHERE `name` = 'reload'; +DELETE FROM `command` WHERE `name` = 'reload all'; +DELETE FROM `command` WHERE `name` = 'reload all_spell'; +INSERT INTO `command` VALUES('reload',3,'Syntax: .reload table_name\r\n\r\nReload table `table_name` if reload support added for this table and this table can be _safe_ reloaded.'); +INSERT INTO `command` VALUES('reload all',3,'Syntax: .reload all\r\n\r\nReload all tables with reload support added and that can be _safe_ reloaded.'); +INSERT INTO `command` VALUES('reload all_spell',3,'Syntax: .reload all\r\n\r\nReload all `spell_*` tables with reload support added and that can be _safe_ reloaded.'); diff --git a/sql/updates/0.8/4133_spell_chain.sql b/sql/updates/0.8/4133_spell_chain.sql new file mode 100644 index 000000000..ff5d35f0b --- /dev/null +++ b/sql/updates/0.8/4133_spell_chain.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (5487,9634,33943,40120); + +INSERT INTO `spell_chain` VALUES +(5487,0,5487,1), +(9634,5487,5487,2), +(33943,0,33943,1), +(40120,33943,33943,2); diff --git a/sql/updates/0.8/4134_command.sql b/sql/updates/0.8/4134_command.sql new file mode 100644 index 000000000..e34ad40fd --- /dev/null +++ b/sql/updates/0.8/4134_command.sql @@ -0,0 +1,6 @@ +DELETE FROM `command` WHERE `name` = 'reload all_area'; +DELETE FROM `command` WHERE `name` = 'reload all_loot'; +DELETE FROM `command` WHERE `name` = 'reload all_quest'; +INSERT INTO `command` VALUES('reload all_area',3,'Syntax: .reload all_area\r\n\r\nReload all `areatrigger_*` tables if reload support added for this table and this table can be _safe_ reloaded.'); +INSERT INTO `command` VALUES('reload all_loot',3,'Syntax: .reload all_loot\r\n\r\nReload all `*_loot_template` tables. This can be slow operation with lags for server run.'); +INSERT INTO `command` VALUES('reload all_quest',3,'Syntax: .reload all_quest\r\n\r\nReload all quest related tables if reload support added for this table and this table can be _safe_ reloaded.'); diff --git a/sql/updates/0.8/4139_spell_proc_event.sql b/sql/updates/0.8/4139_spell_proc_event.sql new file mode 100644 index 000000000..fd83802c0 --- /dev/null +++ b/sql/updates/0.8/4139_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 11255, 12598 ); +INSERT INTO `spell_proc_event` VALUES +(11255,32,0,0,3,0,16384,0), +(12598,32,0,0,3,0,16384,0); + diff --git a/sql/updates/0.8/4140_command.sql b/sql/updates/0.8/4140_command.sql new file mode 100644 index 000000000..f70bb2ce1 --- /dev/null +++ b/sql/updates/0.8/4140_command.sql @@ -0,0 +1,4 @@ +INSERT INTO `command` ( `name` , `security` , `help` ) +VALUES ( +'tele', '1', 'Syntax: .tele $location\n\nTeleport the gm to the provided location. You can look up these locations using .lookuptele' +); \ No newline at end of file diff --git a/sql/updates/0.8/4145_character_reputation.sql b/sql/updates/0.8/4145_character_reputation.sql new file mode 100644 index 000000000..b9849f114 --- /dev/null +++ b/sql/updates/0.8/4145_character_reputation.sql @@ -0,0 +1 @@ +ALTER TABLE `character_reputation` DROP `reputation`; \ No newline at end of file diff --git a/sql/updates/0.8/4154_spell_proc_event.sql b/sql/updates/0.8/4154_spell_proc_event.sql new file mode 100644 index 000000000..dbb1e1e04 --- /dev/null +++ b/sql/updates/0.8/4154_spell_proc_event.sql @@ -0,0 +1,23 @@ +/* for reference +DROP TABLE IF EXISTS `spell_proc_event`; +CREATE TABLE `spell_proc_event` ( + `entry` smallint(6) unsigned NOT NULL default '0', + `SchoolMask` tinyint(4) NOT NULL default '0', + `Category` smallint(6) NOT NULL default '0', + `SkillID` smallint(6) NOT NULL default '0', + `SpellFamilyName` smallint(6) unsigned NOT NULL default '0', + `SpellFamilyMask` bigint(40) unsigned NOT NULL default '0', + `procFlags` int(11) unsigned NOT NULL default '0', + `ppmRate` float NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +*/ + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 30675, 30678, 30679, 30680, 30681 ); +INSERT INTO `spell_proc_event` VALUES +(30675,0,0,0,11,3,16384,0), +(30678,0,0,0,11,3,16384,0), +(30679,0,0,0,11,3,16384,0), +(30680,0,0,0,11,3,16384,0), +(30681,0,0,0,11,3,16384,0); + diff --git a/sql/updates/0.8/4176_character.sql b/sql/updates/0.8/4176_character.sql new file mode 100644 index 000000000..5a7b106b2 --- /dev/null +++ b/sql/updates/0.8/4176_character.sql @@ -0,0 +1 @@ +ALTER TABLE `character` ADD `zone` INT(11) UNSIGNED NOT NULL DEFAULT '0'; diff --git a/sql/updates/0.8/4176_command.sql b/sql/updates/0.8/4176_command.sql new file mode 100644 index 000000000..8e88e84c7 --- /dev/null +++ b/sql/updates/0.8/4176_command.sql @@ -0,0 +1,3 @@ +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES +('gogrid', '3', 'Syntax: .gogrid #gridX #gridY [#mapId]\n\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'); + diff --git a/sql/updates/0.8/4187_command.sql b/sql/updates/0.8/4187_command.sql new file mode 100644 index 000000000..75033a11c --- /dev/null +++ b/sql/updates/0.8/4187_command.sql @@ -0,0 +1,5 @@ +UPDATE `command` SET `help` = 'Syntax: .learn all_myclass\r\n\r\nLearn all spells and talents available for his class.' WHERE `name` = 'learn all_myclass'; +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES +('learn all_myspells',3,'Syntax: .learn all_myspells\r\n\r\nLearn all spells (except talents and spells with first rank learned as talent) available for his class.'), +('learn all_mytalents',3,'Syntax: .learn all_mytalents\r\n\r\nLearn all talents (and spells with first rank learned as talent) available for his class.'); + diff --git a/sql/updates/0.8/4204_command.sql b/sql/updates/0.8/4204_command.sql new file mode 100644 index 000000000..af8b8d373 --- /dev/null +++ b/sql/updates/0.8/4204_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'setmovetype'; + +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES +('setmovetype',2,'Syntax: .setmovetype [#creature_guid] stay/random/way [NODEL]\r\n\r\nSet for creature pointed by #creature_guid (or selected if #creature_guid not provided) movement type and move it to respawn position (if creature alive). Any existing waypoints for creature will be removed from the database if you do not use NODEL. If the creature is dead then movement type will applied at creature respawn.\r\nMake sure you use NODEL, if you want to keep the waypoints.'); \ No newline at end of file diff --git a/sql/updates/0.8/4205_creature_template.sql b/sql/updates/0.8/4205_creature_template.sql new file mode 100644 index 000000000..84a65b400 --- /dev/null +++ b/sql/updates/0.8/4205_creature_template.sql @@ -0,0 +1,4 @@ +update creature_template set attackpower = round((maxdmg + mindmg) / 4 * 7); +update creature_template set mindmg = round(mindmg - attackpower / 7); +update creature_template set maxdmg = round(maxdmg - attackpower / 7); +update creature_template set mindmg = 1 where mindmg < 1; \ No newline at end of file diff --git a/sql/updates/0.8/4224_character_aura.sql b/sql/updates/0.8/4224_character_aura.sql new file mode 100644 index 000000000..3daac5256 --- /dev/null +++ b/sql/updates/0.8/4224_character_aura.sql @@ -0,0 +1,6 @@ +ALTER TABLE `character_aura` + ADD `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier' AFTER `guid`, + ADD `amount` int(11) NOT NULL default '0' AFTER `effect_index`; + +UPDATE `character_aura` + SET `caster_guid` = `guid`; \ No newline at end of file diff --git a/sql/updates/0.8/4224_pet_aura.sql b/sql/updates/0.8/4224_pet_aura.sql new file mode 100644 index 000000000..f185a65ce --- /dev/null +++ b/sql/updates/0.8/4224_pet_aura.sql @@ -0,0 +1,6 @@ +ALTER TABLE `pet_aura` + ADD `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier' AFTER `guid`, + ADD `amount` int(11) NOT NULL default '0' AFTER `effect_index`; + +UPDATE `pet_aura` + SET `caster_guid` = `guid`; \ No newline at end of file diff --git a/sql/updates/0.8/4235_spell_proc_event.sql b/sql/updates/0.8/4235_spell_proc_event.sql new file mode 100644 index 000000000..f87f40b9b --- /dev/null +++ b/sql/updates/0.8/4235_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37514 ); +INSERT INTO `spell_proc_event` (`entry` ,`SchoolMask`,`Category`,`SkillID`,`SpellFamilyName`,`SpellFamilyMask`,`procFlags`,`ppmRate`) +VALUES ('37514', '0', '0', '0', '0', '0', '32', '0'); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37197 ); +INSERT INTO `spell_proc_event` (`entry` ,`SchoolMask`,`Category`,`SkillID`,`SpellFamilyName`,`SpellFamilyMask`,`procFlags`,`ppmRate`) +VALUES ('37197', '0', '0', '0', '0', '0', '16384', '0'); \ No newline at end of file diff --git a/sql/updates/0.8/4239_spell_chain.sql b/sql/updates/0.8/4239_spell_chain.sql new file mode 100644 index 000000000..287a1de6f --- /dev/null +++ b/sql/updates/0.8/4239_spell_chain.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (25477); + +INSERT INTO `spell_chain` VALUES +(25477,19312,18137,7); diff --git a/sql/updates/0.8/4239_spell_proc_event.sql b/sql/updates/0.8/4239_spell_proc_event.sql new file mode 100644 index 000000000..1e4852c33 --- /dev/null +++ b/sql/updates/0.8/4239_spell_proc_event.sql @@ -0,0 +1,9 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (18137,19308,19309,19310,19311,19312,25477); +INSERT INTO `spell_proc_event` VALUES +(18137,0,0,0,0,0,1049602,0), +(19308,0,0,0,0,0,1049602,0), +(19309,0,0,0,0,0,1049602,0), +(19310,0,0,0,0,0,1049602,0), +(19311,0,0,0,0,0,1049602,0), +(19312,0,0,0,0,0,1049602,0), +(25477,0,0,0,0,0,1049602,0); diff --git a/sql/updates/0.8/4242_spell_proc_event.sql b/sql/updates/0.8/4242_spell_proc_event.sql new file mode 100644 index 000000000..5e00ec3d3 --- /dev/null +++ b/sql/updates/0.8/4242_spell_proc_event.sql @@ -0,0 +1,34 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34948, 34949); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(34948, 0, 0, 0, 0, 0, 4, 0), +(34949, 0, 0, 0, 0, 0, 4, 0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (34497, 34498, 34499); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(34497, 0, 0, 0, 0, 0, 4194304, 0), +(34498, 0, 0, 0, 0, 0, 4194304, 0), +(34499, 0, 0, 0, 0, 0, 4194304, 0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (34500, 34502, 34503); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(34500, 0, 0, 0, 0, 0, 4194304, 0), +(34502, 0, 0, 0, 0, 0, 4194304, 0), +(34503, 0, 0, 0, 0, 0, 4194304, 0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (30823); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(30823, 0, 0, 0, 0, 0, 1, 0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (31244,31245); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(31244, 0, 0, 0, 0, 0, 2147483648, 0), +(31245, 0, 0, 0, 0, 0, 2147483648, 0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (34935,34938,34939); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(34935, 0, 0, 0, 0, 0, 2, 0), +(34938, 0, 0, 0, 0, 0, 2, 0), +(34939, 0, 0, 0, 0, 0, 2, 0); diff --git a/sql/updates/0.8/4243_spell_affect.sql b/sql/updates/0.8/4243_spell_affect.sql new file mode 100644 index 000000000..61c0ff8e6 --- /dev/null +++ b/sql/updates/0.8/4243_spell_affect.sql @@ -0,0 +1,19 @@ +/* +DROP TABLE IF EXISTS `spell_affect`; +CREATE TABLE `spell_affect` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `effectId` tinyint(3) unsigned NOT NULL default '0', + `SpellId` smallint(5) unsigned NOT NULL default '0', + `SchoolMask` tinyint(3) unsigned NOT NULL default '0', + `Category` smallint(5) unsigned NOT NULL default '0', + `SkillID` smallint(5) unsigned NOT NULL default '0', + `SpellFamily` tinyint(3) unsigned NOT NULL default '0', + `SpellFamilyMask` bigint(20) unsigned NOT NULL default '0', + `Charges` smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`effectId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +*/ + +DELETE FROM `spell_affect` WHERE `entry` IN (34936); +INSERT INTO `spell_affect` VALUES +(34936,0,0,0,0,0,0,274877906945,1); diff --git a/sql/updates/0.8/4248_spell_chain.sql b/sql/updates/0.8/4248_spell_chain.sql new file mode 100644 index 000000000..718126f95 --- /dev/null +++ b/sql/updates/0.8/4248_spell_chain.sql @@ -0,0 +1,13 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (33878,33986,33987); + +INSERT INTO `spell_chain` VALUES +(33878,0,33878,1), +(33986,33878,33878,2), +(33987,33986,33878,3); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (33876,33982,33983); + +INSERT INTO `spell_chain` VALUES +(33876,0,33876,1), +(33982,33876,33876,2), +(33983,33982,33876,3); diff --git a/sql/updates/0.8/4248_spell_proc_event.sql b/sql/updates/0.8/4248_spell_proc_event.sql new file mode 100644 index 000000000..e8252cd26 --- /dev/null +++ b/sql/updates/0.8/4248_spell_proc_event.sql @@ -0,0 +1,70 @@ +/* fix scholl mask */ +DELETE FROM `spell_proc_event` WHERE `entry` IN (11103,11119,11120,11129,11180,11255,12357,12358,12359,12360,12598,12846,12847,12848,14892,15268,15286,15323,15324,15325,15326,15362,15363,16164,17793,17796,17801,17802,17803,18073,18096,19407,19412,19413,19414,19415,20234,20235,23551,23572,23721,28592,28593,28594,28595,28719,28809,28823,28847,28849,29074,29075,29076,34914,34916,34917); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(11103,4,0,0,0,0,131072,0), +(11119,4,0,0,0,0,65536,0), +(11120,4,0,0,0,0,65536,0), +(11129,4,0,0,0,0,131072,0), +(11180,16,0,0,0,0,131072,0), +(11255,64,0,0,3,0,16384,0), +(12357,4,0,0,0,0,131072,0), +(12358,4,0,0,0,0,131072,0), +(12359,4,0,0,0,0,131072,0), +(12360,4,0,0,0,0,131072,0), +(12598,64,0,0,3,0,16384,0), +(12846,4,0,0,0,0,65536,0), +(12847,4,0,0,0,0,65536,0), +(12848,4,0,0,0,0,65536,0), +(14892,2,0,56,0,7680,268435456,0), +(15268,32,0,0,0,0,131072,0), +(15286,32,0,0,0,0,32768,0), +(15323,32,0,0,0,0,131072,0), +(15324,32,0,0,0,0,131072,0), +(15325,32,0,0,0,0,131072,0), +(15326,32,0,0,0,0,131072,0), +(15362,2,0,56,0,7680,268435456,0), +(15363,2,0,56,0,7680,268435456,0), +(16164,28,0,0,0,0,65536,0), +(17793,32,0,593,0,1,65536,0), +(17796,32,0,593,0,1,65536,0), +(17801,32,0,593,0,1,65536,0), +(17802,32,0,593,0,1,65536,0), +(17803,32,0,593,0,1,65536,0), +(18073,4,0,0,0,96,131072,0), +(18096,4,0,0,0,96,131072,0), +(19407,64,0,0,0,512,131072,0), +(19412,64,0,0,0,512,131072,0), +(19413,64,0,0,0,512,131072,0), +(19414,64,0,0,0,512,131072,0), +(19415,64,0,0,0,512,131072,0), +(20234,2,0,0,0,32768,131072,0), +(20235,2,0,0,0,32768,131072,0), +(23551,8,0,0,0,192,16384,0), +(23572,8,0,0,0,192,16384,0), +(23721,64,0,163,0,2048,131072,0), +(28592,16,0,0,0,0,131072,0), +(28593,16,0,0,0,0,131072,0), +(28594,16,0,0,0,0,131072,0), +(28595,16,0,0,0,0,131072,0), +(28719,8,0,0,0,32,268435456,0), +(28809,2,0,56,0,4096,268435456,0), +(28823,8,0,374,0,192,134217728,0), +(28847,8,0,573,0,32,16384,0), +(28849,8,0,374,0,128,16384,0), +(29074,20,0,0,0,0,65536,0), +(29075,20,0,0,0,0,65536,0), +(29076,20,0,0,0,0,65536,0), +(34914,32,0,0,0,0,32768,0), +(34916,32,0,0,0,0,32768,0), +(34917,32,0,0,0,0,32768,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (6866,18189); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(6866,0,0,0,0,0,114,0), +(18189,0,0,0,0,0,131072,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37377,39437); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(37377,32,0,0,0,0,16384,0), +(39437,4,0,0,0,0,16384,0); diff --git a/sql/updates/0.8/4252_spell_threat.sql b/sql/updates/0.8/4252_spell_threat.sql new file mode 100644 index 000000000..293388810 --- /dev/null +++ b/sql/updates/0.8/4252_spell_threat.sql @@ -0,0 +1,4 @@ +INSERT INTO spell_threat VALUES +(20243,101), +(30016,101), +(30022,101); \ No newline at end of file diff --git a/sql/updates/0.8/4255_spell_chain.sql b/sql/updates/0.8/4255_spell_chain.sql new file mode 100644 index 000000000..13604da3b --- /dev/null +++ b/sql/updates/0.8/4255_spell_chain.sql @@ -0,0 +1,6 @@ +/* dependent from 14752 */ +DELETE FROM `spell_chain` WHERE `spell_id` IN (27681,32999); + +INSERT INTO `spell_chain` VALUES +(27681,14752,14752,2), +(32999,27681,14752,3); diff --git a/sql/updates/0.8/4258_command.sql b/sql/updates/0.8/4258_command.sql new file mode 100644 index 000000000..0936503c3 --- /dev/null +++ b/sql/updates/0.8/4258_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'grouptele'; + +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES +('grouptele',1,'Syntax: .grouptele #location\r\n\r\nTeleport a selected player and his group members to a given location.'); diff --git a/sql/updates/0.8/4259_spell_chain.sql b/sql/updates/0.8/4259_spell_chain.sql new file mode 100644 index 000000000..763396693 --- /dev/null +++ b/sql/updates/0.8/4259_spell_chain.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (27168); +INSERT INTO `spell_chain` VALUES +(27168,20914,20911,5); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (27169); +INSERT INTO `spell_chain` VALUES +(27169,25899,25899,2); diff --git a/sql/updates/0.8/4259_spell_proc_event.sql b/sql/updates/0.8/4259_spell_proc_event.sql new file mode 100644 index 000000000..c5191b472 --- /dev/null +++ b/sql/updates/0.8/4259_spell_proc_event.sql @@ -0,0 +1,19 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (30299,30301,30302); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(30299,36,0,0,0,0,1048576,0), +(30301,36,0,0,0,0,1048576,0), +(30302,36,0,0,0,0,1048576,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (27168); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(27168,0,0,0,0,0,64,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (27169); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(27169,0,0,0,0,0,64,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33150,33154); +INSERT INTO `spell_proc_event` (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate) VALUES +(33150,0,0,0,0,0,65536,0), +(33154,0,0,0,0,0,65536,0); diff --git a/sql/updates/0.8/4262_spell_proc_event.sql b/sql/updates/0.8/4262_spell_proc_event.sql new file mode 100644 index 000000000..d67fefa7c --- /dev/null +++ b/sql/updates/0.8/4262_spell_proc_event.sql @@ -0,0 +1,20 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33191, 33192, 33193, 33194, 33195 ); +INSERT INTO `spell_proc_event` VALUES +(33191,0,0,0,6,4398054932480,131072,0), +(33192,0,0,0,6,4398054932480,131072,0), +(33193,0,0,0,6,4398054932480,131072,0), +(33194,0,0,0,6,4398054932480,131072,0), +(33195,0,0,0,6,4398054932480,131072,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 32385, 32387, 32392, 32393, 32394, 33191, 33192, 33193, 33194, 33195 ); +INSERT INTO `spell_proc_event` VALUES +(32385,0,0,0,5,73014445058,131072,0), +(32387,0,0,0,5,73014445058,131072,0), +(32392,0,0,0,5,73014445058,131072,0), +(32393,0,0,0,5,73014445058,131072,0), +(32394,0,0,0,5,73014445058,131072,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 30482 ); +INSERT INTO `spell_proc_event` VALUES +(30482,0,0,0,0,0,32768,0); diff --git a/sql/updates/0.8/4266_spell_proc_event.sql b/sql/updates/0.8/4266_spell_proc_event.sql new file mode 100644 index 000000000..d53c9168b --- /dev/null +++ b/sql/updates/0.8/4266_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 20210, 20212, 20213, 20214, 20215 ); +INSERT INTO `spell_proc_event` VALUES +(20210,0,0,0,10,3223322624,268435456,0), +(20212,0,0,0,10,3223322624,268435456,0), +(20213,0,0,0,10,3223322624,268435456,0), +(20214,0,0,0,10,3223322624,268435456,0), +(20215,0,0,0,10,3223322624,268435456,0); diff --git a/sql/updates/0.8/4267_command.sql b/sql/updates/0.8/4267_command.sql new file mode 100644 index 000000000..b702353e5 --- /dev/null +++ b/sql/updates/0.8/4267_command.sql @@ -0,0 +1,6 @@ +DELETE FROM `command` WHERE `name` = 'namego'; +DELETE FROM `command` WHERE `name` = 'groupgo'; + +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES +('namego',1,'Syntax: .namego $charactername\r\n\r\nTeleport the given character to you.'), +('groupgo',1,'Syntax: .groupgo $charactername\r\n\r\nTeleport the given character and his group to you.'); diff --git a/sql/updates/0.8/4270_spell_proc_event.sql b/sql/updates/0.8/4270_spell_proc_event.sql new file mode 100644 index 000000000..87d38c81a --- /dev/null +++ b/sql/updates/0.8/4270_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33191, 33192, 33193, 33194, 33195 ); +INSERT INTO `spell_proc_event` VALUES +(33191,0,0,0,6,4398054932480,131072,0), +(33192,0,0,0,6,4398054932480,131072,0), +(33193,0,0,0,6,4398054932480,131072,0), +(33194,0,0,0,6,4398054932480,131072,0), +(33195,0,0,0,6,4398054932480,131072,0); diff --git a/sql/updates/0.8/4272_spell_proc_event.sql b/sql/updates/0.8/4272_spell_proc_event.sql new file mode 100644 index 000000000..1e57bfd02 --- /dev/null +++ b/sql/updates/0.8/4272_spell_proc_event.sql @@ -0,0 +1,11 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 16880 ); +INSERT INTO `spell_proc_event` VALUES +(16880,0,0,0,0,0,65536,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 40475 ); +INSERT INTO `spell_proc_event` VALUES +(40475,0,0,0,0,0,524289,3); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 41434 ); +INSERT INTO `spell_proc_event` VALUES +(41434,0,0,0,0,0,1,2); diff --git a/sql/updates/0.8/4274_character_pet.sql b/sql/updates/0.8/4274_character_pet.sql new file mode 100644 index 000000000..bae4114fb --- /dev/null +++ b/sql/updates/0.8/4274_character_pet.sql @@ -0,0 +1,9 @@ +ALTER TABLE `character_pet` ADD `CreatedBySpell` int(11) unsigned NOT NULL default '0' AFTER `modelid`; +ALTER TABLE `character_pet` ADD `PetType` tinyint(3) unsigned NOT NULL default '0' AFTER `CreatedBySpell`; +UPDATE `character_pet` SET `PetType` = 1, `CreatedBySpell` = 1515 WHERE (`entry` <> 416 AND `entry` <> 417 AND `entry` <> 1860 AND `entry` <> 1863 AND `entry` <> 17252 AND `entry` <> 510); +UPDATE `character_pet` SET `CreatedBySpell` = 688 WHERE (`entry` = 416); +UPDATE `character_pet` SET `CreatedBySpell` = 691 WHERE (`entry` = 417); +UPDATE `character_pet` SET `CreatedBySpell` = 697 WHERE (`entry` = 1860); +UPDATE `character_pet` SET `CreatedBySpell` = 712 WHERE (`entry` = 1863); +UPDATE `character_pet` SET `CreatedBySpell` = 30146 WHERE (`entry` = 17252); +UPDATE `character_pet` SET `CreatedBySpell` = 31687 WHERE (`entry` = 510); \ No newline at end of file diff --git a/sql/updates/0.8/4275_game_event.sql b/sql/updates/0.8/4275_game_event.sql new file mode 100644 index 000000000..5bf5a6f05 --- /dev/null +++ b/sql/updates/0.8/4275_game_event.sql @@ -0,0 +1,21 @@ +CREATE TABLE `game_event_gameobject` ( + `guid` int(10) unsigned NOT NULL, + `event` mediumint(9) NOT NULL DEFAULT '0' COMMENT 'Put negatives values to remove during event', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `game_event_creature` ( + `guid` int(10) unsigned NOT NULL, + `event` mediumint(9) NOT NULL DEFAULT '0' COMMENT 'Put negatives values to remove during event', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `game_event` ( + `entry` mediumint(8) unsigned NOT NULL COMMENT 'Entry of the game event', + `start` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Absolute start date, the event will never start before', + `end` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Absolute end date, the event will never start afler', + `occurence` bigint(20) unsigned NOT NULL DEFAULT '86400' COMMENT 'Delay in hours between occurences of the event', + `length` bigint(20) unsigned NOT NULL DEFAULT '43200' COMMENT 'Length in hours of the event', + `description` varchar(255) DEFAULT NULL COMMENT 'Description of the event displayed in console', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.8/4288_spell_proc_event.sql b/sql/updates/0.8/4288_spell_proc_event.sql new file mode 100644 index 000000000..0e3e6f890 --- /dev/null +++ b/sql/updates/0.8/4288_spell_proc_event.sql @@ -0,0 +1,47 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34320 ); +INSERT INTO `spell_proc_event` VALUES +(34320,0,0,0,0,0,65536,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 38347 ); +INSERT INTO `spell_proc_event` VALUES +(38347,0,0,0,0,0,65536,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 42083 ); +INSERT INTO `spell_proc_event` VALUES +(42083,0,0,0,0,0,4198400,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33012 ); +INSERT INTO `spell_proc_event` VALUES +(33012,0,0,0,0,0,4,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33014 ); +INSERT INTO `spell_proc_event` VALUES +(33014,0,0,0,0,0,4,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 31794 ); +INSERT INTO `spell_proc_event` VALUES +(31794,0,0,0,0,0,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 33089 ); +INSERT INTO `spell_proc_event` VALUES +(33089,0,0,0,0,0,64,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 34586 ); +INSERT INTO `spell_proc_event` VALUES +(34586,0,0,0,0,0,524289,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 38332 ); +INSERT INTO `spell_proc_event` VALUES +(38332,0,0,0,0,0,134217728,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37657 ); +INSERT INTO `spell_proc_event` VALUES +(37657,0,0,0,0,0,65536,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37195 ); +INSERT INTO `spell_proc_event` VALUES +(37195,0,0,0,10,8388608,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37525 ); +INSERT INTO `spell_proc_event` VALUES +(37525,0,0,0,0,0,1049602,0); diff --git a/sql/updates/0.8/4294_spell_proc_event.sql b/sql/updates/0.8/4294_spell_proc_event.sql new file mode 100644 index 000000000..bbf6f413c --- /dev/null +++ b/sql/updates/0.8/4294_spell_proc_event.sql @@ -0,0 +1,23 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 11255, 12598 ); +INSERT INTO `spell_proc_event` VALUES +(11255,0,0,0,3,16384,16384,0), +(12598,0,0,0,3,16384,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 17793, 17796, 17801, 17802, 17803 ); +INSERT INTO `spell_proc_event` VALUES +(17793,0,0,593,5,1,65536,0), +(17796,0,0,593,5,1,65536,0), +(17801,0,0,593,5,1,65536,0), +(17802,0,0,593,5,1,65536,0), +(17803,0,0,593,5,1,65536,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 18094, 18095 ); +INSERT INTO `spell_proc_event` VALUES +(18094,0,0,0,5,10,131072,0), +(18095,0,0,0,5,10,131072,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 37443 ); +INSERT INTO `spell_proc_event` VALUES +(37443,0,0,0,0,0,65536,0); diff --git a/sql/updates/0.8/4296_spell_proc_event.sql b/sql/updates/0.8/4296_spell_proc_event.sql new file mode 100644 index 000000000..902a3f3ca --- /dev/null +++ b/sql/updates/0.8/4296_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN ( 12958, 12311 ); +INSERT INTO `spell_proc_event` VALUES +(12958,0,0,0,4,0x800,0x20000,0), +(12311,0,0,0,4,0x800,0x20000,0); diff --git a/sql/updates/0.8/4317_spell_affect.sql b/sql/updates/0.8/4317_spell_affect.sql new file mode 100644 index 000000000..6239feca4 --- /dev/null +++ b/sql/updates/0.8/4317_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (31670,31672); +INSERT INTO `spell_affect` VALUES +(31670,0,0,0,0,0,0,0x500080000,0), +(31672,0,0,0,0,0,0,0x500080000,0); diff --git a/sql/updates/0.8/4320_spell_affect.sql b/sql/updates/0.8/4320_spell_affect.sql new file mode 100644 index 000000000..0018a669d --- /dev/null +++ b/sql/updates/0.8/4320_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (31670,31672); +INSERT INTO `spell_affect` VALUES +(31670,0,0,0,0,0,0,0x500000200,0), +(31672,0,0,0,0,0,0,0x500000200,0); diff --git a/sql/updates/0.8/4331_spell_chain.sql b/sql/updates/0.8/4331_spell_chain.sql new file mode 100644 index 000000000..4542e6411 --- /dev/null +++ b/sql/updates/0.8/4331_spell_chain.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (974,32593,32594); +INSERT INTO `spell_chain` VALUES +(974,0,974,1), +(32593,974,974,2), +(32594,32593,974,3); + diff --git a/sql/updates/0.8/4331_spell_proc_event.sql b/sql/updates/0.8/4331_spell_proc_event.sql new file mode 100644 index 000000000..cc91ec0c1 --- /dev/null +++ b/sql/updates/0.8/4331_spell_proc_event.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (974,32593,32594); +INSERT INTO `spell_proc_event` VALUES +(974,0,0,0,0,0,0x100402,0), +(32593,0,0,0,0,0,0x100402,0), +(32594,0,0,0,0,0,0x100402,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (2652,19261,19262,19264,19265,19266,25461); +INSERT INTO `spell_proc_event` VALUES +(2652, 0,0,0,0,0,0x2,0), +(19261,0,0,0,0,0,0x2,0), +(19262,0,0,0,0,0,0x2,0), +(19264,0,0,0,0,0,0x2,0), +(19265,0,0,0,0,0,0x2,0), +(19266,0,0,0,0,0,0x2,0), +(25461,0,0,0,0,0,0x2,0); diff --git a/sql/updates/0.8/4341_game_event.sql b/sql/updates/0.8/4341_game_event.sql new file mode 100644 index 000000000..f0fcd34d6 --- /dev/null +++ b/sql/updates/0.8/4341_game_event.sql @@ -0,0 +1,4 @@ +ALTER TABLE `game_event` CHANGE `occurence` `occurence` bigint(20) unsigned NOT NULL default '5184000' COMMENT 'Delay in minutes between occurences of the event'; +ALTER TABLE `game_event` CHANGE `length` `length` bigint(20) unsigned NOT NULL default '2592000' COMMENT 'Length in minutes of the event'; +UPDATE `game_event` SET `occurence` = `occurence` * 60; +UPDATE `game_event` SET `length` = `length` * 60; \ No newline at end of file diff --git a/sql/updates/0.8/4356_command.sql b/sql/updates/0.8/4356_command.sql new file mode 100644 index 000000000..57c6a0b47 --- /dev/null +++ b/sql/updates/0.8/4356_command.sql @@ -0,0 +1 @@ +DELETE FROM `command` WHERE `name` = 'AddSpawn'; diff --git a/sql/updates/0.8/4369_battleground_template.sql b/sql/updates/0.8/4369_battleground_template.sql new file mode 100644 index 000000000..4271a0ede --- /dev/null +++ b/sql/updates/0.8/4369_battleground_template.sql @@ -0,0 +1,2 @@ +DELETE FROM `battleground_template` WHERE `id`='4'; +INSERT INTO `battleground_template` VALUES ('4', '2', '10', '70', '929', '0', '936', '3.14159'); diff --git a/sql/updates/0.8/4376_battleground_template.sql b/sql/updates/0.8/4376_battleground_template.sql new file mode 100644 index 000000000..46738725a --- /dev/null +++ b/sql/updates/0.8/4376_battleground_template.sql @@ -0,0 +1,3 @@ +DELETE FROM `battleground_template` WHERE `id` IN ('5', '6'); +INSERT INTO `battleground_template` VALUES ('5', '2', '10', '70', '939', '0', '940', '3.14159'); +INSERT INTO `battleground_template` VALUES ('6', '2', '10', '70', '0', '0', '0', '0'); diff --git a/sql/updates/0.8/4392_battleground_template.sql b/sql/updates/0.8/4392_battleground_template.sql new file mode 100644 index 000000000..7187f1cd2 --- /dev/null +++ b/sql/updates/0.8/4392_battleground_template.sql @@ -0,0 +1,2 @@ +DELETE FROM `battleground_template` WHERE `id`='8'; +INSERT INTO `battleground_template` VALUES ('8', '2', '10', '70', '1258', '0', '1259', '3.14159'); diff --git a/sql/updates/0.8/4395_spell_chain.sql b/sql/updates/0.8/4395_spell_chain.sql new file mode 100644 index 000000000..fb5b72855 --- /dev/null +++ b/sql/updates/0.8/4395_spell_chain.sql @@ -0,0 +1,20 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (27149); +INSERT INTO `spell_chain` VALUES +(27149,10293,465,8); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (27150); +INSERT INTO `spell_chain` VALUES +(27150,10301,7294,6); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (27151); +INSERT INTO `spell_chain` VALUES +(27151,19896,19876,4); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (27152); +INSERT INTO `spell_chain` VALUES +(27152,19898,19888,4); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (27153); +INSERT INTO `spell_chain` VALUES +(27153,19900,19891,4); + diff --git a/sql/updates/0.8/4397_command.sql b/sql/updates/0.8/4397_command.sql new file mode 100644 index 000000000..ad554c527 --- /dev/null +++ b/sql/updates/0.8/4397_command.sql @@ -0,0 +1,15 @@ +delete from command where name in('whisper2', 'nyi', 'prog', 'run','go', 'object', 'gmon', 'gmoff', 'worldport'); + +update command set name='playemote' where name='emote'; +update command set name='setmodel' where name='displayid'; +update command set name='listgm' where name='gmlist'; + +update command set security=1 where name in ('gogrid', 'goxy') ; +update command set security=2 where name in ('addgo', 'standstate', 'anim', 'morph'); + +delete from command where name in('textemote', 'taxicheat','gm','visible'); +INSERT INTO `command` VALUES +('textemote',3,'Syntax: .text #emoteid\r\n\r\nMake the selected creature to do textemote with an emote of id #emoteid.'), +('taxicheat',1,'Syntax: .taxicheat on/off\r\n\r\nTemporary grant access or remove to all taxi routes for the selected character. If no character is selected, hide or reveal all routes to you.\r\n\r\nVisited taxi nodes sill accessible after removing access.'), +('visible',1,'Syntax: .visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'), +('gm', 1, 'Syntax: .gm on/off\r\n\r\nEnable or Disable GM MODE'); diff --git a/sql/updates/0.8/4401_spell_chain.sql b/sql/updates/0.8/4401_spell_chain.sql new file mode 100644 index 000000000..c67c5b50d --- /dev/null +++ b/sql/updates/0.8/4401_spell_chain.sql @@ -0,0 +1,11 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (30283,30413,30414); +INSERT INTO `spell_chain` VALUES +(30283,0,30283,1), +(30413,30283,30283,2), +(30414,30413,30283,3); + +DELETE FROM `spell_chain` WHERE `spell_id` IN (30108,30404,30405); +INSERT INTO `spell_chain` VALUES +(30108,0,30108,1), +(30404,30108,30108,2), +(30405,30404,30108,3); diff --git a/sql/updates/0.8/4403_reserved_name.sql b/sql/updates/0.8/4403_reserved_name.sql new file mode 100644 index 000000000..a72e9aace --- /dev/null +++ b/sql/updates/0.8/4403_reserved_name.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS `reserved_name`; +CREATE TABLE `reserved_name` ( + `name` VARCHAR(12) NOT NULL DEFAULT '', + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player Reserved Names'; \ No newline at end of file diff --git a/sql/updates/0.8/4407_character.sql b/sql/updates/0.8/4407_character.sql new file mode 100644 index 000000000..394740883 --- /dev/null +++ b/sql/updates/0.8/4407_character.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character` ADD COLUMN `pending_honor` float NOT NULL default '0'; +ALTER TABLE `character` ADD COLUMN `last_honor_date` int(11) unsigned NOT NULL default '0'; +ALTER TABLE `character` ADD COLUMN `last_kill_date` int(11) unsigned NOT NULL default '0'; \ No newline at end of file diff --git a/sql/updates/0.8/4407_character_kill.sql b/sql/updates/0.8/4407_character_kill.sql new file mode 100644 index 000000000..b477a8f4a --- /dev/null +++ b/sql/updates/0.8/4407_character_kill.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `character_kill`; +CREATE TABLE `character_kill` ( + `guid` int(11) NOT NULL default '0', + `victim_guid` int(11) NOT NULL default '0', + `count` tinyint(3) NOT NULL default '0', + PRIMARY KEY (`guid`,`victim_guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Kills Yesterday'; \ No newline at end of file diff --git a/sql/updates/0.8/4407_command.sql b/sql/updates/0.8/4407_command.sql new file mode 100644 index 000000000..4bf2dfa18 --- /dev/null +++ b/sql/updates/0.8/4407_command.sql @@ -0,0 +1,11 @@ +delete from command where name in('honor', 'honor add', 'honor addkill', 'honor flushkills','honor update', 'modify honor'); + +update `command` set `help` = 'Syntax: .modify $parameter $value\r\n\r\nModify the value of various parameters. Use .help modify $parameter to get help on specific parameter usage.\r\n\r\nSupported parameters include hp, mana, rage, energy, money, speed, swim, scale, bit, bwalk, aspeed, faction, spell, tp and honor.' where `name` = 'modify'; + +INSERT INTO `command` ( `name` , `security` , `help` ) VALUES +('honor',2,'Syntax: .honor $command [$value] Various honor related commands. Use .help honor $command to get help on specific parameter usage. Supported parameters include add, addkill, flushkills, update'), +('honor add',2,'Syntax: .honor add $amount\r\n\r\nAdd a certain amount of honor (gained today) to the selected player.'), +('honor addkill',2,'Syntax: .honor addkikll\r\n\r\nAdd the targeted unit as one of your pvp kills today (you only get honor if it\'s a racial leader or a player)'), +('honor flushkills',2,'Syntax: .honor flushkills\r\n\r\nClear today\'s kills from the player limit storage (immediately) and from the DB (on next save) for the selected player.'), +('honor update',2,'Syntax: .honor update\r\n\r\nForce the yesterday\'s honor fields to be updated with today\'s data, which will get reset for the selected player.'), +('modify honor',1,'Syntax: .modify honor $amount\r\n\r\nAdded $amount to the selected player\'s total honor points.'); \ No newline at end of file diff --git a/sql/updates/0.8/4414_spell_chain.sql b/sql/updates/0.8/4414_spell_chain.sql new file mode 100644 index 000000000..75ab4be0d --- /dev/null +++ b/sql/updates/0.8/4414_spell_chain.sql @@ -0,0 +1,312 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN ( +25202,25203,25208,25210,25212,25213,25217,25218,25221,25222,25225,25231,25233,25234,25235,25236,25241, +25242,25248,25258,25264,25266,25269,25272,25275,25308,25312,25331,25363,25364,25367,25368,25372,25375, +25379,25380,25384,25387,25389,25391,25396,25420,25422,25423,25429,25431,25433,25435,25437,25439,25441, +25442,25446,25448,25449,25450,25454,25457,25464,25467,25470,25479,25485,25489,25500,25505,25508,25509, +25525,25528,25533,25546,25547,25552,25557,25560,25563,25567,25570,25574,25577,25585,25587,25596,26839, +26861,26862,26863,26864,26865,26866,26867,26884,26889,26892,26969,26978,26979,26980,26981,26982,26983, +26984,26985,26986,26987,26988,26989,26990,26992,26993,26994,26995,26996,26997,26998,26999,27001,27002, +27003,27005,27006,27008,27009,27011,27012,27013,27014,27015,27016,27018,27019,27020,27021,27022,27023, +27025,27044,27045,27046,27065,27066,27067,27068,27070,27071,27072,27073,27074,27075,27078,27079,27080, +27082,27085,27086,27087,27088,27090,27124,27125,27126,27128,27130,27131,27132,27133,27134,27135,27136, +27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,27154,27155,27158,27166,27173,27174, +27180,27209,27210,27211,27212,27213,27215,27216,27217,27218,27219,27220,27221,27222,27223,27224,27226, +27228,27229,27230,27238,27250,27259,27260,27263,27264,27265,27266,27282,27283,27441,27448,28172,28176, +28189,28275,29704,29707,29722,30016,30022,30324,30330,30356,30357,30459,30545,30546,30908,30909,30910, +30911,30912,31661,31785,31935,32231,32379,32645,32684,32699,32700,32796,32996,33041,33042,33043,33072, +33405,33717,33776,33933,33938,33944,33946,34411,34412,34413,34861,34863,34864,34865,34866,34914,34916, +34917,36916,37420,38692,38697,38699,38704,38764,38768 +); + +INSERT INTO `spell_chain` VALUES +-- Druid +(26978,25297,5185,12), +(26979,26978,5185,13), +(26980,9858,8936,10), +(26981,25299,774,12), +(26982,26981,774,13), +(26983,9863,740,5), +(26984,9912,5176,9), +(26985,26984,5176,10), +(26986,25298,2912,8), +(26987,9835,8921,11), +(26988,26987,8921,12), +(26989,9853,339,7), +(26990,9885,1126,8), +(26992,9910,467,7), +(26993,9907,770,5), +(26994,20748,20484,6), +(26995,9901,2908,4), +(26996,9881,6807,8), +(26997,9908,779,6), +(26998,9898,99,6), +(26999,22896,22842,4), +(27001,9830,5221,6), +(27002,27001,5221,7), +(27003,9904,1822,5), +(27005,9867,6785,5), +(27006,9827,9005,4), +(27008,9896,1079,7), +(27009,17329,16689,7), +(27011,17392,16857,5), +(27012,17402,16914,4), +(27013,24977,5570,6), +-- Hunter +(27014,14266,2973,9), +(27015,14273,781,4), +(27016,25295,1978,10), +(27018,14280,3034,4), +(27019,14287,3044,9), +(27020,15632,20736,7), +(27021,25294,2643,6), +(27022,14295,1510,4), +(27023,14305,13795,6), +(27025,14317,13813,4), +(27044,25296,13165,8), +(27045,20190,20043,3), +(27046,13544,136,8), +(27065,20904,19434,7), +(27066,20906,19506,4), +(27067,20910,19306,4), +(27068,24133,19386,4), +(36916,14271,1495,5), +-- Mage +(27070,25306,133,13), +(27071,25304,116,12), +(27072,27071,116,13), +(27073,10207,2948,8), +(27074,27073,2948,9), +(27075,25345,5143,9), +(27078,10199,2136,8), +(27079,27078,2136,9), +(27080,10202,1449,7), +(27082,27080,1449,8), +(27085,10187,10,7), +(27086,10216,2120,7), +(27087,10161,120,6), +(27088,10230,122,5), +(27090,37420,5504,9), +(27124,10220,7302,5), +(27125,22783,6117,4), +(27126,10157,1459,6), +(27128,10225,543,6), +(27130,10170,1008,5), +(27131,10193,1463,7), +(27132,18809,11366,9), +(27133,13021,11113,6), +(27134,13033,11426,5), +(31661,0,31661,1), +(32796,28609,6143,6), +(33041,31661,31661,2), +(33042,33041,31661,3), +(33043,33042,31661,4), +(33405,27134,11426,6), +(33717,28612,587,8), +(33933,27133,11113,7), +(33938,27132,11366,10), +(33944,10174,604,6), +(33946,27130,1008,6), +(37420,10140,5504,8), +(38692,27070,133,14), +(38697,27072,116,14), +(38699,27075,5143,10), +(38704,38699,5143,11), +-- Paladin +(27135,25292,635,10), +(27136,27135,635,11), +(27137,19943,19750,7), +(27138,10314,879,7), +(27139,10318,2812,3), +(27140,25291,19740,8), +(27141,25916,25782,3), +(27142,25290,19742,7), +(27143,25918,25894,3), +(27144,19979,19977,4), +(27145,25890,25890,2), +(27147,20729,6940,3), +(27148,27147,6940,4), +(27154,10310,633,4), +(27155,20293,21084,9), +(27158,20308,21082,7), +(27166,20357,20166,4), +(27173,20924,26573,6), +(27174,20930,20473,4), +(27180,24239,24275,4), +(31785,0,31785,1), +(31935,0,31935,1), +(32699,31935,31935,2), +(32700,32699,31935,3), +(33072,27174,20473,5), +(33776,31785,31785,2), +-- Priest +(25210,25314,2060,6), +(25213,25210,2060,7), +(25217,10901,17,11), +(25218,25217,17,12), +(25221,25315,139,11), +(25222,25221,139,12), +(25233,10917,2061,8), +(25235,25233,2061,9), +(25308,25316,596,6), +(25312,27841,14752,5), +(25331,27801,15237,7), +(25363,10934,585,9), +(25364,25363,585,10), +(25367,10894,589,9), +(25368,25367,589,10), +(25372,10947,8092,10), +(25375,25372,8092,11), +(25379,10876,8129,6), +(25380,25379,8129,7), +(25384,15261,14914,9), +(25387,18807,15407,7), +(25389,10938,1243,7), +(25429,10942,586,7), +(25431,10952,588,7), +(25433,10958,976,4), +(25435,20770,2006,6), +(25437,19243,13908,8), +(25441,19275,13896,6), +(25446,19305,10797,8), +(25450,19293,2651,6), +(25467,19280,2944,7), +(25470,19285,9035,7), +(25596,10953,453,4), +(28275,27871,724,4), +(32379,0,32379,1), +(32996,32379,32379,2), +(34861,0,34861,1), +(34863,34861,34861,2), +(34864,34863,34861,3), +(34865,34864,34861,4), +(34866,34865,34861,5), +(34914,0,34914,1), +(34916,34914,34914,2), +(34917,34916,34914,3), +-- Rogue +(26839,11290,703,7), +(26861,11294,1752,9), +(26862,26861,1752,10), +(26863,25300,53,10), +(26864,17348,16511,4), +(26865,31016,2098,10), +(26866,11198,8647,6), +(26867,11275,1943,7), +(26884,26839,703,8), +(26889,1857,1856,3), +(26892,11343,8681,7), +(26969,25347,2835,6), +(27282,26969,2835,7), +(27283,13230,13220,5), +(27441,11269,8676,7), +(27448,25302,1966,6), +(32645,0,32645,1), +(32684,32645,32645,2), +(34411,1329,1329,2), +(34412,34411,1329,3), +(34413,34412,1329,4), +(38764,11286,1776,6), +(38768,1769,1766,5), +-- shaman +(25391,25357,331,11), +(25396,25391,331,12), +(25420,10468,8004,7), +(25422,10623,1064,4), +(25423,25422,1064,5), +(25439,10605,421,5), +(25442,25439,421,6), +(25448,15208,403,11), +(25449,25448,403,12), +(25454,10414,8042,8), +(25457,29228,8050,7), +(25464,10473,8056,5), +(25479,16316,8017,8), +(25485,25479,8017,9), +(25489,16342,8024,7), +(25500,16356,8033,6), +(25505,16362,8232,5), +(25508,10408,8071,7), +(25509,25508,8071,8), +(25525,10428,5730,7), +(25528,25361,8075,6), +(25533,10438,3599,7), +(25546,11315,1535,6), +(25547,25546,1535,7), +(25552,10587,8190,5), +(25557,16387,8227,5), +(25560,10479,8181,4), +(25563,10538,8184,4), +(25567,10463,5394,6), +(25570,10497,5675,5), +(25574,10601,10595,4), +(25577,15112,15107,4), +(25585,10614,8512,4), +(25587,25585,8512,5), +-- warlock +(27209,25307,686,11), +(27210,17923,5676,7), +(27211,17924,6353,3), +(27212,11678,5740,5), +(27213,11684,1949,4), +(27215,25309,348,9), +(27216,25311,172,8), +(27217,11675,1120,5), +(27218,11713,980,7), +(27219,11700,689,7), +(27220,27219,689,8), +(27221,11704,5138,5), +(27222,11689,1454,7), +(27223,17926,6789,4), +(27224,11708,702,7), +(27226,11717,704,5), +(27228,11722,1490,4), +(27229,17937,17862,3), +(27230,11730,6201,6), +(27238,20757,693,6), +(27250,17953,6366,5), +(27259,11695,755,8), +(27260,11735,706,6), +(27263,18871,17877,7), +(27264,18881,18265,5), +(27265,18938,18220,4), +(27266,18932,17962,5), +(28172,17728,2362,4), +(28176,0,28176,1), +(28189,28176,28176,2), +(29722,0,29722,1), +(30459,27210,5676,8), +(30545,27211,6353,4), +(30546,27263,17877,8), +(30908,27221,5138,6), +(30909,27224,702,8), +(30910,603,603,2), +(30911,27264,18265,6), +(30912,27266,17962,6), +(32231,29722,29722,2), +-- warrior +(25202,11556,1160,6), +(25203,25202,1160,7), +(25208,11574,772,8), +(25212,7373,1715,4), +(25225,11597,7386,6), +(25231,20569,845,6), +(25234,20662,5308,6), +(25236,25234,5308,7), +(25241,11605,1464,5), +(25242,25241,1464,6), +(25248,21553,12294,5), +(25258,23925,23922,5), +(25264,11581,6343,7), +(25266,20560,694,6), +(25269,25288,6572,7), +(25272,20617,20252,4), +(25275,25272,20252,5), +(29704,1672,72,4), +(29707,25286,78,10), +(30016,20243,20243,2), +(30022,30016,20243,3), +(30324,29707,78,11), +(30330,25248,12294,6), +(30356,25258,23922,6), +(30357,25269,6572,8); + diff --git a/sql/updates/0.8/4414_spell_proc_event.sql b/sql/updates/0.8/4414_spell_proc_event.sql new file mode 100644 index 000000000..3109b44c9 --- /dev/null +++ b/sql/updates/0.8/4414_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (25441,27009,27124,27280,31896); +INSERT INTO `spell_proc_event` VALUES +(25441,0,0,0,0,0,1048576,0), +(27009,0,0,0,0,0,2,0), +(27124,0,0,0,0,0,2,0), +(27280,0,0,0,0,0,2,0), +(31896,0,0,0,0,0,1,2); + diff --git a/sql/updates/0.8/4417_quest_template.sql b/sql/updates/0.8/4417_quest_template.sql new file mode 100644 index 000000000..88a6d0820 --- /dev/null +++ b/sql/updates/0.8/4417_quest_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE `quest_template` CHANGE `RequiredRepFaction` `RequiredMinRepFaction` int(10) unsigned NOT NULL default '0'; +ALTER TABLE `quest_template` CHANGE `RequiredRepValue` `RequiredMinRepValue` int(10) NOT NULL default '0'; +ALTER TABLE `quest_template` ADD `RequiredMaxRepFaction` int(10) unsigned NOT NULL default '0' AFTER `RequiredMinRepValue` ; +ALTER TABLE `quest_template` ADD `RequiredMaxRepValue` int(10) NOT NULL default '0' AFTER `RequiredMaxRepFaction` ; diff --git a/sql/updates/0.8/4420_spell_proc_event.sql b/sql/updates/0.8/4420_spell_proc_event.sql new file mode 100644 index 000000000..c1ce08ceb --- /dev/null +++ b/sql/updates/0.8/4420_spell_proc_event.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (35100,35102,35103); +INSERT INTO `spell_proc_event` VALUES +(35100,0,0,0,0,0,524288,0), +(35102,0,0,0,0,0,524288,0), +(35103,0,0,0,0,0,524288,0); + + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33511); +INSERT INTO `spell_proc_event` VALUES +(33511,0,0,0,0,0,131072,0); diff --git a/sql/updates/0.8/4422_command.sql b/sql/updates/0.8/4422_command.sql new file mode 100644 index 000000000..b2c71c17c --- /dev/null +++ b/sql/updates/0.8/4422_command.sql @@ -0,0 +1 @@ +INSERT INTO `command` (`name`, `security`, `help`) VALUES ('npcwhisper', '1', 'Syntax: .npcwhisper #playerguid #text\r\nMake the selected npc whisper #text to #playerguid.'); diff --git a/sql/updates/0.8/4425_character.sql b/sql/updates/0.8/4425_character.sql new file mode 100644 index 000000000..515ab151b --- /dev/null +++ b/sql/updates/0.8/4425_character.sql @@ -0,0 +1,7 @@ +ALTER TABLE `character` + ADD COLUMN `at_login` int(11) unsigned NOT NULL default '0' AFTER `rename`; + +UPDATE `character` SET `at_login` = 1 WHERE `rename` <> 0; + +ALTER TABLE `character` + DROP COLUMN `rename`; \ No newline at end of file diff --git a/sql/updates/0.8/4425_command.sql b/sql/updates/0.8/4425_command.sql new file mode 100644 index 000000000..b4f61ccdd --- /dev/null +++ b/sql/updates/0.8/4425_command.sql @@ -0,0 +1,10 @@ +delete from command where name in('goxyz','resetall','reset','reset honor','reset level','reset spells','reset stats','reset talents'); +INSERT INTO `command` VALUES +('goxyz',1,'Syntax: .goxyz #x #y #z [#mapid]\r\n\r\nTeleport player to point with (#x,#y,#z) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), +('resetall',3,'Syntax: .resetall spells\r\n\r\nSyntax: .resetall talents\r\n\r\nRequest reset spells or talents at next login each existed character.'), +('reset honor',3,'Syntax:\r\n.reset honor [Playername]\r\n Reset all honor data for targeted character.'), +('reset level',3,'Syntax:\r\n.reset level [Playername]\r\n Reset level to 1 including reset stats and talents. Equipped items with greater level requirement can be lost.'), +('reset spells',3,'Syntax:\r\n.reset spells [Playername]\r\n Removes all non-original spells from spellbook. Playername can be name of offline character.\r\n.'), +('reset stats',3,'Syntax:\r\n.reset stats [Playername]\r\n Resets(recalculate) all stats of the targeted player to their original values at current level.'), +('reset talents',3,'Syntax:\r\n.reset talents [Playername]\r\n Removes all talents of the targeted player. Playername can be name of offline character.'); + diff --git a/sql/updates/0.8/4426_creature_template.sql b/sql/updates/0.8/4426_creature_template.sql new file mode 100644 index 000000000..b50b5ef68 --- /dev/null +++ b/sql/updates/0.8/4426_creature_template.sql @@ -0,0 +1 @@ +ALTER TABLE `creature_template` ADD COLUMN dmgschool tinyint(1) not NULL default 0 after maxdmg; diff --git a/sql/updates/0.8/4430_spell_proc_event.sql b/sql/updates/0.8/4430_spell_proc_event.sql new file mode 100644 index 000000000..368feb1b7 --- /dev/null +++ b/sql/updates/0.8/4430_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (2565); +INSERT INTO `spell_proc_event` VALUES +(2565,0,0,0,0,0,64,0); + diff --git a/sql/updates/0.8/4432_item_template.sql b/sql/updates/0.8/4432_item_template.sql new file mode 100644 index 000000000..efb28784f --- /dev/null +++ b/sql/updates/0.8/4432_item_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE `item_template` + ADD COLUMN `spellppmRate_1` float NOT NULL default '0' AFTER `spellcharges_1`, + ADD COLUMN `spellppmRate_2` float NOT NULL default '0' AFTER `spellcharges_2`, + ADD COLUMN `spellppmRate_3` float NOT NULL default '0' AFTER `spellcharges_3`, + ADD COLUMN `spellppmRate_4` float NOT NULL default '0' AFTER `spellcharges_4`, + ADD COLUMN `spellppmRate_5` float NOT NULL default '0' AFTER `spellcharges_5`; diff --git a/sql/updates/0.8/4432_spell_chain.sql b/sql/updates/0.8/4432_spell_chain.sql new file mode 100644 index 000000000..25b7875a8 --- /dev/null +++ b/sql/updates/0.8/4432_spell_chain.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (29801,30030,30033); + +INSERT INTO `spell_chain` VALUES +(29801,0,29801,1), +(30030,29801,29801,2), +(30033,30030,29801,3); + diff --git a/sql/updates/0.8/4432_spell_proc_event.sql b/sql/updates/0.8/4432_spell_proc_event.sql new file mode 100644 index 000000000..d84e417cf --- /dev/null +++ b/sql/updates/0.8/4432_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (29801,30030,30033); +INSERT INTO `spell_proc_event` VALUES +(29801,0,0,0,0,0,0,0), +(30030,0,0,0,0,0,0,0), +(30033,0,0,0,0,0,0,0); diff --git a/sql/updates/0.8/4434_spell_proc_event.sql b/sql/updates/0.8/4434_spell_proc_event.sql new file mode 100644 index 000000000..7d6d1f25b --- /dev/null +++ b/sql/updates/0.8/4434_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (29801,30030,30033); +INSERT INTO `spell_proc_event` VALUES +(29801,0,0,0,0,0,1,0), +(30030,0,0,0,0,0,1,0), +(30033,0,0,0,0,0,1,0); diff --git a/sql/updates/0.8/4437_character_aura.sql b/sql/updates/0.8/4437_character_aura.sql new file mode 100644 index 000000000..65dabddc4 --- /dev/null +++ b/sql/updates/0.8/4437_character_aura.sql @@ -0,0 +1,6 @@ +ALTER TABLE `character_aura` + ADD `maxduration` int(11) NOT NULL default '0' AFTER `amount`, + ADD `remaincharges` int(11) NOT NULL default '0' AFTER `remaintime`; + +UPDATE `character_aura` + SET `maxduration` = `remaintime`, `remaincharges` = -1; \ No newline at end of file diff --git a/sql/updates/0.8/4437_pet_aura.sql b/sql/updates/0.8/4437_pet_aura.sql new file mode 100644 index 000000000..885adc902 --- /dev/null +++ b/sql/updates/0.8/4437_pet_aura.sql @@ -0,0 +1,6 @@ +ALTER TABLE `pet_aura` + ADD `maxduration` int(11) NOT NULL default '0' AFTER `amount`, + ADD `remaincharges` int(11) NOT NULL default '0' AFTER `remaintime`; + +UPDATE `pet_aura` + SET `maxduration` = `remaintime`, `remaincharges` = -1; diff --git a/sql/updates/0.8/4439_spell_proc_event.sql b/sql/updates/0.8/4439_spell_proc_event.sql new file mode 100644 index 000000000..00dde4fc8 --- /dev/null +++ b/sql/updates/0.8/4439_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (30293,30295,30296); +INSERT INTO `spell_proc_event` VALUES +(30293, 0, 0, 0, 5, 824633721729, 131072, 0), +(30295, 0, 0, 0, 5, 824633721729, 131072, 0), +(30296, 0, 0, 0, 5, 824633721729, 131072, 0); diff --git a/sql/updates/0.8/4446_creature_template.sql b/sql/updates/0.8/4446_creature_template.sql new file mode 100644 index 000000000..ac35882e7 --- /dev/null +++ b/sql/updates/0.8/4446_creature_template.sql @@ -0,0 +1 @@ +ALTER TABLE `creature_template` DROP COLUMN `size`; diff --git a/sql/updates/0.8/4464_instance.sql b/sql/updates/0.8/4464_instance.sql new file mode 100644 index 000000000..6d2add412 --- /dev/null +++ b/sql/updates/0.8/4464_instance.sql @@ -0,0 +1 @@ +ALTER TABLE `instance` ADD `data` LONGTEXT; \ No newline at end of file diff --git a/sql/updates/0.8/4464_instance_template.sql b/sql/updates/0.8/4464_instance_template.sql new file mode 100644 index 000000000..5b5f370b0 --- /dev/null +++ b/sql/updates/0.8/4464_instance_template.sql @@ -0,0 +1 @@ +ALTER TABLE `instance_template` ADD `script` varchar(255) NOT NULL default ''; \ No newline at end of file diff --git a/sql/updates/0.8/4470_command.sql b/sql/updates/0.8/4470_command.sql new file mode 100644 index 000000000..bbd104b73 --- /dev/null +++ b/sql/updates/0.8/4470_command.sql @@ -0,0 +1,4 @@ +delete from command where name in('movegens'); +INSERT INTO `command` VALUES +('movegens',3,'Syntax: .movegens\r\n Show movement generators stack for selected creature or player.'); + diff --git a/sql/updates/0.8/4480_spell_affect.sql b/sql/updates/0.8/4480_spell_affect.sql new file mode 100644 index 000000000..74fec20b9 --- /dev/null +++ b/sql/updates/0.8/4480_spell_affect.sql @@ -0,0 +1,9 @@ +-- Improved Fire Totems 1-2 Rangs +DELETE FROM `spell_affect` WHERE `entry` IN (16544,16086); +INSERT INTO `spell_affect` VALUES +(16544,0,0,0,0,0,0,32,0), +(16544,1,0,0,0,0,0,32,0), +(16544,2,0,0,0,0,0,1073741824,0), +(16086,0,0,0,0,0,0,32,0), +(16086,1,0,0,0,0,0,32,0), +(16086,2,0,0,0,0,0,1073741824,0); diff --git a/sql/updates/0.8/4481_spell_affect.sql b/sql/updates/0.8/4481_spell_affect.sql new file mode 100644 index 000000000..cd1535c8e --- /dev/null +++ b/sql/updates/0.8/4481_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (16544,16086) AND `effectId`=2; +INSERT INTO `spell_affect` VALUES +(16544,2,0,0,0,0,0,4,0), +(16086,2,0,0,0,0,0,4,0); diff --git a/sql/updates/0.8/4482_playercreateinfo.sql b/sql/updates/0.8/4482_playercreateinfo.sql new file mode 100644 index 000000000..bd7c02fb5 --- /dev/null +++ b/sql/updates/0.8/4482_playercreateinfo.sql @@ -0,0 +1,11 @@ +UPDATE playercreateinfo_spell SET Spell = '21084' WHERE Spell = '20154'; +UPDATE playercreateinfo_action SET action = '21084' WHERE action = '20154'; +DELETE FROM `character_spell` WHERE spell='20154'; + +-- re-add all default spells if not have with from spell list +INSERT IGNORE INTO `character_spell` +SELECT `character`.`guid`,`playercreateinfo_spell`.`spell` AS `spell`, '65535' AS `slot`,`playercreateinfo_spell`.`Active` AS `active` +FROM `character`,`playercreateinfo_spell` +WHERE `character`.`class`=`playercreateinfo_spell`.`class` AND `character`.`race`=`playercreateinfo_spell`.`race`; + +UPDATE character_action SET action = '21084' WHERE action = '20154' AND `type` = 0; diff --git a/sql/updates/0.8/4482_spell_proc_event.sql b/sql/updates/0.8/4482_spell_proc_event.sql new file mode 100644 index 000000000..bf1371d15 --- /dev/null +++ b/sql/updates/0.8/4482_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (12284,12701,12702,12703,12704); +INSERT INTO `spell_proc_event` VALUES +(12284,0,0,0,0,0,1,0.33252), +(12701,0,0,0,0,0,1,0.66504), +(12702,0,0,0,0,0,1,0.99756), +(12703,0,0,0,0,0,1,1.33008), +(12704,0,0,0,0,0,1,1.66260); diff --git a/sql/updates/0.8/4488_db_version.sql b/sql/updates/0.8/4488_db_version.sql new file mode 100644 index 000000000..704942e97 --- /dev/null +++ b/sql/updates/0.8/4488_db_version.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS `db_version`; +CREATE TABLE `db_version` ( + `version` varchar(120) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; + +INSERT INTO `db_version` VALUES ( 'unknown world database.' ); diff --git a/sql/updates/0.8/4491_spell_affect.sql b/sql/updates/0.8/4491_spell_affect.sql new file mode 100644 index 000000000..a6d530930 --- /dev/null +++ b/sql/updates/0.8/4491_spell_affect.sql @@ -0,0 +1,9 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (28176, 28189); +INSERT INTO `spell_affect` VALUES +(28176,1,0,0,0,0,0,4295491592,0), +(28189,1,0,0,0,0,0,4295491592,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11252, 12605); +INSERT INTO `spell_affect` VALUES +(11252,0,0,0,0,0,0,32768,0), +(12605,0,0,0,0,0,0,32768,0); diff --git a/sql/updates/0.8/4496_spell_script_target.sql b/sql/updates/0.8/4496_spell_script_target.sql new file mode 100644 index 000000000..a759ac011 --- /dev/null +++ b/sql/updates/0.8/4496_spell_script_target.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS `spell_script_target`; +CREATE TABLE `spell_script_target` ( + `entry` int(6) unsigned NOT NULL, + `type` int(8) unsigned default '0', + `targetEntry` int(11) default '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Spell System'; diff --git a/sql/updates/0.8/4498_spell_proc_event.sql b/sql/updates/0.8/4498_spell_proc_event.sql new file mode 100644 index 000000000..fa3fbada1 --- /dev/null +++ b/sql/updates/0.8/4498_spell_proc_event.sql @@ -0,0 +1,8 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (40971); +INSERT INTO `spell_proc_event` VALUES +(40971,0,0,0,0,0,134217728,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (38427,40407); +INSERT INTO `spell_proc_event` VALUES +(38427,0,0,0,0,0,1,0), +(40407,0,0,0,0,0,1026,6); \ No newline at end of file diff --git a/sql/updates/0.8/4499_spell_script_target.sql b/sql/updates/0.8/4499_spell_script_target.sql new file mode 100644 index 000000000..35926d83d --- /dev/null +++ b/sql/updates/0.8/4499_spell_script_target.sql @@ -0,0 +1,3 @@ +ALTER TABLE `spell_script_target` + CHANGE COLUMN `targetEntry` `targetEntry` int(11) unsigned default '0', + ADD UNIQUE KEY `entry_type_target` (`entry`,`type`,`targetEntry`); diff --git a/sql/updates/0.8/4501.sql b/sql/updates/0.8/4501.sql new file mode 100644 index 000000000..e8e9cc733 --- /dev/null +++ b/sql/updates/0.8/4501.sql @@ -0,0 +1,112 @@ +-- Add definitly a very usefull index to this creature table +-- If this sql file fails because the index already exists, comment the following line +ALTER TABLE `creature` ADD INDEX `index_id` (id); + +-- Add suport to creature table for equipment and model overwritting +ALTER TABLE `creature` + ADD COLUMN `equipment_id` int(11) NOT NULL default '0' AFTER `map`, + ADD COLUMN `modelid` int(11) unsigned default '0' AFTER `map`; + +-- Creation of creature_model_info table +DROP TABLE IF EXISTS `creature_model_info`; +CREATE TABLE `creature_model_info` ( + `modelid` int(11) unsigned NOT NULL default '0', + `bounding_radius` float NOT NULL default '0', + `combat_reach` float NOT NULL default '0', + `gender` tinyint(2) unsigned NOT NULL default '2', + `modelid_other_gender` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`modelid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Creature System (Model related info)'; + +-- Correct possible db problems +UPDATE `creature_template` SET `bounding_radius`=0 WHERE `bounding_radius` IS NULL; +UPDATE `creature_template` SET `combat_reach`=0 WHERE `combat_reach` IS NULL; +UPDATE `creature_template` SET `modelid_m`=0 WHERE `modelid_m` IS NULL; +UPDATE `creature_template` SET `modelid_f`=0 WHERE `modelid_f` IS NULL; + +-- All models defined in creature_template are used to build the table +INSERT IGNORE INTO `creature_model_info` (`modelid`) SELECT DISTINCT `modelid_m` FROM `creature_template`; +INSERT IGNORE INTO `creature_model_info` (`modelid`) SELECT DISTINCT `modelid_f` FROM `creature_template`; + +-- Copy the data from creature_template to creature_model_info +UPDATE `creature_model_info`,`creature_template` SET + `creature_model_info`.`bounding_radius`=`creature_template`.`bounding_radius`, + `creature_model_info`.`combat_reach`=`creature_template`.`combat_reach`, + `creature_model_info`.`modelid_other_gender`=`creature_template`.`modelid_f` + WHERE `creature_model_info`.`modelid`=`creature_template`.`modelid_m`; + +UPDATE `creature_model_info`,`creature_template` SET + `creature_model_info`.`bounding_radius`=`creature_template`.`bounding_radius`, + `creature_model_info`.`combat_reach`=`creature_template`.`combat_reach`, + `creature_model_info`.`modelid_other_gender`=`creature_template`.`modelid_m` + WHERE `creature_model_info`.`modelid`=`creature_template`.`modelid_f`; + +-- Some changes in fields of creature_template +ALTER TABLE `creature_template` + CHANGE `modelid_m` `modelid_A` int(11) unsigned NOT NULL default '0', + CHANGE `modelid_f` `modelid_H` int(11) unsigned NOT NULL default '0', + ADD COLUMN `faction_H` int(4) unsigned NOT NULL default '0' AFTER `faction`, + ADD COLUMN `equipment_id` int(11) unsigned NOT NULL default '0' AFTER `RacialLeader`, + ADD COLUMN `RegenHealth` tinyint(1) unsigned NOT NULL default '1' AFTER `RacialLeader`, + DROP COLUMN `bounding_radius`, + DROP COLUMN `combat_reach`, + -- This index is temporary and enable the population of creature_equip_template to be fast + ADD INDEX `idx_tmp` (`equipmodel1`,`equipmodel2`,`equipmodel3`,`equipinfo1`,`equipinfo2`,`equipinfo3`,`equipslot1`,`equipslot2`,`equipslot3`); + +ALTER TABLE `creature_template` + CHANGE `faction` `faction_A` int(4) unsigned NOT NULL default '0'; + +-- Create table creature_equip_template with temporary auto-increment key +DROP TABLE IF EXISTS `creature_equip_template`; +CREATE TABLE `creature_equip_template` ( + `entry` int(11) unsigned NOT NULL auto_increment COMMENT 'Unique entry', + `equipmodel1` int(11) unsigned NOT NULL default '0', + `equipmodel2` int(11) unsigned NOT NULL default '0', + `equipmodel3` int(11) unsigned NOT NULL default '0', + `equipinfo1` int(11) unsigned NOT NULL default '0', + `equipinfo2` int(11) unsigned NOT NULL default '0', + `equipinfo3` int(11) unsigned NOT NULL default '0', + `equipslot1` int(11) NOT NULL default '0', + `equipslot2` int(11) NOT NULL default '0', + `equipslot3` int(11) NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Creature System (Equipment)'; + +-- Fill the creature_equip_template table with values from creature_template +INSERT INTO `creature_equip_template` (`equipmodel1`,`equipmodel2`,`equipmodel3`,`equipinfo1`,`equipinfo2`,`equipinfo3`,`equipslot1`,`equipslot2`,`equipslot3`) + (SELECT DISTINCT `equipmodel1`,`equipmodel2`,`equipmodel3`,`equipinfo1`,`equipinfo2`,`equipinfo3`,`equipslot1`,`equipslot2`,`equipslot3` FROM `creature_template` WHERE `equipmodel1`<>0 OR `equipmodel2`<>0 OR `equipmodel3`<>0); + +-- Then add to creature_template the id generated for equipements +UPDATE `creature_template`,`creature_equip_template` SET + `creature_template`.`equipment_id`=`creature_equip_template`.`entry` + WHERE `creature_template`.`equipmodel1`=`creature_equip_template`.`equipmodel1` AND + `creature_template`.`equipmodel2`=`creature_equip_template`.`equipmodel2` AND + `creature_template`.`equipmodel3`=`creature_equip_template`.`equipmodel3` AND + `creature_template`.`equipinfo1`=`creature_equip_template`.`equipinfo1` AND + `creature_template`.`equipinfo2`=`creature_equip_template`.`equipinfo2` AND + `creature_template`.`equipinfo3`=`creature_equip_template`.`equipinfo3` AND + `creature_template`.`equipslot1`=`creature_equip_template`.`equipslot1` AND + `creature_template`.`equipslot2`=`creature_equip_template`.`equipslot2` AND + `creature_template`.`equipslot3`=`creature_equip_template`.`equipslot3`; + +-- Remove all equipment fields from creature_template, this will remove the temporary index +ALTER TABLE `creature_template` + DROP COLUMN `equipmodel1`, + DROP COLUMN `equipmodel2`, + DROP COLUMN `equipmodel3`, + DROP COLUMN `equipinfo1`, + DROP COLUMN `equipinfo2`, + DROP COLUMN `equipinfo3`, + DROP COLUMN `equipslot1`, + DROP COLUMN `equipslot2`, + DROP COLUMN `equipslot3`; + +-- Make all modelid and faction fields filled +UPDATE `creature_template` SET `modelid_A`=`modelid_H` WHERE `modelid_A`=0 AND `modelid_H`<>0; +UPDATE `creature_template` SET `modelid_H`=`modelid_A` WHERE `modelid_H`=0 AND `modelid_A`<>0; +UPDATE `creature_template` SET `faction_A`=`faction_H` WHERE `faction_A`=0 AND `faction_H`<>0; +UPDATE `creature_template` SET `faction_H`=`faction_A` WHERE `faction_H`=0 AND `faction_A`<>0; + +-- Finaly remove the no more necessary auto-increment from creature_equip_template +ALTER TABLE `creature_equip_template` + CHANGE `entry` `entry` int(11) unsigned NOT NULL default '0' COMMENT 'Unique entry'; diff --git a/sql/updates/0.8/4503_spell_chain.sql b/sql/updates/0.8/4503_spell_chain.sql new file mode 100644 index 000000000..8dd5cb491 --- /dev/null +++ b/sql/updates/0.8/4503_spell_chain.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (31895); + +INSERT INTO `spell_chain` VALUES +(31895,20164,20164,2); diff --git a/sql/updates/0.8/4503_spell_proc_event.sql b/sql/updates/0.8/4503_spell_proc_event.sql new file mode 100644 index 000000000..bdd37b945 --- /dev/null +++ b/sql/updates/0.8/4503_spell_proc_event.sql @@ -0,0 +1,49 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (5728,6397,6398,6399,10425,10426,25513); +INSERT INTO `spell_proc_event` VALUES +(5728,0,0,0,0,0,1049602,0), +(6397,0,0,0,0,0,1049602,0), +(6398,0,0,0,0,0,1049602,0), +(6399,0,0,0,0,0,1049602,0), +(10425,0,0,0,0,0,1049602,0), +(10426,0,0,0,0,0,1049602,0), +(25513,0,0,0,0,0,1049602,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (31895); +INSERT INTO `spell_proc_event` VALUES +(31895,0,0,0,0,0,1,2); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37705); +INSERT INTO `spell_proc_event` VALUES +(37705,0,0,0,0,0,134217728,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (37247); +INSERT INTO `spell_proc_event` VALUES +(37247,8,0,0,0,0,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (40444); +INSERT INTO `spell_proc_event` VALUES +(40444,0,0,0,0,0,64,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (40482); +INSERT INTO `spell_proc_event` VALUES +(40482,0,0,0,0,0,65536,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33297); +INSERT INTO `spell_proc_event` VALUES +(33297,0,0,0,0,0,131072,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33953); +INSERT INTO `spell_proc_event` VALUES +(33953,0,0,0,0,0,134217728,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (38350); +INSERT INTO `spell_proc_event` VALUES +(38350,0,0,0,0,0,4198400,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (33510); +INSERT INTO `spell_proc_event` VALUES +(33510,0,0,0,0,0,524289,5); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (32215); +INSERT INTO `spell_proc_event` VALUES +(32215,0,0,0,0,0,4,0); diff --git a/sql/updates/0.8/4504_spell_affect.sql b/sql/updates/0.8/4504_spell_affect.sql new file mode 100644 index 000000000..a9eeb98c8 --- /dev/null +++ b/sql/updates/0.8/4504_spell_affect.sql @@ -0,0 +1,24 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (20216) AND `effectId`=0; +INSERT INTO `spell_affect` VALUES +(20216,0,0,0,0,0,0,3223322624,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31842) AND `effectId`=0; +INSERT INTO `spell_affect` VALUES +(31842,0,0,126,0,0,0,0,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31834) AND `effectId`=0; +INSERT INTO `spell_affect` VALUES +(31834,0,0,0,0,0,0,2147483648,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20224,20225,20330,20331,20332) AND `effectId`=0; +INSERT INTO `spell_affect` VALUES +(20224,0,0,0,0,0,0,134218752,0), +(20225,0,0,0,0,0,0,134218752,0), +(20330,0,0,0,0,0,0,134218752,0), +(20331,0,0,0,0,0,0,134218752,0), +(20332,0,0,0,0,0,0,134218752,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (20244,20245) AND `effectId`=0; +INSERT INTO `spell_affect` VALUES +(20244,0,0,0,0,0,0,65536,0), +(20245,0,0,0,0,0,0,65536,0); diff --git a/sql/updates/0.8/4504_spell_proc_event.sql b/sql/updates/0.8/4504_spell_proc_event.sql new file mode 100644 index 000000000..d329b5b5c --- /dev/null +++ b/sql/updates/0.8/4504_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (31801); +INSERT INTO `spell_proc_event` VALUES +(31801,0,0,0,0,0,1,20); diff --git a/sql/updates/0.8/4506_spell_learn_spell.sql b/sql/updates/0.8/4506_spell_learn_spell.sql new file mode 100644 index 000000000..96c0c7226 --- /dev/null +++ b/sql/updates/0.8/4506_spell_learn_spell.sql @@ -0,0 +1,6 @@ +INSERT IGNORE INTO `spell_learn_spell` VALUES +(71,355,0), +(71,7386,0), +(264,3018,0), +(266,3018,0), +(5011,3018,0); diff --git a/sql/updates/0.8/4507_quest_template.sql b/sql/updates/0.8/4507_quest_template.sql new file mode 100644 index 000000000..2a39ae65b --- /dev/null +++ b/sql/updates/0.8/4507_quest_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `quest_template` + CHANGE `ExclusiveGroup` `ExclusiveGroup` int(11) NOT NULL default '0'; diff --git a/sql/updates/0.8/4510_spell_proc_event.sql b/sql/updates/0.8/4510_spell_proc_event.sql new file mode 100644 index 000000000..5d676b9b1 --- /dev/null +++ b/sql/updates/0.8/4510_spell_proc_event.sql @@ -0,0 +1,13 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (32837); +INSERT INTO `spell_proc_event` VALUES +(32837,0,0,0,0,0,16384,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (588,7128,602,1006,10951,10952,25431); +INSERT INTO `spell_proc_event` VALUES +(588,0,0,0,0,0,1026,0), +(602,0,0,0,0,0,1026,0), +(1006,0,0,0,0,0,1026,0), +(7128,0,0,0,0,0,1026,0), +(10951,0,0,0,0,0,1026,0), +(10952,0,0,0,0,0,1026,0), +(25431,0,0,0,0,0,1026,0); diff --git a/sql/updates/0.8/4513_spell_proc_event.sql b/sql/updates/0.8/4513_spell_proc_event.sql new file mode 100644 index 000000000..2e3569ce8 --- /dev/null +++ b/sql/updates/0.8/4513_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (30482); +INSERT INTO `spell_proc_event` VALUES +(30482,0,0,0,0,0,2,0); \ No newline at end of file diff --git a/sql/updates/0.8/4517_spell_affect.sql b/sql/updates/0.8/4517_spell_affect.sql new file mode 100644 index 000000000..4f4ea253c --- /dev/null +++ b/sql/updates/0.8/4517_spell_affect.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (41021,41026); +INSERT INTO `spell_affect` VALUES +(41021,0,0,0,0,0,0,274877906944,0), +(41021,1,0,0,0,0,0,274877906944,0), +(41026,0,0,0,0,0,0,274877906944,0), +(41026,1,0,0,0,0,0,274877906944,0); diff --git a/sql/updates/0.8/4524_spell_proc_event.sql b/sql/updates/0.8/4524_spell_proc_event.sql new file mode 100644 index 000000000..013a117d1 --- /dev/null +++ b/sql/updates/0.8/4524_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (32642); +INSERT INTO `spell_proc_event` VALUES +(32642,0,0,0,0,0,64,0); diff --git a/sql/updates/0.8/4537_player_levelstats.sql b/sql/updates/0.8/4537_player_levelstats.sql new file mode 100644 index 000000000..cf5030dd5 --- /dev/null +++ b/sql/updates/0.8/4537_player_levelstats.sql @@ -0,0 +1,3668 @@ +-- +-- Table structure for table `player_levelstats` +-- + +DROP TABLE IF EXISTS `player_levelstats`; +CREATE TABLE `player_levelstats` ( + `race` tinyint(3) unsigned NOT NULL, + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `hp` smallint(5) unsigned NOT NULL, + `mana` smallint(5) unsigned NOT NULL, + `str` tinyint(3) unsigned NOT NULL, + `agi` tinyint(3) unsigned NOT NULL, + `sta` tinyint(3) unsigned NOT NULL, + `int` tinyint(3) unsigned NOT NULL, + `spi` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`race`,`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +-- +-- Dumping data for table `player_levelstats` +-- + +LOCK TABLES `player_levelstats` WRITE; +/*!40000 ALTER TABLE `player_levelstats` DISABLE KEYS */; +INSERT INTO `player_levelstats` VALUES +(1,1,1,60,0,23,20,22,20,20), +(1,1,2,79,0,24,21,23,20,20), +(1,1,3,98,0,26,22,24,20,21), +(1,1,4,117,0,27,22,26,20,21), +(1,1,5,136,0,28,23,27,20,21), +(1,1,6,155,0,30,24,28,20,21), +(1,1,7,174,0,31,25,29,21,22), +(1,1,8,193,0,32,26,30,21,22), +(1,1,9,212,0,34,26,32,21,22), +(1,1,10,231,0,35,27,33,21,23), +(1,1,11,250,0,36,28,34,21,23), +(1,1,12,269,0,38,29,35,21,23), +(1,1,13,288,0,39,30,37,21,24), +(1,1,14,308,0,41,31,38,21,24), +(1,1,15,329,0,42,32,39,21,24), +(1,1,16,351,0,44,33,41,21,25), +(1,1,17,374,0,45,34,42,22,25), +(1,1,18,398,0,47,34,43,22,25), +(1,1,19,423,0,48,35,45,22,26), +(1,1,20,449,0,50,36,46,22,26), +(1,1,21,476,0,51,37,48,22,26), +(1,1,22,504,0,53,38,49,22,27), +(1,1,23,533,0,54,39,51,22,27), +(1,1,24,563,0,56,40,52,23,28), +(1,1,25,594,0,58,41,53,23,28), +(1,1,26,626,0,59,42,55,23,28), +(1,1,27,659,0,61,43,56,23,29), +(1,1,28,693,0,63,44,58,23,29), +(1,1,29,728,0,64,45,59,23,30), +(1,1,30,764,0,66,46,61,24,30), +(1,1,31,801,0,68,47,62,24,30), +(1,1,32,839,0,69,48,64,24,31), +(1,1,33,878,0,71,50,66,24,31), +(1,1,34,918,0,73,51,67,24,32), +(1,1,35,959,0,74,52,69,24,32), +(1,1,36,1001,0,76,53,70,25,33), +(1,1,37,1045,0,78,54,72,25,33), +(1,1,38,1091,0,80,55,74,25,34), +(1,1,39,1139,0,82,56,75,25,34), +(1,1,40,1189,0,83,57,77,25,35), +(1,1,41,1241,0,85,58,79,26,35), +(1,1,42,1295,0,87,60,80,26,35), +(1,1,43,1351,0,89,61,82,26,36), +(1,1,44,1409,0,91,62,84,26,36), +(1,1,45,1469,0,93,63,85,26,37), +(1,1,46,1531,0,95,64,87,27,37), +(1,1,47,1595,0,97,66,89,27,38), +(1,1,48,1661,0,99,67,91,27,38), +(1,1,49,1729,0,101,68,93,27,39), +(1,1,50,1799,0,103,69,94,28,40), +(1,1,51,1871,0,105,71,96,28,40), +(1,1,52,1945,0,107,72,98,28,41), +(1,1,53,2021,0,109,73,100,28,41), +(1,1,54,2099,0,111,74,102,29,42), +(1,1,55,2179,0,113,76,103,29,42), +(1,1,56,2261,0,115,77,105,29,43), +(1,1,57,2345,0,117,78,107,29,43), +(1,1,58,2431,0,119,79,109,30,44), +(1,1,59,2519,0,121,81,111,30,44), +(1,1,60,2609,0,123,82,113,30,45), +(1,1,61,2842,0,125,83,115,30,46), +(1,1,62,3089,0,127,85,117,31,46), +(1,1,63,3350,0,129,86,119,31,47), +(1,1,64,3625,0,132,88,121,31,47), +(1,1,65,3915,0,134,89,123,32,48), +(1,1,66,4220,0,136,90,125,32,49), +(1,1,67,4540,0,138,92,127,32,49), +(1,1,68,4876,0,140,93,129,32,50), +(1,1,69,5228,0,143,95,131,33,50), +(1,1,70,5596,0,145,96,133,33,51), +(1,2,1,58,80,22,20,22,20,21), +(1,2,2,76,99,23,21,23,21,22), +(1,2,3,94,119,24,21,24,21,22), +(1,2,4,112,140,25,22,25,22,23), +(1,2,5,130,162,26,22,26,23,24), +(1,2,6,148,185,28,23,27,23,25), +(1,2,7,166,209,29,24,28,24,25), +(1,2,8,184,234,30,24,29,25,26), +(1,2,9,202,260,31,25,30,25,27), +(1,2,10,220,287,32,25,32,26,27), +(1,2,11,238,315,33,26,33,27,28), +(1,2,12,256,344,35,27,34,27,29), +(1,2,13,274,374,36,27,35,28,30), +(1,2,14,292,405,37,28,36,29,31), +(1,2,15,311,437,38,29,37,30,31), +(1,2,16,331,470,40,29,38,30,32), +(1,2,17,352,504,41,30,40,31,33), +(1,2,18,374,539,42,31,41,32,34), +(1,2,19,397,575,43,31,42,33,35), +(1,2,20,421,612,45,32,43,33,35), +(1,2,21,446,650,46,33,45,34,36), +(1,2,22,472,689,47,33,46,35,37), +(1,2,23,499,729,49,34,47,36,38), +(1,2,24,527,770,50,35,48,37,39), +(1,2,25,556,812,51,36,50,37,40), +(1,2,26,586,854,53,36,51,38,41), +(1,2,27,617,896,54,37,52,39,42), +(1,2,28,649,938,56,38,54,40,43), +(1,2,29,682,980,57,39,55,41,43), +(1,2,30,716,1022,58,39,56,42,44), +(1,2,31,751,1064,60,40,58,43,45), +(1,2,32,787,1106,61,41,59,43,46), +(1,2,33,824,1148,63,42,60,44,47), +(1,2,34,862,1190,64,43,62,45,48), +(1,2,35,901,1232,66,44,63,46,49), +(1,2,36,941,1274,67,44,65,47,50), +(1,2,37,982,1316,69,45,66,48,51), +(1,2,38,1024,1358,70,46,67,49,52), +(1,2,39,1067,1400,72,47,69,50,53), +(1,2,40,1111,1442,73,48,70,51,54), +(1,2,41,1156,1484,75,49,72,52,55), +(1,2,42,1202,1526,77,49,73,53,56), +(1,2,43,1249,1568,78,50,75,54,57), +(1,2,44,1297,1610,80,51,76,55,58), +(1,2,45,1346,1652,81,52,78,56,59), +(1,2,46,1396,1694,83,53,79,57,61), +(1,2,47,1447,1736,85,54,81,58,62), +(1,2,48,1499,1778,86,55,83,59,63), +(1,2,49,1552,1820,88,56,84,60,64), +(1,2,50,1606,1862,90,57,86,61,65), +(1,2,51,1661,1904,91,58,87,62,66), +(1,2,52,1717,1946,93,59,89,63,67), +(1,2,53,1774,1988,95,60,91,64,68), +(1,2,54,1832,2030,97,61,92,65,69), +(1,2,55,1891,2072,98,61,94,66,71), +(1,2,56,1951,2114,100,62,95,67,72), +(1,2,57,2012,2156,102,63,97,68,73), +(1,2,58,2074,2198,104,64,99,69,74), +(1,2,59,2137,2240,105,65,101,70,75), +(1,2,60,2201,2282,107,66,102,71,77), +(1,2,61,2381,2441,109,67,104,73,78), +(1,2,62,2569,2600,111,69,106,74,79), +(1,2,63,2765,2774,113,70,107,75,80), +(1,2,64,2970,2933,115,71,109,76,81), +(1,2,65,3184,3092,116,72,111,77,83), +(1,2,66,3407,3266,118,73,113,78,84), +(1,2,67,3640,3425,120,74,115,79,85), +(1,2,68,3883,3584,122,75,116,81,86), +(1,2,69,4136,3758,124,76,118,82,88), +(1,2,70,4399,3917,126,77,120,83,89), +(1,4,1,55,0,21,23,21,20,20), +(1,4,2,72,0,22,24,22,20,20), +(1,4,3,89,0,23,26,22,20,21), +(1,4,4,106,0,23,27,23,20,21), +(1,4,5,123,0,24,29,24,21,21), +(1,4,6,140,0,25,30,25,21,22), +(1,4,7,157,0,26,32,25,21,22), +(1,4,8,174,0,26,33,26,21,23), +(1,4,9,191,0,27,35,27,21,23), +(1,4,10,208,0,28,36,27,21,23), +(1,4,11,225,0,29,38,28,22,24), +(1,4,12,242,0,30,39,29,22,24), +(1,4,13,259,0,31,41,30,22,25), +(1,4,14,276,0,31,43,31,22,25), +(1,4,15,293,0,32,44,31,22,25), +(1,4,16,311,0,33,46,32,23,26), +(1,4,17,330,0,34,48,33,23,26), +(1,4,18,350,0,35,49,34,23,27), +(1,4,19,371,0,36,51,35,23,27), +(1,4,20,393,0,37,53,35,23,28), +(1,4,21,416,0,38,54,36,24,28), +(1,4,22,440,0,39,56,37,24,29), +(1,4,23,465,0,40,58,38,24,29), +(1,4,24,491,0,41,60,39,24,30), +(1,4,25,518,0,42,61,40,25,30), +(1,4,26,546,0,43,63,41,25,31), +(1,4,27,575,0,44,65,42,25,31), +(1,4,28,605,0,45,67,43,25,32), +(1,4,29,636,0,46,69,43,25,32), +(1,4,30,668,0,47,71,44,26,33), +(1,4,31,701,0,48,72,45,26,33), +(1,4,32,735,0,49,74,46,26,34), +(1,4,33,770,0,50,76,47,27,34), +(1,4,34,806,0,51,78,48,27,35), +(1,4,35,843,0,52,80,49,27,35), +(1,4,36,881,0,53,82,50,27,36), +(1,4,37,920,0,54,84,51,28,36), +(1,4,38,960,0,55,86,52,28,37), +(1,4,39,1001,0,56,88,53,28,38), +(1,4,40,1043,0,57,90,54,28,38), +(1,4,41,1086,0,58,92,55,29,39), +(1,4,42,1130,0,60,94,56,29,39), +(1,4,43,1175,0,61,96,57,29,40), +(1,4,44,1221,0,62,98,58,30,40), +(1,4,45,1268,0,63,100,59,30,41), +(1,4,46,1316,0,64,103,61,30,42), +(1,4,47,1365,0,65,105,62,31,42), +(1,4,48,1415,0,66,107,63,31,43), +(1,4,49,1466,0,68,109,64,31,44), +(1,4,50,1518,0,69,111,65,32,44), +(1,4,51,1571,0,70,113,66,32,45), +(1,4,52,1625,0,71,116,67,32,45), +(1,4,53,1680,0,73,118,68,33,46), +(1,4,54,1736,0,74,120,69,33,47), +(1,4,55,1793,0,75,122,71,33,47), +(1,4,56,1851,0,76,125,72,34,48), +(1,4,57,1910,0,78,127,73,34,49), +(1,4,58,1970,0,79,129,74,34,49), +(1,4,59,2031,0,80,131,75,35,50), +(1,4,60,2093,0,81,134,77,35,51), +(1,4,61,2282,0,83,136,78,35,51), +(1,4,62,2480,0,84,138,79,36,52), +(1,4,63,2687,0,85,141,80,36,53), +(1,4,64,2903,0,87,143,81,37,54), +(1,4,65,3129,0,88,146,83,37,54), +(1,4,66,3365,0,89,148,84,37,55), +(1,4,67,3611,0,91,151,85,38,56), +(1,4,68,3868,0,92,153,86,38,57), +(1,4,69,4136,0,94,156,88,39,57), +(1,4,70,4415,0,95,158,89,39,58), +(1,5,1,52,160,20,20,20,22,23), +(1,5,2,67,184,20,20,20,23,24), +(1,5,3,82,209,20,20,21,25,26), +(1,5,4,97,235,20,21,21,26,27), +(1,5,5,112,262,21,21,21,27,28), +(1,5,6,127,290,21,21,22,29,30), +(1,5,7,142,319,21,21,22,30,31), +(1,5,8,157,349,21,22,23,31,33), +(1,5,9,172,380,21,22,23,33,34), +(1,5,10,187,412,21,22,23,34,36), +(1,5,11,202,445,22,22,24,36,37), +(1,5,12,217,479,22,23,24,37,39), +(1,5,13,232,514,22,23,25,38,40), +(1,5,14,247,550,22,23,25,40,42), +(1,5,15,262,587,22,23,25,41,43), +(1,5,16,277,625,23,24,26,43,45), +(1,5,17,292,664,23,24,26,44,46), +(1,5,18,307,704,23,24,27,46,48), +(1,5,19,322,745,23,24,27,47,49), +(1,5,20,337,787,23,25,28,49,51), +(1,5,21,352,830,24,25,28,51,53), +(1,5,22,368,874,24,25,29,52,54), +(1,5,23,385,919,24,26,29,54,56), +(1,5,24,403,965,24,26,30,55,58), +(1,5,25,422,1012,25,26,30,57,59), +(1,5,26,442,1060,25,27,31,59,61), +(1,5,27,463,1109,25,27,31,60,63), +(1,5,28,485,1159,25,27,32,62,65), +(1,5,29,508,1210,25,28,32,64,66), +(1,5,30,532,1262,26,28,33,65,68), +(1,5,31,557,1315,26,28,33,67,70), +(1,5,32,583,1369,26,29,34,69,72), +(1,5,33,610,1423,27,29,34,70,73), +(1,5,34,638,1477,27,29,35,72,75), +(1,5,35,667,1531,27,30,35,74,77), +(1,5,36,697,1585,27,30,36,76,79), +(1,5,37,728,1639,28,30,36,78,81), +(1,5,38,760,1693,28,31,37,79,83), +(1,5,39,793,1747,28,31,38,81,85), +(1,5,40,827,1801,28,31,38,83,87), +(1,5,41,862,1855,29,32,39,85,88), +(1,5,42,898,1909,29,32,39,87,90), +(1,5,43,935,1963,29,33,40,89,92), +(1,5,44,973,2017,30,33,40,91,94), +(1,5,45,1012,2071,30,33,41,92,96), +(1,5,46,1052,2125,30,34,42,94,98), +(1,5,47,1093,2179,31,34,42,96,100), +(1,5,48,1135,2233,31,35,43,98,102), +(1,5,49,1178,2287,31,35,44,100,104), +(1,5,50,1222,2341,32,36,44,102,106), +(1,5,51,1267,2395,32,36,45,104,109), +(1,5,52,1313,2449,32,36,45,106,111), +(1,5,53,1360,2503,33,37,46,108,113), +(1,5,54,1408,2557,33,37,47,110,115), +(1,5,55,1457,2611,33,38,47,112,117), +(1,5,56,1507,2665,34,38,48,114,119), +(1,5,57,1558,2719,34,39,49,117,121), +(1,5,58,1610,2773,34,39,49,119,124), +(1,5,59,1663,2827,35,40,50,121,126), +(1,5,60,1717,2881,35,40,51,123,128), +(1,5,61,1887,3050,35,41,51,125,130), +(1,5,62,2065,3204,36,41,52,127,132), +(1,5,63,2251,3373,36,41,53,129,135), +(1,5,64,2445,3527,37,42,54,132,137), +(1,5,65,2647,3696,37,42,54,134,139), +(1,5,66,2858,3850,37,43,55,136,142), +(1,5,67,3078,4019,38,43,56,138,144), +(1,5,68,3307,4173,38,44,57,140,146), +(1,5,69,3545,4342,39,44,57,143,149), +(1,5,70,3792,4511,39,45,58,145,151), +(1,8,1,52,165,20,20,20,23,22), +(1,8,2,67,190,20,20,20,24,23), +(1,8,3,82,216,20,20,21,26,25), +(1,8,4,97,243,20,20,21,27,26), +(1,8,5,112,271,20,21,21,28,27), +(1,8,6,127,300,20,21,21,30,29), +(1,8,7,142,330,21,21,22,31,30), +(1,8,8,157,361,21,21,22,33,31), +(1,8,9,172,393,21,21,22,34,33), +(1,8,10,187,426,21,21,23,36,34), +(1,8,11,202,460,21,22,23,37,36), +(1,8,12,217,495,21,22,23,39,37), +(1,8,13,232,531,21,22,24,40,38), +(1,8,14,247,568,21,22,24,42,40), +(1,8,15,262,606,21,22,24,43,41), +(1,8,16,277,645,21,23,25,45,43), +(1,8,17,292,685,22,23,25,46,44), +(1,8,18,307,726,22,23,25,48,46), +(1,8,19,322,768,22,23,26,49,47), +(1,8,20,337,811,22,23,26,51,49), +(1,8,21,352,855,22,24,26,53,51), +(1,8,22,367,900,22,24,27,54,52), +(1,8,23,382,946,22,24,27,56,54), +(1,8,24,398,993,23,24,28,58,55), +(1,8,25,415,1041,23,25,28,59,57), +(1,8,26,433,1090,23,25,28,61,59), +(1,8,27,452,1140,23,25,29,63,60), +(1,8,28,472,1191,23,25,29,65,62), +(1,8,29,493,1242,23,25,30,66,64), +(1,8,30,515,1293,24,26,30,68,65), +(1,8,31,538,1344,24,26,30,70,67), +(1,8,32,562,1395,24,26,31,72,69), +(1,8,33,587,1446,24,27,31,73,70), +(1,8,34,613,1497,24,27,32,75,72), +(1,8,35,640,1548,24,27,32,77,74), +(1,8,36,668,1599,25,27,33,79,76), +(1,8,37,697,1650,25,28,33,81,78), +(1,8,38,727,1701,25,28,34,83,79), +(1,8,39,758,1752,25,28,34,85,81), +(1,8,40,790,1803,25,28,35,87,83), +(1,8,41,823,1854,26,29,35,88,85), +(1,8,42,857,1905,26,29,35,90,87), +(1,8,43,892,1956,26,29,36,92,89), +(1,8,44,928,2007,26,30,36,94,91), +(1,8,45,965,2058,26,30,37,96,92), +(1,8,46,1003,2109,27,30,37,98,94), +(1,8,47,1042,2160,27,31,38,100,96), +(1,8,48,1082,2211,27,31,38,102,98), +(1,8,49,1123,2262,27,31,39,104,100), +(1,8,50,1165,2313,28,32,40,106,102), +(1,8,51,1208,2364,28,32,40,109,104), +(1,8,52,1252,2415,28,32,41,111,106), +(1,8,53,1297,2466,28,33,41,113,108), +(1,8,54,1343,2517,29,33,42,115,110), +(1,8,55,1390,2568,29,33,42,117,112), +(1,8,56,1438,2619,29,34,43,119,114), +(1,8,57,1487,2670,29,34,43,121,117), +(1,8,58,1537,2721,30,34,44,124,119), +(1,8,59,1588,2772,30,35,44,126,121), +(1,8,60,1640,2823,30,35,45,128,123), +(1,8,61,1806,2956,30,35,46,130,125), +(1,8,62,1981,3104,31,36,46,132,127), +(1,8,63,2165,3237,31,36,47,135,129), +(1,8,64,2358,3385,31,37,47,137,132), +(1,8,65,2560,3518,32,37,48,139,134), +(1,8,66,2772,3666,32,37,49,142,136), +(1,8,67,2994,3799,32,38,49,144,138), +(1,8,68,3226,3947,32,38,50,146,140), +(1,8,69,3469,4080,33,39,50,149,143), +(1,8,70,3723,4228,33,39,51,151,145), +(1,9,1,53,140,20,20,21,22,22), +(1,9,2,68,163,20,20,22,23,23), +(1,9,3,83,187,21,21,22,24,24), +(1,9,4,98,212,21,21,23,26,25), +(1,9,5,113,238,21,21,23,27,27), +(1,9,6,128,265,21,22,24,28,28), +(1,9,7,143,293,22,22,24,29,29), +(1,9,8,158,322,22,23,25,30,30), +(1,9,9,173,352,22,23,26,32,31), +(1,9,10,188,383,23,23,26,33,33), +(1,9,11,203,415,23,24,27,34,34), +(1,9,12,218,448,23,24,27,35,35), +(1,9,13,233,482,24,25,28,37,36), +(1,9,14,248,517,24,25,29,38,38), +(1,9,15,263,553,24,25,29,39,39), +(1,9,16,278,590,25,26,30,41,40), +(1,9,17,293,628,25,26,31,42,42), +(1,9,18,309,667,25,27,31,43,43), +(1,9,19,326,707,26,27,32,45,44), +(1,9,20,344,748,26,28,33,46,46), +(1,9,21,363,790,26,28,33,48,47), +(1,9,22,383,833,27,29,34,49,49), +(1,9,23,404,877,27,29,35,51,50), +(1,9,24,426,922,28,30,35,52,51), +(1,9,25,449,968,28,30,36,53,53), +(1,9,26,473,1015,28,31,37,55,54), +(1,9,27,498,1063,29,31,37,56,56), +(1,9,28,524,1112,29,32,38,58,57), +(1,9,29,551,1162,30,32,39,59,59), +(1,9,30,579,1213,30,33,40,61,60), +(1,9,31,608,1264,30,33,40,62,62), +(1,9,32,638,1315,31,34,41,64,63), +(1,9,33,669,1366,31,34,42,66,65), +(1,9,34,701,1417,32,35,43,67,66), +(1,9,35,734,1468,32,35,44,69,68), +(1,9,36,768,1519,33,36,44,70,69), +(1,9,37,803,1570,33,36,45,72,71), +(1,9,38,839,1621,34,37,46,74,73), +(1,9,39,876,1672,34,38,47,75,74), +(1,9,40,914,1723,35,38,48,77,76), +(1,9,41,953,1774,35,39,48,79,78), +(1,9,42,993,1825,35,39,49,80,79), +(1,9,43,1034,1876,36,40,50,82,81), +(1,9,44,1076,1927,36,40,51,84,83), +(1,9,45,1119,1978,37,41,52,85,84), +(1,9,46,1163,2029,37,42,53,87,86), +(1,9,47,1208,2080,38,42,54,89,88), +(1,9,48,1254,2131,38,43,55,91,89), +(1,9,49,1301,2182,39,44,55,93,91), +(1,9,50,1349,2233,40,44,56,94,93), +(1,9,51,1398,2284,40,45,57,96,95), +(1,9,52,1448,2335,41,45,58,98,97), +(1,9,53,1499,2386,41,46,59,100,98), +(1,9,54,1551,2437,42,47,60,102,100), +(1,9,55,1604,2488,42,47,61,103,102), +(1,9,56,1658,2539,43,48,62,105,104), +(1,9,57,1713,2590,43,49,63,107,106), +(1,9,58,1769,2641,44,49,64,109,108), +(1,9,59,1826,2692,44,50,65,111,109), +(1,9,60,1884,2743,45,51,66,113,111), +(1,9,61,2060,2897,46,51,67,115,113), +(1,9,62,2245,3051,46,52,68,117,115), +(1,9,63,2439,3220,47,53,69,119,117), +(1,9,64,2642,3374,47,54,70,121,119), +(1,9,65,2854,3528,48,54,71,123,121), +(1,9,66,3076,3697,49,55,72,125,123), +(1,9,67,3308,3851,49,56,73,127,125), +(1,9,68,3551,4005,50,57,74,129,127), +(1,9,69,3805,4174,50,57,75,131,129), +(1,9,70,4070,4328,51,58,76,133,131), +(2,1,1,80,0,26,17,24,17,23), +(2,1,2,99,0,27,18,25,17,23), +(2,1,3,118,0,29,19,26,17,24), +(2,1,4,137,0,30,19,27,17,24), +(2,1,5,156,0,31,20,29,17,24), +(2,1,6,175,0,32,21,30,17,24), +(2,1,7,194,0,34,22,31,18,25), +(2,1,8,213,0,35,23,32,18,25), +(2,1,9,232,0,37,24,34,18,25), +(2,1,10,251,0,38,24,35,18,26), +(2,1,11,270,0,39,25,36,18,26), +(2,1,12,289,0,41,26,37,18,26), +(2,1,13,308,0,42,27,39,18,27), +(2,1,14,328,0,44,28,40,18,27), +(2,1,15,349,0,45,29,41,18,27), +(2,1,16,371,0,47,30,43,19,28), +(2,1,17,394,0,48,31,44,19,28), +(2,1,18,418,0,50,32,45,19,28), +(2,1,19,443,0,51,33,47,19,29), +(2,1,20,469,0,53,34,48,19,29), +(2,1,21,496,0,54,34,50,19,29), +(2,1,22,524,0,56,35,51,19,30), +(2,1,23,553,0,57,36,52,20,30), +(2,1,24,583,0,59,37,54,20,30), +(2,1,25,614,0,60,38,55,20,31), +(2,1,26,646,0,62,39,57,20,31), +(2,1,27,679,0,64,40,58,20,32), +(2,1,28,713,0,65,41,60,20,32), +(2,1,29,748,0,67,43,61,21,32), +(2,1,30,784,0,69,44,63,21,33), +(2,1,31,821,0,70,45,64,21,33), +(2,1,32,859,0,72,46,66,21,34), +(2,1,33,898,0,74,47,67,21,34), +(2,1,34,938,0,76,48,69,21,35), +(2,1,35,979,0,77,49,71,22,35), +(2,1,36,1021,0,79,50,72,22,36), +(2,1,37,1065,0,81,51,74,22,36), +(2,1,38,1111,0,83,52,76,22,36), +(2,1,39,1159,0,84,53,77,22,37), +(2,1,40,1209,0,86,55,79,23,37), +(2,1,41,1261,0,88,56,81,23,38), +(2,1,42,1315,0,90,57,82,23,38), +(2,1,43,1371,0,92,58,84,23,39), +(2,1,44,1429,0,94,59,86,23,39), +(2,1,45,1489,0,96,60,87,24,40), +(2,1,46,1551,0,98,62,89,24,40), +(2,1,47,1615,0,100,63,91,24,41), +(2,1,48,1681,0,101,64,93,24,41), +(2,1,49,1749,0,103,65,94,25,42), +(2,1,50,1819,0,105,66,96,25,42), +(2,1,51,1891,0,107,68,98,25,43), +(2,1,52,1965,0,109,69,100,25,43), +(2,1,53,2041,0,111,70,102,25,44), +(2,1,54,2119,0,113,71,104,26,45), +(2,1,55,2199,0,115,73,105,26,45), +(2,1,56,2281,0,118,74,107,26,46), +(2,1,57,2365,0,120,75,109,26,46), +(2,1,58,2451,0,122,77,111,27,47), +(2,1,59,2539,0,124,78,113,27,47), +(2,1,60,2629,0,126,79,115,27,48), +(2,1,61,2862,0,128,81,117,27,48), +(2,1,62,3109,0,130,82,119,28,49), +(2,1,63,3370,0,132,83,121,28,50), +(2,1,64,3645,0,135,85,123,28,50), +(2,1,65,3935,0,137,86,125,29,51), +(2,1,66,4240,0,139,87,127,29,52), +(2,1,67,4560,0,141,89,129,29,52), +(2,1,68,4896,0,143,90,131,29,53), +(2,1,69,5248,0,146,92,133,30,53), +(2,1,70,5616,0,148,93,135,30,54), +(2,3,1,76,82,23,20,23,17,24), +(2,3,2,93,102,23,21,24,18,25), +(2,3,3,110,123,24,23,25,18,25), +(2,3,4,127,145,24,24,26,19,26), +(2,3,5,144,168,25,25,27,19,26), +(2,3,6,161,192,25,27,28,20,27), +(2,3,7,178,217,26,28,28,21,28), +(2,3,8,195,243,26,30,29,21,28), +(2,3,9,212,270,26,31,30,22,29), +(2,3,10,229,298,27,33,31,22,30), +(2,3,11,246,327,27,34,32,23,30), +(2,3,12,263,357,28,36,33,24,31), +(2,3,13,280,388,28,37,34,24,32), +(2,3,14,298,420,29,39,35,25,33), +(2,3,15,317,453,29,40,36,26,33), +(2,3,16,337,487,30,42,37,26,34), +(2,3,17,358,522,30,43,39,27,35), +(2,3,18,380,558,31,45,40,28,35), +(2,3,19,403,595,31,47,41,28,36), +(2,3,20,427,633,32,48,42,29,37), +(2,3,21,452,672,32,50,43,30,38), +(2,3,22,478,712,33,51,44,31,39), +(2,3,23,505,753,34,53,45,31,39), +(2,3,24,533,795,34,55,46,32,40), +(2,3,25,562,838,35,57,47,33,41), +(2,3,26,592,882,35,58,48,34,42), +(2,3,27,623,927,36,60,50,34,43), +(2,3,28,655,972,36,62,51,35,43), +(2,3,29,688,1017,37,63,52,36,44), +(2,3,30,722,1062,38,65,53,37,45), +(2,3,31,757,1107,38,67,54,37,46), +(2,3,32,793,1152,39,69,56,38,47), +(2,3,33,830,1197,39,71,57,39,48), +(2,3,34,868,1242,40,72,58,40,49), +(2,3,35,907,1287,41,74,59,41,49), +(2,3,36,947,1332,41,76,61,42,50), +(2,3,37,988,1377,42,78,62,42,51), +(2,3,38,1030,1422,43,80,63,43,52), +(2,3,39,1073,1467,43,82,64,44,53), +(2,3,40,1117,1512,44,84,66,45,54), +(2,3,41,1162,1557,45,86,67,46,55), +(2,3,42,1208,1602,45,88,68,47,56), +(2,3,43,1255,1647,46,90,70,47,57), +(2,3,44,1303,1692,47,91,71,48,58), +(2,3,45,1352,1737,47,93,72,49,59), +(2,3,46,1402,1782,48,95,74,50,60), +(2,3,47,1453,1827,49,98,75,51,61), +(2,3,48,1505,1872,50,100,77,52,62), +(2,3,49,1558,1917,50,102,78,53,63), +(2,3,50,1612,1962,51,104,79,54,64), +(2,3,51,1667,2007,52,106,81,55,65), +(2,3,52,1723,2052,52,108,82,56,66), +(2,3,53,1780,2097,53,110,84,57,67), +(2,3,54,1838,2142,54,112,85,58,68), +(2,3,55,1897,2187,55,114,87,59,69), +(2,3,56,1957,2232,55,116,88,60,70), +(2,3,57,2018,2277,56,118,90,61,71), +(2,3,58,2080,2322,57,121,91,62,72), +(2,3,59,2143,2367,58,123,93,63,73), +(2,3,60,2207,2412,59,125,94,64,74), +(2,3,61,2393,2593,59,127,96,65,76), +(2,3,62,2588,2774,60,130,97,66,77), +(2,3,63,2792,2955,61,132,99,67,78), +(2,3,64,3005,3136,62,134,100,68,79), +(2,3,65,3227,3332,63,136,102,69,80), +(2,3,66,3459,3513,64,139,104,70,81), +(2,3,67,3701,3694,64,141,105,71,82), +(2,3,68,3953,3875,65,143,107,72,84), +(2,3,69,4215,4056,66,146,108,73,85), +(2,3,70,4488,4252,67,148,110,74,86), +(2,4,1,75,0,24,20,23,17,23), +(2,4,2,92,0,25,21,24,17,23), +(2,4,3,109,0,25,23,24,17,24), +(2,4,4,126,0,26,24,25,17,24), +(2,4,5,143,0,27,26,26,18,24), +(2,4,6,160,0,28,27,26,18,25), +(2,4,7,177,0,29,29,27,18,25), +(2,4,8,194,0,29,30,28,18,26), +(2,4,9,211,0,30,32,29,18,26), +(2,4,10,228,0,31,33,29,19,26), +(2,4,11,245,0,32,35,30,19,27), +(2,4,12,262,0,33,37,31,19,27), +(2,4,13,279,0,34,38,32,19,28), +(2,4,14,296,0,34,40,32,19,28), +(2,4,15,313,0,35,41,33,19,28), +(2,4,16,331,0,36,43,34,20,29), +(2,4,17,350,0,37,45,35,20,29), +(2,4,18,370,0,38,46,36,20,30), +(2,4,19,391,0,39,48,37,20,30), +(2,4,20,413,0,40,50,37,21,31), +(2,4,21,436,0,41,52,38,21,31), +(2,4,22,460,0,42,53,39,21,31), +(2,4,23,485,0,43,55,40,21,32), +(2,4,24,511,0,43,57,41,21,32), +(2,4,25,538,0,44,59,42,22,33), +(2,4,26,566,0,45,60,43,22,33), +(2,4,27,595,0,46,62,44,22,34), +(2,4,28,625,0,47,64,44,22,34), +(2,4,29,656,0,48,66,45,23,35), +(2,4,30,688,0,49,68,46,23,35), +(2,4,31,721,0,50,70,47,23,36), +(2,4,32,755,0,51,72,48,23,36), +(2,4,33,790,0,53,73,49,24,37), +(2,4,34,826,0,54,75,50,24,38), +(2,4,35,863,0,55,77,51,24,38), +(2,4,36,901,0,56,79,52,24,39), +(2,4,37,940,0,57,81,53,25,39), +(2,4,38,980,0,58,83,54,25,40), +(2,4,39,1021,0,59,85,55,25,40), +(2,4,40,1063,0,60,87,56,26,41), +(2,4,41,1106,0,61,89,57,26,41), +(2,4,42,1150,0,62,91,58,26,42), +(2,4,43,1195,0,63,93,59,27,43), +(2,4,44,1241,0,65,95,60,27,43), +(2,4,45,1288,0,66,98,61,27,44), +(2,4,46,1336,0,67,100,62,27,44), +(2,4,47,1385,0,68,102,64,28,45), +(2,4,48,1435,0,69,104,65,28,46), +(2,4,49,1486,0,71,106,66,28,46), +(2,4,50,1538,0,72,108,67,29,47), +(2,4,51,1591,0,73,110,68,29,48), +(2,4,52,1645,0,74,113,69,29,48), +(2,4,53,1700,0,75,115,70,30,49), +(2,4,54,1756,0,77,117,71,30,50), +(2,4,55,1813,0,78,119,73,30,50), +(2,4,56,1871,0,79,122,74,31,51), +(2,4,57,1930,0,80,124,75,31,52), +(2,4,58,1990,0,82,126,76,31,52), +(2,4,59,2051,0,83,129,77,32,53), +(2,4,60,2113,0,84,131,78,32,54), +(2,4,61,2302,0,86,133,80,33,54), +(2,4,62,2500,0,87,136,81,33,55), +(2,4,63,2707,0,88,138,82,33,56), +(2,4,64,2923,0,90,140,83,34,57), +(2,4,65,3149,0,91,143,85,34,57), +(2,4,66,3385,0,92,145,86,34,58), +(2,4,67,3631,0,94,148,87,35,59), +(2,4,68,3888,0,95,150,88,35,59), +(2,4,69,4156,0,97,153,90,36,60), +(2,4,70,4435,0,98,155,91,36,61), +(2,7,1,77,73,24,17,23,18,25), +(2,7,2,94,94,25,17,24,19,26), +(2,7,3,111,116,26,18,25,20,27), +(2,7,4,128,139,26,18,26,21,28), +(2,7,5,145,163,27,19,27,22,29), +(2,7,6,162,188,28,19,28,23,30), +(2,7,7,179,214,29,20,29,24,31), +(2,7,8,196,241,30,20,30,25,32), +(2,7,9,213,269,31,21,31,26,33), +(2,7,10,230,298,32,21,32,27,34), +(2,7,11,247,328,33,22,33,28,36), +(2,7,12,264,359,34,22,34,29,37), +(2,7,13,281,391,34,23,35,30,38), +(2,7,14,298,424,35,23,36,31,39), +(2,7,15,315,458,36,24,37,32,40), +(2,7,16,332,493,37,24,39,33,41), +(2,7,17,350,529,38,25,40,34,43), +(2,7,18,369,566,39,25,41,35,44), +(2,7,19,389,604,40,26,42,36,45), +(2,7,20,410,643,41,26,43,37,46), +(2,7,21,432,683,42,27,44,38,47), +(2,7,22,455,724,43,27,45,39,49), +(2,7,23,479,766,44,28,47,40,50), +(2,7,24,504,809,45,28,48,41,51), +(2,7,25,530,853,47,29,49,43,52), +(2,7,26,557,898,48,30,50,44,54), +(2,7,27,585,944,49,30,52,45,55), +(2,7,28,614,991,50,31,53,46,56), +(2,7,29,644,1039,51,31,54,47,58), +(2,7,30,675,1088,52,32,55,48,59), +(2,7,31,707,1138,53,33,57,50,60), +(2,7,32,740,1189,54,33,58,51,62), +(2,7,33,774,1240,55,34,59,52,63), +(2,7,34,809,1291,57,34,61,53,65), +(2,7,35,845,1342,58,35,62,55,66), +(2,7,36,882,1393,59,36,63,56,67), +(2,7,37,920,1444,60,36,65,57,69), +(2,7,38,959,1495,61,37,66,58,70), +(2,7,39,999,1546,62,38,67,60,72), +(2,7,40,1040,1597,64,38,69,61,73), +(2,7,41,1082,1648,65,39,70,62,75), +(2,7,42,1125,1699,66,40,72,64,76), +(2,7,43,1169,1750,67,40,73,65,78), +(2,7,44,1214,1801,69,41,74,66,79), +(2,7,45,1260,1852,70,42,76,68,81), +(2,7,46,1307,1903,71,42,77,69,82), +(2,7,47,1355,1954,72,43,79,70,84), +(2,7,48,1404,2005,74,44,80,72,85), +(2,7,49,1454,2056,75,45,82,73,87), +(2,7,50,1505,2107,76,45,83,75,89), +(2,7,51,1557,2158,78,46,85,76,90), +(2,7,52,1610,2209,79,47,86,77,92), +(2,7,53,1664,2260,80,47,88,79,93), +(2,7,54,1719,2311,82,48,90,80,95), +(2,7,55,1775,2362,83,49,91,82,97), +(2,7,56,1832,2413,85,50,93,83,98), +(2,7,57,1890,2464,86,50,94,85,100), +(2,7,58,1949,2515,87,51,96,86,102), +(2,7,59,2009,2566,89,52,97,88,103), +(2,7,60,2070,2617,90,53,99,89,105), +(2,7,61,2238,2776,92,54,101,91,107), +(2,7,62,2414,2935,93,54,102,92,109), +(2,7,63,2598,3109,95,55,104,94,110), +(2,7,64,2790,3268,96,56,106,95,112), +(2,7,65,2991,3427,97,57,107,97,114), +(2,7,66,3201,3601,99,58,109,99,116), +(2,7,67,3421,3760,100,58,111,100,118), +(2,7,68,3651,3919,102,59,113,102,119), +(2,7,69,3891,4093,103,60,114,103,121), +(2,7,70,4141,4252,105,61,116,105,123), +(2,9,1,73,109,23,17,23,19,25), +(2,9,2,88,132,23,17,24,20,26), +(2,9,3,103,156,24,18,24,21,27), +(2,9,4,118,181,24,18,25,23,28), +(2,9,5,133,207,24,18,25,24,30), +(2,9,6,148,234,24,19,26,25,31), +(2,9,7,163,262,25,19,26,26,32), +(2,9,8,178,291,25,20,27,27,33), +(2,9,9,193,321,25,20,27,29,34), +(2,9,10,208,352,26,20,28,30,36), +(2,9,11,223,384,26,21,29,31,37), +(2,9,12,238,417,26,21,29,33,38), +(2,9,13,253,451,27,22,30,34,39), +(2,9,14,268,486,27,22,31,35,41), +(2,9,15,283,522,27,23,31,37,42), +(2,9,16,298,559,28,23,32,38,43), +(2,9,17,313,597,28,23,32,39,45), +(2,9,18,329,636,28,24,33,41,46), +(2,9,19,346,676,29,24,34,42,47), +(2,9,20,364,717,29,25,34,43,49), +(2,9,21,383,759,29,25,35,45,50), +(2,9,22,403,802,30,26,36,46,51), +(2,9,23,424,846,30,26,37,48,53), +(2,9,24,446,891,30,27,37,49,54), +(2,9,25,469,937,31,27,38,51,56), +(2,9,26,493,984,31,28,39,52,57), +(2,9,27,518,1032,32,28,39,54,59), +(2,9,28,544,1081,32,29,40,55,60), +(2,9,29,571,1131,32,29,41,57,62), +(2,9,30,599,1182,33,30,42,58,63), +(2,9,31,628,1233,33,30,42,60,65), +(2,9,32,658,1284,34,31,43,61,66), +(2,9,33,689,1335,34,31,44,63,68), +(2,9,34,721,1386,35,32,45,64,69), +(2,9,35,754,1437,35,32,45,66,71), +(2,9,36,788,1488,36,33,46,68,72), +(2,9,37,823,1539,36,34,47,69,74), +(2,9,38,859,1590,36,34,48,71,76), +(2,9,39,896,1641,37,35,49,72,77), +(2,9,40,934,1692,37,35,50,74,79), +(2,9,41,973,1743,38,36,50,76,80), +(2,9,42,1013,1794,38,36,51,77,82), +(2,9,43,1054,1845,39,37,52,79,84), +(2,9,44,1096,1896,39,38,53,81,85), +(2,9,45,1139,1947,40,38,54,83,87), +(2,9,46,1183,1998,40,39,55,84,89), +(2,9,47,1228,2049,41,39,56,86,91), +(2,9,48,1274,2100,41,40,56,88,92), +(2,9,49,1321,2151,42,41,57,90,94), +(2,9,50,1369,2202,42,41,58,91,96), +(2,9,51,1418,2253,43,42,59,93,98), +(2,9,52,1468,2304,43,43,60,95,99), +(2,9,53,1519,2355,44,43,61,97,101), +(2,9,54,1571,2406,45,44,62,99,103), +(2,9,55,1624,2457,45,45,63,101,105), +(2,9,56,1678,2508,46,45,64,102,107), +(2,9,57,1733,2559,46,46,65,104,109), +(2,9,58,1789,2610,47,47,66,106,110), +(2,9,59,1846,2661,47,47,67,108,112), +(2,9,60,1904,2712,48,48,68,110,114), +(2,9,61,2080,2866,48,49,69,112,116), +(2,9,62,2265,3020,49,49,70,114,118), +(2,9,63,2459,3189,50,50,71,116,120), +(2,9,64,2662,3343,50,51,72,118,122), +(2,9,65,2874,3497,51,51,73,120,124), +(2,9,66,3096,3666,52,52,74,122,126), +(2,9,67,3328,3820,52,53,75,124,128), +(2,9,68,3571,3974,53,54,76,126,130), +(2,9,69,3825,4143,53,54,77,128,132), +(2,9,70,4090,4297,54,55,78,130,134), +(3,1,1,90,0,25,16,25,19,19), +(3,1,2,109,0,26,17,26,19,19), +(3,1,3,128,0,28,18,27,19,20), +(3,1,4,147,0,29,18,28,19,20), +(3,1,5,166,0,30,19,30,19,20), +(3,1,6,185,0,31,20,31,19,20), +(3,1,7,204,0,33,21,32,20,21), +(3,1,8,223,0,34,22,33,20,21), +(3,1,9,242,0,36,23,35,20,21), +(3,1,10,261,0,37,23,36,20,22), +(3,1,11,280,0,38,24,37,20,22), +(3,1,12,299,0,40,25,38,20,22), +(3,1,13,318,0,41,26,40,20,23), +(3,1,14,338,0,43,27,41,20,23), +(3,1,15,359,0,44,28,42,20,23), +(3,1,16,381,0,46,29,44,21,24), +(3,1,17,404,0,47,30,45,21,24), +(3,1,18,428,0,49,31,46,21,24), +(3,1,19,453,0,50,32,48,21,25), +(3,1,20,479,0,52,33,49,21,25), +(3,1,21,506,0,53,34,51,21,26), +(3,1,22,534,0,55,34,52,21,26), +(3,1,23,563,0,56,35,53,21,26), +(3,1,24,593,0,58,36,55,22,27), +(3,1,25,624,0,59,37,56,22,27), +(3,1,26,656,0,61,38,58,22,27), +(3,1,27,689,0,63,39,59,22,28), +(3,1,28,723,0,64,41,61,22,28), +(3,1,29,758,0,66,42,62,22,29), +(3,1,30,794,0,68,43,64,23,29), +(3,1,31,831,0,69,44,65,23,30), +(3,1,32,869,0,71,45,67,23,30), +(3,1,33,908,0,73,46,68,23,30), +(3,1,34,948,0,75,47,70,23,31), +(3,1,35,989,0,76,48,72,24,31), +(3,1,36,1031,0,78,49,73,24,32), +(3,1,37,1075,0,80,50,75,24,32), +(3,1,38,1121,0,82,51,76,24,33), +(3,1,39,1169,0,84,52,78,24,33), +(3,1,40,1219,0,85,54,80,24,34), +(3,1,41,1271,0,87,55,81,25,34), +(3,1,42,1325,0,89,56,83,25,35), +(3,1,43,1381,0,91,57,85,25,35), +(3,1,44,1439,0,93,58,87,25,36), +(3,1,45,1499,0,95,59,88,26,36), +(3,1,46,1561,0,97,61,90,26,37), +(3,1,47,1625,0,99,62,92,26,37), +(3,1,48,1691,0,101,63,94,26,38), +(3,1,49,1759,0,102,64,95,26,38), +(3,1,50,1829,0,104,65,97,27,39), +(3,1,51,1901,0,106,67,99,27,39), +(3,1,52,1975,0,108,68,101,27,40), +(3,1,53,2051,0,110,69,103,27,40), +(3,1,54,2129,0,112,70,104,28,41), +(3,1,55,2209,0,115,72,106,28,41), +(3,1,56,2291,0,117,73,108,28,42), +(3,1,57,2375,0,119,74,110,28,42), +(3,1,58,2461,0,121,76,112,29,43), +(3,1,59,2549,0,123,77,114,29,43), +(3,1,60,2639,0,125,78,116,29,44), +(3,1,61,2872,0,127,80,118,29,45), +(3,1,62,3119,0,129,81,120,30,45), +(3,1,63,3380,0,131,82,122,30,46), +(3,1,64,3655,0,134,84,124,30,46), +(3,1,65,3945,0,136,85,126,31,47), +(3,1,66,4250,0,138,86,128,31,48), +(3,1,67,4570,0,140,88,130,31,48), +(3,1,68,4906,0,142,89,132,31,49), +(3,1,69,5258,0,145,91,134,32,49), +(3,1,70,5626,0,147,92,136,32,50), +(3,2,1,88,79,24,16,25,19,20), +(3,2,2,106,98,25,17,26,20,21), +(3,2,3,124,118,26,17,27,20,21), +(3,2,4,142,139,27,18,28,21,22), +(3,2,5,160,161,28,18,29,22,23), +(3,2,6,178,184,29,19,30,22,24), +(3,2,7,196,208,31,20,31,23,24), +(3,2,8,214,233,32,20,32,24,25), +(3,2,9,232,259,33,21,33,24,26), +(3,2,10,250,286,34,21,34,25,26), +(3,2,11,268,314,35,22,36,26,27), +(3,2,12,286,343,36,23,37,26,28), +(3,2,13,304,373,38,23,38,27,29), +(3,2,14,322,404,39,24,39,28,30), +(3,2,15,341,436,40,25,40,29,30), +(3,2,16,361,469,41,25,41,29,31), +(3,2,17,382,503,43,26,43,30,32), +(3,2,18,404,538,44,27,44,31,33), +(3,2,19,427,574,45,28,45,32,34), +(3,2,20,451,611,47,28,46,32,35), +(3,2,21,476,649,48,29,47,33,35), +(3,2,22,502,688,49,30,49,34,36), +(3,2,23,529,728,51,30,50,35,37), +(3,2,24,557,769,52,31,51,36,38), +(3,2,25,586,811,53,32,52,36,39), +(3,2,26,616,853,55,33,54,37,40), +(3,2,27,647,895,56,33,55,38,41), +(3,2,28,679,937,57,34,56,39,42), +(3,2,29,712,979,59,35,58,40,43), +(3,2,30,746,1021,60,36,59,41,43), +(3,2,31,781,1063,62,37,60,42,44), +(3,2,32,817,1105,63,37,62,42,45), +(3,2,33,854,1147,65,38,63,43,46), +(3,2,34,892,1189,66,39,65,44,47), +(3,2,35,931,1231,68,40,66,45,48), +(3,2,36,971,1273,69,41,67,46,49), +(3,2,37,1012,1315,71,41,69,47,50), +(3,2,38,1054,1357,72,42,70,48,51), +(3,2,39,1097,1399,74,43,72,49,52), +(3,2,40,1141,1441,75,44,73,50,53), +(3,2,41,1186,1483,77,45,75,51,54), +(3,2,42,1232,1525,78,46,76,52,55), +(3,2,43,1279,1567,80,47,78,53,56), +(3,2,44,1327,1609,82,47,79,54,57), +(3,2,45,1376,1651,83,48,81,55,59), +(3,2,46,1426,1693,85,49,82,56,60), +(3,2,47,1477,1735,87,50,84,57,61), +(3,2,48,1529,1777,88,51,85,58,62), +(3,2,49,1582,1819,90,52,87,59,63), +(3,2,50,1636,1861,92,53,89,60,64), +(3,2,51,1691,1903,93,54,90,61,65), +(3,2,52,1747,1945,95,55,92,62,66), +(3,2,53,1804,1987,97,56,93,63,67), +(3,2,54,1862,2029,98,57,95,64,69), +(3,2,55,1921,2071,100,58,97,65,70), +(3,2,56,1981,2113,102,59,98,66,71), +(3,2,57,2042,2155,104,60,100,67,72), +(3,2,58,2104,2197,106,61,102,68,73), +(3,2,59,2167,2239,107,62,103,69,74), +(3,2,60,2231,2281,109,63,105,70,76), +(3,2,61,2411,2440,111,64,107,72,77), +(3,2,62,2599,2599,113,65,109,73,78), +(3,2,63,2795,2773,115,66,110,74,79), +(3,2,64,3000,2932,117,67,112,75,80), +(3,2,65,3214,3091,118,68,114,76,82), +(3,2,66,3437,3265,120,69,116,77,83), +(3,2,67,3670,3424,122,70,118,78,84), +(3,2,68,3913,3583,124,71,119,80,85), +(3,2,69,4166,3757,126,72,121,81,87), +(3,2,70,4429,3916,128,73,123,82,88), +(3,3,1,86,84,22,19,24,19,20), +(3,3,2,103,104,22,20,25,20,21), +(3,3,3,120,125,23,22,26,20,21), +(3,3,4,137,147,23,23,27,21,22), +(3,3,5,154,170,24,25,28,21,23), +(3,3,6,171,194,24,26,29,22,23), +(3,3,7,188,219,25,27,29,23,24), +(3,3,8,205,245,25,29,30,23,25), +(3,3,9,222,272,25,30,31,24,25), +(3,3,10,239,300,26,32,32,24,26), +(3,3,11,256,329,26,33,33,25,27), +(3,3,12,273,359,27,35,34,26,27), +(3,3,13,290,390,27,36,35,26,28), +(3,3,14,308,422,28,38,36,27,29), +(3,3,15,327,455,28,39,37,28,29), +(3,3,16,347,489,29,41,38,28,30), +(3,3,17,368,524,29,42,39,29,31), +(3,3,18,390,560,30,44,41,30,32), +(3,3,19,413,597,30,46,42,30,32), +(3,3,20,437,635,31,47,43,31,33), +(3,3,21,462,674,32,49,44,32,34), +(3,3,22,488,714,32,51,45,33,35), +(3,3,23,515,755,33,52,46,33,36), +(3,3,24,543,797,33,54,47,34,36), +(3,3,25,572,840,34,56,48,35,37), +(3,3,26,602,884,34,57,49,35,38), +(3,3,27,633,929,35,59,51,36,39), +(3,3,28,665,974,35,61,52,37,40), +(3,3,29,698,1019,36,63,53,38,40), +(3,3,30,732,1064,37,64,54,39,41), +(3,3,31,767,1109,37,66,55,39,42), +(3,3,32,803,1154,38,68,57,40,43), +(3,3,33,840,1199,38,70,58,41,44), +(3,3,34,878,1244,39,71,59,42,45), +(3,3,35,917,1289,40,73,60,43,46), +(3,3,36,957,1334,40,75,62,43,47), +(3,3,37,998,1379,41,77,63,44,47), +(3,3,38,1040,1424,42,79,64,45,48), +(3,3,39,1083,1469,42,81,65,46,49), +(3,3,40,1127,1514,43,83,67,47,50), +(3,3,41,1172,1559,44,85,68,48,51), +(3,3,42,1218,1604,44,87,69,49,52), +(3,3,43,1265,1649,45,89,71,49,53), +(3,3,44,1313,1694,46,91,72,50,54), +(3,3,45,1362,1739,46,93,73,51,55), +(3,3,46,1412,1784,47,95,75,52,56), +(3,3,47,1463,1829,48,97,76,53,57), +(3,3,48,1515,1874,49,99,78,54,58), +(3,3,49,1568,1919,49,101,79,55,59), +(3,3,50,1622,1964,50,103,80,56,60), +(3,3,51,1677,2009,51,105,82,57,61), +(3,3,52,1733,2054,51,107,83,58,62), +(3,3,53,1790,2099,52,109,85,59,63), +(3,3,54,1848,2144,53,111,86,60,64), +(3,3,55,1907,2189,54,113,88,61,65), +(3,3,56,1967,2234,55,115,89,62,66), +(3,3,57,2028,2279,55,118,91,62,67), +(3,3,58,2090,2324,56,120,92,63,68), +(3,3,59,2153,2369,57,122,94,64,70), +(3,3,60,2217,2414,58,124,95,65,71), +(3,3,61,2403,2595,58,126,97,67,72), +(3,3,62,2598,2776,59,129,98,68,73), +(3,3,63,2802,2957,60,131,100,69,74), +(3,3,64,3015,3138,61,133,101,70,75), +(3,3,65,3237,3334,62,135,103,71,76), +(3,3,66,3469,3515,63,138,105,72,77), +(3,3,67,3711,3696,63,140,106,73,78), +(3,3,68,3963,3877,64,142,108,74,80), +(3,3,69,4225,4058,65,145,109,75,81), +(3,3,70,4498,4254,66,147,111,76,82), +(3,4,1,85,0,23,19,24,19,19), +(3,4,2,102,0,24,20,25,19,19), +(3,4,3,119,0,24,22,25,19,20), +(3,4,4,136,0,25,23,26,19,20), +(3,4,5,153,0,26,25,27,20,20), +(3,4,6,170,0,27,26,27,20,21), +(3,4,7,187,0,28,28,28,20,21), +(3,4,8,204,0,28,29,29,20,22), +(3,4,9,221,0,29,31,30,20,22), +(3,4,10,238,0,30,32,30,20,22), +(3,4,11,255,0,31,34,31,21,23), +(3,4,12,272,0,32,36,32,21,23), +(3,4,13,289,0,33,37,33,21,24), +(3,4,14,306,0,33,39,33,21,24), +(3,4,15,323,0,34,40,34,21,25), +(3,4,16,341,0,35,42,35,22,25), +(3,4,17,360,0,36,44,36,22,25), +(3,4,18,380,0,37,45,37,22,26), +(3,4,19,401,0,38,47,38,22,26), +(3,4,20,423,0,39,49,38,22,27), +(3,4,21,446,0,40,51,39,23,27), +(3,4,22,470,0,41,52,40,23,28), +(3,4,23,495,0,42,54,41,23,28), +(3,4,24,521,0,43,56,42,23,29), +(3,4,25,548,0,44,58,43,24,29), +(3,4,26,576,0,44,59,44,24,30), +(3,4,27,605,0,45,61,44,24,30), +(3,4,28,635,0,46,63,45,24,31), +(3,4,29,666,0,47,65,46,25,31), +(3,4,30,698,0,48,67,47,25,32), +(3,4,31,731,0,49,69,48,25,32), +(3,4,32,765,0,51,71,49,25,33), +(3,4,33,800,0,52,72,50,26,33), +(3,4,34,836,0,53,74,51,26,34), +(3,4,35,873,0,54,76,52,26,34), +(3,4,36,911,0,55,78,53,26,35), +(3,4,37,950,0,56,80,54,27,35), +(3,4,38,990,0,57,82,55,27,36), +(3,4,39,1031,0,58,84,56,27,37), +(3,4,40,1073,0,59,86,57,28,37), +(3,4,41,1116,0,60,88,58,28,38), +(3,4,42,1160,0,61,90,59,28,38), +(3,4,43,1205,0,63,92,60,28,39), +(3,4,44,1251,0,64,95,61,29,39), +(3,4,45,1298,0,65,97,62,29,40), +(3,4,46,1346,0,66,99,63,29,41), +(3,4,47,1395,0,67,101,64,30,41), +(3,4,48,1445,0,68,103,66,30,42), +(3,4,49,1496,0,70,105,67,30,43), +(3,4,50,1548,0,71,107,68,31,43), +(3,4,51,1601,0,72,110,69,31,44), +(3,4,52,1655,0,73,112,70,31,44), +(3,4,53,1710,0,74,114,71,32,45), +(3,4,54,1766,0,76,116,72,32,46), +(3,4,55,1823,0,77,118,73,32,46), +(3,4,56,1881,0,78,121,75,33,47), +(3,4,57,1940,0,80,123,76,33,48), +(3,4,58,2000,0,81,125,77,33,48), +(3,4,59,2061,0,82,128,78,34,49), +(3,4,60,2123,0,83,130,79,34,50), +(3,4,61,2312,0,85,132,81,34,51), +(3,4,62,2510,0,86,135,82,35,51), +(3,4,63,2717,0,87,137,83,35,52), +(3,4,64,2933,0,89,139,84,36,53), +(3,4,65,3159,0,90,142,86,36,53), +(3,4,66,3395,0,91,144,87,36,54), +(3,4,67,3641,0,93,147,88,37,55), +(3,4,68,3898,0,94,149,89,37,56), +(3,4,69,4166,0,96,152,91,38,56), +(3,4,70,4445,0,97,154,92,38,57), +(3,5,1,82,145,22,16,23,21,22), +(3,5,2,97,169,22,16,23,22,23), +(3,5,3,112,194,22,16,24,24,25), +(3,5,4,127,220,22,17,24,25,26), +(3,5,5,142,247,23,17,24,26,27), +(3,5,6,157,275,23,17,25,28,29), +(3,5,7,172,304,23,17,25,29,30), +(3,5,8,187,334,23,18,26,30,32), +(3,5,9,202,365,23,18,26,32,33), +(3,5,10,217,397,23,18,26,33,35), +(3,5,11,232,430,24,18,27,35,36), +(3,5,12,247,464,24,19,27,36,38), +(3,5,13,262,499,24,19,28,37,39), +(3,5,14,277,535,24,19,28,39,41), +(3,5,15,292,572,24,19,28,40,42), +(3,5,16,307,610,24,20,29,42,44), +(3,5,17,322,649,25,20,29,43,45), +(3,5,18,337,689,25,20,30,45,47), +(3,5,19,352,730,25,21,30,46,49), +(3,5,20,367,772,25,21,31,48,50), +(3,5,21,382,815,25,21,31,50,52), +(3,5,22,398,859,26,22,31,51,53), +(3,5,23,415,904,26,22,32,53,55), +(3,5,24,433,950,26,22,32,54,57), +(3,5,25,452,997,26,22,33,56,58), +(3,5,26,472,1045,27,23,33,58,60), +(3,5,27,493,1094,27,23,34,59,62), +(3,5,28,515,1144,27,23,34,61,64), +(3,5,29,538,1195,27,24,35,63,65), +(3,5,30,562,1247,28,24,35,64,67), +(3,5,31,587,1300,28,24,36,66,69), +(3,5,32,613,1354,28,25,36,68,71), +(3,5,33,640,1408,28,25,37,70,72), +(3,5,34,668,1462,29,26,38,71,74), +(3,5,35,697,1516,29,26,38,73,76), +(3,5,36,727,1570,29,26,39,75,78), +(3,5,37,758,1624,29,27,39,77,80), +(3,5,38,790,1678,30,27,40,78,82), +(3,5,39,823,1732,30,27,40,80,84), +(3,5,40,857,1786,30,28,41,82,86), +(3,5,41,892,1840,31,28,41,84,88), +(3,5,42,928,1894,31,29,42,86,89), +(3,5,43,965,1948,31,29,43,88,91), +(3,5,44,1003,2002,32,29,43,90,93), +(3,5,45,1042,2056,32,30,44,92,95), +(3,5,46,1082,2110,32,30,44,93,97), +(3,5,47,1123,2164,32,30,45,95,99), +(3,5,48,1165,2218,33,31,46,97,101), +(3,5,49,1208,2272,33,31,46,99,103), +(3,5,50,1252,2326,33,32,47,101,106), +(3,5,51,1297,2380,34,32,48,103,108), +(3,5,52,1343,2434,34,33,48,105,110), +(3,5,53,1390,2488,35,33,49,107,112), +(3,5,54,1438,2542,35,33,50,109,114), +(3,5,55,1487,2596,35,34,50,111,116), +(3,5,56,1537,2650,36,34,51,113,118), +(3,5,57,1588,2704,36,35,52,116,120), +(3,5,58,1640,2758,36,35,52,118,123), +(3,5,59,1693,2812,37,36,53,120,125), +(3,5,60,1747,2866,37,36,54,122,127), +(3,5,61,1917,3035,37,37,54,124,129), +(3,5,62,2095,3189,38,37,55,126,131), +(3,5,63,2281,3358,38,38,56,128,134), +(3,5,64,2475,3512,39,38,57,131,136), +(3,5,65,2677,3681,39,39,57,133,138), +(3,5,66,2888,3835,39,39,58,135,141), +(3,5,67,3108,4004,40,40,59,137,143), +(3,5,68,3337,4158,40,40,59,139,145), +(3,5,69,3575,4327,41,40,60,142,148), +(3,5,70,3822,4496,41,41,61,144,150), +(4,1,1,50,0,20,25,21,20,20), +(4,1,2,69,0,21,26,22,20,20), +(4,1,3,88,0,23,27,23,20,21), +(4,1,4,107,0,24,27,25,20,21), +(4,1,5,126,0,25,28,26,20,21), +(4,1,6,145,0,27,29,27,20,21), +(4,1,7,164,0,28,30,28,21,22), +(4,1,8,183,0,29,31,29,21,22), +(4,1,9,202,0,31,31,31,21,22), +(4,1,10,221,0,32,32,32,21,23), +(4,1,11,240,0,33,33,33,21,23), +(4,1,12,259,0,35,34,34,21,23), +(4,1,13,278,0,36,35,36,21,24), +(4,1,14,298,0,38,36,37,21,24), +(4,1,15,319,0,39,37,38,21,24), +(4,1,16,341,0,41,37,40,21,25), +(4,1,17,364,0,42,38,41,22,25), +(4,1,18,388,0,44,39,43,22,25), +(4,1,19,413,0,45,40,44,22,26), +(4,1,20,439,0,47,41,45,22,26), +(4,1,21,466,0,48,42,47,22,26), +(4,1,22,494,0,50,43,48,22,27), +(4,1,23,523,0,52,44,50,22,27), +(4,1,24,553,0,53,45,51,23,28), +(4,1,25,584,0,55,46,52,23,28), +(4,1,26,616,0,56,47,54,23,28), +(4,1,27,649,0,58,48,55,23,29), +(4,1,28,683,0,60,49,57,23,29), +(4,1,29,718,0,61,50,58,23,30), +(4,1,30,754,0,63,51,60,24,30), +(4,1,31,791,0,65,52,62,24,30), +(4,1,32,829,0,66,53,63,24,31), +(4,1,33,868,0,68,54,65,24,31), +(4,1,34,908,0,70,55,66,24,32), +(4,1,35,949,0,72,56,68,24,32), +(4,1,36,991,0,73,58,69,25,33), +(4,1,37,1035,0,75,59,71,25,33), +(4,1,38,1081,0,77,60,73,25,34), +(4,1,39,1129,0,79,61,74,25,34), +(4,1,40,1179,0,81,62,76,25,35), +(4,1,41,1231,0,82,63,78,26,35), +(4,1,42,1285,0,84,64,79,26,35), +(4,1,43,1341,0,86,66,81,26,36), +(4,1,44,1399,0,88,67,83,26,36), +(4,1,45,1459,0,90,68,85,26,37), +(4,1,46,1521,0,92,69,86,27,37), +(4,1,47,1585,0,94,70,88,27,38), +(4,1,48,1651,0,96,72,90,27,38), +(4,1,49,1719,0,98,73,92,27,39), +(4,1,50,1789,0,100,74,93,28,40), +(4,1,51,1861,0,102,75,95,28,40), +(4,1,52,1935,0,104,77,97,28,41), +(4,1,53,2011,0,106,78,99,28,41), +(4,1,54,2089,0,108,79,101,29,42), +(4,1,55,2169,0,110,80,103,29,42), +(4,1,56,2251,0,112,82,104,29,43), +(4,1,57,2335,0,114,83,106,29,43), +(4,1,58,2421,0,116,84,108,30,44), +(4,1,59,2509,0,118,86,110,30,44), +(4,1,60,2599,0,120,87,112,30,45), +(4,1,61,2832,0,122,88,114,30,46), +(4,1,62,3079,0,124,90,116,31,46), +(4,1,63,3340,0,127,91,118,31,47), +(4,1,64,3615,0,129,92,120,31,47), +(4,1,65,3905,0,131,94,122,32,48), +(4,1,66,4210,0,133,95,124,32,49), +(4,1,67,4530,0,135,97,126,32,49), +(4,1,68,4866,0,138,98,128,32,50), +(4,1,69,5218,0,140,100,130,33,50), +(4,1,70,5586,0,142,101,132,33,51), +(4,3,1,46,85,17,28,20,20,21), +(4,3,2,63,105,17,29,21,21,22), +(4,3,3,80,126,18,31,22,21,22), +(4,3,4,97,148,18,32,23,22,23), +(4,3,5,114,171,19,33,24,22,24), +(4,3,6,131,195,19,35,25,23,24), +(4,3,7,148,220,20,36,26,24,25), +(4,3,8,165,246,20,38,27,24,25), +(4,3,9,182,273,21,39,27,25,26), +(4,3,10,199,301,21,40,28,25,27), +(4,3,11,216,330,22,42,29,26,28), +(4,3,12,233,360,22,43,30,27,28), +(4,3,13,250,391,23,45,31,27,29), +(4,3,14,268,423,23,46,32,28,30), +(4,3,15,287,456,24,48,34,29,30), +(4,3,16,307,490,24,50,35,29,31), +(4,3,17,328,525,25,51,36,30,32), +(4,3,18,350,561,25,53,37,31,33), +(4,3,19,373,598,26,54,38,31,33), +(4,3,20,397,636,26,56,39,32,34), +(4,3,21,422,675,27,57,40,33,35), +(4,3,22,448,715,27,59,41,33,36), +(4,3,23,475,756,28,61,42,34,36), +(4,3,24,503,798,28,62,43,35,37), +(4,3,25,532,841,29,64,44,36,38), +(4,3,26,562,885,30,66,46,36,39), +(4,3,27,593,930,30,68,47,37,40), +(4,3,28,625,975,31,69,48,38,41), +(4,3,29,658,1020,31,71,49,39,41), +(4,3,30,692,1065,32,73,50,39,42), +(4,3,31,727,1110,33,75,52,40,43), +(4,3,32,763,1155,33,76,53,41,44), +(4,3,33,800,1200,34,78,54,42,45), +(4,3,34,838,1245,34,80,55,43,46), +(4,3,35,877,1290,35,82,57,44,47), +(4,3,36,917,1335,36,84,58,44,48), +(4,3,37,958,1380,36,86,59,45,48), +(4,3,38,1000,1425,37,87,60,46,49), +(4,3,39,1043,1470,38,89,62,47,50), +(4,3,40,1087,1515,38,91,63,48,51), +(4,3,41,1132,1560,39,93,64,49,52), +(4,3,42,1178,1605,40,95,66,49,53), +(4,3,43,1225,1650,40,97,67,50,54), +(4,3,44,1273,1695,41,99,68,51,55), +(4,3,45,1322,1740,42,101,70,52,56), +(4,3,46,1372,1785,42,103,71,53,57), +(4,3,47,1423,1830,43,105,72,54,58), +(4,3,48,1475,1875,44,107,74,55,59), +(4,3,49,1528,1920,45,109,75,56,60), +(4,3,50,1582,1965,45,111,77,57,61), +(4,3,51,1637,2010,46,113,78,58,62), +(4,3,52,1693,2055,47,115,79,59,63), +(4,3,53,1750,2100,47,118,81,60,64), +(4,3,54,1808,2145,48,120,82,61,65), +(4,3,55,1867,2190,49,122,84,61,66), +(4,3,56,1927,2235,50,124,85,62,67), +(4,3,57,1988,2280,50,126,87,63,68), +(4,3,58,2050,2325,51,128,88,64,69), +(4,3,59,2113,2370,52,131,90,65,70), +(4,3,60,2177,2415,53,133,91,66,72), +(4,3,61,2363,2596,54,135,93,67,73), +(4,3,62,2558,2777,54,137,94,69,74), +(4,3,63,2762,2958,55,140,96,70,75), +(4,3,64,2975,3139,56,142,97,71,76), +(4,3,65,3197,3335,57,144,99,72,77), +(4,3,66,3429,3516,58,147,101,73,78), +(4,3,67,3671,3697,58,149,102,74,79), +(4,3,68,3923,3878,59,151,104,75,81), +(4,3,69,4185,4059,60,154,105,76,82), +(4,3,70,4458,4255,61,156,107,77,83), +(4,4,1,45,0,18,28,20,20,20), +(4,4,2,62,0,19,29,21,20,20), +(4,4,3,79,0,20,31,21,20,21), +(4,4,4,96,0,20,32,22,20,21), +(4,4,5,113,0,21,34,23,21,21), +(4,4,6,130,0,22,35,24,21,22), +(4,4,7,147,0,23,37,24,21,22), +(4,4,8,164,0,24,38,25,21,23), +(4,4,9,181,0,24,40,26,21,23), +(4,4,10,198,0,25,41,26,21,23), +(4,4,11,215,0,26,43,27,22,24), +(4,4,12,232,0,27,44,28,22,24), +(4,4,13,249,0,28,46,29,22,25), +(4,4,14,266,0,29,48,30,22,25), +(4,4,15,283,0,29,49,30,22,25), +(4,4,16,301,0,30,51,31,23,26), +(4,4,17,320,0,31,52,32,23,26), +(4,4,18,340,0,32,54,33,23,27), +(4,4,19,361,0,33,56,34,23,27), +(4,4,20,383,0,34,57,35,23,28), +(4,4,21,406,0,35,59,35,24,28), +(4,4,22,430,0,36,61,36,24,29), +(4,4,23,455,0,37,63,37,24,29), +(4,4,24,481,0,38,64,38,24,30), +(4,4,25,508,0,39,66,39,25,30), +(4,4,26,536,0,40,68,40,25,31), +(4,4,27,565,0,41,70,41,25,31), +(4,4,28,595,0,42,72,42,25,32), +(4,4,29,626,0,43,73,43,25,32), +(4,4,30,658,0,44,75,43,26,33), +(4,4,31,691,0,45,77,44,26,33), +(4,4,32,725,0,46,79,45,26,34), +(4,4,33,760,0,47,81,46,27,34), +(4,4,34,796,0,48,83,47,27,35), +(4,4,35,833,0,49,85,48,27,35), +(4,4,36,871,0,50,87,49,27,36), +(4,4,37,910,0,51,89,50,28,36), +(4,4,38,950,0,52,91,51,28,37), +(4,4,39,991,0,53,93,52,28,38), +(4,4,40,1033,0,54,95,53,28,38), +(4,4,41,1076,0,56,97,54,29,39), +(4,4,42,1120,0,57,99,55,29,39), +(4,4,43,1165,0,58,101,56,29,40), +(4,4,44,1211,0,59,103,57,30,40), +(4,4,45,1258,0,60,105,59,30,41), +(4,4,46,1306,0,61,107,60,30,42), +(4,4,47,1355,0,62,109,61,31,42), +(4,4,48,1405,0,64,112,62,31,43), +(4,4,49,1456,0,65,114,63,31,44), +(4,4,50,1508,0,66,116,64,32,44), +(4,4,51,1561,0,67,118,65,32,45), +(4,4,52,1615,0,68,120,66,32,45), +(4,4,53,1670,0,70,123,67,33,46), +(4,4,54,1726,0,71,125,69,33,47), +(4,4,55,1783,0,72,127,70,33,47), +(4,4,56,1841,0,73,129,71,34,48), +(4,4,57,1900,0,75,132,72,34,49), +(4,4,58,1960,0,76,134,73,34,49), +(4,4,59,2021,0,77,136,74,35,50), +(4,4,60,2083,0,79,139,76,35,51), +(4,4,61,2272,0,80,141,77,35,51), +(4,4,62,2470,0,81,143,78,36,52), +(4,4,63,2677,0,82,146,79,36,53), +(4,4,64,2893,0,84,148,80,37,54), +(4,4,65,3119,0,85,151,82,37,54), +(4,4,66,3355,0,87,153,83,37,55), +(4,4,67,3601,0,88,156,84,38,56), +(4,4,68,3858,0,89,158,85,38,57), +(4,4,69,4126,0,91,160,87,39,57), +(4,4,70,4405,0,92,163,88,39,58), +(4,5,1,51,160,17,25,19,22,23), +(4,5,2,66,184,17,25,19,23,24), +(4,5,3,81,209,17,25,20,25,26), +(4,5,4,96,235,17,26,20,26,27), +(4,5,5,111,262,18,26,20,27,28), +(4,5,6,126,290,18,26,21,29,30), +(4,5,7,141,319,18,26,21,30,31), +(4,5,8,156,349,18,26,22,31,33), +(4,5,9,171,380,18,27,22,33,34), +(4,5,10,186,412,19,27,22,34,36), +(4,5,11,201,445,19,27,23,36,37), +(4,5,12,216,479,19,27,23,37,39), +(4,5,13,231,514,19,28,24,38,40), +(4,5,14,246,550,19,28,24,40,42), +(4,5,15,261,587,19,28,25,41,43), +(4,5,16,276,625,20,28,25,43,45), +(4,5,17,291,664,20,29,25,44,46), +(4,5,18,306,704,20,29,26,46,48), +(4,5,19,321,745,20,29,26,47,49), +(4,5,20,336,787,21,30,27,49,51), +(4,5,21,351,830,21,30,27,51,53), +(4,5,22,367,874,21,30,28,52,54), +(4,5,23,384,919,21,30,28,54,56), +(4,5,24,402,965,21,31,29,55,58), +(4,5,25,421,1012,22,31,29,57,59), +(4,5,26,441,1060,22,31,30,59,61), +(4,5,27,462,1109,22,32,30,60,63), +(4,5,28,484,1159,22,32,31,62,65), +(4,5,29,507,1210,23,32,31,64,66), +(4,5,30,531,1262,23,33,32,65,68), +(4,5,31,556,1315,23,33,32,67,70), +(4,5,32,582,1369,23,33,33,69,72), +(4,5,33,609,1423,24,34,33,70,73), +(4,5,34,637,1477,24,34,34,72,75), +(4,5,35,666,1531,24,34,34,74,77), +(4,5,36,696,1585,24,35,35,76,79), +(4,5,37,727,1639,25,35,35,78,81), +(4,5,38,759,1693,25,35,36,79,83), +(4,5,39,792,1747,25,36,37,81,85), +(4,5,40,826,1801,26,36,37,83,87), +(4,5,41,861,1855,26,37,38,85,88), +(4,5,42,897,1909,26,37,38,87,90), +(4,5,43,934,1963,27,37,39,89,92), +(4,5,44,972,2017,27,38,39,91,94), +(4,5,45,1011,2071,27,38,40,92,96), +(4,5,46,1051,2125,27,39,41,94,98), +(4,5,47,1092,2179,28,39,41,96,100), +(4,5,48,1134,2233,28,39,42,98,102), +(4,5,49,1177,2287,28,40,43,100,104), +(4,5,50,1221,2341,29,40,43,102,106), +(4,5,51,1266,2395,29,41,44,104,109), +(4,5,52,1312,2449,29,41,44,106,111), +(4,5,53,1359,2503,30,42,45,108,113), +(4,5,54,1407,2557,30,42,46,110,115), +(4,5,55,1456,2611,30,43,46,112,117), +(4,5,56,1506,2665,31,43,47,114,119), +(4,5,57,1557,2719,31,43,48,117,121), +(4,5,58,1609,2773,31,44,48,119,124), +(4,5,59,1662,2827,32,44,49,121,126), +(4,5,60,1716,2881,32,45,50,123,128), +(4,5,61,1886,3050,33,45,51,125,130), +(4,5,62,2064,3204,33,46,51,127,132), +(4,5,63,2250,3373,33,46,52,129,135), +(4,5,64,2444,3527,34,47,53,132,137), +(4,5,65,2646,3696,34,47,53,134,139), +(4,5,66,2857,3850,34,48,54,136,142), +(4,5,67,3077,4019,35,48,55,138,144), +(4,5,68,3306,4173,35,49,56,140,146), +(4,5,69,3544,4342,36,49,56,143,149), +(4,5,70,3791,4511,36,50,57,145,151), +(4,11,1,53,100,18,25,19,22,22), +(4,11,2,70,122,19,25,20,23,23), +(4,11,3,87,145,19,26,20,24,24), +(4,11,4,104,169,20,26,21,25,26), +(4,11,5,121,194,20,27,22,26,27), +(4,11,6,138,220,21,27,22,27,28), +(4,11,7,155,247,21,28,23,28,29), +(4,11,8,172,275,22,28,24,29,30), +(4,11,9,189,304,23,29,24,30,32), +(4,11,10,206,334,23,29,25,32,33), +(4,11,11,223,365,24,30,26,33,34), +(4,11,12,240,397,24,31,26,34,35), +(4,11,13,257,430,25,31,27,35,37), +(4,11,14,274,464,26,32,28,36,38), +(4,11,15,291,499,26,32,29,37,39), +(4,11,16,308,535,27,33,29,38,41), +(4,11,17,325,572,28,33,30,40,42), +(4,11,18,343,610,28,34,31,41,43), +(4,11,19,362,649,29,35,32,42,45), +(4,11,20,382,689,30,35,32,43,46), +(4,11,21,403,730,30,36,33,45,48), +(4,11,22,425,772,31,36,34,46,49), +(4,11,23,448,815,32,37,35,47,51), +(4,11,24,472,859,32,38,36,48,52), +(4,11,25,497,904,33,38,36,50,53), +(4,11,26,523,949,34,39,37,51,55), +(4,11,27,550,994,35,40,38,52,56), +(4,11,28,578,1039,35,40,39,54,58), +(4,11,29,607,1084,36,41,40,55,59), +(4,11,30,637,1129,37,42,41,56,61), +(4,11,31,668,1174,38,42,42,58,62), +(4,11,32,700,1219,38,43,42,59,64), +(4,11,33,733,1264,39,44,43,60,66), +(4,11,34,767,1309,40,44,44,62,67), +(4,11,35,802,1354,41,45,45,63,69), +(4,11,36,838,1399,42,46,46,65,70), +(4,11,37,875,1444,42,47,47,66,72), +(4,11,38,913,1489,43,47,48,67,74), +(4,11,39,952,1534,44,48,49,69,75), +(4,11,40,992,1579,45,49,50,70,77), +(4,11,41,1033,1624,46,50,51,72,79), +(4,11,42,1075,1669,46,50,52,73,80), +(4,11,43,1118,1714,47,51,53,75,82), +(4,11,44,1162,1759,48,52,54,76,84), +(4,11,45,1207,1804,49,53,55,78,85), +(4,11,46,1253,1849,50,54,56,79,87), +(4,11,47,1300,1894,51,54,57,81,89), +(4,11,48,1348,1939,52,55,58,83,91), +(4,11,49,1397,1984,53,56,59,84,93), +(4,11,50,1447,2029,53,57,60,86,94), +(4,11,51,1498,2074,54,58,61,87,96), +(4,11,52,1550,2119,55,59,62,89,98), +(4,11,53,1603,2164,56,59,63,91,100), +(4,11,54,1657,2209,57,60,64,92,102), +(4,11,55,1712,2254,58,61,65,94,103), +(4,11,56,1768,2299,59,62,66,95,105), +(4,11,57,1825,2344,60,63,67,97,107), +(4,11,58,1883,2389,61,64,68,99,109), +(4,11,59,1942,2434,62,65,69,101,111), +(4,11,60,2002,2479,63,66,70,102,113), +(4,11,61,2177,2607,64,66,72,104,115), +(4,11,62,2363,2750,65,67,73,106,117), +(4,11,63,2560,2893,66,68,74,107,119), +(4,11,64,2768,3036,67,69,75,109,121), +(4,11,65,2987,3179,68,70,76,111,123), +(4,11,66,3217,3322,69,71,77,113,125), +(4,11,67,3459,3465,70,72,78,115,127), +(4,11,68,3713,3608,71,73,80,116,129), +(4,11,69,3979,3751,72,74,81,118,131), +(4,11,70,4257,3894,73,75,82,120,133), +(5,1,1,70,0,22,18,23,18,25), +(5,1,2,89,0,23,19,24,18,25), +(5,1,3,108,0,25,20,25,18,26), +(5,1,4,127,0,26,20,26,18,26), +(5,1,5,146,0,27,21,28,18,26), +(5,1,6,165,0,29,22,29,18,26), +(5,1,7,184,0,30,23,30,19,27), +(5,1,8,203,0,31,24,31,19,27), +(5,1,9,222,0,33,25,33,19,27), +(5,1,10,241,0,34,25,34,19,28), +(5,1,11,260,0,35,26,35,19,28), +(5,1,12,279,0,37,27,36,19,28), +(5,1,13,298,0,38,28,38,19,28), +(5,1,14,318,0,40,29,39,19,29), +(5,1,15,339,0,41,30,40,19,29), +(5,1,16,361,0,43,31,42,20,29), +(5,1,17,384,0,44,32,43,20,30), +(5,1,18,408,0,46,33,44,20,30), +(5,1,19,433,0,47,34,46,20,31), +(5,1,20,459,0,49,34,47,20,31), +(5,1,21,486,0,50,35,49,20,31), +(5,1,22,514,0,52,36,50,20,32), +(5,1,23,543,0,53,37,51,21,32), +(5,1,24,573,0,55,38,53,21,32), +(5,1,25,604,0,57,39,54,21,33), +(5,1,26,636,0,58,40,56,21,33), +(5,1,27,669,0,60,41,57,21,34), +(5,1,28,703,0,62,42,59,21,34), +(5,1,29,738,0,63,43,60,21,34), +(5,1,30,774,0,65,44,62,22,35), +(5,1,31,811,0,67,46,63,22,35), +(5,1,32,849,0,68,47,65,22,36), +(5,1,33,888,0,70,48,67,22,36), +(5,1,34,928,0,72,49,68,22,36), +(5,1,35,969,0,74,50,70,23,37), +(5,1,36,1011,0,75,51,71,23,37), +(5,1,37,1055,0,77,52,73,23,38), +(5,1,38,1101,0,79,53,75,23,38), +(5,1,39,1149,0,81,54,76,23,39), +(5,1,40,1199,0,83,55,78,24,39), +(5,1,41,1251,0,84,57,80,24,40), +(5,1,42,1305,0,86,58,81,24,40), +(5,1,43,1361,0,88,59,83,24,41), +(5,1,44,1419,0,90,60,85,24,41), +(5,1,45,1479,0,92,61,86,25,42), +(5,1,46,1541,0,94,62,88,25,42), +(5,1,47,1605,0,96,64,90,25,43), +(5,1,48,1671,0,98,65,92,25,43), +(5,1,49,1739,0,100,66,93,25,44), +(5,1,50,1809,0,102,67,95,26,44), +(5,1,51,1881,0,104,69,97,26,45), +(5,1,52,1955,0,106,70,99,26,45), +(5,1,53,2031,0,108,71,101,26,46), +(5,1,54,2109,0,110,72,103,27,46), +(5,1,55,2189,0,112,74,104,27,47), +(5,1,56,2271,0,114,75,106,27,48), +(5,1,57,2355,0,116,76,108,27,48), +(5,1,58,2441,0,118,78,110,28,49), +(5,1,59,2529,0,120,79,112,28,49), +(5,1,60,2619,0,122,80,114,28,50), +(5,1,61,2852,0,124,82,116,28,50), +(5,1,62,3099,0,126,83,118,29,51), +(5,1,63,3360,0,128,84,120,29,52), +(5,1,64,3635,0,131,86,122,29,52), +(5,1,65,3925,0,133,87,124,30,53), +(5,1,66,4230,0,135,88,126,30,53), +(5,1,67,4550,0,137,90,128,30,54), +(5,1,68,4886,0,139,91,130,30,55), +(5,1,69,5238,0,142,93,132,31,55), +(5,1,70,5606,0,144,94,134,31,56), +(5,4,1,65,0,20,21,22,18,25), +(5,4,2,82,0,21,22,23,18,25), +(5,4,3,99,0,22,24,23,18,26), +(5,4,4,116,0,22,25,24,18,26), +(5,4,5,133,0,23,27,25,19,26), +(5,4,6,150,0,24,28,25,19,27), +(5,4,7,167,0,25,30,26,19,27), +(5,4,8,184,0,25,31,27,19,27), +(5,4,9,201,0,26,33,28,19,28), +(5,4,10,218,0,27,34,28,19,28), +(5,4,11,235,0,28,36,29,20,29), +(5,4,12,252,0,29,38,30,20,29), +(5,4,13,269,0,30,39,31,20,29), +(5,4,14,286,0,31,41,32,20,30), +(5,4,15,303,0,31,42,32,20,30), +(5,4,16,321,0,32,44,33,21,31), +(5,4,17,340,0,33,46,34,21,31), +(5,4,18,360,0,34,47,35,21,32), +(5,4,19,381,0,35,49,36,21,32), +(5,4,20,403,0,36,51,36,21,32), +(5,4,21,426,0,37,52,37,22,33), +(5,4,22,450,0,38,54,38,22,33), +(5,4,23,475,0,39,56,39,22,34), +(5,4,24,501,0,40,58,40,22,34), +(5,4,25,528,0,41,60,41,23,35), +(5,4,26,556,0,42,61,42,23,35), +(5,4,27,585,0,43,63,43,23,36), +(5,4,28,615,0,44,65,44,23,36), +(5,4,29,646,0,45,67,44,24,37), +(5,4,30,678,0,46,69,45,24,37), +(5,4,31,711,0,47,71,46,24,38), +(5,4,32,745,0,48,72,47,24,38), +(5,4,33,780,0,49,74,48,25,39), +(5,4,34,816,0,50,76,49,25,39), +(5,4,35,853,0,51,78,50,25,40), +(5,4,36,891,0,52,80,51,25,41), +(5,4,37,930,0,53,82,52,26,41), +(5,4,38,970,0,54,84,53,26,42), +(5,4,39,1011,0,55,86,54,26,42), +(5,4,40,1053,0,56,88,55,27,43), +(5,4,41,1096,0,57,90,56,27,43), +(5,4,42,1140,0,59,92,57,27,44), +(5,4,43,1185,0,60,94,58,27,45), +(5,4,44,1231,0,61,96,59,28,45), +(5,4,45,1278,0,62,99,60,28,46), +(5,4,46,1326,0,63,101,61,28,46), +(5,4,47,1375,0,64,103,63,29,47), +(5,4,48,1425,0,66,105,64,29,48), +(5,4,49,1476,0,67,107,65,29,48), +(5,4,50,1528,0,68,109,66,30,49), +(5,4,51,1581,0,69,111,67,30,50), +(5,4,52,1635,0,70,114,68,30,50), +(5,4,53,1690,0,72,116,69,31,51), +(5,4,54,1746,0,73,118,70,31,52), +(5,4,55,1803,0,74,120,72,31,52), +(5,4,56,1861,0,75,123,73,32,53), +(5,4,57,1920,0,77,125,74,32,54), +(5,4,58,1980,0,78,127,75,32,54), +(5,4,59,2041,0,79,130,76,33,55), +(5,4,60,2103,0,81,132,77,33,56), +(5,4,61,2292,0,82,134,79,34,56), +(5,4,62,2490,0,83,137,80,34,57), +(5,4,63,2697,0,84,139,81,34,58), +(5,4,64,2913,0,86,141,82,35,59), +(5,4,65,3139,0,87,144,84,35,59), +(5,4,66,3375,0,88,146,85,35,60), +(5,4,67,3621,0,90,149,86,36,61), +(5,4,68,3878,0,91,151,87,36,61), +(5,4,69,4146,0,93,154,89,37,62), +(5,4,70,4425,0,94,156,90,37,63), +(5,5,1,62,130,19,18,21,20,28), +(5,5,2,77,154,19,18,21,21,29), +(5,5,3,92,179,19,18,22,23,31), +(5,5,4,107,205,19,19,22,24,32), +(5,5,5,122,232,20,19,22,25,33), +(5,5,6,137,260,20,19,23,27,35), +(5,5,7,152,289,20,19,23,28,36), +(5,5,8,167,319,20,20,24,29,38), +(5,5,9,182,350,20,20,24,31,39), +(5,5,10,197,382,20,20,24,32,40), +(5,5,11,212,415,21,20,25,34,42), +(5,5,12,227,449,21,21,25,35,43), +(5,5,13,242,484,21,21,26,37,45), +(5,5,14,257,520,21,21,26,38,46), +(5,5,15,272,557,21,21,26,39,48), +(5,5,16,287,595,22,22,27,41,50), +(5,5,17,302,634,22,22,27,42,51), +(5,5,18,317,674,22,22,28,44,53), +(5,5,19,332,715,22,23,28,46,54), +(5,5,20,347,757,22,23,29,47,56), +(5,5,21,362,800,23,23,29,49,57), +(5,5,22,378,844,23,23,30,50,59), +(5,5,23,395,889,23,24,30,52,61), +(5,5,24,413,935,23,24,31,53,62), +(5,5,25,432,982,24,24,31,55,64), +(5,5,26,452,1030,24,25,32,57,66), +(5,5,27,473,1079,24,25,32,58,68), +(5,5,28,495,1129,24,25,33,60,69), +(5,5,29,518,1180,25,26,33,62,71), +(5,5,30,542,1232,25,26,34,63,73), +(5,5,31,567,1285,25,26,34,65,75), +(5,5,32,593,1339,25,27,35,67,76), +(5,5,33,620,1393,26,27,35,69,78), +(5,5,34,648,1447,26,27,36,70,80), +(5,5,35,677,1501,26,28,36,72,82), +(5,5,36,707,1555,26,28,37,74,84), +(5,5,37,738,1609,27,28,37,76,86), +(5,5,38,770,1663,27,29,38,77,87), +(5,5,39,803,1717,27,29,38,79,89), +(5,5,40,837,1771,28,30,39,81,91), +(5,5,41,872,1825,28,30,40,83,93), +(5,5,42,908,1879,28,30,40,85,95), +(5,5,43,945,1933,28,31,41,87,97), +(5,5,44,983,1987,29,31,41,89,99), +(5,5,45,1022,2041,29,32,42,91,101), +(5,5,46,1062,2095,29,32,43,92,103), +(5,5,47,1103,2149,30,32,43,94,105), +(5,5,48,1145,2203,30,33,44,96,107), +(5,5,49,1188,2257,30,33,44,98,109), +(5,5,50,1232,2311,31,34,45,100,111), +(5,5,51,1277,2365,31,34,46,102,113), +(5,5,52,1323,2419,31,35,46,104,115), +(5,5,53,1370,2473,32,35,47,106,118), +(5,5,54,1418,2527,32,35,48,108,120), +(5,5,55,1467,2581,32,36,48,110,122), +(5,5,56,1517,2635,33,36,49,113,124), +(5,5,57,1568,2689,33,37,50,115,126), +(5,5,58,1620,2743,33,37,50,117,128), +(5,5,59,1673,2797,34,38,51,119,131), +(5,5,60,1727,2851,34,38,52,121,133), +(5,5,61,1897,3020,34,39,52,123,135), +(5,5,62,2075,3174,35,39,53,125,137), +(5,5,63,2261,3343,35,40,54,127,140), +(5,5,64,2455,3497,36,40,55,130,142), +(5,5,65,2657,3666,36,41,55,132,144), +(5,5,66,2868,3820,36,41,56,134,147), +(5,5,67,3088,3989,37,41,57,136,149), +(5,5,68,3317,4143,37,42,58,138,151), +(5,5,69,3555,4312,38,42,58,141,154), +(5,5,70,3802,4481,38,43,59,143,156), +(5,8,1,62,135,19,18,21,21,27), +(5,8,2,77,160,19,18,21,22,28), +(5,8,3,92,186,19,18,22,24,30), +(5,8,4,107,213,19,18,22,25,31), +(5,8,5,122,241,19,19,22,26,32), +(5,8,6,137,270,19,19,22,28,34), +(5,8,7,152,300,20,19,23,29,35), +(5,8,8,167,331,20,19,23,31,36), +(5,8,9,182,363,20,19,23,32,38), +(5,8,10,197,396,20,19,24,34,39), +(5,8,11,212,430,20,20,24,35,40), +(5,8,12,227,465,20,20,24,37,42), +(5,8,13,242,501,20,20,25,38,43), +(5,8,14,257,538,20,20,25,40,45), +(5,8,15,272,576,20,20,25,41,46), +(5,8,16,287,615,21,21,26,43,48), +(5,8,17,302,655,21,21,26,44,49), +(5,8,18,317,696,21,21,26,46,51), +(5,8,19,332,738,21,21,27,48,52), +(5,8,20,347,781,21,21,27,49,54), +(5,8,21,362,825,21,22,27,51,55), +(5,8,22,377,870,21,22,28,52,57), +(5,8,23,392,916,21,22,28,54,58), +(5,8,24,408,963,22,22,29,56,60), +(5,8,25,425,1011,22,23,29,57,62), +(5,8,26,443,1060,22,23,29,59,63), +(5,8,27,462,1110,22,23,30,61,65), +(5,8,28,482,1161,22,23,30,63,67), +(5,8,29,503,1212,22,24,31,64,68), +(5,8,30,525,1263,23,24,31,66,70), +(5,8,31,548,1314,23,24,31,68,72), +(5,8,32,572,1365,23,24,32,70,73), +(5,8,33,597,1416,23,25,32,72,75), +(5,8,34,623,1467,23,25,33,73,77), +(5,8,35,650,1518,24,25,33,75,79), +(5,8,36,678,1569,24,25,34,77,80), +(5,8,37,707,1620,24,26,34,79,82), +(5,8,38,737,1671,24,26,35,81,84), +(5,8,39,768,1722,24,26,35,83,86), +(5,8,40,800,1773,24,27,35,85,88), +(5,8,41,833,1824,25,27,36,87,90), +(5,8,42,867,1875,25,27,36,89,91), +(5,8,43,902,1926,25,27,37,90,93), +(5,8,44,938,1977,25,28,37,92,95), +(5,8,45,975,2028,26,28,38,94,97), +(5,8,46,1013,2079,26,28,38,96,99), +(5,8,47,1052,2130,26,29,39,98,101), +(5,8,48,1092,2181,26,29,39,100,103), +(5,8,49,1133,2232,26,29,40,103,105), +(5,8,50,1175,2283,27,30,40,105,107), +(5,8,51,1218,2334,27,30,41,107,109), +(5,8,52,1262,2385,27,30,42,109,111), +(5,8,53,1307,2436,27,31,42,111,113), +(5,8,54,1353,2487,28,31,43,113,115), +(5,8,55,1400,2538,28,31,43,115,117), +(5,8,56,1448,2589,28,32,44,117,119), +(5,8,57,1497,2640,28,32,44,119,121), +(5,8,58,1547,2691,29,32,45,122,123), +(5,8,59,1598,2742,29,33,45,124,126), +(5,8,60,1650,2793,29,33,46,126,128), +(5,8,61,1816,2926,29,34,47,128,130), +(5,8,62,1991,3074,30,34,47,131,132), +(5,8,63,2175,3207,30,34,48,133,134), +(5,8,64,2368,3355,30,35,48,135,136), +(5,8,65,2570,3488,31,35,49,137,139), +(5,8,66,2782,3636,31,35,50,140,141), +(5,8,67,3004,3769,31,36,50,142,143), +(5,8,68,3236,3917,31,36,51,144,145), +(5,8,69,3479,4050,32,37,51,147,148), +(5,8,70,3733,4198,32,37,52,149,150), +(5,9,1,63,110,19,18,22,20,27), +(5,9,2,78,133,19,18,23,21,28), +(5,9,3,93,157,20,19,23,22,29), +(5,9,4,108,182,20,19,24,24,30), +(5,9,5,123,208,20,19,24,25,32), +(5,9,6,138,235,20,20,25,26,33), +(5,9,7,153,263,21,20,25,27,34), +(5,9,8,168,292,21,21,26,28,35), +(5,9,9,183,322,21,21,26,30,36), +(5,9,10,198,353,22,21,27,31,38), +(5,9,11,213,385,22,22,28,32,39), +(5,9,12,228,418,22,22,28,34,40), +(5,9,13,243,452,23,23,29,35,41), +(5,9,14,258,487,23,23,30,36,43), +(5,9,15,273,523,23,24,30,37,44), +(5,9,16,288,560,24,24,31,39,45), +(5,9,17,303,598,24,24,31,40,47), +(5,9,18,319,637,24,25,32,42,48), +(5,9,19,336,677,25,25,33,43,49), +(5,9,20,354,718,25,26,33,44,51), +(5,9,21,373,760,26,26,34,46,52), +(5,9,22,393,803,26,27,35,47,53), +(5,9,23,414,847,26,27,36,49,55), +(5,9,24,436,892,27,28,36,50,56), +(5,9,25,459,938,27,28,37,52,58), +(5,9,26,483,985,27,29,38,53,59), +(5,9,27,508,1033,28,29,38,55,60), +(5,9,28,534,1082,28,30,39,56,62), +(5,9,29,561,1132,29,30,40,58,63), +(5,9,30,589,1183,29,31,41,59,65), +(5,9,31,618,1234,30,31,41,61,66), +(5,9,32,648,1285,30,32,42,62,68), +(5,9,33,679,1336,30,32,43,64,69), +(5,9,34,711,1387,31,33,44,65,71), +(5,9,35,744,1438,31,33,45,67,73), +(5,9,36,778,1489,32,34,45,69,74), +(5,9,37,813,1540,32,34,46,70,76), +(5,9,38,849,1591,33,35,47,72,77), +(5,9,39,886,1642,33,36,48,73,79), +(5,9,40,924,1693,34,36,49,75,81), +(5,9,41,963,1744,34,37,49,77,82), +(5,9,42,1003,1795,35,37,50,78,84), +(5,9,43,1044,1846,35,38,51,80,86), +(5,9,44,1086,1897,36,39,52,82,87), +(5,9,45,1129,1948,36,39,53,84,89), +(5,9,46,1173,1999,37,40,54,85,91), +(5,9,47,1218,2050,37,40,55,87,92), +(5,9,48,1264,2101,38,41,55,89,94), +(5,9,49,1311,2152,38,42,56,91,96), +(5,9,50,1359,2203,39,42,57,92,98), +(5,9,51,1408,2254,39,43,58,94,100), +(5,9,52,1458,2305,40,44,59,96,101), +(5,9,53,1509,2356,40,44,60,98,103), +(5,9,54,1561,2407,41,45,61,100,105), +(5,9,55,1614,2458,41,45,62,102,107), +(5,9,56,1668,2509,42,46,63,103,109), +(5,9,57,1723,2560,42,47,64,105,111), +(5,9,58,1779,2611,43,47,65,107,112), +(5,9,59,1836,2662,43,48,66,109,114), +(5,9,60,1894,2713,44,49,67,111,116), +(5,9,61,2070,2867,45,50,68,113,118), +(5,9,62,2255,3021,45,50,69,115,120), +(5,9,63,2449,3190,46,51,70,117,122), +(5,9,64,2652,3344,46,52,71,119,124), +(5,9,65,2864,3498,47,52,72,121,126), +(5,9,66,3086,3667,48,53,73,123,128), +(5,9,67,3318,3821,48,54,74,125,130), +(5,9,68,3561,3975,49,55,75,127,132), +(5,9,69,3815,4144,49,55,76,129,134), +(5,9,70,4080,4298,50,56,77,131,136), +(6,1,1,80,0,28,15,24,15,22), +(6,1,2,99,0,29,16,25,15,22), +(6,1,3,118,0,31,17,26,15,23), +(6,1,4,137,0,32,17,27,15,23), +(6,1,5,156,0,33,18,29,15,23), +(6,1,6,175,0,34,19,30,15,23), +(6,1,7,194,0,36,20,31,16,24), +(6,1,8,213,0,37,21,32,16,24), +(6,1,9,232,0,38,22,34,16,24), +(6,1,10,251,0,40,22,35,16,25), +(6,1,11,270,0,41,23,36,16,25), +(6,1,12,289,0,43,24,37,16,25), +(6,1,13,308,0,44,25,39,16,26), +(6,1,14,328,0,46,26,40,16,26), +(6,1,15,349,0,47,27,41,17,26), +(6,1,16,371,0,48,28,43,17,27), +(6,1,17,394,0,50,29,44,17,27), +(6,1,18,418,0,51,30,45,17,27), +(6,1,19,443,0,53,31,47,17,28), +(6,1,20,469,0,54,32,48,17,28), +(6,1,21,496,0,56,33,50,17,28), +(6,1,22,524,0,58,34,51,18,29), +(6,1,23,553,0,59,35,52,18,29), +(6,1,24,583,0,61,36,54,18,30), +(6,1,25,614,0,62,37,55,18,30), +(6,1,26,646,0,64,38,57,18,30), +(6,1,27,679,0,66,39,58,18,31), +(6,1,28,713,0,67,40,60,18,31), +(6,1,29,748,0,69,41,61,19,32), +(6,1,30,784,0,71,42,63,19,32), +(6,1,31,821,0,72,43,64,19,32), +(6,1,32,859,0,74,44,66,19,33), +(6,1,33,898,0,76,45,67,19,33), +(6,1,34,938,0,77,46,69,20,34), +(6,1,35,979,0,79,47,71,20,34), +(6,1,36,1021,0,81,48,72,20,35), +(6,1,37,1065,0,83,49,74,20,35), +(6,1,38,1111,0,85,50,76,20,35), +(6,1,39,1159,0,86,51,77,21,36), +(6,1,40,1209,0,88,53,79,21,36), +(6,1,41,1261,0,90,54,81,21,37), +(6,1,42,1315,0,92,55,82,21,37), +(6,1,43,1371,0,94,56,84,21,38), +(6,1,44,1429,0,96,57,86,22,38), +(6,1,45,1489,0,98,58,87,22,39), +(6,1,46,1551,0,99,60,89,22,39), +(6,1,47,1615,0,101,61,91,22,40), +(6,1,48,1681,0,103,62,93,22,40), +(6,1,49,1749,0,105,63,94,23,41), +(6,1,50,1819,0,107,65,96,23,41), +(6,1,51,1891,0,109,66,98,23,42), +(6,1,52,1965,0,111,67,100,23,42), +(6,1,53,2041,0,113,68,102,24,43), +(6,1,54,2119,0,115,70,104,24,44), +(6,1,55,2199,0,117,71,105,24,44), +(6,1,56,2281,0,119,72,107,24,45), +(6,1,57,2365,0,122,73,109,25,45), +(6,1,58,2451,0,124,75,111,25,46), +(6,1,59,2539,0,126,76,113,25,46), +(6,1,60,2629,0,128,77,115,25,47), +(6,1,61,2862,0,130,79,117,26,48), +(6,1,62,3109,0,132,80,119,26,48), +(6,1,63,3370,0,134,81,121,26,49), +(6,1,64,3645,0,137,83,123,26,49), +(6,1,65,3935,0,139,84,125,27,50), +(6,1,66,4240,0,141,85,127,27,51), +(6,1,67,4560,0,143,87,129,27,51), +(6,1,68,4896,0,145,88,131,27,52), +(6,1,69,5248,0,148,90,133,28,52), +(6,1,70,5616,0,150,91,135,28,53), +(6,3,1,76,80,25,18,23,15,23), +(6,3,2,93,100,25,19,24,16,24), +(6,3,3,110,121,26,21,25,16,24), +(6,3,4,127,143,26,22,26,17,25), +(6,3,5,144,166,27,24,27,17,25), +(6,3,6,161,190,27,25,28,18,26), +(6,3,7,178,215,28,26,28,19,27), +(6,3,8,195,241,28,28,29,19,27), +(6,3,9,212,268,28,29,30,20,28), +(6,3,10,229,296,29,31,31,20,29), +(6,3,11,246,325,29,32,32,21,29), +(6,3,12,263,355,30,34,33,22,30), +(6,3,13,280,386,30,35,34,22,31), +(6,3,14,298,418,31,37,35,23,32), +(6,3,15,317,451,31,38,36,24,32), +(6,3,16,337,485,32,40,37,24,33), +(6,3,17,358,520,32,41,39,25,34), +(6,3,18,380,556,33,43,40,26,35), +(6,3,19,403,593,33,45,41,27,35), +(6,3,20,427,631,34,46,42,27,36), +(6,3,21,452,670,34,48,43,28,37), +(6,3,22,478,710,35,50,44,29,38), +(6,3,23,505,751,35,51,45,29,38), +(6,3,24,533,793,36,53,46,30,39), +(6,3,25,562,836,37,55,47,31,40), +(6,3,26,592,880,37,56,48,32,41), +(6,3,27,623,925,38,58,50,32,42), +(6,3,28,655,970,38,60,51,33,42), +(6,3,29,688,1015,39,62,52,34,43), +(6,3,30,722,1060,39,63,53,35,44), +(6,3,31,757,1105,40,65,54,36,45), +(6,3,32,793,1150,41,67,56,36,46), +(6,3,33,830,1195,41,69,57,37,47), +(6,3,34,868,1240,42,71,58,38,48), +(6,3,35,907,1285,43,72,59,39,48), +(6,3,36,947,1330,43,74,61,40,49), +(6,3,37,988,1375,44,76,62,40,50), +(6,3,38,1030,1420,45,78,63,41,51), +(6,3,39,1073,1465,45,80,64,42,52), +(6,3,40,1117,1510,46,82,66,43,53), +(6,3,41,1162,1555,47,84,67,44,54), +(6,3,42,1208,1600,47,86,68,45,55), +(6,3,43,1255,1645,48,88,70,46,56), +(6,3,44,1303,1690,49,90,71,46,57), +(6,3,45,1352,1735,49,92,72,47,58), +(6,3,46,1402,1780,50,94,74,48,59), +(6,3,47,1453,1825,51,96,75,49,60), +(6,3,48,1505,1870,51,98,77,50,61), +(6,3,49,1558,1915,52,100,78,51,62), +(6,3,50,1612,1960,53,102,79,52,63), +(6,3,51,1667,2005,54,104,81,53,64), +(6,3,52,1723,2050,54,106,82,54,65), +(6,3,53,1780,2095,55,108,84,55,66), +(6,3,54,1838,2140,56,110,85,56,67), +(6,3,55,1897,2185,57,112,87,57,68), +(6,3,56,1957,2230,57,114,88,58,69), +(6,3,57,2018,2275,58,117,90,59,70), +(6,3,58,2080,2320,59,119,91,60,71), +(6,3,59,2143,2365,60,121,93,61,72), +(6,3,60,2207,2410,61,123,94,62,74), +(6,3,61,2393,2591,61,125,96,63,75), +(6,3,62,2588,2772,62,128,97,64,76), +(6,3,63,2792,2953,63,130,99,65,77), +(6,3,64,3005,3134,64,132,100,66,78), +(6,3,65,3227,3330,65,134,102,67,79), +(6,3,66,3459,3511,66,137,104,68,80), +(6,3,67,3701,3692,66,139,105,69,81), +(6,3,68,3953,3873,67,141,107,70,83), +(6,3,69,4215,4054,68,144,108,71,84), +(6,3,70,4488,4250,69,146,110,72,85), +(6,7,1,77,71,26,15,23,16,24), +(6,7,2,94,92,27,15,24,17,25), +(6,7,3,111,114,28,16,25,18,26), +(6,7,4,128,137,28,16,26,19,27), +(6,7,5,145,161,29,17,27,20,28), +(6,7,6,162,186,30,17,28,21,29), +(6,7,7,179,212,31,18,29,22,30), +(6,7,8,196,239,32,18,30,23,31), +(6,7,9,213,267,33,19,31,24,32), +(6,7,10,230,296,34,19,32,25,33), +(6,7,11,247,326,35,20,33,26,35), +(6,7,12,264,357,35,20,34,27,36), +(6,7,13,281,389,36,21,35,28,37), +(6,7,14,298,422,37,21,36,29,38), +(6,7,15,315,456,38,22,37,30,39), +(6,7,16,332,491,39,22,39,31,40), +(6,7,17,350,527,40,23,40,32,42), +(6,7,18,369,564,41,23,41,33,43), +(6,7,19,389,602,42,24,42,34,44), +(6,7,20,410,641,43,24,43,35,45), +(6,7,21,432,681,44,25,44,36,46), +(6,7,22,455,722,45,25,45,37,48), +(6,7,23,479,764,46,26,47,38,49), +(6,7,24,504,807,47,27,48,40,50), +(6,7,25,530,851,48,27,49,41,51), +(6,7,26,557,896,49,28,50,42,53), +(6,7,27,585,942,51,28,52,43,54), +(6,7,28,614,989,52,29,53,44,55), +(6,7,29,644,1037,53,29,54,45,57), +(6,7,30,675,1086,54,30,55,47,58), +(6,7,31,707,1136,55,31,57,48,59), +(6,7,32,740,1187,56,31,58,49,61), +(6,7,33,774,1238,57,32,59,50,62), +(6,7,34,809,1289,58,33,61,51,64), +(6,7,35,845,1340,60,33,62,53,65), +(6,7,36,882,1391,61,34,63,54,66), +(6,7,37,920,1442,62,34,65,55,68), +(6,7,38,959,1493,63,35,66,57,69), +(6,7,39,999,1544,64,36,67,58,71), +(6,7,40,1040,1595,66,36,69,59,72), +(6,7,41,1082,1646,67,37,70,60,74), +(6,7,42,1125,1697,68,38,72,62,75), +(6,7,43,1169,1748,69,38,73,63,77), +(6,7,44,1214,1799,70,39,74,64,78), +(6,7,45,1260,1850,72,40,76,66,80), +(6,7,46,1307,1901,73,41,77,67,81), +(6,7,47,1355,1952,74,41,79,69,83), +(6,7,48,1404,2003,76,42,80,70,84), +(6,7,49,1454,2054,77,43,82,71,86), +(6,7,50,1505,2105,78,43,83,73,88), +(6,7,51,1557,2156,80,44,85,74,89), +(6,7,52,1610,2207,81,45,86,76,91), +(6,7,53,1664,2258,82,46,88,77,92), +(6,7,54,1719,2309,84,46,90,78,94), +(6,7,55,1775,2360,85,47,91,80,96), +(6,7,56,1832,2411,86,48,93,81,97), +(6,7,57,1890,2462,88,49,94,83,99), +(6,7,58,1949,2513,89,49,96,84,101), +(6,7,59,2009,2564,91,50,97,86,102), +(6,7,60,2070,2615,92,51,99,87,104), +(6,7,61,2238,2774,94,52,101,89,106), +(6,7,62,2414,2933,95,52,102,90,108), +(6,7,63,2598,3107,96,53,104,92,109), +(6,7,64,2790,3266,98,54,106,93,111), +(6,7,65,2991,3425,99,55,107,95,113), +(6,7,66,3201,3599,101,56,109,97,115), +(6,7,67,3421,3758,102,57,111,98,117), +(6,7,68,3651,3917,104,57,113,100,118), +(6,7,69,3891,4091,105,58,114,101,120), +(6,7,70,4141,4250,107,59,116,103,122), +(6,11,1,74,67,26,15,22,17,24), +(6,11,2,91,89,27,16,23,18,25), +(6,11,3,108,112,27,16,23,19,26), +(6,11,4,125,136,28,17,24,20,27), +(6,11,5,142,161,28,17,25,21,29), +(6,11,6,159,187,29,18,25,22,30), +(6,11,7,176,214,29,18,26,23,31), +(6,11,8,193,242,30,19,27,24,32), +(6,11,9,210,271,30,19,27,26,34), +(6,11,10,227,301,31,20,28,27,35), +(6,11,11,244,332,32,20,29,28,36), +(6,11,12,261,364,32,21,29,29,37), +(6,11,13,278,397,33,21,30,30,39), +(6,11,14,295,431,33,22,31,31,40), +(6,11,15,312,466,34,23,32,32,41), +(6,11,16,329,502,35,23,32,34,43), +(6,11,17,346,539,35,24,33,35,44), +(6,11,18,364,577,36,24,34,36,45), +(6,11,19,383,616,37,25,35,37,47), +(6,11,20,403,656,37,26,35,39,48), +(6,11,21,424,697,38,26,36,40,50), +(6,11,22,446,739,39,27,37,41,51), +(6,11,23,469,782,39,28,38,42,52), +(6,11,24,493,826,40,28,39,44,54), +(6,11,25,518,871,41,29,39,45,55), +(6,11,26,544,916,41,30,40,46,57), +(6,11,27,571,961,42,30,41,47,58), +(6,11,28,599,1006,43,31,42,49,60), +(6,11,29,628,1051,44,32,43,50,61), +(6,11,30,658,1096,44,32,44,52,63), +(6,11,31,689,1141,45,33,44,53,64), +(6,11,32,721,1186,46,34,45,54,66), +(6,11,33,754,1231,47,34,46,56,67), +(6,11,34,788,1276,47,35,47,57,69), +(6,11,35,823,1321,48,36,48,58,71), +(6,11,36,859,1366,49,36,49,60,72), +(6,11,37,896,1411,50,37,50,61,74), +(6,11,38,934,1456,51,38,51,63,76), +(6,11,39,973,1501,52,39,52,64,77), +(6,11,40,1013,1546,52,39,53,66,79), +(6,11,41,1054,1591,53,40,54,67,81), +(6,11,42,1096,1636,54,41,55,69,82), +(6,11,43,1139,1681,55,42,56,70,84), +(6,11,44,1183,1726,56,43,57,72,86), +(6,11,45,1228,1771,57,43,57,73,87), +(6,11,46,1274,1816,57,44,58,75,89), +(6,11,47,1321,1861,58,45,60,76,91), +(6,11,48,1369,1906,59,46,61,78,93), +(6,11,49,1418,1951,60,47,62,79,94), +(6,11,50,1468,1996,61,47,63,81,96), +(6,11,51,1519,2041,62,48,64,83,98), +(6,11,52,1571,2086,63,49,65,84,100), +(6,11,53,1624,2131,64,50,66,86,102), +(6,11,54,1678,2176,65,51,67,87,104), +(6,11,55,1733,2221,66,51,68,89,105), +(6,11,56,1789,2266,67,52,69,91,107), +(6,11,57,1846,2311,68,53,70,92,109), +(6,11,58,1904,2356,69,54,71,94,111), +(6,11,59,1963,2401,70,55,72,96,113), +(6,11,60,2023,2446,71,56,73,97,115), +(6,11,61,2198,2574,72,57,74,99,117), +(6,11,62,2384,2717,73,58,76,101,119), +(6,11,63,2581,2860,74,59,77,103,121), +(6,11,64,2789,3003,75,59,78,104,123), +(6,11,65,3008,3146,76,60,79,106,125), +(6,11,66,3238,3289,77,61,80,108,127), +(6,11,67,3480,3432,78,62,81,110,129), +(6,11,68,3734,3575,79,63,83,111,131), +(6,11,69,4000,3718,80,64,84,113,133), +(6,11,70,4278,3861,81,65,85,115,135), +(7,1,1,50,0,18,23,21,24,20), +(7,1,2,69,0,19,24,22,24,20), +(7,1,3,88,0,21,25,23,24,21), +(7,1,4,107,0,22,25,25,24,21), +(7,1,5,126,0,23,26,26,24,21), +(7,1,6,145,0,25,27,27,24,21), +(7,1,7,164,0,26,28,28,24,22), +(7,1,8,183,0,27,29,29,25,22), +(7,1,9,202,0,29,29,31,25,22), +(7,1,10,221,0,30,30,32,25,23), +(7,1,11,240,0,32,31,33,25,23), +(7,1,12,259,0,33,32,34,25,23), +(7,1,13,278,0,34,33,36,25,24), +(7,1,14,298,0,36,34,37,25,24), +(7,1,15,319,0,37,35,38,25,24), +(7,1,16,341,0,39,36,40,25,25), +(7,1,17,364,0,40,36,41,25,25), +(7,1,18,388,0,42,37,43,26,25), +(7,1,19,413,0,43,38,44,26,26), +(7,1,20,439,0,45,39,45,26,26), +(7,1,21,466,0,47,40,47,26,26), +(7,1,22,494,0,48,41,48,26,27), +(7,1,23,523,0,50,42,50,26,27), +(7,1,24,553,0,51,43,51,26,28), +(7,1,25,584,0,53,44,52,27,28), +(7,1,26,616,0,55,45,54,27,28), +(7,1,27,649,0,56,46,55,27,29), +(7,1,28,683,0,58,47,57,27,29), +(7,1,29,718,0,59,48,58,27,30), +(7,1,30,754,0,61,49,60,27,30), +(7,1,31,791,0,63,50,62,27,30), +(7,1,32,829,0,65,51,63,28,31), +(7,1,33,868,0,66,52,65,28,31), +(7,1,34,908,0,68,53,66,28,32), +(7,1,35,949,0,70,55,68,28,32), +(7,1,36,991,0,72,56,69,28,33), +(7,1,37,1035,0,73,57,71,29,33), +(7,1,38,1081,0,75,58,73,29,34), +(7,1,39,1129,0,77,59,74,29,34), +(7,1,40,1179,0,79,60,76,29,35), +(7,1,41,1231,0,81,61,78,29,35), +(7,1,42,1285,0,82,62,79,30,35), +(7,1,43,1341,0,84,64,81,30,36), +(7,1,44,1399,0,86,65,83,30,36), +(7,1,45,1459,0,88,66,85,30,37), +(7,1,46,1521,0,90,67,86,30,37), +(7,1,47,1585,0,92,68,88,31,38), +(7,1,48,1651,0,94,70,90,31,38), +(7,1,49,1719,0,96,71,92,31,39), +(7,1,50,1789,0,98,72,93,31,40), +(7,1,51,1861,0,100,73,95,32,40), +(7,1,52,1935,0,102,75,97,32,41), +(7,1,53,2011,0,104,76,99,32,41), +(7,1,54,2089,0,106,77,101,32,42), +(7,1,55,2169,0,108,78,103,33,42), +(7,1,56,2251,0,110,80,104,33,43), +(7,1,57,2335,0,112,81,106,33,43), +(7,1,58,2421,0,114,82,108,33,44), +(7,1,59,2509,0,116,84,110,34,44), +(7,1,60,2599,0,118,85,112,34,45), +(7,1,61,2832,0,120,86,114,34,46), +(7,1,62,3079,0,122,88,116,35,46), +(7,1,63,3340,0,125,89,118,35,47), +(7,1,64,3615,0,127,91,120,35,47), +(7,1,65,3905,0,129,92,122,35,48), +(7,1,66,4210,0,131,93,124,36,49), +(7,1,67,4530,0,133,95,126,36,49), +(7,1,68,4866,0,136,96,128,36,50), +(7,1,69,5218,0,138,98,130,37,50), +(7,1,70,5586,0,140,99,132,37,51), +(7,4,1,45,0,16,26,20,24,20), +(7,4,2,62,0,17,27,21,24,20), +(7,4,3,79,0,18,29,21,24,21), +(7,4,4,96,0,18,30,22,24,21), +(7,4,5,113,0,19,32,23,25,21), +(7,4,6,130,0,20,33,24,25,22), +(7,4,7,147,0,21,35,24,25,22), +(7,4,8,164,0,22,36,25,25,23), +(7,4,9,181,0,22,38,26,25,23), +(7,4,10,198,0,23,39,26,25,23), +(7,4,11,215,0,24,41,27,25,24), +(7,4,12,232,0,25,42,28,26,24), +(7,4,13,249,0,26,44,29,26,25), +(7,4,14,266,0,27,46,30,26,25), +(7,4,15,283,0,28,47,30,26,25), +(7,4,16,301,0,28,49,31,26,26), +(7,4,17,320,0,29,50,32,27,26), +(7,4,18,340,0,30,52,33,27,27), +(7,4,19,361,0,31,54,34,27,27), +(7,4,20,383,0,32,56,35,27,28), +(7,4,21,406,0,33,57,35,27,28), +(7,4,22,430,0,34,59,36,28,29), +(7,4,23,455,0,35,61,37,28,29), +(7,4,24,481,0,36,62,38,28,30), +(7,4,25,508,0,37,64,39,28,30), +(7,4,26,536,0,38,66,40,29,31), +(7,4,27,565,0,39,68,41,29,31), +(7,4,28,595,0,40,70,42,29,32), +(7,4,29,626,0,41,72,43,29,32), +(7,4,30,658,0,42,73,43,29,33), +(7,4,31,691,0,43,75,44,30,33), +(7,4,32,725,0,44,77,45,30,34), +(7,4,33,760,0,45,79,46,30,34), +(7,4,34,796,0,46,81,47,31,35), +(7,4,35,833,0,47,83,48,31,35), +(7,4,36,871,0,48,85,49,31,36), +(7,4,37,910,0,49,87,50,31,36), +(7,4,38,950,0,50,89,51,32,37), +(7,4,39,991,0,51,91,52,32,38), +(7,4,40,1033,0,53,93,53,32,38), +(7,4,41,1076,0,54,95,54,33,39), +(7,4,42,1120,0,55,97,55,33,39), +(7,4,43,1165,0,56,99,56,33,40), +(7,4,44,1211,0,57,101,57,33,40), +(7,4,45,1258,0,58,103,59,34,41), +(7,4,46,1306,0,59,105,60,34,42), +(7,4,47,1355,0,61,107,61,34,42), +(7,4,48,1405,0,62,110,62,35,43), +(7,4,49,1456,0,63,112,63,35,44), +(7,4,50,1508,0,64,114,64,35,44), +(7,4,51,1561,0,65,116,65,36,45), +(7,4,52,1615,0,67,118,66,36,45), +(7,4,53,1670,0,68,121,67,36,46), +(7,4,54,1726,0,69,123,69,37,47), +(7,4,55,1783,0,70,125,70,37,47), +(7,4,56,1841,0,72,127,71,37,48), +(7,4,57,1900,0,73,130,72,38,49), +(7,4,58,1960,0,74,132,73,38,49), +(7,4,59,2021,0,75,134,74,39,50), +(7,4,60,2083,0,77,137,76,39,51), +(7,4,61,2272,0,78,139,77,39,51), +(7,4,62,2470,0,79,141,78,40,52), +(7,4,63,2677,0,81,144,79,40,53), +(7,4,64,2893,0,82,146,80,41,54), +(7,4,65,3119,0,83,149,82,41,54), +(7,4,66,3355,0,85,151,83,41,55), +(7,4,67,3601,0,86,154,84,42,56), +(7,4,68,3858,0,87,156,85,42,57), +(7,4,69,4126,0,89,158,87,43,57), +(7,4,70,4405,0,90,161,88,43,58), +(7,8,1,51,225,15,23,19,27,22), +(7,8,2,66,250,15,23,19,28,23), +(7,8,3,81,276,15,23,20,30,25), +(7,8,4,96,303,15,23,20,31,26), +(7,8,5,111,331,15,24,20,32,27), +(7,8,6,126,360,15,24,20,34,29), +(7,8,7,141,390,16,24,21,35,30), +(7,8,8,156,421,16,24,21,37,31), +(7,8,9,171,453,16,24,21,38,33), +(7,8,10,186,486,16,24,22,40,34), +(7,8,11,201,520,16,25,22,41,36), +(7,8,12,216,555,16,25,22,42,37), +(7,8,13,231,591,16,25,23,44,38), +(7,8,14,246,628,16,25,23,45,40), +(7,8,15,261,666,17,25,23,47,41), +(7,8,16,276,705,17,25,24,49,43), +(7,8,17,291,745,17,26,24,50,44), +(7,8,18,306,786,17,26,24,52,46), +(7,8,19,321,828,17,26,25,53,47), +(7,8,20,336,871,17,26,25,55,49), +(7,8,21,351,915,17,26,26,57,51), +(7,8,22,366,960,18,27,26,58,52), +(7,8,23,381,1006,18,27,26,60,54), +(7,8,24,397,1053,18,27,27,61,55), +(7,8,25,414,1101,18,27,27,63,57), +(7,8,26,432,1150,18,28,27,65,59), +(7,8,27,451,1200,18,28,28,67,60), +(7,8,28,471,1251,18,28,28,68,62), +(7,8,29,492,1302,19,28,29,70,64), +(7,8,30,514,1353,19,29,29,72,65), +(7,8,31,537,1404,19,29,30,74,67), +(7,8,32,561,1455,19,29,30,75,69), +(7,8,33,586,1506,19,29,30,77,70), +(7,8,34,612,1557,20,30,31,79,72), +(7,8,35,639,1608,20,30,31,81,74), +(7,8,36,667,1659,20,30,32,83,76), +(7,8,37,696,1710,20,30,32,85,78), +(7,8,38,726,1761,20,31,33,86,79), +(7,8,39,757,1812,21,31,33,88,81), +(7,8,40,789,1863,21,31,34,90,83), +(7,8,41,822,1914,21,32,34,92,85), +(7,8,42,856,1965,21,32,35,94,87), +(7,8,43,891,2016,21,32,35,96,89), +(7,8,44,927,2067,22,32,36,98,91), +(7,8,45,964,2118,22,33,36,100,92), +(7,8,46,1002,2169,22,33,37,102,94), +(7,8,47,1041,2220,22,33,37,104,96), +(7,8,48,1081,2271,22,34,38,106,98), +(7,8,49,1122,2322,23,34,38,108,100), +(7,8,50,1164,2373,23,34,39,110,102), +(7,8,51,1207,2424,23,35,39,112,104), +(7,8,52,1251,2475,23,35,40,114,106), +(7,8,53,1296,2526,24,35,40,117,108), +(7,8,54,1342,2577,24,36,41,119,110), +(7,8,55,1389,2628,24,36,41,121,112), +(7,8,56,1437,2679,24,37,42,123,114), +(7,8,57,1486,2730,25,37,42,125,117), +(7,8,58,1536,2781,25,37,43,127,119), +(7,8,59,1587,2832,25,38,43,130,121), +(7,8,60,1639,2883,25,38,44,132,123), +(7,8,61,1805,3016,26,38,45,134,125), +(7,8,62,1980,3164,26,39,45,136,127), +(7,8,63,2164,3297,26,39,46,139,129), +(7,8,64,2357,3445,26,40,46,141,132), +(7,8,65,2559,3578,27,40,47,143,134), +(7,8,66,2771,3726,27,40,48,146,136), +(7,8,67,2993,3859,27,41,48,148,138), +(7,8,68,3225,4007,27,41,49,150,140), +(7,8,69,3468,4140,28,42,49,153,143), +(7,8,70,3722,4288,28,42,50,155,145), +(7,9,1,43,200,15,23,20,26,22), +(7,9,2,58,223,15,23,21,27,23), +(7,9,3,73,247,16,24,21,28,24), +(7,9,4,88,272,16,24,22,29,25), +(7,9,5,103,298,16,24,22,31,27), +(7,9,6,118,325,17,25,23,32,28), +(7,9,7,133,353,17,25,23,33,29), +(7,9,8,148,382,17,26,24,34,30), +(7,9,9,163,412,17,26,25,36,31), +(7,9,10,178,443,18,26,25,37,33), +(7,9,11,193,475,18,27,26,38,34), +(7,9,12,208,508,18,27,26,39,35), +(7,9,13,223,542,19,28,27,41,36), +(7,9,14,238,577,19,28,28,42,38), +(7,9,15,253,613,20,28,28,43,39), +(7,9,16,268,650,20,29,29,45,40), +(7,9,17,283,688,20,29,30,46,42), +(7,9,18,299,727,21,30,30,47,43), +(7,9,19,316,767,21,30,31,49,44), +(7,9,20,334,808,21,31,32,50,46), +(7,9,21,353,850,22,31,32,51,47), +(7,9,22,373,893,22,31,33,53,49), +(7,9,23,394,937,23,32,34,54,50), +(7,9,24,416,982,23,32,34,56,51), +(7,9,25,439,1028,23,33,35,57,53), +(7,9,26,463,1075,24,33,36,59,54), +(7,9,27,488,1123,24,34,37,60,56), +(7,9,28,514,1172,25,34,37,62,57), +(7,9,29,541,1222,25,35,38,63,59), +(7,9,30,569,1273,25,35,39,65,60), +(7,9,31,598,1324,26,36,40,66,62), +(7,9,32,628,1375,26,36,40,68,63), +(7,9,33,659,1426,27,37,41,69,65), +(7,9,34,691,1477,27,38,42,71,66), +(7,9,35,724,1528,28,38,43,73,68), +(7,9,36,758,1579,28,39,43,74,69), +(7,9,37,793,1630,28,39,44,76,71), +(7,9,38,829,1681,29,40,45,77,73), +(7,9,39,866,1732,29,40,46,79,74), +(7,9,40,904,1783,30,41,47,81,76), +(7,9,41,943,1834,30,41,48,82,78), +(7,9,42,983,1885,31,42,48,84,79), +(7,9,43,1024,1936,31,43,49,86,81), +(7,9,44,1066,1987,32,43,50,88,83), +(7,9,45,1109,2038,32,44,51,89,84), +(7,9,46,1153,2089,33,44,52,91,86), +(7,9,47,1198,2140,33,45,53,93,88), +(7,9,48,1244,2191,34,46,54,95,89), +(7,9,49,1291,2242,34,46,54,96,91), +(7,9,50,1339,2293,35,47,55,98,93), +(7,9,51,1388,2344,35,48,56,100,95), +(7,9,52,1438,2395,36,48,57,102,97), +(7,9,53,1489,2446,36,49,58,104,98), +(7,9,54,1541,2497,37,50,59,105,100), +(7,9,55,1594,2548,37,50,60,107,102), +(7,9,56,1648,2599,38,51,61,109,104), +(7,9,57,1703,2650,38,52,62,111,106), +(7,9,58,1759,2701,39,52,63,113,108), +(7,9,59,1816,2752,40,53,64,115,109), +(7,9,60,1874,2803,40,54,65,117,111), +(7,9,61,2050,2957,41,54,66,119,113), +(7,9,62,2235,3111,41,55,67,121,115), +(7,9,63,2429,3280,42,56,68,123,117), +(7,9,64,2632,3434,42,57,69,125,119), +(7,9,65,2844,3588,43,57,70,127,121), +(7,9,66,3066,3757,44,58,71,129,123), +(7,9,67,3298,3911,44,59,72,131,125), +(7,9,68,3541,4065,45,59,73,133,127), +(7,9,69,3795,4234,45,60,74,135,129), +(7,9,70,4060,4388,46,61,75,137,131), +(8,1,1,70,0,24,22,23,16,21), +(8,1,2,89,0,25,23,24,16,21), +(8,1,3,108,0,27,24,25,16,22), +(8,1,4,127,0,28,24,26,16,22), +(8,1,5,146,0,29,25,28,16,22), +(8,1,6,165,0,31,26,29,16,22), +(8,1,7,184,0,32,27,30,17,23), +(8,1,8,203,0,33,28,31,17,23), +(8,1,9,222,0,35,28,33,17,23), +(8,1,10,241,0,36,29,34,17,24), +(8,1,11,260,0,37,30,35,17,24), +(8,1,12,279,0,39,31,36,17,24), +(8,1,13,298,0,40,32,38,17,25), +(8,1,14,318,0,42,33,39,17,25), +(8,1,15,339,0,43,34,40,18,25), +(8,1,16,361,0,45,35,42,18,26), +(8,1,17,384,0,46,35,43,18,26), +(8,1,18,408,0,48,36,44,18,26), +(8,1,19,433,0,49,37,46,18,27), +(8,1,20,459,0,51,38,47,18,27), +(8,1,21,486,0,52,39,49,18,27), +(8,1,22,514,0,54,40,50,18,28), +(8,1,23,543,0,55,41,51,19,28), +(8,1,24,573,0,57,42,53,19,29), +(8,1,25,604,0,59,43,54,19,29), +(8,1,26,636,0,60,44,56,19,29), +(8,1,27,669,0,62,45,57,19,30), +(8,1,28,703,0,63,46,59,19,30), +(8,1,29,738,0,65,47,60,20,31), +(8,1,30,774,0,67,48,62,20,31), +(8,1,31,811,0,69,49,63,20,31), +(8,1,32,849,0,70,50,65,20,32), +(8,1,33,888,0,72,51,67,20,32), +(8,1,34,928,0,74,53,68,20,33), +(8,1,35,969,0,75,54,70,21,33), +(8,1,36,1011,0,77,55,71,21,34), +(8,1,37,1055,0,79,56,73,21,34), +(8,1,38,1101,0,81,57,75,21,35), +(8,1,39,1149,0,83,58,76,21,35), +(8,1,40,1199,0,84,59,78,22,35), +(8,1,41,1251,0,86,60,80,22,36), +(8,1,42,1305,0,88,62,81,22,36), +(8,1,43,1361,0,90,63,83,22,37), +(8,1,44,1419,0,92,64,85,22,37), +(8,1,45,1479,0,94,65,86,23,38), +(8,1,46,1541,0,96,66,88,23,38), +(8,1,47,1605,0,98,67,90,23,39), +(8,1,48,1671,0,100,69,92,23,39), +(8,1,49,1739,0,102,70,93,24,40), +(8,1,50,1809,0,103,71,95,24,40), +(8,1,51,1881,0,105,72,97,24,41), +(8,1,52,1955,0,107,74,99,24,42), +(8,1,53,2031,0,109,75,101,25,42), +(8,1,54,2109,0,112,76,103,25,43), +(8,1,55,2189,0,114,78,104,25,43), +(8,1,56,2271,0,116,79,106,25,44), +(8,1,57,2355,0,118,80,108,25,44), +(8,1,58,2441,0,120,81,110,26,45), +(8,1,59,2529,0,122,83,112,26,45), +(8,1,60,2619,0,124,84,114,26,46), +(8,1,61,2852,0,126,85,116,27,47), +(8,1,62,3099,0,128,87,118,27,47), +(8,1,63,3360,0,130,88,120,27,48), +(8,1,64,3635,0,133,90,122,27,48), +(8,1,65,3925,0,135,91,124,28,49), +(8,1,66,4230,0,137,92,126,28,50), +(8,1,67,4550,0,139,94,128,28,50), +(8,1,68,4886,0,141,95,130,28,51), +(8,1,69,5238,0,144,97,132,29,51), +(8,1,70,5606,0,146,98,134,29,52), +(8,3,1,66,81,21,25,22,16,22), +(8,3,2,83,101,21,26,23,17,23), +(8,3,3,100,122,22,28,24,17,23), +(8,3,4,117,144,22,29,25,18,24), +(8,3,5,134,167,23,30,26,18,25), +(8,3,6,151,191,23,32,27,19,25), +(8,3,7,168,216,24,33,28,20,26), +(8,3,8,185,242,24,35,28,20,26), +(8,3,9,202,269,25,36,29,21,27), +(8,3,10,219,297,25,38,30,21,28), +(8,3,11,236,326,25,39,31,22,29), +(8,3,12,253,356,26,41,32,23,29), +(8,3,13,270,387,26,42,33,23,30), +(8,3,14,288,419,27,44,34,24,31), +(8,3,15,307,452,27,45,35,25,31), +(8,3,16,327,486,28,47,36,25,32), +(8,3,17,348,521,28,48,38,26,33), +(8,3,18,370,557,29,50,39,27,34), +(8,3,19,393,594,29,51,40,28,34), +(8,3,20,417,632,30,53,41,28,35), +(8,3,21,442,671,31,55,42,29,36), +(8,3,22,468,711,31,56,43,30,37), +(8,3,23,495,752,32,58,44,30,37), +(8,3,24,523,794,32,60,45,31,38), +(8,3,25,552,837,33,61,46,32,39), +(8,3,26,582,881,33,63,48,33,40), +(8,3,27,613,926,34,65,49,33,41), +(8,3,28,645,971,35,66,50,34,41), +(8,3,29,678,1016,35,68,51,35,42), +(8,3,30,712,1061,36,70,52,36,43), +(8,3,31,747,1106,36,72,53,37,44), +(8,3,32,783,1151,37,73,55,37,45), +(8,3,33,820,1196,38,75,56,38,46), +(8,3,34,858,1241,38,77,57,39,47), +(8,3,35,897,1286,39,79,58,40,48), +(8,3,36,937,1331,39,81,60,41,48), +(8,3,37,978,1376,40,83,61,41,49), +(8,3,38,1020,1421,41,85,62,42,50), +(8,3,39,1063,1466,41,86,63,43,51), +(8,3,40,1107,1511,42,88,65,44,52), +(8,3,41,1152,1556,43,90,66,45,53), +(8,3,42,1198,1601,43,92,67,46,54), +(8,3,43,1245,1646,44,94,69,47,55), +(8,3,44,1293,1691,45,96,70,47,56), +(8,3,45,1342,1736,45,98,71,48,57), +(8,3,46,1392,1781,46,100,73,49,58), +(8,3,47,1443,1826,47,102,74,50,59), +(8,3,48,1495,1871,48,104,76,51,60), +(8,3,49,1548,1916,48,106,77,52,61), +(8,3,50,1602,1961,49,108,78,53,62), +(8,3,51,1657,2006,50,110,80,54,63), +(8,3,52,1713,2051,51,113,81,55,64), +(8,3,53,1770,2096,51,115,83,56,65), +(8,3,54,1828,2141,52,117,84,57,66), +(8,3,55,1887,2186,53,119,86,58,67), +(8,3,56,1947,2231,54,121,87,59,68), +(8,3,57,2008,2276,54,123,89,60,69), +(8,3,58,2070,2321,55,126,90,61,70), +(8,3,59,2133,2366,56,128,92,62,71), +(8,3,60,2197,2411,57,130,93,63,73), +(8,3,61,2383,2592,58,132,95,64,74), +(8,3,62,2578,2773,58,134,96,65,75), +(8,3,63,2782,2954,59,137,98,66,76), +(8,3,64,2995,3135,60,139,99,67,77), +(8,3,65,3217,3331,61,141,101,68,78), +(8,3,66,3449,3512,62,144,103,69,79), +(8,3,67,3691,3693,62,146,104,70,80), +(8,3,68,3943,3874,63,148,106,71,82), +(8,3,69,4205,4055,64,151,107,72,83), +(8,3,70,4478,4251,65,153,109,73,84), +(8,4,1,65,0,22,25,22,16,21), +(8,4,2,82,0,23,26,23,16,21), +(8,4,3,99,0,24,28,23,16,22), +(8,4,4,116,0,24,29,24,16,22), +(8,4,5,133,0,25,31,25,17,22), +(8,4,6,150,0,26,32,25,17,23), +(8,4,7,167,0,27,34,26,17,23), +(8,4,8,184,0,27,35,27,17,24), +(8,4,9,201,0,28,37,28,17,24), +(8,4,10,218,0,29,38,28,18,24), +(8,4,11,235,0,30,40,29,18,25), +(8,4,12,252,0,31,41,30,18,25), +(8,4,13,269,0,32,43,31,18,26), +(8,4,14,286,0,32,45,32,18,26), +(8,4,15,303,0,33,46,32,19,26), +(8,4,16,321,0,34,48,33,19,27), +(8,4,17,340,0,35,50,34,19,27), +(8,4,18,360,0,36,51,35,19,28), +(8,4,19,381,0,37,53,36,19,28), +(8,4,20,403,0,38,55,36,20,29), +(8,4,21,426,0,39,56,37,20,29), +(8,4,22,450,0,40,58,38,20,30), +(8,4,23,475,0,41,60,39,20,30), +(8,4,24,501,0,42,62,40,20,31), +(8,4,25,528,0,43,63,41,21,31), +(8,4,26,556,0,44,65,42,21,32), +(8,4,27,585,0,45,67,43,21,32), +(8,4,28,615,0,46,69,44,21,33), +(8,4,29,646,0,47,71,44,22,33), +(8,4,30,678,0,48,72,45,22,34), +(8,4,31,711,0,49,74,46,22,34), +(8,4,32,745,0,50,76,47,22,35), +(8,4,33,780,0,51,78,48,23,35), +(8,4,34,816,0,52,80,49,23,36), +(8,4,35,853,0,53,82,50,23,36), +(8,4,36,891,0,54,84,51,24,37), +(8,4,37,930,0,55,86,52,24,37), +(8,4,38,970,0,56,88,53,24,38), +(8,4,39,1011,0,57,90,54,24,38), +(8,4,40,1053,0,58,92,55,25,39), +(8,4,41,1096,0,59,94,56,25,40), +(8,4,42,1140,0,60,96,57,25,40), +(8,4,43,1185,0,62,98,58,26,41), +(8,4,44,1231,0,63,100,59,26,41), +(8,4,45,1278,0,64,102,60,26,42), +(8,4,46,1326,0,65,104,61,27,43), +(8,4,47,1375,0,66,107,63,27,43), +(8,4,48,1425,0,67,109,64,27,44), +(8,4,49,1476,0,69,111,65,27,44), +(8,4,50,1528,0,70,113,66,28,45), +(8,4,51,1581,0,71,115,67,28,46), +(8,4,52,1635,0,72,117,68,28,46), +(8,4,53,1690,0,74,120,69,29,47), +(8,4,54,1746,0,75,122,70,29,48), +(8,4,55,1803,0,76,124,72,29,48), +(8,4,56,1861,0,77,126,73,30,49), +(8,4,57,1920,0,79,129,74,30,50), +(8,4,58,1980,0,80,131,75,30,50), +(8,4,59,2041,0,81,133,76,31,51), +(8,4,60,2103,0,82,136,77,31,52), +(8,4,61,2292,0,84,138,79,32,52), +(8,4,62,2490,0,85,140,80,32,53), +(8,4,63,2697,0,86,143,81,32,54), +(8,4,64,2913,0,88,145,82,33,55), +(8,4,65,3139,0,89,148,84,33,55), +(8,4,66,3375,0,90,150,85,33,56), +(8,4,67,3621,0,92,153,86,34,57), +(8,4,68,3878,0,93,155,87,34,58), +(8,4,69,4146,0,95,157,89,35,58), +(8,4,70,4425,0,96,160,90,35,59), +(8,5,1,62,128,21,22,21,18,24), +(8,5,2,77,152,21,22,21,19,25), +(8,5,3,92,177,21,22,22,21,27), +(8,5,4,107,203,21,23,22,22,28), +(8,5,5,122,230,22,23,22,23,29), +(8,5,6,137,258,22,23,23,25,31), +(8,5,7,152,287,22,23,23,26,32), +(8,5,8,167,317,22,24,24,27,34), +(8,5,9,182,348,22,24,24,29,35), +(8,5,10,197,380,22,24,24,30,37), +(8,5,11,212,413,23,24,25,32,38), +(8,5,12,227,447,23,24,25,33,40), +(8,5,13,242,482,23,25,26,35,41), +(8,5,14,257,518,23,25,26,36,43), +(8,5,15,272,555,23,25,26,38,44), +(8,5,16,287,593,24,26,27,39,46), +(8,5,17,302,632,24,26,27,41,47), +(8,5,18,317,672,24,26,28,42,49), +(8,5,19,332,713,24,26,28,44,50), +(8,5,20,347,755,24,27,29,45,52), +(8,5,21,362,798,25,27,29,47,54), +(8,5,22,378,842,25,27,30,48,55), +(8,5,23,395,887,25,28,30,50,57), +(8,5,24,413,933,25,28,31,52,59), +(8,5,25,432,980,25,28,31,53,60), +(8,5,26,452,1028,26,28,32,55,62), +(8,5,27,473,1077,26,29,32,56,64), +(8,5,28,495,1127,26,29,33,58,65), +(8,5,29,518,1178,26,29,33,60,67), +(8,5,30,542,1230,27,30,34,62,69), +(8,5,31,567,1283,27,30,34,63,71), +(8,5,32,593,1337,27,30,35,65,73), +(8,5,33,620,1391,27,31,35,67,74), +(8,5,34,648,1445,28,31,36,68,76), +(8,5,35,677,1499,28,32,36,70,78), +(8,5,36,707,1553,28,32,37,72,80), +(8,5,37,738,1607,29,32,37,74,82), +(8,5,38,770,1661,29,33,38,76,84), +(8,5,39,803,1715,29,33,38,77,86), +(8,5,40,837,1769,29,33,39,79,87), +(8,5,41,872,1823,30,34,40,81,89), +(8,5,42,908,1877,30,34,40,83,91), +(8,5,43,945,1931,30,35,41,85,93), +(8,5,44,983,1985,31,35,41,87,95), +(8,5,45,1022,2039,31,35,42,89,97), +(8,5,46,1062,2093,31,36,43,91,99), +(8,5,47,1103,2147,32,36,43,93,101), +(8,5,48,1145,2201,32,37,44,94,103), +(8,5,49,1188,2255,32,37,44,96,105), +(8,5,50,1232,2309,33,37,45,98,107), +(8,5,51,1277,2363,33,38,46,100,110), +(8,5,52,1323,2417,33,38,46,102,112), +(8,5,53,1370,2471,34,39,47,104,114), +(8,5,54,1418,2525,34,39,48,106,116), +(8,5,55,1467,2579,34,40,48,109,118), +(8,5,56,1517,2633,35,40,49,111,120), +(8,5,57,1568,2687,35,41,50,113,122), +(8,5,58,1620,2741,35,41,50,115,125), +(8,5,59,1673,2795,36,42,51,117,127), +(8,5,60,1727,2849,36,42,52,119,129), +(8,5,61,1897,3018,36,42,52,121,131), +(8,5,62,2075,3172,37,43,53,123,133), +(8,5,63,2261,3341,37,43,54,125,136), +(8,5,64,2455,3495,38,44,55,128,138), +(8,5,65,2657,3664,38,44,55,130,140), +(8,5,66,2868,3818,38,45,56,132,143), +(8,5,67,3088,3987,39,45,57,134,145), +(8,5,68,3317,4141,39,46,58,136,147), +(8,5,69,3555,4310,40,46,58,139,150), +(8,5,70,3802,4479,40,47,59,141,152), +(8,7,1,67,72,22,22,22,17,23), +(8,7,2,84,93,23,22,23,18,24), +(8,7,3,101,115,24,23,24,19,25), +(8,7,4,118,138,25,23,25,20,26), +(8,7,5,135,162,25,24,26,21,27), +(8,7,6,152,187,26,24,27,22,28), +(8,7,7,169,213,27,25,28,23,29), +(8,7,8,186,240,28,25,29,24,30), +(8,7,9,203,268,29,25,30,25,31), +(8,7,10,220,297,30,26,31,26,33), +(8,7,11,237,327,31,26,32,27,34), +(8,7,12,254,358,32,27,33,28,35), +(8,7,13,271,390,33,27,34,29,36), +(8,7,14,288,423,34,28,35,30,37), +(8,7,15,305,457,34,28,36,31,38), +(8,7,16,322,492,35,29,38,32,39), +(8,7,17,340,528,36,29,39,33,41), +(8,7,18,359,565,37,30,40,34,42), +(8,7,19,379,603,38,30,41,35,43), +(8,7,20,400,642,39,31,42,36,44), +(8,7,21,422,682,40,32,43,37,45), +(8,7,22,445,723,41,32,45,38,47), +(8,7,23,469,765,43,33,46,39,48), +(8,7,24,494,808,44,33,47,40,49), +(8,7,25,520,852,45,34,48,42,51), +(8,7,26,547,897,46,34,49,43,52), +(8,7,27,575,943,47,35,51,44,53), +(8,7,28,604,990,48,35,52,45,54), +(8,7,29,634,1038,49,36,53,46,56), +(8,7,30,665,1087,50,37,54,48,57), +(8,7,31,697,1137,51,37,56,49,59), +(8,7,32,730,1188,52,38,57,50,60), +(8,7,33,764,1239,53,38,58,51,61), +(8,7,34,799,1290,55,39,60,52,63), +(8,7,35,835,1341,56,40,61,54,64), +(8,7,36,872,1392,57,40,62,55,66), +(8,7,37,910,1443,58,41,64,56,67), +(8,7,38,949,1494,59,42,65,57,68), +(8,7,39,989,1545,61,42,66,59,70), +(8,7,40,1030,1596,62,43,68,60,71), +(8,7,41,1072,1647,63,44,69,61,73), +(8,7,42,1115,1698,64,44,71,63,74), +(8,7,43,1159,1749,65,45,72,64,76), +(8,7,44,1204,1800,67,46,74,65,77), +(8,7,45,1250,1851,68,46,75,67,79), +(8,7,46,1297,1902,69,47,76,68,80), +(8,7,47,1345,1953,71,48,78,69,82), +(8,7,48,1394,2004,72,49,79,71,83), +(8,7,49,1444,2055,73,49,81,72,85), +(8,7,50,1495,2106,74,50,82,74,87), +(8,7,51,1547,2157,76,51,84,75,88), +(8,7,52,1600,2208,77,51,85,77,90), +(8,7,53,1654,2259,78,52,87,78,92), +(8,7,54,1709,2310,80,53,89,79,93), +(8,7,55,1765,2361,81,54,90,81,95), +(8,7,56,1822,2412,83,55,92,82,96), +(8,7,57,1880,2463,84,55,93,84,98), +(8,7,58,1939,2514,85,56,95,85,100), +(8,7,59,1999,2565,87,57,97,87,102), +(8,7,60,2060,2616,88,58,98,88,103), +(8,7,61,2228,2775,90,58,100,90,105), +(8,7,62,2404,2934,91,59,101,91,107), +(8,7,63,2588,3108,93,60,103,93,108), +(8,7,64,2780,3267,94,61,105,94,110), +(8,7,65,2981,3426,95,62,106,96,112), +(8,7,66,3191,3600,97,63,108,98,114), +(8,7,67,3411,3759,98,63,110,99,116), +(8,7,68,3641,3918,100,64,112,101,117), +(8,7,69,3881,4092,101,65,113,102,119), +(8,7,70,4131,4251,103,66,115,104,121), +(8,8,1,62,119,21,22,21,19,23), +(8,8,2,77,144,21,22,21,20,24), +(8,8,3,92,170,21,22,22,22,26), +(8,8,4,107,197,21,22,22,23,27), +(8,8,5,122,225,21,23,22,25,28), +(8,8,6,137,254,21,23,22,26,30), +(8,8,7,152,284,21,23,23,27,31), +(8,8,8,167,315,22,23,23,29,32), +(8,8,9,182,347,22,23,23,30,34), +(8,8,10,197,380,22,23,24,32,35), +(8,8,11,212,414,22,24,24,33,37), +(8,8,12,227,449,22,24,24,35,38), +(8,8,13,242,485,22,24,25,36,39), +(8,8,14,257,522,22,24,25,38,41), +(8,8,15,272,560,22,24,25,39,42), +(8,8,16,287,599,22,24,26,41,44), +(8,8,17,302,639,23,25,26,42,45), +(8,8,18,317,680,23,25,26,44,47), +(8,8,19,332,722,23,25,27,46,48), +(8,8,20,347,765,23,25,27,47,50), +(8,8,21,362,809,23,25,27,49,51), +(8,8,22,377,854,23,26,28,51,53), +(8,8,23,392,900,23,26,28,52,55), +(8,8,24,408,947,24,26,29,54,56), +(8,8,25,425,995,24,26,29,56,58), +(8,8,26,443,1044,24,27,29,57,60), +(8,8,27,462,1094,24,27,30,59,61), +(8,8,28,482,1145,24,27,30,61,63), +(8,8,29,503,1196,24,27,31,63,65), +(8,8,30,525,1247,24,28,31,64,66), +(8,8,31,548,1298,25,28,31,66,68), +(8,8,32,572,1349,25,28,32,68,70), +(8,8,33,597,1400,25,28,32,70,71), +(8,8,34,623,1451,25,29,33,71,73), +(8,8,35,650,1502,25,29,33,73,75), +(8,8,36,678,1553,26,29,34,75,77), +(8,8,37,707,1604,26,29,34,77,79), +(8,8,38,737,1655,26,30,35,79,80), +(8,8,39,768,1706,26,30,35,81,82), +(8,8,40,800,1757,26,30,35,83,84), +(8,8,41,833,1808,27,31,36,85,86), +(8,8,42,867,1859,27,31,36,87,88), +(8,8,43,902,1910,27,31,37,89,90), +(8,8,44,938,1961,27,32,37,91,91), +(8,8,45,975,2012,27,32,38,93,93), +(8,8,46,1013,2063,28,32,38,95,95), +(8,8,47,1052,2114,28,32,39,97,97), +(8,8,48,1092,2165,28,33,39,99,99), +(8,8,49,1133,2216,28,33,40,101,101), +(8,8,50,1175,2267,29,33,40,103,103), +(8,8,51,1218,2318,29,34,41,105,105), +(8,8,52,1262,2369,29,34,42,107,107), +(8,8,53,1307,2420,29,35,42,109,109), +(8,8,54,1353,2471,30,35,43,111,111), +(8,8,55,1400,2522,30,35,43,113,113), +(8,8,56,1448,2573,30,36,44,115,115), +(8,8,57,1497,2624,30,36,44,118,118), +(8,8,58,1547,2675,31,36,45,120,120), +(8,8,59,1598,2726,31,37,45,122,122), +(8,8,60,1650,2777,31,37,46,124,124), +(8,8,61,1816,2910,31,37,47,126,126), +(8,8,62,1991,3058,32,38,47,129,128), +(8,8,63,2175,3191,32,38,48,131,130), +(8,8,64,2368,3339,32,39,48,133,133), +(8,8,65,2570,3472,33,39,49,135,135), +(8,8,66,2782,3620,33,39,50,138,137), +(8,8,67,3004,3753,33,40,50,140,139), +(8,8,68,3236,3901,33,40,51,142,141), +(8,8,69,3479,4034,34,41,51,145,144), +(8,8,70,3733,4182,34,41,52,147,146), +(10,2,1,38,140,19,22,21,24,20), +(10,2,2,56,159,20,23,22,25,21), +(10,2,3,74,179,21,23,23,25,21), +(10,2,4,92,200,22,24,24,26,22), +(10,2,5,110,222,23,24,25,27,23), +(10,2,6,128,245,25,25,26,27,24), +(10,2,7,146,269,26,25,27,28,24), +(10,2,8,164,294,27,26,28,29,25), +(10,2,9,182,320,28,27,29,29,26), +(10,2,10,200,347,29,27,31,30,26), +(10,2,11,218,375,30,28,32,31,27), +(10,2,12,236,404,32,29,33,31,28), +(10,2,13,254,434,33,29,34,32,29), +(10,2,14,272,465,34,30,35,33,30), +(10,2,15,291,497,35,31,36,33,30), +(10,2,16,311,530,37,31,37,34,31), +(10,2,17,332,564,38,32,39,35,32), +(10,2,18,354,599,39,33,40,36,33), +(10,2,19,377,635,40,33,41,36,34), +(10,2,20,401,672,42,34,42,37,35), +(10,2,21,426,710,43,35,44,38,35), +(10,2,22,452,749,44,35,45,39,36), +(10,2,23,479,789,46,36,46,40,37), +(10,2,24,507,830,47,37,47,40,38), +(10,2,25,536,872,49,38,49,41,39), +(10,2,26,566,914,50,38,50,42,40), +(10,2,27,597,956,51,39,51,43,41), +(10,2,28,629,998,53,40,53,44,42), +(10,2,29,662,1040,54,41,54,45,43), +(10,2,30,696,1082,56,41,55,45,43), +(10,2,31,731,1124,57,42,57,46,44), +(10,2,32,767,1166,58,43,58,47,45), +(10,2,33,804,1208,60,44,59,48,46), +(10,2,34,842,1250,61,45,61,49,47), +(10,2,35,881,1292,63,45,62,50,48), +(10,2,36,921,1334,64,46,64,51,49), +(10,2,37,962,1376,66,47,65,52,50), +(10,2,38,1004,1418,67,48,67,53,51), +(10,2,39,1047,1460,69,49,68,54,52), +(10,2,40,1091,1502,71,50,69,55,53), +(10,2,41,1136,1544,72,50,71,55,54), +(10,2,42,1182,1586,74,51,72,56,55), +(10,2,43,1229,1628,75,52,74,57,56), +(10,2,44,1277,1670,77,53,75,58,57), +(10,2,45,1326,1712,79,54,77,59,59), +(10,2,46,1376,1754,80,55,78,60,60), +(10,2,47,1427,1796,82,56,80,61,61), +(10,2,48,1479,1838,83,57,82,62,62), +(10,2,49,1532,1880,85,58,83,63,63), +(10,2,50,1586,1922,87,59,85,64,64), +(10,2,51,1641,1964,89,60,86,66,65), +(10,2,52,1697,2006,90,61,88,67,66), +(10,2,53,1754,2048,92,61,90,68,67), +(10,2,54,1812,2090,94,62,91,69,69), +(10,2,55,1871,2132,95,63,93,70,70), +(10,2,56,1931,2174,97,64,95,71,71), +(10,2,57,1992,2216,99,65,96,72,72), +(10,2,58,2054,2258,101,66,98,73,73), +(10,2,59,2117,2300,102,67,100,74,74), +(10,2,60,2181,2342,104,68,101,75,76), +(10,2,61,2361,2501,106,69,103,76,77), +(10,2,62,2549,2660,108,70,105,78,78), +(10,2,63,2745,2834,110,72,106,79,79), +(10,2,64,2950,2993,112,73,108,80,80), +(10,2,65,3164,3152,113,74,110,81,82), +(10,2,66,3387,3326,115,75,112,82,83), +(10,2,67,3620,3485,117,76,114,83,84), +(10,2,68,3863,3644,119,77,115,85,85), +(10,2,69,4116,3818,121,78,117,86,87), +(10,2,70,4379,3977,123,79,119,87,88), +(10,3,1,45,145,17,25,20,24,20), +(10,3,2,62,165,17,26,21,25,21), +(10,3,3,79,186,18,28,22,25,21), +(10,3,4,96,208,18,29,23,26,22), +(10,3,5,113,231,19,30,24,26,23), +(10,3,6,130,255,19,32,25,27,23), +(10,3,7,147,280,20,33,26,27,24), +(10,3,8,164,306,20,35,27,28,25), +(10,3,9,181,333,21,36,27,29,25), +(10,3,10,198,361,21,38,28,29,26), +(10,3,11,215,390,22,39,29,30,27), +(10,3,12,232,420,22,41,30,31,27), +(10,3,13,249,451,23,42,31,31,28), +(10,3,14,267,483,23,44,32,32,29), +(10,3,15,286,516,24,45,34,32,29), +(10,3,16,306,550,24,47,35,33,30), +(10,3,17,327,585,25,48,36,34,31), +(10,3,18,349,621,25,50,37,34,32), +(10,3,19,372,658,26,51,38,35,32), +(10,3,20,396,696,26,53,39,36,33), +(10,3,21,421,735,27,55,40,37,34), +(10,3,22,447,775,27,56,41,37,35), +(10,3,23,474,816,28,58,42,38,36), +(10,3,24,502,858,28,60,43,39,36), +(10,3,25,531,901,29,61,44,39,37), +(10,3,26,561,945,30,63,46,40,38), +(10,3,27,592,990,30,65,47,41,39), +(10,3,28,624,1035,31,66,48,42,40), +(10,3,29,657,1080,31,68,49,42,40), +(10,3,30,691,1125,32,70,50,43,41), +(10,3,31,726,1170,33,72,52,44,42), +(10,3,32,762,1215,33,73,53,45,43), +(10,3,33,799,1260,34,75,54,46,44), +(10,3,34,837,1305,34,77,55,46,45), +(10,3,35,876,1350,35,79,57,47,46), +(10,3,36,916,1395,36,81,58,48,47), +(10,3,37,957,1440,36,83,59,49,47), +(10,3,38,999,1485,37,85,60,50,48), +(10,3,39,1042,1530,38,86,62,51,49), +(10,3,40,1086,1575,38,88,63,51,50), +(10,3,41,1131,1620,39,90,64,52,51), +(10,3,42,1177,1665,40,92,66,53,52), +(10,3,43,1224,1710,40,94,67,54,53), +(10,3,44,1272,1755,41,96,68,55,54), +(10,3,45,1321,1800,42,98,70,56,55), +(10,3,46,1371,1845,42,100,71,57,56), +(10,3,47,1422,1890,43,102,72,58,57), +(10,3,48,1474,1935,44,104,74,59,58), +(10,3,49,1527,1980,45,106,75,60,59), +(10,3,50,1581,2025,45,108,77,61,60), +(10,3,51,1636,2070,46,110,78,61,61), +(10,3,52,1692,2115,47,113,79,62,62), +(10,3,53,1749,2160,47,115,81,63,63), +(10,3,54,1807,2205,48,117,82,64,64), +(10,3,55,1866,2250,49,119,84,65,65), +(10,3,56,1926,2295,50,121,85,66,66), +(10,3,57,1987,2340,50,123,87,67,67), +(10,3,58,2049,2385,51,126,88,68,68), +(10,3,59,2112,2430,52,128,90,69,70), +(10,3,60,2176,2475,53,130,91,70,71), +(10,3,61,2362,2656,54,132,93,71,72), +(10,3,62,2557,2837,54,134,94,72,73), +(10,3,63,2761,3018,55,137,96,73,74), +(10,3,64,2974,3199,56,139,97,75,75), +(10,3,65,3196,3395,57,141,99,76,76), +(10,3,66,3428,3576,58,144,101,77,77), +(10,3,67,3670,3757,58,146,102,78,78), +(10,3,68,3922,3938,59,148,104,79,80), +(10,3,69,4184,4119,60,151,105,80,81), +(10,3,70,4457,4315,61,153,107,81,82), +(10,4,1,45,0,18,25,20,24,19), +(10,4,2,62,0,19,26,21,24,19), +(10,4,3,79,0,20,28,21,24,20), +(10,4,4,96,0,20,29,22,24,20), +(10,4,5,113,0,21,31,23,25,20), +(10,4,6,130,0,22,32,24,25,21), +(10,4,7,147,0,23,34,24,25,21), +(10,4,8,164,0,24,35,25,25,22), +(10,4,9,181,0,24,37,26,25,22), +(10,4,10,198,0,25,38,26,25,22), +(10,4,11,215,0,26,40,27,25,23), +(10,4,12,232,0,27,41,28,26,23), +(10,4,13,249,0,28,43,29,26,24), +(10,4,14,266,0,29,45,30,26,24), +(10,4,15,283,0,29,46,30,26,25), +(10,4,16,301,0,30,48,31,26,25), +(10,4,17,320,0,31,50,32,27,25), +(10,4,18,340,0,32,51,33,27,26), +(10,4,19,361,0,33,53,34,27,26), +(10,4,20,383,0,34,55,35,27,27), +(10,4,21,406,0,35,56,35,27,27), +(10,4,22,430,0,36,58,36,28,28), +(10,4,23,455,0,37,60,37,28,28), +(10,4,24,481,0,38,62,38,28,29), +(10,4,25,508,0,39,63,39,28,29), +(10,4,26,536,0,40,65,40,29,30), +(10,4,27,565,0,41,67,41,29,30), +(10,4,28,595,0,42,69,42,29,31), +(10,4,29,626,0,43,71,43,29,31), +(10,4,30,658,0,44,72,43,29,32), +(10,4,31,691,0,45,74,44,30,32), +(10,4,32,725,0,46,76,45,30,33), +(10,4,33,760,0,47,78,46,30,33), +(10,4,34,796,0,48,80,47,31,34), +(10,4,35,833,0,49,82,48,31,34), +(10,4,36,871,0,50,84,49,31,35), +(10,4,37,910,0,51,86,50,31,35), +(10,4,38,950,0,52,88,51,32,36), +(10,4,39,991,0,53,90,52,32,37), +(10,4,40,1033,0,54,92,53,32,37), +(10,4,41,1076,0,56,94,54,33,38), +(10,4,42,1120,0,57,96,55,33,38), +(10,4,43,1165,0,58,98,56,33,39), +(10,4,44,1211,0,59,100,57,33,39), +(10,4,45,1258,0,60,102,59,34,40), +(10,4,46,1306,0,61,104,60,34,41), +(10,4,47,1355,0,62,107,61,34,41), +(10,4,48,1405,0,64,109,62,35,42), +(10,4,49,1456,0,65,111,63,35,43), +(10,4,50,1508,0,66,113,64,35,43), +(10,4,51,1561,0,67,115,65,36,44), +(10,4,52,1615,0,68,117,66,36,44), +(10,4,53,1670,0,70,120,67,36,45), +(10,4,54,1726,0,71,122,69,37,46), +(10,4,55,1783,0,72,124,70,37,46), +(10,4,56,1841,0,73,126,71,37,47), +(10,4,57,1900,0,75,129,72,38,48), +(10,4,58,1960,0,76,131,73,38,48), +(10,4,59,2021,0,77,133,74,39,49), +(10,4,60,2083,0,79,136,76,39,50), +(10,4,61,2272,0,80,138,77,39,51), +(10,4,62,2470,0,81,140,78,40,51), +(10,4,63,2677,0,82,143,79,40,52), +(10,4,64,2893,0,84,145,80,41,53), +(10,4,65,3119,0,85,148,82,41,53), +(10,4,66,3355,0,87,150,83,41,54), +(10,4,67,3601,0,88,153,84,42,55), +(10,4,68,3858,0,89,155,85,42,56), +(10,4,69,4126,0,91,157,87,43,56), +(10,4,70,4405,0,92,160,88,43,57), +(10,5,1,55,220,17,22,19,26,22), +(10,5,2,70,244,17,22,19,27,23), +(10,5,3,85,269,17,22,20,29,25), +(10,5,4,100,295,17,23,20,30,26), +(10,5,5,115,322,18,23,20,31,27), +(10,5,6,130,350,18,23,21,33,29), +(10,5,7,145,379,18,23,21,34,30), +(10,5,8,160,409,18,24,22,35,32), +(10,5,9,175,440,18,24,22,37,33), +(10,5,10,190,472,19,24,22,38,35), +(10,5,11,205,505,19,24,23,39,36), +(10,5,12,220,539,19,24,23,41,38), +(10,5,13,235,574,19,25,24,42,39), +(10,5,14,250,610,19,25,24,44,41), +(10,5,15,265,647,19,25,25,45,42), +(10,5,16,280,685,20,26,25,47,44), +(10,5,17,295,724,20,26,25,48,45), +(10,5,18,310,764,20,26,26,50,47), +(10,5,19,325,805,20,26,26,51,49), +(10,5,20,340,847,21,27,27,53,50), +(10,5,21,355,890,21,27,27,54,52), +(10,5,22,371,934,21,27,28,56,53), +(10,5,23,388,979,21,28,28,58,55), +(10,5,24,406,1025,21,28,29,59,57), +(10,5,25,425,1072,22,28,29,61,58), +(10,5,26,445,1120,22,28,30,62,60), +(10,5,27,466,1169,22,29,30,64,62), +(10,5,28,488,1219,22,29,31,66,64), +(10,5,29,511,1270,23,29,31,67,65), +(10,5,30,535,1322,23,30,32,69,67), +(10,5,31,560,1375,23,30,32,71,69), +(10,5,32,586,1429,23,30,33,72,71), +(10,5,33,613,1483,24,31,33,74,72), +(10,5,34,641,1537,24,31,34,76,74), +(10,5,35,670,1591,24,32,34,78,76), +(10,5,36,700,1645,24,32,35,80,78), +(10,5,37,731,1699,25,32,35,81,80), +(10,5,38,763,1753,25,33,36,83,82), +(10,5,39,796,1807,25,33,37,85,84), +(10,5,40,830,1861,26,33,37,87,86), +(10,5,41,865,1915,26,34,38,89,88), +(10,5,42,901,1969,26,34,38,91,89), +(10,5,43,938,2023,27,35,39,92,91), +(10,5,44,976,2077,27,35,39,94,93), +(10,5,45,1015,2131,27,35,40,96,95), +(10,5,46,1055,2185,27,36,41,98,97), +(10,5,47,1096,2239,28,36,41,100,99), +(10,5,48,1138,2293,28,37,42,102,101), +(10,5,49,1181,2347,28,37,43,104,103), +(10,5,50,1225,2401,29,37,43,106,106), +(10,5,51,1270,2455,29,38,44,108,108), +(10,5,52,1316,2509,29,38,44,110,110), +(10,5,53,1363,2563,30,39,45,112,112), +(10,5,54,1411,2617,30,39,46,114,114), +(10,5,55,1460,2671,30,40,46,116,116), +(10,5,56,1510,2725,31,40,47,118,118), +(10,5,57,1561,2779,31,41,48,120,120), +(10,5,58,1613,2833,31,41,48,123,123), +(10,5,59,1666,2887,32,42,49,125,125), +(10,5,60,1720,2941,32,42,50,127,127), +(10,5,61,1890,3110,33,42,51,129,129), +(10,5,62,2068,3264,33,43,51,131,131), +(10,5,63,2254,3433,33,43,52,133,134), +(10,5,64,2448,3587,34,44,53,135,136), +(10,5,65,2650,3756,34,44,53,138,138), +(10,5,66,2861,3910,34,45,54,140,141), +(10,5,67,3081,4079,35,45,55,142,143), +(10,5,68,3310,4233,35,46,56,144,145), +(10,5,69,3548,4402,36,46,56,147,148), +(10,5,70,3795,4571,36,47,57,149,150), +(10,8,1,55,225,17,22,19,27,21), +(10,8,2,70,250,17,22,19,28,22), +(10,8,3,85,276,17,22,20,30,24), +(10,8,4,100,303,17,22,20,31,25), +(10,8,5,115,331,17,23,20,32,26), +(10,8,6,130,360,17,23,20,34,28), +(10,8,7,145,390,18,23,21,35,29), +(10,8,8,160,421,18,23,21,37,30), +(10,8,9,175,453,18,23,21,38,32), +(10,8,10,190,486,18,23,22,40,33), +(10,8,11,205,520,18,24,22,41,35), +(10,8,12,220,555,18,24,22,42,36), +(10,8,13,235,591,18,24,23,44,37), +(10,8,14,250,628,18,24,23,45,39), +(10,8,15,265,666,18,24,23,47,40), +(10,8,16,280,705,19,24,24,49,42), +(10,8,17,295,745,19,25,24,50,43), +(10,8,18,310,786,19,25,24,52,45), +(10,8,19,325,828,19,25,25,53,46), +(10,8,20,340,871,19,25,25,55,48), +(10,8,21,355,915,19,25,26,57,50), +(10,8,22,370,960,19,26,26,58,51), +(10,8,23,385,1006,20,26,26,60,53), +(10,8,24,401,1053,20,26,27,61,54), +(10,8,25,418,1101,20,26,27,63,56), +(10,8,26,436,1150,20,27,27,65,58), +(10,8,27,455,1200,20,27,28,67,59), +(10,8,28,475,1251,20,27,28,68,61), +(10,8,29,496,1302,21,27,29,70,63), +(10,8,30,518,1353,21,28,29,72,64), +(10,8,31,541,1404,21,28,30,74,66), +(10,8,32,565,1455,21,28,30,75,68), +(10,8,33,590,1506,21,28,30,77,70), +(10,8,34,616,1557,21,29,31,79,71), +(10,8,35,643,1608,22,29,31,81,73), +(10,8,36,671,1659,22,29,32,83,75), +(10,8,37,700,1710,22,29,32,85,77), +(10,8,38,730,1761,22,30,33,86,78), +(10,8,39,761,1812,22,30,33,88,80), +(10,8,40,793,1863,23,30,34,90,82), +(10,8,41,826,1914,23,31,34,92,84), +(10,8,42,860,1965,23,31,35,94,86), +(10,8,43,895,2016,23,31,35,96,88), +(10,8,44,931,2067,23,32,36,98,90), +(10,8,45,968,2118,24,32,36,100,92), +(10,8,46,1006,2169,24,32,37,102,93), +(10,8,47,1045,2220,24,32,37,104,95), +(10,8,48,1085,2271,24,33,38,106,97), +(10,8,49,1126,2322,25,33,38,108,99), +(10,8,50,1168,2373,25,33,39,110,101), +(10,8,51,1211,2424,25,34,39,112,103), +(10,8,52,1255,2475,25,34,40,114,105), +(10,8,53,1300,2526,25,35,40,117,107), +(10,8,54,1346,2577,26,35,41,119,109), +(10,8,55,1393,2628,26,35,41,121,111), +(10,8,56,1441,2679,26,36,42,123,113), +(10,8,57,1490,2730,26,36,42,125,116), +(10,8,58,1540,2781,27,36,43,127,118), +(10,8,59,1591,2832,27,37,43,130,120), +(10,8,60,1643,2883,27,37,44,132,122), +(10,8,61,1809,3016,27,37,45,134,124), +(10,8,62,1984,3164,28,38,45,136,126), +(10,8,63,2168,3297,28,38,46,139,128), +(10,8,64,2361,3445,28,39,46,141,131), +(10,8,65,2563,3578,29,39,47,143,133), +(10,8,66,2775,3726,29,39,48,146,135), +(10,8,67,2997,3859,29,40,48,148,137), +(10,8,68,3229,4007,29,40,49,150,139), +(10,8,69,3472,4140,30,41,49,153,142), +(10,8,70,3726,4288,30,41,50,155,144), +(10,9,1,42,197,17,22,20,26,21), +(10,9,2,57,220,17,22,21,27,22), +(10,9,3,72,244,18,23,21,28,23), +(10,9,4,87,269,18,23,22,29,24), +(10,9,5,102,295,18,23,22,31,26), +(10,9,6,117,322,18,24,23,32,27), +(10,9,7,132,350,19,24,23,33,28), +(10,9,8,147,379,19,25,24,34,29), +(10,9,9,162,409,19,25,25,36,30), +(10,9,10,177,440,20,25,25,37,32), +(10,9,11,192,472,20,26,26,38,33), +(10,9,12,207,505,20,26,26,39,34), +(10,9,13,222,539,21,27,27,41,36), +(10,9,14,237,574,21,27,28,42,37), +(10,9,15,252,610,21,27,28,43,38), +(10,9,16,267,647,22,28,29,45,39), +(10,9,17,282,685,22,28,30,46,41), +(10,9,18,298,724,23,29,30,47,42), +(10,9,19,315,764,23,29,31,49,43), +(10,9,20,333,805,23,30,32,50,45), +(10,9,21,352,847,24,30,32,51,46), +(10,9,22,372,890,24,31,33,53,48), +(10,9,23,393,934,24,31,34,54,49), +(10,9,24,415,979,25,31,34,56,50), +(10,9,25,438,1025,25,32,35,57,52), +(10,9,26,462,1072,26,32,36,59,53), +(10,9,27,487,1120,26,33,37,60,55), +(10,9,28,513,1169,26,33,37,62,56), +(10,9,29,540,1219,27,34,38,63,58), +(10,9,30,568,1270,27,34,39,65,59), +(10,9,31,597,1321,28,35,40,66,61), +(10,9,32,627,1372,28,36,40,68,62), +(10,9,33,658,1423,29,36,41,69,64), +(10,9,34,690,1474,29,37,42,71,65), +(10,9,35,723,1525,29,37,43,73,67), +(10,9,36,757,1576,30,38,43,74,69), +(10,9,37,792,1627,30,38,44,76,70), +(10,9,38,828,1678,31,39,45,77,72), +(10,9,39,865,1729,31,39,46,79,73), +(10,9,40,903,1780,32,40,47,81,75), +(10,9,41,942,1831,32,41,48,82,77), +(10,9,42,982,1882,33,41,48,84,78), +(10,9,43,1023,1933,33,42,49,86,80), +(10,9,44,1065,1984,34,42,50,88,82), +(10,9,45,1108,2035,34,43,51,89,83), +(10,9,46,1152,2086,35,44,52,91,85), +(10,9,47,1197,2137,35,44,53,93,87), +(10,9,48,1243,2188,36,45,54,95,89), +(10,9,49,1290,2239,36,45,54,96,90), +(10,9,50,1338,2290,37,46,55,98,92), +(10,9,51,1387,2341,37,47,56,100,94), +(10,9,52,1437,2392,38,47,57,102,96), +(10,9,53,1488,2443,38,48,58,104,97), +(10,9,54,1540,2494,39,49,59,105,99), +(10,9,55,1593,2545,39,49,60,107,101), +(10,9,56,1647,2596,40,50,61,109,103), +(10,9,57,1702,2647,40,51,62,111,105), +(10,9,58,1758,2698,41,51,63,113,107), +(10,9,59,1815,2749,42,52,64,115,108), +(10,9,60,1873,2800,42,53,65,117,110), +(10,9,61,2049,2954,43,53,66,119,112), +(10,9,62,2234,3108,43,54,67,121,114), +(10,9,63,2428,3277,44,55,68,123,116), +(10,9,64,2631,3431,44,56,69,125,118), +(10,9,65,2843,3585,45,56,70,127,120), +(10,9,66,3065,3754,46,57,71,129,122), +(10,9,67,3297,3908,46,58,72,131,124), +(10,9,68,3540,4062,47,58,73,133,126), +(10,9,69,3794,4231,47,59,74,135,128), +(10,9,70,4059,4385,48,60,75,137,130), +(11,1,1,50,0,24,17,21,21,22), +(11,1,2,69,0,25,18,22,21,22), +(11,1,3,88,0,27,19,23,21,23), +(11,1,4,107,0,28,19,25,21,23), +(11,1,5,126,0,29,20,26,21,23), +(11,1,6,145,0,31,21,27,21,23), +(11,1,7,164,0,32,22,28,21,24), +(11,1,8,183,0,33,23,29,22,24), +(11,1,9,202,0,35,24,31,22,24), +(11,1,10,221,0,36,24,32,22,25), +(11,1,11,240,0,37,25,33,22,25), +(11,1,12,259,0,39,26,34,22,25), +(11,1,13,278,0,40,27,36,22,26), +(11,1,14,298,0,42,28,37,22,26), +(11,1,15,319,0,43,29,38,22,26), +(11,1,16,341,0,45,30,40,22,27), +(11,1,17,364,0,46,31,41,23,27), +(11,1,18,388,0,48,32,43,23,27), +(11,1,19,413,0,49,33,44,23,28), +(11,1,20,439,0,51,34,45,23,28), +(11,1,21,466,0,52,34,47,23,28), +(11,1,22,494,0,54,35,48,23,29), +(11,1,23,523,0,55,36,50,23,29), +(11,1,24,553,0,57,37,51,24,30), +(11,1,25,584,0,59,38,52,24,30), +(11,1,26,616,0,60,39,54,24,30), +(11,1,27,649,0,62,40,55,24,31), +(11,1,28,683,0,63,41,57,24,31), +(11,1,29,718,0,65,43,58,24,32), +(11,1,30,754,0,67,44,60,24,32), +(11,1,31,791,0,69,45,62,25,32), +(11,1,32,829,0,70,46,63,25,33), +(11,1,33,868,0,72,47,65,25,33), +(11,1,34,908,0,74,48,66,25,34), +(11,1,35,949,0,75,49,68,25,34), +(11,1,36,991,0,77,50,69,26,35), +(11,1,37,1035,0,79,51,71,26,35), +(11,1,38,1081,0,81,52,73,26,35), +(11,1,39,1129,0,83,53,74,26,36), +(11,1,40,1179,0,84,55,76,26,36), +(11,1,41,1231,0,86,56,78,27,37), +(11,1,42,1285,0,88,57,79,27,37), +(11,1,43,1341,0,90,58,81,27,38), +(11,1,44,1399,0,92,59,83,27,38), +(11,1,45,1459,0,94,60,85,27,39), +(11,1,46,1521,0,96,62,86,28,39), +(11,1,47,1585,0,98,63,88,28,40), +(11,1,48,1651,0,100,64,90,28,40), +(11,1,49,1719,0,102,65,92,28,41), +(11,1,50,1789,0,103,66,93,29,41), +(11,1,51,1861,0,105,68,95,29,42), +(11,1,52,1935,0,107,69,97,29,42), +(11,1,53,2011,0,109,70,99,29,43), +(11,1,54,2089,0,112,71,101,30,44), +(11,1,55,2169,0,114,73,103,30,44), +(11,1,56,2251,0,116,74,104,30,45), +(11,1,57,2335,0,118,75,106,30,45), +(11,1,58,2421,0,120,77,108,31,46), +(11,1,59,2509,0,122,78,110,31,46), +(11,1,60,2599,0,124,79,112,31,47), +(11,1,61,2832,0,126,81,114,31,48), +(11,1,62,3079,0,128,82,116,32,48), +(11,1,63,3340,0,130,83,118,32,49), +(11,1,64,3615,0,133,85,120,32,49), +(11,1,65,3905,0,135,86,122,33,50), +(11,1,66,4210,0,137,87,124,33,51), +(11,1,67,4530,0,139,89,126,33,51), +(11,1,68,4866,0,141,90,128,33,52), +(11,1,69,5218,0,144,92,130,34,52), +(11,1,70,5586,0,146,93,132,34,53), +(11,2,1,48,95,23,17,21,21,23), +(11,2,2,66,114,24,18,22,22,24), +(11,2,3,84,134,25,18,23,22,24), +(11,2,4,102,155,26,19,24,23,25), +(11,2,5,120,177,27,19,25,24,26), +(11,2,6,138,200,29,20,26,24,26), +(11,2,7,156,224,30,21,27,25,27), +(11,2,8,174,249,31,21,28,26,28), +(11,2,9,192,275,32,22,29,26,29), +(11,2,10,210,302,33,22,31,27,29), +(11,2,11,228,330,34,23,32,28,30), +(11,2,12,246,359,36,24,33,28,31), +(11,2,13,264,389,37,24,34,29,32), +(11,2,14,282,420,38,25,35,30,32), +(11,2,15,301,452,39,26,36,31,33), +(11,2,16,321,485,40,26,37,31,34), +(11,2,17,342,519,42,27,39,32,35), +(11,2,18,364,554,43,28,40,33,36), +(11,2,19,387,590,44,28,41,34,37), +(11,2,20,411,627,46,29,42,34,37), +(11,2,21,436,665,47,30,44,35,38), +(11,2,22,462,704,48,31,45,36,39), +(11,2,23,489,744,50,31,46,37,40), +(11,2,24,517,785,51,32,47,38,41), +(11,2,25,546,827,52,33,49,38,42), +(11,2,26,576,869,54,34,50,39,43), +(11,2,27,607,911,55,34,51,40,44), +(11,2,28,639,953,56,35,53,41,44), +(11,2,29,672,995,58,36,54,42,45), +(11,2,30,706,1037,59,37,55,43,46), +(11,2,31,741,1079,61,37,57,43,47), +(11,2,32,777,1121,62,38,58,44,48), +(11,2,33,814,1163,64,39,59,45,49), +(11,2,34,852,1205,65,40,61,46,50), +(11,2,35,891,1247,67,41,62,47,51), +(11,2,36,931,1289,68,42,64,48,52), +(11,2,37,972,1331,70,42,65,49,53), +(11,2,38,1014,1373,71,43,67,50,54), +(11,2,39,1057,1415,73,44,68,51,55), +(11,2,40,1101,1457,74,45,69,52,56), +(11,2,41,1146,1499,76,46,71,53,57), +(11,2,42,1192,1541,78,47,72,54,58), +(11,2,43,1239,1583,79,47,74,55,59), +(11,2,44,1287,1625,81,48,75,56,60), +(11,2,45,1336,1667,82,49,77,57,61), +(11,2,46,1386,1709,84,50,78,58,62), +(11,2,47,1437,1751,86,51,80,59,64), +(11,2,48,1489,1793,87,52,82,60,65), +(11,2,49,1542,1835,89,53,83,61,66), +(11,2,50,1596,1877,91,54,85,62,67), +(11,2,51,1651,1919,92,55,86,63,68), +(11,2,52,1707,1961,94,56,88,64,69), +(11,2,53,1764,2003,96,57,90,65,70), +(11,2,54,1822,2045,97,58,91,66,71), +(11,2,55,1881,2087,99,59,93,67,73), +(11,2,56,1941,2129,101,60,95,68,74), +(11,2,57,2002,2171,103,61,96,69,75), +(11,2,58,2064,2213,105,62,98,70,76), +(11,2,59,2127,2255,106,63,100,71,77), +(11,2,60,2191,2297,108,64,101,72,78), +(11,2,61,2371,2456,110,65,103,74,80), +(11,2,62,2559,2615,112,66,105,75,81), +(11,2,63,2755,2789,114,67,106,76,82), +(11,2,64,2960,2948,116,68,108,77,83), +(11,2,65,3174,3107,117,69,110,78,85), +(11,2,66,3397,3281,119,70,112,79,86), +(11,2,67,3630,3440,121,71,114,80,87), +(11,2,68,3873,3599,123,72,115,82,88), +(11,2,69,4126,3773,125,73,117,83,90), +(11,2,70,4389,3932,127,74,119,84,91), +(11,3,1,46,100,21,20,20,21,23), +(11,3,2,63,120,21,21,21,22,24), +(11,3,3,80,141,22,23,22,22,24), +(11,3,4,97,163,22,24,23,23,25), +(11,3,5,114,186,23,25,24,23,25), +(11,3,6,131,210,23,27,25,24,26), +(11,3,7,148,235,24,28,26,24,27), +(11,3,8,165,261,24,30,27,25,27), +(11,3,9,182,288,25,31,27,26,28), +(11,3,10,199,316,25,33,28,26,29), +(11,3,11,216,345,25,34,29,27,29), +(11,3,12,233,375,26,36,30,28,30), +(11,3,13,250,406,26,37,31,28,31), +(11,3,14,268,438,27,39,32,29,32), +(11,3,15,287,471,27,40,34,30,32), +(11,3,16,307,505,28,42,35,30,33), +(11,3,17,328,540,28,43,36,31,34), +(11,3,18,350,576,29,45,37,32,35), +(11,3,19,373,613,29,47,38,32,35), +(11,3,20,397,651,30,48,39,33,36), +(11,3,21,422,690,31,50,40,34,37), +(11,3,22,448,730,31,51,41,34,38), +(11,3,23,475,771,32,53,42,35,38), +(11,3,24,503,813,32,55,43,36,39), +(11,3,25,532,856,33,57,44,37,40), +(11,3,26,562,900,33,58,46,37,41), +(11,3,27,593,945,34,60,47,38,42), +(11,3,28,625,990,35,62,48,39,42), +(11,3,29,658,1035,35,63,49,40,43), +(11,3,30,692,1080,36,65,50,40,44), +(11,3,31,727,1125,36,67,52,41,45), +(11,3,32,763,1170,37,69,53,42,46), +(11,3,33,800,1215,38,71,54,43,47), +(11,3,34,838,1260,38,72,55,44,48), +(11,3,35,877,1305,39,74,57,44,48), +(11,3,36,917,1350,39,76,58,45,49), +(11,3,37,958,1395,40,78,59,46,50), +(11,3,38,1000,1440,41,80,60,47,51), +(11,3,39,1043,1485,41,82,62,48,52), +(11,3,40,1087,1530,42,84,63,49,53), +(11,3,41,1132,1575,43,86,64,50,54), +(11,3,42,1178,1620,43,88,66,50,55), +(11,3,43,1225,1665,44,90,67,51,56), +(11,3,44,1273,1710,45,91,68,52,57), +(11,3,45,1322,1755,45,93,70,53,58), +(11,3,46,1372,1800,46,95,71,54,59), +(11,3,47,1423,1845,47,98,72,55,60), +(11,3,48,1475,1890,48,100,74,56,61), +(11,3,49,1528,1935,48,102,75,57,62), +(11,3,50,1582,1980,49,104,77,58,63), +(11,3,51,1637,2025,50,106,78,59,64), +(11,3,52,1693,2070,51,108,79,60,65), +(11,3,53,1750,2115,51,110,81,61,66), +(11,3,54,1808,2160,52,112,82,61,67), +(11,3,55,1867,2205,53,114,84,62,68), +(11,3,56,1927,2250,54,116,85,63,69), +(11,3,57,1988,2295,54,118,87,64,70), +(11,3,58,2050,2340,55,121,88,65,71), +(11,3,59,2113,2385,56,123,90,66,72), +(11,3,60,2177,2430,57,125,91,67,74), +(11,3,61,2363,2611,58,127,93,68,75), +(11,3,62,2558,2792,58,130,94,69,76), +(11,3,63,2762,2973,59,132,96,71,77), +(11,3,64,2975,3154,60,134,97,72,78), +(11,3,65,3197,3350,61,136,99,73,79), +(11,3,66,3429,3531,62,139,101,74,80), +(11,3,67,3671,3712,62,141,102,75,81), +(11,3,68,3923,3893,63,143,104,76,83), +(11,3,69,4185,4074,64,146,105,77,84), +(11,3,70,4458,4270,65,148,107,78,85), +(11,5,1,51,175,21,17,19,23,25), +(11,5,2,66,199,21,17,19,24,26), +(11,5,3,81,224,21,17,20,26,28), +(11,5,4,96,250,21,18,20,27,29), +(11,5,5,111,277,22,18,20,28,30), +(11,5,6,126,305,22,18,21,30,32), +(11,5,7,141,334,22,18,21,31,33), +(11,5,8,156,364,22,19,22,32,35), +(11,5,9,171,395,22,19,22,34,36), +(11,5,10,186,427,22,19,22,35,38), +(11,5,11,201,460,23,19,23,37,39), +(11,5,12,216,494,23,20,23,38,41), +(11,5,13,231,529,23,20,24,39,42), +(11,5,14,246,565,23,20,24,41,44), +(11,5,15,261,602,23,20,25,42,45), +(11,5,16,276,640,24,21,25,44,47), +(11,5,17,291,679,24,21,25,45,48), +(11,5,18,306,719,24,21,26,47,50), +(11,5,19,321,760,24,22,26,48,51), +(11,5,20,336,802,24,22,27,50,53), +(11,5,21,351,845,25,22,27,51,55), +(11,5,22,367,889,25,22,28,53,56), +(11,5,23,384,934,25,23,28,55,58), +(11,5,24,402,980,25,23,29,56,60), +(11,5,25,421,1027,25,23,29,58,61), +(11,5,26,441,1075,26,24,30,60,63), +(11,5,27,462,1124,26,24,30,61,65), +(11,5,28,484,1174,26,24,31,63,66), +(11,5,29,507,1225,26,25,31,65,68), +(11,5,30,531,1277,27,25,32,66,70), +(11,5,31,556,1330,27,25,32,68,72), +(11,5,32,582,1384,27,26,33,70,73), +(11,5,33,609,1438,27,26,33,71,75), +(11,5,34,637,1492,28,26,34,73,77), +(11,5,35,666,1546,28,27,34,75,79), +(11,5,36,696,1600,28,27,35,77,81), +(11,5,37,727,1654,29,28,35,79,83), +(11,5,38,759,1708,29,28,36,80,85), +(11,5,39,792,1762,29,28,37,82,86), +(11,5,40,826,1816,29,29,37,84,88), +(11,5,41,861,1870,30,29,38,86,90), +(11,5,42,897,1924,30,29,38,88,92), +(11,5,43,934,1978,30,30,39,90,94), +(11,5,44,972,2032,31,30,39,91,96), +(11,5,45,1011,2086,31,31,40,93,98), +(11,5,46,1051,2140,31,31,41,95,100), +(11,5,47,1092,2194,32,31,41,97,102), +(11,5,48,1134,2248,32,32,42,99,104), +(11,5,49,1177,2302,32,32,43,101,106), +(11,5,50,1221,2356,33,33,43,103,108), +(11,5,51,1266,2410,33,33,44,105,110), +(11,5,52,1312,2464,33,34,44,107,113), +(11,5,53,1359,2518,34,34,45,109,115), +(11,5,54,1407,2572,34,34,46,111,117), +(11,5,55,1456,2626,34,35,46,113,119), +(11,5,56,1506,2680,35,35,47,115,121), +(11,5,57,1557,2734,35,36,48,118,123), +(11,5,58,1609,2788,35,36,48,120,126), +(11,5,59,1662,2842,36,37,49,122,128), +(11,5,60,1716,2896,36,37,50,124,130), +(11,5,61,1886,3065,36,38,51,126,132), +(11,5,62,2064,3219,37,38,51,128,134), +(11,5,63,2250,3388,37,39,52,130,137), +(11,5,64,2444,3542,38,39,53,133,139), +(11,5,65,2646,3711,38,40,53,135,141), +(11,5,66,2857,3865,38,40,54,137,144), +(11,5,67,3077,4034,39,40,55,139,146), +(11,5,68,3306,4188,39,41,56,141,148), +(11,5,69,3544,4357,40,41,56,144,151), +(11,5,70,3791,4526,40,42,57,146,153), +(11,7,1,47,105,22,17,20,22,24), +(11,7,2,64,126,23,17,21,23,25), +(11,7,3,81,148,24,18,22,24,26), +(11,7,4,98,171,25,18,23,25,27), +(11,7,5,115,195,25,19,24,26,28), +(11,7,6,132,220,26,19,25,27,29), +(11,7,7,149,246,27,20,26,28,30), +(11,7,8,166,273,28,20,27,28,31), +(11,7,9,183,301,29,21,28,29,32), +(11,7,10,200,330,30,21,29,30,33), +(11,7,11,217,360,31,22,30,31,35), +(11,7,12,234,391,32,22,31,32,36), +(11,7,13,251,423,33,23,32,33,37), +(11,7,14,268,456,34,23,33,34,38), +(11,7,15,285,490,34,24,35,35,39), +(11,7,16,302,525,35,24,36,36,40), +(11,7,17,320,561,36,25,37,38,42), +(11,7,18,339,598,37,25,38,39,43), +(11,7,19,359,636,38,26,39,40,44), +(11,7,20,380,675,39,26,40,41,45), +(11,7,21,402,715,40,27,41,42,46), +(11,7,22,425,756,41,27,43,43,48), +(11,7,23,449,798,43,28,44,44,49), +(11,7,24,474,841,44,28,45,45,50), +(11,7,25,500,885,45,29,46,46,51), +(11,7,26,527,930,46,30,47,48,53), +(11,7,27,555,976,47,30,49,49,54), +(11,7,28,584,1023,48,31,50,50,55), +(11,7,29,614,1071,49,31,51,51,57), +(11,7,30,645,1120,50,32,53,52,58), +(11,7,31,677,1170,51,33,54,53,59), +(11,7,32,710,1221,52,33,55,55,61), +(11,7,33,744,1272,53,34,56,56,62), +(11,7,34,779,1323,55,34,58,57,64), +(11,7,35,815,1374,56,35,59,58,65), +(11,7,36,852,1425,57,36,60,60,66), +(11,7,37,890,1476,58,36,62,61,68), +(11,7,38,929,1527,59,37,63,62,69), +(11,7,39,969,1578,61,38,65,63,71), +(11,7,40,1010,1629,62,38,66,65,72), +(11,7,41,1052,1680,63,39,67,66,74), +(11,7,42,1095,1731,64,40,69,67,75), +(11,7,43,1139,1782,65,40,70,69,77), +(11,7,44,1184,1833,67,41,72,70,78), +(11,7,45,1230,1884,68,42,73,71,80), +(11,7,46,1277,1935,69,42,75,73,81), +(11,7,47,1325,1986,71,43,76,74,83), +(11,7,48,1374,2037,72,44,78,76,84), +(11,7,49,1424,2088,73,45,79,77,86), +(11,7,50,1475,2139,74,45,81,78,88), +(11,7,51,1527,2190,76,46,82,80,89), +(11,7,52,1580,2241,77,47,84,81,91), +(11,7,53,1634,2292,78,47,85,83,92), +(11,7,54,1689,2343,80,48,87,84,94), +(11,7,55,1745,2394,81,49,88,86,96), +(11,7,56,1802,2445,83,50,90,87,97), +(11,7,57,1860,2496,84,50,91,89,99), +(11,7,58,1919,2547,85,51,93,90,101), +(11,7,59,1979,2598,87,52,95,92,102), +(11,7,60,2040,2649,88,53,96,93,104), +(11,7,61,2208,2808,90,54,98,95,106), +(11,7,62,2384,2967,91,54,99,96,108), +(11,7,63,2568,3141,93,55,101,98,109), +(11,7,64,2760,3300,94,56,103,99,111), +(11,7,65,2961,3459,95,57,104,101,113), +(11,7,66,3171,3633,97,58,106,103,115), +(11,7,67,3391,3792,98,58,108,104,117), +(11,7,68,3621,3951,100,59,110,106,118), +(11,7,69,3861,4125,101,60,111,107,120), +(11,7,70,4111,4284,103,61,113,109,122), +(11,8,1,51,180,21,17,19,24,24), +(11,8,2,66,205,21,17,19,25,25), +(11,8,3,81,231,21,17,20,27,27), +(11,8,4,96,258,21,17,20,28,28), +(11,8,5,111,286,21,18,20,29,29), +(11,8,6,126,315,21,18,20,31,31), +(11,8,7,141,345,21,18,21,32,32), +(11,8,8,156,376,22,18,21,34,33), +(11,8,9,171,408,22,18,21,35,35), +(11,8,10,186,441,22,19,22,37,36), +(11,8,11,201,475,22,19,22,38,37), +(11,8,12,216,510,22,19,22,40,39), +(11,8,13,231,546,22,19,23,41,40), +(11,8,14,246,583,22,19,23,43,42), +(11,8,15,261,621,22,19,23,44,43), +(11,8,16,276,660,22,20,24,46,45), +(11,8,17,291,700,23,20,24,47,46), +(11,8,18,306,741,23,20,24,49,48), +(11,8,19,321,783,23,20,25,50,49), +(11,8,20,336,826,23,21,25,52,51), +(11,8,21,351,870,23,21,26,54,52), +(11,8,22,366,915,23,21,26,55,54), +(11,8,23,381,961,23,21,26,57,56), +(11,8,24,397,1008,24,21,27,59,57), +(11,8,25,414,1056,24,22,27,60,59), +(11,8,26,432,1105,24,22,27,62,60), +(11,8,27,451,1155,24,22,28,64,62), +(11,8,28,471,1206,24,22,28,65,64), +(11,8,29,492,1257,24,23,29,67,65), +(11,8,30,514,1308,24,23,29,69,67), +(11,8,31,537,1359,25,23,30,71,69), +(11,8,32,561,1410,25,23,30,73,71), +(11,8,33,586,1461,25,24,30,74,72), +(11,8,34,612,1512,25,24,31,76,74), +(11,8,35,639,1563,25,24,31,78,76), +(11,8,36,667,1614,26,24,32,80,78), +(11,8,37,696,1665,26,25,32,82,79), +(11,8,38,726,1716,26,25,33,84,81), +(11,8,39,757,1767,26,25,33,86,83), +(11,8,40,789,1818,26,26,34,87,85), +(11,8,41,822,1869,27,26,34,89,87), +(11,8,42,856,1920,27,26,35,91,89), +(11,8,43,891,1971,27,27,35,93,91), +(11,8,44,927,2022,27,27,36,95,92), +(11,8,45,964,2073,27,27,36,97,94), +(11,8,46,1002,2124,28,27,37,99,96), +(11,8,47,1041,2175,28,28,37,101,98), +(11,8,48,1081,2226,28,28,38,103,100), +(11,8,49,1122,2277,28,28,38,105,102), +(11,8,50,1164,2328,29,29,39,107,104), +(11,8,51,1207,2379,29,29,39,110,106), +(11,8,52,1251,2430,29,29,40,112,108), +(11,8,53,1296,2481,29,30,40,114,110), +(11,8,54,1342,2532,30,30,41,116,112), +(11,8,55,1389,2583,30,30,41,118,114), +(11,8,56,1437,2634,30,31,42,120,116), +(11,8,57,1486,2685,30,31,42,122,118), +(11,8,58,1536,2736,31,31,43,125,121), +(11,8,59,1587,2787,31,32,43,127,123), +(11,8,60,1639,2838,31,32,44,129,125), +(11,8,61,1805,2971,31,33,45,131,127), +(11,8,62,1980,3119,32,33,45,133,129), +(11,8,63,2164,3252,32,33,46,136,131), +(11,8,64,2357,3400,32,34,46,138,134), +(11,8,65,2559,3533,33,34,47,140,136), +(11,8,66,2771,3681,33,34,48,143,138), +(11,8,67,2993,3814,33,35,48,145,140), +(11,8,68,3225,3962,33,35,49,147,142), +(11,8,69,3468,4095,34,36,49,150,145), +(11,8,70,3722,4243,34,36,50,152,147); +/*!40000 ALTER TABLE `player_levelstats` ENABLE KEYS */; +UNLOCK TABLES; diff --git a/sql/updates/0.8/4540_battleground_template.sql b/sql/updates/0.8/4540_battleground_template.sql new file mode 100644 index 000000000..4397f4d35 --- /dev/null +++ b/sql/updates/0.8/4540_battleground_template.sql @@ -0,0 +1 @@ +ALTER TABLE `battleground_template` ADD `MinPlayersPerTeam` int(11) unsigned NOT NULL default '0' AFTER `id`; \ No newline at end of file diff --git a/sql/updates/0.8/4544_creature_addon.sql b/sql/updates/0.8/4544_creature_addon.sql new file mode 100644 index 000000000..182b9362c --- /dev/null +++ b/sql/updates/0.8/4544_creature_addon.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_addon` + DROP COLUMN `RefId`; diff --git a/sql/updates/0.8/4544_creature_template_addon.sql b/sql/updates/0.8/4544_creature_template_addon.sql new file mode 100644 index 000000000..685a40434 --- /dev/null +++ b/sql/updates/0.8/4544_creature_template_addon.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS `creature_template_addon`; +CREATE TABLE `creature_template_addon` ( + `entry` int(11) NOT NULL default '0', + `mount` int(11) unsigned NOT NULL default '0', + `bytes0` int(11) unsigned NOT NULL default '0', + `bytes1` int(11) unsigned NOT NULL default '0', + `bytes2` int(11) unsigned NOT NULL default '0', + `emote` int(11) unsigned NOT NULL default '0', + `aura` int(11) unsigned NOT NULL default '0', + `auraflags` int(11) unsigned NOT NULL default '0', + `auralevels` int(11) unsigned NOT NULL default '0', + `auraapplications` int(11) unsigned NOT NULL default '0', + `aurastate` int(11) unsigned NOT NULL default '0', + UNIQUE KEY `entry` (`entry`), + KEY `emote` (`emote`,`mount`,`aura`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + diff --git a/sql/updates/0.8/4547_spell_affect.sql b/sql/updates/0.8/4547_spell_affect.sql new file mode 100644 index 000000000..5d4b92146 --- /dev/null +++ b/sql/updates/0.8/4547_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (23565, 31821); +INSERT INTO `spell_affect` VALUES +(31821,0,0,0,0,0,0,67240008,0), +(23565,0,0,0,0,0,0,67240008,0); diff --git a/sql/updates/0.8/4547_spell_proc_event.sql b/sql/updates/0.8/4547_spell_proc_event.sql new file mode 100644 index 000000000..2acc33ca5 --- /dev/null +++ b/sql/updates/0.8/4547_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (20127,20130,20135,20136,20137); +INSERT INTO `spell_proc_event` VALUES +(20127,0,0,0,0,0,1026,0), +(20130,0,0,0,0,0,1026,0), +(20135,0,0,0,0,0,1026,0), +(20136,0,0,0,0,0,1026,0), +(20137,0,0,0,0,0,1026,0); diff --git a/sql/updates/0.8/4551_item_template.sql b/sql/updates/0.8/4551_item_template.sql new file mode 100644 index 000000000..02f6f4342 --- /dev/null +++ b/sql/updates/0.8/4551_item_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `item_template` + ADD COLUMN `FoodType` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `DisenchantID`; diff --git a/sql/updates/0.8/4556_realmlist.sql b/sql/updates/0.8/4556_realmlist.sql new file mode 100644 index 000000000..09a9477ce --- /dev/null +++ b/sql/updates/0.8/4556_realmlist.sql @@ -0,0 +1,3 @@ +ALTER TABLE realmd.realmlist + ALTER COLUMN `color` SET DEFAULT '2', + ENGINE = MyISAM; diff --git a/sql/updates/0.8/4561_command.sql b/sql/updates/0.8/4561_command.sql new file mode 100644 index 000000000..d9683a4fe --- /dev/null +++ b/sql/updates/0.8/4561_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('plimit'); +INSERT INTO `command` VALUES +('plimit',3,'Syntax: .plimit [#num|-1|-2|-3|default|player|moderator|gamemaster|administrator]\r\n Without arg show current player amount and security level limitations for login to server, with arg set player linit ($num > 0) or securiti limitation ($num < 0 or security leme name. With `default` arg set default for server player limit (100)'); + diff --git a/sql/updates/0.8/4571_button_scripts.sql b/sql/updates/0.8/4571_button_scripts.sql new file mode 100644 index 000000000..034bb8d0a --- /dev/null +++ b/sql/updates/0.8/4571_button_scripts.sql @@ -0,0 +1,17 @@ +-- +-- Table structure for table `button_scripts` +-- + +DROP TABLE IF EXISTS `button_scripts`; +CREATE TABLE `button_scripts` ( + `id` int(11) unsigned NOT NULL default '0', + `delay` int(11) unsigned NOT NULL default '0', + `command` int(11) unsigned NOT NULL default '0', + `datalong` int(11) unsigned NOT NULL default '0', + `datalong2` int(11) unsigned NOT NULL default '0', + `datatext` text NOT NULL, + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.8/4577_gameobject.sql b/sql/updates/0.8/4577_gameobject.sql new file mode 100644 index 000000000..61b6a9f79 --- /dev/null +++ b/sql/updates/0.8/4577_gameobject.sql @@ -0,0 +1,2 @@ +ALTER TABLE `gameobject` + CHANGE COLUMN `spawntimesecs` `spawntimesecs` int(11) NOT NULL default '0'; diff --git a/sql/updates/0.8/4579.sql b/sql/updates/0.8/4579.sql new file mode 100644 index 000000000..49b9ba70f --- /dev/null +++ b/sql/updates/0.8/4579.sql @@ -0,0 +1,274 @@ +DROP TABLE IF EXISTS `locales_creature`; +CREATE TABLE `locales_creature` ( + `entry` int(11) unsigned NOT NULL default '0', + `name_loc1` varchar(100) NOT NULL default '', + `name_loc2` varchar(100) NOT NULL default '', + `name_loc3` varchar(100) NOT NULL default '', + `name_loc4` varchar(100) NOT NULL default '', + `name_loc5` varchar(100) NOT NULL default '', + `name_loc6` varchar(100) NOT NULL default '', + `name_loc7` varchar(100) NOT NULL default '', + `subname_loc1` varchar(100) default NULL, + `subname_loc2` varchar(100) default NULL, + `subname_loc3` varchar(100) default NULL, + `subname_loc4` varchar(100) default NULL, + `subname_loc5` varchar(100) default NULL, + `subname_loc6` varchar(100) default NULL, + `subname_loc7` varchar(100) default NULL, + `subname_loc8` varchar(100) default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `locales_gameobject`; +CREATE TABLE `locales_gameobject` ( + `entry` int(11) unsigned NOT NULL default '0', + `name_loc1` varchar(100) NOT NULL default '', + `name_loc2` varchar(100) NOT NULL default '', + `name_loc3` varchar(100) NOT NULL default '', + `name_loc4` varchar(100) NOT NULL default '', + `name_loc5` varchar(100) NOT NULL default '', + `name_loc6` varchar(100) NOT NULL default '', + `name_loc7` varchar(100) NOT NULL default '', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `locales_item`; +CREATE TABLE `locales_item` ( + `entry` int(11) unsigned NOT NULL default '0', + `name_loc1` varchar(100) NOT NULL default '', + `name_loc2` varchar(100) NOT NULL default '', + `name_loc3` varchar(100) NOT NULL default '', + `name_loc4` varchar(100) NOT NULL default '', + `name_loc5` varchar(100) NOT NULL default '', + `name_loc6` varchar(100) NOT NULL default '', + `name_loc7` varchar(100) NOT NULL default '', + `description_loc1` varchar(255) default NULL, + `description_loc2` varchar(255) default NULL, + `description_loc3` varchar(255) default NULL, + `description_loc4` varchar(255) default NULL, + `description_loc5` varchar(255) default NULL, + `description_loc6` varchar(255) default NULL, + `description_loc7` varchar(255) default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `locales_quest`; +CREATE TABLE `locales_quest` ( + `entry` int(11) unsigned NOT NULL default '0', + `Title_loc1` text, + `Title_loc2` text, + `Title_loc3` text, + `Title_loc4` text, + `Title_loc5` text, + `Title_loc6` text, + `Title_loc7` text, + `Details_loc1` text, + `Details_loc2` text, + `Details_loc3` text, + `Details_loc4` text, + `Details_loc5` text, + `Details_loc6` text, + `Details_loc7` text, + `Objectives_loc1` text, + `Objectives_loc2` text, + `Objectives_loc3` text, + `Objectives_loc4` text, + `Objectives_loc5` text, + `Objectives_loc6` text, + `Objectives_loc7` text, + `OfferRewardText_loc1` text, + `OfferRewardText_loc2` text, + `OfferRewardText_loc3` text, + `OfferRewardText_loc4` text, + `OfferRewardText_loc5` text, + `OfferRewardText_loc6` text, + `OfferRewardText_loc7` text, + `RequestItemsText_loc1` text, + `RequestItemsText_loc2` text, + `RequestItemsText_loc3` text, + `RequestItemsText_loc4` text, + `RequestItemsText_loc5` text, + `RequestItemsText_loc6` text, + `RequestItemsText_loc7` text, + `EndText_loc1` text, + `EndText_loc2` text, + `EndText_loc3` text, + `EndText_loc4` text, + `EndText_loc5` text, + `EndText_loc6` text, + `EndText_loc7` text, + `ObjectiveText1_loc1` text, + `ObjectiveText1_loc2` text, + `ObjectiveText1_loc3` text, + `ObjectiveText1_loc4` text, + `ObjectiveText1_loc5` text, + `ObjectiveText1_loc6` text, + `ObjectiveText1_loc7` text, + `ObjectiveText2_loc1` text, + `ObjectiveText2_loc2` text, + `ObjectiveText2_loc3` text, + `ObjectiveText2_loc4` text, + `ObjectiveText2_loc5` text, + `ObjectiveText2_loc6` text, + `ObjectiveText2_loc7` text, + `ObjectiveText3_loc1` text, + `ObjectiveText3_loc2` text, + `ObjectiveText3_loc3` text, + `ObjectiveText3_loc4` text, + `ObjectiveText3_loc5` text, + `ObjectiveText3_loc6` text, + `ObjectiveText3_loc7` text, + `ObjectiveText4_loc1` text, + `ObjectiveText4_loc2` text, + `ObjectiveText4_loc3` text, + `ObjectiveText4_loc4` text, + `ObjectiveText4_loc5` text, + `ObjectiveText4_loc6` text, + `ObjectiveText4_loc7` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `locales_npc_text`; +CREATE TABLE `locales_npc_text` ( + `entry` int(11) unsigned NOT NULL default '0', + `Text0_0_loc1` longtext, + `Text0_0_loc2` longtext, + `Text0_0_loc3` longtext, + `Text0_0_loc4` longtext, + `Text0_0_loc5` longtext, + `Text0_0_loc6` longtext, + `Text0_0_loc7` longtext, + `Text0_1_loc1` longtext, + `Text0_1_loc2` longtext, + `Text0_1_loc3` longtext, + `Text0_1_loc4` longtext, + `Text0_1_loc5` longtext, + `Text0_1_loc6` longtext, + `Text0_1_loc7` longtext, + `Text1_0_loc1` longtext, + `Text1_0_loc2` longtext, + `Text1_0_loc3` longtext, + `Text1_0_loc4` longtext, + `Text1_0_loc5` longtext, + `Text1_0_loc6` longtext, + `Text1_0_loc7` longtext, + `Text1_1_loc1` longtext, + `Text1_1_loc2` longtext, + `Text1_1_loc3` longtext, + `Text1_1_loc4` longtext, + `Text1_1_loc5` longtext, + `Text1_1_loc6` longtext, + `Text1_1_loc7` longtext, + `Text2_0_loc1` longtext, + `Text2_0_loc2` longtext, + `Text2_0_loc3` longtext, + `Text2_0_loc4` longtext, + `Text2_0_loc5` longtext, + `Text2_0_loc6` longtext, + `Text2_0_loc7` longtext, + `Text2_1_loc1` longtext, + `Text2_1_loc2` longtext, + `Text2_1_loc3` longtext, + `Text2_1_loc4` longtext, + `Text2_1_loc5` longtext, + `Text2_1_loc6` longtext, + `Text2_1_loc7` longtext, + `Text3_0_loc1` longtext, + `Text3_0_loc2` longtext, + `Text3_0_loc3` longtext, + `Text3_0_loc4` longtext, + `Text3_0_loc5` longtext, + `Text3_0_loc6` longtext, + `Text3_0_loc7` longtext, + `Text3_1_loc1` longtext, + `Text3_1_loc2` longtext, + `Text3_1_loc3` longtext, + `Text3_1_loc4` longtext, + `Text3_1_loc5` longtext, + `Text3_1_loc6` longtext, + `Text3_1_loc7` longtext, + `Text4_0_loc1` longtext, + `Text4_0_loc2` longtext, + `Text4_0_loc3` longtext, + `Text4_0_loc4` longtext, + `Text4_0_loc5` longtext, + `Text4_0_loc6` longtext, + `Text4_0_loc7` longtext, + `Text4_1_loc1` longtext, + `Text4_1_loc2` longtext, + `Text4_1_loc3` longtext, + `Text4_1_loc4` longtext, + `Text4_1_loc5` longtext, + `Text4_1_loc6` longtext, + `Text4_1_loc7` longtext, + `Text5_0_loc1` longtext, + `Text5_0_loc2` longtext, + `Text5_0_loc3` longtext, + `Text5_0_loc4` longtext, + `Text5_0_loc5` longtext, + `Text5_0_loc6` longtext, + `Text5_0_loc7` longtext, + `Text5_1_loc1` longtext, + `Text5_1_loc2` longtext, + `Text5_1_loc3` longtext, + `Text5_1_loc4` longtext, + `Text5_1_loc5` longtext, + `Text5_1_loc6` longtext, + `Text5_1_loc7` longtext, + `Text6_0_loc1` longtext, + `Text6_0_loc2` longtext, + `Text6_0_loc3` longtext, + `Text6_0_loc4` longtext, + `Text6_0_loc5` longtext, + `Text6_0_loc6` longtext, + `Text6_0_loc7` longtext, + `Text6_1_loc1` longtext, + `Text6_1_loc2` longtext, + `Text6_1_loc3` longtext, + `Text6_1_loc4` longtext, + `Text6_1_loc5` longtext, + `Text6_1_loc6` longtext, + `Text6_1_loc7` longtext, + `Text7_0_loc1` longtext, + `Text7_0_loc2` longtext, + `Text7_0_loc3` longtext, + `Text7_0_loc4` longtext, + `Text7_0_loc5` longtext, + `Text7_0_loc6` longtext, + `Text7_0_loc7` longtext, + `Text7_1_loc1` longtext, + `Text7_1_loc2` longtext, + `Text7_1_loc3` longtext, + `Text7_1_loc4` longtext, + `Text7_1_loc5` longtext, + `Text7_1_loc6` longtext, + `Text7_1_loc7` longtext, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `locales_page_text`; +CREATE TABLE `locales_page_text` ( + `entry` int(11) unsigned NOT NULL default '0', + `Text_loc1` longtext, + `Text_loc2` longtext, + `Text_loc3` longtext, + `Text_loc4` longtext, + `Text_loc5` longtext, + `Text_loc6` longtext, + `Text_loc7` longtext, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `realmd`.`localization`; +CREATE TABLE `realmd`.`localization` ( + `locale` tinyint(3) unsigned NOT NULL default '0', + `string` char(2) NOT NULL DEFAULT '', + PRIMARY KEY (`locale`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `realmd`.`localization` VALUES + (0,'en'), + (2,'fr'), + (3,'de'); + +ALTER TABLE `realmd`.`account` ADD COLUMN `locale` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `mutetime`; diff --git a/sql/updates/0.8/4582_spell_affect.sql b/sql/updates/0.8/4582_spell_affect.sql new file mode 100644 index 000000000..1caa6788a --- /dev/null +++ b/sql/updates/0.8/4582_spell_affect.sql @@ -0,0 +1,9 @@ +-- Cleanup +DELETE FROM `spell_affect` WHERE `entry` IN (28787); + +-- Correct data +DELETE FROM `spell_affect` WHERE `entry` IN (37878,37879,37880); +INSERT INTO `spell_affect` VALUES +(37878, 0, 0, 0x00, 0, 0, 0, 0x00000010000000F0, 0), +(37879, 0, 0, 0x00, 0, 0, 0, 0x00000000C0006000, 0), +(37880, 0, 0, 0x00, 0, 0, 0, 0x0000000411041E40, 0); diff --git a/sql/updates/0.8/4584_character_inventory.sql b/sql/updates/0.8/4584_character_inventory.sql new file mode 100644 index 000000000..5fa8cf13d --- /dev/null +++ b/sql/updates/0.8/4584_character_inventory.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_inventory` + ADD KEY `idx_guid` ( `guid` ); diff --git a/sql/updates/0.8/4585_item_instance.sql b/sql/updates/0.8/4585_item_instance.sql new file mode 100644 index 000000000..a9e3bbbf2 --- /dev/null +++ b/sql/updates/0.8/4585_item_instance.sql @@ -0,0 +1,2 @@ +ALTER TABLE `item_instance` + ADD KEY `idx_owner_guid` ( `owner_guid`); diff --git a/sql/updates/0.8/4587_character_quest_daily.sql b/sql/updates/0.8/4587_character_quest_daily.sql new file mode 100644 index 000000000..e9e9b7266 --- /dev/null +++ b/sql/updates/0.8/4587_character_quest_daily.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS `character_queststatus_daily`; +CREATE TABLE `character_queststatus_daily` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`quest`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + diff --git a/sql/updates/0.8/4588_command.sql b/sql/updates/0.8/4588_command.sql new file mode 100644 index 000000000..4b26fcb10 --- /dev/null +++ b/sql/updates/0.8/4588_command.sql @@ -0,0 +1 @@ +DELETE FROM command WHERE name IN ('gameobject'); diff --git a/sql/updates/0.8/4592_command.sql b/sql/updates/0.8/4592_command.sql new file mode 100644 index 000000000..5a1bcd888 --- /dev/null +++ b/sql/updates/0.8/4592_command.sql @@ -0,0 +1 @@ +UPDATE `command` set `help` = 'Syntax: .plimit [#num|-1|-2|-3|reset|player|moderator|gamemaster|administrator]\r\n\r\nWithout arg show current player amount and security level limitations for login to server, with arg set player linit ($num > 0) or securiti limitation ($num < 0 or security leme name. With `reset` sets player limit to the one in the config file' WHERE `name` = 'plimit'; diff --git a/sql/updates/0.8/4592_realmlist.sql b/sql/updates/0.8/4592_realmlist.sql new file mode 100644 index 000000000..dbd8e89bf --- /dev/null +++ b/sql/updates/0.8/4592_realmlist.sql @@ -0,0 +1,2 @@ +ALTER TABLE realmd.realmlist + ADD COLUMN `allowedSecurityLevel` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `timezone`; diff --git a/sql/updates/0.8/4594_item_template.sql b/sql/updates/0.8/4594_item_template.sql new file mode 100644 index 000000000..f9b8e3df7 --- /dev/null +++ b/sql/updates/0.8/4594_item_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `item_template` + ADD COLUMN `minMoneyLoot` int(11) unsigned NOT NULL default '0' AFTER `FoodType`, + ADD COLUMN `maxMoneyLoot` int(11) unsigned NOT NULL default '0' AFTER `minMoneyLoot`; diff --git a/sql/updates/0.8/4595_command.sql b/sql/updates/0.8/4595_command.sql new file mode 100644 index 000000000..50eac0de3 --- /dev/null +++ b/sql/updates/0.8/4595_command.sql @@ -0,0 +1,5 @@ +DELETE FROM command WHERE name IN ('cast','castback'); +INSERT INTO `command` VALUES +('cast',3,'Syntax: .cast #spellid\r\n Cast #spellid to selected target. If no target selected cast to self.'), +('castback',3,'Syntax: .castback #spellid\r\n Selected target cast #spellid to your character.'); + diff --git a/sql/updates/0.8/4595_spell_affect.sql b/sql/updates/0.8/4595_spell_affect.sql new file mode 100644 index 000000000..ba9274597 --- /dev/null +++ b/sql/updates/0.8/4595_spell_affect.sql @@ -0,0 +1,105 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (21873,38314); +INSERT INTO `spell_affect` VALUES +(21873,0,0,0,0,0,0,0x0000E000E2000000,0), -- ?? rare druid armor +(38314,0,0,0,0,0,0,0x0000E000E2000000,0); -- for item 31334 + +DELETE FROM `spell_affect` WHERE `entry` IN (16870); +INSERT INTO `spell_affect` VALUES +(16870,0,0,0,0,0,0,0x001007F100E3FEFF,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16947,16948,16949); +INSERT INTO `spell_affect` VALUES +(16947,1,0,0,0,0,0,0x0000000002000000,0), +(16948,1,0,0,0,0,0,0x0000000002000000,0), +(16949,1,0,0,0,0,0,0x0000000002000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17104,24943,24944,24945,24946); +INSERT INTO `spell_affect` VALUES +(17104,0,0,0,0,0,0,0x00000010000000F0,0), +(17104,1,0,0,0,0,0,0x00000010000000F0,0), +(24943,0,0,0,0,0,0,0x00000010000000F0,0), +(24943,1,0,0,0,0,0,0x00000010000000F0,0), +(24944,0,0,0,0,0,0,0x00000010000000F0,0), +(24944,1,0,0,0,0,0,0x00000010000000F0,0), +(24945,0,0,0,0,0,0,0x00000010000000F0,0), +(24945,1,0,0,0,0,0,0x00000010000000F0,0), +(24946,0,0,0,0,0,0,0x00000010000000F0,0), +(24946,1,0,0,0,0,0,0x00000010000000F0,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37721); +INSERT INTO `spell_affect` VALUES +(37721,0,0,0,0,0,0,0x00000010000000F0,1); -- not used in 2.3.0 + +DELETE FROM `spell_affect` WHERE `entry` IN (42367); +INSERT INTO `spell_affect` VALUES +(42367,0,0,0,0,0,0,0x0000001000000000,0); -- not used in 2.3.0 (?) + +DELETE FROM `spell_affect` WHERE `entry` IN (38447); +INSERT INTO `spell_affect` VALUES +(38447,0,0,0,0,0,0,0x0000040000000000,0), +(38447,1,0,0,0,0,0,0x0000004000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37292); +INSERT INTO `spell_affect` VALUES +(37292,0,0,0,0,0,0,0x0008000000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (39926); +INSERT INTO `spell_affect` VALUES +(39926,1,0,0,0,0,0,0x0000080000000000,0), +(39926,2,0,0,0,0,0,0x0000200000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (38416); +INSERT INTO `spell_affect` VALUES +(38416,0,0,0,0,0,0,0x0010000000800000,0), +(38416,1,0,0,0,0,0,0x0010000000800000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37736); +INSERT INTO `spell_affect` VALUES +(37736,0,0,0,0,0,0,0x0000040000000000,0), +(37736,1,0,0,0,0,0,0x0000004000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28855); +INSERT INTO `spell_affect` VALUES +(28855,0,0,0,0,0,0,0x0000000000000800,0), +(28855,1,0,0,0,0,0,0x0010000000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (23724); +INSERT INTO `spell_affect` VALUES +(23724,0,0,0,0,0,0,0x0000E000E2000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16833,16834,16835); +INSERT INTO `spell_affect` VALUES +(16833,0,0,0,0,0,0,0x0000E000E2000000,0), +(16834,0,0,0,0,0,0,0x0000E000E2000000,0), +(16835,0,0,0,0,0,0,0x0000E000E2000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (16886); +INSERT INTO `spell_affect` VALUES +(16886,0,0,0,0,0,0,0x0000000001000265,1); + +DELETE FROM `spell_affect` WHERE `entry` IN (16819,16820); +INSERT INTO `spell_affect` VALUES +(16819,0,0,0,0,0,0,0x0002122000600707,0), +(16820,0,0,0,0,0,0,0x0002122000600707,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17116,38466); +INSERT INTO `spell_affect` VALUES +(17116,0,0,0,0,0,0,0x0002002010000261,0), +(38466,0,0,0,0,0,0,0x0008000000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37287); +INSERT INTO `spell_affect` VALUES +(37287,0,0,0,0,0,0,0x0000E000E2000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (17118,17119,17120,17121,17122); +INSERT INTO `spell_affect` VALUES +(17118,0,0,0,0,0,0,0x001005D000E193F7,0), +(17118,1,0,0,0,0,0,0x0004103000340750,0), +(17119,0,0,0,0,0,0,0x001005D000E193F7,0), +(17119,1,0,0,0,0,0,0x0004103000340750,0), +(17120,0,0,0,0,0,0,0x001005D000E193F7,0), +(17120,1,0,0,0,0,0,0x0004103000340750,0), +(17121,0,0,0,0,0,0,0x001005D000E193F7,0), +(17121,1,0,0,0,0,0,0x0004103000340750,0), +(17122,0,0,0,0,0,0,0x001005D000E193F7,0), +(17122,1,0,0,0,0,0,0x0004103000340750,0); diff --git a/sql/updates/0.8/4597_realmlist.sql b/sql/updates/0.8/4597_realmlist.sql new file mode 100644 index 000000000..6cab83dfe --- /dev/null +++ b/sql/updates/0.8/4597_realmlist.sql @@ -0,0 +1,2 @@ +ALTER TABLE realmd.realmlist + ADD COLUMN `population` float(0) UNSIGNED NOT NULL DEFAULT 0.0 AFTER `allowedSecurityLevel`; diff --git a/sql/updates/0.8/4599_command.sql b/sql/updates/0.8/4599_command.sql new file mode 100644 index 000000000..50eac0de3 --- /dev/null +++ b/sql/updates/0.8/4599_command.sql @@ -0,0 +1,5 @@ +DELETE FROM command WHERE name IN ('cast','castback'); +INSERT INTO `command` VALUES +('cast',3,'Syntax: .cast #spellid\r\n Cast #spellid to selected target. If no target selected cast to self.'), +('castback',3,'Syntax: .castback #spellid\r\n Selected target cast #spellid to your character.'); + diff --git a/sql/updates/0.8/4603_spell_affect.sql b/sql/updates/0.8/4603_spell_affect.sql new file mode 100644 index 000000000..4d3c72283 --- /dev/null +++ b/sql/updates/0.8/4603_spell_affect.sql @@ -0,0 +1,83 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (34453,34454); +INSERT INTO `spell_affect` VALUES +(34453,1,0,0,0,0,0,0x0000000400000000,0), +(34454,1,0,0,0,0,0,0x0000000400000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (24348); +INSERT INTO `spell_affect` VALUES +(24348,0,0,0,0,0,0,0x0000000000200000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (34462,34464,34465); +INSERT INTO `spell_affect` VALUES +(34462,1,0,0,0,0,0,0x0000000800000000,0), +(34464,1,0,0,0,0,0,0x0000000800000000,0), +(34465,1,0,0,0,0,0,0x0000000800000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19239,19245); +INSERT INTO `spell_affect` VALUES +(19239,0,0,0,0,0,0,0x0000000000000018,0), +(19239,1,0,0,0,0,0,0x0000000000000004,0), +(19245,0,0,0,0,0,0,0x0000000000000018,0), +(19245,1,0,0,0,0,0,0x0000000000000004,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19416,19417,19418,19419,19420); +INSERT INTO `spell_affect` VALUES +(19416,0,0,0,0,0,0,0x000010810007DA00,0), +(19417,0,0,0,0,0,0,0x000010810007DA00,0), +(19418,0,0,0,0,0,0,0x000010810007DA00,0), +(19419,0,0,0,0,0,0,0x000010810007DA00,0), +(19420,0,0,0,0,0,0,0x000010810007DA00,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (34455,34459,34460); +INSERT INTO `spell_affect` VALUES +(34455,0,0,0,0,0,0,0x0000002000000000,0), +(34455,1,0,0,0,0,0,0x0000004000000000,0), +(34459,0,0,0,0,0,0,0x0000002000000000,0), +(34459,1,0,0,0,0,0,0x0000004000000000,0), +(34460,0,0,0,0,0,0,0x0000002000000000,0), +(34460,1,0,0,0,0,0,0x0000004000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (35029,35030); +INSERT INTO `spell_affect` VALUES +(35029,1,0,0,0,0,0,0x0000080000000000,0), +(35030,1,0,0,0,0,0,0x0000080000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19572,19573); +INSERT INTO `spell_affect` VALUES +(19572,1,0,0,0,0,0,0x0000000000800000,0), +(19573,1,0,0,0,0,0,0x0000000000800000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19464,19465,19466,19467,19468); +INSERT INTO `spell_affect` VALUES +(19464,0,0,0,0,0,0,0x0000010000004000,0), +(19464,1,0,0,0,0,0,0x0000008000000000,0), +(19464,2,0,0,0,0,0,0x000011800000C000,0), +(19465,0,0,0,0,0,0,0x0000010000004000,0), +(19465,1,0,0,0,0,0,0x0000008000000000,0), +(19465,2,0,0,0,0,0,0x000011800000C000,0), +(19466,0,0,0,0,0,0,0x0000010000004000,0), +(19466,1,0,0,0,0,0,0x0000008000000000,0), +(19466,2,0,0,0,0,0,0x000011800000C000,0), +(19467,0,0,0,0,0,0,0x0000010000004000,0), +(19467,1,0,0,0,0,0,0x0000008000000000,0), +(19467,2,0,0,0,0,0,0x000011800000C000,0), +(19468,0,0,0,0,0,0,0x0000010000004000,0), +(19468,1,0,0,0,0,0,0x0000008000000000,0), +(19468,2,0,0,0,0,0,0x000011800000C000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (19485,19487,19488,19489,19490); +INSERT INTO `spell_affect` VALUES +(19485,0,0,0,0,0,0,0x0000000000000001,0), +(19487,0,0,0,0,0,0,0x0000000000000001,0), +(19488,0,0,0,0,0,0,0x0000000000000001,0), +(19489,0,0,0,0,0,0,0x0000000000000001,0), +(19490,0,0,0,0,0,0,0x0000000000000001,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (32203,41660); +INSERT INTO `spell_affect` VALUES +(32203,1,0,0,0,0,0,0x0001100001C22000,0), +(41660,1,0,0,0,0,0,0x0001100001C22000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37508); +INSERT INTO `spell_affect` VALUES +(37508,0,0,0,0,0,0,0x0000000100061800,0); diff --git a/sql/updates/0.8/4605_creature_addon.sql b/sql/updates/0.8/4605_creature_addon.sql new file mode 100644 index 000000000..5f1bf1a1f --- /dev/null +++ b/sql/updates/0.8/4605_creature_addon.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_addon` + DROP KEY `guid`, + ADD PRIMARY KEY (`guid`); diff --git a/sql/updates/0.8/4605_creature_template_addon.sql b/sql/updates/0.8/4605_creature_template_addon.sql new file mode 100644 index 000000000..d49df0793 --- /dev/null +++ b/sql/updates/0.8/4605_creature_template_addon.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template_addon` + DROP KEY `entry`, + ADD PRIMARY KEY(`entry`); diff --git a/sql/updates/0.8/4608_game_graveyard_zone.sql b/sql/updates/0.8/4608_game_graveyard_zone.sql new file mode 100644 index 000000000..1dcff5e11 --- /dev/null +++ b/sql/updates/0.8/4608_game_graveyard_zone.sql @@ -0,0 +1,25 @@ +ALTER TABLE `game_graveyard_zone` + DROP COLUMN `ghost_map`; + +UPDATE `game_graveyard_zone` as G1,`game_graveyard_zone` as G2 + SET G1.`faction` = 0 + WHERE G1.`id`=G2.`id` AND G1.`ghost_zone`=G2.`ghost_zone` AND G1.`faction`=67 AND (G2.`faction`=469 OR G2.`faction`=0); + +UPDATE `game_graveyard_zone` as G1,`game_graveyard_zone` as G2 + SET G1.`faction` = 0 + WHERE G1.`id`=G2.`id` AND G1.`ghost_zone`=G2.`ghost_zone` AND G1.`faction`=469 AND (G2.`faction`=67 OR G2.`faction`=0); + +DELETE FROM `game_graveyard_zone` WHERE `ghost_zone`= 0; + +DROP TABLE IF EXISTS `game_graveyard_zone_new`; +CREATE TABLE `game_graveyard_zone_new` ( + `id` int(11) unsigned NOT NULL default '0', + `ghost_zone` int(11) unsigned NOT NULL default '0', + `faction` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`id`,`ghost_zone`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Trigger System'; + +INSERT IGNORE INTO `game_graveyard_zone_new` SELECT `id`,`ghost_zone`,`faction` FROM `game_graveyard_zone`; + +DROP TABLE `game_graveyard_zone`; +RENAME TABLE `game_graveyard_zone_new` TO `game_graveyard_zone`; diff --git a/sql/updates/0.8/4615_creature_template.sql b/sql/updates/0.8/4615_creature_template.sql new file mode 100644 index 000000000..6b1ebaa41 --- /dev/null +++ b/sql/updates/0.8/4615_creature_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template` + ADD COLUMN `modelid_A2` INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER `modelid_A`, + ADD COLUMN `modelid_H2` INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER `modelid_H`; diff --git a/sql/updates/0.8/4627_game_event_model_equip.sql b/sql/updates/0.8/4627_game_event_model_equip.sql new file mode 100644 index 000000000..53ceda549 --- /dev/null +++ b/sql/updates/0.8/4627_game_event_model_equip.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `game_event_model_equip`; +CREATE TABLE `game_event_model_equip` ( + `guid` int(11) unsigned NOT NULL DEFAULT '0', + `modelid` int(11) unsigned NOT NULL DEFAULT '0', + `equipment_id` int(11) unsigned NOT NULL DEFAULT '0', + `event` mediumint(9) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.9/4615_creature_template.sql b/sql/updates/0.9/4615_creature_template.sql new file mode 100644 index 000000000..6b1ebaa41 --- /dev/null +++ b/sql/updates/0.9/4615_creature_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `creature_template` + ADD COLUMN `modelid_A2` INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER `modelid_A`, + ADD COLUMN `modelid_H2` INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER `modelid_H`; diff --git a/sql/updates/0.9/4627_game_event_model_equip.sql b/sql/updates/0.9/4627_game_event_model_equip.sql new file mode 100644 index 000000000..53ceda549 --- /dev/null +++ b/sql/updates/0.9/4627_game_event_model_equip.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `game_event_model_equip`; +CREATE TABLE `game_event_model_equip` ( + `guid` int(11) unsigned NOT NULL DEFAULT '0', + `modelid` int(11) unsigned NOT NULL DEFAULT '0', + `equipment_id` int(11) unsigned NOT NULL DEFAULT '0', + `event` mediumint(9) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.9/4628.sql b/sql/updates/0.9/4628.sql new file mode 100644 index 000000000..a6a19aa8f --- /dev/null +++ b/sql/updates/0.9/4628.sql @@ -0,0 +1,76 @@ +ALTER TABLE `character` + MODIFY COLUMN `logout_time` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `is_logout_resting` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0; + +ALTER TABLE `character_kill` + MODIFY COLUMN `guid` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `victim_guid` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `count` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0; + +ALTER TABLE `character_ticket` + MODIFY COLUMN `ticket_id` int(11) UNSIGNED NOT NULL DEFAULT NULL AUTO_INCREMENT; + +ALTER TABLE `guild_member` + MODIFY COLUMN `guid` int(11) UNSIGNED NOT NULL DEFAULT 0, ROW_FORMAT = FIXED; + +ALTER TABLE `group` + MODIFY COLUMN `leaderGuid` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `mainTank` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `mainAssistant` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `lootMethod` TINYINT(4) UNSIGNED NOT NULL, + MODIFY COLUMN `looterGuid` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `lootThreshold` TINYINT(4) UNSIGNED NOT NULL, + MODIFY COLUMN `icon1` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `icon2` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `icon3` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `icon4` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `icon5` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `icon6` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `icon7` int(11) unsigned NOT NULL, + MODIFY COLUMN `icon8` int(11) unsigned NOT NULL, + MODIFY COLUMN `isRaid` tinyint(1) unsigned NOT NULL; + +ALTER TABLE `group_member` + MODIFY COLUMN `leaderGuid` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `memberGuid` int(11) UNSIGNED NOT NULL, + MODIFY COLUMN `assistant` TINYINT(1) UNSIGNED NOT NULL, + MODIFY COLUMN `subgroup` SMALLINT(6) UNSIGNED NOT NULL, ROW_FORMAT = FIXED; + +ALTER TABLE `item_text` + MODIFY COLUMN `id` int(11) UNSIGNED NOT NULL DEFAULT 0, ROW_FORMAT = FIXED; + +ALTER TABLE `npc_gossip` + MODIFY COLUMN `id` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `npc_guid` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `gossip_type` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `textid` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `option_count` int(11) UNSIGNED DEFAULT NULL; + +ALTER TABLE `npc_text` + MODIFY COLUMN `ID` int(11) UNSIGNED NOT NULL DEFAULT 0; + +ALTER TABLE `npc_trainer` + MODIFY COLUMN `entry` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `spell` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `spellcost` int(11) UNSIGNED DEFAULT 0; + +ALTER TABLE `page_text` + MODIFY COLUMN `entry` int(11) UNSIGNED NOT NULL DEFAULT 0; + +ALTER TABLE `pet_name_generation` + MODIFY COLUMN `id` int(11) UNSIGNED NOT NULL DEFAULT NULL AUTO_INCREMENT, + MODIFY COLUMN `entry` int(11) UNSIGNED NOT NULL DEFAULT 0; + +ALTER TABLE `quest_template` + MODIFY COLUMN `SuggestedPlayers` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `DetailsEmote1` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `DetailsEmote2` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `DetailsEmote3` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `DetailsEmote4` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `IncompleteEmote` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `CompleteEmote` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `OfferRewardEmote1` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `OfferRewardEmote2` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `OfferRewardEmote3` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `OfferRewardEmote4` int(11) UNSIGNED NOT NULL DEFAULT 0, + MODIFY COLUMN `CompleteScript` int(11) UNSIGNED NOT NULL DEFAULT 0; diff --git a/sql/updates/0.9/4632_areatrigger_teleport.sql b/sql/updates/0.9/4632_areatrigger_teleport.sql new file mode 100644 index 000000000..ef7a345f7 --- /dev/null +++ b/sql/updates/0.9/4632_areatrigger_teleport.sql @@ -0,0 +1,12 @@ +ALTER TABLE `areatrigger_template` + DROP COLUMN `trigger_map`, + DROP COLUMN `trigger_position_x`, + DROP COLUMN `trigger_position_y`, + DROP COLUMN `trigger_position_z`; + + +DELETE FROM `areatrigger_template` + WHERE `required_level` = 0 AND `required_item` = 0 + AND `target_map` = 0 AND `target_position_x` = 0 AND `target_position_y` = 0 AND `target_position_z` = 0 AND `target_orientation` = 0; + +ALTER TABLE `areatrigger_template` RENAME TO `areatrigger_teleport`; diff --git a/sql/updates/0.9/4633_spell_teleport.sql b/sql/updates/0.9/4633_spell_teleport.sql new file mode 100644 index 000000000..055fadba1 --- /dev/null +++ b/sql/updates/0.9/4633_spell_teleport.sql @@ -0,0 +1,17 @@ + +DROP TABLE IF EXISTS `spell_teleport`; +CREATE TABLE `spell_teleport` ( + `id` int(11) unsigned NOT NULL default '0' COMMENT 'Identifier', + `target_map` int(11) unsigned NOT NULL default '0', + `target_position_x` float NOT NULL default '0', + `target_position_y` float NOT NULL default '0', + `target_position_z` float NOT NULL default '0', + `target_orientation` float NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System'; + +INSERT INTO `spell_teleport` +SELECT `id`,`target_map`,`target_position_x`,`target_position_y`,`target_position_z`,`target_orientation` +FROM `areatrigger_teleport`; + +DELETE FROM `spell_teleport` WHERE `target_position_x` = 0 AND `target_position_y` = 0 AND `target_position_z` = 0; diff --git a/sql/updates/0.9/4640_command.sql b/sql/updates/0.9/4640_command.sql new file mode 100644 index 000000000..01c7ecefb --- /dev/null +++ b/sql/updates/0.9/4640_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('gotrigger'); +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('gotrigger',2,'Syntax: .gotrigger #trigger_id\r\n\r\nTeleport your character to areatrigger with id #trigger_id. Character will be teleported to trigger target if selected areatrigger is telporting trigger.'); + diff --git a/sql/updates/0.9/4656_game_event_creature_quest.sql b/sql/updates/0.9/4656_game_event_creature_quest.sql new file mode 100644 index 000000000..9fcb04915 --- /dev/null +++ b/sql/updates/0.9/4656_game_event_creature_quest.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `game_event_creature_quest`; +CREATE TABLE `game_event_creature_quest` ( + `id` int(11) unsigned NOT NULL default '0', + `quest` int(11) unsigned NOT NULL default '0', + `event` mediumint(9) unsigned NOT NULL default '0', + PRIMARY KEY (`id`,`quest`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.9/4657_quest_template.sql b/sql/updates/0.9/4657_quest_template.sql new file mode 100644 index 000000000..4f61a8846 --- /dev/null +++ b/sql/updates/0.9/4657_quest_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE `quest_template` + CHANGE `RequiredSkillValue` `RequiredSkillValue` int(11) unsigned NOT NULL default '0'; + +UPDATE `quest_template` + SET `RequiredSkillValue` = 0 WHERE `RequiredSkillValue` = 1 AND `ZoneOrSort` >= 0; \ No newline at end of file diff --git a/sql/updates/0.9/4664.sql b/sql/updates/0.9/4664.sql new file mode 100644 index 000000000..ee3a3a8ea --- /dev/null +++ b/sql/updates/0.9/4664.sql @@ -0,0 +1,982 @@ +CREATE DATABASE `characters` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +GRANT ALL PRIVILEGES ON `characters` . * TO 'mangos'@'localhost' WITH GRANT OPTION; + +DROP TABLE IF EXISTS `characters`.`arena_team`; +CREATE TABLE `characters`.`arena_team` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `name` char(255) NOT NULL, + `captainguid` int(10) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `EmblemStyle` int(10) unsigned NOT NULL default '0', + `EmblemColor` int(10) unsigned NOT NULL default '0', + `BorderStyle` int(10) unsigned NOT NULL default '0', + `BorderColor` int(10) unsigned NOT NULL default '0', + `BackgroundColor` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`arenateamid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `arena_team` +-- + +/*!40000 ALTER TABLE `arena_team` DISABLE KEYS */; +/*!40000 ALTER TABLE `arena_team` ENABLE KEYS */; + + +-- +-- Definition of table `arena_team_member` +-- + +DROP TABLE IF EXISTS `characters`.`arena_team_member`; +CREATE TABLE `characters`.`arena_team_member` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `guid` int(10) unsigned NOT NULL default '0', + `played_week` int(10) unsigned NOT NULL default '0', + `wons_week` int(10) unsigned NOT NULL default '0', + `played_season` int(10) unsigned NOT NULL default '0', + `wons_season` int(10) unsigned NOT NULL default '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `arena_team_member` +-- + +/*!40000 ALTER TABLE `arena_team_member` DISABLE KEYS */; +/*!40000 ALTER TABLE `arena_team_member` ENABLE KEYS */; + + +-- +-- Definition of table `arena_team_stats` +-- + +DROP TABLE IF EXISTS `characters`.`arena_team_stats`; +CREATE TABLE `characters`.`arena_team_stats` ( + `arenateamid` int(10) unsigned NOT NULL default '0', + `rating` int(10) unsigned NOT NULL default '0', + `games` int(10) unsigned NOT NULL default '0', + `wins` int(10) unsigned NOT NULL default '0', + `played` int(10) unsigned NOT NULL default '0', + `wins2` int(10) unsigned NOT NULL default '0', + `rank` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`arenateamid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `arena_team_stats` +-- + +/*!40000 ALTER TABLE `arena_team_stats` DISABLE KEYS */; +/*!40000 ALTER TABLE `arena_team_stats` ENABLE KEYS */; + + +-- +-- Definition of table `auctionhouse` +-- + +DROP TABLE IF EXISTS `characters`.`auctionhouse`; +CREATE TABLE `characters`.`auctionhouse` ( + `id` int(11) unsigned NOT NULL default '0', + `auctioneerguid` int(11) unsigned NOT NULL default '0', + `itemguid` int(11) unsigned NOT NULL default '0', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `itemowner` int(11) unsigned NOT NULL default '0', + `buyoutprice` int(11) NOT NULL default '0', + `time` bigint(40) NOT NULL default '0', + `buyguid` int(11) unsigned NOT NULL default '0', + `lastbid` int(11) NOT NULL default '0', + `startbid` int(11) NOT NULL default '0', + `deposit` int(11) NOT NULL default '0', + `location` tinyint(3) unsigned NOT NULL default '3', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `auctionhouse` +-- + +/*!40000 ALTER TABLE `auctionhouse` DISABLE KEYS */; +/*!40000 ALTER TABLE `auctionhouse` ENABLE KEYS */; + + +-- +-- Definition of table `bugreport` +-- + +DROP TABLE IF EXISTS `characters`.`bugreport`; +CREATE TABLE `characters`.`bugreport` ( + `id` int(11) NOT NULL auto_increment COMMENT 'Identifier', + `type` varchar(255) NOT NULL default '', + `content` varchar(255) NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Debug System'; + +-- +-- Dumping data for table `bugreport` +-- + +/*!40000 ALTER TABLE `bugreport` DISABLE KEYS */; +/*!40000 ALTER TABLE `bugreport` ENABLE KEYS */; + + +-- +-- Definition of table `character` +-- + +DROP TABLE IF EXISTS `characters`.`character`; +CREATE TABLE `characters`.`character` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `account` int(11) unsigned NOT NULL default '0' COMMENT 'Account Identifier', + `data` longtext, + `name` varchar(12) NOT NULL default '', + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `orientation` float NOT NULL default '0', + `taximask` longtext, + `online` tinyint(3) unsigned NOT NULL default '0', + `cinematic` tinyint(3) unsigned NOT NULL default '0', + `totaltime` int(11) unsigned NOT NULL default '0', + `leveltime` int(11) unsigned NOT NULL default '0', + `logout_time` int(11) unsigned NOT NULL default '0', + `is_logout_resting` tinyint(3) unsigned NOT NULL default '0', + `rest_bonus` float NOT NULL default '0', + `resettalents_cost` int(11) unsigned NOT NULL default '0', + `resettalents_time` bigint(20) unsigned NOT NULL default '0', + `trans_x` float NOT NULL default '0', + `trans_y` float NOT NULL default '0', + `trans_z` float NOT NULL default '0', + `trans_o` float NOT NULL default '0', + `transguid` bigint(20) unsigned NOT NULL default '0', + `gmstate` tinyint(3) unsigned NOT NULL default '0', + `stable_slots` tinyint(1) unsigned NOT NULL default '0', + `at_login` int(11) unsigned NOT NULL default '0', + `zone` int(11) unsigned NOT NULL default '0', + `last_honor_date` int(11) unsigned NOT NULL default '0', + `pending_honor` float NOT NULL default '0', + `pending_kills` int(11) NOT NULL default '0', + `last_kill_date` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`), + KEY `idx_account` (`account`), + KEY `idx_online` (`online`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character` +-- + +/*!40000 ALTER TABLE `character` DISABLE KEYS */; +/*!40000 ALTER TABLE `character` ENABLE KEYS */; + + +-- +-- Definition of table `character_action` +-- + +DROP TABLE IF EXISTS `characters`.`character_action`; +CREATE TABLE `characters`.`character_action` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `button` tinyint(3) unsigned NOT NULL default '0', + `action` smallint(5) unsigned NOT NULL default '0', + `type` tinyint(3) unsigned NOT NULL default '0', + `misc` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`button`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_action` +-- + +/*!40000 ALTER TABLE `character_action` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_action` ENABLE KEYS */; + + +-- +-- Definition of table `character_aura` +-- + +DROP TABLE IF EXISTS `characters`.`character_aura`; +CREATE TABLE `characters`.`character_aura` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `amount` int(11) NOT NULL default '0', + `maxduration` int(11) NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + `remaincharges` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`,`effect_index`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_aura` +-- + +/*!40000 ALTER TABLE `character_aura` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_aura` ENABLE KEYS */; + + +-- +-- Definition of table `character_gifts` +-- + +DROP TABLE IF EXISTS `characters`.`character_gifts`; +CREATE TABLE `characters`.`character_gifts` ( + `guid` int(20) unsigned NOT NULL default '0', + `item_guid` int(11) unsigned NOT NULL default '0', + `entry` int(20) unsigned NOT NULL default '0', + `flags` int(20) unsigned NOT NULL default '0', + PRIMARY KEY (`item_guid`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `character_gifts` +-- + +/*!40000 ALTER TABLE `character_gifts` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_gifts` ENABLE KEYS */; + + +-- +-- Definition of table `character_homebind` +-- + +DROP TABLE IF EXISTS `characters`.`character_homebind`; +CREATE TABLE `characters`.`character_homebind` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `zone` int(11) unsigned NOT NULL default '0' COMMENT 'Zone Identifier', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_homebind` +-- + +/*!40000 ALTER TABLE `character_homebind` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_homebind` ENABLE KEYS */; + + +-- +-- Definition of table `character_instance` +-- + +DROP TABLE IF EXISTS `characters`.`character_instance`; +CREATE TABLE `characters`.`character_instance` ( + `guid` int(11) unsigned NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0', + `instance` bigint(40) NOT NULL default '0', + `leader` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`map`), + KEY `instance` (`instance`), + KEY `leader` (`leader`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `character_instance` +-- + +/*!40000 ALTER TABLE `character_instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_instance` ENABLE KEYS */; + + +-- +-- Definition of table `character_inventory` +-- + +DROP TABLE IF EXISTS `characters`.`character_inventory`; +CREATE TABLE `characters`.`character_inventory` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `bag` int(11) unsigned NOT NULL default '0', + `slot` tinyint(3) unsigned NOT NULL default '0', + `item` int(11) unsigned NOT NULL default '0' COMMENT 'Item Global Unique Identifier', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + PRIMARY KEY (`item`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_inventory` +-- + +/*!40000 ALTER TABLE `character_inventory` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_inventory` ENABLE KEYS */; + + +-- +-- Definition of table `character_kill` +-- + +DROP TABLE IF EXISTS `characters`.`character_kill`; +CREATE TABLE `characters`.`character_kill` ( + `guid` int(11) unsigned NOT NULL default '0', + `victim_guid` int(11) unsigned NOT NULL default '0', + `count` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`victim_guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Kills Yesterday'; + +-- +-- Dumping data for table `character_kill` +-- + +/*!40000 ALTER TABLE `character_kill` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_kill` ENABLE KEYS */; + + +-- +-- Definition of table `character_pet` +-- + +DROP TABLE IF EXISTS `characters`.`character_pet`; +CREATE TABLE `characters`.`character_pet` ( + `id` int(11) unsigned NOT NULL default '0', + `entry` int(11) unsigned NOT NULL default '0', + `owner` int(11) unsigned NOT NULL default '0', + `modelid` int(11) unsigned default '0', + `CreatedBySpell` int(11) unsigned NOT NULL default '0', + `PetType` tinyint(3) unsigned NOT NULL default '0', + `level` int(11) unsigned NOT NULL default '1', + `exp` int(11) unsigned NOT NULL default '0', + `nextlvlexp` int(11) unsigned NOT NULL default '100', + `Reactstate` tinyint(1) unsigned NOT NULL default '0', + `Commandstate` tinyint(1) unsigned NOT NULL default '1', + `loyaltypoints` int(11) NOT NULL default '0', + `loyalty` int(11) unsigned NOT NULL default '0', + `trainpoint` int(11) NOT NULL default '0', + `name` varchar(100) default 'Pet', + `renamed` tinyint(1) unsigned NOT NULL default '0', + `slot` int(11) unsigned NOT NULL default '0', + `curhealth` int(11) unsigned NOT NULL default '1', + `curmana` int(11) unsigned NOT NULL default '0', + `curhappiness` int(11) unsigned NOT NULL default '0', + `savetime` bigint(20) unsigned NOT NULL default '0', + `resettalents_cost` int(11) unsigned NOT NULL default '0', + `resettalents_time` bigint(20) unsigned NOT NULL default '0', + `ABData` longtext, + `TeachSpelldata` longtext, + PRIMARY KEY (`id`), + KEY `owner` (`owner`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- +-- Dumping data for table `character_pet` +-- + +/*!40000 ALTER TABLE `character_pet` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_pet` ENABLE KEYS */; + + +-- +-- Definition of table `character_queststatus` +-- + +DROP TABLE IF EXISTS `characters`.`character_queststatus`; +CREATE TABLE `characters`.`character_queststatus` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + `status` int(11) unsigned NOT NULL default '0', + `rewarded` tinyint(1) unsigned NOT NULL default '0', + `explored` tinyint(1) unsigned NOT NULL default '0', + `timer` bigint(20) unsigned NOT NULL default '0', + `mobcount1` int(11) unsigned NOT NULL default '0', + `mobcount2` int(11) unsigned NOT NULL default '0', + `mobcount3` int(11) unsigned NOT NULL default '0', + `mobcount4` int(11) unsigned NOT NULL default '0', + `itemcount1` int(11) unsigned NOT NULL default '0', + `itemcount2` int(11) unsigned NOT NULL default '0', + `itemcount3` int(11) unsigned NOT NULL default '0', + `itemcount4` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`quest`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_queststatus` +-- + +/*!40000 ALTER TABLE `character_queststatus` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus` ENABLE KEYS */; + + +-- +-- Definition of table `character_queststatus_daily` +-- + +DROP TABLE IF EXISTS `characters`.`character_queststatus_daily`; +CREATE TABLE `characters`.`character_queststatus_daily` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`quest`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_queststatus_daily` +-- + +/*!40000 ALTER TABLE `character_queststatus_daily` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus_daily` ENABLE KEYS */; + + +-- +-- Definition of table `character_reputation` +-- + +DROP TABLE IF EXISTS `characters`.`character_reputation`; +CREATE TABLE `characters`.`character_reputation` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `faction` int(11) unsigned NOT NULL default '0', + `standing` int(11) NOT NULL default '0', + `flags` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`faction`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_reputation` +-- + +/*!40000 ALTER TABLE `character_reputation` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_reputation` ENABLE KEYS */; + + +-- +-- Definition of table `character_social` +-- + +DROP TABLE IF EXISTS `characters`.`character_social`; +CREATE TABLE `characters`.`character_social` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `name` varchar(21) NOT NULL default '', + `friend` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `flags` varchar(21) NOT NULL default '', + PRIMARY KEY (`guid`,`friend`,`flags`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_social` +-- + +/*!40000 ALTER TABLE `character_social` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_social` ENABLE KEYS */; + + +-- +-- Definition of table `character_spell` +-- + +DROP TABLE IF EXISTS `characters`.`character_spell`; +CREATE TABLE `characters`.`character_spell` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `slot` int(11) unsigned NOT NULL default '0', + `active` tinyint(3) unsigned NOT NULL default '1', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_spell` +-- + +/*!40000 ALTER TABLE `character_spell` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_spell` ENABLE KEYS */; + + +-- +-- Definition of table `character_spell_cooldown` +-- + +DROP TABLE IF EXISTS `characters`.`character_spell_cooldown`; +CREATE TABLE `characters`.`character_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `item` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `character_spell_cooldown` +-- + +/*!40000 ALTER TABLE `character_spell_cooldown` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_spell_cooldown` ENABLE KEYS */; + + +-- +-- Definition of table `character_ticket` +-- + +DROP TABLE IF EXISTS `characters`.`character_ticket`; +CREATE TABLE `characters`.`character_ticket` ( + `ticket_id` int(11) unsigned NOT NULL auto_increment, + `guid` int(11) unsigned NOT NULL default '0', + `ticket_text` text, + `ticket_category` int(1) NOT NULL default '0', + PRIMARY KEY (`ticket_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_ticket` +-- + +/*!40000 ALTER TABLE `character_ticket` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_ticket` ENABLE KEYS */; + + +-- +-- Definition of table `character_tutorial` +-- + +DROP TABLE IF EXISTS `characters`.`character_tutorial`; +CREATE TABLE `characters`.`character_tutorial` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `tut0` int(11) unsigned NOT NULL default '0', + `tut1` int(11) unsigned NOT NULL default '0', + `tut2` int(11) unsigned NOT NULL default '0', + `tut3` int(11) unsigned NOT NULL default '0', + `tut4` int(11) unsigned NOT NULL default '0', + `tut5` int(11) unsigned NOT NULL default '0', + `tut6` int(11) unsigned NOT NULL default '0', + `tut7` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; + +-- +-- Dumping data for table `character_tutorial` +-- + +/*!40000 ALTER TABLE `character_tutorial` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_tutorial` ENABLE KEYS */; + + +-- +-- Definition of table `corpse` +-- + +DROP TABLE IF EXISTS `characters`.`corpse`; +CREATE TABLE `characters`.`corpse` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `player` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `position_x` float NOT NULL default '0', + `position_y` float NOT NULL default '0', + `position_z` float NOT NULL default '0', + `orientation` float NOT NULL default '0', + `zone` int(11) unsigned NOT NULL default '38' COMMENT 'Zone Identifier', + `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', + `data` longtext, + `time` timestamp NOT NULL default '0000-00-00 00:00:00', + `bones_flag` tinyint(3) NOT NULL default '0', + `instance` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`), + KEY `idx_bones_flag` (`bones_flag`), + KEY `instance` (`instance`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Death System'; + +-- +-- Dumping data for table `corpse` +-- + +/*!40000 ALTER TABLE `corpse` DISABLE KEYS */; +/*!40000 ALTER TABLE `corpse` ENABLE KEYS */; + + +-- +-- Definition of table `group` +-- + +DROP TABLE IF EXISTS `characters`.`group`; +CREATE TABLE `characters`.`group` ( + `leaderGuid` int(11) unsigned NOT NULL, + `mainTank` int(11) unsigned NOT NULL, + `mainAssistant` int(11) unsigned NOT NULL, + `lootMethod` tinyint(4) unsigned NOT NULL, + `looterGuid` int(11) unsigned NOT NULL, + `lootThreshold` tinyint(4) unsigned NOT NULL, + `icon1` int(11) unsigned NOT NULL, + `icon2` int(11) unsigned NOT NULL, + `icon3` int(11) unsigned NOT NULL, + `icon4` int(11) unsigned NOT NULL, + `icon5` int(11) unsigned NOT NULL, + `icon6` int(11) unsigned NOT NULL, + `icon7` int(11) unsigned NOT NULL, + `icon8` int(11) unsigned NOT NULL, + `isRaid` tinyint(1) unsigned NOT NULL, + PRIMARY KEY (`leaderGuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Groups'; + +-- +-- Dumping data for table `group` +-- + +/*!40000 ALTER TABLE `group` DISABLE KEYS */; +/*!40000 ALTER TABLE `group` ENABLE KEYS */; + + +-- +-- Definition of table `group_member` +-- + +DROP TABLE IF EXISTS `characters`.`group_member`; +CREATE TABLE `characters`.`group_member` ( + `leaderGuid` int(11) unsigned NOT NULL, + `memberGuid` int(11) unsigned NOT NULL, + `assistant` tinyint(1) unsigned NOT NULL, + `subgroup` smallint(6) unsigned NOT NULL, + PRIMARY KEY (`leaderGuid`,`memberGuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Groups'; + +-- +-- Dumping data for table `group_member` +-- + +/*!40000 ALTER TABLE `group_member` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_member` ENABLE KEYS */; + + +-- +-- Definition of table `guild` +-- + +DROP TABLE IF EXISTS `characters`.`guild`; +CREATE TABLE `characters`.`guild` ( + `guildid` int(6) unsigned NOT NULL default '0', + `name` varchar(255) NOT NULL default '', + `leaderguid` int(6) unsigned NOT NULL default '0', + `EmblemStyle` int(5) NOT NULL default '0', + `EmblemColor` int(5) NOT NULL default '0', + `BorderStyle` int(5) NOT NULL default '0', + `BorderColor` int(5) NOT NULL default '0', + `BackgroundColor` int(5) NOT NULL default '0', + `info` text NOT NULL, + `MOTD` varchar(255) NOT NULL default '', + `createdate` datetime default NULL, + PRIMARY KEY (`guildid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +-- +-- Dumping data for table `guild` +-- + +/*!40000 ALTER TABLE `guild` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild` ENABLE KEYS */; + + +-- +-- Definition of table `guild_member` +-- + +DROP TABLE IF EXISTS `characters`.`guild_member`; +CREATE TABLE `characters`.`guild_member` ( + `guildid` int(6) unsigned NOT NULL default '0', + `guid` int(11) unsigned NOT NULL default '0', + `rank` tinyint(2) unsigned NOT NULL default '0', + `Pnote` varchar(255) NOT NULL default '', + `OFFnote` varchar(255) NOT NULL default '' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Guild System'; + +-- +-- Dumping data for table `guild_member` +-- + +/*!40000 ALTER TABLE `guild_member` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_member` ENABLE KEYS */; + + +-- +-- Definition of table `guild_rank` +-- + +DROP TABLE IF EXISTS `characters`.`guild_rank`; +CREATE TABLE `characters`.`guild_rank` ( + `guildid` int(6) unsigned NOT NULL default '0', + `rid` int(11) unsigned NOT NULL, + `rname` varchar(255) NOT NULL default '', + `rights` int(3) unsigned NOT NULL default '0', + PRIMARY KEY (`guildid`,`rid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +-- +-- Dumping data for table `guild_rank` +-- + +/*!40000 ALTER TABLE `guild_rank` DISABLE KEYS */; +/*!40000 ALTER TABLE `guild_rank` ENABLE KEYS */; + + +-- +-- Definition of table `instance` +-- + +DROP TABLE IF EXISTS `characters`.`instance`; +CREATE TABLE `characters`.`instance` ( + `id` int(11) unsigned NOT NULL default '0', + `map` int(11) unsigned NOT NULL default '0', + `resettime` bigint(40) NOT NULL default '0', + `data` longtext, + PRIMARY KEY (`id`), + KEY `map` (`map`), + KEY `resettime` (`resettime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `instance` +-- + +/*!40000 ALTER TABLE `instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `instance` ENABLE KEYS */; + + +-- +-- Definition of table `item_instance` +-- + +DROP TABLE IF EXISTS `characters`.`item_instance`; +CREATE TABLE `characters`.`item_instance` ( + `guid` int(11) unsigned NOT NULL default '0', + `owner_guid` int(11) unsigned NOT NULL default '0', + `data` longtext, + PRIMARY KEY (`guid`), + KEY `idx_owner_guid` (`owner_guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Item System'; + +-- +-- Dumping data for table `item_instance` +-- + +/*!40000 ALTER TABLE `item_instance` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_instance` ENABLE KEYS */; + + +-- +-- Definition of table `item_text` +-- + +DROP TABLE IF EXISTS `characters`.`item_text`; +CREATE TABLE `characters`.`item_text` ( + `id` int(11) unsigned NOT NULL default '0', + `text` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +-- +-- Dumping data for table `item_text` +-- + +/*!40000 ALTER TABLE `item_text` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_text` ENABLE KEYS */; + + +-- +-- Definition of table `mail` +-- + +DROP TABLE IF EXISTS `characters`.`mail`; +CREATE TABLE `characters`.`mail` ( + `id` int(11) unsigned NOT NULL default '0' COMMENT 'Identifier', + `messageType` tinyint(3) unsigned NOT NULL default '0', + `sender` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `receiver` int(11) unsigned NOT NULL default '0' COMMENT 'Character Global Unique Identifier', + `subject` longtext, + `itemTextId` int(11) unsigned NOT NULL default '0', + `item_guid` int(11) unsigned NOT NULL default '0' COMMENT 'Mail Item Global Unique Identifier', + `item_template` int(11) unsigned NOT NULL default '0' COMMENT 'Item Identifier', + `expire_time` bigint(40) NOT NULL default '0', + `deliver_time` bigint(40) NOT NULL default '0', + `money` int(11) unsigned NOT NULL default '0', + `cod` int(11) unsigned NOT NULL default '0', + `checked` tinyint(3) unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + KEY `idx_receiver` (`receiver`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Mail System'; + +-- +-- Dumping data for table `mail` +-- + +/*!40000 ALTER TABLE `mail` DISABLE KEYS */; +/*!40000 ALTER TABLE `mail` ENABLE KEYS */; + + +-- +-- Definition of table `pet_aura` +-- + +DROP TABLE IF EXISTS `characters`.`pet_aura`; +CREATE TABLE `characters`.`pet_aura` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0', + `effect_index` int(11) unsigned NOT NULL default '0', + `amount` int(11) NOT NULL default '0', + `maxduration` int(11) NOT NULL default '0', + `remaintime` int(11) NOT NULL default '0', + `remaincharges` int(11) NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`,`effect_index`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- +-- Dumping data for table `pet_aura` +-- + +/*!40000 ALTER TABLE `pet_aura` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_aura` ENABLE KEYS */; + + +-- +-- Definition of table `pet_spell` +-- + +DROP TABLE IF EXISTS `characters`.`pet_spell`; +CREATE TABLE `characters`.`pet_spell` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `slot` int(11) unsigned NOT NULL default '0', + `active` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; + +-- +-- Dumping data for table `pet_spell` +-- + +/*!40000 ALTER TABLE `pet_spell` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_spell` ENABLE KEYS */; + + +-- +-- Definition of table `pet_spell_cooldown` +-- + +DROP TABLE IF EXISTS `characters`.`pet_spell_cooldown`; +CREATE TABLE `characters`.`pet_spell_cooldown` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier, Low part', + `spell` int(11) unsigned NOT NULL default '0' COMMENT 'Spell Identifier', + `time` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`guid`,`spell`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `pet_spell_cooldown` +-- + +/*!40000 ALTER TABLE `pet_spell_cooldown` DISABLE KEYS */; +/*!40000 ALTER TABLE `pet_spell_cooldown` ENABLE KEYS */; + + +-- +-- Definition of table `petition` +-- + +DROP TABLE IF EXISTS `characters`.`petition`; +CREATE TABLE `characters`.`petition` ( + `ownerguid` int(10) unsigned NOT NULL, + `petitionguid` int(10) unsigned default '0', + `name` varchar(255) NOT NULL default '', + `type` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`ownerguid`), + UNIQUE KEY `index_ownerguid_petitionguid` (`ownerguid`,`petitionguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + +-- +-- Dumping data for table `petition` +-- + +/*!40000 ALTER TABLE `petition` DISABLE KEYS */; +/*!40000 ALTER TABLE `petition` ENABLE KEYS */; + + +-- +-- Definition of table `petition_sign` +-- + +DROP TABLE IF EXISTS `characters`.`petition_sign`; +CREATE TABLE `characters`.`petition_sign` ( + `ownerguid` int(10) unsigned NOT NULL, + `petitionguid` int(11) unsigned NOT NULL default '0', + `playerguid` int(11) unsigned NOT NULL default '0', + `player_account` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`petitionguid`,`playerguid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; + + +INSERT INTO `characters`.`arena_team` SELECT * FROM `arena_team`; +INSERT INTO `characters`.`arena_team_member` SELECT * FROM `arena_team_member`; +INSERT INTO `characters`.`arena_team_stats` SELECT * FROM `arena_team_stats`; +INSERT INTO `characters`.`auctionhouse` SELECT * FROM `auctionhouse`; +INSERT INTO `characters`.`bugreport` SELECT * FROM `bugreport`; +INSERT INTO `characters`.`character` SELECT * FROM `character`; +INSERT INTO `characters`.`character_action` SELECT * FROM `character_action`; +INSERT INTO `characters`.`character_aura` SELECT * FROM `character_aura`; +INSERT INTO `characters`.`character_gifts` SELECT * FROM `character_gifts`; +INSERT INTO `characters`.`character_homebind` SELECT * FROM `character_homebind`; +INSERT INTO `characters`.`character_instance` SELECT * FROM `character_instance`; +INSERT INTO `characters`.`character_inventory` SELECT * FROM `character_inventory`; +INSERT INTO `characters`.`character_kill` SELECT * FROM `character_kill`; +INSERT INTO `characters`.`character_pet` SELECT * FROM `character_pet`; +INSERT INTO `characters`.`character_queststatus` SELECT * FROM `character_queststatus`; +INSERT INTO `characters`.`character_queststatus_daily` SELECT * FROM `character_queststatus_daily`; +INSERT INTO `characters`.`character_reputation` SELECT * FROM `character_reputation`; +INSERT INTO `characters`.`character_social` SELECT * FROM `character_social`; +INSERT INTO `characters`.`character_spell` SELECT * FROM `character_spell`; +INSERT INTO `characters`.`character_spell_cooldown` SELECT * FROM `character_spell_cooldown`; +INSERT INTO `characters`.`character_ticket` SELECT * FROM `character_ticket`; +INSERT INTO `characters`.`character_tutorial` SELECT * FROM `character_tutorial`; +INSERT INTO `characters`.`corpse` SELECT * FROM `corpse`; +INSERT INTO `characters`.`group` SELECT * FROM `group`; +INSERT INTO `characters`.`group_member` SELECT * FROM `group_member`; +INSERT INTO `characters`.`guild` SELECT * FROM `guild`; +INSERT INTO `characters`.`guild_member` SELECT * FROM `guild_member`; +INSERT INTO `characters`.`guild_rank` SELECT * FROM `guild_rank`; +INSERT INTO `characters`.`instance` SELECT * FROM `instance`; +INSERT INTO `characters`.`item_instance` SELECT * FROM `item_instance`; +INSERT INTO `characters`.`item_text` SELECT * FROM `item_text`; +INSERT INTO `characters`.`mail` SELECT * FROM `mail`; +INSERT INTO `characters`.`pet_aura` SELECT * FROM `pet_aura`; +INSERT INTO `characters`.`pet_spell` SELECT * FROM `pet_spell`; +INSERT INTO `characters`.`pet_spell_cooldown` SELECT * FROM `pet_spell_cooldown`; +INSERT INTO `characters`.`petition` SELECT * FROM `petition`; +INSERT INTO `characters`.`petition_sign` SELECT * FROM `petition_sign`; + +DROP TABLE `arena_team`; +DROP TABLE `arena_team_member`; +DROP TABLE `arena_team_stats`; +DROP TABLE `auctionhouse`; +DROP TABLE `bugreport`; +DROP TABLE `character`; +DROP TABLE `character_action`; +DROP TABLE `character_aura`; +DROP TABLE `character_gifts`; +DROP TABLE `character_homebind`; +DROP TABLE `character_instance`; +DROP TABLE `character_inventory`; +DROP TABLE `character_kill`; +DROP TABLE `character_pet`; +DROP TABLE `character_queststatus`; +DROP TABLE `character_queststatus_daily`; +DROP TABLE `character_reputation`; +DROP TABLE `character_social`; +DROP TABLE `character_spell`; +DROP TABLE `character_spell_cooldown`; +DROP TABLE `character_ticket`; +DROP TABLE `character_tutorial`; +DROP TABLE `corpse`; +DROP TABLE `group`; +DROP TABLE `group_member`; +DROP TABLE `guild`; +DROP TABLE `guild_member`; +DROP TABLE `guild_rank`; +DROP TABLE `instance`; +DROP TABLE `item_instance`; +DROP TABLE `item_text`; +DROP TABLE `mail`; +DROP TABLE `pet_aura`; +DROP TABLE `pet_spell`; +DROP TABLE `pet_spell_cooldown`; +DROP TABLE `petition`; +DROP TABLE `petition_sign`; \ No newline at end of file diff --git a/sql/updates/0.9/4667_characters_character.sql b/sql/updates/0.9/4667_characters_character.sql new file mode 100644 index 000000000..0b5470197 --- /dev/null +++ b/sql/updates/0.9/4667_characters_character.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character` + DROP COLUMN `pending_kills`; \ No newline at end of file diff --git a/sql/updates/0.9/4674_mangos_skill_discovery_template.sql b/sql/updates/0.9/4674_mangos_skill_discovery_template.sql new file mode 100644 index 000000000..7358a3a2d --- /dev/null +++ b/sql/updates/0.9/4674_mangos_skill_discovery_template.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `skill_discovery_template`; +CREATE TABLE `skill_discovery_template` ( + `spellId` int(11) unsigned NOT NULL default '0' COMMENT 'SpellId of the discoverable spell', + `reqSpell` int(11) unsigned NOT NULL default '0' COMMENT 'spell requirement', + `chance` float NOT NULL default '0' COMMENT 'chance to discover', + + PRIMARY KEY (`spellId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Discovery System'; \ No newline at end of file diff --git a/sql/updates/0.9/4679_mangos_spell_proc_event.sql b/sql/updates/0.9/4679_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d268b87e3 --- /dev/null +++ b/sql/updates/0.9/4679_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34774, 34586); +INSERT INTO `spell_proc_event` VALUES +(34586,0,0,0,0,0,524289,1.5), +(34774,0,0,0,0,0,524289,1.5); diff --git a/sql/updates/0.9/4687_mangos_loot_template.sql b/sql/updates/0.9/4687_mangos_loot_template.sql new file mode 100644 index 000000000..f2be66d26 --- /dev/null +++ b/sql/updates/0.9/4687_mangos_loot_template.sql @@ -0,0 +1,86 @@ +-- +-- Table changes for `creature_loot_template` +-- +ALTER TABLE `creature_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `creature_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `disenchant_loot_template` +-- +ALTER TABLE `disenchant_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `disenchant_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `fishing_loot_template` +-- +ALTER TABLE `fishing_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `fishing_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `gameobject_loot_template` +-- +ALTER TABLE `gameobject_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `gameobject_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `item_loot_template` +-- +ALTER TABLE `item_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `item_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `pickpocketing_loot_template` +-- +ALTER TABLE `pickpocketing_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `pickpocketing_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `skinning_loot_template` +-- +ALTER TABLE `skinning_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `skinning_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); + + +-- +-- Table changes for `prospecting_loot_template` +-- +ALTER TABLE `prospecting_loot_template` CHANGE COLUMN `quest_freeforall` `QuestFFAorLootCondition` TINYINT(3) NOT NULL DEFAULT 1, +ADD COLUMN `condition_value1` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `QuestFFAorLootCondition`, +ADD COLUMN `condition_value2` int(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `condition_value1`; + +ALTER TABLE `prospecting_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`, `condition_value1`); \ No newline at end of file diff --git a/sql/updates/0.9/4689_mangos_loot_template.sql b/sql/updates/0.9/4689_mangos_loot_template.sql new file mode 100644 index 000000000..1f17de638 --- /dev/null +++ b/sql/updates/0.9/4689_mangos_loot_template.sql @@ -0,0 +1,23 @@ +ALTER TABLE `creature_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `disenchant_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `fishing_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `gameobject_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `item_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `pickpocketing_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `skinning_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); + +ALTER TABLE `prospecting_loot_template` DROP PRIMARY KEY, +ADD PRIMARY KEY(`entry`, `item`); diff --git a/sql/updates/0.9/4695_mangos_loot_template.sql b/sql/updates/0.9/4695_mangos_loot_template.sql new file mode 100644 index 000000000..d395dd3f1 --- /dev/null +++ b/sql/updates/0.9/4695_mangos_loot_template.sql @@ -0,0 +1,39 @@ +ALTER TABLE `creature_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `creature_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `disenchant_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `disenchant_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `fishing_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `fishing_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `gameobject_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `gameobject_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `item_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `item_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `pickpocketing_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `pickpocketing_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `skinning_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `skinning_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; + +ALTER TABLE `prospecting_loot_template` + CHANGE `QuestFFAorLootCondition` `freeforall` tinyint(1) unsigned NOT NULL default 0 COMMENT '1 if everybody should get a copy'; +ALTER TABLE `prospecting_loot_template` + ADD COLUMN `lootcondition` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `freeforall`; diff --git a/sql/updates/0.9/4704_mangos_battlemaster_entry.sql b/sql/updates/0.9/4704_mangos_battlemaster_entry.sql new file mode 100644 index 000000000..950649437 --- /dev/null +++ b/sql/updates/0.9/4704_mangos_battlemaster_entry.sql @@ -0,0 +1,11 @@ +-- +-- Definition of table `battlemaster_entry` +-- + +DROP TABLE IF EXISTS `battlemaster_entry`; +CREATE TABLE `battlemaster_entry` ( + `entry` int(11) unsigned NOT NULL default '0' COMMENT 'Entry of a creature', + `bg_template` int(11) unsigned NOT NULL default '0' COMMENT 'Battleground template id', + + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/0.9/4714_mangos_spell_threat.sql b/sql/updates/0.9/4714_mangos_spell_threat.sql new file mode 100644 index 000000000..d56102628 --- /dev/null +++ b/sql/updates/0.9/4714_mangos_spell_threat.sql @@ -0,0 +1,45 @@ +/*Heroic Strike*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('29707', '196'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('30324', '220'); +/*Maul*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('26996', '176'); +/*Shield Slam*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('25258', '286'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('30356', '323'); +/*Revenge*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('25269', '400'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('30357', '483'); +/*Shield Bash*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('29704', '230'); +/*Sunder Armor*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('25225', '300'); +/*Cleave*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('20569', '100'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('25231', '130'); +/*Lacerate*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('33745', '285'); +/*Faerie Fire*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('26993', '127'); +/*Faerie Fire(feral)*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('16857', '108'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('17390', '108'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('17391', '108'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('17392', '108'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('27011', '127'); +/*Thunder Clap: multiplier = 1.75*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('6343', '17'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('8198', '40'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('8204', '64'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('8205', '96'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('11580', '143'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('11581', '180'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('25264', '215'); +/*Mangle (Bear): multiplier = 1.5*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('33878', '129'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('33986', '180'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('33987', '232'); +/*Holy Shield: multiplier = 0.35*/ +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('20925', '20'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('20927', '30'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('20928', '40'); +INSERT INTO `spell_threat` (`entry`, `Threat`) VALUES ('27179', '54'); diff --git a/sql/updates/0.9/4718_mangos_uptime.sql b/sql/updates/0.9/4718_mangos_uptime.sql new file mode 100644 index 000000000..9cc6bb1bd --- /dev/null +++ b/sql/updates/0.9/4718_mangos_uptime.sql @@ -0,0 +1 @@ +ALTER TABLE `uptime` ENGINE=MyISAM; diff --git a/sql/updates/0.9/4737_mangos_command.sql b/sql/updates/0.9/4737_mangos_command.sql new file mode 100644 index 000000000..204430ae4 --- /dev/null +++ b/sql/updates/0.9/4737_mangos_command.sql @@ -0,0 +1,15 @@ + + +DELETE FROM command WHERE name IN ('lookupitem','lookupitemset','lookupcreature','lookupobject','lookupquest','lookupskill','lookupspell','lookuptele'); + + +INSERT INTO `command` VALUES + ('lookup creature',3,'Syntax: .lookup creature $namepart\r\n\r\nLooks up a creature by $namepart, and returns all matches with their creature ID\'s.'), + ('lookup item',3,'Syntax: .lookup item $itemname\r\n\r\nLooks up an item by $itemname, and returns all matches with their Item ID\'s.'), + ('lookup itemset',3,'Syntax: .lookup itemset $itemname\r\n\r\nLooks up an item set by $itemname, and returns all matches with their Item set ID\'s.'), + ('lookup object',3,'Syntax: .lookup object $objname\r\n\r\nLooks up an gameobject by $objname, and returns all matches with their Gameobject ID\'s.'), + ('lookup quest',3,'Syntax: .lookup quest $namepart\r\n\r\nLooks up a quest by $namepart, and returns all matches with their quest ID\'s.'), + ('lookup skill',3,'Syntax: .lookup skill $$namepart\r\n\r\nLooks up a skill by $namepart, and returns all matches with their skill ID\'s.'), + ('lookup spell',3,'Syntax: .lookup spell $namepart\r\n\r\nLooks up a spell by $namepart, and returns all matches with their spell ID\'s.'), + ('lookup tele',1,'Syntax: .lookup tele $substring\r\n\r\nSearch and output all .tele command locations with provide $substring in name.'); + diff --git a/sql/updates/0.9/4764_characters_auctionhouse.sql b/sql/updates/0.9/4764_characters_auctionhouse.sql new file mode 100644 index 000000000..d481deb9a --- /dev/null +++ b/sql/updates/0.9/4764_characters_auctionhouse.sql @@ -0,0 +1,2 @@ +ALTER TABLE `auctionhouse` + ADD UNIQUE KEY `item_guid` (`itemguid`); diff --git a/sql/updates/0.9/4772_mangos_item_template.sql b/sql/updates/0.9/4772_mangos_item_template.sql new file mode 100644 index 000000000..73a81d12b --- /dev/null +++ b/sql/updates/0.9/4772_mangos_item_template.sql @@ -0,0 +1 @@ +UPDATE `item_template` SET `subclass` = '0' where `class` = '0'; \ No newline at end of file diff --git a/sql/updates/0.9/4781_mangos_gameobject_loot_template.sql b/sql/updates/0.9/4781_mangos_gameobject_loot_template.sql new file mode 100644 index 000000000..c7b39204a --- /dev/null +++ b/sql/updates/0.9/4781_mangos_gameobject_loot_template.sql @@ -0,0 +1,50 @@ +-- Addgo command change +DELETE FROM `command` WHERE `name`='addgo'; +INSERT INTO `command` (`name`,`security`,`help`) VALUES + ('addgo',2,'Syntax: .addgo #id \r\n\r\nAdd a game object from game object templates to the world at your current location using the #id.\r\nspawntimesecs sets the spawntime, it is optional.\r\n\r\nNote: this is a copy of .gameobject.'); + +-- Creation of first temp table +DROP TABLE IF EXISTS `goloot`; +CREATE TABLE `goloot` ( + `entry` int(11) unsigned NOT NULL default '0', + `loot` int(11) unsigned NOT NULL default '0', + `sound1` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`), + INDEX `idx_loot` (`loot`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Go Loot Errors'; + +-- Filling table +INSERT IGNORE INTO `goloot` (`entry`,`loot`,`sound1`) SELECT `entry`,`entry`,`sound1` FROM `gameobject_template` WHERE `type` IN (3,25); -- AND `sound1`!=0; +UPDATE `goloot` a,`gameobject` b SET a.`loot`=b.`loot` WHERE a.`entry`=b.`id` AND b.`loot`!=0; + +-- Second temp table +DROP TABLE IF EXISTS `goloot2`; +CREATE TABLE `goloot2` ( + `sound1` int(11) unsigned NOT NULL default '0', + `loot` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`sound1`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Temp Table'; + +-- Put data into +INSERT INTO `goloot2` (`sound1`,`loot`) SELECT DISTINCT `sound1`,MIN(`loot`) FROM `goloot` WHERE `loot`!=0 AND `sound1`!=0 AND `loot` IN (SELECT DISTINCT `entry` FROM `gameobject_loot_template`) GROUP BY `sound1`; + +-- Now update gameobject_loot_template with new ids +UPDATE IGNORE `gameobject_loot_template` a,`goloot2` b SET a.`entry`=b.`sound1`+1000000 WHERE a.`entry`=b.`loot`; + +-- Now remove remaining loots not binded (conflits in several update or just garbage) +DELETE FROM `gameobject_loot_template` WHERE `entry` NOT IN (SELECT DISTINCT `sound1`+1000000 FROM `goloot2` UNION SELECT DISTINCT `loot` FROM `goloot` WHERE `sound1`=0); +UPDATE `gameobject_loot_template` SET `entry`=`entry`-1000000 WHERE `entry`>1000000; + +-- Cleanup but let bad sound1 entries for later correction +DELETE FROM `goloot` WHERE `sound1`!=0; +DELETE FROM `goloot` WHERE `loot` NOT IN (SELECT DISTINCT `entry` FROM `gameobject_loot_template`); + +-- Inverse comments in following 3 lines to see generated errors on conversion for gameobjects type 3 with sound1=0 +-- DROP TABLE IF EXISTS `gameobject_loot_errors`; +-- RENAME TABLE `goloot` TO `gameobject_loot_errors`; +DROP TABLE IF EXISTS `goloot`; + +-- Remove second temp table +DROP TABLE IF EXISTS `goloot2`; +-- Remove now not usefull loot column +ALTER TABLE `gameobject` DROP COLUMN `loot`; diff --git a/sql/updates/0.9/4788_mangos_gameobject_template.sql b/sql/updates/0.9/4788_mangos_gameobject_template.sql new file mode 100644 index 000000000..851cfcf80 --- /dev/null +++ b/sql/updates/0.9/4788_mangos_gameobject_template.sql @@ -0,0 +1,25 @@ +ALTER TABLE `gameobject_template` + CHANGE COLUMN `sound0` `data0` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound1` `data1` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound2` `data2` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound3` `data3` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound4` `data4` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound5` `data5` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound6` `data6` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound7` `data7` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound8` `data8` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound9` `data9` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound10` `data10` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound11` `data11` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound12` `data12` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound13` `data13` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound14` `data14` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound15` `data15` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound16` `data16` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound17` `data17` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound18` `data18` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound19` `data19` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound20` `data20` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound21` `data21` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound22` `data22` int(11) unsigned NOT NULL default '0', + CHANGE COLUMN `sound23` `data23` int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/0.9/4793_mangos_spell_affect.sql b/sql/updates/0.9/4793_mangos_spell_affect.sql new file mode 100644 index 000000000..f59f91088 --- /dev/null +++ b/sql/updates/0.9/4793_mangos_spell_affect.sql @@ -0,0 +1,109 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (37441); +INSERT INTO `spell_affect` VALUES +(37441,0,0,0,0,0,0,0x0000000020000000,0), +(37441,1,0,0,0,0,0,0x0000000020000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (33421,33713,33714); +INSERT INTO `spell_affect` VALUES +(33421,0,0,0,0,0,0,0x0000000200000000,0), +(33713,0,0,0,0,0,0,0x0000000200000000,0), +(33714,0,0,0,0,0,0,0x0000000200000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11222,12839,12840,12841,12842); +INSERT INTO `spell_affect` VALUES +(11222,0,0,0,0,0,0,0x0000000020001800,0), +(12839,0,0,0,0,0,0,0x0000000020001800,0), +(12840,0,0,0,0,0,0,0x0000000020001800,0), +(12841,0,0,0,0,0,0,0x0000000020001800,0), +(12842,0,0,0,0,0,0,0x0000000020001800,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11242,12467,12469); +INSERT INTO `spell_affect` VALUES +(11242,0,0,0,0,0,0,0x0000000020001000,0), +(12467,0,0,0,0,0,0,0x0000000020001000,0), +(12469,0,0,0,0,0,0,0x0000000020001000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12042); +INSERT INTO `spell_affect` VALUES +(12042,0,0,0,0,0,0,0x0000000020E01AF7,0), +(12042,1,0,0,0,0,0,0x0000000020E01AF7,0), +(12042,2,0,0,0,0,0,0x0000000020E01AF7,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11083,12351); +INSERT INTO `spell_affect` VALUES +(11083,0,0,0,0,0,0,0x0000000000C20017,0), +(12351,0,0,0,0,0,0,0x0000000000C20017,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12536); +INSERT INTO `spell_affect` VALUES +(12536,0,0,0,0,0,0,0x0000000020C01AF7,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (28682); +INSERT INTO `spell_affect` VALUES +(28682,0,0,0,0,0,0,0x0000004008C20017,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (37439); +INSERT INTO `spell_affect` VALUES +(37439,0,0,0,0,0,0,0x0000002000000000,0), +(37439,1,0,0,0,0,0,0x0000004000000000,0), +(37439,2,0,0,0,0,0,0x0000008000000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (29438,29439,29440); +INSERT INTO `spell_affect` VALUES +(29438,0,0,0,0,0,0,0x0000000000D000D7,0), +(29439,0,0,0,0,0,0,0x0000000000D000D7,0), +(29440,0,0,0,0,0,0,0x0000000000D000D7,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (31685); +INSERT INTO `spell_affect` VALUES +(31685,0,0,0,0,0,0,0x0000000000000020,0), +(31685,1,0,0,0,0,0,0x0000000000000020,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11124,12378,12398,12399,12400); +INSERT INTO `spell_affect` VALUES +(11124,0,0,0,0,0,0,0x0000000008C20017,0), +(12378,0,0,0,0,0,0,0x0000000008C20017,0), +(12398,0,0,0,0,0,0,0x0000000008C20017,0), +(12399,0,0,0,0,0,0,0x0000000008C20017,0), +(12400,0,0,0,0,0,0,0x0000000008C20017,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11160,12518,12519); +INSERT INTO `spell_affect` VALUES +(11160,0,0,0,0,0,0,0x00000001020003E0,0), +(12518,0,0,0,0,0,0,0x00000001020003E0,0), +(12519,0,0,0,0,0,0,0x00000001020003E0,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (11207,12672,15047,15052,15053); +INSERT INTO `spell_affect` VALUES +(11207,0,0,0,0,0,0,0x00000000000002E0,0), +(12672,0,0,0,0,0,0,0x00000000000002E0,0), +(15047,0,0,0,0,0,0,0x00000000000002E0,0), +(15052,0,0,0,0,0,0,0x00000000000002E0,0), +(15053,0,0,0,0,0,0,0x00000000000002E0,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (24429); +INSERT INTO `spell_affect` VALUES +(24429,0,0,0,0,0,0,0x0000000000004000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (22008); +INSERT INTO `spell_affect` VALUES +(22008,0,0,0,0,0,0,0x0000000021400035,1); + +DELETE FROM `spell_affect` WHERE `entry` IN (11151,12952,12953,12954,12957); +INSERT INTO `spell_affect` VALUES +(11151,0,0,0,0,0,0,0x00000000000002E0,0), +(12952,0,0,0,0,0,0,0x00000000000002E0,0), +(12953,0,0,0,0,0,0,0x00000000000002E0,0), +(12954,0,0,0,0,0,0,0x00000000000002E0,0), +(12957,0,0,0,0,0,0,0x00000000000002E0,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (12043,29976); +INSERT INTO `spell_affect` VALUES +(12043,0,0,0,0,0,0,0x0000000021400035,0), +(29976,0,0,0,0,0,0,0x0000000021400035,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (35578,35581); +INSERT INTO `spell_affect` VALUES +(35578,0,0,0,0,0,0,0x0000000028C21AF7,0), +(35581,0,0,0,0,0,0,0x0000000028C21AF7,0); + diff --git a/sql/updates/0.9/4799_mangos_creature_addon.sql b/sql/updates/0.9/4799_mangos_creature_addon.sql new file mode 100644 index 000000000..7a5971b7f --- /dev/null +++ b/sql/updates/0.9/4799_mangos_creature_addon.sql @@ -0,0 +1,37 @@ +-- create fields +ALTER TABLE `creature_addon` + ADD COLUMN `auras` text DEFAULT NULL AFTER `emote`; +ALTER TABLE `creature_template_addon` + ADD COLUMN `auras` text DEFAULT NULL AFTER `emote`; + +-- move data +UPDATE `creature_template_addon` SET `auras`=CONCAT(`aura`," 0") WHERE `aura`!=0; + +-- create missing records +INSERT IGNORE INTO `creature_addon` (`guid`) SELECT `guid` FROM `creature` WHERE `auras` IS NOT NULL AND TRIM(`auras`)!=""; +-- move data +UPDATE `creature_addon`,`creature` SET `creature_addon`.`auras`=`creature`.`auras` WHERE `creature_addon`.`guid`=`creature`.`guid` AND `creature`.`auras` IS NOT NULL AND TRIM(`creature`.`auras`)!=""; + +-- prepare fields +UPDATE `creature_addon` SET `auras`="" WHERE `auras` IS NULL AND `aura`!=0; +UPDATE `creature_addon` SET `auras`=CONCAT(`auras`," ") WHERE `auras`!="" AND `aura`!=0; +-- move data +UPDATE `creature_addon` SET `auras`=CONCAT(`auras`,`aura`," 0") WHERE `aura`!=0; + +-- Cleanup +ALTER TABLE `creature_addon` + DROP COLUMN `aura`, + DROP COLUMN `auraflags`, + DROP COLUMN `auralevels`, + DROP COLUMN `auraapplications`, + DROP COLUMN `aurastate`; + +ALTER TABLE `creature_template_addon` + DROP COLUMN `aura`, + DROP COLUMN `auraflags`, + DROP COLUMN `auralevels`, + DROP COLUMN `auraapplications`, + DROP COLUMN `aurastate`; + +ALTER TABLE `creature` + DROP COLUMN `auras`; diff --git a/sql/updates/0.9/4815_mangos_quest_template.sql b/sql/updates/0.9/4815_mangos_quest_template.sql new file mode 100644 index 000000000..29d3a9704 --- /dev/null +++ b/sql/updates/0.9/4815_mangos_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` + CHANGE COLUMN `SpecialFlags` `QuestFlags` int(11) unsigned NOT NULL default '0'; +UPDATE `quest_template` SET `QuestFlags`=`QuestFlags`&4096; diff --git a/sql/updates/0.9/4829_mangos_command.sql b/sql/updates/0.9/4829_mangos_command.sql new file mode 100644 index 000000000..1a20bcd87 --- /dev/null +++ b/sql/updates/0.9/4829_mangos_command.sql @@ -0,0 +1,5 @@ +DELETE FROM command WHERE name IN ('gozonexy','lookup area'); + +INSERT INTO `command` VALUES +('gozonexy',1,'Syntax: .gozonexy #x #y [#zone]\r\n\r\nTeleport player to point with (#x,#y) client coordinates at ground(water) level in zone #zoneid or current zone if #zoneid not provided. You can look up zone using .lookup area $namepart'), +('lookup area',1,'Syntax: .lookup area $namepart\r\n\r\nLooks up an area by $namepart, and returns all matches with their area ID\'s.'); diff --git a/sql/updates/0.9/4842_mangos_quest_template.sql b/sql/updates/0.9/4842_mangos_quest_template.sql new file mode 100644 index 000000000..ce05a62c1 --- /dev/null +++ b/sql/updates/0.9/4842_mangos_quest_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE `quest_template` ADD COLUMN `SpecialFlags` tinyint(1) unsigned NOT NULL default '0' AFTER `QuestFlags`; +ALTER TABLE `quest_template` CHANGE COLUMN `QuestFlags` `QuestFlags` smallint(5) unsigned NOT NULL default '0'; +UPDATE `quest_template` SET `SpecialFlags`=1 WHERE `Repeatable`=1; +ALTER TABLE `quest_template` DROP COLUMN `Repeatable`; diff --git a/sql/updates/5651_characters_character_social.sql b/sql/updates/5651_characters_character_social.sql new file mode 100644 index 000000000..a3ba2c22f --- /dev/null +++ b/sql/updates/5651_characters_character_social.sql @@ -0,0 +1,5 @@ +alter table `character_social` +change `guid` `guid` int(11) unsigned NOT NULL DEFAULT '0' comment 'Character Global Unique Identifier' first, +change `friend` `friend` int(11) unsigned NOT NULL DEFAULT '0' comment 'Friend Global Unique Identifier' after `guid`, +change `flags` `flags` tinyint(1) unsigned NOT NULL DEFAULT '0' comment 'Friend flags' after `friend`, +change `name` `note` varchar(21) NOT NULL DEFAULT '' collate utf8_general_ci comment 'Friend Note' after `flags`; diff --git a/sql/updates/5651_characters_characters.sql b/sql/updates/5651_characters_characters.sql new file mode 100644 index 000000000..6d7222875 --- /dev/null +++ b/sql/updates/5651_characters_characters.sql @@ -0,0 +1,19 @@ +UPDATE characters +SET data = CONCAT( + SUBSTRING_INDEX(data,' ',225+1), + ' 1 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',315+1),' ',225-315), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',621+1),' ',315-621), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',822+1),' ',621-822), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1319+1),' ',822-1319), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1351+1),' ',1319-1351), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1447+1),' ',1351-1447), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(data,' ',-1449+1447+1) +) +WHERE SUBSTRING_INDEX(data,' ',1448)=data; diff --git a/sql/updates/5651_characters_guild_bank_tab.sql b/sql/updates/5651_characters_guild_bank_tab.sql new file mode 100644 index 000000000..d4db1dab7 --- /dev/null +++ b/sql/updates/5651_characters_guild_bank_tab.sql @@ -0,0 +1 @@ +alter table guild_bank_tab add column TabText varchar(100) NOT NULL default '' COLLATE utf8_general_ci after TabIcon; diff --git a/sql/updates/5651_mangos_creature_template.sql b/sql/updates/5651_mangos_creature_template.sql new file mode 100644 index 000000000..aa8b75603 --- /dev/null +++ b/sql/updates/5651_mangos_creature_template.sql @@ -0,0 +1,2 @@ +update creature_template set speed=1 where speed=0; +alter table `creature_template` change `speed` `speed` float DEFAULT '1' NULL; diff --git a/sql/updates/5655_mangos_spell_affect.sql b/sql/updates/5655_mangos_spell_affect.sql new file mode 100644 index 000000000..2f589a296 --- /dev/null +++ b/sql/updates/5655_mangos_spell_affect.sql @@ -0,0 +1,39 @@ +-- (46090) Brutal Idol of Steadfastness () +DELETE FROM `spell_affect` WHERE `entry` IN (46090); +INSERT INTO `spell_affect` VALUES (46090, 0, 0, 0x0000000000000002, 0); + +-- (46100) Brutal Idol of Tenacity () +DELETE FROM `spell_affect` WHERE `entry` IN (46100); +INSERT INTO `spell_affect` VALUES (46100, 0, 0, 0x0000001000000000, 0); + +-- (46088) Brutall Idol of Resolve () +DELETE FROM `spell_affect` WHERE `entry` IN (46088); +INSERT INTO `spell_affect` VALUES (46088, 0, 0, 0x0000044000000000, 0); + +-- (46091) Brutal Libram of Fortitude () +DELETE FROM `spell_affect` WHERE `entry` IN (46091); +INSERT INTO `spell_affect` VALUES (46091, 0, 0, 0x0000000000800000, 0); + +-- (46095) Brutal Libram of Vengeance () +DELETE FROM `spell_affect` WHERE `entry` IN (46095); +INSERT INTO `spell_affect` VALUES (46095, 0, 0, 0x0000004000000000, 0); + +-- (46851) Holy Shock Bonus () +DELETE FROM `spell_affect` WHERE `entry` IN (46851); +INSERT INTO `spell_affect` VALUES (46851, 0, 0, 0x0001000000000000, 0); + +-- (46096) Brutal Totem of Indomitability () +DELETE FROM `spell_affect` WHERE `entry` IN (46096); +INSERT INTO `spell_affect` VALUES (46096, 0, 0, 0x0000001000000000, 0); + +-- (46097) Brutal Totem of Survival () +DELETE FROM `spell_affect` WHERE `entry` IN (46097); +INSERT INTO `spell_affect` VALUES (46097, 0, 0, 0x0000000090100000, 0); + +-- By triggers +DELETE FROM `spell_affect` WHERE `entry` IN (31569); +DELETE FROM `spell_affect` WHERE `entry` IN (31570); +-- By dummy +DELETE FROM `spell_affect` WHERE `entry` IN (28830); +DELETE FROM `spell_affect` WHERE `entry` IN (33695); +DELETE FROM `spell_affect` WHERE `entry` IN (37182); \ No newline at end of file diff --git a/sql/updates/5655_mangos_spell_chain.sql b/sql/updates/5655_mangos_spell_chain.sql new file mode 100644 index 000000000..dfce10236 --- /dev/null +++ b/sql/updates/5655_mangos_spell_chain.sql @@ -0,0 +1 @@ +DELETE FROM `spell_chain` WHERE `spell_id` IN (6461,6463,19289,19291,19292,19293,25450); \ No newline at end of file diff --git a/sql/updates/5655_mangos_spell_proc_event.sql b/sql/updates/5655_mangos_spell_proc_event.sql new file mode 100644 index 000000000..daac6ec5f --- /dev/null +++ b/sql/updates/5655_mangos_spell_proc_event.sql @@ -0,0 +1 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (1328,2689,4387,4388,4389,4390,4494,4495,4496,5341,5342,5343,5344,5345,5346,5349,5350,5351,5352,5353,5354,5429,5430,5431,5432,5433,5513,5549,5550,5551,5552,5553,5554,5638,5639,5640,5641,5642,5643,5751,5752,5753,5754,5755,5756,5976,5977,5979,13483); \ No newline at end of file diff --git a/sql/updates/5659_mangos_loot_template.sql b/sql/updates/5659_mangos_loot_template.sql new file mode 100644 index 000000000..a52e182ea --- /dev/null +++ b/sql/updates/5659_mangos_loot_template.sql @@ -0,0 +1,23 @@ +ALTER TABLE `creature_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `disenchant_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `fishing_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `gameobject_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `item_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `pickpocketing_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `prospecting_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; + +ALTER TABLE `skinning_loot_template` + CHANGE `group` groupid tinyint unsigned NOT NULL default '0'; diff --git a/sql/updates/5660_mangos_spell_elixir.sql b/sql/updates/5660_mangos_spell_elixir.sql new file mode 100644 index 000000000..aaa433a64 --- /dev/null +++ b/sql/updates/5660_mangos_spell_elixir.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_elixir` WHERE `entry` IN (46837,46839); +INSERT INTO `spell_elixir` VALUES +(46837,0xB), +(46839,0xB); diff --git a/sql/updates/5664_mangos.sql b/sql/updates/5664_mangos.sql new file mode 100644 index 000000000..e340beab2 --- /dev/null +++ b/sql/updates/5664_mangos.sql @@ -0,0 +1,6 @@ +ALTER TABLE npc_vendor + ADD ExtendedCost mediumint(8) unsigned NOT NULL default '0'; +UPDATE npc_vendor,item_template SET npc_vendor.ExtendedCost = item_template.ExtendedCost WHERE npc_vendor.item = item_template.entry; +ALTER TABLE item_template + DROP ExtendedCost, + DROP CondExtendedCost; \ No newline at end of file diff --git a/sql/updates/5665_mangos_creature_template.sql b/sql/updates/5665_mangos_creature_template.sql new file mode 100644 index 000000000..4a6fe057d --- /dev/null +++ b/sql/updates/5665_mangos_creature_template.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `scale` ='1'; \ No newline at end of file diff --git a/sql/updates/5679_mangos_creature_template.sql b/sql/updates/5679_mangos_creature_template.sql new file mode 100644 index 000000000..7e2a3f341 --- /dev/null +++ b/sql/updates/5679_mangos_creature_template.sql @@ -0,0 +1,9 @@ +ALTER TABLE creature_template + CHANGE resistance1 resistance1 smallint(5) NOT NULL default '0', + CHANGE resistance2 resistance2 smallint(5) NOT NULL default '0', + CHANGE resistance3 resistance3 smallint(5) NOT NULL default '0', + CHANGE resistance4 resistance4 smallint(5) NOT NULL default '0', + CHANGE resistance5 resistance5 smallint(5) NOT NULL default '0', + CHANGE resistance6 resistance6 smallint(5) NOT NULL default '0'; + + diff --git a/sql/updates/5680_mangos_spell_proc_event.sql b/sql/updates/5680_mangos_spell_proc_event.sql new file mode 100644 index 000000000..33f9c7cbd --- /dev/null +++ b/sql/updates/5680_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM spell_proc_event WHERE entry IN (37306,37311,32767); +INSERT IGNORE INTO spell_proc_event VALUES +(37306,0,0,0,0,0x0000000000000000,0x00000001,0), +(37311,0,0,0,0,0x0000000000000000,0x00000001,0); diff --git a/sql/updates/5698_mangos_item_template.sql b/sql/updates/5698_mangos_item_template.sql new file mode 100644 index 000000000..41cbe8b67 --- /dev/null +++ b/sql/updates/5698_mangos_item_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE item_template + CHANGE COLUMN stackable stackable smallint(5) unsigned NOT NULL default '1'; diff --git a/sql/updates/5708_mangos_player_levelstats.sql b/sql/updates/5708_mangos_player_levelstats.sql new file mode 100644 index 000000000..a216ffca4 --- /dev/null +++ b/sql/updates/5708_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 23, `basemana` = 90 WHERE `class` = 9 AND `level`=1; +UPDATE `player_levelstats` SET `basehp` = 28, `basemana` = 98 WHERE `class` = 9 AND `level`=2; +UPDATE `player_levelstats` SET `basehp` = 43, `basemana` = 107 WHERE `class` = 9 AND `level`=3; +UPDATE `player_levelstats` SET `basehp` = 48, `basemana` = 102 WHERE `class` = 9 AND `level`=4; +UPDATE `player_levelstats` SET `basehp` = 63, `basemana` = 113 WHERE `class` = 9 AND `level`=5; +UPDATE `player_levelstats` SET `basehp` = 68, `basemana` = 126 WHERE `class` = 9 AND `level`=6; +UPDATE `player_levelstats` SET `basehp` = 83, `basemana` = 144 WHERE `class` = 9 AND `level`=7; +UPDATE `player_levelstats` SET `basehp` = 88, `basemana` = 162 WHERE `class` = 9 AND `level`=8; +UPDATE `player_levelstats` SET `basehp` = 93, `basemana` = 180 WHERE `class` = 9 AND `level`=9; +UPDATE `player_levelstats` SET `basehp` = 108, `basemana` = 198 WHERE `class` = 9 AND `level`=10; +UPDATE `player_levelstats` SET `basehp` = 123, `basemana` = 200 WHERE `class` = 9 AND `level`=11; +UPDATE `player_levelstats` SET `basehp` = 128, `basemana` = 218 WHERE `class` = 9 AND `level`=12; +UPDATE `player_levelstats` SET `basehp` = 143, `basemana` = 237 WHERE `class` = 9 AND `level`=13; +UPDATE `player_levelstats` SET `basehp` = 148, `basemana` = 257 WHERE `class` = 9 AND `level`=14; +UPDATE `player_levelstats` SET `basehp` = 153, `basemana` = 278 WHERE `class` = 9 AND `level`=15; +UPDATE `player_levelstats` SET `basehp` = 168, `basemana` = 300 WHERE `class` = 9 AND `level`=16; +UPDATE `player_levelstats` SET `basehp` = 173, `basemana` = 308 WHERE `class` = 9 AND `level`=17; +UPDATE `player_levelstats` SET `basehp` = 189, `basemana` = 332 WHERE `class` = 9 AND `level`=18; +UPDATE `player_levelstats` SET `basehp` = 196, `basemana` = 357 WHERE `class` = 9 AND `level`=19; +UPDATE `player_levelstats` SET `basehp` = 204, `basemana` = 383 WHERE `class` = 9 AND `level`=20; +UPDATE `player_levelstats` SET `basehp` = 223, `basemana` = 395 WHERE `class` = 9 AND `level`=21; +UPDATE `player_levelstats` SET `basehp` = 233, `basemana` = 423 WHERE `class` = 9 AND `level`=22; +UPDATE `player_levelstats` SET `basehp` = 244, `basemana` = 452 WHERE `class` = 9 AND `level`=23; +UPDATE `player_levelstats` SET `basehp` = 266, `basemana` = 467 WHERE `class` = 9 AND `level`=24; +UPDATE `player_levelstats` SET `basehp` = 279, `basemana` = 498 WHERE `class` = 9 AND `level`=25; +UPDATE `player_levelstats` SET `basehp` = 293, `basemana` = 530 WHERE `class` = 9 AND `level`=26; +UPDATE `player_levelstats` SET `basehp` = 318, `basemana` = 548 WHERE `class` = 9 AND `level`=27; +UPDATE `player_levelstats` SET `basehp` = 334, `basemana` = 582 WHERE `class` = 9 AND `level`=28; +UPDATE `player_levelstats` SET `basehp` = 351, `basemana` = 602 WHERE `class` = 9 AND `level`=29; +UPDATE `player_levelstats` SET `basehp` = 379, `basemana` = 638 WHERE `class` = 9 AND `level`=30; +UPDATE `player_levelstats` SET `basehp` = 398, `basemana` = 674 WHERE `class` = 9 AND `level`=31; +UPDATE `player_levelstats` SET `basehp` = 418, `basemana` = 695 WHERE `class` = 9 AND `level`=32; +UPDATE `player_levelstats` SET `basehp` = 439, `basemana` = 731 WHERE `class` = 9 AND `level`=33; +UPDATE `player_levelstats` SET `basehp` = 471, `basemana` = 752 WHERE `class` = 9 AND `level`=34; +UPDATE `player_levelstats` SET `basehp` = 494, `basemana` = 788 WHERE `class` = 9 AND `level`=35; +UPDATE `player_levelstats` SET `basehp` = 518, `basemana` = 809 WHERE `class` = 9 AND `level`=36; +UPDATE `player_levelstats` SET `basehp` = 543, `basemana` = 830 WHERE `class` = 9 AND `level`=37; +UPDATE `player_levelstats` SET `basehp` = 569, `basemana` = 866 WHERE `class` = 9 AND `level`=38; +UPDATE `player_levelstats` SET `basehp` = 606, `basemana` = 887 WHERE `class` = 9 AND `level`=39; +UPDATE `player_levelstats` SET `basehp` = 634, `basemana` = 923 WHERE `class` = 9 AND `level`=40; +UPDATE `player_levelstats` SET `basehp` = 663, `basemana` = 944 WHERE `class` = 9 AND `level`=41; +UPDATE `player_levelstats` SET `basehp` = 693, `basemana` = 965 WHERE `class` = 9 AND `level`=42; +UPDATE `player_levelstats` SET `basehp` = 724, `basemana` = 1001 WHERE `class` = 9 AND `level`=43; +UPDATE `player_levelstats` SET `basehp` = 756, `basemana` = 1022 WHERE `class` = 9 AND `level`=44; +UPDATE `player_levelstats` SET `basehp` = 799, `basemana` = 1043 WHERE `class` = 9 AND `level`=45; +UPDATE `player_levelstats` SET `basehp` = 832, `basemana` = 1064 WHERE `class` = 9 AND `level`=46; +UPDATE `player_levelstats` SET `basehp` = 868, `basemana` = 1100 WHERE `class` = 9 AND `level`=47; +UPDATE `player_levelstats` SET `basehp` = 904, `basemana` = 1121 WHERE `class` = 9 AND `level`=48; +UPDATE `player_levelstats` SET `basehp` = 941, `basemana` = 1142 WHERE `class` = 9 AND `level`=49; +UPDATE `player_levelstats` SET `basehp` = 979, `basemana` = 1163 WHERE `class` = 9 AND `level`=50; +UPDATE `player_levelstats` SET `basehp` = 1018, `basemana` = 1184 WHERE `class` = 9 AND `level`=51; +UPDATE `player_levelstats` SET `basehp` = 1058, `basemana` = 1205 WHERE `class` = 9 AND `level`=52; +UPDATE `player_levelstats` SET `basehp` = 1099, `basemana` = 1226 WHERE `class` = 9 AND `level`=53; +UPDATE `player_levelstats` SET `basehp` = 1141, `basemana` = 1247 WHERE `class` = 9 AND `level`=54; +UPDATE `player_levelstats` SET `basehp` = 1184, `basemana` = 1268 WHERE `class` = 9 AND `level`=55; +UPDATE `player_levelstats` SET `basehp` = 1228, `basemana` = 1289 WHERE `class` = 9 AND `level`=56; +UPDATE `player_levelstats` SET `basehp` = 1273, `basemana` = 1310 WHERE `class` = 9 AND `level`=57; +UPDATE `player_levelstats` SET `basehp` = 1319, `basemana` = 1331 WHERE `class` = 9 AND `level`=58; +UPDATE `player_levelstats` SET `basehp` = 1366, `basemana` = 1352 WHERE `class` = 9 AND `level`=59; +UPDATE `player_levelstats` SET `basehp` = 1414, `basemana` = 1373 WHERE `class` = 9 AND `level`=60; +UPDATE `player_levelstats` SET `basehp` = 1580, `basemana` = 1497 WHERE `class` = 9 AND `level`=61; +UPDATE `player_levelstats` SET `basehp` = 1755, `basemana` = 1621 WHERE `class` = 9 AND `level`=62; +UPDATE `player_levelstats` SET `basehp` = 1939, `basemana` = 1745 WHERE `class` = 9 AND `level`=63; +UPDATE `player_levelstats` SET `basehp` = 2133, `basemana` = 1870 WHERE `class` = 9 AND `level`=64; +UPDATE `player_levelstats` SET `basehp` = 2323, `basemana` = 1994 WHERE `class` = 9 AND `level`=65; +UPDATE `player_levelstats` SET `basehp` = 2535, `basemana` = 2118 WHERE `class` = 9 AND `level`=66; +UPDATE `player_levelstats` SET `basehp` = 2758, `basemana` = 2242 WHERE `class` = 9 AND `level`=67; +UPDATE `player_levelstats` SET `basehp` = 2991, `basemana` = 2366 WHERE `class` = 9 AND `level`=68; +UPDATE `player_levelstats` SET `basehp` = 3235, `basemana` = 2490 WHERE `class` = 9 AND `level`=69; +UPDATE `player_levelstats` SET `basehp` = 3490, `basemana` = 2615 WHERE `class` = 9 AND `level`=70; diff --git a/sql/updates/5711_characters_character_kill.sql b/sql/updates/5711_characters_character_kill.sql new file mode 100644 index 000000000..0935ac421 --- /dev/null +++ b/sql/updates/5711_characters_character_kill.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `character_kill`; \ No newline at end of file diff --git a/sql/updates/5711_mangos_command.sql b/sql/updates/5711_mangos_command.sql new file mode 100644 index 000000000..3310c22c3 --- /dev/null +++ b/sql/updates/5711_mangos_command.sql @@ -0,0 +1,5 @@ +DELETE FROM `command` WHERE `name` = "honor flushkills"; + +DELETE FROM `command` WHERE `name` = "honor"; +INSERT INTO `command` VALUES +("honor", 2, "Syntax: .honor $command [$value] Various honor related commands. Use .help honor $command to get help on specific parameter usage. Supported parameters include add, addkill, update"); \ No newline at end of file diff --git a/sql/updates/5714_mangos_command.sql b/sql/updates/5714_mangos_command.sql new file mode 100644 index 000000000..2c6aba79e --- /dev/null +++ b/sql/updates/5714_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE FROM `command` WHERE `name` = "nearobjects"; +INSERT INTO `command` VALUES +('nearobjects',3,'Syntax: .nearobjects [#distance]\r\n\r\nOutput gameobjects at distance #distance from player. Output gameobject guids and coordinates sorted by distance from character. If #distance not provided use 10 as default value.'); diff --git a/sql/updates/5714_mangos_mangos_string.sql b/sql/updates/5714_mangos_mangos_string.sql new file mode 100644 index 000000000..47ad4e3ac --- /dev/null +++ b/sql/updates/5714_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM mangos_string WHERE entry in (524,581); +INSERT INTO mangos_string VALUES +(524,'Selected object:\n|cffffffff|Hitemset:%d|h[%s]|h|r\nGUID: %u ID: %u\nX: %f Y: %f Z: %f MapId: %u\nOrientation: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(581,'Found near gameobjects (distance %f): %u ',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/5718_mangos_command.sql b/sql/updates/5718_mangos_command.sql new file mode 100644 index 000000000..b2c0ae16e --- /dev/null +++ b/sql/updates/5718_mangos_command.sql @@ -0,0 +1,8 @@ +DELETE FROM `command` WHERE `name` = 'modify rep'; +DELETE FROM `command` WHERE `name` = 'modify arena'; +DELETE FROM `command` WHERE `name` = 'lookup faction'; + +INSERT INTO `command` VALUES +('modify rep',2,'Syntax: .modify rep #repId (#repvalue | $rankname [#delta])\r\nSets the selected player\s reputation with faction #repId to #repvalue or to $reprank.\r\nIf the reputation rank name is provided, the resulting reputation will be the lowest reputation for that rank plus the delta amount, if specified.\r\nYou can use \'.pinfo rep\' to list all known reputation ids, or use \'.lookup faction $name\' to locate a specific faction id.'), +('modify arena',3,'Syntax: .modify arena #value\r\nSets the arena points to the #value (0-999999).'), +('lookup faction','3','Syntax: .lookup faction $name\r\nAttempts to find the ID of the faction with the provided $name.'); diff --git a/sql/updates/5718_mangos_creature_template.sql b/sql/updates/5718_mangos_creature_template.sql new file mode 100644 index 000000000..55eb1f400 --- /dev/null +++ b/sql/updates/5718_mangos_creature_template.sql @@ -0,0 +1 @@ +ALTER TABLE `creature_template` CHANGE COLUMN `scale` `scale` float NOT NULL default '1'; diff --git a/sql/updates/5718_mangos_mangos_string.sql b/sql/updates/5718_mangos_mangos_string.sql new file mode 100644 index 000000000..e371c3984 --- /dev/null +++ b/sql/updates/5718_mangos_mangos_string.sql @@ -0,0 +1,26 @@ +DELETE FROM `mangos_string` WHERE `entry` IN (305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327); + +INSERT INTO `mangos_string` VALUES +(305, 'Faction %s (%u) reputation of %s was set to %5d!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(306, 'The arena points of %s was set to %u!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(307, 'No faction found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(308, 'Faction %i unknown!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(309, 'Invalid parameter %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(310, 'delta must be between 0 and %d (inclusive)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(311, '%d - |cffffffff|Hfaction:%d|h[%s]|h|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(312, ' [visible]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(313, ' [at war]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(314, ' [own team]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(315, ' [unknown]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(316, ' [invisible]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(317, ' [inactive]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(318, 'Hated',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(319, 'Hostile',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(320, 'Unfriendly',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(321, 'Neutral',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(322, 'Friendly',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(323, 'Honored',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(324, 'Revered',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(325, 'Exalted',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(326, 'Faction %s (%u) can\'not have reputation.',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(327, ' [no reputation]',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/5720_mangos_command.sql b/sql/updates/5720_mangos_command.sql new file mode 100644 index 000000000..cbc153deb --- /dev/null +++ b/sql/updates/5720_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE FROM `command` WHERE `name` = 'addvendoritem'; +INSERT INTO `command` VALUES +('addvendoritem',2,'Syntax: .addvendoritem #itemId <#maxcount><#incrtime><#extendedcost>r\n\r\nAdd item #itemid to item list of selected vendor. Also optionally set max count item in vendor item list and time to item count restoring and items ExtendedCost.'); diff --git a/sql/updates/5720_mangos_mangos_string.sql b/sql/updates/5720_mangos_mangos_string.sql new file mode 100644 index 000000000..4092ffe4a --- /dev/null +++ b/sql/updates/5720_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry in (206); +INSERT INTO mangos_string VALUES +(206,'Item \'%i\' \'%s\' added to list with maxcount \'%i\' and incrtime \'%i\' and extendedcost \'%i\'',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/5721_mangos_spell_affect.sql b/sql/updates/5721_mangos_spell_affect.sql new file mode 100644 index 000000000..2fdd57d71 --- /dev/null +++ b/sql/updates/5721_mangos_spell_affect.sql @@ -0,0 +1,24 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (16188); +INSERT INTO `spell_affect` VALUES + (16188,0,0,0x00000000000009C3,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (43743); +INSERT INTO `spell_affect` VALUES + (43743,1,0,0x0000000000000400,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (13733,13865,13866); +INSERT INTO `spell_affect` VALUES + (13733,0,0,0x0000000000000004,0), + (13733,1,0,0x0000000400000000,0), + (13865,0,0,0x0000000000000004,0), + (13865,1,0,0x0000000400000000,0), + (13866,0,0,0x0000000000000004,0), + (13866,1,0,0x0000000400000000,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (46834); +INSERT INTO `spell_affect` VALUES + (46834,0,0,0x0000000000000040,0); + +DELETE FROM `spell_affect` WHERE `entry` IN (46833); +INSERT INTO `spell_affect` VALUES + (46833,0,0,0x0000000000000004,0); diff --git a/sql/updates/5733_mangos_creature.sql b/sql/updates/5733_mangos_creature.sql new file mode 100644 index 000000000..e9947232f --- /dev/null +++ b/sql/updates/5733_mangos_creature.sql @@ -0,0 +1,5 @@ +ALTER TABLE `creature` + DROP `spawn_position_x`, + DROP `spawn_position_y`, + DROP `spawn_position_z`, + DROP `spawn_orientation`; diff --git a/sql/updates/5739_mangos_creature.sql b/sql/updates/5739_mangos_creature.sql new file mode 100644 index 000000000..b48c80cc0 --- /dev/null +++ b/sql/updates/5739_mangos_creature.sql @@ -0,0 +1 @@ +ALTER TABLE `creature` ADD COLUMN `spawnMask` tinyint(3) unsigned NOT NULL default '1' AFTER `map`; \ No newline at end of file diff --git a/sql/updates/5739_mangos_gameobject.sql b/sql/updates/5739_mangos_gameobject.sql new file mode 100644 index 000000000..e566cbcd6 --- /dev/null +++ b/sql/updates/5739_mangos_gameobject.sql @@ -0,0 +1 @@ +ALTER TABLE `gameobject` ADD COLUMN `spawnMask` tinyint(3) unsigned NOT NULL default '1' AFTER `map`; \ No newline at end of file diff --git a/sql/updates/5746_mangos_quest_template.sql b/sql/updates/5746_mangos_quest_template.sql new file mode 100644 index 000000000..d62acfd9e --- /dev/null +++ b/sql/updates/5746_mangos_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE `quest_template` ADD COLUMN `CharTitleId` tinyint(3) unsigned NOT NULL default '0' AFTER `SpecialFlags`; +ALTER TABLE `quest_template` ADD COLUMN `RewSpellCast` mediumint(8) unsigned NOT NULL default '0' AFTER `RewSpell`; + diff --git a/sql/updates/5753_mangos_areatrigger_teleport.sql b/sql/updates/5753_mangos_areatrigger_teleport.sql new file mode 100644 index 000000000..035cd9cab --- /dev/null +++ b/sql/updates/5753_mangos_areatrigger_teleport.sql @@ -0,0 +1,6 @@ +ALTER TABLE `areatrigger_teleport` + ADD COLUMN `required_item2` mediumint(8) unsigned NOT NULL default '0' AFTER `required_item`, + ADD COLUMN `heroic_key` mediumint(8) unsigned NOT NULL default '0' AFTER `required_item2`, + ADD COLUMN `heroic_key2` mediumint(8) unsigned NOT NULL default '0' AFTER `heroic_key`, + ADD COLUMN `required_quest_done` int(11) unsigned NOT NULL default '0' AFTER `heroic_key2`, + ADD COLUMN `required_failed_text` text AFTER `required_quest_done`; \ No newline at end of file diff --git a/sql/updates/5758_mangos_creature_addon.sql b/sql/updates/5758_mangos_creature_addon.sql new file mode 100644 index 000000000..3e1537168 --- /dev/null +++ b/sql/updates/5758_mangos_creature_addon.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_addon` ADD `moveflags` int(10) unsigned NOT NULL default '0' AFTER `emote`; +ALTER TABLE `creature_template_addon` ADD `moveflags` int(10) unsigned NOT NULL default '0' AFTER `emote`; \ No newline at end of file diff --git a/sql/updates/5759_mangos_command.sql b/sql/updates/5759_mangos_command.sql new file mode 100644 index 000000000..14aa7c58c --- /dev/null +++ b/sql/updates/5759_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` IN ('gograveyard','drunk'); +INSERT INTO `command` VALUES +('drunk',1,'Syntax: .drunk #value\r\n Set drunk level to #value (0..100). Value 0 remove drunk state, 100 is max drunked state.'), +('gograveyard',2,'Syntax: .gograveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'); diff --git a/sql/updates/5764_characters_characters.sql b/sql/updates/5764_characters_characters.sql new file mode 100644 index 000000000..bc9ce1057 --- /dev/null +++ b/sql/updates/5764_characters_characters.sql @@ -0,0 +1,2 @@ +ALTER TABLE `characters` + DROP `pending_honor`; diff --git a/sql/updates/5764_mangos_command.sql b/sql/updates/5764_mangos_command.sql new file mode 100644 index 000000000..d20861790 --- /dev/null +++ b/sql/updates/5764_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` IN ('modify arena','modify honor'); +INSERT INTO `command` VALUES +('modify arena',3,'Syntax: .modify arena #value\r\nAdd $amount arena points to the selected player.'), +('modify honor',1,'Syntax: .modify honor $amount\r\n\r\nAdd $amount honor points to the selected player.'); diff --git a/sql/updates/5771_mangos_spell_learn_spell.sql b/sql/updates/5771_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..813c71f14 --- /dev/null +++ b/sql/updates/5771_mangos_spell_learn_spell.sql @@ -0,0 +1,9 @@ +ALTER TABLE spell_learn_spell + DROP IfNoSpell; + +DELETE FROM spell_learn_spell WHERE entry IN (34769,13819,5784); + +INSERT INTO spell_learn_spell (entry,spellID) VALUES + (34769,33388), + (13819,33388), + (5784,33388); diff --git a/sql/updates/5772_mangos_command.sql b/sql/updates/5772_mangos_command.sql new file mode 100644 index 000000000..4f80ded6b --- /dev/null +++ b/sql/updates/5772_mangos_command.sql @@ -0,0 +1,118 @@ +DELETE FROM `command` WHERE `name` = 'addgo'; +DELETE FROM `command` WHERE `name` = 'addquest'; +DELETE FROM `command` WHERE `name` = 'addspw'; +DELETE FROM `command` WHERE `name` = 'addtele'; +DELETE FROM `command` WHERE `name` = 'addvendoritem'; +DELETE FROM `command` WHERE `name` = 'addweapon'; +DELETE FROM `command` WHERE `name` = 'allowmove'; +DELETE FROM `command` WHERE `name` = 'anim'; +DELETE FROM `command` WHERE `name` = 'money'; +DELETE FROM `command` WHERE `name` = 'morph'; +DELETE FROM `command` WHERE `name` = 'movecreature'; +DELETE FROM `command` WHERE `name` = 'moveobject'; +DELETE FROM `command` WHERE `name` = 'name'; +DELETE FROM `command` WHERE `name` = 'nametele'; +DELETE FROM `command` WHERE `name` = 'nearobjects'; +DELETE FROM `command` WHERE `name` = 'npcflag'; +DELETE FROM `command` WHERE `name` = 'npcinfo'; +DELETE FROM `command` WHERE `name` = 'npcinfoset'; +DELETE FROM `command` WHERE `name` = 'npcwhisper'; +DELETE FROM `command` WHERE `name` = 'castback'; +DELETE FROM `command` WHERE `name` = 'casttarget'; +DELETE FROM `command` WHERE `name` = 'changelevel'; +DELETE FROM `command` WHERE `name` = 'delete'; +DELETE FROM `command` WHERE `name` = 'delobject'; +DELETE FROM `command` WHERE `name` = 'deltele'; +DELETE FROM `command` WHERE `name` = 'delvendoritem'; +DELETE FROM `command` WHERE `name` = 'drunk'; +DELETE FROM `command` WHERE `name` = 'factionid'; +DELETE FROM `command` WHERE `name` = 'getvalue'; +DELETE FROM `command` WHERE `name` = 'gocreature'; +DELETE FROM `command` WHERE `name` = 'gograveyard'; +DELETE FROM `command` WHERE `name` = 'gogrid'; +DELETE FROM `command` WHERE `name` = 'goobject'; +DELETE FROM `command` WHERE `name` = 'gotrigger'; +DELETE FROM `command` WHERE `name` = 'goxy'; +DELETE FROM `command` WHERE `name` = 'goxyz'; +DELETE FROM `command` WHERE `name` = 'gozonexy'; +DELETE FROM `command` WHERE `name` = 'grouptele'; +DELETE FROM `command` WHERE `name` = 'listcreature'; +DELETE FROM `command` WHERE `name` = 'listgm'; +DELETE FROM `command` WHERE `name` = 'listitem'; +DELETE FROM `command` WHERE `name` = 'listobject'; +DELETE FROM `command` WHERE `name` = 'playemote'; +DELETE FROM `command` WHERE `name` = 'playsound'; +DELETE FROM `command` WHERE `name` = 'removequest'; +DELETE FROM `command` WHERE `name` = 'resetall'; +DELETE FROM `command` WHERE `name` = 'setmodel'; +DELETE FROM `command` WHERE `name` = 'setmovetype'; +DELETE FROM `command` WHERE `name` = 'setvalue'; +DELETE FROM `command` WHERE `name` = 'spawndist'; +DELETE FROM `command` WHERE `name` = 'spawntime'; +DELETE FROM `command` WHERE `name` = 'speed'; +DELETE FROM `command` WHERE `name` = 'standstate'; +DELETE FROM `command` WHERE `name` = 'subname'; +DELETE FROM `command` WHERE `name` = 'targetobject'; +DELETE FROM `command` WHERE `name` = 'textemote'; +DELETE FROM `command` WHERE `name` = 'titles'; +DELETE FROM `command` WHERE `name` = 'turnobject'; +DELETE FROM `command` WHERE `name` = 'update'; +DELETE FROM `command` WHERE `name` = 'visible'; + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('cast back',3,'Syntax: .cast back #spellid\r\n Selected target will cast #spellid to your character.'), +('cast target',3,'Syntax: .cast target #spellid\r\n Selected target will cast #spellid to his victim.'), +('debug anim',2,'Syntax: .debug anim #emoteid\r\n\r\nPlay emote #emoteid for your character.'), +('debug getvalue',3,'Syntax: .debug getvalue #field #isInt\r\n\r\nGet the field #field of the selected creature. If no creature is selected, get the content of your field.\r\n\r\nUse a #isInt of value 1 if the expected field content is an integer.'), +('debug playsound',1,'Syntax: .debug playsound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...'), +('debug setvalue',3,'Syntax: .debug setvalue #field #value #isInt\r\n\r\nSet the field #field of the selected creature with value #value. If no creature is selected, set the content of your field.\r\n\r\nUse a #isInt of value 1 if #value is an integer.'), +('debug standstate',2,'Syntax: .debug standstate #emoteid\r\n\r\nChange the emote of your character while standing to #emoteid.'), +('debug update',3,'Syntax: .debug update #field #value\r\n\r\nUpdate the field #field of the selected character or creature with value #value.\r\n\r\nIf no #value is provided, display the content of field #field.'), +('gm list',0,'Syntax: .gm list\r\n\r\nDisplay a list of available Game Masters.'), +('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'), +('go creature',2,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'), +('go graveyard',2,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'), +('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'), +('go object',1,'Syntax: .go object #object_guid\r\nTeleport your character to gameobject with guid #object_guid'), +('go trigger',2,'Syntax: .go trigger #trigger_id\r\n\r\nTeleport your character to areatrigger with id #trigger_id. Character will be teleported to trigger target if selected areatrigger is telporting trigger.'), +('go xy',1,'Syntax: .go xy #x #y [#mapid]\r\n\r\nTeleport player to point with (#x,#y) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), +('go xyz',1,'Syntax: .go xyz #x #y #z [#mapid]\r\n\r\nTeleport player to point with (#x,#y,#z) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), +('go zonexy',1,'Syntax: .go zonexy #x #y [#zone]\r\n\r\nTeleport player to point with (#x,#y) client coordinates at ground(water) level in zone #zoneid or current zone if #zoneid not provided. You can look up zone using .lookup area $namepart'), +('gobject add',2,'Syntax: .gobject add #id \r\n\r\nAdd a game object from game object templates to the world at your current location using the #id.\r\nspawntimesecs sets the spawntime, it is optional.\r\n\r\nNote: this is a copy of .gameobject.'), +('gobject delete',2,'Syntax: .gobject delete #go_guid\r\nDelete gameobject with guid #go_guid.'), +('gobject move',2,'Syntax: .gobject move #goguid [#x #y #z]\r\n\r\nMove gameobject #goguid to character coordinates (or to (#x,#y,#z) coordinates if its provide).'), +('gobject near ',3,'Syntax: .gobject near [#distance]\r\n\r\nOutput gameobjects at distance #distance from player. Output gameobject guids and coordinates sorted by distance from character. If #distance not provided use 10 as default value.'), +('gobject turn',2,'Syntax: .gobject turn #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'), +('list creature',3,'Syntax: .list creature #creature_id [#max_count]\r\n\r\nOutput creatures with creature id #creature_id found in world. Output creature guids and coordinates sorted by distance from character. Will be output maximum #max_count creatures. If #max_count not provided use 10 as default value.'), +('list item',3,'Syntax: .list item #item_id [#max_count]\r\n\r\nOutput items with item id #item_id found in all character inventories, mails and auctions. Output item guids, item owner guid, owner account and owner name. Will be output maximum #max_count items. If #max_count not provided use 10 as default value.'), +('list object',3,'Syntax: .list object #gameobject_id [#max_count]\r\n\r\nOutput gameobjects with gameobject id #gameobject_id found in world. Output gameobject guids and coordinates sorted by distance from character. Will be output maximum #max_count gameobject. If #max_count not provided use 10 as default value.'), +('modify drunk',1,'Syntax: .modify drunk #value\r\n Set drunk level to #value (0..100). Value 0 remove drunk state, 100 is max drunked state.'), +('modify morph',2,'Syntax: .modify morph #displayid\r\n\r\nChange your current model id to #displayid.'), +('npc add',2,'Syntax: .npc add #creatureid\r\n\r\nSpawn a creature by the given template id of #creatureid.'), +('npc additem',2,'Syntax: .npc additem #itemId <#maxcount><#incrtime><#extendedcost>r\r\n\r\nAdd item #itemid to item list of selected vendor. Also optionally set max count item in vendor item list and time to item count restoring and items ExtendedCost.'), +('npc addweapon',3,'Not yet implemented.'), +('npc allowmove',3,'Syntax: .npc allowmove\r\n\r\nEnable or disable movement for the selected creature.'), +('npc changelevel',2,'Syntax: .npc changelevel #level\r\n\r\nChange the level of the selected creature to #level.\r\n\r\n#level may range from 1 to 63.'), +('npc delete',2,'Syntax: .npc delete\r\n\r\nDelete the selected creature from the world.'), +('npc delitem',2,'Syntax: .npc delitem #itemId\r\n\r\nRemove item #itemid from item list of selected vendor.'), +('npc factionid',2,'Syntax: .npc factionid #factionid\r\n\r\nSet the faction of the selected creature to #factionid.'), +('npc flag',2,'Syntax: .npc flag #npcflag\r\n\r\nSet the NPC flags of creature template of the selected creature and selected creature to #npcflag. NPC flags will applied to all creatures of selected creature template after server restart or grid unload/load.'), +('npc info',3,'Syntax: .npc info\r\n\r\nDisplay a list of details for the selected creature.\r\n\r\nThe list includes:\r\n- GUID, Faction, NPC flags, Entry ID, Model ID,\r\n- Level,\r\n- Health (current/maximum),\r\n\r\n- Field flags, dynamic flags, faction template, \r\n- Position information,\r\n- and the creature type, e.g. if the creature is a vendor.'), +('npc move',2,'Syntax: .npc move [#creature_guid]\r\n\r\nMove the targeted creature spawn point to your coordinates.'), +('npc name',2,'Syntax: .npc name $name\r\n\r\nChange the name of the selected creature or character to $name.\r\n\r\nCommand disabled.'), +('npc playemote',3,'Syntax: .npc playemote #emoteid\r\n\r\nMake the selected creature emote with an emote of id #emoteid.'), +('npc setmodel',2,'Syntax: .npc setmodel #displayid\r\n\r\nChange the model id of the selected creature to #displayid.'), +('npc setmovetype',2,'Syntax: .npc setmovetype [#creature_guid] stay/random/way [NODEL]\r\n\r\nSet for creature pointed by #creature_guid (or selected if #creature_guid not provided) movement type and move it to respawn position (if creature alive). Any existing waypoints for creature will be removed from the database if you do not use NODEL. If the creature is dead then movement type will applied at creature respawn.\r\nMake sure you use NODEL, if you want to keep the waypoints.'), +('npc spawndist',2,'Syntax: .npc spawndist #dist\r\n\r\nAdjust spawndistance of selected creature to dist.'), +('npc spawntime',2,'Syntax: .npc spawntime #time \r\n\r\nAdjust spawntime of selected creature to time.'), +('npc subname',2,'Syntax: .npc subname $Name\r\n\r\nChange the subname of the selected creature or player to $Name.\r\n\r\nCommand disabled.'), +('npc textemote',3,'Syntax: .npc textemote #emoteid\r\n\r\nMake the selected creature to do textemote with an emote of id #emoteid.'), +('npc whisper',1,'Syntax: .npc whisper #playerguid #text\r\nMake the selected npc whisper #text to #playerguid.'), +('quest add',3,'Syntax: .quest add #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'), +('quest remove',3,'Syntax: .quest remove #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'), +('reset all',3,'Syntax: .reset all spells\r\n\r\nSyntax: .reset all talents\r\n\r\nRequest reset spells or talents at next login each existed character.'), +('targetobject',2,'Syntax: .gobject target[#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'), +('tele add',3,'Syntax: .tele add $name\r\n\r\nAdd current your position to .tele command target locations list with name $name.'), +('tele del',3,'Syntax: .tele del $name\r\n\r\nRemove location with name $name for .tele command locations list.'), +('tele group',1,'Syntax: .tele group#location\r\n\r\nTeleport a selected player and his group members to a given location.'), +('tele name',1,'Syntax: .tele name #playername #location\r\n\r\nTeleport a player to a given location.'); \ No newline at end of file diff --git a/sql/updates/5773_mangos_spell_affect.sql b/sql/updates/5773_mangos_spell_affect.sql new file mode 100644 index 000000000..954202438 --- /dev/null +++ b/sql/updates/5773_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (20216); +INSERT INTO `spell_affect` VALUES + (20216,0,0,0x0001000000006000,0); diff --git a/sql/updates/5773_mangos_spell_learn_spell.sql b/sql/updates/5773_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..507b1da95 --- /dev/null +++ b/sql/updates/5773_mangos_spell_learn_spell.sql @@ -0,0 +1,6 @@ +DELETE FROM spell_learn_spell WHERE entry IN (23161,23214,34767); + +INSERT INTO spell_learn_spell (entry,spellID) VALUES +(23161,33391), +(23214,33391), +(34767,33391); \ No newline at end of file diff --git a/sql/updates/5774_mangos_command.sql b/sql/updates/5774_mangos_command.sql new file mode 100644 index 000000000..c9f09b5ef --- /dev/null +++ b/sql/updates/5774_mangos_command.sql @@ -0,0 +1,5 @@ +DELETE FROM `command` WHERE `name` = 'targetobject'; +DELETE FROM `command` WHERE `name` = 'gobject target'; + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('gobject target',2,'Syntax: .gobject target [#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'); diff --git a/sql/updates/5774_mangos_mangos_string.sql b/sql/updates/5774_mangos_mangos_string.sql new file mode 100644 index 000000000..e5573f04b --- /dev/null +++ b/sql/updates/5774_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM `mangos_string` WHERE `entry` IN (582); + +INSERT INTO `mangos_string` VALUES +(582, 'SpawnTime: Full:%s Remain:%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/5777_mangos_command.sql b/sql/updates/5777_mangos_command.sql new file mode 100644 index 000000000..15b817f54 --- /dev/null +++ b/sql/updates/5777_mangos_command.sql @@ -0,0 +1 @@ +DELETE FROM `command` WHERE `name` IN ('honor','modify'); diff --git a/sql/updates/5778_mangos_spell_affect.sql b/sql/updates/5778_mangos_spell_affect.sql new file mode 100644 index 000000000..a4919d46b --- /dev/null +++ b/sql/updates/5778_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +ALTER TABLE `spell_affect` + DROP `SpellFamily`, + DROP `Charges`; diff --git a/sql/updates/5779_mangos_quest_template.sql b/sql/updates/5779_mangos_quest_template.sql new file mode 100644 index 000000000..e3353d5ee --- /dev/null +++ b/sql/updates/5779_mangos_quest_template.sql @@ -0,0 +1,21 @@ +ALTER TABLE `quest_template` ADD COLUMN `ClassOrSkill` smallint(6) NOT NULL default '0' AFTER `ZoneOrSort`; + +UPDATE `quest_template` SET `ClassOrSkill`=182 WHERE `ZoneOrSort`=-24; +UPDATE `quest_template` SET `ClassOrSkill`=356 WHERE `ZoneOrSort`=-101; +UPDATE `quest_template` SET `ClassOrSkill`=164 WHERE `ZoneOrSort`=-121; +UPDATE `quest_template` SET `ClassOrSkill`=171 WHERE `ZoneOrSort`=-181; +UPDATE `quest_template` SET `ClassOrSkill`=165 WHERE `ZoneOrSort`=-182; +UPDATE `quest_template` SET `ClassOrSkill`=202 WHERE `ZoneOrSort`=-201; +UPDATE `quest_template` SET `ClassOrSkill`=197 WHERE `ZoneOrSort`=-264; +UPDATE `quest_template` SET `ClassOrSkill`=185 WHERE `ZoneOrSort`=-304; +UPDATE `quest_template` SET `ClassOrSkill`=129 WHERE `ZoneOrSort`=-324; + +UPDATE `quest_template` SET `ClassOrSkill`=-9 WHERE `ZoneOrSort`=-61; +UPDATE `quest_template` SET `ClassOrSkill`=-1 WHERE `ZoneOrSort`=-81; +UPDATE `quest_template` SET `ClassOrSkill`=-7 WHERE `ZoneOrSort`=-82; +UPDATE `quest_template` SET `ClassOrSkill`=-2 WHERE `ZoneOrSort`=-141; +UPDATE `quest_template` SET `ClassOrSkill`=-8 WHERE `ZoneOrSort`=-161; +UPDATE `quest_template` SET `ClassOrSkill`=-4 WHERE `ZoneOrSort`=-162; +UPDATE `quest_template` SET `ClassOrSkill`=-3 WHERE `ZoneOrSort`=-261; +UPDATE `quest_template` SET `ClassOrSkill`=-5 WHERE `ZoneOrSort`=-262; +UPDATE `quest_template` SET `ClassOrSkill`=-11 WHERE `ZoneOrSort`=-263; diff --git a/sql/updates/5784_mangos_player_levelstats.sql b/sql/updates/5784_mangos_player_levelstats.sql new file mode 100644 index 000000000..a107537d2 --- /dev/null +++ b/sql/updates/5784_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 32, `basemana` = 100 WHERE `class` = 8 AND `level`=1; +UPDATE `player_levelstats` SET `basehp` = 47, `basemana` = 110 WHERE `class` = 8 AND `level`=2; +UPDATE `player_levelstats` SET `basehp` = 52, `basemana` = 106 WHERE `class` = 8 AND `level`=3; +UPDATE `player_levelstats` SET `basehp` = 67, `basemana` = 118 WHERE `class` = 8 AND `level`=4; +UPDATE `player_levelstats` SET `basehp` = 82, `basemana` = 131 WHERE `class` = 8 AND `level`=5; +UPDATE `player_levelstats` SET `basehp` = 97, `basemana` = 130 WHERE `class` = 8 AND `level`=6; +UPDATE `player_levelstats` SET `basehp` = 102, `basemana` = 145 WHERE `class` = 8 AND `level`=7; +UPDATE `player_levelstats` SET `basehp` = 117, `basemana` = 146 WHERE `class` = 8 AND `level`=8; +UPDATE `player_levelstats` SET `basehp` = 132, `basemana` = 163 WHERE `class` = 8 AND `level`=9; +UPDATE `player_levelstats` SET `basehp` = 137, `basemana` = 196 WHERE `class` = 8 AND `level`=10; +UPDATE `player_levelstats` SET `basehp` = 152, `basemana` = 215 WHERE `class` = 8 AND `level`=11; +UPDATE `player_levelstats` SET `basehp` = 167, `basemana` = 220 WHERE `class` = 8 AND `level`=12; +UPDATE `player_levelstats` SET `basehp` = 172, `basemana` = 241 WHERE `class` = 8 AND `level`=13; +UPDATE `player_levelstats` SET `basehp` = 187, `basemana` = 263 WHERE `class` = 8 AND `level`=14; +UPDATE `player_levelstats` SET `basehp` = 202, `basemana` = 271 WHERE `class` = 8 AND `level`=15; +UPDATE `player_levelstats` SET `basehp` = 207, `basemana` = 295 WHERE `class` = 8 AND `level`=16; +UPDATE `player_levelstats` SET `basehp` = 222, `basemana` = 305 WHERE `class` = 8 AND `level`=17; +UPDATE `player_levelstats` SET `basehp` = 237, `basemana` = 331 WHERE `class` = 8 AND `level`=18; +UPDATE `player_levelstats` SET `basehp` = 242, `basemana` = 343 WHERE `class` = 8 AND `level`=19; +UPDATE `player_levelstats` SET `basehp` = 257, `basemana` = 371 WHERE `class` = 8 AND `level`=20; +UPDATE `player_levelstats` SET `basehp` = 272, `basemana` = 385 WHERE `class` = 8 AND `level`=21; +UPDATE `player_levelstats` SET `basehp` = 277, `basemana` = 415 WHERE `class` = 8 AND `level`=22; +UPDATE `player_levelstats` SET `basehp` = 292, `basemana` = 431 WHERE `class` = 8 AND `level`=23; +UPDATE `player_levelstats` SET `basehp` = 298, `basemana` = 463 WHERE `class` = 8 AND `level`=24; +UPDATE `player_levelstats` SET `basehp` = 315, `basemana` = 481 WHERE `class` = 8 AND `level`=25; +UPDATE `player_levelstats` SET `basehp` = 333, `basemana` = 515 WHERE `class` = 8 AND `level`=26; +UPDATE `player_levelstats` SET `basehp` = 342, `basemana` = 535 WHERE `class` = 8 AND `level`=27; +UPDATE `player_levelstats` SET `basehp` = 362, `basemana` = 556 WHERE `class` = 8 AND `level`=28; +UPDATE `player_levelstats` SET `basehp` = 373, `basemana` = 592 WHERE `class` = 8 AND `level`=29; +UPDATE `player_levelstats` SET `basehp` = 395, `basemana` = 613 WHERE `class` = 8 AND `level`=30; +UPDATE `player_levelstats` SET `basehp` = 418, `basemana` = 634 WHERE `class` = 8 AND `level`=31; +UPDATE `player_levelstats` SET `basehp` = 432, `basemana` = 670 WHERE `class` = 8 AND `level`=32; +UPDATE `player_levelstats` SET `basehp` = 457, `basemana` = 691 WHERE `class` = 8 AND `level`=33; +UPDATE `player_levelstats` SET `basehp` = 473, `basemana` = 712 WHERE `class` = 8 AND `level`=34; +UPDATE `player_levelstats` SET `basehp` = 500, `basemana` = 733 WHERE `class` = 8 AND `level`=35; +UPDATE `player_levelstats` SET `basehp` = 518, `basemana` = 754 WHERE `class` = 8 AND `level`=36; +UPDATE `player_levelstats` SET `basehp` = 547, `basemana` = 790 WHERE `class` = 8 AND `level`=37; +UPDATE `player_levelstats` SET `basehp` = 577, `basemana` = 811 WHERE `class` = 8 AND `level`=38; +UPDATE `player_levelstats` SET `basehp` = 598, `basemana` = 832 WHERE `class` = 8 AND `level`=39; +UPDATE `player_levelstats` SET `basehp` = 630, `basemana` = 853 WHERE `class` = 8 AND `level`=40; +UPDATE `player_levelstats` SET `basehp` = 653, `basemana` = 874 WHERE `class` = 8 AND `level`=41; +UPDATE `player_levelstats` SET `basehp` = 687, `basemana` = 895 WHERE `class` = 8 AND `level`=42; +UPDATE `player_levelstats` SET `basehp` = 712, `basemana` = 916 WHERE `class` = 8 AND `level`=43; +UPDATE `player_levelstats` SET `basehp` = 748, `basemana` = 937 WHERE `class` = 8 AND `level`=44; +UPDATE `player_levelstats` SET `basehp` = 775, `basemana` = 958 WHERE `class` = 8 AND `level`=45; +UPDATE `player_levelstats` SET `basehp` = 813, `basemana` = 979 WHERE `class` = 8 AND `level`=46; +UPDATE `player_levelstats` SET `basehp` = 842, `basemana` =1000 WHERE `class` = 8 AND `level`=47; +UPDATE `player_levelstats` SET `basehp` = 882, `basemana` =1021 WHERE `class` = 8 AND `level`=48; +UPDATE `player_levelstats` SET `basehp` = 913, `basemana` =1042 WHERE `class` = 8 AND `level`=49; +UPDATE `player_levelstats` SET `basehp` = 955, `basemana` =1048 WHERE `class` = 8 AND `level`=50; +UPDATE `player_levelstats` SET `basehp` = 988, `basemana` =1069 WHERE `class` = 8 AND `level`=51; +UPDATE `player_levelstats` SET `basehp` =1032, `basemana` =1090 WHERE `class` = 8 AND `level`=52; +UPDATE `player_levelstats` SET `basehp` =1067, `basemana` =1111 WHERE `class` = 8 AND `level`=53; +UPDATE `player_levelstats` SET `basehp` =1103, `basemana` =1117 WHERE `class` = 8 AND `level`=54; +UPDATE `player_levelstats` SET `basehp` =1150, `basemana` =1138 WHERE `class` = 8 AND `level`=55; +UPDATE `player_levelstats` SET `basehp` =1188, `basemana` =1159 WHERE `class` = 8 AND `level`=56; +UPDATE `player_levelstats` SET `basehp` =1237, `basemana` =1165 WHERE `class` = 8 AND `level`=57; +UPDATE `player_levelstats` SET `basehp` =1277, `basemana` =1186 WHERE `class` = 8 AND `level`=58; +UPDATE `player_levelstats` SET `basehp` =1328, `basemana` =1192 WHERE `class` = 8 AND `level`=59; +UPDATE `player_levelstats` SET `basehp` =1370, `basemana` =1213 WHERE `class` = 8 AND `level`=60; +UPDATE `player_levelstats` SET `basehp` =1526, `basemana` =1316 WHERE `class` = 8 AND `level`=61; +UPDATE `player_levelstats` SET `basehp` =1702, `basemana` =1419 WHERE `class` = 8 AND `level`=62; +UPDATE `player_levelstats` SET `basehp` =1875, `basemana` =1521 WHERE `class` = 8 AND `level`=63; +UPDATE `player_levelstats` SET `basehp` =2070, `basemana` =1624 WHERE `class` = 8 AND `level`=64; +UPDATE `player_levelstats` SET `basehp` =2261, `basemana` =1727 WHERE `class` = 8 AND `level`=65; +UPDATE `player_levelstats` SET `basehp` =2461, `basemana` =1830 WHERE `class` = 8 AND `level`=66; +UPDATE `player_levelstats` SET `basehp` =2686, `basemana` =1932 WHERE `class` = 8 AND `level`=67; +UPDATE `player_levelstats` SET `basehp` =2906, `basemana` =2035 WHERE `class` = 8 AND `level`=68; +UPDATE `player_levelstats` SET `basehp` =3136, `basemana` =2138 WHERE `class` = 8 AND `level`=69; +UPDATE `player_levelstats` SET `basehp` =3393, `basemana` =2241 WHERE `class` = 8 AND `level`=70; diff --git a/sql/updates/5787_mangos_player_levelstats.sql b/sql/updates/5787_mangos_player_levelstats.sql new file mode 100644 index 000000000..15935dd99 --- /dev/null +++ b/sql/updates/5787_mangos_player_levelstats.sql @@ -0,0 +1,70 @@ +UPDATE `player_levelstats` SET `basehp` = 25 WHERE `class` = 4 AND `level`=1; +UPDATE `player_levelstats` SET `basehp` = 32 WHERE `class` = 4 AND `level`=2; +UPDATE `player_levelstats` SET `basehp` = 49 WHERE `class` = 4 AND `level`=3; +UPDATE `player_levelstats` SET `basehp` = 56 WHERE `class` = 4 AND `level`=4; +UPDATE `player_levelstats` SET `basehp` = 63 WHERE `class` = 4 AND `level`=5; +UPDATE `player_levelstats` SET `basehp` = 70 WHERE `class` = 4 AND `level`=6; +UPDATE `player_levelstats` SET `basehp` = 87 WHERE `class` = 4 AND `level`=7; +UPDATE `player_levelstats` SET `basehp` = 94 WHERE `class` = 4 AND `level`=8; +UPDATE `player_levelstats` SET `basehp` = 101 WHERE `class` = 4 AND `level`=9; +UPDATE `player_levelstats` SET `basehp` = 118 WHERE `class` = 4 AND `level`=10; +UPDATE `player_levelstats` SET `basehp` = 125 WHERE `class` = 4 AND `level`=11; +UPDATE `player_levelstats` SET `basehp` = 142 WHERE `class` = 4 AND `level`=12; +UPDATE `player_levelstats` SET `basehp` = 149 WHERE `class` = 4 AND `level`=13; +UPDATE `player_levelstats` SET `basehp` = 156 WHERE `class` = 4 AND `level`=14; +UPDATE `player_levelstats` SET `basehp` = 173 WHERE `class` = 4 AND `level`=15; +UPDATE `player_levelstats` SET `basehp` = 181 WHERE `class` = 4 AND `level`=16; +UPDATE `player_levelstats` SET `basehp` = 190 WHERE `class` = 4 AND `level`=17; +UPDATE `player_levelstats` SET `basehp` = 200 WHERE `class` = 4 AND `level`=18; +UPDATE `player_levelstats` SET `basehp` = 221 WHERE `class` = 4 AND `level`=19; +UPDATE `player_levelstats` SET `basehp` = 233 WHERE `class` = 4 AND `level`=20; +UPDATE `player_levelstats` SET `basehp` = 246 WHERE `class` = 4 AND `level`=21; +UPDATE `player_levelstats` SET `basehp` = 260 WHERE `class` = 4 AND `level`=22; +UPDATE `player_levelstats` SET `basehp` = 275 WHERE `class` = 4 AND `level`=23; +UPDATE `player_levelstats` SET `basehp` = 301 WHERE `class` = 4 AND `level`=24; +UPDATE `player_levelstats` SET `basehp` = 318 WHERE `class` = 4 AND `level`=25; +UPDATE `player_levelstats` SET `basehp` = 336 WHERE `class` = 4 AND `level`=26; +UPDATE `player_levelstats` SET `basehp` = 355 WHERE `class` = 4 AND `level`=27; +UPDATE `player_levelstats` SET `basehp` = 375 WHERE `class` = 4 AND `level`=28; +UPDATE `player_levelstats` SET `basehp` = 396 WHERE `class` = 4 AND `level`=29; +UPDATE `player_levelstats` SET `basehp` = 428 WHERE `class` = 4 AND `level`=30; +UPDATE `player_levelstats` SET `basehp` = 451 WHERE `class` = 4 AND `level`=31; +UPDATE `player_levelstats` SET `basehp` = 475 WHERE `class` = 4 AND `level`=32; +UPDATE `player_levelstats` SET `basehp` = 500 WHERE `class` = 4 AND `level`=33; +UPDATE `player_levelstats` SET `basehp` = 526 WHERE `class` = 4 AND `level`=34; +UPDATE `player_levelstats` SET `basehp` = 553 WHERE `class` = 4 AND `level`=35; +UPDATE `player_levelstats` SET `basehp` = 581 WHERE `class` = 4 AND `level`=36; +UPDATE `player_levelstats` SET `basehp` = 610 WHERE `class` = 4 AND `level`=37; +UPDATE `player_levelstats` SET `basehp` = 640 WHERE `class` = 4 AND `level`=38; +UPDATE `player_levelstats` SET `basehp` = 671 WHERE `class` = 4 AND `level`=39; +UPDATE `player_levelstats` SET `basehp` = 703 WHERE `class` = 4 AND `level`=40; +UPDATE `player_levelstats` SET `basehp` = 736 WHERE `class` = 4 AND `level`=41; +UPDATE `player_levelstats` SET `basehp` = 770 WHERE `class` = 4 AND `level`=42; +UPDATE `player_levelstats` SET `basehp` = 805 WHERE `class` = 4 AND `level`=43; +UPDATE `player_levelstats` SET `basehp` = 841 WHERE `class` = 4 AND `level`=44; +UPDATE `player_levelstats` SET `basehp` = 878 WHERE `class` = 4 AND `level`=45; +UPDATE `player_levelstats` SET `basehp` = 916 WHERE `class` = 4 AND `level`=46; +UPDATE `player_levelstats` SET `basehp` = 955 WHERE `class` = 4 AND `level`=47; +UPDATE `player_levelstats` SET `basehp` = 995 WHERE `class` = 4 AND `level`=48; +UPDATE `player_levelstats` SET `basehp` =1026 WHERE `class` = 4 AND `level`=49; +UPDATE `player_levelstats` SET `basehp` =1068 WHERE `class` = 4 AND `level`=50; +UPDATE `player_levelstats` SET `basehp` =1111 WHERE `class` = 4 AND `level`=51; +UPDATE `player_levelstats` SET `basehp` =1155 WHERE `class` = 4 AND `level`=52; +UPDATE `player_levelstats` SET `basehp` =1200 WHERE `class` = 4 AND `level`=53; +UPDATE `player_levelstats` SET `basehp` =1246 WHERE `class` = 4 AND `level`=54; +UPDATE `player_levelstats` SET `basehp` =1283 WHERE `class` = 4 AND `level`=55; +UPDATE `player_levelstats` SET `basehp` =1331 WHERE `class` = 4 AND `level`=56; +UPDATE `player_levelstats` SET `basehp` =1380 WHERE `class` = 4 AND `level`=57; +UPDATE `player_levelstats` SET `basehp` =1430 WHERE `class` = 4 AND `level`=58; +UPDATE `player_levelstats` SET `basehp` =1471 WHERE `class` = 4 AND `level`=59; +UPDATE `player_levelstats` SET `basehp` =1523 WHERE `class` = 4 AND `level`=60; +UPDATE `player_levelstats` SET `basehp` =1702 WHERE `class` = 4 AND `level`=61; +UPDATE `player_levelstats` SET `basehp` =1879 WHERE `class` = 4 AND `level`=62; +UPDATE `player_levelstats` SET `basehp` =2077 WHERE `class` = 4 AND `level`=63; +UPDATE `player_levelstats` SET `basehp` =2285 WHERE `class` = 4 AND `level`=64; +UPDATE `player_levelstats` SET `basehp` =2489 WHERE `class` = 4 AND `level`=65; +UPDATE `player_levelstats` SET `basehp` =2717 WHERE `class` = 4 AND `level`=66; +UPDATE `player_levelstats` SET `basehp` =2941 WHERE `class` = 4 AND `level`=67; +UPDATE `player_levelstats` SET `basehp` =3190 WHERE `class` = 4 AND `level`=68; +UPDATE `player_levelstats` SET `basehp` =3450 WHERE `class` = 4 AND `level`=69; +UPDATE `player_levelstats` SET `basehp` =3704 WHERE `class` = 4 AND `level`=70; diff --git a/sql/updates/5790_mangos_player_classlevelstats.sql b/sql/updates/5790_mangos_player_classlevelstats.sql new file mode 100644 index 000000000..42714761d --- /dev/null +++ b/sql/updates/5790_mangos_player_classlevelstats.sql @@ -0,0 +1,640 @@ +DROP TABLE IF EXISTS `player_classlevelstats`; +CREATE TABLE `player_classlevelstats` ( + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `basehp` smallint(5) unsigned NOT NULL, + `basemana` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +INSERT INTO `player_classlevelstats` VALUES +(1,1,20,0), +(1,2,29,0), +(1,3,38,0), +(1,4,47,0), +(1,5,56,0), +(1,6,65,0), +(1,7,74,0), +(1,8,83,0), +(1,9,92,0), +(1,10,101,0), +(1,11,100,0), +(1,12,109,0), +(1,13,118,0), +(1,14,128,0), +(1,15,139,0), +(1,16,151,0), +(1,17,154,0), +(1,18,168,0), +(1,19,183,0), +(1,20,199,0), +(1,21,206,0), +(1,22,224,0), +(1,23,243,0), +(1,24,253,0), +(1,25,274,0), +(1,26,296,0), +(1,27,309,0), +(1,28,333,0), +(1,29,348,0), +(1,30,374,0), +(1,31,401,0), +(1,32,419,0), +(1,33,448,0), +(1,34,468,0), +(1,35,499,0), +(1,36,521,0), +(1,37,545,0), +(1,38,581,0), +(1,39,609,0), +(1,40,649,0), +(1,41,681,0), +(1,42,715,0), +(1,43,761,0), +(1,44,799,0), +(1,45,839,0), +(1,46,881,0), +(1,47,935,0), +(1,48,981,0), +(1,49,1029,0), +(1,50,1079,0), +(1,51,1131,0), +(1,52,1185,0), +(1,53,1241,0), +(1,54,1299,0), +(1,55,1359,0), +(1,56,1421,0), +(1,57,1485,0), +(1,58,1551,0), +(1,59,1619,0), +(1,60,1689,0), +(1,61,1902,0), +(1,62,2129,0), +(1,63,2357,0), +(1,64,2612,0), +(1,65,2883,0), +(1,66,3169,0), +(1,67,3455,0), +(1,68,3774,0), +(1,69,4109,0), +(1,70,4444,0), +(2,1,28,60), +(2,2,36,78), +(2,3,44,98), +(2,4,52,104), +(2,5,60,111), +(2,6,68,134), +(2,7,76,143), +(2,8,84,153), +(2,9,92,179), +(2,10,100,192), +(2,11,108,205), +(2,12,116,219), +(2,13,124,249), +(2,14,132,265), +(2,15,131,282), +(2,16,141,315), +(2,17,152,334), +(2,18,164,354), +(2,19,177,390), +(2,20,191,412), +(2,21,206,435), +(2,22,222,459), +(2,23,239,499), +(2,24,247,525), +(2,25,266,552), +(2,26,286,579), +(2,27,307,621), +(2,28,329,648), +(2,29,342,675), +(2,30,366,702), +(2,31,391,729), +(2,32,407,756), +(2,33,434,798), +(2,34,462,825), +(2,35,481,852), +(2,36,511,879), +(2,37,542,906), +(2,38,564,933), +(2,39,597,960), +(2,40,621,987), +(2,41,656,1014), +(2,42,682,1041), +(2,43,719,1068), +(2,44,747,1110), +(2,45,786,1137), +(2,46,816,1164), +(2,47,857,1176), +(2,48,889,1203), +(2,49,922,1230), +(2,50,966,1257), +(2,51,1001,1284), +(2,52,1037,1311), +(2,53,1084,1338), +(2,54,1122,1365), +(2,55,1161,1392), +(2,56,1201,1419), +(2,57,1252,1446), +(2,58,1294,1458), +(2,59,1337,1485), +(2,60,1381,1512), +(2,61,1540,1656), +(2,62,1708,1800), +(2,63,1884,1944), +(2,64,2068,2088), +(2,65,2262,2232), +(2,66,2466,2377), +(2,67,2679,2521), +(2,68,2901,2665), +(2,69,3134,2809), +(2,70,3377,2953), +(3,1,46,65), +(3,2,53,70), +(3,3,60,76), +(3,4,67,98), +(3,5,74,106), +(3,6,81,130), +(3,7,88,140), +(3,8,95,166), +(3,9,102,193), +(3,10,109,206), +(3,11,116,235), +(3,12,123,250), +(3,13,130,266), +(3,14,138,298), +(3,15,147,316), +(3,16,157,350), +(3,17,168,370), +(3,18,180,391), +(3,19,193,428), +(3,20,207,451), +(3,21,222,475), +(3,22,238,515), +(3,23,255,541), +(3,24,273,568), +(3,25,292,611), +(3,26,312,640), +(3,27,333,670), +(3,28,355,715), +(3,29,378,745), +(3,30,402,775), +(3,31,417,805), +(3,32,443,850), +(3,33,470,880), +(3,34,498,910), +(3,35,527,940), +(3,36,547,970), +(3,37,578,1015), +(3,38,610,1045), +(3,39,643,1075), +(3,40,667,1105), +(3,41,702,1135), +(3,42,738,1180), +(3,43,775,1210), +(3,44,803,1240), +(3,45,842,1270), +(3,46,872,1300), +(3,47,913,1330), +(3,48,955,1360), +(3,49,994,1390), +(3,50,1047,1420), +(3,51,1067,1450), +(3,52,1113,1480), +(3,53,1150,1510), +(3,54,1198,1540), +(3,55,1237,1570), +(3,56,1287,1600), +(3,57,1328,1630), +(3,58,1370,1660), +(3,59,1423,1690), +(3,60,1467,1720), +(3,61,1633,1886), +(3,62,1819,2053), +(3,63,2003,2219), +(3,64,2195,2385), +(3,65,2397,2552), +(3,66,2623,2718), +(3,67,2844,2884), +(3,68,3075,3050), +(3,69,3316,3217), +(3,70,3568,3383), +(4,1,25,0), +(4,2,32,0), +(4,3,49,0), +(4,4,56,0), +(4,5,63,0), +(4,6,70,0), +(4,7,87,0), +(4,8,94,0), +(4,9,101,0), +(4,10,118,0), +(4,11,125,0), +(4,12,142,0), +(4,13,149,0), +(4,14,156,0), +(4,15,173,0), +(4,16,181,0), +(4,17,190,0), +(4,18,200,0), +(4,19,221,0), +(4,20,233,0), +(4,21,246,0), +(4,22,260,0), +(4,23,275,0), +(4,24,301,0), +(4,25,318,0), +(4,26,336,0), +(4,27,355,0), +(4,28,375,0), +(4,29,396,0), +(4,30,428,0), +(4,31,451,0), +(4,32,475,0), +(4,33,500,0), +(4,34,526,0), +(4,35,553,0), +(4,36,581,0), +(4,37,610,0), +(4,38,640,0), +(4,39,671,0), +(4,40,703,0), +(4,41,736,0), +(4,42,770,0), +(4,43,805,0), +(4,44,841,0), +(4,45,878,0), +(4,46,916,0), +(4,47,955,0), +(4,48,995,0), +(4,49,1026,0), +(4,50,1068,0), +(4,51,1111,0), +(4,52,1155,0), +(4,53,1200,0), +(4,54,1246,0), +(4,55,1283,0), +(4,56,1331,0), +(4,57,1380,0), +(4,58,1430,0), +(4,59,1471,0), +(4,60,1523,0), +(4,61,1702,0), +(4,62,1879,0), +(4,63,2077,0), +(4,64,2285,0), +(4,65,2489,0), +(4,66,2717,0), +(4,67,2941,0), +(4,68,3190,0), +(4,69,3450,0), +(4,70,3704,0), +(5,1,52,73), +(5,2,57,76), +(5,3,72,95), +(5,4,77,114), +(5,5,92,133), +(5,6,97,152), +(5,7,112,171), +(5,8,117,190), +(5,9,132,209), +(5,10,137,212), +(5,11,142,215), +(5,12,157,234), +(5,13,172,254), +(5,14,177,260), +(5,15,192,282), +(5,16,197,305), +(5,17,212,329), +(5,18,227,339), +(5,19,232,365), +(5,20,247,377), +(5,21,252,405), +(5,22,268,434), +(5,23,275,449), +(5,24,293,480), +(5,25,302,497), +(5,26,322,530), +(5,27,343,549), +(5,28,355,584), +(5,29,378,605), +(5,30,392,627), +(5,31,417,665), +(5,32,433,689), +(5,33,460,728), +(5,34,478,752), +(5,35,507,776), +(5,36,527,800), +(5,37,548,839), +(5,38,580,863), +(5,39,603,887), +(5,40,637,911), +(5,41,662,950), +(5,42,698,974), +(5,43,725,998), +(5,44,763,1022), +(5,45,792,1046), +(5,46,822,1070), +(5,47,863,1094), +(5,48,895,1118), +(5,49,928,1142), +(5,50,972,1166), +(5,51,1007,1190), +(5,52,1053,1214), +(5,53,1090,1238), +(5,54,1128,1262), +(5,55,1177,1271), +(5,56,1217,1295), +(5,57,1258,1319), +(5,58,1300,1343), +(5,59,1353,1352), +(5,60,1397,1376), +(5,61,1557,1500), +(5,62,1738,1625), +(5,63,1916,1749), +(5,64,2101,1873), +(5,65,2295,1998), +(5,66,2495,2122), +(5,67,2719,2247), +(5,68,2936,2371), +(5,69,3160,2495), +(5,70,3391,2620), +(7,1,37,85), +(7,2,44,91), +(7,3,51,98), +(7,4,58,106), +(7,5,65,115), +(7,6,72,125), +(7,7,79,136), +(7,8,86,148), +(7,9,93,161), +(7,10,100,175), +(7,11,107,190), +(7,12,114,206), +(7,13,121,223), +(7,14,128,241), +(7,15,135,260), +(7,16,142,280), +(7,17,150,301), +(7,18,159,323), +(7,19,169,346), +(7,20,180,370), +(7,21,192,395), +(7,22,205,421), +(7,23,219,448), +(7,24,234,476), +(7,25,240,505), +(7,26,257,535), +(7,27,275,566), +(7,28,294,598), +(7,29,314,631), +(7,30,335,665), +(7,31,347,699), +(7,32,370,733), +(7,33,394,767), +(7,34,419,786), +(7,35,435,820), +(7,36,462,854), +(7,37,490,888), +(7,38,509,922), +(7,39,539,941), +(7,40,570,975), +(7,41,592,1009), +(7,42,625,1028), +(7,43,649,1062), +(7,44,684,1096), +(7,45,710,1115), +(7,46,747,1149), +(7,47,775,1183), +(7,48,814,1202), +(7,49,844,1236), +(7,50,885,1255), +(7,51,917,1289), +(7,52,960,1323), +(7,53,994,1342), +(7,54,1029,1376), +(7,55,1075,1395), +(7,56,1112,1414), +(7,57,1150,1448), +(7,58,1199,1467), +(7,59,1239,1501), +(7,60,1330,1520), +(7,61,1428,1664), +(7,62,1583,1808), +(7,63,1760,1951), +(7,64,1932,2095), +(7,65,2114,2239), +(7,66,2304,2383), +(7,67,2504,2527), +(7,68,2713,2670), +(7,69,2931,2814), +(7,70,3159,2958), +(8,1,32,100), +(8,2,47,110), +(8,3,52,106), +(8,4,67,118), +(8,5,82,131), +(8,6,97,130), +(8,7,102,145), +(8,8,117,146), +(8,9,132,163), +(8,10,137,196), +(8,11,152,215), +(8,12,167,220), +(8,13,172,241), +(8,14,187,263), +(8,15,202,271), +(8,16,207,295), +(8,17,222,305), +(8,18,237,331), +(8,19,242,343), +(8,20,257,371), +(8,21,272,385), +(8,22,277,415), +(8,23,292,431), +(8,24,298,463), +(8,25,315,481), +(8,26,333,515), +(8,27,342,535), +(8,28,362,556), +(8,29,373,592), +(8,30,395,613), +(8,31,418,634), +(8,32,432,670), +(8,33,457,691), +(8,34,473,712), +(8,35,500,733), +(8,36,518,754), +(8,37,547,790), +(8,38,577,811), +(8,39,598,832), +(8,40,630,853), +(8,41,653,874), +(8,42,687,895), +(8,43,712,916), +(8,44,748,937), +(8,45,775,958), +(8,46,813,979), +(8,47,842,1000), +(8,48,882,1021), +(8,49,913,1042), +(8,50,955,1048), +(8,51,988,1069), +(8,52,1032,1090), +(8,53,1067,1111), +(8,54,1103,1117), +(8,55,1150,1138), +(8,56,1188,1159), +(8,57,1237,1165), +(8,58,1277,1186), +(8,59,1328,1192), +(8,60,1370,1213), +(8,61,1526,1316), +(8,62,1702,1419), +(8,63,1875,1521), +(8,64,2070,1624), +(8,65,2261,1727), +(8,66,2461,1830), +(8,67,2686,1932), +(8,68,2906,2035), +(8,69,3136,2138), +(8,70,3393,2241), +(9,1,23,90), +(9,2,28,98), +(9,3,43,107), +(9,4,48,102), +(9,5,63,113), +(9,6,68,126), +(9,7,83,144), +(9,8,88,162), +(9,9,93,180), +(9,10,108,198), +(9,11,123,200), +(9,12,128,218), +(9,13,143,237), +(9,14,148,257), +(9,15,153,278), +(9,16,168,300), +(9,17,173,308), +(9,18,189,332), +(9,19,196,357), +(9,20,204,383), +(9,21,223,395), +(9,22,233,423), +(9,23,244,452), +(9,24,266,467), +(9,25,279,498), +(9,26,293,530), +(9,27,318,548), +(9,28,334,582), +(9,29,351,602), +(9,30,379,638), +(9,31,398,674), +(9,32,418,695), +(9,33,439,731), +(9,34,471,752), +(9,35,494,788), +(9,36,518,809), +(9,37,543,830), +(9,38,569,866), +(9,39,606,887), +(9,40,634,923), +(9,41,663,944), +(9,42,693,965), +(9,43,724,1001), +(9,44,756,1022), +(9,45,799,1043), +(9,46,832,1064), +(9,47,868,1100), +(9,48,904,1121), +(9,49,941,1142), +(9,50,979,1163), +(9,51,1018,1184), +(9,52,1058,1205), +(9,53,1099,1226), +(9,54,1141,1247), +(9,55,1184,1268), +(9,56,1228,1289), +(9,57,1273,1310), +(9,58,1319,1331), +(9,59,1366,1352), +(9,60,1414,1373), +(9,61,1580,1497), +(9,62,1755,1621), +(9,63,1939,1745), +(9,64,2133,1870), +(9,65,2323,1994), +(9,66,2535,2118), +(9,67,2758,2242), +(9,68,2991,2366), +(9,69,3235,2490), +(9,70,3490,2615), +(11,1,44,60), +(11,2,51,66), +(11,3,58,73), +(11,4,75,81), +(11,5,82,90), +(11,6,89,100), +(11,7,106,111), +(11,8,113,123), +(11,9,120,136), +(11,10,137,150), +(11,11,144,165), +(11,12,151,182), +(11,13,168,200), +(11,14,175,219), +(11,15,182,239), +(11,16,199,260), +(11,17,206,282), +(11,18,214,305), +(11,19,233,329), +(11,20,243,354), +(11,21,254,380), +(11,22,266,392), +(11,23,289,420), +(11,24,303,449), +(11,25,318,479), +(11,26,334,509), +(11,27,361,524), +(11,28,379,554), +(11,29,398,584), +(11,30,418,614), +(11,31,439,629), +(11,32,461,659), +(11,33,494,689), +(11,34,518,704), +(11,35,543,734), +(11,36,569,749), +(11,37,596,779), +(11,38,624,809), +(11,39,653,824), +(11,40,683,854), +(11,41,714,869), +(11,42,746,899), +(11,43,779,914), +(11,44,823,944), +(11,45,858,959), +(11,46,894,989), +(11,47,921,1004), +(11,48,959,1019), +(11,49,998,1049), +(11,50,1038,1064), +(11,51,1079,1079), +(11,52,1121,1109), +(11,53,1164,1124), +(11,54,1208,1139), +(11,55,1253,1154), +(11,56,1299,1169), +(11,57,1346,1199), +(11,58,1384,1214), +(11,59,1433,1229), +(11,60,1483,1244), +(11,61,1657,1357), +(11,62,1840,1469), +(11,63,2020,1582), +(11,64,2222,1694), +(11,65,2433,1807), +(11,66,2640,1919), +(11,67,2872,2032), +(11,68,3114,2145), +(11,69,3351,2257), +(11,70,3614,2370); diff --git a/sql/updates/5790_mangos_player_levelstats.sql b/sql/updates/5790_mangos_player_levelstats.sql new file mode 100644 index 000000000..fa6454892 --- /dev/null +++ b/sql/updates/5790_mangos_player_levelstats.sql @@ -0,0 +1,3 @@ +ALTER TABLE `player_levelstats` + DROP `basehp`, + DROP `basemana`; diff --git a/sql/updates/5799_mangos_spell_proc_event.sql b/sql/updates/5799_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d2047e242 --- /dev/null +++ b/sql/updates/5799_mangos_spell_proc_event.sql @@ -0,0 +1,6 @@ +DELETE FROM spell_proc_event WHERE entry IN (45481,45482,45483,45484); +INSERT INTO spell_proc_event VALUES +(45481,0,0,0,0,0x0000000000000000,0x08020000,0), +(45482,0,0,0,0,0x0000000000000000,0x00080001,0), +(45483,0,0,0,0,0x0000000000000000,0x00080001,0), +(45484,0,0,0,0,0x0000000000000000,0x08000000,0); diff --git a/sql/updates/5813_mangos_mangos_string.sql b/sql/updates/5813_mangos_mangos_string.sql new file mode 100644 index 000000000..3a1dc6008 --- /dev/null +++ b/sql/updates/5813_mangos_mangos_string.sql @@ -0,0 +1,27 @@ +INSERT INTO `mangos_string` VALUES ('614', 'The Alliance flag has been respawned!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('615', 'The Horde flag has been respawned!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('636', 'The battle begins in 1 minute.', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('637', 'The battle begins in 30 seconds.', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('638', 'The battle has begun!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('667', 'The Alliance has taken control of the Mage Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('668', 'The Horde has taken control of the Mage Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('669', 'The Alliance has taken control of the Draenei Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('670', 'The Horde has taken control of the Draenei Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('671', 'The Alliance has taken control of the Blood Elf Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('672', 'The Horde has taken control of the Blood Elf Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('673', 'The Alliance has taken control of the Fel Reaver Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('674', 'The Horde has taken control of the Fel Reaver Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('675', 'The Alliance has lost control of the Mage Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('676', 'The Horde has lost control of the Mage Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('677', 'The Alliance has lost control of the Draenei Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('678', 'The Horde has lost control of the Draenei Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('679', 'The Alliance has lost control of the Blood Elf Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('680', 'The Horde has lost control of the Blood Elf Tower!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('681', 'The Alliance has lost control of the Fel Reaver Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('682', 'The Horde has lost control of the Fel Reaver Ruins!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('683', '$N has taken the flag!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('684', 'The Alliance has captured the flag!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('685', 'The Horde has captured the flag!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('686', 'The Flag has been dropped!', null, null, null, null, null, null, null); +INSERT INTO `mangos_string` VALUES ('687', 'The flag has been reset', null, null, null, null, null, null, null); + diff --git a/sql/updates/5827_mangos_spell_affect.sql b/sql/updates/5827_mangos_spell_affect.sql new file mode 100644 index 000000000..2477ec1c9 --- /dev/null +++ b/sql/updates/5827_mangos_spell_affect.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (32043,35396,35397); +INSERT INTO `spell_affect` VALUES +(32043,1,0x000004000A000000), +(35396,1,0x000004000A000000), +(35397,1,0x000004000A000000); diff --git a/sql/updates/5827_mangos_spell_chain.sql b/sql/updates/5827_mangos_spell_chain.sql new file mode 100644 index 000000000..271d692c1 --- /dev/null +++ b/sql/updates/5827_mangos_spell_chain.sql @@ -0,0 +1,8 @@ +-- wrong entry +DELETE FROM `spell_chain` WHERE `spell_id` IN (5159); + + +DELETE FROM `spell_chain` WHERE `spell_id` IN (5195,5196); +INSERT INTO `spell_chain` (`spell_id`, `prev_spell`, `first_spell`, `rank`) VALUES +(5195,1062,339,3), +(5196,5195,339,4); diff --git a/sql/updates/5827_mangos_spell_learn_spell.sql b/sql/updates/5827_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..59cb8608a --- /dev/null +++ b/sql/updates/5827_mangos_spell_learn_spell.sql @@ -0,0 +1,5 @@ +DELETE FROM spell_learn_spell WHERE entry IN (33872,33873); + +INSERT INTO spell_learn_spell (entry,spellID) VALUES +(33872,47179), +(33873,47180); diff --git a/sql/updates/5827_mangos_spell_proc_event.sql b/sql/updates/5827_mangos_spell_proc_event.sql new file mode 100644 index 000000000..6f8701d15 --- /dev/null +++ b/sql/updates/5827_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` = '33522'; +INSERT INTO `spell_proc_event` VALUES +(33522,0,0,0,0,0x0000000000000000,0x00020000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` = '33648'; +INSERT INTO `spell_proc_event` VALUES +(33648,0,0,0,0,0x0000000000000000,0x00401000,0); diff --git a/sql/updates/5831_mangos_skill_fishing_base_level.sql b/sql/updates/5831_mangos_skill_fishing_base_level.sql new file mode 100644 index 000000000..156651204 --- /dev/null +++ b/sql/updates/5831_mangos_skill_fishing_base_level.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS `skill_fishing_base_level`; +CREATE TABLE `skill_fishing_base_level` ( + `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Area identifier', + `skill` smallint(6) NOT NULL default '0' COMMENT 'Base skill level requirement', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Fishing system'; diff --git a/sql/updates/5842_mangos_spell_affect.sql b/sql/updates/5842_mangos_spell_affect.sql new file mode 100644 index 000000000..d3e77cf12 --- /dev/null +++ b/sql/updates/5842_mangos_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_affect` WHERE `entry` = 19245; +INSERT INTO `spell_affect` VALUES +(19245,0,0x0000000000000018), +(19245,1,0x0000200000000004); diff --git a/sql/updates/5845_mangos_spell_proc_event.sql b/sql/updates/5845_mangos_spell_proc_event.sql new file mode 100644 index 000000000..72ba36c1a --- /dev/null +++ b/sql/updates/5845_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (20164,31895); +INSERT INTO `spell_proc_event` VALUES +(20164,0,0,0,0,0x0000000000000000,0x00000001,5), +(31895,0,0,0,0,0x0000000000000000,0x00000001,5); diff --git a/sql/updates/5847_mangos_command.sql b/sql/updates/5847_mangos_command.sql new file mode 100644 index 000000000..473385d98 --- /dev/null +++ b/sql/updates/5847_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'damage'; + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('damage',3,'Syntax: .damage $damage_amount [$school [$spellid]]\r\n\r\nApply $damage to target. If not $school and $spellid provided then this flat clean melee damage without any modifiers. If $school provided then damage modified by armor reduction (if school physical), and target absorbing modifiers and result applied as melee damage to target. If spell provided then damage modified and applied as spell damage. $spellid can be shift-link.'); diff --git a/sql/updates/5857_mangos_spell_proc_event.sql b/sql/updates/5857_mangos_spell_proc_event.sql new file mode 100644 index 000000000..b6af59868 --- /dev/null +++ b/sql/updates/5857_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (32748); +INSERT INTO `spell_proc_event` VALUES +(32748,0,0,0,8,0x0000000100000000,0x00008000,0); diff --git a/sql/updates/5861_mangos_command.sql b/sql/updates/5861_mangos_command.sql new file mode 100644 index 000000000..15bccbd70 --- /dev/null +++ b/sql/updates/5861_mangos_command.sql @@ -0,0 +1,10 @@ +DELETE FROM `command` WHERE `name` = 'wp import'; +DELETE FROM `command` WHERE `name` = 'wp export'; + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('wp import',3,'Syntax: .wp import $filename'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('wp export',3,'Syntax: .wp export [#creature_guid or Select a Creature] $filename'); + +UPDATE `command` SET `help` = 'Syntax: .wp modify [#creature_guid or Select a Creature]\r\nadd - Add a waypoint after the selected visual\r\nwaittime $time\r\nemote ID\r\nspell ID\r\ntext1| text2| text3| text4| text5 \r\nmodel1 ID\r\nmodel2 ID\r\nmove(moves wp to player pos)\r\ndel (deletes the wp)\r\n\r\nOnly one parameter per time!' WHERE `name` = 'wp modify'; \ No newline at end of file diff --git a/sql/updates/5865_mangos_command.sql b/sql/updates/5865_mangos_command.sql new file mode 100644 index 000000000..d9004433a --- /dev/null +++ b/sql/updates/5865_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` = 'cast self'; + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('cast self',3,'Syntax: .cast self #spellid\r\nCast #spellid by target at target itself.'); diff --git a/sql/updates/5867_mangos_spell_affect.sql b/sql/updates/5867_mangos_spell_affect.sql new file mode 100644 index 000000000..f801715d9 --- /dev/null +++ b/sql/updates/5867_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (12472); +INSERT INTO `spell_affect` VALUES + (12472, 1, 0x00000000E44008A5); diff --git a/sql/updates/5875_mangos_quest_template.sql b/sql/updates/5875_mangos_quest_template.sql new file mode 100644 index 000000000..c10964130 --- /dev/null +++ b/sql/updates/5875_mangos_quest_template.sql @@ -0,0 +1 @@ +ALTER TABLE `quest_template` CHANGE `ClassOrSkill` `SkillOrClass` smallint(6) NOT NULL default '0'; diff --git a/sql/updates/5880_mangos_mangos_string.sql b/sql/updates/5880_mangos_mangos_string.sql new file mode 100644 index 000000000..74d5d92ac --- /dev/null +++ b/sql/updates/5880_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry in (297); +INSERT INTO `mangos_string` VALUES +(297,'Spawn distance changed to: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/5882_mangos_spell_affect.sql b/sql/updates/5882_mangos_spell_affect.sql new file mode 100644 index 000000000..b5453e4b6 --- /dev/null +++ b/sql/updates/5882_mangos_spell_affect.sql @@ -0,0 +1,29 @@ +-- (17954) Emberstorm (Rank 1) +DELETE FROM `spell_affect` WHERE `entry` IN (17954); +INSERT INTO `spell_affect` VALUES (17954, 0, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17954, 1, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17954, 2, 0x0000004000000000); + +-- (17955) Emberstorm (Rank 2) +DELETE FROM `spell_affect` WHERE `entry` IN (17955); +INSERT INTO `spell_affect` VALUES (17955, 0, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17955, 1, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17955, 2, 0x0000004000000000); + +-- (17956) Emberstorm (Rank 3) +DELETE FROM `spell_affect` WHERE `entry` IN (17956); +INSERT INTO `spell_affect` VALUES (17956, 0, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17956, 1, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17956, 2, 0x0000004000000000); + +-- (17957) Emberstorm (Rank 4) +DELETE FROM `spell_affect` WHERE `entry` IN (17957); +INSERT INTO `spell_affect` VALUES (17957, 0, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17957, 1, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17957, 2, 0x0000004000000000); + +-- (17958) Emberstorm (Rank 5) +DELETE FROM `spell_affect` WHERE `entry` IN (17958); +INSERT INTO `spell_affect` VALUES (17958, 0, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17958, 1, 0x000000C000001364); +INSERT INTO `spell_affect` VALUES (17958, 2, 0x0000004000000000); diff --git a/sql/updates/5890_mangos_quest_template.sql b/sql/updates/5890_mangos_quest_template.sql new file mode 100644 index 000000000..1cd696488 --- /dev/null +++ b/sql/updates/5890_mangos_quest_template.sql @@ -0,0 +1 @@ +UPDATE `quest_template` SET `SkillOrClass`=0 WHERE `ZoneOrSort` IN (-61,-81,-82,-141,-161,-162,-261,-262,-263); diff --git a/sql/updates/5896_mangos_spell_proc_event.sql b/sql/updates/5896_mangos_spell_proc_event.sql new file mode 100644 index 000000000..641ea3470 --- /dev/null +++ b/sql/updates/5896_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM spell_proc_event WHERE entry IN (45054,45354); +INSERT INTO spell_proc_event VALUES +(45054,0,0,0,0,0x0000000000000000,0x00020000,0), +(45354,0,0,0,0,0x0000000000000000,0x00000001,0); diff --git a/sql/updates/5923_mangos_spell_affect.sql b/sql/updates/5923_mangos_spell_affect.sql new file mode 100644 index 000000000..836e1bad7 --- /dev/null +++ b/sql/updates/5923_mangos_spell_affect.sql @@ -0,0 +1 @@ +DELETE FROM `spell_affect` WHERE `entry` IN (41660); diff --git a/sql/updates/5940_mangos_spell_affect.sql b/sql/updates/5940_mangos_spell_affect.sql new file mode 100644 index 000000000..51f5c029a --- /dev/null +++ b/sql/updates/5940_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +-- (14177) Cold Blood () +DELETE FROM `spell_affect` WHERE `entry` IN (14177); +INSERT INTO `spell_affect` VALUES (14177, 0, 0x0000000C6012031E); \ No newline at end of file diff --git a/sql/updates/5946_mangos_spell_affect.sql b/sql/updates/5946_mangos_spell_affect.sql new file mode 100644 index 000000000..2f4fc5b7a --- /dev/null +++ b/sql/updates/5946_mangos_spell_affect.sql @@ -0,0 +1,19 @@ +-- (20216) Divine Favor () +DELETE FROM `spell_affect` WHERE `entry` IN (20216); +INSERT INTO `spell_affect` VALUES (20216, 0, 0x00010000C0200000); + +-- (37879) Blessing of Lower City () +DELETE FROM `spell_affect` WHERE `entry` IN (37879); +INSERT INTO `spell_affect` VALUES (37879, 0, 0x00000000C0000000); + +-- (20237) Healing Light (Rank 1) +DELETE FROM `spell_affect` WHERE `entry` IN (20237); +INSERT INTO `spell_affect` VALUES (20237, 0, 0x00000000C0000000); + +-- (20238) Healing Light (Rank 2) +DELETE FROM `spell_affect` WHERE `entry` IN (20238); +INSERT INTO `spell_affect` VALUES (20238, 0, 0x00000000C0000000); + +-- (20239) Healing Light (Rank 3) +DELETE FROM `spell_affect` WHERE `entry` IN (20239); +INSERT INTO `spell_affect` VALUES (20239, 0, 0x00000000C0000000); diff --git a/sql/updates/5955_characters_guild_eventlog.sql b/sql/updates/5955_characters_guild_eventlog.sql new file mode 100644 index 000000000..ea7a9892a --- /dev/null +++ b/sql/updates/5955_characters_guild_eventlog.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS `guild_eventlog`; +CREATE TABLE `guild_eventlog` ( + `guildid` int(11) NOT NULL COMMENT 'Guild Identificator', + `LogGuid` int(11) NOT NULL COMMENT 'Log entry identificator', + `EventType` tinyint(1) NOT NULL COMMENT 'Event type', + `PlayerGuid1` int(11) NOT NULL COMMENT 'Player 1', + `PlayerGuid2` int(11) NOT NULL COMMENT 'Player 2', + `NewRank` tinyint(2) NOT NULL COMMENT 'New rank(in case promotion/demotion)', + `TimeStamp` bigint(20) NOT NULL COMMENT 'Event UNIX time' +) ENGINE = InnoDB DEFAULT CHARSET = latin1 COMMENT 'Guild Eventlog'; diff --git a/sql/updates/5965_mangos_mangos_string.sql b/sql/updates/5965_mangos_mangos_string.sql new file mode 100644 index 000000000..f162006eb --- /dev/null +++ b/sql/updates/5965_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM mangos_string WHERE entry in (468,470); +INSERT INTO `mangos_string` VALUES +(468,'id: %d eff: %d type: %d duration: %d maxduration: %d name: %s%s%s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(470,'id: %d eff: %d name: %s%s%s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/5973_mangos_spell_proc_event.sql b/sql/updates/5973_mangos_spell_proc_event.sql new file mode 100644 index 000000000..5dc5601fc --- /dev/null +++ b/sql/updates/5973_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (44835); +INSERT INTO `spell_proc_event` VALUES +(44835,0,0,0,7,0x0000008000000000,0x00008000,0); + diff --git a/sql/updates/5977_characters_pet.sql b/sql/updates/5977_characters_pet.sql new file mode 100644 index 000000000..f4454ca85 --- /dev/null +++ b/sql/updates/5977_characters_pet.sql @@ -0,0 +1,3 @@ +DELETE FROM pet_aura WHERE guid NOT IN (SELECT id FROM character_pet); +DELETE FROM pet_spell WHERE guid NOT IN (SELECT id FROM character_pet); +DELETE FROM pet_spell_cooldown WHERE guid NOT IN (SELECT id FROM character_pet); diff --git a/sql/updates/5982_mangos.sql b/sql/updates/5982_mangos.sql new file mode 100644 index 000000000..220451655 --- /dev/null +++ b/sql/updates/5982_mangos.sql @@ -0,0 +1,2 @@ +DROP TABLE playercreateinfo_skill; +DROP TABLE spell_learn_skill; \ No newline at end of file diff --git a/sql/updates/5986_mangos_spell_proc_event.sql b/sql/updates/5986_mangos_spell_proc_event.sql new file mode 100644 index 000000000..b544a1e1b --- /dev/null +++ b/sql/updates/5986_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (46832); +INSERT INTO `spell_proc_event` VALUES +(46832,0,0,0,7,0x0000000000000001,0x00004000,0); diff --git a/sql/updates/5999_mangos_spell_proc_event.sql b/sql/updates/5999_mangos_spell_proc_event.sql new file mode 100644 index 000000000..704af8c50 --- /dev/null +++ b/sql/updates/5999_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (37528); +INSERT INTO `spell_proc_event` VALUES +(37528,0,0,0,4,0x0000000000000004,0x00000001,0); diff --git a/sql/updates/6016_mangos_spell_proc_event.sql b/sql/updates/6016_mangos_spell_proc_event.sql new file mode 100644 index 000000000..5099da8ed --- /dev/null +++ b/sql/updates/6016_mangos_spell_proc_event.sql @@ -0,0 +1,12 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (37173); +INSERT INTO `spell_proc_event` VALUES +(37173,0,0,0,8,0x000001062cbc0598,0x000a0001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (30881,30883,30884,30885,30886); +INSERT INTO `spell_proc_event` VALUES +(30881,0,0,0,0,0x0000000000000000,0x00008000,0), +(30883,0,0,0,0,0x0000000000000000,0x00008000,0), +(30884,0,0,0,0,0x0000000000000000,0x00008000,0), +(30885,0,0,0,0,0x0000000000000000,0x00008000,0), +(30886,0,0,0,0,0x0000000000000000,0x00008000,0); + diff --git a/sql/updates/6017_mangos_spell_proc_event.sql b/sql/updates/6017_mangos_spell_proc_event.sql new file mode 100644 index 000000000..a9c55a14b --- /dev/null +++ b/sql/updates/6017_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (37170); +INSERT INTO `spell_proc_event` VALUES +(37170,0,0,0,0,0x0000000000000000,0x00000001,1); diff --git a/sql/updates/6022_mangos_spell_proc_event.sql b/sql/updates/6022_mangos_spell_proc_event.sql new file mode 100644 index 000000000..2525a13c9 --- /dev/null +++ b/sql/updates/6022_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (12322,12999,13000,13001,13002); +INSERT INTO `spell_proc_event` VALUES +(12322,0,0,0,0,0x0000000000000000,0x00000001,2), +(12999,0,0,0,0,0x0000000000000000,0x00000001,4), +(13000,0,0,0,0,0x0000000000000000,0x00000001,6), +(13001,0,0,0,0,0x0000000000000000,0x00000001,8), +(13002,0,0,0,0,0x0000000000000000,0x00000001,10); diff --git a/sql/updates/6023_mangos_mangos_string.sql b/sql/updates/6023_mangos_mangos_string.sql new file mode 100644 index 000000000..c93d5ee98 --- /dev/null +++ b/sql/updates/6023_mangos_mangos_string.sql @@ -0,0 +1,6 @@ +DELETE FROM `mangos_string` WHERE `entry` IN (314,315,316); + +INSERT INTO `mangos_string` VALUES +(314, ' [peace forced]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(315, ' [hidden]',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(316, ' [invisible forced]',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6027_mangos_spell_affect.sql b/sql/updates/6027_mangos_spell_affect.sql new file mode 100644 index 000000000..877ca7215 --- /dev/null +++ b/sql/updates/6027_mangos_spell_affect.sql @@ -0,0 +1,12 @@ +DELETE FROM `spell_affect` WHERE `entry` IN +(12873,12872,11095,11252,12605,20244,20245,23565,16040,16113,16114,16115,16116,22804,14171,14172,14173,12290,12963,16858,16859,16860,16861,16862, +17815,17833,17834,17835,17836,21744,12866,12325,12863,12864,12865,12866,16194,16218,16219,16220,16221,23236,14143,14149,14151,26130,27848); + +DELETE FROM `spell_affect` WHERE `entry` IN (12945,16544,18372) AND `effectId` = 0; + +DELETE FROM `spell_affect` WHERE `entry` IN (14075,14074,14073,14072,14057,16544,23566) AND `effectId` = 1; + +INSERT INTO `spell_affect` VALUES +(14143,0,0x0000000004000206), +(14149,0,0x0000000004000206); + \ No newline at end of file diff --git a/sql/updates/6032_mangos_petcreateinfo_spell.sql b/sql/updates/6032_mangos_petcreateinfo_spell.sql new file mode 100644 index 000000000..e7a8a67a4 --- /dev/null +++ b/sql/updates/6032_mangos_petcreateinfo_spell.sql @@ -0,0 +1 @@ +ALTER TABLE `petcreateinfo_spell` DROP `FamilyPassive`; \ No newline at end of file diff --git a/sql/updates/6037_mangos_spell_affect.sql b/sql/updates/6037_mangos_spell_affect.sql new file mode 100644 index 000000000..152824a2e --- /dev/null +++ b/sql/updates/6037_mangos_spell_affect.sql @@ -0,0 +1,7 @@ +-- (38398) Reduced Cleave Cost () +DELETE FROM `spell_affect` WHERE `entry` IN (38398); +INSERT INTO `spell_affect` VALUES (38398, 0, 0x0000000020000000); + +-- (40389) Crow Discount () +DELETE FROM `spell_affect` WHERE `entry` IN (40389); +INSERT INTO `spell_affect` VALUES (40389, 0, 0x0000800000000000); \ No newline at end of file diff --git a/sql/updates/6038_mangos_creature_template.sql b/sql/updates/6038_mangos_creature_template.sql new file mode 100644 index 000000000..85711757f --- /dev/null +++ b/sql/updates/6038_mangos_creature_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_template` + ADD COLUMN `PetSpellDataId` mediumint(8) unsigned NOT NULL default '0' AFTER `spell4`; \ No newline at end of file diff --git a/sql/updates/6047_characters_character_social.sql b/sql/updates/6047_characters_character_social.sql new file mode 100644 index 000000000..c5ed55d94 --- /dev/null +++ b/sql/updates/6047_characters_character_social.sql @@ -0,0 +1,2 @@ +ALTER TABLE character_social + CHANGE COLUMN `note` `note` varchar(48) NOT NULL DEFAULT '' COMMENT 'Friend Note'; diff --git a/sql/updates/6047_characters_guild_bank_tab.sql b/sql/updates/6047_characters_guild_bank_tab.sql new file mode 100644 index 000000000..d27efd2b3 --- /dev/null +++ b/sql/updates/6047_characters_guild_bank_tab.sql @@ -0,0 +1,2 @@ +ALTER TABLE guild_bank_tab + CHANGE COLUMN `TabText` `TabText` varchar(500) NOT NULL DEFAULT ''; \ No newline at end of file diff --git a/sql/updates/6049_mangos_spell_proc_event.sql b/sql/updates/6049_mangos_spell_proc_event.sql new file mode 100644 index 000000000..5180f58f1 --- /dev/null +++ b/sql/updates/6049_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +INSERT INTO `spell_proc_event` VALUES +(20784,0,0,0,0,0,4096,0), +(32850,0,0,0,0,0,1,0), +(34457,0,0,0,0,0,4096,0); \ No newline at end of file diff --git a/sql/updates/6052_mangos_loot_template.sql b/sql/updates/6052_mangos_loot_template.sql new file mode 100644 index 000000000..3ecb7d1fe --- /dev/null +++ b/sql/updates/6052_mangos_loot_template.sql @@ -0,0 +1,23 @@ +ALTER TABLE `creature_loot_template` + DROP freeforall; + +ALTER TABLE `disenchant_loot_template` + DROP freeforall; + +ALTER TABLE `fishing_loot_template` + DROP freeforall; + +ALTER TABLE `gameobject_loot_template` + DROP freeforall; + +ALTER TABLE `item_loot_template` + DROP freeforall; + +ALTER TABLE `pickpocketing_loot_template` + DROP freeforall; + +ALTER TABLE `prospecting_loot_template` + DROP freeforall; + +ALTER TABLE `skinning_loot_template` + DROP freeforall; diff --git a/sql/updates/6058_mangos_spell_learn_spell.sql b/sql/updates/6058_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..33f3066da --- /dev/null +++ b/sql/updates/6058_mangos_spell_learn_spell.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_learn_spell` WHERE `entry` = 71; + +DELETE FROM `spell_learn_spell` WHERE `entry` = 2842; +INSERT INTO `spell_learn_spell` VALUES (2842,8681); \ No newline at end of file diff --git a/sql/updates/6061_characters_mail.sql b/sql/updates/6061_characters_mail.sql new file mode 100644 index 000000000..8e9b01224 --- /dev/null +++ b/sql/updates/6061_characters_mail.sql @@ -0,0 +1,2 @@ +ALTER TABLE mail + ADD COLUMN `mailTemplateId` mediumint(8) unsigned NOT NULL default '0' AFTER `stationery`; diff --git a/sql/updates/6061_mangos_quest_mail_loot_template.sql b/sql/updates/6061_mangos_quest_mail_loot_template.sql new file mode 100644 index 000000000..e399bd232 --- /dev/null +++ b/sql/updates/6061_mangos_quest_mail_loot_template.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS `quest_mail_loot_template`; +CREATE TABLE `quest_mail_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; diff --git a/sql/updates/6061_mangos_quest_template.sql b/sql/updates/6061_mangos_quest_template.sql new file mode 100644 index 000000000..5e8033382 --- /dev/null +++ b/sql/updates/6061_mangos_quest_template.sql @@ -0,0 +1,3 @@ +ALTER TABLE quest_template + ADD COLUMN `RewMailTemplateId` mediumint(8) unsigned NOT NULL default '0' AFTER `RewSpellCast`, + ADD COLUMN `RewMailDelaySecs` int(11) unsigned NOT NULL default '0' AFTER `RewMailTemplateId`; diff --git a/sql/updates/6062_mangos_spell_proc_event.sql b/sql/updates/6062_mangos_spell_proc_event.sql new file mode 100644 index 000000000..9486bc33d --- /dev/null +++ b/sql/updates/6062_mangos_spell_proc_event.sql @@ -0,0 +1,19 @@ +DELETE FROM spell_proc_event WHERE entry = 13743 OR entry = 13875; +DELETE FROM spell_proc_event WHERE entry = 14076 OR entry = 14094; + +UPDATE spell_proc_event SET Category = 0, SkillId = 0 WHERE entry = 12797 OR entry = 12799 OR entry = 12800; +UPDATE spell_proc_event SET Category = 0 WHERE entry = 13754 OR entry = 13867; +UPDATE spell_proc_event SET Category = 0 WHERE entry = 40458; + +UPDATE spell_proc_event SET SkillId = 0 WHERE entry = 16850 OR entry = 16923 OR entry = 16924; +UPDATE spell_proc_event SET SkillId = 0 WHERE entry = 17793 OR entry = 17796 OR entry = 17801 OR entry = 17802 OR entry = 17803; +UPDATE spell_proc_event SET SkillId = 0, SchoolMask = 0 WHERE entry = 23721; +UPDATE spell_proc_event SET SkillId = 0, SchoolMask = 0 WHERE entry = 28809; +UPDATE spell_proc_event SET SkillId = 0, SchoolMask = 0 WHERE entry = 28823; +UPDATE spell_proc_event SET SkillId = 0 WHERE entry = 23695; + +UPDATE spell_proc_event SET SchoolMask = 0, SpellFamilyMask = 0x8000000060 WHERE entry = 18073 OR entry = 18096; +UPDATE spell_proc_event SET SchoolMask = 0 WHERE entry = 19407 OR entry = 19412 OR entry = 19413 OR entry = 19414 OR entry = 19415; +UPDATE spell_proc_event SET SchoolMask = 0 WHERE entry = 20234 OR entry = 20235; +UPDATE spell_proc_event SET SchoolMask = 0 WHERE entry = 23551 OR entry = 23572; +UPDATE spell_proc_event SET SchoolMask = 0 WHERE entry = 38394; \ No newline at end of file diff --git a/sql/updates/6078_mangos_spell_proc_event.sql b/sql/updates/6078_mangos_spell_proc_event.sql new file mode 100644 index 000000000..19de716a4 --- /dev/null +++ b/sql/updates/6078_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (20210,20212,20213,20214,20215); +INSERT INTO `spell_proc_event` VALUES +(20210,0,0,0,10,0x00010000C0000000,0x10000000,0), +(20212,0,0,0,10,0x00010000C0000000,0x10000000,0), +(20213,0,0,0,10,0x00010000C0000000,0x10000000,0), +(20214,0,0,0,10,0x00010000C0000000,0x10000000,0), +(20215,0,0,0,10,0x00010000C0000000,0x10000000,0); diff --git a/sql/updates/6090_mangos_command.sql b/sql/updates/6090_mangos_command.sql new file mode 100644 index 000000000..34e2985b2 --- /dev/null +++ b/sql/updates/6090_mangos_command.sql @@ -0,0 +1,8 @@ +DELETE FROM `command` WHERE `name` IN ('lookup event','event','event activelist','event start','event stop'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('lookup event',2,'Syntax: .lookup event $name\r\nAttempts to find the ID of the event with the provided $name.'), +('event',2,'Syntax: .event #event_id\r\nShow details about event with #event_id.'), +('event activelist',2,'Syntax: .event activelist\r\nShow list of currently active events.'), +('event start',2,'Syntax: .event start #event_id\r\nStart event #event_id. Set start time for event to current moment (change not saved in DB).'), +('event stop',2,'Syntax: .event stop #event_id\r\nStop event #event_id. Set start time for event to time in past that make current moment is event stop time (change not saved in DB).'); diff --git a/sql/updates/6090_mangos_mangos_string.sql b/sql/updates/6090_mangos_mangos_string.sql new file mode 100644 index 000000000..e9a91151d --- /dev/null +++ b/sql/updates/6090_mangos_mangos_string.sql @@ -0,0 +1,9 @@ +DELETE FROM `mangos_string` WHERE `entry` IN (583,584,585,586,587,588); + +INSERT INTO `mangos_string` VALUES +(583,'%d - |cffffffff|Hgameevent:%d|h[%s]|h|r%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(584,'No event found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(585,'Event not exist!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(586,'Event %u: %s%s\nStart: %s End: %s Occurence: %s Length: %s\nNext state change: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(587,'Event %u already active!',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(588,'Event %u not active!',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6151_mangos_spell_proc_event.sql b/sql/updates/6151_mangos_spell_proc_event.sql new file mode 100644 index 000000000..6f005b654 --- /dev/null +++ b/sql/updates/6151_mangos_spell_proc_event.sql @@ -0,0 +1,14 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (45444,46364); +INSERT INTO `spell_proc_event` VALUES +(45444,0,0,0,0,0x0000000000000000,0x00100402,0), +(46364,0,0,0,0,0x0000000000000000,0x00100402,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (34827); +INSERT INTO `spell_proc_event` VALUES +(34827,0,0,0,0,0x0000000000000000,0x00100402,0); + +-- Creature's Earth Shield proc on melee attacks +DELETE FROM `spell_proc_event` WHERE `entry` IN (32734); +INSERT INTO `spell_proc_event` VALUES +(32734,0,0,0,0,0x0000000000000000,0x00000002,0); + diff --git a/sql/updates/6164_mangos_command.sql b/sql/updates/6164_mangos_command.sql new file mode 100644 index 000000000..a55ddd89b --- /dev/null +++ b/sql/updates/6164_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` IN ('gm fly'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('gm fly',3,'Syntax: .gm fly on/off\r\nEnable/disable gm fly mode.'); diff --git a/sql/updates/6171_mangos_spell_affect.sql b/sql/updates/6171_mangos_spell_affect.sql new file mode 100644 index 000000000..a6fb29e85 --- /dev/null +++ b/sql/updates/6171_mangos_spell_affect.sql @@ -0,0 +1,56 @@ +DELETE FROM spell_affect WHERE (entry = 16757 OR entry = 16758) AND effectId = 1; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +16757, 1, 0x240 +), ( +16758, 1, 0x240 +); +DELETE FROM spell_affect WHERE (entry = 17904 OR (entry >= 17912 AND entry <= 17916)) AND effectId = 0; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +17904, 0, 0 +), ( +17912, 0, 0 +), ( +17913, 0, 0 +), ( +17914, 0, 0 +), ( +17915, 0, 0 +), ( +17916, 0, 0 +); +DELETE FROM spell_affect WHERE entry = 21899 AND effectId = 0; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +21899, 0, 0x100 +); +DELETE FROM spell_affect WHERE entry = 24542 AND effectId = 1; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +24542, 1, 0xF0 +); +DELETE FROM spell_affect WHERE entry = 24546 AND effectId = 1; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +24546, 1, 0x400041E00 +); +DELETE FROM spell_affect WHERE (entry = 29187 OR entry = 29189 OR entry = 29191) AND effectId = 1; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +29187, 1, 0x4103000340750 +), ( +29189, 1, 0x4103000340750 +), ( +29191, 1, 0x4103000340750 +); +DELETE FROM spell_affect WHERE entry = 39805 AND effectId = 1; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +39805, 1, 0x3 +); +DELETE FROM spell_affect WHERE entry = 44293 AND effectId = 0; +INSERT INTO spell_affect ( `entry` , `effectId` , `SpellFamilyMask` ) +VALUES ( +44293, 0, 0x200 +); \ No newline at end of file diff --git a/sql/updates/6179_mangos_mangos_string.sql b/sql/updates/6179_mangos_mangos_string.sql new file mode 100644 index 000000000..1cb1ea7c0 --- /dev/null +++ b/sql/updates/6179_mangos_mangos_string.sql @@ -0,0 +1,6 @@ +DELETE FROM `mangos_string` WHERE `entry` IN (589,590,591); + +INSERT INTO `mangos_string` VALUES +(589,' Point movement to (X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(590,' Fear movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(591,' Distract movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6193_mangos_spell_proc_event.sql b/sql/updates/6193_mangos_spell_proc_event.sql new file mode 100644 index 000000000..98df85ab6 --- /dev/null +++ b/sql/updates/6193_mangos_spell_proc_event.sql @@ -0,0 +1,12 @@ + +DELETE FROM `spell_proc_event` WHERE `entry` IN (39442,39438,39440,39444); +INSERT INTO `spell_proc_event` VALUES +(39442,0,0,0,0,0x0000000000000000,0x00020001,0), +(39438,0,0,0,0,0x0000000000000000,0x00080001,0), +(39440,0,0,0,0,0x0000000000000000,0x00020000,0), +(39444,0,0,0,0,0x0000000000000000,0x00100002,0); + +DELETE FROM `spell_proc_event` WHERE `entry` IN (36111,39443); +INSERT INTO `spell_proc_event` VALUES +(36111,0,0,0,0,0x0000000000000000,0x00000001,0), +(39443,0,0,0,0,0x0000000000000000,0x00401000,0); diff --git a/sql/updates/6199_mangos_spell_proc_event.sql b/sql/updates/6199_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d4526446b --- /dev/null +++ b/sql/updates/6199_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (32748); +INSERT INTO `spell_proc_event` VALUES +(32748,0,0,0,8,0x0000000100000000,0x00080000,0); diff --git a/sql/updates/6210_mangos_spell_proc_event.sql b/sql/updates/6210_mangos_spell_proc_event.sql new file mode 100644 index 000000000..0ca6f9bd3 --- /dev/null +++ b/sql/updates/6210_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (38299); +INSERT INTO `spell_proc_event` VALUES +(38299,0,0,0,0,0x0000000000000000,0x08000000,0); diff --git a/sql/updates/6213_mangos_spell_target_position.sql b/sql/updates/6213_mangos_spell_target_position.sql new file mode 100644 index 000000000..c175e4170 --- /dev/null +++ b/sql/updates/6213_mangos_spell_target_position.sql @@ -0,0 +1 @@ +RENAME TABLE `spell_teleport` TO `spell_target_position`; diff --git a/sql/updates/6219_mangos_spell_proc_event.sql b/sql/updates/6219_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d8fd9740d --- /dev/null +++ b/sql/updates/6219_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (44835); +INSERT INTO `spell_proc_event` VALUES +(44835,0,0,0,7,0x0000008000000000,0x00000001,0); diff --git a/sql/updates/6246_mangos_spell_proc_event.sql b/sql/updates/6246_mangos_spell_proc_event.sql new file mode 100644 index 000000000..8dc2c5cec --- /dev/null +++ b/sql/updates/6246_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (38290); +INSERT INTO `spell_proc_event` VALUES +(38290,0,0,0,0,0x0000000000000000,0x00080000,3); diff --git a/sql/updates/6251_mangos_spell_proc_event.sql b/sql/updates/6251_mangos_spell_proc_event.sql new file mode 100644 index 000000000..81d54f921 --- /dev/null +++ b/sql/updates/6251_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` = 37336; +INSERT INTO `spell_proc_event` VALUES +(37336,0,0,0,0,0x0000000000000000,0x00084001,0); diff --git a/sql/updates/6255_mangos_spell_proc_event.sql b/sql/updates/6255_mangos_spell_proc_event.sql new file mode 100644 index 000000000..184bf953a --- /dev/null +++ b/sql/updates/6255_mangos_spell_proc_event.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_proc_event` WHERE `entry` = 40442; +INSERT INTO `spell_proc_event` VALUES +(40442,0,0,0,7,0x0000044000000014,0x00004001,0); + +DELETE FROM `spell_proc_event` WHERE `entry` = 40470; +INSERT INTO `spell_proc_event` VALUES +(40470,0,0,0,10,0x00000000C0800000,0x00004000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` = 40485; +INSERT INTO `spell_proc_event` VALUES +(40485,0,0,0,9,0x0000000100000000,0x00080000,0); + +DELETE FROM `spell_proc_event` WHERE `entry` = 40478; +INSERT INTO `spell_proc_event` VALUES +(40478,0,0,0,5,0x0000000000000002,0x00020000,0); diff --git a/sql/updates/6265_mangos_pet_name_generation.sql b/sql/updates/6265_mangos_pet_name_generation.sql new file mode 100644 index 000000000..45045d291 --- /dev/null +++ b/sql/updates/6265_mangos_pet_name_generation.sql @@ -0,0 +1,270 @@ +DROP TABLE IF EXISTS `pet_name_generation`; +CREATE TABLE `pet_name_generation` ( + `id` mediumint(8) unsigned NOT NULL auto_increment, + `word` tinytext NOT NULL, + `entry` mediumint(8) unsigned NOT NULL default '0', + `half` tinyint(4) NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `pet_name_generation` (`word`,`entry`,`half`) VALUES +('Aba',416,0), +('Az',416,0), +('Bel',416,0), +('Biz',416,0), +('Cho',416,0), +('Dag',416,0), +('Gak',416,0), +('Gar',416,0), +('Gel',416,0), +('Gho',416,0), +('Gob',416,0), +('Gra',416,0), +('Jak',416,0), +('Jub',416,0), +('Kar',416,0), +('Kup',416,0), +('Laz',416,0), +('Nal',416,0), +('Nok',416,0), +('Pag',416,0), +('Pig',416,0), +('Pip',416,0), +('Piz',416,0), +('Quz',416,0), +('Rui',416,0), +('Rul',416,0), +('Rup',416,0), +('Tar',416,0), +('Vol',416,0), +('Yaz',416,0), +('Zep',416,0), +('Zig',416,0), +('Zil',416,0), +('Zor',416,0), +('bis',416,1), +('fip',416,1), +('gup',416,1), +('ham',416,1), +('jub',416,1), +('kin',416,1), +('kol',416,1), +('lop',416,1), +('loz',416,1), +('mat',416,1), +('mir',416,1), +('nam',416,1), +('nar',416,1), +('nik',416,1), +('nip',416,1), +('pad',416,1), +('pep',416,1), +('pit',416,1), +('qua',416,1), +('rai',416,1), +('rin',416,1), +('rot',416,1), +('tai',416,1), +('tal',416,1), +('tik',416,1), +('tip',416,1), +('tog',416,1), +('tuk',416,1), +('uri',416,1), +('yal',416,1), +('yap',416,1), +('Bhee',417,0), +('Bruu',417,0), +('Czaa',417,0), +('Droo',417,0), +('Flaa',417,0), +('Fzuu',417,0), +('Ghaa',417,0), +('Gree',417,0), +('Gzaa',417,0), +('Haa',417,0), +('Haad',417,0), +('Haag',417,0), +('Haap',417,0), +('Jhaa',417,0), +('Jhuu',417,0), +('Khaa',417,0), +('Khii',417,0), +('Khuu',417,0), +('Kree',417,0), +('Luu',417,0), +('Maa',417,0), +('Nhee',417,0), +('Phuu',417,0), +('Pryy',417,0), +('Rhuu',417,0), +('Shaa',417,0), +('Sloo',417,0), +('Sruu',417,0), +('Thoo',417,0), +('Traa',417,0), +('Wraa',417,0), +('Zhaa',417,0), +('dhon',417,1), +('dhum',417,1), +('dhun',417,1), +('dom',417,1), +('don',417,1), +('drom',417,1), +('dym',417,1), +('fenn',417,1), +('fum',417,1), +('fun',417,1), +('ghon',417,1), +('ghun',417,1), +('grom',417,1), +('grym',417,1), +('hom',417,1), +('hon',417,1), +('hun',417,1), +('jhom',417,1), +('kun',417,1), +('lum',417,1), +('mmon',417,1), +('mon',417,1), +('myn',417,1), +('nam',417,1), +('nem',417,1), +('nhym',417,1), +('nom',417,1), +('num',417,1), +('phom',417,1), +('roon',417,1), +('rym',417,1), +('shon',417,1), +('thun',417,1), +('tom',417,1), +('zhem',417,1), +('zhum',417,1), +('zun',417,1), +('Bar',1860,0), +('Bel',1860,0), +('Char',1860,0), +('Grak\'',1860,0), +('Graz\'',1860,0), +('Grim',1860,0), +('Hath',1860,0), +('Hel',1860,0), +('Hok',1860,0), +('Huk',1860,0), +('Jhaz',1860,0), +('Jhom',1860,0), +('Juk\'',1860,0), +('Kal\'',1860,0), +('Klath',1860,0), +('Kon',1860,0), +('Krag',1860,0), +('Krak',1860,0), +('Mak',1860,0), +('Mezz',1860,0), +('Orm',1860,0), +('Phan',1860,0), +('Sar',1860,0), +('Tang',1860,0), +('Than',1860,0), +('Thog',1860,0), +('Thok',1860,0), +('Thul',1860,0), +('Zag\'',1860,0), +('Zang',1860,0), +('Zhar\'',1860,0), +('kath',1860,1), +('doc',1860,1), +('dok',1860,1), +('gak',1860,1), +('garth',1860,1), +('gore',1860,1), +('gorg',1860,1), +('grave',1860,1), +('gron',1860,1), +('juk',1860,1), +('krast',1860,1), +('kresh',1860,1), +('krit',1860,1), +('los',1860,1), +('mon',1860,1), +('mos',1860,1), +('moth',1860,1), +('nagma',1860,1), +('nak',1860,1), +('nar',1860,1), +('nos',1860,1), +('nuz',1860,1), +('phog',1860,1), +('rath',1860,1), +('tast',1860,1), +('taz',1860,1), +('thak',1860,1), +('thang',1860,1), +('thyk',1860,1), +('vhug',1860,1), +('zazt',1860,1), +('Ael',1863,0), +('Aez',1863,0), +('Ang',1863,0), +('Ban',1863,0), +('Bet',1863,0), +('Bro',1863,0), +('Bry',1863,0), +('Cat',1863,0), +('Dir',1863,0), +('Dis',1863,0), +('Dom',1863,0), +('Drus',1863,0), +('Fie',1863,0), +('Fier',1863,0), +('Gly',1863,0), +('Hel',1863,0), +('Hes',1863,0), +('Kal',1863,0), +('Lyn',1863,0), +('Mir',1863,0), +('Nim',1863,0), +('Sar',1863,0), +('Sel',1863,0), +('Vil',1863,0), +('Zah',1863,0), +('aith',1863,1), +('anda',1863,1), +('antia',1863,1), +('evere',1863,1), +('lia',1863,1), +('lissa',1863,1), +('neri',1863,1), +('neth',1863,1), +('nia',1863,1), +('nlissa',1863,1), +('nora',1863,1), +('nva',1863,1), +('nys',1863,1), +('ola',1863,1), +('ona',1863,1), +('ora',1863,1), +('rah',1863,1), +('riana',1863,1), +('riel',1863,1), +('rona',1863,1), +('tai',1863,1), +('tevere',1863,1), +('thea',1863,1), +('vina',1863,1), +('wena',1863,1), +('wyn',1863,1), +('xia',1863,1), +('yla',1863,1), +('yssa',1863,1), +('Flaa',17252,0), +('Haa',17252,0), +('Jhuu',17252,0), +('Shaa',17252,0), +('Thoo',17252,0), +('dhun',17252,1), +('ghun',17252,1), +('roon',17252,1), +('thun',17252,1), +('tom',17252,1); diff --git a/sql/updates/6270_mangos_spell_proc_event.sql b/sql/updates/6270_mangos_spell_proc_event.sql new file mode 100644 index 000000000..a92da067b --- /dev/null +++ b/sql/updates/6270_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_proc_event` WHERE `entry` in (31569,31570); +INSERT INTO `spell_proc_event` VALUES +(31569,0,0,0,3,0x0000000000010000,0x00004000,0), +(31570,0,0,0,3,0x0000000000010000,0x00004000,0); diff --git a/sql/updates/6291_characters_character_pet.sql b/sql/updates/6291_characters_character_pet.sql new file mode 100644 index 000000000..f65065953 --- /dev/null +++ b/sql/updates/6291_characters_character_pet.sql @@ -0,0 +1 @@ +ALTER TABLE `character_pet` DROP COLUMN `Commandstate`; \ No newline at end of file diff --git a/sql/updates/6297_characters_characters.sql b/sql/updates/6297_characters_characters.sql new file mode 100644 index 000000000..0072d8345 --- /dev/null +++ b/sql/updates/6297_characters_characters.sql @@ -0,0 +1,4 @@ +ALTER TABLE characters + CHANGE `logout_time` `logout_time` bigint(20) unsigned NOT NULL default '0', + DROP `last_honor_date`, + DROP `last_kill_date`; diff --git a/sql/updates/6298_characters_characters.sql b/sql/updates/6298_characters_characters.sql new file mode 100644 index 000000000..55485470a --- /dev/null +++ b/sql/updates/6298_characters_characters.sql @@ -0,0 +1,2 @@ +ALTER TABLE characters + ADD COLUMN death_expire_time bigint(20) unsigned NOT NULL default '0' AFTER zone; diff --git a/sql/updates/6298_characters_corpse.sql b/sql/updates/6298_characters_corpse.sql new file mode 100644 index 000000000..0cb34d26b --- /dev/null +++ b/sql/updates/6298_characters_corpse.sql @@ -0,0 +1,9 @@ +ALTER TABLE corpse + CHANGE time time_old timestamp NOT NULL default '0000-00-00 00:00:00', + ADD COLUMN time bigint(20) unsigned NOT NULL default '0' AFTER data; + +UPDATE corpse + SET time = UNIX_TIMESTAMP(time_old); + +ALTER TABLE corpse + DROP time_old; diff --git a/sql/updates/6304_mangos_spell_proc_event.sql b/sql/updates/6304_mangos_spell_proc_event.sql new file mode 100644 index 000000000..02a8e57cd --- /dev/null +++ b/sql/updates/6304_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_proc_event` WHERE `entry` = 45059; +INSERT INTO `spell_proc_event` VALUES +(45059,0,0,0,0,0x0000000000000000,0x08000000,0); diff --git a/sql/updates/6308_mangos_command.sql b/sql/updates/6308_mangos_command.sql new file mode 100644 index 000000000..9fb1fb423 --- /dev/null +++ b/sql/updates/6308_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` IN ('combatstop'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('combatstop',2,'Syntax: .combatstop\r\nStop combat for selected character. If selected non-player then command applied to self.'); diff --git a/sql/updates/6313_mangos_spell_proc_event.sql b/sql/updates/6313_mangos_spell_proc_event.sql new file mode 100644 index 000000000..164075c22 --- /dev/null +++ b/sql/updates/6313_mangos_spell_proc_event.sql @@ -0,0 +1,12 @@ +DELETE FROM spell_proc_event WHERE entry IN (37982, 37617, 37213, 37237, 37228); +INSERT INTO spell_proc_event VALUES +-- Earthstun (Brutal Earthstorm-Diamond) +(37982,0,0,0,0,0x0000000000000000,0x00000001,0), +-- Desolation Battlegear 4 pieces +(37617,0,0,0,0,0x0000000000000000,0x00000001,0), +-- Shaman Nuker T4 3 pieces +(37213,0,0,0,11,0x0000000090100007,0x00010000,0), +-- Shaman Nuker T5 4 pieces +(37237,0,0,0,11,0x0000000000000001,0x00010000,0), +-- Shaman Nuker T5 2 pieces +(37228,0,0,0,11,0x0000000090100007,0x00020000,0); diff --git a/sql/updates/6314_mangos_command.sql b/sql/updates/6314_mangos_command.sql new file mode 100644 index 000000000..c76561ba7 --- /dev/null +++ b/sql/updates/6314_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` IN ('combatstop'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('combatstop',2,'Syntax: .combatstop [$playername]\r\nStop combat for selected character. If selected non-player then command applied to self. If $playername provided then attempt applied to online player $playername.'); diff --git a/sql/updates/6324_mangos_creature_template.sql b/sql/updates/6324_mangos_creature_template.sql new file mode 100644 index 000000000..84a053e02 --- /dev/null +++ b/sql/updates/6324_mangos_creature_template.sql @@ -0,0 +1 @@ +ALTER TABLE `creature_template` ADD COLUMN `flags_extra` int(10) unsigned NOT NULL default '0' after `mechanic_immune_mask`; \ No newline at end of file diff --git a/sql/updates/6325_mangos_creature_template.sql b/sql/updates/6325_mangos_creature_template.sql new file mode 100644 index 000000000..9b47f8b92 --- /dev/null +++ b/sql/updates/6325_mangos_creature_template.sql @@ -0,0 +1,5 @@ +UPDATE creature_template + SET flags_extra = flags_extra | 2 WHERE civilian <> 0; + +ALTER TABLE `creature_template` + DROP civilian; diff --git a/sql/updates/6326_characters_corpse.sql b/sql/updates/6326_characters_corpse.sql new file mode 100644 index 000000000..0ff3d368e --- /dev/null +++ b/sql/updates/6326_characters_corpse.sql @@ -0,0 +1,8 @@ +ALTER TABLE corpse + ADD COLUMN corpse_type tinyint(3) unsigned NOT NULL default '0' AFTER bones_flag; + +UPDATE corpse + SET corpse_type = 1 WHERE bones_flag = 0; + +ALTER TABLE corpse + DROP bones_flag; diff --git a/sql/updates/6334_mangos_spell_affect.sql b/sql/updates/6334_mangos_spell_affect.sql new file mode 100644 index 000000000..28cd78f75 --- /dev/null +++ b/sql/updates/6334_mangos_spell_affect.sql @@ -0,0 +1,8 @@ +DELETE FROM spell_affect WHERE entry = 34491 AND effectId = 0 LIMIT 1; +DELETE FROM spell_affect WHERE entry = 34492 AND effectId = 0 LIMIT 1; +DELETE FROM spell_affect WHERE entry = 34493 AND effectId = 0 LIMIT 1; + +INSERT INTO spell_affect ( entry , effectId , SpellFamilyMask ) VALUES +(34491, 0, 0x4000000000C2), +(34492, 0, 0x4000000000C2), +(34493, 0, 0x4000000000C2); \ No newline at end of file diff --git a/sql/updates/6335_characters_corpse.sql b/sql/updates/6335_characters_corpse.sql new file mode 100644 index 000000000..ae1c6abfe --- /dev/null +++ b/sql/updates/6335_characters_corpse.sql @@ -0,0 +1,5 @@ +ALTER TABLE corpse + ADD KEY idx_type (corpse_type); + +UPDATE corpse + SET corpse_type = 1 WHERE corpse_type = 2; diff --git a/sql/updates/6351_mangos_spell_proc_event.sql b/sql/updates/6351_mangos_spell_proc_event.sql new file mode 100644 index 000000000..37e3c84b0 --- /dev/null +++ b/sql/updates/6351_mangos_spell_proc_event.sql @@ -0,0 +1,19 @@ +DELETE FROM spell_proc_event WHERE entry IN (17364); +INSERT INTO spell_proc_event VALUES +(17364,0,0,0,0,0x0000000000000000,0x00008000,0); + +DELETE FROM spell_proc_event WHERE entry IN (17794, 17797, 17798, 17799, 17800); +INSERT INTO spell_proc_event VALUES +(17794,0,0,0,0,0x0000000000000000,0x00008000,0), +(17797,0,0,0,0,0x0000000000000000,0x00008000,0), +(17798,0,0,0,0,0x0000000000000000,0x00008000,0), +(17799,0,0,0,0,0x0000000000000000,0x00008000,0), +(17800,0,0,0,0,0x0000000000000000,0x00008000,0); + +DELETE FROM spell_proc_event WHERE entry IN (43823); +INSERT INTO spell_proc_event VALUES +(43823,0,0,0,0,0x0000000000000000,0x00008000,0); + +DELETE FROM spell_proc_event WHERE entry IN (36576); +INSERT INTO spell_proc_event VALUES +(36576,0,0,0,0,0x0000000000000000,0x00008000,0); diff --git a/sql/updates/6360_characters_characters.sql b/sql/updates/6360_characters_characters.sql new file mode 100644 index 000000000..2d51514ec --- /dev/null +++ b/sql/updates/6360_characters_characters.sql @@ -0,0 +1,6 @@ +UPDATE characters SET data = REPLACE(data,' ',' '); +UPDATE characters SET data = CONCAT(TRIM(data),' '); + +UPDATE characters +SET data=CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1396),' ',-1396),' ','0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0',' ',SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1529),' ',-133)) +WHERE SUBSTRING_INDEX(data,' ',1528) = data AND SUBSTRING_INDEX(data,' ',1527) <> data; diff --git a/sql/updates/6360_characters_corpse.sql b/sql/updates/6360_characters_corpse.sql new file mode 100644 index 000000000..60db60a58 --- /dev/null +++ b/sql/updates/6360_characters_corpse.sql @@ -0,0 +1,6 @@ +UPDATE corpse SET data = REPLACE(data,' ',' '); +UPDATE corpse SET data = CONCAT(TRIM(data),' '); + +UPDATE corpse +SET data=CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',8),' ',-8),' ','0 0',' ',SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',39),' ',-31)) +WHERE SUBSTRING_INDEX(data,' ',38) = data AND SUBSTRING_INDEX(data,' ',37) <> data; diff --git a/sql/updates/6362_characters.sql b/sql/updates/6362_characters.sql new file mode 100644 index 000000000..7907025a9 --- /dev/null +++ b/sql/updates/6362_characters.sql @@ -0,0 +1,34 @@ +TRUNCATE `character_instance`; +TRUNCATE `instance`; + +ALTER TABLE `character_instance` + DROP KEY `leader`, + DROP PRIMARY KEY, + ADD PRIMARY KEY `guid` (`guid`,`instance`), + DROP COLUMN `map`, + DROP COLUMN `leader`, + MODIFY COLUMN `instance` int(11) unsigned NOT NULL default '0', + ADD COLUMN `permanent` tinyint(1) unsigned NOT NULL default '0'; + +ALTER TABLE `instance` + ADD COLUMN `difficulty` tinyint(1) unsigned NOT NULL default '0' AFTER `resettime`; + +CREATE TABLE `group_instance` ( + `leaderGuid` int(11) unsigned NOT NULL default '0', + `instance` int(11) unsigned NOT NULL default '0', + `permanent` tinyint(1) unsigned NOT NULL default '0', + PRIMARY KEY (`leaderGuid`,`instance`), + KEY `instance` (`instance`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `instance_reset` ( + `mapid` int(11) unsigned NOT NULL default '0', + `resettime` bigint(40) NOT NULL default '0', + PRIMARY KEY (`mapid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `groups` + ADD COLUMN `difficulty` tinyint(3) unsigned NOT NULL default '0' AFTER `isRaid`; + +ALTER TABLE `characters` + ADD COLUMN `dungeon_difficulty` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `map`; \ No newline at end of file diff --git a/sql/updates/6362_mangos_instance_template.sql b/sql/updates/6362_mangos_instance_template.sql new file mode 100644 index 000000000..f8f4f3c46 --- /dev/null +++ b/sql/updates/6362_mangos_instance_template.sql @@ -0,0 +1 @@ +UPDATE `instance_template` SET `reset_delay` = 0; \ No newline at end of file diff --git a/sql/updates/6367_mangos_spell_proc_event.sql b/sql/updates/6367_mangos_spell_proc_event.sql new file mode 100644 index 000000000..f85330634 --- /dev/null +++ b/sql/updates/6367_mangos_spell_proc_event.sql @@ -0,0 +1 @@ +DELETE FROM spell_proc_event WHERE entry IN (33280,35092,35093,35094); diff --git a/sql/updates/6369_mangos_spell_affect.sql b/sql/updates/6369_mangos_spell_affect.sql new file mode 100644 index 000000000..0d51c00d1 --- /dev/null +++ b/sql/updates/6369_mangos_spell_affect.sql @@ -0,0 +1 @@ +DELETE FROM spell_affect WHERE entry = 16824; diff --git a/sql/updates/6370_mangos_spell_affect.sql b/sql/updates/6370_mangos_spell_affect.sql new file mode 100644 index 000000000..33b575804 --- /dev/null +++ b/sql/updates/6370_mangos_spell_affect.sql @@ -0,0 +1,4 @@ +DELETE FROM spell_affect WHERE entry = 8875 AND effectId = 1 LIMIT 1; + +INSERT INTO spell_affect ( entry , effectId , SpellFamilyMask ) VALUES +(8875, 1, 0x40000000000); diff --git a/sql/updates/6381_mangos_command.sql b/sql/updates/6381_mangos_command.sql new file mode 100644 index 000000000..13414b6c3 --- /dev/null +++ b/sql/updates/6381_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` IN ('quest complete'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('quest complete',3,'Syntax: .quest complete #questid\r\nMark all quest objectives as completed for target character active quest. After this target character can go and get quest reward.'); diff --git a/sql/updates/6387_characters_character_ticket.sql b/sql/updates/6387_characters_character_ticket.sql new file mode 100644 index 000000000..72466ee7a --- /dev/null +++ b/sql/updates/6387_characters_character_ticket.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_ticket` + DROP `ticket_category`; diff --git a/sql/updates/6387_mangos_mangos_string.sql b/sql/updates/6387_mangos_mangos_string.sql new file mode 100644 index 000000000..9216cb922 --- /dev/null +++ b/sql/updates/6387_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry = 290; +INSERT INTO mangos_string VALUES (290, 'Ticket of %s (Last updated: %s):\n%s', NULL, NULL, NULL, NULL, NULL, NULL, NULL); + diff --git a/sql/updates/6397_mangos_creature_template.sql b/sql/updates/6397_mangos_creature_template.sql new file mode 100644 index 000000000..7bd062f21 --- /dev/null +++ b/sql/updates/6397_mangos_creature_template.sql @@ -0,0 +1 @@ +UPDATE creature_template SET flags_extra = flags_extra | 1 WHERE rank = 3; \ No newline at end of file diff --git a/sql/updates/6398_mangos_creature_template.sql b/sql/updates/6398_mangos_creature_template.sql new file mode 100644 index 000000000..0a1b41cc2 --- /dev/null +++ b/sql/updates/6398_mangos_creature_template.sql @@ -0,0 +1,2 @@ +ALTER TABLE `creature_template` + ADD COLUMN `heroic_entry` mediumint(8) unsigned NOT NULL default '0' AFTER entry; diff --git a/sql/updates/6412_characters_declinedname.sql b/sql/updates/6412_characters_declinedname.sql new file mode 100644 index 000000000..50bf21f45 --- /dev/null +++ b/sql/updates/6412_characters_declinedname.sql @@ -0,0 +1,24 @@ +DROP TABLE IF EXISTS `character_declinedname`; +CREATE TABLE `character_declinedname` ( + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', + `genitive` varchar(12) NOT NULL default '', + `dative` varchar(12) NOT NULL default '', + `accusative` varchar(12) NOT NULL default '', + `instrumental` varchar(12) NOT NULL default '', + `prepositional` varchar(12) NOT NULL default '', + PRIMARY KEY (`guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +DROP TABLE IF EXISTS `character_pet_declinedname`; +CREATE TABLE `character_pet_declinedname` ( + `id` int(11) unsigned NOT NULL default '0', + `owner` int(11) unsigned NOT NULL default '0', + `genitive` varchar(12) NOT NULL default '', + `dative` varchar(12) NOT NULL default '', + `accusative` varchar(12) NOT NULL default '', + `instrumental` varchar(12) NOT NULL default '', + `prepositional` varchar(12) NOT NULL default '', + PRIMARY KEY (`id`), + KEY owner_key (`owner`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + diff --git a/sql/updates/6426_mangos_locales.sql b/sql/updates/6426_mangos_locales.sql new file mode 100644 index 000000000..0424eaa8e --- /dev/null +++ b/sql/updates/6426_mangos_locales.sql @@ -0,0 +1,87 @@ + +ALTER TABLE locales_creature + ADD COLUMN name_loc8 varchar(100) NOT NULL default '' AFTER name_loc7, + ADD COLUMN subname_loc8 varchar(100) default NULL AFTER subname_loc7; + +UPDATE locales_creature SET name_loc8 = name_loc7, subname_loc8 = subname_loc7; + +ALTER TABLE locales_gameobject + ADD COLUMN name_loc8 varchar(100) NOT NULL default '' AFTER name_loc7, + ADD COLUMN castbarcaption_loc8 varchar(100) NOT NULL default '' AFTER castbarcaption_loc7; + +UPDATE locales_gameobject SET name_loc8 = name_loc7, castbarcaption_loc8 = castbarcaption_loc7; + +ALTER TABLE locales_item + ADD COLUMN name_loc8 varchar(100) NOT NULL default '' AFTER name_loc7, + ADD COLUMN description_loc8 varchar(255) default NULL AFTER description_loc7; + +UPDATE locales_item SET name_loc8 = name_loc7, description_loc8 = description_loc7; + +ALTER TABLE locales_page_text + ADD COLUMN Text_loc8 longtext AFTER Text_loc7; + +UPDATE locales_page_text SET Text_loc8 = Text_loc7; + +ALTER TABLE locales_quest + ADD COLUMN Title_loc8 text AFTER Title_loc7, + ADD COLUMN Details_loc8 text AFTER Details_loc7, + ADD COLUMN Objectives_loc8 text AFTER Objectives_loc7, + ADD COLUMN OfferRewardText_loc8 text AFTER OfferRewardText_loc7, + ADD COLUMN RequestItemsText_loc8 text AFTER RequestItemsText_loc7, + ADD COLUMN EndText_loc8 text AFTER EndText_loc7, + ADD COLUMN ObjectiveText1_loc8 text AFTER ObjectiveText1_loc7, + ADD COLUMN ObjectiveText2_loc8 text AFTER ObjectiveText2_loc7, + ADD COLUMN ObjectiveText3_loc8 text AFTER ObjectiveText3_loc7, + ADD COLUMN ObjectiveText4_loc8 text AFTER ObjectiveText4_loc7; + +UPDATE locales_quest SET Title_loc8 = Title_loc7, + Details_loc8 = Details_loc7, + Objectives_loc8 = Objectives_loc7, + OfferRewardText_loc8 = OfferRewardText_loc7, + RequestItemsText_loc8 = RequestItemsText_loc7, + EndText_loc8 = EndText_loc7, + ObjectiveText1_loc8 = ObjectiveText1_loc7, + ObjectiveText2_loc8 = ObjectiveText2_loc7, + ObjectiveText3_loc8 = ObjectiveText3_loc7, + ObjectiveText4_loc8 = ObjectiveText4_loc7; + +ALTER TABLE locales_npc_text + ADD COLUMN Text0_0_loc8 longtext AFTER Text0_0_loc7, + ADD COLUMN Text0_1_loc8 longtext AFTER Text0_1_loc7, + ADD COLUMN Text1_0_loc8 longtext AFTER Text1_0_loc7, + ADD COLUMN Text1_1_loc8 longtext AFTER Text1_1_loc7, + ADD COLUMN Text2_0_loc8 longtext AFTER Text2_0_loc7, + ADD COLUMN Text2_1_loc8 longtext AFTER Text2_1_loc7, + ADD COLUMN Text3_0_loc8 longtext AFTER Text3_0_loc7, + ADD COLUMN Text3_1_loc8 longtext AFTER Text3_1_loc7, + ADD COLUMN Text4_0_loc8 longtext AFTER Text4_0_loc7, + ADD COLUMN Text4_1_loc8 longtext AFTER Text4_1_loc7, + ADD COLUMN Text5_0_loc8 longtext AFTER Text5_0_loc7, + ADD COLUMN Text5_1_loc8 longtext AFTER Text5_1_loc7, + ADD COLUMN Text6_0_loc8 longtext AFTER Text6_0_loc7, + ADD COLUMN Text6_1_loc8 longtext AFTER Text6_1_loc7, + ADD COLUMN Text7_0_loc8 longtext AFTER Text7_0_loc7, + ADD COLUMN Text7_1_loc8 longtext AFTER Text7_1_loc7; + +UPDATE locales_npc_text SET Text0_0_loc8 = Text0_0_loc7, + Text0_1_loc8 = Text0_1_loc7, + Text1_0_loc8 = Text1_0_loc7, + Text1_1_loc8 = Text1_1_loc7, + Text2_0_loc8 = Text2_0_loc7, + Text2_1_loc8 = Text2_1_loc7, + Text3_0_loc8 = Text3_0_loc7, + Text3_1_loc8 = Text3_1_loc7, + Text4_0_loc8 = Text4_0_loc7, + Text4_1_loc8 = Text4_1_loc7, + Text5_0_loc8 = Text5_0_loc7, + Text5_1_loc8 = Text5_1_loc7, + Text6_0_loc8 = Text6_0_loc7, + Text6_1_loc8 = Text6_1_loc7, + Text7_0_loc8 = Text7_0_loc7, + Text7_1_loc8 = Text7_1_loc7; + +ALTER TABLE mangos_string + ADD COLUMN content_loc8 text AFTER content_loc7; + +UPDATE mangos_string SET content_loc8 = content_loc7; + diff --git a/sql/updates/6426_realmd_localization.sql b/sql/updates/6426_realmd_localization.sql new file mode 100644 index 000000000..40cd288b8 --- /dev/null +++ b/sql/updates/6426_realmd_localization.sql @@ -0,0 +1 @@ +DROP TABLE localization; diff --git a/sql/updates/6431_mangos_mangos_string.sql b/sql/updates/6431_mangos_mangos_string.sql new file mode 100644 index 000000000..27d3e2b26 --- /dev/null +++ b/sql/updates/6431_mangos_mangos_string.sql @@ -0,0 +1,5 @@ +DELETE FROM mangos_string WHERE entry IN (518,521); +INSERT INTO mangos_string VALUES +(518,'%d - |cffffffff|Hitemset:%d|h[%s %s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(521,'%d - |cffffffff|Hskill:%d|h[%s %s]|h|r %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + diff --git a/sql/updates/6439_mangos_command.sql b/sql/updates/6439_mangos_command.sql new file mode 100644 index 000000000..3e0587e9a --- /dev/null +++ b/sql/updates/6439_mangos_command.sql @@ -0,0 +1,7 @@ +DELETE FROM `command` WHERE `name` IN ('cast','cast back','cast self','cast target'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('cast',3,'Syntax: .cast #spellid [triggered]\r\n Cast #spellid to selected target. If no target selected cast to self. If \'trigered\' or part provided then spell casted with triggered flag.'), +('cast back',3,'Syntax: .cast back #spellid [triggered]\r\n Selected target will cast #spellid to your character. If \'trigered\' or part provided then spell casted with triggered flag.'), +('cast self',3,'Syntax: .cast self #spellid [triggered]\r\nCast #spellid by target at target itself. If \'trigered\' or part provided then spell casted with triggered flag.'), +('cast target',3,'Syntax: .cast target #spellid [triggered]\r\n Selected target will cast #spellid to his victim. If \'trigered\' or part provided then spell casted with triggered flag.'); diff --git a/sql/updates/6456_mangos_command.sql b/sql/updates/6456_mangos_command.sql new file mode 100644 index 000000000..da496969c --- /dev/null +++ b/sql/updates/6456_mangos_command.sql @@ -0,0 +1,7 @@ +DELETE FROM `command` WHERE `name` IN ('instance unbind','instance listbinds','instance stats','instance savedata'); + +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('instance unbind',3,'Syntax: .instance unbind all\r\n All of the selected player\'s binds will be cleared.'), +('instance listbinds',3,'Syntax: .instance listbinds\r\n Lists the binds of the selected player.'), +('instance stats',3,'Syntax: .instance stats\r\n Shows statistics about instances.'), +('instance savedata',3,'Syntax: .instance savedata\r\n Save the InstanceData for the current player\'s map to the DB.'); diff --git a/sql/updates/6472_realmd_account.sql b/sql/updates/6472_realmd_account.sql new file mode 100644 index 000000000..67ef4ce01 --- /dev/null +++ b/sql/updates/6472_realmd_account.sql @@ -0,0 +1,2 @@ +ALTER TABLE account + CHARSET=utf8 COLLATE=utf8_general_ci; diff --git a/sql/updates/6492_mangos_spell_chain.sql b/sql/updates/6492_mangos_spell_chain.sql new file mode 100644 index 000000000..840aa7cdb --- /dev/null +++ b/sql/updates/6492_mangos_spell_chain.sql @@ -0,0 +1,36 @@ +ALTER TABLE spell_chain + ADD COLUMN req_spell mediumint(9) NOT NULL default '0'; + +DELETE FROM `spell_chain` WHERE `spell_id` IN (20217,25898,25890,27145,25782,25916,27141,1038,25895,25899,27169,25894,25918,27143,16689,16810,16811,16812,16813,17329,27009); +INSERT INTO `spell_chain` (spell_id,prev_spell,first_spell,rank,req_spell) VALUES +/* Greater Blessing of Kings */ +(20217,0,20217,1,0), +(25898,0,25898,1,20217), +/* Greater Blessing of Light */ +(25890,0,25890,1,19979), +(27145,25890,25890,2,27144), +/* Greater Blessing of Might */ +(25782,0,25782,1,19838), +(25916,25782,25782,2,25291), +(27141,25916,25782,3,27140), +/* Greater Blessing of Salvation */ +(1038,0,1038,1,0), +(25895,0,25895,1,1038), +/* Greater Blessing of Sanctuary */ +(25899,0,25899,1,20914), +(27169,25899,25899,2,27168), +/* Greater Blessing of Wisdom */ +(25894,0,25894,1,19854), +(25918,25894,25894,2,25290), +(27143,25918,25894,3,27142), +/* Nature's Grasp */ +(16689,0,16689,1,339), +(16810,16689,16689,2,1062), +(16811,16810,16689,3,5195), +(16812,16811,16689,4,5196), +(16813,16812,16689,5,9852), +(17329,16813,16689,6,9853), +(27009,17329,16689,7,26989); + + + diff --git a/sql/updates/6496_mangos_spell_pet_auras.sql b/sql/updates/6496_mangos_spell_pet_auras.sql new file mode 100644 index 000000000..ef1086de6 --- /dev/null +++ b/sql/updates/6496_mangos_spell_pet_auras.sql @@ -0,0 +1,56 @@ +-- +-- Table structure for table `spell_pet_auras` +-- + +DROP TABLE IF EXISTS `spell_pet_auras`; +CREATE TABLE `spell_pet_auras` ( + `spell` mediumint(8) unsigned NOT NULL COMMENT 'dummy spell id', + `pet` mediumint(8) unsigned NOT NULL default '0' COMMENT 'pet id; 0 = all', + `aura` mediumint(8) unsigned NOT NULL COMMENT 'pet aura id', + PRIMARY KEY (`spell`,`pet`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `spell_pet_auras` +-- + +LOCK TABLES `spell_pet_auras` WRITE; +/*!40000 ALTER TABLE `spell_pet_auras` DISABLE KEYS */; +INSERT INTO `spell_pet_auras` VALUES +(19028, 0, 25228), +(19578, 0, 19579), +(20895, 0, 24529), +(28757, 0, 28758), +(35029, 0, 35060), +(35030, 0, 35061), +(35691, 0, 35696), +(35692, 0, 35696), +(35693, 0, 35696), +(23785, 416, 23759), +(23822, 416, 23826), +(23823, 416, 23827), +(23824, 416, 23828), +(23825, 416, 23829), +(23785, 417, 23762), +(23822, 417, 23837), +(23823, 417, 23838), +(23824, 417, 23839), +(23825, 417, 23840), +(23785, 1860, 23760), +(23822, 1860, 23841), +(23823, 1860, 23842), +(23824, 1860, 23843), +(23825, 1860, 23844), +(23785, 1863, 23761), +(23822, 1863, 23833), +(23823, 1863, 23834), +(23824, 1863, 23835), +(23825, 1863, 23836), +(23785, 17252, 35702), +(23822, 17252, 35703), +(23823, 17252, 35704), +(23824, 17252, 35705), +(23825, 17252, 35706); + +/*!40000 ALTER TABLE `spell_pet_auras` ENABLE KEYS */; +UNLOCK TABLES; \ No newline at end of file diff --git a/sql/updates/6506_mangos_spell_proc_event.sql b/sql/updates/6506_mangos_spell_proc_event.sql new file mode 100644 index 000000000..363274d51 --- /dev/null +++ b/sql/updates/6506_mangos_spell_proc_event.sql @@ -0,0 +1,7 @@ +DELETE FROM spell_proc_event WHERE entry IN (34138,42370,43728,46098); + +INSERT INTO spell_proc_event VALUES +(34138,0,0,0,11,0x0000000000000080,0x08000000,0), +(42370,0,0,0,11,0x0000000000000080,0x08000000,0), +(43728,0,0,0,11,0x0000000000000080,0x08000000,0), +(46098,0,0,0,11,0x0000000000000080,0x08000000,0); diff --git a/sql/updates/6509_mangos_command.sql b/sql/updates/6509_mangos_command.sql new file mode 100644 index 000000000..408b98e76 --- /dev/null +++ b/sql/updates/6509_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE IGNORE FROM `command` WHERE `name` = 'learn all_recipes'; +INSERT IGNORE INTO `command` (`name`,`security`,`help`) VALUES +('learn all_recipes',2,'Syntax: .learn all_recipes [$profession]\r\rLearns all recipes of specified profession and sets skill level to max.\rExample: .learn all_recipes enchanting'); diff --git a/sql/updates/6509_mangos_mangos_string.sql b/sql/updates/6509_mangos_mangos_string.sql new file mode 100644 index 000000000..5c6590e3a --- /dev/null +++ b/sql/updates/6509_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM mangos_string WHERE entry IN (592); +INSERT INTO mangos_string VALUES +(592,'You have learned all spells in craft: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + diff --git a/sql/updates/6513_mangos_command.sql b/sql/updates/6513_mangos_command.sql new file mode 100644 index 000000000..a9b9d566a --- /dev/null +++ b/sql/updates/6513_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE IGNORE FROM `command` WHERE `name` = 'cast dist'; +INSERT IGNORE INTO `command` (`name`,`security`,`help`) VALUES +('cast dist',3,'Syntax: .cast dist #spellid [#dist [triggered]]\r\n You will cast spell to pint at distance #dist. If \'trigered\' or part provided then spell casted with triggered flag. Not all spells can be casted as area spells.'); diff --git a/sql/updates/6515_mangos_spell_proc_event.sql b/sql/updates/6515_mangos_spell_proc_event.sql new file mode 100644 index 000000000..1609e37d4 --- /dev/null +++ b/sql/updates/6515_mangos_spell_proc_event.sql @@ -0,0 +1,4 @@ +DELETE FROM spell_proc_event WHERE entry IN(45355,45040); +INSERT INTO spell_proc_event VALUES +(45040,0,0,0,0,0x0000000000000000,0x00080001,0), +(45355,0,0,0,0,0x0000000000000000,0x00080001,0); diff --git a/sql/updates/6521_mangos_spell_proc_event.sql b/sql/updates/6521_mangos_spell_proc_event.sql new file mode 100644 index 000000000..97231e76b --- /dev/null +++ b/sql/updates/6521_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event WHERE entry IN(41260); +INSERT INTO `spell_proc_event` VALUES +(41260,0,0,0,0,0x0000000000000000,0x00000004,0); diff --git a/sql/updates/6523_mangos_spell_proc_event.sql b/sql/updates/6523_mangos_spell_proc_event.sql new file mode 100644 index 000000000..f9d93bbd9 --- /dev/null +++ b/sql/updates/6523_mangos_spell_proc_event.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_proc_event` WHERE `entry` IN (11185,12487,12488,19572,19573,28716,28744); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `Category`, `SkillID`, `SpellFamilyName`, `SpellFamilyMask`, `procFlags`, `ppmRate`) + VALUES + (11185, 0, 0, 0, 3, 0x0000000000000080, 0x00020000, 0), + (12487, 0, 0, 0, 3, 0x0000000000000080, 0x00020000, 0), + (12488, 0, 0, 0, 3, 0x0000000000000080, 0x00020000, 0), + (19572, 0, 0, 0, 9, 0x0000000000800000, 0x08000000, 0), + (19573, 0, 0, 0, 9, 0x0000000000800000, 0x08000000, 0), + (28716, 0, 0, 0, 7, 0x0000000000000010, 0x08000000, 0), + (28744, 0, 0, 0, 7, 0x0000000000000040, 0x08000000, 0); diff --git a/sql/updates/6528_mangos_spell_affect.sql b/sql/updates/6528_mangos_spell_affect.sql new file mode 100644 index 000000000..5ff9a8182 --- /dev/null +++ b/sql/updates/6528_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_affect WHERE entry IN (43743); +INSERT INTO spell_affect VALUES +(43743,1,0x0000000008000400); diff --git a/sql/updates/6528_mangos_spell_proc_event.sql b/sql/updates/6528_mangos_spell_proc_event.sql new file mode 100644 index 000000000..ff266cad2 --- /dev/null +++ b/sql/updates/6528_mangos_spell_proc_event.sql @@ -0,0 +1,85 @@ +ALTER TABLE spell_proc_event + ADD COLUMN cooldown int(10) unsigned NOT NULL default '0'; + +DELETE FROM spell_proc_event WHERE entry IN (324,325,905,945,974,8134,10431,10432,16620,18137, +19308,19309,19310,19311,19312,21185,23552,24398,24932,25469,25472,25477,29441,29444,29445,29446, +29447,30881,30883,30884,30885,30886,32593,32594,32734,32837,33736,33746,33757,33759,34355,34935, +34938,34939,34827,35077,35080,35083,35086,37173,37189,37197,37227,37655,38334,39027,39958,40899, +41260,41262,42135,42136,43737,45054,45057,45354,45481,45482,45483,45484,46569); + +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(324,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(325,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(905,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(945,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(974,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(8134,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(10431,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(10432,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(16620,0,0,0,0,0x0000000000000000,0x00100402,0,30), +(18137,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19308,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19309,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19310,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19311,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(19312,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(21185,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(23552,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(24398,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(24932,0,0,0,0,0x0000000000000000,0x00001000,0,6), +(25469,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(25472,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(25477,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(29441,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29444,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29445,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29446,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(29447,0,0,0,0,0x0000000000000000,0x01000000,0,1), +(30881,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30883,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30884,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30885,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(30886,0,0,0,0,0x0000000000000000,0x00008000,0,5), +(32593,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(32594,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(32734,0,0,0,0,0x0000000000000000,0x00000002,0,3), +(32837,0,0,0,0,0x0000000000000000,0x00004000,0,45), +(33736,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(33746,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(33757,0,0,0,0,0x0000000000000000,0x00000001,0,3), +(33759,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(34355,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(34935,0,0,0,0,0x0000000000000000,0x00000002,0,8), +(34938,0,0,0,0,0x0000000000000000,0x00000002,0,8), +(34939,0,0,0,0,0x0000000000000000,0x00000002,0,8), +(34827,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(35077,0,0,0,0,0x0000000000000000,0x00008000,0,60), +(35080,0,0,0,0,0x0000000000000000,0x00000001,0,60), +(35083,0,0,0,0,0x0000000000000000,0x00020000,0,60), +(35086,0,0,0,0,0x0000000000000000,0x08020000,0,60), +(37173,0,0,0,8,0x000001062CBC0598,0x000A0001,0,30), +(37189,0,0,0,10,0x0000000000006000,0x10000000,0,60), +(37197,0,0,0,0,0x0000000000000000,0x00004000,0,45), +(37227,0,0,0,11,0x00000000000001C0,0x10000000,0,60), +(37655,0,0,0,0,0x0000000000000000,0x00004000,0,60), +(38334,0,0,0,0,0x0000000000000000,0x00004000,0,60), +(39027,0,0,0,0,0x0000000000000000,0x00100402,0,3), +(39958,0,0,0,0,0x0000000000000000,0x00000001,0.7,40), +(40899,0,0,0,0,0x0000000000000000,0x00000001,0,3), +(41260,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(41262,0,0,0,0,0x0000000000000000,0x00000004,0,10), +(42135,0,0,0,7,0x0000044000000000,0x00100402,0,90), +(42136,0,0,0,7,0x0000044000000000,0x00100402,0,90), +(43737,0,0,0,7,0x0000044000000000,0x00000001,0,10), +(45054,0,0,0,0,0x0000000000000000,0x00020000,0,15), +(45057,0,0,0,0,0x0000000000000000,0x00000002,0,30), +(45354,0,0,0,0,0x0000000000000000,0x00000001,0,45), +(45481,0,0,0,0,0x0000000000000000,0x08020000,0,45), +(45482,0,0,0,0,0x0000000000000000,0x00080001,0,45), +(45483,0,0,0,0,0x0000000000000000,0x00080001,0,45), +(45484,0,0,0,0,0x0000000000000000,0x08000000,0,45), +(46569,0,0,0,0,0x0000000000000000,0x00004000,0,45); + +DELETE FROM spell_proc_event WHERE entry IN (43741); +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(43741,0,0,0,10,0x0000000080000000,0x00004000,0,0); diff --git a/sql/updates/6538_mangos_spell_proc_event.sql b/sql/updates/6538_mangos_spell_proc_event.sql new file mode 100644 index 000000000..f757fd77f --- /dev/null +++ b/sql/updates/6538_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event WHERE entry IN(34774); +INSERT INTO `spell_proc_event` VALUES +(34774,0,0,0,0,0x0000000000000000,0x00080001,1.5,20); diff --git a/sql/updates/6540_mangos_spell_proc_event.sql b/sql/updates/6540_mangos_spell_proc_event.sql new file mode 100644 index 000000000..cd9784cf9 --- /dev/null +++ b/sql/updates/6540_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event WHERE entry IN(38319); +INSERT INTO `spell_proc_event` VALUES +(38319,0,0,0,0,0x0000000000000000,0x00004000,0,0); diff --git a/sql/updates/6544_mangos_spell_proc_event.sql b/sql/updates/6544_mangos_spell_proc_event.sql new file mode 100644 index 000000000..835ae6dc3 --- /dev/null +++ b/sql/updates/6544_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM spell_proc_event WHERE entry IN (13983, 14070, 14071); +INSERT INTO `spell_proc_event` VALUES +(13983,0,0,0,0,0x0000000000000000,0x01000010,0,0), +(14070,0,0,0,0,0x0000000000000000,0x01000010,0,0), +(14071,0,0,0,0,0x0000000000000000,0x01000010,0,0); diff --git a/sql/updates/6545_mangos_command.sql b/sql/updates/6545_mangos_command.sql new file mode 100644 index 000000000..a6681fd23 --- /dev/null +++ b/sql/updates/6545_mangos_command.sql @@ -0,0 +1,7 @@ +DELETE FROM `command` WHERE name IN ('idleshutdown','info','shutdown','server info','server shutdown','server restart','server idleshutdown','server idlerestart'); +INSERT INTO `command` VALUES +('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'), +('server shutdown',3,'Syntax: .server shutdown seconds\r\n\r\nShut the server down after given seconds and show "Off server in X" or cancel the restart/shutdown if cancel value is used.'), +('server restart',3,'Syntax: .server restart seconds\r\n\r\nRestart the server after given seconds and show "Restart server in X" or cancel the restart/shutdown if cancel value is used.'), +('server idleshutdown',3,'Syntax: .server idleshutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'), +('server idlerestart',3,'Syntax: .server idlerestart #delay|cancel\r\n\r\nRestart the server after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'); diff --git a/sql/updates/6557_mangos_command.sql b/sql/updates/6557_mangos_command.sql new file mode 100644 index 000000000..688146679 --- /dev/null +++ b/sql/updates/6557_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE FROM command WHERE name = 'npc delete'; +INSERT INTO `command` VALUES +('npc delete',2,'Syntax: .npc delete [#guid]\r\n\r\nDelete creature with guid #guid (or the selected if no guid is provided)'); diff --git a/sql/updates/6574_mangos_spell_proc_event.sql b/sql/updates/6574_mangos_spell_proc_event.sql new file mode 100644 index 000000000..7a09512f7 --- /dev/null +++ b/sql/updates/6574_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event WHERE entry IN (41989); +INSERT INTO `spell_proc_event` VALUES +(41989,0,0,0,0,0x0000000000000000,0x00000001,3,0); diff --git a/sql/updates/6585_mangos_command.sql b/sql/updates/6585_mangos_command.sql new file mode 100644 index 000000000..123d102ba --- /dev/null +++ b/sql/updates/6585_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE FROM command WHERE name = 'reload config'; +INSERT INTO `command` VALUES +('reload config',3,'Syntax: .reload config\r\n\r\nReload config settings (by default stored in mangosd.conf). Not all settings can be change at reload: some new setting values will be ignored until restart, some values will applied with delay or only to new objects/maps, some values will explicitly rejected to change at reload.'); diff --git a/sql/updates/6588_mangos_spell_proc_event.sql b/sql/updates/6588_mangos_spell_proc_event.sql new file mode 100644 index 000000000..083a3524c --- /dev/null +++ b/sql/updates/6588_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event WHERE entry = 41434; +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(41434,0,0,0,0,0x0000000000000000,0x00000001,2,45); diff --git a/sql/updates/6596_characters_arena_team.sql b/sql/updates/6596_characters_arena_team.sql new file mode 100644 index 000000000..0e8afd589 --- /dev/null +++ b/sql/updates/6596_characters_arena_team.sql @@ -0,0 +1,10 @@ +ALTER TABLE arena_team CHANGE EmblemStyle _BackgroundColor int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE EmblemColor _EmblemStyle int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE BorderStyle _EmblemColor int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE BorderColor _BorderStyle int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE BackgroundColor _BorderColor int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE _BackgroundColor BackgroundColor int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE _EmblemStyle EmblemStyle int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE _EmblemColor EmblemColor int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE _BorderStyle BorderStyle int(10) unsigned NOT NULL default '0'; +ALTER TABLE arena_team CHANGE _BorderColor BorderColor int(10) unsigned NOT NULL default '0'; \ No newline at end of file diff --git a/sql/updates/6598_character_spell.sql b/sql/updates/6598_character_spell.sql new file mode 100644 index 000000000..bd5f6fdce --- /dev/null +++ b/sql/updates/6598_character_spell.sql @@ -0,0 +1,2 @@ +ALTER TABLE `character_spell` + ADD COLUMN `disabled` tinyint(3) unsigned NOT NULL default '0'; diff --git a/sql/updates/6609_mangos_mangos_string.sql b/sql/updates/6609_mangos_mangos_string.sql new file mode 100644 index 000000000..be7814d96 --- /dev/null +++ b/sql/updates/6609_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry = 170; +INSERT INTO mangos_string VALUES +(170,'You try to hear sound %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6613_mangos_mangos_string.sql b/sql/updates/6613_mangos_mangos_string.sql new file mode 100644 index 000000000..4b1635f49 --- /dev/null +++ b/sql/updates/6613_mangos_mangos_string.sql @@ -0,0 +1,11 @@ +DELETE FROM `mangos_string` WHERE entry = 636; +INSERT INTO `mangos_string` VALUES +(636,'The Battle for Eye of the Storm begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + +DELETE FROM `mangos_string` WHERE entry = 637; +INSERT INTO `mangos_string` VALUES +(637,'The Battle for Eye of the Storm begins in 30 seconds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + +DELETE FROM `mangos_string` WHERE entry = 638; +INSERT INTO `mangos_string` VALUES +(638,'The Battle for Eye of the Storm has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6627_mangos_creature_movement.sql b/sql/updates/6627_mangos_creature_movement.sql new file mode 100644 index 000000000..05aa78e12 --- /dev/null +++ b/sql/updates/6627_mangos_creature_movement.sql @@ -0,0 +1 @@ +ALTER TABLE creature_movement MODIFY COLUMN id int(10) unsigned NOT NULL COMMENT 'Creature GUID'; \ No newline at end of file diff --git a/sql/updates/6640_mangos_reference_loot_template.sql b/sql/updates/6640_mangos_reference_loot_template.sql new file mode 100644 index 000000000..612af9930 --- /dev/null +++ b/sql/updates/6640_mangos_reference_loot_template.sql @@ -0,0 +1,27 @@ +-- +-- Table structure for table `reference_loot_template` +-- + +DROP TABLE IF EXISTS `reference_loot_template`; +CREATE TABLE `reference_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `reference_loot_template` +-- + +LOCK TABLES `reference_loot_template` WRITE; +/*!40000 ALTER TABLE `reference_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `reference_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + diff --git a/sql/updates/6642_characters_declinedname.sql b/sql/updates/6642_characters_declinedname.sql new file mode 100644 index 000000000..a81690de2 --- /dev/null +++ b/sql/updates/6642_characters_declinedname.sql @@ -0,0 +1,6 @@ +ALTER TABLE character_declinedname + MODIFY COLUMN genitive varchar(15) NOT NULL default '', + MODIFY COLUMN dative varchar(15) NOT NULL default '', + MODIFY COLUMN accusative varchar(15) NOT NULL default '', + MODIFY COLUMN instrumental varchar(15) NOT NULL default '', + MODIFY COLUMN prepositional varchar(15) NOT NULL default ''; diff --git a/sql/updates/6668_mangos_spell_proc_event.sql b/sql/updates/6668_mangos_spell_proc_event.sql new file mode 100644 index 000000000..f6ebc5edb --- /dev/null +++ b/sql/updates/6668_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +DELETE FROM spell_proc_event WHERE entry IN (42135,42136); + +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(42135,0,0,0,0,0x0000000000000000,0x00100402,0,90), +(42136,0,0,0,0,0x0000000000000000,0x00100402,0,90); diff --git a/sql/updates/6673_mangos_areatrigger_scripts.sql b/sql/updates/6673_mangos_areatrigger_scripts.sql new file mode 100644 index 000000000..91d3cc6d9 --- /dev/null +++ b/sql/updates/6673_mangos_areatrigger_scripts.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `areatrigger_scripts`; +CREATE TABLE `areatrigger_scripts` ( + `entry` MEDIUMINT( 8 ) NOT NULL , + `ScriptName` CHAR( 64 ) NOT NULL , + PRIMARY KEY ( `entry` ) +) ENGINE = MYISAM DEFAULT CHARSET=utf8; + diff --git a/sql/updates/6676_mangos_spell_proc_event.sql b/sql/updates/6676_mangos_spell_proc_event.sql new file mode 100644 index 000000000..2a81a9f3b --- /dev/null +++ b/sql/updates/6676_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event where entry = 37447; +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(37447,0,0,0,3,0x0000010000000000,0x00004000,0,0); diff --git a/sql/updates/6681_mangos_mangos_string.sql b/sql/updates/6681_mangos_mangos_string.sql new file mode 100644 index 000000000..1c66abd53 --- /dev/null +++ b/sql/updates/6681_mangos_mangos_string.sql @@ -0,0 +1,5 @@ +DELETE FROM `mangos_string` WHERE entry IN (3,711,712); +INSERT INTO `mangos_string` VALUES +(3,'|cffff0000[System Message]: %s|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(711,'Queue status for %s (Lvl: %u to %u)\nQueued alliances: %u (Need at least %u more)\nQueued hordes: %u (Need at least %u more)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(712,'|cffff0000[BG Queue Announcer]:|r %s -- [%u-%u] A: %u (Need: %u), H: %u (Needs %u)|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6691_mangos_spell_proc_event.sql b/sql/updates/6691_mangos_spell_proc_event.sql new file mode 100644 index 000000000..cbd57317b --- /dev/null +++ b/sql/updates/6691_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_proc_event where entry = 37247; +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(37247,8,0,0,0,0x0000000000000000,0x00004000,0,45); diff --git a/sql/updates/6693_mangos_spell_affect.sql b/sql/updates/6693_mangos_spell_affect.sql new file mode 100644 index 000000000..ea0fb9e96 --- /dev/null +++ b/sql/updates/6693_mangos_spell_affect.sql @@ -0,0 +1,3 @@ +DELETE FROM spell_affect WHERE entry = '12606'; +INSERT INTO spell_affect (entry, effectId, SpellFamilyMask) VALUES +(12606,0,0x0000000000002000); diff --git a/sql/updates/6693_mangos_spell_proc_event.sql b/sql/updates/6693_mangos_spell_proc_event.sql new file mode 100644 index 000000000..fa4df63d5 --- /dev/null +++ b/sql/updates/6693_mangos_spell_proc_event.sql @@ -0,0 +1,11 @@ +DELETE FROM spell_proc_event where entry = 44604; +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(44604,0,0,0,0,0x0000000000000000,0x00004000,0,0); + +DELETE FROM spell_proc_event where entry = 44599; +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(44599,0,0,0,0,0x0000000000000000,0x00000001,0,5); + +DELETE FROM spell_proc_event where entry = 46046; +INSERT INTO spell_proc_event (entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown) VALUES +(46046,0,0,0,0,0x0000000000000000,0x00000001,0,5); diff --git a/sql/updates/6698_characters_character_tutorial.sql b/sql/updates/6698_characters_character_tutorial.sql new file mode 100644 index 000000000..78b6913fa --- /dev/null +++ b/sql/updates/6698_characters_character_tutorial.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS `character_tutorial`; +CREATE TABLE `character_tutorial` ( + `account` bigint(20) unsigned NOT NULL auto_increment COMMENT 'Account Identifier', + `realmid` int(11) unsigned NOT NULL default '0' COMMENT 'Realm Identifier', + `tut0` int(11) unsigned NOT NULL default '0', + `tut1` int(11) unsigned NOT NULL default '0', + `tut2` int(11) unsigned NOT NULL default '0', + `tut3` int(11) unsigned NOT NULL default '0', + `tut4` int(11) unsigned NOT NULL default '0', + `tut5` int(11) unsigned NOT NULL default '0', + `tut6` int(11) unsigned NOT NULL default '0', + `tut7` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`account`,`realmid`), + KEY acc_key (`account`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; diff --git a/sql/updates/6701_mangos_command.sql b/sql/updates/6701_mangos_command.sql new file mode 100644 index 000000000..e7dd8cfc2 --- /dev/null +++ b/sql/updates/6701_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('lookup player account','lookup player ip','lookup player email'); +INSERT INTO `command` VALUES ('lookup player account',2,'Syntax : .lookup player account $account ($limit) \r\n\r\n Searchs players, which account username is $account with optional parametr $limit of results.'); +INSERT INTO `command` VALUES ('lookup player ip',2,'Syntax : .lookup player ip $ip ($limit) \r\n\r\n Searchs players, which account ast_ip is $ip with optional parametr $limit of results.'); +INSERT INTO `command` VALUES ('lookup player email',2,'Syntax : .lookup player email $email ($limit) \r\n\r\n Searchs players, which account email is $email with optional parametr $limit of results.'); diff --git a/sql/updates/6701_mangos_mangos_string.sql b/sql/updates/6701_mangos_mangos_string.sql new file mode 100644 index 000000000..7084843dc --- /dev/null +++ b/sql/updates/6701_mangos_mangos_string.sql @@ -0,0 +1,5 @@ +DELETE FROM mangos_string WHERE entry IN (328,329,330); +INSERT INTO mangos_string VALUES +(328,'Characters at account %s (Id: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(329,' %s (GUID %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(330,'No players found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6708_mangos_mangos_string.sql b/sql/updates/6708_mangos_mangos_string.sql new file mode 100644 index 000000000..07c7943e3 --- /dev/null +++ b/sql/updates/6708_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry IN (167,168,466); +INSERT INTO mangos_string VALUES +(168,'Locations found are:\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6715_mangos_spell_affect.sql b/sql/updates/6715_mangos_spell_affect.sql new file mode 100644 index 000000000..07d1a202d --- /dev/null +++ b/sql/updates/6715_mangos_spell_affect.sql @@ -0,0 +1 @@ +DELETE FROM spell_affect WHERE entry = '12606'; diff --git a/sql/updates/6728_mangos_quest_template.sql b/sql/updates/6728_mangos_quest_template.sql new file mode 100644 index 000000000..f0a22225c --- /dev/null +++ b/sql/updates/6728_mangos_quest_template.sql @@ -0,0 +1 @@ +ALTER TABLE `quest_template` ADD COLUMN `Method` tinyint(3) unsigned NOT NULL default '2' AFTER `entry`; \ No newline at end of file diff --git a/sql/updates/6730_mangos_mangos_string.sql b/sql/updates/6730_mangos_mangos_string.sql new file mode 100644 index 000000000..20b6718d0 --- /dev/null +++ b/sql/updates/6730_mangos_mangos_string.sql @@ -0,0 +1,3 @@ +DELETE FROM mangos_string WHERE entry IN (331); +INSERT INTO mangos_string VALUES +(331,'Extended item cost %u not exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6740_characters_characters.sql b/sql/updates/6740_characters_characters.sql new file mode 100644 index 000000000..d59373327 --- /dev/null +++ b/sql/updates/6740_characters_characters.sql @@ -0,0 +1,2 @@ +ALTER TABLE characters + CHANGE COLUMN gmstate gmstate int(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/6740_mangos_command.sql b/sql/updates/6740_mangos_command.sql new file mode 100644 index 000000000..6c40f0cde --- /dev/null +++ b/sql/updates/6740_mangos_command.sql @@ -0,0 +1,4 @@ +DELETE FROM command WHERE name IN ('gm','gm chat'); +INSERT INTO `command` VALUES +('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'), +('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'); diff --git a/sql/updates/6740_mangos_mangos_string.sql b/sql/updates/6740_mangos_mangos_string.sql new file mode 100644 index 000000000..2c4109135 --- /dev/null +++ b/sql/updates/6740_mangos_mangos_string.sql @@ -0,0 +1,27 @@ +DELETE FROM mangos_string WHERE entry IN (332,333,334,335); +INSERT INTO mangos_string VALUES +(332,'GM mode is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(333,'GM mode is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(334,'GM Chat Badge is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(335,'GM Chat Badge is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + +DELETE FROM mangos_string WHERE entry IN (713,714,715,716); +INSERT INTO mangos_string VALUES +(713,'You must be level %u to join an arena team!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(714,'%s is not high enough level to join your team',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(715,'You don\'t meet Battleground level requirements',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(716,'Your arena team is full, %s cannot join it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + + +DELETE FROM mangos_string WHERE entry IN (800,801,802,803,804,805,806,807,808,809); +INSERT INTO mangos_string VALUES +(800,'Invalid name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(801,'You do not have enough gold',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(802,'You do not have enough free slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(803,'Your partner does not have enough free bag slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(804,'You do not have permission to perform that function',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(805,'Unknown language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(806,'You don\'t know that language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(807,'Please provide character name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(808,'Player %s not found or offline',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6742_mangos_command.sql b/sql/updates/6742_mangos_command.sql new file mode 100644 index 000000000..b84c1816d --- /dev/null +++ b/sql/updates/6742_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE FROM command WHERE name = 'sendmail'; +INSERT INTO `command` VALUES +('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'); diff --git a/sql/updates/6742_mangos_mangos_string.sql b/sql/updates/6742_mangos_mangos_string.sql new file mode 100644 index 000000000..e5309f53e --- /dev/null +++ b/sql/updates/6742_mangos_mangos_string.sql @@ -0,0 +1,4 @@ +DELETE FROM mangos_string WHERE entry IN (52,53); +INSERT INTO mangos_string VALUES +(52,'Invaid item count (%u) for item %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(53,'Mail can\'t have more %u item stacks',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/6748_mangos_mangos_string.sql b/sql/updates/6748_mangos_mangos_string.sql new file mode 100644 index 000000000..8be0f0936 --- /dev/null +++ b/sql/updates/6748_mangos_mangos_string.sql @@ -0,0 +1 @@ +DELETE FROM mangos_string WHERE entry IN (800); diff --git a/sql/updates/6750_mangos_command.sql b/sql/updates/6750_mangos_command.sql new file mode 100644 index 000000000..7b2651071 --- /dev/null +++ b/sql/updates/6750_mangos_command.sql @@ -0,0 +1,3 @@ +DELETE FROM command WHERE name = 'reload all_locales'; +INSERT INTO `command` VALUES +('reload all_locales',3,'Syntax: .reload all_locales\r\n\r\nReload all `locales_*` tables with reload support added and that can be _safe_ reloaded.'); diff --git a/sql/updates/6751_realmd_account.sql b/sql/updates/6751_realmd_account.sql new file mode 100644 index 000000000..2dec54d51 --- /dev/null +++ b/sql/updates/6751_realmd_account.sql @@ -0,0 +1,2 @@ +ALTER TABLE account + CHANGE COLUMN tbc expansion tinyint(3) unsigned NOT NULL default '0'; diff --git a/sql/updates/6760_mangos_creature_template.sql b/sql/updates/6760_mangos_creature_template.sql new file mode 100644 index 000000000..1dfb93b63 --- /dev/null +++ b/sql/updates/6760_mangos_creature_template.sql @@ -0,0 +1,2 @@ +UPDATE creature_template + SET flags_extra = flags_extra | 0x00000080 WHERE entry = 1; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am new file mode 100644 index 000000000..fafcb9363 --- /dev/null +++ b/sql/updates/Makefile.am @@ -0,0 +1,414 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## Change installation location +# datadir = mangos/sql/updates +pkgdatadir = $(datadir)/mangos/sql/updates + +## Files to be installed +# Install basic SQL files to datadir +pkgdata_DATA = \ + 5651_characters_guild_bank_tab.sql \ + 5651_characters_characters.sql \ + 5651_characters_character_social.sql \ + 5651_mangos_creature_template.sql \ + 5655_mangos_spell_affect.sql \ + 5655_mangos_spell_chain.sql \ + 5655_mangos_spell_proc_event.sql \ + 5659_mangos_loot_template.sql \ + 5660_mangos_spell_elixir.sql \ + 5664_mangos.sql \ + 5665_mangos_creature_template.sql \ + 5679_mangos_creature_template.sql \ + 5680_mangos_spell_proc_event.sql \ + 5698_mangos_item_template.sql \ + 5708_mangos_player_levelstats.sql \ + 5711_characters_character_kill.sql \ + 5711_mangos_command.sql \ + 5714_mangos_command.sql \ + 5714_mangos_mangos_string.sql \ + 5718_mangos_command.sql \ + 5718_mangos_creature_template.sql \ + 5718_mangos_mangos_string.sql \ + 5720_mangos_command.sql \ + 5720_mangos_mangos_string.sql \ + 5721_mangos_spell_affect.sql \ + 5733_mangos_creature.sql \ + 5739_mangos_creature.sql \ + 5739_mangos_gameobject.sql \ + 5746_mangos_quest_template.sql \ + 5753_mangos_areatrigger_teleport.sql \ + 5758_mangos_creature_addon.sql \ + 5759_mangos_command.sql \ + 5764_characters_characters.sql \ + 5764_mangos_command.sql \ + 5771_mangos_spell_learn_spell.sql \ + 5772_mangos_command.sql \ + 5773_mangos_spell_affect.sql \ + 5773_mangos_spell_learn_spell.sql \ + 5774_mangos_command.sql \ + 5774_mangos_mangos_string.sql \ + 5777_mangos_command.sql \ + 5778_mangos_spell_affect.sql \ + 5779_mangos_quest_template.sql \ + 5784_mangos_player_levelstats.sql \ + 5787_mangos_player_levelstats.sql \ + 5790_mangos_player_classlevelstats.sql \ + 5790_mangos_player_levelstats.sql \ + 5799_mangos_spell_proc_event.sql \ + 5813_mangos_mangos_string.sql \ + 5827_mangos_spell_affect.sql \ + 5827_mangos_spell_chain.sql \ + 5827_mangos_spell_learn_spell.sql \ + 5827_mangos_spell_proc_event.sql \ + 5831_mangos_skill_fishing_base_level.sql \ + 5842_mangos_spell_affect.sql \ + 5845_mangos_spell_proc_event.sql \ + 5847_mangos_command.sql \ + 5857_mangos_spell_proc_event.sql \ + 5861_mangos_command.sql \ + 5865_mangos_command.sql \ + 5867_mangos_spell_affect.sql \ + 5875_mangos_quest_template.sql \ + 5880_mangos_mangos_string.sql \ + 5882_mangos_spell_affect.sql \ + 5896_mangos_spell_proc_event.sql \ + 5923_mangos_spell_affect.sql \ + 5940_mangos_spell_affect.sql \ + 5946_mangos_spell_affect.sql \ + 5955_characters_guild_eventlog.sql \ + 5965_mangos_mangos_string.sql \ + 5973_mangos_spell_proc_event.sql \ + 5977_characters_pet.sql \ + 5982_mangos.sql \ + 5986_mangos_spell_proc_event.sql \ + 5999_mangos_spell_proc_event.sql \ + 6016_mangos_spell_proc_event.sql \ + 6017_mangos_spell_proc_event.sql \ + 6022_mangos_spell_proc_event.sql \ + 6023_mangos_mangos_string.sql \ + 6027_mangos_spell_affect.sql \ + 6032_mangos_petcreateinfo_spell.sql \ + 6037_mangos_spell_affect.sql \ + 6038_mangos_creature_template.sql \ + 6047_characters_character_social.sql \ + 6047_characters_guild_bank_tab.sql \ + 6049_mangos_spell_proc_event.sql \ + 6052_mangos_loot_template.sql \ + 6058_mangos_spell_learn_spell.sql \ + 6061_characters_mail.sql \ + 6061_mangos_quest_mail_loot_template.sql \ + 6061_mangos_quest_template.sql \ + 6062_mangos_spell_proc_event.sql \ + 6078_mangos_spell_proc_event.sql \ + 6090_mangos_command.sql \ + 6090_mangos_mangos_string.sql \ + 6151_mangos_spell_proc_event.sql \ + 6164_mangos_command.sql \ + 6171_mangos_spell_affect.sql \ + 6179_mangos_mangos_string.sql \ + 6193_mangos_spell_proc_event.sql \ + 6199_mangos_spell_proc_event.sql \ + 6210_mangos_spell_proc_event.sql \ + 6213_mangos_spell_target_position.sql \ + 6219_mangos_spell_proc_event.sql \ + 6246_mangos_spell_proc_event.sql \ + 6251_mangos_spell_proc_event.sql \ + 6255_mangos_spell_proc_event.sql \ + 6265_mangos_pet_name_generation.sql \ + 6270_mangos_spell_proc_event.sql \ + 6291_characters_character_pet.sql \ + 6297_characters_characters.sql \ + 6298_characters_characters.sql \ + 6298_characters_corpse.sql \ + 6304_mangos_spell_proc_event.sql \ + 6308_mangos_command.sql \ + 6313_mangos_spell_proc_event.sql \ + 6314_mangos_command.sql \ + 6324_mangos_creature_template.sql \ + 6325_mangos_creature_template.sql \ + 6326_characters_corpse.sql \ + 6334_mangos_spell_affect.sql \ + 6335_characters_corpse.sql \ + 6351_mangos_spell_proc_event.sql \ + 6360_characters_corpse.sql \ + 6360_characters_characters.sql \ + 6362_characters.sql \ + 6362_mangos_instance_template.sql \ + 6367_mangos_spell_proc_event.sql \ + 6369_mangos_spell_affect.sql \ + 6370_mangos_spell_affect.sql \ + 6381_mangos_command.sql \ + 6387_characters_character_ticket.sql \ + 6387_mangos_mangos_string.sql \ + 6397_mangos_creature_template.sql \ + 6398_mangos_creature_template.sql \ + 6412_characters_declinedname.sql \ + 6426_mangos_locales.sql \ + 6426_realmd_localization.sql \ + 6431_mangos_mangos_string.sql \ + 6439_mangos_command.sql \ + 6456_mangos_command.sql \ + 6472_realmd_account.sql \ + 6492_mangos_spell_chain.sql \ + 6496_mangos_spell_pet_auras.sql \ + 6506_mangos_spell_proc_event.sql \ + 6509_mangos_command.sql \ + 6509_mangos_mangos_string.sql \ + 6513_mangos_command.sql \ + 6515_mangos_spell_proc_event.sql \ + 6521_mangos_spell_proc_event.sql \ + 6523_mangos_spell_proc_event.sql \ + 6528_mangos_spell_affect.sql \ + 6528_mangos_spell_proc_event.sql \ + 6538_mangos_spell_proc_event.sql \ + 6540_mangos_spell_proc_event.sql \ + 6544_mangos_spell_proc_event.sql \ + 6545_mangos_command.sql \ + 6557_mangos_command.sql \ + 6574_mangos_spell_proc_event.sql \ + 6585_mangos_command.sql \ + 6588_mangos_spell_proc_event.sql \ + 6596_characters_arena_team.sql \ + 6598_character_spell.sql \ + 6609_mangos_mangos_string.sql \ + 6613_mangos_mangos_string.sql \ + 6627_mangos_creature_movement.sql \ + 6640_mangos_reference_loot_template.sql \ + 6642_characters_declinedname.sql \ + 6668_mangos_spell_proc_event.sql \ + 6676_mangos_spell_proc_event.sql \ + 6681_mangos_mangos_string.sql \ + 6691_mangos_spell_proc_event.sql \ + 6693_mangos_spell_affect.sql \ + 6693_mangos_spell_proc_event.sql \ + 6698_characters_character_tutorial.sql \ + 6701_mangos_command.sql \ + 6701_mangos_mangos_string.sql \ + 6708_mangos_mangos_string.sql \ + 6715_mangos_spell_affect.sql \ + 6728_mangos_quest_template.sql \ + 6730_mangos_mangos_string.sql \ + 6740_characters_characters.sql \ + 6740_mangos_command.sql \ + 6740_mangos_mangos_string.sql \ + 6742_mangos_command.sql \ + 6742_mangos_mangos_string.sql \ + 6748_mangos_mangos_string.sql \ + 6750_mangos_command.sql \ + 6751_realmd_account.sql \ + 6760_mangos_creature_template.sql \ + README + +## Additional files to include when running 'make dist' +# SQL update files, to upgrade database schema from older revisions +EXTRA_DIST = \ + 5651_characters_guild_bank_tab.sql \ + 5651_characters_characters.sql \ + 5651_characters_character_social.sql \ + 5651_mangos_creature_template.sql \ + 5655_mangos_spell_affect.sql \ + 5655_mangos_spell_chain.sql \ + 5655_mangos_spell_proc_event.sql \ + 5659_mangos_loot_template.sql \ + 5660_mangos_spell_elixir.sql \ + 5664_mangos.sql \ + 5665_mangos_creature_template.sql \ + 5679_mangos_creature_template.sql \ + 5680_mangos_spell_proc_event.sql \ + 5698_mangos_item_template.sql \ + 5708_mangos_player_levelstats.sql \ + 5711_characters_character_kill.sql \ + 5711_mangos_command.sql \ + 5714_mangos_command.sql \ + 5714_mangos_mangos_string.sql \ + 5718_mangos_command.sql \ + 5718_mangos_creature_template.sql \ + 5718_mangos_mangos_string.sql \ + 5720_mangos_command.sql \ + 5720_mangos_mangos_string.sql \ + 5721_mangos_spell_affect.sql \ + 5733_mangos_creature.sql \ + 5739_mangos_creature.sql \ + 5739_mangos_gameobject.sql \ + 5746_mangos_quest_template.sql \ + 5753_mangos_areatrigger_teleport.sql \ + 5758_mangos_creature_addon.sql \ + 5759_mangos_command.sql \ + 5764_characters_characters.sql \ + 5764_mangos_command.sql \ + 5771_mangos_spell_learn_spell.sql \ + 5772_mangos_command.sql \ + 5773_mangos_spell_affect.sql \ + 5773_mangos_spell_learn_spell.sql \ + 5774_mangos_command.sql \ + 5774_mangos_mangos_string.sql \ + 5777_mangos_command.sql \ + 5778_mangos_spell_affect.sql \ + 5779_mangos_quest_template.sql \ + 5784_mangos_player_levelstats.sql \ + 5787_mangos_player_levelstats.sql \ + 5790_mangos_player_classlevelstats.sql \ + 5790_mangos_player_levelstats.sql \ + 5799_mangos_spell_proc_event.sql \ + 5813_mangos_mangos_string.sql \ + 5827_mangos_spell_affect.sql \ + 5827_mangos_spell_chain.sql \ + 5827_mangos_spell_learn_spell.sql \ + 5827_mangos_spell_proc_event.sql \ + 5831_mangos_skill_fishing_base_level.sql \ + 5842_mangos_spell_affect.sql \ + 5845_mangos_spell_proc_event.sql \ + 5847_mangos_command.sql \ + 5857_mangos_spell_proc_event.sql \ + 5861_mangos_command.sql \ + 5865_mangos_command.sql \ + 5867_mangos_spell_affect.sql \ + 5875_mangos_quest_template.sql \ + 5880_mangos_mangos_string.sql \ + 5882_mangos_spell_affect.sql \ + 5896_mangos_spell_proc_event.sql \ + 5923_mangos_spell_affect.sql \ + 5940_mangos_spell_affect.sql \ + 5946_mangos_spell_affect.sql \ + 5955_characters_guild_eventlog.sql \ + 5965_mangos_mangos_string.sql \ + 5973_mangos_spell_proc_event.sql \ + 5977_characters_pet.sql \ + 5982_mangos.sql \ + 5986_mangos_spell_proc_event.sql \ + 5999_mangos_spell_proc_event.sql \ + 6016_mangos_spell_proc_event.sql \ + 6017_mangos_spell_proc_event.sql \ + 6022_mangos_spell_proc_event.sql \ + 6023_mangos_mangos_string.sql \ + 6027_mangos_spell_affect.sql \ + 6032_mangos_petcreateinfo_spell.sql \ + 6037_mangos_spell_affect.sql \ + 6038_mangos_creature_template.sql \ + 6047_characters_character_social.sql \ + 6047_characters_guild_bank_tab.sql \ + 6049_mangos_spell_proc_event.sql \ + 6052_mangos_loot_template.sql \ + 6058_mangos_spell_learn_spell.sql \ + 6061_characters_mail.sql \ + 6061_mangos_quest_mail_loot_template.sql \ + 6061_mangos_quest_template.sql \ + 6062_mangos_spell_proc_event.sql \ + 6078_mangos_spell_proc_event.sql \ + 6090_mangos_command.sql \ + 6090_mangos_mangos_string.sql \ + 6151_mangos_spell_proc_event.sql \ + 6164_mangos_command.sql \ + 6171_mangos_spell_affect.sql \ + 6179_mangos_mangos_string.sql \ + 6193_mangos_spell_proc_event.sql \ + 6199_mangos_spell_proc_event.sql \ + 6210_mangos_spell_proc_event.sql \ + 6213_mangos_spell_target_position.sql \ + 6219_mangos_spell_proc_event.sql \ + 6246_mangos_spell_proc_event.sql \ + 6251_mangos_spell_proc_event.sql \ + 6255_mangos_spell_proc_event.sql \ + 6265_mangos_pet_name_generation.sql \ + 6270_mangos_spell_proc_event.sql \ + 6291_characters_character_pet.sql \ + 6297_characters_characters.sql \ + 6298_characters_characters.sql \ + 6298_characters_corpse.sql \ + 6304_mangos_spell_proc_event.sql \ + 6308_mangos_command.sql \ + 6313_mangos_spell_proc_event.sql \ + 6314_mangos_command.sql \ + 6324_mangos_creature_template.sql \ + 6325_mangos_creature_template.sql \ + 6326_characters_corpse.sql \ + 6334_mangos_spell_affect.sql \ + 6335_characters_corpse.sql \ + 6351_mangos_spell_proc_event.sql \ + 6360_characters_corpse.sql \ + 6360_characters_characters.sql \ + 6362_characters.sql \ + 6362_mangos_instance_template.sql \ + 6367_mangos_spell_proc_event.sql \ + 6369_mangos_spell_affect.sql \ + 6370_mangos_spell_affect.sql \ + 6381_mangos_command.sql \ + 6387_characters_character_ticket.sql \ + 6387_mangos_mangos_string.sql \ + 6397_mangos_creature_template.sql \ + 6398_mangos_creature_template.sql \ + 6412_characters_declinedname.sql \ + 6426_mangos_locales.sql \ + 6426_realmd_localization.sql \ + 6431_mangos_mangos_string.sql \ + 6439_mangos_command.sql \ + 6456_mangos_command.sql \ + 6472_realmd_account.sql \ + 6492_mangos_spell_chain.sql \ + 6496_mangos_spell_pet_auras.sql \ + 6506_mangos_spell_proc_event.sql \ + 6509_mangos_command.sql \ + 6509_mangos_mangos_string.sql \ + 6513_mangos_command.sql \ + 6515_mangos_spell_proc_event.sql \ + 6521_mangos_spell_proc_event.sql \ + 6523_mangos_spell_proc_event.sql \ + 6528_mangos_spell_affect.sql \ + 6528_mangos_spell_proc_event.sql \ + 6538_mangos_spell_proc_event.sql \ + 6540_mangos_spell_proc_event.sql \ + 6544_mangos_spell_proc_event.sql \ + 6545_mangos_command.sql \ + 6557_mangos_command.sql \ + 6574_mangos_spell_proc_event.sql \ + 6585_mangos_command.sql \ + 6588_mangos_spell_proc_event.sql \ + 6596_characters_arena_team.sql \ + 6598_character_spell.sql \ + 6609_mangos_mangos_string.sql \ + 6613_mangos_mangos_string.sql \ + 6627_mangos_creature_movement.sql \ + 6640_mangos_reference_loot_template.sql \ + 6642_characters_declinedname.sql \ + 6668_mangos_spell_proc_event.sql \ + 6673_mangos_areatrigger_scripts.sql \ + 6676_mangos_spell_proc_event.sql \ + 6681_mangos_mangos_string.sql \ + 6691_mangos_spell_proc_event.sql \ + 6693_mangos_spell_affect.sql \ + 6693_mangos_spell_proc_event.sql \ + 6698_characters_character_tutorial.sql \ + 6701_mangos_command.sql \ + 6701_mangos_mangos_string.sql \ + 6708_mangos_mangos_string.sql \ + 6715_mangos_spell_affect.sql \ + 6728_mangos_quest_template.sql \ + 6730_mangos_mangos_string.sql \ + 6740_characters_characters.sql \ + 6740_mangos_command.sql \ + 6740_mangos_mangos_string.sql \ + 6742_mangos_command.sql \ + 6742_mangos_mangos_string.sql \ + 6748_mangos_mangos_string.sql \ + 6750_mangos_command.sql \ + 6751_realmd_account.sql \ + 6760_mangos_creature_template.sql \ + README diff --git a/sql/updates/README b/sql/updates/README new file mode 100644 index 000000000..b76a62b77 --- /dev/null +++ b/sql/updates/README @@ -0,0 +1,33 @@ += MaNGOS -- README = + +Copyright (c) 2005-2008 MaNGOS + +See the COPYING file for copying conditions. + +== Database Updates == +This folder contains SQL files which will apply required updates to your MySQL +database, whenever the MaNGOS database structure has been changed or extended. + +To see if you need an update, the file names have been given a fixed structure +that should enable you to see if you need an update or not. + +=== File name descriptin === +File names are divided into two parts. First part is the revision that will be +compatible with database after apply update. The second part of the name, +is the table that needs and update or has been added. See an example below: + + 1123_characters_character_spell.sql + | | | + | | | + | | The table character_spell + | | will need an update. + | | + | Name of affected DB (default recommended name) + | Can be: characters, mangos, realmd + | + MaNGOS revision older 1123 will need this update. + After appling this update DB compatiable with revision 1122 + will be compatibale with revision 1123. + Revision 1123 and any revision after 1123, e.g. 1124 or 1137, + already includes this update in the default database + file mangos.sql. diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 000000000..abf76a649 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,23 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = tools framework shared realmd game bindings mangosd + +## Additional files to include when running 'make dist' +# Nothing yet. diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am new file mode 100644 index 000000000..9080b8d31 --- /dev/null +++ b/src/bindings/Makefile.am @@ -0,0 +1,17 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +SUBDIRS = universal diff --git a/src/bindings/universal/Makefile.am b/src/bindings/universal/Makefile.am new file mode 100644 index 000000000..462875ab0 --- /dev/null +++ b/src/bindings/universal/Makefile.am @@ -0,0 +1,56 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../shared/ -I$(srcdir)/../../framework/ + +## Build MaNGOS script library as shared library. +# libmangosscript shared library will later be reused by world server daemon. +lib_LTLIBRARIES = libmangosscript.la +libmangosscript_la_SOURCES = \ + ScriptMgr.cpp \ + ScriptMgr.h \ + config.h \ + system.cpp \ + Scripts/sc_default.cpp \ + Scripts/sc_defines.cpp \ + Scripts/sc_defines.h + +## libtool settings +# API versioning +# Link against dependencies +# How to increase version info: +# - only bug fixes implemented: +# bump the version to LTMANGOS_CURRENT:LTMANGOS_REVISION+1:LTMANGOS_AGE +# - augmented the interface: +# bump the version to LTMANGOS_CURRENT+1:0:LTMANGOS_AGE+1 +# - broken old interface: +# bump the version to LTMANGOS_CURRENT+1:0:0 +LTMANGOS_CURRENT = 0 +LTMANGOS_REVISION = 0 +LTMANGOS_AGE = 0 +libmangosscript_la_LIBFLAGS = -version-info $(LTMANGOS_CURRENT):$(LTMANGOS_REVISION):$(LTMANGOS_AGE) + +## Additional files to include when running 'make dist' +# Scripts defaults. +EXTRA_DIST = \ + Scripts/sc_default.cpp \ + Scripts/sc_defines.cpp \ + Scripts/sc_defines.h diff --git a/src/bindings/universal/Readme.txt b/src/bindings/universal/Readme.txt new file mode 100644 index 000000000..e152162de --- /dev/null +++ b/src/bindings/universal/Readme.txt @@ -0,0 +1,32 @@ + +** HOW TO SCRIPT IN C++ ** + +1 - create a file myscript.cpp in scripts folder. +2 - copy the content of script_default.cpp, it as the structure on how the scripting fuctions are organized. + dont forget to change the name of fuctions, like GossipHello_default to GossipHello_myscript. + +3 - in fuction AddSC_default change to AddSC_myscript. +4 - newscript->Name="default"; change the string to "myscript" this name is the one to be called from the db +5 - dont forget to change the name in here to newscript->pGossipHello = &GossipHello_default; this is where the scripted fuctions are stored. +6 - and last thing is in ScriptMgr.cpp + +add your AddSC_myscript in here + +// -- Scripts to be added -- +extern void AddSC_default(); +// ------------------- + +and here + +// -- Inicialize the Scripts to be Added -- + AddSC_default(); + // ---------------------------------------- + +now start using the player fuctions to script ;) +see the sc_defines.h for some fuctions to use. + +hope it helps, any question use our forum. + +copy libscript.so and libscript.a to your server/lib path + +made by: mmcs. diff --git a/src/bindings/universal/ScriptMgr.cpp b/src/bindings/universal/ScriptMgr.cpp new file mode 100644 index 000000000..b43a11dc5 --- /dev/null +++ b/src/bindings/universal/ScriptMgr.cpp @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "ScriptMgr.h" +#include "../../game/GossipDef.h" +#include "../../game/GameObject.h" +#include "../../game/Player.h" +#include "../../game/Map.h" +#include "../../game/ObjectMgr.h" + +//uint8 loglevel = 0; +int nrscripts; +Script *m_scripts[MAX_SCRIPTS]; +InstanceDataScript* m_instance_scripts[MAX_INSTANCE_SCRIPTS]; +int num_inst_scripts; + +// -- Scripts to be added -- +extern void AddSC_default(); +// ------------------- + +MANGOS_DLL_EXPORT +void ScriptsFree() +{ // Free resources before library unload + for(int i=0;iName == Name ) + return m_scripts[i]; + } + return NULL; +} + +MANGOS_DLL_EXPORT +bool GossipHello ( Player * player, Creature *_Creature ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pGossipHello) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGossipHello(player,_Creature); +} + +MANGOS_DLL_EXPORT +bool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 action ) +{ + debug_log("DEBUG: Gossip selection, sender: %d, action: %d",sender, action); + + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pGossipSelect) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGossipSelect(player,_Creature,sender,action); +} + +MANGOS_DLL_EXPORT +bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ) +{ + debug_log("DEBUG: Gossip selection, sender: %d, action: %d",sender, action); + + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pGossipSelectWithCode) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGossipSelectWithCode(player,_Creature,sender,action,sCode); +} + +MANGOS_DLL_EXPORT +bool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pQuestAccept) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pQuestAccept(player,_Creature,_Quest); +} + +MANGOS_DLL_EXPORT +bool QuestSelect( Player *player, Creature *_Creature, Quest *_Quest ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pQuestSelect) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pQuestSelect(player,_Creature,_Quest); +} + +MANGOS_DLL_EXPORT +bool QuestComplete( Player *player, Creature *_Creature, Quest *_Quest ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pQuestComplete) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pQuestComplete(player,_Creature,_Quest); +} + +MANGOS_DLL_EXPORT +bool ChooseReward( Player *player, Creature *_Creature, Quest *_Quest, uint32 opt ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pChooseReward) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pChooseReward(player,_Creature,_Quest,opt); +} + +MANGOS_DLL_EXPORT +uint32 NPCDialogStatus( Player *player, Creature *_Creature ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pNPCDialogStatus) return 100; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pNPCDialogStatus(player,_Creature); +} + +MANGOS_DLL_EXPORT +uint32 GODialogStatus( Player *player, GameObject *_GO ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName); + if(!tmpscript || !tmpscript->pGODialogStatus) return 100; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGODialogStatus(player,_GO); +} + +MANGOS_DLL_EXPORT +bool ItemHello( Player *player, Item *_Item, Quest *_Quest ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_Item->GetProto()->ScriptName); + if(!tmpscript || !tmpscript->pItemHello) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pItemHello(player,_Item,_Quest); +} + +MANGOS_DLL_EXPORT +bool ItemQuestAccept( Player *player, Item *_Item, Quest *_Quest ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_Item->GetProto()->ScriptName); + if(!tmpscript || !tmpscript->pItemQuestAccept) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pItemQuestAccept(player,_Item,_Quest); +} + +MANGOS_DLL_EXPORT +bool GOHello( Player *player, GameObject *_GO ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName); + if(!tmpscript || !tmpscript->pGOHello) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGOHello(player,_GO); +} + +MANGOS_DLL_EXPORT +bool GOQuestAccept( Player *player, GameObject *_GO, Quest *_Quest ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName); + if(!tmpscript || !tmpscript->pGOQuestAccept) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGOQuestAccept(player,_GO,_Quest); +} + +MANGOS_DLL_EXPORT +bool GOChooseReward( Player *player, GameObject *_GO, Quest *_Quest, uint32 opt ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName); + if(!tmpscript || !tmpscript->pGOChooseReward) return false; + + player->PlayerTalkClass->ClearMenus(); + return tmpscript->pGOChooseReward(player,_GO,_Quest,opt); +} + +MANGOS_DLL_EXPORT +bool AreaTrigger ( Player *player, AreaTriggerEntry* atEntry ) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(GetAreaTriggerScriptNameById(atEntry->id)); + if(!tmpscript || !tmpscript->pAreaTrigger) return false; + + return tmpscript->pAreaTrigger(player, atEntry); +} + +MANGOS_DLL_EXPORT +bool ReceiveEmote ( Player *player, Creature *_Creature, uint32 emote ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->pReceiveEmote) return false; + + return tmpscript->pReceiveEmote(player,_Creature, emote); +} + +MANGOS_DLL_EXPORT +bool ItemUse( Player *player, Item* _Item, SpellCastTargets const& targets) +{ + Script *tmpscript = NULL; + + tmpscript = GetScriptByName(_Item->GetProto()->ScriptName); + if(!tmpscript || !tmpscript->pItemUse) return false; + + return tmpscript->pItemUse(player,_Item,targets); +} + +MANGOS_DLL_EXPORT +CreatureAI* GetAI(Creature *_Creature ) +{ + Script *tmpscript = GetScriptByName(_Creature->GetScriptName()); + if(!tmpscript || !tmpscript->GetAI) return NULL; + + return tmpscript->GetAI(_Creature); +} + +MANGOS_DLL_EXPORT +InstanceData* CreateInstanceData(Map *map) +{ + if(!map->IsDungeon()) return NULL; + std::string name = ((InstanceMap*)map)->GetScript(); + if(!name.empty()) + for(int i=0;iname == name) + return m_instance_scripts[i]->GetInstanceData(map); + return NULL; +} + +void ScriptedAI::UpdateAI(const uint32) +{ + //Check if we have a current target + if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim()) + { + //If we are within range melee the target + if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) + { + if( m_creature->isAttackReady() ) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } +} + +void ScriptedAI::EnterEvadeMode() +{ + if( m_creature->isAlive() ) + DoGoHome(); +} + +void ScriptedAI::DoStartAttack(Unit* victim) +{ + if( m_creature->Attack(victim, true) ) + m_creature->GetMotionMaster()->MoveChase(victim); +} + +void ScriptedAI::DoStopAttack() +{ + if( m_creature->getVictim() != NULL ) + { + m_creature->AttackStop(); + } +} + +void ScriptedAI::DoGoHome() +{ + if( !m_creature->getVictim() && m_creature->isAlive() ) + m_creature->GetMotionMaster()->MoveTargetedHome(); +} diff --git a/src/bindings/universal/ScriptMgr.h b/src/bindings/universal/ScriptMgr.h new file mode 100644 index 000000000..f48986069 --- /dev/null +++ b/src/bindings/universal/ScriptMgr.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SCRIPTMGR_H +#define SCRIPTMGR_H + +//Only required includes +#include "../../game/CreatureAI.h" +#include "../../game/Creature.h" +#include "../../game/InstanceData.h" + +class Player; +class Creature; +class Quest; +class Item; +class GameObject; +class SpellCastTargets; +class Map; + +#define MAX_SCRIPTS 1000 +#define MAX_INSTANCE_SCRIPTS 1000 + +struct Script +{ + Script() : + pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL), + pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL), + pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL), + pGOChooseReward(NULL), pReceiveEmote(NULL), pItemUse(NULL), GetAI(NULL) + {} + + std::string Name; + + // -- Quest/gossip Methods to be scripted -- + bool (*pGossipHello )(Player *player, Creature *_Creature); + bool (*pQuestAccept )(Player *player, Creature *_Creature, Quest const*_Quest ); + bool (*pGossipSelect )(Player *player, Creature *_Creature, uint32 sender, uint32 action ); + bool (*pGossipSelectWithCode)(Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ); + bool (*pQuestSelect )(Player *player, Creature *_Creature, Quest const*_Quest ); + bool (*pQuestComplete )(Player *player, Creature *_Creature, Quest const*_Quest ); + uint32 (*pNPCDialogStatus )(Player *player, Creature *_Creature ); + uint32 (*pGODialogStatus )(Player *player, GameObject * _GO ); + bool (*pChooseReward )(Player *player, Creature *_Creature, Quest const*_Quest, uint32 opt ); + bool (*pItemHello )(Player *player, Item *_Item, Quest const*_Quest ); + bool (*pGOHello )(Player *player, GameObject *_GO ); + bool (*pAreaTrigger )(Player *player, AreaTriggerEntry* at); + bool (*pItemQuestAccept )(Player *player, Item *_Item, Quest const*_Quest ); + bool (*pGOQuestAccept )(Player *player, GameObject *_GO, Quest const*_Quest ); + bool (*pGOChooseReward )(Player *player, GameObject *_GO, Quest const*_Quest, uint32 opt ); + bool (*pReceiveEmote )(Player *player, Creature *_Creature, uint32 emote ); + bool (*pItemUse )(Player *player, Item* _Item, SpellCastTargets const& targets); + + CreatureAI* (*GetAI)(Creature *_Creature); + // ----------------------------------------- + +}; + +class InstanceDataScript +{ + public: + InstanceDataScript() : GetInstanceData(NULL) {}; + + std::string name; + InstanceData* (*GetInstanceData)(Map *_Map); +}; + +extern int nrscripts; +extern Script *m_scripts[MAX_SCRIPTS]; +extern InstanceDataScript *m_instance_scripts[MAX_INSTANCE_SCRIPTS]; +extern int num_inst_scripts; + +#define VISIBLE_RANGE (50.0f) + +struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI +{ + ScriptedAI(Creature* creature) : m_creature(creature) {} + ~ScriptedAI() {} + + // Called if IsVisible(Unit *who) is true at each *who move + void MoveInLineOfSight(Unit *) {} + + // Called at each attack of m_creature by any victim + void AttackStart(Unit *) {} + + // Called at stopping attack by any attacker + void EnterEvadeMode(); + + // Called at any heal cast/item used (call non implemented) + void HealBy(Unit* /*healer*/, uint32 /*amount_healed*/) {} + + // Called at any Damage to any victim (before damage apply) + void DamageDeal(Unit* /*done_to*/, uint32& /*damage*/) {} + + // Called at any Damage from any attacker (before damage apply) + void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) {} + + // Is unit visible for MoveInLineOfSight + bool IsVisible(Unit* who) const + { + return !who->HasStealthAura() && m_creature->GetDistance(who) <= VISIBLE_RANGE; + } + + // Called at World update tick + void UpdateAI(const uint32); + + // Called when the creature is killed + void JustDied(Unit *){} + + // Called when the creature kills a unit + void KilledUnit(Unit *){} + + // Called when hit by a spell + void SpellHit(Unit *, const SpellEntry*){} + + Creature* m_creature; + + //= Some useful helpers ========================= + + // Start attack of victim and go to him + void DoStartAttack(Unit* victim); + + // Stop attack of current victim + void DoStopAttack(); + + // Cast spell + void DoCast(Unit* victim, uint32 spelId) + { + m_creature->CastSpell(victim,spelId,true); + } + + void DoCastSpell(Unit* who,SpellEntry *spellInfo) + { + m_creature->CastSpell(who,spellInfo,true); + } + + void DoSay(char const* text, uint32 language) + { + m_creature->Say(text,language,0); + } + + void DoGoHome(); +}; + +#endif diff --git a/src/bindings/universal/Scripts/sc_default.cpp b/src/bindings/universal/Scripts/sc_default.cpp new file mode 100644 index 000000000..b01372d51 --- /dev/null +++ b/src/bindings/universal/Scripts/sc_default.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "sc_defines.h" + +bool GossipHello_default(Player* /*player*/, Creature* /*_Creature*/) +{ + return false; +} + +bool GossipSelect_default(Player* /*player*/, Creature* /*_Creature*/, uint32 /*sender*/, uint32 /*action*/ ) +{ + return false; +} + +bool GossipSelectWithCode_default( Player* /*player*/, Creature* /*_Creature*/, uint32 /*sender*/, uint32 /*action*/, const char* /*sCode*/ ) +{ + return false; +} + +bool QuestAccept_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ ) +{ + return false; +} + +bool QuestSelect_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ ) +{ + return false; +} + +bool QuestComplete_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ ) +{ + return false; +} + +bool ChooseReward_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/, uint32 /*opt*/ ) +{ + return false; +} + +uint32 NPCDialogStatus_default(Player* /*player*/, Creature* /*_Creature*/ ) +{ + return 128; +} + +uint32 GODialogStatus_default(Player* /*player*/, GameObject* /*_Creature*/ ) +{ + return 128; +} + +bool ItemHello_default(Player* /*player*/, Item* /*_Item*/, Quest const* /*_Quest*/ ) +{ + return false; +} + +bool ItemQuestAccept_default(Player* /*player*/, Item* /*_Item*/, Quest const* /*_Quest*/ ) +{ + return false; +} + +bool GOHello_default(Player* /*player*/, GameObject* /*_GO*/ ) +{ + return false; +} + +bool GOQuestAccept_default(Player* /*player*/, GameObject* /*_GO*/, Quest const* /*_Quest*/ ) +{ + return false; +} + +bool GOChooseReward_default(Player* /*player*/, GameObject* /*_GO*/, Quest const* /*_Quest*/, uint32 /*opt*/ ) +{ + return false; +} + +bool AreaTrigger_default(Player* /*player*/, AreaTriggerEntry* /*atEntry*/ ) +{ + return false; +} + +void AddSC_default() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="default"; + newscript->pGossipHello = &GossipHello_default; + newscript->pQuestAccept = &QuestAccept_default; + newscript->pGossipSelect = &GossipSelect_default; + newscript->pGossipSelectWithCode = &GossipSelectWithCode_default; + newscript->pQuestSelect = &QuestSelect_default; + newscript->pQuestComplete = &QuestComplete_default; + newscript->pNPCDialogStatus = &NPCDialogStatus_default; + newscript->pGODialogStatus = &GODialogStatus_default; + newscript->pChooseReward = &ChooseReward_default; + newscript->pItemHello = &ItemHello_default; + newscript->pGOHello = &GOHello_default; + newscript->pAreaTrigger = &AreaTrigger_default; + newscript->pItemQuestAccept = &ItemQuestAccept_default; + newscript->pGOQuestAccept = &GOQuestAccept_default; + newscript->pGOChooseReward = &GOChooseReward_default; + + m_scripts[nrscripts++] = newscript; +} diff --git a/src/bindings/universal/Scripts/sc_defines.cpp b/src/bindings/universal/Scripts/sc_defines.cpp new file mode 100644 index 000000000..3ed91db28 --- /dev/null +++ b/src/bindings/universal/Scripts/sc_defines.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "sc_defines.h" + +#include "../../game/Player.h" + +uint32 GetSkillLevel(Player *player,uint32 trskill) +{ + // Returns the level of some tradetrskill known by player + // Need to add missing spells + + uint32 spell_apprentice = 0; + uint32 spell_journeyman = 0; + uint32 spell_expert = 0; + uint32 spell_artisan = 0; + uint32 spell_master = 0; + + switch(trskill) + { + case TRADESKILL_ALCHEMY: + spell_apprentice = 2259; + spell_journeyman = 3101; + spell_expert = 3464; + spell_artisan = 11611; + spell_master = 28596; // teached by 28597 + break; + case TRADESKILL_BLACKSMITHING: + spell_apprentice = 2018; + spell_journeyman = 3100; + spell_expert = 8768; + spell_artisan = 11454; + spell_master = 29844; // teached by 29845 + break; + case TRADESKILL_COOKING: + spell_apprentice = 2550; + spell_journeyman = 3102; + spell_expert = 3413; + spell_artisan = 18260; + spell_master = 33359; // teached by 33361 + break; + case TRADESKILL_ENCHANTING: + spell_apprentice = 7411; + spell_journeyman = 7412; + spell_expert = 7413; + spell_artisan = 13920; + spell_master = 28029; // teached by 28030 + break; + case TRADESKILL_ENGINEERING: + spell_apprentice = 4036; + spell_journeyman = 4037; + spell_expert = 4038; + spell_artisan = 12656; + spell_master = 30350; // teached by 30351 + break; + case TRADESKILL_FIRSTAID: + spell_apprentice = 3273; + spell_journeyman = 3274; + spell_expert = 7924; + spell_artisan = 10846; + spell_master = 27028; // teached by 27029 + break; + case TRADESKILL_HERBALISM: + spell_apprentice = 2372; + spell_journeyman = 2373; + spell_expert = 3571; + spell_artisan = 11994; + spell_master = 0; + break; + case TRADESKILL_LEATHERWORKING: + spell_apprentice = 2108; + spell_journeyman = 3104; + spell_expert = 20649; + spell_artisan = 10662; + spell_master = 32549; // teached by 32550 + break; + case TRADESKILL_POISONS: + spell_apprentice = 0; + spell_journeyman = 0; + spell_expert = 0; + spell_artisan = 0; + spell_master = 0; + break; + case TRADESKILL_TAILORING: + spell_apprentice = 3908; + spell_journeyman = 3909; + spell_expert = 3910; + spell_artisan = 12180; + spell_master = 26790; // teached by 26791 + break; + case TRADESKILL_MINING: + spell_apprentice = 2581; + spell_journeyman = 2582; + spell_expert = 3568; + spell_artisan = 10249; + spell_master = 29354; // teached by 29355 + break; + case TRADESKILL_FISHING: + spell_apprentice = 7733; + spell_journeyman = 7734; + spell_expert = 7736; + spell_artisan = 18249; + spell_master = 33098; // teached by 33100 + break; + case TRADESKILL_SKINNING: + spell_apprentice = 8615; + spell_journeyman = 8619; + spell_expert = 8620; + spell_artisan = 10769; + spell_master = 32679; // teached by 32678 + break; + case TRADESKILL_JEWELCRAFTING: + spell_apprentice = 25229; // teached by 25245 + spell_journeyman = 25230; // teached by 25246 + spell_expert = 28894; // teached by 28896 + spell_artisan = 28895; // teached by 28899 + spell_master = 28897; // teached by 28901 + break; + } + + if (player->HasSpell(spell_master)) + return TRADESKILL_LEVEL_MASTER; + + if (player->HasSpell(spell_artisan)) + return TRADESKILL_LEVEL_ARTISAN; + + if (player->HasSpell(spell_expert)) + return TRADESKILL_LEVEL_EXPERT; + + if (player->HasSpell(spell_journeyman)) + return TRADESKILL_LEVEL_JOURNEYMAN; + + if (player->HasSpell(spell_apprentice)) + return TRADESKILL_LEVEL_APPRENTICE; + + return TRADESKILL_LEVEL_NONE; +} diff --git a/src/bindings/universal/Scripts/sc_defines.h b/src/bindings/universal/Scripts/sc_defines.h new file mode 100644 index 000000000..deb265239 --- /dev/null +++ b/src/bindings/universal/Scripts/sc_defines.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SC_DEFINES_H +#define SC_DEFINES_H + +#include "../ScriptMgr.h" + +// Skill defines + +#define TRADESKILL_ALCHEMY 1 +#define TRADESKILL_BLACKSMITHING 2 +#define TRADESKILL_COOKING 3 +#define TRADESKILL_ENCHANTING 4 +#define TRADESKILL_ENGINEERING 5 +#define TRADESKILL_FIRSTAID 6 +#define TRADESKILL_HERBALISM 7 +#define TRADESKILL_LEATHERWORKING 8 +#define TRADESKILL_POISONS 9 +#define TRADESKILL_TAILORING 10 +#define TRADESKILL_MINING 11 +#define TRADESKILL_FISHING 12 +#define TRADESKILL_SKINNING 13 +#define TRADESKILL_JEWELCRAFTING 14 + +#define TRADESKILL_LEVEL_NONE 0 +#define TRADESKILL_LEVEL_APPRENTICE 1 +#define TRADESKILL_LEVEL_JOURNEYMAN 2 +#define TRADESKILL_LEVEL_EXPERT 3 +#define TRADESKILL_LEVEL_ARTISAN 4 +#define TRADESKILL_LEVEL_MASTER 5 + +// Gossip defines + +#define GOSSIP_ACTION_TRADE 1 +#define GOSSIP_ACTION_TRAIN 2 +#define GOSSIP_ACTION_TAXI 3 +#define GOSSIP_ACTION_GUILD 4 +#define GOSSIP_ACTION_BATTLE 5 +#define GOSSIP_ACTION_BANK 6 +#define GOSSIP_ACTION_INN 7 +#define GOSSIP_ACTION_HEAL 8 +#define GOSSIP_ACTION_TABARD 9 +#define GOSSIP_ACTION_AUCTION 10 +#define GOSSIP_ACTION_INN_INFO 11 +#define GOSSIP_ACTION_UNLEARN 12 +#define GOSSIP_ACTION_INFO_DEF 1000 + +#define GOSSIP_SENDER_MAIN 1 +#define GOSSIP_SENDER_INN_INFO 2 +#define GOSSIP_SENDER_INFO 3 +#define GOSSIP_SENDER_SEC_PROFTRAIN 4 +#define GOSSIP_SENDER_SEC_CLASSTRAIN 5 +#define GOSSIP_SENDER_SEC_BATTLEINFO 6 + +#define DEFAULT_GOSSIP_MESSAGE 0xffffff + +extern uint32 GetSkillLevel(Player *player,uint32 skill); + +// Defined functions to use with player. + +#define ADD_GOSSIP_ITEM(a,b,c,d,e,f) PlayerTalkClass->GetGossipMenu()->AddMenuItem(a,b,c,d,e,f) +#define SEND_GOSSIP_MENU(a,b) PlayerTalkClass->SendGossipMenu(a,b) +#define SEND_POI(a,b,c,d,e,f) PlayerTalkClass->SendPointOfInterest(a,b,c,d,e,f) +#define CLOSE_GOSSIP_MENU() PlayerTalkClass->CloseGossip(); + +#define QUEST_DIALOG_STATUS(a,b,c) GetSession()->getDialogStatus(a,b,c) +#define SEND_QUEST_DETAILS(a,b,c) PlayerTalkClass->SendQuestDetails(a,b,c) +#define SEND_REQUESTEDITEMS(a,b,c,d) PlayerTalkClass->SendRequestedItems(a,b,c,d) + +#define SEND_VENDORLIST(a) GetSession()->SendListInventory(a) +#define SEND_TRAINERLIST(a) GetSession()->SendTrainerList(a) +#define SEND_BANKERLIST(a) GetSession()->SendShowBank(a) +#define SEND_TABARDLIST(a) GetSession()->SendTabardVendorActivate(a) +#define SEND_AUCTIONLIST(a) GetSession()->SendAuctionHello(a) +#define SEND_TAXILIST(a) GetSession()->SendTaxiStatus(a) +#define SEND_SPRESURRECT() GetSession()->SendSpiritResurrect() +#define GET_HONORRANK() GetHonorRank() + +// ----------------------------------- +#endif diff --git a/src/bindings/universal/system.cpp b/src/bindings/universal/system.cpp new file mode 100644 index 000000000..f15a11766 --- /dev/null +++ b/src/bindings/universal/system.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef WIN32 +#include +BOOL APIENTRY DllMain( HANDLE /*hModule*/, DWORD /*ul_reason_for_call*/, LPVOID /*lpReserved*/) +{ + return true; +} +#endif diff --git a/src/framework/Dynamic/FactoryHolder.h b/src/framework/Dynamic/FactoryHolder.h new file mode 100644 index 000000000..6455af68c --- /dev/null +++ b/src/framework/Dynamic/FactoryHolder.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_FACTORY_HOLDER +#define MANGOS_FACTORY_HOLDER + +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include "ObjectRegistry.h" +#include "Policies/SingletonImp.h" + +/** FactoryHolder holds a factory object of a specific type + */ +template +class MANGOS_DLL_DECL FactoryHolder +{ + public: + typedef ObjectRegistry, Key > FactoryHolderRegistry; + typedef MaNGOS::Singleton FactoryHolderRepository; + + FactoryHolder(Key k) : i_key(k) {} + virtual ~FactoryHolder() {} + inline Key key() const { return i_key; } + + void RegisterSelf(void) { FactoryHolderRepository::Instance().InsertItem(this, i_key); } + void DeregisterSelf(void) { FactoryHolderRepository::Instance().RemoveItem(this, false); } + + /// Abstract Factory create method + virtual T* Create(void *data = NULL) const = 0; + private: + Key i_key; +}; + +/** Permissible is a classic way of letting the object decide + * whether how good they handle things. This is not retricted + * to factory selectors. + */ +template +class Permissible +{ + public: + virtual ~Permissible() {} + virtual int Permit(const T *) const = 0; +}; +#endif diff --git a/src/framework/Dynamic/ObjectRegistry.h b/src/framework/Dynamic/ObjectRegistry.h new file mode 100644 index 000000000..f975ec6dd --- /dev/null +++ b/src/framework/Dynamic/ObjectRegistry.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_OBJECTREGISTRY_H +#define MANGOS_OBJECTREGISTRY_H + +#include "Platform/Define.h" +#include "Utilities/HashMap.h" +#include "Policies/Singleton.h" + +#include +#include + +/** ObjectRegistry holds all registry item of the same type + */ +template +class MANGOS_DLL_DECL ObjectRegistry +{ + public: + typedef std::map RegistryMapType; + + /// Returns a registry item + const T* GetRegistryItem(Key key) const + { + typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key); + return( iter == i_registeredObjects.end() ? NULL : iter->second ); + } + + /// Inserts a registry item + bool InsertItem(T *obj, Key key, bool override = false) + { + typename RegistryMapType::iterator iter = i_registeredObjects.find(key); + if( iter != i_registeredObjects.end() ) + { + if( !override ) + return false; + delete iter->second; + i_registeredObjects.erase(iter); + } + + i_registeredObjects[key] = obj; + return true; + } + + /// Removes a registry item + void RemoveItem(Key key, bool delete_object = true) + { + typename RegistryMapType::iterator iter = i_registeredObjects.find(key); + if( iter != i_registeredObjects.end() ) + { + if( delete_object ) + delete iter->second; + i_registeredObjects.erase(iter); + } + } + + /// Returns true if registry contains an item + bool HasItem(Key key) const + { + return (i_registeredObjects.find(key) != i_registeredObjects.end()); + } + + /// Inefficiently return a vector of registered items + unsigned int GetRegisteredItems(std::vector &l) const + { + unsigned int sz = l.size(); + l.resize(sz + i_registeredObjects.size()); + for(typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter) + l[sz++] = iter->first; + return i_registeredObjects.size(); + } + + /// Return the map of registered items + RegistryMapType const &GetRegisteredItems() const + { + return i_registeredObjects; + } + + private: + RegistryMapType i_registeredObjects; + friend class MaNGOS::OperatorNew >; + + // protected for friend use since it should be a singleton + ObjectRegistry() {} + ~ObjectRegistry() + { + for(typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter) + delete iter->second; + i_registeredObjects.clear(); + } +}; +#endif diff --git a/src/framework/GameSystem/Grid.h b/src/framework/GameSystem/Grid.h new file mode 100644 index 000000000..8379f1a20 --- /dev/null +++ b/src/framework/GameSystem/Grid.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRID_H +#define MANGOS_GRID_H + +/* + @class Grid + Grid is a logical segment of the game world represented inside MaNGOS. + Grid is bind at compile time to a particular type of object which + we call it the object of interested. There are many types of loader, + specially, dynamic loader, static loader, or on-demand loader. There's + a subtle difference between dynamic loader and on-demand loader but + this is implementation specific to the loader class. From the + Grid's perspective, the loader meets its API requirement is suffice. +*/ + +#include "Platform/Define.h" +#include "Policies/ThreadingModel.h" +#include "TypeContainer.h" +#include "TypeContainerVisitor.h" + +// forward declaration +template class GridLoader; + +template +< +class ACTIVE_OBJECT, +class WORLD_OBJECT_TYPES, +class GRID_OBJECT_TYPES, +class ThreadModel = MaNGOS::SingleThreaded +> +class MANGOS_DLL_DECL Grid +{ + // allows the GridLoader to access its internals + template friend class GridLoader; + public: + + /** destructor to clean up its resources. This includes unloading the + grid if it has not been unload. + */ + ~Grid() {} + + /** an object of interested enters the grid + */ + template bool AddWorldObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_objects.template insert(hdl, obj); + } + + /** an object of interested exits the grid + */ + template bool RemoveWorldObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_objects.template remove(obj, hdl); + } + + /** Accessors: Returns a specific type of object in the WORDL_OBJECT_TYPES + */ + template const SPECIFIC_OBJECT* GetWorldObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT* fake) const { return i_objects.template find(hdl); } + template SPECIFIC_OBJECT* GetWorldObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT *fake) { return i_objects.template find(hdl, fake); } + + /** Refreshes/update the grid. This required for remote grids. + */ + void RefreshGrid(void) { /* TBI */} + + /** Locks a grid. Any object enters must wait until the grid is unlock. + */ + void LockGrid(void) { /* TBI */ } + + /** Unlocks the grid. + */ + void UnlockGrid(void) { /* TBI */ } + + /** Grid visitor for grid objects + */ + template void Visit(TypeContainerVisitor > &visitor) + { + visitor.Visit(i_container); + } + + /** Grid visitor for world objects + */ + template void Visit(TypeContainerVisitor > &visitor) + { + visitor.Visit(i_objects); + } + + /** Returns the number of object within the grid. + */ + unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count(); } + + /** Accessors: Returns a specific type of object in the GRID_OBJECT_TYPES + */ + template const SPECIFIC_OBJECT* GetGridObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT *fake) const { return i_container.template find(hdl, fake); } + template SPECIFIC_OBJECT* GetGridObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT *fake) { return i_container.template find(hdl, fake); } + + /** Inserts a container type object into the grid. + */ + template bool AddGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template insert(hdl, obj); } + + /** Removes a containter type object from the grid + */ + template bool RemoveGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template remove(obj, hdl); } + + private: + + typedef typename ThreadModel::Lock Guard; + typedef typename ThreadModel::VolatileType VolatileType; + + TypeMapContainer i_container; + TypeMapContainer i_objects; +}; +#endif diff --git a/src/framework/GameSystem/GridLoader.h b/src/framework/GameSystem/GridLoader.h new file mode 100644 index 000000000..1aa1af06a --- /dev/null +++ b/src/framework/GameSystem/GridLoader.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRIDLOADER_H +#define MANGOS_GRIDLOADER_H + +/** + @class GridLoader + The GridLoader is working in conjuction with the Grid and responsible + for loading and unloading object-types (one or more) when objects + enters a grid. Unloading is scheduled and might be canceled if + an interested object re-enters. GridLoader does not do the actuall + loading and unloading but implements as a template pattern that + delicate its loading and unloading for the actualy loader and unloader. + GridLoader manages the grid (both local and remote). + */ + +#include "Platform/Define.h" +#include "Grid.h" +#include "TypeContainerVisitor.h" + +template +< +class ACTIVE_OBJECT, +class WORLD_OBJECT_TYPES, +class GRID_OBJECT_TYPES +> +class MANGOS_DLL_DECL GridLoader +{ + public: + + /** Loads the grid + */ + template + void Load(Grid &grid, LOADER &loader) + { + grid.LockGrid(); + loader.Load(grid); + grid.UnlockGrid(); + } + + /** Stop the grid + */ + template + void Stop(Grid &grid, STOPER &stoper) + { + grid.LockGrid(); + stoper.Stop(grid); + grid.UnlockGrid(); + } + /** Unloads the grid + */ + template + void Unload(Grid &grid, UNLOADER &unloader) + { + grid.LockGrid(); + unloader.Unload(grid); + grid.UnlockGrid(); + } +}; +#endif diff --git a/src/framework/GameSystem/GridRefManager.h b/src/framework/GameSystem/GridRefManager.h new file mode 100644 index 000000000..f1e3bf6b5 --- /dev/null +++ b/src/framework/GameSystem/GridRefManager.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GRIDREFMANAGER +#define _GRIDREFMANAGER + +#include "Utilities/LinkedReference/RefManager.h" + +template +class GridReference; + +template +class GridRefManager : public RefManager, OBJECT> +{ + public: + typedef LinkedListHead::Iterator< GridReference > iterator; + + GridReference* getFirst() { return (GridReference*)RefManager, OBJECT>::getFirst(); } + GridReference* getLast() { return (GridReference*)RefManager, OBJECT>::getLast(); } + + iterator begin() { return iterator(getFirst()); } + iterator end() { return iterator(NULL); } + iterator rbegin() { return iterator(getLast()); } + iterator rend() { return iterator(NULL); } +}; +#endif diff --git a/src/framework/GameSystem/GridReference.h b/src/framework/GameSystem/GridReference.h new file mode 100644 index 000000000..df491d3d9 --- /dev/null +++ b/src/framework/GameSystem/GridReference.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GRIDREFERENCE_H +#define _GRIDREFERENCE_H + +#include "Utilities/LinkedReference/Reference.h" + +template +class GridRefManager; + +template +class MANGOS_DLL_SPEC GridReference : public Reference, OBJECT> +{ + protected: + void targetObjectBuildLink() + { + // called from link() + this->getTarget()->insertFirst(this); + this->getTarget()->incSize(); + } + void targetObjectDestroyLink() + { + // called from unlink() + if(this->isValid()) this->getTarget()->decSize(); + } + void sourceObjectDestroyLink() + { + // called from invalidate() + this->getTarget()->decSize(); + } + public: + GridReference() : Reference, OBJECT>() {} + ~GridReference() { this->unlink(); } + GridReference *next() { return (GridReference*)Reference, OBJECT>::next(); } +}; +#endif diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h new file mode 100644 index 000000000..569d2312f --- /dev/null +++ b/src/framework/GameSystem/NGrid.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_NGRID_H +#define MANGOS_NGRID_H + +/** NGrid is nothing more than a wrapper of the Grid with an NxN cells + */ + +#include "GameSystem/Grid.h" +#include "GameSystem/GridReference.h" +#include "Timer.h" + +class GridInfo +{ +public: + GridInfo() : i_timer(0) {} + GridInfo(time_t expiry, bool unload = true ) : i_timer(expiry), i_unloadflag(unload) {} + const TimeTracker& getTimeTracker() const { return i_timer; } + bool getUnloadFlag() const { return i_unloadflag; } + void setUnloadFlag( bool pFlag) { i_unloadflag = pFlag; } + void setTimer(const TimeTracker& pTimer) { i_timer = pTimer; } + void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); } + void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); } + +private: + TimeTracker i_timer; + bool i_unloadflag; +}; + +typedef enum +{ + GRID_STATE_INVALID = 0, + GRID_STATE_ACTIVE = 1, + GRID_STATE_IDLE = 2, + GRID_STATE_REMOVAL= 3, + MAX_GRID_STATE = 4 +} grid_state_t; + +template +< +unsigned int N, +class ACTIVE_OBJECT, +class WORLD_OBJECT_TYPES, +class GRID_OBJECT_TYPES, +class ThreadModel = MaNGOS::SingleThreaded +> +class MANGOS_DLL_DECL NGrid +{ + public: + + typedef Grid GridType; + NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true) : + i_gridId(id), i_cellstate(GRID_STATE_INVALID), i_x(x), i_y(y), i_GridObjectDataLoaded(false) + { + i_GridInfo = GridInfo(expiry, unload); + } + + const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; } + GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; } + + inline const uint32& GetGridId(void) const { return i_gridId; } + inline void SetGridId(const uint32 id) const { i_gridId = id; } + inline grid_state_t GetGridState(void) const { return i_cellstate; } + inline void SetGridState(grid_state_t s) { i_cellstate = s; } + inline int32 getX() const { return i_x; } + inline int32 getY() const { return i_y; } + + void link(GridRefManager >* pTo) + { + i_Reference.link(pTo, this); + } + bool isGridObjectDataLoaded() const { return i_GridObjectDataLoaded; } + void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; } + + GridInfo* getGridInfoRef() { return &i_GridInfo; } + const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); } + bool getUnloadFlag() const { return i_GridInfo.getUnloadFlag(); } + void setUnloadFlag( bool pFlag) { i_GridInfo.setUnloadFlag(pFlag); } + void ResetTimeTracker(time_t interval) { i_GridInfo.ResetTimeTracker(interval); } + void UpdateTimeTracker(time_t diff) { i_GridInfo.UpdateTimeTracker(diff); } + + template void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + i_cells[x][y].AddWorldObject(obj, hdl); + } + + template void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + i_cells[x][y].RemoveWorldObject(obj, hdl); + } + + template void Visit(TypeContainerVisitor > &visitor) + { + for(unsigned int x=0; x < N; ++x) + for(unsigned int y=0; y < N; ++y) + i_cells[x][y].Visit(visitor); + } + + template void Visit(const uint32 &x, const uint32 &y, TypeContainerVisitor > &visitor) + { + i_cells[x][y].Visit(visitor); + } + + unsigned int ActiveObjectsInGrid(void) const + { + unsigned int count=0; + for(unsigned int x=0; x < N; ++x) + for(unsigned int y=0; y < N; ++y) + count += i_cells[x][y].ActiveObjectsInGrid(); + return count; + } + + template const SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) const + { + return i_cells[x][y].template GetGridObject(hdl); + } + + template SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) + { + return i_cells[x][y].template GetGridObject(hdl); + } + + template bool AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_cells[x][y].AddGridObject(hdl, obj); + } + + template bool RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_cells[x][y].RemoveGridObject(obj, hdl); + } + + private: + + uint32 i_gridId; + GridInfo i_GridInfo; + GridReference > i_Reference; + int32 i_x; + int32 i_y; + grid_state_t i_cellstate; + GridType i_cells[N][N]; + bool i_GridObjectDataLoaded; +}; +#endif diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h new file mode 100644 index 000000000..685b80640 --- /dev/null +++ b/src/framework/GameSystem/TypeContainer.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_TYPECONTAINER_H +#define MANGOS_TYPECONTAINER_H + +/* + * Here, you'll find a series of containers that allow you to hold multiple + * types of object at the same time. + */ + +#include +#include +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include "GameSystem/GridRefManager.h" + +/* + * @class ContainerMapList is a mulit-type container for map elements + * By itself its meaningless but collaborate along with TypeContainers, + * it become the most powerfully container in the whole system. + */ +template struct ContainerMapList +{ + //std::map _element; + GridRefManager _element; +}; + +template<> struct ContainerMapList /* nothing is in type null */ +{ +}; +template struct ContainerMapList > +{ + ContainerMapList _elements; + ContainerMapList _TailElements; +}; + +/* + * @class ContaierArrayList is a multi-type container for + * array of elements. + */ +template struct ContainerArrayList +{ + std::vector _element; +}; + +// termination condition +template<> struct ContainerArrayList {}; +// recursion +template struct ContainerArrayList > +{ + ContainerArrayList _elements; + ContainerArrayList _TailElements; +}; + +/* + * @class ContainerList is a simple list of different types of elements + * + */ +template struct ContainerList +{ + OBJECT _element; +}; + +/* TypeNull is underfined */ +template<> struct ContainerList {}; +template struct ContainerList > +{ + ContainerList _elements; + ContainerMapList _TailElements; +}; + +#include "TypeContainerFunctions.h" + +/* + * @class TypeMapContainer contains a fixed number of types and is + * determined at compile time. This is probably the most complicated + * class and do its simplest thing, that is, holds objects + * of different types. + */ + +template +class MANGOS_DLL_DECL TypeMapContainer +{ + public: + template size_t Count() const { return MaNGOS::Count(i_elements, (SPECIFIC_TYPE*)NULL); } + + template SPECIFIC_TYPE* find(OBJECT_HANDLE hdl, SPECIFIC_TYPE *fake) { return MaNGOS::Find(i_elements, hdl,fake); } + + /// find a specific type of object in the container + template const SPECIFIC_TYPE* find(OBJECT_HANDLE hdl, SPECIFIC_TYPE *fake) const { return MaNGOS::Find(i_elements, hdl,fake); } + + /// inserts a specific object into the container + template bool insert(OBJECT_HANDLE hdl, SPECIFIC_TYPE *obj) + { + SPECIFIC_TYPE* t = MaNGOS::Insert(i_elements, obj, hdl); + return (t != NULL); + } + + /// Removes the object from the container, and returns the removed object + template bool remove(SPECIFIC_TYPE* obj, OBJECT_HANDLE hdl) + { + SPECIFIC_TYPE* t = MaNGOS::Remove(i_elements, obj, hdl); + return (t != NULL); + } + + ContainerMapList & GetElements(void) { return i_elements; } + const ContainerMapList & GetElements(void) const { return i_elements;} + + private: + ContainerMapList i_elements; +}; +#endif diff --git a/src/framework/GameSystem/TypeContainerFunctions.h b/src/framework/GameSystem/TypeContainerFunctions.h new file mode 100644 index 000000000..1dd7c7a0a --- /dev/null +++ b/src/framework/GameSystem/TypeContainerFunctions.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TYPECONTAINER_FUNCTIONS_H +#define TYPECONTAINER_FUNCTIONS_H + +/* + * Here you'll find a list of helper functions to make + * the TypeContainer usefull. Without it, its hard + * to access or mutate the container. + */ + +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include + +namespace MaNGOS +{ + /* ContainerMapList Helpers */ + // count functions + template size_t Count(const ContainerMapList &elements, SPECIFIC_TYPE* /*fake*/) + { + return elements._element.getSize(); + }; + + template size_t Count(const ContainerMapList &/*elements*/, SPECIFIC_TYPE* /*fake*/) + { + return 0; + } + + template size_t Count(const ContainerMapList &/*elements*/, SPECIFIC_TYPE* /*fake*/) + { + return 0; + } + + template size_t Count(const ContainerMapList >&elements, SPECIFIC_TYPE* fake) + { + return Count(elements._elements,fake); + } + + template size_t Count(const ContainerMapList >&elements, SPECIFIC_TYPE* fake) + { + return Count(elements._TailElements, fake); + } + + // non-const find functions + template SPECIFIC_TYPE* Find(ContainerMapList &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + //typename std::map::iterator iter = elements._element.find(hdl); + //return (iter == elements._element.end() ? NULL : iter->second); + return NULL; + }; + + template SPECIFIC_TYPE* Find(ContainerMapList &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; // terminate recursion + } + + template SPECIFIC_TYPE* Find(ContainerMapList &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; // this is a missed + } + + template SPECIFIC_TYPE* Find(ContainerMapList >&/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + //SPECIFIC_TYPE* t = Find(elements._elements, hdl,fake); + //return (t != NULL ? t :Find(elements._TailElements, hdl,fake)); + return NULL; + } + + // const find functions + template const SPECIFIC_TYPE* Find(const ContainerMapList &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + //typename SPECIFIC_TYPE::iterator iter = elements._element.find(hdl); + //return (iter == elements._element.end() ? NULL : iter->second); + return NULL; + }; + + template const SPECIFIC_TYPE* Find(const ContainerMapList &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; + } + + template const SPECIFIC_TYPE* Find(const ContainerMapList &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; + } + + template SPECIFIC_TYPE* Find(const ContainerMapList >&elements, OBJECT_HANDLE hdl, SPECIFIC_TYPE* fake) + { + SPECIFIC_TYPE* t = Find(elements._elements, hdl,fake); + if( t) + return t; + + return Find(elements._TailElement, hdl,fake); + } + + // non-const insert functions + template SPECIFIC_TYPE* Insert(ContainerMapList &elements, SPECIFIC_TYPE *obj, OBJECT_HANDLE /*hdl*/) + { + //elements._element[hdl] = obj; + obj->GetGridRef().link(&elements._element, obj); + return obj; + }; + + template SPECIFIC_TYPE* Insert(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; + } + + // this is a missed + template SPECIFIC_TYPE* Insert(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; // a missed + } + + // Recursion + template SPECIFIC_TYPE* Insert(ContainerMapList >&elements, SPECIFIC_TYPE *obj, OBJECT_HANDLE hdl) + { + SPECIFIC_TYPE* t= Insert(elements._elements, obj, hdl); + return (t != NULL ? t : Insert(elements._TailElements, obj, hdl)); + } + + // non-const remove method + template SPECIFIC_TYPE* Remove(ContainerMapList & /*elements*/, SPECIFIC_TYPE *obj, OBJECT_HANDLE /*hdl*/) + { + /*typename std::map::iterator iter = elements._element.find(hdl); + if( iter != elements._element.end() ) + { + SPECIFIC_TYPE* t = iter->second; + elements._element.erase(iter); + return t; + }*/ + obj->GetGridRef().unlink(); + return obj; + } + + template SPECIFIC_TYPE* Remove(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; + } + + // this is a missed + template SPECIFIC_TYPE* Remove(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; // a missed + } + + template SPECIFIC_TYPE* Remove(ContainerMapList > &elements, SPECIFIC_TYPE *obj, OBJECT_HANDLE hdl) + { + // The head element is bad + SPECIFIC_TYPE* t = Remove(elements._elements, obj, hdl); + return ( t != NULL ? t : Remove(elements._TailElements, obj, hdl) ); + } + +} +#endif diff --git a/src/framework/GameSystem/TypeContainerFunctionsPtr.h b/src/framework/GameSystem/TypeContainerFunctionsPtr.h new file mode 100644 index 000000000..2076f8e3a --- /dev/null +++ b/src/framework/GameSystem/TypeContainerFunctionsPtr.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TYPECONTAINER_FUNCTIONS_PTR_H +#define TYPECONTAINER_FUNCTIONS_PTR_H + +/* + * Here you'll find a list of helper functions to make + * the TypeContainer usefull. Without it, its hard + * to access or mutate the container. + */ + +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include + +namespace MaNGOS +{ + /* ContainerMapList Helpers */ + // count functions + // template size_t Count(const ContainerMapList &elements, CountedPtr* /*fake*/) + // { + // return elements._element.size(); + // }; + // + // template size_t Count(const ContainerMapList &elements, CountedPtr* /*fake*/) + // { + // return 0; + // } + // + // template size_t Count(const ContainerMapList &elements, CountedPtr* /*fake*/) + // { + // return 0; + // } + // + // template size_t Count(const ContainerMapList >&elements, SPECIFIC_TYPE* fake) + // { + // return Count(elements._elements,fake); + // } + // + // template size_t Count(const ContainerMapList >&elements, SPECIFIC_TYPE* fake) + // { + // return Count(elements._TailElements, fake); + // } + + // non-const find functions + template CountedPtr& Find(ContainerMapList &elements, OBJECT_HANDLE hdl, CountedPtr* /*fake*/) + { + typename std::map >::iterator iter = elements._element.find(hdl); + return (iter == elements._element.end() ? NullPtr((SPECIFIC_TYPE*)NULL) : iter->second); + }; + + template CountedPtr& Find(ContainerMapList &elements, OBJECT_HANDLE hdl, CountedPtr* /*fake*/) + { + return NullPtr((SPECIFIC_TYPE*)NULL);// terminate recursion + } + + template CountedPtr& Find(ContainerMapList &elements, OBJECT_HANDLE hdl, CountedPtr* /*fake*/) + { + return NullPtr((SPECIFIC_TYPE*)NULL);// this is a missed + } + + template CountedPtr& Find(ContainerMapList >&elements, OBJECT_HANDLE hdl, CountedPtr* fake) + { + CountedPtr &t = Find(elements._elements, hdl,fake); + return (!t ? Find(elements._TailElements, hdl,fake) : t); + } + + // const find functions + template const CountedPtr& Find(const ContainerMapList &elements, OBJECT_HANDLE hdl, CountedPtr* /*fake*/) + { + typename CountedPtr::iterator iter = elements._element.find(hdl); + return (iter == elements._element.end() ? NullPtr((SPECIFIC_TYPE*)NULL) : iter->second); + }; + + template const CountedPtr& Find(const ContainerMapList &elements, OBJECT_HANDLE hdl, CountedPtr* /*fake*/) + { + return NullPtr((SPECIFIC_TYPE*)NULL); + } + + template const CountedPtr& Find(const ContainerMapList &elements, OBJECT_HANDLE hdl, CountedPtr* /*fake*/) + { + return NullPtr((SPECIFIC_TYPE*)NULL); + } + + template CountedPtr& Find(const ContainerMapList >&elements, OBJECT_HANDLE hdl, CountedPtr* fake) + { + CountedPtr &t = Find(elements._elements, hdl,fake); + if(!t) + t = Find(elements._TailElement, hdl,fake); + + return t; + } + + // non-const insert functions + template CountedPtr& Insert(ContainerMapList &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + elements._element[hdl] = obj; + return obj; + }; + + template CountedPtr& Insert(ContainerMapList &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + return NullPtr((SPECIFIC_TYPE*)NULL); + } + + // this is a missed + template CountedPtr& Insert(ContainerMapList &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + return NullPtr((SPECIFIC_TYPE*)NULL);// a missed + } + + // Recursion + template CountedPtr& Insert(ContainerMapList >&elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + CountedPtr &t= Insert(elements._elements, obj, hdl); + return (!t ? Insert(elements._TailElements, obj, hdl) : t); + } + + // non-const remove method + template bool Remove(ContainerMapList &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + typename std::map >::iterator iter = elements._element.find(hdl); + if( iter != elements._element.end() ) + { + elements._element.erase(iter); + return true; + } + + return false; // found... terminate the search + } + + template bool Remove(ContainerMapList &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + return false; + } + + // this is a missed + template bool Remove(ContainerMapList &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + return false; + } + + template bool Remove(ContainerMapList > &elements, CountedPtr &obj, OBJECT_HANDLE hdl) + { + // The head element is bad + bool t = Remove(elements._elements, obj, hdl); + return ( !t ? Remove(elements._TailElements, obj, hdl) : t ); + } + +} +#endif diff --git a/src/framework/GameSystem/TypeContainerVisitor.h b/src/framework/GameSystem/TypeContainerVisitor.h new file mode 100644 index 000000000..8f947bdad --- /dev/null +++ b/src/framework/GameSystem/TypeContainerVisitor.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_TYPECONTAINERVISITOR_H +#define MANGOS_TYPECONTAINERVISITOR_H + +/* + * @class TypeContainerVisitor is implemented as a visitor pattern. It is + * a visitor to the TypeContainerList or TypeContainerMapList. The visitor has + * to overload its types as a visit method is called. + */ + +#include "Platform/Define.h" +#include "TypeContainer.h" + +// forward declaration +template class TypeContainerVisitor; + +// visitor helper +template void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c) +{ + v.Visit(c); +}; + +// terminate condition for container list +template void VisitorHelper(VISITOR &v, ContainerList &c) +{ +} + +template void VisitorHelper(VISITOR &v, ContainerList &c) +{ + v.Visit(c._element); +} + +// recursion for container list +template void VisitorHelper(VISITOR &v, ContainerList > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// terminate condition container map list +template void VisitorHelper(VISITOR &/*v*/, ContainerMapList &/*c*/) +{ +} + +template void VisitorHelper(VISITOR &v, ContainerMapList &c) +{ + v.Visit(c._element); +} + +// recursion container map list +template void VisitorHelper(VISITOR &v, ContainerMapList > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// array list +template void VisitorHelper(VISITOR &v, ContainerArrayList &c) +{ + v.Visit(c._element); +} + +template void VisitorHelper(VISITOR &/*v*/, ContainerArrayList &/*c*/) +{ +} + +// recursion +template void VisitorHelper(VISITOR &v, ContainerArrayList > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// for TypeMapContainer +template void VisitorHelper(VISITOR &v, TypeMapContainer &c) +{ + VisitorHelper(v, c.GetElements()); +} + +template +class MANGOS_DLL_DECL TypeContainerVisitor +{ + public: + TypeContainerVisitor(VISITOR &v) : i_visitor(v) {} + + void Visit(TYPE_CONTAINER &c) + { + VisitorHelper(i_visitor, c); + } + + void Visit(const TYPE_CONTAINER &c) const + { + VisitorHelper(i_visitor, c); + } + + private: + VISITOR &i_visitor; +}; +#endif diff --git a/src/framework/Makefile.am b/src/framework/Makefile.am new file mode 100644 index 000000000..66680536b --- /dev/null +++ b/src/framework/Makefile.am @@ -0,0 +1,64 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(srcdir) + +## Build MaNGOS framework library as convenience library. +# libMaNGOSScript shared library will later be reused by world server daemon. +noinst_LIBRARIES = libmangosframework.a +libmangosframework_a_SOURCES = \ + Policies/ObjectLifeTime.cpp \ + Utilities/EventProcessor.cpp + +## Additional files to include when running 'make dist' +# Source and header files for the Framework. +EXTRA_DIST = \ + Dynamic/FactoryHolder.h \ + Dynamic/ObjectRegistry.h \ + GameSystem/Grid.h \ + GameSystem/GridLoader.h \ + GameSystem/GridRefManager.h \ + GameSystem/GridReference.h \ + GameSystem/NGrid.h \ + GameSystem/TypeContainer.h \ + GameSystem/TypeContainerFunctions.h \ + GameSystem/TypeContainerFunctionsPtr.h \ + GameSystem/TypeContainerVisitor.h \ + Network/SocketDefines.h \ + Platform/CompilerDefs.h \ + Platform/Define.h \ + Policies/CreationPolicy.h \ + Policies/ObjectLifeTime.h \ + Policies/Singleton.h \ + Policies/SingletonImp.h \ + Policies/ThreadingModel.h \ + Utilities/CountedReference/Reference.h \ + Utilities/CountedReference/ReferenceHolder.h \ + Utilities/CountedReference/ReferenceImpl.h \ + Utilities/LinkedReference/RefManager.h \ + Utilities/LinkedReference/Reference.h \ + Utilities/ByteConverter.h \ + Utilities/Callback.h \ + Utilities/EventProcessor.h \ + Utilities/HashMap.h \ + Utilities/LinkedList.h \ + Utilities/TypeList.h + diff --git a/src/framework/Network/SocketDefines.h b/src/framework/Network/SocketDefines.h new file mode 100644 index 000000000..495778e0b --- /dev/null +++ b/src/framework/Network/SocketDefines.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_SOCKETDEFINES_H +#define MANGOS_SOCKETDEFINES_H + +#ifdef WIN32 + +/* Windows socket definitions + */ +#define FD_SETSIZE 1024 +#include +#include + +typedef SOCKET SocketHandle; +typedef fd_set SelectSet; + +#else + +/* The unix socket definitions + */ +#include +#include +#ifdef __APPLE_CC__ +#include +#endif + +typedef int SocketHandle; +typedef fd_set SelectSet; +#endif +#endif diff --git a/src/framework/Platform/CompilerDefs.h b/src/framework/Platform/CompilerDefs.h new file mode 100644 index 000000000..6f75205df --- /dev/null +++ b/src/framework/Platform/CompilerDefs.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_COMPILERDEFS_H +#define MANGOS_COMPILERDEFS_H + +#define PLATFORM_WINDOWS 0 +#define PLATFORM_UNIX 1 +#define PLATFORM_APPLE 2 +#define PLATFORM_INTEL 3 + +// must be first (win 64 also define WIN32) +#if defined( _WIN64 ) +# define PLATFORM PLATFORM_WINDOWS +#elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 ) +# define PLATFORM PLATFORM_WINDOWS +#elif defined( __APPLE_CC__ ) +# define PLATFORM PLATFORM_APPLE +#elif defined( __INTEL_COMPILER ) +# define PLATFORM PLATFORM_INTEL +#else +# define PLATFORM PLATFORM_UNIX +#endif + +#define COMPILER_MICROSOFT 0 +#define COMPILER_GNU 1 +#define COMPILER_BORLAND 2 +#define COMPILER_INTEL 3 + +#ifdef _MSC_VER +# define COMPILER COMPILER_MICROSOFT +#elif defined( __BORLANDC__ ) +# define COMPILER COMPILER_BORLAND +#elif defined( __INTEL_COMPILER ) +# define COMPILER COMPILER_INTEL +#elif defined( __GNUC__ ) +# define COMPILER COMPILER_GNU +#else +# pragma error "FATAL ERROR: Unknown compiler." +#endif + +#if COMPILER == COMPILER_MICROSOFT +# pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data +# pragma warning( disable : 4786 ) // identifier was truncated to '255' characters in the debug information +#endif +#endif diff --git a/src/framework/Platform/Define.h b/src/framework/Platform/Define.h new file mode 100644 index 000000000..31435d1e8 --- /dev/null +++ b/src/framework/Platform/Define.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_DEFINE_H +#define MANGOS_DEFINE_H + +#include "Platform/CompilerDefs.h" +#include + +/* Endian detection code from sha2.c: +------------------------------------------------------------------------- +Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. +All rights reserved. + +TERMS + +Redistribution and use in source and binary forms, with or without +modification, are permitted subject to the following conditions: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. The copyright holder's name must not be used to endorse or promote +any products derived from this software without his specific prior +written permission. + +This software is provided 'as is' with no express or implied warranties +of correctness or fitness for purpose. +------------------------------------------------------------------------- +*/ + +/* 1. PLATFORM SPECIFIC INCLUDES */ + +#if defined(__GNU_LIBRARY__) +# include +# include +#elif defined(__CRYPTLIB__) +# if defined( INC_ALL ) +# include "crypt.h" +# elif defined( INC_CHILD ) +# include "../crypt.h" +# else +# include "crypt.h" +# endif +# if defined(DATA_LITTLEENDIAN) +# define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN +# else +# define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN +# endif +#elif defined(_MSC_VER) +# include +#elif !defined(WIN32) +# include +# if !defined (_ENDIAN_H) +# include +# else +# include _ENDIAN_H +# endif +#endif + +/* 2. BYTE ORDER IN 32-BIT WORDS + +To obtain the highest speed on processors with 32-bit words, this code +needs to determine the order in which bytes are packed into such words. +The following block of code is an attempt to capture the most obvious +ways in which various environemnts specify their endian definitions. +It may well fail, in which case the definitions will need to be set by +editing at the points marked **** EDIT HERE IF NECESSARY **** below. +*/ + +#define MANGOS_LITTLEENDIAN 0 +#define MANGOS_BIGENDIAN 1 + +#if !defined(MANGOS_ENDIAN) +# if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN) +# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) +# if defined(BYTE_ORDER) +# if (BYTE_ORDER == LITTLE_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif (BYTE_ORDER == BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# endif +# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN) +# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) +# if defined(_BYTE_ORDER) +# if (_BYTE_ORDER == _LITTLE_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif (_BYTE_ORDER == _BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# endif +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLE_ENDIAN +# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# elif (('1234' >> 24) == '1') +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif (('4321' >> 24) == '1') +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# else +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# endif +#endif + +/* End of Endian detection code from sha2.c: */ + +#if PLATFORM == PLATFORM_WINDOWS +#define MANGOS_EXPORT __declspec(dllexport) +#define MANGOS_LIBRARY_HANDLE HMODULE +#define MANGOS_LOAD_LIBRARY(a) LoadLibrary(a) +#define MANGOS_CLOSE_LIBRARY FreeLibrary +#define MANGOS_GET_PROC_ADDR GetProcAddress +#define MANGOS_IMPORT __cdecl +#define MANGOS_SCRIPT_EXT ".dll" +#define MANGOS_SCRIPT_NAME "MaNGOSScript" +#else +#define MANGOS_LIBRARY_HANDLE void* +#define MANGOS_EXPORT export +#define MANGOS_LOAD_LIBRARY(a) dlopen(a,RTLD_NOW) +#define MANGOS_CLOSE_LIBRARY dlclose +#define MANGOS_GET_PROC_ADDR dlsym + +#if defined(__APPLE_CC__) && defined(BIG_ENDIAN) +#define MANGOS_IMPORT __attribute__ ((longcall)) +#else +#define MANGOS_IMPORT __attribute__ ((cdecl)) +#endif + +#define MANGOS_SCRIPT_EXT ".so" +#define MANGOS_SCRIPT_NAME "libmangosscript" +#endif + +#ifdef WIN32 +#ifdef MANGOS_WIN32_DLL_IMPORT + +#define MANGOS_DLL_DECL __declspec(dllimport) +#else +#ifdef MANGOS_WIND_DLL_EXPORT +#define MANGOS_DLL_DECL __declspec(dllexport) +#else +#define MANGOS_DLL_DECL +#endif +#endif + +#else +#define MANGOS_DLL_DECL +#endif + +#ifndef DEBUG +#define MANGOS_INLINE inline +#else +#ifndef MANGOS_DEBUG +#define MANGOS_DEBUG +#endif +#define MANGOS_INLINE +#endif + +#if COMPILER == COMPILER_MICROSOFT +typedef __int64 int64; +typedef __int32 int32; +typedef __int16 int16; +typedef __int8 int8; +typedef unsigned __int64 uint64; +typedef unsigned __int32 uint32; +typedef unsigned __int16 uint16; +typedef unsigned __int8 uint8; +#else +typedef __int64_t int64; +typedef __int32_t int32; +typedef __int16_t int16; +typedef __int8_t int8; +typedef __uint64_t uint64; +typedef __uint32_t uint32; +typedef __uint16_t uint16; +typedef __uint8_t uint8; +typedef uint16 WORD; +typedef uint32 DWORD; +#endif +typedef uint64 OBJECT_HANDLE; + +#if PLATFORM == PLATFORM_WINDOWS +# define MANGOS_DLL_SPEC __declspec(dllexport) +# ifndef DECLSPEC_NORETURN +# define DECLSPEC_NORETURN __declspec(noreturn) +# endif +#else +# define MANGOS_DLL_SPEC +# define DECLSPEC_NORETURN +#endif + +#if COMPILER == COMPILER_GNU +# define ATTR_NORETURN __attribute__((noreturn)) +# define ATTR_PRINTF(F,V) __attribute__ ((format (printf, F, V))) +#else +# define ATTR_NORETURN +# define ATTR_PRINTF(F,V) +#endif + +#endif diff --git a/src/framework/Policies/CreationPolicy.h b/src/framework/Policies/CreationPolicy.h new file mode 100644 index 000000000..6f187ec99 --- /dev/null +++ b/src/framework/Policies/CreationPolicy.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CREATIONPOLICY_H +#define MANGOS_CREATIONPOLICY_H + +#include +#include "Platform/Define.h" + +namespace MaNGOS +{ + /** + * OperatorNew policy creates an object on the heap using new. + */ + template + class MANGOS_DLL_DECL OperatorNew + { + public: + static T* Create(void) { return (new T); } + static void Destroy(T *obj) { delete obj; } + }; + + /** + * LocalStaticCreation policy creates an object on the stack + * the first time call Create. + */ + template + class MANGOS_DLL_DECL LocalStaticCreation + { + union MaxAlign + { + char t_[sizeof(T)]; + short int shortInt_; + int int_; + long int longInt_; + float float_; + double double_; + long double longDouble_; + struct Test; + int Test::* pMember_; + int (Test::*pMemberFn_)(int); + }; + public: + static T* Create(void) + { + static MaxAlign si_localStatic; + return new(&si_localStatic) T; + } + + static void Destroy(T *obj) { obj->~T(); } + }; + + /** + * CreateUsingMalloc by pass the memory manger. + */ + template + class MANGOS_DLL_DECL CreateUsingMalloc + { + public: + static T* Create() + { + void* p = ::malloc(sizeof(T)); + if (!p) return 0; + return new(p) T; + } + + static void Destroy(T* p) + { + p->~T(); + ::free(p); + } + }; + + /** + * CreateOnCallBack creates the object base on the call back. + */ + template + class MANGOS_DLL_DECL CreateOnCallBack + { + public: + static T* Create() + { + return CALL_BACK::createCallBack(); + } + + static void Destroy(T *p) + { + CALL_BACK::destroyCallBack(p); + } + }; +} +#endif diff --git a/src/framework/Policies/ObjectLifeTime.cpp b/src/framework/Policies/ObjectLifeTime.cpp new file mode 100644 index 000000000..df85f4e41 --- /dev/null +++ b/src/framework/Policies/ObjectLifeTime.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "ObjectLifeTime.h" + +namespace MaNGOS +{ + extern "C" void external_wrapper(void *p) + { + std::atexit( (void (*)())p ); + } + + void MANGOS_DLL_SPEC at_exit( void (*func)() ) + { + external_wrapper((void*)func); + } +} diff --git a/src/framework/Policies/ObjectLifeTime.h b/src/framework/Policies/ObjectLifeTime.h new file mode 100644 index 000000000..f63b05a42 --- /dev/null +++ b/src/framework/Policies/ObjectLifeTime.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_OBJECTLIFETIME_H +#define MANGOS_OBJECTLIFETIME_H + +#include +#include "Platform/Define.h" + +typedef void (* Destroyer)(void); + +namespace MaNGOS +{ + void MANGOS_DLL_SPEC at_exit( void (*func)() ); + + template + class MANGOS_DLL_DECL ObjectLifeTime + { + public: + inline static void ScheduleCall(void (*destroyer)() ) + { + at_exit( destroyer ); + } + + DECLSPEC_NORETURN static void OnDeadReference(void) ATTR_NORETURN; + + }; + + template + inline void ObjectLifeTime::OnDeadReference(void)// We don't handle Dead Reference for now + { + throw std::runtime_error("Dead Reference"); + } +} +#endif diff --git a/src/framework/Policies/Singleton.h b/src/framework/Policies/Singleton.h new file mode 100644 index 000000000..aea45b982 --- /dev/null +++ b/src/framework/Policies/Singleton.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_SINGLETON_H +#define MANGOS_SINGLETON_H + +/** + * @brief class Singleton + */ + +#include "CreationPolicy.h" +#include "ThreadingModel.h" +#include "ObjectLifeTime.h" + +namespace MaNGOS +{ + template + < + typename T, + class ThreadingModel = MaNGOS::SingleThreaded, + class CreatePolicy = MaNGOS::OperatorNew, + class LifeTimePolicy = MaNGOS::ObjectLifeTime + > + class MANGOS_DLL_DECL Singleton + { + public: + static T& Instance(); + + protected: + Singleton() {}; + + private: + + // Prohibited actions...this does not prevent hijacking. + Singleton(const Singleton &); + Singleton& operator=(const Singleton &); + + // Singleton Helpers + static void DestroySingleton(); + + // data structure + typedef typename ThreadingModel::Lock Guard; + static T *si_instance; + static bool si_destroyed; + }; +} +#endif diff --git a/src/framework/Policies/SingletonImp.h b/src/framework/Policies/SingletonImp.h new file mode 100644 index 000000000..da30f5a75 --- /dev/null +++ b/src/framework/Policies/SingletonImp.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_SINGLETONIMPL_H +#define MANGOS_SINGLETONIMPL_H + +#include "Singleton.h" + +// avoid the using namespace here cuz +// its a .h file afterall + +template +< +typename T, +class ThreadingModel, +class CreatePolicy, +class LifeTimePolicy +> +T& +MaNGOS::Singleton::Instance() +{ + if( !si_instance ) + { + // double-checked Locking pattern + Guard(); + if( !si_instance ) + { + if( si_destroyed ) + { + si_destroyed = false; + LifeTimePolicy::OnDeadReference(); + } + si_instance = CreatePolicy::Create(); + LifeTimePolicy::ScheduleCall(&DestroySingleton); + } + } + + return *si_instance; +} + +template +< +typename T, +class ThreadingModel, +class CreatePolicy, +class LifeTimePolicy +> +void +MaNGOS::Singleton::DestroySingleton() +{ + CreatePolicy::Destroy(si_instance); + si_instance = NULL; + si_destroyed = true; +} + +#define INSTANTIATE_SINGLETON_1(TYPE) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton, MaNGOS::OperatorNew, MaNGOS::ObjectLifeTime >; \ + template<> TYPE* MaNGOS::Singleton, MaNGOS::OperatorNew, MaNGOS::ObjectLifeTime >::si_instance = 0; \ + template<> bool MaNGOS::Singleton, MaNGOS::OperatorNew, MaNGOS::ObjectLifeTime >::si_destroyed = false + +#define INSTANTIATE_SINGLETON_2(TYPE, THREADINGMODEL) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton, MaNGOS::ObjectLifeTime >; \ + template<> TYPE* MaNGOS::Singleton, MaNGOS::ObjectLifeTime >::si_instance = 0; \ + template<> bool MaNGOS::Singleton, MaNGOS::ObjectLifeTime >::si_destroyed = false + +#define INSTANTIATE_SINGLETON_3(TYPE, THREADINGMODEL, CREATIONPOLICY ) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton >; \ + template<> TYPE* MaNGOS::Singleton >::si_instance = 0; \ + template<> bool MaNGOS::Singleton >::si_destroyed = false + +#define INSTANTIATE_SINGLETON_4(TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton; \ + template<> TYPE* MaNGOS::Singleton::si_instance = 0; \ + template<> bool MaNGOS::Singleton::si_destroyed = false +#endif diff --git a/src/framework/Policies/ThreadingModel.h b/src/framework/Policies/ThreadingModel.h new file mode 100644 index 000000000..d2cc24b55 --- /dev/null +++ b/src/framework/Policies/ThreadingModel.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_THREADINGMODEL_H +#define MANGOS_THREADINGMODEL_H + +/** + * @class ThreadingModel + * + */ + +#include "Platform/Define.h" + +namespace MaNGOS +{ + inline void Guard(void *) {} + + template class MANGOS_DLL_DECL GeneralLock + { + public: + GeneralLock(MUTEX &m) : i_mutex(m) + { + i_mutex.acquire(); + } + + ~GeneralLock() + { + i_mutex.release(); + } + private: + GeneralLock(const GeneralLock &); + GeneralLock& operator=(const GeneralLock &); + MUTEX &i_mutex; + }; + + template + class MANGOS_DLL_DECL SingleThreaded + { + public: + + struct Lock // empty object + { + Lock() {} + Lock(const T &) {} + Lock(const SingleThreaded &) // for single threaded we ignore this + { + } + }; + + typedef T VolatileType; + }; + + // object level lockable + template + class MANGOS_DLL_DECL ObjectLevelLockable + { + public: + ObjectLevelLockable() : i_mtx() {} + + friend class Lock; + + class Lock + { + public: + Lock(ObjectLevelLockable &host) : i_lock(host.i_mtx) + { + } + + private: + GeneralLock i_lock; + }; + + typedef volatile T VolatileType; + + private: + // prevent the compiler creating a copy construct + ObjectLevelLockable(const ObjectLevelLockable &); + ObjectLevelLockable& operator=(const ObjectLevelLockable &); + + MUTEX i_mtx; + }; + + template + class MANGOS_DLL_DECL ClassLevelLockable + { + public: + class Lock; + friend class Lock; + typedef volatile T VolatileType; + + ClassLevelLockable() {} + + class Lock + { + public: + Lock(T& /*host*/) { ClassLevelLockable::si_mtx.acquire(); } + Lock(ClassLevelLockable &) { ClassLevelLockable::si_mtx.acquire(); } + Lock() { ClassLevelLockable::si_mtx.acquire(); } + ~Lock() { ClassLevelLockable::si_mtx.release(); } + }; + + private: + static MUTEX si_mtx; + }; + +} + +template MUTEX MaNGOS::ClassLevelLockable::si_mtx; + +#define INSTANTIATE_CLASS_MUTEX(CTYPE,MUTEX) \ + template class MANGOS_DLL_DECL MaNGOS::ClassLevelLockable +#endif diff --git a/src/framework/Utilities/ByteConverter.h b/src/framework/Utilities/ByteConverter.h new file mode 100644 index 000000000..047c230af --- /dev/null +++ b/src/framework/Utilities/ByteConverter.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_BYTECONVERTER_H +#define MANGOS_BYTECONVERTER_H + +/** ByteConverter reverse your byte order. This is use + for cross platform where they have different endians. + */ + +#include +#include + +namespace ByteConverter +{ + template + inline void convert(char *val) + { + std::swap(*val, *(val + T - 1)); + convert(val + 1); + } + + template<> inline void convert<0>(char *) {} + template<> inline void convert<1>(char *) {} // ignore central byte + + template inline void apply(T *val) + { + convert((char *)(val)); + } +} + +#if MANGOS_ENDIAN == MANGOS_BIGENDIAN +template inline void EndianConvert(T& val) { ByteConverter::apply(&val); } +#else +template inline void EndianConvert(T&) { } +#endif + +template inline void EndianConvert(T*) { } +inline void EndianConvert(uint8&) { } +inline void EndianConvert( int8&) { } + +#endif diff --git a/src/framework/Utilities/Callback.h b/src/framework/Utilities/Callback.h new file mode 100644 index 000000000..40f7896f4 --- /dev/null +++ b/src/framework/Utilities/Callback.h @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CALLBACK_H +#define MANGOS_CALLBACK_H + +/// ------------ BASE CLASSES ------------ + +namespace MaNGOS +{ + template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class _Callback + { + protected: + typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4); + Class *m_object; + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + ParamType4 m_param4; + void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3, m_param4); } + public: + _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {} + _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4> const& cb) + : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {} + }; + + template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 > + class _Callback < Class, ParamType1, ParamType2, ParamType3 > + { + protected: + typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3); + Class *m_object; + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3); } + public: + _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {} + _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3 > const& cb) + : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {} + }; + + template < class Class, typename ParamType1, typename ParamType2 > + class _Callback < Class, ParamType1, ParamType2 > + { + protected: + typedef void (Class::*Method)(ParamType1, ParamType2); + Class *m_object; + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + void _Execute() { (m_object->*m_method)(m_param1, m_param2); } + public: + _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2) + : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {} + _Callback(_Callback < Class, ParamType1, ParamType2 > const& cb) + : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {} + }; + + template < class Class, typename ParamType1 > + class _Callback < Class, ParamType1 > + { + protected: + typedef void (Class::*Method)(ParamType1); + Class *m_object; + Method m_method; + ParamType1 m_param1; + void _Execute() { (m_object->*m_method)(m_param1); } + public: + _Callback(Class *object, Method method, ParamType1 param1) + : m_object(object), m_method(method), m_param1(param1) {} + _Callback(_Callback < Class, ParamType1 > const& cb) + : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1) {} + }; + + template < class Class > + class _Callback < Class > + { + protected: + typedef void (Class::*Method)(); + Class *m_object; + Method m_method; + void _Execute() { (m_object->*m_method)(); } + public: + _Callback(Class *object, Method method) + : m_object(object), m_method(method) {} + _Callback(_Callback < Class > const& cb) + : m_object(cb.m_object), m_method(cb.m_method) {} + }; + + /// ---- Statics ---- + + template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class _SCallback + { + protected: + typedef void (*Method)(ParamType1, ParamType2, ParamType3, ParamType4); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + ParamType4 m_param4; + void _Execute() { (*m_method)(m_param1, m_param2, m_param3, m_param4); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {} + _SCallback(_SCallback < ParamType1, ParamType2, ParamType3, ParamType4> const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {} + }; + + template < typename ParamType1, typename ParamType2, typename ParamType3 > + class _SCallback < ParamType1, ParamType2, ParamType3 > + { + protected: + typedef void (*Method)(ParamType1, ParamType2, ParamType3); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + void _Execute() { (*m_method)(m_param1, m_param2, m_param3); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : m_method(method), m_param1(param1), m_param2(param2) {} + _SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {} + }; + + template < typename ParamType1, typename ParamType2 > + class _SCallback < ParamType1, ParamType2 > + { + protected: + typedef void (*Method)(ParamType1, ParamType2); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + void _Execute() { (*m_method)(m_param1, m_param2); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2) + : m_method(method), m_param1(param1), m_param2(param2) {} + _SCallback(_SCallback < ParamType1, ParamType2 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {} + }; + + template < typename ParamType1 > + class _SCallback < ParamType1 > + { + protected: + typedef void (*Method)(ParamType1); + Method m_method; + ParamType1 m_param1; + void _Execute() { (*m_method)(m_param1); } + public: + _SCallback(Method method, ParamType1 param1) + : m_method(method), m_param1(param1) {} + _SCallback(_SCallback < ParamType1 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1) {} + }; + + template < > + class _SCallback < > + { + protected: + typedef void (*Method)(); + Method m_method; + void _Execute() { (*m_method)(); } + public: + _SCallback(Method method) + : m_method(method) {} + _SCallback(_SCallback <> const& cb) + : m_method(cb.m_method) {} + }; +} + +/// --------- GENERIC CALLBACKS ---------- + +namespace MaNGOS +{ + class ICallback + { + public: + virtual void Execute() = 0; + virtual ~ICallback() {} + }; + + template < class CB > + class _ICallback : public CB, public ICallback + { + public: + _ICallback(CB const& cb) : CB(cb) {} + void Execute() { CB::_Execute(); } + }; + + template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class Callback : + public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > > + { + private: + typedef _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > C4; + public: + Callback(Class *object, typename C4::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : _ICallback< C4 >(C4(object, method, param1, param2, param3, param4)) {} + }; + + template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 > + class Callback < Class, ParamType1, ParamType2, ParamType3 > : + public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _Callback < Class, ParamType1, ParamType2, ParamType3 > C3; + public: + Callback(Class *object, typename C3::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _ICallback< C3 >(C3(object, method, param1, param2, param3)) {} + }; + + template < class Class, typename ParamType1, typename ParamType2 > + class Callback < Class, ParamType1, ParamType2 > : + public _ICallback< _Callback < Class, ParamType1, ParamType2 > > + { + private: + typedef _Callback < Class, ParamType1, ParamType2 > C2; + public: + Callback(Class *object, typename C2::Method method, ParamType1 param1, ParamType2 param2) + : _ICallback< C2 >(C2(object, method, param1, param2)) {} + }; + + template < class Class, typename ParamType1 > + class Callback < Class, ParamType1 > : + public _ICallback< _Callback < Class, ParamType1 > > + { + private: + typedef _Callback < Class, ParamType1 > C1; + public: + Callback(Class *object, typename C1::Method method, ParamType1 param1) + : _ICallback< C1 >(C1(object, method, param1)) {} + }; + + template < class Class > + class Callback < Class > : public _ICallback< _Callback < Class > > + { + private: + typedef _Callback < Class > C0; + public: + Callback(Class *object, typename C0::Method method) + : _ICallback< C0 >(C0(object, method)) {} + }; +} + +/// ---------- QUERY CALLBACKS ----------- + +class QueryResult; + +namespace MaNGOS +{ + class IQueryCallback + { + public: + virtual void Execute() = 0; + virtual ~IQueryCallback() {} + virtual void SetResult(QueryResult* result) = 0; + virtual QueryResult* GetResult() = 0; + }; + + template < class CB > + class _IQueryCallback : public CB, public IQueryCallback + { + public: + _IQueryCallback(CB const& cb) : CB(cb) {} + void Execute() { CB::_Execute(); } + void SetResult(QueryResult* result) { CB::m_param1 = result; } + QueryResult* GetResult() { return CB::m_param1; } + }; + + template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void > + class QueryCallback : + public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > QC3; + public: + QueryCallback(Class *object, typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _IQueryCallback< QC3 >(QC3(object, method, result, param1, param2, param3)) {} + }; + + template < class Class, typename ParamType1, typename ParamType2 > + class QueryCallback < Class, ParamType1, ParamType2 > : + public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2 > > + { + private: + typedef _Callback < Class, QueryResult*, ParamType1, ParamType2 > QC2; + public: + QueryCallback(Class *object, typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2) + : _IQueryCallback< QC2 >(QC2(object, method, result, param1, param2)) {} + }; + + template < class Class, typename ParamType1 > + class QueryCallback < Class, ParamType1 > : + public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1 > > + { + private: + typedef _Callback < Class, QueryResult*, ParamType1 > QC1; + public: + QueryCallback(Class *object, typename QC1::Method method, QueryResult* result, ParamType1 param1) + : _IQueryCallback< QC1 >(QC1(object, method, result, param1)) {} + }; + + template < class Class > + class QueryCallback < Class > : public _IQueryCallback< _Callback < Class, QueryResult* > > + { + private: + typedef _Callback < Class, QueryResult* > QC0; + public: + QueryCallback(Class *object, typename QC0::Method method, QueryResult* result) + : _IQueryCallback< QC0 >(QC0(object, method, result)) {} + }; + + /// ---- Statics ---- + + template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void > + class SQueryCallback : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > QC3; + public: + SQueryCallback(typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _IQueryCallback< QC3 >(QC3(method, result, param1, param2, param3)) {} + }; + + template < typename ParamType1, typename ParamType2 > + class SQueryCallback < ParamType1, ParamType2 > : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1, ParamType2 > QC2; + public: + SQueryCallback(typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2) + : _IQueryCallback< QC2 >(QC2(method, result, param1, param2)) {} + }; + + template < typename ParamType1 > + class SQueryCallback < ParamType1 > : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1 > QC1; + public: + SQueryCallback(typename QC1::Method method, QueryResult* result, ParamType1 param1) + : _IQueryCallback< QC1 >(QC1(method, result, param1)) {} + }; + + template < > + class SQueryCallback < > : public _IQueryCallback< _SCallback < QueryResult* > > + { + private: + typedef _SCallback < QueryResult* > QC0; + public: + SQueryCallback(QC0::Method method, QueryResult* result) + : _IQueryCallback< QC0 >(QC0(method, result)) {} + }; +} + +#endif diff --git a/src/framework/Utilities/CountedReference/Reference.h b/src/framework/Utilities/CountedReference/Reference.h new file mode 100644 index 000000000..a26abf1b3 --- /dev/null +++ b/src/framework/Utilities/CountedReference/Reference.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_REFERENCE_H +#define MANGOS_REFERENCE_H + +/** + * Referencer + * Referencer is an object that holds a reference holder that hold a reference + * counted object. When an object's reference count drop to zero, it removes + * the object. This is a non intrusive mechanism and any object at any point + * in time can be referenced. When and object is reference counted, do not + * pass the object directly to other methods but rather, pass its + * reference around. Objects can be reference counted in both single threaded + * model and multi-threaded model + */ + +#include +#include "Platform/Define.h" +#include "Policies/ThreadingModel.h" +#include "ReferenceHolder.h" + +template +< +typename T, +class THREADING_MODEL = MaNGOS::SingleThreaded +> +class MANGOS_DLL_DECL Referencer +{ + typedef typename THREADING_MODEL::Lock Lock; + typedef ReferenceHolder ReferenceeHolder; + public: + + /// Constructs a referencer. + Referencer(T *ref = NULL); + + /// Copy constructor + Referencer(const Referencer &obj) : i_holder(NULL) { *this = obj; } + + /// Destructor + ~Referencer(); + + /// Referencee accessor + T* referencee(void) { return (i_holder == NULL ? NULL : i_holder->i_referencee); } + const T* referencee(void) const { return (i_holder == NULL ? NULL : i_holder->i_referencee); } + + //T& referencee(void){ return _referencee(); } + //const T& referencee(void) const { return const_cast(this)->_referencee(); } + operator T&(void) { return _referencee(); } + operator const T&(void) const { return *const_cast(this)->_referencee(); } + + /// cast operators + T* operator*() { return (i_holder == NULL ? NULL : i_holder->i_referencee); } + T const * operator*() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); } + + /// overload operators + T* operator->() { return (i_holder == NULL ? NULL : i_holder->i_referencee); } + const T * operator->() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); } + + /// operator = + Referencer& operator=(const Referencer &obj); + Referencer& operator=(T *); + + /// returns true if i_referencee is null + bool isNull(void) const { return i_holder == NULL; } + + private: + + T& _referencee(void) + { + if( i_holder == NULL ) + throw std::runtime_error("Invalid access to null pointer"); + return *i_holder->i_referencee; + } + + void deReference(ReferenceeHolder *); + void addReference(ReferenceeHolder *); + + // private data + ReferenceeHolder *i_holder; +}; +#endif diff --git a/src/framework/Utilities/CountedReference/ReferenceHolder.h b/src/framework/Utilities/CountedReference/ReferenceHolder.h new file mode 100644 index 000000000..3d4d72570 --- /dev/null +++ b/src/framework/Utilities/CountedReference/ReferenceHolder.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_REFERENCEHOLDER_H +#define MANGOS_REFERENCEHOLDER_H + +/** ReferenceHolder holds the actualy referenced obejct as well the refence + count. The ReferenecHolder implements as a policy base object and + will decided by the Reference class to be consnsitent. + */ + +template +< +typename T, +class THREADING_MODEL +> +struct ReferenceHolder : public THREADING_MODEL +{ + explicit ReferenceHolder(T *ref) : i_referencee(ref), i_referenceCount(0) {} + T *i_referencee; + unsigned int i_referenceCount; + typedef typename THREADING_MODEL::Lock Lock; +}; +#endif diff --git a/src/framework/Utilities/CountedReference/ReferenceImpl.h b/src/framework/Utilities/CountedReference/ReferenceImpl.h new file mode 100644 index 000000000..d5abe759f --- /dev/null +++ b/src/framework/Utilities/CountedReference/ReferenceImpl.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_REFERENCEIMPL_H +#define MANGOS_REFERENCEIMPL_H + +#include "Reference.h" + +template +< +typename T, +class THREADING_MODEL +> +Referencer::Referencer(T *ref) +: i_holder(NULL) +{ + if( ref != NULL ) + { + i_holder = new ReferenceeHolder(ref); + ++i_holder->i_referenceCount; + } +} + +template +< +typename T, +class THREADING_MODEL +> +Referencer::~Referencer() +{ + if( i_holder != NULL ) + deReference(i_holder); + i_holder = NULL; +} + +template +< +typename T, +class THREADING_MODEL +> +Referencer& +Referencer::operator=(const Referencer &obj) +{ + if( i_holder != NULL ) + deReference(i_holder); + if( obj.i_holder != NULL ) + addReference(obj.i_holder); + i_holder = obj.i_holder; + return *this; +} + +template +< +typename T, +class THREADING_MODEL +> +Referencer& +Referencer::operator=(T *ref) +{ + if( i_holder != NULL ) + deReference(i_holder); + i_holder = NULL; + if( ref != NULL ) + { + i_holder = new ReferenceeHolder(ref); + ++i_holder->i_referenceCount; + } + + return *this; +} + +template +< +typename T, +class THREADING_MODEL +> +void +Referencer::deReference(ReferenceHolder *holder) +{ + assert( holder != NULL && holder->i_referenceCount > 0); + bool delete_object = false; + + { + // The guard is within the scope due to the guard + // must release earlier than expected. + Lock guard(*holder); + Guard(&guard); + + --holder->i_referenceCount; + if( holder->i_referenceCount == 0 ) + delete_object = true; + } + + if( delete_object ) + { + delete holder->i_referencee; + delete holder; + } +} + +template +< +typename T, +class THREADING_MODEL +> +void +Referencer::addReference(ReferenceHolder *holder) +{ + assert( i_holder != NULL ); + Lock guard(*holder); + Guard(&guard); + + ++holder->i_referenceCount; +} +#endif diff --git a/src/framework/Utilities/EventProcessor.cpp b/src/framework/Utilities/EventProcessor.cpp new file mode 100644 index 000000000..2f37f53ff --- /dev/null +++ b/src/framework/Utilities/EventProcessor.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "EventProcessor.h" + +EventProcessor::EventProcessor() +{ + m_time = 0; + m_aborting = false; +} + +EventProcessor::~EventProcessor() +{ + KillAllEvents(); +} + +void EventProcessor::Update(uint32 p_time) +{ + // update time + m_time += p_time; + + // main event loop + EventList::iterator i; + while (((i = m_events.begin()) != m_events.end()) && i->first <= m_time) + { + // get and remove event from queue + BasicEvent* Event = i->second; + m_events.erase(i); + + if (!Event->to_Abort) + { + if (Event->Execute(m_time, p_time)) + { + // completely destroy event if it is not re-added + delete Event; + } + } + else + { + Event->Abort(m_time); + delete Event; + } + } +} + +void EventProcessor::KillAllEvents() +{ + // prevent event insertions + m_aborting = true; + + // first, abort all existing events + for (EventList::iterator i = m_events.begin(); i != m_events.end(); ++i) + { + i->second->to_Abort = true; + i->second->Abort(m_time); + delete i->second; + } + + // clear event list + m_events.clear(); +} + +void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime) +{ + if (set_addtime) Event->m_addTime = m_time; + Event->m_execTime = e_time; + m_events.insert(std::pair(e_time, Event)); +} + +uint64 EventProcessor::CalculateTime(uint64 t_offset) +{ + return(m_time + t_offset); +} diff --git a/src/framework/Utilities/EventProcessor.h b/src/framework/Utilities/EventProcessor.h new file mode 100644 index 000000000..e98e6243d --- /dev/null +++ b/src/framework/Utilities/EventProcessor.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __EVENTPROCESSOR_H +#define __EVENTPROCESSOR_H + +#include "Platform/Define.h" + +#include + +// Note. All times are in milliseconds here. + +class BasicEvent +{ + public: + BasicEvent() { to_Abort = false; } + virtual ~BasicEvent() // override destructor to perform some actions on event removal + { + }; + + // this method executes when the event is triggered + // return false if event does not want to be deleted + // e_time is execution time, p_time is update interval + virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; } + + virtual void Abort(uint64 /*e_time*/) {} // this method executes when the event is aborted + + bool to_Abort; // set by externals when the event is aborted, aborted events don't execute + // and get Abort call when deleted + + // these can be used for time offset control + uint64 m_addTime; // time when the event was added to queue, filled by event handler + uint64 m_execTime; // planned time of next execution, filled by event handler +}; + +typedef std::multimap EventList; + +class EventProcessor +{ + public: + EventProcessor(); + ~EventProcessor(); + + void Update(uint32 p_time); + void KillAllEvents(); + void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true); + uint64 CalculateTime(uint64 t_offset); + protected: + uint64 m_time; + EventList m_events; + bool m_aborting; +}; +#endif diff --git a/src/framework/Utilities/HashMap.h b/src/framework/Utilities/HashMap.h new file mode 100644 index 000000000..6dd23d7db --- /dev/null +++ b/src/framework/Utilities/HashMap.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_HASHMAP_H +#define MANGOS_HASHMAP_H + +#include "Platform/CompilerDefs.h" +#include "Platform/Define.h" + +#if COMPILER == COMPILER_INTEL +#include +#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3 +#include +#else +#include +#endif + +#ifdef _STLPORT_VERSION +#define HM_NAMESPACE std +using std::hash_map; +#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300 +#define HM_NAMESPACE stdext +using stdext::hash_map; +#elif COMPILER == COMPILER_INTEL +#define HM_NAMESPACE std +using std::hash_map; +#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3 +#define HM_NAMESPACE __gnu_cxx +using __gnu_cxx::hash_map; + +namespace __gnu_cxx +{ + template<> struct hash + { + size_t operator()(const unsigned long long &__x) const { return (size_t)__x; } + }; + template struct hash + { + size_t operator()(T * const &__x) const { return (size_t)__x; } + }; + +}; + +#else +#define HM_NAMESPACE std +using std::hash_map; +#endif +#endif diff --git a/src/framework/Utilities/LinkedList.h b/src/framework/Utilities/LinkedList.h new file mode 100644 index 000000000..4774920ee --- /dev/null +++ b/src/framework/Utilities/LinkedList.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINKEDLIST +#define _LINKEDLIST + +#include "Common.h" + +//============================================ +class LinkedListHead; + +class LinkedListElement +{ + private: + friend class LinkedListHead; + + LinkedListElement* iNext; + LinkedListElement* iPrev; + public: + LinkedListElement() { iNext = NULL; iPrev = NULL; } + ~LinkedListElement() { delink(); } + + bool hasNext() const { return(iNext->iNext != NULL); } + bool hasPrev() const { return(iPrev->iPrev != NULL); } + bool isInList() const { return(iNext != NULL && iPrev != NULL); } + + LinkedListElement * next() { return hasNext() ? iNext : NULL; } + LinkedListElement const* next() const { return hasNext() ? iNext : NULL; } + LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; } + LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; } + + void delink() + { + if(isInList()) + { + iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL; + } + } + + void insertBefore(LinkedListElement* pElem) + { + pElem->iNext = this; + pElem->iPrev = iPrev; + iPrev->iNext = pElem; + iPrev = pElem; + } + + void insertAfter(LinkedListElement* pElem) + { + pElem->iPrev = this; + pElem->iNext = iNext; + iNext->iPrev = pElem; + iNext = pElem; + } +}; + +//============================================ + +class LinkedListHead +{ + private: + LinkedListElement iFirst; + LinkedListElement iLast; + uint32 iSize; + public: + LinkedListHead() + { + // create empty list + + iFirst.iNext = &iLast; + iLast.iPrev = &iFirst; + iSize = 0; + } + + bool isEmpty() const { return(!iFirst.iNext->isInList()); } + + LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); } + LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); } + + LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); } + LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); } + + void insertFirst(LinkedListElement* pElem) + { + iFirst.insertAfter(pElem); + } + + void insertLast(LinkedListElement* pElem) + { + iLast.insertBefore(pElem); + } + + uint32 getSize() const + { + if(!iSize) + { + uint32 result = 0; + LinkedListElement const* e = getFirst(); + while(e) + { + ++result; + e = e->next(); + } + return result; + } + else + return iSize; + } + + void incSize() { ++iSize; } + void decSize() { --iSize; } + + template + class Iterator + { + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef _Ty value_type; + typedef ptrdiff_t difference_type; + typedef ptrdiff_t distance_type; + typedef _Ty* pointer; + typedef _Ty& reference; + + Iterator() : _Ptr(0) + { // construct with null node pointer + } + + Iterator(pointer _Pnode) : _Ptr(_Pnode) + { // construct with node pointer _Pnode + } + + reference operator*() + { // return designated value + return *_Ptr; + } + + pointer operator->() + { // return pointer to class object + return _Ptr; + } + + Iterator& operator++() + { // preincrement + _Ptr = _Ptr->next(); + return (*this); + } + + Iterator operator++(int) + { // postincrement + iterator _Tmp = *this; + ++*this; + return (_Tmp); + } + + Iterator& operator--() + { // predecrement + _Ptr = _Ptr->prev(); + return (*this); + } + + Iterator operator--(int) + { // postdecrement + iterator _Tmp = *this; + --*this; + return (_Tmp); + } + + bool operator==(Iterator const &_Right) const + { // test for iterator equality + return (_Ptr == _Right._Ptr); + } + + bool operator!=(Iterator const &_Right) const + { // test for iterator inequality + return (!(*this == _Right)); + } + + bool operator==(pointer const &_Right) const + { // test for pointer equality + return (_Ptr != _Right); + } + + bool operator!=(pointer const &_Right) const + { // test for pointer equality + return (!(*this == _Right)); + } + + pointer _Mynode() + { // return node pointer + return (_Ptr); + } + + protected: + pointer _Ptr; // pointer to node + }; + + typedef Iterator iterator; +}; + +//============================================ +#endif diff --git a/src/framework/Utilities/LinkedReference/RefManager.h b/src/framework/Utilities/LinkedReference/RefManager.h new file mode 100644 index 000000000..11e31f0d2 --- /dev/null +++ b/src/framework/Utilities/LinkedReference/RefManager.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _REFMANAGER_H +#define _REFMANAGER_H +//===================================================== + +#include "Utilities/LinkedList.h" +#include "Utilities/LinkedReference/Reference.h" + +template class RefManager : public LinkedListHead +{ + public: + typedef LinkedListHead::Iterator< Reference > iterator; + RefManager() { } + virtual ~RefManager() { clearReferences(); } + + Reference* getFirst() { return ((Reference*) LinkedListHead::getFirst()); } + Reference* getLast() { return ((Reference*) LinkedListHead::getLast()); } + + iterator begin() { return iterator(getFirst()); } + iterator end() { return iterator(NULL); } + iterator rbegin() { return iterator(getLast()); } + iterator rend() { return iterator(NULL); } + + void clearReferences() + { + LinkedListElement* ref; + while((ref = getFirst()) != NULL) + { + ((Reference*) ref)->invalidate(); + ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list + } + } +}; + +//===================================================== +#endif diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h new file mode 100644 index 000000000..a6778cc3a --- /dev/null +++ b/src/framework/Utilities/LinkedReference/Reference.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _REFERENCE_H +#define _REFERENCE_H + +#include "Utilities/LinkedList.h" + +//===================================================== + +template class Reference : public LinkedListElement +{ + private: + TO* iRefTo; + FROM* iRefFrom; + protected: + // Tell our refTo (target) object that we have a link + virtual void targetObjectBuildLink() = 0; + + // Tell our refTo (taget) object, that the link is cut + virtual void targetObjectDestroyLink() = 0; + + // Tell our refFrom (source) object, that the link is cut (Target destroyed) + virtual void sourceObjectDestroyLink() = 0; + public: + Reference() { iRefTo = NULL; iRefFrom = NULL; } + virtual ~Reference() {} + + // Create new link + inline void link(TO* toObj, FROM* fromObj) + { + assert(fromObj); // fromObj MUST not be NULL + if(isValid()) + unlink(); + if(toObj != NULL) + { + iRefTo = toObj; + iRefFrom = fromObj; + targetObjectBuildLink(); + } + } + + // We don't need the reference anymore. Call comes from the refFrom object + // Tell our refTo object, that the link is cut + inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; } + + // Link is invalid due to destruction of referenced target object. Call comes from the refTo object + // Tell our refFrom object, that the link is cut + inline void invalidate() // the iRefFrom MUST remain!! + { + sourceObjectDestroyLink(); delink(); iRefTo = NULL; + } + + inline bool isValid() const // Only check the iRefTo + { + return iRefTo != NULL; + } + + Reference* next() { return((Reference*)LinkedListElement::next()); } + Reference* prev() { return((Reference*)LinkedListElement::prev()); } + + inline TO* operator ->() const { return iRefTo; } + inline TO* getTarget() const { return iRefTo; } + + inline FROM* getSource() const { return iRefFrom; } +}; + +//===================================================== +#endif diff --git a/src/framework/Utilities/TypeList.h b/src/framework/Utilities/TypeList.h new file mode 100644 index 000000000..37b560071 --- /dev/null +++ b/src/framework/Utilities/TypeList.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_TYPELIST_H +#define MANGOS_TYPELIST_H + +/* + @struct TypeList + TypeList is the most simple but yet the most powerfull class of all. It holds + at compile time the different type of objects in a linked list. + */ + +class TypeNull; + +template +struct TypeList +{ + typedef HEAD Head; + typedef TAIL Tail; +}; + +// enough for now.. can be expand at any point in time as needed +#define TYPELIST_1(T1) TypeList +#define TYPELIST_2(T1, T2) TypeList +#define TYPELIST_3(T1, T2, T3) TypeList +#define TYPELIST_4(T1, T2, T3, T4) TypeList +#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList +#endif diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp new file mode 100644 index 000000000..cacccc2ae --- /dev/null +++ b/src/game/AccountMgr.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "AccountMgr.h" +#include "Database/DatabaseEnv.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Policies/SingletonImp.h" +#include "Util.h" + +#ifdef DO_POSTGRESQL +extern DatabasePostgre loginDatabase; +#else +extern DatabaseMysql loginDatabase; +#endif + +INSTANTIATE_SINGLETON_1(AccountMgr); + +AccountMgr::AccountMgr() +{} + +AccountMgr::~AccountMgr() +{} + +AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) +{ + if(utf8length(username) > MAX_ACCOUNT_STR) + return AOR_NAME_TOO_LONG; // username's too long + + normilizeString(username); + normilizeString(password); + + loginDatabase.escape_string(username); + loginDatabase.escape_string(password); + + QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str()); + if(result) + { + delete result; + return AOR_NAME_ALREDY_EXIST; // username does already exist + } + + if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1(CONCAT('%s',':','%s')),NOW())", username.c_str(), username.c_str(), password.c_str())) + return AOR_DB_INTERNAL_ERROR; // unexpected error + loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM account, realmlist WHERE account.id NOT IN (SELECT acctid FROM realmcharacters)"); + + return AOR_OK; // everything's fine +} + +AccountOpResult AccountMgr::DeleteAccount(uint32 accid) +{ + QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid); + if(!result) + return AOR_NAME_NOT_EXIST; // account doesn't exist + delete result; + + result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid); + if (result) + { + do + { + Field *fields = result->Fetch(); + uint32 guidlo = fields[0].GetUInt32(); + uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER); + + // kick if player currently + if(Player* p = objmgr.GetPlayer(guid)) + { + WorldSession* s = p->GetSession(); + s->KickPlayer(); // mark session to remove at next session list update + s->LogoutPlayer(false); // logout player without waiting next session list update + } + + Player::DeleteFromDB(guid, accid, false); // no need to update realm characters + } while (result->NextRow()); + + delete result; + } + + // table realm specific but common for all characters of account for realm + CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid); + + loginDatabase.BeginTransaction(); + + bool res = + loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) && + loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid); + + loginDatabase.CommitTransaction(); + + if(!res) + return AOR_DB_INTERNAL_ERROR; // unexpected error; + + return AOR_OK; +} + +AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd) +{ + QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid); + if(!result) + return AOR_NAME_NOT_EXIST; // account doesn't exist + delete result; + + if(utf8length(new_uname) > MAX_ACCOUNT_STR) + return AOR_NAME_TOO_LONG; + + if(utf8length(new_passwd) > MAX_ACCOUNT_STR) + return AOR_PASS_TOO_LONG; + + normilizeString(new_uname); + normilizeString(new_passwd); + + loginDatabase.escape_string(new_uname); + loginDatabase.escape_string(new_passwd); + if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1(CONCAT('%s',':','%s')) WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid)) + return AOR_DB_INTERNAL_ERROR; // unexpected error + + return AOR_OK; +} + +AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd) +{ + QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid); + if(!result) + return AOR_NAME_NOT_EXIST; // account doesn't exist + delete result; + + if (utf8length(new_passwd) > MAX_ACCOUNT_STR) + return AOR_PASS_TOO_LONG; + + normilizeString(new_passwd); + + loginDatabase.escape_string(new_passwd); + if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1(CONCAT(username,':','%s')) WHERE id='%d'", new_passwd.c_str(), accid)) + return AOR_DB_INTERNAL_ERROR; // unexpected error + + return AOR_OK; +} + +uint32 AccountMgr::GetId(std::string username) +{ + loginDatabase.escape_string(username); + QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str()); + if(!result) + return 0; + else + { + uint32 id = (*result)[0].GetUInt32(); + delete result; + return id; + } +} + +bool AccountMgr::CheckPassword(uint32 accid, std::string passwd) +{ + normilizeString(passwd); + loginDatabase.escape_string(passwd); + + QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", accid, passwd.c_str()); + if (result) + { + delete result; + return true; + } + + return false; +} + +bool AccountMgr::normilizeString(std::string& utf8str) +{ + wchar_t wstr_buf[MAX_ACCOUNT_STR+1]; + + size_t wstr_len = MAX_ACCOUNT_STR; + if(!Utf8toWStr(utf8str,wstr_buf,wstr_len)) + return false; + + std::transform( &wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin ); + + return WStrToUtf8(wstr_buf,wstr_len,utf8str); +} diff --git a/src/game/AccountMgr.h b/src/game/AccountMgr.h new file mode 100644 index 000000000..22b4eff48 --- /dev/null +++ b/src/game/AccountMgr.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ACCMGR_H +#define _ACCMGR_H + +#include "Common.h" +#include "Policies/Singleton.h" +#include + +enum AccountOpResult +{ + AOR_OK, + AOR_NAME_TOO_LONG, + AOR_PASS_TOO_LONG, + AOR_NAME_ALREDY_EXIST, + AOR_NAME_NOT_EXIST, + AOR_DB_INTERNAL_ERROR +}; + +#define MAX_ACCOUNT_STR 16 + +class AccountMgr +{ + public: + AccountMgr(); + ~AccountMgr(); + + AccountOpResult CreateAccount(std::string username, std::string password); + AccountOpResult DeleteAccount(uint32 accid); + AccountOpResult ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd); + AccountOpResult ChangePassword(uint32 accid, std::string new_passwd); + bool CheckPassword(uint32 accid, std::string passwd); + + uint32 GetId(std::string username); + + static bool normilizeString(std::string& utf8str); +}; + +#define accmgr MaNGOS::Singleton::Instance() +#endif diff --git a/src/game/AddonHandler.cpp b/src/game/AddonHandler.cpp new file mode 100644 index 000000000..1f557dd9e --- /dev/null +++ b/src/game/AddonHandler.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "AddonHandler.h" +#include "Database/DatabaseEnv.h" +#include "Opcodes.h" +#include "Log.h" +#include "Policies/SingletonImp.h" +#include "zlib/zlib.h" + +INSTANTIATE_SINGLETON_1( AddonHandler ); + +AddonHandler::AddonHandler() +{ +} + +AddonHandler::~AddonHandler() +{ +} + +bool AddonHandler::BuildAddonPacket(WorldPacket *Source, WorldPacket *Target) +{ + ByteBuffer AddOnPacked; + uLongf AddonRealSize; + uint32 CurrentPosition; + uint32 TempValue; + + unsigned char tdata[256] = + { + 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54, + 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75, + 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34, + 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8, + 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8, + 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A, + 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3, + 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9, + 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22, + 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E, + 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB, + 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7, + 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0, + 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6, + 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, + 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 + }; + + // broken addon packet, can't be received from real client + if (Source->rpos() + 4 > Source->size()) + return false; + + *Source >> TempValue; //get real size of the packed structure + + // empty addon packet, nothing process, can't be received from real client + if(!TempValue) + return false; + + AddonRealSize = TempValue; //temp value because ZLIB only excepts uLongf + + CurrentPosition = Source->rpos(); //get the position of the pointer in the structure + + AddOnPacked.resize(AddonRealSize); //resize target for zlib action + + if (!uncompress(const_cast(AddOnPacked.contents()), &AddonRealSize, const_cast((*Source).contents() + CurrentPosition), (*Source).size() - CurrentPosition)!= Z_OK) + { + Target->Initialize(SMSG_ADDON_INFO); + + while(AddOnPacked.rpos() < AddOnPacked.size()) + { + std::string AddonNames; + uint8 unk6; + uint32 crc, unk7; + + // check next addon data format correctness + if(AddOnPacked.rpos()+1+4+4+1 > AddOnPacked.size()) + return false; + + AddOnPacked >> AddonNames; + + // recheck next addon data format correctness + if(AddOnPacked.rpos()+4+4+1 > AddOnPacked.size()) + return false; + + AddOnPacked >> crc >> unk7 >> unk6; + + //sLog.outDebug("ADDON: Name:%s CRC:%x Unknown1 :%x Unknown2 :%x", AddonNames.c_str(), crc, unk7, unk6); + + *Target << (uint8)2; + + uint8 unk1 = 1; + *Target << (uint8)unk1; + if (unk1) + { + uint8 unk2 = crc != 0x1c776d01LL; //If addon is Standard addon CRC + *Target << (uint8)unk2; + if (unk2) + Target->append(tdata, sizeof(tdata)); + + *Target << (uint32)0; + } + + uint8 unk3 = 0; + *Target << (uint8)unk3; + if (unk3) + { + // String, 256 + } + } + } + else + { + sLog.outError("Addon packet uncompress error :("); + return false; + } + return true; +} + +/* Code use in 1.10.2 when client not ignore ban state sended for addons. Saved for reference if client switch to use server ban state information +void AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target, uint32 Packetoffset) +{ + ByteBuffer AddOnPacked; + uLongf AddonRealSize; + uint32 CurrentPosition; + uint32 TempValue; + + *Source >> TempValue; //get real size of the packed structure + + AddonRealSize = TempValue; //temp value becouse ZLIB only excepts uLongf + + CurrentPosition = Source->rpos(); //get the position of the pointer in the structure + + AddOnPacked.resize(AddonRealSize); //resize target for zlib action + + if (!uncompress((uint8*)AddOnPacked.contents(), &AddonRealSize, (uint8*)(*Source).contents() + CurrentPosition, (*Source).size() - CurrentPosition)!= Z_OK) + { + bool* AddonAllowed = new bool; //handle addon check and enable-ing + + uint32 Unknown1; + uint8 Unknown0; + + AddOnPacked >> Unknown0; + AddOnPacked >> Unknown1; + + Target->Initialize(SMSG_ADDON_INFO); + + uint32 i = 5; //offset for addon extraction + while(i != AddOnPacked.size()) + { + std::string AddonNames; + AddOns* Addonstr = new AddOns; + uint8 unk6; + uint64 CRCCHECK; + AddOnPacked >> AddonNames >> CRCCHECK >> unk6; + + //sLog.outDebug("ADDON: Name:%s CRC:%x Unknown:%x",AddonNames.c_str(), CRCCHECK,unk6); + + Addonstr->Name = AddonNames; + Addonstr->CRC = CRCCHECK; + + //if not allowed but unknown added to list + if (GetAddonStatus(Addonstr, AddonAllowed)) // If addon is new + { + Addonstr->Enabled = m_Addon_Default; // by default new addons are set from Config file + *AddonAllowed = m_Addon_Default; // Set addon allowed on default value + _AddAddon(Addonstr); + sLog.outDetail("Found new Addon, Name:%s CRC:%x Unknown:%x",AddonNames.c_str(), CRCCHECK, unk6); + } + + if (CRCCHECK == 0x4C1C776D01LL) //If addon is Standard addon CRC + { + //value's standard Addons + *Target << uint8(0) << uint8(2) << uint8(1) << uint8(0) << uint32(0); + } + else if (*AddonAllowed) //if addon is Custom addons + //value's enable addon + *Target << uint8(0x00) << uint8(0x01) << uint8(0x00) << uint8(0x01); + else + //value's disable addom + *Target << uint8(0x00) << uint8(0x0) << uint8(0x00) << uint8(0x0); + + i += AddonNames.size() + 10; + } + *Target << uint8(0x0); + + //delete mem allocation + delete AddonAllowed; + } + else + { + //handle uncompress error + } +} +*/ diff --git a/src/game/AddonHandler.h b/src/game/AddonHandler.h new file mode 100644 index 000000000..95c89b662 --- /dev/null +++ b/src/game/AddonHandler.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ADDONHANDLER_H +#define __ADDONHANDLER_H + +#include "Common.h" +#include "Policies/Singleton.h" +#include "WorldPacket.h" +#include "Config/ConfigEnv.h" + +class AddonHandler +{ + public: + /* Construction */ + AddonHandler(); + ~AddonHandler(); + //built addon packet + bool BuildAddonPacket(WorldPacket* Source, WorldPacket* Target); +}; +#define sAddOnHandler MaNGOS::Singleton::Instance() +#endif diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp new file mode 100644 index 000000000..637410c1f --- /dev/null +++ b/src/game/AggressorAI.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "AggressorAI.h" +#include "Errors.h" +#include "Creature.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "VMapFactory.h" +#include "World.h" + +#include + +int +AggressorAI::Permissible(const Creature *creature) +{ + // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight + if( !creature->isCivilian() && !creature->IsNeutralToAll() ) + return PERMIT_BASE_PROACTIVE; + + return PERMIT_BASE_NO; +} + +AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +{ +} + +void +AggressorAI::MoveInLineOfSight(Unit *u) +{ + // Ignore Z for flying creatures + if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE ) + return; + + if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() && + ( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) && + u->isInAccessablePlaceFor(&i_creature) ) + { + float attackRadius = i_creature.GetAttackDistance(u); + if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) ) + { + AttackStart(u); + u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + } +} + +void AggressorAI::EnterEvadeMode() +{ + if( !i_creature.isAlive() ) + { + DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow()); + i_victimGuid = 0; + i_creature.CombatStop(); + i_creature.DeleteThreatList(); + return; + } + + Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid ); + + if( !victim ) + { + DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow()); + } + else if( !victim->isAlive() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow()); + } + else if( victim->HasStealthAura() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow()); + } + else if( victim->isInFlight() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow()); + } + else + { + DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow()); + //i_state = STATE_LOOK_AT_VICTIM; + //i_tracker.Reset(TIME_INTERVAL_LOOK); + } + + if(!i_creature.isCharmed()) + { + i_creature.RemoveAllAuras(); + + // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead + if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) + i_creature.GetMotionMaster()->MoveTargetedHome(); + } + + i_creature.DeleteThreatList(); + i_victimGuid = 0; + i_creature.CombatStop(); + i_creature.SetLootRecipient(NULL); +} + +void +AggressorAI::UpdateAI(const uint32 /*diff*/) +{ + // update i_victimGuid if i_creature.getVictim() !=0 and changed + if(!i_creature.SelectHostilTarget() || !i_creature.getVictim()) + return; + + i_victimGuid = i_creature.getVictim()->GetGUID(); + + if( i_creature.isAttackReady() ) + { + if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE)) + { + i_creature.AttackerStateUpdate(i_creature.getVictim()); + i_creature.resetAttackTimer(); + } + } +} + +bool +AggressorAI::IsVisible(Unit *pl) const +{ + return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER) + && pl->isVisibleForOrDetect(&i_creature,true); +} + +void +AggressorAI::AttackStart(Unit *u) +{ + if( !u ) + return; + + if(i_creature.Attack(u,true)) + { + i_creature.SetInCombatWith(u); + u->SetInCombatWith(&i_creature); + + i_creature.AddThreat(u, 0.0f); + // DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow()); + i_victimGuid = u->GetGUID(); + + i_creature.GetMotionMaster()->MoveChase(u); + } +} diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h new file mode 100644 index 000000000..e51a4e61e --- /dev/null +++ b/src/game/AggressorAI.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_AGGRESSORAI_H +#define MANGOS_AGGRESSORAI_H + +#include "CreatureAI.h" +#include "Timer.h" + +class Creature; + +class MANGOS_DLL_DECL AggressorAI : public CreatureAI +{ + enum AggressorState + { + STATE_NORMAL = 1, + STATE_LOOK_AT_VICTIM = 2 + }; + + public: + + AggressorAI(Creature &c); + + void MoveInLineOfSight(Unit *); + void AttackStart(Unit *); + void EnterEvadeMode(); + bool IsVisible(Unit *) const; + + void UpdateAI(const uint32); + static int Permissible(const Creature *); + + private: + Creature &i_creature; + uint64 i_victimGuid; + AggressorState i_state; + TimeTracker i_tracker; +}; +#endif diff --git a/src/game/AnimalRandomMovementGenerator.h b/src/game/AnimalRandomMovementGenerator.h new file mode 100644 index 000000000..dc42c6e0c --- /dev/null +++ b/src/game/AnimalRandomMovementGenerator.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_ANIMAL_RANDOMMOVEMENTGENERATOR_H +#define MANGOS_ANIMAL_RANDOMMOVEMENTGENERATOR_H + +/** AnimalRandomMovementGenerator follows the research on + * quantifying scale-dependant effects of animal movement + * with simple per-location models (R.H. Gardner, R.V. O'Neil, + * M.G: Turner and V.H. Dale). It is specifically used on + * animal creatures. + */ +#endif diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp new file mode 100644 index 000000000..36ae28165 --- /dev/null +++ b/src/game/ArenaTeam.cpp @@ -0,0 +1,517 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "WorldPacket.h" +#include "ObjectMgr.h" +#include "ArenaTeam.h" + +ArenaTeam::ArenaTeam() +{ + Id = 0; + Type = 0; + Name = ""; + CaptainGuid = 0; + BackgroundColor = 0; // background + EmblemStyle = 0; // icon + EmblemColor = 0; // icon color + BorderStyle = 0; // border + BorderColor = 0; // border color + stats.games = 0; + stats.played = 0; + stats.rank = 0; + stats.rating = 1500; + stats.wins = 0; + stats.wins2 = 0; +} + +ArenaTeam::~ArenaTeam() +{ + +} + +bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamName) +{ + if(!objmgr.GetPlayer(captainGuid)) // player not exist + return false; + if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist + return false; + + sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid)); + + CaptainGuid = captainGuid; + Name = ArenaTeamName; + Type = type; + + QueryResult *result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); + if( result ) + { + Id = (*result)[0].GetUInt32()+1; + delete result; + } + else Id = 1; + + // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB + CharacterDatabase.escape_string(ArenaTeamName); + + CharacterDatabase.BeginTransaction(); + // CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", Id); - MAX(arenateam)+1 not exist + CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id); + CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) " + "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')", + Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor); + CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES " + "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games,stats.wins,stats.played,stats.wins2,stats.rank); + + CharacterDatabase.CommitTransaction(); + + AddMember(CaptainGuid); + return true; +} + +bool ArenaTeam::AddMember(uint64 PlayerGuid) +{ + std::string plName; + uint8 plClass; + + if(GetMembersSize() >= GetType() * 2) + { + // arena team is full (can't have more than type * 2 players!) + // return false + return false; + } + + if(!objmgr.GetPlayerNameByGUID(PlayerGuid, plName)) // player doesnt exist + return false; + // player already in arenateam of that size + if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0) + { + sLog.outError("Arena::AddMember() : player already in this sized team"); + return false; + } + + // remove all player signs from another petitions + // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity + Player::RemovePetitionsAndSigns(PlayerGuid, GetType()); + + Player *pl = objmgr.GetPlayer(PlayerGuid); + if(pl) + { + plClass = (uint8)pl->getClass(); + } + else + { + QueryResult *result = CharacterDatabase.PQuery("SELECT class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid)); + if(!result) + return false; + plClass = (*result)[0].GetUInt8(); + delete result; + } + + ArenaTeamMember newmember; + newmember.name = plName; + newmember.guid = PlayerGuid; + newmember.Class = plClass; + newmember.played_season = 0; + newmember.played_week = 0; + newmember.wons_season = 0; + newmember.wons_week = 0; + members.push_back(newmember); + + CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid)); + + if(pl) + { + pl->SetInArenaTeam(Id, GetSlot()); + pl->SetArenaTeamIdInvited(0); + } + else + { + Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id, PlayerGuid); + } + + // hide promote/remove buttons + if(CaptainGuid != PlayerGuid) + { + if(pl) + pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); + else + Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, PlayerGuid); + } + return true; +} + +bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId) +{ + LoadStatsFromDB(ArenaTeamId); + LoadMembersFromDB(ArenaTeamId); + + // 0 1 2 3 4 5 6 7 8 + QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId); + + if(!result) + return false; + + Field *fields = result->Fetch(); + + Id = fields[0].GetUInt32(); + Name = fields[1].GetCppString(); + CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); + Type = fields[3].GetUInt32(); + BackgroundColor = fields[4].GetUInt32(); + EmblemStyle = fields[5].GetUInt32(); + EmblemColor = fields[6].GetUInt32(); + BorderStyle = fields[7].GetUInt32(); + BorderColor = fields[8].GetUInt32(); + + delete result; + + return true; +} + +void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId) +{ + // 0 1 2 3 4 5 + QueryResult *result = CharacterDatabase.PQuery("SELECT rating,games,wins,played,wins2,rank FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId); + + if(!result) + return; + + Field *fields = result->Fetch(); + + stats.rating = fields[0].GetUInt32(); + stats.games = fields[1].GetUInt32(); + stats.wins = fields[2].GetUInt32(); + stats.played = fields[3].GetUInt32(); + stats.wins2 = fields[4].GetUInt32(); + stats.rank = fields[5].GetUInt32(); + + delete result; +} + +void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId) +{ + Field *fields; + + QueryResult *result = CharacterDatabase.PQuery("SELECT guid,played_week,wons_week,played_season,wons_season FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId); + if(!result) + return; + + do + { + fields = result->Fetch(); + ArenaTeamMember newmember; + newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + LoadPlayerStats(&newmember); + newmember.played_week = fields[1].GetUInt32(); + newmember.wons_week = fields[2].GetUInt32(); + newmember.played_season = fields[3].GetUInt32(); + newmember.wons_season = fields[4].GetUInt32(); + members.push_back(newmember); + }while( result->NextRow() ); + delete result; +} + +void ArenaTeam::LoadPlayerStats(ArenaTeamMember *member) +{ + Field *fields; + + QueryResult *result = CharacterDatabase.PQuery("SELECT name,class FROM characters WHERE guid = '%u'", GUID_LOPART(member->guid)); + if(!result) + return; + fields = result->Fetch(); + member->name = fields[0].GetCppString(); + member->Class = fields[1].GetUInt8(); + + delete result; +} + +void ArenaTeam::SetCaptain(uint64 guid) +{ + // disable remove/promote buttons + Player *oldcaptain = objmgr.GetPlayer(GetCaptain()); + if(oldcaptain) + oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); + else + Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, GetCaptain()); + + // set new captain + CaptainGuid = guid; + + // update database + CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), Id); + + // enable remove/promote buttons + Player *newcaptain = objmgr.GetPlayer(guid); + if(newcaptain) + newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0); + else + Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0, guid); +} + +void ArenaTeam::DelMember(uint64 guid) +{ + MemberList::iterator itr; + for (itr = members.begin(); itr != members.end(); itr++) + { + if (itr->guid == guid) + { + members.erase(itr); + break; + } + } + + Player *player = objmgr.GetPlayer(guid); + if(player) + { + player->SetInArenaTeam(0, GetSlot()); + player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0); + } + else + { + Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), 0, guid); + } + + CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u'", GUID_LOPART(guid)); +} + +void ArenaTeam::Disband(WorldSession *session) +{ + // event + WorldPacket data; + session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), ""); + BroadcastPacket(&data); + + uint32 count = members.size(); + uint64 *memberGuids = new uint64[count]; + + MemberList::iterator itr; + uint32 i=0; + for(itr = members.begin(); itr != members.end(); itr++) + { + memberGuids[i] = itr->guid; + ++i; + } + + for(uint32 j = 0; j < count; j++) + DelMember(memberGuids[j]); + delete[] memberGuids; + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id); + CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id); + CharacterDatabase.CommitTransaction(); + objmgr.RemoveArenaTeam(this); +} + +void ArenaTeam::Roster(WorldSession *session) +{ + Player *pl = NULL; + + WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100); + data << uint32(GetId()); // arena team id + data << uint32(GetMembersSize()); // members count + data << uint32(GetType()); // arena team type? + + for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + pl = objmgr.GetPlayer(itr->guid); + if(pl) + { + data << uint64(pl->GetGUID()); // guid + data << uint8(1); // online flag + data << pl->GetName(); // member name + data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown + data << uint8(pl->getLevel()); // unknown, probably level + data << uint8(pl->getClass()); // class + data << uint32(itr->played_week); // played this week + data << uint32(itr->wons_week); // wins this week + data << uint32(itr->played_season); // played this season + data << uint32(itr->wons_season); // wins this season + data << uint32(0); // personal rating? + } + else + { + data << uint64(itr->guid); // guid + data << uint8(0); // online flag + data << itr->name; // member name + data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown + data << uint8(0); // unknown, level? + data << uint8(itr->Class); // class + data << uint32(itr->played_week); // played this week + data << uint32(itr->wons_week); // wins this week + data << uint32(itr->played_season); // played this season + data << uint32(itr->wons_season); // wins this season + data << uint32(0); // personal rating? + } + } + session->SendPacket(&data); + sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER"); +} + +void ArenaTeam::Query(WorldSession *session) +{ + WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1); + data << uint32(GetId()); // team id + data << GetName(); // team name + data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5) + data << uint32(BackgroundColor); // background color + data << uint32(EmblemStyle); // emblem style + data << uint32(EmblemColor); // emblem color + data << uint32(BorderStyle); // border style + data << uint32(BorderColor); // border color + session->SendPacket(&data); + sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE"); +} + +void ArenaTeam::Stats(WorldSession *session) +{ + WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7); + data << uint32(GetId()); // arena team id + data << uint32(stats.rating); // rating + data << uint32(stats.games); // games + data << uint32(stats.wins); // wins + data << uint32(stats.played); // played + data << uint32(stats.wins2); // wins(again o_O) + data << uint32(stats.rank); // rank + session->SendPacket(&data); +} + +void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) +{ + WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6); + data << uint64(guid); // player guid + data << uint8(GetSlot()); // slot (0...2) + data << uint32(GetId()); // arena team id + data << uint32(stats.rating); // rating + data << uint32(stats.games); // games + data << uint32(stats.wins); // wins + data << uint32(stats.played); // played (count of all games, that played...) + data << uint32(0); // 2.3.3 personal rating? + session->SendPacket(&data); +} + +void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor) +{ + BackgroundColor = backgroundColor; + EmblemStyle = emblemStyle; + EmblemColor = emblemColor; + BorderStyle = borderStyle; + BorderColor = borderColor; + + CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor, Id); +} + +void ArenaTeam::SetStats(uint32 stat_type, uint32 value) +{ + switch(stat_type) + { + case STAT_TYPE_RATING: + stats.rating = value; + CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId()); + break; + case STAT_TYPE_GAMES: + stats.games = value; + CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId()); + break; + case STAT_TYPE_WINS: + stats.wins = value; + CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId()); + break; + case STAT_TYPE_PLAYED: + stats.played = value; + CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId()); + break; + case STAT_TYPE_WINS2: + stats.wins2 = value; + CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId()); + break; + case STAT_TYPE_RANK: + stats.rank = value; + CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId()); + break; + default: + sLog.outDebug("unknown stat type in ArenaTeam::SetStats() %u", stat_type); + break; + } +} + +uint8 ArenaTeam::GetSlot() const +{ + uint8 slot = GetSlotByType(GetType()); + if(slot >= MAX_ARENA_SLOT) + { + sLog.outError("Unknown arena team type %u for arena team %u", uint32(GetType()), GetId()); + return 0; // better return existed slot to prevent untelated data curruption + } + + return slot; +} + +void ArenaTeam::BroadcastPacket(WorldPacket *packet) +{ + for (MemberList::iterator itr = members.begin(); itr != members.end(); itr++) + { + Player *player = objmgr.GetPlayer(itr->guid); + if(player) + player->GetSession()->SendPacket(packet); + } +} + +uint8 ArenaTeam::GetSlotByType( uint32 type ) +{ + switch(type) + { + case ARENA_TEAM_2v2: return 0; + case ARENA_TEAM_3v3: return 1; + case ARENA_TEAM_5v5: return 2; + default: + break; + } + return 0xFF; +} + +bool ArenaTeam::HaveMember( uint64 guid ) const +{ + for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) + if(itr->guid==guid) + return true; + + return false; +} + +/* +arenateam fields (id from 2.3.3 client): +1414 - arena team id 2v2 +1415 - 0=captain, 1=member +1416 - played this season +1417 - played this week +1418 - unk +1419 - unk +1420 - arena team id 3v3 +1421 - 0=captain, 1=member +1422 - played this season +1423 - played this week +1424 - unk +1425 - unk +1426 - arena team id 5v5 +1427 - 0=captain, 1=member +1428 - played this season +1429 - played this week +1430 - unk +1431 - unk +*/ diff --git a/src/game/ArenaTeam.h b/src/game/ArenaTeam.h new file mode 100644 index 000000000..0d26b00cf --- /dev/null +++ b/src/game/ArenaTeam.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_ARENATEAM_H +#define MANGOSSERVER_ARENATEAM_H + +enum ArenaTeamCommandTypes +{ + ERR_ARENA_TEAM_CREATE_S = 0x00, + ERR_ARENA_TEAM_INVITE_SS = 0x01, + //ERR_ARENA_TEAM_QUIT_S = 0x02, + ERR_ARENA_TEAM_QUIT_S = 0x03, + ERR_ARENA_TEAM_FOUNDER_S = 0x0C // need check, probably wrong... +}; + +enum ArenaTeamCommandErrors +{ + //ARENA_TEAM_PLAYER_NO_MORE_IN_ARENA_TEAM = 0x00, + ERR_ARENA_TEAM_INTERNAL = 0x01, + ERR_ALREADY_IN_ARENA_TEAM = 0x02, + ERR_ALREADY_IN_ARENA_TEAM_S = 0x03, + ERR_INVITED_TO_ARENA_TEAM = 0x04, + ERR_ALREADY_INVITED_TO_ARENA_TEAM_S = 0x05, + ERR_ARENA_TEAM_NAME_INVALID = 0x06, + ERR_ARENA_TEAM_NAME_EXISTS_S = 0x07, + ERR_ARENA_TEAM_LEADER_LEAVE_S = 0x08, + ERR_ARENA_TEAM_PERMISSIONS = 0x08, + ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM = 0x09, + ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS = 0x0A, + ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S = 0x0B, + ERR_ARENA_TEAM_NOT_ALLIED = 0x0C +}; + +enum ArenaTeamEvents +{ + ERR_ARENA_TEAM_JOIN_SS = 3, // player name + arena team name + ERR_ARENA_TEAM_LEAVE_SS = 4, // player name + arena team name + ERR_ARENA_TEAM_REMOVE_SSS = 5, // player name + arena team name + captain name + ERR_ARENA_TEAM_LEADER_IS_SS = 6, // player name + arena team name + ERR_ARENA_TEAM_LEADER_CHANGED_SSS = 7, // old captain + new captain + arena team name + ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name +}; + +/* +need info how to send these ones: +ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite +ERR_ARENA_TEAM_TARGET_TOO_LOW_S +ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S +ERR_ARENA_TEAM_LEVEL_TOO_LOW_I +*/ + +enum ArenaTeamStatTypes +{ + STAT_TYPE_RATING = 0, + STAT_TYPE_GAMES = 1, + STAT_TYPE_WINS = 2, + STAT_TYPE_PLAYED = 3, + STAT_TYPE_WINS2 = 4, + STAT_TYPE_RANK = 5 +}; + +enum ArenaTeamTypes +{ + ARENA_TEAM_2v2 = 2, + ARENA_TEAM_3v3 = 3, + ARENA_TEAM_5v5 = 5 +}; + +struct ArenaTeamMember +{ + uint64 guid; + std::string name; + //uint32 unk2; + //uint8 unk1; + uint8 Class; + uint32 played_week; + uint32 wons_week; + uint32 played_season; + uint32 wons_season; +}; + +struct ArenaTeamStats +{ + uint32 rating; + uint32 games; + uint32 wins; + uint32 played; + uint32 wins2; + uint32 rank; +}; + +#define MAX_ARENA_SLOT 3 // 0..2 slots + +class ArenaTeam +{ + public: + ArenaTeam(); + ~ArenaTeam(); + + bool create(uint64 CaptainGuid, uint32 type, std::string ArenaTeamName); + void Disband(WorldSession *session); + + typedef std::list MemberList; + + uint32 GetId() const { return Id; } + uint32 GetType() const { return Type; } + uint8 GetSlot() const; + static uint8 GetSlotByType(uint32 type); + const uint64& GetCaptain() const { return CaptainGuid; } + std::string GetName() const { return Name; } + ArenaTeamStats GetStats() const { return stats; } + void SetStats(uint32 stat_type, uint32 value); + uint32 GetRating() const { return stats.rating; } + + uint32 GetEmblemStyle() const { return EmblemStyle; } + uint32 GetEmblemColor() const { return EmblemColor; } + uint32 GetBorderStyle() const { return BorderStyle; } + uint32 GetBorderColor() const { return BorderColor; } + uint32 GetBackgroundColor() const { return BackgroundColor; } + + void SetCaptain(uint64 guid); + bool AddMember(uint64 PlayerGuid); + void DelMember(uint64 guid); + + void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor); + + uint32 GetMembersSize() const { return members.size(); } + MemberList::iterator membersbegin(){ return members.begin(); } + MemberList::iterator membersEnd(){ return members.end(); } + bool HaveMember(uint64 guid) const; + + bool LoadArenaTeamFromDB(uint32 ArenaTeamId); + void LoadMembersFromDB(uint32 ArenaTeamId); + void LoadStatsFromDB(uint32 ArenaTeamId); + void LoadPlayerStats(ArenaTeamMember* member); + + void BroadcastPacket(WorldPacket *packet); + + void Roster(WorldSession *session); + void Query(WorldSession *session); + void Stats(WorldSession *session); + void InspectStats(WorldSession *session, uint64 guid); + + protected: + + uint32 Id; + uint32 Type; + std::string Name; + uint64 CaptainGuid; + + uint32 BackgroundColor; // ARGB format + uint32 EmblemStyle; // icon id + uint32 EmblemColor; // ARGB format + uint32 BorderStyle; // border image id + uint32 BorderColor; // ARGB format + + MemberList members; + ArenaTeamStats stats; +}; +#endif diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp new file mode 100644 index 000000000..c6b9059e7 --- /dev/null +++ b/src/game/ArenaTeamHandler.cpp @@ -0,0 +1,463 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "WorldSession.h" +#include "WorldPacket.h" +#include "Log.h" +#include "Database/DatabaseEnv.h" +#include "Player.h" +#include "ObjectMgr.h" +#include "ArenaTeam.h" +#include "World.h" +#include "SocialMgr.h" +#include "Language.h" + +void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data) +{ + sLog.outDebug("MSG_INSPECT_ARENA_TEAMS"); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 guid; + recv_data >> guid; + sLog.outDebug("Inspect Arena stats " I64FMTD, guid); + + if(Player *plr = objmgr.GetPlayer(guid)) + { + for (uint8 i = 0; i < MAX_ARENA_SLOT; i++) + { + if(uint32 a_id = plr->GetArenaTeamId(i)) + { + if(ArenaTeam *at = objmgr.GetArenaTeamById(a_id)) + at->InspectStats(this, plr->GetGUID()); + } + } + } +} + +void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data) +{ + sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" ); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4); + + uint32 ArenaTeamId; + recv_data >> ArenaTeamId; + + ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); + if(!arenateam) // arena team not found + return; + + arenateam->Query(this); + arenateam->Stats(this); +} + +void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data) +{ + sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" ); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4); + + uint32 ArenaTeamId; // arena team id + recv_data >> ArenaTeamId; + + ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); + if(!arenateam) + return; + + arenateam->Roster(this); +} + +void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data) +{ + sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER"); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4+1); + + uint32 ArenaTeamId; // arena team id + std::string Invitedname; + + Player * player = NULL; + + recv_data >> ArenaTeamId >> Invitedname; + + if(!Invitedname.empty()) + { + if(!normalizePlayerName(Invitedname)) + return; + + player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); + } + + if(!player) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); + return; + } + + if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + //SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S); + // can't find related opcode + SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName()); + return; + } + + ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); + if(!arenateam) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM); + return; + } + + // OK result but not send invite + if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + return; + + if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); + return; + } + + if(player->GetArenaTeamId(arenateam->GetSlot())) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S); + return; + } + + if(player->GetArenaTeamIdInvited()) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); + return; + } + + if(arenateam->GetMembersSize() >= arenateam->GetType() * 2) + { + // should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL +// SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL); + SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName()); + return; + } + + sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str()); + + player->SetArenaTeamIdInvited(arenateam->GetId()); + + WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); + data << GetPlayer()->GetName(); + data << arenateam->GetName(); + player->GetSession()->SendPacket(&data); + + sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE"); +} + +void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/) +{ + sLog.outDebug("CMSG_ARENA_TEAM_INVITE_ACCEPT"); // empty opcode + + ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited()); + if(!at) + { + // arena team not exist + return; + } + + if(_player->GetArenaTeamId(at->GetSlot())) + { + // already in arena team that size + return; + } + + // not let enemies sign petition + if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain())) + return; + + if(!at->AddMember(_player->GetGUID())) + return; + + // event + WorldPacket data; + BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), ""); + at->BroadcastPacket(&data); +} + +void WorldSession::HandleArenaTeamInviteDeclineOpcode(WorldPacket & /*recv_data*/) +{ + sLog.outDebug("CMSG_ARENA_TEAM_INVITE_DECLINE"); // empty opcode + + _player->SetArenaTeamIdInvited(0); // no more invited +} + +void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data) +{ + sLog.outDebug("CMSG_ARENA_TEAM_LEAVE"); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4); + + uint32 ArenaTeamId; // arena team id + recv_data >> ArenaTeamId; + + ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); + if(!at) + { + // send command result + return; + } + if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1) + { + // check for correctness + SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); + return; + } + // arena team has only one member (=captain) + if(_player->GetGUID() == at->GetCaptain()) + { + at->Disband(this); + delete at; + return; + } + + at->DelMember(_player->GetGUID()); + + // event + WorldPacket data; + BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), ""); + at->BroadcastPacket(&data); + + //SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0); +} + +void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data) +{ + sLog.outDebug("CMSG_ARENA_TEAM_DISBAND"); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4); + + uint32 ArenaTeamId; // arena team id + recv_data >> ArenaTeamId; + + ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); + if(!at) + { + // arena team not found + return; + } + + if(at->GetCaptain() != _player->GetGUID()) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); + return; + } + + at->Disband(this); + delete at; +} + +void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data) +{ + sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM"); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4+1); + + uint32 ArenaTeamId; + std::string name; + + recv_data >> ArenaTeamId; + recv_data >> name; + + ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); + if(!at) + { + // arena team not found + return; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + if(!guid) + { + // player guid not found + return; + } + + if(at->GetCaptain() == guid) + { + // unsure + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); + return; + } + + if(at->GetCaptain() != _player->GetGUID()) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); + return; + } + + if(at->GetCaptain() == guid) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); + return; + } + + at->DelMember(guid); + + // event + WorldPacket data; + BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName()); + at->BroadcastPacket(&data); +} + +void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data) +{ + sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN"); + //recv_data.hexlike(); + + CHECK_PACKET_SIZE(recv_data, 4+1); + + uint32 ArenaTeamId; + std::string name; + + recv_data >> ArenaTeamId; + recv_data >> name; + + ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); + if(!at) + { + // arena team not found + return; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + if(!guid) + { + // player guid not found + return; + } + + if(at->GetCaptain() == guid) + { + // target player already captain + return; + } + + if(at->GetCaptain() != _player->GetGUID()) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); + return; + } + + at->SetCaptain(guid); + + // event + WorldPacket data; + BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName()); + at->BroadcastPacket(&data); +} + +void WorldSession::SendArenaTeamCommandResult(uint32 unk1, std::string str1, std::string str2, uint32 unk3) +{ + WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+str1.length()+1+str2.length()+1+4); + data << unk1; + data << str1; + data << str2; + data << unk3; + SendPacket(&data); +} + +void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, std::string str1, std::string str2, std::string str3) +{ + data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1); + *data << eventid; + *data << str_count; + switch(str_count) + { + case 1: + *data << str1; + break; + case 2: + *data << str1; + *data << str2; + break; + case 3: + *data << str1; + *data << str2; + *data << str3; + break; + default: + sLog.outError("Unhandled str_count %u in SendArenaTeamEvent()", str_count); + return; + } +} + +void WorldSession::SendNotInArenaTeamPacket(uint8 type) +{ + WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team + uint32 unk = 0; + data << uint32(unk); // unk(0) + if(!unk) + data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types... + SendPacket(&data); +} + +/* ++ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team" + ++ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]." ++ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s" ++ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s" +ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]." + ++ERR_ARENA_TEAM_INTERNAL "Internal arena team error" ++ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size" ++ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size" ++ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team" ++ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team" ++ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name" ++ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\"" ++ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team" ++ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that" ++ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size" ++ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s" ++ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found" ++ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance" + ++ERR_ARENA_TEAM_JOIN_SS "%s has joined %s" ++ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]." + ++ERR_ARENA_TEAM_LEAVE_SS "%s has left %s" + ++ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s" ++ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s" + ++ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s" + ++ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s" + +ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team" + +ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full" + +ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team" +*/ diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp new file mode 100644 index 000000000..d85bc34bb --- /dev/null +++ b/src/game/AuctionHouse.cpp @@ -0,0 +1,747 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "UpdateMask.h" +#include "AuctionHouseObject.h" +#include "Util.h" + +//please DO NOT use iterator++, because it is slower than ++iterator!!! +//post-incrementation is always slower than pre-incrementation ! + +//void called when player click on auctioneer npc +void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; //NPC guid + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + SendAuctionHello(guid, unit); +} + +static uint8 AuctioneerFactionToLocation(uint32 faction) +{ + if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + return 7; // neutral + + FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(faction); + if(!u_entry) + return 7; // neutral + + if(u_entry->ourMask & FACTION_MASK_ALLIANCE) + return 2; + else if(u_entry->ourMask & FACTION_MASK_HORDE) + return 6; + else + return 7; +} + +//this void causes that auction window is opened +void WorldSession::SendAuctionHello( uint64 guid, Creature* unit ) +{ + WorldPacket data( MSG_AUCTION_HELLO, 12 ); + data << (uint64) guid; + data << (uint32) AuctioneerFactionToLocation(unit->getFaction()); + SendPacket( &data ); +} + +//this function inserts to WorldPacket auction's data +bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction) +{ + Item *pItem = objmgr.GetAItem(auction->item_guidlow); + if (!pItem) + { + sLog.outError("auction to item, that doesn't exist !!!!"); + return false; + } + data << (uint32) auction->Id; + data << (uint32) pItem->GetEntry(); + + for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) + { + data << (uint32) pItem->GetEnchantmentId(EnchantmentSlot(i)); + data << (uint32) pItem->GetEnchantmentDuration(EnchantmentSlot(i)); + data << (uint32) pItem->GetEnchantmentCharges(EnchantmentSlot(i)); + } + + data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id + data << (uint32) pItem->GetItemSuffixFactor(); //SuffixFactor + data << (uint32) pItem->GetCount(); //item->count + data << (uint32) pItem->GetSpellCharges(); //item->charge FFFFFFF + data << (uint32) 0; //Unknown + data << (uint64) auction->owner; //Auction->owner + data << (uint32) auction->startbid; //Auction->startbid (not sure if useful) + data << (uint32) ((auction->bid)? objmgr.GetAuctionOutBid(auction->bid) : 0); + //minimal outbid + data << (uint32) auction->buyout; //auction->buyout + data << (uint32) (auction->time - time(NULL)) * 1000; //time left + data << (uint64) auction->bidder; //auction->bidder current + data << (uint32) auction->bid; //current bid + return true; +} + +//call this method when player bids, creates, or deletes auction +void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError ) +{ + WorldPacket data( SMSG_AUCTION_COMMAND_RESULT, 16 ); + data << auctionId; + data << Action; + data << ErrorCode; + if ( !ErrorCode && Action ) + data << bidError; //when bid, then send 0, once... + SendPacket(&data); +} + +//this function sends notification, if bidder is online +void WorldSession::SendAuctionBidderNotification( uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template) +{ + WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4)); + data << location; + data << auctionId; + data << (uint64) bidder; + data << bidSum; + data << (uint32) diff; + data << item_template; + data << (uint32) 0; + SendPacket(&data); +} + +//this void causes on client to display: "Your auction sold" +void WorldSession::SendAuctionOwnerNotification( AuctionEntry* auction) +{ + WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (7*4)); + data << auction->Id; + data << auction->bid; + data << (uint32) 0; //unk + data << (uint32) 0; //unk + data << (uint32) 0; //unk + data << auction->item_template; + data << (uint32) 0; //unk + SendPacket(&data); +} + +//this function sends mail to old bidder +void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice) +{ + uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER); + Player *oldBidder = objmgr.GetPlayer(oldBidder_guid); + + uint32 oldBidder_accId = 0; + if(!oldBidder) + oldBidder_accId = objmgr.GetPlayerAccountIdByGUID(oldBidder_guid); + + // old bidder exist + if(oldBidder || oldBidder_accId) + { + std::ostringstream msgAuctionOutbiddedSubject; + msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED; + + if (oldBidder) + oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, objmgr.GetAuctionOutBid(auction->bid), auction->item_template); + + WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); + } +} + +//this function sends mail, when auction is cancelled to old bidder +void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction ) +{ + uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); + Player *bidder = objmgr.GetPlayer(bidder_guid); + + uint32 bidder_accId = 0; + if(!bidder) + bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid); + + // bidder exist + if(bidder || bidder_accId) + { + std::ostringstream msgAuctionCancelledSubject; + msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER; + + WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); + } +} + +//this void creates new auction and adds auction to some auctionhouse +void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+8+4+4+4); + + uint64 auctioneer, item; + uint32 etime, bid, buyout; + recv_data >> auctioneer >> item; + recv_data >> bid >> buyout >> etime; + Player *pl = GetPlayer(); + + if (!item || !bid || !etime) + return; //check for cheaters + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); + return; + } + + // client send time in minutes, convert to common used sec time + etime *= MINUTE; + + // client understand only 3 auction time + switch(etime) + { + case 1*MIN_AUCTION_TIME: + case 2*MIN_AUCTION_TIME: + case 4*MIN_AUCTION_TIME: + break; + default: + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + Item *it = pl->GetItemByGuid( item ); + //do not allow to sell already auctioned items + if(objmgr.GetAItem(GUID_LOPART(item))) + { + sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item)); + SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); + return; + } + // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction) + if(!it) + { + SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND); + return; + } + + if(!it->CanBeTraded()) + { + SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); + return; + } + + if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) + { + SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); + return; + } + + uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); + AuctionHouseObject * mAuctions; + mAuctions = objmgr.GetAuctionsMap( location ); + + //we have to take deposit : + uint32 deposit = objmgr.GetAuctionDeposit( location, etime, it ); + if ( pl->GetMoney() < deposit ) + { + SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); + return; + } + + if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + { + sLog.outCommand("GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", + GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount()); + } + + pl->ModifyMoney( -int32(deposit) ); + + uint32 auction_time = uint32(etime * sWorld.getRate(RATE_AUCTION_TIME)); + + AuctionEntry *AH = new AuctionEntry; + AH->Id = objmgr.GenerateAuctionID(); + AH->auctioneer = GUID_LOPART(auctioneer); + AH->item_guidlow = GUID_LOPART(item); + AH->item_template = it->GetEntry(); + AH->owner = pl->GetGUIDLow(); + AH->startbid = bid; + AH->bidder = 0; + AH->bid = 0; + AH->buyout = buyout; + AH->time = time(NULL) + auction_time; + AH->deposit = deposit; + AH->location = location; + + sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in location: %u", GUID_LOPART(item), GUID_LOPART(auctioneer), bid, buyout, auction_time, location); + mAuctions->AddAuction(AH); + + objmgr.AddAItem(it); + pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true); + + CharacterDatabase.BeginTransaction(); + it->DeleteFromInventoryDB(); + it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone + CharacterDatabase.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location) " + "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u')", + AH->Id, AH->auctioneer, AH->item_guidlow, AH->item_template, AH->owner, AH->buyout, (uint64)AH->time, AH->bidder, AH->bid, AH->startbid, AH->deposit, AH->location); + pl->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); + + SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); +} + +//this function is called when client bids or buys out auction +void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + uint64 auctioneer; + uint32 auctionId; + uint32 price; + recv_data >> auctioneer; + recv_data >> auctionId >> price; + + if (!auctionId || !price) + return; //check for cheaters + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); + + AuctionHouseObject * mAuctions; + mAuctions = objmgr.GetAuctionsMap( location ); + + AuctionEntry *auction = mAuctions->GetAuction(auctionId); + Player *pl = GetPlayer(); + + if( !auction || auction->owner == pl->GetGUIDLow() ) + { + //you cannot bid your own auction: + SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); + return; + } + + // impossible have online own another character (use this for speedup check in case online owner) + Player* auction_owner = objmgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)); + if( !auction_owner && objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId()) + { + //you cannot bid your another character auction: + SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); + return; + } + + if (price < (auction->bid + objmgr.GetAuctionOutBid(auction->bid))) + { + //auction has already higher bid, client tests it! + //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); + return; + } + + if (price > pl->GetMoney()) + { + //you don't have enought money!, client tests! + //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); + return; + } + + if ((price < auction->buyout) || (auction->buyout == 0)) + { + if (auction->bidder > 0) + { + if ( auction->bidder == pl->GetGUIDLow() ) + { + pl->ModifyMoney( -int32(price - auction->bid)); + } + else + { + // mail to last bidder and return money + SendAuctionOutbiddedMail( auction , price ); + pl->ModifyMoney( -int32(price) ); + } + } + else + { + pl->ModifyMoney( -int32(price) ); + } + auction->bidder = pl->GetGUIDLow(); + auction->bid = price; + + // after this update we should save player's money ... + CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); + + SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0 ); + } + else + { + //buyout: + if (pl->GetGUIDLow() == auction->bidder ) + { + pl->ModifyMoney(-int32(auction->buyout - auction->bid)); + } + else + { + pl->ModifyMoney(-int32(auction->buyout)); + if ( auction->bidder ) //buyout for bidded auction .. + { + SendAuctionOutbiddedMail( auction, auction->buyout ); + } + } + auction->bidder = pl->GetGUIDLow(); + auction->bid = auction->buyout; + + objmgr.SendAuctionSalePendingMail( auction ); + objmgr.SendAuctionSuccessfulMail( auction ); + objmgr.SendAuctionWonMail( auction ); + + SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); + + objmgr.RemoveAItem(auction->item_guidlow); + mAuctions->RemoveAuction(auction->Id); + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id); + + delete auction; + } + CharacterDatabase.BeginTransaction(); + pl->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); +} + +//this void is called when auction_owner cancels his auction +void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 auctioneer; + uint32 auctionId; + recv_data >> auctioneer; + recv_data >> auctionId; + //sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId); + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); + + AuctionHouseObject * mAuctions; + mAuctions = objmgr.GetAuctionsMap( location ); + + AuctionEntry *auction = mAuctions->GetAuction(auctionId); + Player *pl = GetPlayer(); + + if (auction && auction->owner == pl->GetGUIDLow()) + { + Item *pItem = objmgr.GetAItem(auction->item_guidlow); + if (pItem) + { + if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid + { + uint32 auctionCut = objmgr.GetAuctionCut( auction->location, auction->bid); + if ( pl->GetMoney() < auctionCut ) //player doesn't have enough money, maybe message needed + return; + //some auctionBidderNotification would be needed, but don't know that parts.. + SendAuctionCancelledToBidderMail( auction ); + pl->ModifyMoney( -int32(auctionCut) ); + } + // Return the item by mail + std::ostringstream msgAuctionCanceledOwner; + msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED; + + MailItemsInfo mi; + mi.AddItem(auction->item_guidlow, auction->item_template, pItem); + + // item will deleted or added to received mail list + WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); + } + else + { + sLog.outError("Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->item_guidlow); + SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR ); + return; + } + } + else + { + SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR ); + //this code isn't possible ... maybe there should be assert + sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId ); + return; + } + + //inform player, that auction is removed + SendAuctionCommandResult( auction->Id, AUCTION_CANCEL, AUCTION_OK ); + // Now remove the auction + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id); + pl->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); + objmgr.RemoveAItem( auction->item_guidlow ); + mAuctions->RemoveAuction( auction->Id ); + delete auction; +} + +//called when player lists his bids +void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + uint64 guid; //NPC guid + uint32 listfrom; //page of auctions + uint32 outbiddedCount; //count of outbidded auctions + + recv_data >> guid; + recv_data >> listfrom; // not used in fact (this list not have page control in client) + recv_data >> outbiddedCount; + if (recv_data.size() != (16 + outbiddedCount * 4 )) + { + sLog.outError("Client sent bad opcode!!! with count: %u and size : %d (mustbe: %d", outbiddedCount, recv_data.size(),(16 + outbiddedCount * 4 )); + outbiddedCount = 0; + } + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); + AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location ); + + WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) ); + Player *pl = GetPlayer(); + data << (uint32) 0; //add 0 as count + uint32 count = 0; + uint32 totalcount = 0; + while ( outbiddedCount > 0) //add all data, which client requires + { + --outbiddedCount; + uint32 outbiddedAuctionId; + recv_data >> outbiddedAuctionId; + AuctionEntry * auction = mAuctions->GetAuction( outbiddedAuctionId ); + if ( auction && SendAuctionInfo(data, auction)) + { + ++totalcount; + ++count; + } + } + for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) + { + AuctionEntry *Aentry = itr->second; + if( Aentry && Aentry->bidder == pl->GetGUIDLow() ) + { + if (SendAuctionInfo(data, itr->second)) + ++count; + ++totalcount; + } + } + data.put( 0, count ); // add count to placeholder + data << totalcount; + data << (uint32)300; //unk 2.3.0 + SendPacket(&data); +} + +//this void sends player info about his auctions +void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint32 listfrom; + uint64 guid; + + recv_data >> guid; + recv_data >> listfrom; // not used in fact (this list not have page control in client) + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + uint32 location = AuctioneerFactionToLocation(pCreature->getFaction()); + + AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location ); + + WorldPacket data( SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4) ); + data << (uint32) 0; // amount place holder + + uint32 count = 0; + uint32 totalcount = 0; + for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) + { + AuctionEntry *Aentry = itr->second; + if( Aentry && Aentry->owner == _player->GetGUIDLow() ) + { + if(SendAuctionInfo(data, itr->second)) + ++count; + ++totalcount; + } + } + data.put(0, count); + data << (uint32) totalcount; + data << (uint32) 0; + SendPacket(&data); +} + +//this void is called when player clicks on search button +void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+1+1+1+4+4+4+4+1); + + std::string searchedname, name; + uint8 levelmin, levelmax, usable, location; + uint32 count, totalcount, listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; + uint64 guid; + + recv_data >> guid; + recv_data >> listfrom; // start, used for page control listing by 50 elements + recv_data >> searchedname; + + // recheck with known string size + CHECK_PACKET_SIZE(recv_data,8+4+(searchedname.size()+1)+1+1+4+4+4+4+1); + + recv_data >> levelmin >> levelmax; + recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; + recv_data >> quality >> usable; + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_AUCTIONEER); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + location = AuctioneerFactionToLocation(pCreature->getFaction()); + AuctionHouseObject * mAuctions; + mAuctions = objmgr.GetAuctionsMap( location ); + + //sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); + + WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) ); + count = 0; + totalcount = 0; + data << (uint32) 0; + + // converting string that we try to find to lower case + std::wstring wsearchedname; + if(!Utf8toWStr(searchedname,wsearchedname)) + return; + + wstrToLower(wsearchedname); + + for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr) + { + AuctionEntry *Aentry = itr->second; + Item *item = objmgr.GetAItem(Aentry->item_guidlow); + if( item ) + { + ItemPrototype const *proto = item->GetProto(); + if( proto ) + { + if( auctionMainCategory == (0xffffffff) || proto->Class == auctionMainCategory ) + { + if( auctionSubCategory == (0xffffffff) || proto->SubClass == auctionSubCategory ) + { + if( auctionSlotID == (0xffffffff) || proto->InventoryType == auctionSlotID ) + { + if( quality == (0xffffffff) || proto->Quality == quality ) + { + if( usable == (0x00) || _player->CanUseItem( item ) == EQUIP_ERR_OK ) + { + if( ( levelmin == (0x00) || proto->RequiredLevel >= levelmin ) && ( levelmax == (0x00) || proto->RequiredLevel <= levelmax ) ) + { + name = proto->Name1; + + // local name + int loc_idx = GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + { + ItemLocale const *il = objmgr.GetItemLocale(proto->ItemId); + if (il) + { + if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + name = il->Name[loc_idx]; + } + } + + if(name.empty()) + continue; + + if( wsearchedname.empty() || Utf8FitTo(name, wsearchedname) ) + { + if ((count < 50) && (totalcount >= listfrom)) + { + ++count; + SendAuctionInfo( data, Aentry); + } + ++totalcount; + } + } + } + } + } + } + } + } + } + } + data.put(0, count); + data << (uint32) totalcount; + data << (uint32) 300; // unk 2.3.0 const? + SendPacket(&data); +} diff --git a/src/game/AuctionHouseObject.h b/src/game/AuctionHouseObject.h new file mode 100644 index 000000000..5cc51692c --- /dev/null +++ b/src/game/AuctionHouseObject.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AUCTION_HOUSE_H +#define _AUCTION_HOUSE_H + +#include "SharedDefines.h" + +#define MIN_AUCTION_TIME (12*HOUR) + +enum AuctionError +{ + AUCTION_OK = 0, + AUCTION_INTERNAL_ERROR = 2, + AUCTION_NOT_ENOUGHT_MONEY = 3, + AUCTION_ITEM_NOT_FOUND = 4, + CANNOT_BID_YOUR_AUCTION_ERROR = 10 +}; + +enum AuctionAction +{ + AUCTION_SELL_ITEM = 0, + AUCTION_CANCEL = 1, + AUCTION_PLACE_BID = 2 +}; + +struct AuctionEntry +{ + uint32 Id; + uint32 auctioneer; + uint32 item_guidlow; + uint32 item_template; + uint32 owner; + uint32 startbid; //maybe useless + uint32 bid; + uint32 buyout; + time_t time; + uint32 bidder; + uint32 deposit; //deposit can be calculated only when creating auction + uint32 location; +}; + +//this class is used as auctionhouse instance +class AuctionHouseObject +{ + public: + AuctionHouseObject() {} + ~AuctionHouseObject() + { + for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) + delete itr->second; + } + + typedef std::map AuctionEntryMap; + + uint32 Getcount() { return AuctionsMap.size(); } + + AuctionEntryMap::iterator GetAuctionsBegin() {return AuctionsMap.begin();} + AuctionEntryMap::iterator GetAuctionsEnd() {return AuctionsMap.end();} + + void AddAuction(AuctionEntry *ah) + { + ASSERT( ah ); + AuctionsMap[ah->Id] = ah; + } + + AuctionEntry* GetAuction(uint32 id) const + { + AuctionEntryMap::const_iterator itr = AuctionsMap.find( id ); + if( itr != AuctionsMap.end() ) + return itr->second; + return NULL; + } + + bool RemoveAuction(uint32 id) + { + AuctionEntryMap::iterator i = AuctionsMap.find(id); + if (i == AuctionsMap.end()) + { + return false; + } + AuctionsMap.erase(i); + return true; + } + + private: + AuctionEntryMap AuctionsMap; +}; +#endif diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp new file mode 100644 index 000000000..6345ff4d5 --- /dev/null +++ b/src/game/Bag.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Bag.h" +#include "ObjectMgr.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "WorldPacket.h" +#include "UpdateData.h" +#include "WorldSession.h" + +Bag::Bag( ): Item() +{ + m_objectType |= TYPEMASK_CONTAINER; + m_objectTypeId = TYPEID_CONTAINER; + + m_valuesCount = CONTAINER_END; + + memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); // Maximum 20 Slots +} + +Bag::~Bag() +{ + for(int i = 0; iAddToWorld(); + } +} + +void Bag::RemoveFromWorld() +{ + for(int i = 0; iRemoveFromWorld(); + } + + Item::RemoveFromWorld(); +} + +bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner) +{ + ItemPrototype const * itemProto = objmgr.GetItemPrototype(itemid); + + if(!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE) + return false; + + Object::_Create( guidlow, 0, HIGHGUID_CONTAINER ); + + SetEntry(itemid); + SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); + + SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0); + SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0); + + SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability); + SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability); + SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags); + SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1); + + // Setting the number of Slots the Container has + SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots); + + // Cleaning 20 slots + for (uint8 i = 0; i < MAX_BAG_SIZE; i++) + { + SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0); + m_bagslot[i] = NULL; + } + + return true; +} + +void Bag::SaveToDB() +{ + Item::SaveToDB(); +} + +bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) +{ + if(!Item::LoadFromDB(guid, owner_guid, result)) + return false; + + // cleanup bag content related item value fields (its will be filled correctly from `character_inventory`) + for (uint32 i = 0; i < GetProto()->ContainerSlots; i++) + { + SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0); + if (m_bagslot[i]) + { + delete m_bagslot[i]; + m_bagslot[i] = NULL; + } + } + + return true; +} + +void Bag::DeleteFromDB() +{ + for (int i = 0; i < MAX_BAG_SIZE; i++) + { + if (m_bagslot[i]) + { + m_bagslot[i]->DeleteFromDB(); + } + } + + Item::DeleteFromDB(); +} + +uint32 Bag::GetFreeSlots() const +{ + uint32 ContainerSlots=GetProto()->ContainerSlots; + uint32 slots = 0; + for (uint8 i=0; i SetContainer(NULL); + + m_bagslot[slot] = NULL; + SetUInt64Value( CONTAINER_FIELD_SLOT_1 + (slot * 2), 0 ); +} + +void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ ) +{ + assert(slot < MAX_BAG_SIZE); + + if( pItem ) + { + m_bagslot[slot] = pItem; + SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (slot * 2), pItem->GetGUID()); + pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, GetGUID()); + pItem->SetUInt64Value( ITEM_FIELD_OWNER, GetOwnerGUID() ); + pItem->SetContainer(this); + pItem->SetSlot(slot); + } +} + +void Bag::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const +{ + Item::BuildCreateUpdateBlockForPlayer( data, target ); + + for (int i = 0; i < MAX_BAG_SIZE; i++) + { + if(m_bagslot[i]) + m_bagslot[i]->BuildCreateUpdateBlockForPlayer( data, target ); + } +} + +// If the bag is empty returns true +bool Bag::IsEmpty() const +{ + uint32 ContainerSlots=GetProto()->ContainerSlots; + for(uint32 i=0; i < ContainerSlots; i++) + if (m_bagslot[i]) return false; + + return true; +} + +uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const +{ + uint32 ContainerSlots=GetProto()->ContainerSlots; + + Item *pItem; + uint32 count = 0; + for(uint32 i=0; i < ContainerSlots; i++) + { + pItem = m_bagslot[i]; + if( pItem && pItem != eItem && pItem->GetEntry() == item ) + count += pItem->GetCount(); + } + + if(eItem && eItem->GetProto()->GemProperties) + { + for(uint32 i=0; i < ContainerSlots; i++) + { + pItem = m_bagslot[i]; + if( pItem && pItem != eItem && pItem->GetProto()->Socket[0].Color ) + count += pItem->GetGemCountWithID(item); + } + } + + return count; +} + +uint8 Bag::GetSlotByItemGUID(uint64 guid) const +{ + uint32 ContainerSlots=GetProto()->ContainerSlots; + + for(uint32 i=0;iGetGUID() == guid) + return i; + } + return NULL_SLOT; +} + +// Adds an item to a bag slot +// - slot can be NULL_SLOT, in that case function searchs for a free slot +// - Return values: 0 - item not added +// 1 - item added to a free slot (and perhaps to a stack) +// 2 - item added to a stack (item should be deleted) +Item* Bag::GetItemByPos( uint8 slot ) const +{ + ItemPrototype const *pBagProto = GetProto(); + if( pBagProto ) + { + if( slot < pBagProto->ContainerSlots ) + return m_bagslot[slot]; + } + return NULL; +} diff --git a/src/game/Bag.h b/src/game/Bag.h new file mode 100644 index 000000000..07ae17341 --- /dev/null +++ b/src/game/Bag.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_BAG_H +#define MANGOS_BAG_H + +// Maximum 36 Slots ( (CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2 +#define MAX_BAG_SIZE 36 // 2.0.12 + +#include "Object.h" +#include "ItemPrototype.h" +#include "Unit.h" +#include "Creature.h" +#include "Item.h" + +class Bag : public Item +{ + public: + + Bag(); + ~Bag(); + + void AddToWorld(); + void RemoveFromWorld(); + + bool Create(uint32 guidlow, uint32 itemid, Player const* owner); + + void Clear(); + void StoreItem( uint8 slot, Item *pItem, bool update ); + void RemoveItem( uint8 slot, bool update ); + + Item* GetItemByPos( uint8 slot ) const; + uint32 GetItemCount( uint32 item, Item* eItem = NULL ) const; + + uint8 GetSlotByItemGUID(uint64 guid) const; + bool IsEmpty() const; + uint32 GetFreeSlots() const; + + // DB operations + // overwrite virtual Item::SaveToDB + void SaveToDB(); + // overwrite virtual Item::LoadFromDB + bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL); + // overwrite virtual Item::DeleteFromDB + void DeleteFromDB(); + + void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const; + + protected: + + // Bag Storage space + Item* m_bagslot[MAX_BAG_SIZE]; +}; + +inline Item* NewItemOrBag(ItemPrototype const * proto) +{ + return (proto->InventoryType == INVTYPE_BAG) ? new Bag : new Item; +} +#endif diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp new file mode 100644 index 000000000..dd199e2ed --- /dev/null +++ b/src/game/BattleGround.cpp @@ -0,0 +1,1153 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "Creature.h" +#include "MapManager.h" +#include "Language.h" +#include "Chat.h" +#include "SpellAuras.h" +#include "World.h" +#include "Util.h" + +BattleGround::BattleGround() +{ + m_TypeID = 0; + m_InstanceID = 0; + m_Status = 0; + m_EndTime = 0; + m_LastResurrectTime = 0; + m_Queue_type = MAX_BATTLEGROUND_QUEUES; + m_InvitedAlliance = 0; + m_InvitedHorde = 0; + m_ArenaType = 0; + m_IsArena = false; + m_Winner = 2; + m_StartTime = 0; + m_Events = 0; + m_IsRated = false; + m_BuffChange = false; + m_Name = ""; + m_LevelMin = 0; + m_LevelMax = 0; + + m_MaxPlayersPerTeam = 0; + m_MaxPlayers = 0; + m_MinPlayersPerTeam = 0; + m_MinPlayers = 0; + + m_MapId = 0; + + m_TeamStartLocX[BG_TEAM_ALLIANCE] = 0; + m_TeamStartLocX[BG_TEAM_HORDE] = 0; + + m_TeamStartLocY[BG_TEAM_ALLIANCE] = 0; + m_TeamStartLocY[BG_TEAM_HORDE] = 0; + + m_TeamStartLocZ[BG_TEAM_ALLIANCE] = 0; + m_TeamStartLocZ[BG_TEAM_HORDE] = 0; + + m_TeamStartLocO[BG_TEAM_ALLIANCE] = 0; + m_TeamStartLocO[BG_TEAM_HORDE] = 0; + + m_BgRaids[BG_TEAM_ALLIANCE] = NULL; + m_BgRaids[BG_TEAM_HORDE] = NULL; + + m_PlayersCount[BG_TEAM_ALLIANCE] = 0; + m_PlayersCount[BG_TEAM_HORDE] = 0; +} + +BattleGround::~BattleGround() +{ + +} + +void BattleGround::Update(time_t diff) +{ + + if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) + //BG is empty + return; + + WorldPacket data; + + if(GetRemovedPlayersSize()) + { + for(std::map::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + switch(itr->second) + { + //following code is handled by event: + /*case 0: + sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].RemovePlayer(itr->first); + //RemovePlayerFromQueue(itr->first); + if(plr) + { + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); + plr->GetSession()->SendPacket(&data); + } + break;*/ + case 1: // currently in bg and was removed from bg + if(plr) + RemovePlayerAtLeave(itr->first, true, true); + else + RemovePlayerAtLeave(itr->first, false, false); + break; + case 2: // revive queue + RemovePlayerFromResurrectQueue(itr->first); + break; + default: + sLog.outError("BattleGround: Unknown remove player case!"); + } + } + m_RemovedPlayers.clear(); + } + + // this code isn't efficient and its idea isn't implemented yet + /* offline players are removed from battleground in worldsession::LogoutPlayer() + // remove offline players from bg after ~5 minutes + if(GetPlayersSize()) + { + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + itr->second.LastOnlineTime += diff; + + if(plr) + itr->second.LastOnlineTime = 0; // update last online time + else + if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes + m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) + } + }*/ + + m_LastResurrectTime += diff; + if (m_LastResurrectTime >= RESURRECTION_INTERVAL) + { + if(GetReviveQueueSize()) + { + for(std::map >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) + { + Creature *sh = NULL; + for(std::vector::iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2) + { + Player *plr = objmgr.GetPlayer(*itr2); + if(!plr) + continue; + + if (!sh) + { + sh = ObjectAccessor::GetCreature(*plr, itr->first); + // only for visual effect + if (sh) + sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); // Spirit Heal, effect 117 + } + + plr->CastSpell(plr, SPELL_RESURRECTION_VISUAL, true); // Resurrection visual + m_ResurrectQueue.push_back(*itr2); + } + (itr->second).clear(); + } + + m_ReviveQueue.clear(); + m_LastResurrectTime = 0; + } + else + // queue is clear and time passed, just update last resurrection time + m_LastResurrectTime = 0; + } + else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC + { + for(std::vector::iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(*itr); + if(!plr) + continue; + plr->ResurrectPlayer(1.0f); + plr->CastSpell(plr, SPELL_SPIRIT_HEAL_MANA, true); + ObjectAccessor::Instance().ConvertCorpseForPlayer(*itr); + } + m_ResurrectQueue.clear(); + } + + if(GetStatus() == STATUS_WAIT_LEAVE) + { + // remove all players from battleground after 2 minutes + m_EndTime += diff; + if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes + { + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + m_RemovedPlayers[itr->first] = 1; // add to remove list (BG) + } + // do not change any battleground's private variables + } + } +} + +void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O) +{ + uint8 idx = GetTeamIndexByTeamId(TeamID); + m_TeamStartLocX[idx] = X; + m_TeamStartLocY[idx] = Y; + m_TeamStartLocZ[idx] = Z; + m_TeamStartLocO[idx] = O; +} + +void BattleGround::SendPacketToAll(WorldPacket *packet) +{ + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + if(plr) + plr->GetSession()->SendPacket(packet); + else + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + } +} + +void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender, bool self) +{ + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + + if(!self && sender == plr) + continue; + + if(plr->GetTeam() == TeamID) + plr->GetSession()->SendPacket(packet); + } +} + +void BattleGround::PlaySoundToAll(uint32 SoundID) +{ + WorldPacket data; + sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID); + SendPacketToAll(&data); +} + +void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID) +{ + WorldPacket data; + + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + + if(plr->GetTeam() == TeamID) + { + sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID); + plr->GetSession()->SendPacket(&data); + } + } +} + +void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID) +{ + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + + if(plr->GetTeam() == TeamID) + plr->CastSpell(plr, SpellID, true); + } +} + +void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID) +{ + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + + if(plr->GetTeam() == TeamID) + UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor); + } +} + +void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID) +{ + FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); + + if(!factionEntry) + return; + + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + + if(plr->GetTeam() == TeamID) + plr->ModifyFactionReputation(factionEntry, Reputation); + } +} + +void BattleGround::UpdateWorldState(uint32 Field, uint32 Value) +{ + WorldPacket data; + sBattleGroundMgr.BuildUpdateWorldStatePacket(&data, Field, Value); + SendPacketToAll(&data); +} + +void BattleGround::UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source) +{ + WorldPacket data; + sBattleGroundMgr.BuildUpdateWorldStatePacket(&data, Field, Value); + Source->GetSession()->SendPacket(&data); +} + +void BattleGround::EndBattleGround(uint32 winner) +{ + WorldPacket data; + Player *Source = NULL; + const char *winmsg = ""; + + if(winner == ALLIANCE) + { + winmsg = GetMangosString(LANG_BG_A_WINS); + + PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound + + SetWinner(WINNER_ALLIANCE); + } + else + { + winmsg = GetMangosString(LANG_BG_H_WINS); + + PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound + + SetWinner(WINNER_HORDE); + } + + SetStatus(STATUS_WAIT_LEAVE); + m_EndTime = 0; + + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + + if(!plr->isAlive()) + { + plr->ResurrectPlayer(1.0f); + plr->SpawnCorpseBones(); + } + + if(plr->GetTeam() == winner) + { + if(!Source) + Source = plr; + RewardMark(plr,ITEM_WINNER_COUNT); + UpdatePlayerScore(plr, SCORE_BONUS_HONOR, 20); + RewardQuest(plr); + } + else + { + RewardMark(plr,ITEM_LOSER_COUNT); + } + + plr->CombatStopWithPets(true); + + BlockMovement(plr); + + sBattleGroundMgr.BuildPvpLogDataPacket(&data, this); + plr->GetSession()->SendPacket(&data); + + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); + plr->GetSession()->SendPacket(&data); + } + + if(Source) + { + ChatHandler(Source).FillMessageData(&data, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, Source->GetGUID(), winmsg); + SendPacketToAll(&data); + } +} + +uint32 BattleGround::GetBattlemasterEntry() const +{ + switch(GetTypeID()) + { + case BATTLEGROUND_AV: return 15972; + case BATTLEGROUND_WS: return 14623; + case BATTLEGROUND_AB: return 14879; + case BATTLEGROUND_EY: return 22516; + case BATTLEGROUND_NA: return 20200; + default: return 0; + } +} + +void BattleGround::RewardMark(Player *plr,uint32 count) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if(plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return; + + BattleGroundMarks mark; + bool IsSpell; + switch(GetTypeID()) + { + case BATTLEGROUND_AV: + IsSpell = true; + if(count == ITEM_WINNER_COUNT) + mark = SPELL_AV_MARK_WINNER; + else + mark = SPELL_AV_MARK_LOSER; + break; + case BATTLEGROUND_WS: + IsSpell = true; + if(count == ITEM_WINNER_COUNT) + mark = SPELL_WS_MARK_WINNER; + else + mark = SPELL_WS_MARK_LOSER; + break; + case BATTLEGROUND_AB: + IsSpell = true; + if(count == ITEM_WINNER_COUNT) + mark = SPELL_AB_MARK_WINNER; + else + mark = SPELL_AB_MARK_LOSER; + break; + case BATTLEGROUND_EY: + IsSpell = false; + mark = ITEM_EY_MARK_OF_HONOR; + break; + default: + return; + } + + if(IsSpell) + plr->CastSpell(plr, mark, true); + else if ( objmgr.GetItemPrototype( mark ) ) + { + ItemPosCountVec dest; + uint32 no_space_count = 0; + uint8 msg = plr->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, mark, count, &no_space_count ); + if( msg != EQUIP_ERR_OK ) // convert to possible store amount + count -= no_space_count; + + if( count != 0 && !dest.empty()) // can add some + if(Item* item = plr->StoreNewItem( dest, mark, true, 0)) + plr->SendNewItem(item,count,false,true); + + if(no_space_count > 0) + SendRewardMarkByMail(plr,mark,no_space_count); + } +} + +void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) +{ + uint32 bmEntry = GetBattlemasterEntry(); + if(!bmEntry) + return; + + ItemPrototype const* markProto = objmgr.GetItemPrototype(mark); + if(!markProto) + return; + + if(Item* markItem = Item::CreateItem(mark,count,plr)) + { + // save new item before send + markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted + + // item + MailItemsInfo mi; + mi.AddItem(markItem->GetGUIDLow(), markItem->GetEntry(), markItem); + + // subject: item name + std::string subject = markProto->Name1; + int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + if(ItemLocale const *il = objmgr.GetItemLocale(markProto->ItemId)) + if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + subject = il->Name[loc_idx]; + + // text + std::string textFormat = plr->GetSession()->GetMangosString(LANG_BG_MARK_BY_MAIL); + char textBuf[300]; + snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName()); + uint32 itemTextId = objmgr.CreateItemText( textBuf ); + + WorldSession::SendMailTo(plr, MAIL_CREATURE, MAIL_STATIONERY_NORMAL, bmEntry, plr->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE); + } +} + +void BattleGround::RewardQuest(Player *plr) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if(plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return; + + uint32 quest; + switch(GetTypeID()) + { + case BATTLEGROUND_AV: + quest = SPELL_AV_QUEST_REWARD; + break; + case BATTLEGROUND_WS: + quest = SPELL_WS_QUEST_REWARD; + break; + case BATTLEGROUND_AB: + quest = SPELL_AB_QUEST_REWARD; + break; + case BATTLEGROUND_EY: + quest = SPELL_EY_QUEST_REWARD; + break; + default: + return; + } + + plr->CastSpell(plr, quest, true); +} + +void BattleGround::BlockMovement(Player *plr) +{ + plr->SetClientControl(plr, 0); // movement disabled NOTE: the effect will be automatically removed by client when the player is teleported from the battleground, so no need to send with uint8(1) in RemovePlayerAtLeave() +} + +void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket) +{ + // Remove from lists/maps + std::map::iterator itr = m_Players.find(guid); + if(itr != m_Players.end()) + { + UpdatePlayersCountByTeam(itr->second.Team, true); // -1 player + m_Players.erase(itr); + } + + std::map::iterator itr2 = m_PlayerScores.find(guid); + if(itr2 != m_PlayerScores.end()) + { + delete itr2->second; // delete player's score + m_PlayerScores.erase(itr2); + } + + RemovePlayerFromResurrectQueue(guid); + + Player *plr = objmgr.GetPlayer(guid); + + if(plr && !plr->isAlive()) // resurrect on exit + { + plr->ResurrectPlayer(1.0f); + plr->SpawnCorpseBones(); + } + + RemovePlayer(plr, guid); // BG subclass specific code + + if(plr) + { + plr->ClearAfkReports(); + + if(isArena()) + { + if(!sWorld.IsFFAPvPRealm()) + plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); + } + + WorldPacket data; + if(SendPacket) + { + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); + plr->GetSession()->SendPacket(&data); + } + + // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg + plr->RemoveBattleGroundQueueId(m_TypeID); + + DecreaseInvitedCount(plr->GetTeam()); + //we should update battleground queue, but only if bg isn't ending + if (GetQueueType() < MAX_BATTLEGROUND_QUEUES) + sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].Update(GetTypeID(), GetQueueType()); + + if(!plr->GetBattleGroundId()) + return; + + Group * group = plr->GetGroup(); + + // remove from raid group if exist + if(group && group == GetBgRaid(plr->GetTeam())) + { + if(!group->RemoveMember(guid, 0)) // group was disbanded + { + SetBgRaid(plr->GetTeam(), NULL); + delete group; + } + } + + // Do next only if found in battleground + plr->SetBattleGroundId(0); // We're not in BG. + + // Let others know + sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr); + SendPacketToTeam(plr->GetTeam(), &data, plr, false); + + if(Transport) + { + plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO()); + //sLog.outDetail("BATTLEGROUND: Sending %s to %f,%f,%f,%f", pl->GetName(), x,y,z,O); + } + + // Log + sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName()); + } + + /// there will be code which will add battleground to BGFreeSlotQueue , when battleground instance will exist + // we always should check if BG is in that queue before adding.. + + if(!GetPlayersSize()) + { + Reset(); + } +} + +// this method is called when no players remains in battleground +void BattleGround::Reset() +{ + SetQueueType(MAX_BATTLEGROUND_QUEUES); + SetWinner(WINNER_NONE); + SetStatus(STATUS_WAIT_QUEUE); + SetStartTime(0); + SetEndTime(0); + SetLastResurrectTime(0); + + m_Events = 0; + + if (m_InvitedAlliance > 0 || m_InvitedHorde > 0) + sLog.outError("BattleGround system ERROR: bad counter, m_InvitedAlliance: %d, m_InvitedHorde: %d", m_InvitedAlliance, m_InvitedHorde); + + m_InvitedAlliance = 0; + m_InvitedHorde = 0; + + m_Players.clear(); + m_PlayerScores.clear(); + + // reset BGSubclass + this->ResetBGSubclass(); +} + +void BattleGround::StartBattleGround() +{ + ///this method should spawn spirit guides and so on + SetStartTime(0); + + SetLastResurrectTime(0); +} + +void BattleGround::AddPlayer(Player *plr) +{ + // score struct must be created in inherited class + + uint64 guid = plr->GetGUID(); + uint32 team = plr->GetBGTeam(); + + BattleGroundPlayer bp; + bp.LastOnlineTime = 0; + bp.Team = team; + + // Add to list/maps + m_Players[guid] = bp; + + UpdatePlayersCountByTeam(team, false); // +1 player + + WorldPacket data; + sBattleGroundMgr.BuildPlayerJoinedBattleGroundPacket(&data, plr); + SendPacketToTeam(team, &data, plr, false); + + if(isArena()) + { + plr->RemoveArenaSpellCooldowns(); + //plr->RemoveArenaAuras(); + plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT); + if(team == ALLIANCE && plr->GetTeam() == ALLIANCE) + plr->CastSpell(plr,SPELL_ALLIANCE_GOLD_FLAG,true); + else if(team == HORDE && plr->GetTeam() == ALLIANCE) + plr->CastSpell(plr,SPELL_ALLIANCE_GREEN_FLAG,true); + else if(team == ALLIANCE && plr->GetTeam() == HORDE) + plr->CastSpell(plr,SPELL_HORDE_GOLD_FLAG,true); + else + plr->CastSpell(plr,SPELL_HORDE_GREEN_FLAG,true); + plr->DestroyConjuredItems(true); + + if(GetStatus() == STATUS_WAIT_JOIN) // not started yet + { + plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true); + + plr->SetHealth(plr->GetMaxHealth()); + plr->SetPower(POWER_MANA, plr->GetMaxPower(POWER_MANA)); + } + } + else + { + if(GetStatus() == STATUS_WAIT_JOIN) // not started yet + plr->CastSpell(plr, SPELL_PREPARATION, true); // reduces all mana cost of spells. + } + + if(isArena()) + plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); + + // Log + sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName()); +} + +/* This method should be called only once ... it adds pointer to queue */ +void BattleGround::AddToBGFreeSlotQueue() +{ + sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this); +} + +/* This method removes this battleground from free queue - it must be called when deleting battleground - not used now*/ +void BattleGround::RemoveFromBGFreeSlotQueue() +{ + /* uncomment this code when battlegrounds will work like instances + for (std::deque::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr) + { + if ((*itr)->GetInstanceID() == m_InstanceID) + { + sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].erase(itr); + return; + } + }*/ +} + +/* +this method should decide, if we can invite new player of certain team to BG, it is based on BATTLEGROUND_STATUS +*/ +bool BattleGround::HasFreeSlotsForTeam(uint32 Team) const +{ + //if BG is starting ... invite anyone: + if (GetStatus() == STATUS_WAIT_JOIN) + return GetInvitedCount(Team) < GetMaxPlayersPerTeam(); + //if BG is already started .. do not allow to join too much players of one faction + uint32 otherTeam; + if (Team == ALLIANCE) + otherTeam = GetInvitedCount(HORDE); + else + otherTeam = GetInvitedCount(ALLIANCE); + if (GetStatus() == STATUS_IN_PROGRESS) + return (GetInvitedCount(Team) <= otherTeam && GetInvitedCount(Team) < GetMaxPlayersPerTeam()); + + return false; +} + +/* this method isn't called already, it will be useful when more battlegrounds of one type will be available */ +bool BattleGround::HasFreeSlots() const +{ + return GetPlayersSize() < GetMaxPlayers(); +} + +void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) +{ + //this procedure is called from virtual function implemented in bg subclass + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found... + return; + + switch(type) + { + case SCORE_KILLING_BLOWS: // Killing blows + itr->second->KillingBlows += value; + break; + case SCORE_DEATHS: // Deaths + itr->second->Deaths += value; + break; + case SCORE_HONORABLE_KILLS: // Honorable kills + itr->second->HonorableKills += value; + break; + case SCORE_BONUS_HONOR: // Honor bonus + // reward honor instantly + if(Source->RewardHonor(NULL, 1, value)) + itr->second->BonusHonor += value; + break; + //used only in EY, but in MSG_PVP_LOG_DATA opcode + case SCORE_DAMAGE_DONE: // Damage Done + itr->second->DamageDone += value; + break; + case SCORE_HEALING_DONE: // Healing Done + itr->second->HealingDone += value; + break; + default: + sLog.outError("BattleGround: Unknown player score type %u", type); + break; + } +} + +void BattleGround::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid) +{ + m_ReviveQueue[npc_guid].push_back(player_guid); + + Player *plr = objmgr.GetPlayer(player_guid); + if(!plr) + return; + + plr->CastSpell(plr, SPELL_WAITING_FOR_RESURRECT, true); + SpellEntry const *spellInfo = sSpellStore.LookupEntry( SPELL_WAITING_FOR_RESURRECT ); + if(spellInfo) + { + Aura *Aur = CreateAura(spellInfo, 0, NULL, plr); + plr->AddAura(Aur); + } +} + +void BattleGround::RemovePlayerFromResurrectQueue(uint64 player_guid) +{ + for(std::map >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) + { + for(std::vector::iterator itr2 =(itr->second).begin(); itr2 != (itr->second).end(); ++itr2) + { + if(*itr2 == player_guid) + { + (itr->second).erase(itr2); + + Player *plr = objmgr.GetPlayer(player_guid); + if(!plr) + return; + + plr->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT); + + return; + } + } + } +} + +bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime) +{ + GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry); + if(!goinfo) + { + sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry); + return false; + } + + uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); + + GameObjectData& data = objmgr.NewGOData(guid); + + data.id = entry; + data.mapid = GetMapId(); + data.posX = x; + data.posY = y; + data.posZ = z; + data.orientation = o; + data.rotation0 = rotation0; + data.rotation1 = rotation1; + data.rotation2 = rotation2; + data.rotation3 = rotation3; + data.spawntimesecs = respawnTime; + data.animprogress = 100; + data.go_state = 1; + data.spawnMask = 1; + objmgr.AddGameobjectToGrid(guid, &data); + + m_BgObjects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT); + + return true; +} + +//some doors aren't despawned so we cannot handle their closing in gameobject::update() +//it would be nice to correctly implement GO_ACTIVATED state and open/close doors in gameobject code +void BattleGround::DoorClose(uint32 type) +{ + GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); + if(obj) + { + //if doors are open, close it + if( obj->getLootState() == GO_ACTIVATED && !obj->GetGoState() ) + { + //change state to allow door to be closed + obj->SetLootState(GO_READY); + obj->UseDoorOrButton(RESPAWN_ONE_DAY); + } + } + else + { + sLog.outError("BattleGround: Door object not found (cannot close doors)"); + } +} + +void BattleGround::DoorOpen(uint32 type) +{ + GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); + if(obj) + { + //change state to be sure they will be opened + obj->SetLootState(GO_READY); + obj->UseDoorOrButton(RESPAWN_ONE_DAY); + } + else + { + sLog.outError("BattleGround: Door object not found! - doors will be closed."); + } +} + +void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime) +{ + if( respawntime == 0 ) + { + GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); + if(obj) + { + //we need to change state from GO_JUST_DEACTIVATED to GO_READY in case battleground is starting again + if( obj->getLootState() == GO_JUST_DEACTIVATED ) + obj->SetLootState(GO_READY); + obj->Respawn(); + } + else + objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, 0); + } + else + { + GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); + if(obj) + { + obj->SetRespawnTime(respawntime); + obj->SetLootState(GO_JUST_DEACTIVATED); + } + else + objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, time(NULL) + respawntime); + } +} + +Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o) +{ + // note: this should normally be FindMap + // but it's a hack to allow the battlegrounds to initialize at server startup + Map * map = MapManager::Instance().GetMap(GetMapId(), 0); + if(!map) return NULL; + + Creature* pCreature = new Creature; + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, entry, teamval)) + { + sLog.outError("Can't create creature entry: %u",entry); + delete pCreature; + return NULL; + } + + pCreature->Relocate(x, y, z, o); + + if(!pCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not added to battleground. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); + return NULL; + } + + pCreature->AIM_Initialize(); + + //pCreature->SetDungeonDifficulty(0); + + map->Add(pCreature); + m_BgCreatures[type] = pCreature->GetGUID(); + return pCreature; +} + +bool BattleGround::DelCreature(uint32 type) +{ + Creature *cr = HashMapHolder::Find(m_BgCreatures[type]); + if(!cr) + { + sLog.outError("Can't find creature guid: %u",m_BgCreatures[type]); + return false; + } + cr->CleanupsBeforeDelete(); + cr->AddObjectToRemoveList(); + m_BgCreatures[type] = 0; + return true; +} + +bool BattleGround::DelObject(uint32 type) +{ + GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); + if(!obj) + { + sLog.outError("Can't find gobject guid: %u",m_BgObjects[type]); + return false; + } + obj->SetRespawnTime(0); // not save respawn time + obj->Delete(); + m_BgObjects[type] = 0; + return true; +} + +bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team) +{ + uint32 entry = 0; + + if(team == ALLIANCE) + entry = 13116; + else + entry = 13117; + + Creature* pCreature = AddCreature(entry,type,team,x,y,z,o); + if(!pCreature) + { + sLog.outError("Can't create Spirit guide. BattleGround not created!"); + this->EndNow(); + return false; + } + + pCreature->setDeathState(DEAD); + + pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID()); + // aura + pCreature->SetUInt32Value(UNIT_FIELD_AURA, SPELL_SPIRIT_HEAL_CHANNEL); + pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009); + pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); + pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF); + // casting visual effect + pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL); + // correct cast speed + pCreature->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + + //pCreature->CastSpell(pCreature, SPELL_SPIRIT_HEAL_CHANNEL, true); + + return true; +} + +void BattleGround::SendMessageToAll(char const* text) +{ + WorldPacket data; + ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, text, NULL); + SendPacketToAll(&data); +} + +void BattleGround::SendMessageToAll(int32 entry) +{ + char const* text = GetMangosString(entry); + WorldPacket data; + ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, text, NULL); + SendPacketToAll(&data); +} + +void BattleGround::EndNow() +{ + SetStatus(STATUS_WAIT_LEAVE); + SetEndTime(TIME_TO_AUTOREMOVE); +} + +// Battleground messages are localized using the dbc lang, they are not client language dependent +const char *BattleGround::GetMangosString(int32 entry) +{ + // FIXME: now we have different DBC locales and need localized message for each target client + return objmgr.GetMangosStringForDBCLocale(entry); +} + +/* +important notice: +buffs aren't spawned/despawned when players captures anything +buffs are in their positions when battleground starts +*/ +void BattleGround::HandleTriggerBuff(uint64 const& go_guid) +{ + GameObject *obj = HashMapHolder::Find(go_guid); + if(!obj || obj->GetGoType() != GAMEOBJECT_TYPE_TRAP || !obj->isSpawned()) + return; + + //change buff type, when buff is used: + int32 index = m_BgObjects.size() - 1; + while (index >= 0 && m_BgObjects[index] != go_guid) + index--; + if (index < 0) + { + sLog.outError("BattleGround (Type: %u) has buff gameobject (Guid: %u Entry: %u Type:%u) but it hasn't that object in its internal data",GetTypeID(),GUID_LOPART(go_guid),obj->GetEntry(),obj->GetGoType()); + return; + } + + //randomly select new buff + uint8 buff = urand(0, 2); + uint32 entry = obj->GetEntry(); + if( m_BuffChange && entry != Buff_Entries[buff] ) + { + //despawn current buff + SpawnBGObject(index, RESPAWN_ONE_DAY); + //set index for new one + for (uint8 currBuffTypeIndex = 0; currBuffTypeIndex < 3; ++currBuffTypeIndex) + if( entry == Buff_Entries[currBuffTypeIndex] ) + { + index -= currBuffTypeIndex; + index += buff; + } + } + + SpawnBGObject(index, BUFF_RESPAWN_TIME); +} + +void BattleGround::HandleKillPlayer( Player *player, Player *killer ) +{ + //keep in mind that for arena this will have to be changed a bit + + // add +1 deaths + UpdatePlayerScore(player, SCORE_DEATHS, 1); + + // add +1 kills to group and +1 killing_blows to killer + if( killer ) + { + UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1); + UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1); + + for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player *plr = objmgr.GetPlayer(itr->first); + + if(!plr || plr == killer) + continue; + + if( plr->GetTeam() == killer->GetTeam() && plr->IsAtGroupRewardDistance(player) ) + UpdatePlayerScore(plr, SCORE_HONORABLE_KILLS, 1); + } + } + + // to be able to remove insignia + player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE ); +} diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h new file mode 100644 index 000000000..9e41e661b --- /dev/null +++ b/src/game/BattleGround.h @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUND_H +#define __BATTLEGROUND_H + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "ObjectMgr.h" +#include "BattleGroundMgr.h" +#include "SharedDefines.h" + +enum BattleGroundSounds +{ + SOUND_HORDE_WINS = 8454, + SOUND_ALLIANCE_WINS = 8455, + SOUND_BG_START = 3439 +}; + +enum BattleGroundQuests +{ + SPELL_WS_QUEST_REWARD = 43483, + SPELL_AB_QUEST_REWARD = 43484, + SPELL_AV_QUEST_REWARD = 43475, + SPELL_AV_QUEST_KILLED_BOSS = 23658, + SPELL_EY_QUEST_REWARD = 43477, + SPELL_AB_QUEST_REWARD_4_BASES = 24061, + SPELL_AB_QUEST_REWARD_5_BASES = 24064 +}; + +enum BattleGroundMarks +{ + SPELL_WS_MARK_LOSER = 24950, + SPELL_WS_MARK_WINNER = 24951, + SPELL_AB_MARK_LOSER = 24952, + SPELL_AB_MARK_WINNER = 24953, + SPELL_AV_MARK_LOSER = 24954, + SPELL_AV_MARK_WINNER = 24955, + ITEM_EY_MARK_OF_HONOR = 29024 +}; + +enum BattleGroundMarksCount +{ + ITEM_WINNER_COUNT = 3, + ITEM_LOSER_COUNT = 1 +}; + +enum BattleGroundSpells +{ + SPELL_WAITING_FOR_RESURRECT = 2584, // Waiting to Resurrect + SPELL_SPIRIT_HEAL_CHANNEL = 22011, // Spirit Heal Channel + SPELL_SPIRIT_HEAL = 22012, // Spirit Heal + SPELL_RESURRECTION_VISUAL = 24171, // Resurrection Impact Visual + SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct + SPELL_ALLIANCE_GOLD_FLAG = 32724, + SPELL_ALLIANCE_GREEN_FLAG = 32725, + SPELL_HORDE_GOLD_FLAG = 35774, + SPELL_HORDE_GREEN_FLAG = 35775, + SPELL_PREPARATION = 44521, // Preparation + SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal + SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag + SPELL_AURA_PLAYER_INACTIVE = 43681 // Inactive +}; + +enum BattleGroundTimeIntervals +{ + RESURRECTION_INTERVAL = 30000, // ms + REMIND_INTERVAL = 30000, // ms + INVITE_ACCEPT_WAIT_TIME = 120000, // ms + TIME_TO_AUTOREMOVE = 120000, // ms + MAX_OFFLINE_TIME = 300000, // ms + START_DELAY0 = 120000, // ms + START_DELAY1 = 60000, // ms + START_DELAY2 = 30000, // ms + START_DELAY3 = 15000, // ms used only in arena + RESPAWN_ONE_DAY = 86400, // secs + RESPAWN_IMMEDIATELY = 0, // secs + BUFF_RESPAWN_TIME = 180, // secs + BG_HONOR_SCORE_TICKS = 330 // points +}; + +enum BattleGroundBuffObjects +{ + BG_OBJECTID_SPEEDBUFF_ENTRY = 179871, + BG_OBJECTID_REGENBUFF_ENTRY = 179904, + BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905 +}; + +const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY }; + +enum BattleGroundStatus +{ + STATUS_NONE = 0, + STATUS_WAIT_QUEUE = 1, + STATUS_WAIT_JOIN = 2, + STATUS_IN_PROGRESS = 3, + STATUS_WAIT_LEAVE = 4 // custom +}; + +struct BattleGroundPlayer +{ + uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes + uint32 Team; // Player's team +}; + +struct BattleGroundObjectInfo +{ + BattleGroundObjectInfo() : object(NULL), timer(0), spellid(0) {} + + GameObject *object; + int32 timer; + uint32 spellid; +}; + +#define MAX_QUEUED_PLAYERS_MAP 7 + +enum BattleGroundTypeId +{ + BATTLEGROUND_AV = 1, + BATTLEGROUND_WS = 2, + BATTLEGROUND_AB = 3, + BATTLEGROUND_NA = 4, + BATTLEGROUND_BE = 5, + BATTLEGROUND_AA = 6, + BATTLEGROUND_EY = 7, + BATTLEGROUND_RL = 8 +}; + +enum ScoreType +{ + SCORE_KILLING_BLOWS = 1, + SCORE_DEATHS = 2, + SCORE_HONORABLE_KILLS = 3, + SCORE_BONUS_HONOR = 4, + //EY, but in MSG_PVP_LOG_DATA opcode! + SCORE_DAMAGE_DONE = 5, + SCORE_HEALING_DONE = 6, + //WS + SCORE_FLAG_CAPTURES = 7, + SCORE_FLAG_RETURNS = 8, + //AB + SCORE_BASES_ASSAULTED = 9, + SCORE_BASES_DEFENDED = 10, + //AV + SCORE_GRAVEYARDS_ASSAULTED = 11, + SCORE_GRAVEYARDS_DEFENDED = 12, + SCORE_TOWERS_ASSAULTED = 13, + SCORE_TOWERS_DEFENDED = 14, + SCORE_MINES_CAPTURED = 15, + SCORE_LEADERS_KILLED = 16, + SCORE_SECONDARY_OBJECTIVES = 17 + // TODO : implement them +}; + +enum ArenaType +{ + ARENA_TYPE_2v2 = 2, + ARENA_TYPE_3v3 = 3, + ARENA_TYPE_5v5 = 5 +}; + +enum BattleGroundType +{ + TYPE_BATTLEGROUND = 3, + TYPE_ARENA = 4 +}; + +enum BattleGroundWinner +{ + WINNER_HORDE = 0, + WINNER_ALLIANCE = 1, + WINNER_NONE = 2 +}; + +enum BattleGroundTeamId +{ + BG_TEAM_ALLIANCE = 0, + BG_TEAM_HORDE = 1 +}; + +class BattleGroundScore +{ + public: + BattleGroundScore() : KillingBlows(0), HonorableKills(0), Deaths(0), DamageDone(0), HealingDone(0), BonusHonor(0) {}; + virtual ~BattleGroundScore() //virtual destructor is used when deleting score from scores map + { + }; + uint32 KillingBlows; + uint32 Deaths; + uint32 HonorableKills; + uint32 BonusHonor; + uint32 DamageDone; + uint32 HealingDone; +}; + +/* +This class is used to: +1. Add player to battleground +2. Remove player from battleground +3. some certain cases, same for all battlegrounds +4. It has properties same for all battlegrounds +*/ +class BattleGround +{ + friend class BattleGroundMgr; + + public: + /* Construction */ + BattleGround(); + virtual ~BattleGround(); + virtual void Update(time_t diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version + virtual bool SetupBattleGround() // must be implemented in BG subclass + { + return true; + } + void Reset(); // resets all common properties for battlegrounds + virtual void ResetBGSubclass() // must be implemented in BG subclass + { + } + + /* Battleground */ + // Get methods: + char const* GetName() const { return m_Name; } + uint32 GetTypeID() const { return m_TypeID; } + uint32 GetQueueType() const { return m_Queue_type; } + uint32 GetInstanceID() const { return m_InstanceID; } + uint32 GetStatus() const { return m_Status; } + uint32 GetStartTime() const { return m_StartTime; } + uint32 GetEndTime() const { return m_EndTime; } + uint32 GetLastResurrectTime() const { return m_LastResurrectTime; } + uint32 GetMaxPlayers() const { return m_MaxPlayers; } + uint32 GetMinPlayers() const { return m_MinPlayers; } + + uint32 GetMinLevel() const { return m_LevelMin; } + uint32 GetMaxLevel() const { return m_LevelMax; } + + uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; } + uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; } + + int GetStartDelayTime() const { return m_StartDelayTime; } + uint8 GetArenaType() const { return m_ArenaType; } + uint8 GetWinner() const { return m_Winner; } + uint32 GetBattlemasterEntry() const; + + // Set methods: + void SetName(char const* Name) { m_Name = Name; } + void SetTypeID(uint32 TypeID) { m_TypeID = TypeID; } + void SetQueueType(uint32 ID) { m_Queue_type = ID; } + void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; } + void SetStatus(uint32 Status) { m_Status = Status; } + void SetStartTime(uint32 Time) { m_StartTime = Time; } + void SetEndTime(uint32 Time) { m_EndTime = Time; } + void SetLastResurrectTime(uint32 Time) { m_LastResurrectTime = Time; } + void SetMaxPlayers(uint32 MaxPlayers) { m_MaxPlayers = MaxPlayers; } + void SetMinPlayers(uint32 MinPlayers) { m_MinPlayers = MinPlayers; } + void SetLevelRange(uint32 min, uint32 max) { m_LevelMin = min; m_LevelMax = max; } + void SetRated(bool state) { m_IsRated = state; } + void SetArenaType(uint8 type) { m_ArenaType = type; } + void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; } + void SetWinner(uint8 winner) { m_Winner = winner; } + + void ModifyStartDelayTime(int diff) { m_StartDelayTime -= diff; } + void SetStartDelayTime(int Time) { m_StartDelayTime = Time; } + + void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; } + void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; } + + void AddToBGFreeSlotQueue(); //this queue will be useful when more battlegrounds instances will be available + void RemoveFromBGFreeSlotQueue(); //this method could delete whole BG instance, if another free is available + + void DecreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? --m_InvitedAlliance : --m_InvitedHorde; } + void IncreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? ++m_InvitedAlliance : ++m_InvitedHorde; } + uint32 GetInvitedCount(uint32 team) const + { + if( team == ALLIANCE ) + return m_InvitedAlliance; + else + return m_InvitedHorde; + } + bool HasFreeSlotsForTeam(uint32 Team) const; + bool HasFreeSlots() const; + + bool isArena() const { return m_IsArena; } + bool isBattleGround() const { return !m_IsArena; } + bool isRated() const { return m_IsRated; } + + typedef std::map BattleGroundPlayerMap; + BattleGroundPlayerMap const& GetPlayers() const { return m_Players; } + uint32 GetPlayersSize() const { return m_Players.size(); } + uint32 GetRemovedPlayersSize() const { return m_RemovedPlayers.size(); } + + std::map::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); } + std::map::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); } + uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); } + + uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); } + + void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid); + void RemovePlayerFromResurrectQueue(uint64 player_guid); + + void StartBattleGround(); + + /* Location */ + void SetMapId(uint32 MapID) { m_MapId = MapID; } + uint32 GetMapId() const { return m_MapId; } + + void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O); + void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const + { + uint8 idx = GetTeamIndexByTeamId(TeamID); + X = m_TeamStartLocX[idx]; + Y = m_TeamStartLocY[idx]; + Z = m_TeamStartLocZ[idx]; + O = m_TeamStartLocO[idx]; + } + + /* Packet Transfer */ + // method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!) + virtual void FillInitialWorldStates(WorldPacket& /*data*/) {} + void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender = NULL, bool self = true); + void SendPacketToAll(WorldPacket *packet); + void PlaySoundToTeam(uint32 SoundID, uint32 TeamID); + void PlaySoundToAll(uint32 SoundID); + void CastSpellOnTeam(uint32 SpellID, uint32 TeamID); + void RewardHonorToTeam(uint32 Honor, uint32 TeamID); + void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); + void RewardMark(Player *plr,uint32 count); + void SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count); + void RewardQuest(Player *plr); + void UpdateWorldState(uint32 Field, uint32 Value); + void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source); + void EndBattleGround(uint32 winner); + void BlockMovement(Player *plr); + + void SendMessageToAll(char const* text); + void SendMessageToAll(int32 entry); + + /* Raid Group */ + Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; } + void SetBgRaid(uint32 TeamID, Group *bg_raid) + { + Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; + if(old_raid) old_raid->SetBattlegroundGroup(NULL); + if(bg_raid) bg_raid->SetBattlegroundGroup(this); + old_raid = bg_raid; + } + + virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + uint8 GetTeamIndexByTeamId(uint32 Team) const { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; } + uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; } + void UpdatePlayersCountByTeam(uint32 Team, bool remove) + { + if(remove) + --m_PlayersCount[GetTeamIndexByTeamId(Team)]; + else + ++m_PlayersCount[GetTeamIndexByTeamId(Team)]; + } + + /* Triggers handle */ + // must be implemented in BG subclass + virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {} + // must be implemented in BG subclass if need AND call base class generic code + virtual void HandleKillPlayer(Player *player, Player *killer); + + /* Battleground events */ + /* these functions will return true event is possible, but false if player is bugger */ + virtual void EventPlayerDroppedFlag(Player* /*player*/) {} + virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {} + virtual void EventPlayerCapturedFlag(Player* /*player*/) {} + + /* Death related */ + virtual WorldSafeLocsEntry const* GetClosestGraveYard(float /*x*/, float /*y*/, float /*z*/, uint32 /*team*/) { return NULL; } + + virtual void AddPlayer(Player *plr); // must be implemented in BG subclass + virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket); + // can be extended in in BG subclass + + void HandleTriggerBuff(uint64 const& go_guid); + + // TODO: make this protected: + typedef std::vector BGObjects; + typedef std::vector BGCreatures; + BGObjects m_BgObjects; + BGCreatures m_BgCreatures; + void SpawnBGObject(uint32 type, uint32 respawntime); + bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0); + Creature* AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o); + bool DelCreature(uint32 type); + bool DelObject(uint32 type); + bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team); + + void DoorOpen(uint32 type); + void DoorClose(uint32 type); + const char *GetMangosString(int32 entry); + + protected: + //this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround + void EndNow(); + + /* Scorekeeping */ + // Player scores + std::map m_PlayerScores; + // must be implemented in BG subclass + virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {} + + /* Player lists, those need to be accessible by inherited classes */ + BattleGroundPlayerMap m_Players; + // Spirit Guide guid + Player list GUIDS + std::map > m_ReviveQueue; + + /* + this is important variable used for invitation messages + */ + uint8 m_Events; + + bool m_BuffChange; + + private: + /* Battleground */ + uint32 m_TypeID; //Battleground type, defined in enum BattleGroundTypeId + uint32 m_InstanceID; //BattleGround Instance's GUID! + uint32 m_Status; + uint32 m_StartTime; + uint32 m_EndTime; + uint32 m_LastResurrectTime; + uint32 m_Queue_type; + uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5 + // this variable is not used .... it can be found in many other ways... but to store it in BG object instance is useless + //uint8 m_BattleGroundType; // 3=BG, 4=arena + //instead of uint8 (in previous line) is bool used + bool m_IsArena; + uint8 m_Winner; // 0=alliance, 1=horde, 2=none + int32 m_StartDelayTime; + bool m_IsRated; // is this battle rated? + char const *m_Name; + + /* Player lists */ + std::vector m_ResurrectQueue; // Player GUID + std::map m_RemovedPlayers; // uint8 is remove type (0 - bgqueue, 1 - bg, 2 - resurrect queue) + + /* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */ + /* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */ + /* Invited players counters*/ + uint32 m_InvitedAlliance; + uint32 m_InvitedHorde; + + /* Raid Group */ + Group *m_BgRaids[2]; // 0 - alliance, 1 - horde + + /* Players count by team */ + uint32 m_PlayersCount[2]; + + /* Limits */ + uint32 m_LevelMin; + uint32 m_LevelMax; + uint32 m_MaxPlayersPerTeam; + uint32 m_MaxPlayers; + uint32 m_MinPlayersPerTeam; + uint32 m_MinPlayers; + + /* Location */ + uint32 m_MapId; + float m_TeamStartLocX[2]; + float m_TeamStartLocY[2]; + float m_TeamStartLocZ[2]; + float m_TeamStartLocO[2]; +}; +#endif diff --git a/src/game/BattleGroundAA.cpp b/src/game/BattleGroundAA.cpp new file mode 100644 index 000000000..585e1caa5 --- /dev/null +++ b/src/game/BattleGroundAA.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundAA.h" + +BattleGroundAA::BattleGroundAA() +{ + +} + +BattleGroundAA::~BattleGroundAA() +{ + +} + +void BattleGroundAA::Update(time_t diff) +{ + BattleGround::Update(diff); +} + +void BattleGroundAA::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundAAScore* sc = new BattleGroundAAScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundAA::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) +{ +} + +void BattleGroundAA::HandleKillPlayer(Player* player, Player* killer) +{ + BattleGround::HandleKillPlayer(player, killer); +} + +void BattleGroundAA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) +{ +} + +bool BattleGroundAA::SetupBattleGround() +{ + return true; +} diff --git a/src/game/BattleGroundAA.h b/src/game/BattleGroundAA.h new file mode 100644 index 000000000..8a81c8c0c --- /dev/null +++ b/src/game/BattleGroundAA.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __BATTLEGROUNDAA_H +#define __BATTLEGROUNDAA_H + +class BattleGround; + +class BattleGroundAAScore : public BattleGroundScore +{ + public: + BattleGroundAAScore() {}; + virtual ~BattleGroundAAScore() {}; + //TODO fix me +}; + +class BattleGroundAA : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundAA(); + ~BattleGroundAA(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + void RemovePlayer(Player *plr, uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + bool SetupBattleGround(); + void HandleKillPlayer(Player* player, Player *killer); +}; +#endif diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp new file mode 100644 index 000000000..dcf23ccff --- /dev/null +++ b/src/game/BattleGroundAB.cpp @@ -0,0 +1,649 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundAB.h" +#include "Creature.h" +#include "Chat.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "Language.h" +#include "Util.h" + +BattleGroundAB::BattleGroundAB() +{ + m_BuffChange = true; + m_BgObjects.resize(BG_AB_OBJECT_MAX); + m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT); +} + +BattleGroundAB::~BattleGroundAB() +{ +} + +void BattleGroundAB::Update(time_t diff) +{ + BattleGround::Update(diff); + + if( GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize() ) + { + ModifyStartDelayTime(diff); + + if( !(m_Events & 0x01) ) + { + m_Events |= 0x01; + + sLog.outDebug("Arathi Basin: entering state STATUS_WAIT_JOIN ..."); + + // despawn banners, auras and buffs + for (int obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * 8; ++obj) + SpawnBGObject(obj, RESPAWN_ONE_DAY); + for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i) + SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY); + + // Starting doors + SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY); + DoorClose(BG_AB_OBJECT_GATE_A); + DoorClose(BG_AB_OBJECT_GATE_H); + + // Starting base spirit guides + _NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE); + _NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE); + + SetStartDelayTime(START_DELAY0); + } + // After 1 minute, warning is signalled + else if( GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04) ) + { + m_Events |= 0x04; + SendMessageToAll(GetMangosString(LANG_BG_AB_ONEMINTOSTART)); + } + // After 1,5 minute, warning is signalled + else if( GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08) ) + { + m_Events |= 0x08; + SendMessageToAll(GetMangosString(LANG_BG_AB_HALFMINTOSTART)); + } + // After 2 minutes, gates OPEN ! x) + else if( GetStartDelayTime() < 0 && !(m_Events & 0x10) ) + { + m_Events |= 0x10; + SendMessageToAll(GetMangosString(LANG_BG_AB_STARTED)); + + // spawn neutral banners + for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i) + SpawnBGObject(banner, RESPAWN_IMMEDIATELY); + for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + { + //randomly select buff to spawn + uint8 buff = urand(0, 2); + SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + buff + i * 3, RESPAWN_IMMEDIATELY); + } + DoorOpen(BG_AB_OBJECT_GATE_A); + DoorOpen(BG_AB_OBJECT_GATE_H); + + PlaySoundToAll(SOUND_BG_START); + SetStatus(STATUS_IN_PROGRESS); + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player* plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_PREPARATION); + } + + } + else if( GetStatus() == STATUS_IN_PROGRESS ) + { + int team_points[2] = { 0, 0 }; + + for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) + { + // 3 sec delay to spawn new banner instead previous despawned one + if( m_BannerTimers[node].timer ) + { + if( m_BannerTimers[node].timer > diff ) + m_BannerTimers[node].timer -= diff; + else + { + m_BannerTimers[node].timer = 0; + _CreateBanner(node, m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false); + } + } + + // 1-minute to occupy a node from contested state + if( m_NodeTimers[node] ) + { + if( m_NodeTimers[node] > diff ) + m_NodeTimers[node] -= diff; + else + { + m_NodeTimers[node] = 0; + // Change from contested to occupied ! + uint8 teamIndex = m_Nodes[node]-1; + m_prevNodes[node] = m_Nodes[node]; + m_Nodes[node] += 2; + // burn current contested banner + _DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex); + // create new occupied banner + _CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true); + _SendNodeUpdate(node); + _NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE); + // Message to chatlog + char buf[256]; + uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE; + sprintf(buf, GetMangosString(LANG_BG_AB_NODE_TAKEN), (teamIndex == 0) ? GetMangosString(LANG_BG_AB_ALLY) : GetMangosString(LANG_BG_AB_HORDE), _GetNodeName(node)); + WorldPacket data; + ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL); + SendPacketToAll(&data); + PlaySoundToAll((teamIndex == 0) ? SOUND_NODE_CAPTURED_ALLIANCE : SOUND_NODE_CAPTURED_HORDE); + } + } + + for (int team = 0; team < 2; ++team) + if( m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED ) + ++team_points[team]; + } + + // Accumulate points + for (int team = 0; team < 2; ++team) + { + int points = team_points[team]; + if( !points ) + continue; + m_lastTick[team] += diff; + if( m_lastTick[team] > BG_AB_TickIntervals[points] ) + { + m_lastTick[team] -= BG_AB_TickIntervals[points]; + m_TeamScores[team] += BG_AB_TickPoints[points]; + m_HonorScoreTics[team] += BG_AB_TickPoints[points]; + m_ReputationScoreTics[team] += BG_AB_TickPoints[points]; + if( m_ReputationScoreTics[team] >= 200 ) + { + (team == BG_TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE); + m_ReputationScoreTics[team] -= 200; + } + if( m_HonorScoreTics[team] >= BG_HONOR_SCORE_TICKS ) + { + (team == BG_TEAM_ALLIANCE) ? RewardHonorToTeam(20, ALLIANCE) : RewardHonorToTeam(20, HORDE); + m_HonorScoreTics[team] -= BG_HONOR_SCORE_TICKS; + } + if( !m_IsInformedNearVictory && m_TeamScores[team] > 1800 ) + { + if( team == BG_TEAM_ALLIANCE ) + SendMessageToAll(GetMangosString(LANG_BG_AB_A_NEAR_VICTORY)); + else + SendMessageToAll(GetMangosString(LANG_BG_AB_H_NEAR_VICTORY)); + PlaySoundToAll(SOUND_NEAR_VICTORY); + m_IsInformedNearVictory = true; + } + + if( m_TeamScores[team] > 2000 ) + m_TeamScores[team] = 2000; + if( team == BG_TEAM_ALLIANCE ) + UpdateWorldState(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[team]); + if( team == BG_TEAM_HORDE ) + UpdateWorldState(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[team]); + } + } + + // Test win condition + if( m_TeamScores[BG_TEAM_ALLIANCE] >= 2000 ) + EndBattleGround(ALLIANCE); + if( m_TeamScores[BG_TEAM_HORDE] >= 2000 ) + EndBattleGround(HORDE); + } +} + +void BattleGroundAB::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in the constructor + BattleGroundABScore* sc = new BattleGroundABScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) +{ + +} + +void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + if( GetStatus() != STATUS_IN_PROGRESS ) + return; + + switch(Trigger) + { + case 3948: // Arathi Basin Alliance Exit. + if( Source->GetTeam() != ALLIANCE ) + Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal"); + else + Source->LeaveBattleground(); + break; + case 3949: // Arathi Basin Horde Exit. + if( Source->GetTeam() != HORDE ) + Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal"); + else + Source->LeaveBattleground(); + break; + case 3866: // Stables + case 3869: // Gold Mine + case 3867: // Farm + case 3868: // Lumber Mill + case 3870: // Black Smith + case 4020: // Unk1 + case 4021: // Unk2 + //break; + default: + //sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + //Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } +} + +/* type: 0-neutral, 1-contested, 3-occupied + teamIndex: 0-ally, 1-horde */ +void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay) +{ + // Just put it into the queue + if( delay ) + { + m_BannerTimers[node].timer = 2000; + m_BannerTimers[node].type = type; + m_BannerTimers[node].teamIndex = teamIndex; + return; + } + + uint8 obj = node*8 + type + teamIndex; + + SpawnBGObject(obj, RESPAWN_IMMEDIATELY); + + // handle aura with banner + if( !type ) + return; + obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7); + SpawnBGObject(obj, RESPAWN_IMMEDIATELY); +} + +void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex) +{ + uint8 obj = node*8 + type + teamIndex; + SpawnBGObject(obj, RESPAWN_ONE_DAY); + + // handle aura with banner + if( !type ) + return; + obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7); + SpawnBGObject(obj, RESPAWN_ONE_DAY); +} + +const char* BattleGroundAB::_GetNodeName(uint8 node) +{ + switch (node) + { + case BG_AB_NODE_STABLES: + return GetMangosString(LANG_BG_AB_NODE_STABLES); + case BG_AB_NODE_BLACKSMITH: + return GetMangosString(LANG_BG_AB_NODE_BLACKSMITH); + case BG_AB_NODE_FARM: + return GetMangosString(LANG_BG_AB_NODE_FARM); + case BG_AB_NODE_LUMBER_MILL: + return GetMangosString(LANG_BG_AB_NODE_LUMBER_MILL); + case BG_AB_NODE_GOLD_MINE: + return GetMangosString(LANG_BG_AB_NODE_GOLD_MINE); + default: + ASSERT(0); + } + return ""; +} + +void BattleGroundAB::FillInitialWorldStates(WorldPacket& data) +{ + const uint8 plusArray[] = {0, 2, 3, 0, 1}; + + // Node icons + for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) + data << uint32(BG_AB_OP_NODEICONS[node]) << uint32((m_Nodes[node]==0)?1:0); + + // Node occupied states + for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) + for (uint8 i = 1; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + data << uint32(BG_AB_OP_NODESTATES[node] + plusArray[i]) << uint32((m_Nodes[node]==i)?1:0); + + // How many bases each team owns + uint8 ally = 0, horde = 0; + for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) + if( m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_OCCUPIED ) + ++ally; + else if( m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED ) + ++horde; + + data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(ally); + data << uint32(BG_AB_OP_OCCUPIED_BASES_HORDE) << uint32(horde); + + // Team scores + data << uint32(BG_AB_OP_RESOURCES_MAX) << uint32(BG_AB_MAX_TEAM_SCORE); + data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_SCORE); + data << uint32(BG_AB_OP_RESOURCES_ALLY) << uint32(m_TeamScores[BG_TEAM_ALLIANCE]); + data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[BG_TEAM_HORDE]); + + // other unknown + data << uint32(0x745) << uint32(0x2); // 37 1861 unk +} + +void BattleGroundAB::_SendNodeUpdate(uint8 node) +{ + // Send node owner state update to refresh map icons on client + const uint8 plusArray[] = {0, 2, 3, 0, 1}; + + if( m_prevNodes[node] ) + UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0); + else + UpdateWorldState(BG_AB_OP_NODEICONS[node], 0); + + UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_Nodes[node]], 1); + + // How many bases each team owns + uint8 ally = 0, horde = 0; + for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + if( m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED ) + ++ally; + else if( m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED ) + ++horde; + + UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, ally); + UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_HORDE, horde); +} + +void BattleGroundAB::_NodeOccupied(uint8 node,Team team) +{ + if( !AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team) ) + sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team); + + uint8 capturedNodes = 0; + for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + { + if( m_Nodes[node] == GetTeamIndexByTeamId(team) + BG_AB_NODE_TYPE_OCCUPIED && !m_NodeTimers[i]) + ++capturedNodes; + } + if(capturedNodes >= 5) + CastSpellOnTeam(SPELL_AB_QUEST_REWARD_5_BASES, team); + if(capturedNodes >= 4) + CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team); +} + +void BattleGroundAB::_NodeDeOccupied(uint8 node) +{ + if( node >= BG_AB_DYNAMIC_NODES_COUNT) + return; + + // Those who are waiting to resurrect at this node are taken to the closest own node's graveyard + std::vector ghost_list = m_ReviveQueue[m_BgCreatures[node]]; + if( !ghost_list.empty() ) + { + WorldSafeLocsEntry const *ClosestGrave = NULL; + Player *plr; + for (std::vector::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr) + { + plr = objmgr.GetPlayer(*ghost_list.begin()); + if( !plr ) + continue; + if( !ClosestGrave ) + ClosestGrave = GetClosestGraveYard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetTeam()); + + plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation()); + } + } + + if( m_BgCreatures[node] ) + DelCreature(node); + + // buff object isn't despawned +} + +/* Invoked if a player used a banner as a gameobject */ +void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/) +{ + if( GetStatus() != STATUS_IN_PROGRESS ) + return; + + uint8 node = BG_AB_NODE_STABLES; + GameObject* obj=HashMapHolder::Find(m_BgObjects[node*8+7]); + while ( (node < BG_AB_DYNAMIC_NODES_COUNT) && ((!obj) || (!source->IsWithinDistInMap(obj,10)))) + { + ++node; + obj=HashMapHolder::Find(m_BgObjects[node*8+BG_AB_OBJECT_AURA_CONTESTED]); + } + + if( node == BG_AB_DYNAMIC_NODES_COUNT) + { + // this means our player isn't close to any of banners - maybe cheater ?? + return; + } + + uint8 teamIndex = GetTeamIndexByTeamId(source->GetTeam()); + + // Message to chatlog + char buf[256]; + uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE; + + // Check if player really could use this banner, not cheated + if( !(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2) ) + return; + + source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); + uint32 sound = 0; + // If node is neutral, change to contested + if( m_Nodes[node] == BG_AB_NODE_TYPE_NEUTRAL ) + { + UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1); + m_prevNodes[node] = m_Nodes[node]; + m_Nodes[node] = teamIndex + 1; + // burn current neutral banner + _DelBanner(node, BG_AB_NODE_TYPE_NEUTRAL, 0); + // create new contested banner + _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); + _SendNodeUpdate(node); + m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; + sprintf(buf, GetMangosString(LANG_BG_AB_NODE_CLAIMED), _GetNodeName(node), (teamIndex == 0) ? GetMangosString(LANG_BG_AB_ALLY) : GetMangosString(LANG_BG_AB_HORDE)); + sound = SOUND_NODE_CLAIMED; + } + // If node is contested + else if( (m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_CONTESTED) || (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_CONTESTED) ) + { + // If last state is NOT occupied, change node to enemy-contested + if( m_prevNodes[node] < BG_AB_NODE_TYPE_OCCUPIED ) + { + UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1); + m_prevNodes[node] = m_Nodes[node]; + m_Nodes[node] = teamIndex + BG_AB_NODE_TYPE_CONTESTED; + // burn current contested banner + _DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, !teamIndex); + // create new contested banner + _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); + _SendNodeUpdate(node); + m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; + sprintf(buf, GetMangosString(LANG_BG_AB_NODE_ASSAULTED), _GetNodeName(node)); + } + // If contested, change back to occupied + else + { + UpdatePlayerScore(source, SCORE_BASES_DEFENDED, 1); + m_prevNodes[node] = m_Nodes[node]; + m_Nodes[node] = teamIndex + BG_AB_NODE_TYPE_OCCUPIED; + // burn current contested banner + _DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, !teamIndex); + // create new occupied banner + _CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true); + _SendNodeUpdate(node); + m_NodeTimers[node] = 0; + _NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE); + sprintf(buf, GetMangosString(LANG_BG_AB_NODE_DEFENDED), _GetNodeName(node)); + } + sound = (teamIndex == 0) ? SOUND_NODE_ASSAULTED_ALLIANCE : SOUND_NODE_ASSAULTED_HORDE; + } + // If node is occupied, change to enemy-contested + else + { + UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1); + m_prevNodes[node] = m_Nodes[node]; + m_Nodes[node] = teamIndex + BG_AB_NODE_TYPE_CONTESTED; + // burn current occupied banner + _DelBanner(node, BG_AB_NODE_TYPE_OCCUPIED, !teamIndex); + // create new contested banner + _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); + _SendNodeUpdate(node); + _NodeDeOccupied(node); + m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; + sprintf(buf, GetMangosString(LANG_BG_AB_NODE_ASSAULTED), _GetNodeName(node)); + sound = (teamIndex == 0) ? SOUND_NODE_ASSAULTED_ALLIANCE : SOUND_NODE_ASSAULTED_HORDE; + } + WorldPacket data; + ChatHandler::FillMessageData(&data, source->GetSession(), type, LANG_UNIVERSAL, NULL, source->GetGUID(), buf, NULL); + SendPacketToAll(&data); + // If node is occupied again, send "X has taken the Y" msg. + if( m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED ) + { + sprintf(buf, GetMangosString(LANG_BG_AB_NODE_TAKEN), (teamIndex == 0) ? GetMangosString(LANG_BG_AB_ALLY) : GetMangosString(LANG_BG_AB_HORDE), _GetNodeName(node)); + ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL); + SendPacketToAll(&data); + } + PlaySoundToAll(sound); +} + +bool BattleGroundAB::SetupBattleGround() +{ + for (int i = 0 ; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + { + if( !AddObject(BG_AB_OBJECT_BANNER_NEUTRAL + 8*i,BG_AB_OBJECTID_NODE_BANNER_0 + i,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_BANNER_CONT_A + 8*i,BG_AB_OBJECTID_BANNER_CONT_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_BANNER_CONT_H + 8*i,BG_AB_OBJECTID_BANNER_CONT_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_BANNER_ALLY + 8*i,BG_AB_OBJECTID_BANNER_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_BANNER_HORDE + 8*i,BG_AB_OBJECTID_BANNER_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_AURA_ALLY + 8*i,BG_AB_OBJECTID_AURA_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_AURA_HORDE + 8*i,BG_AB_OBJECTID_AURA_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_AURA_CONTESTED + 8*i,BG_AB_OBJECTID_AURA_C,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY) + ) + { + sLog.outErrorDb("BatteGroundAB: Failed to spawn some object BattleGround not created!"); + return false; + } + } + if( !AddObject(BG_AB_OBJECT_GATE_A,BG_AB_OBJECTID_GATE_A,BG_AB_DoorPositions[0][0],BG_AB_DoorPositions[0][1],BG_AB_DoorPositions[0][2],BG_AB_DoorPositions[0][3],BG_AB_DoorPositions[0][4],BG_AB_DoorPositions[0][5],BG_AB_DoorPositions[0][6],BG_AB_DoorPositions[0][7],RESPAWN_IMMEDIATELY) + || !AddObject(BG_AB_OBJECT_GATE_H,BG_AB_OBJECTID_GATE_H,BG_AB_DoorPositions[1][0],BG_AB_DoorPositions[1][1],BG_AB_DoorPositions[1][2],BG_AB_DoorPositions[1][3],BG_AB_DoorPositions[1][4],BG_AB_DoorPositions[1][5],BG_AB_DoorPositions[1][6],BG_AB_DoorPositions[1][7],RESPAWN_IMMEDIATELY) + ) + { + sLog.outErrorDb("BatteGroundAB: Failed to spawn door object BattleGround not created!"); + return false; + } + //buffs + for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + { + if( !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i, Buff_Entries[0], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 1, Buff_Entries[1], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY) + || !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 2, Buff_Entries[2], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY) + ) + sLog.outErrorDb("BatteGroundAB: Failed to spawn buff object!"); + } + + return true; +} + +void BattleGroundAB::ResetBGSubclass() +{ + m_TeamScores[BG_TEAM_ALLIANCE] = 0; + m_TeamScores[BG_TEAM_HORDE] = 0; + m_lastTick[BG_TEAM_ALLIANCE] = 0; + m_lastTick[BG_TEAM_HORDE] = 0; + m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0; + m_HonorScoreTics[BG_TEAM_HORDE] = 0; + m_ReputationScoreTics[BG_TEAM_ALLIANCE] = 0; + m_ReputationScoreTics[BG_TEAM_HORDE] = 0; + m_IsInformedNearVictory = false; + for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + { + m_Nodes[i] = 0; + m_prevNodes[i] = 0; + m_NodeTimers[i] = 0; + m_BannerTimers[i].timer = 0; + } + + for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT; ++i) + if(m_BgCreatures[i]) + DelCreature(i); +} + +WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(float x, float y, float /*z*/, uint32 team) +{ + uint8 teamIndex = GetTeamIndexByTeamId(team); + + // Is there any occupied node for this team? + std::vector nodes; + for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + if( m_Nodes[i] == teamIndex + 3 ) + nodes.push_back(i); + + WorldSafeLocsEntry const* good_entry = NULL; + // If so, select the closest node to place ghost on + if( !nodes.empty() ) + { + float mindist = 999999.0f; + for (uint8 i = 0; i < nodes.size(); ++i) + { + WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[nodes[i]] ); + if( !entry ) + continue; + float dist = (entry->x - x)*(entry->x - x)+(entry->y - y)*(entry->y - y); + if( mindist > dist ) + { + mindist = dist; + good_entry = entry; + } + } + nodes.clear(); + } + // If not, place ghost on starting location + if( !good_entry ) + good_entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[teamIndex+5] ); + + return good_entry; +} + +void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) +{ + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if( itr == m_PlayerScores.end() ) // player not found... + return; + + switch(type) + { + case SCORE_BASES_ASSAULTED: + ((BattleGroundABScore*)itr->second)->BasesAssaulted += value; + break; + case SCORE_BASES_DEFENDED: + ((BattleGroundABScore*)itr->second)->BasesDefended += value; + break; + default: + BattleGround::UpdatePlayerScore(Source,type,value); + break; + } +} diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h new file mode 100644 index 000000000..dc3b8c2f8 --- /dev/null +++ b/src/game/BattleGroundAB.h @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __BATTLEGROUNDAB_H +#define __BATTLEGROUNDAB_H + +class BattleGround; + +enum BG_AB_WorldStates +{ + BG_AB_OP_OCCUPIED_BASES_HORDE = 1778, + BG_AB_OP_OCCUPIED_BASES_ALLY = 1779, + BG_AB_OP_RESOURCES_ALLY = 1776, + BG_AB_OP_RESOURCES_HORDE = 1777, + BG_AB_OP_RESOURCES_MAX = 1780, + BG_AB_OP_RESOURCES_WARNING = 1955 +/* + BG_AB_OP_STABLE_ICON = 1842, //Stable map icon (NONE) + BG_AB_OP_STABLE_STATE_ALIENCE = 1767, //Stable map state (ALIENCE) + BG_AB_OP_STABLE_STATE_HORDE = 1768, //Stable map state (HORDE) + BG_AB_OP_STABLE_STATE_CON_ALI = 1769, //Stable map state (CON ALIENCE) + BG_AB_OP_STABLE_STATE_CON_HOR = 1770, //Stable map state (CON HORDE) + BG_AB_OP_FARM_ICON = 1845, //Farm map icon (NONE) + BG_AB_OP_FARM_STATE_ALIENCE = 1772, //Farm state (ALIENCE) + BG_AB_OP_FARM_STATE_HORDE = 1773, //Farm state (HORDE) + BG_AB_OP_FARM_STATE_CON_ALI = 1774, //Farm state (CON ALIENCE) + BG_AB_OP_FARM_STATE_CON_HOR = 1775, //Farm state (CON HORDE) + + BG_AB_OP_BLACKSMITH_ICON = 1846, //Blacksmith map icon (NONE) + BG_AB_OP_BLACKSMITH_STATE_ALIENCE = 1782, //Blacksmith map state (ALIENCE) + BG_AB_OP_BLACKSMITH_STATE_HORDE = 1783, //Blacksmith map state (HORDE) + BG_AB_OP_BLACKSMITH_STATE_CON_ALI = 1784, //Blacksmith map state (CON ALIENCE) + BG_AB_OP_BLACKSMITH_STATE_CON_HOR = 1785, //Blacksmith map state (CON HORDE) + BG_AB_OP_LUMBERMILL_ICON = 1844, //Lumber Mill map icon (NONE) + BG_AB_OP_LUMBERMILL_STATE_ALIENCE = 1792, //Lumber Mill map state (ALIENCE) + BG_AB_OP_LUMBERMILL_STATE_HORDE = 1793, //Lumber Mill map state (HORDE) + BG_AB_OP_LUMBERMILL_STATE_CON_ALI = 1794, //Lumber Mill map state (CON ALIENCE) + BG_AB_OP_LUMBERMILL_STATE_CON_HOR = 1795, //Lumber Mill map state (CON HORDE) + BG_AB_OP_GOLDMINE_ICON = 1843, //Gold Mine map icon (NONE) + BG_AB_OP_GOLDMINE_STATE_ALIENCE = 1787, //Gold Mine map state (ALIENCE) + BG_AB_OP_GOLDMINE_STATE_HORDE = 1788, //Gold Mine map state (HORDE) + BG_AB_OP_GOLDMINE_STATE_CON_ALI = 1789, //Gold Mine map state (CON ALIENCE + BG_AB_OP_GOLDMINE_STATE_CON_HOR = 1790, //Gold Mine map state (CON HORDE) +*/ +}; + +const uint32 BG_AB_OP_NODESTATES[5] = {1767, 1782, 1772, 1792, 1787}; + +const uint32 BG_AB_OP_NODEICONS[5] = {1842, 1846, 1845, 1844, 1843}; + +/* Note: code uses that these IDs follow each other */ +enum BG_AB_NodeObjectId +{ + BG_AB_OBJECTID_NODE_BANNER_0 = 180087, // Stables banner + BG_AB_OBJECTID_NODE_BANNER_1 = 180088, // Blacksmith banner + BG_AB_OBJECTID_NODE_BANNER_2 = 180089, // Farm banner + BG_AB_OBJECTID_NODE_BANNER_3 = 180090, // Lumber mill banner + BG_AB_OBJECTID_NODE_BANNER_4 = 180091 // Gold mine banner +}; + +enum BG_AB_ObjectType +{ + // for all 5 node points 8*5=40 objects + BG_AB_OBJECT_BANNER_NEUTRAL = 0, + BG_AB_OBJECT_BANNER_CONT_A = 1, + BG_AB_OBJECT_BANNER_CONT_H = 2, + BG_AB_OBJECT_BANNER_ALLY = 3, + BG_AB_OBJECT_BANNER_HORDE = 4, + BG_AB_OBJECT_AURA_ALLY = 5, + BG_AB_OBJECT_AURA_HORDE = 6, + BG_AB_OBJECT_AURA_CONTESTED = 7, + //gates + BG_AB_OBJECT_GATE_A = 40, + BG_AB_OBJECT_GATE_H = 41, + //buffs + BG_AB_OBJECT_SPEEDBUFF_STABLES = 42, + BG_AB_OBJECT_REGENBUFF_STABLES = 43, + BG_AB_OBJECT_BERSERKBUFF_STABLES = 44, + BG_AB_OBJECT_SPEEDBUFF_BLACKSMITH = 45, + BG_AB_OBJECT_REGENBUFF_BLACKSMITH = 46, + BG_AB_OBJECT_BERSERKBUFF_BLACKSMITH = 47, + BG_AB_OBJECT_SPEEDBUFF_FARM = 48, + BG_AB_OBJECT_REGENBUFF_FARM = 49, + BG_AB_OBJECT_BERSERKBUFF_FARM = 50, + BG_AB_OBJECT_SPEEDBUFF_LUMBER_MILL = 51, + BG_AB_OBJECT_REGENBUFF_LUMBER_MILL = 52, + BG_AB_OBJECT_BERSERKBUFF_LUMBER_MILL = 53, + BG_AB_OBJECT_SPEEDBUFF_GOLD_MINE = 54, + BG_AB_OBJECT_REGENBUFF_GOLD_MINE = 55, + BG_AB_OBJECT_BERSERKBUFF_GOLD_MINE = 56, + BG_AB_OBJECT_MAX = 57, +}; + +/* Object id templates from DB */ +enum BG_AB_ObjectTypes +{ + BG_AB_OBJECTID_BANNER_A = 180058, + BG_AB_OBJECTID_BANNER_CONT_A = 180059, + BG_AB_OBJECTID_BANNER_H = 180060, + BG_AB_OBJECTID_BANNER_CONT_H = 180061, + + BG_AB_OBJECTID_AURA_A = 180100, + BG_AB_OBJECTID_AURA_H = 180101, + BG_AB_OBJECTID_AURA_C = 180102, + + BG_AB_OBJECTID_GATE_A = 180255, + BG_AB_OBJECTID_GATE_H = 180256 +}; + +enum BG_AB_Timers +{ + BG_AB_FLAG_CAPTURING_TIME = 60000, +}; + +enum BG_AB_Score +{ + BG_AB_MAX_TEAM_SCORE = 2000, + BG_AB_WARNING_SCORE = 1800 +}; + +/* do NOT change the order, else wrong behaviour */ +enum BG_AB_BattleGroundNodes +{ + BG_AB_NODE_STABLES = 0, + BG_AB_NODE_BLACKSMITH = 1, + BG_AB_NODE_FARM = 2, + BG_AB_NODE_LUMBER_MILL = 3, + BG_AB_NODE_GOLD_MINE = 4, + + BG_AB_DYNAMIC_NODES_COUNT = 5, // dynamic nodes that can be captured + + BG_AB_SPIRIT_ALIANCE = 5, + BG_AB_SPIRIT_HORDE = 6, + + BG_AB_ALL_NODES_COUNT = 7, // all nodes (dynamic and static) +}; + +enum BG_AB_NodeStatus +{ + BG_AB_NODE_TYPE_NEUTRAL = 0, + BG_AB_NODE_TYPE_CONTESTED = 1, + BG_AB_NODE_STATUS_ALLY_CONTESTED = 1, + BG_AB_NODE_STATUS_HORDE_CONTESTED = 2, + BG_AB_NODE_TYPE_OCCUPIED = 3, + BG_AB_NODE_STATUS_ALLY_OCCUPIED = 3, + BG_AB_NODE_STATUS_HORDE_OCCUPIED = 4 +}; + +enum BG_AB_Sounds +{ + SOUND_NODE_CLAIMED = 8192, + SOUND_NODE_CAPTURED_ALLIANCE = 8173, + SOUND_NODE_CAPTURED_HORDE = 8213, + SOUND_NODE_ASSAULTED_ALLIANCE = 8174, + SOUND_NODE_ASSAULTED_HORDE = 8212, + SOUND_NEAR_VICTORY = 8456 +}; + +// x, y, z, o +const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { + {1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables + {977.0156f, 1046.616f, -44.80923f, -2.600541f}, // blacksmith + {806.1821f, 874.2723f, -55.99371f, -2.303835f}, // farm + {856.1419f, 1148.902f, 11.18469f, -2.303835f}, // lumber mill + {1146.923f, 848.1782f, -110.917f, -0.7330382f} // gold mine +}; + +// x, y, z, o, rot0, rot1, rot2, rot3 +const float BG_AB_DoorPositions[2][8] = { + {1284.597f, 1281.167f, -15.97792f, 0.7068594f, 0.012957f, -0.060288f, 0.344959f, 0.93659f}, + {708.0903f, 708.4479f, -17.8342f, -2.391099f, 0.050291f, 0.015127f, 0.929217f, -0.365784f} +}; + +// Tick intervals and given points: case 0,1,2,3,4,5 captured nodes +const uint32 BG_AB_TickIntervals[6] = {0, 12000, 9000, 6000, 3000, 1000}; +const uint32 BG_AB_TickPoints[6] = {0, 10, 10, 10, 10, 30}; + +// WorldSafeLocs ids for 5 nodes, and for ally, and horde starting location +const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT] = {895, 894, 893, 897, 896, 898, 899}; + +// x, y, z, o +const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { + {1185.71f, 1185.24f, -56.36f, 2.56f}, // stables + {990.75f, 1008.18f, -42.60f, 2.43f}, // blacksmith + {817.66f, 843.34f, -56.54f, 3.01f}, // farm + {807.46f, 1189.16f, 11.92f, 5.44f}, // lumber mill + {1146.62f, 816.94f, -98.49f, 6.14f} // gold mine +}; + +// x, y, z, o +const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] = { + {1200.03f, 1171.09f, -56.47f, 5.15f}, // stables + {1017.43f, 960.61f, -42.95f, 4.88f}, // blacksmith + {833.00f, 793.00f, -57.25f, 5.27f}, // farm + {775.17f, 1206.40f, 15.79f, 1.90f}, // lumber mill + {1207.48f, 787.00f, -83.36f, 5.51f}, // gold mine + {1354.05f, 1275.48f, -11.30f, 4.77f}, // alliance starting base + {714.61f, 646.15f, -10.87f, 4.34f} // horde starting base +}; + +struct BG_AB_BannerTimer +{ + uint32 timer; + uint8 type; + uint8 teamIndex; +}; + +class BattleGroundABScore : public BattleGroundScore +{ + public: + BattleGroundABScore(): BasesAssaulted(0), BasesDefended(0) {}; + virtual ~BattleGroundABScore() {}; + uint32 BasesAssaulted; + uint32 BasesDefended; +}; + +class BattleGroundAB : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundAB(); + ~BattleGroundAB(); + + void Update(time_t diff); + void AddPlayer(Player *plr); + void RemovePlayer(Player *plr,uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + virtual bool SetupBattleGround(); + virtual void ResetBGSubclass(); + virtual WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 team); + + /* Scorekeeping */ + virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + virtual void FillInitialWorldStates(WorldPacket& data); + + /* Nodes occupying */ + virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj); + + private: + /* Gameobject spawning/despawning */ + void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay); + void _DelBanner(uint8 node, uint8 type, uint8 teamIndex); + void _SendNodeUpdate(uint8 node); + + /* Creature spawning/despawning */ + // TODO: working, scripted peons spawning + void _NodeOccupied(uint8 node,Team team); + void _NodeDeOccupied(uint8 node); + + const char* _GetNodeName(uint8 node); + + /* Nodes info: + 0: neutral + 1: ally contested + 2: horde contested + 3: ally occupied + 4: horde occupied */ + uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT]; + uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT]; + BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT]; + int32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT]; + uint32 m_TeamScores[2]; + uint32 m_lastTick[2]; + uint32 m_HonorScoreTics[2]; + uint32 m_ReputationScoreTics[2]; + bool m_IsInformedNearVictory; +}; +#endif diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp new file mode 100644 index 000000000..9421e97b5 --- /dev/null +++ b/src/game/BattleGroundAV.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundAV.h" +#include "Creature.h" +#include "MapManager.h" +#include "Language.h" + +BattleGroundAV::BattleGroundAV() +{ + +} + +BattleGroundAV::~BattleGroundAV() +{ + +} + +void BattleGroundAV::Update(time_t diff) +{ + BattleGround::Update(diff); +} + +void BattleGroundAV::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundAVScore* sc = new BattleGroundAVScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundAV::RemovePlayer(Player* /*plr*/,uint64 /*guid*/) +{ + +} + +void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + // this is wrong way to implement these things. On official it done by gameobject spell cast. + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + uint32 SpellId = 0; + switch(Trigger) + { + case 95: + case 2606: + case 2608: + case 3326: + case 3327: + case 3328: + case 3329: + case 3330: + case 3331: + break; + default: + sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } + + if(SpellId) + Source->CastSpell(Source, SpellId, true); +} + +void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) +{ + + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found... + return; + + switch(type) + { + case SCORE_GRAVEYARDS_ASSAULTED: + ((BattleGroundAVScore*)itr->second)->GraveyardsAssaulted += value; + break; + case SCORE_GRAVEYARDS_DEFENDED: + ((BattleGroundAVScore*)itr->second)->GraveyardsDefended += value; + break; + case SCORE_TOWERS_ASSAULTED: + ((BattleGroundAVScore*)itr->second)->TowersAssaulted += value; + break; + case SCORE_TOWERS_DEFENDED: + ((BattleGroundAVScore*)itr->second)->TowersDefended += value; + break; + case SCORE_MINES_CAPTURED: + ((BattleGroundAVScore*)itr->second)->MinesCaptured += value; + break; + case SCORE_LEADERS_KILLED: + ((BattleGroundAVScore*)itr->second)->LeadersKilled += value; + break; + case SCORE_SECONDARY_OBJECTIVES: + ((BattleGroundAVScore*)itr->second)->SecondaryObjectives += value; + break; + default: + BattleGround::UpdatePlayerScore(Source,type,value); + break; + } +} diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h new file mode 100644 index 000000000..11bd08b9e --- /dev/null +++ b/src/game/BattleGroundAV.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUNDAV_H +#define __BATTLEGROUNDAV_H + +class BattleGround; + +class BattleGroundAVScore : public BattleGroundScore +{ + public: + BattleGroundAVScore() : GraveyardsAssaulted(0), GraveyardsDefended(0), TowersAssaulted(0), TowersDefended(0), MinesCaptured(0), LeadersKilled(0), SecondaryObjectives(0) {}; + virtual ~BattleGroundAVScore() {}; + uint32 GraveyardsAssaulted; + uint32 GraveyardsDefended; + uint32 TowersAssaulted; + uint32 TowersDefended; + uint32 MinesCaptured; + uint32 LeadersKilled; + uint32 SecondaryObjectives; +}; + +class BattleGroundAV : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundAV(); + ~BattleGroundAV(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + + void RemovePlayer(Player *plr,uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + //bool SetupBattleGround(); + + /* Scorekeeping */ + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + private: +}; +#endif diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp new file mode 100644 index 000000000..dcf994325 --- /dev/null +++ b/src/game/BattleGroundBE.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundBE.h" +#include "Creature.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "Language.h" + +BattleGroundBE::BattleGroundBE() +{ + m_BgObjects.resize(BG_BE_OBJECT_MAX); +} + +BattleGroundBE::~BattleGroundBE() +{ + +} + +void BattleGroundBE::Update(time_t diff) +{ + BattleGround::Update(diff); + + // after bg start we get there + if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) + { + ModifyStartDelayTime(diff); + + if (!(m_Events & 0x01)) + { + m_Events |= 0x01; + for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; i++) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + + for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++) + SpawnBGObject(i, RESPAWN_ONE_DAY); + + SetStartDelayTime(START_DELAY1); + SendMessageToAll(LANG_ARENA_ONE_MINUTE); + } + // After 30 seconds, warning is signalled + else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04)) + { + m_Events |= 0x04; + SendMessageToAll(LANG_ARENA_THIRTY_SECONDS); + } + // After 15 seconds, warning is signalled + else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08)) + { + m_Events |= 0x08; + SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS); + } + // delay expired (1 minute) + else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10)) + { + m_Events |= 0x10; + + for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; i++) + DoorOpen(i); + + for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++) + SpawnBGObject(i, 60); + + SendMessageToAll(LANG_ARENA_BEGUN); + SetStatus(STATUS_IN_PROGRESS); + SetStartDelayTime(0); + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player *plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); + } + } + + /*if(GetStatus() == STATUS_IN_PROGRESS) + { + // update something + }*/ +} + +void BattleGroundBE::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundBEScore* sc = new BattleGroundBEScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundBE::RemovePlayer(Player *plr, uint64 guid) +{ + +} + +void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + if(!killer) + { + sLog.outError("Killer player not found"); + return; + } + + BattleGround::HandleKillPlayer(player, killer); + + uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam()); + + ++m_TeamKills[killer_team_index]; // add kills to killer's team + + if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam())) + { + // all opponents killed + EndBattleGround(killer->GetTeam()); + } +} + +void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + // this is wrong way to implement these things. On official it done by gameobject spell cast. + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + //uint32 SpellId = 0; + //uint64 buff_guid = 0; + switch(Trigger) + { + case 4538: // buff trigger? + //buff_guid = m_BgObjects[BG_BE_OBJECT_BUFF_1]; + break; + case 4539: // buff trigger? + //buff_guid = m_BgObjects[BG_BE_OBJECT_BUFF_2]; + break; + default: + sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } + + //if(buff_guid) + // HandleTriggerBuff(buff_guid,Source); +} + +void BattleGroundBE::ResetBGSubclass() +{ + m_TeamKills[BG_TEAM_ALLIANCE] = 0; + m_TeamKills[BG_TEAM_HORDE] = 0; +} + +bool BattleGroundBE::SetupBattleGround() +{ + // gates + if( !AddObject(BG_BE_OBJECT_DOOR_1, BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_BE_OBJECT_DOOR_2, BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_BE_OBJECT_DOOR_3, BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_BE_OBJECT_DOOR_4, BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY) + // buffs + || !AddObject(BG_BE_OBJECT_BUFF_1, BG_BE_OBJECT_TYPE_BUFF_1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120) + || !AddObject(BG_BE_OBJECT_BUFF_2, BG_BE_OBJECT_TYPE_BUFF_2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120)) + { + sLog.outErrorDb("BatteGroundBE: Failed to spawn some object!"); + return false; + } + + return true; +} + +void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) +{ + + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found... + return; + + //there is nothing special in this score + BattleGround::UpdatePlayerScore(Source,type,value); + +} + +/* +21:45:46 id:231310 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86 +0000: 32 02 00 00 76 0e 00 00 00 00 00 00 09 00 f3 09 | 2...v........... +0010: 00 00 01 00 00 00 f1 09 00 00 01 00 00 00 f0 09 | ................ +0020: 00 00 02 00 00 00 d4 08 00 00 00 00 00 00 d8 08 | ................ +0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................ +0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................ +0050: 00 00 00 00 00 00 | ...... + +spell 32724 - Gold Team +spell 32725 - Green Team +35774 Gold Team +35775 Green Team +*/ diff --git a/src/game/BattleGroundBE.h b/src/game/BattleGroundBE.h new file mode 100644 index 000000000..f74f0a648 --- /dev/null +++ b/src/game/BattleGroundBE.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __BATTLEGROUNDBE_H +#define __BATTLEGROUNDBE_H + +class BattleGround; + +enum BattleGroundBEObjectTypes +{ + BG_BE_OBJECT_DOOR_1 = 0, + BG_BE_OBJECT_DOOR_2 = 1, + BG_BE_OBJECT_DOOR_3 = 2, + BG_BE_OBJECT_DOOR_4 = 3, + BG_BE_OBJECT_BUFF_1 = 4, + BG_BE_OBJECT_BUFF_2 = 5, + BG_BE_OBJECT_MAX = 6 +}; + +enum BattleGroundBEObjects +{ + BG_BE_OBJECT_TYPE_DOOR_1 = 183971, + BG_BE_OBJECT_TYPE_DOOR_2 = 183973, + BG_BE_OBJECT_TYPE_DOOR_3 = 183970, + BG_BE_OBJECT_TYPE_DOOR_4 = 183972, + BG_BE_OBJECT_TYPE_BUFF_1 = 184663, + BG_BE_OBJECT_TYPE_BUFF_2 = 184664 +}; + +class BattleGroundBEScore : public BattleGroundScore +{ + public: + BattleGroundBEScore() {}; + virtual ~BattleGroundBEScore() {}; +}; + +class BattleGroundBE : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundBE(); + ~BattleGroundBE(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + + void RemovePlayer(Player *plr, uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + bool SetupBattleGround(); + void ResetBGSubclass(); + void HandleKillPlayer(Player* player, Player *killer); + + /* Scorekeeping */ + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + private: + uint32 m_TeamKills[2]; // count of kills for each team +}; +#endif diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp new file mode 100644 index 000000000..165b1cf42 --- /dev/null +++ b/src/game/BattleGroundEY.cpp @@ -0,0 +1,909 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundEY.h" +#include "Creature.h" +#include "Chat.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "Language.h" +#include "Util.h" + +BattleGroundEY::BattleGroundEY() +{ + m_BuffChange = true; + m_BgObjects.resize(BG_EY_OBJECT_MAX); + m_BgCreatures.resize(BG_EY_CREATURES_MAX); + m_Points_Trigger[FEL_REALVER] = TR_FEL_REALVER_BUFF; + m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF; + m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF; + m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF; +} + +BattleGroundEY::~BattleGroundEY() +{ +} + +void BattleGroundEY::Update(time_t diff) +{ + BattleGround::Update(diff); + // after bg start we get there (once) + if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) + { + ModifyStartDelayTime(diff); + + if(!(m_Events & 0x01)) + { + m_Events |= 0x01; + + SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY); + + for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i) + SpawnBGObject(i, RESPAWN_ONE_DAY); + + SetStartDelayTime(START_DELAY0); + } + // After 1 minute, warning is signalled + else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04)) + { + m_Events |= 0x04; + SendMessageToAll(GetMangosString(LANG_BG_EY_ONE_MINUTE)); + } + // After 1,5 minute, warning is signalled + else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08)) + { + m_Events |= 0x08; + SendMessageToAll(GetMangosString(LANG_BG_EY_HALF_MINUTE)); + } + // After 2 minutes, gates OPEN ! x) + else if(GetStartDelayTime() < 0 && !(m_Events & 0x10)) + { + m_Events |= 0x10; + SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY); + SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY); + + for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + for(uint32 i = 0; i < EY_POINTS_MAX; ++i) + { + //randomly spawn buff + uint8 buff = urand(0, 2); + SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY); + } + + SendMessageToAll(GetMangosString(LANG_BG_EY_BEGIN)); + + PlaySoundToAll(SOUND_BG_START); + SetStatus(STATUS_IN_PROGRESS); + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player *plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_PREPARATION); + } + } + else if(GetStatus() == STATUS_IN_PROGRESS) + { + m_PointAddingTimer -= diff; + if(m_PointAddingTimer <= 0) + { + m_PointAddingTimer = BG_EY_FPOINTS_TICK_TIME; + if (m_TeamPointsCount[BG_TEAM_ALLIANCE] > 0) + AddPoints(ALLIANCE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_ALLIANCE] - 1]); + if (m_TeamPointsCount[BG_TEAM_HORDE] > 0) + AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]); + } + + if(m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND) + { + m_FlagsTimer -= diff; + + if(m_FlagsTimer < 0) + { + m_FlagsTimer = 0; + if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN) + RespawnFlag(true); + else + RespawnFlagAfterDrop(); + } + } + + m_TowerCapCheckTimer -= diff; + if(m_TowerCapCheckTimer <= 0) + { + //check if player joined point + /*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times + but we can count of players on current point in CheckSomeoneLeftPoint + */ + this->CheckSomeoneJoinedPoint(); + //check if player left point + this->CheckSomeoneLeftPoint(); + this->UpdatePointStatuses(); + m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME; + } + } +} + +void BattleGroundEY::AddPoints(uint32 Team, uint32 Points) +{ + uint8 team_index = GetTeamIndexByTeamId(Team); + m_TeamScores[team_index] += Points; + m_HonorScoreTics[team_index] += Points; + if (m_HonorScoreTics[team_index] >= BG_HONOR_SCORE_TICKS) + { + RewardHonorToTeam(20, Team); + m_HonorScoreTics[team_index] -= BG_HONOR_SCORE_TICKS; + } + UpdateTeamScore(Team); +} + +void BattleGroundEY::CheckSomeoneJoinedPoint() +{ + GameObject *obj = NULL; + for (uint8 i = 0; i < EY_POINTS_MAX; ++i) + { + obj = HashMapHolder::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]); + if (obj) + { + uint8 j = 0; + while (j < m_PlayersNearPoint[EY_POINTS_MAX].size()) + { + Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]); + if(!plr) + { + sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[EY_POINTS_MAX][j]); + ++j; + continue; + } + if (plr->isAlive() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS)) + { + //player joined point! + //show progress bar + UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, plr); + UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[i], plr); + UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, plr); + //add player to point + m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[EY_POINTS_MAX][j]); + //remove player from "free space" + m_PlayersNearPoint[EY_POINTS_MAX].erase(m_PlayersNearPoint[EY_POINTS_MAX].begin() + j); + } + else + ++j; + } + } + } +} + +void BattleGroundEY::CheckSomeoneLeftPoint() +{ + //reset current point counts + for (uint8 i = 0; i < 2*EY_POINTS_MAX; ++i) + m_CurrentPointPlayersCount[i] = 0; + GameObject *obj = NULL; + for(uint8 i = 0; i < EY_POINTS_MAX; ++i) + { + obj = HashMapHolder::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]); + if(obj) + { + uint8 j = 0; + while (j < m_PlayersNearPoint[i].size()) + { + Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[i][j]); + if (!plr) + { + sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[i][j]); + //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug + m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]); + m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j); + ++j; + continue; + } + if (!plr->isAlive() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS)) + //move player out of point (add him to players that are out of points + { + m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]); + m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j); + this->UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, plr); + } + else + { + //player is neat flag, so update count: + m_CurrentPointPlayersCount[2 * i + GetTeamIndexByTeamId(plr->GetTeam())]++; + ++j; + } + } + } + } +} + +void BattleGroundEY::UpdatePointStatuses() +{ + for(uint8 point = 0; point < EY_POINTS_MAX; ++point) + { + if (m_PlayersNearPoint[point].empty()) + continue; + //count new point bar status: + m_PointBarStatus[point] += (m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] < BG_EY_POINT_MAX_CAPTURERS_COUNT) ? m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] : BG_EY_POINT_MAX_CAPTURERS_COUNT; + + if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED) + //point is fully alliance's + m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED; + if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED) + //point is fully horde's + m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED; + + uint32 pointOwnerTeamId = 0; + //find which team should own this point + if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW) + pointOwnerTeamId = HORDE; + else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH) + pointOwnerTeamId = ALLIANCE; + else + pointOwnerTeamId = EY_POINT_NO_OWNER; + + for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i) + { + Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[point][i]); + if (plr) + { + this->UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], plr); + //if point owner changed we must evoke event! + if (pointOwnerTeamId != m_PointOwnedByTeam[point]) + { + //point was uncontrolled and player is from team which captured point + if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId) + this->EventTeamCapturedPoint(plr, point); + + //point was under control and player isn't from team which controlled it + if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point]) + this->EventTeamLostPoint(plr, point); + } + } + } + } +} + +void BattleGroundEY::UpdateTeamScore(uint32 Team) +{ + uint32 score = GetTeamScore(Team); + if(score >= EY_MAX_TEAM_SCORE) + { + score = EY_MAX_TEAM_SCORE; + EndBattleGround(Team); + } + + if(Team == ALLIANCE) + UpdateWorldState(EY_ALLIANCE_RESOURCES, score); + else + UpdateWorldState(EY_HORDE_RESOURCES, score); +} + +void BattleGroundEY::UpdatePointsCount(uint32 Team) +{ + if(Team == ALLIANCE) + UpdateWorldState(EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]); + else + UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]); +} + +void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point) +{ + //we MUST firstly send 0, after that we can send 1!!! + if (m_PointState[Point] == EY_POINT_UNDER_CONTROL) + { + UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 0); + if(Team == ALLIANCE) + UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 1); + else + UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 1); + } + else + { + if(Team == ALLIANCE) + UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 0); + else + UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 0); + UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 1); + } +} + +void BattleGroundEY::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map + BattleGroundEYScore* sc = new BattleGroundEYScore; + + m_PlayersNearPoint[EY_POINTS_MAX].push_back(plr->GetGUID()); + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid) +{ + // sometimes flag aura not removed :( + for (int j = EY_POINTS_MAX; j >= 0; --j) + { + for(int i = 0; i < m_PlayersNearPoint[j].size(); ++i) + if(m_PlayersNearPoint[j][i] == guid) + m_PlayersNearPoint[j].erase(m_PlayersNearPoint[j].begin() + i); + } + if(IsFlagPickedup()) + { + if(m_FlagKeeper == guid) + { + if(plr) + this->EventPlayerDroppedFlag(plr); + else + { + SetFlagPicker(0); + RespawnFlag(true); + } + } + } +} + +void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + if(!Source->isAlive()) //hack code, must be removed later + return; + + switch(Trigger) + { + case TR_BLOOD_ELF_POINT: + if(m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam()) + if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) + EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_BLOOD_ELF); + break; + case TR_FEL_REALVER_POINT: + if(m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REALVER] == Source->GetTeam()) + if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) + EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_FEL_REALVER); + break; + case TR_MAGE_TOWER_POINT: + if(m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam()) + if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) + EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_MAGE_TOWER); + break; + case TR_DRAENEI_RUINS_POINT: + if(m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam()) + if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) + EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_DRAENEI_RUINS); + break; + case 4512: + case 4515: + case 4517: + case 4519: + case 4530: + case 4531: + case 4568: + case 4569: + case 4570: + case 4571: + break; + default: + sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } +} + +bool BattleGroundEY::SetupBattleGround() +{ + // doors + if( !AddObject(BG_EY_OBJECT_DOOR_A, BG_OBJECT_A_DOOR_EY_ENTRY, 2527.6f, 1596.91f, 1262.13f, -3.12414f, -0.173642f, -0.001515f, 0.98477f, -0.008594f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_EY_OBJECT_DOOR_H, BG_OBJECT_H_DOOR_EY_ENTRY, 1803.21f, 1539.49f, 1261.09f, 3.14159f, 0.173648f, 0, 0.984808f, 0, RESPAWN_IMMEDIATELY) + // banners (alliance) + || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY) + // banners (horde) + || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY) + // banners (natural) + || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY) + // flags + || !AddObject(BG_EY_OBJECT_FLAG_NETHERSTORM, BG_OBJECT_FLAG2_EY_ENTRY, 2174.782227f, 1569.054688f, 1160.361938f, -1.448624f, 0, 0, 0.662620f, -0.748956f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_FLAG_FEL_REALVER, BG_OBJECT_FLAG1_EY_ENTRY, 2044.28f, 1729.68f, 1189.96f, -0.017453f, 0, 0, 0.008727f, -0.999962f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_FLAG_BLOOD_ELF, BG_OBJECT_FLAG1_EY_ENTRY, 2048.83f, 1393.65f, 1194.49f, 0.20944f, 0, 0, 0.104528f, 0.994522f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_FLAG_DRAENEI_RUINS, BG_OBJECT_FLAG1_EY_ENTRY, 2286.56f, 1402.36f, 1197.11f, 3.72381f, 0, 0, 0.957926f, -0.287016f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_FLAG_MAGE_TOWER, BG_OBJECT_FLAG1_EY_ENTRY, 2284.48f, 1731.23f, 1189.99f, 2.89725f, 0, 0, 0.992546f, 0.121869f, RESPAWN_ONE_DAY) + // tower cap + || !AddObject(BG_EY_OBJECT_TOWER_CAP_FEL_REALVER, BG_OBJECT_FR_TOWER_CAP_EY_ENTRY, 2024.600708f, 1742.819580f, 1195.157715f, 2.443461f, 0, 0, 0.939693f, 0.342020f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF, BG_OBJECT_BE_TOWER_CAP_EY_ENTRY, 2050.493164f, 1372.235962f, 1194.563477f, 1.710423f, 0, 0, 0.754710f, 0.656059f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS, BG_OBJECT_DR_TOWER_CAP_EY_ENTRY, 2301.010498f, 1386.931641f, 1197.183472f, 1.570796f, 0, 0, 0.707107f, 0.707107f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER, BG_OBJECT_HU_TOWER_CAP_EY_ENTRY, 2282.121582f, 1760.006958f, 1189.707153f, 1.919862f, 0, 0, 0.819152f, 0.573576f, RESPAWN_ONE_DAY) + ) + { + sLog.outErrorDb("BatteGroundEY: Failed to spawn some object BattleGround not created!"); + return false; + } + + //buffs + for (int i = 0; i < EY_POINTS_MAX; ++i) + { + AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(m_Points_Trigger[i]); + if( !at ) + { + sLog.outError("BattleGroundEY: Unknown trigger: %u", m_Points_Trigger[i]); + continue; + } + if ( !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3 + 1, Buff_Entries[1], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY) + || !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY) + ) + sLog.outError("BattleGroundEY: Cannot spawn buff"); + } + + WorldSafeLocsEntry const *sg = NULL; + sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE); + if( !sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE) ) + { + sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!"); + return false; + } + + sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE); + if( !sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE) ) + { + sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!"); + return false; + } + + return true; +} + +void BattleGroundEY::ResetBGSubclass() +{ + m_TeamScores[BG_TEAM_ALLIANCE] = 0; + m_TeamScores[BG_TEAM_HORDE] = 0; + m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0; + m_TeamPointsCount[BG_TEAM_HORDE] = 0; + m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0; + m_HonorScoreTics[BG_TEAM_HORDE] = 0; + m_FlagState = BG_EY_FLAG_STATE_ON_BASE; + m_FlagCapturedBgObjectType = 0; + m_FlagKeeper = 0; + m_DroppedFlagGUID = 0; + m_PointAddingTimer = 0; + m_TowerCapCheckTimer = 0; + + for(uint8 i = 0; i < EY_POINTS_MAX; ++i) + { + m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER; + m_PointState[i] = EY_POINT_STATE_UNCONTROLLED; + m_PointBarStatus[i] = BG_EY_PROGRESS_BAR_STATE_MIDDLE; + m_PlayersNearPoint[i].clear(); + m_PlayersNearPoint[i].reserve(15); //tip size + } + m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].clear(); + m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].reserve(30); +} + +void BattleGroundEY::RespawnFlag(bool send_message) +{ + if (m_FlagCapturedBgObjectType > 0) + SpawnBGObject(m_FlagCapturedBgObjectType, RESPAWN_ONE_DAY); + + m_FlagCapturedBgObjectType = 0; + m_FlagState = BG_EY_FLAG_STATE_ON_BASE; + SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY); + + if(send_message) + { + SendMessageToAll(GetMangosString(LANG_BG_EY_RESETED_FLAG)); + PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound... + } + + UpdateWorldState(NETHERSTORM_FLAG, 1); +} + +void BattleGroundEY::RespawnFlagAfterDrop() +{ + RespawnFlag(true); + + GameObject *obj = HashMapHolder::Find(GetDroppedFlagGUID()); + if(obj) + obj->Delete(); + else + sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GetDroppedFlagGUID()); + + SetDroppedFlagGUID(0); +} + +void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + BattleGround::HandleKillPlayer(player, killer); + EventPlayerDroppedFlag(player); +} + +void BattleGroundEY::EventPlayerDroppedFlag(Player *Source) +{ + // Drop allowed in any BG state + + if(!IsFlagPickedup()) + return; + + if(GetFlagPickerGUID() != Source->GetGUID()) + return; + + const char *message = ""; + uint8 type = 0; + + SetFlagPicker(0); + Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL); + m_FlagState = BG_EY_FLAG_STATE_ON_GROUND; + m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME; + Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true); + Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true); + if(Source->GetTeam() == ALLIANCE) + { + message = GetMangosString(LANG_BG_EY_DROPPED_FLAG); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + } + else + { + message = GetMangosString(LANG_BG_EY_DROPPED_FLAG); + type = CHAT_MSG_BG_SYSTEM_HORDE; + } + //this does not work correctly :( (it should remove flag carrier name) + UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN); + UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN); + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); +} + +void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj) +{ + if(GetStatus() != STATUS_IN_PROGRESS || this->IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10)) + return; + + const char *message; + uint8 type = 0; + message = GetMangosString(LANG_BG_EY_HAS_TAKEN_FLAG); + + if(Source->GetTeam() == ALLIANCE) + { + UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE); + } + else + { + UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER); + type = CHAT_MSG_BG_SYSTEM_HORDE; + PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE); + } + + if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE) + UpdateWorldState(NETHERSTORM_FLAG, 0); + m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER; + + SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY); + SetFlagPicker(Source->GetGUID()); + //get flag aura on player + Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true); + Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); +} + +void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + //Natural point + uint8 message_type = 0; + const char *message = ""; + uint32 Team = m_PointOwnedByTeam[Point]; + + if(!Team) + return; + + if (Team == ALLIANCE) + { + m_TeamPointsCount[BG_TEAM_ALLIANCE]--; + message_type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + message = GetMangosString(m_LoosingPointTypes[Point].MessageIdAlliance); + SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY); + SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY); + SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY); + } + else + { + m_TeamPointsCount[BG_TEAM_HORDE]--; + message_type = CHAT_MSG_BG_SYSTEM_HORDE; + message = GetMangosString(m_LoosingPointTypes[Point].MessageIdHorde); + SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY); + SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY); + SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY); + } + + SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY); + SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY); + SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY); + + //buff isn't despawned + + m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER; + m_PointState[Point] = EY_POINT_NO_OWNER; + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), message_type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); + + UpdatePointsIcons(Team, Point); + UpdatePointsCount(Team); +} + +void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + uint8 type = 0; + const char *message = ""; + uint32 Team = Source->GetTeam(); + + SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY); + SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY); + SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY); + + if (Team == ALLIANCE) + { + m_TeamPointsCount[BG_TEAM_ALLIANCE]++; + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + message = GetMangosString(m_CapturingPointTypes[Point].MessageIdAlliance); + SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY); + SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY); + SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY); + } + else + { + m_TeamPointsCount[BG_TEAM_HORDE]++; + type = CHAT_MSG_BG_SYSTEM_HORDE; + message = GetMangosString(m_CapturingPointTypes[Point].MessageIdHorde); + SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY); + SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY); + SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY); + } + + //buff isn't respawned + + m_PointOwnedByTeam[Point] = Team; + m_PointState[Point] = EY_POINT_UNDER_CONTROL; + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); + + if(m_BgCreatures[Point]) + DelCreature(Point); + + WorldSafeLocsEntry const *sg = NULL; + sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId); + if(!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team)) + sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: u, graveyard_id: %u", Point, Team, m_CapturingPointTypes[Point].GraveYardId); + + UpdatePointsIcons(Team, Point); + UpdatePointsCount(Team); +} + +void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType) +{ + if(GetStatus() != STATUS_IN_PROGRESS || this->GetFlagPickerGUID() != Source->GetGUID()) + return; + + uint8 type = 0; + uint8 team_id = 0; + const char *message = ""; + + SetFlagPicker(0); + m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN; + Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL); + + Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); + if(Source->GetTeam() == ALLIANCE) + { + PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE); + team_id = BG_TEAM_ALLIANCE; + message = GetMangosString(LANG_BG_EY_CAPTURED_FLAG_A); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + } + else + { + PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE); + team_id = BG_TEAM_HORDE; + message = GetMangosString(LANG_BG_EY_CAPTURED_FLAG_H); + type = CHAT_MSG_BG_SYSTEM_HORDE; + } + + SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY); + + m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME; + m_FlagCapturedBgObjectType = BgObjectType; + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); + + if(m_TeamPointsCount[team_id] > 0) + AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]); + + UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); +} + +void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) +{ + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found + return; + + switch(type) + { + case SCORE_FLAG_CAPTURES: // flags captured + ((BattleGroundEYScore*)itr->second)->FlagCaptures += value; + break; + default: + BattleGround::UpdatePlayerScore(Source, type, value); + break; + } +} + +void BattleGroundEY::FillInitialWorldStates(WorldPacket& data) +{ + data << uint32(EY_HORDE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_HORDE]); + data << uint32(EY_ALLIANCE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_ALLIANCE]); + data << uint32(0xab6) << uint32(0x0); + data << uint32(0xab5) << uint32(0x0); + data << uint32(0xab4) << uint32(0x0); + data << uint32(0xab3) << uint32(0x0); + data << uint32(0xab2) << uint32(0x0); + data << uint32(0xab1) << uint32(0x0); + data << uint32(0xab0) << uint32(0x0); + data << uint32(0xaaf) << uint32(0x0); + + data << uint32(DRAENEI_RUINS_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == HORDE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL); + + data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == ALLIANCE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL); + + data << uint32(DRAENEI_RUINS_UNCONTROL) << uint32(m_PointState[DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL); + + data << uint32(MAGE_TOWER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == ALLIANCE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL); + + data << uint32(MAGE_TOWER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == HORDE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL); + + data << uint32(MAGE_TOWER_UNCONTROL) << uint32(m_PointState[MAGE_TOWER] != EY_POINT_UNDER_CONTROL); + + data << uint32(FEL_REAVER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == HORDE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL); + + data << uint32(FEL_REAVER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == ALLIANCE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL); + + data << uint32(FEL_REAVER_UNCONTROL) << uint32(m_PointState[FEL_REALVER] != EY_POINT_UNDER_CONTROL); + + data << uint32(BLOOD_ELF_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == HORDE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL); + + data << uint32(BLOOD_ELF_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == ALLIANCE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL); + + data << uint32(BLOOD_ELF_UNCONTROL) << uint32(m_PointState[BLOOD_ELF] != EY_POINT_UNDER_CONTROL); + + data << uint32(NETHERSTORM_FLAG) << uint32(m_FlagState == BG_EY_FLAG_STATE_ON_BASE); + + data << uint32(0xad2) << uint32(0x1); + data << uint32(0xad1) << uint32(0x1); + data << uint32(0xabe) << uint32(GetTeamScore(HORDE)); + data << uint32(0xabd) << uint32(GetTeamScore(ALLIANCE)); + data << uint32(0xa05) << uint32(0x8e); + data << uint32(0xaa0) << uint32(0x0); + data << uint32(0xa9f) << uint32(0x0); + data << uint32(0xa9e) << uint32(0x0); + data << uint32(0xc0d) << uint32(0x17b); +} + +WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(float x, float y, float z, uint32 team) +{ + uint32 g_id = 0; + + if(team == ALLIANCE) + g_id = EY_GRAVEYARD_MAIN_ALLIANCE; + else if(team == HORDE) + g_id = EY_GRAVEYARD_MAIN_HORDE; + else + return NULL; + + float distance, nearestDistance; + + WorldSafeLocsEntry const* entry = NULL; + WorldSafeLocsEntry const* nearestEntry = NULL; + entry = sWorldSafeLocsStore.LookupEntry(g_id); + nearestEntry = entry; + + if(!entry) + { + sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!"); + return NULL; + } + + distance = (entry->x - x)*(entry->x - x) + (entry->y - y)*(entry->y - y) + (entry->z - z)*(entry->z - z); + nearestDistance = distance; + + for(uint8 i = 0; i < EY_POINTS_MAX; ++i) + { + if(m_PointOwnedByTeam[i]==team && m_PointState[i]==EY_POINT_UNDER_CONTROL) + { + entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId); + if(!entry) + sLog.outError("BattleGroundEY: Not found graveyard: %u",m_CapturingPointTypes[i].GraveYardId); + else + { + distance = (entry->x - x)*(entry->x - x) + (entry->y - y)*(entry->y - y) + (entry->z - z)*(entry->z - z); + if(distance < nearestDistance) + { + nearestDistance = distance; + nearestEntry = entry; + } + } + } + } + + return nearestEntry; +} diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h new file mode 100644 index 000000000..0e57eaa61 --- /dev/null +++ b/src/game/BattleGroundEY.h @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUNDEY_H +#define __BATTLEGROUNDEY_H + +#include "Language.h" + +class BattleGround; + +#define EY_MAX_TEAM_SCORE 2000 +#define BG_EY_FLAG_RESPAWN_TIME 10000 //10 seconds +#define BG_EY_FPOINTS_TICK_TIME 2000 //2 seconds + +enum BG_EY_WorldStates +{ + EY_ALLIANCE_RESOURCES = 2749, + EY_HORDE_RESOURCES = 2750, + EY_ALLIANCE_BASE = 2752, + EY_HORDE_BASE = 2753, + DRAENEI_RUINS_HORDE_CONTROL = 2733, + DRAENEI_RUINS_ALLIANCE_CONTROL = 2732, + DRAENEI_RUINS_UNCONTROL = 2731, + MAGE_TOWER_ALLIANCE_CONTROL = 2730, + MAGE_TOWER_HORDE_CONTROL = 2729, + MAGE_TOWER_UNCONTROL = 2728, + FEL_REAVER_HORDE_CONTROL = 2727, + FEL_REAVER_ALLIANCE_CONTROL = 2726, + FEL_REAVER_UNCONTROL = 2725, + BLOOD_ELF_HORDE_CONTROL = 2724, + BLOOD_ELF_ALLIANCE_CONTROL = 2723, + BLOOD_ELF_UNCONTROL = 2722, + PROGRESS_BAR_PERCENT_GREY = 2720, //100 = empty (only grey), 0 = blue|red (no grey) + PROGRESS_BAR_STATUS = 2719, //50 init!, 48 ... hordak bere .. 33 .. 0 = full 100% hordacky , 100 = full alliance + PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance + NETHERSTORM_FLAG = 2757, + //set to 2 when flag is picked up, and to 1 if it is dropped + NETHERSTORM_FLAG_STATE_ALLIANCE = 2769, + NETHERSTORM_FLAG_STATE_HORDE = 2770 +}; + +enum BG_EY_ProgressBarConsts +{ + BG_EY_POINT_MAX_CAPTURERS_COUNT = 5, + BG_EY_POINT_RADIUS = 70, + BG_EY_PROGRESS_BAR_DONT_SHOW = 0, + BG_EY_PROGRESS_BAR_SHOW = 1, + BG_EY_PROGRESS_BAR_PERCENT_GREY = 40, + BG_EY_PROGRESS_BAR_STATE_MIDDLE = 50, + BG_EY_PROGRESS_BAR_HORDE_CONTROLLED = 0, + BG_EY_PROGRESS_BAR_NEUTRAL_LOW = 30, + BG_EY_PROGRESS_BAR_NEUTRAL_HIGH = 70, + BG_EY_PROGRESS_BAR_ALI_CONTROLLED = 100 +}; + +enum BG_EY_Sounds +{ + //strange ids, but sure about them + BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212, + BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213, + BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174, + BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173, + BG_EY_SOUND_FLAG_RESET = 8192 +}; + +enum BG_EY_Spells +{ + BG_EY_NETHERSTORM_FLAG_SPELL = 34976, + BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991 +}; + +enum EYBattleGroundObjectEntry +{ + BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door + BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door + BG_OBJECT_FLAG1_EY_ENTRY = 184493, //Netherstorm flag (generic) + BG_OBJECT_FLAG2_EY_ENTRY = 184141, //Netherstorm flag (flagstand) + BG_OBJECT_FLAG3_EY_ENTRY = 184142, //Netherstorm flag (flagdrop) + BG_OBJECT_A_BANNER_EY_ENTRY = 184381, //Visual Banner (Alliance) + BG_OBJECT_H_BANNER_EY_ENTRY = 184380, //Visual Banner (Horde) + BG_OBJECT_N_BANNER_EY_ENTRY = 184382, //Visual Banner (Neutral) + BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt + BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt + BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt + BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083 //Draenei Tower Cap Pt +}; + +enum EYBattleGroundPointsTrigger +{ + TR_BLOOD_ELF_POINT = 4476, + TR_FEL_REALVER_POINT = 4514, + TR_MAGE_TOWER_POINT = 4516, + TR_DRAENEI_RUINS_POINT = 4518, + TR_BLOOD_ELF_BUFF = 4568, + TR_FEL_REALVER_BUFF = 4569, + TR_MAGE_TOWER_BUFF = 4570, + TR_DRAENEI_RUINS_BUFF = 4571 +}; + +enum EYBattleGroundGaveyards +{ + EY_GRAVEYARD_MAIN_ALLIANCE = 1103, + EY_GRAVEYARD_MAIN_HORDE = 1104, + EY_GRAVEYARD_FEL_REALVER = 1105, + EY_GRAVEYARD_BLOOD_ELF = 1106, + EY_GRAVEYARD_DRAENEI_RUINS = 1107, + EY_GRAVEYARD_MAGE_TOWER = 1108 +}; + +enum EYBattleGroundPoints +{ + FEL_REALVER = 0, + BLOOD_ELF = 1, + DRAENEI_RUINS = 2, + MAGE_TOWER = 3, + + EY_PLAYERS_OUT_OF_POINTS = 4, + EY_POINTS_MAX = 4 +}; + +enum EYBattleGroundCreaturesTypes +{ + EY_SPIRIT_FEL_REALVER = 0, + EY_SPIRIT_BLOOD_ELF = 1, + EY_SPIRIT_DRAENEI_RUINS = 2, + EY_SPIRIT_MAGE_TOWER = 3, + EY_SPIRIT_MAIN_ALLIANCE = 4, + EY_SPIRIT_MAIN_HORDE = 5, + + BG_EY_CREATURES_MAX = 6 +}; + +enum EYBattleGroundObjectTypes +{ + BG_EY_OBJECT_DOOR_A = 0, + BG_EY_OBJECT_DOOR_H = 1, + BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER = 2, + BG_EY_OBJECT_A_BANNER_FEL_REALVER_LEFT = 3, + BG_EY_OBJECT_A_BANNER_FEL_REALVER_RIGHT = 4, + BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER = 5, + BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT = 6, + BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT = 7, + BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER = 8, + BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT = 9, + BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT = 10, + BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER = 11, + BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT = 12, + BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT = 13, + BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER = 14, + BG_EY_OBJECT_H_BANNER_FEL_REALVER_LEFT = 15, + BG_EY_OBJECT_H_BANNER_FEL_REALVER_RIGHT = 16, + BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER = 17, + BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT = 18, + BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT = 19, + BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER = 20, + BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT = 21, + BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT = 22, + BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER = 23, + BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT = 24, + BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT = 25, + BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER = 26, + BG_EY_OBJECT_N_BANNER_FEL_REALVER_LEFT = 27, + BG_EY_OBJECT_N_BANNER_FEL_REALVER_RIGHT = 28, + BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER = 29, + BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT = 30, + BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT = 31, + BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER = 32, + BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT = 33, + BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT = 34, + BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER = 35, + BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT = 36, + BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT = 37, + BG_EY_OBJECT_TOWER_CAP_FEL_REALVER = 38, + BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF = 39, + BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS = 40, + BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER = 41, + BG_EY_OBJECT_FLAG_NETHERSTORM = 42, + BG_EY_OBJECT_FLAG_FEL_REALVER = 43, + BG_EY_OBJECT_FLAG_BLOOD_ELF = 44, + BG_EY_OBJECT_FLAG_DRAENEI_RUINS = 45, + BG_EY_OBJECT_FLAG_MAGE_TOWER = 46, + //buffs + BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER = 47, + BG_EY_OBJECT_REGENBUFF_FEL_REALVER = 48, + BG_EY_OBJECT_BERSERKBUFF_FEL_REALVER = 49, + BG_EY_OBJECT_SPEEDBUFF_BLOOD_ELF = 50, + BG_EY_OBJECT_REGENBUFF_BLOOD_ELF = 51, + BG_EY_OBJECT_BERSERKBUFF_BLOOD_ELF = 52, + BG_EY_OBJECT_SPEEDBUFF_DRAENEI_RUINS = 53, + BG_EY_OBJECT_REGENBUFF_DRAENEI_RUINS = 54, + BG_EY_OBJECT_BERSERKBUFF_DRAENEI_RUINS = 55, + BG_EY_OBJECT_SPEEDBUFF_MAGE_TOWER = 56, + BG_EY_OBJECT_REGENBUFF_MAGE_TOWER = 57, + BG_EY_OBJECT_BERSERKBUFF_MAGE_TOWER = 58, + BG_EY_OBJECT_MAX = 59 +}; + +enum BG_EY_FlagState +{ + BG_EY_FLAG_STATE_ON_BASE = 0, + BG_EY_FLAG_STATE_WAIT_RESPAWN = 1, + BG_EY_FLAG_STATE_ON_PLAYER = 2, + BG_EY_FLAG_STATE_ON_GROUND = 3 +}; + +enum EYBattleGroundPointState +{ + EY_POINT_NO_OWNER = 0, + EY_POINT_STATE_UNCONTROLLED = 0, + EY_POINT_UNDER_CONTROL = 3 +}; + +struct BattleGroundEYPointIconsStruct +{ + BattleGroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex) + : WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex) {} + uint32 WorldStateControlIndex; + uint32 WorldStateAllianceControlledIndex; + uint32 WorldStateHordeControlledIndex; +}; + +struct BattleGroundEYLoosingPointStruct +{ + BattleGroundEYLoosingPointStruct(uint32 _SpawnNeutralObjectType, uint32 _DespawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _DespawnObjectTypeHorde, uint32 _MessageIdHorde) + : SpawnNeutralObjectType(_SpawnNeutralObjectType), DespawnObjectTypeAlliance(_DespawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance), DespawnObjectTypeHorde(_DespawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde) {} + uint32 SpawnNeutralObjectType; + uint32 DespawnObjectTypeAlliance; + uint32 DespawnObjectTypeHorde; + uint32 MessageIdHorde; + uint32 MessageIdAlliance; +}; + +struct BattleGroundEYCapturingPointStruct +{ + BattleGroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveYardId) + : DespawnNeutralObjectType(_DespawnNeutralObjectType), SpawnObjectTypeAlliance(_SpawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance), SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde), GraveYardId(_GraveYardId) {} + uint32 DespawnNeutralObjectType; + uint32 SpawnObjectTypeAlliance; + uint32 SpawnObjectTypeHorde; + uint32 MessageIdHorde; + uint32 MessageIdAlliance; + uint32 GraveYardId; +}; + +const uint8 BG_EY_TickPoints[EY_POINTS_MAX] = {1, 2, 5, 10}; +const uint32 BG_EY_FlagPoints[EY_POINTS_MAX] = {75, 85, 100, 500}; + +//constant arrays: +const BattleGroundEYPointIconsStruct m_PointsIconStruct[EY_POINTS_MAX] = +{ + BattleGroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL), + BattleGroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL), + BattleGroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL), + BattleGroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL) +}; +const BattleGroundEYLoosingPointStruct m_LoosingPointTypes[EY_POINTS_MAX] = +{ + BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_LOST_A_F_RUINS, BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_LOST_H_F_RUINS), + BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_LOST_A_B_TOWER, BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_LOST_H_B_TOWER), + BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_LOST_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_LOST_H_D_RUINS), + BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_LOST_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_LOST_H_M_TOWER) +}; +const BattleGroundEYCapturingPointStruct m_CapturingPointTypes[EY_POINTS_MAX] = +{ + BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_TAKEN_A_F_RUINS, BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_TAKEN_H_F_RUINS, EY_GRAVEYARD_FEL_REALVER), + BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_TAKEN_A_B_TOWER, BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_TAKEN_H_B_TOWER, EY_GRAVEYARD_BLOOD_ELF), + BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_H_D_RUINS, EY_GRAVEYARD_DRAENEI_RUINS), + BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_H_M_TOWER, EY_GRAVEYARD_MAGE_TOWER) +}; + +class BattleGroundEYScore : public BattleGroundScore +{ + public: + BattleGroundEYScore () : FlagCaptures(0) {}; + virtual ~BattleGroundEYScore() {}; + uint32 FlagCaptures; +}; + +class BattleGroundEY : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundEY(); + ~BattleGroundEY(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + + /* BG Flags */ + uint64 GetFlagPickerGUID() const { return m_FlagKeeper; } + void SetFlagPicker(uint64 guid) { m_FlagKeeper = guid; } + bool IsFlagPickedup() const { return m_FlagKeeper != 0; } + uint8 GetFlagState() const { return m_FlagState; } + void RespawnFlag(bool send_message); + void RespawnFlagAfterDrop(); + + void RemovePlayer(Player *plr,uint64 guid); + void HandleBuffUse(uint64 const& buff_guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + void HandleKillPlayer(Player *player, Player *killer); + virtual WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 team); + virtual bool SetupBattleGround(); + virtual void ResetBGSubclass(); + void UpdateTeamScore(uint32 Team); + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + virtual void FillInitialWorldStates(WorldPacket& data); + void SetDroppedFlagGUID(uint64 guid) { m_DroppedFlagGUID = guid;} + uint64 GetDroppedFlagGUID() const { return m_DroppedFlagGUID;} + + /* Battleground Events */ + virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj); + virtual void EventPlayerDroppedFlag(Player *Source); + + private: + void EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType); + void EventTeamCapturedPoint(Player *Source, uint32 Point); + void EventTeamLostPoint(Player *Source, uint32 Point); + void UpdatePointsCount(uint32 Team); + void UpdatePointsIcons(uint32 Team, uint32 Point); + + /* Point status updating procedures */ + void CheckSomeoneLeftPoint(); + void CheckSomeoneJoinedPoint(); + void UpdatePointStatuses(); + + /* Scorekeeping */ + uint32 GetTeamScore(uint32 Team) const { return m_TeamScores[GetTeamIndexByTeamId(Team)]; } + void AddPoints(uint32 Team, uint32 Points); + + void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; } + void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; } + + uint32 m_TeamScores[2]; + uint32 m_HonorScoreTics[2]; + uint32 m_TeamPointsCount[2]; + + uint32 m_Points_Trigger[EY_POINTS_MAX]; + + uint64 m_FlagKeeper; // keepers guid + uint64 m_DroppedFlagGUID; + uint32 m_FlagCapturedBgObjectType; // type that should be despawned when flag is captured + uint8 m_FlagState; // for checking flag state + int32 m_FlagsTimer; + int32 m_TowerCapCheckTimer; + + uint32 m_PointOwnedByTeam[EY_POINTS_MAX]; + uint8 m_PointState[EY_POINTS_MAX]; + int32 m_PointBarStatus[EY_POINTS_MAX]; + typedef std::vector PlayersNearPointType; + PlayersNearPointType m_PlayersNearPoint[EY_POINTS_MAX + 1]; + uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX]; + + int32 m_PointAddingTimer; +}; +#endif diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp new file mode 100644 index 000000000..e26ed0146 --- /dev/null +++ b/src/game/BattleGroundHandler.cpp @@ -0,0 +1,622 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "Opcodes.h" +#include "Log.h" +#include "Player.h" +#include "ObjectMgr.h" +#include "WorldSession.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Object.h" +#include "BattleGroundMgr.h" +#include "BattleGroundWS.h" +#include "BattleGround.h" +#include "Language.h" + +void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 guid; + recv_data >> guid; + sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from: " I64FMT, guid); + + Creature *unit = ObjectAccessor::GetCreature(*_player, guid); + if(!unit) + return; + + if(!unit->isBattleMaster()) // it's not battlemaster + return; + + // Stop the npc if moving + unit->StopMoving(); + + uint32 bgTypeId = objmgr.GetBattleMasterBG(unit->GetEntry()); + + if(!_player->GetBGAccessByLevel(bgTypeId)) + { + // temp, must be gossip message... + SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR); + return; + } + + SendBattlegGroundList(guid, bgTypeId); +} + +void WorldSession::SendBattlegGroundList( uint64 guid, uint32 bgTypeId ) +{ + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundListPacket(&data, guid, _player, bgTypeId); + SendPacket( &data ); +} + +void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+4+4+1); + + uint64 guid; + uint32 bgTypeId; + uint32 instanceId; + uint8 joinAsGroup; + + recv_data >> guid; // battlemaster guid + recv_data >> bgTypeId; // battleground type id (DBC id) + recv_data >> instanceId; // instance id, 0 if First Available selected + recv_data >> joinAsGroup; // join as group + + sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT " for BG (Type: %u)", guid, bgTypeId); + + if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? + return; + + // ignore if we already in BG or BG queue + if(_player->InBattleGround()) + return; + + Creature *unit = ObjectAccessor::GetCreature(*_player, guid); + if(!unit) + return; + + if(!unit->isBattleMaster()) // it's not battlemaster + return; + + // check Deserter debuff + if( !_player->CanJoinToBattleground() ) + { + WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); + data << (uint32) 0xFFFFFFFE; + _player->GetSession()->SendPacket(&data); + return; + } + + // check existence + BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId); + if(!bg) + return; + + if(joinAsGroup && _player->GetGroup()) + { + Group *grp = _player->GetGroup(); + for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *member = itr->getSource(); + if(!member) continue; + + if( !member->CanJoinToBattleground() ) + { + WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); + data << (uint32) 0xFFFFFFFE; + _player->GetSession()->SendPacket(&data); + continue; + } + if (member->InBattleGroundQueueForBattleGroundType(bgTypeId)) + //player is already in this queue + continue; + + WorldPacket data; + // add to queue + uint32 queueSlot = member->AddBattleGroundQueueId(bgTypeId); + if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES) + { + // fill data packet + //member->GetSession()->SendPacket(data); + continue; + } + + // store entry point coords (same as leader entry point) + member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation()); + + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); + member->GetSession()->SendPacket(&data); + sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); + member->GetSession()->SendPacket(&data); + sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(member, bgTypeId); + } + } + else + { + if (_player->InBattleGroundQueueForBattleGroundType(bgTypeId)) + //player is already in this queue + return; + uint32 queueSlot = _player->AddBattleGroundQueueId(bgTypeId); + if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES) + { + WorldPacket data; + // fill data packet + //SendPacket(data); + return; + } + + // store entry point coords + _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation()); + + WorldPacket data; + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); + SendPacket(&data); + sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(_player, bgTypeId); + } +} + +void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ ) +{ + // empty opcode + sLog.outDebug("WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message"); + + BattleGround *bg = _player->GetBattleGround(); + if(!bg) // can't be received if player not in battleground + return; + + if(bg->GetTypeID() == BATTLEGROUND_WS) + { + uint32 count1 = 0; + uint32 count2 = 0; + + Player *ap = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID()); + if(ap) ++count2; + + Player *hp = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID()); + if(hp) ++count2; + + WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2)); + data << count1; // alliance flag holders count + /*for(uint8 i = 0; i < count1; i++) + { + data << uint64(0); // guid + data << (float)0; // x + data << (float)0; // y + }*/ + data << count2; // horde flag holders count + if(ap) + { + data << (uint64)ap->GetGUID(); + data << (float)ap->GetPositionX(); + data << (float)ap->GetPositionY(); + } + if(hp) + { + data << (uint64)hp->GetGUID(); + data << (float)hp->GetPositionX(); + data << (float)hp->GetPositionY(); + } + + SendPacket(&data); + } +} + +void WorldSession::HandleBattleGroundPVPlogdataOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: Recvd MSG_PVP_LOG_DATA Message"); + + BattleGround *bg = _player->GetBattleGround(); + if(!bg) + return; + + WorldPacket data; + sBattleGroundMgr.BuildPvpLogDataPacket(&data, bg); + SendPacket(&data); + + sLog.outDebug( "WORLD: Sent MSG_PVP_LOG_DATA Message"); +} + +void WorldSession::HandleBattleGroundListOpcode( WorldPacket &recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + + sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message"); + + uint32 bgTypeId; + recv_data >> bgTypeId; // id from DBC + + if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? + return; + + // can't be received if player not in BG queue + if(!_player->InBattleGroundQueueForBattleGroundType(bgTypeId)) + return; + + BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); + + if(!bl) + return; + + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundListPacket(&data, _player->GetGUID(), _player, bgTypeId); + SendPacket( &data ); +} + +void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 1+1+4+2+1); + + sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); + + uint8 unk1; + uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 + uint32 bgTypeId; // type id from dbc + uint16 unk; // 0x1F90 constant? + uint8 action; // enter battle 0x1, leave queue 0x0 + + recv_data >> unk1 >> unk2 >> bgTypeId >> unk >> action; + + if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? + return; + + if(!_player->InBattleGroundQueueForBattleGroundType(bgTypeId)) + return; + + BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId); + if(!bg) + return; + + uint32 queueSlot = 0; + WorldPacket data; + switch(action) + { + case 1: // port to battleground + // cheating? + if(!_player->IsInvitedForBattleGroundType(bgTypeId)) + return; + + // check if player is not deserter + if( !_player->CanJoinToBattleground() ) + { + WorldPacket data2; + data2.Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4); + data2 << (uint32) 0xFFFFFFFE; + SendPacket(&data2); + return; + } + + // if the player is dead, resurrect him before teleport + if(!_player->isAlive()) + { + _player->ResurrectPlayer(1.0f,false); + _player->SpawnCorpseBones(); + } + + // leave current group + _player->RemoveFromGroup(); + + // packet to player about BG status + queueSlot = _player->GetBattleGroundQueueIndex(bgTypeId); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime()); + _player->GetSession()->SendPacket(&data); + + // remove battleground queue status from BGmgr + sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].RemovePlayer(_player->GetGUID(), false); + + // this is still needed here if battleground "jumping" shouldn't add deserter debuff + // also this required to prevent stuck at old battleground after SetBattleGroundId set to new + if (BattleGround *currentBg = _player->GetBattleGround()) + currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true); + + _player->SetBattleGroundId(bg->GetTypeID()); + sBattleGroundMgr.SendToBattleGround(_player, bgTypeId); + bg->AddPlayer(_player); + break; + case 0: // leave queue + queueSlot = _player->GetBattleGroundQueueIndex(bgTypeId); + _player->RemoveBattleGroundQueueId(bgTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_NONE, 0, 0); + sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].RemovePlayer(_player->GetGUID(), true); + SendPacket(&data); + break; + default: + sLog.outError("Battleground port: unknown action %u", action); + break; + } +} + +void WorldSession::HandleBattleGroundLeaveOpcode( WorldPacket & /*recv_data*/ ) +{ + //CHECK_PACKET_SIZE(recv_data, 1+1+4+2); + + sLog.outDebug( "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message"); + + //uint8 unk1, unk2; + //uint32 bgTypeId; // id from DBC + //uint16 unk3; + + //recv_data >> unk1 >> unk2 >> bgTypeId >> unk3; - no used currently + + //if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? but not important in this case + // return; + + // not allow leave battleground in combat + if(_player->isInCombat()) + if(BattleGround* bg = _player->GetBattleGround()) + if(bg->GetStatus() != STATUS_WAIT_LEAVE) + return; + + _player->LeaveBattleground(); +} + +void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) +{ + // empty opcode + sLog.outDebug( "WORLD: Battleground status" ); + + WorldPacket data; + + // TODO: we must put player back to battleground in case disconnect (< 5 minutes offline time) or teleport player on login(!) from battleground map to entry point + if(_player->InBattleGround()) + { + BattleGround *bg = _player->GetBattleGround(); + if(bg) + { + uint32 queueSlot = _player->GetBattleGroundQueueIndex(bg->GetTypeID()); + if((bg->GetStatus() <= STATUS_IN_PROGRESS)) + { + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime()); + SendPacket(&data); + } + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + { + uint32 queue_id = _player->GetBattleGroundQueueId(i); + if (i == queueSlot || !queue_id) + continue; + BattleGround *bg2 = sBattleGroundMgr.GetBattleGround(queue_id); + if(bg2) + { + //in this call is small bug, this call should be filled by player's waiting time in queue + //this call nulls all timers for client : + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0); + SendPacket(&data); + } + } + } + } + else + { + // we should update all queues? .. i'm not sure if this code is correct + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + { + if(uint32 queue_id = _player->GetBattleGroundQueueId(i)) + { + if(BattleGround *bg = sBattleGroundMgr.GetBattleGround(queue_id)) + { + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0); + SendPacket(&data); + } + } + } + } +} + +void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY"); + + CHECK_PACKET_SIZE(recv_data, 8); + + BattleGround *bg = _player->GetBattleGround(); + if(!bg) + return; + + uint64 guid; + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetCreature(*_player, guid); + if(!unit) + return; + + if(!unit->isSpiritService()) // it's not spirit service + return; + + sBattleGroundMgr.SendAreaSpiritHealerQueryOpcode(_player, bg, guid); +} + +void WorldSession::HandleAreaSpiritHealerQueueOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE"); + + CHECK_PACKET_SIZE(recv_data, 8); + + BattleGround *bg = _player->GetBattleGround(); + if(!bg) + return; + + uint64 guid; + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetCreature(*_player, guid); + if(!unit) + return; + + if(!unit->isSpiritService()) // it's not spirit service + return; + + bg->AddPlayerToResurrectQueue(guid, _player->GetGUID()); +} + +void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+1+1+1); + + sLog.outDebug("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); + recv_data.hexlike(); + + // ignore if we already in BG or BG queue + if(_player->InBattleGround()) + return; + + for(int qId = 0; qId < PLAYER_MAX_BATTLEGROUND_QUEUES; ++qId) + { + if(_player->GetBattleGroundQueueId(qId) != 0) + return; + } + + uint64 guid; // arena Battlemaster guid + uint8 type; // 2v2, 3v3 or 5v5 + uint8 asGroup; // asGroup + uint8 isRated; // isRated + recv_data >> guid >> type >> asGroup >> isRated; + + Creature *unit = ObjectAccessor::GetCreature(*_player, guid); + if(!unit) + return; + + if(!unit->isBattleMaster()) // it's not battle master + return; + + uint8 arenatype = 0; + + switch(type) + { + case 0: + arenatype = ARENA_TYPE_2v2; + break; + case 1: + arenatype = ARENA_TYPE_3v3; + break; + case 2: + arenatype = ARENA_TYPE_5v5; + break; + default: + sLog.outError("Unknown arena type %u at HandleBattleGroundArenaJoin()", type); + return; + } + + if(isRated && !_player->GetArenaTeamId(type)) // player not in arena team of that size + { + _player->GetSession()->SendNotInArenaTeamPacket(arenatype); + return; + } + + if(asGroup && !_player->GetGroup()) // player not in group + return; + + // check existence + BattleGround *bg = sBattleGroundMgr.GetBattleGround(BATTLEGROUND_AA); + if(!bg) + return; + + bg->SetArenaType(arenatype); + bg->SetRated(isRated); + + if(asGroup && _player->GetGroup()) + { + Group *grp = _player->GetGroup(); + for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *member = itr->getSource(); + if(!member) continue; + + /*if (!member->CanJoinToBattleground()) + //player has deserter aura .. do nothing + */ + + if (member->InBattleGroundQueueForBattleGroundType(BATTLEGROUND_AA)) + //player is already in this queue + continue; + + // add to queue + uint32 queueSlot = member->AddBattleGroundQueueId(BATTLEGROUND_AA); + if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES) + { + WorldPacket data; + //fill data + //member->GetSession()->SendPacket(data); + continue; + } + + // store entry point coords (same as leader entry point) + member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation()); + + WorldPacket data; + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); + member->GetSession()->SendPacket(&data); + sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, BATTLEGROUND_AA); + member->GetSession()->SendPacket(&data); + sBattleGroundMgr.m_BattleGroundQueues[BATTLEGROUND_AA].AddPlayer(member, BATTLEGROUND_AA); + } + } + else + { + /*if (!member->CanJoinToBattleground()) + //player has deserter aura .. do nothing + */ + + if (_player->InBattleGroundQueueForBattleGroundType(BATTLEGROUND_AA)) + //player is already in this queue + return; + + uint32 queueSlot = _player->AddBattleGroundQueueId(BATTLEGROUND_AA); + if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES) + { + WorldPacket data; + //fill data (player is in 3 queues already) + //SendPacket(data); + return; + } + + // store entry point coords + _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation()); + + WorldPacket data; + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); + SendPacket(&data); + sBattleGroundMgr.m_BattleGroundQueues[BATTLEGROUND_AA].AddPlayer(_player, BATTLEGROUND_AA); + } +} + +void WorldSession::HandleBattleGroundReportAFK( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 playerGuid; + recv_data >> playerGuid; + Player *reportedPlayer = objmgr.GetPlayer(playerGuid); + + if(!reportedPlayer) + { + sLog.outDebug("WorldSession::HandleBattleGroundReportAFK: player not found"); + return; + } + + sLog.outDebug("WorldSession::HandleBattleGroundReportAFK: %s reported %s", _player->GetName(), reportedPlayer->GetName()); + + reportedPlayer->ReportedAfkBy(_player); +} diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp new file mode 100644 index 000000000..7c0d8429a --- /dev/null +++ b/src/game/BattleGroundMgr.cpp @@ -0,0 +1,867 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Player.h" +#include "BattleGroundMgr.h" +#include "BattleGroundAV.h" +#include "BattleGroundAB.h" +#include "BattleGroundEY.h" +#include "BattleGroundWS.h" +#include "BattleGroundNA.h" +#include "BattleGroundBE.h" +#include "BattleGroundAA.h" +#include "BattleGroundRL.h" +#include "SharedDefines.h" +#include "Policies/SingletonImp.h" +#include "MapManager.h" +#include "ObjectMgr.h" +#include "ProgressBar.h" +#include "World.h" +#include "Chat.h" + +INSTANTIATE_SINGLETON_1( BattleGroundMgr ); + +/*********************************************************/ +/*** BATTLEGROUND QUEUE SYSTEM ***/ +/*********************************************************/ + +BattleGroundQueue::BattleGroundQueue() +{ + //queues are empty, we don't have to call clear() + for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) + { + m_QueuedPlayers[i].Horde = 0; + m_QueuedPlayers[i].Alliance = 0; + //m_QueuedPlayers[i].AverageTime = 0; + } +} + +BattleGroundQueue::~BattleGroundQueue() +{ + for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) + { + m_QueuedPlayers[i].clear(); + } +} + +void BattleGroundQueue::AddPlayer(Player *plr, uint32 bgTypeId) +{ + uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(); + + //if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak + PlayerQueueInfo& info = m_QueuedPlayers[queue_id][plr->GetGUID()]; + info.InviteTime = 0; + info.IsInvitedToBGInstanceGUID = 0; + info.LastInviteTime = 0; + info.LastOnlineTime = getMSTime(); + info.Team = plr->GetTeam(); + + //add player to waiting order queue + m_PlayersSortedByWaitTime[queue_id].push_back(plr->GetGUID()); + + if(plr->GetTeam() == ALLIANCE) + ++m_QueuedPlayers[queue_id].Alliance; + else + ++m_QueuedPlayers[queue_id].Horde; + + this->Update(bgTypeId, queue_id); + + if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) ) + { + BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgTypeId); + char const* bgName = bg->GetName(); + + uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id); + uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id); + + // replace hardcoded max level by player max level for nice output + if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); + + int8 MinPlayers = bg->GetMinPlayersPerTeam(); + + uint8 qHorde = m_QueuedPlayers[queue_id].Horde; + uint8 qAlliance = m_QueuedPlayers[queue_id].Alliance; + + // Show queue status to player only (when joining queue) + if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) + { + ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, + bgName, q_min_level, q_max_level, qAlliance, MinPlayers - qAlliance, qHorde, MinPlayers - qHorde); + } + // System message + else + { + sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, + bgName, q_min_level, q_max_level, qAlliance, MinPlayers - qAlliance, qHorde, MinPlayers - qHorde); + } + } +} + +void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) +{ + Player *plr = objmgr.GetPlayer(guid); + + uint32 queue_id = 0; + QueuedPlayersMap::iterator itr; + bool IsSet = false; + if(!plr) + { //player is offline, we need to find him somewhere in queues + /// there is something wrong if this code is run, because we have in queue only online players! + sLog.outError("Battleground: removing offline player from BG queue - this might not happen, but it should not cause crash"); + for (uint32 i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) + { + itr = m_QueuedPlayers[i].find(guid); + if(itr != m_QueuedPlayers[i].end()) + { + queue_id = i; + IsSet = true; + break; + } + } + } + else + { //player is online, we have his level, so we can find exact queue from his level + queue_id = plr->GetBattleGroundQueueIdFromLevel(); + itr = m_QueuedPlayers[queue_id].find(guid); + IsSet = true; + } + + //all variables are set, so remove player + //remove player from time queue + m_PlayersSortedByWaitTime[queue_id].remove(guid); + + if (IsSet && itr != m_QueuedPlayers[queue_id].end()) + { + if (!itr->second.IsInvitedToBGInstanceGUID) + { + if(itr->second.Team == ALLIANCE) + --m_QueuedPlayers[queue_id].Alliance; + else + --m_QueuedPlayers[queue_id].Horde; + } + else + { + if (decreaseInvitedCount) + { + BattleGround* bg = sBattleGroundMgr.GetBattleGround(itr->second.IsInvitedToBGInstanceGUID); + if (bg) + bg->DecreaseInvitedCount(itr->second.Team); + } + } + m_QueuedPlayers[queue_id].erase(itr); + } +} + +/* +this method is called when player is inserted, or removed from BG Queue - there is only one player's status changed, so we don't use while(true) cycles to invite whole queue +add method calls this by itself, the remove method could works in other way, so you have to call this method from other code after calling remove method +*/ +void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id) +{ + if (queue_id >= MAX_BATTLEGROUND_QUEUES) + { + //this is error, that caused crashes (not in , but now it shouldn't) + sLog.outError("BattleGroundQueue::Update() called for non existing queue type - this can cause crash, pls report problem, if this is the last line of error log before crash"); + return; + } + + //if no players in queue ... do nothing + if (this->m_QueuedPlayers[queue_id].Alliance == 0 && this->m_QueuedPlayers[queue_id].Horde == 0) + return; + + //battleground with free slot for player should be always the last in this queue + for (BGFreeSlotQueueType::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); ++itr) + { + // battleground is running, so if: + // DO NOT allow queue manager to invite new player to running arena + if ((*itr)->isBattleGround() && (*itr)->GetQueueType() == queue_id && (*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE) + { + //we must check both teams + BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!) + // and iterator is invalid + + //check if there are some players in queue + if (m_QueuedPlayers[queue_id].Alliance > 0 || m_QueuedPlayers[queue_id].Horde > 0) + { + for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();) + { + Player* plr = objmgr.GetPlayer(*itr2); + if (!plr) + { + //something is wrong!, kick player from queue + sLog.outError("BATTLEGROUND: problem with inviting offline player to Battleground queue .... pls report bug"); + uint64 oldval = *itr2; + itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); + RemovePlayer(oldval, true); + continue; + } + + // player will be invited, if in bg there is a free slot for him + if (bg->HasFreeSlotsForTeam(plr->GetTeam())) + { + // iterator to player's queue status + QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2); + + // remove him from time queue + itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); + + // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and pls report it) + if (itrPlayerStatus == m_QueuedPlayers[queue_id].end()) + continue; + + // check if player is not already invited + if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID) + { + itrPlayerStatus->second.IsInvitedToBGInstanceGUID = bg->GetInstanceID(); + itrPlayerStatus->second.InviteTime = getMSTime(); + itrPlayerStatus->second.LastInviteTime = getMSTime(); + if(itrPlayerStatus->second.Team == ALLIANCE) + --m_QueuedPlayers[queue_id].Alliance; + else + --m_QueuedPlayers[queue_id].Horde; + sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID()); + + WorldPacket data; + uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgTypeId); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0); + plr->GetSession()->SendPacket(&data); + } + } + else + ++itr2; + + //if battleground is FULL, then it is removed from free slot queue - not yet implemented! + if (!bg->HasFreeSlots()) + { + //if bg is full, there is no need to invite other players, so break + break; + //remove BG from BGFreeSlotQueue - not used now, in this system we don't remove BGs from free queue + //bg->RemoveFromBGFreeSlotQueue() --- do not uncomment this - not yet implemented + } + } + } + } + } + + /* THIS IS A CASE THAT IN QUEUE THERE IS ENOUGHT PLAYERS TO START NEW BG */ + //itr->end is the last BG - template, which is not already started! + + /* here will be a most of change, when we create battlegrounds instantiated */ + /* if (there is enough players to start new BG) + Battleground* newbg = sBattleGroundMgr.CreateNewBattleGround(bgTypeId) + - that function will use the COPY constructor on BattleGround class ( in bg manager we should have one battleground as a template + (battleground template will be used only to create new BGs, it will be an instance of BG class, but it won't ever start) */ + + /* following code is working with current Battleground system and it should be removed, when BGs will work like instances */ + BattleGround* bg2 = sBattleGroundMgr.GetBattleGround(bgTypeId); + if (bg2->GetQueueType() != MAX_BATTLEGROUND_QUEUES || bg2->GetStatus() != STATUS_WAIT_QUEUE) + return; + if (m_QueuedPlayers[queue_id].Alliance >= bg2->GetMinPlayersPerTeam() && m_QueuedPlayers[queue_id].Horde >= bg2->GetMinPlayersPerTeam()) + { + bg2->SetStatus(STATUS_WAIT_JOIN); + bg2->SetQueueType(queue_id); + + for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();) + { + Player* plr = objmgr.GetPlayer(*itr2); + if (!plr) + { + //something is wrong!, kick player from queue + sLog.outError("BATTLEGROUND: problem with inviting offline player to Battleground queue .... pls report bug"); + uint64 oldval = *itr2; + itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); + RemovePlayer(oldval, true); + continue; + } + + /* TODO: (i'm not sure this code will be useful: + here should be some condition like if (bg2->isArena() && bg2->isRated()) + { + invite players from 1 certain group on each faction to play arena match + } else if ....and existing code + */ + // player will be invited, if in bg there is a free slot for him + if (bg2->HasFreeSlotsForTeam(plr->GetTeam())) + { + // iterator to player's queue status + QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2); + + // remove him from time queue + itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); + + // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it) + if (itrPlayerStatus == m_QueuedPlayers[queue_id].end()) + continue; + + //check if player is not already invited + if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID) + { + itrPlayerStatus->second.IsInvitedToBGInstanceGUID = bg2->GetInstanceID(); + itrPlayerStatus->second.InviteTime = getMSTime(); + itrPlayerStatus->second.LastInviteTime = getMSTime(); + + if(itrPlayerStatus->second.Team == ALLIANCE) + --m_QueuedPlayers[queue_id].Alliance; + else + --m_QueuedPlayers[queue_id].Horde; + + sBattleGroundMgr.InvitePlayer(plr, bg2->GetInstanceID()); + + WorldPacket data; + uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgTypeId); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0); + plr->GetSession()->SendPacket(&data); + } + } + else + ++itr2; + } + bg2->StartBattleGround(); + } +} + +/*********************************************************/ +/*** BATTLEGROUND QUEUE EVENTS ***/ +/*********************************************************/ + +bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 p_time) +{ + Player* plr = objmgr.GetPlayer( m_PlayerGuid ); + + // player logged off (we should do nothing, he is correctly removed from queue in another procedure) + if (!plr) + return true; + + // Player can be in another BG queue and must be removed in normal way in any case + // // player is already in battleground ... do nothing (battleground queue status is deleted when player is teleported to BG) + // if (plr->GetBattleGroundId() > 0) + // return true; + + BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID); + if (!bg) + return true; + + uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID()); + if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue + { + // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems + BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()]; + BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid); + if (qItr != qpMap.end() && qItr->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID) + { + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME/2, 0); + plr->GetSession()->SendPacket(&data); + } + } + return true; //event will be deleted +} + +void BGQueueInviteEvent::Abort(uint64 /*e_time*/) +{ + //this should not be called + sLog.outError("Battleground invite event ABORTED!"); +} + +bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) +{ + Player* plr = objmgr.GetPlayer( m_PlayerGuid ); + if (!plr) + // player logged off (we should do nothing, he is correctly removed from queue in another procedure) + return true; + + // Player can be in another BG queue and must be removed in normal way in any case + //if (plr->InBattleGround()) + // // player is already in battleground ... do nothing (battleground queue status is deleted when player is teleported to BG) + // return true; + + BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID); + if (!bg) + return true; + + uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID()); + if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue (base at player data + { + // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems + BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()]; + BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid); + if (qItr!=qpMap.end() && qItr->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID) + { + plr->RemoveBattleGroundQueueId(bg->GetTypeID()); + sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].RemovePlayer(m_PlayerGuid, true); + sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].Update(bg->GetTypeID(), bg->GetQueueType()); + + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_NONE, 0, 0); + plr->GetSession()->SendPacket(&data); + } + } + + //event will be deleted + return true; +} + +void BGQueueRemoveEvent::Abort(uint64 /*e_time*/) +{ + //this should not be called + sLog.outError("Battleground remove event ABORTED!"); +} + +/*********************************************************/ +/*** BATTLEGROUND MANAGER ***/ +/*********************************************************/ + +BattleGroundMgr::BattleGroundMgr() +{ + m_BattleGrounds.clear(); +} + +BattleGroundMgr::~BattleGroundMgr() +{ + for(std::map::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr) + delete itr->second; + m_BattleGrounds.clear(); +} + +void BattleGroundMgr::Update(time_t diff) +{ + for(BattleGroundSet::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr) + itr->second->Update(diff); +} + +void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2) +{ + // we can be in 3 queues in same time... + if(StatusID == 0) + { + data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3); + *data << uint32(QueueSlot); // queue id (0...2) + *data << uint64(0); + return; + } + + data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4)); + *data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time + // uint64 in client + *data << uint64( uint64(bg->GetArenaType()) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) ); + *data << uint32(0); // unknown + // alliance/horde for BG and skirmish/rated for Arenas + *data << uint8(bg->isArena() ? (bg->isRated() ? 1 : 0) : bg->GetTeamIndexByTeamId(team)); + *data << uint32(StatusID); // status + switch(StatusID) + { + case STATUS_WAIT_QUEUE: // status_in_queue + *data << uint32(Time1); // average wait time, milliseconds + *data << uint32(Time2); // time in queue, updated every minute? + break; + case STATUS_WAIT_JOIN: // status_invite + *data << uint32(bg->GetMapId()); // map id + *data << uint32(Time1); // time to remove from queue, milliseconds + break; + case STATUS_IN_PROGRESS: // status_in_progress + *data << uint32(bg->GetMapId()); // map id + *data << uint32(Time1); // 0 at bg start, 120000 after bg end, time to bg auto leave, milliseconds + *data << uint32(Time2); // time from bg start, milliseconds + *data << uint8(0x1); // unk sometimes 0x0! + break; + default: + sLog.outError("Unknown BG status!"); + break; + } +} + +void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) +{ + uint8 type = (bg->isArena() ? 1 : 0); + // last check on 2.4.1 + data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize())); + *data << uint8(type); // seems to be type (battleground=0/arena=1) + if(type) // arena + { + for(uint8 i = 0; i < 2; i++) + { + *data << uint32(3000+1+i); // rating change: showed value - 3000 + *data << uint32(0); // 2.4.0, has some to do with rating change... + *data << uint8(0); // some unknown string + } + } + + if(bg->GetWinner() == 2) + { + *data << uint8(0); // bg in progress + } + else + { + *data << uint8(1); // bg ended + *data << uint8(bg->GetWinner()); // who win + } + + *data << (int32)(bg->GetPlayerScoresSize()); + + for(std::map::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr) + { + *data << (uint64)itr->first; + *data << (int32)itr->second->KillingBlows; + if(type) + { + // this value is team (green/gold)? + // that part probably wrong + Player *plr = objmgr.GetPlayer(itr->first); + if(plr) + { + if(plr->GetTeam() == HORDE) + *data << uint8(0); + else if(plr->GetTeam() == ALLIANCE) + *data << uint8(1); + else + *data << uint8(0); + } + else + *data << uint8(0); + } + else + { + *data << (int32)itr->second->HonorableKills; + *data << (int32)itr->second->Deaths; + *data << (int32)itr->second->BonusHonor; // bonus honor + } + *data << (int32)itr->second->DamageDone; // damage done + *data << (int32)itr->second->HealingDone; // healing done + switch(bg->GetTypeID()) // battleground specific things + { + case BATTLEGROUND_AV: + *data << (uint32)0x00000005; // count of next fields + *data << (uint32)((BattleGroundAVScore*)itr->second)->GraveyardsAssaulted; // GraveyardsAssaulted + *data << (uint32)((BattleGroundAVScore*)itr->second)->GraveyardsDefended; // GraveyardsDefended + *data << (uint32)((BattleGroundAVScore*)itr->second)->TowersAssaulted; // TowersAssaulted + *data << (uint32)((BattleGroundAVScore*)itr->second)->TowersDefended; // TowersDefended + *data << (uint32)((BattleGroundAVScore*)itr->second)->MinesCaptured; // MinesCaptured + break; + case BATTLEGROUND_WS: + *data << (uint32)0x00000002; // count of next fields + *data << (uint32)((BattleGroundWGScore*)itr->second)->FlagCaptures; // flag captures + *data << (uint32)((BattleGroundWGScore*)itr->second)->FlagReturns; // flag returns + break; + case BATTLEGROUND_AB: + *data << (uint32)0x00000002; // count of next fields + *data << (uint32)((BattleGroundABScore*)itr->second)->BasesAssaulted; // bases asssulted + *data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended; // bases defended + break; + case BATTLEGROUND_EY: + *data << (uint32)0x00000001; // count of next fields + *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures; // flag captures + break; + case BATTLEGROUND_NA: + case BATTLEGROUND_BE: + case BATTLEGROUND_AA: + case BATTLEGROUND_RL: + *data << (int32)0; // 0 + break; + default: + sLog.outDebug("Unhandled MSG_PVP_LOG_DATA for BG id %u", bg->GetTypeID()); + *data << (int32)0; + break; + } + } +} + +void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId) +{ + /*bgTypeId is: + 0 - Your group has joined a battleground queue, but you are not eligible + 1 - Your group has joined the queue for AV + 2 - Your group has joined the queue for WS + 3 - Your group has joined the queue for AB + 4 - Your group has joined the queue for NA + 5 - Your group has joined the queue for BE Arena + 6 - Your group has joined the queue for All Arenas + 7 - Your group has joined the queue for EotS*/ + data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4); + *data << uint32(bgTypeId); +} + +void BattleGroundMgr::BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value) +{ + data->Initialize(SMSG_UPDATE_WORLD_STATE, 4+4); + *data << uint32(field); + *data << uint32(value); +} + +void BattleGroundMgr::BuildPlaySoundPacket(WorldPacket *data, uint32 soundid) +{ + data->Initialize(SMSG_PLAY_SOUND, 4); + *data << uint32(soundid); +} + +void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr) +{ + data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8); + *data << uint64(plr->GetGUID()); +} + +void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr) +{ + data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8); + *data << uint64(plr->GetGUID()); +} + +void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID) +{ + // set invited player counters: + BattleGround* bg = this->GetBattleGround(bgInstanceGUID); + if(!bg) + return; + + bg->IncreaseInvitedCount(plr->GetTeam()); + plr->SetInviteForBattleGroundType(bg->GetTypeID()); + // create invite events: + //add events to player's counters ---- this is not good way - there should be something like global event processor, where we should add those events + BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), bgInstanceGUID); + plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME/2)); + BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), bgInstanceGUID, plr->GetTeam()); + plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME)); +} + +uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO) +{ + // Create the BG + BattleGround *bg = NULL; + + switch(bgTypeId) + { + case BATTLEGROUND_AV: bg = new BattleGroundAV; break; + case BATTLEGROUND_WS: bg = new BattleGroundWS; break; + case BATTLEGROUND_AB: bg = new BattleGroundAB; break; + case BATTLEGROUND_NA: bg = new BattleGroundNA; break; + case BATTLEGROUND_BE: bg = new BattleGroundBE; break; + case BATTLEGROUND_AA: bg = new BattleGroundAA; break; + case BATTLEGROUND_EY: bg = new BattleGroundEY; break; + case BATTLEGROUND_RL: bg = new BattleGroundRL; break; + default:bg = new BattleGround; break; // placeholder for non implemented BG + } + + bg->SetMapId(MapID); + bg->Reset(); + if(!bg->SetupBattleGround()) + { + delete bg; + return 0; + } + + BattlemasterListEntry const *bl = sBattlemasterListStore.LookupEntry(bgTypeId); + //in previous method is checked if exists entry in sBattlemasterListStore, so no check needed + if (bl) + { + bg->SetArenaorBGType(bl->type == TYPE_ARENA); + } + + bg->SetTypeID(bgTypeId); + bg->SetInstanceID(bgTypeId); // temporary + bg->SetMinPlayersPerTeam(MinPlayersPerTeam); + bg->SetMaxPlayersPerTeam(MaxPlayersPerTeam); + bg->SetMinPlayers(MinPlayersPerTeam*2); + bg->SetMaxPlayers(MaxPlayersPerTeam*2); + bg->SetName(BattleGroundName); + bg->SetTeamStartLoc(ALLIANCE, Team1StartLocX, Team1StartLocY, Team1StartLocZ, Team1StartLocO); + bg->SetTeamStartLoc(HORDE, Team2StartLocX, Team2StartLocY, Team2StartLocZ, Team2StartLocO); + bg->SetLevelRange(LevelMin, LevelMax); + //add BaggleGround instance to FreeSlotQueue + bg->AddToBGFreeSlotQueue(); + + AddBattleGround(bg->GetInstanceID(), bg); + //sLog.outDetail("BattleGroundMgr: Created new battleground: %u %s (Map %u, %u players per team, Levels %u-%u)", bg_TypeID, bg->m_Name, bg->m_MapId, bg->m_MaxPlayersPerTeam, bg->m_LevelMin, bg->m_LevelMax); + return bg->GetInstanceID(); +} + +void BattleGroundMgr::CreateInitialBattleGrounds() +{ + float AStartLoc[4]; + float HStartLoc[4]; + uint32 MaxPlayersPerTeam, MinPlayersPerTeam, MinLvl, MaxLvl, start1, start2; + BattlemasterListEntry const *bl; + WorldSafeLocsEntry const *start; + + uint32 count = 0; + + // 0 1 2 3 4 5 6 7 8 + QueryResult *result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 battlegrounds. DB table `battleground_template` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 bgTypeID = fields[0].GetUInt32(); + + // can be overwrited by values from DB + bl = sBattlemasterListStore.LookupEntry(bgTypeID); + if(!bl) + { + sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.",bgTypeID); + continue; + } + + MaxPlayersPerTeam = bl->maxplayersperteam; + MinPlayersPerTeam = bl->maxplayersperteam/2; + MinLvl = bl->minlvl; + MaxLvl = bl->maxlvl; + + if(fields[1].GetUInt32()) + MinPlayersPerTeam = fields[1].GetUInt32(); + + if(fields[2].GetUInt32()) + MaxPlayersPerTeam = fields[2].GetUInt32(); + + if(fields[3].GetUInt32()) + MinLvl = fields[3].GetUInt32(); + + if(fields[4].GetUInt32()) + MaxLvl = fields[4].GetUInt32(); + + start1 = fields[5].GetUInt32(); + + start = sWorldSafeLocsStore.LookupEntry(start1); + if(start) + { + AStartLoc[0] = start->x; + AStartLoc[1] = start->y; + AStartLoc[2] = start->z; + AStartLoc[3] = fields[6].GetFloat(); + } + else if(bgTypeID == BATTLEGROUND_AA) + { + AStartLoc[0] = 0; + AStartLoc[1] = 0; + AStartLoc[2] = 0; + AStartLoc[3] = fields[6].GetFloat(); + } + else + { + sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.",bgTypeID,start1); + continue; + } + + start2 = fields[7].GetUInt32(); + + start = sWorldSafeLocsStore.LookupEntry(start2); + if(start) + { + HStartLoc[0] = start->x; + HStartLoc[1] = start->y; + HStartLoc[2] = start->z; + HStartLoc[3] = fields[8].GetFloat(); + } + else if(bgTypeID == BATTLEGROUND_AA) + { + HStartLoc[0] = 0; + HStartLoc[1] = 0; + HStartLoc[2] = 0; + HStartLoc[3] = fields[8].GetFloat(); + } + else + { + sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.",bgTypeID,start2); + continue; + } + + //sLog.outDetail("Creating battleground %s, %u-%u", bl->name[sWorld.GetDBClang()], MinLvl, MaxLvl); + if(!CreateBattleGround(bgTypeID, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, bl->name[sWorld.GetDefaultDbcLocale()], bl->mapid[0], AStartLoc[0], AStartLoc[1], AStartLoc[2], AStartLoc[3], HStartLoc[0], HStartLoc[1], HStartLoc[2], HStartLoc[3])) + continue; + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u battlegrounds", count ); +} + +void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player* plr, uint32 bgTypeId) +{ + uint32 PlayerLevel = 10; + + if(plr) + PlayerLevel = plr->getLevel(); + + data->Initialize(SMSG_BATTLEFIELD_LIST); + *data << uint64(guid); // battlemaster guid + *data << uint32(bgTypeId); // battleground id + if(bgTypeId == BATTLEGROUND_AA) // arena + { + *data << uint8(5); // unk + *data << uint32(0); // unk + } + else // battleground + { + *data << uint8(0x00); // unk + + size_t count_pos = data->wpos(); + uint32 count = 0; + *data << uint32(0x00); // number of bg instances + + for(std::map::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr) + { + if(itr->second->GetTypeID() == bgTypeId && (PlayerLevel >= itr->second->GetMinLevel()) && (PlayerLevel <= itr->second->GetMaxLevel())) + { + *data << uint32(itr->second->GetInstanceID()); + ++count; + } + } + data->put( count_pos , count); + } +} + +void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 bgTypeId) +{ + BattleGround *bg = GetBattleGround(bgTypeId); + if(bg) + { + uint32 mapid = bg->GetMapId(); + float x, y, z, O; + bg->GetTeamStartLoc(pl->GetTeam(), x, y, z, O); + + sLog.outDetail("BATTLEGROUND: Sending %s to map %u, X %f, Y %f, Z %f, O %f", pl->GetName(), mapid, x, y, z, O); + pl->TeleportTo(mapid, x, y, z, O); + } +} + +void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid) +{ + WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); + uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds + if(time_ == uint32(-1)) + time_ = 0; + data << guid << time_; + pl->GetSession()->SendPacket(&data); +} diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h new file mode 100644 index 000000000..193e5f430 --- /dev/null +++ b/src/game/BattleGroundMgr.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUNDMGR_H +#define __BATTLEGROUNDMGR_H + +#include "BattleGround.h" +#include "Policies/Singleton.h" + +class BattleGround; + +//TODO it is not possible to have this structure, because we should have BattlegroundSet for each queue +//so i propose to change this type to array 1..MAX_BATTLEGROUND_TYPES of sets or maps.. +typedef std::map BattleGroundSet; +//typedef std::map BattleGroundQueueSet; +typedef std::deque BGFreeSlotQueueType; + +#define MAX_BATTLEGROUND_QUEUES 7 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+ + +#define MAX_BATTLEGROUND_TYPES 9 // each BG type will be in array + +struct PlayerQueueInfo +{ + uint32 InviteTime; // first invite time + uint32 LastInviteTime; // last invite time + uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG + uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes + uint32 Team; // Player team (ALLIANCE/HORDE) + bool IsRated; + bool AsGroup; // uint32 GroupId; + uint8 ArenaType; +}; + +struct PlayersCount +{ + uint32 Alliance; + uint32 Horde; +}; + +template class bgqueue: public std::map<_Kty, _Ty> +{ + public: + uint32 Alliance; + uint32 Horde; + //bool Ready; // not used now + //uint32 AverageTime; //not already implemented (it should be average time in queue for last 10 players) +}; + +class BattleGroundQueue +{ + public: + BattleGroundQueue(); + ~BattleGroundQueue(); +/* + uint32 GetType(); + void SetType(uint32 type);*/ + + void Update(uint32 bgTypeId, uint32 queue_id); + + void AddPlayer(Player *plr, uint32 bgTypeId); + void RemovePlayer(uint64 guid, bool decreaseInvitedCount); + + typedef bgqueue QueuedPlayersMap; + QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES]; + typedef std::list PlayerGuidsSortedByTimeQueue; + PlayerGuidsSortedByTimeQueue m_PlayersSortedByWaitTime[MAX_BATTLEGROUND_QUEUES]; +}; + +/* + This class is used to invite player to BG again, when minute lasts from his first invitation + it is capable to solve all possibilities +*/ +class BGQueueInviteEvent : public BasicEvent +{ + public: + BGQueueInviteEvent(uint64 pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {}; + virtual ~BGQueueInviteEvent() {}; + + virtual bool Execute(uint64 e_time, uint32 p_time); + virtual void Abort(uint64 e_time); + private: + uint64 m_PlayerGuid; + uint32 m_BgInstanceGUID; + +}; + +/* + This class is used to remove player from BG queue after 2 minutes from first invitation +*/ +class BGQueueRemoveEvent : public BasicEvent +{ + public: + BGQueueRemoveEvent(uint64 pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam) {}; + virtual ~BGQueueRemoveEvent() {}; + + virtual bool Execute(uint64 e_time, uint32 p_time); + virtual void Abort(uint64 e_time); + private: + uint64 m_PlayerGuid; + uint32 m_BgInstanceGUID; + uint32 m_PlayersTeam; +}; + + +class BattleGroundMgr +{ + public: + /* Construction */ + BattleGroundMgr(); + ~BattleGroundMgr(); + void Update(time_t diff); + + /* Packet Building */ + void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr); + void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr); + void BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player *plr, uint32 bgTypeId); + void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId); + void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value); + void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg); + void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2); + void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid); + + /* Player invitation */ + // called from Queue update, or from Addplayer to queue + void InvitePlayer(Player* plr, uint32 bgInstanceGUID); + + /* Battlegrounds */ + BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); }; + BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); }; + + BattleGround* GetBattleGround(uint8 ID) + { + BattleGroundSet::iterator i = m_BattleGrounds.find(ID); + if(i != m_BattleGrounds.end()) + return i->second; + else + return NULL; + }; + + uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO); + + inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; }; + + void CreateInitialBattleGrounds(); + + void SendToBattleGround(Player *pl, uint32 bgTypeId); + + /* Battleground queues */ + //these queues are instantiated when creating BattlegroundMrg + BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_TYPES]; // public, because we need to access them in BG handler code + + BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPES]; + + void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid); + + private: + + /* Battlegrounds */ + BattleGroundSet m_BattleGrounds; +}; + +#define sBattleGroundMgr MaNGOS::Singleton::Instance() +#endif diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp new file mode 100644 index 000000000..ac4705f5c --- /dev/null +++ b/src/game/BattleGroundNA.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundNA.h" +#include "Creature.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "Language.h" + +BattleGroundNA::BattleGroundNA() +{ + m_BgObjects.resize(BG_NA_OBJECT_MAX); +} + +BattleGroundNA::~BattleGroundNA() +{ + +} + +void BattleGroundNA::Update(time_t diff) +{ + BattleGround::Update(diff); + + // after bg start we get there + if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) + { + ModifyStartDelayTime(diff); + + if (!(m_Events & 0x01)) + { + m_Events |= 0x01; + for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; i++) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + + SetStartDelayTime(START_DELAY1); + SendMessageToAll(LANG_ARENA_ONE_MINUTE); + } + // After 30 seconds, warning is signalled + else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04)) + { + m_Events |= 0x04; + SendMessageToAll(LANG_ARENA_THIRTY_SECONDS); + } + // After 15 seconds, warning is signalled + else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08)) + { + m_Events |= 0x08; + SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS); + } + // delay expired (1 minute) + else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10)) + { + m_Events |= 0x10; + + for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; i++) + DoorOpen(i); + + SendMessageToAll(LANG_ARENA_BEGUN); + SetStatus(STATUS_IN_PROGRESS); + SetStartDelayTime(0); + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player *plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); + } + } + + /*if(GetStatus() == STATUS_IN_PROGRESS) + { + // update something + }*/ +} + +void BattleGroundNA::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundNAScore* sc = new BattleGroundNAScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/) +{ + +} + +void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + if(!killer) + { + sLog.outError("BattleGroundNA: Killer player not found"); + return; + } + + BattleGround::HandleKillPlayer(player, killer); + + uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam()); + + ++m_TeamKills[killer_team_index]; // add kills to killer's team + + if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam())) + { + // all opponents killed + EndBattleGround(killer->GetTeam()); + } +} + +void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + //uint32 SpellId = 0; + //uint64 buff_guid = 0; + switch(Trigger) + { + case 4536: // buff trigger? + case 4537: // buff trigger? + break; + default: + sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } + + //if(buff_guid) + // HandleTriggerBuff(buff_guid,Source); +} + +void BattleGroundNA::ResetBGSubclass() +{ + m_TeamKills[BG_TEAM_ALLIANCE] = 0; + m_TeamKills[BG_TEAM_HORDE] = 0; +} + +bool BattleGroundNA::SetupBattleGround() +{ + // gates + if( !AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY)) + { + sLog.outErrorDb("BatteGroundNA: Failed to spawn some object!"); + return false; + } + + return true; +} + +/* +20:12:14 id:036668 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86 +0000: 2f 02 00 00 72 0e 00 00 00 00 00 00 09 00 11 0a | /...r........... +0010: 00 00 01 00 00 00 0f 0a 00 00 00 00 00 00 10 0a | ................ +0020: 00 00 00 00 00 00 d4 08 00 00 00 00 00 00 d8 08 | ................ +0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................ +0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................ +0050: 00 00 00 00 00 00 | ...... +*/ diff --git a/src/game/BattleGroundNA.h b/src/game/BattleGroundNA.h new file mode 100644 index 000000000..723e5b08e --- /dev/null +++ b/src/game/BattleGroundNA.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __BATTLEGROUNDNA_H +#define __BATTLEGROUNDNA_H + +class BattleGround; + +enum BattleGroundNAObjectTypes +{ + BG_NA_OBJECT_DOOR_1 = 0, + BG_NA_OBJECT_DOOR_2 = 1, + BG_NA_OBJECT_DOOR_3 = 2, + BG_NA_OBJECT_DOOR_4 = 3, + BG_NA_OBJECT_MAX = 4 +}; + +enum BattleGroundNAObjects +{ + BG_NA_OBJECT_TYPE_DOOR_1 = 183978, + BG_NA_OBJECT_TYPE_DOOR_2 = 183980, + BG_NA_OBJECT_TYPE_DOOR_3 = 183977, + BG_NA_OBJECT_TYPE_DOOR_4 = 183979 +}; + +class BattleGroundNAScore : public BattleGroundScore +{ + public: + BattleGroundNAScore() {}; + virtual ~BattleGroundNAScore() {}; + //TODO fix me +}; + +class BattleGroundNA : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundNA(); + ~BattleGroundNA(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + + void RemovePlayer(Player *plr, uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + bool SetupBattleGround(); + virtual void ResetBGSubclass(); + void HandleKillPlayer(Player* player, Player *killer); + + private: + uint32 m_TeamKills[2]; // count of kills for each team +}; +#endif diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp new file mode 100644 index 000000000..130f46a63 --- /dev/null +++ b/src/game/BattleGroundRL.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundRL.h" +#include "Creature.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "Language.h" + +BattleGroundRL::BattleGroundRL() +{ + m_BgObjects.resize(BG_RL_OBJECT_MAX); +} + +BattleGroundRL::~BattleGroundRL() +{ + +} + +void BattleGroundRL::Update(time_t diff) +{ + BattleGround::Update(diff); + + if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) + { + ModifyStartDelayTime(diff); + + if (!(m_Events & 0x01)) + { + m_Events |= 0x01; + + for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + + SetStartDelayTime(START_DELAY1); + SendMessageToAll(LANG_ARENA_ONE_MINUTE); + } + // After 30 seconds, warning is signalled + else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04)) + { + m_Events |= 0x04; + SendMessageToAll(LANG_ARENA_THIRTY_SECONDS); + } + // After 15 seconds, warning is signalled + else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08)) + { + m_Events |= 0x08; + SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS); + } + // delay expired (1 minute) + else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10)) + { + m_Events |= 0x10; + + for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++) + DoorOpen(i); + + SendMessageToAll(LANG_ARENA_BEGUN); + SetStatus(STATUS_IN_PROGRESS); + SetStartDelayTime(0); + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player *plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); + } + } + + /*if(GetStatus() == STATUS_IN_PROGRESS) + { + // update something + }*/ +} + +void BattleGroundRL::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundRLScore* sc = new BattleGroundRLScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundRL::RemovePlayer(Player *plr, uint64 guid) +{ + +} + +void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + if(!killer) + { + sLog.outError("Killer player not found"); + return; + } + + BattleGround::HandleKillPlayer(player, killer); + + uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam()); + + ++m_TeamKills[killer_team_index]; // add kills to killer's team + + if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam())) + { + // all opponents killed + EndBattleGround(killer->GetTeam()); + } +} + +void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + // this is wrong way to implement these things. On official it done by gameobject spell cast. + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + //uint32 SpellId = 0; + //uint64 buff_guid = 0; + switch(Trigger) + { + case 4696: // buff trigger? + case 4697: // buff trigger? + break; + default: + sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } + + //if(buff_guid) + // HandleTriggerBuff(buff_guid,Source); +} + +void BattleGroundRL::ResetBGSubclass() +{ + m_TeamKills[BG_TEAM_ALLIANCE] = 0; + m_TeamKills[BG_TEAM_HORDE] = 0; +} + +bool BattleGroundRL::SetupBattleGround() +{ + // gates + if( !AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f, RESPAWN_IMMEDIATELY)) + { + sLog.outErrorDb("BatteGroundRL: Failed to spawn some object!"); + return false; + } + + return true; +} + +/* +Packet S->C, id 600, SMSG_INIT_WORLD_STATES (706), len 86 +0000: 3C 02 00 00 80 0F 00 00 00 00 00 00 09 00 BA 0B | <............... +0010: 00 00 01 00 00 00 B9 0B 00 00 02 00 00 00 B8 0B | ................ +0020: 00 00 00 00 00 00 D8 08 00 00 00 00 00 00 D7 08 | ................ +0030: 00 00 00 00 00 00 D6 08 00 00 00 00 00 00 D5 08 | ................ +0040: 00 00 00 00 00 00 D3 08 00 00 00 00 00 00 D4 08 | ................ +0050: 00 00 00 00 00 00 | ...... +*/ diff --git a/src/game/BattleGroundRL.h b/src/game/BattleGroundRL.h new file mode 100644 index 000000000..0e9a38bca --- /dev/null +++ b/src/game/BattleGroundRL.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __BATTLEGROUNDRL_H +#define __BATTLEGROUNDRL_H + +class BattleGround; + +enum BattleGroundRLObjectTypes +{ + BG_RL_OBJECT_DOOR_1 = 0, + BG_RL_OBJECT_DOOR_2 = 1, + BG_RL_OBJECT_MAX = 2 +}; + +enum BattleGroundRLObjects +{ + BG_RL_OBJECT_TYPE_DOOR_1 = 185918, + BG_RL_OBJECT_TYPE_DOOR_2 = 185917 +}; + +class BattleGroundRLScore : public BattleGroundScore +{ + public: + BattleGroundRLScore() {}; + virtual ~BattleGroundRLScore() {}; + //TODO fix me +}; + +class BattleGroundRL : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundRL(); + ~BattleGroundRL(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + + void RemovePlayer(Player *plr, uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + bool SetupBattleGround(); + virtual void ResetBGSubclass(); + void HandleKillPlayer(Player* player, Player *killer); + + private: + uint32 m_TeamKills[2]; // count of kills for each team +}; +#endif diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp new file mode 100644 index 000000000..c482a959e --- /dev/null +++ b/src/game/BattleGroundWS.cpp @@ -0,0 +1,678 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Object.h" +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundWS.h" +#include "Creature.h" +#include "GameObject.h" +#include "Chat.h" +#include "MapManager.h" +#include "Language.h" + +BattleGroundWS::BattleGroundWS() +{ + m_BgObjects.resize(BG_WS_OBJECT_MAX); + m_BgCreatures.resize(BG_CREATURES_MAX_WS); +} + +BattleGroundWS::~BattleGroundWS() +{ +} + +void BattleGroundWS::Update(time_t diff) +{ + BattleGround::Update(diff); + + // after bg start we get there (once) + if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) + { + ModifyStartDelayTime(diff); + + if(!(m_Events & 0x01)) + { + m_Events |= 0x01; + + for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++) + { + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + DoorClose(i); + } + for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++) + SpawnBGObject(i, RESPAWN_ONE_DAY); + + SetStartDelayTime(START_DELAY0); + } + // After 1 minute, warning is signalled + else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04)) + { + m_Events |= 0x04; + SendMessageToAll(GetMangosString(LANG_BG_WS_ONE_MINUTE)); + } + // After 1,5 minute, warning is signalled + else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08)) + { + m_Events |= 0x08; + SendMessageToAll(GetMangosString(LANG_BG_WS_HALF_MINUTE)); + } + // After 2 minutes, gates OPEN ! x) + else if(GetStartDelayTime() < 0 && !(m_Events & 0x10)) + { + m_Events |= 0x10; + for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; i++) + DoorOpen(i); + for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; i++) + DoorOpen(i); + + SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY); + SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY); + SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY); + SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY); + + for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + + SendMessageToAll(GetMangosString(LANG_BG_WS_BEGIN)); + + PlaySoundToAll(SOUND_BG_START); + SetStatus(STATUS_IN_PROGRESS); + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player* plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_PREPARATION); + } + } + else if(GetStatus() == STATUS_IN_PROGRESS) + { + if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) + { + m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff; + + if(m_FlagsTimer[BG_TEAM_ALLIANCE] < 0) + { + m_FlagsTimer[BG_TEAM_ALLIANCE] = 0; + RespawnFlag(ALLIANCE, true); + } + } + if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND) + { + m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff; + + if(m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0) + { + m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0; + RespawnFlagAfterDrop(ALLIANCE); + } + } + if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) + { + m_FlagsTimer[BG_TEAM_HORDE] -= diff; + + if(m_FlagsTimer[BG_TEAM_HORDE] < 0) + { + m_FlagsTimer[BG_TEAM_HORDE] = 0; + RespawnFlag(HORDE, true); + } + } + if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND) + { + m_FlagsDropTimer[BG_TEAM_HORDE] -= diff; + + if(m_FlagsDropTimer[BG_TEAM_HORDE] < 0) + { + m_FlagsDropTimer[BG_TEAM_HORDE] = 0; + RespawnFlagAfterDrop(HORDE); + } + } + } +} + +void BattleGroundWS::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundWGScore* sc = new BattleGroundWGScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundWS::RespawnFlag(uint32 Team, bool captured) +{ + if(Team == ALLIANCE) + { + sLog.outDebug("Respawn Alliance flag"); + m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE; + } + else + { + sLog.outDebug("Respawn Horde flag"); + m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE; + } + + if(captured) + { + //when map_update will be allowed for battlegrounds this code will be useless + SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY); + SendMessageToAll(GetMangosString(LANG_BG_WS_F_PLACED)); + PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound... + } +} + +void BattleGroundWS::RespawnFlagAfterDrop(uint32 team) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + RespawnFlag(team,false); + if(team == ALLIANCE) + { + SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY); + SendMessageToAll(GetMangosString(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED)); + } + else + { + SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY); + SendMessageToAll(GetMangosString(LANG_BG_WS_HORDE_FLAG_RESPAWNED)); + } + + PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); + + GameObject *obj = HashMapHolder::Find(GetDroppedFlagGUID(team)); + if(obj) + obj->Delete(); + else + sLog.outError("unknown droped flag bg, guid: %u",GetDroppedFlagGUID(team)); + + SetDroppedFlagGUID(0,team); +} + +void BattleGroundWS::EventPlayerCapturedFlag(Player *Source) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + uint8 type = 0; + uint32 winner = 0; + const char *message = ""; + + //TODO FIX reputation and honor gains for low level players! + + Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); + if(Source->GetTeam() == ALLIANCE) + { + if (!this->IsHordeFlagPickedup()) + return; + SetHordeFlagPicker(0); // must be before aura remove to prevent 2 events (drop+capture) at the same time + // horde flag in base (but not respawned yet) + m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN; + // Drop Horde Flag from Player + Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG); + message = GetMangosString(LANG_BG_WS_CAPTURED_HF); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + if(GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE) + AddPoint(ALLIANCE, 1); + PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE); + RewardReputationToTeam(890, 35, ALLIANCE); // +35 reputation + RewardHonorToTeam(40, ALLIANCE); // +40 bonushonor + } + else + { + if (!this->IsAllianceFlagPickedup()) + return; + SetAllianceFlagPicker(0); // must be before aura remove to prevent 2 events (drop+capture) at the same time + // alliance flag in base (but not respawned yet) + m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN; + // Drop Alliance Flag from Player + Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG); + message = GetMangosString(LANG_BG_WS_CAPTURED_AF); + type = CHAT_MSG_BG_SYSTEM_HORDE; + if(GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE) + AddPoint(HORDE, 1); + PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE); + RewardReputationToTeam(889, 35, HORDE); // +35 reputation + RewardHonorToTeam(40, HORDE); // +40 bonushonor + } + + SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME); + SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME); + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); + + UpdateFlagState(Source->GetTeam(), 1); // flag state none + UpdateTeamScore(Source->GetTeam()); + // only flag capture should be updated + UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures... + + if(GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE) + winner = ALLIANCE; + + if(GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE) + winner = HORDE; + + if(winner) + { + UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 0); + UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 0); + UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1); + UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1); + + EndBattleGround(winner); + } + else + { + m_FlagsTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME; + } +} + +void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) +{ + // Drop allowed in any BG state + + const char *message = ""; + uint8 type = 0; + bool set = false; + + if(Source->GetTeam() == ALLIANCE) + { + if(!this->IsHordeFlagPickedup()) + return; + if(GetHordeFlagPickerGUID() == Source->GetGUID()) + { + SetHordeFlagPicker(0); + Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG); + m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND; + message = GetMangosString(LANG_BG_WS_DROPPED_HF); + type = CHAT_MSG_BG_SYSTEM_HORDE; + Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true); + set = true; + } + } + else + { + if(!this->IsAllianceFlagPickedup()) + return; + if(GetAllianceFlagPickerGUID() == Source->GetGUID()) + { + SetAllianceFlagPicker(0); + Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG); + m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND; + message = GetMangosString(LANG_BG_WS_DROPPED_AF); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true); + set = true; + } + } + + if (set) + { + Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true); + UpdateFlagState(Source->GetTeam(), 1); + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); + + if(Source->GetTeam() == ALLIANCE) + UpdateWorldState(BG_WS_FLAG_UNK_HORDE, uint32(-1)); + else + UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1)); + + m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME; + } +} + +void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + const char *message; + uint8 type = 0; + + //alliance flag picked up from base + if(Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE + && this->m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID()) + { + message = GetMangosString(LANG_BG_WS_PICKEDUP_AF); + type = CHAT_MSG_BG_SYSTEM_HORDE; + PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP); + SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY); + SetAllianceFlagPicker(Source->GetGUID()); + m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER; + //update world state to show correct flag carrier + UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER); + UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1); + Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true); + } + + //horde flag picked up from base + if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE + && this->m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID()) + { + message = GetMangosString(LANG_BG_WS_PICKEDUP_HF); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP); + SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY); + SetHordeFlagPicker(Source->GetGUID()); + m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER; + //update world state to show correct flag carrier + UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER); + UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1); + Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true); + } + + //Alliance flag on ground(not in base) (returned or picked up again from ground!) + if(this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10)) + { + if(Source->GetTeam() == ALLIANCE) + { + message = GetMangosString(LANG_BG_WS_RETURNED_AF); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN); + RespawnFlag(ALLIANCE, false); + SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY); + PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED); + UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1); + } + else + { + message = GetMangosString(LANG_BG_WS_PICKEDUP_AF); + type = CHAT_MSG_BG_SYSTEM_HORDE; + PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP); + SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY); + SetAllianceFlagPicker(Source->GetGUID()); + Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true); + m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER; + UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER); + UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1); + } + //called in HandleGameObjectUseOpcode: + //target_obj->Delete(); + } + + //Horde flag on ground(not in base) (returned or picked up again) + if(this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10)) + { + if(Source->GetTeam() == HORDE) + { + message = GetMangosString(LANG_BG_WS_RETURNED_HF); + type = CHAT_MSG_BG_SYSTEM_HORDE; + UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN); + RespawnFlag(HORDE, false); + SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY); + PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED); + UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1); + } + else + { + message = GetMangosString(LANG_BG_WS_PICKEDUP_HF); + type = CHAT_MSG_BG_SYSTEM_ALLIANCE; + PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP); + SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY); + SetHordeFlagPicker(Source->GetGUID()); + Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true); + m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER; + UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER); + UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1); + } + //called in HandleGameObjectUseOpcode: + //target_obj->Delete(); + } + + if (!type) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL); + SendPacketToAll(&data); + Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); +} + +void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid) +{ + // sometimes flag aura not removed :( + if(IsAllianceFlagPickedup() && m_FlagKeepers[BG_TEAM_ALLIANCE] == guid) + { + if(!plr) + { + sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!"); + this->SetAllianceFlagPicker(0); + this->RespawnFlag(ALLIANCE, false); + } + else + this->EventPlayerDroppedFlag(plr); + } + if(IsHordeFlagPickedup() && m_FlagKeepers[BG_TEAM_HORDE] == guid) + { + if(!plr) + { + sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!"); + this->SetHordeFlagPicker(0); + this->RespawnFlag(HORDE, false); + } + else + this->EventPlayerDroppedFlag(plr); + } +} + +void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value) +{ + if(team == ALLIANCE) + UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, value); + else + UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value); +} + +void BattleGroundWS::UpdateTeamScore(uint32 team) +{ + if(team == ALLIANCE) + UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(team)); + else + UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team)); +} + +void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger) +{ + // this is wrong way to implement these things. On official it done by gameobject spell cast. + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + //uint32 SpellId = 0; + //uint64 buff_guid = 0; + switch(Trigger) + { + case 3686: // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update(). + //buff_guid = m_BgObjects[BG_WS_OBJECT_SPEEDBUFF_1]; + break; + case 3687: // Horde elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update(). + //buff_guid = m_BgObjects[BG_WS_OBJECT_SPEEDBUFF_2]; + break; + case 3706: // Alliance elixir of regeneration spawn + //buff_guid = m_BgObjects[BG_WS_OBJECT_REGENBUFF_1]; + break; + case 3708: // Horde elixir of regeneration spawn + //buff_guid = m_BgObjects[BG_WS_OBJECT_REGENBUFF_2]; + break; + case 3707: // Alliance elixir of berserk spawn + //buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_1]; + break; + case 3709: // Horde elixir of berserk spawn + //buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_2]; + break; + case 3646: // Alliance Flag spawn + if(m_FlagState[BG_TEAM_HORDE] && !m_FlagState[BG_TEAM_ALLIANCE]) + if(GetHordeFlagPickerGUID() == Source->GetGUID()) + EventPlayerCapturedFlag(Source); + break; + case 3647: // Horde Flag spawn + if(m_FlagState[BG_TEAM_ALLIANCE] && !m_FlagState[BG_TEAM_HORDE]) + if(GetAllianceFlagPickerGUID() == Source->GetGUID()) + EventPlayerCapturedFlag(Source); + break; + case 3649: // unk1 + case 3688: // unk2 + case 4628: // unk3 + case 4629: // unk4 + break; + default: + sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); + Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + break; + } + + //if(buff_guid) + // HandleTriggerBuff(buff_guid,Source); +} + +bool BattleGroundWS::SetupBattleGround() +{ + // flags + if( !AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000) + || !AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, BG_WS_FLAG_RESPAWN_TIME/1000) + // buffs + || !AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME) + || !AddObject(BG_WS_OBJECT_SPEEDBUFF_2, BG_OBJECTID_SPEEDBUFF_ENTRY, 1005.171f, 1447.946f, 335.9032f, 1.64061f, 0, 0, 0.7313537f, 0.6819984f, BUFF_RESPAWN_TIME) + || !AddObject(BG_WS_OBJECT_REGENBUFF_1, BG_OBJECTID_REGENBUFF_ENTRY, 1317.506f, 1550.851f, 313.2344f, -0.2617996f, 0, 0, 0.1305263f, -0.9914448f, BUFF_RESPAWN_TIME) + || !AddObject(BG_WS_OBJECT_REGENBUFF_2, BG_OBJECTID_REGENBUFF_ENTRY, 1110.451f, 1353.656f, 316.5181f, -0.6806787f, 0, 0, 0.333807f, -0.9426414f, BUFF_RESPAWN_TIME) + || !AddObject(BG_WS_OBJECT_BERSERKBUFF_1, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1320.09f, 1378.79f, 314.7532f, 1.186824f, 0, 0, 0.5591929f, 0.8290376f, BUFF_RESPAWN_TIME) + || !AddObject(BG_WS_OBJECT_BERSERKBUFF_2, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1139.688f, 1560.288f, 306.8432f, -2.443461f, 0, 0, 0.9396926f, -0.3420201f, BUFF_RESPAWN_TIME) + // alliance gates + || !AddObject(BG_WS_OBJECT_DOOR_A_1, BG_OBJECT_DOOR_A_1_WS_ENTRY, 1503.335f, 1493.466f, 352.1888f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_A_2, BG_OBJECT_DOOR_A_2_WS_ENTRY, 1492.478f, 1457.912f, 342.9689f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_A_3, BG_OBJECT_DOOR_A_3_WS_ENTRY, 1468.503f, 1494.357f, 351.8618f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_A_4, BG_OBJECT_DOOR_A_4_WS_ENTRY, 1471.555f, 1458.778f, 362.6332f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_A_5, BG_OBJECT_DOOR_A_5_WS_ENTRY, 1492.347f, 1458.34f, 342.3712f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_A_6, BG_OBJECT_DOOR_A_6_WS_ENTRY, 1503.466f, 1493.367f, 351.7352f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY) + // horde gates + || !AddObject(BG_WS_OBJECT_DOOR_H_1, BG_OBJECT_DOOR_H_1_WS_ENTRY, 949.1663f, 1423.772f, 345.6241f, -0.5756807f, -0.01673368f, -0.004956111f, -0.2839723f, 0.9586737f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_H_2, BG_OBJECT_DOOR_H_2_WS_ENTRY, 953.0507f, 1459.842f, 340.6526f, -1.99662f, -0.1971825f, 0.1575096f, -0.8239487f, 0.5073641f, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_H_3, BG_OBJECT_DOOR_H_3_WS_ENTRY, 949.9523f, 1422.751f, 344.9273f, 0.0f, 0, 0, 0, 1, RESPAWN_IMMEDIATELY) + || !AddObject(BG_WS_OBJECT_DOOR_H_4, BG_OBJECT_DOOR_H_4_WS_ENTRY, 950.7952f, 1459.583f, 342.1523f, 0.05235988f, 0, 0, 0.02617695f, 0.9996573f, RESPAWN_IMMEDIATELY) + ) + { + sLog.outErrorDb("BatteGroundWS: Failed to spawn some object BattleGround not created!"); + return false; + } + + WorldSafeLocsEntry const *sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE); + if(!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE)) + { + sLog.outErrorDb("BatteGroundWS: Failed to spawn Alliance spirit guide! BattleGround not created!"); + return false; + } + + sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE); + if(!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE)) + { + sLog.outErrorDb("BatteGroundWS: Failed to spawn Horde spirit guide! BattleGround not created!"); + return false; + } + + sLog.outDebug("BatteGroundWS: BG objects and spirit guides spawned"); + + return true; +} + +void BattleGroundWS::ResetBGSubclass() +{ + m_FlagKeepers[BG_TEAM_ALLIANCE] = 0; + m_FlagKeepers[BG_TEAM_HORDE] = 0; + m_DroppedFlagGUID[BG_TEAM_ALLIANCE] = 0; + m_DroppedFlagGUID[BG_TEAM_HORDE] = 0; + m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE; + m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE; + m_TeamScores[BG_TEAM_ALLIANCE] = 0; + m_TeamScores[BG_TEAM_HORDE] = 0; + + /* Spirit nodes is static at this BG and then not required deleting at BG reset. + if(m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE]) + DelCreature(WS_SPIRIT_MAIN_ALLIANCE); + + if(m_BgCreatures[WS_SPIRIT_MAIN_HORDE]) + DelCreature(WS_SPIRIT_MAIN_HORDE); + */ +} + +void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + + EventPlayerDroppedFlag(player); + + BattleGround::HandleKillPlayer(player, killer); +} + +void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) +{ + + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found + return; + + switch(type) + { + case SCORE_FLAG_CAPTURES: // flags captured + ((BattleGroundWGScore*)itr->second)->FlagCaptures += value; + break; + case SCORE_FLAG_RETURNS: // flags returned + ((BattleGroundWGScore*)itr->second)->FlagReturns += value; + break; + default: + BattleGround::UpdatePlayerScore(Source, type, value); + break; + } +} + +void BattleGroundWS::FillInitialWorldStates(WorldPacket& data) +{ + data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE)); + data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(HORDE)); + + if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND) + data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(-1); + else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER) + data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(1); + else + data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(0); + + if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND) + data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(-1); + else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER) + data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(1); + else + data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(0); + + data << uint32(BG_WS_FLAG_CAPTURES_MAX) << uint32(BG_WS_MAX_TEAM_SCORE); + + if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER) + data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(2); + else + data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(1); + + if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER) + data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(2); + else + data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(1); + +} diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h new file mode 100644 index 000000000..cf6857085 --- /dev/null +++ b/src/game/BattleGroundWS.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUNDWS_H +#define __BATTLEGROUNDWS_H + +#include "BattleGround.h" + +#define BG_WS_MAX_TEAM_SCORE 3 +#define BG_WS_FLAG_RESPAWN_TIME 23000 +#define BG_WS_FLAG_DROP_TIME 10000 + +enum BG_WS_Sound +{ + BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE = 8173, + BG_WS_SOUND_FLAG_CAPTURED_HORDE = 8213, + BG_WS_SOUND_FLAG_PLACED = 8232, + BG_WS_SOUND_FLAG_RETURNED = 8192, + BG_WS_SOUND_HORDE_FLAG_PICKED_UP = 8212, + BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP = 8174, + BG_WS_SOUND_FLAGS_RESPAWNED = 8232 +}; + +enum BG_WS_SpellId +{ + BG_WS_SPELL_WARSONG_FLAG = 23333, + BG_WS_SPELL_WARSONG_FLAG_DROPPED = 23334, + BG_WS_SPELL_SILVERWING_FLAG = 23335, + BG_WS_SPELL_SILVERWING_FLAG_DROPPED = 23336 +}; + +enum BG_WS_WorldStates +{ + BG_WS_FLAG_UNK_ALLIANCE = 1545, + BG_WS_FLAG_UNK_HORDE = 1546, +// FLAG_UNK = 1547, + BG_WS_FLAG_CAPTURES_ALLIANCE = 1581, + BG_WS_FLAG_CAPTURES_HORDE = 1582, + BG_WS_FLAG_CAPTURES_MAX = 1601, + BG_WS_FLAG_STATE_HORDE = 2338, + BG_WS_FLAG_STATE_ALLIANCE = 2339 +}; + +enum BG_WS_ObjectTypes +{ + BG_WS_OBJECT_DOOR_A_1 = 0, + BG_WS_OBJECT_DOOR_A_2 = 1, + BG_WS_OBJECT_DOOR_A_3 = 2, + BG_WS_OBJECT_DOOR_A_4 = 3, + BG_WS_OBJECT_DOOR_A_5 = 4, + BG_WS_OBJECT_DOOR_A_6 = 5, + BG_WS_OBJECT_DOOR_H_1 = 6, + BG_WS_OBJECT_DOOR_H_2 = 7, + BG_WS_OBJECT_DOOR_H_3 = 8, + BG_WS_OBJECT_DOOR_H_4 = 9, + BG_WS_OBJECT_A_FLAG = 10, + BG_WS_OBJECT_H_FLAG = 11, + BG_WS_OBJECT_SPEEDBUFF_1 = 12, + BG_WS_OBJECT_SPEEDBUFF_2 = 13, + BG_WS_OBJECT_REGENBUFF_1 = 14, + BG_WS_OBJECT_REGENBUFF_2 = 15, + BG_WS_OBJECT_BERSERKBUFF_1 = 16, + BG_WS_OBJECT_BERSERKBUFF_2 = 17, + BG_WS_OBJECT_MAX = 18 +}; + +enum BG_WS_ObjectEntry +{ + BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918, + BG_OBJECT_DOOR_A_2_WS_ENTRY = 179919, + BG_OBJECT_DOOR_A_3_WS_ENTRY = 179920, + BG_OBJECT_DOOR_A_4_WS_ENTRY = 179921, + BG_OBJECT_DOOR_A_5_WS_ENTRY = 180322, + BG_OBJECT_DOOR_A_6_WS_ENTRY = 180322, + BG_OBJECT_DOOR_H_1_WS_ENTRY = 179916, + BG_OBJECT_DOOR_H_2_WS_ENTRY = 179917, + BG_OBJECT_DOOR_H_3_WS_ENTRY = 180322, + BG_OBJECT_DOOR_H_4_WS_ENTRY = 180322, + BG_OBJECT_A_FLAG_WS_ENTRY = 179830, + BG_OBJECT_H_FLAG_WS_ENTRY = 179831 +}; + +enum BG_WS_FlagState +{ + BG_WS_FLAG_STATE_ON_BASE = 0, + BG_WS_FLAG_STATE_WAIT_RESPAWN = 1, + BG_WS_FLAG_STATE_ON_PLAYER = 2, + BG_WS_FLAG_STATE_ON_GROUND = 3 +}; + +enum BG_WS_Graveyards +{ + WS_GRAVEYARD_MAIN_ALLIANCE = 771, + WS_GRAVEYARD_MAIN_HORDE = 772 +}; + +enum BG_WS_CreatureTypes +{ + WS_SPIRIT_MAIN_ALLIANCE = 0, + WS_SPIRIT_MAIN_HORDE = 1, + + BG_CREATURES_MAX_WS = 2 +}; + +class BattleGroundWGScore : public BattleGroundScore +{ + public: + BattleGroundWGScore() : FlagCaptures(0), FlagReturns(0) {}; + virtual ~BattleGroundWGScore() {}; + uint32 FlagCaptures; + uint32 FlagReturns; +}; + +class BattleGroundWS : public BattleGround +{ + friend class BattleGroundMgr; + + public: + /* Construction */ + BattleGroundWS(); + ~BattleGroundWS(); + void Update(time_t diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + + /* BG Flags */ + uint64 GetAllianceFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_ALLIANCE]; } + uint64 GetHordeFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_HORDE]; } + void SetAllianceFlagPicker(uint64 guid) { m_FlagKeepers[BG_TEAM_ALLIANCE] = guid; } + void SetHordeFlagPicker(uint64 guid) { m_FlagKeepers[BG_TEAM_HORDE] = guid; } + bool IsAllianceFlagPickedup() const { return m_FlagKeepers[BG_TEAM_ALLIANCE] != 0; } + bool IsHordeFlagPickedup() const { return m_FlagKeepers[BG_TEAM_HORDE] != 0; } + void RespawnFlag(uint32 Team, bool captured); + void RespawnFlagAfterDrop(uint32 Team); + uint8 GetFlagState(uint32 team) { return m_FlagState[GetTeamIndexByTeamId(team)]; } + + /* Battleground Events */ + virtual void EventPlayerDroppedFlag(Player *Source); + virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj); + virtual void EventPlayerCapturedFlag(Player *Source); + + void RemovePlayer(Player *plr, uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + void HandleKillPlayer(Player *player, Player *killer); + bool SetupBattleGround(); + virtual void ResetBGSubclass(); + + void UpdateFlagState(uint32 team, uint32 value); + void UpdateTeamScore(uint32 team); + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + void SetDroppedFlagGUID(uint64 guid, uint32 TeamID) { m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)] = guid;} + uint64 GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)];} + virtual void FillInitialWorldStates(WorldPacket& data); + + /* Scorekeeping */ + uint32 GetTeamScore(uint32 TeamID) const { return m_TeamScores[GetTeamIndexByTeamId(TeamID)]; } + void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; } + void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; } + void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; } + + private: + uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde + uint64 m_DroppedFlagGUID[2]; + uint8 m_FlagState[2]; // for checking flag state + uint32 m_TeamScores[2]; + int32 m_FlagsTimer[2]; + int32 m_FlagsDropTimer[2]; +}; +#endif diff --git a/src/game/Cell.h b/src/game/Cell.h new file mode 100644 index 000000000..5fc4177d3 --- /dev/null +++ b/src/game/Cell.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CELL_H +#define MANGOS_CELL_H + +#include "GameSystem/TypeContainer.h" +#include "GameSystem/TypeContainerVisitor.h" +#include "GridDefines.h" +#include + +class Map; + +enum District +{ + UPPER_DISTRICT = 1, + LOWER_DISTRICT = 1 << 1, + LEFT_DISTRICT = 1 << 2, + RIGHT_DISTRICT = 1 << 3, + CENTER_DISTRICT = 1 << 4, + UPPER_LEFT_DISTRICT = (UPPER_DISTRICT | LEFT_DISTRICT), + UPPER_RIGHT_DISTRICT = (UPPER_DISTRICT | RIGHT_DISTRICT), + LOWER_LEFT_DISTRICT = (LOWER_DISTRICT | LEFT_DISTRICT), + LOWER_RIGHT_DISTRICT = (LOWER_DISTRICT | RIGHT_DISTRICT), + ALL_DISTRICT = (UPPER_DISTRICT | LOWER_DISTRICT | LEFT_DISTRICT | RIGHT_DISTRICT | CENTER_DISTRICT) +}; + +template struct CellLock; + +struct MANGOS_DLL_DECL Cell +{ + Cell() { data.All = 0; } + Cell(const Cell &cell) { data.All = cell.data.All; } + explicit Cell(CellPair const& p); + + void operator|=(Cell &cell) + { + data.Part.reserved = 0; + cell.data.Part.reserved = 0; + uint32 x, y, old_x, old_y; + Compute(x, y); + cell.Compute(old_x, old_y); + + if( std::abs(int(x-old_x)) > 1 || std::abs(int(y-old_y)) > 1) + { + data.Part.reserved = ALL_DISTRICT; + cell.data.Part.reserved = ALL_DISTRICT; + return; + } + + if( x < old_x ) + { + data.Part.reserved |= LEFT_DISTRICT; + cell.data.Part.reserved |= RIGHT_DISTRICT; + } + else if( old_x < x ) + { + data.Part.reserved |= RIGHT_DISTRICT; + cell.data.Part.reserved |= LEFT_DISTRICT; + } + if( y < old_y ) + { + data.Part.reserved |= UPPER_DISTRICT; + cell.data.Part.reserved |= LOWER_DISTRICT; + } + else if( old_y < y ) + { + data.Part.reserved |= LOWER_DISTRICT; + cell.data.Part.reserved |= UPPER_DISTRICT; + } + } + + void Compute(uint32 &x, uint32 &y) const + { + x = data.Part.grid_x*MAX_NUMBER_OF_CELLS + data.Part.cell_x; + y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y; + } + + inline bool DiffCell(const Cell &cell) const + { + return( data.Part.cell_x != cell.data.Part.cell_x || + data.Part.cell_y != cell.data.Part.cell_y ); + } + + inline bool DiffGrid(const Cell &cell) const + { + return( data.Part.grid_x != cell.data.Part.grid_x || + data.Part.grid_y != cell.data.Part.grid_y ); + } + + uint32 CellX() const { return data.Part.cell_x; } + uint32 CellY() const { return data.Part.cell_y; } + uint32 GridX() const { return data.Part.grid_x; } + uint32 GridY() const { return data.Part.grid_y; } + bool NoCreate() const { return data.Part.nocreate; } + void SetNoCreate() { data.Part.nocreate = 1; } + + CellPair cellPair() const + { + return CellPair( + data.Part.grid_x*MAX_NUMBER_OF_CELLS+data.Part.cell_x, + data.Part.grid_y*MAX_NUMBER_OF_CELLS+data.Part.cell_y); + } + + Cell& operator=(const Cell &cell) + { + this->data.All = cell.data.All; + return *this; + } + + bool operator==(const Cell &cell) const { return (data.All == cell.data.All); } + bool operator!=(const Cell &cell) const { return !operator==(cell); } + union + { + struct + { + unsigned grid_x : 6; + unsigned grid_y : 6; + unsigned cell_x : 4; + unsigned cell_y : 4; + unsigned nocreate : 1; + unsigned reserved : 11; + } Part; + uint32 All; + } data; + + template void Visit(const CellLock &, TypeContainerVisitor &visitor, Map &) const; +}; + +template +struct MANGOS_DLL_DECL CellLock +{ + const Cell& i_cell; + const CellPair &i_cellPair; + CellLock(const Cell &c, const CellPair &p) : i_cell(c), i_cellPair(p) {} + CellLock(const CellLock &cell) : i_cell(cell.i_cell), i_cellPair(cell.i_cellPair) {} + const Cell* operator->(void) const { return &i_cell; } + const Cell* operator->(void) { return &i_cell; } + operator const Cell &(void) const { return i_cell; } + CellLock& operator=(const CellLock &cell) + { + this->~CellLock(); + new (this) CellLock(cell); + return *this; + } +}; +#endif diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h new file mode 100644 index 000000000..b673bad76 --- /dev/null +++ b/src/game/CellImpl.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CELLIMPL_H +#define MANGOS_CELLIMPL_H + +#include "Cell.h" +#include "Map.h" +#include + +inline Cell::Cell(CellPair const& p) +{ + data.Part.grid_x = p.x_coord / MAX_NUMBER_OF_CELLS; + data.Part.grid_y = p.y_coord / MAX_NUMBER_OF_CELLS; + data.Part.cell_x = p.x_coord % MAX_NUMBER_OF_CELLS; + data.Part.cell_y = p.y_coord % MAX_NUMBER_OF_CELLS; + data.Part.nocreate = 0; + data.Part.reserved = 0; +} + +template +inline void +Cell::Visit(const CellLock &l, TypeContainerVisitor &visitor, Map &m) const +{ + const CellPair &standing_cell = l.i_cellPair; + if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) + return; + + uint16 district = (District)this->data.Part.reserved; + if(district == CENTER_DISTRICT) + { + m.Visit(l, visitor); + return; + } + + // set up the cell range based on the district + // the overloaded operators handle range checking + CellPair begin_cell = standing_cell; + CellPair end_cell = standing_cell; + + switch( district ) + { + case ALL_DISTRICT: + { + begin_cell << 1; begin_cell -= 1; // upper left + end_cell >> 1; end_cell += 1; // lower right + break; + } + case UPPER_LEFT_DISTRICT: + { + begin_cell << 1; begin_cell -= 1; // upper left + break; + } + case UPPER_RIGHT_DISTRICT: + { + begin_cell -= 1; // up + end_cell >> 1; // right + break; + } + case LOWER_LEFT_DISTRICT: + { + begin_cell << 1; // left + end_cell += 1; // down + break; + } + case LOWER_RIGHT_DISTRICT: + { + end_cell >> 1; end_cell += 1; // lower right + break; + } + case LEFT_DISTRICT: + { + begin_cell -= 1; // up + end_cell >> 1; end_cell += 1; // lower right + break; + } + case RIGHT_DISTRICT: + { + begin_cell << 1; begin_cell -= 1; // upper left + end_cell += 1; // down + break; + } + case UPPER_DISTRICT: + { + begin_cell << 1; begin_cell -= 1; // upper left + end_cell >> 1; // right + break; + } + case LOWER_DISTRICT: + { + begin_cell << 1; // left + end_cell >> 1; end_cell += 1; // lower right + break; + } + default: + { + assert( false ); + break; + } + } + + // loop the cell range + for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++) + { + for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++) + { + CellPair cell_pair(x,y); + Cell r_zone(cell_pair); + r_zone.data.Part.nocreate = l->data.Part.nocreate; + CellLock lock(r_zone, cell_pair); + m.Visit(lock, visitor); + } + } +} +#endif diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp new file mode 100644 index 000000000..ca7c8ff3e --- /dev/null +++ b/src/game/Channel.cpp @@ -0,0 +1,994 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Channel.h" +#include "ObjectMgr.h" +#include "World.h" +#include "SocialMgr.h" + +Channel::Channel(std::string name, uint32 channel_id) +: m_name(name), m_announce(true), m_moderate(false), m_channelId(channel_id), m_ownerGUID(0), m_password(""), m_flags(0) +{ + // set special flags if built-in channel + ChatChannelsEntry const* ch = GetChannelEntryFor(channel_id); + if(ch) // it's built-in channel + { + channel_id = ch->ChannelID; // built-in channel + m_announce = false; // no join/leave announces + + m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels + + if(ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel + m_flags |= CHANNEL_FLAG_TRADE; + + if(ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels + m_flags |= CHANNEL_FLAG_CITY; + + if(ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel + m_flags |= CHANNEL_FLAG_LFG; + else // for all other channels + m_flags |= CHANNEL_FLAG_NOT_LFG; + } + else // it's custom channel + { + m_flags |= CHANNEL_FLAG_CUSTOM; + } +} + +void Channel::Join(uint64 p, const char *pass) +{ + WorldPacket data; + if(IsOn(p)) + { + if(!IsConstant()) // non send error message for built-in channels + { + MakePlayerAlreadyMember(&data, p); + SendToOne(&data, p); + } + return; + } + + if(IsBanned(p)) + { + MakeBanned(&data); + SendToOne(&data, p); + return; + } + + if(m_password.length() > 0 && strcmp(pass, m_password.c_str())) + { + MakeWrongPassword(&data); + SendToOne(&data, p); + return; + } + + Player *plr = objmgr.GetPlayer(p); + + if(plr) + { + if(HasFlag(CHANNEL_FLAG_LFG) && + sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER && + (plr->GetGroup() || plr->m_lookingForGroup.Empty()) ) + { + MakeNotInLfg(&data); + SendToOne(&data, p); + return; + } + + if(plr->GetGuildId() && (GetFlags() == 0x38)) + return; + + plr->JoinedChannel(this); + } + + if(m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) )) + { + MakeJoined(&data, p); + SendToAll(&data); + } + + data.clear(); + + PlayerInfo pinfo; + pinfo.player = p; + pinfo.flags = 0; + players[p] = pinfo; + + MakeYouJoined(&data); + SendToOne(&data, p); + + JoinNotify(p); + + // if no owner first logged will become + if(!IsConstant() && !m_ownerGUID) + { + SetOwner(p, (players.size() > 1 ? true : false)); + players[p].SetModerator(true); + } +} + +void Channel::Leave(uint64 p, bool send) +{ + if(!IsOn(p)) + { + if(send) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + } + else + { + Player *plr = objmgr.GetPlayer(p); + + if(send) + { + WorldPacket data; + MakeYouLeft(&data); + SendToOne(&data, p); + if(plr) + plr->LeftChannel(this); + data.clear(); + } + + bool changeowner = players[p].IsOwner(); + + players.erase(p); + if(m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) )) + { + WorldPacket data; + MakeLeft(&data, p); + SendToAll(&data); + } + + LeaveNotify(p); + + if(changeowner) + { + uint64 newowner = !players.empty() ? players.begin()->second.player : 0; + SetOwner(newowner); + } + } +} + +void Channel::KickOrBan(uint64 good, const char *badname, bool ban) +{ + uint32 sec = 0; + Player *gplr = objmgr.GetPlayer(good); + if(gplr) + sec = gplr->GetSession()->GetSecurity(); + + if(!IsOn(good)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, good); + } + else if(!players[good].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, good); + } + else + { + Player *bad = objmgr.GetPlayer(badname); + if(bad == NULL || !IsOn(bad->GetGUID())) + { + WorldPacket data; + MakePlayerNotFound(&data, badname); + SendToOne(&data, good); + } + else if(sec < SEC_GAMEMASTER && bad->GetGUID() == m_ownerGUID && good != m_ownerGUID) + { + WorldPacket data; + MakeNotOwner(&data); + SendToOne(&data, good); + } + else + { + bool changeowner = (m_ownerGUID == bad->GetGUID()); + + WorldPacket data; + + if(ban && !IsBanned(bad->GetGUID())) + { + banned.push_back(bad->GetGUID()); + MakePlayerBanned(&data, bad->GetGUID(), good); + } + else + MakePlayerKicked(&data, bad->GetGUID(), good); + + SendToAll(&data); + players.erase(bad->GetGUID()); + bad->LeftChannel(this); + + if(changeowner) + { + uint64 newowner = !players.empty() ? good : false; + SetOwner(newowner); + } + } + } +} + +void Channel::UnBan(uint64 good, const char *badname) +{ + uint32 sec = 0; + Player *gplr = objmgr.GetPlayer(good); + if(gplr) + sec = gplr->GetSession()->GetSecurity(); + + if(!IsOn(good)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, good); + } + else if(!players[good].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, good); + } + else + { + Player *bad = objmgr.GetPlayer(badname); + if(bad == NULL || !IsBanned(bad->GetGUID())) + { + WorldPacket data; + MakePlayerNotFound(&data, badname); + SendToOne(&data, good); + } + else + { + banned.remove(bad->GetGUID()); + + WorldPacket data; + MakePlayerUnbanned(&data, bad->GetGUID(), good); + SendToAll(&data); + } + } +} + +void Channel::Password(uint64 p, const char *pass) +{ + uint32 sec = 0; + Player *plr = objmgr.GetPlayer(p); + if(plr) + sec = plr->GetSession()->GetSecurity(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else if(!players[p].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, p); + } + else + { + m_password = pass; + + WorldPacket data; + MakePasswordChanged(&data, p); + SendToAll(&data); + } +} + +void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set) +{ + uint32 sec = 0; + Player *plr = objmgr.GetPlayer(p); + if(plr) + sec = plr->GetSession()->GetSecurity(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else if(!players[p].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, p); + } + else + { + Player *newp = objmgr.GetPlayer(p2n); + if(!newp) + { + WorldPacket data; + MakePlayerNotFound(&data, p2n); + SendToOne(&data, p); + return; + } + + PlayerInfo inf = players[newp->GetGUID()]; + if(p == m_ownerGUID && newp->GetGUID() == m_ownerGUID && mod) + return; + + if(!IsOn(newp->GetGUID())) + { + WorldPacket data; + MakePlayerNotFound(&data, p2n); + SendToOne(&data, p); + return; + } + + // allow make moderator from another team only if both is GMs + // at this moment this only way to show channel post for GM from another team + if( (plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || newp->GetSession()->GetSecurity() < SEC_GAMEMASTER) && + plr->GetTeam() != newp->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) ) + { + WorldPacket data; + MakePlayerNotFound(&data, p2n); + SendToOne(&data, p); + return; + } + + if(m_ownerGUID == newp->GetGUID() && m_ownerGUID != p) + { + WorldPacket data; + MakeNotOwner(&data); + SendToOne(&data, p); + return; + } + + if(mod) + SetModerator(newp->GetGUID(), set); + else + SetMute(newp->GetGUID(), set); + } +} + +void Channel::SetOwner(uint64 p, const char *newname) +{ + uint32 sec = 0; + Player *plr = objmgr.GetPlayer(p); + if(plr) + sec = plr->GetSession()->GetSecurity(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + return; + } + + if(sec < SEC_GAMEMASTER && p != m_ownerGUID) + { + WorldPacket data; + MakeNotOwner(&data); + SendToOne(&data, p); + return; + } + + Player *newp = objmgr.GetPlayer(newname); + if(newp == NULL || !IsOn(newp->GetGUID())) + { + WorldPacket data; + MakePlayerNotFound(&data, newname); + SendToOne(&data, p); + return; + } + + if(newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) + { + WorldPacket data; + MakePlayerNotFound(&data, newname); + SendToOne(&data, p); + return; + } + + players[newp->GetGUID()].SetModerator(true); + SetOwner(newp->GetGUID()); +} + +void Channel::SendWhoOwner(uint64 p) +{ + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else + { + WorldPacket data; + MakeChannelOwner(&data); + SendToOne(&data, p); + } +} + +void Channel::List(Player* player) +{ + uint64 p = player->GetGUID(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else + { + WorldPacket data(SMSG_CHANNEL_LIST, 1+(GetName().size()+1)+1+4+players.size()*(8+1)); + data << uint8(1); // channel type? + data << GetName(); // channel name + data << uint8(GetFlags()); // channel flags? + + size_t pos = data.wpos(); + data << uint32(0); // size of list, placeholder + + bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || player->GetSession()->GetSecurity() > SEC_PLAYER; + + uint32 count = 0; + for(PlayerList::iterator i = players.begin(); i != players.end(); ++i) + { + Player *plr = objmgr.GetPlayer(i->first); + + // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters + // MODERATOR, GAME MASTER, ADMINISTRATOR can see all + if( plr && ( plr->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && plr->IsVisibleGloballyFor(player) ) ) + { + data << uint64(i->first); + data << uint8(i->second.flags); // flags seems to be changed... + ++count; + } + } + + data.put(pos,count); + + SendToOne(&data, p); + } +} + +void Channel::Announce(uint64 p) +{ + uint32 sec = 0; + Player *plr = objmgr.GetPlayer(p); + if(plr) + sec = plr->GetSession()->GetSecurity(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else if(!players[p].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, p); + } + else + { + m_announce = !m_announce; + + WorldPacket data; + if(m_announce) + MakeAnnouncementsOn(&data, p); + else + MakeAnnouncementsOff(&data, p); + SendToAll(&data); + } +} + +void Channel::Moderate(uint64 p) +{ + uint32 sec = 0; + Player *plr = objmgr.GetPlayer(p); + if(plr) + sec = plr->GetSession()->GetSecurity(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else if(!players[p].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, p); + } + else + { + m_moderate = !m_moderate; + + WorldPacket data; + if(m_moderate) + MakeModerationOn(&data, p); + else + MakeModerationOff(&data, p); + SendToAll(&data); + } +} + +void Channel::Say(uint64 p, const char *what, uint32 lang) +{ + if(!what) + return; + if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) + lang = LANG_UNIVERSAL; + + uint32 sec = 0; + Player *plr = objmgr.GetPlayer(p); + if(plr) + sec = plr->GetSession()->GetSecurity(); + + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + } + else if(players[p].IsMuted()) + { + WorldPacket data; + MakeMuted(&data); + SendToOne(&data, p); + } + else if(m_moderate && !players[p].IsModerator() && sec < SEC_GAMEMASTER) + { + WorldPacket data; + MakeNotModerator(&data); + SendToOne(&data, p); + } + else + { + uint32 messageLength = strlen(what) + 1; + + WorldPacket data(SMSG_MESSAGECHAT, 1+4+8+4+m_name.size()+1+8+4+messageLength+1); + data << (uint8)CHAT_MSG_CHANNEL; + data << (uint32)lang; + data << p; // 2.1.0 + data << uint32(0); // 2.1.0 + data << m_name; + data << p; + data << messageLength; + data << what; + data << uint8(plr ? plr->chatTag() : 0); + + SendToAll(&data, !players[p].IsModerator() ? p : false); + } +} + +void Channel::Invite(uint64 p, const char *newname) +{ + if(!IsOn(p)) + { + WorldPacket data; + MakeNotMember(&data); + SendToOne(&data, p); + return; + } + + Player *newp = objmgr.GetPlayer(newname); + if(!newp) + { + WorldPacket data; + MakePlayerNotFound(&data, newname); + SendToOne(&data, p); + return; + } + + Player *plr = objmgr.GetPlayer(p); + if (!plr) + return; + + if (newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) + { + WorldPacket data; + MakeInviteWrongFaction(&data); + SendToOne(&data, p); + return; + } + + if(IsOn(newp->GetGUID())) + { + WorldPacket data; + MakePlayerAlreadyMember(&data, newp->GetGUID()); + SendToOne(&data, p); + return; + } + + WorldPacket data; + if(!newp->GetSocial()->HasIgnore(GUID_LOPART(p))) + { + MakeInvite(&data, p); + SendToOne(&data, newp->GetGUID()); + data.clear(); + } + MakePlayerInvited(&data, newp->GetGUID()); + SendToOne(&data, p); +} + +void Channel::SetOwner(uint64 guid, bool exclaim) +{ + if(m_ownerGUID) + { + // [] will re-add player after it possible removed + PlayerList::iterator p_itr = players.find(m_ownerGUID); + if(p_itr != players.end()) + p_itr->second.SetOwner(false); + } + + m_ownerGUID = guid; + if(m_ownerGUID) + { + uint8 oldFlag = GetPlayerFlags(m_ownerGUID); + players[m_ownerGUID].SetOwner(true); + + WorldPacket data; + MakeModeChange(&data, m_ownerGUID, oldFlag); + SendToAll(&data); + + if(exclaim) + { + MakeOwnerChanged(&data, m_ownerGUID); + SendToAll(&data); + } + } +} + +void Channel::SendToAll(WorldPacket *data, uint64 p) +{ + for(PlayerList::iterator i = players.begin(); i != players.end(); ++i) + { + Player *plr = objmgr.GetPlayer(i->first); + if(plr) + { + if(!p || !plr->GetSocial()->HasIgnore(GUID_LOPART(p))) + plr->GetSession()->SendPacket(data); + } + } +} + +void Channel::SendToAllButOne(WorldPacket *data, uint64 who) +{ + for(PlayerList::iterator i = players.begin(); i != players.end(); ++i) + { + if(i->first != who) + { + Player *plr = objmgr.GetPlayer(i->first); + if(plr) + plr->GetSession()->SendPacket(data); + } + } +} + +void Channel::SendToOne(WorldPacket *data, uint64 who) +{ + Player *plr = objmgr.GetPlayer(who); + if(plr) + plr->GetSession()->SendPacket(data); +} + +void Channel::Voice(uint64 guid1, uint64 guid2) +{ + +} + +void Channel::DeVoice(uint64 guid1, uint64 guid2) +{ + +} + +// done +void Channel::MakeNotifyPacket(WorldPacket *data, uint8 notify_type) +{ + data->Initialize(SMSG_CHANNEL_NOTIFY, 1+m_name.size()+1); + *data << uint8(notify_type); + *data << m_name; +} + +// done 0x00 +void Channel::MakeJoined(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_JOINED_NOTICE); + *data << uint64(guid); +} + +// done 0x01 +void Channel::MakeLeft(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_LEFT_NOTICE); + *data << uint64(guid); +} + +// done 0x02 +void Channel::MakeYouJoined(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_YOU_JOINED_NOTICE); + *data << uint8(GetFlags()); + *data << uint32(GetChannelId()); + *data << uint32(0); +} + +// done 0x03 +void Channel::MakeYouLeft(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE); + *data << uint32(GetChannelId()); + *data << uint8(0); // can be 0x00 and 0x01 +} + +// done 0x04 +void Channel::MakeWrongPassword(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE); +} + +// done 0x05 +void Channel::MakeNotMember(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE); +} + +// done 0x06 +void Channel::MakeNotModerator(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE); +} + +// done 0x07 +void Channel::MakePasswordChanged(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE); + *data << uint64(guid); +} + +// done 0x08 +void Channel::MakeOwnerChanged(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE); + *data << uint64(guid); +} + +// done 0x09 +void Channel::MakePlayerNotFound(WorldPacket *data, std::string name) +{ + MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE); + *data << name; +} + +// done 0x0A +void Channel::MakeNotOwner(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE); +} + +// done 0x0B +void Channel::MakeChannelOwner(WorldPacket *data) +{ + std::string name = ""; + + if(!objmgr.GetPlayerNameByGUID(m_ownerGUID, name) || name.empty()) + name = "PLAYER_NOT_FOUND"; + + MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE); + *data << ((IsConstant() || !m_ownerGUID) ? "Nobody" : name); +} + +// done 0x0C +void Channel::MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags) +{ + MakeNotifyPacket(data, CHAT_MODE_CHANGE_NOTICE); + *data << uint64(guid); + *data << uint8(oldflags); + *data << uint8(GetPlayerFlags(guid)); +} + +// done 0x0D +void Channel::MakeAnnouncementsOn(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE); + *data << uint64(guid); +} + +// done 0x0E +void Channel::MakeAnnouncementsOff(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE); + *data << uint64(guid); +} + +// done 0x0F +void Channel::MakeModerationOn(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_MODERATION_ON_NOTICE); + *data << uint64(guid); +} + +// done 0x10 +void Channel::MakeModerationOff(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_MODERATION_OFF_NOTICE); + *data << uint64(guid); +} + +// done 0x11 +void Channel::MakeMuted(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_MUTED_NOTICE); +} + +// done 0x12 +void Channel::MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good) +{ + MakeNotifyPacket(data, CHAT_PLAYER_KICKED_NOTICE); + *data << uint64(bad); + *data << uint64(good); +} + +// done 0x13 +void Channel::MakeBanned(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_BANNED_NOTICE); +} + +// done 0x14 +void Channel::MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good) +{ + MakeNotifyPacket(data, CHAT_PLAYER_BANNED_NOTICE); + *data << uint64(bad); + *data << uint64(good); +} + +// done 0x15 +void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good) +{ + MakeNotifyPacket(data, CHAT_PLAYER_UNBANNED_NOTICE); + *data << uint64(bad); + *data << uint64(good); +} + +// done 0x16 +void Channel::MakePlayerNotBanned(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE); + *data << uint64(guid); +} + +// done 0x17 +void Channel::MakePlayerAlreadyMember(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE); + *data << uint64(guid); +} + +// done 0x18 +void Channel::MakeInvite(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_INVITE_NOTICE); + *data << uint64(guid); +} + +// done 0x19 +void Channel::MakeInviteWrongFaction(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE); +} + +// done 0x1A +void Channel::MakeWrongFaction(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE); +} + +// done 0x1B +void Channel::MakeInvalidName(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE); +} + +// done 0x1C +void Channel::MakeNotModerated(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE); +} + +// done 0x1D +void Channel::MakePlayerInvited(WorldPacket *data, uint64 guid) +{ + std::string name; + + if(!objmgr.GetPlayerNameByGUID(guid, name) || name.empty()) + return; // player name not found + + MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE); + *data << name; +} + +// done 0x1E +void Channel::MakePlayerInviteBanned(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE); + *data << uint64(guid); +} + +// done 0x1F +void Channel::MakeThrottled(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE); +} + +// done 0x20 +void Channel::MakeNotInArea(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE); +} + +// done 0x21 +void Channel::MakeNotInLfg(WorldPacket *data) +{ + MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE); +} + +// done 0x22 +void Channel::MakeVoiceOn(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE); + *data << uint64(guid); +} + +// done 0x23 +void Channel::MakeVoiceOff(WorldPacket *data, uint64 guid) +{ + MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE); + *data << uint64(guid); +} + +void Channel::JoinNotify(uint64 guid) +{ + WorldPacket data; + + if(IsConstant()) + data.Initialize(SMSG_USERLIST_ADD, 8+1+1+4+GetName().size()+1); + else + data.Initialize(SMSG_USERLIST_UPDATE, 8+1+1+4+GetName().size()+1); + + data << uint64(guid); + data << uint8(GetPlayerFlags(guid)); + data << uint8(GetFlags()); + data << uint32(GetNumPlayers()); + data << GetName(); + SendToAll(&data); +} + +void Channel::LeaveNotify(uint64 guid) +{ + WorldPacket data(SMSG_USERLIST_REMOVE, 8+1+4+GetName().size()+1); + data << uint64(guid); + data << uint8(GetFlags()); + data << uint32(GetNumPlayers()); + data << GetName(); + SendToAll(&data); +} diff --git a/src/game/Channel.h b/src/game/Channel.h new file mode 100644 index 000000000..31e196948 --- /dev/null +++ b/src/game/Channel.h @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _CHANNEL_H +#define _CHANNEL_H + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Player.h" + +#include +#include +#include + +class Channel +{ + enum ChatNotify + { + CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel."; + CHAT_LEFT_NOTICE = 0x01, //+ "%s left channel."; + //CHAT_SUSPENDED_NOTICE = 0x01, // "%s left channel."; + CHAT_YOU_JOINED_NOTICE = 0x02, //+ "Joined Channel: [%s]"; -- You joined + //CHAT_YOU_CHANGED_NOTICE = 0x02, // "Changed Channel: [%s]"; + CHAT_YOU_LEFT_NOTICE = 0x03, //+ "Left Channel: [%s]"; -- You left + CHAT_WRONG_PASSWORD_NOTICE = 0x04, //+ "Wrong password for %s."; + CHAT_NOT_MEMBER_NOTICE = 0x05, //+ "Not on channel %s."; + CHAT_NOT_MODERATOR_NOTICE = 0x06, //+ "Not a moderator of %s."; + CHAT_PASSWORD_CHANGED_NOTICE = 0x07, //+ "[%s] Password changed by %s."; + CHAT_OWNER_CHANGED_NOTICE = 0x08, //+ "[%s] Owner changed to %s."; + CHAT_PLAYER_NOT_FOUND_NOTICE = 0x09, //+ "[%s] Player %s was not found."; + CHAT_NOT_OWNER_NOTICE = 0x0A, //+ "[%s] You are not the channel owner."; + CHAT_CHANNEL_OWNER_NOTICE = 0x0B, //+ "[%s] Channel owner is %s."; + CHAT_MODE_CHANGE_NOTICE = 0x0C, //? + CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s."; + CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s."; + CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s."; + CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s."; + CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak."; + CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s."; + CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are banned from that channel."; + CHAT_PLAYER_BANNED_NOTICE = 0x14, //? "[%s] Player %s banned by %s."; + CHAT_PLAYER_UNBANNED_NOTICE = 0x15, //? "[%s] Player %s unbanned by %s."; + CHAT_PLAYER_NOT_BANNED_NOTICE = 0x16, //+ "[%s] Player %s is not banned."; + CHAT_PLAYER_ALREADY_MEMBER_NOTICE = 0x17, //+ "[%s] Player %s is already on the channel."; + CHAT_INVITE_NOTICE = 0x18, //+ "%2$s has invited you to join the channel '%1$s'."; + CHAT_INVITE_WRONG_FACTION_NOTICE = 0x19, //+ "Target is in the wrong alliance for %s."; + CHAT_WRONG_FACTION_NOTICE = 0x1A, //+ "Wrong alliance for %s."; + CHAT_INVALID_NAME_NOTICE = 0x1B, //+ "Invalid channel name"; + CHAT_NOT_MODERATED_NOTICE = 0x1C, //+ "%s is not moderated"; + CHAT_PLAYER_INVITED_NOTICE = 0x1D, //+ "[%s] You invited %s to join the channel"; + CHAT_PLAYER_INVITE_BANNED_NOTICE = 0x1E, //+ "[%s] %s has been banned."; + CHAT_THROTTLED_NOTICE = 0x1F, //+ "[%s] The number of messages that can be sent to this channel is limited, please wait to send another message."; + CHAT_NOT_IN_AREA_NOTICE = 0x20, //+ "[%s] You are not in the correct area for this channel."; -- The user is trying to send a chat to a zone specific channel, and they're not physically in that zone. + CHAT_NOT_IN_LFG_NOTICE = 0x21, //+ "[%s] You must be queued in looking for group before joining this channel."; -- The user must be in the looking for group system to join LFG chat channels. + CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s."; + CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s."; + }; + + enum ChannelFlags + { + CHANNEL_FLAG_NONE = 0x00, + CHANNEL_FLAG_CUSTOM = 0x01, + // 0x02 + CHANNEL_FLAG_TRADE = 0x04, + CHANNEL_FLAG_NOT_LFG = 0x08, + CHANNEL_FLAG_GENERAL = 0x10, + CHANNEL_FLAG_CITY = 0x20, + CHANNEL_FLAG_LFG = 0x40, + CHANNEL_FLAG_VOICE = 0x80 + // General 0x18 = 0x10 | 0x08 + // Trade 0x3C = 0x20 | 0x10 | 0x08 | 0x04 + // LocalDefence 0x18 = 0x10 | 0x08 + // GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08 + // LookingForGroup 0x50 = 0x40 | 0x10 + }; + + enum ChannelDBCFlags + { + CHANNEL_DBC_FLAG_NONE = 0x00000, + CHANNEL_DBC_FLAG_INITIAL = 0x00001, // General, Trade, LocalDefense, LFG + CHANNEL_DBC_FLAG_ZONE_DEP = 0x00002, // General, Trade, LocalDefense, GuildRecruitment + CHANNEL_DBC_FLAG_GLOBAL = 0x00004, // WorldDefense + CHANNEL_DBC_FLAG_TRADE = 0x00008, // Trade + CHANNEL_DBC_FLAG_CITY_ONLY = 0x00010, // Trade, GuildRecruitment + CHANNEL_DBC_FLAG_CITY_ONLY2 = 0x00020, // Trade, GuildRecruitment + CHANNEL_DBC_FLAG_DEFENSE = 0x10000, // LocalDefense, WorldDefense + CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment + CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup + }; + + enum ChannelMemberFlags + { + MEMBER_FLAG_NONE = 0x00, + MEMBER_FLAG_OWNER = 0x01, + MEMBER_FLAG_MODERATOR = 0x02, + MEMBER_FLAG_VOICED = 0x04, + MEMBER_FLAG_MUTED = 0x08, + MEMBER_FLAG_CUSTOM = 0x10, + MEMBER_FLAG_MIC_MUTED = 0x20, + // 0x40 + // 0x80 + }; + + struct PlayerInfo + { + uint64 player; + uint8 flags; + + bool HasFlag(uint8 flag) { return flags & flag; } + void SetFlag(uint8 flag) { if(!HasFlag(flag)) flags |= flag; } + bool IsOwner() { return flags & MEMBER_FLAG_OWNER; } + void SetOwner(bool state) + { + if(state) flags |= MEMBER_FLAG_OWNER; + else flags &= ~MEMBER_FLAG_OWNER; + } + bool IsModerator() { return flags & MEMBER_FLAG_MODERATOR; } + void SetModerator(bool state) + { + if(state) flags |= MEMBER_FLAG_MODERATOR; + else flags &= ~MEMBER_FLAG_MODERATOR; + } + bool IsMuted() { return flags & MEMBER_FLAG_MUTED; } + void SetMuted(bool state) + { + if(state) flags |= MEMBER_FLAG_MUTED; + else flags &= ~MEMBER_FLAG_MUTED; + } + }; + + typedef std::map PlayerList; + PlayerList players; + typedef std::list BannedList; + BannedList banned; + bool m_announce; + bool m_moderate; + std::string m_name; + std::string m_password; + uint8 m_flags; + uint32 m_channelId; + uint64 m_ownerGUID; + + private: + // initial packet data (notify type and channel name) + void MakeNotifyPacket(WorldPacket *data, uint8 notify_type); + // type specific packet data + void MakeJoined(WorldPacket *data, uint64 guid); //+ 0x00 + void MakeLeft(WorldPacket *data, uint64 guid); //+ 0x01 + void MakeYouJoined(WorldPacket *data); //+ 0x02 + void MakeYouLeft(WorldPacket *data); //+ 0x03 + void MakeWrongPassword(WorldPacket *data); //? 0x04 + void MakeNotMember(WorldPacket *data); //? 0x05 + void MakeNotModerator(WorldPacket *data); //? 0x06 + void MakePasswordChanged(WorldPacket *data, uint64 guid); //+ 0x07 + void MakeOwnerChanged(WorldPacket *data, uint64 guid); //? 0x08 + void MakePlayerNotFound(WorldPacket *data, std::string name); //+ 0x09 + void MakeNotOwner(WorldPacket *data); //? 0x0A + void MakeChannelOwner(WorldPacket *data); //? 0x0B + void MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags); //+ 0x0C + void MakeAnnouncementsOn(WorldPacket *data, uint64 guid); //+ 0x0D + void MakeAnnouncementsOff(WorldPacket *data, uint64 guid); //+ 0x0E + void MakeModerationOn(WorldPacket *data, uint64 guid); //+ 0x0F + void MakeModerationOff(WorldPacket *data, uint64 guid); //+ 0x10 + void MakeMuted(WorldPacket *data); //? 0x11 + void MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good); //? 0x12 + void MakeBanned(WorldPacket *data); //? 0x13 + void MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x14 + void MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x15 + void MakePlayerNotBanned(WorldPacket *data, uint64 guid); //? 0x16 + void MakePlayerAlreadyMember(WorldPacket *data, uint64 guid); //+ 0x17 + void MakeInvite(WorldPacket *data, uint64 guid); //? 0x18 + void MakeInviteWrongFaction(WorldPacket *data); //? 0x19 + void MakeWrongFaction(WorldPacket *data); //? 0x1A + void MakeInvalidName(WorldPacket *data); //? 0x1B + void MakeNotModerated(WorldPacket *data); //? 0x1C + void MakePlayerInvited(WorldPacket *data, uint64 guid); //+ 0x1D + void MakePlayerInviteBanned(WorldPacket *data, uint64 guid); //? 0x1E + void MakeThrottled(WorldPacket *data); //? 0x1F + void MakeNotInArea(WorldPacket *data); //? 0x20 + void MakeNotInLfg(WorldPacket *data); //? 0x21 + void MakeVoiceOn(WorldPacket *data, uint64 guid); //+ 0x22 + void MakeVoiceOff(WorldPacket *data, uint64 guid); //+ 0x23 + + void SendToAll(WorldPacket *data, uint64 p = 0); + void SendToAllButOne(WorldPacket *data, uint64 who); + void SendToOne(WorldPacket *data, uint64 who); + + bool IsOn(uint64 who) const { return players.count(who) > 0; } + + bool IsBanned(const uint64 guid) const + { + for(BannedList::const_iterator i = banned.begin(); i != banned.end(); ++i) + if(*i == guid) + return true; + return false; + } + + bool IsFirst() const { return !(players.size() > 1); } + + uint8 GetPlayerFlags(uint64 p) const + { + PlayerList::const_iterator p_itr = players.find(p); + if(p_itr == players.end()) + return 0; + + return p_itr->second.flags; + } + + void SetModerator(uint64 p, bool set) + { + if(players[p].IsModerator() != set) + { + uint8 oldFlag = GetPlayerFlags(p); + players[p].SetModerator(set); + + WorldPacket data; + MakeModeChange(&data, p, oldFlag); + SendToAll(&data); + } + } + + void SetMute(uint64 p, bool set) + { + if(players[p].IsMuted() != set) + { + uint8 oldFlag = GetPlayerFlags(p); + players[p].SetMuted(set); + + WorldPacket data; + MakeModeChange(&data, p, oldFlag); + SendToAll(&data); + } + } + + public: + Channel(std::string name, uint32 channel_id); + std::string GetName() const { return m_name; } + uint32 GetChannelId() const { return m_channelId; } + bool IsConstant() const { return m_channelId != 0; } + bool IsAnnounce() const { return m_announce; } + bool IsLFG() const { return GetFlags() & CHANNEL_FLAG_LFG; } + std::string GetPassword() const { return m_password; } + void SetPassword(std::string npassword) { m_password = npassword; } + void SetAnnounce(bool nannounce) { m_announce = nannounce; } + uint32 GetNumPlayers() const { return players.size(); } + uint8 GetFlags() const { return m_flags; } + bool HasFlag(uint8 flag) { return m_flags & flag; } + + void Join(uint64 p, const char *pass); + void Leave(uint64 p, bool send = true); + void KickOrBan(uint64 good, const char *badname, bool ban); + void Kick(uint64 good, const char *badname) { KickOrBan(good, badname, false); } + void Ban(uint64 good, const char *badname) { KickOrBan(good, badname, true); } + void UnBan(uint64 good, const char *badname); + void Password(uint64 p, const char *pass); + void SetMode(uint64 p, const char *p2n, bool mod, bool set); + void SetOwner(uint64 p, bool exclaim = true); + void SetOwner(uint64 p, const char *newname); + void SendWhoOwner(uint64 p); + void SetModerator(uint64 p, const char *newname) { SetMode(p, newname, true, true); } + void UnsetModerator(uint64 p, const char *newname) { SetMode(p, newname, true, false); } + void SetMute(uint64 p, const char *newname) { SetMode(p, newname, false, true); } + void UnsetMute(uint64 p, const char *newname) { SetMode(p, newname, false, false); } + void List(Player* p); + void Announce(uint64 p); + void Moderate(uint64 p); + void Say(uint64 p, const char *what, uint32 lang); + void Invite(uint64 p, const char *newp); + void Voice(uint64 guid1, uint64 guid2); + void DeVoice(uint64 guid1, uint64 guid2); + void JoinNotify(uint64 guid); // invisible notify + void LeaveNotify(uint64 guid); // invisible notify +}; +#endif diff --git a/src/game/ChannelHandler.cpp b/src/game/ChannelHandler.cpp new file mode 100644 index 000000000..3a3a73e97 --- /dev/null +++ b/src/game/ChannelHandler.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ObjectMgr.h" // for normalizePlayerName +#include "ChannelMgr.h" +#include "Policies/SingletonImp.h" + +INSTANTIATE_SINGLETON_1( AllianceChannelMgr ); +INSTANTIATE_SINGLETON_1( HordeChannelMgr ); + +void WorldSession::HandleChannelJoin(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 4+1+1+1); + + uint32 channel_id; + uint8 unknown1, unknown2; + std::string channelname, pass; + + recvPacket >> channel_id >> unknown1 >> unknown2; + recvPacket >> channelname; + + if(channelname.empty()) + return; + + // recheck + CHECK_PACKET_SIZE(recvPacket, 4+1+1+(channelname.size()+1)+1); + + recvPacket >> pass; + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetJoinChannel(channelname, channel_id)) + chn->Join(_player->GetGUID(), pass.c_str()); +} + +void WorldSession::HandleChannelLeave(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 4+1); + + uint32 unk; + std::string channelname; + recvPacket >> unk; // channel id? + recvPacket >> channelname; + + if(channelname.empty()) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + { + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Leave(_player->GetGUID(), true); + cMgr->LeftChannel(channelname); + } +} + +void WorldSession::HandleChannelList(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->List(_player); +} + +void WorldSession::HandleChannelPassword(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, pass; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> pass; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Password(_player->GetGUID(), pass.c_str()); +} + +void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, newp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> newp; + + if(!normalizePlayerName(newp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->SetOwner(_player->GetGUID(), newp.c_str()); +} + +void WorldSession::HandleChannelOwner(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->SendWhoOwner(_player->GetGUID()); +} + +void WorldSession::HandleChannelModerator(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->SetModerator(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->UnsetModerator(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelMute(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->SetMute(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->UnsetMute(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelInvite(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Invite(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelKick(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Kick(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelBan(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Ban(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelUnban(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1+1); + + std::string channelname, otp; + recvPacket >> channelname; + + // recheck + CHECK_PACKET_SIZE(recvPacket, (channelname.size()+1)+1); + + recvPacket >> otp; + + if(!normalizePlayerName(otp)) + return; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->UnBan(_player->GetGUID(), otp.c_str()); +} + +void WorldSession::HandleChannelAnnounce(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Announce(_player->GetGUID()); +} + +void WorldSession::HandleChannelModerate(WorldPacket& recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->Moderate(_player->GetGUID()); +} + +void WorldSession::HandleChannelRosterQuery(WorldPacket &recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->List(_player); +} + +void WorldSession::HandleChannelInfoQuery(WorldPacket &recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + { + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + { + WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, chn->GetName().size()+1+1+4); + data << chn->GetName(); + data << uint8(chn->GetFlags()); + data << uint32(chn->GetNumPlayers()); + SendPacket(&data); + } + } +} + +void WorldSession::HandleChannelJoinNotify(WorldPacket &recvPacket) +{ + sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); + //recvPacket.hexlike(); + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string channelname; + recvPacket >> channelname; + /*if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + if(Channel *chn = cMgr->GetChannel(channelname, _player)) + chn->JoinNotify(_player->GetGUID());*/ +} diff --git a/src/game/ChannelMgr.h b/src/game/ChannelMgr.h new file mode 100644 index 000000000..b3e3ac2e4 --- /dev/null +++ b/src/game/ChannelMgr.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef MANGOSSERVER_CHANNELMGR_H +#define MANGOSSERVER_CHANNELMGR_H + +#include "Channel.h" +#include "Policies/Singleton.h" +#include "World.h" + +#include +#include + +class ChannelMgr +{ + public: + typedef std::map ChannelMap; + ChannelMgr() {} + ~ChannelMgr() + { + for(ChannelMap::iterator itr = channels.begin();itr!=channels.end(); ++itr) + delete itr->second; + channels.clear(); + } + Channel *GetJoinChannel(std::string name, uint32 channel_id) + { + if(channels.count(name) == 0) + { + Channel *nchan = new Channel(name,channel_id); + channels[name] = nchan; + } + return channels[name]; + } + Channel *GetChannel(std::string name, Player *p) + { + ChannelMap::const_iterator i = channels.find(name); + + if(i == channels.end()) + { + WorldPacket data; + MakeNotOnPacket(&data,name); + p->GetSession()->SendPacket(&data); + return NULL; + } + else + return i->second; + } + void LeftChannel(std::string name) + { + ChannelMap::const_iterator i = channels.find(name); + + if(i == channels.end()) + return; + + Channel* channel = i->second; + + if(channel->GetNumPlayers() == 0 && !channel->IsConstant()) + { + channels.erase(name); + delete channel; + } + } + private: + ChannelMap channels; + void MakeNotOnPacket(WorldPacket *data, std::string name) + { + data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size + (*data) << (uint8)0x05 << name; + } +}; + +class AllianceChannelMgr : public ChannelMgr {}; +class HordeChannelMgr : public ChannelMgr {}; + +inline ChannelMgr* channelMgr(uint32 team) +{ + if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) + //For Test,No Seprate Faction + return &MaNGOS::Singleton::Instance(); + + if(team==ALLIANCE) + return &MaNGOS::Singleton::Instance(); + if(team==HORDE) + return &MaNGOS::Singleton::Instance(); + return NULL; +} +#endif diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp new file mode 100644 index 000000000..e174fe6c2 --- /dev/null +++ b/src/game/CharacterHandler.cpp @@ -0,0 +1,1080 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "SharedDefines.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Guild.h" +#include "UpdateMask.h" +#include "Auth/md5.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Group.h" +#include "Database/DatabaseImpl.h" +#include "PlayerDump.h" +#include "SocialMgr.h" +#include "Util.h" +#include "Language.h" + +class LoginQueryHolder : public SqlQueryHolder +{ + private: + uint32 m_accountId; + uint64 m_guid; + public: + LoginQueryHolder(uint32 accountId, uint64 guid) + : m_accountId(accountId), m_guid(guid) { } + uint64 GetGuid() const { return m_guid; } + uint32 GetAccountId() const { return m_accountId; } + bool Initialize(); +}; + +bool LoginQueryHolder::Initialize() +{ + SetSize(MAX_PLAYER_LOGIN_QUERY); + + bool res = true; + + // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. + // !!! NOTE: including unused `zone`,`online` + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, gmstate, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,slot,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTUTORIALS, "SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetAccountId(), realmID); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" I64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHOMEBIND, "SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS, "SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'", GUID_LOPART(m_guid)); + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid)); + // in other case still be dummy query + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid)); + + return res; +} + +// don't call WorldSession directly +// it may get deleted before the query callbacks get executed +// instead pass an account id to this handler +class CharacterHandler +{ + public: + void HandleCharEnumCallback(QueryResult * result, uint32 account) + { + WorldSession * session = sWorld.FindSession(account); + if(!session) + { + delete result; + return; + } + session->HandleCharEnum(result); + } + void HandlePlayerLoginCallback(QueryResult * /*dummy*/, SqlQueryHolder * holder) + { + if (!holder) return; + WorldSession *session = sWorld.FindSession(((LoginQueryHolder*)holder)->GetAccountId()); + if(!session) + { + delete holder; + return; + } + session->HandlePlayerLogin((LoginQueryHolder*)holder); + } +} chrHandler; + +void WorldSession::HandleCharEnum(QueryResult * result) +{ + // keys can be non cleared if player open realm list and close it by 'cancel' + loginDatabase.PExecute("UPDATE account SET v = '0', s = '0' WHERE id = '%u'", GetAccountId()); + + WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size + + uint8 num = 0; + + data << num; + + if( result ) + { + Player *plr = new Player(this); + do + { + sLog.outDetail("Loading char guid %u from account %u.",(*result)[0].GetUInt32(),GetAccountId()); + + if(plr->MinimalLoadFromDB( result, (*result)[0].GetUInt32() )) + { + plr->BuildEnumData( result, &data ); + ++num; + } + } + while( result->NextRow() ); + + delete plr; + delete result; + } + + data.put(0, num); + + SendPacket( &data ); +} + +void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) +{ + /// get all the data necessary for loading all characters (along with their pets) on the account + CharacterDatabase.AsyncPQuery(&chrHandler, &CharacterHandler::HandleCharEnumCallback, GetAccountId(), + !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ? + // ------- Query Without Declined Names -------- + // 0 1 2 3 4 5 6 7 8 + "SELECT characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, characters.at_login, " + // 9 10 11 + "character_pet.entry, character_pet.modelid, character_pet.level " + "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' " + "WHERE characters.account = '%u' ORDER BY characters.guid" + : + // --------- Query With Declined Names --------- + // 0 1 2 3 4 5 6 7 8 + "SELECT characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, characters.at_login, " + // 9 10 11 12 + "character_pet.entry, character_pet.modelid, character_pet.level, genitive " + "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' " + "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " + "WHERE characters.account = '%u' ORDER BY characters.guid", + GetAccountId()); +} + +void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1+1+1+1+1+1+1+1+1); + + std::string name; + uint8 race_,class_; + + recv_data >> name; + + // recheck with known string size + CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1+1+1+1+1+1+1+1+1); + + recv_data >> race_; + recv_data >> class_; + + WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases + + if(GetSecurity() == SEC_PLAYER) + { + if(uint32 mask = sWorld.getConfig(CONFIG_CHARACTERS_CREATING_DISABLED)) + { + bool disabled = false; + + uint32 team = Player::TeamForRace(race_); + switch(team) + { + case ALLIANCE: disabled = mask & (1<<0); break; + case HORDE: disabled = mask & (1<<1); break; + } + + if(disabled) + { + data << (uint8)CHAR_CREATE_DISABLED; + SendPacket( &data ); + return; + } + } + } + + ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); + ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_); + + if( !classEntry || !raceEntry ) + { + data << (uint8)CHAR_CREATE_FAILED; + SendPacket( &data ); + sLog.outError("Class: %u or Race %u not found in DBC (Wrong DBC files?) or Cheater?", class_, race_); + return; + } + + // prevent character creating Expansion race without Expansion account + if (raceEntry->addon > Expansion()) + { + data << (uint8)CHAR_CREATE_EXPANSION; + sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_); + SendPacket( &data ); + return; + } + + // prevent character creating Expansion class without Expansion account + // TODO: use possible addon field in ChrClassesEntry in next dbc version + if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT) + { + data << (uint8)CHAR_CREATE_EXPANSION; + sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_); + SendPacket( &data ); + return; + } + + // prevent character creating with invalid name + if(!normalizePlayerName(name)) + { + data << (uint8)CHAR_NAME_INVALID_CHARACTER; + SendPacket( &data ); + sLog.outError("Account:[%d] but tried to Create character with empty [name] ",GetAccountId()); + return; + } + + // check name limitations + if(!ObjectMgr::IsValidName(name,true)) + { + data << (uint8)CHAR_NAME_INVALID_CHARACTER; + SendPacket( &data ); + return; + } + + if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(name)) + { + data << (uint8)CHAR_NAME_RESERVED; + SendPacket( &data ); + return; + } + + if(objmgr.GetPlayerGUIDByName(name)) + { + data << (uint8)CHAR_CREATE_NAME_IN_USE; + SendPacket( &data ); + return; + } + + QueryResult *resultacct = loginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%d'", GetAccountId()); + if ( resultacct ) + { + Field *fields=resultacct->Fetch(); + uint32 acctcharcount = fields[0].GetUInt32(); + delete resultacct; + + if (acctcharcount >= sWorld.getConfig(CONFIG_CHARACTERS_PER_ACCOUNT)) + { + data << (uint8)CHAR_CREATE_ACCOUNT_LIMIT; + SendPacket( &data ); + return; + } + } + + QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", GetAccountId()); + uint8 charcount = 0; + if ( result ) + { + Field *fields=result->Fetch(); + charcount = fields[0].GetUInt8(); + delete result; + + if (charcount >= sWorld.getConfig(CONFIG_CHARACTERS_PER_REALM)) + { + data << (uint8)CHAR_CREATE_SERVER_LIMIT; + SendPacket( &data ); + return; + } + } + + bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER; + uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS); + + bool have_same_race = false; + if(!AllowTwoSideAccounts || skipCinematics == 1) + { + QueryResult *result2 = CharacterDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1"); + if(result2) + { + uint32 team_= Player::TeamForRace(race_); + + Field* field = result2->Fetch(); + uint8 race = field[0].GetUInt32(); + + // need to check team only for first character + // TODO: what to if account already has characters of both races? + if (!AllowTwoSideAccounts) + { + uint32 team=0; + if(race > 0) + team = Player::TeamForRace(race); + + if(team != team_) + { + data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION; + SendPacket( &data ); + delete result2; + return; + } + } + + if (skipCinematics == 1) + { + // TODO: check if cinematic already shown? (already logged in?; cinematic field) + while (race_ != race && result2->NextRow()) + { + field = result2->Fetch(); + race = field[0].GetUInt32(); + } + have_same_race = race_ == race; + } + delete result2; + } + } + + // extract other data required for player creating + uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId; + recv_data >> gender >> skin >> face; + recv_data >> hairStyle >> hairColor >> facialHair >> outfitId; + + Player * pNewChar = new Player(this); + if(!pNewChar->Create( objmgr.GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId )) + { + // Player not create (race/class problem?) + delete pNewChar; + + data << (uint8)CHAR_CREATE_ERROR; + SendPacket( &data ); + + return; + } + + if(have_same_race && skipCinematics == 1 || skipCinematics == 2) + pNewChar->setCinematic(1); // not show intro + + // Player created, save it now + pNewChar->SaveToDB(); + charcount+=1; + + loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID); + loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charcount, GetAccountId(), realmID); + + delete pNewChar; // created only to call SaveToDB() + + data << (uint8)CHAR_CREATE_SUCCESS; + SendPacket( &data ); + + std::string IP_str = GetRemoteAddress().c_str(); + sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); + sLog.outChar("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); +} + +void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + // can't delete loaded character + if(objmgr.GetPlayer(guid)) + return; + + uint32 accountId = 0; + std::string name; + + // is guild leader + if(objmgr.GetGuildByLeader(guid)) + { + WorldPacket data(SMSG_CHAR_DELETE, 1); + data << (uint8)CHAR_DELETE_FAILED_GUILD_LEADER; + SendPacket( &data ); + return; + } + + // is arena team captain + if(objmgr.GetArenaTeamByCapitan(guid)) + { + WorldPacket data(SMSG_CHAR_DELETE, 1); + data << (uint8)CHAR_DELETE_FAILED_ARENA_CAPTAIN; + SendPacket( &data ); + return; + } + + QueryResult *result = CharacterDatabase.PQuery("SELECT account,name FROM characters WHERE guid='%u'", GUID_LOPART(guid)); + if(result) + { + Field *fields = result->Fetch(); + accountId = fields[0].GetUInt32(); + name = fields[1].GetCppString(); + delete result; + } + + // prevent deleting other players' characters using cheating tools + if(accountId != GetAccountId()) + return; + + std::string IP_str = GetRemoteAddress(); + sLog.outBasic("Account: %d (IP: %s) Delete Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); + sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); + + if(sLog.IsOutCharDump()) // optimize GetPlayerDump call + { + std::string dump = PlayerDumpWriter().GetDump(GUID_LOPART(guid)); + sLog.outCharDump(dump.c_str(),GetAccountId(),GUID_LOPART(guid),name.c_str()); + } + + Player::DeleteFromDB(guid, GetAccountId()); + + WorldPacket data(SMSG_CHAR_DELETE, 1); + data << (uint8)CHAR_DELETE_SUCCESS; + SendPacket( &data ); +} + +void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + m_playerLoading = true; + uint64 playerGuid = 0; + + DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); + + recv_data >> playerGuid; + + LoginQueryHolder *holder = new LoginQueryHolder(GetAccountId(), playerGuid); + if(!holder->Initialize()) + { + delete holder; // delete all unprocessed queries + m_playerLoading = false; + return; + } + + CharacterDatabase.DelayQueryHolder(&chrHandler, &CharacterHandler::HandlePlayerLoginCallback, holder); +} + +void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) +{ + uint64 playerGuid = holder->GetGuid(); + + Player* pCurrChar = new Player(this); + pCurrChar->GetMotionMaster()->Initialize(); + + // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) + if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) + { + KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick + delete pCurrChar; // delete it manually + delete holder; // delete all unprocessed queries + m_playerLoading = false; + return; + } + + SetPlayer(pCurrChar); + + pCurrChar->SendDungeonDifficulty(false); + + WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); + data << pCurrChar->GetMapId(); + data << pCurrChar->GetPositionX(); + data << pCurrChar->GetPositionY(); + data << pCurrChar->GetPositionZ(); + data << pCurrChar->GetOrientation(); + SendPacket(&data); + + data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 ); + for(int i = 0; i < 32; i++) + data << uint32(0); + SendPacket(&data); + + data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 + data << uint8(2); // unknown value + data << uint8(0); // enable(1)/disable(0) voice chat interface in client + SendPacket(&data); + + // Send MOTD + { + data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 + data << (uint32)0; + + uint32 linecount=0; + std::string str_motd = sWorld.GetMotd(); + std::string::size_type pos, nextpos; + + pos = 0; + while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) + { + if (nextpos != pos) + { + data << str_motd.substr(pos,nextpos-pos); + ++linecount; + } + pos = nextpos+1; + } + + if (posGetGuildId() != 0) + { + Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); + if(guild) + { + data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); + data << (uint8)GE_MOTD; + data << (uint8)1; + data << guild->GetMOTD(); + SendPacket(&data); + DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); + + data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size + data<<(uint8)GE_SIGNED_ON; + data<<(uint8)1; + data<GetName(); + data<GetGUID(); + guild->BroadcastPacket(&data); + DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); + + // Increment online members of the guild + guild->IncOnlineMemberCount(); + } + else + { + // remove wrong guild data + sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); + pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); + pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); + } + } + + if(!pCurrChar->isAlive()) + pCurrChar->SendCorpseReclaimDelay(true); + + pCurrChar->SendInitialPacketsBeforeAddToMap(); + + //Show cinematic at the first time that player login + if( !pCurrChar->getCinematic() ) + { + pCurrChar->setCinematic(1); + + ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()); + if(rEntry) + { + data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); + data << uint32(rEntry->startmovie); + SendPacket( &data ); + } + } + + //QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); + QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); + + if(resultGuild) + { + Field *fields = resultGuild->Fetch(); + pCurrChar->SetInGuild(fields[0].GetUInt32()); + pCurrChar->SetRank(fields[1].GetUInt32()); + delete resultGuild; + } + else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership + { + pCurrChar->SetInGuild(0); + pCurrChar->SetRank(0); + } + + if (!MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar)) + { + AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); + if(at) + pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); + else + pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); + } + + ObjectAccessor::Instance().AddObject(pCurrChar); + //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); + pCurrChar->GetSocial()->SendSocialList(); + + pCurrChar->SendInitialPacketsAfterAddToMap(); + + CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); + loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId()); + pCurrChar->SetInGameTime( getMSTime() ); + + // announce group about member online (must be after add to player list to receive announce to self) + if(Group *group = pCurrChar->GetGroup()) + { + //pCurrChar->groupInfo.group->SendInit(this); // useless + group->SendUpdate(); + } + + // friend status + sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), "", true); + + // Place character in world (and load zone) before some object loading + pCurrChar->LoadCorpse(); + + // setting Ghost+speed if dead + //if ( pCurrChar->m_deathState == DEAD ) + if (pCurrChar->m_deathState != ALIVE) + { + // not blizz like, we must correctly save and load player instead... + if(pCurrChar->getRace() == RACE_NIGHTELF) + pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) + pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) + + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); + //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); + //if (pCurrChar->getRace() == RACE_NIGHTELF) + //{ + // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); + // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); + //} + //else + //{ + // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); + // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); + //} + pCurrChar->SetMovement(MOVE_WATER_WALK); + } + + if(uint32 sourceNode = pCurrChar->m_taxi.GetTaxiSource()) + { + + sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() ); + + uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam()); + uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath(); + + // search appropriate start path node + uint32 startNode = 0; + + TaxiPathNodeList const& nodeList = sTaxiPathNodesByPath[path]; + + float distPrev = MAP_SIZE*MAP_SIZE; + float distNext = + (nodeList[0].x-pCurrChar->GetPositionX())*(nodeList[0].x-pCurrChar->GetPositionX())+ + (nodeList[0].y-pCurrChar->GetPositionY())*(nodeList[0].y-pCurrChar->GetPositionY())+ + (nodeList[0].z-pCurrChar->GetPositionZ())*(nodeList[0].z-pCurrChar->GetPositionZ()); + + for(uint32 i = 1; i < nodeList.size(); ++i) + { + TaxiPathNode const& node = nodeList[i]; + TaxiPathNode const& prevNode = nodeList[i-1]; + + // skip nodes at another map + if(node.mapid != pCurrChar->GetMapId()) + continue; + + distPrev = distNext; + + distNext = + (node.x-pCurrChar->GetPositionX())*(node.x-pCurrChar->GetPositionX())+ + (node.y-pCurrChar->GetPositionY())*(node.y-pCurrChar->GetPositionY())+ + (node.z-pCurrChar->GetPositionZ())*(node.z-pCurrChar->GetPositionZ()); + + float distNodes = + (node.x-prevNode.x)*(node.x-prevNode.x)+ + (node.y-prevNode.y)*(node.y-prevNode.y)+ + (node.z-prevNode.z)*(node.z-prevNode.z); + + if(distNext + distPrev < distNodes) + { + startNode = i; + break; + } + } + + SendDoFlight( MountId, path, startNode ); + } + + // Load pet if any and player is alive and not in taxi flight + if(pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource()==0) + pCurrChar->LoadPet(); + + // Set FFA PvP for non GM in non-rest mode + if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) + pCurrChar->SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + + if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) + pCurrChar->SetContestedPvP(); + + // Apply at_login requests + if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) + { + pCurrChar->resetSpells(); + SendNotification(LANG_RESET_SPELLS); + } + + if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) + { + pCurrChar->resetTalents(true); + SendNotification(LANG_RESET_TALENTS); + } + + // show time before shutdown if shutdown planned. + if(sWorld.IsShutdowning()) + sWorld.ShutdownMsg(true,pCurrChar); + + if(pCurrChar->isGameMaster()) + SendNotification(LANG_GM_ON); + + std::string IP_str = GetRemoteAddress(); + sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUID()); + + m_playerLoading = false; + delete holder; +} + +void WorldSession::HandleSetFactionAtWar( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+1); + + DEBUG_LOG( "WORLD: Received CMSG_SET_FACTION_ATWAR" ); + + uint32 repListID; + uint8 flag; + + recv_data >> repListID; + recv_data >> flag; + + FactionStateList::iterator itr = GetPlayer()->m_factions.find(repListID); + if (itr == GetPlayer()->m_factions.end()) + return; + + // always invisible or hidden faction can't change war state + if(itr->second.Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN) ) + return; + + GetPlayer()->SetFactionAtWar(&itr->second,flag); +} + +//I think this function is never used :/ I dunno, but i guess this opcode not exists +void WorldSession::HandleSetFactionCheat( WorldPacket & /*recv_data*/ ) +{ + //CHECK_PACKET_SIZE(recv_data,4+4); + + //sLog.outDebug("WORLD SESSION: HandleSetFactionCheat"); + /* + uint32 FactionID; + uint32 Standing; + + recv_data >> FactionID; + recv_data >> Standing; + + std::list::iterator itr; + + for(itr = GetPlayer()->factions.begin(); itr != GetPlayer()->factions.end(); ++itr) + { + if(itr->ReputationListID == FactionID) + { + itr->Standing += Standing; + itr->Flags = (itr->Flags | 1); + break; + } + } + */ + GetPlayer()->UpdateReputation(); +} + +void WorldSession::HandleMeetingStoneInfo( WorldPacket & /*recv_data*/ ) +{ + DEBUG_LOG( "WORLD: Received CMSG_MEETING_STONE_INFO" ); + + WorldPacket data(SMSG_MEETINGSTONE_SETQUEUE, 5); + data << uint32(0) << uint8(6); + SendPacket(&data); +} + +void WorldSession::HandleTutorialFlag( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 iFlag; + recv_data >> iFlag; + + uint32 wInt = (iFlag / 32); + if (wInt >= 8) + { + //sLog.outError("CHEATER? Account:[%d] Guid[%u] tried to send wrong CMSG_TUTORIAL_FLAG", GetAccountId(),GetGUID()); + return; + } + uint32 rInt = (iFlag % 32); + + uint32 tutflag = GetPlayer()->GetTutorialInt( wInt ); + tutflag |= (1 << rInt); + GetPlayer()->SetTutorialInt( wInt, tutflag ); + + //sLog.outDebug("Received Tutorial Flag Set {%u}.", iFlag); +} + +void WorldSession::HandleTutorialClear( WorldPacket & /*recv_data*/ ) +{ + for ( uint32 iI = 0; iI < 8; iI++) + GetPlayer()->SetTutorialInt( iI, 0xFFFFFFFF ); +} + +void WorldSession::HandleTutorialReset( WorldPacket & /*recv_data*/ ) +{ + for ( uint32 iI = 0; iI < 8; iI++) + GetPlayer()->SetTutorialInt( iI, 0x00000000 ); +} + +void WorldSession::HandleSetWatchedFactionIndexOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4); + + DEBUG_LOG("WORLD: Received CMSG_SET_WATCHED_FACTION"); + uint32 fact; + recv_data >> fact; + GetPlayer()->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fact); +} + +void WorldSession::HandleSetWatchedFactionInactiveOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4+1); + + DEBUG_LOG("WORLD: Received CMSG_SET_FACTION_INACTIVE"); + uint32 replistid; + uint8 inactive; + recv_data >> replistid >> inactive; + + FactionStateList::iterator itr = _player->m_factions.find(replistid); + if (itr == _player->m_factions.end()) + return; + + _player->SetFactionInactive(&itr->second, inactive); +} + +void WorldSession::HandleToggleHelmOpcode( WorldPacket & /*recv_data*/ ) +{ + DEBUG_LOG("CMSG_TOGGLE_HELM for %s", _player->GetName()); + _player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM); +} + +void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ ) +{ + DEBUG_LOG("CMSG_TOGGLE_CLOAK for %s", _player->GetName()); + _player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK); +} + +void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8+1); + + uint64 guid; + std::string newname; + std::string oldname; + + CHECK_PACKET_SIZE(recv_data, 8+1); + + recv_data >> guid; + recv_data >> newname; + + QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); + if (result) + { + uint32 at_loginFlags; + Field *fields = result->Fetch(); + at_loginFlags = fields[0].GetUInt32(); + delete result; + + if (!(at_loginFlags & AT_LOGIN_RENAME)) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_CREATE_ERROR; + SendPacket( &data ); + return; + } + } + else + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_CREATE_ERROR; + SendPacket( &data ); + return; + } + + if(!objmgr.GetPlayerNameByGUID(guid, oldname)) // character not exist, because we have no name for this guid + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_LOGIN_NO_CHARACTER; + SendPacket( &data ); + return; + } + + // prevent character rename to invalid name + if(!normalizePlayerName(newname)) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_NAME_NO_NAME; + SendPacket( &data ); + return; + } + + if(!ObjectMgr::IsValidName(newname,true)) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_NAME_INVALID_CHARACTER; + SendPacket( &data ); + return; + } + + // check name limitations + if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_NAME_RESERVED; + SendPacket( &data ); + return; + } + + if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_CREATE_ERROR; + SendPacket( &data ); + return; + } + + if(newname == oldname) // checked by client + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << (uint8)CHAR_NAME_FAILURE; + SendPacket( &data ); + return; + } + + // we have to check character at_login_flag & AT_LOGIN_RENAME also (fake packets hehe) + + CharacterDatabase.escape_string(newname); + CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME),GUID_LOPART(guid)); + CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); + + std::string IP_str = GetRemoteAddress(); + sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",GetAccountId(),IP_str.c_str(),oldname.c_str(),GUID_LOPART(guid),newname.c_str()); + + WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1)); + data << (uint8)RESPONSE_SUCCESS; + data << guid; + data << newname; + SendPacket(&data); +} + +void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data) +{ + uint64 guid; + + CHECK_PACKET_SIZE(recv_data, 8); + recv_data >> guid; + + // not accept declined names for unsupported languages + std::string name; + if(!objmgr.GetPlayerNameByGUID(guid, name)) + { + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(1); + data << uint64(guid); + SendPacket(&data); + return; + } + + std::wstring wname; + if(!Utf8toWStr(name, wname)) + { + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(1); + data << uint64(guid); + SendPacket(&data); + return; + } + + if(!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using + { + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(1); + data << uint64(guid); + SendPacket(&data); + return; + } + + std::string name2; + DeclinedName declinedname; + + CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1); + recv_data >> name2; + + if(name2 != name) // character have different name + { + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(1); + data << uint64(guid); + SendPacket(&data); + return; + } + + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + { + CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1); + recv_data >> declinedname.name[i]; + if(!normalizePlayerName(declinedname.name[i])) + { + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(1); + data << uint64(guid); + SendPacket(&data); + return; + } + } + + if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname, 0), declinedname)) + { + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(1); + data << uint64(guid); + SendPacket(&data); + return; + } + + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + CharacterDatabase.escape_string(declinedname.name[i]); + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid)); + CharacterDatabase.PExecute("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%s','%s','%s','%s','%s')", + GUID_LOPART(guid), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); + CharacterDatabase.CommitTransaction(); + + WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); + data << uint32(0); // OK + data << uint64(guid); + SendPacket(&data); +} diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp new file mode 100644 index 000000000..a45c217e4 --- /dev/null +++ b/src/game/Chat.cpp @@ -0,0 +1,1091 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Language.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "UpdateMask.h" +#include "Chat.h" +#include "MapManager.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" + +bool ChatHandler::load_command_table = true; + +ChatCommand * ChatHandler::getCommandTable() +{ + static ChatCommand serverCommandTable[] = + { + { "idlerestart", SEC_ADMINISTRATOR, &ChatHandler::HandleIdleRestartCommand, "", NULL }, + { "idleshutdown", SEC_ADMINISTRATOR, &ChatHandler::HandleIdleShutDownCommand, "", NULL }, + { "info", SEC_PLAYER, &ChatHandler::HandleInfoCommand, "", NULL }, + { "restart", SEC_ADMINISTRATOR, &ChatHandler::HandleRestartCommand, "", NULL }, + { "shutdown", SEC_ADMINISTRATOR, &ChatHandler::HandleShutDownCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand modifyCommandTable[] = + { + { "hp", SEC_MODERATOR, &ChatHandler::HandleModifyHPCommand, "", NULL }, + { "mana", SEC_MODERATOR, &ChatHandler::HandleModifyManaCommand, "", NULL }, + { "rage", SEC_MODERATOR, &ChatHandler::HandleModifyRageCommand, "", NULL }, + { "energy", SEC_MODERATOR, &ChatHandler::HandleModifyEnergyCommand, "", NULL }, + { "money", SEC_MODERATOR, &ChatHandler::HandleModifyMoneyCommand, "", NULL }, + { "speed", SEC_MODERATOR, &ChatHandler::HandleModifySpeedCommand, "", NULL }, + { "swim", SEC_MODERATOR, &ChatHandler::HandleModifySwimCommand, "", NULL }, + { "scale", SEC_MODERATOR, &ChatHandler::HandleModifyScaleCommand, "", NULL }, + { "bit", SEC_MODERATOR, &ChatHandler::HandleModifyBitCommand, "", NULL }, + { "bwalk", SEC_MODERATOR, &ChatHandler::HandleModifyBWalkCommand, "", NULL }, + { "fly", SEC_MODERATOR, &ChatHandler::HandleModifyFlyCommand, "", NULL }, + { "aspeed", SEC_MODERATOR, &ChatHandler::HandleModifyASpeedCommand, "", NULL }, + { "faction", SEC_MODERATOR, &ChatHandler::HandleModifyFactionCommand, "", NULL }, + { "spell", SEC_MODERATOR, &ChatHandler::HandleModifySpellCommand, "", NULL }, + { "tp", SEC_MODERATOR, &ChatHandler::HandleModifyTalentCommand, "", NULL }, + { "titles", SEC_MODERATOR, &ChatHandler::HandleModifyKnownTitlesCommand, "", NULL }, + { "mount", SEC_MODERATOR, &ChatHandler::HandleModifyMountCommand, "", NULL }, + { "honor", SEC_MODERATOR, &ChatHandler::HandleModifyHonorCommand, "", NULL }, + { "rep", SEC_MODERATOR, &ChatHandler::HandleModifyRepCommand, "", NULL }, + { "arena", SEC_MODERATOR, &ChatHandler::HandleModifyArenaCommand, "", NULL }, + { "drunk", SEC_MODERATOR, &ChatHandler::HandleDrunkCommand, "", NULL }, + { "standstate", SEC_GAMEMASTER, &ChatHandler::HandleStandStateCommand, "", NULL }, + { "morph", SEC_GAMEMASTER, &ChatHandler::HandleMorphCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand wpCommandTable[] = + { + { "show", SEC_GAMEMASTER, &ChatHandler::HandleWpShowCommand, "", NULL }, + { "add", SEC_GAMEMASTER, &ChatHandler::HandleWpAddCommand, "", NULL }, + { "modify", SEC_GAMEMASTER, &ChatHandler::HandleWpModifyCommand, "", NULL }, + { "export", SEC_ADMINISTRATOR, &ChatHandler::HandleWpExportCommand, "", NULL }, + { "import", SEC_ADMINISTRATOR, &ChatHandler::HandleWpImportCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand debugCommandTable[] = + { + { "inarc", SEC_ADMINISTRATOR, &ChatHandler::HandleDebugInArcCommand, "", NULL }, + { "spellfail", SEC_ADMINISTRATOR, &ChatHandler::HandleDebugSpellFailCommand, "", NULL }, + { "setpoi", SEC_ADMINISTRATOR, &ChatHandler::HandleSetPoiCommand, "", NULL }, + { "qpartymsg", SEC_ADMINISTRATOR, &ChatHandler::HandleSendQuestPartyMsgCommand, "", NULL }, + { "qinvalidmsg", SEC_ADMINISTRATOR, &ChatHandler::HandleSendQuestInvalidMsgCommand, "", NULL }, + { "equiperr", SEC_ADMINISTRATOR, &ChatHandler::HandleEquipErrorCommand, "", NULL }, + { "sellerr", SEC_ADMINISTRATOR, &ChatHandler::HandleSellErrorCommand, "", NULL }, + { "buyerr", SEC_ADMINISTRATOR, &ChatHandler::HandleBuyErrorCommand, "", NULL }, + { "sendopcode", SEC_ADMINISTRATOR, &ChatHandler::HandleSendOpcodeCommand, "", NULL }, + { "uws", SEC_ADMINISTRATOR, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL }, + { "ps", SEC_ADMINISTRATOR, &ChatHandler::HandlePlaySound2Command, "", NULL }, + { "scn", SEC_ADMINISTRATOR, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL }, + { "scm", SEC_ADMINISTRATOR, &ChatHandler::HandleSendChatMsgCommand, "", NULL }, + { "getitemstate", SEC_ADMINISTRATOR, &ChatHandler::HandleGetItemState, "", NULL }, + { "playsound", SEC_MODERATOR, &ChatHandler::HandlePlaySoundCommand, "", NULL }, + { "update", SEC_ADMINISTRATOR, &ChatHandler::HandleUpdate, "", NULL }, + { "setvalue", SEC_ADMINISTRATOR, &ChatHandler::HandleSetValue, "", NULL }, + { "getvalue", SEC_ADMINISTRATOR, &ChatHandler::HandleGetValue, "", NULL }, + { "Mod32Value", SEC_ADMINISTRATOR, &ChatHandler::HandleMod32Value, "", NULL }, + { "anim", SEC_GAMEMASTER, &ChatHandler::HandleAnimCommand, "", NULL }, + { "lootrecipient", SEC_GAMEMASTER, &ChatHandler::HandleGetLootRecipient, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand eventCommandTable[] = + { + { "activelist", SEC_GAMEMASTER, &ChatHandler::HandleEventActiveListCommand, "", NULL }, + { "start", SEC_GAMEMASTER, &ChatHandler::HandleEventStartCommand, "", NULL }, + { "stop", SEC_GAMEMASTER, &ChatHandler::HandleEventStopCommand, "", NULL }, + { "", SEC_GAMEMASTER, &ChatHandler::HandleEventInfoCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand learnCommandTable[] = + { + { "all", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllCommand, "", NULL }, + { "all_gm", SEC_GAMEMASTER, &ChatHandler::HandleLearnAllGMCommand, "", NULL }, + { "all_crafts", SEC_GAMEMASTER, &ChatHandler::HandleLearnAllCraftsCommand, "", NULL }, + { "all_default", SEC_MODERATOR, &ChatHandler::HandleLearnAllDefaultCommand, "", NULL }, + { "all_lang", SEC_MODERATOR, &ChatHandler::HandleLearnAllLangCommand, "", NULL }, + { "all_myclass", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllMyClassCommand, "", NULL }, + { "all_myspells", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllMySpellsCommand, "", NULL }, + { "all_mytalents", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllMyTalentsCommand, "", NULL }, + { "all_recipes", SEC_GAMEMASTER, &ChatHandler::HandleLearnAllRecipesCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand reloadCommandTable[] = + { + { "all", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllCommand, "", NULL }, + { "all_loot", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllLootCommand, "", NULL }, + { "all_npc", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllNpcCommand, "", NULL }, + { "all_quest", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllQuestCommand, "", NULL }, + { "all_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL }, + { "all_spell", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllSpellCommand, "", NULL }, + { "all_item", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllItemCommand, "", NULL }, + { "all_locales", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL }, + + { "config", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadConfigCommand, "", NULL }, + + { "areatrigger_tavern", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL }, + { "areatrigger_teleport", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL }, + { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL }, + { "event_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, + { "command", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCommandCommand, "", NULL }, + { "creature_involvedrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, + { "creature_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, + { "creature_questrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, + { "disenchant_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, + { "fishing_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, + { "game_graveyard_zone", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL }, + { "game_tele", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameTeleCommand, "", NULL }, + { "gameobject_involvedrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGOQuestInvRelationsCommand, "", NULL }, + { "gameobject_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL }, + { "gameobject_questrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL }, + { "gameobject_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL }, + { "item_enchantment_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL }, + { "item_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, + { "mangos_string", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadMangosStringCommand, "", NULL }, + { "npc_gossip", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, + { "npc_trainer", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, + { "npc_vendor", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, + { "page_text", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadPageTextsCommand, "", NULL }, + { "pickpocketing_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL}, + { "prospecting_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL }, + { "quest_mail_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL }, + { "quest_end_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL }, + { "quest_start_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL }, + { "quest_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL }, + { "reference_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL }, + { "reserved_name", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadReservedNameCommand, "", NULL }, + { "skill_discovery_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand, "", NULL }, + { "skill_extra_item_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand, "", NULL }, + { "skill_fishing_base_level", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL }, + { "skinning_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL }, + { "spell_affect", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL }, + { "spell_chain", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, + { "spell_elixir", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, + { "spell_learn_spell", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, + { "spell_pet_auras", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, + { "spell_proc_event", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, + { "spell_script_target", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, + { "spell_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL }, + { "spell_target_position", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, + { "spell_threats", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL }, + { "locales_creature", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL }, + { "locales_gameobject", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL }, + { "locales_item", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL }, + { "locales_npc_text", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL }, + { "locales_page_text", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL }, + { "locales_quest", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL }, + + { "", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand honorCommandTable[] = + { + { "add", SEC_GAMEMASTER, &ChatHandler::HandleAddHonorCommand, "", NULL }, + { "addkill", SEC_GAMEMASTER, &ChatHandler::HandleHonorAddKillCommand, "", NULL }, + { "update", SEC_GAMEMASTER, &ChatHandler::HandleUpdateHonorFieldsCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand guildCommandTable[] = + { + { "create", SEC_GAMEMASTER, &ChatHandler::HandleGuildCreateCommand, "", NULL }, + { "delete", SEC_GAMEMASTER, &ChatHandler::HandleGuildDeleteCommand, "", NULL }, + { "invite", SEC_GAMEMASTER, &ChatHandler::HandleGuildInviteCommand, "", NULL }, + { "uninvite", SEC_GAMEMASTER, &ChatHandler::HandleGuildUninviteCommand, "", NULL }, + { "rank", SEC_GAMEMASTER, &ChatHandler::HandleGuildRankCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand lookupPlayerCommandTable[] = + { + { "ip", SEC_GAMEMASTER, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL }, + { "account", SEC_GAMEMASTER, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL }, + { "email", SEC_GAMEMASTER, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand lookupCommandTable[] = + { + { "area", SEC_MODERATOR, &ChatHandler::HandleLookupAreaCommand, "", NULL }, + { "creature", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupCreatureCommand, "", NULL }, + { "event", SEC_GAMEMASTER, &ChatHandler::HandleLookupEventCommand, "", NULL }, + { "faction", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupFactionCommand, "", NULL }, + { "item", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupItemCommand, "", NULL }, + { "itemset", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupItemSetCommand, "", NULL }, + { "object", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupObjectCommand, "", NULL }, + { "quest", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupQuestCommand, "", NULL }, + { "player", SEC_GAMEMASTER, NULL, "", lookupPlayerCommandTable }, + { "skill", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupSkillCommand, "", NULL }, + { "spell", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupSpellCommand, "", NULL }, + { "tele", SEC_MODERATOR, &ChatHandler::HandleLookupTeleCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand resetCommandTable[] = + { + { "honor", SEC_ADMINISTRATOR, &ChatHandler::HandleResetHonorCommand, "", NULL }, + { "level", SEC_ADMINISTRATOR, &ChatHandler::HandleResetLevelCommand, "", NULL }, + { "spells", SEC_ADMINISTRATOR, &ChatHandler::HandleResetSpellsCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, &ChatHandler::HandleResetStatsCommand, "", NULL }, + { "talents", SEC_ADMINISTRATOR, &ChatHandler::HandleResetTalentsCommand, "", NULL }, + { "all", SEC_ADMINISTRATOR, &ChatHandler::HandleResetAllCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand castCommandTable[] = + { + { "back", SEC_ADMINISTRATOR, &ChatHandler::HandleCastBackCommand, "", NULL }, + { "dist", SEC_ADMINISTRATOR, &ChatHandler::HandleCastDistCommand, "", NULL }, + { "self", SEC_ADMINISTRATOR, &ChatHandler::HandleCastSelfCommand, "", NULL }, + { "target", SEC_ADMINISTRATOR, &ChatHandler::HandleCastTargetCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, &ChatHandler::HandleCastCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand pdumpCommandTable[] = + { + { "load", SEC_ADMINISTRATOR, &ChatHandler::HandleLoadPDumpCommand, "", NULL }, + { "write", SEC_ADMINISTRATOR, &ChatHandler::HandleWritePDumpCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand listCommandTable[] = + { + { "creature", SEC_ADMINISTRATOR, &ChatHandler::HandleListCreatureCommand, "", NULL }, + { "item", SEC_ADMINISTRATOR, &ChatHandler::HandleListItemCommand, "", NULL }, + { "object", SEC_ADMINISTRATOR, &ChatHandler::HandleListObjectCommand, "", NULL }, + { "auras", SEC_ADMINISTRATOR, &ChatHandler::HandleListAurasCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand teleCommandTable[] = + { + { "add", SEC_ADMINISTRATOR, &ChatHandler::HandleAddTeleCommand, "", NULL }, + { "del", SEC_ADMINISTRATOR, &ChatHandler::HandleDelTeleCommand, "", NULL }, + { "name", SEC_MODERATOR, &ChatHandler::HandleNameTeleCommand, "", NULL }, + { "group", SEC_MODERATOR, &ChatHandler::HandleGroupTeleCommand, "", NULL }, + { "", SEC_MODERATOR, &ChatHandler::HandleTeleCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand npcCommandTable[] = + { + { "say", SEC_MODERATOR, &ChatHandler::HandleSayCommand, "", NULL }, + { "whisper", SEC_MODERATOR, &ChatHandler::HandleNpcWhisperCommand, "", NULL }, + { "yell", SEC_MODERATOR, &ChatHandler::HandleYellCommand, "", NULL }, + { "textemote", SEC_MODERATOR, &ChatHandler::HandleTextEmoteCommand, "", NULL }, + { "add", SEC_GAMEMASTER, &ChatHandler::HandleAddSpwCommand, "", NULL }, + { "delete", SEC_GAMEMASTER, &ChatHandler::HandleDelCreatureCommand, "", NULL }, + { "spawndist", SEC_GAMEMASTER, &ChatHandler::HandleSpawnDistCommand, "", NULL }, + { "spawntime", SEC_GAMEMASTER, &ChatHandler::HandleSpawnTimeCommand, "", NULL }, + { "factionid", SEC_GAMEMASTER, &ChatHandler::HandleFactionIdCommand, "", NULL }, + { "addmove", SEC_GAMEMASTER, &ChatHandler::HandleAddMoveCommand, "", NULL }, + { "setmovetype", SEC_GAMEMASTER, &ChatHandler::HandleSetMoveTypeCommand, "", NULL }, + { "move", SEC_GAMEMASTER, &ChatHandler::HandleMoveCreatureCommand, "", NULL }, + { "changelevel", SEC_GAMEMASTER, &ChatHandler::HandleChangeLevelCommand, "", NULL }, + { "setmodel", SEC_GAMEMASTER, &ChatHandler::HandleSetModelCommand, "", NULL }, + { "additem", SEC_GAMEMASTER, &ChatHandler::HandleAddVendorItemCommand, "", NULL }, + { "delitem", SEC_GAMEMASTER, &ChatHandler::HandleDelVendorItemCommand, "", NULL }, + { "flag", SEC_GAMEMASTER, &ChatHandler::HandleNPCFlagCommand, "", NULL }, + { "changeentry", SEC_ADMINISTRATOR, &ChatHandler::HandleChangeEntryCommand, "", NULL }, + { "info", SEC_ADMINISTRATOR, &ChatHandler::HandleNpcInfoCommand, "", NULL }, + { "playemote", SEC_ADMINISTRATOR, &ChatHandler::HandlePlayEmoteCommand, "", NULL }, + + //{ TODO: fix or remove this commands + { "name", SEC_GAMEMASTER, &ChatHandler::HandleNameCommand, "", NULL }, + { "subname", SEC_GAMEMASTER, &ChatHandler::HandleSubNameCommand, "", NULL }, + { "addweapon", SEC_ADMINISTRATOR, &ChatHandler::HandleAddWeaponCommand, "", NULL }, + //} + + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand goCommandTable[] = + { + { "grid", SEC_MODERATOR, &ChatHandler::HandleGoGridCommand, "", NULL }, + { "creature", SEC_GAMEMASTER, &ChatHandler::HandleGoCreatureCommand, "", NULL }, + { "object", SEC_GAMEMASTER, &ChatHandler::HandleGoObjectCommand, "", NULL }, + { "trigger", SEC_GAMEMASTER, &ChatHandler::HandleGoTriggerCommand, "", NULL }, + { "graveyard", SEC_GAMEMASTER, &ChatHandler::HandleGoGraveyardCommand, "", NULL }, + { "zonexy", SEC_MODERATOR, &ChatHandler::HandleGoZoneXYCommand, "", NULL }, + { "xy", SEC_MODERATOR, &ChatHandler::HandleGoXYCommand, "", NULL }, + { "xyz", SEC_MODERATOR, &ChatHandler::HandleGoXYZCommand, "", NULL }, + { "", SEC_MODERATOR, &ChatHandler::HandleGoXYZCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand gobjectCommandTable[] = + { + { "add", SEC_GAMEMASTER, &ChatHandler::HandleGameObjectCommand, "", NULL }, + { "delete", SEC_GAMEMASTER, &ChatHandler::HandleDelObjectCommand, "", NULL }, + { "target", SEC_GAMEMASTER, &ChatHandler::HandleTargetObjectCommand, "", NULL }, + { "turn", SEC_GAMEMASTER, &ChatHandler::HandleTurnObjectCommand, "", NULL }, + { "move", SEC_GAMEMASTER, &ChatHandler::HandleMoveObjectCommand, "", NULL }, + { "near", SEC_ADMINISTRATOR, &ChatHandler::HandleNearObjectCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand questCommandTable[] = + { + { "add", SEC_ADMINISTRATOR, &ChatHandler::HandleAddQuest, "", NULL }, + { "complete", SEC_ADMINISTRATOR, &ChatHandler::HandleCompleteQuest, "", NULL }, + { "remove", SEC_ADMINISTRATOR, &ChatHandler::HandleRemoveQuest, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand gmCommandTable[] = + { + { "chat", SEC_MODERATOR, &ChatHandler::HandleGMChatCommand, "", NULL }, + { "list", SEC_PLAYER, &ChatHandler::HandleGMListCommand, "", NULL }, + { "visible", SEC_MODERATOR, &ChatHandler::HandleVisibleCommand, "", NULL }, + { "fly", SEC_ADMINISTRATOR, &ChatHandler::HandleFlyModeCommand, "", NULL }, + { "", SEC_MODERATOR, &ChatHandler::HandleGMmodeCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand instanceCommandTable[] = + { + { "listbinds", SEC_MODERATOR, &ChatHandler::HandleInstanceListBindsCommand, "", NULL }, + { "unbind", SEC_MODERATOR, &ChatHandler::HandleInstanceUnbindCommand, "", NULL }, + { "stats", SEC_MODERATOR, &ChatHandler::HandleInstanceStatsCommand, "", NULL }, + { "savedata", SEC_MODERATOR, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL }, + { NULL, 0, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "gm", SEC_MODERATOR, NULL, "", gmCommandTable }, + { "npc", SEC_MODERATOR, NULL, "", npcCommandTable }, + { "go", SEC_MODERATOR, NULL, "", goCommandTable }, + { "learn", SEC_MODERATOR, NULL, "", learnCommandTable }, + { "modify", SEC_MODERATOR, NULL, "", modifyCommandTable }, + { "debug", SEC_MODERATOR, NULL, "", debugCommandTable }, + { "tele", SEC_MODERATOR, NULL, "", teleCommandTable }, + { "event", SEC_GAMEMASTER, NULL, "", eventCommandTable }, + { "gobject", SEC_GAMEMASTER, NULL, "", gobjectCommandTable }, + { "honor", SEC_GAMEMASTER, NULL, "", honorCommandTable }, + { "wp", SEC_GAMEMASTER, NULL, "", wpCommandTable }, + { "quest", SEC_ADMINISTRATOR, NULL, "", questCommandTable }, + { "reload", SEC_ADMINISTRATOR, NULL, "", reloadCommandTable }, + { "list", SEC_ADMINISTRATOR, NULL, "", listCommandTable }, + { "lookup", SEC_ADMINISTRATOR, NULL, "", lookupCommandTable }, + { "pdump", SEC_ADMINISTRATOR, NULL, "", pdumpCommandTable }, + { "guild", SEC_ADMINISTRATOR, NULL, "", guildCommandTable }, + { "cast", SEC_ADMINISTRATOR, NULL, "", castCommandTable }, + { "reset", SEC_ADMINISTRATOR, NULL, "", resetCommandTable }, + { "instance", SEC_ADMINISTRATOR, NULL, "", instanceCommandTable }, + { "server", SEC_ADMINISTRATOR, NULL, "", serverCommandTable }, + + { "aura", SEC_ADMINISTRATOR, &ChatHandler::HandleAuraCommand, "", NULL }, + { "unaura", SEC_ADMINISTRATOR, &ChatHandler::HandleUnAuraCommand, "", NULL }, + { "acct", SEC_PLAYER, &ChatHandler::HandleAcctCommand, "", NULL }, + { "announce", SEC_MODERATOR, &ChatHandler::HandleAnnounceCommand, "", NULL }, + { "notify", SEC_MODERATOR, &ChatHandler::HandleNotifyCommand, "", NULL }, + { "goname", SEC_MODERATOR, &ChatHandler::HandleGonameCommand, "", NULL }, + { "namego", SEC_MODERATOR, &ChatHandler::HandleNamegoCommand, "", NULL }, + { "groupgo", SEC_MODERATOR, &ChatHandler::HandleGroupgoCommand, "", NULL }, + { "commands", SEC_PLAYER, &ChatHandler::HandleCommandsCommand, "", NULL }, + { "demorph", SEC_GAMEMASTER, &ChatHandler::HandleDeMorphCommand, "", NULL }, + { "die", SEC_ADMINISTRATOR, &ChatHandler::HandleDieCommand, "", NULL }, + { "revive", SEC_ADMINISTRATOR, &ChatHandler::HandleReviveCommand, "", NULL }, + { "dismount", SEC_PLAYER, &ChatHandler::HandleDismountCommand, "", NULL }, + { "gps", SEC_MODERATOR, &ChatHandler::HandleGPSCommand, "", NULL }, + { "guid", SEC_GAMEMASTER, &ChatHandler::HandleGUIDCommand, "", NULL }, + { "help", SEC_PLAYER, &ChatHandler::HandleHelpCommand, "", NULL }, + { "itemmove", SEC_GAMEMASTER, &ChatHandler::HandleItemMoveCommand, "", NULL }, + { "cooldown", SEC_ADMINISTRATOR, &ChatHandler::HandleCooldownCommand, "", NULL }, + { "unlearn", SEC_ADMINISTRATOR, &ChatHandler::HandleUnLearnCommand, "", NULL }, + { "distance", SEC_ADMINISTRATOR, &ChatHandler::HandleGetDistanceCommand, "", NULL }, + { "recall", SEC_MODERATOR, &ChatHandler::HandleRecallCommand, "", NULL }, + { "save", SEC_PLAYER, &ChatHandler::HandleSaveCommand, "", NULL }, + { "saveall", SEC_MODERATOR, &ChatHandler::HandleSaveAllCommand, "", NULL }, + { "kick", SEC_GAMEMASTER, &ChatHandler::HandleKickPlayerCommand, "", NULL }, + { "security", SEC_ADMINISTRATOR, &ChatHandler::HandleSecurityCommand, "", NULL }, + { "ban", SEC_ADMINISTRATOR, &ChatHandler::HandleBanCommand, "", NULL }, + { "unban", SEC_ADMINISTRATOR, &ChatHandler::HandleUnBanCommand, "", NULL }, + { "baninfo", SEC_ADMINISTRATOR, &ChatHandler::HandleBanInfoCommand, "", NULL }, + { "banlist", SEC_ADMINISTRATOR, &ChatHandler::HandleBanListCommand, "", NULL }, + { "plimit", SEC_ADMINISTRATOR, &ChatHandler::HandlePLimitCommand, "", NULL }, + { "start", SEC_PLAYER, &ChatHandler::HandleStartCommand, "", NULL }, + { "taxicheat", SEC_MODERATOR, &ChatHandler::HandleTaxiCheatCommand, "", NULL }, + { "allowmove", SEC_ADMINISTRATOR, &ChatHandler::HandleAllowMovementCommand, "", NULL }, + { "linkgrave", SEC_ADMINISTRATOR, &ChatHandler::HandleLinkGraveCommand, "", NULL }, + { "neargrave", SEC_ADMINISTRATOR, &ChatHandler::HandleNearGraveCommand, "", NULL }, + { "transport", SEC_ADMINISTRATOR, &ChatHandler::HandleSpawnTransportCommand, "", NULL }, + { "explorecheat", SEC_ADMINISTRATOR, &ChatHandler::HandleExploreCheatCommand, "", NULL }, + { "hover", SEC_ADMINISTRATOR, &ChatHandler::HandleHoverCommand, "", NULL }, + { "levelup", SEC_ADMINISTRATOR, &ChatHandler::HandleLevelUpCommand, "", NULL }, + { "showarea", SEC_ADMINISTRATOR, &ChatHandler::HandleShowAreaCommand, "", NULL }, + { "hidearea", SEC_ADMINISTRATOR, &ChatHandler::HandleHideAreaCommand, "", NULL }, + { "additem", SEC_ADMINISTRATOR, &ChatHandler::HandleAddItemCommand, "", NULL }, + { "additemset", SEC_ADMINISTRATOR, &ChatHandler::HandleAddItemSetCommand, "", NULL }, + { "bank", SEC_ADMINISTRATOR, &ChatHandler::HandleBankCommand, "", NULL }, + { "wchange", SEC_ADMINISTRATOR, &ChatHandler::HandleChangeWeather, "", NULL }, + { "ticket", SEC_GAMEMASTER, &ChatHandler::HandleTicketCommand, "", NULL }, + { "delticket", SEC_GAMEMASTER, &ChatHandler::HandleDelTicketCommand, "", NULL }, + { "maxskill", SEC_ADMINISTRATOR, &ChatHandler::HandleMaxSkillCommand, "", NULL }, + { "setskill", SEC_ADMINISTRATOR, &ChatHandler::HandleSetSkillCommand, "", NULL }, + { "whispers", SEC_MODERATOR, &ChatHandler::HandleWhispersCommand, "", NULL }, + { "pinfo", SEC_GAMEMASTER, &ChatHandler::HandlePInfoCommand, "", NULL }, + { "password", SEC_PLAYER, &ChatHandler::HandlePasswordCommand, "", NULL }, + { "lockaccount", SEC_PLAYER, &ChatHandler::HandleLockAccountCommand, "", NULL }, + { "respawn", SEC_ADMINISTRATOR, &ChatHandler::HandleRespawnCommand, "", NULL }, + { "sendmail", SEC_MODERATOR, &ChatHandler::HandleSendMailCommand, "", NULL }, + { "rename", SEC_GAMEMASTER, &ChatHandler::HandleRenameCommand, "", NULL }, + { "loadscripts", SEC_ADMINISTRATOR, &ChatHandler::HandleLoadScriptsCommand, "", NULL }, + { "mute", SEC_GAMEMASTER, &ChatHandler::HandleMuteCommand, "", NULL }, + { "unmute", SEC_GAMEMASTER, &ChatHandler::HandleUnmuteCommand, "", NULL }, + { "movegens", SEC_ADMINISTRATOR, &ChatHandler::HandleMovegensCommand, "", NULL }, + { "cometome", SEC_ADMINISTRATOR, &ChatHandler::HandleComeToMeCommand, "", NULL }, + { "damage", SEC_ADMINISTRATOR, &ChatHandler::HandleDamageCommand, "", NULL }, + { "combatstop", SEC_GAMEMASTER, &ChatHandler::HandleCombatStopCommand, "", NULL }, + + { NULL, 0, NULL, "", NULL } + }; + + if(load_command_table) + { + load_command_table = false; + + QueryResult *result = WorldDatabase.Query("SELECT name,security,help FROM command"); + if (result) + { + do + { + Field *fields = result->Fetch(); + std::string name = fields[0].GetCppString(); + for(uint32 i = 0; commandTable[i].Name != NULL; i++) + { + if (name == commandTable[i].Name) + { + commandTable[i].SecurityLevel = (uint16)fields[1].GetUInt16(); + commandTable[i].Help = fields[2].GetCppString(); + } + if(commandTable[i].ChildCommands != NULL) + { + ChatCommand *ptable = commandTable[i].ChildCommands; + for(uint32 j = 0; ptable[j].Name != NULL; j++) + { + // first case for "" named subcommand + if (ptable[j].Name[0]=='\0' && name == commandTable[i].Name || + name == fmtstring("%s %s", commandTable[i].Name, ptable[j].Name) ) + { + ptable[j].SecurityLevel = (uint16)fields[1].GetUInt16(); + ptable[j].Help = fields[2].GetCppString(); + } + } + } + } + } while(result->NextRow()); + delete result; + } + } + + return commandTable; +} + +const char *ChatHandler::GetMangosString(int32 entry) +{ + return m_session->GetMangosString(entry); +} + +bool ChatHandler::hasStringAbbr(const char* name, const char* part) +{ + // non "" command + if( *name ) + { + // "" part from non-"" command + if( !*part ) + return false; + + for(;;) + { + if( !*part ) + return true; + else if( !*name ) + return false; + else if( tolower( *name ) != tolower( *part ) ) + return false; + ++name; ++part; + } + } + // allow with any for "" + + return true; +} + +void ChatHandler::SendSysMessage(const char *str) +{ + WorldPacket data; + + // need copy to prevent corruption by strtok call in LineFromMessage original string + char* buf = strdup(str); + char* pos = buf; + + while(char* line = LineFromMessage(pos)) + { + FillSystemMessageData(&data, line); + m_session->SendPacket(&data); + } + + free(buf); +} + +void ChatHandler::SendGlobalSysMessage(const char *str) +{ + WorldPacket data; + + // need copy to prevent corruption by strtok call in LineFromMessage original string + char* buf = strdup(str); + char* pos = buf; + + while(char* line = LineFromMessage(pos)) + { + FillSystemMessageData(&data, line); + sWorld.SendGlobalMessage(&data); + } + + free(buf); +} + +void ChatHandler::SendSysMessage(int32 entry) +{ + SendSysMessage(GetMangosString(entry)); +} + +void ChatHandler::PSendSysMessage(int32 entry, ...) +{ + const char *format = GetMangosString(entry); + va_list ap; + char str [1024]; + va_start(ap, entry); + vsnprintf(str,1024,format, ap ); + va_end(ap); + SendSysMessage(str); +} + +void ChatHandler::PSendSysMessage(const char *format, ...) +{ + va_list ap; + char str [1024]; + va_start(ap, format); + vsnprintf(str,1024,format, ap ); + va_end(ap); + SendSysMessage(str); +} + +bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcmd) +{ + char const* oldtext = text; + std::string cmd = ""; + + while (*text != ' ' && *text != '\0') + { + cmd += *text; + ++text; + } + + while (*text == ' ') ++text; + + for(uint32 i = 0; table[i].Name != NULL; i++) + { + if( !hasStringAbbr(table[i].Name, cmd.c_str()) ) + continue; + + // select subcommand from child commands list + if(table[i].ChildCommands != NULL) + { + if(!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd)) + { + if(text && text[0] != '\0') + SendSysMessage(LANG_NO_SUBCMD); + else + SendSysMessage(LANG_CMD_SYNTAX); + + ShowHelpForCommand(table[i].ChildCommands,text); + } + + return true; + } + + // check security level only for simple command (without child commands) + if(m_session->GetSecurity() < table[i].SecurityLevel) + continue; + + SetSentErrorMessage(false); + // table[i].Name == "" is special case: send original command to handler + if((this->*(table[i].Handler))(strlen(table[i].Name)!=0 ? text : oldtext)) + { + if(table[i].SecurityLevel > SEC_PLAYER) + { + Player* p = m_session->GetPlayer(); + uint64 sel_guid = p->GetSelection(); + sLog.outCommand("Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]", + fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(), + GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid)); + } + } + // some commands have custom error messages. Don't send the default one in these cases. + else if(!sentErrorMessage) + { + if(!table[i].Help.empty()) + SendSysMessage(table[i].Help.c_str()); + else + SendSysMessage(LANG_CMD_SYNTAX); + } + + return true; + } + + return false; +} + +int ChatHandler::ParseCommands(const char* text) +{ + ASSERT(text); + ASSERT(*text); + + //if(m_session->GetSecurity() == 0) + // return 0; + + if(text[0] != '!' && text[0] != '.') + return 0; + + // ignore single . and ! in line + if(strlen(text) < 2) + return 0; + + // ignore messages staring from many dots. + if(text[0] == '.' && text[1] == '.' || text[0] == '!' && text[1] == '!') + return 0; + + ++text; + + std::string fullcmd = text; // original `text` can't be used. It content destroyed in command code processing. + + if(!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) + SendSysMessage(LANG_NO_CMD); + + return 1; +} + +bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd) +{ + std::string list; + for(uint32 i = 0; table[i].Name != NULL; ++i) + { + if(m_session->GetSecurity() < table[i].SecurityLevel) + continue; + + if( !hasStringAbbr(table[i].Name, subcmd) ) + continue; + + (list += "\n ") += table[i].Name; + } + + if(list.empty()) + return false; + + if(table==getCommandTable()) + { + SendSysMessage(LANG_AVIABLE_CMD); + PSendSysMessage("%s",list.c_str()); + } + else + PSendSysMessage(LANG_SUBCMDS_LIST,cmd,list.c_str()); + + return true; +} + +bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd) +{ + if(*cmd) + { + for(uint32 i = 0; table[i].Name != NULL; ++i) + { + if(m_session->GetSecurity() < table[i].SecurityLevel) + continue; + + if( !hasStringAbbr(table[i].Name, cmd) ) + continue; + + // have subcommand + char const* subcmd = (*cmd) ? strtok(NULL, " ") : ""; + + if(table[i].ChildCommands && subcmd && *subcmd) + { + if(ShowHelpForCommand(table[i].ChildCommands, subcmd)) + return true; + } + + if(!table[i].Help.empty()) + SendSysMessage(table[i].Help.c_str()); + + if(table[i].ChildCommands) + if(ShowHelpForSubCommands(table[i].ChildCommands,table[i].Name,subcmd ? subcmd : "")) + return true; + + return !table[i].Help.empty(); + } + } + else + { + for(uint32 i = 0; table[i].Name != NULL; ++i) + { + if(m_session->GetSecurity() < table[i].SecurityLevel) + continue; + + if(strlen(table[i].Name)) + continue; + + if(!table[i].Help.empty()) + SendSysMessage(table[i].Help.c_str()); + + if(table[i].ChildCommands) + if(ShowHelpForSubCommands(table[i].ChildCommands,"","")) + return true; + + return !table[i].Help.empty(); + } + } + + return ShowHelpForSubCommands(table,"",cmd); +} + +//Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored) +void ChatHandler::FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker) +{ + uint32 messageLength = (message ? strlen(message) : 0) + 1; + + data->Initialize(SMSG_MESSAGECHAT, 100); // guess size + *data << uint8(type); + if ((type != CHAT_MSG_CHANNEL && type != CHAT_MSG_WHISPER) || language == LANG_ADDON) + *data << uint32(language); + else + *data << uint32(LANG_UNIVERSAL); + + switch(type) + { + case CHAT_MSG_SAY: + case CHAT_MSG_PARTY: + case CHAT_MSG_RAID: + case CHAT_MSG_GUILD: + case CHAT_MSG_OFFICER: + case CHAT_MSG_YELL: + case CHAT_MSG_WHISPER: + case CHAT_MSG_CHANNEL: + case CHAT_MSG_RAID_LEADER: + case CHAT_MSG_RAID_WARNING: + case CHAT_MSG_BG_SYSTEM_NEUTRAL: + case CHAT_MSG_BG_SYSTEM_ALLIANCE: + case CHAT_MSG_BG_SYSTEM_HORDE: + case CHAT_MSG_BATTLEGROUND: + case CHAT_MSG_BATTLEGROUND_LEADER: + target_guid = session ? session->GetPlayer()->GetGUID() : 0; + break; + case CHAT_MSG_MONSTER_SAY: + case CHAT_MSG_MONSTER_PARTY: + case CHAT_MSG_MONSTER_YELL: + case CHAT_MSG_MONSTER_WHISPER: + case CHAT_MSG_MONSTER_EMOTE: + case CHAT_MSG_RAID_BOSS_WHISPER: + case CHAT_MSG_RAID_BOSS_EMOTE: + { + *data << uint64(speaker->GetGUID()); + *data << uint32(0); // 2.1.0 + *data << uint32(strlen(speaker->GetName()) + 1); + *data << speaker->GetName(); + uint64 listener_guid = 0; + *data << uint64(listener_guid); + if(listener_guid && !IS_PLAYER_GUID(listener_guid)) + { + *data << uint32(1); // string listener_name_length + *data << uint8(0); // string listener_name + } + *data << uint32(messageLength); + *data << message; + *data << uint8(0); + return; + } + default: + if (type != CHAT_MSG_REPLY && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) + target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid + break; + } + + *data << uint64(target_guid); // there 0 for BG messages + *data << uint32(0); // can be chat msg group or something + + if (type == CHAT_MSG_CHANNEL) + { + ASSERT(channelName); + *data << channelName; + } + + *data << uint64(target_guid); + *data << uint32(messageLength); + *data << message; + if(session != 0 && type != CHAT_MSG_REPLY && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) + *data << uint8(session->GetPlayer()->chatTag()); + else + *data << uint8(0); +} + +Player * ChatHandler::getSelectedPlayer() +{ + uint64 guid = m_session->GetPlayer()->GetSelection(); + + if (guid == 0) + return m_session->GetPlayer(); + + return objmgr.GetPlayer(guid); +} + +Unit* ChatHandler::getSelectedUnit() +{ + uint64 guid = m_session->GetPlayer()->GetSelection(); + + if (guid == 0) + return m_session->GetPlayer(); + + return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid); +} + +Creature* ChatHandler::getSelectedCreature() +{ + return ObjectAccessor::GetCreatureOrPet(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection()); +} + +char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1) +{ + // skip empty + if(!text) + return NULL; + + // skip speces + while(*text==' '||*text=='\t'||*text=='\b') + ++text; + + if(!*text) + return NULL; + + // return non link case + if(text[0]!='|') + return strtok(text, " "); + + // [name] Shift-click form |color|linkType:key|h[name]|h|r + // or + // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r + + char* check = strtok(text, "|"); // skip color + if(!check) + return NULL; // end of data + + char* cLinkType = strtok(NULL, ":"); // linktype + if(!cLinkType) + return NULL; // end of data + + if(strcmp(cLinkType,linkType) != 0) + { + strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function + SendSysMessage(LANG_WRONG_LINK_TYPE); + return NULL; + } + + char* cKeys = strtok(NULL, "|"); // extract keys and values + char* cKeysTail = strtok(NULL, ""); + + char* cKey = strtok(cKeys, ":|"); // extract key + if(something1) + *something1 = strtok(NULL, ":|"); // extract something + + strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces + strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function + return cKey; +} + +char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1) +{ + // skip empty + if(!text) + return NULL; + + // skip speces + while(*text==' '||*text=='\t'||*text=='\b') + ++text; + + if(!*text) + return NULL; + + // return non link case + if(text[0]!='|') + return strtok(text, " "); + + // [name] Shift-click form |color|linkType:key|h[name]|h|r + // or + // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r + + char* check = strtok(text, "|"); // skip color + if(!check) + return NULL; // end of data + + char* cLinkType = strtok(NULL, ":"); // linktype + if(!cLinkType) + return NULL; // end of data + + for(int i = 0; linkTypes[i]; ++i) + { + if(strcmp(cLinkType,linkTypes[i]) == 0) + { + char* cKeys = strtok(NULL, "|"); // extract keys and values + char* cKeysTail = strtok(NULL, ""); + + char* cKey = strtok(cKeys, ":|"); // extract key + if(something1) + *something1 = strtok(NULL, ":|"); // extract something + + strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces + strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function + if(found_idx) + *found_idx = i; + return cKey; + } + } + + strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function + SendSysMessage(LANG_WRONG_LINK_TYPE); + return NULL; +} + +char const *fmtstring( char const *format, ... ) +{ + va_list argptr; + #define MAX_FMT_STRING 32000 + static char temp_buffer[MAX_FMT_STRING]; + static char string[MAX_FMT_STRING]; + static int index = 0; + char *buf; + int len; + + va_start(argptr, format); + vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr); + va_end(argptr); + + len = strlen(temp_buffer); + + if( len >= MAX_FMT_STRING ) + return "ERROR"; + + if (len + index >= MAX_FMT_STRING-1) + { + index = 0; + } + + buf = &string[index]; + memcpy( buf, temp_buffer, len+1 ); + + index += len + 1; + + return buf; +} + +GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry) +{ + Player* pl = m_session->GetPlayer(); + + GameObject* obj = ObjectAccessor::GetGameObject(*pl, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT)); + + if(!obj && objmgr.GetGOData(lowguid)) // guid is DB guid of object + { + // search near player then + CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid); + MaNGOS::GameObjectSearcher checker(obj,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(pl->GetMapId(), pl)); + } + + return obj; +} + +static char const* const spellTalentKeys[] = { + "Hspell", + "Htalent", + 0 +}; + +uint32 ChatHandler::extractSpellIdFromLink(char* text) +{ + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + // number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r + int type = 0; + char* rankS = NULL; + char* idS = extractKeyFromLink(text,spellTalentKeys,&type,&rankS); + if(!idS) + return 0; + + uint32 id = (uint32)atol(idS); + + // spell + if(type==0) + return id; + + // talent + TalentEntry const* talentEntry = sTalentStore.LookupEntry(id); + if(!talentEntry) + return 0; + + int32 rank = rankS ? (uint32)atol(rankS) : 0; + if(rank >= 5) + return 0; + + if(rank < 0) + rank = 0; + + return talentEntry->RankID[rank]; +} + +GameTele const* ChatHandler::extractGameTeleFromLink(char* text) +{ + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r + char* cId = extractKeyFromLink(text,"Htele"); + if(!cId) + return false; + + // id case (explicit or from shift link) + if(cId[0] >= '0' || cId[0] >= '9') + if(uint32 id = atoi(cId)) + return objmgr.GetGameTele(id); + + return objmgr.GetGameTele(cId); +} diff --git a/src/game/Chat.h b/src/game/Chat.h new file mode 100644 index 000000000..a6da30a3d --- /dev/null +++ b/src/game/Chat.h @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_CHAT_H +#define MANGOSSERVER_CHAT_H + +#include "SharedDefines.h" + +class ChatHandler; +class WorldSession; +class Creature; +class Player; +class Unit; +struct GameTele; + +class ChatCommand +{ + public: + const char * Name; + uint32 SecurityLevel; // function pointer required correct align (use uint32) + bool (ChatHandler::*Handler)(const char* args); + std::string Help; + ChatCommand * ChildCommands; +}; + +class ChatHandler +{ + public: + explicit ChatHandler(WorldSession* session) : m_session(session) {} + explicit ChatHandler(Player* player) : m_session(player->GetSession()) {} + ~ChatHandler() {} + + static void FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker); + + void FillMessageData( WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message) + { + FillMessageData( data, m_session, type, language, NULL, target_guid, message, NULL); + } + + void FillSystemMessageData( WorldPacket *data, const char* message ) + { + FillMessageData( data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message ); + } + + static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; } + + const char *GetMangosString(int32 entry); + + void SendSysMessage( const char *str); + void SendSysMessage( int32 entry); + void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3); + void PSendSysMessage( int32 entry, ... ); + + int ParseCommands(const char* text); + + protected: + bool hasStringAbbr(const char* name, const char* part); + void SendGlobalSysMessage(const char *str); + + bool ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcommand); + bool ShowHelpForCommand(ChatCommand *table, const char* cmd); + bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd); + + ChatCommand* getCommandTable(); + + bool HandleHelpCommand(const char* args); + bool HandleCommandsCommand(const char* args); + bool HandleAcctCommand(const char* args); + bool HandleStartCommand(const char* args); + bool HandleInfoCommand(const char* args); + bool HandleDismountCommand(const char* args); + bool HandleSaveCommand(const char* args); + bool HandleGMListCommand(const char* args); + + bool HandleNamegoCommand(const char* args); + bool HandleGonameCommand(const char* args); + bool HandleGroupgoCommand(const char* args); + bool HandleRecallCommand(const char* args); + bool HandleAnnounceCommand(const char* args); + bool HandleNotifyCommand(const char* args); + bool HandleGMmodeCommand(const char* args); + bool HandleGMChatCommand(const char* args); + bool HandleVisibleCommand(const char* args); + bool HandleGPSCommand(const char* args); + bool HandleTaxiCheatCommand(const char* args); + bool HandleWhispersCommand(const char* args); + bool HandleSayCommand(const char* args); + bool HandleNpcWhisperCommand(const char* args); + bool HandleYellCommand(const char* args); + bool HandlePlayEmoteCommand(const char* args); + bool HandleSendMailCommand(const char* args); + bool HandleNameTeleCommand(const char* args); + bool HandleGroupTeleCommand(const char* args); + bool HandleDrunkCommand(const char* args); + + bool HandleEventActiveListCommand(const char* args); + bool HandleEventStartCommand(const char* args); + bool HandleEventStopCommand(const char* args); + bool HandleEventInfoCommand(const char* args); + + bool HandleModifyKnownTitlesCommand(const char* args); + bool HandleModifyHPCommand(const char* args); + bool HandleModifyManaCommand(const char* args); + bool HandleModifyRageCommand(const char* args); + bool HandleModifyEnergyCommand(const char* args); + bool HandleModifyMoneyCommand(const char* args); + bool HandleModifyASpeedCommand(const char* args); + bool HandleModifySpeedCommand(const char* args); + bool HandleModifyBWalkCommand(const char* args); + bool HandleModifyFlyCommand(const char* args); + bool HandleModifySwimCommand(const char* args); + bool HandleModifyScaleCommand(const char* args); + bool HandleModifyMountCommand(const char* args); + bool HandleModifyBitCommand(const char* args); + bool HandleModifyFactionCommand(const char* args); + bool HandleModifySpellCommand(const char* args); + bool HandleModifyTalentCommand (const char* args); + bool HandleModifyHonorCommand (const char* args); + bool HandleModifyRepCommand(const char* args); + bool HandleModifyArenaCommand(const char* args); + + bool HandleReloadCommand(const char* args); + bool HandleReloadAllCommand(const char* args); + bool HandleReloadAllAreaCommand(const char* args); + bool HandleReloadAllItemCommand(const char* args); + bool HandleReloadAllLootCommand(const char* args); + bool HandleReloadAllNpcCommand(const char* args); + bool HandleReloadAllQuestCommand(const char* args); + bool HandleReloadAllScriptsCommand(const char* args); + bool HandleReloadAllSpellCommand(const char* args); + bool HandleReloadAllLocalesCommand(const char* args); + + bool HandleReloadConfigCommand(const char* args); + + bool HandleReloadAreaTriggerTavernCommand(const char* args); + bool HandleReloadAreaTriggerTeleportCommand(const char* args); + bool HandleReloadEventScriptsCommand(const char* args); + bool HandleReloadCommandCommand(const char* args); + bool HandleReloadCreatureQuestRelationsCommand(const char* args); + bool HandleReloadCreatureQuestInvRelationsCommand(const char* args); + bool HandleReloadGameGraveyardZoneCommand(const char* args); + bool HandleReloadGameObjectScriptsCommand(const char* args); + bool HandleReloadGameTeleCommand(const char* args); + bool HandleReloadGOQuestRelationsCommand(const char* args); + bool HandleReloadGOQuestInvRelationsCommand(const char* args); + bool HandleReloadLootTemplatesCreatureCommand(const char* args); + bool HandleReloadLootTemplatesDisenchantCommand(const char* args); + bool HandleReloadLootTemplatesFishingCommand(const char* args); + bool HandleReloadLootTemplatesGameobjectCommand(const char* args); + bool HandleReloadLootTemplatesItemCommand(const char* args); + bool HandleReloadLootTemplatesPickpocketingCommand(const char* args); + bool HandleReloadLootTemplatesProspectingCommand(const char* args); + bool HandleReloadLootTemplatesReferenceCommand(const char* args); + bool HandleReloadLootTemplatesQuestMailCommand(const char* args); + bool HandleReloadLootTemplatesSkinningCommand(const char* args); + bool HandleReloadMangosStringCommand(const char* args); + bool HandleReloadNpcGossipCommand(const char* args); + bool HandleReloadNpcTrainerCommand(const char* args); + bool HandleReloadNpcVendorCommand(const char* args); + bool HandleReloadQuestAreaTriggersCommand(const char* args); + bool HandleReloadQuestEndScriptsCommand(const char* args); + bool HandleReloadQuestStartScriptsCommand(const char* args); + bool HandleReloadQuestTemplateCommand(const char* args); + bool HandleReloadReservedNameCommand(const char*); + bool HandleReloadSkillDiscoveryTemplateCommand(const char* args); + bool HandleReloadSkillExtraItemTemplateCommand(const char* args); + bool HandleReloadSkillFishingBaseLevelCommand(const char* args); + bool HandleReloadSpellAffectCommand(const char* args); + bool HandleReloadSpellChainCommand(const char* args); + bool HandleReloadSpellElixirCommand(const char* args); + bool HandleReloadSpellLearnSpellCommand(const char* args); + bool HandleReloadSpellProcEventCommand(const char* args); + bool HandleReloadSpellScriptTargetCommand(const char* args); + bool HandleReloadSpellScriptsCommand(const char* args); + bool HandleReloadSpellTargetPositionCommand(const char* args); + bool HandleReloadSpellThreatsCommand(const char* args); + bool HandleReloadSpellPetAurasCommand(const char* args); + bool HandleReloadPageTextsCommand(const char* args); + bool HandleReloadItemEnchantementsCommand(const char* args); + bool HandleReloadLocalesCreatureCommand(const char* args); + bool HandleReloadLocalesGameobjectCommand(const char* args); + bool HandleReloadLocalesItemCommand(const char* args); + bool HandleReloadLocalesNpcTextCommand(const char* args); + bool HandleReloadLocalesPageTextCommand(const char* args); + bool HandleReloadLocalesQuestCommand(const char* args); + + bool HandleInstanceListBindsCommand(const char* args); + bool HandleInstanceUnbindCommand(const char* args); + bool HandleInstanceStatsCommand(const char* args); + bool HandleInstanceSaveDataCommand(const char * args); + + bool HandleAddHonorCommand(const char* args); + bool HandleHonorAddKillCommand(const char* args); + bool HandleUpdateHonorFieldsCommand(const char* args); + + bool HandleLoadScriptsCommand(const char* args); + bool HandleSendQuestPartyMsgCommand(const char* args); + bool HandleSendQuestInvalidMsgCommand(const char* args); + + bool HandleDebugInArcCommand(const char* args); + bool HandleDebugSpellFailCommand(const char* args); + + bool HandleGUIDCommand(const char* args); + bool HandleNameCommand(const char* args); + bool HandleSubNameCommand(const char* args); + bool HandleItemMoveCommand(const char* args); + bool HandleDelCreatureCommand(const char* args); + bool HandleDeMorphCommand(const char* args); + bool HandleAddVendorItemCommand(const char* args); + bool HandleDelVendorItemCommand(const char* args); + bool HandleAddMoveCommand(const char* args); + bool HandleSetMoveTypeCommand(const char* args); + bool HandleChangeLevelCommand(const char* args); + bool HandleSetPoiCommand(const char* args); + bool HandleEquipErrorCommand(const char* args); + bool HandleNPCFlagCommand(const char* args); + bool HandleSetModelCommand(const char* args); + bool HandleFactionIdCommand(const char* args); + bool HandleAddSpwCommand(const char* args); + bool HandleSpawnDistCommand(const char* args); + bool HandleSpawnTimeCommand(const char* args); + bool HandleGoCreatureCommand(const char* args); + bool HandleGoObjectCommand(const char* args); + bool HandleGoTriggerCommand(const char* args); + bool HandleGoGraveyardCommand(const char* args); + bool HandleTargetObjectCommand(const char* args); + bool HandleDelObjectCommand(const char* args); + bool HandleMoveCreatureCommand(const char* args); + bool HandleMoveObjectCommand(const char* args); + bool HandleTurnObjectCommand(const char* args); + bool HandlePInfoCommand(const char* args); + bool HandlePLimitCommand(const char* args); + bool HandleMuteCommand(const char* args); + bool HandleUnmuteCommand(const char* args); + bool HandleMovegensCommand(const char* args); + + bool HandleBanCommand(const char* args); + bool HandleUnBanCommand(const char* args); + bool HandleBanInfoCommand(const char* args); + bool HandleBanListCommand(const char* args); + bool HandleIdleRestartCommand(const char* args); + bool HandleIdleShutDownCommand(const char* args); + bool HandleShutDownCommand(const char* args); + bool HandleRestartCommand(const char* args); + bool HandleSecurityCommand(const char* args); + bool HandleGoXYCommand(const char* args); + bool HandleGoXYZCommand(const char* args); + bool HandleGoZoneXYCommand(const char* args); + bool HandleGoGridCommand(const char* args); + bool HandleAddWeaponCommand(const char* args); + bool HandleAllowMovementCommand(const char* args); + bool HandleGoCommand(const char* args); + + bool HandleLearnCommand(const char* args); + bool HandleLearnAllCommand(const char* args); + bool HandleLearnAllGMCommand(const char* args); + bool HandleLearnAllCraftsCommand(const char* args); + bool HandleLearnAllRecipesCommand(const char* args); + bool HandleLearnAllDefaultCommand(const char* args); + bool HandleLearnAllLangCommand(const char* args); + bool HandleLearnAllMyClassCommand(const char* args); + bool HandleLearnAllMySpellsCommand(const char* args); + bool HandleLearnAllMyTalentsCommand(const char* args); + + bool HandleLookupAreaCommand(const char* args); + bool HandleLookupCreatureCommand(const char* args); + bool HandleLookupEventCommand(const char* args); + bool HandleLookupFactionCommand(const char * args); + bool HandleLookupItemCommand(const char * args); + bool HandleLookupItemSetCommand(const char * args); + bool HandleLookupObjectCommand(const char* args); + bool HandleLookupPlayerIpCommand(const char* args); + bool HandleLookupPlayerAccountCommand(const char* args); + bool HandleLookupPlayerEmailCommand(const char* args); + bool HandleLookupQuestCommand(const char* args); + bool HandleLookupSkillCommand(const char* args); + bool HandleLookupSpellCommand(const char* args); + bool HandleLookupTeleCommand(const char * args); + + bool HandleCooldownCommand(const char* args); + bool HandleUnLearnCommand(const char* args); + bool HandleGetDistanceCommand(const char* args); + bool HandleGameObjectCommand(const char* args); + bool HandleAnimCommand(const char* args); + bool HandlePlaySoundCommand(const char* args); + bool HandleStandStateCommand(const char* args); + bool HandleDieCommand(const char* args); + bool HandleDamageCommand(const char *args); + bool HandleReviveCommand(const char* args); + bool HandleMorphCommand(const char* args); + bool HandleAuraCommand(const char* args); + bool HandleUnAuraCommand(const char* args); + bool HandleLinkGraveCommand(const char* args); + bool HandleNearGraveCommand(const char* args); + bool HandleSpawnTransportCommand(const char* args); + bool HandleExploreCheatCommand(const char* args); + bool HandleTextEmoteCommand(const char* args); + bool HandleNpcInfoCommand(const char* args); + bool HandleHoverCommand(const char* args); + bool HandleLevelUpCommand(const char* args); + bool HandleShowAreaCommand(const char* args); + bool HandleHideAreaCommand(const char* args); + bool HandleAddItemCommand(const char* args); + bool HandleAddItemSetCommand(const char* args); + + bool HandleGuildCreateCommand(const char* args); + bool HandleGuildInviteCommand(const char* args); + bool HandleGuildUninviteCommand(const char* args); + bool HandleGuildRankCommand(const char* args); + bool HandleGuildDeleteCommand(const char* args); + bool HandleUpdate(const char* args); + bool HandleBankCommand(const char* args); + bool HandleChangeWeather(const char* args); + bool HandleKickPlayerCommand(const char * args); + bool HandleTeleCommand(const char * args); + bool HandleAddTeleCommand(const char * args); + bool HandleDelTeleCommand(const char * args); + bool HandleListAurasCommand(const char * args); + + bool HandleResetHonorCommand(const char * args); + bool HandleResetLevelCommand(const char * args); + bool HandleResetSpellsCommand(const char * args); + + bool HandleResetStatsCommand(const char * args); + bool HandleResetTalentsCommand(const char * args); + + bool HandleResetAllCommand(const char * args); + bool HandleTicketCommand(const char* args); + bool HandleDelTicketCommand(const char* args); + bool HandleMaxSkillCommand(const char* args); + bool HandleSetSkillCommand(const char* args); + bool HandleListCreatureCommand(const char* args); + bool HandleListItemCommand(const char* args); + bool HandleListObjectCommand(const char* args); + bool HandleNearObjectCommand(const char* args); + bool HandlePasswordCommand(const char* args); + bool HandleLockAccountCommand(const char* args); + bool HandleRespawnCommand(const char* args); + bool HandleWpAddCommand(const char* args); + bool HandleWpModifyCommand(const char* args); + bool HandleWpShowCommand(const char* args); + bool HandleWpExportCommand(const char* args); + bool HandleWpImportCommand(const char* args); + bool HandleFlyModeCommand(const char* args); + bool HandleSendOpcodeCommand(const char* args); + bool HandleSellErrorCommand(const char* args); + bool HandleBuyErrorCommand(const char* args); + bool HandleUpdateWorldStateCommand(const char* args); + bool HandlePlaySound2Command(const char* args); + bool HandleSendChannelNotifyCommand(const char* args); + bool HandleSendChatMsgCommand(const char* args); + bool HandleRenameCommand(const char * args); + bool HandleLoadPDumpCommand(const char *args); + bool HandleWritePDumpCommand(const char *args); + bool HandleChangeEntryCommand(const char *args); + bool HandleCastCommand(const char *args); + bool HandleCastBackCommand(const char *args); + bool HandleCastDistCommand(const char *args); + bool HandleCastSelfCommand(const char *args); + bool HandleCastTargetCommand(const char *args); + bool HandleComeToMeCommand(const char *args); + bool HandleCombatStopCommand(const char *args); + + //! Development Commands + bool HandleSetValue(const char* args); + bool HandleGetValue(const char* args); + bool HandleSet32Bit(const char* args); + bool HandleMod32Value(const char* args); + bool HandleAddQuest(const char * args); + bool HandleRemoveQuest(const char * args); + bool HandleCompleteQuest(const char * args); + bool HandleSaveAllCommand(const char* args); + bool HandleGetItemState(const char * args); + bool HandleGetLootRecipient(const char * args); + + Player* getSelectedPlayer(); + Creature* getSelectedCreature(); + Unit* getSelectedUnit(); + char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL); + char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL); + uint32 extractSpellIdFromLink(char* text); + GameTele const* extractGameTeleFromLink(char* text); + + GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry); + + WorldSession * m_session; + + // Utility methods for commands + void ShowTicket(uint64 guid, char const* text, char const* time); + uint32 GetTicketIDByNum(uint32 num); + bool LookupPlayerSearchCommand(QueryResult* result, int32 limit); + + void SetSentErrorMessage(bool val){ sentErrorMessage = val;}; + private: + // common global flag + static bool load_command_table; + bool sentErrorMessage; +}; +#endif + +char const *fmtstring( char const *format, ... ); diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp new file mode 100644 index 000000000..a6e05aa64 --- /dev/null +++ b/src/game/ChatHandler.cpp @@ -0,0 +1,583 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Log.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Opcodes.h" +#include "ObjectMgr.h" +#include "Chat.h" +#include "Database/DatabaseEnv.h" +#include "ChannelMgr.h" +#include "Group.h" +#include "Guild.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "ScriptCalls.h" +#include "Player.h" +#include "SpellAuras.h" +#include "Language.h" +#include "Util.h" + +void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+4+1); + + uint32 type; + uint32 lang; + + recv_data >> type; + recv_data >> lang; + + if(type >= MAX_CHAT_MSG_TYPE) + { + sLog.outError("CHAT: Wrong message type received: %u", type); + return; + } + + //sLog.outDebug("CHAT: packet received. type %u, lang %u", type, lang ); + + // prevent talking at unknown language (cheating) + LanguageDesc const* langDesc = GetLanguageDescByID(lang); + if(!langDesc) + { + SendNotification(LANG_UNKNOWN_LANGUAGE); + return; + } + if(langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id)) + { + // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) + Unit::AuraList const& langAuras = _player->GetAurasByType(SPELL_AURA_COMPREHEND_LANGUAGE); + bool foundAura = false; + for(Unit::AuraList::const_iterator i = langAuras.begin();i != langAuras.end(); ++i) + { + if((*i)->GetModifier()->m_miscvalue == lang) + { + foundAura = true; + break; + } + } + if(!foundAura) + { + SendNotification(LANG_NOT_LEARNED_LANGUAGE); + return; + } + } + + if(lang == LANG_ADDON) + { + // Disabled addon channel? + if(!sWorld.getConfig(CONFIG_ADDON_CHANNEL)) + return; + } + // LANG_ADDON should not be changed nor be affected by flood control + else + { + // send in universal language if player in .gmon mode (ignore spell effects) + if (_player->isGameMaster()) + lang = LANG_UNIVERSAL; + else + { + // send in universal language in two side iteration allowed mode + if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT)) + lang = LANG_UNIVERSAL; + else + { + switch(type) + { + case CHAT_MSG_PARTY: + case CHAT_MSG_RAID: + case CHAT_MSG_RAID_LEADER: + case CHAT_MSG_RAID_WARNING: + // allow two side chat at group channel if two side group allowed + if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) + lang = LANG_UNIVERSAL; + break; + case CHAT_MSG_GUILD: + case CHAT_MSG_OFFICER: + // allow two side chat at guild channel if two side guild allowed + if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) + lang = LANG_UNIVERSAL; + break; + } + } + + // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) + Unit::AuraList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE); + if(!ModLangAuras.empty()) + lang = ModLangAuras.front()->GetModifier()->m_miscvalue; + } + + if (!_player->CanSpeak()) + { + std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str()); + return; + } + + if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) + GetPlayer()->UpdateSpeakTime(); + } + + switch(type) + { + case CHAT_MSG_SAY: + case CHAT_MSG_EMOTE: + case CHAT_MSG_YELL: + { + std::string msg = ""; + recv_data >> msg; + + if(msg.empty()) + break; + + if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + break; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + if(type == CHAT_MSG_SAY) + GetPlayer()->Say(msg, lang); + else if(type == CHAT_MSG_EMOTE) + GetPlayer()->TextEmote(msg); + else if(type == CHAT_MSG_YELL) + GetPlayer()->Yell(msg, lang); + } break; + + case CHAT_MSG_WHISPER: + { + std::string to, msg; + recv_data >> to; + CHECK_PACKET_SIZE(recv_data,4+4+(to.size()+1)+1); + recv_data >> msg; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + if(!normalizePlayerName(to)) + { + WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); + data<GetSession()->GetSecurity() : 0; + if(!player || tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers()) + { + WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); + data<GetTeam(); + uint32 sideb = player->GetTeam(); + if( sidea != sideb ) + { + WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); + data<Whisper(msg, lang,player->GetGUID()); + } break; + + case CHAT_MSG_PARTY: + { + std::string msg = ""; + recv_data >> msg; + + if(msg.empty()) + break; + + if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + break; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_PARTY, lang, NULL, 0, msg.c_str(),NULL); + group->BroadcastPacket(&data, group->GetMemberGroup(GetPlayer()->GetGUID())); + } + break; + case CHAT_MSG_GUILD: + { + std::string msg = ""; + recv_data >> msg; + + if(msg.empty()) + break; + + if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + break; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + if (GetPlayer()->GetGuildId()) + { + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if (guild) + guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); + } + + break; + } + case CHAT_MSG_OFFICER: + { + std::string msg = ""; + recv_data >> msg; + + if(msg.empty()) + break; + + if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + break; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + if (GetPlayer()->GetGuildId()) + { + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if (guild) + guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); + } + break; + } + case CHAT_MSG_RAID: + { + std::string msg=""; + recv_data >> msg; + + if(msg.empty()) + break; + + if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + break; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + Group *group = GetPlayer()->GetGroup(); + if(!group || !group->isRaidGroup()) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL); + group->BroadcastPacket(&data); + } break; + case CHAT_MSG_RAID_LEADER: + { + std::string msg=""; + recv_data >> msg; + + if(msg.empty()) + break; + + if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + break; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + Group *group = GetPlayer()->GetGroup(); + if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(),NULL); + group->BroadcastPacket(&data); + } break; + case CHAT_MSG_RAID_WARNING: + { + std::string msg=""; + recv_data >> msg; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + Group *group = GetPlayer()->GetGroup(); + if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID()))) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(),NULL); + group->BroadcastPacket(&data); + } break; + + case CHAT_MSG_BATTLEGROUND: + { + std::string msg=""; + recv_data >> msg; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + Group *group = GetPlayer()->GetGroup(); + if(!group || !group->isRaidGroup()) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(),NULL); + group->BroadcastPacket(&data); + } break; + + case CHAT_MSG_BATTLEGROUND_LEADER: + { + std::string msg=""; + recv_data >> msg; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + Group *group = GetPlayer()->GetGroup(); + if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(),NULL); + group->BroadcastPacket(&data); + } break; + + case CHAT_MSG_CHANNEL: + { + std::string channel = "", msg = ""; + recv_data >> channel; + + // recheck + CHECK_PACKET_SIZE(recv_data,4+4+(channel.size()+1)+1); + + recv_data >> msg; + + // strip invisible characters for non-addon messages + if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if(msg.empty()) + break; + + if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) + { + if(Channel *chn = cMgr->GetChannel(channel,_player)) + chn->Say(_player->GetGUID(),msg.c_str(),lang); + } + } break; + + case CHAT_MSG_AFK: + { + std::string msg; + recv_data >> msg; + + if((msg.empty() || !_player->isAFK()) && !_player->isInCombat() ) + { + if(!_player->isAFK()) + { + if(msg.empty()) + msg = GetMangosString(LANG_PLAYER_AFK_DEFAULT); + _player->afkMsg = msg; + } + _player->ToggleAFK(); + if(_player->isAFK() && _player->isDND()) + _player->ToggleDND(); + } + } break; + + case CHAT_MSG_DND: + { + std::string msg; + recv_data >> msg; + + if(msg.empty() || !_player->isDND()) + { + if(!_player->isDND()) + { + if(msg.empty()) + msg = GetMangosString(LANG_PLAYER_DND_DEFAULT); + _player->dndMsg = msg; + } + _player->ToggleDND(); + if(_player->isDND() && _player->isAFK()) + _player->ToggleAFK(); + } + } break; + + default: + sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang); + break; + } +} + +void WorldSession::HandleEmoteOpcode( WorldPacket & recv_data ) +{ + if(!GetPlayer()->isAlive()) + return; + CHECK_PACKET_SIZE(recv_data,4); + + uint32 emote; + recv_data >> emote; + GetPlayer()->HandleEmoteCommand(emote); +} + +void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data ) +{ + if(!GetPlayer()->isAlive()) + return; + + if (!GetPlayer()->CanSpeak()) + { + std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str()); + return; + } + + CHECK_PACKET_SIZE(recv_data,4+4+8); + + uint32 text_emote, emoteNum; + uint64 guid; + + recv_data >> text_emote; + recv_data >> emoteNum; + recv_data >> guid; + + const char *nam = 0; + uint32 namlen = 1; + + Unit* unit = ObjectAccessor::GetUnit(*_player, guid); + Creature *pCreature = dynamic_cast(unit); + if(unit) + { + nam = unit->GetName(); + namlen = (nam ? strlen(nam) : 0) + 1; + } + + EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote); + if (em) + { + uint32 emote_anim = em->textid; + + WorldPacket data; + + switch(emote_anim) + { + case EMOTE_STATE_SLEEP: + case EMOTE_STATE_SIT: + case EMOTE_STATE_KNEEL: + case EMOTE_ONESHOT_NONE: + break; + default: + GetPlayer()->HandleEmoteCommand(emote_anim); + break; + } + + data.Initialize(SMSG_TEXT_EMOTE, (20+namlen)); + data << GetPlayer()->GetGUID(); + data << (uint32)text_emote; + data << emoteNum; + data << (uint32)namlen; + if( namlen > 1 ) + { + data.append(nam, namlen); + } + else + { + data << (uint8)0x00; + } + + GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true); + + //Send scripted event call + if (pCreature && Script) + Script->ReceiveEmote(GetPlayer(),pCreature,text_emote); + } +} + +void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + + uint64 iguid; + uint8 unk; + //sLog.outDebug("WORLD: Received CMSG_CHAT_IGNORED"); + + recv_data >> iguid; + recv_data >> unk; // probably related to spam reporting + + Player *player = objmgr.GetPlayer(iguid); + if(!player || !player->GetSession()) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(),NULL); + player->GetSession()->SendPacket(&data); +} diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp new file mode 100644 index 000000000..db164ef6b --- /dev/null +++ b/src/game/CombatHandler.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Log.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectAccessor.h" +#include "CreatureAI.h" +#include "ObjectDefines.h" + +void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + DEBUG_LOG( "WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid) ); + + Unit *pEnemy = ObjectAccessor::GetUnit(*_player, guid); + + if(!pEnemy) + { + if(!IS_UNIT_GUID(guid)) + sLog.outError("WORLD: Object %u (TypeID: %u) isn't player, pet or creature",GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); + else + sLog.outError( "WORLD: Enemy %s %u not found",GetLogNameForGuid(guid),GUID_LOPART(guid)); + + // stop attack state at client + SendAttackStop(NULL); + return; + } + + if(_player->IsFriendlyTo(pEnemy) || pEnemy->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) + { + sLog.outError( "WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid)); + + // stop attack state at client + SendAttackStop(pEnemy); + return; + } + + if(!pEnemy->isAlive()) + { + // client can generate swing to known dead target if autoswitch between autoshot and autohit is enabled in client options + // stop attack state at client + SendAttackStop(pEnemy); + return; + } + + _player->Attack(pEnemy,true); +} + +void WorldSession::HandleAttackStopOpcode( WorldPacket & /*recv_data*/ ) +{ + GetPlayer()->AttackStop(); +} + +void WorldSession::HandleSetSheathedOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 sheathed; + recv_data >> sheathed; + + //sLog.outDebug( "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed ); + + GetPlayer()->SetSheath(sheathed); +} + +void WorldSession::SendAttackStop(Unit const* enemy) +{ + WorldPacket data( SMSG_ATTACKSTOP, (4+20) ); // we guess size + data.append(GetPlayer()->GetPackGUID()); + data.append(enemy ? enemy->GetPackGUID() : 0); // must be packed guid + data << uint32(0); // unk, can be 1 also + SendPacket(&data); +} diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp new file mode 100644 index 000000000..c4152a237 --- /dev/null +++ b/src/game/ConfusedMovementGenerator.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Creature.h" +#include "MapManager.h" +#include "Opcodes.h" +#include "ConfusedMovementGenerator.h" +#include "DestinationHolderImp.h" + +template +void +ConfusedMovementGenerator::Initialize(T &unit) +{ + const float wander_distance=11; + float x,y,z; + x = unit.GetPositionX(); + y = unit.GetPositionY(); + z = unit.GetPositionZ(); + uint32 mapid=unit.GetMapId(); + + Map const* map = MapManager::Instance().GetBaseMap(mapid); + + i_nextMove = 1; + + bool is_water_ok, is_land_ok; + _InitSpecific(unit, is_water_ok, is_land_ok); + + for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx) + { + const float wanderX=wander_distance*rand_norm() - wander_distance/2; + const float wanderY=wander_distance*rand_norm() - wander_distance/2; + + i_waypoints[idx][0] = x + wanderX; + i_waypoints[idx][1] = y + wanderY; + + // prevent invalid coordinates generation + MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]); + MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]); + + bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); + // if generated wrong path just ignore + if( is_water && !is_water_ok || !is_water && !is_land_ok ) + { + i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; + i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; + } + unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z); + i_waypoints[idx][2] = z; + } + + unit.StopMoving(); + unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + unit.addUnitState(UNIT_STAT_CONFUSED); +} + +template<> +void +ConfusedMovementGenerator::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) +{ + is_water_ok = creature.canSwim(); + is_land_ok = creature.canWalk(); +} + +template<> +void +ConfusedMovementGenerator::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok) +{ + is_water_ok = true; + is_land_ok = true; +} + +template +void +ConfusedMovementGenerator::Reset(T &unit) +{ + i_nextMove = 1; + i_nextMoveTime.Reset(0); + i_destinationHolder.ResetUpdate(); + unit.StopMoving(); +} + +template +bool +ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) +{ + if(!&unit) + return true; + + if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) + return true; + + if( i_nextMoveTime.Passed() ) + { + // currently moving, update location + Traveller traveller(unit); + if( i_destinationHolder.UpdateTraveller(traveller, diff, false)) + { + if( i_destinationHolder.HasArrived()) + { + // arrived, stop and wait a bit + unit.StopMoving(); + + i_nextMove = urand(1,MAX_CONF_WAYPOINTS); + i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher + } + } + } + else + { + // waiting for next move + i_nextMoveTime.Update(diff); + if( i_nextMoveTime.Passed() ) + { + // start moving + assert( i_nextMove <= MAX_CONF_WAYPOINTS ); + const float x = i_waypoints[i_nextMove][0]; + const float y = i_waypoints[i_nextMove][1]; + const float z = i_waypoints[i_nextMove][2]; + Traveller traveller(unit); + i_destinationHolder.SetDestination(traveller, x, y, z); + } + } + return true; +} + +template +void +ConfusedMovementGenerator::Finalize(T &unit) +{ + unit.clearUnitState(UNIT_STAT_CONFUSED); +} + +template void ConfusedMovementGenerator::Initialize(Player &player); +template void ConfusedMovementGenerator::Initialize(Creature &creature); +template void ConfusedMovementGenerator::Finalize(Player &player); +template void ConfusedMovementGenerator::Finalize(Creature &creature); +template void ConfusedMovementGenerator::Reset(Player &player); +template void ConfusedMovementGenerator::Reset(Creature &creature); +template bool ConfusedMovementGenerator::Update(Player &player, const uint32 &diff); +template bool ConfusedMovementGenerator::Update(Creature &creature, const uint32 &diff); diff --git a/src/game/ConfusedMovementGenerator.h b/src/game/ConfusedMovementGenerator.h new file mode 100644 index 000000000..f023901ce --- /dev/null +++ b/src/game/ConfusedMovementGenerator.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_RANDOMMOTIONGENERATOR_H +#define MANGOS_RANDOMMOTIONGENERATOR_H + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "Traveller.h" + +#define MAX_CONF_WAYPOINTS 24 + +template +class MANGOS_DLL_SPEC ConfusedMovementGenerator +: public MovementGeneratorMedium< T, ConfusedMovementGenerator > +{ + public: + explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {} + + void Initialize(T &); + void Finalize(T &); + void Reset(T &); + bool Update(T &, const uint32 &); + + MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } + private: + void _InitSpecific(T &, bool &, bool &); + TimeTracker i_nextMoveTime; + float i_waypoints[MAX_CONF_WAYPOINTS+1][3]; + DestinationHolder< Traveller > i_destinationHolder; + uint32 i_nextMove; +}; +#endif diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp new file mode 100644 index 000000000..6b298791d --- /dev/null +++ b/src/game/Corpse.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Corpse.h" +#include "Player.h" +#include "UpdateMask.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Database/DatabaseEnv.h" +#include "Opcodes.h" +#include "WorldSession.h" +#include "WorldPacket.h" +#include "GossipDef.h" +#include "World.h" + +Corpse::Corpse(CorpseType type) : WorldObject() +{ + m_objectType |= TYPEMASK_CORPSE; + m_objectTypeId = TYPEID_CORPSE; + // 2.3.2 - 0x58 + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + + m_valuesCount = CORPSE_END; + + m_type = type; + + m_time = time(NULL); + + lootForBody = false; +} + +Corpse::~Corpse() +{ +} + +void Corpse::AddToWorld() +{ + ///- Register the corpse for guid lookup + if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + Object::AddToWorld(); +} + +void Corpse::RemoveFromWorld() +{ + ///- Remove the corpse from the accessor + if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + Object::RemoveFromWorld(); +} + +bool Corpse::Create( uint32 guidlow ) +{ + Object::_Create(guidlow, 0, HIGHGUID_CORPSE); + return true; +} + +bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang ) +{ + SetInstanceId(owner->GetInstanceId()); + + WorldObject::_Create(guidlow, HIGHGUID_CORPSE, mapid); + + Relocate(x,y,z,ang); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %d Y: ^%d)",guidlow,owner->GetName(),x,y); + return false; + } + + SetFloatValue( OBJECT_FIELD_SCALE_X, 1 ); + SetFloatValue( CORPSE_FIELD_POS_X, x ); + SetFloatValue( CORPSE_FIELD_POS_Y, y ); + SetFloatValue( CORPSE_FIELD_POS_Z, z ); + SetFloatValue( CORPSE_FIELD_FACING, ang ); + SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() ); + + m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY()); + + return true; +} + +void Corpse::SaveToDB() +{ + // prevent DB data inconsistance problems and duplicates + CharacterDatabase.BeginTransaction(); + DeleteFromDB(); + + std::ostringstream ss; + ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance) VALUES (" + << GetGUIDLow() << ", " << GUID_LOPART(GetOwnerGUID()) << ", " << GetPositionX() << ", " << GetPositionY() << ", " << GetPositionZ() << ", " + << GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '"; + for(uint16 i = 0; i < m_valuesCount; i++ ) + ss << GetUInt32Value(i) << " "; + ss << "'," << uint64(m_time) <<", " << uint32(GetType()) << ", " << int(GetInstanceId()) << ")"; + CharacterDatabase.Execute( ss.str().c_str() ); + CharacterDatabase.CommitTransaction(); +} + +void Corpse::DeleteBonesFromWorld() +{ + assert(GetType()==CORPSE_BONES); + Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID()); + + if (!corpse) + { + sLog.outError("Bones %u not found in world.", GetGUIDLow()); + return; + } + + AddObjectToRemoveList(); +} + +void Corpse::DeleteFromDB() +{ + if(GetType() == CORPSE_BONES) + // only specific bones + CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow()); + else + // all corpses (not bones) + CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID())); +} + +bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId) +{ + bool external = (result != NULL); + if (!external) + // 0 1 2 3 4 5 6 7 8 + result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid); + + if( ! result ) + { + sLog.outError("ERROR: Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid); + return false; + } + + Field *fields = result->Fetch(); + + if(!LoadFromDB(guid,fields)) + { + if (!external) delete result; + return false; + } + + if (!external) delete result; + return true; +} + +bool Corpse::LoadFromDB(uint32 guid, Field *fields) +{ + // 0 1 2 3 4 5 6 7 8 + //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid); + float positionX = fields[0].GetFloat(); + float positionY = fields[1].GetFloat(); + float positionZ = fields[2].GetFloat(); + float ort = fields[3].GetFloat(); + uint32 mapid = fields[4].GetUInt32(); + + if(!LoadValues( fields[5].GetString() )) + { + sLog.outError("ERROR: Corpse #%d have broken data in `data` field. Can't be loaded.",guid); + return false; + } + + m_time = time_t(fields[6].GetUInt64()); + m_type = CorpseType(fields[7].GetUInt32()); + if(m_type >= MAX_CORPSE_TYPE) + { + sLog.outError("ERROR: Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID())); + return false; + } + uint32 instanceid = fields[8].GetUInt32(); + + // overwrite possible wrong/corrupted guid + SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE)); + + // place + SetInstanceId(instanceid); + SetMapId(mapid); + Relocate(positionX,positionY,positionZ,ort); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %d Y: ^%d)",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()),GetPositionX(),GetPositionY()); + return false; + } + + m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY()); + + return true; +} + +bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const +{ + return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); +} diff --git a/src/game/Corpse.h b/src/game/Corpse.h new file mode 100644 index 000000000..1b8310f5b --- /dev/null +++ b/src/game/Corpse.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_CORPSE_H +#define MANGOSSERVER_CORPSE_H + +#include "Object.h" +#include "Database/DatabaseEnv.h" +#include "GridDefines.h" +#include "LootMgr.h" + +enum CorpseType +{ + CORPSE_BONES = 0, + CORPSE_RESURRECTABLE_PVE = 1, + CORPSE_RESURRECTABLE_PVP = 2 +}; +#define MAX_CORPSE_TYPE 3 + +// Value equal client resurrection dialog show radius. +#define CORPSE_RECLAIM_RADIUS 39 + +enum CorpseFlags +{ + CORPSE_FLAG_NONE = 0x00, + CORPSE_FLAG_BONES = 0x01, + CORPSE_FLAG_UNK1 = 0x02, + CORPSE_FLAG_UNK2 = 0x04, + CORPSE_FLAG_HIDE_HELM = 0x08, + CORPSE_FLAG_HIDE_CLOAK = 0x10, + CORPSE_FLAG_LOOTABLE = 0x20 +}; + +class Corpse : public WorldObject +{ + public: + explicit Corpse( CorpseType type = CORPSE_BONES ); + ~Corpse( ); + + void AddToWorld(); + void RemoveFromWorld(); + + bool Create( uint32 guidlow ); + bool Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang ); + + void SaveToDB(); + bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId); + bool LoadFromDB(uint32 guid, Field *fields); + + void DeleteBonesFromWorld(); + void DeleteFromDB(); + + uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); } + + time_t const& GetGhostTime() const { return m_time; } + void ResetGhostTime() { m_time = time(NULL); } + CorpseType GetType() const { return m_type; } + + GridPair const& GetGrid() const { return m_grid; } + void SetGrid(GridPair const& grid) { m_grid = grid; } + + bool isVisibleForInState(Player const* u, bool inVisibleList) const; + + Loot loot; // remove insignia ONLY at BG + Player* lootRecipient; + bool lootForBody; + + void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); } + void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); } + void TextEmote(const char* text, uint64 TargetGuid) { MonsterTextEmote(text,TargetGuid); } + void Whisper(const char* text, uint64 receiver) { MonsterWhisper(text,receiver); } + void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } + void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } + void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); } + void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); } + + GridReference &GetGridRef() { return m_gridRef; } + private: + GridReference m_gridRef; + + CorpseType m_type; + time_t m_time; + GridPair m_grid; // gride for corpse position for fast search +}; +#endif diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp new file mode 100644 index 000000000..6664e62b5 --- /dev/null +++ b/src/game/Creature.cpp @@ -0,0 +1,2030 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Creature.h" +#include "QuestDef.h" +#include "GossipDef.h" +#include "Player.h" +#include "Opcodes.h" +#include "Log.h" +#include "LootMgr.h" +#include "MapManager.h" +#include "CreatureAI.h" +#include "CreatureAISelector.h" +#include "Formulas.h" +#include "SpellAuras.h" +#include "WaypointMovementGenerator.h" +#include "InstanceData.h" +#include "BattleGround.h" +#include "Util.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" + +// apply implementation of the singletons +#include "Policies/SingletonImp.h" + +void TrainerSpellData::Clear() +{ + for (TrainerSpellList::iterator itr = spellList.begin(); itr != spellList.end(); ++itr) + delete (*itr); + spellList.empty(); +} + +TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const +{ + for(TrainerSpellList::const_iterator itr = spellList.begin(); itr != spellList.end(); ++itr) + if((*itr)->spell == spell_id) + return *itr; + + return NULL; +} + +bool VendorItemData::RemoveItem( uint32 item_id ) +{ + for(VendorItemList::iterator i = m_items.begin(); i != m_items.end(); ++i ) + { + if((*i)->item==item_id) + { + m_items.erase(i); + return true; + } + } + return false; +} + +size_t VendorItemData::FindItemSlot(uint32 item_id) const +{ + for(size_t i = 0; i < m_items.size(); ++i ) + if(m_items[i]->item==item_id) + return i; + return m_items.size(); +} + +VendorItem const* VendorItemData::FindItem(uint32 item_id) const +{ + for(VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i ) + if((*i)->item==item_id) + return *i; + return NULL; +} + +Creature::Creature() : +Unit(), i_AI(NULL), +lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), +m_lootMoney(0), m_lootRecipient(0), +m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), +m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), +m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), +m_AlreadyCallAssistence(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), +m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0) +{ + m_valuesCount = UNIT_END; + + for(int i =0; i<4; ++i) + m_spells[i] = 0; + + m_CreatureSpellCooldowns.clear(); + m_CreatureCategoryCooldowns.clear(); + m_GlobalCooldown = 0; + m_unit_movement_flags = MOVEMENTFLAG_WALK_MODE; +} + +Creature::~Creature() +{ + CleanupsBeforeDelete(); + + m_vendorItemCounts.clear(); + + delete i_AI; + i_AI = NULL; +} + +void Creature::AddToWorld() +{ + ///- Register the creature for guid lookup + if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + Unit::AddToWorld(); +} + +void Creature::RemoveFromWorld() +{ + ///- Remove the creature from the accessor + if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + Unit::RemoveFromWorld(); +} + +void Creature::RemoveCorpse() +{ + if( getDeathState()!=CORPSE && !m_isDeadByDefault || getDeathState()!=ALIVE && m_isDeadByDefault ) + return; + + m_deathTimer = 0; + setDeathState(DEAD); + ObjectAccessor::UpdateObjectVisibility(this); + loot.clear(); + m_respawnTime = time(NULL) + m_respawnDelay; + + float x,y,z,o; + GetRespawnCoord(x, y, z, &o); + MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation(this,x,y,z,o); +} + +/** + * change the entry of creature until respawn + */ +bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) +{ + CreatureInfo const *normalInfo = objmgr.GetCreatureTemplate(Entry); + if(!normalInfo) + { + sLog.outErrorDb("Creature::UpdateEntry creature entry %u does not exist.", Entry); + return false; + } + + // get heroic mode entry + uint32 actualEntry = Entry; + CreatureInfo const *cinfo = normalInfo; + if(normalInfo->HeroicEntry) + { + Map *map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); + if(map && map->IsHeroic()) + { + cinfo = objmgr.GetCreatureTemplate(normalInfo->HeroicEntry); + if(!cinfo) + { + sLog.outErrorDb("Creature::UpdateEntry creature heroic entry %u does not exist.", actualEntry); + return false; + } + } + } + + SetEntry(Entry); // normal entry always + m_creatureInfo = cinfo; // map mode related always + + if (cinfo->DisplayID_A == 0 || cinfo->DisplayID_H == 0) // Cancel load if no model defined + { + sLog.outErrorDb("Creature (Entry: %u) has no model defined for Horde or Alliance in table `creature_template`, can't load. ",Entry); + return false; + } + + uint32 display_id = objmgr.ChooseDisplayId(team, GetCreatureInfo(), data); + CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id); + if (!minfo) + { + sLog.outErrorDb("Creature (Entry: %u) has model %u not found in table `creature_model_info`, can't load. ", Entry, display_id); + return false; + } + else + display_id = minfo->modelid; // it can be different (for another gender) + + SetDisplayId(display_id); + SetNativeDisplayId(display_id); + SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); + + // Load creature equipment + if(!data || data->equipmentId == 0) + { // use default from the template + LoadEquipment(cinfo->equipmentId); + } + else if(data && data->equipmentId != -1) + { // override, -1 means no equipment + LoadEquipment(data->equipmentId); + } + + SetName(normalInfo->Name); // at normal entry always + + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); + SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); + + SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + + SetSpeed(MOVE_WALK, cinfo->speed ); + SetSpeed(MOVE_RUN, cinfo->speed ); + SetSpeed(MOVE_SWIM, cinfo->speed ); + + SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale); + + // checked at loading + m_defaultMovementType = MovementGeneratorType(cinfo->MovementType); + if(!m_respawnradius && m_defaultMovementType==RANDOM_MOTION_TYPE) + m_defaultMovementType = IDLE_MOTION_TYPE; + + return true; +} + +bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) +{ + if(!InitEntry(Entry,team,data)) + return false; + + m_regenHealth = GetCreatureInfo()->RegenHealth; + + // creatures always have melee weapon ready if any + SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_AURAS ); + + SelectLevel(GetCreatureInfo()); + if (team == HORDE) + SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, GetCreatureInfo()->faction_H); + else + SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, GetCreatureInfo()->faction_A); + + SetUInt32Value(UNIT_NPC_FLAGS,GetCreatureInfo()->npcflag); + + SetAttackTime(BASE_ATTACK, GetCreatureInfo()->baseattacktime); + SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); + SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); + + SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->Flags); + SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); + + SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); + SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(GetCreatureInfo()->resistance1)); + SetModifierValue(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(GetCreatureInfo()->resistance2)); + SetModifierValue(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(GetCreatureInfo()->resistance3)); + SetModifierValue(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(GetCreatureInfo()->resistance4)); + SetModifierValue(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(GetCreatureInfo()->resistance5)); + SetModifierValue(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(GetCreatureInfo()->resistance6)); + + SetCanModifyStats(true); + UpdateAllStats(); + + FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(GetCreatureInfo()->faction_A); + if (factionTemplate) // check and error show at loading templates + { + FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction); + if (factionEntry) + if( !(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN) && + (factionEntry->team == ALLIANCE || factionEntry->team == HORDE) ) + SetPvP(true); + } + + m_spells[0] = GetCreatureInfo()->spell1; + m_spells[1] = GetCreatureInfo()->spell2; + m_spells[2] = GetCreatureInfo()->spell3; + m_spells[3] = GetCreatureInfo()->spell4; + + return true; +} + +void Creature::Update(uint32 diff) +{ + if(m_GlobalCooldown <= diff) + m_GlobalCooldown = 0; + else + m_GlobalCooldown -= diff; + + switch( m_deathState ) + { + case JUST_ALIVED: + // Dont must be called, see Creature::setDeathState JUST_ALIVED -> ALIVE promoting. + sLog.outError("Creature (GUIDLow: %u Entry: %u ) in wrong state: JUST_ALIVED (4)",GetGUIDLow(),GetEntry()); + break; + case JUST_DIED: + // Dont must be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting. + sLog.outError("Creature (GUIDLow: %u Entry: %u ) in wrong state: JUST_DEAD (1)",GetGUIDLow(),GetEntry()); + break; + case DEAD: + { + if( m_respawnTime <= time(NULL) ) + { + DEBUG_LOG("Respawning..."); + m_respawnTime = 0; + lootForPickPocketed = false; + lootForBody = false; + + if(m_originalEntry != GetEntry()) + UpdateEntry(m_originalEntry); + + CreatureInfo const *cinfo = GetCreatureInfo(); + + SelectLevel(cinfo); + SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); + if (m_isDeadByDefault) + { + setDeathState(JUST_DIED); + SetHealth(0); + i_motionMaster.Clear(); + clearUnitState(UNIT_STAT_ALL_STATE); + LoadCreaturesAddon(true); + } + else + setDeathState( JUST_ALIVED ); + + //Call AI respawn virtual function + i_AI->JustRespawned(); + + MapManager::Instance().GetMap(GetMapId(), this)->Add(this); + } + break; + } + case CORPSE: + { + if (m_isDeadByDefault) + break; + + if( m_deathTimer <= diff ) + { + RemoveCorpse(); + DEBUG_LOG("Removing corpse... %u ", GetEntry()); + } + else + { + m_deathTimer -= diff; + if (m_groupLootTimer && lootingGroupLeaderGUID) + { + if(diff <= m_groupLootTimer) + { + m_groupLootTimer -= diff; + } + else + { + Group* group = objmgr.GetGroupByLeader(lootingGroupLeaderGUID); + if (group) + group->EndRoll(); + m_groupLootTimer = 0; + lootingGroupLeaderGUID = 0; + } + } + } + + break; + } + case ALIVE: + { + if (m_isDeadByDefault) + { + if( m_deathTimer <= diff ) + { + RemoveCorpse(); + DEBUG_LOG("Removing alive corpse... %u ", GetEntry()); + } + else + { + m_deathTimer -= diff; + } + } + + Unit::Update( diff ); + + // creature can be dead after Unit::Update call + // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly) + if(!isAlive()) + break; + + if(!IsInEvadeMode()) + { + // do not allow the AI to be changed during update + m_AI_locked = true; + i_AI->UpdateAI(diff); + m_AI_locked = false; + } + + // creature can be dead after UpdateAI call + // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly) + if(!isAlive()) + break; + if(m_regenTimer > 0) + { + if(diff >= m_regenTimer) + m_regenTimer = 0; + else + m_regenTimer -= diff; + } + if (m_regenTimer != 0) + break; + + if (!isInCombat() || IsPolymorphed()) + RegenerateHealth(); + + RegenerateMana(); + + m_regenTimer = 2000; + break; + } + default: + break; + } +} + +void Creature::RegenerateMana() +{ + uint32 curValue = GetPower(POWER_MANA); + uint32 maxValue = GetMaxPower(POWER_MANA); + + if (curValue >= maxValue) + return; + + uint32 addvalue = 0; + + // Combat and any controlled creature + if (isInCombat() || GetCharmerOrOwnerGUID()) + { + if(!IsUnderLastManaUseEffect()) + { + float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA); + float Spirit = GetStat(STAT_SPIRIT); + + addvalue = uint32((Spirit/5.0f + 17.0f) * ManaIncreaseRate); + } + } + else + addvalue = maxValue/3; + + ModifyPower(POWER_MANA, addvalue); +} + +void Creature::RegenerateHealth() +{ + if (!isRegeneratingHealth()) + return; + + uint32 curValue = GetHealth(); + uint32 maxValue = GetMaxHealth(); + + if (curValue >= maxValue) + return; + + uint32 addvalue = 0; + + // Not only pet, but any controelled creature + if(GetCharmerOrOwnerGUID()) + { + float HealthIncreaseRate = sWorld.getRate(RATE_HEALTH); + float Spirit = GetStat(STAT_SPIRIT); + + if( GetPower(POWER_MANA) > 0 ) + addvalue = uint32(Spirit * 0.25 * HealthIncreaseRate); + else + addvalue = uint32(Spirit * 0.80 * HealthIncreaseRate); + } + else + addvalue = maxValue/3; + + ModifyHealth(addvalue); +} + +bool Creature::AIM_Initialize() +{ + // make sure nothing can change the AI during AI update + if(m_AI_locked) + { + sLog.outDebug("AIM_Initialize: failed to init, locked."); + return false; + } + + CreatureAI * oldAI = i_AI; + i_motionMaster.Initialize(); + i_AI = FactorySelector::selectAI(this); + if (oldAI) + delete oldAI; + return true; +} + +bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data) +{ + SetMapId(map->GetId()); + SetInstanceId(map->GetInstanceId()); + + //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; + const bool bResult = CreateFromProto(guidlow, Entry, team, data); + + if (bResult) + { + switch (GetCreatureInfo()->rank) + { + case CREATURE_ELITE_RARE: + m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_RARE); + break; + case CREATURE_ELITE_ELITE: + m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_ELITE); + break; + case CREATURE_ELITE_RAREELITE: + m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_RAREELITE); + break; + case CREATURE_ELITE_WORLDBOSS: + m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_WORLDBOSS); + break; + default: + m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_NORMAL); + break; + } + LoadCreaturesAddon(); + } + + return bResult; +} + +bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const +{ + if(!isTrainer()) + return false; + + TrainerSpellData const* trainer_spells = GetTrainerSpells(); + + if(!trainer_spells || trainer_spells->spellList.empty()) + { + sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_TRAINER but have empty trainer spell list.", + GetGUIDLow(),GetEntry()); + return false; + } + + switch(GetCreatureInfo()->trainer_type) + { + case TRAINER_TYPE_CLASS: + if(pPlayer->getClass()!=GetCreatureInfo()->classNum) + { + if(msg) + { + pPlayer->PlayerTalkClass->ClearMenus(); + switch(GetCreatureInfo()->classNum) + { + case CLASS_DRUID: pPlayer->PlayerTalkClass->SendGossipMenu( 4913,GetGUID()); break; + case CLASS_HUNTER: pPlayer->PlayerTalkClass->SendGossipMenu(10090,GetGUID()); break; + case CLASS_MAGE: pPlayer->PlayerTalkClass->SendGossipMenu( 328,GetGUID()); break; + case CLASS_PALADIN:pPlayer->PlayerTalkClass->SendGossipMenu( 1635,GetGUID()); break; + case CLASS_PRIEST: pPlayer->PlayerTalkClass->SendGossipMenu( 4436,GetGUID()); break; + case CLASS_ROGUE: pPlayer->PlayerTalkClass->SendGossipMenu( 4797,GetGUID()); break; + case CLASS_SHAMAN: pPlayer->PlayerTalkClass->SendGossipMenu( 5003,GetGUID()); break; + case CLASS_WARLOCK:pPlayer->PlayerTalkClass->SendGossipMenu( 5836,GetGUID()); break; + case CLASS_WARRIOR:pPlayer->PlayerTalkClass->SendGossipMenu( 4985,GetGUID()); break; + } + } + return false; + } + break; + case TRAINER_TYPE_PETS: + if(pPlayer->getClass()!=CLASS_HUNTER) + { + pPlayer->PlayerTalkClass->ClearMenus(); + pPlayer->PlayerTalkClass->SendGossipMenu(3620,GetGUID()); + return false; + } + break; + case TRAINER_TYPE_MOUNTS: + if(GetCreatureInfo()->race && pPlayer->getRace() != GetCreatureInfo()->race) + { + if(msg) + { + pPlayer->PlayerTalkClass->ClearMenus(); + switch(GetCreatureInfo()->classNum) + { + case RACE_DWARF: pPlayer->PlayerTalkClass->SendGossipMenu(5865,GetGUID()); break; + case RACE_GNOME: pPlayer->PlayerTalkClass->SendGossipMenu(4881,GetGUID()); break; + case RACE_HUMAN: pPlayer->PlayerTalkClass->SendGossipMenu(5861,GetGUID()); break; + case RACE_NIGHTELF: pPlayer->PlayerTalkClass->SendGossipMenu(5862,GetGUID()); break; + case RACE_ORC: pPlayer->PlayerTalkClass->SendGossipMenu(5863,GetGUID()); break; + case RACE_TAUREN: pPlayer->PlayerTalkClass->SendGossipMenu(5864,GetGUID()); break; + case RACE_TROLL: pPlayer->PlayerTalkClass->SendGossipMenu(5816,GetGUID()); break; + case RACE_UNDEAD_PLAYER:pPlayer->PlayerTalkClass->SendGossipMenu( 624,GetGUID()); break; + case RACE_BLOODELF: pPlayer->PlayerTalkClass->SendGossipMenu(5862,GetGUID()); break; + case RACE_DRAENEI: pPlayer->PlayerTalkClass->SendGossipMenu(5864,GetGUID()); break; + } + } + return false; + } + break; + case TRAINER_TYPE_TRADESKILLS: + if(GetCreatureInfo()->trainer_spell && !pPlayer->HasSpell(GetCreatureInfo()->trainer_spell)) + { + if(msg) + { + pPlayer->PlayerTalkClass->ClearMenus(); + pPlayer->PlayerTalkClass->SendGossipMenu(11031,GetGUID()); + } + return false; + } + break; + default: + return false; // checked and error output at creature_template loading + } + return true; +} + +bool Creature::isCanIneractWithBattleMaster(Player* pPlayer, bool msg) const +{ + if(!isBattleMaster()) + return false; + + uint32 bgTypeId = objmgr.GetBattleMasterBG(GetEntry()); + if(!msg) + return pPlayer->GetBGAccessByLevel(bgTypeId); + + if(!pPlayer->GetBGAccessByLevel(bgTypeId)) + { + pPlayer->PlayerTalkClass->ClearMenus(); + switch(bgTypeId) + { + case BATTLEGROUND_AV: pPlayer->PlayerTalkClass->SendGossipMenu(7616,GetGUID()); break; + case BATTLEGROUND_WS: pPlayer->PlayerTalkClass->SendGossipMenu(7599,GetGUID()); break; + case BATTLEGROUND_AB: pPlayer->PlayerTalkClass->SendGossipMenu(7642,GetGUID()); break; + case BATTLEGROUND_EY: + case BATTLEGROUND_NA: + case BATTLEGROUND_BE: + case BATTLEGROUND_AA: + case BATTLEGROUND_RL: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break; + break; + } + return false; + } + return true; +} + +bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const +{ + return pPlayer->getLevel() >= 10 + && GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS + && pPlayer->getClass() == GetCreatureInfo()->classNum; +} + +void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) +{ + PlayerMenu* pm=pPlayer->PlayerTalkClass; + pm->ClearMenus(); + + // lazy loading single time at use + LoadGossipOptions(); + + GossipOption* gso; + GossipOption* ingso; + + for( GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); i++ ) + { + gso=&*i; + if(gso->GossipId == gossipid) + { + bool cantalking=true; + if(gso->Id==1) + { + uint32 textid=GetNpcTextId(); + GossipText * gossiptext=objmgr.GetGossipText(textid); + if(!gossiptext) + cantalking=false; + } + else + { + switch (gso->Action) + { + case GOSSIP_OPTION_QUESTGIVER: + pPlayer->PrepareQuestMenu(GetGUID()); + //if (pm->GetQuestMenu()->MenuItemCount() == 0) + cantalking=false; + //pm->GetQuestMenu()->ClearMenu(); + break; + case GOSSIP_OPTION_ARMORER: + cantalking=false; // added in special mode + break; + case GOSSIP_OPTION_SPIRITHEALER: + if( !pPlayer->isDead() ) + cantalking=false; + break; + case GOSSIP_OPTION_VENDOR: + { + VendorItemData const* vItems = GetVendorItems(); + if(!vItems || vItems->Empty()) + { + sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", + GetGUIDLow(),GetEntry()); + cantalking=false; + } + break; + } + case GOSSIP_OPTION_TRAINER: + if(!isCanTrainingOf(pPlayer,false)) + cantalking=false; + break; + case GOSSIP_OPTION_UNLEARNTALENTS: + if(!isCanTrainingAndResetTalentsOf(pPlayer)) + cantalking=false; + break; + case GOSSIP_OPTION_UNLEARNPETSKILLS: + if(!pPlayer->GetPet() || pPlayer->GetPet()->getPetType() != HUNTER_PET || pPlayer->GetPet()->m_spells.size() <= 1 || GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || GetCreatureInfo()->classNum != CLASS_HUNTER) + cantalking=false; + break; + case GOSSIP_OPTION_TAXIVENDOR: + if ( pPlayer->GetSession()->SendLearnNewTaxiNode(this) ) + return; + break; + case GOSSIP_OPTION_BATTLEFIELD: + if(!isCanIneractWithBattleMaster(pPlayer,false)) + cantalking=false; + break; + case GOSSIP_OPTION_SPIRITGUIDE: + case GOSSIP_OPTION_INNKEEPER: + case GOSSIP_OPTION_BANKER: + case GOSSIP_OPTION_PETITIONER: + case GOSSIP_OPTION_STABLEPET: + case GOSSIP_OPTION_TABARDDESIGNER: + case GOSSIP_OPTION_AUCTIONEER: + break; // no checks + default: + sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u",GetGUIDLow(),GetEntry(),gso->Action); + break; + } + } + + if(!gso->Option.empty() && cantalking ) + { //note for future dev: should have database fields for BoxMessage & BoxMoney + pm->GetGossipMenu().AddMenuItem((uint8)gso->Icon,gso->Option, gossipid,gso->Action,"",0,false); + ingso=gso; + } + } + } + + ///some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) + if(pm->Empty()) + { + if(HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER)) + { + isCanTrainingOf(pPlayer,true); // output error message if need + } + if(HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_BATTLEMASTER)) + { + isCanIneractWithBattleMaster(pPlayer,true); // output error message if need + } + } +} + +void Creature::sendPreparedGossip(Player* player) +{ + if(!player) + return; + + GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu(); + + // in case empty gossip menu open quest menu if any + if (gossipmenu.Empty() && GetNpcTextId() == 0) + { + player->SendPreparedQuest(GetGUID()); + return; + } + + // in case non empty gossip menu (that not included quests list size) show it + // (quest entries from quest menu wiill be included in list) + player->PlayerTalkClass->SendGossipMenu(GetNpcTextId(), GetGUID()); +} + +void Creature::OnGossipSelect(Player* player, uint32 option) +{ + GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu(); + + if(option >= gossipmenu.MenuItemCount()) + return; + + uint32 action=gossipmenu.GetItem(option).m_gAction; + uint32 zoneid=GetZoneId(); + uint64 guid=GetGUID(); + GossipOption const *gossip=GetGossipOption( action ); + uint32 textid; + if(!gossip) + { + zoneid=0; + gossip=GetGossipOption( action ); + if(!gossip) + return; + } + textid=GetGossipTextId( action, zoneid); + if(textid==0) + textid=GetNpcTextId(); + + switch (gossip->Action) + { + case GOSSIP_OPTION_GOSSIP: + player->PlayerTalkClass->CloseGossip(); + player->PlayerTalkClass->SendTalking( textid ); + break; + case GOSSIP_OPTION_SPIRITHEALER: + if( player->isDead() ) + CastSpell(this,17251,true,NULL,NULL,player->GetGUID()); + break; + case GOSSIP_OPTION_QUESTGIVER: + player->PrepareQuestMenu( guid ); + player->SendPreparedQuest( guid ); + break; + case GOSSIP_OPTION_VENDOR: + case GOSSIP_OPTION_ARMORER: + player->GetSession()->SendListInventory(guid); + break; + case GOSSIP_OPTION_STABLEPET: + player->GetSession()->SendStablePet(guid); + break; + case GOSSIP_OPTION_TRAINER: + player->GetSession()->SendTrainerList(guid); + break; + case GOSSIP_OPTION_UNLEARNTALENTS: + player->PlayerTalkClass->CloseGossip(); + player->SendTalentWipeConfirm(guid); + break; + case GOSSIP_OPTION_UNLEARNPETSKILLS: + player->PlayerTalkClass->CloseGossip(); + player->SendPetSkillWipeConfirm(); + break; + case GOSSIP_OPTION_TAXIVENDOR: + player->GetSession()->SendTaxiMenu(this); + break; + case GOSSIP_OPTION_INNKEEPER: + player->PlayerTalkClass->CloseGossip(); + player->SetBindPoint( guid ); + break; + case GOSSIP_OPTION_BANKER: + player->GetSession()->SendShowBank( guid ); + break; + case GOSSIP_OPTION_PETITIONER: + player->PlayerTalkClass->CloseGossip(); + player->GetSession()->SendPetitionShowList( guid ); + break; + case GOSSIP_OPTION_TABARDDESIGNER: + player->PlayerTalkClass->CloseGossip(); + player->GetSession()->SendTabardVendorActivate( guid ); + break; + case GOSSIP_OPTION_AUCTIONEER: + player->GetSession()->SendAuctionHello( guid, this ); + break; + case GOSSIP_OPTION_SPIRITGUIDE: + case GOSSIP_GUARD_SPELLTRAINER: + case GOSSIP_GUARD_SKILLTRAINER: + prepareGossipMenu( player,gossip->Id ); + sendPreparedGossip( player ); + break; + case GOSSIP_OPTION_BATTLEFIELD: + { + uint32 bgTypeId = objmgr.GetBattleMasterBG(GetEntry()); + player->GetSession()->SendBattlegGroundList( GetGUID(), bgTypeId ); + break; + } + default: + OnPoiSelect( player, gossip ); + break; + } + +} + +void Creature::OnPoiSelect(Player* player, GossipOption const *gossip) +{ + if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER) + { + //float x,y; + //bool findnpc=false; + Poi_Icon icon = ICON_POI_0; + //QueryResult *result; + //Field *fields; + uint32 mapid=GetMapId(); + Map const* map=MapManager::Instance().GetBaseMap( mapid ); + uint16 areaflag=map->GetAreaFlag(GetPositionX(),GetPositionY()); + uint32 zoneid=Map::GetZoneId(areaflag,mapid); + std::string areaname= gossip->Option; + /* + uint16 pflag; + + // use the action relate to creaturetemplate.trainer_type ? + result= WorldDatabase.PQuery("SELECT creature.position_x,creature.position_y FROM creature,creature_template WHERE creature.map = '%u' AND creature.id = creature_template.entry AND creature_template.trainer_type = '%u'", mapid, gossip->Action ); + if(!result) + return; + do + { + fields = result->Fetch(); + x=fields[0].GetFloat(); + y=fields[1].GetFloat(); + pflag=map->GetAreaFlag(GetPositionX(),GetPositionY()); + if(pflag==areaflag) + { + findnpc=true; + break; + } + }while(result->NextRow()); + + delete result; + + if(!findnpc) + { + player->PlayerTalkClass->SendTalking( "$NSorry", "Here no this person."); + return; + }*/ + + //need add more case. + switch(gossip->Action) + { + case GOSSIP_GUARD_BANK: + icon=ICON_POI_HOUSE; + break; + case GOSSIP_GUARD_RIDE: + icon=ICON_POI_RWHORSE; + break; + case GOSSIP_GUARD_GUILD: + icon=ICON_POI_BLUETOWER; + break; + default: + icon=ICON_POI_TOWER; + break; + } + uint32 textid=GetGossipTextId( gossip->Action, zoneid ); + player->PlayerTalkClass->SendTalking( textid ); + // how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() ); + } +} + +uint32 Creature::GetGossipTextId(uint32 action, uint32 zoneid) +{ + QueryResult *result= WorldDatabase.PQuery("SELECT textid FROM npc_gossip_textid WHERE action = '%u' AND zoneid ='%u'", action, zoneid ); + + if(!result) + return 0; + + Field *fields = result->Fetch(); + uint32 id = fields[0].GetUInt32(); + + delete result; + + return id; +} + +uint32 Creature::GetNpcTextId() +{ + if (!m_DBTableGuid) + return DEFAULT_GOSSIP_MESSAGE; + + if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid)) + return pos; + + return DEFAULT_GOSSIP_MESSAGE; +} + +GossipOption const* Creature::GetGossipOption( uint32 id ) const +{ + for( GossipOptionList::const_iterator i = m_goptions.begin( ); i != m_goptions.end( ); i++ ) + { + if(i->Action==id ) + return &*i; + } + return NULL; +} + +void Creature::LoadGossipOptions() +{ + if(m_gossipOptionLoaded) + return; + + uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS); + + QueryResult *result = WorldDatabase.PQuery( "SELECT id,gossip_id,npcflag,icon,action,option_text FROM npc_option WHERE (npcflag & %u)<>0", npcflags ); + + if(!result) + return; + + GossipOption go; + do + { + Field *fields = result->Fetch(); + go.Id= fields[0].GetUInt32(); + go.GossipId = fields[1].GetUInt32(); + go.NpcFlag=fields[2].GetUInt32(); + go.Icon=fields[3].GetUInt32(); + go.Action=fields[4].GetUInt32(); + go.Option=fields[5].GetCppString(); + addGossipOption(go); + }while( result->NextRow() ); + delete result; + + m_gossipOptionLoaded = true; +} + +void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type) +{ + /* uint32 timeElap = getMSTime(); + if ((timeElap - m_startMove) < m_moveTime) + { + oX = (dX - oX) * ( (timeElap - m_startMove) / m_moveTime ); + oY = (dY - oY) * ( (timeElap - m_startMove) / m_moveTime ); + } + else + { + oX = dX; + oY = dY; + } + + dX = x; + dY = y; + m_orientation = atan2((oY - dY), (oX - dX)); + + m_startMove = getMSTime(); + m_moveTime = time;*/ + SendMonsterMove(x, y, z, type, MovementFlags, time); +} + +Player *Creature::GetLootRecipient() const +{ + if (!m_lootRecipient) return NULL; + else return ObjectAccessor::FindPlayer(m_lootRecipient); +} + +void Creature::SetLootRecipient(Unit *unit) +{ + // set the player whose group should receive the right + // to loot the creature after it dies + // should be set to NULL after the loot disappears + + if (!unit) + { + m_lootRecipient = 0; + RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER); + return; + } + + Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself(); + if(!player) // normal creature, no player involved + return; + + m_lootRecipient = player->GetGUID(); + SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER); +} + +void Creature::SaveToDB() +{ + // this should only be used when the creature has already been loaded + // perferably after adding to map, because mapid may not be valid otherwise + CreatureData const *data = objmgr.GetCreatureData(m_DBTableGuid); + if(!data) + { + sLog.outError("Creature::SaveToDB failed, cannot get creature data!"); + return; + } + + SaveToDB(GetMapId(), data->spawnMask); +} + +void Creature::SaveToDB(uint32 mapid, uint8 spawnMask) +{ + // update in loaded data + if (!m_DBTableGuid) + m_DBTableGuid = GetGUIDLow(); + CreatureData& data = objmgr.NewOrExistCreatureData(m_DBTableGuid); + + uint32 displayId = GetNativeDisplayId(); + + // check if it's a custom model and if not, use 0 for displayId + CreatureInfo const *cinfo = GetCreatureInfo(); + if(cinfo) + { + if(displayId != cinfo->DisplayID_A && displayId != cinfo->DisplayID_H) + { + CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_A); + if(!minfo || displayId != minfo->modelid_other_gender) + { + minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_H); + if(minfo && displayId == minfo->modelid_other_gender) + displayId = 0; + } + else + displayId = 0; + } + else + displayId = 0; + } + + // data->guid = guid don't must be update at save + data.id = GetEntry(); + data.mapid = mapid; + data.displayid = displayId; + data.equipmentId = GetEquipmentId(); + data.posX = GetPositionX(); + data.posY = GetPositionY(); + data.posZ = GetPositionZ(); + data.orientation = GetOrientation(); + data.spawntimesecs = m_respawnDelay; + // prevent add data integrity problems + data.spawndist = GetDefaultMovementType()==IDLE_MOTION_TYPE ? 0 : m_respawnradius; + data.currentwaypoint = 0; + data.curhealth = GetHealth(); + data.curmana = GetPower(POWER_MANA); + data.is_dead = m_isDeadByDefault; + // prevent add data integrity problems + data.movementType = !m_respawnradius && GetDefaultMovementType()==RANDOM_MOTION_TYPE + ? IDLE_MOTION_TYPE : GetDefaultMovementType(); + data.spawnMask = spawnMask; + + // updated in DB + WorldDatabase.BeginTransaction(); + + WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); + + std::ostringstream ss; + ss << "INSERT INTO creature VALUES (" + << m_DBTableGuid << "," + << GetEntry() << "," + << mapid <<"," + << (uint32)spawnMask << "," + << displayId <<"," + << GetEquipmentId() <<"," + << GetPositionX() << "," + << GetPositionY() << "," + << GetPositionZ() << "," + << GetOrientation() << "," + << m_respawnDelay << "," //respawn time + << (float) m_respawnradius << "," //spawn distance (float) + << (uint32) (0) << "," //currentwaypoint + << GetHealth() << "," //curhealth + << GetPower(POWER_MANA) << "," //curmana + << (m_isDeadByDefault ? 1 : 0) << "," //is_dead + << GetDefaultMovementType() << ")"; //default movement generator type + + WorldDatabase.PExecuteLog( ss.str( ).c_str( ) ); + + WorldDatabase.CommitTransaction(); +} + +void Creature::SelectLevel(const CreatureInfo *cinfo) +{ + uint32 rank = isPet()? 0 : cinfo->rank; + + // level + uint32 minlevel = std::min(cinfo->maxlevel, cinfo->minlevel); + uint32 maxlevel = std::max(cinfo->maxlevel, cinfo->minlevel); + uint32 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel); + SetLevel(level); + + float rellevel = maxlevel == minlevel ? 0 : (float(level - minlevel))/(maxlevel - minlevel); + + // health + float healthmod = _GetHealthMod(rank); + + uint32 minhealth = std::min(cinfo->maxhealth, cinfo->minhealth); + uint32 maxhealth = std::max(cinfo->maxhealth, cinfo->minhealth); + uint32 health = uint32(healthmod * (minhealth + uint32(rellevel*(maxhealth - minhealth)))); + + SetCreateHealth(health); + SetMaxHealth(health); + SetHealth(health); + + // mana + uint32 minmana = std::min(cinfo->maxmana, cinfo->minmana); + uint32 maxmana = std::max(cinfo->maxmana, cinfo->minmana); + uint32 mana = minmana + uint32(rellevel*(maxmana - minmana)); + + SetCreateMana(mana); + SetMaxPower(POWER_MANA, mana); //MAX Mana + SetPower(POWER_MANA, mana); + + SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, health); + SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, mana); + + // damage + float damagemod = _GetDamageMod(rank); + + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cinfo->mindmg * damagemod); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cinfo->maxdmg * damagemod); + + SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,cinfo->minrangedmg * damagemod); + SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,cinfo->maxrangedmg * damagemod); + + SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod); +} + +float Creature::_GetHealthMod(int32 Rank) +{ + switch (Rank) // define rates for each elite rank + { + case CREATURE_ELITE_NORMAL: + return sWorld.getRate(RATE_CREATURE_NORMAL_HP); + case CREATURE_ELITE_ELITE: + return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP); + case CREATURE_ELITE_RAREELITE: + return sWorld.getRate(RATE_CREATURE_ELITE_RAREELITE_HP); + case CREATURE_ELITE_WORLDBOSS: + return sWorld.getRate(RATE_CREATURE_ELITE_WORLDBOSS_HP); + case CREATURE_ELITE_RARE: + return sWorld.getRate(RATE_CREATURE_ELITE_RARE_HP); + default: + return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP); + } +} + +float Creature::_GetDamageMod(int32 Rank) +{ + switch (Rank) // define rates for each elite rank + { + case CREATURE_ELITE_NORMAL: + return sWorld.getRate(RATE_CREATURE_NORMAL_DAMAGE); + case CREATURE_ELITE_ELITE: + return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE); + case CREATURE_ELITE_RAREELITE: + return sWorld.getRate(RATE_CREATURE_ELITE_RAREELITE_DAMAGE); + case CREATURE_ELITE_WORLDBOSS: + return sWorld.getRate(RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE); + case CREATURE_ELITE_RARE: + return sWorld.getRate(RATE_CREATURE_ELITE_RARE_DAMAGE); + default: + return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE); + } +} + +float Creature::GetSpellDamageMod(int32 Rank) +{ + switch (Rank) // define rates for each elite rank + { + case CREATURE_ELITE_NORMAL: + return sWorld.getRate(RATE_CREATURE_NORMAL_SPELLDAMAGE); + case CREATURE_ELITE_ELITE: + return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE); + case CREATURE_ELITE_RAREELITE: + return sWorld.getRate(RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE); + case CREATURE_ELITE_WORLDBOSS: + return sWorld.getRate(RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE); + case CREATURE_ELITE_RARE: + return sWorld.getRate(RATE_CREATURE_ELITE_RARE_SPELLDAMAGE); + default: + return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE); + } +} + +bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data) +{ + CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(Entry); + if(!cinfo) + { + sLog.outErrorDb("Error: creature entry %u does not exist.", Entry); + return false; + } + m_originalEntry = Entry; + + Object::_Create(guidlow, Entry, HIGHGUID_UNIT); + + if(!UpdateEntry(Entry, team, data)) + return false; + + //Notify the map's instance data. + //Only works if you create the object in it, not if it is moves to that map. + //Normally non-players do not teleport to other maps. + Map *map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); + if(map && map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) + { + ((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this, Entry); + } + + return true; +} + +bool Creature::LoadFromDB(uint32 guid, Map *map) +{ + CreatureData const* data = objmgr.GetCreatureData(guid); + + if(!data) + { + sLog.outErrorDb("Creature (GUID: %u) not found in table `creature`, can't load. ",guid); + return false; + } + + m_DBTableGuid = guid; + if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT); + + uint16 team = 0; + if(!Create(guid,map,data->id,team,data)) + return false; + + Relocate(data->posX,data->posY,data->posZ,data->orientation); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",GetGUIDLow(),GetEntry(),GetPositionX(),GetPositionY()); + return false; + } + + m_respawnradius = data->spawndist; + + m_respawnDelay = data->spawntimesecs; + m_isDeadByDefault = data->is_dead; + m_deathState = m_isDeadByDefault ? DEAD : ALIVE; + + m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); + if(m_respawnTime > time(NULL)) // not ready to respawn + m_deathState = DEAD; + else if(m_respawnTime) // respawn time set but expired + { + m_respawnTime = 0; + objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); + } + + uint32 curhealth = data->curhealth; + if(curhealth) + { + curhealth = uint32(curhealth*_GetHealthMod(GetCreatureInfo()->rank)); + if(curhealth < 1) + curhealth = 1; + } + + SetHealth(m_deathState == ALIVE ? curhealth : 0); + SetPower(POWER_MANA,data->curmana); + + SetMeleeDamageSchool(SpellSchools(GetCreatureInfo()->dmgschool)); + + // checked at creature_template loading + m_defaultMovementType = MovementGeneratorType(data->movementType); + + AIM_Initialize(); + return true; +} + +void Creature::LoadEquipment(uint32 equip_entry, bool force) +{ + if(equip_entry == 0) + { + if (force) + { + for (uint8 i = 0; i < 3; i++) + { + SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, 0); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0); + } + m_equipmentId = 0; + } + return; + } + + EquipmentInfo const *einfo = objmgr.GetEquipmentInfo(equip_entry); + if (!einfo) + return; + + m_equipmentId = equip_entry; + for (uint8 i = 0; i < 3; i++) + { + SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, einfo->equipmodel[i]); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), einfo->equipinfo[i]); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, einfo->equipslot[i]); + } +} + +bool Creature::hasQuest(uint32 quest_id) const +{ + QuestRelations const& qr = objmgr.mCreatureQuestRelations; + for(QuestRelations::const_iterator itr = qr.lower_bound(GetEntry()); itr != qr.upper_bound(GetEntry()); ++itr) + { + if(itr->second==quest_id) + return true; + } + return false; +} + +bool Creature::hasInvolvedQuest(uint32 quest_id) const +{ + QuestRelations const& qr = objmgr.mCreatureQuestInvolvedRelations; + for(QuestRelations::const_iterator itr = qr.lower_bound(GetEntry()); itr != qr.upper_bound(GetEntry()); ++itr) + { + if(itr->second==quest_id) + return true; + } + return false; +} + +void Creature::DeleteFromDB() +{ + if (!m_DBTableGuid) + { + sLog.outDebug("Trying to delete not saved creature!"); + return; + } + + objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); + objmgr.DeleteCreatureData(m_DBTableGuid); + + WorldDatabase.BeginTransaction(); + WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); + WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid); + WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id = '%u'", m_DBTableGuid); + WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid); + WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid); + WorldDatabase.CommitTransaction(); +} + +float Creature::GetAttackDistance(Unit const* pl) const +{ + float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO); + if(aggroRate==0) + return 0.0f; + + int32 playerlevel = pl->getLevelForTarget(this); + int32 creaturelevel = getLevelForTarget(pl); + + int32 leveldif = playerlevel - creaturelevel; + + // "The maximum Aggro Radius has a cap of 25 levels under. Example: A level 30 char has the same Aggro Radius of a level 5 char on a level 60 mob." + if ( leveldif < - 25) + leveldif = -25; + + // "The aggro radius of a mob having the same level as the player is roughly 20 yards" + float RetDistance = 20; + + // "Aggro Radius varries with level difference at a rate of roughly 1 yard/level" + // radius grow if playlevel < creaturelevel + RetDistance -= (float)leveldif; + + if(creaturelevel+5 <= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + // detect range auras + RetDistance += GetTotalAuraModifier(SPELL_AURA_MOD_DETECT_RANGE); + + // detected range auras + RetDistance += pl->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE); + } + + // "Minimum Aggro Radius for a mob seems to be combat range (5 yards)" + if(RetDistance < 5) + RetDistance = 5; + + return (RetDistance*aggroRate); +} + +void Creature::setDeathState(DeathState s) +{ + if((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault)) + { + m_deathTimer = m_corpseDelay*1000; + + // always save boss respawn time at death to prevent crash cheating + if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY) || isWorldBoss()) + SaveRespawnTime(); + + if(!IsStopped()) + StopMoving(); + } + Unit::setDeathState(s); + + if(s == JUST_DIED) + { + SetUInt64Value (UNIT_FIELD_TARGET,0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) + SetUInt32Value(UNIT_NPC_FLAGS, 0); + + if(!isPet() && GetCreatureInfo()->SkinLootId) + if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) ) + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + + Unit::setDeathState(CORPSE); + } + if(s == JUST_ALIVED) + { + SetHealth(GetMaxHealth()); + SetLootRecipient(NULL); + Unit::setDeathState(ALIVE); + CreatureInfo const *cinfo = GetCreatureInfo(); + SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); + RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); + clearUnitState(UNIT_STAT_ALL_STATE); + i_motionMaster.Clear(); + SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); + LoadCreaturesAddon(true); + } +} + +void Creature::Respawn() +{ + RemoveCorpse(); + + // forced recreate creature object at clients + UnitVisibility currentVis = GetVisibility(); + SetVisibility(VISIBILITY_RESPAWN); + ObjectAccessor::UpdateObjectVisibility(this); + SetVisibility(currentVis); // restore visibility state + ObjectAccessor::UpdateObjectVisibility(this); + + if(getDeathState()==DEAD) + { + if (m_DBTableGuid) + objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); + m_respawnTime = time(NULL); // respawn at next tick + } +} + +bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges) +{ + if (!spellInfo) + return false; + + if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) + return true; + + return Unit::IsImmunedToSpell(spellInfo, useCharges); +} + +bool Creature::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const +{ + if (GetCreatureInfo()->MechanicImmuneMask & (1 << (mechanic-1))) + return true; + + return Unit::IsImmunedToSpellEffect(effect, mechanic); +} + +SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) +{ + if(!pVictim) + return NULL; + + for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++) + { + if(!m_spells[i]) + continue; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] ); + if(!spellInfo) + { + sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]); + continue; + } + + bool bcontinue = true; + for(uint32 j=0;j<3;j++) + { + if( (spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ) || + (spellInfo->Effect[j] == SPELL_EFFECT_INSTAKILL) || + (spellInfo->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) || + (spellInfo->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ) + ) + { + bcontinue = false; + break; + } + } + if(bcontinue) continue; + + if(spellInfo->manaCost > GetPower(POWER_MANA)) + continue; + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); + float range = GetSpellMaxRange(srange); + float minrange = GetSpellMinRange(srange); + float dist = GetDistance(pVictim); + //if(!isInFront( pVictim, range ) && spellInfo->AttributesEx ) + // continue; + if( dist > range || dist < minrange ) + continue; + if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) + continue; + return spellInfo; + } + return NULL; +} + +SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim) +{ + if(!pVictim) + return NULL; + + for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++) + { + if(!m_spells[i]) + continue; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] ); + if(!spellInfo) + { + sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]); + continue; + } + + bool bcontinue = true; + for(uint32 j=0;j<3;j++) + { + if( (spellInfo->Effect[j] == SPELL_EFFECT_HEAL ) ) + { + bcontinue = false; + break; + } + } + if(bcontinue) continue; + + if(spellInfo->manaCost > GetPower(POWER_MANA)) + continue; + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); + float range = GetSpellMaxRange(srange); + float minrange = GetSpellMinRange(srange); + float dist = GetDistance(pVictim); + //if(!isInFront( pVictim, range ) && spellInfo->AttributesEx ) + // continue; + if( dist > range || dist < minrange ) + continue; + if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) + continue; + return spellInfo; + } + return NULL; +} + +bool Creature::IsVisibleInGridForPlayer(Player* pl) const +{ + // gamemaster in GM mode see all, including ghosts + if(pl->isGameMaster()) + return true; + + // Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0 + if(pl->isAlive() || pl->GetDeathTimer() > 0) + { + if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INVISIBLE) + return false; + return isAlive() || m_deathTimer > 0 || m_isDeadByDefault && m_deathState==CORPSE; + } + + // Dead player see live creatures near own corpse + if(isAlive()) + { + Corpse *corpse = pl->GetCorpse(); + if(corpse) + { + // 20 - aggro distance for same level, 25 - max additional distance if player level less that creature level + if(corpse->IsWithinDistInMap(this,(20+25)*sWorld.getRate(RATE_CREATURE_AGGRO))) + return true; + } + } + + // Dead player see Spirit Healer or Spirit Guide + if(isSpiritService()) + return true; + + // and not see any other + return false; +} + +void Creature::CallAssistence() +{ + if( !m_AlreadyCallAssistence && getVictim() && !isPet() && !isCharmed()) + { + SetNoCallAssistence(true); + + float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTEMCE_RADIUS); + if(radius > 0) + { + std::list assistList; + + { + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius); + MaNGOS::CreatureListSearcher searcher(assistList, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(GetMapId(), this)); + } + + for(std::list::iterator iter = assistList.begin(); iter != assistList.end(); ++iter) + { + (*iter)->SetNoCallAssistence(true); + if((*iter)->AI()) + (*iter)->AI()->AttackStart(getVictim()); + } + } + } +} + +void Creature::SaveRespawnTime() +{ + if(isPet() || !m_DBTableGuid) + return; + + if(m_respawnTime > time(NULL)) // dead (no corpse) + objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime); + else if(m_deathTimer > 0) // dead (corpse) + objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/1000); +} + +bool Creature::IsOutOfThreatArea(Unit* pVictim) const +{ + if(!pVictim) + return true; + + if(!pVictim->IsInMap(this)) + return true; + + if(!pVictim->isTargetableForAttack()) + return true; + + if(!pVictim->isInAccessablePlaceFor(this)) + return true; + + if(sMapStore.LookupEntry(GetMapId())->Instanceable()) + return false; + + float length = pVictim->GetDistance(CombatStartX,CombatStartY,CombatStartZ); + float AttackDist = GetAttackDistance(pVictim); + uint32 ThreatRadius = sWorld.getConfig(CONFIG_THREAT_RADIUS); + + //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and ouf of combat every update tick. + return ( length > (ThreatRadius > AttackDist ? ThreatRadius : AttackDist)); +} + +CreatureDataAddon const* Creature::GetCreatureAddon() const +{ + if (m_DBTableGuid) + { + if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid)) + return addon; + } + + // dependent from heroic mode entry + return ObjectMgr::GetCreatureTemplateAddon(GetCreatureInfo()->Entry); +} + +//creature_addon table +bool Creature::LoadCreaturesAddon(bool reload) +{ + CreatureDataAddon const *cainfo = GetCreatureAddon(); + if(!cainfo) + return false; + + if (cainfo->mount != 0) + Mount(cainfo->mount); + + if (cainfo->bytes0 != 0) + SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0); + + if (cainfo->bytes1 != 0) + SetUInt32Value(UNIT_FIELD_BYTES_1, cainfo->bytes1); + + if (cainfo->bytes2 != 0) + SetUInt32Value(UNIT_FIELD_BYTES_2, cainfo->bytes2); + + if (cainfo->emote != 0) + SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote); + + if (cainfo->move_flags != 0) + SetUnitMovementFlags(cainfo->move_flags); + + if(cainfo->auras) + { + for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura) + { + SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura->spell_id); + if (!AdditionalSpellInfo) + { + sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u ) has wrong spell %u defined in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id); + continue; + } + + // skip already applied aura + if(HasAura(cAura->spell_id,cAura->effect_idx)) + { + if(!reload) + sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u ) has duplicate aura (spell %u effect %u) in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id,cAura->effect_idx); + + continue; + } + + Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0); + AddAura(AdditionalAura); + sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[0],GetGUIDLow(),GetEntry()); + } + } + return true; +} + +/// Send a message to LocalDefense channel for players oposition team in the zone +void Creature::SendZoneUnderAttackMessage(Player* attacker) +{ + uint32 enemy_team = attacker->GetTeam(); + + WorldPacket data(SMSG_ZONE_UNDER_ATTACK,4); + data << (uint32)GetZoneId(); + sWorld.SendGlobalMessage(&data,NULL,(enemy_team==ALLIANCE ? HORDE : ALLIANCE)); +} + +void Creature::_AddCreatureSpellCooldown(uint32 spell_id, time_t end_time) +{ + m_CreatureSpellCooldowns[spell_id] = end_time; +} + +void Creature::_AddCreatureCategoryCooldown(uint32 category, time_t apply_time) +{ + m_CreatureCategoryCooldowns[category] = apply_time; +} + +void Creature::AddCreatureSpellCooldown(uint32 spellid) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); + if(!spellInfo) + return; + + uint32 cooldown = GetSpellRecoveryTime(spellInfo); + if(cooldown) + _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/1000); + + if(spellInfo->Category) + _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL)); + + m_GlobalCooldown = spellInfo->StartRecoveryTime; +} + +bool Creature::HasCategoryCooldown(uint32 spell_id) const +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if(!spellInfo) + return false; + + // check global cooldown if spell affected by it + if (spellInfo->StartRecoveryCategory > 0 && m_GlobalCooldown > 0) + return true; + + CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category); + return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / 1000)) > time(NULL)); +} + +bool Creature::HasSpellCooldown(uint32 spell_id) const +{ + CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id); + return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id); +} + +bool Creature::IsInEvadeMode() const +{ + return !i_motionMaster.empty() && i_motionMaster.GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE; +} + +bool Creature::HasSpell(uint32 spellID) const +{ + uint8 i; + for(i = 0; i < CREATURE_MAX_SPELLS; ++i) + if(spellID == m_spells[i]) + break; + return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells +} + +time_t Creature::GetRespawnTimeEx() const +{ + time_t now = time(NULL); + if(m_respawnTime > now) // dead (no corpse) + return m_respawnTime; + else if(m_deathTimer > 0) // dead (corpse) + return now+m_respawnDelay+m_deathTimer/1000; + else + return now; +} + +void Creature::GetRespawnCoord( float &x, float &y, float &z, float* ori, float* dist ) const +{ + if (m_DBTableGuid) + { + if (CreatureData const* data = objmgr.GetCreatureData(GetDBTableGUIDLow())) + { + x = data->posX; + y = data->posY; + z = data->posZ; + if(ori) + *ori = data->orientation; + if(dist) + *dist = data->spawndist; + + return; + } + } + + x = GetPositionX(); + y = GetPositionY(); + z = GetPositionZ(); + if(ori) + *ori = GetOrientation(); + if(dist) + *dist = 0; +} + +void Creature::AllLootRemovedFromCorpse() +{ + if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE)) + { + uint32 nDeathTimer; + + CreatureInfo const *cinfo = GetCreatureInfo(); + + // corpse was not skinnable -> apply corpse looted timer + if (!cinfo || !cinfo->SkinLootId) + nDeathTimer = (uint32)((m_corpseDelay * 1000) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED)); + // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update + else + nDeathTimer = 0; + + // update death timer only if looted timer is shorter + if (m_deathTimer > nDeathTimer) + m_deathTimer = nDeathTimer; + } +} + +uint32 Creature::getLevelForTarget( Unit const* target ) const +{ + if(!isWorldBoss()) + return Unit::getLevelForTarget(target); + + uint32 level = target->getLevel()+sWorld.getConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF); + if(level < 1) + return 1; + if(level > 255) + return 255; + return level; +} + +char const* Creature::GetScriptName() const +{ + return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptName; +} + +VendorItemData const* Creature::GetVendorItems() const +{ + return objmgr.GetNpcVendorItemList(GetEntry()); +} + +uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem) +{ + if(!vItem->maxcount) + return vItem->maxcount; + + VendorItemCounts::iterator itr = m_vendorItemCounts.begin(); + for(; itr != m_vendorItemCounts.end(); ++itr) + if(itr->itemId==vItem->item) + break; + + if(itr == m_vendorItemCounts.end()) + return vItem->maxcount; + + VendorItemCount* vCount = &*itr; + + time_t ptime = time(NULL); + + if( vCount->lastIncrementTime + vItem->incrtime <= ptime ) + { + ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item); + + uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime); + if((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount ) + { + m_vendorItemCounts.erase(itr); + return vItem->maxcount; + } + + vCount->count += diff * pProto->BuyCount; + vCount->lastIncrementTime = ptime; + } + + return vCount->count; +} + +uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count) +{ + if(!vItem->maxcount) + return 0; + + VendorItemCounts::iterator itr = m_vendorItemCounts.begin(); + for(; itr != m_vendorItemCounts.end(); ++itr) + if(itr->itemId==vItem->item) + break; + + if(itr == m_vendorItemCounts.end()) + { + uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount-used_count : 0; + m_vendorItemCounts.push_back(VendorItemCount(vItem->item,new_count)); + return new_count; + } + + VendorItemCount* vCount = &*itr; + + time_t ptime = time(NULL); + + if( vCount->lastIncrementTime + vItem->incrtime <= ptime ) + { + ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item); + + uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime); + if((vCount->count + diff * pProto->BuyCount) < vItem->maxcount ) + vCount->count += diff * pProto->BuyCount; + else + vCount->count = vItem->maxcount; + } + + vCount->count = vCount->count > used_count ? vCount->count-used_count : 0; + vCount->lastIncrementTime = ptime; + return vCount->count; +} + +TrainerSpellData const* Creature::GetTrainerSpells() const +{ + return objmgr.GetNpcTrainerSpells(GetEntry()); +} diff --git a/src/game/Creature.h b/src/game/Creature.h new file mode 100644 index 000000000..5d0ff9cf7 --- /dev/null +++ b/src/game/Creature.h @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_CREATURE_H +#define MANGOSSERVER_CREATURE_H + +#include "Common.h" +#include "Unit.h" +#include "UpdateMask.h" +#include "ItemPrototype.h" +#include "LootMgr.h" +#include "Database/DatabaseEnv.h" +#include "Cell.h" + +struct SpellEntry; + +class CreatureAI; +class Quest; +class Player; +class WorldSession; + +enum Gossip_Option +{ + GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0, + GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP = 1, + GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER = 2, + GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR = 4, + GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR = 8, + GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER = 16, + GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER = 32, + GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE = 64, + GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER = 128, + GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER = 256, + GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER = 512, + GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER = 1024, + GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON = 2048, + GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER = 4096, + GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE = 8192, + GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER = 16384, + GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) + GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) +}; + +enum Gossip_Guard +{ + GOSSIP_GUARD_BANK = 32, + GOSSIP_GUARD_RIDE = 33, + GOSSIP_GUARD_GUILD = 34, + GOSSIP_GUARD_INN = 35, + GOSSIP_GUARD_MAIL = 36, + GOSSIP_GUARD_AUCTION = 37, + GOSSIP_GUARD_WEAPON = 38, + GOSSIP_GUARD_STABLE = 39, + GOSSIP_GUARD_BATTLE = 40, + GOSSIP_GUARD_SPELLTRAINER = 41, + GOSSIP_GUARD_SKILLTRAINER = 42 +}; + +enum Gossip_Guard_Spell +{ + GOSSIP_GUARD_SPELL_WARRIOR = 64, + GOSSIP_GUARD_SPELL_PALADIN = 65, + GOSSIP_GUARD_SPELL_HUNTER = 66, + GOSSIP_GUARD_SPELL_ROGUE = 67, + GOSSIP_GUARD_SPELL_PRIEST = 68, + GOSSIP_GUARD_SPELL_UNKNOWN1 = 69, + GOSSIP_GUARD_SPELL_SHAMAN = 70, + GOSSIP_GUARD_SPELL_MAGE = 71, + GOSSIP_GUARD_SPELL_WARLOCK = 72, + GOSSIP_GUARD_SPELL_UNKNOWN2 = 73, + GOSSIP_GUARD_SPELL_DRUID = 74 +}; + +enum Gossip_Guard_Skill +{ + GOSSIP_GUARD_SKILL_ALCHEMY = 80, + GOSSIP_GUARD_SKILL_BLACKSMITH = 81, + GOSSIP_GUARD_SKILL_COOKING = 82, + GOSSIP_GUARD_SKILL_ENCHANT = 83, + GOSSIP_GUARD_SKILL_FIRSTAID = 84, + GOSSIP_GUARD_SKILL_FISHING = 85, + GOSSIP_GUARD_SKILL_HERBALISM = 86, + GOSSIP_GUARD_SKILL_LEATHER = 87, + GOSSIP_GUARD_SKILL_MINING = 88, + GOSSIP_GUARD_SKILL_SKINNING = 89, + GOSSIP_GUARD_SKILL_TAILORING = 90, + GOSSIP_GUARD_SKILL_ENGINERING = 91 +}; + +struct GossipOption +{ + uint32 Id; + uint32 GossipId; + uint32 NpcFlag; + uint32 Icon; + uint32 Action; + std::string Option; +}; + +enum CreatureFlagsExtra +{ + CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group + CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility) + CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry + CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry + CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block + CREATURE_FLAG_EXTRA_NO_CRUSH = 0x00000020, // creature can't do crush attacks + CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP + CREATURE_FLAG_EXTRA_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures) +}; + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +// from `creature_template` table +struct CreatureInfo +{ + uint32 Entry; + uint32 HeroicEntry; + uint32 DisplayID_A; + uint32 DisplayID_A2; + uint32 DisplayID_H; + uint32 DisplayID_H2; + char* Name; + char* SubName; + char* IconName; + uint32 minlevel; + uint32 maxlevel; + uint32 minhealth; + uint32 maxhealth; + uint32 minmana; + uint32 maxmana; + uint32 armor; + uint32 faction_A; + uint32 faction_H; + uint32 npcflag; + float speed; + float scale; + uint32 rank; + float mindmg; + float maxdmg; + uint32 dmgschool; + uint32 attackpower; + uint32 baseattacktime; + uint32 rangeattacktime; + uint32 Flags; + uint32 dynamicflags; + uint32 family; + uint32 trainer_type; + uint32 trainer_spell; + uint32 classNum; + uint32 race; + float minrangedmg; + float maxrangedmg; + uint32 rangedattackpower; + uint32 type; + uint32 flag1; + uint32 lootid; + uint32 pickpocketLootId; + uint32 SkinLootId; + int32 resistance1; + int32 resistance2; + int32 resistance3; + int32 resistance4; + int32 resistance5; + int32 resistance6; + uint32 spell1; + uint32 spell2; + uint32 spell3; + uint32 spell4; + uint32 PetSpellDataId; + uint32 mingold; + uint32 maxgold; + char const* AIName; + uint32 MovementType; + uint32 InhabitType; + bool RacialLeader; + bool RegenHealth; + uint32 equipmentId; + uint32 MechanicImmuneMask; + uint32 flags_extra; + char const* ScriptName; +}; + +struct CreatureLocale +{ + std::vector Name; + std::vector SubName; +}; + +struct EquipmentInfo +{ + uint32 entry; + uint32 equipmodel[3]; + uint32 equipinfo[3]; + uint32 equipslot[3]; +}; + +// from `creature` table +struct CreatureData +{ + uint32 id; // entry in creature_template + uint16 mapid; + uint32 displayid; + int32 equipmentId; + float posX; + float posY; + float posZ; + float orientation; + uint32 spawntimesecs; + float spawndist; + uint32 currentwaypoint; + uint32 curhealth; + uint32 curmana; + bool is_dead; + uint8 movementType; + uint8 spawnMask; +}; + +struct CreatureDataAddonAura +{ + uint16 spell_id; + uint8 effect_idx; +}; + +// from `creature_addon` table +struct CreatureDataAddon +{ + uint32 guidOrEntry; + uint32 mount; + uint32 bytes0; + uint32 bytes1; + uint32 bytes2; + uint32 emote; + uint32 move_flags; + CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... " +}; + +struct CreatureModelInfo +{ + uint32 modelid; + float bounding_radius; + float combat_reach; + uint8 gender; + uint32 modelid_other_gender; +}; + +enum InhabitTypeValues +{ + INHABIT_GROUND = 1, + INHABIT_WATER = 2, + INHABIT_AIR = 4, + INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR +}; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif + +// Vendors +struct VendorItem +{ + VendorItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost) + : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {} + + uint32 item; + uint32 maxcount; // 0 for infinity item amount + uint32 incrtime; // time for restore items amount if maxcount != 0 + uint32 ExtendedCost; +}; +typedef std::vector VendorItemList; + +struct VendorItemData +{ + VendorItemList m_items; + + VendorItem* GetItem(uint32 slot) const + { + if(slot>=m_items.size()) return NULL; + return m_items[slot]; + } + bool Empty() const { return m_items.empty(); } + uint8 GetItemCount() const { return m_items.size(); } + void AddItem( uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost) + { + m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost)); + } + bool RemoveItem( uint32 item_id ); + VendorItem const* FindItem(uint32 item_id) const; + size_t FindItemSlot(uint32 item_id) const; + + void Clear() + { + for (VendorItemList::iterator itr = m_items.begin(); itr != m_items.end(); ++itr) + delete (*itr); + } +}; + +struct VendorItemCount +{ + explicit VendorItemCount(uint32 _item, uint32 _count) + : itemId(_item), count(_count), lastIncrementTime(time(NULL)) {} + + uint32 itemId; + uint32 count; + time_t lastIncrementTime; +}; + +typedef std::list VendorItemCounts; + +struct TrainerSpell +{ + uint32 spell; + uint32 spellcost; + uint32 reqskill; + uint32 reqskillvalue; + uint32 reqlevel; +}; + +typedef std::vector TrainerSpellList; + +struct TrainerSpellData +{ + TrainerSpellData() : trainerType(0) {} + + TrainerSpellList spellList; + uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value. + // req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2. + + void Clear(); + TrainerSpell const* Find(uint32 spell_id) const; +}; + +typedef std::list GossipOptionList; + +typedef std::map CreatureSpellCooldowns; + +// max different by z coordinate for creature aggro reaction +#define CREATURE_Z_ATTACK_RANGE 3 + +#define MAX_VENDOR_ITEMS 255 // Limitation in item count field size in SMSG_LIST_INVENTORY + +class MANGOS_DLL_SPEC Creature : public Unit +{ + CreatureAI *i_AI; + + public: + + explicit Creature(); + virtual ~Creature(); + + void AddToWorld(); + void RemoveFromWorld(); + + bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data = NULL); + bool LoadCreaturesAddon(bool reload = false); + void SelectLevel(const CreatureInfo *cinfo); + void LoadEquipment(uint32 equip_entry, bool force=false); + + uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } + char const* GetSubName() const { return GetCreatureInfo()->SubName; } + + void Update( uint32 time ); // overwrited Unit::Update + void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const; + uint32 GetEquipmentId() const { return m_equipmentId; } + + bool isPet() const { return m_isPet; } + void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; } + bool isTotem() const { return m_isTotem; } + bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; } + bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; } + bool canWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; } + bool canSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; } + bool canFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; } + ///// TODO RENAME THIS!!!!! + bool isCanTrainingOf(Player* player, bool msg) const; + bool isCanIneractWithBattleMaster(Player* player, bool msg) const; + bool isCanTrainingAndResetTalentsOf(Player* pPlayer) const; + bool IsOutOfThreatArea(Unit* pVictim) const; + bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false); + // redefine Unit::IsImmunedToSpell + bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const; + // redefine Unit::IsImmunedToSpellEffect + bool isElite() const + { + if(isPet()) + return false; + + uint32 rank = GetCreatureInfo()->rank; + return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE; + } + + bool isWorldBoss() const + { + if(isPet()) + return false; + + return GetCreatureInfo()->rank == CREATURE_ELITE_WORLDBOSS; + } + + uint32 getLevelForTarget(Unit const* target) const; // overwrite Unit::getLevelForTarget for boss level support + + bool IsInEvadeMode() const; + + bool AIM_Initialize(); + + void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type); + CreatureAI* AI() { return i_AI; } + + uint32 GetShieldBlockValue() const //dunno mob block value + { + return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20)); + } + + SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; } + void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); } + + void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time); + void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time); + void AddCreatureSpellCooldown(uint32 spellid); + bool HasSpellCooldown(uint32 spell_id) const; + bool HasCategoryCooldown(uint32 spell_id) const; + + bool HasSpell(uint32 spellID) const; + + bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); + bool UpdateStats(Stats stat); + bool UpdateAllStats(); + void UpdateResistances(uint32 school); + void UpdateArmor(); + void UpdateMaxHealth(); + void UpdateMaxPower(Powers power); + void UpdateAttackPowerAndDamage(bool ranged = false); + void UpdateDamagePhysical(WeaponAttackType attType); + uint32 GetCurrentEquipmentId() { return m_equipmentId; } + float GetSpellDamageMod(int32 Rank); + + VendorItemData const* GetVendorItems() const; + uint32 GetVendorItemCurrentCount(VendorItem const* vItem); + uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count); + + TrainerSpellData const* GetTrainerSpells() const; + + CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; } + CreatureDataAddon const* GetCreatureAddon() const; + char const* GetScriptName() const; + + void prepareGossipMenu( Player *pPlayer,uint32 gossipid ); + void sendPreparedGossip( Player* player); + void OnGossipSelect(Player* player, uint32 option); + void OnPoiSelect(Player* player, GossipOption const *gossip); + + uint32 GetGossipTextId(uint32 action, uint32 zoneid); + uint32 GetNpcTextId(); + void LoadGossipOptions(); + GossipOption const* GetGossipOption( uint32 id ) const; + void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); } + + void setEmoteState(uint8 emote) { m_emoteState = emote; }; + void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); } + void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); } + void TextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(text,TargetGuid,IsBossEmote); } + void Whisper(const char* text, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(text,receiver,IsBossWhisper); } + void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } + void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } + void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); } + void Whisper(int32 textId, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(textId,receiver,IsBossWhisper); } + + void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState + + bool LoadFromDB(uint32 guid, Map *map); + void SaveToDB(); + // overwrited in Pet + virtual void SaveToDB(uint32 mapid, uint8 spawnMask); + virtual void DeleteFromDB(); // overwrited in Pet + + Loot loot; + bool lootForPickPocketed; + bool lootForBody; + Player *GetLootRecipient() const; + bool hasLootRecipient() const { return m_lootRecipient!=0; } + + void SetLootRecipient (Unit* unit); + void AllLootRemovedFromCorpse(); + + SpellEntry const *reachWithSpellAttack(Unit *pVictim); + SpellEntry const *reachWithSpellCure(Unit *pVictim); + + uint32 m_spells[CREATURE_MAX_SPELLS]; + CreatureSpellCooldowns m_CreatureSpellCooldowns; + CreatureSpellCooldowns m_CreatureCategoryCooldowns; + uint32 m_GlobalCooldown; + + float GetAttackDistance(Unit const* pl) const; + + void CallAssistence(); + void SetNoCallAssistence(bool val) { m_AlreadyCallAssistence = val; } + + MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; } + void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; } + + // for use only in LoadHelper, Map::Add Map::CreatureCellRelocation + Cell const& GetCurrentCell() const { return m_currentCell; } + void SetCurrentCell(Cell const& cell) { m_currentCell = cell; } + + bool IsVisibleInGridForPlayer(Player* pl) const; + + void RemoveCorpse(); + + time_t const& GetRespawnTime() const { return m_respawnTime; } + time_t GetRespawnTimeEx() const; + void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; } + void Respawn(); + void SaveRespawnTime(); + + uint32 GetRespawnDelay() const { return m_respawnDelay; } + void SetRespawnDelay(uint32 delay) { m_respawnDelay = delay; } + + float GetRespawnRadius() const { return m_respawnradius; } + void SetRespawnRadius(float dist) { m_respawnradius = dist; } + + uint32 m_groupLootTimer; // (msecs)timer used for group loot + uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse + + void SendZoneUnderAttackMessage(Player* attacker); + + bool hasQuest(uint32 quest_id) const; + bool hasInvolvedQuest(uint32 quest_id) const; + + GridReference &GetGridRef() { return m_gridRef; } + bool isRegeneratingHealth() { return m_regenHealth; } + virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; } + virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const + { + if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->active != ACT_ENABLED) + return 0; + else + return m_charmInfo->GetCharmSpell(pos)->spellId; + } + + void SetCombatStartPosition(float x, float y, float z) { CombatStartX = x; CombatStartY = y; CombatStartZ = z; } + void GetCombatStartPosition(float &x, float &y, float &z) { x = CombatStartX; y = CombatStartY; z = CombatStartZ; } + + protected: + bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL); + bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); + + // vendor items + VendorItemCounts m_vendorItemCounts; + + void _RealtimeSetCreatureInfo(); + + static float _GetHealthMod(int32 Rank); + static float _GetDamageMod(int32 Rank); + + uint32 m_lootMoney; + uint64 m_lootRecipient; + + /// Timers + uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance + time_t m_respawnTime; // (secs) time of next respawn + uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning + uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance + float m_respawnradius; + + bool m_gossipOptionLoaded; + GossipOptionList m_goptions; + + uint8 m_emoteState; + bool m_isPet; // set only in Pet::Pet + bool m_isTotem; // set only in Totem::Totem + void RegenerateMana(); + void RegenerateHealth(); + uint32 m_regenTimer; + MovementGeneratorType m_defaultMovementType; + Cell m_currentCell; // store current cell where creature listed + uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid + uint32 m_equipmentId; + + bool m_AlreadyCallAssistence; + bool m_regenHealth; + bool m_AI_locked; + bool m_isDeadByDefault; + + SpellSchoolMask m_meleeDamageSchoolMask; + uint32 m_originalEntry; + + float CombatStartX; + float CombatStartY; + float CombatStartZ; + private: + GridReference m_gridRef; + CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry()) +}; +#endif diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp new file mode 100644 index 000000000..a66cc4278 --- /dev/null +++ b/src/game/CreatureAI.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "CreatureAI.h" +#include "HateMatrix.h" + +CreatureAI::~CreatureAI() +{ +} + +uint32 HateBinder::si_noHateValue=0; diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h new file mode 100644 index 000000000..5b4ed0545 --- /dev/null +++ b/src/game/CreatureAI.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CREATUREAI_H +#define MANGOS_CREATUREAI_H + +#include "Common.h" +#include "Platform/Define.h" +#include "Policies/Singleton.h" +#include "Dynamic/ObjectRegistry.h" +#include "Dynamic/FactoryHolder.h" + +class Unit; +class Creature; +struct SpellEntry; + +#define TIME_INTERVAL_LOOK 5000 +#define VISIBILITY_RANGE 10000 + +class MANGOS_DLL_SPEC CreatureAI +{ + public: + + virtual ~CreatureAI(); + + // Called if IsVisible(Unit *who) is true at each *who move + virtual void MoveInLineOfSight(Unit *) = 0; + + // Called at each attack of m_creature by any victim + virtual void AttackStart(Unit *) = 0; + + // Called at stopping attack by any attacker + virtual void EnterEvadeMode() = 0; + + // Called at any heal cast/item used (call non implemented) + virtual void HealBy(Unit * /*healer*/, uint32 /*amount_healed*/) {} + + // Called at any Damage to any victim (before damage apply) + virtual void DamageDeal(Unit * /*done_to*/, uint32 & /*damage*/) {} + + // Called at any Damage from any attacker (before damage apply) + virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) { AttackedBy(done_by); } + + // Is unit visible for MoveInLineOfSight + virtual bool IsVisible(Unit *) const = 0; + + // Called at World update tick + virtual void UpdateAI(const uint32 diff ) = 0; + + // Called when the creature is killed + virtual void JustDied(Unit *) {} + + // Called when the creature kills a unit + virtual void KilledUnit(Unit *) {} + + // Called when the creature summon successfully other creature + virtual void JustSummoned(Creature* ) {} + + virtual void SummonedCreatureDespawn(Creature* /*unit*/) {} + + // Called when hit by a spell + virtual void SpellHit(Unit*, const SpellEntry*) {} + + // Called when vitim entered water and creature can not enter water + virtual bool canReachByRangeAttack(Unit*) { return false; } + + // Called when the creature is attacked + virtual void AttackedBy(Unit * /*attacker*/) {} + + // Called when creature is spawned or respawned (for reseting variables) + virtual void JustRespawned() {} + + // Called at waypoint reached or point movement finished + virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {} +}; + +struct SelectableAI : public FactoryHolder, public Permissible +{ + + SelectableAI(const char *id) : FactoryHolder(id) {} +}; + +template +struct CreatureAIFactory : public SelectableAI +{ + CreatureAIFactory(const char *name) : SelectableAI(name) {} + + CreatureAI* Create(void *) const; + + int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } +}; + +enum Permitions +{ + PERMIT_BASE_NO = -1, + PERMIT_BASE_IDLE = 1, + PERMIT_BASE_REACTIVE = 100, + PERMIT_BASE_PROACTIVE = 200, + PERMIT_BASE_FACTION_SPECIFIC = 400, + PERMIT_BASE_SPECIAL = 800 +}; + +typedef FactoryHolder CreatureAICreator; +typedef FactoryHolder::FactoryHolderRegistry CreatureAIRegistry; +typedef FactoryHolder::FactoryHolderRepository CreatureAIRepository; +#endif diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h new file mode 100644 index 000000000..c9f22a730 --- /dev/null +++ b/src/game/CreatureAIImpl.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef CREATUREAIIMPL_H +#define CREATUREAIIMPL_H + +#include "CreatureAI.h" + +template +inline CreatureAI* +CreatureAIFactory::Create(void *data) const +{ + Creature* creature = reinterpret_cast(data); + return (new REAL_AI(*creature)); +} +#endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp new file mode 100644 index 000000000..b76a7211a --- /dev/null +++ b/src/game/CreatureAIRegistry.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "CreatureAIRegistry.h" +#include "NullCreatureAI.h" +#include "ReactorAI.h" +#include "AggressorAI.h" +#include "GuardAI.h" +#include "PetAI.h" +#include "TotemAI.h" +#include "RandomMovementGenerator.h" +#include "CreatureAIImpl.h" +#include "MovementGeneratorImpl.h" +#include "MapManager.h" +#include "CreatureAIRegistry.h" +#include "WaypointMovementGenerator.h" + +namespace AIRegistry +{ + void Initialize() + { + (new CreatureAIFactory("NullAI"))->RegisterSelf(); + (new CreatureAIFactory("AggressorAI"))->RegisterSelf(); + (new CreatureAIFactory("ReactorAI"))->RegisterSelf(); + (new CreatureAIFactory("GuardAI"))->RegisterSelf(); + (new CreatureAIFactory("PetAI"))->RegisterSelf(); + (new CreatureAIFactory("TotemAI"))->RegisterSelf(); + + (new MovementGeneratorFactory >(RANDOM_MOTION_TYPE))->RegisterSelf(); + (new MovementGeneratorFactory >(WAYPOINT_MOTION_TYPE))->RegisterSelf(); + } +} diff --git a/src/game/CreatureAIRegistry.h b/src/game/CreatureAIRegistry.h new file mode 100644 index 000000000..adf6d73ab --- /dev/null +++ b/src/game/CreatureAIRegistry.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CREATUREAIREGISTRY_H +#define MANGOS_CREATUREAIREGISTRY_H + +namespace AIRegistry +{ + void Initialize(void); +} +#endif diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp new file mode 100644 index 000000000..acec57eaf --- /dev/null +++ b/src/game/CreatureAISelector.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Creature.h" +#include "CreatureAIImpl.h" +#include "CreatureAISelector.h" +#include "NullCreatureAI.h" +#include "Policies/SingletonImp.h" +#include "MovementGenerator.h" +#include "ScriptCalls.h" +#include "Pet.h" + +INSTANTIATE_SINGLETON_1(CreatureAIRegistry); +INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry); + +namespace FactorySelector +{ + CreatureAI* selectAI(Creature *creature) + { + // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets) + if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed()) + if(CreatureAI* scriptedAI = Script->GetAI(creature)) + return scriptedAI; + + CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance()); + assert( creature->GetCreatureInfo() != NULL ); + CreatureInfo const *cinfo=creature->GetCreatureInfo(); + + const CreatureAICreator *ai_factory = NULL; + + std::string ainame=cinfo->AIName; + + // select by script name + if( !ainame.empty()) + ai_factory = ai_registry.GetRegistryItem( ainame.c_str() ); + + // select by NPC flags + if(!ai_factory) + { + if( creature->isGuard() ) + ai_factory = ai_registry.GetRegistryItem("GuardAI"); + else if(creature->isPet() || creature->isCharmed()) + ai_factory = ai_registry.GetRegistryItem("PetAI"); + else if(creature->isTotem()) + ai_factory = ai_registry.GetRegistryItem("TotemAI"); + } + + // select by permit check + if(!ai_factory) + { + int best_val = -1; + typedef CreatureAIRegistry::RegistryMapType RMT; + RMT const &l = ai_registry.GetRegisteredItems(); + for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter) + { + const CreatureAICreator *factory = iter->second; + const SelectableAI *p = dynamic_cast(factory); + assert( p != NULL ); + int val = p->Permit(creature); + if( val > best_val ) + { + best_val = val; + ai_factory = p; + } + } + } + + // select NullCreatureAI if not another cases + ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key(); + + DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() ); + return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) ); + } + + MovementGenerator* selectMovementGenerator(Creature *creature) + { + MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance()); + assert( creature->GetCreatureInfo() != NULL ); + const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType()); + + /* if( mv_factory == NULL ) + { + int best_val = -1; + std::vector l; + mv_registry.GetRegisteredItems(l); + for( std::vector::iterator iter = l.begin(); iter != l.end(); ++iter) + { + const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str()); + const SelectableMovement *p = dynamic_cast(factory); + assert( p != NULL ); + int val = p->Permit(creature); + if( val > best_val ) + { + best_val = val; + mv_factory = p; + } + } + }*/ + + return ( mv_factory == NULL ? NULL : mv_factory->Create(creature) ); + + } +} diff --git a/src/game/CreatureAISelector.h b/src/game/CreatureAISelector.h new file mode 100644 index 000000000..ed53a135c --- /dev/null +++ b/src/game/CreatureAISelector.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_CREATUREAISELECTOR_H +#define MANGOS_CREATUREAISELECTOR_H + +class CreatureAI; +class Creature; +class MovementGenerator; + +namespace FactorySelector +{ + CreatureAI* selectAI(Creature *); + MovementGenerator* selectMovementGenerator(Creature *); +} +#endif diff --git a/src/game/DestinationHolder.cpp b/src/game/DestinationHolder.cpp new file mode 100644 index 000000000..4c22ff824 --- /dev/null +++ b/src/game/DestinationHolder.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "DestinationHolder.h" diff --git a/src/game/DestinationHolder.h b/src/game/DestinationHolder.h new file mode 100644 index 000000000..bc6f4ac47 --- /dev/null +++ b/src/game/DestinationHolder.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_DESTINATION_HOLDER_H +#define MANGOS_DESTINATION_HOLDER_H + +#include "Platform/Define.h" +#include "Timer.h" + +class WorldObject; + +#define TRAVELLER_UPDATE_INTERVAL 300 + +template +class MANGOS_DLL_DECL DestinationHolder +{ + TimeTrackerSmall i_tracker; + uint32 i_totalTravelTime; + uint32 i_timeElapsed; + bool i_destSet; + float i_fromX, i_fromY, i_fromZ; + float i_destX, i_destY, i_destZ; + + public: + DestinationHolder() : i_tracker(TRAVELLER_UPDATE_INTERVAL), i_totalTravelTime(0), i_timeElapsed(0), + i_destSet(false), i_fromX(0), i_fromY(0), i_fromZ(0), i_destX(0), i_destY(0), i_destZ(0) {} + + uint32 SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove = true); + void GetDestination(float &x, float &y, float &z) const { x = i_destX; y = i_destY; z = i_destZ; } + bool UpdateExpired(void) const { return i_tracker.Passed(); } + void ResetUpdate(uint32 t = TRAVELLER_UPDATE_INTERVAL) { i_tracker.Reset(t); } + uint32 GetTotalTravelTime(void) const { return i_totalTravelTime; } + void IncreaseTravelTime(uint32 increment) { i_totalTravelTime += increment; } + bool HasDestination(void) const { return i_destSet; } + float GetDestinationDiff(float x, float y, float z) const; + bool HasArrived(void) const { return (i_totalTravelTime == 0 || i_timeElapsed >= i_totalTravelTime); } + bool UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update=false, bool micro_movement=false); + uint32 StartTravel(TRAVELLER &traveller, bool sendMove = true); + void GetLocationNow(uint32 mapid, float &x, float &y, float &z, bool is3D = false) const; + void GetLocationNowNoMicroMovement(float &x, float &y, float &z) const; // For use without micro movement + float GetDistance2dFromDestSq(const WorldObject &obj) const; + + private: + void _findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y); + +}; +#endif diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h new file mode 100644 index 000000000..3043c44e2 --- /dev/null +++ b/src/game/DestinationHolderImp.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_DESTINATIONHOLDERIMP_H +#define MANGOS_DESTINATIONHOLDERIMP_H + +#include "Creature.h" +#include "MapManager.h" +#include "DestinationHolder.h" + +#include + +template +void +DestinationHolder::_findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y) +{ + /* given the point (x1, y1) and (x2, y2).. need to find the point (x,y) on the same line + * such that the distance from (x, y) to (x2, y2) is offset. + * Let the distance of p1 to p2 = d.. then the ratio of offset/d = (x2-x)/(x2-x1) + * hence x = x2 - (offset/d)*(x2-x1) + * like wise offset/d = (y2-y)/(y2-y1); + */ + if( offset == 0 ) + { + x = x2; + y = y2; + } + else + { + double x_diff = double(x2 - x1); + double y_diff = double(y2 - y1); + double distance_d = (double)((x_diff*x_diff) + (y_diff * y_diff)); + if(distance_d == 0) + { + x = x2; + y = y2; + } + else + { + distance_d = ::sqrt(distance_d); // starting distance + double distance_ratio = (double)(distance_d - offset)/(double)distance_d; + // line above has revised formula which is more correct, I think + x = (float)(x1 + (distance_ratio*x_diff)); + y = (float)(y1 + (distance_ratio*y_diff)); + } + } +} + +template +uint32 +DestinationHolder::SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove) +{ + i_destSet = true; + i_destX = dest_x; + i_destY = dest_y; + i_destZ = dest_z; + + return StartTravel(traveller, sendMove); +} + +template +uint32 +DestinationHolder::StartTravel(TRAVELLER &traveller, bool sendMove) +{ + if(!i_destSet) return 0; + + i_fromX = traveller.GetPositionX(); + i_fromY = traveller.GetPositionY(); + i_fromZ = traveller.GetPositionZ(); + + float dx = i_destX - i_fromX; + float dy = i_destY - i_fromY; + float dz = i_destZ - i_fromZ; + + float dist; + //Should be for Creature Flying and Swimming. + if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT)) + dist = sqrt((dx*dx) + (dy*dy) + (dz*dz)); + else //Walking on the ground + dist = sqrt((dx*dx) + (dy*dy)); + float speed = traveller.Speed(); + + speed *= 0.001f; // speed is in seconds so convert from second to millisecond + i_totalTravelTime = static_cast(dist/speed); + i_timeElapsed = 0; + if(sendMove) + traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime); + return i_totalTravelTime; +} + +template +bool +DestinationHolder::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update, bool micro_movement) +{ + if(!micro_movement) + { + i_tracker.Update(diff); + i_timeElapsed += diff; + if( i_tracker.Passed() || force_update ) + { + ResetUpdate(); + if(!i_destSet) return true; + float x,y,z; + GetLocationNowNoMicroMovement(x, y, z); + if( x == -431602080 ) + return false; + if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y ) + { + float ori = traveller.GetTraveller().GetAngle(x, y); + traveller.Relocation(x, y, z, ori); + } + return true; + } + return false; + } + i_tracker.Update(diff); + i_timeElapsed += diff; + if( i_tracker.Passed() || force_update ) + { + ResetUpdate(); + if(!i_destSet) return true; + float x,y,z; + + if(!traveller.GetTraveller().hasUnitState(UNIT_STAT_MOVING | UNIT_STAT_IN_FLIGHT)) + return true; + + if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT)) + GetLocationNow(traveller.GetTraveller().GetMapId() ,x, y, z, true); // Should repositione Object with right Coord, so I can bypass some Grid Relocation + else + GetLocationNow(traveller.GetTraveller().GetMapId(), x, y, z, false); + + if( x == -431602080 ) + return false; + + if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y ) + { + float ori = traveller.GetTraveller().GetAngle(x, y); + traveller.Relocation(x, y, z, ori); + } + // Change movement computation to micro movement based on last tick coords, this makes system work + // even on multiple floors zones without hugh vmaps usage ;) + + // Take care of underrun of uint32 + if (i_totalTravelTime >= i_timeElapsed) + i_totalTravelTime -= i_timeElapsed; // Consider only the remaining part + else + i_totalTravelTime = 0; + + i_timeElapsed = 0; + i_fromX = x; // and change origine + i_fromY = y; // then I take into account only micro movement + i_fromZ = z; + return true; + } + return false; +} + +template +void +DestinationHolder::GetLocationNow(uint32 mapid, float &x, float &y, float &z, bool is3D) const +{ + if( HasArrived() ) + { + x = i_destX; + y = i_destY; + z = i_destZ; + } + else if(HasDestination()) + { + double percent_passed = (double)i_timeElapsed / (double)i_totalTravelTime; + const float distanceX = ((i_destX - i_fromX) * percent_passed); + const float distanceY = ((i_destY - i_fromY) * percent_passed); + const float distanceZ = ((i_destZ - i_fromZ) * percent_passed); + x = i_fromX + distanceX; + y = i_fromY + distanceY; + float z2 = i_fromZ + distanceZ; + // All that is not finished but previous code neither... Traveller need be able to swim. + if(is3D) + z = z2; + else + { + //That part is good for mob Walking on the floor. But the floor is not allways what we thought. + z = MapManager::Instance().GetBaseMap(mapid)->GetHeight(x,y,i_fromZ,false); // Disable cave check + const float groundDist = sqrt(distanceX*distanceX + distanceY*distanceY); + const float zDist = fabs(i_fromZ - z) + 0.000001f; + const float slope = groundDist / zDist; + if(slope < 1.0f) // This prevents the ground returned by GetHeight to be used when in cave + z = z2; // a climb or jump of more than 45 is denied + } + } +} + +template +float +DestinationHolder::GetDistance2dFromDestSq(const WorldObject &obj) const +{ + float x,y,z; + obj.GetPosition(x,y,z); + return (i_destX-x)*(i_destX-x)+(i_destY-y)*(i_destY-y); +} + +template +float +DestinationHolder::GetDestinationDiff(float x, float y, float z) const +{ + return sqrt(((x-i_destX)*(x-i_destX)) + ((y-i_destY)*(y-i_destY)) + ((z-i_destZ)*(z-i_destZ))); +} + +template +void +DestinationHolder::GetLocationNowNoMicroMovement(float &x, float &y, float &z) const +{ + if( HasArrived() ) + { + x = i_destX; + y = i_destY; + z = i_destZ; + } + else + { + double percent_passed = (double)i_timeElapsed / (double)i_totalTravelTime; + x = i_fromX + ((i_destX - i_fromX) * percent_passed); + y = i_fromY + ((i_destY - i_fromY) * percent_passed); + z = i_fromZ + ((i_destZ - i_fromZ) * percent_passed); + } +} + +#endif diff --git a/src/game/DuelHandler.cpp b/src/game/DuelHandler.cpp new file mode 100644 index 000000000..65d50ee87 --- /dev/null +++ b/src/game/DuelHandler.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Log.h" +#include "Opcodes.h" +#include "UpdateData.h" +#include "MapManager.h" +#include "Player.h" + +void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,8); + + uint64 guid; + Player *pl; + Player *plTarget; + + if(!GetPlayer()->duel) // ignore accept from duel-sender + return; + + recvPacket >> guid; + + pl = GetPlayer(); + plTarget = pl->duel->opponent; + + if(pl == pl->duel->initiator || !plTarget || pl == plTarget || pl->duel->startTime != 0 || plTarget->duel->startTime != 0) + return; + + //sLog.outDebug( "WORLD: received CMSG_DUEL_ACCEPTED" ); + DEBUG_LOG("Player 1 is: %u (%s)", pl->GetGUIDLow(),pl->GetName()); + DEBUG_LOG("Player 2 is: %u (%s)", plTarget->GetGUIDLow(),plTarget->GetName()); + + time_t now = time(NULL); + pl->duel->startTimer = now; + plTarget->duel->startTimer = now; + + WorldPacket data(SMSG_DUEL_COUNTDOWN, 4); + data << (uint32)3000; // 3 seconds + pl->GetSession()->SendPacket(&data); + plTarget->GetSession()->SendPacket(&data); +} + +void WorldSession::HandleDuelCancelledOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,8); + + //sLog.outDebug( "WORLD: received CMSG_DUEL_CANCELLED" ); + + // no duel requested + if(!GetPlayer()->duel) + return; + + // player surrendered in a duel using /forfeit + if(GetPlayer()->duel->startTime != 0) + { + GetPlayer()->CombatStopWithPets(true); + if(GetPlayer()->duel->opponent) + GetPlayer()->duel->opponent->CombatStopWithPets(true); + + GetPlayer()->CastSpell(GetPlayer(), 7267, true); // beg + GetPlayer()->DuelComplete(DUEL_WON); + return; + } + + // player either discarded the duel using the "discard button" + // or used "/forfeit" before countdown reached 0 + uint64 guid; + recvPacket >> guid; + + GetPlayer()->DuelComplete(DUEL_INTERUPTED); +} diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp new file mode 100644 index 000000000..86d621905 --- /dev/null +++ b/src/game/DynamicObject.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "GameObject.h" +#include "UpdateMask.h" +#include "Opcodes.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectAccessor.h" +#include "Database/DatabaseEnv.h" +#include "SpellAuras.h" +#include "MapManager.h" +#include "GridNotifiers.h" +#include "CellImpl.h" +#include "GridNotifiersImpl.h" + +DynamicObject::DynamicObject() : WorldObject() +{ + m_objectType |= TYPEMASK_DYNAMICOBJECT; + m_objectTypeId = TYPEID_DYNAMICOBJECT; + // 2.3.2 - 0x58 + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + + m_valuesCount = DYNAMICOBJECT_END; +} + +void DynamicObject::AddToWorld() +{ + ///- Register the dynamicObject for guid lookup + if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + Object::AddToWorld(); +} + +void DynamicObject::RemoveFromWorld() +{ + ///- Remove the dynamicObject from the accessor + if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + Object::RemoveFromWorld(); +} + +bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius ) +{ + SetInstanceId(caster->GetInstanceId()); + + WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId()); + Relocate(x,y,z,0); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effIndex,GetPositionX(),GetPositionY()); + return false; + } + + SetEntry(spellId); + SetFloatValue( OBJECT_FIELD_SCALE_X, 1 ); + SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() ); + SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 ); + SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId ); + SetFloatValue( DYNAMICOBJECT_RADIUS, radius); + SetFloatValue( DYNAMICOBJECT_POS_X, x ); + SetFloatValue( DYNAMICOBJECT_POS_Y, y ); + SetFloatValue( DYNAMICOBJECT_POS_Z, z ); + SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0 + + m_aliveDuration = duration; + m_radius = radius; + m_effIndex = effIndex; + m_spellId = spellId; + m_casterGuid = caster->GetGUID(); + return true; +} + +Unit* DynamicObject::GetCaster() const +{ + // can be not found in some cases + return ObjectAccessor::GetUnit(*this,m_casterGuid); +} + +void DynamicObject::Update(uint32 p_time) +{ + // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor + Unit* caster = GetCaster(); + if(!caster) + { + Delete(); + return; + } + + bool deleteThis = false; + + if(m_aliveDuration > int32(p_time)) + m_aliveDuration -= p_time; + else + deleteThis = true; + + // TODO: make a timer and update this in larger intervals + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::DynamicObjectUpdater notifier(*this,caster); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(GetMapId(), this)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(GetMapId(), this)); + + if(deleteThis) + { + caster->RemoveDynObjectWithGUID(GetGUID()); + Delete(); + } +} + +void DynamicObject::Delete() +{ + SendObjectDeSpawnAnim(GetGUID()); + AddObjectToRemoveList(); +} + +void DynamicObject::Delay(int32 delaytime) +{ + m_aliveDuration -= delaytime; + for(AffectedSet::iterator iunit= m_affected.begin();iunit != m_affected.end();++iunit) + if (*iunit) + (*iunit)->DelayAura(m_spellId, m_effIndex, delaytime); +} + +bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const +{ + return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); +} diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h new file mode 100644 index 000000000..9662397d2 --- /dev/null +++ b/src/game/DynamicObject.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_DYNAMICOBJECT_H +#define MANGOSSERVER_DYNAMICOBJECT_H + +#include "Object.h" + +class Unit; +struct SpellEntry; + +class DynamicObject : public WorldObject +{ + public: + typedef std::set AffectedSet; + explicit DynamicObject(); + + void AddToWorld(); + void RemoveFromWorld(); + + bool Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius); + void Update(uint32 p_time); + void Delete(); + uint32 GetSpellId() const { return m_spellId; } + uint32 GetEffIndex() const { return m_effIndex; } + uint32 GetDuration() const { return m_aliveDuration; } + uint64 GetCasterGUID() const { return m_casterGuid; } + Unit* GetCaster() const; + float GetRadius() const { return m_radius; } + bool IsAffecting(Unit *unit) const { return m_affected.find(unit) != m_affected.end(); } + void AddAffected(Unit *unit) { m_affected.insert(unit); } + void RemoveAffected(Unit *unit) { m_affected.erase(unit); } + void Delay(int32 delaytime); + bool isVisibleForInState(Player const* u, bool inVisibleList) const; + + void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); } + void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); } + void TextEmote(const char* text, uint64 TargetGuid) { MonsterTextEmote(text,TargetGuid); } + void Whisper(const char* text, uint64 receiver) { MonsterWhisper(text,receiver); } + void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } + void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } + void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); } + void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); } + + GridReference &GetGridRef() { return m_gridRef; } + protected: + uint64 m_casterGuid; + uint32 m_spellId; + uint32 m_effIndex; + int32 m_aliveDuration; + time_t m_nextThinkTime; + float m_radius; + AffectedSet m_affected; + private: + GridReference m_gridRef; +}; +#endif diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp new file mode 100644 index 000000000..d5c21f186 --- /dev/null +++ b/src/game/FleeingMovementGenerator.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Creature.h" +#include "MapManager.h" +#include "FleeingMovementGenerator.h" +#include "DestinationHolderImp.h" +#include "ObjectAccessor.h" + +#define MIN_QUIET_DISTANCE 28.0f +#define MAX_QUIET_DISTANCE 43.0f + +template +void +FleeingMovementGenerator::_setTargetLocation(T &owner) +{ + if( !&owner ) + return; + + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) ) + return; + + if(!_setMoveData(owner)) + return; + + float x, y, z; + if(!_getPoint(owner, x, y, z)) + return; + + owner.addUnitState(UNIT_STAT_FLEEING); + Traveller traveller(owner); + i_destinationHolder.SetDestination(traveller, x, y, z); +} + +template +bool +FleeingMovementGenerator::_getPoint(T &owner, float &x, float &y, float &z) +{ + if(!&owner) + return false; + + x = owner.GetPositionX(); + y = owner.GetPositionY(); + z = owner.GetPositionZ(); + + float temp_x, temp_y, angle; + const Map * _map = MapManager::Instance().GetBaseMap(owner.GetMapId()); + //primitive path-finding + for(uint8 i = 0; i < 18; i++) + { + if(i_only_forward && i > 2) + break; + + float distance = 5.0f; + + switch(i) + { + case 0: + angle = i_cur_angle; + break; + case 1: + angle = i_cur_angle; + distance /= 2; + break; + case 2: + angle = i_cur_angle; + distance /= 4; + break; + case 3: + angle = i_cur_angle + M_PI/4.0f; + break; + case 4: + angle = i_cur_angle - M_PI/4.0f; + break; + case 5: + angle = i_cur_angle + M_PI/4.0f; + distance /= 2; + break; + case 6: + angle = i_cur_angle - M_PI/4.0f; + distance /= 2; + break; + case 7: + angle = i_cur_angle + M_PI/2.0f; + break; + case 8: + angle = i_cur_angle - M_PI/2.0f; + break; + case 9: + angle = i_cur_angle + M_PI/2.0f; + distance /= 2; + break; + case 10: + angle = i_cur_angle - M_PI/2.0f; + distance /= 2; + break; + case 11: + angle = i_cur_angle + M_PI/4.0f; + distance /= 4; + break; + case 12: + angle = i_cur_angle - M_PI/4.0f; + distance /= 4; + break; + case 13: + angle = i_cur_angle + M_PI/2.0f; + distance /= 4; + break; + case 14: + angle = i_cur_angle - M_PI/2.0f; + distance /= 4; + break; + case 15: + angle = i_cur_angle + M_PI*3/4.0f; + distance /= 2; + break; + case 16: + angle = i_cur_angle - M_PI*3/4.0f; + distance /= 2; + break; + case 17: + angle = i_cur_angle + M_PI; + distance /= 2; + break; + } + temp_x = x + distance * cos(angle); + temp_y = y + distance * sin(angle); + MaNGOS::NormalizeMapCoord(temp_x); + MaNGOS::NormalizeMapCoord(temp_y); + if( owner.IsWithinLOS(temp_x,temp_y,z)) + { + bool is_water_now = _map->IsInWater(x,y,z); + + if(is_water_now && _map->IsInWater(temp_x,temp_y,z)) + { + x = temp_x; + y = temp_y; + return true; + } + float new_z = _map->GetHeight(temp_x,temp_y,z,true); + + if(new_z <= INVALID_HEIGHT) + continue; + + bool is_water_next = _map->IsInWater(temp_x,temp_y,new_z); + + if((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok)) + continue; + + if( !(new_z - z) || distance / fabs(new_z - z) > 1.0f) + { + float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+M_PI/2),temp_y + 1.0f*sin(angle+M_PI/2),z,true); + float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-M_PI/2),temp_y + 1.0f*sin(angle-M_PI/2),z,true); + if(fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f) + { + x = temp_x; + y = temp_y; + z = new_z; + return true; + } + } + } + } + i_to_distance_from_caster = 0.0f; + i_nextCheckTime.Reset( urand(500,1000) ); + return false; +} + +template +bool +FleeingMovementGenerator::_setMoveData(T &owner) +{ + float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z); + + if(i_to_distance_from_caster > 0.0f) + { + if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) || + // if we reach lower distance + (i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) || + // if we can't be close + (i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) || + // if we reach bigger distance + (cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far + (i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) ) + // if we leave 'quiet zone' + { + // we are very far or too close, stopping + i_to_distance_from_caster = 0.0f; + i_nextCheckTime.Reset( urand(500,1000) ); + return false; + } + else + { + // now we are running, continue + i_last_distance_from_caster = cur_dist_xyz; + return true; + } + } + + float cur_dist; + float angle_to_caster; + + Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID); + + if(fright) + { + cur_dist = fright->GetDistance(&owner); + if(cur_dist < cur_dist_xyz) + { + i_caster_x = fright->GetPositionX(); + i_caster_y = fright->GetPositionY(); + i_caster_z = fright->GetPositionZ(); + angle_to_caster = fright->GetAngle(&owner); + } + else + { + cur_dist = cur_dist_xyz; + angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI; + } + } + else + { + cur_dist = cur_dist_xyz; + angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI; + } + + // if we too close may use 'path-finding' else just stop + i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3; + + //get angle and 'distance from caster' to run + float angle; + + if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time + { + angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3; + i_to_distance_from_caster = MIN_QUIET_DISTANCE; + i_only_forward = true; + } + else if(cur_dist < MIN_QUIET_DISTANCE) + { + angle = M_PI/6 + rand_norm()*M_PI*2/3; + i_to_distance_from_caster = cur_dist*2/3 + rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3); + } + else if(cur_dist > MAX_QUIET_DISTANCE) + { + angle = rand_norm()*M_PI/3 + M_PI*2/3; + i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f); + } + else + { + angle = rand_norm()*M_PI; + i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f); + } + + int8 sign = rand_norm() > 0.5f ? 1 : -1; + i_cur_angle = sign*angle + angle_to_caster; + + // current distance + i_last_distance_from_caster = cur_dist; + + return true; +} + +template +void +FleeingMovementGenerator::Initialize(T &owner) +{ + if(!&owner) + return; + + Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID); + if(!fright) + return; + + _Init(owner); + owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + i_caster_x = fright->GetPositionX(); + i_caster_y = fright->GetPositionY(); + i_caster_z = fright->GetPositionZ(); + i_only_forward = true; + i_cur_angle = 0.0f; + i_last_distance_from_caster = 0.0f; + i_to_distance_from_caster = 0.0f; + _setTargetLocation(owner); +} + +template<> +void +FleeingMovementGenerator::_Init(Creature &owner) +{ + if(!&owner) + return; + owner.SetUInt64Value(UNIT_FIELD_TARGET, 0); + is_water_ok = owner.canSwim(); + is_land_ok = owner.canWalk(); +} + +template<> +void +FleeingMovementGenerator::_Init(Player &) +{ + is_water_ok = true; + is_land_ok = true; +} + +template +void +FleeingMovementGenerator::Finalize(T &owner) +{ + owner.clearUnitState(UNIT_STAT_FLEEING); +} + +template +void +FleeingMovementGenerator::Reset(T &owner) +{ + Initialize(owner); +} + +template +bool +FleeingMovementGenerator::Update(T &owner, const uint32 & time_diff) +{ + if( !&owner || !owner.isAlive() ) + return false; + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) ) + return true; + + Traveller traveller(owner); + + i_nextCheckTime.Update(time_diff); + + if( (owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination() ) + { + _setTargetLocation(owner); + return true; + } + + if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false)) + { + i_destinationHolder.ResetUpdate(50); + if(i_nextCheckTime.Passed() && i_destinationHolder.HasArrived()) + { + _setTargetLocation(owner); + return true; + } + } + return true; +} + +template void FleeingMovementGenerator::Initialize(Player &); +template void FleeingMovementGenerator::Initialize(Creature &); +template bool FleeingMovementGenerator::_setMoveData(Player &); +template bool FleeingMovementGenerator::_setMoveData(Creature &); +template bool FleeingMovementGenerator::_getPoint(Player &, float &, float &, float &); +template bool FleeingMovementGenerator::_getPoint(Creature &, float &, float &, float &); +template void FleeingMovementGenerator::_setTargetLocation(Player &); +template void FleeingMovementGenerator::_setTargetLocation(Creature &); +template void FleeingMovementGenerator::Finalize(Player &); +template void FleeingMovementGenerator::Finalize(Creature &); +template void FleeingMovementGenerator::Reset(Player &); +template void FleeingMovementGenerator::Reset(Creature &); +template bool FleeingMovementGenerator::Update(Player &, const uint32 &); +template bool FleeingMovementGenerator::Update(Creature &, const uint32 &); diff --git a/src/game/FleeingMovementGenerator.h b/src/game/FleeingMovementGenerator.h new file mode 100644 index 000000000..7f4028fc8 --- /dev/null +++ b/src/game/FleeingMovementGenerator.h @@ -0,0 +1,62 @@ +/* +* Copyright (C) 2005-2008 MaNGOS +* +* 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 2 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, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MANGOS_FLEEINGMOVEMENTGENERATOR_H +#define MANGOS_FLEEINGMOVEMENTGENERATOR_H + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "Traveller.h" +#include "MapManager.h" + +template +class MANGOS_DLL_SPEC FleeingMovementGenerator +: public MovementGeneratorMedium< T, FleeingMovementGenerator > +{ + public: + FleeingMovementGenerator(uint64 fright) : i_frightGUID(fright), i_nextCheckTime(0) {} + + void Initialize(T &); + void Finalize(T &); + void Reset(T &); + bool Update(T &, const uint32 &); + + MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; } + + private: + void _setTargetLocation(T &owner); + bool _getPoint(T &owner, float &x, float &y, float &z); + bool _setMoveData(T &owner); + void _Init(T &); + + bool is_water_ok :1; + bool is_land_ok :1; + bool i_only_forward:1; + + float i_caster_x; + float i_caster_y; + float i_caster_z; + float i_last_distance_from_caster; + float i_to_distance_from_caster; + float i_cur_angle; + TimeTracker i_nextCheckTime; + uint64 i_frightGUID; + + DestinationHolder< Traveller > i_destinationHolder; +}; +#endif diff --git a/src/game/FollowerRefManager.h b/src/game/FollowerRefManager.h new file mode 100644 index 000000000..3dfbd647e --- /dev/null +++ b/src/game/FollowerRefManager.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _FOLLOWERREFMANAGER +#define _FOLLOWERREFMANAGER + +#include "Utilities/LinkedReference/RefManager.h" + +class Unit; +class TargetedMovementGeneratorBase; + +class FollowerRefManager : public RefManager +{ + +}; +#endif diff --git a/src/game/FollowerReference.cpp b/src/game/FollowerReference.cpp new file mode 100644 index 000000000..31b925b11 --- /dev/null +++ b/src/game/FollowerReference.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Unit.h" +#include "TargetedMovementGenerator.h" +#include "FollowerReference.h" + +void FollowerReference::targetObjectBuildLink() +{ + getTarget()->addFollower(this); +} + +void FollowerReference::targetObjectDestroyLink() +{ + getTarget()->removeFollower(this); +} + +void FollowerReference::sourceObjectDestroyLink() +{ + getSource()->stopFollowing(); +} diff --git a/src/game/FollowerReference.h b/src/game/FollowerReference.h new file mode 100644 index 000000000..1d2996aba --- /dev/null +++ b/src/game/FollowerReference.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _FOLLOWERREFERENCE_H +#define _FOLLOWERREFERENCE_H + +#include "Utilities/LinkedReference/Reference.h" + +class TargetedMovementGeneratorBase; +class Unit; + +class MANGOS_DLL_SPEC FollowerReference : public Reference +{ + protected: + void targetObjectBuildLink(); + void targetObjectDestroyLink(); + void sourceObjectDestroyLink(); +}; +#endif diff --git a/src/game/Formulas.h b/src/game/Formulas.h new file mode 100644 index 000000000..e7c178913 --- /dev/null +++ b/src/game/Formulas.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_FORMULAS_H +#define MANGOS_FORMULAS_H + +#include "World.h" + +namespace MaNGOS +{ + namespace XP + { + typedef enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY }; + + inline uint32 GetGrayLevel(uint32 pl_level) + { + if( pl_level <= 5 ) + return 0; + else if( pl_level <= 39 ) + return pl_level - 5 - pl_level/10; + else if( pl_level <= 59 ) + return pl_level - 1 - pl_level/5; + else + return pl_level - 9; + } + + inline XPColorChar GetColorCode(uint32 pl_level, uint32 mob_level) + { + if( mob_level >= pl_level + 5 ) + return RED; + else if( mob_level >= pl_level + 3 ) + return ORANGE; + else if( mob_level >= pl_level - 2 ) + return YELLOW; + else if( mob_level > GetGrayLevel(pl_level) ) + return GREEN; + else + return GRAY; + } + + inline uint32 GetZeroDifference(uint32 pl_level) + { + if( pl_level < 8 ) return 5; + if( pl_level < 10 ) return 6; + if( pl_level < 12 ) return 7; + if( pl_level < 16 ) return 8; + if( pl_level < 20 ) return 9; + if( pl_level < 30 ) return 11; + if( pl_level < 40 ) return 12; + if( pl_level < 45 ) return 13; + if( pl_level < 50 ) return 14; + if( pl_level < 55 ) return 15; + if( pl_level < 60 ) return 16; + return 17; + } + + inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content) + { + //TODO: need modifier for CONTENT_71_80 different from CONTENT_61_70? + const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235; + if( mob_level >= pl_level ) + { + uint32 nLevelDiff = mob_level - pl_level; + if (nLevelDiff > 4) + nLevelDiff = 4; + return ((pl_level*5 + nBaseExp) * (20 + nLevelDiff)/10 + 1)/2; + } + else + { + uint32 gray_level = GetGrayLevel(pl_level); + if( mob_level > gray_level ) + { + uint32 ZD = GetZeroDifference(pl_level); + return (pl_level*5 + nBaseExp) * (ZD + mob_level - pl_level)/ZD; + } + return 0; + } + } + + inline uint32 Gain(Player *pl, Unit *u) + { + if(u->GetTypeId()==TYPEID_UNIT && ( + ((Creature*)u)->isTotem() || ((Creature*)u)->isPet() || + (((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) )) + return 0; + + uint32 xp_gain= BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(pl->GetMapId(),pl->GetZoneId())); + if( xp_gain == 0 ) + return 0; + + if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isElite()) + xp_gain *= 2; + + return (uint32)(xp_gain*sWorld.getRate(RATE_XP_KILL)); + } + + inline uint32 xp_Diff(uint32 lvl) + { + if( lvl < 29 ) + return 0; + if( lvl == 29 ) + return 1; + if( lvl == 30 ) + return 3; + if( lvl == 31 ) + return 6; + else + return (5*(lvl-30)); + } + + inline uint32 mxp(uint32 lvl) + { + if (lvl < 60) + { + return (45 + (5*lvl)); + } + else + { + return (235 + (5*lvl)); + } + } + + inline uint32 xp_to_level(uint32 lvl) + { + uint32 xp = 0; + if (lvl < 60) + { + xp = (8*lvl + xp_Diff(lvl)) * mxp(lvl); + } + else if (lvl == 60) + { + xp = (155 + mxp(lvl) * (1344 - 70 - ((69 - lvl) * (7 + (69 - lvl) * 8 - 1)/2))); + } + else if (lvl < 70) + { + xp = (155 + mxp(lvl) * (1344 - ((69-lvl) * (7 + (69 - lvl) * 8 - 1)/2))); + }else + { + // level higher than 70 is not supported + xp = (uint32)(779700 * (pow(sWorld.getRate(RATE_XP_PAST_70), (int32)lvl - 69))); + return ((xp < 0x7fffffff) ? xp : 0x7fffffff); + } + + // The XP to Level is always rounded to the nearest 100 points (50 rounded to high). + xp = ((xp + 50) / 100) * 100; // use additional () for prevent free association operations in C++ + + if ((lvl > 10) && (lvl < 60)) // compute discount added in 2.3.x + { + uint32 discount = (lvl < 28) ? (lvl - 10) : 18; + xp = (xp * (100 - discount)) / 100; // apply discount + xp = (xp / 100) * 100; // floor to hundreds + } + + return xp; + } + + inline float xp_in_group_rate(uint32 count, bool isRaid) + { + if(isRaid) + { + // FIX ME: must apply decrease modifiers dependent from raid size + return 1.0f; + } + else + { + switch(count) + { + case 0: + case 1: + case 2: + return 1.0f; + case 3: + return 1.166f; + case 4: + return 1.3f; + case 5: + default: + return 1.4f; + } + } + } + } +} +#endif diff --git a/src/game/GameEvent.cpp b/src/game/GameEvent.cpp new file mode 100644 index 000000000..5981fd00c --- /dev/null +++ b/src/game/GameEvent.cpp @@ -0,0 +1,659 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "GameEvent.h" +#include "World.h" +#include "ObjectMgr.h" +#include "ProgressBar.h" +#include "Language.h" +#include "Log.h" +#include "MapManager.h" +#include "Policies/SingletonImp.h" + +INSTANTIATE_SINGLETON_1(GameEvent); + +bool GameEvent::CheckOneGameEvent(uint16 entry) const +{ + // Get the event information + time_t currenttime = time(NULL); + if( mGameEvent[entry].start < currenttime && currenttime < mGameEvent[entry].end && + ((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * MINUTE)) < (mGameEvent[entry].length * MINUTE) ) + return true; + else + return false; +} + +uint32 GameEvent::NextCheck(uint16 entry) const +{ + time_t currenttime = time(NULL); + + // outdated event: we return max + if (currenttime > mGameEvent[entry].end) + return max_ge_check_delay; + + // never started event, we return delay before start + if (mGameEvent[entry].start > currenttime) + return (mGameEvent[entry].start - currenttime); + + uint32 delay; + // in event, we return the end of it + if ((((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * 60)) < (mGameEvent[entry].length * 60))) + // we return the delay before it ends + delay = (mGameEvent[entry].length * MINUTE) - ((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * MINUTE)); + else // not in window, we return the delay before next start + delay = (mGameEvent[entry].occurence * MINUTE) - ((currenttime - mGameEvent[entry].start) % (mGameEvent[entry].occurence * MINUTE)); + // In case the end is before next check + if (mGameEvent[entry].end < time_t(currenttime + delay)) + return (mGameEvent[entry].end - currenttime); + else + return delay; +} + +void GameEvent::StartEvent( uint16 event_id, bool overwrite ) +{ + AddActiveEvent(event_id); + ApplyNewEvent(event_id); + if(overwrite) + { + mGameEvent[event_id].start = time(NULL); + if(mGameEvent[event_id].end <= mGameEvent[event_id].start) + mGameEvent[event_id].end = mGameEvent[event_id].start+mGameEvent[event_id].length; + } +} + +void GameEvent::StopEvent( uint16 event_id, bool overwrite ) +{ + RemoveActiveEvent(event_id); + UnApplyEvent(event_id); + if(overwrite) + { + mGameEvent[event_id].start = time(NULL) - mGameEvent[event_id].length * MINUTE; + if(mGameEvent[event_id].end <= mGameEvent[event_id].start) + mGameEvent[event_id].end = mGameEvent[event_id].start+mGameEvent[event_id].length; + } +} + +void GameEvent::LoadFromDB() +{ + { + QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM game_event"); + if( !result ) + { + sLog.outString(">> Table game_event is empty."); + sLog.outString(); + return; + } + + Field *fields = result->Fetch(); + + uint32 max_event_id = fields[0].GetUInt16(); + delete result; + + mGameEvent.resize(max_event_id+1); + } + + QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,description FROM game_event"); + if( !result ) + { + mGameEvent.clear(); + sLog.outString(">> Table game_event is empty:"); + sLog.outString(); + return; + } + + uint32 count = 0; + + barGoLink bar( result->GetRowCount() ); + do + { + ++count; + Field *fields = result->Fetch(); + + bar.step(); + + uint16 event_id = fields[0].GetUInt16(); + if(event_id==0) + { + sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id); + continue; + } + + GameEventData& pGameEvent = mGameEvent[event_id]; + uint64 starttime = fields[1].GetUInt64(); + pGameEvent.start = time_t(starttime); + uint64 endtime = fields[2].GetUInt64(); + pGameEvent.end = time_t(endtime); + pGameEvent.occurence = fields[3].GetUInt32(); + pGameEvent.length = fields[4].GetUInt32(); + + if(pGameEvent.length==0) // length>0 is validity check + { + sLog.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id); + continue; + } + + pGameEvent.description = fields[5].GetCppString(); + + } while( result->NextRow() ); + + sLog.outString(); + sLog.outString( ">> Loaded %u game events", count ); + delete result; + + mGameEventCreatureGuids.resize(mGameEvent.size()*2-1); + // 1 2 + result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event " + "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid"); + + count = 0; + if( !result ) + { + barGoLink bar2(1); + bar2.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u creatures in game events", count ); + } + else + { + + barGoLink bar2( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar2.step(); + + uint32 guid = fields[0].GetUInt32(); + int16 event_id = fields[1].GetInt16(); + + int32 internal_event_id = mGameEvent.size() + event_id - 1; + + if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size()) + { + sLog.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + ++count; + GuidList& crelist = mGameEventCreatureGuids[internal_event_id]; + crelist.push_back(guid); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u creatures in game events", count ); + delete result; + } + + mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1); + // 1 2 + result = WorldDatabase.Query("SELECT gameobject.guid, game_event_gameobject.event " + "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid"); + + count = 0; + if( !result ) + { + barGoLink bar3(1); + bar3.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u gameobjects in game events", count ); + } + else + { + + barGoLink bar3( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar3.step(); + + uint32 guid = fields[0].GetUInt32(); + int16 event_id = fields[1].GetInt16(); + + int32 internal_event_id = mGameEvent.size() + event_id - 1; + + if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size()) + { + sLog.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + ++count; + GuidList& golist = mGameEventGameobjectGuids[internal_event_id]; + golist.push_back(guid); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u gameobjects in game events", count ); + + delete result; + } + + mGameEventModelEquip.resize(mGameEvent.size()); + // 0 1 2 + result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid," + // 3 + "game_event_model_equip.equipment_id " + "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid"); + + count = 0; + if( !result ) + { + barGoLink bar3(1); + bar3.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u model/equipment changes in game events", count ); + } + else + { + + barGoLink bar3( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar3.step(); + uint32 guid = fields[0].GetUInt32(); + uint16 event_id = fields[1].GetUInt16(); + + if(event_id >= mGameEventModelEquip.size()) + { + sLog.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + ++count; + ModelEquipList& equiplist = mGameEventModelEquip[event_id]; + ModelEquip newModelEquipSet; + newModelEquipSet.modelid = fields[2].GetUInt32(); + newModelEquipSet.equipment_id = fields[3].GetUInt32(); + newModelEquipSet.equipement_id_prev = 0; + newModelEquipSet.modelid_prev = 0; + + if(newModelEquipSet.equipment_id > 0) + { + if(!objmgr.GetEquipmentInfo(newModelEquipSet.equipment_id)) + { + sLog.outErrorDb("Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", guid, newModelEquipSet.equipment_id); + continue; + } + } + + equiplist.push_back(std::pair(guid, newModelEquipSet)); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u model/equipment changes in game events", count ); + + delete result; + } + + mGameEventQuests.resize(mGameEvent.size()); + // 0 1 2 + result = WorldDatabase.Query("SELECT id, quest, event FROM game_event_creature_quest"); + + count = 0; + if( !result ) + { + barGoLink bar3(1); + bar3.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u quests additions in game events", count ); + } + else + { + + barGoLink bar3( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar3.step(); + uint32 id = fields[0].GetUInt32(); + uint32 quest = fields[1].GetUInt32(); + uint16 event_id = fields[2].GetUInt16(); + + if(event_id >= mGameEventQuests.size()) + { + sLog.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + ++count; + QuestRelList& questlist = mGameEventQuests[event_id]; + questlist.push_back(QuestRelation(id, quest)); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u quests additions in game events", count ); + + delete result; + } +} + +uint32 GameEvent::Initialize() // return the next event delay in ms +{ + m_ActiveEvents.clear(); + uint32 delay = Update(); + sLog.outBasic("Game Event system initialized." ); + isSystemInit = true; + return delay; +} + +uint32 GameEvent::Update() // return the next event delay in ms +{ + uint32 nextEventDelay = max_ge_check_delay; // 1 day + uint32 calcDelay; + for (uint16 itr = 1; itr < mGameEvent.size(); itr++) + { + //sLog.outErrorDb("Checking event %u",itr); + if (CheckOneGameEvent(itr)) + { + //sLog.outDebug("GameEvent %u is active",itr->first); + if (!IsActiveEvent(itr)) + StartEvent(itr); + } + else + { + //sLog.outDebug("GameEvent %u is not active",itr->first); + if (IsActiveEvent(itr)) + StopEvent(itr); + else + { + if (!isSystemInit) + { + int16 event_nid = (-1) * (itr); + // spawn all negative ones for this event + GameEventSpawn(event_nid); + } + } + } + calcDelay = NextCheck(itr); + if (calcDelay < nextEventDelay) + nextEventDelay = calcDelay; + } + sLog.outBasic("Next game event check in %u seconds.", nextEventDelay + 1); + return (nextEventDelay + 1) * 1000; // Add 1 second to be sure event has started/stopped at next call +} + +void GameEvent::UnApplyEvent(uint16 event_id) +{ + sLog.outString("GameEvent %u \"%s\" removed.", event_id, mGameEvent[event_id].description.c_str()); + // un-spawn positive event tagged objects + GameEventUnspawn(event_id); + // spawn negative event tagget objects + int16 event_nid = (-1) * event_id; + GameEventSpawn(event_nid); + // restore equipment or model + ChangeEquipOrModel(event_id, false); + // Remove quests that are events only to non event npc + UpdateEventQuests(event_id, false); +} + +void GameEvent::ApplyNewEvent(uint16 event_id) +{ + switch(sWorld.getConfig(CONFIG_EVENT_ANNOUNCE)) + { + case 0: // disable + break; + case 1: // announce events + sWorld.SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str()); + break; + } + + sLog.outString("GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str()); + // spawn positive event tagget objects + GameEventSpawn(event_id); + // un-spawn negative event tagged objects + int16 event_nid = (-1) * event_id; + GameEventUnspawn(event_nid); + // Change equipement or model + ChangeEquipOrModel(event_id, true); + // Add quests that are events only to non event npc + UpdateEventQuests(event_id, true); +} + +void GameEvent::GameEventSpawn(int16 event_id) +{ + int32 internal_event_id = mGameEvent.size() + event_id - 1; + + if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size()) + { + sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size()); + return; + } + + for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin();itr != mGameEventCreatureGuids[internal_event_id].end();++itr) + { + // Add to correct cell + CreatureData const* data = objmgr.GetCreatureData(*itr); + if (data) + { + objmgr.AddCreatureToGrid(*itr, data); + + // Spawn if necessary (loaded grids only) + Map* map = const_cast(MapManager::Instance().GetBaseMap(data->mapid)); + // We use spawn coords to spawn + if(!map->Instanceable() && !map->IsRemovalGrid(data->posX,data->posY)) + { + Creature* pCreature = new Creature; + //sLog.outDebug("Spawning creature %u",*itr); + if (!pCreature->LoadFromDB(*itr, map)) + { + delete pCreature; + } + else + { + map->Add(pCreature); + } + } + } + } + + if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size()) + { + sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size()); + return; + } + + for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin();itr != mGameEventGameobjectGuids[internal_event_id].end();++itr) + { + // Add to correct cell + GameObjectData const* data = objmgr.GetGOData(*itr); + if (data) + { + objmgr.AddGameobjectToGrid(*itr, data); + // Spawn if necessary (loaded grids only) + // this base map checked as non-instanced and then only existed + Map* map = const_cast(MapManager::Instance().GetBaseMap(data->mapid)); + // We use current coords to unspawn, not spawn coords since creature can have changed grid + if(!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY)) + { + GameObject* pGameobject = new GameObject; + //sLog.outDebug("Spawning gameobject %u", *itr); + if (!pGameobject->LoadFromDB(*itr, map)) + { + delete pGameobject; + } + else + { + if(pGameobject->isSpawnedByDefault()) + map->Add(pGameobject); + } + } + } + } +} + +void GameEvent::GameEventUnspawn(int16 event_id) +{ + int32 internal_event_id = mGameEvent.size() + event_id - 1; + + if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size()) + { + sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size()); + return; + } + + for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin();itr != mGameEventCreatureGuids[internal_event_id].end();++itr) + { + // Remove the creature from grid + if( CreatureData const* data = objmgr.GetCreatureData(*itr) ) + { + objmgr.RemoveCreatureFromGrid(*itr, data); + + if( Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT), (Creature*)NULL) ) + { + pCreature->CleanupsBeforeDelete(); + pCreature->AddObjectToRemoveList(); + } + } + } + + if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size()) + { + sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size()); + return; + } + + for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin();itr != mGameEventGameobjectGuids[internal_event_id].end();++itr) + { + // Remove the gameobject from grid + if(GameObjectData const* data = objmgr.GetGOData(*itr)) + { + objmgr.RemoveGameobjectFromGrid(*itr, data); + + if( GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL) ) + pGameobject->AddObjectToRemoveList(); + } + } +} + +void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate) +{ + for(ModelEquipList::iterator itr = mGameEventModelEquip[event_id].begin();itr != mGameEventModelEquip[event_id].end();++itr) + { + // Remove the creature from grid + CreatureData const* data = objmgr.GetCreatureData(itr->first); + if(!data) + continue; + + // Update if spawned + Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT), (Creature*)NULL); + if (pCreature) + { + if (activate) + { + itr->second.equipement_id_prev = pCreature->GetCurrentEquipmentId(); + itr->second.modelid_prev = pCreature->GetDisplayId(); + pCreature->LoadEquipment(itr->second.equipment_id, true); + if (itr->second.modelid >0 && itr->second.modelid_prev != itr->second.modelid) + { + CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(itr->second.modelid); + if (minfo) + { + pCreature->SetDisplayId(itr->second.modelid); + pCreature->SetNativeDisplayId(itr->second.modelid); + pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); + pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); + } + } + } + else + { + pCreature->LoadEquipment(itr->second.equipement_id_prev, true); + if (itr->second.modelid_prev >0 && itr->second.modelid_prev != itr->second.modelid) + { + CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(itr->second.modelid_prev); + if (minfo) + { + pCreature->SetDisplayId(itr->second.modelid_prev); + pCreature->SetNativeDisplayId(itr->second.modelid_prev); + pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); + pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); + } + } + } + } + else // If not spawned + { + CreatureData const* data = objmgr.GetCreatureData(itr->first); + if (data && activate) + { + CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(data->id); + uint32 display_id = objmgr.ChooseDisplayId(0,cinfo,data); + CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id); + if (minfo) + display_id = minfo->modelid; + if (data->equipmentId == 0) + itr->second.equipement_id_prev = cinfo->equipmentId; + else if (data->equipmentId != -1) + itr->second.equipement_id_prev = data->equipmentId; + itr->second.modelid_prev = display_id; + } + } + // now last step: put in data + // just to have write access to it + CreatureData& data2 = objmgr.NewOrExistCreatureData(itr->first); + if (activate) + { + data2.displayid = itr->second.modelid; + data2.equipmentId = itr->second.equipment_id; + } + else + { + data2.displayid = itr->second.modelid_prev; + data2.equipmentId = itr->second.equipement_id_prev; + } + } +} + +void GameEvent::UpdateEventQuests(uint16 event_id, bool Activate) +{ + QuestRelList::iterator itr; + for (itr = mGameEventQuests[event_id].begin();itr != mGameEventQuests[event_id].end();++itr) + { + QuestRelations &CreatureQuestMap = objmgr.mCreatureQuestRelations; + if (Activate) // Add the pair(id,quest) to the multimap + CreatureQuestMap.insert(QuestRelations::value_type(itr->first, itr->second)); + else + { // Remove the pair(id,quest) from the multimap + QuestRelations::iterator qitr = CreatureQuestMap.find(itr->first); + if (qitr == CreatureQuestMap.end()) + continue; + QuestRelations::iterator lastElement = CreatureQuestMap.upper_bound(itr->first); + for ( ;qitr != lastElement;++qitr) + { + if (qitr->second == itr->second) + { + CreatureQuestMap.erase(qitr); // iterator is now no more valid + break; // but we can exit loop since the element is found + } + } + } + } +} + +GameEvent::GameEvent() +{ + isSystemInit = false; +} diff --git a/src/game/GameEvent.h b/src/game/GameEvent.h new file mode 100644 index 000000000..7cfb0f1c4 --- /dev/null +++ b/src/game/GameEvent.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GAMEEVENT_H +#define MANGOS_GAMEEVENT_H + +#include "Platform/Define.h" +#include "Creature.h" +#include "GameObject.h" + +#define max_ge_check_delay 86400 // 1 day in seconds + +struct GameEventData +{ + GameEventData() : start(1),end(0),occurence(0),length(0) {} + time_t start; + time_t end; + uint32 occurence; + uint32 length; + std::string description; + + bool isValid() const { return length > 0; } +}; + +struct ModelEquip +{ + uint32 modelid; + uint32 equipment_id; + uint32 modelid_prev; + uint32 equipement_id_prev; +}; + +class GameEvent +{ + public: + GameEvent(); + ~GameEvent() {}; + typedef std::set ActiveEvents; + typedef std::vector GameEventDataMap; + ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; } + GameEventDataMap const& GetEventMap() const { return mGameEvent; } + bool CheckOneGameEvent(uint16 entry) const; + uint32 NextCheck(uint16 entry) const; + void LoadFromDB(); + uint32 Update(); + bool IsActiveEvent(uint16 event_id) { return ( m_ActiveEvents.find(event_id)!=m_ActiveEvents.end()); } + uint32 Initialize(); + void StartEvent(uint16 event_id, bool overwrite = false); + void StopEvent(uint16 event_id, bool overwrite = false); + private: + void AddActiveEvent(uint16 event_id) { m_ActiveEvents.insert(event_id); } + void RemoveActiveEvent(uint16 event_id) { m_ActiveEvents.erase(event_id); } + void ApplyNewEvent(uint16 event_id); + void UnApplyEvent(uint16 event_id); + void GameEventSpawn(int16 event_id); + void GameEventUnspawn(int16 event_id); + void ChangeEquipOrModel(int16 event_id, bool activate); + void UpdateEventQuests(uint16 event_id, bool Activate); + protected: + typedef std::list GuidList; + typedef std::vector GameEventGuidMap; + typedef std::pair ModelEquipPair; + typedef std::list ModelEquipList; + typedef std::vector GameEventModelEquipMap; + typedef std::pair QuestRelation; + typedef std::list QuestRelList; + typedef std::vector GameEventQuestMap; + GameEventQuestMap mGameEventQuests; + GameEventModelEquipMap mGameEventModelEquip; + GameEventGuidMap mGameEventCreatureGuids; + GameEventGuidMap mGameEventGameobjectGuids; + GameEventDataMap mGameEvent; + ActiveEvents m_ActiveEvents; + bool isSystemInit; +}; + +#define gameeventmgr MaNGOS::Singleton::Instance() +#endif diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp new file mode 100644 index 000000000..dc2aee43d --- /dev/null +++ b/src/game/GameObject.cpp @@ -0,0 +1,1247 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "QuestDef.h" +#include "GameObject.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Spell.h" +#include "UpdateMask.h" +#include "Opcodes.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Database/DatabaseEnv.h" +#include "MapManager.h" +#include "LootMgr.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "InstanceData.h" +#include "BattleGround.h" +#include "Util.h" + +GameObject::GameObject() : WorldObject() +{ + m_objectType |= TYPEMASK_GAMEOBJECT; + m_objectTypeId = TYPEID_GAMEOBJECT; + // 2.3.2 - 0x58 + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + + m_valuesCount = GAMEOBJECT_END; + m_respawnTime = 0; + m_respawnDelayTime = 25; + m_lootState = GO_NOT_READY; + m_spawnedByDefault = true; + m_usetimes = 0; + m_spellId = 0; + m_charges = 5; + m_cooldownTime = 0; + m_goInfo = NULL; + + m_DBTableGuid = 0; +} + +GameObject::~GameObject() +{ + if(m_uint32Values) // field array can be not exist if GameOBject not loaded + { + // crash possable at access to deleted GO in Unit::m_gameobj + uint64 owner_guid = GetOwnerGUID(); + if(owner_guid) + { + Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid); + if(owner) + owner->RemoveGameObject(this,false); + else if(!IS_PLAYER_GUID(owner_guid)) + sLog.outError("Delete GameObject (GUID: %u Entry: %u ) that have references in not found creature %u GO list. Crash possable later.",GetGUIDLow(),GetGOInfo()->id,GUID_LOPART(owner_guid)); + } + } +} + +void GameObject::AddToWorld() +{ + ///- Register the gameobject for guid lookup + if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + Object::AddToWorld(); +} + +void GameObject::RemoveFromWorld() +{ + ///- Remove the gameobject from the accessor + if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + Object::RemoveFromWorld(); +} + +bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state) +{ + Relocate(x,y,z,ang); + SetMapId(map->GetId()); + SetInstanceId(map->GetInstanceId()); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y); + return false; + } + + GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(name_id); + if (!goinfo) + { + sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f) ang: %f rotation0: %f rotation1: %f rotation2: %f rotation3: %f",guidlow, name_id, map->GetId(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3); + return false; + } + + Object::_Create(guidlow, goinfo->id, HIGHGUID_GAMEOBJECT); + + m_goInfo = goinfo; + + if (goinfo->type >= MAX_GAMEOBJECT_TYPE) + { + sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist GO type '%u' in `gameobject_template`. It's will crash client if created.",guidlow,name_id,goinfo->type); + return false; + } + + SetFloatValue(GAMEOBJECT_POS_X, x); + SetFloatValue(GAMEOBJECT_POS_Y, y); + SetFloatValue(GAMEOBJECT_POS_Z, z); + SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle + + SetFloatValue (GAMEOBJECT_ROTATION, rotation0); + SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1); + SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2); + SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3); + + SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); + + SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); + SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); + + SetEntry(goinfo->id); + + SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); + + SetGoState(go_state); + SetGoType(GameobjectTypes(goinfo->type)); + + SetGoAnimProgress(animprogress); + + // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) + if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER) + m_charges = goinfo->spellcaster.charges; + + //Notify the map's instance data. + //Only works if you create the object in it, not if it is moves to that map. + //Normally non-players do not teleport to other maps. + if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) + { + ((InstanceMap*)map)->GetInstanceData()->OnObjectCreate(this); + } + + return true; +} + +void GameObject::Update(uint32 /*p_time*/) +{ + if (IS_MO_TRANSPORT(GetGUID())) + { + //((Transport*)this)->Update(p_time); + return; + } + + switch (m_lootState) + { + case GO_NOT_READY: + { + switch(GetGoType()) + { + case GAMEOBJECT_TYPE_TRAP: + { + // Arming Time for GAMEOBJECT_TYPE_TRAP (6) + Unit* owner = GetOwner(); + if (owner && ((Player*)owner)->isInCombat()) + m_cooldownTime = time(NULL) + GetGOInfo()->trap.startDelay; + m_lootState = GO_READY; + break; + } + case GAMEOBJECT_TYPE_FISHINGNODE: + { + // fishing code (bobber ready) + if( time(NULL) > m_respawnTime - FISHING_BOBBER_READY_TIME ) + { + // splash bobber (bobber ready now) + Unit* caster = GetOwner(); + if(caster && caster->GetTypeId()==TYPEID_PLAYER) + { + SetGoState(0); + SetUInt32Value(GAMEOBJECT_FLAGS, 32); + + UpdateData udata; + WorldPacket packet; + BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster)); + udata.BuildPacket(&packet); + ((Player*)caster)->GetSession()->SendPacket(&packet); + + WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4); + data << GetGUID(); + data << (uint32)(0); + ((Player*)caster)->SendMessageToSet(&data,true); + } + + m_lootState = GO_READY; // can be succesfully open with some chance + } + return; + } + default: + m_lootState = GO_READY; // for other GOis same switched without delay to GO_READY + break; + } + // NO BREAK for switch (m_lootState) + } + case GO_READY: + { + if (m_respawnTime > 0) // timer on + { + if (m_respawnTime <= time(NULL)) // timer expired + { + m_respawnTime = 0; + m_SkillupList.clear(); + m_usetimes = 0; + + switch (GetGoType()) + { + case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now + { + Unit* caster = GetOwner(); + if(caster && caster->GetTypeId()==TYPEID_PLAYER) + { + if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) + { + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(false); + } + + WorldPacket data(SMSG_FISH_NOT_HOOKED,0); + ((Player*)caster)->GetSession()->SendPacket(&data); + } + // can be delete + m_lootState = GO_JUST_DEACTIVATED; + return; + } + case GAMEOBJECT_TYPE_DOOR: + case GAMEOBJECT_TYPE_BUTTON: + //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) + if( !GetGoState() ) + SwitchDoorOrButton(false); + //flags in AB are type_button and we need to add them here so no break! + default: + if(!m_spawnedByDefault) // despawn timer + { + // can be despawned or destroyed + SetLootState(GO_JUST_DEACTIVATED); + return; + } + // respawn timer + MapManager::Instance().GetMap(GetMapId(), this)->Add(this); + break; + } + } + } + + // traps can have time and can not have + GameObjectInfo const* goInfo = GetGOInfo(); + if(goInfo->type == GAMEOBJECT_TYPE_TRAP) + { + // traps + Unit* owner = GetOwner(); + Unit* ok = NULL; // pointer to appropriate target if found any + + if(m_cooldownTime >= time(NULL)) + return; + + bool IsBattleGroundTrap = false; + //FIXME: this is activation radius (in different casting radius that must be selected from spell data) + //TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state + float radius = goInfo->trap.radius; + if(!radius) + { + if(goInfo->trap.cooldown != 3) // cast in other case (at some triggring/linked go/etc explicit call) + return; + else + { + if(m_respawnTime > 0) + break; + + radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3 + IsBattleGroundTrap = true; + } + } + + bool NeedDespawn = (goInfo->trap.charges != 0); + + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + // Note: this hack with search required until GO casting not implemented + // search unfriendly creature + if(owner && NeedDespawn) // hunter trap + { + MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius); + MaNGOS::UnitSearcher checker(ok, u_check); + + CellLock cell_lock(cell, p); + + TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); + cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + + // or unfriendly player/pet + if(!ok) + { + TypeContainerVisitor, WorldTypeMapContainer > world_object_checker(checker); + cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + } + } + else // environmental trap + { + // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support + + // affect only players + Player* p_ok = NULL; + MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius); + MaNGOS::PlayerSearcher checker(p_ok, p_check); + + CellLock cell_lock(cell, p); + + TypeContainerVisitor, WorldTypeMapContainer > world_object_checker(checker); + cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + ok = p_ok; + } + + if (ok) + { + Unit *caster = owner ? owner : ok; + + caster->CastSpell(ok, goInfo->trap.spellId, true); + m_cooldownTime = time(NULL) + 4; // 4 seconds + + if(NeedDespawn) + SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed + + if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER) + { + //BattleGround gameobjects case + if(((Player*)ok)->InBattleGround()) + if(BattleGround *bg = ((Player*)ok)->GetBattleGround()) + bg->HandleTriggerBuff(GetGUID()); + } + } + } + + if (m_charges && m_usetimes >= m_charges) + SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed + + break; + } + case GO_ACTIVATED: + { + switch(GetGoType()) + { + case GAMEOBJECT_TYPE_DOOR: + case GAMEOBJECT_TYPE_BUTTON: + if(GetAutoCloseTime() && (m_cooldownTime < time(NULL))) + { + SwitchDoorOrButton(false); + SetLootState(GO_JUST_DEACTIVATED); + } + break; + } + break; + } + case GO_JUST_DEACTIVATED: + { + //if Gameobject should cast spell, then this, but some GOs (type = 10) should be destroyed + if (GetGoType() == GAMEOBJECT_TYPE_GOOBER) + { + uint32 spellId = GetGOInfo()->goober.spellId; + + if(spellId) + { + std::set::iterator it = m_unique_users.begin(); + std::set::iterator end = m_unique_users.end(); + for (; it != end; it++) + { + Unit* owner = Unit::GetUnit(*this, uint64(*it)); + if (owner) owner->CastSpell(owner, spellId, false); + } + + m_unique_users.clear(); + m_usetimes = 0; + } + //any return here in case battleground traps + } + + if(GetOwnerGUID()) + { + m_respawnTime = 0; + Delete(); + return; + } + + //burning flags in some battlegrounds, if you find better condition, just add it + if (GetGoAnimProgress() > 0) + { + SendObjectDeSpawnAnim(this->GetGUID()); + //reset flags + SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); + } + + loot.clear(); + SetLootState(GO_READY); + + if(!m_respawnDelayTime) + return; + + if(!m_spawnedByDefault) + { + m_respawnTime = 0; + return; + } + + m_respawnTime = time(NULL) + m_respawnDelayTime; + + // if option not set then object will be saved at grid unload + if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) + SaveRespawnTime(); + + ObjectAccessor::UpdateObjectVisibility(this); + + break; + } + } +} + +void GameObject::Refresh() +{ + // not refresh despawned not casted GO (despawned casted GO destroyed in all cases anyway) + if(m_respawnTime > 0 && m_spawnedByDefault) + return; + + if(isSpawned()) + MapManager::Instance().GetMap(GetMapId(), this)->Add(this); +} + +void GameObject::AddUniqueUse(Player* player) +{ + AddUse(); + m_unique_users.insert(player->GetGUIDLow()); +} + +void GameObject::Delete() +{ + SendObjectDeSpawnAnim(GetGUID()); + + SetGoState(1); + SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); + + AddObjectToRemoveList(); +} + +void GameObject::getFishLoot(Loot *fishloot) +{ + fishloot->clear(); + + uint32 subzone = GetAreaId(); + + // if subzone loot exist use it + if(LootTemplates_Fishing.HaveLootFor(subzone)) + fishloot->FillLoot(subzone, LootTemplates_Fishing, NULL); + // else use zone loot + else + fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, NULL); +} + +void GameObject::SaveToDB() +{ + // this should only be used when the gameobject has already been loaded + // perferably after adding to map, because mapid may not be valid otherwise + GameObjectData const *data = objmgr.GetGOData(m_DBTableGuid); + if(!data) + { + sLog.outError("GameObject::SaveToDB failed, cannot get gameobject data!"); + return; + } + + SaveToDB(GetMapId(), data->spawnMask); +} + +void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask) +{ + const GameObjectInfo *goI = GetGOInfo(); + + if (!goI) + return; + + if (!m_DBTableGuid) + m_DBTableGuid = GetGUIDLow(); + // update in loaded data (changing data only in this place) + GameObjectData& data = objmgr.NewGOData(m_DBTableGuid); + + // data->guid = guid don't must be update at save + data.id = GetEntry(); + data.mapid = mapid; + data.posX = GetFloatValue(GAMEOBJECT_POS_X); + data.posY = GetFloatValue(GAMEOBJECT_POS_Y); + data.posZ = GetFloatValue(GAMEOBJECT_POS_Z); + data.orientation = GetFloatValue(GAMEOBJECT_FACING); + data.rotation0 = GetFloatValue(GAMEOBJECT_ROTATION+0); + data.rotation1 = GetFloatValue(GAMEOBJECT_ROTATION+1); + data.rotation2 = GetFloatValue(GAMEOBJECT_ROTATION+2); + data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3); + data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime; + data.animprogress = GetGoAnimProgress(); + data.go_state = GetGoState(); + data.spawnMask = spawnMask; + + // updated in DB + std::ostringstream ss; + ss << "INSERT INTO gameobject VALUES ( " + << m_DBTableGuid << ", " + << GetEntry() << ", " + << mapid << ", " + << (uint32)spawnMask << ", " + << GetFloatValue(GAMEOBJECT_POS_X) << ", " + << GetFloatValue(GAMEOBJECT_POS_Y) << ", " + << GetFloatValue(GAMEOBJECT_POS_Z) << ", " + << GetFloatValue(GAMEOBJECT_FACING) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION+1) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION+2) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION+3) << ", " + << m_respawnDelayTime << ", " + << (uint32)GetGoAnimProgress() << ", " + << (uint32)GetGoState() << ")"; + + WorldDatabase.BeginTransaction(); + WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); + WorldDatabase.PExecuteLog( ss.str( ).c_str( ) ); + WorldDatabase.CommitTransaction(); +} + +bool GameObject::LoadFromDB(uint32 guid, Map *map) +{ + GameObjectData const* data = objmgr.GetGOData(guid); + + if( !data ) + { + sLog.outErrorDb("ERROR: Gameobject (GUID: %u) not found in table `gameobject`, can't load. ",guid); + return false; + } + + uint32 entry = data->id; + uint32 map_id = data->mapid; + float x = data->posX; + float y = data->posY; + float z = data->posZ; + float ang = data->orientation; + + float rotation0 = data->rotation0; + float rotation1 = data->rotation1; + float rotation2 = data->rotation2; + float rotation3 = data->rotation3; + + uint32 animprogress = data->animprogress; + uint32 go_state = data->go_state; + + m_DBTableGuid = guid; + if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); + + if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) ) + return false; + + switch(GetGOInfo()->type) + { + case GAMEOBJECT_TYPE_DOOR: + case GAMEOBJECT_TYPE_BUTTON: + /* this code (in comment) isn't correct because in battlegrounds we need despawnable doors and buttons, pls remove + SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); + m_spawnedByDefault = true; + m_respawnDelayTime = 0; + m_respawnTime = 0; + break;*/ + default: + if(data->spawntimesecs >= 0) + { + m_spawnedByDefault = true; + m_respawnDelayTime = data->spawntimesecs; + m_respawnTime = objmgr.GetGORespawnTime(m_DBTableGuid, map->GetInstanceId()); + + // ready to respawn + if(m_respawnTime && m_respawnTime <= time(NULL)) + { + m_respawnTime = 0; + objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); + } + } + else + { + m_spawnedByDefault = false; + m_respawnDelayTime = -data->spawntimesecs; + m_respawnTime = 0; + } + break; + } + + return true; +} + +void GameObject::DeleteFromDB() +{ + objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); + objmgr.DeleteGOData(m_DBTableGuid); + WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); + WorldDatabase.PExecuteLog("DELETE FROM game_event_gameobject WHERE guid = '%u'", m_DBTableGuid); +} + +GameObject* GameObject::GetGameObject(WorldObject& object, uint64 guid) +{ + return ObjectAccessor::GetGameObject(object,guid); +} + +GameObjectInfo const *GameObject::GetGOInfo() const +{ + return m_goInfo; +} + +uint32 GameObject::GetLootId(GameObjectInfo const* ginfo) +{ + if (!ginfo) + return 0; + + switch(ginfo->type) + { + case GAMEOBJECT_TYPE_CHEST: + return ginfo->chest.lootId; + case GAMEOBJECT_TYPE_FISHINGHOLE: + return ginfo->fishinghole.lootId; + case GAMEOBJECT_TYPE_FISHINGNODE: + return ginfo->fishnode.lootId; + default: + return 0; + } +} + +/*********************************************************/ +/*** QUEST SYSTEM ***/ +/*********************************************************/ +bool GameObject::hasQuest(uint32 quest_id) const +{ + QuestRelations const& qr = objmgr.mGOQuestRelations; + for(QuestRelations::const_iterator itr = qr.lower_bound(GetEntry()); itr != qr.upper_bound(GetEntry()); ++itr) + { + if(itr->second==quest_id) + return true; + } + return false; +} + +bool GameObject::hasInvolvedQuest(uint32 quest_id) const +{ + QuestRelations const& qr = objmgr.mGOQuestInvolvedRelations; + for(QuestRelations::const_iterator itr = qr.lower_bound(GetEntry()); itr != qr.upper_bound(GetEntry()); ++itr) + { + if(itr->second==quest_id) + return true; + } + return false; +} + +bool GameObject::IsTransport() const +{ + // If something is marked as a transport, don't transmit an out of range packet for it. + GameObjectInfo const * gInfo = GetGOInfo(); + if(!gInfo) return false; + return gInfo->type == GAMEOBJECT_TYPE_TRANSPORT || gInfo->type == GAMEOBJECT_TYPE_MO_TRANSPORT; +} + +Unit* GameObject::GetOwner() const +{ + return ObjectAccessor::GetUnit(*this, GetOwnerGUID()); +} + +void GameObject::SaveRespawnTime() +{ + if(m_respawnTime > time(NULL) && m_spawnedByDefault) + objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime); +} + +bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const +{ + // Not in world + if(!IsInWorld() || !u->IsInWorld()) + return false; + + // Transport always visible at this step implementation + if(IsTransport() && IsInMap(u)) + return true; + + // quick check visibility false cases for non-GM-mode + if(!u->isGameMaster()) + { + // despawned and then not visible for non-GM in GM-mode + if(!isSpawned()) + return false; + + // special invisibility cases + /* TODO: implement trap stealth, take look at spell 2836 + if(GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP && GetGOInfo()->trap.stealthed && u->IsHostileTo(GetOwner())) + { + if(check stuff here) + return false; + }*/ + + // Smuggled Mana Cell required 10 invisibility type detection/state + if(GetEntry()==187039 && ((u->m_detectInvisibilityMask | u->m_invisibilityMask) & (1<<10))==0) + return false; + } + + // check distance + return IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject() + + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f) ); +} + +void GameObject::Respawn() +{ + if(m_spawnedByDefault && m_respawnTime > 0) + { + m_respawnTime = time(NULL); + objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); + } +} + +bool GameObject::ActivateToQuest( Player *pTarget)const +{ + if(!objmgr.IsGameObjectForQuests(GetEntry())) + return false; + + switch(GetGoType()) + { + // scan GO chest with loot including quest items + case GAMEOBJECT_TYPE_CHEST: + { + if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetLootId(), pTarget)) + return true; + break; + } + case GAMEOBJECT_TYPE_GOOBER: + { + if(pTarget->GetQuestStatus(GetGOInfo()->goober.questId) == QUEST_STATUS_INCOMPLETE) + return true; + break; + } + default: + break; + } + + return false; +} + +void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) +{ + GameObjectInfo const* trapInfo = sGOStorage.LookupEntry(trapEntry); + if(!trapInfo || trapInfo->type!=GAMEOBJECT_TYPE_TRAP) + return; + + SpellEntry const* trapSpell = sSpellStore.LookupEntry(trapInfo->trap.spellId); + if(!trapSpell) // checked at load already + return; + + float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(trapSpell->rangeIndex)); + + // search nearest linked GO + GameObject* trapGO = NULL; + { + // using original GO distance + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range); + MaNGOS::GameObjectLastSearcher checker(trapGO,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + } + + // found correct GO + // FIXME: when GO casting will be implemented trap must cast spell to target + if(trapGO) + target->CastSpell(target,trapSpell,true); +} + +GameObject* GameObject::LookupFishingHoleAround(float range) +{ + GameObject* ok = NULL; + + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + MaNGOS::NearestGameObjectFishingHole u_check(*this, range); + MaNGOS::GameObjectSearcher checker(ok, u_check); + + CellLock cell_lock(cell, p); + + TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); + cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + + return ok; +} + +void GameObject::UseDoorOrButton(uint32 time_to_restore) +{ + if(m_lootState != GO_READY) + return; + + if(!time_to_restore) + time_to_restore = GetAutoCloseTime(); + + SwitchDoorOrButton(true); + SetLootState(GO_ACTIVATED); + + m_cooldownTime = time(NULL) + time_to_restore; + +} + +void GameObject::SwitchDoorOrButton(bool activate) +{ + if(activate) + SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + else + RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + + if(GetGoState()) //if closed -> open + SetGoState(0); + else //if open -> close + SetGoState(1); +} + +void GameObject::Use(Unit* user) +{ + // by default spell caster is user + Unit* spellCaster = user; + uint32 spellId = 0; + + switch(GetGoType()) + { + case GAMEOBJECT_TYPE_DOOR: //0 + case GAMEOBJECT_TYPE_BUTTON: //1 + //doors/buttons never really despawn, only reset to default state/flags + UseDoorOrButton(); + + // activate script + sWorld.ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this); + return; + + case GAMEOBJECT_TYPE_QUESTGIVER: //2 + { + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + player->PrepareQuestMenu( GetGUID() ); + player->SendPreparedQuest( GetGUID() ); + return; + } + //Sitting: Wooden bench, chairs enzz + case GAMEOBJECT_TYPE_CHAIR: //7 + { + GameObjectInfo const* info = GetGOInfo(); + if(!info) + return; + + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + // a chair may have n slots. we have to calculate their positions and teleport the player to the nearest one + + // check if the db is sane + if(info->chair.slots > 0) + { + float lowestDist = DEFAULT_VISIBILITY_DISTANCE; + + float x_lowest = GetPositionX(); + float y_lowest = GetPositionY(); + + // the object orientation + 1/2 pi + // every slot will be on that straight line + float orthogonalOrientation = GetOrientation()+M_PI*0.5f; + // find nearest slot + for(uint32 i=0; ichair.slots; i++) + { + // the distance between this slot and the center of the go - imagine a 1D space + float relativeDistance = (info->size*i)-(info->size*(info->chair.slots-1)/2.0f); + + float x_i = GetPositionX() + relativeDistance * cos(orthogonalOrientation); + float y_i = GetPositionY() + relativeDistance * sin(orthogonalOrientation); + + // calculate the distance between the player and this slot + float thisDistance = player->GetDistance2d(x_i, y_i); + + /* debug code. It will spawn a npc on each slot to visualize them. + Creature* helper = player->SummonCreature(14496, x_i, y_i, GetPositionZ(), GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10000); + std::ostringstream output; + output << i << ": thisDist: " << thisDistance; + helper->MonsterSay(output.str().c_str(), LANG_UNIVERSAL, 0); + */ + + if(thisDistance <= lowestDist) + { + lowestDist = thisDistance; + x_lowest = x_i; + y_lowest = y_i; + } + } + player->TeleportTo(GetMapId(), x_lowest, y_lowest, GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); + } + else + { + // fallback, will always work + player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); + } + player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->chair.height); + return; + } + //big gun, its a spell/aura + case GAMEOBJECT_TYPE_GOOBER: //10 + { + GameObjectInfo const* info = GetGOInfo(); + + if(user->GetTypeId()==TYPEID_PLAYER) + { + Player* player = (Player*)user; + + // show page + if(info->goober.pageId) + { + WorldPacket data(SMSG_GAMEOBJECT_PAGETEXT, 8); + data << GetGUID(); + player->GetSession()->SendPacket(&data); + } + + // possible quest objective for active quests + player->CastedCreatureOrGO(info->id, GetGUID(), 0); + } + + // cast this spell later if provided + spellId = info->goober.spellId; + + break; + } + case GAMEOBJECT_TYPE_CAMERA: //13 + { + GameObjectInfo const* info = GetGOInfo(); + if(!info) + return; + + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + if(info->camera.cinematicId) + { + WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); + data << info->camera.cinematicId; + player->GetSession()->SendPacket(&data); + } + return; + } + //fishing bobber + case GAMEOBJECT_TYPE_FISHINGNODE: //17 + { + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + if(player->GetGUID() != GetOwnerGUID()) + return; + + switch(getLootState()) + { + case GO_READY: // ready for loot + { + // 1) skill must be >= base_zone_skill + // 2) if skill == base_zone_skill => 5% chance + // 3) chance is linear dependence from (base_zone_skill-skill) + + uint32 subzone = GetAreaId(); + + int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone ); + if(!zone_skill) + zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() ); + + //provide error, no fishable zone or area should be 0 + if(!zone_skill) + sLog.outErrorDb("Fishable areaId %u are not properly defined in `skill_fishing_base_level`.",subzone); + + int32 skill = player->GetSkillValue(SKILL_FISHING); + int32 chance = skill - zone_skill + 5; + int32 roll = irand(1,100); + + DEBUG_LOG("Fishing check (skill: %i zone min skill: %i chance %i roll: %i",skill,zone_skill,chance,roll); + + if(skill >= zone_skill && chance >= roll) + { + // prevent removing GO at spell cancel + player->RemoveGameObject(this,false); + SetOwnerGUID(player->GetGUID()); + + //fish catched + player->UpdateFishingSkill(); + + GameObject* ok = LookupFishingHoleAround(DEFAULT_VISIBILITY_DISTANCE); + if (ok) + { + player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE); + SetLootState(GO_JUST_DEACTIVATED); + } + else + player->SendLoot(GetGUID(),LOOT_FISHING); + } + else + { + // fish escaped, can be deleted now + SetLootState(GO_JUST_DEACTIVATED); + + WorldPacket data(SMSG_FISH_ESCAPED, 0); + player->GetSession()->SendPacket(&data); + } + break; + } + case GO_JUST_DEACTIVATED: // nothing to do, will be deleted at next update + break; + default: + { + SetLootState(GO_JUST_DEACTIVATED); + + WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); + player->GetSession()->SendPacket(&data); + break; + } + } + + if(player->m_currentSpells[CURRENT_CHANNELED_SPELL]) + { + player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); + player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); + } + return; + } + + case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18 + { + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + Unit* caster = GetOwner(); + + GameObjectInfo const* info = GetGOInfo(); + + if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) + return; + + // accept only use by player from same group for caster except caster itself + if(((Player*)caster)==player || !((Player*)caster)->IsInSameRaidWith(player)) + return; + + AddUniqueUse(player); + + // full amount unique participants including original summoner + if(GetUniqueUseCount() < info->summoningRitual.reqParticipants) + return; + + // in case summoning ritual caster is GO creator + spellCaster = caster; + + if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) + return; + + spellId = info->summoningRitual.spellId; + + // finish spell + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); + + // can be deleted now + SetLootState(GO_JUST_DEACTIVATED); + + // go to end function to spell casting + break; + } + case GAMEOBJECT_TYPE_SPELLCASTER: //22 + { + SetUInt32Value(GAMEOBJECT_FLAGS,2); + + GameObjectInfo const* info = GetGOInfo(); + if(!info) + return; + + if(info->spellcaster.partyOnly) + { + Unit* caster = GetOwner(); + if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) + return; + + if(user->GetTypeId()!=TYPEID_PLAYER || !((Player*)user)->IsInSameRaidWith((Player*)caster)) + return; + } + + spellId = info->spellcaster.spellId; + + AddUse(); + break; + } + case GAMEOBJECT_TYPE_MEETINGSTONE: //23 + { + GameObjectInfo const* info = GetGOInfo(); + + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection()); + + // accept only use by player from same group for caster except caster itself + if(!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameGroupWith(player)) + return; + + //required lvl checks! + uint8 level = player->getLevel(); + if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) + return; + level = targetPlayer->getLevel(); + if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) + return; + + spellId = 23598; + + break; + } + + case GAMEOBJECT_TYPE_FLAGSTAND: // 24 + { + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + if( player->isAllowUseBattleGroundObject() ) + { + // in battleground check + BattleGround *bg = player->GetBattleGround(); + if(!bg) + return; + // BG flag click + // AB: + // 15001 + // 15002 + // 15003 + // 15004 + // 15005 + bg->EventPlayerClickedOnFlag(player, this); + return; //we don;t need to delete flag ... it is despawned! + } + break; + } + case GAMEOBJECT_TYPE_FLAGDROP: // 26 + { + if(user->GetTypeId()!=TYPEID_PLAYER) + return; + + Player* player = (Player*)user; + + if( player->isAllowUseBattleGroundObject() ) + { + // in battleground check + BattleGround *bg = player->GetBattleGround(); + if(!bg) + return; + // BG flag dropped + // WS: + // 179785 - Silverwing Flag + // 179786 - Warsong Flag + // EotS: + // 184142 - Netherstorm Flag + GameObjectInfo const* info = GetGOInfo(); + if(info) + { + switch(info->id) + { + case 179785: // Silverwing Flag + // check if it's correct bg + if(bg->GetTypeID() == BATTLEGROUND_WS) + bg->EventPlayerClickedOnFlag(player, this); + break; + case 179786: // Warsong Flag + if(bg->GetTypeID() == BATTLEGROUND_WS) + bg->EventPlayerClickedOnFlag(player, this); + break; + case 184142: // Netherstorm Flag + if(bg->GetTypeID() == BATTLEGROUND_EY) + bg->EventPlayerClickedOnFlag(player, this); + break; + } + } + //this cause to call return, all flags must be deleted here!! + spellId = 0; + Delete(); + } + break; + } + default: + sLog.outDebug("Unknown Object Type %u", GetGoType()); + break; + } + + if(!spellId) + return; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); + if(!spellInfo) + { + sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType()); + return; + } + + Spell *spell = new Spell(spellCaster, spellInfo, false); + + // spell target is user of GO + SpellCastTargets targets; + targets.setUnitTarget( user ); + + spell->prepare(&targets); +} diff --git a/src/game/GameObject.h b/src/game/GameObject.h new file mode 100644 index 000000000..1fab1492a --- /dev/null +++ b/src/game/GameObject.h @@ -0,0 +1,592 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_GAMEOBJECT_H +#define MANGOSSERVER_GAMEOBJECT_H + +#include "Common.h" +#include "SharedDefines.h" +#include "Object.h" +#include "LootMgr.h" +#include "Database/DatabaseEnv.h" + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +// from `gameobject_template` +struct GameObjectInfo +{ + uint32 id; + uint32 type; + uint32 displayId; + char *name; + char *castBarCaption; + uint32 faction; + uint32 flags; + float size; + union // different GO types have different data field + { + //0 GAMEOBJECT_TYPE_DOOR + struct + { + uint32 startOpen; //0 used client side to determine GO_ACTIVATED means open/closed + uint32 lockId; //1 -> Lock.dbc + uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 + uint32 noDamageImmune; //3 break opening whenever you recieve damage? + uint32 openTextID; //4 can be used to replace castBarCaption? + uint32 closeTextID; //5 + } door; + //1 GAMEOBJECT_TYPE_BUTTON + struct + { + uint32 startOpen; //0 + uint32 lockId; //1 -> Lock.dbc + uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 + uint32 linkedTrap; //3 + uint32 noDamageImmune; //4 isBattlegroundObject + uint32 large; //5 + uint32 openTextID; //6 can be used to replace castBarCaption? + uint32 closeTextID; //7 + uint32 losOK; //8 + } button; + //2 GAMEOBJECT_TYPE_QUESTGIVER + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 questList; //1 + uint32 pageMaterial; //2 + uint32 gossipID; //3 + uint32 customAnim; //4 + uint32 noDamageImmune; //5 + uint32 openTextID; //6 can be used to replace castBarCaption? + uint32 losOK; //7 + uint32 allowMounted; //8 + uint32 large; //9 + } questgiver; + //3 GAMEOBJECT_TYPE_CHEST + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 lootId; //1 + uint32 chestRestockTime; //2 + uint32 consumable; //3 + uint32 minSuccessOpens; //4 + uint32 maxSuccessOpens; //5 + uint32 eventId; //6 lootedEvent + uint32 linkedTrapId; //7 + uint32 questId; //8 not used currently but store quest required for GO activation for player + uint32 level; //9 + uint32 losOK; //10 + uint32 leaveLoot; //11 + uint32 notInCombat; //12 + uint32 logLoot; //13 + uint32 openTextID; //14 can be used to replace castBarCaption? + uint32 groupLootRules; //15 + } chest; + //5 GAMEOBJECT_TYPE_GENERIC + struct + { + uint32 floatingTooltip; //0 + uint32 highlight; //1 + uint32 serverOnly; //2 + uint32 large; //3 + uint32 floatOnWater; //4 + uint32 questID; //5 + } _generic; + //6 GAMEOBJECT_TYPE_TRAP + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 level; //1 + uint32 radius; //2 radius for trap activation + uint32 spellId; //3 + uint32 charges; //4 need respawn (if > 0) + uint32 cooldown; //5 time in secs + uint32 autoCloseTime; //6 + uint32 startDelay; //7 + uint32 serverOnly; //8 + uint32 stealthed; //9 + uint32 large; //10 + uint32 stealthAffected; //11 + uint32 openTextID; //12 can be used to replace castBarCaption? + uint32 closeTextID; //13 + } trap; + //7 GAMEOBJECT_TYPE_CHAIR + struct + { + uint32 slots; //0 + uint32 height; //1 + uint32 onlyCreatorUse; //2 + } chair; + //8 GAMEOBJECT_TYPE_SPELL_FOCUS + struct + { + uint32 focusId; //0 + uint32 dist; //1 + uint32 linkedTrapId; //2 + uint32 serverOnly; //3 + uint32 questID; //4 + uint32 large; //5 + } spellFocus; + //9 GAMEOBJECT_TYPE_TEXT + struct + { + uint32 pageID; //0 + uint32 language; //1 + uint32 pageMaterial; //2 + uint32 allowMounted; //3 + } text; + //10 GAMEOBJECT_TYPE_GOOBER + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 questId; //1 + uint32 eventId; //2 + uint32 autoCloseTime; //3 + uint32 customAnim; //4 + uint32 consumable; //5 + uint32 cooldown; //6 + uint32 pageId; //7 + uint32 language; //8 + uint32 pageMaterial; //9 + uint32 spellId; //10 + uint32 noDamageImmune; //11 + uint32 linkedTrapId; //12 + uint32 large; //13 + uint32 openTextID; //14 can be used to replace castBarCaption? + uint32 closeTextID; //15 + uint32 losOK; //16 isBattlegroundObject + uint32 allowMounted; //17 + } goober; + //11 GAMEOBJECT_TYPE_TRANSPORT + struct + { + uint32 pause; //0 + uint32 startOpen; //1 + uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 + } transport; + //12 GAMEOBJECT_TYPE_AREADAMAGE + struct + { + uint32 lockId; //0 + uint32 radius; //1 + uint32 damageMin; //2 + uint32 damageMax; //3 + uint32 damageSchool; //4 + uint32 autoCloseTime; //5 secs till autoclose = autoCloseTime / 0x10000 + uint32 openTextID; //6 + uint32 closeTextID; //7 + } areadamage; + //13 GAMEOBJECT_TYPE_CAMERA + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 cinematicId; //1 + uint32 eventID; //2 + uint32 openTextID; //3 can be used to replace castBarCaption? + } camera; + //15 GAMEOBJECT_TYPE_MO_TRANSPORT + struct + { + uint32 taxiPathId; //0 + uint32 moveSpeed; //1 + uint32 accelRate; //2 + uint32 startEventID; //3 + uint32 stopEventID; //4 + uint32 transportPhysics; //5 + uint32 mapID; //6 + } moTransport; + //17 GAMEOBJECT_TYPE_FISHINGNODE + struct + { + uint32 _data0; //0 + uint32 lootId; //1 + } fishnode; + //18 GAMEOBJECT_TYPE_SUMMONING_RITUAL + struct + { + uint32 reqParticipants; //0 + uint32 spellId; //1 + uint32 animSpell; //2 + uint32 ritualPersistent; //3 + uint32 casterTargetSpell; //4 + uint32 casterTargetSpellTargets; //5 + uint32 castersGrouped; //6 + uint32 ritualNoTargetCheck; //7 + } summoningRitual; + //20 GAMEOBJECT_TYPE_AUCTIONHOUSE + struct + { + uint32 actionHouseID; //0 + } auctionhouse; + //21 GAMEOBJECT_TYPE_GUARDPOST + struct + { + uint32 creatureID; //0 + uint32 charges; //1 + } guardpost; + //22 GAMEOBJECT_TYPE_SPELLCASTER + struct + { + uint32 spellId; //0 + uint32 charges; //1 + uint32 partyOnly; //2 + } spellcaster; + //23 GAMEOBJECT_TYPE_MEETINGSTONE + struct + { + uint32 minLevel; //0 + uint32 maxLevel; //1 + uint32 areaID; //2 + } meetingstone; + //24 GAMEOBJECT_TYPE_FLAGSTAND + struct + { + uint32 lockId; //0 + uint32 pickupSpell; //1 + uint32 radius; //2 + uint32 returnAura; //3 + uint32 returnSpell; //4 + uint32 noDamageImmune; //5 + uint32 openTextID; //6 + uint32 losOK; //7 + } flagstand; + //25 GAMEOBJECT_TYPE_FISHINGHOLE // not implemented yet + struct + { + uint32 radius; //0 how close bobber must land for sending loot + uint32 lootId; //1 + uint32 minSuccessOpens; //2 + uint32 maxSuccessOpens; //3 + uint32 lockId; //4 -> Lock.dbc; possibly 1628 for all? + } fishinghole; + //26 GAMEOBJECT_TYPE_FLAGDROP + struct + { + uint32 lockId; //0 + uint32 eventID; //1 + uint32 pickupSpell; //2 + uint32 noDamageImmune; //3 + uint32 openTextID; //4 + } flagdrop; + //27 GAMEOBJECT_TYPE_MINI_GAME + struct + { + uint32 gameType; //0 + } miniGame; + //29 GAMEOBJECT_TYPE_CAPTURE_POINT + struct + { + uint32 radius; //0 + uint32 spell; //1 + uint32 worldState1; //2 + uint32 worldstate2; //3 + uint32 winEventID1; //4 + uint32 winEventID2; //5 + uint32 contestedEventID1; //6 + uint32 contestedEventID2; //7 + uint32 progressEventID1; //8 + uint32 progressEventID2; //9 + uint32 neutralEventID1; //10 + uint32 neutralEventID2; //11 + uint32 neutralPercent; //12 + uint32 worldstate3; //13 + uint32 minSuperiority; //14 + uint32 maxSuperiority; //15 + uint32 minTime; //16 + uint32 maxTime; //17 + uint32 large; //18 + uint32 highlight; //19 + } capturePoint; + //30 GAMEOBJECT_TYPE_AURA_GENERATOR + struct + { + uint32 startOpen; //0 + uint32 radius; //1 + uint32 auraID1; //2 + uint32 conditionID1; //3 + uint32 auraID2; //4 + uint32 conditionID2; //5 + uint32 serverOnly; //6 + } auraGenerator; + //31 GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY + struct + { + uint32 mapID; //0 + uint32 difficulty; //1 + } dungeonDifficulty; + //32 GAMEOBJECT_TYPE_DO_NOT_USE_YET + struct + { + uint32 mapID; //0 + uint32 difficulty; //1 + } doNotUseYet; + //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING + struct + { + uint32 dmgPctState1; //0 + uint32 dmgPctState2; //1 + uint32 state1Name; //2 + uint32 state2Name; //3 + } destructibleBuilding; + + // not use for specific field access (only for output with loop by all filed), also this determinate max union size + struct // GAMEOBJECT_TYPE_SPELLCASTER + { + uint32 data[24]; + } raw; + }; + char *ScriptName; +}; + +struct GameObjectLocale +{ + std::vector Name; + std::vector CastBarCaption; +}; + +// from `gameobject` +struct GameObjectData +{ + uint32 id; // entry in gamobject_template + uint32 mapid; + float posX; + float posY; + float posZ; + float orientation; + float rotation0; + float rotation1; + float rotation2; + float rotation3; + int32 spawntimesecs; + uint32 animprogress; + uint32 go_state; + uint8 spawnMask; +}; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif + +// For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ... +// For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-> +// For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ... +// For door(open): [GO_NOT_READY]->GO_READY (open) ->GO_ACTIVATED (close)->GO_JUST_DEACTIVATED->GO_READY(open) -> ... +enum LootState +{ + GO_NOT_READY = 0, + GO_READY, // can be ready but despawned, and then not possible activate until spawn + GO_ACTIVATED, + GO_JUST_DEACTIVATED +}; + +class Unit; + +// 5 sec for bobber catch +#define FISHING_BOBBER_READY_TIME 5 + +class MANGOS_DLL_SPEC GameObject : public WorldObject +{ + public: + explicit GameObject(); + ~GameObject(); + + void AddToWorld(); + void RemoveFromWorld(); + + bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state); + void Update(uint32 p_time); + static GameObject* GetGameObject(WorldObject& object, uint64 guid); + GameObjectInfo const* GetGOInfo() const; + + bool IsTransport() const; + + void SetOwnerGUID(uint64 owner) + { + m_spawnedByDefault = false; // all object with owner is despawned after delay + SetUInt64Value(OBJECT_FIELD_CREATED_BY, owner); + } + uint64 GetOwnerGUID() const { return GetUInt64Value(OBJECT_FIELD_CREATED_BY); } + Unit* GetOwner() const; + + uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } + + void Say(const char* text, uint32 language, uint64 TargetGuid) { MonsterSay(text,language,TargetGuid); } + void Yell(const char* text, uint32 language, uint64 TargetGuid) { MonsterYell(text,language,TargetGuid); } + void TextEmote(const char* text, uint64 TargetGuid) { MonsterTextEmote(text,TargetGuid); } + void Whisper(const char* text,uint64 receiver) { MonsterWhisper(text,receiver); } + void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } + void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } + void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); } + void Whisper(int32 textId, uint64 receiver) { MonsterWhisper(textId,receiver); } + + void SaveToDB(); + void SaveToDB(uint32 mapid, uint8 spawnMask); + bool LoadFromDB(uint32 guid, Map *map); + void DeleteFromDB(); + void SetLootState(LootState s) { m_lootState = s; } + static uint32 GetLootId(GameObjectInfo const* info); + uint32 GetLootId() const { return GetLootId(GetGOInfo()); } + uint32 GetLockId() const + { + switch(GetGoType()) + { + case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.lockId; + case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.lockId; + case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.lockId; + case GAMEOBJECT_TYPE_CHEST: return GetGOInfo()->chest.lockId; + case GAMEOBJECT_TYPE_TRAP: return GetGOInfo()->trap.lockId; + case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.lockId; + case GAMEOBJECT_TYPE_AREADAMAGE: return GetGOInfo()->areadamage.lockId; + case GAMEOBJECT_TYPE_CAMERA: return GetGOInfo()->camera.lockId; + case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.lockId; + case GAMEOBJECT_TYPE_FISHINGHOLE:return GetGOInfo()->fishinghole.lockId; + case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.lockId; + default: return 0; + } + } + + time_t GetRespawnTime() const { return m_respawnTime; } + time_t GetRespawnTimeEx() const + { + time_t now = time(NULL); + if(m_respawnTime > now) + return m_respawnTime; + else + return now; + } + + void SetRespawnTime(int32 respawn) + { + m_respawnTime = respawn > 0 ? time(NULL) + respawn : 0; + m_respawnDelayTime = respawn > 0 ? respawn : 0; + } + void Respawn(); + bool isSpawned() const + { + return m_respawnDelayTime == 0 || + (m_respawnTime > 0 && !m_spawnedByDefault) || + (m_respawnTime == 0 && m_spawnedByDefault); + } + bool isSpawnedByDefault() const { return m_spawnedByDefault; } + uint32 GetRespawnDelay() const { return m_respawnDelayTime; } + void Refresh(); + void Delete(); + void SetSpellId(uint32 id) { m_spellId = id;} + uint32 GetSpellId() const { return m_spellId;} + void getFishLoot(Loot *loot); + GameobjectTypes GetGoType() const { return GameobjectTypes(GetUInt32Value(GAMEOBJECT_TYPE_ID)); } + void SetGoType(GameobjectTypes type) { SetUInt32Value(GAMEOBJECT_TYPE_ID, type); } + uint32 GetGoState() const { return GetUInt32Value(GAMEOBJECT_STATE); } + void SetGoState(uint32 state) { SetUInt32Value(GAMEOBJECT_STATE, state); } + uint32 GetGoArtKit() const { return GetUInt32Value(GAMEOBJECT_ARTKIT); } + void SetGoArtKit(uint32 artkit) { SetUInt32Value(GAMEOBJECT_ARTKIT, artkit); } + uint32 GetGoAnimProgress() const { return GetUInt32Value(GAMEOBJECT_ANIMPROGRESS); } + void SetGoAnimProgress(uint32 animprogress) { SetUInt32Value(GAMEOBJECT_ANIMPROGRESS, animprogress); } + + void Use(Unit* user); + + LootState getLootState() const { return m_lootState; } + + void AddToSkillupList(uint32 PlayerGuidLow) { m_SkillupList.push_back(PlayerGuidLow); } + bool IsInSkillupList(uint32 PlayerGuidLow) const + { + for (std::list::const_iterator i = m_SkillupList.begin(); i != m_SkillupList.end(); ++i) + if (*i == PlayerGuidLow) return true; + return false; + } + void ClearSkillupList() { m_SkillupList.clear(); } + + void AddUniqueUse(Player* player); + void AddUse() { ++m_usetimes; } + + uint32 GetUseCount() const { return m_usetimes; } + uint32 GetUniqueUseCount() const { return m_unique_users.size(); } + + void SaveRespawnTime(); + + Loot loot; + + bool hasQuest(uint32 quest_id) const; + bool hasInvolvedQuest(uint32 quest_id) const; + bool ActivateToQuest(Player *pTarget) const; + void UseDoorOrButton(uint32 time_to_restore = 0); // 0 = use `gameobject`.`spawntimesecs` + + uint32 GetLinkedGameObjectEntry() const + { + switch(GetGoType()) + { + case GAMEOBJECT_TYPE_CHEST: return GetGOInfo()->chest.linkedTrapId; + case GAMEOBJECT_TYPE_SPELL_FOCUS: return GetGOInfo()->spellFocus.linkedTrapId; + case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.linkedTrapId; + default: return 0; + } + } + + uint32 GetAutoCloseTime() const + { + uint32 autoCloseTime = 0; + switch(GetGoType()) + { + case GAMEOBJECT_TYPE_DOOR: autoCloseTime = GetGOInfo()->door.autoCloseTime; break; + case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = GetGOInfo()->button.autoCloseTime; break; + case GAMEOBJECT_TYPE_TRAP: autoCloseTime = GetGOInfo()->trap.autoCloseTime; break; + case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = GetGOInfo()->goober.autoCloseTime; break; + case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = GetGOInfo()->transport.autoCloseTime; break; + case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = GetGOInfo()->areadamage.autoCloseTime; break; + default: break; + } + return autoCloseTime / 0x10000; + } + + void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target); + + bool isVisibleForInState(Player const* u, bool inVisibleList) const; + + GameObject* LookupFishingHoleAround(float range); + + GridReference &GetGridRef() { return m_gridRef; } + protected: + uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) + uint32 m_spellId; + time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), + uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer + LootState m_lootState; + bool m_spawnedByDefault; + time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). + // For traps this: spell casting cooldown, for doors/buttons: reset time. + std::list m_SkillupList; + + std::set m_unique_users; + uint32 m_usetimes; + + uint32 m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid + GameObjectInfo const* m_goInfo; + private: + void SwitchDoorOrButton(bool activate); + + GridReference m_gridRef; +}; +#endif diff --git a/src/game/GlobalEvents.cpp b/src/game/GlobalEvents.cpp new file mode 100644 index 000000000..14ad25607 --- /dev/null +++ b/src/game/GlobalEvents.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup world +*/ + +#include "Log.h" +#include "Database/DatabaseEnv.h" +#include "Platform/Define.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "GlobalEvents.h" +#include "ObjectDefines.h" +#include "Corpse.h" + +/// Handle periodic erase of corpses and bones +static void CorpsesErase(bool bones,uint32 delay) +{ + ///- Get the list of eligible corpses/bones to be removed + //No SQL injection (uint32 and enum) + QueryResult *result = CharacterDatabase.PQuery("SELECT guid,position_x,position_y,map,player FROM corpse WHERE UNIX_TIMESTAMP()-time > '%u' AND corpse_type %s '0'", delay, (bones ? "=" : "<>") ); + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 guidlow = fields[0].GetUInt32(); + float positionX = fields[1].GetFloat(); + float positionY = fields[2].GetFloat(); + uint32 mapid = fields[3].GetUInt32(); + uint64 player_guid = MAKE_NEW_GUID(fields[4].GetUInt32(), 0, HIGHGUID_PLAYER); + + uint64 guid = MAKE_NEW_GUID(guidlow, 0, HIGHGUID_CORPSE); + + sLog.outDebug("[Global event] Removing %s %u (X:%f Y:%f Map:%u).",(bones?"bones":"corpse"),guidlow,positionX,positionY,mapid); + + /// Resurrectable - convert corpses to bones + if(!bones) + { + if(!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid)) + { + sLog.outDebug("Corpse %u not found in world. Delete from DB.",guidlow); + CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow); + } + } + else + ///- or delete bones + { + MapManager::Instance().RemoveBonesFromMap(mapid, guid, positionX, positionY); + + ///- remove bones from the database + CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow); + } + } while (result->NextRow()); + + delete result; + } +} + +/// not thread guarded variant for call from other thread +void CorpsesErase() +{ + CorpsesErase(true, 20*MINUTE); + CorpsesErase(false,3*DAY); +} diff --git a/src/game/GlobalEvents.h b/src/game/GlobalEvents.h new file mode 100644 index 000000000..fc493ab9e --- /dev/null +++ b/src/game/GlobalEvents.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup world +/// @{ +/// \file + +#ifndef __GLOBALEVENTS_H +#define __GLOBALEVENTS_H + +void CorpsesErase(); +void HandleCorpsesErase(void*); +#endif +/// @} diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp new file mode 100644 index 000000000..880492777 --- /dev/null +++ b/src/game/GossipDef.cpp @@ -0,0 +1,762 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "QuestDef.h" +#include "GossipDef.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "WorldPacket.h" +#include "WorldSession.h" + +GossipMenu::GossipMenu() +{ + m_gItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use +} + +GossipMenu::~GossipMenu() +{ + ClearMenu(); +} + +void GossipMenu::AddMenuItem(uint8 Icon, std::string Message, uint32 dtSender, uint32 dtAction, std::string BoxMessage, uint32 BoxMoney, bool Coded) +{ + ASSERT( m_gItems.size() <= GOSSIP_MAX_MENU_ITEMS ); + + GossipMenuItem gItem; + + gItem.m_gIcon = Icon; + gItem.m_gMessage = Message; + gItem.m_gCoded = Coded; + gItem.m_gSender = dtSender; + gItem.m_gAction = dtAction; + gItem.m_gBoxMessage = BoxMessage; + gItem.m_gBoxMoney = BoxMoney; + + m_gItems.push_back(gItem); +} + +void GossipMenu::AddMenuItem(uint8 Icon, std::string Message, bool Coded) +{ + AddMenuItem( Icon, Message, 0, 0, "", 0, Coded); +} + +void GossipMenu::AddMenuItem(uint8 Icon, char const* Message, bool Coded) +{ + AddMenuItem(Icon, std::string(Message ? Message : ""),Coded); +} + +void GossipMenu::AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded) +{ + AddMenuItem(Icon, std::string(Message ? Message : ""), dtSender, dtAction, std::string(BoxMessage ? BoxMessage : ""), BoxMoney, Coded); +} + +uint32 GossipMenu::MenuItemSender( unsigned int ItemId ) +{ + if ( ItemId >= m_gItems.size() ) return 0; + + return m_gItems[ ItemId ].m_gSender; +} + +uint32 GossipMenu::MenuItemAction( unsigned int ItemId ) +{ + if ( ItemId >= m_gItems.size() ) return 0; + + return m_gItems[ ItemId ].m_gAction; +} + +bool GossipMenu::MenuItemCoded( unsigned int ItemId ) +{ + if ( ItemId >= m_gItems.size() ) return 0; + + return m_gItems[ ItemId ].m_gCoded; +} + +void GossipMenu::ClearMenu() +{ + m_gItems.clear(); +} + +PlayerMenu::PlayerMenu( WorldSession *session ) : pSession(session) +{ +} + +PlayerMenu::~PlayerMenu() +{ + ClearMenus(); +} + +void PlayerMenu::ClearMenus() +{ + mGossipMenu.ClearMenu(); + mQuestMenu.ClearMenu(); +} + +uint32 PlayerMenu::GossipOptionSender( unsigned int Selection ) +{ + return mGossipMenu.MenuItemSender( Selection ); +} + +uint32 PlayerMenu::GossipOptionAction( unsigned int Selection ) +{ + return mGossipMenu.MenuItemAction( Selection ); +} + +bool PlayerMenu::GossipOptionCoded( unsigned int Selection ) +{ + return mGossipMenu.MenuItemCoded( Selection ); +} + +void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID ) +{ + WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size + data << npcGUID; + data << uint32(0); // new 2.4.0 + data << uint32( TitleTextId ); + data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x0F + + for ( unsigned int iI = 0; iI < mGossipMenu.MenuItemCount(); iI++ ) + { + GossipMenuItem const& gItem = mGossipMenu.GetItem(iI); + data << uint32( iI ); + data << uint8( gItem.m_gIcon ); + // icons: + // 0 unlearn talents/misc + // 1 trader + // 2 taxi + // 3 trainer + // 9 BG/arena + data << uint8( gItem.m_gCoded ); // makes pop up box password + data << uint32(gItem.m_gBoxMoney); // money required to open menu, 2.0.3 + data << gItem.m_gMessage; // text for gossip item + data << gItem.m_gBoxMessage; // accept text (related to money) pop up box, 2.0.3 + } + + data << uint32( mQuestMenu.MenuItemCount() ); // max count 0x20 + + for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ ) + { + QuestMenuItem const& qItem = mQuestMenu.GetItem(iI); + uint32 questID = qItem.m_qId; + Quest const* pQuest = objmgr.GetQuestTemplate(questID); + + data << questID; + data << uint32( qItem.m_qIcon ); + data << uint32( pQuest ? pQuest->GetQuestLevel() : 0 ); + std::string Title = pQuest->GetTitle(); + + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + QuestLocale const *ql = objmgr.GetQuestLocale(questID); + if (ql) + { + if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) + Title=ql->Title[loc_idx]; + } + } + data << Title; + } + + pSession->SendPacket( &data ); + //sLog.outDebug( "WORLD: Sent SMSG_GOSSIP_MESSAGE NPCGuid=%u",GUID_LOPART(npcGUID) ); +} + +void PlayerMenu::CloseGossip() +{ + WorldPacket data( SMSG_GOSSIP_COMPLETE, 0 ); + pSession->SendPacket( &data ); + + //sLog.outDebug( "WORLD: Sent SMSG_GOSSIP_COMPLETE" ); +} + +void PlayerMenu::SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, char const * locName ) +{ + WorldPacket data( SMSG_GOSSIP_POI, (4+4+4+4+4+10) ); // guess size + data << Flags; + data << X << Y; + data << uint32(Icon); + data << uint32(Data); + data << locName; + + pSession->SendPacket( &data ); + //sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI"); +} + +void PlayerMenu::SendTalking( uint32 textID ) +{ + GossipText *pGossip; + std::string GossipStr; + + pGossip = objmgr.GetGossipText(textID); + + WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size + data << textID; // can be < 0 + + if (!pGossip) + { + for(uint32 i = 0; i < 8; ++i) + { + data << float(0); + data << "Greetings $N"; + data << "Greetings $N"; + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + } + } + else + { + std::string Text_0[8],Text_1[8]; + for (int i=0;i<8;i++) + { + Text_0[i]=pGossip->Options[i].Text_0; + Text_1[i]=pGossip->Options[i].Text_1; + } + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID); + if (nl) + { + for (int i=0;i<8;i++) + { + if (nl->Text_0[i].size() > loc_idx && !nl->Text_0[i][loc_idx].empty()) + Text_0[i]=nl->Text_0[i][loc_idx]; + if (nl->Text_1[i].size() > loc_idx && !nl->Text_1[i][loc_idx].empty()) + Text_1[i]=nl->Text_1[i][loc_idx]; + } + } + } + for (int i=0; i<8; i++) + { + data << pGossip->Options[i].Probability; + + if ( Text_0[i].empty() ) + data << Text_1[i]; + else + data << Text_0[i]; + + if ( Text_1[i].empty() ) + data << Text_0[i]; + else + data << Text_1[i]; + + data << pGossip->Options[i].Language; + + data << pGossip->Options[i].Emotes[0]._Delay; + data << pGossip->Options[i].Emotes[0]._Emote; + + data << pGossip->Options[i].Emotes[1]._Delay; + data << pGossip->Options[i].Emotes[1]._Emote; + + data << pGossip->Options[i].Emotes[2]._Delay; + data << pGossip->Options[i].Emotes[2]._Emote; + } + } + pSession->SendPacket( &data ); + + sLog.outDebug( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " ); +} + +void PlayerMenu::SendTalking( char const * title, char const * text ) +{ + WorldPacket data( SMSG_NPC_TEXT_UPDATE, 50 ); // guess size + data << uint32(0); + for(uint32 i = 0; i < 8; ++i) + { + data << float(0); + data << title; + data << text; + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + } + + pSession->SendPacket( &data ); + + sLog.outDebug( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " ); +} + +/*********************************************************/ +/*** QUEST SYSTEM ***/ +/*********************************************************/ + +QuestMenu::QuestMenu() +{ + m_qItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use +} + +QuestMenu::~QuestMenu() +{ + ClearMenu(); +} + +void QuestMenu::AddMenuItem( uint32 QuestId, uint8 Icon) +{ + Quest const* qinfo = objmgr.GetQuestTemplate(QuestId); + if (!qinfo) return; + + ASSERT( m_qItems.size() <= GOSSIP_MAX_MENU_ITEMS ); + + QuestMenuItem qItem; + + qItem.m_qId = QuestId; + qItem.m_qIcon = Icon; + + m_qItems.push_back(qItem); +} + +bool QuestMenu::HasItem( uint32 questid ) +{ + for (QuestMenuItemList::iterator i = m_qItems.begin(); i != m_qItems.end(); i++) + { + if(i->m_qId==questid) + { + return true; + } + } + return false; +} + +void QuestMenu::ClearMenu() +{ + m_qItems.clear(); +} + +void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint64 npcGUID ) +{ + WorldPacket data( SMSG_QUESTGIVER_QUEST_LIST, 100 ); // guess size + data << uint64(npcGUID); + data << Title; + data << uint32(eEmote._Delay ); // player emote + data << uint32(eEmote._Emote ); // NPC emote + data << uint8 ( mQuestMenu.MenuItemCount() ); + + for ( uint16 iI = 0; iI < mQuestMenu.MenuItemCount(); iI++ ) + { + QuestMenuItem const& qmi = mQuestMenu.GetItem(iI); + + uint32 questID = qmi.m_qId; + Quest const *pQuest = objmgr.GetQuestTemplate(questID); + + std::string title = pQuest ? pQuest->GetTitle() : ""; + + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + if(QuestLocale const *ql = objmgr.GetQuestLocale(questID)) + { + if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) + title=ql->Title[loc_idx]; + } + } + + data << uint32(questID); + data << uint32(qmi.m_qIcon); + data << uint32(pQuest ? pQuest->GetQuestLevel() : 0); + data << title; + } + pSession->SendPacket( &data ); + //uint32 fqid=pQuestMenu->GetItem(0).m_qId; + //sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u, questid-0=%u",npcGUID,fqid); +} + +void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID ) +{ + WorldPacket data( SMSG_QUESTGIVER_STATUS, 9 ); + data << uint64(npcGUID); + data << uint8(questStatus); + + pSession->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u",GUID_LOPART(npcGUID),questStatus); +} + +void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept ) +{ + WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size + + std::string Title = pQuest->GetTitle(); + std::string Details = pQuest->GetDetails(); + std::string Objectives = pQuest->GetObjectives(); + std::string EndText = pQuest->GetEndText(); + + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId()); + if (ql) + { + if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) + Title=ql->Title[loc_idx]; + if (ql->Details.size() > loc_idx && !ql->Details[loc_idx].empty()) + Details=ql->Details[loc_idx]; + if (ql->Objectives.size() > loc_idx && !ql->Objectives[loc_idx].empty()) + Objectives=ql->Objectives[loc_idx]; + if (ql->EndText.size() > loc_idx && !ql->EndText[loc_idx].empty()) + EndText=ql->EndText[loc_idx]; + } + } + + data << uint64(npcGUID); + data << uint32(pQuest->GetQuestId()); + data << Title << Details << Objectives; + data << uint32(ActivateAccept); + data << uint32(pQuest->GetSuggestedPlayers()); + + if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) + { + data << uint32(0); // Rewarded chosen items hidden + data << uint32(0); // Rewarded items hidden + data << uint32(0); // Rewarded money hidden + } + else + { + ItemPrototype const* IProto; + + data << uint32(pQuest->GetRewChoiceItemsCount()); + for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; i++) + { + if ( !pQuest->RewChoiceItemId[i] ) continue; + data << uint32(pQuest->RewChoiceItemId[i]); + data << uint32(pQuest->RewChoiceItemCount[i]); + IProto = objmgr.GetItemPrototype(pQuest->RewChoiceItemId[i]); + if ( IProto ) + data << uint32(IProto->DisplayInfoID); + else + data << uint32( 0x00 ); + } + + data << uint32(pQuest->GetRewItemsCount()); + for (uint32 i=0; i < QUEST_REWARDS_COUNT; i++) + { + if ( !pQuest->RewItemId[i] ) continue; + data << uint32(pQuest->RewItemId[i]); + data << uint32(pQuest->RewItemCount[i]); + IProto = objmgr.GetItemPrototype(pQuest->RewItemId[i]); + if ( IProto ) + data << uint32(IProto->DisplayInfoID); + else + data << uint32(0); + } + data << uint32(pQuest->GetRewOrReqMoney()); + } + + data << uint32(0); // Honor points reward, not implemented + data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) + data << uint32(pQuest->GetRewSpellCast()); // casted spell + data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) + + data << uint32(QUEST_EMOTE_COUNT); + for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++) + { + data << uint32(pQuest->DetailsEmote[i]); + data << uint32(0); // DetailsEmoteDelay + } + pSession->SendPacket( &data ); + + sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId()); +} + +void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) +{ + std::string Title,Details,Objectives,EndText; + std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; + Title = pQuest->GetTitle(); + Details = pQuest->GetDetails(); + Objectives = pQuest->GetObjectives(); + EndText = pQuest->GetEndText(); + for (int i=0;iObjectiveText[i]; + + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId()); + if (ql) + { + if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) + Title=ql->Title[loc_idx]; + if (ql->Details.size() > loc_idx && !ql->Details[loc_idx].empty()) + Details=ql->Details[loc_idx]; + if (ql->Objectives.size() > loc_idx && !ql->Objectives[loc_idx].empty()) + Objectives=ql->Objectives[loc_idx]; + if (ql->EndText.size() > loc_idx && !ql->EndText[loc_idx].empty()) + EndText=ql->EndText[loc_idx]; + + for (int i=0;iObjectiveText[i].size() > loc_idx && !ql->ObjectiveText[i][loc_idx].empty()) + ObjectiveText[i]=ql->ObjectiveText[i][loc_idx]; + } + } + + WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 ); // guess size + + data << uint32(pQuest->GetQuestId()); + data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details) + data << uint32(pQuest->GetQuestLevel()); // may be 0 + data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log + + data << uint32(pQuest->GetType()); + data << uint32(pQuest->GetSuggestedPlayers()); + + data << uint32(pQuest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective + data << uint32(pQuest->GetRepObjectiveValue()); // shown in quest log as part of quest objective + + data << uint32(0); // RequiredOpositeRepFaction + data << uint32(0); // RequiredOpositeRepValue, required faction value with another (oposite) faction (objective) + + data << uint32(pQuest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0 + + if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) + data << uint32(0); // Hide money rewarded + else + data << uint32(pQuest->GetRewOrReqMoney()); + + data << uint32(pQuest->GetRewMoneyMaxLevel()); // used in XP calculation at client + data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) + data << uint32(pQuest->GetRewSpellCast()); // casted spell + + data << uint32(0); // Honor points reward, not implemented + data << uint32(pQuest->GetSrcItemId()); + data << uint32(pQuest->GetFlags() & 0xFFFF); + data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) + + int iI; + + if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) + { + for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++) + data << uint32(0) << uint32(0); + for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++) + data << uint32(0) << uint32(0); + } + else + { + for (iI = 0; iI < QUEST_REWARDS_COUNT; iI++) + { + data << uint32(pQuest->RewItemId[iI]); + data << uint32(pQuest->RewItemCount[iI]); + } + for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; iI++) + { + data << uint32(pQuest->RewChoiceItemId[iI]); + data << uint32(pQuest->RewChoiceItemCount[iI]); + } + } + + data << pQuest->GetPointMapId(); + data << pQuest->GetPointX(); + data << pQuest->GetPointY(); + data << pQuest->GetPointOpt(); + + data << Title; + data << Objectives; + data << Details; + data << EndText; + + for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++) + { + if (pQuest->ReqCreatureOrGOId[iI] < 0) + { + // client expected gameobject template id in form (id|0x80000000) + data << uint32((pQuest->ReqCreatureOrGOId[iI]*(-1))|0x80000000); + } + else + { + data << uint32(pQuest->ReqCreatureOrGOId[iI]); + } + data << uint32(pQuest->ReqCreatureOrGOCount[iI]); + data << uint32(pQuest->ReqItemId[iI]); + data << uint32(pQuest->ReqItemCount[iI]); + } + + for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++) + data << ObjectiveText[iI]; + + pSession->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() ); +} + +void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext ) +{ + std::string Title = pQuest->GetTitle(); + std::string OfferRewardText = pQuest->GetOfferRewardText(); + + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId()); + if (ql) + { + if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) + Title=ql->Title[loc_idx]; + if (ql->OfferRewardText.size() > loc_idx && !ql->OfferRewardText[loc_idx].empty()) + OfferRewardText=ql->OfferRewardText[loc_idx]; + } + } + + WorldPacket data( SMSG_QUESTGIVER_OFFER_REWARD, 50 ); // guess size + + data << npcGUID; + data << pQuest->GetQuestId(); + data << Title; + data << OfferRewardText; + + data << uint32( EnbleNext ); + data << uint32(0); // unk + + uint32 EmoteCount = 0; + for (uint32 i = 0; i < QUEST_EMOTE_COUNT; i++) + { + if(pQuest->OfferRewardEmote[i] <= 0) + break; + ++EmoteCount; + } + + data << EmoteCount; // Emote Count + for (uint32 i = 0; i < EmoteCount; i++) + { + data << uint32(0); // Delay Emote + data << pQuest->OfferRewardEmote[i]; + } + + ItemPrototype const *pItem; + + data << uint32(pQuest->GetRewChoiceItemsCount()); + for (uint32 i=0; i < pQuest->GetRewChoiceItemsCount(); i++) + { + pItem = objmgr.GetItemPrototype( pQuest->RewChoiceItemId[i] ); + + data << uint32(pQuest->RewChoiceItemId[i]); + data << uint32(pQuest->RewChoiceItemCount[i]); + + if ( pItem ) + data << uint32(pItem->DisplayInfoID); + else + data << uint32(0); + } + + data << uint32(pQuest->GetRewItemsCount()); + for (uint16 i=0; i < pQuest->GetRewItemsCount(); i++) + { + pItem = objmgr.GetItemPrototype(pQuest->RewItemId[i]); + data << uint32(pQuest->RewItemId[i]); + data << uint32(pQuest->RewItemCount[i]); + + if ( pItem ) + data << uint32(pItem->DisplayInfoID); + else + data << uint32(0); + } + + data << uint32(pQuest->GetRewOrReqMoney()); + data << uint32(0x00); // new 2.3.0. Honor points + data << uint32(0x08); // unused by client? + data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) + data << uint32(pQuest->GetRewSpellCast()); // casted spell + data << uint32(0); // Honor points reward, not implemented + pSession->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); +} + +void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel ) +{ + // We can always call to RequestItems, but this packet only goes out if there are actually + // items. Otherwise, we'll skip straight to the OfferReward + + // We may wish a better check, perhaps checking the real quest requirements + if (pQuest->GetRequestItemsText().empty()) + { + SendQuestGiverOfferReward(pQuest, npcGUID, true); + return; + } + + std::string Title,RequestItemsText; + Title = pQuest->GetTitle(); + RequestItemsText = pQuest->GetRequestItemsText(); + + int loc_idx = pSession->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId()); + if (ql) + { + if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) + Title=ql->Title[loc_idx]; + if (ql->RequestItemsText.size() > loc_idx && !ql->RequestItemsText[loc_idx].empty()) + RequestItemsText=ql->RequestItemsText[loc_idx]; + } + } + + WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 ); // guess size + data << npcGUID; + data << pQuest->GetQuestId(); + data << Title; + data << RequestItemsText; + + data << uint32(0x00); // unknown + + if(Completable) + data << pQuest->GetCompleteEmote(); + else + data << pQuest->GetIncompleteEmote(); + + // Close Window after cancel + if (CloseOnCancel) + data << uint32(0x01); + else + data << uint32(0x00); + + data << uint32(0x00); // unknown + + // Required Money + data << uint32(pQuest->GetRewOrReqMoney() < 0 ? -pQuest->GetRewOrReqMoney() : 0); + + data << uint32( pQuest->GetReqItemsCount() ); + ItemPrototype const *pItem; + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + if ( !pQuest->ReqItemId[i] ) continue; + pItem = objmgr.GetItemPrototype(pQuest->ReqItemId[i]); + data << uint32(pQuest->ReqItemId[i]); + data << uint32(pQuest->ReqItemCount[i]); + + if ( pItem ) + data << uint32(pItem->DisplayInfoID); + else + data << uint32(0); + } + + if ( !Completable ) + data << uint32(0x00); + else + data << uint32(0x03); + + data << uint32(0x04) << uint32(0x08) << uint32(0x10); + + pSession->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); +} diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h new file mode 100644 index 000000000..ba5b36008 --- /dev/null +++ b/src/game/GossipDef.h @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_GOSSIP_H +#define MANGOSSERVER_GOSSIP_H + +#include "Common.h" +#include "QuestDef.h" +#include "NPCHandler.h" + +class WorldSession; + +#define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough +#define DEFAULT_GOSSIP_MESSAGE 0xffffff + +//POI defines +enum Poi_Icon +{ + ICON_POI_0 = 0, // Grey ? + ICON_POI_1 = 1, // Red ? + ICON_POI_2 = 2, // Blue ? + ICON_POI_BWTOMB = 3, // Blue and White Tomb Stone + ICON_POI_HOUSE = 4, // House + ICON_POI_TOWER = 5, // Tower + ICON_POI_REDFLAG = 6, // Red Flag with Yellow ! + ICON_POI_TOMB = 7, // Tomb Stone + ICON_POI_BWTOWER = 8, // Blue and White Tower + ICON_POI_REDTOWER = 9, // Red Tower + ICON_POI_BLUETOWER = 10, // Blue Tower + ICON_POI_RWTOWER = 11, // Red and White Tower + ICON_POI_REDTOMB = 12, // Red Tomb Stone + ICON_POI_RWTOMB = 13, // Red and White Tomb Stone + ICON_POI_BLUETOMB = 14, // Blue Tomb Stone + ICON_POI_NOTHING = 15, // NOTHING + ICON_POI_16 = 16, // Red ? + ICON_POI_17 = 17, // Grey ? + ICON_POI_18 = 18, // Blue ? + ICON_POI_19 = 19, // Red and White ? + ICON_POI_20 = 20, // Red ? + ICON_POI_GREYLOGS = 21, // Grey Wood Logs + ICON_POI_BWLOGS = 22, // Blue and White Wood Logs + ICON_POI_BLUELOGS = 23, // Blue Wood Logs + ICON_POI_RWLOGS = 24, // Red and White Wood Logs + ICON_POI_REDLOGS = 25, // Red Wood Logs + ICON_POI_26 = 26, // Grey ? + ICON_POI_27 = 27, // Blue and White ? + ICON_POI_28 = 28, // Blue ? + ICON_POI_29 = 29, // Red and White ? + ICON_POI_30 = 30, // Red ? + ICON_POI_GREYHOUSE = 31, // Grey House + ICON_POI_BWHOUSE = 32, // Blue and White House + ICON_POI_BLUEHOUSE = 33, // Blue House + ICON_POI_RWHOUSE = 34, // Red and White House + ICON_POI_REDHOUSE = 35, // Red House + ICON_POI_GREYHORSE = 36, // Grey Horse + ICON_POI_BWHORSE = 37, // Blue and White Horse + ICON_POI_BLUEHORSE = 38, // Blue Horse + ICON_POI_RWHORSE = 39, // Red and White Horse + ICON_POI_REDHORSE = 40 // Red Horse +}; + +struct GossipMenuItem +{ + uint8 m_gIcon; + bool m_gCoded; + std::string m_gMessage; + uint32 m_gSender; + uint32 m_gAction; + std::string m_gBoxMessage; + uint32 m_gBoxMoney; +}; + +typedef std::vector GossipMenuItemList; + +struct QuestMenuItem +{ + uint32 m_qId; + uint8 m_qIcon; +}; + +typedef std::vector QuestMenuItemList; + +class MANGOS_DLL_SPEC GossipMenu +{ + public: + GossipMenu(); + ~GossipMenu(); + + void AddMenuItem(uint8 Icon, std::string Message, bool Coded = false); + void AddMenuItem(uint8 Icon, std::string Message, uint32 dtSender, uint32 dtAction, std::string BoxMessage, uint32 BoxMoney, bool Coded = false); + + // for using from scripts, don't must be inlined + void AddMenuItem(uint8 Icon, char const* Message, bool Coded = false); + void AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded = false); + + unsigned int MenuItemCount() const + { + return m_gItems.size(); + } + + bool Empty() const + { + return m_gItems.empty(); + } + + GossipMenuItem const& GetItem( unsigned int Id ) + { + return m_gItems[ Id ]; + } + + uint32 MenuItemSender( unsigned int ItemId ); + uint32 MenuItemAction( unsigned int ItemId ); + bool MenuItemCoded( unsigned int ItemId ); + + void ClearMenu(); + + protected: + GossipMenuItemList m_gItems; +}; + +class QuestMenu +{ + public: + QuestMenu(); + ~QuestMenu(); + + void AddMenuItem( uint32 QuestId, uint8 Icon); + void ClearMenu(); + + uint8 MenuItemCount() const + { + return m_qItems.size(); + } + + bool Empty() const + { + return m_qItems.empty(); + } + + bool HasItem( uint32 questid ); + + QuestMenuItem const& GetItem( uint16 Id ) + { + return m_qItems[ Id ]; + } + + protected: + QuestMenuItemList m_qItems; +}; + +class MANGOS_DLL_SPEC PlayerMenu +{ + private: + GossipMenu mGossipMenu; + QuestMenu mQuestMenu; + WorldSession* pSession; + + public: + PlayerMenu( WorldSession *Session ); + ~PlayerMenu(); + + GossipMenu& GetGossipMenu() { return mGossipMenu; } + QuestMenu& GetQuestMenu() { return mQuestMenu; } + + bool Empty() const { return mGossipMenu.Empty() && mQuestMenu.Empty(); } + + void ClearMenus(); + uint32 GossipOptionSender( unsigned int Selection ); + uint32 GossipOptionAction( unsigned int Selection ); + bool GossipOptionCoded( unsigned int Selection ); + + void SendGossipMenu( uint32 TitleTextId, uint64 npcGUID ); + void CloseGossip(); + void SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, const char * locName ); + void SendTalking( uint32 textID ); + void SendTalking( char const * title, char const * text ); + + /*********************************************************/ + /*** QUEST SYSTEM ***/ + /*********************************************************/ + void SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID ); + + void SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint64 npcGUID ); + + void SendQuestQueryResponse ( Quest const *pQuest ); + void SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept); + + void SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext ); + void SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel ); +}; +#endif diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h new file mode 100644 index 000000000..0942c5c31 --- /dev/null +++ b/src/game/GridDefines.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRIDDEFINES_H +#define MANGOS_GRIDDEFINES_H + +#include "Common.h" +#include "GameSystem/NGrid.h" +#include + +// Forward class definitions +class Corpse; +class Creature; +class DynamicObject; +class GameObject; +class Pet; +class Player; + +#define MAX_NUMBER_OF_GRIDS 64 + +#define SIZE_OF_GRIDS 533.33333f +#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2) + +#define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2) + +#define MIN_GRID_DELAY MINUTE*1000 +#define MIN_MAP_UPDATE_DELAY 50 + +#define MAX_NUMBER_OF_CELLS 8 +#define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS) + +#define CENTER_GRID_CELL_ID 256 +#define CENTER_GRID_CELL_OFFSET (SIZE_OF_GRID_CELL/2) + +#define TOTAL_NUMBER_OF_CELLS_PER_MAP (MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_CELLS) + +#define MAP_RESOLUTION 256 + +#define MAP_SIZE (SIZE_OF_GRIDS*MAX_NUMBER_OF_GRIDS) +#define MAP_HALFSIZE (MAP_SIZE/2) + +// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) +typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes; +typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes; + +typedef GridRefManager CorpseMapType; +typedef GridRefManager CreatureMapType; +typedef GridRefManager DynamicObjectMapType; +typedef GridRefManager GameObjectMapType; +typedef GridRefManager PlayerMapType; + +typedef Grid GridType; +typedef NGrid<8, Player, AllWorldObjectTypes, AllGridObjectTypes> NGridType; + +typedef TypeMapContainer GridTypeMapContainer; +typedef TypeMapContainer WorldTypeMapContainer; + +template +struct MANGOS_DLL_DECL CoordPair +{ + CoordPair(uint32 x=0, uint32 y=0) : x_coord(x), y_coord(y) {} + CoordPair(const CoordPair &obj) : x_coord(obj.x_coord), y_coord(obj.y_coord) {} + bool operator==(const CoordPair &obj) const { return (obj.x_coord == x_coord && obj.y_coord == y_coord); } + bool operator!=(const CoordPair &obj) const { return !operator==(obj); } + CoordPair& operator=(const CoordPair &obj) + { + x_coord = obj.x_coord; + y_coord = obj.y_coord; + return *this; + } + + void operator<<(const uint32 val) + { + if( x_coord >= val ) + x_coord -= val; + } + + void operator>>(const uint32 val) + { + if( x_coord+val < LIMIT ) + x_coord += val; + } + + void operator-=(const uint32 val) + { + if( y_coord >= val ) + y_coord -= val; + } + + void operator+=(const uint32 val) + { + if( y_coord+val < LIMIT ) + y_coord += val; + } + + uint32 x_coord; + uint32 y_coord; +}; + +typedef CoordPair GridPair; +typedef CoordPair CellPair; + +namespace MaNGOS +{ + template + inline RET_TYPE Compute(float x, float y, float center_offset, float size) + { + // calculate and store temporary values in double format for having same result as same mySQL calculations + double x_offset = (double(x) - center_offset)/size; + double y_offset = (double(y) - center_offset)/size; + + int x_val = int(x_offset+CENTER_VAL + 0.5); + int y_val = int(y_offset+CENTER_VAL + 0.5); + return RET_TYPE(x_val, y_val); + } + + inline GridPair ComputeGridPair(float x, float y) + { + return Compute(x, y, CENTER_GRID_OFFSET, SIZE_OF_GRIDS); + } + + inline CellPair ComputeCellPair(float x, float y) + { + return Compute(x, y, CENTER_GRID_CELL_OFFSET, SIZE_OF_GRID_CELL); + } + + inline void NormalizeMapCoord(float &c) + { + if(c > MAP_HALFSIZE - 0.5) + c = MAP_HALFSIZE - 0.5; + else if(c < -(MAP_HALFSIZE - 0.5)) + c = -(MAP_HALFSIZE - 0.5); + } + + inline bool IsValidMapCoord(float c) + { + return finite(c) && (std::fabs(c) <= MAP_HALFSIZE - 0.5); + } + + inline bool IsValidMapCoord(float x, float y) + { + return IsValidMapCoord(x) && IsValidMapCoord(y); + } + + inline bool IsValidMapCoord(float x, float y, float z) + { + return IsValidMapCoord(x,y) && finite(z); + } + + inline bool IsValidMapCoord(float x, float y, float z, float o) + { + return IsValidMapCoord(x,y,z) && finite(o); + } +} +#endif diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp new file mode 100644 index 000000000..2d2d63750 --- /dev/null +++ b/src/game/GridNotifiers.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "GridNotifiers.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "UpdateData.h" +#include "Item.h" +#include "Map.h" +#include "MapManager.h" +#include "Transports.h" +#include "ObjectAccessor.h" + +using namespace MaNGOS; + +void +MaNGOS::PlayerNotifier::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if( iter->getSource() == &i_player ) + continue; + + iter->getSource()->UpdateVisibilityOf(&i_player); + i_player.UpdateVisibilityOf(iter->getSource()); + } +} + +void +VisibleChangesNotifier::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if(iter->getSource() == &i_object) + continue; + + iter->getSource()->UpdateVisibilityOf(&i_object); + } +} + +void +VisibleNotifier::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if( iter->getSource() == &i_player ) + continue; + + iter->getSource()->UpdateVisibilityOf(&i_player); + i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_data_updates,i_visibleNow); + i_clientGUIDs.erase(iter->getSource()->GetGUID()); + } +} + +void +VisibleNotifier::Notify() +{ + // at this moment i_clientGUIDs have guids that not iterate at grid level checks + // but exist one case when this possible and object not out of range: transports + if(Transport* transport = i_player.GetTransport()) + { + for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr) + { + if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end()) + { + (*itr)->UpdateVisibilityOf(&i_player); + i_player.UpdateVisibilityOf((*itr),i_data,i_data_updates,i_visibleNow); + i_clientGUIDs.erase((*itr)->GetGUID()); + } + } + } + + // generate outOfRange for not iterate objects + i_data.AddOutOfRangeGUID(i_clientGUIDs); + for(Player::ClientGUIDs::iterator itr = i_clientGUIDs.begin();itr!=i_clientGUIDs.end();++itr) + { + i_player.m_clientGUIDs.erase(*itr); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u) is out of range (no in active cells set) now for player %u",GUID_LOPART(*itr),GuidHigh2TypeId(GUID_HIPART(*itr)),i_player.GetGUIDLow()); + #endif + } + + // send update to other players (except player updates that already sent using SendUpdateToPlayer) + for(UpdateDataMapType::iterator iter = i_data_updates.begin(); iter != i_data_updates.end(); ++iter) + { + if(iter->first==&i_player) + continue; + + WorldPacket packet; + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + } + + if( i_data.HasData() ) + { + // send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer) + WorldPacket packet; + i_data.BuildPacket(&packet); + i_player.GetSession()->SendPacket(&packet); + + // send out of range to other players if need + std::set const& oor = i_data.GetOutOfRangeGUIDs(); + for(std::set::const_iterator iter = oor.begin(); iter != oor.end(); ++iter) + { + if(!IS_PLAYER_GUID(*iter)) + continue; + + Player* plr = ObjectAccessor::GetPlayer(i_player,*iter); + if(plr) + plr->UpdateVisibilityOf(&i_player); + } + } + + // Now do operations that required done at object visibility change to visible + + // target aura duration for caster show only if target exist at caster client + // send data at target visibility change (adding to client) + for(std::set::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr) + if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT)) + i_player.SendAuraDurationsForTarget((Unit*)(*vItr)); +} + +void +MessageDeliverer::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if( i_toSelf || iter->getSource() != &i_player) + { + if(WorldSession* session = iter->getSource()->GetSession()) + session->SendPacket(i_message); + } + } +} + +void +ObjectMessageDeliverer::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if(WorldSession* session = iter->getSource()->GetSession()) + session->SendPacket(i_message); + } +} + +void +MessageDistDeliverer::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if( (i_toSelf || iter->getSource() != &i_player ) && + (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) && + (!i_dist || iter->getSource()->GetDistance(&i_player) <= i_dist) ) + { + if(WorldSession* session = iter->getSource()->GetSession()) + session->SendPacket(i_message); + } + } +} + +void +ObjectMessageDistDeliverer::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if( !i_dist || iter->getSource()->GetDistance(&i_object) <= i_dist ) + { + if(WorldSession* session = iter->getSource()->GetSession()) + session->SendPacket(i_message); + } + } +} + +template void +ObjectUpdater::Visit(GridRefManager &m) +{ + for(typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter) + { + iter->getSource()->Update(i_timeDiff); + } +} + +template void ObjectUpdater::Visit(GameObjectMapType &); +template void ObjectUpdater::Visit(DynamicObjectMapType &); + +bool CannibalizeObjectCheck::operator()(Corpse* u) +{ + // ignore bones + if(u->GetType()==CORPSE_BONES) + return false; + + Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID()); + + if( !owner || i_funit->IsFriendlyTo(owner)) + return false; + + if(i_funit->IsWithinDistInMap(u, i_range) ) + return true; + + return false; +} diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h new file mode 100644 index 000000000..1a22438e7 --- /dev/null +++ b/src/game/GridNotifiers.h @@ -0,0 +1,812 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRIDNOTIFIERS_H +#define MANGOS_GRIDNOTIFIERS_H + +#include "ObjectGridLoader.h" +#include "ByteBuffer.h" +#include "UpdateData.h" +#include + +#include "Corpse.h" +#include "Object.h" +#include "DynamicObject.h" +#include "GameObject.h" +#include "Player.h" +#include "Unit.h" + +class Player; +//class Map; + +namespace MaNGOS +{ + + struct MANGOS_DLL_DECL PlayerNotifier + { + explicit PlayerNotifier(Player &pl) : i_player(pl) {} + void Visit(PlayerMapType &); + template void Visit(GridRefManager &) {} + Player &i_player; + }; + + struct MANGOS_DLL_DECL VisibleNotifier + { + Player &i_player; + UpdateData i_data; + UpdateDataMapType i_data_updates; + Player::ClientGUIDs i_clientGUIDs; + std::set i_visibleNow; + + explicit VisibleNotifier(Player &player) : i_player(player),i_clientGUIDs(player.m_clientGUIDs) {} + template void Visit(GridRefManager &m); + void Visit(PlayerMapType &); + void Notify(void); + }; + + struct MANGOS_DLL_DECL VisibleChangesNotifier + { + WorldObject &i_object; + + explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {} + template void Visit(GridRefManager &) {} + void Visit(PlayerMapType &); + }; + + struct MANGOS_DLL_DECL GridUpdater + { + GridType &i_grid; + uint32 i_timeDiff; + GridUpdater(GridType &grid, uint32 diff) : i_grid(grid), i_timeDiff(diff) {} + + template void updateObjects(GridRefManager &m) + { + for(typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter) + iter->getSource()->Update(i_timeDiff); + } + + void Visit(PlayerMapType &m) { updateObjects(m); } + void Visit(CreatureMapType &m){ updateObjects(m); } + void Visit(GameObjectMapType &m) { updateObjects(m); } + void Visit(DynamicObjectMapType &m) { updateObjects(m); } + void Visit(CorpseMapType &m) { updateObjects(m); } + }; + + struct MANGOS_DLL_DECL MessageDeliverer + { + Player &i_player; + WorldPacket *i_message; + bool i_toSelf; + MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {} + void Visit(PlayerMapType &m); + template void Visit(GridRefManager &) {} + }; + + struct MANGOS_DLL_DECL ObjectMessageDeliverer + { + WorldPacket *i_message; + explicit ObjectMessageDeliverer(WorldPacket *msg) : i_message(msg) {} + void Visit(PlayerMapType &m); + template void Visit(GridRefManager &) {} + }; + + struct MANGOS_DLL_DECL MessageDistDeliverer + { + Player &i_player; + WorldPacket *i_message; + bool i_toSelf; + bool i_ownTeamOnly; + float i_dist; + MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly) : i_player(pl), i_message(msg), i_dist(dist), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly) {} + void Visit(PlayerMapType &m); + template void Visit(GridRefManager &) {} + }; + + struct MANGOS_DLL_DECL ObjectMessageDistDeliverer + { + WorldObject &i_object; + WorldPacket *i_message; + float i_dist; + ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {} + void Visit(PlayerMapType &m); + template void Visit(GridRefManager &) {} + }; + + struct MANGOS_DLL_DECL ObjectUpdater + { + uint32 i_timeDiff; + explicit ObjectUpdater(const uint32 &diff) : i_timeDiff(diff) {} + template void Visit(GridRefManager &m); + void Visit(PlayerMapType &) {} + void Visit(CorpseMapType &) {} + void Visit(CreatureMapType &); + }; + + template + struct MANGOS_DLL_DECL ObjectAccessorNotifier + { + T *& i_object; + + uint64 i_id; + ObjectAccessorNotifier(T * &obj, uint64 id) : i_object(obj), i_id(id) + { + i_object = NULL; + } + + void Visit(GridRefManager &m ) + { + if( i_object == NULL ) + { + GridRefManager *iter = m.find(i_id); + if( iter != m.end() ) + { + assert( iter->second != NULL ); + i_object = iter->second; + } + } + } + + template void Visit(GridRefManager &) {} + }; + + struct MANGOS_DLL_DECL PlayerRelocationNotifier + { + Player &i_player; + PlayerRelocationNotifier(Player &pl) : i_player(pl) {} + template void Visit(GridRefManager &) {} + void Visit(PlayerMapType &); + void Visit(CreatureMapType &); + }; + + struct MANGOS_DLL_DECL CreatureRelocationNotifier + { + Creature &i_creature; + CreatureRelocationNotifier(Creature &c) : i_creature(c) {} + template void Visit(GridRefManager &) {} + #ifdef WIN32 + template<> void Visit(PlayerMapType &); + #endif + }; + + struct MANGOS_DLL_DECL DynamicObjectUpdater + { + DynamicObject &i_dynobject; + Unit* i_check; + DynamicObjectUpdater(DynamicObject &dynobject, Unit* caster) : i_dynobject(dynobject) + { + i_check = caster; + Unit* owner = i_check->GetOwner(); + if(owner) + i_check = owner; + } + + template inline void Visit(GridRefManager &) {} + #ifdef WIN32 + template<> inline void Visit(PlayerMapType &); + template<> inline void Visit(CreatureMapType &); + #endif + + void VisitHelper(Unit* target); + }; + + // SEARCHERS & LIST SEARCHERS & WORKERS + + // WorldObject searchers & workers + + template + struct MANGOS_DLL_DECL WorldObjectSearcher + { + WorldObject* &i_object; + Check &i_check; + + WorldObjectSearcher(WorldObject* & result, Check& check) : i_object(result),i_check(check) {} + + void Visit(GameObjectMapType &m); + void Visit(PlayerMapType &m); + void Visit(CreatureMapType &m); + void Visit(CorpseMapType &m); + void Visit(DynamicObjectMapType &m); + + template void Visit(GridRefManager &) {} + }; + + template + struct MANGOS_DLL_DECL WorldObjectListSearcher + { + std::list &i_objects; + Check& i_check; + + WorldObjectListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + + void Visit(PlayerMapType &m); + void Visit(CreatureMapType &m); + void Visit(CorpseMapType &m); + void Visit(GameObjectMapType &m); + void Visit(DynamicObjectMapType &m); + + template void Visit(GridRefManager &) {} + }; + + template + struct MANGOS_DLL_DECL WorldObjectWorker + { + Do const& i_do; + + explicit WorldObjectWorker(Do const& _do) : i_do(_do) {} + + void Visit(GameObjectMapType &m) + { + for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + i_do(itr->getSource()); + } + + void Visit(PlayerMapType &m) + { + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + i_do(itr->getSource()); + } + void Visit(CreatureMapType &m) + { + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + i_do(itr->getSource()); + } + + void Visit(CorpseMapType &m) + { + for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + i_do(itr->getSource()); + } + + void Visit(DynamicObjectMapType &m) + { + for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + i_do(itr->getSource()); + } + + template void Visit(GridRefManager &) {} + }; + + // Gameobject searchers + + template + struct MANGOS_DLL_DECL GameObjectSearcher + { + GameObject* &i_object; + Check &i_check; + + GameObjectSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {} + + void Visit(GameObjectMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // Last accepted by Check GO if any (Check can change requirements at each call) + template + struct MANGOS_DLL_DECL GameObjectLastSearcher + { + GameObject* &i_object; + Check& i_check; + + GameObjectLastSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {} + + void Visit(GameObjectMapType &m); + + template void Visit(GridRefManager &) {} + }; + + template + struct MANGOS_DLL_DECL GameObjectListSearcher + { + std::list &i_objects; + Check& i_check; + + GameObjectListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + + void Visit(GameObjectMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // Unit searchers + + // First accepted by Check Unit if any + template + struct MANGOS_DLL_DECL UnitSearcher + { + Unit* &i_object; + Check & i_check; + + UnitSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {} + + void Visit(CreatureMapType &m); + void Visit(PlayerMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // Last accepted by Check Unit if any (Check can change requirements at each call) + template + struct MANGOS_DLL_DECL UnitLastSearcher + { + Unit* &i_object; + Check & i_check; + + UnitLastSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {} + + void Visit(CreatureMapType &m); + void Visit(PlayerMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // All accepted by Check units if any + template + struct MANGOS_DLL_DECL UnitListSearcher + { + std::list &i_objects; + Check& i_check; + + UnitListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + + void Visit(PlayerMapType &m); + void Visit(CreatureMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // Creature searchers + + template + struct MANGOS_DLL_DECL CreatureSearcher + { + Creature* &i_object; + Check & i_check; + + CreatureSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {} + + void Visit(CreatureMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // Last accepted by Check Creature if any (Check can change requirements at each call) + template + struct MANGOS_DLL_DECL CreatureLastSearcher + { + Creature* &i_object; + Check & i_check; + + CreatureLastSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {} + + void Visit(CreatureMapType &m); + + template void Visit(GridRefManager &) {} + }; + + template + struct MANGOS_DLL_DECL CreatureListSearcher + { + std::list &i_objects; + Check& i_check; + + CreatureListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + + void Visit(CreatureMapType &m); + + template void Visit(GridRefManager &) {} + }; + + // Player searchers + + template + struct MANGOS_DLL_DECL PlayerSearcher + { + Player* &i_object; + Check & i_check; + + PlayerSearcher(Player* & result, Check & check) : i_object(result),i_check(check) {} + + void Visit(PlayerMapType &m); + + template void Visit(GridRefManager &) {} + }; + + template + struct MANGOS_DLL_DECL PlayerWorker + { + Do& i_do; + + explicit PlayerWorker(Do& _do) : i_do(_do) {} + + void Visit(PlayerMapType &m) + { + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + i_do(itr->getSource()); + } + + template void Visit(GridRefManager &) {} + }; + + // CHECKS && DO classes + + // WorldObject check classes + class CannibalizeObjectCheck + { + public: + CannibalizeObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {} + bool operator()(Player* u) + { + if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ) + return false; + + if(i_funit->IsWithinDistInMap(u, i_range) ) + return true; + + return false; + } + bool operator()(Corpse* u); + bool operator()(Creature* u) + { + if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() || + (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0) + return false; + + if(i_funit->IsWithinDistInMap(u, i_range) ) + return true; + + return false; + } + template bool operator()(NOT_INTERESTED* u) { return false; } + private: + Unit* const i_funit; + float i_range; + }; + + // WorldObject do classes + + class RespawnDo + { + public: + RespawnDo() {} + void operator()(Creature* u) const { u->Respawn(); } + void operator()(GameObject* u) const { u->Respawn(); } + void operator()(WorldObject*) const {} + void operator()(Corpse*) const {} + }; + + // GameObject checks + + class GameObjectFocusCheck + { + public: + GameObjectFocusCheck(Unit const* unit,uint32 focusId) : i_unit(unit), i_focusId(focusId) {} + bool operator()(GameObject* go) const + { + if(go->GetGOInfo()->type != GAMEOBJECT_TYPE_SPELL_FOCUS) + return false; + + if(go->GetGOInfo()->spellFocus.focusId != i_focusId) + return false; + + float dist = go->GetGOInfo()->spellFocus.dist; + + return go->IsWithinDistInMap(i_unit, dist); + } + private: + Unit const* i_unit; + uint32 i_focusId; + }; + + // Find the nearest Fishing hole and return true only if source object is in range of hole + class NearestGameObjectFishingHole + { + public: + NearestGameObjectFishingHole(WorldObject const& obj, float range) : i_obj(obj), i_range(range) {} + bool operator()(GameObject* go) + { + if(go->GetGOInfo()->type == GAMEOBJECT_TYPE_FISHINGHOLE && go->isSpawned() && i_obj.IsWithinDistInMap(go, i_range) && i_obj.IsWithinDistInMap(go, go->GetGOInfo()->fishinghole.radius)) + { + i_range = i_obj.GetDistance(go); + return true; + } + return false; + } + float GetLastRange() const { return i_range; } + private: + WorldObject const& i_obj; + float i_range; + + // prevent clone + NearestGameObjectFishingHole(NearestGameObjectFishingHole const&); + }; + + // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO) + class NearestGameObjectEntryInObjectRangeCheck + { + public: + NearestGameObjectEntryInObjectRangeCheck(WorldObject const& obj,uint32 entry, float range) : i_obj(obj), i_entry(entry), i_range(range) {} + bool operator()(GameObject* go) + { + if(go->GetEntry() == i_entry && i_obj.IsWithinDistInMap(go, i_range)) + { + i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check + return true; + } + return false; + } + float GetLastRange() const { return i_range; } + private: + WorldObject const& i_obj; + uint32 i_entry; + float i_range; + + // prevent clone this object + NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&); + }; + + class GameObjectWithDbGUIDCheck + { + public: + GameObjectWithDbGUIDCheck(WorldObject const& obj,uint32 db_guid) : i_obj(obj), i_db_guid(db_guid) {} + bool operator()(GameObject const* go) const + { + return go->GetDBTableGUIDLow() == i_db_guid; + } + private: + WorldObject const& i_obj; + uint32 i_db_guid; + }; + + // Unit checks + + class AnyUnfriendlyUnitInObjectRangeCheck + { + public: + AnyUnfriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} + bool operator()(Unit* u) + { + if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u)) + return true; + else + return false; + } + private: + WorldObject const* i_obj; + Unit const* i_funit; + float i_range; + }; + + class AnyFriendlyUnitInObjectRangeCheck + { + public: + AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} + bool operator()(Unit* u) + { + if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u)) + return true; + else + return false; + } + private: + WorldObject const* i_obj; + Unit const* i_funit; + float i_range; + }; + + class AnyUnitInObjectRangeCheck + { + public: + AnyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {} + bool operator()(Unit* u) + { + if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range)) + return true; + + return false; + } + private: + WorldObject const* i_obj; + float i_range; + }; + + // Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit) + class NearestAttackableUnitInObjectRangeCheck + { + public: + NearestAttackableUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} + bool operator()(Unit* u) + { + if( u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) && + !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,false) ) + { + i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check + return true; + } + + return false; + } + private: + WorldObject const* i_obj; + Unit const* i_funit; + float i_range; + + // prevent clone this object + NearestAttackableUnitInObjectRangeCheck(NearestAttackableUnitInObjectRangeCheck const&); + }; + + class AnyAoETargetUnitInObjectRangeCheck + { + public: + AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) + : i_obj(obj), i_funit(funit), i_range(range) + { + Unit const* check = i_funit; + Unit const* owner = i_funit->GetOwner(); + if(owner) + check = owner; + i_targetForPlayer = ( check->GetTypeId()==TYPEID_PLAYER ); + } + bool operator()(Unit* u) + { + // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems + if (!u->isTargetableForAttack()) + return false; + if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem()) + return false; + + if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range)) + return true; + + return false; + } + private: + bool i_targetForPlayer; + WorldObject const* i_obj; + Unit const* i_funit; + float i_range; + }; + + struct AnyDeadUnitCheck + { + bool operator()(Unit* u) { return !u->isAlive(); } + }; + + struct AnyStealthedCheck + { + bool operator()(Unit* u) { return u->GetVisibility()==VISIBILITY_GROUP_STEALTH; } + }; + + // Creature checks + + class InAttackDistanceFromAnyHostileCreatureCheck + { + public: + explicit InAttackDistanceFromAnyHostileCreatureCheck(Unit* funit) : i_funit(funit) {} + bool operator()(Creature* u) + { + if(u->isAlive() && u->IsHostileTo(i_funit) && i_funit->IsWithinDistInMap(u, u->GetAttackDistance(i_funit))) + return true; + + return false; + } + private: + Unit* const i_funit; + }; + + class AnyAssistCreatureInRangeCheck + { + public: + AnyAssistCreatureInRangeCheck(Unit* funit, Unit* enemy, float range) + : i_funit(funit), i_enemy(enemy), i_range(range) + { + } + bool operator()(Creature* u) + { + if(u == i_funit) + return false; + + // we don't need help from zombies :) + if( !u->isAlive() ) + return false; + + // skip fighting creature + if( u->isInCombat() ) + return false; + + // only from same creature faction + if(u->getFaction() != i_funit->getFaction() ) + return false; + + // only free creature + if( u->GetCharmerOrOwnerGUID() ) + return false; + + // too far + if( !i_funit->IsWithinDistInMap(u, i_range) ) + return false; + + // skip non hostile to caster enemy creatures + if( !u->IsHostileTo(i_enemy) ) + return false; + + // only if see assisted creature + if(!u->IsWithinLOSInMap(i_funit) ) + return false; + + return true; + } + private: + Unit* const i_funit; + Unit* const i_enemy; + float i_range; + }; + + // Success at unit in range, range update for next check (this can be use with CreatureLastSearcher to find nearest creature) + class NearestCreatureEntryWithLiveStateInObjectRangeCheck + { + public: + NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject const& obj,uint32 entry, bool alive, float range) + : i_obj(obj), i_entry(entry), i_alive(alive), i_range(range) {} + + bool operator()(Creature* u) + { + if(u->GetEntry() == i_entry && u->isAlive()==i_alive && i_obj.IsWithinDistInMap(u, i_range)) + { + i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check + return true; + } + return false; + } + float GetLastRange() const { return i_range; } + private: + WorldObject const& i_obj; + uint32 i_entry; + bool i_alive; + float i_range; + + // prevent clone this object + NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&); + }; + + class AnyPlayerInObjectRangeCheck + { + public: + AnyPlayerInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {} + bool operator()(Player* u) + { + if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range)) + return true; + + return false; + } + private: + WorldObject const* i_obj; + float i_range; + }; + + #ifndef WIN32 + template<> void PlayerRelocationNotifier::Visit(CreatureMapType &); + template<> void PlayerRelocationNotifier::Visit(PlayerMapType &); + template<> void CreatureRelocationNotifier::Visit(PlayerMapType &); + template<> void CreatureRelocationNotifier::Visit(CreatureMapType &); + template<> inline void DynamicObjectUpdater::Visit(CreatureMapType &); + template<> inline void DynamicObjectUpdater::Visit(PlayerMapType &); + #endif +} +#endif diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h new file mode 100644 index 000000000..05eb46197 --- /dev/null +++ b/src/game/GridNotifiersImpl.h @@ -0,0 +1,489 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRIDNOTIFIERSIMPL_H +#define MANGOS_GRIDNOTIFIERSIMPL_H + +#include "GridNotifiers.h" +#include "WorldPacket.h" +#include "Corpse.h" +#include "Player.h" +#include "UpdateData.h" +#include "CreatureAI.h" +#include "SpellAuras.h" + +template +inline void +MaNGOS::VisibleNotifier::Visit(GridRefManager &m) +{ + for(typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter) + { + i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_data_updates,i_visibleNow); + i_clientGUIDs.erase(iter->getSource()->GetGUID()); + } +} + +inline void +MaNGOS::ObjectUpdater::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + if(!iter->getSource()->isSpiritService()) + iter->getSource()->Update(i_timeDiff); +} + +inline void +MaNGOS::PlayerRelocationNotifier::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if(&i_player==iter->getSource()) + continue; + + // visibility for players updated by ObjectAccessor::UpdateVisibilityFor calls in appropriate places + + // Cancel Trade + if(i_player.GetTrader()==iter->getSource()) + // iteraction distance + if(!i_player.IsWithinDistInMap(iter->getSource(), 5)) + i_player.GetSession()->SendCancelTrade(); // will clode both side trade windows + } +} + +inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c) +{ + // update creature visibility at player/creature move + pl->UpdateVisibilityOf(c); + + // Creature AI reaction + if(!c->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) + { + if( c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode() ) + c->AI()->MoveInLineOfSight(pl); + } +} + +inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) +{ + if(!c1->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) + { + if( c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode() ) + c1->AI()->MoveInLineOfSight(c2); + } + + if(!c2->hasUnitState(UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING)) + { + if( c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode() ) + c2->AI()->MoveInLineOfSight(c1); + } +} + +inline void +MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m) +{ + if(!i_player.isAlive() || i_player.isInFlight()) + return; + + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + if( iter->getSource()->isAlive()) + PlayerCreatureRelocationWorker(&i_player,iter->getSource()); +} + +template<> +inline void +MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m) +{ + if(!i_creature.isAlive()) + return; + + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + if( iter->getSource()->isAlive() && !iter->getSource()->isInFlight()) + PlayerCreatureRelocationWorker(iter->getSource(), &i_creature); +} + +template<> +inline void +MaNGOS::CreatureRelocationNotifier::Visit(CreatureMapType &m) +{ + if(!i_creature.isAlive()) + return; + + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + Creature* c = iter->getSource(); + if( c != &i_creature && c->isAlive()) + CreatureCreatureRelocationWorker(c, &i_creature); + } +} + +inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) +{ + if(!target->isAlive() || target->isInFlight() ) + return; + + if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isTotem()) + return; + + if (!i_dynobject.IsWithinDistInMap(target, i_dynobject.GetRadius())) + return; + + //Check targets for not_selectable unit flag and remove + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) + return; + + // Evade target + if( target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->IsInEvadeMode() ) + return; + + //Check player targets and remove if in GM mode or GM invisibility (for not self casting case) + if( target->GetTypeId()==TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) ) + return; + + if( i_check->GetTypeId()==TYPEID_PLAYER ) + { + if (i_check->IsFriendlyTo( target )) + return; + } + else + { + if (!i_check->IsHostileTo( target )) + return; + } + + if (i_dynobject.IsAffecting(target)) + return; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId()); + uint32 eff_index = i_dynobject.GetEffIndex(); + // Check target immune to spell or aura + if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo->Effect[eff_index], spellInfo->EffectMechanic[eff_index])) + return; + // Apply PersistentAreaAura on target + PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster()); + target->AddAura(Aur); + i_dynobject.AddAffected(target); +} + +template<> +inline void +MaNGOS::DynamicObjectUpdater::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + VisitHelper(itr->getSource()); +} + +template<> +inline void +MaNGOS::DynamicObjectUpdater::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + VisitHelper(itr->getSource()); +} + +// SEARCHERS & LIST SEARCHERS & WORKERS + +// WorldObject searchers & workers + +template +void MaNGOS::WorldObjectSearcher::Visit(GameObjectMapType &m) +{ + // already found + if(i_object) + return; + + for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::WorldObjectSearcher::Visit(PlayerMapType &m) +{ + // already found + if(i_object) + return; + + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::WorldObjectSearcher::Visit(CreatureMapType &m) +{ + // already found + if(i_object) + return; + + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::WorldObjectSearcher::Visit(CorpseMapType &m) +{ + // already found + if(i_object) + return; + + for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::WorldObjectSearcher::Visit(DynamicObjectMapType &m) +{ + // already found + if(i_object) + return; + + for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::WorldObjectListSearcher::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +template +void MaNGOS::WorldObjectListSearcher::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +template +void MaNGOS::WorldObjectListSearcher::Visit(CorpseMapType &m) +{ + for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +template +void MaNGOS::WorldObjectListSearcher::Visit(GameObjectMapType &m) +{ + for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +template +void MaNGOS::WorldObjectListSearcher::Visit(DynamicObjectMapType &m) +{ + for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +// Gameobject searchers + +template +void MaNGOS::GameObjectSearcher::Visit(GameObjectMapType &m) +{ + // already found + if(i_object) + return; + + for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::GameObjectLastSearcher::Visit(GameObjectMapType &m) +{ + for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + i_object = itr->getSource(); + } +} + +template +void MaNGOS::GameObjectListSearcher::Visit(GameObjectMapType &m) +{ + for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +// Unit searchers + +template +void MaNGOS::UnitSearcher::Visit(CreatureMapType &m) +{ + // already found + if(i_object) + return; + + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::UnitSearcher::Visit(PlayerMapType &m) +{ + // already found + if(i_object) + return; + + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::UnitLastSearcher::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + i_object = itr->getSource(); + } +} + +template +void MaNGOS::UnitLastSearcher::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + i_object = itr->getSource(); + } +} + +template +void MaNGOS::UnitListSearcher::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +template +void MaNGOS::UnitListSearcher::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +// Creature searchers + +template +void MaNGOS::CreatureSearcher::Visit(CreatureMapType &m) +{ + // already found + if(i_object) + return; + + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +template +void MaNGOS::CreatureLastSearcher::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + i_object = itr->getSource(); + } +} + +template +void MaNGOS::CreatureListSearcher::Visit(CreatureMapType &m) +{ + for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); +} + +template +void MaNGOS::PlayerSearcher::Visit(PlayerMapType &m) +{ + // already found + if(i_object) + return; + + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + if(i_check(itr->getSource())) + { + i_object = itr->getSource(); + return; + } + } +} + +#endif // MANGOS_GRIDNOTIFIERSIMPL_H diff --git a/src/game/GridStates.cpp b/src/game/GridStates.cpp new file mode 100644 index 000000000..abbac8054 --- /dev/null +++ b/src/game/GridStates.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "GridStates.h" +#include "GridNotifiers.h" +#include "ObjectAccessor.h" +#include "GameSystem/Grid.h" +#include "Log.h" + +void +InvalidState::Update(Map &, NGridType &, GridInfo &, const uint32 &/*x*/, const uint32 &/*y*/, const uint32 &) const +{ +} + +void +ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const +{ + // Only check grid activity every (grid_expiry/10) ms, because it's really useless to do it every cycle + info.UpdateTimeTracker(t_diff); + if( info.getTimeTracker().Passed() ) + { + if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().PlayersNearGrid(x, y, m.GetId(), m.GetInstanceId()) ) + { + ObjectGridStoper stoper(grid); + stoper.StopN(); + grid.SetGridState(GRID_STATE_IDLE); + } + else + { + m.ResetGridExpiry(grid, 0.1f); + } + } +} + +void +IdleState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &) const +{ + m.ResetGridExpiry(grid); + grid.SetGridState(GRID_STATE_REMOVAL); + sLog.outDebug("Grid[%u,%u] on map %u moved to IDLE state", x, y, m.GetId()); +} + +void +RemovalState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const +{ + if(info.getUnloadFlag()) + { + info.UpdateTimeTracker(t_diff); + if( info.getTimeTracker().Passed() ) + { + if( !m.UnloadGrid(x, y, false) ) + { + sLog.outDebug("Grid[%u,%u] for map %u differed unloading due to players nearby", x, y, m.GetId()); + m.ResetGridExpiry(grid); + } + } + } +} diff --git a/src/game/GridStates.h b/src/game/GridStates.h new file mode 100644 index 000000000..8e2e6eeec --- /dev/null +++ b/src/game/GridStates.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRIDSTATES_H +#define MANGOS_GRIDSTATES_H + +#include "Map.h" + +class MANGOS_DLL_DECL GridState +{ + public: +#ifdef MANGOS_DEBUG +#define MAGIC_TESTVAL 0xFBE823BA + GridState() { i_Magic = MAGIC_TESTVAL; } + bool checkMagic() + { + if(i_Magic != MAGIC_TESTVAL) + { + sLog.outError("!!! GridState: Magic value gone !!!"); + return false; + } + return true; + } + void setMagic() { i_Magic = MAGIC_TESTVAL; } + unsigned int i_Magic; +#endif + virtual void Update(Map &, NGridType&, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &t_diff) const = 0; +}; + +class MANGOS_DLL_DECL InvalidState : public GridState +{ + public: + + void Update(Map &, NGridType &, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &t_diff) const; +}; + +class MANGOS_DLL_DECL ActiveState : public GridState +{ + public: + + void Update(Map &, NGridType &, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &t_diff) const; +}; + +class MANGOS_DLL_DECL IdleState : public GridState +{ + public: + + void Update(Map &, NGridType &, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &t_diff) const; +}; + +class MANGOS_DLL_DECL RemovalState : public GridState +{ + public: + + void Update(Map &, NGridType &, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &t_diff) const; +}; +#endif diff --git a/src/game/Group.cpp b/src/game/Group.cpp new file mode 100644 index 000000000..512350333 --- /dev/null +++ b/src/game/Group.cpp @@ -0,0 +1,1405 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Opcodes.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Player.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Group.h" +#include "ObjectAccessor.h" +#include "BattleGround.h" +#include "MapManager.h" +#include "InstanceSaveMgr.h" +#include "MapInstanced.h" +#include "Util.h" + +Group::Group() +{ + m_leaderGuid = 0; + m_mainTank = 0; + m_mainAssistant = 0; + m_groupType = (GroupType)0; + m_bgGroup = NULL; + m_lootMethod = (LootMethod)0; + m_looterGuid = 0; + m_lootThreshold = ITEM_QUALITY_UNCOMMON; + + for(int i=0; iGetBgRaid(ALLIANCE) == this) m_bgGroup->SetBgRaid(ALLIANCE, NULL); + else if(m_bgGroup->GetBgRaid(HORDE) == this) m_bgGroup->SetBgRaid(HORDE, NULL); + else sLog.outError("Group::~Group: battleground group is not linked to the correct battleground."); + } + Rolls::iterator itr; + while(!RollId.empty()) + { + itr = RollId.begin(); + Roll *r = *itr; + RollId.erase(itr); + delete(r); + } + + // it is undefined whether objectmgr (which stores the groups) or instancesavemgr + // will be unloaded first so we must be prepared for both cases + // this may unload some instance saves + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) + itr->second.save->RemoveGroup(this); +} + +bool Group::Create(const uint64 &guid, const char * name) +{ + m_leaderGuid = guid; + m_leaderName = name; + + m_groupType = isBGGroup() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL; + m_lootMethod = GROUP_LOOT; + m_lootThreshold = ITEM_QUALITY_UNCOMMON; + m_looterGuid = guid; + + m_difficulty = DIFFICULTY_NORMAL; + if(!isBGGroup()) + { + Player *leader = objmgr.GetPlayer(guid); + if(leader) m_difficulty = leader->GetDifficulty(); + + Player::ConvertInstancesToGroup(leader, this, guid); + + // store group in database + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid)); + CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid)); + CharacterDatabase.PExecute("INSERT INTO groups(leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,isRaid,difficulty) " + "VALUES('%u','%u','%u','%u','%u','%u','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','%u','%u')", + GUID_LOPART(m_leaderGuid), GUID_LOPART(m_mainTank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod), + GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), m_difficulty); + } + + if(!AddMember(guid, name)) + return false; + + if(!isBGGroup()) CharacterDatabase.CommitTransaction(); + + return true; +} + +bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool loadMembers) +{ + if(isBGGroup()) + return false; + + bool external = true; + if(!result) + { + external = false; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + result = CharacterDatabase.PQuery("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(leaderGuid)); + if(!result) + return false; + } + + m_leaderGuid = leaderGuid; + + // group leader not exist + if(!objmgr.GetPlayerNameByGUID(m_leaderGuid, m_leaderName)) + { + if(!external) delete result; + return false; + } + + m_groupType = (*result)[13].GetBool() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL; + m_difficulty = (*result)[14].GetUInt8(); + m_mainTank = (*result)[0].GetUInt64(); + m_mainAssistant = (*result)[1].GetUInt64(); + m_lootMethod = (LootMethod)(*result)[2].GetUInt8(); + m_looterGuid = MAKE_NEW_GUID((*result)[3].GetUInt32(), 0, HIGHGUID_PLAYER); + m_lootThreshold = (ItemQualities)(*result)[4].GetUInt16(); + + for(int i=0; iNextRow() ); + delete result; + // group too small + if(GetMembersCount() < 2) + return false; + } + + return true; +} + +bool Group::LoadMemberFromDB(uint32 guidLow, uint8 subgroup, bool assistant) +{ + MemberSlot member; + member.guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER); + + // skip non-existed member + if(!objmgr.GetPlayerNameByGUID(member.guid, member.name)) + return false; + + member.group = subgroup; + member.assistant = assistant; + m_memberSlots.push_back(member); + return true; +} + +bool Group::AddInvite(Player *player) +{ + if(!player || player->GetGroupInvite() || player->GetGroup()) + return false; + + RemoveInvite(player); + + m_invitees.insert(player->GetGUID()); + + player->SetGroupInvite(this); + + return true; +} + +bool Group::AddLeaderInvite(Player *player) +{ + if(!AddInvite(player)) + return false; + + m_leaderGuid = player->GetGUID(); + m_leaderName = player->GetName(); + return true; +} + +uint32 Group::RemoveInvite(Player *player) +{ + for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr) + { + if((*itr) == player->GetGUID()) + { + m_invitees.erase(itr); + break; + } + } + + player->SetGroupInvite(NULL); + return GetMembersCount(); +} + +void Group::RemoveAllInvites() +{ + for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr) + { + Player *invitee = objmgr.GetPlayer(*itr); + if(invitee) + invitee->SetGroupInvite(NULL); + } + m_invitees.clear(); +} + +bool Group::AddMember(const uint64 &guid, const char* name) +{ + if(!_addMember(guid, name)) + return false; + SendUpdate(); + + Player *player = objmgr.GetPlayer(guid); + if(player) + { + if(!IsLeader(player->GetGUID()) && !isBGGroup()) + { + // reset the new member's instances, unless he is currently in one of them + // including raid/heroic instances that they are not permanently bound to! + player->ResetInstances(INSTANCE_RESET_GROUP_JOIN); + + if(player->getLevel() >= LEVELREQUIREMENT_HEROIC && player->GetDifficulty() != GetDifficulty() ) + { + player->SetDifficulty(m_difficulty); + player->SendDungeonDifficulty(true); + } + } + player->SetGroupUpdateFlag(GROUP_UPDATE_FULL); + UpdatePlayerOutOfRange(player); + } + + return true; +} + +uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method) +{ + // remove member and change leader (if need) only if strong more 2 members _before_ member remove + if(GetMembersCount() > (isBGGroup() ? 1 : 2)) // in BG group case allow 1 members group + { + bool leaderChanged = _removeMember(guid); + + Player *player = objmgr.GetPlayer( guid ); + if (player) + { + WorldPacket data; + + if(method == 1) + { + data.Initialize( SMSG_GROUP_UNINVITE, 0 ); + player->GetSession()->SendPacket( &data ); + } + + data.Initialize(SMSG_GROUP_LIST, 24); + data << uint64(0) << uint64(0) << uint64(0); + player->GetSession()->SendPacket(&data); + + _homebindIfInstance(player); + } + + if(leaderChanged) + { + WorldPacket data(SMSG_GROUP_SET_LEADER, (m_memberSlots.front().name.size()+1)); + data << m_memberSlots.front().name; + BroadcastPacket(&data); + } + + SendUpdate(); + } + // if group before remove <= 2 disband it + else + Disband(true); + + return m_memberSlots.size(); +} + +void Group::ChangeLeader(const uint64 &guid) +{ + member_citerator slot = _getMemberCSlot(guid); + + if(slot==m_memberSlots.end()) + return; + + _setLeader(guid); + + WorldPacket data(SMSG_GROUP_SET_LEADER, slot->name.size()+1); + data << slot->name; + BroadcastPacket(&data); + SendUpdate(); +} + +void Group::Disband(bool hideDestroy) +{ + Player *player; + + for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + { + player = objmgr.GetPlayer(citr->guid); + if(!player) + continue; + + player->SetGroup(NULL); + + if(!player->GetSession()) + continue; + + WorldPacket data; + if(!hideDestroy) + { + data.Initialize(SMSG_GROUP_DESTROYED, 0); + player->GetSession()->SendPacket(&data); + } + + data.Initialize(SMSG_GROUP_LIST, 24); + data << uint64(0) << uint64(0) << uint64(0); + player->GetSession()->SendPacket(&data); + + _homebindIfInstance(player); + } + RollId.clear(); + m_memberSlots.clear(); + + RemoveAllInvites(); + + if(!isBGGroup()) + { + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); + CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); + CharacterDatabase.CommitTransaction(); + ResetInstances(INSTANCE_RESET_GROUP_DISBAND, NULL); + } + + m_leaderGuid = 0; + m_leaderName = ""; +} + +/*********************************************************/ +/*** LOOT SYSTEM ***/ +/*********************************************************/ + +void Group::SendLootStartRoll(uint32 CountDown, const Roll &r) +{ + WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4)); + data << uint64(r.itemGUID); // guid of rolled item + data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it??? + data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for + data << uint32(r.itemRandomSuffix); // randomSuffix + data << uint32(r.itemRandomPropId); // item random property ID + data << uint32(CountDown); // the countdown time to choose "need" or "greed" + + for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr!=r.playerVote.end(); ++itr) + { + Player *p = objmgr.GetPlayer(itr->first); + if(!p || !p->GetSession()) + continue; + + if(itr->second != NOT_VALID) + p->GetSession()->SendPacket( &data ); + } +} + +void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) +{ + WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1)); + data << uint64(SourceGuid); // guid of the item rolled + data << uint32(0); // unknown, maybe amount of players + data << uint64(TargetGuid); + data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for + data << uint32(r.itemRandomSuffix); // randomSuffix + data << uint32(r.itemRandomPropId); // Item random property ID + data << uint8(RollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number + data << uint8(RollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll + data << uint8(0); // 2.4.0 + + for( Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr!=r.playerVote.end(); ++itr) + { + Player *p = objmgr.GetPlayer(itr->first); + if(!p || !p->GetSession()) + continue; + + if(itr->second != NOT_VALID) + p->GetSession()->SendPacket( &data ); + } +} + +void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) +{ + WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1)); + data << uint64(SourceGuid); // guid of the item rolled + data << uint32(0); // unknown, maybe amount of players + data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for + data << uint32(r.itemRandomSuffix); // randomSuffix + data << uint32(r.itemRandomPropId); // Item random property + data << uint64(TargetGuid); // guid of the player who won. + data << uint8(RollNumber); // rollnumber realted to SMSG_LOOT_ROLL + data << uint8(RollType); // Rolltype related to SMSG_LOOT_ROLL + + for( Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr!=r.playerVote.end(); ++itr) + { + Player *p = objmgr.GetPlayer(itr->first); + if(!p || !p->GetSession()) + continue; + + if(itr->second != NOT_VALID) + p->GetSession()->SendPacket( &data ); + } +} + +void Group::SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r) +{ + WorldPacket data(SMSG_LOOT_ALL_PASSED, (8+4+4+4+4)); + data << uint64(r.itemGUID); // Guid of the item rolled + data << uint32(NumberOfPlayers); // The number of players rolling for it??? + data << uint32(r.itemid); // The itemEntryId for the item that shall be rolled for + data << uint32(r.itemRandomPropId); // Item random property ID + data << uint32(r.itemRandomSuffix); // Item random suffix ID + + for( Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr!=r.playerVote.end(); ++itr) + { + Player *p = objmgr.GetPlayer(itr->first); + if(!p || !p->GetSession()) + continue; + + if(itr->second != NOT_VALID) + p->GetSession()->SendPacket( &data ); + } +} + +void Group::GroupLoot(uint64 playerGUID, Loot *loot, Creature *creature) +{ + std::vector::iterator i; + ItemPrototype const *item; + uint8 itemSlot = 0; + Player *player = objmgr.GetPlayer(playerGUID); + Group *group = player->GetGroup(); + + for (i=loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot) + { + item = objmgr.GetItemPrototype(i->itemid); + if (!item) + { + //sLog.outDebug("Group::GroupLoot: missing item prototype for item with id: %d", i->itemid); + continue; + } + + //roll for over-threshold item if it's one-player loot + if (item->Quality >= uint32(m_lootThreshold) && !i->freeforall) + { + uint64 newitemGUID = MAKE_NEW_GUID(objmgr.GenerateLowGuid(HIGHGUID_ITEM),0,HIGHGUID_ITEM); + Roll* r=new Roll(newitemGUID,*i); + + //a vector is filled with only near party members + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *member = itr->getSource(); + if(!member || !member->GetSession()) + continue; + if ( i->AllowedForPlayer(member) ) + { + if (member->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + { + r->playerVote[member->GetGUID()] = NOT_EMITED_YET; + ++r->totalPlayersRolling; + } + } + } + + r->setLoot(loot); + r->itemSlot = itemSlot; + + group->SendLootStartRoll(60000, *r); + + loot->items[itemSlot].is_blocked = true; + creature->m_groupLootTimer = 60000; + creature->lootingGroupLeaderGUID = GetLeaderGUID(); + + RollId.push_back(r); + } + else + i->is_underthreshold=1; + + } +} + +void Group::NeedBeforeGreed(uint64 playerGUID, Loot *loot, Creature *creature) +{ + ItemPrototype const *item; + Player *player = objmgr.GetPlayer(playerGUID); + Group *group = player->GetGroup(); + + uint8 itemSlot = 0; + for(std::vector::iterator i=loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot) + { + item = objmgr.GetItemPrototype(i->itemid); + + //only roll for one-player items, not for ones everyone can get + if (item->Quality >= uint32(m_lootThreshold) && !i->freeforall) + { + uint64 newitemGUID = MAKE_NEW_GUID(objmgr.GenerateLowGuid(HIGHGUID_ITEM),0,HIGHGUID_ITEM); + Roll* r=new Roll(newitemGUID,*i); + + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *playerToRoll = itr->getSource(); + if(!playerToRoll || !playerToRoll->GetSession()) + continue; + + if (playerToRoll->CanUseItem(item) && i->AllowedForPlayer(playerToRoll) ) + { + if (playerToRoll->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + { + r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; + ++r->totalPlayersRolling; + } + } + } + + if (r->totalPlayersRolling > 0) + { + r->setLoot(loot); + r->itemSlot = itemSlot; + + group->SendLootStartRoll(60000, *r); + + loot->items[itemSlot].is_blocked = true; + + RollId.push_back(r); + } + else + { + delete r; + } + } + else + i->is_underthreshold=1; + } +} + +void Group::MasterLoot(uint64 playerGUID, Loot* /*loot*/, Creature *creature) +{ + Player *player = objmgr.GetPlayer(playerGUID); + if(!player) + return; + + sLog.outDebug("Group::MasterLoot (SMSG_LOOT_MASTER_LIST, 330) player = [%s].", player->GetName()); + + uint32 real_count = 0; + + WorldPacket data(SMSG_LOOT_MASTER_LIST, 330); + data << (uint8)GetMembersCount(); + + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *looter = itr->getSource(); + if (!looter->IsInWorld()) + continue; + + if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + { + data << looter->GetGUID(); + ++real_count; + } + } + + data.put(0,real_count); + + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *looter = itr->getSource(); + if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + looter->GetSession()->SendPacket(&data); + } +} + +void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise) +{ + Rolls::iterator rollI = GetRoll(Guid); + if (rollI == RollId.end()) + return; + Roll* roll = *rollI; + + Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGUID); + // this condition means that player joins to the party after roll begins + if (itr == roll->playerVote.end()) + return; + + if (roll->getLoot()) + if (roll->getLoot()->items.empty()) + return; + + switch (Choise) + { + case 0: //Player choose pass + { + SendLootRoll(0, playerGUID, 128, 128, *roll); + ++roll->totalPass; + itr->second = PASS; + } + break; + case 1: //player choose Need + { + SendLootRoll(0, playerGUID, 0, 0, *roll); + ++roll->totalNeed; + itr->second = NEED; + } + break; + case 2: //player choose Greed + { + SendLootRoll(0, playerGUID, 128, 2, *roll); + ++roll->totalGreed; + itr->second = GREED; + } + break; + } + if (roll->totalPass + roll->totalGreed + roll->totalNeed >= roll->totalPlayersRolling) + { + CountTheRoll(rollI, NumberOfPlayers); + } +} + +//called when roll timer expires +void Group::EndRoll() +{ + Rolls::iterator itr; + while(!RollId.empty()) + { + //need more testing here, if rolls disappear + itr = RollId.begin(); + CountTheRoll(itr, GetMembersCount()); //i don't have to edit player votes, who didn't vote ... he will pass + } +} + +void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers) +{ + Roll* roll = *rollI; + if(!roll->isValid()) // is loot already deleted ? + { + RollId.erase(rollI); + delete roll; + return; + } + //end of the roll + if (roll->totalNeed > 0) + { + if(!roll->playerVote.empty()) + { + uint8 maxresul = 0; + uint64 maxguid = (*roll->playerVote.begin()).first; + Player *player; + + for( Roll::PlayerVote::const_iterator itr=roll->playerVote.begin(); itr!=roll->playerVote.end(); ++itr) + { + if (itr->second != NEED) + continue; + + uint8 randomN = urand(1, 99); + SendLootRoll(0, itr->first, randomN, 1, *roll); + if (maxresul < randomN) + { + maxguid = itr->first; + maxresul = randomN; + } + } + SendLootRollWon(0, maxguid, maxresul, 1, *roll); + player = objmgr.GetPlayer(maxguid); + + if(player && player->GetSession()) + { + ItemPosCountVec dest; + LootItem *item = &(roll->getLoot()->items[roll->itemSlot]); + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count ); + if ( msg == EQUIP_ERR_OK ) + { + item->is_looted = true; + roll->getLoot()->NotifyItemRemoved(roll->itemSlot); + --roll->getLoot()->unlootedCount; + player->StoreNewItem( dest, roll->itemid, true, item->randomPropertyId); + } + else + { + item->is_blocked = false; + player->SendEquipError( msg, NULL, NULL ); + } + } + } + } + else if (roll->totalGreed > 0) + { + if(!roll->playerVote.empty()) + { + uint8 maxresul = 0; + uint64 maxguid = (*roll->playerVote.begin()).first; + Player *player; + + Roll::PlayerVote::iterator itr; + for (itr=roll->playerVote.begin(); itr!=roll->playerVote.end(); ++itr) + { + if (itr->second != GREED) + continue; + + uint8 randomN = urand(1, 99); + SendLootRoll(0, itr->first, randomN, 2, *roll); + if (maxresul < randomN) + { + maxguid = itr->first; + maxresul = randomN; + } + } + SendLootRollWon(0, maxguid, maxresul, 2, *roll); + player = objmgr.GetPlayer(maxguid); + + if(player && player->GetSession()) + { + ItemPosCountVec dest; + LootItem *item = &(roll->getLoot()->items[roll->itemSlot]); + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count ); + if ( msg == EQUIP_ERR_OK ) + { + item->is_looted = true; + roll->getLoot()->NotifyItemRemoved(roll->itemSlot); + --roll->getLoot()->unlootedCount; + player->StoreNewItem( dest, roll->itemid, true, item->randomPropertyId); + } + else + { + item->is_blocked = false; + player->SendEquipError( msg, NULL, NULL ); + } + } + } + } + else + { + SendLootAllPassed(NumberOfPlayers, *roll); + LootItem *item = &(roll->getLoot()->items[roll->itemSlot]); + if(item) item->is_blocked = false; + } + RollId.erase(rollI); + delete roll; +} + +void Group::SetTargetIcon(uint8 id, uint64 guid) +{ + if(id >= TARGETICONCOUNT) + return; + + // clean other icons + if( guid != 0 ) + for(int i=0; inext()) + { + Player* member = itr->getSource(); + if(!member || !member->isAlive()) // only for alive + continue; + + if(!member->IsAtGroupRewardDistance(victim)) // at req. distance + continue; + + ++count; + sum_level += member->getLevel(); + if(!member_with_max_level || member_with_max_level->getLevel() < member->getLevel()) + member_with_max_level = member; + } +} + +void Group::SendTargetIconList(WorldSession *session) +{ + if(!session) + return; + + WorldPacket data(MSG_RAID_TARGET_UPDATE, (1+TARGETICONCOUNT*9)); + data << (uint8)1; + + for(int i=0; iSendPacket(&data); +} + +void Group::SendUpdate() +{ + Player *player; + + for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + { + player = objmgr.GetPlayer(citr->guid); + if(!player || !player->GetSession()) + continue; + // guess size + WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+8+4+GetMembersCount()*20)); + data << (uint8)m_groupType; // group type + data << (uint8)(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? + data << (uint8)(citr->group); // groupid + data << (uint8)(citr->assistant?0x01:0); // 0x2 main assist, 0x4 main tank + data << uint64(0x50000000FFFFFFFELL); // related to voice chat? + data << uint32(GetMembersCount()-1); + for(member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) + { + if(citr->guid == citr2->guid) + continue; + + data << citr2->name; + data << (uint64)citr2->guid; + // online-state + data << (uint8)(objmgr.GetPlayer(citr2->guid) ? 1 : 0); + data << (uint8)(citr2->group); // groupid + data << (uint8)(citr2->assistant?0x01:0); // 0x2 main assist, 0x4 main tank + } + + data << uint64(m_leaderGuid); // leader guid + if(GetMembersCount()-1) + { + data << (uint8)m_lootMethod; // loot method + data << (uint64)m_looterGuid; // looter guid + data << (uint8)m_lootThreshold; // loot threshold + data << (uint8)m_difficulty; // Heroic Mod Group + } + player->GetSession()->SendPacket( &data ); + } +} + +void Group::UpdatePlayerOutOfRange(Player* pPlayer) +{ + if(!pPlayer) + return; + + Player *player; + WorldPacket data; + pPlayer->GetSession()->BuildPartyMemberStatsChangedPacket(pPlayer, &data); + + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + player = itr->getSource(); + if (player && player != pPlayer && !pPlayer->isVisibleFor(player)) + player->GetSession()->SendPacket(&data); + } +} + +void Group::BroadcastPacket(WorldPacket *packet, int group, uint64 ignore) +{ + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pl = itr->getSource(); + if(!pl || (ignore != 0 && pl->GetGUID() == ignore)) + continue; + + if (pl->GetSession() && (group==-1 || itr->getSubGroup()==group)) + pl->GetSession()->SendPacket(packet); + } +} + +void Group::BroadcastReadyCheck(WorldPacket *packet) +{ + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pl = itr->getSource(); + if(pl && pl->GetSession()) + if(IsLeader(pl->GetGUID()) || IsAssistant(pl->GetGUID())) + pl->GetSession()->SendPacket(packet); + } +} + +void Group::OfflineReadyCheck() +{ + for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + { + Player *pl = objmgr.GetPlayer(citr->guid); + if (!pl || !pl->GetSession()) + { + WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9); + data << citr->guid; + data << (uint8)0; + BroadcastReadyCheck(&data); + } + } +} + +bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant) +{ + // get first not-full group + uint8 groupid = 0; + std::vector temp(MAXRAIDSIZE/MAXGROUPSIZE); + for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + if (itr->group >= temp.size()) continue; + ++temp[itr->group]; + if(temp[groupid] >= MAXGROUPSIZE) + ++groupid; + } + + return _addMember(guid, name, isAssistant, groupid); +} + +bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group) +{ + if(IsFull()) + return false; + + if(!guid) + return false; + + Player *player = objmgr.GetPlayer(guid); + + MemberSlot member; + member.guid = guid; + member.name = name; + member.group = group; + member.assistant = isAssistant; + m_memberSlots.push_back(member); + + if(player) + { + player->SetGroupInvite(NULL); + player->SetGroup(this, group); + // if the same group invites the player back, cancel the homebind timer + InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player->GetDifficulty()); + if(bind && bind->save->GetInstanceId() == player->GetInstanceId()) + player->m_InstanceValid = true; + } + + if(!isRaidGroup()) // reset targetIcons for non-raid-groups + { + for(int i=0; iSetGroup(NULL); + } + + _removeRolls(guid); + + member_witerator slot = _getMemberWSlot(guid); + if (slot != m_memberSlots.end()) + m_memberSlots.erase(slot); + + if(!isBGGroup()) + CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid='%u'", GUID_LOPART(guid)); + + if(m_leaderGuid == guid) // leader was removed + { + if(GetMembersCount() > 0) + _setLeader(m_memberSlots.front().guid); + return true; + } + + return false; +} + +void Group::_setLeader(const uint64 &guid) +{ + member_citerator slot = _getMemberCSlot(guid); + if(slot==m_memberSlots.end()) + return; + + if(!isBGGroup()) + { + // TODO: set a time limit to have this function run rarely cause it can be slow + CharacterDatabase.BeginTransaction(); + + // update the group's bound instances when changing leaders + + // remove all permanent binds from the group + // in the DB also remove solo binds that will be replaced with permbinds + // from the new leader + CharacterDatabase.PExecute( + "DELETE FROM group_instance WHERE leaderguid='%u' AND (permanent = 1 OR " + "instance IN (SELECT instance FROM character_instance WHERE guid = '%u')" + ")", GUID_LOPART(m_leaderGuid), GUID_LOPART(slot->guid) + ); + + Player *player = objmgr.GetPlayer(slot->guid); + if(player) + { + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();) + { + if(itr->second.perm) + { + itr->second.save->RemoveGroup(this); + m_boundInstances[i].erase(itr++); + } + else + ++itr; + } + } + } + + // update the group's solo binds to the new leader + CharacterDatabase.PExecute("UPDATE group_instance SET leaderGuid='%u' WHERE leaderGuid = '%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_leaderGuid)); + + // copy the permanent binds from the new leader to the group + // overwriting the solo binds with permanent ones if necessary + // in the DB those have been deleted already + Player::ConvertInstancesToGroup(player, this, slot->guid); + + // update the group leader + CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE leaderGuid='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_leaderGuid)); + CharacterDatabase.PExecute("UPDATE group_member SET leaderGuid='%u' WHERE leaderGuid='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_leaderGuid)); + CharacterDatabase.CommitTransaction(); + } + + m_leaderGuid = slot->guid; + m_leaderName = slot->name; +} + +void Group::_removeRolls(const uint64 &guid) +{ + for (Rolls::iterator it = RollId.begin(); it < RollId.end(); it++) + { + Roll* roll = *it; + Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid); + if(itr2 == roll->playerVote.end()) + continue; + + if (itr2->second == GREED) --roll->totalGreed; + if (itr2->second == NEED) --roll->totalNeed; + if (itr2->second == PASS) --roll->totalPass; + if (itr2->second != NOT_VALID) --roll->totalPlayersRolling; + + roll->playerVote.erase(itr2); + + CountRollVote(guid, roll->itemGUID, GetMembersCount()-1, 3); + } +} + +void Group::_convertToRaid() +{ + m_groupType = GROUPTYPE_RAID; + + if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); +} + +bool Group::_setMembersGroup(const uint64 &guid, const uint8 &group) +{ + member_witerator slot = _getMemberWSlot(guid); + if(slot==m_memberSlots.end()) + return false; + + slot->group = group; + if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid)); + return true; +} + +bool Group::_setAssistantFlag(const uint64 &guid, const bool &state) +{ + member_witerator slot = _getMemberWSlot(guid); + if(slot==m_memberSlots.end()) + return false; + + slot->assistant = state; + if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET assistant='%u' WHERE memberGuid='%u'", (state==true)?1:0, GUID_LOPART(guid)); + return true; +} + +bool Group::_setMainTank(const uint64 &guid) +{ + member_citerator slot = _getMemberCSlot(guid); + if(slot==m_memberSlots.end()) + return false; + + if(m_mainAssistant == guid) + _setMainAssistant(0); + m_mainTank = guid; + if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET mainTank='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainTank), GUID_LOPART(m_leaderGuid)); + return true; +} + +bool Group::_setMainAssistant(const uint64 &guid) +{ + member_witerator slot = _getMemberWSlot(guid); + if(slot==m_memberSlots.end()) + return false; + + if(m_mainTank == guid) + _setMainTank(0); + m_mainAssistant = guid; + if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET mainAssistant='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainAssistant), GUID_LOPART(m_leaderGuid)); + return true; +} + +bool Group::SameSubGroup(Player const* member1, Player const* member2) const +{ + if(!member1 || !member2) return false; + if (member1->GetGroup() != this || member2->GetGroup() != this) return false; + else return member1->GetSubGroup() == member2->GetSubGroup(); +} + +// allows setting subgroup for offline members +void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group) +{ + if(!isRaidGroup()) + return; + Player *player = objmgr.GetPlayer(guid); + if (!player) + { + if(_setMembersGroup(guid, group)) + SendUpdate(); + } + else ChangeMembersGroup(player, group); +} + +// only for online members +void Group::ChangeMembersGroup(Player *player, const uint8 &group) +{ + if(!player || !isRaidGroup()) + return; + if(_setMembersGroup(player->GetGUID(), group)) + { + player->GetGroupRef().setSubGroup(group); + SendUpdate(); + } +} + +void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) +{ + switch (GetLootMethod()) + { + case MASTER_LOOT: + case FREE_FOR_ALL: + return; + default: + // round robin style looting applies for all low + // quality items in each loot method except free for all and master loot + break; + } + + member_citerator guid_itr = _getMemberCSlot(GetLooterGuid()); + if(guid_itr != m_memberSlots.end()) + { + if(ifneed) + { + // not update if only update if need and ok + Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid); + if(looter && looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + return; + } + ++guid_itr; + } + + // search next after current + if(guid_itr != m_memberSlots.end()) + { + for(member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr) + { + if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) + { + if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + { + bool refresh = pl->GetLootGUID()==creature->GetGUID(); + + //if(refresh) // update loot for new looter + // pl->GetSession()->DoLootRelease(pl->GetLootGUID()); + SetLooterGuid(pl->GetGUID()); + SendUpdate(); + if(refresh) // update loot for new looter + pl->SendLoot(creature->GetGUID(),LOOT_CORPSE); + return; + } + } + } + } + + // search from start + for(member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr) + { + if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) + { + if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + { + bool refresh = pl->GetLootGUID()==creature->GetGUID(); + + //if(refresh) // update loot for new looter + // pl->GetSession()->DoLootRelease(pl->GetLootGUID()); + SetLooterGuid(pl->GetGUID()); + SendUpdate(); + if(refresh) // update loot for new looter + pl->SendLoot(creature->GetGUID(),LOOT_CORPSE); + return; + } + } + } + + SetLooterGuid(0); + SendUpdate(); +} + +//=================================================== +//============== Roll =============================== +//=================================================== + +void Roll::targetObjectBuildLink() +{ + // called from link() + this->getTarget()->addLootValidatorRef(this); +} + +void Group::SetDifficulty(uint8 difficulty) +{ + m_difficulty = difficulty; + if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE leaderGuid ='%u'", m_difficulty, GUID_LOPART(m_leaderGuid)); + + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *player = itr->getSource(); + if(!player->GetSession() || player->getLevel() < LEVELREQUIREMENT_HEROIC) + continue; + player->SetDifficulty(difficulty); + player->SendDungeonDifficulty(true); + } +} + +bool Group::InCombatToInstance(uint32 instanceId) +{ + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pPlayer = itr->getSource(); + if(pPlayer->getAttackers().size() && pPlayer->GetInstanceId() == instanceId) + return true; + } + return false; +} + +void Group::ResetInstances(uint8 method, Player* SendMsgTo) +{ + if(isBGGroup()) + return; + + // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND + + // we assume that when the difficulty changes, all instances that can be reset will be + uint8 dif = GetDifficulty(); + + for(BoundInstancesMap::iterator itr = m_boundInstances[dif].begin(); itr != m_boundInstances[dif].end();) + { + InstanceSave *p = itr->second.save; + const MapEntry *entry = sMapStore.LookupEntry(itr->first); + if(!entry || (!p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND)) + { + ++itr; + continue; + } + + if(method == INSTANCE_RESET_ALL) + { + // the "reset all instances" method can only reset normal maps + if(dif == DIFFICULTY_HEROIC || entry->map_type == MAP_RAID) + { + ++itr; + continue; + } + } + + bool isEmpty = true; + // if the map is loaded, reset it + Map *map = MapManager::Instance().FindMap(p->GetMapId(), p->GetInstanceId()); + if(map && map->IsDungeon()) + isEmpty = ((InstanceMap*)map)->Reset(method); + + if(SendMsgTo) + { + if(isEmpty) SendMsgTo->SendResetInstanceSuccess(p->GetMapId()); + else SendMsgTo->SendResetInstanceFailed(0, p->GetMapId()); + } + + if(isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY) + { + // do not reset the instance, just unbind if others are permanently bound to it + if(p->CanReset()) p->DeleteFromDB(); + else CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", p->GetInstanceId()); + // i don't know for sure if hash_map iterators + m_boundInstances[dif].erase(itr); + itr = m_boundInstances[dif].begin(); + // this unloads the instance save unless online players are bound to it + // (eg. permanent binds or GM solo binds) + p->RemoveGroup(this); + } + else + ++itr; + } +} + +InstanceGroupBind* Group::GetBoundInstance(uint32 mapid, uint8 difficulty) +{ + // some instances only have one difficulty + const MapEntry* entry = sMapStore.LookupEntry(mapid); + if(!entry || !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); + if(itr != m_boundInstances[difficulty].end()) + return &itr->second; + else + return NULL; +} + +InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, bool load) +{ + if(save && !isBGGroup()) + { + InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()]; + if(bind.save) + { + // when a boss is killed or when copying the players's binds to the group + if(permanent != bind.perm || save != bind.save) + if(!load) CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u', permanent = '%u' WHERE leaderGuid = '%u' AND instance = '%u'", save->GetInstanceId(), permanent, GUID_LOPART(GetLeaderGUID()), bind.save->GetInstanceId()); + } + else + if(!load) CharacterDatabase.PExecute("INSERT INTO group_instance (leaderGuid, instance, permanent) VALUES ('%u', '%u', '%u')", GUID_LOPART(GetLeaderGUID()), save->GetInstanceId(), permanent); + + if(bind.save != save) + { + if(bind.save) bind.save->RemoveGroup(this); + save->AddGroup(this); + } + + bind.save = save; + bind.perm = permanent; + if(!load) sLog.outDebug("Group::BindToInstance: %d is now bound to map %d, instance %d, difficulty %d", GUID_LOPART(GetLeaderGUID()), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty()); + return &bind; + } + else + return NULL; +} + +void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload) +{ + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); + if(itr != m_boundInstances[difficulty].end()) + { + if(!unload) CharacterDatabase.PExecute("DELETE FROM group_instance WHERE leaderGuid = '%u' AND instance = '%u'", GUID_LOPART(GetLeaderGUID()), itr->second.save->GetInstanceId()); + itr->second.save->RemoveGroup(this); // save can become invalid + m_boundInstances[difficulty].erase(itr); + } +} + +void Group::_homebindIfInstance(Player *player) +{ + if(player && !player->isGameMaster() && sMapStore.LookupEntry(player->GetMapId())->IsDungeon()) + { + // leaving the group in an instance, the homebind timer is started + // unless the player is permanently saved to the instance + InstanceSave *save = sInstanceSaveManager.GetInstanceSave(player->GetInstanceId()); + InstancePlayerBind *playerBind = save ? player->GetBoundInstance(save->GetMapId(), save->GetDifficulty()) : NULL; + if(!playerBind || !playerBind->perm) + player->m_InstanceValid = false; + } +} diff --git a/src/game/Group.h b/src/game/Group.h new file mode 100644 index 000000000..e30e84732 --- /dev/null +++ b/src/game/Group.h @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_GROUP_H +#define MANGOSSERVER_GROUP_H + +#include "GroupReference.h" +#include "GroupRefManager.h" +#include "LootMgr.h" + +#include +#include + +#define MAXGROUPSIZE 5 +#define MAXRAIDSIZE 40 +#define TARGETICONCOUNT 8 + +enum RollVote +{ + PASS = 0, + NEED = 1, + GREED = 2, + NOT_EMITED_YET = 3, + NOT_VALID = 4 +}; + +enum GroupMemberOnlineStatus +{ + MEMBER_STATUS_OFFLINE = 0x0000, + MEMBER_STATUS_ONLINE = 0x0001, + MEMBER_STATUS_PVP = 0x0002, + MEMBER_STATUS_UNK0 = 0x0004, // dead? (health=0) + MEMBER_STATUS_UNK1 = 0x0008, // ghost? (health=1) + MEMBER_STATUS_UNK2 = 0x0010, // never seen + MEMBER_STATUS_UNK3 = 0x0020, // never seen + MEMBER_STATUS_UNK4 = 0x0040, // appears with dead and ghost flags + MEMBER_STATUS_UNK5 = 0x0080, // never seen +}; + +enum GroupType +{ + GROUPTYPE_NORMAL = 0, + GROUPTYPE_RAID = 1 +}; + +class BattleGround; + +enum GroupUpdateFlags +{ + GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing + GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags + GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint16 + GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint16 + GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 + GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // uint16 + GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // uint16 + GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 + GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 + GROUP_UPDATE_FLAG_POSITION = 0x00000100, // uint16, uint16 + GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint16 spellid + uint8 unk + GROUP_UPDATE_FLAG_PET_GUID = 0x00000400, // uint64 pet guid + GROUP_UPDATE_FLAG_PET_NAME = 0x00000800, // pet name, NULL terminated string + GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00001000, // uint16, model id + GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint16 pet cur health + GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint16 pet max health + GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00008000, // uint8 pet power type + GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power + GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power + GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint16 spellid + uint8 unk, pet auras... + GROUP_UPDATE_PET = 0x0007FC00, // all pet flags + GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags +}; + +#define GROUP_UPDATE_FLAGS_COUNT 20 + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19 +static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 2, 2, 2, 1, 2, 2, 2, 2, 4, 8, 8, 1, 2, 2, 2, 1, 2, 2, 8}; + +class InstanceSave; + +class Roll : public LootValidatorRef +{ + public: + Roll(uint64 _guid, LootItem const& li) + : itemGUID(_guid), itemid(li.itemid), itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), + totalPlayersRolling(0), totalNeed(0), totalGreed(0), totalPass(0), itemSlot(0) {} + ~Roll() { } + void setLoot(Loot *pLoot) { link(pLoot, this); } + Loot *getLoot() { return getTarget(); } + void targetObjectBuildLink(); + + uint64 itemGUID; + uint32 itemid; + int32 itemRandomPropId; + uint32 itemRandomSuffix; + typedef std::map PlayerVote; + PlayerVote playerVote; //vote position correspond with player position (in group) + uint8 totalPlayersRolling; + uint8 totalNeed; + uint8 totalGreed; + uint8 totalPass; + uint8 itemSlot; +}; + +struct InstanceGroupBind +{ + InstanceSave *save; + bool perm; + /* permanent InstanceGroupBinds exist iff the leader has a permanent + PlayerInstanceBind for the same instance. */ + InstanceGroupBind() : save(NULL), perm(false) {} +}; + +/** request member stats checken **/ +/** todo: uninvite people that not accepted invite **/ +class MANGOS_DLL_SPEC Group +{ + public: + struct MemberSlot + { + uint64 guid; + std::string name; + uint8 group; + bool assistant; + }; + typedef std::list MemberSlotList; + typedef MemberSlotList::const_iterator member_citerator; + + typedef HM_NAMESPACE::hash_map< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap; + protected: + typedef MemberSlotList::iterator member_witerator; + typedef std::set InvitesList; + + typedef std::vector Rolls; + + public: + Group(); + ~Group(); + + // group manipulation methods + bool Create(const uint64 &guid, const char * name); + bool LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result = NULL, bool loadMembers = true); + bool LoadMemberFromDB(uint32 guidLow, uint8 subgroup, bool assistant); + bool AddInvite(Player *player); + uint32 RemoveInvite(Player *player); + void RemoveAllInvites(); + bool AddLeaderInvite(Player *player); + bool AddMember(const uint64 &guid, const char* name); + // method: 0=just remove, 1=kick + uint32 RemoveMember(const uint64 &guid, const uint8 &method); + void ChangeLeader(const uint64 &guid); + void SetLootMethod(LootMethod method) { m_lootMethod = method; } + void SetLooterGuid(const uint64 &guid) { m_looterGuid = guid; } + void UpdateLooterGuid( Creature* creature, bool ifneed = false ); + void SetLootThreshold(ItemQualities threshold) { m_lootThreshold = threshold; } + void Disband(bool hideDestroy=false); + + // properties accessories + bool IsFull() const { return (m_groupType==GROUPTYPE_NORMAL) ? (m_memberSlots.size()>=MAXGROUPSIZE) : (m_memberSlots.size()>=MAXRAIDSIZE); } + bool isRaidGroup() const { return m_groupType==GROUPTYPE_RAID; } + bool isBGGroup() const { return m_bgGroup != NULL; } + bool IsCreated() const { return GetMembersCount() > 0; } + const uint64& GetLeaderGUID() const { return m_leaderGuid; } + const char * GetLeaderName() const { return m_leaderName.c_str(); } + LootMethod GetLootMethod() const { return m_lootMethod; } + const uint64& GetLooterGuid() const { return m_looterGuid; } + ItemQualities GetLootThreshold() const { return m_lootThreshold; } + + // member manipulation methods + bool IsMember(uint64 guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); } + bool IsLeader(uint64 guid) const { return (GetLeaderGUID() == guid); } + bool IsAssistant(uint64 guid) const + { + member_citerator mslot = _getMemberCSlot(guid); + if(mslot==m_memberSlots.end()) + return false; + + return mslot->assistant; + } + + bool SameSubGroup(uint64 guid1, uint64 guid2) const + { + member_citerator mslot2 = _getMemberCSlot(guid2); + if(mslot2==m_memberSlots.end()) + return false; + + return SameSubGroup(guid1,&*mslot2); + } + + bool SameSubGroup(uint64 guid1, MemberSlot const* slot2) const + { + member_citerator mslot1 = _getMemberCSlot(guid1); + if(mslot1==m_memberSlots.end() || !slot2) + return false; + + return (mslot1->group==slot2->group); + } + + bool SameSubGroup(Player const* member1, Player const* member2) const; + + MemberSlotList const& GetMemberSlots() const { return m_memberSlots; } + GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); } + uint32 GetMembersCount() const { return m_memberSlots.size(); } + void GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level); + uint8 GetMemberGroup(uint64 guid) const + { + member_citerator mslot = _getMemberCSlot(guid); + if(mslot==m_memberSlots.end()) + return (MAXRAIDSIZE/MAXGROUPSIZE+1); + + return mslot->group; + } + + // some additional raid methods + void ConvertToRaid() + { + _convertToRaid(); + SendUpdate(); + } + void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; } + + void ChangeMembersGroup(const uint64 &guid, const uint8 &group); + void ChangeMembersGroup(Player *player, const uint8 &group); + + void SetAssistant(const uint64 &guid, const bool &state) + { + if(!isRaidGroup()) + return; + if(_setAssistantFlag(guid, state)) + SendUpdate(); + } + void SetMainTank(const uint64 &guid) + { + if(!isRaidGroup()) + return; + + if(_setMainTank(guid)) + SendUpdate(); + } + void SetMainAssistant(const uint64 &guid) + { + if(!isRaidGroup()) + return; + + if(_setMainAssistant(guid)) + SendUpdate(); + } + + void SetTargetIcon(uint8 id, uint64 guid); + void SetDifficulty(uint8 difficulty); + uint8 GetDifficulty() { return m_difficulty; } + uint16 InInstance(); + bool InCombatToInstance(uint32 instanceId); + void ResetInstances(uint8 method, Player* SendMsgTo); + + // -no description- + //void SendInit(WorldSession *session); + void SendTargetIconList(WorldSession *session); + void SendUpdate(); + void UpdatePlayerOutOfRange(Player* pPlayer); + // ignore: GUID of player that will be ignored + void BroadcastPacket(WorldPacket *packet, int group=-1, uint64 ignore=0); + void BroadcastReadyCheck(WorldPacket *packet); + void OfflineReadyCheck(); + + /*********************************************************/ + /*** LOOT SYSTEM ***/ + /*********************************************************/ + + void SendLootStartRoll(uint32 CountDown, const Roll &r); + void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); + void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); + void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r); + void GroupLoot(uint64 playerGUID, Loot *loot, Creature *creature); + void NeedBeforeGreed(uint64 playerGUID, Loot *loot, Creature *creature); + void MasterLoot(uint64 playerGUID, Loot *loot, Creature *creature); + Rolls::iterator GetRoll(uint64 Guid) + { + Rolls::iterator iter; + for (iter=RollId.begin(); iter != RollId.end(); ++iter) + { + if ((*iter)->itemGUID == Guid && (*iter)->isValid()) + { + return iter; + } + } + return RollId.end(); + } + void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers); + void CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise); + void EndRoll(); + + void LinkMember(GroupReference *pRef) { m_memberMgr.insertFirst(pRef); } + void DelinkMember(GroupReference* /*pRef*/ ) { } + + InstanceGroupBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false); + void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false); + InstanceGroupBind* GetBoundInstance(uint32 mapid, uint8 difficulty); + BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; } + + protected: + bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false); + bool _addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group); + bool _removeMember(const uint64 &guid); // returns true if leader has changed + void _setLeader(const uint64 &guid); + + void _removeRolls(const uint64 &guid); + + void _convertToRaid(); + bool _setMembersGroup(const uint64 &guid, const uint8 &group); + bool _setAssistantFlag(const uint64 &guid, const bool &state); + bool _setMainTank(const uint64 &guid); + bool _setMainAssistant(const uint64 &guid); + + void _homebindIfInstance(Player *player); + + member_citerator _getMemberCSlot(uint64 Guid) const + { + for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + if (itr->guid == Guid) + return itr; + } + return m_memberSlots.end(); + } + + member_witerator _getMemberWSlot(uint64 Guid) + { + for(member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + if (itr->guid == Guid) + return itr; + } + return m_memberSlots.end(); + } + + MemberSlotList m_memberSlots; + GroupRefManager m_memberMgr; + InvitesList m_invitees; + uint64 m_leaderGuid; + std::string m_leaderName; + uint64 m_mainTank; + uint64 m_mainAssistant; + GroupType m_groupType; + uint8 m_difficulty; + BattleGround* m_bgGroup; + uint64 m_targetIcons[TARGETICONCOUNT]; + LootMethod m_lootMethod; + ItemQualities m_lootThreshold; + uint64 m_looterGuid; + Rolls RollId; + BoundInstancesMap m_boundInstances[TOTAL_DIFFICULTIES]; +}; +#endif diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp new file mode 100644 index 000000000..5695f1290 --- /dev/null +++ b/src/game/GroupHandler.cpp @@ -0,0 +1,928 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Opcodes.h" +#include "Log.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Group.h" +#include "ObjectAccessor.h" +#include "MapManager.h" +#include "SocialMgr.h" +#include "Util.h" + +/* differeces from off: + -you can uninvite yourself - is is useful + -you can accept invitation even if leader went offline +*/ +/* todo: + -group_destroyed msg is sent but not shown + -reduce xp gaining when in raid group + -quest sharing has to be corrected + -FIX sending PartyMemberStats +*/ + +void WorldSession::SendPartyResult(PartyOperation operation, std::string member, PartyResult res) +{ + WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1)); + data << (uint32)operation; + data << member; + data << (uint32)res; + + SendPacket( &data ); +} + +void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) +{ + std::string membername; + recv_data >> membername; + + if(_player->InBattleGround()) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED); + return; + } + + // attempt add selected player + + // cheating + if(!normalizePlayerName(membername)) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); + return; + } + + Player *player = objmgr.GetPlayer(membername.c_str()); + + // no player + if(!player) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); + return; + } + + // can't group with + if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY); + return; + } + if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE); + return; + } + // just ignore us + if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); + return; + } + + // player already in another group or invited + if(player->GetGroup() || player->GetGroupInvite() ) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP); + return; + } + + Group *group = GetPlayer()->GetGroup(); + + if(group) + { + // not have permissions for invite + if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER); + return; + } + + // not have place + if(group->IsFull()) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); + return; + } + } + + // ok, but group not exist, start a new group + // but don't create and save the group to the DB until + // at least one person joins + if(!group) + { + group = new Group; + // new group: if can't add then delete + if(!group->AddLeaderInvite(GetPlayer())) + { + delete group; + return; + } + if(!group->AddInvite(player)) + { + delete group; + return; + } + } + else + { + // already existed group: if can't add then just leave + if(!group->AddInvite(player)) + { + return; + } + } + + // ok, we do it + WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size + data << GetPlayer()->GetName(); + player->GetSession()->SendPacket(&data); + + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK); +} + +void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ ) +{ + Group *group = GetPlayer()->GetGroupInvite(); + if (!group) return; + + if(group->GetLeaderGUID() == GetPlayer()->GetGUID()) + { + sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); + return; + } + + // remove in from ivites in any case + group->RemoveInvite(GetPlayer()); + + /** error handling **/ + /********************/ + + // not have place + if(group->IsFull()) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); + return; + } + + Player* leader = objmgr.GetPlayer(group->GetLeaderGUID()); + + if(leader && leader->InBattleGround()) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); + return; + } + + // forming a new group, create it + if(!group->IsCreated()) + { + if(leader) group->RemoveInvite(leader); + group->Create(group->GetLeaderGUID(), group->GetLeaderName()); + objmgr.AddGroup(group); + } + + // everything's fine, do it + if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName())) + return; + + uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID()); + + GetPlayer()->SetGroup(group, subgroup); +} + +void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ ) +{ + Group *group = GetPlayer()->GetGroupInvite(); + if (!group) return; + + Player *leader = objmgr.GetPlayer(group->GetLeaderGUID()); + + /** error handling **/ + if(!leader || !leader->GetSession()) + return; + /********************/ + + // everything's fine, do it + if(!group->IsCreated()) + { + // note: this means that if you invite more than one person + // and one of them declines before the first one accepts + // all invites will be cleared + // fixme: is that ok ? + group->RemoveAllInvites(); + delete group; + } + + GetPlayer()->SetGroupInvite(NULL); + + WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size + data << GetPlayer()->GetName(); + leader->GetSession()->SendPacket( &data ); +} + +void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + if(_player->InBattleGround()) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); + return; + } + + std::string membername; + if(!objmgr.GetPlayerNameByGUID(guid, membername)) + return; // not found + + HandleGroupUninvite(guid, membername); +} + +void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,1); + + std::string membername; + recv_data >> membername; + + if(_player->InBattleGround()) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED); + return; + } + + // player not found + if(!normalizePlayerName(membername)) + return; + + uint64 guid = objmgr.GetPlayerGUIDByName(membername); + + // player not found + if(!guid) + return; + + HandleGroupUninvite(guid, membername); +} + +void WorldSession::HandleGroupUninvite(uint64 guid, std::string name) +{ + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + if(_player->InBattleGround()) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); + return; + } + + Player *player = objmgr.GetPlayer(guid); + + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + { + SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_YOU_NOT_LEADER); + return; + } + + if(!group->IsMember(guid) && (player && player->GetGroupInvite() != group)) + { + SendPartyResult(PARTY_OP_LEAVE, name, PARTY_RESULT_NOT_IN_YOUR_PARTY); + return; + } + + if(guid == GetPlayer()->GetGUID()) + { + sLog.outError("WorldSession::HandleGroupUninvite: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); + return; + } + /********************/ + + // everything's fine, do it + + if(player && player->GetGroupInvite()) // uninvite invitee + player->UninviteFromGroup(); + else // uninvite member + Player::RemoveFromGroup(group,guid); +} + +void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + uint64 guid; + recv_data >> guid; + + Player *player = objmgr.GetPlayer(guid); + + /** error handling **/ + if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group) + return; + /********************/ + + // everything's fine, do it + group->ChangeLeader(guid); +} + +void WorldSession::HandleGroupLeaveOpcode( WorldPacket & /*recv_data*/ ) +{ + if(!GetPlayer()->GetGroup()) + return; + + if(_player->InBattleGround()) + { + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); + return; + } + + /** error handling **/ + /********************/ + + // everything's fine, do it + SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK); + + GetPlayer()->RemoveFromGroup(); +} + +void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+8+4); + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + uint32 lootMethod; + uint64 lootMaster; + uint32 lootThreshold; + recv_data >> lootMethod >> lootMaster >> lootThreshold; + + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID())) + return; + /********************/ + + // everything's fine, do it + group->SetLootMethod((LootMethod)lootMethod); + group->SetLooterGuid(lootMaster); + group->SetLootThreshold((ItemQualities)lootThreshold); + group->SendUpdate(); +} + +void WorldSession::HandleLootRoll( WorldPacket &recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+1); + + if(!GetPlayer()->GetGroup()) + return; + + uint64 Guid; + uint32 NumberOfPlayers; + uint8 Choise; + recv_data >> Guid; //guid of the item rolled + recv_data >> NumberOfPlayers; + recv_data >> Choise; //0: pass, 1: need, 2: greed + + //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise); + + Group* group = GetPlayer()->GetGroup(); + if(!group) + return; + + // everything's fine, do it + group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise); +} + +void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4+4); + + if(!GetPlayer()->GetGroup()) + return; + + float x, y; + recv_data >> x; + recv_data >> y; + + //sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y); + + /** error handling **/ + /********************/ + + // everything's fine, do it + WorldPacket data(MSG_MINIMAP_PING, (8+4+4)); + data << GetPlayer()->GetGUID(); + data << x; + data << y; + GetPlayer()->GetGroup()->BroadcastPacket(&data, -1, GetPlayer()->GetGUID()); +} + +void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4+4); + + uint32 minimum, maximum, roll; + recv_data >> minimum; + recv_data >> maximum; + + /** error handling **/ + if(minimum > maximum || maximum > 10000) // < 32768 for urand call + return; + /********************/ + + // everything's fine, do it + roll = urand(minimum, maximum); + + //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll); + + WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8); + data << minimum; + data << maximum; + data << roll; + data << GetPlayer()->GetGUID(); + if(GetPlayer()->GetGroup()) + GetPlayer()->GetGroup()->BroadcastPacket(&data); + else + SendPacket(&data); +} + +void WorldSession::HandleRaidIconTargetOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1); + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + uint8 x; + recv_data >> x; + + /** error handling **/ + /********************/ + + // everything's fine, do it + if(x == 0xFF) // target icon request + { + group->SendTargetIconList(this); + } + else // target icon update + { + // recheck + CHECK_PACKET_SIZE(recv_data,1+8); + + if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + + uint64 guid; + recv_data >> guid; + group->SetTargetIcon(x, guid); + } +} + +void WorldSession::HandleRaidConvertOpcode( WorldPacket & /*recv_data*/ ) +{ + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + if(_player->InBattleGround()) + return; + + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2) + return; + /********************/ + + // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code) + SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK); + group->ConvertToRaid(); +} + +void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1); + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + std::string name; + uint8 groupNr; + recv_data >> name; + + // recheck + CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1); + + recv_data >> groupNr; + + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + /********************/ + + // everything's fine, do it + group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr); +} + +void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+1); + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + uint64 guid; + uint8 flag; + recv_data >> guid; + recv_data >> flag; + + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID())) + return; + /********************/ + + // everything's fine, do it + group->SetAssistant(guid, (flag==0?false:true)); +} + +void WorldSession::HandleGroupPromoteOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 1+1+8); + + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + uint8 flag1, flag2; + uint64 guid; + recv_data >> flag1 >> flag2; + recv_data >> guid; + // if(flag1) Main Assist + // 0x4 + // if(flag2) Main Tank + // 0x2 + + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID())) + return; + /********************/ + + // everything's fine, do it + if(flag1 == 1) + group->SetMainAssistant(guid); + if(flag2 == 1) + group->SetMainTank(guid); +} + +void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data ) +{ + Group *group = GetPlayer()->GetGroup(); + if(!group) + return; + + if(recv_data.empty()) // request + { + /** error handling **/ + if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + /********************/ + + // everything's fine, do it + WorldPacket data(MSG_RAID_READY_CHECK, 8); + data << GetPlayer()->GetGUID(); + group->BroadcastPacket(&data, -1); + + group->OfflineReadyCheck(); + } + else // answer + { + uint8 state; + recv_data >> state; + + // everything's fine, do it + WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9); + data << GetPlayer()->GetGUID(); + data << state; + group->BroadcastReadyCheck(&data); + } +} + +void WorldSession::HandleRaidReadyCheckFinishOpcode( WorldPacket & recv_data ) +{ + //Group* group = GetPlayer()->GetGroup(); + //if(!group) + // return; + + //if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + // return; + + // Is any reaction need? +} + +void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data) +{ + uint32 mask = player->GetGroupUpdateFlag(); + + if (mask == GROUP_UPDATE_FLAG_NONE) + return; + + if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also + mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); + + if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets + mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); + + uint32 byteCount = 0; + for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) + if (mask & (1 << i)) + byteCount += GroupUpdateLength[i]; + + data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); + data->append(player->GetPackGUID()); + *data << (uint32) mask; + + if (mask & GROUP_UPDATE_FLAG_STATUS) + { + if (player) + { + if (player->IsPvP()) + *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); + else + *data << (uint16) MEMBER_STATUS_ONLINE; + } + else + *data << (uint16) MEMBER_STATUS_OFFLINE; + } + + if (mask & GROUP_UPDATE_FLAG_CUR_HP) + *data << (uint16) player->GetHealth(); + + if (mask & GROUP_UPDATE_FLAG_MAX_HP) + *data << (uint16) player->GetMaxHealth(); + + Powers powerType = player->getPowerType(); + if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) + *data << (uint8) powerType; + + if (mask & GROUP_UPDATE_FLAG_CUR_POWER) + *data << (uint16) player->GetPower(powerType); + + if (mask & GROUP_UPDATE_FLAG_MAX_POWER) + *data << (uint16) player->GetMaxPower(powerType); + + if (mask & GROUP_UPDATE_FLAG_LEVEL) + *data << (uint16) player->getLevel(); + + if (mask & GROUP_UPDATE_FLAG_ZONE) + *data << (uint16) player->GetZoneId(); + + if (mask & GROUP_UPDATE_FLAG_POSITION) + *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY(); + + if (mask & GROUP_UPDATE_FLAG_AURAS) + { + uint64 auramask = player->GetAuraUpdateMask(); + *data << uint64(auramask); + for(uint32 i = 0; i < MAX_AURAS; ++i) + { + if(auramask & (uint64(1) << i)) + { + *data << uint16(player->GetUInt32Value(UNIT_FIELD_AURA + i)); + *data << uint8(1); + } + } + } + + Pet *pet = player->GetPet(); + if (mask & GROUP_UPDATE_FLAG_PET_GUID) + { + if(pet) + *data << (uint64) pet->GetGUID(); + else + *data << (uint64) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_NAME) + { + if(pet) + *data << pet->GetName(); + else + *data << (uint8) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) + { + if(pet) + *data << (uint16) pet->GetDisplayId(); + else + *data << (uint16) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) + { + if(pet) + *data << (uint16) pet->GetHealth(); + else + *data << (uint16) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) + { + if(pet) + *data << (uint16) pet->GetMaxHealth(); + else + *data << (uint16) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) + { + if(pet) + *data << (uint8) pet->getPowerType(); + else + *data << (uint8) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) + { + if(pet) + *data << (uint16) pet->GetPower(pet->getPowerType()); + else + *data << (uint16) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) + { + if(pet) + *data << (uint16) pet->GetMaxPower(pet->getPowerType()); + else + *data << (uint16) 0; + } + + if (mask & GROUP_UPDATE_FLAG_PET_AURAS) + { + if(pet) + { + uint64 auramask = pet->GetAuraUpdateMask(); + *data << uint64(auramask); + for(uint32 i = 0; i < MAX_AURAS; ++i) + { + if(auramask & (uint64(1) << i)) + { + *data << uint16(pet->GetUInt32Value(UNIT_FIELD_AURA + i)); + *data << uint8(1); + } + } + } + else + *data << (uint64) 0; + } +} + +/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ +void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); + uint64 Guid; + recv_data >> Guid; + + Player *player = objmgr.GetPlayer(Guid); + if(!player) + { + WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); + data.appendPackGUID(Guid); + data << (uint32) GROUP_UPDATE_FLAG_STATUS; + data << (uint16) MEMBER_STATUS_OFFLINE; + SendPacket(&data); + return; + } + + Pet *pet = player->GetPet(); + + WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); + data.append(player->GetPackGUID()); + + uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF + if(pet) + mask1 = 0x7FFFFFFF; // for hunters and other classes with pets + + Powers powerType = player->getPowerType(); + data << (uint32) mask1; // group update mask + data << (uint16) MEMBER_STATUS_ONLINE; // member's online status + data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP + data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP + data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE + data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER + data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER + data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL + data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE + data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION + data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION + + uint64 auramask = 0; + size_t maskPos = data.wpos(); + data << (uint64) auramask; // placeholder + for(uint8 i = 0; i < MAX_AURAS; ++i) + { + if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) + { + auramask |= (uint64(1) << i); + data << uint16(aura); + data << uint8(1); + } + } + data.put(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS + + if(pet) + { + Powers petpowertype = pet->getPowerType(); + data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID + data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME + data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID + data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP + data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP + data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE + data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER + data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER + + uint64 petauramask = 0; + size_t petMaskPos = data.wpos(); + data << (uint64) petauramask; // placeholder + for(uint8 i = 0; i < MAX_AURAS; ++i) + { + if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) + { + petauramask |= (uint64(1) << i); + data << (uint16) petaura; + data << (uint8) 1; + } + } + data.put(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS + } + else + { + data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME + data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS + } + + SendPacket(&data); +} + +/*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ ) +{ + // every time the player checks the character screen + _player->SendRaidInfo(); +} + +/*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." ); +}*/ + +void WorldSession::HandleGroupPassOnLootOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + + sLog.outDebug("WORLD: Received CMSG_GROUP_PASS_ON_LOOT"); + + uint32 unkn; + recv_data >> unkn; + + // ignore if player not loaded + if(!GetPlayer()) // needed because STATUS_AUTHED + { + if(unkn!=0) + sLog.outError("CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!"); + return; + } + + if(unkn!=0) + sLog.outError("CMSG_GROUP_PASS_ON_LOOT: activation not implemented!"); +} diff --git a/src/game/GroupRefManager.h b/src/game/GroupRefManager.h new file mode 100644 index 000000000..72bcbdb71 --- /dev/null +++ b/src/game/GroupRefManager.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GROUPREFMANAGER +#define _GROUPREFMANAGER + +#include "Utilities/LinkedReference/RefManager.h" + +class Group; +class Player; +class GroupReference; + +class GroupRefManager : public RefManager +{ + public: + GroupReference* getFirst() { return ((GroupReference* ) RefManager::getFirst()); } +}; +#endif diff --git a/src/game/GroupReference.cpp b/src/game/GroupReference.cpp new file mode 100644 index 000000000..6c9bd38dc --- /dev/null +++ b/src/game/GroupReference.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Player.h" +#include "Group.h" +#include "GroupReference.h" + +void GroupReference::targetObjectBuildLink() +{ + // called from link() + getTarget()->LinkMember(this); +} + +void GroupReference::targetObjectDestroyLink() +{ + // called from unlink() + getTarget()->DelinkMember(this); +} + +void GroupReference::sourceObjectDestroyLink() +{ + // called from invalidate() + getTarget()->DelinkMember(this); +} diff --git a/src/game/GroupReference.h b/src/game/GroupReference.h new file mode 100644 index 000000000..7d8d8a922 --- /dev/null +++ b/src/game/GroupReference.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GROUPREFERENCE_H +#define _GROUPREFERENCE_H + +#include "Utilities/LinkedReference/Reference.h" + +class Group; +class Player; + +class MANGOS_DLL_SPEC GroupReference : public Reference +{ + protected: + uint8 iSubGroup; + void targetObjectBuildLink(); + void targetObjectDestroyLink(); + void sourceObjectDestroyLink(); + public: + GroupReference() : Reference(), iSubGroup(0) {} + ~GroupReference() { unlink(); } + GroupReference *next() { return (GroupReference*)Reference::next(); } + uint8 getSubGroup() const { return iSubGroup; } + void setSubGroup(uint8 pSubGroup) { iSubGroup = pSubGroup; } +}; +#endif diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp new file mode 100644 index 000000000..5672f149b --- /dev/null +++ b/src/game/GuardAI.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "GuardAI.h" +#include "Errors.h" +#include "Creature.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "World.h" + +int GuardAI::Permissible(const Creature *creature) +{ + if( creature->isGuard()) + return PERMIT_BASE_SPECIAL; + + return PERMIT_BASE_NO; +} + +GuardAI::GuardAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +{ +} + +void GuardAI::MoveInLineOfSight(Unit *u) +{ + // Ignore Z for flying creatures + if ( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE ) + return; + + if( !i_creature.getVictim() && u->isTargetableForAttack() && + ( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) && + u->isInAccessablePlaceFor(&i_creature)) + { + float attackRadius = i_creature.GetAttackDistance(u); + if(i_creature.IsWithinDistInMap(u,attackRadius)) + { + //Need add code to let guard support player + AttackStart(u); + u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + } +} + +void GuardAI::EnterEvadeMode() +{ + if( !i_creature.isAlive() ) + { + DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow()); + i_creature.StopMoving(); + i_creature.GetMotionMaster()->MoveIdle(); + + i_state = STATE_NORMAL; + + i_victimGuid = 0; + i_creature.CombatStop(); + i_creature.DeleteThreatList(); + return; + } + + Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid ); + + if( !victim ) + { + DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow()); + } + else if( !victim ->isAlive() ) + { + DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", i_creature.GetGUIDLow()); + } + else if( victim ->HasStealthAura() ) + { + DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", i_creature.GetGUIDLow()); + } + else if( victim ->isInFlight() ) + { + DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", i_creature.GetGUIDLow()); + } + else + { + DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", i_creature.GetGUIDLow()); + } + + i_creature.RemoveAllAuras(); + i_creature.DeleteThreatList(); + i_victimGuid = 0; + i_creature.CombatStop(); + i_state = STATE_NORMAL; + + // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead + if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) + i_creature.GetMotionMaster()->MoveTargetedHome(); +} + +void GuardAI::UpdateAI(const uint32 /*diff*/) +{ + // update i_victimGuid if i_creature.getVictim() !=0 and changed + if(!i_creature.SelectHostilTarget() || !i_creature.getVictim()) + return; + + i_victimGuid = i_creature.getVictim()->GetGUID(); + + if( i_creature.isAttackReady() ) + { + if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE)) + { + i_creature.AttackerStateUpdate(i_creature.getVictim()); + i_creature.resetAttackTimer(); + } + } +} + +bool GuardAI::IsVisible(Unit *pl) const +{ + return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER) + && pl->isVisibleForOrDetect(&i_creature,true); +} + +void GuardAI::AttackStart(Unit *u) +{ + if( !u ) + return; + + // DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow()); + if(i_creature.Attack(u,true)) + { + i_creature.SetInCombatWith(u); + u->SetInCombatWith(&i_creature); + + i_creature.AddThreat(u, 0.0f); + i_victimGuid = u->GetGUID(); + i_creature.GetMotionMaster()->MoveChase(u); + } +} + +void GuardAI::JustDied(Unit *killer) +{ + if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) + i_creature.SendZoneUnderAttackMessage(pkiller); +} diff --git a/src/game/GuardAI.h b/src/game/GuardAI.h new file mode 100644 index 000000000..092e222ed --- /dev/null +++ b/src/game/GuardAI.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GUARDAI_H +#define MANGOS_GUARDAI_H + +#include "CreatureAI.h" +#include "Timer.h" + +class Creature; + +class MANGOS_DLL_DECL GuardAI : public CreatureAI +{ + enum GuardState + { + STATE_NORMAL = 1, + STATE_LOOK_AT_VICTIM = 2 + }; + + public: + + GuardAI(Creature &c); + + void MoveInLineOfSight(Unit *); + void AttackStart(Unit *); + void EnterEvadeMode(); + void JustDied(Unit *); + bool IsVisible(Unit *) const; + + void UpdateAI(const uint32); + static int Permissible(const Creature *); + + private: + Creature &i_creature; + uint64 i_victimGuid; + GuardState i_state; + TimeTracker i_tracker; +}; +#endif diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp new file mode 100644 index 000000000..aeb150b65 --- /dev/null +++ b/src/game/Guild.cpp @@ -0,0 +1,1962 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "MapManager.h" +#include "Player.h" +#include "Opcodes.h" +#include "ObjectMgr.h" +#include "Guild.h" +#include "Chat.h" +#include "SocialMgr.h" +#include "Util.h" + +Guild::Guild() +{ + Id = 0; + name = ""; + leaderGuid = 0; + GINFO = MOTD = ""; + EmblemStyle = 0; + EmblemColor = 0; + BorderStyle = 0; + BorderColor = 0; + BackgroundColor = 0; + + CreatedYear = 0; + CreatedMonth = 0; + CreatedDay = 0; +} + +Guild::~Guild() +{ + +} + +bool Guild::create(uint64 lGuid, std::string gname) +{ + std::string rname; + std::string lName; + + if(!objmgr.GetPlayerNameByGUID(lGuid, lName)) + return false; + if(objmgr.GetGuildByName(gname)) + return false; + + sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(lGuid)); + + leaderGuid = lGuid; + name = gname; + GINFO = ""; + MOTD = "No message set."; + guildbank_money = 0; + purchased_tabs = 0; + + QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" ); + if( result ) + { + Id = (*result)[0].GetUInt32()+1; + delete result; + } + else Id = 1; + + // gname already assigned to Guild::name, use it to encode string for DB + CharacterDatabase.escape_string(gname); + + std::string dbGINFO = GINFO; + std::string dbMOTD = MOTD; + CharacterDatabase.escape_string(dbGINFO); + CharacterDatabase.escape_string(dbMOTD); + + CharacterDatabase.BeginTransaction(); + // CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid='%u'", Id); - MAX(guildid)+1 not exist + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", Id); + CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid='%u'", Id); + CharacterDatabase.PExecute("INSERT INTO guild (guildid,name,leaderguid,info,motd,createdate,EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor,BankMoney) " + "VALUES('%u','%s','%u', '%s', '%s', NOW(),'%u','%u','%u','%u','%u','" I64FMTD "')", + Id, gname.c_str(), GUID_LOPART(leaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, guildbank_money); + CharacterDatabase.CommitTransaction(); + + rname = "Guild Master"; + CreateRank(rname,GR_RIGHT_ALL); + rname = "Officer"; + CreateRank(rname,GR_RIGHT_ALL); + rname = "Veteran"; + CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); + rname = "Member"; + CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); + rname = "Initiate"; + CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); + + return AddMember(lGuid, (uint32)GR_GUILDMASTER); +} + +bool Guild::AddMember(uint64 plGuid, uint32 plRank) +{ + if(Player::GetGuildIdFromDB(plGuid) != 0) // player already in guild + return false; + + // remove all player signs from another petitions + // this will be prevent attempt joining player to many guilds and corrupt guild data integrity + Player::RemovePetitionsAndSigns(plGuid, 9); + + // fill player data + MemberSlot newmember; + + if(!FillPlayerData(plGuid, &newmember)) // problems with player data collection + return false; + + newmember.RankId = plRank; + newmember.OFFnote = (std::string)""; + newmember.Pnote = (std::string)""; + newmember.logout_time = time(NULL); + newmember.BankResetTimeMoney = 0; // this will force update at first query + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + newmember.BankResetTimeTab[i] = 0; + members[GUID_LOPART(plGuid)] = newmember; + + std::string dbPnote = newmember.Pnote; + std::string dbOFFnote = newmember.OFFnote; + CharacterDatabase.escape_string(dbPnote); + CharacterDatabase.escape_string(dbOFFnote); + + CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')", + Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); + + Player* pl = objmgr.GetPlayer(plGuid); + if(pl) + { + pl->SetInGuild(Id); + pl->SetRank(newmember.RankId); + pl->SetGuildIdInvited(0); + } + else + { + Player::SetUInt32ValueInDB(PLAYER_GUILDID, Id, plGuid); + Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, newmember.RankId, plGuid); + } + return true; +} + +void Guild::SetMOTD(std::string motd) +{ + MOTD = motd; + + // motd now can be used for encoding to DB + CharacterDatabase.escape_string(motd); + CharacterDatabase.PExecute("UPDATE guild SET motd='%s' WHERE guildid='%u'", motd.c_str(), Id); +} + +void Guild::SetGINFO(std::string ginfo) +{ + GINFO = ginfo; + + // ginfo now can be used for encoding to DB + CharacterDatabase.escape_string(ginfo); + CharacterDatabase.PExecute("UPDATE guild SET info='%s' WHERE guildid='%u'", ginfo.c_str(), Id); +} + +bool Guild::LoadGuildFromDB(uint32 GuildId) +{ + if(!LoadRanksFromDB(GuildId)) + return false; + + if(!LoadMembersFromDB(GuildId)) + return false; + + QueryResult *result = CharacterDatabase.PQuery("SELECT MAX(TabId) FROM guild_bank_tab WHERE guildid='%u'", GuildId); + if(result) + { + Field *fields = result->Fetch(); + purchased_tabs = fields[0].GetUInt8()+1; // Because TabId begins at 0 + delete result; + } + else + purchased_tabs = 0; + + LoadBankRightsFromDB(GuildId); // Must be after LoadRanksFromDB because it populates rank struct + + // 0 1 2 3 4 5 6 + result = CharacterDatabase.PQuery("SELECT guildid, name, leaderguid, EmblemStyle, EmblemColor, BorderStyle, BorderColor," + // 7 8 9 10 11 + "BackgroundColor, info, motd, createdate, BankMoney FROM guild WHERE guildid = '%u'", GuildId); + + if(!result) + return false; + + Field *fields = result->Fetch(); + + Id = fields[0].GetUInt32(); + name = fields[1].GetCppString(); + leaderGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); + + EmblemStyle = fields[3].GetUInt32(); + EmblemColor = fields[4].GetUInt32(); + BorderStyle = fields[5].GetUInt32(); + BorderColor = fields[6].GetUInt32(); + BackgroundColor = fields[7].GetUInt32(); + GINFO = fields[8].GetCppString(); + MOTD = fields[9].GetCppString(); + uint64 time = fields[10].GetUInt64(); //datetime is uint64 type ... YYYYmmdd:hh:mm:ss + guildbank_money = fields[11].GetUInt64(); + + delete result; + + uint64 dTime = time /1000000; + CreatedDay = dTime%100; + CreatedMonth = (dTime/100)%100; + CreatedYear = (dTime/10000)%10000; + + // If the leader does not exist attempt to promote another member + if(!objmgr.GetPlayerAccountIdByGUID(leaderGuid )) + { + DelMember(leaderGuid); + + // check no members case (disbanded) + if(members.empty()) + return false; + } + + sLog.outDebug("Guild %u Creation time Loaded day: %u, month: %u, year: %u", GuildId, CreatedDay, CreatedMonth, CreatedYear); + m_bankloaded = false; + m_eventlogloaded = false; + m_onlinemembers = 0; + RenumBankLogs(); + RenumGuildEventlog(); + return true; +} + +bool Guild::LoadRanksFromDB(uint32 GuildId) +{ + Field *fields; + QueryResult *result = CharacterDatabase.PQuery("SELECT rname,rights,BankMoneyPerDay,rid FROM guild_rank WHERE guildid = '%u' ORDER BY rid ASC", GuildId); + + if(!result) + return false; + + bool broken_ranks = false; + + do + { + fields = result->Fetch(); + + std::string rankName = fields[0].GetCppString(); + uint32 rankRights = fields[1].GetUInt32(); + uint32 rankMoney = fields[2].GetUInt32(); + uint32 rankRID = fields[3].GetUInt32(); + + if(rankRID != m_ranks.size()+1) // guild_rank.rid always store rank+1 + broken_ranks = true; + + if(m_ranks.size()==GR_GUILDMASTER) // prevent loss leader rights + rankRights |= GR_RIGHT_ALL; + + AddRank(rankName,rankRights,rankMoney); + }while( result->NextRow() ); + delete result; + + if(m_ranks.size()==0) // empty rank table? + { + AddRank("Guild Master",GR_RIGHT_ALL,0); + broken_ranks = true; + } + + // guild_rank have wrong numbered ranks, repair + if(broken_ranks) + { + sLog.outError("Guild %u have broken `guild_rank` data, repairing...",GuildId); + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", GuildId); + for(size_t i =0; i < m_ranks.size(); ++i) + { + // guild_rank.rid always store rank+1 + std::string name = m_ranks[i].name; + uint32 rights = m_ranks[i].rights; + CharacterDatabase.escape_string(name); + CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", GuildId, i+1, name.c_str(), rights); + } + CharacterDatabase.CommitTransaction(); + } + + return true; +} + +bool Guild::LoadMembersFromDB(uint32 GuildId) +{ + // 0 1 2 3 4 5 + QueryResult *result = CharacterDatabase.PQuery("SELECT guild_member.guid,rank, pnote, offnote, BankResetTimeMoney,BankRemMoney," + // 6 7 8 9 10 11 + "BankResetTimeTab0, BankRemSlotsTab0, BankResetTimeTab1, BankRemSlotsTab1, BankResetTimeTab2, BankRemSlotsTab2," + // 12 13 14 15 16 17 + "BankResetTimeTab3, BankRemSlotsTab3, BankResetTimeTab4, BankRemSlotsTab4, BankResetTimeTab5, BankRemSlotsTab5," + // 18 + "logout_time FROM guild_member LEFT JOIN characters ON characters.guid = guild_member.guid WHERE guildid = '%u'", GuildId); + + if(!result) + return false; + + do + { + Field *fields = result->Fetch(); + MemberSlot newmember; + newmember.RankId = fields[1].GetUInt32(); + uint64 guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + + // Player does not exist + if(!FillPlayerData(guid, &newmember)) + continue; + + newmember.Pnote = fields[2].GetCppString(); + newmember.OFFnote = fields[3].GetCppString(); + newmember.BankResetTimeMoney = fields[4].GetUInt32(); + newmember.BankRemMoney = fields[5].GetUInt32(); + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + newmember.BankResetTimeTab[i] = fields[6+(2*i)].GetUInt32(); + newmember.BankRemSlotsTab[i] = fields[7+(2*i)].GetUInt32(); + } + newmember.logout_time = fields[18].GetUInt64(); + members[GUID_LOPART(guid)] = newmember; + + }while( result->NextRow() ); + delete result; + + if(members.empty()) + return false; + + return true; +} + +bool Guild::FillPlayerData(uint64 guid, MemberSlot* memslot) +{ + std::string plName; + uint32 plLevel; + uint32 plClass; + uint32 plZone; + + Player* pl = objmgr.GetPlayer(guid); + if(pl) + { + plName = pl->GetName(); + plLevel = pl->getLevel(); + plClass = pl->getClass(); + plZone = pl->GetZoneId(); + } + else + { + if(!objmgr.GetPlayerNameByGUID(guid, plName)) // player doesn't exist + return false; + + plLevel = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL, guid); + if(plLevel<1||plLevel>255) // can be at broken `data` field + { + sLog.outError("Player (GUID: %u) has a broken data in field `characters`.`data`.",GUID_LOPART(guid)); + return false; + } + plZone = Player::GetZoneIdFromDB(guid); + + QueryResult *result = CharacterDatabase.PQuery("SELECT class FROM characters WHERE guid='%u'", GUID_LOPART(guid)); + if(!result) + return false; + plClass = (*result)[0].GetUInt32(); + if(plClass=MAX_CLASSES) // can be at broken `class` field + { + sLog.outError("Player (GUID: %u) has a broken data in field `characters`.`class`.",GUID_LOPART(guid)); + return false; + } + + delete result; + } + + memslot->name = plName; + memslot->level = plLevel; + memslot->Class = plClass; + memslot->zoneId = plZone; + + return(true); +} + +void Guild::LoadPlayerStatsByGuid(uint64 guid) +{ + MemberList::iterator itr = members.find(GUID_LOPART(guid)); + if (itr == members.end() ) + return; + + Player *pl = ObjectAccessor::FindPlayer(guid); + if(!pl) + return; + itr->second.name = pl->GetName(); + itr->second.level = pl->getLevel(); + itr->second.Class = pl->getClass(); +} + +void Guild::SetLeader(uint64 guid) +{ + leaderGuid = guid; + this->ChangeRank(guid, GR_GUILDMASTER); + + CharacterDatabase.PExecute("UPDATE guild SET leaderguid='%u' WHERE guildid='%u'", GUID_LOPART(guid), Id); +} + +void Guild::DelMember(uint64 guid, bool isDisbanding) +{ + if(this->leaderGuid == guid && !isDisbanding) + { + std::ostringstream ss; + ss<<"SELECT guid FROM guild_member WHERE guildid='"<SetLeader(newLeaderGUID); + + newLeader = objmgr.GetPlayer(newLeaderGUID); + if(newLeader) + { + newLeader->SetRank(GR_GUILDMASTER); + newLeaderName = newLeader->GetName(); + } + else + { + Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, GR_GUILDMASTER, newLeaderGUID); + objmgr.GetPlayerNameByGUID(newLeaderGUID, newLeaderName); + } + + // when leader non-exist (at guild load with deleted leader only) not send broadcasts + if(objmgr.GetPlayerNameByGUID(guid, oldLeaderName)) + { + WorldPacket data(SMSG_GUILD_EVENT, (1+1+oldLeaderName.size()+1+newLeaderName.size()+1)); + data << (uint8)GE_LEADER_CHANGED; + data << (uint8)2; + data << oldLeaderName; + data << newLeaderName; + this->BroadcastPacket(&data); + + data.Initialize(SMSG_GUILD_EVENT, (1+1+oldLeaderName.size()+1)); + data << (uint8)GE_LEFT; + data << (uint8)1; + data << oldLeaderName; + this->BroadcastPacket(&data); + } + + sLog.outDebug( "WORLD: Sent (SMSG_GUILD_EVENT)" ); + } + else + { + this->Disband(); + return; + } + } + + members.erase(GUID_LOPART(guid)); + + Player *player = objmgr.GetPlayer(guid); + if(player) + { + player->SetInGuild(0); + player->SetRank(0); + } + else + { + Player::SetUInt32ValueInDB(PLAYER_GUILDID, 0, guid); + Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, GR_GUILDMASTER, guid); + } + + CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", GUID_LOPART(guid)); +} + +void Guild::ChangeRank(uint64 guid, uint32 newRank) +{ + MemberList::iterator itr = members.find(GUID_LOPART(guid)); + if( itr != members.end() ) + itr->second.RankId = newRank; + + Player *player = objmgr.GetPlayer(guid); + if(player) + player->SetRank(newRank); + else + Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, newRank, guid); + + CharacterDatabase.PExecute( "UPDATE guild_member SET rank='%u' WHERE guid='%u'", newRank, GUID_LOPART(guid) ); +} + +void Guild::SetPNOTE(uint64 guid,std::string pnote) +{ + MemberList::iterator itr = members.find(GUID_LOPART(guid)); + if( itr == members.end() ) + return; + + itr->second.Pnote = pnote; + + // pnote now can be used for encoding to DB + CharacterDatabase.escape_string(pnote); + CharacterDatabase.PExecute("UPDATE guild_member SET pnote = '%s' WHERE guid = '%u'", pnote.c_str(), itr->first); +} + +void Guild::SetOFFNOTE(uint64 guid,std::string offnote) +{ + MemberList::iterator itr = members.find(GUID_LOPART(guid)); + if( itr == members.end() ) + return; + itr->second.OFFnote = offnote; + // offnote now can be used for encoding to DB + CharacterDatabase.escape_string(offnote); + CharacterDatabase.PExecute("UPDATE guild_member SET offnote = '%s' WHERE guid = '%u'", offnote.c_str(), itr->first); +} + +void Guild::BroadcastToGuild(WorldSession *session, std::string msg, uint32 language) +{ + if (session && session->GetPlayer() && HasRankRight(session->GetPlayer()->GetRank(),GR_RIGHT_GCHATSPEAK)) + { + WorldPacket data; + ChatHandler(session).FillMessageData(&data, CHAT_MSG_GUILD, language, 0, msg.c_str()); + + for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) + { + Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + + if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_GCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()) ) + pl->GetSession()->SendPacket(&data); + } + } +} + +void Guild::BroadcastToOfficers(WorldSession *session, std::string msg, uint32 language) +{ + if (session && session->GetPlayer() && HasRankRight(session->GetPlayer()->GetRank(),GR_RIGHT_OFFCHATSPEAK)) + { + for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + WorldPacket data; + ChatHandler::FillMessageData(&data, session, CHAT_MSG_OFFICER, language, NULL, 0, msg.c_str(),NULL); + + Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + + if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_OFFCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow())) + pl->GetSession()->SendPacket(&data); + } + } +} + +void Guild::BroadcastPacket(WorldPacket *packet) +{ + for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + if(player) + player->GetSession()->SendPacket(packet); + } +} + +void Guild::BroadcastPacketToRank(WorldPacket *packet, uint32 rankId) +{ + for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + if (itr->second.RankId == rankId) + { + Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + if(player) + player->GetSession()->SendPacket(packet); + } + } +} + +void Guild::CreateRank(std::string name_,uint32 rights) +{ + if(m_ranks.size() >= GUILD_MAX_RANKS) + return; + + AddRank(name_,rights,0); + + for (int i = 0; i < purchased_tabs; ++i) + { + CreateBankRightForTab(m_ranks.size()-1, uint8(i)); + } + + // guild_rank.rid always store rank+1 value + + // name now can be used for encoding to DB + CharacterDatabase.escape_string(name_); + CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", Id, m_ranks.size(), name_.c_str(), rights ); +} + +void Guild::AddRank(std::string name_,uint32 rights, uint32 money) +{ + m_ranks.push_back(RankInfo(name_,rights,money)); +} + +void Guild::DelRank() +{ + if(m_ranks.empty()) + return; + + // guild_rank.rid always store rank+1 value + uint32 rank = m_ranks.size()-1; + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE rid>='%u' AND guildid='%u'", (rank+1), Id); + + m_ranks.pop_back(); +} + +std::string Guild::GetRankName(uint32 rankId) +{ + if(rankId >= m_ranks.size()) + return ""; + + return m_ranks[rankId].name; +} + +uint32 Guild::GetRankRights(uint32 rankId) +{ + if(rankId >= m_ranks.size()) + return 0; + + return m_ranks[rankId].rights; +} + +void Guild::SetRankName(uint32 rankId, std::string name_) +{ + if(rankId >= m_ranks.size()) + return; + + m_ranks[rankId].name = name_; + + // name now can be used for encoding to DB + CharacterDatabase.escape_string(name_); + CharacterDatabase.PExecute("UPDATE guild_rank SET rname='%s' WHERE rid='%u' AND guildid='%u'", name_.c_str(), (rankId+1), Id); +} + +void Guild::SetRankRights(uint32 rankId, uint32 rights) +{ + if(rankId >= m_ranks.size()) + return; + + m_ranks[rankId].rights = rights; + + CharacterDatabase.PExecute("UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'", rights, (rankId+1), Id); +} + +void Guild::Disband() +{ + WorldPacket data(SMSG_GUILD_EVENT, 1); + data << (uint8)GE_DISBANDED; + this->BroadcastPacket(&data); + + while (!members.empty()) + { + MemberList::iterator itr = members.begin(); + DelMember(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER), true); + } + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid = '%u'",Id); + CharacterDatabase.CommitTransaction(); + objmgr.RemoveGuild(this); +} + +void Guild::Roster(WorldSession *session) +{ + // we can only guess size + WorldPacket data(SMSG_GUILD_ROSTER, (4+MOTD.length()+1+GINFO.length()+1+4+m_ranks.size()*(4+4+GUILD_BANK_MAX_TABS*(4+4))+members.size()*50)); + data << (uint32)members.size(); + data << MOTD; + data << GINFO; + + data << (uint32)m_ranks.size(); + for (RankList::iterator ritr = m_ranks.begin(); ritr != m_ranks.end();++ritr) + { + data << (uint32)ritr->rights; + data << (uint32)ritr->BankMoneyPerDay; // count of: withdraw gold(gold/day) Note: in game set gold, in packet set bronze. + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + data << (uint32)ritr->TabRight[i]; // for TAB_i rights: view tabs = 0x01, deposit items =0x02 + data << (uint32)ritr->TabSlotPerDay[i]; // for TAB_i count of: withdraw items(stack/day) + } + } + for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + if (Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) + { + data << (uint64)pl->GetGUID(); + data << (uint8)1; + data << (std::string)pl->GetName(); + data << (uint32)itr->second.RankId; + data << (uint8)pl->getLevel(); + data << (uint8)pl->getClass(); + data << (uint8)0; // new 2.4.0 + data << (uint32)pl->GetZoneId(); + data << itr->second.Pnote; + data << itr->second.OFFnote; + } + else + { + data << uint64(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + data << (uint8)0; + data << itr->second.name; + data << (uint32)itr->second.RankId; + data << (uint8)itr->second.level; + data << (uint8)itr->second.Class; + data << (uint8)0; // new 2.4.0 + data << (uint32)itr->second.zoneId; + data << (float(time(NULL)-itr->second.logout_time) / DAY); + data << itr->second.Pnote; + data << itr->second.OFFnote; + } + } + session->SendPacket(&data);; + sLog.outDebug( "WORLD: Sent (SMSG_GUILD_ROSTER)" ); +} + +void Guild::Query(WorldSession *session) +{ + WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, (8*32+200));// we can only guess size + + data << Id; + data << name; + RankList::iterator itr; + for (size_t i = 0 ; i < 10; ++i) // show always 10 ranks + { + if(i < m_ranks.size()) + data << m_ranks[i].name; + else + data << (uint8)0; // null string + } + + data << uint32(EmblemStyle); + data << uint32(EmblemColor); + data << uint32(BorderStyle); + data << uint32(BorderColor); + data << uint32(BackgroundColor); + + session->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" ); +} + +void Guild::SetEmblem(uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor, uint32 backgroundColor) +{ + this->EmblemStyle = emblemStyle; + this->EmblemColor = emblemColor; + this->BorderStyle = borderStyle; + this->BorderColor = borderColor; + this->BackgroundColor = backgroundColor; + + CharacterDatabase.PExecute("UPDATE guild SET EmblemStyle=%u, EmblemColor=%u, BorderStyle=%u, BorderColor=%u, BackgroundColor=%u WHERE guildid = %u", EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, Id); +} + +void Guild::UpdateLogoutTime(uint64 guid) +{ + MemberList::iterator itr = members.find(GUID_LOPART(guid)); + if (itr == members.end() ) + return; + + itr->second.logout_time = time(NULL); + + if (m_onlinemembers > 0) + --m_onlinemembers; + else + { + UnloadGuildBank(); + UnloadGuildEventlog(); + } +} + +// ************************************************* +// Guild Eventlog part +// ************************************************* +// Display guild eventlog +void Guild::DisplayGuildEventlog(WorldSession *session) +{ + // Load guild eventlog, if not already done + if (!m_eventlogloaded) + LoadGuildEventLogFromDB(); + + // Sending result + WorldPacket data(MSG_GUILD_EVENT_LOG_QUERY, 0); + // count, max count == 100 + data << uint8(m_GuildEventlog.size()); + for (GuildEventlog::const_iterator itr = m_GuildEventlog.begin(); itr != m_GuildEventlog.end(); ++itr) + { + // Event type + data << uint8((*itr)->EventType); + // Player 1 + data << uint64((*itr)->PlayerGuid1); + // Player 2 not for left/join guild events + if( (*itr)->EventType != GUILD_EVENT_LOG_JOIN_GUILD && (*itr)->EventType != GUILD_EVENT_LOG_LEAVE_GUILD ) + data << uint64((*itr)->PlayerGuid2); + // New Rank - only for promote/demote guild events + if( (*itr)->EventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || (*itr)->EventType == GUILD_EVENT_LOG_DEMOTE_PLAYER ) + data << uint8((*itr)->NewRank); + // Event timestamp + data << uint32(time(NULL)-(*itr)->TimeStamp); + } + session->SendPacket(&data); + sLog.outDebug("WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)"); +} + +// Load guild eventlog from DB +void Guild::LoadGuildEventLogFromDB() +{ + // Return if already loaded + if (m_eventlogloaded) + return; + + QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog WHERE guildid=%u ORDER BY LogGuid DESC LIMIT %u", Id, GUILD_EVENTLOG_MAX_ENTRIES); + if(!result) + return; + do + { + Field *fields = result->Fetch(); + GuildEventlogEntry *NewEvent = new GuildEventlogEntry; + // Fill entry + NewEvent->LogGuid = fields[0].GetUInt32(); + NewEvent->EventType = fields[1].GetUInt8(); + NewEvent->PlayerGuid1 = fields[2].GetUInt32(); + NewEvent->PlayerGuid2 = fields[3].GetUInt32(); + NewEvent->NewRank = fields[4].GetUInt8(); + NewEvent->TimeStamp = fields[5].GetUInt64(); + // Add entry to map + m_GuildEventlog.push_front(NewEvent); + + } while( result->NextRow() ); + delete result; + + // Check lists size in case to many event entries in db + // This cases can happen only if a crash occured somewhere and table has too many log entries + if (!m_GuildEventlog.empty()) + { + CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid=%u AND LogGuid < %u", Id, m_GuildEventlog.front()->LogGuid); + } + m_eventlogloaded = true; +} + +// Unload guild eventlog +void Guild::UnloadGuildEventlog() +{ + if (!m_eventlogloaded) + return; + GuildEventlogEntry *EventLogEntry; + if( !m_GuildEventlog.empty() ) + { + do + { + EventLogEntry = *(m_GuildEventlog.begin()); + m_GuildEventlog.pop_front(); + delete EventLogEntry; + }while( !m_GuildEventlog.empty() ); + } + m_eventlogloaded = false; +} + +// This will renum guids used at load to prevent always going up until infinit +void Guild::RenumGuildEventlog() +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT Min(LogGuid), Max(LogGuid) FROM guild_eventlog WHERE guildid = %u", Id); + if(!result) + return; + + Field *fields = result->Fetch(); + CharacterDatabase.PExecute("UPDATE guild_eventlog SET LogGuid=LogGuid-%u+1 WHERE guildid=%u ORDER BY LogGuid %s",fields[0].GetUInt32(), Id, fields[0].GetUInt32()?"ASC":"DESC"); + GuildEventlogMaxGuid = fields[1].GetUInt32()+1; + delete result; +} + +// Add entry to guild eventlog +void Guild::LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank) +{ + GuildEventlogEntry *NewEvent = new GuildEventlogEntry; + // Fill entry + NewEvent->LogGuid = GuildEventlogMaxGuid++; + NewEvent->EventType = EventType; + NewEvent->PlayerGuid1 = PlayerGuid1; + NewEvent->PlayerGuid2 = PlayerGuid2; + NewEvent->NewRank = NewRank; + NewEvent->TimeStamp = uint32(time(NULL)); + // Check max entry limit and delete from db if needed + if (m_GuildEventlog.size() > GUILD_EVENTLOG_MAX_ENTRIES) + { + GuildEventlogEntry *OldEvent = *(m_GuildEventlog.begin()); + m_GuildEventlog.pop_front(); + CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, OldEvent->LogGuid); + delete OldEvent; + } + // Add entry to map + m_GuildEventlog.push_back(NewEvent); + // Add new eventlog entry into DB + CharacterDatabase.PExecute("INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" I64FMTD "')", + Id, NewEvent->LogGuid, uint32(NewEvent->EventType), NewEvent->PlayerGuid1, NewEvent->PlayerGuid2, uint32(NewEvent->NewRank), NewEvent->TimeStamp); +} + +// ************************************************* +// Guild Bank part +// ************************************************* +// Bank content related +void Guild::DisplayGuildBankContent(WorldSession *session, uint8 TabId) +{ + WorldPacket data(SMSG_GUILD_BANK_LIST,1200); + + GuildBankTab const* tab = GetBankTab(TabId); + if (!tab) + return; + + if(!IsMemberHaveRights(session->GetPlayer()->GetGUIDLow(),TabId,GUILD_BANK_RIGHT_VIEW_TAB)) + return; + + data << uint64(GetGuildBankMoney()); + data << uint8(TabId); + // remaining slots for today + data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetGUIDLow(), TabId)); + data << uint8(0); // Tell client this is a tab content packet + + data << uint8(GUILD_BANK_MAX_SLOTS); + + for (int i=0; iSendPacket(&data); + + sLog.outDebug("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); +} + +void Guild::DisplayGuildBankMoneyUpdate() +{ + WorldPacket data(SMSG_GUILD_BANK_LIST, 8+1+4+1+1); + + data << uint64(GetGuildBankMoney()); + data << uint8(0); + // remaining slots for today + + size_t rempos = data.wpos(); + data << uint32(0); // will be filled later + data << uint8(0); // Tell client this is a tab content packet + + data << uint8(0); // not send items + + BroadcastPacket(&data); + + sLog.outDebug("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); +} + +void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2) +{ + GuildBankTab const* tab = GetBankTab(TabId); + if (!tab) + return; + + WorldPacket data(SMSG_GUILD_BANK_LIST,1200); + + data << uint64(GetGuildBankMoney()); + data << uint8(TabId); + // remaining slots for today + + size_t rempos = data.wpos(); + data << uint32(0); // will be filled later + data << uint8(0); // Tell client this is a tab content packet + + if(slot2==-1) // single item in slot1 + { + data << uint8(1); + + AppendDisplayGuildBankSlot(data, tab, slot1); + } + else // 2 items (in slot1 and slot2) + { + data << uint8(2); + + if(slot1 > slot2) + std::swap(slot1,slot2); + + AppendDisplayGuildBankSlot(data, tab, slot1); + AppendDisplayGuildBankSlot(data, tab, slot2); + } + + for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + if(!player) + continue; + + if(!IsMemberHaveRights(itr->first,TabId,GUILD_BANK_RIGHT_VIEW_TAB)) + continue; + + data.put(rempos,uint32(GetMemberSlotWithdrawRem(player->GetGUIDLow(), TabId))); + + player->GetSession()->SendPacket(&data); + } + + sLog.outDebug("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); +} + +void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots) +{ + GuildBankTab const* tab = GetBankTab(TabId); + if (!tab) + return; + + WorldPacket data(SMSG_GUILD_BANK_LIST,1200); + + data << uint64(GetGuildBankMoney()); + data << uint8(TabId); + // remaining slots for today + + size_t rempos = data.wpos(); + data << uint32(0); // will be filled later + data << uint8(0); // Tell client this is a tab content packet + + data << uint8(slots.size()); // updates count + + for(GuildItemPosCountVec::const_iterator itr = slots.begin(); itr != slots.end(); ++itr) + AppendDisplayGuildBankSlot(data, tab, itr->slot); + + for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + { + Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + if(!player) + continue; + + if(!IsMemberHaveRights(itr->first,TabId,GUILD_BANK_RIGHT_VIEW_TAB)) + continue; + + data.put(rempos,uint32(GetMemberSlotWithdrawRem(player->GetGUIDLow(), TabId))); + + player->GetSession()->SendPacket(&data); + } + + sLog.outDebug("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); +} + +Item* Guild::GetItem(uint8 TabId, uint8 SlotId) +{ + if (TabId >= m_TabListMap.size() || SlotId >= GUILD_BANK_MAX_SLOTS) + return NULL; + return m_TabListMap[TabId]->Slots[SlotId]; +} + +// ************************************************* +// Tab related + +void Guild::DisplayGuildBankTabsInfo(WorldSession *session) +{ + // Time to load bank if not already done + if (!m_bankloaded) + LoadGuildBankFromDB(); + + WorldPacket data(SMSG_GUILD_BANK_LIST, 500); + + data << uint64(GetGuildBankMoney()); + data << uint8(0); // TabInfo packet must be for TabId 0 + data << uint32(0xFFFFFFFF); // bit 9 must be set for this packet to work + data << uint8(1); // Tell Client this is a TabInfo packet + + data << uint8(purchased_tabs); // here is the number of tabs + + for(int i = 0; i < purchased_tabs; ++i) + { + data << m_TabListMap[i]->Name.c_str(); + data << m_TabListMap[i]->Icon.c_str(); + } + data << uint8(0); // Do not send tab content + session->SendPacket(&data); + + sLog.outDebug("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); +} + +void Guild::CreateNewBankTab() +{ + if (purchased_tabs >= GUILD_BANK_MAX_TABS) + return; + + ++purchased_tabs; + + GuildBankTab* AnotherTab = new GuildBankTab; + memset(AnotherTab->Slots, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); + m_TabListMap.resize(purchased_tabs); + m_TabListMap[purchased_tabs-1] = AnotherTab; + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", Id, uint32(purchased_tabs-1)); + CharacterDatabase.PExecute("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", Id, uint32(purchased_tabs-1)); + CharacterDatabase.CommitTransaction(); +} + +void Guild::SetGuildBankTabInfo(uint8 TabId, std::string Name, std::string Icon) +{ + if (TabId >= GUILD_BANK_MAX_TABS) + return; + if (TabId >= m_TabListMap.size()) + return; + + if (!m_TabListMap[TabId]) + return; + + if(m_TabListMap[TabId]->Name == Name && m_TabListMap[TabId]->Icon == Icon) + return; + + m_TabListMap[TabId]->Name = Name; + m_TabListMap[TabId]->Icon = Icon; + + CharacterDatabase.escape_string(Name); + CharacterDatabase.escape_string(Icon); + CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabName='%s',TabIcon='%s' WHERE guildid='%u' AND TabId='%u'", Name.c_str(), Icon.c_str(), Id, uint32(TabId)); +} + +void Guild::CreateBankRightForTab(uint32 rankId, uint8 TabId) +{ + sLog.outDebug("CreateBankRightForTab. rank: %u, TabId: %u", rankId, uint32(TabId)); + if (rankId >= m_ranks.size() || TabId >= GUILD_BANK_MAX_TABS) + return; + + m_ranks[rankId].TabRight[TabId]=0; + m_ranks[rankId].TabSlotPerDay[TabId]=0; + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u' AND TabId = '%u' AND rid = '%u'", Id, uint32(TabId), rankId); + CharacterDatabase.PExecute("INSERT INTO guild_bank_right (guildid,TabId,rid) VALUES ('%u','%u','%u')", Id, uint32(TabId), rankId); + CharacterDatabase.CommitTransaction(); +} + +uint32 Guild::GetBankRights(uint32 rankId, uint8 TabId) const +{ + if(rankId >= m_ranks.size() || TabId >= GUILD_BANK_MAX_TABS) + return 0; + + return m_ranks[rankId].TabRight[TabId]; +} + +// ************************************************* +// Guild bank loading/unloading related + +// This load should be called when the bank is first accessed by a guild member +void Guild::LoadGuildBankFromDB() +{ + if (m_bankloaded) + return; + + m_bankloaded = true; + LoadGuildBankEventLogFromDB(); + + // 0 1 2 3 + QueryResult *result = CharacterDatabase.PQuery("SELECT TabId, TabName, TabIcon, TabText FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId", Id); + if(!result) + { + purchased_tabs = 0; + return; + } + + m_TabListMap.resize(purchased_tabs); + do + { + Field *fields = result->Fetch(); + uint8 TabId = fields[0].GetUInt8(); + + GuildBankTab *NewTab = new GuildBankTab; + memset(NewTab->Slots, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); + + NewTab->Name = fields[1].GetCppString(); + NewTab->Icon = fields[2].GetCppString(); + NewTab->Text = fields[3].GetCppString(); + + m_TabListMap[TabId] = NewTab; + }while( result->NextRow() ); + + delete result; + + // 0 1 2 3 + result = CharacterDatabase.PQuery("SELECT TabId, SlotId, item_guid, item_entry FROM guild_bank_item WHERE guildid='%u' ORDER BY TabId", Id); + if(!result) + return; + + do + { + Field *fields = result->Fetch(); + uint8 TabId = fields[0].GetUInt8(); + uint8 SlotId = fields[1].GetUInt8(); + uint32 ItemGuid = fields[2].GetUInt32(); + uint32 ItemEntry = fields[3].GetUInt32(); + + if (TabId >= purchased_tabs || TabId >= GUILD_BANK_MAX_TABS) + { + sLog.outError( "Guild::LoadGuildBankFromDB: Invalid tab for item (GUID: %u id: #%u) in guild bank, skipped.", ItemGuid,ItemEntry); + continue; + } + + if (SlotId >= GUILD_BANK_MAX_SLOTS) + { + sLog.outError( "Guild::LoadGuildBankFromDB: Invalid slot for item (GUID: %u id: #%u) in guild bank, skipped.", ItemGuid,ItemEntry); + continue; + } + + ItemPrototype const *proto = objmgr.GetItemPrototype(ItemEntry); + + if(!proto) + { + sLog.outError( "Guild::LoadGuildBankFromDB: Unknown item (GUID: %u id: #%u) in guild bank, skipped.", ItemGuid,ItemEntry); + continue; + } + + Item *pItem = NewItemOrBag(proto); + if(!pItem->LoadFromDB(ItemGuid, 0)) + { + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", Id, uint32(TabId), uint32(SlotId)); + sLog.outError("Item GUID %u not found in item_instance, deleting from Guild Bank!", ItemGuid); + delete pItem; + continue; + } + + pItem->AddToWorld(); + m_TabListMap[TabId]->Slots[SlotId] = pItem; + }while( result->NextRow() ); + + delete result; +} + +// This unload should be called when the last member of the guild gets offline +void Guild::UnloadGuildBank() +{ + if (!m_bankloaded) + return; + for (uint8 i = 0 ; i < purchased_tabs ; ++i ) + { + for (uint8 j = 0 ; j < GUILD_BANK_MAX_SLOTS ; ++j) + { + if (m_TabListMap[i]->Slots[j]) + { + m_TabListMap[i]->Slots[j]->RemoveFromWorld(); + delete m_TabListMap[i]->Slots[j]; + } + } + delete m_TabListMap[i]; + } + m_TabListMap.clear(); + + UnloadGuildBankEventLog(); + m_bankloaded = false; +} + +// ************************************************* +// Money deposit/withdraw related + +void Guild::SendMoneyInfo(WorldSession *session, uint32 LowGuid) +{ + WorldPacket data(MSG_GUILD_BANK_MONEY_WITHDRAWN, 4); + data << uint32(GetMemberMoneyWithdrawRem(LowGuid)); + session->SendPacket(&data); + sLog.outDebug("WORLD: Sent MSG_GUILD_BANK_MONEY_WITHDRAWN"); +} + +bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid) +{ + uint32 MoneyWithDrawRight = GetMemberMoneyWithdrawRem(LowGuid); + + if (MoneyWithDrawRight < amount || GetGuildBankMoney() < amount) + return false; + + SetBankMoney(GetGuildBankMoney()-amount); + + if (MoneyWithDrawRight < WITHDRAW_MONEY_UNLIMITED) + { + MemberList::iterator itr = members.find(LowGuid); + if (itr == members.end() ) + return false; + itr->second.BankRemMoney -= amount; + CharacterDatabase.PExecute("UPDATE guild_member SET BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'", + itr->second.BankRemMoney, Id, LowGuid); + } + return true; +} + +void Guild::SetBankMoney(int64 money) +{ + if (money < 0) // I don't know how this happens, it does!! + money = 0; + guildbank_money = money; + + CharacterDatabase.PExecute("UPDATE guild SET BankMoney='" I64FMTD "' WHERE guildid='%u'", money, Id); +} + +// ************************************************* +// Item per day and money per day related + +bool Guild::MemberItemWithdraw(uint8 TabId, uint32 LowGuid) +{ + uint32 SlotsWithDrawRight = GetMemberSlotWithdrawRem(LowGuid, TabId); + + if (SlotsWithDrawRight == 0) + return false; + + if (SlotsWithDrawRight < WITHDRAW_SLOT_UNLIMITED) + { + MemberList::iterator itr = members.find(LowGuid); + if (itr == members.end() ) + return false; + --itr->second.BankRemSlotsTab[TabId]; + CharacterDatabase.PExecute("UPDATE guild_member SET BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'", + uint32(TabId), itr->second.BankRemSlotsTab[TabId], Id, LowGuid); + } + return true; +} + +bool Guild::IsMemberHaveRights(uint32 LowGuid, uint8 TabId, uint32 rights) const +{ + MemberList::const_iterator itr = members.find(LowGuid); + if (itr == members.end() ) + return false; + + if (itr->second.RankId == GR_GUILDMASTER) + return true; + + return (GetBankRights(itr->second.RankId,TabId) & rights)==rights; +} + +uint32 Guild::GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId) +{ + MemberList::iterator itr = members.find(LowGuid); + if (itr == members.end() ) + return 0; + + if (itr->second.RankId == GR_GUILDMASTER) + return WITHDRAW_SLOT_UNLIMITED; + + if((GetBankRights(itr->second.RankId,TabId) & GUILD_BANK_RIGHT_VIEW_TAB)!=GUILD_BANK_RIGHT_VIEW_TAB) + return 0; + + uint32 curTime = uint32(time(NULL)/MINUTE); + if (curTime - itr->second.BankResetTimeTab[TabId] >= 24*HOUR/MINUTE) + { + itr->second.BankResetTimeTab[TabId] = curTime; + itr->second.BankRemSlotsTab[TabId] = GetBankSlotPerDay(itr->second.RankId, TabId); + CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeTab%u='%u',BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'", + uint32(TabId), itr->second.BankResetTimeTab[TabId], uint32(TabId), itr->second.BankRemSlotsTab[TabId], Id, LowGuid); + } + return itr->second.BankRemSlotsTab[TabId]; +} + +uint32 Guild::GetMemberMoneyWithdrawRem(uint32 LowGuid) +{ + MemberList::iterator itr = members.find(LowGuid); + if (itr == members.end() ) + return 0; + + if (itr->second.RankId == GR_GUILDMASTER) + return WITHDRAW_MONEY_UNLIMITED; + + uint32 curTime = uint32(time(NULL)/MINUTE); // minutes + // 24 hours + if (curTime > itr->second.BankResetTimeMoney + 24*HOUR/MINUTE) + { + itr->second.BankResetTimeMoney = curTime; + itr->second.BankRemMoney = GetBankMoneyPerDay(itr->second.RankId); + CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='%u',BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'", + itr->second.BankResetTimeMoney, itr->second.BankRemMoney, Id, LowGuid); + } + return itr->second.BankRemMoney; +} + +void Guild::SetBankMoneyPerDay(uint32 rankId, uint32 money) +{ + if (rankId >= m_ranks.size()) + return; + + if (rankId == GR_GUILDMASTER) + money = WITHDRAW_MONEY_UNLIMITED; + + m_ranks[rankId].BankMoneyPerDay = money; + + for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + if (itr->second.RankId == rankId) + itr->second.BankResetTimeMoney = 0; + + CharacterDatabase.PExecute("UPDATE guild_rank SET BankMoneyPerDay='%u' WHERE rid='%u' AND guildid='%u'", money, (rankId+1), Id); + CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='0' WHERE guildid='%u' AND rank='%u'", Id, rankId); +} + +void Guild::SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 nbSlots, bool db) +{ + if(rankId >= m_ranks.size() || + TabId >= GUILD_BANK_MAX_TABS || + TabId >= purchased_tabs) + return; + + if (rankId == GR_GUILDMASTER) + { + nbSlots = WITHDRAW_SLOT_UNLIMITED; + right = GUILD_BANK_RIGHT_FULL; + } + + m_ranks[rankId].TabSlotPerDay[TabId]=nbSlots; + m_ranks[rankId].TabRight[TabId]=right; + + if (db) + { + for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + if (itr->second.RankId == rankId) + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + itr->second.BankResetTimeTab[i] = 0; + + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid='%u' AND TabId='%u' AND rid='%u'", Id, uint32(TabId), rankId); + CharacterDatabase.PExecute("INSERT INTO guild_bank_right (guildid,TabId,rid,gbright,SlotPerDay) VALUES " + "('%u','%u','%u','%u','%u')", Id, uint32(TabId), rankId, m_ranks[rankId].TabRight[TabId], m_ranks[rankId].TabSlotPerDay[TabId]); + CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeTab%u='0' WHERE guildid='%u' AND rank='%u'", uint32(TabId), Id, rankId); + } +} + +uint32 Guild::GetBankMoneyPerDay(uint32 rankId) +{ + if(rankId >= m_ranks.size()) + return 0; + + if (rankId == GR_GUILDMASTER) + return WITHDRAW_MONEY_UNLIMITED; + return m_ranks[rankId].BankMoneyPerDay; +} + +uint32 Guild::GetBankSlotPerDay(uint32 rankId, uint8 TabId) +{ + if(rankId >= m_ranks.size() || TabId >= GUILD_BANK_MAX_TABS) + return 0; + + if (rankId == GR_GUILDMASTER) + return WITHDRAW_SLOT_UNLIMITED; + return m_ranks[rankId].TabSlotPerDay[TabId]; +} + +// ************************************************* +// Rights per day related + +void Guild::LoadBankRightsFromDB(uint32 GuildId) +{ + // 0 1 2 3 + QueryResult *result = CharacterDatabase.PQuery("SELECT TabId, rid, gbright, SlotPerDay FROM guild_bank_right WHERE guildid = '%u' ORDER BY TabId", GuildId); + + if(!result) + return; + + do + { + Field *fields = result->Fetch(); + uint8 TabId = fields[0].GetUInt8(); + uint32 rankId = fields[1].GetUInt32(); + uint16 right = fields[2].GetUInt16(); + uint16 SlotPerDay = fields[3].GetUInt16(); + + SetBankRightsAndSlots(rankId, TabId, right, SlotPerDay, false); + + }while( result->NextRow() ); + delete result; + + return; +} + +// ************************************************* +// Bank log related + +void Guild::LoadGuildBankEventLogFromDB() +{ + // We can't add a limit as in Guild::LoadGuildEventLogFromDB since we fetch both money and bank log and know nothing about the composition + // 0 1 2 3 4 5 6 7 + QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, LogEntry, TabId, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' ORDER BY TimeStamp DESC", Id); + if(!result) + return; + + do + { + Field *fields = result->Fetch(); + GuildBankEvent *NewEvent = new GuildBankEvent; + + NewEvent->LogGuid = fields[0].GetUInt32(); + NewEvent->LogEntry = fields[1].GetUInt8(); + uint8 TabId = fields[2].GetUInt8(); + NewEvent->PlayerGuid = fields[3].GetUInt32(); + NewEvent->ItemOrMoney = fields[4].GetUInt32(); + NewEvent->ItemStackCount = fields[5].GetUInt8(); + NewEvent->DestTabId = fields[6].GetUInt8(); + NewEvent->TimeStamp = fields[7].GetUInt64(); + + if (TabId >= GUILD_BANK_MAX_TABS) + { + sLog.outError( "Guild::LoadGuildBankEventLogFromDB: Invalid tabid '%u' for guild bank log entry (guild: '%s', LogGuid: %u), skipped.", TabId, GetName().c_str(), NewEvent->LogGuid); + delete NewEvent; + continue; + } + if (NewEvent->isMoneyEvent() && m_GuildBankEventLog_Money.size() >= GUILD_BANK_MAX_LOGS + || m_GuildBankEventLog_Item[TabId].size() >= GUILD_BANK_MAX_LOGS) + { + delete NewEvent; + continue; + } + if (NewEvent->isMoneyEvent()) + m_GuildBankEventLog_Money.push_front(NewEvent); + else + m_GuildBankEventLog_Item[TabId].push_front(NewEvent); + + }while( result->NextRow() ); + delete result; + + // Check lists size in case to many event entries in db for a tab or for money + // This cases can happen only if a crash occured somewhere and table has too many log entries + if (!m_GuildBankEventLog_Money.empty()) + { + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u", + Id, m_GuildBankEventLog_Money.front()->LogGuid); + } + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + if (!m_GuildBankEventLog_Item[i].empty()) + { + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u", + Id, m_GuildBankEventLog_Item[i].front()->LogGuid); + } + } +} + +void Guild::UnloadGuildBankEventLog() +{ + GuildBankEvent *EventLogEntry; + if( !m_GuildBankEventLog_Money.empty() ) + { + do + { + EventLogEntry = *(m_GuildBankEventLog_Money.begin()); + m_GuildBankEventLog_Money.pop_front(); + delete EventLogEntry; + }while( !m_GuildBankEventLog_Money.empty() ); + } + + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + if( !m_GuildBankEventLog_Item[i].empty() ) + { + do + { + EventLogEntry = *(m_GuildBankEventLog_Item[i].begin()); + m_GuildBankEventLog_Item[i].pop_front(); + delete EventLogEntry; + }while( !m_GuildBankEventLog_Item[i].empty() ); + } + } +} + +void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) +{ + if (TabId > GUILD_BANK_MAX_TABS) + return; + + if (TabId == GUILD_BANK_MAX_TABS) + { + // Here we display money logs + WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, m_GuildBankEventLog_Money.size()*(4*4+1)+1+1); + data << uint8(TabId); // Here GUILD_BANK_MAX_TABS + data << uint8(m_GuildBankEventLog_Money.size()); // number of log entries + for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Money.begin(); itr != m_GuildBankEventLog_Money.end(); ++itr) + { + data << uint8((*itr)->LogEntry); + data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); + data << uint32((*itr)->ItemOrMoney); + data << uint32(time(NULL)-(*itr)->TimeStamp); + } + session->SendPacket(&data); + } + else + { + // here we display current tab logs + WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, m_GuildBankEventLog_Item[TabId].size()*(4*4+1+1)+1+1); + data << uint8(TabId); // Here a real Tab Id + // number of log entries + data << uint8(m_GuildBankEventLog_Item[TabId].size()); + for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Item[TabId].begin(); itr != m_GuildBankEventLog_Item[TabId].end(); ++itr) + { + data << uint8((*itr)->LogEntry); + data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); + data << uint32((*itr)->ItemOrMoney); + data << uint8((*itr)->ItemStackCount); + if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) + data << uint8((*itr)->DestTabId); // moved tab + data << uint32(time(NULL)-(*itr)->TimeStamp); + } + session->SendPacket(&data); + } + sLog.outDebug("WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)"); +} + +void Guild::LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId) +{ + GuildBankEvent *NewEvent = new GuildBankEvent; + + NewEvent->LogGuid = LogMaxGuid++; + NewEvent->LogEntry = LogEntry; + NewEvent->PlayerGuid = PlayerGuidLow; + NewEvent->ItemOrMoney = ItemOrMoney; + NewEvent->ItemStackCount = ItemStackCount; + NewEvent->DestTabId = DestTabId; + NewEvent->TimeStamp = uint32(time(NULL)); + + if (NewEvent->isMoneyEvent()) + { + if (m_GuildBankEventLog_Money.size() > GUILD_BANK_MAX_LOGS) + { + GuildBankEvent *OldEvent = *(m_GuildBankEventLog_Money.begin()); + m_GuildBankEventLog_Money.pop_front(); + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, OldEvent->LogGuid); + delete OldEvent; + } + m_GuildBankEventLog_Money.push_back(NewEvent); + } + else + { + if (m_GuildBankEventLog_Item[TabId].size() > GUILD_BANK_MAX_LOGS) + { + GuildBankEvent *OldEvent = *(m_GuildBankEventLog_Item[TabId].begin()); + m_GuildBankEventLog_Item[TabId].pop_front(); + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, OldEvent->LogGuid); + delete OldEvent; + } + m_GuildBankEventLog_Item[TabId].push_back(NewEvent); + } + CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,LogEntry,TabId,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" I64FMTD "')", + Id, NewEvent->LogGuid, uint32(NewEvent->LogEntry), uint32(TabId), NewEvent->PlayerGuid, NewEvent->ItemOrMoney, uint32(NewEvent->ItemStackCount), uint32(NewEvent->DestTabId), NewEvent->TimeStamp); +} + +// This will renum guids used at load to prevent always going up until infinit +void Guild::RenumBankLogs() +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT Min(LogGuid), Max(LogGuid) FROM guild_bank_eventlog WHERE guildid = %u", Id); + if(!result) + return; + + Field *fields = result->Fetch(); + CharacterDatabase.PExecute("UPDATE guild_bank_eventlog SET LogGuid=LogGuid-%u+1 WHERE guildid=%u ORDER BY LogGuid %s",fields[0].GetUInt32(), Id, fields[0].GetUInt32()?"ASC":"DESC"); + LogMaxGuid = fields[1].GetUInt32()+1; + delete result; +} + +bool Guild::AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry ) +{ + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u' AND TabId = '%u'AND SlotId = '%u'", GuildId, BankTab, BankTabSlot); + CharacterDatabase.PExecute("INSERT INTO guild_bank_item (guildid,TabId,SlotId,item_guid,item_entry) " + "VALUES ('%u', '%u', '%u', '%u', '%u')", GuildId, BankTab, BankTabSlot, GUIDLow, Entry); + return true; +} + +void Guild::AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *tab, int slot ) +{ + Item *pItem = tab->Slots[slot]; + uint32 entry = pItem ? pItem->GetEntry() : 0; + + data << uint8(slot); + data << uint32(entry); + if (entry) + { + // random item property id +8 + data << (uint32) pItem->GetItemRandomPropertyId(); + if (pItem->GetItemRandomPropertyId()) + // SuffixFactor +4 + data << (uint32) pItem->GetItemSuffixFactor(); + // +12 // ITEM_FIELD_STACK_COUNT + data << uint8(pItem->GetCount()); + data << uint32(0); // +16 // Unknown value + data << uint8(0); // unknown 2.4.2 + if (uint32 Enchant0 = pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)) + { + data << uint8(1); // number of enchantments (max 3) why max 3? + data << uint8(PERM_ENCHANTMENT_SLOT); // enchantment slot (range: 0:2) + data << uint32(Enchant0); // enchantment id + } + else + data << uint8(0); // no enchantments (0) + } +} + +Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pItem ) +{ + if( !pItem ) + return NULL; + + Item* lastItem = pItem; + + for(GuildItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ) + { + uint8 slot = itr->slot; + uint32 count = itr->count; + + ++itr; + + if(itr == dest.end()) + { + lastItem = _StoreItem(tabId,slot,pItem,count,false); + break; + } + + lastItem = _StoreItem(tabId,slot,pItem,count,true); + } + + return lastItem; +} + +// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case. +Item* Guild::_StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone ) +{ + if( !pItem ) + return NULL; + + sLog.outDebug( "GUILD STORAGE: StoreItem tab = %u, slot = %u, item = %u, count = %u", tab, slot, pItem->GetEntry(), count); + + Item* pItem2 = m_TabListMap[tab]->Slots[slot]; + + if( !pItem2 ) + { + if(clone) + pItem = pItem->CloneItem(count); + else + pItem->SetCount(count); + + if(!pItem) + return NULL; + + m_TabListMap[tab]->Slots[slot] = pItem; + + pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); + pItem->SetUInt64Value(ITEM_FIELD_OWNER, 0); + AddGBankItemToDB(GetId(), tab, slot, pItem->GetGUIDLow(), pItem->GetEntry()); + pItem->FSetState(ITEM_NEW); + pItem->SaveToDB(); // not in onventory and can be save standalone + + return pItem; + } + else + { + pItem2->SetCount( pItem2->GetCount() + count ); + pItem2->FSetState(ITEM_CHANGED); + pItem2->SaveToDB(); // not in onventory and can be save standalone + + if(!clone) + { + pItem->RemoveFromWorld(); + pItem->DeleteFromDB(); + delete pItem; + } + + return pItem2; + } +} + +void Guild::RemoveItem(uint8 tab, uint8 slot ) +{ + m_TabListMap[tab]->Slots[slot] = NULL; + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", + GetId(), uint32(tab), uint32(slot)); +} + +uint8 Guild::_CanStoreItem_InSpecificSlot( uint8 tab, uint8 slot, GuildItemPosCountVec &dest, uint32& count, bool swap, Item* pSrcItem ) const +{ + Item* pItem2 = m_TabListMap[tab]->Slots[slot]; + + // ignore move item (this slot will be empty at move) + if(pItem2==pSrcItem) + pItem2 = NULL; + + uint32 need_space; + + // empty specific slot - check item fit to slot + if( !pItem2 || swap ) + { + // non empty stack with space + need_space = pSrcItem->GetMaxStackCount(); + } + // non empty slot, check item type + else + { + // check item type + if(pItem2->GetEntry() != pSrcItem->GetEntry()) + return EQUIP_ERR_ITEM_CANT_STACK; + + // check free space + if(pItem2->GetCount() >= pSrcItem->GetMaxStackCount()) + return EQUIP_ERR_ITEM_CANT_STACK; + + need_space = pSrcItem->GetMaxStackCount() - pItem2->GetCount(); + } + + if(need_space > count) + need_space = count; + + GuildItemPosCount newPosition = GuildItemPosCount(slot,need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + } + + return EQUIP_ERR_OK; +} + +uint8 Guild::_CanStoreItem_InTab( uint8 tab, GuildItemPosCountVec &dest, uint32& count, bool merge, Item* pSrcItem, uint8 skip_slot ) const +{ + for(uint32 j = 0; j < GUILD_BANK_MAX_SLOTS; j++) + { + // skip specific slot already processed in first called _CanStoreItem_InSpecificSlot + if(j==skip_slot) + continue; + + Item* pItem2 = m_TabListMap[tab]->Slots[j]; + + // ignore move item (this slot will be empty at move) + if(pItem2==pSrcItem) + pItem2 = NULL; + + // if merge skip empty, if !merge skip non-empty + if((pItem2!=NULL)!=merge) + continue; + + if( pItem2 ) + { + if(pItem2->GetEntry() == pSrcItem->GetEntry() && pItem2->GetCount() < pSrcItem->GetMaxStackCount() ) + { + uint32 need_space = pSrcItem->GetMaxStackCount() - pItem2->GetCount(); + if(need_space > count) + need_space = count; + + GuildItemPosCount newPosition = GuildItemPosCount(j,need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + + if(count==0) + return EQUIP_ERR_OK; + } + } + } + else + { + uint32 need_space = pSrcItem->GetMaxStackCount(); + if(need_space > count) + need_space = count; + + GuildItemPosCount newPosition = GuildItemPosCount(j,need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + + if(count==0) + return EQUIP_ERR_OK; + } + } + } + return EQUIP_ERR_OK; +} + +uint8 Guild::CanStoreItem( uint8 tab, uint8 slot, GuildItemPosCountVec &dest, uint32 count, Item *pItem, bool swap ) const +{ + sLog.outDebug( "GUILD STORAGE: CanStoreItem tab = %u, slot = %u, item = %u, count = %u", tab, slot, pItem->GetEntry(), count); + + if(count > pItem->GetCount()) + return EQUIP_ERR_COULDNT_SPLIT_ITEMS; + + if(pItem->IsSoulBound()) + return EQUIP_ERR_CANT_DROP_SOULBOUND; + + // in specific slot + if( slot != NULL_SLOT ) + { + uint8 res = _CanStoreItem_InSpecificSlot(tab,slot,dest,count,swap,pItem); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + + // not specific slot or have spece for partly store only in specific slot + + // search stack in tab for merge to + if( pItem->GetMaxStackCount() > 1 ) + { + uint8 res = _CanStoreItem_InTab(tab,dest,count,true,pItem,slot); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + + // search free slot in bag for place to + uint8 res = _CanStoreItem_InTab(tab,dest,count,false,pItem,slot); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + + return EQUIP_ERR_BANK_FULL; +} + +void Guild::SetGuildBankTabText(uint8 TabId, std::string text) +{ + if (TabId >= GUILD_BANK_MAX_TABS) + return; + if (TabId >= m_TabListMap.size()) + return; + if (!m_TabListMap[TabId]) + return; + + if(m_TabListMap[TabId]->Text==text) + return; + + utf8truncate(text,500); // DB and client size limitation + + m_TabListMap[TabId]->Text = text; + + CharacterDatabase.escape_string(text); + CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabText='%s' WHERE guildid='%u' AND TabId='%u'", text.c_str(), Id, uint32(TabId)); +} + +void Guild::SendGuildBankTabText(WorldSession *session, uint8 TabId) +{ + if (TabId > GUILD_BANK_MAX_TABS) + return; + + GuildBankTab const *tab = GetBankTab(TabId); + if (!tab) + return; + + WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1+tab->Text.size()+1); + data << uint8(TabId); + data << tab->Text; + session->SendPacket(&data); +} + +bool GuildItemPosCount::isContainedIn(GuildItemPosCountVec const &vec) const +{ + for(GuildItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr) + if(itr->slot == this->slot) + return true; + + return false; +} diff --git a/src/game/Guild.h b/src/game/Guild.h new file mode 100644 index 000000000..cb46e1107 --- /dev/null +++ b/src/game/Guild.h @@ -0,0 +1,437 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_GUILD_H +#define MANGOSSERVER_GUILD_H + +#define WITHDRAW_MONEY_UNLIMITED 0xFFFFFFFF +#define WITHDRAW_SLOT_UNLIMITED 0xFFFFFFFF + +#include "Item.h" + +class Item; + +enum GuildDefaultRanks +{ + GR_GUILDMASTER = 0, + GR_OFFICER = 1, + //GR_VETERAN = 2, -- not used anywhere and possible incorrect in modified rank list + //GR_MEMBER = 3, + //GR_INITIATE = 4, -- use Guild::GetLowestRank() instead for lowest rank +}; + +enum GuildRankRights +{ + GR_RIGHT_EMPTY = 0x00000040, + GR_RIGHT_GCHATLISTEN = 0x00000041, + GR_RIGHT_GCHATSPEAK = 0x00000042, + GR_RIGHT_OFFCHATLISTEN = 0x00000044, + GR_RIGHT_OFFCHATSPEAK = 0x00000048, + GR_RIGHT_PROMOTE = 0x000000C0, + GR_RIGHT_DEMOTE = 0x00000140, + GR_RIGHT_INVITE = 0x00000050, + GR_RIGHT_REMOVE = 0x00000060, + GR_RIGHT_SETMOTD = 0x00001040, + GR_RIGHT_EPNOTE = 0x00002040, + GR_RIGHT_VIEWOFFNOTE = 0x00004040, + GR_RIGHT_EOFFNOTE = 0x00008040, + GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040, + GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity + GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair + GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold + GR_RIGHT_ALL = 0x000FF1FF +}; + +enum Typecommand +{ + GUILD_CREATE_S = 0x00, + GUILD_INVITE_S = 0x01, + GUILD_QUIT_S = 0x03, + GUILD_FOUNDER_S = 0x0E, + GUILD_UNK1 = 0x10, + GUILD_BANK_S = 0x15, + GUILD_UNK3 = 0x16 +}; + +enum CommandErrors +{ + GUILD_PLAYER_NO_MORE_IN_GUILD = 0x00, + GUILD_INTERNAL = 0x01, + GUILD_ALREADY_IN_GUILD = 0x02, + ALREADY_IN_GUILD = 0x03, + INVITED_TO_GUILD = 0x04, + ALREADY_INVITED_TO_GUILD = 0x05, + GUILD_NAME_INVALID = 0x06, + GUILD_NAME_EXISTS = 0x07, + GUILD_LEADER_LEAVE = 0x08, + GUILD_PERMISSIONS = 0x08, + GUILD_PLAYER_NOT_IN_GUILD = 0x09, + GUILD_PLAYER_NOT_IN_GUILD_S = 0x0A, + GUILD_PLAYER_NOT_FOUND = 0x0B, + GUILD_NOT_ALLIED = 0x0C, + GUILD_RANK_TOO_HIGH_S = 0x0D, + GUILD_ALREADY_LOWEST_RANK_S = 0x0E, + GUILD_TEMP_ERROR = 0x11, + GUILD_RANK_IN_USE = 0x12, + GUILD_IGNORE = 0x13, + GUILD_ERR_UNK1 = 0x17, + GUILD_WITHDRAW_TOO_MUCH = 0x18, + GUILD_BANK_NO_MONEY = 0x19, + GUILD_BANK_TAB_IS_FULL = 0x1B, + GUILD_BANK_ITEM_NOT_FOUND = 0x1C +}; + +enum GuildEvents +{ + GE_PROMOTION = 0x00, + GE_DEMOTION = 0x01, + GE_MOTD = 0x02, + GE_JOINED = 0x03, + GE_LEFT = 0x04, + GE_REMOVED = 0x05, + GE_LEADER_IS = 0x06, + GE_LEADER_CHANGED = 0x07, + GE_DISBANDED = 0x08, + GE_TABARDCHANGE = 0x09, + GE_UNK1 = 0x0A, // string, string + GE_UNK2 = 0x0B, + GE_SIGNED_ON = 0x0C, + GE_SIGNED_OFF = 0x0D, + GE_UNK3 = 0x0E, + GE_BANKTAB_PURCHASED= 0x0F, + GE_UNK5 = 0x10, + GE_UNK6 = 0x11, // string 0000000000002710 is 1 gold + GE_UNK7 = 0x12 +}; + +enum PetitionTurns +{ + PETITION_TURN_OK = 0, + PETITION_TURN_ALREADY_IN_GUILD = 2, + PETITION_TURN_NEED_MORE_SIGNATURES = 4, +}; + +enum PetitionSigns +{ + PETITION_SIGN_OK = 0, + PETITION_SIGN_ALREADY_SIGNED = 1, + PETITION_SIGN_ALREADY_IN_GUILD = 2, + PETITION_SIGN_CANT_SIGN_OWN = 3, + PETITION_SIGN_NOT_SERVER = 4, +}; + +enum GuildBankRights +{ + GUILD_BANK_RIGHT_VIEW_TAB = 0x01, + GUILD_BANK_RIGHT_PUT_ITEM = 0x02, + GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, + + GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, + GUILD_BANK_RIGHT_FULL = 0xFF, +}; + +enum GuildBankLogEntries +{ + GUILD_BANK_LOG_DEPOSIT_ITEM = 1, + GUILD_BANK_LOG_WITHDRAW_ITEM = 2, + GUILD_BANK_LOG_MOVE_ITEM = 3, + GUILD_BANK_LOG_DEPOSIT_MONEY = 4, + GUILD_BANK_LOG_WITHDRAW_MONEY = 5, + GUILD_BANK_LOG_REPAIR_MONEY = 6, + GUILD_BANK_LOG_MOVE_ITEM2 = 7, +}; + +enum GuildEventLogEntryTypes +{ + GUILD_EVENT_LOG_INVITE_PLAYER = 1, + GUILD_EVENT_LOG_JOIN_GUILD = 2, + GUILD_EVENT_LOG_PROMOTE_PLAYER = 3, + GUILD_EVENT_LOG_DEMOTE_PLAYER = 4, + GUILD_EVENT_LOG_UNINVITE_PLAYER = 5, + GUILD_EVENT_LOG_LEAVE_GUILD = 6, +}; + +struct GuildEventlogEntry +{ + uint32 LogGuid; + uint8 EventType; + uint32 PlayerGuid1; + uint32 PlayerGuid2; + uint8 NewRank; + uint64 TimeStamp; +}; + +enum GuildEmblem +{ + ERR_GUILDEMBLEM_SUCCESS = 0, + ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1, + ERR_GUILDEMBLEM_NOGUILD = 2, + ERR_GUILDEMBLEM_NOTGUILDMASTER = 3, + ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4, + ERR_GUILDEMBLEM_INVALIDVENDOR = 5 +}; + +struct GuildBankEvent +{ + uint32 LogGuid; + uint8 LogEntry; + uint8 TabId; + uint32 PlayerGuid; + uint32 ItemOrMoney; + uint8 ItemStackCount; + uint8 DestTabId; + uint64 TimeStamp; + + const bool isMoneyEvent() + { + return LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || + LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || + LogEntry == GUILD_BANK_LOG_REPAIR_MONEY; + } +}; + +struct GuildBankTab +{ + Item* Slots[GUILD_BANK_MAX_SLOTS]; + std::string Name; + std::string Icon; + std::string Text; +}; + +struct GuildItemPosCount +{ + GuildItemPosCount(uint8 _slot, uint8 _count) : slot(_slot), count(_count) {} + + bool isContainedIn(std::vector const& vec) const; + + uint8 slot; + uint8 count; +}; +typedef std::vector GuildItemPosCountVec; + +struct MemberSlot +{ + uint64 logout_time; + std::string name; + std::string Pnote; + std::string OFFnote; + uint32 RankId; + uint32 zoneId; + uint8 level; + uint8 Class; + uint32 BankResetTimeMoney; + uint32 BankRemMoney; + uint32 BankResetTimeTab[GUILD_BANK_MAX_TABS]; + uint32 BankRemSlotsTab[GUILD_BANK_MAX_TABS]; +}; + +struct RankInfo +{ + RankInfo(std::string _name, uint32 _rights, uint32 _money) : name(_name), rights(_rights), BankMoneyPerDay(_money) + { + for(uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + TabRight[i] = 0; + TabSlotPerDay[i] = 0; + } + } + + std::string name; + uint32 rights; + uint32 BankMoneyPerDay; + uint32 TabRight[GUILD_BANK_MAX_TABS]; + uint32 TabSlotPerDay[GUILD_BANK_MAX_TABS]; +}; + +class Guild +{ + public: + Guild(); + ~Guild(); + + bool create(uint64 lGuid, std::string gname); + void Disband(); + + typedef std::map MemberList; + typedef std::vector RankList; + + uint32 GetId(){ return Id; } + const uint64& GetLeader(){ return leaderGuid; } + std::string GetName(){ return name; } + std::string GetMOTD(){ return MOTD; } + std::string GetGINFO(){ return GINFO; } + + uint32 GetCreatedYear(){ return CreatedYear; } + uint32 GetCreatedMonth(){ return CreatedMonth; } + uint32 GetCreatedDay(){ return CreatedDay; } + + uint32 GetEmblemStyle(){ return EmblemStyle; } + uint32 GetEmblemColor(){ return EmblemColor; } + uint32 GetBorderStyle(){ return BorderStyle; } + uint32 GetBorderColor(){ return BorderColor; } + uint32 GetBackgroundColor(){ return BackgroundColor; } + + void SetLeader(uint64 guid); + bool AddMember(uint64 plGuid, uint32 plRank); + void ChangeRank(uint64 guid, uint32 newRank); + void DelMember(uint64 guid, bool isDisbanding=false); + uint32 GetLowestRank() const { return GetNrRanks()-1; } + + void SetMOTD(std::string motd); + void SetGINFO(std::string ginfo); + void SetPNOTE(uint64 guid,std::string pnote); + void SetOFFNOTE(uint64 guid,std::string offnote); + void SetEmblem(uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor, uint32 backgroundColor); + + uint32 GetMemberSize() const { return members.size(); } + + bool LoadGuildFromDB(uint32 GuildId); + bool LoadRanksFromDB(uint32 GuildId); + bool LoadMembersFromDB(uint32 GuildId); + + bool FillPlayerData(uint64 guid, MemberSlot* memslot); + void LoadPlayerStatsByGuid(uint64 guid); + + void BroadcastToGuild(WorldSession *session, std::string msg, uint32 language = LANG_UNIVERSAL); + void BroadcastToOfficers(WorldSession *session, std::string msg, uint32 language = LANG_UNIVERSAL); + void BroadcastPacketToRank(WorldPacket *packet, uint32 rankId); + void BroadcastPacket(WorldPacket *packet); + + void CreateRank(std::string name,uint32 rights); + void DelRank(); + std::string GetRankName(uint32 rankId); + uint32 GetRankRights(uint32 rankId); + uint32 GetNrRanks() const { return m_ranks.size(); } + + void SetRankName(uint32 rankId, std::string name); + void SetRankRights(uint32 rankId, uint32 rights); + bool HasRankRight(uint32 rankId, uint32 right) + { + return ((GetRankRights(rankId) & right) != GR_RIGHT_EMPTY) ? true : false; + } + + void Roster(WorldSession *session); + void Query(WorldSession *session); + + void UpdateLogoutTime(uint64 guid); + // Guild eventlog + void LoadGuildEventLogFromDB(); + void UnloadGuildEventlog(); + void DisplayGuildEventlog(WorldSession *session); + void LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank); + void RenumGuildEventlog(); + + // ** Guild bank ** + // Content & item deposit/withdraw + void DisplayGuildBankContent(WorldSession *session, uint8 TabId); + void DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2 = -1); + void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots); + void DisplayGuildBankMoneyUpdate(); + + Item* GetItem(uint8 TabId, uint8 SlotId); + uint8 CanStoreItem( uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32 count, Item *pItem, bool swap = false) const; + Item* StoreItem( uint8 tab, GuildItemPosCountVec const& pos, Item *pItem ); + void RemoveItem(uint8 tab, uint8 slot ); + + // Tabs + void DisplayGuildBankTabsInfo(WorldSession *session); + void CreateNewBankTab(); + void SetGuildBankTabText(uint8 TabId, std::string text); + void SendGuildBankTabText(WorldSession *session, uint8 TabId); + void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon); + void CreateBankRightForTab(uint32 rankid, uint8 TabId); + const GuildBankTab *GetBankTab(uint8 index) { if(index >= m_TabListMap.size()) return NULL; return m_TabListMap[index]; } + const uint8 GetPurchasedTabs() const { return purchased_tabs; } + uint32 GetBankRights(uint32 rankId, uint8 TabId) const; + bool IsMemberHaveRights(uint32 LowGuid, uint8 TabId,uint32 rights) const; + bool CanMemberViewTab(uint32 LowGuid, uint8 TabId) const; + // Load/unload + void LoadGuildBankFromDB(); + void UnloadGuildBank(); + void IncOnlineMemberCount() { ++m_onlinemembers; } + // Money deposit/withdraw + void SendMoneyInfo(WorldSession *session, uint32 LowGuid); + bool MemberMoneyWithdraw(uint32 amount, uint32 LowGuid); + uint64 GetGuildBankMoney() { return guildbank_money; } + void SetBankMoney(int64 money); + // per days + bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid); + uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId); + uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid); + void SetBankMoneyPerDay(uint32 rankId, uint32 money); + void SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 SlotPerDay, bool db); + uint32 GetBankMoneyPerDay(uint32 rankId); + uint32 GetBankSlotPerDay(uint32 rankId, uint8 TabId); + // rights per day + void LoadBankRightsFromDB(uint32 GuildId); + // logs + void LoadGuildBankEventLogFromDB(); + void UnloadGuildBankEventLog(); + void DisplayGuildBankLogs(WorldSession *session, uint8 TabId); + void LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount=0, uint8 DestTabId=0); + void RenumBankLogs(); + bool AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry ); + + protected: + void AddRank(std::string name,uint32 rights,uint32 money); + + uint32 Id; + std::string name; + uint64 leaderGuid; + std::string MOTD; + std::string GINFO; + uint32 CreatedYear; + uint32 CreatedMonth; + uint32 CreatedDay; + + uint32 EmblemStyle; + uint32 EmblemColor; + uint32 BorderStyle; + uint32 BorderColor; + uint32 BackgroundColor; + + RankList m_ranks; + + MemberList members; + + typedef std::vector TabListMap; + TabListMap m_TabListMap; + + /** These are actually ordered lists. The first element is the oldest entry.*/ + typedef std::list GuildEventlog; + typedef std::list GuildBankEventLog; + GuildEventlog m_GuildEventlog; + GuildBankEventLog m_GuildBankEventLog_Money; + GuildBankEventLog m_GuildBankEventLog_Item[GUILD_BANK_MAX_TABS]; + + bool m_bankloaded; + bool m_eventlogloaded; + uint32 m_onlinemembers; + uint64 guildbank_money; + uint8 purchased_tabs; + + uint32 LogMaxGuid; + uint32 GuildEventlogMaxGuid; + private: + // internal common parts for CanStore/StoreItem functions + void AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *tab, int32 slot ); + uint8 _CanStoreItem_InSpecificSlot( uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32& count, bool swap, Item *pSrcItem ) const; + uint8 _CanStoreItem_InTab( uint8 tab, GuildItemPosCountVec& dest, uint32& count, bool merge, Item *pSrcItem, uint8 skip_slot ) const; + Item* _StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone ); +}; +#endif diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp new file mode 100644 index 000000000..a97a2d7da --- /dev/null +++ b/src/game/GuildHandler.cpp @@ -0,0 +1,1815 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Log.h" +#include "Opcodes.h" +#include "Guild.h" +#include "MapManager.h" +#include "GossipDef.h" +#include "SocialMgr.h" + +void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 4); + + uint32 guildId; + Guild *guild; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY"); + + recvPacket >> guildId; + + guild = objmgr.GetGuildById(guildId); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + guild->Query(this); +} + +void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string gname; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE"); + + recvPacket >> gname; + + if(GetPlayer()->GetGuildId()) + return; + + Guild *guild = new Guild; + if(!guild->create(GetPlayer()->GetGUID(),gname)) + { + delete guild; + return; + } + + objmgr.AddGuild(guild); +} + +void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string Invitedname, plname; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE"); + + Player * player = NULL; + + recvPacket >> Invitedname; + + if(normalizePlayerName(Invitedname)) + player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); + + if(!player) + { + SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_PLAYER_NOT_FOUND); + return; + } + + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + // OK result but not send invite + if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + return; + + // not let enemies sign guild charter + if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) + { + SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_NOT_ALLIED); + return; + } + + if(player->GetGuildId()) + { + plname = player->GetName(); + SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_IN_GUILD); + return; + } + + if(player->GetGuildIdInvited()) + { + plname = player->GetName(); + SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_INVITED_TO_GUILD); + return; + } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str()); + + player->SetGuildIdInvited(GetPlayer()->GetGuildId()); + // Put record into guildlog + guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0); + + WorldPacket data(SMSG_GUILD_INVITE, (8+10)); // guess size + data << GetPlayer()->GetName(); + data << guild->GetName(); + player->GetSession()->SendPacket(&data); + + //sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)"); +} + +void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string plName; + uint64 plGuid; + uint32 plGuildId; + Guild *guild; + Player *player; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE"); + + recvPacket >> plName; + + if(!normalizePlayerName(plName)) + return; + + player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + + if(player) + { + plGuid = player->GetGUID(); + plGuildId = player->GetGuildId(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(plName); + plGuildId = Player::GetGuildIdFromDB(plGuid); + } + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if(!plGuid) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); + return; + } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + if(plGuid == guild->GetLeader()) + { + SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE); + return; + } + + if(GetPlayer()->GetGuildId() != plGuildId) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); + return; + } + + guild->DelMember(plGuid); + // Put record into guildlog + guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), 0); + + WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size + data << (uint8)GE_REMOVED; + data << (uint8)2; // strings count + data << plName; + data << GetPlayer()->GetName(); + guild->BroadcastPacket(&data); +} + +void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) +{ + Guild *guild; + Player *player = GetPlayer(); + + //sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT"); + + guild = objmgr.GetGuildById(player->GetGuildIdInvited()); + if(!guild || player->GetGuildId()) + return; + + // not let enemies sign guild charter + if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != objmgr.GetPlayerTeamByGUID(guild->GetLeader())) + return; + + if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank())) + return; + // Put record into guildlog + guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0); + + WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size + data << (uint8)GE_JOINED; + data << (uint8)1; + data << player->GetName(); + guild->BroadcastPacket(&data); + + //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); +} + +void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) +{ + //sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE"); + + GetPlayer()->SetGuildIdInvited(0); + GetPlayer()->SetInGuild(0); +} + +void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/) +{ + Guild *guild; + //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO"); + + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1)); + data << guild->GetName(); + data << guild->GetCreatedDay(); + data << guild->GetCreatedMonth(); + data << guild->GetCreatedYear(); + data << guild->GetMemberSize(); + data << guild->GetMemberSize(); + + SendPacket(&data); +} + +void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/) +{ + //sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER"); + + Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + return; + + guild->Roster(this); +} + +void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string plName; + uint64 plGuid; + uint32 plGuildId; + uint32 plRankId; + Player *player; + Guild *guild; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE"); + + recvPacket >> plName; + + if(!normalizePlayerName(plName)) + return; + + player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(player) + { + plGuid = player->GetGUID(); + plGuildId = player->GetGuildId(); + plRankId = player->GetRank(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(plName); + plGuildId = Player::GetGuildIdFromDB(plGuid); + plRankId = Player::GetRankFromDB(plGuid); + } + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + else if(!plGuid) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); + return; + } + else if(plGuid == GetPlayer()->GetGUID()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID); + return; + } + else if(GetPlayer()->GetGuildId() != plGuildId) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); + return; + } + else if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + else if((plRankId-1) == 0 || (plRankId-1) < this->GetPlayer()->GetRank()) + return; + + if(plRankId < 1) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_INTERNAL); + return; + } + + uint32 newRankId = plRankId < guild->GetNrRanks() ? plRankId-1 : guild->GetNrRanks()-1; + + guild->ChangeRank(plGuid, newRankId); + // Put record into guildlog + guild->LogGuildEvent(GUILD_EVENT_LOG_PROMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId); + + WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size + data << (uint8)GE_PROMOTION; + data << (uint8)3; + data << GetPlayer()->GetName(); + data << plName; + data << guild->GetRankName(newRankId); + guild->BroadcastPacket(&data); +} + +void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string plName; + uint64 plGuid; + uint32 plGuildId; + uint32 plRankId; + Player *player; + Guild *guild; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE"); + + recvPacket >> plName; + + if(!normalizePlayerName(plName)) + return; + + player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(player) + { + plGuid = player->GetGUID(); + plGuildId = player->GetGuildId(); + plRankId = player->GetRank(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(plName); + plGuildId = Player::GetGuildIdFromDB(plGuid); + plRankId = Player::GetRankFromDB(plGuid); + } + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if( !plGuid ) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); + return; + } + + if(plGuid == GetPlayer()->GetGUID()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID); + return; + } + + if(GetPlayer()->GetGuildId() != plGuildId) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); + return; + } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + if((plRankId+1) >= guild->GetNrRanks() || plRankId <= this->GetPlayer()->GetRank()) + return; + + guild->ChangeRank(plGuid, (plRankId+1)); + // Put record into guildlog + guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), (plRankId+1)); + + WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size + data << (uint8)GE_DEMOTION; + data << (uint8)3; + data << GetPlayer()->GetName(); + data << plName; + data << guild->GetRankName(plRankId+1); + guild->BroadcastPacket(&data); +} + +void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) +{ + std::string plName; + Guild *guild; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE"); + + guild = objmgr.GetGuildById(_player->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1) + { + SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE); + return; + } + + if(_player->GetGUID() == guild->GetLeader()) + { + guild->Disband(); + return; + } + + plName = _player->GetName(); + + guild->DelMember(_player->GetGUID()); + // Put record into guildlog + guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0); + + WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size + data << (uint8)GE_LEFT; + data << (uint8)1; + data << plName; + guild->BroadcastPacket(&data); + + //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); + + SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), GUILD_PLAYER_NO_MORE_IN_GUILD); +} + +void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) +{ + std::string name; + Guild *guild; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND"); + + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + if(GetPlayer()->GetGUID() != guild->GetLeader()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + guild->Disband(); + + //sLog.outDebug("WORLD: Guild Sucefully Disbanded"); +} + +void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + std::string name; + Player *newLeader; + uint64 newLeaderGUID; + uint32 newLeaderGuild; + Player *oldLeader = GetPlayer(); + Guild *guild; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER"); + + recvPacket >> name; + + if(!normalizePlayerName(name)) + return; + + newLeader = ObjectAccessor::Instance().FindPlayerByName(name.c_str()); + if(newLeader) + { + newLeaderGUID = newLeader->GetGUID(); + newLeaderGuild = newLeader->GetGuildId(); + } + else + { + newLeaderGUID = objmgr.GetPlayerGUIDByName(name); + newLeaderGuild = Player::GetGuildIdFromDB(newLeaderGUID); + } + guild = objmgr.GetGuildById(oldLeader->GetGuildId()); + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + else if(!newLeaderGUID) + { + SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND); + return; + } + if(oldLeader->GetGuildId() != newLeaderGuild) + { + SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S); + return; + } + if(oldLeader->GetGUID() != guild->GetLeader()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + guild->SetLeader(newLeaderGUID); + guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER); + + WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size + data << (uint8)GE_LEADER_CHANGED; + data << (uint8)2; + data << oldLeader->GetName(); + data << name.c_str(); + guild->BroadcastPacket(&data); + + //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); +} + +void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) +{ + Guild *guild; + std::string MOTD; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD"); + + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_SETMOTD)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + if(!recvPacket.empty()) + recvPacket >> MOTD; + else + MOTD = ""; + + guild->SetMOTD(MOTD); + + WorldPacket data(SMSG_GUILD_EVENT, (2+MOTD.size()+1)); + data << (uint8)GE_MOTD; + data << (uint8)1; + data << MOTD; + guild->BroadcastPacket(&data); + + //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); +} + +void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + Guild *guild; + Player *player; + uint64 plGuid; + uint32 plGuildId; + std::string name,PNOTE; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE"); + + recvPacket >> name; + + if(!normalizePlayerName(name)) + return; + + player = ObjectAccessor::Instance().FindPlayerByName(name.c_str()); + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(player) + { + plGuid = player->GetGUID(); + plGuildId = player->GetGuildId(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(name); + plGuildId = Player::GetGuildIdFromDB(plGuid); + } + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + else if(!plGuid) + { + SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND); + return; + } + else if(GetPlayer()->GetGuildId() != plGuildId) + { + SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S); + return; + } + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + recvPacket >> PNOTE; + guild->SetPNOTE(plGuid, PNOTE); + + guild->Roster(this); +} + +void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + Guild *guild; + Player *player; + uint64 plGuid; + uint32 plGuildId; + std::string plName, OFFNOTE; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE"); + + recvPacket >> plName; + + if(!normalizePlayerName(plName)) + return; + + player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(player) + { + plGuid = player->GetGUID(); + plGuildId = player->GetGuildId(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(plName); + plGuildId = Player::GetGuildIdFromDB(plGuid); + } + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + else if( !plGuid ) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); + return; + } + else if(GetPlayer()->GetGuildId() != plGuildId) + { + SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); + return; + } + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + recvPacket >> OFFNOTE; + guild->SetOFFNOTE(plGuid, OFFNOTE); + + guild->Roster(this); +} + +void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 4+4+1+4*13); + //recvPacket.hexlike(); + + Guild *guild; + std::string rankname; + uint32 rankId; + uint32 rights, MoneyPerDay; + uint32 BankRights; + uint32 BankSlotPerDay; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_RANK"); + + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + else if(GetPlayer()->GetGUID() != guild->GetLeader()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + recvPacket >> rankId; + recvPacket >> rights; + recvPacket >> rankname; + recvPacket >> MoneyPerDay; + + for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + recvPacket >> BankRights; + recvPacket >> BankSlotPerDay; + guild->SetBankRightsAndSlots(rankId, uint8(i), uint16(BankRights & 0xFF), uint16(BankSlotPerDay), true); + } + sLog.outDebug("WORLD: Changed RankName to %s , Rights to 0x%.4X", rankname.c_str(), rights); + + guild->SetBankMoneyPerDay(rankId, MoneyPerDay); + guild->SetRankName(rankId, rankname); + + if(rankId==GR_GUILDMASTER) // prevent loss leader rights + rights |= GR_RIGHT_ALL; + + guild->SetRankRights(rankId, rights); + + guild->Query(this); + guild->Roster(this); +} + +void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + Guild *guild; + std::string rankname; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK"); + + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if(GetPlayer()->GetGUID() != guild->GetLeader()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + if(guild->GetNrRanks() >= GUILD_MAX_RANKS) // client not let create more 10 than ranks + return; + + recvPacket >> rankname; + + guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); + + guild->Query(this); + guild->Roster(this); +} + +void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/) +{ + Guild *guild; + std::string rankname; + + //sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK"); + + guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + else if(GetPlayer()->GetGUID() != guild->GetLeader()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + guild->DelRank(); + + guild->Query(this); + guild->Roster(this); +} + +void WorldSession::SendGuildCommandResult(uint32 typecmd,std::string str,uint32 cmdresult) +{ + WorldPacket data(SMSG_GUILD_COMMAND_RESULT, (8+str.size()+1)); + data << typecmd; + data << str; + data << cmdresult; + SendPacket(&data); + + //sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)"); +} + +void WorldSession::HandleGuildChangeInfoOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT"); + + std::string GINFO; + + recvPacket >> GINFO; + + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_MODIFY_GUILD_INFO)) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PERMISSIONS); + return; + } + + guild->SetGINFO(GINFO); +} + +void WorldSession::HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 8+4+4+4+4+4); + + //sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM"); + + uint64 vendorGuid; + + uint32 EmblemStyle; + uint32 EmblemColor; + uint32 BorderStyle; + uint32 BorderColor; + uint32 BackgroundColor; + + recvPacket >> vendorGuid; + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER); + if (!pCreature) + { + //"That's not an emblem vendor!" + SendSaveGuildEmblem(ERR_GUILDEMBLEM_INVALIDVENDOR); + sLog.outDebug("WORLD: HandleGuildSaveEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid)); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + recvPacket >> EmblemStyle; + recvPacket >> EmblemColor; + recvPacket >> BorderStyle; + recvPacket >> BorderColor; + recvPacket >> BackgroundColor; + + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + //"You are not part of a guild!"; + SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOGUILD); + return; + } + + if (guild->GetLeader() != GetPlayer()->GetGUID()) + { + //"Only guild leaders can create emblems." + SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTGUILDMASTER); + return; + } + + if(GetPlayer()->GetMoney() < 10*GOLD) + { + //"You can't afford to do that." + SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTENOUGHMONEY); + return; + } + + GetPlayer()->ModifyMoney(-10*GOLD); + guild->SetEmblem(EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor); + + //"Guild Emblem saved." + SendSaveGuildEmblem(ERR_GUILDEMBLEM_SUCCESS); + + guild->Query(this); +} + +void WorldSession::HandleGuildEventLogOpcode(WorldPacket& /* recvPacket */) +{ + // empty + sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)"); + //recvPacket.hexlike(); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + pGuild->DisplayGuildEventlog(this); +} + +/****** GUILD BANK *******/ + +void WorldSession::HandleGuildBankGetMoneyAmount( WorldPacket & /* recv_data */ ) +{ + sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)"); + //recv_data.hexlike(); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); +} + +void WorldSession::HandleGuildBankGetRights( WorldPacket& /* recv_data */ ) +{ + sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)"); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint32 rankId = GetPlayer()->GetRank(); + + WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1); + data << uint32(rankId); // guild rank id + data << uint32(pGuild->GetRankRights(rankId)); // rank rights + // money per day left + data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow())); + data << uint8(pGuild->GetPurchasedTabs()); // tabs count + for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + data << uint32(pGuild->GetBankRights(rankId, uint8(i))); + data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i))); + } + SendPacket(&data); + sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)"); +} + +/* Called when clicking on Guild bank gameobject */ +void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)"); + CHECK_PACKET_SIZE(recv_data,8+1); + uint64 GoGuid; + uint8 unk; + recv_data >> GoGuid >> unk; + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + if (uint32 GuildId = GetPlayer()->GetGuildId()) + { + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + { + pGuild->DisplayGuildBankTabsInfo(this); + return; + } + } + + SendGuildCommandResult(GUILD_BANK_S, "", GUILD_PLAYER_NOT_IN_GUILD); +} + +/* Called when opening guild bank tab only (first one) */ +void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)"); + CHECK_PACKET_SIZE(recv_data,8+1+1); + uint64 GoGuid; + uint8 TabId,unk1; + recv_data >> GoGuid >> TabId >> unk1; + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + // Let's update the amount of gold the player can withdraw before displaying the content + // This is usefull if money withdraw right has changed + pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); + + pGuild->DisplayGuildBankContent(this, TabId); +} + +void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)"); + CHECK_PACKET_SIZE(recv_data,8+4); + uint64 GoGuid; + uint32 money; + recv_data >> GoGuid >> money; + + if (!money) + return; + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + if (GetPlayer()->GetMoney() < money) + return; + + CharacterDatabase.BeginTransaction(); + + pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money); + GetPlayer()->ModifyMoney(-int(money)); + GetPlayer()->SaveGoldToDB(); + + CharacterDatabase.CommitTransaction(); + + // logging money + if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand("GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)", + _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId); + } + + // log + pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money); + + pGuild->DisplayGuildBankTabsInfo(this); + pGuild->DisplayGuildBankContent(this, 0); + pGuild->DisplayGuildBankMoneyUpdate(); +} + +void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)"); + CHECK_PACKET_SIZE(recv_data,8+4); + uint64 GoGuid; + uint32 money; + recv_data >> GoGuid >> money; + + if (!money) + return; + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + if (pGuild->GetGuildBankMoney()HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD)) + return; + + CharacterDatabase.BeginTransaction(); + + if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow())) + { + CharacterDatabase.RollbackTransaction(); + return; + } + + GetPlayer()->ModifyMoney(money); + GetPlayer()->SaveGoldToDB(); + + CharacterDatabase.CommitTransaction(); + + // Log + pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money); + + pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); + pGuild->DisplayGuildBankTabsInfo(this); + pGuild->DisplayGuildBankContent(this, 0); + pGuild->DisplayGuildBankMoneyUpdate(); +} + +void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)"); + //recv_data.hexlike(); + + uint64 GoGuid; + uint8 BankToBank; + + uint8 BankTab, BankTabSlot, AutoStore, AutoStoreCount, PlayerSlot, PlayerBag, SplitedAmount = 0; + uint8 BankTabDst, BankTabSlotDst, unk2, ToChar = 1; + uint32 ItemEntry, unk1; + bool BankToChar = false; + + CHECK_PACKET_SIZE(recv_data,8+1); + recv_data >> GoGuid >> BankToBank; + if (BankToBank) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1+1+4+1+1); + recv_data >> BankTabDst; + recv_data >> BankTabSlotDst; + recv_data >> unk1; // always 0 + recv_data >> BankTab; + recv_data >> BankTabSlot; + recv_data >> ItemEntry; + recv_data >> unk2; // always 0 + recv_data >> SplitedAmount; + + if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS) + return; + if (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot) + return; + } + else + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+4+1); + recv_data >> BankTab; + recv_data >> BankTabSlot; + recv_data >> ItemEntry; + recv_data >> AutoStore; + if (AutoStore) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1); + recv_data >> AutoStoreCount; + } + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1); + recv_data >> PlayerBag; + recv_data >> PlayerSlot; + if (!AutoStore) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1); + recv_data >> ToChar; + recv_data >> SplitedAmount; + } + + if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF) + return; + } + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + Player *pl = GetPlayer(); + + // Bank <-> Bank + if (BankToBank) + { + // empty operation + if(BankTab==BankTabDst && BankTabSlot==BankTabSlotDst) + return; + + Item *pItemSrc = pGuild->GetItem(BankTab, BankTabSlot); + if (!pItemSrc) // may prevent crash + return; + + if(SplitedAmount > pItemSrc->GetCount()) + return; // cheating? + else if(SplitedAmount == pItemSrc->GetCount()) + SplitedAmount = 0; // no split + + Item *pItemDst = pGuild->GetItem(BankTabDst, BankTabSlotDst); + + if(BankTab!=BankTabDst) + { + // check dest pos rights (if different tabs) + if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTabDst, GUILD_BANK_RIGHT_DEPOSIT_ITEM)) + return; + + // check source pos rights (if different tabs) + uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab); + if(remRight <= 0) + return; + } + + if (SplitedAmount) + { // Bank -> Bank item split (in empty or non empty slot + GuildItemPosCountVec dest; + uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,dest,SplitedAmount,pItemSrc,false); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemSrc, NULL ); + return; + } + + Item *pNewItem = pItemSrc->CloneItem( SplitedAmount ); + if( !pNewItem ) + { + pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemSrc, NULL ); + return; + } + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst); + + pl->ItemRemovedQuestCheck( pItemSrc->GetEntry(), SplitedAmount ); + pItemSrc->SetCount( pItemSrc->GetCount() - SplitedAmount ); + pItemSrc->FSetState(ITEM_CHANGED); + pItemSrc->SaveToDB(); // not in inventory and can be save standalone + pGuild->StoreItem(BankTabDst,dest,pNewItem); + CharacterDatabase.CommitTransaction(); + } + else // non split + { + GuildItemPosCountVec gDest; + uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,false); + if( msg == EQUIP_ERR_OK ) // merge to + { + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst); + + pGuild->RemoveItem(BankTab, BankTabSlot); + pGuild->StoreItem(BankTabDst, gDest, pItemSrc); + CharacterDatabase.CommitTransaction(); + } + else // swap + { + gDest.clear(); + uint8 msg = pGuild->CanStoreItem(BankTabDst,BankTabSlotDst,gDest,pItemSrc->GetCount(),pItemSrc,true); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemSrc, NULL ); + return; + } + + GuildItemPosCountVec gSrc; + msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gSrc,pItemDst->GetCount(),pItemDst,true); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemDst, NULL ); + return; + } + + if(BankTab!=BankTabDst) + { + // check source pos rights (item swapped to src) + if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM)) + return; + + // check dest pos rights (item swapped to src) + uint32 remRightDst = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTabDst); + if(remRightDst <= 0) + return; + } + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst); + pGuild->LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab); + + pGuild->RemoveItem(BankTab, BankTabSlot); + pGuild->RemoveItem(BankTabDst, BankTabSlotDst); + pGuild->StoreItem(BankTab, gSrc, pItemDst); + pGuild->StoreItem(BankTabDst, gDest, pItemSrc); + CharacterDatabase.CommitTransaction(); + } + } + pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab==BankTabDst ? BankTabSlotDst : -1); + if(BankTab!=BankTabDst) + pGuild->DisplayGuildBankContentUpdate(BankTabDst,BankTabSlotDst); + return; + } + + // Player <-> Bank + + // char->bank autostore click return BankTabSlot = 255 = NULL_SLOT + // do similar for bank->char + if(AutoStore && ToChar) + { + PlayerBag = NULL_BAG; + PlayerSlot = NULL_SLOT; + } + + // allow work with inventory only + if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) ) + { + _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL ); + return; + } + + Item *pItemBank = pGuild->GetItem(BankTab, BankTabSlot); + Item *pItemChar = GetPlayer()->GetItemByPos(PlayerBag, PlayerSlot); + if (!pItemChar && !pItemBank) // Nothing to do + return; + + if (!pItemChar && !ToChar) // Problem to get item from player + return; + + if (!pItemBank && ToChar) // Problem to get bank item + return; + + // BankToChar swap or char to bank remaining + + if (ToChar) // Bank -> Char cases + { + if(SplitedAmount > pItemBank->GetCount()) + return; // cheating? + else if(SplitedAmount == pItemBank->GetCount()) + SplitedAmount = 0; // no split + + if (SplitedAmount) + { // Bank -> Char split to slot (patly move) + Item *pNewItem = pItemBank->CloneItem( SplitedAmount ); + if( !pNewItem ) + { + pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemBank, NULL ); + return; + } + + ItemPosCountVec dest; + uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pNewItem, false); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pNewItem, NULL ); + delete pNewItem; + return; + } + + // check source pos rights (item moved to inventory) + uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab); + if(remRight <= 0) + { + delete pNewItem; + return; + } + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount); + + pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount); + pItemBank->FSetState(ITEM_CHANGED); + pItemBank->SaveToDB(); // not in inventory and can be save standalone + pl->MoveItemToInventory(dest,pNewItem,true); + pl->SaveInventoryAndGoldToDB(); + + pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow()); + CharacterDatabase.CommitTransaction(); + } + else // Bank -> Char swap with slot (move) + { + ItemPosCountVec dest; + uint8 msg = pl->CanStoreItem(PlayerBag, PlayerSlot, dest, pItemBank, false); + if( msg == EQUIP_ERR_OK ) // merge case + { + // check source pos rights (item moved to inventory) + uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab); + if(remRight <= 0) + return; + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount()); + + pGuild->RemoveItem(BankTab, BankTabSlot); + pl->MoveItemToInventory(dest,pItemBank,true); + pl->SaveInventoryAndGoldToDB(); + + pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow()); + CharacterDatabase.CommitTransaction(); + } + else // Bank <-> Char swap items + { + // check source pos rights (item swapped to bank) + if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM)) + return; + + if(pItemChar) + { + if(!pItemChar->CanBeTraded()) + { + _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL ); + return; + } + } + + ItemPosCountVec iDest; + msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemBank, NULL ); + return; + } + + GuildItemPosCountVec gDest; + if(pItemChar) + { + msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemChar, NULL ); + return; + } + } + + // check source pos rights (item moved to inventory) + uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab); + if(remRight <= 0) + return; + + if(pItemChar) + { + // logging item move to bank + if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )", + _player->GetName(),_player->GetSession()->GetAccountId(), + pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(), + GuildId); + } + } + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount()); + if(pItemChar) + pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount()); + + pGuild->RemoveItem(BankTab, BankTabSlot); + if(pItemChar) + { + pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true); + pItemChar->DeleteFromInventoryDB(); + } + + if(pItemChar) + pGuild->StoreItem(BankTab, gDest, pItemChar); + pl->MoveItemToInventory(iDest,pItemBank,true); + pl->SaveInventoryAndGoldToDB(); + + pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow()); + CharacterDatabase.CommitTransaction(); + } + } + pGuild->DisplayGuildBankContentUpdate(BankTab,BankTabSlot); + return; + } // End "To char" part + + // Char -> Bank cases + + if(!pItemChar->CanBeTraded()) + { + _player->SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL ); + return; + } + + // check source pos rights (item moved to bank) + if(!pGuild->IsMemberHaveRights(pl->GetGUIDLow(), BankTab, GUILD_BANK_RIGHT_DEPOSIT_ITEM)) + return; + + if(SplitedAmount > pItemChar->GetCount()) + return; // cheating? + else if(SplitedAmount == pItemChar->GetCount()) + SplitedAmount = 0; // no split + + if (SplitedAmount) + { // Char -> Bank split to empty or non-empty slot (partly move) + GuildItemPosCountVec dest; + uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,SplitedAmount,pItemChar,false); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemChar, NULL ); + return; + } + + Item *pNewItem = pItemChar->CloneItem( SplitedAmount ); + if( !pNewItem ) + { + pl->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pItemChar, NULL ); + return; + } + + // logging item move to bank (before items merge + if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )", + _player->GetName(),_player->GetSession()->GetAccountId(), + pItemChar->GetProto()->Name1,pItemChar->GetEntry(),SplitedAmount,GuildId); + } + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount); + + pl->ItemRemovedQuestCheck( pItemChar->GetEntry(), SplitedAmount ); + pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount); + pItemChar->SetState(ITEM_CHANGED); + pl->SaveInventoryAndGoldToDB(); + pGuild->StoreItem(BankTab, dest, pNewItem); + CharacterDatabase.CommitTransaction(); + + pGuild->DisplayGuildBankContentUpdate(BankTab,dest); + } + else // Char -> Bank swap with empty or non-empty (move) + { + GuildItemPosCountVec dest; + uint8 msg = pGuild->CanStoreItem(BankTab,BankTabSlot,dest,pItemChar->GetCount(),pItemChar,false); + if( msg == EQUIP_ERR_OK ) // merge + { + // logging item move to bank + if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )", + _player->GetName(),_player->GetSession()->GetAccountId(), + pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(), + GuildId); + } + + CharacterDatabase.BeginTransaction(); + pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount()); + + pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true); + pItemChar->DeleteFromInventoryDB(); + + pGuild->StoreItem(BankTab,dest,pItemChar); + pl->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); + + pGuild->DisplayGuildBankContentUpdate(BankTab,dest); + } + else // Char <-> Bank swap items (posible NULL bank item) + { + ItemPosCountVec iDest; + if(pItemBank) + { + msg = pl->CanStoreItem(PlayerBag, PlayerSlot, iDest, pItemBank, true); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemBank, NULL ); + return; + } + } + + GuildItemPosCountVec gDest; + msg = pGuild->CanStoreItem(BankTab,BankTabSlot,gDest,pItemChar->GetCount(),pItemChar,true); + if( msg != EQUIP_ERR_OK ) + { + pl->SendEquipError( msg, pItemChar, NULL ); + return; + } + + if(pItemBank) + { + // check bank pos rights (item swapped with inventory) + uint32 remRight = pGuild->GetMemberSlotWithdrawRem(pl->GetGUIDLow(), BankTab); + if(remRight <= 0) + return; + } + + // logging item move to bank + if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand("GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )", + _player->GetName(),_player->GetSession()->GetAccountId(), + pItemChar->GetProto()->Name1,pItemChar->GetEntry(),pItemChar->GetCount(), + GuildId); + } + + CharacterDatabase.BeginTransaction(); + if(pItemBank) + pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount()); + pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount()); + + pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true); + pItemChar->DeleteFromInventoryDB(); + if(pItemBank) + pGuild->RemoveItem(BankTab, BankTabSlot); + + pGuild->StoreItem(BankTab,gDest,pItemChar); + if(pItemBank) + pl->MoveItemToInventory(iDest,pItemBank,true); + pl->SaveInventoryAndGoldToDB(); + if(pItemBank) + pGuild->MemberItemWithdraw(BankTab, pl->GetGUIDLow()); + CharacterDatabase.CommitTransaction(); + + pGuild->DisplayGuildBankContentUpdate(BankTab,gDest); + } + } +} + +void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)"); + CHECK_PACKET_SIZE(recv_data, 8+1); + //recv_data.hexlike(); + uint64 GoGuid; + uint8 TabId; + + recv_data >> GoGuid; + recv_data >> TabId; + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId==0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint32 TabCost = objmgr.GetGuildBankTabPrice(TabId) * GOLD; + if (!TabCost) + return; + + if (pGuild->GetPurchasedTabs() >= GUILD_BANK_MAX_TABS) + return; + + if (TabId != pGuild->GetPurchasedTabs()) // purchased_tabs = 0 when buying Tab 0, that is why this check can be made + { + sLog.outError("Error: trying to buy a tab non contigous to owned ones"); + return; + } + + if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client + return; + + // Go on with creating tab + pGuild->CreateNewBankTab(); + GetPlayer()->ModifyMoney(-int(TabCost)); + pGuild->SetBankMoneyPerDay(GetPlayer()->GetRank(), WITHDRAW_MONEY_UNLIMITED); + pGuild->SetBankRightsAndSlots(GetPlayer()->GetRank(), TabId, GUILD_BANK_RIGHT_FULL, WITHDRAW_SLOT_UNLIMITED, true); + pGuild->Roster(this); + pGuild->DisplayGuildBankTabsInfo(this); +} + +void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)"); + //recv_data.hexlike(); + CHECK_PACKET_SIZE(recv_data, 8+1+1+1); + uint64 GoGuid; + uint8 TabId; + std::string Name; + std::string IconIndex; + + recv_data >> GoGuid; + recv_data >> TabId; + recv_data >> Name; + recv_data >> IconIndex; + + if(Name.empty()) + return; + + if(IconIndex.empty()) + return; + + if (!objmgr.IsGuildVaultGameObject(_player, GoGuid)) + return; + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId==0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex); + pGuild->DisplayGuildBankTabsInfo(this); + pGuild->DisplayGuildBankContent(this, TabId); +} + +void WorldSession::HandleGuildBankLog( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)"); + CHECK_PACKET_SIZE(recv_data, 1); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint8 TabId; + recv_data >> TabId; + + pGuild->DisplayGuildBankLogs(this, TabId); +} + +void WorldSession::HandleGuildBankTabText(WorldPacket &recv_data) +{ + sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT"); + CHECK_PACKET_SIZE(recv_data, 1); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint8 TabId; + recv_data >> TabId; + + pGuild->SendGuildBankTabText(this, TabId); +} + +void WorldSession::HandleGuildBankSetTabText(WorldPacket &recv_data) +{ + sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT"); + CHECK_PACKET_SIZE(recv_data, 1+1); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint8 TabId; + std::string Text; + recv_data >> TabId; + recv_data >> Text; + + pGuild->SetGuildBankTabText(TabId, Text); +} + +void WorldSession::SendSaveGuildEmblem( uint32 msg ) +{ + WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4); + data << uint32(msg); // not part of guild + SendPacket( &data ); +} diff --git a/src/game/HateMatrix.h b/src/game/HateMatrix.h new file mode 100644 index 000000000..ab03e34c8 --- /dev/null +++ b/src/game/HateMatrix.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_HATEMATRIX_H +#define MANGOS_HATEMATRIX_H + +#include "Utilities/HashMap.h" +#include + +class Unit; + +struct MANGOS_DLL_DECL HateMatrix +{ + typedef hash_map HateMatrixMapType; + + inline uint32 operator[](Unit *unit) const + { + HateMatrixMapType::const_iterator iter = i_hateValues.find(unit); + return (iter == i_hateValues.end() ? 0 : iter->second); + } + + inline uint32& operator[](Unit *unit) + { + HateMatrixMapType::iterator iter = i_hateValues.find(unit); + if( iter == i_hateValues.end() ) + { + std::pair p = i_hateValues.insert( HateMatrixMapType::value_type(unit, 0) ); + assert(p.second); + iter = p.first; + } + + return iter->second; + } + + inline void ClearMatrix(void) { i_hateValues.clear(); } + + inline void RemoveValue(Unit *unit) + { + HateMatrixMapType::iterator iter = i_hateValues.find(unit); + if( iter != i_hateValues.end() ) + i_hateValues.erase( iter ); + } + + inline void AddValue(Unit *unit, uint32 val) + { + (*this)[unit] += val; + } + + private: + HateMatrixMapType i_hateValues; +}; + +struct HateBinder +{ + static uint32 si_noHateValue; + uint32 &i_hateValue; + Unit *i_unit; + HateBinder(uint32 &val, Unit *u) : i_hateValue(val), i_unit(u) {} + HateBinder() : i_hateValue(si_noHateValue), i_unit(NULL) {} + HateBinder(const HateBinder &obj) : i_hateValue(obj.i_hateValue), i_unit(obj.i_unit) {} + + HateBinder& operator=(const HateBinder &obj) + { + i_hateValue = obj.i_hateValue; + i_unit = obj.i_unit; + return *this; + } +}; +#endif diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp new file mode 100644 index 000000000..7b166e8ec --- /dev/null +++ b/src/game/HomeMovementGenerator.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "HomeMovementGenerator.h" +#include "Creature.h" +#include "Traveller.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "DestinationHolderImp.h" +#include "ObjectMgr.h" +#include "WorldPacket.h" + +void +HomeMovementGenerator::Initialize(Creature & owner) +{ + owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + _setTargetLocation(owner); +} + +void +HomeMovementGenerator::Reset(Creature &) +{ +} + +void +HomeMovementGenerator::_setTargetLocation(Creature & owner) +{ + if( !&owner ) + return; + + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) ) + return; + + float x, y, z; + owner.GetRespawnCoord(x, y, z); + + CreatureTraveller traveller(owner); + + uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z); + modifyTravelTime(travel_time); + owner.clearUnitState(UNIT_STAT_ALL_STATE); +} + +bool +HomeMovementGenerator::Update(Creature &owner, const uint32& time_diff) +{ + CreatureTraveller traveller( owner); + i_destinationHolder.UpdateTraveller(traveller, time_diff, false); + + if (time_diff > i_travel_timer) + { + owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + + // restore orientation of not moving creature at returning to home + if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE) + { + if(CreatureData const* data = objmgr.GetCreatureData(owner.GetDBTableGUIDLow())) + { + owner.SetOrientation(data->orientation); + WorldPacket packet; + owner.BuildHeartBeatMsg(&packet); + owner.SendMessageToSet(&packet, false); + } + } + return false; + } + + i_travel_timer -= time_diff; + + return true; +} diff --git a/src/game/HomeMovementGenerator.h b/src/game/HomeMovementGenerator.h new file mode 100644 index 000000000..7ce0678ec --- /dev/null +++ b/src/game/HomeMovementGenerator.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_HOMEMOVEMENTGENERATOR_H +#define MANGOS_HOMEMOVEMENTGENERATOR_H + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "Traveller.h" + +class Creature; + +template < class T > +class MANGOS_DLL_SPEC HomeMovementGenerator; + +template <> +class MANGOS_DLL_SPEC HomeMovementGenerator +: public MovementGeneratorMedium< Creature, HomeMovementGenerator > +{ + public: + + HomeMovementGenerator() {} + ~HomeMovementGenerator() {} + + void Initialize(Creature &); + void Finalize(Creature &) {} + void Reset(Creature &); + bool Update(Creature &, const uint32 &); + void modifyTravelTime(uint32 travel_time) { i_travel_timer = travel_time; } + MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; } + + bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; } + private: + void _setTargetLocation(Creature &); + DestinationHolder< Traveller > i_destinationHolder; + + uint32 i_travel_timer; +}; +#endif diff --git a/src/game/HostilRefManager.cpp b/src/game/HostilRefManager.cpp new file mode 100644 index 000000000..e0cc01280 --- /dev/null +++ b/src/game/HostilRefManager.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "HostilRefManager.h" +#include "ThreatManager.h" +#include "Unit.h" +#include "Database/DBCStructure.h" +#include "SpellMgr.h" + +HostilRefManager::~HostilRefManager() +{ + deleteReferences(); +} + +//================================================= +// send threat to all my hateres for the pVictim +// The pVictim is hated than by them as well +// use for buffs and healing threat functionality + +void HostilRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry const *pThreatSpell, bool pSingleTarget) +{ + HostilReference* ref; + + uint32 size = pSingleTarget ? 1 : getSize(); // if pSingleTarget do not devide threat + ref = getFirst(); + while(ref != NULL) + { + float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, (pThreatSpell ? GetSpellSchoolMask(pThreatSpell) : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell); + if(pVictim == getOwner()) + ref->addThreat(float (threat) / size); // It is faster to modify the threat durectly if possible + else + ref->getSource()->addThreat(pVictim, float (threat) / size); + ref = ref->next(); + } +} + +//================================================= + +void HostilRefManager::addThreatPercent(int32 pValue) +{ + HostilReference* ref; + + ref = getFirst(); + while(ref != NULL) + { + ref->addThreatPercent(pValue); + ref = ref->next(); + } +} + +//================================================= +// The online / offline status is given to the method. The calculation has to be done before + +void HostilRefManager::setOnlineOfflineState(bool pIsOnline) +{ + HostilReference* ref; + + ref = getFirst(); + while(ref != NULL) + { + ref->setOnlineOfflineState(pIsOnline); + ref = ref->next(); + } +} + +//================================================= +// The online / offline status is calculated and set + +void HostilRefManager::updateThreatTables() +{ + HostilReference* ref = getFirst(); + while(ref) + { + ref->updateOnlineStatus(); + ref = ref->next(); + } +} + +//================================================= +// The references are not needed anymore +// tell the source to remove them from the list and free the mem + +void HostilRefManager::deleteReferences() +{ + HostilReference* ref = getFirst(); + while(ref) + { + HostilReference* nextRef = ref->next(); + ref->removeReference(); + delete ref; + ref = nextRef; + } +} + +//================================================= +// delete one reference, defined by Unit + +void HostilRefManager::deleteReference(Unit *pCreature) +{ + HostilReference* ref = getFirst(); + while(ref) + { + HostilReference* nextRef = ref->next(); + if(ref->getSource()->getOwner() == pCreature) + { + ref->removeReference(); + delete ref; + break; + } + ref = nextRef; + } +} + +//================================================= +// set state for one reference, defined by Unit + +void HostilRefManager::setOnlineOfflineState(Unit *pCreature,bool pIsOnline) +{ + HostilReference* ref = getFirst(); + while(ref) + { + HostilReference* nextRef = ref->next(); + if(ref->getSource()->getOwner() == pCreature) + { + ref->setOnlineOfflineState(pIsOnline); + break; + } + ref = nextRef; + } +} + +//================================================= diff --git a/src/game/HostilRefManager.h b/src/game/HostilRefManager.h new file mode 100644 index 000000000..576597a52 --- /dev/null +++ b/src/game/HostilRefManager.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _HOSTILEREFMANAGER +#define _HOSTILEREFMANAGER + +#include "Common.h" +#include "Utilities/LinkedReference/RefManager.h" + +class Unit; +class ThreatManager; +class HostilReference; +struct SpellEntry; + +//================================================= + +class HostilRefManager : public RefManager +{ + private: + Unit *iOwner; + public: + explicit HostilRefManager(Unit *pOwner) { iOwner = pOwner; } + ~HostilRefManager(); + + Unit* getOwner() { return iOwner; } + + // send threat to all my hateres for the pVictim + // The pVictim is hated than by them as well + // use for buffs and healing threat functionality + void threatAssist(Unit *pVictim, float threat, SpellEntry const *threatSpell = 0, bool pSingleTarget=false); + + void addThreatPercent(int32 pValue); + + // The references are not needed anymore + // tell the source to remove them from the list and free the mem + void deleteReferences(); + + HostilReference* getFirst() { return ((HostilReference* ) RefManager::getFirst()); } + + void updateThreatTables(); + + void setOnlineOfflineState(bool pIsOnline); + + // set state for one reference, defined by Unit + void setOnlineOfflineState(Unit *pCreature,bool pIsOnline); + + // delete one reference, defined by Unit + void deleteReference(Unit *pCreature); +}; +//================================================= +#endif diff --git a/src/game/IdleMovementGenerator.cpp b/src/game/IdleMovementGenerator.cpp new file mode 100644 index 000000000..dd1c4d0bf --- /dev/null +++ b/src/game/IdleMovementGenerator.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "IdleMovementGenerator.h" +#include "Creature.h" + +IdleMovementGenerator si_idleMovement; + +void +IdleMovementGenerator::Reset(Unit& /*owner*/) +{ +} + +void +DistractMovementGenerator::Initialize(Unit& owner) +{ + owner.addUnitState(UNIT_STAT_DISTRACTED); +} + +void +DistractMovementGenerator::Finalize(Unit& owner) +{ + owner.clearUnitState(UNIT_STAT_DISTRACTED); +} + +bool +DistractMovementGenerator::Update(Unit& owner, const uint32& time_diff) +{ + if(time_diff > m_timer) + return false; + + m_timer -= time_diff; + return true; +} diff --git a/src/game/IdleMovementGenerator.h b/src/game/IdleMovementGenerator.h new file mode 100644 index 000000000..c74774562 --- /dev/null +++ b/src/game/IdleMovementGenerator.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_IDLEMOVEMENTGENERATOR_H +#define MANGOS_IDLEMOVEMENTGENERATOR_H + +#include "MovementGenerator.h" + +class MANGOS_DLL_SPEC IdleMovementGenerator : public MovementGenerator +{ + public: + + void Initialize(Unit &) { } + void Finalize(Unit &) { } + void Reset(Unit &); + bool Update(Unit &, const uint32 &) { return true; } + MovementGeneratorType GetMovementGeneratorType() { return IDLE_MOTION_TYPE; } +}; + +extern IdleMovementGenerator si_idleMovement; + +class MANGOS_DLL_SPEC DistractMovementGenerator : public MovementGenerator +{ + public: + explicit DistractMovementGenerator(uint32 timer) : m_timer(timer) {} + + void Initialize(Unit& owner); + void Finalize(Unit& owner); + void Reset(Unit& owner) { Initialize(owner); } + bool Update(Unit& owner, const uint32& time_diff); + MovementGeneratorType GetMovementGeneratorType() { return DISTRACT_MOTION_TYPE; } + + private: + uint32 m_timer; +}; + +#endif diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp new file mode 100644 index 000000000..b90c9b656 --- /dev/null +++ b/src/game/InstanceData.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "InstanceData.h" +#include "Database/DatabaseEnv.h" +#include "Map.h" + +void InstanceData::SaveToDB() +{ + if(!Save()) return; + std::string data = Save(); + CharacterDatabase.escape_string(data); + CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId()); +} diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h new file mode 100644 index 000000000..a610b8036 --- /dev/null +++ b/src/game/InstanceData.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_INSTANCE_DATA_H +#define MANGOS_INSTANCE_DATA_H + +#include "Common.h" + +class Map; +class Unit; +class Player; +class GameObject; +class Creature; + +class MANGOS_DLL_SPEC InstanceData +{ + public: + + explicit InstanceData(Map *map) : instance(map) {} + virtual ~InstanceData() {} + + Map *instance; + + //On creation, NOT load. + virtual void Initialize() {} + + //On load + virtual void Load(const char* /*data*/) {} + + //When save is needed, this function generates the data + virtual const char* Save() { return ""; } + + void SaveToDB(); + + //Called every map update + virtual void Update(uint32 /*diff*/) {} + + //Used by the map's CanEnter function. + //This is to prevent players from entering during boss encounters. + virtual bool IsEncounterInProgress() const { return false; }; + + //Called when a player successfully enters the instance. + virtual void OnPlayerEnter(Player *) {} + + //Called when a gameobject is created + virtual void OnObjectCreate(GameObject *) {} + + //called on creature creation + virtual void OnCreatureCreate(Creature * /*creature*/, uint32 /*creature_entry*/) {} +}; +#endif diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp new file mode 100644 index 000000000..21aff8093 --- /dev/null +++ b/src/game/InstanceSaveMgr.cpp @@ -0,0 +1,649 @@ +/* + * Copyright (C) 2005,2006,2007 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "InstanceSaveMgr.h" +#include "Common.h" +#include "Database/SQLStorage.h" + +#include "Player.h" +#include "GridNotifiers.h" +#include "WorldSession.h" +#include "Log.h" +#include "GridStates.h" +#include "CellImpl.h" +#include "Map.h" +#include "MapManager.h" +#include "MapInstanced.h" +#include "InstanceSaveMgr.h" +#include "Timer.h" +#include "GridNotifiersImpl.h" +#include "Config/ConfigEnv.h" +#include "Transports.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "World.h" +#include "Group.h" +#include "InstanceData.h" +#include "ProgressBar.h" + +INSTANTIATE_SINGLETON_1( InstanceSaveManager ); + +InstanceSaveManager::InstanceSaveManager() : lock_instLists(false) +{ +} + +InstanceSaveManager::~InstanceSaveManager() +{ + // it is undefined whether this or objectmgr will be unloaded first + // so we must be prepared for both cases + lock_instLists = true; + for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) + { + InstanceSave *save = itr->second; + for(InstanceSave::PlayerListType::iterator itr = save->m_playerList.begin(), next = itr; itr != save->m_playerList.end(); itr = next) + { + ++next; + (*itr)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true); + } + save->m_playerList.clear(); + for(InstanceSave::GroupListType::iterator itr = save->m_groupList.begin(), next = itr; itr != save->m_groupList.end(); itr = next) + { + ++next; + (*itr)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true); + } + save->m_groupList.clear(); + delete save; + } +} + +/* +- adding instance into manager +- called from InstanceMap::Add, _LoadBoundInstances, LoadGroups +*/ +InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load) +{ + InstanceSave *save = GetInstanceSave(instanceId); + if(save) return save; + + const MapEntry* entry = sMapStore.LookupEntry(mapId); + if(!entry || instanceId == 0) + { + sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d!", mapId, instanceId); + return NULL; + } + + if(!resetTime) + { + // initialize reset time + // for normal instances if no creatures are killed the instance will reset in two hours + if(entry->map_type == MAP_RAID || difficulty == DIFFICULTY_HEROIC) + resetTime = GetResetTimeFor(mapId); + else + { + resetTime = time(NULL) + 2 * HOUR; + // normally this will be removed soon after in InstanceMap::Add, prevent error + ScheduleReset(true, resetTime, InstResetEvent(0, mapId, instanceId)); + } + } + + sLog.outDebug("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d", mapId, instanceId); + + save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset); + if(!load) save->SaveToDB(); + + m_instanceSaveById[instanceId] = save; + return save; +} + +InstanceSave *InstanceSaveManager::GetInstanceSave(uint32 InstanceId) +{ + InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(InstanceId); + return itr != m_instanceSaveById.end() ? itr->second : NULL; +} + +void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid) +{ + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'", instanceid); + CharacterDatabase.PExecute("DELETE FROM character_instance WHERE instance = '%u'", instanceid); + CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", instanceid); + CharacterDatabase.CommitTransaction(); + // respawn times should be deleted only when the map gets unloaded +} + +void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) +{ + InstanceSaveHashMap::iterator itr = m_instanceSaveById.find( InstanceId ); + if(itr != m_instanceSaveById.end()) + { + // save the resettime for normal instances only when they get unloaded + if(time_t resettime = itr->second->GetResetTimeForDB()) + CharacterDatabase.PExecute("UPDATE instance SET resettime = '"I64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId); + delete itr->second; + m_instanceSaveById.erase(itr); + } +} + +InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, + time_t resetTime, bool canReset) +: m_mapid(MapId), m_instanceid(InstanceId), m_resetTime(resetTime), + m_difficulty(difficulty), m_canReset(canReset) +{ +} + +InstanceSave::~InstanceSave() +{ + // the players and groups must be unbound before deleting the save + assert(m_playerList.empty() && m_groupList.empty()); +} + +/* + Called from AddInstanceSave +*/ +void InstanceSave::SaveToDB() +{ + // save instance data too + std::string data; + + Map *map = MapManager::Instance().FindMap(m_instanceid, GetMapId()); + if(map) + { + assert(map->IsDungeon()); + InstanceData *iData = ((InstanceMap *)map)->GetInstanceData(); + if(iData && iData->Save()) + { + data = iData->Save(); + CharacterDatabase.escape_string(data); + } + } + + CharacterDatabase.PExecute("INSERT INTO instance VALUES ('%u', '%u', '"I64FMTD"', '%u', '%s')", m_instanceid, GetMapId(), (uint64)GetResetTimeForDB(), GetDifficulty(), data.c_str()); +} + +time_t InstanceSave::GetResetTimeForDB() +{ + // only save the reset time for normal instances + const MapEntry *entry = sMapStore.LookupEntry(GetMapId()); + if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DIFFICULTY_HEROIC) + return 0; + else + return GetResetTime(); +} + +// to cache or not to cache, that is the question +InstanceTemplate const* InstanceSave::GetTemplate() +{ + return objmgr.GetInstanceTemplate(m_mapid); +} + +MapEntry const* InstanceSave::GetMapEntry() +{ + return sMapStore.LookupEntry(m_mapid); +} + +void InstanceSave::DeleteFromDB() +{ + InstanceSaveManager::DeleteInstanceFromDB(GetInstanceId()); +} + +/* true if the instance save is still valid */ +bool InstanceSave::UnloadIfEmpty() +{ + if(m_playerList.empty() && m_groupList.empty()) + { + if(!sInstanceSaveManager.lock_instLists) + sInstanceSaveManager.RemoveInstanceSave(GetInstanceId()); + return false; + } + else + return true; +} + +void InstanceSaveManager::_DelHelper(DatabaseType &db, const char *fields, const char *table, const char *queryTail,...) +{ + Tokens fieldTokens = StrSplit(fields, ", "); + assert(fieldTokens.size() != 0); + + va_list ap; + char szQueryTail [MAX_QUERY_LEN]; + va_start(ap, queryTail); + int res = vsnprintf( szQueryTail, MAX_QUERY_LEN, queryTail, ap ); + va_end(ap); + + QueryResult *result = db.PQuery("SELECT %s FROM %s %s", fields, table, szQueryTail); + if(result) + { + do + { + Field *fields = result->Fetch(); + std::ostringstream ss; + for(size_t i = 0; i < fieldTokens.size(); i++) + { + std::string fieldValue = fields[i].GetCppString(); + db.escape_string(fieldValue); + ss << (i != 0 ? " AND " : "") << fieldTokens[i] << " = '" << fieldValue << "'"; + } + db.DirectPExecute("DELETE FROM %s WHERE %s", table, ss.str().c_str()); + } while (result->NextRow()); + delete result; + } +} + +void InstanceSaveManager::CleanupInstances() +{ + uint64 now = (uint64)time(NULL); + + barGoLink bar(2); + bar.step(); + + // load reset times and clean expired instances + sInstanceSaveManager.LoadResetTimes(); + + // clean character/group - instance binds with invalid group/characters + _DelHelper(CharacterDatabase, "character_instance.guid, instance", "character_instance", "LEFT JOIN characters ON character_instance.guid = characters.guid WHERE characters.guid IS NULL"); + _DelHelper(CharacterDatabase, "group_instance.leaderGuid, instance", "group_instance", "LEFT JOIN characters ON group_instance.leaderGuid = characters.guid LEFT JOIN groups ON group_instance.leaderGuid = groups.leaderGuid WHERE characters.guid IS NULL OR groups.leaderGuid IS NULL"); + + // clean instances that do not have any players or groups bound to them + _DelHelper(CharacterDatabase, "id, map, difficulty", "instance", "LEFT JOIN character_instance ON character_instance.instance = id LEFT JOIN group_instance ON group_instance.instance = id WHERE character_instance.instance IS NULL AND group_instance.instance IS NULL"); + + // clean invalid instance references in other tables + _DelHelper(CharacterDatabase, "character_instance.guid, instance", "character_instance", "LEFT JOIN instance ON character_instance.instance = instance.id WHERE instance.id IS NULL"); + _DelHelper(CharacterDatabase, "group_instance.leaderGuid, instance", "group_instance", "LEFT JOIN instance ON group_instance.instance = instance.id WHERE instance.id IS NULL"); + + // creature_respawn and gameobject_respawn are in another database + // first, obtain total instance set + std::set< uint32 > InstanceSet; + QueryResult *result = CharacterDatabase.PQuery("SELECT id FROM instance"); + if( result ) + { + do + { + Field *fields = result->Fetch(); + InstanceSet.insert(fields[0].GetUInt32()); + } + while (result->NextRow()); + delete result; + } + + // creature_respawn + result = WorldDatabase.PQuery("SELECT DISTINCT(instance) FROM creature_respawn WHERE instance <> 0"); + if( result ) + { + do + { + Field *fields = result->Fetch(); + if(InstanceSet.find(fields[0].GetUInt32()) == InstanceSet.end()) + WorldDatabase.DirectPExecute("DELETE FROM creature_respawn WHERE instance = '%u'", fields[0].GetUInt32()); + } + while (result->NextRow()); + delete result; + } + + // gameobject_respawn + result = WorldDatabase.PQuery("SELECT DISTINCT(instance) FROM gameobject_respawn WHERE instance <> 0"); + if( result ) + { + do + { + Field *fields = result->Fetch(); + if(InstanceSet.find(fields[0].GetUInt32()) == InstanceSet.end()) + WorldDatabase.DirectPExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", fields[0].GetUInt32()); + } + while (result->NextRow()); + delete result; + } + + bar.step(); + sLog.outString(); + sLog.outString( ">> Initialized %u instances", (uint32)InstanceSet.size()); +} + +void InstanceSaveManager::PackInstances() +{ + // this routine renumbers player instance associations in such a way so they start from 1 and go up + // TODO: this can be done a LOT more efficiently + + // obtain set of all associations + std::set< uint32 > InstanceSet; + + // all valid ids are in the instance table + // any associations to ids not in this table are assumed to be + // cleaned already in CleanupInstances + QueryResult *result = CharacterDatabase.PQuery("SELECT id FROM instance"); + if( result ) + { + do + { + Field *fields = result->Fetch(); + InstanceSet.insert(fields[0].GetUInt32()); + } + while (result->NextRow()); + delete result; + } + + barGoLink bar( InstanceSet.size() + 1); + bar.step(); + + uint32 InstanceNumber = 1; + // we do assume std::set is sorted properly on integer value + for (std::set< uint32 >::iterator i = InstanceSet.begin(); i != InstanceSet.end(); i++) + { + if (*i != InstanceNumber) + { + // remap instance id + WorldDatabase.PExecute("UPDATE creature_respawn SET instance = '%u' WHERE instance = '%u'", InstanceNumber, *i); + WorldDatabase.PExecute("UPDATE gameobject_respawn SET instance = '%u' WHERE instance = '%u'", InstanceNumber, *i); + CharacterDatabase.PExecute("UPDATE corpse SET instance = '%u' WHERE instance = '%u'", InstanceNumber, *i); + CharacterDatabase.PExecute("UPDATE character_instance SET instance = '%u' WHERE instance = '%u'", InstanceNumber, *i); + CharacterDatabase.PExecute("UPDATE instance SET id = '%u' WHERE id = '%u'", InstanceNumber, *i); + CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u' WHERE instance = '%u'", InstanceNumber, *i); + } + + ++InstanceNumber; + bar.step(); + } + + sLog.outString(); + sLog.outString( ">> Instance numbers remapped, next instance id is %u", InstanceNumber ); +} + +void InstanceSaveManager::LoadResetTimes() +{ + time_t now = time(NULL); + time_t today = (now / DAY) * DAY; + + // NOTE: Use DirectPExecute for tables that will be queried later + + // get the current reset times for normal instances (these may need to be updated) + // these are only kept in memory for InstanceSaves that are loaded later + // resettime = 0 in the DB for raid/heroic instances so those are skipped + typedef std::map > ResetTimeMapType; + ResetTimeMapType InstResetTime; + QueryResult *result = CharacterDatabase.PQuery("SELECT id, map, resettime FROM instance WHERE resettime > 0"); + if( result ) + { + do + { + if(uint64 resettime = (*result)[2].GetUInt64()) + { + uint32 id = (*result)[0].GetUInt32(); + uint32 mapid = (*result)[1].GetUInt32(); + InstResetTime[id] = std::pair(mapid, resettime); + } + } + while (result->NextRow()); + delete result; + + // update reset time for normal instances with the max creature respawn time + X hours + result = WorldDatabase.PQuery("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); + if( result ) + { + do + { + Field *fields = result->Fetch(); + uint32 instance = fields[1].GetUInt32(); + uint64 resettime = fields[0].GetUInt64() + 2 * HOUR; + ResetTimeMapType::iterator itr = InstResetTime.find(instance); + if(itr != InstResetTime.end() && itr->second.second != resettime) + { + CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"I64FMTD"' WHERE id = '%u'", resettime, instance); + itr->second.second = resettime; + } + } + while (result->NextRow()); + delete result; + } + + // schedule the reset times + for(ResetTimeMapType::iterator itr = InstResetTime.begin(); itr != InstResetTime.end(); ++itr) + if(itr->second.second > now) + ScheduleReset(true, itr->second.second, InstResetEvent(0, itr->second.first, itr->first)); + } + + // load the global respawn times for raid/heroic instances + uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; + m_resetTimeByMapId.resize(sMapStore.GetNumRows()+1); + result = CharacterDatabase.Query("SELECT mapid, resettime FROM instance_reset"); + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 mapid = fields[0].GetUInt32(); + if(!objmgr.GetInstanceTemplate(mapid)) + { + sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid %u in instance_reset!", mapid); + CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u'", mapid); + continue; + } + + // update the reset time if the hour in the configs changes + uint64 oldresettime = fields[1].GetUInt64(); + uint64 newresettime = (oldresettime / DAY) * DAY + diff; + if(oldresettime != newresettime) + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"I64FMTD"' WHERE mapid = '%u'", newresettime, mapid); + + m_resetTimeByMapId[mapid] = newresettime; + } while(result->NextRow()); + delete result; + } + + // clean expired instances, references to them will be deleted in CleanupInstances + // must be done before calculating new reset times + _DelHelper(CharacterDatabase, "id, map, difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map WHERE (instance.resettime < '"I64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"I64FMTD"')", (uint64)now, (uint64)now); + + // calculate new global reset times for expired instances and those that have never been reset yet + // add the global reset times to the priority queue + for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) + { + InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(i); + if(!temp) continue; + // only raid/heroic maps have a global reset time + const MapEntry* entry = sMapStore.LookupEntry(temp->map); + if(!entry || !entry->HasResetTime()) + continue; + + uint32 period = temp->reset_delay * DAY; + assert(period != 0); + time_t t = m_resetTimeByMapId[temp->map]; + if(!t) + { + // initialize the reset time + t = today + period + diff; + CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','"I64FMTD"')", i, (uint64)t); + } + + if(t < now) + { + // assume that expired instances have already been cleaned + // calculate the next reset time + t = (t / DAY) * DAY; + t += ((today - t) / period + 1) * period + diff; + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"I64FMTD"' WHERE mapid = '%u'", (uint64)t, i); + } + + m_resetTimeByMapId[temp->map] = t; + + // schedule the global reset/warning + uint8 type = 1; + static int tim[4] = {3600, 900, 300, 60}; + for(; type < 4; type++) + if(t - tim[type-1] > now) break; + ScheduleReset(true, t - tim[type-1], InstResetEvent(type, i)); + } +} + +void InstanceSaveManager::ScheduleReset(bool add, time_t time, InstResetEvent event) +{ + if(add) m_resetTimeQueue.insert(std::pair(time, event)); + else + { + // find the event in the queue and remove it + ResetTimeQueue::iterator itr; + std::pair range; + range = m_resetTimeQueue.equal_range(time); + for(itr = range.first; itr != range.second; ++itr) + if(itr->second == event) { m_resetTimeQueue.erase(itr); return; } + // in case the reset time changed (should happen very rarely), we search the whole queue + if(itr == range.second) + { + for(itr = m_resetTimeQueue.begin(); itr != m_resetTimeQueue.end(); ++itr) + if(itr->second == event) { m_resetTimeQueue.erase(itr); return; } + if(itr == m_resetTimeQueue.end()) + sLog.outError("InstanceSaveManager::ScheduleReset: cannot cancel the reset, the event(%d,%d,%d) was not found!", event.type, event.mapid, event.instanceId); + } + } +} + +void InstanceSaveManager::Update() +{ + time_t now = time(NULL), t; + while(!m_resetTimeQueue.empty() && (t = m_resetTimeQueue.begin()->first) < now) + { + InstResetEvent &event = m_resetTimeQueue.begin()->second; + if(event.type == 0) + { + // for individual normal instances, max creature respawn + X hours + _ResetInstance(event.mapid, event.instanceId); + m_resetTimeQueue.erase(m_resetTimeQueue.begin()); + } + else + { + // global reset/warning for a certain map + time_t resetTime = GetResetTimeFor(event.mapid); + _ResetOrWarnAll(event.mapid, event.type != 4, resetTime - now); + if(event.type != 4) + { + // schedule the next warning/reset + event.type++; + static int tim[4] = {3600, 900, 300, 60}; + ScheduleReset(true, resetTime - tim[event.type-1], event); + } + m_resetTimeQueue.erase(m_resetTimeQueue.begin()); + } + } +} + +void InstanceSaveManager::_ResetSave(InstanceSaveHashMap::iterator &itr) +{ + // unbind all players bound to the instance + // do not allow UnbindInstance to automatically unload the InstanceSaves + lock_instLists = true; + InstanceSave::PlayerListType &pList = itr->second->m_playerList; + while(!pList.empty()) + { + Player *player = *(pList.begin()); + player->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficulty(), true); + } + InstanceSave::GroupListType &gList = itr->second->m_groupList; + while(!gList.empty()) + { + Group *group = *(gList.begin()); + group->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficulty(), true); + } + m_instanceSaveById.erase(itr++); + lock_instLists = false; +} + +void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) +{ + sLog.outDebug("InstanceSaveMgr::_ResetInstance %u, %u", mapid, instanceId); + Map *map = (MapInstanced*)MapManager::Instance().GetBaseMap(mapid); + if(!map->Instanceable()) + return; + + InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(instanceId); + if(itr != m_instanceSaveById.end()) _ResetSave(itr); + DeleteInstanceFromDB(instanceId); // even if save not loaded + + Map* iMap = ((MapInstanced*)map)->FindMap(instanceId); + if(iMap && iMap->IsDungeon()) ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY); + else objmgr.DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded +} + +void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLeft) +{ + // global reset for all instances of the given map + // note: this isn't fast but it's meant to be executed very rarely + Map *map = (MapInstanced*)MapManager::Instance().GetBaseMap(mapid); + if(!map->Instanceable()) + return; + uint64 now = (uint64)time(NULL); + + if(!warn) + { + // this is called one minute before the reset time + InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(mapid); + if(!temp || !temp->reset_delay) + { + sLog.outError("InstanceSaveManager::ResetOrWarnAll: no instance template or reset delay for map %d", mapid); + return; + } + + // remove all binds to instances of the given map + for(InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();) + { + if(itr->second->GetMapId() == mapid) + _ResetSave(itr); + else + ++itr; + } + + // delete them from the DB, even if not loaded + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = '%u'", mapid); + CharacterDatabase.PExecute("DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = '%u'", mapid); + CharacterDatabase.PExecute("DELETE FROM instance WHERE map = '%u'", mapid); + CharacterDatabase.CommitTransaction(); + + // calculate the next reset time + uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; + uint32 period = temp->reset_delay * DAY; + uint64 next_reset = ((now + timeLeft + MINUTE) / DAY * DAY) + period + diff; + // update it in the DB + CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"I64FMTD"' WHERE mapid = '%d'", next_reset, mapid); + } + + MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); + MapInstanced::InstancedMaps::iterator mitr; + for(mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr) + { + Map *map = mitr->second; + if(!map->IsDungeon()) continue; + if(warn) ((InstanceMap*)map)->SendResetWarnings(timeLeft); + else ((InstanceMap*)map)->Reset(INSTANCE_RESET_GLOBAL); + } + + // TODO: delete creature/gameobject respawn times even if the maps are not loaded +} + +uint32 InstanceSaveManager::GetNumBoundPlayersTotal() +{ + uint32 ret = 0; + for(InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) + ret += itr->second->GetPlayerCount(); + return ret; +} + +uint32 InstanceSaveManager::GetNumBoundGroupsTotal() +{ + uint32 ret = 0; + for(InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) + ret += itr->second->GetGroupCount(); + return ret; +} diff --git a/src/game/InstanceSaveMgr.h b/src/game/InstanceSaveMgr.h new file mode 100644 index 000000000..b9313ccbe --- /dev/null +++ b/src/game/InstanceSaveMgr.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2005,2006,2007 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __InstanceSaveMgr_H +#define __InstanceSaveMgr_H + +#include "Platform/Define.h" +#include "Policies/Singleton.h" +#include "zthread/Mutex.h" +#include +#include +#include "Utilities/HashMap.h" +#include "Database/DatabaseEnv.h" + +struct InstanceTemplate; +struct MapEntry; +class Player; +class Group; + +/* + Holds the information necessary for creating a new map for an existing instance + Is referenced in three cases: + - player-instance binds for solo players (not in group) + - player-instance binds for permanent heroic/raid saves + - group-instance binds (both solo and permanent) cache the player binds for the group leader +*/ +class InstanceSave +{ + friend class InstanceSaveManager; + public: + /* Created either when: + - any new instance is being generated + - the first time a player bound to InstanceId logs in + - when a group bound to the instance is loaded */ + InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset); + + /* Unloaded when m_playerList and m_groupList become empty + or when the instance is reset */ + ~InstanceSave(); + + uint8 GetPlayerCount() { return m_playerList.size(); } + uint8 GetGroupCount() { return m_groupList.size(); } + + /* A map corresponding to the InstanceId/MapId does not always exist. + InstanceSave objects may be created on player logon but the maps are + created and loaded only when a player actually enters the instance. */ + uint32 GetInstanceId() { return m_instanceid; } + uint32 GetMapId() { return m_mapid; } + + /* Saved when the instance is generated for the first time */ + void SaveToDB(); + /* When the instance is being reset (permanently deleted) */ + void DeleteFromDB(); + + /* for normal instances this corresponds to max(creature respawn time) + X hours + for raid/heroic instances this caches the global respawn time for the map */ + time_t GetResetTime() { return m_resetTime; } + void SetResetTime(time_t resetTime) { m_resetTime = resetTime; } + time_t GetResetTimeForDB(); + + InstanceTemplate const* GetTemplate(); + MapEntry const* GetMapEntry(); + + /* online players bound to the instance (perm/solo) + does not include the members of the group unless they have permanent saves */ + void AddPlayer(Player *player) { m_playerList.push_back(player); } + bool RemovePlayer(Player *player) { m_playerList.remove(player); return UnloadIfEmpty(); } + /* all groups bound to the instance */ + void AddGroup(Group *group) { m_groupList.push_back(group); } + bool RemoveGroup(Group *group) { m_groupList.remove(group); return UnloadIfEmpty(); } + + /* instances cannot be reset (except at the global reset time) + if there are players permanently bound to it + this is cached for the case when those players are offline */ + bool CanReset() { return m_canReset; } + void SetCanReset(bool canReset) { m_canReset = canReset; } + + /* currently it is possible to omit this information from this structure + but that would depend on a lot of things that can easily change in future */ + uint8 GetDifficulty() { return m_difficulty; } + + typedef std::list PlayerListType; + typedef std::list GroupListType; + private: + bool UnloadIfEmpty(); + /* the only reason the instSave-object links are kept is because + the object-instSave links need to be broken at reset time + TODO: maybe it's enough to just store the number of players/groups */ + PlayerListType m_playerList; + GroupListType m_groupList; + time_t m_resetTime; + uint32 m_instanceid; + uint16 m_mapid; + uint8 m_difficulty; + bool m_canReset; +}; + +class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton > +{ + friend class InstanceSave; + public: + InstanceSaveManager(); + ~InstanceSaveManager(); + + typedef std::map InstanceSaveMap; + typedef HM_NAMESPACE::hash_map InstanceSaveHashMap; + typedef std::map InstanceSaveMapMap; + + /* resetTime is a global propery of each (raid/heroic) map + all instances of that map reset at the same time */ + struct InstResetEvent + { + uint8 type; + uint16 mapid; + uint16 instanceId; + InstResetEvent(uint8 t = 0, uint16 m = 0, uint16 i = 0) : type(t), mapid(m), instanceId(i) {} + bool operator == (const InstResetEvent& e) { return e.instanceId == instanceId; } + }; + typedef std::multimap ResetTimeQueue; + typedef std::vector ResetTimeVector; + + void CleanupInstances(); + void PackInstances(); + + void LoadResetTimes(); + time_t GetResetTimeFor(uint32 mapid) { return m_resetTimeByMapId[mapid]; } + void ScheduleReset(bool add, time_t time, InstResetEvent event); + + void Update(); + + InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load = false); + void RemoveInstanceSave(uint32 InstanceId); + static void DeleteInstanceFromDB(uint32 instanceid); + + InstanceSave *GetInstanceSave(uint32 InstanceId); + + /* statistics */ + uint32 GetNumInstanceSaves() { return m_instanceSaveById.size(); } + uint32 GetNumBoundPlayersTotal(); + uint32 GetNumBoundGroupsTotal(); + + private: + void _ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeleft); + void _ResetInstance(uint32 mapid, uint32 instanceId); + void _ResetSave(InstanceSaveHashMap::iterator &itr); + void _DelHelper(DatabaseType &db, const char *fields, const char *table, const char *queryTail,...); + // used during global instance resets + bool lock_instLists; + // fast lookup by instance id + InstanceSaveHashMap m_instanceSaveById; + // fast lookup for reset times + ResetTimeVector m_resetTimeByMapId; + ResetTimeQueue m_resetTimeQueue; +}; + +#define sInstanceSaveManager MaNGOS::Singleton::Instance() +#endif diff --git a/src/game/Item.cpp b/src/game/Item.cpp new file mode 100644 index 000000000..7f9f2145b --- /dev/null +++ b/src/game/Item.cpp @@ -0,0 +1,916 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Item.h" +#include "ObjectMgr.h" +#include "WorldPacket.h" +#include "Database/DatabaseEnv.h" +#include "ItemEnchantmentMgr.h" + +void AddItemsSetItem(Player*player,Item *item) +{ + ItemPrototype const *proto = item->GetProto(); + uint32 setid = proto->ItemSet; + + ItemSetEntry const *set = sItemSetStore.LookupEntry(setid); + + if(!set) + { + sLog.outErrorDb("Item set %u for item (id %u) not found, mods not applied.",setid,proto->ItemId); + return; + } + + if( set->required_skill_id && player->GetSkillValue(set->required_skill_id) < set->required_skill_value ) + return; + + ItemSetEffect *eff = NULL; + + for(size_t x = 0; x < player->ItemSetEff.size(); ++x) + { + if(player->ItemSetEff[x] && player->ItemSetEff[x]->setid == setid) + { + eff = player->ItemSetEff[x]; + break; + } + } + + if(!eff) + { + eff = new ItemSetEffect; + memset(eff,0,sizeof(ItemSetEffect)); + eff->setid = setid; + + size_t x = 0; + for(; x < player->ItemSetEff.size(); x++) + if(!player->ItemSetEff[x]) + break; + + if(x < player->ItemSetEff.size()) + player->ItemSetEff[x]=eff; + else + player->ItemSetEff.push_back(eff); + } + + ++eff->item_count; + + for(uint32 x=0;x<8;x++) + { + if(!set->spells [x]) + continue; + //not enough for spell + if(set->items_to_triggerspell[x] > eff->item_count) + continue; + + uint32 z=0; + for(;z<8;z++) + if(eff->spells[z] && eff->spells[z]->Id==set->spells[x]) + break; + + if(z < 8) + continue; + + //new spell + for(uint32 y=0;y<8;y++) + { + if(!eff->spells[y]) // free slot + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(set->spells[x]); + if(!spellInfo) + { + sLog.outError("WORLD: unknown spell id %u in items set %u effects", set->spells[x],setid); + break; + } + + // spell casted only if fit form requirement, in other case will casted at form change + player->ApplyEquipSpell(spellInfo,NULL,true); + eff->spells[y] = spellInfo; + break; + } + } + } +} + +void RemoveItemsSetItem(Player*player,ItemPrototype const *proto) +{ + uint32 setid = proto->ItemSet; + + ItemSetEntry const *set = sItemSetStore.LookupEntry(setid); + + if(!set) + { + sLog.outErrorDb("Item set #%u for item #%u not found, mods not removed.",setid,proto->ItemId); + return; + } + + ItemSetEffect *eff = NULL; + size_t setindex = 0; + for(;setindex < player->ItemSetEff.size(); setindex++) + { + if(player->ItemSetEff[setindex] && player->ItemSetEff[setindex]->setid == setid) + { + eff = player->ItemSetEff[setindex]; + break; + } + } + + // can be in case now enough skill requirement for set appling but set has been appliend when skill requirement not enough + if(!eff) + return; + + --eff->item_count; + + for(uint32 x=0;x<8;x++) + { + if(!set->spells[x]) + continue; + + // enough for spell + if(set->items_to_triggerspell[x] <= eff->item_count) + continue; + + for(uint32 z=0;z<8;z++) + { + if(eff->spells[z] && eff->spells[z]->Id==set->spells[x]) + { + // spell can be not active if not fit form requirement + player->ApplyEquipSpell(eff->spells[z],NULL,false); + eff->spells[z]=NULL; + break; + } + } + } + + if(!eff->item_count) //all items of a set were removed + { + assert(eff == player->ItemSetEff[setindex]); + delete eff; + player->ItemSetEff[setindex] = NULL; + } +} + +bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProto) +{ + if(!pProto || !pBagProto) + return false; + + switch(pBagProto->Class) + { + case ITEM_CLASS_CONTAINER: + switch(pBagProto->SubClass) + { + case ITEM_SUBCLASS_CONTAINER: + return true; + case ITEM_SUBCLASS_SOUL_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_SOUL_SHARDS)) + return false; + return true; + case ITEM_SUBCLASS_HERB_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_HERBS)) + return false; + return true; + case ITEM_SUBCLASS_ENCHANTING_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_ENCHANTING_SUPP)) + return false; + return true; + case ITEM_SUBCLASS_MINING_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)) + return false; + return true; + case ITEM_SUBCLASS_ENGINEERING_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_ENGINEERING_SUPP)) + return false; + return true; + case ITEM_SUBCLASS_GEM_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_GEMS)) + return false; + return true; + case ITEM_SUBCLASS_LEATHERWORKING_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP)) + return false; + return true; + default: + return false; + } + case ITEM_CLASS_QUIVER: + switch(pBagProto->SubClass) + { + case ITEM_SUBCLASS_QUIVER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_ARROWS)) + return false; + return true; + case ITEM_SUBCLASS_AMMO_POUCH: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_BULLETS)) + return false; + return true; + default: + return false; + } + } + return false; +} + +Item::Item( ) +{ + m_objectType |= TYPEMASK_ITEM; + m_objectTypeId = TYPEID_ITEM; + // 2.3.2 - 0x18 + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID); + + m_valuesCount = ITEM_END; + m_slot = 0; + uState = ITEM_NEW; + uQueuePos = -1; + m_container = NULL; + m_lootGenerated = false; + mb_in_trade = false; +} + +bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner) +{ + Object::_Create( guidlow, 0, HIGHGUID_ITEM ); + + SetEntry(itemid); + SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); + + SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0); + SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0); + + ItemPrototype const *itemProto = objmgr.GetItemPrototype(itemid); + if(!itemProto) + return false; + + SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1); + SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability); + SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability); + + for(int i = 0; i < 5; ++i) + SetSpellCharges(i,itemProto->Spells[i].SpellCharges); + + SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags); + SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration)); + + return true; +} + +void Item::UpdateDuration(Player* owner, uint32 diff) +{ + if (!GetUInt32Value(ITEM_FIELD_DURATION)) + return; + + sLog.outDebug("Item::UpdateDuration Item (Entry: %u Duration %u Diff %u)",GetEntry(),GetUInt32Value(ITEM_FIELD_DURATION),diff); + + if (GetUInt32Value(ITEM_FIELD_DURATION)<=diff) + { + owner->DestroyItem(GetBagSlot(), GetSlot(), true); + return; + } + + SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION) - diff); + SetState(ITEM_CHANGED); // save new time in database +} + +void Item::SaveToDB() +{ + uint32 guid = GetGUIDLow(); + switch (uState) + { + case ITEM_NEW: + { + CharacterDatabase.PExecute( "DELETE FROM item_instance WHERE guid = '%u'", guid ); + std::ostringstream ss; + ss << "INSERT INTO item_instance (guid,owner_guid,data) VALUES (" << guid << "," << GUID_LOPART(GetOwnerGUID()) << ",'"; + for(uint16 i = 0; i < m_valuesCount; i++ ) + ss << GetUInt32Value(i) << " "; + ss << "' )"; + CharacterDatabase.Execute( ss.str().c_str() ); + } break; + case ITEM_CHANGED: + { + std::ostringstream ss; + ss << "UPDATE item_instance SET data = '"; + for(uint16 i = 0; i < m_valuesCount; i++ ) + ss << GetUInt32Value(i) << " "; + ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'"; + + CharacterDatabase.Execute( ss.str().c_str() ); + + if(HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + CharacterDatabase.PExecute("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow()); + } break; + case ITEM_REMOVED: + { + if (GetUInt32Value(ITEM_FIELD_ITEM_TEXT_ID) > 0 ) + CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", GetUInt32Value(ITEM_FIELD_ITEM_TEXT_ID)); + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", guid); + if(HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow()); + delete this; + return; + } + case ITEM_UNCHANGED: + break; + } + SetState(ITEM_UNCHANGED); +} + +bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) +{ + // create item before any checks for store correct guid + // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB + Object::_Create(guid, 0, HIGHGUID_ITEM); + + bool delete_result = false; + if(!result) + { + result = CharacterDatabase.PQuery("SELECT data FROM item_instance WHERE guid = '%u'", guid); + delete_result = true; + } + + if (!result) + { + sLog.outError("ERROR: Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid)); + return false; + } + + Field *fields = result->Fetch(); + + if(!LoadValues(fields[0].GetString())) + { + sLog.outError("ERROR: Item #%d have broken data in `data` field. Can't be loaded.",guid); + if (delete_result) delete result; + return false; + } + + bool need_save = false; // need explicit save data at load fixes + + // overwrite possible wrong/corrupted guid + uint64 new_item_guid = MAKE_NEW_GUID(guid,0, HIGHGUID_ITEM); + if(GetUInt64Value(OBJECT_FIELD_GUID) != new_item_guid) + { + SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid,0, HIGHGUID_ITEM)); + need_save = true; + } + + if (delete_result) delete result; + + ItemPrototype const* proto = GetProto(); + if(!proto) + return false; + + // recalculate suffix factor + if(GetItemRandomPropertyId() < 0) + { + if(UpdateItemSuffixFactor()) + need_save = true; + } + + // Remove bind flag for items vs NO_BIND set + if (IsSoulBound() && proto->Bonding == NO_BIND) + { + ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED, false); + need_save = true; + } + + // update duration if need, and remove if not need + if((proto->Duration==0) != (GetUInt32Value(ITEM_FIELD_DURATION)==0)) + { + SetUInt32Value(ITEM_FIELD_DURATION,abs(proto->Duration)); + need_save = true; + } + + // set correct owner + if(owner_guid != 0 && GetOwnerGUID() != owner_guid) + { + SetOwnerGUID(owner_guid); + need_save = true; + } + + if(need_save) // normal item changed state set not work at loading + { + std::ostringstream ss; + ss << "UPDATE item_instance SET data = '"; + for(uint16 i = 0; i < m_valuesCount; i++ ) + ss << GetUInt32Value(i) << " "; + ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'"; + + CharacterDatabase.Execute( ss.str().c_str() ); + } + + return true; +} + +void Item::DeleteFromDB() +{ + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'",GetGUIDLow()); +} + +void Item::DeleteFromInventoryDB() +{ + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'",GetGUIDLow()); +} + +ItemPrototype const *Item::GetProto() const +{ + return objmgr.GetItemPrototype(GetEntry()); +} + +Player* Item::GetOwner()const +{ + return objmgr.GetPlayer(GetOwnerGUID()); +} + +uint32 Item::GetSkill() +{ + const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] = + { + SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES, + SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0, + SKILL_STAVES, 0, 0, SKILL_UNARMED, 0, + SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS, + SKILL_FISHING + }; + + const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] = + { + 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0 + }; + + ItemPrototype const* proto = GetProto(); + + switch (proto->Class) + { + case ITEM_CLASS_WEAPON: + if( proto->SubClass >= MAX_ITEM_SUBCLASS_WEAPON ) + return 0; + else + return item_weapon_skills[proto->SubClass]; + + case ITEM_CLASS_ARMOR: + if( proto->SubClass >= MAX_ITEM_SUBCLASS_ARMOR ) + return 0; + else + return item_armor_skills[proto->SubClass]; + + default: + return 0; + } +} + +uint32 Item::GetSpell() +{ + ItemPrototype const* proto = GetProto(); + + switch (proto->Class) + { + case ITEM_CLASS_WEAPON: + switch (proto->SubClass) + { + case ITEM_SUBCLASS_WEAPON_AXE: return 196; + case ITEM_SUBCLASS_WEAPON_AXE2: return 197; + case ITEM_SUBCLASS_WEAPON_BOW: return 264; + case ITEM_SUBCLASS_WEAPON_GUN: return 266; + case ITEM_SUBCLASS_WEAPON_MACE: return 198; + case ITEM_SUBCLASS_WEAPON_MACE2: return 199; + case ITEM_SUBCLASS_WEAPON_POLEARM: return 200; + case ITEM_SUBCLASS_WEAPON_SWORD: return 201; + case ITEM_SUBCLASS_WEAPON_SWORD2: return 202; + case ITEM_SUBCLASS_WEAPON_STAFF: return 227; + case ITEM_SUBCLASS_WEAPON_DAGGER: return 1180; + case ITEM_SUBCLASS_WEAPON_THROWN: return 2567; + case ITEM_SUBCLASS_WEAPON_SPEAR: return 3386; + case ITEM_SUBCLASS_WEAPON_CROSSBOW:return 5011; + case ITEM_SUBCLASS_WEAPON_WAND: return 5009; + default: return 0; + } + case ITEM_CLASS_ARMOR: + switch(proto->SubClass) + { + case ITEM_SUBCLASS_ARMOR_CLOTH: return 9078; + case ITEM_SUBCLASS_ARMOR_LEATHER: return 9077; + case ITEM_SUBCLASS_ARMOR_MAIL: return 8737; + case ITEM_SUBCLASS_ARMOR_PLATE: return 750; + case ITEM_SUBCLASS_ARMOR_SHIELD: return 9116; + default: return 0; + } + } + return 0; +} + +int32 Item::GenerateItemRandomPropertyId(uint32 item_id) +{ + ItemPrototype const *itemProto = sItemStorage.LookupEntry(item_id); + + if(!itemProto) + return 0; + + // item must have one from this field values not null if it can have random enchantments + if((!itemProto->RandomProperty) && (!itemProto->RandomSuffix)) + return 0; + + // item can have not null only one from field values + if((itemProto->RandomProperty) && (itemProto->RandomSuffix)) + { + sLog.outErrorDb("Item template %u have RandomProperty==%u and RandomSuffix==%u, but must have one from field =0",itemProto->ItemId,itemProto->RandomProperty,itemProto->RandomSuffix); + return 0; + } + + // RandomProperty case + if(itemProto->RandomProperty) + { + uint32 randomPropId = GetItemEnchantMod(itemProto->RandomProperty); + ItemRandomPropertiesEntry const *random_id = sItemRandomPropertiesStore.LookupEntry(randomPropId); + if(!random_id) + { + sLog.outErrorDb("Enchantment id #%u used but it doesn't have records in 'ItemRandomProperties.dbc'",randomPropId); + return 0; + } + + return random_id->ID; + } + // RandomSuffix case + else + { + uint32 randomPropId = GetItemEnchantMod(itemProto->RandomSuffix); + ItemRandomSuffixEntry const *random_id = sItemRandomSuffixStore.LookupEntry(randomPropId); + if(!random_id) + { + sLog.outErrorDb("Enchantment id #%u used but it doesn't have records in sItemRandomSuffixStore.",randomPropId); + return 0; + } + + return -int32(random_id->ID); + } +} + +void Item::SetItemRandomProperties(int32 randomPropId) +{ + if(!randomPropId) + return; + + if(randomPropId > 0) + { + ItemRandomPropertiesEntry const *item_rand = sItemRandomPropertiesStore.LookupEntry(randomPropId); + if(item_rand) + { + if(GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != int32(item_rand->ID)) + { + SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID,item_rand->ID); + SetState(ITEM_CHANGED); + } + for(uint32 i = PROP_ENCHANTMENT_SLOT_2; i < PROP_ENCHANTMENT_SLOT_2 + 3; ++i) + SetEnchantment(EnchantmentSlot(i),item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_2],0,0); + } + } + else + { + ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(-randomPropId); + if(item_rand) + { + if( GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != -int32(item_rand->ID) || + !GetItemSuffixFactor()) + { + SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID,-int32(item_rand->ID)); + UpdateItemSuffixFactor(); + SetState(ITEM_CHANGED); + } + + for(uint32 i = PROP_ENCHANTMENT_SLOT_0; i < PROP_ENCHANTMENT_SLOT_0 + 3; ++i) + SetEnchantment(EnchantmentSlot(i),item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_0],0,0); + } + } +} + +bool Item::UpdateItemSuffixFactor() +{ + uint32 suffixFactor = GenerateEnchSuffixFactor(GetEntry()); + if(GetItemSuffixFactor()==suffixFactor) + return false; + SetUInt32Value(ITEM_FIELD_PROPERTY_SEED,suffixFactor); + return true; +} + +void Item::SetState(ItemUpdateState state, Player *forplayer) +{ + if (uState == ITEM_NEW && state == ITEM_REMOVED) + { + // pretend the item never existed + RemoveFromUpdateQueueOf(forplayer); + delete this; + return; + } + + if (state != ITEM_UNCHANGED) + { + // new items must stay in new state until saved + if (uState != ITEM_NEW) uState = state; + AddToUpdateQueueOf(forplayer); + } + else + { + // unset in queue + // the item must be removed from the queue manually + uQueuePos = -1; + uState = ITEM_UNCHANGED; + } +} + +void Item::AddToUpdateQueueOf(Player *player) +{ + if (IsInUpdateQueue()) return; + + if (!player) + { + player = GetOwner(); + if (!player) + { + sLog.outError("Item::AddToUpdateQueueOf - GetPlayer didn't find a player matching owner's guid (%u)!", GUID_LOPART(GetOwnerGUID())); + return; + } + } + + if (player->GetGUID() != GetOwnerGUID()) + { + sLog.outError("Item::AddToUpdateQueueOf - Owner's guid (%u) and player's guid (%u) don't match!", GUID_LOPART(GetOwnerGUID()), player->GetGUIDLow()); + return; + } + + if (player->m_itemUpdateQueueBlocked) return; + + player->m_itemUpdateQueue.push_back(this); + uQueuePos = player->m_itemUpdateQueue.size()-1; +} + +void Item::RemoveFromUpdateQueueOf(Player *player) +{ + if (!IsInUpdateQueue()) return; + + if (!player) + { + player = GetOwner(); + if (!player) + { + sLog.outError("Item::RemoveFromUpdateQueueOf - GetPlayer didn't find a player matching owner's guid (%u)!", GUID_LOPART(GetOwnerGUID())); + return; + } + } + + if (player->GetGUID() != GetOwnerGUID()) + { + sLog.outError("Item::RemoveFromUpdateQueueOf - Owner's guid (%u) and player's guid (%u) don't match!", GUID_LOPART(GetOwnerGUID()), player->GetGUIDLow()); + return; + } + + if (player->m_itemUpdateQueueBlocked) return; + + player->m_itemUpdateQueue[uQueuePos] = NULL; + uQueuePos = -1; +} + +uint8 Item::GetBagSlot() const +{ + return m_container ? m_container->GetSlot() : uint8(INVENTORY_SLOT_BAG_0); +} + +bool Item::IsEquipped() const +{ + return !IsInBag() && m_slot < EQUIPMENT_SLOT_END; +} + +bool Item::CanBeTraded() const +{ + if(IsSoulBound()) + return false; + if(IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()) ) + return false; + + if(Player* owner = GetOwner()) + { + if(owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK ) + return false; + if(owner->GetLootGUID()==GetGUID()) + return false; + } + + if (IsBoundByEnchant()) + return false; + + return true; +} + +bool Item::IsBoundByEnchant() const +{ + // Check all enchants for soulbound + for(uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) + { + uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + continue; + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + if(enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND) + return true; + } + return false; +} + +bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const +{ + ItemPrototype const* proto = GetProto(); + + if (spellInfo->EquippedItemClass != -1) // -1 == any item class + { + if(spellInfo->EquippedItemClass != int32(proto->Class)) + return false; // wrong item class + + if(spellInfo->EquippedItemSubClassMask != 0) // 0 == any subclass + { + if((spellInfo->EquippedItemSubClassMask & (1 << proto->SubClass)) == 0) + return false; // subclass not present in mask + } + } + + if(spellInfo->EquippedItemInventoryTypeMask != 0) // 0 == any inventory type + { + if((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0) + return false; // inventory type not present in mask + } + + return true; +} + +void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges) +{ + // Better lost small time at check in comparison lost time at item save to DB. + if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges)) + return; + + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); + SetState(ITEM_CHANGED); +} + +void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration) +{ + if(GetEnchantmentDuration(slot) == duration) + return; + + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); + SetState(ITEM_CHANGED); +} + +void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges) +{ + if(GetEnchantmentCharges(slot) == charges) + return; + + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); + SetState(ITEM_CHANGED); +} + +void Item::ClearEnchantment(EnchantmentSlot slot) +{ + if(!GetEnchantmentId(slot)) + return; + + for(uint8 x = 0; x < 3; ++x) + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0); + SetState(ITEM_CHANGED); +} + +bool Item::GemsFitSockets() const +{ + bool fits = true; + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + { + uint8 SocketColor = GetProto()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color; + + uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + { + if(SocketColor) fits &= false; + continue; + } + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + { + if(SocketColor) fits &= false; + continue; + } + + uint8 GemColor = 0; + + uint32 gemid = enchantEntry->GemID; + if(gemid) + { + ItemPrototype const* gemProto = sItemStorage.LookupEntry(gemid); + if(gemProto) + { + GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GemProperties); + if(gemProperty) + GemColor = gemProperty->color; + } + } + + fits &= (GemColor & SocketColor) ? true : false; + } + return fits; +} + +uint8 Item::GetGemCountWithID(uint32 GemID) const +{ + uint8 count = 0; + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + { + uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + continue; + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + if(GemID == enchantEntry->GemID) + ++count; + } + return count; +} + +bool Item::IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const +{ + ItemPrototype const* proto = GetProto(); + return proto && (proto->Map && proto->Map != cur_mapId || proto->Area && proto->Area != cur_zoneId ); +} + +// Though the client has the information in the item's data field, +// we have to send SMSG_ITEM_TIME_UPDATE to display the remaining +// time. +void Item::SendTimeUpdate(Player* owner) +{ + if (!GetUInt32Value(ITEM_FIELD_DURATION)) + return; + + WorldPacket data(SMSG_ITEM_TIME_UPDATE, (8+4)); + data << (uint64)GetGUID(); + data << (uint32)GetUInt32Value(ITEM_FIELD_DURATION); + owner->GetSession()->SendPacket(&data); +} + +Item* Item::CreateItem( uint32 item, uint32 count, Player const* player ) +{ + if ( count < 1 ) + return NULL; //don't create item at zero count + + ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); + if( pProto ) + { + if ( count > pProto->Stackable ) + count = pProto->Stackable; + + assert(count !=0 && "pProto->Stackable==0 but checked at loading already"); + + Item *pItem = NewItemOrBag( pProto ); + if( pItem->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM), item, player) ) + { + pItem->SetCount( count ); + return pItem; + } + else + delete pItem; + } + return NULL; +} + +Item* Item::CloneItem( uint32 count, Player const* player ) const +{ + Item* newItem = CreateItem( GetEntry(), count, player ); + if(!newItem) + return NULL; + + newItem->SetUInt32Value( ITEM_FIELD_CREATOR, GetUInt32Value( ITEM_FIELD_CREATOR ) ); + newItem->SetUInt32Value( ITEM_FIELD_GIFTCREATOR, GetUInt32Value( ITEM_FIELD_GIFTCREATOR ) ); + newItem->SetUInt32Value( ITEM_FIELD_FLAGS, GetUInt32Value( ITEM_FIELD_FLAGS ) ); + newItem->SetUInt32Value( ITEM_FIELD_DURATION, GetUInt32Value( ITEM_FIELD_DURATION ) ); + newItem->SetItemRandomProperties(GetItemRandomPropertyId()); + return newItem; +} diff --git a/src/game/Item.h b/src/game/Item.h new file mode 100644 index 000000000..c1430beab --- /dev/null +++ b/src/game/Item.h @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_ITEM_H +#define MANGOSSERVER_ITEM_H + +#include "Common.h" +#include "Object.h" +#include "LootMgr.h" +#include "ItemPrototype.h" + +struct SpellEntry; +class Bag; +class QueryResult; + +struct ItemSetEffect +{ + uint32 setid; + uint32 item_count; + SpellEntry const *spells[8]; +}; + +enum InventoryChangeFailure +{ + EQUIP_ERR_OK = 0, + EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1, + EQUIP_ERR_ERR_CANT_EQUIP_SKILL = 2, + EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT = 3, + EQUIP_ERR_BAG_FULL = 4, + EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG = 5, + EQUIP_ERR_CANT_TRADE_EQUIP_BAGS = 6, + EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE = 7, + EQUIP_ERR_NO_REQUIRED_PROFICIENCY = 8, + EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE = 9, + EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM = 10, + EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2 = 11, + EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2 = 12, + EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED = 13, + EQUIP_ERR_CANT_DUAL_WIELD = 14, + EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG = 15, + EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 = 16, + EQUIP_ERR_CANT_CARRY_MORE_OF_THIS = 17, + EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3 = 18, + EQUIP_ERR_ITEM_CANT_STACK = 19, + EQUIP_ERR_ITEM_CANT_BE_EQUIPPED = 20, + EQUIP_ERR_ITEMS_CANT_BE_SWAPPED = 21, + EQUIP_ERR_SLOT_IS_EMPTY = 22, + EQUIP_ERR_ITEM_NOT_FOUND = 23, + EQUIP_ERR_CANT_DROP_SOULBOUND = 24, + EQUIP_ERR_OUT_OF_RANGE = 25, + EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT = 26, + EQUIP_ERR_COULDNT_SPLIT_ITEMS = 27, + EQUIP_ERR_MISSING_REAGENT = 28, + EQUIP_ERR_NOT_ENOUGH_MONEY = 29, + EQUIP_ERR_NOT_A_BAG = 30, + EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS = 31, + EQUIP_ERR_DONT_OWN_THAT_ITEM = 32, + EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER = 33, + EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT = 34, + EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK = 35, + EQUIP_ERR_ITEM_LOCKED = 36, + EQUIP_ERR_YOU_ARE_STUNNED = 37, + EQUIP_ERR_YOU_ARE_DEAD = 38, + EQUIP_ERR_CANT_DO_RIGHT_NOW = 39, + EQUIP_ERR_INT_BAG_ERROR = 40, + EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER2 = 41, + EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH = 42, + EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED = 43, + EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED = 44, + EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED = 45, + EQUIP_ERR_BOUND_CANT_BE_WRAPPED = 46, + EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED = 47, + EQUIP_ERR_BAGS_CANT_BE_WRAPPED = 48, + EQUIP_ERR_ALREADY_LOOTED = 49, + EQUIP_ERR_INVENTORY_FULL = 50, + EQUIP_ERR_BANK_FULL = 51, + EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT = 52, + EQUIP_ERR_BAG_FULL3 = 53, + EQUIP_ERR_ITEM_NOT_FOUND2 = 54, + EQUIP_ERR_ITEM_CANT_STACK2 = 55, + EQUIP_ERR_BAG_FULL4 = 56, + EQUIP_ERR_ITEM_SOLD_OUT = 57, + EQUIP_ERR_OBJECT_IS_BUSY = 58, + EQUIP_ERR_NONE = 59, + EQUIP_ERR_NOT_IN_COMBAT = 60, + EQUIP_ERR_NOT_WHILE_DISARMED = 61, + EQUIP_ERR_BAG_FULL6 = 62, + EQUIP_ERR_CANT_EQUIP_RANK = 63, + EQUIP_ERR_CANT_EQUIP_REPUTATION = 64, + EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65, + EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66, + EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE = 67, + EQUIP_ERR_VENDOR_MISSING_TURNINS = 68, + EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69, + EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70, + EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71, + EQUIP_ERR_MAIL_BOUND_ITEM = 72, + EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING = 73, + EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75, + EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76, + EQUIP_ERR_TOO_MUCH_GOLD = 77, + EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78, + EQUIP_ERR_CANNOT_TRADE_THAT = 79, + EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80 + // probably exist more +}; + +enum BuyFailure +{ + BUY_ERR_CANT_FIND_ITEM = 0, + BUY_ERR_ITEM_ALREADY_SOLD = 1, + BUY_ERR_NOT_ENOUGHT_MONEY = 2, + BUY_ERR_SELLER_DONT_LIKE_YOU = 4, + BUY_ERR_DISTANCE_TOO_FAR = 5, + BUY_ERR_ITEM_SOLD_OUT = 7, + BUY_ERR_CANT_CARRY_MORE = 8, + BUY_ERR_RANK_REQUIRE = 11, + BUY_ERR_REPUTATION_REQUIRE = 12 +}; + +enum SellFailure +{ + SELL_ERR_CANT_FIND_ITEM = 1, + SELL_ERR_CANT_SELL_ITEM = 2, // merchant doesn't like that item + SELL_ERR_CANT_FIND_VENDOR = 3, // merchant doesn't like you + SELL_ERR_YOU_DONT_OWN_THAT_ITEM = 4, // you don't own that item + SELL_ERR_UNK = 5, // nothing appears... + SELL_ERR_ONLY_EMPTY_BAG = 6 // can only do with empty bags +}; + +// -1 from client enchantment slot number +enum EnchantmentSlot +{ + PERM_ENCHANTMENT_SLOT = 0, + TEMP_ENCHANTMENT_SLOT = 1, + SOCK_ENCHANTMENT_SLOT = 2, + SOCK_ENCHANTMENT_SLOT_2 = 3, + SOCK_ENCHANTMENT_SLOT_3 = 4, + BONUS_ENCHANTMENT_SLOT = 5, + MAX_INSPECTED_ENCHANTMENT_SLOT = 6, + + PROP_ENCHANTMENT_SLOT_0 = 6, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_1 = 7, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_2 = 8, // used with RandomSuffix and RandomProperty + PROP_ENCHANTMENT_SLOT_3 = 9, // used with RandomProperty + PROP_ENCHANTMENT_SLOT_4 = 10, // used with RandomProperty + MAX_ENCHANTMENT_SLOT = 11 +}; + +#define MAX_VISIBLE_ITEM_OFFSET 16 // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1)) + +enum EnchantmentOffset +{ + ENCHANTMENT_ID_OFFSET = 0, + ENCHANTMENT_DURATION_OFFSET = 1, + ENCHANTMENT_CHARGES_OFFSET = 2 +}; + +#define MAX_ENCHANTMENT_OFFSET 3 + +enum EnchantmentSlotMask +{ + ENCHANTMENT_CAN_SOULBOUND = 0x01, + ENCHANTMENT_UNK1 = 0x02, + ENCHANTMENT_UNK2 = 0x04, + ENCHANTMENT_UNK3 = 0x08 +}; + +enum ItemUpdateState +{ + ITEM_UNCHANGED = 0, + ITEM_CHANGED = 1, + ITEM_NEW = 2, + ITEM_REMOVED = 3 +}; + +bool ItemCanGoIntoBag(ItemPrototype const *proto, ItemPrototype const *pBagProto); + +class MANGOS_DLL_SPEC Item : public Object +{ + public: + static Item* CreateItem( uint32 item, uint32 count, Player const* player = NULL ); + Item* CloneItem( uint32 count, Player const* player = NULL ) const; + + Item ( ); + + virtual bool Create( uint32 guidlow, uint32 itemid, Player const* owner); + + ItemPrototype const* GetProto() const; + + uint64 const& GetOwnerGUID() const { return GetUInt64Value(ITEM_FIELD_OWNER); } + void SetOwnerGUID(uint64 guid) { SetUInt64Value(ITEM_FIELD_OWNER, guid); } + Player* GetOwner()const; + + void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); } + bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); } + bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; } + bool IsBoundByEnchant() const; + virtual void SaveToDB(); + virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL); + virtual void DeleteFromDB(); + void DeleteFromInventoryDB(); + + bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; } + bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; } + bool CanBeTraded() const; + void SetInTrade(bool b = true) { mb_in_trade = b; } + bool IsInTrade() const { return mb_in_trade; } + + bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const; + bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const; + bool GemsFitSockets() const; + + uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); } + void SetCount(uint32 value) { SetUInt32Value (ITEM_FIELD_STACK_COUNT, value); } + uint32 GetMaxStackCount() const { return GetProto()->Stackable; } + uint8 GetGemCountWithID(uint32 GemID) const; + + uint8 GetSlot() const {return m_slot;} + Bag *GetContainer() { return m_container; } + uint8 GetBagSlot() const; + void SetSlot(uint8 slot) {m_slot = slot;} + uint16 GetPos() const { return uint16(GetBagSlot()) << 8 | GetSlot(); } + void SetContainer(Bag *container) { m_container = container; } + + bool IsInBag() const { return m_container != NULL; } + bool IsEquipped() const; + + uint32 GetSkill(); + uint32 GetSpell(); + + // RandomPropertyId (signed but stored as unsigned) + int32 GetItemRandomPropertyId() const { return GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID); } + uint32 GetItemSuffixFactor() const { return GetUInt32Value(ITEM_FIELD_PROPERTY_SEED); } + void SetItemRandomProperties(int32 randomPropId); + bool UpdateItemSuffixFactor(); + static int32 GenerateItemRandomPropertyId(uint32 item_id); + void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges); + void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration); + void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges); + void ClearEnchantment(EnchantmentSlot slot); + uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);} + uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);} + uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);} + + void SendTimeUpdate(Player* owner); + void UpdateDuration(Player* owner, uint32 diff); + + // spell charges (signed but stored as unsigned) + int32 GetSpellCharges(uint8 index/*0..5*/ = 0) const { return GetInt32Value(ITEM_FIELD_SPELL_CHARGES + index); } + void SetSpellCharges(uint8 index/*0..5*/, int32 value) { SetInt32Value(ITEM_FIELD_SPELL_CHARGES + index,value); } + + Loot loot; + bool m_lootGenerated; + + // Update States + ItemUpdateState GetState() const { return uState; } + void SetState(ItemUpdateState state, Player *forplayer = NULL); + void AddToUpdateQueueOf(Player *player); + void RemoveFromUpdateQueueOf(Player *player); + bool IsInUpdateQueue() const { return uQueuePos != -1; } + uint16 GetQueuePos() const { return uQueuePos; } + void FSetState(ItemUpdateState state) // forced + { + uState = state; + } + + bool hasQuest(uint32 quest_id) const + { + ItemPrototype const *itemProto = GetProto(); + return itemProto && itemProto->StartQuest == quest_id; + } + bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; } + + private: + uint8 m_slot; + Bag *m_container; + ItemUpdateState uState; + int16 uQueuePos; + bool mb_in_trade; // true if item is currently in trade-window +}; +#endif diff --git a/src/game/ItemEnchantmentMgr.cpp b/src/game/ItemEnchantmentMgr.cpp new file mode 100644 index 000000000..a912a7a07 --- /dev/null +++ b/src/game/ItemEnchantmentMgr.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "ItemEnchantmentMgr.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "ProgressBar.h" +#include +#include +#include "Util.h" + +struct EnchStoreItem +{ + uint32 ench; + float chance; + + EnchStoreItem() + : ench(0), chance(0) {} + + EnchStoreItem(uint32 _ench, float _chance) + : ench(_ench), chance(_chance) {} +}; + +typedef std::vector EnchStoreList; +typedef HM_NAMESPACE::hash_map EnchantmentStore; + +static EnchantmentStore RandomItemEnch; + +void LoadRandomEnchantmentsTable() +{ + RandomItemEnch.clear(); // for reload case + + EnchantmentStore::iterator tab; + uint32 entry, ench; + float chance; + uint32 count = 0; + + QueryResult *result = WorldDatabase.Query("SELECT entry, ench, chance FROM item_enchantment_template"); + + if (result) + { + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + entry = fields[0].GetUInt32(); + ench = fields[1].GetUInt32(); + chance = fields[2].GetFloat(); + + if (chance > 0.000001f && chance <= 100.0f) + RandomItemEnch[entry].push_back( EnchStoreItem(ench, chance) ); + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u Item Enchantment definitions", count ); + } + else + { + sLog.outString(); + sLog.outErrorDb( ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty."); + } +} + +uint32 GetItemEnchantMod(uint32 entry) +{ + if (!entry) return 0; + + EnchantmentStore::iterator tab = RandomItemEnch.find(entry); + + if (tab == RandomItemEnch.end()) + { + sLog.outErrorDb("Item RandomProperty / RandomSuffix id #%u used in `item_template` but it doesn't have records in `item_enchantment_template` table.",entry); + return 0; + } + + double dRoll = rand_chance(); + float fCount = 0; + + for(EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter) + { + fCount += ench_iter->chance; + + if (fCount > dRoll) return ench_iter->ench; + } + + //we could get here only if sum of all enchantment chances is lower than 100% + dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100; + fCount = 0; + + for(EnchStoreList::iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter) + { + fCount += ench_iter->chance; + + if (fCount > dRoll) return ench_iter->ench; + } + + return 0; +} + +uint32 GenerateEnchSuffixFactor(uint32 item_id) +{ + ItemPrototype const *itemProto = objmgr.GetItemPrototype(item_id); + + if(!itemProto) + return 0; + if(!itemProto->RandomSuffix) + return 0; + + RandomPropertiesPointsEntry const *randomProperty = sRandomPropertiesPointsStore.LookupEntry(itemProto->ItemLevel); + if(!randomProperty) + return 0; + + uint32 suffixFactor; + switch(itemProto->InventoryType) + { + // Items of that type don`t have points + case INVTYPE_NON_EQUIP: + case INVTYPE_BAG: + case INVTYPE_TABARD: + case INVTYPE_AMMO: + case INVTYPE_QUIVER: + case INVTYPE_RELIC: + return 0; + // Select point coefficient + case INVTYPE_HEAD: + case INVTYPE_BODY: + case INVTYPE_CHEST: + case INVTYPE_LEGS: + case INVTYPE_2HWEAPON: + case INVTYPE_ROBE: + suffixFactor = 0; + break; + case INVTYPE_SHOULDERS: + case INVTYPE_WAIST: + case INVTYPE_FEET: + case INVTYPE_HANDS: + case INVTYPE_TRINKET: + suffixFactor = 1; + break; + case INVTYPE_NECK: + case INVTYPE_WRISTS: + case INVTYPE_FINGER: + case INVTYPE_SHIELD: + case INVTYPE_CLOAK: + case INVTYPE_HOLDABLE: + suffixFactor = 2; + break; + case INVTYPE_WEAPON: + case INVTYPE_WEAPONMAINHAND: + case INVTYPE_WEAPONOFFHAND: + suffixFactor = 3; + break; + case INVTYPE_RANGED: + case INVTYPE_THROWN: + case INVTYPE_RANGEDRIGHT: + suffixFactor = 4; + break; + default: + return 0; + } + // Select rare/epic modifier + switch (itemProto->Quality) + { + case ITEM_QUALITY_UNCOMMON: + return randomProperty->UncommonPropertiesPoints[suffixFactor]; + case ITEM_QUALITY_RARE: + return randomProperty->RarePropertiesPoints[suffixFactor]; + case ITEM_QUALITY_EPIC: + return randomProperty->EpicPropertiesPoints[suffixFactor]; + case ITEM_QUALITY_LEGENDARY: + case ITEM_QUALITY_ARTIFACT: + return 0; // not have random properties + default: + break; + } + return 0; +} diff --git a/src/game/ItemEnchantmentMgr.h b/src/game/ItemEnchantmentMgr.h new file mode 100644 index 000000000..d2d60dc17 --- /dev/null +++ b/src/game/ItemEnchantmentMgr.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ITEM_ENCHANTMENT_MGR_H +#define _ITEM_ENCHANTMENT_MGR_H + +#include "Common.h" + +void LoadRandomEnchantmentsTable(); +uint32 GetItemEnchantMod(uint32 entry); +uint32 GenerateEnchSuffixFactor(uint32 item_id); +#endif diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp new file mode 100644 index 000000000..04355c85d --- /dev/null +++ b/src/game/ItemHandler.cpp @@ -0,0 +1,1214 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Opcodes.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Item.h" +#include "UpdateData.h" +#include "ObjectAccessor.h" + +void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1+1+1+1); + + //sLog.outDebug("WORLD: CMSG_SPLIT_ITEM"); + uint8 srcbag, srcslot, dstbag, dstslot, count; + + recv_data >> srcbag >> srcslot >> dstbag >> dstslot >> count; + //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u, count = %u", srcbag, srcslot, dstbag, dstslot, count); + + uint16 src = ( (srcbag << 8) | srcslot ); + uint16 dst = ( (dstbag << 8) | dstslot ); + + if(src==dst) + return; + + if (count==0) + return; //check count - if zero it's fake packet + + _player->SplitItem( src, dst, count ); +} + +void WorldSession::HandleSwapInvItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1); + + //sLog.outDebug("WORLD: CMSG_SWAP_INV_ITEM"); + uint8 srcslot, dstslot; + + recv_data >> srcslot >> dstslot; + //sLog.outDebug("STORAGE: receive srcslot = %u, dstslot = %u", srcslot, dstslot); + + // prevent attempt swap same item to current position generated by client at special checting sequence + if(srcslot==dstslot) + return; + + uint16 src = ( (INVENTORY_SLOT_BAG_0 << 8) | srcslot ); + uint16 dst = ( (INVENTORY_SLOT_BAG_0 << 8) | dstslot ); + + _player->SwapItem( src, dst ); +} + +void WorldSession::HandleAutoEquipItemSlotOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+1); + uint64 itemguid; + uint8 dstslot; + recv_data >> itemguid >> dstslot; + + // cheating attempt, client should never send opcode in that case + if(!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, dstslot)) + return; + + Item* item = _player->GetItemByGuid(itemguid); + uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8); + + if(!item || item->GetPos() == dstpos) + return; + + _player->SwapItem(item->GetPos(), dstpos); +} + +void WorldSession::HandleSwapItem( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1+1+1); + + //sLog.outDebug("WORLD: CMSG_SWAP_ITEM"); + uint8 dstbag, dstslot, srcbag, srcslot; + + recv_data >> dstbag >> dstslot >> srcbag >> srcslot ; + //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u", srcbag, srcslot, dstbag, dstslot); + + uint16 src = ( (srcbag << 8) | srcslot ); + uint16 dst = ( (dstbag << 8) | dstslot ); + + // prevent attempt swap same item to current position generated by client at special checting sequence + if(src==dst) + return; + + _player->SwapItem( src, dst ); +} + +void WorldSession::HandleAutoEquipItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1); + + //sLog.outDebug("WORLD: CMSG_AUTOEQUIP_ITEM"); + uint8 srcbag, srcslot; + + recv_data >> srcbag >> srcslot; + //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot); + + Item *pSrcItem = _player->GetItemByPos( srcbag, srcslot ); + if( !pSrcItem ) + return; // only at cheat + + if(pSrcItem->m_lootGenerated) // prevent swap looting item + { + //best error message found for attempting to swap while looting + _player->SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pSrcItem, NULL ); + return; + } + + uint16 dest; + uint8 msg = _player->CanEquipItem( NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag() ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pSrcItem, NULL ); + return; + } + + uint16 src = pSrcItem->GetPos(); + if(dest==src) // prevent equip in same slot, only at cheat + return; + + Item *pDstItem = _player->GetItemByPos( dest ); + if( !pDstItem ) // empty slot, simple case + { + _player->RemoveItem( srcbag, srcslot, true ); + _player->EquipItem( dest, pSrcItem, true ); + _player->AutoUnequipOffhandIfNeed(); + } + else // have currently equipped item, not simple case + { + uint8 dstbag = pDstItem->GetBagSlot(); + uint8 dstslot = pDstItem->GetSlot(); + + msg = _player->CanUnequipItem( dest, !pSrcItem->IsBag() ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pDstItem, NULL ); + return; + } + + // check dest->src move possibility + ItemPosCountVec sSrc; + uint16 eSrc; + if( _player->IsInventoryPos( src ) ) + { + msg = _player->CanStoreItem( srcbag, srcslot, sSrc, pDstItem, true ); + if( msg != EQUIP_ERR_OK ) + msg = _player->CanStoreItem( srcbag, NULL_SLOT, sSrc, pDstItem, true ); + if( msg != EQUIP_ERR_OK ) + msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, sSrc, pDstItem, true ); + } + else if( _player->IsBankPos( src ) ) + { + msg = _player->CanBankItem( srcbag, srcslot, sSrc, pDstItem, true ); + if( msg != EQUIP_ERR_OK ) + msg = _player->CanBankItem( srcbag, NULL_SLOT, sSrc, pDstItem, true ); + if( msg != EQUIP_ERR_OK ) + msg = _player->CanBankItem( NULL_BAG, NULL_SLOT, sSrc, pDstItem, true ); + } + else if( _player->IsEquipmentPos( src ) ) + { + msg = _player->CanEquipItem( srcslot, eSrc, pDstItem, true); + if( msg == EQUIP_ERR_OK ) + msg = _player->CanUnequipItem( eSrc, true); + } + + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pDstItem, pSrcItem ); + return; + } + + // now do moves, remove... + _player->RemoveItem(dstbag, dstslot, false); + _player->RemoveItem(srcbag, srcslot, false); + + // add to dest + _player->EquipItem(dest, pSrcItem, true); + + // add to src + if( _player->IsInventoryPos( src ) ) + _player->StoreItem(sSrc, pDstItem, true); + else if( _player->IsBankPos( src ) ) + _player->BankItem(sSrc, pDstItem, true); + else if( _player->IsEquipmentPos( src ) ) + _player->EquipItem(eSrc, pDstItem, true); + + _player->AutoUnequipOffhandIfNeed(); + } +} + +void WorldSession::HandleDestroyItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1+1+1+1+1); + + //sLog.outDebug("WORLD: CMSG_DESTROYITEM"); + uint8 bag, slot, count, data1, data2, data3; + + recv_data >> bag >> slot >> count >> data1 >> data2 >> data3; + //sLog.outDebug("STORAGE: receive bag = %u, slot = %u, count = %u", bag, slot, count); + + uint16 pos = (bag << 8) | slot; + + // prevent drop unequipable items (in combat, for example) and non-empty bags + if(_player->IsEquipmentPos(pos) || _player->IsBagPos(pos)) + { + uint8 msg = _player->CanUnequipItem( pos, false ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, _player->GetItemByPos(pos), NULL ); + return; + } + } + + Item *pItem = _player->GetItemByPos( bag, slot ); + if(!pItem) + { + _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + + if(count) + { + uint32 i_count = count; + _player->DestroyItemCount( pItem, i_count, true ); + } + else + _player->DestroyItem( bag, slot, true ); +} + +// Only _static_ data send in this packet !!! +void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + + //sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE"); + uint32 item; + recv_data >> item; + + sLog.outDetail("STORAGE: Item Query = %u", item); + + ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); + if( pProto ) + { + std::string Name = pProto->Name1; + std::string Description = pProto->Description; + + int loc_idx = GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + { + ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); + if (il) + { + if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + Name = il->Name[loc_idx]; + if (il->Description.size() > loc_idx && !il->Description[loc_idx].empty()) + Description = il->Description[loc_idx]; + } + } + // guess size + WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); + data << pProto->ItemId; + data << pProto->Class; + data << pProto->SubClass; + data << uint32(-1); // new 2.0.3, not exist in wdb cache? + data << Name; + data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... + data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); + data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00); + data << pProto->DisplayInfoID; + data << pProto->Quality; + data << pProto->Flags; + data << pProto->BuyPrice; + data << pProto->SellPrice; + data << pProto->InventoryType; + data << pProto->AllowableClass; + data << pProto->AllowableRace; + data << pProto->ItemLevel; + data << pProto->RequiredLevel; + data << pProto->RequiredSkill; + data << pProto->RequiredSkillRank; + data << pProto->RequiredSpell; + data << pProto->RequiredHonorRank; + data << pProto->RequiredCityRank; + data << pProto->RequiredReputationFaction; + data << pProto->RequiredReputationRank; + data << pProto->MaxCount; + data << pProto->Stackable; + data << pProto->ContainerSlots; + for(int i = 0; i < 10; i++) + { + data << pProto->ItemStat[i].ItemStatType; + data << pProto->ItemStat[i].ItemStatValue; + } + for(int i = 0; i < 5; i++) + { + data << pProto->Damage[i].DamageMin; + data << pProto->Damage[i].DamageMax; + data << pProto->Damage[i].DamageType; + } + + // resistances (7) + data << pProto->Armor; + data << pProto->HolyRes; + data << pProto->FireRes; + data << pProto->NatureRes; + data << pProto->FrostRes; + data << pProto->ShadowRes; + data << pProto->ArcaneRes; + + data << pProto->Delay; + data << pProto->Ammo_type; + data << pProto->RangedModRange; + + for(int s = 0; s < 5; s++) + { + // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown + // use `item_template` or if not set then only use spell cooldowns + SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId); + if(spell) + { + bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0; + + data << pProto->Spells[s].SpellId; + data << pProto->Spells[s].SpellTrigger; + data << uint32(-abs(pProto->Spells[s].SpellCharges)); + + if(db_data) + { + data << uint32(pProto->Spells[s].SpellCooldown); + data << uint32(pProto->Spells[s].SpellCategory); + data << uint32(pProto->Spells[s].SpellCategoryCooldown); + } + else + { + data << uint32(spell->RecoveryTime); + data << uint32(spell->Category); + data << uint32(spell->CategoryRecoveryTime); + } + } + else + { + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(-1); + data << uint32(0); + data << uint32(-1); + } + } + data << pProto->Bonding; + data << Description; + data << pProto->PageText; + data << pProto->LanguageID; + data << pProto->PageMaterial; + data << pProto->StartQuest; + data << pProto->LockID; + data << pProto->Material; + data << pProto->Sheath; + data << pProto->RandomProperty; + data << pProto->RandomSuffix; + data << pProto->Block; + data << pProto->ItemSet; + data << pProto->MaxDurability; + data << pProto->Area; + data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch + data << pProto->BagFamily; + data << pProto->TotemCategory; + for(int s = 0; s < 3; s++) + { + data << pProto->Socket[s].Color; + data << pProto->Socket[s].Content; + } + data << pProto->socketBonus; + data << pProto->GemProperties; + data << pProto->RequiredDisenchantSkill; + data << pProto->ArmorDamageModifier; + data << uint32(0); // added in 2.4.2.8209, duration (seconds) + SendPacket( &data ); + } + else + { + sLog.outDebug( "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item ); + WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); + data << uint32(item | 0x80000000); + SendPacket( &data ); + } +} + +void WorldSession::HandleReadItem( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1); + + //sLog.outDebug( "WORLD: CMSG_READ_ITEM"); + + uint8 bag, slot; + recv_data >> bag >> slot; + + //sLog.outDetail("STORAGE: Read bag = %u, slot = %u", bag, slot); + Item *pItem = _player->GetItemByPos( bag, slot ); + + if( pItem && pItem->GetProto()->PageText ) + { + WorldPacket data; + + uint8 msg = _player->CanUseItem( pItem ); + if( msg == EQUIP_ERR_OK ) + { + data.Initialize (SMSG_READ_ITEM_OK, 8); + sLog.outDetail("STORAGE: Item page sent"); + } + else + { + data.Initialize( SMSG_READ_ITEM_FAILED, 8 ); + sLog.outDetail("STORAGE: Unable to read item"); + _player->SendEquipError( msg, pItem, NULL ); + } + data << pItem->GetGUID(); + SendPacket(&data); + } + else + _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); +} + +void WorldSession::HandlePageQuerySkippedOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+8); + + sLog.outDebug( "WORLD: Received CMSG_PAGE_TEXT_QUERY" ); + + uint32 itemid; + uint64 guid; + + recv_data >> itemid >> guid; + + sLog.outDetail( "Packet Info: itemid: %u guidlow: %u guidentry: %u guidhigh: %u", + itemid, GUID_LOPART(guid), GUID_ENPART(guid), GUID_HIPART(guid)); +} + +void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+8+1); + + sLog.outDebug( "WORLD: Received CMSG_SELL_ITEM" ); + uint64 vendorguid, itemguid; + uint8 _count; + + recv_data >> vendorguid >> itemguid >> _count; + + // prevent possible overflow, as mangos uses uint32 for item count + uint32 count = _count; + + if(!itemguid) + return; + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorguid,UNIT_NPC_FLAG_VENDOR); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleSellItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); + _player->SendSellError( SELL_ERR_CANT_FIND_VENDOR, NULL, itemguid, 0); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + Item *pItem = _player->GetItemByGuid( itemguid ); + if( pItem ) + { + // prevent sell not owner item + if(_player->GetGUID()!=pItem->GetOwnerGUID()) + { + _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); + return; + } + + // prevent sell non empty bag by drag-and-drop at vendor's item list + if(pItem->IsBag() && !((Bag*)pItem)->IsEmpty()) + { + _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); + return; + } + + // prevent sell currently looted item + if(_player->GetLootGUID()==pItem->GetGUID()) + { + _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); + return; + } + + // special case at auto sell (sell all) + if(count==0) + { + count = pItem->GetCount(); + } + else + { + // prevent sell more items that exist in stack (possable only not from client) + if(count > pItem->GetCount()) + { + _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); + return; + } + } + + ItemPrototype const *pProto = pItem->GetProto(); + if( pProto ) + { + if( pProto->SellPrice > 0 ) + { + if(count < pItem->GetCount()) // need split items + { + Item *pNewItem = pItem->CloneItem( count, _player ); + if (!pNewItem) + { + sLog.outError("WORLD: HandleSellItemOpcode - could not create clone of item %u; count = %u", pItem->GetEntry(), count ); + _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); + return; + } + + pItem->SetCount( pItem->GetCount() - count ); + _player->ItemRemovedQuestCheck( pItem->GetEntry(), count ); + if( _player->IsInWorld() ) + pItem->SendUpdateToPlayer( _player ); + pItem->SetState(ITEM_CHANGED, _player); + + _player->AddItemToBuyBackSlot( pNewItem ); + if( _player->IsInWorld() ) + pNewItem->SendUpdateToPlayer( _player ); + } + else + { + _player->ItemRemovedQuestCheck( pItem->GetEntry(), pItem->GetCount()); + _player->RemoveItem( pItem->GetBagSlot(), pItem->GetSlot(), true); + pItem->RemoveFromUpdateQueueOf(_player); + _player->AddItemToBuyBackSlot( pItem ); + } + + _player->ModifyMoney( pProto->SellPrice * count ); + } + else + _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); + return; + } + } + _player->SendSellError( SELL_ERR_CANT_FIND_ITEM, pCreature, itemguid, 0); + return; +} + +void WorldSession::HandleBuybackItem(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + sLog.outDebug( "WORLD: Received CMSG_BUYBACK_ITEM" ); + uint64 vendorguid; + uint32 slot; + + recv_data >> vendorguid >> slot; + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorguid,UNIT_NPC_FLAG_VENDOR); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleBuybackItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); + _player->SendSellError( SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + Item *pItem = _player->GetItemFromBuyBackSlot( slot ); + if( pItem ) + { + uint32 price = _player->GetUInt32Value( PLAYER_FIELD_BUYBACK_PRICE_1 + slot - BUYBACK_SLOT_START ); + if( _player->GetMoney() < price ) + { + _player->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, pItem->GetEntry(), 0); + return; + } + + ItemPosCountVec dest; + uint8 msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, dest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + { + _player->ModifyMoney( -(int32)price ); + _player->RemoveItemFromBuyBackSlot( slot, false ); + _player->ItemAddedQuestCheck( pItem->GetEntry(), pItem->GetCount()); + _player->StoreItem( dest, pItem, true ); + } + else + _player->SendEquipError( msg, pItem, NULL ); + return; + } + else + _player->SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, 0, 0); +} + +void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+8+1+1); + + sLog.outDebug( "WORLD: Received CMSG_BUY_ITEM_IN_SLOT" ); + uint64 vendorguid, bagguid; + uint32 item; + uint8 slot, count; + + recv_data >> vendorguid >> item >> bagguid >> slot >> count; + + GetPlayer()->BuyItemFromVendor(vendorguid,item,count,bagguid,slot); +} + +void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+1+1); + + sLog.outDebug( "WORLD: Received CMSG_BUY_ITEM" ); + uint64 vendorguid; + uint32 item; + uint8 count, unk1; + + recv_data >> vendorguid >> item >> count >> unk1; + + GetPlayer()->BuyItemFromVendor(vendorguid,item,count,NULL_BAG,NULL_SLOT); +} + +void WorldSession::HandleListInventoryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + + recv_data >> guid; + + if(!GetPlayer()->isAlive()) + return; + + sLog.outDebug( "WORLD: Recvd CMSG_LIST_INVENTORY" ); + + SendListInventory( guid ); +} + +void WorldSession::SendListInventory( uint64 vendorguid ) +{ + sLog.outDebug( "WORLD: Sent SMSG_LIST_INVENTORY" ); + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, vendorguid,UNIT_NPC_FLAG_VENDOR); + if (!pCreature) + { + sLog.outDebug( "WORLD: SendListInventory - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); + _player->SendSellError( SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + // Stop the npc if moving + pCreature->StopMoving(); + + VendorItemData const* vItems = pCreature->GetVendorItems(); + if(!vItems) + { + _player->SendSellError( SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0); + return; + } + + uint8 numitems = vItems->GetItemCount(); + uint8 count = 0; + + WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*8*4) ); + data << uint64(vendorguid); + data << uint8(numitems); + + float discountMod = _player->GetReputationPriceDiscount(pCreature); + + for(int i = 0; i < numitems; i++ ) + { + if(VendorItem const* crItem = vItems->GetItem(i)) + { + if(ItemPrototype const *pProto = objmgr.GetItemPrototype(crItem->item)) + { + if((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster()) + continue; + + ++count; + + // reputation discount + uint32 price = uint32(floor(pProto->BuyPrice * discountMod)); + + data << uint32(count); + data << uint32(crItem->item); + data << uint32(pProto->DisplayInfoID); + data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); + data << uint32(price); + data << uint32(pProto->MaxDurability); + data << uint32(pProto->BuyCount); + data << uint32(crItem->ExtendedCost); + } + } + } + + if ( count == 0 || data.size() != 8 + 1 + size_t(count) * 8 * 4 ) + return; + + data.put(8, count); + SendPacket( &data ); +} + +void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1+1); + + //sLog.outDebug("WORLD: CMSG_AUTOSTORE_BAG_ITEM"); + uint8 srcbag, srcslot, dstbag; + + recv_data >> srcbag >> srcslot >> dstbag; + //sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u", srcbag, srcslot, dstbag); + + Item *pItem = _player->GetItemByPos( srcbag, srcslot ); + if( !pItem ) + return; + + uint16 src = pItem->GetPos(); + + // check unequip potability for equipped items and bank bags + if(_player->IsEquipmentPos ( src ) || _player->IsBagPos ( src )) + { + uint8 msg = _player->CanUnequipItem( src, !_player->IsBagPos ( src )); + if(msg != EQUIP_ERR_OK) + { + _player->SendEquipError( msg, pItem, NULL ); + return; + } + } + + ItemPosCountVec dest; + uint8 msg = _player->CanStoreItem( dstbag, NULL_SLOT, dest, pItem, false ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pItem, NULL ); + return; + } + + // no-op: placed in same slot + if(dest.size()==1 && dest[0].pos==src) + { + // just remove grey item state + _player->SendEquipError( EQUIP_ERR_NONE, pItem, NULL ); + return; + } + + _player->RemoveItem(srcbag, srcslot, true ); + _player->StoreItem( dest, pItem, true ); +} + +void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/) +{ + sLog.outDebug("WORLD: CMSG_BUY_BANK_SLOT"); + + uint32 slot = _player->GetByteValue(PLAYER_BYTES_2, 2); + + // next slot + ++slot; + + sLog.outDetail("PLAYER: Buy bank bag slot, slot number = %u", slot); + + BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot); + + if(!slotEntry) + return; + + uint32 price = slotEntry->price; + + if (_player->GetMoney() < price) + return; + + _player->SetByteValue(PLAYER_BYTES_2, 2, slot); + _player->ModifyMoney(-int32(price)); +} + +void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,1+1); + + sLog.outDebug("WORLD: CMSG_AUTOBANK_ITEM"); + uint8 srcbag, srcslot; + + recvPacket >> srcbag >> srcslot; + sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot); + + Item *pItem = _player->GetItemByPos( srcbag, srcslot ); + if( !pItem ) + return; + + ItemPosCountVec dest; + uint8 msg = _player->CanBankItem( NULL_BAG, NULL_SLOT, dest, pItem, false ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pItem, NULL ); + return; + } + + _player->RemoveItem(srcbag, srcslot, true); + _player->BankItem( dest, pItem, true ); +} + +void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,1+1); + + sLog.outDebug("WORLD: CMSG_AUTOSTORE_BANK_ITEM"); + uint8 srcbag, srcslot; + + recvPacket >> srcbag >> srcslot; + sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot); + + Item *pItem = _player->GetItemByPos( srcbag, srcslot ); + if( !pItem ) + return; + + if(_player->IsBankPos(srcbag, srcslot)) // moving from bank to inventory + { + ItemPosCountVec dest; + uint8 msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, dest, pItem, false ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pItem, NULL ); + return; + } + + _player->RemoveItem(srcbag, srcslot, true); + _player->StoreItem( dest, pItem, true ); + } + else // moving from inventory to bank + { + ItemPosCountVec dest; + uint8 msg = _player->CanBankItem( NULL_BAG, NULL_SLOT, dest, pItem, false ); + if( msg != EQUIP_ERR_OK ) + { + _player->SendEquipError( msg, pItem, NULL ); + return; + } + + _player->RemoveItem(srcbag, srcslot, true); + _player->BankItem( dest, pItem, true ); + } +} + +void WorldSession::HandleSetAmmoOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4); + + if(!GetPlayer()->isAlive()) + { + GetPlayer()->SendEquipError( EQUIP_ERR_YOU_ARE_DEAD, NULL, NULL ); + return; + } + + sLog.outDebug("WORLD: CMSG_SET_AMMO"); + uint32 item; + + recv_data >> item; + + if(!item) + GetPlayer()->RemoveAmmo(); + else + GetPlayer()->SetAmmo(item); +} + +void WorldSession::SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID) +{ + WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4+1)); // last check 2.0.10 + data << Target; + data << Caster; + data << ItemID; + data << SpellID; + data << uint8(0); + SendPacket(&data); +} + +void WorldSession::SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid,uint32 slot,uint32 Duration) +{ + // last check 2.0.10 + WorldPacket data(SMSG_ITEM_ENCHANT_TIME_UPDATE, (8+4+4+8)); + data << uint64(Itemguid); + data << uint32(slot); + data << uint32(Duration); + data << uint64(Playerguid); + SendPacket(&data); +} + +void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 itemid; + recv_data >> itemid; + sLog.outDebug("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid); + ItemPrototype const *pProto = objmgr.GetItemPrototype( itemid ); + if( pProto ) + { + std::string Name; + Name = pProto->Name1; + + int loc_idx = GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); + if (il) + { + if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + Name = il->Name[loc_idx]; + } + } + // guess size + WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+10)); + data << uint32(pProto->ItemId); + data << Name; + data << uint32(pProto->InventoryType); + SendPacket(&data); + return; + } + else + sLog.outDebug("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (unknown item)", itemid); +} + +void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,1+1+1+1); + + sLog.outDebug("Received opcode CMSG_WRAP_ITEM"); + + uint8 gift_bag, gift_slot, item_bag, item_slot; + //recv_data.hexlike(); + + recv_data >> gift_bag >> gift_slot; // paper + recv_data >> item_bag >> item_slot; // item + + sLog.outDebug("WRAP: receive gift_bag = %u, gift_slot = %u, item_bag = %u, item_slot = %u", gift_bag, gift_slot, item_bag, item_slot); + + Item *gift = _player->GetItemByPos( gift_bag, gift_slot ); + if(!gift) + { + _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL ); + return; + } + + if(!gift->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPER))// cheating: non-wrapper wrapper + { + _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL ); + return; + } + + Item *item = _player->GetItemByPos( item_bag, item_slot ); + + if( !item ) + { + _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, item, NULL ); + return; + } + + if(item==gift) // not possable with pacjket from real client + { + _player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL ); + return; + } + + if(item->IsEquipped()) + { + _player->SendEquipError( EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, item, NULL ); + return; + } + + if(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); + { + _player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL ); + return; + } + + if(item->IsBag()) + { + _player->SendEquipError( EQUIP_ERR_BAGS_CANT_BE_WRAPPED, item, NULL ); + return; + } + + if(item->IsSoulBound()) + { + _player->SendEquipError( EQUIP_ERR_BOUND_CANT_BE_WRAPPED, item, NULL ); + return; + } + + if(item->GetMaxStackCount() != 1) + { + _player->SendEquipError( EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, item, NULL ); + return; + } + + // maybe not correct check (it is better than nothing) + if(item->GetProto()->MaxCount>0) + { + _player->SendEquipError( EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, NULL ); + return; + } + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS)); + item->SetEntry(gift->GetEntry()); + + switch (item->GetEntry()) + { + case 5042: item->SetEntry( 5043); break; + case 5048: item->SetEntry( 5044); break; + case 17303: item->SetEntry(17302); break; + case 17304: item->SetEntry(17305); break; + case 17307: item->SetEntry(17308); break; + case 21830: item->SetEntry(21831); break; + } + item->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); + item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); + item->SetState(ITEM_CHANGED, _player); + + if(item->GetState()==ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` + { + // after save it will be impossible to remove the item from the queue + item->RemoveFromUpdateQueueOf(_player); + item->SaveToDB(); // item gave inventory record unchanged and can be save standalone + } + CharacterDatabase.CommitTransaction(); + + uint32 count = 1; + _player->DestroyItemCount(gift, count, true); +} + +void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) +{ + sLog.outDebug("WORLD: CMSG_SOCKET_GEMS"); + + CHECK_PACKET_SIZE(recv_data,8*4); + + uint64 guids[4]; + uint32 GemEnchants[3], OldEnchants[3]; + Item *Gems[3]; + bool SocketBonusActivated, SocketBonusToBeActivated; + + for(int i = 0; i < 4; i++) + recv_data >> guids[i]; + + if(!guids[0]) + return; + + //cheat -> tried to socket same gem multiple times + if((guids[1] && (guids[1] == guids[2] || guids[1] == guids[3])) || (guids[2] && (guids[2] == guids[3]))) + return; + + Item *itemTarget = _player->GetItemByGuid(guids[0]); + if(!itemTarget) //missing item to socket + return; + + //this slot is excepted when applying / removing meta gem bonus + uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : NULL_SLOT; + + for(int i = 0; i < 3; i++) + Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL; + + GemPropertiesEntry const *GemProps[3]; + for(int i = 0; i < 3; ++i) //get geminfo from dbc storage + { + GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL; + } + + for(int i = 0; i < 3; ++i) //check for hack maybe + { + // tried to put gem in socket where no socket exists / tried to put normal gem in meta socket + // tried to put meta gem in normal socket + if( GemProps[i] && ( !itemTarget->GetProto()->Socket[i].Color || + itemTarget->GetProto()->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META || + itemTarget->GetProto()->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META ) ) + return; + } + + for(int i = 0; i < 3; ++i) //get new and old enchantments + { + GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0; + OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i)); + } + + // check unique-equipped conditions + for(int i = 0; i < 3; ++i) + { + if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)) + { + // for equipped item check all equipment for duplicate equipped gems + if(itemTarget->IsEquipped()) + { + if(GetPlayer()->GetItemOrItemWithGemEquipped(Gems[i]->GetEntry())) + { + _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE, itemTarget, NULL ); + return; + } + } + + // continue check for case when attempt add 2 similar unique equipped gems in one item. + for (int j = 0; j < 3; ++j) + { + if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId)) + { + _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL ); + return; + } + } + for (int j = 0; j < 3; ++j) + { + if (OldEnchants[j]) + { + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]); + if(!enchantEntry) + continue; + + if ((enchantEntry->GemID == Gems[i]->GetProto()->ItemId) && (i != j)) + { + _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL ); + return; + } + } + } + } + } + + SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus + _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item) + + //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met + + //remove ALL enchants + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),false); + + for(int i = 0; i < 3; ++i) + { + if(GemEnchants[i]) + { + itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0); + if(Item* guidItem = _player->GetItemByGuid(guids[i + 1])) + _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true ); + } + } + + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true); + + SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state + if(SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change... + { + _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,false); + itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetProto()->socketBonus : 0), 0, 0); + _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,true); + //it is not displayed, client has an inbuilt system to determine if the bonus is activated + } + + _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item) +} + +void WorldSession::HandleCancelTempItemEnchantmentOpcode(WorldPacket& recv_data) +{ + sLog.outDebug("WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT"); + + CHECK_PACKET_SIZE(recv_data,4); + + uint32 eslot; + + recv_data >> eslot; + + // apply only to equipped item + if(!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0,eslot)) + return; + + Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, eslot); + + if(!item) + return; + + if(!item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) + return; + + GetPlayer()->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false); + item->ClearEnchantment(TEMP_ENCHANTMENT_SLOT); +} diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h new file mode 100644 index 000000000..9dd7fd701 --- /dev/null +++ b/src/game/ItemPrototype.h @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ITEMPROTOTYPE_H +#define _ITEMPROTOTYPE_H + +#include "Common.h" + +enum ItemModType +{ + ITEM_MOD_MANA = 0, + ITEM_MOD_HEALTH = 1, + ITEM_MOD_AGILITY = 3, + ITEM_MOD_STRENGTH = 4, + ITEM_MOD_INTELLECT = 5, + ITEM_MOD_SPIRIT = 6, + ITEM_MOD_STAMINA = 7, + ITEM_MOD_DEFENSE_SKILL_RATING = 12, + ITEM_MOD_DODGE_RATING = 13, + ITEM_MOD_PARRY_RATING = 14, + ITEM_MOD_BLOCK_RATING = 15, + ITEM_MOD_HIT_MELEE_RATING = 16, + ITEM_MOD_HIT_RANGED_RATING = 17, + ITEM_MOD_HIT_SPELL_RATING = 18, + ITEM_MOD_CRIT_MELEE_RATING = 19, + ITEM_MOD_CRIT_RANGED_RATING = 20, + ITEM_MOD_CRIT_SPELL_RATING = 21, + ITEM_MOD_HIT_TAKEN_MELEE_RATING = 22, + ITEM_MOD_HIT_TAKEN_RANGED_RATING = 23, + ITEM_MOD_HIT_TAKEN_SPELL_RATING = 24, + ITEM_MOD_CRIT_TAKEN_MELEE_RATING = 25, + ITEM_MOD_CRIT_TAKEN_RANGED_RATING = 26, + ITEM_MOD_CRIT_TAKEN_SPELL_RATING = 27, + ITEM_MOD_HASTE_MELEE_RATING = 28, + ITEM_MOD_HASTE_RANGED_RATING = 29, + ITEM_MOD_HASTE_SPELL_RATING = 30, + ITEM_MOD_HIT_RATING = 31, + ITEM_MOD_CRIT_RATING = 32, + ITEM_MOD_HIT_TAKEN_RATING = 33, + ITEM_MOD_CRIT_TAKEN_RATING = 34, + ITEM_MOD_RESILIENCE_RATING = 35, + ITEM_MOD_HASTE_RATING = 36, + ITEM_MOD_EXPERTISE_RATING = 37 +}; + +#define MAX_ITEM_MOD 38 + +enum ItemSpelltriggerType +{ + ITEM_SPELLTRIGGER_ON_USE = 0, // use after equip cooldown + ITEM_SPELLTRIGGER_ON_EQUIP = 1, + ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2, + ITEM_SPELLTRIGGER_SOULSTONE = 4, + ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown + ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1 +}; + +#define MAX_ITEM_SPELLTRIGGER 7 + +enum ItemBondingType +{ + NO_BIND = 0, + BIND_WHEN_PICKED_UP = 1, + BIND_WHEN_EQUIPED = 2, + BIND_WHEN_USE = 3, + BIND_QUEST_ITEM = 4, + BIND_QUEST_ITEM1 = 5 // not used in game +}; + +#define MAX_BIND_TYPE 6 + +// masks for ITEM_FIELD_FLAGS field +enum ITEM_FLAGS +{ + ITEM_FLAGS_BINDED = 0x00000001, + ITEM_FLAGS_CONJURED = 0x00000002, + ITEM_FLAGS_OPENABLE = 0x00000004, + ITEM_FLAGS_WRAPPED = 0x00000008, + ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper + ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not + ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter + ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000, + ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000, + ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip + ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0 + ITEM_FLAGS_BOA = 0x08000000, // bind on account + ITEM_FLAGS_MILLABLE = 0x20000000 +}; + +enum BAG_FAMILY_MASK +{ + BAG_FAMILY_MASK_ARROWS = 0x00000001, + BAG_FAMILY_MASK_BULLETS = 0x00000002, + BAG_FAMILY_MASK_SOUL_SHARDS = 0x00000004, + BAG_FAMILY_MASK_LEATHERWORKING_SUPP = 0x00000008, + BAG_FAMILY_MASK_INSCRIPTION_SUPP = 0x00000010, + BAG_FAMILY_MASK_HERBS = 0x00000020, + BAG_FAMILY_MASK_ENCHANTING_SUPP = 0x00000040, + BAG_FAMILY_MASK_ENGINEERING_SUPP = 0x00000080, + BAG_FAMILY_MASK_KEYS = 0x00000100, + BAG_FAMILY_MASK_GEMS = 0x00000200, + BAG_FAMILY_MASK_MINING_SUPP = 0x00000400, + BAG_FAMILY_MASK_SOULBOUND_EQUIPMENT = 0x00000800, + BAG_FAMILY_MASK_VANITY_PETS = 0x00001000, + BAG_FAMILY_MASK_CURRENCY_TOKENS = 0x00002000, + BAG_FAMILY_MASK_QUEST_ITEMS = 0x00004000 +}; + +enum SocketColor +{ + SOCKET_COLOR_META = 1, + SOCKET_COLOR_RED = 2, + SOCKET_COLOR_YELLOW = 4, + SOCKET_COLOR_BLUE = 8 +}; + +#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE) + +enum InventoryType +{ + INVTYPE_NON_EQUIP = 0, + INVTYPE_HEAD = 1, + INVTYPE_NECK = 2, + INVTYPE_SHOULDERS = 3, + INVTYPE_BODY = 4, + INVTYPE_CHEST = 5, + INVTYPE_WAIST = 6, + INVTYPE_LEGS = 7, + INVTYPE_FEET = 8, + INVTYPE_WRISTS = 9, + INVTYPE_HANDS = 10, + INVTYPE_FINGER = 11, + INVTYPE_TRINKET = 12, + INVTYPE_WEAPON = 13, + INVTYPE_SHIELD = 14, + INVTYPE_RANGED = 15, + INVTYPE_CLOAK = 16, + INVTYPE_2HWEAPON = 17, + INVTYPE_BAG = 18, + INVTYPE_TABARD = 19, + INVTYPE_ROBE = 20, + INVTYPE_WEAPONMAINHAND = 21, + INVTYPE_WEAPONOFFHAND = 22, + INVTYPE_HOLDABLE = 23, + INVTYPE_AMMO = 24, + INVTYPE_THROWN = 25, + INVTYPE_RANGEDRIGHT = 26, + INVTYPE_QUIVER = 27, + INVTYPE_RELIC = 28 +}; + +#define MAX_INVTYPE 29 + +enum ItemClass +{ + ITEM_CLASS_CONSUMABLE = 0, + ITEM_CLASS_CONTAINER = 1, + ITEM_CLASS_WEAPON = 2, + ITEM_CLASS_GEM = 3, + ITEM_CLASS_ARMOR = 4, + ITEM_CLASS_REAGENT = 5, + ITEM_CLASS_PROJECTILE = 6, + ITEM_CLASS_TRADE_GOODS = 7, + ITEM_CLASS_GENERIC = 8, + ITEM_CLASS_RECIPE = 9, + ITEM_CLASS_MONEY = 10, + ITEM_CLASS_QUIVER = 11, + ITEM_CLASS_QUEST = 12, + ITEM_CLASS_KEY = 13, + ITEM_CLASS_PERMANENT = 14, + ITEM_CLASS_JUNK = 15 +}; + +#define MAX_ITEM_CLASS 16 + +enum ItemSubclassConsumable +{ + ITEM_SUBCLASS_CONSUMABLE = 0, + ITEM_SUBCLASS_POTION = 1, + ITEM_SUBCLASS_ELIXIR = 2, + ITEM_SUBCLASS_FLASK = 3, + ITEM_SUBCLASS_SCROLL = 4, + ITEM_SUBCLASS_FOOD = 5, + ITEM_SUBCLASS_ITEM_ENHANCEMENT = 6, + ITEM_SUBCLASS_BANDAGE = 7, + ITEM_SUBCLASS_CONSUMABLE_OTHER = 8 +}; + +#define MAX_ITEM_SUBCLASS_CONSUMABLE 9 + +enum ItemSubclassContainer +{ + ITEM_SUBCLASS_CONTAINER = 0, + ITEM_SUBCLASS_SOUL_CONTAINER = 1, + ITEM_SUBCLASS_HERB_CONTAINER = 2, + ITEM_SUBCLASS_ENCHANTING_CONTAINER = 3, + ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4, + ITEM_SUBCLASS_GEM_CONTAINER = 5, + ITEM_SUBCLASS_MINING_CONTAINER = 6, + ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7 +}; + +#define MAX_ITEM_SUBCLASS_CONTAINER 8 + +enum ItemSubclassWeapon +{ + ITEM_SUBCLASS_WEAPON_AXE = 0, + ITEM_SUBCLASS_WEAPON_AXE2 = 1, + ITEM_SUBCLASS_WEAPON_BOW = 2, + ITEM_SUBCLASS_WEAPON_GUN = 3, + ITEM_SUBCLASS_WEAPON_MACE = 4, + ITEM_SUBCLASS_WEAPON_MACE2 = 5, + ITEM_SUBCLASS_WEAPON_POLEARM = 6, + ITEM_SUBCLASS_WEAPON_SWORD = 7, + ITEM_SUBCLASS_WEAPON_SWORD2 = 8, + ITEM_SUBCLASS_WEAPON_obsolete = 9, + ITEM_SUBCLASS_WEAPON_STAFF = 10, + ITEM_SUBCLASS_WEAPON_EXOTIC = 11, + ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12, + ITEM_SUBCLASS_WEAPON_FIST = 13, + ITEM_SUBCLASS_WEAPON_MISC = 14, + ITEM_SUBCLASS_WEAPON_DAGGER = 15, + ITEM_SUBCLASS_WEAPON_THROWN = 16, + ITEM_SUBCLASS_WEAPON_SPEAR = 17, + ITEM_SUBCLASS_WEAPON_CROSSBOW = 18, + ITEM_SUBCLASS_WEAPON_WAND = 19, + ITEM_SUBCLASS_WEAPON_FISHING_POLE = 20 +}; + +#define MAX_ITEM_SUBCLASS_WEAPON 21 + +enum ItemSubclassGem +{ + ITEM_SUBCLASS_GEM_RED = 0, + ITEM_SUBCLASS_GEM_BLUE = 1, + ITEM_SUBCLASS_GEM_YELLOW = 2, + ITEM_SUBCLASS_GEM_PURPLE = 3, + ITEM_SUBCLASS_GEM_GREEN = 4, + ITEM_SUBCLASS_GEM_ORANGE = 5, + ITEM_SUBCLASS_GEM_META = 6, + ITEM_SUBCLASS_GEM_SIMPLE = 7, + ITEM_SUBCLASS_GEM_PRISMATIC = 8 +}; + +#define MAX_ITEM_SUBCLASS_GEM 9 + +enum ItemSubclassArmor +{ + ITEM_SUBCLASS_ARMOR_MISC = 0, + ITEM_SUBCLASS_ARMOR_CLOTH = 1, + ITEM_SUBCLASS_ARMOR_LEATHER = 2, + ITEM_SUBCLASS_ARMOR_MAIL = 3, + ITEM_SUBCLASS_ARMOR_PLATE = 4, + ITEM_SUBCLASS_ARMOR_BUCKLER = 5, + ITEM_SUBCLASS_ARMOR_SHIELD = 6, + ITEM_SUBCLASS_ARMOR_LIBRAM = 7, + ITEM_SUBCLASS_ARMOR_IDOL = 8, + ITEM_SUBCLASS_ARMOR_TOTEM = 9 +}; + +#define MAX_ITEM_SUBCLASS_ARMOR 10 + +enum ItemSubclassReagent +{ + ITEM_SUBCLASS_REAGENT = 0 +}; + +#define MAX_ITEM_SUBCLASS_REAGENT 1 + +enum ItemSubclassProjectile +{ + ITEM_SUBCLASS_WAND = 0, // ABS + ITEM_SUBCLASS_BOLT = 1, // ABS + ITEM_SUBCLASS_ARROW = 2, + ITEM_SUBCLASS_BULLET = 3, + ITEM_SUBCLASS_THROWN = 4 // ABS +}; + +#define MAX_ITEM_SUBCLASS_PROJECTILE 5 + +enum ItemSubclassTradeGoods +{ + ITEM_SUBCLASS_TRADE_GOODS = 0, + ITEM_SUBCLASS_PARTS = 1, + ITEM_SUBCLASS_EXPLOSIVES = 2, + ITEM_SUBCLASS_DEVICES = 3, + ITEM_SUBCLASS_JEWELCRAFTING = 4, + ITEM_SUBCLASS_CLOTH = 5, + ITEM_SUBCLASS_LEATHER = 6, + ITEM_SUBCLASS_METAL_STONE = 7, + ITEM_SUBCLASS_MEAT = 8, + ITEM_SUBCLASS_HERB = 9, + ITEM_SUBCLASS_ELEMENTAL = 10, + ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11, + ITEM_SUBCLASS_ENCHANTING = 12, + ITEM_SUBCLASS_MATERIAL = 13 // Added in 2.4.2 +}; + +#define MAX_ITEM_SUBCLASS_TRADE_GOODS 14 + +enum ItemSubclassGeneric +{ + ITEM_SUBCLASS_GENERIC = 0 +}; + +#define MAX_ITEM_SUBCLASS_GENERIC 1 + +enum ItemSubclassRecipe +{ + ITEM_SUBCLASS_BOOK = 0, + ITEM_SUBCLASS_LEATHERWORKING_PATTERN = 1, + ITEM_SUBCLASS_TAILORING_PATTERN = 2, + ITEM_SUBCLASS_ENGINEERING_SCHEMATIC = 3, + ITEM_SUBCLASS_BLACKSMITHING = 4, + ITEM_SUBCLASS_COOKING_RECIPE = 5, + ITEM_SUBCLASS_ALCHEMY_RECIPE = 6, + ITEM_SUBCLASS_FIRST_AID_MANUAL = 7, + ITEM_SUBCLASS_ENCHANTING_FORMULA = 8, + ITEM_SUBCLASS_FISHING_MANUAL = 9, + ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10 +}; + +#define MAX_ITEM_SUBCLASS_RECIPE 11 + +enum ItemSubclassMoney +{ + ITEM_SUBCLASS_MONEY = 0 +}; + +#define MAX_ITEM_SUBCLASS_MONEY 1 + +enum ItemSubclassQuiver +{ + ITEM_SUBCLASS_QUIVER0 = 0, // ABS + ITEM_SUBCLASS_QUIVER1 = 1, // ABS + ITEM_SUBCLASS_QUIVER = 2, + ITEM_SUBCLASS_AMMO_POUCH = 3 +}; + +#define MAX_ITEM_SUBCLASS_QUIVER 4 + +enum ItemSubclassQuest +{ + ITEM_SUBCLASS_QUEST = 0 +}; + +#define MAX_ITEM_SUBCLASS_QUEST 1 + +enum ItemSubclassKey +{ + ITEM_SUBCLASS_KEY = 0, + ITEM_SUBCLASS_LOCKPICK = 1 +}; + +#define MAX_ITEM_SUBCLASS_KEY 2 + +enum ItemSubclassPermanent +{ + ITEM_SUBCLASS_PERMANENT = 0 +}; + +#define MAX_ITEM_SUBCLASS_PERMANENT 1 + +enum ItemSubclassJunk +{ + ITEM_SUBCLASS_JUNK = 0, + ITEM_SUBCLASS_JUNK_REAGENT = 1, + ITEM_SUBCLASS_JUNK_PET = 2, + ITEM_SUBCLASS_JUNK_HOLIDAY = 3, + ITEM_SUBCLASS_JUNK_OTHER = 4, + ITEM_SUBCLASS_JUNK_MOUNT = 5 +}; + +#define MAX_ITEM_SUBCLASS_JUNK 6 + +enum ItemSubclassGlyph +{ + ITEM_SUBCLASS_GLYPH_WARRIOR = 1, + ITEM_SUBCLASS_GLYPH_PALADIN = 2, + ITEM_SUBCLASS_GLYPH_HUNTER = 3, + ITEM_SUBCLASS_GLYPH_ROGUE = 4, + ITEM_SUBCLASS_GLYPH_PRIEST = 5, + ITEM_SUBCLASS_GLYPH_DEATH_KNIGHT = 6, + ITEM_SUBCLASS_GLYPH_SHAMAN = 7, + ITEM_SUBCLASS_GLYPH_MAGE = 8, + ITEM_SUBCLASS_GLYPH_WARLOCK = 9, + ITEM_SUBCLASS_GLYPH_DRUID = 11 +}; + +#define MAX_ITEM_SUBCLASS_GLYPH 12 + +const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = +{ + MAX_ITEM_SUBCLASS_CONSUMABLE, + MAX_ITEM_SUBCLASS_CONTAINER, + MAX_ITEM_SUBCLASS_WEAPON, + MAX_ITEM_SUBCLASS_GEM, + MAX_ITEM_SUBCLASS_ARMOR, + MAX_ITEM_SUBCLASS_REAGENT, + MAX_ITEM_SUBCLASS_PROJECTILE, + MAX_ITEM_SUBCLASS_TRADE_GOODS, + MAX_ITEM_SUBCLASS_GENERIC, + MAX_ITEM_SUBCLASS_RECIPE, + MAX_ITEM_SUBCLASS_MONEY, + MAX_ITEM_SUBCLASS_QUIVER, + MAX_ITEM_SUBCLASS_QUEST, + MAX_ITEM_SUBCLASS_KEY, + MAX_ITEM_SUBCLASS_PERMANENT, + MAX_ITEM_SUBCLASS_JUNK +}; + +inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass) +{ + switch(ItemClass) + { + case ITEM_CLASS_WEAPON: return ItemSubClass; + case ITEM_CLASS_ARMOR: return ItemSubClass + 21; + } + return 0; +} + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct _Damage +{ + float DamageMin; + float DamageMax; + uint32 DamageType; // id from Resistances.dbc + +}; + +struct _ItemStat +{ + uint32 ItemStatType; + int32 ItemStatValue; + +}; +struct _Spell +{ + uint32 SpellId; // id from Spell.dbc + uint32 SpellTrigger; + int32 SpellCharges; + float SpellPPMRate; + int32 SpellCooldown; + uint32 SpellCategory; // id from SpellCategory.dbc + int32 SpellCategoryCooldown; + +}; + +struct _Socket +{ + uint32 Color; + uint32 Content; +}; + +struct ItemPrototype +{ + uint32 ItemId; + uint32 Class; // id from ItemClass.dbc + uint32 SubClass; // id from ItemSubClass.dbc + uint32 Unk0; + char* Name1; + uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc + uint32 Quality; + uint32 Flags; + uint32 BuyCount; + uint32 BuyPrice; + uint32 SellPrice; + uint32 InventoryType; + uint32 AllowableClass; + uint32 AllowableRace; + uint32 ItemLevel; + uint32 RequiredLevel; + uint32 RequiredSkill; // id from SkillLine.dbc + uint32 RequiredSkillRank; + uint32 RequiredSpell; // id from Spell.dbc + uint32 RequiredHonorRank; + uint32 RequiredCityRank; + uint32 RequiredReputationFaction; // id from Faction.dbc + uint32 RequiredReputationRank; + uint32 MaxCount; + uint32 Stackable; + uint32 ContainerSlots; + _ItemStat ItemStat[10]; + _Damage Damage[5]; + uint32 Armor; + uint32 HolyRes; + uint32 FireRes; + uint32 NatureRes; + uint32 FrostRes; + uint32 ShadowRes; + uint32 ArcaneRes; + uint32 Delay; + uint32 Ammo_type; + float RangedModRange; + + _Spell Spells[5]; + uint32 Bonding; + char* Description; + uint32 PageText; + uint32 LanguageID; + uint32 PageMaterial; + uint32 StartQuest; // id from QuestCache.wdb + uint32 LockID; + uint32 Material; // id from Material.dbc + uint32 Sheath; + uint32 RandomProperty; // id from ItemRandomProperties.dbc + uint32 RandomSuffix; // id from ItemRandomSuffix.dbc + uint32 Block; + uint32 ItemSet; // id from ItemSet.dbc + uint32 MaxDurability; + uint32 Area; // id from AreaTable.dbc + uint32 Map; // id from Map.dbc + uint32 BagFamily; // id from ItemBagFamily.dbc + uint32 TotemCategory; // id from TotemCategory.dbc + _Socket Socket[3]; + uint32 socketBonus; // id from SpellItemEnchantment.dbc + uint32 GemProperties; // id from GemProperties.dbc + uint32 RequiredDisenchantSkill; + float ArmorDamageModifier; + char* ScriptName; + uint32 DisenchantID; + uint32 FoodType; + uint32 MinMoneyLoot; + uint32 MaxMoneyLoot; + int32 Duration; // negative = realtime, positive = ingame time + + // helpers + bool CanChangeEquipStateInCombat() const + { + switch(InventoryType) + { + case INVTYPE_RELIC: + case INVTYPE_SHIELD: + return true; + } + + switch(Class) + { + case ITEM_CLASS_WEAPON: + case ITEM_CLASS_PROJECTILE: + return true; + } + + return false; + } +}; + +struct ItemLocale +{ + std::vector Name; + std::vector Description; +}; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif +#endif diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp new file mode 100644 index 000000000..09655eac8 --- /dev/null +++ b/src/game/LFGHandler.cpp @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "WorldSession.h" +#include "Log.h" +#include "Database/DatabaseEnv.h" +#include "Player.h" +#include "WorldPacket.h" +#include "ObjectMgr.h" +#include "World.h" + +static void AttemptJoin(Player* _player) +{ + // skip not can autojoin cases and player group case + if(!_player->m_lookingForGroup.canAutoJoin() || _player->GetGroup()) + return; + + //TODO: Guard Player Map + HashMapHolder::MapType const& players = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter) + { + Player *plr = iter->second; + + // skip enemies and self + if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam()) + continue; + + // skip not auto add, not group leader cases + if(!plr->GetSession()->LookingForGroup_auto_add || plr->GetGroup() && plr->GetGroup()->GetLeaderGUID()!=plr->GetGUID()) + continue; + + // skip non auto-join or empty slots, or non compatible slots + if(!plr->m_lookingForGroup.more.canAutoJoin() || !_player->m_lookingForGroup.HaveInSlot(plr->m_lookingForGroup.more)) + continue; + + // attempt create group, or skip + if(!plr->GetGroup()) + { + Group* group = new Group; + if(!group->Create(plr->GetGUID(), plr->GetName())) + { + delete group; + continue; + } + + objmgr.AddGroup(group); + } + + // stop at success join + if(plr->GetGroup()->AddMember(_player->GetGUID(), _player->GetName())) + { + if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER ) + _player->LeaveLFGChannel(); + break; + } + // full + else + { + if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER ) + plr->LeaveLFGChannel(); + } + } +} + +static void AttemptAddMore(Player* _player) +{ + // skip not group leader case + if(_player->GetGroup() && _player->GetGroup()->GetLeaderGUID()!=_player->GetGUID()) + return; + + if(!_player->m_lookingForGroup.more.canAutoJoin()) + return; + + //TODO: Guard Player map + HashMapHolder::MapType const& players = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter) + { + Player *plr = iter->second; + + // skip enemies and self + if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam()) + continue; + + // skip not auto join or in group + if(!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup() ) + continue; + + if(!plr->m_lookingForGroup.HaveInSlot(_player->m_lookingForGroup.more)) + continue; + + // attempt create group if need, or stop attempts + if(!_player->GetGroup()) + { + Group* group = new Group; + if(!group->Create(_player->GetGUID(), _player->GetName())) + { + delete group; + return; // cann't create group (??) + } + + objmgr.AddGroup(group); + } + + // stop at join fail (full) + if(!_player->GetGroup()->AddMember(plr->GetGUID(), plr->GetName()) ) + { + if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER ) + _player->LeaveLFGChannel(); + + break; + } + + // joined + if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER ) + plr->LeaveLFGChannel(); + + // and group full + if(_player->GetGroup()->IsFull() ) + { + if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER ) + _player->LeaveLFGChannel(); + + break; + } + } +} + +void WorldSession::HandleLfgAutoJoinOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("CMSG_SET_LFG_AUTO_JOIN"); + LookingForGroup_auto_join = true; + + if(!_player) // needed because STATUS_AUTHED + return; + + AttemptJoin(_player); +} + +void WorldSession::HandleLfgCancelAutoJoinOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("CMSG_UNSET_LFG_AUTO_JOIN"); + LookingForGroup_auto_join = false; +} + +void WorldSession::HandleLfmAutoAddMembersOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("CMSG_SET_LFM_AUTOADD"); + LookingForGroup_auto_add = true; + + if(!_player) // needed because STATUS_AUTHED + return; + + AttemptAddMore(_player); +} + +void WorldSession::HandleLfmCancelAutoAddmembersOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("CMSG_UNSET_LFM_AUTOADD"); + LookingForGroup_auto_add = false; +} + +void WorldSession::HandleLfgClearOpcode( WorldPacket & /*recv_data */ ) +{ + sLog.outDebug("CMSG_LOOKING_FOR_GROUP_CLEAR"); + + for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i) + _player->m_lookingForGroup.slots[i].Clear(); + + if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER ) + _player->LeaveLFGChannel(); +} + +void WorldSession::HandleLfmSetNoneOpcode( WorldPacket & /*recv_data */) +{ + sLog.outDebug("CMSG_SET_LOOKING_FOR_NONE"); + + _player->m_lookingForGroup.more.Clear(); +} + +void WorldSession::HandleLfmSetOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4); + + sLog.outDebug("CMSG_SET_LOOKING_FOR_MORE"); + //recv_data.hexlike(); + uint32 temp, entry, type; + + recv_data >> temp; + + entry = ( temp & 0xFFFF); + type = ( (temp >> 24) & 0xFFFF); + + _player->m_lookingForGroup.more.Set(entry,type); + sLog.outDebug("LFM set: temp %u, zone %u, type %u", temp, entry, type); + + if(LookingForGroup_auto_add) + AttemptAddMore(_player); + + SendLfgResult(type, entry, 1); +} + +void WorldSession::HandleLfgSetCommentOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1); + + sLog.outDebug("CMSG_SET_COMMENTARY"); + //recv_data.hexlike(); + + std::string comment; + recv_data >> comment; + sLog.outDebug("LFG comment %s", comment.c_str()); + + _player->m_lookingForGroup.comment = comment; +} + +void WorldSession::HandleLookingForGroup(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4+4+4); + + sLog.outDebug("MSG_LOOKING_FOR_GROUP"); + //recv_data.hexlike(); + uint32 type, entry, unk; + + recv_data >> type >> entry >> unk; + sLog.outDebug("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type, entry, unk); + + if(LookingForGroup_auto_add) + AttemptAddMore(_player); + + if(LookingForGroup_auto_join) + AttemptJoin(_player); + + SendLfgResult(type, entry, 0); +} + +void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type) +{ + uint32 number = 0; + + // start preper packet; + WorldPacket data(MSG_LOOKING_FOR_GROUP); + data << uint32(type); // type + data << uint32(entry); // entry from LFGDungeons.dbc + data << uint32(0); // count, placeholder + data << uint32(0); // count again, strange, placeholder + + //TODO: Guard Player map + HashMapHolder::MapType const& players = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter) + { + Player *plr = iter->second; + + if(!plr || plr->GetTeam() != _player->GetTeam()) + continue; + + if(!plr->m_lookingForGroup.HaveInSlot(entry,type)) + continue; + + ++number; + + data.append(plr->GetPackGUID()); // packed guid + data << plr->getLevel(); // level + data << plr->GetZoneId(); // current zone + data << lfg_type; // 0x00 - LFG, 0x01 - LFM + + for(uint8 j = 0; j < MAX_LOOKING_FOR_GROUP_SLOT; ++j) + { + data << uint32( plr->m_lookingForGroup.slots[j].entry | (plr->m_lookingForGroup.slots[j].type << 24) ); + } + data << plr->m_lookingForGroup.comment; + + Group *group = plr->GetGroup(); + if(group) + { + data << group->GetMembersCount()-1; // count of group members without group leader + for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *member = itr->getSource(); + if(member && member->GetGUID() != plr->GetGUID()) + { + data.append(member->GetPackGUID()); // packed guid + data << member->getLevel(); // player level + } + } + } + else + { + data << uint32(0x00); + } + } + + // fill count placeholders + data.put(4+4, number); + data.put(4+4+4,number); + + SendPacket(&data); +} + +void WorldSession::HandleSetLfgOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+4); + + sLog.outDebug("CMSG_SET_LOOKING_FOR_GROUP"); + //recv_data.hexlike(); + uint32 slot, temp, entry, type; + + recv_data >> slot >> temp; + + entry = ( temp & 0xFFFF); + type = ( (temp >> 24) & 0xFFFF); + + if(slot >= MAX_LOOKING_FOR_GROUP_SLOT) + return; + + _player->m_lookingForGroup.slots[slot].Set(entry,type); + sLog.outDebug("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, temp, type, entry); + + if(LookingForGroup_auto_join) + AttemptJoin(_player); + + SendLfgResult(type, entry, 0); +} diff --git a/src/game/Language.h b/src/game/Language.h new file mode 100644 index 000000000..4d4c155cf --- /dev/null +++ b/src/game/Language.h @@ -0,0 +1,645 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MANGOS_LANGUAGE_H +#define __MANGOS_LANGUAGE_H + +enum MangosStrings +{ + // for chat commands + LANG_SELECT_CHAR_OR_CREATURE = 1, + LANG_SELECT_CREATURE = 2, + + // level 0 chat + LANG_SYSTEMMESSAGE = 3, + LANG_EVENTMESSAGE = 4, + LANG_NO_HELP_CMD = 5, + LANG_NO_CMD = 6, + LANG_NO_SUBCMD = 7, + LANG_SUBCMDS_LIST = 8, + LANG_AVIABLE_CMD = 9, + LANG_CMD_SYNTAX = 10, + LANG_ACCOUNT_LEVEL = 11, + LANG_CONNECTED_USERS = 12, + LANG_UPTIME = 13, + LANG_PLAYER_SAVED = 14, + LANG_PLAYERS_SAVED = 15, + LANG_GMS_ON_SRV = 16, + LANG_GMS_NOT_LOGGED = 17, + LANG_YOU_IN_FLIGHT = 18, + //LANG_YOU_IN_BATTLEGROUND = 19, not used + //LANG_TARGET_IN_FLIGHT = 20, not used + LANG_CHAR_IN_FLIGHT = 21, + LANG_CHAR_NON_MOUNTED = 22, + LANG_YOU_IN_COMBAT = 23, + LANG_YOU_USED_IT_RECENTLY = 24, + LANG_COMMAND_NOTCHANGEPASSWORD = 25, + LANG_COMMAND_PASSWORD = 26, + LANG_COMMAND_WRONGOLDPASSWORD = 27, + LANG_COMMAND_ACCLOCKLOCKED = 28, + LANG_COMMAND_ACCLOCKUNLOCKED = 29, + LANG_SPELL_RANK = 30, + LANG_KNOWN = 31, + LANG_LEARN = 32, + LANG_PASSIVE = 33, + LANG_TALENT = 34, + LANG_ACTIVE = 35, + LANG_COMPLETE = 36, + LANG_OFFLINE = 37, + LANG_ON = 38, + LANG_OFF = 39, + LANG_YOU_ARE = 40, + LANG_VISIBLE = 41, + LANG_INVISIBLE = 42, + LANG_DONE = 43, + LANG_YOU = 44, + LANG_UNKNOWN = 45, + LANG_ERROR = 46, + LANG_NON_EXIST_CHARACTER = 47, + LANG_FRIEND_IGNORE_UNKNOWN = 48, + LANG_LEVEL_MINREQUIRED = 49, + LANG_LEVEL_MINREQUIRED_AND_ITEM = 50, + LANG_NPC_TAINER_HELLO = 51, + LANG_COMMAND_INVALID_ITEM_COUNT = 52, + LANG_COMMAND_MAIL_ITEMS_LIMIT = 53, + // Room for more level 0 54-99 not used + + // level 1 chat + LANG_GLOBAL_NOTIFY = 100, + LANG_MAP_POSITION = 101, + LANG_IS_TELEPORTED = 102, + LANG_CANNOT_SUMMON_TO_INST = 103, + LANG_CANNOT_GO_TO_INST_PARTY = 104, + LANG_CANNOT_GO_TO_INST_GM = 105, + LANG_CANNOT_GO_INST_INST = 106, + LANG_CANNOT_SUMMON_INST_INST = 107, + + LANG_SUMMONING = 108, + LANG_SUMMONED_BY = 109, + LANG_TELEPORTING_TO = 110, + LANG_TELEPORTED_TO_BY = 111, + LANG_NO_PLAYER = 112, + LANG_APPEARING_AT = 113, + LANG_APPEARING_TO = 114, + + LANG_BAD_VALUE = 115, + LANG_NO_CHAR_SELECTED = 116, + LANG_NOT_IN_GROUP = 117, + + LANG_YOU_CHANGE_HP = 118, + LANG_YOURS_HP_CHANGED = 119, + LANG_YOU_CHANGE_MANA = 120, + LANG_YOURS_MANA_CHANGED = 121, + LANG_YOU_CHANGE_ENERGY = 122, + LANG_YOURS_ENERGY_CHANGED = 123, + + LANG_CURRENT_ENERGY = 124, //log + LANG_YOU_CHANGE_RAGE = 125, + LANG_YOURS_RAGE_CHANGED = 126, + LANG_YOU_CHANGE_LVL = 127, + LANG_CURRENT_FACTION = 128, + LANG_WRONG_FACTION = 129, + LANG_YOU_CHANGE_FACTION = 130, + LANG_YOU_CHANGE_SPELLFLATID = 131, + LANG_YOURS_SPELLFLATID_CHANGED = 132, + LANG_YOU_GIVE_TAXIS = 133, + LANG_YOU_REMOVE_TAXIS = 134, + LANG_YOURS_TAXIS_ADDED = 135, + LANG_YOURS_TAXIS_REMOVED = 136, + + LANG_YOU_CHANGE_ASPEED = 137, + LANG_YOURS_ASPEED_CHANGED = 138, + LANG_YOU_CHANGE_SPEED = 139, + LANG_YOURS_SPEED_CHANGED = 140, + LANG_YOU_CHANGE_SWIM_SPEED = 141, + LANG_YOURS_SWIM_SPEED_CHANGED = 142, + LANG_YOU_CHANGE_BACK_SPEED = 143, + LANG_YOURS_BACK_SPEED_CHANGED = 144, + LANG_YOU_CHANGE_FLY_SPEED = 145, + LANG_YOURS_FLY_SPEED_CHANGED = 146, + + LANG_YOU_CHANGE_SIZE = 147, + LANG_YOURS_SIZE_CHANGED = 148, + LANG_NO_MOUNT = 149, + LANG_YOU_GIVE_MOUNT = 150, + LANG_MOUNT_GIVED = 151, + + LANG_CURRENT_MONEY = 152, + LANG_YOU_TAKE_ALL_MONEY = 153, + LANG_YOURS_ALL_MONEY_GONE = 154, + LANG_YOU_TAKE_MONEY = 155, + LANG_YOURS_MONEY_TAKEN = 156, + LANG_YOU_GIVE_MONEY = 157, + LANG_YOURS_MONEY_GIVEN = 158, + LANG_YOU_HEAR_SOUND = 159, + + LANG_NEW_MONEY = 160, // Log + + LANG_REMOVE_BIT = 161, + LANG_SET_BIT = 162, + LANG_COMMAND_TELE_TABLEEMPTY = 163, + LANG_COMMAND_TELE_NOTFOUND = 164, + LANG_COMMAND_TELE_PARAMETER = 165, + LANG_COMMAND_TELE_NOLOCATION = 166, + // 167 // not used + LANG_COMMAND_TELE_LOCATION = 168, + + LANG_MAIL_SENT = 169, + LANG_SOUND_NOT_EXIST = 170, + // Room for more level 1 171-199 not used + + // level 2 chat + LANG_NO_SELECTION = 200, + LANG_OBJECT_GUID = 201, + LANG_TOO_LONG_NAME = 202, + LANG_CHARS_ONLY = 203, + LANG_TOO_LONG_SUBNAME = 204, + LANG_NOT_IMPLEMENTED = 205, + + LANG_ITEM_ADDED_TO_LIST = 206, + LANG_ITEM_NOT_FOUND = 207, + LANG_ITEM_DELETED_FROM_LIST = 208, + LANG_ITEM_NOT_IN_LIST = 209, + LANG_ITEM_ALREADY_IN_LIST = 210, + + LANG_RESET_SPELLS_ONLINE = 211, + LANG_RESET_SPELLS_OFFLINE = 212, + LANG_RESET_TALENTS_ONLINE = 213, + LANG_RESET_TALENTS_OFFLINE = 214, + LANG_RESET_SPELLS = 215, + LANG_RESET_TALENTS = 216, + + LANG_RESETALL_UNKNOWN_CASE = 217, + LANG_RESETALL_SPELLS = 218, + LANG_RESETALL_TALENTS = 219, + + LANG_WAYPOINT_NOTFOUND = 220, + LANG_WAYPOINT_NOTFOUNDLAST = 221, + LANG_WAYPOINT_NOTFOUNDSEARCH = 222, + LANG_WAYPOINT_NOTFOUNDDBPROBLEM = 223, + LANG_WAYPOINT_CREATSELECTED = 224, + LANG_WAYPOINT_CREATNOTFOUND = 225, + LANG_WAYPOINT_VP_SELECT = 226, + LANG_WAYPOINT_VP_NOTFOUND = 227, + LANG_WAYPOINT_VP_NOTCREATED = 228, + LANG_WAYPOINT_VP_ALLREMOVED = 229, + LANG_WAYPOINT_NOTCREATED = 230, + LANG_WAYPOINT_NOGUID = 231, + LANG_WAYPOINT_NOWAYPOINTGIVEN = 232, + LANG_WAYPOINT_ARGUMENTREQ = 233, + LANG_WAYPOINT_ADDED = 234, + LANG_WAYPOINT_ADDED_NO = 235, + LANG_WAYPOINT_CHANGED = 236, + LANG_WAYPOINT_CHANGED_NO = 237, + LANG_WAYPOINT_EXPORTED = 238, + LANG_WAYPOINT_NOTHINGTOEXPORT = 239, + LANG_WAYPOINT_IMPORTED = 240, + LANG_WAYPOINT_REMOVED = 241, + LANG_WAYPOINT_NOTREMOVED = 242, + LANG_WAYPOINT_TOOFAR1 = 243, + LANG_WAYPOINT_TOOFAR2 = 244, + LANG_WAYPOINT_TOOFAR3 = 245, + LANG_WAYPOINT_INFO_TITLE = 246, + LANG_WAYPOINT_INFO_WAITTIME = 247, + LANG_WAYPOINT_INFO_MODEL = 248, + LANG_WAYPOINT_INFO_EMOTE = 249, + LANG_WAYPOINT_INFO_SPELL = 250, + LANG_WAYPOINT_INFO_TEXT = 251, + LANG_WAYPOINT_INFO_AISCRIPT = 252, + + LANG_RENAME_PLAYER = 253, + LANG_RENAME_PLAYER_GUID = 254, + + LANG_WAYPOINT_WPCREATNOTFOUND = 255, + LANG_WAYPOINT_NPCNOTFOUND = 256, + + LANG_MOVE_TYPE_SET = 257, + LANG_MOVE_TYPE_SET_NODEL = 258, + LANG_USE_BOL = 259, + LANG_VALUE_SAVED = 260, + LANG_VALUE_SAVED_REJOIN = 261, + + LANG_COMMAND_GOAREATRNOTFOUND = 262, + LANG_INVALID_TARGET_COORD = 263, + LANG_INVALID_ZONE_COORD = 264, + LANG_INVALID_ZONE_MAP = 265, + LANG_COMMAND_TARGETOBJNOTFOUND = 266, + LANG_COMMAND_GOOBJNOTFOUND = 267, + LANG_COMMAND_GOCREATNOTFOUND = 268, + LANG_COMMAND_GOCREATMULTIPLE = 269, + LANG_COMMAND_DELCREATMESSAGE = 270, + LANG_COMMAND_CREATUREMOVED = 271, + LANG_COMMAND_CREATUREATSAMEMAP = 272, + LANG_COMMAND_OBJNOTFOUND = 273, + LANG_COMMAND_DELOBJREFERCREATURE = 274, + LANG_COMMAND_DELOBJMESSAGE = 275, + LANG_COMMAND_TURNOBJMESSAGE = 276, + LANG_COMMAND_MOVEOBJMESSAGE = 277, + LANG_COMMAND_VENDORSELECTION = 278, + LANG_COMMAND_NEEDITEMSEND = 279, + LANG_COMMAND_ADDVENDORITEMITEMS = 280, + LANG_COMMAND_KICKSELF = 281, + LANG_COMMAND_KICKMESSAGE = 282, + LANG_COMMAND_KICKNOTFOUNDPLAYER = 283, + LANG_COMMAND_WHISPERACCEPTING = 284, + LANG_COMMAND_WHISPERON = 285, + LANG_COMMAND_WHISPEROFF = 286, + LANG_COMMAND_CREATGUIDNOTFOUND = 287, + LANG_COMMAND_TICKETCOUNT = 288, + LANG_COMMAND_TICKETNEW = 289, + LANG_COMMAND_TICKETVIEW = 290, + LANG_COMMAND_TICKETON = 291, + LANG_COMMAND_TICKETOFF = 292, + LANG_COMMAND_TICKENOTEXIST = 293, + LANG_COMMAND_ALLTICKETDELETED = 294, + LANG_COMMAND_TICKETPLAYERDEL = 295, + LANG_COMMAND_TICKETDEL = 296, + LANG_COMMAND_SPAWNDIST = 297, + LANG_COMMAND_SPAWNTIME = 298, + LANG_COMMAND_MODIFY_HONOR = 299, + + LANG_YOUR_CHAT_DISABLED = 300, + LANG_YOU_DISABLE_CHAT = 301, + LANG_CHAT_ALREADY_ENABLED = 302, + LANG_YOUR_CHAT_ENABLED = 303, + LANG_YOU_ENABLE_CHAT = 304, + + LANG_COMMAND_MODIFY_REP = 305, + LANG_COMMAND_MODIFY_ARENA = 306, + LANG_COMMAND_FACTION_NOTFOUND = 307, + LANG_COMMAND_FACTION_UNKNOWN = 308, + LANG_COMMAND_FACTION_INVPARAM = 309, + LANG_COMMAND_FACTION_DELTA = 310, + LANG_FACTION_LIST = 311, + LANG_FACTION_VISIBLE = 312, + LANG_FACTION_ATWAR = 313, + LANG_FACTION_PEACE_FORCED = 314, + LANG_FACTION_HIDDEN = 315, + LANG_FACTION_INVISIBLE_FORCED = 316, + LANG_FACTION_INACTIVE = 317, + LANG_REP_HATED = 318, + LANG_REP_HOSTILE = 319, + LANG_REP_UNFRIENDLY = 320, + LANG_REP_NEUTRAL = 321, + LANG_REP_FRIENDLY = 322, + LANG_REP_HONORED = 323, + LANG_REP_REVERED = 324, + LANG_REP_EXALTED = 325, + LANG_COMMAND_FACTION_NOREP_ERROR = 326, + LANG_FACTION_NOREPUTATION = 327, + LANG_LOOKUP_PLAYER_ACCOUNT = 328, + LANG_LOOKUP_PLAYER_CHARACTER = 329, + LANG_NO_PLAYERS_FOUND = 330, + LANG_EXTENDED_COST_NOT_EXIST = 331, + LANG_GM_ON = 332, + LANG_GM_OFF = 333, + LANG_GM_CHAT_ON = 334, + LANG_GM_CHAT_OFF = 335, + // Room for more level 2 336-399 not used + + // level 3 chat + LANG_SCRIPTS_RELOADED = 400, + LANG_YOU_CHANGE_SECURITY = 401, + LANG_YOURS_SECURITY_CHANGED = 402, + LANG_YOURS_SECURITY_IS_LOW = 403, + LANG_CREATURE_MOVE_DISABLED = 404, + LANG_CREATURE_MOVE_ENABLED = 405, + LANG_NO_WEATHER = 406, + LANG_WEATHER_DISABLED = 407, + + LANG_BAN_YOUBANNED = 408, + LANG_BAN_YOUPERMBANNED = 409, + LANG_BAN_NOTFOUND = 410, + + LANG_UNBAN_UNBANNED = 411, + LANG_UNBAN_ERROR = 412, + + LANG_BANINFO_NOACCOUNT = 413, + LANG_BANINFO_NOCHARACTER = 414, + LANG_BANINFO_NOIP = 415, + LANG_BANINFO_NOACCOUNTBAN = 416, + LANG_BANINFO_BANHISTORY = 417, + LANG_BANINFO_HISTORYENTRY = 418, + LANG_BANINFO_INFINITE = 419, + LANG_BANINFO_NEVER = 420, + LANG_BANINFO_YES = 421, + LANG_BANINFO_NO = 422, + LANG_BANINFO_IPENTRY = 423, + + LANG_BANLIST_NOIP = 424, + LANG_BANLIST_NOACCOUNT = 425, + LANG_BANLIST_NOCHARACTER = 426, + LANG_BANLIST_MATCHINGIP = 427, + LANG_BANLIST_MATCHINGACCOUNT = 428, + + LANG_COMMAND_LEARN_MANY_SPELLS = 429, + LANG_COMMAND_LEARN_CLASS_SPELLS = 430, + LANG_COMMAND_LEARN_CLASS_TALENTS = 431, + LANG_COMMAND_LEARN_ALL_LANG = 432, + LANG_COMMAND_LEARN_ALL_CRAFT = 433, + LANG_COMMAND_COULDNOTFIND = 434, + LANG_COMMAND_ITEMIDINVALID = 435, + LANG_COMMAND_NOITEMFOUND = 436, + LANG_COMMAND_LISTOBJINVALIDID = 437, + LANG_COMMAND_LISTITEMMESSAGE = 438, + LANG_COMMAND_LISTOBJMESSAGE = 439, + LANG_COMMAND_INVALIDCREATUREID = 440, + LANG_COMMAND_LISTCREATUREMESSAGE = 441, + LANG_COMMAND_NOAREAFOUND = 442, + LANG_COMMAND_NOITEMSETFOUND = 443, + LANG_COMMAND_NOSKILLFOUND = 444, + LANG_COMMAND_NOSPELLFOUND = 445, + LANG_COMMAND_NOQUESTFOUND = 446, + LANG_COMMAND_NOCREATUREFOUND = 447, + LANG_COMMAND_NOGAMEOBJECTFOUND = 448, + LANG_COMMAND_GRAVEYARDNOEXIST = 449, + LANG_COMMAND_GRAVEYARDALRLINKED = 450, + LANG_COMMAND_GRAVEYARDLINKED = 451, + LANG_COMMAND_GRAVEYARDWRONGZONE = 452, + LANG_COMMAND_GRAVEYARDWRONGTEAM = 453, + LANG_COMMAND_GRAVEYARDERROR = 454, + LANG_COMMAND_GRAVEYARD_NOTEAM = 455, + LANG_COMMAND_GRAVEYARD_ANY = 456, + LANG_COMMAND_GRAVEYARD_ALLIANCE = 457, + LANG_COMMAND_GRAVEYARD_HORDE = 458, + LANG_COMMAND_GRAVEYARDNEAREST = 459, + LANG_COMMAND_ZONENOGRAVEYARDS = 460, + LANG_COMMAND_ZONENOGRAFACTION = 461, + LANG_COMMAND_TP_ALREADYEXIST = 462, + LANG_COMMAND_TP_ADDED = 463, + LANG_COMMAND_TP_ADDEDERR = 464, + LANG_COMMAND_TP_DELETED = 465, + // 466, // not used + + LANG_COMMAND_TARGET_LISTAURAS = 467, + LANG_COMMAND_TARGET_AURADETAIL = 468, + LANG_COMMAND_TARGET_LISTAURATYPE = 469, + LANG_COMMAND_TARGET_AURASIMPLE = 470, + + LANG_COMMAND_QUEST_NOTFOUND = 471, + LANG_COMMAND_QUEST_STARTFROMITEM = 472, + LANG_COMMAND_QUEST_REMOVED = 473, + LANG_COMMAND_QUEST_REWARDED = 474, + LANG_COMMAND_QUEST_COMPLETE = 475, + LANG_COMMAND_QUEST_ACTIVE = 476, + + LANG_COMMAND_FLYMODE_STATUS = 477, + + LANG_COMMAND_OPCODESENT = 478, + + LANG_COMMAND_IMPORT_SUCCESS = 479, + LANG_COMMAND_IMPORT_FAILED = 480, + LANG_COMMAND_EXPORT_SUCCESS = 481, + LANG_COMMAND_EXPORT_FAILED = 482, + + LANG_COMMAND_SPELL_BROKEN = 483, + + LANG_SET_SKILL = 484, + LANG_SET_SKILL_ERROR = 485, + + LANG_INVALID_SKILL_ID = 486, + LANG_LEARNING_GM_SKILLS = 487, + LANG_YOU_KNOWN_SPELL = 488, + LANG_TARGET_KNOWN_SPELL = 489, + LANG_UNKNOWN_SPELL = 490, + LANG_FORGET_SPELL = 491, + LANG_REMOVEALL_COOLDOWN = 492, + LANG_REMOVE_COOLDOWN = 493, + + LANG_ADDITEM = 494, //log + LANG_ADDITEMSET = 495, //log + LANG_REMOVEITEM = 496, + LANG_ITEM_CANNOT_CREATE = 497, + LANG_INSERT_GUILD_NAME = 498, + LANG_PLAYER_NOT_FOUND = 499, + LANG_PLAYER_IN_GUILD = 500, + LANG_GUILD_NOT_CREATED = 501, + LANG_NO_ITEMS_FROM_ITEMSET_FOUND = 502, + + LANG_DISTANCE = 503, + + LANG_ITEM_SLOT = 504, + LANG_ITEM_SLOT_NOT_EXIST = 505, + LANG_ITEM_ADDED_TO_SLOT = 506, + LANG_ITEM_SAVE_FAILED = 507, + LANG_ITEMLIST_SLOT = 508, + LANG_ITEMLIST_MAIL = 509, + LANG_ITEMLIST_AUCTION = 510, + + LANG_WRONG_LINK_TYPE = 511, + LANG_ITEM_LIST = 512, + LANG_QUEST_LIST = 513, + LANG_CREATURE_ENTRY_LIST = 514, + LANG_CREATURE_LIST = 515, + LANG_GO_ENTRY_LIST = 516, + LANG_GO_LIST = 517, + LANG_ITEMSET_LIST = 518, + LANG_TELE_LIST = 519, + LANG_SPELL_LIST = 520, + LANG_SKILL_LIST = 521, + + LANG_GAMEOBJECT_NOT_EXIST = 522, + + LANG_GAMEOBJECT_CURRENT = 523, //log + LANG_GAMEOBJECT_DETAIL = 524, + LANG_GAMEOBJECT_ADD = 525, + + LANG_MOVEGENS_LIST = 526, + LANG_MOVEGENS_IDLE = 527, + LANG_MOVEGENS_RANDOM = 528, + LANG_MOVEGENS_WAYPOINT = 529, + LANG_MOVEGENS_ANIMAL_RANDOM = 530, + LANG_MOVEGENS_CONFUSED = 531, + LANG_MOVEGENS_TARGETED_PLAYER = 532, + LANG_MOVEGENS_TARGETED_CREATURE = 533, + LANG_MOVEGENS_TARGETED_NULL = 534, + LANG_MOVEGENS_HOME_CREATURE = 535, + LANG_MOVEGENS_HOME_PLAYER = 536, + LANG_MOVEGENS_FLIGHT = 537, + LANG_MOVEGENS_UNKNOWN = 538, + + LANG_NPCINFO_CHAR = 539, + LANG_NPCINFO_LEVEL = 540, + LANG_NPCINFO_HEALTH = 541, + LANG_NPCINFO_FLAGS = 542, + LANG_NPCINFO_LOOT = 543, + LANG_NPCINFO_POSITION = 544, + LANG_NPCINFO_VENDOR = 545, + LANG_NPCINFO_TRAINER = 546, + LANG_NPCINFO_DUNGEON_ID = 547, + + LANG_PINFO_ACCOUNT = 548, + LANG_PINFO_LEVEL = 549, + LANG_PINFO_NO_REP = 550, + + LANG_YOU_SET_EXPLORE_ALL = 551, + LANG_YOU_SET_EXPLORE_NOTHING = 552, + LANG_YOURS_EXPLORE_SET_ALL = 553, + LANG_YOURS_EXPLORE_SET_NOTHING = 554, + + LANG_HOVER_ENABLED = 555, + LANG_HOVER_DISABLED = 556, + LANG_YOURS_LEVEL_UP = 557, + LANG_YOURS_LEVEL_DOWN = 558, + LANG_YOURS_LEVEL_PROGRESS_RESET = 559, + LANG_EXPLORE_AREA = 560, + LANG_UNEXPLORE_AREA = 561, + + LANG_UPDATE = 562, + LANG_UPDATE_CHANGE = 563, + LANG_TOO_BIG_INDEX = 564, + LANG_SET_UINT = 565, //log + LANG_SET_UINT_FIELD = 566, + LANG_SET_FLOAT = 567, //log + LANG_SET_FLOAT_FIELD = 568, + LANG_GET_UINT = 569, //log + LANG_GET_UINT_FIELD = 570, + LANG_GET_FLOAT = 571, //log + LANG_GET_FLOAT_FIELD = 572, + LANG_SET_32BIT = 573, //log + LANG_SET_32BIT_FIELD = 574, + LANG_CHANGE_32BIT = 575, //log + LANG_CHANGE_32BIT_FIELD = 576, + + LANG_INVISIBLE_INVISIBLE = 577, + LANG_INVISIBLE_VISIBLE = 578, + LANG_SELECTED_TARGET_NOT_HAVE_VICTIM = 579, + + LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST = 580, + LANG_COMMAND_NEAROBJMESSAGE = 581, + LANG_COMMAND_RAWPAWNTIMES = 582, + + LANG_EVENT_ENTRY_LIST = 583, + LANG_NOEVENTFOUND = 584, + LANG_EVENT_NOT_EXIST = 585, + LANG_EVENT_INFO = 586, + LANG_EVENT_ALREADY_ACTIVE = 587, + LANG_EVENT_NOT_ACTIVE = 588, + + LANG_MOVEGENS_POINT = 589, + LANG_MOVEGENS_FEAR = 590, + LANG_MOVEGENS_DISTRACT = 591, + + LANG_COMMAND_LEARN_ALL_RECIPES = 592, + + // Battleground + LANG_BG_A_WINS = 600, + LANG_BG_H_WINS = 601, + LANG_BG_WS_ONE_MINUTE = 602, + LANG_BG_WS_HALF_MINUTE = 603, + LANG_BG_WS_BEGIN = 604, + + LANG_BG_WS_CAPTURED_HF = 605, + LANG_BG_WS_CAPTURED_AF = 606, + LANG_BG_WS_DROPPED_HF = 607, + LANG_BG_WS_DROPPED_AF = 608, + LANG_BG_WS_RETURNED_AF = 609, + LANG_BG_WS_RETURNED_HF = 610, + LANG_BG_WS_PICKEDUP_HF = 611, + LANG_BG_WS_PICKEDUP_AF = 612, + LANG_BG_WS_F_PLACED = 613, + LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED = 614, + LANG_BG_WS_HORDE_FLAG_RESPAWNED = 615, + + LANG_BG_EY_ONE_MINUTE = 636, + LANG_BG_EY_HALF_MINUTE = 637, + LANG_BG_EY_BEGIN = 638, + + LANG_BG_AB_ALLY = 650, + LANG_BG_AB_HORDE = 651, + LANG_BG_AB_NODE_STABLES = 652, + LANG_BG_AB_NODE_BLACKSMITH = 653, + LANG_BG_AB_NODE_FARM = 654, + LANG_BG_AB_NODE_LUMBER_MILL = 655, + LANG_BG_AB_NODE_GOLD_MINE = 656, + LANG_BG_AB_NODE_TAKEN = 657, + LANG_BG_AB_NODE_DEFENDED = 658, + LANG_BG_AB_NODE_ASSAULTED = 659, + LANG_BG_AB_NODE_CLAIMED = 660, + LANG_BG_AB_ONEMINTOSTART = 661, + LANG_BG_AB_HALFMINTOSTART = 662, + LANG_BG_AB_STARTED = 663, + LANG_BG_AB_A_NEAR_VICTORY = 664, + LANG_BG_AB_H_NEAR_VICTORY = 665, + LANG_BG_MARK_BY_MAIL = 666, + + LANG_BG_EY_HAS_TAKEN_A_M_TOWER = 667, + LANG_BG_EY_HAS_TAKEN_H_M_TOWER = 668, + LANG_BG_EY_HAS_TAKEN_A_D_RUINS = 669, + LANG_BG_EY_HAS_TAKEN_H_D_RUINS = 670, + LANG_BG_EY_HAS_TAKEN_A_B_TOWER = 671, + LANG_BG_EY_HAS_TAKEN_H_B_TOWER = 672, + LANG_BG_EY_HAS_TAKEN_A_F_RUINS = 673, + LANG_BG_EY_HAS_TAKEN_H_F_RUINS = 674, + LANG_BG_EY_HAS_LOST_A_M_TOWER = 675, + LANG_BG_EY_HAS_LOST_H_M_TOWER = 676, + LANG_BG_EY_HAS_LOST_A_D_RUINS = 677, + LANG_BG_EY_HAS_LOST_H_D_RUINS = 678, + LANG_BG_EY_HAS_LOST_A_B_TOWER = 679, + LANG_BG_EY_HAS_LOST_H_B_TOWER = 680, + LANG_BG_EY_HAS_LOST_A_F_RUINS = 681, + LANG_BG_EY_HAS_LOST_H_F_RUINS = 682, + LANG_BG_EY_HAS_TAKEN_FLAG = 683, + LANG_BG_EY_CAPTURED_FLAG_A = 684, + LANG_BG_EY_CAPTURED_FLAG_H = 685, + LANG_BG_EY_DROPPED_FLAG = 686, + LANG_BG_EY_RESETED_FLAG = 687, + + LANG_ARENA_ONE_TOOLOW = 700, + LANG_ARENA_ONE_MINUTE = 701, + LANG_ARENA_THIRTY_SECONDS = 702, + LANG_ARENA_FIFTEEN_SECONDS = 703, + LANG_ARENA_BEGUN = 704, + + LANG_WAIT_BEFORE_SPEAKING = 705, + LANG_NOT_EQUIPPED_ITEM = 706, + LANG_PLAYER_DND = 707, + LANG_PLAYER_AFK = 708, + LANG_PLAYER_DND_DEFAULT = 709, + LANG_PLAYER_AFK_DEFAULT = 710, + + LANG_BG_QUEUE_ANNOUNCE_SELF = 711, + LANG_BG_QUEUE_ANNOUNCE_WORLD = 712, + + LANG_YOUR_ARENA_LEVEL_REQ_ERROR = 713, + LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714, + LANG_YOUR_BG_LEVEL_REQ_ERROR = 715, + LANG_YOUR_ARENA_TEAM_FULL = 716, + // Room for BG/ARENA 717-799 not used + + // in game strings + // = 800, not used + LANG_NOT_ENOUGH_GOLD = 801, + LANG_NOT_FREE_TRADE_SLOTS = 802, + LANG_NOT_PARTNER_FREE_TRADE_SLOTS = 803, + LANG_YOU_NOT_HAVE_PERMISSION = 804, + LANG_UNKNOWN_LANGUAGE = 805, + LANG_NOT_LEARNED_LANGUAGE = 806, + LANG_NEED_CHARACTER_NAME = 807, + LANG_PLAYER_NOT_EXIST_OR_OFFLINE = 808, + LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND = 809, + // Room for in-game strings 810-999 not used + + // FREE IDS 1000-9999 + + // Use for not-in-svn patches 10000-10999 + // Use for custom patches 11000-11999 + + // NOT RESERVED IDS 12000- +}; +#endif diff --git a/src/game/Level0.cpp b/src/game/Level0.cpp new file mode 100644 index 000000000..48f3d7639 --- /dev/null +++ b/src/game/Level0.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Player.h" +#include "Opcodes.h" +#include "Chat.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Language.h" +#include "AccountMgr.h" +#include "SystemConfig.h" +#include "Util.h" + +bool ChatHandler::HandleHelpCommand(const char* args) +{ + if(!*args) + return false; + + char* cmd = strtok((char*)args, " "); + if(!cmd) + return false; + + if(!ShowHelpForCommand(getCommandTable(), cmd)) + SendSysMessage(LANG_NO_HELP_CMD); + + return true; +} + +bool ChatHandler::HandleCommandsCommand(const char* args) +{ + ShowHelpForCommand(getCommandTable(), ""); + return true; +} + +bool ChatHandler::HandleAcctCommand(const char* /*args*/) +{ + uint32 gmlevel = m_session->GetSecurity(); + PSendSysMessage(LANG_ACCOUNT_LEVEL, gmlevel); + return true; +} + +bool ChatHandler::HandleStartCommand(const char* /*args*/) +{ + Player *chr = m_session->GetPlayer(); + + if(chr->isInFlight()) + { + SendSysMessage(LANG_YOU_IN_FLIGHT); + SetSentErrorMessage(true); + return false; + } + + if(chr->isInCombat()) + { + SendSysMessage(LANG_YOU_IN_COMBAT); + SetSentErrorMessage(true); + return false; + } + + // cast spell Stuck + chr->CastSpell(chr,7355,false); + return true; +} + +bool ChatHandler::HandleInfoCommand(const char* /*args*/) +{ + uint32 activeClientsNum = sWorld.GetActiveSessionCount(); + uint32 queuedClientsNum = sWorld.GetQueuedSessionCount(); + uint32 maxActiveClientsNum = sWorld.GetMaxActiveSessionCount(); + uint32 maxQueuedClientsNum = sWorld.GetMaxQueuedSessionCount(); + std::string str = secsToTimeString(sWorld.GetUptime()); + + PSendSysMessage(_FULLVERSION); + PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); + PSendSysMessage(LANG_UPTIME, str.c_str()); + + return true; +} + +bool ChatHandler::HandleDismountCommand(const char* /*args*/) +{ + //If player is not mounted, so go out :) + if (!m_session->GetPlayer( )->IsMounted()) + { + SendSysMessage(LANG_CHAR_NON_MOUNTED); + SetSentErrorMessage(true); + return false; + } + + if(m_session->GetPlayer( )->isInFlight()) + { + SendSysMessage(LANG_YOU_IN_FLIGHT); + SetSentErrorMessage(true); + return false; + } + + m_session->GetPlayer()->Unmount(); + m_session->GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + return true; +} + +bool ChatHandler::HandleSaveCommand(const char* /*args*/) +{ + Player *player=m_session->GetPlayer(); + + // save GM account without delay and output message (testing, etc) + if(m_session->GetSecurity()) + { + player->SaveToDB(); + SendSysMessage(LANG_PLAYER_SAVED); + return true; + } + + // save or plan save after 20 sec (logout delay) if current next save time more this value and _not_ output any messages to prevent cheat planning + uint32 save_interval = sWorld.getConfig(CONFIG_INTERVAL_SAVE); + if(save_interval==0 || save_interval > 20*1000 && player->GetSaveTimer() <= save_interval - 20*1000) + player->SaveToDB(); + + return true; +} + +bool ChatHandler::HandleGMListCommand(const char* /*args*/) +{ + bool first = true; + + HashMapHolder::MapType &m = HashMapHolder::GetContainer(); + HashMapHolder::MapType::iterator itr = m.begin(); + for(; itr != m.end(); ++itr) + { + if( itr->second->GetSession()->GetSecurity() && (itr->second->isGameMaster() || sWorld.getConfig(CONFIG_GM_IN_GM_LIST) ) && + itr->second->IsVisibleGloballyFor(m_session->GetPlayer()) ) + { + if(first) + { + SendSysMessage(LANG_GMS_ON_SRV); + first = false; + } + + SendSysMessage(itr->second->GetName()); + } + } + + if(first) + SendSysMessage(LANG_GMS_NOT_LOGGED); + + return true; +} + +bool ChatHandler::HandlePasswordCommand(const char* args) +{ + if(!*args) + return false; + + char *old_pass = strtok ((char*)args, " "); + char *new_pass = strtok (NULL, " "); + char *new_pass_c = strtok (NULL, " "); + + if( !old_pass || !new_pass || !new_pass_c ) + return false; + + std::string password_old = old_pass; + std::string password_new = new_pass; + std::string password_new_c = new_pass_c; + + if(!accmgr.CheckPassword(m_session->GetAccountId(), password_old) || password_new != password_new_c) + { + SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); + SetSentErrorMessage(true); + return false; + } + + AccountOpResult result = accmgr.ChangePassword(m_session->GetAccountId(), password_new); + + switch(result) + { + case AOR_OK: + SendSysMessage(LANG_COMMAND_PASSWORD); + break; + default: + SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleLockAccountCommand(const char* args) +{ + if (!*args) + { + SendSysMessage(LANG_USE_BOL); + return true; + } + + std::string argstr = (char*)args; + if (argstr == "on") + { + loginDatabase.PExecute( "UPDATE account SET locked = '1' WHERE id = '%d'",m_session->GetAccountId()); + PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); + return true; + } + + if (argstr == "off") + { + loginDatabase.PExecute( "UPDATE account SET locked = '0' WHERE id = '%d'",m_session->GetAccountId()); + PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); + return true; + } + + SendSysMessage(LANG_USE_BOL); + return true; +} diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp new file mode 100644 index 000000000..11a1f415d --- /dev/null +++ b/src/game/Level1.cpp @@ -0,0 +1,2429 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Opcodes.h" +#include "Chat.h" +#include "Log.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Language.h" +#include "CellImpl.h" +#include "InstanceSaveMgr.h" +#include "Util.h" +#ifdef _DEBUG_VMAPS +#include "VMapFactory.h" +#endif + +bool ChatHandler::HandleSayCommand(const char* args) +{ + if(!*args) + return false; + + Creature* pCreature = getSelectedCreature(); + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + pCreature->Say(args, LANG_UNIVERSAL, 0); + + return true; +} + +bool ChatHandler::HandleYellCommand(const char* args) +{ + if(!*args) + return false; + + Creature* pCreature = getSelectedCreature(); + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + pCreature->Yell(args, LANG_UNIVERSAL, 0); + + return true; +} + +//show text emote by creature in chat +bool ChatHandler::HandleTextEmoteCommand(const char* args) +{ + if(!*args) + return false; + + Creature* pCreature = getSelectedCreature(); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + pCreature->TextEmote(args, 0); + + return true; +} + +// make npc whisper to player +bool ChatHandler::HandleNpcWhisperCommand(const char* args) +{ + if(!*args) + return false; + + char* receiver_str = strtok((char*)args, " "); + char* text = strtok(NULL, ""); + + uint64 guid = m_session->GetPlayer()->GetSelection(); + Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); + + if(!pCreature || !receiver_str || !text) + { + return false; + } + + uint64 receiver_guid= atol(receiver_str); + + pCreature->Whisper(text,receiver_guid); + + return true; +} + +// global announce +bool ChatHandler::HandleAnnounceCommand(const char* args) +{ + if(!*args) + return false; + + sWorld.SendWorldText(LANG_SYSTEMMESSAGE,args); + return true; +} + +//notification player at the screen +bool ChatHandler::HandleNotifyCommand(const char* args) +{ + if(!*args) + return false; + + std::string str = GetMangosString(LANG_GLOBAL_NOTIFY); + str += args; + + WorldPacket data(SMSG_NOTIFICATION, (str.size()+1)); + data << str; + sWorld.SendGlobalMessage(&data); + + return true; +} + +//Enable\Dissable GM Mode +bool ChatHandler::HandleGMmodeCommand(const char* args) +{ + if(!*args) + { + if(m_session->GetPlayer()->isGameMaster()) + m_session->SendNotification(LANG_GM_ON); + else + m_session->SendNotification(LANG_GM_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + m_session->GetPlayer()->SetGameMaster(true); + m_session->SendNotification(LANG_GM_ON); + #ifdef _DEBUG_VMAPS + VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); + vMapManager->processCommand("stoplog"); + #endif + return true; + } + + if (argstr == "off") + { + m_session->GetPlayer()->SetGameMaster(false); + m_session->SendNotification(LANG_GM_OFF); + #ifdef _DEBUG_VMAPS + VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); + vMapManager->processCommand("startlog"); + #endif + return true; + } + + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; +} + +// Enables or disables hiding of the staff badge +bool ChatHandler::HandleGMChatCommand(const char* args) +{ + if(!*args) + { + if(m_session->GetPlayer()->isGMChat()) + m_session->SendNotification(LANG_GM_CHAT_ON); + else + m_session->SendNotification(LANG_GM_CHAT_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + m_session->GetPlayer()->SetGMChat(true); + m_session->SendNotification(LANG_GM_CHAT_ON); + return true; + } + + if (argstr == "off") + { + m_session->GetPlayer()->SetGMChat(false); + m_session->SendNotification(LANG_GM_CHAT_OFF); + return true; + } + + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; +} + +//Enable\Dissable Invisible mode +bool ChatHandler::HandleVisibleCommand(const char* args) +{ + if (!*args) + { + PSendSysMessage(LANG_YOU_ARE, m_session->GetPlayer()->isGMVisible() ? GetMangosString(LANG_VISIBLE) : GetMangosString(LANG_INVISIBLE)); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + m_session->GetPlayer()->SetGMVisible(true); + m_session->SendNotification(LANG_INVISIBLE_VISIBLE); + return true; + } + + if (argstr == "off") + { + m_session->SendNotification(LANG_INVISIBLE_INVISIBLE); + m_session->GetPlayer()->SetGMVisible(false); + return true; + } + + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; +} + +bool ChatHandler::HandleGPSCommand(const char* args) +{ + WorldObject *obj = NULL; + if (*args) + { + std::string name = args; + if(normalizePlayerName(name)) + obj = objmgr.GetPlayer(name.c_str()); + + if(!obj) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + } + else + { + obj = getSelectedUnit(); + + if(!obj) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + } + CellPair cell_val = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + Cell cell(cell_val); + + uint32 zone_id = obj->GetZoneId(); + uint32 area_id = obj->GetAreaId(); + + MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId()); + AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id); + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(area_id); + + float zone_x = obj->GetPositionX(); + float zone_y = obj->GetPositionY(); + + Map2ZoneCoordinates(zone_x,zone_y,zone_id); + + Map const *map = MapManager::Instance().GetMap(obj->GetMapId(), obj); + float ground_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), MAX_HEIGHT); + float floor_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ()); + + GridPair p = MaNGOS::ComputeGridPair(obj->GetPositionX(), obj->GetPositionY()); + + int gx=63-p.x_coord; + int gy=63-p.y_coord; + + uint32 have_map = Map::ExistMap(obj->GetMapId(),gx,gy) ? 1 : 0; + uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0; + + PSendSysMessage(LANG_MAP_POSITION, + obj->GetMapId(), (mapEntry ? mapEntry->name[m_session->GetSessionDbcLocale()] : "" ), + zone_id, (zoneEntry ? zoneEntry->area_name[m_session->GetSessionDbcLocale()] : "" ), + area_id, (areaEntry ? areaEntry->area_name[m_session->GetSessionDbcLocale()] : "" ), + obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(), + cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), + zone_x, zone_y, ground_z, floor_z, have_map, have_vmap ); + + sLog.outDebug("Player %s GPS call for %s '%s' (%s: %u):", + m_session->GetPlayer()->GetName(), + (obj->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), obj->GetName(), + (obj->GetTypeId() == TYPEID_PLAYER ? "GUID" : "Entry"), (obj->GetTypeId() == TYPEID_PLAYER ? obj->GetGUIDLow(): obj->GetEntry()) ); + sLog.outDebug(GetMangosString(LANG_MAP_POSITION), + obj->GetMapId(), (mapEntry ? mapEntry->name[sWorld.GetDefaultDbcLocale()] : "" ), + zone_id, (zoneEntry ? zoneEntry->area_name[sWorld.GetDefaultDbcLocale()] : "" ), + area_id, (areaEntry ? areaEntry->area_name[sWorld.GetDefaultDbcLocale()] : "" ), + obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(), + cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), + zone_x, zone_y, ground_z, floor_z, have_map, have_vmap ); + + return true; +} + +//Summon Player +bool ChatHandler::HandleNamegoCommand(const char* args) +{ + if(!*args) + return false; + + std::string name = args; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + Player *chr = objmgr.GetPlayer(name.c_str()); + if (chr) + { + if(chr->IsBeingTeleported()==true) + { + PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + Map* pMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer()); + + if(pMap->Instanceable()) + { + Map* cMap = MapManager::Instance().GetMap(chr->GetMapId(),chr); + if( cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId() ) + { + // cannot summon from instance to instance + PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + // we are in instance, and can summon only player in our group with us as lead + if ( !m_session->GetPlayer()->GetGroup() || !chr->GetGroup() || + (chr->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || + (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) ) + // the last check is a bit excessive, but let it be, just in case + { + PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + } + + PSendSysMessage(LANG_SUMMONING, chr->GetName(),""); + + if (m_session->GetPlayer()->IsVisibleGloballyFor(chr)) + ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, m_session->GetPlayer()->GetName()); + + // stop flight if need + if(chr->isInFlight()) + { + chr->GetMotionMaster()->MovementExpired(); + chr->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + chr->SaveRecallPosition(); + + // before GM + float x,y,z; + m_session->GetPlayer()->GetClosePoint(x,y,z,chr->GetObjectSize()); + chr->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,chr->GetOrientation()); + } + else if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) + { + PSendSysMessage(LANG_SUMMONING, name.c_str(),GetMangosString(LANG_OFFLINE)); + + // in point where GM stay + Player::SavePositionInDB(m_session->GetPlayer()->GetMapId(), + m_session->GetPlayer()->GetPositionX(), + m_session->GetPlayer()->GetPositionY(), + m_session->GetPlayer()->GetPositionZ(), + m_session->GetPlayer()->GetOrientation(), + m_session->GetPlayer()->GetZoneId(), + guid); + } + else + { + PSendSysMessage(LANG_NO_PLAYER, args); + SetSentErrorMessage(true); + } + + return true; +} + +//Teleport to Player +bool ChatHandler::HandleGonameCommand(const char* args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + std::string name = args; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + Player *chr = objmgr.GetPlayer(name.c_str()); + if (chr) + { + Map* cMap = MapManager::Instance().GetMap(chr->GetMapId(),chr); + if(cMap->Instanceable()) + { + Map* pMap = MapManager::Instance().GetMap(_player->GetMapId(),_player); + + // we have to go to instance, and can go to player only if: + // 1) we are in his group (either as leader or as member) + // 2) we are not bound to any group and have GM mode on + if (_player->GetGroup()) + { + // we are in group, we can go only if we are in the player group + if (_player->GetGroup() != chr->GetGroup()) + { + PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + } + else + { + // we are not in group, let's verify our GM mode + if (!_player->isGameMaster()) + { + PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + } + + // if the player or the player's group is bound to another instance + // the player will not be bound to another one + InstancePlayerBind *pBind = _player->GetBoundInstance(chr->GetMapId(), chr->GetDifficulty()); + if(!pBind) + { + Group *group = _player->GetGroup(); + InstanceGroupBind *gBind = group ? group->GetBoundInstance(chr->GetMapId(), chr->GetDifficulty()) : NULL; + if(!gBind) + { + // if no bind exists, create a solo bind + InstanceSave *save = sInstanceSaveManager.GetInstanceSave(chr->GetInstanceId()); + if(save) _player->BindToInstance(save, !save->CanReset()); + } + } + + _player->SetDifficulty(chr->GetDifficulty()); + } + + PSendSysMessage(LANG_APPEARING_AT, chr->GetName()); + + if (_player->IsVisibleGloballyFor(chr)) + ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, _player->GetName()); + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + // to point to see at target with same orientation + float x,y,z; + chr->GetContactPoint(m_session->GetPlayer(),x,y,z); + + _player->TeleportTo(chr->GetMapId(), x, y, z, _player->GetAngle( chr ), TELE_TO_GM_MODE); + + return true; + } + + if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) + { + PSendSysMessage(LANG_APPEARING_AT, name.c_str()); + + // to point where player stay (if loaded) + float x,y,z,o; + uint32 map; + bool in_flight; + if(Player::LoadPositionFromDB(map,x,y,z,o,in_flight,guid)) + { + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(map, x, y, z,_player->GetOrientation()); + return true; + } + } + + PSendSysMessage(LANG_NO_PLAYER, args); + + SetSentErrorMessage(true); + return false; +} + +// Teleport player to last position +bool ChatHandler::HandleRecallCommand(const char* args) +{ + Player* chr = NULL; + + if(!*args) + { + chr = getSelectedPlayer(); + if(!chr) + chr = m_session->GetPlayer(); + } + else + { + std::string name = args; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + chr = objmgr.GetPlayer(name.c_str()); + + if(!chr) + { + PSendSysMessage(LANG_NO_PLAYER, args); + SetSentErrorMessage(true); + return false; + } + } + + if(chr->IsBeingTeleported()) + { + PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(chr->isInFlight()) + { + chr->GetMotionMaster()->MovementExpired(); + chr->m_taxi.ClearTaxiDestinations(); + } + + chr->TeleportTo(chr->m_recallMap, chr->m_recallX, chr->m_recallY, chr->m_recallZ, chr->m_recallO); + return true; +} + +//Edit Player KnownTitles +bool ChatHandler::HandleModifyKnownTitlesCommand(const char* args) +{ + if(!*args) + return false; + + uint64 titles = 0; + + sscanf((char*)args, I64FMTD, &titles); + + Player *chr = getSelectedPlayer(); + if (!chr) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + uint64 titles2 = titles; + + for(int i=1; i < sCharTitlesStore.GetNumRows(); ++i) + if(CharTitlesEntry const* tEntry = sCharTitlesStore.LookupEntry(i)) + titles2 &= ~(uint64(1) << tEntry->bit_index); + + titles &= ~titles2; // remove not existed titles + + chr->SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES, titles); + SendSysMessage(LANG_DONE); + + return true; +} + +//Edit Player HP +bool ChatHandler::HandleModifyHPCommand(const char* args) +{ + if(!*args) + return false; + + // char* pHp = strtok((char*)args, " "); + // if (!pHp) + // return false; + + // char* pHpMax = strtok(NULL, " "); + // if (!pHpMax) + // return false; + + // int32 hpm = atoi(pHpMax); + // int32 hp = atoi(pHp); + + int32 hp = atoi((char*)args); + int32 hpm = atoi((char*)args); + + if (hp <= 0 || hpm <= 0 || hpm < hp) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_HP, chr->GetName(), hp, hpm); + ChatHandler(chr).PSendSysMessage(LANG_YOURS_HP_CHANGED, m_session->GetPlayer()->GetName(), hp, hpm); + + chr->SetMaxHealth( hpm ); + chr->SetHealth( hp ); + + return true; +} + +//Edit Player Mana +bool ChatHandler::HandleModifyManaCommand(const char* args) +{ + if(!*args) + return false; + + // char* pmana = strtok((char*)args, " "); + // if (!pmana) + // return false; + + // char* pmanaMax = strtok(NULL, " "); + // if (!pmanaMax) + // return false; + + // int32 manam = atoi(pmanaMax); + // int32 mana = atoi(pmana); + int32 mana = atoi((char*)args); + int32 manam = atoi((char*)args); + + if (mana <= 0 || manam <= 0 || manam < mana) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_MANA, chr->GetName(), mana, manam); + ChatHandler(chr).PSendSysMessage(LANG_YOURS_MANA_CHANGED, m_session->GetPlayer()->GetName(), mana, manam); + + chr->SetMaxPower(POWER_MANA,manam ); + chr->SetPower(POWER_MANA, mana ); + + return true; +} + +//Edit Player Energy +bool ChatHandler::HandleModifyEnergyCommand(const char* args) +{ + if(!*args) + return false; + + // char* pmana = strtok((char*)args, " "); + // if (!pmana) + // return false; + + // char* pmanaMax = strtok(NULL, " "); + // if (!pmanaMax) + // return false; + + // int32 manam = atoi(pmanaMax); + // int32 mana = atoi(pmana); + + int32 energy = atoi((char*)args)*10; + int32 energym = atoi((char*)args)*10; + + if (energy <= 0 || energym <= 0 || energym < energy) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (!chr) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_ENERGY, chr->GetName(), energy/10, energym/10); + ChatHandler(chr).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, m_session->GetPlayer()->GetName(), energy/10, energym/10); + + chr->SetMaxPower(POWER_ENERGY,energym ); + chr->SetPower(POWER_ENERGY, energy ); + + sLog.outDetail(GetMangosString(LANG_CURRENT_ENERGY),chr->GetMaxPower(POWER_ENERGY)); + + return true; +} + +//Edit Player Rage +bool ChatHandler::HandleModifyRageCommand(const char* args) +{ + if(!*args) + return false; + + // char* pmana = strtok((char*)args, " "); + // if (!pmana) + // return false; + + // char* pmanaMax = strtok(NULL, " "); + // if (!pmanaMax) + // return false; + + // int32 manam = atoi(pmanaMax); + // int32 mana = atoi(pmana); + + int32 rage = atoi((char*)args)*10; + int32 ragem = atoi((char*)args)*10; + + if (rage <= 0 || ragem <= 0 || ragem < rage) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_RAGE, chr->GetName(), rage/10, ragem/10); + // Special case: I use GetMangosString here to get local of destination char ;) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_RAGE_CHANGED), m_session->GetPlayer()->GetName(), rage/10, ragem/10); + + chr->SetMaxPower(POWER_RAGE,ragem ); + chr->SetPower(POWER_RAGE, rage ); + + return true; +} + +//Edit Player Faction +bool ChatHandler::HandleModifyFactionCommand(const char* args) +{ + if(!*args) + return false; + + char* pfactionid = extractKeyFromLink((char*)args,"Hfaction"); + + Creature* chr = getSelectedCreature(); + if(!chr) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(!pfactionid) + { + if(chr) + { + uint32 factionid = chr->getFaction(); + uint32 flag = chr->GetUInt32Value(UNIT_FIELD_FLAGS); + uint32 npcflag = chr->GetUInt32Value(UNIT_NPC_FLAGS); + uint32 dyflag = chr->GetUInt32Value(UNIT_DYNAMIC_FLAGS); + PSendSysMessage(LANG_CURRENT_FACTION,chr->GetGUIDLow(),factionid,flag,npcflag,dyflag); + } + return true; + } + + if( !chr ) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + uint32 factionid = atoi(pfactionid); + uint32 flag; + + char *pflag = strtok(NULL, " "); + if (!pflag) + flag = chr->GetUInt32Value(UNIT_FIELD_FLAGS); + else + flag = atoi(pflag); + + char* pnpcflag = strtok(NULL, " "); + + uint32 npcflag; + if(!pnpcflag) + npcflag = chr->GetUInt32Value(UNIT_NPC_FLAGS); + else + npcflag = atoi(pnpcflag); + + char* pdyflag = strtok(NULL, " "); + + uint32 dyflag; + if(!pdyflag) + dyflag = chr->GetUInt32Value(UNIT_DYNAMIC_FLAGS); + else + dyflag = atoi(pdyflag); + + if(!sFactionTemplateStore.LookupEntry(factionid)) + { + PSendSysMessage(LANG_WRONG_FACTION, factionid); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_FACTION, chr->GetGUIDLow(),factionid,flag,npcflag,dyflag); + + //sprintf((char*)buf,"%s changed your Faction to %i.", m_session->GetPlayer()->GetName(), factionid); + //FillSystemMessageData(&data, m_session, buf); + + //chr->GetSession()->SendPacket(&data); + + chr->setFaction(factionid); + chr->SetUInt32Value(UNIT_FIELD_FLAGS,flag); + chr->SetUInt32Value(UNIT_NPC_FLAGS,npcflag); + chr->SetUInt32Value(UNIT_DYNAMIC_FLAGS,dyflag); + + return true; +} + +//Edit Player Spell +bool ChatHandler::HandleModifySpellCommand(const char* args) +{ + if(!*args) return false; + char* pspellflatid = strtok((char*)args, " "); + if (!pspellflatid) + return false; + + char* pop = strtok(NULL, " "); + if (!pop) + return false; + + char* pval = strtok(NULL, " "); + if (!pval) + return false; + + uint16 mark; + + char* pmark = strtok(NULL, " "); + + uint8 spellflatid = atoi(pspellflatid); + uint8 op = atoi(pop); + uint16 val = atoi(pval); + if(!pmark) + mark = 65535; + else + mark = atoi(pmark); + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, chr->GetName()); + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, m_session->GetPlayer()->GetName(), spellflatid, val, mark); + + WorldPacket data(SMSG_SET_FLAT_SPELL_MODIFIER, (1+1+2+2)); + data << uint8(spellflatid); + data << uint8(op); + data << uint16(val); + data << uint16(mark); + chr->GetSession()->SendPacket(&data); + + return true; +} + +//Edit Player TP +bool ChatHandler::HandleModifyTalentCommand (const char* args) +{ + if (!*args) + return false; + + int tp = atoi((char*)args); + if (tp>0) + { + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + player->SetFreeTalentPoints(tp); + return true; + } + return false; +} + +//Enable On\OFF all taxi paths +bool ChatHandler::HandleTaxiCheatCommand(const char* args) +{ + if (!*args) + { + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; + } + + std::string argstr = (char*)args; + + Player *chr = getSelectedPlayer(); + if (!chr) + { + chr=m_session->GetPlayer(); + } + + if (argstr == "on") + { + chr->SetTaxiCheater(true); + PSendSysMessage(LANG_YOU_GIVE_TAXIS, chr->GetName()); + + if(chr != m_session->GetPlayer()) + // to send localized data to target + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_TAXIS_ADDED), m_session->GetPlayer()->GetName()); + return true; + } + + if (argstr == "off") + { + chr->SetTaxiCheater(false); + PSendSysMessage(LANG_YOU_REMOVE_TAXIS, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_TAXIS_REMOVED), m_session->GetPlayer()->GetName()); + + return true; + } + + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; +} + +//Edit Player Aspeed +bool ChatHandler::HandleModifyASpeedCommand(const char* args) +{ + if (!*args) + return false; + + float ASpeed = (float)atof((char*)args); + + if (ASpeed > 10 || ASpeed < 0.1) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(chr->isInFlight()) + { + PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_ASPEED_CHANGED), m_session->GetPlayer()->GetName(), ASpeed); + + chr->SetSpeed(MOVE_WALK, ASpeed,true); + chr->SetSpeed(MOVE_RUN, ASpeed,true); + chr->SetSpeed(MOVE_SWIM, ASpeed,true); + //chr->SetSpeed(MOVE_TURN, ASpeed,true); + chr->SetSpeed(MOVE_FLY, ASpeed,true); + return true; +} + +//Edit Player Speed +bool ChatHandler::HandleModifySpeedCommand(const char* args) +{ + if (!*args) + return false; + + float Speed = (float)atof((char*)args); + + if (Speed > 10 || Speed < 0.1) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(chr->isInFlight()) + { + PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_SPEED_CHANGED), m_session->GetPlayer()->GetName(), Speed); + + chr->SetSpeed(MOVE_RUN,Speed,true); + + return true; +} + +//Edit Player Swim Speed +bool ChatHandler::HandleModifySwimCommand(const char* args) +{ + if (!*args) + return false; + + float Swim = (float)atof((char*)args); + + if (Swim > 10.0f || Swim < 0.01f) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(chr->isInFlight()) + { + PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_SWIM_SPEED_CHANGED), m_session->GetPlayer()->GetName(), Swim); + + chr->SetSpeed(MOVE_SWIM,Swim,true); + + return true; +} + +//Edit Player Walk Speed +bool ChatHandler::HandleModifyBWalkCommand(const char* args) +{ + if (!*args) + return false; + + float BSpeed = (float)atof((char*)args); + + if (BSpeed > 10.0f || BSpeed < 0.1f) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(chr->isInFlight()) + { + PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_BACK_SPEED_CHANGED), m_session->GetPlayer()->GetName(), BSpeed); + + chr->SetSpeed(MOVE_WALKBACK,BSpeed,true); + + return true; +} + +//Edit Player Fly +bool ChatHandler::HandleModifyFlyCommand(const char* args) +{ + if (!*args) + return false; + + float FSpeed = (float)atof((char*)args); + + if (FSpeed > 10.0f || FSpeed < 0.1f) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_FLY_SPEED_CHANGED), m_session->GetPlayer()->GetName(), FSpeed); + + chr->SetSpeed(MOVE_FLY,FSpeed,true); + + return true; +} + +//Edit Player Scale +bool ChatHandler::HandleModifyScaleCommand(const char* args) +{ + if (!*args) + return false; + + float Scale = (float)atof((char*)args); + if (Scale > 3.0f || Scale <= 0.0f) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_SIZE_CHANGED), m_session->GetPlayer()->GetName(), Scale); + + chr->SetFloatValue(OBJECT_FIELD_SCALE_X, Scale); + + return true; +} + +//Enable Player mount +bool ChatHandler::HandleModifyMountCommand(const char* args) +{ + if(!*args) + return false; + + uint16 mId = 1147; + float speed = (float)15; + uint32 num = 0; + + num = atoi((char*)args); + switch(num) + { + case 1: + mId=14340; + break; + case 2: + mId=4806; + break; + case 3: + mId=6471; + break; + case 4: + mId=12345; + break; + case 5: + mId=6472; + break; + case 6: + mId=6473; + break; + case 7: + mId=10670; + break; + case 8: + mId=10719; + break; + case 9: + mId=10671; + break; + case 10: + mId=10672; + break; + case 11: + mId=10720; + break; + case 12: + mId=14349; + break; + case 13: + mId=11641; + break; + case 14: + mId=12244; + break; + case 15: + mId=12242; + break; + case 16: + mId=14578; + break; + case 17: + mId=14579; + break; + case 18: + mId=14349; + break; + case 19: + mId=12245; + break; + case 20: + mId=14335; + break; + case 21: + mId=207; + break; + case 22: + mId=2328; + break; + case 23: + mId=2327; + break; + case 24: + mId=2326; + break; + case 25: + mId=14573; + break; + case 26: + mId=14574; + break; + case 27: + mId=14575; + break; + case 28: + mId=604; + break; + case 29: + mId=1166; + break; + case 30: + mId=2402; + break; + case 31: + mId=2410; + break; + case 32: + mId=2409; + break; + case 33: + mId=2408; + break; + case 34: + mId=2405; + break; + case 35: + mId=14337; + break; + case 36: + mId=6569; + break; + case 37: + mId=10661; + break; + case 38: + mId=10666; + break; + case 39: + mId=9473; + break; + case 40: + mId=9476; + break; + case 41: + mId=9474; + break; + case 42: + mId=14374; + break; + case 43: + mId=14376; + break; + case 44: + mId=14377; + break; + case 45: + mId=2404; + break; + case 46: + mId=2784; + break; + case 47: + mId=2787; + break; + case 48: + mId=2785; + break; + case 49: + mId=2736; + break; + case 50: + mId=2786; + break; + case 51: + mId=14347; + break; + case 52: + mId=14346; + break; + case 53: + mId=14576; + break; + case 54: + mId=9695; + break; + case 55: + mId=9991; + break; + case 56: + mId=6448; + break; + case 57: + mId=6444; + break; + case 58: + mId=6080; + break; + case 59: + mId=6447; + break; + case 60: + mId=4805; + break; + case 61: + mId=9714; + break; + case 62: + mId=6448; + break; + case 63: + mId=6442; + break; + case 64: + mId=14632; + break; + case 65: + mId=14332; + break; + case 66: + mId=14331; + break; + case 67: + mId=8469; + break; + case 68: + mId=2830; + break; + case 69: + mId=2346; + break; + default: + SendSysMessage(LANG_NO_MOUNT); + SetSentErrorMessage(true); + return false; + } + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_GIVE_MOUNT, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_MOUNT_GIVED), m_session->GetPlayer()->GetName()); + + chr->SetUInt32Value( UNIT_FIELD_FLAGS , 0x001000 ); + chr->Mount(mId); + + WorldPacket data( SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+1+4) ); + data.append(chr->GetPackGUID()); + data << (uint32)0; + data << (uint8)0; //new 2.1.0 + data << float(speed); + chr->SendMessageToSet( &data, true ); + + data.Initialize( SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4) ); + data.append(chr->GetPackGUID()); + data << (uint32)0; + data << float(speed); + chr->SendMessageToSet( &data, true ); + + return true; +} + +//Edit Player money +bool ChatHandler::HandleModifyMoneyCommand(const char* args) +{ + if (!*args) + return false; + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + int32 addmoney = atoi((char*)args); + + uint32 moneyuser = chr->GetMoney(); + + if(addmoney < 0) + { + int32 newmoney = moneyuser + addmoney; + + sLog.outDetail(GetMangosString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney); + if(newmoney <= 0 ) + { + PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, chr->GetName()); + + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_ALL_MONEY_GONE), m_session->GetPlayer()->GetName()); + + chr->SetMoney(0); + } + else + { + PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), chr->GetName()); + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_MONEY_TAKEN), m_session->GetPlayer()->GetName(), abs(addmoney)); + chr->SetMoney( newmoney ); + } + } + else + { + PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, chr->GetName()); + if(chr != m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(ChatHandler(chr).GetMangosString(LANG_YOURS_MONEY_GIVEN), m_session->GetPlayer()->GetName(), addmoney); + chr->ModifyMoney( addmoney ); + } + + sLog.outDetail(GetMangosString(LANG_NEW_MONEY), moneyuser, addmoney, chr->GetMoney() ); + + return true; +} + +//Edit Player field +bool ChatHandler::HandleModifyBitCommand(const char* args) +{ + if( !*args ) + return false; + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + char* pField = strtok((char*)args, " "); + if (!pField) + return false; + + char* pBit = strtok(NULL, " "); + if (!pBit) + return false; + + uint16 field = atoi(pField); + uint32 bit = atoi(pBit); + + if (field < 1 || field >= PLAYER_END) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + if (bit < 1 || bit > 32) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + if ( chr->HasFlag( field, (1<<(bit-1)) ) ) + { + chr->RemoveFlag( field, (1<<(bit-1)) ); + PSendSysMessage(LANG_REMOVE_BIT, bit, field); + } + else + { + chr->SetFlag( field, (1<<(bit-1)) ); + PSendSysMessage(LANG_SET_BIT, bit, field); + } + + return true; +} + +bool ChatHandler::HandleModifyHonorCommand (const char* args) +{ + if (!*args) + return false; + + Player *target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + int32 amount = (uint32)atoi(args); + + target->ModifyHonorPoints(amount); + + PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, target->GetName(), target->GetHonorPoints()); + + return true; +} + +bool ChatHandler::HandleTeleCommand(const char * args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r + GameTele const* tele = extractGameTeleFromLink((char*)args); + + if (!tele) + { + SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation); + return true; +} + +bool ChatHandler::HandleLookupAreaCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + uint32 counter = 0; // Counter for figure out that we found smth. + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + // Search in AreaTable.dbc + for (uint32 areaflag = 0; areaflag < sAreaStore.GetNumRows(); ++areaflag) + { + AreaTableEntry const *areaEntry = sAreaStore.LookupEntry(areaflag); + if(areaEntry) + { + int loc = m_session->GetSessionDbcLocale(); + std::string name = areaEntry->area_name[loc]; + if(name.empty()) + continue; + + if(!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(loc==m_session->GetSessionDbcLocale()) + continue; + + name = areaEntry->area_name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + // send area in "id - [name]" format + std::ostringstream ss; + ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << " " << localeNames[loc]<< "]|h|r"; + + SendSysMessage(ss.str().c_str()); + + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOAREAFOUND); + return true; +} + +//Find tele in game_tele order by name +bool ChatHandler::HandleLookupTeleCommand(const char * args) +{ + if(!*args) + { + SendSysMessage(LANG_COMMAND_TELE_PARAMETER); + SetSentErrorMessage(true); + return false; + } + char const* str = strtok((char*)args, " "); + if(!str) + return false; + + std::string namepart = str; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + GameTeleMap const & teleMap = objmgr.GetGameTeleMap(); + + std::ostringstream reply; + for(GameTeleMap::const_iterator itr = teleMap.begin(); itr != teleMap.end(); ++itr) + { + GameTele const* tele = &itr->second; + + if(tele->wnameLow.find(wnamepart) == std::wstring::npos) + continue; + + reply << " |cffffffff|Htele:"; + reply << itr->first; + reply << "|h["; + reply << tele->name; + reply << "]|h|r\n"; + } + + if(reply.str().empty()) + SendSysMessage(LANG_COMMAND_TELE_NOLOCATION); + else + PSendSysMessage(LANG_COMMAND_TELE_LOCATION,reply.str().c_str()); + + return true; +} + +//Enable\Dissable accept whispers (for GM) +bool ChatHandler::HandleWhispersCommand(const char* args) +{ + if(!*args) + { + PSendSysMessage(LANG_COMMAND_WHISPERACCEPTING, m_session->GetPlayer()->isAcceptWhispers() ? GetMangosString(LANG_ON) : GetMangosString(LANG_OFF)); + return true; + } + + std::string argstr = (char*)args; + // whisper on + if (argstr == "on") + { + m_session->GetPlayer()->SetAcceptWhispers(true); + SendSysMessage(LANG_COMMAND_WHISPERON); + return true; + } + + // whisper off + if (argstr == "off") + { + m_session->GetPlayer()->SetAcceptWhispers(false); + SendSysMessage(LANG_COMMAND_WHISPEROFF); + return true; + } + + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; +} + +//Play sound +bool ChatHandler::HandlePlaySoundCommand(const char* args) +{ + // USAGE: .debug playsound #soundid + // #soundid - ID decimal number from SoundEntries.dbc (1st column) + // this file have about 5000 sounds. + // In this realization only caller can hear this sound. + if( *args ) + { + uint32 dwSoundId = atoi((char*)args); + + if( !sSoundEntriesStore.LookupEntry(dwSoundId) ) + { + PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId); + SetSentErrorMessage(true); + return false; + } + + WorldPacket data(SMSG_PLAY_OBJECT_SOUND,4+8); + data << uint32(dwSoundId) << m_session->GetPlayer()->GetGUID(); + m_session->SendPacket(&data); + + PSendSysMessage(LANG_YOU_HEAR_SOUND, dwSoundId); + return true; + } + + return false; +} + +//Save all players in the world +bool ChatHandler::HandleSaveAllCommand(const char* /*args*/) +{ + ObjectAccessor::Instance().SaveAllPlayers(); + SendSysMessage(LANG_PLAYERS_SAVED); + return true; +} + +//Send mail by command +bool ChatHandler::HandleSendMailCommand(const char* args) +{ + if(!*args) + return false; + + // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] + + char* pName = strtok((char*)args, " "); + if(!pName) + return false; + + char* tail1 = strtok(NULL, ""); + if(!tail1) + return false; + + char* msgSubject; + if(*tail1=='"') + msgSubject = strtok(tail1+1, "\""); + else + { + char* space = strtok(tail1, "\""); + if(!space) + return false; + msgSubject = strtok(NULL, "\""); + } + + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if(!tail2) + return false; + + char* msgText; + if(*tail2=='"') + msgText = strtok(tail2+1, "\""); + else + { + char* space = strtok(tail2, "\""); + if(!space) + return false; + msgText = strtok(NULL, "\""); + } + + if (!msgText) + return false; + + // pName, msgSubject, msgText isn't NUL after prev. check + std::string name = pName; + std::string subject = msgSubject; + std::string text = msgText; + + // extract items + typedef std::pair ItemPair; + typedef std::list< ItemPair > ItemPairs; + ItemPairs items; + + // get all tail string + char* tail = strtok(NULL, ""); + + // get from tail next item str + while(char* itemStr = strtok(tail, " ")) + { + // and get new tail + tail = strtok(NULL, ""); + + // parse item str + char* itemIdStr = strtok(itemStr, ":"); + char* itemCountStr = strtok(NULL, " "); + + uint32 item_id = atoi(itemIdStr); + if(!item_id) + return false; + + ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id); + if(!item_proto) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); + SetSentErrorMessage(true); + return false; + } + + uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1; + if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount) + { + PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id); + SetSentErrorMessage(true); + return false; + } + + while(item_count > item_proto->Stackable) + { + items.push_back(ItemPair(item_id,item_proto->Stackable)); + item_count -= item_proto->Stackable; + } + + items.push_back(ItemPair(item_id,item_count)); + + if(items.size() > MAX_MAIL_ITEMS) + { + PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); + SetSentErrorMessage(true); + return false; + } + } + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); + if(!receiver_guid) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint32 mailId = objmgr.GenerateMailID(); + uint32 sender_guidlo = m_session->GetPlayer()->GetGUIDLow(); + uint32 messagetype = MAIL_NORMAL; + uint32 stationery = MAIL_STATIONERY_GM; + uint32 itemTextId = 0; + if (!text.empty()) + { + itemTextId = objmgr.CreateItemText( text ); + } + + Player *receiver = objmgr.GetPlayer(receiver_guid); + + // fill mail + MailItemsInfo mi; // item list preparing + + for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) + { + if(Item* item = Item::CreateItem(itr->first,itr->second,m_session->GetPlayer())) + { + item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + } + } + + WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE); + + PSendSysMessage(LANG_MAIL_SENT, name.c_str()); + return true; +} + +// teleport player to given game_tele.entry +bool ChatHandler::HandleNameTeleCommand(const char * args) +{ + if(!*args) + return false; + + char* pName = strtok((char*)args, " "); + + if(!pName) + return false; + + std::string name = pName; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + char* tail = strtok(NULL, ""); + if(!tail) + return false; + + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r + GameTele const* tele = extractGameTeleFromLink(tail); + if(!tele) + { + SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); + SetSentErrorMessage(true); + return false; + } + + Player *chr = objmgr.GetPlayer(name.c_str()); + if (chr) + { + + if(chr->IsBeingTeleported()==true) + { + PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName()); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_TELEPORTING_TO, chr->GetName(),"", tele->name.c_str()); + + if (m_session->GetPlayer()->IsVisibleGloballyFor(chr)) + ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, m_session->GetPlayer()->GetName()); + + // stop flight if need + if(chr->isInFlight()) + { + chr->GetMotionMaster()->MovementExpired(); + chr->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + chr->SaveRecallPosition(); + + chr->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation); + } + else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str())) + { + PSendSysMessage(LANG_TELEPORTING_TO, name.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str()); + Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y),guid); + } + else + PSendSysMessage(LANG_NO_PLAYER, name.c_str()); + + return true; +} + +//Teleport group to given game_tele.entry +bool ChatHandler::HandleGroupTeleCommand(const char * args) +{ + if(!*args) + return false; + + Player *player = getSelectedPlayer(); + if (!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r + GameTele const* tele = extractGameTeleFromLink((char*)args); + if(!tele) + { + SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); + SetSentErrorMessage(true); + return false; + } + + Group *grp = player->GetGroup(); + if(!grp) + { + PSendSysMessage(LANG_NOT_IN_GROUP,player->GetName()); + SetSentErrorMessage(true); + return false; + } + + for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pl = itr->getSource(); + + if(!pl || !pl->GetSession() ) + continue; + + if(pl->IsBeingTeleported()) + { + PSendSysMessage(LANG_IS_TELEPORTED, pl->GetName()); + continue; + } + + PSendSysMessage(LANG_TELEPORTING_TO, pl->GetName(),"", tele->name.c_str()); + + if (m_session->GetPlayer() != pl && m_session->GetPlayer()->IsVisibleGloballyFor(pl)) + ChatHandler(pl).PSendSysMessage(LANG_TELEPORTED_TO_BY, m_session->GetPlayer()->GetName()); + + // stop flight if need + if(pl->isInFlight()) + { + pl->GetMotionMaster()->MovementExpired(); + pl->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + pl->SaveRecallPosition(); + + pl->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation); + } + + return true; +} + +//Summon group of player +bool ChatHandler::HandleGroupgoCommand(const char* args) +{ + if(!*args) + return false; + + std::string name = args; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + Player *player = objmgr.GetPlayer(name.c_str()); + if (!player) + { + PSendSysMessage(LANG_NO_PLAYER, args); + SetSentErrorMessage(true); + return false; + } + + Group *grp = player->GetGroup(); + + if(!grp) + { + PSendSysMessage(LANG_NOT_IN_GROUP,player->GetName()); + SetSentErrorMessage(true); + return false; + } + + Map* gmMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer()); + bool to_instance = gmMap->Instanceable(); + + // we are in instance, and can summon only player in our group with us as lead + if ( to_instance && ( + !m_session->GetPlayer()->GetGroup() || (grp->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || + (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) ) ) + // the last check is a bit excessive, but let it be, just in case + { + SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); + SetSentErrorMessage(true); + return false; + } + + for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pl = itr->getSource(); + + if(!pl || pl==m_session->GetPlayer() || !pl->GetSession() ) + continue; + + if(pl->IsBeingTeleported()==true) + { + PSendSysMessage(LANG_IS_TELEPORTED, pl->GetName()); + SetSentErrorMessage(true); + return false; + } + + if (to_instance) + { + Map* plMap = MapManager::Instance().GetMap(pl->GetMapId(),pl); + + if ( plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId() ) + { + // cannot summon from instance to instance + PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,pl->GetName()); + SetSentErrorMessage(true); + return false; + } + } + + PSendSysMessage(LANG_SUMMONING, pl->GetName(),""); + + if (m_session->GetPlayer()->IsVisibleGloballyFor(pl)) + ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, m_session->GetPlayer()->GetName()); + + // stop flight if need + if(pl->isInFlight()) + { + pl->GetMotionMaster()->MovementExpired(); + pl->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + pl->SaveRecallPosition(); + + // before GM + float x,y,z; + m_session->GetPlayer()->GetClosePoint(x,y,z,pl->GetObjectSize()); + pl->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,pl->GetOrientation()); + } + + return true; +} + +//teleport at coordinates +bool ChatHandler::HandleGoXYCommand(const char* args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + uint32 mapid; + if (pmapid) + mapid = (uint32)atoi(pmapid); + else mapid = _player->GetMapId(); + + if(!MapManager::IsValidMapCoord(mapid,x,y)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + Map const *map = MapManager::Instance().GetBaseMap(mapid); + float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + + _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); + + return true; +} + +//teleport at coordinates, including Z +bool ChatHandler::HandleGoXYZCommand(const char* args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py || !pz) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + float z = (float)atof(pz); + uint32 mapid; + if (pmapid) + mapid = (uint32)atoi(pmapid); + else + mapid = _player->GetMapId(); + + if(!MapManager::IsValidMapCoord(mapid,x,y,z)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); + + return true; +} + +//teleport at coordinates +bool ChatHandler::HandleGoZoneXYCommand(const char* args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* tail = strtok(NULL,""); + + char* cAreaId = extractKeyFromLink(tail,"Harea"); // string or [name] Shift-click form |color|Harea:area_id|h[name]|h|r + + if (!px || !py) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + uint32 areaid = cAreaId ? (uint32)atoi(cAreaId) : _player->GetZoneId(); + + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaid); + + if( x<0 || x>100 || y<0 || y>100 || !areaEntry ) + { + PSendSysMessage(LANG_INVALID_ZONE_COORD,x,y,areaid); + SetSentErrorMessage(true); + return false; + } + + // update to parent zone if exist (client map show only zones without parents) + AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry; + + Map const *map = MapManager::Instance().GetBaseMap(zoneEntry->mapid); + + if(map->Instanceable()) + { + PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[m_session->GetSessionDbcLocale()],map->GetId(),map->GetMapName()); + SetSentErrorMessage(true); + return false; + } + + Zone2MapCoordinates(x,y,zoneEntry->ID); + + if(!MapManager::IsValidMapCoord(zoneEntry->mapid,x,y)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,zoneEntry->mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + _player->TeleportTo(zoneEntry->mapid, x, y, z, _player->GetOrientation()); + + return true; +} + +//teleport to grid +bool ChatHandler::HandleGoGridCommand(const char* args) +{ + if(!*args) return false; + Player* _player = m_session->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py) + return false; + + float grid_x = (float)atof(px); + float grid_y = (float)atof(py); + uint32 mapid; + if (pmapid) + mapid = (uint32)atoi(pmapid); + else mapid = _player->GetMapId(); + + // center of grid + float x = (grid_x-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS; + float y = (grid_y-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS; + + if(!MapManager::IsValidMapCoord(mapid,x,y)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + Map const *map = MapManager::Instance().GetBaseMap(mapid); + float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); + + return true; +} + +bool ChatHandler::HandleDrunkCommand(const char* args) +{ + if(!*args) return false; + + uint32 drunklevel = (uint32)atoi(args); + if(drunklevel > 100) + drunklevel = 100; + + uint16 drunkMod = drunklevel * 0xFFFF / 100; + + m_session->GetPlayer()->SetDrunkValue(drunkMod); + + return true; +} diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp new file mode 100644 index 000000000..83e626245 --- /dev/null +++ b/src/game/Level2.cpp @@ -0,0 +1,4008 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Item.h" +#include "GameObject.h" +#include "Opcodes.h" +#include "Chat.h" +#include "ObjectAccessor.h" +#include "MapManager.h" +#include "Language.h" +#include "World.h" +#include "GameEvent.h" +#include "SpellMgr.h" +#include "AccountMgr.h" +#include "WaypointManager.h" +#include "Util.h" +#include +#include +#include +#include + +static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] = +{ + LANG_REP_HATED, LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL, + LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED, LANG_REP_EXALTED +}; + +//mute player for some times +bool ChatHandler::HandleMuteCommand(const char* args) +{ + if (!*args) + return false; + + char *charname = strtok((char*)args, " "); + if (!charname) + return false; + + std::string cname = charname; + + char *timetonotspeak = strtok(NULL, " "); + if(!timetonotspeak) + return false; + + uint32 notspeaktime = (uint32) atoi(timetonotspeak); + + if(!normalizePlayerName(cname)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); + if(!guid) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + Player *chr = objmgr.GetPlayer(guid); + + // check security + uint32 account_id = 0; + uint32 security = 0; + + if (chr) + { + account_id = chr->GetSession()->GetAccountId(); + security = chr->GetSession()->GetSecurity(); + } + else + { + account_id = objmgr.GetPlayerAccountIdByGUID(guid); + security = objmgr.GetSecurityByAccount(account_id); + } + + if(security >= m_session->GetSecurity()) + { + SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage(true); + return false; + } + + time_t mutetime = time(NULL) + notspeaktime*60; + + if (chr) + chr->GetSession()->m_muteTime = mutetime; + + loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); + + if(chr) + ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); + + PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime); + + return true; +} + +//unmute player +bool ChatHandler::HandleUnmuteCommand(const char* args) +{ + if (!*args) + return false; + + char *charname = strtok((char*)args, " "); + if (!charname) + return false; + + std::string cname = charname; + + if(!normalizePlayerName(cname)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); + if(!guid) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + Player *chr = objmgr.GetPlayer(guid); + + // check security + uint32 account_id = 0; + uint32 security = 0; + + if (chr) + { + account_id = chr->GetSession()->GetAccountId(); + security = chr->GetSession()->GetSecurity(); + } + else + { + account_id = objmgr.GetPlayerAccountIdByGUID(guid); + security = objmgr.GetSecurityByAccount(account_id); + } + + if(security >= m_session->GetSecurity()) + { + SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage(true); + return false; + } + + if (chr) + { + if(chr->CanSpeak()) + { + SendSysMessage(LANG_CHAT_ALREADY_ENABLED); + SetSentErrorMessage(true); + return false; + } + + chr->GetSession()->m_muteTime = 0; + } + + loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id ); + + if(chr) + ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); + + PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str()); + return true; +} + +bool ChatHandler::HandleTargetObjectCommand(const char* args) +{ + Player* pl = m_session->GetPlayer(); + QueryResult *result; + GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList(); + if(*args) + { + int32 id = atoi((char*)args); + if(id) + result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id); + else + { + std::string name = args; + WorldDatabase.escape_string(name); + result = WorldDatabase.PQuery( + "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " + "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str()); + } + } + else + { + std::ostringstream eventFilter; + eventFilter << " AND (event IS NULL "; + bool initString = true; + + for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr) + { + if (initString) + { + eventFilter << "OR event IN (" <<*itr; + initString =false; + } + else + eventFilter << "," << *itr; + } + + if (!initString) + eventFilter << "))"; + else + eventFilter << ")"; + + result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, " + "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject " + "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1", + m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str()); + } + + if (!result) + { + SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND); + return true; + } + + Field *fields = result->Fetch(); + uint32 lowguid = fields[0].GetUInt32(); + uint32 id = fields[1].GetUInt32(); + float x = fields[2].GetFloat(); + float y = fields[3].GetFloat(); + float z = fields[4].GetFloat(); + float o = fields[5].GetFloat(); + int mapid = fields[6].GetUInt16(); + delete result; + + GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id); + + if (!goI) + { + PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); + return false; + } + + GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT)); + + PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o); + + if(target) + { + int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); + if(curRespawnDelay < 0) + curRespawnDelay = 0; + + std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); + std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); + + PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); + } + return true; +} + +//teleport to gameobject +bool ChatHandler::HandleGoObjectCommand(const char* args) +{ + if(!*args) + return false; + + Player* _player = m_session->GetPlayer(); + + // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameobject"); + if(!cId) + return false; + + int32 guid = atoi(cId); + if(!guid) + return false; + + float x, y, z, ort; + int mapid; + + // by DB guid + if (GameObjectData const* go_data = objmgr.GetGOData(guid)) + { + x = go_data->posX; + y = go_data->posY; + z = go_data->posZ; + ort = go_data->orientation; + mapid = go_data->mapid; + } + else + { + SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND); + SetSentErrorMessage(true); + return false; + } + + if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, ort); + return true; +} + +bool ChatHandler::HandleGoTriggerCommand(const char* args) +{ + Player* _player = m_session->GetPlayer(); + + if (!*args) + return false; + + char *atId = strtok((char*)args, " "); + if (!atId) + return false; + + int32 i_atId = atoi(atId); + + if(!i_atId) + return false; + + AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId); + if (!at) + { + PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId); + SetSentErrorMessage(true); + return false; + } + + if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation()); + return true; +} + +bool ChatHandler::HandleGoGraveyardCommand(const char* args) +{ + Player* _player = m_session->GetPlayer(); + + if (!*args) + return false; + + char *gyId = strtok((char*)args, " "); + if (!gyId) + return false; + + int32 i_gyId = atoi(gyId); + + if(!i_gyId) + return false; + + WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId); + if (!gy) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId); + SetSentErrorMessage(true); + return false; + } + + if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation()); + return true; +} + +/** \brief Teleport the GM to the specified creature + * + * .gocreature --> TP using creature.guid + * .gocreature azuregos --> TP player to the mob with this name + * Warning: If there is more than one mob with this name + * you will be teleported to the first one that is found. + * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry + * Warning: If there is more than one mob with this "id" + * you will be teleported to the first one that is found. + */ +//teleport to creature +bool ChatHandler::HandleGoCreatureCommand(const char* args) +{ + if(!*args) + return false; + Player* _player = m_session->GetPlayer(); + + // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* pParam1 = extractKeyFromLink((char*)args,"Hcreature"); + if (!pParam1) + return false; + + std::ostringstream whereClause; + + // User wants to teleport to the NPC's template entry + if( strcmp(pParam1, "id") == 0 ) + { + //sLog.outError("DEBUG: ID found"); + + // Get the "creature_template.entry" + // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* tail = strtok(NULL,""); + if(!tail) + return false; + char* cId = extractKeyFromLink(tail,"Hcreature_entry"); + if(!cId) + return false; + + int32 tEntry = atoi(cId); + //sLog.outError("DEBUG: ID value: %d", tEntry); + if(!tEntry) + return false; + + whereClause << "WHERE id = '" << tEntry << "'"; + } + else + { + //sLog.outError("DEBUG: ID *not found*"); + + int32 guid = atoi(pParam1); + + // Number is invalid - maybe the user specified the mob's name + if(!guid) + { + std::string name = pParam1; + WorldDatabase.escape_string(name); + whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'"; + } + else + { + whereClause << "WHERE guid = '" << guid << "'"; + } + } + //sLog.outError("DEBUG: %s", whereClause.c_str()); + + QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() ); + if (!result) + { + SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); + SetSentErrorMessage(true); + return false; + } + if( result->GetRowCount() > 1 ) + { + SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE); + } + + Field *fields = result->Fetch(); + float x = fields[0].GetFloat(); + float y = fields[1].GetFloat(); + float z = fields[2].GetFloat(); + float ort = fields[3].GetFloat(); + int mapid = fields[4].GetUInt16(); + + delete result; + + if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if(_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, ort); + return true; +} + +bool ChatHandler::HandleGUIDCommand(const char* /*args*/) +{ + uint64 guid = m_session->GetPlayer()->GetSelection(); + + if (guid == 0) + { + SendSysMessage(LANG_NO_SELECTION); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); + return true; +} + +bool ChatHandler::HandleLookupFactionCommand(const char* args) +{ + if(!*args) + return false; + + Player *target = getSelectedPlayer(); + if (!target) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + for (uint32 id = 0; id < sFactionStore.GetNumRows(); id++) + //for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr) + { + FactionEntry const *factionEntry = sFactionStore.LookupEntry(id); + //FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); + if (factionEntry) + { + FactionStateList::const_iterator repItr = target->m_factions.find(factionEntry->reputationListID); + + int loc = m_session->GetSessionDbcLocale(); + std::string name = factionEntry->name[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(loc==m_session->GetSessionDbcLocale()) + continue; + + name = factionEntry->name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format + // or "id - [faction] [no reputation]" format + std::ostringstream ss; + ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r"; + + if (repItr != target->m_factions.end()) + { + ReputationRank rank = target->GetReputationRank(factionEntry); + std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); + + ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")"; + + if(repItr->second.Flags & FACTION_FLAG_VISIBLE) + ss << GetMangosString(LANG_FACTION_VISIBLE); + if(repItr->second.Flags & FACTION_FLAG_AT_WAR) + ss << GetMangosString(LANG_FACTION_ATWAR); + if(repItr->second.Flags & FACTION_FLAG_PEACE_FORCED) + ss << GetMangosString(LANG_FACTION_PEACE_FORCED); + if(repItr->second.Flags & FACTION_FLAG_HIDDEN) + ss << GetMangosString(LANG_FACTION_HIDDEN); + if(repItr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED) + ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED); + if(repItr->second.Flags & FACTION_FLAG_INACTIVE) + ss << GetMangosString(LANG_FACTION_INACTIVE); + } + else + ss << GetMangosString(LANG_FACTION_NOREPUTATION); + + SendSysMessage(ss.str().c_str()); + counter++; + } + } + } + + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND); + return true; +} + +bool ChatHandler::HandleModifyRepCommand(const char * args) +{ + if (!*args) return false; + + Player* target = NULL; + target = getSelectedPlayer(); + + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + char* factionTxt = extractKeyFromLink((char*)args,"Hfaction"); + if(!factionTxt) + return false; + + uint32 factionId = atoi(factionTxt); + + int32 amount = 0; + char *rankTxt = strtok(NULL, " "); + if (!factionTxt || !rankTxt) + return false; + + amount = atoi(rankTxt); + if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0])) + { + std::string rankStr = rankTxt; + std::wstring wrankStr; + if(!Utf8toWStr(rankStr,wrankStr)) + return false; + wstrToLower( wrankStr ); + + int r = 0; + amount = -42000; + for (; r < MAX_REPUTATION_RANK; ++r) + { + std::string rank = GetMangosString(ReputationRankStrIndex[r]); + if(rank.empty()) + continue; + + std::wstring wrank; + if(!Utf8toWStr(rank,wrank)) + continue; + + wstrToLower(wrank); + + if(wrank.substr(0,wrankStr.size())==wrankStr) + { + char *deltaTxt = strtok(NULL, " "); + if (deltaTxt) + { + int32 delta = atoi(deltaTxt); + if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1)) + { + PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1)); + SetSentErrorMessage(true); + return false; + } + amount += delta; + } + break; + } + amount += Player::ReputationRank_Length[r]; + } + if (r >= MAX_REPUTATION_RANK) + { + PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt); + SetSentErrorMessage(true); + return false; + } + } + + FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId); + + if (!factionEntry) + { + PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId); + SetSentErrorMessage(true); + return false; + } + + if (factionEntry->reputationListID < 0) + { + PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId); + SetSentErrorMessage(true); + return false; + } + + target->SetFactionReputation(factionEntry,amount); + PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId)); + return true; +} + +bool ChatHandler::HandleNameCommand(const char* args) +{ + /* Temp. disabled + if(!*args) + return false; + + if(strlen((char*)args)>75) + { + PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75); + return true; + } + + for (uint8 i = 0; i < strlen(args); i++) + { + if(!isalpha(args[i]) && args[i]!=' ') + { + SendSysMessage(LANG_CHARS_ONLY); + return false; + } + } + + uint64 guid; + guid = m_session->GetPlayer()->GetSelection(); + if (guid == 0) + { + SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + pCreature->SetName(args); + uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName()); + pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); + + pCreature->SaveToDB(); + */ + + return true; +} + +bool ChatHandler::HandleSubNameCommand(const char* /*args*/) +{ + /* Temp. disabled + + if(!*args) + args = ""; + + if(strlen((char*)args)>75) + { + + PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75); + return true; + } + + for (uint8 i = 0; i < strlen(args); i++) + { + if(!isalpha(args[i]) && args[i]!=' ') + { + SendSysMessage(LANG_CHARS_ONLY); + return false; + } + } + uint64 guid; + guid = m_session->GetPlayer()->GetSelection(); + if (guid == 0) + { + SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID)); + pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); + + pCreature->SaveToDB(); + */ + return true; +} + +//move item to other slot +bool ChatHandler::HandleItemMoveCommand(const char* args) +{ + if(!*args) + return false; + uint8 srcslot, dstslot; + + char* pParam1 = strtok((char*)args, " "); + if (!pParam1) + return false; + + char* pParam2 = strtok(NULL, " "); + if (!pParam2) + return false; + + srcslot = (uint8)atoi(pParam1); + dstslot = (uint8)atoi(pParam2); + + uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot); + uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot); + + if(srcslot==dstslot) + return true; + + m_session->GetPlayer()->SwapItem( src, dst ); + + return true; +} + +//add spawn of creature +bool ChatHandler::HandleAddSpwCommand(const char* args) +{ + if(!*args) + return false; + char* charID = strtok((char*)args, " "); + if (!charID) + return false; + + char* team = strtok(NULL, " "); + int32 teamval = 0; + if (team) { teamval = atoi(team); } + if (teamval < 0) { teamval = 0; } + + uint32 id = atoi(charID); + + Player *chr = m_session->GetPlayer(); + float x = chr->GetPositionX(); + float y = chr->GetPositionY(); + float z = chr->GetPositionZ(); + float o = chr->GetOrientation(); + Map *map = chr->GetMap(); + + Creature* pCreature = new Creature; + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval)) + { + delete pCreature; + return false; + } + + pCreature->Relocate(x,y,z,o); + + if(!pCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); + delete pCreature; + return false; + } + + pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + + uint32 db_guid = pCreature->GetDBTableGUIDLow(); + + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + pCreature->LoadFromDB(db_guid, map); + + map->Add(pCreature); + objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid)); + return true; +} + +bool ChatHandler::HandleDelCreatureCommand(const char* args) +{ + Creature* unit = NULL; + + if(*args) + { + // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hcreature"); + if(!cId) + return false; + + uint32 lowguid = atoi(cId); + if(!lowguid) + return false; + + if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid)) + unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT)); + } + else + unit = getSelectedCreature(); + + if(!unit || unit->isPet() || unit->isTotem()) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // Delete the creature + unit->CombatStop(); + unit->DeleteFromDB(); + unit->CleanupsBeforeDelete(); + unit->AddObjectToRemoveList(); + + SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); + + return true; +} + +//delete object by selection or guid +bool ChatHandler::HandleDelObjectCommand(const char* args) +{ + // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameobject"); + if(!cId) + return false; + + uint32 lowguid = atoi(cId); + if(!lowguid) + return false; + + GameObject* obj = NULL; + + // by DB guid + if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) + obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); + + if(!obj) + { + PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + uint64 owner_guid = obj->GetOwnerGUID(); + if(owner_guid) + { + Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid); + if(!owner && !IS_PLAYER_GUID(owner_guid)) + { + PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow()); + SetSentErrorMessage(true); + return false; + } + + owner->RemoveGameObject(obj,false); + } + + obj->SetRespawnTime(0); // not save respawn time + obj->Delete(); + obj->DeleteFromDB(); + + PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow()); + + return true; +} + +//turn selected object +bool ChatHandler::HandleTurnObjectCommand(const char* args) +{ + // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameobject"); + if(!cId) + return false; + + uint32 lowguid = atoi(cId); + if(!lowguid) + return false; + + GameObject* obj = NULL; + + // by DB guid + if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) + obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); + + if(!obj) + { + PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + char* po = strtok(NULL, " "); + float o; + + if (po) + { + o = (float)atof(po); + } + else + { + Player *chr = m_session->GetPlayer(); + o = chr->GetOrientation(); + } + + float rot2 = sin(o/2); + float rot3 = cos(o/2); + + Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); + map->Remove(obj,false); + + obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o); + + obj->SetFloatValue(GAMEOBJECT_FACING, o); + obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2); + obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3); + + map->Add(obj); + + obj->SaveToDB(); + obj->Refresh(); + + PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o); + + return true; +} + +//move selected creature +bool ChatHandler::HandleMoveCreatureCommand(const char* args) +{ + uint32 lowguid = 0; + + Creature* pCreature = getSelectedCreature(); + + if(!pCreature) + { + // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hcreature"); + if(!cId) + return false; + + uint32 lowguid = atoi(cId); + + /* FIXME: impossibel without entry + if(lowguid) + pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); + */ + + // Attempting creature load from DB data + if(!pCreature) + { + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + uint32 map_id = data->mapid; + + if(m_session->GetPlayer()->GetMapId()!=map_id) + { + PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); + SetSentErrorMessage(true); + return false; + } + } + else + { + lowguid = pCreature->GetDBTableGUIDLow(); + } + } + else + { + lowguid = pCreature->GetDBTableGUIDLow(); + } + + float x = m_session->GetPlayer()->GetPositionX(); + float y = m_session->GetPlayer()->GetPositionY(); + float z = m_session->GetPlayer()->GetPositionZ(); + float o = m_session->GetPlayer()->GetOrientation(); + + if (pCreature) + { + if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow())) + { + const_cast(data)->posX = x; + const_cast(data)->posY = y; + const_cast(data)->posZ = z; + const_cast(data)->orientation = o; + } + MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o); + pCreature->GetMotionMaster()->Initialize(); + if(pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + } + + WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); + PSendSysMessage(LANG_COMMAND_CREATUREMOVED); + return true; +} + +//move selected object +bool ChatHandler::HandleMoveObjectCommand(const char* args) +{ + // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameobject"); + if(!cId) + return false; + + uint32 lowguid = atoi(cId); + if(!lowguid) + return false; + + GameObject* obj = NULL; + + // by DB guid + if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) + obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); + + if(!obj) + { + PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + char* px = strtok(NULL, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + + if (!px) + { + Player *chr = m_session->GetPlayer(); + + Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); + map->Remove(obj,false); + + obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation()); + obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX()); + obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY()); + obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ()); + + map->Add(obj); + } + else + { + if(!py || !pz) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + float z = (float)atof(pz); + + if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId()); + SetSentErrorMessage(true); + return false; + } + + Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); + map->Remove(obj,false); + + obj->Relocate(x, y, z, obj->GetOrientation()); + obj->SetFloatValue(GAMEOBJECT_POS_X, x); + obj->SetFloatValue(GAMEOBJECT_POS_Y, y); + obj->SetFloatValue(GAMEOBJECT_POS_Z, z); + + map->Add(obj); + } + + obj->SaveToDB(); + obj->Refresh(); + + PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow()); + + return true; +} + +//demorph player or unit +bool ChatHandler::HandleDeMorphCommand(const char* /*args*/) +{ + Unit *target = getSelectedUnit(); + if(!target) + target = m_session->GetPlayer(); + + target->DeMorph(); + + return true; +} + +//add item in vendorlist +bool ChatHandler::HandleAddVendorItemCommand(const char* args) +{ + if (!*args) + return false; + + char* pitem = extractKeyFromLink((char*)args,"Hitem"); + if (!pitem) + { + SendSysMessage(LANG_COMMAND_NEEDITEMSEND); + SetSentErrorMessage(true); + return false; + } + + uint32 itemId = atol(pitem); + + char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 + uint32 maxcount = 0; + if (fmaxcount) + maxcount = atol(fmaxcount); + + char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0 + uint32 incrtime = 0; + if (fincrtime) + incrtime = atol(fincrtime); + + char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 + uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; + + Creature* vendor = getSelectedCreature(); + + uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; + + if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer())) + { + SetSentErrorMessage(true); + return false; + } + + objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost); + + ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId); + + PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost); + return true; +} + +//del item from vendor list +bool ChatHandler::HandleDelVendorItemCommand(const char* args) +{ + if (!*args) + return false; + + Creature* vendor = getSelectedCreature(); + if (!vendor || !vendor->isVendor()) + { + SendSysMessage(LANG_COMMAND_VENDORSELECTION); + SetSentErrorMessage(true); + return false; + } + + char* pitem = extractKeyFromLink((char*)args,"Hitem"); + if (!pitem) + { + SendSysMessage(LANG_COMMAND_NEEDITEMSEND); + SetSentErrorMessage(true); + return false; + } + uint32 itemId = atol(pitem); + + if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId)) + { + PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); + SetSentErrorMessage(true); + return false; + } + + ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId); + + PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1); + return true; +} + +//add move for creature +bool ChatHandler::HandleAddMoveCommand(const char* args) +{ + if(!*args) + return false; + + char* guid_str = strtok((char*)args, " "); + char* wait_str = strtok((char*)NULL, " "); + + uint32 lowguid = atoi((char*)guid_str); + + Creature* pCreature = NULL; + + /* FIXME: impossible without entry + if(lowguid) + pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); + */ + + // attempt check creature existence by DB data + if(!pCreature) + { + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + } + else + { + // obtain real GUID for DB operations + lowguid = pCreature->GetDBTableGUIDLow(); + } + + int wait = wait_str ? atoi(wait_str) : 0; + + if(wait < 0) + wait = 0; + + Player* player = m_session->GetPlayer(); + + WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0); + + // update movement type + WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); + if(pCreature) + { + pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); + pCreature->GetMotionMaster()->Initialize(); + if(pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + pCreature->SaveToDB(); + } + + SendSysMessage(LANG_WAYPOINT_ADDED); + + return true; +} + +/** + * Set the movement type for an NPC.
+ *
+ * Valid movement types are: + *
    + *
  • stay - NPC wont move
  • + *
  • random - NPC will move randomly according to the spawndist
  • + *
  • way - NPC will move with given waypoints set
  • + *
+ * additional parameter: NODEL - so no waypoints are deleted, if you + * change the movement type + */ +bool ChatHandler::HandleSetMoveTypeCommand(const char* args) +{ + if(!*args) + return false; + + // 3 arguments: + // GUID (optional - you can also select the creature) + // stay|random|way (determines the kind of movement) + // NODEL (optional - tells the system NOT to delete any waypoints) + // this is very handy if you want to do waypoints, that are + // later switched on/off according to special events (like escort + // quests, etc) + char* guid_str = strtok((char*)args, " "); + char* type_str = strtok((char*)NULL, " "); + char* dontdel_str = strtok((char*)NULL, " "); + + bool doNotDelete = false; + + if(!guid_str) + return false; + + uint32 lowguid = 0; + Creature* pCreature = NULL; + + if( dontdel_str ) + { + //sLog.outError("DEBUG: All 3 params are set"); + + // All 3 params are set + // GUID + // type + // doNotDEL + if( stricmp( dontdel_str, "NODEL" ) == 0 ) + { + //sLog.outError("DEBUG: doNotDelete = true;"); + doNotDelete = true; + } + } + else + { + // Only 2 params - but maybe NODEL is set + if( type_str ) + { + sLog.outError("DEBUG: Only 2 params "); + if( stricmp( type_str, "NODEL" ) == 0 ) + { + //sLog.outError("DEBUG: type_str, NODEL "); + doNotDelete = true; + type_str = NULL; + } + } + } + + if(!type_str) // case .setmovetype $move_type (with selected creature) + { + type_str = guid_str; + pCreature = getSelectedCreature(); + if(!pCreature || pCreature->isPet()) + return false; + lowguid = pCreature->GetDBTableGUIDLow(); + } + else // case .setmovetype #creature_guid $move_type (with selected creature) + { + lowguid = atoi((char*)guid_str); + + /* impossible without entry + if(lowguid) + pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); + */ + + // attempt check creature existence by DB data + if(!pCreature) + { + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + } + else + { + lowguid = pCreature->GetDBTableGUIDLow(); + } + } + + // now lowguid is low guid really existed creature + // and pCreature point (maybe) to this creature or NULL + + MovementGeneratorType move_type; + + std::string type = type_str; + + if(type == "stay") + move_type = IDLE_MOTION_TYPE; + else if(type == "random") + move_type = RANDOM_MOTION_TYPE; + else if(type == "way") + move_type = WAYPOINT_MOTION_TYPE; + else + return false; + + // update movement type + if(doNotDelete == false) + WaypointMgr.DeletePath(lowguid); + + if(pCreature) + { + pCreature->SetDefaultMovementType(move_type); + pCreature->GetMotionMaster()->Initialize(); + if(pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + pCreature->SaveToDB(); + } + if( doNotDelete == false ) + { + PSendSysMessage(LANG_MOVE_TYPE_SET,type_str); + } + else + { + PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str); + } + + return true; +} // HandleSetMoveTypeCommand + +//change level of creature or pet +bool ChatHandler::HandleChangeLevelCommand(const char* args) +{ + if (!*args) + return false; + + uint8 lvl = (uint8) atoi((char*)args); + if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Creature* pCreature = getSelectedCreature(); + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(pCreature->isPet()) + { + ((Pet*)pCreature)->GivePetLevel(lvl); + } + else + { + pCreature->SetMaxHealth( 100 + 30*lvl); + pCreature->SetHealth( 100 + 30*lvl); + pCreature->SetLevel( lvl); + pCreature->SaveToDB(); + } + + return true; +} + +//set npcflag of creature +bool ChatHandler::HandleNPCFlagCommand(const char* args) +{ + if (!*args) + return false; + + uint32 npcFlags = (uint32) atoi((char*)args); + + Creature* pCreature = getSelectedCreature(); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); + + WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); + + SendSysMessage(LANG_VALUE_SAVED_REJOIN); + + return true; +} + +//set model of creature +bool ChatHandler::HandleSetModelCommand(const char* args) +{ + if (!*args) + return false; + + uint32 displayId = (uint32) atoi((char*)args); + + Creature *pCreature = getSelectedCreature(); + + if(!pCreature || pCreature->isPet()) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + pCreature->SetDisplayId(displayId); + pCreature->SetNativeDisplayId(displayId); + + pCreature->SaveToDB(); + + return true; +} + +//morph creature or player +bool ChatHandler::HandleMorphCommand(const char* args) +{ + if (!*args) + return false; + + uint16 display_id = (uint16)atoi((char*)args); + + Unit *target = getSelectedUnit(); + if(!target) + target = m_session->GetPlayer(); + + target->SetDisplayId(display_id); + + return true; +} + +//set faction of creature or go +bool ChatHandler::HandleFactionIdCommand(const char* args) +{ + if (!*args) + return false; + + uint32 factionId = (uint32) atoi((char*)args); + + if (!sFactionTemplateStore.LookupEntry(factionId)) + { + PSendSysMessage(LANG_WRONG_FACTION, factionId); + SetSentErrorMessage(true); + return false; + } + + Creature* pCreature = getSelectedCreature(); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + pCreature->setFaction(factionId); + + // faction is set in creature_template - not inside creature + + // update in memory + if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo()) + { + const_cast(cinfo)->faction_A = factionId; + const_cast(cinfo)->faction_H = factionId; + } + + // and DB + WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry()); + + return true; +} + +//kick player +bool ChatHandler::HandleKickPlayerCommand(const char *args) +{ + char* kickName = strtok((char*)args, " "); + if (!kickName) + { + Player* player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(player==m_session->GetPlayer()) + { + SendSysMessage(LANG_COMMAND_KICKSELF); + SetSentErrorMessage(true); + return false; + } + + player->GetSession()->KickPlayer(); + } + else + { + std::string name = kickName; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(name==m_session->GetPlayer()->GetName()) + { + SendSysMessage(LANG_COMMAND_KICKSELF); + SetSentErrorMessage(true); + return false; + } + + if(sWorld.KickPlayer(name)) + { + PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str()); + } + else + PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str()); + } + + return true; +} + +//show info of player +bool ChatHandler::HandlePInfoCommand(const char* args) +{ + Player* target = NULL; + uint64 targetGUID = 0; + + char* px = strtok((char*)args, " "); + char* py = NULL; + + std::string name; + + if (px) + { + name = px; + + if(name.empty()) + return false; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + target = objmgr.GetPlayer(name.c_str()); + if (target) + py = strtok(NULL, " "); + else + { + targetGUID = objmgr.GetPlayerGUIDByName(name); + if(targetGUID) + py = strtok(NULL, " "); + else + py = px; + } + } + + if(!target && !targetGUID) + { + target = getSelectedPlayer(); + } + + if(!target && !targetGUID) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint32 accId = 0; + uint32 money = 0; + uint32 total_player_time = 0; + uint32 level = 0; + uint32 latency = 0; + + // get additional information from Player object + if(target) + { + targetGUID = target->GetGUID(); + name = target->GetName(); // re-read for case getSelectedPlayer() target + accId = target->GetSession()->GetAccountId(); + money = target->GetMoney(); + total_player_time = target->GetTotalPlayedTime(); + level = target->getLevel(); + latency = target->GetSession()->GetLatency(); + } + // get additional information from DB + else + { + accId = objmgr.GetPlayerAccountIdByGUID(targetGUID); + Player plr(m_session); // use current session for temporary load + plr.MinimalLoadFromDB(NULL, targetGUID); + money = plr.GetMoney(); + total_player_time = plr.GetTotalPlayedTime(); + level = plr.getLevel(); + } + + std::string username = GetMangosString(LANG_ERROR); + std::string last_ip = GetMangosString(LANG_ERROR); + uint32 security = 0; + std::string last_login = GetMangosString(LANG_ERROR); + + QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId); + if(result) + { + Field* fields = result->Fetch(); + username = fields[0].GetCppString(); + security = fields[1].GetUInt32(); + if(m_session->GetSecurity() >= security) + { + last_ip = fields[2].GetCppString(); + last_login = fields[3].GetCppString(); + } + else + { + last_ip = "-"; + last_login = "-"; + } + + delete result; + } + + PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency); + + std::string timeStr = secsToTimeString(total_player_time,true,true); + uint32 gold = money /GOLD; + uint32 silv = (money % GOLD) / SILVER; + uint32 copp = (money % GOLD) % SILVER; + PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp ); + + if ( py && strncmp(py, "rep", 3) == 0 ) + { + if(!target) + { + // rep option not implemented for offline case + SendSysMessage(LANG_PINFO_NO_REP); + SetSentErrorMessage(true); + return false; + } + + char* FactionName; + for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr) + { + FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); + if (factionEntry) + FactionName = factionEntry->name[m_session->GetSessionDbcLocale()]; + else + FactionName = "#Not found#"; + ReputationRank rank = target->GetReputationRank(factionEntry); + std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); + std::ostringstream ss; + ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")"; + + if(itr->second.Flags & FACTION_FLAG_VISIBLE) + ss << GetMangosString(LANG_FACTION_VISIBLE); + if(itr->second.Flags & FACTION_FLAG_AT_WAR) + ss << GetMangosString(LANG_FACTION_ATWAR); + if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED) + ss << GetMangosString(LANG_FACTION_PEACE_FORCED); + if(itr->second.Flags & FACTION_FLAG_HIDDEN) + ss << GetMangosString(LANG_FACTION_HIDDEN); + if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED) + ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED); + if(itr->second.Flags & FACTION_FLAG_INACTIVE) + ss << GetMangosString(LANG_FACTION_INACTIVE); + + SendSysMessage(ss.str().c_str()); + } + } + return true; +} + +//show tickets +void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time) +{ + std::string name; + if(!objmgr.GetPlayerNameByGUID(guid,name)) + name = GetMangosString(LANG_UNKNOWN); + + PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text); +} + +//ticket commands +bool ChatHandler::HandleTicketCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + + // ticket + if (!px) + { + size_t count; + QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket"); + if(result) + { + count = (*result)[0].GetUInt32(); + delete result; + } + else + count = 0; + + PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, m_session->GetPlayer()->isAcceptTickets() ? GetMangosString(LANG_ON) : GetMangosString(LANG_OFF)); + return true; + } + + // ticket on + if(strncmp(px,"on",3) == 0) + { + m_session->GetPlayer()->SetAcceptTicket(true); + SendSysMessage(LANG_COMMAND_TICKETON); + return true; + } + + // ticket off + if(strncmp(px,"off",4) == 0) + { + m_session->GetPlayer()->SetAcceptTicket(false); + SendSysMessage(LANG_COMMAND_TICKETOFF); + return true; + } + + // ticket #num + int num = atoi(px); + if(num > 0) + { + QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC LIMIT %d,1",num-1); + + if(!result) + { + PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); + delete result; + SetSentErrorMessage(true); + return false; + } + + Field* fields = result->Fetch(); + + uint64 guid = fields[0].GetUInt64(); + char const* text = fields[1].GetString(); + char const* time = fields[2].GetString(); + + ShowTicket(guid,text,time); + delete result; + return true; + } + + std::string name = px; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + + if(!guid) + return false; + + // ticket $char_name + QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid)); + + if(!result) + return false; + + Field* fields = result->Fetch(); + + char const* text = fields[0].GetString(); + char const* time = fields[1].GetString(); + + ShowTicket(guid,text,time); + delete result; + + return true; +} + +uint32 ChatHandler::GetTicketIDByNum(uint32 num) +{ + QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket"); + + if(!result || num > result->GetRowCount()) + { + PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); + delete result; + return 0; + } + + for(uint32 i = 1; i < num; ++i) + result->NextRow(); + + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + delete result; + return id; +} + +//dell all tickets +bool ChatHandler::HandleDelTicketCommand(const char *args) +{ + char* px = strtok((char*)args, " "); + if (!px) + return false; + + // delticket all + if(strncmp(px,"all",4) == 0) + { + QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket"); + + if(!result) + return true; + + // notify players about ticket deleting + do + { + Field* fields = result->Fetch(); + + uint64 guid = fields[0].GetUInt64(); + + if(Player* sender = objmgr.GetPlayer(guid)) + sender->GetSession()->SendGMTicketGetTicket(0x0A,0); + + }while(result->NextRow()); + + delete result; + + CharacterDatabase.PExecute("DELETE FROM character_ticket"); + SendSysMessage(LANG_COMMAND_ALLTICKETDELETED); + return true; + } + + int num = (uint32)atoi(px); + + // delticket #num + if(num > 0) + { + QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket LIMIT %i",num); + + if(!result || uint64(num) > result->GetRowCount()) + { + PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); + delete result; + SetSentErrorMessage(true); + return false; + } + + for(int i = 1; i < num; ++i) + result->NextRow(); + + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + uint64 guid = fields[1].GetUInt64(); + delete result; + + CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id); + + // notify players about ticket deleting + if(Player* sender = objmgr.GetPlayer(guid)) + { + sender->GetSession()->SendGMTicketGetTicket(0x0A,0); + PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName()); + } + else + SendSysMessage(LANG_COMMAND_TICKETDEL); + + return true; + } + + std::string name = px; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + + if(!guid) + return false; + + // delticket $char_name + CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid)); + + // notify players about ticket deleting + if(Player* sender = objmgr.GetPlayer(guid)) + sender->GetSession()->SendGMTicketGetTicket(0x0A,0); + + PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px); + return true; +} + +//set spawn dist of creature +bool ChatHandler::HandleSpawnDistCommand(const char* args) +{ + if(!*args) + return false; + + float option = atof((char*)args); + if (option < 0.0f) + { + SendSysMessage(LANG_BAD_VALUE); + return false; + } + + MovementGeneratorType mtype = IDLE_MOTION_TYPE; + if (option >0.0f) + mtype = RANDOM_MOTION_TYPE; + + Creature *pCreature = getSelectedCreature(); + uint32 u_guidlow = 0; + + if (pCreature) + u_guidlow = pCreature->GetDBTableGUIDLow(); + else + return false; + + pCreature->SetRespawnRadius((float)option); + pCreature->SetDefaultMovementType(mtype); + pCreature->GetMotionMaster()->Initialize(); + if(pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + + WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); + PSendSysMessage(LANG_COMMAND_SPAWNDIST,option); + return true; +} + +bool ChatHandler::HandleSpawnTimeCommand(const char* args) +{ + if(!*args) + return false; + + char* stime = strtok((char*)args, " "); + + if (!stime) + return false; + + int i_stime = atoi((char*)stime); + + if (i_stime < 0) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Creature *pCreature = getSelectedCreature(); + uint32 u_guidlow = 0; + + if (pCreature) + u_guidlow = pCreature->GetDBTableGUIDLow(); + else + return false; + + WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); + pCreature->SetRespawnDelay((uint32)i_stime); + PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime); + + return true; +} + +/** + * Add a waypoint to a creature. + * + * The user can either select an npc or provide its GUID. + * + * The user can even select a visual waypoint - then the new waypoint + * is placed *after* the selected one - this makes insertion of new + * waypoints possible. + * + * eg: + * .wp add 12345 + * -> adds a waypoint to the npc with the GUID 12345 + * + * .wp add + * -> adds a waypoint to the currently selected creature + * + * + * @param args if the user did not provide a GUID, it is NULL + * + * @return true - command did succeed, false - something went wrong + */ +bool ChatHandler::HandleWpAddCommand(const char* args) +{ + sLog.outDebug("DEBUG: HandleWpAddCommand"); + + // optional + char* guid_str = NULL; + + if(*args) + { + guid_str = strtok((char*)args, " "); + } + + uint32 lowguid = 0; + uint32 point = 0; + Creature* target = getSelectedCreature(); + // Did player provide a GUID? + if (!guid_str) + { + sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided"); + + // No GUID provided + // -> Player must have selected a creature + + if(!target || target->isPet()) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + if (target->GetEntry() == VISUAL_WAYPOINT ) + { + sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) "); + + QueryResult *result = + WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u", + target->GetGUIDLow() ); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow()); + // User selected a visual spawnpoint -> get the NPC + // Select NPC GUID + // Since we compare float values, we have to deal with + // some difficulties. + // Here we search for all waypoints that only differ in one from 1 thousand + // (0.001) - There is no other way to compare C++ floats with mySQL floats + // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html + const char* maxDIFF = "0.01"; + result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )", + target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow()); + SetSentErrorMessage(true); + return false; + } + } + do + { + Field *fields = result->Fetch(); + lowguid = fields[0].GetUInt32(); + point = fields[1].GetUInt32(); + }while( result->NextRow() ); + delete result; + + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT)); + if(!target) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid); + SetSentErrorMessage(true); + return false; + } + } + else + { + lowguid = target->GetDBTableGUIDLow(); + } + } + else + { + sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided"); + + // GUID provided + // Warn if player also selected a creature + // -> Creature selection is ignored <- + if(target) + { + SendSysMessage(LANG_WAYPOINT_CREATSELECTED); + } + lowguid = atoi((char*)guid_str); + + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT)); + if(!target || target->isPet()) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + } + // lowguid -> GUID of the NPC + // point -> number of the waypoint (if not 0) + sLog.outDebug("DEBUG: HandleWpAddCommand - danach"); + + sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0"); + + Player* player = m_session->GetPlayer(); + WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0); + + // update movement type + if(target) + { + target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); + target->GetMotionMaster()->Initialize(); + if(target->isAlive()) // dead creature will reset movement generator at respawn + { + target->setDeathState(JUST_DIED); + target->Respawn(); + } + target->SaveToDB(); + } + else + WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); + + PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid); + + return true; +} // HandleWpAddCommand + +/** + * .wp modify emote | spell | text | del | move | add + * + * add -> add a WP after the selected visual waypoint + * User must select a visual waypoint and then issue ".wp modify add" + * + * emote + * User has selected a visual waypoint before. + * is added to this waypoint. Everytime the + * NPC comes to this waypoint, the emote is called. + * + * emote + * User has not selected visual waypoint before. + * For the waypoint for the NPC with + * an emote is added. + * Everytime the NPC comes to this waypoint, the emote is called. + * + * + * info -> User did not select a visual waypoint and + */ +bool ChatHandler::HandleWpModifyCommand(const char* args) +{ + sLog.outDebug("DEBUG: HandleWpModifyCommand"); + + if(!*args) + return false; + + // first arg: add del text emote spell waittime move + char* show_str = strtok((char*)args, " "); + if (!show_str) + { + return false; + } + + std::string show = show_str; + // Check + // Remember: "show" must also be the name of a column! + if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2") + && (show != "text3") && (show != "text4") && (show != "text5") + && (show != "waittime") && (show != "del") && (show != "move") && (show != "add") + && (show != "model1") && (show != "model2") && (show != "orientation")) + { + return false; + } + + // Next arg is: + + // Did user provide a GUID + // or did the user select a creature? + // -> variable lowguid is filled with the GUID of the NPC + uint32 lowguid = 0; + uint32 point = 0; + uint32 wpGuid = 0; + Creature* target = getSelectedCreature(); + + if(target) + { + sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC"); + + // Did the user select a visual spawnpoint? + if (target->GetEntry() != VISUAL_WAYPOINT ) + { + PSendSysMessage(LANG_WAYPOINT_VP_SELECT); + SetSentErrorMessage(true); + return false; + } + + wpGuid = target->GetGUIDLow(); + + // The visual waypoint + QueryResult *result = + WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1", + target->GetGUIDLow() ); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); + SetSentErrorMessage(true); + return false; + } + sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid"); + + Field *fields = result->Fetch(); + lowguid = fields[0].GetUInt32(); + point = fields[1].GetUInt32(); + + // Cleanup memory + sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory"); + delete result; + } + else + { + // User did provide + + char* guid_str = strtok((char*)NULL, " "); + if( !guid_str ) + { + SendSysMessage(LANG_WAYPOINT_NOGUID); + return false; + } + lowguid = atoi((char*)guid_str); + + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage("DEBUG: GUID provided: %d", lowguid); + + char* point_str = strtok((char*)NULL, " "); + if( !point_str ) + { + SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN); + return false; + } + point = atoi((char*)point_str); + + PSendSysMessage("DEBUG: wpNumber provided: %d", point); + + // Now we need the GUID of the visual waypoint + // -> "del", "move", "add" command + + QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point); + if (!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point); + SetSentErrorMessage(true); + return false; + } + + Field *fields = result->Fetch(); + wpGuid = fields[0].GetUInt32(); + + // Free memory + delete result; + } + + char* arg_str = NULL; + // Check for argument + if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add")) + { + // Text is enclosed in "<>", all other arguments not + if( show.find("text") != std::string::npos ) + arg_str = strtok((char*)NULL, "<>"); + else + arg_str = strtok((char*)NULL, " "); + + if( !arg_str) + { + PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str); + return false; + } + } + + sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command"); + + // wpGuid -> GUID of the waypoint creature + // lowguid -> GUID of the NPC + // point -> waypoint number + + // Special functions: + // add - move - del -> no args commands + // Add a waypoint after the selected visual + if(show == "add" && target) + { + PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid); + + // Get the creature for which we read the waypoint + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT)); + + if( !npcCreature ) + { + PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND); + SetSentErrorMessage(true); + return false; + } + + sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature"); + + // What to do: + // Add the visual spawnpoint (DB only) + // Adjust the waypoints + // Respawn the owner of the waypoints + sLog.outDebug("DEBUG: HandleWpModifyCommand - add"); + + Player* chr = m_session->GetPlayer(); + Map *map = chr->GetMap(); + + if(npcCreature) + { + npcCreature->GetMotionMaster()->Initialize(); + if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn + { + npcCreature->setDeathState(JUST_DIED); + npcCreature->Respawn(); + } + } + + // create the waypoint creature + wpGuid = 0; + Creature* wpCreature = new Creature; + if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0)) + { + PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); + delete wpCreature; + } + else + { + wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()); + + if(!wpCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY()); + delete wpCreature; + } + else + { + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map); + map->Add(wpCreature); + wpGuid = wpCreature->GetGUIDLow(); + } + } + + WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid); + + if(!wpGuid) + return false; + + PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1); + return true; + } // add + + if(show == "del" && target) + { + PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid); + + // Get the creature for which we read the waypoint + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT)); + + // wpCreature + Creature* wpCreature = NULL; + if( wpGuid != 0 ) + { + wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); + wpCreature->DeleteFromDB(); + wpCreature->CleanupsBeforeDelete(); + wpCreature->AddObjectToRemoveList(); + } + + // What to do: + // Remove the visual spawnpoint + // Adjust the waypoints + // Respawn the owner of the waypoints + + WaypointMgr.DeleteNode(lowguid, point); + + if(npcCreature) + { + // Any waypoints left? + QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid); + if(!result2) + { + npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE); + } + else + { + npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); + delete result2; + } + npcCreature->GetMotionMaster()->Initialize(); + if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn + { + npcCreature->setDeathState(JUST_DIED); + npcCreature->Respawn(); + } + npcCreature->SaveToDB(); + } + + PSendSysMessage(LANG_WAYPOINT_REMOVED); + return true; + } // del + + if(show == "move" && target) + { + PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid); + + Player *chr = m_session->GetPlayer(); + Map *map = chr->GetMap(); + { + // Get the creature for which we read the waypoint + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT)); + + // wpCreature + Creature* wpCreature = NULL; + // What to do: + // Move the visual spawnpoint + // Respawn the owner of the waypoints + if( wpGuid != 0 ) + { + wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); + wpCreature->DeleteFromDB(); + wpCreature->CleanupsBeforeDelete(); + wpCreature->AddObjectToRemoveList(); + // re-create + Creature* wpCreature2 = new Creature; + if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0)) + { + PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); + delete wpCreature2; + return false; + } + + wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()); + + if(!wpCreature2->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY()); + delete wpCreature2; + return false; + } + + wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map); + map->Add(wpCreature2); + //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2); + } + + WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ()); + + if(npcCreature) + { + npcCreature->GetMotionMaster()->Initialize(); + if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn + { + npcCreature->setDeathState(JUST_DIED); + npcCreature->Respawn(); + } + } + PSendSysMessage(LANG_WAYPOINT_CHANGED); + } + return true; + } // move + + // Create creature - npc that has the waypoint + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str); + + Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT)); + if(npcCreature) + { + npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); + npcCreature->GetMotionMaster()->Initialize(); + if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn + { + npcCreature->setDeathState(JUST_DIED); + npcCreature->Respawn(); + } + } + PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); + + return true; +} + +/** + * .wp show info | on | off + * + * info -> User has selected a visual waypoint before + * + * info -> User did not select a visual waypoint and + * provided the GUID of the NPC and the number of + * the waypoint. + * + * on -> User has selected an NPC; all visual waypoints for this + * NPC are added to the world + * + * on -> User did not select an NPC - instead the GUID of the + * NPC is provided. All visual waypoints for this NPC + * are added from the world. + * + * off -> User has selected an NPC; all visual waypoints for this + * NPC are removed from the world. + * + * on -> User did not select an NPC - instead the GUID of the + * NPC is provided. All visual waypoints for this NPC + * are removed from the world. + * + * + */ +bool ChatHandler::HandleWpShowCommand(const char* args) +{ + sLog.outDebug("DEBUG: HandleWpShowCommand"); + + if(!*args) + return false; + + // first arg: on, off, first, last + char* show_str = strtok((char*)args, " "); + if (!show_str) + { + return false; + } + // second arg: GUID (optional, if a creature is selected) + char* guid_str = strtok((char*)NULL, " "); + sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str); + //if (!guid_str) { + // return false; + //} + + // Did user provide a GUID + // or did the user select a creature? + // -> variable lowguid is filled with the GUID + Creature* target = getSelectedCreature(); + // Did player provide a GUID? + if (!guid_str) + { + sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str"); + // No GUID provided + // -> Player must have selected a creature + + if(!target) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + } + else + { + sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided"); + // GUID provided + // Warn if player also selected a creature + // -> Creature selection is ignored <- + if(target) + { + SendSysMessage(LANG_WAYPOINT_CREATSELECTED); + } + + uint32 lowguid = atoi((char*)guid_str); + + CreatureData const* data = objmgr.GetCreatureData(lowguid); + if(!data) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT)); + + if(!target) + { + PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + } + + uint32 lowguid = target->GetDBTableGUIDLow(); + + std::string show = show_str; + uint32 Maxpoint; + + sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid); + + sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", target ); + + sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str); + //PSendSysMessage("wpshow - show: %s", show); + + // Show info for the selected waypoint + if(show == "info") + { + PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid); + + // Check if the user did specify a visual waypoint + if( target->GetEntry() != VISUAL_WAYPOINT ) + { + PSendSysMessage(LANG_WAYPOINT_VP_SELECT); + SetSentErrorMessage(true); + return false; + } + + //PSendSysMessage("wp on, GUID: %u", lowguid); + + //pCreature->GetPositionX(); + + QueryResult *result = + WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u", + target->GetGUID() ); + if(!result) + { + // Since we compare float values, we have to deal with + // some difficulties. + // Here we search for all waypoints that only differ in one from 1 thousand + // (0.001) - There is no other way to compare C++ floats with mySQL floats + // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html + const char* maxDIFF = "0.01"; + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID()); + + result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )", + target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid); + SetSentErrorMessage(true); + return false; + } + } + do + { + Field *fields = result->Fetch(); + uint32 creGUID = fields[0].GetUInt32(); + uint32 point = fields[1].GetUInt32(); + int waittime = fields[2].GetUInt32(); + uint32 emote = fields[3].GetUInt32(); + uint32 spell = fields[4].GetUInt32(); + const char * text1 = fields[5].GetString(); + const char * text2 = fields[6].GetString(); + const char * text3 = fields[7].GetString(); + const char * text4 = fields[8].GetString(); + const char * text5 = fields[9].GetString(); + uint32 model1 = fields[10].GetUInt32(); + uint32 model2 = fields[11].GetUInt32(); + + // Get the creature for which we read the waypoint + Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT)); + + PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : ""), creGUID); + PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime); + PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1); + PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2); + PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote); + PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell); + PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1); + PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2); + PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3); + PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4); + PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5); + + }while( result->NextRow() ); + // Cleanup memory + delete result; + return true; + } + + if(show == "on") + { + PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid); + + QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + // Delete all visuals for this NPC + QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid); + if(result2) + { + bool hasError = false; + do + { + Field *fields = result2->Fetch(); + uint32 wpguid = fields[0].GetUInt32(); + Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT)); + + if(!pCreature) + { + PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid); + hasError = true; + WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid); + } + else + { + pCreature->DeleteFromDB(); + pCreature->CleanupsBeforeDelete(); + pCreature->AddObjectToRemoveList(); + } + + }while( result2->NextRow() ); + delete result2; + if( hasError ) + { + PSendSysMessage(LANG_WAYPOINT_TOOFAR1); + PSendSysMessage(LANG_WAYPOINT_TOOFAR2); + PSendSysMessage(LANG_WAYPOINT_TOOFAR3); + } + } + + do + { + Field *fields = result->Fetch(); + uint32 point = fields[0].GetUInt32(); + float x = fields[1].GetFloat(); + float y = fields[2].GetFloat(); + float z = fields[3].GetFloat(); + + uint32 id = VISUAL_WAYPOINT; + + Player *chr = m_session->GetPlayer(); + Map *map = chr->GetMap(); + float o = chr->GetOrientation(); + + Creature* wpCreature = new Creature; + if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) + { + PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); + delete wpCreature; + delete result; + return false; + } + + wpCreature->Relocate(x, y, z, o); + + if(!wpCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY()); + delete wpCreature; + delete result; + return false; + } + + wpCreature->SetVisibility(VISIBILITY_OFF); + sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u"); + // set "wpguid" column to the visual waypoint + WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point); + + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map); + map->Add(wpCreature); + //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature); + }while( result->NextRow() ); + + // Cleanup memory + delete result; + return true; + } + + if(show == "first") + { + PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid); + + QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + Field *fields = result->Fetch(); + float x = fields[0].GetFloat(); + float y = fields[1].GetFloat(); + float z = fields[2].GetFloat(); + uint32 id = VISUAL_WAYPOINT; + + Player *chr = m_session->GetPlayer(); + float o = chr->GetOrientation(); + Map *map = chr->GetMap(); + + Creature* pCreature = new Creature; + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0)) + { + PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); + delete pCreature; + delete result; + return false; + } + + pCreature->Relocate(x, y, z, o); + + if(!pCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); + delete pCreature; + delete result; + return false; + } + + pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map); + map->Add(pCreature); + //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint"); + + // Cleanup memory + delete result; + return true; + } + + if(show == "last") + { + PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid); + + QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid); + if( result ) + { + Maxpoint = (*result)[0].GetUInt32(); + + delete result; + } + else + Maxpoint = 0; + + result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid); + if(!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid); + SetSentErrorMessage(true); + return false; + } + Field *fields = result->Fetch(); + float x = fields[0].GetFloat(); + float y = fields[1].GetFloat(); + float z = fields[2].GetFloat(); + uint32 id = VISUAL_WAYPOINT; + + Player *chr = m_session->GetPlayer(); + float o = chr->GetOrientation(); + Map *map = chr->GetMap(); + + Creature* pCreature = new Creature; + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) + { + PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); + delete pCreature; + delete result; + return false; + } + + pCreature->Relocate(x, y, z, o); + + if(!pCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); + delete pCreature; + delete result; + return false; + } + + pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map); + map->Add(pCreature); + //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint"); + // Cleanup memory + delete result; + return true; + } + + if(show == "off") + { + QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT); + if(!result) + { + SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND); + SetSentErrorMessage(true); + return false; + } + bool hasError = false; + do + { + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT)); + + //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); + + if(!pCreature) + { + PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid); + hasError = true; + WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid); + } + else + { + pCreature->DeleteFromDB(); + pCreature->CleanupsBeforeDelete(); + pCreature->AddObjectToRemoveList(); + } + }while(result->NextRow()); + // set "wpguid" column to "empty" - no visual waypoint spawned + WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'"); + + if( hasError ) + { + PSendSysMessage(LANG_WAYPOINT_TOOFAR1); + PSendSysMessage(LANG_WAYPOINT_TOOFAR2); + PSendSysMessage(LANG_WAYPOINT_TOOFAR3); + } + + SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED); + // Cleanup memory + delete result; + + return true; + } + + PSendSysMessage("DEBUG: wpshow - no valid command found"); + + return true; +} // HandleWpShowCommand + +bool ChatHandler::HandleWpExportCommand(const char *args) +{ + if(!*args) + return false; + + // Next arg is: + + // Did user provide a GUID + // or did the user select a creature? + // -> variable lowguid is filled with the GUID of the NPC + uint32 lowguid = 0; + Creature* target = getSelectedCreature(); + char* arg_str = NULL; + if (target) + { + if (target->GetEntry() != VISUAL_WAYPOINT) + lowguid = target->GetGUIDLow(); + else + { + QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() ); + if (!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow()); + return true; + } + Field *fields = result->Fetch(); + lowguid = fields[0].GetUInt32();; + delete result; + } + + arg_str = strtok((char*)args, " "); + } + else + { + // user provided + char* guid_str = strtok((char*)args, " "); + if( !guid_str ) + { + SendSysMessage(LANG_WAYPOINT_NOGUID); + return false; + } + lowguid = atoi((char*)guid_str); + + arg_str = strtok((char*)NULL, " "); + } + + if( !arg_str) + { + PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export"); + return false; + } + + PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid); + + QueryResult *result = WorldDatabase.PQuery( + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid ); + + if (!result) + { + PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT); + SetSentErrorMessage(true); + return false; + } + + std::ofstream outfile; + outfile.open (arg_str); + + do + { + Field *fields = result->Fetch(); + + outfile << "INSERT INTO creature_movement "; + outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES "; + + outfile << "( "; + outfile << fields[15].GetUInt32(); // id + outfile << ", "; + outfile << fields[0].GetUInt32(); // point + outfile << ", "; + outfile << fields[1].GetFloat(); // position_x + outfile << ", "; + outfile << fields[2].GetFloat(); // position_y + outfile << ", "; + outfile << fields[3].GetUInt32(); // position_z + outfile << ", "; + outfile << fields[4].GetUInt32(); // orientation + outfile << ", "; + outfile << fields[5].GetUInt32(); // model1 + outfile << ", "; + outfile << fields[6].GetUInt32(); // model2 + outfile << ", "; + outfile << fields[7].GetUInt16(); // waittime + outfile << ", "; + outfile << fields[8].GetUInt32(); // emote + outfile << ", "; + outfile << fields[9].GetUInt32(); // spell + outfile << ", "; + const char *tmpChar = fields[10].GetString(); + if( !tmpChar ) + { + outfile << "NULL"; // text1 + } + else + { + outfile << "'"; + outfile << tmpChar; // text1 + outfile << "'"; + } + outfile << ", "; + tmpChar = fields[11].GetString(); + if( !tmpChar ) + { + outfile << "NULL"; // text2 + } + else + { + outfile << "'"; + outfile << tmpChar; // text2 + outfile << "'"; + } + outfile << ", "; + tmpChar = fields[12].GetString(); + if( !tmpChar ) + { + outfile << "NULL"; // text3 + } + else + { + outfile << "'"; + outfile << tmpChar; // text3 + outfile << "'"; + } + outfile << ", "; + tmpChar = fields[13].GetString(); + if( !tmpChar ) + { + outfile << "NULL"; // text4 + } + else + { + outfile << "'"; + outfile << tmpChar; // text4 + outfile << "'"; + } + outfile << ", "; + tmpChar = fields[14].GetString(); + if( !tmpChar ) + { + outfile << "NULL"; // text5 + } + else + { + outfile << "'"; + outfile << tmpChar; // text5 + outfile << "'"; + } + outfile << ");\n "; + + } while( result->NextRow() ); + delete result; + + PSendSysMessage(LANG_WAYPOINT_EXPORTED); + outfile.close(); + + return true; +} + +bool ChatHandler::HandleWpImportCommand(const char *args) +{ + if(!*args) + return false; + + char* arg_str = strtok((char*)args, " "); + if (!arg_str) + return false; + + std::string line; + std::ifstream infile (arg_str); + if (infile.is_open()) + { + while (! infile.eof() ) + { + getline (infile,line); + //cout << line << endl; + QueryResult *result = WorldDatabase.PQuery(line.c_str()); + delete result; + } + infile.close(); + } + PSendSysMessage(LANG_WAYPOINT_IMPORTED); + + return true; +} + +//rename characters +bool ChatHandler::HandleRenameCommand(const char* args) +{ + Player* target = NULL; + uint64 targetGUID = 0; + std::string oldname; + + char* px = strtok((char*)args, " "); + + if(px) + { + oldname = px; + + if(!normalizePlayerName(oldname)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + target = objmgr.GetPlayer(oldname.c_str()); + + if (!target) + targetGUID = objmgr.GetPlayerGUIDByName(oldname); + } + + if(!target && !targetGUID) + { + target = getSelectedPlayer(); + } + + if(!target && !targetGUID) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(target) + { + PSendSysMessage(LANG_RENAME_PLAYER, target->GetName()); + target->SetAtLoginFlag(AT_LOGIN_RENAME); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow()); + } + else + { + PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID)); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID)); + } + + return true; +} + +//spawn go +bool ChatHandler::HandleGameObjectCommand(const char* args) +{ + if (!*args) + return false; + + char* pParam1 = strtok((char*)args, " "); + if (!pParam1) + return false; + + uint32 id = atoi((char*)pParam1); + if(!id) + return false; + + char* spawntimeSecs = strtok(NULL, " "); + + const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id); + + if (!goI) + { + PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); + SetSentErrorMessage(true); + return false; + } + + Player *chr = m_session->GetPlayer(); + float x = float(chr->GetPositionX()); + float y = float(chr->GetPositionY()); + float z = float(chr->GetPositionZ()); + float o = float(chr->GetOrientation()); + Map *map = chr->GetMap(); + + float rot2 = sin(o/2); + float rot3 = cos(o/2); + + GameObject* pGameObj = new GameObject; + uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); + + if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1)) + { + delete pGameObj; + return false; + } + + if( spawntimeSecs ) + { + uint32 value = atoi((char*)spawntimeSecs); + pGameObj->SetRespawnTime(value); + //sLog.outDebug("*** spawntimeSecs: %d", value); + } + + // fill the gameobject data and save to the db + pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); + + // this will generate a new guid if the object is in an instance + if(!pGameObj->LoadFromDB(db_lowGUID, map)) + { + delete pGameObj; + return false; + } + + sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o); + + map->Add(pGameObj); + + // TODO: is it really necessary to add both the real and DB table guid here ? + objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID)); + + PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z); + return true; +} + +//show animation +bool ChatHandler::HandleAnimCommand(const char* args) +{ + if (!*args) + return false; + + uint32 anim_id = atoi((char*)args); + m_session->GetPlayer()->HandleEmoteCommand(anim_id); + return true; +} + +//change standstate +bool ChatHandler::HandleStandStateCommand(const char* args) +{ + if (!*args) + return false; + + uint32 anim_id = atoi((char*)args); + m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id ); + + return true; +} + +bool ChatHandler::HandleAddHonorCommand(const char* args) +{ + if (!*args) + return false; + + Player *target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint32 amount = (uint32)atoi(args); + target->RewardHonor(NULL, 1, amount); + return true; +} + +bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/) +{ + Unit *target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + m_session->GetPlayer()->RewardHonor(target, 1); + return true; +} + +bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/) +{ + Player *target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + target->UpdateHonorFields(); + return true; +} + +bool ChatHandler::HandleLookupEventCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0; + + GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); + + for(uint32 id = 0; id < events.size(); ++id ) + { + GameEventData const& eventData = events[id]; + + std::string descr = eventData.description; + if(descr.empty()) + continue; + + if (Utf8FitTo(descr, wnamepart)) + { + char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : ""; + PSendSysMessage(LANG_EVENT_ENTRY_LIST,id,id,descr.c_str(),active ); + ++counter; + } + } + + if (counter==0) + SendSysMessage(LANG_NOEVENTFOUND); + + return true; +} + +bool ChatHandler::HandleEventActiveListCommand(const char* args) +{ + uint32 counter = 0; + + GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); + + char const* active = GetMangosString(LANG_ACTIVE); + + for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr ) + { + uint32 event_id = *itr; + GameEventData const& eventData = events[event_id]; + + PSendSysMessage(LANG_EVENT_ENTRY_LIST,event_id,event_id,eventData.description.c_str(),active ); + ++counter; + } + + if (counter==0) + SendSysMessage(LANG_NOEVENTFOUND); + + return true; +} + +bool ChatHandler::HandleEventInfoCommand(const char* args) +{ + if(!*args) + return false; + + // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameevent"); + if(!cId) + return false; + + uint32 event_id = atoi(cId); + + GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + + if(event_id >=events.size()) + { + SendSysMessage(LANG_EVENT_NOT_EXIST); + SetSentErrorMessage(true); + return false; + } + + GameEventData const& eventData = events[event_id]; + if(!eventData.isValid()) + { + SendSysMessage(LANG_EVENT_NOT_EXIST); + SetSentErrorMessage(true); + return false; + } + + GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); + bool active = activeEvents.find(event_id) != activeEvents.end(); + char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : ""; + + std::string startTimeStr = TimeToTimestampStr(eventData.start); + std::string endTimeStr = TimeToTimestampStr(eventData.end); + + uint32 delay = gameeventmgr.NextCheck(event_id); + time_t nextTime = time(NULL)+delay; + std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-"; + + std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE); + std::string lengthStr = secsToTimeString(eventData.length * MINUTE); + + PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr, + startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(), + nextStr.c_str()); + return true; +} + +bool ChatHandler::HandleEventStartCommand(const char* args) +{ + if(!*args) + return false; + + // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameevent"); + if(!cId) + return false; + + int32 event_id = atoi(cId); + + GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + + if(event_id < 1 || event_id >=events.size()) + { + SendSysMessage(LANG_EVENT_NOT_EXIST); + SetSentErrorMessage(true); + return false; + } + + GameEventData const& eventData = events[event_id]; + if(!eventData.isValid()) + { + SendSysMessage(LANG_EVENT_NOT_EXIST); + SetSentErrorMessage(true); + return false; + } + + GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); + if(activeEvents.find(event_id) != activeEvents.end()) + { + PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id); + SetSentErrorMessage(true); + return false; + } + + gameeventmgr.StartEvent(event_id,true); + return true; +} + +bool ChatHandler::HandleEventStopCommand(const char* args) +{ + if(!*args) + return false; + + // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameevent"); + if(!cId) + return false; + + int32 event_id = atoi(cId); + + GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + + if(event_id < 1 || event_id >=events.size()) + { + SendSysMessage(LANG_EVENT_NOT_EXIST); + SetSentErrorMessage(true); + return false; + } + + GameEventData const& eventData = events[event_id]; + if(!eventData.isValid()) + { + SendSysMessage(LANG_EVENT_NOT_EXIST); + SetSentErrorMessage(true); + return false; + } + + GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); + + if(activeEvents.find(event_id) == activeEvents.end()) + { + PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id); + SetSentErrorMessage(true); + return false; + } + + gameeventmgr.StopEvent(event_id,true); + return true; +} + +bool ChatHandler::HandleCombatStopCommand(const char* args) +{ + Player *player; + + if(*args) + { + std::string playername = args; + + if(!normalizePlayerName(playername)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(playername.c_str()); + + if(!player) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + } + else + { + player = getSelectedPlayer(); + + if (!player) + player = m_session->GetPlayer(); + } + + player->CombatStop(); + player->getHostilRefManager().deleteReferences(); + return true; +} + +bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/) +{ + uint32 classmask = m_session->GetPlayer()->getClassMask(); + + for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) + { + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i); + if( !skillInfo ) + continue; + + if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY ) + { + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + { + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); + if( !skillLine ) + continue; + + // skip racial skills + if( skillLine->racemask != 0 ) + continue; + + // skip wrong class skills + if( skillLine->classmask && (skillLine->classmask & classmask) == 0) + continue; + + if( skillLine->skillId != i || skillLine->forward_spellid ) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + m_session->GetPlayer()->learnSpell(skillLine->spellId); + } + } + } + + SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT); + return true; +} + +bool ChatHandler::HandleLearnAllRecipesCommand(const char* args) +{ + // Learns all recipes of specified profession and sets skill to max + // Example: .learn all_recipes enchanting + + Player* target = getSelectedPlayer(); + if( !target ) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + return false; + } + + if(!*args) + return false; + + std::wstring wnamepart; + + if(!Utf8toWStr(args,wnamepart)) + return false; + + uint32 counter = 0; // Counter for figure out that we found smth. + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 classmask = m_session->GetPlayer()->getClassMask(); + + for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) + { + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i); + if( !skillInfo ) + continue; + + if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && + skillInfo->categoryId != SKILL_CATEGORY_SECONDARY ) + continue; + + int loc = m_session->GetSessionDbcLocale(); + std::string name = skillInfo->name[loc]; + + if(Utf8FitTo(name, wnamepart)) + { + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + { + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); + if( !skillLine ) + continue; + + if( skillLine->skillId != i || skillLine->forward_spellid ) + continue; + + // skip racial skills + if( skillLine->racemask != 0 ) + continue; + + // skip wrong class skills + if( skillLine->classmask && (skillLine->classmask & classmask) == 0) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + if( !target->HasSpell(spellInfo->Id) ) + m_session->GetPlayer()->learnSpell(skillLine->spellId); + } + + uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id); + target->SetSkill(skillInfo->id, maxLevel, maxLevel); + PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); + return true; + } + } + + return false; +} + +bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) +{ + + if(!*args) + return false; + + std::string ip = strtok((char*)args, " "); + char* limit_str = strtok(NULL, " "); + int32 limit = limit_str ? atoi(limit_str) : -1; + + loginDatabase.escape_string(ip); + + QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str()); + + return LookupPlayerSearchCommand(result,limit); +} + +bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args) +{ + if(!*args) + return false; + + std::string account = strtok((char*)args, " "); + char* limit_str = strtok(NULL, " "); + int32 limit = limit_str ? atoi(limit_str) : -1; + + if(!AccountMgr::normilizeString(account)) + return false; + + loginDatabase.escape_string(account); + + QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE username = '%s'", account.c_str()); + + return LookupPlayerSearchCommand(result,limit); +} + +bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args) +{ + + if(!*args) + return false; + + std::string email = strtok((char*)args, " "); + char* limit_str = strtok(NULL, " "); + int32 limit = limit_str ? atoi(limit_str) : -1; + + loginDatabase.escape_string(email); + + QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE email = '%s'", email.c_str()); + + return LookupPlayerSearchCommand(result,limit); +} + +bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit) +{ + if(!result) + { + PSendSysMessage(LANG_NO_PLAYERS_FOUND); + SetSentErrorMessage(true); + return false; + } + + int i =0; + do + { + Field* fields = result->Fetch(); + uint32 acc_id = fields[0].GetUInt32(); + std::string acc_name = fields[1].GetCppString(); + + QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id); + if(chars) + { + PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id); + + uint64 guid = 0; + std::string name; + + do + { + Field* charfields = chars->Fetch(); + guid = charfields[0].GetUInt64(); + name = charfields[1].GetCppString(); + + PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid); + ++i; + + } while( chars->NextRow() && ( limit == -1 || i < limit ) ); + + delete chars; + } + } while(result->NextRow()); + + delete result; + + return true; +} diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp new file mode 100644 index 000000000..ca00ab0aa --- /dev/null +++ b/src/game/Level3.cpp @@ -0,0 +1,5517 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "PlayerDump.h" +#include "SpellMgr.h" +#include "Player.h" +#include "Opcodes.h" +#include "GameObject.h" +#include "Chat.h" +#include "Log.h" +#include "Guild.h" +#include "ObjectAccessor.h" +#include "MapManager.h" +#include "SpellAuras.h" +#include "ScriptCalls.h" +#include "Language.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "Weather.h" +#include "PointMovementGenerator.h" +#include "TargetedMovementGenerator.h" +#include "SkillDiscovery.h" +#include "SkillExtraItems.h" +#include "SystemConfig.h" +#include "Config/ConfigEnv.h" +#include "Util.h" +#include "ItemEnchantmentMgr.h" +#include "InstanceSaveMgr.h" +#include "InstanceData.h" + +//reload commands +bool ChatHandler::HandleReloadCommand(const char* arg) +{ + // this is error catcher for wrong table name in .reload commands + PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg); + SetSentErrorMessage(true); + return false; +} + +bool ChatHandler::HandleReloadAllCommand(const char*) +{ + HandleReloadAreaTriggerTeleportCommand(""); + HandleReloadSkillFishingBaseLevelCommand(""); + + HandleReloadAllAreaCommand(""); + HandleReloadAllLootCommand(""); + HandleReloadAllNpcCommand(""); + HandleReloadAllQuestCommand(""); + HandleReloadAllSpellCommand(""); + HandleReloadAllItemCommand(""); + HandleReloadAllLocalesCommand(""); + + HandleReloadCommandCommand(""); + HandleReloadReservedNameCommand(""); + HandleReloadMangosStringCommand(""); + HandleReloadGameTeleCommand(""); + return true; +} + +bool ChatHandler::HandleReloadAllAreaCommand(const char*) +{ + //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand + HandleReloadAreaTriggerTeleportCommand(""); + HandleReloadAreaTriggerTavernCommand(""); + HandleReloadGameGraveyardZoneCommand(""); + return true; +} + +bool ChatHandler::HandleReloadAllLootCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables..." ); + LoadLootTables(); + SendGlobalSysMessage("DB tables `*_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/) +{ + HandleReloadNpcGossipCommand("a"); + HandleReloadNpcTrainerCommand("a"); + HandleReloadNpcVendorCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/) +{ + HandleReloadQuestAreaTriggersCommand("a"); + HandleReloadQuestTemplateCommand("a"); + + sLog.outString( "Re-Loading Quests Relations..." ); + objmgr.LoadQuestRelations(); + SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAllScriptsCommand(const char*) +{ + if(sWorld.IsScriptScheduled()) + { + PSendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + sLog.outString( "Re-Loading Scripts..." ); + HandleReloadGameObjectScriptsCommand("a"); + HandleReloadEventScriptsCommand("a"); + HandleReloadQuestEndScriptsCommand("a"); + HandleReloadQuestStartScriptsCommand("a"); + HandleReloadSpellScriptsCommand("a"); + SendGlobalSysMessage("DB tables `*_scripts` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAllSpellCommand(const char*) +{ + HandleReloadSkillDiscoveryTemplateCommand("a"); + HandleReloadSkillExtraItemTemplateCommand("a"); + HandleReloadSpellAffectCommand("a"); + HandleReloadSpellChainCommand("a"); + HandleReloadSpellElixirCommand("a"); + HandleReloadSpellLearnSpellCommand("a"); + HandleReloadSpellProcEventCommand("a"); + HandleReloadSpellScriptTargetCommand("a"); + HandleReloadSpellTargetPositionCommand("a"); + HandleReloadSpellThreatsCommand("a"); + HandleReloadSpellPetAurasCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllItemCommand(const char*) +{ + HandleReloadPageTextsCommand("a"); + HandleReloadItemEnchantementsCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllLocalesCommand(const char* args) +{ + HandleReloadLocalesCreatureCommand("a"); + HandleReloadLocalesGameobjectCommand("a"); + HandleReloadLocalesItemCommand("a"); + HandleReloadLocalesNpcTextCommand("a"); + HandleReloadLocalesPageTextCommand("a"); + HandleReloadLocalesQuestCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadConfigCommand(const char* arg) +{ + sLog.outString( "Re-Loading config settings..." ); + sWorld.LoadConfigSettings(true); + SendGlobalSysMessage("World config settings reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*) +{ + sLog.outString( "Re-Loading Tavern Area Triggers..." ); + objmgr.LoadTavernAreaTriggers(); + SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*) +{ + sLog.outString( "Re-Loading AreaTrigger teleport definitions..." ); + objmgr.LoadAreaTriggerTeleports(); + SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadCommandCommand(const char*) +{ + load_command_table = true; + SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use."); + return true; +} + +bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" ); + objmgr.LoadCreatureQuestRelations(); + SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" ); + objmgr.LoadCreatureInvolvedRelations(); + SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" ); + objmgr.LoadGameobjectQuestRelations(); + SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" ); + objmgr.LoadGameobjectInvolvedRelations(); + SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*) +{ + sLog.outString( "Re-Loading Quest Area Triggers..." ); + objmgr.LoadQuestAreaTriggers(); + SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadQuestTemplateCommand(const char*) +{ + sLog.outString( "Re-Loading Quest Templates..." ); + objmgr.LoadQuests(); + SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" ); + LoadLootTemplates_Creature(); + LootTemplates_Creature.CheckLootRefs(); + SendGlobalSysMessage("DB table `creature_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" ); + LoadLootTemplates_Disenchant(); + LootTemplates_Disenchant.CheckLootRefs(); + SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" ); + LoadLootTemplates_Fishing(); + LootTemplates_Fishing.CheckLootRefs(); + SendGlobalSysMessage("DB table `fishing_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" ); + LoadLootTemplates_Gameobject(); + LootTemplates_Gameobject.CheckLootRefs(); + SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" ); + LoadLootTemplates_Item(); + LootTemplates_Item.CheckLootRefs(); + SendGlobalSysMessage("DB table `item_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" ); + LoadLootTemplates_Pickpocketing(); + LootTemplates_Pickpocketing.CheckLootRefs(); + SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" ); + LoadLootTemplates_Prospecting(); + LootTemplates_Prospecting.CheckLootRefs(); + SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" ); + LoadLootTemplates_QuestMail(); + LootTemplates_QuestMail.CheckLootRefs(); + SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" ); + LoadLootTemplates_Reference(); + SendGlobalSysMessage("DB table `reference_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" ); + LoadLootTemplates_Skinning(); + LootTemplates_Skinning.CheckLootRefs(); + SendGlobalSysMessage("DB table `skinning_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadMangosStringCommand(const char*) +{ + sLog.outString( "Re-Loading mangos_string Table!" ); + objmgr.LoadMangosStrings(); + SendGlobalSysMessage("DB table `mangos_string` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcGossipCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_gossip` Table!" ); + objmgr.LoadNpcTextId(); + SendGlobalSysMessage("DB table `npc_gossip` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcTrainerCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_trainer` Table!" ); + objmgr.LoadTrainerSpell(); + SendGlobalSysMessage("DB table `npc_trainer` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcVendorCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_vendor` Table!" ); + objmgr.LoadVendors(); + SendGlobalSysMessage("DB table `npc_vendor` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadReservedNameCommand(const char*) +{ + sLog.outString( "Loading ReservedNames... (`reserved_name`)" ); + objmgr.LoadReservedPlayersNames(); + SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading Skill Discovery Table..." ); + LoadSkillDiscoveryTable(); + SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading Skill Extra Item Table..." ); + LoadSkillExtraItemTable(); + SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading Skill Fishing base level requirements..." ); + objmgr.LoadFishingBaseSkillLevel(); + SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellAffectCommand(const char*) +{ + sLog.outString( "Re-Loading SpellAffect definitions..." ); + spellmgr.LoadSpellAffects(); + SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellChainCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Chain Data... " ); + spellmgr.LoadSpellChains(); + SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellElixirCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Elixir types..." ); + spellmgr.LoadSpellElixirs(); + SendGlobalSysMessage("DB table `spell_elixir` (spell exlixir types) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Learn Spells..." ); + spellmgr.LoadSpellLearnSpells(); + SendGlobalSysMessage("DB table `spell_learn_spell` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellProcEventCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Proc Event conditions..." ); + spellmgr.LoadSpellProcEvents(); + SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*) +{ + sLog.outString( "Re-Loading SpellsScriptTarget..." ); + spellmgr.LoadSpellScriptTarget(); + SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*) +{ + sLog.outString( "Re-Loading Spell target coordinates..." ); + spellmgr.LoadSpellTargetPositions(); + SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellThreatsCommand(const char*) +{ + sLog.outString( "Re-Loading Aggro Spells Definitions..."); + spellmgr.LoadSpellThreats(); + SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*) +{ + sLog.outString( "Re-Loading Spell pet auras..."); + spellmgr.LoadSpellPetAuras(); + SendGlobalSysMessage("DB table `spell_pet_auras` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadPageTextsCommand(const char*) +{ + sLog.outString( "Re-Loading Page Texts..." ); + objmgr.LoadPageTexts(); + SendGlobalSysMessage("DB table `page_texts` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*) +{ + sLog.outString( "Re-Loading Item Random Enchantments Table..." ); + LoadRandomEnchantmentsTable(); + SendGlobalSysMessage("DB table `item_enchantment_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `gameobject_scripts`..."); + + objmgr.LoadGameObjectScripts(); + + if(*arg!='a') + SendGlobalSysMessage("DB table `gameobject_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `event_scripts`..."); + + objmgr.LoadEventScripts(); + + if(*arg!='a') + SendGlobalSysMessage("DB table `event_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `quest_end_scripts`..."); + + objmgr.LoadQuestEndScripts(); + + if(*arg!='a') + SendGlobalSysMessage("DB table `quest_end_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `quest_start_scripts`..."); + + objmgr.LoadQuestStartScripts(); + + if(*arg!='a') + SendGlobalSysMessage("DB table `quest_start_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `spell_scripts`..."); + + objmgr.LoadSpellScripts(); + + if(*arg!='a') + SendGlobalSysMessage("DB table `spell_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Graveyard-zone links..."); + + objmgr.LoadGraveyardZones(); + + SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Game Tele coordinates..."); + + objmgr.LoadGameTele(); + + SendGlobalSysMessage("DB table `game_tele` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Creature ..."); + objmgr.LoadCreatureLocales(); + SendGlobalSysMessage("DB table `locales_creature` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Gameobject ... "); + objmgr.LoadGameObjectLocales(); + SendGlobalSysMessage("DB table `locales_gameobject` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Item ... "); + objmgr.LoadItemLocales(); + SendGlobalSysMessage("DB table `locales_item` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales NPC Text ... "); + objmgr.LoadNpcTextLocales(); + SendGlobalSysMessage("DB table `locales_npc_text` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Page Text ... "); + objmgr.LoadPageTextLocales(); + SendGlobalSysMessage("DB table `locales_page_text` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Quest ... "); + objmgr.LoadQuestLocales(); + SendGlobalSysMessage("DB table `locales_quest` reloaded."); + return true; +} + +bool ChatHandler::HandleLoadScriptsCommand(const char* args) +{ + if(!LoadScriptingModule(args)) return true; + + sWorld.SendWorldText(LANG_SCRIPTS_RELOADED); + return true; +} + +bool ChatHandler::HandleSecurityCommand(const char* args) +{ + char* arg1 = strtok((char*)args, " "); + if( !arg1 ) + return false; + + char* arg2 = 0; + + std::string targetName; + uint32 targetAccountId = 0; + uint32 targetSecurity = 0; + + Player* targetPlayer = getSelectedPlayer(); + if(targetPlayer) + { + targetName = targetPlayer->GetName(); + targetAccountId = targetPlayer->GetSession()->GetAccountId(); + targetSecurity = targetPlayer->GetSession()->GetSecurity(); + arg2 = arg1; + } + else + { + targetName = arg1; + if(!normalizePlayerName(targetName)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + targetPlayer = ObjectAccessor::Instance().FindPlayerByName(targetName.c_str()); + if(targetPlayer) + { + targetAccountId = targetPlayer->GetSession()->GetAccountId(); + targetSecurity = targetPlayer->GetSession()->GetSecurity(); + } + else + { + uint64 targetGUID = objmgr.GetPlayerGUIDByName(targetName.c_str()); + if(!targetGUID) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + targetAccountId = objmgr.GetPlayerAccountIdByGUID(targetGUID); + targetSecurity = objmgr.GetSecurityByAccount(targetAccountId); + } + + arg2 = strtok(NULL, " "); + } + + int32 gm = (int32)atoi(arg2); + if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR ) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + // can set security level only for target with less security and to less security that we have + if(targetSecurity >= m_session->GetSecurity() || uint32(gm) >= m_session->GetSecurity() ) + { + SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage(true); + return false; + } + + if(targetPlayer) + { + if( targetPlayer != m_session->GetPlayer() ) + ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,m_session->GetPlayer()->GetName(), gm); + + targetPlayer->GetSession()->SetSecurity(gm); + } + + PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetName.c_str(), gm); + loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId); + + return true; +} + +bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/) +{ + if(sWorld.getAllowMovement()) + { + sWorld.SetAllowMovement(false); + SendSysMessage(LANG_CREATURE_MOVE_DISABLED); + } + else + { + sWorld.SetAllowMovement(true); + SendSysMessage(LANG_CREATURE_MOVE_ENABLED); + } + return true; +} + +bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/) +{ + Player* SelectedPlayer = getSelectedPlayer(); + if(!SelectedPlayer) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // each skills that have max skill value dependent from level seted to current level max skill value + SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); + return true; +} + +bool ChatHandler::HandleSetSkillCommand(const char* args) +{ + // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r + char* skill_p = extractKeyFromLink((char*)args,"Hskill"); + if(!skill_p) + return false; + + char *level_p = strtok (NULL, " "); + + if( !level_p) + return false; + + char *max_p = strtok (NULL, " "); + + int32 skill = atoi(skill_p); + + if (skill <= 0) + { + PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + SetSentErrorMessage(true); + return false; + } + + int32 level = atol (level_p); + + Player * target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill); + if(!sl) + { + PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + SetSentErrorMessage(true); + return false; + } + + if(!target->GetSkillValue(skill)) + { + PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]); + SetSentErrorMessage(true); + return false; + } + + int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill); + + if( level <= 0 || level > max || max <= 0 ) + return false; + + target->SetSkill(skill, level, max); + PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max); + + return true; +} + +bool ChatHandler::HandleUnLearnCommand(const char* args) +{ + if (!*args) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + uint32 min_id = extractSpellIdFromLink((char*)args); + if(!min_id) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + char* tail = strtok(NULL,""); + + uint32 max_id = extractSpellIdFromLink(tail); + + if (!max_id) + { + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + max_id = min_id+1; + } + else + { + if (max_id < min_id) + std::swap(min_id,max_id); + + max_id=max_id+1; + } + + Player* target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + for(uint32 spell=min_id;spellHasSpell(spell)) + target->removeSpell(spell); + else + SendSysMessage(LANG_FORGET_SPELL); + } + + return true; +} + +bool ChatHandler::HandleCooldownCommand(const char* args) +{ + Player* target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if (!*args) + { + target->RemoveAllSpellCooldown(); + PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName()); + } + else + { + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell_id = extractSpellIdFromLink((char*)args); + if(!spell_id) + return false; + + if(!sSpellStore.LookupEntry(spell_id)) + { + PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName()); + SetSentErrorMessage(true); + return false; + } + + WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) ); + data << uint32(spell_id); + data << uint64(target->GetGUID()); + target->GetSession()->SendPacket(&data); + target->RemoveSpellCooldown(spell_id); + PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName()); + } + return true; +} + +bool ChatHandler::HandleLearnAllCommand(const char* /*args*/) +{ + static const char *allSpellList[] = + { + "3365", + "6233", + "6247", + "6246", + "6477", + "6478", + "22810", + "8386", + "21651", + "21652", + "522", + "7266", + "8597", + "2479", + "22027", + "6603", + "5019", + "133", + "168", + "227", + "5009", + "9078", + "668", + "203", + "20599", + "20600", + "81", + "20597", + "20598", + "20864", + "1459", + "5504", + "587", + "5143", + "118", + "5505", + "597", + "604", + "1449", + "1460", + "2855", + "1008", + "475", + "5506", + "1463", + "12824", + "8437", + "990", + "5145", + "8450", + "1461", + "759", + "8494", + "8455", + "8438", + "6127", + "8416", + "6129", + "8451", + "8495", + "8439", + "3552", + "8417", + "10138", + "12825", + "10169", + "10156", + "10144", + "10191", + "10201", + "10211", + "10053", + "10173", + "10139", + "10145", + "10192", + "10170", + "10202", + "10054", + "10174", + "10193", + "12826", + "2136", + "143", + "145", + "2137", + "2120", + "3140", + "543", + "2138", + "2948", + "8400", + "2121", + "8444", + "8412", + "8457", + "8401", + "8422", + "8445", + "8402", + "8413", + "8458", + "8423", + "8446", + "10148", + "10197", + "10205", + "10149", + "10215", + "10223", + "10206", + "10199", + "10150", + "10216", + "10207", + "10225", + "10151", + "116", + "205", + "7300", + "122", + "837", + "10", + "7301", + "7322", + "6143", + "120", + "865", + "8406", + "6141", + "7302", + "8461", + "8407", + "8492", + "8427", + "8408", + "6131", + "7320", + "10159", + "8462", + "10185", + "10179", + "10160", + "10180", + "10219", + "10186", + "10177", + "10230", + "10181", + "10161", + "10187", + "10220", + "2018", + "2663", + "12260", + "2660", + "3115", + "3326", + "2665", + "3116", + "2738", + "3293", + "2661", + "3319", + "2662", + "9983", + "8880", + "2737", + "2739", + "7408", + "3320", + "2666", + "3323", + "3324", + "3294", + "22723", + "23219", + "23220", + "23221", + "23228", + "23338", + "10788", + "10790", + "5611", + "5016", + "5609", + "2060", + "10963", + "10964", + "10965", + "22593", + "22594", + "596", + "996", + "499", + "768", + "17002", + "1448", + "1082", + "16979", + "1079", + "5215", + "20484", + "5221", + "15590", + "17007", + "6795", + "6807", + "5487", + "1446", + "1066", + "5421", + "3139", + "779", + "6811", + "6808", + "1445", + "5216", + "1737", + "5222", + "5217", + "1432", + "6812", + "9492", + "5210", + "3030", + "1441", + "783", + "6801", + "20739", + "8944", + "9491", + "22569", + "5226", + "6786", + "1433", + "8973", + "1828", + "9495", + "9006", + "6794", + "8993", + "5203", + "16914", + "6784", + "9635", + "22830", + "20722", + "9748", + "6790", + "9753", + "9493", + "9752", + "9831", + "9825", + "9822", + "5204", + "5401", + "22831", + "6793", + "9845", + "17401", + "9882", + "9868", + "20749", + "9893", + "9899", + "9895", + "9832", + "9902", + "9909", + "22832", + "9828", + "9851", + "9883", + "9869", + "17406", + "17402", + "9914", + "20750", + "9897", + "9848", + "3127", + "107", + "204", + "9116", + "2457", + "78", + "18848", + "331", + "403", + "2098", + "1752", + "11278", + "11288", + "11284", + "6461", + "2344", + "2345", + "6463", + "2346", + "2352", + "775", + "1434", + "1612", + "71", + "2468", + "2458", + "2467", + "7164", + "7178", + "7367", + "7376", + "7381", + "21156", + "5209", + "3029", + "5201", + "9849", + "9850", + "20719", + "22568", + "22827", + "22828", + "22829", + "6809", + "8972", + "9005", + "9823", + "9827", + "6783", + "9913", + "6785", + "6787", + "9866", + "9867", + "9894", + "9896", + "6800", + "8992", + "9829", + "9830", + "780", + "769", + "6749", + "6750", + "9755", + "9754", + "9908", + "20745", + "20742", + "20747", + "20748", + "9746", + "9745", + "9880", + "9881", + "5391", + "842", + "3025", + "3031", + "3287", + "3329", + "1945", + "3559", + "4933", + "4934", + "4935", + "4936", + "5142", + "5390", + "5392", + "5404", + "5420", + "6405", + "7293", + "7965", + "8041", + "8153", + "9033", + "9034", + //"9036", problems with ghost state + "16421", + "21653", + "22660", + "5225", + "9846", + "2426", + "5916", + "6634", + //"6718", phasing stealth, annoing for learn all case. + "6719", + "8822", + "9591", + "9590", + "10032", + "17746", + "17747", + "8203", + "11392", + "12495", + "16380", + "23452", + "4079", + "4996", + "4997", + "4998", + "4999", + "5000", + "6348", + "6349", + "6481", + "6482", + "6483", + "6484", + "11362", + "11410", + "11409", + "12510", + "12509", + "12885", + "13142", + "21463", + "23460", + "11421", + "11416", + "11418", + "1851", + "10059", + "11423", + "11417", + "11422", + "11419", + "11424", + "11420", + "27", + "31", + "33", + "34", + "35", + "15125", + "21127", + "22950", + "1180", + "201", + "12593", + "12842", + "16770", + "6057", + "12051", + "18468", + "12606", + "12605", + "18466", + "12502", + "12043", + "15060", + "12042", + "12341", + "12848", + "12344", + "12353", + "18460", + "11366", + "12350", + "12352", + "13043", + "11368", + "11113", + "12400", + "11129", + "16766", + "12573", + "15053", + "12580", + "12475", + "12472", + "12953", + "12488", + "11189", + "12985", + "12519", + "16758", + "11958", + "12490", + "11426", + "3565", + "3562", + "18960", + "3567", + "3561", + "3566", + "3563", + "1953", + "2139", + "12505", + "13018", + "12522", + "12523", + "5146", + "5144", + "5148", + "8419", + "8418", + "10213", + "10212", + "10157", + "12524", + "13019", + "12525", + "13020", + "12526", + "13021", + "18809", + "13031", + "13032", + "13033", + "4036", + "3920", + "3919", + "3918", + "7430", + "3922", + "3923", + "7411", + "7418", + "7421", + "13262", + "7412", + "7415", + "7413", + "7416", + "13920", + "13921", + "7745", + "7779", + "7428", + "7457", + "7857", + "7748", + "7426", + "13421", + "7454", + "13378", + "7788", + "14807", + "14293", + "7795", + "6296", + "20608", + "755", + "444", + "427", + "428", + "442", + "447", + "3578", + "3581", + "19027", + "3580", + "665", + "3579", + "3577", + "6755", + "3576", + "2575", + "2577", + "2578", + "2579", + "2580", + "2656", + "2657", + "2576", + "3564", + "10248", + "8388", + "2659", + "14891", + "3308", + "3307", + "10097", + "2658", + "3569", + "16153", + "3304", + "10098", + "4037", + "3929", + "3931", + "3926", + "3924", + "3930", + "3977", + "3925", + "136", + "228", + "5487", + "43", + "202", + "0" + }; + + int loop = 0; + while(strcmp(allSpellList[loop], "0")) + { + uint32 spell = atol((char*)allSpellList[loop++]); + + if (m_session->GetPlayer()->HasSpell(spell)) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + continue; + } + + m_session->GetPlayer()->learnSpell(spell); + } + + SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS); + + return true; +} + +bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/) +{ + static const char *gmSpellList[] = + { + "24347", // Become A Fish, No Breath Bar + "35132", // Visual Boom + "38488", // Attack 4000-8000 AOE + "38795", // Attack 2000 AOE + Slow Down 90% + "15712", // Attack 200 + "1852", // GM Spell Silence + "31899", // Kill + "31924", // Kill + "29878", // Kill My Self + "26644", // More Kill + + "28550", //Invisible 24 + "23452", //Invisible + Target + "0" + }; + + uint16 gmSpellIter = 0; + while( strcmp(gmSpellList[gmSpellIter], "0") ) + { + uint32 spell = atol((char*)gmSpellList[gmSpellIter++]); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + continue; + } + + m_session->GetPlayer()->learnSpell(spell); + } + + SendSysMessage(LANG_LEARNING_GM_SKILLS); + return true; +} + +bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/) +{ + HandleLearnAllMySpellsCommand(""); + HandleLearnAllMyTalentsCommand(""); + return true; +} + +bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/) +{ + ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass()); + if(!clsEntry) + return true; + uint32 family = clsEntry->spellfamily; + + for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i); + if(!spellInfo) + continue; + + // skip wrong class/race skills + if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id)) + continue; + + // skip other spell families + if( spellInfo->SpellFamilyName != family) + continue; + + //TODO: skip triggered spells + + // skip spells with first rank learned as talent (and all talents then also) + uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id); + if(GetTalentSpellCost(first_rank) > 0 ) + continue; + + // skip broken spells + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + m_session->GetPlayer()->learnSpell(i); + } + + SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); + return true; +} + +static void learnAllHighRanks(Player* player, uint32 spellid) +{ + SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext(); + for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr) + { + player->learnSpell(itr->second); + learnAllHighRanks(player,itr->second); + } +} + +bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/) +{ + Player* player = m_session->GetPlayer(); + uint32 classMask = player->getClassMask(); + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if(!talentInfo) + continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + if(!talentTabInfo) + continue; + + if( (classMask & talentTabInfo->ClassMask) == 0 ) + continue; + + // search highest talent rank + uint32 spellid = 0; + int rank = 4; + for(; rank >= 0; --rank) + { + if(talentInfo->RankID[rank]!=0) + { + spellid = talentInfo->RankID[rank]; + break; + } + } + + if(!spellid) // ??? none spells in telent + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + // learn highest rank of talent + player->learnSpell(spellid); + + // and learn all non-talent spell ranks (recursive by tree) + learnAllHighRanks(player,spellid); + } + + SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); + return true; +} + +bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/) +{ + // skipping UNIVERSAL language (0) + for(int i = 1; i < LANGUAGES_COUNT; ++i) + m_session->GetPlayer()->learnSpell(lang_description[i].spell_id); + + SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); + return true; +} + +bool ChatHandler::HandleLearnAllDefaultCommand(const char* args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = pName; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(name.c_str()); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + player->learnDefaultSpells(); + player->learnQuestRewardedSpells(); + + PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName()); + return true; +} + +bool ChatHandler::HandleLearnCommand(const char* args) +{ + Player* targetPlayer = getSelectedPlayer(); + + if(!targetPlayer) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell || !sSpellStore.LookupEntry(spell)) + return false; + + if (targetPlayer->HasSpell(spell)) + { + if(targetPlayer == m_session->GetPlayer()) + SendSysMessage(LANG_YOU_KNOWN_SPELL); + else + PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName()); + SetSentErrorMessage(true); + return false; + } + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + targetPlayer->learnSpell(spell); + + return true; +} + +bool ChatHandler::HandleAddItemCommand(const char* args) +{ + if (!*args) + return false; + + uint32 itemId = 0; + + if(args[0]=='[') // [name] manual form + { + char* citemName = citemName = strtok((char*)args, "]"); + + if(citemName && citemName[0]) + { + std::string itemName = citemName+1; + WorldDatabase.escape_string(itemName); + QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str()); + if (!result) + { + PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1); + SetSentErrorMessage(true); + return false; + } + itemId = result->Fetch()->GetUInt16(); + delete result; + } + else + return false; + } + else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r + { + char* cId = extractKeyFromLink((char*)args,"Hitem"); + if(!cId) + return false; + itemId = atol(cId); + } + + char* ccount = strtok(NULL, " "); + + int32 count = 1; + + if (ccount) + count = strtol(ccount, NULL, 10); + + if (count == 0) + count = 1; + + Player* pl = m_session->GetPlayer(); + Player* plTarget = getSelectedPlayer(); + if(!plTarget) + plTarget = pl; + + sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count); + + ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId); + if(!pProto) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + SetSentErrorMessage(true); + return false; + } + + //Subtract + if (count < 0) + { + plTarget->DestroyItemCount(itemId, -count, true, false); + PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName()); + return true; + } + + //Adding items + uint32 noSpaceForCount = 0; + + // check space and find places + ItemPosCountVec dest; + uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount ); + if( msg != EQUIP_ERR_OK ) // convert to possible store amount + count -= noSpaceForCount; + + if( count == 0 || dest.empty()) // can't add any + { + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount ); + SetSentErrorMessage(true); + return false; + } + + Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + + // remove binding (let GM give it to another player later) + if(pl==plTarget) + for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) + if(Item* item1 = pl->GetItemByPos(itr->pos)) + item1->SetBinding( false ); + + if(count > 0 && item) + { + pl->SendNewItem(item,count,false,true); + if(pl!=plTarget) + plTarget->SendNewItem(item,count,true,false); + } + + if(noSpaceForCount > 0) + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + + return true; +} + +bool ChatHandler::HandleAddItemSetCommand(const char* args) +{ + if (!*args) + return false; + + char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r + if (!cId) + return false; + + uint32 itemsetId = atol(cId); + + // prevent generation all items with itemset field value '0' + if (itemsetId == 0) + { + PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); + SetSentErrorMessage(true); + return false; + } + + Player* pl = m_session->GetPlayer(); + Player* plTarget = getSelectedPlayer(); + if(!plTarget) + plTarget = pl; + + sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId); + + QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE itemset = %u",itemsetId); + + if(!result) + { + PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); + + SetSentErrorMessage(true); + return false; + } + + do + { + Field *fields = result->Fetch(); + uint32 itemId = fields[0].GetUInt32(); + + ItemPosCountVec dest; + uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, 1 ); + if( msg == EQUIP_ERR_OK ) + { + Item* item = plTarget->StoreNewItem( dest, itemId, true); + + // remove binding (let GM give it to another player later) + if(pl==plTarget) + item->SetBinding( false ); + + pl->SendNewItem(item,1,false,true); + if(pl!=plTarget) + plTarget->SendNewItem(item,1,true,false); + } + else + { + pl->SendEquipError( msg, NULL, NULL ); + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, 1); + } + + }while( result->NextRow() ); + + delete result; + + return true; +} + +bool ChatHandler::HandleListItemCommand(const char* args) +{ + if(!*args) + return false; + + char* cId = extractKeyFromLink((char*)args,"Hitem"); + if(!cId) + return false; + uint32 item_id = atol(cId); + + ItemPrototype const* itemProto = item_id ? itemProto = objmgr.GetItemPrototype(item_id) : NULL; + + if(!itemProto) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); + SetSentErrorMessage(true); + return false; + } + + char* c_count = strtok(NULL, " "); + int count = c_count ? atol(c_count) : 10; + + if(count < 0) + return false; + + QueryResult *result; + + // inventory case + uint32 inv_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id); + if(result) + { + inv_count = (*result)[0].GetUInt32(); + delete result; + } + + result=CharacterDatabase.PQuery( + // 0 1 2 3 4 5 + "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name " + "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters " + "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ", + item_id,uint32(count)); + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 item_bag = fields[1].GetUInt32(); + uint32 item_slot = fields[2].GetUInt32(); + uint32 owner_guid = fields[3].GetUInt32(); + uint32 owner_acc = fields[4].GetUInt32(); + std::string owner_name = fields[5].GetCppString(); + + char const* item_pos = 0; + if(Player::IsEquipmentPos(item_bag,item_slot)) + item_pos = "[equipped]"; + else if(Player::IsInventoryPos(item_bag,item_slot)) + item_pos = "[in inventory]"; + else if(Player::IsBankPos(item_bag,item_slot)) + item_pos = "[in bank]"; + else + item_pos = ""; + + PSendSysMessage(LANG_ITEMLIST_SLOT, + item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos); + } while (result->NextRow()); + + int64 res_count = result->GetRowCount(); + + delete result; + + if(count > res_count) + count-=res_count; + else if(count) + count = 0; + } + + // mail case + uint32 mail_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id); + if(result) + { + mail_count = (*result)[0].GetUInt32(); + delete result; + } + + if(count > 0) + { + result=CharacterDatabase.PQuery( + // 0 1 2 3 4 5 6 + "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name " + "FROM mail,mail_items,characters as char_s,characters as char_r " + "WHERE mail_items.item_template='%u' AND char_s.guid = mail.sender AND char_r.guid = mail.receiver AND mail.id=mail_items.mail_id LIMIT %u", + item_id,uint32(count)); + } + else + result = NULL; + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 item_s = fields[1].GetUInt32(); + uint32 item_r = fields[2].GetUInt32(); + uint32 item_s_acc = fields[3].GetUInt32(); + std::string item_s_name = fields[4].GetCppString(); + uint32 item_r_acc = fields[5].GetUInt32(); + std::string item_r_name = fields[6].GetCppString(); + + char const* item_pos = "[in mail]"; + + PSendSysMessage(LANG_ITEMLIST_MAIL, + item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos); + } while (result->NextRow()); + + int64 res_count = result->GetRowCount(); + + delete result; + + if(count > res_count) + count-=res_count; + else if(count) + count = 0; + } + + // auction case + uint32 auc_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id); + if(result) + { + auc_count = (*result)[0].GetUInt32(); + delete result; + } + + if(count > 0) + { + result=CharacterDatabase.PQuery( + // 0 1 2 3 + "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name " + "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u", + item_id,uint32(count)); + } + else + result = NULL; + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 owner = fields[1].GetUInt32(); + uint32 owner_acc = fields[2].GetUInt32(); + std::string owner_name = fields[3].GetCppString(); + + char const* item_pos = "[in auction]"; + + PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos); + } while (result->NextRow()); + + delete result; + } + + if(inv_count+mail_count+auc_count == 0) + { + SendSysMessage(LANG_COMMAND_NOITEMFOUND); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count,inv_count,mail_count,auc_count); + + return true; +} + +bool ChatHandler::HandleListObjectCommand(const char* args) +{ + if(!*args) + return false; + + // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry"); + if(!cId) + return false; + + uint32 go_id = atol(cId); + + GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id); + + if(!go_id || !gInfo) + { + PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); + SetSentErrorMessage(true); + return false; + } + + char* c_count = strtok(NULL, " "); + int count = c_count ? atol(c_count) : 10; + + if(count < 0) + return false; + + Player* pl = m_session->GetPlayer(); + QueryResult *result; + + uint32 obj_count = 0; + result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id); + if(result) + { + obj_count = (*result)[0].GetUInt32(); + delete result; + } + + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count)); + + if (result) + { + do + { + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + float x = fields[1].GetFloat(); + float y = fields[2].GetFloat(); + float z = fields[3].GetFloat(); + int mapid = fields[4].GetUInt16(); + + PSendSysMessage(LANG_GO_LIST, guid, guid, gInfo->name, x, y, z, mapid); + } while (result->NextRow()); + + delete result; + } + + PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count); + return true; +} + +bool ChatHandler::HandleNearObjectCommand(const char* args) +{ + float distance = (!*args) ? 10 : atol(args); + uint32 count = 0; + + Player* pl = m_session->GetPlayer(); + QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, " + "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ " + "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), + pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance); + + if (result) + { + do + { + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + uint32 entry = fields[1].GetUInt32(); + float x = fields[2].GetFloat(); + float y = fields[3].GetFloat(); + float z = fields[4].GetFloat(); + int mapid = fields[5].GetUInt16(); + + GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry); + + if(!gInfo) + continue; + + PSendSysMessage(LANG_GO_LIST, guid, guid, gInfo->name, x, y, z, mapid); + + ++count; + } while (result->NextRow()); + + delete result; + } + + PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count); + return true; +} + +bool ChatHandler::HandleListCreatureCommand(const char* args) +{ + if(!*args) + return false; + + // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hcreature_entry"); + if(!cId) + return false; + + uint32 cr_id = atol(cId); + + CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id); + + if(!cr_id || !cInfo) + { + PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); + SetSentErrorMessage(true); + return false; + } + + char* c_count = strtok(NULL, " "); + int count = c_count ? atol(c_count) : 10; + + if(count < 0) + return false; + + Player* pl = m_session->GetPlayer(); + QueryResult *result; + + uint32 cr_count = 0; + result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id); + if(result) + { + cr_count = (*result)[0].GetUInt32(); + delete result; + } + + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count)); + + if (result) + { + do + { + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + float x = fields[1].GetFloat(); + float y = fields[2].GetFloat(); + float z = fields[3].GetFloat(); + int mapid = fields[4].GetUInt16(); + + PSendSysMessage(LANG_CREATURE_LIST, guid, guid, cInfo->Name, x, y, z, mapid); + } while (result->NextRow()); + + delete result; + } + + PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count); + return true; +} + +bool ChatHandler::HandleLookupItemCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0; + + // Search in `item_template` + for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) + { + ItemPrototype const *pProto = sItemStorage.LookupEntry(id); + if(!pProto) + continue; + + int loc_idx = m_session->GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + { + ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); + if (il) + { + if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + { + std::string name = il->Name[loc_idx]; + + if (Utf8FitTo(name, wnamepart)) + { + PSendSysMessage(LANG_ITEM_LIST, id, id, name.c_str()); + ++counter; + continue; + } + } + } + } + + std::string name = pProto->Name1; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + { + PSendSysMessage(LANG_ITEM_LIST, id, id, name.c_str()); + ++counter; + } + } + + if (counter==0) + SendSysMessage(LANG_COMMAND_NOITEMFOUND); + + return true; +} + +bool ChatHandler::HandleLookupItemSetCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in ItemSet.dbc + for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++) + { + ItemSetEntry const *set = sItemSetStore.LookupEntry(id); + if(set) + { + int loc = m_session->GetSessionDbcLocale(); + std::string name = set->name[m_session->GetSessionDbcLocale()]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(loc==m_session->GetSessionDbcLocale()) + continue; + + name = set->name[m_session->GetSessionDbcLocale()]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + // send item set in "id - [namedlink locale]" format + PSendSysMessage(LANG_ITEMSET_LIST,id,id,name.c_str(),localeNames[loc]); + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOITEMSETFOUND); + return true; +} + +bool ChatHandler::HandleLookupSkillCommand(const char* args) +{ + Player* target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in SkillLine.dbc + for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++) + { + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id); + if(skillInfo) + { + int loc = m_session->GetSessionDbcLocale(); + std::string name = skillInfo->name[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(loc==m_session->GetSessionDbcLocale()) + continue; + + name = skillInfo->name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + // send skill in "id - [namedlink locale]" format + PSendSysMessage(LANG_SKILL_LIST,id,id,name.c_str(),localeNames[loc],(target->HasSkill(id) ? m_session->GetMangosString(LANG_KNOWN) : "")); + + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOSKILLFOUND); + return true; +} + +bool ChatHandler::HandleLookupSpellCommand(const char* args) +{ + Player* target = getSelectedPlayer(); + if( !target ) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in Spell.dbc + for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(id); + if(spellInfo) + { + int loc = m_session->GetSessionDbcLocale(); + std::string name = spellInfo->SpellName[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(loc==m_session->GetSessionDbcLocale()) + continue; + + name = spellInfo->SpellName[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + bool known = target->HasSpell(id); + bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL); + + uint32 telentCost = GetTalentSpellCost(id); + + bool talent = (telentCost > 0); + bool passive = IsPassiveSpell(id); + bool active = target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2); + + // unit32 used to prevent interpreting uint8 as char at output + // find rank of learned spell for learning spell, or talent rank + uint32 rank = telentCost ? telentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id); + + // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format + std::ostringstream ss; + ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; + + // include rank in link name + if(rank) + ss << GetMangosString(LANG_SPELL_RANK) << rank; + + ss << " " << localeNames[loc] << "]|h|r"; + + if(talent) + ss << GetMangosString(LANG_TALENT); + if(passive) + ss << GetMangosString(LANG_PASSIVE); + if(learn) + ss << GetMangosString(LANG_LEARN); + if(known) + ss << GetMangosString(LANG_KNOWN); + if(active) + ss << GetMangosString(LANG_ACTIVE); + + SendSysMessage(ss.str().c_str()); + + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOSPELLFOUND); + return true; +} + +bool ChatHandler::HandleLookupQuestCommand(const char* args) +{ + Player* target = getSelectedPlayer(); + if( !target ) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0 ; + + ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates(); + for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter) + { + Quest * qinfo = iter->second; + + int loc_idx = m_session->GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + { + QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId()); + if (il) + { + if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty()) + { + std::string title = il->Title[loc_idx]; + + if (Utf8FitTo(title, wnamepart)) + { + QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); + + char const* statusStr = ""; + if(status == QUEST_STATUS_COMPLETE) + { + if(target->GetQuestRewardStatus(qinfo->GetQuestId())) + statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED); + else + statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE); + } + else if(status == QUEST_STATUS_INCOMPLETE) + statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE); + + PSendSysMessage(LANG_QUEST_LIST,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),(status == QUEST_STATUS_COMPLETE ? GetMangosString(LANG_COMPLETE) : (status == QUEST_STATUS_INCOMPLETE ? GetMangosString(LANG_ACTIVE) : "") )); + ++counter; + continue; + } + } + } + } + + std::string title = qinfo->GetTitle(); + if(title.empty()) + continue; + + if (Utf8FitTo(title, wnamepart)) + { + QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); + + char const* statusStr = ""; + if(status == QUEST_STATUS_COMPLETE) + { + if(target->GetQuestRewardStatus(qinfo->GetQuestId())) + statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED); + else + statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE); + } + else if(status == QUEST_STATUS_INCOMPLETE) + statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE); + + PSendSysMessage(LANG_QUEST_LIST,qinfo->GetQuestId(),qinfo->GetQuestId(), title.c_str(),(status == QUEST_STATUS_COMPLETE ? GetMangosString(LANG_COMPLETE) : (status == QUEST_STATUS_INCOMPLETE ? GetMangosString(LANG_ACTIVE) : "") )); + ++counter; + } + } + + if (counter==0) + SendSysMessage(LANG_COMMAND_NOQUESTFOUND); + + return true; +} + +bool ChatHandler::HandleLookupCreatureCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0; + + for (uint32 id = 0; id< sCreatureStorage.MaxEntry; id++ ) + { + CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(id); + if(!cInfo) + continue; + + int loc_idx = m_session->GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + { + CreatureLocale const *cl = objmgr.GetCreatureLocale(id); + if (cl) + { + if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty()) + { + std::string name = cl->Name[loc_idx]; + + if (Utf8FitTo(name, wnamepart)) + { + PSendSysMessage(LANG_CREATURE_ENTRY_LIST, id, id, name.c_str()); + ++counter; + continue; + } + } + } + } + + std::string name = cInfo->Name; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + { + PSendSysMessage(LANG_CREATURE_ENTRY_LIST,id,id,name.c_str()); + ++counter; + } + } + + if (counter==0) + SendSysMessage(LANG_COMMAND_NOCREATUREFOUND); + + return true; +} + +bool ChatHandler::HandleLookupObjectCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0; + + for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ ) + { + GameObjectInfo const* gInfo = sGOStorage.LookupEntry(id); + if(!gInfo) + continue; + + int loc_idx = m_session->GetSessionDbLocaleIndex(); + if ( loc_idx >= 0 ) + { + GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id); + if (gl) + { + if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty()) + { + std::string name = gl->Name[loc_idx]; + + if (Utf8FitTo(name, wnamepart)) + { + PSendSysMessage(LANG_GO_ENTRY_LIST, id, id, name.c_str()); + ++counter; + continue; + } + } + } + } + + std::string name = gInfo->name; + if(name.empty()) + continue; + + if(Utf8FitTo(name, wnamepart)) + { + PSendSysMessage(LANG_GO_ENTRY_LIST, id, id, name.c_str()); + ++counter; + } + } + + if(counter==0) + SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND); + + return true; +} + +/** \brief GM command level 3 - Create a guild. + * + * This command allows a GM (level 3) to create a guild. + * + * The "args" parameter contains the name of the guild leader + * and then the name of the guild. + * + */ +bool ChatHandler::HandleGuildCreateCommand(const char* args) +{ + + if (!*args) + return false; + + Guild *guild; + Player * player; + char *lname,*gname; + std::string guildname; + + lname = strtok((char*)args, " "); + gname = strtok(NULL, ""); + + if(!lname) + return false; + else if(!gname) + { + SendSysMessage(LANG_INSERT_GUILD_NAME); + SetSentErrorMessage(true); + return false; + } + + guildname = gname; + player = ObjectAccessor::Instance().FindPlayerByName(lname); + + if(!player) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(!player->GetGuildId()) + { + guild = new Guild; + if(!guild->create(player->GetGUID(),guildname)) + { + delete guild; + SendSysMessage(LANG_GUILD_NOT_CREATED); + SetSentErrorMessage(true); + return false; + } + + objmgr.AddGuild(guild); + } + else + SendSysMessage(LANG_PLAYER_IN_GUILD); + + return true; +} + +bool ChatHandler::HandleGuildInviteCommand(const char *args) +{ + if(!*args) + return false; + + char* par1 = strtok((char*)args, " "); + char* par2 = strtok (NULL, ""); + if(!par1 || !par2) + return false; + + std::string glName = par2; + Guild* targetGuild = objmgr.GetGuildByName(glName); + if(!targetGuild) + return false; + + std::string plName = par1; + if(!normalizePlayerName(plName)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 plGuid = 0; + if(Player* targetPlayer = ObjectAccessor::Instance().FindPlayerByName(plName.c_str())) + plGuid = targetPlayer->GetGUID(); + else + plGuid = objmgr.GetPlayerGUIDByName(plName.c_str()); + + if(!plGuid) + false; + + // players's guild membership checked in AddMember before add + if(!targetGuild->AddMember(plGuid,targetGuild->GetLowestRank())) + return false; + + return true; +} + +bool ChatHandler::HandleGuildUninviteCommand(const char *args) +{ + if(!*args) + return false; + + char* par1 = strtok((char*)args, " "); + if(!par1) + return false; + std::string plName = par1; + if(!normalizePlayerName(plName)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 plGuid = 0; + uint32 glId = 0; + if(Player* targetPlayer = ObjectAccessor::Instance().FindPlayerByName(plName.c_str())) + { + plGuid = targetPlayer->GetGUID(); + glId = targetPlayer->GetGuildId(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(plName.c_str()); + glId = Player::GetGuildIdFromDB(plGuid); + } + + if(!plGuid || !glId) + return false; + + Guild* targetGuild = objmgr.GetGuildById(glId); + if(!targetGuild) + return false; + + targetGuild->DelMember(plGuid); + + return true; +} + +bool ChatHandler::HandleGuildRankCommand(const char *args) +{ + if(!*args) + return false; + + char* par1 = strtok((char*)args, " "); + char* par2 = strtok(NULL, " "); + if(!par1 || !par2) + return false; + std::string plName = par1; + if(!normalizePlayerName(plName)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 plGuid = 0; + uint32 glId = 0; + if(Player* targetPlayer = ObjectAccessor::Instance().FindPlayerByName(plName.c_str())) + { + plGuid = targetPlayer->GetGUID(); + glId = targetPlayer->GetGuildId(); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName(plName.c_str()); + glId = Player::GetGuildIdFromDB(plGuid); + } + + if(!plGuid || !glId) + return false; + + Guild* targetGuild = objmgr.GetGuildById(glId); + if(!targetGuild) + return false; + + uint32 newrank = uint32(atoi(par2)); + if(newrank > targetGuild->GetLowestRank()) + return false; + + targetGuild->ChangeRank(plGuid,newrank); + + return true; +} + +bool ChatHandler::HandleGuildDeleteCommand(const char* args) +{ + if(!*args) + return false; + + char* par1 = strtok((char*)args, " "); + if(!par1) + return false; + + std::string gld = par1; + + Guild* targetGuild = objmgr.GetGuildByName(gld); + if(!targetGuild) + return false; + + targetGuild->Disband(); + + return true; +} + +bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/) +{ + Unit* pUnit = getSelectedUnit(); + + if(!pUnit) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit)); + + return true; +} + +// FIX-ME!!! + +bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/) +{ + /*if (!*args) + return false; + + uint64 guid = m_session->GetPlayer()->GetSelection(); + if (guid == 0) + { + SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + char* pSlotID = strtok((char*)args, " "); + if (!pSlotID) + return false; + + char* pItemID = strtok(NULL, " "); + if (!pItemID) + return false; + + uint32 ItemID = atoi(pItemID); + uint32 SlotID = atoi(pSlotID); + + ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID); + + bool added = false; + if(tmpItem) + { + switch(SlotID) + { + case 1: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID); + added = true; + break; + case 2: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID); + added = true; + break; + case 3: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID); + added = true; + break; + default: + PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); + added = false; + break; + } + if(added) + { + PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); + } + } + else + { + PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); + return true; + } + */ + return true; +} + +bool ChatHandler::HandleDieCommand(const char* /*args*/) +{ + Unit* target = getSelectedUnit(); + + if(!target || !m_session->GetPlayer()->GetSelection()) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if( target->isAlive() ) + { + m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + return true; +} + +bool ChatHandler::HandleDamageCommand(const char * args) +{ + if (!*args) + return false; + + Unit* target = getSelectedUnit(); + + if(!target || !m_session->GetPlayer()->GetSelection()) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if( !target->isAlive() ) + return true; + + char* damageStr = strtok((char*)args, " "); + if(!damageStr) + return false; + + int32 damage = atoi((char*)damageStr); + if(damage <=0) + return true; + + char* schoolStr = strtok((char*)NULL, " "); + + // flat melee damage without resistence/etc reduction + if(!schoolStr) + { + m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0); + return true; + } + + uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL; + if(school >= MAX_SPELL_SCHOOL) + return false; + + SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); + + if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL ) + damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage); + + char* spellStr = strtok((char*)NULL, " "); + + // melee damage by specific school + if(!spellStr) + { + uint32 absorb = 0; + uint32 resist = 0; + + m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); + + if (damage <= absorb + resist) + return true; + + damage -= absorb + resist; + + m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0); + return true; + } + + // non-melee damage + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellid = extractSpellIdFromLink((char*)args); + if(!spellid || !sSpellStore.LookupEntry(spellid)) + return false; + + m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false); + return true; +} + +bool ChatHandler::HandleModifyArenaCommand(const char * args) +{ + if (!*args) + return false; + + Player *target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + int32 amount = (uint32)atoi(args); + + target->ModifyArenaPoints(amount); + + PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints()); + + return true; +} + +bool ChatHandler::HandleReviveCommand(const char* args) +{ + Player* SelectedPlayer = NULL; + + if (*args) + { + std::string name = args; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + SelectedPlayer = objmgr.GetPlayer(name.c_str()); + } + else + SelectedPlayer = getSelectedPlayer(); + + if(!SelectedPlayer) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + SelectedPlayer->ResurrectPlayer(0.5f); + SelectedPlayer->SpawnCorpseBones(); + SelectedPlayer->SaveToDB(); + return true; +} + +bool ChatHandler::HandleAuraCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + if (!px) + return false; + + Unit *target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint32 spellID = (uint32)atoi(px); + SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID ); + if(spellInfo) + { + for(uint32 i = 0;i<3;i++) + { + uint8 eff = spellInfo->Effect[i]; + if (eff>=TOTAL_SPELL_EFFECTS) + continue; + if( IsAreaAuraEffect(eff) || + eff == SPELL_EFFECT_APPLY_AURA || + eff == SPELL_EFFECT_PERSISTENT_AREA_AURA ) + { + Aura *Aur = CreateAura(spellInfo, i, NULL, target); + target->AddAura(Aur); + } + } + } + + return true; +} + +bool ChatHandler::HandleUnAuraCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + if (!px) + return false; + + Unit *target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + std::string argstr = args; + if (argstr == "all") + { + target->RemoveAllAuras(); + return true; + } + + uint32 spellID = (uint32)atoi(px); + target->RemoveAurasDueToSpell(spellID); + + return true; +} + +bool ChatHandler::HandleLinkGraveCommand(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + if (!px) + return false; + + uint32 g_id = (uint32)atoi(px); + + uint32 g_team; + + char* px2 = strtok(NULL, " "); + + if (!px2) + g_team = 0; + else if (strncmp(px2,"horde",6)==0) + g_team = HORDE; + else if (strncmp(px2,"alliance",9)==0) + g_team = ALLIANCE; + else + return false; + + WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id); + + if(!graveyard ) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id); + SetSentErrorMessage(true); + return false; + } + + Player* player = m_session->GetPlayer(); + + uint32 zoneId = player->GetZoneId(); + + AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId); + if(!areaEntry || areaEntry->zone !=0 ) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId); + SetSentErrorMessage(true); + return false; + } + + if(graveyard->map_id != areaEntry->mapid && g_team != 0) + { + SendSysMessage(LANG_COMMAND_GRAVEYARDWRONGTEAM); + SetSentErrorMessage(true); + return false; + } + + if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team)) + PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId); + else + PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId); + + return true; +} + +bool ChatHandler::HandleNearGraveCommand(const char* args) +{ + uint32 g_team; + + size_t argslen = strlen(args); + + if(!*args) + g_team = 0; + else if (strncmp((char*)args,"horde",argslen)==0) + g_team = HORDE; + else if (strncmp((char*)args,"alliance",argslen)==0) + g_team = ALLIANCE; + else + return false; + + Player* player = m_session->GetPlayer(); + + WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard( + player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team); + + if(graveyard) + { + uint32 g_id = graveyard->ID; + + GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId()); + if (!data) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id); + SetSentErrorMessage(true); + return false; + } + + g_team = data->team; + + std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM); + + if(g_team == 0) + team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY); + else if(g_team == HORDE) + team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE); + else if(g_team == ALLIANCE) + team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId()); + } + else + { + std::string team_name; + + if(g_team == 0) + team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY); + else if(g_team == HORDE) + team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE); + else if(g_team == ALLIANCE) + team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + if(g_team == ~uint32(0)) + PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId()); + else + PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str()); + } + + return true; +} + +bool ChatHandler::HandleSpawnTransportCommand(const char* /*args*/) +{ + return true; +} + +//play npc emote +bool ChatHandler::HandlePlayEmoteCommand(const char* args) +{ + uint32 emote = atoi((char*)args); + + Creature* target = getSelectedCreature(); + if(!target) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote); + + return true; +} + +bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/) +{ + Creature* target = getSelectedCreature(); + + if(!target) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint32 faction = target->getFaction(); + uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS); + uint32 displayid = target->GetDisplayId(); + uint32 nativeid = target->GetNativeDisplayId(); + uint32 Entry = target->GetEntry(); + CreatureInfo const* cInfo = target->GetCreatureInfo(); + + int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); + if(curRespawnDelay < 0) + curRespawnDelay = 0; + std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); + std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); + + PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid); + PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); + PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); + PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); + PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); + PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId); + PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); + PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); + + if ((npcflags & UNIT_NPC_FLAG_VENDOR) ) + { + SendSysMessage(LANG_NPCINFO_VENDOR); + } + if ((npcflags & UNIT_NPC_FLAG_TRAINER) ) + { + SendSysMessage(LANG_NPCINFO_TRAINER); + } + + return true; +} + +bool ChatHandler::HandleExploreCheatCommand(const char* args) +{ + if (!*args) + return false; + + int flag = atoi((char*)args); + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName()); + if(chr!=m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,m_session->GetPlayer()->GetName()); + } + else + { + PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName()); + if(chr!=m_session->GetPlayer()) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,m_session->GetPlayer()->GetName()); + } + + for (uint8 i=0; i<128; i++) + { + if (flag != 0) + { + m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF); + } + else + { + m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0); + } + } + + return true; +} + +bool ChatHandler::HandleHoverCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + uint32 flag; + if (!px) + flag = 1; + else + flag = atoi(px); + + m_session->GetPlayer()->SetHover(flag); + + if (flag) + SendSysMessage(LANG_HOVER_ENABLED); + else + SendSysMessage(LANG_HOVER_DISABLED); + + return true; +} + +bool ChatHandler::HandleLevelUpCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + char* py = strtok((char*)NULL, " "); + + // command format parsing + char* pname = (char*)NULL; + int addlevel = 1; + + if(px && py) // .levelup name level + { + addlevel = atoi(py); + pname = px; + } + else if(px && !py) // .levelup name OR .levelup level + { + if(isalpha(px[0])) // .levelup name + pname = px; + else // .levelup level + addlevel = atoi(px); + } + // else .levelup - nothing do for prepering + + // player + Player *chr = NULL; + uint64 chr_guid = 0; + + std::string name; + + if(pname) // player by name + { + name = pname; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + chr = objmgr.GetPlayer(name.c_str()); + if(!chr) // not in game + { + chr_guid = objmgr.GetPlayerGUIDByName(name); + if (chr_guid == 0) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + } + } + else // player by selection + { + chr = getSelectedPlayer(); + + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + name = chr->GetName(); + } + + assert(chr || chr_guid); + + int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid); + int32 newlevel = oldlevel + addlevel; + if(newlevel < 1) + newlevel = 1; + if(newlevel > 255) // hardcoded maximum level + newlevel = 255; + + if(chr) + { + chr->GiveLevel(newlevel); + chr->InitTalentForLevel(); + chr->SetUInt32Value(PLAYER_XP,0); + + if(oldlevel == newlevel) + ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET); + else + if(oldlevel < newlevel) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel); + else + if(oldlevel > newlevel) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel); + } + else + { + // update levle and XP at level, all other will be updated at loading + Tokens values; + Player::LoadValuesArrayFromDB(values,chr_guid); + Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel); + Player::SetUInt32ValueInArray(values,PLAYER_XP,0); + Player::SaveValuesArrayInDB(values,chr_guid); + } + + if(m_session->GetPlayer() != chr) // including chr==NULL + PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel); + return true; +} + +bool ChatHandler::HandleShowAreaCommand(const char* args) +{ + if (!*args) + return false; + + int area = atoi((char*)args); + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + int offset = area / 32; + uint32 val = (uint32)(1 << (area % 32)); + + if(offset >= 128) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); + + SendSysMessage(LANG_EXPLORE_AREA); + return true; +} + +bool ChatHandler::HandleHideAreaCommand(const char* args) +{ + if (!*args) + return false; + + int area = atoi((char*)args); + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + int offset = area / 32; + uint32 val = (uint32)(1 << (area % 32)); + + if(offset >= 128) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val)); + + SendSysMessage(LANG_UNEXPLORE_AREA); + return true; +} + +bool ChatHandler::HandleUpdate(const char* args) +{ + if(!*args) + return false; + + uint32 updateIndex; + uint32 value; + + char* pUpdateIndex = strtok((char*)args, " "); + + Unit* chr = getSelectedUnit(); + if (chr == NULL) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(!pUpdateIndex) + { + return true; + } + updateIndex = atoi(pUpdateIndex); + //check updateIndex + if(chr->GetTypeId() == TYPEID_PLAYER) + { + if (updateIndex>=PLAYER_END) return true; + } + else + { + if (updateIndex>=UNIT_END) return true; + } + + char* pvalue = strtok(NULL, " "); + if (!pvalue) + { + value=chr->GetUInt32Value(updateIndex); + + PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value); + return true; + } + + value=atoi(pvalue); + + PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value); + + chr->SetUInt32Value(updateIndex,value); + + return true; +} + +bool ChatHandler::HandleBankCommand(const char* /*args*/) +{ + m_session->SendShowBank( m_session->GetPlayer()->GetGUID() ); + + return true; +} + +bool ChatHandler::HandleChangeWeather(const char* args) +{ + if(!*args) + return false; + + //Weather is OFF + if (!sWorld.getConfig(CONFIG_WEATHER)) + { + SendSysMessage(LANG_WEATHER_DISABLED); + SetSentErrorMessage(true); + return false; + } + + //*Change the weather of a cell + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand + float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather + + Player *player = m_session->GetPlayer(); + uint32 zoneid = player->GetZoneId(); + + Weather* wth = sWorld.FindWeather(zoneid); + + if(!wth) + wth = sWorld.AddWeather(zoneid); + if(!wth) + { + SendSysMessage(LANG_NO_WEATHER); + SetSentErrorMessage(true); + return false; + } + + wth->SetWeather(WeatherType(type), grade); + + return true; +} + +bool ChatHandler::HandleSetValue(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + + if (!px || !py) + return false; + + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = target->GetGUID(); + + uint32 Opcode = (uint32)atoi(px); + if(Opcode >= target->GetValuesCount()) + { + PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); + return false; + } + uint32 iValue; + float fValue; + bool isint32 = true; + if(pz) + isint32 = (bool)atoi(pz); + if(isint32) + { + iValue = (uint32)atoi(py); + sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue); + target->SetUInt32Value( Opcode , iValue ); + PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue); + } + else + { + fValue = (float)atof(py); + sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue); + target->SetFloatValue( Opcode , fValue ); + PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue); + } + + return true; +} + +bool ChatHandler::HandleGetValue(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* pz = strtok(NULL, " "); + + if (!px) + return false; + + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = target->GetGUID(); + + uint32 Opcode = (uint32)atoi(px); + if(Opcode >= target->GetValuesCount()) + { + PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); + return false; + } + uint32 iValue; + float fValue; + bool isint32 = true; + if(pz) + isint32 = (bool)atoi(pz); + + if(isint32) + { + iValue = target->GetUInt32Value( Opcode ); + sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue); + PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue); + } + else + { + fValue = target->GetFloatValue( Opcode ); + sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue); + PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue); + } + + return true; +} + +bool ChatHandler::HandleSet32Bit(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 Opcode = (uint32)atoi(px); + uint32 Value = (uint32)atoi(py); + if (Value > 32) //uint32 = 32 bits + return false; + + sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value); + + m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value ); + + PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1); + return true; +} + +bool ChatHandler::HandleMod32Value(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 Opcode = (uint32)atoi(px); + int Value = atoi(py); + + if(Opcode >= m_session->GetPlayer()->GetValuesCount()) + { + PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount()); + return false; + } + + sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value); + + int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode ); + + CurrentValue += Value; + m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue ); + + PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue); + + return true; +} + +bool ChatHandler::HandleAddTeleCommand(const char * args) +{ + if(!*args) + return false; + + Player *player=m_session->GetPlayer(); + if (!player) + return false; + + std::string name = args; + + if(objmgr.GetGameTele(name)) + { + SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST); + SetSentErrorMessage(true); + return false; + } + + GameTele tele; + tele.position_x = player->GetPositionX(); + tele.position_y = player->GetPositionY(); + tele.position_z = player->GetPositionZ(); + tele.orientation = player->GetOrientation(); + tele.mapId = player->GetMapId(); + tele.name = name; + + if(objmgr.AddGameTele(tele)) + { + SendSysMessage(LANG_COMMAND_TP_ADDED); + } + else + { + SendSysMessage(LANG_COMMAND_TP_ADDEDERR); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleDelTeleCommand(const char * args) +{ + if(!*args) + return false; + + std::string name = args; + + if(!objmgr.DeleteGameTele(name)) + { + SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); + SetSentErrorMessage(true); + return false; + } + + SendSysMessage(LANG_COMMAND_TP_DELETED); + return true; +} + +bool ChatHandler::HandleListAurasCommand (const char * /*args*/) +{ + Unit *unit = getSelectedUnit(); + if(!unit) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + char const* talentStr = GetMangosString(LANG_TALENT); + char const* passiveStr = GetMangosString(LANG_PASSIVE); + + Unit::AuraMap const& uAuras = unit->GetAuras(); + PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); + for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) + { + bool talent = GetTalentSpellCost(itr->second->GetId()) > 0; + PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(), + itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), + itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()], + (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); + } + for (int i = 0; i < TOTAL_AURAS; i++) + { + Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i)); + if (uAuraList.empty()) continue; + PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i); + for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr) + { + bool talent = GetTalentSpellCost((*itr)->GetId()) > 0; + PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), + (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID())); + } + } + return true; +} + +bool ChatHandler::HandleResetHonorCommand (const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = pName; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str()); + player = objmgr.GetPlayer(guid); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + return true; + } + + player->SetUInt32Value(PLAYER_FIELD_KILLS, 0); + player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); + player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0); + player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); + player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); + + return true; +} + +static bool HandleResetStatsOrLevelHelper(Player* player) +{ + PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); + if(!info) return false; + + ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass()); + if(!cEntry) + { + sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass()); + return false; + } + + uint8 powertype = cEntry->powerType; + + uint32 unitfield; + if(powertype == POWER_RAGE) + unitfield = 0x1100EE00; + else if(powertype == POWER_ENERGY) + unitfield = 0x00000000; + else if(powertype == POWER_MANA) + unitfield = 0x0000EE00; + else + { + sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass()); + return false; + } + + // reset m_form if no aura + if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) + player->m_form = FORM_NONE; + + player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); + player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f ); + + player->setFactionForRace(player->getRace()); + + player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) ); + + // reset only if player not in some form; + if(player->m_form==FORM_NONE) + { + switch(player->getGender()) + { + case GENDER_FEMALE: + player->SetDisplayId(info->displayId_f); + player->SetNativeDisplayId(info->displayId_f); + break; + case GENDER_MALE: + player->SetDisplayId(info->displayId_m); + player->SetNativeDisplayId(info->displayId_m); + break; + default: + break; + } + } + + // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value + player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); + player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); + player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form); + + player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + + //-1 is default value + player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); + + //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 ); + return true; +} + +bool ChatHandler::HandleResetLevelCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = pName; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str()); + player = objmgr.GetPlayer(guid); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(!HandleResetStatsOrLevelHelper(player)) + return false; + + player->SetLevel(1); + player->InitStatsForLevel(true); + player->InitTaxiNodesForLevel(); + player->InitTalentForLevel(); + player->SetUInt32Value(PLAYER_XP,0); + + // reset level to summoned pet + Pet* pet = player->GetPet(); + if(pet && pet->getPetType()==SUMMON_PET) + pet->InitStatsForLevel(1); + + return true; +} + +bool ChatHandler::HandleResetStatsCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = pName; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str()); + player = objmgr.GetPlayer(guid); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(!HandleResetStatsOrLevelHelper(player)) + return false; + + player->InitStatsForLevel(true); + player->InitTaxiNodesForLevel(); + player->InitTalentForLevel(); + + return true; +} + +bool ChatHandler::HandleResetSpellsCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + uint64 playerGUID = 0; + if (pName) + { + std::string name = pName; + + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(name.c_str()); + if(!player) + playerGUID = objmgr.GetPlayerGUIDByName(name.c_str()); + } + else + player = getSelectedPlayer(); + + if(!player && !playerGUID) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(player) + { + player->resetSpells(); + + ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS); + + if(m_session->GetPlayer()!=player) + PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName()); + } + else + { + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID)); + PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName); + } + + return true; +} + +bool ChatHandler::HandleResetTalentsCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + uint64 playerGUID = 0; + if (pName) + { + std::string name = pName; + if(!normalizePlayerName(name)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(name.c_str()); + if(!player) + playerGUID = objmgr.GetPlayerGUIDByName(name.c_str()); + } + else + player = getSelectedPlayer(); + + if(!player && !playerGUID) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(player) + { + player->resetTalents(true); + + ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS); + + if(m_session->GetPlayer()!=player) + PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName()); + } + else + { + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) ); + PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName); + } + + return true; +} + +bool ChatHandler::HandleResetAllCommand(const char * args) +{ + if(!*args) + return false; + + std::string casename = args; + + AtLoginFlags atLogin; + + // Command specially created as single command to prevent using short case names + if(casename=="spells") + { + atLogin = AT_LOGIN_RESET_SPELLS; + sWorld.SendWorldText(LANG_RESETALL_SPELLS); + } + else if(casename=="talents") + { + atLogin = AT_LOGIN_RESET_TALENTS; + sWorld.SendWorldText(LANG_RESETALL_TALENTS); + } + else + { + PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args); + SetSentErrorMessage(true); + return false; + } + + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u'",atLogin); + HashMapHolder::MapType const& plist = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) + itr->second->SetAtLoginFlag(atLogin); + + return true; +} + +bool ChatHandler::HandleShutDownCommand(const char* args) +{ + if(!*args) + return false; + + if(std::string(args)=="cancel") + { + sWorld.ShutdownCancel(); + } + else + { + int32 time = atoi(args); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + return false; + + sWorld.ShutdownServ(time); + } + return true; +} + +bool ChatHandler::HandleRestartCommand(const char* args) +{ + if(!*args) + return false; + + if(std::string(args)=="cancel") + { + sWorld.ShutdownCancel(); + } + else + { + int32 time = atoi(args); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + return false; + + sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART); + } + return true; +} + +bool ChatHandler::HandleIdleRestartCommand(const char* args) +{ + if(!*args) + return false; + + if(std::string(args)=="cancel") + { + sWorld.ShutdownCancel(); + } + else + { + int32 time = atoi(args); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + return false; + + sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART+SHUTDOWN_MASK_IDLE); + } + return true; +} + +bool ChatHandler::HandleIdleShutDownCommand(const char* args) +{ + if(!*args) + return false; + + if(std::string(args)=="cancel") + { + sWorld.ShutdownCancel(); + } + else + { + int32 time = atoi(args); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + return false; + + sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE); + } + return true; +} + +bool ChatHandler::HandleAddQuest(const char* args) +{ + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // .addquest #entry' + // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hquest"); + if(!cId) + return false; + + uint32 entry = atol(cId); + + Quest const* pQuest = objmgr.GetQuestTemplate(entry); + + if(!pQuest) + { + PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry); + SetSentErrorMessage(true); + return false; + } + + // check item starting quest (it can work incorrectly if added without item in inventory) + QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE startquest = '%u' LIMIT 1",entry); + if(result) + { + Field* fields = result->Fetch(); + uint32 item_id = fields[0].GetUInt32(); + delete result; + + PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry,item_id); + SetSentErrorMessage(true); + return false; + } + + // ok, normal (creature/GO starting) quest + if( player->CanAddQuest( pQuest, true ) ) + { + player->AddQuest( pQuest, NULL ); + + if ( player->CanCompleteQuest( entry ) ) + player->CompleteQuest( entry ); + } + + return true; +} + +bool ChatHandler::HandleRemoveQuest(const char* args) +{ + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // .removequest #entry' + // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hquest"); + if(!cId) + return false; + + uint32 entry = atol(cId); + + Quest const* pQuest = objmgr.GetQuestTemplate(entry); + + if(!pQuest) + { + PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); + SetSentErrorMessage(true); + return false; + } + + // remove all quest entries for 'entry' from quest log + for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot ) + { + uint32 quest = player->GetQuestSlotQuestId(slot); + if(quest==entry) + { + player->SetQuestSlot(slot,0); + + // we ignore unequippable quest items in this case, its' still be equipped + player->TakeQuestSourceItem( quest, false ); + } + } + + // set quest status to not started (will updated in DB at next save) + player->SetQuestStatus( entry, QUEST_STATUS_NONE); + + // reset rewarded for restart repeatable quest + player->getQuestStatusMap()[entry].m_rewarded = false; + + SendSysMessage(LANG_COMMAND_QUEST_REMOVED); + return true; +} + +bool ChatHandler::HandleCompleteQuest(const char* args) +{ + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // .quest complete #entry + // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hquest"); + if(!cId) + return false; + + uint32 entry = atol(cId); + + Quest const* pQuest = objmgr.GetQuestTemplate(entry); + + // If player doesn't have the quest + if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) + { + PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); + SetSentErrorMessage(true); + return false; + } + + // Add quest items for quests that require items + for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x) + { + uint32 id = pQuest->ReqItemId[x]; + uint32 count = pQuest->ReqItemCount[x]; + if(!id || !count) + continue; + + uint32 curItemCount = player->GetItemCount(id,true); + + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount ); + if( msg == EQUIP_ERR_OK ) + { + Item* item = player->StoreNewItem( dest, id, true); + player->SendNewItem(item,count-curItemCount,true,false); + } + } + + // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10") + for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + uint32 creature = pQuest->ReqCreatureOrGOId[i]; + uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i]; + + if(uint32 spell_id = pQuest->ReqSpell[i]) + { + for(uint16 z = 0; z < creaturecount; ++z) + player->CastedCreatureOrGO(creature,0,spell_id); + } + else if(creature > 0) + { + for(uint16 z = 0; z < creaturecount; ++z) + player->KilledMonster(creature,0); + } + else if(creature < 0) + { + for(uint16 z = 0; z < creaturecount; ++z) + player->CastedCreatureOrGO(creature,0,0); + } + } + + // If the quest requires reputation to complete + if(uint32 repFaction = pQuest->GetRepObjectiveFaction()) + { + uint32 repValue = pQuest->GetRepObjectiveValue(); + uint32 curRep = player->GetReputation(repFaction); + if(curRep < repValue) + { + FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction); + player->SetFactionReputation(factionEntry,repValue); + } + } + + // If the quest requires money + int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney(); + if(ReqOrRewMoney < 0) + player->ModifyMoney(-ReqOrRewMoney); + + player->CompleteQuest(entry); + return true; +} + +bool ChatHandler::HandleBanCommand(const char* args) +{ + if(!args) + return false; + + char* type = strtok((char*)args, " "); + + if(!type) + return false; + char* nameOrIP = strtok(NULL, " "); + + if(!nameOrIP) + return false; + + char* duration = strtok(NULL," "); + if(!duration || !atoi(duration)) + return false; + + char* reason = strtok(NULL,""); + if(!reason) + return false; + + switch(sWorld.BanAccount(type, nameOrIP, duration, reason,m_session->GetPlayerName())) + { + case BAN_SUCCESS: + if(atoi(duration)>0) + PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP,secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason); + else + PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP,reason); + break; + case BAN_SYNTAX_ERROR: + return false; + case BAN_NOTFOUND: + PSendSysMessage(LANG_BAN_NOTFOUND,type,nameOrIP); + break; + } + + return true; +} + +bool ChatHandler::HandleUnBanCommand(const char* args) +{ + if(!args) + return false; + char* type = strtok((char*)args, " "); + if(!type) + return false; + char* nameOrIP = strtok(NULL, " "); + + if(!nameOrIP) + return false; + + if(sWorld.RemoveBanAccount(type,nameOrIP)) + PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP); + else + PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP); + + return true; +} + +bool ChatHandler::HandleBanInfoCommand(const char* args) +{ + if(!args) + return false; + + char* cType = strtok((char*)args, " "); + char* cnameOrIP = strtok(NULL, ""); + if(!cType || !cnameOrIP) + return false; + + std::string nameOrIP = cnameOrIP; + std::string type = cType; + if (!IsIPAddress(cnameOrIP) && type=="ip") + return false; + + Field *fields; + if(type != "ip") + { + //look the accountid up + uint32 accountid; + std::string accountname; + if(type == "account") + { + loginDatabase.escape_string(nameOrIP); + QueryResult *result = loginDatabase.PQuery("SELECT id, username FROM account WHERE username = '%s'",nameOrIP.c_str()); + if (!result) + { + PSendSysMessage(LANG_BANINFO_NOACCOUNT); + return true; + } + fields = result->Fetch(); + accountid = fields[0].GetUInt32(); + accountname = fields[1].GetCppString(); + delete result; + } + else if(type == "character") + { + if(!normalizePlayerName(nameOrIP)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + loginDatabase.escape_string(nameOrIP); + QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", nameOrIP.c_str()); + if (!result) + { + PSendSysMessage(LANG_BANINFO_NOCHARACTER); + return true; + } + fields = result->Fetch(); + accountid = fields[0].GetUInt32(); + delete result; + result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", accountid); + if (!result) + { + PSendSysMessage(LANG_BANINFO_NOCHARACTER); + return true; + } + fields = result->Fetch(); + accountname = fields[0].GetCppString(); + delete result; + } + else + return false; + + QueryResult *result = loginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid); + if(!result) + { + PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname.c_str()); + return true; + } + + PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname.c_str()); + do + { + fields = result->Fetch(); + + time_t unbandate = time_t(fields[3].GetUInt64()); + bool active = false; + if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) ) + active = true; + bool permanent = (fields[1].GetUInt64() == (uint64)0); + std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true); + PSendSysMessage(LANG_BANINFO_HISTORYENTRY, + fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString()); + }while (result->NextRow()); + + delete result; + } + else + { + loginDatabase.escape_string(nameOrIP); + QueryResult *result = loginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",nameOrIP.c_str()); + if(!result) + { + PSendSysMessage(LANG_BANINFO_NOIP); + return true; + } + fields = result->Fetch(); + bool permanent = (fields[6].GetUInt64()==(uint64)0); + PSendSysMessage(LANG_BANINFO_IPENTRY, + fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(), + permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString()); + delete result; + } + return true; +} + +bool ChatHandler::HandleBanListCommand(const char* args) +{ + loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + if(!*args) + return false; + char* cType = strtok((char*)args, " "); + char* cFilter = strtok(NULL, ""); + if(!cType || !cFilter) + return false; + std::string Filter = cFilter; + std::string Type = cType; + loginDatabase.escape_string(Filter); + + QueryResult* result = NULL; + Field *fields = NULL; + if(Type == "ip") + { + result = loginDatabase.PQuery("SELECT ip FROM ip_banned WHERE ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); + if(!result) + { + PSendSysMessage(LANG_BANLIST_NOIP); + return true; + } + PSendSysMessage(LANG_BANLIST_MATCHINGIP); + do + { + fields = result->Fetch(); + PSendSysMessage("%s",fields[0].GetString()); + } while (result->NextRow()); + + delete result; + return true; + } + //lookup accountid + if(Type == "account") + { + result = loginDatabase.PQuery("SELECT id FROM account WHERE username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); + if (!result) + { + PSendSysMessage(LANG_BANLIST_NOACCOUNT); + return true; + } + //do not delete result + } + else if(Type == "characters") + { + result = CharacterDatabase.PQuery("SELECT account FROM characters, WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); + if (!result) + { + PSendSysMessage(LANG_BANLIST_NOCHARACTER); + return true; + } + } + else + return false; + + PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); + do + { + fields = result->Fetch(); + uint32 accountid = fields[0].GetUInt32(); + QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.active = '1' AND account_banned.id=account.id",accountid); + if(banresult) + { + Field* fields2 = banresult->Fetch(); + PSendSysMessage("%s",fields2[0].GetString()); + delete banresult; + } + } while (result->NextRow()); + + delete result; + return true; +} + +bool ChatHandler::HandleRespawnCommand(const char* /*args*/) +{ + Player* pl = m_session->GetPlayer(); + + CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::RespawnDo u_do; + MaNGOS::WorldObjectWorker worker(u_do); + + TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl)); + + return true; +} + +bool ChatHandler::HandleFlyModeCommand(const char* args) +{ + if(!args) + return false; + + Unit *unit = getSelectedUnit(); + if (!unit || (unit->GetTypeId() != TYPEID_PLAYER)) + unit = m_session->GetPlayer(); + + WorldPacket data(12); + if (strncmp(args, "on", 3) == 0) + data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + else if (strncmp(args, "off", 4) == 0) + data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + else + { + SendSysMessage(LANG_USE_BOL); + return false; + } + data.append(unit->GetPackGUID()); + data << uint32(0); // unknown + unit->SendMessageToSet(&data, true); + PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args); + return true; +} + +bool ChatHandler::HandleLoadPDumpCommand(const char *args) +{ + if(!args) + return false; + + char * file = strtok((char*)args, " "); if(!file) return false; + char * acc = strtok(NULL, " "); if(!acc) return false; + if(!file || !acc) + return false; + + uint32 account_id = objmgr.GetAccountByAccountName(acc); + if(!account_id) + { + account_id = atoi(acc); + if(account_id) + { + std::string acc_name; + if(!objmgr.GetAccountNameByAccount(account_id,acc_name)) + return false; + } + else + return false; + } + + char * name = strtok(NULL, " "); + char * guid_str = name ? strtok(NULL, " ") : NULL; + + uint32 guid = guid_str ? atoi(guid_str) : 0; + + if(PlayerDumpReader().LoadDump(file, account_id, name ? name : "", guid)) + PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS); + else + PSendSysMessage(LANG_COMMAND_IMPORT_FAILED); + + return true; +} + +bool ChatHandler::HandleChangeEntryCommand(const char *args) +{ + if(!args) + return false; + + uint32 newEntryNum = atoi(args); + if(!newEntryNum) + return false; + + Unit* unit = getSelectedUnit(); + if(!unit || unit->GetTypeId() != TYPEID_UNIT) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + Creature* creature = (Creature*)unit; + if(creature->UpdateEntry(newEntryNum)) + SendSysMessage(LANG_DONE); + else + SendSysMessage(LANG_ERROR); + return true; +} + +bool ChatHandler::HandleWritePDumpCommand(const char *args) +{ + if(!args) + return false; + + char* file = strtok((char*)args, " "); + char* p2 = strtok(NULL, " "); + + if(!file || !p2) + return false; + + uint32 guid = objmgr.GetPlayerGUIDByName(p2); + if(!guid) + guid = atoi(p2); + + if (PlayerDumpWriter().WriteDump(file, guid)) + PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS); + else + PSendSysMessage(LANG_COMMAND_EXPORT_FAILED); + + return true; +} + +bool ChatHandler::HandleMovegensCommand(const char* /*args*/) +{ + Unit* unit = getSelectedUnit(); + if(!unit) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow()); + + MotionMaster* mm = unit->GetMotionMaster(); + for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr) + { + switch((*itr)->GetMovementGeneratorType()) + { + case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break; + case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break; + case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break; + case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break; + case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break; + case TARGETED_MOTION_TYPE: + { + if(unit->GetTypeId()==TYPEID_PLAYER) + { + TargetedMovementGenerator const* mgen = static_cast const*>(*itr); + Unit* target = mgen->GetTarget(); + if(target) + PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow()); + else + SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); + } + else + { + TargetedMovementGenerator const* mgen = static_cast const*>(*itr); + Unit* target = mgen->GetTarget(); + if(target) + PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow()); + else + SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); + } + break; + } + case HOME_MOTION_TYPE: + if(unit->GetTypeId()==TYPEID_UNIT) + { + float x,y,z; + (*itr)->GetDestination(x,y,z); + PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z); + } + else + SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); + break; + case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break; + case POINT_MOTION_TYPE: + { + float x,y,z; + (*itr)->GetDestination(x,y,z); + PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z); + break; + } + case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break; + case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break; + default: + PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType()); + break; + } + } + return true; +} + +bool ChatHandler::HandlePLimitCommand(const char *args) +{ + if(*args) + { + char* param = strtok((char*)args, " "); + if(!param) + return false; + + int l = strlen(param); + + if( strncmp(param,"player",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_PLAYER); + else if(strncmp(param,"moderator",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_MODERATOR); + else if(strncmp(param,"gamemaster",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_GAMEMASTER); + else if(strncmp(param,"administrator",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); + else if(strncmp(param,"reset",l) == 0 ) + sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) ); + else + { + int val = atoi(param); + if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR; + + sWorld.SetPlayerLimit(val); + } + + // kick all low security level players + if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER) + sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); + } + + uint32 pLimit = sWorld.GetPlayerAmountLimit(); + AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); + char const* secName = ""; + switch(allowedAccountType) + { + case SEC_PLAYER: secName = "Player"; break; + case SEC_MODERATOR: secName = "Moderator"; break; + case SEC_GAMEMASTER: secName = "Gamemaster"; break; + case SEC_ADMINISTRATOR: secName = "Administrator"; break; + default: secName = ""; break; + } + + PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName); + + return true; +} + +bool ChatHandler::HandleCastCommand(const char* args) +{ + if(!*args) + return false; + + Unit* target = getSelectedUnit(); + + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell) + return false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo) + return false; + + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + m_session->GetPlayer()->CastSpell(target,spell,triggered); + + return true; +} + +bool ChatHandler::HandleCastBackCommand(const char* args) +{ + Creature* caster = getSelectedCreature(); + + if(!caster) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell || !sSpellStore.LookupEntry(spell)) + return false; + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + // update orientation at server + caster->SetOrientation(caster->GetAngle(m_session->GetPlayer())); + + // and client + WorldPacket data; + caster->BuildHeartBeatMsg(&data); + caster->SendMessageToSet(&data,true); + + caster->CastSpell(m_session->GetPlayer(),spell,false); + + return true; +} + +bool ChatHandler::HandleCastDistCommand(const char* args) +{ + if(!*args) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell) + return false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo) + return false; + + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + char *distStr = strtok(NULL, " "); + + float dist = 0; + + if(distStr) + sscanf(distStr, "%f", &dist); + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + float x,y,z; + m_session->GetPlayer()->GetClosePoint(x,y,z,dist); + + m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered); + return true; +} + +bool ChatHandler::HandleCastTargetCommand(const char* args) +{ + Creature* caster = getSelectedCreature(); + + if(!caster) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(!caster->getVictim()) + { + SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell || !sSpellStore.LookupEntry(spell)) + return false; + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + // update orientation at server + caster->SetOrientation(caster->GetAngle(m_session->GetPlayer())); + + // and client + WorldPacket data; + caster->BuildHeartBeatMsg(&data); + caster->SendMessageToSet(&data,true); + + caster->CastSpell(caster->getVictim(),spell,false); + + return true; +} + +/* +ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator +Without this function 3rd party scripting library will get linking errors (unresolved external) +when attempting to use the PointMovementGenerator +*/ +bool ChatHandler::HandleComeToMeCommand(const char *args) +{ + Creature* caster = getSelectedCreature(); + + if(!caster) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + char* newFlagStr = strtok((char*)args, " "); + + if(!newFlagStr) + return false; + + uint32 newFlags = atoi(newFlagStr); + + caster->SetUnitMovementFlags(newFlags); + + Player* pl = m_session->GetPlayer(); + + caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ()); + return true; +} + +bool ChatHandler::HandleCastSelfCommand(const char* args) +{ + if(!*args) + return false; + + Unit* target = getSelectedUnit(); + + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell) + return false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo) + return false; + + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + target->CastSpell(target,spell,false); + + return true; +} + +std::string GetTimeString(uint32 time) +{ + uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE; + std::ostringstream ss; + if(days) ss << days << "d "; + if(hours) ss << hours << "h "; + ss << minute << "m"; + return ss.str(); +} + +bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) +{ + Player* player = getSelectedPlayer(); + if (!player) player = m_session->GetPlayer(); + uint32 counter = 0; + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr) + { + InstanceSave *save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + counter++; + } + } + PSendSysMessage("player binds: %d", counter); + counter = 0; + Group *group = player->GetGroup(); + if(group) + { + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + Group::BoundInstancesMap &binds = group->GetBoundInstances(i); + for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr) + { + InstanceSave *save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + counter++; + } + } + } + PSendSysMessage("group binds: %d", counter); + + return true; +} + +bool ChatHandler::HandleInstanceUnbindCommand(const char* args) +{ + if(!*args) + return false; + + std::string cmd = args; + if(cmd == "all") + { + Player* player = getSelectedPlayer(); + if (!player) player = m_session->GetPlayer(); + uint32 counter = 0; + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) + { + if(itr->first != player->GetMapId()) + { + InstanceSave *save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + player->UnbindInstance(itr, i); + counter++; + } + else + ++itr; + } + } + PSendSysMessage("instances unbound: %d", counter); + } + return true; +} + +bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/) +{ + PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances()); + PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances()); + PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves()); + PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal()); + PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal()); + return true; +} + +bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) +{ + Player* pl = m_session->GetPlayer(); + + Map* map = pl->GetMap(); + if (!map->IsDungeon()) + { + PSendSysMessage("Map is not a dungeon."); + SetSentErrorMessage(true); + return false; + } + + if (!((InstanceMap*)map)->GetInstanceData()) + { + PSendSysMessage("Map has no instance data."); + SetSentErrorMessage(true); + return false; + } + + ((InstanceMap*)map)->GetInstanceData()->SaveToDB(); + return true; +} diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp new file mode 100644 index 000000000..97314423f --- /dev/null +++ b/src/game/LootHandler.cpp @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "Log.h" +#include "Corpse.h" +#include "GameObject.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "WorldSession.h" +#include "LootMgr.h" +#include "Object.h" +#include "Group.h" +#include "World.h" +#include "Util.h" + +void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1); + + sLog.outDebug("WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); + Player *player = GetPlayer(); + uint64 lguid = player->GetLootGUID(); + Loot *loot; + uint8 lootSlot; + + recv_data >> lootSlot; + + if (IS_GAMEOBJECT_GUID(lguid)) + { + GameObject *go = + ObjectAccessor::GetGameObject(*player, lguid); + + // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO + if (!go || (go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) + { + player->SendLootRelease(lguid); + return; + } + + loot = &go->loot; + } + else if (IS_ITEM_GUID(lguid)) + { + Item *pItem = player->GetItemByGuid( lguid ); + + if (!pItem) + { + player->SendLootRelease(lguid); + return; + } + + loot = &pItem->loot; + } + else + { + Creature* pCreature = + ObjectAccessor::GetCreature(*player, lguid); + + bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); + + if( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + { + player->SendLootRelease(lguid); + return; + } + + loot = &pCreature->loot; + } + + QuestItem *qitem = NULL; + QuestItem *ffaitem = NULL; + QuestItem *conditem = NULL; + + LootItem *item = loot->LootItemInSlot(lootSlot,player,&qitem,&ffaitem,&conditem); + + if(!item) + { + player->SendEquipError( EQUIP_ERR_ALREADY_LOOTED, NULL, NULL ); + return; + } + + // questitems use the blocked field for other purposes + if (!qitem && item->is_blocked) + { + player->SendLootRelease(lguid); + return; + } + + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count ); + if ( msg == EQUIP_ERR_OK ) + { + Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId); + + if (qitem) + { + qitem->is_looted = true; + //freeforall is 1 if everyone's supposed to get the quest item. + if (item->freeforall || loot->GetPlayerQuestItems().size() == 1) + player->SendNotifyLootItemRemoved(lootSlot); + else + loot->NotifyQuestItemRemoved(qitem->index); + } + else + { + if (ffaitem) + { + //freeforall case, notify only one player of the removal + ffaitem->is_looted=true; + player->SendNotifyLootItemRemoved(lootSlot); + } + else + { + //not freeforall, notify everyone + if(conditem) + conditem->is_looted=true; + loot->NotifyItemRemoved(lootSlot); + } + } + + //if only one person is supposed to loot the item, then set it to looted + if (!item->freeforall) + item->is_looted = true; + + --loot->unlootedCount; + + player->SendNewItem(newitem, uint32(item->count), false, false, true); + } + else + player->SendEquipError( msg, NULL, NULL ); +} + +void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("WORLD: CMSG_LOOT_MONEY"); + + Player *player = GetPlayer(); + uint64 guid = player->GetLootGUID(); + if(!guid) + return; + + Loot *pLoot = NULL; + + switch(GUID_HIPART(guid)) + { + case HIGHGUID_GAMEOBJECT: + { + GameObject *pGameObject = ObjectAccessor::GetGameObject(*GetPlayer(), guid); + + // not check distance for GO in case owned GO (fishing bobber case, for example) + if( pGameObject && (pGameObject->GetOwnerGUID()==_player->GetGUID() || pGameObject->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) ) + pLoot = &pGameObject->loot; + + break; + } + case HIGHGUID_CORPSE: // remove insignia ONLY in BG + { + Corpse *bones = ObjectAccessor::GetCorpse(*GetPlayer(), guid); + + if (bones && bones->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + pLoot = &bones->loot; + + break; + } + case HIGHGUID_ITEM: + { + if(Item *item = GetPlayer()->GetItemByGuid(guid)) + pLoot = &item->loot; + break; + } + case HIGHGUID_UNIT: + { + Creature* pCreature = ObjectAccessor::GetCreature(*GetPlayer(), guid); + + bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); + + if ( ok_loot && pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + pLoot = &pCreature->loot ; + + break; + } + default: + return; // unlootable type + } + + if( pLoot ) + { + if (!IS_ITEM_GUID(guid) && player->GetGroup()) //item can be looted only single player + { + Group *group = player->GetGroup(); + + std::vector playersNear; + for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* playerGroup = itr->getSource(); + if(!playerGroup) + continue; + if (player->GetDistance2d(playerGroup) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + playersNear.push_back(playerGroup); + } + + uint32 money_per_player = uint32((pLoot->gold)/(playersNear.size())); + + for (std::vector::iterator i = playersNear.begin(); i != playersNear.end(); ++i) + { + (*i)->ModifyMoney( money_per_player ); + //Offset surely incorrect, but works + WorldPacket data( SMSG_LOOT_MONEY_NOTIFY, 4 ); + data << uint32(money_per_player); + (*i)->GetSession()->SendPacket( &data ); + } + } + else + player->ModifyMoney( pLoot->gold ); + pLoot->gold = 0; + pLoot->NotifyMoneyRemoved(); + } +} + +void WorldSession::HandleLootOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug("WORLD: CMSG_LOOT"); + + uint64 guid; + recv_data >> guid; + + GetPlayer()->SendLoot(guid, LOOT_CORPSE); +} + +void WorldSession::HandleLootReleaseOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug("WORLD: CMSG_LOOT_RELEASE"); + + // cheaters can modify lguid to prevent correct apply loot release code and re-loot + // use internal stored guid + //uint64 lguid; + //recv_data >> lguid; + + if(uint64 lguid = GetPlayer()->GetLootGUID()) + DoLootRelease(lguid); +} + +void WorldSession::DoLootRelease( uint64 lguid ) +{ + Player *player = GetPlayer(); + Loot *loot; + + player->SetLootGUID(0); + player->SendLootRelease(lguid); + + player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); + + if (IS_GAMEOBJECT_GUID(lguid)) + { + GameObject *go = + ObjectAccessor::GetGameObject(*player, lguid); + + // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO + if (!go || (go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) + return; + + loot = &go->loot; + + if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR) + { + // locked doors are opened with spelleffect openlock, prevent remove its as looted + go->UseDoorOrButton(); + } + else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE) + { + // GO is mineral vein? so it is not removed after its looted + if(go->GetGoType() == GAMEOBJECT_TYPE_CHEST) + { + uint32 go_min = go->GetGOInfo()->chest.minSuccessOpens; + uint32 go_max = go->GetGOInfo()->chest.maxSuccessOpens; + + // only vein pass this check + if(go_min != 0 && go_max > go_min) + { + float amount_rate = sWorld.getRate(RATE_MINING_AMOUNT); + float min_amount = go_min*amount_rate; + float max_amount = go_max*amount_rate; + + go->AddUse(); + float uses = float(go->GetUseCount()); + + if(uses < max_amount) + { + if(uses >= min_amount) + { + float chance_rate = sWorld.getRate(RATE_MINING_NEXT); + + int32 ReqValue = 175; + LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId); + if(lockInfo) + ReqValue = lockInfo->requiredminingskill; + float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25); + double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses)); + if(roll_chance_f(100*chance+skill)) + { + go->SetLootState(GO_READY); + } + else // not have more uses + go->SetLootState(GO_JUST_DEACTIVATED); + } + else // 100% chance until min uses + go->SetLootState(GO_READY); + } + else // max uses already + go->SetLootState(GO_JUST_DEACTIVATED); + } + else // not vein + go->SetLootState(GO_JUST_DEACTIVATED); + } + else if (go->GetGoType() == GAMEOBJECT_TYPE_FISHINGHOLE) + { // The fishing hole used once more + go->AddUse(); // if the max usage is reached, will be despawned in next tick + if (go->GetUseCount()>=irand(go->GetGOInfo()->fishinghole.minSuccessOpens,go->GetGOInfo()->fishinghole.maxSuccessOpens)) + { + go->SetLootState(GO_JUST_DEACTIVATED); + } + else + go->SetLootState(GO_READY); + } + else // not chest (or vein/herb/etc) + go->SetLootState(GO_JUST_DEACTIVATED); + + loot->clear(); + } + else + // not fully looted object + go->SetLootState(GO_ACTIVATED); + } + else if (IS_CORPSE_GUID(lguid)) // ONLY remove insignia at BG + { + Corpse *corpse = ObjectAccessor::GetCorpse(*player, lguid); + if (!corpse || !corpse->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + return; + + loot = &corpse->loot; + + if (loot->isLooted()) + { + loot->clear(); + corpse->RemoveFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE); + } + } + else if (IS_ITEM_GUID(lguid)) + { + Item *pItem = player->GetItemByGuid(lguid ); + if(!pItem) + return; + if( (pItem->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) && + pItem->GetProto()->Class == ITEM_CLASS_TRADE_GOODS && + pItem->GetCount() >= 5) + { + pItem->m_lootGenerated = false; + pItem->loot.clear(); + + uint32 count = 5; + player->DestroyItemCount(pItem, count, true); + } + else + // FIXME: item don't must be deleted in case not fully looted state. But this pre-request implement loot saving in DB at item save. Or checting possible. + player->DestroyItem( pItem->GetBagSlot(),pItem->GetSlot(), true); + return; // item can be looted only single player + } + else + { + Creature* pCreature = ObjectAccessor::GetCreature(*player, lguid); + + bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); + if ( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + return; + + loot = &pCreature->loot; + + // update next looter + if(Player *recipient = pCreature->GetLootRecipient()) + if(Group* group = recipient->GetGroup()) + if (group->GetLooterGuid() == player->GetGUID()) + group->UpdateLooterGuid(pCreature); + + if (loot->isLooted()) + { + // skip pickpocketing loot for speed, skinning timer redunction is no-op in fact + if(!pCreature->isAlive()) + pCreature->AllLootRemovedFromCorpse(); + + pCreature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + loot->clear(); + } + } + + //Player is not looking at loot list, he doesn't need to see updates on the loot list + loot->RemoveLooter(player->GetGUID()); +} + +void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+1+8); + + uint8 slotid; + uint64 lootguid, target_playerguid; + + recv_data >> lootguid >> slotid >> target_playerguid; + + if(!_player->GetGroup() || _player->GetGroup()->GetLooterGuid() != _player->GetGUID()) + { + _player->SendLootRelease(GetPlayer()->GetLootGUID()); + return; + } + + Player *target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER)); + if(!target) + return; + + sLog.outDebug("WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [%s].", target->GetName()); + + if(_player->GetLootGUID() != lootguid) + return; + + Loot *pLoot = NULL; + + if(IS_CREATURE_GUID(GetPlayer()->GetLootGUID())) + { + Creature *pCreature = ObjectAccessor::GetCreature(*GetPlayer(), lootguid); + if(!pCreature) + return; + + pLoot = &pCreature->loot; + } + else if(IS_GAMEOBJECT_GUID(GetPlayer()->GetLootGUID())) + { + GameObject *pGO = ObjectAccessor::GetGameObject(*GetPlayer(), lootguid); + if(!pGO) + return; + + pLoot = &pGO->loot; + } + + if(!pLoot) + return; + + if (slotid > pLoot->items.size()) + { + sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %d)",GetPlayer()->GetName(), slotid, pLoot->items.size()); + return; + } + + LootItem& item = pLoot->items[slotid]; + + ItemPosCountVec dest; + uint8 msg = target->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item.itemid, item.count ); + if ( msg != EQUIP_ERR_OK ) + { + target->SendEquipError( msg, NULL, NULL ); + _player->SendEquipError( msg, NULL, NULL ); // send duplicate of error massage to master looter + return; + } + + // not move item from loot to target inventory + Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); + target->SendNewItem(newitem, uint32(item.count), false, false, true ); + + // mark as looted + item.count=0; + item.is_looted=true; + + + pLoot->NotifyItemRemoved(slotid); + --pLoot->unlootedCount; +} diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp new file mode 100644 index 000000000..c19535ccd --- /dev/null +++ b/src/game/LootMgr.cpp @@ -0,0 +1,1238 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "LootMgr.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "ProgressBar.h" +#include "World.h" +#include "Util.h" +#include "SharedDefines.h" + +static Rates const qualityToRate[MAX_ITEM_QUALITY] = { + RATE_DROP_ITEM_POOR, // ITEM_QUALITY_POOR + RATE_DROP_ITEM_NORMAL, // ITEM_QUALITY_NORMAL + RATE_DROP_ITEM_UNCOMMON, // ITEM_QUALITY_UNCOMMON + RATE_DROP_ITEM_RARE, // ITEM_QUALITY_RARE + RATE_DROP_ITEM_EPIC, // ITEM_QUALITY_EPIC + RATE_DROP_ITEM_LEGENDARY, // ITEM_QUALITY_LEGENDARY + RATE_DROP_ITEM_ARTIFACT, // ITEM_QUALITY_ARTIFACT +}; + +LootStore LootTemplates_Creature( "creature_loot_template", "creature entry"); +LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id"); +LootStore LootTemplates_Fishing( "fishing_loot_template", "area id"); +LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry"); +LootStore LootTemplates_Item( "item_loot_template", "item entry"); +LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid"); +LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry"); +LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id"); +LootStore LootTemplates_Reference( "reference_loot_template", "reference id"); +LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id"); + +class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed) +{ + public: + void AddEntry(LootStoreItem& item); // Adds an entry to the group (at loading stage) + bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry + bool HasQuestDropForPlayer(Player const * player) const; + // The same for active quests of the player + void Process(Loot& loot) const; // Rolls an item from the group (if any) and adds the item to the loot + float RawTotalChance() const; // Overall chance for the group (without equal chanced items) + float TotalChance() const; // Overall chance for the group + + void Verify(LootStore const& lootstore, uint32 id, uint32 group_id) const; + void CollectLootIds(LootIdSet& set) const; + void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const; + private: + LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB + LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance + + LootStoreItem const * Roll() const; // Rolls an item from the group, returns NULL if all miss their chances +}; + +//Remove all data and free all memory +void LootStore::Clear() +{ + for (LootTemplateMap::const_iterator itr=m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr) + delete itr->second; + m_LootTemplates.clear(); +} + +// Checks validity of the loot store +// Actual checks are done within LootTemplate::Verify() which is called for every template +void LootStore::Verify() const +{ + for (LootTemplateMap::const_iterator i = m_LootTemplates.begin(); i != m_LootTemplates.end(); ++i ) + i->second->Verify(*this, i->first); +} + +// Loads a *_loot_template DB table into loot store +// All checks of the loaded template are called from here, no error reports at loot generation required +void LootStore::LoadLootTable() +{ + LootTemplateMap::iterator tab; + uint32 count = 0; + + // Clearing store (for reloading case) + Clear(); + + sLog.outString( "%s :", GetName()); + + // 0 1 2 3 4 5 6 7 8 + QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2 FROM %s",GetName()); + + if (result) + { + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + uint32 item = fields[1].GetUInt32(); + float chanceOrQuestChance = fields[2].GetFloat(); + uint8 group = fields[3].GetUInt8(); + int32 mincountOrRef = fields[4].GetInt32(); + uint8 maxcount = fields[5].GetUInt8(); + ConditionType condition = (ConditionType)fields[6].GetUInt8(); + uint32 cond_value1 = fields[7].GetUInt32(); + uint32 cond_value2 = fields[8].GetUInt32(); + + if(!PlayerCondition::IsValid(condition,cond_value1, cond_value2)) + { + sLog.outErrorDb("... in table '%s' entry %u item %u", GetName(), entry, item); + continue; // error already printed to log/console. + } + + // (condition + cond_value1/2) are converted into single conditionId + uint16 conditionId = objmgr.GetConditionId(condition, cond_value1, cond_value2); + + LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount); + + if (!storeitem.IsValid(*this,entry)) // Validity checks + continue; + + // Looking for the template of the entry + // often entries are put together + if (m_LootTemplates.empty() || tab->first != entry) + { + // Searching the template (in case template Id changed) + tab = m_LootTemplates.find(entry); + if ( tab == m_LootTemplates.end() ) + { + std::pair< LootTemplateMap::iterator, bool > pr = m_LootTemplates.insert(LootTemplateMap::value_type(entry, new LootTemplate)); + tab = pr.first; + } + } + // else is empty - template Id and iter are the same + // finally iter refers to already existed or just created + + // Adds current row to the template + tab->second->AddEntry(storeitem); + ++count; + + } while (result->NextRow()); + + delete result; + + Verify(); // Checks validity of the loot store + + sLog.outString(); + sLog.outString( ">> Loaded %u loot definitions (%d templates)", count, m_LootTemplates.size()); + } + else + { + sLog.outString(); + sLog.outErrorDb( ">> Loaded 0 loot definitions. DB table `%s` is empty.",GetName() ); + } +} + +bool LootStore::HaveQuestLootFor(uint32 loot_id) const +{ + LootTemplateMap::const_iterator itr = m_LootTemplates.find(loot_id); + if(itr == m_LootTemplates.end()) + return false; + + // scan loot for quest items + return itr->second->HasQuestDrop(m_LootTemplates); +} + +bool LootStore::HaveQuestLootForPlayer(uint32 loot_id,Player* player) const +{ + LootTemplateMap::const_iterator tab = m_LootTemplates.find(loot_id); + if (tab != m_LootTemplates.end()) + if (tab->second->HasQuestDropForPlayer(m_LootTemplates, player)) + return true; + + return false; +} + +LootTemplate const* LootStore::GetLootFor(uint32 loot_id) const +{ + LootTemplateMap::const_iterator tab = m_LootTemplates.find(loot_id); + + if (tab == m_LootTemplates.end()) + return NULL; + + return tab->second; +} + +void LootStore::LoadAndCollectLootIds(LootIdSet& ids_set) +{ + LoadLootTable(); + + for(LootTemplateMap::const_iterator tab = m_LootTemplates.begin(); tab != m_LootTemplates.end(); ++tab) + ids_set.insert(tab->first); +} + +void LootStore::CheckLootRefs(LootIdSet* ref_set) const +{ + for(LootTemplateMap::const_iterator ltItr = m_LootTemplates.begin(); ltItr != m_LootTemplates.end(); ++ltItr) + ltItr->second->CheckLootRefs(m_LootTemplates,ref_set); +} + +void LootStore::ReportUnusedIds(LootIdSet const& ids_set) const +{ + // all still listed ids isn't referenced + for(LootIdSet::const_iterator itr = ids_set.begin(); itr != ids_set.end(); ++itr) + sLog.outErrorDb("Table '%s' entry %d isn't %s and not referenced from loot, and then useless.", GetName(), *itr,GetEntryName()); +} + +void LootStore::ReportNotExistedId(uint32 id) const +{ + sLog.outErrorDb("Table '%s' entry %d (%s) not exist but used as loot id in DB.", GetName(), id,GetEntryName()); +} + +// +// --------- LootStoreItem --------- +// + +// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation) +// RATE_DROP_ITEMS is no longer used for all types of entries +bool LootStoreItem::Roll() const +{ + if(chance>=100.f) + return true; + + if(mincountOrRef < 0) // reference case + return roll_chance_f(chance*sWorld.getRate(RATE_DROP_ITEM_REFERENCED)); + + ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid); + + float qualityModifier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; + + return roll_chance_f(chance*qualityModifier); +} + +// Checks correctness of values +bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const +{ + if (mincountOrRef == 0) + { + sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef); + return false; + } + + if( mincountOrRef > 0 ) // item (quest or non-quest) entry, maybe grouped + { + ItemPrototype const *proto = objmgr.GetItemPrototype(itemid); + if(!proto) + { + sLog.outErrorDb("Table '%s' entry %d item %d: item entry not listed in `item_template` - skipped", store.GetName(), entry, itemid); + return false; + } + + if( chance == 0 && group == 0) // Zero chance is allowed for grouped entries only + { + sLog.outErrorDb("Table '%s' entry %d item %d: equal-chanced grouped entry, but group not defined - skipped", store.GetName(), entry, itemid); + return false; + } + + if( chance != 0 && chance < 0.000001f ) // loot with low chance + { + sLog.outErrorDb("Table '%s' entry %d item %d: low chance (%d) - skipped", store.GetName(), entry, itemid, chance); + return false; + } + } + else // mincountOrRef < 0 + { + if (needs_quest) + sLog.outErrorDb("Table '%s' entry %d item %d: quest chance will be treated as non-quest chance", store.GetName(), entry, itemid); + else if( chance == 0 ) // no chance for the reference + { + sLog.outErrorDb("Table '%s' entry %d item %d: zero chance is specified for a reference, skipped", store.GetName(), entry, itemid); + return false; + } + } + return true; // Referenced template existence is checked at whole store level +} + +// +// --------- LootItem --------- +// + +// Constructor, copies most fields from LootStoreItem and generates random count +LootItem::LootItem(LootStoreItem const& li) +{ + itemid = li.itemid; + conditionId = li.conditionId; + + ItemPrototype const* proto = objmgr.GetItemPrototype(itemid); + freeforall = proto && (proto->Flags & ITEM_FLAGS_PARTY_LOOT); + + needs_quest = li.needs_quest; + + count = urand(li.mincountOrRef, li.maxcount); // constructor called for mincountOrRef > 0 only + randomSuffix = GenerateEnchSuffixFactor(itemid); + randomPropertyId = Item::GenerateItemRandomPropertyId(itemid); + is_looted = 0; + is_blocked = 0; + is_underthreshold = 0; + is_counted = 0; +} + +// Basic checks for player/item compatibility - if false no chance to see the item in the loot +bool LootItem::AllowedForPlayer(Player const * player) const +{ + // DB conditions check + if ( !objmgr.IsPlayerMeetToCondition(player,conditionId) ) + return false; + + if ( needs_quest ) + { + // Checking quests for quest-only drop (check only quests requirements in this case) + if( !player->HasQuestForItem(itemid) ) + return false; + } + else + { + // Not quest only drop (check quest starting items for already accepted non-repeatable quests) + ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid); + if (pProto && pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid)) + return false; + } + + return true; +} + +// +// --------- Loot --------- +// + +// Inserts the item into the loot (called by LootTemplate processors) +void Loot::AddItem(LootStoreItem const & item) +{ + if (item.needs_quest) // Quest drop + { + if (quest_items.size() < MAX_NR_QUEST_ITEMS) + quest_items.push_back(LootItem(item)); + } + else if (items.size() < MAX_NR_LOOT_ITEMS) // Non-quest drop + { + items.push_back(LootItem(item)); + + // non-conditional one-player only items are counted here, + // free for all items are counted in FillFFALoot(), + // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() + if( !item.conditionId ) + { + ItemPrototype const* proto = objmgr.GetItemPrototype(item.itemid); + if( !proto || (proto->Flags & ITEM_FLAGS_PARTY_LOOT)==0 ) + ++unlootedCount; + } + } +} + +// Calls processor of corresponding LootTemplate (which handles everything including references) +void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner) +{ + LootTemplate const* tab = store.GetLootFor(loot_id); + + if (!tab) + { + sLog.outErrorDb("Table '%s' loot id #%u used but it doesn't have records.",store.GetName(),loot_id); + return; + } + + items.reserve(MAX_NR_LOOT_ITEMS); + quest_items.reserve(MAX_NR_QUEST_ITEMS); + + tab->Process(*this, store); // Processing is done there, callback via Loot::AddItem() + + // Setting access rights fow group-looting case + if(!loot_owner) + return; + Group * pGroup=loot_owner->GetGroup(); + if(!pGroup) + return; + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + //fill the quest item map for every player in the recipient's group + Player* pl = itr->getSource(); + if(!pl) + continue; + uint32 plguid = pl->GetGUIDLow(); + QuestItemMap::iterator qmapitr = PlayerQuestItems.find(plguid); + if (qmapitr == PlayerQuestItems.end()) + { + FillQuestLoot(pl); + } + qmapitr = PlayerFFAItems.find(plguid); + if (qmapitr == PlayerFFAItems.end()) + { + FillFFALoot(pl); + } + qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid); + if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end()) + { + FillNonQuestNonFFAConditionalLoot(pl); + } + } +} + +QuestItemList* Loot::FillFFALoot(Player* player) +{ + QuestItemList *ql = new QuestItemList(); + + for(uint8 i = 0; i < items.size(); i++) + { + LootItem &item = items[i]; + if(!item.is_looted && item.freeforall && item.AllowedForPlayer(player) ) + { + ql->push_back(QuestItem(i)); + ++unlootedCount; + } + } + if (ql->empty()) + { + delete ql; + return NULL; + } + + PlayerFFAItems[player->GetGUIDLow()] = ql; + return ql; +} + +QuestItemList* Loot::FillQuestLoot(Player* player) +{ + if (items.size() == MAX_NR_LOOT_ITEMS) return NULL; + QuestItemList *ql = new QuestItemList(); + + for(uint8 i = 0; i < quest_items.size(); i++) + { + LootItem &item = quest_items[i]; + if(!item.is_looted && item.AllowedForPlayer(player) ) + { + ql->push_back(QuestItem(i)); + + // questitems get blocked when they first apper in a + // player's quest vector + // + // increase once if one looter only, looter-times if free for all + if (item.freeforall || !item.is_blocked) + ++unlootedCount; + + item.is_blocked = true; + + if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS) + break; + } + } + if (ql->empty()) + { + delete ql; + return NULL; + } + + PlayerQuestItems[player->GetGUIDLow()] = ql; + return ql; +} + +QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player) +{ + QuestItemList *ql = new QuestItemList(); + + for(uint8 i = 0; i < items.size(); ++i) + { + LootItem &item = items[i]; + if(!item.is_looted && !item.freeforall && item.conditionId && item.AllowedForPlayer(player)) + { + ql->push_back(QuestItem(i)); + if(!item.is_counted) + { + ++unlootedCount; + item.is_counted=true; + } + } + } + if (ql->empty()) + { + delete ql; + return NULL; + } + + PlayerNonQuestNonFFAConditionalItems[player->GetGUIDLow()] = ql; + return ql; +} + +//=================================================== + +void Loot::NotifyItemRemoved(uint8 lootIndex) +{ + // notify all players that are looting this that the item was removed + // convert the index to the slot the player sees + std::set::iterator i_next; + for(std::set::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) + { + i_next = i; + ++i_next; + if(Player* pl = ObjectAccessor::FindPlayer(*i)) + pl->SendNotifyLootItemRemoved(lootIndex); + else + PlayersLooting.erase(i); + } +} + +void Loot::NotifyMoneyRemoved() +{ + // notify all players that are looting this that the money was removed + std::set::iterator i_next; + for(std::set::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) + { + i_next = i; + ++i_next; + if(Player* pl = ObjectAccessor::FindPlayer(*i)) + pl->SendNotifyLootMoneyRemoved(); + else + PlayersLooting.erase(i); + } +} + +void Loot::NotifyQuestItemRemoved(uint8 questIndex) +{ + // when a free for all questitem is looted + // all players will get notified of it being removed + // (other questitems can be looted by each group member) + // bit inefficient but isnt called often + + std::set::iterator i_next; + for(std::set::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) + { + i_next = i; + ++i_next; + if(Player* pl = ObjectAccessor::FindPlayer(*i)) + { + QuestItemMap::iterator pq = PlayerQuestItems.find(pl->GetGUIDLow()); + if (pq != PlayerQuestItems.end() && pq->second) + { + // find where/if the player has the given item in it's vector + QuestItemList& pql = *pq->second; + + uint8 j; + for (j = 0; j < pql.size(); ++j) + if (pql[j].index == questIndex) + break; + + if (j < pql.size()) + pl->SendNotifyLootItemRemoved(items.size()+j); + } + } + else + PlayersLooting.erase(i); + } +} + +void Loot::generateMoneyLoot( uint32 minAmount, uint32 maxAmount ) +{ + if (maxAmount > 0) + { + if (maxAmount <= minAmount) + gold = uint32(maxAmount * sWorld.getRate(RATE_DROP_MONEY)); + else if ((maxAmount - minAmount) < 32700) + gold = uint32(urand(minAmount, maxAmount) * sWorld.getRate(RATE_DROP_MONEY)); + else + gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld.getRate(RATE_DROP_MONEY)) << 8; + } +} + +LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qitem, QuestItem **ffaitem, QuestItem **conditem) +{ + LootItem* item = NULL; + bool is_looted = true; + if (lootSlot >= items.size()) + { + uint32 questSlot = lootSlot - items.size(); + QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUIDLow()); + if (itr != PlayerQuestItems.end() && questSlot < itr->second->size()) + { + QuestItem *qitem2 = &itr->second->at(questSlot); + if(qitem) + *qitem = qitem2; + item = &quest_items[qitem2->index]; + is_looted = qitem2->is_looted; + } + } + else + { + item = &items[lootSlot]; + is_looted = item->is_looted; + if(item->freeforall) + { + QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUIDLow()); + if (itr != PlayerFFAItems.end()) + { + for(QuestItemList::iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) + if(iter->index==lootSlot) + { + QuestItem *ffaitem2 = (QuestItem*)&(*iter); + if(ffaitem) + *ffaitem = ffaitem2; + is_looted = ffaitem2->is_looted; + break; + } + } + } + else if(item->conditionId) + { + QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow()); + if (itr != PlayerNonQuestNonFFAConditionalItems.end()) + { + for(QuestItemList::iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) + { + if(iter->index==lootSlot) + { + QuestItem *conditem2 = (QuestItem*)&(*iter); + if(conditem) + *conditem = conditem2; + is_looted = conditem2->is_looted; + break; + } + } + } + } + } + + if(is_looted) + return NULL; + + return item; +} + +ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li) +{ + b << uint32(li.itemid); + b << uint32(li.count); // nr of items of this type + b << uint32(objmgr.GetItemPrototype(li.itemid)->DisplayInfoID); + b << uint32(li.randomSuffix); + b << uint32(li.randomPropertyId); + //b << uint8(0); // slot type - will send after this function call + return b; +} + +ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) +{ + Loot &l = lv.loot; + + uint8 itemsShown = 0; + + //gold + b << uint32(lv.permission!=NONE_PERMISSION ? l.gold : 0); + + size_t count_pos = b.wpos(); // pos of item count byte + b << uint8(0); // item count placeholder + + switch (lv.permission) + { + case GROUP_PERMISSION: + { + // You are not the items proprietary, so you can only see + // blocked rolled items and quest items, and !ffa items + for (uint8 i = 0; i < l.items.size(); ++i) + { + if (!l.items[i].is_looted && !l.items[i].freeforall && !l.items[i].conditionId && l.items[i].AllowedForPlayer(lv.viewer)) + { + uint8 slot_type = (l.items[i].is_blocked || l.items[i].is_underthreshold) ? 0 : 1; + + b << uint8(i) << l.items[i]; //send the index and the item if it's not looted, and blocked or under threshold, free for all items will be sent later, only one-player loots here + b << uint8(slot_type); // 0 - get 1 - look only + ++itemsShown; + } + } + break; + } + case ALL_PERMISSION: + case MASTER_PERMISSION: + { + uint8 slot_type = (lv.permission==MASTER_PERMISSION) ? 2 : 0; + for (uint8 i = 0; i < l.items.size(); ++i) + { + if (!l.items[i].is_looted && !l.items[i].freeforall && !l.items[i].conditionId && l.items[i].AllowedForPlayer(lv.viewer)) + { + b << uint8(i) << l.items[i]; //only send one-player loot items now, free for all will be sent later + b << uint8(slot_type); // 0 - get 2 - master selection + ++itemsShown; + } + } + break; + } + case NONE_PERMISSION: + default: + return b; // nothing output more + } + + if (lv.qlist) + { + for (QuestItemList::iterator qi = lv.qlist->begin() ; qi != lv.qlist->end(); ++qi) + { + LootItem &item = l.quest_items[qi->index]; + if (!qi->is_looted && !item.is_looted) + { + b << uint8(l.items.size() + (qi - lv.qlist->begin())); + b << item; + b << uint8(0); // allow loot + ++itemsShown; + } + } + } + + if (lv.ffalist) + { + for (QuestItemList::iterator fi = lv.ffalist->begin() ; fi != lv.ffalist->end(); ++fi) + { + LootItem &item = l.items[fi->index]; + if (!fi->is_looted && !item.is_looted) + { + b << uint8(fi->index) << item; + b << uint8(0); // allow loot + ++itemsShown; + } + } + } + + if (lv.conditionallist) + { + for (QuestItemList::iterator ci = lv.conditionallist->begin() ; ci != lv.conditionallist->end(); ++ci) + { + LootItem &item = l.items[ci->index]; + if (!ci->is_looted && !item.is_looted) + { + b << uint8(ci->index) << item; + b << uint8(0); // allow loot + ++itemsShown; + } + } + } + + //update number of items shown + b.put(count_pos,itemsShown); + + return b; +} + +// +// --------- LootTemplate::LootGroup --------- +// + +// Adds an entry to the group (at loading stage) +void LootTemplate::LootGroup::AddEntry(LootStoreItem& item) +{ + if (item.chance != 0) + ExplicitlyChanced.push_back(item); + else + EqualChanced.push_back(item); +} + +// Rolls an item from the group, returns NULL if all miss their chances +LootStoreItem const * LootTemplate::LootGroup::Roll() const +{ + if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked + { + float Roll = rand_chance(); + + for (uint32 i=0; i=100.f) + return &ExplicitlyChanced[i]; + + ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid); + float qualityMultiplier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; + Roll -= ExplicitlyChanced[i].chance * qualityMultiplier; + if (Roll < 0) + return &ExplicitlyChanced[i]; + } + } + if (!EqualChanced.empty()) // If nothing selected yet - an item is taken from equal-chanced part + return &EqualChanced[irand(0, EqualChanced.size()-1)]; + + return NULL; // Empty drop from the group +} + +// True if group includes at least 1 quest drop entry +bool LootTemplate::LootGroup::HasQuestDrop() const +{ + for (LootStoreItemList::const_iterator i=ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) + if (i->needs_quest) + return true; + for (LootStoreItemList::const_iterator i=EqualChanced.begin(); i != EqualChanced.end(); ++i) + if (i->needs_quest) + return true; + return false; +} + +// True if group includes at least 1 quest drop entry for active quests of the player +bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const +{ + for (LootStoreItemList::const_iterator i=ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) + if (player->HasQuestForItem(i->itemid)) + return true; + for (LootStoreItemList::const_iterator i=EqualChanced.begin(); i != EqualChanced.end(); ++i) + if (player->HasQuestForItem(i->itemid)) + return true; + return false; +} + +// Rolls an item from the group (if any takes its chance) and adds the item to the loot +void LootTemplate::LootGroup::Process(Loot& loot) const +{ + LootStoreItem const * item = Roll(); + if (item != NULL) + loot.AddItem(*item); +} + +// Overall chance for the group without equal chanced items +float LootTemplate::LootGroup::RawTotalChance() const +{ + float result = 0; + + for (LootStoreItemList::const_iterator i=ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) + if ( !i->needs_quest ) + result += i->chance; + + return result; +} + +// Overall chance for the group +float LootTemplate::LootGroup::TotalChance() const +{ + float result = RawTotalChance(); + + if (!EqualChanced.empty() && result < 100.0f) + return 100.0f; + + return result; +} + +void LootTemplate::LootGroup::Verify(LootStore const& lootstore, uint32 id, uint32 group_id) const +{ + float chance = RawTotalChance(); + if (chance > 101.0f) // TODO: replace with 100% when DBs will be ready + { + sLog.outErrorDb("Table '%s' entry %u group %d has total chance > 100%% (%f)", lootstore.GetName(), id, group_id, chance); + } + + if(chance >= 100.0f && !EqualChanced.empty()) + { + sLog.outErrorDb("Table '%s' entry %u group %d has items with chance=0%% but group total chance >= 100%% (%f)", lootstore.GetName(), id, group_id, chance); + } +} + +void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const +{ + for (LootStoreItemList::const_iterator ieItr=ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr) + { + if(ieItr->mincountOrRef < 0) + { + if(!LootTemplates_Reference.GetLootFor(-ieItr->mincountOrRef)) + LootTemplates_Reference.ReportNotExistedId(-ieItr->mincountOrRef); + else if(ref_set) + ref_set->erase(-ieItr->mincountOrRef); + } + } + + for (LootStoreItemList::const_iterator ieItr=EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr) + { + if(ieItr->mincountOrRef < 0) + { + if(!LootTemplates_Reference.GetLootFor(-ieItr->mincountOrRef)) + LootTemplates_Reference.ReportNotExistedId(-ieItr->mincountOrRef); + else if(ref_set) + ref_set->erase(-ieItr->mincountOrRef); + } + } +} + +// +// --------- LootTemplate --------- +// + +// Adds an entry to the group (at loading stage) +void LootTemplate::AddEntry(LootStoreItem& item) +{ + if (item.group > 0 && item.mincountOrRef > 0) // Group + { + if (item.group >= Groups.size()) + Groups.resize(item.group); // Adds new group the the loot template if needed + Groups[item.group-1].AddEntry(item); // Adds new entry to the group + } + else // Non-grouped entries and references are stored together + Entries.push_back(item); +} + +// Rolls for every item in the template and adds the rolled items the the loot +void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) const +{ + if (groupId) // Group reference uses own processing of the group + { + if (groupId > Groups.size()) + return; // Error message already printed at loading stage + + Groups[groupId-1].Process(loot); + return; + } + + // Rolling non-grouped items + for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; i++ ) + { + if ( !i->Roll() ) + continue; // Bad luck for the entry + + if (i->mincountOrRef < 0) // References processing + { + LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-i->mincountOrRef); + + if(!Referenced) + continue; // Error message already printed at loading stage + + for (uint32 loop=0; loop < i->maxcount; ++loop )// Ref multiplicator + Referenced->Process(loot, store, i->group); // Ref processing + } + else // Plain entries (not a reference, not grouped) + loot.AddItem(*i); // Chance is already checked, just add + } + + // Now processing groups + for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; i++ ) + i->Process(loot); +} + +// True if template includes at least 1 quest drop entry +bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) const +{ + if (groupId) // Group reference + { + if (groupId > Groups.size()) + return false; // Error message [should be] already printed at loading stage + return Groups[groupId-1].HasQuestDrop(); + } + + for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i ) + { + if (i->mincountOrRef < 0) // References + { + LootTemplateMap::const_iterator Referenced = store.find(-i->mincountOrRef); + if( Referenced ==store.end() ) + continue; // Error message [should be] already printed at loading stage + if (Referenced->second->HasQuestDrop(store, i->group) ) + return true; + } + else if ( i->needs_quest ) + return true; // quest drop found + } + + // Now processing groups + for (LootGroups::const_iterator i = Groups.begin() ; i != Groups.end() ; i++ ) + if (i->HasQuestDrop()) + return true; + + return false; +} + +// True if template includes at least 1 quest drop for an active quest of the player +bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player const* player, uint8 groupId) const +{ + if (groupId) // Group reference + { + if (groupId > Groups.size()) + return false; // Error message already printed at loading stage + return Groups[groupId-1].HasQuestDropForPlayer(player); + } + + // Checking non-grouped entries + for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; i++ ) + { + if (i->mincountOrRef < 0) // References processing + { + LootTemplateMap::const_iterator Referenced = store.find(-i->mincountOrRef); + if (Referenced == store.end() ) + continue; // Error message already printed at loading stage + if (Referenced->second->HasQuestDropForPlayer(store, player, i->group) ) + return true; + } + else if ( player->HasQuestForItem(i->itemid) ) + return true; // active quest drop found + } + + // Now checking groups + for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i ) + if (i->HasQuestDrop()) + return true; + + return false; +} + +// Checks integrity of the template +void LootTemplate::Verify(LootStore const& lootstore, uint32 id) const +{ + // Checking group chances + for (uint32 i=0; i < Groups.size(); ++i) + Groups[i].Verify(lootstore,id,i+1); + + // TODO: References validity checks +} + +void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const +{ + for(LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr) + { + if(ieItr->mincountOrRef < 0) + { + if(!LootTemplates_Reference.GetLootFor(-ieItr->mincountOrRef)) + LootTemplates_Reference.ReportNotExistedId(-ieItr->mincountOrRef); + else if(ref_set) + ref_set->erase(-ieItr->mincountOrRef); + } + } + + for(LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr) + grItr->CheckLootRefs(store,ref_set); +} + +void LoadLootTemplates_Creature() +{ + LootIdSet ids_set, ids_setUsed; + LootTemplates_Creature.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i ) + { + if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(i)) + { + if(uint32 lootid = cInfo->lootid) + { + if(!ids_set.count(lootid)) + LootTemplates_Creature.ReportNotExistedId(lootid); + else + ids_setUsed.insert(lootid); + } + } + } + for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) + ids_set.erase(*itr); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Creature.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Disenchant() +{ + LootIdSet ids_set, ids_setUsed; + LootTemplates_Disenchant.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) + { + if(ItemPrototype const* proto = sItemStorage.LookupEntry(i)) + { + if(uint32 lootid = proto->DisenchantID) + { + if(!ids_set.count(lootid)) + LootTemplates_Disenchant.ReportNotExistedId(lootid); + else + ids_setUsed.insert(lootid); + } + } + } + for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) + ids_set.erase(*itr); + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Disenchant.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Fishing() +{ + LootIdSet ids_set; + LootTemplates_Fishing.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sAreaStore.GetNumRows(); ++i ) + { + if(AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(i)) + if(ids_set.count(areaEntry->ID)) + ids_set.erase(areaEntry->ID); + } + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Fishing.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Gameobject() +{ + LootIdSet ids_set, ids_setUsed; + LootTemplates_Gameobject.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sGOStorage.MaxEntry; ++i ) + { + if(GameObjectInfo const* gInfo = sGOStorage.LookupEntry(i)) + { + if(uint32 lootid = GameObject::GetLootId(gInfo)) + { + if(!ids_set.count(lootid)) + LootTemplates_Gameobject.ReportNotExistedId(lootid); + else + ids_setUsed.insert(lootid); + } + } + } + for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) + ids_set.erase(*itr); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Gameobject.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Item() +{ + LootIdSet ids_set; + LootTemplates_Item.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) + if(ItemPrototype const* proto = sItemStorage.LookupEntry(i)) + if(ids_set.count(proto->ItemId)) + ids_set.erase(proto->ItemId); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Item.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Pickpocketing() +{ + LootIdSet ids_set, ids_setUsed; + LootTemplates_Pickpocketing.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i ) + { + if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(i)) + { + if(uint32 lootid = cInfo->pickpocketLootId) + { + if(!ids_set.count(lootid)) + LootTemplates_Pickpocketing.ReportNotExistedId(lootid); + else + ids_setUsed.insert(lootid); + } + } + } + for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) + ids_set.erase(*itr); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Pickpocketing.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Prospecting() +{ + LootIdSet ids_set; + LootTemplates_Prospecting.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) + if(ItemPrototype const* proto = sItemStorage.LookupEntry(i)) + if(ids_set.count(proto->ItemId)) + ids_set.erase(proto->ItemId); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Prospecting.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_QuestMail() +{ + LootIdSet ids_set; + LootTemplates_QuestMail.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates(); + for(ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr ) + if(ids_set.count(itr->first)) + ids_set.erase(itr->first); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_QuestMail.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Skinning() +{ + LootIdSet ids_set, ids_setUsed; + LootTemplates_Skinning.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i ) + { + if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(i)) + { + if(uint32 lootid = cInfo->SkinLootId) + { + if(!ids_set.count(lootid)) + LootTemplates_Skinning.ReportNotExistedId(lootid); + else + ids_setUsed.insert(lootid); + } + } + } + for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) + ids_set.erase(*itr); + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_Skinning.ReportUnusedIds(ids_set); +} + +void LoadLootTemplates_Reference() +{ + LootIdSet ids_set; + LootTemplates_Reference.LoadAndCollectLootIds(ids_set); + + // check references and remove used + LootTemplates_Creature.CheckLootRefs(&ids_set); + LootTemplates_Fishing.CheckLootRefs(&ids_set); + LootTemplates_Gameobject.CheckLootRefs(&ids_set); + LootTemplates_Item.CheckLootRefs(&ids_set); + LootTemplates_Pickpocketing.CheckLootRefs(&ids_set); + LootTemplates_Skinning.CheckLootRefs(&ids_set); + LootTemplates_Disenchant.CheckLootRefs(&ids_set); + LootTemplates_Prospecting.CheckLootRefs(&ids_set); + LootTemplates_QuestMail.CheckLootRefs(&ids_set); + LootTemplates_Reference.CheckLootRefs(&ids_set); + + // output error for any still listed ids (not referenced from any loot table) + LootTemplates_Reference.ReportUnusedIds(ids_set); +} diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h new file mode 100644 index 000000000..4885dd4fc --- /dev/null +++ b/src/game/LootMgr.h @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_LOOTMGR_H +#define MANGOS_LOOTMGR_H + +#include "ItemEnchantmentMgr.h" +#include "ByteBuffer.h" +#include "Utilities/LinkedReference/RefManager.h" + +#include +#include + +enum RollType +{ + ROLL_PASS = 0, + ROLL_NEED = 1, + ROLL_GREED = 2 +}; + +#define MAX_NR_LOOT_ITEMS 16 +// note: the client cannot show more than 16 items total +#define MAX_NR_QUEST_ITEMS 32 +// unrelated to the number of quest items shown, just for reserve + +enum LootMethod +{ + FREE_FOR_ALL = 0, + ROUND_ROBIN = 1, + MASTER_LOOT = 2, + GROUP_LOOT = 3, + NEED_BEFORE_GREED = 4 +}; + +enum PermissionTypes +{ + ALL_PERMISSION = 0, + GROUP_PERMISSION = 1, + MASTER_PERMISSION = 2, + NONE_PERMISSION = 3 +}; + +class Player; +class LootStore; + +struct LootStoreItem +{ + uint32 itemid; // id of the item + float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs + int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative) + uint8 group :8; + uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative) + uint16 conditionId :16; // additional loot condition Id + bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB) + + // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest) + // displayid is filled in IsValid() which must be called after + LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount) + : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), + group(_group), maxcount(_maxcount), conditionId(_conditionId), + needs_quest(_chanceOrQuestChance < 0) {} + + bool Roll() const; // Checks if the entry takes it's chance (at loot generation) + bool IsValid(LootStore const& store, uint32 entry) const; + // Checks correctness of values +}; + +struct LootItem +{ + uint32 itemid; + uint32 randomSuffix; + int32 randomPropertyId; + uint16 conditionId :16; // allow compiler pack structure + uint8 count : 8; + bool is_looted : 1; + bool is_blocked : 1; + bool freeforall : 1; // free for all + bool is_underthreshold : 1; + bool is_counted : 1; + bool needs_quest : 1; // quest drop + + // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties + // Should be called for non-reference LootStoreItem entries only (mincountOrRef > 0) + explicit LootItem(LootStoreItem const& li); + + // Basic checks for player/item compatibility - if false no chance to see the item in the loot + bool AllowedForPlayer(Player const * player) const; +}; + +struct QuestItem +{ + uint8 index; // position in quest_items; + bool is_looted; + + QuestItem() + : index(0), is_looted(false) {} + + QuestItem(uint8 _index, bool _islooted = false) + : index(_index), is_looted(_islooted) {} +}; + +struct Loot; +class LootTemplate; + +typedef std::vector QuestItemList; +typedef std::map QuestItemMap; +typedef std::vector LootStoreItemList; +typedef HM_NAMESPACE::hash_map LootTemplateMap; + +typedef std::set LootIdSet; + +class LootStore +{ + public: + explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {} + virtual ~LootStore() { Clear(); } + + void Verify() const; + + void LoadAndCollectLootIds(LootIdSet& ids_set); + void CheckLootRefs(LootIdSet* ref_set = NULL) const;// check existence reference and remove it from ref_set + void ReportUnusedIds(LootIdSet const& ids_set) const; + void ReportNotExistedId(uint32 id) const; + + bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); } + bool HaveQuestLootFor(uint32 loot_id) const; + bool HaveQuestLootForPlayer(uint32 loot_id,Player* player) const; + + LootTemplate const* GetLootFor(uint32 loot_id) const; + + char const* GetName() const { return m_name; } + char const* GetEntryName() const { return m_entryName; } + protected: + void LoadLootTable(); + void Clear(); + private: + LootTemplateMap m_LootTemplates; + char const* m_name; + char const* m_entryName; +}; + +class LootTemplate +{ + class LootGroup; // A set of loot definitions for items (refs are not allowed inside) + typedef std::vector LootGroups; + + public: + // Adds an entry to the group (at loading stage) + void AddEntry(LootStoreItem& item); + // Rolls for every item in the template and adds the rolled items the the loot + void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const; + + // True if template includes at least 1 quest drop entry + bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const; + // True if template includes at least 1 quest drop for an active quest of the player + bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const * player, uint8 GroupId = 0) const; + + // Checks integrity of the template + void Verify(LootStore const& store, uint32 Id) const; + void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const; + private: + LootStoreItemList Entries; // not grouped only + LootGroups Groups; // groups have own (optimised) processing, grouped entries go there +}; + +//===================================================== + +class LootValidatorRef : public Reference +{ + public: + LootValidatorRef() {} + void targetObjectDestroyLink() {} + void sourceObjectDestroyLink() {} +}; + +//===================================================== + +class LootValidatorRefManager : public RefManager +{ + public: + typedef LinkedListHead::Iterator< LootValidatorRef > iterator; + + LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager::getFirst(); } + LootValidatorRef* getLast() { return (LootValidatorRef*)RefManager::getLast(); } + + iterator begin() { return iterator(getFirst()); } + iterator end() { return iterator(NULL); } + iterator rbegin() { return iterator(getLast()); } + iterator rend() { return iterator(NULL); } +}; + +//===================================================== + +struct Loot +{ + QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; } + QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; } + QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; } + + QuestItemList* FillFFALoot(Player* player); + QuestItemList* FillQuestLoot(Player* player); + QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player); + + std::vector items; + std::vector quest_items; + uint32 gold; + uint8 unlootedCount; + + Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0) {} + ~Loot() { clear(); } + + // if loot becomes invalid this reference is used to inform the listener + void addLootValidatorRef(LootValidatorRef* pLootValidatorRef) + { + i_LootValidatorRefManager.insertFirst(pLootValidatorRef); + } + + // void clear(); + void clear() + { + items.clear(); gold = 0; PlayersLooting.clear(); + for (QuestItemMap::iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr) + delete itr->second; + for (QuestItemMap::iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr) + delete itr->second; + for (QuestItemMap::iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr) + delete itr->second; + + PlayerQuestItems.clear(); + PlayerFFAItems.clear(); + PlayerNonQuestNonFFAConditionalItems.clear(); + + items.clear(); + quest_items.clear(); + gold = 0; + unlootedCount = 0; + i_LootValidatorRefManager.clearReferences(); + } + + bool empty() const { return items.empty() && gold == 0; } + bool isLooted() const { return gold == 0 && unlootedCount == 0; } + + void NotifyItemRemoved(uint8 lootIndex); + void NotifyQuestItemRemoved(uint8 questIndex); + void NotifyMoneyRemoved(); + void AddLooter(uint64 GUID) { PlayersLooting.insert(GUID); } + void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); } + + void generateMoneyLoot(uint32 minAmount, uint32 maxAmount); + void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner); + + // Inserts the item into the loot (called by LootTemplate processors) + void AddItem(LootStoreItem const & item); + + LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL); + private: + std::set PlayersLooting; + QuestItemMap PlayerQuestItems; + QuestItemMap PlayerFFAItems; + QuestItemMap PlayerNonQuestNonFFAConditionalItems; + + // All rolls are registered here. They need to know, when the loot is not valid anymore + LootValidatorRefManager i_LootValidatorRefManager; + +}; + +struct LootView +{ + Loot &loot; + QuestItemList *qlist; + QuestItemList *ffalist; + QuestItemList *conditionallist; + Player *viewer; + PermissionTypes permission; + LootView(Loot &_loot, QuestItemList *_qlist, QuestItemList *_ffalist, QuestItemList *_conditionallist, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION) + : loot(_loot), qlist(_qlist), ffalist(_ffalist), conditionallist(_conditionallist), viewer(_viewer), permission(_permission) {} +}; + +extern LootStore LootTemplates_Creature; +extern LootStore LootTemplates_Fishing; +extern LootStore LootTemplates_Gameobject; +extern LootStore LootTemplates_Item; +extern LootStore LootTemplates_Pickpocketing; +extern LootStore LootTemplates_Skinning; +extern LootStore LootTemplates_Disenchant; +extern LootStore LootTemplates_Prospecting; +extern LootStore LootTemplates_QuestMail; + +void LoadLootTemplates_Creature(); +void LoadLootTemplates_Fishing(); +void LoadLootTemplates_Gameobject(); +void LoadLootTemplates_Item(); +void LoadLootTemplates_Pickpocketing(); +void LoadLootTemplates_Skinning(); +void LoadLootTemplates_Disenchant(); +void LoadLootTemplates_Prospecting(); +void LoadLootTemplates_QuestMail(); +void LoadLootTemplates_Reference(); + +inline void LoadLootTables() +{ + LoadLootTemplates_Creature(); + LoadLootTemplates_Fishing(); + LoadLootTemplates_Gameobject(); + LoadLootTemplates_Item(); + LoadLootTemplates_Pickpocketing(); + LoadLootTemplates_Skinning(); + LoadLootTemplates_Disenchant(); + LoadLootTemplates_Prospecting(); + LoadLootTemplates_QuestMail(); + LoadLootTemplates_Reference(); +} + +ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li); +ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); +#endif diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp new file mode 100644 index 000000000..ee9ad968b --- /dev/null +++ b/src/game/Mail.cpp @@ -0,0 +1,838 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Mail.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "UpdateMask.h" +#include "Unit.h" +#include "Language.h" +#include "Database/DBCStores.h" + +void MailItem::deleteItem( bool inDB ) +{ + if(item) + { + if(inDB) + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow()); + + delete item; + item=NULL; + } +} + +void WorldSession::HandleSendMail(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+1+1+1+4+4+1+4+4+8+1); + + uint64 mailbox, unk3; + std::string receiver, subject, body; + uint32 unk1, unk2, money, COD; + uint8 unk4; + recv_data >> mailbox; + recv_data >> receiver; + + // recheck + CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+1+1+4+4+1+4+4+8+1); + + recv_data >> subject; + + // recheck + CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+(subject.size()+1)+1+4+4+1+4+4+8+1); + + recv_data >> body; + + // recheck + CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+(subject.size()+1)+(body.size()+1)+4+4+1+4+4+8+1); + + recv_data >> unk1; // stationery? + recv_data >> unk2; // 0x00000000 + + MailItemsInfo mi; + + uint8 items_count; + recv_data >> items_count; // attached items count + + if(items_count > 12) // client limit + return; + + // recheck + CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+(subject.size()+1)+(body.size()+1)+4+4+1+items_count*(1+8)+4+4+8+1); + + if(items_count) + { + for(uint8 i = 0; i < items_count; ++i) + { + uint8 item_slot; + uint64 item_guid; + recv_data >> item_slot; + recv_data >> item_guid; + mi.AddItem(GUID_LOPART(item_guid), item_slot); + } + } + + recv_data >> money >> COD; // money and cod + recv_data >> unk3; // const 0 + recv_data >> unk4; // const 0 + + items_count = mi.size(); // this is the real size after the duplicates have been removed + + if (receiver.empty()) + return; + + Player* pl = _player; + + uint64 rc = 0; + if(normalizePlayerName(receiver)) + rc = objmgr.GetPlayerGUIDByName(receiver); + + if (!rc) + { + sLog.outDetail("Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", + pl->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + pl->SendMailResult(0, 0, MAIL_ERR_RECIPIENT_NOT_FOUND); + return; + } + + sLog.outDetail("Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + + if(pl->GetGUID() == rc) + { + pl->SendMailResult(0, 0, MAIL_ERR_CANNOT_SEND_TO_SELF); + return; + } + + uint32 reqmoney = money + 30; + if (items_count) + reqmoney = money + (30 * items_count); + + if (pl->GetMoney() < reqmoney) + { + pl->SendMailResult(0, 0, MAIL_ERR_NOT_ENOUGH_MONEY); + return; + } + + Player *receive = objmgr.GetPlayer(rc); + + uint32 rc_team = 0; + uint8 mails_count = 0; //do not allow to send to one player more than 100 mails + + if(receive) + { + rc_team = receive->GetTeam(); + mails_count = receive->GetMailSize(); + } + else + { + rc_team = objmgr.GetPlayerTeamByGUID(rc); + QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc)); + if(result) + { + Field *fields = result->Fetch(); + mails_count = fields[0].GetUInt32(); + delete result; + } + } + //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. + if (mails_count > 100) + { + pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR); + return; + } + // test the receiver's Faction... + if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER) + { + pl->SendMailResult(0, 0, MAIL_ERR_NOT_YOUR_TEAM); + return; + } + + if (items_count) + { + for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter) + { + MailItem& mailItem = mailItemIter->second; + + if(!mailItem.item_guidlow) + { + pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR); + return; + } + + mailItem.item = pl->GetItemByGuid(MAKE_NEW_GUID(mailItem.item_guidlow, 0, HIGHGUID_ITEM)); + // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) + if(!mailItem.item || !mailItem.item->CanBeTraded()) + { + pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR); + return; + } + if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION)) + { + pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR); + return; + } + } + } + pl->SendMailResult(0, 0, MAIL_OK); + + uint32 itemTextId = 0; + if (!body.empty()) + { + itemTextId = objmgr.CreateItemText( body ); + } + + pl->ModifyMoney( -int32(reqmoney) ); + + bool needItemDelay = false; + + if(items_count > 0 || money > 0) + { + uint32 rc_account = 0; + if(receive) + rc_account = receive->GetSession()->GetAccountId(); + else + rc_account = objmgr.GetPlayerAccountIdByGUID(rc); + + if (items_count > 0) + { + for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter) + { + MailItem& mailItem = mailItemIter->second; + if(!mailItem.item) + continue; + + mailItem.item_template = mailItem.item ? mailItem.item->GetEntry() : 0; + + if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + { + sLog.outCommand("GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", + GetPlayerName(), GetAccountId(), mailItem.item->GetProto()->Name1, mailItem.item->GetEntry(), mailItem.item->GetCount(), receiver.c_str(), rc_account); + } + + pl->MoveItemFromInventory(mailItem.item->GetBagSlot(), mailItem.item->GetSlot(), true); + CharacterDatabase.BeginTransaction(); + mailItem.item->DeleteFromInventoryDB(); //deletes item from character's inventory + mailItem.item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone + // owner in data will set at mail receive and item extracting + CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), mailItem.item->GetGUIDLow()); + CharacterDatabase.CommitTransaction(); + } + + // if item send to character at another account, then apply item delivery delay + needItemDelay = pl->GetSession()->GetAccountId() != rc_account; + } + + if(money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand("GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", + GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account); + } + } + + // If theres is an item, there is a one hour delivery delay if sent to another account's character. + uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; + + // will delete item or place to receiver mail list + WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, pl->GetGUIDLow(), GUID_LOPART(rc), subject, itemTextId, &mi, money, COD, MAIL_CHECK_MASK_NONE, deliver_delay); + + CharacterDatabase.BeginTransaction(); + pl->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); +} + +//called when mail is read +void WorldSession::HandleMarkAsRead(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 mailbox; + uint32 mailId; + recv_data >> mailbox; + recv_data >> mailId; + Player *pl = _player; + Mail *m = pl->GetMail(mailId); + if (m) + { + if (pl->unReadMails) + --pl->unReadMails; + m->checked = m->checked | MAIL_CHECK_MASK_READ; + // m->expire_time = time(NULL) + (30 * DAY); // Expire time do not change at reading mail + pl->m_mailsUpdated = true; + m->state = MAIL_STATE_CHANGED; + } +} + +//called when client deletes mail +void WorldSession::HandleMailDelete(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 mailbox; + uint32 mailId; + recv_data >> mailbox; + recv_data >> mailId; + Player* pl = _player; + pl->m_mailsUpdated = true; + Mail *m = pl->GetMail(mailId); + if(m) + m->state = MAIL_STATE_DELETED; + pl->SendMailResult(mailId, MAIL_DELETED, 0); +} + +void WorldSession::HandleReturnToSender(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 mailbox; + uint32 mailId; + recv_data >> mailbox; + recv_data >> mailId; + Player *pl = _player; + Mail *m = pl->GetMail(mailId); + if(!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + { + pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_ERR_INTERNAL_ERROR); + return; + } + //we can return mail now + //so firstly delete the old one + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mailId); + // needed? + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mailId); + CharacterDatabase.CommitTransaction(); + pl->RemoveMail(mailId); + + MailItemsInfo mi; + + if(m->HasItems()) + { + for(std::vector::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2) + { + Item *item = pl->GetMItem(itr2->item_guid); + if(item) + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + else + { + //WTF? + } + + pl->RemoveMItem(itr2->item_guid); + } + } + + SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, 0, m->mailTemplateId); + + delete m; //we can deallocate old mail + pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, 0); +} + +void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, std::string subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint32 COD, uint16 mailTemplateId ) +{ + if(messageType != MAIL_NORMAL) // return only to players + { + mi->deleteIncludedItems(true); + return; + } + + Player *receiver = objmgr.GetPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER)); + + uint32 rc_account = 0; + if(!receiver) + rc_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER)); + + if(!receiver && !rc_account) // sender not exist + { + mi->deleteIncludedItems(true); + return; + } + + // preper mail and send in other case + bool needItemDelay = false; + + if(mi && !mi->empty()) + { + // if item send to character at another account, then apply item delivery delay + needItemDelay = sender_acc != rc_account; + + // set owner to new receiver (to prevent delete item with sender char deleting) + CharacterDatabase.BeginTransaction(); + for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter) + { + MailItem& mailItem = mailItemIter->second; + mailItem.item->SaveToDB(); // item not in inventory and can be save standalone + // owner in data will set at mail receive and item extracting + CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, mailItem.item->GetGUIDLow()); + } + CharacterDatabase.CommitTransaction(); + } + + // If theres is an item, there is a one hour delivery delay. + uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; + + // will delete item or place to receiver mail list + WorldSession::SendMailTo(receiver, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, sender_guid, receiver_guid, subject, itemTextId, mi, money, 0, MAIL_CHECK_MASK_RETURNED,deliver_delay,mailTemplateId); +} + +//called when player takes item attached in mail +void WorldSession::HandleTakeItem(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + uint64 mailbox; + uint32 mailId; + uint32 itemId; + recv_data >> mailbox; + recv_data >> mailId; + recv_data >> itemId; // item guid low? + Player* pl = _player; + + Mail* m = pl->GetMail(mailId); + if(!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + { + pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_INTERNAL_ERROR); + return; + } + + // prevent cheating with skip client money check + if(pl->GetMoney() < m->COD) + { + pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_NOT_ENOUGH_MONEY); + return; + } + + Item *it = pl->GetMItem(itemId); + + ItemPosCountVec dest; + uint8 msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, dest, it, false ); + if( msg == EQUIP_ERR_OK ) + { + m->RemoveItem(itemId); + m->removedItems.push_back(itemId); + + if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail + { + uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); + Player *receive = objmgr.GetPlayer(sender_guid); + + uint32 sender_accId = 0; + + if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + { + std::string sender_name; + if(receive) + { + sender_accId = receive->GetSession()->GetAccountId(); + sender_name = receive->GetName(); + } + else + { + // can be calculated early + sender_accId = objmgr.GetPlayerAccountIdByGUID(sender_guid); + + if(!objmgr.GetPlayerNameByGUID(sender_guid,sender_name)) + sender_name = objmgr.GetMangosStringForDBCLocale(LANG_UNKNOWN); + } + sLog.outCommand("GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", + GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount(),m->COD,sender_name.c_str(),sender_accId); + } + else if(!receive) + sender_accId = objmgr.GetPlayerAccountIdByGUID(sender_guid); + + // check player existanse + if(receive || sender_accId) + { + WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, m->receiver, m->sender, m->subject, 0, NULL, m->COD, 0, MAIL_CHECK_MASK_COD_PAYMENT); + } + + pl->ModifyMoney( -int32(m->COD) ); + } + m->COD = 0; + m->state = MAIL_STATE_CHANGED; + pl->m_mailsUpdated = true; + pl->RemoveMItem(it->GetGUIDLow()); + + uint32 count = it->GetCount(); // save counts before store and possible merge with deleting + pl->MoveItemToInventory(dest,it,true); + + CharacterDatabase.BeginTransaction(); + pl->SaveInventoryAndGoldToDB(); + pl->_SaveMail(); + CharacterDatabase.CommitTransaction(); + + pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count); + } + else + pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_BAG_FULL, msg); +} + +void WorldSession::HandleTakeMoney(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 mailbox; + uint32 mailId; + recv_data >> mailbox; + recv_data >> mailId; + Player *pl = _player; + + Mail* m = pl->GetMail(mailId); + if(!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + { + pl->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_ERR_INTERNAL_ERROR); + return; + } + + pl->SendMailResult(mailId, MAIL_MONEY_TAKEN, 0); + + pl->ModifyMoney(m->money); + m->money = 0; + m->state = MAIL_STATE_CHANGED; + pl->m_mailsUpdated = true; + + // save money and mail to prevent cheating + CharacterDatabase.BeginTransaction(); + pl->SetUInt32ValueInDB(PLAYER_FIELD_COINAGE,pl->GetMoney(),pl->GetGUID()); + pl->_SaveMail(); + CharacterDatabase.CommitTransaction(); +} + +//called when player lists his received mails +void WorldSession::HandleGetMail(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 mailbox; + recv_data >> mailbox; + + //GameObject* obj = ObjectAccessor::GetGameObject(_player, mailbox); + //if(!obj || !obj->IsMailBox()) + // return; + + Player* pl = _player; + + //load players mails, and mailed items + if(!pl->m_mailsLoaded) + pl ->_LoadMail(); + + // client can't work with packets > max int16 value + const uint32 maxPacketSize = 32767; + + uint32 mails_count = 0; // real send to client mails amount + + WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size + data << uint8(0); // mail's count + time_t cur_time = time(NULL); + + for(PlayerMails::iterator itr = pl->GetmailBegin(); itr != pl->GetmailEnd(); ++itr) + { + // skip deleted or not delivered (deliver delay not expired) mails + if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) + continue; + + uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12) + + size_t next_mail_size = 2+4+1+8+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+6*3*4+4+4+1+4+4+4); + + if(data.wpos()+next_mail_size > maxPacketSize) + break; + + data << (uint16) 0x0040; // unknown 2.3.0, different values + data << (uint32) (*itr)->messageID; // Message ID + data << (uint8) (*itr)->messageType; // Message Type + + switch((*itr)->messageType) + { + case MAIL_NORMAL: // sender guid + data << uint64(MAKE_NEW_GUID((*itr)->sender, 0, HIGHGUID_PLAYER)); + break; + case MAIL_CREATURE: + case MAIL_GAMEOBJECT: + case MAIL_AUCTION: + data << (uint32) (*itr)->sender; // creature/gameobject entry, auction id + break; + case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI + break; + } + + data << (uint32) (*itr)->COD; // COD + data << (uint32) (*itr)->itemTextId; // sure about this + data << (uint32) 0; // unknown + data << (uint32) (*itr)->stationery; // stationery (Stationery.dbc) + data << (uint32) (*itr)->money; // Gold + data << (uint32) 0x04; // unknown, 0x4 - auction, 0x10 - normal + // Time + data << (float) ((*itr)->expire_time-time(NULL))/DAY; + data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc) + data << (*itr)->subject; // Subject string - once 00, when mail type = 3 + + data << (uint8) item_count; + + for(uint8 i = 0; i < item_count; ++i) + { + Item *item = pl->GetMItem((*itr)->items[i].item_guid); + // item index (0-6?) + data << (uint8) i; + // item guid low? + data << (uint32) (item ? item->GetGUIDLow() : 0); + // entry + data << (uint32) (item ? item->GetEntry() : 0); + for(uint8 j = 0; j < 6; ++j) + { + // unsure + data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); + // unsure + data << (uint32) (item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0); + // unsure + data << (uint32) (item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0); + } + // can be negative + data << (uint32) (item ? item->GetItemRandomPropertyId() : 0); + // unk + data << (uint32) (item ? item->GetItemSuffixFactor() : 0); + // stack count + data << (uint8) (item ? item->GetCount() : 0); + // charges + data << (uint32) (item ? item->GetSpellCharges() : 0); + // durability + data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); + // durability + data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); + } + + mails_count += 1; + } + + data.put(0, mails_count); // set real send mails to client + SendPacket(&data); + + // recalculate m_nextMailDelivereTime and unReadMails + _player->UpdateNextMailTimeAndUnreads(); +} + +///this function is called when client needs mail message body, or when player clicks on item which has ITEM_FIELD_ITEM_TEXT_ID > 0 +void WorldSession::HandleItemTextQuery(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+4+4); + + uint32 itemTextId; + uint32 mailId; //this value can be item id in bag, but it is also mail id + uint32 unk; //maybe something like state - 0x70000000 + + recv_data >> itemTextId >> mailId >> unk; + + //some check needed, if player has item with guid mailId, or has mail with id mailId + + sLog.outDebug("CMSG_ITEM_TEXT_QUERY itemguid: %u, mailId: %u, unk: %u", itemTextId, mailId, unk); + + WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10));// guess size + data << itemTextId; + data << objmgr.GetItemText( itemTextId ); + SendPacket(&data); +} + +//used when player copies mail body to his inventory +void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 mailbox; + uint32 mailId; + + recv_data >> mailbox >> mailId; + + Player *pl = _player; + + Mail* m = pl->GetMail(mailId); + if(!m || !m->itemTextId || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + { + pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); + return; + } + + Item *bodyItem = new Item; // This is not bag and then can be used new Item. + if(!bodyItem->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM), MAIL_BODY_ITEM_TEMPLATE, pl)) + { + delete bodyItem; + return; + } + + bodyItem->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID , m->itemTextId ); + bodyItem->SetUInt32Value( ITEM_FIELD_CREATOR, m->sender); + + sLog.outDetail("HandleMailCreateTextItem mailid=%u",mailId); + + ItemPosCountVec dest; + uint8 msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, dest, bodyItem, false ); + if( msg == EQUIP_ERR_OK ) + { + m->itemTextId = 0; + m->state = MAIL_STATE_CHANGED; + pl->m_mailsUpdated = true; + + pl->StoreItem(dest, bodyItem, true); + //bodyItem->SetState(ITEM_NEW, pl); is set automatically + pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, 0); + } + else + { + pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_BAG_FULL, msg); + delete bodyItem; + } +} + +//TODO Fix me! ... this void has probably bad condition, but good data are sent +void WorldSession::HandleMsgQueryNextMailtime(WorldPacket & /*recv_data*/ ) +{ + WorldPacket data(MSG_QUERY_NEXT_MAIL_TIME, 8); + + if(!_player->m_mailsLoaded) + _player->_LoadMail(); + + if( _player->unReadMails > 0 ) + { + data << (uint32) 0; // float + data << (uint32) 0; // count + uint32 count = 0; + for(PlayerMails::iterator itr = _player->GetmailBegin(); itr != _player->GetmailEnd(); ++itr) + { + Mail *m = (*itr); + // not checked yet, already must be delivered + if((m->checked & MAIL_CHECK_MASK_READ)==0 && (m->deliver_time <= time(NULL))) + { + ++count; + + if(count > 2) + { + count = 2; + break; + } + + data << (uint64) m->sender; // sender guid + + switch(m->messageType) + { + case MAIL_AUCTION: + data << (uint32) 2; + data << (uint32) 2; + data << (uint32) m->stationery; + break; + default: + data << (uint32) 0; + data << (uint32) 0; + data << (uint32) m->stationery; + break; + } + data << (uint32) 0xC6000000; // float unk, time or something + } + } + data.put(4, count); + } + else + { + data << (uint32) 0xC7A8C000; + data << (uint32) 0x00000000; + } + SendPacket(&data); +} + +void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 receiver_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay, uint16 mailTemplateId) +{ + uint32 mailId = objmgr.GenerateMailID(); + + time_t deliver_time = time(NULL) + deliver_delay; + + //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour + uint32 expire_delay; + if(messageType == MAIL_AUCTION && !mi && !money) // auction mail without any items and money + expire_delay = HOUR; + else + expire_delay = (COD > 0) ? 3*DAY : 30*DAY; + + time_t expire_time = deliver_time + expire_delay; + + if(mailTemplateId && !sMailTemplateStore.LookupEntry(mailTemplateId)) + { + sLog.outError( "WorldSession::SendMailTo - Mail have not existed MailTemplateId (%u), remove at send", mailTemplateId); + mailTemplateId = 0; + } + + if(receiver) + { + receiver->AddNewMailDeliverTime(deliver_time); + + if ( receiver->IsMailsLoaded() ) + { + Mail * m = new Mail; + m->messageID = mailId; + m->messageType = messageType; + m->stationery = stationery; + m->mailTemplateId = mailTemplateId; + m->sender = sender_guidlow_or_entry; + m->receiver = receiver->GetGUIDLow(); + m->subject = subject; + m->itemTextId = itemTextId; + + if(mi) + m->AddAllItems(*mi); + + m->expire_time = expire_time; + m->deliver_time = deliver_time; + m->money = money; + m->COD = COD; + m->checked = checked; + m->state = MAIL_STATE_UNCHANGED; + + receiver->AddMail(m); //to insert new mail to beginning of maillist + + if(mi) + { + for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter) + { + MailItem& mailItem = mailItemIter->second; + if(mailItem.item) + receiver->AddMItem(mailItem.item); + } + } + } + else if(mi) + mi->deleteIncludedItems(); + } + else if(mi) + mi->deleteIncludedItems(); + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.escape_string(subject); + CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) " + "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" I64FMTD "','" I64FMTD "', '%u', '%u', '%d')", + mailId, messageType, stationery, mailTemplateId, sender_guidlow_or_entry, receiver_guidlow, subject.c_str(), itemTextId, (mi && !mi->empty() ? 1 : 0), (uint64)expire_time, (uint64)deliver_time, money, COD, checked); + + if(mi) + { + for(MailItemMap::const_iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter) + { + MailItem const& mailItem = mailItemIter->second; + CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, mailItem.item_guidlow, mailItem.item_template,receiver_guidlow); + } + } + CharacterDatabase.CommitTransaction(); +} diff --git a/src/game/Mail.h b/src/game/Mail.h new file mode 100644 index 000000000..e7adf6202 --- /dev/null +++ b/src/game/Mail.h @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef MANGOS_MAIL_H +#define MANGOS_MAIL_H + +#include "Common.h" +#include + +class Item; + +#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889 +#define MAX_MAIL_ITEMS 12 + +enum MAIL_RESPONSE +{ + MAIL_OK = 0, + MAIL_MONEY_TAKEN = 1, + MAIL_ITEM_TAKEN = 2, + MAIL_RETURNED_TO_SENDER = 3, + MAIL_DELETED = 4, + MAIL_MADE_PERMANENT = 5 +}; + +enum MAIL_ERRORS +{ + MAIL_ERR_BAG_FULL = 1, + MAIL_ERR_CANNOT_SEND_TO_SELF = 2, + MAIL_ERR_NOT_ENOUGH_MONEY = 3, + MAIL_ERR_RECIPIENT_NOT_FOUND = 4, + MAIL_ERR_NOT_YOUR_TEAM = 5, + MAIL_ERR_INTERNAL_ERROR = 6, + MAIL_ERR_DISABLED_FOR_TRIAL_ACC = 14, + MAIL_ERR_RECIPIENT_CAP_REACHED = 15, + MAIL_ERR_CANT_SEND_WRAPPED_COD = 16, + MAIL_ERR_MAIL_AND_CHAT_SUSPENDED = 17 +}; + +enum MailCheckMask +{ + MAIL_CHECK_MASK_NONE = 0, + MAIL_CHECK_MASK_READ = 1, + MAIL_CHECK_MASK_AUCTION = 4, + MAIL_CHECK_MASK_COD_PAYMENT = 8, + MAIL_CHECK_MASK_RETURNED = 16 +}; + +enum MailMessageType +{ + MAIL_NORMAL = 0, + MAIL_AUCTION = 2, + MAIL_CREATURE = 3, // client send CMSG_CREATURE_QUERY on this mailmessagetype + MAIL_GAMEOBJECT = 4, // client send CMSG_GAMEOBJECT_QUERY on this mailmessagetype + MAIL_ITEM = 5, // client send CMSG_ITEM_QUERY on this mailmessagetype +}; + +enum MailState +{ + MAIL_STATE_UNCHANGED = 1, + MAIL_STATE_CHANGED = 2, + MAIL_STATE_DELETED = 3 +}; + +enum MailAuctionAnswers +{ + AUCTION_OUTBIDDED = 0, + AUCTION_WON = 1, + AUCTION_SUCCESSFUL = 2, + AUCTION_EXPIRED = 3, + AUCTION_CANCELLED_TO_BIDDER = 4, + AUCTION_CANCELED = 5, + AUCTION_SALE_PENDING = 6 +}; + +// gathered from Stationery.dbc +enum MailStationery +{ + MAIL_STATIONERY_UNKNOWN = 0x01, + MAIL_STATIONERY_NORMAL = 0x29, + MAIL_STATIONERY_GM = 0x3D, + MAIL_STATIONERY_AUCTION = 0x3E, + MAIL_STATIONERY_VAL = 0x40, + MAIL_STATIONERY_CHR = 0x41 +}; + +struct MailItemInfo +{ + uint32 item_guid; + uint32 item_template; +}; + +struct MailItem +{ + MailItem() : item_slot(0), item_guidlow(0), item_template(0), item(NULL) {} + + uint8 item_slot; // slot in mail + uint32 item_guidlow; // item guid (low part) + uint32 item_template; // item entry + Item *item; // item pointer + + void deleteItem(bool inDB = false); +}; + +typedef std::map MailItemMap; + +class MailItemsInfo +{ + public: + MailItemMap::const_iterator begin() const { return i_MailItemMap.begin(); } + MailItemMap::const_iterator end() const { return i_MailItemMap.end(); } + MailItemMap::iterator begin() { return i_MailItemMap.begin(); } + MailItemMap::iterator end() { return i_MailItemMap.end(); } + + void AddItem(uint32 guidlow, uint32 _template, Item *item, uint8 slot = 0) + { + MailItem mailItem; + mailItem.item_slot = slot; + mailItem.item_guidlow = guidlow; + mailItem.item_template = _template; + mailItem.item = item; + i_MailItemMap[guidlow] = mailItem; + } + + void AddItem(uint32 guidlow, uint8 slot = 0) + { + MailItem mailItem; + mailItem.item_guidlow = guidlow; + mailItem.item_slot = slot; + i_MailItemMap[guidlow] = mailItem; + } + + uint8 size() const { return i_MailItemMap.size(); } + bool empty() const { return i_MailItemMap.empty(); } + + void deleteIncludedItems(bool inDB = false) + { + for(MailItemMap::iterator mailItemIter = begin(); mailItemIter != end(); ++mailItemIter) + { + MailItem& mailItem = mailItemIter->second; + mailItem.deleteItem(inDB); + } + } + private: + MailItemMap i_MailItemMap; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid +}; + +struct Mail +{ + uint32 messageID; + uint8 messageType; + uint8 stationery; + uint16 mailTemplateId; + uint32 sender; + uint32 receiver; + std::string subject; + uint32 itemTextId; + std::vector items; + std::vector removedItems; + time_t expire_time; + time_t deliver_time; + uint32 money; + uint32 COD; + uint32 checked; + MailState state; + + void AddItem(uint32 itemGuidLow, uint32 item_template) + { + MailItemInfo mii; + mii.item_guid = itemGuidLow; + mii.item_template = item_template; + items.push_back(mii); + } + + void AddAllItems(MailItemsInfo& pMailItemsInfo) + { + for(MailItemMap::iterator mailItemIter = pMailItemsInfo.begin(); mailItemIter != pMailItemsInfo.end(); ++mailItemIter) + { + MailItem& mailItem = mailItemIter->second; + AddItem(mailItem.item_guidlow, mailItem.item_template); + } + } + + bool RemoveItem(uint32 itemId) + { + for(std::vector::iterator itr = items.begin(); itr != items.end(); ++itr) + { + if(itr->item_guid == itemId) + { + items.erase(itr); + return true; + } + } + return false; + } + + bool HasItems() const { return !items.empty(); } +}; +#endif diff --git a/src/game/Makefile.am b/src/game/Makefile.am new file mode 100644 index 000000000..e8d24ddf7 --- /dev/null +++ b/src/game/Makefile.am @@ -0,0 +1,273 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../shared/vmap -I$(srcdir)/../realmd + +## Build MaNGOS game library as convenience library. +# All libraries will be convenience libraries. Might be changed to shared +# later. +noinst_LIBRARIES = libmangosgame.a + +# libmangossgame library will later be reused by ... +libmangosgame_a_SOURCES = \ + AccountMgr.cpp \ + AccountMgr.h \ + AddonHandler.cpp \ + AddonHandler.h \ + AggressorAI.cpp \ + AggressorAI.h \ + AnimalRandomMovementGenerator.h \ + ArenaTeam.cpp \ + ArenaTeam.h \ + ArenaTeamHandler.cpp \ + AuctionHouse.cpp \ + AuctionHouseObject.h \ + Bag.cpp \ + Bag.h \ + BattleGround.cpp \ + BattleGroundAA.cpp \ + BattleGroundAB.cpp \ + BattleGroundAV.cpp \ + BattleGroundBE.cpp \ + BattleGroundEY.cpp \ + BattleGroundNA.cpp \ + BattleGroundRL.cpp \ + BattleGroundWS.cpp \ + BattleGround.h \ + BattleGroundAA.h \ + BattleGroundAB.h \ + BattleGroundAV.h \ + BattleGroundBE.h \ + BattleGroundEY.h \ + BattleGroundNA.h \ + BattleGroundRL.h \ + BattleGroundWS.h \ + BattleGroundHandler.cpp \ + BattleGroundMgr.cpp \ + BattleGroundMgr.h \ + Cell.h \ + CellImpl.h \ + Channel.cpp \ + Channel.h \ + ChannelHandler.cpp \ + ChannelMgr.h \ + CharacterHandler.cpp \ + Chat.cpp \ + Chat.h \ + ChatHandler.cpp \ + CombatHandler.cpp \ + ConfusedMovementGenerator.cpp \ + ConfusedMovementGenerator.h \ + Corpse.cpp \ + Corpse.h \ + CreatureAI.cpp \ + CreatureAI.h \ + CreatureAIImpl.h \ + CreatureAIRegistry.cpp \ + CreatureAIRegistry.h \ + CreatureAISelector.cpp \ + CreatureAISelector.h \ + Creature.cpp \ + Creature.h \ + debugcmds.cpp \ + DestinationHolder.cpp \ + DestinationHolder.h \ + DestinationHolderImp.h \ + DuelHandler.cpp \ + DynamicObject.cpp \ + DynamicObject.h \ + FleeingMovementGenerator.cpp \ + FleeingMovementGenerator.h \ + Formulas.h \ + GameEvent.cpp \ + GameEvent.h \ + GameObject.cpp \ + GameObject.h \ + GlobalEvents.cpp \ + GlobalEvents.h \ + GossipDef.cpp \ + GossipDef.h \ + GridDefines.h \ + GridNotifiers.cpp \ + GridNotifiers.h \ + GridNotifiersImpl.h \ + GridStates.cpp \ + GridStates.h \ + Group.cpp \ + Group.h \ + GroupHandler.cpp \ + GuardAI.cpp \ + GuardAI.h \ + Guild.cpp \ + Guild.h \ + GuildHandler.cpp \ + HateMatrix.h \ + HomeMovementGenerator.cpp \ + HomeMovementGenerator.h \ + HostilRefManager.cpp \ + HostilRefManager.h \ + IdleMovementGenerator.cpp \ + IdleMovementGenerator.h \ + InstanceData.cpp \ + InstanceData.h \ + InstanceSaveMgr.cpp \ + InstanceSaveMgr.h \ + Item.cpp \ + Item.h \ + ItemEnchantmentMgr.cpp \ + ItemEnchantmentMgr.h \ + ItemHandler.cpp \ + ItemPrototype.h \ + Language.h \ + Level0.cpp \ + Level1.cpp \ + Level2.cpp \ + Level3.cpp \ + LFGHandler.cpp \ + LootHandler.cpp \ + LootMgr.cpp \ + LootMgr.h \ + Mail.cpp \ + Mail.h \ + Map.cpp \ + Map.h \ + MapInstanced.cpp \ + MapInstanced.h \ + MapManager.cpp \ + MapManager.h \ + MiscHandler.cpp \ + MotionMaster.cpp \ + MotionMaster.h \ + MovementGenerator.cpp \ + MovementGenerator.h \ + MovementGeneratorImpl.h \ + MovementHandler.cpp \ + NPCHandler.cpp \ + NPCHandler.h \ + NullCreatureAI.cpp \ + NullCreatureAI.h \ + ObjectAccessor.cpp \ + ObjectAccessor.h \ + Object.cpp \ + ObjectDefines.h \ + ObjectGridLoader.cpp \ + ObjectGridLoader.h \ + Object.h \ + ObjectMgr.cpp \ + ObjectMgr.h \ + ObjectPosSelector.cpp \ + ObjectPosSelector.h \ + Opcodes.cpp \ + Opcodes.h \ + Path.h \ + PetAI.cpp \ + PetAI.h \ + Pet.cpp \ + Pet.h \ + PetHandler.cpp \ + PetitionsHandler.cpp \ + Player.cpp \ + Player.h \ + PlayerDump.cpp \ + PlayerDump.h \ + PointMovementGenerator.cpp \ + PointMovementGenerator.h \ + QueryHandler.cpp \ + QuestDef.cpp \ + QuestDef.h \ + QuestHandler.cpp \ + RandomMovementGenerator.cpp \ + RandomMovementGenerator.h \ + ReactorAI.cpp \ + ReactorAI.h \ + ScriptCalls.cpp \ + ScriptCalls.h \ + SharedDefines.h \ + SkillHandler.cpp \ + SpellAuraDefines.h \ + SpellAuras.cpp \ + SpellAuras.h \ + Spell.cpp \ + SpellEffects.cpp \ + Spell.h \ + SkillDiscovery.cpp \ + SkillDiscovery.h \ + SkillExtraItems.cpp \ + SkillExtraItems.h \ + SpellHandler.cpp \ + SocialMgr.cpp \ + SocialMgr.h \ + SpellMgr.cpp \ + SpellMgr.h \ + StatSystem.cpp \ + TargetedMovementGenerator.cpp \ + TargetedMovementGenerator.h \ + TaxiHandler.cpp \ + TemporarySummon.cpp \ + TemporarySummon.h \ + tools.cpp \ + Tools.h \ + TotemAI.cpp \ + TotemAI.h \ + Totem.cpp \ + Totem.h \ + TradeHandler.cpp \ + Transports.cpp \ + Transports.h \ + ThreatManager.cpp \ + ThreatManager.h \ + Traveller.h \ + Unit.cpp \ + Unit.h \ + UnitEvents.h \ + UpdateData.cpp \ + UpdateData.h \ + UpdateFields.h \ + UpdateMask.h \ + VoiceChatHandler.cpp \ + WaypointManager.cpp \ + WaypointManager.h \ + WaypointMovementGenerator.cpp \ + WaypointMovementGenerator.h \ + Weather.cpp \ + Weather.h \ + World.cpp \ + World.h \ + WorldLog.cpp \ + WorldLog.h \ + WorldSession.cpp \ + WorldSession.h \ + WorldSocket.cpp \ + WorldSocket.h \ + WorldSocketMgr.cpp \ + WorldSocketMgr.h \ + FollowerReference.cpp \ + FollowerReference.h \ + FollowerRefManager.h \ + GroupReference.cpp \ + GroupReference.h \ + GroupRefManager.h + +## Link against shared library +libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a + +## Additional files to include when running 'make dist' +# Nothing yet. diff --git a/src/game/Map.cpp b/src/game/Map.cpp new file mode 100644 index 000000000..9dc0dd468 --- /dev/null +++ b/src/game/Map.cpp @@ -0,0 +1,1794 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MapManager.h" +#include "Player.h" +#include "GridNotifiers.h" +#include "WorldSession.h" +#include "Log.h" +#include "GridStates.h" +#include "CellImpl.h" +#include "InstanceData.h" +#include "Map.h" +#include "GridNotifiersImpl.h" +#include "Config/ConfigEnv.h" +#include "Transports.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "World.h" +#include "ScriptCalls.h" +#include "Group.h" + +#include "MapInstanced.h" +#include "InstanceSaveMgr.h" +#include "VMapFactory.h" + +#define DEFAULT_GRID_EXPIRY 300 +#define MAX_GRID_LOAD_TIME 50 + +// magic *.map header +const char MAP_MAGIC[] = "MAP_2.00"; + +GridState* si_GridStates[MAX_GRID_STATE]; + +Map::~Map() +{ + UnloadAll(true); +} + +bool Map::ExistMap(uint32 mapid,int x,int y) +{ + int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1; + char* tmp = new char[len]; + snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y); + + FILE *pf=fopen(tmp,"rb"); + + if(!pf) + { + sLog.outError("Check existing of map file '%s': not exist!",tmp); + delete[] tmp; + return false; + } + + char magic[8]; + fread(magic,1,8,pf); + if(strncmp(MAP_MAGIC,magic,8)) + { + sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp); + delete [] tmp; + fclose(pf); //close file before return + return false; + } + + delete [] tmp; + fclose(pf); + + return true; +} + +bool Map::ExistVMap(uint32 mapid,int x,int y) +{ + if(VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager()) + { + if(vmgr->isMapLoadingEnabled()) + { + // x and y are swapped !! => fixed now + bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, x,y); + if(!exists) + { + std::string name = vmgr->getDirFileName(mapid,x,y); + sLog.outError("VMap file '%s' is missing or point to wrong version vmap file, redo vmaps with latest vmap_assembler.exe program", (sWorld.GetDataPath()+"vmaps/"+name).c_str()); + return false; + } + } + } + + return true; +} + +void Map::LoadVMap(int x,int y) +{ + // x and y are swapped !! + int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), GetId(), x,y); + switch(vmapLoadResult) + { + case VMAP::VMAP_LOAD_RESULT_OK: + sLog.outDetail("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y); + break; + case VMAP::VMAP_LOAD_RESULT_ERROR: + sLog.outDetail("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y); + break; + case VMAP::VMAP_LOAD_RESULT_IGNORED: + DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y); + break; + } +} + +void Map::LoadMap(uint32 mapid, uint32 instanceid, int x,int y) +{ + if( instanceid != 0 ) + { + if(GridMaps[x][y]) + return; + + Map* baseMap = const_cast(MapManager::Instance().GetBaseMap(mapid)); + + // load gridmap for base map + if (!baseMap->GridMaps[x][y]) + baseMap->EnsureGridCreated(GridPair(63-x,63-y)); + +//+++ if (!baseMap->GridMaps[x][y]) don't check for GridMaps[gx][gy], we need the management for vmaps +// return; + + ((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(x,y)); + baseMap->SetUnloadFlag(GridPair(63-x,63-y), false); + GridMaps[x][y] = baseMap->GridMaps[x][y]; + return; + } + + //map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?) + if(GridMaps[x][y]) + { + sLog.outDetail("Unloading already loaded map %u before reloading.",mapid); + delete (GridMaps[x][y]); + GridMaps[x][y]=NULL; + } + + // map file name + char *tmp=NULL; + // Pihhan: dataPath length + "maps/" + 3+2+2+ ".map" length may be > 32 ! + int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1; + tmp = new char[len]; + snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y); + sLog.outDetail("Loading map %s",tmp); + // loading data + FILE *pf=fopen(tmp,"rb"); + if(!pf) + { + delete [] tmp; + return; + } + + char magic[8]; + fread(magic,1,8,pf); + if(strncmp(MAP_MAGIC,magic,8)) + { + sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp); + delete [] tmp; + fclose(pf); //close file before return + return; + } + delete [] tmp; + + GridMap * buf= new GridMap; + fread(buf,1,sizeof(GridMap),pf); + fclose(pf); + + GridMaps[x][y] = buf; +} + +void Map::LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x,int y) +{ + LoadMap(mapid,instanceid,x,y); + if(instanceid == 0) + LoadVMap(x, y); // Only load the data for the base map +} + +void Map::InitStateMachine() +{ + si_GridStates[GRID_STATE_INVALID] = new InvalidState; + si_GridStates[GRID_STATE_ACTIVE] = new ActiveState; + si_GridStates[GRID_STATE_IDLE] = new IdleState; + si_GridStates[GRID_STATE_REMOVAL] = new RemovalState; +} + +void Map::DeleteStateMachine() +{ + delete si_GridStates[GRID_STATE_INVALID]; + delete si_GridStates[GRID_STATE_ACTIVE]; + delete si_GridStates[GRID_STATE_IDLE]; + delete si_GridStates[GRID_STATE_REMOVAL]; +} + +Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) + : i_id(id), i_gridExpiry(expiry), i_mapEntry (sMapStore.LookupEntry(id)), + i_InstanceId(InstanceId), i_spawnMode(SpawnMode), m_unloadTimer(0) +{ + for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) + { + for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) + { + //z code + GridMaps[idx][j] =NULL; + setNGrid(NULL, idx, j); + } + } +} + +// Template specialization of utility methods +template +void Map::AddToGrid(T* obj, NGridType *grid, Cell const& cell) +{ + (*grid)(cell.CellX(), cell.CellY()).template AddGridObject(obj, obj->GetGUID()); +} + +template<> +void Map::AddToGrid(Player* obj, NGridType *grid, Cell const& cell) +{ + (*grid)(cell.CellX(), cell.CellY()).AddWorldObject(obj, obj->GetGUID()); +} + +template<> +void Map::AddToGrid(Corpse *obj, NGridType *grid, Cell const& cell) +{ + // add to world object registry in grid + if(obj->GetType()!=CORPSE_BONES) + { + (*grid)(cell.CellX(), cell.CellY()).AddWorldObject(obj, obj->GetGUID()); + } + // add to grid object store + else + { + (*grid)(cell.CellX(), cell.CellY()).AddGridObject(obj, obj->GetGUID()); + } +} + +template<> +void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell) +{ + // add to world object registry in grid + if(obj->isPet()) + { + (*grid)(cell.CellX(), cell.CellY()).AddWorldObject(obj, obj->GetGUID()); + obj->SetCurrentCell(cell); + } + // add to grid object store + else + { + (*grid)(cell.CellX(), cell.CellY()).AddGridObject(obj, obj->GetGUID()); + obj->SetCurrentCell(cell); + } +} + +template +void Map::RemoveFromGrid(T* obj, NGridType *grid, Cell const& cell) +{ + (*grid)(cell.CellX(), cell.CellY()).template RemoveGridObject(obj, obj->GetGUID()); +} + +template<> +void Map::RemoveFromGrid(Player* obj, NGridType *grid, Cell const& cell) +{ + (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject(obj, obj->GetGUID()); +} + +template<> +void Map::RemoveFromGrid(Corpse *obj, NGridType *grid, Cell const& cell) +{ + // remove from world object registry in grid + if(obj->GetType()!=CORPSE_BONES) + { + (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject(obj, obj->GetGUID()); + } + // remove from grid object store + else + { + (*grid)(cell.CellX(), cell.CellY()).RemoveGridObject(obj, obj->GetGUID()); + } +} + +template<> +void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell) +{ + // remove from world object registry in grid + if(obj->isPet()) + { + (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject(obj, obj->GetGUID()); + } + // remove from grid object store + else + { + (*grid)(cell.CellX(), cell.CellY()).RemoveGridObject(obj, obj->GetGUID()); + } +} + +template +void Map::DeleteFromWorld(T* obj) +{ + // Note: In case resurrectable corpse and pet its removed from global lists in own destructor + delete obj; +} + +template +void Map::AddNotifier(T* , Cell const& , CellPair const& ) +{ +} + +template<> +void Map::AddNotifier(Player* obj, Cell const& cell, CellPair const& cellpair) +{ + PlayerRelocationNotify(obj,cell,cellpair); +} + +template<> +void Map::AddNotifier(Creature* obj, Cell const& cell, CellPair const& cellpair) +{ + CreatureRelocationNotify(obj,cell,cellpair); +} + +void +Map::EnsureGridCreated(const GridPair &p) +{ + if(!getNGrid(p.x_coord, p.y_coord)) + { + Guard guard(*this); + if(!getNGrid(p.x_coord, p.y_coord)) + { + setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_GRID_UNLOAD)), + p.x_coord, p.y_coord); + + // build a linkage between this map and NGridType + buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); + + getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); + + //z coord + int gx=63-p.x_coord; + int gy=63-p.y_coord; + + if(!GridMaps[gx][gy]) + Map::LoadMapAndVMap(i_id,i_InstanceId,gx,gy); + } + } +} + +void +Map::EnsureGridLoadedForPlayer(const Cell &cell, Player *player, bool add_player) +{ + EnsureGridCreated(GridPair(cell.GridX(), cell.GridY())); + NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); + + assert(grid != NULL); + if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) ) + { + if( player != NULL ) + { + player->SendDelayResponse(MAX_GRID_LOAD_TIME); + DEBUG_LOG("Player %s enter cell[%u,%u] triggers of loading grid[%u,%u] on map %u", player->GetName(), cell.CellX(), cell.CellY(), cell.GridX(), cell.GridY(), i_id); + } + else + { + DEBUG_LOG("Player nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id); + } + + ObjectGridLoader loader(*grid, this, cell); + loader.LoadN(); + setGridObjectDataLoaded(true, cell.GridX(), cell.GridY()); + + // Add resurrectable corpses to world object list in grid + ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this); + + ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f); + grid->SetGridState(GRID_STATE_ACTIVE); + + if( add_player && player != NULL ) + (*grid)(cell.CellX(), cell.CellY()).AddWorldObject(player, player->GetGUID()); + } + else if( player && add_player ) + AddToGrid(player,grid,cell); +} + +void +Map::LoadGrid(const Cell& cell, bool no_unload) +{ + EnsureGridCreated(GridPair(cell.GridX(), cell.GridY())); + NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); + + assert(grid != NULL); + if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) ) + { + ObjectGridLoader loader(*grid, this, cell); + loader.LoadN(); + + // Add resurrectable corpses to world object list in grid + ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this); + + setGridObjectDataLoaded(true,cell.GridX(), cell.GridY()); + if(no_unload) + getNGrid(cell.GridX(), cell.GridY())->setUnloadFlag(false); + } + LoadVMap(63-cell.GridX(),63-cell.GridY()); +} + +bool Map::Add(Player *player) +{ + player->SetInstanceId(this->GetInstanceId()); + + // update player state for other player and visa-versa + CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); + Cell cell(p); + EnsureGridLoadedForPlayer(cell, player, true); + player->AddToWorld(); + + SendInitSelf(player); + SendInitTransports(player); + + UpdatePlayerVisibility(player,cell,p); + UpdateObjectsVisibilityFor(player,cell,p); + + AddNotifier(player,cell,p); + return true; +} + +template +void +Map::Add(T *obj) +{ + CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + + assert(obj); + + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::Add: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + return; + } + + Cell cell(p); + EnsureGridCreated(GridPair(cell.GridX(), cell.GridY())); + NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); + assert( grid != NULL ); + + AddToGrid(obj,grid,cell); + obj->AddToWorld(); + + DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY()); + + UpdateObjectVisibility(obj,cell,p); + + AddNotifier(obj,cell,p); +} + +void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self) +{ + CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); + + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord); + return; + } + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) + return; + + MaNGOS::MessageDeliverer post_man(*player, msg, to_self); + TypeContainerVisitor message(post_man); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *this); +} + +void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg) +{ + CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + return; + } + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) + return; + + MaNGOS::ObjectMessageDeliverer post_man(msg); + TypeContainerVisitor message(post_man); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *this); +} + +void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only) +{ + CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); + + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord); + return; + } + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) + return; + + MaNGOS::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only); + TypeContainerVisitor message(post_man); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *this); +} + +void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist) +{ + CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + return; + } + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) + return; + + MaNGOS::ObjectMessageDistDeliverer post_man(*obj, msg,dist); + TypeContainerVisitor message(post_man); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *this); +} + +bool Map::loaded(const GridPair &p) const +{ + return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) ); +} + +void Map::Update(const uint32 &t_diff) +{ + // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! + // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended + if (IsBattleGroundOrArena()) + return; + + for (GridRefManager::iterator i = GridRefManager::begin(); i != GridRefManager::end(); ) + { + NGridType *grid = i->getSource(); + GridInfo *info = i->getSource()->getGridInfoRef(); + ++i; // The update might delete the map and we need the next map before the iterator gets invalid + assert(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE); + si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, grid->getX(), grid->getY(), t_diff); + } +} + +void InstanceMap::Update(const uint32& t_diff) +{ + Map::Update(t_diff); + + if(i_data) + i_data->Update(t_diff); +} + +void Map::Remove(Player *player, bool remove) +{ + CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) + { + // invalid coordinates + player->RemoveFromWorld(); + + if( remove ) + DeleteFromWorld(player); + + return; + } + + Cell cell(p); + + if( !getNGrid(cell.data.Part.grid_x, cell.data.Part.grid_y) ) + { + sLog.outError("Map::Remove() i_grids was NULL x:%d, y:%d",cell.data.Part.grid_x,cell.data.Part.grid_y); + return; + } + + DEBUG_LOG("Remove player %s from grid[%u,%u]", player->GetName(), cell.GridX(), cell.GridY()); + NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); + assert(grid != NULL); + + player->RemoveFromWorld(); + RemoveFromGrid(player,grid,cell); + + SendRemoveTransports(player); + + UpdateObjectsVisibilityFor(player,cell,p); + + if( remove ) + DeleteFromWorld(player); +} + +bool Map::RemoveBones(uint64 guid, float x, float y) +{ + if (IsRemovalGrid(x, y)) + { + Corpse * corpse = ObjectAccessor::Instance().GetObjectInWorld(GetId(), x, y, guid, (Corpse*)NULL); + if(corpse && corpse->GetTypeId() == TYPEID_CORPSE && corpse->GetType() == CORPSE_BONES) + corpse->DeleteBonesFromWorld(); + else + return false; + } + return true; +} + +template +void +Map::Remove(T *obj, bool remove) +{ + CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("Map::Remove: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + return; + } + + Cell cell(p); + if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) + return; + + DEBUG_LOG("Remove object " I64FMTD " from grid[%u,%u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y); + NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); + assert( grid != NULL ); + + obj->RemoveFromWorld(); + RemoveFromGrid(obj,grid,cell); + + UpdateObjectVisibility(obj,cell,p); + + if( remove ) + { + // if option set then object already saved at this moment + if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) + obj->SaveRespawnTime(); + DeleteFromWorld(obj); + } +} + +void +Map::PlayerRelocation(Player *player, float x, float y, float z, float orientation) +{ + assert(player); + + CellPair old_val = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); + CellPair new_val = MaNGOS::ComputeCellPair(x, y); + + Cell old_cell(old_val); + Cell new_cell(new_val); + new_cell |= old_cell; + bool same_cell = (new_cell == old_cell); + + player->Relocate(x, y, z, orientation); + + if( old_cell.DiffGrid(new_cell) || old_cell.DiffCell(new_cell) ) + { + DEBUG_LOG("Player %s relocation grid[%u,%u]cell[%u,%u]->grid[%u,%u]cell[%u,%u]", player->GetName(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + + // update player position for group at taxi flight + if(player->GetGroup() && player->isInFlight()) + player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION); + + NGridType* oldGrid = getNGrid(old_cell.GridX(), old_cell.GridY()); + RemoveFromGrid(player, oldGrid,old_cell); + if( !old_cell.DiffGrid(new_cell) ) + AddToGrid(player, oldGrid,new_cell); + + if( old_cell.DiffGrid(new_cell) ) + EnsureGridLoadedForPlayer(new_cell, player, true); + } + + // if move then update what player see and who seen + UpdatePlayerVisibility(player,new_cell,new_val); + UpdateObjectsVisibilityFor(player,new_cell,new_val); + PlayerRelocationNotify(player,new_cell,new_val); + NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY()); + if( !same_cell && newGrid->GetGridState()!= GRID_STATE_ACTIVE ) + { + ResetGridExpiry(*newGrid, 0.1f); + newGrid->SetGridState(GRID_STATE_ACTIVE); + } +} + +void +Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang) +{ + assert(CheckGridIntegrity(creature,false)); + + Cell old_cell = creature->GetCurrentCell(); + + CellPair new_val = MaNGOS::ComputeCellPair(x, y); + Cell new_cell(new_val); + + // delay creature move for grid/cell to grid/cell moves + if( old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell) ) + { + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) added to moving list from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + #endif + AddCreatureToMoveList(creature,x,y,z,ang); + // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList + } + else + { + creature->Relocate(x, y, z, ang); + CreatureRelocationNotify(creature,new_cell,new_val); + } + assert(CheckGridIntegrity(creature,true)); +} + +void Map::AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang) +{ + if(!c) + return; + + i_creaturesToMove[c] = CreatureMover(x,y,z,ang); +} + +void Map::MoveAllCreaturesInMoveList() +{ + while(!i_creaturesToMove.empty()) + { + // get data and remove element; + CreatureMoveList::iterator iter = i_creaturesToMove.begin(); + Creature* c = iter->first; + CreatureMover cm = iter->second; + i_creaturesToMove.erase(iter); + + // calculate cells + CellPair new_val = MaNGOS::ComputeCellPair(cm.x, cm.y); + Cell new_cell(new_val); + + // do move or do move to respawn or remove creature if previous all fail + if(CreatureCellRelocation(c,new_cell)) + { + // update pos + c->Relocate(cm.x, cm.y, cm.z, cm.ang); + CreatureRelocationNotify(c,new_cell,new_cell.cellPair()); + } + else + { + // if creature can't be move in new cell/grid (not loaded) move it to repawn cell/grid + // creature coordinates will be updated and notifiers send + if(!CreatureRespawnRelocation(c)) + { + // ... or unload (if respawn grid also not loaded) + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",c->GetGUIDLow(),c->GetEntry()); + #endif + c->CleanupsBeforeDelete(); + AddObjectToRemoveList(c); + } + } + } +} + +bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) +{ + Cell const& old_cell = c->GetCurrentCell(); + if(!old_cell.DiffGrid(new_cell) ) // in same grid + { + // if in same cell then none do + if(old_cell.DiffCell(new_cell)) + { + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) moved in grid[%u,%u] from cell[%u,%u] to cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); + #endif + + if( !old_cell.DiffGrid(new_cell) ) + { + RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell); + AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell); + c->SetCurrentCell(new_cell); + } + } + else + { + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) move in same grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); + #endif + } + } + else // in diff. grids + if(loaded(GridPair(new_cell.GridX(), new_cell.GridY()))) + { + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + #endif + + RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell); + { + EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY())); + AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell); + } + } + else + { + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + #endif + return false; + } + + return true; +} + +bool Map::CreatureRespawnRelocation(Creature *c) +{ + float resp_x, resp_y, resp_z, resp_o; + c->GetRespawnCoord(resp_x, resp_y, resp_z, &resp_o); + + CellPair resp_val = MaNGOS::ComputeCellPair(resp_x, resp_y); + Cell resp_cell(resp_val); + + c->CombatStop(); + c->GetMotionMaster()->Clear(); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) will moved from grid[%u,%u]cell[%u,%u] to respawn grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); + #endif + + // teleport it to respawn point (like normal respawn if player see) + if(CreatureCellRelocation(c,resp_cell)) + { + c->Relocate(resp_x, resp_y, resp_z, resp_o); + c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators + CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair()); + return true; + } + else + return false; +} + +bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce) +{ + NGridType *grid = getNGrid(x, y); + assert( grid != NULL); + + { + if(!pForce && ObjectAccessor::Instance().PlayersNearGrid(x, y, i_id, i_InstanceId) ) + return false; + + DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id); + ObjectGridUnloader unloader(*grid); + + // Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids + // Must know real mob position before move + DoDelayedMovesAndRemoves(); + + // move creatures to respawn grids if this is diff.grid or to remove list + unloader.MoveToRespawnN(); + + // Finish creature moves, remove and delete all creatures with delayed remove before unload + DoDelayedMovesAndRemoves(); + + unloader.UnloadN(); + delete getNGrid(x, y); + setNGrid(NULL, x, y); + } + int gx=63-x; + int gy=63-y; + + // delete grid map, but don't delete if it is from parent map (and thus only reference) + //+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps + { + if (i_InstanceId == 0) + { + if(GridMaps[gx][gy]) delete (GridMaps[gx][gy]); + // x and y are swaped + VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx); + } + else + ((MapInstanced*)(MapManager::Instance().GetBaseMap(i_id)))->RemoveGridMapReference(GridPair(gx, gy)); + GridMaps[gx][gy] = NULL; + } + DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id); + return true; +} + +void Map::UnloadAll(bool pForce) +{ + // clear all delayed moves, useless anyway do this moves before map unload. + i_creaturesToMove.clear(); + + for (GridRefManager::iterator i = GridRefManager::begin(); i != GridRefManager::end(); ) + { + NGridType &grid(*i->getSource()); + ++i; + UnloadGrid(grid.getX(), grid.getY(), pForce); // deletes the grid and removes it from the GridRefManager + } +} + +float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const +{ + GridPair p = MaNGOS::ComputeGridPair(x, y); + + // half opt method + int gx=(int)(32-x/SIZE_OF_GRIDS); //grid x + int gy=(int)(32-y/SIZE_OF_GRIDS); //grid y + + float lx=MAP_RESOLUTION*(32 -x/SIZE_OF_GRIDS - gx); + float ly=MAP_RESOLUTION*(32 -y/SIZE_OF_GRIDS - gy); + + // ensure GridMap is loaded + const_cast(this)->EnsureGridCreated(GridPair(63-gx,63-gy)); + + // find raw .map surface under Z coordinates + float mapHeight; + if(GridMap* gmap = GridMaps[gx][gy]) + { + int lx_int = (int)lx; + int ly_int = (int)ly; + + float zi[4]; + // Probe 4 nearest points (except border cases) + zi[0] = gmap->Z[lx_int][ly_int]; + zi[1] = lx < MAP_RESOLUTION-1 ? gmap->Z[lx_int+1][ly_int] : zi[0]; + zi[2] = ly < MAP_RESOLUTION-1 ? gmap->Z[lx_int][ly_int+1] : zi[0]; + zi[3] = lx < MAP_RESOLUTION-1 && ly < MAP_RESOLUTION-1 ? gmap->Z[lx_int+1][ly_int+1] : zi[0]; + // Recalculate them like if their x,y positions were in the range 0,1 + float b[4]; + b[0] = zi[0]; + b[1] = zi[1]-zi[0]; + b[2] = zi[2]-zi[0]; + b[3] = zi[0]-zi[1]-zi[2]+zi[3]; + // Normalize the dx and dy to be in range 0..1 + float fact_x = lx - lx_int; + float fact_y = ly - ly_int; + // Use the simplified bilinear equation, as described in [url="http://en.wikipedia.org/wiki/Bilinear_interpolation"]http://en.wikipedia.org/wiki/Bilinear_interpolation[/url] + float _mapheight = b[0] + (b[1]*fact_x) + (b[2]*fact_y) + (b[3]*fact_x*fact_y); + + // look from a bit higher pos to find the floor, ignore under surface case + if(z + 2.0f > _mapheight) + mapHeight = _mapheight; + else + mapHeight = VMAP_INVALID_HEIGHT_VALUE; + } + else + mapHeight = VMAP_INVALID_HEIGHT_VALUE; + + float vmapHeight; + if(pUseVmaps) + { + VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); + if(vmgr->isHeightCalcEnabled()) + { + // look from a bit higher pos to find the floor + vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f); + } + else + vmapHeight = VMAP_INVALID_HEIGHT_VALUE; + } + else + vmapHeight = VMAP_INVALID_HEIGHT_VALUE; + + // mapHeight set for any above raw ground Z or <= INVALID_HEIGHT + // vmapheight set for any under Z value or <= INVALID_HEIGHT + + if( vmapHeight > INVALID_HEIGHT ) + { + if( mapHeight > INVALID_HEIGHT ) + { + // we have mapheight and vmapheight and must select more appropriate + + // we are already under the surface or vmap height above map heigt + // or if the distance of the vmap height is less the land height distance + if( z < mapHeight || vmapHeight > mapHeight || fabs(mapHeight-z) > fabs(vmapHeight-z) ) + return vmapHeight; + else + return mapHeight; // better use .map surface height + + } + else + return vmapHeight; // we have only vmapHeight (if have) + } + else + { + if(!pUseVmaps) + return mapHeight; // explicitly use map data (if have) + else if(mapHeight > INVALID_HEIGHT && (z < mapHeight + 2 || z == MAX_HEIGHT)) + return mapHeight; // explicitly use map data if original z < mapHeight but map found (z+2 > mapHeight) + else + return VMAP_INVALID_HEIGHT_VALUE; // we not have any height + } +} + +uint16 Map::GetAreaFlag(float x, float y ) const +{ + //local x,y coords + float lx,ly; + int gx,gy; + GridPair p = MaNGOS::ComputeGridPair(x, y); + + // half opt method + gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x + gy=(int)(32-y/SIZE_OF_GRIDS); //grid y + + lx=16*(32 -x/SIZE_OF_GRIDS - gx); + ly=16*(32 -y/SIZE_OF_GRIDS - gy); + //DEBUG_LOG("my %d %d si %d %d",gx,gy,p.x_coord,p.y_coord); + + // ensure GridMap is loaded + const_cast(this)->EnsureGridCreated(GridPair(63-gx,63-gy)); + + if(GridMaps[gx][gy]) + return GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)]; + // this used while not all *.map files generated (instances) + else + return GetAreaFlagByMapId(i_id); +} + +uint8 Map::GetTerrainType(float x, float y ) const +{ + //local x,y coords + float lx,ly; + int gx,gy; + + // half opt method + gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x + gy=(int)(32-y/SIZE_OF_GRIDS); //grid y + + lx=16*(32 -x/SIZE_OF_GRIDS - gx); + ly=16*(32 -y/SIZE_OF_GRIDS - gy); + + // ensure GridMap is loaded + const_cast(this)->EnsureGridCreated(GridPair(63-gx,63-gy)); + + if(GridMaps[gx][gy]) + return GridMaps[gx][gy]->terrain_type[(int)(lx)][(int)(ly)]; + else + return 0; + +} + +float Map::GetWaterLevel(float x, float y ) const +{ + //local x,y coords + float lx,ly; + int gx,gy; + + // half opt method + gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x + gy=(int)(32-y/SIZE_OF_GRIDS); //grid y + + lx=128*(32 -x/SIZE_OF_GRIDS - gx); + ly=128*(32 -y/SIZE_OF_GRIDS - gy); + + // ensure GridMap is loaded + const_cast(this)->EnsureGridCreated(GridPair(63-gx,63-gy)); + + if(GridMaps[gx][gy]) + return GridMaps[gx][gy]->liquid_level[(int)(lx)][(int)(ly)]; + else + return 0; +} + +uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id) +{ + AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id); + + if (entry) + return entry->ID; + else + return 0; +} + +uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id) +{ + AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id); + + if( entry ) + return ( entry->zone != 0 ) ? entry->zone : entry->ID; + else + return 0; +} + +bool Map::IsInWater(float x, float y, float pZ) const +{ + // This method is called too often to use vamps for that (4. parameter = false). + // The pZ pos is taken anyway for future use + float z = GetHeight(x,y,pZ,false); // use .map base surface height + + // underground or instance without vmap + if(z <= INVALID_HEIGHT) + return false; + + float water_z = GetWaterLevel(x,y); + uint8 flag = GetTerrainType(x,y); + return (z < (water_z-2)) && (flag & 0x01); +} + +bool Map::IsUnderWater(float x, float y, float z) const +{ + float water_z = GetWaterLevel(x,y); + uint8 flag = GetTerrainType(x,y); + return (z < (water_z-2)) && (flag & 0x01); +} + +bool Map::CheckGridIntegrity(Creature* c, bool moved) const +{ + Cell const& cur_cell = c->GetCurrentCell(); + + CellPair xy_val = MaNGOS::ComputeCellPair(c->GetPositionX(), c->GetPositionY()); + Cell xy_cell(xy_val); + if(xy_cell != cur_cell) + { + sLog.outError("ERROR: %s (GUID: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]", + (c->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature"),c->GetGUIDLow(), + c->GetPositionX(),c->GetPositionY(),(moved ? "final" : "original"), + cur_cell.GridX(), cur_cell.GridY(), cur_cell.CellX(), cur_cell.CellY(), + xy_cell.GridX(), xy_cell.GridY(), xy_cell.CellX(), xy_cell.CellY()); + return true; // not crash at error, just output error in debug mode + } + + return true; +} + +const char* Map::GetMapName() const +{ + return i_mapEntry ? i_mapEntry->name[sWorld.GetDefaultDbcLocale()] : "UNNAMEDMAP\x0"; +} + +void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair) +{ + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + MaNGOS::VisibleChangesNotifier notifier(*obj); + TypeContainerVisitor player_notifier(notifier); + CellLock cell_lock(cell, cellpair); + cell_lock->Visit(cell_lock, player_notifier, *this); +} + +void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair ) +{ + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::PlayerNotifier pl_notifier(*player); + TypeContainerVisitor player_notifier(pl_notifier); + + CellLock cell_lock(cell, cellpair); + cell_lock->Visit(cell_lock, player_notifier, *this); +} + +void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair ) +{ + MaNGOS::VisibleNotifier notifier(*player); + + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + TypeContainerVisitor world_notifier(notifier); + TypeContainerVisitor grid_notifier(notifier); + CellLock cell_lock(cell, cellpair); + cell_lock->Visit(cell_lock, world_notifier, *this); + cell_lock->Visit(cell_lock, grid_notifier, *this); + + // send data + notifier.Notify(); +} + +void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair ) +{ + CellLock cell_lock(cell, cellpair); + MaNGOS::PlayerRelocationNotifier relocationNotifier(*player); + cell.data.Part.reserved = ALL_DISTRICT; + + TypeContainerVisitor p2grid_relocation(relocationNotifier); + TypeContainerVisitor p2world_relocation(relocationNotifier); + + cell_lock->Visit(cell_lock, p2grid_relocation, *this); + cell_lock->Visit(cell_lock, p2world_relocation, *this); +} + +void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair) +{ + CellLock cell_lock(cell, cellpair); + MaNGOS::CreatureRelocationNotifier relocationNotifier(*creature); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); // not trigger load unloaded grids at notifier call + + TypeContainerVisitor c2world_relocation(relocationNotifier); + TypeContainerVisitor c2grid_relocation(relocationNotifier); + + cell_lock->Visit(cell_lock, c2world_relocation, *this); + cell_lock->Visit(cell_lock, c2grid_relocation, *this); +} + +void Map::SendInitSelf( Player * player ) +{ + sLog.outDetail("Creating player data for himself %u", player->GetGUIDLow()); + + UpdateData data; + + bool hasTransport = false; + + // attach to player data current transport data + if(Transport* transport = player->GetTransport()) + { + hasTransport = true; + transport->BuildCreateUpdateBlockForPlayer(&data, player); + } + + // build data for self presence in world at own client (one time for map) + player->BuildCreateUpdateBlockForPlayer(&data, player); + + // build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map + if(Transport* transport = player->GetTransport()) + { + for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr) + { + if(player!=(*itr) && player->HaveAtClient(*itr)) + { + hasTransport = true; + (*itr)->BuildCreateUpdateBlockForPlayer(&data, player); + } + } + } + + WorldPacket packet; + data.BuildPacket(&packet, hasTransport); + player->GetSession()->SendPacket(&packet); +} + +void Map::SendInitTransports( Player * player ) +{ + // Hack to send out transports + MapManager::TransportMap& tmap = MapManager::Instance().m_TransportsByMap; + + // no transports at map + if (tmap.find(player->GetMapId()) == tmap.end()) + return; + + UpdateData transData; + + MapManager::TransportSet& tset = tmap[player->GetMapId()]; + + bool hasTransport = false; + + for (MapManager::TransportSet::iterator i = tset.begin(); i != tset.end(); ++i) + { + if((*i) != player->GetTransport()) // send data for current transport in other place + { + hasTransport = true; + (*i)->BuildCreateUpdateBlockForPlayer(&transData, player); + } + } + + WorldPacket packet; + transData.BuildPacket(&packet, hasTransport); + player->GetSession()->SendPacket(&packet); +} + +void Map::SendRemoveTransports( Player * player ) +{ + // Hack to send out transports + MapManager::TransportMap& tmap = MapManager::Instance().m_TransportsByMap; + + // no transports at map + if (tmap.find(player->GetMapId()) == tmap.end()) + return; + + UpdateData transData; + + MapManager::TransportSet& tset = tmap[player->GetMapId()]; + + // except used transport + for (MapManager::TransportSet::iterator i = tset.begin(); i != tset.end(); ++i) + if(player->GetTransport() != (*i)) + (*i)->BuildOutOfRangeUpdateBlock(&transData); + + WorldPacket packet; + transData.BuildPacket(&packet); + player->GetSession()->SendPacket(&packet); +} + +inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y) +{ + if(x >= MAX_NUMBER_OF_GRIDS || y >= MAX_NUMBER_OF_GRIDS) + { + sLog.outError("map::setNGrid() Invalid grid coordinates found: %d, %d!",x,y); + assert(false); + } + i_grids[x][y] = grid; +} + +void Map::DoDelayedMovesAndRemoves() +{ + MoveAllCreaturesInMoveList(); + RemoveAllObjectsInRemoveList(); +} + +void Map::AddObjectToRemoveList(WorldObject *obj) +{ + assert(obj->GetMapId()==GetId() && obj->GetInstanceId()==GetInstanceId()); + + i_objectsToRemove.insert(obj); + //sLog.outDebug("Object (GUID: %u TypeId: %u ) added to removing list.",obj->GetGUIDLow(),obj->GetTypeId()); +} + +void Map::RemoveAllObjectsInRemoveList() +{ + if(i_objectsToRemove.empty()) + return; + + //sLog.outDebug("Object remover 1 check."); + while(!i_objectsToRemove.empty()) + { + WorldObject* obj = *i_objectsToRemove.begin(); + i_objectsToRemove.erase(i_objectsToRemove.begin()); + + switch(obj->GetTypeId()) + { + case TYPEID_CORPSE: + { + Corpse* corpse = ObjectAccessor::Instance().GetCorpse(*obj, obj->GetGUID()); + if (!corpse) + sLog.outError("ERROR: Try delete corpse/bones %u that not in map", obj->GetGUIDLow()); + else + Remove(corpse,true); + break; + } + case TYPEID_DYNAMICOBJECT: + Remove((DynamicObject*)obj,true); + break; + case TYPEID_GAMEOBJECT: + Remove((GameObject*)obj,true); + break; + case TYPEID_UNIT: + Remove((Creature*)obj,true); + break; + default: + sLog.outError("Non-grid object (TypeId: %u) in grid object removing list, ignored.",obj->GetTypeId()); + break; + } + } + //sLog.outDebug("Object remover 2 check."); +} + +bool Map::CanUnload(const uint32 &diff) +{ + if(!m_unloadTimer) return false; + if(m_unloadTimer < diff) return true; + m_unloadTimer -= diff; + return false; +} + +template void Map::Add(Corpse *); +template void Map::Add(Creature *); +template void Map::Add(GameObject *); +template void Map::Add(DynamicObject *); + +template void Map::Remove(Corpse *,bool); +template void Map::Remove(Creature *,bool); +template void Map::Remove(GameObject *, bool); +template void Map::Remove(DynamicObject *, bool); + +/* ******* Dungeon Instance Maps ******* */ + +InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) + : Map(id, expiry, InstanceId, SpawnMode), i_data(NULL), + m_resetAfterUnload(false), m_unloadWhenEmpty(false) +{ + // the timer is started by default, and stopped when the first player joins + // this make sure it gets unloaded if for some reason no player joins + m_unloadTimer = std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); +} + +InstanceMap::~InstanceMap() +{ + if(i_data) + { + delete i_data; + i_data = NULL; + } +} + +/* + Do map specific checks to see if the player can enter +*/ +bool InstanceMap::CanEnter(Player *player) +{ + if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) + { + sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode()); + assert(false); + return false; + } + + // cannot enter if the instance is full (player cap), GMs don't count + InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId()); + if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= iTemplate->maxPlayers) + { + sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), iTemplate->maxPlayers, player->GetName()); + player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS); + return false; + } + + // cannot enter while players in the instance are in combat + Group *pGroup = player->GetGroup(); + if(pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId()) + { + player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT); + return false; + } + + return Map::CanEnter(player); +} + +/* + Do map specific checks and add the player to the map if successful. +*/ +bool InstanceMap::Add(Player *player) +{ + // TODO: Not sure about checking player level: already done in HandleAreaTriggerOpcode + // GMs still can teleport player in instance. + // Is it needed? + + { + Guard guard(*this); + if(!CanEnter(player)) + return false; + + // get or create an instance save for the map + InstanceSave *mapSave = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); + if(!mapSave) + { + sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId()); + mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true); + } + + // check for existing instance binds + InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode()); + if(playerBind && playerBind->perm) + { + // cannot enter other instances if bound permanently + if(playerBind->save != mapSave) + { + sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset()); + assert(false); + } + } + else + { + Group *pGroup = player->GetGroup(); + if(pGroup) + { + // solo saves should be reset when entering a group + InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode()); + if(playerBind) + { + sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); + if(groupBind) sLog.outError("InstanceMap::Add: the group is bound to instance %d,%d,%d,%d,%d,%d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); + assert(false); + } + // bind to the group or keep using the group save + if(!groupBind) + pGroup->BindToInstance(mapSave, false); + else + { + // cannot jump to a different instance without resetting it + if(groupBind->save != mapSave) + { + sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d but he is in group %d which is bound to instance %d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), GUID_LOPART(pGroup->GetLeaderGUID()), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); + if(mapSave) + sLog.outError("MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount()); + else + sLog.outError("MapSave NULL"); + if(groupBind->save) + sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount()); + else + sLog.outError("GroupBind save NULL"); + assert(false); + } + // if the group/leader is permanently bound to the instance + // players also become permanently bound when they enter + if(groupBind->perm) + { + WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); + data << uint32(0); + player->GetSession()->SendPacket(&data); + player->BindToInstance(mapSave, true); + } + } + } + else + { + // set up a solo bind or continue using it + if(!playerBind) + player->BindToInstance(mapSave, false); + else + // cannot jump to a different instance without resetting it + assert(playerBind->save == mapSave); + } + } + + if(i_data) i_data->OnPlayerEnter(player); + SetResetSchedule(false); + + i_Players.push_back(player); + player->SendInitWorldStates(); + sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); + // initialize unload state + m_unloadTimer = 0; + m_resetAfterUnload = false; + m_unloadWhenEmpty = false; + } + + // this will acquire the same mutex so it cannot be in the previous block + Map::Add(player); + return true; +} + +void InstanceMap::Remove(Player *player, bool remove) +{ + sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); + i_Players.remove(player); + SetResetSchedule(true); + if(!m_unloadTimer && i_Players.empty()) + m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); + Map::Remove(player, remove); +} + +void InstanceMap::CreateInstanceData(bool load) +{ + if(i_data != NULL) + return; + + InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(GetId()); + if (mInstance) + { + i_script = mInstance->script; + i_data = Script->CreateInstanceData(this); + } + + if(!i_data) + return; + + if(load) + { + // TODO: make a global storage for this + QueryResult* result = CharacterDatabase.PQuery("SELECT data FROM instance WHERE map = '%u' AND id = '%u'", GetId(), i_InstanceId); + if (result) + { + Field* fields = result->Fetch(); + const char* data = fields[0].GetString(); + if(data) + { + sLog.outDebug("Loading instance data for `%s` with id %u", i_script.c_str(), i_InstanceId); + i_data->Load(data); + } + delete result; + } + } + else + { + sLog.outDebug("New instance data, \"%s\" ,initialized!",i_script.c_str()); + i_data->Initialize(); + } +} + +/* + Returns true if there are no players in the instance +*/ +bool InstanceMap::Reset(uint8 method) +{ + // note: since the map may not be loaded when the instance needs to be reset + // the instance must be deleted from the DB by InstanceSaveManager + + if(!i_Players.empty()) + { + if(method == INSTANCE_RESET_ALL) + { + // notify the players to leave the instance so it can be reset + for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + (*itr)->SendResetFailedNotify(GetId()); + } + else + { + if(method == INSTANCE_RESET_GLOBAL) + { + // set the homebind timer for players inside (1 minute) + for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + (*itr)->m_InstanceValid = false; + } + + // the unload timer is not started + // instead the map will unload immediately after the players have left + m_unloadWhenEmpty = true; + m_resetAfterUnload = true; + } + } + else + { + // unloaded at next update + m_unloadTimer = MIN_UNLOAD_DELAY; + m_resetAfterUnload = true; + } + + return i_Players.empty(); +} + +uint32 InstanceMap::GetPlayersCountExceptGMs() const +{ + uint32 count = 0; + for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + if(!(*itr)->isGameMaster()) + ++count; + return count; +} + +void InstanceMap::PermBindAllPlayers(Player *player) +{ + InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); + if(!save) + { + sLog.outError("Cannot bind players, no instance save available for map!\n"); + return; + } + + Group *group = player->GetGroup(); + // group members outside the instance group don't get bound + for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + { + if(*itr) + { + // players inside an instance cannot be bound to other instances + // some players may already be permanently bound, in this case nothing happens + InstancePlayerBind *bind = (*itr)->GetBoundInstance(save->GetMapId(), save->GetDifficulty()); + if(!bind || !bind->perm) + { + (*itr)->BindToInstance(save, true); + WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); + data << uint32(0); + (*itr)->GetSession()->SendPacket(&data); + } + + // if the leader is not in the instance the group will not get a perm bind + if(group && group->GetLeaderGUID() == (*itr)->GetGUID()) + group->BindToInstance(save, true); + } + } +} + +time_t InstanceMap::GetResetTime() +{ + InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); + return save ? save->GetDifficulty() : DIFFICULTY_NORMAL; +} + +void InstanceMap::UnloadAll(bool pForce) +{ + if(!i_Players.empty()) + { + sLog.outError("InstanceMap::UnloadAll: there are still players in the instance at unload, should not happen!"); + for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + if(*itr) (*itr)->TeleportTo((*itr)->m_homebindMapId, (*itr)->m_homebindX, (*itr)->m_homebindY, (*itr)->m_homebindZ, (*itr)->GetOrientation()); + } + + if(m_resetAfterUnload == true) + objmgr.DeleteRespawnTimeForInstance(GetInstanceId()); + + Map::UnloadAll(pForce); +} + +void InstanceMap::SendResetWarnings(uint32 timeLeft) +{ + for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + (*itr)->SendInstanceResetWarning(GetId(), timeLeft); +} + +void InstanceMap::SetResetSchedule(bool on) +{ + // only for normal instances + // the reset time is only scheduled when there are no payers inside + // it is assumed that the reset time will rarely (if ever) change while the reset is scheduled + if(i_Players.empty() && !IsRaid() && !IsHeroic()) + { + InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); + if(!save) sLog.outError("InstanceMap::SetResetSchedule: cannot turn schedule %s, no save available for instance %d of %d", on ? "on" : "off", GetInstanceId(), GetId()); + else sInstanceSaveManager.ScheduleReset(on, save->GetResetTime(), InstanceSaveManager::InstResetEvent(0, GetId(), GetInstanceId())); + } +} + +void InstanceMap::SendToPlayers(WorldPacket const* data) const +{ + for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) + (*itr)->GetSession()->SendPacket(data); +} + +/* ******* Battleground Instance Maps ******* */ + +BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId) + : Map(id, expiry, InstanceId, DIFFICULTY_NORMAL) +{ +} + +BattleGroundMap::~BattleGroundMap() +{ +} + +bool BattleGroundMap::CanEnter(Player * player) +{ + if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) + { + sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow()); + assert(false); + return false; + } + + if(player->GetBattleGroundId() != GetInstanceId()) + return false; + + // player number limit is checked in bgmgr, no need to do it here + + return Map::CanEnter(player); +} + +bool BattleGroundMap::Add(Player * player) +{ + { + Guard guard(*this); + if(!CanEnter(player)) + return false; + i_Players.push_back(player); + // reset instance validity, battleground maps do not homebind + player->m_InstanceValid = true; + } + return Map::Add(player); +} + +void BattleGroundMap::Remove(Player *player, bool remove) +{ + sLog.outDetail("MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); + i_Players.remove(player); + Map::Remove(player, remove); +} + +void BattleGroundMap::SetUnload() +{ + m_unloadTimer = MIN_UNLOAD_DELAY; +} + +void BattleGroundMap::UnloadAll(bool pForce) +{ + while(!i_Players.empty()) + { + PlayerList::iterator itr = i_Players.begin(); + Player * plr = *itr; + if(plr) (plr)->TeleportTo((*itr)->m_homebindMapId, (*itr)->m_homebindX, (*itr)->m_homebindY, (*itr)->m_homebindZ, (*itr)->GetOrientation()); + // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator. + // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop + // note that this remove is not needed if the code works well in other places + i_Players.remove(plr); + } + + Map::UnloadAll(pForce); +} diff --git a/src/game/Map.h b/src/game/Map.h new file mode 100644 index 000000000..6da1e56ae --- /dev/null +++ b/src/game/Map.h @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_MAP_H +#define MANGOS_MAP_H + +#include "Platform/Define.h" +#include "Policies/ThreadingModel.h" +#include "zthread/Lockable.h" +#include "zthread/Mutex.h" +#include "zthread/FairReadWriteLock.h" +#include "Database/DBCStructure.h" +#include "GridDefines.h" +#include "Cell.h" +#include "Object.h" +#include "Timer.h" +#include "SharedDefines.h" +#include "GameSystem/GridRefManager.h" + +#include +#include + +class Unit; +class WorldPacket; +class InstanceData; +class Group; +class InstanceSave; + +namespace ZThread +{ + class Lockable; + class ReadWriteLock; +} + +typedef ZThread::FairReadWriteLock GridRWLock; + +template +struct RGuard +{ + RGuard(MUTEX &l) : i_lock(l.getReadLock()) {} + MaNGOS::GeneralLock i_lock; +}; + +template +struct WGuard +{ + WGuard(MUTEX &l) : i_lock(l.getWriteLock()) {} + MaNGOS::GeneralLock i_lock; +}; + +typedef RGuard GridReadGuard; +typedef WGuard GridWriteGuard; +typedef MaNGOS::SingleThreaded::Lock NullGuard; + +typedef struct +{ + uint16 area_flag[16][16]; + uint8 terrain_type[16][16]; + float liquid_level[128][128]; + float Z[MAP_RESOLUTION][MAP_RESOLUTION]; +}GridMap; + +struct CreatureMover +{ + CreatureMover() : x(0), y(0), z(0), ang(0) {} + CreatureMover(float _x, float _y, float _z, float _ang) : x(_x), y(_y), z(_z), ang(_ang) {} + + float x, y, z, ang; +}; + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct InstanceTemplate +{ + uint32 map; + uint32 parent; + uint32 levelMin; + uint32 levelMax; + uint32 maxPlayers; + uint32 reset_delay; + float startLocX; + float startLocY; + float startLocZ; + float startLocO; + char const* script; +}; + +enum LevelRequirementVsMode +{ + LEVELREQUIREMENT_HEROIC = 70 +}; + +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif + +typedef HM_NAMESPACE::hash_map CreatureMoveList; + +#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface +#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE +#define MIN_UNLOAD_DELAY 1 // immediate unload + +class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::ObjectLevelLockable +{ + public: + Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode); + virtual ~Map(); + + // currently unused for normal maps + virtual bool CanUnload(const uint32& diff); + + virtual bool Add(Player *); + virtual void Remove(Player *, bool); + template void Add(T *); + template void Remove(T *, bool); + + virtual void Update(const uint32&); + + void MessageBroadcast(Player *, WorldPacket *, bool to_self); + void MessageBroadcast(WorldObject *, WorldPacket *); + void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false); + void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist); + + void PlayerRelocation(Player *, float x, float y, float z, float angl); + void CreatureRelocation(Creature *creature, float x, float y, float, float); + + template void Visit(const CellLock &cell, TypeContainerVisitor &visitor); + + inline bool IsRemovalGrid(float x, float y) const + { + GridPair p = MaNGOS::ComputeGridPair(x, y); + return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL ); + } + + bool GetUnloadFlag(const GridPair &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadFlag(); } + void SetUnloadFlag(const GridPair &p, bool unload) { getNGrid(p.x_coord, p.y_coord)->setUnloadFlag(unload); } + void LoadGrid(const Cell& cell, bool no_unload = false); + bool UnloadGrid(const uint32 &x, const uint32 &y, bool pForce); + virtual void UnloadAll(bool pForce); + + void ResetGridExpiry(NGridType &grid, float factor = 1) const + { + grid.ResetTimeTracker((time_t)((float)i_gridExpiry*factor)); + } + + time_t GetGridExpiry(void) const { return i_gridExpiry; } + uint32 GetId(void) const { return i_id; } + + static bool ExistMap(uint32 mapid, int x, int y); + static bool ExistVMap(uint32 mapid, int x, int y); + void LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x, int y); + + static void InitStateMachine(); + static void DeleteStateMachine(); + + // some calls like isInWater should not use vmaps due to processor power + // can return INVALID_HEIGHT if under z+2 z coord not found height + float GetHeight(float x, float y, float z, bool pCheckVMap=true) const; + bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use + + uint16 GetAreaFlag(float x, float y ) const; + uint8 GetTerrainType(float x, float y ) const; + float GetWaterLevel(float x, float y ) const; + bool IsUnderWater(float x, float y, float z) const; + + static uint32 GetAreaId(uint16 areaflag,uint32 map_id); + static uint32 GetZoneId(uint16 areaflag,uint32 map_id); + + uint32 GetAreaId(float x, float y) const + { + return GetAreaId(GetAreaFlag(x,y),i_id); + } + + uint32 GetZoneId(float x, float y) const + { + return GetZoneId(GetAreaFlag(x,y),i_id); + } + + virtual void MoveAllCreaturesInMoveList(); + virtual void RemoveAllObjectsInRemoveList(); + + bool CreatureRespawnRelocation(Creature *c); // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader + + // assert print helper + bool CheckGridIntegrity(Creature* c, bool moved) const; + + uint32 GetInstanceId() { return i_InstanceId; } + uint8 GetSpawnMode() { return (i_spawnMode); } + virtual bool CanEnter(Player* /*player*/) { return true; } + const char* GetMapName() const; + + bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); } + // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable + bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); } + bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); } + bool IsHeroic() const { return i_spawnMode == DIFFICULTY_HEROIC; } + bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); } + bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } + bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); } + + void AddObjectToRemoveList(WorldObject *obj); + void DoDelayedMovesAndRemoves(); + + virtual bool RemoveBones(uint64 guid, float x, float y); + + void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair); + void UpdatePlayerVisibility(Player* player, Cell cell, CellPair cellpair); + void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair); + + void resetMarkedCells() { marked_cells.reset(); } + bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); } + void markCell(uint32 pCellId) { marked_cells.set(pCellId); } + private: + void LoadVMap(int pX, int pY); + void LoadMap(uint32 mapid, uint32 instanceid, int x,int y); + + void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; } + //uint64 CalculateGridMask(const uint32 &y) const; + + void SendInitSelf( Player * player ); + + void SendInitTransports( Player * player ); + void SendRemoveTransports( Player * player ); + + void PlayerRelocationNotify(Player* player, Cell cell, CellPair cellpair); + void CreatureRelocationNotify(Creature *creature, Cell newcell, CellPair newval); + + bool CreatureCellRelocation(Creature *creature, Cell new_cell); + + void AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang); + CreatureMoveList i_creaturesToMove; + + bool loaded(const GridPair &) const; + void EnsureGridLoadedForPlayer(const Cell&, Player*, bool add_player); + void EnsureGridCreated(const GridPair &); + + void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); } + + template void AddType(T *obj); + template void RemoveType(T *obj, bool); + + NGridType* getNGrid(uint32 x, uint32 y) const + { + return i_grids[x][y]; + } + + bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x,y)->isGridObjectDataLoaded(); } + void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); } + + inline void setNGrid(NGridType* grid, uint32 x, uint32 y); + + protected: + typedef MaNGOS::ObjectLevelLockable::Lock Guard; + + MapEntry const* i_mapEntry; + uint8 i_spawnMode; + uint32 i_id; + uint32 i_InstanceId; + uint32 m_unloadTimer; + + private: + typedef GridReadGuard ReadGuard; + typedef GridWriteGuard WriteGuard; + + NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; + GridMap *GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; + std::bitset marked_cells; + + time_t i_gridExpiry; + + std::set i_objectsToRemove; + + // Type specific code for add/remove to/from grid + template + void AddToGrid(T*, NGridType *, Cell const&); + + template + void AddNotifier(T*, Cell const&, CellPair const&); + + template + void RemoveFromGrid(T*, NGridType *, Cell const&); + + template + void DeleteFromWorld(T*); +}; + +enum InstanceResetMethod +{ + INSTANCE_RESET_ALL, + INSTANCE_RESET_CHANGE_DIFFICULTY, + INSTANCE_RESET_GLOBAL, + INSTANCE_RESET_GROUP_DISBAND, + INSTANCE_RESET_GROUP_JOIN, + INSTANCE_RESET_RESPAWN_DELAY +}; + +class MANGOS_DLL_SPEC InstanceMap : public Map +{ + public: + typedef std::list PlayerList; // online players only + + InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode); + ~InstanceMap(); + bool Add(Player *); + void Remove(Player *, bool); + void Update(const uint32&); + void CreateInstanceData(bool load); + bool Reset(uint8 method); + std::string GetScript() { return i_script; } + InstanceData* GetInstanceData() { return i_data; } + void PermBindAllPlayers(Player *player); + PlayerList const& GetPlayers() const { return i_Players;} + void SendToPlayers(WorldPacket const* data) const; + time_t GetResetTime(); + void UnloadAll(bool pForce); + bool CanEnter(Player* player); + uint32 GetPlayersCountExceptGMs() const; + uint32 HavePlayers() const { return !i_Players.empty(); } + void SendResetWarnings(uint32 timeLeft); + void SetResetSchedule(bool on); + private: + bool m_resetAfterUnload; + bool m_unloadWhenEmpty; + InstanceData* i_data; + std::string i_script; + // only online players that are inside the instance currently + // TODO ? - use the grid instead to access the players + PlayerList i_Players; +}; + +class MANGOS_DLL_SPEC BattleGroundMap : public Map +{ + public: + typedef std::list PlayerList; // online players only + + BattleGroundMap(uint32 id, time_t, uint32 InstanceId); + ~BattleGroundMap(); + + bool Add(Player *); + void Remove(Player *, bool); + bool CanEnter(Player* player); + void SetUnload(); + void UnloadAll(bool pForce); + private: + PlayerList i_Players; +}; + +/*inline +uint64 +Map::CalculateGridMask(const uint32 &y) const +{ + uint64 mask = 1; + mask <<= y; + return mask; +} +*/ + +template +inline void +Map::Visit(const CellLock &cell, TypeContainerVisitor &visitor) +{ + const uint32 x = cell->GridX(); + const uint32 y = cell->GridY(); + const uint32 cell_x = cell->CellX(); + const uint32 cell_y = cell->CellY(); + + if( !cell->NoCreate() || loaded(GridPair(x,y)) ) + { + EnsureGridLoadedForPlayer(cell, NULL, false); + //LOCK_TYPE guard(i_info[x][y]->i_lock); + getNGrid(x, y)->Visit(cell_x, cell_y, visitor); + } +} +#endif diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp new file mode 100644 index 000000000..741e0a996 --- /dev/null +++ b/src/game/MapInstanced.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MapInstanced.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "BattleGround.h" +#include "VMapFactory.h" +#include "InstanceSaveMgr.h" +#include "World.h" + +MapInstanced::MapInstanced(uint32 id, time_t expiry, uint32 aInstanceId) : Map(id, expiry, 0, 0) +{ + // initialize instanced maps list + m_InstancedMaps.clear(); + // fill with zero + memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16)); +} + +void MapInstanced::Update(const uint32& t) +{ + // take care of loaded GridMaps (when unused, unload it!) + Map::Update(t); + + // update the instanced maps + InstancedMaps::iterator i = m_InstancedMaps.begin(); + + while (i != m_InstancedMaps.end()) + { + if(i->second->CanUnload(t)) + { + DestroyInstance(i); // iterator incremented + } + else + { + // update only here, because it may schedule some bad things before delete + i->second->Update(t); + ++i; + } + } +} + +void MapInstanced::MoveAllCreaturesInMoveList() +{ + for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) + { + i->second->MoveAllCreaturesInMoveList(); + } + + Map::MoveAllCreaturesInMoveList(); +} + +void MapInstanced::RemoveAllObjectsInRemoveList() +{ + for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) + { + i->second->RemoveAllObjectsInRemoveList(); + } + + Map::RemoveAllObjectsInRemoveList(); +} + +bool MapInstanced::RemoveBones(uint64 guid, float x, float y) +{ + bool remove_result = false; + + for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) + { + remove_result = remove_result || i->second->RemoveBones(guid, x, y); + } + + return remove_result || Map::RemoveBones(guid,x,y); +} + +void MapInstanced::UnloadAll(bool pForce) +{ + // Unload instanced maps + for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) + i->second->UnloadAll(pForce); + + // Delete the maps only after everything is unloaded to prevent crashes + for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); i++) + delete i->second; + + m_InstancedMaps.clear(); + + // Unload own grids (just dummy(placeholder) grids, neccesary to unload GridMaps!) + Map::UnloadAll(pForce); +} + +/* +- return the right instance for the object, based on its InstanceId +- create the instance if it's not created already +- the player is not actually added to the instance (only in InstanceMap::Add) +*/ +Map* MapInstanced::GetInstance(const WorldObject* obj) +{ + uint32 CurInstanceId = obj->GetInstanceId(); + Map* map = NULL; + + if (obj->GetMapId() == GetId() && CurInstanceId != 0) + { + // the object wants to be put in a certain instance of this map + map = _FindMap(CurInstanceId); + if(!map) + { + // For players if the instanceId is set, it's assumed they are already in a map, + // hence the map must be loaded. For Creatures, GameObjects etc the map must exist + // prior to calling GetMap, they are not allowed to create maps for themselves. + sLog.outError("GetInstance: object %s(%d), typeId %d, in world %d, should be in map %d,%d but that's not loaded yet.", obj->GetName(), obj->GetGUIDLow(), obj->GetTypeId(), obj->IsInWorld(), obj->GetMapId(), obj->GetInstanceId()); + assert(false); + } + return(map); + } + else + { + // instance not specified, find an existing or create a new one + if(obj->GetTypeId() != TYPEID_PLAYER) + { + sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u TypeID: %u) is in map %d,%d and requested base map instance of map %d, this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), obj->GetMapId(), obj->GetInstanceId(), GetId()); + assert(false); + return NULL; + } + else + { + uint32 NewInstanceId = 0; // instanceId of the resulting map + Player* player = (Player*)obj; + + // TODO: battlegrounds and arenas + + InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty()); + InstanceSave *pSave = pBind ? pBind->save : NULL; + + // the player's permanet player bind is taken into consideration first + // then the player's group bind and finally the solo bind. + if(!pBind || !pBind->perm) + { + InstanceGroupBind *groupBind = NULL; + Group *group = player->GetGroup(); + // use the player's difficulty setting (it may not be the same as the group's) + if(group && (groupBind = group->GetBoundInstance(GetId(), player->GetDifficulty()))) + pSave = groupBind->save; + } + + if(pSave) + { + // solo/perm/group + NewInstanceId = pSave->GetInstanceId(); + map = _FindMap(NewInstanceId); + // it is possible that the save exists but the map doesn't + if(!map) + map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty()); + return map; + } + else + { + // if no instanceId via group members or instance saves is found + // the instance will be created for the first time + NewInstanceId = MapManager::Instance().GenerateInstanceId(); + return CreateInstance(NewInstanceId, NULL, player->GetDifficulty()); + } + } + } +} + +InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty) +{ + // load/create a map + Guard guard(*this); + + // make sure we have a valid map id + const MapEntry* entry = sMapStore.LookupEntry(GetId()); + if(!entry) + { + sLog.outError("CreateInstance: no entry for map %d", GetId()); + assert(false); + } + const InstanceTemplate * iTemplate = objmgr.GetInstanceTemplate(GetId()); + if(!iTemplate) + { + sLog.outError("CreateInstance: no instance template for map %d", GetId()); + assert(false); + } + + // some instances only have one difficulty + if(!entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + + sLog.outDebug("MapInstanced::CreateInstance: %smap instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal"); + + InstanceMap *map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty); + assert(map->IsDungeon()); + + bool load_data = save != NULL; + map->CreateInstanceData(load_data); + + m_InstancedMaps[InstanceId] = map; + return map; +} + +BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId) +{ + // load/create a map + Guard guard(*this); + + sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId()); + + BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId); + assert(map->IsBattleGroundOrArena()); + + m_InstancedMaps[InstanceId] = map; + return map; +} + +void MapInstanced::DestroyInstance(uint32 InstanceId) +{ + InstancedMaps::iterator itr = m_InstancedMaps.find(InstanceId); + if(itr != m_InstancedMaps.end()) + DestroyInstance(itr); +} + +// increments the iterator after erase +void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr) +{ + itr->second->UnloadAll(true); + // should only unload VMaps if this is the last instance and grid unloading is enabled + if(m_InstancedMaps.size() <= 1 && sWorld.getConfig(CONFIG_GRID_UNLOAD)) + { + VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(itr->second->GetId()); + // in that case, unload grids of the base map, too + // so in the next map creation, (EnsureGridCreated actually) VMaps will be reloaded + Map::UnloadAll(true); + } + // erase map + delete itr->second; + m_InstancedMaps.erase(itr++); +} diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h new file mode 100644 index 000000000..d4535b42f --- /dev/null +++ b/src/game/MapInstanced.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_MAP_INSTANCED_H +#define MANGOS_MAP_INSTANCED_H + +#include "Map.h" +#include "InstanceSaveMgr.h" + +class MANGOS_DLL_DECL MapInstanced : public Map +{ + friend class MapManager; + public: + typedef HM_NAMESPACE::hash_map< uint32, Map* > InstancedMaps; + + MapInstanced(uint32 id, time_t, uint32 aInstanceId); + ~MapInstanced() {} + + // functions overwrite Map versions + void Update(const uint32&); + void MoveAllCreaturesInMoveList(); + void RemoveAllObjectsInRemoveList(); + bool RemoveBones(uint64 guid, float x, float y); + void UnloadAll(bool pForce); + + Map* GetInstance(const WorldObject* obj); + Map* FindMap(uint32 InstanceId) { return _FindMap(InstanceId); } + void DestroyInstance(uint32 InstanceId); + void DestroyInstance(InstancedMaps::iterator &itr); + void AddGridMapReference(const GridPair &p) { ++GridMapReference[p.x_coord][p.y_coord]; } + void RemoveGridMapReference(const GridPair &p) + { + --GridMapReference[p.x_coord][p.y_coord]; + if (!GridMapReference[p.x_coord][p.y_coord]) { SetUnloadFlag(GridPair(63-p.x_coord,63-p.y_coord), true); } + } + + InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; } + + private: + + InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty); + BattleGroundMap* CreateBattleGround(uint32 InstanceId); + + InstancedMaps m_InstancedMaps; + + Map* _FindMap(uint32 InstanceId) + { + InstancedMaps::iterator i = m_InstancedMaps.find(InstanceId); + + return(i == m_InstancedMaps.end() ? NULL : i->second); + } + + uint16 GridMapReference[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]; +}; +#endif diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp new file mode 100644 index 000000000..a8d897bad --- /dev/null +++ b/src/game/MapManager.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MapManager.h" +#include "InstanceSaveMgr.h" +#include "Policies/SingletonImp.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "ObjectAccessor.h" +#include "Transports.h" +#include "GridDefines.h" +#include "MapInstanced.h" +#include "DestinationHolderImp.h" +#include "World.h" +#include "CellImpl.h" +#include "Corpse.h" +#include "ObjectMgr.h" + +#define CLASS_LOCK MaNGOS::ClassLevelLockable +INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK); +INSTANTIATE_CLASS_MUTEX(MapManager, ZThread::Mutex); + +extern GridState* si_GridStates[]; // debugging code, should be deleted some day + +MapManager::MapManager() : i_gridCleanUpDelay(sWorld.getConfig(CONFIG_INTERVAL_GRIDCLEAN)) +{ + i_timer.SetInterval(sWorld.getConfig(CONFIG_INTERVAL_MAPUPDATE)); +} + +MapManager::~MapManager() +{ + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) + delete iter->second; + + for(TransportSet::iterator i = m_Transports.begin(); i != m_Transports.end(); ++i) + delete *i; + + Map::DeleteStateMachine(); +} + +void +MapManager::Initialize() +{ + Map::InitStateMachine(); + + // debugging code, should be deleted some day + { + for(int i=0;icheckMagic()) + { + ok = false; + si_GridStates[i]->setMagic(); + } + #endif + } + if(!ok) + ++i_GridStateErrorCount; + if(i_GridStateErrorCount > 2) + assert(false); // force a crash. Too many errors +} + +Map* +MapManager::_GetBaseMap(uint32 id) +{ + Map *m = _findMap(id); + + if( m == NULL ) + { + Guard guard(*this); + + const MapEntry* entry = sMapStore.LookupEntry(id); + if (entry && entry->IsDungeon()) + { + m = new MapInstanced(id, i_gridCleanUpDelay, 0); + } + else + { + m = new Map(id, i_gridCleanUpDelay, 0, 0); + } + i_maps[id] = m; + } + + assert(m != NULL); + return m; +} + +Map* MapManager::GetMap(uint32 id, const WorldObject* obj) +{ + //if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId()); + Map *m = _GetBaseMap(id); + + if (m && obj && m->Instanceable()) m = ((MapInstanced*)m)->GetInstance(obj); + + return m; +} + +Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) +{ + Map *map = FindMap(mapid); + if(!map) return NULL; + if(!map->Instanceable()) return instanceId == 0 ? map : NULL; + return ((MapInstanced*)map)->FindMap(instanceId); +} + +/* + checks that do not require a map to be created + will send transfer error messages on fail +*/ +bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) +{ + const MapEntry *entry = sMapStore.LookupEntry(mapid); + if(!entry) return false; + const char *mapName = entry->name[player->GetSession()->GetSessionDbcLocale()]; + + if(entry->map_type == MAP_INSTANCE || entry->map_type == MAP_RAID) + { + if (entry->map_type == MAP_RAID) + { + // GMs can avoid raid limitations + if(!player->isGameMaster() && !sWorld.getConfig(CONFIG_INSTANCE_IGNORE_RAID)) + { + // can only enter in a raid group + Group* group = player->GetGroup(); + if (!group || !group->isRaidGroup()) + { + // probably there must be special opcode, because client has this string constant in GlobalStrings.lua + // TODO: this is not a good place to send the message + player->GetSession()->SendAreaTriggerMessage("You must be in a raid group to enter %s instance", mapName); + sLog.outDebug("MAP: Player '%s' must be in a raid group to enter instance of '%s'", player->GetName(), mapName); + return false; + } + } + } + + //The player has a heroic mode and tries to enter into instance which has no a heroic mode + if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC) + { + player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY2); //Send aborted message + return false; + } + + if (!player->isAlive()) + { + if(Corpse *corpse = player->GetCorpse()) + { + // let enter in ghost mode in instance that connected to inner instance with corpse + uint32 instance_map = corpse->GetMapId(); + do + { + if(instance_map==mapid) + break; + + InstanceTemplate const* instance = objmgr.GetInstanceTemplate(instance_map); + instance_map = instance ? instance->parent : 0; + } + while (instance_map); + + if (!instance_map) + { + player->GetSession()->SendAreaTriggerMessage("You cannot enter %s while in a ghost mode", mapName); + sLog.outDebug("MAP: Player '%s' doesn't has a corpse in instance '%s' and can't enter", player->GetName(), mapName); + return false; + } + sLog.outDebug("MAP: Player '%s' has corpse in instance '%s' and can enter", player->GetName(), mapName); + } + else + { + sLog.outDebug("Map::CanEnter - player '%s' is dead but doesn't have a corpse!", player->GetName()); + } + } + + // TODO: move this to a map dependent location + /*if(i_data && i_data->IsEncounterInProgress()) + { + sLog.outDebug("MAP: Player '%s' can't enter instance '%s' while an encounter is in progress.", player->GetName(), GetMapName()); + player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT); + return(false); + }*/ + return true; + } + else + return true; +} + +void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode) +{ + Map *m = _GetBaseMap(mapid); + if (m && m->Instanceable()) + ((MapInstanced*)m)->DestroyInstance(instanceId); +} + +void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y) +{ + bool remove_result = _GetBaseMap(mapid)->RemoveBones(guid, x, y); + + if (!remove_result) + { + sLog.outDebug("Bones %u not found in world. Delete from DB also.", GUID_LOPART(guid)); + } +} + +void +MapManager::Update(time_t diff) +{ + i_timer.Update(diff); + if( !i_timer.Passed() ) + return; + + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) + { + checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day + iter->second->Update(i_timer.GetCurrent()); + } + + ObjectAccessor::Instance().Update(i_timer.GetCurrent()); + for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter) + (*iter)->Update(i_timer.GetCurrent()); + + i_timer.SetCurrent(0); +} + +void MapManager::DoDelayedMovesAndRemoves() +{ + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) + iter->second->DoDelayedMovesAndRemoves(); +} + +bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y) +{ + GridPair p = MaNGOS::ComputeGridPair(x,y); + + int gx=63-p.x_coord; + int gy=63-p.y_coord; + + return Map::ExistMap(mapid,gx,gy) && Map::ExistVMap(mapid,gx,gy); +} + +bool MapManager::IsValidMAP(uint32 mapid) +{ + MapEntry const* mEntry = sMapStore.LookupEntry(mapid); + return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid)); +} + +void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload) +{ + CellPair p = MaNGOS::ComputeCellPair(x,y); + Cell cell(p); + GetMap(mapid, obj)->LoadGrid(cell,no_unload); +} + +void MapManager::UnloadAll() +{ + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) + iter->second->UnloadAll(true); + + while(!i_maps.empty()) + { + delete i_maps.begin()->second; + i_maps.erase(i_maps.begin()); + } +} + +void MapManager::InitMaxInstanceId() +{ + i_MaxInstanceId = 0; + + QueryResult *result = CharacterDatabase.Query( "SELECT MAX(id) FROM instance" ); + if( result ) + { + i_MaxInstanceId = result->Fetch()[0].GetUInt32(); + delete result; + } +} + +uint32 MapManager::GetNumInstances() +{ + uint32 ret = 0; + for(MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) + { + Map *map = itr->second; + if(!map->Instanceable()) continue; + MapInstanced::InstancedMaps &maps = ((MapInstanced *)map)->GetInstancedMaps(); + for(MapInstanced::InstancedMaps::iterator mitr = maps.begin(); mitr != maps.end(); ++mitr) + if(mitr->second->IsDungeon()) ret++; + } + return ret; +} + +uint32 MapManager::GetNumPlayersInInstances() +{ + uint32 ret = 0; + for(MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) + { + Map *map = itr->second; + if(!map->Instanceable()) continue; + MapInstanced::InstancedMaps &maps = ((MapInstanced *)map)->GetInstancedMaps(); + for(MapInstanced::InstancedMaps::iterator mitr = maps.begin(); mitr != maps.end(); ++mitr) + if(mitr->second->IsDungeon()) + ret += ((InstanceMap*)mitr->second)->GetPlayers().size(); + } + return ret; +} diff --git a/src/game/MapManager.h b/src/game/MapManager.h new file mode 100644 index 000000000..4dacca09d --- /dev/null +++ b/src/game/MapManager.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_MAPMANAGER_H +#define MANGOS_MAPMANAGER_H + +#include "Platform/Define.h" +#include "Policies/Singleton.h" +#include "zthread/Mutex.h" +#include "Common.h" +#include "Map.h" +#include "GridStates.h" + +class Transport; + +class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton > +{ + + friend class MaNGOS::OperatorNew; + typedef HM_NAMESPACE::hash_map MapMapType; + typedef std::pair::iterator, bool> MapMapPair; + + public: + + Map* GetMap(uint32, const WorldObject* obj); + Map* FindMap(uint32 mapid) { return _findMap(mapid); } + Map* FindMap(uint32 mapid, uint32 instanceId); + + // only const version for outer users + Map const* GetBaseMap(uint32 id) const { return const_cast(this)->_GetBaseMap(id); } + void DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode); + + inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const + { + Map const* m = GetBaseMap(mapid); + return m->GetAreaFlag(x, y); + } + inline uint32 GetAreaId(uint32 mapid, float x, float y) { return Map::GetAreaId(GetAreaFlag(mapid, x, y),mapid); } + inline uint32 GetZoneId(uint32 mapid, float x, float y) { return Map::GetZoneId(GetAreaFlag(mapid, x, y),mapid); } + + void Initialize(void); + void Update(time_t); + + inline void SetGridCleanUpDelay(uint32 t) + { + if( t < MIN_GRID_DELAY ) + i_gridCleanUpDelay = MIN_GRID_DELAY; + else + i_gridCleanUpDelay = t; + } + + inline void SetMapUpdateInterval(uint32 t) + { + if( t > MIN_MAP_UPDATE_DELAY ) + t = MIN_MAP_UPDATE_DELAY; + + i_timer.SetInterval(t); + i_timer.Reset(); + } + + void LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload = false); + void UnloadAll(); + + static bool ExistMapAndVMap(uint32 mapid, float x, float y); + static bool IsValidMAP(uint32 mapid); + + static bool IsValidMapCoord(uint32 mapid, float x,float y) + { + return IsValidMAP(mapid) && MaNGOS::IsValidMapCoord(x,y); + } + + static bool IsValidMapCoord(uint32 mapid, float x,float y,float z) + { + return IsValidMAP(mapid) && MaNGOS::IsValidMapCoord(x,y,z); + } + + static bool IsValidMapCoord(uint32 mapid, float x,float y,float z,float o) + { + return IsValidMAP(mapid) && MaNGOS::IsValidMapCoord(x,y,z,o); + } + + void DoDelayedMovesAndRemoves(); + + void LoadTransports(); + + typedef std::set TransportSet; + TransportSet m_Transports; + + typedef std::map TransportMap; + TransportMap m_TransportsByMap; + + bool CanPlayerEnter(uint32 mapid, Player* player); + void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y); + inline uint32 GenerateInstanceId() { return ++i_MaxInstanceId; } + void InitMaxInstanceId(); + + /* statistics */ + uint32 GetNumInstances(); + uint32 GetNumPlayersInInstances(); + + private: + // debugging code, should be deleted some day + void checkAndCorrectGridStatesArray(); // just for debugging to find some memory overwrites + GridState* i_GridStates[MAX_GRID_STATE]; // shadow entries to the global array in Map.cpp + int i_GridStateErrorCount; + private: + MapManager(); + ~MapManager(); + + MapManager(const MapManager &); + MapManager& operator=(const MapManager &); + + Map* _GetBaseMap(uint32 id); + Map* _findMap(uint32 id) const + { + MapMapType::const_iterator iter = i_maps.find(id); + return (iter == i_maps.end() ? NULL : iter->second); + } + + typedef MaNGOS::ClassLevelLockable::Lock Guard; + uint32 i_gridCleanUpDelay; + MapMapType i_maps; + IntervalTimer i_timer; + + uint32 i_MaxInstanceId; +}; +#endif diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp new file mode 100644 index 000000000..238bfa883 --- /dev/null +++ b/src/game/MiscHandler.cpp @@ -0,0 +1,1756 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Language.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "Opcodes.h" +#include "Log.h" +#include "Player.h" +#include "World.h" +#include "ObjectMgr.h" +#include "WorldSession.h" +#include "Auth/BigNumber.h" +#include "Auth/Sha1.h" +#include "UpdateData.h" +#include "LootMgr.h" +#include "Chat.h" +#include "ScriptCalls.h" +#include +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Object.h" +#include "BattleGround.h" +#include "SpellAuras.h" +#include "Pet.h" +#include "SocialMgr.h" + +void WorldSession::HandleRepopRequestOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: Recvd CMSG_REPOP_REQUEST Message" ); + + if(GetPlayer()->isAlive()||GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + return; + + // the world update order is sessions, players, creatures + // the netcode runs in parallel with all of these + // creatures can kill players + // so if the server is lagging enough the player can + // release spirit after he's killed but before he is updated + if(GetPlayer()->getDeathState() == JUST_DIED) + { + sLog.outDebug("HandleRepopRequestOpcode: got request after player %s(%d) was killed and before he was updated", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); + GetPlayer()->KillPlayer(); + } + + //this is spirit release confirm? + GetPlayer()->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true); + GetPlayer()->BuildPlayerRepop(); + GetPlayer()->RepopAtGraveyard(); +} + +void WorldSession::HandleWhoOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+4+1+1+4+4+4+4); + + sLog.outDebug( "WORLD: Recvd CMSG_WHO Message" ); + //recv_data.hexlike(); + + uint32 clientcount = 0; + + uint32 level_min, level_max, racemask, classmask, zones_count, str_count; + uint32 zoneids[10]; // 10 is client limit + std::string player_name, guild_name; + + recv_data >> level_min; // maximal player level, default 0 + recv_data >> level_max; // minimal player level, default 100 + recv_data >> player_name; // player name, case sensitive... + + // recheck + CHECK_PACKET_SIZE(recv_data,4+4+(player_name.size()+1)+1+4+4+4+4); + + recv_data >> guild_name; // guild name, case sensitive... + + // recheck + CHECK_PACKET_SIZE(recv_data,4+4+(player_name.size()+1)+(guild_name.size()+1)+4+4+4+4); + + recv_data >> racemask; // race mask + recv_data >> classmask; // class mask + recv_data >> zones_count; // zones count, client limit=10 (2.0.10) + + if(zones_count > 10) + return; // can't be received from real client or broken packet + + // recheck + CHECK_PACKET_SIZE(recv_data,4+4+(player_name.size()+1)+(guild_name.size()+1)+4+4+4+(4*zones_count)+4); + + for(uint32 i = 0; i < zones_count; i++) + { + uint32 temp; + recv_data >> temp; // zone id, 0 if zone is unknown... + zoneids[i] = temp; + sLog.outDebug("Zone %u: %u", i, zoneids[i]); + } + + recv_data >> str_count; // user entered strings count, client limit=4 (checked on 2.0.10) + + if(str_count > 4) + return; // can't be received from real client or broken packet + + // recheck + CHECK_PACKET_SIZE(recv_data,4+4+(player_name.size()+1)+(guild_name.size()+1)+4+4+4+(4*zones_count)+4+(1*str_count)); + + sLog.outDebug("Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", level_min, level_max, player_name.c_str(), guild_name.c_str(), racemask, classmask, zones_count, str_count); + + std::wstring str[4]; // 4 is client limit + for(uint32 i = 0; i < str_count; i++) + { + // recheck (have one more byte) + CHECK_PACKET_SIZE(recv_data,recv_data.rpos()); + + std::string temp; + recv_data >> temp; // user entered string, it used as universal search pattern(guild+player name)? + + if(!Utf8toWStr(temp,str[i])) + continue; + + wstrToLower(str[i]); + + sLog.outDebug("String %u: %s", i, str[i].c_str()); + } + + std::wstring wplayer_name; + std::wstring wguild_name; + if(!(Utf8toWStr(player_name, wplayer_name) && Utf8toWStr(guild_name, wguild_name))) + return; + wstrToLower(wplayer_name); + wstrToLower(wguild_name); + + // client send in case not set max level value 100 but mangos support 255 max level, + // update it to show GMs with characters after 100 level + if(level_max >= 100) + level_max = 255; + + uint32 team = _player->GetTeam(); + uint32 security = GetSecurity(); + bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); + bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST); + + WorldPacket data( SMSG_WHO, 50 ); // guess size + data << clientcount; // clientcount place holder + data << clientcount; // clientcount place holder + + //TODO: Guard Player map + HashMapHolder::MapType& m = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::iterator itr = m.begin(); itr != m.end(); ++itr) + { + if (security == SEC_PLAYER) + { + // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST + if (itr->second->GetTeam() != team && !allowTwoSideWhoList ) + continue; + + // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST + if ((itr->second->GetSession()->GetSecurity() > SEC_PLAYER && !gmInWhoList)) + continue; + } + + // check if target is globally visible for player + if (!(itr->second->IsVisibleGloballyFor(_player))) + continue; + + // check if target's level is in level range + uint32 lvl = itr->second->getLevel(); + if (lvl < level_min || lvl > level_max) + continue; + + // check if class matches classmask + uint32 class_ = itr->second->getClass(); + if (!(classmask & (1 << class_))) + continue; + + // check if race matches racemask + uint32 race = itr->second->getRace(); + if (!(racemask & (1 << race))) + continue; + + uint32 pzoneid = itr->second->GetZoneId(); + + bool z_show = true; + for(uint32 i = 0; i < zones_count; i++) + { + if(zoneids[i] == pzoneid) + { + z_show = true; + break; + } + + z_show = false; + } + if (!z_show) + continue; + + std::string pname = itr->second->GetName(); + std::wstring wpname; + if(!Utf8toWStr(pname,wpname)) + continue; + wstrToLower(wpname); + + if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos)) + continue; + + std::string gname = objmgr.GetGuildNameById(itr->second->GetGuildId()); + std::wstring wgname; + if(!Utf8toWStr(gname,wgname)) + continue; + wstrToLower(wgname); + + if (!(wguild_name.empty() || wgname.find(wguild_name) != std::wstring::npos)) + continue; + + std::string aname; + if(AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId())) + aname = areaEntry->area_name[GetSessionDbcLocale()]; + + bool s_show = true; + for(uint32 i = 0; i < str_count; i++) + { + if (!str[i].empty()) + { + if (wgname.find(str[i]) != std::wstring::npos || + wpname.find(str[i]) != std::wstring::npos || + Utf8FitTo(aname, str[i]) ) + { + s_show = true; + break; + } + s_show = false; + } + } + if (!s_show) + continue; + + data << pname; // player name + data << gname; // guild name + data << uint32( lvl ); // player level + data << uint32( class_ ); // player class + data << uint32( race ); // player race + data << uint8(0); // new 2.4.0 + data << uint32( pzoneid ); // player zone id + + // 49 is maximum player count sent to client + if ((++clientcount) == 49) + break; + } + + data.put( 0, clientcount ); //insert right count + data.put( sizeof(uint32), clientcount ); //insert right count + + SendPacket(&data); + sLog.outDebug( "WORLD: Send SMSG_WHO Message" ); +} + +void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - %u", GetSecurity() ); + + if (uint64 lguid = GetPlayer()->GetLootGUID()) + DoLootRelease(lguid); + + //instant logout for admins, gm's, mod's + if( GetSecurity() > SEC_PLAYER ) + { + LogoutPlayer(true); + return; + } + + //Can not logout if... + if( GetPlayer()->isInCombat() || //...is in combat + GetPlayer()->duel || //...is in Duel + //...is jumping ...is falling + GetPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING)) + { + WorldPacket data( SMSG_LOGOUT_RESPONSE, (2+4) ) ; + data << (uint8)0xC; + data << uint32(0); + data << uint8(0); + SendPacket( &data ); + LogoutRequest(0); + return; + } + + //instant logout in taverns/cities or on taxi + if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight()) + { + LogoutPlayer(true); + return; + } + + // not set flags if player can't free move to prevent lost state at logout cancel + if(GetPlayer()->CanFreeMove()) + { + GetPlayer()->SetStandState(PLAYER_STATE_SIT); + + WorldPacket data( SMSG_FORCE_MOVE_ROOT, (8+4) ); // guess size + data.append(GetPlayer()->GetPackGUID()); + data << (uint32)2; + SendPacket( &data ); + GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + } + + WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 ); + data << uint32(0); + data << uint8(0); + SendPacket( &data ); + LogoutRequest(time(NULL)); +} + +void WorldSession::HandlePlayerLogoutOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: Recvd CMSG_PLAYER_LOGOUT Message" ); +} + +void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: Recvd CMSG_LOGOUT_CANCEL Message" ); + + LogoutRequest(0); + + WorldPacket data( SMSG_LOGOUT_CANCEL_ACK, 0 ); + SendPacket( &data ); + + // not remove flags if can't free move - its not set in Logout request code. + if(GetPlayer()->CanFreeMove()) + { + //!we can move again + data.Initialize( SMSG_FORCE_MOVE_UNROOT, 8 ); // guess size + data.append(GetPlayer()->GetPackGUID()); + data << uint32(0); + SendPacket( &data ); + + //! Stand Up + GetPlayer()->SetStandState(PLAYER_STATE_NONE); + + //! DISABLE_ROTATE + GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + } + + sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" ); +} + +void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text) +{ + int len = text ? strlen(text) : 0; + WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) ); + data << uint32(status); // standard 0x0A, 0x06 if text present + if(status == 6) + { + data << text; // ticket text + data << uint8(0x7); // ticket category + data << float(0); // time from ticket creation? + data << float(0); // const + data << float(0); // const + data << uint8(0); // const + data << uint8(0); // const + } + SendPacket( &data ); +} + +void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ ) +{ + WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 ); + data << (uint32)time(NULL); + data << (uint32)0; + SendPacket( &data ); + + uint64 guid; + Field *fields; + guid = GetPlayer()->GetGUID(); + + QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(ticket_id) FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid)); + + if (result) + { + int cnt; + fields = result->Fetch(); + cnt = fields[0].GetUInt32(); + delete result; + + if ( cnt > 0 ) + { + QueryResult *result2 = CharacterDatabase.PQuery("SELECT ticket_text FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid)); + if(result2) + { + Field *fields2 = result2->Fetch(); + SendGMTicketGetTicket(0x06,fields2[0].GetString()); + delete result2; + } + } + else + SendGMTicketGetTicket(0x0A,0); + } +} + +void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1); + + std::string ticketText; + recv_data >> ticketText; + + CharacterDatabase.escape_string(ticketText); + CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", ticketText.c_str(), _player->GetGUIDLow()); +} + +void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ ) +{ + uint32 guid = GetPlayer()->GetGUIDLow(); + + CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1",guid); + + WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 ); + data << uint32(9); + SendPacket( &data ); + + SendGMTicketGetTicket(0x0A, 0); +} + +void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4); + + uint32 map; + float x, y, z; + std::string ticketText = ""; + uint32 unk1, unk2; + + recv_data >> map >> x >> y >> z; // last check 2.4.3 + recv_data >> ticketText; + + // recheck + CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4); + + recv_data >> unk1 >> unk2; + // note: the packet might contain more data, but the exact structure of that is unknown + + sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2); + + CharacterDatabase.escape_string(ticketText); + + QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM character_ticket WHERE guid = '%u'", _player->GetGUIDLow()); + + if (result) + { + int cnt; + Field *fields = result->Fetch(); + cnt = fields[0].GetUInt32(); + delete result; + + if ( cnt > 0 ) + { + WorldPacket data( SMSG_GMTICKET_CREATE, 4 ); + data << uint32(1); + SendPacket( &data ); + } + else + { + CharacterDatabase.PExecute("INSERT INTO character_ticket (guid,ticket_text) VALUES ('%u', '%s')", _player->GetGUIDLow(), ticketText.c_str()); + + WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 ); + data << (uint32)time(NULL); + data << (uint32)0; + SendPacket( &data ); + + data.Initialize( SMSG_GMTICKET_CREATE, 4 ); + data << uint32(2); + SendPacket( &data ); + DEBUG_LOG("update the ticket\n"); + + //TODO: Guard player map + HashMapHolder::MapType &m = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::iterator itr = m.begin(); itr != m.end(); ++itr) + { + if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets()) + ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName()); + } + } + } +} + +void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ ) +{ + WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 ); + data << uint32(1); // we can also disable ticket system by sending 0 value + + SendPacket( &data ); +} + +void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data) +{ + // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3 + CHECK_PACKET_SIZE(recv_data,4+4); + uint32 x; + recv_data >> x; // answer range? (6 = 0-5?) + sLog.outDebug("SURVEY: X = %u", x); + + uint8 result[10]; + memset(result, 0, sizeof(result)); + for( int i = 0; i < 10; ++i) + { + CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4); + uint32 questionID; + recv_data >> questionID; // GMSurveyQuestions.dbc + if (!questionID) + break; + + CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1); + uint8 value; + std::string unk_text; + recv_data >> value; // answer + recv_data >> unk_text; // always empty? + + result[i] = value; + sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str()); + } + + CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1); + std::string comment; + recv_data >> comment; // addional comment + sLog.outDebug("SURVEY: comment %s", comment.c_str()); + + // TODO: chart this data in some way +} + +void WorldSession::HandleTogglePvP( WorldPacket & recv_data ) +{ + // this opcode can be used in two ways: Either set explicit new status or toggle old status + if(recv_data.size() == 1) + { + bool newPvPStatus; + recv_data >> newPvPStatus; + GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus); + } + else + { + GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP); + } + + if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) + { + if(!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.endTimer != 0) + GetPlayer()->UpdatePvP(true, true); + } + else + { + if(!GetPlayer()->pvpInfo.inHostileArea && GetPlayer()->IsPvP()) + GetPlayer()->pvpInfo.endTimer = time(NULL); // start toggle-off + } +} + +void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 newZone; + recv_data >> newZone; + + sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone); + + if(newZone != _player->GetZoneId()) + GetPlayer()->SendInitWorldStates(); // only if really enters to new zone, not just area change, works strange... + + GetPlayer()->UpdateZone(newZone); +} + +void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data ) +{ + // When this packet send? + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid ; + recv_data >> guid; + + _player->SetUInt32Value(UNIT_FIELD_TARGET,guid); + + // update reputation list if need + Unit* unit = ObjectAccessor::GetUnit(*_player, guid ); + if(!unit) + return; + + _player->SetFactionVisibleForFactionTemplateId(unit->getFaction()); +} + +void WorldSession::HandleSetSelectionOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + _player->SetSelection(guid); + + // update reputation list if need + Unit* unit = ObjectAccessor::GetUnit(*_player, guid ); + if(!unit) + return; + + _player->SetFactionVisibleForFactionTemplateId(unit->getFaction()); +} + +void WorldSession::HandleStandStateChangeOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1); + + sLog.outDebug( "WORLD: Received CMSG_STAND_STATE_CHANGE" ); + uint8 animstate; + recv_data >> animstate; + + _player->SetStandState(animstate); +} + +void WorldSession::HandleFriendListOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + sLog.outDebug( "WORLD: Received CMSG_CONTACT_LIST" ); + uint32 unk; + recv_data >> unk; + sLog.outDebug("unk value is %u", unk); + _player->GetSocial()->SendSocialList(); +} + +void WorldSession::HandleAddFriendOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 1+1); + + sLog.outDebug( "WORLD: Received CMSG_ADD_FRIEND" ); + + std::string friendName = GetMangosString(LANG_FRIEND_IGNORE_UNKNOWN); + std::string friendNote; + FriendsResult friendResult = FRIEND_NOT_FOUND; + Player *pFriend = NULL; + uint64 friendGuid = 0; + + recv_data >> friendName; + + // recheck + CHECK_PACKET_SIZE(recv_data, (friendName.size()+1)+1); + + recv_data >> friendNote; + + if(!normalizePlayerName(friendName)) + return; + + CharacterDatabase.escape_string(friendName); // prevent SQL injection - normal name don't must changed by this call + + sLog.outDebug( "WORLD: %s asked to add friend : '%s'", + GetPlayer()->GetName(), friendName.c_str() ); + + friendGuid = objmgr.GetPlayerGUIDByName(friendName); + + if(friendGuid) + { + pFriend = ObjectAccessor::FindPlayer(friendGuid); + if(pFriend==GetPlayer()) + friendResult = FRIEND_SELF; + else if(GetPlayer()->GetTeam()!=objmgr.GetPlayerTeamByGUID(friendGuid) && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && GetSecurity() < SEC_MODERATOR) + friendResult = FRIEND_ENEMY; + else if(GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) + friendResult = FRIEND_ALREADY; + } + + if (friendGuid && friendResult==FRIEND_NOT_FOUND) + { + if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer())) + friendResult = FRIEND_ADDED_ONLINE; + else + friendResult = FRIEND_ADDED_OFFLINE; + + if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false)) + { + friendResult = FRIEND_LIST_FULL; + sLog.outDebug( "WORLD: %s's friend list is full.", GetPlayer()->GetName()); + } + + _player->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote); + + sLog.outDebug( "WORLD: %s Guid found '%u'.", friendName.c_str(), GUID_LOPART(friendGuid)); + } + else if(friendResult==FRIEND_ALREADY) + { + sLog.outDebug( "WORLD: %s Guid Already a Friend.", friendName.c_str() ); + } + else if(friendResult==FRIEND_SELF) + { + sLog.outDebug( "WORLD: %s Guid can't add himself.", friendName.c_str() ); + } + else + { + sLog.outDebug( "WORLD: %s Guid not found.", friendName.c_str() ); + } + + sSocialMgr.SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), friendName, false); + + sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" ); +} + +void WorldSession::HandleDelFriendOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 FriendGUID; + + sLog.outDebug( "WORLD: Received CMSG_DEL_FRIEND" ); + + recv_data >> FriendGUID; + + _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(FriendGUID), false); + + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), "", false); + + sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" ); +} + +void WorldSession::HandleAddIgnoreOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1); + + sLog.outDebug( "WORLD: Received CMSG_ADD_IGNORE" ); + + std::string IgnoreName = GetMangosString(LANG_FRIEND_IGNORE_UNKNOWN); + FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND; + uint64 IgnoreGuid = 0; + + recv_data >> IgnoreName; + + if(!normalizePlayerName(IgnoreName)) + return; + + CharacterDatabase.escape_string(IgnoreName); // prevent SQL injection - normal name don't must changed by this call + + sLog.outDebug( "WORLD: %s asked to Ignore: '%s'", + GetPlayer()->GetName(), IgnoreName.c_str() ); + + IgnoreGuid = objmgr.GetPlayerGUIDByName(IgnoreName); + + if(IgnoreGuid) + { + if(IgnoreGuid==GetPlayer()->GetGUID()) + ignoreResult = FRIEND_IGNORE_SELF; + else + { + if( GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) ) + ignoreResult = FRIEND_IGNORE_ALREADY; + } + } + + if (IgnoreGuid && ignoreResult == FRIEND_IGNORE_NOT_FOUND) + { + ignoreResult = FRIEND_IGNORE_ADDED; + + if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true)) + ignoreResult = FRIEND_IGNORE_FULL; + } + else if(ignoreResult==FRIEND_IGNORE_ALREADY) + { + sLog.outDebug( "WORLD: %s Guid Already Ignored.", IgnoreName.c_str() ); + } + else if(ignoreResult==FRIEND_IGNORE_SELF) + { + sLog.outDebug( "WORLD: %s Guid can't add himself.", IgnoreName.c_str() ); + } + else + { + sLog.outDebug( "WORLD: %s Guid not found.", IgnoreName.c_str() ); + } + + sSocialMgr.SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), "", false); + + sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" ); +} + +void WorldSession::HandleDelIgnoreOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 IgnoreGUID; + + sLog.outDebug( "WORLD: Received CMSG_DEL_IGNORE" ); + + recv_data >> IgnoreGUID; + + _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(IgnoreGUID), true); + + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), "", false); + + sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" ); +} + +void WorldSession::HandleSetFriendNoteOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + uint64 guid; + std::string note; + recv_data >> guid >> note; + _player->GetSocial()->SetFriendNote(guid, note); +} + +void WorldSession::HandleBugOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+4+1+4+1); + + uint32 suggestion, contentlen; + std::string content; + uint32 typelen; + std::string type; + + recv_data >> suggestion >> contentlen >> content; + + //recheck + CHECK_PACKET_SIZE(recv_data,4+4+(content.size()+1)+4+1); + + recv_data >> typelen >> type; + + if( suggestion == 0 ) + sLog.outDebug( "WORLD: Received CMSG_BUG [Bug Report]" ); + else + sLog.outDebug( "WORLD: Received CMSG_BUG [Suggestion]" ); + + sLog.outDebug( type.c_str( ) ); + sLog.outDebug( content.c_str( ) ); + + CharacterDatabase.escape_string(type); + CharacterDatabase.escape_string(content); + CharacterDatabase.PExecute ("INSERT INTO bugreport (type,content) VALUES('%s', '%s')", type.c_str( ), content.c_str( )); +} + +void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDetail("WORLD: Received CMSG_RECLAIM_CORPSE"); + if (GetPlayer()->isAlive()) + return; + + // body not released yet + if(!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + return; + + Corpse *corpse = GetPlayer()->GetCorpse(); + + if (!corpse ) + return; + + // prevent resurrect before 30-sec delay after body release not finished + if(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP) > time(NULL)) + return; + + float dist = corpse->GetDistance2d(GetPlayer()); + sLog.outDebug("Corpse 2D Distance: \t%f",dist); + if (dist > CORPSE_RECLAIM_RADIUS) + return; + + uint64 guid; + recv_data >> guid; + + // resurrect + GetPlayer()->ResurrectPlayer(GetPlayer()->InBattleGround() ? 1.0f : 0.5f); + + // spawn bones + GetPlayer()->SpawnCorpseBones(); + + GetPlayer()->SaveToDB(); +} + +void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8+1); + + sLog.outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE"); + + if(GetPlayer()->isAlive()) + return; + + uint64 guid; + uint8 status; + recv_data >> guid; + recv_data >> status; + + if(status == 0) + { + GetPlayer()->clearResurrectRequestData(); // reject + return; + } + + if(!GetPlayer()->isRessurectRequestedBy(guid)) + return; + + GetPlayer()->ResurectUsingRequestData(); + GetPlayer()->SaveToDB(); +} + +void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4); + + sLog.outDebug("WORLD: Received CMSG_AREATRIGGER"); + + uint32 Trigger_ID; + + recv_data >> Trigger_ID; + sLog.outDebug("Trigger ID:%u",Trigger_ID); + + if(GetPlayer()->isInFlight()) + { + sLog.outDebug("Player '%s' (GUID: %u) in flight, ignore Area Trigger ID:%u",GetPlayer()->GetName(),GetPlayer()->GetGUIDLow(), Trigger_ID); + return; + } + + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); + if(!atEntry) + { + sLog.outDebug("Player '%s' (GUID: %u) send unknown (by DBC) Area Trigger ID:%u",GetPlayer()->GetName(),GetPlayer()->GetGUIDLow(), Trigger_ID); + return; + } + + if (GetPlayer()->GetMapId()!=atEntry->mapid) + { + sLog.outDebug("Player '%s' (GUID: %u) too far (trigger map: %u player map: %u), ignore Area Trigger ID: %u", GetPlayer()->GetName(), atEntry->mapid, GetPlayer()->GetMapId(), GetPlayer()->GetGUIDLow(), Trigger_ID); + return; + } + + // delta is safe radius + const float delta = 5.0f; + // check if player in the range of areatrigger + Player* pl = GetPlayer(); + + if (atEntry->radius > 0) + { + // if we have radius check it + float dist = pl->GetDistance(atEntry->x,atEntry->y,atEntry->z); + if(dist > atEntry->radius + delta) + { + sLog.outDebug("Player '%s' (GUID: %u) too far (radius: %f distance: %f), ignore Area Trigger ID: %u", + pl->GetName(), pl->GetGUIDLow(), atEntry->radius, dist, Trigger_ID); + return; + } + } + else + { + // we have only extent + float dx = pl->GetPositionX() - atEntry->x; + float dy = pl->GetPositionY() - atEntry->y; + float dz = pl->GetPositionZ() - atEntry->z; + double es = sin(atEntry->box_orientation); + double ec = cos(atEntry->box_orientation); + // calc rotated vector based on extent axis + double rotateDx = dx*ec - dy*es; + double rotateDy = dx*es + dy*ec; + + if( (fabs(rotateDx) > atEntry->box_x/2 + delta) || + (fabs(rotateDy) > atEntry->box_y/2 + delta) || + (fabs(dz) > atEntry->box_z/2 + delta) ) + { + sLog.outDebug("Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %u 1/2 box Z: %u rotate dX: %f rotate dY: %f dZ:%f), ignore Area Trigger ID: %u", + pl->GetName(), pl->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotateDx, rotateDy, dz, Trigger_ID); + return; + } + } + + if(Script->scriptAreaTrigger(GetPlayer(), atEntry)) + return; + + uint32 quest_id = objmgr.GetQuestForAreaTrigger( Trigger_ID ); + if( quest_id && GetPlayer()->isAlive() && GetPlayer()->IsActiveQuest(quest_id) ) + { + Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + if( pQuest ) + { + if(GetPlayer()->GetQuestStatus(quest_id) == QUEST_STATUS_INCOMPLETE) + GetPlayer()->AreaExploredOrEventHappens( quest_id ); + } + } + + if(objmgr.IsTavernAreaTrigger(Trigger_ID)) + { + // set resting flag we are in the inn + GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); + GetPlayer()->InnEnter(time(NULL), atEntry->mapid, atEntry->x, atEntry->y, atEntry->z); + GetPlayer()->SetRestType(REST_TYPE_IN_TAVERN); + + if(sWorld.IsFFAPvPRealm()) + GetPlayer()->RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + + return; + } + + if(GetPlayer()->InBattleGround()) + { + BattleGround* bg = GetPlayer()->GetBattleGround(); + if(bg) + if(bg->GetStatus() == STATUS_IN_PROGRESS) + bg->HandleAreaTrigger(GetPlayer(), Trigger_ID); + + return; + } + + // NULL if all values default (non teleport trigger) + AreaTrigger const* at = objmgr.GetAreaTrigger(Trigger_ID); + if(!at) + return; + + if(!GetPlayer()->isGameMaster()) + { + uint32 missingLevel = 0; + if(GetPlayer()->getLevel() < at->requiredLevel && !sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL)) + missingLevel = at->requiredLevel; + + // must have one or the other, report the first one that's missing + uint32 missingItem = 0; + if(at->requiredItem) + { + if(!GetPlayer()->HasItemCount(at->requiredItem, 1) && + (!at->requiredItem2 || !GetPlayer()->HasItemCount(at->requiredItem2, 1))) + missingItem = at->requiredItem; + } + else if(at->requiredItem2 && !GetPlayer()->HasItemCount(at->requiredItem2, 1)) + missingItem = at->requiredItem2; + + uint32 missingKey = 0; + if(GetPlayer()->GetDifficulty() == DIFFICULTY_HEROIC) + { + if(at->heroicKey) + { + if(!GetPlayer()->HasItemCount(at->heroicKey, 1) && + (!at->heroicKey2 || !GetPlayer()->HasItemCount(at->heroicKey2, 1))) + missingKey = at->heroicKey; + } + else if(at->heroicKey2 && !GetPlayer()->HasItemCount(at->heroicKey2, 1)) + missingKey = at->heroicKey2; + } + + uint32 missingQuest = 0; + if(at->requiredQuest && !GetPlayer()->GetQuestRewardStatus(at->requiredQuest)) + missingQuest = at->requiredQuest; + + if(missingLevel || missingItem || missingKey || missingQuest) + { + // TODO: all this is probably wrong + if(missingItem) + SendAreaTriggerMessage(GetMangosString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1); + else if(missingKey) + GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY2); + else if(missingQuest) + SendAreaTriggerMessage(at->requiredFailedText.c_str()); + else if(missingLevel) + SendAreaTriggerMessage(GetMangosString(LANG_LEVEL_MINREQUIRED), missingLevel); + return; + } + } + + GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT); +} + +void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/) +{ + sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); + //recv_data.hexlike(); +} + +void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/) +{ + sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); + //recv_data.hexlike(); +} + +void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,1+2+1+1); + + sLog.outDebug( "WORLD: Received CMSG_SET_ACTION_BUTTON" ); + uint8 button, misc, type; + uint16 action; + recv_data >> button >> action >> misc >> type; + sLog.outDetail( "BUTTON: %u ACTION: %u TYPE: %u MISC: %u", button, action, type, misc ); + if(action==0) + { + sLog.outDetail( "MISC: Remove action from button %u", button ); + + GetPlayer()->removeActionButton(button); + } + else + { + if(type==ACTION_BUTTON_MACRO || type==ACTION_BUTTON_CMACRO) + { + sLog.outDetail( "MISC: Added Macro %u into button %u", action, button ); + GetPlayer()->addActionButton(button,action,type,misc); + } + else if(type==ACTION_BUTTON_SPELL) + { + sLog.outDetail( "MISC: Added Action %u into button %u", action, button ); + GetPlayer()->addActionButton(button,action,type,misc); + } + else if(type==ACTION_BUTTON_ITEM) + { + sLog.outDetail( "MISC: Added Item %u into button %u", action, button ); + GetPlayer()->addActionButton(button,action,type,misc); + } + else + sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button ); + } +} + +void WorldSession::HandleCompleteCinema( WorldPacket & /*recv_data*/ ) +{ + DEBUG_LOG( "WORLD: Player is watching cinema" ); +} + +void WorldSession::HandleNextCinematicCamera( WorldPacket & /*recv_data*/ ) +{ + DEBUG_LOG( "WORLD: Which movie to play" ); +} + +void WorldSession::HandleMoveTimeSkippedOpcode( WorldPacket & /*recv_data*/ ) +{ + /* WorldSession::Update( getMSTime() );*/ + DEBUG_LOG( "WORLD: Time Lag/Synchronization Resent/Update" ); + + /* + CHECK_PACKET_SIZE(recv_data,8+4); + uint64 guid; + uint32 time_skipped; + recv_data >> guid; + recv_data >> time_skipped; + sLog.outDebug( "WORLD: CMSG_MOVE_TIME_SKIPPED" ); + + /// TODO + must be need use in mangos + We substract server Lags to move time ( AntiLags ) + for exmaple + GetPlayer()->ModifyLastMoveTime( -int32(time_skipped) ); + */ +} + +void WorldSession::HandleFeatherFallAck(WorldPacket &/*recv_data*/) +{ + DEBUG_LOG("WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); +} + +void WorldSession::HandleMoveUnRootAck(WorldPacket&/* recv_data*/) +{ + /* + CHECK_PACKET_SIZE(recv_data,8+8+4+4+4+4+4); + + sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK" ); + recv_data.hexlike(); + uint64 guid; + uint64 unknown1; + uint32 unknown2; + float PositionX; + float PositionY; + float PositionZ; + float Orientation; + + recv_data >> guid; + recv_data >> unknown1; + recv_data >> unknown2; + recv_data >> PositionX; + recv_data >> PositionY; + recv_data >> PositionZ; + recv_data >> Orientation; + + // TODO for later may be we can use for anticheat + DEBUG_LOG("Guid " I64FMTD,guid); + DEBUG_LOG("unknown1 " I64FMTD,unknown1); + DEBUG_LOG("unknown2 %u",unknown2); + DEBUG_LOG("X %f",PositionX); + DEBUG_LOG("Y %f",PositionY); + DEBUG_LOG("Z %f",PositionZ); + DEBUG_LOG("O %f",Orientation); + */ +} + +void WorldSession::HandleMoveRootAck(WorldPacket&/* recv_data*/) +{ + /* + CHECK_PACKET_SIZE(recv_data,8+8+4+4+4+4+4); + + sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_ROOT_ACK" ); + recv_data.hexlike(); + uint64 guid; + uint64 unknown1; + uint32 unknown2; + float PositionX; + float PositionY; + float PositionZ; + float Orientation; + + recv_data >> guid; + recv_data >> unknown1; + recv_data >> unknown2; + recv_data >> PositionX; + recv_data >> PositionY; + recv_data >> PositionZ; + recv_data >> Orientation; + + // for later may be we can use for anticheat + DEBUG_LOG("Guid " I64FMTD,guid); + DEBUG_LOG("unknown1 " I64FMTD,unknown1); + DEBUG_LOG("unknown1 %u",unknown2); + DEBUG_LOG("X %f",PositionX); + DEBUG_LOG("Y %f",PositionY); + DEBUG_LOG("Z %f",PositionZ); + DEBUG_LOG("O %f",Orientation); + */ +} + +void WorldSession::HandleMoveTeleportAck(WorldPacket&/* recv_data*/) +{ + /* + CHECK_PACKET_SIZE(recv_data,8+4); + + sLog.outDebug("MSG_MOVE_TELEPORT_ACK"); + uint64 guid; + uint32 flags, time; + + recv_data >> guid; + recv_data >> flags >> time; + DEBUG_LOG("Guid " I64FMTD,guid); + DEBUG_LOG("Flags %u, time %u",flags, time/1000); + */ +} + +void WorldSession::HandleSetActionBar(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,1); + + uint8 ActionBar; + + recv_data >> ActionBar; + + if(!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED) + { + if(ActionBar!=0) + sLog.outError("WorldSession::HandleSetActionBar in not logged state with value: %u, ignored",uint32(ActionBar)); + return; + } + + GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, ActionBar); +} + +void WorldSession::HandleWardenDataOpcode(WorldPacket& /*recv_data*/) +{ + /* + CHECK_PACKET_SIZE(recv_data,1); + + uint8 tmp; + recv_data >> tmp; + sLog.outDebug("Received opcode CMSG_WARDEN_DATA, not resolve.uint8 = %u",tmp); + */ +} + +void WorldSession::HandlePlayedTime(WorldPacket& /*recv_data*/) +{ + uint32 TotalTimePlayed = GetPlayer()->GetTotalPlayedTime(); + uint32 LevelPlayedTime = GetPlayer()->GetLevelPlayedTime(); + + WorldPacket data(SMSG_PLAYED_TIME, 8); + data << TotalTimePlayed; + data << LevelPlayedTime; + SendPacket(&data); +} + +void WorldSession::HandleInspectOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 guid; + recv_data >> guid; + DEBUG_LOG("Inspected guid is " I64FMTD, guid); + + _player->SetSelection(guid); + + Player *plr = objmgr.GetPlayer(guid); + if(!plr) // wrong player + return; + + uint32 talent_points = 0x3D; + uint32 guid_size = plr->GetPackGUID().size(); + WorldPacket data(SMSG_INSPECT_TALENT, 4+talent_points); + data.append(plr->GetPackGUID()); + data << uint32(talent_points); + + // fill by 0 talents array + for(uint32 i = 0; i < talent_points; ++i) + data << uint8(0); + + if(sWorld.getConfig(CONFIG_TALENTS_INSPECTING) || _player->isGameMaster()) + { + // find class talent tabs (all players have 3 talent tabs) + uint32 const* talentTabIds = GetTalentTabPages(plr->getClass()); + + uint32 talentTabPos = 0; // pos of first talent rank in tab including all prev tabs + for(uint32 i = 0; i < 3; ++i) + { + uint32 talentTabId = talentTabIds[i]; + + // fill by real data + for(uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId) + { + TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); + if(!talentInfo) + continue; + + // skip another tab talents + if(talentInfo->TalentTab != talentTabId) + continue; + + // find talent rank + uint32 curtalent_maxrank = 0; + for(uint32 k = 5; k > 0; --k) + { + if(talentInfo->RankID[k-1] && plr->HasSpell(talentInfo->RankID[k-1])) + { + curtalent_maxrank = k; + break; + } + } + + // not learned talent + if(!curtalent_maxrank) + continue; + + // 1 rank talent bit index + uint32 curtalent_index = talentTabPos + GetTalentInspectBitPosInTab(talentId); + + uint32 curtalent_rank_index = curtalent_index+curtalent_maxrank-1; + + // slot/offset in 7-bit bytes + uint32 curtalent_rank_slot7 = curtalent_rank_index / 7; + uint32 curtalent_rank_offset7 = curtalent_rank_index % 7; + + // rank pos with skipped 8 bit + uint32 curtalent_rank_index2 = curtalent_rank_slot7 * 8 + curtalent_rank_offset7; + + // slot/offset in 8-bit bytes with skipped high bit + uint32 curtalent_rank_slot = curtalent_rank_index2 / 8; + uint32 curtalent_rank_offset = curtalent_rank_index2 % 8; + + // apply mask + uint32 val = data.read(guid_size + 4 + curtalent_rank_slot); + val |= (1 << curtalent_rank_offset); + data.put(guid_size + 4 + curtalent_rank_slot, val & 0xFF); + } + + talentTabPos += GetTalentTabInspectBitSize(talentTabId); + } + } + + SendPacket(&data); +} + +void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 guid; + recv_data >> guid; + + Player *player = objmgr.GetPlayer(guid); + + if(!player) + { + sLog.outError("InspectHonorStats: WTF, player not found..."); + return; + } + + WorldPacket data(MSG_INSPECT_HONOR_STATS, 8+1+4*4); + data << uint64(player->GetGUID()); + data << uint8(player->GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY)); + data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS)); + data << uint32(player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); + data << uint32(player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); + data << uint32(player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS)); + SendPacket(&data); +} + +void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4+4+4+4+4+4); + + // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180 + // Received opcode CMSG_WORLD_TELEPORT + // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593 + + //sLog.outDebug("Received opcode CMSG_WORLD_TELEPORT"); + + if(GetPlayer()->isInFlight()) + { + sLog.outDebug("Player '%s' (GUID: %u) in flight, ignore worldport command.",GetPlayer()->GetName(),GetPlayer()->GetGUIDLow()); + return; + } + + uint32 time; + uint32 mapid; + float PositionX; + float PositionY; + float PositionZ; + float Orientation; + + recv_data >> time; // time in m.sec. + recv_data >> mapid; + recv_data >> PositionX; + recv_data >> PositionY; + recv_data >> PositionZ; + recv_data >> Orientation; // o (3.141593 = 180 degrees) + DEBUG_LOG("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation); + + if (GetSecurity() >= SEC_ADMINISTRATOR) + GetPlayer()->TeleportTo(mapid,PositionX,PositionY,PositionZ,Orientation); + else + SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); + sLog.outDebug("Received worldport command from player %s", GetPlayer()->GetName()); +} + +void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 1); + + sLog.outDebug("Received opcode CMSG_WHOIS"); + std::string charname; + recv_data >> charname; + + if (GetSecurity() < SEC_ADMINISTRATOR) + { + SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); + return; + } + + if(charname.empty()) + { + SendNotification(LANG_NEED_CHARACTER_NAME); + return; + } + + Player *plr = objmgr.GetPlayer(charname.c_str()); + + if(!plr) + { + SendNotification(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, charname.c_str()); + return; + } + + uint32 accid = plr->GetSession()->GetAccountId(); + + QueryResult *result = loginDatabase.PQuery("SELECT username,email,last_ip FROM account WHERE id=%u", accid); + if(!result) + { + SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, charname.c_str()); + return; + } + + Field *fields = result->Fetch(); + std::string acc = fields[0].GetCppString(); + if(acc.empty()) + acc = "Unknown"; + std::string email = fields[1].GetCppString(); + if(email.empty()) + email = "Unknown"; + std::string lastip = fields[2].GetCppString(); + if(lastip.empty()) + lastip = "Unknown"; + + std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip; + + WorldPacket data(SMSG_WHOIS, msg.size()+1); + data << msg; + _player->GetSession()->SendPacket(&data); + + delete result; + + sLog.outDebug("Received whois command from player %s for character %s", GetPlayer()->GetName(), charname.c_str()); +} + +void WorldSession::HandleReportSpamOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 1+8); + sLog.outDebug("WORLD: CMSG_REPORT_SPAM"); + recv_data.hexlike(); + + uint8 spam_type; // 0 - mail, 1 - chat + uint64 spammer_guid; + uint32 unk1, unk2, unk3, unk4 = 0; + std::string description = ""; + recv_data >> spam_type; // unk 0x01 const, may be spam type (mail/chat) + recv_data >> spammer_guid; // player guid + switch(spam_type) + { + case 0: + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4); + recv_data >> unk1; // const 0 + recv_data >> unk2; // probably mail id + recv_data >> unk3; // const 0 + break; + case 1: + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4+1); + recv_data >> unk1; // probably language + recv_data >> unk2; // message type? + recv_data >> unk3; // probably channel id + recv_data >> unk4; // unk random value + recv_data >> description; // spam description string (messagetype, channel name, player name, message) + break; + } + + // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam. + // if it's mail spam - ALL mails from this spammer automatically removed by client + + // Complaint Received message + WorldPacket data(SMSG_COMPLAIN_RESULT, 1); + data << uint8(0); + SendPacket(&data); + + sLog.outDebug("REPORT SPAM: type %u, guid %u, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", spam_type, GUID_LOPART(spammer_guid), unk1, unk2, unk3, unk4, description.c_str()); +} + +void WorldSession::HandleRealmStateRequestOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + + sLog.outDebug("CMSG_REALM_SPLIT"); + + uint32 unk; + std::string split_date = "01/01/01"; + recv_data >> unk; + + WorldPacket data(SMSG_REALM_SPLIT, 4+4+split_date.size()+1); + data << unk; + data << uint32(0x00000000); // realm split state + // split states: + // 0x0 realm normal + // 0x1 realm split + // 0x2 realm split pending + data << split_date; + SendPacket(&data); + //sLog.outDebug("response sent %u", unk); +} + +void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 1); + + sLog.outDebug("WORLD: CMSG_FAR_SIGHT"); + //recv_data.hexlike(); + + uint8 unk; + recv_data >> unk; + + switch(unk) + { + case 0: + //WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0) + //SendPacket(&data); + //_player->SetUInt64Value(PLAYER_FARSIGHT, 0); + sLog.outDebug("Removed FarSight from player %u", _player->GetGUIDLow()); + break; + case 1: + sLog.outDebug("Added FarSight " I64FMTD " to player %u", _player->GetUInt64Value(PLAYER_FARSIGHT), _player->GetGUIDLow()); + break; + } +} + +void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + + sLog.outDebug("CMSG_SET_TITLE"); + + int32 title; + recv_data >> title; + + // -1 at none + if(title > 0 && title < 64) + { + if(!GetPlayer()->HasFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << title)) + return; + } + else + title = 0; + + GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title); +} + +void WorldSession::HandleAllowMoveAckOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4+4); + + sLog.outDebug("CMSG_ALLOW_MOVE_ACK"); + + uint32 counter, time_; + recv_data >> counter >> time_; + + // time_ seems always more than getMSTime() + uint32 diff = getMSTimeDiff(getMSTime(),time_); + + sLog.outDebug("response sent: counter %u, time %u (HEX: %X), ms. time %u, diff %u", counter, time_, time_, getMSTime(), diff); +} + +void WorldSession::HandleResetInstancesOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("WORLD: CMSG_RESET_INSTANCES"); + Group *pGroup = _player->GetGroup(); + if(pGroup) + { + if(pGroup->IsLeader(_player->GetGUID())) + pGroup->ResetInstances(INSTANCE_RESET_ALL, _player); + } + else + _player->ResetInstances(INSTANCE_RESET_ALL); +} + +void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4); + + sLog.outDebug("MSG_SET_DUNGEON_DIFFICULTY"); + + uint32 mode; + recv_data >> mode; + + if(mode == _player->GetDifficulty()) + return; + + if(mode > DIFFICULTY_HEROIC) + { + sLog.outError("WorldSession::HandleDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode); + return; + } + + // cannot reset while in an instance + Map *map = _player->GetMap(); + if(map && map->IsDungeon()) + { + sLog.outError("WorldSession::HandleDungeonDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow()); + return; + } + + if(_player->getLevel() < LEVELREQUIREMENT_HEROIC) + return; + Group *pGroup = _player->GetGroup(); + if(pGroup) + { + if(pGroup->IsLeader(_player->GetGUID())) + { + // the difficulty is set even if the instances can't be reset + //_player->SendDungeonDifficulty(true); + pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, _player); + pGroup->SetDifficulty(mode); + } + } + else + { + _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY); + _player->SetDifficulty(mode); + } +} + +void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("New Unknown Opcode %u", recv_data.GetOpcode()); + recv_data.hexlike(); + /* + New Unknown Opcode 837 + STORAGE_SIZE: 60 + 02 00 00 00 00 00 00 00 | 00 00 00 00 01 20 00 00 + 89 EB 33 01 71 5C 24 C4 | 15 03 35 45 74 47 8B 42 + BA B8 1B 40 00 00 00 00 | 00 00 00 00 77 66 42 BF + 23 91 26 3F 00 00 60 41 | 00 00 00 00 + + New Unknown Opcode 837 + STORAGE_SIZE: 44 + 02 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00 + 7B 80 34 01 84 EA 2B C4 | 5F A1 36 45 C9 39 1C 42 + BA B8 1B 40 CE 06 00 00 | 00 00 80 3F + */ +} + +void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA"); + //recv_data.hexlike(); + + //If player is not mounted, so go out :) + if (!_player->IsMounted()) // not blizz like; no any messages on blizz + { + ChatHandler(this).SendSysMessage(LANG_CHAR_NON_MOUNTED); + return; + } + + if(_player->isInFlight()) // not blizz like; no any messages on blizz + { + ChatHandler(this).SendSysMessage(LANG_YOU_IN_FLIGHT); + return; + } + + _player->Unmount(); + _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); +} + +void WorldSession::HandleMoveFlyModeChangeAckOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+4+4); + + // fly mode on/off + sLog.outDebug("WORLD: CMSG_MOVE_SET_CAN_FLY_ACK"); + //recv_data.hexlike(); + + uint64 guid; + uint32 unk; + uint32 flags; + + recv_data >> guid >> unk >> flags; + + _player->SetUnitMovementFlags(flags); + /* + on: + 25 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00 + 85 4E A9 01 19 BA 7A C3 | 42 0D 70 44 44 B0 A8 42 + 78 15 94 40 39 03 00 00 | 00 00 80 3F + off: + 25 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 + 10 FD A9 01 19 BA 7A C3 | 42 0D 70 44 44 B0 A8 42 + 78 15 94 40 39 03 00 00 | 00 00 00 00 + */ +} + +void WorldSession::HandleRequestPetInfoOpcode( WorldPacket & /*recv_data */) +{ + /* + sLog.outDebug("WORLD: CMSG_REQUEST_PET_INFO"); + recv_data.hexlike(); + */ +} + +void WorldSession::HandleSetTaxiBenchmarkOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 1); + + uint8 mode; + recv_data >> mode; + + sLog.outDebug("Client used \"/timetest %d\" command", mode); +} diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp new file mode 100644 index 000000000..0ebb40cd6 --- /dev/null +++ b/src/game/MotionMaster.cpp @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MotionMaster.h" +#include "CreatureAISelector.h" +#include "Creature.h" +#include "Traveller.h" + +#include "ConfusedMovementGenerator.h" +#include "FleeingMovementGenerator.h" +#include "HomeMovementGenerator.h" +#include "IdleMovementGenerator.h" +#include "PointMovementGenerator.h" +#include "TargetedMovementGenerator.h" +#include "WaypointMovementGenerator.h" + +#include + +inline bool isStatic(MovementGenerator *mv) +{ + return (mv == &si_idleMovement); +} + +void +MotionMaster::Initialize() +{ + // clear ALL movement generators (including default) + while(!empty()) + { + MovementGenerator *curr = top(); + curr->Finalize(*i_owner); + pop(); + if( !isStatic( curr ) ) + delete curr; + } + + // set new default movement generator + if(i_owner->GetTypeId() == TYPEID_UNIT) + { + MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner); + push( movement == NULL ? &si_idleMovement : movement ); + top()->Initialize(*i_owner); + } + else + push(&si_idleMovement); +} + +MotionMaster::~MotionMaster() +{ + // clear ALL movement generators (including default) + while(!empty()) + { + MovementGenerator *curr = top(); + curr->Finalize(*i_owner); + pop(); + if( !isStatic( curr ) ) + delete curr; + } +} + +void +MotionMaster::UpdateMotion(const uint32 &diff) +{ + if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) ) + return; + assert( !empty() ); + if (!top()->Update(*i_owner, diff)) + MovementExpired(); +} + +void +MotionMaster::Clear(bool reset) +{ + while( !empty() && size() > 1 ) + { + MovementGenerator *curr = top(); + curr->Finalize(*i_owner); + pop(); + if( !isStatic( curr ) ) + delete curr; + } + + if (reset) + { + assert( !empty() ); + top()->Reset(*i_owner); + } +} + +void +MotionMaster::MovementExpired(bool reset) +{ + if( empty() || size() == 1 ) + return; + + MovementGenerator *curr = top(); + curr->Finalize(*i_owner); + pop(); + + if( !isStatic(curr) ) + delete curr; + + assert( !empty() ); + while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE ) + { + // Should check if target is still valid? If not valid it will crash. + curr = top(); + curr->Finalize(*i_owner); + pop(); + delete curr; + } + if( empty() ) + Initialize(); + if (reset) top()->Reset(*i_owner); +} + +void MotionMaster::MoveIdle() +{ + if( empty() || !isStatic( top() ) ) + push( &si_idleMovement ); +} + +void +MotionMaster::MoveTargetedHome() +{ + if(i_owner->hasUnitState(UNIT_STAT_FLEEING)) + return; + + Clear(false); + + if(i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID()) + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow()); + Mutate(new HomeMovementGenerator()); + } + else if(i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID()) + { + sLog.outError("Pet or controlled creature (Entry: %u GUID: %u) attempt targeted home", + i_owner->GetEntry(), i_owner->GetGUIDLow() ); + } + else + { + sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() ); + } +} + +void +MotionMaster::MoveConfused() +{ + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) move confused", i_owner->GetGUIDLow() ); + Mutate(new ConfusedMovementGenerator()); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) move confused", + i_owner->GetEntry(), i_owner->GetGUIDLow() ); + Mutate(new ConfusedMovementGenerator()); + } +} + +void +MotionMaster::MoveChase(Unit* target, float dist, float angle) +{ + // ignore movement request if target not exist + if(!target) + return; + + i_owner->clearUnitState(UNIT_STAT_FOLLOW); + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) chase to %s (GUID: %u)", + target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", + target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() ); + Mutate(new TargetedMovementGenerator(*target,dist,angle)); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)", + i_owner->GetEntry(), i_owner->GetGUIDLow(), + target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", + target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() ); + Mutate(new TargetedMovementGenerator(*target,dist,angle)); + } +} + +void +MotionMaster::MoveFollow(Unit* target, float dist, float angle) +{ + Clear(); + + // ignore movement request if target not exist + if(!target) + return; + + i_owner->addUnitState(UNIT_STAT_FOLLOW); + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(), + target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", + target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() ); + Mutate(new TargetedMovementGenerator(*target,dist,angle)); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)", + i_owner->GetEntry(), i_owner->GetGUIDLow(), + target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", + target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() ); + Mutate(new TargetedMovementGenerator(*target,dist,angle)); + } +} + +void +MotionMaster::MovePoint(uint32 id, float x, float y, float z) +{ + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), id, x, y, z ); + Mutate(new PointMovementGenerator(id,x,y,z)); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)", + i_owner->GetEntry(), i_owner->GetGUIDLow(), id, x, y, z ); + Mutate(new PointMovementGenerator(id,x,y,z)); + } +} + +void +MotionMaster::MoveFleeing(Unit* enemy) +{ + if(!enemy) + return; + + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) flee from %s (GUID: %u)", i_owner->GetGUIDLow(), + enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", + enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() ); + Mutate(new FleeingMovementGenerator(enemy->GetGUID())); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)", + i_owner->GetEntry(), i_owner->GetGUIDLow(), + enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", + enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() ); + Mutate(new FleeingMovementGenerator(enemy->GetGUID())); + } +} + +void +MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) +{ + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) taxi to (Path %u node %u)", i_owner->GetGUIDLow(), path, pathnode); + FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(path,pathnode); + Mutate(mgen); + } + else + { + sLog.outError("Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)", + i_owner->GetEntry(), i_owner->GetGUIDLow(), path, pathnode ); + } +} + +void +MotionMaster::MoveDistract(uint32 timer) +{ + if(i_owner->GetTypeId()==TYPEID_PLAYER) + { + DEBUG_LOG("Player (GUID: %u) distracted (timer: %u)", i_owner->GetGUIDLow(), timer); + } + else + { + DEBUG_LOG("Creature (Entry: %u GUID: %u) (timer: %u)", + i_owner->GetEntry(), i_owner->GetGUIDLow(), timer); + } + + DistractMovementGenerator* mgen = new DistractMovementGenerator(timer); + Mutate(mgen); +} + +void MotionMaster::Mutate(MovementGenerator *m) +{ + if (!empty()) + { + switch(top()->GetMovementGeneratorType()) + { + // HomeMovement is not that important, delete it if meanwhile a new comes + case HOME_MOTION_TYPE: + // DistractMovement interrupted by any other movement + case DISTRACT_MOTION_TYPE: + MovementExpired(false); + } + } + m->Initialize(*i_owner); + push(m); +} + +void MotionMaster::propagateSpeedChange() +{ + Impl::container_type::iterator it = Impl::c.begin(); + for ( ;it != end(); ++it) + { + (*it)->unitSpeedChanged(); + } +} + +MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const +{ + if(empty()) + return IDLE_MOTION_TYPE; + + return top()->GetMovementGeneratorType(); +} + +bool MotionMaster::GetDestination(float &x, float &y, float &z) +{ + if(empty()) + return false; + + return top()->GetDestination(x,y,z); +} diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h new file mode 100644 index 000000000..b4a19cd86 --- /dev/null +++ b/src/game/MotionMaster.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_MOTIONMASTER_H +#define MANGOS_MOTIONMASTER_H + +#include "Common.h" +#include + +class MovementGenerator; +class Unit; + +// Creature Entry ID used for waypoints show, visible only for GMs +#define VISUAL_WAYPOINT 1 + +// values 0 ... MAX_DB_MOTION_TYPE-1 used in DB +enum MovementGeneratorType +{ + IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h + RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h + WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h + MAX_DB_MOTION_TYPE = 3, // *** this and below motion types can't be set in DB. + ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h + CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h + TARGETED_MOTION_TYPE = 5, // TargetedMovementGenerator.h + HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h + FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h + POINT_MOTION_TYPE = 8, // PointMovementGenerator.h + FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h + DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h +}; + +class MANGOS_DLL_SPEC MotionMaster : private std::stack +{ + private: + typedef std::stack Impl; + public: + + explicit MotionMaster(Unit *unit) : i_owner(unit) {} + ~MotionMaster(); + + void Initialize(); + + MovementGenerator* operator->(void) { return top(); } + + using Impl::top; + using Impl::empty; + + typedef Impl::container_type::const_iterator const_iterator; + const_iterator begin() const { return Impl::c.begin(); } + const_iterator end() const { return Impl::c.end(); } + + void UpdateMotion(const uint32 &diff); + void Clear(bool reset = true); + void MovementExpired(bool reset = true); + + void MoveIdle(); + void MoveTargetedHome(); + void MoveFollow(Unit* target, float dist, float angle); + void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f); + void MoveConfused(); + void MoveFleeing(Unit* enemy); + void MovePoint(uint32 id, float x,float y,float z); + void MoveTaxiFlight(uint32 path, uint32 pathnode); + void MoveDistract(uint32 time); + + MovementGeneratorType GetCurrentMovementGeneratorType() const; + + void propagateSpeedChange(); + + bool GetDestination(float &x, float &y, float &z); + private: + void Mutate(MovementGenerator *m); // use Move* functions instead + + Unit *i_owner; +}; +#endif diff --git a/src/game/MovementGenerator.cpp b/src/game/MovementGenerator.cpp new file mode 100644 index 000000000..9266858d3 --- /dev/null +++ b/src/game/MovementGenerator.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MovementGenerator.h" + +MovementGenerator::~MovementGenerator() +{ +} diff --git a/src/game/MovementGenerator.h b/src/game/MovementGenerator.h new file mode 100644 index 000000000..5d95a5a96 --- /dev/null +++ b/src/game/MovementGenerator.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_MOVEMENTGENERATOR_H +#define MANGOS_MOVEMENTGENERATOR_H + +#include "Platform/Define.h" +#include "Policies/Singleton.h" +#include "Dynamic/ObjectRegistry.h" +#include "Dynamic/FactoryHolder.h" +#include "Common.h" +#include "MotionMaster.h" + +class Unit; + +class MANGOS_DLL_SPEC MovementGenerator +{ + public: + virtual ~MovementGenerator(); + + virtual void Initialize(Unit &) = 0; + virtual void Finalize(Unit &) = 0; + + virtual void Reset(Unit &) = 0; + + virtual bool Update(Unit &, const uint32 &time_diff) = 0; + + virtual MovementGeneratorType GetMovementGeneratorType() = 0; + + virtual void unitSpeedChanged() { } + + virtual bool GetDestination(float& /*x*/, float& /*y*/, float& /*z*/) const { return false; } +}; + +template +class MANGOS_DLL_SPEC MovementGeneratorMedium : public MovementGenerator +{ + public: + void Initialize(Unit &u) + { + //u->AssertIsType(); + (static_cast(this))->Initialize(*((T*)&u)); + } + void Finalize(Unit &u) + { + //u->AssertIsType(); + (static_cast(this))->Finalize(*((T*)&u)); + } + void Reset(Unit &u) + { + //u->AssertIsType(); + (static_cast(this))->Reset(*((T*)&u)); + } + bool Update(Unit &u, const uint32 &time_diff) + { + //u->AssertIsType(); + return (static_cast(this))->Update(*((T*)&u), time_diff); + } + public: + // will not link if not overridden in the generators + void Initialize(T &u); + void Finalize(T &u); + void Reset(T &u); + bool Update(T &u, const uint32 &time_diff); +}; + +struct SelectableMovement : public FactoryHolder +{ + SelectableMovement(MovementGeneratorType mgt) : FactoryHolder(mgt) {} +}; + +template +struct MovementGeneratorFactory : public SelectableMovement +{ + MovementGeneratorFactory(MovementGeneratorType mgt) : SelectableMovement(mgt) {} + + MovementGenerator* Create(void *) const; +}; + +typedef FactoryHolder MovementGeneratorCreator; +typedef FactoryHolder::FactoryHolderRegistry MovementGeneratorRegistry; +typedef FactoryHolder::FactoryHolderRepository MovementGeneratorRepository; +#endif diff --git a/src/game/MovementGeneratorImpl.h b/src/game/MovementGeneratorImpl.h new file mode 100644 index 000000000..83df8325b --- /dev/null +++ b/src/game/MovementGeneratorImpl.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_MOVEMENTGENERATOR_IMPL_H +#define MANGOS_MOVEMENTGENERATOR_IMPL_H + +#include "MovementGenerator.h" + +template +inline MovementGenerator* +MovementGeneratorFactory::Create(void *data) const +{ + Creature* creature = reinterpret_cast(data); + return (new MOVEMENT_GEN(*creature)); +} +#endif diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp new file mode 100644 index 000000000..694bde89b --- /dev/null +++ b/src/game/MovementHandler.cpp @@ -0,0 +1,585 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "Corpse.h" +#include "Player.h" +#include "MapManager.h" +#include "Transports.h" +#include "BattleGround.h" +#include "WaypointMovementGenerator.h" +#include "InstanceSaveMgr.h" + +void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: got MSG_MOVE_WORLDPORT_ACK." ); + HandleMoveWorldportAckOpcode(); +} + +void WorldSession::HandleMoveWorldportAckOpcode() +{ + // get the teleport destination + WorldLocation &loc = GetPlayer()->GetTeleportDest(); + + // possible errors in the coordinate validity check + if(!MapManager::IsValidMapCoord(loc.mapid,loc.x,loc.y,loc.z,loc.o)) + { + LogoutPlayer(false); + return; + } + + // get the destination map entry, not the current one, this will fix homebind and reset greeting + MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); + InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.mapid); + + // reset instance validity, except if going to an instance inside an instance + if(GetPlayer()->m_InstanceValid == false && !mInstance) + GetPlayer()->m_InstanceValid = true; + + GetPlayer()->SetSemaphoreTeleport(false); + + // relocate the player to the teleport destination + GetPlayer()->SetMapId(loc.mapid); + GetPlayer()->Relocate(loc.x, loc.y, loc.z, loc.o); + + // since the MapId is set before the GetInstance call, the InstanceId must be set to 0 + // to let GetInstance() determine the proper InstanceId based on the player's binds + GetPlayer()->SetInstanceId(0); + + // check this before Map::Add(player), because that will create the instance save! + bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty()) == NULL); + + GetPlayer()->SendInitialPacketsBeforeAddToMap(); + // the CanEnter checks are done in TeleporTo but conditions may change + // while the player is in transit, for example the map may get full + if(!MapManager::Instance().GetMap(GetPlayer()->GetMapId(), GetPlayer())->Add(GetPlayer())) + { + sLog.outDebug("WORLD: teleport of player %s (%d) to location %d,%f,%f,%f,%f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.x, loc.y, loc.z, loc.o); + // teleport the player home + GetPlayer()->SetDontMove(false); + if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation())) + { + // the player must always be able to teleport home + sLog.outError("WORLD: failed to teleport player %s (%d) to homebind location %d,%f,%f,%f,%f!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); + assert(false); + } + return; + } + GetPlayer()->SendInitialPacketsAfterAddToMap(); + + // flight fast teleport case + if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) + { + if(!_player->InBattleGround()) + { + // short preparations to continue flight + GetPlayer()->SetDontMove(false); + FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); + flight->Initialize(*GetPlayer()); + return; + } + + // battleground state prepare, stop flight + GetPlayer()->GetMotionMaster()->MovementExpired(); + GetPlayer()->m_taxi.ClearTaxiDestinations(); + } + + // resurrect character at enter into instance where his corpse exist after add to map + Corpse *corpse = GetPlayer()->GetCorpse(); + if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) + { + if( mEntry->IsDungeon() ) + { + GetPlayer()->ResurrectPlayer(0.5f,false); + GetPlayer()->SpawnCorpseBones(); + GetPlayer()->SaveToDB(); + } + } + + if(mEntry->IsRaid() && mInstance) + { + if(reset_notify) + { + uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); + GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance + } + } + + // mount allow check + if(!mEntry->IsMountAllowed()) + _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + + // battleground state preper + if(_player->InBattleGround()) + { + BattleGround *bg = _player->GetBattleGround(); + if(bg) + { + if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg + { + if(!bg->GetBgRaid(_player->GetTeam())) // first player joined + { + Group *group = new Group; + bg->SetBgRaid(_player->GetTeam(), group); + group->Create(_player->GetGUIDLow(), _player->GetName()); + } + else // raid already exist + { + bg->GetBgRaid(_player->GetTeam())->AddMember(_player->GetGUID(), _player->GetName()); + } + } + } + } + + // honorless target + if(GetPlayer()->pvpInfo.inHostileArea) + GetPlayer()->CastSpell(GetPlayer(), 2479, true); + + // resummon pet + if(GetPlayer()->m_temporaryUnsummonedPetNumber) + { + Pet* NewPet = new Pet; + if(!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true)) + delete NewPet; + + GetPlayer()->m_temporaryUnsummonedPetNumber = 0; + } + + GetPlayer()->SetDontMove(false); +} + +void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4); + + if(GetPlayer()->GetDontMove()) + return; + + /* extract packet */ + MovementInfo movementInfo; + uint32 MovementFlags; + + recv_data >> MovementFlags; + recv_data >> movementInfo.unk1; + recv_data >> movementInfo.time; + recv_data >> movementInfo.x; + recv_data >> movementInfo.y; + recv_data >> movementInfo.z; + recv_data >> movementInfo.o; + + //Save movement flags + _player->SetUnitMovementFlags(MovementFlags); + + if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); + + recv_data >> movementInfo.t_guid; + recv_data >> movementInfo.t_x; + recv_data >> movementInfo.t_y; + recv_data >> movementInfo.t_z; + recv_data >> movementInfo.t_o; + recv_data >> movementInfo.t_time; + } + + if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.fallTime; // duration of last jump (when in jump duration from jump begin to now) + + if(MovementFlags & MOVEMENTFLAG_JUMPING) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); + + recv_data >> movementInfo.j_unk; // constant, but different when jumping in water and on land? + recv_data >> movementInfo.j_sinAngle; // sin of angle between orientation0 and players orientation + recv_data >> movementInfo.j_cosAngle; // cos of angle between orientation0 and players orientation + recv_data >> movementInfo.j_xyspeed; // speed of xy movement + } + + if(MovementFlags & MOVEMENTFLAG_SPLINE) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.u_unk1; // unknown + } + /*----------------*/ + + if(recv_data.size() != recv_data.rpos()) + { + sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is %u bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos()); + KickPlayer(); + return; + } + + if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o)) + return; + + /* handle special cases */ + if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) + { + // transports size limited + // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) + if( movementInfo.t_x > 50 || movementInfo.t_y > 50 || movementInfo.t_z > 50 ) + return; + + if( !MaNGOS::IsValidMapCoord(movementInfo.x+movementInfo.t_x, movementInfo.y+movementInfo.t_y, + movementInfo.z+movementInfo.t_z, movementInfo.o+movementInfo.t_o) ) + return; + + // if we boarded a transport, add us to it + if (!GetPlayer()->m_transport) + { + // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list + for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter) + { + if ((*iter)->GetGUID() == movementInfo.t_guid) + { + // unmount before boarding + _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + + GetPlayer()->m_transport = (*iter); + (*iter)->AddPassenger(GetPlayer()); + break; + } + } + } + } + else if (GetPlayer()->m_transport) // if we were on a transport, leave + { + GetPlayer()->m_transport->RemovePassenger(GetPlayer()); + GetPlayer()->m_transport = NULL; + movementInfo.t_x = 0.0f; + movementInfo.t_y = 0.0f; + movementInfo.t_z = 0.0f; + movementInfo.t_o = 0.0f; + movementInfo.t_time = 0; + } + + // fall damage generation (ignore in flight case that can be triggred also at lags in moment teleportation to another map). + if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) + { + Player *target = GetPlayer(); + + //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored + if (movementInfo.fallTime > 1100 && !target->isDead() && !target->isGameMaster() && + !target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL) && + !target->HasAuraType(SPELL_AURA_FLY) && !target->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) ) + { + //Safe fall, fall time reduction + int32 safe_fall = target->GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); + uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0; + + if(fall_time > 1100) //Prevent damage if fall time < 1100 + { + //Fall Damage calculation + float fallperc = float(fall_time)/1100; + uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * target->GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL)); + + float height = movementInfo.z; + target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height); + + if (damage > 0) + { + //Prevent fall damage from being more than the player maximum health + if (damage > target->GetMaxHealth()) + damage = target->GetMaxHealth(); + + // Gust of Wind + if (target->GetDummyAura(43621)) + damage = target->GetMaxHealth()/2; + + target->EnvironmentalDamage(target->GetGUID(), DAMAGE_FALL, damage); + } + + //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction + DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, target->GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall); + } + } + + //handle fall and logout at the same time (logout started before fall finished) + /* outdated and create problems with sit at stun sometime + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE)) + { + target->SetStandState(PLAYER_STATE_SIT); + // Can't move + WorldPacket data( SMSG_FORCE_MOVE_ROOT, 12 ); + data.append(target->GetPackGUID()); + data << (uint32)2; + SendPacket( &data ); + } + */ + } + + if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) + { + // now client not include swimming flag in case jumping under water + GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); + } + + /*----------------------*/ + + /* process position-change */ + recv_data.put(5, getMSTime()); // offset flags(4) + unk(1) + WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size())); + data.append(GetPlayer()->GetPackGUID()); + data.append(recv_data.contents(), recv_data.size()); + GetPlayer()->SendMessageToSet(&data, false); + + GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + GetPlayer()->m_movementInfo = movementInfo; + + if(GetPlayer()->isMovingOrTurning()) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + if(movementInfo.z < -500.0f) + { + // NOTE: this is actually called many times while falling + // even after the player has been teleported away + // TODO: discard movement packets after the player is rooted + if(GetPlayer()->isAlive()) + { + GetPlayer()->EnvironmentalDamage(GetPlayer()->GetGUID(),DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); + // change the death state to CORPSE to prevent the death timer from + // starting in the next player update + GetPlayer()->KillPlayer(); + GetPlayer()->BuildPlayerRepop(); + } + + // cancel the death timer here if started + GetPlayer()->RepopAtGraveyard(); + } +} + +void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4); + + /* extract packet */ + uint64 guid; + uint8 unkB; + uint32 unk1, flags, time, fallTime; + float x, y, z, orientation; + + uint64 t_GUID; + float t_x, t_y, t_z, t_o; + uint32 t_time; + float s_pitch; + float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed; + float u_unk1; + float newspeed; + + recv_data >> guid; + + // now can skip not our packet + if(_player->GetGUID() != guid) + return; + + // continue parse packet + + recv_data >> unk1; + recv_data >> flags >> unkB >> time; + recv_data >> x >> y >> z >> orientation; + if (flags & MOVEMENTFLAG_ONTRANSPORT) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); + + recv_data >> t_GUID; + recv_data >> t_x >> t_y >> t_z >> t_o >> t_time; + } + if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now) + + if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); + + recv_data >> j_unk1; // ?constant, but different when jumping in water and on land? + recv_data >> j_sinAngle >> j_cosAngle; // sin + cos of angle between orientation0 and players orientation + recv_data >> j_xyspeed; // speed of xy movement + } + + if(flags & MOVEMENTFLAG_SPLINE) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> u_unk1; // unknown + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> newspeed; + /*----------------*/ + + // client ACK send one packet for mounted/run case and need skip all except last from its + // in other cases anti-cheat check can be fail in false case + UnitMoveType move_type; + UnitMoveType force_move_type; + + static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "Walkback", "Swim", "Swimback", "Turn", "Fly", "Flyback" }; + + uint16 opcode = recv_data.GetOpcode(); + switch(opcode) + { + case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; + case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break; + case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_WALKBACK; force_move_type = MOVE_WALKBACK; break; + case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break; + case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIMBACK; force_move_type = MOVE_SWIMBACK; break; + case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN; force_move_type = MOVE_TURN; break; + case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLY; force_move_type = MOVE_FLY; break; + case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLYBACK; force_move_type = MOVE_FLYBACK; break; + default: + sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); + return; + } + + // skip all forced speed changes except last and unexpected + // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both. + if(_player->m_forced_speed_changes[force_move_type] > 0) + { + --_player->m_forced_speed_changes[force_move_type]; + if(_player->m_forced_speed_changes[force_move_type] > 0) + return; + } + + if (!_player->GetTransport() && fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f) + { + if(_player->GetSpeed(move_type) > newspeed) // must be greater - just correct + { + sLog.outError("%sSpeedChange player %s is NOT correct (must be %f instead %f), force set to correct value", + move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed); + _player->SetSpeed(move_type,_player->GetSpeedRate(move_type),true); + } + else // must be lesser - cheating + { + sLog.outBasic("Player %s from account id %u kicked for incorrect speed (must be %f instead %f)", + _player->GetName(),_player->GetSession()->GetAccountId(),_player->GetSpeed(move_type), newspeed); + _player->GetSession()->KickPlayer(); + } + } +} + +void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data) +{ + sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); + + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement + data << uint32(0x00000000); // on blizz it increments periodically + SendPacket(&data); +} + +void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/) +{ + //sLog.outDebug("WORLD: Recvd CMSG_MOUNTSPECIAL_ANIM"); + + WorldPacket data(SMSG_MOUNTSPECIAL_ANIM, 8); + data << uint64(GetPlayer()->GetGUID()); + + GetPlayer()->SendMessageToSet(&data, false); +} + +void WorldSession::HandleMoveKnockBackAck( WorldPacket & /*recv_data*/ ) +{ + // CHECK_PACKET_SIZE(recv_data,?); + sLog.outDebug("CMSG_MOVE_KNOCK_BACK_ACK"); + // Currently not used but maybe use later for recheck final player position + // (must be at call same as into "recv_data >> x >> y >> z >> orientation;" + + /* + uint32 flags, time; + float x, y, z, orientation; + uint64 guid; + uint32 sequence; + uint32 ukn1; + float xdirection,ydirection,hspeed,vspeed; + + recv_data >> guid; + recv_data >> sequence; + recv_data >> flags >> time; + recv_data >> x >> y >> z >> orientation; + recv_data >> ukn1; //unknown + recv_data >> vspeed >> xdirection >> ydirection >> hspeed; + + // skip not personal message; + if(GetPlayer()->GetGUID()!=guid) + return; + + // check code + */ +} + +void WorldSession::HandleMoveHoverAck( WorldPacket& /*recv_data*/ ) +{ + sLog.outDebug("CMSG_MOVE_HOVER_ACK"); +} + +void WorldSession::HandleMoveWaterWalkAck(WorldPacket& /*recv_data*/) +{ + sLog.outDebug("CMSG_MOVE_WATER_WALK_ACK"); +} + +void WorldSession::HandleSummonResponseOpcode(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8+1); + + if(!_player->isAlive() || _player->isInCombat() ) + return; + + uint64 summoner_guid; + bool agree; + recv_data >> summoner_guid; + recv_data >> agree; + + _player->SummonIfPossible(agree); +} diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp new file mode 100644 index 000000000..40d486c35 --- /dev/null +++ b/src/game/NPCHandler.cpp @@ -0,0 +1,826 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Language.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Player.h" +#include "GossipDef.h" +#include "SpellAuras.h" +#include "UpdateMask.h" +#include "ScriptCalls.h" +#include "ObjectAccessor.h" +#include "Creature.h" +#include "MapManager.h" +#include "Pet.h" +#include "BattleGroundMgr.h" +#include "BattleGround.h" +#include "Guild.h" + +void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TABARDDESIGNER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleTabardVendorActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + SendTabardVendorActivate(guid); +} + +void WorldSession::SendTabardVendorActivate( uint64 guid ) +{ + WorldPacket data( MSG_TABARDVENDOR_ACTIVATE, 8 ); + data << guid; + SendPacket( &data ); +} + +void WorldSession::HandleBankerActivateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + + sLog.outDebug( "WORLD: Received CMSG_BANKER_ACTIVATE" ); + + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_BANKER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleBankerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + SendShowBank(guid); +} + +void WorldSession::SendShowBank( uint64 guid ) +{ + WorldPacket data( SMSG_SHOW_BANK, 8 ); + data << guid; + SendPacket( &data ); +} + +void WorldSession::HandleTrainerListOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + + recv_data >> guid; + SendTrainerList( guid ); +} + +void WorldSession::SendTrainerList( uint64 guid ) +{ + std::string str = GetMangosString(LANG_NPC_TAINER_HELLO); + SendTrainerList( guid, str ); +} + +void WorldSession::SendTrainerList( uint64 guid,std::string strTitle ) +{ + sLog.outDebug( "WORLD: SendTrainerList" ); + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TRAINER); + if (!unit) + { + sLog.outDebug( "WORLD: SendTrainerList - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + // trainer list loaded at check; + if(!unit->isCanTrainingOf(_player,true)) + return; + + CreatureInfo const *ci = unit->GetCreatureInfo(); + + if (!ci) + { + sLog.outDebug( "WORLD: SendTrainerList - (%u) NO CREATUREINFO! (GUID: %u)", uint32(GUID_LOPART(guid)), guid ); + return; + } + + TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); + if(!trainer_spells) + { + sLog.outDebug( "WORLD: SendTrainerList - Training spells not found for creature (GUID: %u Entry: %u)", guid, unit->GetEntry()); + return; + } + + WorldPacket data( SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1); + data << guid; + data << uint32(trainer_spells->trainerType); + + size_t count_pos = data.wpos(); + data << uint32(trainer_spells->spellList.size()); + + // reputation discount + float fDiscountMod = _player->GetReputationPriceDiscount(unit); + + uint32 count = 0; + for(TrainerSpellList::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr) + { + TrainerSpell const* tSpell = *itr; + + if(!_player->IsSpellFitByClassAndRace(tSpell->spell)) + continue; + + ++count; + + bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->spell); + + SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->spell); + + data << uint32(tSpell->spell); + data << uint8(_player->GetTrainerSpellState(tSpell)); + data << uint32(floor(tSpell->spellcost * fDiscountMod)); + + data << uint32(primary_prof_first_rank ? 1 : 0); // primary prof. learn confirmation dialog + data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state + data << uint8(tSpell->reqlevel); + data << uint32(tSpell->reqskill); + data << uint32(tSpell->reqskillvalue); + data << uint32(chain_node ? (chain_node->prev ? chain_node->prev : chain_node->req) : 0); + data << uint32(chain_node && chain_node->prev ? chain_node->req : 0); + data << uint32(0); + } + + data << strTitle; + + data.put(count_pos,count); + SendPacket( &data ); +} + +void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 guid; + uint32 spellId = 0; + + recv_data >> guid >> spellId; + sLog.outDebug( "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u",uint32(GUID_LOPART(guid)), spellId ); + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_TRAINER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + if(!unit->isCanTrainingOf(_player,true)) + return; + + // check present spell in trainer spell list + TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); + if(!trainer_spells) + return; + + // not found, cheat? + TrainerSpell const* trainer_spell = trainer_spells->Find(spellId); + if(!trainer_spell) + return; + + // can't be learn, cheat? Or double learn with lags... + if(_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN) + return; + + // apply reputation discount + uint32 nSpellCost = uint32(floor(trainer_spell->spellcost * _player->GetReputationPriceDiscount(unit))); + + // check money requirement + if(_player->GetMoney() < nSpellCost ) + return; + + WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer + data << uint64(guid) << uint32(0xB3); + SendPacket(&data); + + data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player + data << uint64(_player->GetGUID()) << uint32(0x016A); + SendPacket(&data); + + _player->ModifyMoney( -int32(nSpellCost) ); + + // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation + _player->learnSpell(trainer_spell->spell); + + data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12); + data << uint64(guid) << uint32(spellId); + SendPacket(&data); +} + +void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug( "WORLD: Received CMSG_GOSSIP_HELLO" ); + + uint64 guid; + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_NONE); + if (!unit) + { + sLog.outDebug( "WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + if( unit->isArmorer() || unit->isCivilian() || unit->isQuestGiver() || unit->isServiceProvider()) + { + unit->StopMoving(); + } + + // If spiritguide, no need for gossip menu, just put player into resurrect queue + if (unit->isSpiritGuide()) + { + BattleGround *bg = _player->GetBattleGround(); + if(bg) + { + bg->AddPlayerToResurrectQueue(unit->GetGUID(), _player->GetGUID()); + sBattleGroundMgr.SendAreaSpiritHealerQueryOpcode(_player, bg, unit->GetGUID()); + return; + } + } + + if(!Script->GossipHello( _player, unit )) + { + _player->TalkedToCreature(unit->GetEntry(),unit->GetGUID()); + unit->prepareGossipMenu(_player,0); + unit->sendPreparedGossip( _player ); + } +} + +void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + sLog.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION"); + + uint32 option; + uint32 unk; + uint64 guid; + std::string code = ""; + + recv_data >> guid >> unk >> option; + + if(_player->PlayerTalkClass->GossipOptionCoded( option )) + { + // recheck + CHECK_PACKET_SIZE(recv_data,8+4+1); + sLog.outBasic("reading string"); + recv_data >> code; + sLog.outBasic("string read: %s", code.c_str()); + } + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_NONE); + if (!unit) + { + sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + if(!code.empty()) + { + + if(!Script->GossipSelectWithCode( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option ), code.c_str()) ) + unit->OnGossipSelect( _player, option ); + } + else + + if(!Script->GossipSelect( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )) ) + unit->OnGossipSelect( _player, option ); +} + +void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug("WORLD: CMSG_SPIRIT_HEALER_ACTIVATE"); + + uint64 guid; + + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_SPIRITHEALER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleSpiritHealerActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + SendSpiritResurrect(); +} + +void WorldSession::SendSpiritResurrect() +{ + _player->ResurrectPlayer(0.5f,false, true); + + _player->DurabilityLossAll(0.25f,true); + + // get corpse nearest graveyard + WorldSafeLocsEntry const *corpseGrave = NULL; + Corpse *corpse = _player->GetCorpse(); + if(corpse) + corpseGrave = objmgr.GetClosestGraveYard( + corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetMapId(), _player->GetTeam() ); + + // now can spawn bones + _player->SpawnCorpseBones(); + + // teleport to nearest from corpse graveyard, if different from nearest to player ghost + if(corpseGrave) + { + WorldSafeLocsEntry const *ghostGrave = objmgr.GetClosestGraveYard( + _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeam() ); + + if(corpseGrave != ghostGrave) + _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); + // or update at original position + else + ObjectAccessor::UpdateVisibilityForPlayer(_player); + } + // or update at original position + else + ObjectAccessor::UpdateVisibilityForPlayer(_player); + + _player->SaveToDB(); +} + +void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 npcGUID; + recv_data >> npcGUID; + + if(!GetPlayer()->isAlive()) + return; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID,UNIT_NPC_FLAG_INNKEEPER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleBinderActivateOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + SendBindPoint(unit); +} + +void WorldSession::SendBindPoint(Creature *npc) +{ + uint32 bindspell = 3286; + + // update sql homebind + CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), _player->GetZoneId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow()); + _player->m_homebindMapId = _player->GetMapId(); + _player->m_homebindZoneId = _player->GetZoneId(); + _player->m_homebindX = _player->GetPositionX(); + _player->m_homebindY = _player->GetPositionY(); + _player->m_homebindZ = _player->GetPositionZ(); + + // send spell for bind 3286 bind magic + npc->CastSpell(_player, bindspell, true); + + WorldPacket data( SMSG_TRAINER_BUY_SUCCEEDED, (8+4)); + data << npc->GetGUID(); + data << bindspell; + SendPacket( &data ); + + // binding + data.Initialize( SMSG_BINDPOINTUPDATE, (4+4+4+4+4) ); + data << float(_player->GetPositionX()); + data << float(_player->GetPositionY()); + data << float(_player->GetPositionZ()); + data << uint32(_player->GetMapId()); + data << uint32(_player->GetZoneId()); + SendPacket( &data ); + + DEBUG_LOG("New Home Position X is %f",_player->GetPositionX()); + DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY()); + DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ()); + DEBUG_LOG("New Home MapId is %u",_player->GetMapId()); + DEBUG_LOG("New Home ZoneId is %u",_player->GetZoneId()); + + // zone update + data.Initialize( SMSG_PLAYERBOUND, 8+4 ); + data << uint64(_player->GetGUID()); + data << uint32(_player->GetZoneId()); + SendPacket( &data ); + + _player->PlayerTalkClass->CloseGossip(); +} + +//Need fix +void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS"); + uint64 npcGUID; + + recv_data >> npcGUID; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleListStabledPetsOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + SendStablePet(npcGUID); +} + +void WorldSession::SendStablePet(uint64 guid ) +{ + sLog.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS Send."); + + WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size + data << uint64 ( guid ); + + Pet *pet = _player->GetPet(); + + data << uint8(0); // place holder for slot show number + data << uint8(GetPlayer()->m_stableSlots); + + uint8 num = 0; // counter for place holder + + // not let move dead pet in slot + if(pet && pet->isAlive() && pet->getPetType()==HUNTER_PET) + { + data << uint32(pet->GetCharmInfo()->GetPetNumber()); + data << uint32(pet->GetEntry()); + data << uint32(pet->getLevel()); + data << pet->GetName(); // petname + data << uint32(pet->GetLoyaltyLevel()); // loyalty + data << uint8(0x01); // client slot 1 == current pet (0) + ++num; + } + + // 0 1 2 3 4 5 6 + QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + data << uint32(fields[2].GetUInt32()); // petnumber + data << uint32(fields[3].GetUInt32()); // creature entry + data << uint32(fields[4].GetUInt32()); // level + data << fields[6].GetString(); // name + data << uint32(fields[5].GetUInt32()); // loyalty + data << uint8(fields[1].GetUInt32()+1); // slot + + ++num; + }while( result->NextRow() ); + + delete result; + } + + data.put(8, num); // set real data to placeholder + SendPacket(&data); +} + +void WorldSession::HandleStablePet( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug("WORLD: Recv CMSG_STABLE_PET not dispose."); + uint64 npcGUID; + + recv_data >> npcGUID; + + if(!GetPlayer()->isAlive()) + return; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleStablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + Pet *pet = _player->GetPet(); + + WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size + + // can't place in stable dead pet + if(!pet||!pet->isAlive()||pet->getPetType()!=HUNTER_PET) + { + data << uint8(0x06); + SendPacket(&data); + return; + } + + uint32 free_slot = 1; + + QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3 ORDER BY slot ",_player->GetGUIDLow()); + if(result) + { + do + { + Field *fields = result->Fetch(); + + uint32 slot = fields[1].GetUInt32(); + + if(slot==free_slot) // this slot not free + ++free_slot; + }while( result->NextRow() ); + } + delete result; + + if( free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots) + { + _player->RemovePet(pet,PetSaveMode(free_slot)); + data << uint8(0x08); + } + else + data << uint8(0x06); + + SendPacket(&data); +} + +void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + sLog.outDebug("WORLD: Recv CMSG_UNSTABLE_PET."); + uint64 npcGUID; + uint32 petnumber; + + recv_data >> npcGUID >> petnumber; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleUnstablePet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size + + Pet* pet = _player->GetPet(); + if(pet && pet->isAlive()) + { + uint8 i = 0x06; + data << uint8(i); + SendPacket(&data); + return; + } + + // delete dead pet + if(pet) + _player->RemovePet(pet,PET_SAVE_AS_DELETED); + + Pet *newpet = NULL; + + QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow(),petnumber); + if(result) + { + Field *fields = result->Fetch(); + uint32 petentry = fields[0].GetUInt32(); + + newpet = new Pet(HUNTER_PET); + if(!newpet->LoadPetFromDB(_player,petentry,petnumber)) + { + delete newpet; + newpet = NULL; + } + delete result; + } + + if(newpet) + data << uint8(0x09); + else + data << uint8(0x06); + SendPacket(&data); +} + +void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug("WORLD: Recv CMSG_BUY_STABLE_SLOT."); + uint64 npcGUID; + + recv_data >> npcGUID; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleBuyStableSlot - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + WorldPacket data(SMSG_STABLE_RESULT, 200); + + if(GetPlayer()->m_stableSlots < 2) // max slots amount = 2 + { + StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1); + if(_player->GetMoney() >= SlotPrice->Price) + { + ++GetPlayer()->m_stableSlots; + _player->ModifyMoney(-int32(SlotPrice->Price)); + data << uint8(0x0A); // success buy + } + else + data << uint8(0x06); + } + else + data << uint8(0x06); + + SendPacket(&data); +} + +void WorldSession::HandleStableRevivePet( WorldPacket &/* recv_data */) +{ + sLog.outDebug("HandleStableRevivePet: Not implemented"); +} + +void WorldSession::HandleStableSwapPet( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + sLog.outDebug("WORLD: Recv CMSG_STABLE_SWAP_PET."); + uint64 npcGUID; + uint32 pet_number; + + recv_data >> npcGUID >> pet_number; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_STABLEMASTER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleStableSwapPet - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size + + Pet* pet = _player->GetPet(); + + if(!pet || pet->getPetType()!=HUNTER_PET) + return; + + // find swapped pet slot in stable + QueryResult *result = CharacterDatabase.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'",_player->GetGUIDLow(),pet_number); + if(!result) + return; + + Field *fields = result->Fetch(); + + uint32 slot = fields[0].GetUInt32(); + uint32 petentry = fields[1].GetUInt32(); + delete result; + + // move alive pet to slot or delele dead pet + _player->RemovePet(pet,pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED); + + // summon unstabled pet + Pet *newpet = new Pet; + if(!newpet->LoadPetFromDB(_player,petentry,pet_number)) + { + delete newpet; + data << uint8(0x06); + } + else + data << uint8(0x09); + + SendPacket(&data); +} + +void WorldSession::HandleRepairItemOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+8+1); + + sLog.outDebug("WORLD: CMSG_REPAIR_ITEM"); + + uint64 npcGUID, itemGUID; + uint8 guildBank; // new in 2.3.2, bool that means from guild bank money + + recv_data >> npcGUID >> itemGUID >> guildBank; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, npcGUID, UNIT_NPC_FLAG_REPAIR); + if (!unit) + { + sLog.outDebug( "WORLD: HandleRepairItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(npcGUID)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + // reputation discount + float discountMod = _player->GetReputationPriceDiscount(unit); + + uint32 TotalCost = 0; + if (itemGUID) + { + sLog.outDebug("ITEM: Repair item, itemGUID = %u, npcGUID = %u", GUID_LOPART(itemGUID), GUID_LOPART(npcGUID)); + + Item* item = _player->GetItemByGuid(itemGUID); + + if(item) + TotalCost= _player->DurabilityRepair(item->GetPos(),true,discountMod,guildBank>0?true:false); + } + else + { + sLog.outDebug("ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGUID)); + + TotalCost = _player->DurabilityRepairAll(true,discountMod,guildBank>0?true:false); + } + if (guildBank) + { + uint32 GuildId = _player->GetGuildId(); + if (!GuildId) + return; + Guild *pGuild = objmgr.GetGuildById(GuildId); + if (!pGuild) + return; + pGuild->LogBankEvent(GUILD_BANK_LOG_REPAIR_MONEY, 0, _player->GetGUIDLow(), TotalCost); + pGuild->SendMoneyInfo(this, _player->GetGUIDLow()); + } +} diff --git a/src/game/NPCHandler.h b/src/game/NPCHandler.h new file mode 100644 index 000000000..8ae245876 --- /dev/null +++ b/src/game/NPCHandler.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __NPCHANDLER_H +#define __NPCHANDLER_H + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct PageText +{ + uint32 Page_ID; + char * Text; + + uint32 Next_Page; +}; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif + +struct QEmote +{ + uint32 _Emote; + uint32 _Delay; +}; + +struct GossipTextOption +{ + std::string Text_0; + std::string Text_1; + uint32 Language; + float Probability; + QEmote Emotes[3]; +}; + +struct GossipText +{ + uint32 Text_ID; + GossipTextOption Options[8]; +}; + +struct PageTextLocale +{ + std::vector Text; +}; + +struct NpcTextLocale +{ + NpcTextLocale() { Text_0.resize(8); Text_1.resize(8); } + + std::vector > Text_0; + std::vector > Text_1; +}; +#endif diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp new file mode 100644 index 000000000..62113c230 --- /dev/null +++ b/src/game/NullCreatureAI.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "NullCreatureAI.h" + +NullCreatureAI::~NullCreatureAI() +{ +} diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h new file mode 100644 index 000000000..642669e72 --- /dev/null +++ b/src/game/NullCreatureAI.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_NULLCREATUREAI_H +#define MANGOS_NULLCREATUREAI_H + +#include "CreatureAI.h" + +class MANGOS_DLL_DECL NullCreatureAI : public CreatureAI +{ + public: + + NullCreatureAI(Creature &) {} + NullCreatureAI() {} + + ~NullCreatureAI(); + + void MoveInLineOfSight(Unit *) {} + void AttackStart(Unit *) {} + void EnterEvadeMode() {} + + bool IsVisible(Unit *) const { return false; } + + void UpdateAI(const uint32) {} + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } +}; +#endif diff --git a/src/game/Object.cpp b/src/game/Object.cpp new file mode 100644 index 000000000..71bc3fa35 --- /dev/null +++ b/src/game/Object.cpp @@ -0,0 +1,1631 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "SharedDefines.h" +#include "WorldPacket.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "Object.h" +#include "Creature.h" +#include "Player.h" +#include "ObjectMgr.h" +#include "WorldSession.h" +#include "UpdateData.h" +#include "UpdateMask.h" +#include "Util.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Log.h" +#include "Transports.h" +#include "TargetedMovementGenerator.h" +#include "WaypointMovementGenerator.h" +#include "VMapFactory.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" + +#include "ObjectPosSelector.h" + +#include "TemporarySummon.h" + +uint32 GuidHigh2TypeId(uint32 guid_hi) +{ + switch(guid_hi) + { + case HIGHGUID_ITEM: return TYPEID_ITEM; + //case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER==HIGHGUID_ITEM currently + case HIGHGUID_UNIT: return TYPEID_UNIT; + case HIGHGUID_PET: return TYPEID_UNIT; + case HIGHGUID_PLAYER: return TYPEID_PLAYER; + case HIGHGUID_GAMEOBJECT: return TYPEID_GAMEOBJECT; + case HIGHGUID_DYNAMICOBJECT:return TYPEID_DYNAMICOBJECT; + case HIGHGUID_CORPSE: return TYPEID_CORPSE; + case HIGHGUID_MO_TRANSPORT: return TYPEID_GAMEOBJECT; + } + return 10; // unknown +} + +Object::Object( ) +{ + m_objectTypeId = TYPEID_OBJECT; + m_objectType = TYPEMASK_OBJECT; + + m_uint32Values = 0; + m_uint32Values_mirror = 0; + m_valuesCount = 0; + + m_inWorld = false; + m_objectUpdated = false; + + m_PackGUID.clear(); + m_PackGUID.appendPackGUID(0); +} + +Object::~Object( ) +{ + if(m_objectUpdated) + ObjectAccessor::Instance().RemoveUpdateObject(this); + + if(m_uint32Values) + { + if(IsInWorld()) + { + ///- Do NOT call RemoveFromWorld here, if the object is a player it will crash + sLog.outError("Object::~Object - guid="I64FMTD", typeid=%d deleted but still in world!!", GetGUID(), GetTypeId()); + //assert(0); + } + + //DEBUG_LOG("Object desctr 1 check (%p)",(void*)this); + delete [] m_uint32Values; + delete [] m_uint32Values_mirror; + //DEBUG_LOG("Object desctr 2 check (%p)",(void*)this); + } +} + +void Object::_InitValues() +{ + m_uint32Values = new uint32[ m_valuesCount ]; + memset(m_uint32Values, 0, m_valuesCount*sizeof(uint32)); + + m_uint32Values_mirror = new uint32[ m_valuesCount ]; + memset(m_uint32Values_mirror, 0, m_valuesCount*sizeof(uint32)); + + m_objectUpdated = false; +} + +void Object::_Create( uint32 guidlow, uint32 entry, HighGuid guidhigh ) +{ + if(!m_uint32Values) _InitValues(); + + uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh); // required more changes to make it working + SetUInt64Value( OBJECT_FIELD_GUID, guid ); + SetUInt32Value( OBJECT_FIELD_TYPE, m_objectType ); + m_PackGUID.clear(); + m_PackGUID.appendPackGUID(GetGUID()); +} + +void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const +{ + ByteBuffer buf(500); + + buf << uint8( UPDATETYPE_MOVEMENT ); + buf << GetGUID(); + + _BuildMovementUpdate(&buf, flags, 0x00000000); + + data->AddUpdateBlock(buf); +} + +void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const +{ + if(!target) + { + return; + } + + uint8 updatetype = UPDATETYPE_CREATE_OBJECT; + uint8 flags = m_updateFlag; + uint32 flags2 = 0; + + /** lower flag1 **/ + if(target == this) // building packet for oneself + { + flags |= UPDATEFLAG_SELF; + + /*** temporary reverted - until real source of stack corruption will not found + updatetype = UPDATETYPE_CREATE_OBJECT2; + ****/ + } + + if(flags & UPDATEFLAG_HASPOSITION) + { + // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses... + if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER)) + updatetype = UPDATETYPE_CREATE_OBJECT2; + + // UPDATETYPE_CREATE_OBJECT2 for pets... + if(target->GetPetGUID() == GetGUID()) + updatetype = UPDATETYPE_CREATE_OBJECT2; + + // UPDATETYPE_CREATE_OBJECT2 for some gameobject types... + if(isType(TYPEMASK_GAMEOBJECT)) + { + switch(((GameObject*)this)->GetGoType()) + { + case GAMEOBJECT_TYPE_TRAP: + case GAMEOBJECT_TYPE_DUEL_ARBITER: + case GAMEOBJECT_TYPE_FLAGSTAND: + case GAMEOBJECT_TYPE_FLAGDROP: + updatetype = UPDATETYPE_CREATE_OBJECT2; + break; + case GAMEOBJECT_TYPE_TRANSPORT: + flags |= UPDATEFLAG_TRANSPORT; + break; + } + } + } + + //sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2); + + ByteBuffer buf(500); + buf << (uint8)updatetype; + //buf.append(GetPackGUID()); //client crashes when using this + buf << (uint8)0xFF << GetGUID(); + buf << (uint8)m_objectTypeId; + + _BuildMovementUpdate(&buf, flags, flags2); + + UpdateMask updateMask; + updateMask.SetCount( m_valuesCount ); + _SetCreateBits( &updateMask, target ); + _BuildValuesUpdate(updatetype, &buf, &updateMask, target ); + data->AddUpdateBlock(buf); +} + +void Object::BuildUpdate(UpdateDataMapType &update_players) +{ + ObjectAccessor::_buildUpdateObject(this,update_players); + ClearUpdateMask(true); +} + +void Object::SendUpdateToPlayer(Player* player) +{ + // send update to another players + SendUpdateObjectToAllExcept(player); + + // send create update to player + UpdateData upd; + WorldPacket packet; + + upd.Clear(); + BuildCreateUpdateBlockForPlayer(&upd, player); + upd.BuildPacket(&packet); + player->GetSession()->SendPacket(&packet); + + // now object updated/(create updated) +} + +void Object::BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const +{ + ByteBuffer buf(500); + + buf << (uint8) UPDATETYPE_VALUES; + //buf.append(GetPackGUID()); //client crashes when using this. but not have crash in debug mode + buf << (uint8)0xFF; + buf << GetGUID(); + + UpdateMask updateMask; + updateMask.SetCount( m_valuesCount ); + + _SetUpdateBits( &updateMask, target ); + _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target ); + + data->AddUpdateBlock(buf); +} + +void Object::BuildOutOfRangeUpdateBlock(UpdateData * data) const +{ + data->AddOutOfRangeGUID(GetGUID()); +} + +void Object::DestroyForPlayer(Player *target) const +{ + ASSERT(target); + + WorldPacket data(SMSG_DESTROY_OBJECT, 8); + data << GetGUID(); + target->GetSession()->SendPacket( &data ); +} + +void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const +{ + *data << (uint8)flags; // update flags + + // 0x20 + if (flags & UPDATEFLAG_LIVING) + { + switch(GetTypeId()) + { + case TYPEID_UNIT: + { + flags2 = ((Unit*)this)->GetUnitMovementFlags(); + } + break; + case TYPEID_PLAYER: + { + flags2 = ((Player*)this)->GetUnitMovementFlags(); + + if(((Player*)this)->GetTransport()) + flags2 |= MOVEMENTFLAG_ONTRANSPORT; + else + flags2 &= ~MOVEMENTFLAG_ONTRANSPORT; + + // remove unknown, unused etc flags for now + flags2 &= ~MOVEMENTFLAG_SPLINE2; // will be set manually + + if(((Player*)this)->isInFlight()) + { + WPAssert(((Player*)this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE); + flags2 = (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE2); + } + } + break; + } + + *data << uint32(flags2); // movement flags + *data << uint8(0); // unk 2.3.0 + *data << uint32(getMSTime()); // time (in milliseconds) + } + + // 0x40 + if (flags & UPDATEFLAG_HASPOSITION) + { + // 0x02 + if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT) + { + *data << (float)0; + *data << (float)0; + *data << (float)0; + *data << ((WorldObject *)this)->GetOrientation(); + } + else + { + *data << ((WorldObject *)this)->GetPositionX(); + *data << ((WorldObject *)this)->GetPositionY(); + *data << ((WorldObject *)this)->GetPositionZ(); + *data << ((WorldObject *)this)->GetOrientation(); + } + } + + // 0x20 + if(flags & UPDATEFLAG_LIVING) + { + // 0x00000200 + if(flags2 & MOVEMENTFLAG_ONTRANSPORT) + { + if(GetTypeId() == TYPEID_PLAYER) + { + *data << (uint64)((Player*)this)->GetTransport()->GetGUID(); + *data << (float)((Player*)this)->GetTransOffsetX(); + *data << (float)((Player*)this)->GetTransOffsetY(); + *data << (float)((Player*)this)->GetTransOffsetZ(); + *data << (float)((Player*)this)->GetTransOffsetO(); + *data << (uint32)((Player*)this)->GetTransTime(); + } + //MaNGOS currently not have support for other than player on transport + } + + // 0x02200000 + if(flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + if(GetTypeId() == TYPEID_PLAYER) + *data << (float)((Player*)this)->m_movementInfo.s_pitch; + else + *data << (float)0; // is't part of movement packet, we must store and send it... + } + + if(GetTypeId() == TYPEID_PLAYER) + *data << (uint32)((Player*)this)->m_movementInfo.fallTime; + else + *data << (uint32)0; // last fall time + + // 0x00001000 + if(flags2 & MOVEMENTFLAG_JUMPING) + { + if(GetTypeId() == TYPEID_PLAYER) + { + *data << (float)((Player*)this)->m_movementInfo.j_unk; + *data << (float)((Player*)this)->m_movementInfo.j_sinAngle; + *data << (float)((Player*)this)->m_movementInfo.j_cosAngle; + *data << (float)((Player*)this)->m_movementInfo.j_xyspeed; + } + else + { + *data << (float)0; + *data << (float)0; + *data << (float)0; + *data << (float)0; + } + } + + // 0x04000000 + if(flags2 & MOVEMENTFLAG_SPLINE) + { + if(GetTypeId() == TYPEID_PLAYER) + *data << (float)((Player*)this)->m_movementInfo.u_unk1; + else + *data << (float)0; + } + + *data << ((Unit*)this)->GetSpeed( MOVE_WALK ); + *data << ((Unit*)this)->GetSpeed( MOVE_RUN ); + *data << ((Unit*)this)->GetSpeed( MOVE_SWIMBACK ); + *data << ((Unit*)this)->GetSpeed( MOVE_SWIM ); + *data << ((Unit*)this)->GetSpeed( MOVE_WALKBACK ); + *data << ((Unit*)this)->GetSpeed( MOVE_FLY ); + *data << ((Unit*)this)->GetSpeed( MOVE_FLYBACK ); + *data << ((Unit*)this)->GetSpeed( MOVE_TURN ); + + // 0x08000000 + if(flags2 & MOVEMENTFLAG_SPLINE2) + { + if(GetTypeId() != TYPEID_PLAYER) + { + sLog.outDebug("_BuildMovementUpdate: MOVEMENTFLAG_SPLINE2 for non-player"); + return; + } + + if(!((Player*)this)->isInFlight()) + { + sLog.outDebug("_BuildMovementUpdate: MOVEMENTFLAG_SPLINE2 but not in flight"); + return; + } + + WPAssert(((Player*)this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE); + + FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(((Player*)this)->GetMotionMaster()->top()); + + uint32 flags3 = 0x00000300; + + *data << uint32(flags3); // splines flag? + + if(flags3 & 0x10000) // probably x,y,z coords there + { + *data << (float)0; + *data << (float)0; + *data << (float)0; + } + + if(flags3 & 0x20000) // probably guid there + { + *data << uint64(0); + } + + if(flags3 & 0x40000) // may be orientation + { + *data << (float)0; + } + + Path &path = fmg->GetPath(); + + float x, y, z; + ((Player*)this)->GetPosition(x, y, z); + + uint32 inflighttime = uint32(path.GetPassedLength(fmg->GetCurrentNode(), x, y, z) * 32); + uint32 traveltime = uint32(path.GetTotalLength() * 32); + + *data << uint32(inflighttime); // passed move time? + *data << uint32(traveltime); // full move time? + *data << uint32(0); // ticks count? + + uint32 poscount = uint32(path.Size()); + + *data << uint32(poscount); // points count + + for(uint32 i = 0; i < poscount; ++i) + { + *data << path.GetNodes()[i].x; + *data << path.GetNodes()[i].y; + *data << path.GetNodes()[i].z; + } + + /*for(uint32 i = 0; i < poscount; i++) + { + // path points + *data << (float)0; + *data << (float)0; + *data << (float)0; + }*/ + + *data << path.GetNodes()[poscount-1].x; + *data << path.GetNodes()[poscount-1].y; + *data << path.GetNodes()[poscount-1].z; + + // target position (path end) + /**data << ((Unit*)this)->GetPositionX(); + *data << ((Unit*)this)->GetPositionY(); + *data << ((Unit*)this)->GetPositionZ();*/ + } + } + + // 0x8 + if(flags & UPDATEFLAG_LOWGUID) + { + switch(GetTypeId()) + { + case TYPEID_OBJECT: + case TYPEID_ITEM: + case TYPEID_CONTAINER: + case TYPEID_GAMEOBJECT: + case TYPEID_DYNAMICOBJECT: + case TYPEID_CORPSE: + *data << uint32(GetGUIDLow()); // GetGUIDLow() + break; + case TYPEID_UNIT: + *data << uint32(0x0000000B); // unk, can be 0xB or 0xC + break; + case TYPEID_PLAYER: + if(flags & UPDATEFLAG_SELF) + *data << uint32(0x00000015); // unk, can be 0x15 or 0x22 + else + *data << uint32(0x00000008); // unk, can be 0x7 or 0x8 + break; + default: + *data << uint32(0x00000000); // unk + break; + } + } + + // 0x10 + if(flags & UPDATEFLAG_HIGHGUID) + { + switch(GetTypeId()) + { + case TYPEID_OBJECT: + case TYPEID_ITEM: + case TYPEID_CONTAINER: + case TYPEID_GAMEOBJECT: + case TYPEID_DYNAMICOBJECT: + case TYPEID_CORPSE: + *data << uint32(GetGUIDHigh()); // GetGUIDHigh() + break; + default: + *data << uint32(0x00000000); // unk + break; + } + } + + // 0x4 + if(flags & UPDATEFLAG_FULLGUID) + { + *data << uint8(0); // packed guid (probably target guid) + } + + // 0x2 + if(flags & UPDATEFLAG_TRANSPORT) + { + *data << uint32(getMSTime()); // ms time + } +} + +void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const +{ + if(!target) + return; + + bool IsActivateToQuest = false; + if (updatetype == UPDATETYPE_CREATE_OBJECT || updatetype == UPDATETYPE_CREATE_OBJECT2) + { + if (isType(TYPEMASK_GAMEOBJECT) && !((GameObject*)this)->IsTransport()) + { + if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster()) + { + IsActivateToQuest = true; + updateMask->SetBit(GAMEOBJECT_DYN_FLAGS); + } + } + } + else //case UPDATETYPE_VALUES + { + if (isType(TYPEMASK_GAMEOBJECT) && !((GameObject*)this)->IsTransport()) + { + if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster()) + { + IsActivateToQuest = true; + } + updateMask->SetBit(GAMEOBJECT_DYN_FLAGS); + updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS); + } + } + + WPAssert(updateMask && updateMask->GetCount() == m_valuesCount); + + *data << (uint8)updateMask->GetBlockCount(); + data->append( updateMask->GetMask(), updateMask->GetLength() ); + + // 2 specialized loops for speed optimization in non-unit case + if(isType(TYPEMASK_UNIT)) // unit (creature/player) case + { + for( uint16 index = 0; index < m_valuesCount; index ++ ) + { + if( updateMask->GetBit( index ) ) + { + // remove custom flag before send + if( index == UNIT_NPC_FLAGS ) + *data << uint32(m_uint32Values[ index ] & ~UNIT_NPC_FLAG_GUARD); + // FIXME: Some values at server stored in float format but must be sent to client in uint32 format + else if(index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME) + { + // convert from float to uint32 and send + *data << uint32(m_floatValues[ index ] < 0 ? 0 : m_floatValues[ index ]); + } + // there are some float values which may be negative or can't get negative due to other checks + else if(index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4 || + index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6) || + index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6) || + index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4) + { + *data << uint32(m_floatValues[ index ]); + } + // Gamemasters should be always able to select units - remove not selectable flag + else if(index == UNIT_FIELD_FLAGS && target->isGameMaster()) + { + *data << (m_uint32Values[ index ] & ~UNIT_FLAG_NOT_SELECTABLE); + } + // hide lootable animation for unallowed players + else if(index == UNIT_DYNAMIC_FLAGS && GetTypeId() == TYPEID_UNIT) + { + if(!target->isAllowedToLoot((Creature*)this)) + *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_LOOTABLE); + else + *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_OTHER_TAGGER); + } + else + { + // send in current format (float as float, uint32 as uint32) + *data << m_uint32Values[ index ]; + } + } + } + } + else if(isType(TYPEMASK_GAMEOBJECT)) // gameobject case + { + for( uint16 index = 0; index < m_valuesCount; index ++ ) + { + if( updateMask->GetBit( index ) ) + { + // send in current format (float as float, uint32 as uint32) + if ( index == GAMEOBJECT_DYN_FLAGS ) + { + if(IsActivateToQuest ) + { + switch(((GameObject*)this)->GetGoType()) + { + case GAMEOBJECT_TYPE_CHEST: + *data << uint32(9); // enable quest object. Represent 9, but 1 for client before 2.3.0 + break; + case GAMEOBJECT_TYPE_GOOBER: + *data << uint32(1); + break; + default: + *data << uint32(0); //unknown. not happen. + break; + } + } + else + *data << uint32(0); // disable quest object + } + else + *data << m_uint32Values[ index ]; // other cases + } + } + } + else // other objects case (no special index checks) + { + for( uint16 index = 0; index < m_valuesCount; index ++ ) + { + if( updateMask->GetBit( index ) ) + { + // send in current format (float as float, uint32 as uint32) + *data << m_uint32Values[ index ]; + } + } + } +} + +void Object::ClearUpdateMask(bool remove) +{ + for( uint16 index = 0; index < m_valuesCount; index ++ ) + { + if(m_uint32Values_mirror[index]!= m_uint32Values[index]) + m_uint32Values_mirror[index] = m_uint32Values[index]; + } + if(m_objectUpdated) + { + if(remove) + ObjectAccessor::Instance().RemoveUpdateObject(this); + m_objectUpdated = false; + } +} + +// Send current value fields changes to all viewers +void Object::SendUpdateObjectToAllExcept(Player* exceptPlayer) +{ + // changes will be send in create packet + if(!IsInWorld()) + return; + + // nothing do + if(!m_objectUpdated) + return; + + ObjectAccessor::UpdateObject(this,exceptPlayer); +} + +bool Object::LoadValues(const char* data) +{ + if(!m_uint32Values) _InitValues(); + + Tokens tokens = StrSplit(data, " "); + + if(tokens.size() != m_valuesCount) + return false; + + Tokens::iterator iter; + int index; + for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, ++index) + { + m_uint32Values[index] = atol((*iter).c_str()); + } + + return true; +} + +void Object::_SetUpdateBits(UpdateMask *updateMask, Player* /*target*/) const +{ + for( uint16 index = 0; index < m_valuesCount; index ++ ) + { + if(m_uint32Values_mirror[index]!= m_uint32Values[index]) + updateMask->SetBit(index); + } +} + +void Object::_SetCreateBits(UpdateMask *updateMask, Player* /*target*/) const +{ + for( uint16 index = 0; index < m_valuesCount; index++ ) + { + if(GetUInt32Value(index) != 0) + updateMask->SetBit(index); + } +} + +void Object::SetInt32Value( uint16 index, int32 value ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + + if(m_int32Values[ index ] != value) + { + m_int32Values[ index ] = value; + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::SetUInt32Value( uint16 index, uint32 value ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + + if(m_uint32Values[ index ] != value) + { + m_uint32Values[ index ] = value; + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::SetUInt64Value( uint16 index, const uint64 &value ) +{ + ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , true ) ); + if(*((uint64*)&(m_uint32Values[ index ])) != value) + { + m_uint32Values[ index ] = *((uint32*)&value); + m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1); + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::SetFloatValue( uint16 index, float value ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + + if(m_floatValues[ index ] != value) + { + m_floatValues[ index ] = value; + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::SetByteValue( uint16 index, uint8 offset, uint8 value ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + + if(offset > 4) + { + sLog.outError("Object::SetByteValue: wrong offset %u", offset); + return; + } + + if(uint8(m_uint32Values[ index ] >> (offset * 8)) != value) + { + m_uint32Values[ index ] &= ~uint32(uint32(0xFF) << (offset * 8)); + m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 8)); + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::SetUInt16Value( uint16 index, uint8 offset, uint16 value ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + + if(offset > 2) + { + sLog.outError("Object::SetUInt16Value: wrong offset %u", offset); + return; + } + + if(uint8(m_uint32Values[ index ] >> (offset * 16)) != value) + { + m_uint32Values[ index ] &= ~uint32(uint32(0xFFFF) << (offset * 16)); + m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 16)); + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::SetStatFloatValue( uint16 index, float value) +{ + if(value < 0) + value = 0.0f; + + SetFloatValue(index, value); +} + +void Object::SetStatInt32Value( uint16 index, int32 value) +{ + if(value < 0) + value = 0; + + SetUInt32Value(index, uint32(value)); +} + +void Object::ApplyModUInt32Value(uint16 index, int32 val, bool apply) +{ + int32 cur = GetUInt32Value(index); + cur += (apply ? val : -val); + if(cur < 0) + cur = 0; + SetUInt32Value(index,cur); +} + +void Object::ApplyModInt32Value(uint16 index, int32 val, bool apply) +{ + int32 cur = GetInt32Value(index); + cur += (apply ? val : -val); + SetInt32Value(index,cur); +} + +void Object::ApplyModSignedFloatValue(uint16 index, float val, bool apply) +{ + float cur = GetFloatValue(index); + cur += (apply ? val : -val); + SetFloatValue(index,cur); +} + +void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply) +{ + float cur = GetFloatValue(index); + cur += (apply ? val : -val); + if(cur < 0) + cur = 0; + SetFloatValue(index,cur); +} + +void Object::SetFlag( uint16 index, uint32 newFlag ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + uint32 oldval = m_uint32Values[ index ]; + uint32 newval = oldval | newFlag; + + if(oldval != newval) + { + m_uint32Values[ index ] = newval; + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +void Object::RemoveFlag( uint16 index, uint32 oldFlag ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + uint32 oldval = m_uint32Values[ index ]; + uint32 newval = oldval & ~oldFlag; + + if(oldval != newval) + { + m_uint32Values[ index ] = newval; + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + +bool Object::PrintIndexError(uint32 index, bool set) const +{ + sLog.outError("ERROR: Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u",(set ? "set value to" : "get value from"),index,m_valuesCount,GetTypeId(),m_objectType); + + // assert must fail after function call + return false; +} + +WorldObject::WorldObject() +{ + m_positionX = 0.0f; + m_positionY = 0.0f; + m_positionZ = 0.0f; + m_orientation = 0.0f; + + m_mapId = 0; + m_InstanceId = 0; + + m_name = ""; + + mSemaphoreTeleport = false; +} + +void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid ) +{ + Object::_Create(guidlow, 0, guidhigh); + + m_mapId = mapid; +} + +uint32 WorldObject::GetZoneId() const +{ + return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY); +} + +uint32 WorldObject::GetAreaId() const +{ + return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY); +} + +InstanceData* WorldObject::GetInstanceData() +{ + Map *map = MapManager::Instance().GetMap(m_mapId, this); + return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL; +} + + //slow +float WorldObject::GetDistance(const WorldObject* obj) const +{ + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float dz = GetPositionZ() - obj->GetPositionZ(); + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + float dist = sqrt((dx*dx) + (dy*dy) + (dz*dz)) - sizefactor; + return ( dist > 0 ? dist : 0); +} + +float WorldObject::GetDistance2d(float x, float y) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float sizefactor = GetObjectSize(); + float dist = sqrt((dx*dx) + (dy*dy)) - sizefactor; + return ( dist > 0 ? dist : 0); +} + +float WorldObject::GetDistance(const float x, const float y, const float z) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float dz = GetPositionZ() - z; + float sizefactor = GetObjectSize(); + float dist = sqrt((dx*dx) + (dy*dy) + (dz*dz)) - sizefactor; + return ( dist > 0 ? dist : 0); +} + +float WorldObject::GetDistance2d(const WorldObject* obj) const +{ + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + float dist = sqrt((dx*dx) + (dy*dy)) - sizefactor; + return ( dist > 0 ? dist : 0); +} + +float WorldObject::GetDistanceZ(const WorldObject* obj) const +{ + float dz = fabs(GetPositionZ() - obj->GetPositionZ()); + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + float dist = dz - sizefactor; + return ( dist > 0 ? dist : 0); +} + +bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare) const +{ + if (!obj || !IsInMap(obj)) return false; + + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float dz = GetPositionZ() - obj->GetPositionZ(); + float distsq = dx*dx + dy*dy + dz*dz; + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + float maxdist = dist2compare + sizefactor; + + return distsq < maxdist * maxdist; +} + +bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const +{ + if (!IsInMap(obj)) return false; + float ox,oy,oz; + obj->GetPosition(ox,oy,oz); + return(IsWithinLOS(ox, oy, oz )); +} + +bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) const +{ + float x,y,z; + GetPosition(x,y,z); + VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); + return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f); +} + +float WorldObject::GetAngle(const WorldObject* obj) const +{ + if(!obj) return 0; + return GetAngle( obj->GetPositionX(), obj->GetPositionY() ); +} + +// Return angle in range 0..2*pi +float WorldObject::GetAngle( const float x, const float y ) const +{ + float dx = x - GetPositionX(); + float dy = y - GetPositionY(); + + float ang = atan2(dy, dx); + ang = (ang >= 0) ? ang : 2 * M_PI + ang; + return ang; +} + +bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const +{ + float arc = arcangle; + + // move arc to range 0.. 2*pi + while( arc >= 2.0f * M_PI ) + arc -= 2.0f * M_PI; + while( arc < 0 ) + arc += 2.0f * M_PI; + + float angle = GetAngle( obj ); + angle -= m_orientation; + + // move angle to range -pi ... +pi + while( angle > M_PI) + angle -= 2.0f * M_PI; + while(angle < -M_PI) + angle += 2.0f * M_PI; + + float lborder = -1 * (arc/2.0f); // in range -pi..0 + float rborder = (arc/2.0f); // in range 0..pi + return (( angle >= lborder ) && ( angle <= rborder )); +} + +void WorldObject::GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z) const +{ + if(distance==0) + { + rand_x = x; + rand_y = y; + rand_z = z; + return; + } + + // angle to face `obj` to `this` + float angle = rand_norm()*2*M_PI; + float new_dist = rand_norm()*distance; + + rand_x = x + new_dist * cos(angle); + rand_y = y + new_dist * sin(angle); + rand_z = z; + + MaNGOS::NormalizeMapCoord(rand_x); + MaNGOS::NormalizeMapCoord(rand_y); + UpdateGroundPositionZ(rand_x,rand_y,rand_z); // update to LOS height if available +} + +void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const +{ + float new_z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(x,y,z,true); + if(new_z > INVALID_HEIGHT) + z = new_z+ 0.05f; // just to be sure that we are not a few pixel under the surface +} + +bool WorldObject::IsPositionValid() const +{ + return MaNGOS::IsValidMapCoord(m_positionX,m_positionY,m_positionZ,m_orientation); +} + +void WorldObject::MonsterSay(const char* text, uint32 language, uint64 TargetGuid) +{ + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildMonsterChat(&data,CHAT_MSG_MONSTER_SAY,text,language,GetName(),TargetGuid); + SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),true); +} + +void WorldObject::MonsterYell(const char* text, uint32 language, uint64 TargetGuid) +{ + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,text,language,GetName(),TargetGuid); + SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),true); +} + +void WorldObject::MonsterTextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote) +{ + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildMonsterChat(&data,IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE,text,LANG_UNIVERSAL,GetName(),TargetGuid); + SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true); +} + +void WorldObject::MonsterWhisper(const char* text, uint64 receiver, bool IsBossWhisper) +{ + Player *player = objmgr.GetPlayer(receiver); + if(!player || !player->GetSession()) + return; + + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildMonsterChat(&data,IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER,text,LANG_UNIVERSAL,GetName(),receiver); + + player->GetSession()->SendPacket(&data); +} + +namespace MaNGOS +{ + class MessageChatLocaleCacheDo + { + public: + MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist) + : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), + i_targetGUID(targetGUID), i_dist(dist) + { + } + + ~MessageChatLocaleCacheDo() + { + for(int i = 0; i < i_data_cache.size(); ++i) + delete i_data_cache[i]; + } + + void operator()(Player* p) + { + // skip far away players + if(p->GetDistance(&i_object) > i_dist) + return; + + uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); + uint32 cache_idx = loc_idx+1; + WorldPacket* data; + + // create if not cached yet + if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx]) + { + if(i_data_cache.size() < cache_idx+1) + i_data_cache.resize(cache_idx+1); + + char const* text = objmgr.GetMangosString(i_textId,loc_idx); + + data = new WorldPacket(SMSG_MESSAGECHAT, 200); + + // TODO: i_object.GetName() also must be localized? + i_object.BuildMonsterChat(data,i_msgtype,text,i_language,i_object.GetName(),i_targetGUID); + + i_data_cache[cache_idx] = data; + } + else + data = i_data_cache[cache_idx]; + + p->SendDirectMessage(data); + } + + private: + WorldObject const& i_object; + ChatMsg i_msgtype; + int32 i_textId; + uint32 i_language; + uint64 i_targetGUID; + float i_dist; + std::vector i_data_cache; // 0 = default, i => i-1 locale index + }; +} // namespace MaNGOS + +void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid) +{ + CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()); + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY)); + MaNGOS::PlayerWorker say_worker(say_do); + TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *GetMap()); +} + +void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid) +{ + CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()); + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL)); + MaNGOS::PlayerWorker say_worker(say_do); + TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *GetMap()); +} + +void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote) +{ + CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()); + + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); + MaNGOS::PlayerWorker say_worker(say_do); + TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, message, *GetMap()); +} + +void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper) +{ + Player *player = objmgr.GetPlayer(receiver); + if(!player || !player->GetSession()) + return; + + uint32 loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); + char const* text = objmgr.GetMangosString(textId,loc_idx); + + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildMonsterChat(&data,IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER,text,LANG_UNIVERSAL,GetName(),receiver); + + player->GetSession()->SendPacket(&data); +} + +void WorldObject::BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 targetGuid) const +{ + bool pre = (msgtype==CHAT_MSG_MONSTER_EMOTE || msgtype==CHAT_MSG_RAID_BOSS_EMOTE); + + *data << (uint8)msgtype; + *data << (uint32)language; + *data << (uint64)GetGUID(); + *data << (uint32)0; //2.1.0 + *data << (uint32)(strlen(name)+1); + *data << name; + *data << (uint64)targetGuid; //Unit Target + if( targetGuid && !IS_PLAYER_GUID(targetGuid) ) + { + *data << (uint32)1; // target name length + *data << (uint8)0; // target name + } + *data << (uint32)(strlen(text)+1+(pre?3:0)); + if(pre) + data->append("%s ",3); + *data << text; + *data << (uint8)0; // ChatTag +} + +void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const +{ + //Heartbeat message cannot be used for non-units + if (!isType(TYPEMASK_UNIT)) + return; + + data->Initialize(MSG_MOVE_HEARTBEAT, 32); + data->append(GetPackGUID()); + *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags + *data << uint8(0); // 2.3.0 + *data << getMSTime(); // time + *data << m_positionX; + *data << m_positionY; + *data << m_positionZ; + *data << m_orientation; + *data << uint32(0); +} + +void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float z, float ang) const +{ + //TeleportAck message cannot be used for non-units + if (!isType(TYPEMASK_UNIT)) + return; + + data->Initialize(MSG_MOVE_TELEPORT_ACK, 41); + data->append(GetPackGUID()); + *data << uint32(0); // this value increments every time + *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags + *data << uint8(0); // 2.3.0 + *data << getMSTime(); // time + *data << x; + *data << y; + *data << z; + *data << ang; + *data << uint32(0); +} + +void WorldObject::SendMessageToSet(WorldPacket *data, bool /*bToSelf*/) +{ + MapManager::Instance().GetMap(m_mapId, this)->MessageBroadcast(this, data); +} + +void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/) +{ + MapManager::Instance().GetMap(m_mapId, this)->MessageDistBroadcast(this, data, dist); +} + +void WorldObject::SendObjectDeSpawnAnim(uint64 guid) +{ + WorldPacket data(SMSG_GAMEOBJECT_DESPAWN_ANIM, 8); + data << guid; + SendMessageToSet(&data, true); +} + +Map* WorldObject::GetMap() const +{ + return MapManager::Instance().GetMap(GetMapId(), this); +} + +Map const* WorldObject::GetBaseMap() const +{ + return MapManager::Instance().GetBaseMap(GetMapId()); +} + +void WorldObject::AddObjectToRemoveList() +{ + Map* map = GetMap(); + if(!map) + { + sLog.outError("Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).",GetTypeId(),GetEntry(),GetGUIDLow(),GetMapId()); + return; + } + + map->AddObjectToRemoveList(this); +} + +Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime) +{ + TemporarySummon* pCreature = new TemporarySummon(GetGUID()); + + pCreature->SetInstanceId(GetInstanceId()); + uint32 team = 0; + if (GetTypeId()==TYPEID_PLAYER) + team = ((Player*)this)->GetTeam(); + + if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), id, team)) + { + delete pCreature; + return NULL; + } + + if (x == 0.0f && y == 0.0f && z == 0.0f) + GetClosePoint(x, y, z, pCreature->GetObjectSize()); + + pCreature->Relocate(x, y, z, ang); + + if(!pCreature->IsPositionValid()) + { + sLog.outError("ERROR: Creature (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); + delete pCreature; + return NULL; + } + + pCreature->Summon(spwtype, despwtime); + + if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->AI()) + ((Creature*)this)->AI()->JustSummoned(pCreature); + + //return the creature therewith the summoner has access to it + return pCreature; +} + +namespace MaNGOS +{ + class NearUsedPosDo + { + public: + NearUsedPosDo(WorldObject const& obj, WorldObject const* searcher, float angle, ObjectPosSelector& selector) + : i_object(obj), i_searcher(searcher), i_angle(angle), i_selector(selector) {} + + void operator()(Corpse*) const {} + void operator()(DynamicObject*) const {} + + void operator()(Creature* c) const + { + // skip self or target + if(c==i_searcher || c==&i_object) + return; + + float x,y,z; + + if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) || + !c->GetMotionMaster()->GetDestination(x,y,z) ) + { + x = c->GetPositionX(); + y = c->GetPositionY(); + } + + add(c,x,y); + } + + template + void operator()(T* u) const + { + // skip self or target + if(u==i_searcher || u==&i_object) + return; + + float x,y; + + x = u->GetPositionX(); + y = u->GetPositionY(); + + add(u,x,y); + } + + // we must add used pos that can fill places around center + void add(WorldObject* u, float x, float y) const + { + // dist include size of u + float dist2d = i_object.GetDistance2d(x,y); + + // u is too nearest to i_object + if(dist2d + i_object.GetObjectSize() + u->GetObjectSize() < i_selector.m_dist - i_selector.m_size) + return; + + // u is too far away from i_object + if(dist2d + i_object.GetObjectSize() - u->GetObjectSize() > i_selector.m_dist + i_selector.m_size) + return; + + float angle = i_object.GetAngle(u)-i_angle; + + // move angle to range -pi ... +pi + while( angle > M_PI) + angle -= 2.0f * M_PI; + while(angle < -M_PI) + angle += 2.0f * M_PI; + + i_selector.AddUsedPos(u->GetObjectSize(),angle,dist2d + i_object.GetObjectSize()); + } + private: + WorldObject const& i_object; + WorldObject const* i_searcher; + float i_angle; + ObjectPosSelector& i_selector; + }; +} // namespace MaNGOS + +//=================================================================================================== + +void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float absAngle ) const +{ + x = GetPositionX() + (GetObjectSize() + distance2d) * cos(absAngle); + y = GetPositionY() + (GetObjectSize() + distance2d) * sin(absAngle); + + MaNGOS::NormalizeMapCoord(x); + MaNGOS::NormalizeMapCoord(y); +} + +void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle ) const +{ + GetNearPoint2D(x,y,distance2d+searcher_size,absAngle); + z = GetPositionZ(); + + // if detection disabled, return first point + if(!sWorld.getConfig(CONFIG_DETECT_POS_COLLISION)) + { + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + return; + } + + // or remember first point + float first_x = x; + float first_y = y; + bool first_los_conflict = false; // first point LOS problems + + // prepare selector for work + ObjectPosSelector selector(GetPositionX(),GetPositionY(),GetObjectSize(),distance2d+searcher_size); + + // adding used positions around object + { + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::NearUsedPosDo u_do(*this,searcher,absAngle,selector); + MaNGOS::WorldObjectWorker worker(u_do); + + TypeContainerVisitor, GridTypeMapContainer > grid_obj_worker(worker); + TypeContainerVisitor, WorldTypeMapContainer > world_obj_worker(worker); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_obj_worker, *MapManager::Instance().GetMap(GetMapId(), this)); + cell_lock->Visit(cell_lock, world_obj_worker, *MapManager::Instance().GetMap(GetMapId(), this)); + } + + // maybe can just place in primary position + if( selector.CheckOriginal() ) + { + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + + first_los_conflict = true; // first point have LOS problems + } + + float angle; // candidate of angle for free pos + + // special case when one from list empty and then empty side preferred + if(selector.FirstAngle(angle)) + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + + // set first used pos in lists + selector.InitializeAngle(); + + // select in positions after current nodes (selection one by one) + while(selector.NextAngle(angle)) // angle for free pos + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + + // BAD NEWS: not free pos (or used or have LOS problems) + // Attempt find _used_ pos without LOS problem + + if(!first_los_conflict) + { + x = first_x; + y = first_y; + + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + return; + } + + // special case when one from list empty and then empty side preferred + if( selector.IsNonBalanced() ) + { + if(!selector.FirstAngle(angle)) // _used_ pos + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + } + + // set first used pos in lists + selector.InitializeAngle(); + + // select in positions after current nodes (selection one by one) + while(selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + + // BAD BAD NEWS: all found pos (free and used) have LOS problem :( + x = first_x; + y = first_y; + + UpdateGroundPositionZ(x,y,z); // update to LOS height if available +} diff --git a/src/game/Object.h b/src/game/Object.h new file mode 100644 index 000000000..127205401 --- /dev/null +++ b/src/game/Object.h @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _OBJECT_H +#define _OBJECT_H + +#include "Common.h" +#include "ByteBuffer.h" +#include "UpdateFields.h" +#include "UpdateData.h" +#include "GameSystem/GridReference.h" +#include "ObjectDefines.h" + +#include +#include + +#define CONTACT_DISTANCE 0.5f +#define INTERACTION_DISTANCE 5 +#define ATTACK_DISTANCE 5 +#define DETECT_DISTANCE 20 // max distance to successful detect stealthed unit +#define MAX_VISIBILITY_DISTANCE (5*SIZE_OF_GRID_CELL/2.0f) // max distance for visible object show, limited by active zone for player based at cell size (active zone = 5x5 cells) +#define DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL) // default visible distance + +#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects + +enum TypeMask +{ + TYPEMASK_OBJECT = 0x0001, + TYPEMASK_ITEM = 0x0002, + TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004 + TYPEMASK_UNIT = 0x0008, + TYPEMASK_PLAYER = 0x0010, + TYPEMASK_GAMEOBJECT = 0x0020, + TYPEMASK_DYNAMICOBJECT = 0x0040, + TYPEMASK_CORPSE = 0x0080, + TYPEMASK_AIGROUP = 0x0100, + TYPEMASK_AREATRIGGER = 0x0200 +}; + +enum TypeID +{ + TYPEID_OBJECT = 0, + TYPEID_ITEM = 1, + TYPEID_CONTAINER = 2, + TYPEID_UNIT = 3, + TYPEID_PLAYER = 4, + TYPEID_GAMEOBJECT = 5, + TYPEID_DYNAMICOBJECT = 6, + TYPEID_CORPSE = 7, + TYPEID_AIGROUP = 8, + TYPEID_AREATRIGGER = 9 +}; + +uint32 GuidHigh2TypeId(uint32 guid_hi); + +enum TempSummonType +{ + TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears + TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies + TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time + TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat + TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death + TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death + TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears + TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called +}; + +class WorldPacket; +class UpdateData; +class ByteBuffer; +class WorldSession; +class Creature; +class Player; +class Map; +class UpdateMask; +class InstanceData; + +typedef HM_NAMESPACE::hash_map UpdateDataMapType; + +struct WorldLocation +{ + uint32 mapid; + float x; + float y; + float z; + float o; + explicit WorldLocation(uint32 mapid = 0, float x = 0, float y = 0, float z = 0, float o = 0) + : mapid(mapid), x(x), y(y), z(z), o(o) {} + WorldLocation(WorldLocation const &loc) + : mapid(loc.mapid), x(loc.x), y(loc.y), z(loc.z), o(loc.o) {} +}; + +class MANGOS_DLL_SPEC Object +{ + public: + virtual ~Object ( ); + + const bool& IsInWorld() const { return m_inWorld; } + virtual void AddToWorld() + { + if(m_inWorld) + return; + + m_inWorld = true; + + // synchronize values mirror with values array (changes will send in updatecreate opcode any way + ClearUpdateMask(true); + } + virtual void RemoveFromWorld() + { + // if we remove from world then sending changes not required + if(m_uint32Values) + ClearUpdateMask(true); + m_inWorld = false; + } + + const uint64& GetGUID() const { return GetUInt64Value(0); } + uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); } + uint32 GetGUIDMid() const { return GUID_ENPART(GetUInt64Value(0)); } + uint32 GetGUIDHigh() const { return GUID_HIPART(GetUInt64Value(0)); } + const ByteBuffer& GetPackGUID() const { return m_PackGUID; } + uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); } + void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); } + + uint8 GetTypeId() const { return m_objectTypeId; } + bool isType(uint16 mask) const { return (mask & m_objectType); } + + virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const; + void SendUpdateToPlayer(Player* player); + + void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const; + void BuildOutOfRangeUpdateBlock( UpdateData *data ) const; + void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const; + void BuildUpdate(UpdateDataMapType &); + + virtual void DestroyForPlayer( Player *target ) const; + + const int32& GetInt32Value( uint16 index ) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false) ); + return m_int32Values[ index ]; + } + + const uint32& GetUInt32Value( uint16 index ) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false) ); + return m_uint32Values[ index ]; + } + + const uint64& GetUInt64Value( uint16 index ) const + { + ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , false) ); + return *((uint64*)&(m_uint32Values[ index ])); + } + + const float& GetFloatValue( uint16 index ) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false ) ); + return m_floatValues[ index ]; + } + + uint8 GetByteValue( uint16 index, uint8 offset) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false) ); + ASSERT( offset < 4 ); + return *(((uint8*)&m_uint32Values[ index ])+offset); + } + + uint8 GetUInt16Value( uint16 index, uint8 offset) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false) ); + ASSERT( offset < 2 ); + return *(((uint16*)&m_uint32Values[ index ])+offset); + } + + void SetInt32Value( uint16 index, int32 value ); + void SetUInt32Value( uint16 index, uint32 value ); + void SetUInt64Value( uint16 index, const uint64 &value ); + void SetFloatValue( uint16 index, float value ); + void SetByteValue( uint16 index, uint8 offset, uint8 value ); + void SetUInt16Value( uint16 index, uint8 offset, uint16 value ); + void SetInt16Value( uint16 index, uint8 offset, int16 value ) { SetUInt16Value(index,offset,(uint16)value); } + void SetStatFloatValue( uint16 index, float value); + void SetStatInt32Value( uint16 index, int32 value); + + void ApplyModUInt32Value(uint16 index, int32 val, bool apply); + void ApplyModInt32Value(uint16 index, int32 val, bool apply); + void ApplyModUInt64Value(uint16 index, int32 val, bool apply); + void ApplyModPositiveFloatValue( uint16 index, float val, bool apply); + void ApplyModSignedFloatValue( uint16 index, float val, bool apply); + + void ApplyPercentModFloatValue(uint16 index, float val, bool apply) + { + val = val != -100.0f ? val : -99.9f ; + SetFloatValue(index, GetFloatValue(index) * (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)) ); + } + + void SetFlag( uint16 index, uint32 newFlag ); + void RemoveFlag( uint16 index, uint32 oldFlag ); + + void ToggleFlag( uint16 index, uint32 flag) + { + if(HasFlag(index, flag)) + RemoveFlag(index, flag); + else + SetFlag(index, flag); + } + + bool HasFlag( uint16 index, uint32 flag ) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false ) ); + return (m_uint32Values[ index ] & flag) != 0; + } + + void ApplyModFlag( uint16 index, uint32 flag, bool apply) + { + if(apply) SetFlag(index,flag); else RemoveFlag(index,flag); + } + + void SetFlag64( uint16 index, uint64 newFlag ) + { + uint64 oldval = GetUInt64Value(index); + uint64 newval = oldval | newFlag; + SetUInt64Value(index,newval); + } + + void RemoveFlag64( uint16 index, uint64 oldFlag ) + { + uint64 oldval = GetUInt64Value(index); + uint64 newval = oldval & ~oldFlag; + SetUInt64Value(index,newval); + } + + void ToggleFlag64( uint16 index, uint64 flag) + { + if(HasFlag64(index, flag)) + RemoveFlag64(index, flag); + else + SetFlag64(index, flag); + } + + bool HasFlag64( uint16 index, uint64 flag ) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false ) ); + return (GetUInt64Value( index ) & flag) != 0; + } + + void ApplyModFlag64( uint16 index, uint64 flag, bool apply) + { + if(apply) SetFlag64(index,flag); else RemoveFlag64(index,flag); + } + + void ClearUpdateMask(bool remove); + void SendUpdateObjectToAllExcept(Player* exceptPlayer); + + bool LoadValues(const char* data); + + uint16 GetValuesCount() const { return m_valuesCount; } + + void InitValues() { _InitValues(); } + + virtual bool hasQuest(uint32 /* quest_id */) const { return false; } + virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; } + protected: + + Object ( ); + + void _InitValues(); + void _Create (uint32 guidlow, uint32 entry, HighGuid guidhigh); + + virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const; + + virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const; + void _BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const; + void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const; + + uint16 m_objectType; + + uint8 m_objectTypeId; + uint8 m_updateFlag; + + union + { + int32 *m_int32Values; + uint32 *m_uint32Values; + float *m_floatValues; + }; + + uint32 *m_uint32Values_mirror; + + uint16 m_valuesCount; + + bool m_objectUpdated; + + private: + bool m_inWorld; + + ByteBuffer m_PackGUID; + + // for output helpfull error messages from asserts + bool PrintIndexError(uint32 index, bool set) const; + Object(const Object&); // prevent generation copy constructor + Object& operator=(Object const&); // prevent generation assigment operator +}; + +class MANGOS_DLL_SPEC WorldObject : public Object +{ + public: + virtual ~WorldObject ( ) {} + + virtual void Update ( uint32 /*time_diff*/ ) { } + + void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid ); + + void Relocate(float x, float y, float z, float orientation) + { + m_positionX = x; + m_positionY = y; + m_positionZ = z; + m_orientation = orientation; + } + + void Relocate(float x, float y, float z) + { + m_positionX = x; + m_positionY = y; + m_positionZ = z; + } + + void Relocate(WorldLocation const & loc) + { + SetMapId(loc.mapid); + Relocate(loc.x, loc.y, loc.z, loc.o); + } + + void SetOrientation(float orientation) { m_orientation = orientation; } + + float GetPositionX( ) const { return m_positionX; } + float GetPositionY( ) const { return m_positionY; } + float GetPositionZ( ) const { return m_positionZ; } + void GetPosition( float &x, float &y, float &z ) const + { x = m_positionX; y = m_positionY; z = m_positionZ; } + void GetPosition( WorldLocation &loc ) const + { loc.mapid = GetMapId(); GetPosition(loc.x, loc.y, loc.z); loc.o = GetOrientation(); } + float GetOrientation( ) const { return m_orientation; } + void GetNearPoint2D( float &x, float &y, float distance, float absAngle) const; + void GetNearPoint( WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d,float absAngle) const; + void GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0) const + { + // angle calculated from current orientation + GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle); + } + void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const + { + // angle to face `obj` to `this` using distance includes size of `obj` + GetNearPoint(obj,x,y,z,obj->GetObjectSize(),distance2d,GetAngle( obj )); + } + + float GetObjectSize() const + { + return ( m_valuesCount > UNIT_FIELD_BOUNDINGRADIUS ) ? m_floatValues[UNIT_FIELD_BOUNDINGRADIUS] : DEFAULT_WORLD_OBJECT_SIZE; + } + bool IsPositionValid() const; + void UpdateGroundPositionZ(float x, float y, float &z) const; + + void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const; + + void SetMapId(uint32 newMap) { m_mapId = newMap; } + + uint32 GetMapId() const { return m_mapId; } + + uint32 GetZoneId() const; + uint32 GetAreaId() const; + + InstanceData* GetInstanceData(); + + const char* GetName() const { return m_name.c_str(); } + void SetName(std::string newname) { m_name=newname; } + + float GetDistance( const WorldObject* obj ) const; + float GetDistance(const float x, const float y, const float z) const; + float GetDistance2d(const WorldObject* obj) const; + float GetDistance2d(const float x, const float y) const; + float GetDistanceZ(const WorldObject* obj) const; + bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); } + bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare) const; + bool IsWithinLOS(const float x, const float y, const float z ) const; + bool IsWithinLOSInMap(const WorldObject* obj) const; + + float GetAngle( const WorldObject* obj ) const; + float GetAngle( const float x, const float y ) const; + bool HasInArc( const float arcangle, const WorldObject* obj ) const; + + virtual void SendMessageToSet(WorldPacket *data, bool self); + virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self); + void BuildHeartBeatMsg( WorldPacket *data ) const; + void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const; + bool IsBeingTeleported() { return mSemaphoreTeleport; } + void SetSemaphoreTeleport(bool semphsetting) { mSemaphoreTeleport = semphsetting; } + + void MonsterSay(const char* text, uint32 language, uint64 TargetGuid); + void MonsterYell(const char* text, uint32 language, uint64 TargetGuid); + void MonsterTextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote = false); + void MonsterWhisper(const char* text, uint64 receiver, bool IsBossWhisper = false); + void MonsterSay(int32 textId, uint32 language, uint64 TargetGuid); + void MonsterYell(int32 textId, uint32 language, uint64 TargetGuid); + void MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false); + void MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper = false); + void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 TargetGuid) const; + + void SendObjectDeSpawnAnim(uint64 guid); + + virtual void SaveRespawnTime() {} + + uint32 GetInstanceId() const { return m_InstanceId; } + void SetInstanceId(uint32 val) { m_InstanceId = val; } + + void AddObjectToRemoveList(); + + // main visibility check function in normal case (ignore grey zone distance check) + bool isVisibleFor(Player const* u) const { return isVisibleForInState(u,false); } + + // low level function for visibility change code, must be define in all main world object subclasses + virtual bool isVisibleForInState(Player const* u, bool inVisibleList) const = 0; + + Map * GetMap() const; + Map const* GetBaseMap() const; + Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); + + protected: + explicit WorldObject(); + std::string m_name; + + private: + uint32 m_mapId; + + float m_positionX; + float m_positionY; + float m_positionZ; + float m_orientation; + + bool mSemaphoreTeleport; + + uint32 m_InstanceId; +}; +#endif diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp new file mode 100644 index 000000000..f1cf1e57b --- /dev/null +++ b/src/game/ObjectAccessor.cpp @@ -0,0 +1,648 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Policies/SingletonImp.h" +#include "Player.h" +#include "Creature.h" +#include "GameObject.h" +#include "DynamicObject.h" +#include "Corpse.h" +#include "WorldSession.h" +#include "WorldPacket.h" +#include "Item.h" +#include "Corpse.h" +#include "GridNotifiers.h" +#include "MapManager.h" +#include "Map.h" +#include "CellImpl.h" +#include "GridNotifiersImpl.h" +#include "Opcodes.h" +#include "ObjectDefines.h" +#include "MapInstanced.h" + +#include + +#define CLASS_LOCK MaNGOS::ClassLevelLockable +INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK); +INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ZThread::FastMutex); + +namespace MaNGOS +{ + + struct MANGOS_DLL_DECL BuildUpdateForPlayer + { + Player &i_player; + UpdateDataMapType &i_updatePlayers; + + BuildUpdateForPlayer(Player &player, UpdateDataMapType &data_map) : i_player(player), i_updatePlayers(data_map) {} + + void Visit(PlayerMapType &m) + { + for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + if( iter->getSource() == &i_player ) + continue; + + UpdateDataMapType::iterator iter2 = i_updatePlayers.find(iter->getSource()); + if( iter2 == i_updatePlayers.end() ) + { + std::pair p = i_updatePlayers.insert( ObjectAccessor::UpdateDataValueType(iter->getSource(), UpdateData()) ); + assert(p.second); + iter2 = p.first; + } + + i_player.BuildValuesUpdateBlockForPlayer(&iter2->second, iter2->first); + } + } + + template void Visit(GridRefManager &) {} + }; +} + +ObjectAccessor::ObjectAccessor() {} +ObjectAccessor::~ObjectAccessor() {} + +Creature* +ObjectAccessor::GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask) +{ + // unit checks + if (!guid) + return NULL; + + // exist + Creature *unit = GetCreature(player, guid); + if (!unit) + return NULL; + + // player check + if(!player.CanInteractWithNPCs(!unit->isSpiritService())) + return NULL; + + // appropriate npc type + if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask )) + return NULL; + + // alive or spirit healer + if(!unit->isAlive() && (!unit->isSpiritService() || player.isAlive() )) + return NULL; + + // not allow interaction under control + if(unit->GetCharmerOrOwnerGUID()) + return NULL; + + // not enemy + if( unit->IsHostileTo(&player)) + return NULL; + + // not unfriendly + FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(unit->getFaction()); + if(factionTemplate) + { + FactionEntry const* faction = sFactionStore.LookupEntry(factionTemplate->faction); + if( faction->reputationListID >= 0 && player.GetReputationRank(faction) <= REP_UNFRIENDLY) + return NULL; + } + + // not too far + if(!unit->IsWithinDistInMap(&player,INTERACTION_DISTANCE)) + return NULL; + + return unit; +} + +Creature* +ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid) +{ + if(Creature *unit = GetPet(guid)) + return unit; + + return GetCreature(u, guid); +} + +Creature* +ObjectAccessor::GetCreature(WorldObject const &u, uint64 guid) +{ + Creature * ret = GetObjectInWorld(guid, (Creature*)NULL); + if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + return ret; +} + +Unit* +ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid) +{ + if(!guid) + return NULL; + + if(IS_PLAYER_GUID(guid)) + return FindPlayer(guid); + + return GetCreatureOrPet(u, guid); +} + +Corpse* +ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid) +{ + Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL); + if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + return ret; +} + +Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 typemask) +{ + Object *obj = NULL; + + if(typemask & TYPEMASK_PLAYER) + { + obj = FindPlayer(guid); + if(obj) return obj; + } + + if(typemask & TYPEMASK_UNIT) + { + obj = GetCreatureOrPet(p,guid); + if(obj) return obj; + } + + if(typemask & TYPEMASK_GAMEOBJECT) + { + obj = GetGameObject(p,guid); + if(obj) return obj; + } + + if(typemask & TYPEMASK_DYNAMICOBJECT) + { + obj = GetDynamicObject(p,guid); + if(obj) return obj; + } + + if(typemask & TYPEMASK_ITEM) + { + obj = p.GetItemByGuid( guid ); + if(obj) return obj; + } + + return NULL; +} + +GameObject* +ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid) +{ + GameObject * ret = GetObjectInWorld(guid, (GameObject*)NULL); + if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + return ret; +} + +DynamicObject* +ObjectAccessor::GetDynamicObject(Unit const &u, uint64 guid) +{ + DynamicObject * ret = GetObjectInWorld(guid, (DynamicObject*)NULL); + if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + return ret; +} + +Player* +ObjectAccessor::FindPlayer(uint64 guid) +{ + return GetObjectInWorld(guid, (Player*)NULL); +} + +Player* +ObjectAccessor::FindPlayerByName(const char *name) +{ + //TODO: Player Guard + HashMapHolder::MapType& m = HashMapHolder::GetContainer(); + HashMapHolder::MapType::iterator iter = m.begin(); + for(; iter != m.end(); ++iter) + if( ::strcmp(name, iter->second->GetName()) == 0 ) + return iter->second; + return NULL; +} + +void +ObjectAccessor::SaveAllPlayers() +{ + Guard guard(*HashMapHolder::GetLock()); + HashMapHolder::MapType& m = HashMapHolder::GetContainer(); + HashMapHolder::MapType::iterator itr = m.begin(); + for(; itr != m.end(); ++itr) + itr->second->SaveToDB(); +} + +void +ObjectAccessor::_update() +{ + UpdateDataMapType update_players; + { + Guard guard(i_updateGuard); + while(!i_objects.empty()) + { + Object* obj = *i_objects.begin(); + i_objects.erase(i_objects.begin()); + if (!obj) + continue; + _buildUpdateObject(obj, update_players); + obj->ClearUpdateMask(false); + } + } + + WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 + for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); // clean the string + } +} + +void +ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer) +{ + UpdateDataMapType update_players; + obj->BuildUpdate(update_players); + + WorldPacket packet; + for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + if(iter->first == exceptPlayer) + continue; + + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); + } +} + +void +ObjectAccessor::AddUpdateObject(Object *obj) +{ + Guard guard(i_updateGuard); + i_objects.insert(obj); +} + +void +ObjectAccessor::RemoveUpdateObject(Object *obj) +{ + Guard guard(i_updateGuard); + std::set::iterator iter = i_objects.find(obj); + if( iter != i_objects.end() ) + i_objects.erase( iter ); +} + +void +ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players) +{ + bool build_for_all = true; + Player *pl = NULL; + if( obj->isType(TYPEMASK_ITEM) ) + { + Item *item = static_cast(obj); + pl = item->GetOwner(); + build_for_all = false; + } + + if( pl != NULL ) + _buildPacket(pl, obj, update_players); + + // Capt: okey for all those fools who think its a real fix + // THIS IS A TEMP FIX + if( build_for_all ) + { + WorldObject * temp = dynamic_cast(obj); + + //assert(dynamic_cast(obj)!=NULL); + if (temp) + _buildChangeObjectForPlayer(temp, update_players); + else + sLog.outDebug("ObjectAccessor: Ln 405 Temp bug fix"); + } +} + +void +ObjectAccessor::_buildPacket(Player *pl, Object *obj, UpdateDataMapType &update_players) +{ + UpdateDataMapType::iterator iter = update_players.find(pl); + + if( iter == update_players.end() ) + { + std::pair p = update_players.insert( UpdateDataValueType(pl, UpdateData()) ); + assert(p.second); + iter = p.first; + } + + obj->BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); +} + +void +ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players) +{ + CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + WorldObjectChangeAccumulator notifier(*obj, update_players); + TypeContainerVisitor player_notifier(notifier); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, player_notifier, *MapManager::Instance().GetMap(obj->GetMapId(), obj)); +} + +Pet* +ObjectAccessor::GetPet(uint64 guid) +{ + return GetObjectInWorld(guid, (Pet*)NULL); +} + +Corpse* +ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) +{ + Guard guard(i_corpseGuard); + + Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid); + if( iter == i_player2corpse.end() ) return NULL; + + assert(iter->second->GetType() != CORPSE_BONES); + + return iter->second; +} + +void +ObjectAccessor::RemoveCorpse(Corpse *corpse) +{ + assert(corpse && corpse->GetType() != CORPSE_BONES); + + Guard guard(i_corpseGuard); + Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID()); + if( iter == i_player2corpse.end() ) + return; + + // build mapid*cellid -> guid_set map + CellPair cell_pair = MaNGOS::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY()); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + objmgr.DeleteCorpseCellData(corpse->GetMapId(),cell_id,corpse->GetOwnerGUID()); + corpse->RemoveFromWorld(); + + i_player2corpse.erase(iter); +} + +void +ObjectAccessor::AddCorpse(Corpse *corpse) +{ + assert(corpse && corpse->GetType() != CORPSE_BONES); + + Guard guard(i_corpseGuard); + assert(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end()); + i_player2corpse[corpse->GetOwnerGUID()] = corpse; + + // build mapid*cellid -> guid_set map + CellPair cell_pair = MaNGOS::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY()); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + objmgr.AddCorpseCellData(corpse->GetMapId(),cell_id,corpse->GetOwnerGUID(),corpse->GetInstanceId()); +} + +void +ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map) +{ + Guard guard(i_corpseGuard); + for(Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter) + if(iter->second->GetGrid()==gridpair) + { + // verify, if the corpse in our instance (add only corpses which are) + if (map->Instanceable()) + { + if (iter->second->GetInstanceId() == map->GetInstanceId()) + { + grid.AddWorldObject(iter->second,iter->second->GetGUID()); + } + } + else + { + grid.AddWorldObject(iter->second,iter->second->GetGUID()); + } + } +} + +Corpse* +ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid) +{ + Corpse *corpse = GetCorpseForPlayerGUID(player_guid); + if(!corpse) + { + //in fact this function is called from several places + //even when player doesn't have a corpse, not an error + //sLog.outError("ERROR: Try remove corpse that not in map for GUID %ul", player_guid); + return NULL; + } + + DEBUG_LOG("Deleting Corpse and spawning bones.\n"); + + // remove corpse from player_guid -> corpse map + RemoveCorpse(corpse); + + // remove resurrectble corpse from grid object registry (loaded state checked into call) + // do not load the map if it's not loaded + Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId()); + if(map) map->Remove(corpse,false); + + // remove corpse from DB + corpse->DeleteFromDB(); + + Corpse *bones = NULL; + // create the bones only if the map and the grid is loaded at the corpse's location + if(map && !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY())) + { + // Create bones, don't change Corpse + bones = new Corpse; + bones->Create(corpse->GetGUIDLow()); + + for (int i = 3; i < CORPSE_END; i++) // don't overwrite guid and object type + bones->SetUInt32Value(i, corpse->GetUInt32Value(i)); + + bones->SetGrid(corpse->GetGrid()); + // bones->m_time = m_time; // don't overwrite time + // bones->m_inWorld = m_inWorld; // don't overwrite world state + // bones->m_type = m_type; // don't overwrite type + bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); + bones->SetMapId(corpse->GetMapId()); + bones->SetInstanceId(corpse->GetInstanceId()); + + bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES); + bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0); + + for (int i = 0; i < EQUIPMENT_SLOT_END; i++) + { + if(corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i)) + bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0); + } + + // add bones in grid store if grid loaded where corpse placed + map->Add(bones); + } + + // all references to the corpse should be removed at this point + delete corpse; + + return bones; +} + +void +ObjectAccessor::Update(uint32 diff) +{ + { + typedef std::multimap CreatureLocationHolderType; + CreatureLocationHolderType creature_locations; + //TODO: Player guard + HashMapHolder::MapType& playerMap = HashMapHolder::GetContainer(); + for(HashMapHolder::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter) + { + if(iter->second->IsInWorld()) + { + iter->second->Update(diff); + creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) ); + } + } + + Map *map; + + MaNGOS::ObjectUpdater updater(diff); + // for creature + TypeContainerVisitor grid_object_update(updater); + // for pets + TypeContainerVisitor world_object_update(updater); + + for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter) + { + MapManager::Instance().GetMap((*iter).first, (*iter).second)->resetMarkedCells(); + } + + for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter) + { + Player *player = (*iter).second; + map = MapManager::Instance().GetMap((*iter).first, player); + + CellPair standing_cell(MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY())); + + // Check for correctness of standing_cell, it also avoids problems with update_cell + if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) + continue; + + // the overloaded operators handle range checking + // so ther's no need for range checking inside the loop + CellPair begin_cell(standing_cell), end_cell(standing_cell); + begin_cell << 1; begin_cell -= 1; // upper left + end_cell >> 1; end_cell += 1; // lower right + + for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++) + { + for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++) + { + uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; + if( !map->isCellMarked(cell_id) ) + { + CellPair cell_pair(x,y); + map->markCell(cell_id); + Cell cell(cell_pair); + cell.data.Part.reserved = CENTER_DISTRICT; + cell.SetNoCreate(); + CellLock cell_lock(cell, cell_pair); + cell_lock->Visit(cell_lock, grid_object_update, *map); + cell_lock->Visit(cell_lock, world_object_update, *map); + } + } + } + } + } + + _update(); +} + +bool +ObjectAccessor::PlayersNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) const +{ + CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); + CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); + cell_min << 2; + cell_min -= 2; + cell_max >> 2; + cell_max += 2; + + //TODO: Guard player + HashMapHolder::MapType& playerMap = HashMapHolder::GetContainer(); + for(HashMapHolder::MapType::const_iterator iter=playerMap.begin(); iter != playerMap.end(); ++iter) + { + if( m_id != iter->second->GetMapId() || i_id != iter->second->GetInstanceId() ) + continue; + + CellPair p = MaNGOS::ComputeCellPair(iter->second->GetPositionX(), iter->second->GetPositionY()); + if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && + (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) + return true; + } + + return false; +} + +void +ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m) +{ + for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) + if(iter->getSource()->HaveAtClient(&i_object)) + ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas); +} + +void +ObjectAccessor::UpdateObjectVisibility(WorldObject *obj) +{ + CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); + Cell cell(p); + + MapManager::Instance().GetMap(obj->GetMapId(), obj)->UpdateObjectVisibility(obj,cell,p); +} + +void ObjectAccessor::UpdateVisibilityForPlayer( Player* player ) +{ + CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); + Cell cell(p); + Map* m = MapManager::Instance().GetMap(player->GetMapId(),player); + + m->UpdatePlayerVisibility(player,cell,p); + m->UpdateObjectsVisibilityFor(player,cell,p); +} + +/// Define the static member of HashMapHolder + +template HM_NAMESPACE::hash_map< uint64, T* > HashMapHolder::m_objectMap; +template ZThread::FastMutex HashMapHolder::i_lock; + +/// Global defintions for the hashmap storage + +template class HashMapHolder; +template class HashMapHolder; +template class HashMapHolder; +template class HashMapHolder; +template class HashMapHolder; +template class HashMapHolder; + +template Player* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/); +template Pet* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); +template Creature* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/); +template Corpse* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/); +template GameObject* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/); +template DynamicObject* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, DynamicObject* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h new file mode 100644 index 000000000..92483adf0 --- /dev/null +++ b/src/game/ObjectAccessor.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_OBJECTACCESSOR_H +#define MANGOS_OBJECTACCESSOR_H + +#include "Platform/Define.h" +#include "Policies/Singleton.h" +#include "zthread/FastMutex.h" +#include "Utilities/HashMap.h" +#include "Policies/ThreadingModel.h" + +#include "ByteBuffer.h" +#include "UpdateData.h" + +#include "GridDefines.h" +#include "Object.h" +#include "Player.h" + +#include + +class Creature; +class Corpse; +class Unit; +class GameObject; +class DynamicObject; +class WorldObject; +class Map; + +template +class HashMapHolder +{ + public: + + typedef HM_NAMESPACE::hash_map< uint64, T* > MapType; + typedef ZThread::FastMutex LockType; + typedef MaNGOS::GeneralLock Guard; + + static void Insert(T* o) { m_objectMap[o->GetGUID()] = o; } + + static void Remove(T* o) + { + Guard guard(i_lock); + typename MapType::iterator itr = m_objectMap.find(o->GetGUID()); + if (itr != m_objectMap.end()) + m_objectMap.erase(itr); + } + + static T* Find(uint64 guid) + { + typename MapType::iterator itr = m_objectMap.find(guid); + return (itr != m_objectMap.end()) ? itr->second : NULL; + } + + static MapType& GetContainer() { return m_objectMap; } + + static LockType* GetLock() { return &i_lock; } + private: + + //Non instanciable only static + HashMapHolder() {} + + static LockType i_lock; + static MapType m_objectMap; +}; + +class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton > +{ + + friend class MaNGOS::OperatorNew; + ObjectAccessor(); + ~ObjectAccessor(); + ObjectAccessor(const ObjectAccessor &); + ObjectAccessor& operator=(const ObjectAccessor &); + + public: + typedef HM_NAMESPACE::hash_map Player2CorpsesMapType; + typedef HM_NAMESPACE::hash_map::value_type UpdateDataValueType; + + template static T* GetObjectInWorld(uint64 guid, T* /*fake*/) + { + return HashMapHolder::Find(guid); + } + + static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/) + { + if(!guid) + return NULL; + + if (IS_PLAYER_GUID(guid)) + return (Unit*)HashMapHolder::Find(guid); + + if (Unit* u = (Unit*)HashMapHolder::Find(guid)) + return u; + + return (Unit*)HashMapHolder::Find(guid); + } + + template static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/) + { + T* obj = HashMapHolder::Find(guid); + if(!obj || obj->GetMapId() != mapid) return NULL; + + CellPair p = MaNGOS::ComputeCellPair(x,y); + if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord); + return NULL; + } + + CellPair q = MaNGOS::ComputeCellPair(obj->GetPositionX(),obj->GetPositionY()); + if(q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) + { + sLog.outError("ObjectAccessor::GetObjecInWorld: object "I64FMTD" has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord); + return NULL; + } + + int32 dx = int32(p.x_coord) - int32(q.x_coord); + int32 dy = int32(p.y_coord) - int32(q.y_coord); + + if (dx > -2 && dx < 2 && dy > -2 && dy < 2) return obj; + else return NULL; + } + + static Object* GetObjectByTypeMask(Player const &, uint64, uint32 typemask); + static Creature* GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask); + static Creature* GetCreature(WorldObject const &, uint64); + static Creature* GetCreatureOrPet(WorldObject const &, uint64); + static Unit* GetUnit(WorldObject const &, uint64); + static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); } + static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); } + static GameObject* GetGameObject(WorldObject const &, uint64); + static DynamicObject* GetDynamicObject(Unit const &, uint64); + static Corpse* GetCorpse(WorldObject const &u, uint64 guid); + static Pet* GetPet(uint64 guid); + static Player* FindPlayer(uint64); + + Player* FindPlayerByName(const char *name) ; + + HashMapHolder::MapType& GetPlayers() + { + return HashMapHolder::GetContainer(); + } + + template void AddObject(T *object) + { + HashMapHolder::Insert(object); + } + + template void RemoveObject(T *object) + { + HashMapHolder::Remove(object); + } + + void RemoveObject(Player *pl) + { + HashMapHolder::Remove(pl); + + Guard guard(i_updateGuard); + + std::set::iterator iter2 = std::find(i_objects.begin(), i_objects.end(), (Object *)pl); + if( iter2 != i_objects.end() ) + i_objects.erase(iter2); + } + + void SaveAllPlayers(); + + void AddUpdateObject(Object *obj); + void RemoveUpdateObject(Object *obj); + + void Update(uint32 diff); + + Corpse* GetCorpseForPlayerGUID(uint64 guid); + void RemoveCorpse(Corpse *corpse); + void AddCorpse(Corpse* corpse); + void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map); + Corpse* ConvertCorpseForPlayer(uint64 player_guid); + + bool PlayersNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const; + + static void UpdateObject(Object* obj, Player* exceptPlayer); + static void _buildUpdateObject(Object* obj, UpdateDataMapType &); + + static void UpdateObjectVisibility(WorldObject* obj); + static void UpdateVisibilityForPlayer(Player* player); + private: + struct WorldObjectChangeAccumulator + { + UpdateDataMapType &i_updateDatas; + WorldObject &i_object; + WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {} + void Visit(PlayerMapType &); + template void Visit(GridRefManager &) {} + }; + + friend struct WorldObjectChangeAccumulator; + Player2CorpsesMapType i_player2corpse; + + typedef ZThread::FastMutex LockType; + typedef MaNGOS::GeneralLock Guard; + + static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &); + static void _buildPacket(Player *, Object *, UpdateDataMapType &); + void _update(void); + std::set i_objects; + LockType i_playerGuard; + LockType i_updateGuard; + LockType i_corpseGuard; + LockType i_petGuard; +}; +#endif diff --git a/src/game/ObjectDefines.h b/src/game/ObjectDefines.h new file mode 100644 index 000000000..c7dbc54c0 --- /dev/null +++ b/src/game/ObjectDefines.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_OBJECTDEFINES_H +#define MANGOS_OBJECTDEFINES_H + +#include "Platform/Define.h" + +// used for creating values for respawn for example +#define MAKE_PAIR64(l, h) uint64( uint32(l) | ( uint64(h) << 32 ) ) +#define PAIR64_HIPART(x) (uint32)((uint64(x) >> 32) & 0x00000000FFFFFFFFLL) +#define PAIR64_LOPART(x) (uint32)(uint64(x) & 0x00000000FFFFFFFFLL) + +#define MAKE_PAIR32(l, h) uint32( uint16(l) | ( uint32(h) << 16 ) ) +#define PAIR32_HIPART(x) (uint16)((uint32(x) >> 16) & 0x0000FFFF) +#define PAIR32_LOPART(x) (uint16)(uint32(x) & 0x0000FFFF) + +enum HighGuid +{ + HIGHGUID_ITEM = 0x4000, // blizz 4000 + HIGHGUID_CONTAINER = 0x4000, // blizz 4000 + HIGHGUID_PLAYER = 0x0000, // blizz 0000 + HIGHGUID_GAMEOBJECT = 0xF110, // blizz F110 + HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) + HIGHGUID_UNIT = 0xF130, // blizz F130 + HIGHGUID_PET = 0xF140, // blizz F140 + HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100 + HIGHGUID_CORPSE = 0xF101, // blizz F100 + HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) +}; + +#define IS_EMPTY_GUID(Guid) ( Guid == 0 ) + +#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT ) +#define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET ) +#define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) ) +#define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 ) +#define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) ) + // special case for empty guid need check +#define IS_ITEM_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_ITEM ) +#define IS_GAMEOBJECT_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_GAMEOBJECT ) +#define IS_DYNAMICOBJECT_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_DYNAMICOBJECT ) +#define IS_CORPSE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_CORPSE ) +#define IS_TRANSPORT(Guid) ( GUID_HIPART(Guid) == HIGHGUID_TRANSPORT ) +#define IS_MO_TRANSPORT(Guid) ( GUID_HIPART(Guid) == HIGHGUID_MO_TRANSPORT ) + +// l - OBJECT_FIELD_GUID +// e - OBJECT_FIELD_ENTRY for GO (except GAMEOBJECT_TYPE_MO_TRANSPORT) and creatures or UNIT_FIELD_PETNUMBER for pets +// h - OBJECT_FIELD_GUID + 1 +#define MAKE_NEW_GUID(l, e, h) uint64( uint64(l) | ( uint64(e) << 24 ) | ( uint64(h) << 48 ) ) + +#define GUID_HIPART(x) (uint32)((uint64(x) >> 48) & 0x0000FFFF) + +// We have different low and middle part size for different guid types +#define _GUID_ENPART_2(x) 0 +#define _GUID_ENPART_3(x) (uint32)((uint64(x) >> 24) & 0x0000000000FFFFFFLL) +#define _GUID_LOPART_2(x) (uint32)(uint64(x) & 0x00000000FFFFFFFFLL) +#define _GUID_LOPART_3(x) (uint32)(uint64(x) & 0x0000000000FFFFFFLL) + +inline bool IsGuidHaveEnPart(uint64 const& guid) +{ + switch(GUID_HIPART(guid)) + { + case HIGHGUID_ITEM: + case HIGHGUID_PLAYER: + case HIGHGUID_DYNAMICOBJECT: + case HIGHGUID_CORPSE: + return false; + case HIGHGUID_GAMEOBJECT: + case HIGHGUID_TRANSPORT: + case HIGHGUID_UNIT: + case HIGHGUID_PET: + case HIGHGUID_MO_TRANSPORT: + default: + return true; + } +} + +#define GUID_ENPART(x) (IsGuidHaveEnPart(x) ? _GUID_ENPART_3(x) : _GUID_ENPART_2(x)) +#define GUID_LOPART(x) (IsGuidHaveEnPart(x) ? _GUID_LOPART_3(x) : _GUID_LOPART_2(x)) + +inline char const* GetLogNameForGuid(uint64 guid) +{ + switch(GUID_HIPART(guid)) + { + case HIGHGUID_ITEM: return "item"; + case HIGHGUID_PLAYER: return guid ? "player" : "none"; + case HIGHGUID_GAMEOBJECT: return "gameobject"; + case HIGHGUID_TRANSPORT: return "transport"; + case HIGHGUID_UNIT: return "creature"; + case HIGHGUID_PET: return "pet"; + case HIGHGUID_DYNAMICOBJECT:return "dynobject"; + case HIGHGUID_CORPSE: return "corpse"; + case HIGHGUID_MO_TRANSPORT: return "mo_transport"; + default: + return ""; + } +} +#endif diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp new file mode 100644 index 000000000..8b6db82bd --- /dev/null +++ b/src/game/ObjectGridLoader.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ObjectGridLoader.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "MapManager.h" +#include "Creature.h" +#include "GameObject.h" +#include "DynamicObject.h" +#include "Corpse.h" +#include "World.h" +#include "CellImpl.h" + +class MANGOS_DLL_DECL ObjectGridRespawnMover +{ + public: + ObjectGridRespawnMover() {} + + void Move(GridType &grid); + + template void Visit(GridRefManager &) {} + void Visit(CreatureMapType &m); +}; + +void +ObjectGridRespawnMover::Move(GridType &grid) +{ + TypeContainerVisitor mover(*this); + grid.Visit(mover); +} + +void +ObjectGridRespawnMover::Visit(CreatureMapType &m) +{ + // creature in unloading grid can have respawn point in another grid + // if it will be unloaded then it will not respawn in original grid until unload/load original grid + // move to respwn point to prevent this case. For player view in respawn grid this wll be normal respawn. + for(CreatureMapType::iterator iter=m.begin(), next; iter != m.end(); iter = next) + { + next = iter; ++next; + + Creature * c = iter->getSource(); + + assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets"); + + Cell const& cur_cell = c->GetCurrentCell(); + + float resp_x, resp_y, resp_z; + c->GetRespawnCoord(resp_x, resp_y, resp_z); + CellPair resp_val = MaNGOS::ComputeCellPair(resp_x, resp_y); + Cell resp_cell(resp_val); + + if(cur_cell.DiffGrid(resp_cell)) + { + MapManager::Instance().GetMap(c->GetMapId(), c)->CreatureRespawnRelocation(c); + // false result ignored: will be unload with other creatures at grid + } + } +} + +// for loading world object at grid loading (Corpses) +class ObjectWorldLoader +{ + public: + explicit ObjectWorldLoader(ObjectGridLoader& gloader) + : i_cell(gloader.i_cell), i_grid(gloader.i_grid), i_map(gloader.i_map), i_corpses (0) + {} + + void Visit(CorpseMapType &m); + + template void Visit(GridRefManager&) { } + + private: + Cell i_cell; + NGridType &i_grid; + Map* i_map; + public: + uint32 i_corpses; +}; + +template void addUnitState(T* /*obj*/, CellPair const& /*cell_pair*/) +{ +} + +template<> void addUnitState(Creature *obj, CellPair const& cell_pair) +{ + Cell cell(cell_pair); + + obj->SetCurrentCell(cell); + if(obj->isSpiritService()) + obj->setDeathState(DEAD); +} + +template +void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager &m, uint32 &count, Map* map) +{ + for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid) + { + T* obj = new T; + uint32 guid = *i_guid; + //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid); + if(!obj->LoadFromDB(guid, map)) + { + delete obj; + continue; + } + + obj->GetGridRef().link(&m, obj); + + addUnitState(obj,cell); + obj->AddToWorld(); + ++count; + + } +} + +void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map) +{ + if(cell_corpses.empty()) + return; + + for(CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr) + { + if(itr->second != map->GetInstanceId()) + continue; + + uint32 player_guid = itr->first; + + Corpse *obj = ObjectAccessor::Instance().GetCorpseForPlayerGUID(player_guid); + if(!obj) + continue; + + obj->GetGridRef().link(&m, obj); + + addUnitState(obj,cell); + obj->AddToWorld(); + ++count; + } +} + +void +ObjectGridLoader::Visit(GameObjectMapType &m) +{ + uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX(); + uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY(); + CellPair cell_pair(x,y); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + CellObjectGuids const& cell_guids = objmgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id); + + LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map); +} + +void +ObjectGridLoader::Visit(CreatureMapType &m) +{ + uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX(); + uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY(); + CellPair cell_pair(x,y); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + CellObjectGuids const& cell_guids = objmgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id); + + LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map); +} + +void +ObjectWorldLoader::Visit(CorpseMapType &m) +{ + uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX(); + uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY(); + CellPair cell_pair(x,y); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + // corpses are always added to spawn mode 0 and they are spawned by their instance id + CellObjectGuids const& cell_guids = objmgr.GetCellObjectGuids(i_map->GetId(), 0, cell_id); + LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map); +} + +void +ObjectGridLoader::Load(GridType &grid) +{ + { + TypeContainerVisitor loader(*this); + grid.Visit(loader); + } + + { + ObjectWorldLoader wloader(*this); + TypeContainerVisitor loader(wloader); + grid.Visit(loader); + i_corpses = wloader.i_corpses; + } +} + +void ObjectGridLoader::LoadN(void) +{ + i_gameObjects = 0; i_creatures = 0; i_corpses = 0; + i_cell.data.Part.cell_y = 0; + for(unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x) + { + i_cell.data.Part.cell_x = x; + for(unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y) + { + i_cell.data.Part.cell_y = y; + GridLoader loader; + loader.Load(i_grid(x, y), *this); + } + } + sLog.outDebug("%u GameObjects, %u Creatures, and %u Corpses/Bones loaded for grid %u on map %u", i_gameObjects, i_creatures, i_corpses,i_grid.GetGridId(), i_map->GetId()); +} + +void ObjectGridUnloader::MoveToRespawnN() +{ + for(unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x) + { + for(unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y) + { + ObjectGridRespawnMover mover; + mover.Move(i_grid(x, y)); + } + } +} + +void +ObjectGridUnloader::Unload(GridType &grid) +{ + TypeContainerVisitor unloader(*this); + grid.Visit(unloader); +} + +template +void +ObjectGridUnloader::Visit(GridRefManager &m) +{ + while(!m.isEmpty()) + { + T *obj = m.getFirst()->getSource(); + // if option set then object already saved at this moment + if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) + obj->SaveRespawnTime(); + ///- object must be out of world before delete + obj->RemoveFromWorld(); + ///- object will get delinked from the manager when deleted + delete obj; + } +} + +template<> +void +ObjectGridUnloader::Visit(CreatureMapType &m) +{ + // remove all cross-reference before deleting + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + iter->getSource()->CleanupsBeforeDelete(); + + while(!m.isEmpty()) + { + Creature *obj = m.getFirst()->getSource(); + // if option set then object already saved at this moment + if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) + obj->SaveRespawnTime(); + ///- object will get delinked from the manager when deleted + delete obj; + } +} + +void +ObjectGridStoper::Stop(GridType &grid) +{ + TypeContainerVisitor stoper(*this); + grid.Visit(stoper); +} + +void +ObjectGridStoper::Visit(CreatureMapType &m) +{ + // stop any fights at grid de-activation and remove dynobjects created at cast by creatures + for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) + { + iter->getSource()->CombatStop(); + iter->getSource()->DeleteThreatList(); + iter->getSource()->RemoveAllDynObjects(); + } +} + +template void ObjectGridUnloader::Visit(GameObjectMapType &); +template void ObjectGridUnloader::Visit(DynamicObjectMapType &); diff --git a/src/game/ObjectGridLoader.h b/src/game/ObjectGridLoader.h new file mode 100644 index 000000000..1590ba5c2 --- /dev/null +++ b/src/game/ObjectGridLoader.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_OBJECTGRIDLOADER_H +#define MANGOS_OBJECTGRIDLOADER_H + +#include "Utilities/TypeList.h" +#include "Platform/Define.h" +#include "GameSystem/GridLoader.h" +#include "GridDefines.h" +#include "Cell.h" + +class ObjectWorldLoader; + +class MANGOS_DLL_DECL ObjectGridLoader +{ + friend class ObjectWorldLoader; + + public: + ObjectGridLoader(NGridType &grid, Map* map, const Cell &cell) + : i_cell(cell), i_grid(grid), i_map(map), i_gameObjects(0), i_creatures(0), i_corpses (0) + {} + + void Load(GridType &grid); + void Visit(GameObjectMapType &m); + void Visit(CreatureMapType &m); + void Visit(CorpseMapType &) {} + + void Visit(DynamicObjectMapType&) { } + + void LoadN(void); + + private: + Cell i_cell; + NGridType &i_grid; + Map* i_map; + uint32 i_gameObjects; + uint32 i_creatures; + uint32 i_corpses; +}; + +class MANGOS_DLL_DECL ObjectGridUnloader +{ + public: + ObjectGridUnloader(NGridType &grid) : i_grid(grid) {} + + void MoveToRespawnN(); + void UnloadN() + { + for(unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x) + { + for(unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y) + { + GridLoader loader; + loader.Unload(i_grid(x, y), *this); + } + } + } + + void Unload(GridType &grid); + template void Visit(GridRefManager &m); + private: + NGridType &i_grid; +}; + +class MANGOS_DLL_DECL ObjectGridStoper +{ + public: + ObjectGridStoper(NGridType &grid) : i_grid(grid) {} + + void MoveToRespawnN(); + void StopN() + { + for(unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x) + { + for(unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y) + { + GridLoader loader; + loader.Stop(i_grid(x, y), *this); + } + } + } + + void Stop(GridType &grid); + void Visit(CreatureMapType &m); + + template void Visit(GridRefManager &) {} + private: + NGridType &i_grid; +}; + +typedef GridLoader GridLoaderType; +#endif diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp new file mode 100644 index 000000000..b90c5146b --- /dev/null +++ b/src/game/ObjectMgr.cpp @@ -0,0 +1,7009 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Database/SQLStorage.h" + +#include "Log.h" +#include "MapManager.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "UpdateMask.h" +#include "World.h" +#include "WorldSession.h" +#include "Group.h" +#include "Guild.h" +#include "ArenaTeam.h" +#include "Transports.h" +#include "ProgressBar.h" +#include "Policies/SingletonImp.h" +#include "Language.h" +#include "GameEvent.h" +#include "Spell.h" +#include "Chat.h" +#include "InstanceSaveMgr.h" +#include "SpellAuras.h" +#include "Util.h" + +INSTANTIATE_SINGLETON_1(ObjectMgr); + +ScriptMapMap sQuestEndScripts; +ScriptMapMap sQuestStartScripts; +ScriptMapMap sSpellScripts; +ScriptMapMap sGameObjectScripts; +ScriptMapMap sEventScripts; + +bool normalizePlayerName(std::string& name) +{ + if(name.empty()) + return false; + + wchar_t wstr_buf[MAX_INTERNAL_PLAYER_NAME+1]; + size_t wstr_len = MAX_INTERNAL_PLAYER_NAME; + + if(!Utf8toWStr(name,&wstr_buf[0],wstr_len)) + return false; + + wstr_buf[0] = wcharToUpper(wstr_buf[0]); + for(size_t i = 1; i < wstr_len; ++i) + wstr_buf[i] = wcharToLower(wstr_buf[i]); + + if(!WStrToUtf8(wstr_buf,wstr_len,name)) + return false; + + return true; +} + +LanguageDesc lang_description[LANGUAGES_COUNT] = +{ + { LANG_ADDON, 0, 0 }, + { LANG_UNIVERSAL, 0, 0 }, + { LANG_ORCISH, 669, SKILL_LANG_ORCISH }, + { LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN }, + { LANG_TAURAHE, 670, SKILL_LANG_TAURAHE }, + { LANG_DWARVISH, 672, SKILL_LANG_DWARVEN }, + { LANG_COMMON, 668, SKILL_LANG_COMMON }, + { LANG_DEMONIC, 815, SKILL_LANG_DEMON_TONGUE }, + { LANG_TITAN, 816, SKILL_LANG_TITAN }, + { LANG_THALASSIAN, 813, SKILL_LANG_THALASSIAN }, + { LANG_DRACONIC, 814, SKILL_LANG_DRACONIC }, + { LANG_KALIMAG, 817, SKILL_LANG_OLD_TONGUE }, + { LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH }, + { LANG_TROLL, 7341, SKILL_LANG_TROLL }, + { LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK }, + { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI }, + { LANG_ZOMBIE, 0, 0 }, + { LANG_GNOMISH_BINARY, 0, 0 }, + { LANG_GOBLIN_BINARY, 0, 0 } +}; + +LanguageDesc const* GetLanguageDescByID(uint32 lang) +{ + for(int i = 0; i < LANGUAGES_COUNT; ++i) + { + if(uint32(lang_description[i].lang_id) == lang) + return &lang_description[i]; + } + + return NULL; +} + +ObjectMgr::ObjectMgr() +{ + m_hiCharGuid = 1; + m_hiCreatureGuid = 1; + m_hiPetGuid = 1; + m_hiItemGuid = 1; + m_hiGoGuid = 1; + m_hiDoGuid = 1; + m_hiCorpseGuid = 1; + + m_hiPetNumber = 1; + + mGuildBankTabPrice.resize(GUILD_BANK_MAX_TABS); + mGuildBankTabPrice[0] = 100; + mGuildBankTabPrice[1] = 250; + mGuildBankTabPrice[2] = 500; + mGuildBankTabPrice[3] = 1000; + mGuildBankTabPrice[4] = 2500; + mGuildBankTabPrice[5] = 5000; + + // Only zero condition left, others will be added while loading DB tables + mConditions.resize(1); +} + +ObjectMgr::~ObjectMgr() +{ + for( QuestMap::iterator i = mQuestTemplates.begin( ); i != mQuestTemplates.end( ); ++ i ) + { + delete i->second; + } + mQuestTemplates.clear( ); + + for( GossipTextMap::iterator i = mGossipText.begin( ); i != mGossipText.end( ); ++ i ) + { + delete i->second; + } + mGossipText.clear( ); + + mAreaTriggers.clear(); + + for(PetLevelInfoMap::iterator i = petInfo.begin( ); i != petInfo.end( ); ++ i ) + { + delete[] i->second; + } + petInfo.clear(); + + // free only if loaded + for (int class_ = 0; class_ < MAX_CLASSES; ++class_) + delete[] playerClassInfo[class_].levelInfo; + + for (int race = 0; race < MAX_RACES; ++race) + for (int class_ = 0; class_ < MAX_CLASSES; ++class_) + delete[] playerInfo[race][class_].levelInfo; + + // free group and guild objects + for (GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr) + delete (*itr); + for (GuildSet::iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr) + delete (*itr); + + for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr) + delete itr->second; + + for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) + itr->second.Clear(); + + for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr) + itr->second.Clear(); +} + +Group * ObjectMgr::GetGroupByLeader(const uint64 &guid) const +{ + for(GroupSet::const_iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr) + if ((*itr)->GetLeaderGUID() == guid) + return *itr; + + return NULL; +} + +Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const +{ + for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++) + if ((*itr)->GetId() == GuildId) + return *itr; + + return NULL; +} + +Guild * ObjectMgr::GetGuildByName(std::string guildname) const +{ + for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++) + if ((*itr)->GetName() == guildname) + return *itr; + + return NULL; +} + +std::string ObjectMgr::GetGuildNameById(const uint32 GuildId) const +{ + for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++) + if ((*itr)->GetId() == GuildId) + return (*itr)->GetName(); + + return ""; +} + +Guild* ObjectMgr::GetGuildByLeader(const uint64 &guid) const +{ + for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr) + if( (*itr)->GetLeader() == guid) + return *itr; + + return NULL; +} + +ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const +{ + for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++) + if ((*itr)->GetId() == ArenaTeamId) + return *itr; + + return NULL; +} + +ArenaTeam* ObjectMgr::GetArenaTeamByName(std::string arenateamname) const +{ + for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++) + if ((*itr)->GetName() == arenateamname) + return *itr; + + return NULL; +} + +ArenaTeam* ObjectMgr::GetArenaTeamByCapitan(uint64 const& guid) const +{ + for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++) + if ((*itr)->GetCaptain() == guid) + return *itr; + + return NULL; +} + +AuctionHouseObject * ObjectMgr::GetAuctionsMap( uint32 location ) +{ + switch ( location ) + { + case 6: //horde + return & mHordeAuctions; + break; + case 2: //alliance + return & mAllianceAuctions; + break; + default: //neutral + return & mNeutralAuctions; + } +} + +uint32 ObjectMgr::GetAuctionCut(uint32 location, uint32 highBid) +{ + if (location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT)); + else + return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT)); +} + +uint32 ObjectMgr::GetAuctionDeposit(uint32 location, uint32 time, Item *pItem) +{ + float percentance; // in 0..1 + if ( location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + percentance = 0.75f; + else + percentance = 0.15f; + + percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT); + + return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) ); +} + +/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c +uint32 ObjectMgr::GetAuctionOutBid(uint32 currentBid) +{ + uint32 outbid = (currentBid / 100) * 5; + if (!outbid) + outbid = 1; + return outbid; +} + +//does not clear ram +void ObjectMgr::SendAuctionWonMail( AuctionEntry *auction ) +{ + Item *pItem = GetAItem(auction->item_guidlow); + if(!pItem) + return; + + uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); + Player *bidder = GetPlayer(bidder_guid); + + uint32 bidder_accId = 0; + + // data for gm.log + if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + { + uint32 bidder_security = 0; + std::string bidder_name; + if (bidder) + { + bidder_accId = bidder->GetSession()->GetAccountId(); + bidder_security = bidder->GetSession()->GetSecurity(); + bidder_name = bidder->GetName(); + } + else + { + bidder_accId = GetPlayerAccountIdByGUID(bidder_guid); + bidder_security = GetSecurityByAccount(bidder_accId); + + if(bidder_security > SEC_PLAYER ) // not do redundant DB requests + { + if(!GetPlayerNameByGUID(bidder_guid,bidder_name)) + bidder_name = GetMangosStringForDBCLocale(LANG_UNKNOWN); + } + } + + if( bidder_security > SEC_PLAYER ) + { + std::string owner_name; + if(!GetPlayerNameByGUID(auction->owner,owner_name)) + owner_name = GetMangosStringForDBCLocale(LANG_UNKNOWN); + + uint32 owner_accid = GetPlayerAccountIdByGUID(auction->owner); + + sLog.outCommand("GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", + bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid); + } + } + else if(!bidder) + bidder_accId = GetPlayerAccountIdByGUID(bidder_guid); + + // receiver exist + if(bidder || bidder_accId) + { + std::ostringstream msgAuctionWonSubject; + msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON; + + std::ostringstream msgAuctionWonBody; + msgAuctionWonBody.width(16); + msgAuctionWonBody << std::right << std::hex << auction->owner; + msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout; + sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() ); + + //prepare mail data... : + uint32 itemTextId = this->CreateItemText( msgAuctionWonBody.str() ); + + // set owner to bidder (to prevent delete item with sender char deleting) + // owner in `data` will set at mail receive and item extracting + CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow()); + CharacterDatabase.CommitTransaction(); + + MailItemsInfo mi; + mi.AddItem(auction->item_guidlow, auction->item_template, pItem); + + if (bidder) + bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template); + else + RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! + + // will delete item or place to receiver mail list + WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION); + } + // receiver not exist + else + { + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow()); + RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! + delete pItem; + } +} + +void ObjectMgr::SendAuctionSalePendingMail( AuctionEntry * auction ) +{ + uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); + Player *owner = GetPlayer(owner_guid); + + // owner exist (online or offline) + if(owner || GetPlayerAccountIdByGUID(owner_guid)) + { + std::ostringstream msgAuctionSalePendingSubject; + msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING; + + std::ostringstream msgAuctionSalePendingBody; + uint32 auctionCut = GetAuctionCut(auction->location, auction->bid); + + time_t distrTime = time(NULL) + HOUR; + + msgAuctionSalePendingBody.width(16); + msgAuctionSalePendingBody << std::right << std::hex << auction->bidder; + msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout; + msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:"; + msgAuctionSalePendingBody << secsToTimeBitFields(distrTime); + + sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str()); + + uint32 itemTextId = this->CreateItemText( msgAuctionSalePendingBody.str() ); + + WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION); + } +} + +//call this method to send mail to auction owner, when auction is successful, it does not clear ram +void ObjectMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) +{ + uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); + Player *owner = GetPlayer(owner_guid); + + uint32 owner_accId = 0; + if(!owner) + owner_accId = GetPlayerAccountIdByGUID(owner_guid); + + // owner exist + if(owner || owner_accId) + { + std::ostringstream msgAuctionSuccessfulSubject; + msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL; + + std::ostringstream auctionSuccessfulBody; + uint32 auctionCut = GetAuctionCut(auction->location, auction->bid); + + auctionSuccessfulBody.width(16); + auctionSuccessfulBody << std::right << std::hex << auction->bidder; + auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout; + auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut; + + sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str()); + + uint32 itemTextId = this->CreateItemText( auctionSuccessfulBody.str() ); + + uint32 profit = auction->bid + auction->deposit - auctionCut; + + if (owner) + { + //send auction owner notification, bidder must be current! + owner->GetSession()->SendAuctionOwnerNotification( auction ); + } + + WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR); + } +} + +//does not clear ram +void ObjectMgr::SendAuctionExpiredMail( AuctionEntry * auction ) +{ //return an item in auction to its owner by mail + Item *pItem = GetAItem(auction->item_guidlow); + if(!pItem) + { + sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow); + return; + } + + uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); + Player *owner = GetPlayer(owner_guid); + + uint32 owner_accId = 0; + if(!owner) + owner_accId = GetPlayerAccountIdByGUID(owner_guid); + + // owner exist + if(owner || owner_accId) + { + std::ostringstream subject; + subject << auction->item_template << ":0:" << AUCTION_EXPIRED; + + if ( owner ) + owner->GetSession()->SendAuctionOwnerNotification( auction ); + else + RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! + + MailItemsInfo mi; + mi.AddItem(auction->item_guidlow, auction->item_template, pItem); + + // will delete item or place to receiver mail list + WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); + } + // owner not found + else + { + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem->GetGUIDLow()); + RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! + delete pItem; + } +} + +CreatureInfo const* ObjectMgr::GetCreatureTemplate(uint32 id) +{ + return sCreatureStorage.LookupEntry(id); +} + +void ObjectMgr::LoadCreatureLocales() +{ + mCreatureLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,subname_loc1,name_loc2,subname_loc2,name_loc3,subname_loc3,name_loc4,subname_loc4,name_loc5,subname_loc5,name_loc6,subname_loc6,name_loc7,subname_loc7,name_loc8,subname_loc8 FROM locales_creature"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 creature locale strings. DB table `locales_creature` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + CreatureLocale& data = mCreatureLocaleMap[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[1+2*(i-1)].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Name.size() <= idx) + data.Name.resize(idx+1); + + data.Name[idx] = str; + } + } + str = fields[1+2*(i-1)+1].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.SubName.size() <= idx) + data.SubName.resize(idx+1); + + data.SubName[idx] = str; + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() ); +} + +void ObjectMgr::LoadCreatureTemplates() +{ + sCreatureStorage.Load(); + + sLog.outString( ">> Loaded %u creature definitions", sCreatureStorage.RecordCount ); + sLog.outString(); + + std::set heroicEntries; // already loaded heroic value in creatures + std::set hasHeroicEntries; // already loaded creatures with heroic entry values + + // check data correctness + for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i) + { + CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(i); + if(!cInfo) + continue; + + if(cInfo->HeroicEntry) + { + CreatureInfo const* heroicInfo = GetCreatureTemplate(cInfo->HeroicEntry); + if(!heroicInfo) + { + sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u not exist.",cInfo->HeroicEntry,cInfo->HeroicEntry); + continue; + } + + if(heroicEntries.find(i)!=heroicEntries.end()) + { + sLog.outErrorDb("Creature (Entry: %u) listed as heroic but have value in `heroic_entry`.",i); + continue; + } + + if(heroicEntries.find(cInfo->HeroicEntry)!=heroicEntries.end()) + { + sLog.outErrorDb("Creature (Entry: %u) already listed as heroic for another entry.",cInfo->HeroicEntry); + continue; + } + + if(hasHeroicEntries.find(cInfo->HeroicEntry)!=hasHeroicEntries.end()) + { + sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u have heroic entry also.",i,cInfo->HeroicEntry,cInfo->HeroicEntry); + continue; + } + + if(cInfo->npcflag != heroicInfo->npcflag) + { + sLog.outErrorDb("Creature (Entry: %u) has different `npcflag` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry); + continue; + } + + if(cInfo->classNum != heroicInfo->classNum) + { + sLog.outErrorDb("Creature (Entry: %u) has different `classNum` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry); + continue; + } + + if(cInfo->race != heroicInfo->race) + { + sLog.outErrorDb("Creature (Entry: %u) has different `race` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry); + continue; + } + + if(cInfo->trainer_type != heroicInfo->trainer_type) + { + sLog.outErrorDb("Creature (Entry: %u) has different `trainer_type` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry); + continue; + } + + if(cInfo->trainer_spell != heroicInfo->trainer_spell) + { + sLog.outErrorDb("Creature (Entry: %u) has different `trainer_spell` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry); + continue; + } + + hasHeroicEntries.insert(i); + heroicEntries.insert(cInfo->HeroicEntry); + } + + FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_A); + if(!factionTemplate) + sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_A template (%u)", cInfo->Entry, cInfo->faction_A); + + factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_H); + if(!factionTemplate) + sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H); + + CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry(cInfo->DisplayID_A); + if (!minfo) + sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u)", cInfo->Entry, cInfo->DisplayID_A); + minfo = sCreatureModelStorage.LookupEntry(cInfo->DisplayID_H); + if (!minfo) + sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H); + + if(cInfo->dmgschool >= MAX_SPELL_SCHOOL) + { + sLog.outErrorDb("Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`",cInfo->Entry,cInfo->dmgschool); + const_cast(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL; + } + + if(cInfo->baseattacktime == 0) + const_cast(cInfo)->baseattacktime = BASE_ATTACK_TIME; + + if(cInfo->rangeattacktime == 0) + const_cast(cInfo)->rangeattacktime = BASE_ATTACK_TIME; + + if((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE) + sLog.outErrorDb("Creature (Entry: %u) has wrong trainer type %u",cInfo->Entry,cInfo->trainer_type); + + if(cInfo->InhabitType <= 0 || cInfo->InhabitType > INHABIT_ANYWHERE) + { + sLog.outErrorDb("Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly",cInfo->Entry,cInfo->InhabitType); + const_cast(cInfo)->InhabitType = INHABIT_ANYWHERE; + } + + if(cInfo->PetSpellDataId) + { + CreatureSpellDataEntry const* spellDataId = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId); + if(!spellDataId) + sLog.outErrorDb("Creature (Entry: %u) has non-existing PetSpellDataId (%u)", cInfo->Entry, cInfo->PetSpellDataId); + } + + if(cInfo->MovementType >= MAX_DB_MOTION_TYPE) + { + sLog.outErrorDb("Creature (Entry: %u) has wrong movement generator type (%u), ignore and set to IDLE.",cInfo->Entry,cInfo->MovementType); + const_cast(cInfo)->MovementType = IDLE_MOTION_TYPE; + } + + if(cInfo->equipmentId > 0) // 0 no equipment + { + if(!GetEquipmentInfo(cInfo->equipmentId)) + { + sLog.outErrorDb("Table `creature_template` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", cInfo->Entry, cInfo->equipmentId); + const_cast(cInfo)->equipmentId = 0; + } + } + + /// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc + if(cInfo->scale <= 0.0f) + { + CreatureDisplayInfoEntry const* ScaleEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A); + const_cast(cInfo)->scale = ScaleEntry ? ScaleEntry->scale : 1.0f; + } + } +} + +void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr) +{ + // Now add the auras, format "spellid effectindex spellid effectindex..." + char *p,*s; + std::vector val; + s=p=(char*)reinterpret_cast(addon->auras); + if(p) + { + while (p[0]!=0) + { + ++p; + if (p[0]==' ') + { + val.push_back(atoi(s)); + s=++p; + } + } + if (p!=s) + val.push_back(atoi(s)); + + // free char* loaded memory + delete[] (char*)reinterpret_cast(addon->auras); + + // wrong list + if (val.size()%2) + { + addon->auras = NULL; + sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`.",guidEntryStr,addon->guidOrEntry,table); + return; + } + } + + // empty list + if(val.empty()) + { + addon->auras = NULL; + return; + } + + // replace by new strucutres array + const_cast(addon->auras) = new CreatureDataAddonAura[val.size()/2+1]; + + int i=0; + for(int j=0;j(addon->auras[i]); + cAura.spell_id = (uint32)val[2*j+0]; + cAura.effect_idx = (uint32)val[2*j+1]; + if ( cAura.effect_idx > 2 ) + { + sLog.outErrorDb("Creature (%s: %u) has wrong effect %u for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table); + continue; + } + SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura.spell_id); + if (!AdditionalSpellInfo) + { + sLog.outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table); + continue; + } + + if (!AdditionalSpellInfo->Effect[cAura.effect_idx] || !AdditionalSpellInfo->EffectApplyAuraName[cAura.effect_idx]) + { + sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table); + continue; + } + + ++i; + } + + // fill terminator element (after last added) + CreatureDataAddonAura& endAura = const_cast(addon->auras[i]); + endAura.spell_id = 0; + endAura.effect_idx = 0; +} + +void ObjectMgr::LoadCreatureAddons() +{ + sCreatureInfoAddonStorage.Load(); + + sLog.outString( ">> Loaded %u creature template addons", sCreatureInfoAddonStorage.RecordCount ); + sLog.outString(); + + // check data correctness and convert 'auras' + for(uint32 i = 1; i < sCreatureInfoAddonStorage.MaxEntry; ++i) + { + CreatureDataAddon const* addon = sCreatureInfoAddonStorage.LookupEntry(i); + if(!addon) + continue; + + ConvertCreatureAddonAuras(const_cast(addon), "creature_template_addon", "Entry"); + + if(!sCreatureStorage.LookupEntry(addon->guidOrEntry)) + sLog.outErrorDb("Creature (Entry: %u) does not exist but has a record in `creature_template_addon`",addon->guidOrEntry); + } + + sCreatureDataAddonStorage.Load(); + + sLog.outString( ">> Loaded %u creature addons", sCreatureDataAddonStorage.RecordCount ); + sLog.outString(); + + // check data correctness and convert 'auras' + for(uint32 i = 1; i < sCreatureDataAddonStorage.MaxEntry; ++i) + { + CreatureDataAddon const* addon = sCreatureDataAddonStorage.LookupEntry(i); + if(!addon) + continue; + + ConvertCreatureAddonAuras(const_cast(addon), "creature_addon", "GUIDLow"); + + if(mCreatureDataMap.find(addon->guidOrEntry)==mCreatureDataMap.end()) + sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`",addon->guidOrEntry); + } +} + +EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry) +{ + return sEquipmentStorage.LookupEntry(entry); +} + +void ObjectMgr::LoadEquipmentTemplates() +{ + sEquipmentStorage.Load(); + + sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount ); + sLog.outString(); +} + +CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid) +{ + return sCreatureModelStorage.LookupEntry(modelid); +} + +uint32 ObjectMgr::ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data) +{ + // Load creature model (display id) + uint32 display_id; + if (!data || data->displayid == 0) // use defaults from the template + { + // DisplayID_A is used if no team is given + if (team == HORDE) + display_id = (cinfo->DisplayID_H2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_H2 : cinfo->DisplayID_H; + else + display_id = (cinfo->DisplayID_A2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_A2 : cinfo->DisplayID_A; + } + else // overriden in creature data + display_id = data->displayid; + + return display_id; +} + +CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(uint32 display_id) +{ + CreatureModelInfo const *minfo = GetCreatureModelInfo(display_id); + if(!minfo) + return NULL; + + // If a model for another gender exists, 50% chance to use it + if(minfo->modelid_other_gender != 0 && urand(0,1) == 0) + { + CreatureModelInfo const *minfo_tmp = GetCreatureModelInfo(minfo->modelid_other_gender); + if(!minfo_tmp) + { + sLog.outErrorDb("Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", minfo->modelid, minfo->modelid_other_gender); + return minfo; // not fatal, just use the previous one + } + else + return minfo_tmp; + } + else + return minfo; +} + +void ObjectMgr::LoadCreatureModelInfo() +{ + sCreatureModelStorage.Load(); + + sLog.outString( ">> Loaded %u creature model based info", sCreatureModelStorage.RecordCount ); + sLog.outString(); +} + +void ObjectMgr::LoadCreatures() +{ + uint32 count = 0; + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid," + // 4 5 6 7 8 9 10 11 + "equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint," + // 12 13 14 15 16 17 + "curhealth, curmana, DeathState, MovementType, spawnMask, event " + "FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outErrorDb(">> Loaded 0 creature. DB table `creature` is empty."); + return; + } + + // build single time for check creature data + std::set heroicCreatures; + for(uint32 i = 0; i < sCreatureStorage.MaxEntry; ++i) + if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(i)) + if(cInfo->HeroicEntry) + heroicCreatures.insert(cInfo->HeroicEntry); + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 guid = fields[0].GetUInt32(); + + CreatureData& data = mCreatureDataMap[guid]; + + data.id = fields[ 1].GetUInt32(); + data.mapid = fields[ 2].GetUInt32(); + data.displayid = fields[ 3].GetUInt32(); + data.equipmentId = fields[ 4].GetUInt32(); + data.posX = fields[ 5].GetFloat(); + data.posY = fields[ 6].GetFloat(); + data.posZ = fields[ 7].GetFloat(); + data.orientation = fields[ 8].GetFloat(); + data.spawntimesecs = fields[ 9].GetUInt32(); + data.spawndist = fields[10].GetFloat(); + data.currentwaypoint= fields[11].GetUInt32(); + data.curhealth = fields[12].GetUInt32(); + data.curmana = fields[13].GetUInt32(); + data.is_dead = fields[14].GetBool(); + data.movementType = fields[15].GetUInt8(); + data.spawnMask = fields[16].GetUInt8(); + int16 gameEvent = fields[17].GetInt16(); + + CreatureInfo const* cInfo = GetCreatureTemplate(data.id); + if(!cInfo) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u) with not existed creature entry %u, skipped.",guid,data.id ); + continue; + } + + if(heroicCreatures.find(data.id)!=heroicCreatures.end()) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u) that listed as heroic template in `creature_template`, skipped.",guid,data.id ); + continue; + } + + if(data.equipmentId > 0) // -1 no equipment, 0 use default + { + if(!GetEquipmentInfo(data.equipmentId)) + { + sLog.outErrorDb("Table `creature` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", data.id, data.equipmentId); + data.equipmentId = -1; + } + } + + if(cInfo->RegenHealth && data.curhealth < cInfo->minhealth) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`RegenHealth`=1 and low current health (%u), `creature_template`.`minhealth`=%u.",guid,data.id,data.curhealth, cInfo->minhealth ); + data.curhealth = cInfo->minhealth; + } + + if(data.curmana < cInfo->minmana) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with low current mana (%u), `creature_template`.`minmana`=%u.",guid,data.id,data.curmana, cInfo->minmana ); + data.curmana = cInfo->minmana; + } + + if(data.spawndist < 0.0f) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `spawndist`< 0, set to 0.",guid,data.id ); + data.spawndist = 0.0f; + } + else if(data.movementType == RANDOM_MOTION_TYPE) + { + if(data.spawndist == 0.0f) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=1 (random movement) but with `spawndist`=0, replace by idle movement type (0).",guid,data.id ); + data.movementType = IDLE_MOTION_TYPE; + } + } + else if(data.movementType == IDLE_MOTION_TYPE) + { + if(data.spawndist != 0.0f) + { + sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=0 (idle) have `spawndist`<>0, set to 0.",guid,data.id ); + data.spawndist = 0.0f; + } + } + + if (gameEvent==0) // if not this is to be managed by GameEvent System + AddCreatureToGrid(guid, &data); + ++count; + + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u creatures", mCreatureDataMap.size() ); +} + +void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data) +{ + uint8 mask = data->spawnMask; + for(uint8 i = 0; mask != 0; i++, mask >>= 1) + { + if(mask & 1) + { + CellPair cell_pair = MaNGOS::ComputeCellPair(data->posX, data->posY); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id]; + cell_guids.creatures.insert(guid); + } + } +} + +void ObjectMgr::RemoveCreatureFromGrid(uint32 guid, CreatureData const* data) +{ + uint8 mask = data->spawnMask; + for(uint8 i = 0; mask != 0; i++, mask >>= 1) + { + if(mask & 1) + { + CellPair cell_pair = MaNGOS::ComputeCellPair(data->posX, data->posY); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id]; + cell_guids.creatures.erase(guid); + } + } +} + +void ObjectMgr::LoadGameobjects() +{ + uint32 count = 0; + + // 0 1 2 3 4 5 6 + QueryResult *result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation," + // 7 8 9 10 11 12 13 14 15 + "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, event " + "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 gameobjects. DB table `gameobject` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 guid = fields[0].GetUInt32(); + + GameObjectData& data = mGameObjectDataMap[guid]; + + data.id = fields[ 1].GetUInt32(); + data.mapid = fields[ 2].GetUInt32(); + data.posX = fields[ 3].GetFloat(); + data.posY = fields[ 4].GetFloat(); + data.posZ = fields[ 5].GetFloat(); + data.orientation = fields[ 6].GetFloat(); + data.rotation0 = fields[ 7].GetFloat(); + data.rotation1 = fields[ 8].GetFloat(); + data.rotation2 = fields[ 9].GetFloat(); + data.rotation3 = fields[10].GetFloat(); + data.spawntimesecs = fields[11].GetInt32(); + data.animprogress = fields[12].GetUInt32(); + data.go_state = fields[13].GetUInt32(); + data.spawnMask = fields[14].GetUInt8(); + int16 gameEvent = fields[15].GetInt16(); + + GameObjectInfo const* gInfo = GetGameObjectInfo(data.id); + if(!gInfo) + { + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u) with not existed gameobject entry %u, skipped.",guid,data.id ); + continue; + } + + if (gameEvent==0) // if not this is to be managed by GameEvent System + AddGameobjectToGrid(guid, &data); + ++count; + + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u gameobjects", mGameObjectDataMap.size()); +} + +void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data) +{ + uint8 mask = data->spawnMask; + for(uint8 i = 0; mask != 0; i++, mask >>= 1) + { + if(mask & 1) + { + CellPair cell_pair = MaNGOS::ComputeCellPair(data->posX, data->posY); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id]; + cell_guids.gameobjects.insert(guid); + } + } +} + +void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data) +{ + uint8 mask = data->spawnMask; + for(uint8 i = 0; mask != 0; i++, mask >>= 1) + { + if(mask & 1) + { + CellPair cell_pair = MaNGOS::ComputeCellPair(data->posX, data->posY); + uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; + + CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id]; + cell_guids.gameobjects.erase(guid); + } + } +} + +void ObjectMgr::LoadCreatureRespawnTimes() +{ + // remove outdated data + WorldDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); + + uint32 count = 0; + + QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM creature_respawn"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outString(">> Loaded 0 creature respawn time."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 loguid = fields[0].GetUInt32(); + uint64 respawn_time = fields[1].GetUInt64(); + uint32 instance = fields[2].GetUInt32(); + + mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time); + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString( ">> Loaded %u creature respawn times", mCreatureRespawnTimes.size() ); + sLog.outString(); +} + +void ObjectMgr::LoadGameobjectRespawnTimes() +{ + // remove outdated data + WorldDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); + + uint32 count = 0; + + QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM gameobject_respawn"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outString(">> Loaded 0 gameobject respawn time."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 loguid = fields[0].GetUInt32(); + uint64 respawn_time = fields[1].GetUInt64(); + uint32 instance = fields[2].GetUInt32(); + + mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time); + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString( ">> Loaded %u gameobject respawn times", mGORespawnTimes.size() ); + sLog.outString(); +} + +// name must be checked to correctness (if received) before call this function +uint64 ObjectMgr::GetPlayerGUIDByName(std::string name) const +{ + uint64 guid = 0; + + CharacterDatabase.escape_string(name); + + // Player name safe to sending to DB (checked at login) and this function using + QueryResult *result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE name = '%s'", name.c_str()); + if(result) + { + guid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); + + delete result; + } + + return guid; +} + +bool ObjectMgr::GetPlayerNameByGUID(const uint64 &guid, std::string &name) const +{ + // prevent DB access for online player + if(Player* player = GetPlayer(guid)) + { + name = player->GetName(); + return true; + } + + QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + + if(result) + { + name = (*result)[0].GetCppString(); + delete result; + return true; + } + + return false; +} + +uint32 ObjectMgr::GetPlayerTeamByGUID(const uint64 &guid) const +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT race FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + + if(result) + { + uint8 race = (*result)[0].GetUInt8(); + delete result; + return Player::TeamForRace(race); + } + + return 0; +} + +uint32 ObjectMgr::GetPlayerAccountIdByGUID(const uint64 &guid) const +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); + if(result) + { + uint32 acc = (*result)[0].GetUInt32(); + delete result; + return acc; + } + + return 0; +} + +uint32 ObjectMgr::GetSecurityByAccount(uint32 acc_id) const +{ + QueryResult *result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id); + if(result) + { + uint32 sec = (*result)[0].GetUInt32(); + delete result; + return sec; + } + + return 0; +} + +bool ObjectMgr::GetAccountNameByAccount(uint32 acc_id, std::string &name) const +{ + QueryResult *result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id); + if(result) + { + name = (*result)[0].GetCppString(); + delete result; + return true; + } + + return false; +} + +uint32 ObjectMgr::GetAccountByAccountName(std::string name) const +{ + loginDatabase.escape_string(name); + QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", name.c_str()); + if(result) + { + uint32 id = (*result)[0].GetUInt32(); + delete result; + return id; + } + + return 0; +} + +void ObjectMgr::LoadAuctions() +{ + QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse"); + if( !result ) + return; + + Field *fields = result->Fetch(); + uint32 AuctionCount=fields[0].GetUInt32(); + delete result; + + if(!AuctionCount) + return; + + result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" ); + if( !result ) + return; + + barGoLink bar( AuctionCount ); + + AuctionEntry *aItem; + + do + { + fields = result->Fetch(); + + bar.step(); + + aItem = new AuctionEntry; + aItem->Id = fields[0].GetUInt32(); + aItem->auctioneer = fields[1].GetUInt32(); + aItem->item_guidlow = fields[2].GetUInt32(); + aItem->item_template = fields[3].GetUInt32(); + aItem->owner = fields[4].GetUInt32(); + aItem->buyout = fields[5].GetUInt32(); + aItem->time = fields[6].GetUInt32(); + aItem->bidder = fields[7].GetUInt32(); + aItem->bid = fields[8].GetUInt32(); + aItem->startbid = fields[9].GetUInt32(); + aItem->deposit = fields[10].GetUInt32(); + aItem->location = fields[11].GetUInt8(); + //check if sold item exists + if ( this->GetAItem( aItem->item_guidlow ) ) + { + GetAuctionsMap( aItem->location )->AddAuction(aItem); + } + else + { + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id); + sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow); + delete aItem; + } + } while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u auctions", AuctionCount ); + sLog.outString(); +} + +void ObjectMgr::LoadItemLocales() +{ + mItemLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,description_loc1,name_loc2,description_loc2,name_loc3,description_loc3,name_loc4,description_loc4,name_loc5,description_loc5,name_loc6,description_loc6,name_loc7,description_loc7,name_loc8,description_loc8 FROM locales_item"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 Item locale strings. DB table `locales_item` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + ItemLocale& data = mItemLocaleMap[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[1+2*(i-1)].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Name.size() <= idx) + data.Name.resize(idx+1); + + data.Name[idx] = str; + } + } + + str = fields[1+2*(i-1)+1].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Description.size() <= idx) + data.Description.resize(idx+1); + + data.Description[idx] = str; + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u Item locale strings", mItemLocaleMap.size() ); +} + +void ObjectMgr::LoadItemPrototypes() +{ + sItemStorage.Load (); + sLog.outString( ">> Loaded %u item prototypes", sItemStorage.RecordCount ); + sLog.outString(); + + // check data correctness + for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i) + { + ItemPrototype const* proto = sItemStorage.LookupEntry(i); + ItemEntry const *dbcitem = sItemStore.LookupEntry(i); + if(!proto) + { + /* to many errors, and possible not all items really used in game + if (dbcitem) + sLog.outErrorDb("Item (Entry: %u) doesn't exists in DB, but must exist.",i); + */ + continue; + } + + if(dbcitem) + { + if(proto->InventoryType != dbcitem->InventoryType) + { + sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).",i,proto->InventoryType,dbcitem->InventoryType); + // It safe let use InventoryType from DB + } + + if(proto->DisplayInfoID != dbcitem->DisplayId) + { + sLog.outErrorDb("Item (Entry: %u) not correct %u display id, must be %u (using it).",i,proto->DisplayInfoID,dbcitem->DisplayId); + const_cast(proto)->DisplayInfoID = dbcitem->DisplayId; + } + if(proto->Sheath != dbcitem->Sheath) + { + sLog.outErrorDb("Item (Entry: %u) not correct %u sheath, must be %u (using it).",i,proto->Sheath,dbcitem->Sheath); + const_cast(proto)->Sheath = dbcitem->Sheath; + } + } + else + { + sLog.outErrorDb("Item (Entry: %u) not correct (not listed in list of existed items).",i); + } + + if(proto->Class >= MAX_ITEM_CLASS) + { + sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class); + const_cast(proto)->Class = ITEM_CLASS_JUNK; + } + + if(proto->SubClass >= MaxItemSubclassValues[proto->Class]) + { + sLog.outErrorDb("Item (Entry: %u) has wrong Subclass value (%u) for class %u",i,proto->SubClass,proto->Class); + const_cast(proto)->SubClass = 0;// exist for all item classes + } + + if(proto->Quality >= MAX_ITEM_QUALITY) + { + sLog.outErrorDb("Item (Entry: %u) has wrong Quality value (%u)",i,proto->Quality); + const_cast(proto)->Quality = ITEM_QUALITY_NORMAL; + } + + if(proto->BuyCount <= 0) + { + sLog.outErrorDb("Item (Entry: %u) has wrong BuyCount value (%u), set to default(1).",i,proto->BuyCount); + const_cast(proto)->BuyCount = 1; + } + + if(proto->InventoryType >= MAX_INVTYPE) + { + sLog.outErrorDb("Item (Entry: %u) has wrong InventoryType value (%u)",i,proto->InventoryType); + const_cast(proto)->InventoryType = INVTYPE_NON_EQUIP; + } + + if(proto->RequiredSkill >= MAX_SKILL_TYPE) + { + sLog.outErrorDb("Item (Entry: %u) has wrong RequiredSkill value (%u)",i,proto->RequiredSkill); + const_cast(proto)->RequiredSkill = 0; + } + + if(!(proto->AllowableClass & CLASSMASK_ALL_PLAYABLE)) + { + sLog.outErrorDb("Item (Entry: %u) not have in `AllowableClass` any playable classes (%u) and can't be equipped.",i,proto->AllowableClass); + } + + if(!(proto->AllowableRace & RACEMASK_ALL_PLAYABLE)) + { + sLog.outErrorDb("Item (Entry: %u) not have in `AllowableRace` any playable races (%u) and can't be equipped.",i,proto->AllowableRace); + } + + if(proto->RequiredSpell && !sSpellStore.LookupEntry(proto->RequiredSpell)) + { + sLog.outErrorDb("Item (Entry: %u) have wrong (non-existed) spell in RequiredSpell (%u)",i,proto->RequiredSpell); + const_cast(proto)->RequiredSpell = 0; + } + + if(proto->RequiredReputationRank >= MAX_REPUTATION_RANK) + sLog.outErrorDb("Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used.",i,proto->RequiredReputationRank); + + if(proto->RequiredReputationFaction) + { + if(!sFactionStore.LookupEntry(proto->RequiredReputationFaction)) + { + sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)",i,proto->RequiredReputationFaction); + const_cast(proto)->RequiredReputationFaction = 0; + } + + if(proto->RequiredReputationRank == MIN_REPUTATION_RANK) + sLog.outErrorDb("Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.",i); + } + else if(proto->RequiredReputationRank > MIN_REPUTATION_RANK) + sLog.outErrorDb("Item (Entry: %u) has RequiredReputationFaction ==0 but RequiredReputationRank > 0, rank setting is useless.",i); + + if(proto->Stackable==0) + { + sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%u), replace by default 1.",i,proto->Stackable); + const_cast(proto)->Stackable = 1; + } + else if(proto->Stackable > 255) + { + sLog.outErrorDb("Item (Entry: %u) has too large value in stackable (%u), replace by hardcoded upper limit (255).",i,proto->Stackable); + const_cast(proto)->Stackable = 255; + } + + for (int j = 0; j < 10; j++) + { + // for ItemStatValue != 0 + if(proto->ItemStat[j].ItemStatValue && proto->ItemStat[j].ItemStatType >= MAX_ITEM_MOD) + { + sLog.outErrorDb("Item (Entry: %u) has wrong stat_type%d (%u)",i,j+1,proto->ItemStat[j].ItemStatType); + const_cast(proto)->ItemStat[j].ItemStatType = 0; + } + } + + for (int j = 0; j < 5; j++) + { + if(proto->Damage[j].DamageType >= MAX_SPELL_SCHOOL) + { + sLog.outErrorDb("Item (Entry: %u) has wrong dmg_type%d (%u)",i,j+1,proto->Damage[j].DamageType); + const_cast(proto)->Damage[j].DamageType = 0; + } + } + + // special format + if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) + { + // spell_1 + if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) + { + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format",i,0+1,proto->Spells[0].SpellTrigger); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + + // spell_2 have learning spell + if(proto->Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID) + { + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.",i,1+1,proto->Spells[1].SpellTrigger); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + else if(!proto->Spells[1].SpellId) + { + sLog.outErrorDb("Item (Entry: %u) not has expected spell in spellid_%d in special learning format.",i,1+1); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + else + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[1].SpellId); + if(!spellInfo) + { + sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + // allowed only in special format + else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) + { + sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + } + + // spell_3*,spell_4*,spell_5* is empty + for (int j = 2; j < 5; j++) + { + if(proto->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) + { + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger); + const_cast(proto)->Spells[j].SpellId = 0; + const_cast(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + else if(proto->Spells[j].SpellId != 0) + { + sLog.outErrorDb("Item (Entry: %u) has wrong spell in spellid_%d (%u) for learning special format",i,j+1,proto->Spells[j].SpellId); + const_cast(proto)->Spells[j].SpellId = 0; + } + } + } + // normal spell list + else + { + for (int j = 0; j < 5; j++) + { + if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID) + { + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger); + const_cast(proto)->Spells[j].SpellId = 0; + const_cast(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + + if(proto->Spells[j].SpellId) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[j].SpellId); + if(!spellInfo) + { + sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId); + const_cast(proto)->Spells[j].SpellId = 0; + } + // allowed only in special format + else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) + { + sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId); + const_cast(proto)->Spells[j].SpellId = 0; + } + } + } + } + + if(proto->Bonding >= MAX_BIND_TYPE) + sLog.outErrorDb("Item (Entry: %u) has wrong Bonding value (%u)",i,proto->Bonding); + + if(proto->PageText && !sPageTextStore.LookupEntry(proto->PageText)) + sLog.outErrorDb("Item (Entry: %u) has non existing first page (Id:%u)", i,proto->PageText); + + if(proto->LockID && !sLockStore.LookupEntry(proto->LockID)) + sLog.outErrorDb("Item (Entry: %u) has wrong LockID (%u)",i,proto->LockID); + + if(proto->Sheath >= MAX_SHEATHETYPE) + { + sLog.outErrorDb("Item (Entry: %u) has wrong Sheath (%u)",i,proto->Sheath); + const_cast(proto)->Sheath = SHEATHETYPE_NONE; + } + + if(proto->RandomProperty && !sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(proto->RandomProperty))) + { + sLog.outErrorDb("Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)",i,proto->RandomProperty); + const_cast(proto)->RandomProperty = 0; + } + + if(proto->RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(proto->RandomSuffix))) + { + sLog.outErrorDb("Item (Entry: %u) has wrong RandomSuffix (%u)",i,proto->RandomSuffix); + const_cast(proto)->RandomSuffix = 0; + } + + if(proto->ItemSet && !sItemSetStore.LookupEntry(proto->ItemSet)) + { + sLog.outErrorDb("Item (Entry: %u) have wrong ItemSet (%u)",i,proto->ItemSet); + const_cast(proto)->ItemSet = 0; + } + + if(proto->Area && !GetAreaEntryByAreaID(proto->Area)) + sLog.outErrorDb("Item (Entry: %u) has wrong Area (%u)",i,proto->Area); + + if(proto->Map && !sMapStore.LookupEntry(proto->Map)) + sLog.outErrorDb("Item (Entry: %u) has wrong Map (%u)",i,proto->Map); + + if(proto->TotemCategory && !sTotemCategoryStore.LookupEntry(proto->TotemCategory)) + sLog.outErrorDb("Item (Entry: %u) has wrong TotemCategory (%u)",i,proto->TotemCategory); + + for (int j = 0; j < 3; j++) + { + if(proto->Socket[j].Color && (proto->Socket[j].Color & SOCKET_COLOR_ALL) != proto->Socket[j].Color) + { + sLog.outErrorDb("Item (Entry: %u) has wrong socketColor_%d (%u)",i,j+1,proto->Socket[j].Color); + const_cast(proto)->Socket[j].Color = 0; + } + } + + if(proto->GemProperties && !sGemPropertiesStore.LookupEntry(proto->GemProperties)) + sLog.outErrorDb("Item (Entry: %u) has wrong GemProperties (%u)",i,proto->GemProperties); + + if(proto->FoodType >= MAX_PET_DIET) + { + sLog.outErrorDb("Item (Entry: %u) has wrong FoodType value (%u)",i,proto->FoodType); + const_cast(proto)->FoodType = 0; + } + } + + // this DBC used currently only for check item templates in DB. + sItemStore.Clear(); +} + +void ObjectMgr::LoadAuctionItems() +{ + QueryResult *result = CharacterDatabase.Query( "SELECT itemguid,item_template FROM auctionhouse" ); + + if( !result ) + return; + + barGoLink bar( result->GetRowCount() ); + + uint32 count = 0; + + Field *fields; + do + { + bar.step(); + + fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 item_template = fields[1].GetUInt32(); + + ItemPrototype const *proto = GetItemPrototype(item_template); + + if(!proto) + { + sLog.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template); + continue; + } + + Item *item = NewItemOrBag(proto); + + if(!item->LoadFromDB(item_guid,0)) + { + delete item; + continue; + } + AddAItem(item); + + ++count; + } + while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u auction items", count ); +} + +void ObjectMgr::LoadPetLevelInfo() +{ + // Loading levels data + { + // 0 1 2 3 4 5 6 7 8 9 + QueryResult *result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u level pet stats definitions", count ); + sLog.outErrorDb( "Error loading `pet_levelstats` table or empty table."); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 creature_id = fields[0].GetUInt32(); + if(!sCreatureStorage.LookupEntry(creature_id)) + { + sLog.outErrorDb("Wrong creature id %u in `pet_levelstats` table, ignoring.",creature_id); + continue; + } + + uint32 current_level = fields[1].GetUInt32(); + if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + if(current_level > 255) // hardcoded level maximum + sLog.outErrorDb("Wrong (> 255) level %u in `pet_levelstats` table, ignoring.",current_level); + else + sLog.outDetail("Unused (> MaxPlayerLevel in mangosd.conf) level %u in `pet_levelstats` table, ignoring.",current_level); + continue; + } + else if(current_level < 1) + { + sLog.outErrorDb("Wrong (<1) level %u in `pet_levelstats` table, ignoring.",current_level); + continue; + } + + PetLevelInfo*& pInfoMapEntry = petInfo[creature_id]; + + if(pInfoMapEntry==NULL) + pInfoMapEntry = new PetLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)]; + + // data for level 1 stored in [0] array element, ... + PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level-1]; + + pLevelInfo->health = fields[2].GetUInt16(); + pLevelInfo->mana = fields[3].GetUInt16(); + pLevelInfo->armor = fields[9].GetUInt16(); + + for (int i = 0; i < MAX_STATS; i++) + { + pLevelInfo->stats[i] = fields[i+4].GetUInt16(); + } + + bar.step(); + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u level pet stats definitions", count ); + } + + // Fill gaps and check integrity + for (PetLevelInfoMap::iterator itr = petInfo.begin(); itr != petInfo.end(); ++itr) + { + PetLevelInfo* pInfo = itr->second; + + // fatal error if no level 1 data + if(!pInfo || pInfo[0].health == 0 ) + { + sLog.outErrorDb("Creature %u does not have pet stats data for Level 1!",itr->first); + exit(1); + } + + // fill level gaps + for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) + { + if(pInfo[level].health == 0) + { + sLog.outErrorDb("Creature %u has no data for Level %i pet stats data, using data of Level %i.",itr->first,level+1, level); + pInfo[level] = pInfo[level-1]; + } + } + } +} + +PetLevelInfo const* ObjectMgr::GetPetLevelInfo(uint32 creature_id, uint32 level) const +{ + if(level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); + + PetLevelInfoMap::const_iterator itr = petInfo.find(creature_id); + if(itr == petInfo.end()) + return NULL; + + return &itr->second[level-1]; // data for level 1 stored in [0] array element, ... +} + +void ObjectMgr::LoadPlayerInfo() +{ + // Load playercreate + { + // 0 1 2 3 4 5 6 + QueryResult *result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z FROM playercreateinfo"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u player create definitions", count ); + sLog.outErrorDb( "Error loading `playercreateinfo` table or empty table."); + exit(1); + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_race = fields[0].GetUInt32(); + uint32 current_class = fields[1].GetUInt32(); + uint32 mapId = fields[2].GetUInt32(); + uint32 zoneId = fields[3].GetUInt32(); + float positionX = fields[4].GetFloat(); + float positionY = fields[5].GetFloat(); + float positionZ = fields[6].GetFloat(); + + if(current_race >= MAX_RACES) + { + sLog.outErrorDb("Wrong race %u in `playercreateinfo` table, ignoring.",current_race); + continue; + } + + ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race); + if(!rEntry) + { + sLog.outErrorDb("Wrong race %u in `playercreateinfo` table, ignoring.",current_race); + continue; + } + + if(current_class >= MAX_CLASSES) + { + sLog.outErrorDb("Wrong class %u in `playercreateinfo` table, ignoring.",current_class); + continue; + } + + if(!sChrClassesStore.LookupEntry(current_class)) + { + sLog.outErrorDb("Wrong class %u in `playercreateinfo` table, ignoring.",current_class); + continue; + } + + // accept DB data only for valid position (and non instanceable) + if( !MapManager::IsValidMapCoord(mapId,positionX,positionY,positionZ) ) + { + sLog.outErrorDb("Wrong home position for class %u race %u pair in `playercreateinfo` table, ignoring.",current_class,current_race); + continue; + } + + if( sMapStore.LookupEntry(mapId)->Instanceable() ) + { + sLog.outErrorDb("Home position in instanceable map for class %u race %u pair in `playercreateinfo` table, ignoring.",current_class,current_race); + continue; + } + + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; + + pInfo->mapId = mapId; + pInfo->zoneId = zoneId; + pInfo->positionX = positionX; + pInfo->positionY = positionY; + pInfo->positionZ = positionZ; + + pInfo->displayId_m = rEntry->model_m; + pInfo->displayId_f = rEntry->model_f; + + bar.step(); + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u player create definitions", count ); + } + + // Load playercreate items + { + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u player create items", count ); + sLog.outErrorDb( "Error loading `playercreateinfo_item` table or empty table."); + } + else + { + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_race = fields[0].GetUInt32(); + if(current_race >= MAX_RACES) + { + sLog.outErrorDb("Wrong race %u in `playercreateinfo_item` table, ignoring.",current_race); + continue; + } + + uint32 current_class = fields[1].GetUInt32(); + if(current_class >= MAX_CLASSES) + { + sLog.outErrorDb("Wrong class %u in `playercreateinfo_item` table, ignoring.",current_class); + continue; + } + + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; + + uint32 item_id = fields[2].GetUInt32(); + + if(!GetItemPrototype(item_id)) + { + sLog.outErrorDb("Item id %u (race %u class %u) in `playercreateinfo_item` table but not listed in `item_template`, ignoring.",item_id,current_race,current_class); + continue; + } + + uint32 amount = fields[3].GetUInt32(); + + if(!amount) + { + sLog.outErrorDb("Item id %u (class %u race %u) have amount==0 in `playercreateinfo_item` table, ignoring.",item_id,current_race,current_class); + continue; + } + + pInfo->item.push_back(PlayerCreateInfoItem( item_id, amount)); + + bar.step(); + ++count; + } + while(result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u player create items", count ); + } + } + + // Load playercreate spells + { + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u player create spells", count ); + sLog.outErrorDb( "Error loading `playercreateinfo_spell` table or empty table."); + } + else + { + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_race = fields[0].GetUInt32(); + if(current_race >= MAX_RACES) + { + sLog.outErrorDb("Wrong race %u in `playercreateinfo_spell` table, ignoring.",current_race); + continue; + } + + uint32 current_class = fields[1].GetUInt32(); + if(current_class >= MAX_CLASSES) + { + sLog.outErrorDb("Wrong class %u in `playercreateinfo_spell` table, ignoring.",current_class); + continue; + } + + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; + pInfo->spell.push_back(CreateSpellPair(fields[2].GetUInt16(), fields[3].GetUInt8())); + + bar.step(); + ++count; + } + while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u player create spells", count ); + } + } + + // Load playercreate actions + { + // 0 1 2 3 4 5 + QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type, misc FROM playercreateinfo_action"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u player create actions", count ); + sLog.outErrorDb( "Error loading `playercreateinfo_action` table or empty table."); + } + else + { + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_race = fields[0].GetUInt32(); + if(current_race >= MAX_RACES) + { + sLog.outErrorDb("Wrong race %u in `playercreateinfo_action` table, ignoring.",current_race); + continue; + } + + uint32 current_class = fields[1].GetUInt32(); + if(current_class >= MAX_CLASSES) + { + sLog.outErrorDb("Wrong class %u in `playercreateinfo_action` table, ignoring.",current_class); + continue; + } + + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; + pInfo->action[0].push_back(fields[2].GetUInt16()); + pInfo->action[1].push_back(fields[3].GetUInt16()); + pInfo->action[2].push_back(fields[4].GetUInt16()); + pInfo->action[3].push_back(fields[5].GetUInt16()); + + bar.step(); + ++count; + } + while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u player create actions", count ); + } + } + + // Loading levels data (class only dependent) + { + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u level health/mana definitions", count ); + sLog.outErrorDb( "Error loading `player_classlevelstats` table or empty table."); + exit(1); + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_class = fields[0].GetUInt32(); + if(current_class >= MAX_CLASSES) + { + sLog.outErrorDb("Wrong class %u in `player_classlevelstats` table, ignoring.",current_class); + continue; + } + + uint32 current_level = fields[1].GetUInt32(); + if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + if(current_level > 255) // hardcoded level maximum + sLog.outErrorDb("Wrong (> 255) level %u in `player_classlevelstats` table, ignoring.",current_level); + else + sLog.outDetail("Unused (> MaxPlayerLevel in mangosd.conf) level %u in `player_classlevelstats` table, ignoring.",current_level); + continue; + } + + PlayerClassInfo* pClassInfo = &playerClassInfo[current_class]; + + if(!pClassInfo->levelInfo) + pClassInfo->levelInfo = new PlayerClassLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)]; + + PlayerClassLevelInfo* pClassLevelInfo = &pClassInfo->levelInfo[current_level-1]; + + pClassLevelInfo->basehealth = fields[2].GetUInt16(); + pClassLevelInfo->basemana = fields[3].GetUInt16(); + + bar.step(); + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u level health/mana definitions", count ); + } + + // Fill gaps and check integrity + for (int class_ = 0; class_ < MAX_CLASSES; ++class_) + { + // skip non existed classes + if(!sChrClassesStore.LookupEntry(class_)) + continue; + + PlayerClassInfo* pClassInfo = &playerClassInfo[class_]; + + // fatal error if no level 1 data + if(!pClassInfo->levelInfo || pClassInfo->levelInfo[0].basehealth == 0 ) + { + sLog.outErrorDb("Class %i Level 1 does not have health/mana data!",class_); + exit(1); + } + + // fill level gaps + for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) + { + if(pClassInfo->levelInfo[level].basehealth == 0) + { + sLog.outErrorDb("Class %i Level %i does not have health/mana data. Using stats data of level %i.",class_,level+1, level); + pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level-1]; + } + } + } + + // Loading levels data (class/race dependent) + { + // 0 1 2 3 4 5 6 7 + QueryResult *result = WorldDatabase.Query("SELECT race, class, level, str, agi, sta, inte, spi FROM player_levelstats"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u level stats definitions", count ); + sLog.outErrorDb( "Error loading `player_levelstats` table or empty table."); + exit(1); + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_race = fields[0].GetUInt32(); + if(current_race >= MAX_RACES) + { + sLog.outErrorDb("Wrong race %u in `player_levelstats` table, ignoring.",current_race); + continue; + } + + uint32 current_class = fields[1].GetUInt32(); + if(current_class >= MAX_CLASSES) + { + sLog.outErrorDb("Wrong class %u in `player_levelstats` table, ignoring.",current_class); + continue; + } + + uint32 current_level = fields[2].GetUInt32(); + if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + if(current_level > 255) // hardcoded level maximum + sLog.outErrorDb("Wrong (> 255) level %u in `player_levelstats` table, ignoring.",current_level); + else + sLog.outDetail("Unused (> MaxPlayerLevel in mangosd.conf) level %u in `player_levelstats` table, ignoring.",current_level); + continue; + } + + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; + + if(!pInfo->levelInfo) + pInfo->levelInfo = new PlayerLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)]; + + PlayerLevelInfo* pLevelInfo = &pInfo->levelInfo[current_level-1]; + + for (int i = 0; i < MAX_STATS; i++) + { + pLevelInfo->stats[i] = fields[i+3].GetUInt8(); + } + + bar.step(); + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u level stats definitions", count ); + } + + // Fill gaps and check integrity + for (int race = 0; race < MAX_RACES; ++race) + { + // skip non existed races + if(!sChrRacesStore.LookupEntry(race)) + continue; + + for (int class_ = 0; class_ < MAX_CLASSES; ++class_) + { + // skip non existed classes + if(!sChrClassesStore.LookupEntry(class_)) + continue; + + PlayerInfo* pInfo = &playerInfo[race][class_]; + + // skip non loaded combinations + if(!pInfo->displayId_m || !pInfo->displayId_f) + continue; + + // skip expansion races if not playing with expansion + if (sWorld.getConfig(CONFIG_EXPANSION) < 1 && (race == RACE_BLOODELF || race == RACE_DRAENEI)) + continue; + + // skip expansion classes if not playing with expansion + if (sWorld.getConfig(CONFIG_EXPANSION) < 2 && class_ == CLASS_DEATH_KNIGHT) + continue; + + // fatal error if no level 1 data + if(!pInfo->levelInfo || pInfo->levelInfo[0].stats[0] == 0 ) + { + sLog.outErrorDb("Race %i Class %i Level 1 does not have stats data!",race,class_); + exit(1); + } + + // fill level gaps + for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) + { + if(pInfo->levelInfo[level].stats[0] == 0) + { + sLog.outErrorDb("Race %i Class %i Level %i does not have stats data. Using stats data of level %i.",race,class_,level+1, level); + pInfo->levelInfo[level] = pInfo->levelInfo[level-1]; + } + } + } + } +} + +void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint32 level, PlayerClassLevelInfo* info) const +{ + if(level < 1 || class_ >= MAX_CLASSES) + return; + + PlayerClassInfo const* pInfo = &playerClassInfo[class_]; + + if(level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); + + *info = pInfo->levelInfo[level-1]; +} + +void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint32 level, PlayerLevelInfo* info) const +{ + if(level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES) + return; + + PlayerInfo const* pInfo = &playerInfo[race][class_]; + if(pInfo->displayId_m==0 || pInfo->displayId_f==0) + return; + + if(level <= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + *info = pInfo->levelInfo[level-1]; + else + BuildPlayerLevelInfo(race,class_,level,info); +} + +void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, PlayerLevelInfo* info) const +{ + // base data (last known level) + *info = playerInfo[race][_class].levelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)-1]; + + for(int lvl = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)-1; lvl < level; ++lvl) + { + switch(_class) + { + case CLASS_WARRIOR: + info->stats[STAT_STRENGTH] += (lvl > 23 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_STAMINA] += (lvl > 23 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_AGILITY] += (lvl > 36 ? 1: (lvl > 6 && (lvl%2) ? 1: 0)); + info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl%2) ? 1: 0); + info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl%2) ? 1: 0); + break; + case CLASS_PALADIN: + info->stats[STAT_STRENGTH] += (lvl > 3 ? 1: 0); + info->stats[STAT_STAMINA] += (lvl > 33 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_AGILITY] += (lvl > 38 ? 1: (lvl > 7 && !(lvl%2) ? 1: 0)); + info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl%2) ? 1: 0); + info->stats[STAT_SPIRIT] += (lvl > 7 ? 1: 0); + break; + case CLASS_HUNTER: + info->stats[STAT_STRENGTH] += (lvl > 4 ? 1: 0); + info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0); + info->stats[STAT_AGILITY] += (lvl > 33 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl%2) ? 1: 0); + info->stats[STAT_SPIRIT] += (lvl > 38 ? 1: (lvl > 9 && !(lvl%2) ? 1: 0)); + break; + case CLASS_ROGUE: + info->stats[STAT_STRENGTH] += (lvl > 5 ? 1: 0); + info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0); + info->stats[STAT_AGILITY] += (lvl > 16 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl%2) ? 1: 0); + info->stats[STAT_SPIRIT] += (lvl > 38 ? 1: (lvl > 9 && !(lvl%2) ? 1: 0)); + break; + case CLASS_PRIEST: + info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0); + info->stats[STAT_STAMINA] += (lvl > 5 ? 1: 0); + info->stats[STAT_AGILITY] += (lvl > 38 ? 1: (lvl > 8 && (lvl%2) ? 1: 0)); + info->stats[STAT_INTELLECT] += (lvl > 22 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_SPIRIT] += (lvl > 3 ? 1: 0); + break; + case CLASS_SHAMAN: + info->stats[STAT_STRENGTH] += (lvl > 34 ? 1: (lvl > 6 && (lvl%2) ? 1: 0)); + info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0); + info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl%2) ? 1: 0); + info->stats[STAT_INTELLECT] += (lvl > 5 ? 1: 0); + info->stats[STAT_SPIRIT] += (lvl > 4 ? 1: 0); + break; + case CLASS_MAGE: + info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0); + info->stats[STAT_STAMINA] += (lvl > 5 ? 1: 0); + info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl%2) ? 1: 0); + info->stats[STAT_INTELLECT] += (lvl > 24 ? 2: (lvl > 1 ? 1: 0)); + info->stats[STAT_SPIRIT] += (lvl > 33 ? 2: (lvl > 2 ? 1: 0)); + break; + case CLASS_WARLOCK: + info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0); + info->stats[STAT_STAMINA] += (lvl > 38 ? 2: (lvl > 3 ? 1: 0)); + info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl%2) ? 1: 0); + info->stats[STAT_INTELLECT] += (lvl > 33 ? 2: (lvl > 2 ? 1: 0)); + info->stats[STAT_SPIRIT] += (lvl > 38 ? 2: (lvl > 3 ? 1: 0)); + break; + case CLASS_DRUID: + info->stats[STAT_STRENGTH] += (lvl > 38 ? 2: (lvl > 6 && (lvl%2) ? 1: 0)); + info->stats[STAT_STAMINA] += (lvl > 32 ? 2: (lvl > 4 ? 1: 0)); + info->stats[STAT_AGILITY] += (lvl > 38 ? 2: (lvl > 8 && (lvl%2) ? 1: 0)); + info->stats[STAT_INTELLECT] += (lvl > 38 ? 3: (lvl > 4 ? 1: 0)); + info->stats[STAT_SPIRIT] += (lvl > 38 ? 3: (lvl > 5 ? 1: 0)); + } + } +} + +void ObjectMgr::LoadGuilds() +{ + Guild *newguild; + uint32 count = 0; + + QueryResult *result = CharacterDatabase.Query( "SELECT guildid FROM guild" ); + + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u guild definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + ++count; + + newguild = new Guild; + if(!newguild->LoadGuildFromDB(fields[0].GetUInt32())) + { + newguild->Disband(); + delete newguild; + continue; + } + AddGuild(newguild); + + }while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u guild definitions", count ); +} + +void ObjectMgr::LoadArenaTeams() +{ + uint32 count = 0; + + QueryResult *result = CharacterDatabase.Query( "SELECT arenateamid FROM arena_team" ); + + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u arenateam definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + ++count; + + ArenaTeam *newarenateam = new ArenaTeam; + if(!newarenateam->LoadArenaTeamFromDB(fields[0].GetUInt32())) + { + delete newarenateam; + continue; + } + AddArenaTeam(newarenateam); + }while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u arenateam definitions", count ); +} + +void ObjectMgr::LoadGroups() +{ + // -- loading groups -- + Group *group = NULL; + uint64 leaderGuid = 0; + uint32 count = 0; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + QueryResult *result = CharacterDatabase.PQuery("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u group definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + Field *fields = result->Fetch(); + ++count; + leaderGuid = MAKE_NEW_GUID(fields[15].GetUInt32(),0,HIGHGUID_PLAYER); + + group = new Group; + if(!group->LoadGroupFromDB(leaderGuid, result, false)) + { + group->Disband(); + delete group; + continue; + } + AddGroup(group); + }while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u group definitions", count ); + + // -- loading members -- + count = 0; + group = NULL; + leaderGuid = 0; + // 0 1 2 3 + result = CharacterDatabase.PQuery("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid"); + if(!result) + { + barGoLink bar( 1 ); + bar.step(); + } + else + { + barGoLink bar( result->GetRowCount() ); + do + { + bar.step(); + Field *fields = result->Fetch(); + count++; + leaderGuid = MAKE_NEW_GUID(fields[3].GetUInt32(), 0, HIGHGUID_PLAYER); + if(!group || group->GetLeaderGUID() != leaderGuid) + { + group = GetGroupByLeader(leaderGuid); + if(!group) + { + sLog.outErrorDb("Incorrect entry in group_member table : no group with leader %d for member %d!", fields[3].GetUInt32(), fields[0].GetUInt32()); + CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid = '%d'", fields[0].GetUInt32()); + continue; + } + } + + if(!group->LoadMemberFromDB(fields[0].GetUInt32(), fields[2].GetUInt8(), fields[1].GetBool())) + { + sLog.outErrorDb("Incorrect entry in group_member table : member %d cannot be added to player %d's group!", fields[0].GetUInt32(), fields[3].GetUInt32()); + CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid = '%d'", fields[0].GetUInt32()); + } + }while( result->NextRow() ); + delete result; + } + + // clean groups + // TODO: maybe delete from the DB before loading in this case + for(GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end();) + { + if((*itr)->GetMembersCount() < 2) + { + (*itr)->Disband(); + delete *itr; + mGroupSet.erase(itr++); + } + else + ++itr; + } + + // -- loading instances -- + count = 0; + group = NULL; + leaderGuid = 0; + result = CharacterDatabase.PQuery( + // 0 1 2 3 4 5 + "SELECT leaderGuid, map, instance, permanent, difficulty, resettime, " + // 6 + "(SELECT COUNT(*) FROM character_instance WHERE guid = leaderGuid AND instance = group_instance.instance AND permanent = 1 LIMIT 1) " + "FROM group_instance LEFT JOIN instance ON instance = id ORDER BY leaderGuid" + ); + + if(!result) + { + barGoLink bar( 1 ); + bar.step(); + } + else + { + barGoLink bar( result->GetRowCount() ); + do + { + bar.step(); + Field *fields = result->Fetch(); + count++; + leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + if(!group || group->GetLeaderGUID() != leaderGuid) + { + group = GetGroupByLeader(leaderGuid); + if(!group) + { + sLog.outErrorDb("Incorrect entry in group_instance table : no group with leader %d", fields[0].GetUInt32()); + continue; + } + } + + InstanceSave *save = sInstanceSaveManager.AddInstanceSave(fields[1].GetUInt32(), fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true); + group->BindToInstance(save, fields[3].GetBool(), true); + }while( result->NextRow() ); + delete result; + } + + sLog.outString(); + sLog.outString( ">> Loaded %u group-instance binds total", count ); + + sLog.outString(); + sLog.outString( ">> Loaded %u group members total", count ); +} + +void ObjectMgr::LoadQuests() +{ + // For reload case + for(QuestMap::const_iterator itr=mQuestTemplates.begin(); itr != mQuestTemplates.end(); ++itr) + delete itr->second; + mQuestTemplates.clear(); + + mExclusiveQuestGroups.clear(); + + // 0 1 2 3 4 5 6 7 8 + QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue," + // 9 10 11 12 13 14 15 16 + "RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime," + // 17 18 19 20 21 22 23 24 25 26 + "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell," + // 27 28 29 30 31 32 33 34 35 36 + "Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4," + // 37 38 39 40 41 42 43 44 + "ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4," + // 45 46 47 48 49 50 51 52 53 54 54 55 + "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4," + // 57 58 59 60 61 62 63 64 + "ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4," + // 65 66 67 68 + "ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4," + // 69 70 71 72 73 74 + "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6," + // 75 76 77 78 79 80 + "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6," + // 81 82 83 84 85 86 87 88 + "RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4," + // 89 90 91 92 93 94 95 96 97 98 + "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5," + // 99 100 101 102 103 104 105 106 107 108 + "RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt," + // 109 110 111 112 113 114 115 116 117 118 + "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4," + // 119 120 + "StartScript, CompleteScript" + " FROM quest_template"); + if(result == NULL) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded 0 quests definitions" ); + sLog.outErrorDb("`quest_template` table is empty!"); + return; + } + + // create multimap previous quest for each existed quest + // some quests can have many previous maps set by NextQuestId in previous quest + // for example set of race quests can lead to single not race specific quest + barGoLink bar( result->GetRowCount() ); + do + { + bar.step(); + Field *fields = result->Fetch(); + + Quest * newQuest = new Quest(fields); + mQuestTemplates[newQuest->GetQuestId()] = newQuest; + } while( result->NextRow() ); + + delete result; + + // Post processing + for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); iter++) + { + Quest * qinfo = iter->second; + + // additional quest integrity checks (GO, creature_template and item_template must be loaded already) + + if( qinfo->GetQuestMethod() >= 3 ) + { + sLog.outErrorDb("Quest %u has `Method` = %u, expected values are 0, 1 or 2.",qinfo->GetQuestId(),qinfo->GetQuestMethod()); + } + + if (qinfo->QuestFlags & ~QUEST_MANGOS_FLAGS_DB_ALLOWED) + { + sLog.outErrorDb("Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u", + qinfo->GetQuestId(),qinfo->QuestFlags,QUEST_MANGOS_FLAGS_DB_ALLOWED >> 16); + qinfo->QuestFlags &= QUEST_MANGOS_FLAGS_DB_ALLOWED; + } + + if(qinfo->QuestFlags & QUEST_FLAGS_DAILY) + { + if(!(qinfo->QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE)) + { + sLog.outErrorDb("Daily Quest %u not marked as repeatable in `SpecialFlags`, added.",qinfo->GetQuestId()); + qinfo->QuestFlags |= QUEST_MANGOS_FLAGS_REPEATABLE; + } + } + + if(qinfo->QuestFlags & QUEST_FLAGS_AUTO_REWARDED) + { + // at auto-reward can be rewarded only RewChoiceItemId[0] + for(int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j ) + { + if(uint32 id = qinfo->RewChoiceItemId[j]) + { + sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but item from `RewChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_AUTO_REWARDED.", + qinfo->GetQuestId(),j+1,id,j+1); + // no changes, quest ignore this data + } + } + } + + // client quest log visual (area case) + if( qinfo->ZoneOrSort > 0 ) + { + if(!GetAreaEntryByAreaID(qinfo->ZoneOrSort)) + { + sLog.outErrorDb("Quest %u has `ZoneOrSort` = %u (zone case) but zone with this id does not exist.", + qinfo->GetQuestId(),qinfo->ZoneOrSort); + // no changes, quest not dependent from this value but can have problems at client + } + } + // client quest log visual (sort case) + if( qinfo->ZoneOrSort < 0 ) + { + QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->ZoneOrSort)); + if( !qSort ) + { + sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (sort case) but quest sort with this id does not exist.", + qinfo->GetQuestId(),qinfo->ZoneOrSort); + // no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check) + } + //check SkillOrClass value (class case). + if( ClassByQuestSort(-int32(qinfo->ZoneOrSort)) ) + { + // SkillOrClass should not have class case when class case already set in ZoneOrSort. + if(qinfo->SkillOrClass < 0) + { + sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (class sort case) and `SkillOrClass` = %i (class case), redundant.", + qinfo->GetQuestId(),qinfo->ZoneOrSort,qinfo->SkillOrClass); + } + } + //check for proper SkillOrClass value (skill case) + if(int32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort))) + { + // skill is positive value in SkillOrClass + if(qinfo->SkillOrClass != skill_id ) + { + sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (skill sort case) but `SkillOrClass` does not have a corresponding value (%i).", + qinfo->GetQuestId(),qinfo->ZoneOrSort,skill_id); + //override, and force proper value here? + } + } + } + + // SkillOrClass (class case) + if( qinfo->SkillOrClass < 0 ) + { + if( !sChrClassesStore.LookupEntry(-int32(qinfo->SkillOrClass)) ) + { + sLog.outErrorDb("Quest %u has `SkillOrClass` = %i (class case) but class (%i) does not exist", + qinfo->GetQuestId(),qinfo->SkillOrClass,-qinfo->SkillOrClass); + } + } + // SkillOrClass (skill case) + if( qinfo->SkillOrClass > 0 ) + { + if( !sSkillLineStore.LookupEntry(qinfo->SkillOrClass) ) + { + sLog.outErrorDb("Quest %u has `SkillOrClass` = %u (skill case) but skill (%i) does not exist", + qinfo->GetQuestId(),qinfo->SkillOrClass,qinfo->SkillOrClass); + } + } + + if( qinfo->RequiredSkillValue ) + { + if( qinfo->RequiredSkillValue > sWorld.GetConfigMaxSkillValue() ) + { + sLog.outErrorDb("Quest %u has `RequiredSkillValue` = %u but max possible skill is %u, quest can't be done.", + qinfo->GetQuestId(),qinfo->RequiredSkillValue,sWorld.GetConfigMaxSkillValue()); + // no changes, quest can't be done for this requirement + } + + if( qinfo->SkillOrClass <= 0 ) + { + sLog.outErrorDb("Quest %u has `RequiredSkillValue` = %u but `SkillOrClass` = %i (class case), value ignored.", + qinfo->GetQuestId(),qinfo->RequiredSkillValue,qinfo->SkillOrClass); + // no changes, quest can't be done for this requirement (fail at wrong skill id) + } + } + // else Skill quests can have 0 skill level, this is ok + + if(qinfo->RepObjectiveFaction && !sFactionStore.LookupEntry(qinfo->RepObjectiveFaction)) + { + sLog.outErrorDb("Quest %u has `RepObjectiveFaction` = %u but faction template %u does not exist, quest can't be done.", + qinfo->GetQuestId(),qinfo->RepObjectiveFaction,qinfo->RepObjectiveFaction); + // no changes, quest can't be done for this requirement + } + + if(qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction)) + { + sLog.outErrorDb("Quest %u has `RequiredMinRepFaction` = %u but faction template %u does not exist, quest can't be done.", + qinfo->GetQuestId(),qinfo->RequiredMinRepFaction,qinfo->RequiredMinRepFaction); + // no changes, quest can't be done for this requirement + } + + if(qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction)) + { + sLog.outErrorDb("Quest %u has `RequiredMaxRepFaction` = %u but faction template %u does not exist, quest can't be done.", + qinfo->GetQuestId(),qinfo->RequiredMaxRepFaction,qinfo->RequiredMaxRepFaction); + // no changes, quest can't be done for this requirement + } + + if(qinfo->RequiredMinRepValue && qinfo->RequiredMinRepValue > Player::Reputation_Cap) + { + sLog.outErrorDb("Quest %u has `RequiredMinRepValue` = %d but max reputation is %u, quest can't be done.", + qinfo->GetQuestId(),qinfo->RequiredMinRepValue,Player::Reputation_Cap); + // no changes, quest can't be done for this requirement + } + + if(qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue) + { + sLog.outErrorDb("Quest %u has `RequiredMaxRepValue` = %d and `RequiredMinRepValue` = %d, quest can't be done.", + qinfo->GetQuestId(),qinfo->RequiredMaxRepValue,qinfo->RequiredMinRepValue); + // no changes, quest can't be done for this requirement + } + + if(!qinfo->RepObjectiveFaction && qinfo->RepObjectiveValue > 0 ) + { + sLog.outErrorDb("Quest %u has `RepObjectiveValue` = %d but `RepObjectiveFaction` is 0, value has no effect", + qinfo->GetQuestId(),qinfo->RepObjectiveValue); + // warning + } + + if(!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue > 0 ) + { + sLog.outErrorDb("Quest %u has `RequiredMinRepValue` = %d but `RequiredMinRepFaction` is 0, value has no effect", + qinfo->GetQuestId(),qinfo->RequiredMinRepValue); + // warning + } + + if(!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue > 0 ) + { + sLog.outErrorDb("Quest %u has `RequiredMaxRepValue` = %d but `RequiredMaxRepFaction` is 0, value has no effect", + qinfo->GetQuestId(),qinfo->RequiredMaxRepValue); + // warning + } + + if(qinfo->CharTitleId && !sCharTitlesStore.LookupEntry(qinfo->CharTitleId)) + { + sLog.outErrorDb("Quest %u has `CharTitleId` = %u but CharTitle Id %u does not exist, quest can't be rewarded with title.", + qinfo->GetQuestId(),qinfo->GetCharTitleId(),qinfo->GetCharTitleId()); + qinfo->CharTitleId = 0; + // quest can't reward this title + } + + if(qinfo->SrcItemId) + { + if(!sItemStorage.LookupEntry(qinfo->SrcItemId)) + { + sLog.outErrorDb("Quest %u has `SrcItemId` = %u but item with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(),qinfo->SrcItemId,qinfo->SrcItemId); + qinfo->SrcItemId = 0; // quest can't be done for this requirement + } + else if(qinfo->SrcItemCount==0) + { + sLog.outErrorDb("Quest %u has `SrcItemId` = %u but `SrcItemCount` = 0, set to 1 but need fix in DB.", + qinfo->GetQuestId(),qinfo->SrcItemId); + qinfo->SrcItemCount = 1; // update to 1 for allow quest work for backward comptibility with DB + } + } + else if(qinfo->SrcItemCount>0) + { + sLog.outErrorDb("Quest %u has `SrcItemId` = 0 but `SrcItemCount` = %u, useless value.", + qinfo->GetQuestId(),qinfo->SrcItemCount); + qinfo->SrcItemCount=0; // no quest work changes in fact + } + + if(qinfo->SrcSpell) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->SrcSpell); + if(!spellInfo) + { + sLog.outErrorDb("Quest %u has `SrcSpell` = %u but spell %u doesn't exist, quest can't be done.", + qinfo->GetQuestId(),qinfo->SrcSpell,qinfo->SrcSpell); + qinfo->SrcSpell = 0; // quest can't be done for this requirement + } + else if(!SpellMgr::IsSpellValid(spellInfo)) + { + sLog.outErrorDb("Quest %u has `SrcSpell` = %u but spell %u is broken, quest can't be done.", + qinfo->GetQuestId(),qinfo->SrcSpell,qinfo->SrcSpell); + qinfo->SrcSpell = 0; // quest can't be done for this requirement + } + } + + for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j ) + { + uint32 id = qinfo->ReqItemId[j]; + if(id) + { + if(qinfo->ReqItemCount[j]==0) + { + sLog.outErrorDb("Quest %u has `ReqItemId%d` = %u but `ReqItemCount%d` = 0, quest can't be done.", + qinfo->GetQuestId(),j+1,id,j+1); + // no changes, quest can't be done for this requirement + } + + qinfo->SetFlag(QUEST_MANGOS_FLAGS_DELIVER); + + if(!sItemStorage.LookupEntry(id)) + { + sLog.outErrorDb("Quest %u has `ReqItemId%d` = %u but item with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(),j+1,id,id); + qinfo->ReqItemCount[j] = 0; // prevent incorrect work of quest + } + } + else if(qinfo->ReqItemCount[j]>0) + { + sLog.outErrorDb("Quest %u has `ReqItemId%d` = 0 but `ReqItemCount%d` = %u, quest can't be done.", + qinfo->GetQuestId(),j+1,j+1,qinfo->ReqItemCount[j]); + qinfo->ReqItemCount[j] = 0; // prevent incorrect work of quest + } + } + + for(int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j ) + { + uint32 id = qinfo->ReqSourceId[j]; + if(id) + { + if(!sItemStorage.LookupEntry(id)) + { + sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but item with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(),j+1,id,id); + // no changes, quest can't be done for this requirement + } + + if(!qinfo->ReqSourceCount[j]) + { + sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but `ReqSourceCount%d` = 0, quest can't be done.", + qinfo->GetQuestId(),j+1,id,j+1); + qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest + } + + if(!qinfo->ReqSourceRef[j]) + { + sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but `ReqSourceRef%d` = 0, quest can't be done.", + qinfo->GetQuestId(),j+1,id,j+1); + qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest + } + } + else + { + if(qinfo->ReqSourceCount[j]>0) + { + sLog.outErrorDb("Quest %u has `ReqSourceId%d` = 0 but `ReqSourceCount%d` = %u.", + qinfo->GetQuestId(),j+1,j+1,qinfo->ReqSourceCount[j]); + // no changes, quest ignore this data + } + + if(qinfo->ReqSourceRef[j]>0) + { + sLog.outErrorDb("Quest %u has `ReqSourceId%d` = 0 but `ReqSourceRef%d` = %u.", + qinfo->GetQuestId(),j+1,j+1,qinfo->ReqSourceRef[j]); + // no changes, quest ignore this data + } + } + } + + for(int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j ) + { + uint32 ref = qinfo->ReqSourceRef[j]; + if(ref) + { + if(ref > QUEST_OBJECTIVES_COUNT) + { + sLog.outErrorDb("Quest %u has `ReqSourceRef%d` = %u but max value in `ReqSourceRef%d` is %u, quest can't be done.", + qinfo->GetQuestId(),j+1,ref,j+1,QUEST_OBJECTIVES_COUNT); + // no changes, quest can't be done for this requirement + } + else + if(!qinfo->ReqItemId[ref-1] && !qinfo->ReqSpell[ref-1]) + { + sLog.outErrorDb("Quest %u has `ReqSourceRef%d` = %u but `ReqItemId%u` = 0 and `ReqSpellCast%u` = 0, quest can't be done.", + qinfo->GetQuestId(),j+1,ref,ref,ref); + // no changes, quest can't be done for this requirement + } + else if(qinfo->ReqItemId[ref-1] && qinfo->ReqSpell[ref-1]) + { + sLog.outErrorDb("Quest %u has `ReqItemId%u` = %u and `ReqSpellCast%u` = %u, quest can't have both fields <> 0, then can't be done.", + qinfo->GetQuestId(),ref,qinfo->ReqItemId[ref-1],ref,qinfo->ReqSpell[ref-1]); + // no changes, quest can't be done for this requirement + qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest + } + } + } + + for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j ) + { + uint32 id = qinfo->ReqSpell[j]; + if(id) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(id); + if(!spellInfo) + { + sLog.outErrorDb("Quest %u has `ReqSpellCast%d` = %u but spell %u does not exist, quest can't be done.", + qinfo->GetQuestId(),j+1,id,id); + // no changes, quest can't be done for this requirement + } + + if(!qinfo->ReqCreatureOrGOId[j]) + { + bool found = false; + for(int k = 0; k < 3; ++k) + { + if( spellInfo->Effect[k]==SPELL_EFFECT_QUEST_COMPLETE && uint32(spellInfo->EffectMiscValue[k])==qinfo->QuestId || + spellInfo->Effect[k]==SPELL_EFFECT_SEND_EVENT) + { + found = true; + break; + } + } + + if(found) + { + if(!qinfo->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) + { + sLog.outErrorDb("Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT for quest %u and ReqCreatureOrGOId%d = 0, but quest not have flag QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT. Quest flags or ReqCreatureOrGOId%d must be fixed, quest modified to enable objective.",spellInfo->Id,qinfo->QuestId,j+1,j+1); + + // this will prevent quest completing without objective + const_cast(qinfo)->SetFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT); + } + } + else + { + sLog.outErrorDb("Quest %u has `ReqSpellCast%d` = %u and ReqCreatureOrGOId%d = 0 but spell %u does not have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT effect for this quest, quest can't be done.", + qinfo->GetQuestId(),j+1,id,j+1,id); + // no changes, quest can't be done for this requirement + } + } + } + } + + for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j ) + { + int32 id = qinfo->ReqCreatureOrGOId[j]; + if(id < 0 && !sGOStorage.LookupEntry(-id)) + { + sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %i but gameobject %u does not exist, quest can't be done.", + qinfo->GetQuestId(),j+1,id,uint32(-id)); + qinfo->ReqCreatureOrGOId[j] = 0; // quest can't be done for this requirement + } + + if(id > 0 && !sCreatureStorage.LookupEntry(id)) + { + sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %i but creature with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(),j+1,id,uint32(id)); + qinfo->ReqCreatureOrGOId[j] = 0; // quest can't be done for this requirement + } + + if(id) + { + // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast + + qinfo->SetFlag(QUEST_MANGOS_FLAGS_KILL_OR_CAST | QUEST_MANGOS_FLAGS_SPEAKTO); + + if(!qinfo->ReqCreatureOrGOCount[j]) + { + sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %u but `ReqCreatureOrGOCount%d` = 0, quest can't be done.", + qinfo->GetQuestId(),j+1,id,j+1); + // no changes, quest can be incorrectly done, but we already report this + } + } + else if(qinfo->ReqCreatureOrGOCount[j]>0) + { + sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = 0 but `ReqCreatureOrGOCount%d` = %u.", + qinfo->GetQuestId(),j+1,j+1,qinfo->ReqCreatureOrGOCount[j]); + // no changes, quest ignore this data + } + } + + for(int j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j ) + { + uint32 id = qinfo->RewChoiceItemId[j]; + if(id) + { + if(!sItemStorage.LookupEntry(id)) + { + sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.", + qinfo->GetQuestId(),j+1,id,id); + qinfo->RewChoiceItemId[j] = 0; // no changes, quest will not reward this + } + + if(!qinfo->RewChoiceItemCount[j]) + { + sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but `RewChoiceItemCount%d` = 0, quest can't be done.", + qinfo->GetQuestId(),j+1,id,j+1); + // no changes, quest can't be done + } + } + else if(qinfo->RewChoiceItemCount[j]>0) + { + sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = 0 but `RewChoiceItemCount%d` = %u.", + qinfo->GetQuestId(),j+1,j+1,qinfo->RewChoiceItemCount[j]); + // no changes, quest ignore this data + } + } + + for(int j = 0; j < QUEST_REWARDS_COUNT; ++j ) + { + uint32 id = qinfo->RewItemId[j]; + if(id) + { + if(!sItemStorage.LookupEntry(id)) + { + sLog.outErrorDb("Quest %u has `RewItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.", + qinfo->GetQuestId(),j+1,id,id); + qinfo->RewItemId[j] = 0; // no changes, quest will not reward this item + } + + if(!qinfo->RewItemCount[j]) + { + sLog.outErrorDb("Quest %u has `RewItemId%d` = %u but `RewItemCount%d` = 0, quest will not reward this item.", + qinfo->GetQuestId(),j+1,id,j+1); + // no changes + } + } + else if(qinfo->RewItemCount[j]>0) + { + sLog.outErrorDb("Quest %u has `RewItemId%d` = 0 but `RewItemCount%d` = %u.", + qinfo->GetQuestId(),j+1,j+1,qinfo->RewItemCount[j]); + // no changes, quest ignore this data + } + } + + for(int j = 0; j < QUEST_REPUTATIONS_COUNT; ++j) + { + if(qinfo->RewRepFaction[j]) + { + if(!qinfo->RewRepValue[j]) + { + sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but `RewRepValue%d` = 0, quest will not reward this reputation.", + qinfo->GetQuestId(),j+1,qinfo->RewRepValue[j],j+1); + // no changes + } + + if(!sFactionStore.LookupEntry(qinfo->RewRepFaction[j])) + { + sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but raw faction (faction.dbc) %u does not exist, quest will not reward reputation for this faction.", + qinfo->GetQuestId(),j+1,qinfo->RewRepFaction[j] ,qinfo->RewRepFaction[j] ); + qinfo->RewRepFaction[j] = 0; // quest will not reward this + } + } + else if(qinfo->RewRepValue[j]!=0) + { + sLog.outErrorDb("Quest %u has `RewRepFaction%d` = 0 but `RewRepValue%d` = %u.", + qinfo->GetQuestId(),j+1,j+1,qinfo->RewRepValue[j]); + // no changes, quest ignore this data + } + } + + if(qinfo->RewSpell) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpell); + + if(!spellInfo) + { + sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u does not exist, spell removed as display reward.", + qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell); + qinfo->RewSpell = 0; // no spell reward will display for this quest + } + + else if(!SpellMgr::IsSpellValid(spellInfo)) + { + sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is broken, quest can't be done.", + qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell); + qinfo->RewSpell = 0; // no spell reward will display for this quest + } + + } + + if(qinfo->RewSpellCast) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpellCast); + + if(!spellInfo) + { + sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.", + qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast); + qinfo->RewSpellCast = 0; // no spell will be casted on player + } + + else if(!SpellMgr::IsSpellValid(spellInfo)) + { + sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u is broken, quest can't be done.", + qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast); + qinfo->RewSpellCast = 0; // no spell will be casted on player + } + + } + + if(qinfo->RewMailTemplateId) + { + if(!sMailTemplateStore.LookupEntry(qinfo->RewMailTemplateId)) + { + sLog.outErrorDb("Quest %u has `RewMailTemplateId` = %u but mail template %u does not exist, quest will not have a mail reward.", + qinfo->GetQuestId(),qinfo->RewMailTemplateId,qinfo->RewMailTemplateId); + qinfo->RewMailTemplateId = 0; // no mail will send to player + qinfo->RewMailDelaySecs = 0; // no mail will send to player + } + } + + if(qinfo->NextQuestInChain) + { + if(mQuestTemplates.find(qinfo->NextQuestInChain) == mQuestTemplates.end()) + { + sLog.outErrorDb("Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.", + qinfo->GetQuestId(),qinfo->NextQuestInChain ,qinfo->NextQuestInChain ); + qinfo->NextQuestInChain = 0; + } + else + mQuestTemplates[qinfo->NextQuestInChain]->prevChainQuests.push_back(qinfo->GetQuestId()); + } + + // fill additional data stores + if(qinfo->PrevQuestId) + { + if (mQuestTemplates.find(abs(qinfo->GetPrevQuestId())) == mQuestTemplates.end()) + { + sLog.outErrorDb("Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId()); + } + else + { + qinfo->prevQuests.push_back(qinfo->PrevQuestId); + } + } + + if(qinfo->NextQuestId) + { + if (mQuestTemplates.find(abs(qinfo->GetNextQuestId())) == mQuestTemplates.end()) + { + sLog.outErrorDb("Quest %d has NextQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId()); + } + else + { + int32 signedQuestId = qinfo->NextQuestId < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId()); + mQuestTemplates[abs(qinfo->GetNextQuestId())]->prevQuests.push_back(signedQuestId); + } + } + + if(qinfo->ExclusiveGroup) + mExclusiveQuestGroups.insert(std::pair(qinfo->ExclusiveGroup, qinfo->GetQuestId())); + if(qinfo->LimitTime) + qinfo->SetFlag(QUEST_MANGOS_FLAGS_TIMED); + } + + // check QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE + for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i); + if(!spellInfo) + continue; + + for(int j = 0; j < 3; ++j) + { + if(spellInfo->Effect[j] != SPELL_EFFECT_QUEST_COMPLETE) + continue; + + uint32 quest_id = spellInfo->EffectMiscValue[j]; + + Quest const* quest = GetQuestTemplate(quest_id); + + // some quest referenced in spells not exist (outdataed spells) + if(!quest) + continue; + + if(!quest->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) + { + sLog.outErrorDb("Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE for quest %u , but quest not have flag QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT. Quest flags must be fixed, quest modified to enable objective.",spellInfo->Id,quest_id); + + // this will prevent quest completing without objective + const_cast(quest)->SetFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT); + } + } + } + + sLog.outString(); + sLog.outString( ">> Loaded %u quests definitions", mQuestTemplates.size() ); +} + +void ObjectMgr::LoadQuestLocales() +{ + mQuestLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT entry," + "Title_loc1,Details_loc1,Objectives_loc1,OfferRewardText_loc1,RequestItemsText_loc1,EndText_loc1,ObjectiveText1_loc1,ObjectiveText2_loc1,ObjectiveText3_loc1,ObjectiveText4_loc1," + "Title_loc2,Details_loc2,Objectives_loc2,OfferRewardText_loc2,RequestItemsText_loc2,EndText_loc2,ObjectiveText1_loc2,ObjectiveText2_loc2,ObjectiveText3_loc2,ObjectiveText4_loc2," + "Title_loc3,Details_loc3,Objectives_loc3,OfferRewardText_loc3,RequestItemsText_loc3,EndText_loc3,ObjectiveText1_loc3,ObjectiveText2_loc3,ObjectiveText3_loc3,ObjectiveText4_loc3," + "Title_loc4,Details_loc4,Objectives_loc4,OfferRewardText_loc4,RequestItemsText_loc4,EndText_loc4,ObjectiveText1_loc4,ObjectiveText2_loc4,ObjectiveText3_loc4,ObjectiveText4_loc4," + "Title_loc5,Details_loc5,Objectives_loc5,OfferRewardText_loc5,RequestItemsText_loc5,EndText_loc5,ObjectiveText1_loc5,ObjectiveText2_loc5,ObjectiveText3_loc5,ObjectiveText4_loc5," + "Title_loc6,Details_loc6,Objectives_loc6,OfferRewardText_loc6,RequestItemsText_loc6,EndText_loc6,ObjectiveText1_loc6,ObjectiveText2_loc6,ObjectiveText3_loc6,ObjectiveText4_loc6," + "Title_loc7,Details_loc7,Objectives_loc7,OfferRewardText_loc7,RequestItemsText_loc7,EndText_loc7,ObjectiveText1_loc7,ObjectiveText2_loc7,ObjectiveText3_loc7,ObjectiveText4_loc7," + "Title_loc8,Details_loc8,Objectives_loc8,OfferRewardText_loc8,RequestItemsText_loc8,EndText_loc8,ObjectiveText1_loc8,ObjectiveText2_loc8,ObjectiveText3_loc8,ObjectiveText4_loc8" + " FROM locales_quest" + ); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_quest` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + QuestLocale& data = mQuestLocaleMap[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[1+10*(i-1)].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Title.size() <= idx) + data.Title.resize(idx+1); + + data.Title[idx] = str; + } + } + str = fields[1+10*(i-1)+1].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Details.size() <= idx) + data.Details.resize(idx+1); + + data.Details[idx] = str; + } + } + str = fields[1+10*(i-1)+2].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Objectives.size() <= idx) + data.Objectives.resize(idx+1); + + data.Objectives[idx] = str; + } + } + str = fields[1+10*(i-1)+3].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.OfferRewardText.size() <= idx) + data.OfferRewardText.resize(idx+1); + + data.OfferRewardText[idx] = str; + } + } + str = fields[1+10*(i-1)+4].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.RequestItemsText.size() <= idx) + data.RequestItemsText.resize(idx+1); + + data.RequestItemsText[idx] = str; + } + } + str = fields[1+10*(i-1)+5].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.EndText.size() <= idx) + data.EndText.resize(idx+1); + + data.EndText[idx] = str; + } + } + for(int k = 0; k < 4; ++k) + { + str = fields[1+10*(i-1)+6+k].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.ObjectiveText[k].size() <= idx) + data.ObjectiveText[k].resize(idx+1); + + data.ObjectiveText[k][idx] = str; + } + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u Quest locale strings", mQuestLocaleMap.size() ); +} + +void ObjectMgr::LoadPetCreateSpells() +{ + QueryResult *result = WorldDatabase.PQuery("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell"); + if(!result) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded 0 pet create spells" ); + sLog.outErrorDb("`petcreateinfo_spell` table is empty!"); + return; + } + + uint32 count = 0; + + barGoLink bar( result->GetRowCount() ); + + mPetCreateSpell.clear(); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 creature_id = fields[0].GetUInt32(); + + if(!creature_id || !sCreatureStorage.LookupEntry(creature_id)) + continue; + + PetCreateSpellEntry PetCreateSpell; + for(int i = 0; i < 4; i++) + { + PetCreateSpell.spellid[i] = fields[i + 1].GetUInt32(); + + if(PetCreateSpell.spellid[i] && !sSpellStore.LookupEntry(PetCreateSpell.spellid[i])) + sLog.outErrorDb("Spell %u listed in `petcreateinfo_spell` does not exist",PetCreateSpell.spellid[i]); + } + + mPetCreateSpell[creature_id] = PetCreateSpell; + + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u pet create spells", count ); +} + +void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) +{ + if(sWorld.IsScriptScheduled()) // function don't must be called in time scripts use. + return; + + sLog.outString( "%s :", tablename); + + scripts.clear(); // need for reload support + + QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,datatext, x, y, z, o FROM %s", tablename ); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u script definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + ScriptInfo tmp; + tmp.id = fields[0].GetUInt32(); + tmp.delay = fields[1].GetUInt32(); + tmp.command = fields[2].GetUInt32(); + tmp.datalong = fields[3].GetUInt32(); + tmp.datalong2 = fields[4].GetUInt32(); + tmp.datatext = fields[5].GetCppString(); + tmp.x = fields[6].GetFloat(); + tmp.y = fields[7].GetFloat(); + tmp.z = fields[8].GetFloat(); + tmp.o = fields[9].GetFloat(); + + // generic command args check + switch(tmp.command) + { + case SCRIPT_COMMAND_TALK: + { + if(tmp.datalong > 3) + { + sLog.outErrorDb("Table `%s` has invalid talk type (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.datalong,tmp.id); + continue; + } + break; + } + + case SCRIPT_COMMAND_TELEPORT_TO: + { + if(!sMapStore.LookupEntry(tmp.datalong)) + { + sLog.outErrorDb("Table `%s` has invalid map (Id: %u) in SCRIPT_COMMAND_TELEPORT_TO for script id %u",tablename,tmp.datalong,tmp.id); + continue; + } + + if(!MaNGOS::IsValidMapCoord(tmp.x,tmp.y,tmp.z,tmp.o)) + { + sLog.outErrorDb("Table `%s` has invalid coordinates (X: %f Y: %f) in SCRIPT_COMMAND_TELEPORT_TO for script id %u",tablename,tmp.x,tmp.y,tmp.id); + continue; + } + break; + } + + case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: + { + if(!MaNGOS::IsValidMapCoord(tmp.x,tmp.y,tmp.z,tmp.o)) + { + sLog.outErrorDb("Table `%s` has invalid coordinates (X: %f Y: %f) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u",tablename,tmp.x,tmp.y,tmp.id); + continue; + } + + if(!GetCreatureTemplate(tmp.datalong)) + { + sLog.outErrorDb("Table `%s` has invalid creature (Entry: %u) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u",tablename,tmp.datalong,tmp.id); + continue; + } + break; + } + + case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT: + { + GameObjectData const* data = GetGOData(tmp.datalong); + if(!data) + { + sLog.outErrorDb("Table `%s` has invalid gameobject (GUID: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,tmp.datalong,tmp.id); + continue; + } + + GameObjectInfo const* info = GetGameObjectInfo(data->id); + if(!info) + { + sLog.outErrorDb("Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,tmp.datalong,data->id,tmp.id); + continue; + } + + if( info->type==GAMEOBJECT_TYPE_FISHINGNODE || + info->type==GAMEOBJECT_TYPE_FISHINGHOLE || + info->type==GAMEOBJECT_TYPE_DOOR || + info->type==GAMEOBJECT_TYPE_BUTTON || + info->type==GAMEOBJECT_TYPE_TRAP ) + { + sLog.outErrorDb("Table `%s` have gameobject type (%u) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,info->id,tmp.id); + continue; + } + break; + } + case SCRIPT_COMMAND_OPEN_DOOR: + case SCRIPT_COMMAND_CLOSE_DOOR: + { + GameObjectData const* data = GetGOData(tmp.datalong); + if(!data) + { + sLog.outErrorDb("Table `%s` has invalid gameobject (GUID: %u) in %s for script id %u",tablename,tmp.datalong,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id); + continue; + } + + GameObjectInfo const* info = GetGameObjectInfo(data->id); + if(!info) + { + sLog.outErrorDb("Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in %s for script id %u",tablename,tmp.datalong,data->id,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id); + continue; + } + + if( info->type!=GAMEOBJECT_TYPE_DOOR) + { + sLog.outErrorDb("Table `%s` has gameobject type (%u) non supported by command %s for script id %u",tablename,info->id,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id); + continue; + } + + break; + } + case SCRIPT_COMMAND_QUEST_EXPLORED: + { + Quest const* quest = GetQuestTemplate(tmp.datalong); + if(!quest) + { + sLog.outErrorDb("Table `%s` has invalid quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",tablename,tmp.datalong,tmp.id); + continue; + } + + if(!quest->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) + { + sLog.outErrorDb("Table `%s` has quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, but quest not have flag QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT in quest flags. Script command or quest flags wrong. Quest modified to require objective.",tablename,tmp.datalong,tmp.id); + + // this will prevent quest completing without objective + const_cast(quest)->SetFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT); + + // continue; - quest objective requiremet set and command can be allowed + } + + if(float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE) + { + sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",tablename,tmp.datalong2,tmp.id); + continue; + } + + if(tmp.datalong2 && float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE) + { + sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, max distance is %u or 0 for disable distance check",tablename,tmp.datalong2,tmp.id,uint32(DEFAULT_VISIBILITY_DISTANCE)); + continue; + } + + if(tmp.datalong2 && float(tmp.datalong2) < INTERACTION_DISTANCE) + { + sLog.outErrorDb("Table `%s` has too small distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, min distance is %u or 0 for disable distance check",tablename,tmp.datalong2,tmp.id,uint32(INTERACTION_DISTANCE)); + continue; + } + + break; + } + + case SCRIPT_COMMAND_REMOVE_AURA: + case SCRIPT_COMMAND_CAST_SPELL: + { + if(!sSpellStore.LookupEntry(tmp.datalong)) + { + sLog.outErrorDb("Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_REMOVE_AURA or SCRIPT_COMMAND_CAST_SPELL for script id %u",tablename,tmp.datalong,tmp.id); + continue; + } + break; + } + } + + if (scripts.find(tmp.id) == scripts.end()) + { + ScriptMap emptyMap; + scripts[tmp.id] = emptyMap; + } + scripts[tmp.id].insert(std::pair(tmp.delay, tmp)); + + ++count; + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u script definitions", count ); +} + +void ObjectMgr::LoadGameObjectScripts() +{ + LoadScripts(sGameObjectScripts, "gameobject_scripts"); + + // check ids + for(ScriptMapMap::const_iterator itr = sGameObjectScripts.begin(); itr != sGameObjectScripts.end(); ++itr) + { + if(!GetGOData(itr->first)) + sLog.outErrorDb("Table `gameobject_scripts` has not existing gameobject (GUID: %u) as script id",itr->first); + } +} + +void ObjectMgr::LoadQuestEndScripts() +{ + LoadScripts(sQuestEndScripts, "quest_end_scripts"); + + // check ids + for(ScriptMapMap::const_iterator itr = sQuestEndScripts.begin(); itr != sQuestEndScripts.end(); ++itr) + { + if(!GetQuestTemplate(itr->first)) + sLog.outErrorDb("Table `quest_end_scripts` has not existing quest (Id: %u) as script id",itr->first); + } +} + +void ObjectMgr::LoadQuestStartScripts() +{ + LoadScripts(sQuestStartScripts,"quest_start_scripts"); + + // check ids + for(ScriptMapMap::const_iterator itr = sQuestStartScripts.begin(); itr != sQuestStartScripts.end(); ++itr) + { + if(!GetQuestTemplate(itr->first)) + sLog.outErrorDb("Table `quest_start_scripts` has not existing quest (Id: %u) as script id",itr->first); + } +} + +void ObjectMgr::LoadSpellScripts() +{ + LoadScripts(sSpellScripts, "spell_scripts"); + + // check ids + for(ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); + + if(!spellInfo) + { + sLog.outErrorDb("Table `spell_scripts` has not existing spell (Id: %u) as script id",itr->first); + continue; + } + + //check for correct spellEffect + bool found = false; + for(int i=0; i<3; ++i) + { + // skip empty effects + if( !spellInfo->Effect[i] ) + continue; + + if( spellInfo->Effect[i] == SPELL_EFFECT_SCRIPT_EFFECT ) + { + found = true; + break; + } + } + + if(!found) + sLog.outErrorDb("Table `spell_scripts` has unsupported spell (Id: %u) without SPELL_EFFECT_SCRIPT_EFFECT (%u) spell effect",itr->first,SPELL_EFFECT_SCRIPT_EFFECT); + } +} + +void ObjectMgr::LoadEventScripts() +{ + LoadScripts(sEventScripts, "event_scripts"); + + std::set evt_scripts; + // Load all possible script entries from gameobjects + for(uint32 i = 1; i < sGOStorage.MaxEntry; ++i) + { + GameObjectInfo const * goInfo = sGOStorage.LookupEntry(i); + if (goInfo) + { + switch(goInfo->type) + { + case GAMEOBJECT_TYPE_GOOBER: + if(goInfo->goober.eventId) + evt_scripts.insert(goInfo->goober.eventId); + break; + case GAMEOBJECT_TYPE_CHEST: + if(goInfo->chest.eventId) + evt_scripts.insert(goInfo->chest.eventId); + break; + default: + break; + } + } + } + // Load all possible script entries from spells + for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) + { + SpellEntry const * spell = sSpellStore.LookupEntry(i); + if (spell) + { + for(int j=0; j<3; ++j) + { + if( spell->Effect[j] == SPELL_EFFECT_SEND_EVENT ) + { + if (spell->EffectMiscValue[j]) + evt_scripts.insert(spell->EffectMiscValue[j]); + } + } + } + } + // Then check if all scripts are in above list of possible script entries + for(ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr) + { + std::set::const_iterator itr2 = evt_scripts.find(itr->first); + if (itr2 == evt_scripts.end()) + sLog.outErrorDb("Table `event_scripts` has script (Id: %u) not refering to any gameobject_template type 10 data2 field or type 3 data6 field or any spell effect %u", itr->first, SPELL_EFFECT_SEND_EVENT); + } +} + +void ObjectMgr::LoadItemTexts() +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT id, text FROM item_text"); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u item pages", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + Field* fields; + do + { + bar.step(); + + fields = result->Fetch(); + + mItemTexts[ fields[0].GetUInt32() ] = fields[1].GetCppString(); + + ++count; + + } while ( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u item texts", count ); +} + +void ObjectMgr::LoadPageTexts() +{ + sPageTextStore.Free(); // for reload case + + sPageTextStore.Load(); + sLog.outString( ">> Loaded %u page texts", sPageTextStore.RecordCount ); + sLog.outString(); + + for(uint32 i = 1; i < sPageTextStore.MaxEntry; ++i) + { + // check data correctness + PageText const* page = sPageTextStore.LookupEntry(i); + if(!page) + continue; + + if(page->Next_Page && !sPageTextStore.LookupEntry(page->Next_Page)) + { + sLog.outErrorDb("Page text (Id: %u) has not existing next page (Id:%u)", i,page->Next_Page); + continue; + } + + // detect circular reference + std::set checkedPages; + for(PageText const* pageItr = page; pageItr; pageItr = sPageTextStore.LookupEntry(pageItr->Next_Page)) + { + if(!pageItr->Next_Page) + break; + checkedPages.insert(pageItr->Page_ID); + if(checkedPages.find(pageItr->Next_Page)!=checkedPages.end()) + { + std::ostringstream ss; + ss<< "The text page(s) "; + for (std::set::iterator itr= checkedPages.begin();itr!=checkedPages.end(); itr++) + ss << *itr << " "; + ss << "create(s) a circular reference, which can cause the server to freeze. Changing Next_Page of page " + << pageItr->Page_ID <<" to 0"; + sLog.outErrorDb(ss.str().c_str()); + const_cast(pageItr)->Next_Page = 0; + break; + } + } + } +} + +void ObjectMgr::LoadPageTextLocales() +{ + mPageTextLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.PQuery("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 PageText locale strings. DB table `locales_page_text` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + PageTextLocale& data = mPageTextLocaleMap[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[i].GetCppString(); + if(str.empty()) + continue; + + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Text.size() <= idx) + data.Text.resize(idx+1); + + data.Text[idx] = str; + } + } + + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u PageText locale strings", mPageTextLocaleMap.size() ); +} + +void ObjectMgr::LoadInstanceTemplate() +{ + sInstanceTemplate.Load(); + + for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) + { + InstanceTemplate* temp = (InstanceTemplate*)GetInstanceTemplate(i); + if(!temp) continue; + const MapEntry* entry = sMapStore.LookupEntry(temp->map); + if(!entry) + { + sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: bad mapid %d for template!", temp->map); + continue; + } + else if(!entry->HasResetTime()) + continue; + + if(temp->reset_delay == 0) + { + // use defaults from the DBC + if(entry->SupportsHeroicMode()) + { + temp->reset_delay = entry->resetTimeHeroic / DAY; + } + else if (entry->resetTimeRaid && entry->map_type == MAP_RAID) + { + temp->reset_delay = entry->resetTimeRaid / DAY; + } + } + + // the reset_delay must be atleast one day + temp->reset_delay = std::max((uint32)1, (uint32)(temp->reset_delay * sWorld.getRate(RATE_INSTANCE_RESET_TIME))); + } + + sLog.outString( ">> Loaded %u Instance Template definitions", sInstanceTemplate.RecordCount ); + sLog.outString(); +} + +void ObjectMgr::AddGossipText(GossipText *pGText) +{ + ASSERT( pGText->Text_ID ); + ASSERT( mGossipText.find(pGText->Text_ID) == mGossipText.end() ); + mGossipText[pGText->Text_ID] = pGText; +} + +GossipText *ObjectMgr::GetGossipText(uint32 Text_ID) +{ + GossipTextMap::const_iterator itr; + for (itr = mGossipText.begin(); itr != mGossipText.end(); itr++) + { + if(itr->second->Text_ID == Text_ID) + return itr->second; + } + return NULL; +} + +void ObjectMgr::LoadGossipText() +{ + GossipText *pGText; + QueryResult *result = WorldDatabase.Query( "SELECT * FROM npc_text" ); + + int count = 0; + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u npc texts", count ); + return; + } + + int cic; + + barGoLink bar( result->GetRowCount() ); + + do + { + ++count; + cic = 0; + + Field *fields = result->Fetch(); + + bar.step(); + + pGText = new GossipText; + pGText->Text_ID = fields[cic++].GetUInt32(); + + for (int i=0; i< 8; i++) + { + pGText->Options[i].Text_0 = fields[cic++].GetCppString(); + pGText->Options[i].Text_1 = fields[cic++].GetCppString(); + + pGText->Options[i].Language = fields[cic++].GetUInt32(); + pGText->Options[i].Probability = fields[cic++].GetFloat(); + + pGText->Options[i].Emotes[0]._Delay = fields[cic++].GetUInt32(); + pGText->Options[i].Emotes[0]._Emote = fields[cic++].GetUInt32(); + + pGText->Options[i].Emotes[1]._Delay = fields[cic++].GetUInt32(); + pGText->Options[i].Emotes[1]._Emote = fields[cic++].GetUInt32(); + + pGText->Options[i].Emotes[2]._Delay = fields[cic++].GetUInt32(); + pGText->Options[i].Emotes[2]._Emote = fields[cic++].GetUInt32(); + } + + if ( !pGText->Text_ID ) continue; + AddGossipText( pGText ); + + } while( result->NextRow() ); + + sLog.outString(); + sLog.outString( ">> Loaded %u npc texts", count ); + delete result; +} + +void ObjectMgr::LoadNpcTextLocales() +{ + mNpcTextLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT entry," + "Text0_0_loc1,Text0_1_loc1,Text1_0_loc1,Text1_1_loc1,Text2_0_loc1,Text2_1_loc1,Text3_0_loc1,Text3_1_loc1,Text4_0_loc1,Text4_1_loc1,Text5_0_loc1,Text5_1_loc1,Text6_0_loc1,Text6_1_loc1,Text7_0_loc1,Text7_1_loc1," + "Text0_0_loc2,Text0_1_loc2,Text1_0_loc2,Text1_1_loc2,Text2_0_loc2,Text2_1_loc2,Text3_0_loc2,Text3_1_loc1,Text4_0_loc2,Text4_1_loc2,Text5_0_loc2,Text5_1_loc2,Text6_0_loc2,Text6_1_loc2,Text7_0_loc2,Text7_1_loc2," + "Text0_0_loc3,Text0_1_loc3,Text1_0_loc3,Text1_1_loc3,Text2_0_loc3,Text2_1_loc3,Text3_0_loc3,Text3_1_loc1,Text4_0_loc3,Text4_1_loc3,Text5_0_loc3,Text5_1_loc3,Text6_0_loc3,Text6_1_loc3,Text7_0_loc3,Text7_1_loc3," + "Text0_0_loc4,Text0_1_loc4,Text1_0_loc4,Text1_1_loc4,Text2_0_loc4,Text2_1_loc4,Text3_0_loc4,Text3_1_loc1,Text4_0_loc4,Text4_1_loc4,Text5_0_loc4,Text5_1_loc4,Text6_0_loc4,Text6_1_loc4,Text7_0_loc4,Text7_1_loc4," + "Text0_0_loc5,Text0_1_loc5,Text1_0_loc5,Text1_1_loc5,Text2_0_loc5,Text2_1_loc5,Text3_0_loc5,Text3_1_loc1,Text4_0_loc5,Text4_1_loc5,Text5_0_loc5,Text5_1_loc5,Text6_0_loc5,Text6_1_loc5,Text7_0_loc5,Text7_1_loc5," + "Text0_0_loc6,Text0_1_loc6,Text1_0_loc6,Text1_1_loc6,Text2_0_loc6,Text2_1_loc6,Text3_0_loc6,Text3_1_loc1,Text4_0_loc6,Text4_1_loc6,Text5_0_loc6,Text5_1_loc6,Text6_0_loc6,Text6_1_loc6,Text7_0_loc6,Text7_1_loc6," + "Text0_0_loc7,Text0_1_loc7,Text1_0_loc7,Text1_1_loc7,Text2_0_loc7,Text2_1_loc7,Text3_0_loc7,Text3_1_loc1,Text4_0_loc7,Text4_1_loc7,Text5_0_loc7,Text5_1_loc7,Text6_0_loc7,Text6_1_loc7,Text7_0_loc7,Text7_1_loc7, " + "Text0_0_loc8,Text0_1_loc8,Text1_0_loc8,Text1_1_loc8,Text2_0_loc8,Text2_1_loc8,Text3_0_loc8,Text3_1_loc1,Text4_0_loc8,Text4_1_loc8,Text5_0_loc8,Text5_1_loc8,Text6_0_loc8,Text6_1_loc8,Text7_0_loc8,Text7_1_loc8 " + " FROM locales_npc_text"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_npc_text` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + NpcTextLocale& data = mNpcTextLocaleMap[entry]; + + for(int i=1; i= 0) + { + if(data.Text_0[j].size() <= idx) + data.Text_0[j].resize(idx+1); + + data.Text_0[j][idx] = str0; + } + } + std::string str1 = fields[1+8*2*(i-1)+2*j+1].GetCppString(); + if(!str1.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Text_1[j].size() <= idx) + data.Text_1[j].resize(idx+1); + + data.Text_1[j][idx] = str1; + } + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u NpcText locale strings", mNpcTextLocaleMap.size() ); +} + +//not very fast function but it is called only once a day, or on starting-up +void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) +{ + time_t basetime = time(NULL); + sLog.outDebug("Returning mails current time: hour: %d, minute: %d, second: %d ", localtime(&basetime)->tm_hour, localtime(&basetime)->tm_min, localtime(&basetime)->tm_sec); + //delete all old mails without item and without body immediately, if starting server + if (!serverUp) + CharacterDatabase.PExecute("DELETE FROM mail WHERE expire_time < '" I64FMTD "' AND has_items = '0' AND itemTextId = 0", (uint64)basetime); + // 0 1 2 3 4 5 6 7 8 9 + QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" I64FMTD "'", (uint64)basetime); + if ( !result ) + return; // any mails need to be returned or deleted + Field *fields; + //std::ostringstream delitems, delmails; //will be here for optimization + //bool deletemail = false, deleteitem = false; + //delitems << "DELETE FROM item_instance WHERE guid IN ( "; + //delmails << "DELETE FROM mail WHERE id IN ( " + do + { + fields = result->Fetch(); + Mail *m = new Mail; + m->messageID = fields[0].GetUInt32(); + m->messageType = fields[1].GetUInt8(); + m->sender = fields[2].GetUInt32(); + m->receiver = fields[3].GetUInt32(); + m->itemTextId = fields[4].GetUInt32(); + bool has_items = fields[5].GetBool(); + m->expire_time = (time_t)fields[6].GetUInt64(); + m->deliver_time = 0; + m->COD = fields[7].GetUInt32(); + m->checked = fields[8].GetUInt32(); + m->mailTemplateId = fields[9].GetInt16(); + + Player *pl = 0; + if (serverUp) + pl = GetPlayer((uint64)m->receiver); + if (pl && pl->m_mailsLoaded) + { //this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail + //his in mailbox and he has already listed his mails ) + delete m; + continue; + } + //delete or return mail: + if (has_items) + { + QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", m->messageID); + if(resultItems) + { + do + { + Field *fields2 = resultItems->Fetch(); + + uint32 item_guid_low = fields2[0].GetUInt32(); + uint32 item_template = fields2[1].GetUInt32(); + + m->AddItem(item_guid_low, item_template); + } + while (resultItems->NextRow()); + + delete resultItems; + } + //if it is mail from AH, it shouldn't be returned, but deleted + if (m->messageType != MAIL_NORMAL || (m->checked & (MAIL_CHECK_MASK_AUCTION | MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED))) + { + // mail open and then not returned + for(std::vector::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2) + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid); + } + else + { + //mail will be returned: + CharacterDatabase.PExecute("UPDATE mail SET sender = '%u', receiver = '%u', expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',cod = '0', checked = '%u' WHERE id = '%u'", m->receiver, m->sender, (uint64)(basetime + 30*DAY), (uint64)basetime, MAIL_CHECK_MASK_RETURNED, m->messageID); + delete m; + continue; + } + } + + if (m->itemTextId) + CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId); + + //deletemail = true; + //delmails << m->messageID << ", "; + CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID); + delete m; + } while (result->NextRow()); + delete result; +} + +void ObjectMgr::LoadQuestAreaTriggers() +{ + mQuestAreaTriggerMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query( "SELECT id,quest FROM areatrigger_involvedrelation" ); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u quest trigger points", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + ++count; + bar.step(); + + Field *fields = result->Fetch(); + + uint32 trigger_ID = fields[0].GetUInt32(); + uint32 quest_ID = fields[1].GetUInt32(); + + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(trigger_ID); + if(!atEntry) + { + sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",trigger_ID); + continue; + } + + Quest const* quest = GetQuestTemplate(quest_ID); + + if(!quest) + { + sLog.outErrorDb("Table `areatrigger_involvedrelation` has record (id: %u) for not existing quest %u",trigger_ID,quest_ID); + continue; + } + + if(!quest->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) + { + sLog.outErrorDb("Table `areatrigger_involvedrelation` has record (id: %u) for not quest %u, but quest not have flag QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT. Trigger or quest flags must be fixed, quest modified to require objective.",trigger_ID,quest_ID); + + // this will prevent quest completing without objective + const_cast(quest)->SetFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT); + + // continue; - quest modified to required obkective and trigger can be allowed. + } + + mQuestAreaTriggerMap[trigger_ID] = quest_ID; + + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u quest trigger points", count ); +} + +void ObjectMgr::LoadTavernAreaTriggers() +{ + mTavernAreaTriggerSet.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT id FROM areatrigger_tavern"); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u tavern triggers", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + ++count; + bar.step(); + + Field *fields = result->Fetch(); + + uint32 Trigger_ID = fields[0].GetUInt32(); + + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); + if(!atEntry) + { + sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID); + continue; + } + + mTavernAreaTriggerSet.insert(Trigger_ID); + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u tavern triggers", count ); +} + +void ObjectMgr::LoadAreaTriggerScripts() +{ + mAreaTriggerScripts.clear(); // need for reload case + QueryResult *result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts"); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u areatrigger scripts", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + ++count; + bar.step(); + + Field *fields = result->Fetch(); + + uint32 Trigger_ID = fields[0].GetUInt32(); + std::string scriptName = fields[1].GetCppString(); + + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); + if(!atEntry) + { + sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID); + continue; + } + mAreaTriggerScripts[Trigger_ID] = scriptName; + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u areatrigger scripts", count ); +} + +uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid ) +{ + bool found = false; + float dist; + uint32 id = 0; + + for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) + { + TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); + if(node && node->map_id == mapid) + { + float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z); + if(found) + { + if(dist2 < dist) + { + dist = dist2; + id = i; + } + } + else + { + found = true; + dist = dist2; + id = i; + } + } + } + + return id; +} + +void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost) +{ + TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source); + if(src_i==sTaxiPathSetBySource.end()) + { + path = 0; + cost = 0; + return; + } + + TaxiPathSetForSource& pathSet = src_i->second; + + TaxiPathSetForSource::iterator dest_i = pathSet.find(destination); + if(dest_i==pathSet.end()) + { + path = 0; + cost = 0; + return; + } + + cost = dest_i->second.price; + path = dest_i->second.ID; +} + +uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team ) +{ + uint16 mount_entry = 0; + uint16 mount_id = 0; + + TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id); + if(node) + { + if (team == ALLIANCE) + { + mount_entry = node->alliance_mount_type; + CreatureInfo const *ci = GetCreatureTemplate(mount_entry); + if(ci) + mount_id = ci->DisplayID_A; + } + if (team == HORDE) + { + mount_entry = node->horde_mount_type; + CreatureInfo const *ci = GetCreatureTemplate(mount_entry); + if(ci) + mount_id = ci->DisplayID_H; + } + } + + CreatureModelInfo const *minfo = GetCreatureModelInfo(mount_id); + if(!minfo) + { + sLog.outErrorDb("Taxi mount (Entry: %u) for taxi node (Id: %u) for team %u has model %u not found in table `creature_model_info`, can't load. ", + mount_entry,id,team,mount_id); + + return false; + } + if(minfo->modelid_other_gender!=0) + mount_id = urand(0,1) ? mount_id : minfo->modelid_other_gender; + + return mount_id; +} + +void ObjectMgr::GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector& mapIds) +{ + if(path >= sTaxiPathNodesByPath.size()) + return; + + TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path]; + + pathnodes.Resize(nodeList.size()); + mapIds.resize(nodeList.size()); + + for(size_t i = 0; i < nodeList.size(); ++i) + { + pathnodes[ i ].x = nodeList[i].x; + pathnodes[ i ].y = nodeList[i].y; + pathnodes[ i ].z = nodeList[i].z; + + mapIds[i] = nodeList[i].mapid; + } +} + +void ObjectMgr::GetTransportPathNodes( uint32 path, TransportPath &pathnodes ) +{ + if(path >= sTaxiPathNodesByPath.size()) + return; + + TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path]; + + pathnodes.Resize(nodeList.size()); + + for(size_t i = 0; i < nodeList.size(); ++i) + { + pathnodes[ i ].mapid = nodeList[i].mapid; + pathnodes[ i ].x = nodeList[i].x; + pathnodes[ i ].y = nodeList[i].y; + pathnodes[ i ].z = nodeList[i].z; + pathnodes[ i ].actionFlag = nodeList[i].actionFlag; + pathnodes[ i ].delay = nodeList[i].delay; + } +} + +void ObjectMgr::LoadGraveyardZones() +{ + mGraveYardMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT id,ghost_zone,faction FROM game_graveyard_zone"); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u graveyard-zone links", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + ++count; + bar.step(); + + Field *fields = result->Fetch(); + + uint32 safeLocId = fields[0].GetUInt32(); + uint32 zoneId = fields[1].GetUInt32(); + uint32 team = fields[2].GetUInt32(); + + WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(safeLocId); + if(!entry) + { + sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped.",safeLocId); + continue; + } + + AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId); + if(!areaEntry) + { + sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing zone id (%u), skipped.",zoneId); + continue; + } + + if(areaEntry->zone != 0) + { + sLog.outErrorDb("Table `game_graveyard_zone` has record subzone id (%u) instead of zone, skipped.",zoneId); + continue; + } + + if(team!=0 && team!=HORDE && team!=ALLIANCE) + { + sLog.outErrorDb("Table `game_graveyard_zone` has record for non player faction (%u), skipped.",team); + continue; + } + + if(entry->map_id != areaEntry->mapid && team != 0) + { + sLog.outErrorDb("Table `game_graveyard_zone` has record for ghost zone (%u) at map %u and graveyard (%u) at map %u for team %u, but in case maps are different, player faction setting is ignored. Use faction 0 instead.",zoneId,areaEntry->mapid, safeLocId, entry->map_id, team); + team = 0; + } + + if(!AddGraveYardLink(safeLocId,zoneId,team,false)) + sLog.outErrorDb("Table `game_graveyard_zone` has a duplicate record for Garveyard (ID: %u) and Zone (ID: %u), skipped.",safeLocId,zoneId); + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u graveyard-zone links", count ); +} + +WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) +{ + // search for zone associated closest graveyard + uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y); + + // Simulate std. algorithm: + // found some graveyard associated to (ghost_zone,ghost_map) + // + // if mapId == graveyard.mapId (ghost in plain zone or city or battleground) and search graveyard at same map + // then check faction + // if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated + // then skip check faction + GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId); + GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId); + if(graveLow==graveUp) + { + sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team); + return NULL; + } + + bool foundNear = false; + float distNear; + WorldSafeLocsEntry const* entryNear = NULL; + WorldSafeLocsEntry const* entryFar = NULL; + + for(GraveYardMap::const_iterator itr = graveLow; itr != graveUp; ++itr) + { + GraveYardData const& data = itr->second; + + WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(data.safeLocId); + if(!entry) + { + sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped.",data.safeLocId); + continue; + } + + // remember first graveyard at another map and ignore other + if(MapId != entry->map_id) + { + if(!entryFar) + entryFar = entry; + continue; + } + + // skip enemy faction graveyard at same map (normal area, city, or battleground) + // team == 0 case can be at call from .neargrave + if(data.team != 0 && team != 0 && data.team != team) + continue; + + // find now nearest graveyard at same map + float dist2 = (entry->x - x)*(entry->x - x)+(entry->y - y)*(entry->y - y)+(entry->z - z)*(entry->z - z); + if(foundNear) + { + if(dist2 < distNear) + { + distNear = dist2; + entryNear = entry; + } + } + else + { + foundNear = true; + distNear = dist2; + entryNear = entry; + } + } + + if(entryNear) + return entryNear; + + return entryFar; +} + +GraveYardData const* ObjectMgr::FindGraveYardData(uint32 id, uint32 zoneId) +{ + GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId); + GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId); + + for(GraveYardMap::const_iterator itr = graveLow; itr != graveUp; ++itr) + { + if(itr->second.safeLocId==id) + return &itr->second; + } + + return NULL; +} + +bool ObjectMgr::AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inDB) +{ + if(FindGraveYardData(id,zoneId)) + return false; + + // add link to loaded data + GraveYardData data; + data.safeLocId = id; + data.team = team; + + mGraveYardMap.insert(GraveYardMap::value_type(zoneId,data)); + + // add link to DB + if(inDB) + { + WorldDatabase.PExecuteLog("INSERT INTO game_graveyard_zone ( id,ghost_zone,faction) " + "VALUES ('%u', '%u','%u')",id,zoneId,team); + } + + return true; +} + +void ObjectMgr::LoadAreaTriggerTeleports() +{ + mAreaTriggers.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 + QueryResult *result = WorldDatabase.Query("SELECT id, required_level, required_item, required_item2, heroic_key, heroic_key2, required_quest_done, required_failed_text, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u area trigger teleport definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + ++count; + + uint32 Trigger_ID = fields[0].GetUInt32(); + + AreaTrigger at; + + at.requiredLevel = fields[1].GetUInt8(); + at.requiredItem = fields[2].GetUInt32(); + at.requiredItem2 = fields[3].GetUInt32(); + at.heroicKey = fields[4].GetUInt32(); + at.heroicKey2 = fields[5].GetUInt32(); + at.requiredQuest = fields[6].GetUInt32(); + at.requiredFailedText = fields[7].GetCppString(); + at.target_mapId = fields[8].GetUInt32(); + at.target_X = fields[9].GetFloat(); + at.target_Y = fields[10].GetFloat(); + at.target_Z = fields[11].GetFloat(); + at.target_Orientation = fields[12].GetFloat(); + + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); + if(!atEntry) + { + sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID); + continue; + } + + if(at.requiredItem) + { + ItemPrototype const *pProto = GetItemPrototype(at.requiredItem); + if(!pProto) + { + sLog.outError("Key item %u does not exist for trigger %u, removing key requirement.", at.requiredItem, Trigger_ID); + at.requiredItem = 0; + } + } + if(at.requiredItem2) + { + ItemPrototype const *pProto = GetItemPrototype(at.requiredItem2); + if(!pProto) + { + sLog.outError("Second item %u not exist for trigger %u, remove key requirement.", at.requiredItem2, Trigger_ID); + at.requiredItem2 = 0; + } + } + + if(at.heroicKey) + { + ItemPrototype const *pProto = GetItemPrototype(at.heroicKey); + if(!pProto) + { + sLog.outError("Heroic key item %u not exist for trigger %u, remove key requirement.", at.heroicKey, Trigger_ID); + at.heroicKey = 0; + } + } + + if(at.heroicKey2) + { + ItemPrototype const *pProto = GetItemPrototype(at.heroicKey2); + if(!pProto) + { + sLog.outError("Heroic second key item %u not exist for trigger %u, remove key requirement.", at.heroicKey2, Trigger_ID); + at.heroicKey2 = 0; + } + } + + if(at.requiredQuest) + { + if(!mQuestTemplates[at.requiredQuest]) + { + sLog.outErrorDb("Required Quest %u not exist for trigger %u, remove quest done requirement.",at.requiredQuest,Trigger_ID); + at.requiredQuest = 0; + } + } + + MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId); + if(!mapEntry) + { + sLog.outErrorDb("Area trigger (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.",Trigger_ID,at.target_mapId); + continue; + } + + if(at.target_X==0 && at.target_Y==0 && at.target_Z==0) + { + sLog.outErrorDb("Area trigger (ID:%u) target coordinates not provided.",Trigger_ID); + continue; + } + + mAreaTriggers[Trigger_ID] = at; + + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u area trigger teleport definitions", count ); +} + +AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const +{ + const MapEntry *mapEntry = sMapStore.LookupEntry(Map); + if(!mapEntry) return NULL; + for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); itr++) + { + if(itr->second.target_mapId == mapEntry->parent_map) + { + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first); + if(atEntry && atEntry->mapid == Map) + return &itr->second; + } + } + return NULL; +} + +void ObjectMgr::SetHighestGuids() +{ + QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" ); + if( result ) + { + m_hiCharGuid = (*result)[0].GetUInt32()+1; + + delete result; + } + + result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" ); + if( result ) + { + m_hiCreatureGuid = (*result)[0].GetUInt32()+1; + + delete result; + } + + result = CharacterDatabase.Query( "SELECT MAX(id) FROM character_pet" ); + if( result ) + { + m_hiPetGuid = (*result)[0].GetUInt32()+1; + + delete result; + } + + result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" ); + if( result ) + { + m_hiItemGuid = (*result)[0].GetUInt32()+1; + + delete result; + } + + // Cleanup other tables from not existed guids (>=m_hiItemGuid) + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_hiItemGuid); + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_hiItemGuid); + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_hiItemGuid); + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_hiItemGuid); + + result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" ); + if( result ) + { + m_hiGoGuid = (*result)[0].GetUInt32()+1; + + delete result; + } + + result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" ); + if( result ) + { + m_auctionid = (*result)[0].GetUInt32()+1; + + delete result; + } + else + { + m_auctionid = 0; + } + result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" ); + if( result ) + { + m_mailid = (*result)[0].GetUInt32()+1; + + delete result; + } + else + { + m_mailid = 0; + } + result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" ); + if( result ) + { + m_ItemTextId = (*result)[0].GetUInt32(); + + delete result; + } + else + m_ItemTextId = 0; + + result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" ); + if( result ) + { + m_hiCorpseGuid = (*result)[0].GetUInt32()+1; + + delete result; + } +} + +uint32 ObjectMgr::GenerateAuctionID() +{ + ++m_auctionid; + if(m_auctionid>=0xFFFFFFFF) + { + sLog.outError("Auctions ids overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_auctionid; +} + +uint32 ObjectMgr::GenerateMailID() +{ + ++m_mailid; + if(m_mailid>=0xFFFFFFFF) + { + sLog.outError("Mail ids overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_mailid; +} + +uint32 ObjectMgr::GenerateItemTextID() +{ + ++m_ItemTextId; + if(m_ItemTextId>=0xFFFFFFFF) + { + sLog.outError("Item text ids overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_ItemTextId; +} + +uint32 ObjectMgr::CreateItemText(std::string text) +{ + uint32 newItemTextId = GenerateItemTextID(); + //insert new itempage to container + mItemTexts[ newItemTextId ] = text; + //save new itempage + CharacterDatabase.escape_string(text); + //any Delete query needed, itemTextId is maximum of all ids + std::ostringstream query; + query << "INSERT INTO item_text (id,text) VALUES ( '" << newItemTextId << "', '" << text << "')"; + CharacterDatabase.Execute(query.str().c_str()); //needs to be run this way, because mail body may be more than 1024 characters + return newItemTextId; +} + +uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) +{ + switch(guidhigh) + { + case HIGHGUID_ITEM: + ++m_hiItemGuid; + if(m_hiItemGuid>=0xFFFFFFFF) + { + sLog.outError("Item guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiItemGuid; + case HIGHGUID_UNIT: + ++m_hiCreatureGuid; + if(m_hiCreatureGuid>=0x00FFFFFF) + { + sLog.outError("Creature guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiCreatureGuid; + case HIGHGUID_PET: + ++m_hiPetGuid; + if(m_hiPetGuid>=0x00FFFFFF) + { + sLog.outError("Pet guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiPetGuid; + case HIGHGUID_PLAYER: + ++m_hiCharGuid; + if(m_hiCharGuid>=0xFFFFFFFF) + { + sLog.outError("Players guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiCharGuid; + case HIGHGUID_GAMEOBJECT: + ++m_hiGoGuid; + if(m_hiGoGuid>=0x00FFFFFF) + { + sLog.outError("Gameobject guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiGoGuid; + case HIGHGUID_CORPSE: + ++m_hiCorpseGuid; + if(m_hiCorpseGuid>=0xFFFFFFFF) + { + sLog.outError("Corpse guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiCorpseGuid; + case HIGHGUID_DYNAMICOBJECT: + ++m_hiDoGuid; + if(m_hiDoGuid>=0xFFFFFFFF) + { + sLog.outError("DynamicObject guid overflow!! Can't continue, shuting down server. "); + sWorld.m_stopEvent = true; + } + return m_hiDoGuid; + default: + ASSERT(0); + } + + ASSERT(0); + return 0; +} + +void ObjectMgr::LoadGameObjectLocales() +{ + mGameObjectLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT entry," + "name_loc1,name_loc2,name_loc3,name_loc4,name_loc5,name_loc6,name_loc7,name_loc8," + "castbarcaption_loc1,castbarcaption_loc2,castbarcaption_loc3,castbarcaption_loc4," + "castbarcaption_loc5,castbarcaption_loc6,castbarcaption_loc7,castbarcaption_loc8 FROM locales_gameobject"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 gameobject locale strings. DB table `locales_gameobject` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + GameObjectLocale& data = mGameObjectLocaleMap[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[i].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.Name.size() <= idx) + data.Name.resize(idx+1); + + data.Name[idx] = str; + } + } + } + + for(int i = MAX_LOCALE; i < MAX_LOCALE*2-1; ++i) + { + std::string str = fields[i].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.CastBarCaption.size() <= idx) + data.CastBarCaption.resize(idx+1); + + data.CastBarCaption[idx] = str; + } + } + } + + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u gameobject locale strings", mGameObjectLocaleMap.size() ); +} + +void ObjectMgr::LoadGameobjectInfo() +{ + sGOStorage.Load(); + + // some checks + for(uint32 id = 1; id < sGOStorage.MaxEntry; id++) + { + GameObjectInfo const* goInfo = sGOStorage.LookupEntry(id); + if(!goInfo) + continue; + + switch(goInfo->type) + { + case GAMEOBJECT_TYPE_DOOR: //0 + { + if(goInfo->door.lockId) + { + if(!sLockStore.LookupEntry(goInfo->door.lockId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but lock (Id: %u) not found.", + id,goInfo->type,goInfo->door.lockId,goInfo->door.lockId); + } + break; + } + case GAMEOBJECT_TYPE_BUTTON: //1 + { + if(goInfo->button.lockId) + { + if(!sLockStore.LookupEntry(goInfo->button.lockId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but lock (Id: %u) not found.", + id,goInfo->type,goInfo->button.lockId,goInfo->button.lockId); + } + break; + } + case GAMEOBJECT_TYPE_CHEST: //3 + { + if(goInfo->chest.lockId) + { + if(!sLockStore.LookupEntry(goInfo->chest.lockId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but lock (Id: %u) not found.", + id,goInfo->type,goInfo->chest.lockId,goInfo->chest.lockId); + } + if(goInfo->chest.linkedTrapId) // linked trap + { + if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry(goInfo->chest.linkedTrapId)) + { + if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.", + id,goInfo->type,goInfo->chest.linkedTrapId,goInfo->chest.linkedTrapId,GAMEOBJECT_TYPE_TRAP); + } + /* disable check for while + else + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but trap GO (Entry %u) not exist in `gameobject_template`.", + id,goInfo->type,goInfo->chest.linkedTrapId,goInfo->chest.linkedTrapId); + */ + } + break; + } + case GAMEOBJECT_TYPE_TRAP: //6 + { + /* disable check for while + if(goInfo->trap.spellId) // spell + { + if(!sSpellStore.LookupEntry(goInfo->trap.spellId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data3=%u but Spell (Entry %u) not exist.", + id,goInfo->type,goInfo->trap.spellId,goInfo->trap.spellId); + } + */ + break; + } + case GAMEOBJECT_TYPE_CHAIR: //7 + if(goInfo->chair.height > 2) + { + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but correct chair height in range 0..2.", + id,goInfo->type,goInfo->chair.height); + + // prevent client and server unexpected work + const_cast(goInfo)->chair.height = 0; + } + break; + case GAMEOBJECT_TYPE_SPELL_FOCUS: //8 + { + if(goInfo->spellFocus.focusId) + { + if(!sSpellFocusObjectStore.LookupEntry(goInfo->spellFocus.focusId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but SpellFocus (Id: %u) not exist.", + id,goInfo->type,goInfo->spellFocus.focusId,goInfo->spellFocus.focusId); + } + + if(goInfo->spellFocus.linkedTrapId) // linked trap + { + if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry(goInfo->spellFocus.linkedTrapId)) + { + if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.", + id,goInfo->type,goInfo->spellFocus.linkedTrapId,goInfo->spellFocus.linkedTrapId,GAMEOBJECT_TYPE_TRAP); + } + /* disable check for while + else + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but trap GO (Entry %u) not exist in `gameobject_template`.", + id,goInfo->type,goInfo->spellFocus.linkedTrapId,goInfo->spellFocus.linkedTrapId); + */ + } + break; + } + case GAMEOBJECT_TYPE_GOOBER: //10 + { + if(goInfo->goober.pageId) // pageId + { + if(!sPageTextStore.LookupEntry(goInfo->goober.pageId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but PageText (Entry %u) not exist.", + id,goInfo->type,goInfo->goober.pageId,goInfo->goober.pageId); + } + /* disable check for while + if(goInfo->goober.spellId) // spell + { + if(!sSpellStore.LookupEntry(goInfo->goober.spellId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but Spell (Entry %u) not exist.", + id,goInfo->type,goInfo->goober.spellId,goInfo->goober.spellId); + } + */ + if(goInfo->goober.linkedTrapId) // linked trap + { + if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry(goInfo->goober.linkedTrapId)) + { + if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data12=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.", + id,goInfo->type,goInfo->goober.linkedTrapId,goInfo->goober.linkedTrapId,GAMEOBJECT_TYPE_TRAP); + } + /* disable check for while + else + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data12=%u but trap GO (Entry %u) not exist in `gameobject_template`.", + id,goInfo->type,goInfo->goober.linkedTrapId,goInfo->goober.linkedTrapId); + */ + } + break; + } + case GAMEOBJECT_TYPE_MO_TRANSPORT: //15 + { + if(goInfo->moTransport.taxiPathId) + { + if(goInfo->moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[goInfo->moTransport.taxiPathId].empty()) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but TaxiPath (Id: %u) not exist.", + id,goInfo->type,goInfo->moTransport.taxiPathId,goInfo->moTransport.taxiPathId); + } + break; + } + case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18 + { + /* disabled + if(goInfo->summoningRitual.spellId) + { + if(!sSpellStore.LookupEntry(goInfo->summoningRitual.spellId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but Spell (Entry %u) not exist.", + id,goInfo->type,goInfo->summoningRitual.spellId,goInfo->summoningRitual.spellId); + } + */ + break; + } + case GAMEOBJECT_TYPE_SPELLCASTER: //22 + { + if(goInfo->spellcaster.spellId) // spell + { + if(!sSpellStore.LookupEntry(goInfo->spellcaster.spellId)) + sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data3=%u but Spell (Entry %u) not exist.", + id,goInfo->type,goInfo->spellcaster.spellId,goInfo->spellcaster.spellId); + } + break; + } + } + } + + sLog.outString( ">> Loaded %u game object templates", sGOStorage.RecordCount ); + sLog.outString(); +} + +void ObjectMgr::LoadExplorationBaseXP() +{ + uint32 count = 0; + QueryResult *result = WorldDatabase.Query("SELECT level,basexp FROM exploration_basexp"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u BaseXP definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + uint32 level = fields[0].GetUInt32(); + uint32 basexp = fields[1].GetUInt32(); + mBaseXPTable[level] = basexp; + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u BaseXP definitions", count ); +} + +uint32 ObjectMgr::GetBaseXP(uint32 level) +{ + return mBaseXPTable[level] ? mBaseXPTable[level] : 0; +} + +void ObjectMgr::LoadPetNames() +{ + uint32 count = 0; + QueryResult *result = WorldDatabase.Query("SELECT word,entry,half FROM pet_name_generation"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u pet name parts", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + std::string word = fields[0].GetString(); + uint32 entry = fields[1].GetUInt32(); + bool half = fields[2].GetBool(); + if(half) + PetHalfName1[entry].push_back(word); + else + PetHalfName0[entry].push_back(word); + ++count; + } + while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u pet name parts", count ); +} + +void ObjectMgr::LoadPetNumber() +{ + QueryResult* result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet"); + if(result) + { + Field *fields = result->Fetch(); + m_hiPetNumber = fields[0].GetUInt32()+1; + delete result; + } + + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded the max pet number: %d", m_hiPetNumber-1); +} + +std::string ObjectMgr::GeneratePetName(uint32 entry) +{ + std::vector & list0 = PetHalfName0[entry]; + std::vector & list1 = PetHalfName1[entry]; + + if(list0.empty() || list1.empty()) + { + CreatureInfo const *cinfo = GetCreatureTemplate(entry); + char* petname = GetPetName(cinfo->family, sWorld.GetDefaultDbcLocale()); + if(!petname) + petname = cinfo->Name; + return std::string(petname); + } + + return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1)); +} + +uint32 ObjectMgr::GeneratePetNumber() +{ + return ++m_hiPetNumber; +} + +void ObjectMgr::LoadCorpses() +{ + uint32 count = 0; + // 0 1 2 3 4 5 6 7 8 10 + QueryResult *result = CharacterDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u corpses", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + + uint32 guid = fields[result->GetFieldCount()-1].GetUInt32(); + + Corpse *corpse = new Corpse; + if(!corpse->LoadFromDB(guid,fields)) + { + delete corpse; + continue; + } + + ObjectAccessor::Instance().AddCorpse(corpse); + + ++count; + } + while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u corpses", count ); +} + +void ObjectMgr::LoadReputationOnKill() +{ + uint32 count = 0; + + // 0 1 2 + QueryResult *result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2," + // 3 4 5 6 7 8 9 + "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent " + "FROM creature_onkill_reputation"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 creature_id = fields[0].GetUInt32(); + + ReputationOnKillEntry repOnKill; + repOnKill.repfaction1 = fields[1].GetUInt32(); + repOnKill.repfaction2 = fields[2].GetUInt32(); + repOnKill.is_teamaward1 = fields[3].GetBool(); + repOnKill.reputation_max_cap1 = fields[4].GetUInt32(); + repOnKill.repvalue1 = fields[5].GetInt32(); + repOnKill.is_teamaward2 = fields[6].GetBool(); + repOnKill.reputation_max_cap2 = fields[7].GetUInt32(); + repOnKill.repvalue2 = fields[8].GetInt32(); + repOnKill.team_dependent = fields[9].GetUInt8(); + + if(!GetCreatureTemplate(creature_id)) + { + sLog.outErrorDb("Table `creature_onkill_reputation` have data for not existed creature entry (%u), skipped",creature_id); + continue; + } + + if(repOnKill.repfaction1) + { + FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(repOnKill.repfaction1); + if(!factionEntry1) + { + sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction1); + continue; + } + } + + if(repOnKill.repfaction2) + { + FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(repOnKill.repfaction2); + if(!factionEntry2) + { + sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction2); + continue; + } + } + + mRepOnKill[creature_id] = repOnKill; + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString(">> Loaded %u creature award reputation definitions", count); +} + +void ObjectMgr::LoadWeatherZoneChances() +{ + uint32 count = 0; + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 + QueryResult *result = WorldDatabase.Query("SELECT zone, spring_rain_chance, spring_snow_chance, spring_storm_chance, summer_rain_chance, summer_snow_chance, summer_storm_chance, fall_rain_chance, fall_snow_chance, fall_storm_chance, winter_rain_chance, winter_snow_chance, winter_storm_chance FROM game_weather"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 weather definitions. DB table `game_weather` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 zone_id = fields[0].GetUInt32(); + + WeatherZoneChances& wzc = mWeatherZoneMap[zone_id]; + + for(int season = 0; season < WEATHER_SEASONS; ++season) + { + wzc.data[season].rainChance = fields[season * (MAX_WEATHER_TYPE-1) + 1].GetUInt32(); + wzc.data[season].snowChance = fields[season * (MAX_WEATHER_TYPE-1) + 2].GetUInt32(); + wzc.data[season].stormChance = fields[season * (MAX_WEATHER_TYPE-1) + 3].GetUInt32(); + + if(wzc.data[season].rainChance > 100) + { + wzc.data[season].rainChance = 25; + sLog.outErrorDb("Weather for zone %u season %u has wrong rain chance > 100%",zone_id,season); + } + + if(wzc.data[season].snowChance > 100) + { + wzc.data[season].snowChance = 25; + sLog.outErrorDb("Weather for zone %u season %u has wrong snow chance > 100%",zone_id,season); + } + + if(wzc.data[season].stormChance > 100) + { + wzc.data[season].stormChance = 25; + sLog.outErrorDb("Weather for zone %u season %u has wrong storm chance > 100%",zone_id,season); + } + } + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString(">> Loaded %u weather definitions", count); +} + +void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t) +{ + mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = t; + WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); + if(t) + WorldDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance); +} + +void ObjectMgr::DeleteCreatureData(uint32 guid) +{ + // remove mapid*cellid -> guid_set map + CreatureData const* data = GetCreatureData(guid); + if(data) + RemoveCreatureFromGrid(guid, data); + + mCreatureDataMap.erase(guid); +} + +void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t) +{ + mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = t; + WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); + if(t) + WorldDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance); +} + +void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance) +{ + RespawnTimes::iterator next; + + for(RespawnTimes::iterator itr = mGORespawnTimes.begin(); itr != mGORespawnTimes.end(); itr = next) + { + next = itr; + ++next; + + if(GUID_HIPART(itr->first)==instance) + mGORespawnTimes.erase(itr); + } + + for(RespawnTimes::iterator itr = mCreatureRespawnTimes.begin(); itr != mCreatureRespawnTimes.end(); itr = next) + { + next = itr; + ++next; + + if(GUID_HIPART(itr->first)==instance) + mCreatureRespawnTimes.erase(itr); + } + + WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", instance); + WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", instance); +} + +void ObjectMgr::DeleteGOData(uint32 guid) +{ + // remove mapid*cellid -> guid_set map + GameObjectData const* data = GetGOData(guid); + if(data) + RemoveGameobjectFromGrid(guid, data); + + mGameObjectDataMap.erase(guid); +} + +void ObjectMgr::AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance) +{ + // corpses are always added to spawn mode 0 and they are spawned by their instance id + CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(mapid,0)][cellid]; + cell_guids.corpses[player_guid] = instance; +} + +void ObjectMgr::DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid) +{ + // corpses are always added to spawn mode 0 and they are spawned by their instance id + CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(mapid,0)][cellid]; + cell_guids.corpses.erase(player_guid); +} + +void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map,char const* table) +{ + map.clear(); // need for reload case + + uint32 count = 0; + + QueryResult *result = WorldDatabase.PQuery("SELECT id,quest FROM %s",table); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 quest relations from %s. DB table `%s` is empty.",table,table); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 id = fields[0].GetUInt32(); + uint32 quest = fields[1].GetUInt32(); + + if(mQuestTemplates.find(quest) == mQuestTemplates.end()) + { + sLog.outErrorDb("Table `%s: Quest %u listed for entry %u does not exist.",table,quest,id); + continue; + } + + map.insert(QuestRelations::value_type(id,quest)); + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString(">> Loaded %u quest relations from %s", count,table); +} + +void ObjectMgr::LoadGameobjectQuestRelations() +{ + LoadQuestRelationsHelper(mGOQuestRelations,"gameobject_questrelation"); + + for(QuestRelations::iterator itr = mGOQuestRelations.begin(); itr != mGOQuestRelations.end(); ++itr) + { + GameObjectInfo const* goInfo = GetGameObjectInfo(itr->first); + if(!goInfo) + sLog.outErrorDb("Table `gameobject_questrelation` have data for not existed gameobject entry (%u) and existed quest %u",itr->first,itr->second); + else if(goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER) + sLog.outErrorDb("Table `gameobject_questrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER",itr->first,itr->second); + } +} + +void ObjectMgr::LoadGameobjectInvolvedRelations() +{ + LoadQuestRelationsHelper(mGOQuestInvolvedRelations,"gameobject_involvedrelation"); + + for(QuestRelations::iterator itr = mGOQuestInvolvedRelations.begin(); itr != mGOQuestInvolvedRelations.end(); ++itr) + { + GameObjectInfo const* goInfo = GetGameObjectInfo(itr->first); + if(!goInfo) + sLog.outErrorDb("Table `gameobject_involvedrelation` have data for not existed gameobject entry (%u) and existed quest %u",itr->first,itr->second); + else if(goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER) + sLog.outErrorDb("Table `gameobject_involvedrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER",itr->first,itr->second); + } +} + +void ObjectMgr::LoadCreatureQuestRelations() +{ + LoadQuestRelationsHelper(mCreatureQuestRelations,"creature_questrelation"); + + for(QuestRelations::iterator itr = mCreatureQuestRelations.begin(); itr != mCreatureQuestRelations.end(); ++itr) + { + CreatureInfo const* cInfo = GetCreatureTemplate(itr->first); + if(!cInfo) + sLog.outErrorDb("Table `creature_questrelation` have data for not existed creature entry (%u) and existed quest %u",itr->first,itr->second); + else if(!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER)) + sLog.outErrorDb("Table `creature_questrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER",itr->first,itr->second); + } +} + +void ObjectMgr::LoadCreatureInvolvedRelations() +{ + LoadQuestRelationsHelper(mCreatureQuestInvolvedRelations,"creature_involvedrelation"); + + for(QuestRelations::iterator itr = mCreatureQuestInvolvedRelations.begin(); itr != mCreatureQuestInvolvedRelations.end(); ++itr) + { + CreatureInfo const* cInfo = GetCreatureTemplate(itr->first); + if(!cInfo) + sLog.outErrorDb("Table `creature_involvedrelation` have data for not existed creature entry (%u) and existed quest %u",itr->first,itr->second); + else if(!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER)) + sLog.outErrorDb("Table `creature_involvedrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER",itr->first,itr->second); + } +} + +void ObjectMgr::LoadReservedPlayersNames() +{ + m_ReservedNames.clear(); // need for reload case + + QueryResult *result = WorldDatabase.PQuery("SELECT name FROM reserved_name"); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u reserved player names", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + Field* fields; + do + { + bar.step(); + fields = result->Fetch(); + std::string name= fields[0].GetCppString(); + if(normalizePlayerName(name)) + { + m_ReservedNames.insert(name); + ++count; + } + } while ( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u reserved player names", count ); +} + +enum LanguageType +{ + LT_BASIC_LATIN = 0x0000, + LT_EXTENDEN_LATIN = 0x0001, + LT_CYRILLIC = 0x0002, + LT_EAST_ASIA = 0x0004, + LT_ANY = 0xFFFF +}; + +static LanguageType GetRealmLanguageType(bool create) +{ + switch(sWorld.getConfig(CONFIG_REALM_ZONE)) + { + case REALM_ZONE_UNKNOWN: // any language + case REALM_ZONE_DEVELOPMENT: + case REALM_ZONE_TEST_SERVER: + case REALM_ZONE_QA_SERVER: + return LT_ANY; + case REALM_ZONE_UNITED_STATES: // extended-Latin + case REALM_ZONE_OCEANIC: + case REALM_ZONE_LATIN_AMERICA: + case REALM_ZONE_ENGLISH: + case REALM_ZONE_GERMAN: + case REALM_ZONE_FRENCH: + case REALM_ZONE_SPANISH: + return LT_EXTENDEN_LATIN; + case REALM_ZONE_KOREA: // East-Asian + case REALM_ZONE_TAIWAN: + case REALM_ZONE_CHINA: + return LT_EAST_ASIA; + case REALM_ZONE_RUSSIAN: // Cyrillic + return LT_CYRILLIC; + default: + return create ? LT_BASIC_LATIN : LT_ANY; // basic-Latin at create, any at login + } +} + +bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create = false) +{ + if(strictMask==0) // any language, ignore realm + { + if(isExtendedLatinString(wstr,numericOrSpace)) + return true; + if(isCyrillicString(wstr,numericOrSpace)) + return true; + if(isEastAsianString(wstr,numericOrSpace)) + return true; + return false; + } + + if(strictMask & 0x2) // realm zone specific + { + LanguageType lt = GetRealmLanguageType(create); + if(lt & LT_EXTENDEN_LATIN) + if(isExtendedLatinString(wstr,numericOrSpace)) + return true; + if(lt & LT_CYRILLIC) + if(isCyrillicString(wstr,numericOrSpace)) + return true; + if(lt & LT_EAST_ASIA) + if(isEastAsianString(wstr,numericOrSpace)) + return true; + } + + if(strictMask & 0x1) // basic latin + { + if(isBasicLatinString(wstr,numericOrSpace)) + return true; + } + + return false; +} + +bool ObjectMgr::IsValidName( std::string name, bool create ) +{ + std::wstring wname; + if(!Utf8toWStr(name,wname)) + return false; + + if(wname.size() < 1 || wname.size() > MAX_PLAYER_NAME) + return false; + + uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_PLAYER_NAMES); + + return isValidString(wname,strictMask,false,create); +} + +bool ObjectMgr::IsValidCharterName( std::string name ) +{ + std::wstring wname; + if(!Utf8toWStr(name,wname)) + return false; + + if(wname.size() < 1) + return false; + + uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_CHARTER_NAMES); + + return isValidString(wname,strictMask,true); +} + +bool ObjectMgr::IsValidPetName( std::string name ) +{ + std::wstring wname; + if(!Utf8toWStr(name,wname)) + return false; + + if(wname.size() < 1) + return false; + + uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_PET_NAMES); + + return isValidString(wname,strictMask,false); +} + +int ObjectMgr::GetIndexForLocale( LocaleConstant loc ) +{ + if(loc==LOCALE_enUS) + return -1; + + for(size_t i=0;i < m_LocalForIndex.size(); ++i) + if(m_LocalForIndex[i]==loc) + return i; + + return -1; +} + +LocaleConstant ObjectMgr::GetLocaleForIndex(int i) +{ + if (i<0 || i>=m_LocalForIndex.size()) + return LOCALE_enUS; + + return m_LocalForIndex[i]; +} + +int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc ) +{ + if(loc==LOCALE_enUS) + return -1; + + for(size_t i=0;i < m_LocalForIndex.size(); ++i) + if(m_LocalForIndex[i]==loc) + return i; + + m_LocalForIndex.push_back(loc); + return m_LocalForIndex.size()-1; +} + +void ObjectMgr::LoadBattleMastersEntry() +{ + mBattleMastersMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" ); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + ++count; + bar.step(); + + Field *fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + uint32 bgTypeId = fields[1].GetUInt32(); + + mBattleMastersMap[entry] = bgTypeId; + + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u battlemaster entries", count ); +} + +void ObjectMgr::LoadGameObjectForQuests() +{ + mGameObjectForQuestSet.clear(); // need for reload case + + uint32 count = 0; + + // collect GO entries for GO that must activated + for(uint32 go_entry = 1; go_entry < sGOStorage.MaxEntry; ++go_entry) + { + GameObjectInfo const* goInfo = sGOStorage.LookupEntry(go_entry); + if(!goInfo) + continue; + + switch(goInfo->type) + { + // scan GO chest with loot including quest items + case GAMEOBJECT_TYPE_CHEST: + { + uint32 loot_id = GameObject::GetLootId(goInfo); + + // find quest loot for GO + if(LootTemplates_Gameobject.HaveQuestLootFor(loot_id)) + { + mGameObjectForQuestSet.insert(go_entry); + ++count; + } + break; + } + case GAMEOBJECT_TYPE_GOOBER: + { + if(goInfo->goober.questId) //quests objects + { + mGameObjectForQuestSet.insert(go_entry); + count++; + } + break; + } + default: + break; + } + } + + sLog.outString(); + sLog.outString( ">> Loaded %u GameObject for quests", count ); +} + +bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value) +{ + // cleanup affected map part for reloading case + for(MangosStringLocaleMap::iterator itr = mMangosStringLocaleMap.begin(); itr != mMangosStringLocaleMap.end();) + { + if(itr->first >= min_value && itr->first <= max_value) + { + MangosStringLocaleMap::iterator itr2 = itr; + ++itr; + mMangosStringLocaleMap.erase(itr2); + } + else + ++itr; + } + + QueryResult *result = db.PQuery("SELECT entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8 FROM %s",table); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + if(min_value > 0) // error only in case internal strings + sLog.outErrorDb(">> Loaded 0 mangos strings. DB table `%s` is empty. Cannot continue.",table); + else + sLog.outString(">> Loaded 0 string templates. DB table `%s` is empty.",table); + return false; + } + + uint32 count = 0; + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + int32 entry = fields[0].GetInt32(); + + if(entry==0) + { + sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.",table); + continue; + } + else if(entry < min_value || entry > max_value) + { + int32 start = min_value > 0 ? min_value : max_value; + int32 end = min_value > 0 ? max_value : min_value; + sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,start,end); + continue; + } + + MangosStringLocale& data = mMangosStringLocaleMap[entry]; + + if(data.Content.size() > 0) + { + sLog.outErrorDb("Table `%s` contain data for already loaded entry %i (from another table?), ignored.",table,entry); + continue; + } + + data.Content.resize(1); + ++count; + + // 0 -> default, idx in to idx+1 + data.Content[0] = fields[1].GetCppString(); + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[i+1].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + // 0 -> default, idx in to idx+1 + if(data.Content.size() <= idx+1) + data.Content.resize(idx+2); + + data.Content[idx+1] = str; + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + if(min_value > 0) // internal mangos strings + sLog.outString( ">> Loaded %u MaNGOS strings from table %s", count,table); + else + sLog.outString( ">> Loaded %u string templates from %s", count,table); + + return true; +} + +const char *ObjectMgr::GetMangosString(int32 entry, int locale_idx) const +{ + // locale_idx==-1 -> default, locale_idx >= 0 in to idx+1 + // Content[0] always exist if exist MangosStringLocale + if(MangosStringLocale const *msl = GetMangosStringLocale(entry)) + { + if(msl->Content.size() > locale_idx+1 && !msl->Content[locale_idx+1].empty()) + return msl->Content[locale_idx+1].c_str(); + else + return msl->Content[0].c_str(); + } + + if(entry > 0) + sLog.outErrorDb("Entry %i not found in `mangos_string` table.",entry); + else + sLog.outErrorDb("Mangos string entry %i not found in DB.",entry); + return ""; +} + +void ObjectMgr::LoadFishingBaseSkillLevel() +{ + mFishingBaseForArea.clear(); // for relaod case + + uint32 count = 0; + QueryResult *result = WorldDatabase.Query("SELECT entry,skill FROM skill_fishing_base_level"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `skill_fishing_base_level`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + uint32 entry = fields[0].GetUInt32(); + int32 skill = fields[1].GetInt32(); + + AreaTableEntry const* fArea = GetAreaEntryByAreaID(entry); + if(!fArea) + { + sLog.outErrorDb("AreaId %u defined in `skill_fishing_base_level` does not exist",entry); + continue; + } + + mFishingBaseForArea[entry] = skill; + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u areas for fishing base skill level", count ); +} + +// Searches for the same condition already in Conditions store +// Returns Id if found, else adds it to Conditions and returns Id +uint16 ObjectMgr::GetConditionId( ConditionType condition, uint32 value1, uint32 value2 ) +{ + PlayerCondition lc = PlayerCondition(condition, value1, value2); + for (uint16 i=0; i < mConditions.size(); ++i) + { + if (lc == mConditions[i]) + return i; + } + + mConditions.push_back(lc); + + if(mConditions.size() > 0xFFFF) + { + sLog.outError("Conditions store overflow! Current and later loaded conditions will ignored!"); + return 0; + } + + return mConditions.size() - 1; +} + +bool ObjectMgr::CheckDeclinedNames( std::wstring mainpart, DeclinedName const& names ) +{ + for(int i =0; i < MAX_DECLINED_NAME_CASES; ++i) + { + std::wstring wname; + if(!Utf8toWStr(names.name[i],wname)) + return false; + + if(mainpart!=GetMainPartOfName(wname,i+1)) + return false; + } + return true; +} + +const char* ObjectMgr::GetAreaTriggerScriptName(uint32 id) +{ + AreaTriggerScriptMap::const_iterator i = mAreaTriggerScripts.find(id); + if(i!= mAreaTriggerScripts.end()) + return i->second.c_str(); + return ""; +} + +// Checks if player meets the condition +bool PlayerCondition::Meets(Player const * player) const +{ + if( !player ) + return false; // player not present, return false + + switch (condition) + { + case CONDITION_NONE: + return true; // empty condition, always met + case CONDITION_AURA: + return player->HasAura(value1, value2); + case CONDITION_ITEM: + return player->HasItemCount(value1, value2); + case CONDITION_ITEM_EQUIPPED: + return player->GetItemOrItemWithGemEquipped(value1) != NULL; + case CONDITION_ZONEID: + return player->GetZoneId() == value1; + case CONDITION_REPUTATION_RANK: + { + FactionEntry const* faction = sFactionStore.LookupEntry(value1); + return faction && player->GetReputationRank(faction) >= value2; + } + case CONDITION_TEAM: + return player->GetTeam() == value1; + case CONDITION_SKILL: + return player->HasSkill(value1) && player->GetBaseSkillValue(value1) >= value2; + case CONDITION_QUESTREWARDED: + return player->GetQuestRewardStatus(value1); + case CONDITION_QUESTTAKEN: + { + QuestStatus status = player->GetQuestStatus(value1); + return (status == QUEST_STATUS_INCOMPLETE); + } + case CONDITION_AD_COMMISSION_AURA: + { + Unit::AuraMap const& auras = player->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580) + return true; + return false; + } + default: + return false; + } +} + +// Verification of condition values validity +bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 value2) +{ + if( condition >= MAX_CONDITION) // Wrong condition type + { + sLog.outErrorDb("Condition has bad type of %u, skipped ", condition ); + return false; + } + + switch (condition) + { + case CONDITION_AURA: + { + if(!sSpellStore.LookupEntry(value1)) + { + sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1); + return false; + } + if(value2 > 2) + { + sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2); + return false; + } + break; + } + case CONDITION_ITEM: + { + ItemPrototype const *proto = objmgr.GetItemPrototype(value1); + if(!proto) + { + sLog.outErrorDb("Item condition requires to have non existing item (%u), skipped", value1); + return false; + } + break; + } + case CONDITION_ITEM_EQUIPPED: + { + ItemPrototype const *proto = objmgr.GetItemPrototype(value1); + if(!proto) + { + sLog.outErrorDb("ItemEquipped condition requires to have non existing item (%u) equipped, skipped", value1); + return false; + } + break; + } + case CONDITION_ZONEID: + { + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(value1); + if(!areaEntry) + { + sLog.outErrorDb("Zone condition requires to be in non existing area (%u), skipped", value1); + return false; + } + if(areaEntry->zone != 0) + { + sLog.outErrorDb("Zone condition requires to be in area (%u) which is a subzone but zone expected, skipped", value1); + return false; + } + break; + } + case CONDITION_REPUTATION_RANK: + { + FactionEntry const* factionEntry = sFactionStore.LookupEntry(value1); + if(!factionEntry) + { + sLog.outErrorDb("Reputation condition requires to have reputation non existing faction (%u), skipped", value1); + return false; + } + break; + } + case CONDITION_TEAM: + { + if (value1 != ALLIANCE && value1 != HORDE) + { + sLog.outErrorDb("Team condition specifies unknown team (%u), skipped", value1); + return false; + } + break; + } + case CONDITION_SKILL: + { + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(value1); + if (!pSkill) + { + sLog.outErrorDb("Skill condition specifies non-existing skill (%u), skipped", value1); + return false; + } + if (value2 < 1 || value2 > sWorld.GetConfigMaxSkillValue() ) + { + sLog.outErrorDb("Skill condition specifies invalid skill value (%u), skipped", value2); + return false; + } + break; + } + case CONDITION_QUESTREWARDED: + case CONDITION_QUESTTAKEN: + { + Quest const *Quest = objmgr.GetQuestTemplate(value1); + if (!Quest) + { + sLog.outErrorDb("Quest condition specifies non-existing quest (%u), skipped", value1); + return false; + } + if(value2) + sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2); + break; + } + case CONDITION_AD_COMMISSION_AURA: + { + if(value1) + sLog.outErrorDb("Quest condition has useless data in value1 (%u)!", value1); + if(value2) + sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2); + break; + } + } + return true; +} + +SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial) +{ + switch(pSkill->categoryId) + { + case SKILL_CATEGORY_LANGUAGES: return SKILL_RANGE_LANGUAGE; + case SKILL_CATEGORY_WEAPON: + if(pSkill->id!=SKILL_FIST_WEAPONS) + return SKILL_RANGE_LEVEL; + else + return SKILL_RANGE_MONO; + case SKILL_CATEGORY_ARMOR: + case SKILL_CATEGORY_CLASS: + if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING) + return SKILL_RANGE_MONO; + else + return SKILL_RANGE_LEVEL; + case SKILL_CATEGORY_SECONDARY: + case SKILL_CATEGORY_PROFESSION: + // not set skills for professions and racial abilities + if(IsProfessionSkill(pSkill->id)) + return SKILL_RANGE_RANK; + else if(racial) + return SKILL_RANGE_NONE; + else + return SKILL_RANGE_MONO; + default: + case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc + case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND) + return SKILL_RANGE_NONE; + } +} + +void ObjectMgr::LoadGameTele() +{ + m_GameTeleMap.clear(); // for relaod case + + uint32 count = 0; + QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `game_tele`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + + GameTele gt; + + gt.position_x = fields[1].GetFloat(); + gt.position_y = fields[2].GetFloat(); + gt.position_z = fields[3].GetFloat(); + gt.orientation = fields[4].GetFloat(); + gt.mapId = fields[5].GetUInt32(); + gt.name = fields[6].GetCppString(); + + if(!MapManager::IsValidMapCoord(gt.mapId,gt.position_x,gt.position_y,gt.position_z,gt.orientation)) + { + sLog.outErrorDb("Wrong position for id %u (name: %s) in `game_tele` table, ignoring.",id,gt.name.c_str()); + continue; + } + + if(!Utf8toWStr(gt.name,gt.wnameLow)) + { + sLog.outErrorDb("Wrong UTF8 name for id %u in `game_tele` table, ignoring.",id); + continue; + } + + wstrToLower( gt.wnameLow ); + + m_GameTeleMap[id] = gt; + + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u game tele's", count ); +} + +GameTele const* ObjectMgr::GetGameTele(std::string name) const +{ + // explicit name case + std::wstring wname; + if(!Utf8toWStr(name,wname)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wname ); + + for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr) + if(itr->second.wnameLow == wname) + return &itr->second; + + return NULL; +} + +bool ObjectMgr::AddGameTele(GameTele& tele) +{ + // find max id + uint32 new_id = 0; + for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr) + if(itr->first > new_id) + new_id = itr->first; + + // use next + ++new_id; + + if(!Utf8toWStr(tele.name,tele.wnameLow)) + return false; + + wstrToLower( tele.wnameLow ); + + m_GameTeleMap[new_id] = tele; + + return WorldDatabase.PExecuteLog("INSERT INTO game_tele (id,position_x,position_y,position_z,orientation,map,name) VALUES (%u,%f,%f,%f,%f,%d,'%s')", + new_id,tele.position_x,tele.position_y,tele.position_z,tele.orientation,tele.mapId,tele.name.c_str()); +} + +bool ObjectMgr::DeleteGameTele(std::string name) +{ + // explicit name case + std::wstring wname; + if(!Utf8toWStr(name,wname)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wname ); + + for(GameTeleMap::iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr) + { + if(itr->second.wnameLow == wname) + { + WorldDatabase.PExecuteLog("DELETE FROM game_tele WHERE name = '%s'",itr->second.name.c_str()); + m_GameTeleMap.erase(itr); + return true; + } + } + + return false; +} + +void ObjectMgr::LoadTrainerSpell() +{ + // For reload case + for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr) + itr->second.Clear(); + m_mCacheTrainerSpellMap.clear(); + + std::set skip_trainers; + + QueryResult *result = WorldDatabase.PQuery("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `npc_trainer`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + uint32 count = 0; + do + { + bar.step(); + + Field* fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + uint32 spell = fields[1].GetUInt32(); + + CreatureInfo const* cInfo = GetCreatureTemplate(entry); + + if(!cInfo) + { + sLog.outErrorDb("Table `npc_trainer` have entry for not existed creature template (Entry: %u), ignore", entry); + continue; + } + + if(!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER)) + { + if(skip_trainers.count(entry) == 0) + { + sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry); + skip_trainers.insert(entry); + } + continue; + } + + SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell); + if(!spellinfo) + { + sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u ) has non existing spell %u, ignore", entry,spell); + continue; + } + + if(!SpellMgr::IsSpellValid(spellinfo)) + { + sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u) has broken learning spell %u, ignore", entry, spell); + continue; + } + + TrainerSpell* pTrainerSpell = new TrainerSpell(); + pTrainerSpell->spell = spell; + pTrainerSpell->spellcost = fields[2].GetUInt32(); + pTrainerSpell->reqskill = fields[3].GetUInt32(); + pTrainerSpell->reqskillvalue = fields[4].GetUInt32(); + pTrainerSpell->reqlevel = fields[5].GetUInt32(); + + if(!pTrainerSpell->reqlevel) + pTrainerSpell->reqlevel = spellinfo->spellLevel; + + + TrainerSpellData& data = m_mCacheTrainerSpellMap[entry]; + + if(SpellMgr::IsProfessionSpell(spell)) + data.trainerType = 2; + + data.spellList.push_back(pTrainerSpell); + ++count; + + } while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded Trainers %d", count ); +} + +void ObjectMgr::LoadVendors() +{ + // For reload case + for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) + itr->second.Clear(); + m_mCacheVendorItemMap.clear(); + + std::set skip_vendors; + + QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor"); + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `npc_vendor`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + uint32 count = 0; + do + { + bar.step(); + Field* fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + uint32 item_id = fields[1].GetUInt32(); + uint32 maxcount = fields[2].GetUInt32(); + uint32 incrtime = fields[3].GetUInt32(); + uint32 ExtendedCost = fields[4].GetUInt32(); + + if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors)) + continue; + + VendorItemData& vList = m_mCacheVendorItemMap[entry]; + + vList.AddItem(item_id,maxcount,incrtime,ExtendedCost); + ++count; + + } while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %d Vendors ", count ); +} + +void ObjectMgr::LoadNpcTextId() +{ + + m_mCacheNpcTextIdMap.clear(); + + QueryResult* result = WorldDatabase.PQuery("SELECT npc_guid, textid FROM npc_gossip"); + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `npc_gossip`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + uint32 count = 0; + uint32 guid,textid; + do + { + bar.step(); + + Field* fields = result->Fetch(); + + guid = fields[0].GetUInt32(); + textid = fields[1].GetUInt32(); + + if (!GetCreatureData(guid)) + { + sLog.outErrorDb("Table `npc_gossip` have not existed creature (GUID: %u) entry, ignore. ",guid); + continue; + } + if (!GetGossipText(textid)) + { + sLog.outErrorDb("Table `npc_gossip` for creature (GUID: %u) have wrong Textid (%u), ignore. ", guid, textid); + continue; + } + + m_mCacheNpcTextIdMap[guid] = textid ; + ++count; + + } while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %d NpcTextId ", count ); +} + +void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost ) +{ + VendorItemData& vList = m_mCacheVendorItemMap[entry]; + vList.AddItem(item,maxcount,incrtime,extendedcost); + + WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost); +} + +bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item ) +{ + CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry); + if(iter == m_mCacheVendorItemMap.end()) + return false; + + if(!iter->second.FindItem(item)) + return false; + + iter->second.RemoveItem(item); + WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item); + return true; +} + +bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set* skip_vendors ) const +{ + CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry); + if(!cInfo) + { + if(pl) + ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); + else + sLog.outErrorDb("Table `npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry); + return false; + } + + if(!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR)) + { + if(!skip_vendors || skip_vendors->count(vendor_entry)==0) + { + if(pl) + ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); + else + sLog.outErrorDb("Table `npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry); + + if(skip_vendors) + skip_vendors->insert(vendor_entry); + } + return false; + } + + if(!GetItemPrototype(item_id)) + { + if(pl) + ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id); + else + sLog.outErrorDb("Table `npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id); + return false; + } + + if(ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) + { + if(pl) + ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost); + else + sLog.outErrorDb("Table `npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry); + return false; + } + + if(maxcount > 0 && incrtime == 0) + { + if(pl) + ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount); + else + sLog.outErrorDb( "Table `npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry); + return false; + } + else if(maxcount==0 && incrtime > 0) + { + if(pl) + ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0"); + else + sLog.outErrorDb( "Table `npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry); + return false; + } + + VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry); + if(!vItems) + return true; // later checks for non-empty lists + + if(vItems->FindItem(item_id)) + { + if(pl) + ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,item_id); + else + sLog.outErrorDb( "Table `npc_vendor` has duplicate items %u for vendor (Entry: %u), ignore", item_id, vendor_entry); + return false; + } + + if(vItems->GetItemCount() >= MAX_VENDOR_ITEMS) + { + if(pl) + ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS); + else + sLog.outErrorDb( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", vItems->GetItemCount(), MAX_VENDOR_ITEMS, vendor_entry); + return false; + } + + return true; +} + +// Functions for scripting access +const char* GetAreaTriggerScriptNameById(uint32 id) +{ + return objmgr.GetAreaTriggerScriptName(id); +} + +bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value) +{ + if(start_value >= 0 || start_value <= end_value) // start/end reversed for negative values + { + sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), use (%d - %d) instead.",table,start_value,end_value,-1,std::numeric_limits::min()); + start_value = -1; + end_value = std::numeric_limits::min(); + } + + // for scripting localized strings allowed use _only_ negative entries + return objmgr.LoadMangosStrings(db,table,end_value,start_value); +} diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h new file mode 100644 index 000000000..fbb41cf5d --- /dev/null +++ b/src/game/ObjectMgr.h @@ -0,0 +1,862 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _OBJECTMGR_H +#define _OBJECTMGR_H + +#include "Log.h" +#include "Object.h" +#include "Bag.h" +#include "Creature.h" +#include "Player.h" +#include "DynamicObject.h" +#include "GameObject.h" +#include "Corpse.h" +#include "QuestDef.h" +#include "Path.h" +#include "ItemPrototype.h" +#include "NPCHandler.h" +#include "Database/DatabaseEnv.h" +#include "AuctionHouseObject.h" +#include "Mail.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "ObjectDefines.h" +#include "Policies/Singleton.h" +#include "Database/SQLStorage.h" + +#include +#include +#include + +extern SQLStorage sCreatureStorage; +extern SQLStorage sCreatureDataAddonStorage; +extern SQLStorage sCreatureInfoAddonStorage; +extern SQLStorage sCreatureModelStorage; +extern SQLStorage sEquipmentStorage; +extern SQLStorage sGOStorage; +extern SQLStorage sPageTextStore; +extern SQLStorage sItemStorage; +extern SQLStorage sInstanceTemplate; + +class Group; +class Guild; +class ArenaTeam; +class Path; +class TransportPath; +class Item; + +struct GameTele +{ + float position_x; + float position_y; + float position_z; + float orientation; + uint32 mapId; + std::string name; + std::wstring wnameLow; +}; + +typedef HM_NAMESPACE::hash_map GameTeleMap; + +struct ScriptInfo +{ + uint32 id; + uint32 delay; + uint32 command; + uint32 datalong; + uint32 datalong2; + std::string datatext; + float x; + float y; + float z; + float o; +}; + +typedef std::multimap ScriptMap; +typedef std::map ScriptMapMap; +extern ScriptMapMap sQuestEndScripts; +extern ScriptMapMap sQuestStartScripts; +extern ScriptMapMap sSpellScripts; +extern ScriptMapMap sGameObjectScripts; +extern ScriptMapMap sEventScripts; + +struct AreaTrigger +{ + uint8 requiredLevel; + uint32 requiredItem; + uint32 requiredItem2; + uint32 heroicKey; + uint32 heroicKey2; + uint32 requiredQuest; + std::string requiredFailedText; + uint32 target_mapId; + float target_X; + float target_Y; + float target_Z; + float target_Orientation; +}; + +typedef std::set CellGuidSet; +typedef std::map CellCorpseSet; +struct CellObjectGuids +{ + CellGuidSet creatures; + CellGuidSet gameobjects; + CellCorpseSet corpses; +}; +typedef HM_NAMESPACE::hash_map CellObjectGuidsMap; +typedef HM_NAMESPACE::hash_map MapObjectGuids; + +typedef HM_NAMESPACE::hash_map RespawnTimes; + +struct MangosStringLocale +{ + std::vector Content; // 0 -> default, i -> i-1 locale index +}; + +typedef HM_NAMESPACE::hash_map CreatureDataMap; +typedef HM_NAMESPACE::hash_map GameObjectDataMap; +typedef HM_NAMESPACE::hash_map CreatureLocaleMap; +typedef HM_NAMESPACE::hash_map GameObjectLocaleMap; +typedef HM_NAMESPACE::hash_map ItemLocaleMap; +typedef HM_NAMESPACE::hash_map QuestLocaleMap; +typedef HM_NAMESPACE::hash_map NpcTextLocaleMap; +typedef HM_NAMESPACE::hash_map PageTextLocaleMap; +typedef HM_NAMESPACE::hash_map MangosStringLocaleMap; + +typedef std::multimap QuestRelations; + +struct PetLevelInfo +{ + PetLevelInfo() : health(0), mana(0) { for(int i=0; i < MAX_STATS; ++i ) stats[i] = 0; } + + uint16 stats[MAX_STATS]; + uint16 health; + uint16 mana; + uint16 armor; +}; + +struct ReputationOnKillEntry +{ + uint32 repfaction1; + uint32 repfaction2; + bool is_teamaward1; + uint32 reputation_max_cap1; + int32 repvalue1; + bool is_teamaward2; + uint32 reputation_max_cap2; + int32 repvalue2; + bool team_dependent; +}; + +struct PetCreateSpellEntry +{ + uint32 spellid[4]; +}; + +#define WEATHER_SEASONS 4 +struct WeatherSeasonChances +{ + uint32 rainChance; + uint32 snowChance; + uint32 stormChance; +}; + +struct WeatherZoneChances +{ + WeatherSeasonChances data[WEATHER_SEASONS]; +}; + +struct GraveYardData +{ + uint32 safeLocId; + uint32 team; +}; +typedef std::multimap GraveYardMap; + +enum ConditionType +{ // value1 value2 for the Condition enumed + CONDITION_NONE = 0, // 0 0 + CONDITION_AURA = 1, // spell_id effindex + CONDITION_ITEM = 2, // item_id count + CONDITION_ITEM_EQUIPPED = 3, // item_id 0 + CONDITION_ZONEID = 4, // zone_id 0 + CONDITION_REPUTATION_RANK = 5, // faction_id min_rank + CONDITION_TEAM = 6, // player_team 0, (469 - Alliance 67 - Horde) + CONDITION_SKILL = 7, // skill_id skill_value + CONDITION_QUESTREWARDED = 8, // quest_id 0 + CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active. + CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD ñommission aura active +}; + +#define MAX_CONDITION 11 // maximum value in ConditionType enum + +struct PlayerCondition +{ + ConditionType condition; // additional condition type + uint32 value1; // data for the condition - see ConditionType definition + uint32 value2; + + PlayerCondition(uint8 _condition = 0, uint32 _value1 = 0, uint32 _value2 = 0) + : condition(ConditionType(_condition)), value1(_value1), value2(_value2) {} + + static bool IsValid(ConditionType condition, uint32 value1, uint32 value2); + // Checks correctness of values + bool Meets(Player const * APlayer) const; // Checks if the player meets the condition + bool operator == (PlayerCondition const& lc) const + { + return (lc.condition == condition && lc.value1 == value1 && lc.value2 == value2); + } +}; + +// NPC gossip text id +typedef HM_NAMESPACE::hash_map CacheNpcTextIdMap; + +typedef HM_NAMESPACE::hash_map CacheVendorItemMap; +typedef HM_NAMESPACE::hash_map CacheTrainerSpellMap; + +enum SkillRangeType +{ + SKILL_RANGE_LANGUAGE, // 300..300 + SKILL_RANGE_LEVEL, // 1..max skill for level + SKILL_RANGE_MONO, // 1..1, grey monolite bar + SKILL_RANGE_RANK, // 1..skill for known rank + SKILL_RANGE_NONE, // 0..0 always +}; + +SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial); + +#define MAX_PLAYER_NAME 12 // max allowed by client name length +#define MAX_INTERNAL_PLAYER_NAME 15 // max server internal player name length ( > MAX_PLAYER_NAME for support declined names ) + +bool normalizePlayerName(std::string& name); + +struct MANGOS_DLL_SPEC LanguageDesc +{ + Language lang_id; + uint32 spell_id; + uint32 skill_id; +}; + +extern LanguageDesc lang_description[LANGUAGES_COUNT]; +MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang); + +class PlayerDumpReader; + +class ObjectMgr +{ + friend class PlayerDumpReader; + + public: + ObjectMgr(); + ~ObjectMgr(); + + typedef HM_NAMESPACE::hash_map ItemMap; + + typedef std::set< Group * > GroupSet; + typedef std::set< Guild * > GuildSet; + typedef std::set< ArenaTeam * > ArenaTeamSet; + + typedef HM_NAMESPACE::hash_map QuestMap; + + typedef HM_NAMESPACE::hash_map AreaTriggerMap; + + typedef HM_NAMESPACE::hash_map AreaTriggerScriptMap; + + typedef HM_NAMESPACE::hash_map RepOnKillMap; + + typedef HM_NAMESPACE::hash_map WeatherZoneMap; + + typedef HM_NAMESPACE::hash_map PetCreateSpellMap; + + Player* GetPlayer(const char* name) const { return ObjectAccessor::Instance().FindPlayerByName(name);} + Player* GetPlayer(uint64 guid) const { return ObjectAccessor::FindPlayer(guid); } + + static GameObjectInfo const *GetGameObjectInfo(uint32 id) { return sGOStorage.LookupEntry(id); } + + void LoadGameobjectInfo(); + void AddGameobjectInfo(GameObjectInfo *goinfo); + + Group * GetGroupByLeader(const uint64 &guid) const; + void AddGroup(Group* group) { mGroupSet.insert( group ); } + void RemoveGroup(Group* group) { mGroupSet.erase( group ); } + + Guild* GetGuildByLeader(uint64 const&guid) const; + Guild* GetGuildById(const uint32 GuildId) const; + Guild* GetGuildByName(std::string guildname) const; + std::string GetGuildNameById(const uint32 GuildId) const; + void AddGuild(Guild* guild) { mGuildSet.insert( guild ); } + void RemoveGuild(Guild* guild) { mGuildSet.erase( guild ); } + + ArenaTeam* GetArenaTeamById(const uint32 ArenaTeamId) const; + ArenaTeam* GetArenaTeamByName(std::string ArenaTeamName) const; + ArenaTeam* GetArenaTeamByCapitan(uint64 const& guid) const; + void AddArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.insert( arenateam ); } + void RemoveArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.erase( arenateam ); } + + static CreatureInfo const *GetCreatureTemplate( uint32 id ); + CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid ); + CreatureModelInfo const* GetCreatureModelRandomGender(uint32 display_id); + uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data = NULL); + EquipmentInfo const *GetEquipmentInfo( uint32 entry ); + static CreatureDataAddon const *GetCreatureAddon( uint32 lowguid ) + { + return sCreatureDataAddonStorage.LookupEntry(lowguid); + } + + static CreatureDataAddon const *GetCreatureTemplateAddon( uint32 entry ) + { + return sCreatureInfoAddonStorage.LookupEntry(entry); + } + + static ItemPrototype const* GetItemPrototype(uint32 id) { return sItemStorage.LookupEntry(id); } + + static InstanceTemplate const* GetInstanceTemplate(uint32 map) + { + return sInstanceTemplate.LookupEntry(map); + } + + Item* GetAItem(uint32 id) + { + ItemMap::const_iterator itr = mAitems.find(id); + if (itr != mAitems.end()) + { + return itr->second; + } + return NULL; + } + void AddAItem(Item* it) + { + ASSERT( it ); + ASSERT( mAitems.find(it->GetGUIDLow()) == mAitems.end()); + mAitems[it->GetGUIDLow()] = it; + } + bool RemoveAItem(uint32 id) + { + ItemMap::iterator i = mAitems.find(id); + if (i == mAitems.end()) + { + return false; + } + mAitems.erase(i); + return true; + } + AuctionHouseObject * GetAuctionsMap( uint32 location ); + + //auction messages + void SendAuctionWonMail( AuctionEntry * auction ); + void SendAuctionSalePendingMail( AuctionEntry * auction ); + void SendAuctionSuccessfulMail( AuctionEntry * auction ); + void SendAuctionExpiredMail( AuctionEntry * auction ); + static uint32 GetAuctionCut( uint32 location, uint32 highBid ); + static uint32 GetAuctionDeposit(uint32 location, uint32 time, Item *pItem); + static uint32 GetAuctionOutBid(uint32 currentBid); + + PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const; + + PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const + { + if(class_ >= MAX_CLASSES) return NULL; + return &playerClassInfo[class_]; + } + void GetPlayerClassLevelInfo(uint32 class_,uint32 level, PlayerClassLevelInfo* info) const; + + PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const + { + if(race >= MAX_RACES) return NULL; + if(class_ >= MAX_CLASSES) return NULL; + PlayerInfo const* info = &playerInfo[race][class_]; + if(info->displayId_m==0 || info->displayId_f==0) return NULL; + return info; + } + void GetPlayerLevelInfo(uint32 race, uint32 class_,uint32 level, PlayerLevelInfo* info) const; + + uint64 GetPlayerGUIDByName(std::string name) const; + bool GetPlayerNameByGUID(const uint64 &guid, std::string &name) const; + uint32 GetPlayerTeamByGUID(const uint64 &guid) const; + uint32 GetPlayerAccountIdByGUID(const uint64 &guid) const; + uint32 GetSecurityByAccount(uint32 acc_id) const; + bool GetAccountNameByAccount(uint32 acc_id, std::string &name) const; + uint32 GetAccountByAccountName(std::string name) const; + + uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid ); + void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost); + uint16 GetTaxiMount( uint32 id, uint32 team ); + void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector& mapIds ); + void GetTransportPathNodes( uint32 path, TransportPath &pathnodes ); + + Quest const* GetQuestTemplate(uint32 quest_id) const + { + QuestMap::const_iterator itr = mQuestTemplates.find(quest_id); + return itr != mQuestTemplates.end() ? itr->second : NULL; + } + QuestMap const& GetQuestTemplates() const { return mQuestTemplates; } + + uint32 GetQuestForAreaTrigger(uint32 Trigger_ID) const + { + QuestAreaTriggerMap::const_iterator itr = mQuestAreaTriggerMap.find(Trigger_ID); + if(itr != mQuestAreaTriggerMap.end()) + return itr->second; + return 0; + } + bool IsTavernAreaTrigger(uint32 Trigger_ID) const { return mTavernAreaTriggerSet.count(Trigger_ID) != 0; } + bool IsGameObjectForQuests(uint32 entry) const { return mGameObjectForQuestSet.count(entry) != 0; } + bool IsGuildVaultGameObject(Player *player, uint64 guid) const + { + if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid)) + if(go->GetGoType() == GAMEOBJECT_TYPE_GUILD_BANK) + return true; + return false; + } + + uint32 GetBattleMasterBG(uint32 entry) const + { + BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry); + if(itr != mBattleMastersMap.end()) + return itr->second; + return 2; //BATTLEGROUND_WS - i will not add include only for constant usage! + } + + void AddGossipText(GossipText *pGText); + GossipText *GetGossipText(uint32 Text_ID); + + WorldSafeLocsEntry const *GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team); + bool AddGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = true); + void LoadGraveyardZones(); + GraveYardData const* FindGraveYardData(uint32 id, uint32 zone); + + AreaTrigger const* GetAreaTrigger(uint32 trigger) const + { + AreaTriggerMap::const_iterator itr = mAreaTriggers.find( trigger ); + if( itr != mAreaTriggers.end( ) ) + return &itr->second; + return NULL; + } + + AreaTrigger const* GetGoBackTrigger(uint32 Map) const; + + const char* GetAreaTriggerScriptName(uint32 id); + + ReputationOnKillEntry const* GetReputationOnKilEntry(uint32 id) const + { + RepOnKillMap::const_iterator itr = mRepOnKill.find(id); + if(itr != mRepOnKill.end()) + return &itr->second; + return NULL; + } + + PetCreateSpellEntry const* GetPetCreateSpellEntry(uint32 id) const + { + PetCreateSpellMap::const_iterator itr = mPetCreateSpell.find(id); + if(itr != mPetCreateSpell.end()) + return &itr->second; + return NULL; + } + + void LoadGuilds(); + void LoadArenaTeams(); + void LoadGroups(); + void LoadQuests(); + void LoadQuestRelations() + { + LoadGameobjectQuestRelations(); + LoadGameobjectInvolvedRelations(); + LoadCreatureQuestRelations(); + LoadCreatureInvolvedRelations(); + } + void LoadGameobjectQuestRelations(); + void LoadGameobjectInvolvedRelations(); + void LoadCreatureQuestRelations(); + void LoadCreatureInvolvedRelations(); + + QuestRelations mGOQuestRelations; + QuestRelations mGOQuestInvolvedRelations; + QuestRelations mCreatureQuestRelations; + QuestRelations mCreatureQuestInvolvedRelations; + + void LoadGameObjectScripts(); + void LoadQuestEndScripts(); + void LoadQuestStartScripts(); + void LoadEventScripts(); + void LoadSpellScripts(); + + bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); + bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase,"mangos_string",1,std::numeric_limits::max()); } + void LoadPetCreateSpells(); + void LoadCreatureLocales(); + void LoadCreatureTemplates(); + void LoadCreatures(); + void LoadCreatureRespawnTimes(); + void LoadCreatureAddons(); + void LoadCreatureModelInfo(); + void LoadEquipmentTemplates(); + void LoadGameObjectLocales(); + void LoadGameobjects(); + void LoadGameobjectRespawnTimes(); + void LoadItemPrototypes(); + void LoadItemLocales(); + void LoadQuestLocales(); + void LoadNpcTextLocales(); + void LoadPageTextLocales(); + void LoadInstanceTemplate(); + + void LoadGossipText(); + + void LoadAreaTriggerTeleports(); + void LoadQuestAreaTriggers(); + void LoadAreaTriggerScripts(); + void LoadTavernAreaTriggers(); + void LoadBattleMastersEntry(); + void LoadGameObjectForQuests(); + + void LoadItemTexts(); + void LoadPageTexts(); + + //load first auction items, because of check if item exists, when loading + void LoadAuctionItems(); + void LoadAuctions(); + void LoadPlayerInfo(); + void LoadPetLevelInfo(); + void LoadExplorationBaseXP(); + void LoadPetNames(); + void LoadPetNumber(); + void LoadCorpses(); + void LoadFishingBaseSkillLevel(); + + void LoadReputationOnKill(); + + void LoadWeatherZoneChances(); + void LoadGameTele(); + + void LoadNpcTextId(); + void LoadVendors(); + void LoadTrainerSpell(); + + std::string GeneratePetName(uint32 entry); + uint32 GetBaseXP(uint32 level); + + int32 GetFishingBaseSkillLevel(uint32 entry) const + { + FishingBaseSkillMap::const_iterator itr = mFishingBaseForArea.find(entry); + return itr != mFishingBaseForArea.end() ? itr->second : 0; + } + + void ReturnOrDeleteOldMails(bool serverUp); + + void SetHighestGuids(); + uint32 GenerateLowGuid(HighGuid guidhigh); + uint32 GenerateAuctionID(); + uint32 GenerateMailID(); + uint32 GenerateItemTextID(); + uint32 GeneratePetNumber(); + + uint32 CreateItemText(std::string text); + std::string GetItemText( uint32 id ) + { + ItemTextMap::const_iterator itr = mItemTexts.find( id ); + if ( itr != mItemTexts.end() ) + return itr->second; + else + return "There is no info for this item"; + } + + typedef std::multimap ExclusiveQuestGroups; + ExclusiveQuestGroups mExclusiveQuestGroups; + + WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const + { + WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id); + if(itr != mWeatherZoneMap.end()) + return &itr->second; + else + return NULL; + } + + CellObjectGuids const& GetCellObjectGuids(uint16 mapid, uint8 spawnMode, uint32 cell_id) + { + return mMapObjectGuids[MAKE_PAIR32(mapid,spawnMode)][cell_id]; + } + + CreatureData const* GetCreatureData(uint32 guid) const + { + CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid); + if(itr==mCreatureDataMap.end()) return NULL; + return &itr->second; + } + CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; } + void DeleteCreatureData(uint32 guid); + CreatureLocale const* GetCreatureLocale(uint32 entry) const + { + CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry); + if(itr==mCreatureLocaleMap.end()) return NULL; + return &itr->second; + } + GameObjectLocale const* GetGameObjectLocale(uint32 entry) const + { + GameObjectLocaleMap::const_iterator itr = mGameObjectLocaleMap.find(entry); + if(itr==mGameObjectLocaleMap.end()) return NULL; + return &itr->second; + } + ItemLocale const* GetItemLocale(uint32 entry) const + { + ItemLocaleMap::const_iterator itr = mItemLocaleMap.find(entry); + if(itr==mItemLocaleMap.end()) return NULL; + return &itr->second; + } + QuestLocale const* GetQuestLocale(uint32 entry) const + { + QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry); + if(itr==mQuestLocaleMap.end()) return NULL; + return &itr->second; + } + NpcTextLocale const* GetNpcTextLocale(uint32 entry) const + { + NpcTextLocaleMap::const_iterator itr = mNpcTextLocaleMap.find(entry); + if(itr==mNpcTextLocaleMap.end()) return NULL; + return &itr->second; + } + PageTextLocale const* GetPageTextLocale(uint32 entry) const + { + PageTextLocaleMap::const_iterator itr = mPageTextLocaleMap.find(entry); + if(itr==mPageTextLocaleMap.end()) return NULL; + return &itr->second; + } + + GameObjectData const* GetGOData(uint32 guid) const + { + GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid); + if(itr==mGameObjectDataMap.end()) return NULL; + return &itr->second; + } + GameObjectData& NewGOData(uint32 guid) { return mGameObjectDataMap[guid]; } + void DeleteGOData(uint32 guid); + + MangosStringLocale const* GetMangosStringLocale(int32 entry) const + { + MangosStringLocaleMap::const_iterator itr = mMangosStringLocaleMap.find(entry); + if(itr==mMangosStringLocaleMap.end()) return NULL; + return &itr->second; + } + const char *GetMangosString(int32 entry, int locale_idx) const; + const char *GetMangosStringForDBCLocale(int32 entry) const { return GetMangosString(entry,DBCLocaleIndex); } + void SetDBCLocaleIndex(uint32 lang) { DBCLocaleIndex = GetIndexForLocale(LocaleConstant(lang)); } + + void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance); + void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid); + + time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance) { return mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)]; } + void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t); + time_t GetGORespawnTime(uint32 loguid, uint32 instance) { return mGORespawnTimes[MAKE_PAIR64(loguid,instance)]; } + void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t); + void DeleteRespawnTimeForInstance(uint32 instance); + + // grid objects + void AddCreatureToGrid(uint32 guid, CreatureData const* data); + void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data); + void AddGameobjectToGrid(uint32 guid, GameObjectData const* data); + void RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data); + + // reserved names + void LoadReservedPlayersNames(); + bool IsReservedName(std::string name) const + { + return m_ReservedNames.find(name) != m_ReservedNames.end(); + } + + // name with valid structure and symbols + static bool IsValidName( std::string name, bool create = false ); + static bool IsValidCharterName( std::string name ); + static bool IsValidPetName( std::string name ); + + static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names); + + int GetIndexForLocale(LocaleConstant loc); + LocaleConstant GetLocaleForIndex(int i); + // guild bank tabs + const uint32 GetGuildBankTabPrice(uint8 Index) { return Index < GUILD_BANK_MAX_TABS ? mGuildBankTabPrice[Index] : 0; } + + uint16 GetConditionId(ConditionType condition, uint32 value1, uint32 value2); + bool IsPlayerMeetToCondition(Player const* player, uint16 condition_id) const + { + if(condition_id >= mConditions.size()) + return false; + + return mConditions[condition_id].Meets(player); + } + + GameTele const* GetGameTele(uint32 id) const + { + GameTeleMap::const_iterator itr = m_GameTeleMap.find(id); + if(itr==m_GameTeleMap.end()) return NULL; + return &itr->second; + } + GameTele const* GetGameTele(std::string name) const; + GameTeleMap const& GetGameTeleMap() const { return m_GameTeleMap; } + bool AddGameTele(GameTele& data); + bool DeleteGameTele(std::string name); + + uint32 GetNpcGossip(uint32 entry) const + { + CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry); + if(iter == m_mCacheNpcTextIdMap.end()) + return 0; + + return iter->second; + } + + TrainerSpellData const* GetNpcTrainerSpells(uint32 entry) const + { + CacheTrainerSpellMap::const_iterator iter = m_mCacheTrainerSpellMap.find(entry); + if(iter == m_mCacheTrainerSpellMap.end()) + return NULL; + + return &iter->second; + } + + VendorItemData const* GetNpcVendorItemList(uint32 entry) const + { + CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry); + if(iter == m_mCacheVendorItemMap.end()) + return NULL; + + return &iter->second; + } + void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost); + bool RemoveVendorItem(uint32 entry,uint32 item); + bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL ) const; + protected: + uint32 m_auctionid; + uint32 m_mailid; + uint32 m_ItemTextId; + + uint32 m_hiCharGuid; + uint32 m_hiCreatureGuid; + uint32 m_hiPetGuid; + uint32 m_hiItemGuid; + uint32 m_hiGoGuid; + uint32 m_hiDoGuid; + uint32 m_hiCorpseGuid; + + uint32 m_hiPetNumber; + + QuestMap mQuestTemplates; + + typedef HM_NAMESPACE::hash_map GossipTextMap; + typedef HM_NAMESPACE::hash_map QuestAreaTriggerMap; + typedef HM_NAMESPACE::hash_map BattleMastersMap; + typedef HM_NAMESPACE::hash_map ItemTextMap; + typedef std::set TavernAreaTriggerSet; + typedef std::set GameObjectForQuestSet; + + GroupSet mGroupSet; + GuildSet mGuildSet; + ArenaTeamSet mArenaTeamSet; + + ItemMap mItems; + ItemMap mAitems; + + ItemTextMap mItemTexts; + + AuctionHouseObject mHordeAuctions; + AuctionHouseObject mAllianceAuctions; + AuctionHouseObject mNeutralAuctions; + + QuestAreaTriggerMap mQuestAreaTriggerMap; + BattleMastersMap mBattleMastersMap; + TavernAreaTriggerSet mTavernAreaTriggerSet; + GameObjectForQuestSet mGameObjectForQuestSet; + GossipTextMap mGossipText; + AreaTriggerMap mAreaTriggers; + AreaTriggerScriptMap mAreaTriggerScripts; + + RepOnKillMap mRepOnKill; + + WeatherZoneMap mWeatherZoneMap; + + PetCreateSpellMap mPetCreateSpell; + + //character reserved names + typedef std::set ReservedNamesMap; + ReservedNamesMap m_ReservedNames; + + GraveYardMap mGraveYardMap; + + GameTeleMap m_GameTeleMap; + + typedef std::vector LocalForIndex; + LocalForIndex m_LocalForIndex; + int GetOrNewIndexForLocale(LocaleConstant loc); + + int DBCLocaleIndex; + private: + void LoadScripts(ScriptMapMap& scripts, char const* tablename); + void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); + void LoadQuestRelationsHelper(QuestRelations& map,char const* table); + + typedef std::map PetLevelInfoMap; + // PetLevelInfoMap[creature_id][level] + PetLevelInfoMap petInfo; // [creature_id][level] + + PlayerClassInfo playerClassInfo[MAX_CLASSES]; + + void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const; + PlayerInfo playerInfo[MAX_RACES][MAX_CLASSES]; + + typedef std::map BaseXPMap; // [area level][base xp] + BaseXPMap mBaseXPTable; + + typedef std::map FishingBaseSkillMap; // [areaId][base skill level] + FishingBaseSkillMap mFishingBaseForArea; + + typedef std::map > HalfNameMap; + HalfNameMap PetHalfName0; + HalfNameMap PetHalfName1; + + MapObjectGuids mMapObjectGuids; + CreatureDataMap mCreatureDataMap; + CreatureLocaleMap mCreatureLocaleMap; + GameObjectDataMap mGameObjectDataMap; + GameObjectLocaleMap mGameObjectLocaleMap; + ItemLocaleMap mItemLocaleMap; + QuestLocaleMap mQuestLocaleMap; + NpcTextLocaleMap mNpcTextLocaleMap; + PageTextLocaleMap mPageTextLocaleMap; + MangosStringLocaleMap mMangosStringLocaleMap; + RespawnTimes mCreatureRespawnTimes; + RespawnTimes mGORespawnTimes; + + typedef std::vector GuildBankTabPriceMap; + GuildBankTabPriceMap mGuildBankTabPrice; + + // Storage for Conditions. First element (index 0) is reserved for zero-condition (nothing required) + typedef std::vector ConditionStore; + ConditionStore mConditions; + + CacheNpcTextIdMap m_mCacheNpcTextIdMap; + CacheVendorItemMap m_mCacheVendorItemMap; + CacheTrainerSpellMap m_mCacheTrainerSpellMap; +}; + +#define objmgr MaNGOS::Singleton::Instance() + +// scripting access functions +bool MANGOS_DLL_SPEC LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits::min()); +MANGOS_DLL_SPEC const char* GetAreaTriggerScriptNameById(uint32 id); + +#endif diff --git a/src/game/ObjectPosSelector.cpp b/src/game/ObjectPosSelector.cpp new file mode 100644 index 000000000..6855e21f8 --- /dev/null +++ b/src/game/ObjectPosSelector.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ObjectPosSelector.h" + +ObjectPosSelector::ObjectPosSelector(float x,float y,float size,float dist) +: m_center_x(x),m_center_y(y),m_size(size),m_dist(dist) +{ + m_anglestep = acos(m_dist/(m_dist+2*m_size)); + + m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].end(); + m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].end(); + + m_smallStepAngle[USED_POS_PLUS] = 0; + m_smallStepAngle[USED_POS_MINUS] = 0; + + m_smallStepOk[USED_POS_PLUS] = false; + m_smallStepOk[USED_POS_MINUS] = false; + + m_smallStepNextUsedPos[USED_POS_PLUS] = NULL; + m_smallStepNextUsedPos[USED_POS_MINUS] = NULL; +} + +ObjectPosSelector::UsedPosList::value_type const* ObjectPosSelector::nextUsedPos(UsedPosType uptype) +{ + UsedPosList::const_iterator itr = m_nextUsedPos[uptype]; + if(itr!=m_UsedPosLists[uptype].end()) + ++itr; + + if(itr==m_UsedPosLists[uptype].end()) + { + if(!m_UsedPosLists[~uptype].empty()) + return &*m_UsedPosLists[~uptype].rbegin(); + else + return NULL; + } + else + return &*itr; +} + +void ObjectPosSelector::AddUsedPos(float size,float angle,float dist) +{ + if(angle>=0) + m_UsedPosLists[USED_POS_PLUS].insert(UsedPosList::value_type(angle,UsedPos(1.0,size,dist))); + else + m_UsedPosLists[USED_POS_MINUS].insert(UsedPosList::value_type(-angle,UsedPos(-1.0,size,dist))); +} + +void ObjectPosSelector::InitializeAngle() +{ + m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].begin(); + m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].begin(); + + m_smallStepAngle[USED_POS_PLUS] = 0; + m_smallStepAngle[USED_POS_MINUS] = 0; + + m_smallStepOk[USED_POS_PLUS] = true; + m_smallStepOk[USED_POS_MINUS] = true; +} + +bool ObjectPosSelector::FirstAngle(float& angle) +{ + if(m_UsedPosLists[USED_POS_PLUS].empty() && !m_UsedPosLists[USED_POS_MINUS].empty() ) + return NextAngleFor(*m_UsedPosLists[USED_POS_MINUS].begin(),1.0,USED_POS_PLUS,angle); + else if(m_UsedPosLists[USED_POS_MINUS].empty() && !m_UsedPosLists[USED_POS_PLUS].empty() ) + return NextAngleFor(*m_UsedPosLists[USED_POS_PLUS].begin(),-1.0,USED_POS_MINUS,angle); + + return false; +} + +bool ObjectPosSelector::NextAngle(float& angle) +{ + while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() || + m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() || + m_smallStepOk[USED_POS_PLUS] || m_smallStepOk[USED_POS_MINUS] ) + { + // calculate next possible angle + if(NextPosibleAngle(angle)) + return true; + } + + return false; +} + +bool ObjectPosSelector::NextUsedAngle(float& angle) +{ + while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() || + m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() ) + { + // calculate next possible angle + if(!NextPosibleAngle(angle)) + return true; + } + + return false; +} + +bool ObjectPosSelector::NextPosibleAngle( float& angle ) +{ + // ++ direction less updated + if( m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() && + (m_nextUsedPos[USED_POS_MINUS]==m_UsedPosLists[USED_POS_MINUS].end() || m_nextUsedPos[USED_POS_PLUS]->first <= m_nextUsedPos[USED_POS_MINUS]->first) ) + { + bool ok; + if(m_smallStepOk[USED_POS_PLUS]) + ok = NextSmallStepAngle(1.0,USED_POS_PLUS,angle); + else + ok = NextAngleFor(*m_nextUsedPos[USED_POS_PLUS],1.0,USED_POS_PLUS,angle); + + if(!ok) + ++m_nextUsedPos[USED_POS_PLUS]; // increase. only at fail (original or checked) + return ok; + } + // -- direction less updated + else if( m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end()) + { + bool ok; + if(m_smallStepOk[USED_POS_MINUS]) + ok = NextSmallStepAngle(-1.0,USED_POS_MINUS,angle); + else + ok = NextAngleFor(*m_nextUsedPos[USED_POS_MINUS],-1.0,USED_POS_MINUS,angle); + + if(!ok) + ++m_nextUsedPos[USED_POS_MINUS]; + return ok; + } + else // both list empty + { + if( m_smallStepOk[USED_POS_PLUS] && (!m_smallStepOk[USED_POS_MINUS] || m_smallStepAngle[USED_POS_PLUS] <= m_smallStepAngle[USED_POS_MINUS]) ) + { + return NextSmallStepAngle(1.0,USED_POS_PLUS,angle); + } + // -- direction less updated + else if( m_smallStepOk[USED_POS_MINUS] ) + { + return NextSmallStepAngle(-1.0,USED_POS_MINUS,angle); + } + } + + // no angles + return false; +} diff --git a/src/game/ObjectPosSelector.h b/src/game/ObjectPosSelector.h new file mode 100644 index 000000000..bc4de0c1d --- /dev/null +++ b/src/game/ObjectPosSelector.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _OBJECT_POS_SELECTOR_H +#define _OBJECT_POS_SELECTOR_H + +#include + +#include + +enum UsedPosType { USED_POS_PLUS, USED_POS_MINUS }; + +inline UsedPosType operator ~(UsedPosType uptype) +{ + return uptype==USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS; +} + +struct ObjectPosSelector +{ + struct UsedPos + { + UsedPos(float sign_, float size_,float dist_) : sign(sign_), size(size_),dist(dist_) {} + + float sign; + + float size; // size of point + float dist; // dist to central point (including central point size) + }; + + typedef std::multimap UsedPosList; // abs(angle)->Node + + ObjectPosSelector(float x,float y,float size,float dist); + + void AddUsedPos(float size,float angle,float dist); + void InitializeAngle(); + + bool FirstAngle(float& angle); + bool NextAngle(float& angle); + bool NextUsedAngle(float& angle); + + bool NextPosibleAngle( float& angle ); + + bool CheckAngle(UsedPosList::value_type const& nextUsedPos, float sign, float angle ) const + { + float angle_step2 = GetAngle(nextUsedPos.second); + + float next_angle = nextUsedPos.first; + if(nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha) + next_angle = 2*M_PI-next_angle; // move to positive + + return fabs(angle)+angle_step2 <= next_angle; + } + + bool CheckOriginal() const + { + return (m_UsedPosLists[USED_POS_PLUS].empty() || CheckAngle( *m_UsedPosLists[USED_POS_PLUS].begin(),1.0,0)) && + (m_UsedPosLists[USED_POS_MINUS].empty() || CheckAngle( *m_UsedPosLists[USED_POS_MINUS].begin(),-1.0,0)); + } + + bool IsNonBalanced() const { return m_UsedPosLists[USED_POS_PLUS].empty() != m_UsedPosLists[USED_POS_MINUS].empty(); } + + bool NextAngleFor( UsedPosList::value_type const& usedPos, float sign, UsedPosType uptype, float &angle ) + { + float angle_step = GetAngle(usedPos.second); + + // next possible angle + angle = usedPos.first * usedPos.second.sign + angle_step * sign; + + UsedPosList::value_type const* nextNode = nextUsedPos(uptype); + if(nextNode) + { + // if next node permit use selected angle, then do it + if(!CheckAngle(*nextNode, sign, angle)) + { + m_smallStepOk[uptype] = false; + return false; + } + } + + // possible more points + m_smallStepOk[uptype] = true; + m_smallStepAngle[uptype] = angle; + m_smallStepNextUsedPos[uptype] = nextNode; + + return true; + } + + bool NextSmallStepAngle( float sign, UsedPosType uptype, float &angle ) + { + // next possible angle + angle = m_smallStepAngle[uptype] + m_anglestep * sign; + + if(fabs(angle) > M_PI) + { + m_smallStepOk[uptype] = false; + return false; + } + + if(m_smallStepNextUsedPos[uptype]) + { + if(fabs(angle) >= m_smallStepNextUsedPos[uptype]->first) + { + m_smallStepOk[uptype] = false; + return false; + } + + // if next node permit use selected angle, then do it + if(!CheckAngle(*m_smallStepNextUsedPos[uptype], sign, angle)) + { + m_smallStepOk[uptype] = false; + return false; + } + } + + // possible more points + m_smallStepAngle[uptype] = angle; + return true; + } + + // next used post for m_nextUsedPos[uptype] + UsedPosList::value_type const* nextUsedPos(UsedPosType uptype); + + // angle from used pos to next possible free pos + float GetAngle(UsedPos const& usedPos) const { return acos(m_dist/(usedPos.dist+usedPos.size+m_size)); } + + float m_center_x; + float m_center_y; + float m_size; // size of object in center + float m_dist; // distance for searching pos (including central object size) + float m_anglestep; + + UsedPosList m_UsedPosLists[2]; + UsedPosList::const_iterator m_nextUsedPos[2]; + + // field for small step from first after next used pos until next pos + float m_smallStepAngle[2]; + bool m_smallStepOk[2]; + UsedPosList::value_type const* m_smallStepNextUsedPos[2]; +}; +#endif diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp new file mode 100644 index 000000000..06f910d8a --- /dev/null +++ b/src/game/Opcodes.cpp @@ -0,0 +1,1089 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup u2w +*/ + +#include "Opcodes.h" +#include "WorldSession.h" + +/// Correspondence between opcodes and their names +OpcodeHandler opcodeTable[NUM_MSG_TYPES] = +{ + /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode }, + /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL }, + /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00D*/ { "CMSG_EMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00E*/ { "CMSG_UNEMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x01E*/ { "SMSG_DEBUGINFOSPELLMISS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x032*/ { "CMSG_PVP_PORT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode }, + /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode }, + /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode }, + /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode }, + /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode }, + /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode }, + /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode }, + /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode }, + /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery }, + /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode }, + /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode }, + /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode }, + /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode }, + /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode }, + /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode }, + /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode }, + /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode }, + /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode }, + /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode }, + /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode }, + /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode }, + /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode }, + /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode }, + /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode }, + /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Depricated }, + /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode }, + /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode }, + /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode }, + /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode }, + /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode }, + /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode }, + /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode }, + /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode }, + /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode }, + /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode }, + /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode }, + /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode }, + /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode }, + /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode }, + /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode }, + /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode }, + /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode }, + /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode }, + /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode }, + /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode }, + /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode }, + /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin }, + /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave }, + /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList }, + /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword }, + /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner }, + /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner }, + /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator }, + /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator }, + /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute }, + /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute }, + /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite }, + /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick }, + /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan }, + /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban }, + /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce }, + /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate }, + /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode }, + /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode }, + /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem }, + /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode }, + /*0x0B2*/ { "CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode }, + /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck }, + /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING, &WorldSession::HandleMoveWorldportAckOpcode}, + /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck }, + /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck }, + /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck }, + /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck }, + /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera }, + /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema }, + /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag }, + /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear }, + /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset }, + /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode }, + /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode }, + /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode }, + /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode }, + /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode }, + /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode }, + /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem }, + /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode }, + /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode }, + /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode }, + /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode }, + /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode }, + /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode }, + /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode }, + /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode }, + /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode }, + /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode }, + /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode }, + /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode }, + /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode }, + /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode }, + /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode }, + /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar }, + /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat }, + /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode }, + /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode }, + /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode }, + /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode }, + /*0x137*/ { "SMSG_UPDATE_AURA_DURATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling }, + /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode }, + /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode }, + /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode }, + /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode }, + /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14F*/ { "SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x152*/ { "CMSG_SHEATHE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode }, + /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode }, + /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode }, + /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode }, + /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode }, + /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode }, + /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode }, + /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode }, + /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction }, + /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction }, + /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon }, + /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename }, + /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode }, + /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode }, + /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode }, + /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode}, + /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode }, + /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode}, + /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch }, + /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode}, + /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete }, + /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode}, + /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode}, + /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel }, + /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest }, + /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest }, + /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept }, + /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty }, + /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode }, + /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode }, + /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode }, + /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode }, + /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode }, + /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodesOpcode}, + /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode }, + /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode }, + /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode }, + /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode }, + /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode }, + /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode }, + /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode }, + /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode }, + /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode }, + /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode }, + /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode }, + /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode }, + /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode }, + /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode }, + /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode }, + /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime }, + /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode }, + /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode }, + /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode }, + /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode }, + /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, + /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode }, + /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, + /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode }, + /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode }, + /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode}, + /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode }, + /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode }, + /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup }, + /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode }, + /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode }, + /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode }, + /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode }, + /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData }, + /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleUpdateAccountData }, + /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode }, + /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode }, + /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode }, + /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode}, + /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, + /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x21E*/ { "SMSG_SET_REST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode }, + /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode }, + /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode }, + /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode }, + /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode }, + /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode }, + /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail }, + /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail }, + /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode }, + /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery }, + /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney }, + /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem }, + /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead }, + /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender }, + /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete }, + /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem }, + /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode }, + /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP }, + /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode }, + /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem }, + /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem }, + /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems }, + /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems }, + /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid }, + /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems }, + /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode }, + /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode }, + /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode }, + /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode}, + /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode }, + /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet }, + /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet }, + /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot }, + /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet }, + /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet }, + /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult }, + /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode }, + /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode }, + /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode }, + /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode}, + /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode }, + /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode }, + /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime }, + /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode }, + /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode }, + /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem }, + /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo }, + /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode }, + /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll }, + /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode }, + /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode }, + /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode }, + /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode }, + /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode }, + /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B9*/ { "CMSG_TOGGLE_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode }, + /*0x2BA*/ { "CMSG_TOGGLE_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode }, + /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar }, + /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode }, + /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode }, + /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode }, + /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode }, + /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode }, + /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode }, + /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck }, + /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck }, + /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode }, + /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode}, + /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode }, + /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode }, + /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode}, + /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode }, + /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, + /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, + /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode }, + /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS",STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode}, + /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode }, + /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode }, + /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode }, + /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode }, + /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode }, + /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode}, + /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode}, + /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode }, + /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode }, + /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode }, + /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode }, + /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, &WorldSession::HandleGMSurveySubmit }, + /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode}, + /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode }, + /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode }, + /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode }, + /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode }, + /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode}, + /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode}, + /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode }, + /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode}, + /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode }, + /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode}, + /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin }, + /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode }, + /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode }, + /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode }, + /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode}, + /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode }, + /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode }, + /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode }, + /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode }, + /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode }, + /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode }, + /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode }, + /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode}, + /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode }, + /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode }, + /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode }, + /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleAllowMoveAckOpcode }, + /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide}, + /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode }, + /*0x3B0*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B1*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B2*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B3*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B4*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B5*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B6*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B7*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B8*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B9*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3BA*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3BB*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3BC*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3BD*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3BE*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3BF*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3C0*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C1*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3C3*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C4*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C5*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode}, + /*0x3C6*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode }, + /*0x3C7*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C8*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C9*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CA*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CB*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CD*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CF*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D0*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D1*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery }, + /*0x3D2*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery }, + /*0x3D3*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery }, + /*0x3D4*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3D5*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode }, + /*0x3D6*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D7*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D8*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3D9*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3DA*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DB*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DC*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DD*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DE*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DF*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E0*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E1*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E2*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E3*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK }, + /*0x3E4*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3E5*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery }, + /*0x3E6*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon }, + /*0x3E7*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E8*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem }, + /*0x3E9*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab }, + /*0x3EA*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab }, + /*0x3EB*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit }, + /*0x3EC*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw }, + /*0x3ED*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog }, + /*0x3EE*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify }, + /*0x3EF*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F0*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F1*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F2*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3F3*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F4*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F5*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F6*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3F7*/ { "CMSG_SPELLCLICK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3F8*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F9*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3FA*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3FB*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3FC*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights }, + /*0x3FD*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount }, + /*0x3FE*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode }, + /*0x3FF*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x400*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x401*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x402*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x403*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x404*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_NULL }, + /*0x405*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x406*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, + /*0x407*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x408*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode }, + /*0x409*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText }, + /*0x40A*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText }, + /*0x40B*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40C*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40D*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40E*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x410*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x411*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x412*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x413*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy }, + /*0x414*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x415*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x416*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY",STATUS_LOGGEDIN,&WorldSession::HandleQuestgiverStatusQueryMultipleOpcode}, + /*0x417*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x418*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode }, + /*0x419*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x41A*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x41B*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x41C*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x41D*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x41E*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x41F*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x420*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x421*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x422*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x423*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, +}; diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h new file mode 100644 index 000000000..a706fdea8 --- /dev/null +++ b/src/game/Opcodes.h @@ -0,0 +1,1125 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup u2w +/// @{ +/// \file + +#ifndef _OPCODES_H +#define _OPCODES_H + +#include "Common.h" + +/// List of Opcodes +enum Opcodes +{ + MSG_NULL_ACTION = 0x000, + CMSG_BOOTME = 0x001, + CMSG_DBLOOKUP = 0x002, + SMSG_DBLOOKUP = 0x003, + CMSG_QUERY_OBJECT_POSITION = 0x004, + SMSG_QUERY_OBJECT_POSITION = 0x005, + CMSG_QUERY_OBJECT_ROTATION = 0x006, + SMSG_QUERY_OBJECT_ROTATION = 0x007, + CMSG_WORLD_TELEPORT = 0x008, + CMSG_TELEPORT_TO_UNIT = 0x009, + CMSG_ZONE_MAP = 0x00A, + SMSG_ZONE_MAP = 0x00B, + CMSG_DEBUG_CHANGECELLZONE = 0x00C, + CMSG_EMBLAZON_TABARD_OBSOLETE = 0x00D, + CMSG_UNEMBLAZON_TABARD_OBSOLETE = 0x00E, + CMSG_RECHARGE = 0x00F, + CMSG_LEARN_SPELL = 0x010, + CMSG_CREATEMONSTER = 0x011, + CMSG_DESTROYMONSTER = 0x012, + CMSG_CREATEITEM = 0x013, + CMSG_CREATEGAMEOBJECT = 0x014, + SMSG_CHECK_FOR_BOTS = 0x015, + CMSG_MAKEMONSTERATTACKGUID = 0x016, + CMSG_BOT_DETECTED2 = 0x017, + CMSG_FORCEACTION = 0x018, + CMSG_FORCEACTIONONOTHER = 0x019, + CMSG_FORCEACTIONSHOW = 0x01A, + SMSG_FORCEACTIONSHOW = 0x01B, + CMSG_PETGODMODE = 0x01C, + SMSG_PETGODMODE = 0x01D, + SMSG_DEBUGINFOSPELLMISS_OBSOLETE = 0x01E, + CMSG_WEATHER_SPEED_CHEAT = 0x01F, + CMSG_UNDRESSPLAYER = 0x020, + CMSG_BEASTMASTER = 0x021, + CMSG_GODMODE = 0x022, + SMSG_GODMODE = 0x023, + CMSG_CHEAT_SETMONEY = 0x024, + CMSG_LEVEL_CHEAT = 0x025, + CMSG_PET_LEVEL_CHEAT = 0x026, + CMSG_SET_WORLDSTATE = 0x027, + CMSG_COOLDOWN_CHEAT = 0x028, + CMSG_USE_SKILL_CHEAT = 0x029, + CMSG_FLAG_QUEST = 0x02A, + CMSG_FLAG_QUEST_FINISH = 0x02B, + CMSG_CLEAR_QUEST = 0x02C, + CMSG_SEND_EVENT = 0x02D, + CMSG_DEBUG_AISTATE = 0x02E, + SMSG_DEBUG_AISTATE = 0x02F, + CMSG_DISABLE_PVP_CHEAT = 0x030, + CMSG_ADVANCE_SPAWN_TIME = 0x031, + CMSG_PVP_PORT_OBSOLETE = 0x032, + CMSG_AUTH_SRP6_BEGIN = 0x033, + CMSG_AUTH_SRP6_PROOF = 0x034, + CMSG_AUTH_SRP6_RECODE = 0x035, + CMSG_CHAR_CREATE = 0x036, + CMSG_CHAR_ENUM = 0x037, + CMSG_CHAR_DELETE = 0x038, + SMSG_AUTH_SRP6_RESPONSE = 0x039, + SMSG_CHAR_CREATE = 0x03A, + SMSG_CHAR_ENUM = 0x03B, + SMSG_CHAR_DELETE = 0x03C, + CMSG_PLAYER_LOGIN = 0x03D, + SMSG_NEW_WORLD = 0x03E, + SMSG_TRANSFER_PENDING = 0x03F, + SMSG_TRANSFER_ABORTED = 0x040, + SMSG_CHARACTER_LOGIN_FAILED = 0x041, + SMSG_LOGIN_SETTIMESPEED = 0x042, + SMSG_GAMETIME_UPDATE = 0x043, + CMSG_GAMETIME_SET = 0x044, + SMSG_GAMETIME_SET = 0x045, + CMSG_GAMESPEED_SET = 0x046, + SMSG_GAMESPEED_SET = 0x047, + CMSG_SERVERTIME = 0x048, + SMSG_SERVERTIME = 0x049, + CMSG_PLAYER_LOGOUT = 0x04A, + CMSG_LOGOUT_REQUEST = 0x04B, + SMSG_LOGOUT_RESPONSE = 0x04C, + SMSG_LOGOUT_COMPLETE = 0x04D, + CMSG_LOGOUT_CANCEL = 0x04E, + SMSG_LOGOUT_CANCEL_ACK = 0x04F, + CMSG_NAME_QUERY = 0x050, + SMSG_NAME_QUERY_RESPONSE = 0x051, + CMSG_PET_NAME_QUERY = 0x052, + SMSG_PET_NAME_QUERY_RESPONSE = 0x053, + CMSG_GUILD_QUERY = 0x054, + SMSG_GUILD_QUERY_RESPONSE = 0x055, + CMSG_ITEM_QUERY_SINGLE = 0x056, + CMSG_ITEM_QUERY_MULTIPLE = 0x057, + SMSG_ITEM_QUERY_SINGLE_RESPONSE = 0x058, + SMSG_ITEM_QUERY_MULTIPLE_RESPONSE = 0x059, + CMSG_PAGE_TEXT_QUERY = 0x05A, + SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x05B, + CMSG_QUEST_QUERY = 0x05C, + SMSG_QUEST_QUERY_RESPONSE = 0x05D, + CMSG_GAMEOBJECT_QUERY = 0x05E, + SMSG_GAMEOBJECT_QUERY_RESPONSE = 0x05F, + CMSG_CREATURE_QUERY = 0x060, + SMSG_CREATURE_QUERY_RESPONSE = 0x061, + CMSG_WHO = 0x062, + SMSG_WHO = 0x063, + CMSG_WHOIS = 0x064, + SMSG_WHOIS = 0x065, + CMSG_CONTACT_LIST = 0x066, + SMSG_CONTACT_LIST = 0x067, + SMSG_FRIEND_STATUS = 0x068, + CMSG_ADD_FRIEND = 0x069, + CMSG_DEL_FRIEND = 0x06A, + CMSG_SET_CONTACT_NOTES = 0x06B, + CMSG_ADD_IGNORE = 0x06C, + CMSG_DEL_IGNORE = 0x06D, + CMSG_GROUP_INVITE = 0x06E, + SMSG_GROUP_INVITE = 0x06F, + CMSG_GROUP_CANCEL = 0x070, + SMSG_GROUP_CANCEL = 0x071, + CMSG_GROUP_ACCEPT = 0x072, + CMSG_GROUP_DECLINE = 0x073, + SMSG_GROUP_DECLINE = 0x074, + CMSG_GROUP_UNINVITE = 0x075, + CMSG_GROUP_UNINVITE_GUID = 0x076, + SMSG_GROUP_UNINVITE = 0x077, + CMSG_GROUP_SET_LEADER = 0x078, + SMSG_GROUP_SET_LEADER = 0x079, + CMSG_LOOT_METHOD = 0x07A, + CMSG_GROUP_DISBAND = 0x07B, + SMSG_GROUP_DESTROYED = 0x07C, + SMSG_GROUP_LIST = 0x07D, + SMSG_PARTY_MEMBER_STATS = 0x07E, + SMSG_PARTY_COMMAND_RESULT = 0x07F, + UMSG_UPDATE_GROUP_MEMBERS = 0x080, + CMSG_GUILD_CREATE = 0x081, + CMSG_GUILD_INVITE = 0x082, + SMSG_GUILD_INVITE = 0x083, + CMSG_GUILD_ACCEPT = 0x084, + CMSG_GUILD_DECLINE = 0x085, + SMSG_GUILD_DECLINE = 0x086, + CMSG_GUILD_INFO = 0x087, + SMSG_GUILD_INFO = 0x088, + CMSG_GUILD_ROSTER = 0x089, + SMSG_GUILD_ROSTER = 0x08A, + CMSG_GUILD_PROMOTE = 0x08B, + CMSG_GUILD_DEMOTE = 0x08C, + CMSG_GUILD_LEAVE = 0x08D, + CMSG_GUILD_REMOVE = 0x08E, + CMSG_GUILD_DISBAND = 0x08F, + CMSG_GUILD_LEADER = 0x090, + CMSG_GUILD_MOTD = 0x091, + SMSG_GUILD_EVENT = 0x092, + SMSG_GUILD_COMMAND_RESULT = 0x093, + UMSG_UPDATE_GUILD = 0x094, + CMSG_MESSAGECHAT = 0x095, + SMSG_MESSAGECHAT = 0x096, + CMSG_JOIN_CHANNEL = 0x097, + CMSG_LEAVE_CHANNEL = 0x098, + SMSG_CHANNEL_NOTIFY = 0x099, + CMSG_CHANNEL_LIST = 0x09A, + SMSG_CHANNEL_LIST = 0x09B, + CMSG_CHANNEL_PASSWORD = 0x09C, + CMSG_CHANNEL_SET_OWNER = 0x09D, + CMSG_CHANNEL_OWNER = 0x09E, + CMSG_CHANNEL_MODERATOR = 0x09F, + CMSG_CHANNEL_UNMODERATOR = 0x0A0, + CMSG_CHANNEL_MUTE = 0x0A1, + CMSG_CHANNEL_UNMUTE = 0x0A2, + CMSG_CHANNEL_INVITE = 0x0A3, + CMSG_CHANNEL_KICK = 0x0A4, + CMSG_CHANNEL_BAN = 0x0A5, + CMSG_CHANNEL_UNBAN = 0x0A6, + CMSG_CHANNEL_ANNOUNCEMENTS = 0x0A7, + CMSG_CHANNEL_MODERATE = 0x0A8, + SMSG_UPDATE_OBJECT = 0x0A9, + SMSG_DESTROY_OBJECT = 0x0AA, + CMSG_USE_ITEM = 0x0AB, + CMSG_OPEN_ITEM = 0x0AC, + CMSG_READ_ITEM = 0x0AD, + SMSG_READ_ITEM_OK = 0x0AE, + SMSG_READ_ITEM_FAILED = 0x0AF, + SMSG_ITEM_COOLDOWN = 0x0B0, + CMSG_GAMEOBJ_USE = 0x0B1, + CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE = 0x0B2, + SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3, + CMSG_AREATRIGGER = 0x0B4, + MSG_MOVE_START_FORWARD = 0x0B5, + MSG_MOVE_START_BACKWARD = 0x0B6, + MSG_MOVE_STOP = 0x0B7, + MSG_MOVE_START_STRAFE_LEFT = 0x0B8, + MSG_MOVE_START_STRAFE_RIGHT = 0x0B9, + MSG_MOVE_STOP_STRAFE = 0x0BA, + MSG_MOVE_JUMP = 0x0BB, + MSG_MOVE_START_TURN_LEFT = 0x0BC, + MSG_MOVE_START_TURN_RIGHT = 0x0BD, + MSG_MOVE_STOP_TURN = 0x0BE, + MSG_MOVE_START_PITCH_UP = 0x0BF, + MSG_MOVE_START_PITCH_DOWN = 0x0C0, + MSG_MOVE_STOP_PITCH = 0x0C1, + MSG_MOVE_SET_RUN_MODE = 0x0C2, + MSG_MOVE_SET_WALK_MODE = 0x0C3, + MSG_MOVE_TOGGLE_LOGGING = 0x0C4, + MSG_MOVE_TELEPORT = 0x0C5, + MSG_MOVE_TELEPORT_CHEAT = 0x0C6, + MSG_MOVE_TELEPORT_ACK = 0x0C7, + MSG_MOVE_TOGGLE_FALL_LOGGING = 0x0C8, + MSG_MOVE_FALL_LAND = 0x0C9, + MSG_MOVE_START_SWIM = 0x0CA, + MSG_MOVE_STOP_SWIM = 0x0CB, + MSG_MOVE_SET_RUN_SPEED_CHEAT = 0x0CC, + MSG_MOVE_SET_RUN_SPEED = 0x0CD, + MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT = 0x0CE, + MSG_MOVE_SET_RUN_BACK_SPEED = 0x0CF, + MSG_MOVE_SET_WALK_SPEED_CHEAT = 0x0D0, + MSG_MOVE_SET_WALK_SPEED = 0x0D1, + MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0x0D2, + MSG_MOVE_SET_SWIM_SPEED = 0x0D3, + MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT = 0x0D4, + MSG_MOVE_SET_SWIM_BACK_SPEED = 0x0D5, + MSG_MOVE_SET_ALL_SPEED_CHEAT = 0x0D6, + MSG_MOVE_SET_TURN_RATE_CHEAT = 0x0D7, + MSG_MOVE_SET_TURN_RATE = 0x0D8, + MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0x0D9, + MSG_MOVE_SET_FACING = 0x0DA, + MSG_MOVE_SET_PITCH = 0x0DB, + MSG_MOVE_WORLDPORT_ACK = 0x0DC, + SMSG_MONSTER_MOVE = 0x0DD, + SMSG_MOVE_WATER_WALK = 0x0DE, + SMSG_MOVE_LAND_WALK = 0x0DF, + MSG_MOVE_SET_RAW_POSITION_ACK = 0x0E0, + CMSG_MOVE_SET_RAW_POSITION = 0x0E1, + SMSG_FORCE_RUN_SPEED_CHANGE = 0x0E2, + CMSG_FORCE_RUN_SPEED_CHANGE_ACK = 0x0E3, + SMSG_FORCE_RUN_BACK_SPEED_CHANGE = 0x0E4, + CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK = 0x0E5, + SMSG_FORCE_SWIM_SPEED_CHANGE = 0x0E6, + CMSG_FORCE_SWIM_SPEED_CHANGE_ACK = 0x0E7, + SMSG_FORCE_MOVE_ROOT = 0x0E8, + CMSG_FORCE_MOVE_ROOT_ACK = 0x0E9, + SMSG_FORCE_MOVE_UNROOT = 0x0EA, + CMSG_FORCE_MOVE_UNROOT_ACK = 0x0EB, + MSG_MOVE_ROOT = 0x0EC, + MSG_MOVE_UNROOT = 0x0ED, + MSG_MOVE_HEARTBEAT = 0x0EE, + SMSG_MOVE_KNOCK_BACK = 0x0EF, + CMSG_MOVE_KNOCK_BACK_ACK = 0x0F0, + MSG_MOVE_KNOCK_BACK = 0x0F1, + SMSG_MOVE_FEATHER_FALL = 0x0F2, + SMSG_MOVE_NORMAL_FALL = 0x0F3, + SMSG_MOVE_SET_HOVER = 0x0F4, + SMSG_MOVE_UNSET_HOVER = 0x0F5, + CMSG_MOVE_HOVER_ACK = 0x0F6, + MSG_MOVE_HOVER = 0x0F7, + CMSG_TRIGGER_CINEMATIC_CHEAT = 0x0F8, + CMSG_OPENING_CINEMATIC = 0x0F9, + SMSG_TRIGGER_CINEMATIC = 0x0FA, + CMSG_NEXT_CINEMATIC_CAMERA = 0x0FB, + CMSG_COMPLETE_CINEMATIC = 0x0FC, + SMSG_TUTORIAL_FLAGS = 0x0FD, + CMSG_TUTORIAL_FLAG = 0x0FE, + CMSG_TUTORIAL_CLEAR = 0x0FF, + CMSG_TUTORIAL_RESET = 0x100, + CMSG_STANDSTATECHANGE = 0x101, + CMSG_EMOTE = 0x102, + SMSG_EMOTE = 0x103, + CMSG_TEXT_EMOTE = 0x104, + SMSG_TEXT_EMOTE = 0x105, + CMSG_AUTOEQUIP_GROUND_ITEM = 0x106, + CMSG_AUTOSTORE_GROUND_ITEM = 0x107, + CMSG_AUTOSTORE_LOOT_ITEM = 0x108, + CMSG_STORE_LOOT_IN_SLOT = 0x109, + CMSG_AUTOEQUIP_ITEM = 0x10A, + CMSG_AUTOSTORE_BAG_ITEM = 0x10B, + CMSG_SWAP_ITEM = 0x10C, + CMSG_SWAP_INV_ITEM = 0x10D, + CMSG_SPLIT_ITEM = 0x10E, + CMSG_AUTOEQUIP_ITEM_SLOT = 0x10F, + OBSOLETE_DROP_ITEM = 0x110, + CMSG_DESTROYITEM = 0x111, + SMSG_INVENTORY_CHANGE_FAILURE = 0x112, + SMSG_OPEN_CONTAINER = 0x113, + CMSG_INSPECT = 0x114, + SMSG_INSPECT = 0x115, + CMSG_INITIATE_TRADE = 0x116, + CMSG_BEGIN_TRADE = 0x117, + CMSG_BUSY_TRADE = 0x118, + CMSG_IGNORE_TRADE = 0x119, + CMSG_ACCEPT_TRADE = 0x11A, + CMSG_UNACCEPT_TRADE = 0x11B, + CMSG_CANCEL_TRADE = 0x11C, + CMSG_SET_TRADE_ITEM = 0x11D, + CMSG_CLEAR_TRADE_ITEM = 0x11E, + CMSG_SET_TRADE_GOLD = 0x11F, + SMSG_TRADE_STATUS = 0x120, + SMSG_TRADE_STATUS_EXTENDED = 0x121, + SMSG_INITIALIZE_FACTIONS = 0x122, + SMSG_SET_FACTION_VISIBLE = 0x123, + SMSG_SET_FACTION_STANDING = 0x124, + CMSG_SET_FACTION_ATWAR = 0x125, + CMSG_SET_FACTION_CHEAT = 0x126, + SMSG_SET_PROFICIENCY = 0x127, + CMSG_SET_ACTION_BUTTON = 0x128, + SMSG_ACTION_BUTTONS = 0x129, + SMSG_INITIAL_SPELLS = 0x12A, + SMSG_LEARNED_SPELL = 0x12B, + SMSG_SUPERCEDED_SPELL = 0x12C, + CMSG_NEW_SPELL_SLOT = 0x12D, + CMSG_CAST_SPELL = 0x12E, + CMSG_CANCEL_CAST = 0x12F, + SMSG_CAST_FAILED = 0x130, + SMSG_SPELL_START = 0x131, + SMSG_SPELL_GO = 0x132, + SMSG_SPELL_FAILURE = 0x133, + SMSG_SPELL_COOLDOWN = 0x134, + SMSG_COOLDOWN_EVENT = 0x135, + CMSG_CANCEL_AURA = 0x136, + SMSG_UPDATE_AURA_DURATION = 0x137, + SMSG_PET_CAST_FAILED = 0x138, + MSG_CHANNEL_START = 0x139, + MSG_CHANNEL_UPDATE = 0x13A, + CMSG_CANCEL_CHANNELLING = 0x13B, + SMSG_AI_REACTION = 0x13C, + CMSG_SET_SELECTION = 0x13D, + CMSG_SET_TARGET_OBSOLETE = 0x13E, + CMSG_UNUSED = 0x13F, + CMSG_UNUSED2 = 0x140, + CMSG_ATTACKSWING = 0x141, + CMSG_ATTACKSTOP = 0x142, + SMSG_ATTACKSTART = 0x143, + SMSG_ATTACKSTOP = 0x144, + SMSG_ATTACKSWING_NOTINRANGE = 0x145, + SMSG_ATTACKSWING_BADFACING = 0x146, + SMSG_ATTACKSWING_NOTSTANDING = 0x147, + SMSG_ATTACKSWING_DEADTARGET = 0x148, + SMSG_ATTACKSWING_CANT_ATTACK = 0x149, + SMSG_ATTACKERSTATEUPDATE = 0x14A, + SMSG_VICTIMSTATEUPDATE_OBSOLETE = 0x14B, + SMSG_DAMAGE_DONE_OBSOLETE = 0x14C, + SMSG_DAMAGE_TAKEN_OBSOLETE = 0x14D, + SMSG_CANCEL_COMBAT = 0x14E, + SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE = 0x14F, + SMSG_SPELLHEALLOG = 0x150, + SMSG_SPELLENERGIZELOG = 0x151, + CMSG_SHEATHE_OBSOLETE = 0x152, + CMSG_SAVE_PLAYER = 0x153, + CMSG_SETDEATHBINDPOINT = 0x154, + SMSG_BINDPOINTUPDATE = 0x155, + CMSG_GETDEATHBINDZONE = 0x156, + SMSG_BINDZONEREPLY = 0x157, + SMSG_PLAYERBOUND = 0x158, + SMSG_CLIENT_CONTROL_UPDATE = 0x159, + CMSG_REPOP_REQUEST = 0x15A, + SMSG_RESURRECT_REQUEST = 0x15B, + CMSG_RESURRECT_RESPONSE = 0x15C, + CMSG_LOOT = 0x15D, + CMSG_LOOT_MONEY = 0x15E, + CMSG_LOOT_RELEASE = 0x15F, + SMSG_LOOT_RESPONSE = 0x160, + SMSG_LOOT_RELEASE_RESPONSE = 0x161, + SMSG_LOOT_REMOVED = 0x162, + SMSG_LOOT_MONEY_NOTIFY = 0x163, + SMSG_LOOT_ITEM_NOTIFY = 0x164, + SMSG_LOOT_CLEAR_MONEY = 0x165, + SMSG_ITEM_PUSH_RESULT = 0x166, + SMSG_DUEL_REQUESTED = 0x167, + SMSG_DUEL_OUTOFBOUNDS = 0x168, + SMSG_DUEL_INBOUNDS = 0x169, + SMSG_DUEL_COMPLETE = 0x16A, + SMSG_DUEL_WINNER = 0x16B, + CMSG_DUEL_ACCEPTED = 0x16C, + CMSG_DUEL_CANCELLED = 0x16D, + SMSG_MOUNTRESULT = 0x16E, + SMSG_DISMOUNTRESULT = 0x16F, + SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 0x170, + CMSG_MOUNTSPECIAL_ANIM = 0x171, + SMSG_MOUNTSPECIAL_ANIM = 0x172, + SMSG_PET_TAME_FAILURE = 0x173, + CMSG_PET_SET_ACTION = 0x174, + CMSG_PET_ACTION = 0x175, + CMSG_PET_ABANDON = 0x176, + CMSG_PET_RENAME = 0x177, + SMSG_PET_NAME_INVALID = 0x178, + SMSG_PET_SPELLS = 0x179, + SMSG_PET_MODE = 0x17A, + CMSG_GOSSIP_HELLO = 0x17B, + CMSG_GOSSIP_SELECT_OPTION = 0x17C, + SMSG_GOSSIP_MESSAGE = 0x17D, + SMSG_GOSSIP_COMPLETE = 0x17E, + CMSG_NPC_TEXT_QUERY = 0x17F, + SMSG_NPC_TEXT_UPDATE = 0x180, + SMSG_NPC_WONT_TALK = 0x181, + CMSG_QUESTGIVER_STATUS_QUERY = 0x182, + SMSG_QUESTGIVER_STATUS = 0x183, + CMSG_QUESTGIVER_HELLO = 0x184, + SMSG_QUESTGIVER_QUEST_LIST = 0x185, + CMSG_QUESTGIVER_QUERY_QUEST = 0x186, + CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0x187, + SMSG_QUESTGIVER_QUEST_DETAILS = 0x188, + CMSG_QUESTGIVER_ACCEPT_QUEST = 0x189, + CMSG_QUESTGIVER_COMPLETE_QUEST = 0x18A, + SMSG_QUESTGIVER_REQUEST_ITEMS = 0x18B, + CMSG_QUESTGIVER_REQUEST_REWARD = 0x18C, + SMSG_QUESTGIVER_OFFER_REWARD = 0x18D, + CMSG_QUESTGIVER_CHOOSE_REWARD = 0x18E, + SMSG_QUESTGIVER_QUEST_INVALID = 0x18F, + CMSG_QUESTGIVER_CANCEL = 0x190, + SMSG_QUESTGIVER_QUEST_COMPLETE = 0x191, + SMSG_QUESTGIVER_QUEST_FAILED = 0x192, + CMSG_QUESTLOG_SWAP_QUEST = 0x193, + CMSG_QUESTLOG_REMOVE_QUEST = 0x194, + SMSG_QUESTLOG_FULL = 0x195, + SMSG_QUESTUPDATE_FAILED = 0x196, + SMSG_QUESTUPDATE_FAILEDTIMER = 0x197, + SMSG_QUESTUPDATE_COMPLETE = 0x198, + SMSG_QUESTUPDATE_ADD_KILL = 0x199, + SMSG_QUESTUPDATE_ADD_ITEM = 0x19A, + CMSG_QUEST_CONFIRM_ACCEPT = 0x19B, + SMSG_QUEST_CONFIRM_ACCEPT = 0x19C, + CMSG_PUSHQUESTTOPARTY = 0x19D, + CMSG_LIST_INVENTORY = 0x19E, + SMSG_LIST_INVENTORY = 0x19F, + CMSG_SELL_ITEM = 0x1A0, + SMSG_SELL_ITEM = 0x1A1, + CMSG_BUY_ITEM = 0x1A2, + CMSG_BUY_ITEM_IN_SLOT = 0x1A3, + SMSG_BUY_ITEM = 0x1A4, + SMSG_BUY_FAILED = 0x1A5, + CMSG_TAXICLEARALLNODES = 0x1A6, + CMSG_TAXIENABLEALLNODES = 0x1A7, + CMSG_TAXISHOWNODES = 0x1A8, + SMSG_SHOWTAXINODES = 0x1A9, + CMSG_TAXINODE_STATUS_QUERY = 0x1AA, + SMSG_TAXINODE_STATUS = 0x1AB, + CMSG_TAXIQUERYAVAILABLENODES = 0x1AC, + CMSG_ACTIVATETAXI = 0x1AD, + SMSG_ACTIVATETAXIREPLY = 0x1AE, + SMSG_NEW_TAXI_PATH = 0x1AF, + CMSG_TRAINER_LIST = 0x1B0, + SMSG_TRAINER_LIST = 0x1B1, + CMSG_TRAINER_BUY_SPELL = 0x1B2, + SMSG_TRAINER_BUY_SUCCEEDED = 0x1B3, + SMSG_TRAINER_BUY_FAILED = 0x1B4, + CMSG_BINDER_ACTIVATE = 0x1B5, + SMSG_PLAYERBINDERROR = 0x1B6, + CMSG_BANKER_ACTIVATE = 0x1B7, + SMSG_SHOW_BANK = 0x1B8, + CMSG_BUY_BANK_SLOT = 0x1B9, + SMSG_BUY_BANK_SLOT_RESULT = 0x1BA, + CMSG_PETITION_SHOWLIST = 0x1BB, + SMSG_PETITION_SHOWLIST = 0x1BC, + CMSG_PETITION_BUY = 0x1BD, + CMSG_PETITION_SHOW_SIGNATURES = 0x1BE, + SMSG_PETITION_SHOW_SIGNATURES = 0x1BF, + CMSG_PETITION_SIGN = 0x1C0, + SMSG_PETITION_SIGN_RESULTS = 0x1C1, + MSG_PETITION_DECLINE = 0x1C2, + CMSG_OFFER_PETITION = 0x1C3, + CMSG_TURN_IN_PETITION = 0x1C4, + SMSG_TURN_IN_PETITION_RESULTS = 0x1C5, + CMSG_PETITION_QUERY = 0x1C6, + SMSG_PETITION_QUERY_RESPONSE = 0x1C7, + SMSG_FISH_NOT_HOOKED = 0x1C8, + SMSG_FISH_ESCAPED = 0x1C9, + CMSG_BUG = 0x1CA, + SMSG_NOTIFICATION = 0x1CB, + CMSG_PLAYED_TIME = 0x1CC, + SMSG_PLAYED_TIME = 0x1CD, + CMSG_QUERY_TIME = 0x1CE, + SMSG_QUERY_TIME_RESPONSE = 0x1CF, + SMSG_LOG_XPGAIN = 0x1D0, + SMSG_AURACASTLOG = 0x1D1, + CMSG_RECLAIM_CORPSE = 0x1D2, + CMSG_WRAP_ITEM = 0x1D3, + SMSG_LEVELUP_INFO = 0x1D4, + MSG_MINIMAP_PING = 0x1D5, + SMSG_RESISTLOG = 0x1D6, + SMSG_ENCHANTMENTLOG = 0x1D7, + CMSG_SET_SKILL_CHEAT = 0x1D8, + SMSG_START_MIRROR_TIMER = 0x1D9, + SMSG_PAUSE_MIRROR_TIMER = 0x1DA, + SMSG_STOP_MIRROR_TIMER = 0x1DB, + CMSG_PING = 0x1DC, + SMSG_PONG = 0x1DD, + SMSG_CLEAR_COOLDOWN = 0x1DE, + SMSG_GAMEOBJECT_PAGETEXT = 0x1DF, + CMSG_SETSHEATHED = 0x1E0, + SMSG_COOLDOWN_CHEAT = 0x1E1, + SMSG_SPELL_DELAYED = 0x1E2, + CMSG_PLAYER_MACRO_OBSOLETE = 0x1E3, + SMSG_PLAYER_MACRO_OBSOLETE = 0x1E4, + CMSG_GHOST = 0x1E5, + CMSG_GM_INVIS = 0x1E6, + SMSG_INVALID_PROMOTION_CODE = 0x1E7, + MSG_GM_BIND_OTHER = 0x1E8, + MSG_GM_SUMMON = 0x1E9, + SMSG_ITEM_TIME_UPDATE = 0x1EA, + SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x1EB, + SMSG_AUTH_CHALLENGE = 0x1EC, + CMSG_AUTH_SESSION = 0x1ED, + SMSG_AUTH_RESPONSE = 0x1EE, + MSG_GM_SHOWLABEL = 0x1EF, + CMSG_PET_CAST_SPELL = 0x1F0, + MSG_SAVE_GUILD_EMBLEM = 0x1F1, + MSG_TABARDVENDOR_ACTIVATE = 0x1F2, + SMSG_PLAY_SPELL_VISUAL = 0x1F3, + CMSG_ZONEUPDATE = 0x1F4, + SMSG_PARTYKILLLOG = 0x1F5, + SMSG_COMPRESSED_UPDATE_OBJECT = 0x1F6, + SMSG_PLAY_SPELL_IMPACT = 0x1F7, + SMSG_EXPLORATION_EXPERIENCE = 0x1F8, + CMSG_GM_SET_SECURITY_GROUP = 0x1F9, + CMSG_GM_NUKE = 0x1FA, + MSG_RANDOM_ROLL = 0x1FB, + SMSG_ENVIRONMENTALDAMAGELOG = 0x1FC, + CMSG_RWHOIS_OBSOLETE = 0x1FD, + SMSG_RWHOIS = 0x1FE, + MSG_LOOKING_FOR_GROUP = 0x1FF, + CMSG_SET_LOOKING_FOR_GROUP = 0x200, + CMSG_UNLEARN_SPELL = 0x201, + CMSG_UNLEARN_SKILL = 0x202, + SMSG_REMOVED_SPELL = 0x203, + CMSG_DECHARGE = 0x204, + CMSG_GMTICKET_CREATE = 0x205, + SMSG_GMTICKET_CREATE = 0x206, + CMSG_GMTICKET_UPDATETEXT = 0x207, + SMSG_GMTICKET_UPDATETEXT = 0x208, + SMSG_ACCOUNT_DATA_TIMES = 0x209, + CMSG_REQUEST_ACCOUNT_DATA = 0x20A, + CMSG_UPDATE_ACCOUNT_DATA = 0x20B, + SMSG_UPDATE_ACCOUNT_DATA = 0x20C, + SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x20D, + SMSG_POWERGAINLOG_OBSOLETE = 0x20E, + CMSG_GM_TEACH = 0x20F, + CMSG_GM_CREATE_ITEM_TARGET = 0x210, + CMSG_GMTICKET_GETTICKET = 0x211, + SMSG_GMTICKET_GETTICKET = 0x212, + CMSG_UNLEARN_TALENTS = 0x213, + SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE = 0x214, + SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x215, + MSG_CORPSE_QUERY = 0x216, + CMSG_GMTICKET_DELETETICKET = 0x217, + SMSG_GMTICKET_DELETETICKET = 0x218, + SMSG_CHAT_WRONG_FACTION = 0x219, + CMSG_GMTICKET_SYSTEMSTATUS = 0x21A, + SMSG_GMTICKET_SYSTEMSTATUS = 0x21B, + CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C, + CMSG_SET_STAT_CHEAT = 0x21D, + SMSG_SET_REST_START = 0x21E, + CMSG_SKILL_BUY_STEP = 0x21F, + CMSG_SKILL_BUY_RANK = 0x220, + CMSG_XP_CHEAT = 0x221, + SMSG_SPIRIT_HEALER_CONFIRM = 0x222, + CMSG_CHARACTER_POINT_CHEAT = 0x223, + SMSG_GOSSIP_POI = 0x224, + CMSG_CHAT_IGNORED = 0x225, + CMSG_GM_VISION = 0x226, + CMSG_SERVER_COMMAND = 0x227, + CMSG_GM_SILENCE = 0x228, + CMSG_GM_REVEALTO = 0x229, + CMSG_GM_RESURRECT = 0x22A, + CMSG_GM_SUMMONMOB = 0x22B, + CMSG_GM_MOVECORPSE = 0x22C, + CMSG_GM_FREEZE = 0x22D, + CMSG_GM_UBERINVIS = 0x22E, + CMSG_GM_REQUEST_PLAYER_INFO = 0x22F, + SMSG_GM_PLAYER_INFO = 0x230, + CMSG_GUILD_RANK = 0x231, + CMSG_GUILD_ADD_RANK = 0x232, + CMSG_GUILD_DEL_RANK = 0x233, + CMSG_GUILD_SET_PUBLIC_NOTE = 0x234, + CMSG_GUILD_SET_OFFICER_NOTE = 0x235, + SMSG_LOGIN_VERIFY_WORLD = 0x236, + CMSG_CLEAR_EXPLORATION = 0x237, + CMSG_SEND_MAIL = 0x238, + SMSG_SEND_MAIL_RESULT = 0x239, + CMSG_GET_MAIL_LIST = 0x23A, + SMSG_MAIL_LIST_RESULT = 0x23B, + CMSG_BATTLEFIELD_LIST = 0x23C, + SMSG_BATTLEFIELD_LIST = 0x23D, + CMSG_BATTLEFIELD_JOIN = 0x23E, + SMSG_BATTLEFIELD_WIN_OBSOLETE = 0x23F, + SMSG_BATTLEFIELD_LOSE_OBSOLETE = 0x240, + CMSG_TAXICLEARNODE = 0x241, + CMSG_TAXIENABLENODE = 0x242, + CMSG_ITEM_TEXT_QUERY = 0x243, + SMSG_ITEM_TEXT_QUERY_RESPONSE = 0x244, + CMSG_MAIL_TAKE_MONEY = 0x245, + CMSG_MAIL_TAKE_ITEM = 0x246, + CMSG_MAIL_MARK_AS_READ = 0x247, + CMSG_MAIL_RETURN_TO_SENDER = 0x248, + CMSG_MAIL_DELETE = 0x249, + CMSG_MAIL_CREATE_TEXT_ITEM = 0x24A, + SMSG_SPELLLOGMISS = 0x24B, + SMSG_SPELLLOGEXECUTE = 0x24C, + SMSG_DEBUGAURAPROC = 0x24D, + SMSG_PERIODICAURALOG = 0x24E, + SMSG_SPELLDAMAGESHIELD = 0x24F, + SMSG_SPELLNONMELEEDAMAGELOG = 0x250, + CMSG_LEARN_TALENT = 0x251, + SMSG_RESURRECT_FAILED = 0x252, + CMSG_TOGGLE_PVP = 0x253, + SMSG_ZONE_UNDER_ATTACK = 0x254, + MSG_AUCTION_HELLO = 0x255, + CMSG_AUCTION_SELL_ITEM = 0x256, + CMSG_AUCTION_REMOVE_ITEM = 0x257, + CMSG_AUCTION_LIST_ITEMS = 0x258, + CMSG_AUCTION_LIST_OWNER_ITEMS = 0x259, + CMSG_AUCTION_PLACE_BID = 0x25A, + SMSG_AUCTION_COMMAND_RESULT = 0x25B, + SMSG_AUCTION_LIST_RESULT = 0x25C, + SMSG_AUCTION_OWNER_LIST_RESULT = 0x25D, + SMSG_AUCTION_BIDDER_NOTIFICATION = 0x25E, + SMSG_AUCTION_OWNER_NOTIFICATION = 0x25F, + SMSG_PROCRESIST = 0x260, + SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE = 0x261, + SMSG_DISPEL_FAILED = 0x262, + SMSG_SPELLORDAMAGE_IMMUNE = 0x263, + CMSG_AUCTION_LIST_BIDDER_ITEMS = 0x264, + SMSG_AUCTION_BIDDER_LIST_RESULT = 0x265, + SMSG_SET_FLAT_SPELL_MODIFIER = 0x266, + SMSG_SET_PCT_SPELL_MODIFIER = 0x267, + CMSG_SET_AMMO = 0x268, + SMSG_CORPSE_RECLAIM_DELAY = 0x269, + CMSG_SET_ACTIVE_MOVER = 0x26A, + CMSG_PET_CANCEL_AURA = 0x26B, + CMSG_PLAYER_AI_CHEAT = 0x26C, + CMSG_CANCEL_AUTO_REPEAT_SPELL = 0x26D, + MSG_GM_ACCOUNT_ONLINE = 0x26E, + MSG_LIST_STABLED_PETS = 0x26F, + CMSG_STABLE_PET = 0x270, + CMSG_UNSTABLE_PET = 0x271, + CMSG_BUY_STABLE_SLOT = 0x272, + SMSG_STABLE_RESULT = 0x273, + CMSG_STABLE_REVIVE_PET = 0x274, + CMSG_STABLE_SWAP_PET = 0x275, + MSG_QUEST_PUSH_RESULT = 0x276, + SMSG_PLAY_MUSIC = 0x277, + SMSG_PLAY_OBJECT_SOUND = 0x278, + CMSG_REQUEST_PET_INFO = 0x279, + CMSG_FAR_SIGHT = 0x27A, + SMSG_SPELLDISPELLOG = 0x27B, + SMSG_DAMAGE_CALC_LOG = 0x27C, + CMSG_ENABLE_DAMAGE_LOG = 0x27D, + CMSG_GROUP_CHANGE_SUB_GROUP = 0x27E, + CMSG_REQUEST_PARTY_MEMBER_STATS = 0x27F, + CMSG_GROUP_SWAP_SUB_GROUP = 0x280, + CMSG_RESET_FACTION_CHEAT = 0x281, + CMSG_AUTOSTORE_BANK_ITEM = 0x282, + CMSG_AUTOBANK_ITEM = 0x283, + MSG_QUERY_NEXT_MAIL_TIME = 0x284, + SMSG_RECEIVED_MAIL = 0x285, + SMSG_RAID_GROUP_ONLY = 0x286, + CMSG_SET_DURABILITY_CHEAT = 0x287, + CMSG_SET_PVP_RANK_CHEAT = 0x288, + CMSG_ADD_PVP_MEDAL_CHEAT = 0x289, + CMSG_DEL_PVP_MEDAL_CHEAT = 0x28A, + CMSG_SET_PVP_TITLE = 0x28B, + SMSG_PVP_CREDIT = 0x28C, + SMSG_AUCTION_REMOVED_NOTIFICATION = 0x28D, + CMSG_GROUP_RAID_CONVERT = 0x28E, + CMSG_GROUP_ASSISTANT_LEADER = 0x28F, + CMSG_BUYBACK_ITEM = 0x290, + SMSG_SERVER_MESSAGE = 0x291, + CMSG_MEETINGSTONE_JOIN = 0x292, + CMSG_MEETINGSTONE_LEAVE = 0x293, + CMSG_MEETINGSTONE_CHEAT = 0x294, + SMSG_MEETINGSTONE_SETQUEUE = 0x295, + CMSG_MEETINGSTONE_INFO = 0x296, + SMSG_MEETINGSTONE_COMPLETE = 0x297, + SMSG_MEETINGSTONE_IN_PROGRESS = 0x298, + SMSG_MEETINGSTONE_MEMBER_ADDED = 0x299, + CMSG_GMTICKETSYSTEM_TOGGLE = 0x29A, + CMSG_CANCEL_GROWTH_AURA = 0x29B, + SMSG_CANCEL_AUTO_REPEAT = 0x29C, + SMSG_STANDSTATE_UPDATE = 0x29D, + SMSG_LOOT_ALL_PASSED = 0x29E, + SMSG_LOOT_ROLL_WON = 0x29F, + CMSG_LOOT_ROLL = 0x2A0, + SMSG_LOOT_START_ROLL = 0x2A1, + SMSG_LOOT_ROLL = 0x2A2, + CMSG_LOOT_MASTER_GIVE = 0x2A3, + SMSG_LOOT_MASTER_LIST = 0x2A4, + SMSG_SET_FORCED_REACTIONS = 0x2A5, + SMSG_SPELL_FAILED_OTHER = 0x2A6, + SMSG_GAMEOBJECT_RESET_STATE = 0x2A7, + CMSG_REPAIR_ITEM = 0x2A8, + SMSG_CHAT_PLAYER_NOT_FOUND = 0x2A9, + MSG_TALENT_WIPE_CONFIRM = 0x2AA, + SMSG_SUMMON_REQUEST = 0x2AB, + CMSG_SUMMON_RESPONSE = 0x2AC, + MSG_MOVE_TOGGLE_GRAVITY_CHEAT = 0x2AD, + SMSG_MONSTER_MOVE_TRANSPORT = 0x2AE, + SMSG_PET_BROKEN = 0x2AF, + MSG_MOVE_FEATHER_FALL = 0x2B0, + MSG_MOVE_WATER_WALK = 0x2B1, + CMSG_SERVER_BROADCAST = 0x2B2, + CMSG_SELF_RES = 0x2B3, + SMSG_FEIGN_DEATH_RESISTED = 0x2B4, + CMSG_RUN_SCRIPT = 0x2B5, + SMSG_SCRIPT_MESSAGE = 0x2B6, + SMSG_DUEL_COUNTDOWN = 0x2B7, + SMSG_AREA_TRIGGER_MESSAGE = 0x2B8, + CMSG_TOGGLE_HELM = 0x2B9, + CMSG_TOGGLE_CLOAK = 0x2BA, + SMSG_MEETINGSTONE_JOINFAILED = 0x2BB, + SMSG_PLAYER_SKINNED = 0x2BC, + SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD, + CMSG_SET_EXPLORATION = 0x2BE, + CMSG_SET_ACTIONBAR_TOGGLES = 0x2BF, + UMSG_DELETE_GUILD_CHARTER = 0x2C0, + MSG_PETITION_RENAME = 0x2C1, + SMSG_INIT_WORLD_STATES = 0x2C2, + SMSG_UPDATE_WORLD_STATE = 0x2C3, + CMSG_ITEM_NAME_QUERY = 0x2C4, + SMSG_ITEM_NAME_QUERY_RESPONSE = 0x2C5, + SMSG_PET_ACTION_FEEDBACK = 0x2C6, + CMSG_CHAR_RENAME = 0x2C7, + SMSG_CHAR_RENAME = 0x2C8, + CMSG_MOVE_SPLINE_DONE = 0x2C9, + CMSG_MOVE_FALL_RESET = 0x2CA, + SMSG_INSTANCE_SAVE_CREATED = 0x2CB, + SMSG_RAID_INSTANCE_INFO = 0x2CC, + CMSG_REQUEST_RAID_INFO = 0x2CD, + CMSG_MOVE_TIME_SKIPPED = 0x2CE, + CMSG_MOVE_FEATHER_FALL_ACK = 0x2CF, + CMSG_MOVE_WATER_WALK_ACK = 0x2D0, + CMSG_MOVE_NOT_ACTIVE_MOVER = 0x2D1, + SMSG_PLAY_SOUND = 0x2D2, + CMSG_BATTLEFIELD_STATUS = 0x2D3, + SMSG_BATTLEFIELD_STATUS = 0x2D4, + CMSG_BATTLEFIELD_PORT = 0x2D5, + MSG_INSPECT_HONOR_STATS = 0x2D6, + CMSG_BATTLEMASTER_HELLO = 0x2D7, + CMSG_MOVE_START_SWIM_CHEAT = 0x2D8, + CMSG_MOVE_STOP_SWIM_CHEAT = 0x2D9, + SMSG_FORCE_WALK_SPEED_CHANGE = 0x2DA, + CMSG_FORCE_WALK_SPEED_CHANGE_ACK = 0x2DB, + SMSG_FORCE_SWIM_BACK_SPEED_CHANGE = 0x2DC, + CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK = 0x2DD, + SMSG_FORCE_TURN_RATE_CHANGE = 0x2DE, + CMSG_FORCE_TURN_RATE_CHANGE_ACK = 0x2DF, + MSG_PVP_LOG_DATA = 0x2E0, + CMSG_LEAVE_BATTLEFIELD = 0x2E1, + CMSG_AREA_SPIRIT_HEALER_QUERY = 0x2E2, + CMSG_AREA_SPIRIT_HEALER_QUEUE = 0x2E3, + SMSG_AREA_SPIRIT_HEALER_TIME = 0x2E4, + CMSG_GM_UNTEACH = 0x2E5, + SMSG_WARDEN_DATA = 0x2E6, + CMSG_WARDEN_DATA = 0x2E7, + SMSG_GROUP_JOINED_BATTLEGROUND = 0x2E8, + MSG_BATTLEGROUND_PLAYER_POSITIONS = 0x2E9, + CMSG_PET_STOP_ATTACK = 0x2EA, + SMSG_BINDER_CONFIRM = 0x2EB, + SMSG_BATTLEGROUND_PLAYER_JOINED = 0x2EC, + SMSG_BATTLEGROUND_PLAYER_LEFT = 0x2ED, + CMSG_BATTLEMASTER_JOIN = 0x2EE, + SMSG_ADDON_INFO = 0x2EF, + CMSG_PET_UNLEARN = 0x2F0, + SMSG_PET_UNLEARN_CONFIRM = 0x2F1, + SMSG_PARTY_MEMBER_STATS_FULL = 0x2F2, + CMSG_PET_SPELL_AUTOCAST = 0x2F3, + SMSG_WEATHER = 0x2F4, + SMSG_PLAY_TIME_WARNING = 0x2F5, + SMSG_MINIGAME_SETUP = 0x2F6, + SMSG_MINIGAME_STATE = 0x2F7, + CMSG_MINIGAME_MOVE = 0x2F8, + SMSG_MINIGAME_MOVE_FAILED = 0x2F9, + SMSG_RAID_INSTANCE_MESSAGE = 0x2FA, + SMSG_COMPRESSED_MOVES = 0x2FB, + CMSG_GUILD_INFO_TEXT = 0x2FC, + SMSG_CHAT_RESTRICTED = 0x2FD, + SMSG_SPLINE_SET_RUN_SPEED = 0x2FE, + SMSG_SPLINE_SET_RUN_BACK_SPEED = 0x2FF, + SMSG_SPLINE_SET_SWIM_SPEED = 0x300, + SMSG_SPLINE_SET_WALK_SPEED = 0x301, + SMSG_SPLINE_SET_SWIM_BACK_SPEED = 0x302, + SMSG_SPLINE_SET_TURN_RATE = 0x303, + SMSG_SPLINE_MOVE_UNROOT = 0x304, + SMSG_SPLINE_MOVE_FEATHER_FALL = 0x305, + SMSG_SPLINE_MOVE_NORMAL_FALL = 0x306, + SMSG_SPLINE_MOVE_SET_HOVER = 0x307, + SMSG_SPLINE_MOVE_UNSET_HOVER = 0x308, + SMSG_SPLINE_MOVE_WATER_WALK = 0x309, + SMSG_SPLINE_MOVE_LAND_WALK = 0x30A, + SMSG_SPLINE_MOVE_START_SWIM = 0x30B, + SMSG_SPLINE_MOVE_STOP_SWIM = 0x30C, + SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x30D, + SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x30E, + CMSG_GM_NUKE_ACCOUNT = 0x30F, + MSG_GM_DESTROY_CORPSE = 0x310, + CMSG_GM_DESTROY_ONLINE_CORPSE = 0x311, + CMSG_ACTIVATETAXIEXPRESS = 0x312, + SMSG_SET_FACTION_ATWAR = 0x313, + SMSG_GAMETIMEBIAS_SET = 0x314, + CMSG_DEBUG_ACTIONS_START = 0x315, + CMSG_DEBUG_ACTIONS_STOP = 0x316, + CMSG_SET_FACTION_INACTIVE = 0x317, + CMSG_SET_WATCHED_FACTION = 0x318, + MSG_MOVE_TIME_SKIPPED = 0x319, + SMSG_SPLINE_MOVE_ROOT = 0x31A, + CMSG_SET_EXPLORATION_ALL = 0x31B, + SMSG_INVALIDATE_PLAYER = 0x31C, + CMSG_RESET_INSTANCES = 0x31D, + SMSG_INSTANCE_RESET = 0x31E, + SMSG_INSTANCE_RESET_FAILED = 0x31F, + SMSG_UPDATE_LAST_INSTANCE = 0x320, + MSG_RAID_TARGET_UPDATE = 0x321, + MSG_RAID_READY_CHECK = 0x322, + CMSG_LUA_USAGE = 0x323, + SMSG_PET_ACTION_SOUND = 0x324, + SMSG_PET_DISMISS_SOUND = 0x325, + SMSG_GHOSTEE_GONE = 0x326, + CMSG_GM_UPDATE_TICKET_STATUS = 0x327, + SMSG_GM_TICKET_STATUS_UPDATE = 0x328, + MSG_SET_DUNGEON_DIFFICULTY = 0x329, + CMSG_GMSURVEY_SUBMIT = 0x32A, + SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x32B, + CMSG_IGNORE_KNOCKBACK_CHEAT = 0x32C, + SMSG_CHAT_PLAYER_AMBIGUOUS = 0x32D, + MSG_DELAY_GHOST_TELEPORT = 0x32E, + SMSG_SPELLINSTAKILLLOG = 0x32F, + SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x330, + CMSG_CHAT_FILTERED = 0x331, + SMSG_EXPECTED_SPAM_RECORDS = 0x332, + SMSG_SPELLSTEALLOG = 0x333, + CMSG_LOTTERY_QUERY_OBSOLETE = 0x334, + SMSG_LOTTERY_QUERY_RESULT_OBSOLETE = 0x335, + CMSG_BUY_LOTTERY_TICKET_OBSOLETE = 0x336, + SMSG_LOTTERY_RESULT_OBSOLETE = 0x337, + SMSG_CHARACTER_PROFILE = 0x338, + SMSG_CHARACTER_PROFILE_REALM_CONNECTED = 0x339, + SMSG_DEFENSE_MESSAGE = 0x33A, + SMSG_INSTANCE_DIFFICULTY = 0x33B, + MSG_GM_RESETINSTANCELIMIT = 0x33C, + SMSG_MOTD = 0x33D, + SMSG_MOVE_SET_FLIGHT_OBSOLETE = 0x33E, + SMSG_MOVE_UNSET_FLIGHT_OBSOLETE = 0x33F, + CMSG_MOVE_FLIGHT_ACK_OBSOLETE = 0x340, + MSG_MOVE_START_SWIM_CHEAT = 0x341, + MSG_MOVE_STOP_SWIM_CHEAT = 0x342, + SMSG_MOVE_SET_CAN_FLY = 0x343, + SMSG_MOVE_UNSET_CAN_FLY = 0x344, + CMSG_MOVE_SET_CAN_FLY_ACK = 0x345, + CMSG_MOVE_SET_FLY = 0x346, + CMSG_SOCKET_GEMS = 0x347, + CMSG_ARENA_TEAM_CREATE = 0x348, + SMSG_ARENA_TEAM_COMMAND_RESULT = 0x349, + UMSG_UPDATE_ARENA_TEAM_OBSOLETE = 0x34A, + CMSG_ARENA_TEAM_QUERY = 0x34B, + SMSG_ARENA_TEAM_QUERY_RESPONSE = 0x34C, + CMSG_ARENA_TEAM_ROSTER = 0x34D, + SMSG_ARENA_TEAM_ROSTER = 0x34E, + CMSG_ARENA_TEAM_INVITE = 0x34F, + SMSG_ARENA_TEAM_INVITE = 0x350, + CMSG_ARENA_TEAM_ACCEPT = 0x351, + CMSG_ARENA_TEAM_DECLINE = 0x352, + CMSG_ARENA_TEAM_LEAVE = 0x353, + CMSG_ARENA_TEAM_REMOVE = 0x354, + CMSG_ARENA_TEAM_DISBAND = 0x355, + CMSG_ARENA_TEAM_LEADER = 0x356, + SMSG_ARENA_TEAM_EVENT = 0x357, + CMSG_BATTLEMASTER_JOIN_ARENA = 0x358, + MSG_MOVE_START_ASCEND = 0x359, + MSG_MOVE_STOP_ASCEND = 0x35A, + SMSG_ARENA_TEAM_STATS = 0x35B, + CMSG_LFG_SET_AUTOJOIN = 0x35C, + CMSG_LFG_CLEAR_AUTOJOIN = 0x35D, + CMSG_LFM_SET_AUTOFILL = 0x35E, + CMSG_LFM_CLEAR_AUTOFILL = 0x35F, + CMSG_ACCEPT_LFG_MATCH = 0x360, + CMSG_DECLINE_LFG_MATCH = 0x361, + CMSG_CANCEL_PENDING_LFG = 0x362, + CMSG_CLEAR_LOOKING_FOR_GROUP = 0x363, + CMSG_CLEAR_LOOKING_FOR_MORE = 0x364, + CMSG_SET_LOOKING_FOR_MORE = 0x365, + CMSG_SET_LFG_COMMENT = 0x366, + SMSG_LFG_TIMEDOUT = 0x367, + SMSG_LFG_OTHER_TIMEDOUT = 0x368, + SMSG_LFG_AUTOJOIN_FAILED = 0x369, + SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER = 0x36A, + SMSG_LFG_LEADER_IS_LFM = 0x36B, + SMSG_LFG_UPDATE = 0x36C, + SMSG_LFG_UPDATE_LFM = 0x36D, + SMSG_LFG_UPDATE_LFG = 0x36E, + SMSG_LFG_UPDATE_QUEUED = 0x36F, + SMSG_LFG_PENDING_INVITE = 0x370, + SMSG_LFG_PENDING_MATCH = 0x371, + SMSG_LFG_PENDING_MATCH_DONE = 0x372, + SMSG_TITLE_EARNED = 0x373, + CMSG_SET_TITLE = 0x374, + CMSG_CANCEL_MOUNT_AURA = 0x375, + SMSG_ARENA_ERROR = 0x376, + MSG_INSPECT_ARENA_TEAMS = 0x377, + SMSG_DEATH_RELEASE_LOC = 0x378, + CMSG_CANCEL_TEMP_ENCHANTMENT = 0x379, + SMSG_FORCED_DEATH_UPDATE = 0x37A, + CMSG_CHEAT_SET_HONOR_CURRENCY = 0x37B, + CMSG_CHEAT_SET_ARENA_CURRENCY = 0x37C, + MSG_MOVE_SET_FLIGHT_SPEED_CHEAT = 0x37D, + MSG_MOVE_SET_FLIGHT_SPEED = 0x37E, + MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT = 0x37F, + MSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x380, + SMSG_FORCE_FLIGHT_SPEED_CHANGE = 0x381, + CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0x382, + SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE = 0x383, + CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK = 0x384, + SMSG_SPLINE_SET_FLIGHT_SPEED = 0x385, + SMSG_SPLINE_SET_FLIGHT_BACK_SPEED = 0x386, + CMSG_MAELSTROM_INVALIDATE_CACHE = 0x387, + SMSG_FLIGHT_SPLINE_SYNC = 0x388, + CMSG_SET_TAXI_BENCHMARK_MODE = 0x389, + SMSG_JOINED_BATTLEGROUND_QUEUE = 0x38A, + SMSG_REALM_SPLIT = 0x38B, + CMSG_REALM_SPLIT = 0x38C, + CMSG_MOVE_CHNG_TRANSPORT = 0x38D, + MSG_PARTY_ASSIGNMENT = 0x38E, + SMSG_OFFER_PETITION_ERROR = 0x38F, + SMSG_TIME_SYNC_REQ = 0x390, + CMSG_TIME_SYNC_RESP = 0x391, + CMSG_SEND_LOCAL_EVENT = 0x392, + CMSG_SEND_GENERAL_TRIGGER = 0x393, + CMSG_SEND_COMBAT_TRIGGER = 0x394, + CMSG_MAELSTROM_GM_SENT_MAIL = 0x395, + SMSG_RESET_FAILED_NOTIFY = 0x396, + SMSG_REAL_GROUP_UPDATE = 0x397, + SMSG_LFG_DISABLED = 0x398, + CMSG_ACTIVE_PVP_CHEAT = 0x399, + CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY = 0x39A, + SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE = 0x39B, + SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE = 0x39C, + SMSG_UPDATE_COMBO_POINTS = 0x39D, + SMSG_VOICE_SESSION_ROSTER_UPDATE = 0x39E, + SMSG_VOICE_SESSION_LEAVE = 0x39F, + SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0, + CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1, + SMSG_VOICE_SET_TALKER_MUTED = 0x3A2, + SMSG_INIT_EXTRA_AURA_INFO = 0x3A3, + SMSG_SET_EXTRA_AURA_INFO = 0x3A4, + SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE = 0x3A5, + SMSG_CLEAR_EXTRA_AURA_INFO = 0x3A6, + MSG_MOVE_START_DESCEND = 0x3A7, + CMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A8, + SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A9, + SMSG_SPELL_CHANCE_PROC_LOG = 0x3AA, + CMSG_MOVE_SET_RUN_SPEED = 0x3AB, + SMSG_DISMOUNT = 0x3AC, + MSG_MOVE_UPDATE_CAN_FLY = 0x3AD, + MSG_RAID_READY_CHECK_CONFIRM = 0x3AE, + CMSG_VOICE_SESSION_ENABLE = 0x3AF, + SMSG_VOICE_PARENTAL_CONTROLS = 0x3B0, + CMSG_GM_WHISPER = 0x3B1, + SMSG_GM_MESSAGECHAT = 0x3B2, + MSG_GM_GEARRATING = 0x3B3, + CMSG_COMMENTATOR_ENABLE = 0x3B4, + SMSG_COMMENTATOR_STATE_CHANGED = 0x3B5, + CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B6, + SMSG_COMMENTATOR_MAP_INFO = 0x3B7, + CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B8, + SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9, + SMSG_COMMENTATOR_PLAYER_INFO = 0x3BA, + CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BB, + CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BC, + CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BD, + SMSG_CLEAR_TARGET = 0x3BE, + CMSG_BOT_DETECTED = 0x3BF, + SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C0, + CMSG_CHEAT_PLAYER_LOGIN = 0x3C1, + CMSG_CHEAT_PLAYER_LOOKUP = 0x3C2, + SMSG_CHEAT_PLAYER_LOOKUP = 0x3C3, + SMSG_KICK_REASON = 0x3C4, + MSG_RAID_READY_CHECK_FINISHED = 0x3C5, + CMSG_COMPLAIN = 0x3C6, + SMSG_COMPLAIN_RESULT = 0x3C7, + SMSG_FEATURE_SYSTEM_STATUS = 0x3C8, + CMSG_GM_SHOW_COMPLAINTS = 0x3C9, + CMSG_GM_UNSQUELCH = 0x3CA, + CMSG_CHANNEL_SILENCE_VOICE = 0x3CB, + CMSG_CHANNEL_SILENCE_ALL = 0x3CC, + CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CD, + CMSG_CHANNEL_UNSILENCE_ALL = 0x3CE, + CMSG_TARGET_CAST = 0x3CF, + CMSG_TARGET_SCRIPT_CAST = 0x3D0, + CMSG_CHANNEL_DISPLAY_LIST = 0x3D1, + CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D2, + CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D3, + SMSG_CHANNEL_MEMBER_COUNT = 0x3D4, + CMSG_CHANNEL_VOICE_ON = 0x3D5, + CMSG_CHANNEL_VOICE_OFF = 0x3D6, + CMSG_DEBUG_LIST_TARGETS = 0x3D7, + SMSG_DEBUG_LIST_TARGETS = 0x3D8, + SMSG_AVAILABLE_VOICE_CHANNEL = 0x3D9, + CMSG_ADD_VOICE_IGNORE = 0x3DA, + CMSG_DEL_VOICE_IGNORE = 0x3DB, + CMSG_PARTY_SILENCE = 0x3DC, + CMSG_PARTY_UNSILENCE = 0x3DD, + MSG_NOTIFY_PARTY_SQUELCH = 0x3DE, + SMSG_COMSAT_RECONNECT_TRY = 0x3DF, + SMSG_COMSAT_DISCONNECT = 0x3E0, + SMSG_COMSAT_CONNECT_FAIL = 0x3E1, + SMSG_VOICE_CHAT_STATUS = 0x3E2, + CMSG_REPORT_PVP_AFK = 0x3E3, + CMSG_REPORT_PVP_AFK_RESULT = 0x3E4, + CMSG_GUILD_BANKER_ACTIVATE = 0x3E5, + CMSG_GUILD_BANK_QUERY_TAB = 0x3E6, + SMSG_GUILD_BANK_LIST = 0x3E7, + CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E8, + CMSG_GUILD_BANK_BUY_TAB = 0x3E9, + CMSG_GUILD_BANK_UPDATE_TAB = 0x3EA, + CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EB, + CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3EC, + MSG_GUILD_BANK_LOG_QUERY = 0x3ED, + CMSG_SET_CHANNEL_WATCH = 0x3EE, + SMSG_USERLIST_ADD = 0x3EF, + SMSG_USERLIST_REMOVE = 0x3F0, + SMSG_USERLIST_UPDATE = 0x3F1, + CMSG_CLEAR_CHANNEL_WATCH = 0x3F2, + SMSG_INSPECT_TALENT = 0x3F3, + SMSG_GOGOGO_OBSOLETE = 0x3F4, + SMSG_ECHO_PARTY_SQUELCH = 0x3F5, + CMSG_SET_TITLE_SUFFIX = 0x3F6, + CMSG_SPELLCLICK = 0x3F7, + SMSG_LOOT_LIST = 0x3F8, + CMSG_GM_CHARACTER_RESTORE = 0x3F9, + CMSG_GM_CHARACTER_SAVE = 0x3FA, + SMSG_VOICESESSION_FULL = 0x3FB, + MSG_GUILD_PERMISSIONS = 0x3FC, + MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FD, + MSG_GUILD_EVENT_LOG_QUERY = 0x3FE, + CMSG_MAELSTROM_RENAME_GUILD = 0x3FF, + CMSG_GET_MIRRORIMAGE_DATA = 0x400, + SMSG_MIRRORIMAGE_DATA = 0x401, + SMSG_FORCE_DISPLAY_UPDATE = 0x402, + SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x403, + CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x404, + SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405, + CMSG_KEEP_ALIVE = 0x406, + SMSG_RAID_READY_CHECK_ERROR = 0x407, + CMSG_OPT_OUT_OF_LOOT = 0x408, + MSG_QUERY_GUILD_BANK_TEXT = 0x409, + CMSG_SET_GUILD_BANK_TEXT = 0x40A, + CMSG_SET_GRANTABLE_LEVELS = 0x40B, + CMSG_GRANT_LEVEL = 0x40C, + CMSG_REFER_A_FRIEND = 0x40D, + MSG_GM_CHANGE_ARENA_RATING = 0x40E, + CMSG_DECLINE_CHANNEL_INVITE = 0x40F, + CMSG_GROUPACTION_THROTTLED = 0x410, + SMSG_OVERRIDE_LIGHT = 0x411, + SMSG_TOTEM_CREATED = 0x412, + CMSG_TOTEM_DESTROYED = 0x413, + CMSG_EXPIRE_RAID_INSTANCE = 0x414, + CMSG_NO_SPELL_VARIANCE = 0x415, + CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x416, + SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x417, + CMSG_SET_PLAYER_DECLINED_NAMES = 0x418, + SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x419, + CMSG_QUERY_SERVER_BUCK_DATA = 0x41A, + CMSG_CLEAR_SERVER_BUCK_DATA = 0x41B, + SMSG_SERVER_BUCK_DATA = 0x41C, + SMSG_SEND_UNLEARN_SPELLS = 0x41D, + SMSG_PROPOSE_LEVEL_GRANT = 0x41E, + CMSG_ACCEPT_LEVEL_GRANT = 0x41F, + SMSG_REFER_A_FRIEND_FAILURE = 0x420, + SMSG_SPLINE_MOVE_SET_FLYING = 0x421, + SMSG_SPLINE_MOVE_UNSET_FLYING = 0x422, + SMSG_SUMMON_CANCEL = 0x423 +}; + +// Don't forget to change this value and add opcode name to Opcodes.cpp when you add new opcode! +#define NUM_MSG_TYPES 0x424 + +/// Player state +enum SessionStatus +{ + STATUS_AUTHED = 0, ///< Player authenticated + STATUS_LOGGEDIN, ///< Player in game + STATUS_TRANSFER_PENDING, ///< Player transferring to another map + STATUS_NEVER ///< Opcode not accepted from client (deprecated or server side only) +}; + +class WorldSession; +class WorldPacket; + +struct OpcodeHandler +{ + char const* name; + SessionStatus status; + void (WorldSession::*handler)(WorldPacket& recvPacket); +}; + +extern OpcodeHandler opcodeTable[NUM_MSG_TYPES]; + +/// Lookup opcode name for human understandable logging +inline const char* LookupOpcodeName(uint16 id) +{ + if (id >= NUM_MSG_TYPES) + return "Received unknown opcode, it's more than max!"; + return opcodeTable[id].name; +} +#endif +/// @} diff --git a/src/game/Path.h b/src/game/Path.h new file mode 100644 index 000000000..71564dada --- /dev/null +++ b/src/game/Path.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_PATH_H +#define MANGOSSERVER_PATH_H + +#include "Common.h" +#include + +class Path +{ + public: + struct PathNode + { + float x,y,z; + }; + + void SetLength(const unsigned int sz) + { + i_nodes.resize( sz ); + } + + unsigned int Size() const { return i_nodes.size(); } + bool Empty() const { return i_nodes.empty(); } + void Resize(unsigned int sz) { i_nodes.resize(sz); } + void Clear(void) { i_nodes.clear(); } + PathNode const* GetNodes(uint32 start = 0) const { return &i_nodes[start]; } + float GetTotalLength() const { return GetTotalLength(0,Size()); } + float GetTotalLength(uint32 start, uint32 end) const + { + float len = 0, xd, yd, zd; + for(unsigned int idx=start+1; idx < end; ++idx) + { + xd = i_nodes[ idx ].x - i_nodes[ idx-1 ].x; + yd = i_nodes[ idx ].y - i_nodes[ idx-1 ].y; + zd = i_nodes[ idx ].z - i_nodes[ idx-1 ].z; + len += sqrtf( xd*xd + yd*yd + zd*zd ); + } + return len; + } + + float GetPassedLength(uint32 curnode, float x, float y, float z) + { + float len = 0, xd, yd, zd; + for(unsigned int idx=1; idx < curnode; ++idx) + { + xd = i_nodes[ idx ].x - i_nodes[ idx-1 ].x; + yd = i_nodes[ idx ].y - i_nodes[ idx-1 ].y; + zd = i_nodes[ idx ].z - i_nodes[ idx-1 ].z; + len += sqrtf( xd*xd + yd*yd + zd*zd ); + } + + if(curnode > 0) + { + xd = x - i_nodes[curnode-1].x; + yd = y - i_nodes[curnode-1].y; + zd = z - i_nodes[curnode-1].z; + len += sqrtf( xd*xd + yd*yd + zd*zd ); + } + + return len; + } + + PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; } + const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; } + + protected: + std::vector i_nodes; +}; +#endif diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp new file mode 100644 index 000000000..caa129746 --- /dev/null +++ b/src/game/Pet.cpp @@ -0,0 +1,1750 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "WorldSession.h" +#include "WorldPacket.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Pet.h" +#include "MapManager.h" +#include "Formulas.h" +#include "SpellAuras.h" +#include "CreatureAI.h" +#include "Unit.h" +#include "Util.h" + +char const* petTypeSuffix[MAX_PET_TYPE] = +{ + "'s Minion", // SUMMON_PET + "'s Pet", // HUNTER_PET + "'s Guardian", // GUARDIAN_PET + "'s Companion" // MINI_PET +}; + +//numbers represent minutes * 100 while happy (you get 100 loyalty points per min while happy) +uint32 const LevelUpLoyalty[6] = +{ + 5500, + 11500, + 17000, + 23500, + 31000, + 39500, +}; + +uint32 const LevelStartLoyalty[6] = +{ + 2000, + 4500, + 7000, + 10000, + 13500, + 17500, +}; + +Pet::Pet(PetType type) : Creature() +{ + m_isPet = true; + m_name = "Pet"; + m_petType = type; + + m_removed = false; + m_regenTimer = 4000; + m_happinessTimer = 7500; + m_loyaltyTimer = 12000; + m_duration = 0; + m_bonusdamage = 0; + + m_loyaltyPoints = 0; + m_TrainingPoints = 0; + m_resetTalentsCost = 0; + m_resetTalentsTime = 0; + + m_auraUpdateMask = 0; + + // pets always have a charminfo, even if they are not actually charmed + CharmInfo* charmInfo = InitCharmInfo(this); + + if(type == MINI_PET) // always passive + charmInfo->SetReactState(REACT_PASSIVE); + else if(type == GUARDIAN_PET) // always aggressive + charmInfo->SetReactState(REACT_AGGRESSIVE); + + m_spells.clear(); + m_Auras.clear(); + m_CreatureSpellCooldowns.clear(); + m_CreatureCategoryCooldowns.clear(); + m_autospells.clear(); + m_declinedname = NULL; +} + +Pet::~Pet() +{ + if(m_uint32Values) // only for fully created Object + { + for (PetSpellMap::iterator i = m_spells.begin(); i != m_spells.end(); ++i) + delete i->second; + ObjectAccessor::Instance().RemoveObject(this); + } + + delete m_declinedname; +} + +void Pet::AddToWorld() +{ + ///- Register the pet for guid lookup + if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + Unit::AddToWorld(); +} + +void Pet::RemoveFromWorld() +{ + ///- Remove the pet from the accessor + if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + ///- Don't call the function for Creature, normal mobs + totems go in a different storage + Unit::RemoveFromWorld(); +} + +bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current ) +{ + uint32 ownerid = owner->GetGUIDLow(); + + QueryResult *result; + + if(petnumber) + // known petnumber entry 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber); + else if(current) + // current pet (slot 0) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid ); + else if(petentry) + // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry ); + else + // any current or other non-stabled pet (for hunter "call pet") + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid); + + if(!result) + return false; + + Field *fields = result->Fetch(); + + // update for case of current pet "slot = 0" + petentry = fields[1].GetUInt32(); + if(!petentry) + { + delete result; + return false; + } + + uint32 summon_spell_id = fields[21].GetUInt32(); + SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id); + + bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0; + + // check temporary summoned pets like mage water elemental + if(current && is_temporary_summoned) + { + delete result; + return false; + } + + Map *map = owner->GetMap(); + uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET); + uint32 pet_number = fields[0].GetUInt32(); + if(!Create(guid, map, petentry, pet_number)) + { + delete result; + return false; + } + + float px, py, pz; + owner->GetClosePoint(px, py, pz,GetObjectSize(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); + + Relocate(px, py, pz, owner->GetOrientation()); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %d Y: ^%d)", GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); + delete result; + return false; + } + + setPetType(PetType(fields[22].GetUInt8())); + SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction()); + SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id); + + CreatureInfo const *cinfo = GetCreatureInfo(); + if(cinfo->type == CREATURE_TYPE_CRITTER) + { + AIM_Initialize(); + map->Add((Creature*)this); + delete result; + return true; + } + if(getPetType()==HUNTER_PET || getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK) + m_charmInfo->SetPetNumber(pet_number, true); + else + m_charmInfo->SetPetNumber(pet_number, false); + SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()); + SetDisplayId(fields[3].GetUInt32()); + SetNativeDisplayId(fields[3].GetUInt32()); + uint32 petlevel=fields[4].GetUInt32(); + SetUInt32Value(UNIT_NPC_FLAGS , 0); + SetName(fields[11].GetString()); + + switch(getPetType()) + { + + case SUMMON_PET: + petlevel=owner->getLevel(); + + SetUInt32Value(UNIT_FIELD_BYTES_0,2048); + SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + // this enables popup window (pet dismiss, cancel) + break; + case HUNTER_PET: + SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); + SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[8].GetUInt32()); + SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); + + if(fields[12].GetBool()) + SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED); + else + SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); + + SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + // this enables popup window (pet abandon, cancel) + SetTP(fields[9].GetInt32()); + SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); + SetPower( POWER_HAPPINESS,fields[15].GetUInt32()); + setPowerType(POWER_FOCUS); + break; + default: + sLog.outError("Pet have incorrect type (%u) for pet loading.",getPetType()); + } + InitStatsForLevel( petlevel); + SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); + SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32()); + SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID()); + + m_charmInfo->SetReactState( ReactStates( fields[6].GetUInt8() )); + m_loyaltyPoints = fields[7].GetInt32(); + + uint32 savedhealth = fields[13].GetUInt32(); + uint32 savedmana = fields[14].GetUInt32(); + + // set current pet as current + if(fields[10].GetUInt32() != 0) + { + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'",ownerid, m_charmInfo->GetPetNumber()); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'",ownerid, m_charmInfo->GetPetNumber()); + CharacterDatabase.CommitTransaction(); + } + + if(!is_temporary_summoned) + { + // permanent controlled pets store state in DB + Tokens tokens = StrSplit(fields[16].GetString(), " "); + + if(tokens.size() != 20) + { + delete result; + return false; + } + + int index; + Tokens::iterator iter; + for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index ) + { + m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str()); + ++iter; + m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str()); + } + + //init teach spells + tokens = StrSplit(fields[17].GetString(), " "); + for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index) + { + uint32 tmp = atol((*iter).c_str()); + + ++iter; + + if(tmp) + AddTeachSpell(tmp, atol((*iter).c_str())); + else + break; + } + } + + // since last save (in seconds) + uint32 timediff = (time(NULL) - fields[18].GetUInt32()); + + delete result; + + //load spells/cooldowns/auras + SetCanModifyStats(true); + _LoadAuras(timediff); + + //init AB + if(is_temporary_summoned) + { + // Temporary summoned pets always have initial spell list at load + InitPetCreateSpells(); + } + else + { + LearnPetPassives(); + CastPetAuras(current); + } + + if(getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current + { + SetHealth(GetMaxHealth()); + SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); + } + else + { + SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); + SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); + } + + AIM_Initialize(); + map->Add((Creature*)this); + + // Spells should be loaded after pet is added to map, because in CanCast is check on it + _LoadSpells(); + _LoadSpellCooldowns(); + + owner->SetPet(this); // in DB stored only full controlled creature + sLog.outDebug("New Pet has guid %u", GetGUIDLow()); + + if(owner->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)owner)->PetSpellInitialize(); + if(((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_PET); + } + + if(owner->GetTypeId() == TYPEID_PLAYER && getPetType() == HUNTER_PET) + { + result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'",owner->GetGUIDLow(),GetCharmInfo()->GetPetNumber()); + + if(result) + { + if(m_declinedname) + delete m_declinedname; + + m_declinedname = new DeclinedName; + Field *fields = result->Fetch(); + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + { + m_declinedname->name[i] = fields[i].GetCppString(); + } + } + } + + return true; +} + +void Pet::SavePetToDB(PetSaveMode mode) +{ + if(!GetEntry()) + return; + + // save only fully controlled creature + if(!isControlled()) + return; + + uint32 curhealth = GetHealth(); + uint32 curmana = GetPower(POWER_MANA); + + switch(mode) + { + case PET_SAVE_IN_STABLE_SLOT_1: + case PET_SAVE_IN_STABLE_SLOT_2: + case PET_SAVE_NOT_IN_SLOT: + { + RemoveAllAuras(); + + //only alive hunter pets get auras saved, the others don't + if(!(getPetType() == HUNTER_PET && isAlive())) + m_Auras.clear(); + } + default: + break; + } + + _SaveSpells(); + _SaveSpellCooldowns(); + _SaveAuras(); + + switch(mode) + { + case PET_SAVE_AS_CURRENT: + case PET_SAVE_IN_STABLE_SLOT_1: + case PET_SAVE_IN_STABLE_SLOT_2: + case PET_SAVE_NOT_IN_SLOT: + { + uint32 loyalty =1; + if(getPetType()!=HUNTER_PET) + loyalty = GetLoyaltyLevel(); + + uint32 owner = GUID_LOPART(GetOwnerGUID()); + std::string name = m_name; + CharacterDatabase.escape_string(name); + CharacterDatabase.BeginTransaction(); + // remove current data + CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber() ); + + // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT) + if(mode!=PET_SAVE_NOT_IN_SLOT) + CharacterDatabase.PExecute("UPDATE character_pet SET slot = 3 WHERE owner = '%u' AND slot = '%u'", owner, uint32(mode) ); + + // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT + if(getPetType()==HUNTER_PET && (mode==PET_SAVE_AS_CURRENT||mode==PET_SAVE_NOT_IN_SLOT)) + CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner ); + // save pet + std::ostringstream ss; + ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata,TeachSpelldata,savetime,resettalents_cost,resettalents_time,CreatedBySpell,PetType) " + << "VALUES (" + << m_charmInfo->GetPetNumber() << ", " + << GetEntry() << ", " + << owner << ", " + << GetNativeDisplayId() << ", " + << getLevel() << ", " + << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", " + << uint32(m_charmInfo->GetReactState()) << ", " + << m_loyaltyPoints << ", " + << GetLoyaltyLevel() << ", " + << m_TrainingPoints << ", " + << uint32(mode) << ", '" + << name.c_str() << "', " + << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", " + << (curhealth<1?1:curhealth) << ", " + << curmana << ", " + << GetPower(POWER_HAPPINESS) << ", '"; + + for(uint32 i = 0; i < 10; i++) + ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " "; + ss << "', '"; + + //save spells the pet can teach to it's Master + { + int i = 0; + for(TeachSpellMap::iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr) + ss << itr->first << " " << itr->second << " "; + for(; i < 4; ++i) + ss << uint32(0) << " " << uint32(0) << " "; + } + + ss << "', " + << time(NULL) << ", " + << uint32(m_resetTalentsCost) << ", " + << uint64(m_resetTalentsTime) << ", " + << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", " + << uint32(getPetType()) << ")"; + + CharacterDatabase.Execute( ss.str().c_str() ); + + CharacterDatabase.CommitTransaction(); + break; + } + case PET_SAVE_AS_DELETED: + { + RemoveAllAuras(); + uint32 owner = GUID_LOPART(GetOwnerGUID()); + DeleteFromDB(m_charmInfo->GetPetNumber()); + break; + } + default: + sLog.outError("Unknown pet save/remove mode: %d",mode); + } +} + +void Pet::DeleteFromDB(uint32 guidlow) +{ + CharacterDatabase.PExecute("DELETE FROM character_pet WHERE id = '%u'", guidlow); + CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow); + CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", guidlow); + CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'", guidlow); + CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow); +} + +void Pet::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState +{ + Creature::setDeathState(s); + if(getDeathState()==CORPSE) + { + //remove summoned pet (no corpse) + if(getPetType()==SUMMON_PET) + Remove(PET_SAVE_NOT_IN_SLOT); + // other will despawn at corpse desppawning (Pet::Update code) + else + { + // pet corpse non lootable and non skinnable + SetUInt32Value( UNIT_DYNAMIC_FLAGS, 0x00 ); + RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + + //lose happiness when died and not in BG/Arena + MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId()); + if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND)) + ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE); + + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + } + } + else if(getDeathState()==ALIVE) + { + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + CastPetAuras(true); + } +} + +void Pet::Update(uint32 diff) +{ + if(m_removed) // pet already removed, just wait in remove queue, no updates + return; + + switch( m_deathState ) + { + case CORPSE: + { + if( m_deathTimer <= diff ) + { + assert(getPetType()!=SUMMON_PET && "Must be already removed."); + Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER! + return; + } + break; + } + case ALIVE: + { + // unsummon pet that lost owner + Unit* owner = GetOwner(); + if(!owner || !IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) || isControlled() && !owner->GetPetGUID()) + { + Remove(PET_SAVE_NOT_IN_SLOT, true); + return; + } + + if(isControlled()) + { + if( owner->GetPetGUID() != GetGUID() ) + { + Remove(getPetType()==HUNTER_PET?PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT); + return; + } + } + + if(m_duration > 0) + { + if(m_duration > diff) + m_duration -= diff; + else + { + Remove(getPetType() != SUMMON_PET ? PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT); + return; + } + } + + if(getPetType() != HUNTER_PET) + break; + + //regenerate Focus + if(m_regenTimer <= diff) + { + RegenerateFocus(); + m_regenTimer = 4000; + } + else + m_regenTimer -= diff; + + if(m_happinessTimer <= diff) + { + LooseHappiness(); + m_happinessTimer = 7500; + } + else + m_happinessTimer -= diff; + + if(m_loyaltyTimer <= diff) + { + TickLoyaltyChange(); + m_loyaltyTimer = 12000; + } + else + m_loyaltyTimer -= diff; + + break; + } + default: + break; + } + Creature::Update(diff); +} + +void Pet::RegenerateFocus() +{ + uint32 curValue = GetPower(POWER_FOCUS); + uint32 maxValue = GetMaxPower(POWER_FOCUS); + + if (curValue >= maxValue) + return; + + float addvalue = 24 * sWorld.getRate(RATE_POWER_FOCUS); + + AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT); + for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue == POWER_FOCUS) + addvalue *= ((*i)->GetModifier()->m_amount + 100) / 100.0f; + + ModifyPower(POWER_FOCUS, (int32)addvalue); +} + +void Pet::LooseHappiness() +{ + uint32 curValue = GetPower(POWER_HAPPINESS); + if (curValue <= 0) + return; + int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs) + if(isInCombat()) //we know in combat happiness fades faster, multiplier guess + addvalue = int32(addvalue * 1.5); + ModifyPower(POWER_HAPPINESS, -addvalue); +} + +void Pet::ModifyLoyalty(int32 addvalue) +{ + uint32 loyaltylevel = GetLoyaltyLevel(); + + if(addvalue > 0) //only gain influenced, not loss + addvalue = int32((float)addvalue * sWorld.getRate(RATE_LOYALTY)); + + if(loyaltylevel >= BEST_FRIEND && (addvalue + m_loyaltyPoints) > int32(GetMaxLoyaltyPoints(loyaltylevel))) + return; + + m_loyaltyPoints += addvalue; + + if(m_loyaltyPoints < 0) + { + if(loyaltylevel > REBELLIOUS) + { + //level down + --loyaltylevel; + SetLoyaltyLevel(LoyaltyLevel(loyaltylevel)); + m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel); + SetTP(m_TrainingPoints - int32(getLevel())); + } + else + { + m_loyaltyPoints = 0; + Unit* owner = GetOwner(); + if(owner && owner->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_PET_BROKEN, 0); + ((Player*)owner)->GetSession()->SendPacket(&data); + + //run away + ((Player*)owner)->RemovePet(this,PET_SAVE_AS_DELETED); + } + } + } + //level up + else if(m_loyaltyPoints > int32(GetMaxLoyaltyPoints(loyaltylevel))) + { + ++loyaltylevel; + SetLoyaltyLevel(LoyaltyLevel(loyaltylevel)); + m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel); + SetTP(m_TrainingPoints + getLevel()); + } +} + +void Pet::TickLoyaltyChange() +{ + int32 addvalue; + + switch(GetHappinessState()) + { + case HAPPY: addvalue = 20; break; + case CONTENT: addvalue = 10; break; + case UNHAPPY: addvalue = -20; break; + default: + return; + } + ModifyLoyalty(addvalue); +} + +void Pet::KillLoyaltyBonus(uint32 level) +{ + if(level > 100) + return; + + //at lower levels gain is faster | the lower loyalty the more loyalty is gained + uint32 bonus = uint32(((100 - level) / 10) + (6 - GetLoyaltyLevel())); + ModifyLoyalty(bonus); +} + +HappinessState Pet::GetHappinessState() +{ + if(GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE) + return UNHAPPY; + else if(GetPower(POWER_HAPPINESS) >= HAPPINESS_LEVEL_SIZE * 2) + return HAPPY; + else + return CONTENT; +} + +void Pet::SetLoyaltyLevel(LoyaltyLevel level) +{ + SetByteValue(UNIT_FIELD_BYTES_1, 1, level); +} + +bool Pet::CanTakeMoreActiveSpells(uint32 spellid) +{ + uint8 activecount = 1; + uint32 chainstartstore[ACTIVE_SPELLS_MAX]; + + if(IsPassiveSpell(spellid)) + return true; + + chainstartstore[0] = spellmgr.GetFirstSpellInChain(spellid); + + for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(IsPassiveSpell(itr->first)) + continue; + + uint32 chainstart = spellmgr.GetFirstSpellInChain(itr->first); + + uint8 x; + + for(x = 0; x < activecount; x++) + { + if(chainstart == chainstartstore[x]) + break; + } + + if(x == activecount) //spellchain not yet saved -> add active count + { + ++activecount; + if(activecount > ACTIVE_SPELLS_MAX) + return false; + chainstartstore[x] = chainstart; + } + } + return true; +} + +bool Pet::HasTPForSpell(uint32 spellid) +{ + int32 neededtrainp = GetTPForSpell(spellid); + if((m_TrainingPoints - neededtrainp < 0 || neededtrainp < 0) && neededtrainp != 0) + return false; + return true; +} + +int32 Pet::GetTPForSpell(uint32 spellid) +{ + uint32 basetrainp = 0; + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid); + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + if(!_spell_idx->second->reqtrainpoints) + return 0; + + basetrainp = _spell_idx->second->reqtrainpoints; + break; + } + + uint32 spenttrainp = 0; + uint32 chainstart = spellmgr.GetFirstSpellInChain(spellid); + + for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + + if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) + { + SkillLineAbilityMap::const_iterator _lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first); + SkillLineAbilityMap::const_iterator _upper = spellmgr.GetEndSkillLineAbilityMap(itr->first); + + for(SkillLineAbilityMap::const_iterator _spell_idx2 = _lower; _spell_idx2 != _upper; ++_spell_idx2) + { + if(_spell_idx2->second->reqtrainpoints > spenttrainp) + { + spenttrainp = _spell_idx2->second->reqtrainpoints; + break; + } + } + } + } + + return int32(basetrainp) - int32(spenttrainp); +} + +uint32 Pet::GetMaxLoyaltyPoints(uint32 level) +{ + return LevelUpLoyalty[level - 1]; +} + +uint32 Pet::GetStartLoyaltyPoints(uint32 level) +{ + return LevelStartLoyalty[level - 1]; +} + +void Pet::SetTP(int32 TP) +{ + m_TrainingPoints = TP; + SetUInt32Value(UNIT_TRAINING_POINTS, (uint32)GetDispTP()); +} + +int32 Pet::GetDispTP() +{ + if(getPetType()!= HUNTER_PET) + return(0); + if(m_TrainingPoints < 0) + return -m_TrainingPoints; + else + return -(m_TrainingPoints + 1); +} + +void Pet::Remove(PetSaveMode mode, bool returnreagent) +{ + Unit* owner = GetOwner(); + + if(owner) + { + if(owner->GetTypeId()==TYPEID_PLAYER) + { + ((Player*)owner)->RemovePet(this,mode,returnreagent); + return; + } + + // only if current pet in slot + if(owner->GetPetGUID()==GetGUID()) + owner->SetPet(0); + } + + CleanupsBeforeDelete(); + AddObjectToRemoveList(); + m_removed = true; +} + +void Pet::GivePetXP(uint32 xp) +{ + if(getPetType() != HUNTER_PET) + return; + + if ( xp < 1 ) + return; + + if(!isAlive()) + return; + + uint32 level = getLevel(); + + // XP to money conversion processed in Player::RewardQuest + if(level >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + return; + + uint32 curXP = GetUInt32Value(UNIT_FIELD_PETEXPERIENCE); + uint32 nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP); + uint32 newXP = curXP + xp; + + if(newXP >= nextLvlXP && level+1 > GetOwner()->getLevel()) + { + SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, nextLvlXP-1); + return; + } + + while( newXP >= nextLvlXP && level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) + { + newXP -= nextLvlXP; + + SetLevel( level + 1 ); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(level+1))/4)); + + level = getLevel(); + nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP); + GivePetLevel(level); + } + + SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP); + + if(getPetType() == HUNTER_PET) + KillLoyaltyBonus(level); +} + +void Pet::GivePetLevel(uint32 level) +{ + if(!level) + return; + + InitStatsForLevel( level); + + SetTP(m_TrainingPoints + (GetLoyaltyLevel() - 1)); +} + +bool Pet::CreateBaseAtCreature(Creature* creature) +{ + if(!creature) + { + sLog.outError("CRITICAL ERROR: NULL pointer parsed into CreateBaseAtCreature()"); + return false; + } + uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET); + + sLog.outBasic("SetInstanceID()"); + SetInstanceId(creature->GetInstanceId()); + + sLog.outBasic("Create pet"); + uint32 pet_number = objmgr.GeneratePetNumber(); + if(!Create(guid, creature->GetMap(), creature->GetEntry(), pet_number)) + return false; + + Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %d Y: ^%d)", GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); + return false; + } + + CreatureInfo const *cinfo = GetCreatureInfo(); + if(!cinfo) + { + sLog.outError("ERROR: CreateBaseAtCreature() failed, creatureInfo is missing!"); + return false; + } + + if(cinfo->type == CREATURE_TYPE_CRITTER) + { + setPetType(MINI_PET); + return true; + } + SetDisplayId(creature->GetDisplayId()); + SetNativeDisplayId(creature->GetNativeDisplayId()); + SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); + SetPower( POWER_HAPPINESS,166500); + setPowerType(POWER_FOCUS); + SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); + SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(creature->getLevel()))/4)); + SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + SetUInt32Value(UNIT_NPC_FLAGS , 0); + + CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family); + if( char* familyname = cFamily->Name[sWorld.GetDefaultDbcLocale()] ) + SetName(familyname); + else + SetName(creature->GetName()); + + m_loyaltyPoints = 1000; + if(cinfo->type == CREATURE_TYPE_BEAST) + { + SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); + SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); + SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); + + SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) ); + SetLoyaltyLevel(REBELLIOUS); + } + return true; +} + +bool Pet::InitStatsForLevel(uint32 petlevel) +{ + CreatureInfo const *cinfo = GetCreatureInfo(); + assert(cinfo); + + Unit* owner = GetOwner(); + if(!owner) + { + sLog.outError("ERROR: attempt to summon pet (Entry %u) without owner! Attempt terminated.", cinfo->Entry); + return false; + } + + uint32 creature_ID = (getPetType() == HUNTER_PET) ? 1 : cinfo->Entry; + + SetLevel( petlevel); + + SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); + + SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel*50)); + + SetAttackTime(BASE_ATTACK, BASE_ATTACK_TIME); + SetAttackTime(OFF_ATTACK, BASE_ATTACK_TIME); + SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); + + SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0); + + CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); + if(cFamily && cFamily->minScale > 0.0f) + { + float scale; + if (getLevel() >= cFamily->maxScaleLevel) + scale = cFamily->maxScale; + else if (getLevel() <= cFamily->minScaleLevel) + scale = cFamily->minScale; + else + scale = cFamily->minScale + (getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale); + + SetFloatValue(OBJECT_FIELD_SCALE_X, scale); + } + m_bonusdamage = 0; + + int32 createResistance[MAX_SPELL_SCHOOL] = {0,0,0,0,0,0,0}; + + if(cinfo && getPetType() != HUNTER_PET) + { + createResistance[SPELL_SCHOOL_HOLY] = cinfo->resistance1; + createResistance[SPELL_SCHOOL_FIRE] = cinfo->resistance2; + createResistance[SPELL_SCHOOL_NATURE] = cinfo->resistance3; + createResistance[SPELL_SCHOOL_FROST] = cinfo->resistance4; + createResistance[SPELL_SCHOOL_SHADOW] = cinfo->resistance5; + createResistance[SPELL_SCHOOL_ARCANE] = cinfo->resistance6; + } + + switch(getPetType()) + { + case SUMMON_PET: + { + if(owner->GetTypeId() == TYPEID_PLAYER) + { + switch(owner->getClass()) + { + case CLASS_WARLOCK: + { + + //the damage bonus used for pets is either fire or shadow damage, whatever is higher + uint32 fire = owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE); + uint32 shadow = owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW); + uint32 val = (fire > shadow) ? fire : shadow; + + SetBonusDamage(int32 (val * 0.15f)); + //bonusAP += val * 0.57; + break; + } + case CLASS_MAGE: + { + //40% damage bonus of mage's frost damage + float val = owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST) * 0.4; + if(val < 0) + val = 0; + SetBonusDamage( int32(val)); + break; + } + default: + break; + } + } + + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)) ); + + //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower)); + + PetLevelInfo const* pInfo = objmgr.GetPetLevelInfo(creature_ID, petlevel); + if(pInfo) // exist in DB + { + SetCreateHealth(pInfo->health); + SetCreateMana(pInfo->mana); + + if(pInfo->armor > 0) + SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor)); + + for(int stat = 0; stat < MAX_STATS; ++stat) + { + SetCreateStat(Stats(stat),float(pInfo->stats[stat])); + } + } + else // not exist in DB, use some default fake data + { + sLog.outErrorDb("Summoned pet (Entry: %u) not have pet stats data in DB",cinfo->Entry); + + // remove elite bonuses included in DB values + SetCreateHealth(uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) ); + SetCreateMana( uint32(((float(cinfo->maxmana) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) ); + + SetCreateStat(STAT_STRENGTH,22); + SetCreateStat(STAT_AGILITY,22); + SetCreateStat(STAT_STAMINA,25); + SetCreateStat(STAT_INTELLECT,28); + SetCreateStat(STAT_SPIRIT,27); + } + break; + } + case HUNTER_PET: + { + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(petlevel))/4)); + + //these formula may not be correct; however, it is designed to be close to what it should be + //this makes dps 0.5 of pets level + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); + //damage range is then petlevel / 2 + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)) ); + //damage is increased afterwards as strength and pet scaling modify attack power + + //stored standard pet stats are entry 1 in pet_levelinfo + PetLevelInfo const* pInfo = objmgr.GetPetLevelInfo(creature_ID, petlevel); + if(pInfo) // exist in DB + { + SetCreateHealth(pInfo->health); + SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor)); + //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower)); + + for( int i = STAT_STRENGTH; i < MAX_STATS; i++) + { + SetCreateStat(Stats(i), float(pInfo->stats[i])); + } + } + else // not exist in DB, use some default fake data + { + sLog.outErrorDb("Hunter pet levelstats missing in DB"); + + // remove elite bonuses included in DB values + SetCreateHealth( uint32(((float(cinfo->maxhealth) / cinfo->maxlevel) / (1 + 2 * cinfo->rank)) * petlevel) ); + + SetCreateStat(STAT_STRENGTH,22); + SetCreateStat(STAT_AGILITY,22); + SetCreateStat(STAT_STAMINA,25); + SetCreateStat(STAT_INTELLECT,28); + SetCreateStat(STAT_SPIRIT,27); + } + break; + } + case GUARDIAN_PET: + SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); + + SetCreateMana( 28 + 10*petlevel ); + SetCreateHealth( 28 + 30*petlevel ); + + // FIXME: this is wrong formula, possible each guardian pet have own damage formula + //these formula may not be correct; however, it is designed to be close to what it should be + //this makes dps 0.5 of pets level + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); + //damage range is then petlevel / 2 + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)) ); + break; + default: + sLog.outError("Pet have incorrect type (%u) for levelup.",getPetType()); break; + } + + for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]) ); + + UpdateAllStats(); + + SetHealth(GetMaxHealth()); + SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); + + return true; +} + +bool Pet::HaveInDiet(ItemPrototype const* item) const +{ + if (!item->FoodType) + return false; + + CreatureInfo const* cInfo = GetCreatureInfo(); + if(!cInfo) + return false; + + CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cInfo->family); + if(!cFamily) + return false; + + uint32 diet = cFamily->petFoodMask; + uint32 FoodMask = 1 << (item->FoodType-1); + return diet & FoodMask; +} + +uint32 Pet::GetCurrentFoodBenefitLevel(uint32 itemlevel) +{ + // -5 or greater food level + if(getLevel() <= itemlevel +5) //possible to feed level 60 pet with level 55 level food for full effect + return 35000; + // -10..-6 + else if(getLevel() <= itemlevel + 10) //pure guess, but sounds good + return 17000; + // -14..-11 + else if(getLevel() <= itemlevel + 14) //level 55 food gets green on 70, makes sense to me + return 8000; + // -15 or less + else + return 0; //food too low level +} + +void Pet::_LoadSpellCooldowns() +{ + m_CreatureSpellCooldowns.clear(); + m_CreatureCategoryCooldowns.clear(); + + QueryResult *result = CharacterDatabase.PQuery("SELECT spell,time FROM pet_spell_cooldown WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + + if(result) + { + time_t curTime = time(NULL); + + WorldPacket data(SMSG_SPELL_COOLDOWN, (8+1+result->GetRowCount()*8)); + data << GetGUID(); + data << uint8(0x0); // flags (0x1, 0x2) + + do + { + Field *fields = result->Fetch(); + + uint32 spell_id = fields[0].GetUInt32(); + time_t db_time = (time_t)fields[1].GetUInt64(); + + if(!sSpellStore.LookupEntry(spell_id)) + { + sLog.outError("Pet %u have unknown spell %u in `pet_spell_cooldown`, skipping.",m_charmInfo->GetPetNumber(),spell_id); + continue; + } + + // skip outdated cooldown + if(db_time <= curTime) + continue; + + data << uint32(spell_id); + data << uint32(uint32(db_time-curTime)*1000); // in m.secs + + _AddCreatureSpellCooldown(spell_id,db_time); + + sLog.outDebug("Pet (Number: %u) spell %u cooldown loaded (%u secs).",m_charmInfo->GetPetNumber(),spell_id,uint32(db_time-curTime)); + } + while( result->NextRow() ); + + delete result; + + if(!m_CreatureSpellCooldowns.empty() && GetOwner()) + { + ((Player*)GetOwner())->GetSession()->SendPacket(&data); + } + } +} + +void Pet::_SaveSpellCooldowns() +{ + CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber()); + + time_t curTime = time(NULL); + + // remove oudated and save active + for(CreatureSpellCooldowns::iterator itr = m_CreatureSpellCooldowns.begin();itr != m_CreatureSpellCooldowns.end();) + { + if(itr->second <= curTime) + m_CreatureSpellCooldowns.erase(itr++); + else + { + CharacterDatabase.PExecute("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" I64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second)); + ++itr; + } + } +} + +void Pet::_LoadSpells() +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT spell,slot,active FROM pet_spell WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + addSpell(fields[0].GetUInt16(), fields[2].GetUInt16(), PETSPELL_UNCHANGED, fields[1].GetUInt16()); + } + while( result->NextRow() ); + + delete result; + } +} + +void Pet::_SaveSpells() +{ + for (PetSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next) + { + ++next; + if (itr->second->type == PETSPELL_FAMILY) continue; // prevent saving family passives to DB + if (itr->second->state == PETSPELL_REMOVED || itr->second->state == PETSPELL_CHANGED) + CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first); + if (itr->second->state == PETSPELL_NEW || itr->second->state == PETSPELL_CHANGED) + CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,slot,active) VALUES ('%u', '%u', '%u','%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second->slotId,itr->second->active); + + if (itr->second->state == PETSPELL_REMOVED) + _removeSpell(itr->first); + else + itr->second->state = PETSPELL_UNCHANGED; + } +} + +void Pet::_LoadAuras(uint32 timediff) +{ + m_Auras.clear(); + for (int i = 0; i < TOTAL_AURAS; i++) + m_modAuras[i].clear(); + + // all aura related fields + for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) + SetUInt32Value(i, 0); + + QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint64 caster_guid = fields[0].GetUInt64(); + uint32 spellid = fields[1].GetUInt32(); + uint32 effindex = fields[2].GetUInt32(); + int32 damage = (int32)fields[3].GetUInt32(); + int32 maxduration = (int32)fields[4].GetUInt32(); + int32 remaintime = (int32)fields[5].GetUInt32(); + int32 remaincharges = (int32)fields[6].GetUInt32(); + + SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); + if(!spellproto) + { + sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex); + continue; + } + + if(effindex >= 3) + { + sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex); + continue; + } + + // negative effects should continue counting down after logout + if (remaintime != -1 && !IsPositiveEffect(spellid, effindex)) + { + if(remaintime <= int32(timediff)) + continue; + + remaintime -= timediff; + } + + // prevent wrong values of remaincharges + if(spellproto->procCharges) + { + if(remaincharges <= 0 || remaincharges > spellproto->procCharges) + remaincharges = spellproto->procCharges; + } + else + remaincharges = -1; + + Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); + + if(!damage) + damage = aura->GetModifier()->m_amount; + aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); + AddAura(aura); + } + while( result->NextRow() ); + + delete result; + } +} + +void Pet::_SaveAuras() +{ + CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + + AuraMap const& auras = GetAuras(); + for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. + SpellEntry const *spellInfo = itr->second->GetSpellProto(); + uint8 i; + for (i = 0; i < 3; i++) + if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH || + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) + break; + + if (i == 3 && !itr->second->IsPassive()) + CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) " + "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d')", + m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(),(*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges)); + } +} + +bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 slot_id, PetSpellType type) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if (!spellInfo) + { + // do pet spell book cleanup + if(state == PETSPELL_UNCHANGED) // spell load case + { + sLog.outError("Pet::addSpell: Non-existed in SpellStore spell #%u request, deleting for all pets in `pet_spell`.",spell_id); + CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE spell = '%u'",spell_id); + } + else + sLog.outError("Pet::addSpell: Non-existed in SpellStore spell #%u request.",spell_id); + + return false; + } + + PetSpellMap::iterator itr = m_spells.find(spell_id); + if (itr != m_spells.end()) + { + if (itr->second->state == PETSPELL_REMOVED) + { + delete itr->second; + m_spells.erase(itr); + state = PETSPELL_CHANGED; + } + else if (state == PETSPELL_UNCHANGED && itr->second->state != PETSPELL_UNCHANGED) + { + // can be in case spell loading but learned at some previous spell loading + itr->second->state = PETSPELL_UNCHANGED; + return false; + } + else + return false; + } + + uint32 oldspell_id = 0; + + PetSpell *newspell = new PetSpell; + newspell->state = state; + newspell->type = type; + + if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here + { + if(IsPassiveSpell(spell_id)) + newspell->active = ACT_PASSIVE; + else + newspell->active = ACT_DISABLED; + } + else + newspell->active = active; + + uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id); + + for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); itr++) + { + if(itr->second->state == PETSPELL_REMOVED) continue; + + if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) + { + slot_id = itr->second->slotId; + newspell->active = itr->second->active; + + if(newspell->active == ACT_ENABLED) + ToggleAutocast(itr->first, false); + + oldspell_id = itr->first; + removeSpell(itr->first); + } + } + + uint16 tmpslot=slot_id; + + if (tmpslot == 0xffff) + { + uint16 maxid = 0; + PetSpellMap::iterator itr; + for (itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) continue; + if (itr->second->slotId > maxid) maxid = itr->second->slotId; + } + tmpslot = maxid + 1; + } + + newspell->slotId = tmpslot; + m_spells[spell_id] = newspell; + + if (IsPassiveSpell(spell_id)) + CastSpell(this, spell_id, true); + else if(state == PETSPELL_NEW) + m_charmInfo->AddSpellToAB(oldspell_id, spell_id); + + if(newspell->active == ACT_ENABLED) + ToggleAutocast(spell_id, true); + + return true; +} + +bool Pet::learnSpell(uint16 spell_id) +{ + // prevent duplicated entires in spell book + if (!addSpell(spell_id)) + return false; + + Unit* owner = GetOwner(); + if(owner->GetTypeId()==TYPEID_PLAYER) + ((Player*)owner)->PetSpellInitialize(); + return true; +} + +void Pet::removeSpell(uint16 spell_id) +{ + PetSpellMap::iterator itr = m_spells.find(spell_id); + if (itr == m_spells.end()) + return; + + if(itr->second->state == PETSPELL_REMOVED) + return; + + if(itr->second->state == PETSPELL_NEW) + { + delete itr->second; + m_spells.erase(itr); + } + else + itr->second->state = PETSPELL_REMOVED; + + RemoveAurasDueToSpell(spell_id); +} + +bool Pet::_removeSpell(uint16 spell_id) +{ + PetSpellMap::iterator itr = m_spells.find(spell_id); + if (itr != m_spells.end()) + { + delete itr->second; + m_spells.erase(itr); + return true; + } + return false; +} + +void Pet::InitPetCreateSpells() +{ + m_charmInfo->InitPetActionBar(); + + m_spells.clear(); + int32 usedtrainpoints = 0, petspellid; + PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry()); + if(CreateSpells) + { + for(uint8 i = 0; i < 4; i++) + { + if(!CreateSpells->spellid[i]) + break; + + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(CreateSpells->spellid[i]); + if(!learn_spellproto) + continue; + + if(learn_spellproto->Effect[0] == SPELL_EFFECT_LEARN_SPELL || learn_spellproto->Effect[0] == SPELL_EFFECT_LEARN_PET_SPELL) + { + petspellid = learn_spellproto->EffectTriggerSpell[0]; + Unit* owner = GetOwner(); + if(owner->GetTypeId() == TYPEID_PLAYER && !((Player*)owner)->HasSpell(learn_spellproto->Id)) + { + if(IsPassiveSpell(petspellid)) //learn passive skills when tamed, not sure if thats right + ((Player*)owner)->learnSpell(learn_spellproto->Id); + else + AddTeachSpell(learn_spellproto->EffectTriggerSpell[0], learn_spellproto->Id); + } + } + else + petspellid = learn_spellproto->Id; + + addSpell(petspellid); + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + usedtrainpoints += _spell_idx->second->reqtrainpoints; + break; + } + } + } + + LearnPetPassives(); + + CastPetAuras(false); + + SetTP(-usedtrainpoints); +} + +void Pet::CheckLearning(uint32 spellid) +{ + //charmed case -> prevent crash + if(GetTypeId() == TYPEID_PLAYER || getPetType() != HUNTER_PET) + return; + + Unit* owner = GetOwner(); + + if(m_teachspells.empty() || !owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + TeachSpellMap::iterator itr = m_teachspells.find(spellid); + if(itr == m_teachspells.end()) + return; + + if(urand(0, 100) < 10) + { + ((Player*)owner)->learnSpell(itr->second); + m_teachspells.erase(itr); + } +} + +uint32 Pet::resetTalentsCost() const +{ + uint32 days = (sWorld.GetGameTime() - m_resetTalentsTime)/DAY; + + // The first time reset costs 10 silver; after 1 day cost is reset to 10 silver + if(m_resetTalentsCost < 10*SILVER || days > 0) + return 10*SILVER; + // then 50 silver + else if(m_resetTalentsCost < 50*SILVER) + return 50*SILVER; + // then 1 gold + else if(m_resetTalentsCost < 1*GOLD) + return 1*GOLD; + // then increasing at a rate of 1 gold; cap 10 gold + else + return (m_resetTalentsCost + 1*GOLD > 10*GOLD ? 10*GOLD : m_resetTalentsCost + 1*GOLD); +} + +void Pet::ToggleAutocast(uint32 spellid, bool apply) +{ + if(IsPassiveSpell(spellid)) + return; + + PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid); + + int i; + + if(apply) + { + for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++); + if (i == m_autospells.size()) + { + m_autospells.push_back(spellid); + itr->second->active = ACT_ENABLED; + itr->second->state = PETSPELL_CHANGED; + } + } + else + { + AutoSpellList::iterator itr2 = m_autospells.begin(); + for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++); + if (i < m_autospells.size()) + { + m_autospells.erase(itr2); + itr->second->active = ACT_DISABLED; + itr->second->state = PETSPELL_CHANGED; + } + } +} + +bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number) +{ + SetMapId(map->GetId()); + SetInstanceId(map->GetInstanceId()); + + Object::_Create(guidlow, pet_number, HIGHGUID_PET); + + m_DBTableGuid = guidlow; + m_originalEntry = Entry; + + if(!InitEntry(Entry)) + return false; + + SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); + + if(getPetType() == MINI_PET) // always non-attackable + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + return true; +} + +bool Pet::HasSpell(uint32 spell) const +{ + return (m_spells.find(spell) != m_spells.end()); +} + +// Get all passive spells in our skill line +void Pet::LearnPetPassives() +{ + CreatureInfo const* cInfo = GetCreatureInfo(); + if(!cInfo) + return; + + CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cInfo->family); + if(!cFamily) + return; + + PetFamilySpellsStore::const_iterator petStore = sPetFamilySpellsStore.find(cFamily->ID); + if(petStore != sPetFamilySpellsStore.end()) + { + for(PetFamilySpellsSet::const_iterator petSet = petStore->second.begin(); petSet != petStore->second.end(); ++petSet) + addSpell(*petSet, ACT_DECIDE, PETSPELL_NEW, 0xffff, PETSPELL_FAMILY); + } +} + +void Pet::CastPetAuras(bool current) +{ + Unit* owner = GetOwner(); + if(!owner) + return; + + if(getPetType() != HUNTER_PET && (getPetType() != SUMMON_PET || owner->getClass() != CLASS_WARLOCK)) + return; + + for(PetAuraSet::iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end(); ) + { + PetAura const* pa = *itr; + ++itr; + + if(!current && pa->IsRemovedOnChangePet()) + owner->RemovePetAura(pa); + else + CastPetAura(pa); + } +} + +void Pet::CastPetAura(PetAura const* aura) +{ + uint16 auraId = aura->GetAura(GetEntry()); + if(!auraId) + return; + + if(auraId == 35696) // Demonic Knowledge + { + int32 basePoints = int32(aura->GetDamage() * (GetStat(STAT_STAMINA) + GetStat(STAT_INTELLECT)) / 100); + CastCustomSpell(this,auraId,&basePoints, NULL, NULL, true ); + } + else + CastSpell(this, auraId, true); +} diff --git a/src/game/Pet.h b/src/game/Pet.h new file mode 100644 index 000000000..f7a372adf --- /dev/null +++ b/src/game/Pet.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_PET_H +#define MANGOSSERVER_PET_H + +#include "ObjectDefines.h" +#include "Creature.h" +#include "Unit.h" + +enum PetType +{ + SUMMON_PET = 0, + HUNTER_PET = 1, + GUARDIAN_PET = 2, + MINI_PET = 3, + MAX_PET_TYPE = 4 +}; + +extern char const* petTypeSuffix[MAX_PET_TYPE]; + +enum PetSaveMode +{ + PET_SAVE_AS_DELETED =-1, + PET_SAVE_AS_CURRENT = 0, + PET_SAVE_IN_STABLE_SLOT_1 = 1, + PET_SAVE_IN_STABLE_SLOT_2 = 2, + PET_SAVE_NOT_IN_SLOT = 3 +}; + +enum HappinessState +{ + UNHAPPY = 1, + CONTENT = 2, + HAPPY = 3 +}; + +enum LoyaltyLevel +{ + REBELLIOUS = 1, + UNRULY = 2, + SUBMISSIVE = 3, + DEPENDABLE = 4, + FAITHFUL = 5, + BEST_FRIEND = 6 +}; + +enum PetSpellState +{ + PETSPELL_UNCHANGED = 0, + PETSPELL_CHANGED = 1, + PETSPELL_NEW = 2, + PETSPELL_REMOVED = 3 +}; + +enum PetSpellType +{ + PETSPELL_NORMAL = 0, + PETSPELL_FAMILY = 1, +}; + +struct PetSpell +{ + uint16 slotId; + uint16 active; + PetSpellState state : 16; + PetSpellType type : 16; +}; + +enum ActionFeedback +{ + FEEDBACK_NONE = 0, + FEEDBACK_PET_DEAD = 1, + FEEDBACK_NOTHING_TO_ATT = 2, + FEEDBACK_CANT_ATT_TARGET = 3 +}; + +enum PetTalk +{ + PET_TALK_SPECIAL_SPELL = 0, + PET_TALK_ATTACK = 1 +}; + +enum PetNameInvalidReason +{ + PET_NAME_INVALID = 1, + PET_NAME_NO_NAME = 2, + PET_NAME_TOO_SHORT = 3, + PET_NAME_TOO_LONG = 4, + PET_NAME_MIXED_LANGUAGES = 6, + PET_NAME_PROFANE = 7, + PET_NAME_RESERVED = 8, + PET_NAME_THREE_CONSECUTIVE = 11, + PET_NAME_INVALID_SPACE = 12, + PET_NAME_CONSECUTIVE_SPACES = 13, + PET_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 14, + PET_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 15, + PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16 +}; + +typedef HM_NAMESPACE::hash_map PetSpellMap; +typedef std::map TeachSpellMap; +typedef std::vector AutoSpellList; + +#define HAPPINESS_LEVEL_SIZE 333000 + +extern const uint32 LevelUpLoyalty[6]; +extern const uint32 LevelStartLoyalty[6]; + +#define ACTIVE_SPELLS_MAX 4 + +#define OWNER_MAX_DISTANCE 100 + +#define PET_FOLLOW_DIST 1 +#define PET_FOLLOW_ANGLE (M_PI/2) + +class Pet : public Creature +{ + public: + explicit Pet(PetType type = MAX_PET_TYPE); + virtual ~Pet(); + + void AddToWorld(); + void RemoveFromWorld(); + + PetType getPetType() const { return m_petType; } + void setPetType(PetType type) { m_petType = type; } + bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; } + bool isTemporarySummoned() const { return m_duration > 0; } + + bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number); + bool CreateBaseAtCreature( Creature* creature ); + bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false ); + void SavePetToDB(PetSaveMode mode); + void Remove(PetSaveMode mode, bool returnreagent = false); + static void DeleteFromDB(uint32 guidlow); + + void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState + void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update + + uint8 GetPetAutoSpellSize() const { return m_autospells.size(); } + uint32 GetPetAutoSpellOnPos(uint8 pos) const + { + if (pos >= m_autospells.size()) + return 0; + else + return m_autospells[pos]; + } + + void RegenerateFocus(); + void LooseHappiness(); + void TickLoyaltyChange(); + void ModifyLoyalty(int32 addvalue); + HappinessState GetHappinessState(); + uint32 GetMaxLoyaltyPoints(uint32 level); + uint32 GetStartLoyaltyPoints(uint32 level); + void KillLoyaltyBonus(uint32 level); + uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } + void SetLoyaltyLevel(LoyaltyLevel level); + void GivePetXP(uint32 xp); + void GivePetLevel(uint32 level); + bool InitStatsForLevel(uint32 level); + bool HaveInDiet(ItemPrototype const* item) const; + uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel); + void SetDuration(int32 dur) { m_duration = dur; } + + int32 GetBonusDamage() { return m_bonusdamage; } + void SetBonusDamage(int32 damage) { m_bonusdamage = damage; } + + bool UpdateStats(Stats stat); + bool UpdateAllStats(); + void UpdateResistances(uint32 school); + void UpdateArmor(); + void UpdateMaxHealth(); + void UpdateMaxPower(Powers power); + void UpdateAttackPowerAndDamage(bool ranged = false); + void UpdateDamagePhysical(WeaponAttackType attType); + + bool CanTakeMoreActiveSpells(uint32 SpellIconID); + void ToggleAutocast(uint32 spellid, bool apply); + bool HasTPForSpell(uint32 spellid); + int32 GetTPForSpell(uint32 spellid); + + bool HasSpell(uint32 spell) const; + void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; } + + void LearnPetPassives(); + void CastPetAuras(bool current); + void CastPetAura(PetAura const* aura); + + void _LoadSpellCooldowns(); + void _SaveSpellCooldowns(); + void _LoadAuras(uint32 timediff); + void _SaveAuras(); + void _LoadSpells(); + void _SaveSpells(); + + bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL); + bool learnSpell(uint16 spell_id); + void removeSpell(uint16 spell_id); + bool _removeSpell(uint16 spell_id); + + PetSpellMap m_spells; + TeachSpellMap m_teachspells; + AutoSpellList m_autospells; + + void InitPetCreateSpells(); + void CheckLearning(uint32 spellid); + uint32 resetTalentsCost() const; + + void SetTP(int32 TP); + int32 GetDispTP(); + + int32 m_TrainingPoints; + uint32 m_resetTalentsCost; + time_t m_resetTalentsTime; + + uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } + void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } + void ResetAuraUpdateMask() { m_auraUpdateMask = 0; } + + DeclinedName const* GetDeclinedNames() const { return m_declinedname; } + + bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved) + protected: + uint32 m_regenTimer; + uint32 m_happinessTimer; + uint32 m_loyaltyTimer; + PetType m_petType; + int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) + int32 m_loyaltyPoints; + int32 m_bonusdamage; + uint64 m_auraUpdateMask; + + DeclinedName *m_declinedname; + + private: + void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called + { + assert(false); + } + void DeleteFromDB() // overwrited of Creature::DeleteFromDB - don't must be called + { + assert(false); + } +}; +#endif diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp new file mode 100644 index 000000000..81ca6889f --- /dev/null +++ b/src/game/PetAI.cpp @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PetAI.h" +#include "Errors.h" +#include "Pet.h" +#include "Player.h" +#include "Database/DBCStores.h" +#include "Spell.h" +#include "ObjectAccessor.h" +#include "SpellMgr.h" +#include "Creature.h" +#include "World.h" +#include "Util.h" + +int PetAI::Permissible(const Creature *creature) +{ + if( creature->isPet()) + return PERMIT_BASE_SPECIAL; + + return PERMIT_BASE_NO; +} + +PetAI::PetAI(Creature &c) : i_pet(c), i_victimGuid(0), i_tracker(TIME_INTERVAL_LOOK) +{ + m_AllySet.clear(); + UpdateAllies(); +} + +void PetAI::MoveInLineOfSight(Unit *u) +{ + if( !i_pet.getVictim() && i_pet.GetCharmInfo() && + i_pet.GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) && + u->isTargetableForAttack() && i_pet.IsHostileTo( u ) && + u->isInAccessablePlaceFor(&i_pet)) + { + float attackRadius = i_pet.GetAttackDistance(u); + if(i_pet.IsWithinDistInMap(u, attackRadius) && i_pet.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE) + { + if(i_pet.IsWithinLOSInMap(u)) + { + AttackStart(u); + u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + } + } + } +} + +void PetAI::AttackStart(Unit *u) +{ + if( i_pet.getVictim() || !u || i_pet.isPet() && ((Pet&)i_pet).getPetType()==MINI_PET ) + return; + + if(i_pet.Attack(u,true)) + { + i_pet.clearUnitState(UNIT_STAT_FOLLOW); + // TMGs call CreatureRelocation which via MoveInLineOfSight can call this function + // thus with the following clear the original TMG gets invalidated and crash, doh + // hope it doesn't start to leak memory without this :-/ + //i_pet->Clear(); + i_victimGuid = u->GetGUID(); + i_pet.GetMotionMaster()->MoveChase(u); + } +} + +void PetAI::EnterEvadeMode() +{ +} + +bool PetAI::IsVisible(Unit *pl) const +{ + return _isVisible(pl); +} + +bool PetAI::_needToStop() const +{ + if(!i_pet.getVictim() || !i_pet.isAlive()) + return true; + + // This is needed for charmed creatures, as once their target was reset other effects can trigger threat + if(i_pet.isCharmed() && i_pet.getVictim() == i_pet.GetCharmer()) + return true; + + return !i_pet.getVictim()->isTargetableForAttack(); +} + +void PetAI::_stopAttack() +{ + if( !i_victimGuid ) + return; + + Unit* victim = ObjectAccessor::GetUnit(i_pet, i_victimGuid ); + + if ( !victim ) + return; + + assert(!i_pet.getVictim() || i_pet.getVictim() == victim); + + if( !i_pet.isAlive() ) + { + DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow()); + i_pet.StopMoving(); + i_pet.GetMotionMaster()->Clear(); + i_pet.GetMotionMaster()->MoveIdle(); + i_victimGuid = 0; + i_pet.CombatStop(); + i_pet.getHostilRefManager().deleteReferences(); + + return; + } + else if( !victim ) + { + DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_pet.GetGUIDLow()); + } + else if( !victim->isAlive() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_pet.GetGUIDLow()); + } + else if( victim->HasStealthAura() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_pet.GetGUIDLow()); + } + else if( victim->isInFlight() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_pet.GetGUIDLow()); + } + else + { + DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_pet.GetGUIDLow()); + } + + Unit* owner = i_pet.GetCharmerOrOwner(); + + if(owner && i_pet.GetCharmInfo() && i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) + { + i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); + } + else + { + i_pet.clearUnitState(UNIT_STAT_FOLLOW); + i_pet.GetMotionMaster()->Clear(); + i_pet.GetMotionMaster()->MoveIdle(); + } + i_victimGuid = 0; + i_pet.AttackStop(); +} + +void PetAI::UpdateAI(const uint32 diff) +{ + // update i_victimGuid if i_pet.getVictim() !=0 and changed + if(i_pet.getVictim()) + i_victimGuid = i_pet.getVictim()->GetGUID(); + + Unit* owner = i_pet.GetCharmerOrOwner(); + + if(m_updateAlliesTimer <= diff) + // UpdateAllies self set update timer + UpdateAllies(); + else + m_updateAlliesTimer -= diff; + + // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc. + if( i_victimGuid ) + { + if( _needToStop() ) + { + DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow()); + _stopAttack(); // i_victimGuid == 0 && i_pet.getVictim() == NULL now + return; + } + else if( i_pet.IsStopped() || i_pet.IsWithinDistInMap(i_pet.getVictim(), ATTACK_DISTANCE)) + { + // required to be stopped cases + if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) ) + { + if( i_pet.hasUnitState(UNIT_STAT_FOLLOW) ) + i_pet.InterruptNonMeleeSpells(false); + else + return; + } + // not required to be stopped case + else if( i_pet.isAttackReady() && i_pet.canReachWithAttack(i_pet.getVictim()) ) + { + i_pet.AttackerStateUpdate(i_pet.getVictim()); + + i_pet.resetAttackTimer(); + + if ( !i_pet.getVictim() ) + return; + + //if pet misses its target, it will also be the first in threat list + i_pet.getVictim()->AddThreat(&i_pet,0.0f); + + if( _needToStop() ) + _stopAttack(); + } + } + } + else if(owner && i_pet.GetCharmInfo()) + { + if(owner->isInCombat() && !(i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY))) + { + AttackStart(owner->getAttackerForHelper()); + } + else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) + { + if (!i_pet.hasUnitState(UNIT_STAT_FOLLOW) ) + { + i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); + } + } + } + + //Autocast + HM_NAMESPACE::hash_map targetMap; + targetMap.clear(); + SpellCastTargets NULLtargets; + + for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++) + { + uint32 spellID = i_pet.GetPetAutoSpellOnPos(i); + if (!spellID) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); + if (!spellInfo) + continue; + + Spell *spell = new Spell(&i_pet, spellInfo, false, 0); + + if(!IsPositiveSpell(spellInfo->Id) && i_pet.getVictim() && !_needToStop() && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim())) + targetMap[spellID] = i_pet.getVictim(); + else + { + spell->m_targets = NULLtargets; + for(std::set::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) + { + Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar); + + //only buff targets that are in combat, unless the spell can only be cast while out of combat + if(!Target || (!Target->isInCombat() && !IsNonCombatSpell(spellInfo))) + continue; + if(spell->CanAutoCast(Target)) + targetMap[spellID] = Target; + } + } + + delete spell; + } + + //found units to cast on to + if(!targetMap.empty()) + { + uint32 index = urand(1, targetMap.size()); + HM_NAMESPACE::hash_map::iterator itr; + uint32 i; + for(itr = targetMap.begin(), i = 1; i < index; ++itr, ++i); + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + + Spell *spell = new Spell(&i_pet, spellInfo, false); + + SpellCastTargets targets; + targets.setUnitTarget( itr->second ); + + if(!i_pet.HasInArc(M_PI, itr->second)) + { + i_pet.SetInFront(itr->second); + if( itr->second->GetTypeId() == TYPEID_PLAYER ) + i_pet.SendUpdateToPlayer( (Player*)itr->second ); + + if(owner && owner->GetTypeId() == TYPEID_PLAYER) + i_pet.SendUpdateToPlayer( (Player*)owner ); + } + + i_pet.AddCreatureSpellCooldown(itr->first); + if(i_pet.isPet()) + ((Pet*)&i_pet)->CheckLearning(itr->first); + + spell->prepare(&targets); + } + targetMap.clear(); +} + +bool PetAI::_isVisible(Unit *u) const +{ + //return false; //( ((Creature*)&i_pet)->GetDistanceSq(u) * 1.0<= sWorld.getConfig(CONFIG_SIGHT_GUARDER) && !u->m_stealth && u->isAlive()); + return i_pet.GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER) + && u->isVisibleForOrDetect(&i_pet,true); +} + +void PetAI::UpdateAllies() +{ + Unit* owner = i_pet.GetCharmerOrOwner(); + Group *pGroup = NULL; + + m_updateAlliesTimer = 10000; //update friendly targets every 10 seconds, lesser checks increase performance + + if(!owner) + return; + else if(owner->GetTypeId() == TYPEID_PLAYER) + pGroup = ((Player*)owner)->GetGroup(); + + //only pet and owner/not in group->ok + if(m_AllySet.size() == 2 && !pGroup) + return; + //owner is in group; group members filled in already (no raid -> subgroupcount = whole count) + if(pGroup && !pGroup->isRaidGroup() && m_AllySet.size() == (pGroup->GetMembersCount() + 2)) + return; + + m_AllySet.clear(); + m_AllySet.insert(i_pet.GetGUID()); + if(pGroup) //add group + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + if(!Target || !pGroup->SameSubGroup((Player*)owner, Target)) + continue; + + if(Target->GetGUID() == owner->GetGUID()) + continue; + + m_AllySet.insert(Target->GetGUID()); + } + } + else //remove group + m_AllySet.insert(owner->GetGUID()); +} + +void PetAI::AttackedBy(Unit *attacker) +{ + //when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway + if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) && + (!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.canReachWithAttack(attacker))) + AttackStart(attacker); +} diff --git a/src/game/PetAI.h b/src/game/PetAI.h new file mode 100644 index 000000000..1b0579525 --- /dev/null +++ b/src/game/PetAI.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_PETAI_H +#define MANGOS_PETAI_H + +#include "CreatureAI.h" +#include "Timer.h" + +class Creature; + +class MANGOS_DLL_DECL PetAI : public CreatureAI +{ + public: + + PetAI(Creature &c); + + void MoveInLineOfSight(Unit *); + void AttackStart(Unit *); + void EnterEvadeMode(); + void DamageTaken(Unit *done_by, uint32& /*damage*/) { AttackedBy(done_by); } + void AttackedBy(Unit*); + bool IsVisible(Unit *) const; + + void UpdateAI(const uint32); + void UpdateAllies(); + static int Permissible(const Creature *); + + private: + bool _isVisible(Unit *) const; + bool _needToStop(void) const; + void _stopAttack(void); + + Creature &i_pet; + uint64 i_victimGuid; + TimeTracker i_tracker; + //uint32 i_RepeatAction; + std::set m_AllySet; + uint32 m_updateAlliesTimer; +}; +#endif diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp new file mode 100644 index 000000000..197c6b2ef --- /dev/null +++ b/src/game/PetHandler.cpp @@ -0,0 +1,676 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Log.h" +#include "Opcodes.h" +#include "Spell.h" +#include "ObjectAccessor.h" +#include "MapManager.h" +#include "CreatureAI.h" +#include "Util.h" +#include "Pet.h" +#include "Language.h" + +void WorldSession::HandlePetAction( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+2+2+8); + + uint64 guid1; + uint16 spellid; + uint16 flag; + uint64 guid2; + recv_data >> guid1; //pet guid + recv_data >> spellid; + recv_data >> flag; //delete = 0x0700 CastSpell = C100 + recv_data >> guid2; //tag guid + + // used also for charmed creature + Unit* pet= ObjectAccessor::GetUnit(*_player,guid1); + sLog.outDetail( "HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.\n", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) ); + if(!pet) + { + sLog.outError( "Pet %u not exist.\n", uint32(GUID_LOPART(guid1)) ); + return; + } + + if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm()) + { + sLog.outError( "HandlePetAction.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid1)),GetPlayer()->GetName() ); + return; + } + + if(!pet->isAlive()) + return; + + if(pet->GetTypeId() == TYPEID_PLAYER && !(flag == ACT_COMMAND && spellid == COMMAND_ATTACK)) + return; + + CharmInfo *charmInfo = pet->GetCharmInfo(); + if(!charmInfo) + { + sLog.outError("WorldSession::HandlePetAction: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + return; + } + + switch(flag) + { + case ACT_COMMAND: //0x0700 + switch(spellid) + { + case COMMAND_STAY: //flat=1792 //STAY + pet->StopMoving(); + pet->GetMotionMaster()->Clear(); + pet->GetMotionMaster()->MoveIdle(); + charmInfo->SetCommandState( COMMAND_STAY ); + break; + case COMMAND_FOLLOW: //spellid=1792 //FOLLOW + pet->AttackStop(); + pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); + charmInfo->SetCommandState( COMMAND_FOLLOW ); + break; + case COMMAND_ATTACK: //spellid=1792 //ATTACK + { + // only place where pet can be player + pet->clearUnitState(UNIT_STAT_FOLLOW); + uint64 selguid = _player->GetSelection(); + Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid); + if(!TargetUnit) + return; + + // not let attack friendly units. + if( GetPlayer()->IsFriendlyTo(TargetUnit)) + return; + + if(pet->getVictim()) + pet->AttackStop(); + + if(pet->GetTypeId() != TYPEID_PLAYER) + { + pet->GetMotionMaster()->Clear(); + if (((Creature*)pet)->AI()) + ((Creature*)pet)->AI()->AttackStart(TargetUnit); + + //10% chance to play special pet attack talk, else growl + if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10) + pet->SendPetTalk((uint32)PET_TALK_ATTACK); + else + { + // 90% chance for pet and 100% chance for charmed creature + pet->SendPetAIReaction(guid1); + } + } + else // charmed player + { + pet->Attack(TargetUnit,true); + pet->SendPetAIReaction(guid1); + } + break; + } + case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) + if(((Creature*)pet)->isPet()) + { + Pet* p = (Pet*)pet; + if(p->getPetType() == HUNTER_PET) + _player->RemovePet(p,PET_SAVE_AS_DELETED); + else + //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) + p->setDeathState(CORPSE); + } + else // charmed + _player->Uncharm(); + break; + default: + sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid); + } + break; + case ACT_REACTION: // 0x600 + switch(spellid) + { + case REACT_PASSIVE: //passive + case REACT_DEFENSIVE: //recovery + case REACT_AGGRESSIVE: //activete + charmInfo->SetReactState( ReactStates(spellid) ); + break; + } + break; + case ACT_DISABLED: //0x8100 spell (disabled), ignore + case ACT_CAST: //0x0100 + case ACT_ENABLED: //0xc100 spell + { + Unit* unit_target; + if(guid2) + unit_target = ObjectAccessor::GetUnit(*_player,guid2); + else + unit_target = NULL; + + // do not cast unknown spells + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); + if(!spellInfo) + { + sLog.outError("WORLD: unknown PET spell id %i\n", spellid); + return; + } + + for(uint32 i = 0; i < 3;i++) + { + if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) + return; + } + + // do not cast not learned spells + if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) + return; + + pet->clearUnitState(UNIT_STAT_FOLLOW); + + Spell *spell = new Spell(pet, spellInfo, false); + + int16 result = spell->PetCanCast(unit_target); + + //auto turn to target unless possessed + if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) + { + pet->SetInFront(unit_target); + if( unit_target->GetTypeId() == TYPEID_PLAYER ) + pet->SendUpdateToPlayer( (Player*)unit_target ); + if(Unit* powner = pet->GetCharmerOrOwner()) + if(powner->GetTypeId() == TYPEID_PLAYER) + pet->SendUpdateToPlayer((Player*)powner); + result = -1; + } + + if(result == -1) + { + ((Creature*)pet)->AddCreatureSpellCooldown(spellid); + if (((Creature*)pet)->isPet()) + ((Pet*)pet)->CheckLearning(spellid); + + unit_target = spell->m_targets.getUnitTarget(); + + //10% chance to play special pet attack talk, else growl + //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell + if(((Creature*)pet)->isPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10)) + pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); + else + { + pet->SendPetAIReaction(guid1); + } + + if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) + { + pet->clearUnitState(UNIT_STAT_FOLLOW); + if(pet->getVictim()) + pet->AttackStop(); + pet->GetMotionMaster()->Clear(); + if (((Creature*)pet)->AI()) + ((Creature*)pet)->AI()->AttackStart(unit_target); + } + + spell->prepare(&(spell->m_targets)); + } + else + { + if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) + { + WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); + data << uint32(spellid) << uint8(2) << uint8(result); + switch (result) + { + case SPELL_FAILED_REQUIRES_SPELL_FOCUS: + data << uint32(spellInfo->RequiresSpellFocus); + break; + case SPELL_FAILED_REQUIRES_AREA: + data << uint32(spellInfo->AreaId); + break; + } + SendPacket(&data); + } + else + pet->SendPetCastFail(spellid, result); + + if(!((Creature*)pet)->HasSpellCooldown(spellid)) + pet->SendPetClearCooldown(spellid); + + spell->finish(false); + delete spell; + } + break; + } + default: + sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid); + } +} + +void WorldSession::HandlePetNameQuery( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+8); + + sLog.outDetail( "HandlePetNameQuery. CMSG_PET_NAME_QUERY\n" ); + + uint32 petnumber; + uint64 petguid; + + recv_data >> petnumber; + recv_data >> petguid; + + SendPetNameQuery(petguid,petnumber); +} + +void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber) +{ + Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid); + if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber) + return; + + std::string name = pet->GetName(); + + WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4+4+name.size()+1)); + data << uint32(petnumber); + data << name.c_str(); + data << uint32(pet->GetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP)); + + if( pet->isPet() && ((Pet*)pet)->GetDeclinedNames() ) + { + data << uint8(1); + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + data << ((Pet*)pet)->GetDeclinedNames()->name[i]; + } + else + data << uint8(0); + + _player->GetSession()->SendPacket(&data); +} + +void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+2+2); + + sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION\n" ); + + uint64 petguid; + uint32 position; + uint16 spell_id; + uint16 act_state; + uint8 count; + + recv_data >> petguid; + + // FIXME: charmed case + //Pet* pet = ObjectAccessor::Instance().GetPet(petguid); + if(ObjectAccessor::FindPlayer(petguid)) + return; + + Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid); + + if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) + { + sLog.outError( "HandlePetSetAction: Unknown pet or pet owner.\n" ); + return; + } + + CharmInfo *charmInfo = pet->GetCharmInfo(); + if(!charmInfo) + { + sLog.outError("WorldSession::HandlePetSetAction: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + return; + } + + count = (recv_data.size() == 24) ? 2 : 1; + for(uint8 i = 0; i < count; i++) + { + recv_data >> position; + recv_data >> spell_id; + recv_data >> act_state; + + sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state); + + //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add + if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id))) + { + //sign for autocast + if(act_state == ACT_ENABLED && spell_id) + { + if(pet->isCharmed()) + charmInfo->ToggleCreatureAutocast(spell_id, true); + else + ((Pet*)pet)->ToggleAutocast(spell_id, true); + } + //sign for no/turn off autocast + else if(act_state == ACT_DISABLED && spell_id) + { + if(pet->isCharmed()) + charmInfo->ToggleCreatureAutocast(spell_id, false); + else + ((Pet*)pet)->ToggleAutocast(spell_id, false); + } + + charmInfo->GetActionBarEntry(position)->Type = act_state; + charmInfo->GetActionBarEntry(position)->SpellOrAction = spell_id; + } + } +} + +void WorldSession::HandlePetRename( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + + sLog.outDetail( "HandlePetRename. CMSG_PET_RENAME\n" ); + + uint64 petguid; + uint8 isdeclined; + + std::string name; + DeclinedName declinedname; + + recv_data >> petguid; + recv_data >> name; + CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1); + recv_data >> isdeclined; + + Pet* pet = ObjectAccessor::GetPet(petguid); + // check it! + if( !pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || + pet->GetByteValue(UNIT_FIELD_BYTES_2, 2) != UNIT_RENAME_ALLOWED || + pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() ) + return; + + if(!ObjectMgr::IsValidPetName(name)) + { + SendPetNameInvalid(PET_NAME_INVALID, name, NULL); + return; + } + + if(objmgr.IsReservedName(name)) + { + SendPetNameInvalid(PET_NAME_RESERVED, name, NULL); + return; + } + + pet->SetName(name); + + Unit *owner = pet->GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); + + pet->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED); + + if(isdeclined) + { + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + { + CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1); + recv_data >> declinedname.name[i]; + } + + std::wstring wname; + Utf8toWStr(name, wname); + if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname,0),declinedname)) + { + SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname); + return; + } + } + + CharacterDatabase.BeginTransaction(); + if(isdeclined) + { + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + CharacterDatabase.escape_string(declinedname.name[i]); + CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber()); + CharacterDatabase.PExecute("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%u','%s','%s','%s','%s','%s')", + pet->GetCharmInfo()->GetPetNumber(), _player->GetGUIDLow(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); + } + + CharacterDatabase.escape_string(name); + CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber()); + CharacterDatabase.CommitTransaction(); + + pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); +} + +void WorldSession::HandlePetAbandon( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + uint64 guid; + recv_data >> guid; //pet guid + sLog.outDetail( "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid) ); + + // pet/charmed + Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, guid); + if(pet) + { + if(pet->isPet()) + { + if(pet->GetGUID() == _player->GetPetGUID()) + { + uint32 feelty = pet->GetPower(POWER_HAPPINESS); + pet->SetPower(POWER_HAPPINESS ,(feelty-50000) > 0 ?(feelty-50000) : 0); + } + + _player->RemovePet((Pet*)pet,PET_SAVE_AS_DELETED); + } + else if(pet->GetGUID() == _player->GetCharmGUID()) + { + _player->Uncharm(); + } + } +} + +void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,8); + + sLog.outDetail("CMSG_PET_UNLEARN"); + uint64 guid; + recvPacket >> guid; + + Pet* pet = _player->GetPet(); + + if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1) + return; + + if(guid != pet->GetGUID()) + { + sLog.outError( "HandlePetUnlearnOpcode.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); + return; + } + + CharmInfo *charmInfo = pet->GetCharmInfo(); + if(!charmInfo) + { + sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + return; + } + + uint32 cost = pet->resetTalentsCost(); + + if (GetPlayer()->GetMoney() < cost) + { + GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); + return; + } + + for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();) + { + uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell + ++itr; + pet->removeSpell(spell_id); + } + + pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1)); + + for(uint8 i = 0; i < 10; i++) + { + if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) + charmInfo->GetActionBarEntry(i)->SpellOrAction = 0; + } + + // relearn pet passives + pet->LearnPetPassives(); + + pet->m_resetTalentsTime = time(NULL); + pet->m_resetTalentsCost = cost; + GetPlayer()->ModifyMoney(-(int32)cost); + + GetPlayer()->PetSpellInitialize(); +} + +void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) +{ + CHECK_PACKET_SIZE(recvPacket,8+2+2+1); + + sLog.outDetail("CMSG_PET_SPELL_AUTOCAST"); + uint64 guid; + uint16 spellid; + uint16 spellid2; //maybe second spell, automatically toggled off when first toggled on? + uint8 state; //1 for on, 0 for off + recvPacket >> guid >> spellid >> spellid2 >> state; + + if(!_player->GetPet() && !_player->GetCharm()) + return; + + if(ObjectAccessor::FindPlayer(guid)) + return; + + Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid); + + if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) + { + sLog.outError( "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); + return; + } + + // do not add not learned spells/ passive spells + if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) + return; + + CharmInfo *charmInfo = pet->GetCharmInfo(); + if(!charmInfo) + { + sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + return; + } + + if(pet->isCharmed()) + //state can be used as boolean + pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state); + else + ((Pet*)pet)->ToggleAutocast(spellid, state); + + for(uint8 i = 0; i < 10; ++i) + { + if((charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) && spellid == charmInfo->GetActionBarEntry(i)->SpellOrAction) + charmInfo->GetActionBarEntry(i)->Type = state ? ACT_ENABLED : ACT_DISABLED; + } +} + +void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) +{ + sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL"); + + CHECK_PACKET_SIZE(recvPacket,8+4); + uint64 guid; + uint32 spellid; + + recvPacket >> guid >> spellid; + + if(!_player->GetPet() && !_player->GetCharm()) + return; + + if(ObjectAccessor::FindPlayer(guid)) + return; + + Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid); + + if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm())) + { + sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); + return; + } + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); + if(!spellInfo) + { + sLog.outError("WORLD: unknown PET spell id %i\n", spellid); + return; + } + + // do not cast not learned spells + if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) + return; + + SpellCastTargets targets; + if(!targets.read(&recvPacket,pet)) + return; + + pet->clearUnitState(UNIT_STAT_FOLLOW); + + Spell *spell = new Spell(pet, spellInfo, false); + spell->m_targets = targets; + + int16 result = spell->PetCanCast(NULL); + if(result == -1) + { + pet->AddCreatureSpellCooldown(spellid); + if(pet->isPet()) + { + Pet* p = (Pet*)pet; + p->CheckLearning(spellid); + //10% chance to play special pet attack talk, else growl + //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell + if(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) + pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); + else + pet->SendPetAIReaction(guid); + } + + spell->prepare(&(spell->m_targets)); + } + else + { + pet->SendPetCastFail(spellid, result); + if(!pet->HasSpellCooldown(spellid)) + pet->SendPetClearCooldown(spellid); + + spell->finish(false); + delete spell; + } +} + +void WorldSession::SendPetNameInvalid(uint32 error, std::string name, DeclinedName *declinedName) +{ + WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1); + data << uint32(error); + data << name; + if(declinedName) + { + data << uint8(1); + for(uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + data << declinedName->name[i]; + } + else + data << uint8(0); + SendPacket(&data); +} diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp new file mode 100644 index 000000000..d53e7ab24 --- /dev/null +++ b/src/game/PetitionsHandler.cpp @@ -0,0 +1,936 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Language.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Log.h" +#include "Opcodes.h" +#include "Guild.h" +#include "ArenaTeam.h" +#include "MapManager.h" +#include "GossipDef.h" +#include "SocialMgr.h" + +/*enum PetitionType // dbc data +{ + PETITION_TYPE_GUILD = 1, + PETITION_TYPE_ARENA_TEAM = 3 +};*/ + +// Charters ID in item_template +#define GUILD_CHARTER 5863 +#define GUILD_CHARTER_COST 1000 // 10 S +#define ARENA_TEAM_CHARTER_2v2 23560 +#define ARENA_TEAM_CHARTER_2v2_COST 800000 // 80 G +#define ARENA_TEAM_CHARTER_3v3 23561 +#define ARENA_TEAM_CHARTER_3v3_COST 1200000 // 120 G +#define ARENA_TEAM_CHARTER_5v5 23562 +#define ARENA_TEAM_CHARTER_5v5_COST 2000000 // 200 G + +void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8+8+4+1+5*8+2+1+4+4); + + sLog.outDebug("Received opcode CMSG_PETITION_BUY"); + //recv_data.hexlike(); + + uint64 guidNPC; + uint64 unk1, unk3, unk4, unk5, unk6, unk7; + uint32 unk2; + std::string name; + uint16 unk8; + uint8 unk9; + uint32 unk10; // selected index + uint32 unk11; + recv_data >> guidNPC; // NPC GUID + recv_data >> unk1; // 0 + recv_data >> unk2; // 0 + recv_data >> name; // name + + // recheck + CHECK_PACKET_SIZE(recv_data, 8+8+4+(name.size()+1)+5*8+2+1+4+4); + + recv_data >> unk3; // 0 + recv_data >> unk4; // 0 + recv_data >> unk5; // 0 + recv_data >> unk6; // 0 + recv_data >> unk7; // 0 + recv_data >> unk8; // 0 + recv_data >> unk9; // 0 + recv_data >> unk10; // index + recv_data >> unk11; // 0 + sLog.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str()); + + // prevent cheating + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guidNPC,UNIT_NPC_FLAG_PETITIONER); + if (!pCreature) + { + sLog.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC)); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + uint32 charterid = 0; + uint32 cost = 0; + uint32 type = 0; + if(pCreature->isTabardDesigner()) + { + // if tabard designer, then trying to buy a guild charter. + // do not let if already in guild. + if(_player->GetGuildId()) + return; + + charterid = GUILD_CHARTER; + cost = GUILD_CHARTER_COST; + type = 9; + } + else + { + // TODO: find correct opcode + if(_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + SendNotification(LANG_ARENA_ONE_TOOLOW, 70); + return; + } + + for(uint8 i = 0; i < MAX_ARENA_SLOT; i++) + { + if(_player->GetArenaTeamId(i) && (i == (unk10-1))) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); + return; + } + } + switch(unk10) + { + case 1: + charterid = ARENA_TEAM_CHARTER_2v2; + cost = ARENA_TEAM_CHARTER_2v2_COST; + type = 2; // 2v2 + break; + case 2: + charterid = ARENA_TEAM_CHARTER_3v3; + cost = ARENA_TEAM_CHARTER_3v3_COST; + type = 3; // 3v3 + break; + case 3: + charterid = ARENA_TEAM_CHARTER_5v5; + cost = ARENA_TEAM_CHARTER_5v5_COST; + type = 5; // 5v5 + break; + default: + sLog.outDebug("unknown selection at buy petition: %u", unk10); + return; + } + } + + if(type == 9) + { + if(objmgr.GetGuildByName(name)) + { + SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS); + return; + } + if(objmgr.IsReservedName(name)) + { + SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID); + return; + } + if(!ObjectMgr::IsValidCharterName(name)) + { + SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID); + return; + } + } + else + { + if(objmgr.GetArenaTeamByName(name)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); + return; + } + if(objmgr.IsReservedName(name)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID); + return; + } + if(!ObjectMgr::IsValidCharterName(name)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID); + return; + } + } + + ItemPrototype const *pProto = objmgr.GetItemPrototype(charterid); + if(!pProto) + { + _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0); + return; + } + + if(_player->GetMoney() < cost) + { //player hasn't got enough money + _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, charterid, 0); + return; + } + + ItemPosCountVec dest; + uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount ); + if(msg != EQUIP_ERR_OK) + { + _player->SendBuyError(msg, pCreature, charterid, 0); + return; + } + + _player->ModifyMoney(-(int32)cost); + Item *charter = _player->StoreNewItem(dest, charterid, true); + if(!charter) + return; + + charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow()); + // ITEM_FIELD_ENCHANTMENT is guild/arenateam id + // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item) + charter->SetState(ITEM_CHANGED, _player); + _player->SendNewItem(charter, 1, true, false); + + // a petition is invalid, if both the owner and the type matches + QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player->GetGUIDLow(), type); + + std::ostringstream ssInvalidPetitionGUIDs; + + if (result) + { + + do + { + Field *fields = result->Fetch(); + ssInvalidPetitionGUIDs << "'" << fields[0].GetUInt32() << "' , "; + } while (result->NextRow()); + + delete result; + } + + // delete petitions with the same guid as this one + ssInvalidPetitionGUIDs << "'" << charter->GetGUIDLow() << "'"; + + sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); + CharacterDatabase.escape_string(name); + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str()); + CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str()); + CharacterDatabase.PExecute("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')", + _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type); + CharacterDatabase.CommitTransaction(); +} + +void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + // ok + sLog.outDebug("Received opcode CMSG_PETITION_SHOW_SIGNATURES"); + //recv_data.hexlike(); + + uint8 signs = 0; + uint64 petitionguid; + recv_data >> petitionguid; // petition guid + + // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?) + uint32 petitionguid_low = GUID_LOPART(petitionguid); + + QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid, type FROM petition WHERE petitionguid = '%u'", petitionguid_low); + if(!result) + { + sLog.outError("any petition on server..."); + return; + } + Field *fields = result->Fetch(); + uint32 type = fields[1].GetUInt32(); + delete result; + // if guild petition and has guild => error, return; + if(type==9 && _player->GetGuildId()) + return; + + result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low); + + // result==NULL also correct in case no sign yet + if(result) + signs = result->GetRowCount(); + + sLog.outDebug("CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionguid_low); + + WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+1+signs*12)); + data << petitionguid; // petition guid + data << _player->GetGUID(); // owner guid + data << petitionguid_low; // guild guid (in mangos always same as GUID_LOPART(petitionguid) + data << signs; // sign's count + + for(uint8 i = 1; i <= signs; i++) + { + Field *fields = result->Fetch(); + uint64 plguid = fields[0].GetUInt64(); + + data << plguid; // Player GUID + data << (uint32)0; // there 0 ... + + result->NextRow(); + } + delete result; + SendPacket(&data); +} + +void WorldSession::HandlePetitionQueryOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 4+8); + + sLog.outDebug("Received opcode CMSG_PETITION_QUERY"); // ok + //recv_data.hexlike(); + + uint32 guildguid; + uint64 petitionguid; + recv_data >> guildguid; // in mangos always same as GUID_LOPART(petitionguid) + recv_data >> petitionguid; // petition guid + sLog.outDebug("CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionguid), guildguid); + + SendPetitionQueryOpcode(petitionguid); +} + +void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) +{ + uint64 ownerguid = 0; + uint32 type; + std::string name = "NO_NAME_FOR_GUID"; + uint8 signs = 0; + + QueryResult *result = CharacterDatabase.PQuery( + "SELECT ownerguid, name, " + " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs " + "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid)); + + if(result) + { + Field* fields = result->Fetch(); + ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + name = fields[1].GetCppString(); + signs = fields[2].GetUInt8(); + delete result; + } + else + { + sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); + return; + } + + QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + + if(result2) + { + Field* fields = result2->Fetch(); + type = fields[0].GetUInt32(); + delete result2; + } + else + { + sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); + return; + } + + WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*13)); + data << GUID_LOPART(petitionguid); // guild/team guid (in mangos always same as GUID_LOPART(petition guid) + data << ownerguid; // charter owner guid + data << name; // name (guild/arena team) + data << uint8(0); // 1 + if(type == 9) + { + data << uint32(9); + data << uint32(9); + data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition + } + else + { + data << type-1; + data << type-1; + data << type; // bypass client - side limitation, a different value is needed here for each petition + } + data << uint32(0); // 5 + data << uint32(0); // 6 + data << uint32(0); // 7 + data << uint32(0); // 8 + data << uint16(0); // 9 2 bytes field + data << uint32(0); // 10 + data << uint32(0); // 11 + data << uint32(0); // 13 count of next strings? + data << uint32(0); // 14 + if(type == 9) + data << uint32(0); // 15 0 - guild, 1 - arena team + else + data << uint32(1); + SendPacket(&data); +} + +void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + + sLog.outDebug("Received opcode MSG_PETITION_RENAME"); // ok + //recv_data.hexlike(); + + uint64 petitionguid; + uint32 type; + std::string newname; + + recv_data >> petitionguid; // guid + recv_data >> newname; // new name + + Item *item = _player->GetItemByGuid(petitionguid); + if(!item) + return; + + QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + + if(result2) + { + Field* fields = result2->Fetch(); + type = fields[0].GetUInt32(); + delete result2; + } + else + { + sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); + return; + } + + if(type == 9) + { + if(objmgr.GetGuildByName(newname)) + { + SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_EXISTS); + return; + } + if(objmgr.IsReservedName(newname)) + { + SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID); + return; + } + if(!ObjectMgr::IsValidCharterName(newname)) + { + SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID); + return; + } + } + else + { + if(objmgr.GetArenaTeamByName(newname)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S); + return; + } + if(objmgr.IsReservedName(newname)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID); + return; + } + if(!ObjectMgr::IsValidCharterName(newname)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID); + return; + } + } + + std::string db_newname = newname; + CharacterDatabase.escape_string(db_newname); + CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'", + db_newname.c_str(), GUID_LOPART(petitionguid)); + + sLog.outDebug("Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid), newname.c_str()); + WorldPacket data(MSG_PETITION_RENAME, (8+newname.size()+1)); + data << petitionguid; + data << newname; + SendPacket(&data); +} + +void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + + sLog.outDebug("Received opcode CMSG_PETITION_SIGN"); // ok + //recv_data.hexlike(); + + Field *fields; + uint64 petitionguid; + uint32 type; + uint8 unk; + uint64 ownerguid; + recv_data >> petitionguid; // petition guid + recv_data >> unk; + + uint8 signs = 0; + + QueryResult *result = CharacterDatabase.PQuery( + "SELECT ownerguid, " + " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs " + "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid)); + + if(!result) + { + sLog.outError("any petition on server..."); + return; + } + + fields = result->Fetch(); + ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + signs = fields[1].GetUInt8(); + + delete result; + + uint32 plguidlo = _player->GetGUIDLow(); + if(GUID_LOPART(ownerguid) == plguidlo) + return; + + // not let enemies sign guild charter + if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != objmgr.GetPlayerTeamByGUID(ownerguid)) + return; + + QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + + if(result2) + { + Field* fields = result2->Fetch(); + type = fields[0].GetUInt32(); + delete result2; + } + else + { + sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); + return; + } + + if(type != 9 && _player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + // player is too low level to join an arena team + SendNotification(LANG_YOUR_ARENA_LEVEL_REQ_ERROR,sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); + return; + } + + signs += 1; + if(signs > type) // client signs maximum + return; + + //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account + //not allow sign another player from already sign player account + result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid)); + + if(result) + { + delete result; + WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4)); + data << petitionguid; + data << _player->GetGUID(); + data << (uint32)PETITION_SIGN_ALREADY_SIGNED; + + // close at signer side + SendPacket(&data); + + // update for owner if online + if(Player *owner = objmgr.GetPlayer(ownerguid)) + owner->GetSession()->SendPacket(&data); + return; + } + + CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GUID_LOPART(ownerguid),GUID_LOPART(petitionguid), plguidlo,GetAccountId()); + + sLog.outDebug("PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid), _player->GetName(),plguidlo,GetAccountId()); + + WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4)); + data << petitionguid; + data << _player->GetGUID(); + data << (uint32)PETITION_SIGN_OK; + + // close at signer side + SendPacket(&data); + + // update signs count on charter, required testing... + //Item *item = _player->GetItemByGuid(petitionguid)); + //if(item) + // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs); + + // update for owner if online + if(Player *owner = objmgr.GetPlayer(ownerguid)) + owner->GetSession()->SendPacket(&data); +} + +void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + sLog.outDebug("Received opcode MSG_PETITION_DECLINE"); // ok + //recv_data.hexlike(); + + uint64 petitionguid; + uint64 ownerguid; + recv_data >> petitionguid; // petition guid + sLog.outDebug("Petition %u declined by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); + + QueryResult *result = CharacterDatabase.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + if(!result) + return; + + Field *fields = result->Fetch(); + ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + delete result; + + Player *owner = objmgr.GetPlayer(ownerguid); + if(owner) // petition owner online + { + WorldPacket data(MSG_PETITION_DECLINE, 8); + data << _player->GetGUID(); + owner->GetSession()->SendPacket(&data); + } +} + +void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 4+8+8); + + sLog.outDebug("Received opcode CMSG_OFFER_PETITION"); // ok + //recv_data.hexlike(); + + uint8 signs = 0; + uint64 petitionguid, plguid; + uint32 petitiontype; + Player *player; + recv_data >> petitiontype; // 2.0.8 - petition type? + recv_data >> petitionguid; // petition guid + recv_data >> plguid; // player guid + sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", petitiontype, GUID_LOPART(petitionguid), GUID_LOPART(plguid)); + + player = ObjectAccessor::FindPlayer(plguid); + if(!player || player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + return; + + // not let offer to enemies + if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam() ) + return; + + QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + if(!result) + { + sLog.outError("any petition on server..."); + return; + } + + delete result; + + result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + // result==NULL also correct charter without signs + if(result) + signs = result->GetRowCount(); + + WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12)); + data << petitionguid; // petition guid + data << _player->GetGUID(); // owner guid + data << GUID_LOPART(petitionguid); // guild guid (in mangos always same as GUID_LOPART(petition guid) + data << signs; // sign's count + + for(uint8 i = 1; i <= signs; i++) + { + Field *fields = result->Fetch(); + uint64 plguid = fields[0].GetUInt64(); + + data << plguid; // Player GUID + data << (uint32)0; // there 0 ... + + result->NextRow(); + } + + delete result; + player->GetSession()->SendPacket(&data); +} + +void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + sLog.outDebug("Received opcode CMSG_TURN_IN_PETITION"); // ok + //recv_data.hexlike(); + + WorldPacket data; + uint64 petitionguid; + + uint32 ownerguidlo; + uint32 type; + std::string name; + + recv_data >> petitionguid; + + sLog.outDebug("Petition %u turned in by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); + + // data + QueryResult *result = CharacterDatabase.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + if(result) + { + Field *fields = result->Fetch(); + ownerguidlo = fields[0].GetUInt32(); + name = fields[1].GetCppString(); + type = fields[2].GetUInt32(); + delete result; + } + else + { + sLog.outError("petition table has broken data!"); + return; + } + + if(type == 9) + { + if(_player->GetGuildId()) + { + data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); + data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild + _player->GetSession()->SendPacket(&data); + return; + } + } + else + { + uint8 slot = ArenaTeam::GetSlotByType(type); + if(slot >= MAX_ARENA_SLOT) + return; + + if(_player->GetArenaTeamId(slot)) + { + //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); + //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild + //_player->GetSession()->SendPacket(&data); + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); + return; + } + } + + if(_player->GetGUIDLow() != ownerguidlo) + return; + + // signs + uint8 signs; + result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + if(result) + signs = result->GetRowCount(); + else + signs = 0; + + uint32 count; + //if(signs < sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS)) + if(type == 9) + count = sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS); + else + count = type-1; + if(signs < count) + { + data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); + data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES; // need more signatures... + SendPacket(&data); + delete result; + return; + } + + if(type == 9) + { + if(objmgr.GetGuildByName(name)) + { + SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS); + delete result; + return; + } + } + else + { + if(objmgr.GetArenaTeamByName(name)) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); + delete result; + return; + } + } + + // and at last charter item check + Item *item = _player->GetItemByGuid(petitionguid); + if(!item) + { + delete result; + return; + } + + // OK! + + // delete charter item + _player->DestroyItem(item->GetBagSlot(),item->GetSlot(), true); + + if(type == 9) // create guild + { + Guild* guild = new Guild; + if(!guild->create(_player->GetGUID(), name)) + { + delete guild; + delete result; + return; + } + + // register guild and add guildmaster + objmgr.AddGuild(guild); + + // add members + for(uint8 i = 0; i < signs; ++i) + { + Field* fields = result->Fetch(); + guild->AddMember(fields[0].GetUInt64(), guild->GetLowestRank()); + result->NextRow(); + } + } + else // or arena team + { + ArenaTeam* at = new ArenaTeam; + if(!at->create(_player->GetGUID(), type, name)) + { + sLog.outError("PetitionsHandler: arena team create failed."); + delete at; + delete result; + return; + } + + CHECK_PACKET_SIZE(recv_data, 8+5*4); + uint32 icon, iconcolor, border, bordercolor, backgroud; + recv_data >> backgroud >> icon >> iconcolor >> border >> bordercolor; + + at->SetEmblem(backgroud, icon, iconcolor, border, bordercolor); + + // register team and add captain + objmgr.AddArenaTeam(at); + sLog.outDebug("PetitonsHandler: arena team added to objmrg"); + + // add members + for(uint8 i = 0; i < signs; ++i) + { + Field* fields = result->Fetch(); + sLog.outDebug("PetitionsHandler: adding arena member %u", fields[0].GetUInt64()); + at->AddMember(fields[0].GetUInt64()); + result->NextRow(); + } + } + + delete result; + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); + CharacterDatabase.CommitTransaction(); + + // created + sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid)); + + data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); + data << (uint32)PETITION_TURN_OK; + SendPacket(&data); +} + +void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8); + + sLog.outDebug("Received CMSG_PETITION_SHOWLIST"); // ok + //recv_data.hexlike(); + + uint64 guid; + recv_data >> guid; + + SendPetitionShowList(guid); +} + +void WorldSession::SendPetitionShowList(uint64 guid) +{ + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_PETITIONER); + if (!pCreature) + { + sLog.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + uint8 count = 0; + if(pCreature->isTabardDesigner()) + count = 1; + else + count = 3; + + WorldPacket data(SMSG_PETITION_SHOWLIST, 8+1+4*6); + data << guid; // npc guid + data << count; // count + if(count == 1) + { + data << uint32(1); // index + data << uint32(GUILD_CHARTER); // charter entry + data << uint32(16161); // charter display id + data << uint32(GUILD_CHARTER_COST); // charter cost + data << uint32(0); // unknown + data << uint32(9); // required signs? + } + else + { + // 2v2 + data << uint32(1); // index + data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry + data << uint32(16161); // charter display id + data << uint32(ARENA_TEAM_CHARTER_2v2_COST); // charter cost + data << uint32(2); // unknown + data << uint32(2); // required signs? + // 3v3 + data << uint32(2); // index + data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry + data << uint32(16161); // charter display id + data << uint32(ARENA_TEAM_CHARTER_3v3_COST); // charter cost + data << uint32(3); // unknown + data << uint32(3); // required signs? + // 5v5 + data << uint32(3); // index + data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry + data << uint32(16161); // charter display id + data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost + data << uint32(5); // unknown + data << uint32(5); // required signs? + } + //for(uint8 i = 0; i < count; i++) + //{ + // data << uint32(i); // index + // data << uint32(GUILD_CHARTER); // charter entry + // data << uint32(16161); // charter display id + // data << uint32(GUILD_CHARTER_COST+i); // charter cost + // data << uint32(0); // unknown + // data << uint32(9); // required signs? + //} + SendPacket(&data); + sLog.outDebug("Sent SMSG_PETITION_SHOWLIST"); +} diff --git a/src/game/Player.cpp b/src/game/Player.cpp new file mode 100644 index 000000000..8de8daaca --- /dev/null +++ b/src/game/Player.cpp @@ -0,0 +1,18170 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Language.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "Opcodes.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "UpdateMask.h" +#include "Player.h" +#include "SkillDiscovery.h" +#include "QuestDef.h" +#include "GossipDef.h" +#include "UpdateData.h" +#include "Channel.h" +#include "ChannelMgr.h" +#include "MapManager.h" +#include "MapInstanced.h" +#include "InstanceSaveMgr.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "ObjectMgr.h" +#include "ObjectAccessor.h" +#include "CreatureAI.h" +#include "Formulas.h" +#include "Group.h" +#include "Guild.h" +#include "Pet.h" +#include "SpellAuras.h" +#include "Util.h" +#include "Transports.h" +#include "Weather.h" +#include "BattleGround.h" +#include "BattleGroundMgr.h" +#include "ArenaTeam.h" +#include "Chat.h" +#include "Database/DatabaseImpl.h" +#include "Spell.h" +#include "SocialMgr.h" + +#include + +#define ZONE_UPDATE_INTERVAL 1000 + +#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3)) +#define PLAYER_SKILL_VALUE_INDEX(x) (PLAYER_SKILL_INDEX(x)+1) +#define PLAYER_SKILL_BONUS_INDEX(x) (PLAYER_SKILL_INDEX(x)+2) + +#define SKILL_VALUE(x) PAIR32_LOPART(x) +#define SKILL_MAX(x) PAIR32_HIPART(x) +#define MAKE_SKILL_VALUE(v, m) MAKE_PAIR32(v,m) + +#define SKILL_TEMP_BONUS(x) int16(PAIR32_LOPART(x)) +#define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x)) +#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t,p) + +enum CharacterFlags +{ + CHARACTER_FLAG_NONE = 0x00000000, + CHARACTER_FLAG_UNK1 = 0x00000001, + CHARACTER_FLAG_UNK2 = 0x00000002, + CHARACTER_LOCKED_FOR_TRANSFER = 0x00000004, + CHARACTER_FLAG_UNK4 = 0x00000008, + CHARACTER_FLAG_UNK5 = 0x00000010, + CHARACTER_FLAG_UNK6 = 0x00000020, + CHARACTER_FLAG_UNK7 = 0x00000040, + CHARACTER_FLAG_UNK8 = 0x00000080, + CHARACTER_FLAG_UNK9 = 0x00000100, + CHARACTER_FLAG_UNK10 = 0x00000200, + CHARACTER_FLAG_HIDE_HELM = 0x00000400, + CHARACTER_FLAG_HIDE_CLOAK = 0x00000800, + CHARACTER_FLAG_UNK13 = 0x00001000, + CHARACTER_FLAG_GHOST = 0x00002000, + CHARACTER_FLAG_RENAME = 0x00004000, + CHARACTER_FLAG_UNK16 = 0x00008000, + CHARACTER_FLAG_UNK17 = 0x00010000, + CHARACTER_FLAG_UNK18 = 0x00020000, + CHARACTER_FLAG_UNK19 = 0x00040000, + CHARACTER_FLAG_UNK20 = 0x00080000, + CHARACTER_FLAG_UNK21 = 0x00100000, + CHARACTER_FLAG_UNK22 = 0x00200000, + CHARACTER_FLAG_UNK23 = 0x00400000, + CHARACTER_FLAG_UNK24 = 0x00800000, + CHARACTER_FLAG_LOCKED_BY_BILLING = 0x01000000, + CHARACTER_FLAG_DECLINED = 0x02000000, + CHARACTER_FLAG_UNK27 = 0x04000000, + CHARACTER_FLAG_UNK28 = 0x08000000, + CHARACTER_FLAG_UNK29 = 0x10000000, + CHARACTER_FLAG_UNK30 = 0x20000000, + CHARACTER_FLAG_UNK31 = 0x40000000, + CHARACTER_FLAG_UNK32 = 0x80000000 +}; + +// corpse reclaim times +#define DEATH_EXPIRE_STEP (5*MINUTE) +#define MAX_DEATH_COUNT 3 + +static uint32 copseReclaimDelay[MAX_DEATH_COUNT] = { 30, 60, 120 }; + +//== PlayerTaxi ================================================ + +PlayerTaxi::PlayerTaxi() +{ + // Taxi nodes + memset(m_taximask, 0, sizeof(m_taximask)); +} + +void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level) +{ + // capital and taxi hub masks + switch(race) + { + case RACE_HUMAN: SetTaximaskNode(2); break; // Human + case RACE_ORC: SetTaximaskNode(23); break; // Orc + case RACE_DWARF: SetTaximaskNode(6); break; // Dwarf + case RACE_NIGHTELF: SetTaximaskNode(26); + SetTaximaskNode(27); break; // Night Elf + case RACE_UNDEAD_PLAYER: SetTaximaskNode(11); break;// Undead + case RACE_TAUREN: SetTaximaskNode(22); break; // Tauren + case RACE_GNOME: SetTaximaskNode(6); break; // Gnome + case RACE_TROLL: SetTaximaskNode(23); break; // Troll + case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf + case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei + } + // new continent starting masks (It will be accessible only at new map) + switch(Player::TeamForRace(race)) + { + case ALLIANCE: SetTaximaskNode(100); break; + case HORDE: SetTaximaskNode(99); break; + } + // level dependent taxi hubs + if(level>=68) + SetTaximaskNode(213); //Shattered Sun Staging Area +} + +void PlayerTaxi::LoadTaxiMask(const char* data) +{ + Tokens tokens = StrSplit(data, " "); + + int index; + Tokens::iterator iter; + for (iter = tokens.begin(), index = 0; + (index < TaxiMaskSize) && (iter != tokens.end()); ++iter, ++index) + { + // load and set bits only for existed taxi nodes + m_taximask[index] = sTaxiNodesMask[index] & uint32(atol((*iter).c_str())); + } +} + +void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all ) +{ + if(all) + { + for (uint8 i=0; ic_str())); + AddTaxiDestination(node); + } + + if(m_TaxiDestinations.empty()) + return true; + + // Check integrity + if(m_TaxiDestinations.size() < 2) + return false; + + for(size_t i = 1; i < m_TaxiDestinations.size(); ++i) + { + uint32 cost; + uint32 path; + objmgr.GetTaxiPath(m_TaxiDestinations[i-1],m_TaxiDestinations[i],path,cost); + if(!path) + return false; + } + + return true; +} + +std::string PlayerTaxi::SaveTaxiDestinationsToString() +{ + if(m_TaxiDestinations.empty()) + return ""; + + std::ostringstream ss; + + for(size_t i=0; i < m_TaxiDestinations.size(); ++i) + ss << m_TaxiDestinations[i] << " "; + + return ss.str(); +} + +uint32 PlayerTaxi::GetCurrentTaxiPath() const +{ + if(m_TaxiDestinations.size() < 2) + return 0; + + uint32 path; + uint32 cost; + + objmgr.GetTaxiPath(m_TaxiDestinations[0],m_TaxiDestinations[1],path,cost); + + return path; +} + +//== Player ==================================================== + +const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000}; + +UpdateMask Player::updateVisualBits; + +Player::Player (WorldSession *session): Unit() +{ + m_transport = 0; + + m_speakTime = 0; + m_speakCount = 0; + + m_objectType |= TYPEMASK_PLAYER; + m_objectTypeId = TYPEID_PLAYER; + + m_valuesCount = PLAYER_END; + + m_session = session; + + m_divider = 0; + + m_ExtraFlags = 0; + if(GetSession()->GetSecurity() >= SEC_GAMEMASTER) + SetAcceptTicket(true); + + // players always accept + if(GetSession()->GetSecurity() == SEC_PLAYER) + SetAcceptWhispers(true); + + m_curSelection = 0; + m_lootGuid = 0; + + m_comboTarget = 0; + m_comboPoints = 0; + + m_usedTalentCount = 0; + + m_regenTimer = 0; + m_weaponChangeTimer = 0; + + m_zoneUpdateId = 0; + m_zoneUpdateTimer = 0; + + m_areaUpdateId = 0; + + m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE); + + // randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE] + // this must help in case next save after mass player load after server startup + m_nextSave = urand(m_nextSave/2,m_nextSave*3/2); + + clearResurrectRequestData(); + + m_SpellModRemoveCount = 0; + + memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT); + + m_social = NULL; + + // group is initialized in the reference constructor + SetGroupInvite(NULL); + m_groupUpdateMask = 0; + m_auraUpdateMask = 0; + + duel = NULL; + + m_GuildIdInvited = 0; + m_ArenaTeamIdInvited = 0; + + m_atLoginFlags = AT_LOGIN_NONE; + + m_dontMove = false; + + pTrader = 0; + ClearTrade(); + + m_cinematic = 0; + + PlayerTalkClass = new PlayerMenu( GetSession() ); + m_currentBuybackSlot = BUYBACK_SLOT_START; + + for ( int aX = 0 ; aX < 8 ; aX++ ) + m_Tutorials[ aX ] = 0x00; + m_TutorialsChanged = false; + + m_DailyQuestChanged = false; + m_lastDailyQuestTime = 0; + + m_regenTimer = 0; + m_weaponChangeTimer = 0; + m_breathTimer = 0; + m_isunderwater = 0; + m_isInWater = false; + m_drunkTimer = 0; + m_drunk = 0; + m_restTime = 0; + m_deathTimer = 0; + m_deathExpireTime = 0; + + m_swingErrorMsg = 0; + + m_DetectInvTimer = 1000; + + m_bgBattleGroundID = 0; + for (int j=0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; j++) + { + m_bgBattleGroundQueueID[j].bgType = 0; + m_bgBattleGroundQueueID[j].invited = false; + } + m_bgTeam = 0; + + m_logintime = time(NULL); + m_Last_tick = m_logintime; + m_WeaponProficiency = 0; + m_ArmorProficiency = 0; + m_canParry = false; + m_canBlock = false; + m_canDualWield = false; + m_ammoDPS = 0.0f; + + m_temporaryUnsummonedPetNumber = 0; + //cache for UNIT_CREATED_BY_SPELL to allow + //returning reagests for temporarily removed pets + //when dying/logging out + m_oldpetspell = 0; + + ////////////////////Rest System///////////////////// + time_inn_enter=0; + inn_pos_mapid=0; + inn_pos_x=0; + inn_pos_y=0; + inn_pos_z=0; + m_rest_bonus=0; + rest_type=REST_TYPE_NO; + ////////////////////Rest System///////////////////// + + m_mailsLoaded = false; + m_mailsUpdated = false; + unReadMails = 0; + m_nextMailDelivereTime = 0; + + m_resetTalentsCost = 0; + m_resetTalentsTime = 0; + m_itemUpdateQueueBlocked = false; + + for (int i = 0; i < MAX_MOVE_TYPE; ++i) + m_forced_speed_changes[i] = 0; + + m_stableSlots = 0; + + /////////////////// Instance System ///////////////////// + + m_HomebindTimer = 0; + m_InstanceValid = true; + m_dungeonDifficulty = DIFFICULTY_NORMAL; + + for (int i = 0; i < BASEMOD_END; i++) + { + m_auraBaseMod[i][FLAT_MOD] = 0.0f; + m_auraBaseMod[i][PCT_MOD] = 1.0f; + } + + // Honor System + m_lastHonorUpdateTime = time(NULL); + + // Player summoning + m_summon_expire = 0; + m_summon_mapid = 0; + m_summon_x = 0.0f; + m_summon_y = 0.0f; + m_summon_z = 0.0f; + + //Default movement to run mode + m_unit_movement_flags = 0; + + m_miniPet = 0; + m_bgAfkReportedTimer = 0; + m_contestedPvPTimer = 0; + + m_declinedname = NULL; +} + +Player::~Player () +{ + CleanupsBeforeDelete(); + + if(m_uint32Values) // only for fully created Object + { + sSocialMgr.RemovePlayerSocial(GetGUIDLow()); + } + + // Note: buy back item already deleted from DB when player was saved + for(int i = 0; i < PLAYER_SLOTS_COUNT; ++i) + { + if(m_items[i]) + delete m_items[i]; + } + CleanupChannels(); + + for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + delete itr->second; + + //all mailed items should be deleted, also all mail should be deallocated + for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end();++itr) + delete *itr; + + for (ItemMap::iterator iter = mMitems.begin(); iter != mMitems.end(); ++iter) + delete iter->second; //if item is duplicated... then server may crash ... but that item should be deallocated + + delete PlayerTalkClass; + + if (m_transport) + { + m_transport->RemovePassenger(this); + } + + for(size_t x = 0; x < ItemSetEff.size(); x++) + if(ItemSetEff[x]) + delete ItemSetEff[x]; + + // clean up player-instance binds, may unload some instance saves + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) + itr->second.save->RemovePlayer(this); + + delete m_declinedname; +} + +void Player::CleanupsBeforeDelete() +{ + if(m_uint32Values) // only for fully created Object + { + TradeCancel(false); + DuelComplete(DUEL_INTERUPTED); + } + Unit::CleanupsBeforeDelete(); +} + +bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId ) +{ + Object::_Create(guidlow, 0, HIGHGUID_PLAYER); + + m_name = name; + + PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_); + if(!info) + { + sLog.outError("Player have incorrect race/class pair. Can't be loaded."); + return false; + } + + for (int i = 0; i < PLAYER_SLOTS_COUNT; i++) + m_items[i] = NULL; + + //for(int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; j++) + //{ + // SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1+j*2,0); + // SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1+j,0); + // SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1+j,0); + //} + + m_race = race; + m_class = class_; + + SetMapId(info->mapId); + Relocate(info->positionX,info->positionY,info->positionZ); + + ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(class_); + if(!cEntry) + { + sLog.outError("Class %u not found in DBC (Wrong DBC files?)",class_); + return false; + } + + uint8 powertype = cEntry->powerType; + + uint32 unitfield; + + switch(powertype) + { + case POWER_ENERGY: + case POWER_MANA: + unitfield = 0x00000000; + break; + case POWER_RAGE: + unitfield = 0x00110000; + break; + default: + sLog.outError("Invalid default powertype %u for player (class %u)",powertype,class_); + return false; + } + + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); + SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f ); + + switch(gender) + { + case GENDER_FEMALE: + SetDisplayId(info->displayId_f ); + SetNativeDisplayId(info->displayId_f ); + break; + case GENDER_MALE: + SetDisplayId(info->displayId_m ); + SetNativeDisplayId(info->displayId_m ); + break; + default: + sLog.outError("Invalid gender %u for player",gender); + return false; + break; + } + + setFactionForRace(m_race); + + SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( race ) | ( class_ << 8 ) | ( gender << 16 ) | ( powertype << 24 ) ) ); + SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); + SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); + SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client + + //-1 is default value + SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); + + SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); + SetUInt32Value(PLAYER_BYTES_2, (facialHair | (0x00 << 8) | (0x00 << 16) | (0x02 << 24))); + SetByteValue(PLAYER_BYTES_3, 0, gender); + + SetUInt32Value( PLAYER_GUILDID, 0 ); + SetUInt32Value( PLAYER_GUILDRANK, 0 ); + SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 ); + + SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES, 0 ); // 0=disabled + SetUInt32Value( PLAYER_CHOSEN_TITLE, 0 ); + SetUInt32Value( PLAYER_FIELD_KILLS, 0 ); + SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 ); + SetUInt32Value( PLAYER_FIELD_TODAY_CONTRIBUTION, 0 ); + SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 ); + + // set starting level + SetUInt32Value( UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) ); + + // Played time + m_Last_tick = time(NULL); + m_Played_time[0] = 0; + m_Played_time[1] = 0; + + // base stats and related field values + InitStatsForLevel(); + InitTaxiNodesForLevel(); + InitTalentForLevel(); + InitPrimaryProffesions(); // to max set before any spell added + + // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() + UpdateMaxHealth(); // Update max Health (for add bonus from stamina) + SetHealth(GetMaxHealth()); + if (getPowerType()==POWER_MANA) + { + UpdateMaxPower(POWER_MANA); // Update max Mana (for add bonus from intelect) + SetPower(POWER_MANA,GetMaxPower(POWER_MANA)); + } + + learnDefaultSpells(true); + + std::list::const_iterator action_itr[4]; + for(int i=0; i<4; i++) + action_itr[i] = info->action[i].begin(); + + for (; action_itr[0]!=info->action[0].end() && action_itr[1]!=info->action[1].end();) + { + uint16 taction[4]; + for(int i=0; i<4 ;i++) + taction[i] = (*action_itr[i]); + + addActionButton((uint8)taction[0], taction[1], (uint8)taction[2], (uint8)taction[3]); + + for(int i=0; i<4 ;i++) + ++action_itr[i]; + } + + for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++) + { + uint32 titem_id = item_id_itr->item_id; + uint32 titem_amount = item_id_itr->item_amount; + + sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount); + + // attempt equip + uint16 eDest; + uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false ); + if( msg == EQUIP_ERR_OK ) + { + EquipNewItem( eDest, titem_id, titem_amount, true); + AutoUnequipOffhandIfNeed(); + continue; // equipped, to next + } + + // attempt store + ItemPosCountVec sDest; + // store in main bag to simplify second pass (special bags can be not equipped yet at this moment) + msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount ); + if( msg == EQUIP_ERR_OK ) + { + StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) ); + continue; // stored, to next + } + + // item can't be added + sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,race,class_,msg); + } + + // bags and main-hand weapon must equipped at this moment + // now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon) + // or ammo not equipped in special bag + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + if(Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + { + uint16 eDest; + // equip offhand weapon/shield if it attempt equipped before main-hand weapon + uint8 msg = CanEquipItem( NULL_SLOT, eDest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + { + RemoveItem(INVENTORY_SLOT_BAG_0, i,true); + EquipItem( eDest, pItem, true); + } + // move other items to more appropriate slots (ammo not equipped in special bag) + else + { + ItemPosCountVec sDest; + msg = CanStoreItem( NULL_BAG, NULL_SLOT, sDest, pItem, false ); + if( msg == EQUIP_ERR_OK ) + { + RemoveItem(INVENTORY_SLOT_BAG_0, i,true); + pItem = StoreItem( sDest, pItem, true); + } + + // if this is ammo then use it + uint8 msg = CanUseAmmo( pItem->GetProto()->ItemId ); + if( msg == EQUIP_ERR_OK ) + SetAmmo( pItem->GetProto()->ItemId ); + } + } + } + // all item positions resolved + + return true; +} + +void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue) +{ + uint32 BreathRegen = (uint32)-1; + + WorldPacket data(SMSG_START_MIRROR_TIMER, (21)); + data << (uint32)Type; + data << MaxValue; + data << MaxValue; + data << BreathRegen; + data << (uint8)0; + data << (uint32)0; // spell id + GetSession()->SendPacket(&data); +} + +void Player::ModifyMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, uint32 Regen) +{ + if(Type==BREATH_TIMER) + m_breathTimer = ((MaxValue + 1000) - CurrentValue) / Regen; + + WorldPacket data(SMSG_START_MIRROR_TIMER, (21)); + data << (uint32)Type; + data << CurrentValue; + data << MaxValue; + data << Regen; + data << (uint8)0; + data << (uint32)0; // spell id + GetSession()->SendPacket( &data ); +} + +void Player::StopMirrorTimer(MirrorTimerType Type) +{ + if(Type==BREATH_TIMER) + m_breathTimer = 0; + + WorldPacket data(SMSG_STOP_MIRROR_TIMER, 4); + data << (uint32)Type; + GetSession()->SendPacket( &data ); +} + +void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 damage) +{ + WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21)); + data << (uint64)guid; + data << (uint8)(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL); + data << (uint32)damage; + data << (uint32)0; + data << (uint32)0; + //m_session->SendPacket(&data); + //Let other players see that you get damage + SendMessageToSet(&data, true); + DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + + if(type==DAMAGE_FALL && !isAlive()) // DealDamage not apply item durability loss at self damage + { + DEBUG_LOG("We are fall to death, loosing 10 percents durability"); + DurabilityLossAll(0.10f,false); + // durability lost message + WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); + GetSession()->SendPacket(&data); + } +} + +void Player::HandleDrowning() +{ + if(!m_isunderwater) + return; + + //if have water breath , then remove bar + if(waterbreath || isGameMaster() || !isAlive()) + { + StopMirrorTimer(BREATH_TIMER); + m_isunderwater = 0; + return; + } + + uint32 UnderWaterTime = 1*MINUTE*1000; // default leangthL 1 min + + AuraList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING); + for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i) + UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifier()->m_amount) / 100.0f); + + if ((m_isunderwater & 0x01) && !(m_isunderwater & 0x80) && isAlive()) + { + //single trigger timer + if (!(m_isunderwater & 0x02)) + { + m_isunderwater|= 0x02; + m_breathTimer = UnderWaterTime + 1000; + } + //single trigger "Breathbar" + if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & 0x04)) + { + m_isunderwater|= 0x04; + StartMirrorTimer(BREATH_TIMER, UnderWaterTime); + } + //continius trigger drowning "Damage" + if ((m_breathTimer == 0) && (m_isunderwater & 0x01)) + { + //TODO: Check this formula + uint64 guid = GetGUID(); + uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1); + + EnvironmentalDamage(guid, DAMAGE_DROWNING,damage); + m_breathTimer = 2000; + } + } + //single trigger retract bar + else if (!(m_isunderwater & 0x01) && !(m_isunderwater & 0x08) && (m_isunderwater & 0x02) && (m_breathTimer > 0) && isAlive()) + { + m_isunderwater = 0x08; + + uint32 BreathRegen = 10; + ModifyMirrorTimer(BREATH_TIMER, UnderWaterTime, m_breathTimer,BreathRegen); + m_isunderwater = 0x10; + } + //remove bar + else if ((m_breathTimer < 50) && !(m_isunderwater & 0x01) && (m_isunderwater == 0x10)) + { + StopMirrorTimer(BREATH_TIMER); + m_isunderwater = 0; + } +} + +void Player::HandleLava() +{ + bool ValidArea = false; + + if ((m_isunderwater & 0x80) && isAlive()) + { + //Single trigger Set BreathTimer + if (!(m_isunderwater & 0x80)) + { + m_isunderwater|= 0x04; + m_breathTimer = 1000; + } + //Reset BreathTimer and still in the lava + if (!m_breathTimer) + { + uint64 guid = GetGUID(); + uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage + uint32 dmgZone = GetZoneId(); // TODO: Find correct "lava dealing zone" flag in Area Table + + // Deal lava damage only in lava zones. + switch(dmgZone) + { + case 0x8D: + ValidArea = false; + break; + case 0x94: + ValidArea = false; + break; + case 0x2CE: + ValidArea = false; + break; + case 0x2CF: + ValidArea = false; + break; + default: + if (dmgZone / 5 & 0x408) + ValidArea = true; + } + + // if is valid area and is not gamemaster then deal damage + if ( ValidArea && !isGameMaster() ) + EnvironmentalDamage(guid, DAMAGE_LAVA, damage); + + m_breathTimer = 1000; + } + + } + //Death timer disabled and WaterFlags reset + else if (m_deathState == DEAD) + { + m_breathTimer = 0; + m_isunderwater = 0; + } +} + +///The player sobers by 256 every 10 seconds +void Player::HandleSobering() +{ + m_drunkTimer = 0; + + uint32 drunk = (m_drunk <= 256) ? 0 : (m_drunk - 256); + SetDrunkValue(drunk); +} + +DrunkenState Player::GetDrunkenstateByValue(uint16 value) +{ + if(value >= 23000) + return DRUNKEN_SMASHED; + if(value >= 12800) + return DRUNKEN_DRUNK; + if(value & 0xFFFE) + return DRUNKEN_TIPSY; + return DRUNKEN_SOBER; +} + +void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId) +{ + uint32 oldDrunkenState = Player::GetDrunkenstateByValue(m_drunk); + + m_drunk = newDrunkenValue; + SetUInt32Value(PLAYER_BYTES_3,(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFF0001) | (m_drunk & 0xFFFE)); + + uint32 newDrunkenState = Player::GetDrunkenstateByValue(m_drunk); + + // special drunk invisibility detection + if(newDrunkenState >= DRUNKEN_DRUNK) + m_detectInvisibilityMask |= (1<<6); + else + m_detectInvisibilityMask &= ~(1<<6); + + if(newDrunkenState == oldDrunkenState) + return; + + WorldPacket data(SMSG_CROSSED_INEBRIATION_THRESHOLD, (8+4+4)); + data << GetGUID(); + data << uint32(newDrunkenState); + data << uint32(itemId); + + SendMessageToSet(&data, true); +} + +void Player::Update( uint32 p_time ) +{ + if(!IsInWorld()) + return; + + // undelivered mail + if(m_nextMailDelivereTime && m_nextMailDelivereTime <= time(NULL)) + { + SendNewMail(); + ++unReadMails; + + // It will be recalculate at mailbox open (for unReadMails important non-0 until mailbox open, it also will be recalculated) + m_nextMailDelivereTime = 0; + } + + Unit::Update( p_time ); + + // update player only attacks + if(uint32 ranged_att = getAttackTimer(RANGED_ATTACK)) + { + setAttackTimer(RANGED_ATTACK, (p_time >= ranged_att ? 0 : ranged_att - p_time) ); + } + + if(uint32 off_att = getAttackTimer(OFF_ATTACK)) + { + setAttackTimer(OFF_ATTACK, (p_time >= off_att ? 0 : off_att - p_time) ); + } + + time_t now = time (NULL); + + UpdatePvPFlag(now); + + UpdateContestedPvP(p_time); + + UpdateDuelFlag(now); + + CheckDuelDistance(now); + + UpdateAfkReport(now); + + CheckExploreSystem(); + + // Update items that have just a limited lifetime + if (now>m_Last_tick) + UpdateItemDuration(uint32(now- m_Last_tick)); + + if (!m_timedquests.empty()) + { + std::set::iterator iter = m_timedquests.begin(); + while (iter != m_timedquests.end()) + { + QuestStatusData& q_status = mQuestStatus[*iter]; + if( q_status.m_timer <= p_time ) + { + uint32 quest_id = *iter; + ++iter; // current iter will be removed in FailTimedQuest + FailTimedQuest( quest_id ); + } + else + { + q_status.m_timer -= p_time; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + ++iter; + } + } + } + + if (hasUnitState(UNIT_STAT_MELEE_ATTACKING)) + { + Unit *pVictim = getVictim(); + if( !IsNonMeleeSpellCasted(false) && pVictim) + { + // default combat reach 10 + // TODO add weapon,skill check + + float pldistance = ATTACK_DISTANCE; + + if (isAttackReady(BASE_ATTACK)) + { + if(!IsWithinDistInMap(pVictim, pldistance)) + { + setAttackTimer(BASE_ATTACK,100); + if(m_swingErrorMsg != 1) // send single time (client auto repeat) + { + SendAttackSwingNotInRange(); + m_swingErrorMsg = 1; + } + } + //120 degrees of radiant range + else if( !HasInArc( 2*M_PI/3, pVictim )) + { + setAttackTimer(BASE_ATTACK,100); + if(m_swingErrorMsg != 2) // send single time (client auto repeat) + { + SendAttackSwingBadFacingAttack(); + m_swingErrorMsg = 2; + } + } + else + { + m_swingErrorMsg = 0; // reset swing error state + + // prevent base and off attack in same time, delay attack at 0.2 sec + if(haveOffhandWeapon()) + { + uint32 off_att = getAttackTimer(OFF_ATTACK); + if(off_att < ATTACK_DISPLAY_DELAY) + setAttackTimer(OFF_ATTACK,ATTACK_DISPLAY_DELAY); + } + AttackerStateUpdate(pVictim, BASE_ATTACK); + resetAttackTimer(BASE_ATTACK); + } + } + + if ( haveOffhandWeapon() && isAttackReady(OFF_ATTACK)) + { + if(!IsWithinDistInMap(pVictim, pldistance)) + { + setAttackTimer(OFF_ATTACK,100); + } + else if( !HasInArc( 2*M_PI/3, pVictim )) + { + setAttackTimer(OFF_ATTACK,100); + } + else + { + // prevent base and off attack in same time, delay attack at 0.2 sec + uint32 base_att = getAttackTimer(BASE_ATTACK); + if(base_att < ATTACK_DISPLAY_DELAY) + setAttackTimer(BASE_ATTACK,ATTACK_DISPLAY_DELAY); + // do attack + AttackerStateUpdate(pVictim, OFF_ATTACK); + resetAttackTimer(OFF_ATTACK); + } + } + + Unit *owner = pVictim->GetOwner(); + Unit *u = owner ? owner : pVictim; + if(u->IsPvP() && (!duel || duel->opponent != u)) + { + UpdatePvP(true); + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); + } + } + } + + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) + { + if(roll_chance_i(3) && GetTimeInnEnter() > 0) //freeze update + { + int time_inn = time(NULL)-GetTimeInnEnter(); + if (time_inn >= 10) //freeze update + { + float bubble = 0.125*sWorld.getRate(RATE_REST_INGAME); + //speed collect rest bonus (section/in hour) + SetRestBonus( GetRestBonus()+ time_inn*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble ); + UpdateInnerTime(time(NULL)); + } + } + } + + if(m_regenTimer > 0) + { + if(p_time >= m_regenTimer) + m_regenTimer = 0; + else + m_regenTimer -= p_time; + } + + if (m_weaponChangeTimer > 0) + { + if(p_time >= m_weaponChangeTimer) + m_weaponChangeTimer = 0; + else + m_weaponChangeTimer -= p_time; + } + + if (m_zoneUpdateTimer > 0) + { + if(p_time >= m_zoneUpdateTimer) + { + uint32 newzone = GetZoneId(); + if( m_zoneUpdateId != newzone ) + UpdateZone(newzone); // also update area + else + { + // use area updates as well + // needed for free far all arenas for example + uint32 newarea = GetAreaId(); + if( m_areaUpdateId != newarea ) + UpdateArea(newarea); + + m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; + } + } + else + m_zoneUpdateTimer -= p_time; + } + + if (isAlive()) + { + RegenerateAll(); + } + + if (m_deathState == JUST_DIED) + { + KillPlayer(); + } + + if(m_nextSave > 0) + { + if(p_time >= m_nextSave) + { + // m_nextSave reseted in SaveToDB call + SaveToDB(); + sLog.outDetail("Player '%s' (GUID: %u) saved", GetName(), GetGUIDLow()); + } + else + { + m_nextSave -= p_time; + } + } + + //Breathtimer + if(m_breathTimer > 0) + { + if(p_time >= m_breathTimer) + m_breathTimer = 0; + else + m_breathTimer -= p_time; + + } + + //Handle Water/drowning + HandleDrowning(); + + //Handle lava + HandleLava(); + + //Handle detect stealth players + if (m_DetectInvTimer > 0) + { + if (p_time >= m_DetectInvTimer) + { + m_DetectInvTimer = 3000; + HandleStealthedUnitsDetection(); + } + else + m_DetectInvTimer -= p_time; + } + + // Played time + if (now > m_Last_tick) + { + uint32 elapsed = uint32(now - m_Last_tick); + m_Played_time[0] += elapsed; // Total played time + m_Played_time[1] += elapsed; // Level played time + m_Last_tick = now; + } + + if (m_drunk) + { + m_drunkTimer += p_time; + + if (m_drunkTimer > 10000) + HandleSobering(); + } + + // not auto-free ghost from body in instances + if(m_deathTimer > 0 && !GetBaseMap()->Instanceable()) + { + if(p_time >= m_deathTimer) + { + m_deathTimer = 0; + BuildPlayerRepop(); + RepopAtGraveyard(); + } + else + m_deathTimer -= p_time; + } + + UpdateEnchantTime(p_time); + UpdateHomebindTime(p_time); + + // group update + SendUpdateToOutOfRangeGroupMembers(); + + Pet* pet = GetPet(); + if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE)) + { + RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); + return; + } +} + +void Player::setDeathState(DeathState s) +{ + uint32 ressSpellId = 0; + + bool cur = isAlive(); + + if(s == JUST_DIED && cur) + { + // drunken state is cleared on death + SetDrunkValue(0); + // lost combo points at any target (targeted combo points clear in Unit::setDeathState) + ClearComboPoints(); + + clearResurrectRequestData(); + + // remove form before other mods to prevent incorrect stats calculation + RemoveAurasDueToSpell(m_ShapeShiftFormSpellId); + + //FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD) + RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + + // remove uncontrolled pets + RemoveMiniPet(); + RemoveGuardians(); + + // save value before aura remove in Unit::setDeathState + ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL); + + // passive spell + if(!ressSpellId) + ressSpellId = GetResurrectionSpellId(); + } + Unit::setDeathState(s); + + // restore resurrection spell id for player after aura remove + if(s == JUST_DIED && cur && ressSpellId) + SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId); + + if(isAlive() && !cur) + { + //clear aura case after resurrection by another way (spells will be applied before next death) + SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); + + // restore default warrior stance + if(getClass()== CLASS_WARRIOR) + CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); + } +} + +void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) +{ + *p_data << GetGUID(); + *p_data << m_name; + + *p_data << getRace(); + uint8 pClass = getClass(); + *p_data << pClass; + *p_data << getGender(); + + uint32 bytes = GetUInt32Value(PLAYER_BYTES); + *p_data << uint8(bytes); + *p_data << uint8(bytes >> 8); + *p_data << uint8(bytes >> 16); + *p_data << uint8(bytes >> 24); + + bytes = GetUInt32Value(PLAYER_BYTES_2); + *p_data << uint8(bytes); + + *p_data << uint8(getLevel()); // player level + // do not use GetMap! it will spawn a new instance since the bound instances are not loaded + uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY()); + + *p_data << zoneId; + *p_data << GetMapId(); + + *p_data << GetPositionX(); + *p_data << GetPositionY(); + *p_data << GetPositionZ(); + + *p_data << GetUInt32Value(PLAYER_GUILDID); // guild id + + uint32 char_flags = 0; + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) + char_flags |= CHARACTER_FLAG_HIDE_HELM; + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK)) + char_flags |= CHARACTER_FLAG_HIDE_CLOAK; + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + char_flags |= CHARACTER_FLAG_GHOST; + if(HasAtLoginFlag(AT_LOGIN_RENAME)) + char_flags |= CHARACTER_FLAG_RENAME; + // always send the flag if declined names aren't used + // to let the client select a default method of declining the name + if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[12].GetCppString() != "")) + char_flags |= CHARACTER_FLAG_DECLINED; + + *p_data << (uint32)char_flags; // character flags + + *p_data << (uint8)1; // unknown + + // Pets info + { + uint32 petDisplayId = 0; + uint32 petLevel = 0; + uint32 petFamily = 0; + + // show pet at selection character in character list only for non-ghost character + if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER)) + { + Field* fields = result->Fetch(); + + uint32 entry = fields[9].GetUInt32(); + CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(entry); + if(cInfo) + { + petDisplayId = fields[10].GetUInt32(); + petLevel = fields[11].GetUInt32(); + petFamily = cInfo->family; + } + } + + *p_data << (uint32)petDisplayId; + *p_data << (uint32)petLevel; + *p_data << (uint32)petFamily; + } + + /*ItemPrototype const *items[EQUIPMENT_SLOT_END]; + for (int i = 0; i < EQUIPMENT_SLOT_END; i++) + items[i] = NULL; + + QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow()); + if (result) + { + do + { + Field *fields = result->Fetch(); + uint8 slot = fields[0].GetUInt8() & 255; + uint32 item_id = fields[1].GetUInt32(); + if( slot >= EQUIPMENT_SLOT_END ) + continue; + + items[slot] = objmgr.GetItemPrototype(item_id); + if(!items[slot]) + { + sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id ); + continue; + } + } while (result->NextRow()); + delete result; + }*/ + + for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++) + { + uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); + uint32 item_id = GetUInt32Value(visualbase); + const ItemPrototype * proto = objmgr.GetItemPrototype(item_id); + SpellItemEnchantmentEntry const *enchant = NULL; + + for(uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot<=TEMP_ENCHANTMENT_SLOT; enchantSlot++) + { + uint32 enchantId = GetUInt32Value(visualbase+1+enchantSlot); + if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId)) + break; + } + + if (proto != NULL) + { + *p_data << (uint32)proto->DisplayInfoID; + *p_data << (uint8)proto->InventoryType; + *p_data << (uint32)(enchant?enchant->aura_id:0); + } + else + { + *p_data << (uint32)0; + *p_data << (uint8)0; + *p_data << (uint32)0; // enchant? + } + } + *p_data << (uint32)0; // first bag display id + *p_data << (uint8)0; // first bag inventory type + *p_data << (uint32)0; // enchant? +} + +bool Player::ToggleAFK() +{ + ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); + + bool state = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); + + // afk player not allowed in battleground + if(state && InBattleGround()) + LeaveBattleground(); + + return state; +} + +bool Player::ToggleDND() +{ + ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); + + return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); +} + +uint8 Player::chatTag() const +{ + // it's bitmask + // 0x8 - ?? + // 0x4 - gm + // 0x2 - dnd + // 0x1 - afk + if(isGMChat()) + return 4; + else if(isDND()) + return 3; + if(isAFK()) + return 1; + else + return 0; +} + +bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options) +{ + if(!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) + { + sLog.outError("TeleportTo: invalid map %d or absent instance template.", mapid); + return false; + } + + // preparing unsummon pet if lost (we must get pet before teleportation or will not find it later) + Pet* pet = GetPet(); + + MapEntry const* mEntry = sMapStore.LookupEntry(mapid); + + // don't let enter battlegrounds without assigned battleground id (for example through areatrigger)... + if(!InBattleGround() && mEntry->IsBattleGround() && !GetSession()->GetSecurity()) + return false; + + // client without expansion support + if(GetSession()->Expansion() < mEntry->Expansion()) + { + sLog.outDebug("Player %s using client without required expansion tried teleport to non accessable map %u", GetName(), mapid); + + if(GetTransport()) + RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :) + + SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL1); + + return false; // normal client can't teleport to this map... + } + else + { + sLog.outDebug("Player %s will teleported to map %u", GetName(), mapid); + } + + // if we were on a transport, leave + if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT) && m_transport) + { + m_transport->RemovePassenger(this); + m_transport = NULL; + m_movementInfo.t_x = 0.0f; + m_movementInfo.t_y = 0.0f; + m_movementInfo.t_z = 0.0f; + m_movementInfo.t_o = 0.0f; + m_movementInfo.t_time = 0; + } + + SetSemaphoreTeleport(true); + + // The player was ported to another map and looses the duel immediatly. + // We have to perform this check before the teleport, otherwise the + // ObjectAccessor won't find the flag. + if (duel && this->GetMapId()!=mapid) + { + GameObject* obj = ObjectAccessor::GetGameObject(*this, GetUInt64Value(PLAYER_DUEL_ARBITER)); + if (obj) + DuelComplete(DUEL_FLED); + } + + // reset movement flags at teleport, because player will continue move with these flags after teleport + SetUnitMovementFlags(0); + + if ((this->GetMapId() == mapid) && (!m_transport)) + { + // prepare zone change detect + uint32 old_zone = GetZoneId(); + + // near teleport + if(!GetSession()->PlayerLogout()) + { + WorldPacket data; + BuildTeleportAckMsg(&data, x, y, z, orientation); + GetSession()->SendPacket(&data); + SetPosition( x, y, z, orientation, true); + } + else + // this will be used instead of the current location in SaveToDB + m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + + //BuildHeartBeatMsg(&data); + //SendMessageToSet(&data, true); + if (!(options & TELE_TO_NOT_UNSUMMON_PET)) + { + //same map, only remove pet if out of range + if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE)) + { + if(pet->isControlled() && !pet->isTemporarySummoned() ) + m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber(); + else + m_temporaryUnsummonedPetNumber = 0; + + RemovePet(pet, PET_SAVE_NOT_IN_SLOT); + } + } + + if(!(options & TELE_TO_NOT_LEAVE_COMBAT)) + CombatStop(); + + if (!(options & TELE_TO_NOT_UNSUMMON_PET)) + { + // resummon pet + if(pet && m_temporaryUnsummonedPetNumber) + { + Pet* NewPet = new Pet; + if(!NewPet->LoadPetFromDB(this, 0, m_temporaryUnsummonedPetNumber, true)) + delete NewPet; + + m_temporaryUnsummonedPetNumber = 0; + } + } + + if(!GetSession()->PlayerLogout()) + { + // don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB + SetSemaphoreTeleport(false); + + UpdateZone(GetZoneId()); + } + + // new zone + if(old_zone != GetZoneId()) + { + // honorless target + if(pvpInfo.inHostileArea) + CastSpell(this, 2479, true); + } + } + else + { + // far teleport to another map + Map* oldmap = IsInWorld() ? MapManager::Instance().GetMap(GetMapId(), this) : NULL; + // check if we can enter before stopping combat / removing pet / totems / interrupting spells + + // Check enter rights before map getting to avoid creating instance copy for player + // this check not dependent from map instance copy and same for all instance copies of selected map + if (!MapManager::Instance().CanPlayerEnter(mapid, this)) + { + SetSemaphoreTeleport(false); + return false; + } + + // If the map is not created, assume it is possible to enter it. + // It will be created in the WorldPortAck. + Map *map = MapManager::Instance().FindMap(mapid); + if (!map || map->CanEnter(this)) + { + SetSelection(0); + + CombatStop(); + + ResetContestedPvP(); + + // remove player from battleground on far teleport (when changing maps) + if(BattleGround const* bg = GetBattleGround()) + { + // Note: at battleground join battleground id set before teleport + // and we already will found "current" battleground + // just need check that this is targeted map or leave + if(bg->GetMapId() != mapid) + LeaveBattleground(false); // don't teleport to entry point + } + + // remove pet on map change + if (pet) + { + //leaving map -> delete pet right away (doing this later will cause problems) + if(pet->isControlled() && !pet->isTemporarySummoned()) + m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber(); + else + m_temporaryUnsummonedPetNumber = 0; + + RemovePet(pet, PET_SAVE_NOT_IN_SLOT); + } + + // remove all dyn objects + RemoveAllDynObjects(); + + // stop spellcasting + // not attempt interrupt teleportation spell at caster teleport + if(!(options & TELE_TO_SPELL)) + if(IsNonMeleeSpellCasted(true)) + InterruptNonMeleeSpells(true); + + if(!GetSession()->PlayerLogout()) + { + // send transfer packets + WorldPacket data(SMSG_TRANSFER_PENDING, (4+4+4)); + data << uint32(mapid); + if (m_transport) + { + data << m_transport->GetEntry() << GetMapId(); + } + GetSession()->SendPacket(&data); + + data.Initialize(SMSG_NEW_WORLD, (20)); + if (m_transport) + { + data << (uint32)mapid << m_movementInfo.t_x << m_movementInfo.t_y << m_movementInfo.t_z << m_movementInfo.t_o; + } + else + { + data << (uint32)mapid << (float)x << (float)y << (float)z << (float)orientation; + } + GetSession()->SendPacket( &data ); + SendSavedInstances(); + + // remove from old map now + if(oldmap) oldmap->Remove(this, false); + } + + // new final coordinates + float final_x = x; + float final_y = y; + float final_z = z; + float final_o = orientation; + + if(m_transport) + { + final_x += m_movementInfo.t_x; + final_y += m_movementInfo.t_y; + final_z += m_movementInfo.t_z; + final_o += m_movementInfo.t_o; + } + + m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o); + // if the player is saved before worldportack (at logout for example) + // this will be used instead of the current location in SaveToDB + + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP); + + // move packet sent by client always after far teleport + // SetPosition(final_x, final_y, final_z, final_o, true); + SetDontMove(true); + + // code for finish transfer to new map called in WorldSession::HandleMoveWorldportAckOpcode at client packet + } + else + return false; + } + return true; +} + +void Player::AddToWorld() +{ + ///- Do not add/remove the player from the object storage + ///- It will crash when updating the ObjectAccessor + ///- The player should only be added when logging in + Unit::AddToWorld(); + + for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + { + if(m_items[i]) + m_items[i]->AddToWorld(); + } +} + +void Player::RemoveFromWorld() +{ + // cleanup + if(IsInWorld()) + { + ///- Release charmed creatures, unsummon totems and remove pets/guardians + Uncharm(); + UnsummonAllTotems(); + RemoveMiniPet(); + RemoveGuardians(); + } + + for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + { + if(m_items[i]) + m_items[i]->RemoveFromWorld(); + } + + ///- Do not add/remove the player from the object storage + ///- It will crash when updating the ObjectAccessor + ///- The player should only be removed when logging out + Unit::RemoveFromWorld(); +} + +void Player::RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker ) +{ + float addRage; + + float rageconversion = ((0.0091107836 * getLevel()*getLevel())+3.225598133*getLevel())+4.2652911; + + if(attacker) + { + addRage = ((damage/rageconversion*7.5 + weaponSpeedHitFactor)/2); + + // talent who gave more rage on attack + addRage *= 1.0f + GetTotalAuraModifier(SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT) / 100.0f; + } + else + { + addRage = damage/rageconversion*2.5; + + // Berserker Rage effect + if(HasAura(18499,0)) + addRage *= 1.3; + } + + addRage *= sWorld.getRate(RATE_POWER_RAGE_INCOME); + + ModifyPower(POWER_RAGE, uint32(addRage*10)); +} + +void Player::RegenerateAll() +{ + if (m_regenTimer != 0) + return; + uint32 regenDelay = 2000; + + // Not in combat or they have regeneration + if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) || + HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT) || IsPolymorphed() ) + { + RegenerateHealth(); + if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) + Regenerate(POWER_RAGE); + } + + Regenerate( POWER_ENERGY ); + + Regenerate( POWER_MANA ); + + m_regenTimer = regenDelay; +} + +void Player::Regenerate(Powers power) +{ + uint32 curValue = GetPower(power); + uint32 maxValue = GetMaxPower(power); + + float addvalue = 0.0f; + + switch (power) + { + case POWER_MANA: + { + bool recentCast = IsUnderLastManaUseEffect(); + float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA); + if (recentCast) + { + // Mangos Updates Mana in intervals of 2s, which is correct + addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f; + } + else + { + addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN) * ManaIncreaseRate * 2.00f; + } + } break; + case POWER_RAGE: // Regenerate rage + { + float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS); + addvalue = 30 * RageDecreaseRate; // 3 rage by tick + } break; + case POWER_ENERGY: // Regenerate energy (rogue) + addvalue = 20; + break; + case POWER_FOCUS: + case POWER_HAPPINESS: + break; + } + + // Mana regen calculated in Player::UpdateManaRegen() + // Exist only for POWER_MANA, POWER_ENERGY, POWER_FOCUS auras + if(power != POWER_MANA) + { + AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT); + for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue == power) + addvalue *= ((*i)->GetModifier()->m_amount + 100) / 100.0f; + } + + if (power != POWER_RAGE) + { + curValue += uint32(addvalue); + if (curValue > maxValue) + curValue = maxValue; + } + else + { + if(curValue <= uint32(addvalue)) + curValue = 0; + else + curValue -= uint32(addvalue); + } + SetPower(power, curValue); +} + +void Player::RegenerateHealth() +{ + uint32 curValue = GetHealth(); + uint32 maxValue = GetMaxHealth(); + + if (curValue >= maxValue) return; + + float HealthIncreaseRate = sWorld.getRate(RATE_HEALTH); + + float addvalue = 0.0f; + + // polymorphed case + if ( IsPolymorphed() ) + addvalue = GetMaxHealth()/3; + // normal regen case (maybe partly in combat case) + else if (!isInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) ) + { + addvalue = OCTRegenHPPerSpirit()* HealthIncreaseRate; + if (!isInCombat()) + { + AuraList const& mModHealthRegenPct = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT); + for(AuraList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i) + addvalue *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f; + } + else if(HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT)) + addvalue *= GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT) / 100.0f; + + if(!IsStandState()) + addvalue *= 1.5; + } + + // always regeneration bonus (including combat) + addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT); + + if(addvalue < 0) + addvalue = 0; + + ModifyHealth(int32(addvalue)); +} + +bool Player::CanInteractWithNPCs(bool alive) const +{ + if(alive && !isAlive()) + return false; + if(isInFlight()) + return false; + + return true; +} + +bool Player::IsUnderWater() const +{ + return IsInWater() && + GetPositionZ() < (MapManager::Instance().GetBaseMap(GetMapId())->GetWaterLevel(GetPositionX(),GetPositionY())-2); +} + +void Player::SetInWater(bool apply) +{ + if(m_isInWater==apply) + return; + + //define player in water by opcodes + //move player's guid into HateOfflineList of those mobs + //which can't swim and move guid back into ThreatList when + //on surface. + //TODO: exist also swimming mobs, and function must be symmetric to enter/leave water + m_isInWater = apply; + + // remove auras that need water/land + RemoveAurasWithInterruptFlags(apply ? AURA_INTERRUPT_FLAG_NOT_ABOVEWATER : AURA_INTERRUPT_FLAG_NOT_UNDERWATER); + + getHostilRefManager().updateThreatTables(); +} + +void Player::SetGameMaster(bool on) +{ + if(on) + { + m_ExtraFlags |= PLAYER_EXTRA_GM_ON; + setFaction(35); + SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); + + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); + ResetContestedPvP(); + + getHostilRefManager().setOnlineOfflineState(false); + CombatStop(); + } + else + { + m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; + setFactionForRace(getRace()); + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); + + // restore FFA PvP Server state + if(sWorld.IsFFAPvPRealm()) + SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + + // restore FFA PvP area state, remove not allowed for GM mounts + UpdateArea(m_areaUpdateId); + + getHostilRefManager().setOnlineOfflineState(true); + } + + ObjectAccessor::UpdateVisibilityForPlayer(this); +} + +void Player::SetGMVisible(bool on) +{ + if(on) + { + m_ExtraFlags &= ~PLAYER_EXTRA_GM_INVISIBLE; //remove flag + + // Reapply stealth/invisibility if active or show if not any + if(HasAuraType(SPELL_AURA_MOD_STEALTH)) + SetVisibility(VISIBILITY_GROUP_STEALTH); + else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) + SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + else + SetVisibility(VISIBILITY_ON); + } + else + { + m_ExtraFlags |= PLAYER_EXTRA_GM_INVISIBLE; //add flag + + SetAcceptWhispers(false); + SetGameMaster(true); + + SetVisibility(VISIBILITY_OFF); + } +} + +bool Player::IsGroupVisibleFor(Player* p) const +{ + switch(sWorld.getConfig(CONFIG_GROUP_VISIBILITY)) + { + default: return IsInSameGroupWith(p); + case 1: return IsInSameRaidWith(p); + case 2: return GetTeam()==p->GetTeam(); + } +} + +bool Player::IsInSameGroupWith(Player const* p) const +{ + return p==this || GetGroup() != NULL && + GetGroup() == p->GetGroup() && + GetGroup()->SameSubGroup((Player*)this, (Player*)p); +} + +///- If the player is invited, remove him. If the group if then only 1 person, disband the group. +/// \todo Shouldn't we also check if there is no other invitees before disbanding the group? +void Player::UninviteFromGroup() +{ + if(GetGroupInvite()) // uninvited invitee + { + Group* group = GetGroupInvite(); + group->RemoveInvite(this); + + if(group->GetMembersCount() <= 1) // group has just 1 member => disband + { + if(group->IsCreated()) + { + group->Disband(true); + objmgr.RemoveGroup(group); + } + else + group->RemoveAllInvites(); + + delete group; + } + } +} + +void Player::RemoveFromGroup(Group* group, uint64 guid) +{ + if(group) + { + if (group->RemoveMember(guid, 0) <= 1) + { + // group->Disband(); already disbanded in RemoveMember + objmgr.RemoveGroup(group); + delete group; + // removemember sets the player's group pointer to NULL + } + } +} + +void Player::SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 RestXP) +{ + WorldPacket data(SMSG_LOG_XPGAIN, 21); + data << uint64(victim ? victim->GetGUID() : 0); // guid + data << uint32(GivenXP+RestXP); // given experience + data << uint8(victim ? 0 : 1); // 00-kill_xp type, 01-non_kill_xp type + if(victim) + { + data << uint32(GivenXP); // experience without rested bonus + data << float(1); // 1 - none 0 - 100% group bonus output + } + data << uint8(0); // new 2.4.0 + GetSession()->SendPacket(&data); +} + +void Player::GiveXP(uint32 xp, Unit* victim) +{ + if ( xp < 1 ) + return; + + if(!isAlive()) + return; + + uint32 level = getLevel(); + + // XP to money conversion processed in Player::RewardQuest + if(level >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + return; + + // handle SPELL_AURA_MOD_XP_PCT auras + Unit::AuraList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT); + for(Unit::AuraList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i) + xp = uint32(xp*(1.0f + (*i)->GetModifier()->m_amount / 100.0f)); + + // XP resting bonus for kill + uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0; + + SendLogXPGain(xp,victim,rested_bonus_xp); + + uint32 curXP = GetUInt32Value(PLAYER_XP); + uint32 nextLvlXP = GetUInt32Value(PLAYER_NEXT_LEVEL_XP); + uint32 newXP = curXP + xp + rested_bonus_xp; + + while( newXP >= nextLvlXP && level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) + { + newXP -= nextLvlXP; + + if ( level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) + GiveLevel(level + 1); + + level = getLevel(); + nextLvlXP = GetUInt32Value(PLAYER_NEXT_LEVEL_XP); + } + + SetUInt32Value(PLAYER_XP, newXP); +} + +// Update player to next level +// Current player experience not update (must be update by caller) +void Player::GiveLevel(uint32 level) +{ + if ( level == getLevel() ) + return; + + PlayerLevelInfo info; + objmgr.GetPlayerLevelInfo(getRace(),getClass(),level,&info); + + PlayerClassLevelInfo classInfo; + objmgr.GetPlayerClassLevelInfo(getClass(),level,&classInfo); + + // send levelup info to client + WorldPacket data(SMSG_LEVELUP_INFO, (4+4+MAX_POWERS*4+MAX_STATS*4)); + data << uint32(level); + data << uint32(int32(classInfo.basehealth) - int32(GetCreateHealth())); + // for(int i = 0; i < MAX_POWERS; ++i) // Powers loop (0-6) + data << uint32(int32(classInfo.basemana) - int32(GetCreateMana())); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + // end for + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4) + data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i))); + + GetSession()->SendPacket(&data); + + SetUInt32Value(PLAYER_NEXT_LEVEL_XP, MaNGOS::XP::xp_to_level(level)); + + //update level, max level of skills + if(getLevel()!= level) + m_Played_time[1] = 0; // Level Played Time reset + SetLevel(level); + UpdateMaxSkills(); + + // save base values (bonuses already included in stored stats + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) + SetCreateStat(Stats(i), info.stats[i]); + + SetCreateHealth(classInfo.basehealth); + SetCreateMana(classInfo.basemana); + + InitTalentForLevel(); + InitTaxiNodesForLevel(); + + UpdateAllStats(); + + // set current level health and mana/energy to maximum after applying all mods. + SetHealth(GetMaxHealth()); + SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); + SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); + if(GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE)) + SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE)); + SetPower(POWER_FOCUS, 0); + SetPower(POWER_HAPPINESS, 0); + + // give level to summoned pet + Pet* pet = GetPet(); + if(pet && pet->getPetType()==SUMMON_PET) + pet->GivePetLevel(level); +} + +void Player::InitTalentForLevel() +{ + uint32 level = getLevel(); + // talents base at level diff ( talents = level - 9 but some can be used already) + if(level < 10) + { + // Remove all talent points + if(m_usedTalentCount > 0) // Free any used talents + { + resetTalents(true); + SetFreeTalentPoints(0); + } + } + else + { + uint32 talentPointsForLevel = uint32((level-9)*sWorld.getRate(RATE_TALENT)); + // if used more that have then reset + if(m_usedTalentCount > talentPointsForLevel) + { + if (GetSession()->GetSecurity() < SEC_ADMINISTRATOR) + resetTalents(true); + else + SetFreeTalentPoints(0); + } + // else update amount of free points + else + SetFreeTalentPoints(talentPointsForLevel-m_usedTalentCount); + } +} + +void Player::InitStatsForLevel(bool reapplyMods) +{ + if(reapplyMods) //reapply stats values only on .reset stats (level) command + _RemoveAllStatBonuses(); + + PlayerClassLevelInfo classInfo; + objmgr.GetPlayerClassLevelInfo(getClass(),getLevel(),&classInfo); + + PlayerLevelInfo info; + objmgr.GetPlayerLevelInfo(getRace(),getClass(),getLevel(),&info); + + SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ); + SetUInt32Value(PLAYER_NEXT_LEVEL_XP, MaNGOS::XP::xp_to_level(getLevel())); + + UpdateMaxSkills (); + + // set default cast time multiplier + SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + + // reset size before reapply auras + SetFloatValue(OBJECT_FIELD_SCALE_X,1.0f); + + // save base values (bonuses already included in stored stats + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) + SetCreateStat(Stats(i), info.stats[i]); + + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) + SetStat(Stats(i), info.stats[i]); + + SetCreateHealth(classInfo.basehealth); + + //set create powers + SetCreateMana(classInfo.basemana); + + SetArmor(int32(m_createStats[STAT_AGILITY]*2)); + + InitStatBuffMods(); + + //reset rating fields values + for(uint16 index = PLAYER_FIELD_COMBAT_RATING_1; index < PLAYER_FIELD_COMBAT_RATING_1 + MAX_COMBAT_RATING; ++index) + SetUInt32Value(index, 0); + + SetUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS,0); + for (int i = 0; i < 7; i++) + { + SetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i, 0); + SetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, 0); + SetFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i, 1.00f); + } + + //reset attack power, damage and attack speed fields + SetFloatValue(UNIT_FIELD_BASEATTACKTIME, 2000.0f ); + SetFloatValue(UNIT_FIELD_BASEATTACKTIME + 1, 2000.0f ); // offhand attack time + SetFloatValue(UNIT_FIELD_RANGEDATTACKTIME, 2000.0f ); + + SetFloatValue(UNIT_FIELD_MINDAMAGE, 0.0f ); + SetFloatValue(UNIT_FIELD_MAXDAMAGE, 0.0f ); + SetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, 0.0f ); + SetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, 0.0f ); + SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, 0.0f ); + SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, 0.0f ); + + SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 ); + SetUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0 ); + SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER,0.0f); + SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 ); + SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS,0 ); + SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER,0.0f); + + // Base crit values (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset + SetFloatValue(PLAYER_CRIT_PERCENTAGE,0.0f); + SetFloatValue(PLAYER_OFFHAND_CRIT_PERCENTAGE,0.0f); + SetFloatValue(PLAYER_RANGED_CRIT_PERCENTAGE,0.0f); + + // Init spell schools (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset + for (uint8 i = 0; i < 7; ++i) + SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1+i, 0.0f); + + SetFloatValue(PLAYER_PARRY_PERCENTAGE, 0.0f); + SetFloatValue(PLAYER_BLOCK_PERCENTAGE, 0.0f); + SetUInt32Value(PLAYER_SHIELD_BLOCK, 0); + + // Dodge percentage + SetFloatValue(PLAYER_DODGE_PERCENTAGE, 0.0f); + + // set armor (resistance 0) to original value (create_agility*2) + SetArmor(int32(m_createStats[STAT_AGILITY]*2)); + SetResistanceBuffMods(SpellSchools(0), true, 0.0f); + SetResistanceBuffMods(SpellSchools(0), false, 0.0f); + // set other resistance to original value (0) + for (int i = 1; i < MAX_SPELL_SCHOOL; i++) + { + SetResistance(SpellSchools(i), 0); + SetResistanceBuffMods(SpellSchools(i), true, 0.0f); + SetResistanceBuffMods(SpellSchools(i), false, 0.0f); + } + + SetUInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,0); + SetUInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,0); + for(int i = 0; i < MAX_SPELL_SCHOOL; ++i) + { + SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f); + SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f); + } + // Init data for form but skip reapply item mods for form + InitDataForForm(reapplyMods); + + // save new stats + for (int i = POWER_MANA; i < MAX_POWERS; i++) + SetMaxPower(Powers(i), uint32(GetCreatePowers(Powers(i)))); + + SetMaxHealth(classInfo.basehealth); // stamina bonus will applied later + + // cleanup mounted state (it will set correctly at aura loading if player saved at mount. + SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); + + // cleanup unit flags (will be re-applied if need at aura load). + RemoveFlag( UNIT_FIELD_FLAGS, + UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 | + UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED | + UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | + UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE | + UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT ); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set + + // cleanup player flags (will be re-applied if need at aura load), to avoid have ghost flag without ghost aura, for example. + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_FLAGS_FFA_PVP); + + SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00); // one form stealth modified bytes + + // restore if need some important flags + SetUInt32Value(PLAYER_FIELD_BYTES2, 0 ); // flags empty by default + + if(reapplyMods) //reapply stats values only on .reset stats (level) command + _ApplyAllStatBonuses(); + + // set current level health and mana/energy to maximum after applying all mods. + SetHealth(GetMaxHealth()); + SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); + SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); + if(GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE)) + SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE)); + SetPower(POWER_FOCUS, 0); + SetPower(POWER_HAPPINESS, 0); +} + +void Player::SendInitialSpells() +{ + uint16 spellCount = 0; + + WorldPacket data(SMSG_INITIAL_SPELLS, (1+2+4*m_spells.size()+2+m_spellCooldowns.size()*(2+2+2+4+4))); + data << uint8(0); + + size_t countPos = data.wpos(); + data << uint16(spellCount); // spell count placeholder + + for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PLAYERSPELL_REMOVED) + continue; + + if(!itr->second->active || itr->second->disabled) + continue; + + data << uint16(itr->first); + //data << uint16(itr->second->slotId); + data << uint16(0); // it's not slot id + + spellCount +=1; + } + + data.put(countPos,spellCount); // write real count value + + uint16 spellCooldowns = m_spellCooldowns.size(); + data << uint16(spellCooldowns); + for(SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr!=m_spellCooldowns.end(); itr++) + { + SpellEntry const *sEntry = sSpellStore.LookupEntry(itr->first); + if(!sEntry) + continue; + + data << uint16(itr->first); + + time_t cooldown = 0; + time_t curTime = time(NULL); + if(itr->second.end > curTime) + cooldown = (itr->second.end-curTime)*1000; + + data << uint16(itr->second.itemid); // cast item id + data << uint16(sEntry->Category); // spell category + if(sEntry->Category) // may be wrong, but anyway better than nothing... + { + data << uint32(0); + data << uint32(cooldown); + } + else + { + data << uint32(cooldown); + data << uint32(0); + } + } + + GetSession()->SendPacket(&data); + + sLog.outDetail( "CHARACTER: Sent Initial Spells" ); +} + +void Player::RemoveMail(uint32 id) +{ + for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end();++itr) + { + if ((*itr)->messageID == id) + { + //do not delete item, because Player::removeMail() is called when returning mail to sender. + m_mail.erase(itr); + return; + } + } +} + +void Player::SendMailResult(uint32 mailId, uint32 mailAction, uint32 mailError, uint32 equipError, uint32 item_guid, uint32 item_count) +{ + WorldPacket data(SMSG_SEND_MAIL_RESULT, (4+4+4+(mailError == MAIL_ERR_BAG_FULL?4:(mailAction == MAIL_ITEM_TAKEN?4+4:0)))); + data << (uint32) mailId; + data << (uint32) mailAction; + data << (uint32) mailError; + if ( mailError == MAIL_ERR_BAG_FULL ) + data << (uint32) equipError; + else if( mailAction == MAIL_ITEM_TAKEN ) + { + data << (uint32) item_guid; // item guid low? + data << (uint32) item_count; // item count? + } + GetSession()->SendPacket(&data); +} + +void Player::SendNewMail() +{ + // deliver undelivered mail + WorldPacket data(SMSG_RECEIVED_MAIL, 4); + data << (uint32) 0; + GetSession()->SendPacket(&data); +} + +void Player::UpdateNextMailTimeAndUnreads() +{ + // calculate next delivery time (min. from non-delivered mails + // and recalculate unReadMail + time_t cTime = time(NULL); + m_nextMailDelivereTime = 0; + unReadMails = 0; + for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr) + { + if((*itr)->deliver_time > cTime) + { + if(!m_nextMailDelivereTime || m_nextMailDelivereTime > (*itr)->deliver_time) + m_nextMailDelivereTime = (*itr)->deliver_time; + } + else if(((*itr)->checked & MAIL_CHECK_MASK_READ) == 0) + ++unReadMails; + } +} + +void Player::AddNewMailDeliverTime(time_t deliver_time) +{ + if(deliver_time <= time(NULL)) // ready now + { + ++unReadMails; + SendNewMail(); + } + else // not ready and no have ready mails + { + if(!m_nextMailDelivereTime || m_nextMailDelivereTime > deliver_time) + m_nextMailDelivereTime = deliver_time; + } +} + +bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, uint16 slot_id, bool disabled) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if (!spellInfo) + { + // do character spell book cleanup (all characters) + if(loading && !learning) // spell load case + { + sLog.outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.",spell_id); + CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id); + } + else + sLog.outError("Player::addSpell: Non-existed in SpellStore spell #%u request.",spell_id); + + return false; + } + + if(!SpellMgr::IsSpellValid(spellInfo,this,false)) + { + // do character spell book cleanup (all characters) + if(loading && !learning) // spell load case + { + sLog.outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.",spell_id); + CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id); + } + else + sLog.outError("Player::addSpell: Broken spell #%u learning not allowed.",spell_id); + + return false; + } + + PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED; + + bool disabled_case = false; + bool superceded_old = false; + + PlayerSpellMap::iterator itr = m_spells.find(spell_id); + if (itr != m_spells.end()) + { + // update active state for known spell + if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled) + { + itr->second->active = active; + + // loading && !learning == explicitly load from DB and then exist in it already and set correctly + if(loading && !learning) + itr->second->state = PLAYERSPELL_UNCHANGED; + else if(itr->second->state != PLAYERSPELL_NEW) + itr->second->state = PLAYERSPELL_CHANGED; + + if(!active) + { + WorldPacket data(SMSG_REMOVED_SPELL, 4); + data << uint16(spell_id); + GetSession()->SendPacket(&data); + } + return active; // learn (show in spell book if active now) + } + + if(itr->second->disabled != disabled && itr->second->state != PLAYERSPELL_REMOVED) + { + if(itr->second->state != PLAYERSPELL_NEW) + itr->second->state = PLAYERSPELL_CHANGED; + itr->second->disabled = disabled; + + if(disabled) + return false; + + disabled_case = true; + } + else switch(itr->second->state) + { + case PLAYERSPELL_UNCHANGED: // known saved spell + return false; + case PLAYERSPELL_REMOVED: // re-learning removed not saved spell + { + delete itr->second; + m_spells.erase(itr); + state = PLAYERSPELL_CHANGED; + break; // need re-add + } + default: // known not saved yet spell (new or modified) + { + // can be in case spell loading but learned at some previous spell loading + if(loading && !learning) + itr->second->state = PLAYERSPELL_UNCHANGED; + + return false; + } + } + } + + if(!disabled_case) // skip new spell adding if spell already known (disabled spells case) + { + // talent: unlearn all other talent ranks (high and low) + if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id)) + { + if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id )) + { + for(int i=0; i <5; ++i) + { + // skip learning spell and no rank spell case + uint32 rankSpellId = talentInfo->RankID[i]; + if(!rankSpellId || rankSpellId==spell_id) + continue; + + // skip unknown ranks + if(!HasSpell(rankSpellId)) + continue; + + removeSpell(rankSpellId); + } + } + } + // non talent spell: learn low ranks (recursive call) + else if(uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id)) + { + if(loading) // at spells loading, no output, but allow save + addSpell(prev_spell,active,true,loading,SPELL_WITHOUT_SLOT_ID,disabled); + else // at normal learning + learnSpell(prev_spell); + } + + PlayerSpell *newspell = new PlayerSpell; + newspell->active = active; + newspell->state = state; + newspell->disabled = disabled; + + // replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible + if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0) + { + for( PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr ) + { + if(itr->second->state == PLAYERSPELL_REMOVED) continue; + SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr->first); + if(!i_spellInfo) continue; + + if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr->first) ) + { + if(itr->second->active) + { + if(spellmgr.IsHighRankOfSpell(spell_id,itr->first)) + { + if(!loading) // not send spell (re-/over-)learn packets at loading + { + WorldPacket data(SMSG_SUPERCEDED_SPELL, (4)); + data << uint16(itr->first); + data << uint16(spell_id); + GetSession()->SendPacket( &data ); + } + + // mark old spell as disable (SMSG_SUPERCEDED_SPELL replace it in client by new) + itr->second->active = false; + itr->second->state = PLAYERSPELL_CHANGED; + superceded_old = true; // new spell replace old in action bars and spell book. + } + else if(spellmgr.IsHighRankOfSpell(itr->first,spell_id)) + { + if(!loading) // not send spell (re-/over-)learn packets at loading + { + WorldPacket data(SMSG_SUPERCEDED_SPELL, (4)); + data << uint16(spell_id); + data << uint16(itr->first); + GetSession()->SendPacket( &data ); + } + + // mark new spell as disable (not learned yet for client and will not learned) + newspell->active = false; + if(newspell->state != PLAYERSPELL_NEW) + newspell->state = PLAYERSPELL_CHANGED; + } + } + } + } + } + + uint16 tmpslot=slot_id; + + if (tmpslot == SPELL_WITHOUT_SLOT_ID) + { + uint16 maxid = 0; + PlayerSpellMap::iterator itr; + for (itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PLAYERSPELL_REMOVED) + continue; + if (itr->second->slotId > maxid) + maxid = itr->second->slotId; + } + tmpslot = maxid + 1; + } + + newspell->slotId = tmpslot; + m_spells[spell_id] = newspell; + + // return false if spell disabled + if (newspell->disabled) + return false; + } + + uint32 talentCost = GetTalentSpellCost(spell_id); + + // cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned) + // note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive + if( talentCost > 0 && IsSpellHaveEffect(spellInfo,SPELL_EFFECT_LEARN_SPELL) ) + { + // ignore stance requirement for talent learn spell (stance set for spell only for client spell description show) + CastSpell(this, spell_id, true); + } + // also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks + else if (IsPassiveSpell(spell_id)) + { + // if spell doesn't require a stance or the player is in the required stance + if( ( !spellInfo->Stances && + spell_id != 5420 && spell_id != 5419 && spell_id != 7376 && + spell_id != 7381 && spell_id != 21156 && spell_id != 21009 && + spell_id != 21178 && spell_id != 33948 && spell_id != 40121 ) || + m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))) || + (spell_id == 5420 && m_form == FORM_TREE) || + (spell_id == 5419 && m_form == FORM_TRAVEL) || + (spell_id == 7376 && m_form == FORM_DEFENSIVESTANCE) || + (spell_id == 7381 && m_form == FORM_BERSERKERSTANCE) || + (spell_id == 21156 && m_form == FORM_BATTLESTANCE)|| + (spell_id == 21178 && (m_form == FORM_BEAR || m_form == FORM_DIREBEAR) ) || + (spell_id == 33948 && m_form == FORM_FLIGHT) || + (spell_id == 40121 && m_form == FORM_FLIGHT_EPIC) ) + //Check CasterAuraStates + if (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState))) + CastSpell(this, spell_id, true); + } + else if( IsSpellHaveEffect(spellInfo,SPELL_EFFECT_SKILL_STEP) ) + { + CastSpell(this, spell_id, true); + return false; + } + + // update used talent points count + m_usedTalentCount += talentCost; + + // update free primary prof.points (if any, can be none in case GM .learn prof. learning) + if(uint32 freeProfs = GetFreePrimaryProffesionPoints()) + { + if(spellmgr.IsPrimaryProfessionFirstRankSpell(spell_id)) + SetFreePrimaryProffesions(freeProfs-1); + } + + // add dependent skills + uint16 maxskill = GetMaxSkillValueForLevel(); + + SpellLearnSkillNode const* spellLearnSkill = spellmgr.GetSpellLearnSkill(spell_id); + + if(spellLearnSkill) + { + uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill); + uint32 skill_max_value = GetPureMaxSkillValue(spellLearnSkill->skill); + + if(skill_value < spellLearnSkill->value) + skill_value = spellLearnSkill->value; + + uint32 new_skill_max_value = spellLearnSkill->maxvalue == 0 ? maxskill : spellLearnSkill->maxvalue; + + if(skill_max_value < new_skill_max_value) + skill_max_value = new_skill_max_value; + + SetSkill(spellLearnSkill->skill,skill_value,skill_max_value); + } + else + { + // not ranked skills + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->skillId); + if(!pSkill) + continue; + + if(HasSkill(pSkill->id)) + continue; + + if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || + // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 || + // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 ) + { + switch(GetSkillRangeType(pSkill,_spell_idx->second->racemask!=0)) + { + case SKILL_RANGE_LANGUAGE: + SetSkill(pSkill->id, 300, 300 ); + break; + case SKILL_RANGE_LEVEL: + SetSkill(pSkill->id, 1, GetMaxSkillValueForLevel() ); + break; + case SKILL_RANGE_MONO: + SetSkill(pSkill->id, 1, 1 ); + break; + default: + break; + } + } + } + } + + // learn dependent spells + SpellLearnSpellMap::const_iterator spell_begin = spellmgr.GetBeginSpellLearnSpell(spell_id); + SpellLearnSpellMap::const_iterator spell_end = spellmgr.GetEndSpellLearnSpell(spell_id); + + for(SpellLearnSpellMap::const_iterator itr = spell_begin; itr != spell_end; ++itr) + { + if(!itr->second.autoLearned) + { + if(loading) // at spells loading, no output, but allow save + addSpell(itr->second.spell,true,true,loading); + else // at normal learning + learnSpell(itr->second.spell); + } + } + + // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell + return active && !disabled && !superceded_old; +} + +void Player::learnSpell(uint32 spell_id) +{ + PlayerSpellMap::iterator itr = m_spells.find(spell_id); + + bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false; + bool active = disabled ? itr->second->active : true; + + bool learning = addSpell(spell_id,active); + + // learn all disabled higher ranks (recursive) + SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext(); + for(SpellChainMapNext::const_iterator i = nextMap.lower_bound(spell_id); i != nextMap.upper_bound(spell_id); ++i) + { + PlayerSpellMap::iterator iter = m_spells.find(i->second); + if (disabled && iter != m_spells.end() && iter->second->disabled) + learnSpell(i->second); + } + + // prevent duplicated entires in spell book + if(!learning) + return; + + WorldPacket data(SMSG_LEARNED_SPELL, 4); + data << uint32(spell_id); + GetSession()->SendPacket(&data); +} + +void Player::removeSpell(uint32 spell_id, bool disabled) +{ + PlayerSpellMap::iterator itr = m_spells.find(spell_id); + if (itr == m_spells.end()) + return; + + if(itr->second->state == PLAYERSPELL_REMOVED || disabled && itr->second->disabled) + return; + + // unlearn non talent higher ranks (recursive) + SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext(); + for(SpellChainMapNext::const_iterator itr2 = nextMap.lower_bound(spell_id); itr2 != nextMap.upper_bound(spell_id); ++itr2) + if(HasSpell(itr2->second) && !GetTalentSpellPos(itr2->second)) + removeSpell(itr2->second,disabled); + + // removing + WorldPacket data(SMSG_REMOVED_SPELL, 4); + data << uint16(spell_id); + GetSession()->SendPacket(&data); + + if (disabled) + { + itr->second->disabled = disabled; + if(itr->second->state != PLAYERSPELL_NEW) + itr->second->state = PLAYERSPELL_CHANGED; + } + else + { + if(itr->second->state == PLAYERSPELL_NEW) + { + delete itr->second; + m_spells.erase(itr); + } + else + itr->second->state = PLAYERSPELL_REMOVED; + } + + RemoveAurasDueToSpell(spell_id); + + // remove pet auras + if(PetAura const* petSpell = spellmgr.GetPetAura(spell_id)) + RemovePetAura(petSpell); + + // free talent points + uint32 talentCosts = GetTalentSpellCost(spell_id); + if(talentCosts > 0) + { + if(talentCosts < m_usedTalentCount) + m_usedTalentCount -= talentCosts; + else + m_usedTalentCount = 0; + } + + // update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning) + if(spellmgr.IsPrimaryProfessionFirstRankSpell(spell_id)) + { + uint32 freeProfs = GetFreePrimaryProffesionPoints()+1; + if(freeProfs <= sWorld.getConfig(CONFIG_MAX_PRIMARY_TRADE_SKILL)) + SetFreePrimaryProffesions(freeProfs); + } + + // remove dependent skill + SpellLearnSkillNode const* spellLearnSkill = spellmgr.GetSpellLearnSkill(spell_id); + if(spellLearnSkill) + { + uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id); + if(!prev_spell) // first rank, remove skill + SetSkill(spellLearnSkill->skill,0,0); + else + { + // search prev. skill setting by spell ranks chain + SpellLearnSkillNode const* prevSkill = spellmgr.GetSpellLearnSkill(prev_spell); + while(!prevSkill && prev_spell) + { + prev_spell = spellmgr.GetPrevSpellInChain(prev_spell); + prevSkill = spellmgr.GetSpellLearnSkill(spellmgr.GetFirstSpellInChain(prev_spell)); + } + + if(!prevSkill) // not found prev skill setting, remove skill + SetSkill(spellLearnSkill->skill,0,0); + else // set to prev. skill setting values + { + uint32 skill_value = GetPureSkillValue(prevSkill->skill); + uint32 skill_max_value = GetPureMaxSkillValue(prevSkill->skill); + + if(skill_value > prevSkill->value) + skill_value = prevSkill->value; + + uint32 new_skill_max_value = prevSkill->maxvalue == 0 ? GetMaxSkillValueForLevel() : prevSkill->maxvalue; + + if(skill_max_value > new_skill_max_value) + skill_max_value = new_skill_max_value; + + SetSkill(prevSkill->skill,skill_value,skill_max_value); + } + } + + } + else + { + // not ranked skills + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->skillId); + if(!pSkill) + continue; + + if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || + // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 || + // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 ) + { + // not reset skills for professions and racial abilities + if( (pSkill->categoryId==SKILL_CATEGORY_SECONDARY || pSkill->categoryId==SKILL_CATEGORY_PROFESSION) && + (IsProfessionSkill(pSkill->id) || _spell_idx->second->racemask!=0) ) + continue; + + SetSkill(pSkill->id, 0, 0 ); + } + } + } + + // remove dependent spells + SpellLearnSpellMap::const_iterator spell_begin = spellmgr.GetBeginSpellLearnSpell(spell_id); + SpellLearnSpellMap::const_iterator spell_end = spellmgr.GetEndSpellLearnSpell(spell_id); + + for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2) + removeSpell(itr2->second.spell, disabled); +} + +void Player::RemoveArenaSpellCooldowns() +{ + // remove cooldowns on spells that has < 15 min CD + SpellCooldowns::iterator itr, next; + // iterate spell cooldowns + for(itr = m_spellCooldowns.begin();itr != m_spellCooldowns.end(); itr = next) + { + next = itr; + ++next; + SpellEntry const * entry = sSpellStore.LookupEntry(itr->first); + // check if spellentry is present and if the cooldown is less than 15 mins + if( entry && + entry->RecoveryTime <= 15 * MINUTE * 1000 && + entry->CategoryRecoveryTime <= 15 * MINUTE * 1000 ) + { + // notify player + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(itr->first); + data << GetGUID(); + GetSession()->SendPacket(&data); + // remove cooldown + m_spellCooldowns.erase(itr); + } + } +} + +void Player::RemoveAllSpellCooldown() +{ + if(!m_spellCooldowns.empty()) + { + for(SpellCooldowns::const_iterator itr = m_spellCooldowns.begin();itr != m_spellCooldowns.end(); ++itr) + { + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(itr->first); + data << uint64(GetGUID()); + GetSession()->SendPacket(&data); + } + m_spellCooldowns.clear(); + } +} + +void Player::_LoadSpellCooldowns(QueryResult *result) +{ + m_spellCooldowns.clear(); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'",GetGUIDLow()); + + if(result) + { + time_t curTime = time(NULL); + + do + { + Field *fields = result->Fetch(); + + uint32 spell_id = fields[0].GetUInt32(); + uint32 item_id = fields[1].GetUInt32(); + time_t db_time = (time_t)fields[2].GetUInt64(); + + if(!sSpellStore.LookupEntry(spell_id)) + { + sLog.outError("Player %u have unknown spell %u in `character_spell_cooldown`, skipping.",GetGUIDLow(),spell_id); + continue; + } + + // skip outdated cooldown + if(db_time <= curTime) + continue; + + AddSpellCooldown(spell_id, item_id, db_time); + + sLog.outDebug("Player (GUID: %u) spell %u, item %u cooldown loaded (%u secs).", GetGUIDLow(), spell_id, item_id, uint32(db_time-curTime)); + } + while( result->NextRow() ); + + delete result; + } +} + +void Player::_SaveSpellCooldowns() +{ + CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow()); + + time_t curTime = time(NULL); + + // remove outdated and save active + for(SpellCooldowns::iterator itr = m_spellCooldowns.begin();itr != m_spellCooldowns.end();) + { + if(itr->second.end <= curTime) + m_spellCooldowns.erase(itr++); + else + { + CharacterDatabase.PExecute("INSERT INTO character_spell_cooldown (guid,spell,item,time) VALUES ('%u', '%u', '%u', '" I64FMTD "')", GetGUIDLow(), itr->first, itr->second.itemid, uint64(itr->second.end)); + ++itr; + } + } +} + +uint32 Player::resetTalentsCost() const +{ + // The first time reset costs 1 gold + if(m_resetTalentsCost < 1*GOLD) + return 1*GOLD; + // then 5 gold + else if(m_resetTalentsCost < 5*GOLD) + return 5*GOLD; + // After that it increases in increments of 5 gold + else if(m_resetTalentsCost < 10*GOLD) + return 10*GOLD; + else + { + uint32 months = (sWorld.GetGameTime() - m_resetTalentsTime)/MONTH; + if(months > 0) + { + // This cost will be reduced by a rate of 5 gold per month + int32 new_cost = int32(m_resetTalentsCost) - 5*GOLD*months; + // to a minimum of 10 gold. + return (new_cost < 10*GOLD ? 10*GOLD : new_cost); + } + else + { + // After that it increases in increments of 5 gold + int32 new_cost = m_resetTalentsCost + 5*GOLD; + // until it hits a cap of 50 gold. + if(new_cost > 50*GOLD) + new_cost = 50*GOLD; + return new_cost; + } + } +} + +bool Player::resetTalents(bool no_cost) +{ + // not need after this call + if(HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) + { + m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_TALENTS; + CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_TALENTS), GetGUIDLow()); + } + + uint32 level = getLevel(); + uint32 talentPointsForLevel = level < 10 ? 0 : uint32((level-9)*sWorld.getRate(RATE_TALENT)); + + if (m_usedTalentCount == 0) + { + SetFreeTalentPoints(talentPointsForLevel); + return false; + } + + uint32 cost = 0; + + if(!no_cost) + { + cost = resetTalentsCost(); + + if (GetMoney() < cost) + { + SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); + return false; + } + } + + for (unsigned int i = 0; i < sTalentStore.GetNumRows(); i++) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + + if (!talentInfo) continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + + if(!talentTabInfo) + continue; + + // unlearn only talents for character class + // some spell learned by one class as normal spells or know at creation but another class learn it as talent, + // to prevent unexpected lost normal learned spell skip another class talents + if( (getClassMask() & talentTabInfo->ClassMask) == 0 ) + continue; + + for (int j = 0; j < 5; j++) + { + for(PlayerSpellMap::iterator itr = GetSpellMap().begin(); itr != GetSpellMap().end();) + { + if(itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled) + { + ++itr; + continue; + } + + // remove learned spells (all ranks) + uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first); + + // unlearn if first rank is talent or learned by talent + if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId)) + { + removeSpell(itr->first,!IsPassiveSpell(itr->first)); + itr = GetSpellMap().begin(); + continue; + } + else + ++itr; + } + } + } + + SetFreeTalentPoints(talentPointsForLevel); + + if(!no_cost) + { + ModifyMoney(-(int32)cost); + + m_resetTalentsCost = cost; + m_resetTalentsTime = time(NULL); + } + + //FIXME: remove pet before or after unlearn spells? for now after unlearn to allow removing of talent related, pet affecting auras + RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true); + + return true; +} + +bool Player::_removeSpell(uint16 spell_id) +{ + PlayerSpellMap::iterator itr = m_spells.find(spell_id); + if (itr != m_spells.end()) + { + delete itr->second; + m_spells.erase(itr); + return true; + } + return false; +} + +Mail* Player::GetMail(uint32 id) +{ + for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); itr++) + { + if ((*itr)->messageID == id) + { + return (*itr); + } + } + return NULL; +} + +void Player::_SetCreateBits(UpdateMask *updateMask, Player *target) const +{ + if(target == this) + { + Object::_SetCreateBits(updateMask, target); + } + else + { + for(uint16 index = 0; index < m_valuesCount; index++) + { + if(GetUInt32Value(index) != 0 && updateVisualBits.GetBit(index)) + updateMask->SetBit(index); + } + } +} + +void Player::_SetUpdateBits(UpdateMask *updateMask, Player *target) const +{ + if(target == this) + { + Object::_SetUpdateBits(updateMask, target); + } + else + { + Object::_SetUpdateBits(updateMask, target); + *updateMask &= updateVisualBits; + } +} + +void Player::InitVisibleBits() +{ + updateVisualBits.SetCount(PLAYER_END); + + updateVisualBits.SetBit(OBJECT_FIELD_GUID); + updateVisualBits.SetBit(OBJECT_FIELD_TYPE); + updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X); + + updateVisualBits.SetBit(UNIT_FIELD_CHARM); + updateVisualBits.SetBit(UNIT_FIELD_CHARM+1); + + updateVisualBits.SetBit(UNIT_FIELD_SUMMON); + updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1); + + updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY); + + updateVisualBits.SetBit(UNIT_FIELD_TARGET); + updateVisualBits.SetBit(UNIT_FIELD_TARGET+1); + + updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT); + updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT+1); + + updateVisualBits.SetBit(UNIT_FIELD_HEALTH); + updateVisualBits.SetBit(UNIT_FIELD_POWER1); + updateVisualBits.SetBit(UNIT_FIELD_POWER2); + updateVisualBits.SetBit(UNIT_FIELD_POWER3); + updateVisualBits.SetBit(UNIT_FIELD_POWER4); + updateVisualBits.SetBit(UNIT_FIELD_POWER5); + + updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER3); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER4); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5); + + updateVisualBits.SetBit(UNIT_FIELD_LEVEL); + updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE); + updateVisualBits.SetBit(UNIT_FIELD_BYTES_0); + updateVisualBits.SetBit(UNIT_FIELD_FLAGS); + updateVisualBits.SetBit(UNIT_FIELD_FLAGS_2); + for(uint16 i = UNIT_FIELD_AURA; i < UNIT_FIELD_AURASTATE; ++i) + updateVisualBits.SetBit(i); + updateVisualBits.SetBit(UNIT_FIELD_AURASTATE); + updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME); + updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1); + updateVisualBits.SetBit(UNIT_FIELD_RANGEDATTACKTIME); + updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS); + updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH); + updateVisualBits.SetBit(UNIT_FIELD_DISPLAYID); + updateVisualBits.SetBit(UNIT_FIELD_NATIVEDISPLAYID); + updateVisualBits.SetBit(UNIT_FIELD_MOUNTDISPLAYID); + updateVisualBits.SetBit(UNIT_FIELD_BYTES_1); + updateVisualBits.SetBit(UNIT_FIELD_MOUNTDISPLAYID); + updateVisualBits.SetBit(UNIT_FIELD_PETNUMBER); + updateVisualBits.SetBit(UNIT_FIELD_PET_NAME_TIMESTAMP); + updateVisualBits.SetBit(UNIT_DYNAMIC_FLAGS); + updateVisualBits.SetBit(UNIT_CHANNEL_SPELL); + updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED); + updateVisualBits.SetBit(UNIT_FIELD_BYTES_2); + + updateVisualBits.SetBit(PLAYER_FLAGS); + updateVisualBits.SetBit(PLAYER_BYTES); + updateVisualBits.SetBit(PLAYER_BYTES_2); + updateVisualBits.SetBit(PLAYER_BYTES_3); + updateVisualBits.SetBit(PLAYER_GUILDID); + updateVisualBits.SetBit(PLAYER_GUILDRANK); + updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP); + updateVisualBits.SetBit(PLAYER_DUEL_TEAM); + updateVisualBits.SetBit(PLAYER_DUEL_ARBITER); + updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1); + + // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)... + for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4) + updateVisualBits.SetBit(i); + + //Players visible items are not inventory stuff + //431) = 884 (0x374) = main weapon + for(uint16 i = 0; i < EQUIPMENT_SLOT_END; i++) + { + // item creator + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 0); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 1); + + uint16 visual_base = PLAYER_VISIBLE_ITEM_1_0 + (i*MAX_VISIBLE_ITEM_OFFSET); + + // item entry + updateVisualBits.SetBit(visual_base + 0); + + // item enchantment IDs + for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) + updateVisualBits.SetBit(visual_base + 1 + j); + + // random properties + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (i*MAX_VISIBLE_ITEM_OFFSET)); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (i*MAX_VISIBLE_ITEM_OFFSET)); + } + + updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE); + + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 1); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 2); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 3); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 4); + updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 5); +} + +void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const +{ + for(int i = 0; i < EQUIPMENT_SLOT_END; i++) + { + if(m_items[i] == NULL) + continue; + + m_items[i]->BuildCreateUpdateBlockForPlayer( data, target ); + } + + if(target == this) + { + + for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + if(m_items[i] == NULL) + continue; + + m_items[i]->BuildCreateUpdateBlockForPlayer( data, target ); + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + if(m_items[i] == NULL) + continue; + + m_items[i]->BuildCreateUpdateBlockForPlayer( data, target ); + } + } + + Unit::BuildCreateUpdateBlockForPlayer( data, target ); +} + +void Player::DestroyForPlayer( Player *target ) const +{ + Unit::DestroyForPlayer( target ); + + for(int i = 0; i < INVENTORY_SLOT_BAG_END; i++) + { + if(m_items[i] == NULL) + continue; + + m_items[i]->DestroyForPlayer( target ); + } + + if(target == this) + { + + for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + if(m_items[i] == NULL) + continue; + + m_items[i]->DestroyForPlayer( target ); + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + if(m_items[i] == NULL) + continue; + + m_items[i]->DestroyForPlayer( target ); + } + } +} + +bool Player::HasSpell(uint32 spell) const +{ + PlayerSpellMap::const_iterator itr = m_spells.find((uint16)spell); + return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled); +} + +TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const +{ + if (!trainer_spell) + return TRAINER_SPELL_RED; + + if (!trainer_spell->spell) + return TRAINER_SPELL_RED; + + // known spell + if(HasSpell(trainer_spell->spell)) + return TRAINER_SPELL_GRAY; + + // check race/class requirement + if(!IsSpellFitByClassAndRace(trainer_spell->spell)) + return TRAINER_SPELL_RED; + + // check level requirement + if(getLevel() < trainer_spell->reqlevel) + return TRAINER_SPELL_RED; + + if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->spell)) + { + // check prev.rank requirement + if(spell_chain->prev && !HasSpell(spell_chain->prev)) + return TRAINER_SPELL_RED; + + // check additional spell requirement + if(spell_chain->req && !HasSpell(spell_chain->req)) + return TRAINER_SPELL_RED; + } + + // check skill requirement + if(trainer_spell->reqskill && GetBaseSkillValue(trainer_spell->reqskill) < trainer_spell->reqskillvalue) + return TRAINER_SPELL_RED; + + // exist, already checked at loading + SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->spell); + + // secondary prof. or not prof. spell + uint32 skill = spell->EffectMiscValue[1]; + + if(spell->Effect[1] != SPELL_EFFECT_SKILL || !IsPrimaryProfessionSkill(skill)) + return TRAINER_SPELL_GREEN; + + // check primary prof. limit + if(spellmgr.IsPrimaryProfessionFirstRankSpell(spell->Id) && GetFreePrimaryProffesionPoints() == 0) + return TRAINER_SPELL_RED; + + return TRAINER_SPELL_GREEN; +} + +void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars) +{ + uint32 guid = GUID_LOPART(playerguid); + + // convert corpse to bones if exist (to prevent exiting Corpse in World without DB entry) + // bones will be deleted by corpse/bones deleting thread shortly + ObjectAccessor::Instance().ConvertCorpseForPlayer(playerguid); + + // remove from guild + uint32 guildId = GetGuildIdFromDB(playerguid); + if(guildId != 0) + { + Guild* guild = objmgr.GetGuildById(guildId); + if(guild) + guild->DelMember(guid); + } + + // the player was uninvited already on logout so just remove from group + QueryResult *resultGroup = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", guid); + if(resultGroup) + { + uint64 leaderGuid = MAKE_NEW_GUID((*resultGroup)[0].GetUInt32(), 0, HIGHGUID_PLAYER); + delete resultGroup; + Group* group = objmgr.GetGroupByLeader(leaderGuid); + if(group) + { + RemoveFromGroup(group, playerguid); + } + } + + // remove signs from petitions (also remove petitions if owner); + RemovePetitionsAndSigns(playerguid, 10); + + // return back all mails with COD and Item 0 1 2 3 4 5 6 + QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,mailTemplateId,sender,subject,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid); + if(resultMail) + { + do + { + Field *fields = resultMail->Fetch(); + + uint32 mail_id = fields[0].GetUInt32(); + uint16 mailTemplateId= fields[1].GetUInt16(); + uint32 sender = fields[2].GetUInt32(); + std::string subject = fields[3].GetCppString(); + uint32 itemTextId = fields[4].GetUInt32(); + uint32 money = fields[5].GetUInt32(); + bool has_items = fields[6].GetBool(); + + //we can return mail now + //so firstly delete the old one + CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mail_id); + + MailItemsInfo mi; + if(has_items) + { + QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", mail_id); + if(resultItems) + { + do + { + Field *fields2 = resultItems->Fetch(); + + uint32 item_guidlow = fields2[0].GetUInt32(); + uint32 item_template = fields2[1].GetUInt32(); + + ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_template); + if(!itemProto) + { + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guidlow); + continue; + } + + Item *pItem = NewItemOrBag(itemProto); + if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER))) + { + pItem->FSetState(ITEM_REMOVED); + pItem->SaveToDB(); // it also deletes item object ! + continue; + } + + mi.AddItem(item_guidlow, item_template, pItem); + } + while (resultItems->NextRow()); + + delete resultItems; + } + } + + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id); + + uint32 pl_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); + + WorldSession::SendReturnToSender(MAIL_NORMAL, pl_account, guid, sender, subject, itemTextId, &mi, money, 0, mailTemplateId); + } + while (resultMail->NextRow()); + + delete resultMail; + } + + // unsummon and delete for pets in world is not required: player deleted from CLI or character list with not loaded pet. + // Get guids of character's pets, will deleted in transaction + QueryResult *resultPets = CharacterDatabase.PQuery("SELECT id FROM character_pet WHERE owner = '%u'",guid); + + // NOW we can finally clear other DB data related to character + CharacterDatabase.BeginTransaction(); + if (resultPets) + { + do + { + Field *fields3 = resultPets->Fetch(); + uint32 petguidlow = fields3[0].GetUInt32(); + Pet::DeleteFromDB(petguidlow); + } while (resultPets->NextRow()); + delete resultPets; + } + + CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_homebind WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM group_instance WHERE leaderGuid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_queststatus WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE owner_guid = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid); + CharacterDatabase.PExecute("DELETE FROM mail WHERE receiver = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid); + CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid); + CharacterDatabase.CommitTransaction(); + + //loginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID); + if(updateRealmChars) sWorld.UpdateRealmCharCount(accountId); +} + +void Player::SetMovement(PlayerMovementType pType) +{ + WorldPacket data; + switch(pType) + { + case MOVE_ROOT: data.Initialize(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size()+4); break; + case MOVE_UNROOT: data.Initialize(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size()+4); break; + case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_WATER_WALK, GetPackGUID().size()+4); break; + case MOVE_LAND_WALK: data.Initialize(SMSG_MOVE_LAND_WALK, GetPackGUID().size()+4); break; + default: + sLog.outError("Player::SetMovement: Unsupported move type (%d), data not sent to client.",pType); + return; + } + data.append(GetPackGUID()); + data << uint32(0); + GetSession()->SendPacket( &data ); +} + +/* Preconditions: + - a resurrectable corpse must not be loaded for the player (only bones) + - the player must be in world +*/ +void Player::BuildPlayerRepop() +{ + if(getRace() == RACE_NIGHTELF) + CastSpell(this, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) + CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) + + // there must be SMSG.FORCE_RUN_SPEED_CHANGE, SMSG.FORCE_SWIM_SPEED_CHANGE, SMSG.MOVE_WATER_WALK + // there must be SMSG.STOP_MIRROR_TIMER + // there we must send 888 opcode + + // the player cannot have a corpse already, only bones which are not returned by GetCorpse + if(GetCorpse()) + { + sLog.outError("BuildPlayerRepop: player %s(%d) already has a corpse", GetName(), GetGUIDLow()); + assert(false); + } + + // create a corpse and place it at the player's location + CreateCorpse(); + Corpse *corpse = GetCorpse(); + if(!corpse) + { + sLog.outError("Error creating corpse for Player %s [%u]", GetName(), GetGUIDLow()); + return; + } + GetMap()->Add(corpse); + + // convert player body to ghost + SetHealth( 1 ); + + SetMovement(MOVE_WATER_WALK); + if(!GetSession()->isLogingOut()) + SetMovement(MOVE_UNROOT); + + // BG - remove insignia related + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + + SendCorpseReclaimDelay(); + + // to prevent cheating + corpse->ResetGhostTime(); + + StopMirrorTimers(); //disable timers(bars) + + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, (float)1.0); //see radius of death player? + + SetByteValue(UNIT_FIELD_BYTES_1, 3, PLAYER_STATE_FLAG_ALWAYS_STAND); +} + +void Player::SendDelayResponse(const uint32 ml_seconds) +{ + WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 ); + data << (uint32)time(NULL); + data << (uint32)0; + GetSession()->SendPacket( &data ); +} + +void Player::ResurrectPlayer(float restore_percent, bool updateToWorld, bool applySickness) +{ + WorldPacket data(SMSG_DEATH_RELEASE_LOC, 4*4); // remove spirit healer position + data << uint32(-1); + data << float(0); + data << float(0); + data << float(0); + GetSession()->SendPacket(&data); + + // speed change, land walk + + // remove death flag + set aura + SetByteValue(UNIT_FIELD_BYTES_1, 3, 0x00); + if(getRace() == RACE_NIGHTELF) + RemoveAurasDueToSpell(20584); // speed bonuses + RemoveAurasDueToSpell(8326); // SPELL_AURA_GHOST + + setDeathState(ALIVE); + + SetMovement(MOVE_LAND_WALK); + SetMovement(MOVE_UNROOT); + + m_deathTimer = 0; + + // set health/powers (0- will be set in caller) + if(restore_percent>0.0f) + { + SetHealth(uint32(GetMaxHealth()*restore_percent)); + SetPower(POWER_MANA, uint32(GetMaxPower(POWER_MANA)*restore_percent)); + SetPower(POWER_RAGE, 0); + SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent)); + } + + // update visbility + ObjectAccessor::UpdateVisibilityForPlayer(this); + + // some items limited to specific map + DestroyZoneLimitedItem( true, GetZoneId()); + + if(!applySickness || getLevel() <= 10) + return; + + //Characters from level 1-10 are not affected by resurrection sickness. + //Characters from level 11-19 will suffer from one minute of sickness + //for each level they are above 10. + //Characters level 20 and up suffer from ten minutes of sickness. + int32 startLevel = sWorld.getConfig(CONFIG_DEATH_SICKNESS_LEVEL); + + if(int32(getLevel()) >= startLevel) + { + // set resurrection sickness + CastSpell(this,SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,true); + + // not full duration + if(int32(getLevel()) < startLevel+9) + { + int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE; + + for(int i =0; i < 3; ++i) + { + if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i)) + { + Aur->SetAuraDuration(delta*1000); + Aur->UpdateAuraDuration(); + } + } + } + } +} + +void Player::KillPlayer() +{ + SetMovement(MOVE_ROOT); + + StopMirrorTimers(); //disable timers(bars) + + setDeathState(CORPSE); + //SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_IN_PVP ); + + SetFlag(UNIT_DYNAMIC_FLAGS, 0x00); + ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable()); + + // 6 minutes until repop at graveyard + m_deathTimer = 6*MINUTE*1000; + + UpdateCorpseReclaimDelay(); // dependent at use SetDeathPvP() call before kill + + // don't create corpse at this moment, player might be falling + + // update visibility + ObjectAccessor::UpdateObjectVisibility(this); +} + +void Player::CreateCorpse() +{ + // prevent existence 2 corpse for player + SpawnCorpseBones(); + + uint32 _uf, _pb, _pb2, _cfb1, _cfb2; + + Corpse *corpse = new Corpse( (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE ); + SetPvPDeath(false); + + if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this, GetMapId(), GetPositionX(), + GetPositionY(), GetPositionZ(), GetOrientation())) + { + delete corpse; + return; + } + + _uf = GetUInt32Value(UNIT_FIELD_BYTES_0); + _pb = GetUInt32Value(PLAYER_BYTES); + _pb2 = GetUInt32Value(PLAYER_BYTES_2); + + uint8 race = (uint8)(_uf); + uint8 skin = (uint8)(_pb); + uint8 face = (uint8)(_pb >> 8); + uint8 hairstyle = (uint8)(_pb >> 16); + uint8 haircolor = (uint8)(_pb >> 24); + uint8 facialhair = (uint8)(_pb2); + + _cfb1 = ((0x00) | (race << 8) | (getGender() << 16) | (skin << 24)); + _cfb2 = ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24)); + + corpse->SetUInt32Value( CORPSE_FIELD_BYTES_1, _cfb1 ); + corpse->SetUInt32Value( CORPSE_FIELD_BYTES_2, _cfb2 ); + + uint32 flags = CORPSE_FLAG_UNK2; + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) + flags |= CORPSE_FLAG_HIDE_HELM; + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK)) + flags |= CORPSE_FLAG_HIDE_CLOAK; + if(InBattleGround()) + flags |= CORPSE_FLAG_LOOTABLE; // to be able to remove insignia + corpse->SetUInt32Value( CORPSE_FIELD_FLAGS, flags ); + + corpse->SetUInt32Value( CORPSE_FIELD_DISPLAY_ID, GetNativeDisplayId() ); + + corpse->SetUInt32Value( CORPSE_FIELD_GUILD, GetGuildId() ); + + uint32 iDisplayID; + uint16 iIventoryType; + uint32 _cfi; + for (int i = 0; i < EQUIPMENT_SLOT_END; i++) + { + if(m_items[i]) + { + iDisplayID = m_items[i]->GetProto()->DisplayInfoID; + iIventoryType = (uint16)m_items[i]->GetProto()->InventoryType; + + _cfi = (uint16(iDisplayID)) | (iIventoryType)<< 24; + corpse->SetUInt32Value(CORPSE_FIELD_ITEM + i,_cfi); + } + } + + // we don't SaveToDB for players in battlegrounds so don't do it for corpses either + const MapEntry *entry = sMapStore.LookupEntry(corpse->GetMapId()); + assert(entry); + if(entry->map_type != MAP_BATTLEGROUND) + corpse->SaveToDB(); + + // register for player, but not show + ObjectAccessor::Instance().AddCorpse(corpse); +} + +void Player::SpawnCorpseBones() +{ + if(ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID())) + SaveToDB(); // prevent loading as ghost without corpse +} + +Corpse* Player::GetCorpse() const +{ + return ObjectAccessor::Instance().GetCorpseForPlayerGUID(GetGUID()); +} + +void Player::DurabilityLossAll(double percent, bool inventory) +{ + for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + if(Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + DurabilityLoss(pItem,percent); + + if(inventory) + { + // bags not have durability + // for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + if(Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + DurabilityLoss(pItem,percent); + + // keys not have durability + //for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if(ItemPrototype const *pBagProto = pBag->GetProto()) + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + if(Item* pItem = GetItemByPos( i, j )) + DurabilityLoss(pItem,percent); + } +} + +void Player::DurabilityLoss(Item* item, double percent) +{ + if(!item ) + return; + + uint32 pMaxDurability = item ->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); + + if(!pMaxDurability) + return; + + uint32 pDurabilityLoss = uint32(pMaxDurability*percent); + + if(pDurabilityLoss < 1 ) + pDurabilityLoss = 1; + + DurabilityPointsLoss(item,pDurabilityLoss); +} + +void Player::DurabilityPointsLossAll(int32 points, bool inventory) +{ + for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + if(Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + DurabilityPointsLoss(pItem,points); + + if(inventory) + { + // bags not have durability + // for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + if(Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + DurabilityPointsLoss(pItem,points); + + // keys not have durability + //for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if(ItemPrototype const *pBagProto = pBag->GetProto()) + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + if(Item* pItem = GetItemByPos( i, j )) + DurabilityPointsLoss(pItem,points); + } +} + +void Player::DurabilityPointsLoss(Item* item, int32 points) +{ + int32 pMaxDurability = item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); + int32 pOldDurability = item->GetUInt32Value(ITEM_FIELD_DURABILITY); + int32 pNewDurability = pOldDurability - points; + + if (pNewDurability < 0) + pNewDurability = 0; + else if (pNewDurability > pMaxDurability) + pNewDurability = pMaxDurability; + + if (pOldDurability != pNewDurability) + { + // modify item stats _before_ Durability set to 0 to pass _ApplyItemMods internal check + if ( pNewDurability == 0 && pOldDurability > 0 && item->IsEquipped()) + _ApplyItemMods(item,item->GetSlot(), false); + + item->SetUInt32Value(ITEM_FIELD_DURABILITY, pNewDurability); + + // modify item stats _after_ restore durability to pass _ApplyItemMods internal check + if ( pNewDurability > 0 && pOldDurability == 0 && item->IsEquipped()) + _ApplyItemMods(item,item->GetSlot(), true); + + item->SetState(ITEM_CHANGED, this); + } +} + +void Player::DurabilityPointLossForEquipSlot(EquipmentSlots slot) +{ + if(Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, slot )) + DurabilityPointsLoss(pItem,1); +} + +uint32 Player::DurabilityRepairAll(bool cost, float discountMod, bool guildBank) +{ + uint32 TotalCost = 0; + // equipped, backpack, bags itself + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + TotalCost += DurabilityRepair(( (INVENTORY_SLOT_BAG_0 << 8) | i ),cost,discountMod, guildBank); + + // bank, buyback and keys not repaired + + // items in inventory bags + for(int j = INVENTORY_SLOT_BAG_START; j < INVENTORY_SLOT_BAG_END; j++) + for(int i = 0; i < MAX_BAG_SIZE; i++) + TotalCost += DurabilityRepair(( (j << 8) | i ),cost,discountMod, guildBank); + return TotalCost; +} + +uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank) +{ + Item* item = GetItemByPos(pos); + + uint32 TotalCost = 0; + if(!item) + return TotalCost; + + uint32 maxDurability = item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); + if(!maxDurability) + return TotalCost; + + uint32 curDurability = item->GetUInt32Value(ITEM_FIELD_DURABILITY); + + if(cost) + { + uint32 LostDurability = maxDurability - curDurability; + if(LostDurability>0) + { + ItemPrototype const *ditemProto = sItemStorage.LookupEntry(item->GetEntry()); + if(!ditemProto) + { + sLog.outError("ERROR: RepairDurability: Unknown item id %u", ditemProto); + return TotalCost; + } + + DurabilityCostsEntry const *dcost = sDurabilityCostsStore.LookupEntry(ditemProto->ItemLevel); + if(!dcost) + { + sLog.outError("ERROR: RepairDurability: Wrong item lvl %u", dcost); + return TotalCost; + } + + DurabilityQualityEntry const *dQualitymodEntry = sDurabilityQualityStore.LookupEntry((ditemProto->Quality+1)*2); + if(!dQualitymodEntry) + { + sLog.outError("ERROR: RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntry); + return TotalCost; + } + + uint32 dmultiplier = dcost->multiplier[ItemSubClassToDurabilityMultiplierId(ditemProto->Class,ditemProto->SubClass)]; + uint32 costs = uint32(LostDurability*dmultiplier*double(dQualitymodEntry->quality_mod)); + + costs = uint32(costs * discountMod); + + if (costs==0) //fix for ITEM_QUALITY_ARTIFACT + costs = 1; + + if (guildBank) + { + if (GetGuildId()==0) + { + DEBUG_LOG("You are not member of a guild"); + return TotalCost; + } + + Guild *pGuild = objmgr.GetGuildById(GetGuildId()); + if (!pGuild) + return TotalCost; + + if (!pGuild->HasRankRight(GetRank(), GR_RIGHT_WITHDRAW_REPAIR)) + { + DEBUG_LOG("You do not have rights to withdraw for repairs"); + return TotalCost; + } + + if (pGuild->GetMemberMoneyWithdrawRem(GetGUIDLow()) < costs) + { + DEBUG_LOG("You do not have enough money withdraw amount remaining"); + return TotalCost; + } + + if (pGuild->GetGuildBankMoney() < costs) + { + DEBUG_LOG("There is not enough money in bank"); + return TotalCost; + } + + pGuild->MemberMoneyWithdraw(costs, GetGUIDLow()); + TotalCost = costs; + } + else if (GetMoney() < costs) + { + DEBUG_LOG("You do not have enough money"); + return TotalCost; + } + else + ModifyMoney( -int32(costs) ); + } + } + + item->SetUInt32Value(ITEM_FIELD_DURABILITY, maxDurability); + item->SetState(ITEM_CHANGED, this); + + // reapply mods for total broken and repaired item if equipped + if(IsEquipmentPos(pos) && !curDurability) + _ApplyItemMods(item,pos & 255, true); + return TotalCost; +} + +void Player::RepopAtGraveyard() +{ + // note: this can be called also when the player is alive + // for example from WorldSession::HandleMovementOpcodes + + AreaTableEntry const *zone = GetAreaEntryByAreaID(GetAreaId()); + + // Such zones are considered unreachable as a ghost and the player must be automatically revived + if(!isAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY || GetTransport()) + { + ResurrectPlayer(0.5f); + SpawnCorpseBones(); + } + + WorldSafeLocsEntry const *ClosestGrave = NULL; + + // Special handle for battleground maps + BattleGround *bg = sBattleGroundMgr.GetBattleGround(GetBattleGroundId()); + + if(bg && (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_EY)) + ClosestGrave = bg->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetTeam()); + else + ClosestGrave = objmgr.GetClosestGraveYard( GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam() ); + + // stop countdown until repop + m_deathTimer = 0; + + // if no grave found, stay at the current location + // and don't show spirit healer location + if(ClosestGrave) + { + TeleportTo(ClosestGrave->map_id, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, GetOrientation()); + if(isDead()) // not send if alive, because it used in TeleportTo() + { + WorldPacket data(SMSG_DEATH_RELEASE_LOC, 4*4); // show spirit healer position on minimap + data << ClosestGrave->map_id; + data << ClosestGrave->x; + data << ClosestGrave->y; + data << ClosestGrave->z; + GetSession()->SendPacket(&data); + } + } +} + +void Player::JoinedChannel(Channel *c) +{ + m_channels.push_back(c); +} + +void Player::LeftChannel(Channel *c) +{ + m_channels.remove(c); +} + +void Player::CleanupChannels() +{ + while(!m_channels.empty()) + { + Channel* ch = *m_channels.begin(); + m_channels.erase(m_channels.begin()); // remove from player's channel list + ch->Leave(GetGUID(), false); // not send to client, not remove from player's channel list + if (ChannelMgr* cMgr = channelMgr(GetTeam())) + cMgr->LeftChannel(ch->GetName()); // deleted channel if empty + + } + sLog.outDebug("Player: channels cleaned up!"); +} + +void Player::UpdateLocalChannels(uint32 newZone ) +{ + if(m_channels.empty()) + return; + + AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone); + if(!current_zone) + return; + + ChannelMgr* cMgr = channelMgr(GetTeam()); + if(!cMgr) + return; + + std::string current_zone_name = current_zone->area_name[GetSession()->GetSessionDbcLocale()]; + + for(JoinedChannelsList::iterator i = m_channels.begin(), next; i != m_channels.end(); i = next) + { + next = i; ++next; + + // skip non built-in channels + if(!(*i)->IsConstant()) + continue; + + ChatChannelsEntry const* ch = GetChannelEntryFor((*i)->GetChannelId()); + if(!ch) + continue; + + if((ch->flags & 4) == 4) // global channel without zone name in pattern + continue; + + // new channel + char new_channel_name_buf[100]; + snprintf(new_channel_name_buf,100,ch->pattern[m_session->GetSessionDbcLocale()],current_zone_name.c_str()); + Channel* new_channel = cMgr->GetJoinChannel(new_channel_name_buf,ch->ChannelID); + + if((*i)!=new_channel) + { + new_channel->Join(GetGUID(),""); // will output Changed Channel: N. Name + + // leave old channel + (*i)->Leave(GetGUID(),false); // not send leave channel, it already replaced at client + std::string name = (*i)->GetName(); // stroe name, (*i)erase in LeftChannel + LeftChannel(*i); // remove from player's channel list + cMgr->LeftChannel(name); // delete if empty + } + } + sLog.outDebug("Player: channels cleaned up!"); +} + +void Player::LeaveLFGChannel() +{ + for(JoinedChannelsList::iterator i = m_channels.begin(); i != m_channels.end(); ++i ) + { + if((*i)->IsLFG()) + { + (*i)->Leave(GetGUID()); + break; + } + } +} + +void Player::UpdateDefense() +{ + uint32 defense_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_DEFENSE); + + if(UpdateSkill(SKILL_DEFENSE,defense_skill_gain)) + { + // update dependent from defense skill part + UpdateDefenseBonusesMod(); + } +} + +void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply, bool affectStats) +{ + if(modGroup >= BASEMOD_END || modType >= MOD_END) + { + sLog.outError("ERROR in HandleBaseModValue(): nonexisted BaseModGroup of wrong BaseModType!"); + return; + } + + float val = 1.0f; + + switch(modType) + { + case FLAT_MOD: + m_auraBaseMod[modGroup][modType] += apply ? amount : -amount; + break; + case PCT_MOD: + if(amount <= -100.0f) + amount = -200.0f; + + val = (100.0f + amount) / 100.0f; + m_auraBaseMod[modGroup][modType] *= apply ? val : (1.0f/val); + break; + } + + if(!CanModifyStats()) + return; + + switch(modGroup) + { + case CRIT_PERCENTAGE: UpdateCritPercentage(BASE_ATTACK); break; + case RANGED_CRIT_PERCENTAGE: UpdateCritPercentage(RANGED_ATTACK); break; + case OFFHAND_CRIT_PERCENTAGE: UpdateCritPercentage(OFF_ATTACK); break; + case SHIELD_BLOCK_VALUE: UpdateShieldBlockValue(); break; + default: break; + } +} + +float Player::GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const +{ + if(modGroup >= BASEMOD_END || modType > MOD_END) + { + sLog.outError("ERROR: trial to access nonexisted BaseModGroup or wrong BaseModType!"); + return 0.0f; + } + + if(modType == PCT_MOD && m_auraBaseMod[modGroup][PCT_MOD] <= 0.0f) + return 0.0f; + + return m_auraBaseMod[modGroup][modType]; +} + +float Player::GetTotalBaseModValue(BaseModGroup modGroup) const +{ + if(modGroup >= BASEMOD_END) + { + sLog.outError("ERROR: wrong BaseModGroup in GetTotalBaseModValue()!"); + return 0.0f; + } + + if(m_auraBaseMod[modGroup][PCT_MOD] <= 0.0f) + return 0.0f; + + return m_auraBaseMod[modGroup][FLAT_MOD] * m_auraBaseMod[modGroup][PCT_MOD]; +} + +uint32 Player::GetShieldBlockValue() const +{ + BaseModGroup modGroup = SHIELD_BLOCK_VALUE; + + float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH)/20 - 1; + + value = (value < 0) ? 0 : value; + + return uint32(value); +} + +float Player::GetMeleeCritFromAgility() +{ + uint32 level = getLevel(); + uint32 pclass = getClass(); + + if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; + + GtChanceToMeleeCritBaseEntry const *critBase = sGtChanceToMeleeCritBaseStore.LookupEntry(pclass-1); + GtChanceToMeleeCritEntry const *critRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + if (critBase==NULL || critRatio==NULL) + return 0.0f; + + float crit=critBase->base + GetStat(STAT_AGILITY)*critRatio->ratio; + return crit*100.0f; +} + +float Player::GetDodgeFromAgility() +{ + // Table for base dodge values + float dodge_base[MAX_CLASSES] = { + 0.0075f, // Warrior + 0.00652f, // Paladin + -0.0545f, // Hunter + -0.0059f, // Rogue + 0.03183f, // Priest + 0.0114f, // DK + 0.0167f, // Shaman + 0.034575f, // Mage + 0.02011f, // Warlock + 0.0f, // ?? + -0.0187f // Druid + }; + // Crit/agility to dodge/agility coefficient multipliers + float crit_to_dodge[MAX_CLASSES] = { + 1.1f, // Warrior + 1.0f, // Paladin + 1.6f, // Hunter + 2.0f, // Rogue + 1.0f, // Priest + 1.0f, // DK? + 1.0f, // Shaman + 1.0f, // Mage + 1.0f, // Warlock + 0.0f, // ?? + 1.7f // Druid + }; + + uint32 level = getLevel(); + uint32 pclass = getClass(); + + if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; + + // Dodge per agility for most classes equal crit per agility (but for some classes need apply some multiplier) + GtChanceToMeleeCritEntry const *dodgeRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + if (dodgeRatio==NULL || pclass > MAX_CLASSES) + return 0.0f; + + float dodge=dodge_base[pclass-1] + GetStat(STAT_AGILITY) * dodgeRatio->ratio * crit_to_dodge[pclass-1]; + return dodge*100.0f; +} + +float Player::GetSpellCritFromIntellect() +{ + uint32 level = getLevel(); + uint32 pclass = getClass(); + + if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; + + GtChanceToSpellCritBaseEntry const *critBase = sGtChanceToSpellCritBaseStore.LookupEntry(pclass-1); + GtChanceToSpellCritEntry const *critRatio = sGtChanceToSpellCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + if (critBase==NULL || critRatio==NULL) + return 0.0f; + + float crit=critBase->base + GetStat(STAT_INTELLECT)*critRatio->ratio; + return crit*100.0f; +} + +float Player::GetRatingCoefficient(CombatRating cr) const +{ + uint32 level = getLevel(); + + if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; + + GtCombatRatingsEntry const *Rating = sGtCombatRatingsStore.LookupEntry(cr*GT_MAX_LEVEL+level-1); + if (Rating == NULL) + return 1.0f; // By default use minimum coefficient (not must be called) + + return Rating->ratio; +} + +float Player::GetRatingBonusValue(CombatRating cr) const +{ + return float(GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr)) / GetRatingCoefficient(cr); +} + +uint32 Player::GetMeleeCritDamageReduction(uint32 damage) const +{ + float melee = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*2.0f; + if (melee>25.0f) melee = 25.0f; + return uint32 (melee * damage /100.0f); +} + +uint32 Player::GetRangedCritDamageReduction(uint32 damage) const +{ + float ranged = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED)*2.0f; + if (ranged>25.0f) ranged=25.0f; + return uint32 (ranged * damage /100.0f); +} + +uint32 Player::GetSpellCritDamageReduction(uint32 damage) const +{ + float spell = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2.0f; + // In wow script resilience limited to 25% + if (spell>25.0f) + spell = 25.0f; + return uint32 (spell * damage / 100.0f); +} + +uint32 Player::GetDotDamageReduction(uint32 damage) const +{ + float spellDot = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL); + // Dot resilience not limited (limit it by 100%) + if (spellDot > 100.0f) + spellDot = 100.0f; + return uint32 (spellDot * damage / 100.0f); +} + +float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const +{ + switch (attType) + { + case BASE_ATTACK: + return GetUInt32Value(PLAYER_EXPERTISE) / 4.0f; + case OFF_ATTACK: + return GetUInt32Value(PLAYER_OFFHAND_EXPERTISE) / 4.0f; + default: + break; + } + return 0.0f; +} + +float Player::OCTRegenHPPerSpirit() +{ + uint32 level = getLevel(); + uint32 pclass = getClass(); + + if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; + + GtOCTRegenHPEntry const *baseRatio = sGtOCTRegenHPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + GtRegenHPPerSptEntry const *moreRatio = sGtRegenHPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + if (baseRatio==NULL || moreRatio==NULL) + return 0.0f; + + // Formula from PaperDollFrame script + float spirit = GetStat(STAT_SPIRIT); + float baseSpirit = spirit; + if (baseSpirit>50) baseSpirit = 50; + float moreSpirit = spirit - baseSpirit; + float regen = baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio; + return regen; +} + +float Player::OCTRegenMPPerSpirit() +{ + uint32 level = getLevel(); + uint32 pclass = getClass(); + + if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; + +// GtOCTRegenMPEntry const *baseRatio = sGtOCTRegenMPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + GtRegenMPPerSptEntry const *moreRatio = sGtRegenMPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + if (moreRatio==NULL) + return 0.0f; + + // Formula get from PaperDollFrame script + float spirit = GetStat(STAT_SPIRIT); + float regen = spirit * moreRatio->ratio; + return regen; +} + +void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) +{ + ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply); + + float RatingCoeffecient = GetRatingCoefficient(cr); + float RatingChange = 0.0f; + + bool affectStats = CanModifyStats(); + + switch (cr) + { + case CR_WEAPON_SKILL: // Implemented in Unit::RollMeleeOutcomeAgainst + case CR_DEFENSE_SKILL: + UpdateDefenseBonusesMod(); + break; + case CR_DODGE: + UpdateDodgePercentage(); + break; + case CR_PARRY: + UpdateParryPercentage(); + break; + case CR_BLOCK: + UpdateBlockPercentage(); + break; + case CR_HIT_MELEE: + RatingChange = value / RatingCoeffecient; + m_modMeleeHitChance += apply ? RatingChange : -RatingChange; + break; + case CR_HIT_RANGED: + RatingChange = value / RatingCoeffecient; + m_modRangedHitChance += apply ? RatingChange : -RatingChange; + break; + case CR_HIT_SPELL: + RatingChange = value / RatingCoeffecient; + m_modSpellHitChance += apply ? RatingChange : -RatingChange; + break; + case CR_CRIT_MELEE: + if(affectStats) + { + UpdateCritPercentage(BASE_ATTACK); + UpdateCritPercentage(OFF_ATTACK); + } + break; + case CR_CRIT_RANGED: + if(affectStats) + UpdateCritPercentage(RANGED_ATTACK); + break; + case CR_CRIT_SPELL: + if(affectStats) + UpdateAllSpellCritChances(); + break; + case CR_HIT_TAKEN_MELEE: // Implemented in Unit::MeleeMissChanceCalc + case CR_HIT_TAKEN_RANGED: + break; + case CR_HIT_TAKEN_SPELL: // Implemented in Unit::MagicSpellHitResult + break; + case CR_CRIT_TAKEN_MELEE: // Implemented in Unit::RollMeleeOutcomeAgainst (only for chance to crit) + case CR_CRIT_TAKEN_RANGED: + break; + case CR_CRIT_TAKEN_SPELL: // Implemented in Unit::SpellCriticalBonus (only for chance to crit) + break; + case CR_HASTE_MELEE: + RatingChange = value / RatingCoeffecient; + ApplyAttackTimePercentMod(BASE_ATTACK,RatingChange,apply); + ApplyAttackTimePercentMod(OFF_ATTACK,RatingChange,apply); + break; + case CR_HASTE_RANGED: + RatingChange = value / RatingCoeffecient; + ApplyAttackTimePercentMod(RANGED_ATTACK, RatingChange, apply); + break; + case CR_HASTE_SPELL: + RatingChange = value / RatingCoeffecient; + ApplyCastTimePercentMod(RatingChange,apply); + break; + case CR_WEAPON_SKILL_MAINHAND: // Implemented in Unit::RollMeleeOutcomeAgainst + case CR_WEAPON_SKILL_OFFHAND: + case CR_WEAPON_SKILL_RANGED: + break; + case CR_EXPERTISE: + if(affectStats) + { + UpdateExpertise(BASE_ATTACK); + UpdateExpertise(OFF_ATTACK); + } + break; + } +} + +void Player::SetRegularAttackTime() +{ + for(int i = 0; i < MAX_ATTACK; ++i) + { + Item *tmpitem = GetWeaponForAttack(WeaponAttackType(i)); + if(tmpitem && !tmpitem->IsBroken()) + { + ItemPrototype const *proto = tmpitem->GetProto(); + if(proto->Delay) + SetAttackTime(WeaponAttackType(i), proto->Delay); + else + SetAttackTime(WeaponAttackType(i), BASE_ATTACK_TIME); + } + } +} + +//skill+step, checking for max value +bool Player::UpdateSkill(uint32 skill_id, uint32 step) +{ + if(!skill_id) + return false; + + uint16 i=0; + for (; i < PLAYER_MAX_SKILLS; i++) + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill_id) + break; + + if(i>=PLAYER_MAX_SKILLS) + return false; + + uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)); + uint32 value = SKILL_VALUE(data); + uint32 max = SKILL_MAX(data); + + if ((!max) || (!value) || (value >= max)) + return false; + + if (value*512 < max*urand(0,512)) + { + uint32 new_value = value+step; + if(new_value > max) + new_value = max; + + SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max)); + return true; + } + + return false; +} + +inline int SkillGainChance(uint32 SkillValue, uint32 GrayLevel, uint32 GreenLevel, uint32 YellowLevel) +{ + if ( SkillValue >= GrayLevel ) + return sWorld.getConfig(CONFIG_SKILL_CHANCE_GREY)*10; + if ( SkillValue >= GreenLevel ) + return sWorld.getConfig(CONFIG_SKILL_CHANCE_GREEN)*10; + if ( SkillValue >= YellowLevel ) + return sWorld.getConfig(CONFIG_SKILL_CHANCE_YELLOW)*10; + return sWorld.getConfig(CONFIG_SKILL_CHANCE_ORANGE)*10; +} + +bool Player::UpdateCraftSkill(uint32 spellid) +{ + sLog.outDebug("UpdateCraftSkill spellid %d", spellid); + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + if(_spell_idx->second->skillId) + { + uint32 SkillValue = GetPureSkillValue(_spell_idx->second->skillId); + + // Alchemy Discoveries here + SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellid); + if(spellEntry && spellEntry->Mechanic==MECHANIC_DISCOVERY) + { + if(uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this)) + learnSpell(discoveredSpell); + } + + uint32 craft_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_CRAFTING); + + return UpdateSkillPro(_spell_idx->second->skillId, SkillGainChance(SkillValue, + _spell_idx->second->max_value, + (_spell_idx->second->max_value + _spell_idx->second->min_value)/2, + _spell_idx->second->min_value), + craft_skill_gain); + } + } + return false; +} + +bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator ) +{ + sLog.outDebug("UpdateGatherSkill(SkillId %d SkillLevel %d RedLevel %d)", SkillId, SkillValue, RedLevel); + + uint32 gathering_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_GATHERING); + + // For skinning and Mining chance decrease with level. 1-74 - no decrease, 75-149 - 2 times, 225-299 - 8 times + switch (SkillId) + { + case SKILL_HERBALISM: + case SKILL_LOCKPICKING: + case SKILL_JEWELCRAFTING: + return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain); + case SKILL_SKINNING: + if( sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)==0) + return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain); + else + return UpdateSkillPro(SkillId, (SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator) >> (SkillValue/sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)), gathering_skill_gain); + case SKILL_MINING: + if (sWorld.getConfig(CONFIG_SKILL_CHANCE_MINING_STEPS)==0) + return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain); + else + return UpdateSkillPro(SkillId, (SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator) >> (SkillValue/sWorld.getConfig(CONFIG_SKILL_CHANCE_MINING_STEPS)),gathering_skill_gain); + } + return false; +} + +bool Player::UpdateFishingSkill() +{ + sLog.outDebug("UpdateFishingSkill"); + + uint32 SkillValue = GetPureSkillValue(SKILL_FISHING); + + int32 chance = SkillValue < 75 ? 100 : 2500/(SkillValue-50); + + uint32 gathering_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_GATHERING); + + return UpdateSkillPro(SKILL_FISHING,chance*10,gathering_skill_gain); +} + +bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) +{ + sLog.outDebug("UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance/10.0); + if ( !SkillId ) + return false; + + if(Chance <= 0) // speedup in 0 chance case + { + sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% missed", Chance/10.0); + return false; + } + + uint16 i=0; + for (; i < PLAYER_MAX_SKILLS; i++) + if ( SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_INDEX(i))) == SkillId ) break; + if ( i >= PLAYER_MAX_SKILLS ) + return false; + + uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)); + uint16 SkillValue = SKILL_VALUE(data); + uint16 MaxValue = SKILL_MAX(data); + + if ( !MaxValue || !SkillValue || SkillValue >= MaxValue ) + return false; + + int32 Roll = irand(1,1000); + + if ( Roll <= Chance ) + { + uint32 new_value = SkillValue+step; + if(new_value > MaxValue) + new_value = MaxValue; + + SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue)); + sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0); + return true; + } + + sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% missed", Chance/10.0); + return false; +} + +void Player::UpdateWeaponSkill (WeaponAttackType attType) +{ + // no skill gain in pvp + Unit *pVictim = getVictim(); + if(pVictim && pVictim->GetTypeId() == TYPEID_PLAYER) + return; + + if(IsInFeralForm()) + return; // always maximized SKILL_FERAL_COMBAT in fact + + if(m_form == FORM_TREE) + return; // use weapon but not skill up + + uint32 weapon_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_WEAPON); + + switch(attType) + { + case BASE_ATTACK: + { + Item *tmpitem = GetWeaponForAttack(attType,true); + + if (!tmpitem) + UpdateSkill(SKILL_UNARMED,weapon_skill_gain); + else if(tmpitem->GetProto()->SubClass != ITEM_SUBCLASS_WEAPON_FISHING_POLE) + UpdateSkill(tmpitem->GetSkill(),weapon_skill_gain); + break; + } + case OFF_ATTACK: + case RANGED_ATTACK: + { + Item *tmpitem = GetWeaponForAttack(attType,true); + if (tmpitem) + UpdateSkill(tmpitem->GetSkill(),weapon_skill_gain); + break; + } + } + UpdateAllCritPercentages(); +} + +void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence) +{ + switch(outcome) + { + case MELEE_HIT_CRIT: + case MELEE_HIT_DODGE: + case MELEE_HIT_PARRY: + case MELEE_HIT_BLOCK: + case MELEE_HIT_BLOCK_CRIT: + return; + + default: + break; + } + + uint32 plevel = getLevel(); // if defense than pVictim == attacker + uint32 greylevel = MaNGOS::XP::GetGrayLevel(plevel); + uint32 moblevel = pVictim->getLevelForTarget(this); + if(moblevel < greylevel) + return; + + if (moblevel > plevel + 5) + moblevel = plevel + 5; + + uint32 lvldif = moblevel - greylevel; + if(lvldif < 3) + lvldif = 3; + + uint32 skilldif = 5 * plevel - (defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType)); + if(skilldif <= 0) + return; + + float chance = float(3 * lvldif * skilldif) / plevel; + if(!defence) + { + if(getClass() == CLASS_WARRIOR || getClass() == CLASS_ROGUE) + chance *= 0.1f * GetStat(STAT_INTELLECT); + } + + chance = chance < 1.0f ? 1.0f : chance; //minimum chance to increase skill is 1% + + if(roll_chance_f(chance)) + { + if(defence) + UpdateDefense(); + else + UpdateWeaponSkill(attType); + } + else + return; +} + +void Player::ModifySkillBonus(uint32 skillid,int32 val, bool talent) +{ + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skillid) + { + uint32 bonus_val = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)); + int16 temp_bonus = SKILL_TEMP_BONUS(bonus_val); + int16 perm_bonus = SKILL_PERM_BONUS(bonus_val); + + if(talent) // permanent bonus stored in high part + SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),MAKE_SKILL_BONUS(temp_bonus,perm_bonus+val)); + else // temporary/item bonus stored in low part + SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),MAKE_SKILL_BONUS(temp_bonus+val,perm_bonus)); + return; + } +} + +void Player::UpdateMaxSkills() +{ + uint16 maxconfskill = sWorld.GetConfigMaxSkillValue(); + + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + if (GetUInt32Value(PLAYER_SKILL_INDEX(i))) + { + uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF; + + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(pskill); + if(!pSkill) + continue; + + if(GetSkillRangeType(pSkill,false) != SKILL_RANGE_LEVEL) + continue; + + uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)); + uint32 max = SKILL_MAX(data); + uint32 val = SKILL_VALUE(data); + + // update only level dependent max skill values + if(max!=1 && max != maxconfskill) + { + uint32 max_Skill = GetMaxSkillValueForLevel(); + SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(val,max_Skill)); + } + } +} + +void Player::UpdateSkillsToMaxSkillsForLevel() +{ + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + if (GetUInt32Value(PLAYER_SKILL_INDEX(i))) + { + uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF; + if( IsProfessionSkill(pskill) || pskill == SKILL_RIDING ) + continue; + uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)); + + uint32 max = SKILL_MAX(data); + + if(max > 1) + SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(max,max)); + + if(pskill == SKILL_DEFENSE) + UpdateDefenseBonusesMod(); + } +} + +// This functions sets a skill line value (and adds if doesn't exist yet) +// To "remove" a skill line, set it's values to zero +void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal) +{ + if(!id) + return; + + uint16 i=0; + for (; i < PLAYER_MAX_SKILLS; i++) + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == id) break; + + if(isecond->state == PLAYERSPELL_REMOVED) + continue; + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(itr->first); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + if (_spell_idx->second->skillId == id) + { + // this may remove more than one spell (dependants) + removeSpell(itr->first); + next = m_spells.begin(); + break; + } + } + } + } + } + else if(currVal) //add + { + for (i=0; i < PLAYER_MAX_SKILLS; i++) + if (!GetUInt32Value(PLAYER_SKILL_INDEX(i))) + { + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id); + if(!pSkill) + { + sLog.outError("Skill not found in SkillLineStore: skill #%u", id); + return; + } + // enable unlearn button for primary professions only + if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION) + SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1)); + else + SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0)); + SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal)); + + // apply skill bonuses + SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0); + + // temporary bonuses + AuraList const& mModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL); + for(AuraList::const_iterator i = mModSkill.begin(); i != mModSkill.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue == int32(id)) + (*i)->ApplyModifier(true); + + // permanent bonuses + AuraList const& mModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT); + for(AuraList::const_iterator i = mModSkillTalent.begin(); i != mModSkillTalent.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue == int32(id)) + (*i)->ApplyModifier(true); + + // Learn all spells for skill + learnSkillRewardedSpells(id); + return; + } + } +} + +bool Player::HasSkill(uint32 skill) const +{ + if(!skill)return false; + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + return true; + } + } + return false; +} + +uint16 Player::GetSkillValue(uint32 skill) const +{ + if(!skill) + return 0; + + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)); + + int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)))); + result += SKILL_TEMP_BONUS(bonus); + result += SKILL_PERM_BONUS(bonus); + return result < 0 ? 0 : result; + } + } + return 0; +} + +uint16 Player::GetMaxSkillValue(uint32 skill) const +{ + if(!skill)return 0; + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)); + + int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)))); + result += SKILL_TEMP_BONUS(bonus); + result += SKILL_PERM_BONUS(bonus); + return result < 0 ? 0 : result; + } + } + return 0; +} + +uint16 Player::GetPureMaxSkillValue(uint32 skill) const +{ + if(!skill)return 0; + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + return SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i))); + } + } + return 0; +} + +uint16 Player::GetBaseSkillValue(uint32 skill) const +{ + if(!skill)return 0; + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)))); + result += SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i))); + return result < 0 ? 0 : result; + } + } + return 0; +} + +uint16 Player::GetPureSkillValue(uint32 skill) const +{ + if(!skill)return 0; + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + return SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i))); + } + } + return 0; +} + +int16 Player::GetSkillTempBonusValue(uint32 skill) const +{ + if(!skill) + return 0; + + for (int i = 0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + return SKILL_TEMP_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i))); + } + } + + return 0; +} + +void Player::SendInitialActionButtons() +{ + sLog.outDetail( "Initializing Action Buttons for '%u'", GetGUIDLow() ); + + WorldPacket data(SMSG_ACTION_BUTTONS, (MAX_ACTION_BUTTONS*4)); + for(int button = 0; button < MAX_ACTION_BUTTONS; ++button) + { + ActionButtonList::const_iterator itr = m_actionButtons.find(button); + if(itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED) + { + data << uint16(itr->second.action); + data << uint8(itr->second.misc); + data << uint8(itr->second.type); + } + else + { + data << uint32(0); + } + } + + GetSession()->SendPacket( &data ); + sLog.outDetail( "Action Buttons for '%u' Initialized", GetGUIDLow() ); +} + +void Player::addActionButton(const uint8 button, const uint16 action, const uint8 type, const uint8 misc) +{ + if(button >= MAX_ACTION_BUTTONS) + { + sLog.outError( "Action %u not added into button %u for player %s: button must be < 132", action, button, GetName() ); + return; + } + + // check cheating with adding non-known spells to action bar + if(type==ACTION_BUTTON_SPELL) + { + if(!sSpellStore.LookupEntry(action)) + { + sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() ); + return; + } + + if(!HasSpell(action)) + { + sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() ); + return; + } + } + + ActionButtonList::iterator buttonItr = m_actionButtons.find(button); + + if (buttonItr==m_actionButtons.end()) + { // just add new button + m_actionButtons[button] = ActionButton(action,type,misc); + } + else + { // change state of current button + ActionButtonUpdateState uState = buttonItr->second.uState; + buttonItr->second = ActionButton(action,type,misc); + if (uState != ACTIONBUTTON_NEW) buttonItr->second.uState = ACTIONBUTTON_CHANGED; + }; + + sLog.outDetail( "Player '%u' Added Action '%u' to Button '%u'", GetGUIDLow(), action, button ); +} + +void Player::removeActionButton(uint8 button) +{ + ActionButtonList::iterator buttonItr = m_actionButtons.find(button); + if (buttonItr==m_actionButtons.end()) + return; + + if(buttonItr->second.uState==ACTIONBUTTON_NEW) + m_actionButtons.erase(buttonItr); // new and not saved + else + buttonItr->second.uState = ACTIONBUTTON_DELETED; // saved, will deleted at next save + + sLog.outDetail( "Action Button '%u' Removed from Player '%u'", button, GetGUIDLow() ); +} + +void Player::SetDontMove(bool dontMove) +{ + m_dontMove = dontMove; +} + +bool Player::SetPosition(float x, float y, float z, float orientation, bool teleport) +{ + // prevent crash when a bad coord is sent by the client + if(!MaNGOS::IsValidMapCoord(x,y,z,orientation)) + { + sLog.outDebug("Player::SetPosition(%f, %f, %f, %f, %d) .. bad coordinates for player %d!",x,y,z,orientation,teleport,GetGUIDLow()); + return false; + } + + Map *m = MapManager::Instance().GetMap(GetMapId(), this); + + const float old_x = GetPositionX(); + const float old_y = GetPositionY(); + const float old_z = GetPositionZ(); + const float old_r = GetOrientation(); + + if( teleport || old_x != x || old_y != y || old_z != z || old_r != orientation ) + { + if (teleport || old_x != x || old_y != y || old_z != z) + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); + else + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING); + + // move and update visible state if need + m->PlayerRelocation(this, x, y, z, orientation); + + // reread after Map::Relocation + m = MapManager::Instance().GetMap(GetMapId(), this); + x = GetPositionX(); + y = GetPositionY(); + z = GetPositionZ(); + } + + // code block for underwater state update + UpdateUnderwaterState(m, x, y, z); + + CheckExploreSystem(); + + // group update + if(GetGroup()) + SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION); + + return true; +} + +void Player::SaveRecallPosition() +{ + m_recallMap = GetMapId(); + m_recallX = GetPositionX(); + m_recallY = GetPositionY(); + m_recallZ = GetPositionZ(); + m_recallO = GetOrientation(); +} + +void Player::SendMessageToSet(WorldPacket *data, bool self) +{ + MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self); +} + +void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self) +{ + MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self); +} + +void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only) +{ + MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self,own_team_only); +} + +void Player::SendDirectMessage(WorldPacket *data) +{ + GetSession()->SendPacket(data); +} + +void Player::CheckExploreSystem() +{ + if (!isAlive()) + return; + + if (isInFlight()) + return; + + uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY()); + if(areaFlag==0xffff) + return; + int offset = areaFlag / 32; + + if(offset >= 128) + { + sLog.outError("ERROR: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 64 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset); + return; + } + + uint32 val = (uint32)(1 << (areaFlag % 32)); + uint32 currFields = GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + + if( !(currFields & val) ) + { + SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); + + AreaTableEntry const *p = GetAreaEntryByAreaFlagAndMap(areaFlag,GetMapId()); + if(!p) + { + sLog.outError("PLAYER: Player %u discovered unknown area (x: %f y: %f map: %u", GetGUIDLow(), GetPositionX(),GetPositionY(),GetMapId()); + } + else if(p->area_level > 0) + { + uint32 area = p->ID; + if (getLevel() >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + SendExplorationExperience(area,0); + } + else + { + int32 diff = int32(getLevel()) - p->area_level; + uint32 XP = 0; + if (diff < -5) + { + XP = uint32(objmgr.GetBaseXP(getLevel()+5)*sWorld.getRate(RATE_XP_EXPLORE)); + } + else if (diff > 5) + { + int32 exploration_percent = (100-((diff-5)*5)); + if (exploration_percent > 100) + exploration_percent = 100; + else if (exploration_percent < 0) + exploration_percent = 0; + + XP = uint32(objmgr.GetBaseXP(p->area_level)*exploration_percent/100*sWorld.getRate(RATE_XP_EXPLORE)); + } + else + { + XP = uint32(objmgr.GetBaseXP(p->area_level)*sWorld.getRate(RATE_XP_EXPLORE)); + } + + GiveXP( XP, NULL ); + SendExplorationExperience(area,XP); + } + sLog.outDetail("PLAYER: Player %u discovered a new area: %u", GetGUIDLow(), area); + } + } +} + +uint32 Player::TeamForRace(uint8 race) +{ + ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race); + if(!rEntry) + { + sLog.outError("Race %u not found in DBC: wrong DBC files?",uint32(race)); + return ALLIANCE; + } + + switch(rEntry->TeamID) + { + case 7: return ALLIANCE; + case 1: return HORDE; + } + + sLog.outError("Race %u have wrong team id in DBC: wrong DBC files?",uint32(race),rEntry->TeamID); + return ALLIANCE; +} + +uint32 Player::getFactionForRace(uint8 race) +{ + ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race); + if(!rEntry) + { + sLog.outError("Race %u not found in DBC: wrong DBC files?",uint32(race)); + return 0; + } + + return rEntry->FactionID; +} + +void Player::setFactionForRace(uint8 race) +{ + m_team = TeamForRace(race); + setFaction( getFactionForRace(race) ); +} + +void Player::UpdateReputation() const +{ + sLog.outDetail( "WORLD: Player::UpdateReputation" ); + + for(FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) + { + SendFactionState(&(itr->second)); + } +} + +void Player::SendFactionState(FactionState const* faction) const +{ + if(faction->Flags & FACTION_FLAG_VISIBLE) //If faction is visible then update it + { + WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0 + data << (float) 0; // unk 2.4.0 + data << (uint32) 1; // count + // for + data << (uint32) faction->ReputationListID; + data << (uint32) faction->Standing; + // end for + GetSession()->SendPacket(&data); + } +} + +void Player::SendInitialReputations() +{ + WorldPacket data(SMSG_INITIALIZE_FACTIONS, (4+128*5)); + data << uint32 (0x00000080); + + RepListID a = 0; + + for (FactionStateList::const_iterator itr = m_factions.begin(); itr != m_factions.end(); itr++) + { + // fill in absent fields + for (; a != itr->first; a++) + { + data << uint8 (0x00); + data << uint32 (0x00000000); + } + + // fill in encountered data + data << uint8 (itr->second.Flags); + data << uint32 (itr->second.Standing); + + ++a; + } + + // fill in absent fields + for (; a != 128; a++) + { + data << uint8 (0x00); + data << uint32 (0x00000000); + } + + GetSession()->SendPacket(&data); +} + +FactionState const* Player::GetFactionState( FactionEntry const* factionEntry) const +{ + FactionStateList::const_iterator itr = m_factions.find(factionEntry->reputationListID); + if (itr != m_factions.end()) + return &itr->second; + + return NULL; +} + +void Player::SetFactionAtWar(FactionState* faction, bool atWar) +{ + // not allow declare war to own faction + if(atWar && (faction->Flags & FACTION_FLAG_PEACE_FORCED) ) + return; + + // already set + if(((faction->Flags & FACTION_FLAG_AT_WAR) != 0) == atWar) + return; + + if( atWar ) + faction->Flags |= FACTION_FLAG_AT_WAR; + else + faction->Flags &= ~FACTION_FLAG_AT_WAR; + + faction->Changed = true; +} + +void Player::SetFactionInactive(FactionState* faction, bool inactive) +{ + // always invisible or hidden faction can't be inactive + if(inactive && ((faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN)) || !(faction->Flags & FACTION_FLAG_VISIBLE) ) ) + return; + + // already set + if(((faction->Flags & FACTION_FLAG_INACTIVE) != 0) == inactive) + return; + + if(inactive) + faction->Flags |= FACTION_FLAG_INACTIVE; + else + faction->Flags &= ~FACTION_FLAG_INACTIVE; + + faction->Changed = true; +} + +void Player::SetFactionVisibleForFactionTemplateId(uint32 FactionTemplateId) +{ + FactionTemplateEntry const*factionTemplateEntry = sFactionTemplateStore.LookupEntry(FactionTemplateId); + + if(!factionTemplateEntry) + return; + + SetFactionVisibleForFactionId(factionTemplateEntry->faction); +} + +void Player::SetFactionVisibleForFactionId(uint32 FactionId) +{ + FactionEntry const *factionEntry = sFactionStore.LookupEntry(FactionId); + if(!factionEntry) + return; + + if(factionEntry->reputationListID < 0) + return; + + FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); + if (itr == m_factions.end()) + return; + + SetFactionVisible(&itr->second); +} + +void Player::SetFactionVisible(FactionState* faction) +{ + // always invisible or hidden faction can't be make visible + if(faction->Flags & (FACTION_FLAG_INVISIBLE_FORCED|FACTION_FLAG_HIDDEN)) + return; + + // already set + if(faction->Flags & FACTION_FLAG_VISIBLE) + return; + + faction->Flags |= FACTION_FLAG_VISIBLE; + faction->Changed = true; + + if(!m_session->PlayerLoading()) + { + // make faction visible in reputation list at client + WorldPacket data(SMSG_SET_FACTION_VISIBLE, 4); + data << faction->ReputationListID; + GetSession()->SendPacket(&data); + } +} + +void Player::SetInitialFactions() +{ + for(unsigned int i = 1; i < sFactionStore.GetNumRows(); i++) + { + FactionEntry const *factionEntry = sFactionStore.LookupEntry(i); + + if( factionEntry && (factionEntry->reputationListID >= 0)) + { + FactionState newFaction; + newFaction.ID = factionEntry->ID; + newFaction.ReputationListID = factionEntry->reputationListID; + newFaction.Standing = 0; + newFaction.Flags = GetDefaultReputationFlags(factionEntry); + newFaction.Changed = true; + + m_factions[newFaction.ReputationListID] = newFaction; + } + } +} + +uint32 Player::GetDefaultReputationFlags(const FactionEntry *factionEntry) const +{ + if (!factionEntry) + return 0; + + uint32 raceMask = getRaceMask(); + uint32 classMask = getClassMask(); + for (int i=0; i < 4; i++) + { + if( (factionEntry->BaseRepRaceMask[i] & raceMask) && + (factionEntry->BaseRepClassMask[i]==0 || + (factionEntry->BaseRepClassMask[i] & classMask) ) ) + return factionEntry->ReputationFlags[i]; + } + return 0; +} + +int32 Player::GetBaseReputation(const FactionEntry *factionEntry) const +{ + if (!factionEntry) + return 0; + + uint32 raceMask = getRaceMask(); + uint32 classMask = getClassMask(); + for (int i=0; i < 4; i++) + { + if( (factionEntry->BaseRepRaceMask[i] & raceMask) && + (factionEntry->BaseRepClassMask[i]==0 || + (factionEntry->BaseRepClassMask[i] & classMask) ) ) + return factionEntry->BaseRepValue[i]; + } + + // in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i]==0 + return 0; +} + +int32 Player::GetReputation(uint32 faction_id) const +{ + FactionEntry const *factionEntry = sFactionStore.LookupEntry(faction_id); + + if (!factionEntry) + { + sLog.outError("Player::GetReputation: Can't get reputation of %s for unknown faction (faction template id) #%u.",GetName(), faction_id); + return 0; + } + + return GetReputation(factionEntry); +} + +int32 Player::GetReputation(const FactionEntry *factionEntry) const +{ + // Faction without recorded reputation. Just ignore. + if(!factionEntry) + return 0; + + FactionStateList::const_iterator itr = m_factions.find(factionEntry->reputationListID); + if (itr != m_factions.end()) + return GetBaseReputation(factionEntry) + itr->second.Standing; + + return 0; +} + +ReputationRank Player::GetReputationRank(uint32 faction) const +{ + FactionEntry const*factionEntry = sFactionStore.LookupEntry(faction); + if(!factionEntry) + return MIN_REPUTATION_RANK; + + return GetReputationRank(factionEntry); +} + +ReputationRank Player::ReputationToRank(int32 standing) const +{ + int32 Limit = Reputation_Cap + 1; + for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i) + { + Limit -= ReputationRank_Length[i]; + if (standing >= Limit ) + return ReputationRank(i); + } + return MIN_REPUTATION_RANK; +} + +ReputationRank Player::GetReputationRank(const FactionEntry *factionEntry) const +{ + int32 Reputation = GetReputation(factionEntry); + return ReputationToRank(Reputation); +} + +ReputationRank Player::GetBaseReputationRank(const FactionEntry *factionEntry) const +{ + int32 Reputation = GetBaseReputation(factionEntry); + return ReputationToRank(Reputation); +} + +bool Player::ModifyFactionReputation(uint32 FactionTemplateId, int32 DeltaReputation) +{ + FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(FactionTemplateId); + + if(!factionTemplateEntry) + { + sLog.outError("Player::ModifyFactionReputation: Can't update reputation of %s for unknown faction (faction template id) #%u.", GetName(), FactionTemplateId); + return false; + } + + FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction); + + // Faction without recorded reputation. Just ignore. + if(!factionEntry) + return false; + + return ModifyFactionReputation(factionEntry, DeltaReputation); +} + +bool Player::ModifyFactionReputation(FactionEntry const* factionEntry, int32 standing) +{ + SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID); + if (flist) + { + bool res = false; + for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr) + { + FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr); + if(factionEntryCalc) + res = ModifyOneFactionReputation(factionEntryCalc, standing); + } + return res; + } + else + return ModifyOneFactionReputation(factionEntry, standing); +} + +bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32 standing) +{ + FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); + if (itr != m_factions.end()) + { + int32 BaseRep = GetBaseReputation(factionEntry); + int32 new_rep = BaseRep + itr->second.Standing + standing; + + if (new_rep > Reputation_Cap) + new_rep = Reputation_Cap; + else + if (new_rep < Reputation_Bottom) + new_rep = Reputation_Bottom; + + if(ReputationToRank(new_rep) <= REP_HOSTILE) + SetFactionAtWar(&itr->second,true); + + itr->second.Standing = new_rep - BaseRep; + itr->second.Changed = true; + + SetFactionVisible(&itr->second); + + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + if(uint32 questid = GetQuestSlotQuestId(i)) + { + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if( qInfo && qInfo->GetRepObjectiveFaction() == factionEntry->ID ) + { + QuestStatusData& q_status = mQuestStatus[questid]; + if( q_status.m_status == QUEST_STATUS_INCOMPLETE ) + { + if(GetReputation(factionEntry) >= qInfo->GetRepObjectiveValue()) + if ( CanCompleteQuest( questid ) ) + CompleteQuest( questid ); + } + else if( q_status.m_status == QUEST_STATUS_COMPLETE ) + { + if(GetReputation(factionEntry) < qInfo->GetRepObjectiveValue()) + IncompleteQuest( questid ); + } + } + } + } + + SendFactionState(&(itr->second)); + + return true; + } + return false; +} + +bool Player::SetFactionReputation(uint32 FactionTemplateId, int32 standing) +{ + FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(FactionTemplateId); + + if(!factionTemplateEntry) + { + sLog.outError("Player::SetFactionReputation: Can't set reputation of %s for unknown faction (faction template id) #%u.", GetName(), FactionTemplateId); + return false; + } + + FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction); + + // Faction without recorded reputation. Just ignore. + if(!factionEntry) + return false; + + return SetFactionReputation(factionEntry, standing); +} + +bool Player::SetFactionReputation(FactionEntry const* factionEntry, int32 standing) +{ + SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID); + if (flist) + { + bool res = false; + for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr) + { + FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr); + if(factionEntryCalc) + res = SetOneFactionReputation(factionEntryCalc, standing); + } + return res; + } + else + return SetOneFactionReputation(factionEntry, standing); +} + +bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing) +{ + FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); + if (itr != m_factions.end()) + { + if (standing > Reputation_Cap) + standing = Reputation_Cap; + else + if (standing < Reputation_Bottom) + standing = Reputation_Bottom; + + int32 BaseRep = GetBaseReputation(factionEntry); + itr->second.Standing = standing - BaseRep; + itr->second.Changed = true; + + SetFactionVisible(&itr->second); + + if(ReputationToRank(standing) <= REP_HOSTILE) + SetFactionAtWar(&itr->second,true); + + SendFactionState(&(itr->second)); + return true; + } + return false; +} + +//Calculate total reputation percent player gain with quest/creature level +int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest) +{ + // for grey creature kill received 20%, in other case 100. + int32 percent = (!for_quest && (creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel()))) ? 20 : 100; + + int32 repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + + percent += rep > 0 ? repMod : -repMod; + + if(percent <=0) + return 0; + + return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100); +} + +//Calculates how many reputation points player gains in victim's enemy factions +void Player::RewardReputation(Unit *pVictim, float rate) +{ + if(!pVictim || pVictim->GetTypeId() == TYPEID_PLAYER) + return; + + ReputationOnKillEntry const* Rep = objmgr.GetReputationOnKilEntry(((Creature*)pVictim)->GetCreatureInfo()->Entry); + + if(!Rep) + return; + + if(Rep->repfaction1 && (!Rep->team_dependent || GetTeam()==ALLIANCE)) + { + int32 donerep1 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue1,false); + donerep1 = int32(donerep1*rate); + FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(Rep->repfaction1); + uint32 current_reputation_rank1 = GetReputationRank(factionEntry1); + if(factionEntry1 && current_reputation_rank1 <= Rep->reputation_max_cap1) + ModifyFactionReputation(factionEntry1, donerep1); + + // Wiki: Team factions value divided by 2 + if(Rep->is_teamaward1) + { + FactionEntry const *team1_factionEntry = sFactionStore.LookupEntry(factionEntry1->team); + if(team1_factionEntry) + ModifyFactionReputation(team1_factionEntry, donerep1 / 2); + } + } + + if(Rep->repfaction2 && (!Rep->team_dependent || GetTeam()==HORDE)) + { + int32 donerep2 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue2,false); + donerep2 = int32(donerep2*rate); + FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(Rep->repfaction2); + uint32 current_reputation_rank2 = GetReputationRank(factionEntry2); + if(factionEntry2 && current_reputation_rank2 <= Rep->reputation_max_cap2) + ModifyFactionReputation(factionEntry2, donerep2); + + // Wiki: Team factions value divided by 2 + if(Rep->is_teamaward2) + { + FactionEntry const *team2_factionEntry = sFactionStore.LookupEntry(factionEntry2->team); + if(team2_factionEntry) + ModifyFactionReputation(team2_factionEntry, donerep2 / 2); + } + } +} + +//Calculate how many reputation points player gain with the quest +void Player::RewardReputation(Quest const *pQuest) +{ + // quest reputation reward/loss + for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) + { + if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] ) + { + int32 rep = CalculateReputationGain(pQuest->GetQuestLevel(),pQuest->RewRepValue[i],true); + FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]); + if(factionEntry) + ModifyFactionReputation(factionEntry, rep); + } + } + + // TODO: implement reputation spillover +} + +void Player::UpdateArenaFields(void) +{ + /* arena calcs go here */ +} + +void Player::UpdateHonorFields() +{ + /// called when rewarding honor and at each save + uint64 now = time(NULL); + uint64 today = uint64(time(NULL) / DAY) * DAY; + + if(m_lastHonorUpdateTime < today) + { + uint64 yesterday = today - DAY; + + uint16 kills_today = PAIR32_LOPART(GetUInt32Value(PLAYER_FIELD_KILLS)); + + // update yesterday's contribution + if(m_lastHonorUpdateTime >= yesterday ) + { + SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); + + // this is the first update today, reset today's contribution + SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); + SetUInt32Value(PLAYER_FIELD_KILLS, MAKE_PAIR32(0,kills_today)); + } + else + { + // no honor/kills yesterday or today, reset + SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); + SetUInt32Value(PLAYER_FIELD_KILLS, 0); + } + } + + m_lastHonorUpdateTime = now; +} + +///Calculate the amount of honor gained based on the victim +///and the size of the group for which the honor is divided +///An exact honor value can also be given (overriding the calcs) +bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if(GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return false; + + uint64 victim_guid = 0; + uint32 victim_rank = 0; + time_t now = time(NULL); + + // need call before fields update to have chance move yesterday data to appropriate fields before today data change. + UpdateHonorFields(); + + if(honor <= 0) + { + if(!uVictim || uVictim == this || uVictim->HasAuraType(SPELL_AURA_NO_PVP_CREDIT)) + return false; + + victim_guid = uVictim->GetGUID(); + + if( uVictim->GetTypeId() == TYPEID_PLAYER ) + { + Player *pVictim = (Player *)uVictim; + + if( GetTeam() == pVictim->GetTeam() && !sWorld.IsFFAPvPRealm() ) + return false; + + float f = 1; //need for total kills (?? need more info) + uint32 k_grey = 0; + uint32 k_level = getLevel(); + uint32 v_level = pVictim->getLevel(); + + { + // PLAYER_CHOSEN_TITLE VALUES DESCRIPTION + // [0] Just name + // [1..14] Alliance honor titles and player name + // [15..28] Horde honor titles and player name + // [29..38] Other title and player name + // [39+] Nothing + uint32 victim_title = pVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE); + // Get Killer titles, CharTitlesEntry::bit_index + // Ranks: + // title[1..14] -> rank[5..18] + // title[15..28] -> rank[5..18] + // title[other] -> 0 + if (victim_title == 0) + victim_guid = 0; // Don't show HK: message, only log. + else if (victim_title < 15) + victim_rank = victim_title + 4; + else if (victim_title < 29) + victim_rank = victim_title - 14 + 4; + else + victim_guid = 0; // Don't show HK: message, only log. + } + + if(k_level <= 5) + k_grey = 0; + else if( k_level <= 39 ) + k_grey = k_level - 5 - k_level/10; + else + k_grey = k_level - 1 - k_level/5; + + if(v_level<=k_grey) + return false; + + float diff_level = (k_level == k_grey) ? 1 : ((float(v_level) - float(k_grey)) / (float(k_level) - float(k_grey))); + + int32 v_rank =1; //need more info + + honor = ((f * diff_level * (190 + v_rank*10))/6); + honor *= ((float)k_level) / 70.0f; //factor of dependence on levels of the killer + + // count the number of playerkills in one day + ApplyModUInt32Value(PLAYER_FIELD_KILLS, 1, true); + // and those in a lifetime + ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 1, true); + } + else + { + Creature *cVictim = (Creature *)uVictim; + + if (!cVictim->isRacialLeader()) + return false; + + honor = 100; // ??? need more info + victim_rank = 19; // HK: Leader + } + } + + if (uVictim != NULL) + { + honor *= sWorld.getRate(RATE_HONOR); + + if(groupsize > 1) + honor /= groupsize; + + honor *= (((float)urand(8,12))/10); // approx honor: 80% - 120% of real honor + } + + // honor - for show honor points in log + // victim_guid - for show victim name in log + // victim_rank [1..4] HK: + // victim_rank [5..19] HK: + // victim_rank [0,20+] HK: <> + WorldPacket data(SMSG_PVP_CREDIT,4+8+4); + data << (uint32) honor; + data << (uint64) victim_guid; + data << (uint32) victim_rank; + + GetSession()->SendPacket(&data); + + // add honor points + ModifyHonorPoints(int32(honor)); + + ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, uint32(honor), true); + return true; +} + +void Player::ModifyHonorPoints( int32 value ) +{ + if(value < 0) + { + if (GetHonorPoints() > sWorld.getConfig(CONFIG_MAX_HONOR_POINTS)) + SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_MAX_HONOR_POINTS) + value); + else + SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, GetHonorPoints() > uint32(-value) ? GetHonorPoints() + value : 0); + } + else + SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, GetHonorPoints() < sWorld.getConfig(CONFIG_MAX_HONOR_POINTS) - value ? GetHonorPoints() + value : sWorld.getConfig(CONFIG_MAX_HONOR_POINTS)); +} + +void Player::ModifyArenaPoints( int32 value ) +{ + if(value < 0) + { + if (GetArenaPoints() > sWorld.getConfig(CONFIG_MAX_ARENA_POINTS)) + SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, sWorld.getConfig(CONFIG_MAX_ARENA_POINTS) + value); + else + SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, GetArenaPoints() > uint32(-value) ? GetArenaPoints() + value : 0); + } + else + SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, GetArenaPoints() < sWorld.getConfig(CONFIG_MAX_ARENA_POINTS) - value ? GetArenaPoints() + value : sWorld.getConfig(CONFIG_MAX_ARENA_POINTS)); +} + +uint32 Player::GetGuildIdFromDB(uint64 guid) +{ + std::ostringstream ss; + ss<<"SELECT guildid FROM guild_member WHERE guid='"<Fetch()[0].GetUInt32(); + delete result; + return v; + } + else + return 0; +} + +uint32 Player::GetRankFromDB(uint64 guid) +{ + std::ostringstream ss; + ss<<"SELECT rank FROM guild_member WHERE guid='"<Fetch()[0].GetUInt32(); + delete result; + return v; + } + else + return 0; +} + +uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) +{ + // need fix it! + QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid FROM arena_team_member WHERE guid='%u'", GUID_LOPART(guid)); + if(result) + { + // init id to 0, check the arena type before assigning a value to id + uint32 id = 0; + do + { + QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM arena_team WHERE arenateamid='%u'", id); + if(result2) + { + uint8 dbtype = (*result2)[0].GetUInt32(); + delete result2; + if(dbtype == type) + { + // if the type matches, we've found the id + id = (*result)[0].GetUInt32(); + break; + } + } + } while(result->NextRow()); + delete result; + return id; + } + // no arenateam for the specified guid, return 0 + return 0; +} + +uint32 Player::GetZoneIdFromDB(uint64 guid) +{ + std::ostringstream ss; + + ss<<"SELECT zone FROM characters WHERE guid='"<Fetch(); + uint32 zone = fields[0].GetUInt32(); + delete result; + + if (!zone) + { + // stored zone is zero, use generic and slow zone detection + ss.str(""); + ss<<"SELECT map,position_x,position_y FROM characters WHERE guid='"<Fetch(); + uint32 map = fields[0].GetUInt32(); + float posx = fields[1].GetFloat(); + float posy = fields[2].GetFloat(); + delete result; + + zone = MapManager::Instance().GetZoneId(map,posx,posy); + + ss.str(""); + ss << "UPDATE characters SET zone='"<flags & AREA_FLAG_ARENA)) + { + if(!isGameMaster()) + SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); + } + else + { + // remove ffa flag only if not ffapvp realm + // removal in sanctuaries and capitals is handled in zone update + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && !sWorld.IsFFAPvPRealm()) + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); + } + + UpdateAreaDependentAuras(newArea); +} + +void Player::UpdateZone(uint32 newZone) +{ + m_zoneUpdateId = newZone; + m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; + + // zone changed, so area changed as well, update it + UpdateArea(GetAreaId()); + + AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone); + if(!zone) + return; + + if (sWorld.getConfig(CONFIG_WEATHER)) + { + Weather *wth = sWorld.FindWeather(zone->ID); + if(wth) + { + wth->SendWeatherUpdateToPlayer(this); + } + else + { + if(!sWorld.AddWeather(zone->ID)) + { + // send fine weather packet to remove old zone's weather + Weather::SendFineWeatherUpdateToPlayer(this); + } + } + } + + pvpInfo.inHostileArea = + GetTeam() == ALLIANCE && zone->team == AREATEAM_HORDE || + GetTeam() == HORDE && zone->team == AREATEAM_ALLY || + sWorld.IsPvPRealm() && zone->team == AREATEAM_NONE || + InBattleGround(); // overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this + + if(pvpInfo.inHostileArea) // in hostile area + { + if(!IsPvP() || pvpInfo.endTimer != 0) + UpdatePvP(true, true); + } + else // in friendly area + { + if(IsPvP() && !HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0) + pvpInfo.endTimer = time(0); // start toggle-off + } + + if(zone->flags & AREA_FLAG_SANCTUARY) // in sanctuary + { + SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY); + if(sWorld.IsFFAPvPRealm()) + RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + } + else + { + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY); + } + + if(zone->flags & AREA_FLAG_CAPITAL) // in capital city + { + SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); + SetRestType(REST_TYPE_IN_CITY); + InnEnter(time(0),GetMapId(),0,0,0); + + if(sWorld.IsFFAPvPRealm()) + RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + } + else // anywhere else + { + if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) // but resting (walk from city or maybe in tavern or leave tavern recently) + { + if(GetRestType()==REST_TYPE_IN_TAVERN) // has been in tavern. Is still in? + { + if(GetMapId()!=GetInnPosMapId() || sqrt((GetPositionX()-GetInnPosX())*(GetPositionX()-GetInnPosX())+(GetPositionY()-GetInnPosY())*(GetPositionY()-GetInnPosY())+(GetPositionZ()-GetInnPosZ())*(GetPositionZ()-GetInnPosZ()))>40) + { + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); + SetRestType(REST_TYPE_NO); + + if(sWorld.IsFFAPvPRealm()) + SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + } + } + else // not in tavern (leave city then) + { + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); + SetRestType(REST_TYPE_NO); + + // Set player to FFA PVP when not in rested enviroment. + if(sWorld.IsFFAPvPRealm()) + SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); + } + } + } + + // remove items with area/map limitations (delete only for alive player to allow back in ghost mode) + // if player resurrected at teleport this will be applied in resurrect code + if(isAlive()) + DestroyZoneLimitedItem( true, newZone ); + + // recent client version not send leave/join channel packets for built-in local channels + UpdateLocalChannels( newZone ); + + // group update + if(GetGroup()) + SetGroupUpdateFlag(GROUP_UPDATE_FLAG_ZONE); + + UpdateZoneDependentAuras(newZone); +} + +//If players are too far way of duel flag... then player loose the duel +void Player::CheckDuelDistance(time_t currTime) +{ + if(!duel) + return; + + uint64 duelFlagGUID = GetUInt64Value(PLAYER_DUEL_ARBITER); + GameObject* obj = ObjectAccessor::GetGameObject(*this, duelFlagGUID); + if(!obj) + return; + + if(duel->outOfBound == 0) + { + if(!IsWithinDistInMap(obj, 50)) + { + duel->outOfBound = currTime; + + WorldPacket data(SMSG_DUEL_OUTOFBOUNDS, 0); + GetSession()->SendPacket(&data); + } + } + else + { + if(IsWithinDistInMap(obj, 40)) + { + duel->outOfBound = 0; + + WorldPacket data(SMSG_DUEL_INBOUNDS, 0); + GetSession()->SendPacket(&data); + } + else if(currTime >= (duel->outOfBound+10)) + { + DuelComplete(DUEL_FLED); + } + } +} + +void Player::DuelComplete(DuelCompleteType type) +{ + // duel not requested + if(!duel) + return; + + WorldPacket data(SMSG_DUEL_COMPLETE, (1)); + data << (uint8)((type != DUEL_INTERUPTED) ? 1 : 0); + GetSession()->SendPacket(&data); + duel->opponent->GetSession()->SendPacket(&data); + + if(type != DUEL_INTERUPTED) + { + data.Initialize(SMSG_DUEL_WINNER, (1+20)); // we guess size + data << (uint8)((type==DUEL_WON) ? 0 : 1); // 0 = just won; 1 = fled + data << duel->opponent->GetName(); + data << GetName(); + SendMessageToSet(&data,true); + } + + // cool-down duel spell + /*data.Initialize(SMSG_SPELL_COOLDOWN, 17); + + data<SendPacket(&data); + data.Initialize(SMSG_SPELL_COOLDOWN, 17); + data<opponent->GetGUID(); + data<opponent->GetSession()->SendPacket(&data);*/ + + //Remove Duel Flag object + GameObject* obj = ObjectAccessor::GetGameObject(*this, GetUInt64Value(PLAYER_DUEL_ARBITER)); + if(obj) + duel->initiator->RemoveGameObject(obj,true); + + /* remove auras */ + std::vector auras2remove; + AuraMap const& vAuras = duel->opponent->GetAuras(); + for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); i++) + { + if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) + auras2remove.push_back(i->second->GetId()); + } + + for(size_t i=0; iopponent->RemoveAurasDueToSpell(auras2remove[i]); + + auras2remove.clear(); + AuraMap const& auras = GetAuras(); + for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); i++) + { + if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) + auras2remove.push_back(i->second->GetId()); + } + for(size_t i=0; iopponent->GetGUID()) + ClearComboPoints(); + else if(GetComboTarget()==duel->opponent->GetPetGUID()) + ClearComboPoints(); + + if(duel->opponent->GetComboTarget()==GetGUID()) + duel->opponent->ClearComboPoints(); + else if(duel->opponent->GetComboTarget()==GetPetGUID()) + duel->opponent->ClearComboPoints(); + + //cleanups + SetUInt64Value(PLAYER_DUEL_ARBITER, 0); + SetUInt32Value(PLAYER_DUEL_TEAM, 0); + duel->opponent->SetUInt64Value(PLAYER_DUEL_ARBITER, 0); + duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 0); + + delete duel->opponent->duel; + duel->opponent->duel = NULL; + delete duel; + duel = NULL; +} + +//---------------------------------------------------------// + +void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply) +{ + if(slot >= INVENTORY_SLOT_BAG_END || !item) + return; + + // not apply/remove mods for broken item + if(item->IsBroken()) + return; + + ItemPrototype const *proto = item->GetProto(); + + if(!proto) + return; + + sLog.outDetail("applying mods for item %u ",item->GetGUIDLow()); + + uint32 attacktype = Player::GetAttackBySlot(slot); + if(attacktype < MAX_ATTACK) + _ApplyWeaponDependentAuraMods(item,WeaponAttackType(attacktype),apply); + + _ApplyItemBonuses(proto,slot,apply); + + if( slot==EQUIPMENT_SLOT_RANGED ) + _ApplyAmmoBonuses(); + + ApplyItemEquipSpell(item,apply); + ApplyEnchantment(item, apply); + + if(proto->Socket[0].Color) //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items + CorrectMetaGemEnchants(slot, apply); + + sLog.outDebug("_ApplyItemMods complete."); +} + +void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply) +{ + if(slot >= INVENTORY_SLOT_BAG_END || !proto) + return; + + for (int i = 0; i < 10; i++) + { + float val = float (proto->ItemStat[i].ItemStatValue); + + if(val==0) + continue; + + switch (proto->ItemStat[i].ItemStatType) + { + case ITEM_MOD_MANA: + HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_HEALTH: // modify HP + HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_AGILITY: // modify agility + HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply); + ApplyStatBuffMod(STAT_AGILITY, val, apply); + break; + case ITEM_MOD_STRENGTH: //modify strength + HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply); + ApplyStatBuffMod(STAT_STRENGTH, val, apply); + break; + case ITEM_MOD_INTELLECT: //modify intellect + HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply); + ApplyStatBuffMod(STAT_INTELLECT, val, apply); + break; + case ITEM_MOD_SPIRIT: //modify spirit + HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply); + ApplyStatBuffMod(STAT_SPIRIT, val, apply); + break; + case ITEM_MOD_STAMINA: //modify stamina + HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply); + ApplyStatBuffMod(STAT_STAMINA, val, apply); + break; + case ITEM_MOD_DEFENSE_SKILL_RATING: + ApplyRatingMod(CR_DEFENSE_SKILL, int32(val), apply); + break; + case ITEM_MOD_DODGE_RATING: + ApplyRatingMod(CR_DODGE, int32(val), apply); + break; + case ITEM_MOD_PARRY_RATING: + ApplyRatingMod(CR_PARRY, int32(val), apply); + break; + case ITEM_MOD_BLOCK_RATING: + ApplyRatingMod(CR_BLOCK, int32(val), apply); + break; + case ITEM_MOD_HIT_MELEE_RATING: + ApplyRatingMod(CR_HIT_MELEE, int32(val), apply); + break; + case ITEM_MOD_HIT_RANGED_RATING: + ApplyRatingMod(CR_HIT_RANGED, int32(val), apply); + break; + case ITEM_MOD_HIT_SPELL_RATING: + ApplyRatingMod(CR_HIT_SPELL, int32(val), apply); + break; + case ITEM_MOD_CRIT_MELEE_RATING: + ApplyRatingMod(CR_CRIT_MELEE, int32(val), apply); + break; + case ITEM_MOD_CRIT_RANGED_RATING: + ApplyRatingMod(CR_CRIT_RANGED, int32(val), apply); + break; + case ITEM_MOD_CRIT_SPELL_RATING: + ApplyRatingMod(CR_CRIT_SPELL, int32(val), apply); + break; + case ITEM_MOD_HIT_TAKEN_MELEE_RATING: + ApplyRatingMod(CR_HIT_TAKEN_MELEE, int32(val), apply); + break; + case ITEM_MOD_HIT_TAKEN_RANGED_RATING: + ApplyRatingMod(CR_HIT_TAKEN_RANGED, int32(val), apply); + break; + case ITEM_MOD_HIT_TAKEN_SPELL_RATING: + ApplyRatingMod(CR_HIT_TAKEN_SPELL, int32(val), apply); + break; + case ITEM_MOD_CRIT_TAKEN_MELEE_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply); + break; + case ITEM_MOD_CRIT_TAKEN_RANGED_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply); + break; + case ITEM_MOD_CRIT_TAKEN_SPELL_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply); + break; + case ITEM_MOD_HASTE_MELEE_RATING: + ApplyRatingMod(CR_HASTE_MELEE, int32(val), apply); + break; + case ITEM_MOD_HASTE_RANGED_RATING: + ApplyRatingMod(CR_HASTE_RANGED, int32(val), apply); + break; + case ITEM_MOD_HASTE_SPELL_RATING: + ApplyRatingMod(CR_HASTE_SPELL, int32(val), apply); + break; + case ITEM_MOD_HIT_RATING: + ApplyRatingMod(CR_HIT_MELEE, int32(val), apply); + ApplyRatingMod(CR_HIT_RANGED, int32(val), apply); + ApplyRatingMod(CR_HIT_SPELL, int32(val), apply); + break; + case ITEM_MOD_CRIT_RATING: + ApplyRatingMod(CR_CRIT_MELEE, int32(val), apply); + ApplyRatingMod(CR_CRIT_RANGED, int32(val), apply); + ApplyRatingMod(CR_CRIT_SPELL, int32(val), apply); + break; + case ITEM_MOD_HIT_TAKEN_RATING: + ApplyRatingMod(CR_HIT_TAKEN_MELEE, int32(val), apply); + ApplyRatingMod(CR_HIT_TAKEN_RANGED, int32(val), apply); + ApplyRatingMod(CR_HIT_TAKEN_SPELL, int32(val), apply); + break; + case ITEM_MOD_CRIT_TAKEN_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply); + ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply); + ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply); + break; + case ITEM_MOD_RESILIENCE_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply); + ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply); + ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply); + break; + case ITEM_MOD_HASTE_RATING: + ApplyRatingMod(CR_HASTE_MELEE, int32(val), apply); + ApplyRatingMod(CR_HASTE_RANGED, int32(val), apply); + ApplyRatingMod(CR_HASTE_SPELL, int32(val), apply); + break; + case ITEM_MOD_EXPERTISE_RATING: + ApplyRatingMod(CR_EXPERTISE, int32(val), apply); + break; + } + } + + if (proto->Armor) + HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(proto->Armor), apply); + + if (proto->Block) + HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply); + + if (proto->HolyRes) + HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(proto->HolyRes), apply); + + if (proto->FireRes) + HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(proto->FireRes), apply); + + if (proto->NatureRes) + HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(proto->NatureRes), apply); + + if (proto->FrostRes) + HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(proto->FrostRes), apply); + + if (proto->ShadowRes) + HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(proto->ShadowRes), apply); + + if (proto->ArcaneRes) + HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply); + + WeaponAttackType attType = BASE_ATTACK; + float damage = 0.0f; + + if( slot == EQUIPMENT_SLOT_RANGED && ( + proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_THROWN || + proto->InventoryType == INVTYPE_RANGEDRIGHT )) + { + attType = RANGED_ATTACK; + } + else if(slot==EQUIPMENT_SLOT_OFFHAND) + { + attType = OFF_ATTACK; + } + + if (proto->Damage[0].DamageMin > 0 ) + { + damage = apply ? proto->Damage[0].DamageMin : BASE_MINDAMAGE; + SetBaseWeaponDamage(attType, MINDAMAGE, damage); + //sLog.outError("applying mindam: assigning %f to weapon mindamage, now is: %f", damage, GetWeaponDamageRange(attType, MINDAMAGE)); + } + + if (proto->Damage[0].DamageMax > 0 ) + { + damage = apply ? proto->Damage[0].DamageMax : BASE_MAXDAMAGE; + SetBaseWeaponDamage(attType, MAXDAMAGE, damage); + } + + if(!IsUseEquipedWeapon(slot==EQUIPMENT_SLOT_MAINHAND)) + return; + + if (proto->Delay) + { + if(slot == EQUIPMENT_SLOT_RANGED) + SetAttackTime(RANGED_ATTACK, apply ? proto->Delay: BASE_ATTACK_TIME); + else if(slot==EQUIPMENT_SLOT_MAINHAND) + SetAttackTime(BASE_ATTACK, apply ? proto->Delay: BASE_ATTACK_TIME); + else if(slot==EQUIPMENT_SLOT_OFFHAND) + SetAttackTime(OFF_ATTACK, apply ? proto->Delay: BASE_ATTACK_TIME); + } + + if(CanModifyStats() && (damage || proto->Delay)) + UpdateDamagePhysical(attType); +} + +void Player::_ApplyWeaponDependentAuraMods(Item *item,WeaponAttackType attackType,bool apply) +{ + AuraList const& auraCritList = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT); + for(AuraList::const_iterator itr = auraCritList.begin(); itr!=auraCritList.end();++itr) + _ApplyWeaponDependentAuraCritMod(item,attackType,*itr,apply); + + AuraList const& auraDamageFlatList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE); + for(AuraList::const_iterator itr = auraDamageFlatList.begin(); itr!=auraDamageFlatList.end();++itr) + _ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply); + + AuraList const& auraDamagePCTList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for(AuraList::const_iterator itr = auraDamagePCTList.begin(); itr!=auraDamagePCTList.end();++itr) + _ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply); +} + +void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply) +{ + // generic not weapon specific case processes in aura code + if(aura->GetSpellProto()->EquippedItemClass == -1) + return; + + BaseModGroup mod = BASEMOD_END; + switch(attackType) + { + case BASE_ATTACK: mod = CRIT_PERCENTAGE; break; + case OFF_ATTACK: mod = OFFHAND_CRIT_PERCENTAGE;break; + case RANGED_ATTACK: mod = RANGED_CRIT_PERCENTAGE; break; + default: return; + } + + if (item->IsFitToSpellRequirements(aura->GetSpellProto())) + { + HandleBaseModValue(mod, FLAT_MOD, float (aura->GetModifier()->m_amount), apply); + } +} + +void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply) +{ + // ignore spell mods for not wands + Modifier const* modifier = aura->GetModifier(); + if((modifier->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)==0 && (getClassMask() & CLASSMASK_WAND_USERS)==0) + return; + + // generic not weapon specific case processes in aura code + if(aura->GetSpellProto()->EquippedItemClass == -1) + return; + + UnitMods unitMod = UNIT_MOD_END; + switch(attackType) + { + case BASE_ATTACK: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; + case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; + case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; + default: return; + } + + UnitModifierType unitModType = TOTAL_VALUE; + switch(modifier->m_auraname) + { + case SPELL_AURA_MOD_DAMAGE_DONE: unitModType = TOTAL_VALUE; break; + case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: unitModType = TOTAL_PCT; break; + default: return; + } + + if (item->IsFitToSpellRequirements(aura->GetSpellProto())) + { + HandleStatModifier(unitMod, unitModType, float(modifier->m_amount),apply); + } +} + +void Player::ApplyItemEquipSpell(Item *item, bool apply, bool form_change) +{ + if(!item) + return; + + ItemPrototype const *proto = item->GetProto(); + if(!proto) + return; + + for (int i = 0; i < 5; i++) + { + _Spell const& spellData = proto->Spells[i]; + + // no spell + if(!spellData.SpellId ) + continue; + + // wrong triggering type + if(apply && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_EQUIP) + continue; + + // check if it is valid spell + SpellEntry const* spellproto = sSpellStore.LookupEntry(spellData.SpellId); + if(!spellproto) + continue; + + ApplyEquipSpell(spellproto,item,apply,form_change); + } +} + +void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change) +{ + if(apply) + { + // Cannot be used in this stance/form + if(GetErrorAtShapeshiftedCast(spellInfo, m_form)!=0) + return; + + if(form_change) // check aura active state from other form + { + bool found = false; + for (int k=0; k < 3; ++k) + { + spellEffectPair spair = spellEffectPair(spellInfo->Id, k); + for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter) + { + if(!item || iter->second->GetCastItemGUID() == item->GetGUID()) + { + found = true; + break; + } + } + if(found) + break; + } + + if(found) // and skip re-cast already active aura at form change + return; + } + + DEBUG_LOG("WORLD: cast %s Equip spellId - %i", (item ? "item" : "itemset"), spellInfo->Id); + + CastSpell(this,spellInfo,true,item); + } + else + { + if(form_change) // check aura compatibility + { + // Cannot be used in this stance/form + if(GetErrorAtShapeshiftedCast(spellInfo, m_form)==0) + return; // and remove only not compatible at form change + } + + if(item) + RemoveAurasDueToItemSpell(item,spellInfo->Id); // un-apply all spells , not only at-equipped + else + RemoveAurasDueToSpell(spellInfo->Id); // un-apply spell (item set case) + } +} + +void Player::UpdateEquipSpellsAtFormChange() +{ + for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++) + { + if(m_items[i] && !m_items[i]->IsBroken()) + { + ApplyItemEquipSpell(m_items[i],false,true); // remove spells that not fit to form + ApplyItemEquipSpell(m_items[i],true,true); // add spells that fit form but not active + } + } + + // item set bonuses not dependent from item broken state + for(size_t setindex = 0; setindex < ItemSetEff.size(); ++setindex) + { + ItemSetEffect* eff = ItemSetEff[setindex]; + if(!eff) + continue; + + for(uint32 y=0;y<8; ++y) + { + SpellEntry const* spellInfo = eff->spells[y]; + if(!spellInfo) + continue; + + ApplyEquipSpell(spellInfo,NULL,false,true); // remove spells that not fit to form + ApplyEquipSpell(spellInfo,NULL,true,true); // add spells that fit form but not active + } + } +} + +void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType) +{ + if(!item || item->IsBroken()) + return; + + ItemPrototype const *proto = item->GetProto(); + if(!proto) + return; + + if (!Target || Target == this ) + return; + + for (int i = 0; i < 5; i++) + { + _Spell const& spellData = proto->Spells[i]; + + // no spell + if(!spellData.SpellId ) + continue; + + // wrong triggering type + if(spellData.SpellTrigger != ITEM_SPELLTRIGGER_CHANCE_ON_HIT) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId); + if(!spellInfo) + { + sLog.outError("WORLD: unknown Item spellid %i", spellData.SpellId); + continue; + } + + // not allow proc extra attack spell at extra attack + if( m_extraAttacks && IsSpellHaveEffect(spellInfo,SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) + return; + + float chance = spellInfo->procChance; + + if(spellData.SpellPPMRate) + { + uint32 WeaponSpeed = GetAttackTime(attType); + chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate); + } + else if(chance > 100.0f) + { + chance = GetWeaponProcChance(); + } + + if (roll_chance_f(chance)) + this->CastSpell(Target, spellInfo->Id, true, item); + } + + // item combat enchantments + for(int e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) + { + uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot)); + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) continue; + for (int s=0;s<3;s++) + { + if(pEnchant->type[s]!=ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(pEnchant->spellid[s]); + if (!spellInfo) + { + sLog.outError("Player::CastItemCombatSpell Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]); + continue; + } + + float chance = pEnchant->amount[s] != 0 ? float(pEnchant->amount[s]) : GetWeaponProcChance(); + if (roll_chance_f(chance)) + { + if(IsPositiveSpell(pEnchant->spellid[s])) + CastSpell(this, pEnchant->spellid[s], true, item); + else + CastSpell(Target, pEnchant->spellid[s], true, item); + } + } + } +} + +void Player::_RemoveAllItemMods() +{ + sLog.outDebug("_RemoveAllItemMods start."); + + for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++) + { + if(m_items[i]) + { + ItemPrototype const *proto = m_items[i]->GetProto(); + if(!proto) + continue; + + // item set bonuses not dependent from item broken state + if(proto->ItemSet) + RemoveItemsSetItem(this,proto); + + if(m_items[i]->IsBroken()) + continue; + + ApplyItemEquipSpell(m_items[i],false); + ApplyEnchantment(m_items[i], false); + } + } + + for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++) + { + if(m_items[i]) + { + if(m_items[i]->IsBroken()) + continue; + ItemPrototype const *proto = m_items[i]->GetProto(); + if(!proto) + continue; + + uint32 attacktype = Player::GetAttackBySlot(i); + if(attacktype < MAX_ATTACK) + _ApplyWeaponDependentAuraMods(m_items[i],WeaponAttackType(attacktype),false); + + _ApplyItemBonuses(proto,i, false); + + if( i == EQUIPMENT_SLOT_RANGED ) + _ApplyAmmoBonuses(); + } + } + + sLog.outDebug("_RemoveAllItemMods complete."); +} + +void Player::_ApplyAllItemMods() +{ + sLog.outDebug("_ApplyAllItemMods start."); + + for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++) + { + if(m_items[i]) + { + if(m_items[i]->IsBroken()) + continue; + + ItemPrototype const *proto = m_items[i]->GetProto(); + if(!proto) + continue; + + uint32 attacktype = Player::GetAttackBySlot(i); + if(attacktype < MAX_ATTACK) + _ApplyWeaponDependentAuraMods(m_items[i],WeaponAttackType(attacktype),true); + + _ApplyItemBonuses(proto,i, true); + + if( i == EQUIPMENT_SLOT_RANGED ) + _ApplyAmmoBonuses(); + } + } + + for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++) + { + if(m_items[i]) + { + ItemPrototype const *proto = m_items[i]->GetProto(); + if(!proto) + continue; + + // item set bonuses not dependent from item broken state + if(proto->ItemSet) + AddItemsSetItem(this,m_items[i]); + + if(m_items[i]->IsBroken()) + continue; + + ApplyItemEquipSpell(m_items[i],true); + ApplyEnchantment(m_items[i], true); + } + } + + sLog.outDebug("_ApplyAllItemMods complete."); +} + +void Player::_ApplyAmmoBonuses() +{ + // check ammo + uint32 ammo_id = GetUInt32Value(PLAYER_AMMO_ID); + if(!ammo_id) + return; + + float currentAmmoDPS; + + ItemPrototype const *ammo_proto = objmgr.GetItemPrototype( ammo_id ); + if( !ammo_proto || ammo_proto->Class!=ITEM_CLASS_PROJECTILE || !CheckAmmoCompatibility(ammo_proto)) + currentAmmoDPS = 0.0f; + else + currentAmmoDPS = ammo_proto->Damage[0].DamageMin; + + if(currentAmmoDPS == GetAmmoDPS()) + return; + + m_ammoDPS = currentAmmoDPS; + + if(CanModifyStats()) + UpdateDamagePhysical(RANGED_ATTACK); +} + +bool Player::CheckAmmoCompatibility(const ItemPrototype *ammo_proto) const +{ + if(!ammo_proto) + return false; + + // check ranged weapon + Item *weapon = GetWeaponForAttack( RANGED_ATTACK ); + if(!weapon || weapon->IsBroken() ) + return false; + + ItemPrototype const* weapon_proto = weapon->GetProto(); + if(!weapon_proto || weapon_proto->Class!=ITEM_CLASS_WEAPON ) + return false; + + // check ammo ws. weapon compatibility + switch(weapon_proto->SubClass) + { + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + if(ammo_proto->SubClass!=ITEM_SUBCLASS_ARROW) + return false; + break; + case ITEM_SUBCLASS_WEAPON_GUN: + if(ammo_proto->SubClass!=ITEM_SUBCLASS_BULLET) + return false; + break; + default: + return false; + } + + return true; +} + +/* If in a battleground a player dies, and an enemy removes the insignia, the player's bones is lootable + Called by remove insignia spell effect */ +void Player::RemovedInsignia(Player* looterPlr) +{ + if (!GetBattleGroundId()) + return; + + // If not released spirit, do it ! + if(m_deathTimer > 0) + { + m_deathTimer = 0; + BuildPlayerRepop(); + RepopAtGraveyard(); + } + + Corpse *corpse = GetCorpse(); + if (!corpse) + return; + + // We have to convert player corpse to bones, not to be able to resurrect there + // SpawnCorpseBones isn't handy, 'cos it saves player while he in BG + Corpse *bones = ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID()); + if (!bones) + return; + + // Now we must make bones lootable, and send player loot + bones->SetFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE); + + // We store the level of our player in the gold field + // We retrieve this information at Player::SendLoot() + bones->loot.gold = getLevel(); + bones->lootRecipient = looterPlr; + looterPlr->SendLoot(bones->GetGUID(), LOOT_INSIGNIA); +} + +/*Loot type MUST be +1-corpse, go +2-skinning +3-Fishing +*/ + +void Player::SendLootRelease( uint64 guid ) +{ + WorldPacket data( SMSG_LOOT_RELEASE_RESPONSE, (8+1) ); + data << uint64(guid) << uint8(1); + SendDirectMessage( &data ); +} + +void Player::SendLoot(uint64 guid, LootType loot_type) +{ + Loot *loot = 0; + PermissionTypes permission = ALL_PERMISSION; + + sLog.outDebug("Player::SendLoot"); + if (IS_GAMEOBJECT_GUID(guid)) + { + sLog.outDebug(" IS_GAMEOBJECT_GUID(guid)"); + GameObject *go = + ObjectAccessor::GetGameObject(*this, guid); + + // not check distance for GO in case owned GO (fishing bobber case, for example) + // And permit out of range GO with no owner in case fishing hole + if (!go || (loot_type != LOOT_FISHINGHOLE && (loot_type != LOOT_FISHING || go->GetOwnerGUID() != GetGUID()) && !go->IsWithinDistInMap(this,INTERACTION_DISTANCE))) + { + SendLootRelease(guid); + return; + } + + loot = &go->loot; + + if(go->getLootState() == GO_READY) + { + uint32 lootid = go->GetLootId(); + + if(lootid) + { + sLog.outDebug(" if(lootid)"); + loot->clear(); + loot->FillLoot(lootid, LootTemplates_Gameobject, this); + } + + if(loot_type == LOOT_FISHING) + go->getFishLoot(loot); + + go->SetLootState(GO_ACTIVATED); + } + } + else if (IS_ITEM_GUID(guid)) + { + Item *item = GetItemByGuid( guid ); + + if (!item) + { + SendLootRelease(guid); + return; + } + + if(loot_type == LOOT_DISENCHANTING) + { + loot = &item->loot; + + if(!item->m_lootGenerated) + { + item->m_lootGenerated = true; + loot->clear(); + loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this); + } + } + else if(loot_type == LOOT_PROSPECTING) + { + loot = &item->loot; + + if(!item->m_lootGenerated) + { + item->m_lootGenerated = true; + loot->clear(); + loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this); + } + } + else + { + loot = &item->loot; + + if(!item->m_lootGenerated) + { + item->m_lootGenerated = true; + loot->clear(); + loot->FillLoot(item->GetEntry(), LootTemplates_Item, this); + + loot->generateMoneyLoot(item->GetProto()->MinMoneyLoot,item->GetProto()->MaxMoneyLoot); + } + } + } + else if (IS_CORPSE_GUID(guid)) // remove insignia + { + Corpse *bones = ObjectAccessor::GetCorpse(*this, guid); + + if (!bones || !((loot_type == LOOT_CORPSE) || (loot_type == LOOT_INSIGNIA)) || (bones->GetType() != CORPSE_BONES) ) + { + SendLootRelease(guid); + return; + } + + loot = &bones->loot; + + if (!bones->lootForBody) + { + bones->lootForBody = true; + uint32 pLevel = bones->loot.gold; + bones->loot.clear(); + // It may need a better formula + // Now it works like this: lvl10: ~6copper, lvl70: ~9silver + bones->loot.gold = (uint32)( urand(50, 150) * 0.016f * pow( ((float)pLevel)/5.76f, 2.5f) * sWorld.getRate(RATE_DROP_MONEY) ); + } + + if (bones->lootRecipient != this) + permission = NONE_PERMISSION; + } + else + { + Creature *creature = ObjectAccessor::GetCreature(*this, guid); + + // must be in range and creature must be alive for pickpocket and must be dead for another loot + if (!creature || creature->isAlive()!=(loot_type == LOOT_PICKPOCKETING) || !creature->IsWithinDistInMap(this,INTERACTION_DISTANCE)) + { + SendLootRelease(guid); + return; + } + + if(loot_type == LOOT_PICKPOCKETING && IsFriendlyTo(creature)) + { + SendLootRelease(guid); + return; + } + + loot = &creature->loot; + + if(loot_type == LOOT_PICKPOCKETING) + { + if ( !creature->lootForPickPocketed ) + { + creature->lootForPickPocketed = true; + loot->clear(); + + if (uint32 lootid = creature->GetCreatureInfo()->pickpocketLootId) + loot->FillLoot(lootid, LootTemplates_Pickpocketing, this); + + // Generate extra money for pick pocket loot + const uint32 a = urand(0, creature->getLevel()/2); + const uint32 b = urand(0, getLevel()/2); + loot->gold = uint32(10 * (a + b) * sWorld.getRate(RATE_DROP_MONEY)); + } + } + else + { + // the player whose group may loot the corpse + Player *recipient = creature->GetLootRecipient(); + if (!recipient) + { + creature->SetLootRecipient(this); + recipient = this; + } + + if (creature->lootForPickPocketed) + { + creature->lootForPickPocketed = false; + loot->clear(); + } + + if(!creature->lootForBody) + { + creature->lootForBody = true; + loot->clear(); + + if (uint32 lootid = creature->GetCreatureInfo()->lootid) + loot->FillLoot(lootid, LootTemplates_Creature, recipient); + + loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold); + + if(Group* group = recipient->GetGroup()) + { + group->UpdateLooterGuid(creature,true); + + switch (group->GetLootMethod()) + { + case GROUP_LOOT: + // GroupLoot delete items over threshold (threshold even not implemented), and roll them. Items with qualityGroupLoot(recipient->GetGUID(), loot, creature); + break; + case NEED_BEFORE_GREED: + group->NeedBeforeGreed(recipient->GetGUID(), loot, creature); + break; + case MASTER_LOOT: + group->MasterLoot(recipient->GetGUID(), loot, creature); + break; + default: + break; + } + } + } + + // possible only if creature->lootForBody && loot->empty() at spell cast check + if (loot_type == LOOT_SKINNING) + { + loot->clear(); + loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this); + } + // set group rights only for loot_type != LOOT_SKINNING + else + { + if(Group* group = GetGroup()) + { + if( group == recipient->GetGroup() ) + { + if(group->GetLootMethod() == FREE_FOR_ALL) + permission = ALL_PERMISSION; + else if(group->GetLooterGuid() == GetGUID()) + { + if(group->GetLootMethod() == MASTER_LOOT) + permission = MASTER_PERMISSION; + else + permission = ALL_PERMISSION; + } + else + permission = GROUP_PERMISSION; + } + else + permission = NONE_PERMISSION; + } + else if(recipient == this) + permission = ALL_PERMISSION; + else + permission = NONE_PERMISSION; + } + } + } + + SetLootGUID(guid); + + QuestItemList *q_list = 0; + if (permission != NONE_PERMISSION) + { + QuestItemMap const& lootPlayerQuestItems = loot->GetPlayerQuestItems(); + QuestItemMap::const_iterator itr = lootPlayerQuestItems.find(GetGUIDLow()); + if (itr == lootPlayerQuestItems.end()) + q_list = loot->FillQuestLoot(this); + else + q_list = itr->second; + } + + QuestItemList *ffa_list = 0; + if (permission != NONE_PERMISSION) + { + QuestItemMap const& lootPlayerFFAItems = loot->GetPlayerFFAItems(); + QuestItemMap::const_iterator itr = lootPlayerFFAItems.find(GetGUIDLow()); + if (itr == lootPlayerFFAItems.end()) + ffa_list = loot->FillFFALoot(this); + else + ffa_list = itr->second; + } + + QuestItemList *conditional_list = 0; + if (permission != NONE_PERMISSION) + { + QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = loot->GetPlayerNonQuestNonFFAConditionalItems(); + QuestItemMap::const_iterator itr = lootPlayerNonQuestNonFFAConditionalItems.find(GetGUIDLow()); + if (itr == lootPlayerNonQuestNonFFAConditionalItems.end()) + conditional_list = loot->FillNonQuestNonFFAConditionalLoot(this); + else + conditional_list = itr->second; + } + + // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING and LOOT_INSIGNIA unsupported by client, sending LOOT_SKINNING instead + if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA) + loot_type = LOOT_SKINNING; + + if(loot_type == LOOT_FISHINGHOLE) + loot_type = LOOT_FISHING; + + WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size + + data << uint64(guid); + data << uint8(loot_type); + data << LootView(*loot, q_list, ffa_list, conditional_list, this, permission); + + SendDirectMessage(&data); + + // add 'this' player as one of the players that are looting 'loot' + if (permission != NONE_PERMISSION) + loot->AddLooter(GetGUID()); + + if ( loot_type == LOOT_CORPSE && !IS_ITEM_GUID(guid) ) + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); +} + +void Player::SendNotifyLootMoneyRemoved() +{ + WorldPacket data(SMSG_LOOT_CLEAR_MONEY, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SendNotifyLootItemRemoved(uint8 lootSlot) +{ + WorldPacket data(SMSG_LOOT_REMOVED, 1); + data << uint8(lootSlot); + GetSession()->SendPacket( &data ); +} + +void Player::SendUpdateWorldState(uint32 Field, uint32 Value) +{ + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8); + data << Field; + data << Value; + GetSession()->SendPacket(&data); +} + +void Player::SendInitWorldStates() +{ + // data depends on zoneid/mapid... + BattleGround* bg = GetBattleGround(); + uint16 NumberOfFields = 0; + uint32 mapid = GetMapId(); + uint32 zoneid = GetZoneId(); + uint32 areaid = GetAreaId(); + sLog.outDebug("Sending SMSG_INIT_WORLD_STATES to Map:%u, Zone: %u", mapid, zoneid); + // may be exist better way to do this... + switch(zoneid) + { + case 0: + case 1: + case 4: + case 8: + case 10: + case 11: + case 12: + case 36: + case 38: + case 40: + case 41: + case 51: + case 267: + case 1519: + case 1537: + case 2257: + case 2918: + NumberOfFields = 6; + break; + case 2597: + NumberOfFields = 81; + break; + case 3277: + NumberOfFields = 14; + break; + case 3358: + case 3820: + NumberOfFields = 38; + break; + case 3483: + NumberOfFields = 22; + break; + case 3519: + NumberOfFields = 36; + break; + case 3521: + NumberOfFields = 35; + break; + case 3698: + case 3702: + case 3968: + NumberOfFields = 9; + break; + case 3703: + NumberOfFields = 9; + break; + default: + NumberOfFields = 10; + break; + } + + WorldPacket data(SMSG_INIT_WORLD_STATES, (4+4+4+2+(NumberOfFields*8))); + data << uint32(mapid); // mapid + data << uint32(zoneid); // zone id + data << uint32(areaid); // area id, new 2.1.0 + data << uint16(NumberOfFields); // count of uint64 blocks + data << uint32(0x8d8) << uint32(0x0); // 1 + data << uint32(0x8d7) << uint32(0x0); // 2 + data << uint32(0x8d6) << uint32(0x0); // 3 + data << uint32(0x8d5) << uint32(0x0); // 4 + data << uint32(0x8d4) << uint32(0x0); // 5 + data << uint32(0x8d3) << uint32(0x0); // 6 + if(mapid == 530) // Outland + { + data << uint32(0x9bf) << uint32(0x0); // 7 + data << uint32(0x9bd) << uint32(0xF); // 8 + data << uint32(0x9bb) << uint32(0xF); // 9 + } + switch(zoneid) + { + case 1: + case 11: + case 12: + case 38: + case 40: + case 51: + case 1519: + case 1537: + case 2257: + break; + case 2597: // AV + data << uint32(0x7ae) << uint32(0x1); // 7 + data << uint32(0x532) << uint32(0x1); // 8 + data << uint32(0x531) << uint32(0x0); // 9 + data << uint32(0x52e) << uint32(0x0); // 10 + data << uint32(0x571) << uint32(0x0); // 11 + data << uint32(0x570) << uint32(0x0); // 12 + data << uint32(0x567) << uint32(0x1); // 13 + data << uint32(0x566) << uint32(0x1); // 14 + data << uint32(0x550) << uint32(0x1); // 15 + data << uint32(0x544) << uint32(0x0); // 16 + data << uint32(0x536) << uint32(0x0); // 17 + data << uint32(0x535) << uint32(0x1); // 18 + data << uint32(0x518) << uint32(0x0); // 19 + data << uint32(0x517) << uint32(0x0); // 20 + data << uint32(0x574) << uint32(0x0); // 21 + data << uint32(0x573) << uint32(0x0); // 22 + data << uint32(0x572) << uint32(0x0); // 23 + data << uint32(0x56f) << uint32(0x0); // 24 + data << uint32(0x56e) << uint32(0x0); // 25 + data << uint32(0x56d) << uint32(0x0); // 26 + data << uint32(0x56c) << uint32(0x0); // 27 + data << uint32(0x56b) << uint32(0x0); // 28 + data << uint32(0x56a) << uint32(0x1); // 29 + data << uint32(0x569) << uint32(0x1); // 30 + data << uint32(0x568) << uint32(0x1); // 13 + data << uint32(0x565) << uint32(0x0); // 32 + data << uint32(0x564) << uint32(0x0); // 33 + data << uint32(0x563) << uint32(0x0); // 34 + data << uint32(0x562) << uint32(0x0); // 35 + data << uint32(0x561) << uint32(0x0); // 36 + data << uint32(0x560) << uint32(0x0); // 37 + data << uint32(0x55f) << uint32(0x0); // 38 + data << uint32(0x55e) << uint32(0x0); // 39 + data << uint32(0x55d) << uint32(0x0); // 40 + data << uint32(0x3c6) << uint32(0x4); // 41 + data << uint32(0x3c4) << uint32(0x6); // 42 + data << uint32(0x3c2) << uint32(0x4); // 43 + data << uint32(0x516) << uint32(0x1); // 44 + data << uint32(0x515) << uint32(0x0); // 45 + data << uint32(0x3b6) << uint32(0x6); // 46 + data << uint32(0x55c) << uint32(0x0); // 47 + data << uint32(0x55b) << uint32(0x0); // 48 + data << uint32(0x55a) << uint32(0x0); // 49 + data << uint32(0x559) << uint32(0x0); // 50 + data << uint32(0x558) << uint32(0x0); // 51 + data << uint32(0x557) << uint32(0x0); // 52 + data << uint32(0x556) << uint32(0x0); // 53 + data << uint32(0x555) << uint32(0x0); // 54 + data << uint32(0x554) << uint32(0x1); // 55 + data << uint32(0x553) << uint32(0x1); // 56 + data << uint32(0x552) << uint32(0x1); // 57 + data << uint32(0x551) << uint32(0x1); // 58 + data << uint32(0x54f) << uint32(0x0); // 59 + data << uint32(0x54e) << uint32(0x0); // 60 + data << uint32(0x54d) << uint32(0x1); // 61 + data << uint32(0x54c) << uint32(0x0); // 62 + data << uint32(0x54b) << uint32(0x0); // 63 + data << uint32(0x545) << uint32(0x0); // 64 + data << uint32(0x543) << uint32(0x1); // 65 + data << uint32(0x542) << uint32(0x0); // 66 + data << uint32(0x540) << uint32(0x0); // 67 + data << uint32(0x53f) << uint32(0x0); // 68 + data << uint32(0x53e) << uint32(0x0); // 69 + data << uint32(0x53d) << uint32(0x0); // 70 + data << uint32(0x53c) << uint32(0x0); // 71 + data << uint32(0x53b) << uint32(0x0); // 72 + data << uint32(0x53a) << uint32(0x1); // 73 + data << uint32(0x539) << uint32(0x0); // 74 + data << uint32(0x538) << uint32(0x0); // 75 + data << uint32(0x537) << uint32(0x0); // 76 + data << uint32(0x534) << uint32(0x0); // 77 + data << uint32(0x533) << uint32(0x0); // 78 + data << uint32(0x530) << uint32(0x0); // 79 + data << uint32(0x52f) << uint32(0x0); // 80 + data << uint32(0x52d) << uint32(0x1); // 81 + break; + case 3277: // WS + if (bg && bg->GetTypeID() == BATTLEGROUND_WS) + bg->FillInitialWorldStates(data); + else + { + data << uint32(0x62d) << uint32(0x0); // 7 1581 alliance flag captures + data << uint32(0x62e) << uint32(0x0); // 8 1582 horde flag captures + data << uint32(0x609) << uint32(0x0); // 9 1545 unk, set to 1 on alliance flag pickup... + data << uint32(0x60a) << uint32(0x0); // 10 1546 unk, set to 1 on horde flag pickup, after drop it's -1 + data << uint32(0x60b) << uint32(0x2); // 11 1547 unk + data << uint32(0x641) << uint32(0x3); // 12 1601 unk (max flag captures?) + data << uint32(0x922) << uint32(0x1); // 13 2338 horde (0 - hide, 1 - flag ok, 2 - flag picked up (flashing), 3 - flag picked up (not flashing) + data << uint32(0x923) << uint32(0x1); // 14 2339 alliance (0 - hide, 1 - flag ok, 2 - flag picked up (flashing), 3 - flag picked up (not flashing) + } + break; + case 3358: // AB + if (bg && bg->GetTypeID() == BATTLEGROUND_AB) + bg->FillInitialWorldStates(data); + else + { + data << uint32(0x6e7) << uint32(0x0); // 7 1767 stables alliance + data << uint32(0x6e8) << uint32(0x0); // 8 1768 stables horde + data << uint32(0x6e9) << uint32(0x0); // 9 1769 unk, ST? + data << uint32(0x6ea) << uint32(0x0); // 10 1770 stables (show/hide) + data << uint32(0x6ec) << uint32(0x0); // 11 1772 farm (0 - horde controlled, 1 - alliance controlled) + data << uint32(0x6ed) << uint32(0x0); // 12 1773 farm (show/hide) + data << uint32(0x6ee) << uint32(0x0); // 13 1774 farm color + data << uint32(0x6ef) << uint32(0x0); // 14 1775 gold mine color, may be FM? + data << uint32(0x6f0) << uint32(0x0); // 15 1776 alliance resources + data << uint32(0x6f1) << uint32(0x0); // 16 1777 horde resources + data << uint32(0x6f2) << uint32(0x0); // 17 1778 horde bases + data << uint32(0x6f3) << uint32(0x0); // 18 1779 alliance bases + data << uint32(0x6f4) << uint32(0x7d0); // 19 1780 max resources (2000) + data << uint32(0x6f6) << uint32(0x0); // 20 1782 blacksmith color + data << uint32(0x6f7) << uint32(0x0); // 21 1783 blacksmith (show/hide) + data << uint32(0x6f8) << uint32(0x0); // 22 1784 unk, bs? + data << uint32(0x6f9) << uint32(0x0); // 23 1785 unk, bs? + data << uint32(0x6fb) << uint32(0x0); // 24 1787 gold mine (0 - horde contr, 1 - alliance contr) + data << uint32(0x6fc) << uint32(0x0); // 25 1788 gold mine (0 - conflict, 1 - horde) + data << uint32(0x6fd) << uint32(0x0); // 26 1789 gold mine (1 - show/0 - hide) + data << uint32(0x6fe) << uint32(0x0); // 27 1790 gold mine color + data << uint32(0x700) << uint32(0x0); // 28 1792 gold mine color, wtf?, may be LM? + data << uint32(0x701) << uint32(0x0); // 29 1793 lumber mill color (0 - conflict, 1 - horde contr) + data << uint32(0x702) << uint32(0x0); // 30 1794 lumber mill (show/hide) + data << uint32(0x703) << uint32(0x0); // 31 1795 lumber mill color color + data << uint32(0x732) << uint32(0x1); // 32 1842 stables (1 - uncontrolled) + data << uint32(0x733) << uint32(0x1); // 33 1843 gold mine (1 - uncontrolled) + data << uint32(0x734) << uint32(0x1); // 34 1844 lumber mill (1 - uncontrolled) + data << uint32(0x735) << uint32(0x1); // 35 1845 farm (1 - uncontrolled) + data << uint32(0x736) << uint32(0x1); // 36 1846 blacksmith (1 - uncontrolled) + data << uint32(0x745) << uint32(0x2); // 37 1861 unk + data << uint32(0x7a3) << uint32(0x708); // 38 1955 warning limit (1800) + } + break; + case 3820: // EY + if (bg && bg->GetTypeID() == BATTLEGROUND_EY) + bg->FillInitialWorldStates(data); + else + { + data << uint32(0xac1) << uint32(0x0); // 7 2753 Horde Bases + data << uint32(0xac0) << uint32(0x0); // 8 2752 Alliance Bases + data << uint32(0xab6) << uint32(0x0); // 9 2742 Mage Tower - Horde conflict + data << uint32(0xab5) << uint32(0x0); // 10 2741 Mage Tower - Alliance conflict + data << uint32(0xab4) << uint32(0x0); // 11 2740 Fel Reaver - Horde conflict + data << uint32(0xab3) << uint32(0x0); // 12 2739 Fel Reaver - Alliance conflict + data << uint32(0xab2) << uint32(0x0); // 13 2738 Draenei - Alliance conflict + data << uint32(0xab1) << uint32(0x0); // 14 2737 Draenei - Horde conflict + data << uint32(0xab0) << uint32(0x0); // 15 2736 unk // 0 at start + data << uint32(0xaaf) << uint32(0x0); // 16 2735 unk // 0 at start + data << uint32(0xaad) << uint32(0x0); // 17 2733 Draenei - Horde control + data << uint32(0xaac) << uint32(0x0); // 18 2732 Draenei - Alliance control + data << uint32(0xaab) << uint32(0x1); // 19 2731 Draenei uncontrolled (1 - yes, 0 - no) + data << uint32(0xaaa) << uint32(0x0); // 20 2730 Mage Tower - Alliance control + data << uint32(0xaa9) << uint32(0x0); // 21 2729 Mage Tower - Horde control + data << uint32(0xaa8) << uint32(0x1); // 22 2728 Mage Tower uncontrolled (1 - yes, 0 - no) + data << uint32(0xaa7) << uint32(0x0); // 23 2727 Fel Reaver - Horde control + data << uint32(0xaa6) << uint32(0x0); // 24 2726 Fel Reaver - Alliance control + data << uint32(0xaa5) << uint32(0x1); // 25 2725 Fel Reaver uncontroled (1 - yes, 0 - no) + data << uint32(0xaa4) << uint32(0x0); // 26 2724 Boold Elf - Horde control + data << uint32(0xaa3) << uint32(0x0); // 27 2723 Boold Elf - Alliance control + data << uint32(0xaa2) << uint32(0x1); // 28 2722 Boold Elf uncontrolled (1 - yes, 0 - no) + data << uint32(0xac5) << uint32(0x1); // 29 2757 Flag (1 - show, 0 - hide) - doesn't work exactly this way! + data << uint32(0xad2) << uint32(0x1); // 30 2770 Horde top-stats (1 - show, 0 - hide) // 02 -> horde picked up the flag + data << uint32(0xad1) << uint32(0x1); // 31 2769 Alliance top-stats (1 - show, 0 - hide) // 02 -> alliance picked up the flag + data << uint32(0xabe) << uint32(0x0); // 32 2750 Horde resources + data << uint32(0xabd) << uint32(0x0); // 33 2749 Alliance resources + data << uint32(0xa05) << uint32(0x8e); // 34 2565 unk, constant? + data << uint32(0xaa0) << uint32(0x0); // 35 2720 Capturing progress-bar (100 -> empty (only grey), 0 -> blue|red (no grey), default 0) + data << uint32(0xa9f) << uint32(0x0); // 36 2719 Capturing progress-bar (0 - left, 100 - right) + data << uint32(0xa9e) << uint32(0x0); // 37 2718 Capturing progress-bar (1 - show, 0 - hide) + data << uint32(0xc0d) << uint32(0x17b); // 38 3085 unk + // and some more ... unknown + } + break; + case 3483: // Hellfire Peninsula + data << uint32(0x9ba) << uint32(0x1); // 10 + data << uint32(0x9b9) << uint32(0x1); // 11 + data << uint32(0x9b5) << uint32(0x0); // 12 + data << uint32(0x9b4) << uint32(0x1); // 13 + data << uint32(0x9b3) << uint32(0x0); // 14 + data << uint32(0x9b2) << uint32(0x0); // 15 + data << uint32(0x9b1) << uint32(0x1); // 16 + data << uint32(0x9b0) << uint32(0x0); // 17 + data << uint32(0x9ae) << uint32(0x0); // 18 horde pvp objectives captured + data << uint32(0x9ac) << uint32(0x0); // 19 + data << uint32(0x9a8) << uint32(0x0); // 20 + data << uint32(0x9a7) << uint32(0x0); // 21 + data << uint32(0x9a6) << uint32(0x1); // 22 + break; + case 3519: // Terokkar Forest + data << uint32(0xa41) << uint32(0x0); // 10 + data << uint32(0xa40) << uint32(0x14); // 11 + data << uint32(0xa3f) << uint32(0x0); // 12 + data << uint32(0xa3e) << uint32(0x0); // 13 + data << uint32(0xa3d) << uint32(0x5); // 14 + data << uint32(0xa3c) << uint32(0x0); // 15 + data << uint32(0xa87) << uint32(0x0); // 16 + data << uint32(0xa86) << uint32(0x0); // 17 + data << uint32(0xa85) << uint32(0x0); // 18 + data << uint32(0xa84) << uint32(0x0); // 19 + data << uint32(0xa83) << uint32(0x0); // 20 + data << uint32(0xa82) << uint32(0x0); // 21 + data << uint32(0xa81) << uint32(0x0); // 22 + data << uint32(0xa80) << uint32(0x0); // 23 + data << uint32(0xa7e) << uint32(0x0); // 24 + data << uint32(0xa7d) << uint32(0x0); // 25 + data << uint32(0xa7c) << uint32(0x0); // 26 + data << uint32(0xa7b) << uint32(0x0); // 27 + data << uint32(0xa7a) << uint32(0x0); // 28 + data << uint32(0xa79) << uint32(0x0); // 29 + data << uint32(0x9d0) << uint32(0x5); // 30 + data << uint32(0x9ce) << uint32(0x0); // 31 + data << uint32(0x9cd) << uint32(0x0); // 32 + data << uint32(0x9cc) << uint32(0x0); // 33 + data << uint32(0xa88) << uint32(0x0); // 34 + data << uint32(0xad0) << uint32(0x0); // 35 + data << uint32(0xacf) << uint32(0x1); // 36 + break; + case 3521: // Zangarmarsh + data << uint32(0x9e1) << uint32(0x0); // 10 + data << uint32(0x9e0) << uint32(0x0); // 11 + data << uint32(0x9df) << uint32(0x0); // 12 + data << uint32(0xa5d) << uint32(0x1); // 13 + data << uint32(0xa5c) << uint32(0x0); // 14 + data << uint32(0xa5b) << uint32(0x1); // 15 + data << uint32(0xa5a) << uint32(0x0); // 16 + data << uint32(0xa59) << uint32(0x1); // 17 + data << uint32(0xa58) << uint32(0x0); // 18 + data << uint32(0xa57) << uint32(0x0); // 19 + data << uint32(0xa56) << uint32(0x0); // 20 + data << uint32(0xa55) << uint32(0x1); // 21 + data << uint32(0xa54) << uint32(0x0); // 22 + data << uint32(0x9e7) << uint32(0x0); // 23 + data << uint32(0x9e6) << uint32(0x0); // 24 + data << uint32(0x9e5) << uint32(0x0); // 25 + data << uint32(0xa00) << uint32(0x0); // 26 + data << uint32(0x9ff) << uint32(0x1); // 27 + data << uint32(0x9fe) << uint32(0x0); // 28 + data << uint32(0x9fd) << uint32(0x0); // 29 + data << uint32(0x9fc) << uint32(0x1); // 30 + data << uint32(0x9fb) << uint32(0x0); // 31 + data << uint32(0xa62) << uint32(0x0); // 32 + data << uint32(0xa61) << uint32(0x1); // 33 + data << uint32(0xa60) << uint32(0x1); // 34 + data << uint32(0xa5f) << uint32(0x0); // 35 + break; + case 3698: // Nagrand Arena + data << uint32(0xa0f) << uint32(0x0); // 7 + data << uint32(0xa10) << uint32(0x0); // 8 + data << uint32(0xa11) << uint32(0x0); // 9 + break; + case 3702: // Blade's Edge Arena + data << uint32(0x9f0) << uint32(0x0); // 7 + data << uint32(0x9f1) << uint32(0x0); // 8 + data << uint32(0x9f3) << uint32(0x0); // 9 + break; + case 3968: // Ruins of Lordaeron + data << uint32(0xbb8) << uint32(0x0); // 7 + data << uint32(0xbb9) << uint32(0x0); // 8 + data << uint32(0xbba) << uint32(0x0); // 9 + break; + case 3703: // Shattrath City + break; + default: + data << uint32(0x914) << uint32(0x0); // 7 + data << uint32(0x913) << uint32(0x0); // 8 + data << uint32(0x912) << uint32(0x0); // 9 + data << uint32(0x915) << uint32(0x0); // 10 + break; + } + GetSession()->SendPacket(&data); +} + +uint32 Player::GetXPRestBonus(uint32 xp) +{ + uint32 rested_bonus = (uint32)GetRestBonus(); // xp for each rested bonus + + if(rested_bonus > xp) // max rested_bonus == xp or (r+x) = 200% xp + rested_bonus = xp; + + SetRestBonus( GetRestBonus() - rested_bonus); + + sLog.outDetail("Player gain %u xp (+ %u Rested Bonus). Rested points=%f",xp+rested_bonus,rested_bonus,GetRestBonus()); + return rested_bonus; +} + +void Player::SetBindPoint(uint64 guid) +{ + WorldPacket data(SMSG_BINDER_CONFIRM, 8); + data << uint64(guid); + GetSession()->SendPacket( &data ); +} + +void Player::SendTalentWipeConfirm(uint64 guid) +{ + WorldPacket data(MSG_TALENT_WIPE_CONFIRM, (8+4)); + data << uint64(guid); + data << uint32(resetTalentsCost()); + GetSession()->SendPacket( &data ); +} + +void Player::SendPetSkillWipeConfirm() +{ + Pet* pet = GetPet(); + if(!pet) + return; + WorldPacket data(SMSG_PET_UNLEARN_CONFIRM, (8+4)); + data << pet->GetGUID(); + data << uint32(pet->resetTalentsCost()); + GetSession()->SendPacket( &data ); +} + +/*********************************************************/ +/*** STORAGE SYSTEM ***/ +/*********************************************************/ + +void Player::SetVirtualItemSlot( uint8 i, Item* item) +{ + assert(i < 3); + if(i < 2 && item) + { + if(!item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) + return; + uint32 charges = item->GetEnchantmentCharges(TEMP_ENCHANTMENT_SLOT); + if(charges == 0) + return; + if(charges > 1) + item->SetEnchantmentCharges(TEMP_ENCHANTMENT_SLOT,charges-1); + else if(charges <= 1) + { + ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false); + item->ClearEnchantment(TEMP_ENCHANTMENT_SLOT); + } + } +} + +void Player::SetSheath( uint32 sheathed ) +{ + switch (sheathed) + { + case SHEATH_STATE_UNARMED: // no prepared weapon + SetVirtualItemSlot(0,NULL); + SetVirtualItemSlot(1,NULL); + SetVirtualItemSlot(2,NULL); + break; + case SHEATH_STATE_MELEE: // prepared melee weapon + { + SetVirtualItemSlot(0,GetWeaponForAttack(BASE_ATTACK,true)); + SetVirtualItemSlot(1,GetWeaponForAttack(OFF_ATTACK,true)); + SetVirtualItemSlot(2,NULL); + }; break; + case SHEATH_STATE_RANGED: // prepared ranged weapon + SetVirtualItemSlot(0,NULL); + SetVirtualItemSlot(1,NULL); + SetVirtualItemSlot(2,GetWeaponForAttack(RANGED_ATTACK,true)); + break; + default: + SetVirtualItemSlot(0,NULL); + SetVirtualItemSlot(1,NULL); + SetVirtualItemSlot(2,NULL); + break; + } + SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); // this must visualize Sheath changing for other players... +} + +uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const +{ + uint8 pClass = getClass(); + + uint8 slots[4]; + slots[0] = NULL_SLOT; + slots[1] = NULL_SLOT; + slots[2] = NULL_SLOT; + slots[3] = NULL_SLOT; + switch( proto->InventoryType ) + { + case INVTYPE_HEAD: + slots[0] = EQUIPMENT_SLOT_HEAD; + break; + case INVTYPE_NECK: + slots[0] = EQUIPMENT_SLOT_NECK; + break; + case INVTYPE_SHOULDERS: + slots[0] = EQUIPMENT_SLOT_SHOULDERS; + break; + case INVTYPE_BODY: + slots[0] = EQUIPMENT_SLOT_BODY; + break; + case INVTYPE_CHEST: + slots[0] = EQUIPMENT_SLOT_CHEST; + break; + case INVTYPE_ROBE: + slots[0] = EQUIPMENT_SLOT_CHEST; + break; + case INVTYPE_WAIST: + slots[0] = EQUIPMENT_SLOT_WAIST; + break; + case INVTYPE_LEGS: + slots[0] = EQUIPMENT_SLOT_LEGS; + break; + case INVTYPE_FEET: + slots[0] = EQUIPMENT_SLOT_FEET; + break; + case INVTYPE_WRISTS: + slots[0] = EQUIPMENT_SLOT_WRISTS; + break; + case INVTYPE_HANDS: + slots[0] = EQUIPMENT_SLOT_HANDS; + break; + case INVTYPE_FINGER: + slots[0] = EQUIPMENT_SLOT_FINGER1; + slots[1] = EQUIPMENT_SLOT_FINGER2; + break; + case INVTYPE_TRINKET: + slots[0] = EQUIPMENT_SLOT_TRINKET1; + slots[1] = EQUIPMENT_SLOT_TRINKET2; + break; + case INVTYPE_CLOAK: + slots[0] = EQUIPMENT_SLOT_BACK; + break; + case INVTYPE_WEAPON: + { + slots[0] = EQUIPMENT_SLOT_MAINHAND; + + // suggest offhand slot only if know dual wielding + // (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ... + if(CanDualWield()) + slots[1] = EQUIPMENT_SLOT_OFFHAND; + };break; + case INVTYPE_SHIELD: + slots[0] = EQUIPMENT_SLOT_OFFHAND; + break; + case INVTYPE_RANGED: + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case INVTYPE_2HWEAPON: + slots[0] = EQUIPMENT_SLOT_MAINHAND; + break; + case INVTYPE_TABARD: + slots[0] = EQUIPMENT_SLOT_TABARD; + break; + case INVTYPE_WEAPONMAINHAND: + slots[0] = EQUIPMENT_SLOT_MAINHAND; + break; + case INVTYPE_WEAPONOFFHAND: + slots[0] = EQUIPMENT_SLOT_OFFHAND; + break; + case INVTYPE_HOLDABLE: + slots[0] = EQUIPMENT_SLOT_OFFHAND; + break; + case INVTYPE_THROWN: + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case INVTYPE_RANGEDRIGHT: + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case INVTYPE_BAG: + slots[0] = INVENTORY_SLOT_BAG_1; + slots[1] = INVENTORY_SLOT_BAG_2; + slots[2] = INVENTORY_SLOT_BAG_3; + slots[3] = INVENTORY_SLOT_BAG_4; + break; + case INVTYPE_RELIC: + { + switch(proto->SubClass) + { + case ITEM_SUBCLASS_ARMOR_LIBRAM: + if (pClass == CLASS_PALADIN) + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case ITEM_SUBCLASS_ARMOR_IDOL: + if (pClass == CLASS_DRUID) + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case ITEM_SUBCLASS_ARMOR_TOTEM: + if (pClass == CLASS_SHAMAN) + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case ITEM_SUBCLASS_ARMOR_MISC: + if (pClass == CLASS_WARLOCK) + slots[0] = EQUIPMENT_SLOT_RANGED; + break; + } + break; + } + default : + return NULL_SLOT; + } + + if( slot != NULL_SLOT ) + { + if( swap || !GetItemByPos( INVENTORY_SLOT_BAG_0, slot ) ) + { + for (int i = 0; i < 4; i++) + { + if ( slots[i] == slot ) + return slot; + } + } + } + else + { + // search free slot at first + for (int i = 0; i < 4; i++) + { + if ( slots[i] != NULL_SLOT && !GetItemByPos( INVENTORY_SLOT_BAG_0, slots[i] ) ) + { + // in case 2hand equipped weapon offhand slot empty but not free + if(slots[i]==EQUIPMENT_SLOT_OFFHAND) + { + Item* mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) + return slots[i]; + } + else + return slots[i]; + } + } + + // if not found free and can swap return first appropriate from used + for (int i = 0; i < 4; i++) + { + if ( slots[i] != NULL_SLOT && swap ) + return slots[i]; + } + } + + // no free position + return NULL_SLOT; +} + +uint8 Player::CanUnequipItems( uint32 item, uint32 count ) const +{ + Item *pItem; + uint32 tempcount = 0; + + uint8 res = EQUIP_ERR_OK; + + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + uint8 ires = CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i, false); + if(ires==EQUIP_ERR_OK) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return EQUIP_ERR_OK; + } + else + res = ires; + } + } + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return EQUIP_ERR_OK; + } + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return EQUIP_ERR_OK; + } + } + Bag *pBag; + ItemPrototype const *pBagProto; + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + pItem = GetItemByPos( i, j ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return EQUIP_ERR_OK; + } + } + } + } + } + + // not found req. item count and have unequippable items + return res; +} + +uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) const +{ + uint32 count = 0; + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem != skipItem && pItem->GetEntry() == item ) + count += pItem->GetCount(); + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem != skipItem && pItem->GetEntry() == item ) + count += pItem->GetCount(); + } + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + count += pBag->GetItemCount(item,skipItem); + } + + if(skipItem && skipItem->GetProto()->GemProperties) + { + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem != skipItem && pItem->GetProto()->Socket[0].Color ) + count += pItem->GetGemCountWithID(item); + } + } + + if(inBankAlso) + { + for(int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem != skipItem && pItem->GetEntry() == item ) + count += pItem->GetCount(); + } + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + count += pBag->GetItemCount(item,skipItem); + } + + if(skipItem && skipItem->GetProto()->GemProperties) + { + for(int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem != skipItem && pItem->GetProto()->Socket[0].Color ) + count += pItem->GetGemCountWithID(item); + } + } + } + + return count; +} + +Item* Player::GetItemByGuid( uint64 guid ) const +{ + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetGUID() == guid ) + return pItem; + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetGUID() == guid ) + return pItem; + } + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + ItemPrototype const *pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = pBag->GetItemByPos( j ); + if( pItem && pItem->GetGUID() == guid ) + return pItem; + } + } + } + } + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + ItemPrototype const *pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = pBag->GetItemByPos( j ); + if( pItem && pItem->GetGUID() == guid ) + return pItem; + } + } + } + } + + return NULL; +} + +Item* Player::GetItemByPos( uint16 pos ) const +{ + uint8 bag = pos >> 8; + uint8 slot = pos & 255; + return GetItemByPos( bag, slot ); +} + +Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const +{ + if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) + return m_items[slot]; + else if(bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END + || bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END ) + { + Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); + if ( pBag ) + return pBag->GetItemByPos(slot); + } + return NULL; +} + +Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) const +{ + uint16 slot; + switch (attackType) + { + case BASE_ATTACK: slot = EQUIPMENT_SLOT_MAINHAND; break; + case OFF_ATTACK: slot = EQUIPMENT_SLOT_OFFHAND; break; + case RANGED_ATTACK: slot = EQUIPMENT_SLOT_RANGED; break; + default: return NULL; + } + + Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON) + return NULL; + + if(!useable) + return item; + + if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) ) + return NULL; + + return item; +} + +Item* Player::GetShield(bool useable) const +{ + Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + if (!item || item->GetProto()->Class != ITEM_CLASS_ARMOR) + return NULL; + + if(!useable) + return item; + + if( item->IsBroken()) + return NULL; + + return item; +} + +uint32 Player::GetAttackBySlot( uint8 slot ) +{ + switch(slot) + { + case EQUIPMENT_SLOT_MAINHAND: return BASE_ATTACK; + case EQUIPMENT_SLOT_OFFHAND: return OFF_ATTACK; + case EQUIPMENT_SLOT_RANGED: return RANGED_ATTACK; + default: return MAX_ATTACK; + } +} + +bool Player::HasBankBagSlot( uint8 slot ) const +{ + uint32 maxslot = GetByteValue(PLAYER_BYTES_2, 2) + BANK_SLOT_BAG_START; + if( slot < maxslot ) + return true; + return false; +} + +bool Player::IsInventoryPos( uint8 bag, uint8 slot ) +{ + if( bag == INVENTORY_SLOT_BAG_0 && slot == NULL_SLOT ) + return true; + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_END ) ) + return true; + if( bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END ) + return true; + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) + return true; + return false; +} + +bool Player::IsEquipmentPos( uint8 bag, uint8 slot ) +{ + if( bag == INVENTORY_SLOT_BAG_0 && ( slot < EQUIPMENT_SLOT_END ) ) + return true; + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END ) ) + return true; + return false; +} + +bool Player::IsBankPos( uint8 bag, uint8 slot ) +{ + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= BANK_SLOT_ITEM_START && slot < BANK_SLOT_ITEM_END ) ) + return true; + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END ) ) + return true; + if( bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END ) + return true; + return false; +} + +bool Player::IsBagPos( uint16 pos ) +{ + uint8 bag = pos >> 8; + uint8 slot = pos & 255; + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END ) ) + return true; + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END ) ) + return true; + return false; +} + +bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const +{ + uint32 tempcount = 0; + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return true; + } + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return true; + } + } + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + { + if(ItemPrototype const *pBagProto = pBag->GetProto()) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = GetItemByPos( i, j ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return true; + } + } + } + } + } + + if(inBankAlso) + { + for(int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; i++) + { + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return true; + } + } + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + { + if(ItemPrototype const *pBagProto = pBag->GetProto()) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = GetItemByPos( i, j ); + if( pItem && pItem->GetEntry() == item ) + { + tempcount += pItem->GetCount(); + if( tempcount >= count ) + return true; + } + } + } + } + } + } + + return false; +} + +Item* Player::GetItemOrItemWithGemEquipped( uint32 item ) const +{ + Item *pItem; + for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + return pItem; + } + + ItemPrototype const *pProto = objmgr.GetItemPrototype(item); + if (pProto && pProto->GemProperties) + { + for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetProto()->Socket[0].Color ) + { + if (pItem->GetGemCountWithID(item) > 0 ) + return pItem; + } + } + } + + return NULL; +} + +uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count ) const +{ + ItemPrototype const *pProto = objmgr.GetItemPrototype(entry); + if( !pProto ) + { + if(no_space_count) + *no_space_count = count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + + // no maximum + if(pProto->MaxCount == 0) + return EQUIP_ERR_OK; + + uint32 curcount = GetItemCount(pProto->ItemId,true,pItem); + + if( curcount + count > pProto->MaxCount ) + { + if(no_space_count) + *no_space_count = count +curcount - pProto->MaxCount; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + + return EQUIP_ERR_OK; +} + +bool Player::HasItemTotemCategory( uint32 TotemCategory ) const +{ + Item *pItem; + for(uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) + return true; + } + for(uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) + return true; + } + Bag *pBag; + ItemPrototype const *pBagProto; + for(uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + { + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; ++j) + { + pItem = GetItemByPos( i, j ); + if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) + return true; + } + } + } + } + return false; +} + +uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec &dest, ItemPrototype const *pProto, uint32& count, bool swap, Item* pSrcItem ) const +{ + Item* pItem2 = GetItemByPos( bag, slot ); + + // ignore move item (this slot will be empty at move) + if(pItem2==pSrcItem) + pItem2 = NULL; + + uint32 need_space; + + // empty specific slot - check item fit to slot + if( !pItem2 || swap ) + { + if( bag == INVENTORY_SLOT_BAG_0 ) + { + // keyring case + if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS)) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + // prevent cheating + if(slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + } + else + { + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); + if( !pBag ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + ItemPrototype const* pBagProto = pBag->GetProto(); + if( !pBagProto ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + if( !ItemCanGoIntoBag(pProto,pBagProto) ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + } + + // non empty stack with space + need_space = pProto->Stackable; + } + // non empty slot, check item type + else + { + // check item type + if(pItem2->GetEntry() != pProto->ItemId) + return EQUIP_ERR_ITEM_CANT_STACK; + + // check free space + if(pItem2->GetCount() >= pProto->Stackable) + return EQUIP_ERR_ITEM_CANT_STACK; + + need_space = pProto->Stackable - pItem2->GetCount(); + } + + if(need_space > count) + need_space = count; + + ItemPosCount newPosition = ItemPosCount((bag << 8) | slot, need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + } + return EQUIP_ERR_OK; +} + +uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototype const *pProto, uint32& count, bool merge, bool non_specialized, Item* pSrcItem, uint8 skip_bag, uint8 skip_slot ) const +{ + // skip specific bag already processed in first called _CanStoreItem_InBag + if(bag==skip_bag) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); + if( !pBag ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + ItemPrototype const* pBagProto = pBag->GetProto(); + if( !pBagProto ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + // specialized bag mode or non-specilized + if( non_specialized != (pBagProto->Class == ITEM_CLASS_CONTAINER && pBagProto->SubClass == ITEM_SUBCLASS_CONTAINER) ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + if( !ItemCanGoIntoBag(pProto,pBagProto) ) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + // skip specific slot already processed in first called _CanStoreItem_InSpecificSlot + if(j==skip_slot) + continue; + + Item* pItem2 = GetItemByPos( bag, j ); + + // ignore move item (this slot will be empty at move) + if(pItem2==pSrcItem) + pItem2 = NULL; + + // if merge skip empty, if !merge skip non-empty + if((pItem2!=NULL)!=merge) + continue; + + if( pItem2 ) + { + if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->Stackable ) + { + uint32 need_space = pProto->Stackable - pItem2->GetCount(); + if(need_space > count) + need_space = count; + + ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + + if(count==0) + return EQUIP_ERR_OK; + } + } + } + else + { + uint32 need_space = pProto->Stackable; + if(need_space > count) + need_space = count; + + ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + + if(count==0) + return EQUIP_ERR_OK; + } + } + } + return EQUIP_ERR_OK; +} + +uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end, ItemPosCountVec &dest, ItemPrototype const *pProto, uint32& count, bool merge, Item* pSrcItem, uint8 skip_bag, uint8 skip_slot ) const +{ + for(uint32 j = slot_begin; j < slot_end; j++) + { + // skip specific slot already processed in first called _CanStoreItem_InSpecificSlot + if(INVENTORY_SLOT_BAG_0==skip_bag && j==skip_slot) + continue; + + Item* pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, j ); + + // ignore move item (this slot will be empty at move) + if(pItem2==pSrcItem) + pItem2 = NULL; + + // if merge skip empty, if !merge skip non-empty + if((pItem2!=NULL)!=merge) + continue; + + if( pItem2 ) + { + if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->Stackable ) + { + uint32 need_space = pProto->Stackable - pItem2->GetCount(); + if(need_space > count) + need_space = count; + ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + + if(count==0) + return EQUIP_ERR_OK; + } + } + } + else + { + uint32 need_space = pProto->Stackable; + if(need_space > count) + need_space = count; + + ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space); + if(!newPosition.isContainedIn(dest)) + { + dest.push_back(newPosition); + count -= need_space; + + if(count==0) + return EQUIP_ERR_OK; + } + } + } + return EQUIP_ERR_OK; +} + +uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 entry, uint32 count, Item *pItem, bool swap, uint32* no_space_count ) const +{ + sLog.outDebug( "STORAGE: CanStoreItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, entry, count); + + ItemPrototype const *pProto = objmgr.GetItemPrototype(entry); + if( !pProto ) + { + if(no_space_count) + *no_space_count = count; + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED :EQUIP_ERR_ITEM_NOT_FOUND; + } + + if(pItem && pItem->IsBindedNotWith(GetGUID())) + { + if(no_space_count) + *no_space_count = count; + return EQUIP_ERR_DONT_OWN_THAT_ITEM; + } + + // check count of items (skip for auto move for same player from bank) + uint32 no_similar_count = 0; // can't store this amount similar items + uint8 res = _CanTakeMoreSimilarItems(entry,count,pItem,&no_similar_count); + if(res!=EQUIP_ERR_OK) + { + if(count==no_similar_count) + { + if(no_space_count) + *no_space_count = no_similar_count; + return res; + } + count -= no_similar_count; + } + + // in specific slot + if( bag != NULL_BAG && slot != NULL_SLOT ) + { + res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + + // not specific slot or have spece for partly store only in specific slot + + // in specific bag + if( bag != NULL_BAG ) + { + // search stack in bag for merge to + if( pProto->Stackable > 1 ) + { + if( bag == INVENTORY_SLOT_BAG_0 ) // inventory + { + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + + res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + else // equipped bag + { + // we need check 2 time (specilized/non_specialized), use NULL_BAG to prevent skipping bag + res = _CanStoreItem_InBag(bag,dest,pProto,count,true,false,pItem,NULL_BAG,slot); + if(res!=EQUIP_ERR_OK) + res = _CanStoreItem_InBag(bag,dest,pProto,count,true,true,pItem,NULL_BAG,slot); + + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + } + + // search free slot in bag for place to + if( bag == INVENTORY_SLOT_BAG_0 ) // inventory + { + // search free slot - keyring case + if(pProto->BagFamily & BAG_FAMILY_MASK_KEYS) + { + uint32 keyringSize = GetMaxKeyringSize(); + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_START+keyringSize,dest,pProto,count,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + + res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + else // equipped bag + { + res = _CanStoreItem_InBag(bag,dest,pProto,count,false,false,pItem,NULL_BAG,slot); + if(res!=EQUIP_ERR_OK) + res = _CanStoreItem_InBag(bag,dest,pProto,count,false,true,pItem,NULL_BAG,slot); + + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + } + + // not specific bag or have space for partly store only in specific bag + + // search stack for merge to + if( pProto->Stackable > 1 ) + { + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + + res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + + if( pProto->BagFamily ) + { + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,true,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + } + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,true,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + } + + // search free slot - special bag case + if( pProto->BagFamily ) + { + if(pProto->BagFamily & BAG_FAMILY_MASK_KEYS) + { + uint32 keyringSize = GetMaxKeyringSize(); + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_START+keyringSize,dest,pProto,count,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,false,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + } + + // search free slot + res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + { + if(no_space_count) + *no_space_count = count + no_similar_count; + return res; + } + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,false,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + { + if(no_similar_count==0) + return EQUIP_ERR_OK; + + if(no_space_count) + *no_space_count = count + no_similar_count; + return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; + } + } + + if(no_space_count) + *no_space_count = count + no_similar_count; + + return EQUIP_ERR_INVENTORY_FULL; +} + +////////////////////////////////////////////////////////////////////////// +uint8 Player::CanStoreItems( Item **pItems,int count) const +{ + Item *pItem2; + + // fill space table + int inv_slot_items[INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START]; + int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; + int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START]; + + memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START)); + memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE); + memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START)); + + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + + if (pItem2 && !pItem2->IsInTrade()) + { + inv_slot_items[i-INVENTORY_SLOT_ITEM_START] = pItem2->GetCount(); + } + } + + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + + if (pItem2 && !pItem2->IsInTrade()) + { + inv_keys[i-KEYRING_SLOT_START] = pItem2->GetCount(); + } + } + + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Bag *pBag; + ItemPrototype const *pBagProto; + + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + pItem2 = GetItemByPos( i, j ); + if (pItem2 && !pItem2->IsInTrade()) + { + inv_bags[i-INVENTORY_SLOT_BAG_START][j] = pItem2->GetCount(); + } + } + } + } + } + + // check free space for all items + for (int k=0;kGetEntry(), pItem->GetCount()); + ItemPrototype const *pProto = pItem->GetProto(); + + // strange item + if( !pProto ) + return EQUIP_ERR_ITEM_NOT_FOUND; + + // item it 'bind' + if(pItem->IsBindedNotWith(GetGUID())) + return EQUIP_ERR_DONT_OWN_THAT_ITEM; + + Bag *pBag; + ItemPrototype const *pBagProto; + + // item is 'one item only' + uint8 res = CanTakeMoreSimilarItems(pItem); + if(res != EQUIP_ERR_OK) + return res; + + // search stack for merge to + if( pProto->Stackable > 1 ) + { + bool b_found = false; + + for(int t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; t++) + { + pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); + if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) + { + inv_keys[t-KEYRING_SLOT_START] += pItem->GetCount(); + b_found = true; + break; + } + } + if (b_found) continue; + + for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++) + { + pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); + if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->Stackable ) + { + inv_slot_items[t-INVENTORY_SLOT_ITEM_START] += pItem->GetCount(); + b_found = true; + break; + } + } + if (b_found) continue; + + for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++) + { + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + pItem2 = GetItemByPos( t, j ); + if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->Stackable ) + { + inv_bags[t-INVENTORY_SLOT_BAG_START][j] += pItem->GetCount(); + b_found = true; + break; + } + } + } + } + } + if (b_found) continue; + } + + // special bag case + if( pProto->BagFamily ) + { + bool b_found = false; + if(pProto->BagFamily & BAG_FAMILY_MASK_KEYS) + { + uint32 keyringSize = GetMaxKeyringSize(); + for(uint32 t = KEYRING_SLOT_START; t < KEYRING_SLOT_START+keyringSize; ++t) + { + if( inv_keys[t-KEYRING_SLOT_START] == 0 ) + { + inv_keys[t-KEYRING_SLOT_START] = 1; + b_found = true; + break; + } + } + } + + if (b_found) continue; + + for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++) + { + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + + // not plain container check + if( pBagProto && (pBagProto->Class != ITEM_CLASS_CONTAINER || pBagProto->SubClass != ITEM_SUBCLASS_CONTAINER) && + ItemCanGoIntoBag(pProto,pBagProto) ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + if( inv_bags[t-INVENTORY_SLOT_BAG_START][j] == 0 ) + { + inv_bags[t-INVENTORY_SLOT_BAG_START][j] = 1; + b_found = true; + break; + } + } + } + } + } + if (b_found) continue; + } + + // search free slot + bool b_found = false; + for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++) + { + if( inv_slot_items[t-INVENTORY_SLOT_ITEM_START] == 0 ) + { + inv_slot_items[t-INVENTORY_SLOT_ITEM_START] = 1; + b_found = true; + break; + } + } + if (b_found) continue; + + // search free slot in bags + for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++) + { + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + if( pBagProto && ItemCanGoIntoBag(pProto,pBagProto)) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + if( inv_bags[t-INVENTORY_SLOT_BAG_START][j] == 0 ) + { + inv_bags[t-INVENTORY_SLOT_BAG_START][j] = 1; + b_found = true; + break; + } + } + } + } + } + + // no free slot found? + if (!b_found) + return EQUIP_ERR_INVENTORY_FULL; + } + + return EQUIP_ERR_OK; +} + +////////////////////////////////////////////////////////////////////////// +uint8 Player::CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, uint32 count, bool swap ) const +{ + dest = 0; + Item *pItem = Item::CreateItem( item, count, this ); + if( pItem ) + { + uint8 result = CanEquipItem(slot, dest, pItem, swap ); + delete pItem; + return result; + } + + return EQUIP_ERR_ITEM_NOT_FOUND; +} + +uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading ) const +{ + dest = 0; + if( pItem ) + { + sLog.outDebug( "STORAGE: CanEquipItem slot = %u, item = %u, count = %u", slot, pItem->GetEntry(), pItem->GetCount()); + ItemPrototype const *pProto = pItem->GetProto(); + if( pProto ) + { + // May be here should be more stronger checks; STUNNED checked + // ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked. + if (not_loading && hasUnitState(UNIT_STAT_STUNNED)) + return EQUIP_ERR_YOU_ARE_STUNNED; + + if(pItem->IsBindedNotWith(GetGUID())) + return EQUIP_ERR_DONT_OWN_THAT_ITEM; + + // check count of items (skip for auto move for same player from bank) + uint8 res = CanTakeMoreSimilarItems(pItem); + if(res != EQUIP_ERR_OK) + return res; + + // do not allow equipping gear except weapons, offhands, projectiles, relics in + // - combat + // - in-progress arenas + if( !pProto->CanChangeEquipStateInCombat() ) + { + if( isInCombat() ) + return EQUIP_ERR_NOT_IN_COMBAT; + + if(BattleGround* bg = GetBattleGround()) + if( bg->isArena() && bg->GetStatus() == STATUS_IN_PROGRESS ) + return EQUIP_ERR_NOT_DURING_ARENA_MATCH; + } + + if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0) + return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err + + if(IsNonMeleeSpellCasted(false)) + return EQUIP_ERR_CANT_DO_RIGHT_NOW; + + uint8 eslot = FindEquipSlot( pProto, slot, swap ); + if( eslot == NULL_SLOT ) + return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; + + uint8 msg = CanUseItem( pItem , not_loading ); + if( msg != EQUIP_ERR_OK ) + return msg; + if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) ) + return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE; + + // check unique-equipped on item + if (pProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED) + { + // there is an equip limit on this item + Item* tItem = GetItemOrItemWithGemEquipped(pProto->ItemId); + if (tItem && (!swap || tItem->GetSlot() != eslot ) ) + return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE; + } + + // check unique-equipped on gems + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + { + uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + continue; + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID); + if(pGem && (pGem->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)) + { + Item* tItem = GetItemOrItemWithGemEquipped(enchantEntry->GemID); + if(tItem && (!swap || tItem->GetSlot() != eslot )) + return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE; + } + } + + // check unique-equipped special item classes + if (pProto->Class == ITEM_CLASS_QUIVER) + { + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + { + if( Item* pBag = GetItemByPos( INVENTORY_SLOT_BAG_0, i ) ) + { + if( ItemPrototype const* pBagProto = pBag->GetProto() ) + { + if( pBagProto->Class==pProto->Class && pBagProto->SubClass==pProto->SubClass && + (!swap || pBag->GetSlot() != eslot ) ) + { + if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) + return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH; + else + return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; + } + } + } + } + } + + uint32 type = pProto->InventoryType; + + if(eslot == EQUIPMENT_SLOT_OFFHAND) + { + if( type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND ) + { + if(!CanDualWield()) + return EQUIP_ERR_CANT_DUAL_WIELD; + } + + Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + if(mainItem) + { + if(mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON) + return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; + } + } + + // equip two-hand weapon case (with possible unequip 2 items) + if( type == INVTYPE_2HWEAPON ) + { + if(eslot != EQUIPMENT_SLOT_MAINHAND) + return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; + + // offhand item must can be stored in inventitory for offhand item and it also must be unequipped + Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); + ItemPosCountVec off_dest; + if( offItem && (!not_loading || + CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || + CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; + } + dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot); + return EQUIP_ERR_OK; + } + } + if( !swap ) + return EQUIP_ERR_ITEM_NOT_FOUND; + else + return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; +} + +uint8 Player::CanUnequipItem( uint16 pos, bool swap ) const +{ + // Applied only to equipped items and bank bags + if(!IsEquipmentPos(pos) && !IsBagPos(pos)) + return EQUIP_ERR_OK; + + Item* pItem = GetItemByPos(pos); + + // Applied only to existed equipped item + if( !pItem ) + return EQUIP_ERR_OK; + + sLog.outDebug( "STORAGE: CanUnequipItem slot = %u, item = %u, count = %u", pos, pItem->GetEntry(), pItem->GetCount()); + + ItemPrototype const *pProto = pItem->GetProto(); + if( !pProto ) + return EQUIP_ERR_ITEM_NOT_FOUND; + + // do not allow unequipping gear except weapons, offhands, projectiles, relics in + // - combat + // - in-progress arenas + if( !pProto->CanChangeEquipStateInCombat() ) + { + if( isInCombat() ) + return EQUIP_ERR_NOT_IN_COMBAT; + + if(BattleGround* bg = GetBattleGround()) + if( bg->isArena() && bg->GetStatus() == STATUS_IN_PROGRESS ) + return EQUIP_ERR_NOT_DURING_ARENA_MATCH; + } + + if(!swap && pItem->IsBag() && !((Bag*)pItem)->IsEmpty()) + return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS; + + return EQUIP_ERR_OK; +} + +uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading ) const +{ + if( !pItem ) + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND; + + uint32 count = pItem->GetCount(); + + sLog.outDebug( "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount()); + ItemPrototype const *pProto = pItem->GetProto(); + if( !pProto ) + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND; + + if( pItem->IsBindedNotWith(GetGUID()) ) + return EQUIP_ERR_DONT_OWN_THAT_ITEM; + + // check count of items (skip for auto move for same player from bank) + uint8 res = CanTakeMoreSimilarItems(pItem); + if(res != EQUIP_ERR_OK) + return res; + + // in specific slot + if( bag != NULL_BAG && slot != NULL_SLOT ) + { + if( pProto->InventoryType == INVTYPE_BAG ) + { + Bag *pBag = (Bag*)pItem; + if( pBag ) + { + if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END ) + { + if( !HasBankBagSlot( slot ) ) + return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT; + if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK ) + return cantuse; + } + else + { + if( !pBag->IsEmpty() ) + return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG; + } + } + } + else + { + if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END ) + return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT; + } + + res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + + // not specific slot or have spece for partly store only in specific slot + + // in specific bag + if( bag != NULL_BAG ) + { + if( pProto->InventoryType == INVTYPE_BAG ) + { + Bag *pBag = (Bag*)pItem; + if( pBag && !pBag->IsEmpty() ) + return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG; + } + + // search stack in bag for merge to + if( pProto->Stackable > 1 ) + { + if( bag == INVENTORY_SLOT_BAG_0 ) + { + res = _CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START,BANK_SLOT_ITEM_END,dest,pProto,count,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + else + { + res = _CanStoreItem_InBag(bag,dest,pProto,count,true,false,pItem,NULL_BAG,slot); + if(res!=EQUIP_ERR_OK) + res = _CanStoreItem_InBag(bag,dest,pProto,count,true,true,pItem,NULL_BAG,slot); + + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + } + + // search free slot in bag + if( bag == INVENTORY_SLOT_BAG_0 ) + { + res = _CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START,BANK_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + else + { + res = _CanStoreItem_InBag(bag,dest,pProto,count,false,false,pItem,NULL_BAG,slot); + if(res!=EQUIP_ERR_OK) + res = _CanStoreItem_InBag(bag,dest,pProto,count,false,true,pItem,NULL_BAG,slot); + + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + } + } + + // not specific bag or have spece for partly store only in specific bag + + // search stack for merge to + if( pProto->Stackable > 1 ) + { + // in slots + res = _CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START,BANK_SLOT_ITEM_END,dest,pProto,count,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + + // in special bags + if( pProto->BagFamily ) + { + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,true,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + return EQUIP_ERR_OK; + } + } + + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,true,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + return EQUIP_ERR_OK; + } + } + + // search free place in special bag + if( pProto->BagFamily ) + { + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,false,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + return EQUIP_ERR_OK; + } + } + + // search free space + res = _CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START,BANK_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + return res; + + if(count==0) + return EQUIP_ERR_OK; + + for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) + { + res = _CanStoreItem_InBag(i,dest,pProto,count,false,true,pItem,bag,slot); + if(res!=EQUIP_ERR_OK) + continue; + + if(count==0) + return EQUIP_ERR_OK; + } + return EQUIP_ERR_BANK_FULL; +} + +uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const +{ + if( pItem ) + { + sLog.outDebug( "STORAGE: CanUseItem item = %u", pItem->GetEntry()); + if( !isAlive() && not_loading ) + return EQUIP_ERR_YOU_ARE_DEAD; + //if( isStunned() ) + // return EQUIP_ERR_YOU_ARE_STUNNED; + ItemPrototype const *pProto = pItem->GetProto(); + if( pProto ) + { + if( pItem->IsBindedNotWith(GetGUID()) ) + return EQUIP_ERR_DONT_OWN_THAT_ITEM; + if( (pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0 ) + return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; + if( pItem->GetSkill() != 0 ) + { + if( GetSkillValue( pItem->GetSkill() ) == 0 ) + return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; + } + if( pProto->RequiredSkill != 0 ) + { + if( GetSkillValue( pProto->RequiredSkill ) == 0 ) + return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; + else if( GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank ) + return EQUIP_ERR_ERR_CANT_EQUIP_SKILL; + } + if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) ) + return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; + if( pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank ) + return EQUIP_ERR_CANT_EQUIP_REPUTATION; + if( getLevel() < pProto->RequiredLevel ) + return EQUIP_ERR_CANT_EQUIP_LEVEL_I; + return EQUIP_ERR_OK; + } + } + return EQUIP_ERR_ITEM_NOT_FOUND; +} + +bool Player::CanUseItem( ItemPrototype const *pProto ) +{ + // Used by group, function NeedBeforeGreed, to know if a prototype can be used by a player + + if( pProto ) + { + if( (pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0 ) + return false; + if( pProto->RequiredSkill != 0 ) + { + if( GetSkillValue( pProto->RequiredSkill ) == 0 ) + return false; + else if( GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank ) + return false; + } + if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) ) + return false; + if( getLevel() < pProto->RequiredLevel ) + return false; + return true; + } + return false; +} + +uint8 Player::CanUseAmmo( uint32 item ) const +{ + sLog.outDebug( "STORAGE: CanUseAmmo item = %u", item); + if( !isAlive() ) + return EQUIP_ERR_YOU_ARE_DEAD; + //if( isStunned() ) + // return EQUIP_ERR_YOU_ARE_STUNNED; + ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); + if( pProto ) + { + if( pProto->InventoryType!= INVTYPE_AMMO ) + return EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE; + if( (pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0 ) + return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; + if( pProto->RequiredSkill != 0 ) + { + if( GetSkillValue( pProto->RequiredSkill ) == 0 ) + return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; + else if( GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank ) + return EQUIP_ERR_ERR_CANT_EQUIP_SKILL; + } + if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) ) + return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; + /*if( GetReputation() < pProto->RequiredReputation ) + return EQUIP_ERR_CANT_EQUIP_REPUTATION; + */ + if( getLevel() < pProto->RequiredLevel ) + return EQUIP_ERR_CANT_EQUIP_LEVEL_I; + + // Requires No Ammo + if(GetDummyAura(46699)) + return EQUIP_ERR_BAG_FULL6; + + return EQUIP_ERR_OK; + } + return EQUIP_ERR_ITEM_NOT_FOUND; +} + +void Player::SetAmmo( uint32 item ) +{ + if(!item) + return; + + // already set + if( GetUInt32Value(PLAYER_AMMO_ID) == item ) + return; + + // check ammo + if(item) + { + uint8 msg = CanUseAmmo( item ); + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, NULL, NULL ); + return; + } + } + + SetUInt32Value(PLAYER_AMMO_ID, item); + + _ApplyAmmoBonuses(); +} + +void Player::RemoveAmmo() +{ + SetUInt32Value(PLAYER_AMMO_ID, 0); + + m_ammoDPS = 0.0f; + + if(CanModifyStats()) + UpdateDamagePhysical(RANGED_ATTACK); +} + +// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case. +Item* Player::StoreNewItem( ItemPosCountVec const& dest, uint32 item, bool update,int32 randomPropertyId ) +{ + uint32 count = 0; + for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) + count += itr->count; + + Item *pItem = Item::CreateItem( item, count, this ); + if( pItem ) + { + ItemAddedQuestCheck( item, count ); + if(randomPropertyId) + pItem->SetItemRandomProperties(randomPropertyId); + pItem = StoreItem( dest, pItem, update ); + } + return pItem; +} + +Item* Player::StoreItem( ItemPosCountVec const& dest, Item* pItem, bool update ) +{ + if( !pItem ) + return NULL; + + Item* lastItem = pItem; + + for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ) + { + uint16 pos = itr->pos; + uint32 count = itr->count; + + ++itr; + + if(itr == dest.end()) + { + lastItem = _StoreItem(pos,pItem,count,false,update); + break; + } + + lastItem = _StoreItem(pos,pItem,count,true,update); + } + + return lastItem; +} + +// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case. +Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update ) +{ + if( !pItem ) + return NULL; + + uint8 bag = pos >> 8; + uint8 slot = pos & 255; + + sLog.outDebug( "STORAGE: StoreItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), count); + + Item *pItem2 = GetItemByPos( bag, slot ); + + if( !pItem2 ) + { + if(clone) + pItem = pItem->CloneItem(count,this); + else + pItem->SetCount(count); + + if(!pItem) + return NULL; + + if( pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || + pItem->GetProto()->Bonding == BIND_QUEST_ITEM || + pItem->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos) ) + pItem->SetBinding( true ); + + if( bag == INVENTORY_SLOT_BAG_0 ) + { + m_items[slot] = pItem; + SetUInt64Value( (uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2) ), pItem->GetGUID() ); + pItem->SetUInt64Value( ITEM_FIELD_CONTAINED, GetGUID() ); + pItem->SetUInt64Value( ITEM_FIELD_OWNER, GetGUID() ); + + pItem->SetSlot( slot ); + pItem->SetContainer( NULL ); + + if( IsInWorld() && update ) + { + pItem->AddToWorld(); + pItem->SendUpdateToPlayer( this ); + } + + pItem->SetState(ITEM_CHANGED, this); + } + else + { + Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); + if( pBag ) + { + pBag->StoreItem( slot, pItem, update ); + if( IsInWorld() && update ) + { + pItem->AddToWorld(); + pItem->SendUpdateToPlayer( this ); + } + pItem->SetState(ITEM_CHANGED, this); + pBag->SetState(ITEM_CHANGED, this); + } + } + + AddEnchantmentDurations(pItem); + AddItemDurations(pItem); + + return pItem; + } + else + { + if( pItem2->GetProto()->Bonding == BIND_WHEN_PICKED_UP || + pItem2->GetProto()->Bonding == BIND_QUEST_ITEM || + pItem2->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos) ) + pItem2->SetBinding( true ); + + pItem2->SetCount( pItem2->GetCount() + count ); + if( IsInWorld() && update ) + pItem2->SendUpdateToPlayer( this ); + + if(!clone) + { + // delete item (it not in any slot currently) + if( IsInWorld() && update ) + { + pItem->RemoveFromWorld(); + pItem->DestroyForPlayer( this ); + } + + RemoveEnchantmentDurations(pItem); + RemoveItemDurations(pItem); + + pItem->SetOwnerGUID(GetGUID()); // prevent error at next SetState in case trade/mail/buy from vendor + pItem->SetState(ITEM_REMOVED, this); + } + // AddItemDurations(pItem2); - pItem2 already have duration listed for player + AddEnchantmentDurations(pItem2); + + pItem2->SetState(ITEM_CHANGED, this); + + return pItem2; + } +} + +Item* Player::EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update ) +{ + Item *pItem = Item::CreateItem( item, count, this ); + if( pItem ) + { + ItemAddedQuestCheck( item, count ); + Item * retItem = EquipItem( pos, pItem, update ); + + return retItem; + } + return NULL; +} + +Item* Player::EquipItem( uint16 pos, Item *pItem, bool update ) +{ + if( pItem ) + { + AddEnchantmentDurations(pItem); + AddItemDurations(pItem); + + uint8 bag = pos >> 8; + uint8 slot = pos & 255; + + Item *pItem2 = GetItemByPos( bag, slot ); + + if( !pItem2 ) + { + VisualizeItem( slot, pItem); + + if(isAlive()) + { + ItemPrototype const *pProto = pItem->GetProto(); + + // item set bonuses applied only at equip and removed at unequip, and still active for broken items + if(pProto && pProto->ItemSet) + AddItemsSetItem(this,pItem); + + _ApplyItemMods(pItem, slot, true); + + if(pProto && isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer == 0) + { + m_weaponChangeTimer = DEFAULT_SWITCH_WEAPON; + if (getClass() == CLASS_ROGUE) + m_weaponChangeTimer = ROGUE_SWITCH_WEAPON; + } + } + + if( IsInWorld() && update ) + { + pItem->AddToWorld(); + pItem->SendUpdateToPlayer( this ); + } + + ApplyEquipCooldown(pItem); + + if( slot == EQUIPMENT_SLOT_MAINHAND ) + UpdateExpertise(BASE_ATTACK); + else if( slot == EQUIPMENT_SLOT_OFFHAND ) + UpdateExpertise(OFF_ATTACK); + } + else + { + pItem2->SetCount( pItem2->GetCount() + pItem->GetCount() ); + if( IsInWorld() && update ) + pItem2->SendUpdateToPlayer( this ); + + // delete item (it not in any slot currently) + //pItem->DeleteFromDB(); + if( IsInWorld() && update ) + { + pItem->RemoveFromWorld(); + pItem->DestroyForPlayer( this ); + } + + RemoveEnchantmentDurations(pItem); + RemoveItemDurations(pItem); + + pItem->SetOwnerGUID(GetGUID()); // prevent error at next SetState in case trade/mail/buy from vendor + pItem->SetState(ITEM_REMOVED, this); + pItem2->SetState(ITEM_CHANGED, this); + + ApplyEquipCooldown(pItem2); + + return pItem2; + } + } + + return pItem; +} + +void Player::QuickEquipItem( uint16 pos, Item *pItem) +{ + if( pItem ) + { + AddEnchantmentDurations(pItem); + AddItemDurations(pItem); + + uint8 slot = pos & 255; + VisualizeItem( slot, pItem); + + if( IsInWorld() ) + { + pItem->AddToWorld(); + pItem->SendUpdateToPlayer( this ); + } + } +} + +void Player::SetVisibleItemSlot(uint8 slot, Item *pItem) +{ + // PLAYER_VISIBLE_ITEM_i_CREATOR // Size: 2 + // PLAYER_VISIBLE_ITEM_i_0 // Size: 12 + // entry // Size: 1 + // inspected enchantments // Size: 6 + // ? // Size: 5 + // PLAYER_VISIBLE_ITEM_i_PROPERTIES // Size: 1 (property,suffix factor) + // PLAYER_VISIBLE_ITEM_i_PAD // Size: 1 + // // = 16 + + if(pItem) + { + SetUInt64Value(PLAYER_VISIBLE_ITEM_1_CREATOR + (slot * MAX_VISIBLE_ITEM_OFFSET), pItem->GetUInt64Value(ITEM_FIELD_CREATOR)); + + int VisibleBase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); + SetUInt32Value(VisibleBase + 0, pItem->GetEntry()); + + for(int i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i) + SetUInt32Value(VisibleBase + 1 + i, pItem->GetEnchantmentId(EnchantmentSlot(i))); + + // Use SetInt16Value to prevent set high part to FFFF for negative value + SetInt16Value( PLAYER_VISIBLE_ITEM_1_PROPERTIES + (slot * MAX_VISIBLE_ITEM_OFFSET), 0, pItem->GetItemRandomPropertyId()); + SetUInt32Value(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (slot * MAX_VISIBLE_ITEM_OFFSET), pItem->GetItemSuffixFactor()); + } + else + { + SetUInt64Value(PLAYER_VISIBLE_ITEM_1_CREATOR + (slot * MAX_VISIBLE_ITEM_OFFSET), 0); + + int VisibleBase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); + SetUInt32Value(VisibleBase + 0, 0); + + for(int i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i) + SetUInt32Value(VisibleBase + 1 + i, 0); + + SetUInt32Value(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (slot * MAX_VISIBLE_ITEM_OFFSET), 0); + SetUInt32Value(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (slot * MAX_VISIBLE_ITEM_OFFSET), 0); + } +} + +void Player::VisualizeItem( uint8 slot, Item *pItem) +{ + if(!pItem) + return; + + // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory) + if( pItem->GetProto()->Bonding == BIND_WHEN_EQUIPED || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM ) + pItem->SetBinding( true ); + + sLog.outDebug( "STORAGE: EquipItem slot = %u, item = %u", slot, pItem->GetEntry()); + + m_items[slot] = pItem; + SetUInt64Value( (uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2) ), pItem->GetGUID() ); + pItem->SetUInt64Value( ITEM_FIELD_CONTAINED, GetGUID() ); + pItem->SetUInt64Value( ITEM_FIELD_OWNER, GetGUID() ); + pItem->SetSlot( slot ); + pItem->SetContainer( NULL ); + + if( slot < EQUIPMENT_SLOT_END ) + SetVisibleItemSlot(slot,pItem); + + pItem->SetState(ITEM_CHANGED, this); +} + +void Player::RemoveItem( uint8 bag, uint8 slot, bool update ) +{ + // note: removeitem does not actually change the item + // it only takes the item out of storage temporarily + // note2: if removeitem is to be used for delinking + // the item must be removed from the player's updatequeue + + Item *pItem = GetItemByPos( bag, slot ); + if( pItem ) + { + sLog.outDebug( "STORAGE: RemoveItem bag = %u, slot = %u, item = %u", bag, slot, pItem->GetEntry()); + + RemoveEnchantmentDurations(pItem); + RemoveItemDurations(pItem); + + if( bag == INVENTORY_SLOT_BAG_0 ) + { + if ( slot < INVENTORY_SLOT_BAG_END ) + { + ItemPrototype const *pProto = pItem->GetProto(); + // item set bonuses applied only at equip and removed at unequip, and still active for broken items + + if(pProto && pProto->ItemSet) + RemoveItemsSetItem(this,pProto); + + _ApplyItemMods(pItem, slot, false); + + // remove item dependent auras and casts (only weapon and armor slots) + if(slot < EQUIPMENT_SLOT_END) + RemoveItemDependentAurasAndCasts(pItem); + + // remove held enchantments + if ( slot == EQUIPMENT_SLOT_MAINHAND ) + { + if (pItem->GetItemSuffixFactor()) + { + pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_3); + pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_4); + } + else + { + pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_0); + pItem->ClearEnchantment(PROP_ENCHANTMENT_SLOT_1); + } + } + } + + m_items[slot] = NULL; + SetUInt64Value((uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)), 0); + + if ( slot < EQUIPMENT_SLOT_END ) + SetVisibleItemSlot(slot,NULL); + } + else + { + Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); + if( pBag ) + pBag->RemoveItem(slot, update); + } + pItem->SetUInt64Value( ITEM_FIELD_CONTAINED, 0 ); + // pItem->SetUInt64Value( ITEM_FIELD_OWNER, 0 ); not clear owner at remove (it will be set at store). This used in mail and auction code + pItem->SetSlot( NULL_SLOT ); + if( IsInWorld() && update ) + pItem->SendUpdateToPlayer( this ); + + if( slot == EQUIPMENT_SLOT_MAINHAND ) + UpdateExpertise(BASE_ATTACK); + else if( slot == EQUIPMENT_SLOT_OFFHAND ) + UpdateExpertise(OFF_ATTACK); + } +} + +// Common operation need to remove item from inventory without delete in trade, auction, guild bank, mail.... +void Player::MoveItemFromInventory(uint8 bag, uint8 slot, bool update) +{ + if(Item* it = GetItemByPos(bag,slot)) + { + ItemRemovedQuestCheck(it->GetEntry(),it->GetCount()); + RemoveItem( bag,slot,update); + it->RemoveFromUpdateQueueOf(this); + if(it->IsInWorld()) + { + it->RemoveFromWorld(); + it->DestroyForPlayer( this ); + } + } +} + +// Common operation need to add item from inventory without delete in trade, guild bank, mail.... +void Player::MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool update, bool in_characterInventoryDB) +{ + // update quest counters + ItemAddedQuestCheck(pItem->GetEntry(),pItem->GetCount()); + + // store item + Item* pLastItem = StoreItem( dest, pItem, update); + + // only set if not merged to existed stack (pItem can be deleted already but we can compare pointers any way) + if(pLastItem==pItem) + { + // update owner for last item (this can be original item with wrong owner + if(pLastItem->GetOwnerGUID() != GetGUID()) + pLastItem->SetOwnerGUID(GetGUID()); + + // if this original item then it need create record in inventory + // in case trade we laready have item in other player inventory + pLastItem->SetState(in_characterInventoryDB ? ITEM_CHANGED : ITEM_NEW, this); + } +} + +void Player::DestroyItem( uint8 bag, uint8 slot, bool update ) +{ + Item *pItem = GetItemByPos( bag, slot ); + if( pItem ) + { + sLog.outDebug( "STORAGE: DestroyItem bag = %u, slot = %u, item = %u", bag, slot, pItem->GetEntry()); + + // start from destroy contained items (only equipped bag can have its) + if (pItem->IsBag() && pItem->IsEquipped()) // this also prevent infinity loop if empty bag stored in bag==slot + { + for (int i = 0; i < MAX_BAG_SIZE; i++) + DestroyItem(slot,i,update); + } + + if(pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow()); + + ItemPrototype const *pProto = pItem->GetProto(); + + RemoveEnchantmentDurations(pItem); + RemoveItemDurations(pItem); + + ItemRemovedQuestCheck( pItem->GetEntry(), pItem->GetCount() ); + + if( bag == INVENTORY_SLOT_BAG_0 ) + { + + SetUInt64Value((uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)), 0); + + // equipment and equipped bags can have applied bonuses + if ( slot < INVENTORY_SLOT_BAG_END ) + { + ItemPrototype const *pProto = pItem->GetProto(); + + // item set bonuses applied only at equip and removed at unequip, and still active for broken items + if(pProto && pProto->ItemSet) + RemoveItemsSetItem(this,pProto); + + _ApplyItemMods(pItem, slot, false); + } + + if ( slot < EQUIPMENT_SLOT_END ) + { + // remove item dependent auras and casts (only weapon and armor slots) + RemoveItemDependentAurasAndCasts(pItem); + + // equipment visual show + SetVisibleItemSlot(slot,NULL); + } + + m_items[slot] = NULL; + } + else if(Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag )) + pBag->RemoveItem(slot, update); + + if( IsInWorld() && update ) + { + pItem->RemoveFromWorld(); + pItem->DestroyForPlayer(this); + } + + //pItem->SetOwnerGUID(0); + pItem->SetUInt64Value( ITEM_FIELD_CONTAINED, 0 ); + pItem->SetSlot( NULL_SLOT ); + pItem->SetState(ITEM_REMOVED, this); + } +} + +void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool unequip_check) +{ + sLog.outDebug( "STORAGE: DestroyItemCount item = %u, count = %u", item, count); + Item *pItem; + ItemPrototype const *pProto; + uint32 remcount = 0; + + // in inventory + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + if( pItem->GetCount() + remcount <= count ) + { + // all items in inventory can unequipped + remcount += pItem->GetCount(); + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + + if(remcount >=count) + return; + } + else + { + pProto = pItem->GetProto(); + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if( IsInWorld() & update ) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); + return; + } + } + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + if( pItem->GetCount() + remcount <= count ) + { + // all keys can be unequipped + remcount += pItem->GetCount(); + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + + if(remcount >=count) + return; + } + else + { + pProto = pItem->GetProto(); + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if( IsInWorld() & update ) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); + return; + } + } + } + + // in inventory bags + Bag *pBag; + ItemPrototype const *pBagProto; + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + pItem = pBag->GetItemByPos(j); + if( pItem && pItem->GetEntry() == item ) + { + // all items in bags can be unequipped + if( pItem->GetCount() + remcount <= count ) + { + remcount += pItem->GetCount(); + DestroyItem( i, j, update ); + + if(remcount >=count) + return; + } + else + { + pProto = pItem->GetProto(); + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if( IsInWorld() && update ) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); + return; + } + } + } + } + } + } + + // in equipment and bag list + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + { + pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEntry() == item ) + { + if( pItem->GetCount() + remcount <= count ) + { + if(!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i,false) == EQUIP_ERR_OK ) + { + remcount += pItem->GetCount(); + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + + if(remcount >=count) + return; + } + } + else + { + pProto = pItem->GetProto(); + ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount ); + pItem->SetCount( pItem->GetCount() - count + remcount ); + if( IsInWorld() & update ) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); + return; + } + } + } +} + +void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone ) +{ + sLog.outDebug( "STORAGE: DestroyZoneLimitedItem in map %u and area %u", GetMapId(), new_zone ); + + // in inventory + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + } + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + } + + // in inventory bags + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + ItemPrototype const *pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = pBag->GetItemByPos(j); + if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) + DestroyItem( i, j, update); + } + } + } + } + + // in equipment and bag list + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + } +} + +void Player::DestroyConjuredItems( bool update ) +{ + // used when entering arena + // distroys all conjured items + sLog.outDebug( "STORAGE: DestroyConjuredItems" ); + + // in inventory + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetProto() && + (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) && + (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) ) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + } + + // in inventory bags + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + ItemPrototype const *pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = pBag->GetItemByPos(j); + if( pItem && pItem->GetProto() && + (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) && + (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) ) + DestroyItem( i, j, update); + } + } + } + } + + // in equipment and bag list + for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetProto() && + (pItem->GetProto()->Class == ITEM_CLASS_CONSUMABLE) && + (pItem->GetProto()->Flags & ITEM_FLAGS_CONJURED) ) + DestroyItem( INVENTORY_SLOT_BAG_0, i, update); + } +} + +void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update ) +{ + if(!pItem) + return; + + sLog.outDebug( "STORAGE: DestroyItemCount item (GUID: %u, Entry: %u) count = %u", pItem->GetGUIDLow(),pItem->GetEntry(), count); + + if( pItem->GetCount() <= count ) + { + count-= pItem->GetCount(); + + DestroyItem( pItem->GetBagSlot(),pItem->GetSlot(), update); + } + else + { + ItemRemovedQuestCheck( pItem->GetEntry(), count); + pItem->SetCount( pItem->GetCount() - count ); + count = 0; + if( IsInWorld() & update ) + pItem->SendUpdateToPlayer( this ); + pItem->SetState(ITEM_CHANGED, this); + } +} + +void Player::SplitItem( uint16 src, uint16 dst, uint32 count ) +{ + uint8 srcbag = src >> 8; + uint8 srcslot = src & 255; + + uint8 dstbag = dst >> 8; + uint8 dstslot = dst & 255; + + Item *pSrcItem = GetItemByPos( srcbag, srcslot ); + if( !pSrcItem ) + { + SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pSrcItem, NULL ); + return; + } + + // not let split all items (can be only at cheating) + if(pSrcItem->GetCount() == count) + { + SendEquipError( EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL ); + return; + } + + // not let split more existed items (can be only at cheating) + if(pSrcItem->GetCount() < count) + { + SendEquipError( EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT, pSrcItem, NULL ); + return; + } + + if(pSrcItem->m_lootGenerated) // prevent split looting item (item + { + //best error message found for attempting to split while looting + SendEquipError( EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL ); + return; + } + + sLog.outDebug( "STORAGE: SplitItem bag = %u, slot = %u, item = %u, count = %u", dstbag, dstslot, pSrcItem->GetEntry(), count); + Item *pNewItem = pSrcItem->CloneItem( count, this ); + if( !pNewItem ) + { + SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, pSrcItem, NULL ); + return; + } + + if( IsInventoryPos( dst ) ) + { + // change item amount before check (for unique max count check) + pSrcItem->SetCount( pSrcItem->GetCount() - count ); + + ItemPosCountVec dest; + uint8 msg = CanStoreItem( dstbag, dstslot, dest, pNewItem, false ); + if( msg != EQUIP_ERR_OK ) + { + delete pNewItem; + pSrcItem->SetCount( pSrcItem->GetCount() + count ); + SendEquipError( msg, pSrcItem, NULL ); + return; + } + + if( IsInWorld() ) + pSrcItem->SendUpdateToPlayer( this ); + pSrcItem->SetState(ITEM_CHANGED, this); + StoreItem( dest, pNewItem, true); + } + else if( IsBankPos ( dst ) ) + { + // change item amount before check (for unique max count check) + pSrcItem->SetCount( pSrcItem->GetCount() - count ); + + ItemPosCountVec dest; + uint8 msg = CanBankItem( dstbag, dstslot, dest, pNewItem, false ); + if( msg != EQUIP_ERR_OK ) + { + delete pNewItem; + pSrcItem->SetCount( pSrcItem->GetCount() + count ); + SendEquipError( msg, pSrcItem, NULL ); + return; + } + + if( IsInWorld() ) + pSrcItem->SendUpdateToPlayer( this ); + pSrcItem->SetState(ITEM_CHANGED, this); + BankItem( dest, pNewItem, true); + } + else if( IsEquipmentPos ( dst ) ) + { + // change item amount before check (for unique max count check), provide space for splitted items + pSrcItem->SetCount( pSrcItem->GetCount() - count ); + + uint16 dest; + uint8 msg = CanEquipItem( dstslot, dest, pNewItem, false ); + if( msg != EQUIP_ERR_OK ) + { + delete pNewItem; + pSrcItem->SetCount( pSrcItem->GetCount() + count ); + SendEquipError( msg, pSrcItem, NULL ); + return; + } + + if( IsInWorld() ) + pSrcItem->SendUpdateToPlayer( this ); + pSrcItem->SetState(ITEM_CHANGED, this); + EquipItem( dest, pNewItem, true); + AutoUnequipOffhandIfNeed(); + } +} + +void Player::SwapItem( uint16 src, uint16 dst ) +{ + uint8 srcbag = src >> 8; + uint8 srcslot = src & 255; + + uint8 dstbag = dst >> 8; + uint8 dstslot = dst & 255; + + Item *pSrcItem = GetItemByPos( srcbag, srcslot ); + Item *pDstItem = GetItemByPos( dstbag, dstslot ); + + if( !pSrcItem ) + return; + + sLog.outDebug( "STORAGE: SwapItem bag = %u, slot = %u, item = %u", dstbag, dstslot, pSrcItem->GetEntry()); + + if(!isAlive() ) + { + SendEquipError( EQUIP_ERR_YOU_ARE_DEAD, pSrcItem, pDstItem ); + return; + } + + if(pSrcItem->m_lootGenerated) // prevent swap looting item + { + //best error message found for attempting to swap while looting + SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pSrcItem, NULL ); + return; + } + + // check unequip potability for equipped items and bank bags + if(IsEquipmentPos ( src ) || IsBagPos ( src )) + { + // bags can be swapped with empty bag slots + uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst )); + if(msg != EQUIP_ERR_OK) + { + SendEquipError( msg, pSrcItem, pDstItem ); + return; + } + } + + // prevent put equipped/bank bag in self + if( IsBagPos ( src ) && srcslot == dstbag) + { + SendEquipError( EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem ); + return; + } + + if( !pDstItem ) + { + if( IsInventoryPos( dst ) ) + { + ItemPosCountVec dest; + uint8 msg = CanStoreItem( dstbag, dstslot, dest, pSrcItem, false ); + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, pSrcItem, NULL ); + return; + } + + RemoveItem(srcbag, srcslot, true); + StoreItem( dest, pSrcItem, true); + } + else if( IsBankPos ( dst ) ) + { + ItemPosCountVec dest; + uint8 msg = CanBankItem( dstbag, dstslot, dest, pSrcItem, false); + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, pSrcItem, NULL ); + return; + } + + RemoveItem(srcbag, srcslot, true); + BankItem( dest, pSrcItem, true); + } + else if( IsEquipmentPos ( dst ) ) + { + uint16 dest; + uint8 msg = CanEquipItem( dstslot, dest, pSrcItem, false ); + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, pSrcItem, NULL ); + return; + } + + RemoveItem(srcbag, srcslot, true); + EquipItem( dest, pSrcItem, true); + AutoUnequipOffhandIfNeed(); + } + } + else // if (!pDstItem) + { + if(pDstItem->m_lootGenerated) // prevent swap looting item + { + //best error message found for attempting to swap while looting + SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pDstItem, NULL ); + return; + } + + // check unequip potability for equipped items and bank bags + if(IsEquipmentPos ( dst ) || IsBagPos ( dst )) + { + // bags can be swapped with empty bag slots + uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) ); + if(msg != EQUIP_ERR_OK) + { + SendEquipError( msg, pSrcItem, pDstItem ); + return; + } + } + + // attempt merge to / fill target item + { + uint8 msg; + ItemPosCountVec sDest; + uint16 eDest; + if( IsInventoryPos( dst ) ) + msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, false ); + else if( IsBankPos ( dst ) ) + msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, false ); + else if( IsEquipmentPos ( dst ) ) + msg = CanEquipItem( dstslot, eDest, pSrcItem, false ); + else + return; + + // can be merge/fill + if(msg == EQUIP_ERR_OK) + { + if( pSrcItem->GetCount() + pDstItem->GetCount() <= pSrcItem->GetProto()->Stackable ) + { + RemoveItem(srcbag, srcslot, true); + + if( IsInventoryPos( dst ) ) + StoreItem( sDest, pSrcItem, true); + else if( IsBankPos ( dst ) ) + BankItem( sDest, pSrcItem, true); + else if( IsEquipmentPos ( dst ) ) + { + EquipItem( eDest, pSrcItem, true); + AutoUnequipOffhandIfNeed(); + } + } + else + { + pSrcItem->SetCount( pSrcItem->GetCount() + pDstItem->GetCount() - pSrcItem->GetProto()->Stackable ); + pDstItem->SetCount( pSrcItem->GetProto()->Stackable ); + pSrcItem->SetState(ITEM_CHANGED, this); + pDstItem->SetState(ITEM_CHANGED, this); + if( IsInWorld() ) + { + pSrcItem->SendUpdateToPlayer( this ); + pDstItem->SendUpdateToPlayer( this ); + } + } + return; + } + } + + // impossible merge/fill, do real swap + uint8 msg; + + // check src->dest move possibility + ItemPosCountVec sDest; + uint16 eDest; + if( IsInventoryPos( dst ) ) + msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, true ); + else if( IsBankPos( dst ) ) + msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, true ); + else if( IsEquipmentPos( dst ) ) + { + msg = CanEquipItem( dstslot, eDest, pSrcItem, true ); + if( msg == EQUIP_ERR_OK ) + msg = CanUnequipItem( eDest, true ); + } + + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, pSrcItem, pDstItem ); + return; + } + + // check dest->src move possibility + ItemPosCountVec sDest2; + uint16 eDest2; + if( IsInventoryPos( src ) ) + msg = CanStoreItem( srcbag, srcslot, sDest2, pDstItem, true ); + else if( IsBankPos( src ) ) + msg = CanBankItem( srcbag, srcslot, sDest2, pDstItem, true ); + else if( IsEquipmentPos( src ) ) + { + msg = CanEquipItem( srcslot, eDest2, pDstItem, true); + if( msg == EQUIP_ERR_OK ) + msg = CanUnequipItem( eDest2, true); + } + + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, pDstItem, pSrcItem ); + return; + } + + // now do moves, remove... + RemoveItem(dstbag, dstslot, false); + RemoveItem(srcbag, srcslot, false); + + // add to dest + if( IsInventoryPos( dst ) ) + StoreItem(sDest, pSrcItem, true); + else if( IsBankPos( dst ) ) + BankItem(sDest, pSrcItem, true); + else if( IsEquipmentPos( dst ) ) + EquipItem(eDest, pSrcItem, true); + + // add to src + if( IsInventoryPos( src ) ) + StoreItem(sDest2, pDstItem, true); + else if( IsBankPos( src ) ) + BankItem(sDest2, pDstItem, true); + else if( IsEquipmentPos( src ) ) + EquipItem(eDest2, pDstItem, true); + + AutoUnequipOffhandIfNeed(); + } +} + +void Player::AddItemToBuyBackSlot( Item *pItem ) +{ + if( pItem ) + { + uint32 slot = m_currentBuybackSlot; + // if current back slot non-empty search oldest or free + if(m_items[slot]) + { + uint32 oldest_time = GetUInt32Value( PLAYER_FIELD_BUYBACK_TIMESTAMP_1 ); + uint32 oldest_slot = BUYBACK_SLOT_START; + + for(uint32 i = BUYBACK_SLOT_START+1; i < BUYBACK_SLOT_END; ++i ) + { + // found empty + if(!m_items[i]) + { + slot = i; + break; + } + + uint32 i_time = GetUInt32Value( PLAYER_FIELD_BUYBACK_TIMESTAMP_1 + i - BUYBACK_SLOT_START); + + if(oldest_time > i_time) + { + oldest_time = i_time; + oldest_slot = i; + } + } + + // find oldest + slot = oldest_slot; + } + + RemoveItemFromBuyBackSlot( slot, true ); + sLog.outDebug( "STORAGE: AddItemToBuyBackSlot item = %u, slot = %u", pItem->GetEntry(), slot); + + m_items[slot] = pItem; + time_t base = time(NULL); + uint32 etime = uint32(base - m_logintime + (30 * 3600)); + uint32 eslot = slot - BUYBACK_SLOT_START; + + SetUInt64Value( PLAYER_FIELD_VENDORBUYBACK_SLOT_1 + eslot * 2, pItem->GetGUID() ); + ItemPrototype const *pProto = pItem->GetProto(); + if( pProto ) + SetUInt32Value( PLAYER_FIELD_BUYBACK_PRICE_1 + eslot, pProto->SellPrice * pItem->GetCount() ); + else + SetUInt32Value( PLAYER_FIELD_BUYBACK_PRICE_1 + eslot, 0 ); + SetUInt32Value( PLAYER_FIELD_BUYBACK_TIMESTAMP_1 + eslot, (uint32)etime ); + + // move to next (for non filled list is move most optimized choice) + if(m_currentBuybackSlot < BUYBACK_SLOT_END-1) + ++m_currentBuybackSlot; + } +} + +Item* Player::GetItemFromBuyBackSlot( uint32 slot ) +{ + sLog.outDebug( "STORAGE: GetItemFromBuyBackSlot slot = %u", slot); + if( slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END ) + return m_items[slot]; + return NULL; +} + +void Player::RemoveItemFromBuyBackSlot( uint32 slot, bool del ) +{ + sLog.outDebug( "STORAGE: RemoveItemFromBuyBackSlot slot = %u", slot); + if( slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END ) + { + Item *pItem = m_items[slot]; + if( pItem ) + { + pItem->RemoveFromWorld(); + if(del) pItem->SetState(ITEM_REMOVED, this); + } + + m_items[slot] = NULL; + + uint32 eslot = slot - BUYBACK_SLOT_START; + SetUInt64Value( PLAYER_FIELD_VENDORBUYBACK_SLOT_1 + eslot * 2, 0 ); + SetUInt32Value( PLAYER_FIELD_BUYBACK_PRICE_1 + eslot, 0 ); + SetUInt32Value( PLAYER_FIELD_BUYBACK_TIMESTAMP_1 + eslot, 0 ); + + // if current backslot is filled set to now free slot + if(m_items[m_currentBuybackSlot]) + m_currentBuybackSlot = slot; + } +} + +void Player::SendEquipError( uint8 msg, Item* pItem, Item *pItem2 ) +{ + sLog.outDebug( "WORLD: Sent SMSG_INVENTORY_CHANGE_FAILURE (%u)",msg); + WorldPacket data( SMSG_INVENTORY_CHANGE_FAILURE, (msg == EQUIP_ERR_CANT_EQUIP_LEVEL_I ? 22 : 18) ); + data << uint8(msg); + + if(msg) + { + data << uint64(pItem ? pItem->GetGUID() : 0); + data << uint64(pItem2 ? pItem2->GetGUID() : 0); + data << uint8(0); // not 0 there... + + if(msg == EQUIP_ERR_CANT_EQUIP_LEVEL_I) + { + uint32 level = 0; + + if(pItem) + if(ItemPrototype const* proto = pItem->GetProto()) + level = proto->RequiredLevel; + + data << uint32(level); // new 2.4.0 + } + } + GetSession()->SendPacket(&data); +} + +void Player::SendBuyError( uint8 msg, Creature* pCreature, uint32 item, uint32 param ) +{ + sLog.outDebug( "WORLD: Sent SMSG_BUY_FAILED" ); + WorldPacket data( SMSG_BUY_FAILED, (8+4+4+1) ); + data << uint64(pCreature ? pCreature->GetGUID() : 0); + data << uint32(item); + if( param > 0 ) + data << uint32(param); + data << uint8(msg); + GetSession()->SendPacket(&data); +} + +void Player::SendSellError( uint8 msg, Creature* pCreature, uint64 guid, uint32 param ) +{ + sLog.outDebug( "WORLD: Sent SMSG_SELL_ITEM" ); + WorldPacket data( SMSG_SELL_ITEM,(8+8+(param?4:0)+1)); // last check 2.0.10 + data << uint64(pCreature ? pCreature->GetGUID() : 0); + data << uint64(guid); + if( param > 0 ) + data << uint32(param); + data << uint8(msg); + GetSession()->SendPacket(&data); +} + +void Player::ClearTrade() +{ + tradeGold = 0; + acceptTrade = false; + for(int i = 0; i < TRADE_SLOT_COUNT; i++) + tradeItems[i] = NULL_SLOT; +} + +void Player::TradeCancel(bool sendback) +{ + if(pTrader) + { + // send yellow "Trade cancelled" message to both traders + WorldSession* ws; + ws = GetSession(); + if(sendback) + ws->SendCancelTrade(); + ws = pTrader->GetSession(); + if(!ws->PlayerLogout()) + ws->SendCancelTrade(); + + // cleanup + ClearTrade(); + pTrader->ClearTrade(); + // prevent loss of reference + pTrader->pTrader = NULL; + pTrader = NULL; + } +} + +void Player::UpdateItemDuration(uint32 time, bool realtimeonly) +{ + if(m_itemDuration.empty()) + return; + + sLog.outDebug("Player::UpdateItemDuration(%u,%u)", time,realtimeonly); + + for(ItemDurationList::iterator itr = m_itemDuration.begin();itr != m_itemDuration.end(); ) + { + Item* item = *itr; + ++itr; // current element can be erased in UpdateDuration + + if (realtimeonly && item->GetProto()->Duration < 0 || !realtimeonly) + item->UpdateDuration(this,time); + } +} + +void Player::UpdateEnchantTime(uint32 time) +{ + for(EnchantDurationList::iterator itr = m_enchantDuration.begin(),next;itr != m_enchantDuration.end();itr=next) + { + assert(itr->item); + next=itr; + if(!itr->item->GetEnchantmentId(itr->slot)) + { + next = m_enchantDuration.erase(itr); + } + else if(itr->leftduration <= time) + { + ApplyEnchantment(itr->item,itr->slot,false,false); + itr->item->ClearEnchantment(itr->slot); + next = m_enchantDuration.erase(itr); + } + else if(itr->leftduration > time) + { + itr->leftduration -= time; + ++next; + } + } +} + +void Player::AddEnchantmentDurations(Item *item) +{ + for(int x=0;xGetEnchantmentId(EnchantmentSlot(x))) + continue; + + uint32 duration = item->GetEnchantmentDuration(EnchantmentSlot(x)); + if( duration > 0 ) + AddEnchantmentDuration(item,EnchantmentSlot(x),duration); + } +} + +void Player::RemoveEnchantmentDurations(Item *item) +{ + for(EnchantDurationList::iterator itr = m_enchantDuration.begin();itr != m_enchantDuration.end();) + { + if(itr->item == item) + { + // save duration in item + item->SetEnchantmentDuration(EnchantmentSlot(itr->slot),itr->leftduration); + itr = m_enchantDuration.erase(itr); + } + else + ++itr; + } +} + +void Player::RemoveAllEnchantments(EnchantmentSlot slot) +{ + // remove enchantments from equipped items first to clean up the m_enchantDuration list + for(EnchantDurationList::iterator itr = m_enchantDuration.begin(),next;itr != m_enchantDuration.end();itr=next) + { + next = itr; + if(itr->slot==slot) + { + if(itr->item && itr->item->GetEnchantmentId(slot)) + { + // remove from stats + ApplyEnchantment(itr->item,slot,false,false); + // remove visual + itr->item->ClearEnchantment(slot); + } + // remove from update list + next = m_enchantDuration.erase(itr); + } + else + ++next; + } + + // remove enchants from inventory items + // NOTE: no need to remove these from stats, since these aren't equipped + // in inventory + for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + { + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pItem && pItem->GetEnchantmentId(slot) ) + pItem->ClearEnchantment(slot); + } + + // in inventory bags + for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + { + Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if( pBag ) + { + ItemPrototype const *pBagProto = pBag->GetProto(); + if( pBagProto ) + { + for(uint32 j = 0; j < pBagProto->ContainerSlots; j++) + { + Item* pItem = pBag->GetItemByPos(j); + if( pItem && pItem->GetEnchantmentId(slot) ) + pItem->ClearEnchantment(slot); + } + } + } + } +} + +// duration == 0 will remove item enchant +void Player::AddEnchantmentDuration(Item *item,EnchantmentSlot slot,uint32 duration) +{ + if(!item) + return; + + if(slot >= MAX_ENCHANTMENT_SLOT) + return; + + for(EnchantDurationList::iterator itr = m_enchantDuration.begin();itr != m_enchantDuration.end();++itr) + { + if(itr->item == item && itr->slot == slot) + { + itr->item->SetEnchantmentDuration(itr->slot,itr->leftduration); + m_enchantDuration.erase(itr); + break; + } + } + if(item && duration > 0 ) + { + GetSession()->SendItemEnchantTimeUpdate(GetGUID(), item->GetGUID(),slot,uint32(duration/1000)); + m_enchantDuration.push_back(EnchantDuration(item,slot,duration)); + } +} + +void Player::ApplyEnchantment(Item *item,bool apply) +{ + for(uint32 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) + ApplyEnchantment(item, EnchantmentSlot(slot), apply); +} + +void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool apply_dur, bool ignore_condition) +{ + if(!item) + return; + + if(!item->IsEquipped()) + return; + + if(slot >= MAX_ENCHANTMENT_SLOT) + return; + + uint32 enchant_id = item->GetEnchantmentId(slot); + if(!enchant_id) + return; + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return; + + if(!ignore_condition && pEnchant->EnchantmentCondition && !((Player*)this)->EnchantmentFitsRequirements(pEnchant->EnchantmentCondition, -1)) + return; + + for (int s=0; s<3; s++) + { + uint32 enchant_display_type = pEnchant->type[s]; + uint32 enchant_amount = pEnchant->amount[s]; + uint32 enchant_spell_id = pEnchant->spellid[s]; + + switch(enchant_display_type) + { + case ITEM_ENCHANTMENT_TYPE_NONE: + break; + case ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL: + // processed in Player::CastItemCombatSpell + break; + case ITEM_ENCHANTMENT_TYPE_DAMAGE: + if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND) + HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(enchant_amount), apply); + else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND) + HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(enchant_amount), apply); + else if (item->GetSlot() == EQUIPMENT_SLOT_RANGED) + HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(enchant_amount), apply); + break; + case ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL: + if(enchant_spell_id) + { + if(apply) + { + int32 basepoints = int32(enchant_amount); + // Random Property Exist - try found basepoints for spell (basepoints depencs from item suffix factor) + if (item->GetItemRandomPropertyId() !=0 && !enchant_amount) + { + ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId())); + if (item_rand) + { + // Search enchant_amount + for (int k=0; k<3; k++) + { + if(item_rand->enchant_id[k] == enchant_id) + { + basepoints = int32((item_rand->prefix[k]*item->GetItemSuffixFactor()) / 10000 ); + break; + } + } + } + } + // Cast custom spell vs all equal basepoints getted from enchant_amount + if (basepoints) + CastCustomSpell(this,enchant_spell_id,&basepoints,&basepoints,&basepoints,true,item); + else + CastSpell(this,enchant_spell_id,true,item); + } + else + RemoveAurasDueToItemSpell(item,enchant_spell_id); + } + break; + case ITEM_ENCHANTMENT_TYPE_RESISTANCE: + if (!enchant_amount) + { + ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId())); + if(item_rand) + { + for (int k=0; k<3; k++) + { + if(item_rand->enchant_id[k] == enchant_id) + { + enchant_amount = uint32((item_rand->prefix[k]*item->GetItemSuffixFactor()) / 10000 ); + break; + } + } + } + } + + HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply); + break; + case ITEM_ENCHANTMENT_TYPE_STAT: + { + if (!enchant_amount) + { + ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId())); + if(item_rand_suffix) + { + for (int k=0; k<3; k++) + { + if(item_rand_suffix->enchant_id[k] == enchant_id) + { + enchant_amount = uint32((item_rand_suffix->prefix[k]*item->GetItemSuffixFactor()) / 10000 ); + break; + } + } + } + } + + sLog.outDebug("Adding %u to stat nb %u",enchant_amount,enchant_spell_id); + switch (enchant_spell_id) + { + case ITEM_MOD_AGILITY: + sLog.outDebug("+ %u AGILITY",enchant_amount); + HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply); + ApplyStatBuffMod(STAT_AGILITY, enchant_amount, apply); + break; + case ITEM_MOD_STRENGTH: + sLog.outDebug("+ %u STRENGTH",enchant_amount); + HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply); + ApplyStatBuffMod(STAT_STRENGTH, enchant_amount, apply); + break; + case ITEM_MOD_INTELLECT: + sLog.outDebug("+ %u INTELLECT",enchant_amount); + HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply); + ApplyStatBuffMod(STAT_INTELLECT, enchant_amount, apply); + break; + case ITEM_MOD_SPIRIT: + sLog.outDebug("+ %u SPIRIT",enchant_amount); + HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, float(enchant_amount), apply); + ApplyStatBuffMod(STAT_SPIRIT, enchant_amount, apply); + break; + case ITEM_MOD_STAMINA: + sLog.outDebug("+ %u STAMINA",enchant_amount); + HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply); + ApplyStatBuffMod(STAT_STAMINA, enchant_amount, apply); + break; + case ITEM_MOD_DEFENSE_SKILL_RATING: + ((Player*)this)->ApplyRatingMod(CR_DEFENSE_SKILL, enchant_amount, apply); + sLog.outDebug("+ %u DEFENCE", enchant_amount); + break; + case ITEM_MOD_DODGE_RATING: + ((Player*)this)->ApplyRatingMod(CR_DODGE, enchant_amount, apply); + sLog.outDebug("+ %u DODGE", enchant_amount); + break; + case ITEM_MOD_PARRY_RATING: + ((Player*)this)->ApplyRatingMod(CR_PARRY, enchant_amount, apply); + sLog.outDebug("+ %u PARRY", enchant_amount); + break; + case ITEM_MOD_BLOCK_RATING: + ((Player*)this)->ApplyRatingMod(CR_BLOCK, enchant_amount, apply); + sLog.outDebug("+ %u SHIELD_BLOCK", enchant_amount); + break; + case ITEM_MOD_HIT_MELEE_RATING: + ((Player*)this)->ApplyRatingMod(CR_HIT_MELEE, enchant_amount, apply); + sLog.outDebug("+ %u MELEE_HIT", enchant_amount); + break; + case ITEM_MOD_HIT_RANGED_RATING: + ((Player*)this)->ApplyRatingMod(CR_HIT_RANGED, enchant_amount, apply); + sLog.outDebug("+ %u RANGED_HIT", enchant_amount); + break; + case ITEM_MOD_HIT_SPELL_RATING: + ((Player*)this)->ApplyRatingMod(CR_HIT_SPELL, enchant_amount, apply); + sLog.outDebug("+ %u SPELL_HIT", enchant_amount); + break; + case ITEM_MOD_CRIT_MELEE_RATING: + ((Player*)this)->ApplyRatingMod(CR_CRIT_MELEE, enchant_amount, apply); + sLog.outDebug("+ %u MELEE_CRIT", enchant_amount); + break; + case ITEM_MOD_CRIT_RANGED_RATING: + ((Player*)this)->ApplyRatingMod(CR_CRIT_RANGED, enchant_amount, apply); + sLog.outDebug("+ %u RANGED_CRIT", enchant_amount); + break; + case ITEM_MOD_CRIT_SPELL_RATING: + ((Player*)this)->ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply); + sLog.outDebug("+ %u SPELL_CRIT", enchant_amount); + break; +// Values from ITEM_STAT_MELEE_HA_RATING to ITEM_MOD_HASTE_RANGED_RATING are never used +// in Enchantments +// case ITEM_MOD_HIT_TAKEN_MELEE_RATING: +// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply); +// break; +// case ITEM_MOD_HIT_TAKEN_RANGED_RATING: +// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply); +// break; +// case ITEM_MOD_HIT_TAKEN_SPELL_RATING: +// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply); +// break; +// case ITEM_MOD_CRIT_TAKEN_MELEE_RATING: +// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply); +// break; +// case ITEM_MOD_CRIT_TAKEN_RANGED_RATING: +// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply); +// break; +// case ITEM_MOD_CRIT_TAKEN_SPELL_RATING: +// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply); +// break; +// case ITEM_MOD_HASTE_MELEE_RATING: +// ((Player*)this)->ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply); +// break; +// case ITEM_MOD_HASTE_RANGED_RATING: +// ((Player*)this)->ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply); +// break; + case ITEM_MOD_HASTE_SPELL_RATING: + ((Player*)this)->ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply); + break; + case ITEM_MOD_HIT_RATING: + ((Player*)this)->ApplyRatingMod(CR_HIT_MELEE, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_HIT_RANGED, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_HIT_SPELL, enchant_amount, apply); + sLog.outDebug("+ %u HIT", enchant_amount); + break; + case ITEM_MOD_CRIT_RATING: + ((Player*)this)->ApplyRatingMod(CR_CRIT_MELEE, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_CRIT_RANGED, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply); + sLog.outDebug("+ %u CRITICAL", enchant_amount); + break; +// Values ITEM_MOD_HIT_TAKEN_RATING and ITEM_MOD_CRIT_TAKEN_RATING are never used in Enchantment +// case ITEM_MOD_HIT_TAKEN_RATING: +// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply); +// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply); +// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply); +// break; +// case ITEM_MOD_CRIT_TAKEN_RATING: +// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply); +// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply); +// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply); +// break; + case ITEM_MOD_RESILIENCE_RATING: + ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply); + sLog.outDebug("+ %u RESILIENCE", enchant_amount); + break; + case ITEM_MOD_HASTE_RATING: + ((Player*)this)->ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply); + ((Player*)this)->ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply); + sLog.outDebug("+ %u HASTE", enchant_amount); + break; + case ITEM_MOD_EXPERTISE_RATING: + ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply); + sLog.outDebug("+ %u EXPERTISE", enchant_amount); + break; + default: + break; + } + break; + } + case ITEM_ENCHANTMENT_TYPE_TOTEM: // Shaman Rockbiter Weapon + { + if(getClass() == CLASS_SHAMAN) + { + float addValue = 0.0f; + if(item->GetSlot() == EQUIPMENT_SLOT_MAINHAND) + { + addValue = float(enchant_amount * item->GetProto()->Delay/1000.0f); + HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, addValue, apply); + } + else if(item->GetSlot() == EQUIPMENT_SLOT_OFFHAND ) + { + addValue = float(enchant_amount * item->GetProto()->Delay/1000.0f); + HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, addValue, apply); + } + } + break; + } + default: + sLog.outError("Unknown item enchantment display type: %d",enchant_display_type); + break; + } /*switch(enchant_display_type)*/ + } /*for*/ + + // visualize enchantment at player and equipped items + if(slot < MAX_INSPECTED_ENCHANTMENT_SLOT) + { + int VisibleBase = PLAYER_VISIBLE_ITEM_1_0 + (item->GetSlot() * MAX_VISIBLE_ITEM_OFFSET); + SetUInt32Value(VisibleBase + 1 + slot, apply? item->GetEnchantmentId(slot) : 0); + } + + if(apply_dur) + { + if(apply) + { + // set duration + uint32 duration = item->GetEnchantmentDuration(slot); + if(duration > 0) + AddEnchantmentDuration(item,slot,duration); + } + else + { + // duration == 0 will remove EnchantDuration + AddEnchantmentDuration(item,slot,0); + } + } +} + +void Player::SendEnchantmentDurations() +{ + for(EnchantDurationList::iterator itr = m_enchantDuration.begin();itr != m_enchantDuration.end();++itr) + { + GetSession()->SendItemEnchantTimeUpdate(GetGUID(), itr->item->GetGUID(),itr->slot,uint32(itr->leftduration)/1000); + } +} + +void Player::SendItemDurations() +{ + for(ItemDurationList::iterator itr = m_itemDuration.begin();itr != m_itemDuration.end();++itr) + { + (*itr)->SendTimeUpdate(this); + } +} + +void Player::SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast) +{ + if(!item) // prevent crash + return; + + // last check 2.0.10 + WorldPacket data( SMSG_ITEM_PUSH_RESULT, (8+4+4+4+1+4+4+4+4+4) ); + data << GetGUID(); // player GUID + data << uint32(received); // 0=looted, 1=from npc + data << uint32(created); // 0=received, 1=created + data << uint32(1); // always 0x01 (probably meant to be count of listed items) + data << (uint8)item->GetBagSlot(); // bagslot + // item slot, but when added to stack: 0xFFFFFFFF + data << (uint32) ((item->GetCount()==count) ? item->GetSlot() : -1); + data << uint32(item->GetEntry()); // item id + data << uint32(item->GetItemSuffixFactor()); // SuffixFactor + data << uint32(item->GetItemRandomPropertyId()); // random item property id + data << uint32(count); // count of items + data << GetItemCount(item->GetEntry()); // count of items in inventory + + if (broadcast && GetGroup()) + GetGroup()->BroadcastPacket(&data); + else + GetSession()->SendPacket(&data); +} + +/*********************************************************/ +/*** QUEST SYSTEM ***/ +/*********************************************************/ + +void Player::PrepareQuestMenu( uint64 guid ) +{ + Object *pObject; + QuestRelations* pObjectQR; + QuestRelations* pObjectQIR; + Creature *pCreature = ObjectAccessor::GetCreature(*this, guid); + if( pCreature ) + { + pObject = (Object*)pCreature; + pObjectQR = &objmgr.mCreatureQuestRelations; + pObjectQIR = &objmgr.mCreatureQuestInvolvedRelations; + } + else + { + GameObject *pGameObject = ObjectAccessor::GetGameObject(*this, guid); + if( pGameObject ) + { + pObject = (Object*)pGameObject; + pObjectQR = &objmgr.mGOQuestRelations; + pObjectQIR = &objmgr.mGOQuestInvolvedRelations; + } + else + return; + } + + QuestMenu &qm = PlayerTalkClass->GetQuestMenu(); + qm.ClearMenu(); + + for(QuestRelations::const_iterator i = pObjectQIR->lower_bound(pObject->GetEntry()); i != pObjectQIR->upper_bound(pObject->GetEntry()); ++i) + { + uint32 quest_id = i->second; + QuestStatus status = GetQuestStatus( quest_id ); + if ( status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus( quest_id ) ) + qm.AddMenuItem(quest_id, DIALOG_STATUS_REWARD_REP); + else if ( status == QUEST_STATUS_INCOMPLETE ) + qm.AddMenuItem(quest_id, DIALOG_STATUS_INCOMPLETE); + else if (status == QUEST_STATUS_AVAILABLE ) + qm.AddMenuItem(quest_id, DIALOG_STATUS_CHAT); + } + + for(QuestRelations::const_iterator i = pObjectQR->lower_bound(pObject->GetEntry()); i != pObjectQR->upper_bound(pObject->GetEntry()); ++i) + { + uint32 quest_id = i->second; + Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + if(!pQuest) continue; + + QuestStatus status = GetQuestStatus( quest_id ); + + if (pQuest->IsAutoComplete() && CanTakeQuest(pQuest, false)) + qm.AddMenuItem(quest_id, DIALOG_STATUS_REWARD_REP); + else if ( status == QUEST_STATUS_NONE && CanTakeQuest( pQuest, false ) ) + qm.AddMenuItem(quest_id, DIALOG_STATUS_AVAILABLE); + } +} + +void Player::SendPreparedQuest( uint64 guid ) +{ + QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu(); + if( questMenu.Empty() ) + return; + + QuestMenuItem const& qmi0 = questMenu.GetItem( 0 ); + + uint32 status = qmi0.m_qIcon; + + // single element case + if ( questMenu.MenuItemCount() == 1 ) + { + // Auto open -- maybe also should verify there is no greeting + uint32 quest_id = qmi0.m_qId; + Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + if ( pQuest ) + { + if( status == DIALOG_STATUS_REWARD_REP && !GetQuestRewardStatus( quest_id ) ) + PlayerTalkClass->SendQuestGiverRequestItems( pQuest, guid, CanRewardQuest(pQuest,false), true ); + else if( status == DIALOG_STATUS_INCOMPLETE ) + PlayerTalkClass->SendQuestGiverRequestItems( pQuest, guid, false, true ); + // Send completable on repeatable quest if player don't have quest + else if( pQuest->IsRepeatable() ) + PlayerTalkClass->SendQuestGiverRequestItems( pQuest, guid, CanCompleteRepeatableQuest(pQuest), true ); + else + PlayerTalkClass->SendQuestGiverQuestDetails( pQuest, guid, true ); + } + } + // multiply entries + else + { + QEmote qe; + qe._Delay = 0; + qe._Emote = 0; + std::string title = ""; + Creature *pCreature = ObjectAccessor::GetCreature(*this, guid); + if( pCreature ) + { + uint32 textid = pCreature->GetNpcTextId(); + GossipText * gossiptext = objmgr.GetGossipText(textid); + if( !gossiptext ) + { + qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote + qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote + title = ""; + } + else + { + qe = gossiptext->Options[0].Emotes[0]; + + if(!gossiptext->Options[0].Text_0.empty()) + { + title = gossiptext->Options[0].Text_0; + + int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textid); + if (nl) + { + if (nl->Text_0[0].size() > loc_idx && !nl->Text_0[0][loc_idx].empty()) + title = nl->Text_0[0][loc_idx]; + } + } + } + else + { + title = gossiptext->Options[0].Text_1; + + int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textid); + if (nl) + { + if (nl->Text_1[0].size() > loc_idx && !nl->Text_1[0][loc_idx].empty()) + title = nl->Text_1[0][loc_idx]; + } + } + } + } + } + PlayerTalkClass->SendQuestGiverQuestList( qe, title, guid ); + } +} + +bool Player::IsActiveQuest( uint32 quest_id ) const +{ + QuestStatusMap::const_iterator itr = mQuestStatus.find(quest_id); + + return itr != mQuestStatus.end() && itr->second.m_status != QUEST_STATUS_NONE; +} + +Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest ) +{ + Object *pObject; + QuestRelations* pObjectQR; + QuestRelations* pObjectQIR; + + Creature *pCreature = ObjectAccessor::GetCreature(*this, guid); + if( pCreature ) + { + pObject = (Object*)pCreature; + pObjectQR = &objmgr.mCreatureQuestRelations; + pObjectQIR = &objmgr.mCreatureQuestInvolvedRelations; + } + else + { + GameObject *pGameObject = ObjectAccessor::GetGameObject(*this, guid); + if( pGameObject ) + { + pObject = (Object*)pGameObject; + pObjectQR = &objmgr.mGOQuestRelations; + pObjectQIR = &objmgr.mGOQuestInvolvedRelations; + } + else + return NULL; + } + + uint32 nextQuestID = pQuest->GetNextQuestInChain(); + for(QuestRelations::const_iterator itr = pObjectQR->lower_bound(pObject->GetEntry()); itr != pObjectQR->upper_bound(pObject->GetEntry()); ++itr) + { + if (itr->second == nextQuestID) + return objmgr.GetQuestTemplate(nextQuestID); + } + + return NULL; +} + +bool Player::CanSeeStartQuest( Quest const *pQuest ) +{ + if( SatisfyQuestRace( pQuest, false ) && SatisfyQuestSkillOrClass( pQuest, false ) && + SatisfyQuestExclusiveGroup( pQuest, false ) && SatisfyQuestReputation( pQuest, false ) && + SatisfyQuestPreviousQuest( pQuest, false ) && SatisfyQuestNextChain( pQuest, false ) && + SatisfyQuestPrevChain( pQuest, false ) && SatisfyQuestDay( pQuest, false ) ) + { + return getLevel() + sWorld.getConfig(CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel(); + } + + return false; +} + +bool Player::CanTakeQuest( Quest const *pQuest, bool msg ) +{ + return SatisfyQuestStatus( pQuest, msg ) && SatisfyQuestExclusiveGroup( pQuest, msg ) + && SatisfyQuestRace( pQuest, msg ) && SatisfyQuestLevel( pQuest, msg ) + && SatisfyQuestSkillOrClass( pQuest, msg ) && SatisfyQuestReputation( pQuest, msg ) + && SatisfyQuestPreviousQuest( pQuest, msg ) && SatisfyQuestTimed( pQuest, msg ) + && SatisfyQuestNextChain( pQuest, msg ) && SatisfyQuestPrevChain( pQuest, msg ) + && SatisfyQuestDay( pQuest, msg ); +} + +bool Player::CanAddQuest( Quest const *pQuest, bool msg ) +{ + if( !SatisfyQuestLog( msg ) ) + return false; + + uint32 srcitem = pQuest->GetSrcItemId(); + if( srcitem > 0 ) + { + uint32 count = pQuest->GetSrcItemCount(); + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, srcitem, count ); + + // player already have max number (in most case 1) source item, no additional item needed and quest can be added. + if( msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS ) + return true; + else if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, NULL, NULL ); + return false; + } + } + return true; +} + +bool Player::CanCompleteQuest( uint32 quest_id ) +{ + if( quest_id ) + { + QuestStatusData& q_status = mQuestStatus[quest_id]; + if( q_status.m_status == QUEST_STATUS_COMPLETE ) + return false; // not allow re-complete quest + + Quest const* qInfo = objmgr.GetQuestTemplate(quest_id); + + if(!qInfo) + return false; + + // auto complete quest + if (qInfo->IsAutoComplete() && CanTakeQuest(qInfo, false)) + return true; + + if ( q_status.m_status == QUEST_STATUS_INCOMPLETE ) + { + + if ( qInfo->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ) ) + { + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + if( qInfo->ReqItemCount[i]!= 0 && q_status.m_itemcount[i] < qInfo->ReqItemCount[i] ) + return false; + } + } + + if ( qInfo->HasFlag(QUEST_MANGOS_FLAGS_KILL_OR_CAST | QUEST_MANGOS_FLAGS_SPEAKTO) ) + { + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + if( qInfo->ReqCreatureOrGOId[i] == 0 ) + continue; + + if( qInfo->ReqCreatureOrGOCount[i] != 0 && q_status.m_creatureOrGOcount[i] < qInfo->ReqCreatureOrGOCount[i] ) + return false; + } + } + + if ( qInfo->HasFlag( QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT ) && !q_status.m_explored ) + return false; + + if ( qInfo->HasFlag( QUEST_MANGOS_FLAGS_TIMED ) && q_status.m_timer == 0 ) + return false; + + if ( qInfo->GetRewOrReqMoney() < 0 ) + { + if ( GetMoney() < uint32(-qInfo->GetRewOrReqMoney()) ) + return false; + } + + uint32 repFacId = qInfo->GetRepObjectiveFaction(); + if ( repFacId && GetReputation(repFacId) < qInfo->GetRepObjectiveValue() ) + return false; + + return true; + } + } + return false; +} + +bool Player::CanCompleteRepeatableQuest( Quest const *pQuest ) +{ + // Solve problem that player don't have the quest and try complete it. + // if repeatable she must be able to complete event if player don't have it. + // Seem that all repeatable quest are DELIVER Flag so, no need to add more. + if( !CanTakeQuest(pQuest, false) ) + return false; + + if (pQuest->HasFlag( QUEST_MANGOS_FLAGS_DELIVER) ) + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + if( pQuest->ReqItemId[i] && pQuest->ReqItemCount[i] && !HasItemCount(pQuest->ReqItemId[i],pQuest->ReqItemCount[i]) ) + return false; + + if( !CanRewardQuest(pQuest, false) ) + return false; + + return true; +} + +bool Player::CanRewardQuest( Quest const *pQuest, bool msg ) +{ + // not auto complete quest and not completed quest (only cheating case, then ignore without message) + if(!pQuest->IsAutoComplete() && GetQuestStatus(pQuest->GetQuestId()) != QUEST_STATUS_COMPLETE) + return false; + + // daily quest can't be rewarded (10 daily quest already completed) + if(!SatisfyQuestDay(pQuest,true)) + return false; + + // rewarded and not repeatable quest (only cheating case, then ignore without message) + if(GetQuestRewardStatus(pQuest->GetQuestId())) + return false; + + // prevent receive reward with quest items in bank + if ( pQuest->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ) ) + { + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + if( pQuest->ReqItemCount[i]!= 0 && + GetItemCount(pQuest->ReqItemId[i]) < pQuest->ReqItemCount[i] ) + { + if(msg) + SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return false; + } + } + } + + // prevent receive reward with low money and GetRewOrReqMoney() < 0 + if(pQuest->GetRewOrReqMoney() < 0 && GetMoney() < uint32(-pQuest->GetRewOrReqMoney()) ) + return false; + + return true; +} + +bool Player::CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg ) +{ + // prevent receive reward with quest items in bank or for not completed quest + if(!CanRewardQuest(pQuest,msg)) + return false; + + if ( pQuest->GetRewChoiceItemsCount() > 0 ) + { + if( pQuest->RewChoiceItemId[reward] ) + { + ItemPosCountVec dest; + uint8 res = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewChoiceItemId[reward], pQuest->RewChoiceItemCount[reward] ); + if( res != EQUIP_ERR_OK ) + { + SendEquipError( res, NULL, NULL ); + return false; + } + } + } + + if ( pQuest->GetRewItemsCount() > 0 ) + { + for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i) + { + if( pQuest->RewItemId[i] ) + { + ItemPosCountVec dest; + uint8 res = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewItemId[i], pQuest->RewItemCount[i] ); + if( res != EQUIP_ERR_OK ) + { + SendEquipError( res, NULL, NULL ); + return false; + } + } + } + } + + return true; +} + +void Player::AddQuest( Quest const *pQuest, Object *questGiver ) +{ + uint16 log_slot = FindQuestSlot( 0 ); + assert(log_slot < MAX_QUEST_LOG_SIZE); + + uint32 quest_id = pQuest->GetQuestId(); + + // if not exist then created with set uState==NEW and rewarded=false + QuestStatusData& questStatusData = mQuestStatus[quest_id]; + if (questStatusData.uState != QUEST_NEW) + questStatusData.uState = QUEST_CHANGED; + + // check for repeatable quests status reset + questStatusData.m_status = QUEST_STATUS_INCOMPLETE; + questStatusData.m_explored = false; + + if ( pQuest->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ) ) + { + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + questStatusData.m_itemcount[i] = 0; + } + + if ( pQuest->HasFlag(QUEST_MANGOS_FLAGS_KILL_OR_CAST | QUEST_MANGOS_FLAGS_SPEAKTO) ) + { + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + questStatusData.m_creatureOrGOcount[i] = 0; + } + + GiveQuestSourceItem( pQuest ); + AdjustQuestReqItemCount( pQuest ); + + if( pQuest->GetRepObjectiveFaction() ) + SetFactionVisibleForFactionId(pQuest->GetRepObjectiveFaction()); + + uint32 qtime = 0; + if( pQuest->HasFlag( QUEST_MANGOS_FLAGS_TIMED ) ) + { + uint32 limittime = pQuest->GetLimitTime(); + + // shared timed quest + if(questGiver && questGiver->GetTypeId()==TYPEID_PLAYER) + limittime = ((Player*)questGiver)->getQuestStatusMap()[quest_id].m_timer / 1000; + + AddTimedQuest( quest_id ); + questStatusData.m_timer = limittime * 1000; + qtime = static_cast(time(NULL)) + limittime; + } + else + questStatusData.m_timer = 0; + + SetQuestSlot(log_slot, quest_id, qtime); + + //starting initial quest script + if(questGiver && pQuest->GetQuestStartScript()!=0) + sWorld.ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this); + + UpdateForQuestsGO(); +} + +void Player::CompleteQuest( uint32 quest_id ) +{ + if( quest_id ) + { + SetQuestStatus( quest_id, QUEST_STATUS_COMPLETE ); + + uint16 log_slot = FindQuestSlot( quest_id ); + if( log_slot < MAX_QUEST_LOG_SIZE) + SetQuestSlotState(log_slot,QUEST_STATE_COMPLETE); + + if(Quest const* qInfo = objmgr.GetQuestTemplate(quest_id)) + { + if( qInfo->HasFlag(QUEST_FLAGS_AUTO_REWARDED) ) + RewardQuest(qInfo,0,this,false); + else + SendQuestComplete( quest_id ); + } + } +} + +void Player::IncompleteQuest( uint32 quest_id ) +{ + if( quest_id ) + { + SetQuestStatus( quest_id, QUEST_STATUS_INCOMPLETE ); + + uint16 log_slot = FindQuestSlot( quest_id ); + if( log_slot < MAX_QUEST_LOG_SIZE) + RemoveQuestSlotState(log_slot,QUEST_STATE_COMPLETE); + } +} + +void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce ) +{ + uint32 quest_id = pQuest->GetQuestId(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++ ) + { + if ( pQuest->ReqItemId[i] ) + DestroyItemCount( pQuest->ReqItemId[i], pQuest->ReqItemCount[i], true); + } + + //if( qInfo->HasSpecialFlag( QUEST_FLAGS_TIMED ) ) + // SetTimedQuest( 0 ); + m_timedquests.erase(pQuest->GetQuestId()); + + if ( pQuest->GetRewChoiceItemsCount() > 0 ) + { + if( pQuest->RewChoiceItemId[reward] ) + { + ItemPosCountVec dest; + if( CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewChoiceItemId[reward], pQuest->RewChoiceItemCount[reward] ) == EQUIP_ERR_OK ) + { + Item* item = StoreNewItem( dest, pQuest->RewChoiceItemId[reward], true); + SendNewItem(item, pQuest->RewChoiceItemCount[reward], true, false); + } + } + } + + if ( pQuest->GetRewItemsCount() > 0 ) + { + for (uint32 i=0; i < pQuest->GetRewItemsCount(); ++i) + { + if( pQuest->RewItemId[i] ) + { + ItemPosCountVec dest; + if( CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewItemId[i], pQuest->RewItemCount[i] ) == EQUIP_ERR_OK ) + { + Item* item = StoreNewItem( dest, pQuest->RewItemId[i], true); + SendNewItem(item, pQuest->RewItemCount[i], true, false); + } + } + } + } + + RewardReputation( pQuest ); + + if( pQuest->GetRewSpellCast() > 0 ) + CastSpell( this, pQuest->GetRewSpellCast(), true); + else if( pQuest->GetRewSpell() > 0) + CastSpell( this, pQuest->GetRewSpell(), true); + + uint16 log_slot = FindQuestSlot( quest_id ); + if( log_slot < MAX_QUEST_LOG_SIZE) + SetQuestSlot(log_slot,0); + + QuestStatusData& q_status = mQuestStatus[quest_id]; + + // Not give XP in case already completed once repeatable quest + uint32 XP = q_status.m_rewarded ? 0 : uint32(pQuest->XPValue( this )*sWorld.getRate(RATE_XP_QUEST)); + + if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) + GiveXP( XP , NULL ); + else + ModifyMoney( int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY)) ); + + // Give player extra money if GetRewOrReqMoney > 0 and get ReqMoney if negative + ModifyMoney( pQuest->GetRewOrReqMoney() ); + + // title reward + if(pQuest->GetCharTitleId()) + { + if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId())) + SetFlag64(PLAYER__FIELD_KNOWN_TITLES, (uint64(1) << titleEntry->bit_index)); + } + + // Send reward mail + if(pQuest->GetRewMailTemplateId()) + { + MailMessageType mailType; + uint32 senderGuidOrEntry; + switch(questGiver->GetTypeId()) + { + case TYPEID_UNIT: + mailType = MAIL_CREATURE; + senderGuidOrEntry = questGiver->GetEntry(); + break; + case TYPEID_GAMEOBJECT: + mailType = MAIL_GAMEOBJECT; + senderGuidOrEntry = questGiver->GetEntry(); + break; + case TYPEID_ITEM: + mailType = MAIL_ITEM; + senderGuidOrEntry = questGiver->GetEntry(); + break; + case TYPEID_PLAYER: + mailType = MAIL_NORMAL; + senderGuidOrEntry = questGiver->GetGUIDLow(); + break; + default: + mailType = MAIL_NORMAL; + senderGuidOrEntry = GetGUIDLow(); + break; + } + + Loot questMailLoot; + + questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this); + + // fill mail + MailItemsInfo mi; // item list preparing + + for(size_t i = 0; mi.size() < MAX_MAIL_ITEMS && i < questMailLoot.items.size(); ++i) + { + if(LootItem* lootitem = questMailLoot.LootItemInSlot(i,this)) + { + if(Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,this)) + { + item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + } + } + } + + for(size_t i = 0; mi.size() < MAX_MAIL_ITEMS && i < questMailLoot.quest_items.size(); ++i) + { + if(LootItem* lootitem = questMailLoot.LootItemInSlot(i+questMailLoot.items.size(),this)) + { + if(Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,this)) + { + item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + } + } + } + + WorldSession::SendMailTo(this, mailType, MAIL_STATIONERY_NORMAL, senderGuidOrEntry, GetGUIDLow(), "", 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE,pQuest->GetRewMailDelaySecs(),pQuest->GetRewMailTemplateId()); + } + + if(pQuest->IsDaily()) + SetDailyQuestStatus(quest_id); + + if ( !pQuest->IsRepeatable() ) + SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE); + else + SetQuestStatus(quest_id, QUEST_STATUS_NONE); + + q_status.m_rewarded = true; + + if(announce) + SendQuestReward( pQuest, XP, questGiver ); + + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; +} + +void Player::FailQuest( uint32 quest_id ) +{ + if( quest_id ) + { + IncompleteQuest( quest_id ); + + uint16 log_slot = FindQuestSlot( quest_id ); + if( log_slot < MAX_QUEST_LOG_SIZE) + { + SetQuestSlotTimer(log_slot, 1 ); + SetQuestSlotState(log_slot,QUEST_STATE_FAIL); + } + SendQuestFailed( quest_id ); + } +} + +void Player::FailTimedQuest( uint32 quest_id ) +{ + if( quest_id ) + { + QuestStatusData& q_status = mQuestStatus[quest_id]; + + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + q_status.m_timer = 0; + + IncompleteQuest( quest_id ); + + uint16 log_slot = FindQuestSlot( quest_id ); + if( log_slot < MAX_QUEST_LOG_SIZE) + { + SetQuestSlotTimer(log_slot, 1 ); + SetQuestSlotState(log_slot,QUEST_STATE_FAIL); + } + SendQuestTimerFailed( quest_id ); + } +} + +bool Player::SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg ) +{ + int32 zoneOrSort = qInfo->GetZoneOrSort(); + int32 skillOrClass = qInfo->GetSkillOrClass(); + + // skip zone zoneOrSort and 0 case skillOrClass + if( zoneOrSort >= 0 && skillOrClass == 0 ) + return true; + + int32 questSort = -zoneOrSort; + uint8 reqSortClass = ClassByQuestSort(questSort); + + // check class sort cases in zoneOrSort + if( reqSortClass != 0 && getClass() != reqSortClass) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + + // check class + if( skillOrClass < 0 ) + { + uint8 reqClass = -int32(skillOrClass); + if(getClass() != reqClass) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + } + // check skill + else if( skillOrClass > 0 ) + { + uint32 reqSkill = skillOrClass; + if( GetSkillValue( reqSkill ) < qInfo->GetRequiredSkillValue() ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + } + + return true; +} + +bool Player::SatisfyQuestLevel( Quest const* qInfo, bool msg ) +{ + if( getLevel() < qInfo->GetMinLevel() ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + return true; +} + +bool Player::SatisfyQuestLog( bool msg ) +{ + // exist free slot + if( FindQuestSlot(0) < MAX_QUEST_LOG_SIZE ) + return true; + + if( msg ) + { + WorldPacket data( SMSG_QUESTLOG_FULL, 0 ); + GetSession()->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent QUEST_LOG_FULL_MESSAGE" ); + } + return false; +} + +bool Player::SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg ) +{ + // No previous quest (might be first quest in a series) + if( qInfo->prevQuests.empty()) + return true; + + for(Quest::PrevQuests::const_iterator iter = qInfo->prevQuests.begin(); iter != qInfo->prevQuests.end(); ++iter ) + { + uint32 prevId = abs(*iter); + + QuestStatusMap::iterator i_prevstatus = mQuestStatus.find( prevId ); + Quest const* qPrevInfo = objmgr.GetQuestTemplate(prevId); + + if( qPrevInfo && i_prevstatus != mQuestStatus.end() ) + { + // If any of the positive previous quests completed, return true + if( *iter > 0 && i_prevstatus->second.m_rewarded ) + { + // skip one-from-all exclusive group + if(qPrevInfo->GetExclusiveGroup() >= 0) + return true; + + // each-from-all exclusive group ( < 0) + // can be start if only all quests in prev quest exclusive group complited and rewarded + ObjectMgr::ExclusiveQuestGroups::iterator iter = objmgr.mExclusiveQuestGroups.lower_bound(qPrevInfo->GetExclusiveGroup()); + ObjectMgr::ExclusiveQuestGroups::iterator end = objmgr.mExclusiveQuestGroups.upper_bound(qPrevInfo->GetExclusiveGroup()); + + assert(iter!=end); // always must be found if qPrevInfo->ExclusiveGroup != 0 + + for(; iter != end; ++iter) + { + uint32 exclude_Id = iter->second; + + // skip checked quest id, only state of other quests in group is interesting + if(exclude_Id == prevId) + continue; + + QuestStatusMap::iterator i_exstatus = mQuestStatus.find( exclude_Id ); + + // alternative quest from group also must be completed and rewarded(reported) + if( i_exstatus == mQuestStatus.end() || !i_exstatus->second.m_rewarded ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + } + return true; + } + // If any of the negative previous quests active, return true + if( *iter < 0 && (i_prevstatus->second.m_status == QUEST_STATUS_INCOMPLETE + || (i_prevstatus->second.m_status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(prevId)))) + { + // skip one-from-all exclusive group + if(qPrevInfo->GetExclusiveGroup() >= 0) + return true; + + // each-from-all exclusive group ( < 0) + // can be start if only all quests in prev quest exclusive group active + ObjectMgr::ExclusiveQuestGroups::iterator iter = objmgr.mExclusiveQuestGroups.lower_bound(qPrevInfo->GetExclusiveGroup()); + ObjectMgr::ExclusiveQuestGroups::iterator end = objmgr.mExclusiveQuestGroups.upper_bound(qPrevInfo->GetExclusiveGroup()); + + assert(iter!=end); // always must be found if qPrevInfo->ExclusiveGroup != 0 + + for(; iter != end; ++iter) + { + uint32 exclude_Id = iter->second; + + // skip checked quest id, only state of other quests in group is interesting + if(exclude_Id == prevId) + continue; + + QuestStatusMap::iterator i_exstatus = mQuestStatus.find( exclude_Id ); + + // alternative quest from group also must be active + if( i_exstatus == mQuestStatus.end() || + i_exstatus->second.m_status != QUEST_STATUS_INCOMPLETE && + (i_prevstatus->second.m_status != QUEST_STATUS_COMPLETE || GetQuestRewardStatus(prevId)) ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + } + return true; + } + } + } + + // Has only positive prev. quests in non-rewarded state + // and negative prev. quests in non-active state + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + + return false; +} + +bool Player::SatisfyQuestRace( Quest const* qInfo, bool msg ) +{ + uint32 reqraces = qInfo->GetRequiredRaces(); + if ( reqraces == 0 ) + return true; + if( (reqraces & getRaceMask()) == 0 ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_QUEST_FAILED_WRONG_RACE ); + return false; + } + return true; +} + +bool Player::SatisfyQuestReputation( Quest const* qInfo, bool msg ) +{ + uint32 fIdMin = qInfo->GetRequiredMinRepFaction(); //Min required rep + if(fIdMin && GetReputation(fIdMin) < qInfo->GetRequiredMinRepValue()) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + + uint32 fIdMax = qInfo->GetRequiredMaxRepFaction(); //Max required rep + if(fIdMax && GetReputation(fIdMax) >= qInfo->GetRequiredMaxRepValue()) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + + return true; +} + +bool Player::SatisfyQuestStatus( Quest const* qInfo, bool msg ) +{ + QuestStatusMap::iterator itr = mQuestStatus.find( qInfo->GetQuestId() ); + if ( itr != mQuestStatus.end() && itr->second.m_status != QUEST_STATUS_NONE ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_QUEST_ALREADY_ON ); + return false; + } + return true; +} + +bool Player::SatisfyQuestTimed( Quest const* qInfo, bool msg ) +{ + if ( (find(m_timedquests.begin(), m_timedquests.end(), qInfo->GetQuestId()) != m_timedquests.end()) && qInfo->HasFlag(QUEST_MANGOS_FLAGS_TIMED) ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_QUEST_ONLY_ONE_TIMED ); + return false; + } + return true; +} + +bool Player::SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg ) +{ + // non positive exclusive group, if > 0 then can be start if any other quest in exclusive group already started/completed + if(qInfo->GetExclusiveGroup() <= 0) + return true; + + ObjectMgr::ExclusiveQuestGroups::iterator iter = objmgr.mExclusiveQuestGroups.lower_bound(qInfo->GetExclusiveGroup()); + ObjectMgr::ExclusiveQuestGroups::iterator end = objmgr.mExclusiveQuestGroups.upper_bound(qInfo->GetExclusiveGroup()); + + assert(iter!=end); // always must be found if qInfo->ExclusiveGroup != 0 + + for(; iter != end; ++iter) + { + uint32 exclude_Id = iter->second; + + // skip checked quest id, only state of other quests in group is interesting + if(exclude_Id == qInfo->GetQuestId()) + continue; + + QuestStatusMap::iterator i_exstatus = mQuestStatus.find( exclude_Id ); + + // alternative quest already started or completed + if( i_exstatus != mQuestStatus.end() + && (i_exstatus->second.m_status == QUEST_STATUS_COMPLETE || i_exstatus->second.m_status == QUEST_STATUS_INCOMPLETE) ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + } + return true; +} + +bool Player::SatisfyQuestNextChain( Quest const* qInfo, bool msg ) +{ + if(!qInfo->GetNextQuestInChain()) + return true; + + // next quest in chain already started or completed + QuestStatusMap::iterator itr = mQuestStatus.find( qInfo->GetNextQuestInChain() ); + if( itr != mQuestStatus.end() + && (itr->second.m_status == QUEST_STATUS_COMPLETE || itr->second.m_status == QUEST_STATUS_INCOMPLETE) ) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + + // check for all quests further up the chain + // only necessary if there are quest chains with more than one quest that can be skipped + //return SatisfyQuestNextChain( qInfo->GetNextQuestInChain(), msg ); + return true; +} + +bool Player::SatisfyQuestPrevChain( Quest const* qInfo, bool msg ) +{ + // No previous quest in chain + if( qInfo->prevChainQuests.empty()) + return true; + + for(Quest::PrevChainQuests::const_iterator iter = qInfo->prevChainQuests.begin(); iter != qInfo->prevChainQuests.end(); ++iter ) + { + uint32 prevId = *iter; + + QuestStatusMap::iterator i_prevstatus = mQuestStatus.find( prevId ); + + if( i_prevstatus != mQuestStatus.end() ) + { + // If any of the previous quests in chain active, return false + if( i_prevstatus->second.m_status == QUEST_STATUS_INCOMPLETE + || (i_prevstatus->second.m_status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(prevId))) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); + return false; + } + } + + // check for all quests further down the chain + // only necessary if there are quest chains with more than one quest that can be skipped + //if( !SatisfyQuestPrevChain( prevId, msg ) ) + // return false; + } + + // No previous quest in chain active + return true; +} + +bool Player::SatisfyQuestDay( Quest const* qInfo, bool msg ) +{ + if(!qInfo->IsDaily()) + return true; + + bool have_slot = false; + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) + { + uint32 id = GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx); + if(qInfo->GetQuestId()==id) + return false; + + if(!id) + have_slot = true; + } + + if(!have_slot) + { + if( msg ) + SendCanTakeQuestResponse( INVALIDREASON_DAILY_QUESTS_REMAINING ); + return false; + } + + return true; +} + +bool Player::GiveQuestSourceItem( Quest const *pQuest ) +{ + uint32 srcitem = pQuest->GetSrcItemId(); + if( srcitem > 0 ) + { + uint32 count = pQuest->GetSrcItemCount(); + if( count <= 0 ) + count = 1; + + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, srcitem, count ); + if( msg == EQUIP_ERR_OK ) + { + Item * item = StoreNewItem(dest, srcitem, true); + SendNewItem(item, count, true, false); + return true; + } + // player already have max amount required item, just report success + else if( msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS ) + return true; + else + SendEquipError( msg, NULL, NULL ); + return false; + } + + return true; +} + +bool Player::TakeQuestSourceItem( uint32 quest_id, bool msg ) +{ + Quest const* qInfo = objmgr.GetQuestTemplate(quest_id); + if( qInfo ) + { + uint32 srcitem = qInfo->GetSrcItemId(); + if( srcitem > 0 ) + { + uint32 count = qInfo->GetSrcItemCount(); + if( count <= 0 ) + count = 1; + + // exist one case when destroy source quest item not possible: + // non un-equippable item (equipped non-empty bag, for example) + uint8 res = CanUnequipItems(srcitem,count); + if(res != EQUIP_ERR_OK) + { + if(msg) + SendEquipError( res, NULL, NULL ); + return false; + } + + DestroyItemCount(srcitem, count, true, true); + } + } + return true; +} + +bool Player::GetQuestRewardStatus( uint32 quest_id ) const +{ + Quest const* qInfo = objmgr.GetQuestTemplate(quest_id); + if( qInfo ) + { + // for repeatable quests: rewarded field is set after first reward only to prevent getting XP more than once + QuestStatusMap::const_iterator itr = mQuestStatus.find( quest_id ); + if( itr != mQuestStatus.end() && itr->second.m_status != QUEST_STATUS_NONE + && !qInfo->IsRepeatable() ) + return itr->second.m_rewarded; + + return false; + } + return false; +} + +QuestStatus Player::GetQuestStatus( uint32 quest_id ) const +{ + if( quest_id ) + { + QuestStatusMap::const_iterator itr = mQuestStatus.find( quest_id ); + if( itr != mQuestStatus.end() ) + return itr->second.m_status; + } + return QUEST_STATUS_NONE; +} + +bool Player::CanShareQuest(uint32 quest_id) const +{ + Quest const* qInfo = objmgr.GetQuestTemplate(quest_id); + if( qInfo && qInfo->HasFlag(QUEST_FLAGS_SHARABLE) ) + { + QuestStatusMap::const_iterator itr = mQuestStatus.find( quest_id ); + if( itr != mQuestStatus.end() ) + return itr->second.m_status == QUEST_STATUS_NONE || itr->second.m_status == QUEST_STATUS_INCOMPLETE; + } + return false; +} + +void Player::SetQuestStatus( uint32 quest_id, QuestStatus status ) +{ + Quest const* qInfo = objmgr.GetQuestTemplate(quest_id); + if( qInfo ) + { + if( status == QUEST_STATUS_NONE || status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_COMPLETE ) + { + if( qInfo->HasFlag( QUEST_MANGOS_FLAGS_TIMED ) ) + m_timedquests.erase(qInfo->GetQuestId()); + } + + QuestStatusData& q_status = mQuestStatus[quest_id]; + + q_status.m_status = status; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + } + + UpdateForQuestsGO(); +} + +// not used in MaNGOS, but used in scripting code +uint32 Player::GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry) +{ + Quest const* qInfo = objmgr.GetQuestTemplate(quest_id); + if( !qInfo ) + return 0; + + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + if ( qInfo->ReqCreatureOrGOId[j] == entry ) + return mQuestStatus[quest_id].m_creatureOrGOcount[j]; + + return 0; +} + +void Player::AdjustQuestReqItemCount( Quest const* pQuest ) +{ + if ( pQuest->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ) ) + { + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + uint32 reqitemcount = pQuest->ReqItemCount[i]; + if( reqitemcount != 0 ) + { + uint32 quest_id = pQuest->GetQuestId(); + uint32 curitemcount = GetItemCount(pQuest->ReqItemId[i],true); + + QuestStatusData& q_status = mQuestStatus[quest_id]; + q_status.m_itemcount[i] = std::min(curitemcount, reqitemcount); + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + } + } + } +} + +uint16 Player::FindQuestSlot( uint32 quest_id ) const +{ + for ( uint16 i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + if ( GetQuestSlotQuestId(i) == quest_id ) + return i; + + return MAX_QUEST_LOG_SIZE; +} + +void Player::AreaExploredOrEventHappens( uint32 questId ) +{ + if( questId ) + { + uint16 log_slot = FindQuestSlot( questId ); + if( log_slot < MAX_QUEST_LOG_SIZE) + { + QuestStatusData& q_status = mQuestStatus[questId]; + + if(!q_status.m_explored) + { + q_status.m_explored = true; + if (q_status.uState != QUEST_NEW) + q_status.uState = QUEST_CHANGED; + } + } + if( CanCompleteQuest( questId ) ) + CompleteQuest( questId ); + } +} + +//not used in mangosd, function for external script library +void Player::GroupEventHappens( uint32 questId, WorldObject const* pEventObject ) +{ + if( Group *pGroup = GetGroup() ) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pGroupGuy = itr->getSource(); + + // for any leave or dead (with not released body) group member at appropriate distance + if( pGroupGuy && pGroupGuy->IsAtGroupRewardDistance(pEventObject) && !pGroupGuy->GetCorpse() ) + pGroupGuy->AreaExploredOrEventHappens(questId); + } + } + else + AreaExploredOrEventHappens(questId); +} + +void Player::ItemAddedQuestCheck( uint32 entry, uint32 count ) +{ + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + uint32 questid = GetQuestSlotQuestId(i); + if ( questid == 0 ) + continue; + + QuestStatusData& q_status = mQuestStatus[questid]; + + if ( q_status.m_status != QUEST_STATUS_INCOMPLETE ) + continue; + + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if( !qInfo || !qInfo->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ) ) + continue; + + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + uint32 reqitem = qInfo->ReqItemId[j]; + if ( reqitem == entry ) + { + uint32 reqitemcount = qInfo->ReqItemCount[j]; + uint32 curitemcount = q_status.m_itemcount[j]; + if ( curitemcount < reqitemcount ) + { + uint32 additemcount = ( curitemcount + count <= reqitemcount ? count : reqitemcount - curitemcount); + q_status.m_itemcount[j] += additemcount; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + + SendQuestUpdateAddItem( qInfo, j, additemcount ); + } + if ( CanCompleteQuest( questid ) ) + CompleteQuest( questid ); + return; + } + } + } + UpdateForQuestsGO(); +} + +void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count ) +{ + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + uint32 questid = GetQuestSlotQuestId(i); + if(!questid) + continue; + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if ( !qInfo ) + continue; + if( !qInfo->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ) ) + continue; + + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + uint32 reqitem = qInfo->ReqItemId[j]; + if ( reqitem == entry ) + { + QuestStatusData& q_status = mQuestStatus[questid]; + + uint32 reqitemcount = qInfo->ReqItemCount[j]; + uint32 curitemcount; + if( q_status.m_status != QUEST_STATUS_COMPLETE ) + curitemcount = q_status.m_itemcount[j]; + else + curitemcount = GetItemCount(entry,true); + if ( curitemcount < reqitemcount + count ) + { + uint32 remitemcount = ( curitemcount <= reqitemcount ? count : count + reqitemcount - curitemcount); + q_status.m_itemcount[j] = curitemcount - remitemcount; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + + IncompleteQuest( questid ); + } + return; + } + } + } + UpdateForQuestsGO(); +} + +void Player::KilledMonster( uint32 entry, uint64 guid ) +{ + uint32 addkillcount = 1; + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + uint32 questid = GetQuestSlotQuestId(i); + if(!questid) + continue; + + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if( !qInfo ) + continue; + // just if !ingroup || !noraidgroup || raidgroup + QuestStatusData& q_status = mQuestStatus[questid]; + if( q_status.m_status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->GetType() == QUEST_TYPE_RAID)) + { + if( qInfo->HasFlag( QUEST_MANGOS_FLAGS_KILL_OR_CAST) ) + { + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + // skip GO activate objective or none + if(qInfo->ReqCreatureOrGOId[j] <=0) + continue; + + // skip Cast at creature objective + if(qInfo->ReqSpell[j] !=0 ) + continue; + + uint32 reqkill = qInfo->ReqCreatureOrGOId[j]; + + if ( reqkill == entry ) + { + uint32 reqkillcount = qInfo->ReqCreatureOrGOCount[j]; + uint32 curkillcount = q_status.m_creatureOrGOcount[j]; + if ( curkillcount < reqkillcount ) + { + q_status.m_creatureOrGOcount[j] = curkillcount + addkillcount; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + + SendQuestUpdateAddCreatureOrGo( qInfo, guid, j, curkillcount, addkillcount); + } + if ( CanCompleteQuest( questid ) ) + CompleteQuest( questid ); + + // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization). + continue; + } + } + } + } + } +} + +void Player::CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id ) +{ + bool isCreature = IS_CREATURE_GUID(guid); + + uint32 addCastCount = 1; + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + uint32 questid = GetQuestSlotQuestId(i); + if(!questid) + continue; + + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if ( !qInfo ) + continue; + + QuestStatusData& q_status = mQuestStatus[questid]; + + if ( q_status.m_status == QUEST_STATUS_INCOMPLETE ) + { + if( qInfo->HasFlag( QUEST_MANGOS_FLAGS_KILL_OR_CAST ) ) + { + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + // skip kill creature objective (0) or wrong spell casts + if(qInfo->ReqSpell[j] != spell_id ) + continue; + + uint32 reqTarget = 0; + + if(isCreature) + { + // creature activate objectives + if(qInfo->ReqCreatureOrGOId[j] > 0) + // checked at quest_template loading + reqTarget = qInfo->ReqCreatureOrGOId[j]; + } + else + { + // GO activate objective + if(qInfo->ReqCreatureOrGOId[j] < 0) + // checked at quest_template loading + reqTarget = - qInfo->ReqCreatureOrGOId[j]; + } + + // other not this creature/GO related objectives + if( reqTarget != entry ) + continue; + + uint32 reqCastCount = qInfo->ReqCreatureOrGOCount[j]; + uint32 curCastCount = q_status.m_creatureOrGOcount[j]; + if ( curCastCount < reqCastCount ) + { + q_status.m_creatureOrGOcount[j] = curCastCount + addCastCount; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + + SendQuestUpdateAddCreatureOrGo( qInfo, guid, j, curCastCount, addCastCount); + } + + if ( CanCompleteQuest( questid ) ) + CompleteQuest( questid ); + + // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization). + break; + } + } + } + } +} + +void Player::TalkedToCreature( uint32 entry, uint64 guid ) +{ + uint32 addTalkCount = 1; + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + uint32 questid = GetQuestSlotQuestId(i); + if(!questid) + continue; + + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if ( !qInfo ) + continue; + + QuestStatusData& q_status = mQuestStatus[questid]; + + if ( q_status.m_status == QUEST_STATUS_INCOMPLETE ) + { + if( qInfo->HasFlag( QUEST_MANGOS_FLAGS_KILL_OR_CAST | QUEST_MANGOS_FLAGS_SPEAKTO ) ) + { + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + // skip spell casts and Gameobject objectives + if(qInfo->ReqSpell[j] > 0 || qInfo->ReqCreatureOrGOId[j] < 0) + continue; + + uint32 reqTarget = 0; + + if(qInfo->ReqCreatureOrGOId[j] > 0) // creature activate objectives + // checked at quest_template loading + reqTarget = qInfo->ReqCreatureOrGOId[j]; + else + continue; + + if ( reqTarget == entry ) + { + uint32 reqTalkCount = qInfo->ReqCreatureOrGOCount[j]; + uint32 curTalkCount = q_status.m_creatureOrGOcount[j]; + if ( curTalkCount < reqTalkCount ) + { + q_status.m_creatureOrGOcount[j] = curTalkCount + addTalkCount; + if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; + + SendQuestUpdateAddCreatureOrGo( qInfo, guid, j, curTalkCount, addTalkCount); + } + if ( CanCompleteQuest( questid ) ) + CompleteQuest( questid ); + + // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization). + continue; + } + } + } + } + } +} + +void Player::MoneyChanged( uint32 count ) +{ + for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) + { + uint32 questid = GetQuestSlotQuestId(i); + if (!questid) + continue; + + Quest const* qInfo = objmgr.GetQuestTemplate(questid); + if( qInfo && qInfo->GetRewOrReqMoney() < 0 ) + { + QuestStatusData& q_status = mQuestStatus[questid]; + + if( q_status.m_status == QUEST_STATUS_INCOMPLETE ) + { + if(int32(count) >= -qInfo->GetRewOrReqMoney()) + { + if ( CanCompleteQuest( questid ) ) + CompleteQuest( questid ); + } + } + else if( q_status.m_status == QUEST_STATUS_COMPLETE ) + { + if(int32(count) < -qInfo->GetRewOrReqMoney()) + IncompleteQuest( questid ); + } + } + } +} + +bool Player::HasQuestForItem( uint32 itemid ) const +{ + for( QuestStatusMap::const_iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i ) + { + QuestStatusData const& q_status = i->second; + + if (q_status.m_status == QUEST_STATUS_INCOMPLETE) + { + Quest const* qinfo = objmgr.GetQuestTemplate(i->first); + if(!qinfo) + continue; + + // hide quest if player is in raid-group and quest is no raid quest + if(GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID) + continue; + + // There should be no mixed ReqItem/ReqSource drop + // This part for ReqItem drop + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + if(itemid == qinfo->ReqItemId[j] && q_status.m_itemcount[j] < qinfo->ReqItemCount[j] ) + return true; + } + // This part - for ReqSource + for (int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; j++) + { + // examined item is a source item + if (qinfo->ReqSourceId[j] == itemid && qinfo->ReqSourceRef[j] > 0 && qinfo->ReqSourceRef[j] <= QUEST_OBJECTIVES_COUNT) + { + uint32 idx = qinfo->ReqSourceRef[j]-1; + + // total count of created ReqItems and SourceItems is less than ReqItemCount + if(qinfo->ReqItemId[idx] != 0 && + q_status.m_itemcount[idx] * qinfo->ReqSourceCount[j] + GetItemCount(itemid,true) < qinfo->ReqItemCount[idx] * qinfo->ReqSourceCount[j]) + return true; + + // total count of casted ReqCreatureOrGOs and SourceItems is less than ReqCreatureOrGOCount + if (qinfo->ReqCreatureOrGOId[idx] != 0) + { + if(q_status.m_creatureOrGOcount[idx] * qinfo->ReqSourceCount[j] + GetItemCount(itemid,true) < qinfo->ReqCreatureOrGOCount[idx] * qinfo->ReqSourceCount[j]) + return true; + } + // spell with SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT (with script) case + else if(qinfo->ReqSpell[idx] != 0) + { + // not casted and need more reagents/item for use. + if(!q_status.m_explored && GetItemCount(itemid,true) < qinfo->ReqSourceCount[j]) + return true; + } + } + } + } + } + return false; +} + +void Player::SendQuestComplete( uint32 quest_id ) +{ + if( quest_id ) + { + WorldPacket data( SMSG_QUESTUPDATE_COMPLETE, 4 ); + data << quest_id; + GetSession()->SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id ); + } +} + +void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGiver ) +{ + uint32 questid = pQuest->GetQuestId(); + sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid ); + WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4+4+pQuest->GetRewItemsCount()*8) ); + data << questid; + data << uint32(0x03); + + if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) + { + data << XP; + data << uint32(pQuest->GetRewOrReqMoney()); + } + else + { + data << uint32(0); + data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY))); + } + data << uint32(0); // new 2.3.0, HonorPoints? + data << uint32( pQuest->GetRewItemsCount() ); // max is 5 + + for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i) + { + if ( pQuest->RewItemId[i] > 0 ) + data << pQuest->RewItemId[i] << pQuest->RewItemCount[i]; + else + data << uint32(0) << uint32(0); + } + GetSession()->SendPacket( &data ); + + if (pQuest->GetQuestCompleteScript() != 0) + sWorld.ScriptsStart(sQuestEndScripts, pQuest->GetQuestCompleteScript(), questGiver, this); +} + +void Player::SendQuestFailed( uint32 quest_id ) +{ + if( quest_id ) + { + WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 ); + data << quest_id; + GetSession()->SendPacket( &data ); + sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED"); + } +} + +void Player::SendQuestTimerFailed( uint32 quest_id ) +{ + if( quest_id ) + { + WorldPacket data( SMSG_QUESTUPDATE_FAILEDTIMER, 4 ); + data << quest_id; + GetSession()->SendPacket( &data ); + sLog.outDebug("WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER"); + } +} + +void Player::SendCanTakeQuestResponse( uint32 msg ) +{ + WorldPacket data( SMSG_QUESTGIVER_QUEST_INVALID, 4 ); + data << uint32(msg); + GetSession()->SendPacket( &data ); + sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID"); +} + +void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg ) +{ + if( pPlayer ) + { + WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1) ); + data << uint64(pPlayer->GetGUID()); + data << uint8(msg); // valid values: 0-8 + GetSession()->SendPacket( &data ); + sLog.outDebug("WORLD: Sent MSG_QUEST_PUSH_RESULT"); + } +} + +void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ) +{ + WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, (4+4) ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM" ); + data << pQuest->ReqItemId[item_idx]; + data << count; + GetSession()->SendPacket( &data ); +} + +void Player::SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count ) +{ + assert(old_count + add_count < 256 && "mob/GO count store in 8 bits 2^8 = 256 (0..256)"); + + int32 entry = pQuest->ReqCreatureOrGOId[ creatureOrGO_idx ]; + if (entry < 0) + // client expected gameobject template id in form (id|0x80000000) + entry = (-entry) | 0x80000000; + + WorldPacket data( SMSG_QUESTUPDATE_ADD_KILL, (4*4+8) ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_KILL" ); + data << uint32(pQuest->GetQuestId()); + data << uint32(entry); + data << uint32(old_count + add_count); + data << uint32(pQuest->ReqCreatureOrGOCount[ creatureOrGO_idx ]); + data << uint64(guid); + GetSession()->SendPacket(&data); + + uint16 log_slot = FindQuestSlot( pQuest->GetQuestId() ); + if( log_slot < MAX_QUEST_LOG_SIZE) + SetQuestSlotCounter(log_slot,creatureOrGO_idx,GetQuestSlotCounter(log_slot,creatureOrGO_idx)+add_count); +} + +/*********************************************************/ +/*** LOAD SYSTEM ***/ +/*********************************************************/ + +bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) +{ + bool delete_result = true; + if(!result) + { + // 0 1 2 3 4 5 6 7 8 + result = CharacterDatabase.PQuery("SELECT data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); + if(!result) return false; + } + else delete_result = false; + + Field *fields = result->Fetch(); + + if(!LoadValues( fields[0].GetString())) + { + sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); + if(delete_result) delete result; + return false; + } + + // overwrite possible wrong/corrupted guid + SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); + + m_name = fields[1].GetCppString(); + + Relocate(fields[2].GetFloat(),fields[3].GetFloat(),fields[4].GetFloat()); + SetMapId(fields[5].GetUInt32()); + // the instance id is not needed at character enum + + m_Played_time[0] = fields[6].GetUInt32(); + m_Played_time[1] = fields[7].GetUInt32(); + + m_atLoginFlags = fields[8].GetUInt32(); + + // I don't see these used anywhere .. + /*_LoadGroup(); + + _LoadBoundInstances();*/ + + if (delete_result) delete result; + + for (int i = 0; i < PLAYER_SLOTS_COUNT; i++) + m_items[i] = NULL; + + if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) ) + m_deathState = DEAD; + + return true; +} + +void Player::_LoadDeclinedNames(QueryResult* result) +{ + if(!result) + return; + + if(m_declinedname) + delete m_declinedname; + + m_declinedname = new DeclinedName; + Field *fields = result->Fetch(); + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + m_declinedname->name[i] = fields[i].GetCppString(); + + delete result; +} + +bool Player::LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid) +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,taxi_path FROM characters WHERE guid = '%u'",GUID_LOPART(guid)); + if(!result) + return false; + + Field *fields = result->Fetch(); + + x = fields[0].GetFloat(); + y = fields[1].GetFloat(); + z = fields[2].GetFloat(); + o = fields[3].GetFloat(); + mapid = fields[4].GetUInt32(); + in_flight = !fields[5].GetCppString().empty(); + + delete result; + return true; +} + +bool Player::LoadValuesArrayFromDB(Tokens& data, uint64 guid) +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT data FROM characters WHERE guid='%u'",GUID_LOPART(guid)); + if( !result ) + return false; + + Field *fields = result->Fetch(); + + data = StrSplit(fields[0].GetCppString(), " "); + + delete result; + + return true; +} + +uint32 Player::GetUInt32ValueFromArray(Tokens const& data, uint16 index) +{ + if(index >= data.size()) + return 0; + + return (uint32)atoi(data[index].c_str()); +} + +float Player::GetFloatValueFromArray(Tokens const& data, uint16 index) +{ + float result; + uint32 temp = Player::GetUInt32ValueFromArray(data,index); + memcpy(&result, &temp, sizeof(result)); + + return result; +} + +uint32 Player::GetUInt32ValueFromDB(uint16 index, uint64 guid) +{ + Tokens data; + if(!LoadValuesArrayFromDB(data,guid)) + return 0; + + return GetUInt32ValueFromArray(data,index); +} + +float Player::GetFloatValueFromDB(uint16 index, uint64 guid) +{ + float result; + uint32 temp = Player::GetUInt32ValueFromDB(index, guid); + memcpy(&result, &temp, sizeof(result)); + + return result; +} + +bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) +{ + //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 + //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, gmstate, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", guid); + QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM); + + if(!result) + { + sLog.outError("ERROR: Player (GUID: %u) not found in table `characters`, can't load. ",guid); + return false; + } + + Field *fields = result->Fetch(); + + uint32 dbAccountId = fields[1].GetUInt32(); + + // check if the character's account in the db and the logged in account match. + // player should be able to load/delete character only with correct account! + if( dbAccountId != GetSession()->GetAccountId() ) + { + sLog.outError("ERROR: Player (GUID: %u) loading from wrong account (is: %u, should be: %u)",guid,GetSession()->GetAccountId(),dbAccountId); + delete result; + return false; + } + + Object::_Create( guid, 0, HIGHGUID_PLAYER ); + + m_name = fields[3].GetCppString(); + + // check name limitations + if(!ObjectMgr::IsValidName(m_name) || GetSession()->GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(m_name)) + { + delete result; + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid ='%u'", uint32(AT_LOGIN_RENAME),guid); + return false; + } + + if(!LoadValues( fields[2].GetString())) + { + sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); + delete result; + return false; + } + + // overwrite possible wrong/corrupted guid + SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); + + // cleanup inventory related item value fields (its will be filled correctly in _LoadInventory) + for(uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) + { + SetUInt64Value( (uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2) ), 0 ); + SetVisibleItemSlot(slot,NULL); + + if (m_items[slot]) + { + delete m_items[slot]; + m_items[slot] = NULL; + } + } + + // update money limits + if(GetMoney() > MAX_MONEY_AMOUNT) + SetMoney(MAX_MONEY_AMOUNT); + + sLog.outDebug("Load Basic value of player %s is: ", m_name.c_str()); + outDebugValues(); + + m_race = fields[4].GetUInt8(); + //Need to call it to initialize m_team (m_team can be calculated from m_race) + //Other way is to saves m_team into characters table. + setFactionForRace(m_race); + SetCharm(0); + + m_class = fields[5].GetUInt8(); + + PlayerInfo const *info = objmgr.GetPlayerInfo(m_race, m_class); + if(!info) + { + sLog.outError("Player have incorrect race/class pair. Can't be loaded."); + delete result; + return false; + } + + InitPrimaryProffesions(); // to max set before any spell loaded + + uint32 transGUID = fields[24].GetUInt32(); + Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat()); + SetMapId(fields[9].GetUInt32()); + SetDifficulty(fields[32].GetUInt32()); // may be changed in _LoadGroup + + _LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP)); + + // check arena teams integrity + for(uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) + { + uint32 arena_team_id = GetArenaTeamId(arena_slot); + if(!arena_team_id) + continue; + + if(ArenaTeam * at = objmgr.GetArenaTeamById(arena_team_id)) + if(at->HaveMember(GetGUID())) + continue; + + // arena team not exist or not member, cleanup fields + for(int j =0; j < 6; ++j) + SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arena_slot * 6 + j, 0); + } + + _LoadBoundInstances(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES)); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); + + SetMapId(info->mapId); + Relocate(info->positionX,info->positionY,info->positionZ,0.0f); + + transGUID = 0; + + m_movementInfo.t_x = 0.0f; + m_movementInfo.t_y = 0.0f; + m_movementInfo.t_z = 0.0f; + m_movementInfo.t_o = 0.0f; + } + + // load the player's map here if it's not already loaded + Map *map = GetMap(); + // since the player may not be bound to the map yet, make sure subsequent + // getmap calls won't create new maps + SetInstanceId(map->GetInstanceId()); + + SaveRecallPosition(); + + if (transGUID != 0) + { + m_movementInfo.t_x = fields[20].GetFloat(); + m_movementInfo.t_y = fields[21].GetFloat(); + m_movementInfo.t_z = fields[22].GetFloat(); + m_movementInfo.t_o = fields[23].GetFloat(); + + if( !MaNGOS::IsValidMapCoord( + GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y, + GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o) || + // transport size limited + m_movementInfo.t_x > 50 || m_movementInfo.t_y > 50 || m_movementInfo.t_z > 50 ) + { + sLog.outError("ERROR: Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.", + guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y, + GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o); + + SetMapId(info->mapId); + Relocate(info->positionX,info->positionY,info->positionZ,0.0f); + + m_movementInfo.t_x = 0.0f; + m_movementInfo.t_y = 0.0f; + m_movementInfo.t_z = 0.0f; + m_movementInfo.t_o = 0.0f; + + transGUID = 0; + } + } + + if (transGUID != 0) + { + for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter) + { + if( (*iter)->GetGUIDLow() == transGUID) + { + m_transport = *iter; + m_transport->AddPassenger(this); + SetMapId(m_transport->GetMapId()); + break; + } + } + + if(!m_transport) + { + sLog.outError("ERROR: Player (guidlow %d) have invalid transport guid (%u). Teleport to default race/class locations.", + guid,transGUID); + + SetMapId(info->mapId); + Relocate(info->positionX,info->positionY,info->positionZ,0.0f); + + m_movementInfo.t_x = 0.0f; + m_movementInfo.t_y = 0.0f; + m_movementInfo.t_z = 0.0f; + m_movementInfo.t_o = 0.0f; + + transGUID = 0; + } + } + + time_t now = time(NULL); + time_t logoutTime = time_t(fields[16].GetUInt64()); + + // since last logout (in seconds) + uint64 time_diff = uint64(now - logoutTime); + + // set value, including drunk invisibility detection + // calculate sobering. after 15 minutes logged out, the player will be sober again + float soberFactor; + if(time_diff > 15*MINUTE) + soberFactor = 0; + else + soberFactor = 1-time_diff/(15.0f*MINUTE); + uint16 newDrunkenValue = uint16(soberFactor*(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE)); + SetDrunkValue(newDrunkenValue); + + m_rest_bonus = fields[15].GetFloat(); + //speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour) + float bubble0 = 0.031; + //speed collect rest bonus in offline, in logout, in tavern, city (section/in hour) + float bubble1 = 0.125; + + if((int32)fields[16].GetUInt32() > 0) + { + float bubble = fields[17].GetUInt32() > 0 + ? bubble1*sWorld.getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY) + : bubble0*sWorld.getRate(RATE_REST_OFFLINE_IN_WILDERNESS); + + SetRestBonus(GetRestBonus()+ time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble); + } + + m_cinematic = fields[12].GetUInt32(); + m_Played_time[0]= fields[13].GetUInt32(); + m_Played_time[1]= fields[14].GetUInt32(); + + m_resetTalentsCost = fields[18].GetUInt32(); + m_resetTalentsTime = time_t(fields[19].GetUInt64()); + + // reserve some flags + uint32 old_safe_flags = GetUInt32Value(PLAYER_FLAGS) & ( PLAYER_FLAGS_HIDE_CLOAK | PLAYER_FLAGS_HIDE_HELM ); + + if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM) ) + SetUInt32Value(PLAYER_FLAGS, 0 | old_safe_flags); + + m_taxi.LoadTaxiMask( fields[11].GetString() ); // must be before InitTaxiNodesForLevel + + uint32 gmstate = fields[25].GetUInt32(); + + m_stableSlots = fields[26].GetUInt32(); + if(m_stableSlots > 2) + { + sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots)); + m_stableSlots = 2; + } + + m_atLoginFlags = fields[27].GetUInt32(); + + // Honor system + // Update Honor kills data + m_lastHonorUpdateTime = logoutTime; + UpdateHonorFields(); + + m_deathExpireTime = (time_t)fields[30].GetUInt64(); + if(m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP) + m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1; + + std::string taxi_nodes = fields[31].GetCppString(); + + delete result; + + // clear channel spell data (if saved at channel spell casting) + SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, 0); + SetUInt32Value(UNIT_CHANNEL_SPELL,0); + + // clear charm/summon related fields + SetUInt64Value(UNIT_FIELD_CHARM,0); + SetUInt64Value(UNIT_FIELD_SUMMON,0); + SetUInt64Value(UNIT_FIELD_CHARMEDBY,0); + SetUInt64Value(UNIT_FIELD_SUMMONEDBY,0); + SetUInt64Value(UNIT_FIELD_CREATEDBY,0); + + // reset some aura modifiers before aura apply + SetUInt64Value(PLAYER_FARSIGHT, 0); + SetUInt32Value(PLAYER_TRACK_CREATURES, 0 ); + SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 ); + + // reset skill modifiers and set correct unlearn flags + for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++) + { + SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0); + + // set correct unlearn bit + uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF; + if(!id) continue; + + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id); + if(!pSkill) continue; + + // enable unlearn button for primary professions only + if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION) + SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1)); + else + SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0)); + } + + // make sure the unit is considered out of combat for proper loading + ClearInCombat(); + + // make sure the unit is considered not in duel for proper loading + SetUInt64Value(PLAYER_DUEL_ARBITER, 0); + SetUInt32Value(PLAYER_DUEL_TEAM, 0); + + // remember loaded power/health values to restore after stats initialization and modifier applying + uint32 savedHealth = GetHealth(); + uint32 savedPower[MAX_POWERS]; + for(uint32 i = 0; i < MAX_POWERS; ++i) + savedPower[i] = GetPower(Powers(i)); + + // reset stats before loading any modifiers + InitStatsForLevel(); + InitTaxiNodesForLevel(); + + // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() + + //mails are loaded only when needed ;-) - when player in game click on mailbox. + //_LoadMail(); + + _LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff); + + // add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura) + if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) ) + m_deathState = DEAD; + + _LoadSpells(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLS)); + + // after spell load + InitTalentForLevel(); + learnSkillRewardedSpells(); + + // after spell load, learn rewarded spell if need also + _LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS)); + _LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS)); + + _LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS)); + + // must be before inventory (some items required reputation check) + _LoadReputation(holder->GetResult(PLAYER_LOGIN_QUERY_LOADREPUTATION)); + + _LoadInventory(holder->GetResult(PLAYER_LOGIN_QUERY_LOADINVENTORY), time_diff); + + // update items with duration and realtime + UpdateItemDuration(time_diff, true); + + _LoadActions(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACTIONS)); + + // unread mails and next delivery time, actual mails not loaded + _LoadMailInit(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILCOUNT), holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILDATE)); + + m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow()); + + if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND))) + return false; + + // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES + // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded + if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE)) + { + if(!HasFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << curTitle)) + SetUInt32Value(PLAYER_CHOSEN_TITLE,0); + } + + // Not finish taxi flight path + if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes)) + { + // problems with taxi path loading + TaxiNodesEntry const* nodeEntry = NULL; + if(uint32 node_id = m_taxi.GetTaxiSource()) + nodeEntry = sTaxiNodesStore.LookupEntry(node_id); + + if(!nodeEntry) // don't know taxi start node, to homebind + { + sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow()); + SetMapId(m_homebindMapId); + Relocate( m_homebindX, m_homebindY, m_homebindZ,0.0f); + SaveRecallPosition(); // save as recall also to prevent recall and fall from sky + } + else // have start node, to it + { + sLog.outError("Character %u have too short taxi destination list, teleport to original node.",GetGUIDLow()); + SetMapId(nodeEntry->map_id); + Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f); + SaveRecallPosition(); // save as recall also to prevent recall and fall from sky + } + m_taxi.ClearTaxiDestinations(); + } + else if(uint32 node_id = m_taxi.GetTaxiSource()) + { + // save source node as recall coord to prevent recall and fall from sky + TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(node_id); + assert(nodeEntry); // checked in m_taxi.LoadTaxiDestinationsFromString + m_recallMap = nodeEntry->map_id; + m_recallX = nodeEntry->x; + m_recallY = nodeEntry->y; + m_recallZ = nodeEntry->z; + + // flight will started later + } + + _LoadSpellCooldowns(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS)); + + // Spell code allow apply any auras to dead character in load time in aura/spell/item loading + // Do now before stats re-calculation cleanup for ghost state unexpected auras + if(!isAlive()) + RemoveAllAurasOnDeath(); + + //apply all stat bonuses from items and auras + SetCanModifyStats(true); + UpdateAllStats(); + + // restore remembered power/health values (but not more max values) + SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth); + for(uint32 i = 0; i < MAX_POWERS; ++i) + SetPower(Powers(i),savedPower[i] > GetMaxPower(Powers(i)) ? GetMaxPower(Powers(i)) : savedPower[i]); + + sLog.outDebug("The value of player %s after load item and aura is: ", m_name.c_str()); + outDebugValues(); + + // GM state + if(GetSession()->GetSecurity() > SEC_PLAYER) + { + switch(sWorld.getConfig(CONFIG_GM_LOGIN_STATE)) + { + default: + case 0: break; // disable + case 1: SetGameMaster(true); break; // enable + case 2: // save state + if(gmstate & PLAYER_EXTRA_GM_ON) + SetGameMaster(true); + break; + } + + switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS)) + { + default: + case 0: break; // disable + case 1: SetAcceptTicket(true); break; // enable + case 2: // save state + if(gmstate & PLAYER_EXTRA_GM_ACCEPT_TICKETS) + SetAcceptTicket(true); + break; + } + + switch(sWorld.getConfig(CONFIG_GM_CHAT)) + { + default: + case 0: break; // disable + case 1: SetGMChat(true); break; // enable + case 2: // save state + if(gmstate & PLAYER_EXTRA_GM_CHAT) + SetGMChat(true); + break; + } + + switch(sWorld.getConfig(CONFIG_GM_WISPERING_TO)) + { + default: + case 0: break; // disable + case 1: SetAcceptWhispers(true); break; // enable + case 2: // save state + if(gmstate & PLAYER_EXTRA_ACCEPT_WHISPERS) + SetAcceptWhispers(true); + break; + } + } + + _LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES)); + + return true; +} + +bool Player::isAllowedToLoot(Creature* creature) +{ + if(Player* recipient = creature->GetLootRecipient()) + { + if (recipient == this) + return true; + if( Group* otherGroup = recipient->GetGroup()) + { + Group* thisGroup = GetGroup(); + if(!thisGroup) + return false; + return thisGroup == otherGroup; + } + return false; + } + else + // prevent other players from looting if the recipient got disconnected + return !creature->hasLootRecipient(); +} + +void Player::_LoadActions(QueryResult *result) +{ + m_actionButtons.clear(); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button",GetGUIDLow()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + uint8 button = fields[0].GetUInt8(); + + addActionButton(button, fields[1].GetUInt16(), fields[2].GetUInt8(), fields[3].GetUInt8()); + + m_actionButtons[button].uState = ACTIONBUTTON_UNCHANGED; + } + while( result->NextRow() ); + + delete result; + } +} + +void Player::_LoadAuras(QueryResult *result, uint32 timediff) +{ + m_Auras.clear(); + for (int i = 0; i < TOTAL_AURAS; i++) + m_modAuras[i].clear(); + + // all aura related fields + for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) + SetUInt32Value(i, 0); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint64 caster_guid = fields[0].GetUInt64(); + uint32 spellid = fields[1].GetUInt32(); + uint32 effindex = fields[2].GetUInt32(); + int32 damage = (int32)fields[3].GetUInt32(); + int32 maxduration = (int32)fields[4].GetUInt32(); + int32 remaintime = (int32)fields[5].GetUInt32(); + int32 remaincharges = (int32)fields[6].GetUInt32(); + + SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); + if(!spellproto) + { + sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex); + continue; + } + + if(effindex >= 3) + { + sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex); + continue; + } + + // negative effects should continue counting down after logout + if (remaintime != -1 && !IsPositiveEffect(spellid, effindex)) + { + if(remaintime <= int32(timediff)) + continue; + + remaintime -= timediff; + } + + // prevent wrong values of remaincharges + if(spellproto->procCharges) + { + if(remaincharges <= 0 || remaincharges > spellproto->procCharges) + remaincharges = spellproto->procCharges; + } + else + remaincharges = -1; + + //do not load single target auras (unless they were cast by the player) + if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto)) + continue; + + Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); + if(!damage) + damage = aura->GetModifier()->m_amount; + aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); + AddAura(aura); + } + while( result->NextRow() ); + + delete result; + } + + if(m_class == CLASS_WARRIOR) + CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); +} + +void Player::LoadCorpse() +{ + if( isAlive() ) + { + ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID()); + } + else + { + if(Corpse *corpse = GetCorpse()) + { + ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, corpse && !sMapStore.LookupEntry(corpse->GetMapId())->Instanceable() ); + } + else + { + //Prevent Dead Player login without corpse + ResurrectPlayer(0.5f); + } + } +} + +void Player::_LoadInventory(QueryResult *result, uint32 timediff) +{ + //QueryResult *result = CharacterDatabase.PQuery("SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GetGUIDLow()); + std::map bagMap; // fast guid lookup for bags + //NOTE: the "order by `bag`" is important because it makes sure + //the bagMap is filled before items in the bags are loaded + //NOTE2: the "order by `slot`" is needed becaue mainhand weapons are (wrongly?) + //expected to be equipped before offhand items (TODO: fixme) + + uint32 zone = GetZoneId(); + + if (result) + { + std::list problematicItems; + + // prevent items from being added to the queue when stored + m_itemUpdateQueueBlocked = true; + do + { + Field *fields = result->Fetch(); + uint32 bag_guid = fields[1].GetUInt32(); + uint8 slot = fields[2].GetUInt8(); + uint32 item_guid = fields[3].GetUInt32(); + uint32 item_id = fields[4].GetUInt32(); + + ItemPrototype const * proto = objmgr.GetItemPrototype(item_id); + + if(!proto) + { + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guid); + sLog.outError( "Player::_LoadInventory: Player %s has an unknown item (id: #%u) in inventory, deleted.", GetName(),item_id ); + continue; + } + + Item *item = NewItemOrBag(proto); + + if(!item->LoadFromDB(item_guid, GetGUID(), result)) + { + sLog.outError( "Player::_LoadInventory: Player %s has broken item (id: #%u) in inventory, deleted.", GetName(),item_id ); + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); + item->FSetState(ITEM_REMOVED); + item->SaveToDB(); // it also deletes item object ! + continue; + } + + // not allow have in alive state item limited to another map/zone + if(isAlive() && item->IsLimitedToAnotherMapOrZone(GetMapId(),zone) ) + { + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); + item->FSetState(ITEM_REMOVED); + item->SaveToDB(); // it also deletes item object ! + continue; + } + + // "Conjured items disappear if you are logged out for more than 15 minutes" + if ((timediff > 15*60) && (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED))) + { + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); + item->FSetState(ITEM_REMOVED); + item->SaveToDB(); // it also deletes item object ! + continue; + } + + bool success = true; + + if (!bag_guid) + { + // the item is not in a bag + item->SetContainer( NULL ); + item->SetSlot(slot); + + if( IsInventoryPos( INVENTORY_SLOT_BAG_0, slot ) ) + { + ItemPosCountVec dest; + if( CanStoreItem( INVENTORY_SLOT_BAG_0, slot, dest, item, false ) == EQUIP_ERR_OK ) + item = StoreItem(dest, item, true); + else + success = false; + } + else if( IsEquipmentPos( INVENTORY_SLOT_BAG_0, slot ) ) + { + uint16 dest; + if( CanEquipItem( slot, dest, item, false, false ) == EQUIP_ERR_OK ) + QuickEquipItem(dest, item); + else + success = false; + } + else if( IsBankPos( INVENTORY_SLOT_BAG_0, slot ) ) + { + ItemPosCountVec dest; + if( CanBankItem( INVENTORY_SLOT_BAG_0, slot, dest, item, false, false ) == EQUIP_ERR_OK ) + item = BankItem(dest, item, true); + else + success = false; + } + + if(success) + { + // store bags that may contain items in them + if(item->IsBag() && IsBagPos(item->GetPos())) + bagMap[item_guid] = (Bag*)item; + } + } + else + { + item->SetSlot(NULL_SLOT); + // the item is in a bag, find the bag + std::map::iterator itr = bagMap.find(bag_guid); + if(itr != bagMap.end()) + itr->second->StoreItem(slot, item, true ); + else + success = false; + } + + // item's state may have changed after stored + if (success) + item->SetState(ITEM_UNCHANGED, this); + else + { + sLog.outError("Player::_LoadInventory: Player %s has item (GUID: %u Entry: %u) can't be loaded to inventory (Bag GUID: %u Slot: %u) by some reason, will send by mail.", GetName(),item_guid, item_id, bag_guid, slot); + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); + problematicItems.push_back(item); + } + } while (result->NextRow()); + + delete result; + m_itemUpdateQueueBlocked = false; + + // send by mail problematic items + while(!problematicItems.empty()) + { + // fill mail + MailItemsInfo mi; // item list prepering + + for(int i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i) + { + Item* item = problematicItems.front(); + problematicItems.pop_front(); + + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + } + + std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM); + + WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); + } + } + //if(isAlive()) + _ApplyAllItemMods(); +} + +// load mailed item which should receive current player +void Player::_LoadMailedItems(Mail *mail) +{ + QueryResult* result = CharacterDatabase.PQuery("SELECT item_guid, item_template FROM mail_items WHERE mail_id='%u'", mail->messageID); + if(!result) + return; + + do + { + Field *fields = result->Fetch(); + uint32 item_guid_low = fields[0].GetUInt32(); + uint32 item_template = fields[1].GetUInt32(); + + mail->AddItem(item_guid_low, item_template); + + ItemPrototype const *proto = objmgr.GetItemPrototype(item_template); + + if(!proto) + { + sLog.outError( "Player %u have unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), item_guid_low, item_template,mail->messageID); + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low); + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guid_low); + continue; + } + + Item *item = NewItemOrBag(proto); + + if(!item->LoadFromDB(item_guid_low, 0)) + { + sLog.outError( "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low); + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low); + item->FSetState(ITEM_REMOVED); + item->SaveToDB(); // it also deletes item object ! + continue; + } + + AddMItem(item); + } while (result->NextRow()); + + delete result; +} + +void Player::_LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery) +{ + //set a count of unread mails + //QueryResult *resultMails = CharacterDatabase.PQuery("SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" I64FMTD "'", GUID_LOPART(playerGuid),(uint64)cTime); + if (resultUnread) + { + Field *fieldMail = resultUnread->Fetch(); + unReadMails = fieldMail[0].GetUInt8(); + delete resultUnread; + } + + // store nearest delivery time (it > 0 and if it < current then at next player update SendNewMaill will be called) + //resultMails = CharacterDatabase.PQuery("SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(playerGuid)); + if (resultDelivery) + { + Field *fieldMail = resultDelivery->Fetch(); + m_nextMailDelivereTime = (time_t)fieldMail[0].GetUInt64(); + delete resultDelivery; + } +} + +void Player::_LoadMail() +{ + m_mail.clear(); + //mails are in right order 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + QueryResult *result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC",GetGUIDLow()); + if(result) + { + do + { + Field *fields = result->Fetch(); + Mail *m = new Mail; + m->messageID = fields[0].GetUInt32(); + m->messageType = fields[1].GetUInt8(); + m->sender = fields[2].GetUInt32(); + m->receiver = fields[3].GetUInt32(); + m->subject = fields[4].GetCppString(); + m->itemTextId = fields[5].GetUInt32(); + bool has_items = fields[6].GetBool(); + m->expire_time = (time_t)fields[7].GetUInt64(); + m->deliver_time = (time_t)fields[8].GetUInt64(); + m->money = fields[9].GetUInt32(); + m->COD = fields[10].GetUInt32(); + m->checked = fields[11].GetUInt32(); + m->stationery = fields[12].GetUInt8(); + m->mailTemplateId = fields[13].GetInt16(); + + if(m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId)) + { + sLog.outError( "Player::_LoadMail - Mail (%u) have not existed MailTemplateId (%u), remove at load", m->messageID, m->mailTemplateId); + m->mailTemplateId = 0; + } + + m->state = MAIL_STATE_UNCHANGED; + + if (has_items) + _LoadMailedItems(m); + + m_mail.push_back(m); + } while( result->NextRow() ); + delete result; + } + m_mailsLoaded = true; +} + +void Player::LoadPet() +{ + //fixme: the pet should still be loaded if the player is not in world + // just not added to the map + if(IsInWorld()) + { + Pet *pet = new Pet; + if(!pet->LoadPetFromDB(this,0,0,true)) + delete pet; + } +} + +void Player::_LoadQuestStatus(QueryResult *result) +{ + mQuestStatus.clear(); + + uint32 slot = 0; + + //// 0 1 2 3 4 5 6 7 8 9 10 11 12 + //QueryResult *result = CharacterDatabase.PQuery("SELECT quest, status, rewarded, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, itemcount1, itemcount2, itemcount3, itemcount4 FROM character_queststatus WHERE guid = '%u'", GetGUIDLow()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + uint32 quest_id = fields[0].GetUInt32(); + // used to be new, no delete? + Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + if( pQuest ) + { + // find or create + QuestStatusData& questStatusData = mQuestStatus[quest_id]; + + uint32 qstatus = fields[1].GetUInt32(); + if(qstatus < MAX_QUEST_STATUS) + questStatusData.m_status = QuestStatus(qstatus); + else + { + questStatusData.m_status = QUEST_STATUS_NONE; + sLog.outError("Player %s have invalid quest %d status (%d), replaced by QUEST_STATUS_NONE(0).",GetName(),quest_id,qstatus); + } + + questStatusData.m_rewarded = ( fields[2].GetUInt8() > 0 ); + questStatusData.m_explored = ( fields[3].GetUInt8() > 0 ); + + time_t quest_time = time_t(fields[4].GetUInt64()); + + if( pQuest->HasFlag( QUEST_MANGOS_FLAGS_TIMED ) && !GetQuestRewardStatus(quest_id) && questStatusData.m_status != QUEST_STATUS_NONE ) + { + AddTimedQuest( quest_id ); + + if (quest_time <= sWorld.GetGameTime()) + questStatusData.m_timer = 1; + else + questStatusData.m_timer = (quest_time - sWorld.GetGameTime()) * 1000; + } + else + quest_time = 0; + + questStatusData.m_creatureOrGOcount[0] = fields[5].GetUInt32(); + questStatusData.m_creatureOrGOcount[1] = fields[6].GetUInt32(); + questStatusData.m_creatureOrGOcount[2] = fields[7].GetUInt32(); + questStatusData.m_creatureOrGOcount[3] = fields[8].GetUInt32(); + questStatusData.m_itemcount[0] = fields[9].GetUInt32(); + questStatusData.m_itemcount[1] = fields[10].GetUInt32(); + questStatusData.m_itemcount[2] = fields[11].GetUInt32(); + questStatusData.m_itemcount[3] = fields[12].GetUInt32(); + + questStatusData.uState = QUEST_UNCHANGED; + + // add to quest log + if( slot < MAX_QUEST_LOG_SIZE && + ( questStatusData.m_status==QUEST_STATUS_INCOMPLETE || + questStatusData.m_status==QUEST_STATUS_COMPLETE && !questStatusData.m_rewarded ) ) + { + SetQuestSlot(slot,quest_id,quest_time); + + if(questStatusData.m_status == QUEST_STATUS_COMPLETE) + SetQuestSlotState(slot,QUEST_STATE_COMPLETE); + + for(uint8 idx = 0; idx < QUEST_OBJECTIVES_COUNT; ++idx) + if(questStatusData.m_creatureOrGOcount[idx]) + SetQuestSlotCounter(slot,idx,questStatusData.m_creatureOrGOcount[idx]); + + ++slot; + } + + if(questStatusData.m_rewarded) + { + // learn rewarded spell if unknown + learnQuestRewardedSpells(pQuest); + + // set rewarded title if any + if(pQuest->GetCharTitleId()) + { + if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId())) + SetFlag64(PLAYER__FIELD_KNOWN_TITLES, (uint64(1) << titleEntry->bit_index)); + } + } + + sLog.outDebug("Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.m_status, quest_id, GetGUIDLow()); + } + } + while( result->NextRow() ); + + delete result; + } + + // clear quest log tail + for ( uint16 i = slot; i < MAX_QUEST_LOG_SIZE; ++i ) + SetQuestSlot(i,0); +} + +void Player::_LoadDailyQuestStatus(QueryResult *result) +{ + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) + SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx,0); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GetGUIDLow()); + + if(result) + { + uint32 quest_daily_idx = 0; + + do + { + if(quest_daily_idx >= PLAYER_MAX_DAILY_QUESTS) // max amount with exist data in query + { + sLog.outError("Player (GUID: %u) have more 25 daily quest records in `charcter_queststatus_daily`",GetGUIDLow()); + break; + } + + Field *fields = result->Fetch(); + + uint32 quest_id = fields[0].GetUInt32(); + + // save _any_ from daily quest times (it must be after last reset anyway) + m_lastDailyQuestTime = (time_t)fields[1].GetUInt64(); + + Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + if( !pQuest ) + continue; + + SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx,quest_id); + ++quest_daily_idx; + + sLog.outDebug("Daily quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow()); + } + while( result->NextRow() ); + + delete result; + } + + m_DailyQuestChanged = false; +} + +void Player::_LoadReputation(QueryResult *result) +{ + m_factions.clear(); + + // Set initial reputations (so everything is nifty before DB data load) + SetInitialFactions(); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'",GetGUIDLow()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + FactionEntry const *factionEntry = sFactionStore.LookupEntry(fields[0].GetUInt32()); + if( factionEntry && (factionEntry->reputationListID >= 0)) + { + FactionState* faction = &m_factions[factionEntry->reputationListID]; + + // update standing to current + faction->Standing = int32(fields[1].GetUInt32()); + + uint32 dbFactionFlags = fields[2].GetUInt32(); + + if( dbFactionFlags & FACTION_FLAG_VISIBLE ) + SetFactionVisible(faction); // have internal checks for forced invisibility + + if( dbFactionFlags & FACTION_FLAG_INACTIVE) + SetFactionInactive(faction,true); // have internal checks for visibility requirement + + if( dbFactionFlags & FACTION_FLAG_AT_WAR ) // DB at war + SetFactionAtWar(faction,true); // have internal checks for FACTION_FLAG_PEACE_FORCED + else // DB not at war + { + // allow remove if visible (and then not FACTION_FLAG_INVISIBLE_FORCED or FACTION_FLAG_HIDDEN) + if( faction->Flags & FACTION_FLAG_VISIBLE ) + SetFactionAtWar(faction,false); // have internal checks for FACTION_FLAG_PEACE_FORCED + } + + // set atWar for hostile + if(GetReputationRank(factionEntry) <= REP_HOSTILE) + SetFactionAtWar(faction,true); + + // reset changed flag if values similar to saved in DB + if(faction->Flags==dbFactionFlags) + faction->Changed = false; + } + } + while( result->NextRow() ); + + delete result; + } +} + +void Player::_LoadSpells(QueryResult *result) +{ + for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + delete itr->second; + m_spells.clear(); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,slot,active FROM character_spell WHERE guid = '%u'",GetGUIDLow()); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + addSpell(fields[0].GetUInt16(), fields[2].GetBool(), false, true, fields[1].GetUInt16(), fields[3].GetBool()); + } + while( result->NextRow() ); + + delete result; + } +} + +void Player::_LoadTutorials(QueryResult *result) +{ + //QueryResult *result = CharacterDatabase.PQuery("SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetAccountId(), realmid); + + if(result) + { + do + { + Field *fields = result->Fetch(); + + for (int iI=0; iI<8; iI++) + m_Tutorials[iI] = fields[iI].GetUInt32(); + } + while( result->NextRow() ); + + delete result; + } + + m_TutorialsChanged = false; +} + +void Player::_LoadGroup(QueryResult *result) +{ + //QueryResult *result = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", GetGUIDLow()); + if(result) + { + uint64 leaderGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); + delete result; + Group* group = objmgr.GetGroupByLeader(leaderGuid); + if(group) + { + uint8 subgroup = group->GetMemberGroup(GetGUID()); + SetGroup(group, subgroup); + if(getLevel() >= LEVELREQUIREMENT_HEROIC) + { + // the group leader may change the instance difficulty while the player is offline + SetDifficulty(group->GetDifficulty()); + } + } + } +} + +void Player::_LoadBoundInstances(QueryResult *result) +{ + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + m_boundInstances[i].clear(); + + Group *group = GetGroup(); + + //QueryResult *result = CharacterDatabase.PQuery("SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); + if(result) + { + do + { + Field *fields = result->Fetch(); + bool perm = fields[1].GetBool(); + uint32 mapId = fields[2].GetUInt32(); + uint32 instanceId = fields[0].GetUInt32(); + uint8 difficulty = fields[3].GetUInt8(); + time_t resetTime = (time_t)fields[4].GetUInt64(); + // the resettime for normal instances is only saved when the InstanceSave is unloaded + // so the value read from the DB may be wrong here but only if the InstanceSave is loaded + // and in that case it is not used + + if(!perm && group) + { + sLog.outError("_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d,%d,%d", GetName(), GetGUIDLow(), GUID_LOPART(group->GetLeaderGUID()), mapId, instanceId, difficulty); + CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId); + continue; + } + + // since non permanent binds are always solo bind, they can always be reset + InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapId, instanceId, difficulty, resetTime, !perm, true); + if(save) BindToInstance(save, perm, true); + } while(result->NextRow()); + delete result; + } +} + +InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, uint8 difficulty) +{ + // some instances only have one difficulty + const MapEntry* entry = sMapStore.LookupEntry(mapid); + if(!entry || !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); + if(itr != m_boundInstances[difficulty].end()) + return &itr->second; + else + return NULL; +} + +void Player::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload) +{ + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); + UnbindInstance(itr, difficulty, unload); +} + +void Player::UnbindInstance(BoundInstancesMap::iterator &itr, uint8 difficulty, bool unload) +{ + if(itr != m_boundInstances[difficulty].end()) + { + if(!unload) CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u' AND instance = '%u'", GetGUIDLow(), itr->second.save->GetInstanceId()); + itr->second.save->RemovePlayer(this); // save can become invalid + m_boundInstances[difficulty].erase(itr++); + } +} + +InstancePlayerBind* Player::BindToInstance(InstanceSave *save, bool permanent, bool load) +{ + if(save) + { + InstancePlayerBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()]; + if(bind.save) + { + // update the save when the group kills a boss + if(permanent != bind.perm || save != bind.save) + if(!load) CharacterDatabase.PExecute("UPDATE character_instance SET instance = '%u', permanent = '%u' WHERE guid = '%u' AND instance = '%u'", save->GetInstanceId(), permanent, GetGUIDLow(), bind.save->GetInstanceId()); + } + else + if(!load) CharacterDatabase.PExecute("INSERT INTO character_instance (guid, instance, permanent) VALUES ('%u', '%u', '%u')", GetGUIDLow(), save->GetInstanceId(), permanent); + + if(bind.save != save) + { + if(bind.save) bind.save->RemovePlayer(this); + save->AddPlayer(this); + } + + if(permanent) save->SetCanReset(false); + + bind.save = save; + bind.perm = permanent; + if(!load) sLog.outDebug("Player::BindToInstance: %s(%d) is now bound to map %d, instance %d, difficulty %d", GetName(), GetGUIDLow(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty()); + return &bind; + } + else + return NULL; +} + +void Player::SendRaidInfo() +{ + WorldPacket data(SMSG_RAID_INSTANCE_INFO, 4); + + uint32 counter = 0, i; + for(i = 0; i < TOTAL_DIFFICULTIES; i++) + for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); itr++) + if(itr->second.perm) counter++; + + data << counter; + for(i = 0; i < TOTAL_DIFFICULTIES; i++) + { + for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); itr++) + { + if(itr->second.perm) + { + InstanceSave *save = itr->second.save; + data << (save->GetMapId()); + data << (uint32)(save->GetResetTime() - time(NULL)); + data << save->GetInstanceId(); + data << uint32(counter); + counter--; + } + } + } + GetSession()->SendPacket(&data); +} + +/* +- called on every successful teleportation to a map +*/ +void Player::SendSavedInstances() +{ + bool hasBeenSaved = false; + WorldPacket data; + + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) + { + if(itr->second.perm) // only permanent binds are sent + { + hasBeenSaved = true; + break; + } + } + } + + //Send opcode 811. true or flase means, whether you have current raid/heroic instances + data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP); + data << uint32(hasBeenSaved); + GetSession()->SendPacket(&data); + + if(!hasBeenSaved) + return; + + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) + { + if(itr->second.perm) + { + data.Initialize(SMSG_UPDATE_LAST_INSTANCE); + data << uint32(itr->second.save->GetMapId()); + GetSession()->SendPacket(&data); + } + } + } +} + +/// convert the player's binds to the group +void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player_guid) +{ + bool has_binds = false; + bool has_solo = false; + + if(player) { player_guid = player->GetGUID(); if(!group) group = player->GetGroup(); } + assert(player_guid); + + // copy all binds to the group, when changing leader it's assumed the character + // will not have any solo binds + + if(player) + { + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + for (BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();) + { + has_binds = true; + if(group) group->BindToInstance(itr->second.save, itr->second.perm, true); + // permanent binds are not removed + if(!itr->second.perm) + { + player->UnbindInstance(itr, i, true); // increments itr + has_solo = true; + } + else + ++itr; + } + } + } + + // if the player's not online we don't know what binds it has + if(!player || !group || has_binds) CharacterDatabase.PExecute("INSERT INTO group_instance SELECT guid, instance, permanent FROM character_instance WHERE guid = '%u'", GUID_LOPART(player_guid)); + // the following should not get executed when changing leaders + if(!player || has_solo) CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND permanent = 0", GUID_LOPART(player_guid)); +} + +bool Player::_LoadHomeBind(QueryResult *result) +{ + bool ok = false; + //QueryResult *result = CharacterDatabase.PQuery("SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(playerGuid)); + if (result) + { + Field *fields = result->Fetch(); + m_homebindMapId = fields[0].GetUInt32(); + m_homebindZoneId = fields[1].GetUInt16(); + m_homebindX = fields[2].GetFloat(); + m_homebindY = fields[3].GetFloat(); + m_homebindZ = fields[4].GetFloat(); + delete result; + + // accept saved data only for valid position (and non instanceable) + if( MapManager::IsValidMapCoord(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ) && + !sMapStore.LookupEntry(m_homebindMapId)->Instanceable() ) + { + ok = true; + } + else + CharacterDatabase.PExecute("DELETE FROM character_homebind WHERE guid = '%u'", GetGUIDLow()); + } + + if(!ok) + { + PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass()); + if(!info) return false; + + m_homebindMapId = info->mapId; + m_homebindZoneId = info->zoneId; + m_homebindX = info->positionX; + m_homebindY = info->positionY; + m_homebindZ = info->positionZ; + + CharacterDatabase.PExecute("INSERT INTO character_homebind (guid,map,zone,position_x,position_y,position_z) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GetGUIDLow(), m_homebindMapId, (uint32)m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ); + } + + DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n", + m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ); + + return true; +} + +/*********************************************************/ +/*** SAVE SYSTEM ***/ +/*********************************************************/ + +void Player::SaveToDB() +{ + // delay auto save at any saves (manual, in code, or autosave) + m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE); + + // first save/honor gain after midnight will also update the player's honor fields + UpdateHonorFields(); + + // Must saved before enter into BattleGround + if(InBattleGround()) + return; + + int is_save_resting = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0; + //save, far from tavern/city + //save, but in tavern/city + sLog.outDebug("The value of player %s at save: ", m_name.c_str()); + outDebugValues(); + + // save state (after auras removing), if aura remove some flags then it must set it back by self) + uint32 tmp_bytes = GetUInt32Value(UNIT_FIELD_BYTES_1); + uint32 tmp_bytes2 = GetUInt32Value(UNIT_FIELD_BYTES_2); + uint32 tmp_flags = GetUInt32Value(UNIT_FIELD_FLAGS); + uint32 tmp_pflags = GetUInt32Value(PLAYER_FLAGS); + uint32 tmp_displayid = GetDisplayId(); + + // Set player sit state to standing on save, also stealth and shifted form + SetByteValue(UNIT_FIELD_BYTES_1, 0, 0); // stand state + SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift + SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); // stand flags? + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + SetDisplayId(GetNativeDisplayId()); + + bool inworld = IsInWorld(); + + CharacterDatabase.BeginTransaction(); + + CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",GetGUIDLow()); + + std::string sql_name = m_name; + CharacterDatabase.escape_string(sql_name); + + std::ostringstream ss; + ss << "INSERT INTO characters (guid,account,name,race,class," + "map, dungeon_difficulty, position_x, position_y, position_z, orientation, data, " + "taximask, online, cinematic, " + "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " + "trans_x, trans_y, trans_z, trans_o, transguid, gmstate, stable_slots, at_login, zone, " + "death_expire_time, taxi_path) VALUES (" + << GetGUIDLow() << ", " + << GetSession()->GetAccountId() << ", '" + << sql_name << "', " + << m_race << ", " + << m_class << ", "; + + bool save_to_dest = false; + if(IsBeingTeleported()) + { + // don't save to battlegrounds or arenas + const MapEntry *entry = sMapStore.LookupEntry(GetTeleportDest().mapid); + if(entry && entry->map_type != MAP_BATTLEGROUND && entry->map_type != MAP_ARENA) + save_to_dest = true; + } + + if(!save_to_dest) + { + ss << GetMapId() << ", " + << (uint32)GetDifficulty() << ", " + << finiteAlways(GetPositionX()) << ", " + << finiteAlways(GetPositionY()) << ", " + << finiteAlways(GetPositionZ()) << ", " + << finiteAlways(GetOrientation()) << ", '"; + } + else + { + ss << GetTeleportDest().mapid << ", " + << (uint32)GetDifficulty() << ", " + << finiteAlways(GetTeleportDest().x) << ", " + << finiteAlways(GetTeleportDest().y) << ", " + << finiteAlways(GetTeleportDest().z) << ", " + << finiteAlways(GetTeleportDest().o) << ", '"; + } + + uint16 i; + for( i = 0; i < m_valuesCount; i++ ) + { + ss << GetUInt32Value(i) << " "; + } + + ss << "', '"; + + for( i = 0; i < 8; i++ ) + ss << m_taxi.GetTaximask(i) << " "; + + ss << "', "; + ss << (inworld ? 1 : 0); + + ss << ", "; + ss << m_cinematic; + + ss << ", "; + ss << m_Played_time[0]; + ss << ", "; + ss << m_Played_time[1]; + + ss << ", "; + ss << finiteAlways(m_rest_bonus); + ss << ", "; + ss << (uint64)time(NULL); + ss << ", "; + ss << is_save_resting; + ss << ", "; + ss << m_resetTalentsCost; + ss << ", "; + ss << (uint64)m_resetTalentsTime; + + ss << ", "; + ss << finiteAlways(m_movementInfo.t_x); + ss << ", "; + ss << finiteAlways(m_movementInfo.t_y); + ss << ", "; + ss << finiteAlways(m_movementInfo.t_z); + ss << ", "; + ss << finiteAlways(m_movementInfo.t_o); + ss << ", "; + if (m_transport) + ss << m_transport->GetGUIDLow(); + else + ss << "0"; + + ss << ", "; + ss << m_ExtraFlags; + + ss << ", "; + ss << uint32(m_stableSlots); // to prevent save uint8 as char + + ss << ", "; + ss << uint32(m_atLoginFlags); + + ss << ", "; + ss << GetZoneId(); + + ss << ", "; + ss << (uint64)m_deathExpireTime; + + ss << ", '"; + ss << m_taxi.SaveTaxiDestinationsToString(); + ss << "' )"; + + CharacterDatabase.Execute( ss.str().c_str() ); + + if(m_mailsUpdated) //save mails only when needed + _SaveMail(); + + _SaveInventory(); + _SaveQuestStatus(); + _SaveDailyQuestStatus(); + _SaveTutorials(); + _SaveSpells(); + _SaveSpellCooldowns(); + _SaveActions(); + _SaveAuras(); + _SaveReputation(); + + CharacterDatabase.CommitTransaction(); + + // restore state (before aura apply, if aura remove flag then aura must set it ack by self) + SetDisplayId(tmp_displayid); + SetUInt32Value(UNIT_FIELD_BYTES_1, tmp_bytes); + SetUInt32Value(UNIT_FIELD_BYTES_2, tmp_bytes2); + SetUInt32Value(UNIT_FIELD_FLAGS, tmp_flags); + SetUInt32Value(PLAYER_FLAGS, tmp_pflags); + + // save pet (hunter pet level and experience and all type pets health/mana). + if(Pet* pet = GetPet()) + pet->SavePetToDB(PET_SAVE_AS_CURRENT); +} + +// fast save function for item/money cheating preventing - save only inventory and money state +void Player::SaveInventoryAndGoldToDB() +{ + _SaveInventory(); + SetUInt32ValueInDB(PLAYER_FIELD_COINAGE,GetMoney(),GetGUID()); +} + +void Player::_SaveActions() +{ + for(ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end(); ) + { + switch (itr->second.uState) + { + case ACTIONBUTTON_NEW: + CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type,misc) VALUES ('%u', '%u', '%u', '%u', '%u')", + GetGUIDLow(), (uint32)itr->first, (uint32)itr->second.action, (uint32)itr->second.type, (uint32)itr->second.misc ); + itr->second.uState = ACTIONBUTTON_UNCHANGED; + ++itr; + break; + case ACTIONBUTTON_CHANGED: + CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u', misc= '%u' WHERE guid= '%u' AND button= '%u' ", + (uint32)itr->second.action, (uint32)itr->second.type, (uint32)itr->second.misc, GetGUIDLow(), (uint32)itr->first ); + itr->second.uState = ACTIONBUTTON_UNCHANGED; + ++itr; + break; + case ACTIONBUTTON_DELETED: + CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u' and button = '%u'", GetGUIDLow(), (uint32)itr->first ); + m_actionButtons.erase(itr++); + break; + default: + ++itr; + break; + }; + } +} + +void Player::_SaveAuras() +{ + CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow()); + + AuraMap const& auras = GetAuras(); + for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const *spellInfo = itr->second->GetSpellProto(); + + //skip all auras from spells that are passive or need a shapeshift + if (itr->second->IsPassive() || itr->second->IsRemovedOnShapeLost()) + continue; + + //do not save single target auras (unless they were cast by the player) + if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)) + continue; + + uint8 i; + // or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras + for (i = 0; i < 3; i++) + if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT || + spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH) + break; + + if (i == 3) + { + CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u' and spell = '%u' and effect_index= '%u'",GetGUIDLow(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex()); + CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) " + "VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%d', '%d', '%d', '%d')", + GetGUIDLow(), itr->second->GetCasterGUID(), (uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(), (*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges)); + } + } +} + +void Player::_SaveInventory() +{ + // force items in buyback slots to new state + // and remove those that aren't already + for (uint8 i = BUYBACK_SLOT_START; i < BUYBACK_SLOT_END; i++) + { + Item *item = m_items[i]; + if (!item || item->GetState() == ITEM_NEW) continue; + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow()); + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow()); + m_items[i]->FSetState(ITEM_NEW); + } + + // update enchantment durations + for(EnchantDurationList::iterator itr = m_enchantDuration.begin();itr != m_enchantDuration.end();++itr) + { + itr->item->SetEnchantmentDuration(itr->slot,itr->leftduration); + } + + // if no changes + if (m_itemUpdateQueue.empty()) return; + + // do not save if the update queue is corrupt + bool error = false; + for(size_t i = 0; i < m_itemUpdateQueue.size(); i++) + { + Item *item = m_itemUpdateQueue[i]; + if(!item || item->GetState() == ITEM_REMOVED) continue; + Item *test = GetItemByPos( item->GetBagSlot(), item->GetSlot()); + + if (test == NULL) + { + sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have an item at that position!", GetGUIDLow(), GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow()); + error = true; + } + else if (test != item) + { + sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", GetGUIDLow(), GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow()); + error = true; + } + } + + if (error) + { + sLog.outError("Player::_SaveInventory - one or more errors occurred save aborted!"); + ChatHandler(this).SendSysMessage(LANG_ITEM_SAVE_FAILED); + return; + } + + for(size_t i = 0; i < m_itemUpdateQueue.size(); i++) + { + Item *item = m_itemUpdateQueue[i]; + if(!item) continue; + + Bag *container = item->GetContainer(); + uint32 bag_guid = container ? container->GetGUIDLow() : 0; + + switch(item->GetState()) + { + case ITEM_NEW: + CharacterDatabase.PExecute("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry()); + break; + case ITEM_CHANGED: + CharacterDatabase.PExecute("UPDATE character_inventory SET guid='%u', bag='%u', slot='%u', item_template='%u' WHERE item='%u'", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetEntry(), item->GetGUIDLow()); + break; + case ITEM_REMOVED: + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow()); + break; + case ITEM_UNCHANGED: + break; + } + + item->SaveToDB(); // item have unchanged inventory record and can be save standalone + } + m_itemUpdateQueue.clear(); +} + +void Player::_SaveMail() +{ + if (!m_mailsLoaded) + return; + + for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); itr++) + { + Mail *m = (*itr); + if (m->state == MAIL_STATE_CHANGED) + { + CharacterDatabase.PExecute("UPDATE mail SET itemTextId = '%u',has_items = '%u',expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'", + m->itemTextId, m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID); + if(m->removedItems.size()) + { + for(std::vector::iterator itr2 = m->removedItems.begin(); itr2 != m->removedItems.end(); ++itr2) + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", *itr2); + m->removedItems.clear(); + } + m->state = MAIL_STATE_UNCHANGED; + } + else if (m->state == MAIL_STATE_DELETED) + { + if (m->HasItems()) + for(std::vector::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2) + CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid); + if (m->itemTextId) + CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId); + CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID); + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID); + } + } + + //deallocate deleted mails... + for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ) + { + if ((*itr)->state == MAIL_STATE_DELETED) + { + Mail* m = *itr; + m_mail.erase(itr); + delete m; + itr = m_mail.begin(); + } + else + ++itr; + } + + m_mailsUpdated = false; +} + +void Player::_SaveQuestStatus() +{ + // we don't need transactions here. + for( QuestStatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i ) + { + switch (i->second.uState) + { + case QUEST_NEW : + CharacterDatabase.PExecute("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) " + "VALUES ('%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", + GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / 1000 + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]); + break; + case QUEST_CHANGED : + CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" I64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ", + i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / 1000 + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first ); + break; + case QUEST_UNCHANGED: + break; + }; + i->second.uState = QUEST_UNCHANGED; + } +} + +void Player::_SaveDailyQuestStatus() +{ + if(!m_DailyQuestChanged) + return; + + m_DailyQuestChanged = false; + + // save last daily quest time for all quests: we need only mostly reset time for reset check anyway + + // we don't need transactions here. + CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow()); + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) + if(GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) + CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" I64FMTD "')", + GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime)); +} + +void Player::_SaveReputation() +{ + for(FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr) + { + if (itr->second.Changed) + { + CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", GetGUIDLow(), itr->second.ID); + CharacterDatabase.PExecute("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags); + itr->second.Changed = false; + } + } +} + +void Player::_SaveSpells() +{ + for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next) + { + ++next; + if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) + CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first); + if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED) + CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,slot,active,disabled) VALUES ('%u', '%u', '%u','%u','%u')", GetGUIDLow(), itr->first, itr->second->slotId,itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0); + + if (itr->second->state == PLAYERSPELL_REMOVED) + _removeSpell(itr->first); + else + itr->second->state = PLAYERSPELL_UNCHANGED; + } +} + +void Player::_SaveTutorials() +{ + if(!m_TutorialsChanged) + return; + + uint32 Rows=0; + // it's better than rebuilding indexes multiple times + QueryResult *result = CharacterDatabase.PQuery("SELECT count(*) AS r FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetSession()->GetAccountId(), realmID ); + if(result) + { + Rows = result->Fetch()[0].GetUInt32(); + delete result; + } + + if (Rows) + { + CharacterDatabase.PExecute("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u' AND realmid = '%u'", + m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetSession()->GetAccountId(), realmID ); + } + else + { + CharacterDatabase.PExecute("INSERT INTO character_tutorial (account,realmid,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetSession()->GetAccountId(), realmID, m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]); + }; + + m_TutorialsChanged = false; +} + +void Player::outDebugValues() const +{ + if(!sLog.IsOutDebug()) // optimize disabled debug output + return; + + sLog.outDebug("HP is: \t\t\t%u\t\tMP is: \t\t\t%u",GetMaxHealth(), GetMaxPower(POWER_MANA)); + sLog.outDebug("AGILITY is: \t\t%f\t\tSTRENGTH is: \t\t%f",GetStat(STAT_AGILITY), GetStat(STAT_STRENGTH)); + sLog.outDebug("INTELLECT is: \t\t%f\t\tSPIRIT is: \t\t%f",GetStat(STAT_INTELLECT), GetStat(STAT_SPIRIT)); + sLog.outDebug("STAMINA is: \t\t%f\t\tSPIRIT is: \t\t%f",GetStat(STAT_STAMINA), GetStat(STAT_SPIRIT)); + sLog.outDebug("Armor is: \t\t%u\t\tBlock is: \t\t%f",GetArmor(), GetFloatValue(PLAYER_BLOCK_PERCENTAGE)); + sLog.outDebug("HolyRes is: \t\t%u\t\tFireRes is: \t\t%u",GetResistance(SPELL_SCHOOL_HOLY), GetResistance(SPELL_SCHOOL_FIRE)); + sLog.outDebug("NatureRes is: \t\t%u\t\tFrostRes is: \t\t%u",GetResistance(SPELL_SCHOOL_NATURE), GetResistance(SPELL_SCHOOL_FROST)); + sLog.outDebug("ShadowRes is: \t\t%u\t\tArcaneRes is: \t\t%u",GetResistance(SPELL_SCHOOL_SHADOW), GetResistance(SPELL_SCHOOL_ARCANE)); + sLog.outDebug("MIN_DAMAGE is: \t\t%f\tMAX_DAMAGE is: \t\t%f",GetFloatValue(UNIT_FIELD_MINDAMAGE), GetFloatValue(UNIT_FIELD_MAXDAMAGE)); + sLog.outDebug("MIN_OFFHAND_DAMAGE is: \t%f\tMAX_OFFHAND_DAMAGE is: \t%f",GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE), GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)); + sLog.outDebug("MIN_RANGED_DAMAGE is: \t%f\tMAX_RANGED_DAMAGE is: \t%f",GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE), GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE)); + sLog.outDebug("ATTACK_TIME is: \t%u\t\tRANGE_ATTACK_TIME is: \t%u",GetAttackTime(BASE_ATTACK), GetAttackTime(RANGED_ATTACK)); +} + +/*********************************************************/ +/*** FLOOD FILTER SYSTEM ***/ +/*********************************************************/ + +void Player::UpdateSpeakTime() +{ + // ignore chat spam protection for GMs in any mode + if(GetSession()->GetSecurity() > SEC_PLAYER) + return; + + time_t current = time (NULL); + if(m_speakTime > current) + { + uint32 max_count = sWorld.getConfig(CONFIG_CHATFLOOD_MESSAGE_COUNT); + if(!max_count) + return; + + ++m_speakCount; + if(m_speakCount >= max_count) + { + // prevent overwrite mute time, if message send just before mutes set, for example. + time_t new_mute = current + sWorld.getConfig(CONFIG_CHATFLOOD_MUTE_TIME); + if(GetSession()->m_muteTime < new_mute) + GetSession()->m_muteTime = new_mute; + + m_speakCount = 0; + } + } + else + m_speakCount = 0; + + m_speakTime = current + sWorld.getConfig(CONFIG_CHATFLOOD_MESSAGE_DELAY); +} + +bool Player::CanSpeak() const +{ + return GetSession()->m_muteTime <= time (NULL); +} + +/*********************************************************/ +/*** LOW LEVEL FUNCTIONS:Notifiers ***/ +/*********************************************************/ + +void Player::SendAttackSwingNotInRange() +{ + WorldPacket data(SMSG_ATTACKSWING_NOTINRANGE, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid) +{ + std::ostringstream ss; + ss << "UPDATE characters SET position_x='"<= tokens.size()) + return; + + tokens[index] = buf; +} + +void Player::SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid) +{ + Tokens tokens; + if(!LoadValuesArrayFromDB(tokens,guid)) + return; + + if(index >= tokens.size()) + return; + + char buf[11]; + snprintf(buf,11,"%u",value); + tokens[index] = buf; + + SaveValuesArrayInDB(tokens,guid); +} + +void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid) +{ + uint32 temp; + memcpy(&temp, &value, sizeof(value)); + Player::SetUInt32ValueInDB(index, temp, guid); +} + +void Player::SendAttackSwingNotStanding() +{ + WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SendAttackSwingDeadTarget() +{ + WorldPacket data(SMSG_ATTACKSWING_DEADTARGET, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SendAttackSwingCantAttack() +{ + WorldPacket data(SMSG_ATTACKSWING_CANT_ATTACK, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SendAttackSwingCancelAttack() +{ + WorldPacket data(SMSG_CANCEL_COMBAT, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SendAttackSwingBadFacingAttack() +{ + WorldPacket data(SMSG_ATTACKSWING_BADFACING, 0); + GetSession()->SendPacket( &data ); +} + +void Player::SendAutoRepeatCancel() +{ + WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, 0); + GetSession()->SendPacket( &data ); +} + +void Player::PlaySound(uint32 Sound, bool OnlySelf) +{ + WorldPacket data(SMSG_PLAY_SOUND, 4); + data << Sound; + if (OnlySelf) + GetSession()->SendPacket( &data ); + else + SendMessageToSet( &data, true ); +} + +void Player::SendExplorationExperience(uint32 Area, uint32 Experience) +{ + WorldPacket data( SMSG_EXPLORATION_EXPERIENCE, 8 ); + data << Area; + data << Experience; + GetSession()->SendPacket(&data); +} + +void Player::SendDungeonDifficulty(bool IsInGroup) +{ + uint8 val = 0x00000001; + WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12); + data << (uint32)GetDifficulty(); + data << uint32(val); + data << uint32(IsInGroup); + GetSession()->SendPacket(&data); +} + +void Player::SendResetFailedNotify(uint32 mapid) +{ + WorldPacket data(SMSG_RESET_FAILED_NOTIFY, 4); + data << uint32(mapid); + GetSession()->SendPacket(&data); +} + +/// Reset all solo instances and optionally send a message on success for each +void Player::ResetInstances(uint8 method) +{ + // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN + + // we assume that when the difficulty changes, all instances that can be reset will be + uint8 dif = GetDifficulty(); + + for (BoundInstancesMap::iterator itr = m_boundInstances[dif].begin(); itr != m_boundInstances[dif].end();) + { + InstanceSave *p = itr->second.save; + const MapEntry *entry = sMapStore.LookupEntry(itr->first); + if(!entry || !p->CanReset()) + { + ++itr; + continue; + } + + if(method == INSTANCE_RESET_ALL) + { + // the "reset all instances" method can only reset normal maps + if(dif == DIFFICULTY_HEROIC || entry->map_type == MAP_RAID) + { + ++itr; + continue; + } + } + + // if the map is loaded, reset it + Map *map = MapManager::Instance().FindMap(p->GetMapId(), p->GetInstanceId()); + if(map && map->IsDungeon()) + ((InstanceMap*)map)->Reset(method); + + // since this is a solo instance there should not be any players inside + if(method == INSTANCE_RESET_ALL || method == INSTANCE_RESET_CHANGE_DIFFICULTY) + SendResetInstanceSuccess(p->GetMapId()); + + p->DeleteFromDB(); + m_boundInstances[dif].erase(itr++); + + // the following should remove the instance save from the manager and delete it as well + p->RemovePlayer(this); + } +} + +void Player::SendResetInstanceSuccess(uint32 MapId) +{ + WorldPacket data(SMSG_INSTANCE_RESET, 4); + data << MapId; + GetSession()->SendPacket(&data); +} + +void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) +{ + // TODO: find what other fail reasons there are besides players in the instance + WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 4); + data << reason; + data << MapId; + GetSession()->SendPacket(&data); +} + +/*********************************************************/ +/*** Update timers ***/ +/*********************************************************/ + +///checks the 15 afk reports per 5 minutes limit +void Player::UpdateAfkReport(time_t currTime) +{ + if(m_bgAfkReportedTimer <= currTime) + { + m_bgAfkReportedCount = 0; + m_bgAfkReportedTimer = currTime+5*MINUTE; + } +} + +void Player::UpdateContestedPvP(uint32 diff) +{ + if(!m_contestedPvPTimer||isInCombat()) + return; + if(m_contestedPvPTimer <= diff) + { + ResetContestedPvP(); + } + else + m_contestedPvPTimer -= diff; +} + +void Player::UpdatePvPFlag(time_t currTime) +{ + if(!IsPvP()) + return; + if(pvpInfo.endTimer == 0 || currTime < (pvpInfo.endTimer + 300)) + return; + + UpdatePvP(false); +} + +void Player::UpdateDuelFlag(time_t currTime) +{ + if(!duel || duel->startTimer == 0 ||currTime < duel->startTimer + 3) + return; + + SetUInt32Value(PLAYER_DUEL_TEAM, 1); + duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 2); + + duel->startTimer = 0; + duel->startTime = currTime; + duel->opponent->duel->startTimer = 0; + duel->opponent->duel->startTime = currTime; +} + +void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) +{ + if(!pet) + pet = GetPet(); + + if(returnreagent && (pet || m_temporaryUnsummonedPetNumber)) + { + //returning of reagents only for players, so best done here + uint32 spellId = pet ? pet->GetUInt32Value(UNIT_CREATED_BY_SPELL) : m_oldpetspell; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + + if(spellInfo) + { + for(uint32 i = 0; i < 7; ++i) + { + if(spellInfo->Reagent[i] > 0) + { + ItemPosCountVec dest; //for succubus, voidwalker, felhunter and felguard credit soulshard when despawn reason other than death (out of range, logout) + uint8 msg = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->Reagent[i], spellInfo->ReagentCount[i] ); + if( msg == EQUIP_ERR_OK ) + { + Item* item = StoreNewItem( dest, spellInfo->Reagent[i], true); + if(IsInWorld()) + SendNewItem(item,spellInfo->ReagentCount[i],true,false); + } + } + } + } + m_temporaryUnsummonedPetNumber = 0; + } + + if(!pet || pet->GetOwnerGUID()!=GetGUID()) + return; + + // only if current pet in slot + switch(pet->getPetType()) + { + case MINI_PET: + m_miniPet = 0; + break; + case GUARDIAN_PET: + m_guardianPets.erase(pet->GetGUID()); + break; + default: + if(GetPetGUID()==pet->GetGUID()) + SetPet(0); + break; + } + + pet->CombatStop(); + + if(returnreagent) + { + switch(pet->GetEntry()) + { + //warlock pets except imp are removed(?) when logging out + case 1860: + case 1863: + case 417: + case 17252: + mode = PET_SAVE_NOT_IN_SLOT; + break; + } + } + + pet->SavePetToDB(mode); + + pet->CleanupsBeforeDelete(); + pet->AddObjectToRemoveList(); + pet->m_removed = true; + + if(pet->isControlled()) + { + WorldPacket data(SMSG_PET_SPELLS, 8); + data << uint64(0); + GetSession()->SendPacket(&data); + + if(GetGroup()) + SetGroupUpdateFlag(GROUP_UPDATE_PET); + } +} + +void Player::RemoveMiniPet() +{ + if(Pet* pet = GetMiniPet()) + { + pet->Remove(PET_SAVE_AS_DELETED); + m_miniPet = 0; + } +} + +Pet* Player::GetMiniPet() +{ + if(!m_miniPet) + return NULL; + return ObjectAccessor::GetPet(m_miniPet); +} + +void Player::RemoveGuardians() +{ + while(!m_guardianPets.empty()) + { + uint64 guid = *m_guardianPets.begin(); + if(Pet* pet = ObjectAccessor::GetPet(guid)) + pet->Remove(PET_SAVE_AS_DELETED); + + m_guardianPets.erase(guid); + } +} + +bool Player::HasGuardianWithEntry(uint32 entry) +{ + // pet guid middle part is entry (and creature also) + // and in guardian list must be guardians with same entry _always_ + for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) + if(GUID_ENPART(*itr)==entry) + return true; + + return false; +} + +void Player::Uncharm() +{ + Unit* charm = GetCharm(); + if(!charm) + return; + + charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM); + charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS); +} + +void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, std::string text, uint32 language) const +{ + *data << (uint8)msgtype; + *data << (uint32)language; + *data << (uint64)GetGUID(); + *data << (uint32)language; //language 2.1.0 ? + *data << (uint64)GetGUID(); + *data << (uint32)(text.length()+1); + *data << text; + *data << (uint8)chatTag(); +} + +void Player::Say(const std::string text, const uint32 language) +{ + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildPlayerChat(&data, CHAT_MSG_SAY, text, language); + SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),true); +} + +void Player::Yell(const std::string text, const uint32 language) +{ + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildPlayerChat(&data, CHAT_MSG_YELL, text, language); + SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),true); +} + +void Player::TextEmote(const std::string text) +{ + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildPlayerChat(&data, CHAT_MSG_EMOTE, text, LANG_UNIVERSAL); + SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) ); +} + +void Player::Whisper(std::string text, uint32 language,uint64 receiver) +{ + if (language != LANG_ADDON) // if not addon data + language = LANG_UNIVERSAL; // whispers should always be readable + + Player *rPlayer = objmgr.GetPlayer(receiver); + + // when player you are whispering to is dnd, he cannot receive your message, unless you are in gm mode + if(!rPlayer->isDND() || isGameMaster()) + { + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildPlayerChat(&data, CHAT_MSG_WHISPER, text, language); + rPlayer->GetSession()->SendPacket(&data); + + data.Initialize(SMSG_MESSAGECHAT, 200); + rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language); + GetSession()->SendPacket(&data); + } + else + { + // announce to player that player he is whispering to is dnd and cannot receive his message + ChatHandler(this).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName(), rPlayer->dndMsg.c_str()); + } + + if(!isAcceptWhispers()) + { + SetAcceptWhispers(true); + ChatHandler(this).SendSysMessage(LANG_COMMAND_WHISPERON); + } + + // announce to player that player he is whispering to is afk + if(rPlayer->isAFK()) + ChatHandler(this).PSendSysMessage(LANG_PLAYER_AFK, rPlayer->GetName(), rPlayer->afkMsg.c_str()); + + // if player whisper someone, auto turn of dnd to be able to receive an answer + if(isDND() && !rPlayer->isGameMaster()) + ToggleDND(); +} + +void Player::PetSpellInitialize() +{ + Pet* pet = GetPet(); + + if(pet) + { + uint8 addlist = 0; + + sLog.outDebug("Pet Spells Groups"); + + CreatureInfo const *cinfo = pet->GetCreatureInfo(); + + if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)) + { + for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();itr++) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + ++addlist; + } + } + + // first line + actionbar + spellcount + spells + last adds + WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25); + + CharmInfo *charmInfo = pet->GetCharmInfo(); + + //16 + data << (uint64)pet->GetGUID() << uint32(0x00000000) << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); + + for(uint32 i = 0; i < 10; i++) //40 + { + data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); + } + + data << uint8(addlist); //1 + + if(addlist && pet->isControlled()) + { + for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + + data << uint16(itr->first); + data << uint16(itr->second->active); // pet spell active state isn't boolean + } + } + + //data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00); //15 + uint8 count = 3; //1+8+8+8=25 + + // if count = 0, then end of packet... + data << count; + // uint32 value is spell id... + // uint64 value is constant 0, unknown... + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + //data << uint32(0x5fd1) << uint64(0); // if count = 2 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 + + GetSession()->SendPacket(&data); + } +} + +void Player::PossessSpellInitialize() +{ + Unit* charm = GetCharm(); + + if(!charm) + return; + + CharmInfo *charmInfo = charm->GetCharmInfo(); + + if(!charmInfo) + { + sLog.outError("Player::PossessSpellInitialize(): charm ("I64FMTD") has no charminfo!", charm->GetGUID()); + return; + } + + uint8 addlist = 0; + WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds + + //16 + data << (uint64)charm->GetGUID() << uint32(0x00000000) << uint8(0) << uint8(0) << uint16(0); + + for(uint32 i = 0; i < 10; i++) //40 + { + data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); + } + + data << uint8(addlist); //1 + + uint8 count = 3; + data << count; + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 + + GetSession()->SendPacket(&data); +} + +void Player::CharmSpellInitialize() +{ + Unit* charm = GetCharm(); + + if(!charm) + return; + + CharmInfo *charmInfo = charm->GetCharmInfo(); + if(!charmInfo) + { + sLog.outError("Player::CharmSpellInitialize(): the player's charm ("I64FMTD") has no charminfo!", charm->GetGUID()); + return; + } + + uint8 addlist = 0; + + if(charm->GetTypeId() != TYPEID_PLAYER) + { + CreatureInfo const *cinfo = ((Creature*)charm)->GetCreatureInfo(); + + if(cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK) + { + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + { + if(charmInfo->GetCharmSpell(i)->spellId) + ++addlist; + } + } + } + + WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds + + data << (uint64)charm->GetGUID() << uint32(0x00000000); + + if(charm->GetTypeId() != TYPEID_PLAYER) + data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()); + else + data << uint8(0) << uint8(0); + + data << uint16(0); + + for(uint32 i = 0; i < 10; i++) //40 + { + data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); + } + + data << uint8(addlist); //1 + + if(addlist) + { + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + { + CharmSpellEntry *cspell = charmInfo->GetCharmSpell(i); + if(cspell->spellId) + { + data << uint16(cspell->spellId); + data << uint16(cspell->active); + } + } + } + + uint8 count = 3; + data << count; + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 + + GetSession()->SendPacket(&data); +} + +int32 Player::GetTotalFlatMods(uint32 spellId, SpellModOp op) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 total = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod)) + continue; + + if (mod->type == SPELLMOD_FLAT) + total += mod->value; + } + return total; +} + +int32 Player::GetTotalPctMods(uint32 spellId, SpellModOp op) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 total = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod)) + continue; + + if (mod->type == SPELLMOD_PCT) + total += mod->value; + } + return total; +} + +bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell) +{ + if (!mod || !spellInfo) + return false; + + if(mod->charges == -1 && mod->lastAffected ) // marked as expired but locked until spell casting finish + { + // prevent apply to any spell except spell that trigger expire + if(spell) + { + if(mod->lastAffected != spell) + return false; + } + else if(mod->lastAffected != FindCurrentSpellBySpellId(spellInfo->Id)) + return false; + } + + return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask); +} + +void Player::AddSpellMod(SpellModifier* mod, bool apply) +{ + uint16 Opcode= (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; + + for(int eff=0;eff<64;++eff) + { + uint64 _mask = uint64(1) << eff; + if ( mod->mask & _mask) + { + int32 val = 0; + for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) + { + if ((*itr)->type == mod->type && (*itr)->mask & _mask) + val += (*itr)->value; + } + val += apply ? mod->value : -(mod->value); + WorldPacket data(Opcode, (1+1+4)); + data << uint8(eff); + data << uint8(mod->op); + data << int32(val); + SendDirectMessage(&data); + } + } + + if (apply) + m_spellMods[mod->op].push_back(mod); + else + { + if (mod->charges == -1) + --m_SpellModRemoveCount; + m_spellMods[mod->op].remove(mod); + delete mod; + } +} + +void Player::RemoveSpellMods(Spell const* spell) +{ + if(!spell || (m_SpellModRemoveCount == 0)) + return; + + for(int i=0;icharges == -1 && (mod->lastAffected == spell || mod->lastAffected==NULL)) + { + RemoveAurasDueToSpell(mod->spellId); + if (m_spellMods[i].empty()) + break; + else + itr = m_spellMods[i].begin(); + } + } + } +} + +// send Proficiency +void Player::SendProficiency(uint8 pr1, uint32 pr2) +{ + WorldPacket data(SMSG_SET_PROFICIENCY, 8); + data << pr1 << pr2; + GetSession()->SendPacket (&data); +} + +void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type) +{ + QueryResult *result = NULL; + if(type==10) + result = CharacterDatabase.PQuery("SELECT ownerguid,petitionguid FROM petition_sign WHERE playerguid = '%u'", GUID_LOPART(guid)); + else + result = CharacterDatabase.PQuery("SELECT ownerguid,petitionguid FROM petition_sign WHERE playerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); + if(result) + { + do // this part effectively does nothing, since the deletion / modification only takes place _after_ the PetitionQuery. Though I don't know if the result remains intact if I execute the delete query beforehand. + { // and SendPetitionQueryOpcode reads data from the DB + Field *fields = result->Fetch(); + uint64 ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + uint64 petitionguid = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_ITEM); + + // send update if charter owner in game + Player* owner = objmgr.GetPlayer(ownerguid); + if(owner) + owner->GetSession()->SendPetitionQueryOpcode(petitionguid); + + } while ( result->NextRow() ); + + delete result; + + if(type==10) + CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE playerguid = '%u'", GUID_LOPART(guid)); + else + CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE playerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); + } + + CharacterDatabase.BeginTransaction(); + if(type == 10) + { + CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid)); + CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE ownerguid = '%u'", GUID_LOPART(guid)); + } + else + { + CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); + CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type); + } + CharacterDatabase.CommitTransaction(); +} + +void Player::SetRestBonus (float rest_bonus_new) +{ + // Prevent resting on max level + if(getLevel() >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + rest_bonus_new = 0; + + if(rest_bonus_new < 0) + rest_bonus_new = 0; + + float rest_bonus_max = (float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)*1.5/2; + + if(rest_bonus_new > rest_bonus_max) + m_rest_bonus = rest_bonus_max; + else + m_rest_bonus = rest_bonus_new; + + // update data for client + if(m_rest_bonus>10) + SetByteValue(PLAYER_BYTES_2, 3, 0x01); // Set Reststate = Rested + else if(m_rest_bonus<=1) + SetByteValue(PLAYER_BYTES_2, 3, 0x02); // Set Reststate = Normal + + //RestTickUpdate + SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, uint32(m_rest_bonus)); +} + +void Player::HandleStealthedUnitsDetection() +{ + std::list stealthedUnits; + + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::AnyStealthedCheck u_check; + MaNGOS::UnitListSearcher searcher(stealthedUnits, u_check); + + TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); + TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(GetMapId(), this)); + cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(GetMapId(), this)); + + for (std::list::iterator i = stealthedUnits.begin(); i != stealthedUnits.end();) + { + if((*i)==this) + { + i = stealthedUnits.erase(i); + continue; + } + + if ((*i)->isVisibleForOrDetect(this,true)) + { + + (*i)->SendUpdateToPlayer(this); + m_clientGUIDs.insert((*i)->GetGUID()); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i)); + #endif + + // target aura duration for caster show only if target exist at caster client + // send data at target visibility change (adding to client) + if((*i)!=this && (*i)->isType(TYPEMASK_UNIT)) + SendAuraDurationsForTarget(*i); + + i = stealthedUnits.erase(i); + continue; + } + + ++i; + } +} + +bool Player::ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_id, Creature* npc) +{ + if(nodes.size() < 2) + return false; + + // not let cheating with start flight mounted + if(IsMounted()) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERALREADYMOUNTED); + GetSession()->SendPacket(&data); + return false; + } + + if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERSHAPESHIFTED); + GetSession()->SendPacket(&data); + return false; + } + + // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi + if(GetSession()->isLogingOut() || + (!m_currentSpells[CURRENT_GENERIC_SPELL] || + m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Effect[0] != SPELL_EFFECT_SEND_TAXI)&& + IsNonMeleeSpellCasted(false) || + isInCombat()) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERBUSY); + GetSession()->SendPacket(&data); + return false; + } + + if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) + return false; + + uint32 sourcenode = nodes[0]; + + // starting node too far away (cheat?) + TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(sourcenode); + if( !node || node->map_id != GetMapId() || + (node->x - GetPositionX())*(node->x - GetPositionX())+ + (node->y - GetPositionY())*(node->y - GetPositionY())+ + (node->z - GetPositionZ())*(node->z - GetPositionZ()) > + (2*INTERACTION_DISTANCE)*(2*INTERACTION_DISTANCE)*(2*INTERACTION_DISTANCE) ) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); + GetSession()->SendPacket(&data); + return false; + } + + // Prepare to flight start now + + // stop combat at start taxi flight if any + CombatStop(); + + // stop trade (client cancel trade at taxi map open but cheating tools can be used for reopen it) + TradeCancel(true); + + // clean not finished taxi path if any + m_taxi.ClearTaxiDestinations(); + + // 0 element current node + m_taxi.AddTaxiDestination(sourcenode); + + // fill destinations path tail + uint32 sourcepath = 0; + uint32 totalcost = 0; + + uint32 prevnode = sourcenode; + uint32 lastnode = 0; + + for(uint32 i = 1; i < nodes.size(); ++i) + { + uint32 path, cost; + + lastnode = nodes[i]; + objmgr.GetTaxiPath(prevnode, lastnode, path, cost); + + if(!path) + { + m_taxi.ClearTaxiDestinations(); + return false; + } + + totalcost += cost; + + if(prevnode == sourcenode) + sourcepath = path; + + m_taxi.AddTaxiDestination(lastnode); + + prevnode = lastnode; + } + + if(!mount_id) // if not provide then attempt use default. + mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam()); + + if (mount_id == 0 || sourcepath == 0) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); + GetSession()->SendPacket(&data); + m_taxi.ClearTaxiDestinations(); + return false; + } + + uint32 money = GetMoney(); + + if(npc) + { + totalcost = (uint32)ceil(totalcost*GetReputationPriceDiscount(npc)); + } + + if(money < totalcost) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXINOTENOUGHMONEY); + GetSession()->SendPacket(&data); + m_taxi.ClearTaxiDestinations(); + return false; + } + + //Checks and preparations done, DO FLIGHT + ModifyMoney(-(int32)totalcost); + + // prevent stealth flight + RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIOK); + GetSession()->SendPacket(&data); + + sLog.outDebug("WORLD: Sent SMSG_ACTIVATETAXIREPLY"); + + GetSession()->SendDoFlight(mount_id, sourcepath); + + return true; +} + +void Player::ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ) +{ + // last check 2.0.10 + WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8); + data << GetGUID(); + data << uint8(0x0); // flags (0x1, 0x2) + time_t curTime = time(NULL); + for(PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if (itr->second->state == PLAYERSPELL_REMOVED) + continue; + uint32 unSpellId = itr->first; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(unSpellId); + if (!spellInfo) + { + ASSERT(spellInfo); + continue; + } + + // Not send cooldown for this spells + if (spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + continue; + + if((idSchoolMask & GetSpellSchoolMask(spellInfo)) && GetSpellCooldownDelay(unSpellId) < unTimeMs ) + { + data << unSpellId; + data << unTimeMs; // in m.secs + AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/1000); + } + } + GetSession()->SendPacket(&data); +} + +void Player::InitDataForForm(bool reapplyMods) +{ + SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(m_form); + if(ssEntry && ssEntry->attackSpeed) + { + SetAttackTime(BASE_ATTACK,ssEntry->attackSpeed); + SetAttackTime(OFF_ATTACK,ssEntry->attackSpeed); + SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); + } + else + SetRegularAttackTime(); + + switch(m_form) + { + case FORM_CAT: + { + if(getPowerType()!=POWER_ENERGY) + setPowerType(POWER_ENERGY); + break; + } + case FORM_BEAR: + case FORM_DIREBEAR: + { + if(getPowerType()!=POWER_RAGE) + setPowerType(POWER_RAGE); + break; + } + default: // 0, for example + { + ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(getClass()); + if(cEntry && cEntry->powerType < MAX_POWERS && uint32(getPowerType()) != cEntry->powerType) + setPowerType(Powers(cEntry->powerType)); + break; + } + } + + // update auras at form change, ignore this at mods reapply (.reset stats/etc) when form not change. + if (!reapplyMods) + UpdateEquipSpellsAtFormChange(); + + UpdateAttackPowerAndDamage(); + UpdateAttackPowerAndDamage(true); +} + +// Return true is the bought item has a max count to force refresh of window by caller +bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot) +{ + // cheating attempt + if(count < 1) count = 1; + + if(!isAlive()) + return false; + + ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); + if( !pProto ) + { + SendBuyError( BUY_ERR_CANT_FIND_ITEM, NULL, item, 0); + return false; + } + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*this, vendorguid,UNIT_NPC_FLAG_VENDOR); + if (!pCreature) + { + sLog.outDebug( "WORLD: BuyItemFromVendor - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); + SendBuyError( BUY_ERR_DISTANCE_TOO_FAR, NULL, item, 0); + return false; + } + + VendorItemData const* vItems = pCreature->GetVendorItems(); + if(!vItems || vItems->Empty()) + { + SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); + return false; + } + + size_t vendor_slot = vItems->FindItemSlot(item); + if(vendor_slot >= vItems->GetItemCount()) + { + SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); + return false; + } + + VendorItem const* crItem = vItems->m_items[vendor_slot]; + + // check current item amount if it limited + if( crItem->maxcount != 0 ) + { + if(pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count ) + { + SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); + return false; + } + } + + if( uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) + { + SendBuyError( BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0); + return false; + } + + if(crItem->ExtendedCost) + { + ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); + if(!iece) + { + sLog.outError("Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost); + return false; + } + + // honor points price + if(GetHonorPoints() < (iece->reqhonorpoints * count)) + { + SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); + return false; + } + + // arena points price + if(GetArenaPoints() < (iece->reqarenapoints * count)) + { + SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); + return false; + } + + // item base price + for (uint8 i = 0; i < 5; ++i) + { + if(iece->reqitem[i] && !HasItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count))) + { + SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); + return false; + } + } + + // check for personal arena rating requirement + if( GetMaxPersonalArenaRatingRequirement() < iece->reqpersonalarenarating ) + { + // probably not the proper equip err + SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK,NULL,NULL); + return false; + } + } + + uint32 price = pProto->BuyPrice * count; + + // reputation discount + price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); + + if( GetMoney() < price ) + { + SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); + return false; + } + + uint8 bag = 0; // init for case invalid bagGUID + + if (bagguid != NULL_BAG && slot != NULL_SLOT) + { + Bag *pBag; + if( bagguid == GetGUID() ) + { + bag = INVENTORY_SLOT_BAG_0; + } + else + { + for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END;i++) + { + pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0,i); + if( pBag ) + { + if( bagguid == pBag->GetGUID() ) + { + bag = i; + break; + } + } + } + } + } + + if( IsInventoryPos( bag, slot ) || (bagguid == NULL_BAG && slot == NULL_SLOT) ) + { + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem( bag, slot, dest, item, pProto->BuyCount * count ); + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, NULL, NULL ); + return false; + } + + ModifyMoney( -(int32)price ); + if(crItem->ExtendedCost) // case for new honor system + { + ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); + if(iece->reqhonorpoints) + ModifyHonorPoints( - int32(iece->reqhonorpoints * count)); + if(iece->reqarenapoints) + ModifyArenaPoints( - int32(iece->reqarenapoints * count)); + for (uint8 i = 0; i < 5; ++i) + { + if(iece->reqitem[i]) + DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true); + } + } + + if(Item *it = StoreNewItem( dest, item, true )) + { + uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); + + WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); + data << pCreature->GetGUID(); + data << (uint32)(vendor_slot+1); // numbered from 1 at client + data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); + data << (uint32)count; + GetSession()->SendPacket(&data); + + SendNewItem(it, pProto->BuyCount*count, true, false, false); + } + } + else if( IsEquipmentPos( bag, slot ) ) + { + uint16 dest; + uint8 msg = CanEquipNewItem( slot, dest, item, pProto->BuyCount * count, false ); + if( msg != EQUIP_ERR_OK ) + { + SendEquipError( msg, NULL, NULL ); + return false; + } + + ModifyMoney( -(int32)price ); + if(crItem->ExtendedCost) // case for new honor system + { + ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); + if(iece->reqhonorpoints) + ModifyHonorPoints( - int32(iece->reqhonorpoints)); + if(iece->reqarenapoints) + ModifyArenaPoints( - int32(iece->reqarenapoints)); + for (uint8 i = 0; i < 5; ++i) + { + if(iece->reqitem[i]) + DestroyItemCount(iece->reqitem[i], iece->reqitemcount[i], true); + } + } + + if(Item *it = EquipNewItem( dest, item, pProto->BuyCount * count, true )) + { + uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); + + WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); + data << pCreature->GetGUID(); + data << (uint32)(vendor_slot+1); // numbered from 1 at client + data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); + data << (uint32)count; + GetSession()->SendPacket(&data); + + SendNewItem(it, pProto->BuyCount*count, true, false, false); + + AutoUnequipOffhandIfNeed(); + } + } + else + { + SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL ); + return false; + } + + return crItem->maxcount!=0; +} + +uint32 Player::GetMaxPersonalArenaRatingRequirement() +{ + // returns the maximal personal arena rating that can be used to purchase items requiring this condition + // the personal rating of the arena team must match the required limit as well + // so return max[in arenateams](min(personalrating[teamtype], teamrating[teamtype])) + uint32 max_personal_rating = 0; + for(int i = 0; i < MAX_ARENA_SLOT; ++i) + { + if(ArenaTeam * at = objmgr.GetArenaTeamById(GetArenaTeamId(i))) + { + uint32 p_rating = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (i * 6) + 5); + uint32 t_rating = at->GetRating(); + p_rating = p_ratingSendPacket(&data); + } + // instance is valid, reset homebind timer + m_HomebindTimer = 0; + } + else if (m_HomebindTimer > 0) + { + if (time >= m_HomebindTimer) + { + // teleport to homebind location + TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation()); + } + else + m_HomebindTimer -= time; + } + else + { + // instance is invalid, start homebind timer + m_HomebindTimer = 60000; + // send message to player + WorldPacket data(SMSG_RAID_GROUP_ONLY, 4+4); + data << m_HomebindTimer; + data << uint32(1); + GetSession()->SendPacket(&data); + sLog.outDebug("PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName(),GetGUIDLow()); + } +} + +void Player::UpdatePvP(bool state, bool ovrride) +{ + if(!state || ovrride) + { + SetPvP(state); + if(Pet* pet = GetPet()) + pet->SetPvP(state); + if(Unit* charmed = GetCharm()) + charmed->SetPvP(state); + + pvpInfo.endTimer = 0; + } + else + { + if(pvpInfo.endTimer != 0) + pvpInfo.endTimer = time(NULL); + else + { + SetPvP(state); + + if(Pet* pet = GetPet()) + pet->SetPvP(state); + if(Unit* charmed = GetCharm()) + charmed->SetPvP(state); + } + } +} + +void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time) +{ + SpellCooldown sc; + sc.end = end_time; + sc.itemid = itemid; + m_spellCooldowns[spellid] = sc; +} + +void Player::SendCooldownEvent(SpellEntry const *spellInfo) +{ + if ( !(spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) ) + return; + + // Get spell cooldwn + int32 cooldown = GetSpellRecoveryTime(spellInfo); + // Apply spellmods + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, cooldown); + if (cooldown < 0) + cooldown = 0; + // Add cooldown + AddSpellCooldown(spellInfo->Id, 0, time(NULL) + cooldown / 1000); + // Send activate + WorldPacket data(SMSG_COOLDOWN_EVENT, (4+8)); + data << spellInfo->Id; + data << GetGUID(); + SendDirectMessage(&data); +} + //slot to be excluded while counting +bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) +{ + if(!enchantmentcondition) + return true; + + SpellItemEnchantmentConditionEntry const *Condition = sSpellItemEnchantmentConditionStore.LookupEntry(enchantmentcondition); + + if(!Condition) + return true; + + uint8 curcount[4] = {0, 0, 0, 0}; + + //counting current equipped gem colors + for(uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) + { + if(i == slot) + continue; + Item *pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + if(pItem2 && pItem2->GetProto()->Socket[0].Color) + { + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + { + uint32 enchant_id = pItem2->GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + continue; + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + uint32 gemid = enchantEntry->GemID; + if(!gemid) + continue; + + ItemPrototype const* gemProto = sItemStorage.LookupEntry(gemid); + if(!gemProto) + continue; + + GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GemProperties); + if(!gemProperty) + continue; + + uint8 GemColor = gemProperty->color; + + for(uint8 b = 0, tmpcolormask = 1; b < 4; b++, tmpcolormask <<= 1) + { + if(tmpcolormask & GemColor) + ++curcount[b]; + } + } + } + } + + bool activate = true; + + for(int i = 0; i < 5; i++) + { + if(!Condition->Color[i]) + continue; + + uint32 _cur_gem = curcount[Condition->Color[i] - 1]; + + // if have use them as count, else use from Condition + uint32 _cmp_gem = Condition->CompareColor[i] ? curcount[Condition->CompareColor[i] - 1]: Condition->Value[i]; + + switch(Condition->Comparator[i]) + { + case 2: // requires less than ( || ) gems + activate &= (_cur_gem < _cmp_gem) ? true : false; + break; + case 3: // requires more than ( || ) gems + activate &= (_cur_gem > _cmp_gem) ? true : false; + break; + case 5: // requires at least than ( || ) gems + activate &= (_cur_gem >= _cmp_gem) ? true : false; + break; + } + } + + sLog.outDebug("Checking Condition %u, there are %u Meta Gems, %u Red Gems, %u Yellow Gems and %u Blue Gems, Activate:%s", enchantmentcondition, curcount[0], curcount[1], curcount[2], curcount[3], activate ? "yes" : "no"); + + return activate; +} + +void Player::CorrectMetaGemEnchants(uint8 exceptslot, bool apply) +{ + //cycle all equipped items + for(uint32 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) + { + //enchants for the slot being socketed are handled by Player::ApplyItemMods + if(slot == exceptslot) + continue; + + Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, slot ); + + if(!pItem || !pItem->GetProto()->Socket[0].Color) + continue; + + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + { + uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + continue; + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + uint32 condition = enchantEntry->EnchantmentCondition; + if(condition) + { + //was enchant active with/without item? + bool wasactive = EnchantmentFitsRequirements(condition, apply ? exceptslot : -1); + //should it now be? + if(wasactive ^ EnchantmentFitsRequirements(condition, apply ? -1 : exceptslot)) + { + // ignore item gem conditions + //if state changed, (dis)apply enchant + ApplyEnchantment(pItem,EnchantmentSlot(enchant_slot),!wasactive,true,true); + } + } + } + } +} + + //if false -> then toggled off if was on| if true -> toggled on if was off AND meets requirements +void Player::ToggleMetaGemsActive(uint8 exceptslot, bool apply) +{ + //cycle all equipped items + for(int slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) + { + //enchants for the slot being socketed are handled by WorldSession::HandleSocketOpcode(WorldPacket& recv_data) + if(slot == exceptslot) + continue; + + Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, slot ); + + if(!pItem || !pItem->GetProto()->Socket[0].Color) //if item has no sockets or no item is equipped go to next item + continue; + + //cycle all (gem)enchants + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + { + uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) //if no enchant go to next enchant(slot) + continue; + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + //only metagems to be (de)activated, so only enchants with condition + uint32 condition = enchantEntry->EnchantmentCondition; + if(condition) + ApplyEnchantment(pItem,EnchantmentSlot(enchant_slot), apply); + } + } +} + +void Player::LeaveBattleground(bool teleportToEntryPoint) +{ + if(BattleGround *bg = GetBattleGround()) + { + bool need_debuf = bg->isBattleGround() && (bg->GetStatus() == STATUS_IN_PROGRESS) && sWorld.getConfig(CONFIG_BATTLEGROUND_CAST_DESERTER); + + bg->RemovePlayerAtLeave(GetGUID(), teleportToEntryPoint, true); + + // call after remove to be sure that player resurrected for correct cast + if(need_debuf) + CastSpell(this, 26013, true); // Deserter + } +} + +bool Player::CanJoinToBattleground() const +{ + // check Deserter debuff + if(GetDummyAura(26013)) + return false; + + return true; +} + +bool Player::CanReportAfkDueToLimit() +{ + // a player can complain about 15 people per 5 minutes + if(m_bgAfkReportedCount >= 15) + return false; + ++m_bgAfkReportedCount; + return true; +} + +///This player has been blamed to be inactive in a battleground +void Player::ReportedAfkBy(Player* reporter) +{ + BattleGround *bg = GetBattleGround(); + if(!bg || bg != reporter->GetBattleGround() || GetTeam() != reporter->GetTeam()) + return; + + // check if player has 'Idle' or 'Inactive' debuff + if(m_bgAfkReporter.find(reporter->GetGUIDLow())==m_bgAfkReporter.end() && !HasAura(43680,0) && !HasAura(43681,0) && reporter->CanReportAfkDueToLimit()) + { + m_bgAfkReporter.insert(reporter->GetGUIDLow()); + // 3 players have to complain to apply debuff + if(m_bgAfkReporter.size() >= 3) + { + // cast 'Idle' spell + CastSpell(this, 43680, true); + m_bgAfkReporter.clear(); + } + } +} + +bool Player::IsVisibleInGridForPlayer( Player* pl ) const +{ + // gamemaster in GM mode see all, including ghosts + if(pl->isGameMaster() && GetSession()->GetSecurity() <= pl->GetSession()->GetSecurity()) + return true; + + // It seems in battleground everyone sees everyone, except the enemy-faction ghosts + if (InBattleGround()) + { + if (!(isAlive() || m_deathTimer > 0) && !IsFriendlyTo(pl) ) + return false; + return true; + } + + // Live player see live player or dead player with not realized corpse + if(pl->isAlive() || pl->m_deathTimer > 0) + { + return isAlive() || m_deathTimer > 0; + } + + // Ghost see other friendly ghosts, that's for sure + if(!(isAlive() || m_deathTimer > 0) && IsFriendlyTo(pl)) + return true; + + // Dead player see live players near own corpse + if(isAlive()) + { + Corpse *corpse = pl->GetCorpse(); + if(corpse) + { + // 20 - aggro distance for same level, 25 - max additional distance if player level less that creature level + if(corpse->IsWithinDistInMap(this,(20+25)*sWorld.getRate(RATE_CREATURE_AGGRO))) + return true; + } + } + + // and not see any other + return false; +} + +bool Player::IsVisibleGloballyFor( Player* u ) const +{ + if(!u) + return false; + + // Always can see self + if (u==this) + return true; + + // Visible units, always are visible for all players + if (GetVisibility() == VISIBILITY_ON) + return true; + + // GMs are visible for higher gms (or players are visible for gms) + if (u->GetSession()->GetSecurity() > SEC_PLAYER) + return GetSession()->GetSecurity() <= u->GetSession()->GetSecurity(); + + // non faction visibility non-breakable for non-GMs + if (GetVisibility() == VISIBILITY_OFF) + return false; + + // non-gm stealth/invisibility not hide from global player lists + return true; +} + +void Player::UpdateVisibilityOf(WorldObject* target) +{ + if(HaveAtClient(target)) + { + if(!target->isVisibleForInState(this,true)) + { + target->DestroyForPlayer(this); + m_clientGUIDs.erase(target->GetGUID()); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u) out of range for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),GetGUIDLow(),GetDistance(target)); + #endif + } + } + else + { + if(target->isVisibleForInState(this,false)) + { + target->SendUpdateToPlayer(this); + if(target->GetTypeId()!=TYPEID_GAMEOBJECT||!((GameObject*)target)->IsTransport()) + m_clientGUIDs.insert(target->GetGUID()); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u) is visible now for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),GetGUIDLow(),GetDistance(target)); + #endif + + // target aura duration for caster show only if target exist at caster client + // send data at target visibility change (adding to client) + if(target!=this && target->isType(TYPEMASK_UNIT)) + SendAuraDurationsForTarget((Unit*)target); + + if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isAlive()) + ((Creature*)target)->SendMonsterMoveWithSpeedToCurrentDestination(this); + } + } +} + +template +inline void UpdateVisibilityOf_helper(std::set& s64, T* target) +{ + s64.insert(target->GetGUID()); +} + +template<> +inline void UpdateVisibilityOf_helper(std::set& s64, GameObject* target) +{ + if(!target->IsTransport()) + s64.insert(target->GetGUID()); +} + +template +void Player::UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow) +{ + if(HaveAtClient(target)) + { + if(!target->isVisibleForInState(this,true)) + { + target->BuildOutOfRangeUpdateBlock(&data); + m_clientGUIDs.erase(target->GetGUID()); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u, Entry: %u) is out of range for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),target->GetEntry(),GetGUIDLow(),GetDistance(target)); + #endif + } + } + else + { + if(target->isVisibleForInState(this,false)) + { + visibleNow.insert(target); + target->BuildUpdate(data_updates); + target->BuildCreateUpdateBlockForPlayer(&data, this); + UpdateVisibilityOf_helper(m_clientGUIDs,target); + + #ifdef MANGOS_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0) + sLog.outDebug("Object %u (Type: %u, Entry: %u) is visible now for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),target->GetEntry(),GetGUIDLow(),GetDistance(target)); + #endif + } + } +} + +template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); +template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); +template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); +template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); +template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); + +void Player::InitPrimaryProffesions() +{ + SetFreePrimaryProffesions(sWorld.getConfig(CONFIG_MAX_PRIMARY_TRADE_SKILL)); +} + +void Player::SendComboPoints() +{ + Unit *combotarget = ObjectAccessor::GetUnit(*this, m_comboTarget); + if (combotarget) + { + WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1); + data.append(combotarget->GetPackGUID()); + data << uint8(m_comboPoints); + GetSession()->SendPacket(&data); + } +} + +void Player::AddComboPoints(Unit* target, int8 count) +{ + if(!count) + return; + + // without combo points lost (duration checked in aura) + RemoveSpellsCausingAura(SPELL_AURA_RETAIN_COMBO_POINTS); + + if(target->GetGUID() == m_comboTarget) + { + m_comboPoints += count; + } + else + { + if(m_comboTarget) + if(Unit* target = ObjectAccessor::GetUnit(*this,m_comboTarget)) + target->RemoveComboPointHolder(GetGUIDLow()); + + m_comboTarget = target->GetGUID(); + m_comboPoints = count; + + target->AddComboPointHolder(GetGUIDLow()); + } + + if (m_comboPoints > 5) m_comboPoints = 5; + if (m_comboPoints < 0) m_comboPoints = 0; + + SendComboPoints(); +} + +void Player::ClearComboPoints() +{ + if(!m_comboTarget) + return; + + // without combopoints lost (duration checked in aura) + RemoveSpellsCausingAura(SPELL_AURA_RETAIN_COMBO_POINTS); + + m_comboPoints = 0; + + SendComboPoints(); + + if(Unit* target = ObjectAccessor::GetUnit(*this,m_comboTarget)) + target->RemoveComboPointHolder(GetGUIDLow()); + + m_comboTarget = 0; +} + +void Player::SetGroup(Group *group, int8 subgroup) +{ + if(group == NULL) m_group.unlink(); + else + { + // never use SetGroup without a subgroup unless you specify NULL for group + assert(subgroup >= 0); + m_group.link(group, this); + m_group.setSubGroup((uint8)subgroup); + } +} + +void Player::SendInitialPacketsBeforeAddToMap() +{ + WorldPacket data(SMSG_SET_REST_START, 4); + data << uint32(0); // unknown, may be rest state time or expirience + GetSession()->SendPacket(&data); + + // Homebind + data.Initialize(SMSG_BINDPOINTUPDATE, 5*4); + data << m_homebindX << m_homebindY << m_homebindZ; + data << (uint32) m_homebindMapId; + data << (uint32) m_homebindZoneId; + GetSession()->SendPacket(&data); + + // SMSG_SET_PROFICIENCY + // SMSG_UPDATE_AURA_DURATION + + // tutorial stuff + data.Initialize(SMSG_TUTORIAL_FLAGS, 8*4); + for (int i = 0; i < 8; ++i) + data << uint32( GetTutorialInt(i) ); + GetSession()->SendPacket(&data); + + SendInitialSpells(); + + data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4); + data << uint32(0); // count, for(count) uint32; + GetSession()->SendPacket(&data); + + SendInitialActionButtons(); + SendInitialReputations(); + UpdateZone(GetZoneId()); + SendInitWorldStates(); + + // SMSG_SET_AURA_SINGLE + + data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8); + data << uint32(secsToTimeBitFields(sWorld.GetGameTime())); + data << (float)0.01666667f; // game speed + GetSession()->SendPacket( &data ); + + // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment + if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight()) + AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); +} + +void Player::SendInitialPacketsAfterAddToMap() +{ + CastSpell(this, 836, true); // LOGINEFFECT + + // set some aura effects that send packet to player client after add player to map + // SendMessageToSet not send it to player not it map, only for aura that not changed anything at re-apply + // same auras state lost at far teleport, send it one more time in this case also + static const AuraType auratypes[] = + { + SPELL_AURA_MOD_FEAR, SPELL_AURA_TRANSFORM, SPELL_AURA_WATER_WALK, + SPELL_AURA_FEATHER_FALL, SPELL_AURA_HOVER, SPELL_AURA_SAFE_FALL, + SPELL_AURA_FLY, SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED, SPELL_AURA_NONE + }; + for(AuraType const* itr = &auratypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr) + { + Unit::AuraList const& auraList = GetAurasByType(*itr); + if(!auraList.empty()) + auraList.front()->ApplyModifier(true,true); + } + + if(HasAuraType(SPELL_AURA_MOD_STUN)) + SetMovement(MOVE_ROOT); + + // manual send package (have code in ApplyModifier(true,true); that don't must be re-applied. + if(HasAuraType(SPELL_AURA_MOD_ROOT)) + { + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); + data.append(GetPackGUID()); + data << (uint32)2; + SendMessageToSet(&data,true); + } + + SendEnchantmentDurations(); // must be after add to map + SendItemDurations(); // must be after add to map +} + +void Player::SendUpdateToOutOfRangeGroupMembers() +{ + if (m_groupUpdateMask == GROUP_UPDATE_FLAG_NONE) + return; + if(Group* group = GetGroup()) + group->UpdatePlayerOutOfRange(this); + + m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE; + m_auraUpdateMask = 0; + if(Pet *pet = GetPet()) + pet->ResetAuraUpdateMask(); +} + +void Player::SendTransferAborted(uint32 mapid, uint16 reason) +{ + WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2); + data << uint32(mapid); + data << uint16(reason); // transfer abort reason + GetSession()->SendPacket(&data); +} + +void Player::SendInstanceResetWarning(uint32 mapid, uint32 time) +{ + // type of warning, based on the time remaining until reset + uint32 type; + if(time > 3600) + type = RAID_INSTANCE_WELCOME; + else if(time > 900 && time <= 3600) + type = RAID_INSTANCE_WARNING_HOURS; + else if(time > 300 && time <= 900) + type = RAID_INSTANCE_WARNING_MIN; + else + type = RAID_INSTANCE_WARNING_MIN_SOON; + WorldPacket data(SMSG_RAID_INSTANCE_MESSAGE, 4+4+4); + data << uint32(type); + data << uint32(mapid); + data << uint32(time); + GetSession()->SendPacket(&data); +} + +void Player::ApplyEquipCooldown( Item * pItem ) +{ + for(int i = 0; i <5; ++i) + { + _Spell const& spellData = pItem->GetProto()->Spells[i]; + + // no spell + if( !spellData.SpellId ) + continue; + + // wrong triggering type (note: ITEM_SPELLTRIGGER_ON_NO_DELAY_USE not have cooldown) + if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE ) + continue; + + AddSpellCooldown(spellData.SpellId, pItem->GetEntry(), time(NULL) + 30); + + WorldPacket data(SMSG_ITEM_COOLDOWN, 12); + data << pItem->GetGUID(); + data << uint32(spellData.SpellId); + GetSession()->SendPacket(&data); + } +} + +void Player::resetSpells() +{ + // not need after this call + if(HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) + { + m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_SPELLS; + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_SPELLS), GetGUIDLow()); + } + + // make full copy of map (spells removed and marked as deleted at another spell remove + // and we can't use original map for safe iterative with visit each spell at loop end + PlayerSpellMap smap = GetSpellMap(); + + for(PlayerSpellMap::const_iterator iter = smap.begin();iter != smap.end(); ++iter) + removeSpell(iter->first); // only iter->first can be accessed, object by iter->second can be deleted already + + learnDefaultSpells(); + learnQuestRewardedSpells(); +} + +void Player::learnDefaultSpells(bool loading) +{ + // learn default race/class spells + PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(),getClass()); + std::list::const_iterator spell_itr; + for (spell_itr = info->spell.begin(); spell_itr!=info->spell.end(); ++spell_itr) + { + uint16 tspell = spell_itr->first; + if (tspell) + { + sLog.outDebug("PLAYER: Adding initial spell, id = %u",tspell); + if(loading || !spell_itr->second) // not care about passive spells or loading case + addSpell(tspell,spell_itr->second); + else // but send in normal spell in game learn case + learnSpell(tspell); + } + } +} + +void Player::learnQuestRewardedSpells(Quest const* quest) +{ + uint32 spell_id = quest->GetRewSpellCast(); + + // skip quests without rewarded spell + if( !spell_id ) + return; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if(!spellInfo) + return; + + // check learned spells state + bool found = false; + for(int i=0; i < 3; ++i) + { + if(spellInfo->Effect[i] == SPELL_EFFECT_LEARN_SPELL && !HasSpell(spellInfo->EffectTriggerSpell[i])) + { + found = true; + break; + } + } + + // skip quests with not teaching spell or already known spell + if(!found) + return; + + // prevent learn non first rank unknown profession and second specialization for same profession) + uint32 learned_0 = spellInfo->EffectTriggerSpell[0]; + if( spellmgr.GetSpellRank(learned_0) > 1 && !HasSpell(learned_0) ) + { + // not have first rank learned (unlearned prof?) + uint32 first_spell = spellmgr.GetFirstSpellInChain(learned_0); + if( !HasSpell(first_spell) ) + return; + + SpellEntry const *learnedInfo = sSpellStore.LookupEntry(learned_0); + if(!learnedInfo) + return; + + // specialization + if(learnedInfo->Effect[0]==SPELL_EFFECT_TRADE_SKILL && learnedInfo->Effect[1]==0) + { + // search other specialization for same prof + for(PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PLAYERSPELL_REMOVED || itr->first==learned_0) + continue; + + SpellEntry const *itrInfo = sSpellStore.LookupEntry(itr->first); + if(!itrInfo) + return; + + // compare only specializations + if(itrInfo->Effect[0]!=SPELL_EFFECT_TRADE_SKILL || itrInfo->Effect[1]!=0) + continue; + + // compare same chain spells + if(spellmgr.GetFirstSpellInChain(itr->first) != first_spell) + continue; + + // now we have 2 specialization, learn possible only if found is lesser specialization rank + if(!spellmgr.IsHighRankOfSpell(learned_0,itr->first)) + return; + } + } + } + + CastSpell( this, spell_id, true); +} + +void Player::learnQuestRewardedSpells() +{ + // learn spells received from quest completing + for(QuestStatusMap::const_iterator itr = mQuestStatus.begin(); itr != mQuestStatus.end(); ++itr) + { + // skip no rewarded quests + if(!itr->second.m_rewarded) + continue; + + Quest const* quest = objmgr.GetQuestTemplate(itr->first); + if( !quest ) + continue; + + learnQuestRewardedSpells(quest); + } +} + +void Player::learnSkillRewardedSpells(uint32 skill_id ) +{ + uint32 raceMask = getRaceMask(); + uint32 classMask = getClassMask(); + for (uint32 j=0; jskillId!=skill_id || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL) + continue; + // Check race if set + if (pAbility->racemask && !(pAbility->racemask & raceMask)) + continue; + // Check class if set + if (pAbility->classmask && !(pAbility->classmask & classMask)) + continue; + + if (SpellEntry const* spellentry = sSpellStore.LookupEntry(pAbility->spellId)) + { + // Ok need learn spell + learnSpell(pAbility->spellId); + } + } +} + +void Player::learnSkillRewardedSpells() +{ + for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++) + { + if(!GetUInt32Value(PLAYER_SKILL_INDEX(i))) + continue; + + uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF; + + learnSkillRewardedSpells(pskill); + } +} + +void Player::SendAuraDurationsForTarget(Unit* target) +{ + for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) + { + Aura* aura = itr->second; + if(aura->GetAuraSlot() >= MAX_AURAS || aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) + continue; + + aura->SendAuraDurationForCaster(this); + } +} + +void Player::SetDailyQuestStatus( uint32 quest_id ) +{ + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) + { + if(!GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) + { + SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx,quest_id); + m_lastDailyQuestTime = time(NULL); // last daily quest time + m_DailyQuestChanged = true; + break; + } + } +} + +void Player::ResetDailyQuestStatus() +{ + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) + SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx,0); + + // DB data deleted in caller + m_DailyQuestChanged = false; + m_lastDailyQuestTime = 0; +} + +BattleGround* Player::GetBattleGround() const +{ + if(GetBattleGroundId()==0) + return NULL; + + return sBattleGroundMgr.GetBattleGround(GetBattleGroundId()); +} + +bool Player::InArena() const +{ + BattleGround *bg = GetBattleGround(); + if(!bg || !bg->isArena()) + return false; + + return true; +} + +bool Player::GetBGAccessByLevel(uint32 bgTypeId) const +{ + BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId); + if(!bg) + return false; + + if(getLevel() < bg->GetMinLevel() || getLevel() > bg->GetMaxLevel()) + return false; + + return true; +} + +uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id) +{ + if(queue_id < 1) + return 0; + + if(queue_id >=6) + queue_id = 6; + + return 10*(queue_id+1); +} + +uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id) +{ + if(queue_id >=6) + return 255; // hardcoded max level + + return 10*(queue_id+2)-1; +} + +uint32 Player::GetBattleGroundQueueIdFromLevel() const +{ + uint32 level = getLevel(); + if(level <= 19) + return 0; + else if (level > 69) + return 6; + else + return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ... +} + +float Player::GetReputationPriceDiscount( Creature const* pCreature ) const +{ + FactionTemplateEntry const* vendor_faction = pCreature->getFactionTemplateEntry(); + if(!vendor_faction) + return 1.0f; + + ReputationRank rank = GetReputationRank(vendor_faction->faction); + if(rank <= REP_NEUTRAL) + return 1.0f; + + return 1.0f - 0.05f* (rank - REP_NEUTRAL); +} + +bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const +{ + uint32 racemask = getRaceMask(); + uint32 classmask = getClassMask(); + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + // skip wrong race skills + if( _spell_idx->second->racemask && (_spell_idx->second->racemask & racemask) == 0) + return false; + + // skip wrong class skills + if( _spell_idx->second->classmask && (_spell_idx->second->classmask & classmask) == 0) + return false; + } + return true; +} + +bool Player::HasQuestForGO(int32 GOId) +{ + for( QuestStatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i ) + { + QuestStatusData qs=i->second; + if (qs.m_status == QUEST_STATUS_INCOMPLETE) + { + Quest const* qinfo = objmgr.GetQuestTemplate(i->first); + if(!qinfo) + continue; + + if(GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID) + continue; + + for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++) + { + if (qinfo->ReqCreatureOrGOId[j]>=0) //skip non GO case + continue; + + if((-1)*GOId == qinfo->ReqCreatureOrGOId[j] && qs.m_creatureOrGOcount[j] < qinfo->ReqCreatureOrGOCount[j]) + return true; + } + } + } + return false; +} + +void Player::UpdateForQuestsGO() +{ + if(m_clientGUIDs.empty()) + return; + + UpdateData udata; + WorldPacket packet; + for(ClientGUIDs::iterator itr=m_clientGUIDs.begin(); itr!=m_clientGUIDs.end(); ++itr) + { + if(IS_GAMEOBJECT_GUID(*itr)) + { + GameObject *obj = HashMapHolder::Find(*itr); + if(obj) + obj->BuildValuesUpdateBlockForPlayer(&udata,this); + } + } + udata.BuildPacket(&packet); + GetSession()->SendPacket(&packet); +} + +void Player::SummonIfPossible(bool agree) +{ + if(!agree) + { + m_summon_expire = 0; + return; + } + + // expire and auto declined + if(m_summon_expire < time(NULL)) + return; + + // stop taxi flight at summon + if(isInFlight()) + { + GetMotionMaster()->MovementExpired(); + m_taxi.ClearTaxiDestinations(); + } + + // drop flag at summon + if(BattleGround *bg = GetBattleGround()) + bg->EventPlayerDroppedFlag(this); + + m_summon_expire = 0; + + TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z,GetOrientation()); +} + +void Player::RemoveItemDurations( Item *item ) +{ + for(ItemDurationList::iterator itr = m_itemDuration.begin();itr != m_itemDuration.end(); ++itr) + { + if(*itr==item) + { + m_itemDuration.erase(itr); + break; + } + } +} + +void Player::AddItemDurations( Item *item ) +{ + if(item->GetUInt32Value(ITEM_FIELD_DURATION)) + { + m_itemDuration.push_back(item); + item->SendTimeUpdate(this); + } +} + +void Player::AutoUnequipOffhandIfNeed() +{ + Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); + if(!offItem) + return; + + Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + + if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) + return; + + ItemPosCountVec off_dest; + uint8 off_msg = CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ); + if( off_msg == EQUIP_ERR_OK ) + { + RemoveItem(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true); + StoreItem( off_dest, offItem, true ); + } + else + { + sLog.outError("Player::EquipItem: Can's store offhand item at 2hand item equip for player (GUID: %u).",GetGUIDLow()); + } +} + +bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem) +{ + if(spellInfo->EquippedItemClass < 0) + return true; + + // scan other equipped items for same requirements (mostly 2 daggers/etc) + // for optimize check 2 used cases only + switch(spellInfo->EquippedItemClass) + { + case ITEM_CLASS_WEAPON: + { + for(int i= EQUIPMENT_SLOT_MAINHAND; i < EQUIPMENT_SLOT_TABARD; ++i) + if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo)) + return true; + break; + } + case ITEM_CLASS_ARMOR: + { + // tabard not have dependent spells + for(int i= EQUIPMENT_SLOT_START; i< EQUIPMENT_SLOT_MAINHAND; ++i) + if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i )) + if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo)) + return true; + + // shields can be equipped to offhand slot + if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) + if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo)) + return true; + + // ranged slot can have some armor subclasses + if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED)) + if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo)) + return true; + + break; + } + default: + sLog.outError("HasItemFitToSpellReqirements: Not handeled spell reqirement for item class %u",spellInfo->EquippedItemClass); + break; + } + + return false; +} + +void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) +{ + AuraMap& auras = GetAuras(); + for(AuraMap::iterator itr = auras.begin(); itr != auras.end(); ) + { + Aura* aura = itr->second; + + // skip passive (passive item dependent spells work in another way) and not self applied auras + SpellEntry const* spellInfo = aura->GetSpellProto(); + if(aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) + { + ++itr; + continue; + } + + // skip if not item dependent or have alternative item + if(HasItemFitToSpellReqirements(spellInfo,pItem)) + { + ++itr; + continue; + } + + // no alt item, remove aura, restart check + RemoveAurasDueToSpell(aura->GetId()); + itr = auras.begin(); + } + + // currently casted spells can be dependent from item + for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) + { + if( m_currentSpells[i] && m_currentSpells[i]->getState()!=SPELL_STATE_DELAYED && + !HasItemFitToSpellReqirements(m_currentSpells[i]->m_spellInfo,pItem) ) + InterruptSpell(i); + } +} + +uint32 Player::GetResurrectionSpellId() +{ + // search priceless resurrection possabilities + uint32 prio = 0; + uint32 spell_id = 0; + AuraList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + // Soulstone Resurrection // prio: 3 (max, non death persistent) + if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 ) + { + switch((*itr)->GetId()) + { + case 20707: spell_id = 3026; break; // rank 1 + case 20762: spell_id = 20758; break; // rank 2 + case 20763: spell_id = 20759; break; // rank 3 + case 20764: spell_id = 20760; break; // rank 4 + case 20765: spell_id = 20761; break; // rank 5 + case 27239: spell_id = 27240; break; // rank 6 + default: + sLog.outError("Unhandled spell %%u: S.Resurrection",(*itr)->GetId()); + continue; + } + + prio = 3; + } + // Twisting Nether // prio: 2 (max) + else if((*itr)->GetId()==23701 && roll_chance_i(10)) + { + prio = 2; + spell_id = 23700; + } + } + + // Reincarnation (passive spell) // prio: 1 + if(prio < 1 && HasSpell(20608) && !HasSpellCooldown(21169) && HasItemCount(17030,1)) + spell_id = 21169; + + return spell_id; +} + +bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim) +{ + bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer(); + + // prepare data for near group iteration (PvP and !PvP cases) + uint32 xp = 0; + bool honored_kill = false; + + if(Group *pGroup = GetGroup()) + { + uint32 count = 0; + uint32 sum_level = 0; + Player* member_with_max_level = NULL; + + pGroup->GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level); + + if(member_with_max_level) + { + xp = PvP ? 0 : MaNGOS::XP::Gain(member_with_max_level, pVictim); + + // skip in check PvP case (for speed, not used) + bool is_raid = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsRaid() && pGroup->isRaidGroup(); + bool is_dungeon = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsDungeon(); + float group_rate = MaNGOS::XP::xp_in_group_rate(count,is_raid); + + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* pGroupGuy = itr->getSource(); + if(!pGroupGuy) + continue; + + if(!pGroupGuy->IsAtGroupRewardDistance(pVictim)) + continue; // member (alive or dead) or his corpse at req. distance + + // honor can be in PvP and !PvP (racial leader) cases (for alive) + if(pGroupGuy->isAlive() && pGroupGuy->RewardHonor(pVictim,count) && pGroupGuy==this) + honored_kill = true; + + // xp and reputation only in !PvP case + if(!PvP) + { + float rate = group_rate * float(pGroupGuy->getLevel()) / sum_level; + + // if is in dungeon then all receive full reputation at kill + // rewarded any alive/dead/near_corpse group member + pGroupGuy->RewardReputation(pVictim,is_dungeon ? 1.0f : rate); + + // XP updated only for alive group member + if(pGroupGuy->isAlive()) + { + uint32 itr_xp = uint32(xp*rate); + + pGroupGuy->GiveXP(itr_xp, pVictim); + if(Pet* pet = pGroupGuy->GetPet()) + pet->GivePetXP(itr_xp/2); + } + + // quest objectives updated only for alive group member or dead but with not released body + if(pGroupGuy->isAlive()|| !pGroupGuy->GetCorpse()) + { + // normal creature (not pet/etc) can be only in !PvP case + if(pVictim->GetTypeId()==TYPEID_UNIT) + pGroupGuy->KilledMonster(pVictim->GetEntry(), pVictim->GetGUID()); + } + } + } + } + } + else // if (!pGroup) + { + xp = PvP ? 0 : MaNGOS::XP::Gain(this, pVictim); + + // honor can be in PvP and !PvP (racial leader) cases + if(RewardHonor(pVictim,1)) + honored_kill = true; + + // xp and reputation only in !PvP case + if(!PvP) + { + RewardReputation(pVictim,1); + GiveXP(xp, pVictim); + + if(Pet* pet = GetPet()) + pet->GivePetXP(xp); + + // normal creature (not pet/etc) can be only in !PvP case + if(pVictim->GetTypeId()==TYPEID_UNIT) + KilledMonster(pVictim->GetEntry(),pVictim->GetGUID()); + } + } + return xp || honored_kill; +} + +bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const +{ + if(pRewardSource->GetDistance(this) <= sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + return true; + + if(isAlive()) + return false; + + Corpse* corpse = GetCorpse(); + if(!corpse) + return false; + + return pRewardSource->GetDistance(corpse) <= sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE); +} + +uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const +{ + Item* item = GetWeaponForAttack(attType,true); + + // unarmmed only with base attack + if(attType != BASE_ATTACK && !item) + return 0; + + // weapon skill or (unarmed for base attack) + uint32 skill = item ? item->GetSkill() : SKILL_UNARMED; + return GetBaseSkillValue(skill); +} + +void Player::ResurectUsingRequestData() +{ + ResurrectPlayer(0.0f,false); + + if(GetMaxHealth() > m_resurrectHealth) + SetHealth( m_resurrectHealth ); + else + SetHealth( GetMaxHealth() ); + + if(GetMaxPower(POWER_MANA) > m_resurrectMana) + SetPower(POWER_MANA, m_resurrectMana ); + else + SetPower(POWER_MANA, GetMaxPower(POWER_MANA) ); + + SetPower(POWER_RAGE, 0 ); + + SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) ); + + SpawnCorpseBones(); + + TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); +} + +void Player::SetClientControl(Unit* target, uint8 allowMove) +{ + WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, target->GetPackGUID().size()+1); + data.append(target->GetPackGUID()); + data << uint8(allowMove); + GetSession()->SendPacket(&data); +} + +void Player::UpdateZoneDependentAuras( uint32 newZone ) +{ + // remove new continent flight forms + if( !isGameMaster() && + GetVirtualMapForMapAndZone(GetMapId(),newZone) != 530) + { + RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED); + RemoveSpellsCausingAura(SPELL_AURA_FLY); + } + + // Some spells applied at enter into zone (with subzones) + // Human Illusion + // NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP); + if ( newZone == 2367 ) // Old Hillsbrad Foothills + { + uint32 spellid = 0; + // all horde races + if( GetTeam() == HORDE ) + spellid = getGender() == GENDER_FEMALE ? 35481 : 35480; + // and some alliance races + else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI ) + spellid = getGender() == GENDER_FEMALE ? 35483 : 35482; + + if(spellid && !HasAura(spellid,0) ) + CastSpell(this,spellid,true); + } +} + +void Player::UpdateAreaDependentAuras( uint32 newArea ) +{ + // remove auras from spells with area limitations + for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) + { + // use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date + if(!IsSpellAllowedInLocation(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea)) + RemoveAura(iter); + else + ++iter; + } + + // unmount if enter in this subzone + if( newArea == 35) + RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + // Dragonmaw Illusion + else if( newArea == 3759 || newArea == 3966 || newArea == 3939 ) + { + if( GetDummyAura(40214) ) + { + if( !HasAura(40216,0) ) + CastSpell(this,40216,true); + if( !HasAura(42016,0) ) + CastSpell(this,42016,true); + } + } +} + +uint32 Player::GetCorpseReclaimDelay(bool pvp) const +{ + if( pvp && !sWorld.getConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP) || + !pvp && !sWorld.getConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE) ) + { + return copseReclaimDelay[0]; + } + + time_t now = time(NULL); + // 0..2 full period + uint32 count = (now < m_deathExpireTime) ? (m_deathExpireTime - now)/DEATH_EXPIRE_STEP : 0; + return copseReclaimDelay[count]; +} + +void Player::UpdateCorpseReclaimDelay() +{ + bool pvp = m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH; + + if( pvp && !sWorld.getConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP) || + !pvp && !sWorld.getConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE) ) + return; + + time_t now = time(NULL); + if(now < m_deathExpireTime) + { + // full and partly periods 1..3 + uint32 count = (m_deathExpireTime - now)/DEATH_EXPIRE_STEP +1; + if(count < MAX_DEATH_COUNT) + m_deathExpireTime = now+(count+1)*DEATH_EXPIRE_STEP; + else + m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP; + } + else + m_deathExpireTime = now+DEATH_EXPIRE_STEP; +} + +void Player::SendCorpseReclaimDelay(bool load) +{ + Corpse* corpse = GetCorpse(); + if(!corpse) + return; + + uint32 delay; + if(load) + { + if(corpse->GetGhostTime() > m_deathExpireTime) + return; + + bool pvp = corpse->GetType()==CORPSE_RESURRECTABLE_PVP; + + uint32 count; + if( pvp && sWorld.getConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP) || + !pvp && sWorld.getConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE) ) + { + count = (m_deathExpireTime-corpse->GetGhostTime())/DEATH_EXPIRE_STEP; + if(count>=MAX_DEATH_COUNT) + count = MAX_DEATH_COUNT-1; + } + else + count=0; + + time_t expected_time = corpse->GetGhostTime()+copseReclaimDelay[count]; + + time_t now = time(NULL); + if(now >= expected_time) + return; + + delay = expected_time-now; + } + else + delay = GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP); + + //! corpse reclaim delay 30 * 1000ms or longer at often deaths + WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4); + data << uint32(delay*1000); + GetSession()->SendPacket( &data ); +} + +Player* Player::GetNextRandomRaidMember(float radius) +{ + Group *pGroup = GetGroup(); + if(!pGroup) + return NULL; + + std::vector nearMembers; + nearMembers.reserve(pGroup->GetMembersCount()); + + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + + // IsHostileTo check duel and controlled by enemy + if( Target && Target != this && IsWithinDistInMap(Target, radius) && + !Target->HasInvisibilityAura() && !IsHostileTo(Target) ) + nearMembers.push_back(Target); + } + + if (nearMembers.empty()) + return NULL; + + uint32 randTarget = urand(0,nearMembers.size()-1); + return nearMembers[randTarget]; +} + +void Player::UpdateUnderwaterState( Map* m, float x, float y, float z ) +{ + float water_z = m->GetWaterLevel(x,y); + float height_z = m->GetHeight(x,y,z, false); // use .map base surface height + uint8 flag1 = m->GetTerrainType(x,y); + + //!Underwater check, not in water if underground or above water level + if (height_z <= INVALID_HEIGHT || z < (height_z-2) || z > (water_z - 2) ) + m_isunderwater &= 0x7A; + else if ((z < (water_z - 2)) && (flag1 & 0x01)) + m_isunderwater |= 0x01; + + //!in lava check, anywhere under lava level + if ((height_z <= INVALID_HEIGHT || z < (height_z - 0)) && (flag1 == 0x00) && IsInWater()) + m_isunderwater |= 0x80; +} + +void Player::SetCanParry( bool value ) +{ + if(m_canParry==value) + return; + + m_canParry = value; + UpdateParryPercentage(); +} + +void Player::SetCanBlock( bool value ) +{ + if(m_canBlock==value) + return; + + m_canBlock = value; + UpdateBlockPercentage(); +} + +bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const +{ + for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr) + if(itr->pos == this->pos) + return true; + + return false; +} + +bool Player::isAllowUseBattleGroundObject() +{ + return ( //InBattleGround() && // in battleground - not need, check in other cases + !IsMounted() && // not mounted + !HasStealthAura() && // not stealthed + !HasInvisibilityAura() && // not invisible + !HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup + isAlive() // live player + ); +} diff --git a/src/game/Player.h b/src/game/Player.h new file mode 100644 index 000000000..aaaaac60f --- /dev/null +++ b/src/game/Player.h @@ -0,0 +1,2317 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PLAYER_H +#define _PLAYER_H + +#include "Common.h" +#include "ItemPrototype.h" +#include "Unit.h" +#include "Item.h" + +#include "Database/DatabaseEnv.h" +#include "NPCHandler.h" +#include "QuestDef.h" +#include "Group.h" +#include "Bag.h" +#include "WorldSession.h" +#include "Pet.h" +#include "Util.h" // for Tokens typedef + +#include +#include + +struct Mail; +class Channel; +class DynamicObject; +class Creature; +class Pet; +class PlayerMenu; +class Transport; +class UpdateMask; +class PlayerSocial; + +typedef std::deque PlayerMails; + +#define PLAYER_MAX_SKILLS 127 +#define PLAYER_MAX_DAILY_QUESTS 25 + +// Note: SPELLMOD_* values is aura types in fact +enum SpellModType +{ + SPELLMOD_FLAT = 107, // SPELL_AURA_ADD_FLAT_MODIFIER + SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER +}; + +enum PlayerSpellState +{ + PLAYERSPELL_UNCHANGED = 0, + PLAYERSPELL_CHANGED = 1, + PLAYERSPELL_NEW = 2, + PLAYERSPELL_REMOVED = 3 +}; + +struct PlayerSpell +{ + uint16 slotId : 16; + PlayerSpellState state : 8; + bool active : 1; + bool disabled : 1; +}; + +#define SPELL_WITHOUT_SLOT_ID uint16(-1) + +struct SpellModifier +{ + SpellModOp op : 8; + SpellModType type : 8; + int16 charges : 16; + int32 value; + uint64 mask; + uint32 spellId; + uint32 effectId; + Spell const* lastAffected; +}; + +typedef HM_NAMESPACE::hash_map PlayerSpellMap; +typedef std::list SpellModList; + +struct SpellCooldown +{ + time_t end; + uint16 itemid; +}; + +typedef std::map SpellCooldowns; + +enum TrainerSpellState +{ + TRAINER_SPELL_GREEN = 0, + TRAINER_SPELL_RED = 1, + TRAINER_SPELL_GRAY = 2 +}; + +enum ActionButtonUpdateState +{ + ACTIONBUTTON_UNCHANGED = 0, + ACTIONBUTTON_CHANGED = 1, + ACTIONBUTTON_NEW = 2, + ACTIONBUTTON_DELETED = 3 +}; + +struct ActionButton +{ + ActionButton() : action(0), type(0), misc(0), uState( ACTIONBUTTON_NEW ) {} + ActionButton(uint16 _action, uint8 _type, uint8 _misc) : action(_action), type(_type), misc(_misc), uState( ACTIONBUTTON_NEW ) {} + + uint16 action; + uint8 type; + uint8 misc; + ActionButtonUpdateState uState; +}; + +enum ActionButtonType +{ + ACTION_BUTTON_SPELL = 0, + ACTION_BUTTON_MACRO = 64, + ACTION_BUTTON_CMACRO= 65, + ACTION_BUTTON_ITEM = 128 +}; + +#define MAX_ACTION_BUTTONS 132 //checked in 2.3.0 + +typedef std::map ActionButtonList; + +typedef std::pair CreateSpellPair; + +struct PlayerCreateInfoItem +{ + PlayerCreateInfoItem(uint32 id, uint32 amount) : item_id(id), item_amount(amount) {} + + uint32 item_id; + uint32 item_amount; +}; + +typedef std::list PlayerCreateInfoItems; + +struct PlayerClassLevelInfo +{ + PlayerClassLevelInfo() : basehealth(0), basemana(0) {} + uint16 basehealth; + uint16 basemana; +}; + +struct PlayerClassInfo +{ + PlayerClassInfo() : levelInfo(NULL) { } + + PlayerClassLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1 +}; + +struct PlayerLevelInfo +{ + PlayerLevelInfo() { for(int i=0; i < MAX_STATS; ++i ) stats[i] = 0; } + + uint8 stats[MAX_STATS]; +}; + +struct PlayerInfo +{ + // existence checked by displayId != 0 // existence checked by displayId != 0 + PlayerInfo() : displayId_m(0),displayId_f(0),levelInfo(NULL) + { + } + + uint32 mapId; + uint32 zoneId; + float positionX; + float positionY; + float positionZ; + uint16 displayId_m; + uint16 displayId_f; + PlayerCreateInfoItems item; + std::list spell; + std::list action[4]; + + PlayerLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1 +}; + +struct PvPInfo +{ + PvPInfo() : inHostileArea(false), endTimer(0) {} + + bool inHostileArea; + time_t endTimer; +}; + +struct DuelInfo +{ + DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0) {} + + Player *initiator; + Player *opponent; + time_t startTimer; + time_t startTime; + time_t outOfBound; +}; + +struct Areas +{ + uint32 areaID; + uint32 areaFlag; + float x1; + float x2; + float y1; + float y2; +}; + +enum FactionFlags +{ + FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction) + FACTION_FLAG_AT_WAR = 0x02, // enable AtWar-button in client. player controlled (except opposition team always war state), Flag only set on initial creation + FACTION_FLAG_HIDDEN = 0x04, // hidden faction from reputation pane in client (player can gain reputation, but this update not sent to client) + FACTION_FLAG_INVISIBLE_FORCED = 0x08, // always overwrite FACTION_FLAG_VISIBLE and hide faction in rep.list, used for hide opposite team factions + FACTION_FLAG_PEACE_FORCED = 0x10, // always overwrite FACTION_FLAG_AT_WAR, used for prevent war with own team factions + FACTION_FLAG_INACTIVE = 0x20, // player controlled, state stored in characters.data ( CMSG_SET_FACTION_INACTIVE ) + FACTION_FLAG_RIVAL = 0x40 // flag for the two competing outland factions +}; + +typedef uint32 RepListID; +struct FactionState +{ + uint32 ID; + RepListID ReputationListID; + uint32 Flags; + int32 Standing; + bool Changed; +}; + +typedef std::map FactionStateList; + +typedef std::map ForcedReactions; + +typedef std::set GuardianPetList; + +struct EnchantDuration +{ + EnchantDuration() : item(NULL), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) {}; + EnchantDuration(Item * _item, EnchantmentSlot _slot, uint32 _leftduration) : item(_item), slot(_slot), leftduration(_leftduration) { assert(item); }; + + Item * item; + EnchantmentSlot slot; + uint32 leftduration; +}; + +typedef std::list EnchantDurationList; +typedef std::list ItemDurationList; + +struct LookingForGroupSlot +{ + LookingForGroupSlot() : entry(0), type(0) {} + bool Empty() const { return !entry && !type; } + void Clear() { entry = 0; type = 0; } + void Set(uint32 _entry, uint32 _type ) { entry = _entry; type = _type; } + bool Is(uint32 _entry, uint32 _type) const { return entry==_entry && type==_type; } + bool canAutoJoin() const { return entry && (type == 1 || type == 5); } + + uint32 entry; + uint32 type; +}; + +#define MAX_LOOKING_FOR_GROUP_SLOT 3 + +struct LookingForGroup +{ + LookingForGroup() {} + bool HaveInSlot(LookingForGroupSlot const& slot) const { return HaveInSlot(slot.entry,slot.type); } + bool HaveInSlot(uint32 _entry, uint32 _type) const + { + for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i) + if(slots[i].Is(_entry,_type)) + return true; + return false; + } + + bool canAutoJoin() const + { + for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i) + if(slots[i].canAutoJoin()) + return true; + return false; + } + + bool Empty() const + { + for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i) + if(!slots[i].Empty()) + return false; + return more.Empty(); + } + + LookingForGroupSlot slots[MAX_LOOKING_FOR_GROUP_SLOT]; + LookingForGroupSlot more; + std::string comment; +}; + +enum PlayerMovementType +{ + MOVE_ROOT = 1, + MOVE_UNROOT = 2, + MOVE_WATER_WALK = 3, + MOVE_LAND_WALK = 4 +}; + +enum DrunkenState +{ + DRUNKEN_SOBER = 0, + DRUNKEN_TIPSY = 1, + DRUNKEN_DRUNK = 2, + DRUNKEN_SMASHED = 3 +}; + +enum PlayerStateType +{ + /* + PLAYER_STATE_DANCE + PLAYER_STATE_SLEEP + PLAYER_STATE_SIT + PLAYER_STATE_STAND + PLAYER_STATE_READYUNARMED + PLAYER_STATE_WORK + PLAYER_STATE_POINT(DNR) + PLAYER_STATE_NONE // not used or just no state, just standing there? + PLAYER_STATE_STUN + PLAYER_STATE_DEAD + PLAYER_STATE_KNEEL + PLAYER_STATE_USESTANDING + PLAYER_STATE_STUN_NOSHEATHE + PLAYER_STATE_USESTANDING_NOSHEATHE + PLAYER_STATE_WORK_NOSHEATHE + PLAYER_STATE_SPELLPRECAST + PLAYER_STATE_READYRIFLE + PLAYER_STATE_WORK_NOSHEATHE_MINING + PLAYER_STATE_WORK_NOSHEATHE_CHOPWOOD + PLAYER_STATE_AT_EASE + PLAYER_STATE_READY1H + PLAYER_STATE_SPELLKNEELSTART + PLAYER_STATE_SUBMERGED + */ + + PLAYER_STATE_NONE = 0, + PLAYER_STATE_SIT = 1, + PLAYER_STATE_SIT_CHAIR = 2, + PLAYER_STATE_SLEEP = 3, + PLAYER_STATE_SIT_LOW_CHAIR = 4, + PLAYER_STATE_SIT_MEDIUM_CHAIR = 5, + PLAYER_STATE_SIT_HIGH_CHAIR = 6, + PLAYER_STATE_DEAD = 7, + PLAYER_STATE_KNEEL = 8, + + PLAYER_STATE_FORM_ALL = 0x00FF0000, + + PLAYER_STATE_FLAG_ALWAYS_STAND = 0x01, // byte 4 + PLAYER_STATE_FLAG_CREEP = 0x02000000, + PLAYER_STATE_FLAG_UNTRACKABLE = 0x04000000, + PLAYER_STATE_FLAG_ALL = 0xFF000000, +}; + +enum PlayerFlags +{ + PLAYER_FLAGS_GROUP_LEADER = 0x00000001, + PLAYER_FLAGS_AFK = 0x00000002, + PLAYER_FLAGS_DND = 0x00000004, + PLAYER_FLAGS_GM = 0x00000008, + PLAYER_FLAGS_GHOST = 0x00000010, + PLAYER_FLAGS_RESTING = 0x00000020, + PLAYER_FLAGS_FFA_PVP = 0x00000080, + PLAYER_FLAGS_CONTESTED_PVP = 0x00000100, // Player has been involved in a PvP combat and will be attacked by contested guards + PLAYER_FLAGS_IN_PVP = 0x00000200, + PLAYER_FLAGS_HIDE_HELM = 0x00000400, + PLAYER_FLAGS_HIDE_CLOAK = 0x00000800, + PLAYER_FLAGS_UNK1 = 0x00001000, // played long time + PLAYER_FLAGS_UNK2 = 0x00002000, // played too long time + PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag + PLAYER_FLAGS_SANCTUARY = 0x00010000, // player entered sanctuary + PLAYER_FLAGS_UNK4 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1) + PLAYER_UNK = 0x00040000, // 2.0.8... +}; + +// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1< QuestStatusMap; + +enum QuestSlotOffsets +{ + QUEST_ID_OFFSET = 0, + QUEST_STATE_OFFSET = 1, + QUEST_COUNTS_OFFSET = 2, + QUEST_TIME_OFFSET = 3 +}; + +#define MAX_QUEST_OFFSET 4 + +enum QuestSlotStateMask +{ + QUEST_STATE_NONE = 0x0000, + QUEST_STATE_COMPLETE = 0x0001, + QUEST_STATE_FAIL = 0x0002 +}; + +class Quest; +class Spell; +class Item; +class WorldSession; + +enum PlayerSlots +{ + // first slot for item stored (in any way in player m_items data) + PLAYER_SLOT_START = 0, + // last+1 slot for item stored (in any way in player m_items data) + PLAYER_SLOT_END = 118, + PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START) +}; + +enum EquipmentSlots +{ + EQUIPMENT_SLOT_START = 0, + EQUIPMENT_SLOT_HEAD = 0, + EQUIPMENT_SLOT_NECK = 1, + EQUIPMENT_SLOT_SHOULDERS = 2, + EQUIPMENT_SLOT_BODY = 3, + EQUIPMENT_SLOT_CHEST = 4, + EQUIPMENT_SLOT_WAIST = 5, + EQUIPMENT_SLOT_LEGS = 6, + EQUIPMENT_SLOT_FEET = 7, + EQUIPMENT_SLOT_WRISTS = 8, + EQUIPMENT_SLOT_HANDS = 9, + EQUIPMENT_SLOT_FINGER1 = 10, + EQUIPMENT_SLOT_FINGER2 = 11, + EQUIPMENT_SLOT_TRINKET1 = 12, + EQUIPMENT_SLOT_TRINKET2 = 13, + EQUIPMENT_SLOT_BACK = 14, + EQUIPMENT_SLOT_MAINHAND = 15, + EQUIPMENT_SLOT_OFFHAND = 16, + EQUIPMENT_SLOT_RANGED = 17, + EQUIPMENT_SLOT_TABARD = 18, + EQUIPMENT_SLOT_END = 19 +}; + +enum InventorySlots +{ + INVENTORY_SLOT_BAG_0 = 255, + INVENTORY_SLOT_BAG_START = 19, + INVENTORY_SLOT_BAG_1 = 19, + INVENTORY_SLOT_BAG_2 = 20, + INVENTORY_SLOT_BAG_3 = 21, + INVENTORY_SLOT_BAG_4 = 22, + INVENTORY_SLOT_BAG_END = 23, + + INVENTORY_SLOT_ITEM_START = 23, + INVENTORY_SLOT_ITEM_1 = 23, + INVENTORY_SLOT_ITEM_2 = 24, + INVENTORY_SLOT_ITEM_3 = 25, + INVENTORY_SLOT_ITEM_4 = 26, + INVENTORY_SLOT_ITEM_5 = 27, + INVENTORY_SLOT_ITEM_6 = 28, + INVENTORY_SLOT_ITEM_7 = 29, + INVENTORY_SLOT_ITEM_8 = 30, + INVENTORY_SLOT_ITEM_9 = 31, + INVENTORY_SLOT_ITEM_10 = 32, + INVENTORY_SLOT_ITEM_11 = 33, + INVENTORY_SLOT_ITEM_12 = 34, + INVENTORY_SLOT_ITEM_13 = 35, + INVENTORY_SLOT_ITEM_14 = 36, + INVENTORY_SLOT_ITEM_15 = 37, + INVENTORY_SLOT_ITEM_16 = 38, + INVENTORY_SLOT_ITEM_END = 39 +}; + +enum BankSlots +{ + BANK_SLOT_ITEM_START = 39, + BANK_SLOT_ITEM_1 = 39, + BANK_SLOT_ITEM_2 = 40, + BANK_SLOT_ITEM_3 = 41, + BANK_SLOT_ITEM_4 = 42, + BANK_SLOT_ITEM_5 = 43, + BANK_SLOT_ITEM_6 = 44, + BANK_SLOT_ITEM_7 = 45, + BANK_SLOT_ITEM_8 = 46, + BANK_SLOT_ITEM_9 = 47, + BANK_SLOT_ITEM_10 = 48, + BANK_SLOT_ITEM_11 = 49, + BANK_SLOT_ITEM_12 = 50, + BANK_SLOT_ITEM_13 = 51, + BANK_SLOT_ITEM_14 = 52, + BANK_SLOT_ITEM_15 = 53, + BANK_SLOT_ITEM_16 = 54, + BANK_SLOT_ITEM_17 = 55, + BANK_SLOT_ITEM_18 = 56, + BANK_SLOT_ITEM_19 = 57, + BANK_SLOT_ITEM_20 = 58, + BANK_SLOT_ITEM_21 = 59, + BANK_SLOT_ITEM_22 = 60, + BANK_SLOT_ITEM_23 = 61, + BANK_SLOT_ITEM_24 = 62, + BANK_SLOT_ITEM_25 = 63, + BANK_SLOT_ITEM_26 = 64, + BANK_SLOT_ITEM_27 = 65, + BANK_SLOT_ITEM_28 = 66, + BANK_SLOT_ITEM_END = 67, + + BANK_SLOT_BAG_START = 67, + BANK_SLOT_BAG_1 = 67, + BANK_SLOT_BAG_2 = 68, + BANK_SLOT_BAG_3 = 69, + BANK_SLOT_BAG_4 = 70, + BANK_SLOT_BAG_5 = 71, + BANK_SLOT_BAG_6 = 72, + BANK_SLOT_BAG_7 = 73, + BANK_SLOT_BAG_END = 74 +}; + +enum BuyBackSlots +{ + // stored in m_buybackitems + BUYBACK_SLOT_START = 74, + BUYBACK_SLOT_1 = 74, + BUYBACK_SLOT_2 = 75, + BUYBACK_SLOT_3 = 76, + BUYBACK_SLOT_4 = 77, + BUYBACK_SLOT_5 = 78, + BUYBACK_SLOT_6 = 79, + BUYBACK_SLOT_7 = 80, + BUYBACK_SLOT_8 = 81, + BUYBACK_SLOT_9 = 82, + BUYBACK_SLOT_10 = 83, + BUYBACK_SLOT_11 = 84, + BUYBACK_SLOT_12 = 85, + BUYBACK_SLOT_END = 86 +}; + +enum KeyRingSlots +{ + KEYRING_SLOT_START = 86, + KEYRING_SLOT_END = 118 +}; + +struct ItemPosCount +{ + ItemPosCount(uint16 _pos, uint8 _count) : pos(_pos), count(_count) {} + bool isContainedIn(std::vector const& vec) const; + uint16 pos; + uint8 count; +}; +typedef std::vector ItemPosCountVec; + +enum SwitchWeapon +{ + DEFAULT_SWITCH_WEAPON = 1500, //cooldown in ms + ROGUE_SWITCH_WEAPON = 1000 +}; + +enum TradeSlots +{ + TRADE_SLOT_COUNT = 7, + TRADE_SLOT_TRADED_COUNT = 6, + TRADE_SLOT_NONTRADED = 6 +}; + +enum TransferAbortReason +{ + TRANSFER_ABORT_MAX_PLAYERS = 0x0001, // Transfer Aborted: instance is full + TRANSFER_ABORT_NOT_FOUND = 0x0002, // Transfer Aborted: instance not found + TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x0003, // You have entered too many instances recently. + TRANSFER_ABORT_ZONE_IN_COMBAT = 0x0005, // Unable to zone in while an encounter is in progress. + TRANSFER_ABORT_INSUF_EXPAN_LVL1 = 0x0106, // You must have TBC expansion installed to access this area. + TRANSFER_ABORT_DIFFICULTY1 = 0x0007, // Normal difficulty mode is not available for %s. + TRANSFER_ABORT_DIFFICULTY2 = 0x0107, // Heroic difficulty mode is not available for %s. + TRANSFER_ABORT_DIFFICULTY3 = 0x0207 // Epic difficulty mode is not available for %s. +}; + +enum InstanceResetWarningType +{ + RAID_INSTANCE_WARNING_HOURS = 1, // WARNING! %s is scheduled to reset in %d hour(s). + RAID_INSTANCE_WARNING_MIN = 2, // WARNING! %s is scheduled to reset in %d minute(s)! + RAID_INSTANCE_WARNING_MIN_SOON = 3, // WARNING! %s is scheduled to reset in %d minute(s). Please exit the zone or you will be returned to your bind location! + RAID_INSTANCE_WELCOME = 4 // Welcome to %s. This raid instance is scheduled to reset in %s. +}; + +struct MovementInfo +{ + // common + //uint32 flags; + uint8 unk1; + uint32 time; + float x, y, z, o; + // transport + uint64 t_guid; + float t_x, t_y, t_z, t_o; + uint32 t_time; + // swimming and unk + float s_pitch; + // last fall time + uint32 fallTime; + // jumping + float j_unk, j_sinAngle, j_cosAngle, j_xyspeed; + // spline + float u_unk1; + + MovementInfo() + { + //flags = + time = t_time = fallTime = 0; + unk1 = 0; + x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f; + t_guid = 0; + } + + /*void SetMovementFlags(uint32 _flags) + { + flags = _flags; + }*/ +}; + +// flags that use in movement check for example at spell casting +MovementFlags const movementFlagsMask = MovementFlags( + MOVEMENTFLAG_FORWARD |MOVEMENTFLAG_BACKWARD |MOVEMENTFLAG_STRAFE_LEFT|MOVEMENTFLAG_STRAFE_RIGHT| + MOVEMENTFLAG_PITCH_UP|MOVEMENTFLAG_PITCH_DOWN|MOVEMENTFLAG_FLY_UNK1 | + MOVEMENTFLAG_JUMPING |MOVEMENTFLAG_FALLING |MOVEMENTFLAG_FLY_UP | + MOVEMENTFLAG_FLYING |MOVEMENTFLAG_SPLINE +); + +MovementFlags const movementOrTurningFlagsMask = MovementFlags( + movementFlagsMask | MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT +); +class InstanceSave; + +enum RestType +{ + REST_TYPE_NO = 0, + REST_TYPE_IN_TAVERN = 1, + REST_TYPE_IN_CITY = 2 +}; + +enum DuelCompleteType +{ + DUEL_INTERUPTED = 0, + DUEL_WON = 1, + DUEL_FLED = 2 +}; + +enum TeleportToOptions +{ + TELE_TO_GM_MODE = 0x01, + TELE_TO_NOT_LEAVE_TRANSPORT = 0x02, + TELE_TO_NOT_LEAVE_COMBAT = 0x04, + TELE_TO_NOT_UNSUMMON_PET = 0x08, + TELE_TO_SPELL = 0x10, +}; + +/// Type of environmental damages +enum EnviromentalDamage +{ + DAMAGE_EXHAUSTED = 0, + DAMAGE_DROWNING = 1, + DAMAGE_FALL = 2, + DAMAGE_LAVA = 3, + DAMAGE_SLIME = 4, + DAMAGE_FIRE = 5, + DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss +}; + +// used at player loading query list preparing, and later result selection +enum PlayerLoginQueryIndex +{ + PLAYER_LOGIN_QUERY_LOADFROM = 0, + PLAYER_LOGIN_QUERY_LOADGROUP = 1, + PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES = 2, + PLAYER_LOGIN_QUERY_LOADAURAS = 3, + PLAYER_LOGIN_QUERY_LOADSPELLS = 4, + PLAYER_LOGIN_QUERY_LOADQUESTSTATUS = 5, + PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS = 6, + PLAYER_LOGIN_QUERY_LOADTUTORIALS = 7, // common for all characters for some account at specific realm + PLAYER_LOGIN_QUERY_LOADREPUTATION = 8, + PLAYER_LOGIN_QUERY_LOADINVENTORY = 9, + PLAYER_LOGIN_QUERY_LOADACTIONS = 10, + PLAYER_LOGIN_QUERY_LOADMAILCOUNT = 11, + PLAYER_LOGIN_QUERY_LOADMAILDATE = 12, + PLAYER_LOGIN_QUERY_LOADSOCIALLIST = 13, + PLAYER_LOGIN_QUERY_LOADHOMEBIND = 14, + PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 15, + PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16, + PLAYER_LOGIN_QUERY_LOADGUILD = 17, +}; + +#define MAX_PLAYER_LOGIN_QUERY 18 + +// Player summoning auto-decline time (in secs) +#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) +#define MAX_MONEY_AMOUNT (0x7FFFFFFF-1) + +struct InstancePlayerBind +{ + InstanceSave *save; + bool perm; + /* permanent PlayerInstanceBinds are created in Raid/Heroic instances for players + that aren't already permanently bound when they are inside when a boss is killed + or when they enter an instance that the group leader is permanently bound to. */ + InstancePlayerBind() : save(NULL), perm(false) {} +}; + +class MANGOS_DLL_SPEC PlayerTaxi +{ + public: + PlayerTaxi(); + ~PlayerTaxi() {} + // Nodes + void InitTaxiNodesForLevel(uint32 race, uint32 level); + void LoadTaxiMask(const char* data); + void SaveTaxiMask(const char* data); + + uint32 GetTaximask( uint8 index ) const { return m_taximask[index]; } + bool IsTaximaskNodeKnown(uint32 nodeidx) const + { + uint8 field = uint8((nodeidx - 1) / 32); + uint32 submask = 1<<((nodeidx-1)%32); + return (m_taximask[field] & submask) == submask; + } + bool SetTaximaskNode(uint32 nodeidx) + { + uint8 field = uint8((nodeidx - 1) / 32); + uint32 submask = 1<<((nodeidx-1)%32); + if ((m_taximask[field] & submask) != submask ) + { + m_taximask[field] |= submask; + return true; + } + else + return false; + } + void AppendTaximaskTo(ByteBuffer& data,bool all); + + // Destinations + bool LoadTaxiDestinationsFromString(std::string values); + std::string SaveTaxiDestinationsToString(); + + void ClearTaxiDestinations() { m_TaxiDestinations.clear(); } + void AddTaxiDestination(uint32 dest) { m_TaxiDestinations.push_back(dest); } + uint32 GetTaxiSource() const { return m_TaxiDestinations.empty() ? 0 : m_TaxiDestinations.front(); } + uint32 GetTaxiDestination() const { return m_TaxiDestinations.size() < 2 ? 0 : m_TaxiDestinations[1]; } + uint32 GetCurrentTaxiPath() const; + uint32 NextTaxiDestination() + { + m_TaxiDestinations.pop_front(); + return GetTaxiDestination(); + } + bool empty() const { return m_TaxiDestinations.empty(); } + private: + TaxiMask m_taximask; + std::deque m_TaxiDestinations; +}; + +class MANGOS_DLL_SPEC Player : public Unit +{ + friend class WorldSession; + friend void Item::AddToUpdateQueueOf(Player *player); + friend void Item::RemoveFromUpdateQueueOf(Player *player); + public: + explicit Player (WorldSession *session); + ~Player ( ); + + void CleanupsBeforeDelete(); + + static UpdateMask updateVisualBits; + static void InitVisibleBits(); + + void AddToWorld(); + void RemoveFromWorld(); + + bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); + + bool TeleportTo(WorldLocation const &loc, uint32 options = 0) + { + return TeleportTo(loc.mapid, loc.x, loc.y, loc.z, options); + } + + void SetSummonPoint(uint32 mapid, float x, float y, float z) + { + m_summon_expire = time(NULL) + MAX_PLAYER_SUMMON_DELAY; + m_summon_mapid = mapid; + m_summon_x = x; + m_summon_y = y; + m_summon_z = z; + } + void SummonIfPossible(bool agree); + + bool Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId ); + + void Update( uint32 time ); + + void BuildEnumData( QueryResult * result, WorldPacket * p_data ); + + void SetInWater(bool apply); + + bool IsInWater() const { return m_isInWater; } + bool IsUnderWater() const; + + void SendInitialPacketsBeforeAddToMap(); + void SendInitialPacketsAfterAddToMap(); + void SendTransferAborted(uint32 mapid, uint16 reason); + void SendInstanceResetWarning(uint32 mapid, uint32 time); + + bool CanInteractWithNPCs(bool alive = true) const; + + bool ToggleAFK(); + bool ToggleDND(); + bool isAFK() const { return HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_AFK); }; + bool isDND() const { return HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_DND); }; + uint8 chatTag() const; + std::string afkMsg; + std::string dndMsg; + + PlayerSocial *GetSocial() { return m_social; } + + PlayerTaxi m_taxi; + void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(),getLevel()); } + bool ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_id = 0 , Creature* npc = NULL); + // mount_id can be used in scripting calls + bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); } + void SetAcceptTicket(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_GM_ACCEPT_TICKETS; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_ACCEPT_TICKETS; } + bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; } + void SetAcceptWhispers(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; } + bool isGameMaster() const { return m_ExtraFlags & PLAYER_EXTRA_GM_ON; } + void SetGameMaster(bool on); + bool isGMChat() const { return GetSession()->GetSecurity() >= SEC_MODERATOR && (m_ExtraFlags & PLAYER_EXTRA_GM_CHAT); } + void SetGMChat(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_GM_CHAT; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_CHAT; } + bool isTaxiCheater() const { return m_ExtraFlags & PLAYER_EXTRA_TAXICHEAT; } + void SetTaxiCheater(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; } + bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); } + void SetGMVisible(bool on); + void SetPvPDeath(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_PVP_DEATH; else m_ExtraFlags &= ~PLAYER_EXTRA_PVP_DEATH; } + + void GiveXP(uint32 xp, Unit* victim); + void GiveLevel(uint32 level); + void InitStatsForLevel(bool reapplyMods = false); + + // Played Time Stuff + time_t m_logintime; + time_t m_Last_tick; + uint32 m_Played_time[2]; + uint32 GetTotalPlayedTime() { return m_Played_time[0]; }; + uint32 GetLevelPlayedTime() { return m_Played_time[1]; }; + + void setDeathState(DeathState s); // overwrite Unit::setDeathState + + void InnEnter (int time,uint32 mapid, float x,float y,float z) + { + inn_pos_mapid = mapid; + inn_pos_x = x; + inn_pos_y = y; + inn_pos_z = z; + time_inn_enter = time; + }; + + float GetRestBonus() const { return m_rest_bonus; }; + void SetRestBonus(float rest_bonus_new); + + RestType GetRestType() const { return rest_type; }; + void SetRestType(RestType n_r_type) { rest_type = n_r_type; }; + + uint32 GetInnPosMapId() const { return inn_pos_mapid; }; + float GetInnPosX() const { return inn_pos_x; }; + float GetInnPosY() const { return inn_pos_y; }; + float GetInnPosZ() const { return inn_pos_z; }; + + int GetTimeInnEnter() const { return time_inn_enter; }; + void UpdateInnerTime (int time) { time_inn_enter = time; }; + + void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); + void RemoveMiniPet(); + Pet* GetMiniPet(); + void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); } + void RemoveGuardians(); + bool HasGuardianWithEntry(uint32 entry); + void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); } + GuardianPetList const& GetGuardians() const { return m_guardianPets; } + void Uncharm(); + + void Say(std::string text, const uint32 language); + void Yell(std::string text, const uint32 language); + void TextEmote(std::string text); + void Whisper(std::string text, const uint32 language,uint64 receiver); + void BuildPlayerChat(WorldPacket *data, uint8 msgtype, std::string text, uint32 language) const; + + /*********************************************************/ + /*** STORAGE SYSTEM ***/ + /*********************************************************/ + + void SetVirtualItemSlot( uint8 i, Item* item); + void SetSheath( uint32 sheathed ); + uint8 FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const; + uint32 GetItemCount( uint32 item, bool inBankAlso = false, Item* skipItem = NULL ) const; + Item* GetItemByGuid( uint64 guid ) const; + Item* GetItemByPos( uint16 pos ) const; + Item* GetItemByPos( uint8 bag, uint8 slot ) const; + Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const; + Item* GetShield(bool useable = false) const; + static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot + std::vector &GetItemUpdateQueue() { return m_itemUpdateQueue; } + static bool IsInventoryPos( uint16 pos ) { return IsInventoryPos(pos >> 8,pos & 255); } + static bool IsInventoryPos( uint8 bag, uint8 slot ); + static bool IsEquipmentPos( uint16 pos ) { return IsEquipmentPos(pos >> 8,pos & 255); } + static bool IsEquipmentPos( uint8 bag, uint8 slot ); + static bool IsBagPos( uint16 pos ); + static bool IsBankPos( uint16 pos ) { return IsBankPos(pos >> 8,pos & 255); } + static bool IsBankPos( uint8 bag, uint8 slot ); + bool HasBankBagSlot( uint8 slot ) const; + bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const; + bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL); + Item* GetItemOrItemWithGemEquipped( uint32 item ) const; + uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); } + uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); } + uint8 CanStoreNewItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL ) const + { + return _CanStoreItem(bag, slot, dest, item, count, NULL, false, no_space_count ); + } + uint8 CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, Item *pItem, bool swap = false ) const + { + if(!pItem) + return EQUIP_ERR_ITEM_NOT_FOUND; + uint32 count = pItem->GetCount(); + return _CanStoreItem( bag, slot, dest, pItem->GetEntry(), count, pItem, swap, NULL ); + + } + uint8 CanStoreItems( Item **pItem,int count) const; + uint8 CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, uint32 count, bool swap ) const; + uint8 CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading = true ) const; + uint8 CanUnequipItems( uint32 item, uint32 count ) const; + uint8 CanUnequipItem( uint16 src, bool swap ) const; + uint8 CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, Item *pItem, bool swap, bool not_loading = true ) const; + uint8 CanUseItem( Item *pItem, bool not_loading = true ) const; + bool HasItemTotemCategory( uint32 TotemCategory ) const; + bool CanUseItem( ItemPrototype const *pItem ); + uint8 CanUseAmmo( uint32 item ) const; + Item* StoreNewItem( ItemPosCountVec const& pos, uint32 item, bool update,int32 randomPropertyId = 0 ); + Item* StoreItem( ItemPosCountVec const& pos, Item *pItem, bool update ); + Item* EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update ); + Item* EquipItem( uint16 pos, Item *pItem, bool update ); + void AutoUnequipOffhandIfNeed(); + + uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; + uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const; + + void ApplyEquipCooldown( Item * pItem ); + void SetAmmo( uint32 item ); + void RemoveAmmo(); + float GetAmmoDPS() const { return m_ammoDPS; } + bool CheckAmmoCompatibility(const ItemPrototype *ammo_proto) const; + void QuickEquipItem( uint16 pos, Item *pItem); + void VisualizeItem( uint8 slot, Item *pItem); + void SetVisibleItemSlot(uint8 slot, Item *pItem); + Item* BankItem( ItemPosCountVec const& dest, Item *pItem, bool update ) + { + return StoreItem( dest, pItem, update); + } + Item* BankItem( uint16 pos, Item *pItem, bool update ); + void RemoveItem( uint8 bag, uint8 slot, bool update ); + void MoveItemFromInventory(uint8 bag, uint8 slot, bool update); + // in trade, auction, guild bank, mail.... + void MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool update, bool in_characterInventoryDB = false); + // in trade, guild bank, mail.... + void RemoveItemDependentAurasAndCasts( Item * pItem ); + void DestroyItem( uint8 bag, uint8 slot, bool update ); + void DestroyItemCount( uint32 item, uint32 count, bool update, bool unequip_check = false); + void DestroyItemCount( Item* item, uint32& count, bool update ); + void DestroyConjuredItems( bool update ); + void DestroyZoneLimitedItem( bool update, uint32 new_zone ); + void SplitItem( uint16 src, uint16 dst, uint32 count ); + void SwapItem( uint16 src, uint16 dst ); + void AddItemToBuyBackSlot( Item *pItem ); + Item* GetItemFromBuyBackSlot( uint32 slot ); + void RemoveItemFromBuyBackSlot( uint32 slot, bool del ); + uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END-KEYRING_SLOT_START; } + void SendEquipError( uint8 msg, Item* pItem, Item *pItem2 ); + void SendBuyError( uint8 msg, Creature* pCreature, uint32 item, uint32 param ); + void SendSellError( uint8 msg, Creature* pCreature, uint64 guid, uint32 param ); + void AddWeaponProficiency(uint32 newflag) { m_WeaponProficiency |= newflag; } + void AddArmorProficiency(uint32 newflag) { m_ArmorProficiency |= newflag; } + uint32 GetWeaponProficiency() const { return m_WeaponProficiency; } + uint32 GetArmorProficiency() const { return m_ArmorProficiency; } + bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; } + bool IsUseEquipedWeapon( bool mainhand ) const + { + // disarm applied only to mainhand weapon + return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) ); + } + void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false ); + bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot); + + float GetReputationPriceDiscount( Creature const* pCreature ) const; + Player* GetTrader() const { return pTrader; } + void ClearTrade(); + void TradeCancel(bool sendback); + uint16 GetItemPosByTradeSlot(uint32 slot) const { return tradeItems[slot]; } + + void UpdateEnchantTime(uint32 time); + void UpdateItemDuration(uint32 time, bool realtimeonly=false); + void AddEnchantmentDurations(Item *item); + void RemoveEnchantmentDurations(Item *item); + void RemoveAllEnchantments(EnchantmentSlot slot); + void AddEnchantmentDuration(Item *item,EnchantmentSlot slot,uint32 duration); + void ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool apply_dur = true, bool ignore_condition = false); + void ApplyEnchantment(Item *item,bool apply); + void SendEnchantmentDurations(); + void AddItemDurations(Item *item); + void RemoveItemDurations(Item *item); + void SendItemDurations(); + void LoadCorpse(); + void LoadPet(); + + uint32 m_stableSlots; + + /*********************************************************/ + /*** QUEST SYSTEM ***/ + /*********************************************************/ + + void PrepareQuestMenu( uint64 guid ); + void SendPreparedQuest( uint64 guid ); + bool IsActiveQuest( uint32 quest_id ) const; + Quest const *GetNextQuest( uint64 guid, Quest const *pQuest ); + bool CanSeeStartQuest( Quest const *pQuest ); + bool CanTakeQuest( Quest const *pQuest, bool msg ); + bool CanAddQuest( Quest const *pQuest, bool msg ); + bool CanCompleteQuest( uint32 quest_id ); + bool CanCompleteRepeatableQuest(Quest const *pQuest); + bool CanRewardQuest( Quest const *pQuest, bool msg ); + bool CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg ); + void AddQuest( Quest const *pQuest, Object *questGiver ); + void CompleteQuest( uint32 quest_id ); + void IncompleteQuest( uint32 quest_id ); + void RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce = true ); + void FailQuest( uint32 quest_id ); + void FailTimedQuest( uint32 quest_id ); + bool SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg ); + bool SatisfyQuestLevel( Quest const* qInfo, bool msg ); + bool SatisfyQuestLog( bool msg ); + bool SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg ); + bool SatisfyQuestRace( Quest const* qInfo, bool msg ); + bool SatisfyQuestReputation( Quest const* qInfo, bool msg ); + bool SatisfyQuestStatus( Quest const* qInfo, bool msg ); + bool SatisfyQuestTimed( Quest const* qInfo, bool msg ); + bool SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg ); + bool SatisfyQuestNextChain( Quest const* qInfo, bool msg ); + bool SatisfyQuestPrevChain( Quest const* qInfo, bool msg ); + bool SatisfyQuestDay( Quest const* qInfo, bool msg ); + bool GiveQuestSourceItem( Quest const *pQuest ); + bool TakeQuestSourceItem( uint32 quest_id, bool msg ); + bool GetQuestRewardStatus( uint32 quest_id ) const; + QuestStatus GetQuestStatus( uint32 quest_id ) const; + void SetQuestStatus( uint32 quest_id, QuestStatus status ); + + void SetDailyQuestStatus( uint32 quest_id ); + void ResetDailyQuestStatus(); + + uint16 FindQuestSlot( uint32 quest_id ) const; + uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_ID_OFFSET); } + uint32 GetQuestSlotState(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET); } + uint32 GetQuestSlotCounters(uint16 slot)const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET); } + uint8 GetQuestSlotCounter(uint16 slot,uint8 counter) const { return GetByteValue(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET,counter); } + uint32 GetQuestSlotTime(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_TIME_OFFSET); } + void SetQuestSlot(uint16 slot,uint32 quest_id, uint32 timer = 0) + { + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_ID_OFFSET,quest_id); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET,0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET,0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_TIME_OFFSET,timer); + } + void SetQuestSlotCounter(uint16 slot,uint8 counter,uint8 count) { SetByteValue(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET,counter,count); } + void SetQuestSlotState(uint16 slot,uint32 state) { SetFlag(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET,state); } + void RemoveQuestSlotState(uint16 slot,uint32 state) { RemoveFlag(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET,state); } + void SetQuestSlotTimer(uint16 slot,uint32 timer) { SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_TIME_OFFSET,timer); } + void SwapQuestSlot(uint16 slot1,uint16 slot2) + { + for (int i = 0; i < MAX_QUEST_OFFSET ; ++i ) + { + uint32 temp1 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot1 + i); + uint32 temp2 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot2 + i); + + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot1 + i, temp2); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot2 + i, temp1); + } + } + uint32 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry); + void AdjustQuestReqItemCount( Quest const* pQuest ); + void AreaExploredOrEventHappens( uint32 questId ); + void GroupEventHappens( uint32 questId, WorldObject const* pEventObject ); + void ItemAddedQuestCheck( uint32 entry, uint32 count ); + void ItemRemovedQuestCheck( uint32 entry, uint32 count ); + void KilledMonster( uint32 entry, uint64 guid ); + void CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id ); + void TalkedToCreature( uint32 entry, uint64 guid ); + void MoneyChanged( uint32 value ); + bool HasQuestForItem( uint32 itemid ) const; + bool HasQuestForGO(int32 GOId); + void UpdateForQuestsGO(); + bool CanShareQuest(uint32 quest_id) const; + + void SendQuestComplete( uint32 quest_id ); + void SendQuestReward( Quest const *pQuest, uint32 XP, Object* questGiver ); + void SendQuestFailed( uint32 quest_id ); + void SendQuestTimerFailed( uint32 quest_id ); + void SendCanTakeQuestResponse( uint32 msg ); + void SendPushToPartyResponse( Player *pPlayer, uint32 msg ); + void SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ); + void SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count ); + + uint64 GetDivider() { return m_divider; }; + void SetDivider( uint64 guid ) { m_divider = guid; }; + + uint32 GetInGameTime() { return m_ingametime; }; + + void SetInGameTime( uint32 time ) { m_ingametime = time; }; + + void AddTimedQuest( uint32 quest_id ) { m_timedquests.insert(quest_id); } + + /*********************************************************/ + /*** LOAD SYSTEM ***/ + /*********************************************************/ + + bool LoadFromDB(uint32 guid, SqlQueryHolder *holder); + bool MinimalLoadFromDB(QueryResult *result, uint32 guid); + static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid); + static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index); + static float GetFloatValueFromArray(Tokens const& data, uint16 index); + static uint32 GetUInt32ValueFromDB(uint16 index, uint64 guid); + static float GetFloatValueFromDB(uint16 index, uint64 guid); + static uint32 GetZoneIdFromDB(uint64 guid); + static bool LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid); + + /*********************************************************/ + /*** SAVE SYSTEM ***/ + /*********************************************************/ + + void SaveToDB(); + void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing + void SaveGoldToDB() { SetUInt32ValueInDB(PLAYER_FIELD_COINAGE,GetMoney(),GetGUID()); } + static bool SaveValuesArrayInDB(Tokens const& data,uint64 guid); + static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value); + static void SetFloatValueInArray(Tokens& data,uint16 index, float value); + static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid); + static void SetFloatValueInDB(uint16 index, float value, uint64 guid); + static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid); + + bool m_mailsLoaded; + bool m_mailsUpdated; + + void SetBindPoint(uint64 guid); + void SendTalentWipeConfirm(uint64 guid); + void RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker ); + void SendPetSkillWipeConfirm(); + void CalcRage( uint32 damage,bool attacker ); + void RegenerateAll(); + void Regenerate(Powers power); + void RegenerateHealth(); + void setRegenTimer(uint32 time) {m_regenTimer = time;} + void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;} + + uint32 GetMoney() { return GetUInt32Value (PLAYER_FIELD_COINAGE); } + void ModifyMoney( int32 d ) + { + if(d < 0) + SetMoney (GetMoney() > uint32(-d) ? GetMoney() + d : 0); + else + SetMoney (GetMoney() < MAX_MONEY_AMOUNT - d ? GetMoney() + d : MAX_MONEY_AMOUNT); + + // "At Gold Limit" + if(GetMoney() >= MAX_MONEY_AMOUNT) + SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD,NULL,NULL); + } + void SetMoney( uint32 value ) + { + SetUInt32Value (PLAYER_FIELD_COINAGE, value); + MoneyChanged( value ); + } + + uint32 GetTutorialInt(uint32 intId ) + { + ASSERT( (intId < 8) ); + return m_Tutorials[intId]; + } + + void SetTutorialInt(uint32 intId, uint32 value) + { + ASSERT( (intId < 8) ); + if(m_Tutorials[intId]!=value) + { + m_Tutorials[intId] = value; + m_TutorialsChanged = true; + } + } + + QuestStatusMap& getQuestStatusMap() { return mQuestStatus; }; + + const uint64& GetSelection( ) const { return m_curSelection; } + void SetSelection(const uint64 &guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); } + + uint8 GetComboPoints() { return m_comboPoints; } + uint64 GetComboTarget() { return m_comboTarget; } + + void AddComboPoints(Unit* target, int8 count); + void ClearComboPoints(); + void SendComboPoints(); + + void SendMailResult(uint32 mailId, uint32 mailAction, uint32 mailError, uint32 equipError = 0, uint32 item_guid = 0, uint32 item_count = 0); + void SendNewMail(); + void UpdateNextMailTimeAndUnreads(); + void AddNewMailDeliverTime(time_t deliver_time); + bool IsMailsLoaded() const { return m_mailsLoaded; } + + //void SetMail(Mail *m); + void RemoveMail(uint32 id); + + void AddMail(Mail* mail) { m_mail.push_front(mail);}// for call from WorldSession::SendMailTo + uint32 GetMailSize() { return m_mail.size();}; + Mail* GetMail(uint32 id); + + PlayerMails::iterator GetmailBegin() { return m_mail.begin();}; + PlayerMails::iterator GetmailEnd() { return m_mail.end();}; + + /*********************************************************/ + /*** MAILED ITEMS SYSTEM ***/ + /*********************************************************/ + + uint8 unReadMails; + time_t m_nextMailDelivereTime; + + typedef HM_NAMESPACE::hash_map ItemMap; + + ItemMap mMitems; //template defined in objectmgr.cpp + + Item* GetMItem(uint32 id) + { + ItemMap::const_iterator itr = mMitems.find(id); + if (itr != mMitems.end()) + return itr->second; + + return NULL; + } + + void AddMItem(Item* it) + { + ASSERT( it ); + //assert deleted, because items can be added before loading + mMitems[it->GetGUIDLow()] = it; + } + + bool RemoveMItem(uint32 id) + { + ItemMap::iterator i = mMitems.find(id); + if (i == mMitems.end()) + return false; + + mMitems.erase(i); + return true; + } + + void PetSpellInitialize(); + void CharmSpellInitialize(); + void PossessSpellInitialize(); + bool HasSpell(uint32 spell) const; + TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const; + bool IsSpellFitByClassAndRace( uint32 spell_id ) const; + + void SendProficiency(uint8 pr1, uint32 pr2); + void SendInitialSpells(); + bool addSpell(uint32 spell_id, bool active, bool learning = true, bool loading = false, uint16 slot_id=SPELL_WITHOUT_SLOT_ID, bool disabled = false); + void learnSpell(uint32 spell_id); + void removeSpell(uint32 spell_id, bool disabled = false); + void resetSpells(); + void learnDefaultSpells(bool loading = false); + void learnQuestRewardedSpells(); + void learnQuestRewardedSpells(Quest const* quest); + + uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); } + void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); } + bool resetTalents(bool no_cost = false); + uint32 resetTalentsCost() const; + void InitTalentForLevel(); + + uint32 GetFreePrimaryProffesionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); } + void SetFreePrimaryProffesions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2,profs); } + void InitPrimaryProffesions(); + + PlayerSpellMap const& GetSpellMap() const { return m_spells; } + PlayerSpellMap & GetSpellMap() { return m_spells; } + + void AddSpellMod(SpellModifier* mod, bool apply); + int32 GetTotalFlatMods(uint32 spellId, SpellModOp op); + int32 GetTotalPctMods(uint32 spellId, SpellModOp op); + bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL); + template T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL); + void RemoveSpellMods(Spell const* spell); + + bool HasSpellCooldown(uint32 spell_id) const + { + SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); + return itr != m_spellCooldowns.end() && itr->second.end > time(NULL); + } + uint32 GetSpellCooldownDelay(uint32 spell_id) const + { + SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); + time_t t = time(NULL); + return itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0; + } + void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); + void SendCooldownEvent(SpellEntry const *spellInfo); + void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ); + void RemoveSpellCooldown(uint32 spell_id) { m_spellCooldowns.erase(spell_id); } + void RemoveArenaSpellCooldowns(); + void RemoveAllSpellCooldown(); + void _LoadSpellCooldowns(QueryResult *result); + void _SaveSpellCooldowns(); + + void setResurrectRequestData(uint64 guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana) + { + m_resurrectGUID = guid; + m_resurrectMap = mapId; + m_resurrectX = X; + m_resurrectY = Y; + m_resurrectZ = Z; + m_resurrectHealth = health; + m_resurrectMana = mana; + }; + void clearResurrectRequestData() { setResurrectRequestData(0,0,0.0f,0.0f,0.0f,0,0); } + bool isRessurectRequestedBy(uint64 guid) const { return m_resurrectGUID == guid; } + bool isRessurectRequested() const { return m_resurrectGUID != 0; } + void ResurectUsingRequestData(); + + int getCinematic() + { + return m_cinematic; + } + void setCinematic(int cine) + { + m_cinematic = cine; + } + + void addActionButton(uint8 button, uint16 action, uint8 type, uint8 misc); + void removeActionButton(uint8 button); + void SendInitialActionButtons(); + + PvPInfo pvpInfo; + void UpdatePvP(bool state, bool ovrride=false); + void UpdateZone(uint32 newZone); + void UpdateArea(uint32 newArea); + + void UpdateZoneDependentAuras( uint32 zone_id ); // zones + void UpdateAreaDependentAuras( uint32 area_id ); // subzones + + void UpdateAfkReport(time_t currTime); + void UpdatePvPFlag(time_t currTime); + void UpdateContestedPvP(uint32 currTime); + void SetContestedPvPTimer(uint32 newTime) {m_contestedPvPTimer = newTime;} + void ResetContestedPvP() + { + clearUnitState(UNIT_STAT_ATTACK_PLAYER); + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP); + m_contestedPvPTimer = 0; + } + + /** todo: -maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler.. **/ + DuelInfo *duel; + void UpdateDuelFlag(time_t currTime); + void CheckDuelDistance(time_t currTime); + void DuelComplete(DuelCompleteType type); + + bool IsGroupVisibleFor(Player* p) const; + bool IsInSameGroupWith(Player const* p) const; + bool IsInSameRaidWith(Player const* p) const { return p==this || (GetGroup() != NULL && GetGroup() == p->GetGroup()); } + void UninviteFromGroup(); + static void RemoveFromGroup(Group* group, uint64 guid); + void RemoveFromGroup() { RemoveFromGroup(GetGroup(),GetGUID()); } + void SendUpdateToOutOfRangeGroupMembers(); + + void SetInGuild(uint32 GuildId) { SetUInt32Value(PLAYER_GUILDID, GuildId); Player::SetUInt32ValueInDB(PLAYER_GUILDID, GuildId, this->GetGUID()); } + void SetRank(uint32 rankId){ SetUInt32Value(PLAYER_GUILDRANK, rankId); Player::SetUInt32ValueInDB(PLAYER_GUILDRANK, rankId, this->GetGUID()); } + void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; } + uint32 GetGuildId() { return GetUInt32Value(PLAYER_GUILDID); } + static uint32 GetGuildIdFromDB(uint64 guid); + uint32 GetRank(){ return GetUInt32Value(PLAYER_GUILDRANK); } + static uint32 GetRankFromDB(uint64 guid); + int GetGuildIdInvited() { return m_GuildIdInvited; } + static void RemovePetitionsAndSigns(uint64 guid, uint32 type); + + // Arena Team + void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot) + { + SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId); + SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId, this->GetGUID()); + } + uint32 GetArenaTeamId(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6)); } + static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot); + void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; } + uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; } + + void SetDifficulty(uint32 dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; } + uint8 GetDifficulty() { return m_dungeonDifficulty; } + + bool UpdateSkill(uint32 skill_id, uint32 step); + bool UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step); + + bool UpdateCraftSkill(uint32 spellid); + bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1); + bool UpdateFishingSkill(); + + uint32 GetBaseDefenseSkillValue() const { return GetBaseSkillValue(SKILL_DEFENSE); } + uint32 GetBaseWeaponSkillValue(WeaponAttackType attType) const; + + uint32 GetSpellByProto(ItemPrototype *proto); + + float GetHealthBonusFromStamina(); + float GetManaBonusFromIntellect(); + + bool UpdateStats(Stats stat); + bool UpdateAllStats(); + void UpdateResistances(uint32 school); + void UpdateArmor(); + void UpdateMaxHealth(); + void UpdateMaxPower(Powers power); + void UpdateAttackPowerAndDamage(bool ranged = false); + void UpdateShieldBlockValue(); + void UpdateDamagePhysical(WeaponAttackType attType); + void UpdateSpellDamageAndHealingBonus(); + + void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage); + + void UpdateDefenseBonusesMod(); + void ApplyRatingMod(CombatRating cr, int32 value, bool apply); + float GetMeleeCritFromAgility(); + float GetDodgeFromAgility(); + float GetSpellCritFromIntellect(); + float OCTRegenHPPerSpirit(); + float OCTRegenMPPerSpirit(); + float GetRatingCoefficient(CombatRating cr) const; + float GetRatingBonusValue(CombatRating cr) const; + uint32 GetMeleeCritDamageReduction(uint32 damage) const; + uint32 GetRangedCritDamageReduction(uint32 damage) const; + uint32 GetSpellCritDamageReduction(uint32 damage) const; + uint32 GetDotDamageReduction(uint32 damage) const; + + float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const; + void UpdateBlockPercentage(); + void UpdateCritPercentage(WeaponAttackType attType); + void UpdateAllCritPercentages(); + void UpdateParryPercentage(); + void UpdateDodgePercentage(); + void UpdateAllSpellCritChances(); + void UpdateSpellCritChance(uint32 school); + void UpdateExpertise(WeaponAttackType attType); + void UpdateManaRegen(); + + const uint64& GetLootGUID() const { return m_lootGuid; } + void SetLootGUID(const uint64 &guid) { m_lootGuid = guid; } + + void RemovedInsignia(Player* looterPlr); + + WorldSession* GetSession() const { return m_session; } + void SetSession(WorldSession *s) { m_session = s; } + + void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const; + void DestroyForPlayer( Player *target ) const; + void SendDelayResponse(const uint32); + void SendLogXPGain(uint32 GivenXP,Unit* victim,uint32 RestXP); + + //Low Level Packets + void PlaySound(uint32 Sound, bool OnlySelf); + //notifiers + void SendAttackSwingCantAttack(); + void SendAttackSwingCancelAttack(); + void SendAttackSwingDeadTarget(); + void SendAttackSwingNotStanding(); + void SendAttackSwingNotInRange(); + void SendAttackSwingBadFacingAttack(); + void SendAutoRepeatCancel(); + void SendExplorationExperience(uint32 Area, uint32 Experience); + + void SendDungeonDifficulty(bool IsInGroup); + void ResetInstances(uint8 method); + void SendResetInstanceSuccess(uint32 MapId); + void SendResetInstanceFailed(uint32 reason, uint32 MapId); + void SendResetFailedNotify(uint32 mapid); + + bool SetPosition(float x, float y, float z, float orientation, bool teleport = false); + void UpdateUnderwaterState( Map * m, float x, float y, float z ); + + void SendMessageToSet(WorldPacket *data, bool self);// overwrite Object::SendMessageToSet + void SendMessageToSetInRange(WorldPacket *data, float fist, bool self); + // overwrite Object::SendMessageToSetInRange + void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only); + + static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars = true); + + Corpse *GetCorpse() const; + void SpawnCorpseBones(); + void CreateCorpse(); + void KillPlayer(); + uint32 GetResurrectionSpellId(); + void ResurrectPlayer(float restore_percent, bool updateToWorld = true, bool applySickness = false); + void BuildPlayerRepop(); + void RepopAtGraveyard(); + + void DurabilityLossAll(double percent, bool inventory); + void DurabilityLoss(Item* item, double percent); + void DurabilityPointsLossAll(int32 points, bool inventory); + void DurabilityPointsLoss(Item* item, int32 points); + void DurabilityPointLossForEquipSlot(EquipmentSlots slot); + uint32 DurabilityRepairAll(bool cost, float discountMod, bool guildBank); + uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank); + + void StopMirrorTimers() + { + StopMirrorTimer(FATIGUE_TIMER); + StopMirrorTimer(BREATH_TIMER); + StopMirrorTimer(FIRE_TIMER); + } + + void SetMovement(PlayerMovementType pType); + + void JoinedChannel(Channel *c); + void LeftChannel(Channel *c); + void CleanupChannels(); + void UpdateLocalChannels( uint32 newZone ); + void LeaveLFGChannel(); + + void UpdateDefense(); + void UpdateWeaponSkill (WeaponAttackType attType); + void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence); + + void SetSkill(uint32 id, uint16 currVal, uint16 maxVal); + uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + uint16 GetPureMaxSkillValue(uint32 skill) const; // max + uint16 GetSkillValue(uint32 skill) const; // skill value + perm. bonus + temp bonus + uint16 GetBaseSkillValue(uint32 skill) const; // skill value + perm. bonus + uint16 GetPureSkillValue(uint32 skill) const; // skill value + int16 GetSkillTempBonusValue(uint32 skill) const; + bool HasSkill(uint32 skill) const; + void learnSkillRewardedSpells( uint32 id ); + void learnSkillRewardedSpells(); + + void SetDontMove(bool dontMove); + bool GetDontMove() const { return m_dontMove; } + + void CheckExploreSystem(void); + + static uint32 TeamForRace(uint8 race); + uint32 GetTeam() const { return m_team; } + static uint32 getFactionForRace(uint8 race); + void setFactionForRace(uint8 race); + + bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const; + bool RewardPlayerAndGroupAtKill(Unit* pVictim); + + FactionStateList m_factions; + ForcedReactions m_forcedReactions; + uint32 GetDefaultReputationFlags(const FactionEntry *factionEntry) const; + int32 GetBaseReputation(const FactionEntry *factionEntry) const; + int32 GetReputation(uint32 faction_id) const; + int32 GetReputation(const FactionEntry *factionEntry) const; + ReputationRank GetReputationRank(uint32 faction) const; + ReputationRank GetReputationRank(const FactionEntry *factionEntry) const; + ReputationRank GetBaseReputationRank(const FactionEntry *factionEntry) const; + ReputationRank ReputationToRank(int32 standing) const; + const static int32 ReputationRank_Length[MAX_REPUTATION_RANK]; + const static int32 Reputation_Cap = 42999; + const static int32 Reputation_Bottom = -42000; + bool ModifyFactionReputation(uint32 FactionTemplateId, int32 DeltaReputation); + bool ModifyFactionReputation(FactionEntry const* factionEntry, int32 standing); + bool ModifyOneFactionReputation(FactionEntry const* factionEntry, int32 standing); + bool SetFactionReputation(uint32 FactionTemplateId, int32 standing); + bool SetFactionReputation(FactionEntry const* factionEntry, int32 standing); + bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing); + int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest); + void RewardReputation(Unit *pVictim, float rate); + void RewardReputation(Quest const *pQuest); + void SetInitialFactions(); + void UpdateReputation() const; + void SendFactionState(FactionState const* faction) const; + void SendInitialReputations(); + FactionState const* GetFactionState( FactionEntry const* factionEntry) const; + void SetFactionAtWar(FactionState* faction, bool atWar); + void SetFactionInactive(FactionState* faction, bool inactive); + void SetFactionVisible(FactionState* faction); + void SetFactionVisibleForFactionTemplateId(uint32 FactionTemplateId); + void SetFactionVisibleForFactionId(uint32 FactionId); + void UpdateMaxSkills(); + void UpdateSkillsToMaxSkillsForLevel(); // for .levelup + void ModifySkillBonus(uint32 skillid,int32 val, bool talent); + + /*********************************************************/ + /*** PVP SYSTEM ***/ + /*********************************************************/ + void UpdateArenaFields(); + void UpdateHonorFields(); + bool RewardHonor(Unit *pVictim, uint32 groupsize, float honor = -1); + uint32 GetHonorPoints() { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); } + uint32 GetArenaPoints() { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); } + void ModifyHonorPoints( int32 value ); + void ModifyArenaPoints( int32 value ); + uint32 GetMaxPersonalArenaRatingRequirement(); + + //End of PvP System + + void SetDrunkValue(uint16 newDrunkValue, uint32 itemid=0); + uint16 GetDrunkValue() const { return m_drunk; } + static DrunkenState GetDrunkenstateByValue(uint16 value); + + uint32 GetDeathTimer() const { return m_deathTimer; } + uint32 GetCorpseReclaimDelay(bool pvp) const; + void UpdateCorpseReclaimDelay(); + void SendCorpseReclaimDelay(bool load = false); + + uint32 GetShieldBlockValue() const; // overwrite Unit version (virtual) + bool CanParry() const { return m_canParry; } + void SetCanParry(bool value); + bool CanBlock() const { return m_canBlock; } + void SetCanBlock(bool value); + bool CanDualWield() const { return m_canDualWield; } + void SetCanDualWield(bool value) { m_canDualWield = value; } + + void SetRegularAttackTime(); + void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; } + void HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply, bool affectStats = true); + float GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const; + float GetTotalBaseModValue(BaseModGroup modGroup) const; + float GetTotalPercentageModValue(BaseModGroup modGroup) const { return m_auraBaseMod[modGroup][FLAT_MOD] + m_auraBaseMod[modGroup][PCT_MOD]; } + void _ApplyAllStatBonuses(); + void _RemoveAllStatBonuses(); + + void _ApplyWeaponDependentAuraMods(Item *item, WeaponAttackType attackType, bool apply); + void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply); + void _ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply); + + void _ApplyItemMods(Item *item,uint8 slot,bool apply); + void _RemoveAllItemMods(); + void _ApplyAllItemMods(); + void _ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply); + void _ApplyAmmoBonuses(); + bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot); + void ToggleMetaGemsActive(uint8 exceptslot, bool apply); + void CorrectMetaGemEnchants(uint8 slot, bool apply); + void InitDataForForm(bool reapplyMods = false); + + void ApplyItemEquipSpell(Item *item, bool apply, bool form_change = false); + void ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change = false); + void UpdateEquipSpellsAtFormChange(); + void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType); + + void SendInitWorldStates(); + void SendUpdateWorldState(uint32 Field, uint32 Value); + void SendDirectMessage(WorldPacket *data); + + void SendAuraDurationsForTarget(Unit* target); + + PlayerMenu* PlayerTalkClass; + std::vector ItemSetEff; + + void SendLoot(uint64 guid, LootType loot_type); + void SendLootRelease( uint64 guid ); + void SendNotifyLootItemRemoved(uint8 lootSlot); + void SendNotifyLootMoneyRemoved(); + + /*********************************************************/ + /*** BATTLEGROUND SYSTEM ***/ + /*********************************************************/ + + bool InBattleGround() const { return m_bgBattleGroundID != 0; } + uint32 GetBattleGroundId() const { return m_bgBattleGroundID; } + BattleGround* GetBattleGround() const; + bool InArena() const; + + static uint32 GetMinLevelForBattleGroundQueueId(uint32 queue_id); + static uint32 GetMaxLevelForBattleGroundQueueId(uint32 queue_id); + uint32 GetBattleGroundQueueIdFromLevel() const; + + uint32 GetBattleGroundQueueId(uint32 index) const { return m_bgBattleGroundQueueID[index].bgType; } + uint32 GetBattleGroundQueueIndex(uint32 bgType) const + { + for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + if (m_bgBattleGroundQueueID[i].bgType == bgType) + return i; + return PLAYER_MAX_BATTLEGROUND_QUEUES; + } + bool IsInvitedForBattleGroundType(uint32 bgType) const + { + for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + if (m_bgBattleGroundQueueID[i].bgType == bgType) + return m_bgBattleGroundQueueID[i].invited; + return PLAYER_MAX_BATTLEGROUND_QUEUES; + } + bool InBattleGroundQueueForBattleGroundType(uint32 bgType) const + { + return GetBattleGroundQueueIndex(bgType) < PLAYER_MAX_BATTLEGROUND_QUEUES; + } + + void SetBattleGroundId(uint32 val) { m_bgBattleGroundID = val; } + uint32 AddBattleGroundQueueId(uint32 val) + { + for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + { + if (m_bgBattleGroundQueueID[i].bgType == 0 || m_bgBattleGroundQueueID[i].bgType == val) + { + m_bgBattleGroundQueueID[i].bgType = val; + m_bgBattleGroundQueueID[i].invited = false; + return i; + } + } + return PLAYER_MAX_BATTLEGROUND_QUEUES; + } + void RemoveBattleGroundQueueId(uint32 val) + { + for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + { + if (m_bgBattleGroundQueueID[i].bgType == val) + { + m_bgBattleGroundQueueID[i].bgType = 0; + m_bgBattleGroundQueueID[i].invited = false; + return; + } + } + } + void SetInviteForBattleGroundType(uint32 bgType) + { + for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + if (m_bgBattleGroundQueueID[i].bgType == bgType) + m_bgBattleGroundQueueID[i].invited = true; + } + + uint32 GetBattleGroundEntryPointMap() const { return m_bgEntryPointMap; } + float GetBattleGroundEntryPointX() const { return m_bgEntryPointX; } + float GetBattleGroundEntryPointY() const { return m_bgEntryPointY; } + float GetBattleGroundEntryPointZ() const { return m_bgEntryPointZ; } + float GetBattleGroundEntryPointO() const { return m_bgEntryPointO; } + void SetBattleGroundEntryPoint(uint32 Map, float PosX, float PosY, float PosZ, float PosO ) + { + m_bgEntryPointMap = Map; + m_bgEntryPointX = PosX; + m_bgEntryPointY = PosY; + m_bgEntryPointZ = PosZ; + m_bgEntryPointO = PosO; + } + + void SetBGTeam(uint32 team) { m_bgTeam = team; } + uint32 GetBGTeam() const { return m_bgTeam ? m_bgTeam : GetTeam(); } + + void LeaveBattleground(bool teleportToEntryPoint = true); + bool CanJoinToBattleground() const; + bool CanReportAfkDueToLimit(); + void ReportedAfkBy(Player* reporter); + void ClearAfkReports() { m_bgAfkReporter.clear(); } + + bool GetBGAccessByLevel(uint32 bgTypeId) const; + bool isAllowUseBattleGroundObject(); + + /*********************************************************/ + /*** REST SYSTEM ***/ + /*********************************************************/ + + bool isRested() const { return GetRestTime() >= 10000; } + uint32 GetXPRestBonus(uint32 xp); + uint32 GetRestTime() const { return m_restTime;}; + void SetRestTime(uint32 v) { m_restTime = v;}; + + /*********************************************************/ + /*** ENVIROMENTAL SYSTEM ***/ + /*********************************************************/ + + void EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 damage); + + /*********************************************************/ + /*** FLOOD FILTER SYSTEM ***/ + /*********************************************************/ + + void UpdateSpeakTime(); + bool CanSpeak() const; + void ChangeSpeakTime(int utime); + + /*********************************************************/ + /*** VARIOUS SYSTEMS ***/ + /*********************************************************/ + MovementInfo m_movementInfo; + bool isMoving() const { return HasUnitMovementFlag(movementFlagsMask); } + bool isMovingOrTurning() const { return HasUnitMovementFlag(movementOrTurningFlagsMask); } + + bool CanFly() const { return HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); } + bool IsFlying() const { return HasUnitMovementFlag(MOVEMENTFLAG_FLYING); } + + void HandleDrowning(); + + void SetClientControl(Unit* target, uint8 allowMove); + + // Transports + Transport * GetTransport() const { return m_transport; } + void SetTransport(Transport * t) { m_transport = t; } + + float GetTransOffsetX() const { return m_movementInfo.t_x; } + float GetTransOffsetY() const { return m_movementInfo.t_y; } + float GetTransOffsetZ() const { return m_movementInfo.t_z; } + float GetTransOffsetO() const { return m_movementInfo.t_o; } + uint32 GetTransTime() const { return m_movementInfo.t_time; } + + uint32 GetSaveTimer() const { return m_nextSave; } + void SetSaveTimer(uint32 timer) { m_nextSave = timer; } + + // Recall position + uint32 m_recallMap; + float m_recallX; + float m_recallY; + float m_recallZ; + float m_recallO; + void SaveRecallPosition(); + + // Homebind coordinates + uint32 m_homebindMapId; + uint16 m_homebindZoneId; + float m_homebindX; + float m_homebindY; + float m_homebindZ; + + // currently visible objects at player client + typedef std::set ClientGUIDs; + ClientGUIDs m_clientGUIDs; + + bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } + + bool IsVisibleInGridForPlayer(Player* pl) const; + bool IsVisibleGloballyFor(Player* pl) const; + + void UpdateVisibilityOf(WorldObject* target); + + template + void UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set& visibleNow); + + // Stealth detection system + uint32 m_DetectInvTimer; + void HandleStealthedUnitsDetection(); + + uint8 m_forced_speed_changes[MAX_MOVE_TYPE]; + + bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; } + void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; } + + LookingForGroup m_lookingForGroup; + + // Temporarily removed pet cache + uint32 GetTemporaryUnsummonedPetNumber() const { return m_temporaryUnsummonedPetNumber; } + void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; } + uint32 GetOldPetSpell() const { return m_oldpetspell; } + void SetOldPetSpell(uint32 petspell) { m_oldpetspell = petspell; } + + /*********************************************************/ + /*** INSTANCE SYSTEM ***/ + /*********************************************************/ + + typedef HM_NAMESPACE::hash_map< uint32 /*mapId*/, InstancePlayerBind > BoundInstancesMap; + + void UpdateHomebindTime(uint32 time); + + uint32 m_HomebindTimer; + bool m_InstanceValid; + // permanent binds and solo binds by difficulty + BoundInstancesMap m_boundInstances[TOTAL_DIFFICULTIES]; + InstancePlayerBind* GetBoundInstance(uint32 mapid, uint8 difficulty); + BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; } + void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false); + void UnbindInstance(BoundInstancesMap::iterator &itr, uint8 difficulty, bool unload = false); + InstancePlayerBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false); + void SendRaidInfo(); + void SendSavedInstances(); + static void ConvertInstancesToGroup(Player *player, Group *group = NULL, uint64 player_guid = 0); + + /*********************************************************/ + /*** GROUP SYSTEM ***/ + /*********************************************************/ + + Group * GetGroupInvite() { return m_groupInvite; } + void SetGroupInvite(Group *group) { m_groupInvite = group; } + Group * GetGroup() { return m_group.getTarget(); } + const Group * GetGroup() const { return (const Group*)m_group.getTarget(); } + GroupReference& GetGroupRef() { return m_group; } + void SetGroup(Group *group, int8 subgroup = -1); + uint8 GetSubGroup() const { return m_group.getSubGroup(); } + uint32 GetGroupUpdateFlag() { return m_groupUpdateMask; } + void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } + uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } + void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } + Player* GetNextRandomRaidMember(float radius); + + GridReference &GetGridRef() { return m_gridRef; } + bool isAllowedToLoot(Creature* creature); + + WorldLocation& GetTeleportDest() { return m_teleport_dest; } + + DeclinedName const* GetDeclinedNames() const { return m_declinedname; } + + protected: + + /*********************************************************/ + /*** BATTLEGROUND SYSTEM ***/ + /*********************************************************/ + + /* this variable is set to bg->m_InstanceID, when player is teleported to BG - (it is battleground's GUID)*/ + uint32 m_bgBattleGroundID; + /* + this is an array of BG queues (BgTypeIDs) in which is player + */ + struct BgBattleGroundQueueID_Rec + { + uint32 bgType; + bool invited; + }; + BgBattleGroundQueueID_Rec m_bgBattleGroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES]; + uint32 m_bgEntryPointMap; + float m_bgEntryPointX; + float m_bgEntryPointY; + float m_bgEntryPointZ; + float m_bgEntryPointO; + + std::set m_bgAfkReporter; + uint8 m_bgAfkReportedCount; + time_t m_bgAfkReportedTimer; + uint32 m_contestedPvPTimer; + + uint32 m_bgTeam; // what side the player will be added to + + /*********************************************************/ + /*** QUEST SYSTEM ***/ + /*********************************************************/ + + std::set m_timedquests; + + uint64 m_divider; + uint32 m_ingametime; + + /*********************************************************/ + /*** LOAD SYSTEM ***/ + /*********************************************************/ + + void _LoadActions(QueryResult *result); + void _LoadAuras(QueryResult *result, uint32 timediff); + void _LoadBoundInstances(QueryResult *result); + void _LoadInventory(QueryResult *result, uint32 timediff); + void _LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery); + void _LoadMail(); + void _LoadMailedItems(Mail *mail); + void _LoadQuestStatus(QueryResult *result); + void _LoadDailyQuestStatus(QueryResult *result); + void _LoadGroup(QueryResult *result); + void _LoadReputation(QueryResult *result); + void _LoadSpells(QueryResult *result); + void _LoadTutorials(QueryResult *result); + void _LoadFriendList(QueryResult *result); + bool _LoadHomeBind(QueryResult *result); + void _LoadDeclinedNames(QueryResult *result); + + /*********************************************************/ + /*** SAVE SYSTEM ***/ + /*********************************************************/ + + void _SaveActions(); + void _SaveAuras(); + void _SaveInventory(); + void _SaveMail(); + void _SaveQuestStatus(); + void _SaveDailyQuestStatus(); + void _SaveReputation(); + void _SaveSpells(); + void _SaveTutorials(); + + void _SetCreateBits(UpdateMask *updateMask, Player *target) const; + void _SetUpdateBits(UpdateMask *updateMask, Player *target) const; + + /*********************************************************/ + /*** ENVIRONMENTAL SYSTEM ***/ + /*********************************************************/ + void HandleLava(); + void HandleSobering(); + void StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue); + void ModifyMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, uint32 Regen); + void StopMirrorTimer(MirrorTimerType Type); + uint8 m_isunderwater; + bool m_isInWater; + + /*********************************************************/ + /*** HONOR SYSTEM ***/ + /*********************************************************/ + time_t m_lastHonorUpdateTime; + + void outDebugValues() const; + bool _removeSpell(uint16 spell_id); + uint64 m_lootGuid; + + uint32 m_race; + uint32 m_class; + uint32 m_team; + uint32 m_nextSave; + time_t m_speakTime; + uint32 m_speakCount; + uint32 m_dungeonDifficulty; + + uint32 m_atLoginFlags; + + Item* m_items[PLAYER_SLOTS_COUNT]; + uint32 m_currentBuybackSlot; + + std::vector m_itemUpdateQueue; + bool m_itemUpdateQueueBlocked; + + uint32 m_ExtraFlags; + uint64 m_curSelection; + + uint64 m_comboTarget; + int8 m_comboPoints; + + QuestStatusMap mQuestStatus; + + uint32 m_GuildIdInvited; + uint32 m_ArenaTeamIdInvited; + + PlayerMails m_mail; + PlayerSpellMap m_spells; + SpellCooldowns m_spellCooldowns; + + ActionButtonList m_actionButtons; + + float m_auraBaseMod[BASEMOD_END][MOD_END]; + + SpellModList m_spellMods[MAX_SPELLMOD]; + int32 m_SpellModRemoveCount; + EnchantDurationList m_enchantDuration; + ItemDurationList m_itemDuration; + + uint64 m_resurrectGUID; + uint32 m_resurrectMap; + float m_resurrectX, m_resurrectY, m_resurrectZ; + uint32 m_resurrectHealth, m_resurrectMana; + + WorldSession *m_session; + + typedef std::list JoinedChannelsList; + JoinedChannelsList m_channels; + + bool m_dontMove; + + int m_cinematic; + + Player *pTrader; + bool acceptTrade; + uint16 tradeItems[TRADE_SLOT_COUNT]; + uint32 tradeGold; + + time_t m_nextThinkTime; + + uint32 m_Tutorials[8]; + bool m_TutorialsChanged; + + bool m_DailyQuestChanged; + time_t m_lastDailyQuestTime; + + uint32 m_regenTimer; + uint32 m_breathTimer; + uint32 m_drunkTimer; + uint16 m_drunk; + uint32 m_weaponChangeTimer; + + uint32 m_zoneUpdateId; + uint32 m_zoneUpdateTimer; + uint32 m_areaUpdateId; + + uint32 m_deathTimer; + time_t m_deathExpireTime; + + uint32 m_restTime; + + uint32 m_WeaponProficiency; + uint32 m_ArmorProficiency; + bool m_canParry; + bool m_canBlock; + bool m_canDualWield; + uint8 m_swingErrorMsg; + float m_ammoDPS; + ////////////////////Rest System///////////////////// + int time_inn_enter; + uint32 inn_pos_mapid; + float inn_pos_x; + float inn_pos_y; + float inn_pos_z; + float m_rest_bonus; + RestType rest_type; + ////////////////////Rest System///////////////////// + + // Transports + Transport * m_transport; + + uint32 m_resetTalentsCost; + time_t m_resetTalentsTime; + uint32 m_usedTalentCount; + + // Social + PlayerSocial *m_social; + + // Groups + GroupReference m_group; + Group *m_groupInvite; + uint32 m_groupUpdateMask; + uint64 m_auraUpdateMask; + + // Temporarily removed pet cache + uint32 m_temporaryUnsummonedPetNumber; + uint32 m_oldpetspell; + + uint64 m_miniPet; + GuardianPetList m_guardianPets; + + // Player summoning + time_t m_summon_expire; + uint32 m_summon_mapid; + float m_summon_x; + float m_summon_y; + float m_summon_z; + + // Far Teleport + WorldLocation m_teleport_dest; + + DeclinedName *m_declinedname; + private: + // internal common parts for CanStore/StoreItem functions + uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const; + uint8 _CanStoreItem_InBag( uint8 bag, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, bool non_specialized, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot ) const; + uint8 _CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot ) const; + Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update ); + + GridReference m_gridRef; +}; + +void AddItemsSetItem(Player*player,Item *item); +void RemoveItemsSetItem(Player*player,ItemPrototype const *proto); + +// "the bodies of template functions must be made available in a header file" +template T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 totalpct = 0; + int32 totalflat = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod,spell)) + continue; + if (mod->type == SPELLMOD_FLAT) + totalflat += mod->value; + else if (mod->type == SPELLMOD_PCT) + { + // skip percent mods for null basevalue (most important for spell mods with charges ) + if(basevalue == T(0)) + continue; + + // special case (skip >10sec spell casts for instant cast setting) + if( mod->op==SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100) + continue; + + totalpct += mod->value; + } + + if (mod->charges > 0 ) + { + --mod->charges; + if (mod->charges == 0) + { + mod->charges = -1; + mod->lastAffected = spell; + if(!mod->lastAffected) + mod->lastAffected = FindCurrentSpellBySpellId(spellId); + ++m_SpellModRemoveCount; + } + } + } + + float diff = (float)basevalue*(float)totalpct/100.0f + (float)totalflat; + basevalue = T((float)basevalue + diff); + return T(diff); +} +#endif diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp new file mode 100644 index 000000000..bd5149b2c --- /dev/null +++ b/src/game/PlayerDump.cpp @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "PlayerDump.h" +#include "Database/DatabaseEnv.h" +#include "Database/SQLStorage.h" +#include "UpdateFields.h" +#include "ObjectMgr.h" + +// Character Dump tables +#define DUMP_TABLE_COUNT 20 + +struct DumpTable +{ + char const* name; + DumpTableType type; +}; + +static DumpTable dumpTables[DUMP_TABLE_COUNT] = +{ + { "characters", DTT_CHARACTER }, + { "character_queststatus", DTT_CHAR_TABLE }, + { "character_reputation", DTT_CHAR_TABLE }, + { "character_spell", DTT_CHAR_TABLE }, + { "character_spell_cooldown", DTT_CHAR_TABLE }, + { "character_action", DTT_CHAR_TABLE }, + { "character_aura", DTT_CHAR_TABLE }, + { "character_homebind", DTT_CHAR_TABLE }, + { "character_ticket", DTT_CHAR_TABLE }, + { "character_inventory", DTT_INVENTORY }, + { "mail", DTT_MAIL }, + { "mail_items", DTT_MAIL_ITEM }, + { "item_instance", DTT_ITEM }, + { "character_gifts", DTT_ITEM_GIFT }, + { "item_text", DTT_ITEM_TEXT }, + { "character_pet", DTT_PET }, + { "pet_aura", DTT_PET_TABLE }, + { "pet_spell", DTT_PET_TABLE }, + { "pet_spell_cooldown", DTT_PET_TABLE }, +}; + +// Low level functions +static bool findtoknth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e) +{ + int i; s = e = 0; + std::string::size_type size = str.size(); + for(i = 1; s < size && i < n; s++) if(str[s] == ' ') ++i; + if (i < n) + return false; + + e = str.find(' ', s); + + return e != std::string::npos; +} + +std::string gettoknth(std::string &str, int n) +{ + std::string::size_type s = 0, e = 0; + if(!findtoknth(str, n, s, e)) + return ""; + + return str.substr(s, e-s); +} + +bool findnth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e) +{ + s = str.find("VALUES ('")+9; + if (s == std::string::npos) return false; + + do + { + e = str.find("'",s); + if (e == std::string::npos) return false; + } while(str[e-1] == '\\'); + + for(int i = 1; i < n; i++) + { + do + { + s = e+4; + e = str.find("'",s); + if (e == std::string::npos) return false; + } while (str[e-1] == '\\'); + } + return true; +} + +std::string gettablename(std::string &str) +{ + std::string::size_type s = 13; + std::string::size_type e = str.find(_TABLE_SIM_, s); + if (e == std::string::npos) + return ""; + + return str.substr(s, e-s); +} + +bool changenth(std::string &str, int n, const char *with, bool insert = false, bool nonzero = false) +{ + std::string::size_type s, e; + if(!findnth(str,n,s,e)) + return false; + + if(nonzero && str.substr(s,e-s) == "0") + return true; // not an error + if(!insert) + str.replace(s,e-s, with); + else + str.insert(s, with); + + return true; +} + +std::string getnth(std::string &str, int n) +{ + std::string::size_type s, e; + if(!findnth(str,n,s,e)) + return ""; + + return str.substr(s, e-s); +} + +bool changetoknth(std::string &str, int n, const char *with, bool insert = false, bool nonzero = false) +{ + std::string::size_type s = 0, e = 0; + if(!findtoknth(str, n, s, e)) + return false; + if(nonzero && str.substr(s,e-s) == "0") + return true; // not an error + if(!insert) + str.replace(s, e-s, with); + else + str.insert(s, with); + + return true; +} + +uint32 registerNewGuid(uint32 oldGuid, std::map &guidMap, uint32 hiGuid) +{ + std::map::iterator itr = guidMap.find(oldGuid); + if(itr != guidMap.end()) + return itr->second; + + uint32 newguid = hiGuid + guidMap.size(); + guidMap[oldGuid] = newguid; + return newguid; +} + +bool changeGuid(std::string &str, int n, std::map &guidMap, uint32 hiGuid, bool nonzero = false) +{ + char chritem[20]; + uint32 oldGuid = atoi(getnth(str, n).c_str()); + if (nonzero && oldGuid == 0) + return true; // not an error + + uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid); + snprintf(chritem, 20, "%d", newGuid); + + return changenth(str, n, chritem, false, nonzero); +} + +bool changetokGuid(std::string &str, int n, std::map &guidMap, uint32 hiGuid, bool nonzero = false) +{ + char chritem[20]; + uint32 oldGuid = atoi(gettoknth(str, n).c_str()); + if (nonzero && oldGuid == 0) + return true; // not an error + + uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid); + snprintf(chritem, 20, "%d", newGuid); + + return changetoknth(str, n, chritem, false, nonzero); +} + +std::string CreateDumpString(char const* tableName, QueryResult *result) +{ + if(!tableName || !result) return ""; + std::ostringstream ss; + ss << "INSERT INTO "<< _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES ("; + Field *fields = result->Fetch(); + for(uint32 i = 0; i < result->GetFieldCount(); i++) + { + if (i == 0) ss << "'"; + else ss << ", '"; + + std::string s = fields[i].GetCppString(); + CharacterDatabase.escape_string(s); + ss << s; + + ss << "'"; + } + ss << ");"; + return ss.str(); +} + +std::string PlayerDumpWriter::GenerateWhereStr(char const* field, uint32 guid) +{ + std::ostringstream wherestr; + wherestr << field << " = '" << guid << "'"; + return wherestr.str(); +} + +std::string PlayerDumpWriter::GenerateWhereStr(char const* field, GUIDs const& guids, GUIDs::const_iterator& itr) +{ + std::ostringstream wherestr; + wherestr << field << " IN ('"; + for(; itr != guids.end(); ++itr) + { + wherestr << *itr; + + if(wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query + { + ++itr; + break; + } + + GUIDs::const_iterator itr2 = itr; + if(++itr2 != guids.end()) + wherestr << "','"; + } + wherestr << "')"; + return wherestr.str(); +} + +void StoreGUID(QueryResult *result,uint32 field,std::set& guids) +{ + Field* fields = result->Fetch(); + uint32 guid = fields[field].GetUInt32(); + if(guid) + guids.insert(guid); +} + +void StoreGUID(QueryResult *result,uint32 data,uint32 field, std::set& guids) +{ + Field* fields = result->Fetch(); + std::string dataStr = fields[data].GetCppString(); + uint32 guid = atoi(gettoknth(dataStr, field).c_str()); + if(guid) + guids.insert(guid); +} + +// Writing - High-level functions +bool PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type) +{ + if (!tableFrom || !tableTo) + return false; + + GUIDs const* guids = NULL; + char const* fieldname = NULL; + + switch ( type ) + { + case DTT_ITEM: fieldname = "guid"; guids = &items; break; + case DTT_ITEM_GIFT: fieldname = "item_guid"; guids = &items; break; + case DTT_PET: fieldname = "owner"; break; + case DTT_PET_TABLE: fieldname = "guid"; guids = &pets; break; + case DTT_MAIL: fieldname = "receiver"; break; + case DTT_MAIL_ITEM: fieldname = "mail_id"; guids = &mails; break; + case DTT_ITEM_TEXT: fieldname = "id"; guids = &texts; break; + default: fieldname = "guid"; break; + } + + // for guid set stop if set is empty + if(guids && guids->empty()) + return true; // nothing to do + + // setup for guids case start position + GUIDs::const_iterator guids_itr; + if(guids) + guids_itr = guids->begin(); + + do + { + std::string wherestr; + + if(guids) // set case, get next guids string + wherestr = GenerateWhereStr(fieldname,*guids,guids_itr); + else // not set case, get single guid string + wherestr = GenerateWhereStr(fieldname,guid); + + QueryResult *result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str()); + if(!result) + return false; + + do + { + // collect guids + switch ( type ) + { + case DTT_INVENTORY: + StoreGUID(result,3,items); break; // item guid collection + case DTT_ITEM: + StoreGUID(result,0,ITEM_FIELD_ITEM_TEXT_ID,texts); break; + // item text id collection + case DTT_PET: + StoreGUID(result,0,pets); break; // pet guid collection + case DTT_MAIL: + StoreGUID(result,0,mails); // mail id collection + StoreGUID(result,6,texts); break; // item text id collection + case DTT_MAIL_ITEM: + StoreGUID(result,1,items); break; // item guid collection + default: break; + } + + dump += CreateDumpString(tableTo, result); + dump += "\n"; + } + while (result->NextRow()); + + delete result; + } + while(guids && guids_itr != guids->end()); // not set case iterate single time, set case iterate for all guids + + return true; +} + +std::string PlayerDumpWriter::GetDump(uint32 guid) +{ + std::string dump; + for(int i = 0; i < DUMP_TABLE_COUNT; i++) + DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type); + + // TODO: Add instance/group/gifts.. + // TODO: Add a dump level option to skip some non-important tables + + return dump; +} + +bool PlayerDumpWriter::WriteDump(std::string file, uint32 guid) +{ + FILE *fout = fopen(file.c_str(), "w"); + if (!fout) { sLog.outError("Failed to open file!\r\n"); return false; } + + std::string dump = GetDump(guid); + + fprintf(fout,"%s\n",dump.c_str()); + fclose(fout); + return true; +} + +// Reading - High-level functions +#define ROLLBACK {CharacterDatabase.RollbackTransaction(); fclose(fin); return false;} + +bool PlayerDumpReader::LoadDump(std::string file, uint32 account, std::string name, uint32 guid) +{ + // check character count + { + QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", account); + uint8 charcount = 0; + if ( result ) + { + Field *fields=result->Fetch(); + charcount = fields[0].GetUInt8(); + delete result; + + if (charcount >= 10) + { + return false; + } + } + } + FILE *fin = fopen(file.c_str(), "r"); + if(!fin) return false; + + QueryResult * result = NULL; + char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20]; + + // make sure the same guid doesn't already exist and is safe to use + bool incHighest = true; + if(guid != 0 && guid < objmgr.m_hiCharGuid) + { + result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid); + if (result) + { + guid = objmgr.m_hiCharGuid; // use first free if exists + delete result; + } + else incHighest = false; + } + else guid = objmgr.m_hiCharGuid; + + // normalize the name if specified and check if it exists + if(!normalizePlayerName(name)) + name = ""; + + if(ObjectMgr::IsValidName(name,true)) + { + CharacterDatabase.escape_string(name); // for safe, we use name only for sql quearies anyway + result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE name = '%s'", name.c_str()); + if (result) + { + name = ""; // use the one from the dump + delete result; + } + } + else name = ""; + + // name encoded or empty + + snprintf(newguid, 20, "%d", guid); + snprintf(chraccount, 20, "%d", account); + snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber()); + snprintf(lastpetid, 20, "%s", ""); + + std::map items; + std::map mails; + char buf[32000] = ""; + + typedef std::map PetIds; // old->new petid relation + typedef PetIds::value_type PetIdsPair; + PetIds petids; + + CharacterDatabase.BeginTransaction(); + while(!feof(fin)) + { + if(!fgets(buf, 32000, fin)) + { + if(feof(fin)) break; + sLog.outError("LoadPlayerDump: File read error!"); + ROLLBACK; + } + + std::string line; line.assign(buf); + + // skip empty strings + if(line.find_first_not_of(" \t\n\r\7")==std::string::npos) + continue; + + // determine table name and load type + std::string tn = gettablename(line); + if(tn.empty()) + { + sLog.outError("LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str()); + ROLLBACK; + } + + DumpTableType type; + uint8 i; + for(i = 0; i < DUMP_TABLE_COUNT; i++) + { + if (tn == dumpTables[i].name) + { + type = dumpTables[i].type; + break; + } + } + + if (i == DUMP_TABLE_COUNT) + { + sLog.outError("LoadPlayerDump: Unknown table: '%s'!", tn.c_str()); + ROLLBACK; + } + + // change the data to server values + switch(type) + { + case DTT_CHAR_TABLE: + if(!changenth(line, 1, newguid)) ROLLBACK; + break; + + case DTT_CHARACTER: // character t. + { + if(!changenth(line, 1, newguid)) ROLLBACK; + + // guid, data field:guid, items + if(!changenth(line, 2, chraccount)) ROLLBACK; + std::string vals = getnth(line, 3); + if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid)) ROLLBACK; + for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++) + if(!changetokGuid(vals, field+1, items, objmgr.m_hiItemGuid, true)) ROLLBACK; + if(!changenth(line, 3, vals.c_str())) ROLLBACK; + if (name == "") + { + // check if the original name already exists + name = getnth(line, 4); + CharacterDatabase.escape_string(name); + + result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE name = '%s'", name.c_str()); + if (result) + { + delete result; + // rename on login: `at_login` field 30 in raw field list + if(!changenth(line, 30, "1")) ROLLBACK; + } + } + else if(!changenth(line, 4, name.c_str())) ROLLBACK; + + break; + } + case DTT_INVENTORY: // character_inventory t. + { + if(!changenth(line, 1, newguid)) ROLLBACK; + + // bag, item + if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid, true)) ROLLBACK; + if(!changeGuid(line, 4, items, objmgr.m_hiItemGuid)) ROLLBACK; + break; + } + case DTT_ITEM: // item_instance t. + { + // item, owner, data field:item, owner guid + if(!changeGuid(line, 1, items, objmgr.m_hiItemGuid)) ROLLBACK; + if(!changenth(line, 2, newguid)) ROLLBACK; + std::string vals = getnth(line,3); + if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, objmgr.m_hiItemGuid)) ROLLBACK; + if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) ROLLBACK; + if(!changenth(line, 3, vals.c_str())) ROLLBACK; + break; + } + case DTT_ITEM_GIFT: // character_gift + { + // guid,item_guid, + if(!changenth(line, 1, newguid)) ROLLBACK; + if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid)) ROLLBACK; + break; + } + case DTT_PET: // character_pet t + { + //store a map of old pet id to new inserted pet id for use by type 5 tables + snprintf(currpetid, 20, "%s", getnth(line, 1).c_str()); + if(strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid); + if(strcmp(lastpetid,currpetid)!=0) + { + snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber()); + snprintf(lastpetid, 20, "%s", currpetid); + } + + std::map :: const_iterator petids_iter = petids.find(atoi(currpetid)); + + if(petids_iter == petids.end()) + { + petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid))); + } + + // item, entry, owner, ... + if(!changenth(line, 1, newpetid)) ROLLBACK; + if(!changenth(line, 3, newguid)) ROLLBACK; + + break; + } + case DTT_PET_TABLE: // pet_aura, pet_spell, pet_spell_cooldown t + { + snprintf(currpetid, 20, "%s", getnth(line, 1).c_str()); + + // lookup currpetid and match to new inserted pet id + std::map :: const_iterator petids_iter = petids.find(atoi(currpetid)); + if(petids_iter == petids.end()) ROLLBACK; // couldn't find new inserted id + + snprintf(newpetid, 20, "%d", petids_iter->second); + + if(!changenth(line, 1, newpetid)) ROLLBACK; + + break; + } + case DTT_MAIL: // mail + { + // id,messageType,stationery,sender,receiver + if(!changeGuid(line, 1, mails, objmgr.m_mailid)) ROLLBACK; + if(!changenth(line, 5, newguid)) ROLLBACK; + break; + } + case DTT_MAIL_ITEM: // mail_items + { + // mail_id,item_guid,item_template,receiver + if(!changeGuid(line, 1, mails, objmgr.m_mailid)) ROLLBACK; + if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid)) ROLLBACK; + if(!changenth(line, 4, newguid)) ROLLBACK; + break; + } + default: + sLog.outError("Unknown dump table type: %u",type); + break; + } + + if(!CharacterDatabase.Execute(line.c_str())) ROLLBACK; + } + + CharacterDatabase.CommitTransaction(); + + objmgr.m_hiItemGuid += items.size(); + objmgr.m_mailid += mails.size(); + + if(incHighest) + ++objmgr.m_hiCharGuid; + + fclose(fin); + + return true; +} diff --git a/src/game/PlayerDump.h b/src/game/PlayerDump.h new file mode 100644 index 000000000..0df90b80d --- /dev/null +++ b/src/game/PlayerDump.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PLAYER_DUMP_H +#define _PLAYER_DUMP_H +/* +#include "Log.h" +#include "Object.h" +#include "Bag.h" +#include "Creature.h" +#include "Player.h" +#include "DynamicObject.h" +#include "GameObject.h" +#include "Corpse.h" +#include "QuestDef.h" +#include "Path.h" +#include "ItemPrototype.h" +#include "NPCHandler.h" +#include "Database/DatabaseEnv.h" +#include "AuctionHouseObject.h" +#include "Mail.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "ObjectDefines.h" +#include "Policies/Singleton.h" +#include "Database/SQLStorage.h" +*/ +#include +#include +#include + +enum DumpTableType +{ + DTT_CHARACTER, // // characters + + DTT_CHAR_TABLE, // // character_action, character_aura, character_homebind, + // character_queststatus, character_reputation, + // character_spell, character_spell_cooldown, character_ticket, + // character_tutorial + + DTT_INVENTORY, // -> item guids collection // character_inventory + + DTT_MAIL, // -> mail ids collection // mail + // -> item_text + + DTT_MAIL_ITEM, // <- mail ids // mail_items + // -> item guids collection + + DTT_ITEM, // <- item guids // item_instance + // -> item_text + + DTT_ITEM_GIFT, // <- item guids // character_gifts + + DTT_PET, // -> pet guids collection // character_pet + DTT_PET_TABLE, // <- pet guids // pet_aura, pet_spell, pet_spell_cooldown + DTT_ITEM_TEXT, // <- item_text // item_text +}; + +class PlayerDump +{ + protected: + PlayerDump() {} +}; + +class PlayerDumpWriter : public PlayerDump +{ + public: + PlayerDumpWriter() {} + + std::string GetDump(uint32 guid); + bool WriteDump(std::string file, uint32 guid); + private: + typedef std::set GUIDs; + + bool DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type); + std::string GenerateWhereStr(char const* field, GUIDs const& guids, GUIDs::const_iterator& itr); + std::string GenerateWhereStr(char const* field, uint32 guid); + + GUIDs pets; + GUIDs mails; + GUIDs items; + GUIDs texts; +}; + +class PlayerDumpReader : public PlayerDump +{ + public: + PlayerDumpReader() {} + + bool LoadDump(std::string file, uint32 account, std::string name, uint32 guid); +}; + +#endif diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp new file mode 100644 index 000000000..d70d2e69c --- /dev/null +++ b/src/game/PointMovementGenerator.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PointMovementGenerator.h" +#include "Errors.h" +#include "Creature.h" +#include "CreatureAI.h" +#include "MapManager.h" +#include "DestinationHolderImp.h" + +//----- Point Movement Generator +template +void PointMovementGenerator::Initialize(T &unit) +{ + unit.StopMoving(); + Traveller traveller(unit); + i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z); + + if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly()) + unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); +} + +template +bool PointMovementGenerator::Update(T &unit, const uint32 &diff) +{ + if(!&unit) + return false; + + if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED)) + return true; + + Traveller traveller(unit); + + i_destinationHolder.UpdateTraveller(traveller, diff, false); + + if(i_destinationHolder.HasArrived()) + { + unit.StopMoving(); + MovementInform(unit); + return false; + } + + return true; +} + +template +void PointMovementGenerator::MovementInform(T &unit) +{ +} + +template <> void PointMovementGenerator::MovementInform(Creature &unit) +{ + unit.AI()->MovementInform(POINT_MOTION_TYPE, id); +} + +template void PointMovementGenerator::Initialize(Player&); +template bool PointMovementGenerator::Update(Player &, const uint32 &diff); +template void PointMovementGenerator::MovementInform(Player&); + +template void PointMovementGenerator::Initialize(Creature&); +template bool PointMovementGenerator::Update(Creature&, const uint32 &diff); diff --git a/src/game/PointMovementGenerator.h b/src/game/PointMovementGenerator.h new file mode 100644 index 000000000..27c6005ad --- /dev/null +++ b/src/game/PointMovementGenerator.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_POINTMOVEMENTGENERATOR_H +#define MANGOS_POINTMOVEMENTGENERATOR_H + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "Traveller.h" +#include "FollowerReference.h" + +template +class MANGOS_DLL_SPEC PointMovementGenerator +: public MovementGeneratorMedium< T, PointMovementGenerator > +{ + public: + PointMovementGenerator(uint32 _id, float _x, float _y, float _z) : id(_id), + i_x(_x), i_y(_y), i_z(_z), i_nextMoveTime(0) {} + + void Initialize(T &); + void Finalize(T &){} + void Reset(T &unit){unit.StopMoving();} + bool Update(T &, const uint32 &diff); + + void MovementInform(T &); + + MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; } + + bool GetDestination(float& x, float& y, float& z) const { x=i_x; y=i_y; z=i_z; return true; } + private: + TimeTracker i_nextMoveTime; + float i_x,i_y,i_z; + uint32 id; + DestinationHolder< Traveller > i_destinationHolder; +}; +#endif diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp new file mode 100644 index 000000000..9dc17bcd7 --- /dev/null +++ b/src/game/QueryHandler.cpp @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Language.h" +#include "Database/DatabaseEnv.h" +#include "Database/DatabaseImpl.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "UpdateMask.h" +#include "NPCHandler.h" +#include "ObjectAccessor.h" +#include "Pet.h" + +void WorldSession::SendNameQueryOpcode(Player *p) +{ + if(!p) + return; + + // guess size + WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+4+4+4+10) ); + data << p->GetGUID(); + data << p->GetName(); + data << uint8(0); // realm name for cross realm BG usage + data << uint32(p->getRace()); + data << uint32(p->getGender()); + data << uint32(p->getClass()); + if(DeclinedName const* names = p->GetDeclinedNames()) + { + data << uint8(1); // is declined + for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + data << names->name[i]; + } + else + data << uint8(0); // is not declined + + SendPacket(&data); +} + +void WorldSession::SendNameQueryOpcodeFromDB(uint64 guid) +{ + CharacterDatabase.AsyncPQuery(&WorldSession::SendNameQueryOpcodeFromDBCallBack, GetAccountId(), + !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ? + // ------- Query Without Declined Names -------- + // 0 1 2 + "SELECT guid, name, SUBSTRING(data, LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))+2, LENGTH(SUBSTRING_INDEX(data, ' ', '%u')) - LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))-1) " + "FROM characters WHERE guid = '%u'" + : + // --------- Query With Declined Names --------- + // 0 1 2 + "SELECT characters.guid, name, SUBSTRING(data, LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))+2, LENGTH(SUBSTRING_INDEX(data, ' ', '%u')) - LENGTH(SUBSTRING_INDEX(data, ' ', '%u'))-1), " + // 3 4 5 6 7 + "genitive, dative, accusative, instrumental, prepositional " + "FROM characters LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid WHERE characters.guid = '%u'", + UNIT_FIELD_BYTES_0, UNIT_FIELD_BYTES_0+1, UNIT_FIELD_BYTES_0, GUID_LOPART(guid)); +} + +void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32 accountId) +{ + if(!result) + return; + + WorldSession * session = sWorld.FindSession(accountId); + if(!session) + { + delete result; + return; + } + + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + std::string name = fields[1].GetCppString(); + uint32 field = 0; + if(name == "") + name = session->GetMangosString(LANG_NON_EXIST_CHARACTER); + else + field = fields[2].GetUInt32(); + + // guess size + WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+4+4+4+10) ); + data << MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER); + data << name; + data << (uint8)0; + data << (uint32)(field & 0xFF); + data << (uint32)((field >> 16) & 0xFF); + data << (uint32)((field >> 8) & 0xFF); + + // if the first declined name field (3) is empty, the rest must be too + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && fields[3].GetCppString() != "") + { + data << (uint8)1; // is declined + for(int i = 3; i < MAX_DECLINED_NAME_CASES+3; ++i) + data << fields[i].GetCppString(); + } + else + data << (uint8)0; // is declined + + session->SendPacket( &data ); + delete result; +} + +void WorldSession::HandleNameQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + + recv_data >> guid; + + Player *pChar = objmgr.GetPlayer(guid); + + if (pChar) + SendNameQueryOpcode(pChar); + else + SendNameQueryOpcodeFromDB(guid); +} + +void WorldSession::HandleQueryTimeOpcode( WorldPacket & /*recv_data*/ ) +{ + WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 ); + data << (uint32)time(NULL); + data << (uint32)0; + SendPacket( &data ); +} + +/// Only _static_ data send in this packet !!! +void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+8); + + uint32 entry; + recv_data >> entry; + + CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); + if (ci) + { + + std::string Name, SubName; + Name = ci->Name; + SubName = ci->SubName; + + int loc_idx = GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + CreatureLocale const *cl = objmgr.GetCreatureLocale(entry); + if (cl) + { + if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty()) + Name = cl->Name[loc_idx]; + if (cl->SubName.size() > loc_idx && !cl->SubName[loc_idx].empty()) + SubName = cl->SubName[loc_idx]; + } + } + sLog.outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name, entry); + // guess size + WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 100 ); + data << (uint32)entry; // creature entry + data << Name; + data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty + data << SubName; + data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 + data << (uint32)ci->flag1; // flags wdbFeild7=wad flags1 + data << (uint32)ci->type; + data << (uint32)ci->family; // family wdbFeild9 + data << (uint32)ci->rank; // rank wdbFeild10 + data << (uint32)0; // unknown wdbFeild11 + data << (uint32)ci->PetSpellDataId; // Id from CreatureSpellData.dbc wdbField12 + data << (uint32)ci->DisplayID_A; // modelid_male1 + data << (uint32)ci->DisplayID_H; // modelid_female1 ? + data << (uint32)ci->DisplayID_A2; // modelid_male2 ? + data << (uint32)ci->DisplayID_H2; // modelid_femmale2 ? + data << (float)1.0f; // unk + data << (float)1.0f; // unk + data << (uint8)ci->RacialLeader; + SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE " ); + } + else + { + uint64 guid; + recv_data >> guid; + + sLog.outDebug( "WORLD: CMSG_CREATURE_QUERY - (%u) NO CREATURE INFO! (GUID: %u, ENTRY: %u)", uint32(GUID_LOPART(guid)), guid, entry ); + WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 ); + data << uint32(entry | 0x80000000); + SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE " ); + } +} + +/// Only _static_ data send in this packet !!! +void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+8); + + uint32 entryID; + recv_data >> entryID; + + const GameObjectInfo *info = objmgr.GetGameObjectInfo(entryID); + if(info) + { + + std::string Name; + std::string CastBarCaption; + + Name = info->name; + CastBarCaption = info->castBarCaption; + + int loc_idx = GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + GameObjectLocale const *gl = objmgr.GetGameObjectLocale(entryID); + if (gl) + { + if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty()) + Name = gl->Name[loc_idx]; + if (gl->CastBarCaption.size() > loc_idx && !gl->CastBarCaption[loc_idx].empty()) + CastBarCaption = gl->CastBarCaption[loc_idx]; + } + } + sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID); + WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 ); + data << entryID; + data << (uint32)info->type; + data << (uint32)info->displayId; + data << Name; + data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4 + data << uint8(0); // 2.0.3, string + data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting") + data << uint8(0); // 2.0.3, probably string + data.append(info->raw.data,24); + data << float(info->size); // go size + SendPacket( &data ); + sLog.outDebug( "WORLD: Sent CMSG_GAMEOBJECT_QUERY " ); + } + else + { + + uint64 guid; + recv_data >> guid; + + sLog.outDebug( "WORLD: CMSG_GAMEOBJECT_QUERY - (%u) Missing gameobject info for (GUID: %u, ENTRY: %u)", uint32(GUID_LOPART(guid)), guid, entryID ); + WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 ); + data << uint32(entryID | 0x80000000); + SendPacket( &data ); + sLog.outDebug( "WORLD: Sent CMSG_GAMEOBJECT_QUERY " ); + } +} + +void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) +{ + sLog.outDetail("WORLD: Received MSG_CORPSE_QUERY"); + + Corpse *corpse = GetPlayer()->GetCorpse(); + + uint8 found = 1; + if(!corpse) + found = 0; + + WorldPacket data(MSG_CORPSE_QUERY, (1+found*(5*4))); + data << uint8(found); + if(found) + { + data << corpse->GetMapId(); + data << corpse->GetPositionX(); + data << corpse->GetPositionY(); + data << corpse->GetPositionZ(); + data << _player->GetMapId(); + } + SendPacket(&data); +} + +void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+8); + + uint32 textID; + uint64 guid; + GossipText *pGossip; + std::string GossipStr; + + recv_data >> textID; + sLog.outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); + + recv_data >> guid; + GetPlayer()->SetUInt64Value(UNIT_FIELD_TARGET, guid); + + pGossip = objmgr.GetGossipText(textID); + + WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size + data << textID; + + if (!pGossip) + { + for(uint32 i = 0; i < 8; ++i) + { + data << float(0); + data << "Greetings $N"; + data << "Greetings $N"; + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + } + } + else + { + std::string Text_0[8], Text_1[8]; + for (int i=0;i<8;i++) + { + Text_0[i]=pGossip->Options[i].Text_0; + Text_1[i]=pGossip->Options[i].Text_1; + } + + int loc_idx = GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + NpcTextLocale const *nl = objmgr.GetNpcTextLocale(textID); + if (nl) + { + for (int i=0;i<8;i++) + { + if (nl->Text_0[i].size() > loc_idx && !nl->Text_0[i][loc_idx].empty()) + Text_0[i]=nl->Text_0[i][loc_idx]; + if (nl->Text_1[i].size() > loc_idx && !nl->Text_1[i][loc_idx].empty()) + Text_1[i]=nl->Text_1[i][loc_idx]; + } + } + } + + for (int i=0; i<8; i++) + { + data << pGossip->Options[i].Probability; + + if ( Text_0[i].empty() ) + data << Text_1[i]; + else + data << Text_0[i]; + + if ( Text_1[i].empty() ) + data << Text_0[i]; + else + data << Text_1[i]; + + data << pGossip->Options[i].Language; + + data << pGossip->Options[i].Emotes[0]._Delay; + data << pGossip->Options[i].Emotes[0]._Emote; + + data << pGossip->Options[i].Emotes[1]._Delay; + data << pGossip->Options[i].Emotes[1]._Emote; + + data << pGossip->Options[i].Emotes[2]._Delay; + data << pGossip->Options[i].Emotes[2]._Emote; + } + } + + SendPacket( &data ); + + sLog.outDebug( "WORLD: Sent SMSG_NPC_TEXT_UPDATE " ); +} + +void WorldSession::HandlePageQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 pageID; + + recv_data >> pageID; + sLog.outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY for pageID '%u'", pageID); + + while (pageID) + { + PageText const *pPage = sPageTextStore.LookupEntry( pageID ); + // guess size + WorldPacket data( SMSG_PAGE_TEXT_QUERY_RESPONSE, 50 ); + data << pageID; + + if (!pPage) + { + data << "Item page missing."; + data << uint32(0); + pageID = 0; + } + else + { + std::string Text = pPage->Text; + + int loc_idx = GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + PageTextLocale const *pl = objmgr.GetPageTextLocale(pageID); + if (pl) + { + if (pl->Text.size() > loc_idx && !pl->Text[loc_idx].empty()) + Text = pl->Text[loc_idx]; + } + } + + data << Text; + data << uint32(pPage->Next_Page); + pageID = pPage->Next_Page; + } + SendPacket( &data ); + + sLog.outDebug( "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE " ); + } +} diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp new file mode 100644 index 000000000..4a96d265e --- /dev/null +++ b/src/game/QuestDef.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "QuestDef.h" +#include "Player.h" +#include "World.h" + +Quest::Quest(Field * questRecord) +{ + QuestId = questRecord[0].GetUInt32(); + QuestMethod = questRecord[1].GetUInt32(); + ZoneOrSort = questRecord[2].GetInt32(); + SkillOrClass = questRecord[3].GetInt32(); + MinLevel = questRecord[4].GetUInt32(); + QuestLevel = questRecord[5].GetUInt32(); + Type = questRecord[6].GetUInt32(); + RequiredRaces = questRecord[7].GetUInt32(); + RequiredSkillValue = questRecord[8].GetUInt32(); + RepObjectiveFaction = questRecord[9].GetUInt32(); + RepObjectiveValue = questRecord[10].GetInt32(); + RequiredMinRepFaction = questRecord[11].GetUInt32(); + RequiredMinRepValue = questRecord[12].GetInt32(); + RequiredMaxRepFaction = questRecord[13].GetUInt32(); + RequiredMaxRepValue = questRecord[14].GetInt32(); + SuggestedPlayers = questRecord[15].GetUInt32(); + LimitTime = questRecord[16].GetUInt32(); + QuestFlags = questRecord[17].GetUInt16(); + uint32 SpecialFlags = questRecord[18].GetUInt16(); + CharTitleId = questRecord[19].GetUInt32(); + PrevQuestId = questRecord[20].GetInt32(); + NextQuestId = questRecord[21].GetInt32(); + ExclusiveGroup = questRecord[22].GetInt32(); + NextQuestInChain = questRecord[23].GetUInt32(); + SrcItemId = questRecord[24].GetUInt32(); + SrcItemCount = questRecord[25].GetUInt32(); + SrcSpell = questRecord[26].GetUInt32(); + Title = questRecord[27].GetCppString(); + Details = questRecord[28].GetCppString(); + Objectives = questRecord[29].GetCppString(); + OfferRewardText = questRecord[30].GetCppString(); + RequestItemsText = questRecord[31].GetCppString(); + EndText = questRecord[32].GetCppString(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + ObjectiveText[i] = questRecord[33+i].GetCppString(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + ReqItemId[i] = questRecord[37+i].GetUInt32(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + ReqItemCount[i] = questRecord[41+i].GetUInt32(); + + for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) + ReqSourceId[i] = questRecord[45+i].GetUInt32(); + + for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) + ReqSourceCount[i] = questRecord[49+i].GetUInt32(); + + for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) + ReqSourceRef[i] = questRecord[53+i].GetUInt32(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32(); + + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + ReqSpell[i] = questRecord[65+i].GetUInt32(); + + for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + RewChoiceItemId[i] = questRecord[69+i].GetUInt32(); + + for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + RewChoiceItemCount[i] = questRecord[75+i].GetUInt32(); + + for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) + RewItemId[i] = questRecord[81+i].GetUInt32(); + + for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) + RewItemCount[i] = questRecord[85+i].GetUInt32(); + + for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) + RewRepFaction[i] = questRecord[89+i].GetUInt32(); + + for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) + RewRepValue[i] = questRecord[94+i].GetInt32(); + + RewOrReqMoney = questRecord[99].GetInt32(); + RewMoneyMaxLevel = questRecord[100].GetUInt32(); + RewSpell = questRecord[101].GetUInt32(); + RewSpellCast = questRecord[102].GetUInt32(); + RewMailTemplateId = questRecord[103].GetUInt32(); + RewMailDelaySecs = questRecord[104].GetUInt32(); + PointMapId = questRecord[105].GetUInt32(); + PointX = questRecord[106].GetFloat(); + PointY = questRecord[107].GetFloat(); + PointOpt = questRecord[108].GetUInt32(); + + for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) + DetailsEmote[i] = questRecord[109+i].GetUInt32(); + + IncompleteEmote = questRecord[113].GetUInt32(); + CompleteEmote = questRecord[114].GetUInt32(); + + for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) + OfferRewardEmote[i] = questRecord[115+i].GetInt32(); + + QuestStartScript = questRecord[119].GetUInt32(); + QuestCompleteScript = questRecord[120].GetUInt32(); + + QuestFlags |= SpecialFlags << 16; + + m_reqitemscount = 0; + m_reqCreatureOrGOcount = 0; + m_rewitemscount = 0; + m_rewchoiceitemscount = 0; + + for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++) + { + if ( ReqItemId[i] ) + ++m_reqitemscount; + if ( ReqCreatureOrGOId[i] ) + ++m_reqCreatureOrGOcount; + } + + for (int i=0; i < QUEST_REWARDS_COUNT; i++) + { + if ( RewItemId[i] ) + ++m_rewitemscount; + } + + for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++) + { + if (RewChoiceItemId[i]) + ++m_rewchoiceitemscount; + } +} + +uint32 Quest::XPValue( Player *pPlayer ) const +{ + if( pPlayer ) + { + if( RewMoneyMaxLevel > 0 ) + { + uint32 pLevel = pPlayer->getLevel(); + uint32 qLevel = QuestLevel; + float fullxp = 0; + if (qLevel >= 65) + fullxp = RewMoneyMaxLevel / 6.0f; + else if (qLevel == 64) + fullxp = RewMoneyMaxLevel / 4.8f; + else if (qLevel == 63) + fullxp = RewMoneyMaxLevel / 3.6f; + else if (qLevel == 62) + fullxp = RewMoneyMaxLevel / 2.4f; + else if (qLevel == 61) + fullxp = RewMoneyMaxLevel / 1.2f; + else if (qLevel > 0 && qLevel <= 60) + fullxp = RewMoneyMaxLevel / 0.6f; + + if( pLevel <= qLevel + 5 ) + return (uint32)fullxp; + else if( pLevel == qLevel + 6 ) + return (uint32)(fullxp * 0.8f); + else if( pLevel == qLevel + 7 ) + return (uint32)(fullxp * 0.6f); + else if( pLevel == qLevel + 8 ) + return (uint32)(fullxp * 0.4f); + else if( pLevel == qLevel + 9 ) + return (uint32)(fullxp * 0.2f); + else + return (uint32)(fullxp * 0.1f); + } + } + return 0; +} + +int32 Quest::GetRewOrReqMoney() const +{ + if(RewOrReqMoney <=0) + return RewOrReqMoney; + + return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY)); +} diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h new file mode 100644 index 000000000..7dc55cab8 --- /dev/null +++ b/src/game/QuestDef.h @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_QUEST_H +#define MANGOSSERVER_QUEST_H + +#include "Platform/Define.h" +#include "Database/DatabaseEnv.h" + +#include +#include + +class Player; + +class ObjectMgr; + +#define MAX_QUEST_LOG_SIZE 25 + +#define QUEST_OBJECTIVES_COUNT 4 +#define QUEST_SOURCE_ITEM_IDS_COUNT 4 +#define QUEST_REWARD_CHOICES_COUNT 6 +#define QUEST_REWARDS_COUNT 4 +#define QUEST_DEPLINK_COUNT 10 +#define QUEST_REPUTATIONS_COUNT 5 +#define QUEST_EMOTE_COUNT 4 + +enum QuestFailedReasons +{ + INVALIDREASON_DONT_HAVE_REQ = 0, + INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest. + INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race. + INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest. + INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time. + INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest + INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account. + INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest + INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage. + INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest. + INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today + INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time +}; + +enum QuestShareMessages +{ + QUEST_PARTY_MSG_SHARING_QUEST = 0, + QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1, + QUEST_PARTY_MSG_ACCEPT_QUEST = 2, + QUEST_PARTY_MSG_REFUSE_QUEST = 3, + QUEST_PARTY_MSG_TOO_FAR = 4, + QUEST_PARTY_MSG_BUSY = 5, + QUEST_PARTY_MSG_LOG_FULL = 6, + QUEST_PARTY_MSG_HAVE_QUEST = 7, + QUEST_PARTY_MSG_FINISH_QUEST = 8, +}; + +enum __QuestTradeSkill +{ + QUEST_TRSKILL_NONE = 0, + QUEST_TRSKILL_ALCHEMY = 1, + QUEST_TRSKILL_BLACKSMITHING = 2, + QUEST_TRSKILL_COOKING = 3, + QUEST_TRSKILL_ENCHANTING = 4, + QUEST_TRSKILL_ENGINEERING = 5, + QUEST_TRSKILL_FIRSTAID = 6, + QUEST_TRSKILL_HERBALISM = 7, + QUEST_TRSKILL_LEATHERWORKING = 8, + QUEST_TRSKILL_POISONS = 9, + QUEST_TRSKILL_TAILORING = 10, + QUEST_TRSKILL_MINING = 11, + QUEST_TRSKILL_FISHING = 12, + QUEST_TRSKILL_SKINNING = 13, + QUEST_TRSKILL_JEWELCRAFTING = 14, +}; + +enum QuestStatus +{ + QUEST_STATUS_NONE = 0, + QUEST_STATUS_COMPLETE = 1, + QUEST_STATUS_UNAVAILABLE = 2, + QUEST_STATUS_INCOMPLETE = 3, + QUEST_STATUS_AVAILABLE = 4, + MAX_QUEST_STATUS +}; + +enum __QuestGiverStatus +{ + DIALOG_STATUS_NONE = 0, + DIALOG_STATUS_UNAVAILABLE = 1, + DIALOG_STATUS_CHAT = 2, + DIALOG_STATUS_INCOMPLETE = 3, + DIALOG_STATUS_REWARD_REP = 4, + DIALOG_STATUS_AVAILABLE_REP = 5, + DIALOG_STATUS_AVAILABLE = 6, + DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap + DIALOG_STATUS_REWARD = 8 // yellow dot on minimap +}; + +enum __QuestFlags +{ + // Flags used at server and sended to client + QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently + QUEST_FLAGS_PARTY_ACCEPT = 2, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT + QUEST_FLAGS_EXPLORATION = 4, // Not used currently + QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest() + //QUEST_FLAGS_NONE2 = 16, // Not used currently + QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content + QUEST_FLAGS_RAID = 64, // Not used currently + QUEST_FLAGS_TBC = 128, // Not used currently: Available if TBC expension enabled only + QUEST_FLAGS_UNK2 = 256, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs + QUEST_FLAGS_HIDDEN_REWARDS = 512, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) + QUEST_FLAGS_AUTO_REWARDED = 1024, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. + QUEST_FLAGS_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests + QUEST_FLAGS_DAILY = 4096, // Used to know quest is Daily one + + // Mangos flags for set SpecialFlags in DB if required but used only at server + QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB + QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if reequired area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL) + QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT, + + // Mangos flags for internal use only + QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // Internal flag computed only + QUEST_MANGOS_FLAGS_SPEAKTO = 0x080000, // Internal flag computed only + QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x100000, // Internal flag computed only + QUEST_MANGOS_FLAGS_TIMED = 0x200000, // Internal flag computed only +}; + +struct QuestLocale +{ + QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); } + + std::vector Title; + std::vector Details; + std::vector Objectives; + std::vector OfferRewardText; + std::vector RequestItemsText; + std::vector EndText; + std::vector< std::vector > ObjectiveText; +}; + +// This Quest class provides a convenient way to access a few pretotaled (cached) quest details, +// all base quest information, and any utility functions such as generating the amount of +// xp to give +class Quest +{ + friend class ObjectMgr; + public: + Quest(Field * questRecord); + uint32 XPValue( Player *pPlayer ) const; + + bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; } + void SetFlag( uint32 flag ) { QuestFlags |= flag; } + + // table data accessors: + uint32 GetQuestId() const { return QuestId; } + uint32 GetQuestMethod() const { return QuestMethod; } + int32 GetZoneOrSort() const { return ZoneOrSort; } + int32 GetSkillOrClass() const { return SkillOrClass; } + uint32 GetMinLevel() const { return MinLevel; } + uint32 GetQuestLevel() const { return QuestLevel; } + uint32 GetType() const { return Type; } + uint32 GetRequiredRaces() const { return RequiredRaces; } + uint32 GetRequiredSkillValue() const { return RequiredSkillValue; } + uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; } + int32 GetRepObjectiveValue() const { return RepObjectiveValue; } + uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; } + int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; } + uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; } + int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; } + uint32 GetSuggestedPlayers() const { return SuggestedPlayers; } + uint32 GetLimitTime() const { return LimitTime; } + int32 GetPrevQuestId() const { return PrevQuestId; } + int32 GetNextQuestId() const { return NextQuestId; } + int32 GetExclusiveGroup() const { return ExclusiveGroup; } + uint32 GetNextQuestInChain() const { return NextQuestInChain; } + uint32 GetCharTitleId() const { return CharTitleId; } + uint32 GetSrcItemId() const { return SrcItemId; } + uint32 GetSrcItemCount() const { return SrcItemCount; } + uint32 GetSrcSpell() const { return SrcSpell; } + std::string GetTitle() const { return Title; } + std::string GetDetails() const { return Details; } + std::string GetObjectives() const { return Objectives; } + std::string GetOfferRewardText() const { return OfferRewardText; } + std::string GetRequestItemsText() const { return RequestItemsText; } + std::string GetEndText() const { return EndText; } + int32 GetRewOrReqMoney() const; + uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; } + // use in XP calculation at client + uint32 GetRewSpell() const { return RewSpell; } + uint32 GetRewSpellCast() const { return RewSpellCast; } + uint32 GetRewMailTemplateId() const { return RewMailTemplateId; } + uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; } + uint32 GetPointMapId() const { return PointMapId; } + float GetPointX() const { return PointX; } + float GetPointY() const { return PointY; } + uint32 GetPointOpt() const { return PointOpt; } + uint32 GetIncompleteEmote() const { return IncompleteEmote; } + uint32 GetCompleteEmote() const { return CompleteEmote; } + uint32 GetQuestStartScript() const { return QuestStartScript; } + uint32 GetQuestCompleteScript() const { return QuestCompleteScript; } + bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; } + bool IsAutoComplete() const { return QuestMethod ? false : true; } + uint32 GetFlags() const { return QuestFlags; } + bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; } + + // multiple values + std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; + uint32 ReqItemId[QUEST_OBJECTIVES_COUNT]; + uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT]; + uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT]; + uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT]; + uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT]; + int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject + uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT]; + uint32 ReqSpell[QUEST_OBJECTIVES_COUNT]; + uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT]; + uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT]; + uint32 RewItemId[QUEST_REWARDS_COUNT]; + uint32 RewItemCount[QUEST_REWARDS_COUNT]; + uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT]; + int32 RewRepValue[QUEST_REPUTATIONS_COUNT]; + uint32 DetailsEmote[QUEST_EMOTE_COUNT]; + uint32 OfferRewardEmote[QUEST_EMOTE_COUNT]; + + uint32 GetReqItemsCount() const { return m_reqitemscount; } + uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; } + uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; } + uint32 GetRewItemsCount() const { return m_rewitemscount; } + + typedef std::vector PrevQuests; + PrevQuests prevQuests; + typedef std::vector PrevChainQuests; + PrevChainQuests prevChainQuests; + + // cached data + private: + uint32 m_reqitemscount; + uint32 m_reqCreatureOrGOcount; + uint32 m_rewchoiceitemscount; + uint32 m_rewitemscount; + + // table data + protected: + uint32 QuestId; + uint32 QuestMethod; + int32 ZoneOrSort; + int32 SkillOrClass; + uint32 MinLevel; + uint32 QuestLevel; + uint32 Type; + uint32 RequiredRaces; + uint32 RequiredSkillValue; + uint32 RepObjectiveFaction; + int32 RepObjectiveValue; + uint32 RequiredMinRepFaction; + int32 RequiredMinRepValue; + uint32 RequiredMaxRepFaction; + int32 RequiredMaxRepValue; + uint32 SuggestedPlayers; + uint32 LimitTime; + uint32 QuestFlags; + uint32 CharTitleId; + int32 PrevQuestId; + int32 NextQuestId; + int32 ExclusiveGroup; + uint32 NextQuestInChain; + uint32 SrcItemId; + uint32 SrcItemCount; + uint32 SrcSpell; + std::string Title; + std::string Details; + std::string Objectives; + std::string OfferRewardText; + std::string RequestItemsText; + std::string EndText; + int32 RewOrReqMoney; + uint32 RewMoneyMaxLevel; + uint32 RewSpell; + uint32 RewSpellCast; + uint32 RewMailTemplateId; + uint32 RewMailDelaySecs; + uint32 PointMapId; + float PointX; + float PointY; + uint32 PointOpt; + uint32 IncompleteEmote; + uint32 CompleteEmote; + uint32 QuestStartScript; + uint32 QuestCompleteScript; +}; + +enum QuestUpdateState +{ + QUEST_UNCHANGED = 0, + QUEST_CHANGED = 1, + QUEST_NEW = 2 +}; + +struct QuestStatusData +{ + QuestStatusData() + : m_status(QUEST_STATUS_NONE),m_rewarded(false), + m_explored(false), m_timer(0), uState(QUEST_NEW) + { + memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32)); + memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32)); + } + + QuestStatus m_status; + bool m_rewarded; + bool m_explored; + uint32 m_timer; + QuestUpdateState uState; + + uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ]; + uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ]; +}; +#endif diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp new file mode 100644 index 000000000..42eea5082 --- /dev/null +++ b/src/game/QuestHandler.cpp @@ -0,0 +1,651 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Log.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "GossipDef.h" +#include "QuestDef.h" +#include "ObjectAccessor.h" +#include "ScriptCalls.h" +#include "Group.h" + +void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + uint8 questStatus = DIALOG_STATUS_NONE; + uint8 defstatus = DIALOG_STATUS_NONE; + + Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if(!questgiver) + { + sLog.outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)",GuidHigh2TypeId(GUID_HIPART(guid)),GUID_LOPART(guid)); + return; + } + + switch(questgiver->GetTypeId()) + { + case TYPEID_UNIT: + { + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u",uint32(GUID_LOPART(guid)) ); + Creature* cr_questgiver=(Creature*)questgiver; + if( !cr_questgiver->IsHostileTo(_player)) // not show quest status to enemies + { + questStatus = Script->NPCDialogStatus(_player, cr_questgiver); + if( questStatus > 6 ) + questStatus = getDialogStatus(_player, cr_questgiver, defstatus); + } + break; + } + case TYPEID_GAMEOBJECT: + { + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u",uint32(GUID_LOPART(guid)) ); + GameObject* go_questgiver=(GameObject*)questgiver; + questStatus = Script->GODialogStatus(_player, go_questgiver); + if( questStatus > 6 ) + questStatus = getDialogStatus(_player, go_questgiver, defstatus); + break; + } + default: + sLog.outError("QuestGiver called for unexpected type %u", questgiver->GetTypeId()); + break; + } + + //inform client about status of quest + _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid); +} + +void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + recv_data >> guid; + + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u",guid ); + + Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_NONE); + if (!pCreature) + { + sLog.outDebug( "WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + // Stop the npc if moving + pCreature->StopMoving(); + + if(Script->GossipHello( _player, pCreature ) ) + return; + + pCreature->prepareGossipMenu(_player,0); + pCreature->sendPreparedGossip( _player ); +} + +void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 guid; + uint32 quest; + recv_data >> guid >> quest; + + if(!GetPlayer()->isAlive()) + return; + + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest ); + + Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); + + // no or incorrect quest giver + if(!pObject + || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest)) + || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) + ) + { + _player->PlayerTalkClass->CloseGossip(); + _player->SetDivider( 0 ); + return; + } + + Quest const* qInfo = objmgr.GetQuestTemplate(quest); + if ( qInfo ) + { + // prevent cheating + if(!GetPlayer()->CanTakeQuest(qInfo,true) ) + { + _player->PlayerTalkClass->CloseGossip(); + _player->SetDivider( 0 ); + return; + } + + if( _player->GetDivider() != 0 ) + { + Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() ); + if( pPlayer ) + { + pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST ); + _player->SetDivider( 0 ); + } + } + + if( _player->CanAddQuest( qInfo, true ) ) + { + _player->AddQuest( qInfo, pObject ); + + if ( _player->CanCompleteQuest( quest ) ) + _player->CompleteQuest( quest ); + + switch(pObject->GetTypeId()) + { + case TYPEID_UNIT: + Script->QuestAccept(_player, ((Creature*)pObject), qInfo ); + break; + case TYPEID_ITEM: + case TYPEID_CONTAINER: + { + Script->ItemQuestAccept(_player, ((Item*)pObject), qInfo ); + + // destroy not required for quest finish quest starting item + bool destroyItem = true; + for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount != 0)) + { + destroyItem = false; + break; + } + } + + if(destroyItem) + _player->DestroyItem(((Item*)pObject)->GetBagSlot(),((Item*)pObject)->GetSlot(),true); + + break; + } + case TYPEID_GAMEOBJECT: + Script->GOQuestAccept(_player, ((GameObject*)pObject), qInfo ); + break; + } + _player->PlayerTalkClass->CloseGossip(); + + if( qInfo->GetSrcSpell() > 0 ) + _player->CastSpell( _player, qInfo->GetSrcSpell(), true); + + return; + } + } + + _player->PlayerTalkClass->CloseGossip(); +} + +void WorldSession::HandleQuestgiverQuestQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint64 guid; + uint32 quest; + recv_data >> guid >> quest; + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest ); + + // Verify that the guid is valid and is a questgiver or involved in the requested quest + Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM); + if(!pObject||!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest)) + { + _player->PlayerTalkClass->CloseGossip(); + return; + } + + Quest const* pQuest = objmgr.GetQuestTemplate(quest); + if ( pQuest ) + { + _player->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, pObject->GetGUID(), true); + } +} + +void WorldSession::HandleQuestQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 quest; + recv_data >> quest; + sLog.outDebug( "WORLD: Received CMSG_QUEST_QUERY quest = %u",quest ); + + Quest const *pQuest = objmgr.GetQuestTemplate(quest); + if ( pQuest ) + { + _player->PlayerTalkClass->SendQuestQueryResponse( pQuest ); + } +} + +void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + uint32 quest, reward; + uint64 guid; + recv_data >> guid >> quest >> reward; + + if(reward >= QUEST_REWARD_CHOICES_COUNT) + { + sLog.outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward); + return; + } + + if(!GetPlayer()->isAlive()) + return; + + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward ); + + Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if(!pObject) + return; + + if(!pObject->hasInvolvedQuest(quest)) + return; + + Quest const *pQuest = objmgr.GetQuestTemplate(quest); + if( pQuest ) + { + if( _player->CanRewardQuest( pQuest, reward, true ) ) + { + _player->RewardQuest( pQuest, reward, pObject ); + + switch(pObject->GetTypeId()) + { + case TYPEID_UNIT: + if( !(Script->ChooseReward( _player, ((Creature*)pObject), pQuest, reward )) ) + { + // Send next quest + if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) ) + _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true); + } + break; + case TYPEID_GAMEOBJECT: + if( !Script->GOChooseReward( _player, ((GameObject*)pObject), pQuest, reward ) ) + { + // Send next quest + if(Quest const* nextquest = _player->GetNextQuest( guid ,pQuest ) ) + _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest,guid,true); + } + break; + } + } + else + _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true ); + } +} + +void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint32 quest; + uint64 guid; + recv_data >> guid >> quest; + + if(!GetPlayer()->isAlive()) + return; + + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest ); + + Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if(!pObject||!pObject->hasInvolvedQuest(quest)) + return; + + if ( _player->CanCompleteQuest( quest ) ) + _player->CompleteQuest( quest ); + + if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE ) + return; + + if(Quest const *pQuest = objmgr.GetQuestTemplate(quest)) + _player->PlayerTalkClass->SendQuestGiverOfferReward( pQuest, guid, true ); +} + +void WorldSession::HandleQuestgiverCancel(WorldPacket& /*recv_data*/ ) +{ + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CANCEL" ); + + _player->PlayerTalkClass->CloseGossip(); +} + +void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,1+1); + + uint8 slot1, slot2; + recv_data >> slot1 >> slot2; + + if(slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE) + return; + + sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = %u, slot 2 = %u", slot1, slot2 ); + + GetPlayer()->SwapQuestSlot(slot1,slot2); +} + +void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,1); + + uint8 slot; + recv_data >> slot; + + sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u",slot ); + + if( slot < MAX_QUEST_LOG_SIZE ) + { + if(uint32 quest = _player->GetQuestSlotQuestId(slot)) + { + if(!_player->TakeQuestSourceItem( quest, true )) + return; // can't un-equip some items, reject quest cancel + + _player->SetQuestStatus( quest, QUEST_STATUS_NONE); + } + + _player->SetQuestSlot(slot, 0); + } +} + +void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 quest; + recv_data >> quest; + + sLog.outDebug( "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u",quest ); +} + +void WorldSession::HandleQuestComplete(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data,8+4); + + uint32 quest; + uint64 guid; + recv_data >> guid >> quest; + + if(!GetPlayer()->isAlive()) + return; + + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest ); + + Quest const *pQuest = objmgr.GetQuestTemplate(quest); + if( pQuest ) + { + if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE ) + { + if( pQuest->IsRepeatable() ) + _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanCompleteRepeatableQuest(pQuest), false); + else + _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false); + } + else + _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest,false), false); + } +} + +void WorldSession::HandleQuestAutoLaunch(WorldPacket& /*recvPacket*/) +{ + sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUEST_AUTOLAUNCH (Send your log to anakin if you see this message)" ); +} + +void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,4); + + uint32 quest; + recvPacket >> quest; + + sLog.outDebug( "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", quest ); + + Quest const *pQuest = objmgr.GetQuestTemplate(quest); + if( pQuest ) + { + if( _player->GetGroup() ) + { + Group *pGroup = _player->GetGroup(); + if( pGroup ) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *pPlayer = itr->getSource(); + if (!pPlayer || pPlayer == _player) // skip self + continue; + + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); + + if( _player->GetDistance( pPlayer ) > 10 ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR ); + continue; + } + + if( !pPlayer->SatisfyQuestStatus( pQuest, false ) ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST ); + continue; + } + + if( pPlayer->GetQuestStatus( quest ) == QUEST_STATUS_COMPLETE ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_FINISH_QUEST ); + continue; + } + + if( !pPlayer->CanTakeQuest( pQuest, false ) ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST ); + continue; + } + + if( !pPlayer->SatisfyQuestLog( false ) ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_LOG_FULL ); + continue; + } + + if( pPlayer->GetDivider() != 0 ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_BUSY ); + continue; + } + + pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails( pQuest, _player->GetGUID(), true ); + pPlayer->SetDivider( _player->GetGUID() ); + } + } + } + } +} + +void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,8+1); + + uint64 guid; + uint8 msg; + recvPacket >> guid >> msg; + + sLog.outDebug( "WORLD: Received MSG_QUEST_PUSH_RESULT" ); + + if( _player->GetDivider() != 0 ) + { + Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() ); + if( pPlayer ) + { + WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1) ); + data << uint64(guid); + data << uint8(msg); // valid values: 0-8 + pPlayer->GetSession()->SendPacket(&data); + _player->SetDivider( 0 ); + } + } +} + +uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus) +{ + uint32 result = defstatus; + + QuestRelations const* qir; + QuestRelations const* qr; + + switch(questgiver->GetTypeId()) + { + case TYPEID_GAMEOBJECT: + { + qir = &objmgr.mGOQuestInvolvedRelations; + qr = &objmgr.mGOQuestRelations; + break; + } + case TYPEID_UNIT: + { + qir = &objmgr.mCreatureQuestInvolvedRelations; + qr = &objmgr.mCreatureQuestRelations; + break; + } + default: + //its imposible, but check ^) + sLog.outError("Warning: GetDialogStatus called for unexpected type %u", questgiver->GetTypeId()); + return DIALOG_STATUS_NONE; + } + + for(QuestRelations::const_iterator i = qir->lower_bound(questgiver->GetEntry()); i != qir->upper_bound(questgiver->GetEntry()); ++i ) + { + uint32 result2 = 0; + uint32 quest_id = i->second; + Quest const *pQuest = objmgr.GetQuestTemplate(quest_id); + if ( !pQuest ) continue; + + QuestStatus status = pPlayer->GetQuestStatus( quest_id ); + if( (status == QUEST_STATUS_COMPLETE && !pPlayer->GetQuestRewardStatus(quest_id)) || + (pQuest->IsAutoComplete() && pPlayer->CanTakeQuest(pQuest, false)) ) + { + if ( pQuest->IsAutoComplete() && pQuest->IsRepeatable() ) + result2 = DIALOG_STATUS_REWARD_REP; + else + result2 = DIALOG_STATUS_REWARD; + } + else if ( status == QUEST_STATUS_INCOMPLETE ) + result2 = DIALOG_STATUS_INCOMPLETE; + + if (result2 > result) + result = result2; + } + + for(QuestRelations::const_iterator i = qr->lower_bound(questgiver->GetEntry()); i != qr->upper_bound(questgiver->GetEntry()); ++i ) + { + uint32 result2 = 0; + uint32 quest_id = i->second; + Quest const *pQuest = objmgr.GetQuestTemplate(quest_id); + if ( !pQuest ) + continue; + + QuestStatus status = pPlayer->GetQuestStatus( quest_id ); + if ( status == QUEST_STATUS_NONE ) + { + if ( pPlayer->CanSeeStartQuest( pQuest ) ) + { + if ( pPlayer->SatisfyQuestLevel(pQuest, false) ) + { + if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded)) + result2 = DIALOG_STATUS_REWARD_REP; + else if (pPlayer->getLevel() <= pQuest->GetQuestLevel() + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) ) + { + if (pQuest->HasFlag(QUEST_FLAGS_DAILY)) + result2 = DIALOG_STATUS_AVAILABLE_REP; + else + result2 = DIALOG_STATUS_AVAILABLE; + } + else + result2 = DIALOG_STATUS_CHAT; + } + else + result2 = DIALOG_STATUS_UNAVAILABLE; + } + } + + if (result2 > result) + result = result2; + } + + if(questgiver->GetTypeId()==TYPEID_UNIT && ((Creature*)questgiver)->isCanTrainingAndResetTalentsOf(pPlayer) && result < DIALOG_STATUS_CHAT) + result = DIALOG_STATUS_CHAT; + + return result; +} + +void WorldSession::HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& /*recvPacket*/) +{ + sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY"); + + uint32 count = 0; + + WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4); + data << uint32(count); // placeholder + + for(Player::ClientGUIDs::iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) + { + uint8 questStatus = DIALOG_STATUS_NONE; + uint8 defstatus = DIALOG_STATUS_NONE; + + if(IS_CREATURE_GUID(*itr)) + { + Creature *questgiver = ObjectAccessor::GetCreature(*_player, *itr); + if(!questgiver || questgiver->IsHostileTo(_player)) + continue; + if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) + continue; + questStatus = Script->NPCDialogStatus(_player, questgiver); + if( questStatus > 6 ) + questStatus = getDialogStatus(_player, questgiver, defstatus); + + data << uint64(questgiver->GetGUID()); + data << uint8(questStatus); + ++count; + } + else if(IS_GAMEOBJECT_GUID(*itr)) + { + GameObject *questgiver = ObjectAccessor::GetGameObject(*_player, *itr); + if(!questgiver) + continue; + if(questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) + continue; + questStatus = Script->GODialogStatus(_player, questgiver); + if( questStatus > 6 ) + questStatus = getDialogStatus(_player, questgiver, defstatus); + + data << uint64(questgiver->GetGUID()); + data << uint8(questStatus); + ++count; + } + } + + data.put(0, count); // write real count + SendPacket(&data); +} diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp new file mode 100644 index 000000000..10f54e9c6 --- /dev/null +++ b/src/game/RandomMovementGenerator.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Creature.h" +#include "MapManager.h" +#include "RandomMovementGenerator.h" +#include "DestinationHolderImp.h" +#include "Map.h" +#include "Util.h" + +#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV" + +template<> +void +RandomMovementGenerator::_setRandomLocation(Creature &creature) +{ + float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist; + + creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance); + + z = creature.GetPositionZ(); + uint32 mapid=creature.GetMapId(); + Map const* map = MapManager::Instance().GetBaseMap(mapid); + + // For 2D/3D system selection + bool is_land_ok = creature.canWalk(); + bool is_water_ok = creature.canSwim(); + bool is_air_ok = creature.canFly(); + + const float angle = rand_norm()*(M_PI*2); + const float range = rand_norm()*wander_distance; + const float distanceX = range * cos(angle); + const float distanceY = range * sin(angle); + + nx = X + distanceX; + ny = Y + distanceY; + + // prevent invalid coordinates generation + MaNGOS::NormalizeMapCoord(nx); + MaNGOS::NormalizeMapCoord(ny); + + dist = distanceX*distanceX + distanceY*distanceY; + + if (is_air_ok) // 3D system above ground and above water (flying mode) + { + const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change + nz = Z + distanceZ; + float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. + float wz = map->GetWaterLevel(nx, ny); + if (tz >= nz || wz >= nz) + return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick + } + //else if (is_water_ok) // 3D system under water and above ground (swimming mode) + else // 2D only + { + dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) + // The fastest way to get an accurate result 90% of the time. + // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. + nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check + if (fabs(nz-Z)>dist) + { + nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above + if (fabs(nz-Z)>dist) + { + nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher + if (fabs(nz-Z)>dist) + return; // let's forget this bad coords where a z cannot be find and retry at next tick + } + } + } + + Traveller traveller(creature); + creature.SetOrientation(creature.GetAngle(nx,ny)); + i_destinationHolder.SetDestination(traveller, nx, ny, nz); + creature.addUnitState(UNIT_STAT_ROAMING); + if (is_air_ok) + { + i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + } + //else if (is_water_ok) // Swimming mode to be done with more than this check + else + { + i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime())); + creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); + } +} + +template<> +void +RandomMovementGenerator::Initialize(Creature &creature) +{ + if(!creature.isAlive()) + return; + + if (creature.canFly()) + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + else + creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE ); + _setRandomLocation(creature); +} + +template<> +void +RandomMovementGenerator::Reset(Creature &creature) +{ + Initialize(creature); +} + +template<> +bool +RandomMovementGenerator::Update(Creature &creature, const uint32 &diff) +{ + if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) + { + i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer + creature.clearUnitState(UNIT_STAT_ROAMING); + return true; + } + + i_nextMoveTime.Update(diff); + + if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly()) + creature.clearUnitState(UNIT_STAT_ROAMING); + + if(!i_destinationHolder.HasArrived() && creature.IsStopped()) + creature.addUnitState(UNIT_STAT_ROAMING); + + CreatureTraveller traveller(creature); + + if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) ) + { + if(i_nextMoveTime.Passed()) + { + if (creature.canFly()) + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + else + creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE); + _setRandomLocation(creature); + } + else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f) + { + creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE); + _setRandomLocation(creature); + } + } + return true; +} diff --git a/src/game/RandomMovementGenerator.h b/src/game/RandomMovementGenerator.h new file mode 100644 index 000000000..83dfecb0d --- /dev/null +++ b/src/game/RandomMovementGenerator.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_RANDOMMOTIONGENERATOR_H +#define MANGOS_RANDOMMOTIONGENERATOR_H + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "Traveller.h" + +template +class MANGOS_DLL_SPEC RandomMovementGenerator +: public MovementGeneratorMedium< T, RandomMovementGenerator > +{ + public: + RandomMovementGenerator(const Unit &) : i_nextMoveTime(0) {} + + void _setRandomLocation(T &); + void Initialize(T &); + void Finalize(T &) {} + void Reset(T &); + bool Update(T &, const uint32 &); + void UpdateMapPosition(uint32 mapid, float &x ,float &y, float &z) + { + i_destinationHolder.GetLocationNow(mapid, x,y,z); + } + MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; } + private: + TimeTrackerSmall i_nextMoveTime; + + DestinationHolder< Traveller > i_destinationHolder; + uint32 i_nextMove; +}; +#endif diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp new file mode 100644 index 000000000..a3037cc55 --- /dev/null +++ b/src/game/ReactorAI.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ByteBuffer.h" +#include "ReactorAI.h" +#include "Errors.h" +#include "Creature.h" +#include "Log.h" +#include "ObjectAccessor.h" + +#define REACTOR_VISIBLE_RANGE (26.46f) + +int +ReactorAI::Permissible(const Creature *creature) +{ + if( creature->isCivilian() || creature->IsNeutralToAll() ) + return PERMIT_BASE_REACTIVE; + + return PERMIT_BASE_NO; +} + +void +ReactorAI::MoveInLineOfSight(Unit *) +{ +} + +void +ReactorAI::AttackStart(Unit *p) +{ + if(!p) + return; + + if(i_creature.Attack(p,true)) + { + DEBUG_LOG("Tag unit GUID: %u (TypeId: %u) as a victim", p->GetGUIDLow(), p->GetTypeId()); + i_creature.SetInCombatWith(p); + p->SetInCombatWith(&i_creature); + + i_creature.AddThreat(p, 0.0f); + i_victimGuid = p->GetGUID(); + i_creature.GetMotionMaster()->MoveChase(p); + } +} + +bool +ReactorAI::IsVisible(Unit *) const +{ + return false; +} + +void +ReactorAI::UpdateAI(const uint32 /*time_diff*/) +{ + // update i_victimGuid if i_creature.getVictim() !=0 and changed + if(!i_creature.SelectHostilTarget() || !i_creature.getVictim()) + return; + + i_victimGuid = i_creature.getVictim()->GetGUID(); + + if( i_creature.isAttackReady() ) + { + if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE)) + { + i_creature.AttackerStateUpdate(i_creature.getVictim()); + i_creature.resetAttackTimer(); + } + } +} + +void +ReactorAI::EnterEvadeMode() +{ + if( !i_creature.isAlive() ) + { + DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow()); + i_creature.GetMotionMaster()->MovementExpired(); + i_creature.GetMotionMaster()->MoveIdle(); + i_victimGuid = 0; + i_creature.CombatStop(); + i_creature.DeleteThreatList(); + return; + } + + Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid ); + + if( !victim ) + { + DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow()); + } + else if( victim->HasStealthAura() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow()); + } + else if( victim->isInFlight() ) + { + DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow()); + } + else + { + DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", i_creature.GetGUIDLow()); + } + + i_creature.RemoveAllAuras(); + i_creature.DeleteThreatList(); + i_victimGuid = 0; + i_creature.CombatStop(); + i_creature.SetLootRecipient(NULL); + + // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead + if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) + i_creature.GetMotionMaster()->MoveTargetedHome(); +} diff --git a/src/game/ReactorAI.h b/src/game/ReactorAI.h new file mode 100644 index 000000000..117156bb5 --- /dev/null +++ b/src/game/ReactorAI.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_REACTORAI_H +#define MANGOS_REACTORAI_H + +#include "CreatureAI.h" + +class Unit; + +class MANGOS_DLL_DECL ReactorAI : public CreatureAI +{ + public: + + ReactorAI(Creature &c) : i_creature(c), i_victimGuid(0) {} + + void MoveInLineOfSight(Unit *); + void AttackStart(Unit *); + void EnterEvadeMode(); + bool IsVisible(Unit *) const; + + void UpdateAI(const uint32); + static int Permissible(const Creature *); + + private: + Creature &i_creature; + uint64 i_victimGuid; +}; +#endif diff --git a/src/game/ScriptCalls.cpp b/src/game/ScriptCalls.cpp new file mode 100644 index 000000000..2a744e437 --- /dev/null +++ b/src/game/ScriptCalls.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef WIN32 +#include +#endif + +#include "Platform/Define.h" +#include "ScriptCalls.h" + +ScriptsSet Script=NULL; + +void UnloadScriptingModule() +{ + if(Script) + { + //todo: some check if some func from script library is called right now + Script->ScriptsFree(); + MANGOS_CLOSE_LIBRARY(Script->hScriptsLib); + delete Script; + Script = NULL; + } +} + +bool LoadScriptingModule(char const* libName) +{ + ScriptsSet testScript=new _ScriptSet; + + std::string name = strlen(libName) ? libName : MANGOS_SCRIPT_NAME; + name += MANGOS_SCRIPT_EXT; + + testScript->hScriptsLib=MANGOS_LOAD_LIBRARY(name.c_str()); + + if(!testScript->hScriptsLib ) + { + printf("Error loading Scripts Library %s !\n",name.c_str()); + delete testScript; + return false; + } + + if( !(testScript->ScriptsInit =(scriptCallScriptsInit )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsInit" )) + ||!(testScript->ScriptsFree =(scriptCallScriptsFree )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsFree" )) + ||!(testScript->GossipHello =(scriptCallGossipHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipHello" )) + ||!(testScript->GOChooseReward =(scriptCallGOChooseReward )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOChooseReward" )) + ||!(testScript->QuestAccept =(scriptCallQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestAccept" )) + ||!(testScript->GossipSelect =(scriptCallGossipSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelect" )) + ||!(testScript->GossipSelectWithCode=(scriptCallGossipSelectWithCode)MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelectWithCode")) + ||!(testScript->QuestSelect =(scriptCallQuestSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestSelect" )) + ||!(testScript->QuestComplete =(scriptCallQuestComplete )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestComplete" )) + ||!(testScript->NPCDialogStatus =(scriptCallNPCDialogStatus )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"NPCDialogStatus" )) + ||!(testScript->GODialogStatus =(scriptCallGODialogStatus )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GODialogStatus" )) + ||!(testScript->ChooseReward =(scriptCallChooseReward )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ChooseReward" )) + ||!(testScript->ItemHello =(scriptCallItemHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemHello" )) + ||!(testScript->GOHello =(scriptCallGOHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOHello" )) + ||!(testScript->scriptAreaTrigger =(scriptCallAreaTrigger )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"AreaTrigger" )) + ||!(testScript->ItemQuestAccept =(scriptCallItemQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemQuestAccept" )) + ||!(testScript->GOQuestAccept =(scriptCallGOQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOQuestAccept" )) + ||!(testScript->ReceiveEmote =(scriptCallReceiveEmote )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ReceiveEmote" )) + ||!(testScript->ItemUse =(scriptCallItemUse )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemUse" )) + ||!(testScript->GetAI =(scriptCallGetAI )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GetAI" )) + ||!(testScript->CreateInstanceData =(scriptCallCreateInstanceData )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"CreateInstanceData" )) + ) + { + printf("Error loading Scripts Library %s !\n Library missing required functions.",name.c_str()); + MANGOS_CLOSE_LIBRARY(testScript->hScriptsLib); + delete testScript; + return false; + } + + printf("Scripts Library %s was successfully loaded.\n",name.c_str()); + + //heh we are still there :P we have a valid library + //we reload script + UnloadScriptingModule(); + + Script=testScript; + Script->ScriptsInit(); + + return true; +} diff --git a/src/game/ScriptCalls.h b/src/game/ScriptCalls.h new file mode 100644 index 000000000..0b8b58344 --- /dev/null +++ b/src/game/ScriptCalls.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SCRIPT_CALLS_H +#define __SCRIPT_CALLS_H + +#include "Common.h" +#include "ObjectMgr.h" + +class Creature; +class CreatureAI; +class GameObject; +class Item; +class Player; +class Quest; +class SpellCastTargets; +class Map; +class InstanceData; + +bool LoadScriptingModule(char const* libName = ""); +void UnloadScriptingModule(); + +typedef void(MANGOS_IMPORT * scriptCallScriptsInit) (); +typedef void(MANGOS_IMPORT * scriptCallScriptsFree) (); + +typedef bool(MANGOS_IMPORT * scriptCallGossipHello) (Player *player, Creature *_Creature ); +typedef bool(MANGOS_IMPORT * scriptCallQuestAccept) (Player *player, Creature *_Creature, Quest const *); +typedef bool(MANGOS_IMPORT * scriptCallGossipSelect)(Player *player, Creature *_Creature, uint32 sender, uint32 action); +typedef bool(MANGOS_IMPORT * scriptCallGossipSelectWithCode)( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode ); +typedef bool(MANGOS_IMPORT * scriptCallQuestSelect)( Player *player, Creature *_Creature, Quest const* ); +typedef bool(MANGOS_IMPORT * scriptCallQuestComplete)(Player *player, Creature *_Creature, Quest const*); +typedef uint32(MANGOS_IMPORT * scriptCallNPCDialogStatus)( Player *player, Creature *_Creature); +typedef uint32(MANGOS_IMPORT * scriptCallGODialogStatus)( Player *player, GameObject * _GO); +typedef bool(MANGOS_IMPORT * scriptCallChooseReward)( Player *player, Creature *_Creature, Quest const*, uint32 opt ); +typedef bool(MANGOS_IMPORT * scriptCallItemHello)( Player *player, Item *, Quest const*); +typedef bool(MANGOS_IMPORT * scriptCallGOHello)( Player *player, GameObject * ); +typedef bool(MANGOS_IMPORT * scriptCallAreaTrigger)( Player *player, AreaTriggerEntry const* ); +typedef bool(MANGOS_IMPORT * scriptCallItemQuestAccept)(Player *player, Item *, Quest const*); +typedef bool(MANGOS_IMPORT * scriptCallGOQuestAccept)(Player *player, GameObject *, Quest const*); +typedef bool(MANGOS_IMPORT * scriptCallGOChooseReward)(Player *player, GameObject *, Quest const*, uint32 opt ); +typedef bool(MANGOS_IMPORT * scriptCallReceiveEmote) ( Player *player, Creature *_Creature, uint32 emote ); +typedef bool(MANGOS_IMPORT * scriptCallItemUse) (Player *player, Item *_Item, SpellCastTargets const& targets); +typedef CreatureAI* (MANGOS_IMPORT * scriptCallGetAI) ( Creature *_Creature ); +typedef InstanceData* (MANGOS_IMPORT * scriptCallCreateInstanceData) (Map *map); + +typedef struct +{ + scriptCallScriptsInit ScriptsInit; + scriptCallScriptsFree ScriptsFree; + + scriptCallGossipHello GossipHello; + scriptCallGOChooseReward GOChooseReward; + scriptCallQuestAccept QuestAccept; + scriptCallGossipSelect GossipSelect; + scriptCallGossipSelectWithCode GossipSelectWithCode; + scriptCallQuestSelect QuestSelect; + scriptCallQuestComplete QuestComplete; + scriptCallNPCDialogStatus NPCDialogStatus; + scriptCallGODialogStatus GODialogStatus; + scriptCallChooseReward ChooseReward; + scriptCallItemHello ItemHello; + scriptCallGOHello GOHello; + scriptCallAreaTrigger scriptAreaTrigger; + scriptCallItemQuestAccept ItemQuestAccept; + scriptCallGOQuestAccept GOQuestAccept; + scriptCallReceiveEmote ReceiveEmote; + scriptCallItemUse ItemUse; + scriptCallGetAI GetAI; + scriptCallCreateInstanceData CreateInstanceData; + + MANGOS_LIBRARY_HANDLE hScriptsLib; +}_ScriptSet,*ScriptsSet; + +extern ScriptsSet Script; +#endif diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h new file mode 100644 index 000000000..6c2ab2a92 --- /dev/null +++ b/src/game/SharedDefines.h @@ -0,0 +1,2101 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_SHAREDDEFINES_H +#define MANGOS_SHAREDDEFINES_H + +#include "Platform/Define.h" +#include + +enum Gender +{ + GENDER_MALE = 0, + GENDER_FEMALE = 1, + GENDER_NONE = 2 +}; + +// Race value is index in ChrRaces.dbc +enum Races +{ + RACE_HUMAN = 1, + RACE_ORC = 2, + RACE_DWARF = 3, + RACE_NIGHTELF = 4, + RACE_UNDEAD_PLAYER = 5, + RACE_TAUREN = 6, + RACE_GNOME = 7, + RACE_TROLL = 8, + RACE_GOBLIN = 9, + RACE_BLOODELF = 10, + RACE_DRAENEI = 11, + RACE_FEL_ORC = 12, + RACE_NAGA = 13, + RACE_BROKEN = 14, + RACE_SKELETON = 15, + MAX_RACES = 16 +}; + +#define RACEMASK_ALL_PLAYABLE \ + ((1<<(RACE_HUMAN-1)) |(1<<(RACE_ORC-1)) |(1<<(RACE_DWARF-1)) | \ + (1<<(RACE_NIGHTELF-1))|(1<<(RACE_UNDEAD_PLAYER-1))|(1<<(RACE_TAUREN-1)) | \ + (1<<(RACE_GNOME-1)) |(1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1))| \ + (1<<(RACE_DRAENEI-1)) ) + +// Class value is index in ChrClasses.dbc +enum Classes +{ + CLASS_WARRIOR = 1, + CLASS_PALADIN = 2, + CLASS_HUNTER = 3, + CLASS_ROGUE = 4, + CLASS_PRIEST = 5, + CLASS_DEATH_KNIGHT = 6, + CLASS_SHAMAN = 7, + CLASS_MAGE = 8, + CLASS_WARLOCK = 9, + // CLASS_UNK2 = 10,unused + CLASS_DRUID = 11, + MAX_CLASSES = 12 +}; + +#define CLASSMASK_ALL_PLAYABLE \ + ((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \ + (1<<(CLASS_ROGUE-1)) |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \ + (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) ) + +#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1))) + +#define PLAYER_MAX_BATTLEGROUND_QUEUES 3 + +enum ReputationRank +{ + REP_HATED = 0, + REP_HOSTILE = 1, + REP_UNFRIENDLY = 2, + REP_NEUTRAL = 3, + REP_FRIENDLY = 4, + REP_HONORED = 5, + REP_REVERED = 6, + REP_EXALTED = 7 +}; + +#define MIN_REPUTATION_RANK (REP_HATED) +#define MAX_REPUTATION_RANK 8 + +enum MoneyConstants +{ + COPPER = 1, + SILVER = COPPER*100, + GOLD = SILVER*100 +}; + +enum Stats +{ + STAT_STRENGTH = 0, + STAT_AGILITY = 1, + STAT_STAMINA = 2, + STAT_INTELLECT = 3, + STAT_SPIRIT = 4 +}; + +#define MAX_STATS 5 + +enum Powers +{ + POWER_MANA = 0, + POWER_RAGE = 1, + POWER_FOCUS = 2, + POWER_ENERGY = 3, + POWER_HAPPINESS = 4, + POWER_RUNES = 5, + POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) +}; + +#define MAX_POWERS 5 // not count POWER_RUNES for now + +enum SpellSchools +{ + SPELL_SCHOOL_NORMAL = 0, + SPELL_SCHOOL_HOLY = 1, + SPELL_SCHOOL_FIRE = 2, + SPELL_SCHOOL_NATURE = 3, + SPELL_SCHOOL_FROST = 4, + SPELL_SCHOOL_SHADOW = 5, + SPELL_SCHOOL_ARCANE = 6 +}; + +#define MAX_SPELL_SCHOOL 7 + +enum SpellSchoolMask +{ + SPELL_SCHOOL_MASK_NONE = 0x00, // not exist + SPELL_SCHOOL_MASK_NORMAL = (1 << SPELL_SCHOOL_NORMAL), // PHYSICAL (Armor) + SPELL_SCHOOL_MASK_HOLY = (1 << SPELL_SCHOOL_HOLY ), + SPELL_SCHOOL_MASK_FIRE = (1 << SPELL_SCHOOL_FIRE ), + SPELL_SCHOOL_MASK_NATURE = (1 << SPELL_SCHOOL_NATURE), + SPELL_SCHOOL_MASK_FROST = (1 << SPELL_SCHOOL_FROST ), + SPELL_SCHOOL_MASK_SHADOW = (1 << SPELL_SCHOOL_SHADOW), + SPELL_SCHOOL_MASK_ARCANE = (1 << SPELL_SCHOOL_ARCANE), + + // unions + + // 124, not include normal and holy damage + SPELL_SCHOOL_MASK_SPELL = ( SPELL_SCHOOL_MASK_FIRE | + SPELL_SCHOOL_MASK_NATURE | SPELL_SCHOOL_MASK_FROST | + SPELL_SCHOOL_MASK_SHADOW | SPELL_SCHOOL_MASK_ARCANE ), + // 126 + SPELL_SCHOOL_MASK_MAGIC = ( SPELL_SCHOOL_MASK_HOLY | SPELL_SCHOOL_MASK_SPELL ), + + // 127 + SPELL_SCHOOL_MASK_ALL = ( SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_MASK_MAGIC ) +}; + +#define SPELL_SCHOOL_MASK_MAGIC \ + ( SPELL_SCHOOL_MASK_HOLY | SPELL_SCHOOL_MASK_FIRE | SPELL_SCHOOL_MASK_NATURE | \ + SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW | \ + SPELL_SCHOOL_MASK_ARCANE ) + +inline SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask) +{ + for(int i = 0; i < MAX_SPELL_SCHOOL; ++i) + if(mask & (1 << i)) + return SpellSchools(i); + + return SPELL_SCHOOL_NORMAL; +} + +enum ItemQualities +{ + ITEM_QUALITY_POOR = 0, //GREY + ITEM_QUALITY_NORMAL = 1, //WHITE + ITEM_QUALITY_UNCOMMON = 2, //GREEN + ITEM_QUALITY_RARE = 3, //BLUE + ITEM_QUALITY_EPIC = 4, //PURPLE + ITEM_QUALITY_LEGENDARY = 5, //ORANGE + ITEM_QUALITY_ARTIFACT = 6 //LIGHT YELLOW +}; + +#define MAX_ITEM_QUALITY 7 + +// *********************************** +// Spell Attributes definitions +// *********************************** + +#define SPELL_ATTR_UNK0 0x00000001 // 0 +#define SPELL_ATTR_RANGED 0x00000002 // 1 All ranged abilites have this flag +#define SPELL_ATTR_ON_NEXT_SWING_1 0x00000004 // 2 on next swing +#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 2.4.2 +#define SPELL_ATTR_UNK4 0x00000010 // 4 +#define SPELL_ATTR_UNK5 0x00000020 // 5 trade spells? +#define SPELL_ATTR_PASSIVE 0x00000040 // 6 Passive spell +#define SPELL_ATTR_UNK7 0x00000080 // 7 visible? +#define SPELL_ATTR_UNK8 0x00000100 // 8 +#define SPELL_ATTR_UNK9 0x00000200 // 9 +#define SPELL_ATTR_ON_NEXT_SWING_2 0x00000400 // 10 on next swing 2 +#define SPELL_ATTR_UNK11 0x00000800 // 11 +#define SPELL_ATTR_DAYTIME_ONLY 0x00001000 // 12 only useable at daytime, not set in 2.4.2 +#define SPELL_ATTR_NIGHT_ONLY 0x00002000 // 13 only useable at night, not set in 2.4.2 +#define SPELL_ATTR_INDOORS_ONLY 0x00004000 // 14 only useable indoors, not set in 2.4.2 +#define SPELL_ATTR_OUTDOORS_ONLY 0x00008000 // 15 Only useable outdoors. +#define SPELL_ATTR_NOT_SHAPESHIFT 0x00010000 // 16 Not while shapeshifted +#define SPELL_ATTR_ONLY_STEALTHED 0x00020000 // 17 Must be in stealth +#define SPELL_ATTR_UNK18 0x00040000 // 18 +#define SPELL_ATTR_LEVEL_DAMAGE_CALCULATION 0x00080000 // 19 spelldamage depends on caster level +#define SPELL_ATTR_STOP_ATTACK_TARGET 0x00100000 // 20 Stop attack after use this spell (and not begin attack if use) +#define SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK 0x00200000 // 21 Cannot be dodged/parried/blocked +#define SPELL_ATTR_UNK22 0x00400000 // 22 +#define SPELL_ATTR_UNK23 0x00800000 // 23 castable while dead? +#define SPELL_ATTR_CASTABLE_WHILE_MOUNTED 0x01000000 // 24 castable while mounted +#define SPELL_ATTR_DISABLED_WHILE_ACTIVE 0x02000000 // 25 Activate and start cooldown after aura fade or remove summoned creature or go +#define SPELL_ATTR_UNK26 0x04000000 // 26 +#define SPELL_ATTR_CASTABLE_WHILE_SITTING 0x08000000 // 27 castable while sitting +#define SPELL_ATTR_CANT_USED_IN_COMBAT 0x10000000 // 28 Cannot be used in combat +#define SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY 0x20000000 // 29 unaffected by invulnerability (hmm possible not...) +#define SPELL_ATTR_UNK30 0x40000000 // 30 breakable by damage? +#define SPELL_ATTR_CANT_CANCEL 0x80000000 // 31 positive aura can't be canceled + +#define SPELL_ATTR_EX_UNK0 0x00000001 // 0 +#define SPELL_ATTR_EX_DRAIN_ALL_POWER 0x00000002 // 1 use all power (Only paladin Lay of Hands and Bunyanize) +#define SPELL_ATTR_EX_CHANNELED_1 0x00000004 // 2 channeled 1 +#define SPELL_ATTR_EX_UNK3 0x00000008 // 3 +#define SPELL_ATTR_EX_UNK4 0x00000010 // 4 +#define SPELL_ATTR_EX_NOT_BREAK_STEALTH 0x00000020 // 5 Not break stealth +#define SPELL_ATTR_EX_CHANNELED_2 0x00000040 // 6 channeled 2 +#define SPELL_ATTR_EX_NEGATIVE 0x00000080 // 7 +#define SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET 0x00000100 // 8 Spell req target not to be in combat state +#define SPELL_ATTR_EX_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX_UNK10 0x00000400 // 10 +#define SPELL_ATTR_EX_UNK11 0x00000800 // 11 +#define SPELL_ATTR_EX_UNK12 0x00001000 // 12 +#define SPELL_ATTR_EX_UNK13 0x00002000 // 13 +#define SPELL_ATTR_EX_UNK14 0x00004000 // 14 +#define SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY 0x00008000 // 15 remove auras on immunity +#define SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE 0x00010000 // 16 unaffected by school immunity +#define SPELL_ATTR_EX_UNK17 0x00020000 // 17 +#define SPELL_ATTR_EX_UNK18 0x00040000 // 18 +#define SPELL_ATTR_EX_UNK19 0x00080000 // 19 +#define SPELL_ATTR_EX_REQ_COMBO_POINTS1 0x00100000 // 20 Req combo points on target +#define SPELL_ATTR_EX_UNK21 0x00200000 // 21 +#define SPELL_ATTR_EX_REQ_COMBO_POINTS2 0x00400000 // 22 Req combo points on target +#define SPELL_ATTR_EX_UNK23 0x00800000 // 23 +#define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole?? +#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 not set in 2.4.2 +#define SPELL_ATTR_EX_UNK26 0x04000000 // 26 +#define SPELL_ATTR_EX_UNK27 0x08000000 // 27 +#define SPELL_ATTR_EX_UNK28 0x10000000 // 28 +#define SPELL_ATTR_EX_UNK29 0x20000000 // 29 +#define SPELL_ATTR_EX_UNK30 0x40000000 // 30 overpower +#define SPELL_ATTR_EX_UNK31 0x80000000 // 31 + +#define SPELL_ATTR_EX2_UNK0 0x00000001 // 0 +#define SPELL_ATTR_EX2_UNK1 0x00000002 // 1 +#define SPELL_ATTR_EX2_UNK2 0x00000004 // 2 +#define SPELL_ATTR_EX2_UNK3 0x00000008 // 3 +#define SPELL_ATTR_EX2_UNK4 0x00000010 // 4 +#define SPELL_ATTR_EX2_UNK5 0x00000020 // 5 +#define SPELL_ATTR_EX2_UNK6 0x00000040 // 6 +#define SPELL_ATTR_EX2_UNK7 0x00000080 // 7 +#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 2.4.2 +#define SPELL_ATTR_EX2_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX2_UNK10 0x00000400 // 10 +#define SPELL_ATTR_EX2_HEALTH_FUNNEL 0x00000800 // 11 +#define SPELL_ATTR_EX2_UNK12 0x00001000 // 12 +#define SPELL_ATTR_EX2_UNK13 0x00002000 // 13 +#define SPELL_ATTR_EX2_UNK14 0x00004000 // 14 +#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 2.4.2 +#define SPELL_ATTR_EX2_UNK16 0x00010000 // 16 +#define SPELL_ATTR_EX2_UNK17 0x00020000 // 17 Hunters Shot and Stings only have this flag +#define SPELL_ATTR_EX2_UNK18 0x00040000 // 18 Only Revive pet - possible req dead pet +#define SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT 0x00080000 // 19 does not necessarly need shapeshift +#define SPELL_ATTR_EX2_UNK20 0x00100000 // 20 +#define SPELL_ATTR_EX2_UNK21 0x00200000 // 21 +#define SPELL_ATTR_EX2_UNK22 0x00400000 // 22 +#define SPELL_ATTR_EX2_UNK23 0x00800000 // 23 Only mage Arcane Concentration have this flag +#define SPELL_ATTR_EX2_UNK24 0x01000000 // 24 +#define SPELL_ATTR_EX2_UNK25 0x02000000 // 25 +#define SPELL_ATTR_EX2_UNK26 0x04000000 // 26 unaffected by school immunity +#define SPELL_ATTR_EX2_UNK27 0x08000000 // 27 +#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28 +#define SPELL_ATTR_EX2_CANT_CRIT 0x20000000 // 29 Spell can't crit +#define SPELL_ATTR_EX2_UNK30 0x40000000 // 30 +#define SPELL_ATTR_EX2_UNK31 0x80000000 // 31 + +#define SPELL_ATTR_EX3_UNK0 0x00000001 // 0 +#define SPELL_ATTR_EX3_UNK1 0x00000002 // 1 +#define SPELL_ATTR_EX3_UNK2 0x00000004 // 2 +#define SPELL_ATTR_EX3_UNK3 0x00000008 // 3 +#define SPELL_ATTR_EX3_UNK4 0x00000010 // 4 Druid Rebirth only this spell have this flag +#define SPELL_ATTR_EX3_UNK5 0x00000020 // 5 +#define SPELL_ATTR_EX3_UNK6 0x00000040 // 6 +#define SPELL_ATTR_EX3_UNK7 0x00000080 // 7 +#define SPELL_ATTR_EX3_UNK8 0x00000100 // 8 +#define SPELL_ATTR_EX3_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX3_MAIN_HAND 0x00000400 // 10 Main hand weapon required +#define SPELL_ATTR_EX3_BATTLEGROUND 0x00000800 // 11 Can casted only on battleground +#define SPELL_ATTR_EX3_UNK12 0x00001000 // 12 +#define SPELL_ATTR_EX3_UNK13 0x00002000 // 13 +#define SPELL_ATTR_EX3_UNK14 0x00004000 // 14 "Honorless Target" only this spells have this flag +#define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag +#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16 +#define SPELL_ATTR_EX3_NO_INITIAL_AGGRO 0x00020000 // 17 no initial aggro +#define SPELL_ATTR_EX3_UNK18 0x00040000 // 18 +#define SPELL_ATTR_EX3_UNK19 0x00080000 // 19 +#define SPELL_ATTR_EX3_DEATH_PERSISTENT 0x00100000 // 20 Death persistent spells +#define SPELL_ATTR_EX3_UNK21 0x00200000 // 21 +#define SPELL_ATTR_EX3_REQ_WAND 0x00400000 // 22 Req wand +#define SPELL_ATTR_EX3_UNK23 0x00800000 // 23 +#define SPELL_ATTR_EX3_REQ_OFFHAND 0x01000000 // 24 Req offhand weapon +#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25 +#define SPELL_ATTR_EX3_UNK26 0x04000000 // 26 +#define SPELL_ATTR_EX3_UNK27 0x08000000 // 27 +#define SPELL_ATTR_EX3_UNK28 0x10000000 // 28 +#define SPELL_ATTR_EX3_UNK29 0x20000000 // 29 +#define SPELL_ATTR_EX3_UNK30 0x40000000 // 30 +#define SPELL_ATTR_EX3_UNK31 0x80000000 // 31 + +#define SPELL_ATTR_EX4_UNK0 0x00000001 // 0 +#define SPELL_ATTR_EX4_UNK1 0x00000002 // 1 proc on finishing move? +#define SPELL_ATTR_EX4_UNK2 0x00000004 // 2 +#define SPELL_ATTR_EX4_UNK3 0x00000008 // 3 +#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4 +#define SPELL_ATTR_EX4_UNK5 0x00000020 // 5 +#define SPELL_ATTR_EX4_UNK6 0x00000040 // 6 +#define SPELL_ATTR_EX4_UNK7 0x00000080 // 7 +#define SPELL_ATTR_EX4_UNK8 0x00000100 // 8 +#define SPELL_ATTR_EX4_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX4_SPELL_VS_EXTEND_COST 0x00000400 // 10 Rogue Shiv have this flag +#define SPELL_ATTR_EX4_UNK11 0x00000800 // 11 +#define SPELL_ATTR_EX4_UNK12 0x00001000 // 12 +#define SPELL_ATTR_EX4_UNK13 0x00002000 // 13 +#define SPELL_ATTR_EX4_UNK14 0x00004000 // 14 +#define SPELL_ATTR_EX4_UNK15 0x00008000 // 15 +#define SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA 0x00010000 // 16 not usable in arena +#define SPELL_ATTR_EX4_USABLE_IN_ARENA 0x00020000 // 17 usable in arena +#define SPELL_ATTR_EX4_UNK18 0x00040000 // 18 +#define SPELL_ATTR_EX4_UNK19 0x00080000 // 19 +#define SPELL_ATTR_EX4_UNK20 0x00100000 // 20 +#define SPELL_ATTR_EX4_UNK21 0x00200000 // 21 +#define SPELL_ATTR_EX4_UNK22 0x00400000 // 22 +#define SPELL_ATTR_EX4_UNK23 0x00800000 // 23 +#define SPELL_ATTR_EX4_UNK24 0x01000000 // 24 +#define SPELL_ATTR_EX4_UNK25 0x02000000 // 25 pet scaling auras +#define SPELL_ATTR_EX4_CAST_ONLY_IN_OUTLAND 0x04000000 // 26 Can only be used in Outland. +#define SPELL_ATTR_EX4_UNK27 0x08000000 // 27 +#define SPELL_ATTR_EX4_UNK28 0x10000000 // 28 +#define SPELL_ATTR_EX4_UNK29 0x20000000 // 29 +#define SPELL_ATTR_EX4_UNK30 0x40000000 // 30 +#define SPELL_ATTR_EX4_UNK31 0x80000000 // 31 + +#define SPELL_ATTR_EX5_UNK0 0x00000001 // 0 +#define SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP 0x00000002 // 1 not need reagents if UNIT_FLAG_PREPARATION +#define SPELL_ATTR_EX5_UNK2 0x00000004 // 2 +#define SPELL_ATTR_EX5_USABLE_WHILE_STUNNED 0x00000008 // 3 usable while stunned +#define SPELL_ATTR_EX5_UNK4 0x00000010 // 4 +#define SPELL_ATTR_EX5_SINGLE_TARGET_SPELL 0x00000020 // 5 Only one target can be apply at a time +#define SPELL_ATTR_EX5_UNK6 0x00000040 // 6 +#define SPELL_ATTR_EX5_UNK7 0x00000080 // 7 +#define SPELL_ATTR_EX5_UNK8 0x00000100 // 8 +#define SPELL_ATTR_EX5_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX5_UNK10 0x00000400 // 10 +#define SPELL_ATTR_EX5_UNK11 0x00000800 // 11 +#define SPELL_ATTR_EX5_UNK12 0x00001000 // 12 +#define SPELL_ATTR_EX5_UNK13 0x00002000 // 13 +#define SPELL_ATTR_EX5_UNK14 0x00004000 // 14 +#define SPELL_ATTR_EX5_UNK15 0x00008000 // 15 +#define SPELL_ATTR_EX5_UNK16 0x00010000 // 16 +#define SPELL_ATTR_EX5_USABLE_WHILE_FEARED 0x00020000 // 17 usable while feared +#define SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED 0x00040000 // 18 usable while confused +#define SPELL_ATTR_EX5_UNK19 0x00080000 // 19 +#define SPELL_ATTR_EX5_UNK20 0x00100000 // 20 +#define SPELL_ATTR_EX5_UNK21 0x00200000 // 21 +#define SPELL_ATTR_EX5_UNK22 0x00400000 // 22 +#define SPELL_ATTR_EX5_UNK23 0x00800000 // 23 +#define SPELL_ATTR_EX5_UNK24 0x01000000 // 24 +#define SPELL_ATTR_EX5_UNK25 0x02000000 // 25 +#define SPELL_ATTR_EX5_UNK26 0x04000000 // 26 +#define SPELL_ATTR_EX5_UNK27 0x08000000 // 27 +#define SPELL_ATTR_EX5_UNK28 0x10000000 // 28 +#define SPELL_ATTR_EX5_UNK29 0x20000000 // 29 +#define SPELL_ATTR_EX5_UNK30 0x40000000 // 30 +#define SPELL_ATTR_EX5_UNK31 0x80000000 // 31 Forces all nearby enemies to focus attacks caster + +#define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag +#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK2 0x00000004 // 2 +#define SPELL_ATTR_EX6_UNK3 0x00000008 // 3 +#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK5 0x00000020 // 5 +#define SPELL_ATTR_EX6_UNK6 0x00000040 // 6 +#define SPELL_ATTR_EX6_UNK7 0x00000080 // 7 +#define SPELL_ATTR_EX6_UNK8 0x00000100 // 8 +#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK10 0x00000400 // 10 +#define SPELL_ATTR_EX6_UNK11 0x00000800 // 11 +#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 2.4.2 + +enum SheathTypes +{ + SHEATHETYPE_NONE = 0, + SHEATHETYPE_MAINHAND = 1, + SHEATHETYPE_OFFHAND = 2, + SHEATHETYPE_LARGEWEAPONLEFT = 3, + SHEATHETYPE_LARGEWEAPONRIGHT = 4, + SHEATHETYPE_HIPWEAPONLEFT = 5, + SHEATHETYPE_HIPWEAPONRIGHT = 6, + SHEATHETYPE_SHIELD = 7 +}; + +#define MAX_SHEATHETYPE 8 + +enum CharacterSlot +{ + SLOT_HEAD = 0, + SLOT_NECK = 1, + SLOT_SHOULDERS = 2, + SLOT_SHIRT = 3, + SLOT_CHEST = 4, + SLOT_WAIST = 5, + SLOT_LEGS = 6, + SLOT_FEET = 7, + SLOT_WRISTS = 8, + SLOT_HANDS = 9, + SLOT_FINGER1 = 10, + SLOT_FINGER2 = 11, + SLOT_TRINKET1 = 12, + SLOT_TRINKET2 = 13, + SLOT_BACK = 14, + SLOT_MAIN_HAND = 15, + SLOT_OFF_HAND = 16, + SLOT_RANGED = 17, + SLOT_TABARD = 18, + SLOT_EMPTY = 19 +}; + +enum Language +{ + LANG_UNIVERSAL = 0, + LANG_ORCISH = 1, + LANG_DARNASSIAN = 2, + LANG_TAURAHE = 3, + LANG_DWARVISH = 6, + LANG_COMMON = 7, + LANG_DEMONIC = 8, + LANG_TITAN = 9, + LANG_THALASSIAN = 10, + LANG_DRACONIC = 11, + LANG_KALIMAG = 12, + LANG_GNOMISH = 13, + LANG_TROLL = 14, + LANG_GUTTERSPEAK = 33, + LANG_DRAENEI = 35, + LANG_ZOMBIE = 36, + LANG_GNOMISH_BINARY = 37, + LANG_GOBLIN_BINARY = 38, + LANG_ADDON = 0xFFFFFFFF // used by addons, in 2.4.0 not exit, replaced by messagetype? +}; + +#define LANGUAGES_COUNT 19 + +enum Team +{ + HORDE = 67, + ALLIANCE = 469, + //TEAM_STEAMWHEEDLE_CARTEL = 169, // not used in code + //TEAM_ALLIANCE_FORCES = 891, + //TEAM_HORDE_FORCES = 892, + //TEAM_SANCTUARY = 936, + //TEAM_OUTLAND = 980, + //TEAM_OTHER = 0, // if ReputationListId > 0 && Flags != FACTION_FLAG_TEAM_HEADER +}; + +enum SpellEffects +{ + SPELL_EFFECT_INSTAKILL = 1, + SPELL_EFFECT_SCHOOL_DAMAGE = 2, + SPELL_EFFECT_DUMMY = 3, + SPELL_EFFECT_PORTAL_TELEPORT = 4, + SPELL_EFFECT_TELEPORT_UNITS = 5, + SPELL_EFFECT_APPLY_AURA = 6, + SPELL_EFFECT_ENVIRONMENTAL_DAMAGE = 7, + SPELL_EFFECT_POWER_DRAIN = 8, + SPELL_EFFECT_HEALTH_LEECH = 9, + SPELL_EFFECT_HEAL = 10, + SPELL_EFFECT_BIND = 11, + SPELL_EFFECT_PORTAL = 12, + SPELL_EFFECT_RITUAL_BASE = 13, + SPELL_EFFECT_RITUAL_SPECIALIZE = 14, + SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL = 15, + SPELL_EFFECT_QUEST_COMPLETE = 16, + SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL = 17, + SPELL_EFFECT_RESURRECT = 18, + SPELL_EFFECT_ADD_EXTRA_ATTACKS = 19, + SPELL_EFFECT_DODGE = 20, + SPELL_EFFECT_EVADE = 21, + SPELL_EFFECT_PARRY = 22, + SPELL_EFFECT_BLOCK = 23, + SPELL_EFFECT_CREATE_ITEM = 24, + SPELL_EFFECT_WEAPON = 25, + SPELL_EFFECT_DEFENSE = 26, + SPELL_EFFECT_PERSISTENT_AREA_AURA = 27, + SPELL_EFFECT_SUMMON = 28, + SPELL_EFFECT_LEAP = 29, + SPELL_EFFECT_ENERGIZE = 30, + SPELL_EFFECT_WEAPON_PERCENT_DAMAGE = 31, + SPELL_EFFECT_TRIGGER_MISSILE = 32, + SPELL_EFFECT_OPEN_LOCK = 33, + SPELL_EFFECT_SUMMON_CHANGE_ITEM = 34, + SPELL_EFFECT_APPLY_AREA_AURA_PARTY = 35, + SPELL_EFFECT_LEARN_SPELL = 36, + SPELL_EFFECT_SPELL_DEFENSE = 37, + SPELL_EFFECT_DISPEL = 38, + SPELL_EFFECT_LANGUAGE = 39, + SPELL_EFFECT_DUAL_WIELD = 40, + SPELL_EFFECT_SUMMON_WILD = 41, + SPELL_EFFECT_SUMMON_GUARDIAN = 42, + SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43, + SPELL_EFFECT_SKILL_STEP = 44, + SPELL_EFFECT_UNDEFINED_45 = 45, + SPELL_EFFECT_SPAWN = 46, + SPELL_EFFECT_TRADE_SKILL = 47, + SPELL_EFFECT_STEALTH = 48, + SPELL_EFFECT_DETECT = 49, + // SPELL_EFFECT_SUMMON_OBJECT = 50, + SPELL_EFFECT_TRANS_DOOR = 50, + SPELL_EFFECT_FORCE_CRITICAL_HIT = 51, + SPELL_EFFECT_GUARANTEE_HIT = 52, + SPELL_EFFECT_ENCHANT_ITEM = 53, + SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY = 54, + SPELL_EFFECT_TAMECREATURE = 55, + SPELL_EFFECT_SUMMON_PET = 56, + SPELL_EFFECT_LEARN_PET_SPELL = 57, + SPELL_EFFECT_WEAPON_DAMAGE = 58, + SPELL_EFFECT_OPEN_LOCK_ITEM = 59, + SPELL_EFFECT_PROFICIENCY = 60, + SPELL_EFFECT_SEND_EVENT = 61, + SPELL_EFFECT_POWER_BURN = 62, + SPELL_EFFECT_THREAT = 63, + SPELL_EFFECT_TRIGGER_SPELL = 64, + SPELL_EFFECT_HEALTH_FUNNEL = 65, + SPELL_EFFECT_POWER_FUNNEL = 66, + SPELL_EFFECT_HEAL_MAX_HEALTH = 67, + SPELL_EFFECT_INTERRUPT_CAST = 68, + SPELL_EFFECT_DISTRACT = 69, + SPELL_EFFECT_PULL = 70, + SPELL_EFFECT_PICKPOCKET = 71, + SPELL_EFFECT_ADD_FARSIGHT = 72, + SPELL_EFFECT_SUMMON_POSSESSED = 73, + SPELL_EFFECT_SUMMON_TOTEM = 74, + SPELL_EFFECT_HEAL_MECHANICAL = 75, + SPELL_EFFECT_SUMMON_OBJECT_WILD = 76, + SPELL_EFFECT_SCRIPT_EFFECT = 77, + SPELL_EFFECT_ATTACK = 78, + SPELL_EFFECT_SANCTUARY = 79, + SPELL_EFFECT_ADD_COMBO_POINTS = 80, + SPELL_EFFECT_CREATE_HOUSE = 81, + SPELL_EFFECT_BIND_SIGHT = 82, + SPELL_EFFECT_DUEL = 83, + SPELL_EFFECT_STUCK = 84, + SPELL_EFFECT_SUMMON_PLAYER = 85, + SPELL_EFFECT_ACTIVATE_OBJECT = 86, + SPELL_EFFECT_SUMMON_TOTEM_SLOT1 = 87, + SPELL_EFFECT_SUMMON_TOTEM_SLOT2 = 88, + SPELL_EFFECT_SUMMON_TOTEM_SLOT3 = 89, + SPELL_EFFECT_SUMMON_TOTEM_SLOT4 = 90, + SPELL_EFFECT_THREAT_ALL = 91, + SPELL_EFFECT_ENCHANT_HELD_ITEM = 92, + SPELL_EFFECT_SUMMON_PHANTASM = 93, + SPELL_EFFECT_SELF_RESURRECT = 94, + SPELL_EFFECT_SKINNING = 95, + SPELL_EFFECT_CHARGE = 96, + SPELL_EFFECT_SUMMON_CRITTER = 97, + SPELL_EFFECT_KNOCK_BACK = 98, + SPELL_EFFECT_DISENCHANT = 99, + SPELL_EFFECT_INEBRIATE = 100, + SPELL_EFFECT_FEED_PET = 101, + SPELL_EFFECT_DISMISS_PET = 102, + SPELL_EFFECT_REPUTATION = 103, + SPELL_EFFECT_SUMMON_OBJECT_SLOT1 = 104, + SPELL_EFFECT_SUMMON_OBJECT_SLOT2 = 105, + SPELL_EFFECT_SUMMON_OBJECT_SLOT3 = 106, + SPELL_EFFECT_SUMMON_OBJECT_SLOT4 = 107, + SPELL_EFFECT_DISPEL_MECHANIC = 108, + SPELL_EFFECT_SUMMON_DEAD_PET = 109, + SPELL_EFFECT_DESTROY_ALL_TOTEMS = 110, + SPELL_EFFECT_DURABILITY_DAMAGE = 111, + SPELL_EFFECT_SUMMON_DEMON = 112, + SPELL_EFFECT_RESURRECT_NEW = 113, + SPELL_EFFECT_ATTACK_ME = 114, + SPELL_EFFECT_DURABILITY_DAMAGE_PCT = 115, + SPELL_EFFECT_SKIN_PLAYER_CORPSE = 116, + SPELL_EFFECT_SPIRIT_HEAL = 117, + SPELL_EFFECT_SKILL = 118, + SPELL_EFFECT_APPLY_AREA_AURA_PET = 119, + SPELL_EFFECT_TELEPORT_GRAVEYARD = 120, + SPELL_EFFECT_NORMALIZED_WEAPON_DMG = 121, + SPELL_EFFECT_122 = 122, + SPELL_EFFECT_SEND_TAXI = 123, + SPELL_EFFECT_PLAYER_PULL = 124, + SPELL_EFFECT_MODIFY_THREAT_PERCENT = 125, + SPELL_EFFECT_STEAL_BENEFICIAL_BUFF = 126, + SPELL_EFFECT_PROSPECTING = 127, + SPELL_EFFECT_APPLY_AREA_AURA_FRIEND = 128, + SPELL_EFFECT_APPLY_AREA_AURA_ENEMY = 129, + SPELL_EFFECT_REDIRECT_THREAT = 130, + SPELL_EFFECT_131 = 131, + SPELL_EFFECT_132 = 132, + SPELL_EFFECT_UNLEARN_SPECIALIZATION = 133, + SPELL_EFFECT_KILL_CREDIT = 134, + SPELL_EFFECT_135 = 135, + SPELL_EFFECT_HEAL_PCT = 136, + SPELL_EFFECT_ENERGIZE_PCT = 137, + SPELL_EFFECT_138 = 138, + SPELL_EFFECT_139 = 139, + SPELL_EFFECT_FORCE_CAST = 140, + SPELL_EFFECT_141 = 141, + SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE = 142, + SPELL_EFFECT_APPLY_AREA_AURA_OWNER = 143, + SPELL_EFFECT_144 = 144, + SPELL_EFFECT_145 = 145, + SPELL_EFFECT_146 = 146, + SPELL_EFFECT_QUEST_FAIL = 147, + SPELL_EFFECT_148 = 148, + SPELL_EFFECT_149 = 149, + SPELL_EFFECT_150 = 150, + SPELL_EFFECT_TRIGGER_SPELL_2 = 151, + SPELL_EFFECT_152 = 152, + SPELL_EFFECT_153 = 153, + TOTAL_SPELL_EFFECTS = 154 +}; + +// Spell aura states +enum AuraState +{ // (C) used in caster aura state (T) used in target aura state + // (c) used in caster aura state-not (t) used in target aura state-not + AURA_STATE_DEFENSE = 1, // C | + AURA_STATE_HEALTHLESS_20_PERCENT = 2, // CcT | + AURA_STATE_BERSERKING = 3, // C T | + //AURA_STATE_UNKNOWN4 = 4, // c t| some limitation to charge spells (?) and target test spells + AURA_STATE_JUDGEMENT = 5, // C | + //AURA_STATE_UNKNOWN6 = 6, // | not used + AURA_STATE_HUNTER_PARRY = 7, // C | + AURA_STATE_ROGUE_ATTACK_FROM_STEALTH = 7, // C | FIX ME: not implemented yet! + //AURA_STATE_UNKNOWN7c = 7, // c | random/focused bursts spells (?) + //AURA_STATE_UNKNOWN8 = 8, // | not used + //AURA_STATE_UNKNOWN9 = 9, // | not used + AURA_STATE_WARRIOR_VICTORY_RUSH = 10, // C | warrior victory rush + AURA_STATE_HUNTER_CRIT_STRIKE = 10, // C | hunter crit strike + AURA_STATE_CRIT = 11, // C | + AURA_STATE_FAERIE_FIRE = 12, // c t| + AURA_STATE_HEALTHLESS_35_PERCENT = 13, // C T | + AURA_STATE_IMMOLATE = 14, // T | + AURA_STATE_SWIFTMEND = 15, // T | + AURA_STATE_DEADLY_POISON = 16, // T | + AURA_STATE_FORBEARANCE = 17, // c t| + AURA_STATE_WEAKENED_SOUL = 18, // t| + AURA_STATE_HYPOTHERMIA = 19 // c | +}; + +// Spell mechanics +enum Mechanics +{ + MECHANIC_NONE = 0, + MECHANIC_CHARM = 1, + MECHANIC_CONFUSED = 2, + MECHANIC_DISARM = 3, + MECHANIC_DISTRACT = 4, + MECHANIC_FEAR = 5, + MECHANIC_FUMBLE = 6, + MECHANIC_ROOT = 7, + MECHANIC_PACIFY = 8, //0 spells use this mechanic + MECHANIC_SILENCE = 9, + MECHANIC_SLEEP = 10, + MECHANIC_SNARE = 11, + MECHANIC_STUN = 12, + MECHANIC_FREEZE = 13, + MECHANIC_KNOCKOUT = 14, + MECHANIC_BLEED = 15, + MECHANIC_BANDAGE = 16, + MECHANIC_POLYMORPH = 17, + MECHANIC_BANISH = 18, + MECHANIC_SHIELD = 19, + MECHANIC_SHACKLE = 20, + MECHANIC_MOUNT = 21, + MECHANIC_PERSUADE = 22, //0 spells use this mechanic + MECHANIC_TURN = 23, + MECHANIC_HORROR = 24, + MECHANIC_INVULNERABILITY = 25, + MECHANIC_INTERRUPT = 26, + MECHANIC_DAZE = 27, + MECHANIC_DISCOVERY = 28, + MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block + MECHANIC_SAPPED = 30 +}; + +// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6) +#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \ + (1<(only this effect in the spell) can't cast to it, +//some aura(related to Mechanics or ImmuneToState) can't apply to it. +enum SpellImmunity +{ + IMMUNITY_EFFECT = 0, // enum SpellEffects + IMMUNITY_STATE = 1, // enum AuraType + IMMUNITY_SCHOOL = 2, // enum SpellSchoolMask + IMMUNITY_DAMAGE = 3, // enum SpellSchoolMask + IMMUNITY_DISPEL = 4, // enum DispelType + IMMUNITY_MECHANIC = 5 // enum Mechanics +}; + +#define MAX_SPELL_IMMUNITY 6 + +enum Targets +{ + TARGET_SELF = 1, + TARGET_RANDOM_ENEMY_CHAIN_IN_AREA = 2, // only one spell has that, but regardless, it's a target type after all + TARGET_PET = 5, + TARGET_CHAIN_DAMAGE = 6, + TARGET_AREAEFFECT_CUSTOM = 8, + TARGET_INNKEEPER_COORDINATES = 9, // uses in teleport to innkeeper spells + TARGET_ALL_ENEMY_IN_AREA = 15, + TARGET_ALL_ENEMY_IN_AREA_INSTANT = 16, + TARGET_TABLE_X_Y_Z_COORDINATES = 17, // uses in teleport spells and some other + TARGET_EFFECT_SELECT = 18, // highly depends on the spell effect + TARGET_ALL_PARTY_AROUND_CASTER = 20, + TARGET_SINGLE_FRIEND = 21, + TARGET_ALL_AROUND_CASTER = 22, // used only in TargetA, target selection dependent from TargetB + TARGET_GAMEOBJECT = 23, + TARGET_IN_FRONT_OF_CASTER = 24, + TARGET_DUELVSPLAYER = 25, + TARGET_GAMEOBJECT_ITEM = 26, + TARGET_MASTER = 27, + TARGET_ALL_ENEMY_IN_AREA_CHANNELED = 28, + TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER = 30, // in TargetB used only with TARGET_ALL_AROUND_CASTER and in self casting range in TargetA + TARGET_ALL_FRIENDLY_UNITS_IN_AREA = 31, + TARGET_MINION = 32, + TARGET_ALL_PARTY = 33, + TARGET_ALL_PARTY_AROUND_CASTER_2 = 34, // used in Tranquility + TARGET_SINGLE_PARTY = 35, + TARGET_AREAEFFECT_PARTY = 37, + TARGET_SCRIPT = 38, + TARGET_SELF_FISHING = 39, + TARGET_TOTEM_EARTH = 41, + TARGET_TOTEM_WATER = 42, + TARGET_TOTEM_AIR = 43, + TARGET_TOTEM_FIRE = 44, + TARGET_CHAIN_HEAL = 45, + TARGET_SCRIPT_COORDINATES = 46, + TARGET_DYNAMIC_OBJECT = 47, + TARGET_SUMMON = 48, + TARGET_AREAEFFECT_CUSTOM_2 = 52, + TARGET_CURRENT_ENEMY_COORDINATES = 53, // set unit coordinates as dest, only 16 target B imlemented + TARGET_RANDOM_RAID_MEMBER = 56, + TARGET_SINGLE_FRIEND_2 = 57, + TARGET_AREAEFFECT_PARTY_AND_CLASS = 61, + TARGET_DUELVSPLAYER_COORDINATES = 63, + TARGET_BEHIND_VICTIM = 65, // uses in teleport behind spells + TARGET_SINGLE_ENEMY = 77, + TARGET_SELF2 = 87, + TARGET_NONCOMBAT_PET = 90, +}; + +enum SpellMissInfo +{ + SPELL_MISS_NONE = 0, + SPELL_MISS_MISS = 1, + SPELL_MISS_RESIST = 2, + SPELL_MISS_DODGE = 3, + SPELL_MISS_PARRY = 4, + SPELL_MISS_BLOCK = 5, + SPELL_MISS_EVADE = 6, + SPELL_MISS_IMMUNE = 7, + SPELL_MISS_IMMUNE2 = 8, + SPELL_MISS_DEFLECT = 9, + SPELL_MISS_ABSORB = 10, + SPELL_MISS_REFLECT = 11, +}; + +enum SpellHitType +{ + SPELL_HIT_TYPE_UNK1 = 0x00001, + SPELL_HIT_TYPE_CRIT = 0x00002, + SPELL_HIT_TYPE_UNK2 = 0x00004, + SPELL_HIT_TYPE_UNK3 = 0x00008, + SPELL_HIT_TYPE_UNK4 = 0x00020 +}; + +enum SpellDmgClass +{ + SPELL_DAMAGE_CLASS_NONE = 0, + SPELL_DAMAGE_CLASS_MAGIC = 1, + SPELL_DAMAGE_CLASS_MELEE = 2, + SPELL_DAMAGE_CLASS_RANGED = 3 +}; + +enum SpellPreventionType +{ + SPELL_PREVENTION_TYPE_NONE = 0, + SPELL_PREVENTION_TYPE_SILENCE = 1, + SPELL_PREVENTION_TYPE_PACIFY = 2 +}; + +enum GameobjectTypes +{ + GAMEOBJECT_TYPE_DOOR = 0, + GAMEOBJECT_TYPE_BUTTON = 1, + GAMEOBJECT_TYPE_QUESTGIVER = 2, + GAMEOBJECT_TYPE_CHEST = 3, + GAMEOBJECT_TYPE_BINDER = 4, + GAMEOBJECT_TYPE_GENERIC = 5, + GAMEOBJECT_TYPE_TRAP = 6, + GAMEOBJECT_TYPE_CHAIR = 7, + GAMEOBJECT_TYPE_SPELL_FOCUS = 8, + GAMEOBJECT_TYPE_TEXT = 9, + GAMEOBJECT_TYPE_GOOBER = 10, + GAMEOBJECT_TYPE_TRANSPORT = 11, + GAMEOBJECT_TYPE_AREADAMAGE = 12, + GAMEOBJECT_TYPE_CAMERA = 13, + GAMEOBJECT_TYPE_MAP_OBJECT = 14, + GAMEOBJECT_TYPE_MO_TRANSPORT = 15, + GAMEOBJECT_TYPE_DUEL_ARBITER = 16, + GAMEOBJECT_TYPE_FISHINGNODE = 17, + GAMEOBJECT_TYPE_SUMMONING_RITUAL = 18, + GAMEOBJECT_TYPE_MAILBOX = 19, + GAMEOBJECT_TYPE_AUCTIONHOUSE = 20, + GAMEOBJECT_TYPE_GUARDPOST = 21, + GAMEOBJECT_TYPE_SPELLCASTER = 22, + GAMEOBJECT_TYPE_MEETINGSTONE = 23, + GAMEOBJECT_TYPE_FLAGSTAND = 24, + GAMEOBJECT_TYPE_FISHINGHOLE = 25, + GAMEOBJECT_TYPE_FLAGDROP = 26, + GAMEOBJECT_TYPE_MINI_GAME = 27, + GAMEOBJECT_TYPE_LOTTERY_KIOSK = 28, + GAMEOBJECT_TYPE_CAPTURE_POINT = 29, + GAMEOBJECT_TYPE_AURA_GENERATOR = 30, + GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY = 31, + GAMEOBJECT_TYPE_BARBER_CHAIR = 32, + GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING = 33, + GAMEOBJECT_TYPE_GUILD_BANK = 34, +}; + +#define MAX_GAMEOBJECT_TYPE 35 // sending to client this or greater value can crash client. + +#define GAMEOBJECT_FISHINGNODE_ENTRY 35591 // Better to define it somewhere instead of hardcoding everywhere + +enum GameObjectFlags +{ + GO_FLAG_IN_USE = 0x01, //disables interaction while animated + GO_FLAG_LOCKED = 0x02, //require key, spell, event, etc to be opened. Makes "Locked" appear in tooltip + GO_FLAG_INTERACT_COND = 0x04, //cannot interact (condition to interact) + GO_FLAG_TRANSPORT = 0x08, //any kind of transport? Object can transport (elevator, boat, car) + GO_FLAG_UNK1 = 0x10, // + GO_FLAG_NODESPAWN = 0x20, //never despawn, typically for doors, they just change state + GO_FLAG_TRIGGERED = 0x40, //typically, summoned objects. Triggered by spell or other events +}; + +enum TextEmotes +{ + TEXTEMOTE_AGREE = 1, + TEXTEMOTE_AMAZE = 2, + TEXTEMOTE_ANGRY = 3, + TEXTEMOTE_APOLOGIZE = 4, + TEXTEMOTE_APPLAUD = 5, + TEXTEMOTE_BASHFUL = 6, + TEXTEMOTE_BECKON = 7, + TEXTEMOTE_BEG = 8, + TEXTEMOTE_BITE = 9, + TEXTEMOTE_BLEED = 10, + TEXTEMOTE_BLINK = 11, + TEXTEMOTE_BLUSH = 12, + TEXTEMOTE_BONK = 13, + TEXTEMOTE_BORED = 14, + TEXTEMOTE_BOUNCE = 15, + TEXTEMOTE_BRB = 16, + TEXTEMOTE_BOW = 17, + TEXTEMOTE_BURP = 18, + TEXTEMOTE_BYE = 19, + TEXTEMOTE_CACKLE = 20, + TEXTEMOTE_CHEER = 21, + TEXTEMOTE_CHICKEN = 22, + TEXTEMOTE_CHUCKLE = 23, + TEXTEMOTE_CLAP = 24, + TEXTEMOTE_CONFUSED = 25, + TEXTEMOTE_CONGRATULATE = 26, + TEXTEMOTE_COUGH = 27, + TEXTEMOTE_COWER = 28, + TEXTEMOTE_CRACK = 29, + TEXTEMOTE_CRINGE = 30, + TEXTEMOTE_CRY = 31, + TEXTEMOTE_CURIOUS = 32, + TEXTEMOTE_CURTSEY = 33, + TEXTEMOTE_DANCE = 34, + TEXTEMOTE_DRINK = 35, + TEXTEMOTE_DROOL = 36, + TEXTEMOTE_EAT = 37, + TEXTEMOTE_EYE = 38, + TEXTEMOTE_FART = 39, + TEXTEMOTE_FIDGET = 40, + TEXTEMOTE_FLEX = 41, + TEXTEMOTE_FROWN = 42, + TEXTEMOTE_GASP = 43, + TEXTEMOTE_GAZE = 44, + TEXTEMOTE_GIGGLE = 45, + TEXTEMOTE_GLARE = 46, + TEXTEMOTE_GLOAT = 47, + TEXTEMOTE_GREET = 48, + TEXTEMOTE_GRIN = 49, + TEXTEMOTE_GROAN = 50, + TEXTEMOTE_GROVEL = 51, + TEXTEMOTE_GUFFAW = 52, + TEXTEMOTE_HAIL = 53, + TEXTEMOTE_HAPPY = 54, + TEXTEMOTE_HELLO = 55, + TEXTEMOTE_HUG = 56, + TEXTEMOTE_HUNGRY = 57, + TEXTEMOTE_KISS = 58, + TEXTEMOTE_KNEEL = 59, + TEXTEMOTE_LAUGH = 60, + TEXTEMOTE_LAYDOWN = 61, + TEXTEMOTE_MESSAGE = 62, + TEXTEMOTE_MOAN = 63, + TEXTEMOTE_MOON = 64, + TEXTEMOTE_MOURN = 65, + TEXTEMOTE_NO = 66, + TEXTEMOTE_NOD = 67, + TEXTEMOTE_NOSEPICK = 68, + TEXTEMOTE_PANIC = 69, + TEXTEMOTE_PEER = 70, + TEXTEMOTE_PLEAD = 71, + TEXTEMOTE_POINT = 72, + TEXTEMOTE_POKE = 73, + TEXTEMOTE_PRAY = 74, + TEXTEMOTE_ROAR = 75, + TEXTEMOTE_ROFL = 76, + TEXTEMOTE_RUDE = 77, + TEXTEMOTE_SALUTE = 78, + TEXTEMOTE_SCRATCH = 79, + TEXTEMOTE_SEXY = 80, + TEXTEMOTE_SHAKE = 81, + TEXTEMOTE_SHOUT = 82, + TEXTEMOTE_SHRUG = 83, + TEXTEMOTE_SHY = 84, + TEXTEMOTE_SIGH = 85, + TEXTEMOTE_SIT = 86, + TEXTEMOTE_SLEEP = 87, + TEXTEMOTE_SNARL = 88, + TEXTEMOTE_SPIT = 89, + TEXTEMOTE_STARE = 90, + TEXTEMOTE_SURPRISED = 91, + TEXTEMOTE_SURRENDER = 92, + TEXTEMOTE_TALK = 93, + TEXTEMOTE_TALKEX = 94, + TEXTEMOTE_TALKQ = 95, + TEXTEMOTE_TAP = 96, + TEXTEMOTE_THANK = 97, + TEXTEMOTE_THREATEN = 98, + TEXTEMOTE_TIRED = 99, + TEXTEMOTE_VICTORY = 100, + TEXTEMOTE_WAVE = 101, + TEXTEMOTE_WELCOME = 102, + TEXTEMOTE_WHINE = 103, + TEXTEMOTE_WHISTLE = 104, + TEXTEMOTE_WORK = 105, + TEXTEMOTE_YAWN = 106, + TEXTEMOTE_BOGGLE = 107, + TEXTEMOTE_CALM = 108, + TEXTEMOTE_COLD = 109, + TEXTEMOTE_COMFORT = 110, + TEXTEMOTE_CUDDLE = 111, + TEXTEMOTE_DUCK = 112, + TEXTEMOTE_INSULT = 113, + TEXTEMOTE_INTRODUCE = 114, + TEXTEMOTE_JK = 115, + TEXTEMOTE_LICK = 116, + TEXTEMOTE_LISTEN = 117, + TEXTEMOTE_LOST = 118, + TEXTEMOTE_MOCK = 119, + TEXTEMOTE_PONDER = 120, + TEXTEMOTE_POUNCE = 121, + TEXTEMOTE_PRAISE = 122, + TEXTEMOTE_PURR = 123, + TEXTEMOTE_PUZZLE = 124, + TEXTEMOTE_RAISE = 125, + TEXTEMOTE_READY = 126, + TEXTEMOTE_SHIMMY = 127, + TEXTEMOTE_SHIVER = 128, + TEXTEMOTE_SHOO = 129, + TEXTEMOTE_SLAP = 130, + TEXTEMOTE_SMIRK = 131, + TEXTEMOTE_SNIFF = 132, + TEXTEMOTE_SNUB = 133, + TEXTEMOTE_SOOTHE = 134, + TEXTEMOTE_STINK = 135, + TEXTEMOTE_TAUNT = 136, + TEXTEMOTE_TEASE = 137, + TEXTEMOTE_THIRSTY = 138, + TEXTEMOTE_VETO = 139, + TEXTEMOTE_SNICKER = 140, + TEXTEMOTE_STAND = 141, + TEXTEMOTE_TICKLE = 142, + TEXTEMOTE_VIOLIN = 143, + TEXTEMOTE_SMILE = 163, + TEXTEMOTE_RASP = 183, + TEXTEMOTE_PITY = 203, + TEXTEMOTE_GROWL = 204, + TEXTEMOTE_BARK = 205, + TEXTEMOTE_SCARED = 223, + TEXTEMOTE_FLOP = 224, + TEXTEMOTE_LOVE = 225, + TEXTEMOTE_MOO = 226, + TEXTEMOTE_OPENFIRE = 327, + TEXTEMOTE_FLIRT = 328, + TEXTEMOTE_JOKE = 329, + TEXTEMOTE_COMMEND = 243, + TEXTEMOTE_WINK = 363, + TEXTEMOTE_PAT = 364, + TEXTEMOTE_SERIOUS = 365, + TEXTEMOTE_MOUNTSPECIAL = 366, + TEXTEMOTE_GOODLUCK = 367, + TEXTEMOTE_BLAME = 368, + TEXTEMOTE_BLANK = 369, + TEXTEMOTE_BRANDISH = 370, + TEXTEMOTE_BREATH = 371, + TEXTEMOTE_DISAGREE = 372, + TEXTEMOTE_DOUBT = 373, + TEXTEMOTE_EMBARRASS = 374, + TEXTEMOTE_ENCOURAGE = 375, + TEXTEMOTE_ENEMY = 376, + TEXTEMOTE_EYEBROW = 377, + TEXTEMOTE_TOAST = 378 +}; + +enum Emote +{ + EMOTE_ONESHOT_NONE = 0, + EMOTE_ONESHOT_TALK = 1, + EMOTE_ONESHOT_BOW = 2, + EMOTE_ONESHOT_WAVE = 3, + EMOTE_ONESHOT_CHEER = 4, + EMOTE_ONESHOT_EXCLAMATION = 5, + EMOTE_ONESHOT_QUESTION = 6, + EMOTE_ONESHOT_EAT = 7, + EMOTE_STATE_DANCE = 10, + EMOTE_ONESHOT_LAUGH = 11, + EMOTE_STATE_SLEEP = 12, + EMOTE_STATE_SIT = 13, + EMOTE_ONESHOT_RUDE = 14, + EMOTE_ONESHOT_ROAR = 15, + EMOTE_ONESHOT_KNEEL = 16, + EMOTE_ONESHOT_KISS = 17, + EMOTE_ONESHOT_CRY = 18, + EMOTE_ONESHOT_CHICKEN = 19, + EMOTE_ONESHOT_BEG = 20, + EMOTE_ONESHOT_APPLAUD = 21, + EMOTE_ONESHOT_SHOUT = 22, + EMOTE_ONESHOT_FLEX = 23, + EMOTE_ONESHOT_SHY = 24, + EMOTE_ONESHOT_POINT = 25, + EMOTE_STATE_STAND = 26, + EMOTE_STATE_READYUNARMED = 27, + EMOTE_STATE_WORK = 28, + EMOTE_STATE_POINT = 29, + EMOTE_STATE_NONE = 30, + EMOTE_ONESHOT_WOUND = 33, + EMOTE_ONESHOT_WOUNDCRITICAL = 34, + EMOTE_ONESHOT_ATTACKUNARMED = 35, + EMOTE_ONESHOT_ATTACK1H = 36, + EMOTE_ONESHOT_ATTACK2HTIGHT = 37, + EMOTE_ONESHOT_ATTACK2HLOOSE = 38, + EMOTE_ONESHOT_PARRYUNARMED = 39, + EMOTE_ONESHOT_PARRYSHIELD = 43, + EMOTE_ONESHOT_READYUNARMED = 44, + EMOTE_ONESHOT_READY1H = 45, + EMOTE_ONESHOT_READYBOW = 48, + EMOTE_ONESHOT_SPELLPRECAST = 50, + EMOTE_ONESHOT_SPELLCAST = 51, + EMOTE_ONESHOT_BATTLEROAR = 53, + EMOTE_ONESHOT_SPECIALATTACK1H = 54, + EMOTE_ONESHOT_KICK = 60, + EMOTE_ONESHOT_ATTACKTHROWN = 61, + EMOTE_STATE_STUN = 64, + EMOTE_STATE_DEAD = 65, + EMOTE_ONESHOT_SALUTE = 66, + EMOTE_STATE_KNEEL = 68, + EMOTE_STATE_USESTANDING = 69, + EMOTE_ONESHOT_WAVE_NOSHEATHE = 70, + EMOTE_ONESHOT_CHEER_NOSHEATHE = 71, + EMOTE_ONESHOT_EAT_NOSHEATHE = 92, + EMOTE_STATE_STUN_NOSHEATHE = 93, + EMOTE_ONESHOT_DANCE = 94, + EMOTE_ONESHOT_SALUTE_NOSHEATH = 113, + EMOTE_STATE_USESTANDING_NOSHEATHE = 133, + EMOTE_ONESHOT_LAUGH_NOSHEATHE = 153, + EMOTE_STATE_WORK_NOSHEATHE = 173, + EMOTE_STATE_SPELLPRECAST = 193, + EMOTE_ONESHOT_READYRIFLE = 213, + EMOTE_STATE_READYRIFLE = 214, + EMOTE_STATE_WORK_NOSHEATHE_MINING = 233, + EMOTE_STATE_WORK_NOSHEATHE_CHOPWOOD= 234, + EMOTE_zzOLDONESHOT_LIFTOFF = 253, + EMOTE_ONESHOT_LIFTOFF = 254, + EMOTE_ONESHOT_YES = 273, + EMOTE_ONESHOT_NO = 274, + EMOTE_ONESHOT_TRAIN = 275, + EMOTE_ONESHOT_LAND = 293, + EMOTE_STATE_AT_EASE = 313, + EMOTE_STATE_READY1H = 333, + EMOTE_STATE_SPELLKNEELSTART = 353, + EMOTE_STATE_SUBMERGED = 373, + EMOTE_ONESHOT_SUBMERGE = 374, + EMOTE_STATE_READY2H = 375, + EMOTE_STATE_READYBOW = 376, + EMOTE_ONESHOT_MOUNTSPECIAL = 377, + EMOTE_STATE_TALK = 378, + EMOTE_STATE_FISHING = 379, + EMOTE_ONESHOT_FISHING = 380, + EMOTE_ONESHOT_LOOT = 381, + EMOTE_STATE_WHIRLWIND = 382, + EMOTE_STATE_DROWNED = 383, + EMOTE_STATE_HOLD_BOW = 384, + EMOTE_STATE_HOLD_RIFLE = 385, + EMOTE_STATE_HOLD_THROWN = 386, + EMOTE_ONESHOT_DROWN = 387, + EMOTE_ONESHOT_STOMP = 388, + EMOTE_ONESHOT_ATTACKOFF = 389, + EMOTE_ONESHOT_ATTACKOFFPIERCE = 390, + EMOTE_STATE_ROAR = 391, + EMOTE_STATE_LAUGH = 392, + EMOTE_ONESHOT_CREATURE_SPECIAL = 393, + EMOTE_ONESHOT_JUMPLANDRUN = 394, + EMOTE_ONESHOT_JUMPEND = 395, + EMOTE_ONESHOT_TALK_NOSHEATHE = 396, + EMOTE_ONESHOT_POINT_NOSHEATHE = 397, + EMOTE_STATE_CANNIBALIZE = 398, + EMOTE_ONESHOT_JUMPSTART = 399, + EMOTE_STATE_DANCESPECIAL = 400, + EMOTE_ONESHOT_DANCESPECIAL = 401, + EMOTE_ONESHOT_CUSTOMSPELL01 = 402, + EMOTE_ONESHOT_CUSTOMSPELL02 = 403, + EMOTE_ONESHOT_CUSTOMSPELL03 = 404, + EMOTE_ONESHOT_CUSTOMSPELL04 = 405, + EMOTE_ONESHOT_CUSTOMSPELL05 = 406, + EMOTE_ONESHOT_CUSTOMSPELL06 = 407, + EMOTE_ONESHOT_CUSTOMSPELL07 = 408, + EMOTE_ONESHOT_CUSTOMSPELL08 = 409, + EMOTE_ONESHOT_CUSTOMSPELL09 = 410, + EMOTE_ONESHOT_CUSTOMSPELL10 = 411, + EMOTE_STATE_EXCLAIM = 412, + EMOTE_STATE_SIT_CHAIR_MED = 415, + EMOTE_STATE_SPELLEFFECT_HOLD = 422 +}; + +enum Anim +{ + ANIM_STAND = 0x0, + ANIM_DEATH = 0x1, + ANIM_SPELL = 0x2, + ANIM_STOP = 0x3, + ANIM_WALK = 0x4, + ANIM_RUN = 0x5, + ANIM_DEAD = 0x6, + ANIM_RISE = 0x7, + ANIM_STANDWOUND = 0x8, + ANIM_COMBATWOUND = 0x9, + ANIM_COMBATCRITICAL = 0xA, + ANIM_SHUFFLE_LEFT = 0xB, + ANIM_SHUFFLE_RIGHT = 0xC, + ANIM_WALK_BACKWARDS = 0xD, + ANIM_STUN = 0xE, + ANIM_HANDS_CLOSED = 0xF, + ANIM_ATTACKUNARMED = 0x10, + ANIM_ATTACK1H = 0x11, + ANIM_ATTACK2HTIGHT = 0x12, + ANIM_ATTACK2HLOOSE = 0x13, + ANIM_PARRYUNARMED = 0x14, + ANIM_PARRY1H = 0x15, + ANIM_PARRY2HTIGHT = 0x16, + ANIM_PARRY2HLOOSE = 0x17, + ANIM_PARRYSHIELD = 0x18, + ANIM_READYUNARMED = 0x19, + ANIM_READY1H = 0x1A, + ANIM_READY2HTIGHT = 0x1B, + ANIM_READY2HLOOSE = 0x1C, + ANIM_READYBOW = 0x1D, + ANIM_DODGE = 0x1E, + ANIM_SPELLPRECAST = 0x1F, + ANIM_SPELLCAST = 0x20, + ANIM_SPELLCASTAREA = 0x21, + ANIM_NPCWELCOME = 0x22, + ANIM_NPCGOODBYE = 0x23, + ANIM_BLOCK = 0x24, + ANIM_JUMPSTART = 0x25, + ANIM_JUMP = 0x26, + ANIM_JUMPEND = 0x27, + ANIM_FALL = 0x28, + ANIM_SWIMIDLE = 0x29, + ANIM_SWIM = 0x2A, + ANIM_SWIM_LEFT = 0x2B, + ANIM_SWIM_RIGHT = 0x2C, + ANIM_SWIM_BACKWARDS = 0x2D, + ANIM_ATTACKBOW = 0x2E, + ANIM_FIREBOW = 0x2F, + ANIM_READYRIFLE = 0x30, + ANIM_ATTACKRIFLE = 0x31, + ANIM_LOOT = 0x32, + ANIM_SPELL_PRECAST_DIRECTED = 0x33, + ANIM_SPELL_PRECAST_OMNI = 0x34, + ANIM_SPELL_CAST_DIRECTED = 0x35, + ANIM_SPELL_CAST_OMNI = 0x36, + ANIM_SPELL_BATTLEROAR = 0x37, + ANIM_SPELL_READYABILITY = 0x38, + ANIM_SPELL_SPECIAL1H = 0x39, + ANIM_SPELL_SPECIAL2H = 0x3A, + ANIM_SPELL_SHIELDBASH = 0x3B, + ANIM_EMOTE_TALK = 0x3C, + ANIM_EMOTE_EAT = 0x3D, + ANIM_EMOTE_WORK = 0x3E, + ANIM_EMOTE_USE_STANDING = 0x3F, + ANIM_EMOTE_EXCLAMATION = 0x40, + ANIM_EMOTE_QUESTION = 0x41, + ANIM_EMOTE_BOW = 0x42, + ANIM_EMOTE_WAVE = 0x43, + ANIM_EMOTE_CHEER = 0x44, + ANIM_EMOTE_DANCE = 0x45, + ANIM_EMOTE_LAUGH = 0x46, + ANIM_EMOTE_SLEEP = 0x47, + ANIM_EMOTE_SIT_GROUND = 0x48, + ANIM_EMOTE_RUDE = 0x49, + ANIM_EMOTE_ROAR = 0x4A, + ANIM_EMOTE_KNEEL = 0x4B, + ANIM_EMOTE_KISS = 0x4C, + ANIM_EMOTE_CRY = 0x4D, + ANIM_EMOTE_CHICKEN = 0x4E, + ANIM_EMOTE_BEG = 0x4F, + ANIM_EMOTE_APPLAUD = 0x50, + ANIM_EMOTE_SHOUT = 0x51, + ANIM_EMOTE_FLEX = 0x52, + ANIM_EMOTE_SHY = 0x53, + ANIM_EMOTE_POINT = 0x54, + ANIM_ATTACK1HPIERCE = 0x55, + ANIM_ATTACK2HLOOSEPIERCE = 0x56, + ANIM_ATTACKOFF = 0x57, + ANIM_ATTACKOFFPIERCE = 0x58, + ANIM_SHEATHE = 0x59, + ANIM_HIPSHEATHE = 0x5A, + ANIM_MOUNT = 0x5B, + ANIM_RUN_LEANRIGHT = 0x5C, + ANIM_RUN_LEANLEFT = 0x5D, + ANIM_MOUNT_SPECIAL = 0x5E, + ANIM_KICK = 0x5F, + ANIM_SITDOWN = 0x60, + ANIM_SITTING = 0x61, + ANIM_SITUP = 0x62, + ANIM_SLEEPDOWN = 0x63, + ANIM_SLEEPING = 0x64, + ANIM_SLEEPUP = 0x65, + ANIM_SITCHAIRLOW = 0x66, + ANIM_SITCHAIRMEDIUM = 0x67, + ANIM_SITCHAIRHIGH = 0x68, + ANIM_LOADBOW = 0x69, + ANIM_LOADRIFLE = 0x6A, + ANIM_ATTACKTHROWN = 0x6B, + ANIM_READYTHROWN = 0x6C, + ANIM_HOLDBOW = 0x6D, + ANIM_HOLDRIFLE = 0x6E, + ANIM_HOLDTHROWN = 0x6F, + ANIM_LOADTHROWN = 0x70, + ANIM_EMOTE_SALUTE = 0x71, + ANIM_KNEELDOWN = 0x72, + ANIM_KNEELING = 0x73, + ANIM_KNEELUP = 0x74, + ANIM_ATTACKUNARMEDOFF = 0x75, + ANIM_SPECIALUNARMED = 0x76, + ANIM_STEALTHWALK = 0x77, + ANIM_STEALTHSTAND = 0x78, + ANIM_KNOCKDOWN = 0x79, + ANIM_EATING = 0x7A, + ANIM_USESTANDINGLOOP = 0x7B, + ANIM_CHANNELCASTDIRECTED = 0x7C, + ANIM_CHANNELCASTOMNI = 0x7D, + ANIM_WHIRLWIND = 0x7E, + ANIM_BIRTH = 0x7F, + ANIM_USESTANDINGSTART = 0x80, + ANIM_USESTANDINGEND = 0x81, + ANIM_HOWL = 0x82, + ANIM_DROWN = 0x83, + ANIM_DROWNED = 0x84, + ANIM_FISHINGCAST = 0x85, + ANIM_FISHINGLOOP = 0x86, + ANIM_FLY = 0x87, + ANIM_EMOTE_WORK_NO_SHEATHE = 0x88, + ANIM_EMOTE_STUN_NO_SHEATHE = 0x89, + ANIM_EMOTE_USE_STANDING_NO_SHEATHE= 0x8A, + ANIM_SPELL_SLEEP_DOWN = 0x8B, + ANIM_SPELL_KNEEL_START = 0x8C, + ANIM_SPELL_KNEEL_LOOP = 0x8D, + ANIM_SPELL_KNEEL_END = 0x8E, + ANIM_SPRINT = 0x8F, + ANIM_IN_FIGHT = 0x90, + + ANIM_GAMEOBJ_SPAWN = 145, + ANIM_GAMEOBJ_CLOSE = 146, + ANIM_GAMEOBJ_CLOSED = 147, + ANIM_GAMEOBJ_OPEN = 148, + ANIM_GAMEOBJ_OPENED = 149, + ANIM_GAMEOBJ_DESTROY = 150, + ANIM_GAMEOBJ_DESTROYED = 151, + ANIM_GAMEOBJ_REBUILD = 152, + ANIM_GAMEOBJ_CUSTOM0 = 153, + ANIM_GAMEOBJ_CUSTOM1 = 154, + ANIM_GAMEOBJ_CUSTOM2 = 155, + ANIM_GAMEOBJ_CUSTOM3 = 156, + ANIM_GAMEOBJ_DESPAWN = 157, + ANIM_HOLD = 158, + ANIM_DECAY = 159, + ANIM_BOWPULL = 160, + ANIM_BOWRELEASE = 161, + ANIM_SHIPSTART = 162, + ANIM_SHIPMOVEING = 163, + ANIM_SHIPSTOP = 164, + ANIM_GROUPARROW = 165, + ANIM_ARROW = 166, + ANIM_CORPSEARROW = 167, + ANIM_GUIDEARROW = 168, + ANIM_SWAY = 169, + ANIM_DRUIDCATPOUNCE = 170, + ANIM_DRUIDCATRIP = 171, + ANIM_DRUIDCATRAKE = 172, + ANIM_DRUIDCATRAVAGE = 173, + ANIM_DRUIDCATCLAW = 174, + ANIM_DRUIDCATCOWER = 175, + ANIM_DRUIDBEARSWIPE = 176, + ANIM_DRUIDBEARBITE = 177, + ANIM_DRUIDBEARMAUL = 178, + ANIM_DRUIDBEARBASH = 179, + ANIM_DRAGONTAIL = 180, + ANIM_DRAGONSTOMP = 181, + ANIM_DRAGONSPIT = 182, + ANIM_DRAGONSPITHOVER = 183, + ANIM_DRAGONSPITFLY = 184, + ANIM_EMOTEYES = 185, + ANIM_EMOTENO = 186, + ANIM_JUMPLANDRUN = 187, + ANIM_LOOTHOLD = 188, + ANIM_LOOTUP = 189, + ANIM_STANDHIGH = 190, + ANIM_IMPACT = 191, + ANIM_LIFTOFF = 192, + ANIM_HOVER = 193, + ANIM_SUCCUBUSENTICE = 194, + ANIM_EMOTETRAIN = 195, + ANIM_EMOTEDEAD = 196, + ANIM_EMOTEDANCEONCE = 197, + ANIM_DEFLECT = 198, + ANIM_EMOTEEATNOSHEATHE = 199, + ANIM_LAND = 200, + ANIM_SUBMERGE = 201, + ANIM_SUBMERGED = 202, + ANIM_CANNIBALIZE = 203, + ANIM_ARROWBIRTH = 204, + ANIM_GROURARROWBIRTH = 205, + ANIM_CORPSEARROWBIRTH = 206, + ANIM_GUIDEARROWBIRTH = 207, + ANIM_EMOTETALKNOSHEATHE = 208, + ANIM_EMOTEPOINTNOSHEATHE = 209, + ANIM_EMOTESALUTENOSHEATHE = 210, + ANIM_EMOTEDANCESPECIAL = 211, + ANIM_MUTILATE = 212, + ANIM_CUSTOMSPELL01 = 213, + ANIM_CUSTOMSPELL02 = 214, + ANIM_CUSTOMSPELL03 = 215, + ANIM_CUSTOMSPELL04 = 216, + ANIM_CUSTOMSPELL05 = 217, + ANIM_CUSTOMSPELL06 = 218, + ANIM_CUSTOMSPELL07 = 219, + ANIM_CUSTOMSPELL08 = 220, + ANIM_CUSTOMSPELL09 = 221, + ANIM_CUSTOMSPELL10 = 222, + ANIM_StealthRun = 223 +}; + +enum LockKeyType +{ + LOCK_KEY_NONE = 0, + LOCK_KEY_ITEM = 1, + LOCK_KEY_SKILL = 2 +}; + +enum LockType +{ + LOCKTYPE_PICKLOCK = 1, + LOCKTYPE_HERBALISM = 2, + LOCKTYPE_MINING = 3, + LOCKTYPE_DISARM_TRAP = 4, + LOCKTYPE_OPEN = 5, + LOCKTYPE_TREASURE = 6, + LOCKTYPE_CALCIFIED_ELVEN_GEMS = 7, + LOCKTYPE_CLOSE = 8, + LOCKTYPE_ARM_TRAP = 9, + LOCKTYPE_QUICK_OPEN = 10, + LOCKTYPE_QUICK_CLOSE = 11, + LOCKTYPE_OPEN_TINKERING = 12, + LOCKTYPE_OPEN_KNEELING = 13, + LOCKTYPE_OPEN_ATTACKING = 14, + LOCKTYPE_GAHZRIDIAN = 15, + LOCKTYPE_BLASTING = 16, + LOCKTYPE_SLOW_OPEN = 17, + LOCKTYPE_SLOW_CLOSE = 18, + LOCKTYPE_FISHING = 19 +}; + +enum TrainerType // this is important type for npcs! +{ + TRAINER_TYPE_CLASS = 0, + TRAINER_TYPE_MOUNTS = 1, // on blizz it's 2 + TRAINER_TYPE_TRADESKILLS = 2, + TRAINER_TYPE_PETS = 3 +}; + +#define MAX_TRAINER_TYPE 4 + +enum CreatureType +{ + CREATURE_TYPE_BEAST = 1, + CREATURE_TYPE_DRAGONKIN = 2, + CREATURE_TYPE_DEMON = 3, + CREATURE_TYPE_ELEMENTAL = 4, + CREATURE_TYPE_GIANT = 5, + CREATURE_TYPE_UNDEAD = 6, + CREATURE_TYPE_HUMANOID = 7, + CREATURE_TYPE_CRITTER = 8, + CREATURE_TYPE_MECHANICAL = 9, + CREATURE_TYPE_NOT_SPECIFIED = 10, + CREATURE_TYPE_TOTEM = 11, + CREATURE_TYPE_NON_COMBAT_PET = 12, + CREATURE_TYPE_GAS_CLOUD = 13 +}; + +uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1)); + +enum CreatureFamily +{ + CREATURE_FAMILY_WOLF = 1, + CREATURE_FAMILY_CAT = 2, + CREATURE_FAMILY_SPIDER = 3, + CREATURE_FAMILY_BEAR = 4, + CREATURE_FAMILY_BOAR = 5, + CREATURE_FAMILY_CROCILISK = 6, + CREATURE_FAMILY_CARRION_BIRD = 7, + CREATURE_FAMILY_CRAB = 8, + CREATURE_FAMILY_GORILLA = 9, + CREATURE_FAMILY_RAPTOR = 11, + CREATURE_FAMILY_TALLSTRIDER = 12, + CREATURE_FAMILY_FELHUNTER = 15, + CREATURE_FAMILY_VOIDWALKER = 16, + CREATURE_FAMILY_SUCCUBUS = 17, + CREATURE_FAMILY_DOOMGUARD = 19, + CREATURE_FAMILY_SCORPID = 20, + CREATURE_FAMILY_TURTLE = 21, + CREATURE_FAMILY_IMP = 23, + CREATURE_FAMILY_BAT = 24, + CREATURE_FAMILY_HYENA = 25, + CREATURE_FAMILY_OWL = 26, + CREATURE_FAMILY_WIND_SERPENT = 27, + CREATURE_FAMILY_REMOTE_CONTROL = 28, + CREATURE_FAMILY_FELGUARD = 29, + CREATURE_FAMILY_DRAGONHAWK = 30, + CREATURE_FAMILY_RAVAGER = 31, + CREATURE_FAMILY_WARP_STALKER = 32, + CREATURE_FAMILY_SPOREBAT = 33, + CREATURE_FAMILY_NETHER_RAY = 34, + CREATURE_FAMILY_SERPENT = 35, + CREATURE_FAMILY_SEA_LION = 36 +}; + +enum CreatureEliteType +{ + CREATURE_ELITE_NORMAL = 0, + CREATURE_ELITE_ELITE = 1, + CREATURE_ELITE_RAREELITE = 2, + CREATURE_ELITE_WORLDBOSS = 3, + CREATURE_ELITE_RARE = 4, + CREATURE_UNKNOWN = 5 // found in 2.2.3 for 2 mobs +}; + +// values based at QuestInfo.dbc +enum QuestTypes +{ + QUEST_TYPE_ELITE = 1, + QUEST_TYPE_LIFE = 21, + QUEST_TYPE_PVP = 41, + QUEST_TYPE_RAID = 62, + QUEST_TYPE_DUNGEON = 81, + QUEST_TYPE_WORLD_EVENT = 82, + QUEST_TYPE_LEGENDARY = 83, + QUEST_TYPE_ESCORT = 84, + QUEST_TYPE_HEROIC = 85, +}; + +// values based at QuestSort.dbc +enum QuestSort +{ + QUEST_SORT_EPIC = 1, + QUEST_SORT_WAILING_CAVERNS_OLD = 21, + QUEST_SORT_SEASONAL = 22, + QUEST_SORT_UNDERCITY_OLD = 23, + QUEST_SORT_HERBALISM = 24, + QUEST_SORT_SCARLET_MONASTERY_OLD= 25, + QUEST_SORT_ULDAMN_OLD = 41, + QUEST_SORT_WARLOCK = 61, + QUEST_SORT_WARRIOR = 81, + QUEST_SORT_SHAMAN = 82, + QUEST_SORT_FISHING = 101, + QUEST_SORT_BLACKSMITHING = 121, + QUEST_SORT_PALADIN = 141, + QUEST_SORT_MAGE = 161, + QUEST_SORT_ROGUE = 162, + QUEST_SORT_ALCHEMY = 181, + QUEST_SORT_LEATHERWORKING = 182, + QUEST_SORT_ENGINERING = 201, + QUEST_SORT_TREASURE_MAP = 221, + QUEST_SORT_SUNKEN_TEMPLE_OLD = 241, + QUEST_SORT_HUNTER = 261, + QUEST_SORT_PRIEST = 262, + QUEST_SORT_DRUID = 263, + QUEST_SORT_TAILORING = 264, + QUEST_SORT_SPECIAL = 284, + QUEST_SORT_COOKING = 304, + QUEST_SORT_FIRST_AID = 324, + QUEST_SORT_LEGENDARY = 344, + QUEST_SORT_DARKMOON_FAIRE = 364, + QUEST_SORT_AHN_QIRAJ_WAR = 365, + QUEST_SORT_LUNAR_FESTIVAL = 366, + QUEST_SORT_REPUTATION = 367, + QUEST_SORT_INVASION = 368, + QUEST_SORT_MIDSUMMER = 369, + QUEST_SORT_BREWFEST = 370 +}; + +inline uint8 ClassByQuestSort(int32 QuestSort) +{ + switch(QuestSort) + { + case QUEST_SORT_WARLOCK: return CLASS_WARLOCK; + case QUEST_SORT_WARRIOR: return CLASS_WARRIOR; + case QUEST_SORT_SHAMAN: return CLASS_SHAMAN; + case QUEST_SORT_PALADIN: return CLASS_PALADIN; + case QUEST_SORT_MAGE: return CLASS_MAGE; + case QUEST_SORT_ROGUE: return CLASS_ROGUE; + case QUEST_SORT_HUNTER: return CLASS_HUNTER; + case QUEST_SORT_PRIEST: return CLASS_PRIEST; + case QUEST_SORT_DRUID: return CLASS_DRUID; + } + return 0; +} + +enum SkillType +{ + SKILL_FROST = 6, + SKILL_FIRE = 8, + SKILL_ARMS = 26, + SKILL_COMBAT = 38, + SKILL_SUBTLETY = 39, + SKILL_POISONS = 40, + SKILL_SWORDS = 43, + SKILL_AXES = 44, + SKILL_BOWS = 45, + SKILL_GUNS = 46, + SKILL_BEAST_MASTERY = 50, + SKILL_SURVIVAL = 51, + SKILL_MACES = 54, + SKILL_HOLY = 56, + SKILL_2H_SWORDS = 55, + SKILL_SHADOW = 78, + SKILL_DEFENSE = 95, + SKILL_LANG_COMMON = 98, + SKILL_RACIAL_DWARVEN = 101, + SKILL_LANG_ORCISH = 109, + SKILL_LANG_DWARVEN = 111, + SKILL_LANG_DARNASSIAN = 113, + SKILL_LANG_TAURAHE = 115, + SKILL_DUAL_WIELD = 118, + SKILL_RACIAL_TAUREN = 124, + SKILL_ORC_RACIAL = 125, + SKILL_RACIAL_NIGHT_ELF = 126, + SKILL_FIRST_AID = 129, + SKILL_FERAL_COMBAT = 134, + SKILL_STAVES = 136, + SKILL_LANG_THALASSIAN = 137, + SKILL_LANG_DRACONIC = 138, + SKILL_LANG_DEMON_TONGUE = 139, + SKILL_LANG_TITAN = 140, + SKILL_LANG_OLD_TONGUE = 141, + SKILL_SURVIVAL2 = 142, + SKILL_RIDING_HORSE = 148, + SKILL_RIDING_WOLF = 149, + SKILL_RIDING_RAM = 152, + SKILL_RIDING_TIGER = 150, + SKILL_SWIMING = 155, + SKILL_2H_MACES = 160, + SKILL_UNARMED = 162, + SKILL_MARKSMANSHIP = 163, + SKILL_BLACKSMITHING = 164, + SKILL_LEATHERWORKING = 165, + SKILL_ALCHEMY = 171, + SKILL_2H_AXES = 172, + SKILL_DAGGERS = 173, + SKILL_THROWN = 176, + SKILL_HERBALISM = 182, + SKILL_GENERIC_DND = 183, + SKILL_RETRIBUTION = 184, + SKILL_COOKING = 185, + SKILL_MINING = 186, + SKILL_PET_IMP = 188, + SKILL_PET_FELHUNTER = 189, + SKILL_TAILORING = 197, + SKILL_ENGINERING = 202, + SKILL_PET_SPIDER = 203, + SKILL_PET_VOIDWALKER = 204, + SKILL_PET_SUCCUBUS = 205, + SKILL_PET_INFERNAL = 206, + SKILL_PET_DOOMGUARD = 207, + SKILL_PET_WOLF = 208, + SKILL_PET_CAT = 209, + SKILL_PET_BEAR = 210, + SKILL_PET_BOAR = 211, + SKILL_PET_CROCILISK = 212, + SKILL_PET_CARRION_BIRD = 213, + SKILL_PET_GORILLA = 215, + SKILL_PET_CRAB = 214, + SKILL_PET_RAPTOR = 217, + SKILL_PET_TALLSTRIDER = 218, + SKILL_RACIAL_UNDED = 220, + SKILL_WEAPON_TALENTS = 222, + SKILL_CROSSBOWS = 226, + SKILL_SPEARS = 227, + SKILL_WANDS = 228, + SKILL_POLEARMS = 229, + SKILL_PET_SCORPID = 236, + SKILL_ARCANE = 237, + SKILL_OPEN_LOCK = 242, + SKILL_PET_TURTLE = 251, + SKILL_ASSASSINATION = 253, + SKILL_FURY = 256, + SKILL_PROTECTION = 257, + SKILL_BEAST_TRAINING = 261, + SKILL_PROTECTION2 = 267, + SKILL_PET_TALENTS = 270, + SKILL_PLATE_MAIL = 293, + SKILL_LANG_GNOMISH = 313, + SKILL_LANG_TROLL = 315, + SKILL_ENCHANTING = 333, + SKILL_DEMONOLOGY = 354, + SKILL_AFFLICTION = 355, + SKILL_FISHING = 356, + SKILL_ENHANCEMENT = 373, + SKILL_RESTORATION = 374, + SKILL_ELEMENTAL_COMBAT = 375, + SKILL_SKINNING = 393, + SKILL_MAIL = 413, + SKILL_LEATHER = 414, + SKILL_CLOTH = 415, + SKILL_SHIELD = 433, + SKILL_FIST_WEAPONS = 473, + SKILL_RIDING_RAPTOR = 533, + SKILL_RIDING_MECHANOSTRIDER = 553, + SKILL_RIDING_UNDEAD_HORSE = 554, + SKILL_RESTORATION2 = 573, + SKILL_BALANCE = 574, + SKILL_DESTRUCTION = 593, + SKILL_HOLY2 = 594, + SKILL_DISCIPLINE = 613, + SKILL_LOCKPICKING = 633, + SKILL_PET_BAT = 653, + SKILL_PET_HYENA = 654, + SKILL_PET_OWL = 655, + SKILL_PET_WIND_SERPENT = 656, + SKILL_LANG_GUTTERSPEAK = 673, + SKILL_RIDING_KODO = 713, + SKILL_RACIAL_TROLL = 733, + SKILL_RACIAL_GNOME = 753, + SKILL_RACIAL_HUMAN = 754, + SKILL_JEWELCRAFTING = 755, + SKILL_RACIAL_BLOODELF = 756, + SKILL_PET_EVENT_RC = 758, + SKILL_LANG_DRAENEI = 759, + SKILL_RACIAL_DRAENEI = 760, + SKILL_PET_FELGUARD = 761, + SKILL_RIDING = 762, + SKILL_PET_DRAGONHAWK = 763, + SKILL_PET_NETHER_RAY = 764, + SKILL_PET_SPOREBAT = 765, + SKILL_PET_WARP_STALKER = 766, + SKILL_PET_RAVAGER = 767, + SKILL_PET_SERPENT = 768, + SKILL_INTERNAL = 769 +}; + +#define MAX_SKILL_TYPE 770 + +inline uint32 SkillByQuestSort(int32 QuestSort) +{ + switch(QuestSort) + { + case QUEST_SORT_HERBALISM: return SKILL_HERBALISM; + case QUEST_SORT_FISHING: return SKILL_FISHING; + case QUEST_SORT_BLACKSMITHING: return SKILL_BLACKSMITHING; + case QUEST_SORT_ALCHEMY: return SKILL_ALCHEMY; + case QUEST_SORT_LEATHERWORKING: return SKILL_LEATHERWORKING; + case QUEST_SORT_ENGINERING: return SKILL_ENGINERING; + case QUEST_SORT_TAILORING: return SKILL_TAILORING; + case QUEST_SORT_COOKING: return SKILL_COOKING; + case QUEST_SORT_FIRST_AID: return SKILL_FIRST_AID; + } + return 0; +} + +enum SkillCategory +{ + SKILL_CATEGORY_ATTRIBUTES = 5, + SKILL_CATEGORY_WEAPON = 6, + SKILL_CATEGORY_CLASS = 7, + SKILL_CATEGORY_ARMOR = 8, + SKILL_CATEGORY_SECONDARY = 9, // secondary professions + SKILL_CATEGORY_LANGUAGES = 10, + SKILL_CATEGORY_PROFESSION = 11, // primary professions + SKILL_CATEGORY_NOT_DISPLAYED = 12 +}; + +enum TotemCategory +{ + TC_SKINNING_SKIFE = 1, + TC_EARTH_TOTEM = 2, + TC_AIR_TOTEM = 3, + TC_FIRE_TOTEM = 4, + TC_WATER_TOTEM = 5, + TC_COPPER_ROD = 6, + TC_SILVER_ROD = 7, + TC_GOLDEN_ROD = 8, + TC_TRUESILVER_ROD = 9, + TC_ARCANITE_ROD = 10, + TC_MINING_PICK = 11, + TC_PHILOSOPHERS_STONE = 12, + TC_BLACKSMITH_HAMMER = 13, + TC_ARCLIGHT_SPANNER = 14, + TC_GYROMATIC_MA = 15, + TC_MASTER_TOTEM = 21, + TC_FEL_IRON_ROD = 41, + TC_ADAMANTITE_ROD = 62, + TC_ETERNIUM_ROD = 63 +}; + +enum UnitDynFlags +{ + UNIT_DYNFLAG_LOOTABLE = 0x0001, + UNIT_DYNFLAG_TRACK_UNIT = 0x0002, + UNIT_DYNFLAG_OTHER_TAGGER = 0x0004, + UNIT_DYNFLAG_ROOTED = 0x0008, + UNIT_DYNFLAG_SPECIALINFO = 0x0010, + UNIT_DYNFLAG_DEAD = 0x0020 +}; + +enum CorpseDynFlags +{ + CORPSE_DYNFLAG_LOOTABLE = 0x0001 +}; + +// Passive Spell codes explicit used in code +#define SPELL_ID_GENERIC_LEARN 483 +#define SPELL_ID_PASSIVE_BATTLE_STANCE 2457 +#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS 15007 + +enum WeatherType +{ + WEATHER_TYPE_FINE = 0, + WEATHER_TYPE_RAIN = 1, + WEATHER_TYPE_SNOW = 2, + WEATHER_TYPE_STORM = 3, + WEATHER_TYPE_THUNDERS = 86, + WEATHER_TYPE_BLACKRAIN = 90 +}; + +#define MAX_WEATHER_TYPE 4 + +enum ChatMsg +{ + CHAT_MSG_ADDON = 0xFFFFFFFF, + CHAT_MSG_SYSTEM = 0x00, + CHAT_MSG_SAY = 0x01, + CHAT_MSG_PARTY = 0x02, + CHAT_MSG_RAID = 0x03, + CHAT_MSG_GUILD = 0x04, + CHAT_MSG_OFFICER = 0x05, + CHAT_MSG_YELL = 0x06, + CHAT_MSG_WHISPER = 0x07, + CHAT_MSG_WHISPER_INFORM = 0x08, + CHAT_MSG_REPLY = 0x09, + CHAT_MSG_EMOTE = 0x0A, + CHAT_MSG_TEXT_EMOTE = 0x0B, + CHAT_MSG_MONSTER_SAY = 0x0C, + CHAT_MSG_MONSTER_PARTY = 0x0D, + CHAT_MSG_MONSTER_YELL = 0x0E, + CHAT_MSG_MONSTER_WHISPER = 0x0F, + CHAT_MSG_MONSTER_EMOTE = 0x10, + CHAT_MSG_CHANNEL = 0x11, + CHAT_MSG_CHANNEL_JOIN = 0x12, + CHAT_MSG_CHANNEL_LEAVE = 0x13, + CHAT_MSG_CHANNEL_LIST = 0x14, + CHAT_MSG_CHANNEL_NOTICE = 0x15, + CHAT_MSG_CHANNEL_NOTICE_USER = 0x16, + CHAT_MSG_AFK = 0x17, + CHAT_MSG_DND = 0x18, + CHAT_MSG_IGNORED = 0x19, + CHAT_MSG_SKILL = 0x1A, + CHAT_MSG_LOOT = 0x1B, + CHAT_MSG_MONEY = 0x1C, + CHAT_MSG_OPENING = 0x1D, + CHAT_MSG_TRADESKILLS = 0x1E, + CHAT_MSG_PET_INFO = 0x1F, + CHAT_MSG_COMBAT_MISC_INFO = 0x20, + CHAT_MSG_COMBAT_XP_GAIN = 0x21, + CHAT_MSG_COMBAT_HONOR_GAIN = 0x22, + CHAT_MSG_COMBAT_FACTION_CHANGE = 0x23, + CHAT_MSG_BG_SYSTEM_NEUTRAL = 0x24, + CHAT_MSG_BG_SYSTEM_ALLIANCE = 0x25, + CHAT_MSG_BG_SYSTEM_HORDE = 0x26, + CHAT_MSG_RAID_LEADER = 0x27, + CHAT_MSG_RAID_WARNING = 0x28, + CHAT_MSG_RAID_BOSS_WHISPER = 0x29, + CHAT_MSG_RAID_BOSS_EMOTE = 0x2A, + CHAT_MSG_FILTERED = 0x2B, + CHAT_MSG_BATTLEGROUND = 0x2C, + CHAT_MSG_BATTLEGROUND_LEADER = 0x2D, + CHAT_MSG_RESTRICTED = 0x2E, +}; + +#define MAX_CHAT_MSG_TYPE 0x2F + +// Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask +enum PetDiet +{ + PET_DIET_MEAT = 1, + PET_DIET_FISH = 2, + PET_DIET_CHEESE = 3, + PET_DIET_BREAD = 4, + PET_DIET_FUNGAS = 5, + PET_DIET_FRUIT = 6, + PET_DIET_RAW_MEAT = 7, + PET_DIET_RAW_FISH = 8 +}; + +#define MAX_PET_DIET 9 + +#define CHAIN_SPELL_JUMP_RADIUS 10 + +// Max values for Guild & Guild Bank +#define GUILD_BANK_MAX_TABS 6 +#define GUILD_BANK_MAX_SLOTS 98 +#define GUILD_BANK_MAX_LOGS 24 +#define GUILD_EVENTLOG_MAX_ENTRIES 100 +#define GUILD_MAX_RANKS 10 + +enum AiReaction +{ + AI_REACTION_UNK1 = 1, + AI_REACTION_AGGRO = 2, + AI_REACTION_UNK3 = 3, + AI_REACTION_UNK4 = 4 +}; + +// Diminishing Returns Types +enum DiminishingReturnsType +{ + DRTYPE_NONE = 0, // this spell is not diminished, but may have limited it's duration to 10s + DRTYPE_PLAYER = 1, // this spell is diminished only when applied on players + DRTYPE_ALL = 2 // this spell is diminished in every case +}; + +// Diminishing Return Groups +enum DiminishingGroup +{ + // Common Groups + DIMINISHING_NONE, + DIMINISHING_CONTROL_STUN, // Player Controlled stuns + DIMINISHING_TRIGGER_STUN, // By aura proced stuns, usualy chance on hit talents + DIMINISHING_SLEEP, + DIMINISHING_CONTROL_ROOT, // Immobilizing effects from casted spells + DIMINISHING_TRIGGER_ROOT, // Immobilizing effects from triggered spells like Frostbite + DIMINISHING_FEAR, // Non-warlock fears + DIMINISHING_CHARM, + // Mage Specific + DIMINISHING_POLYMORPH, + // Rogue Specific + DIMINISHING_KIDNEYSHOT, // Kidney Shot is not diminished with Cheap Shot + // Warlock Specific + DIMINISHING_DEATHCOIL, // Death Coil Diminish only with another Death Coil + DIMINISHING_WARLOCK_FEAR, // Also with Sedduction + // Shared Class Specific + DIMINISHING_BLIND_CYCLONE, // From 2.3.0 + DIMINISHING_DISARM, // From 2.3.0 + DIMINISHING_SILENCE, // From 2.3.0 + DIMINISHING_FREEZE, // Hunter's Freezing Trap + DIMINISHING_KNOCKOUT, // Also with Sap, all Knockout mechanics are here + DIMINISHING_BANISH, + // Other + // Don't Diminish, but limit duration to 10s + DIMINISHING_LIMITONLY +}; + +enum DungeonDifficulties +{ + DIFFICULTY_NORMAL = 0, + DIFFICULTY_HEROIC = 1, + TOTAL_DIFFICULTIES +}; + +enum SummonType +{ + SUMMON_TYPE_CRITTER = 41, + SUMMON_TYPE_GUARDIAN = 61, + SUMMON_TYPE_TOTEM_SLOT1 = 63, + SUMMON_TYPE_WILD = 64, + SUMMON_TYPE_POSESSED = 65, + SUMMON_TYPE_DEMON = 66, + SUMMON_TYPE_SUMMON = 67, + SUMMON_TYPE_TOTEM_SLOT2 = 81, + SUMMON_TYPE_TOTEM_SLOT3 = 82, + SUMMON_TYPE_TOTEM_SLOT4 = 83, + SUMMON_TYPE_TOTEM = 121, + SUMMON_TYPE_UNKNOWN3 = 181, + SUMMON_TYPE_UNKNOWN4 = 187, + SUMMON_TYPE_UNKNOWN1 = 247, + SUMMON_TYPE_CRITTER2 = 407, + SUMMON_TYPE_CRITTER3 = 307, + SUMMON_TYPE_UNKNOWN5 = 409, + SUMMON_TYPE_UNKNOWN2 = 427, + SUMMON_TYPE_POSESSED2 = 428 +}; + +enum ResponseCodes +{ + RESPONSE_SUCCESS = 0x00, + RESPONSE_FAILURE = 0x01, + RESPONSE_CANCELLED = 0x02, + RESPONSE_DISCONNECTED = 0x03, + RESPONSE_FAILED_TO_CONNECT = 0x04, + RESPONSE_CONNECTED = 0x05, + RESPONSE_VERSION_MISMATCH = 0x06, + + CSTATUS_CONNECTING = 0x07, + CSTATUS_NEGOTIATING_SECURITY = 0x08, + CSTATUS_NEGOTIATION_COMPLETE = 0x09, + CSTATUS_NEGOTIATION_FAILED = 0x0A, + CSTATUS_AUTHENTICATING = 0x0B, + + AUTH_OK = 0x0C, + AUTH_FAILED = 0x0D, + AUTH_REJECT = 0x0E, + AUTH_BAD_SERVER_PROOF = 0x0F, + AUTH_UNAVAILABLE = 0x10, + AUTH_SYSTEM_ERROR = 0x11, + AUTH_BILLING_ERROR = 0x12, + AUTH_BILLING_EXPIRED = 0x13, + AUTH_VERSION_MISMATCH = 0x14, + AUTH_UNKNOWN_ACCOUNT = 0x15, + AUTH_INCORRECT_PASSWORD = 0x16, + AUTH_SESSION_EXPIRED = 0x17, + AUTH_SERVER_SHUTTING_DOWN = 0x18, + AUTH_ALREADY_LOGGING_IN = 0x19, + AUTH_LOGIN_SERVER_NOT_FOUND = 0x1A, + AUTH_WAIT_QUEUE = 0x1B, + AUTH_BANNED = 0x1C, + AUTH_ALREADY_ONLINE = 0x1D, + AUTH_NO_TIME = 0x1E, + AUTH_DB_BUSY = 0x1F, + AUTH_SUSPENDED = 0x20, + AUTH_PARENTAL_CONTROL = 0x21, + AUTH_LOCKED_ENFORCED = 0x22, + + REALM_LIST_IN_PROGRESS = 0x23, + REALM_LIST_SUCCESS = 0x24, + REALM_LIST_FAILED = 0x25, + REALM_LIST_INVALID = 0x26, + REALM_LIST_REALM_NOT_FOUND = 0x27, + + ACCOUNT_CREATE_IN_PROGRESS = 0x28, + ACCOUNT_CREATE_SUCCESS = 0x29, + ACCOUNT_CREATE_FAILED = 0x2A, + + CHAR_LIST_RETRIEVING = 0x2B, + CHAR_LIST_RETRIEVED = 0x2C, + CHAR_LIST_FAILED = 0x2D, + + CHAR_CREATE_IN_PROGRESS = 0x2E, + CHAR_CREATE_SUCCESS = 0x2F, + CHAR_CREATE_ERROR = 0x30, + CHAR_CREATE_FAILED = 0x31, + CHAR_CREATE_NAME_IN_USE = 0x32, + CHAR_CREATE_DISABLED = 0x33, + CHAR_CREATE_PVP_TEAMS_VIOLATION = 0x34, + CHAR_CREATE_SERVER_LIMIT = 0x35, + CHAR_CREATE_ACCOUNT_LIMIT = 0x36, + CHAR_CREATE_SERVER_QUEUE = 0x37, + CHAR_CREATE_ONLY_EXISTING = 0x38, + CHAR_CREATE_EXPANSION = 0x39, + + CHAR_DELETE_IN_PROGRESS = 0x3A, + CHAR_DELETE_SUCCESS = 0x3B, + CHAR_DELETE_FAILED = 0x3C, + CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3D, + CHAR_DELETE_FAILED_GUILD_LEADER = 0x3E, + CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x3F, + + CHAR_LOGIN_IN_PROGRESS = 0x40, + CHAR_LOGIN_SUCCESS = 0x41, + CHAR_LOGIN_NO_WORLD = 0x42, + CHAR_LOGIN_DUPLICATE_CHARACTER = 0x43, + CHAR_LOGIN_NO_INSTANCES = 0x44, + CHAR_LOGIN_FAILED = 0x45, + CHAR_LOGIN_DISABLED = 0x46, + CHAR_LOGIN_NO_CHARACTER = 0x47, + CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x48, + CHAR_LOGIN_LOCKED_BY_BILLING = 0x49, + + CHAR_NAME_SUCCESS = 0x4A, + CHAR_NAME_FAILURE = 0x4B, + CHAR_NAME_NO_NAME = 0x4C, + CHAR_NAME_TOO_SHORT = 0x4D, + CHAR_NAME_TOO_LONG = 0x4E, + CHAR_NAME_INVALID_CHARACTER = 0x4F, + CHAR_NAME_MIXED_LANGUAGES = 0x50, + CHAR_NAME_PROFANE = 0x51, + CHAR_NAME_RESERVED = 0x52, + CHAR_NAME_INVALID_APOSTROPHE = 0x53, + CHAR_NAME_MULTIPLE_APOSTROPHES = 0x54, + CHAR_NAME_THREE_CONSECUTIVE = 0x55, + CHAR_NAME_INVALID_SPACE = 0x56, + CHAR_NAME_CONSECUTIVE_SPACES = 0x57, + CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x58, + CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x59, + CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5A, +}; +#endif diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp new file mode 100644 index 000000000..5a1de100f --- /dev/null +++ b/src/game/SkillDiscovery.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "ProgressBar.h" +#include "Policies/SingletonImp.h" +#include "ObjectAccessor.h" +#include "World.h" +#include "Util.h" +#include "SkillDiscovery.h" +#include "SpellMgr.h" +#include + +struct SkillDiscoveryEntry +{ + uint32 spellId; + float chance; + + SkillDiscoveryEntry() + : spellId(0), chance(0) {} + + SkillDiscoveryEntry(uint16 _spellId, float _chance) + : spellId(_spellId), chance(_chance) {} +}; + +typedef std::list SkillDiscoveryList; +typedef HM_NAMESPACE::hash_map SkillDiscoveryMap; + +static SkillDiscoveryMap SkillDiscoveryStore; + +void LoadSkillDiscoveryTable() +{ + + SkillDiscoveryStore.clear(); // need for reload + + uint32 count = 0; + + // 0 1 2 + QueryResult *result = WorldDatabase.PQuery("SELECT spellId, reqSpell, chance FROM skill_discovery_template"); + + if (result) + { + barGoLink bar(result->GetRowCount()); + + std::ostringstream ssNonDiscoverableEntries; + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 spellId = fields[0].GetUInt32(); + int32 reqSkillOrSpell = fields[1].GetInt32(); + float chance = fields[2].GetFloat(); + + if( chance <= 0 ) // chance + { + ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " chance = " << chance << "\n"; + continue; + } + + if(reqSkillOrSpell > 0) // spell case + { + SpellEntry const* spellEntry = sSpellStore.LookupEntry(reqSkillOrSpell); + if( !spellEntry ) + { + sLog.outErrorDb("Spell (ID: %u) have not existed spell (ID: %i) in `reqSpell` field in `skill_discovery_template` table",spellId,reqSkillOrSpell); + continue; + } + + if( spellEntry->Mechanic != MECHANIC_DISCOVERY ) + { + sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc but listed in `skill_discovery_template` table",spellId); + continue; + } + + SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, chance) ); + } + else if( reqSkillOrSpell == 0 ) // skill case + { + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellId); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellId); + + if(lower==upper) + { + sLog.outErrorDb("Spell (ID: %u) not listed in `SkillLineAbility.dbc` but listed with `reqSpell`=0 in `skill_discovery_template` table",spellId); + continue; + } + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, chance) ); + } + } + else + { + sLog.outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table",spellId); + continue; + } + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u skill discovery definitions", count ); + if(!ssNonDiscoverableEntries.str().empty()) + sLog.outErrorDb("Some items can't be successfully discovered: have in chance field value < 0.000001 in `skill_discovery_template` DB table . List:\n%s",ssNonDiscoverableEntries.str().c_str()); + } + else + { + sLog.outString(); + sLog.outString( ">> Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty." ); + } +} + +uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) +{ + // check spell case + SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId); + + if(tab != SkillDiscoveryStore.end()) + { + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + { + if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) + && !player->HasSpell(item_iter->spellId) ) + return item_iter->spellId; + } + + return 0; + } + + // check skill line case + tab = SkillDiscoveryStore.find(-(int32)skillId); + if(tab != SkillDiscoveryStore.end()) + { + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + { + if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) + && !player->HasSpell(item_iter->spellId) ) + return item_iter->spellId; + } + + return 0; + } + + return 0; +} diff --git a/src/game/SkillDiscovery.h b/src/game/SkillDiscovery.h new file mode 100644 index 000000000..651ead552 --- /dev/null +++ b/src/game/SkillDiscovery.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_SKILLDISCOVERY_H +#define MANGOS_SKILLDISCOVERY_H + +#include "Common.h" + +class Player; + +void LoadSkillDiscoveryTable(); +uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player); +#endif diff --git a/src/game/SkillExtraItems.cpp b/src/game/SkillExtraItems.cpp new file mode 100644 index 000000000..c9d5f7e03 --- /dev/null +++ b/src/game/SkillExtraItems.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "SkillExtraItems.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "ProgressBar.h" +#include "Player.h" +#include + +// some type definitions +// no use putting them in the header file, they're only used in this .cpp + +// struct to store information about extra item creation +// one entry for every spell that is able to create an extra item +struct SkillExtraItemEntry +{ + // the spell id of the specialization required to create extra items + uint32 requiredSpecialization; + // the chance to create one additional item + float additionalCreateChance; + // maximum number of extra items created per crafting + uint8 additionalMaxNum; + + SkillExtraItemEntry() + : requiredSpecialization(0), additionalCreateChance(0.0f), additionalMaxNum(0) {} + + SkillExtraItemEntry(uint32 rS, float aCC, uint8 aMN) + : requiredSpecialization(rS), additionalCreateChance(aCC), additionalMaxNum(aMN) {} +}; + +// map to store the extra item creation info, the key is the spellId of the creation spell, the mapped value is the assigned SkillExtraItemEntry +typedef std::map SkillExtraItemMap; + +SkillExtraItemMap SkillExtraItemStore; + +// loads the extra item creation info from DB +void LoadSkillExtraItemTable() +{ + uint32 count = 0; + + SkillExtraItemStore.clear(); // need for reload + + // 0 1 2 3 + QueryResult *result = WorldDatabase.PQuery("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template"); + + if (result) + { + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 spellId = fields[0].GetUInt32(); + + if(!sSpellStore.LookupEntry(spellId)) + { + sLog.outError("Skill specialization %u has non-existent spell id in `skill_extra_item_template`!", spellId); + continue; + } + + uint32 requiredSpecialization = fields[1].GetUInt32(); + if(!sSpellStore.LookupEntry(requiredSpecialization)) + { + sLog.outError("Skill specialization %u have not existed required specialization spell id %u in `skill_extra_item_template`!", spellId,requiredSpecialization); + continue; + } + + float additionalCreateChance = fields[2].GetFloat(); + if(additionalCreateChance <= 0.0f) + { + sLog.outError("Skill specialization %u has too low additional create chance in `skill_extra_item_template`!", spellId); + continue; + } + + uint8 additionalMaxNum = fields[3].GetUInt8(); + if(!additionalMaxNum) + { + sLog.outError("Skill specialization %u has 0 max number of extra items in `skill_extra_item_template`!", spellId); + continue; + } + + SkillExtraItemEntry& skillExtraItemEntry = SkillExtraItemStore[spellId]; + + skillExtraItemEntry.requiredSpecialization = requiredSpecialization; + skillExtraItemEntry.additionalCreateChance = additionalCreateChance; + skillExtraItemEntry.additionalMaxNum = additionalMaxNum; + + ++count; + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell specialization definitions", count ); + } + else + { + sLog.outString(); + sLog.outString( ">> Loaded 0 spell specialization definitions. DB table `skill_extra_item_template` is empty." ); + } +} + +bool canCreateExtraItems(Player * player, uint32 spellId, float &additionalChance, uint8 &additionalMax) +{ + // get the info for the specified spell + SkillExtraItemMap::const_iterator ret = SkillExtraItemStore.find(spellId); + if(ret==SkillExtraItemStore.end()) + return false; + + SkillExtraItemEntry const* specEntry = &ret->second; + + // if no entry, then no extra items can be created + if(!specEntry) + return false; + + // the player doesn't have the required specialization, return false + if(!player->HasSpell(specEntry->requiredSpecialization)) + return false; + + // set the arguments to the appropriate values + additionalChance = specEntry->additionalCreateChance; + additionalMax = specEntry->additionalMaxNum; + + // enable extra item creation + return true; +} diff --git a/src/game/SkillExtraItems.h b/src/game/SkillExtraItems.h new file mode 100644 index 000000000..2afe0ddd2 --- /dev/null +++ b/src/game/SkillExtraItems.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_SKILL_EXTRA_ITEMS_H +#define MANGOS_SKILL_EXTRA_ITEMS_H + +#include "Common.h" + +// predef classes used in functions +class Player; +// returns true and sets the appropriate info if the player can create extra items with the given spellId +bool canCreateExtraItems(Player * player, uint32 spellId, float &additionalChance, uint8 &additionalMax); +// function to load the extra item creation info from DB +void LoadSkillExtraItemTable(); +#endif diff --git a/src/game/SkillHandler.cpp b/src/game/SkillHandler.cpp new file mode 100644 index 000000000..6427a82bc --- /dev/null +++ b/src/game/SkillHandler.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Opcodes.h" +#include "Log.h" +#include "Player.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "ObjectAccessor.h" +#include "UpdateMask.h" +#include "SpellAuras.h" + +void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,4+4); + + uint32 talent_id, requested_rank; + recv_data >> talent_id >> requested_rank; + + uint32 CurTalentPoints = GetPlayer()->GetFreeTalentPoints(); + + if(CurTalentPoints == 0) + return; + + if (requested_rank > 4) + return; + + TalentEntry const *talentInfo = sTalentStore.LookupEntry( talent_id ); + + if(!talentInfo) + return; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + + if(!talentTabInfo) + return; + + Player * player = GetPlayer(); + + // prevent learn talent for different class (cheating) + if( (player->getClassMask() & talentTabInfo->ClassMask) == 0 ) + return; + + // prevent skip talent ranks (cheating) + if(requested_rank > 0 && !player->HasSpell(talentInfo->RankID[requested_rank-1])) + return; + + // Check if it requires another talent + if (talentInfo->DependsOn > 0) + { + if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn)) + { + bool hasEnoughRank = false; + for (int i = talentInfo->DependsOnRank; i <= 4; i++) + { + if (depTalentInfo->RankID[i] != 0) + if (player->HasSpell(depTalentInfo->RankID[i])) + hasEnoughRank = true; + } + if (!hasEnoughRank) + return; + } + } + + // Check if it requires spell + if( talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) ) + return; + + // Find out how many points we have in this field + uint32 spentPoints = 0; + + uint32 tTab = talentInfo->TalentTab; + if (talentInfo->Row > 0) + { + unsigned int numRows = sTalentStore.GetNumRows(); + for (unsigned int i = 0; i < numRows; i++) // Loop through all talents. + { + // Someday, someone needs to revamp + const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i); + if (tmpTalent) // the way talents are tracked + { + if (tmpTalent->TalentTab == tTab) + { + for (int j = 0; j <= 4; j++) + { + if (tmpTalent->RankID[j] != 0) + { + if (player->HasSpell(tmpTalent->RankID[j])) + { + spentPoints += j + 1; + } + } + } + } + } + } + } + + // not have required min points spent in talent tree + if(spentPoints < (talentInfo->Row * 5)) + return; + + // spell not set in talent.dbc + uint32 spellid = talentInfo->RankID[requested_rank]; + if( spellid == 0 ) + { + sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank); + return; + } + + // already known + if(GetPlayer( )->HasSpell(spellid)) + return; + + // learn! (other talent ranks will unlearned at learning) + GetPlayer( )->learnSpell(spellid); + sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid); + + // update free talent points + GetPlayer()->SetFreeTalentPoints(CurTalentPoints - 1); +} + +void WorldSession::HandleTalentWipeOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDetail("MSG_TALENT_WIPE_CONFIRM"); + uint64 guid; + recv_data >> guid; + + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_TRAINER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleTalentWipeOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + if(!(_player->resetTalents())) + { + WorldPacket data( MSG_TALENT_WIPE_CONFIRM, 8+4); //you have not any talent + data << uint64(0); + data << uint32(0); + SendPacket( &data ); + return; + } + + unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect" +} + +void WorldSession::HandleUnlearnSkillOpcode(WorldPacket & recv_data) +{ + CHECK_PACKET_SIZE(recv_data,4); + + uint32 skill_id; + recv_data >> skill_id; + GetPlayer()->SetSkill(skill_id, 0, 0); +} diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp new file mode 100644 index 000000000..cdb2c3919 --- /dev/null +++ b/src/game/SocialMgr.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "SocialMgr.h" +#include "Policies/SingletonImp.h" +#include "Database/DatabaseEnv.h" +#include "Opcodes.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Player.h" +#include "ObjectMgr.h" +#include "World.h" +#include "Util.h" + +INSTANTIATE_SINGLETON_1( SocialMgr ); + +PlayerSocial::PlayerSocial() +{ + m_playerGUID = 0; +} + +PlayerSocial::~PlayerSocial() +{ + m_playerSocialMap.clear(); +} + +uint32 PlayerSocial::GetNumberOfSocialsWithFlag(SocialFlag flag) +{ + uint32 counter = 0; + for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr) + { + if(itr->second.Flags & flag) + counter++; + } + return counter; +} + +bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore) +{ + // check client limits + if(ignore) + { + if(GetNumberOfSocialsWithFlag(SOCIAL_FLAG_IGNORED) >= SOCIALMGR_IGNORE_LIMIT) + return false; + } + else + { + if(GetNumberOfSocialsWithFlag(SOCIAL_FLAG_FRIEND) >= SOCIALMGR_FRIEND_LIMIT) + return false; + } + + uint32 flag = SOCIAL_FLAG_FRIEND; + if(ignore) + flag = SOCIAL_FLAG_IGNORED; + + PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid); + if(itr != m_playerSocialMap.end()) + { + CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags | %u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid); + m_playerSocialMap[friend_guid].Flags |= flag; + } + else + { + CharacterDatabase.PExecute("INSERT INTO character_social (guid, friend, flags) VALUES ('%u', '%u', '%u')", GetPlayerGUID(), friend_guid, flag); + FriendInfo fi; + fi.Flags |= flag; + m_playerSocialMap[friend_guid] = fi; + } + return true; +} + +void PlayerSocial::RemoveFromSocialList(uint32 friend_guid, bool ignore) +{ + PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid); + if(itr == m_playerSocialMap.end()) // not exist + return; + + uint32 flag = SOCIAL_FLAG_FRIEND; + if(ignore) + flag = SOCIAL_FLAG_IGNORED; + + itr->second.Flags &= ~flag; + if(itr->second.Flags == 0) + { + CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u'", GetPlayerGUID(), friend_guid); + m_playerSocialMap.erase(itr); + } + else + { + CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags & ~%u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid); + } +} + +void PlayerSocial::SetFriendNote(uint32 friend_guid, std::string note) +{ + PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid); + if(itr == m_playerSocialMap.end()) // not exist + return; + + utf8truncate(note,48); // DB and client size limitation + + CharacterDatabase.escape_string(note); + CharacterDatabase.PExecute("UPDATE character_social SET note = '%s' WHERE guid = '%u' AND friend = '%u'", note.c_str(), GetPlayerGUID(), friend_guid); + m_playerSocialMap[friend_guid].Note = note; +} + +void PlayerSocial::SendSocialList() +{ + Player *plr = objmgr.GetPlayer(GetPlayerGUID()); + if(!plr) + return; + + uint32 size = m_playerSocialMap.size(); + + WorldPacket data(SMSG_CONTACT_LIST, (4+4+size*25)); // just can guess size + data << uint32(7); // unk flag (0x1, 0x2, 0x4), 0x7 if it include ignore list + data << uint32(size); // friends count + + for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr) + { + sSocialMgr.GetFriendInfo(plr, itr->first, itr->second); + + data << uint64(itr->first); // player guid + data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?) + data << itr->second.Note; // string note + if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend() + { + data << uint8(itr->second.Status); // online/offline/etc? + if(itr->second.Status) // if online + { + data << uint32(itr->second.Area); // player area + data << uint32(itr->second.Level); // player level + data << uint32(itr->second.Class); // player class + } + } + } + + plr->GetSession()->SendPacket(&data); + sLog.outDebug("WORLD: Sent SMSG_CONTACT_LIST"); +} + +bool PlayerSocial::HasFriend(uint32 friend_guid) +{ + PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid); + if(itr != m_playerSocialMap.end()) + return itr->second.Flags & SOCIAL_FLAG_FRIEND; + return false; +} + +bool PlayerSocial::HasIgnore(uint32 ignore_guid) +{ + PlayerSocialMap::iterator itr = m_playerSocialMap.find(ignore_guid); + if(itr != m_playerSocialMap.end()) + return itr->second.Flags & SOCIAL_FLAG_IGNORED; + return false; +} + +SocialMgr::SocialMgr() +{ + +} + +SocialMgr::~SocialMgr() +{ + +} + +void SocialMgr::RemovePlayerSocial(uint32 guid) +{ + SocialMap::iterator itr = m_socialMap.find(guid); + if(itr != m_socialMap.end()) + m_socialMap.erase(itr); +} + +void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo) +{ + if(!player) + return; + + Player *pFriend = ObjectAccessor::FindPlayer(friendGUID); + + uint32 team = player->GetTeam(); + uint32 security = player->GetSession()->GetSecurity(); + bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); + bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER; + + PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID); + if(itr != player->GetSocial()->m_playerSocialMap.end()) + friendInfo.Note = itr->second.Note; + + // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters + // MODERATOR, GAME MASTER, ADMINISTRATOR can see all + if( pFriend && pFriend->GetName() && + ( security > SEC_PLAYER || + ( pFriend->GetTeam() == team || allowTwoSideWhoList ) && + ( pFriend->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && pFriend->IsVisibleGloballyFor(player) ))) + { + friendInfo.Status = FRIEND_STATUS_ONLINE; + if(pFriend->isAFK()) + friendInfo.Status = FRIEND_STATUS_AFK; + if(pFriend->isDND()) + friendInfo.Status = FRIEND_STATUS_DND; + friendInfo.Area = pFriend->GetZoneId(); + friendInfo.Level = pFriend->getLevel(); + friendInfo.Class = pFriend->getClass(); + } + else + { + friendInfo.Status = FRIEND_STATUS_OFFLINE; + friendInfo.Area = 0; + friendInfo.Level = 0; + friendInfo.Class = 0; + } +} + +void SocialMgr::MakeFriendStatusPacket(FriendsResult result, uint32 guid, WorldPacket *data) +{ + data->Initialize(SMSG_FRIEND_STATUS, 5); + *data << uint8(result); + *data << uint64(guid); +} + +void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast) +{ + FriendInfo fi; + + WorldPacket data; + MakeFriendStatusPacket(result, friend_guid, &data); + GetFriendInfo(player, friend_guid, fi); + switch(result) + { + case FRIEND_ADDED_OFFLINE: + case FRIEND_ADDED_ONLINE: + data << fi.Note; + break; + } + + switch(result) + { + case FRIEND_ADDED_ONLINE: + case FRIEND_ONLINE: + data << uint8(fi.Status); + data << uint32(fi.Area); + data << uint32(fi.Level); + data << uint32(fi.Class); + break; + } + + if(broadcast) + BroadcastToFriendListers(player, &data); + else + player->GetSession()->SendPacket(&data); +} + +void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet) +{ + if(!player) + return; + + uint32 team = player->GetTeam(); + uint32 security = player->GetSession()->GetSecurity(); + uint32 guid = player->GetGUIDLow(); + bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST); + bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); + + for(SocialMap::iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr) + { + PlayerSocialMap::iterator itr2 = itr->second.m_playerSocialMap.find(guid); + if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) + { + Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + + // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters + // MODERATOR, GAME MASTER, ADMINISTRATOR can see all + if( pFriend && pFriend->IsInWorld() && + ( pFriend->GetSession()->GetSecurity() > SEC_PLAYER || + ( pFriend->GetTeam() == team || allowTwoSideWhoList ) && + (security == SEC_PLAYER || gmInWhoList && player->IsVisibleGloballyFor(pFriend) ))) + { + pFriend->GetSession()->SendPacket(packet); + } + } + } +} + +PlayerSocial *SocialMgr::LoadFromDB(QueryResult *result, uint32 guid) +{ + PlayerSocial *social = &m_socialMap[guid]; + social->SetPlayerGUID(guid); + + if(!result) + return social; + + uint32 friend_guid = 0; + uint32 flags = 0; + std::string note = ""; + + // used to speed up check below. Using GetNumberOfSocialsWithFlag will cause unneeded iteration + uint32 friendCounter=0, ignoreCounter=0; + + do + { + Field *fields = result->Fetch(); + + friend_guid = fields[0].GetUInt32(); + flags = fields[1].GetUInt32(); + note = fields[2].GetCppString(); + + if((flags & SOCIAL_FLAG_IGNORED) && ignoreCounter >= SOCIALMGR_IGNORE_LIMIT) + continue; + if((flags & SOCIAL_FLAG_FRIEND) && friendCounter >= SOCIALMGR_FRIEND_LIMIT) + continue; + + social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note); + + if(flags & SOCIAL_FLAG_IGNORED) + ignoreCounter++; + else + friendCounter++; + } + while( result->NextRow() ); + delete result; + return social; +} diff --git a/src/game/SocialMgr.h b/src/game/SocialMgr.h new file mode 100644 index 000000000..c4a19295a --- /dev/null +++ b/src/game/SocialMgr.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MANGOS_SOCIALMGR_H +#define __MANGOS_SOCIALMGR_H + +#include "Policies/Singleton.h" +#include "Database/DatabaseEnv.h" +#include "Common.h" + +class SocialMgr; +class PlayerSocial; +class Player; +class WorldPacket; + +enum FriendStatus +{ + FRIEND_STATUS_OFFLINE = 0, + FRIEND_STATUS_ONLINE = 1, + FRIEND_STATUS_AFK = 2, + FRIEND_STATUS_UNK3 = 3, + FRIEND_STATUS_DND = 4 +}; + +enum SocialFlag +{ + SOCIAL_FLAG_FRIEND = 0x01, + SOCIAL_FLAG_IGNORED = 0x02, + SOCIAL_FLAG_MUTED = 0x04 // guessed +}; + +struct FriendInfo +{ + FriendStatus Status; + uint32 Flags; + uint32 Area; + uint32 Level; + uint32 Class; + std::string Note; + + FriendInfo() + { + Status = FRIEND_STATUS_OFFLINE; + Flags = 0; + Area = 0; + Level = 0; + Class = 0; + Note = ""; + } + + FriendInfo(uint32 flags, std::string note) + { + Status = FRIEND_STATUS_OFFLINE; + Flags = flags; + Area = 0; + Level = 0; + Class = 0; + Note = note; + } +}; + +typedef std::map PlayerSocialMap; +typedef std::map SocialMap; + +/// Results of friend related commands +enum FriendsResult +{ + FRIEND_DB_ERROR = 0x00, + FRIEND_LIST_FULL = 0x01, + FRIEND_ONLINE = 0x02, + FRIEND_OFFLINE = 0x03, + FRIEND_NOT_FOUND = 0x04, + FRIEND_REMOVED = 0x05, + FRIEND_ADDED_ONLINE = 0x06, + FRIEND_ADDED_OFFLINE = 0x07, + FRIEND_ALREADY = 0x08, + FRIEND_SELF = 0x09, + FRIEND_ENEMY = 0x0A, + FRIEND_IGNORE_FULL = 0x0B, + FRIEND_IGNORE_SELF = 0x0C, + FRIEND_IGNORE_NOT_FOUND = 0x0D, + FRIEND_IGNORE_ALREADY = 0x0E, + FRIEND_IGNORE_ADDED = 0x0F, + FRIEND_IGNORE_REMOVED = 0x10, + FRIEND_IGNORE_AMBIGUOUS = 0x11, // That name is ambiguous, type more of the player's server name + FRIEND_MUTE_FULL = 0x12, + FRIEND_MUTE_SELF = 0x13, + FRIEND_MUTE_NOT_FOUND = 0x14, + FRIEND_MUTE_ALREADY = 0x15, + FRIEND_MUTE_ADDED = 0x16, + FRIEND_MUTE_REMOVED = 0x17, + FRIEND_MUTE_AMBIGUOUS = 0x18, // That name is ambiguous, type more of the player's server name + FRIEND_UNK7 = 0x19, // no message at client + FRIEND_UNKNOWN = 0x1A // Unknown friend response from server +}; + +#define SOCIALMGR_FRIEND_LIMIT 50 +#define SOCIALMGR_IGNORE_LIMIT 25 + +class PlayerSocial +{ + friend class SocialMgr; + public: + PlayerSocial(); + ~PlayerSocial(); + // adding/removing + bool AddToSocialList(uint32 friend_guid, bool ignore); + void RemoveFromSocialList(uint32 friend_guid, bool ignore); + void SetFriendNote(uint32 friend_guid, std::string note); + // Packet send's + void SendSocialList(); + // Misc + bool HasFriend(uint32 friend_guid); + bool HasIgnore(uint32 ignore_guid); + uint32 GetPlayerGUID() { return m_playerGUID; } + void SetPlayerGUID(uint32 guid) { m_playerGUID = guid; } + uint32 GetNumberOfSocialsWithFlag(SocialFlag flag); + private: + PlayerSocialMap m_playerSocialMap; + uint32 m_playerGUID; +}; + +class SocialMgr +{ + public: + SocialMgr(); + ~SocialMgr(); + // Misc + void RemovePlayerSocial(uint32 guid); + void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo); + // Packet management + void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data); + void SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast); + void BroadcastToFriendListers(Player *player, WorldPacket *packet); + // Loading + PlayerSocial *LoadFromDB(QueryResult *result, uint32 guid); + private: + SocialMap m_socialMap; +}; + +#define sSocialMgr MaNGOS::Singleton::Instance() +#endif diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp new file mode 100644 index 000000000..544432d15 --- /dev/null +++ b/src/game/Spell.cpp @@ -0,0 +1,5075 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "Opcodes.h" +#include "Log.h" +#include "UpdateMask.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Player.h" +#include "Pet.h" +#include "Unit.h" +#include "Spell.h" +#include "DynamicObject.h" +#include "SpellAuras.h" +#include "Group.h" +#include "UpdateData.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "CellImpl.h" +#include "Policies/SingletonImp.h" +#include "SharedDefines.h" +#include "Tools.h" +#include "LootMgr.h" +#include "VMapFactory.h" +#include "BattleGround.h" +#include "Util.h" + +#define SPELL_CHANNEL_UPDATE_INTERVAL 1000 + +extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; + +bool IsQuestTameSpell(uint32 spellId) +{ + SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId); + if (!spellproto) return false; + + return spellproto->Effect[0] == SPELL_EFFECT_THREAT + && spellproto->Effect[1] == SPELL_EFFECT_APPLY_AURA && spellproto->EffectApplyAuraName[1] == SPELL_AURA_DUMMY; +} + +SpellCastTargets::SpellCastTargets() +{ + m_unitTarget = NULL; + m_itemTarget = NULL; + m_GOTarget = NULL; + + m_unitTargetGUID = 0; + m_GOTargetGUID = 0; + m_CorpseTargetGUID = 0; + m_itemTargetGUID = 0; + m_itemTargetEntry = 0; + + m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0; + m_strTarget = ""; + m_targetMask = 0; +} + +SpellCastTargets::~SpellCastTargets() +{ +} + +void SpellCastTargets::setUnitTarget(Unit *target) +{ + if (!target) + return; + + m_destX = target->GetPositionX(); + m_destY = target->GetPositionY(); + m_destZ = target->GetPositionZ(); + m_unitTarget = target; + m_unitTargetGUID = target->GetGUID(); + m_targetMask |= TARGET_FLAG_UNIT; +} + +void SpellCastTargets::setDestination(float x, float y, float z) +{ + m_destX = x; + m_destY = y; + m_destZ = z; + m_targetMask |= TARGET_FLAG_DEST_LOCATION; +} + +void SpellCastTargets::setGOTarget(GameObject *target) +{ + m_GOTarget = target; + m_GOTargetGUID = target->GetGUID(); + // m_targetMask |= TARGET_FLAG_OBJECT; +} + +void SpellCastTargets::setItemTarget(Item* item) +{ + if(!item) + return; + + m_itemTarget = item; + m_itemTargetGUID = item->GetGUID(); + m_itemTargetEntry = item->GetEntry(); + m_targetMask |= TARGET_FLAG_ITEM; +} + +void SpellCastTargets::setCorpseTarget(Corpse* corpse) +{ + m_CorpseTargetGUID = corpse->GetGUID(); +} + +void SpellCastTargets::Update(Unit* caster) +{ + m_GOTarget = m_GOTargetGUID ? ObjectAccessor::GetGameObject(*caster,m_GOTargetGUID) : NULL; + m_unitTarget = m_unitTargetGUID ? + ( m_unitTargetGUID==caster->GetGUID() ? caster : ObjectAccessor::GetUnit(*caster, m_unitTargetGUID) ) : + NULL; + + m_itemTarget = NULL; + if(caster->GetTypeId()==TYPEID_PLAYER) + { + if(m_targetMask & TARGET_FLAG_ITEM) + m_itemTarget = ((Player*)caster)->GetItemByGuid(m_itemTargetGUID); + else + { + Player* pTrader = ((Player*)caster)->GetTrader(); + if(pTrader && m_itemTargetGUID < TRADE_SLOT_COUNT) + m_itemTarget = pTrader->GetItemByPos(pTrader->GetItemPosByTradeSlot(m_itemTargetGUID)); + } + if(m_itemTarget) + m_itemTargetEntry = m_itemTarget->GetEntry(); + } +} + +bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) +{ + if(data->rpos()+4 > data->size()) + return false; + + *data >> m_targetMask; + + if(m_targetMask == TARGET_FLAG_SELF) + { + m_destX = caster->GetPositionX(); + m_destY = caster->GetPositionY(); + m_destZ = caster->GetPositionZ(); + m_unitTarget = caster; + m_unitTargetGUID = caster->GetGUID(); + return true; + } + + // TARGET_FLAG_UNK2 is used for non-combat pets, maybe other? + if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_UNK2 )) + if(!readGUID(*data, m_unitTargetGUID)) + return false; + + if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK )) + if(!readGUID(*data, m_GOTargetGUID)) + return false; + + if(( m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM )) && caster->GetTypeId() == TYPEID_PLAYER) + if(!readGUID(*data, m_itemTargetGUID)) + return false; + + if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) + { + if(data->rpos()+4+4+4 > data->size()) + return false; + + *data >> m_srcX >> m_srcY >> m_srcZ; + if(!MaNGOS::IsValidMapCoord(m_srcX, m_srcY, m_srcZ)) + return false; + } + + if( m_targetMask & TARGET_FLAG_DEST_LOCATION ) + { + if(data->rpos()+4+4+4 > data->size()) + return false; + + *data >> m_destX >> m_destY >> m_destZ; + if(!MaNGOS::IsValidMapCoord(m_destX, m_destY, m_destZ)) + return false; + } + + if( m_targetMask & TARGET_FLAG_STRING ) + { + if(data->rpos()+1 > data->size()) + return false; + + *data >> m_strTarget; + } + + if( m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) ) + if(!readGUID(*data, m_CorpseTargetGUID)) + return false; + + // find real units/GOs + Update(caster); + return true; +} + +void SpellCastTargets::write ( WorldPacket * data ) +{ + *data << uint32(m_targetMask); + + if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) ) + { + if(m_targetMask & TARGET_FLAG_UNIT) + { + if(m_unitTarget) + data->append(m_unitTarget->GetPackGUID()); + else + *data << uint8(0); + } + else if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK ) ) + { + if(m_GOTarget) + data->append(m_GOTarget->GetPackGUID()); + else + *data << uint8(0); + } + else if( m_targetMask & ( TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) ) + data->appendPackGUID(m_CorpseTargetGUID); + else + *data << uint8(0); + } + + if( m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM ) ) + { + if(m_itemTarget) + data->append(m_itemTarget->GetPackGUID()); + else + *data << uint8(0); + } + + if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) + *data << m_srcX << m_srcY << m_srcZ; + + if( m_targetMask & TARGET_FLAG_DEST_LOCATION ) + *data << m_destX << m_destY << m_destZ; + + if( m_targetMask & TARGET_FLAG_STRING ) + *data << m_strTarget; +} + +Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, Spell** triggeringContainer ) +{ + ASSERT( Caster != NULL && info != NULL ); + ASSERT( info == sSpellStore.LookupEntry( info->Id ) && "`info` must be pointer to sSpellStore element"); + + m_spellInfo = info; + m_caster = Caster; + m_selfContainer = NULL; + m_triggeringContainer = triggeringContainer; + m_deletable = true; + m_delayAtDamageCount = 0; + + m_applyMultiplierMask = 0; + + // Get data for type of attack + switch (m_spellInfo->DmgClass) + { + case SPELL_DAMAGE_CLASS_MELEE: + if (m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND) + m_attackType = OFF_ATTACK; + else + m_attackType = BASE_ATTACK; + break; + case SPELL_DAMAGE_CLASS_RANGED: + m_attackType = RANGED_ATTACK; + break; + default: + // Wands + if (m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_WAND) + m_attackType = RANGED_ATTACK; + else + m_attackType = BASE_ATTACK; + break; + } + + m_spellSchoolMask = GetSpellSchoolMask(info); // Can be override for some spell (wand shoot for example) + + if(m_attackType == RANGED_ATTACK) + { + // wand case + if((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId()==TYPEID_PLAYER) + { + if(Item* pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK)) + m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType); + } + } + + if(originalCasterGUID) + m_originalCasterGUID = originalCasterGUID; + else + m_originalCasterGUID = m_caster->GetGUID(); + + if(m_originalCasterGUID==m_caster->GetGUID()) + m_originalCaster = m_caster; + else + { + m_originalCaster = ObjectAccessor::GetUnit(*m_caster,m_originalCasterGUID); + if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL; + } + + for(int i=0; i <3; ++i) + m_currentBasePoints[i] = m_spellInfo->EffectBasePoints[i]; + + m_spellState = SPELL_STATE_NULL; + + m_castPositionX = m_castPositionY = m_castPositionZ = 0; + m_TriggerSpells.clear(); + m_IsTriggeredSpell = triggered; + //m_AreaAura = false; + m_CastItem = NULL; + + unitTarget = NULL; + itemTarget = NULL; + gameObjTarget = NULL; + focusObject = NULL; + m_cast_count = 0; + m_triggeredByAuraSpell = NULL; + + //Auto Shot & Shoot + if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered ) + m_autoRepeat = true; + else + m_autoRepeat = false; + + m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before. + m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before. + m_timer = 0; // will set to castime in preper + + m_needAliveTargetMask = 0; + + // determine reflection + m_canReflect = false; + + if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && (m_spellInfo->AttributesEx2 & 0x4)==0) + { + for(int j=0;j<3;j++) + { + if (m_spellInfo->Effect[j]==0) + continue; + + if(!IsPositiveTarget(m_spellInfo->EffectImplicitTargetA[j],m_spellInfo->EffectImplicitTargetB[j])) + m_canReflect = true; + else + m_canReflect = (m_spellInfo->AttributesEx & (1<<7)) ? true : false; + + if(m_canReflect) + continue; + else + break; + } + } + + CleanupTargetList(); +} + +Spell::~Spell() +{ +} + +void Spell::FillTargetMap() +{ + // TODO: ADD the correct target FILLS!!!!!! + + for(uint32 i=0;i<3;i++) + { + // not call for empty effect. + // Also some spells use not used effect targets for store targets for dummy effect in triggered spells + if(m_spellInfo->Effect[i]==0) + continue; + + // targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT filled in Spell::canCast call + if( m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT || + m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF ) + continue; + + // TODO: find a way so this is not needed? + // for area auras always add caster as target (needed for totems for example) + if(IsAreaAuraEffect(m_spellInfo->Effect[i])) + AddUnitTarget(m_caster, i); + + std::list tmpUnitMap; + + // TargetA/TargetB dependent from each other, we not switch to full support this dependences + // but need it support in some know cases + switch(m_spellInfo->EffectImplicitTargetA[i]) + { + case TARGET_ALL_AROUND_CASTER: + if( m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_PARTY || + m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER || + m_spellInfo->EffectImplicitTargetB[i]==TARGET_RANDOM_RAID_MEMBER ) + { + SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); + } + // Note: this hack with search required until GO casting not implemented + // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support + // currently each enemy selected explicitly and self cast damage + else if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) + { + if(m_targets.getUnitTarget()) + tmpUnitMap.push_back(m_targets.getUnitTarget()); + } + else + { + SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); + SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); + } + break; + case TARGET_TABLE_X_Y_Z_COORDINATES: + // Only if target A, for target B (used in teleports) dest select in effect + SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); + break; + default: + switch(m_spellInfo->EffectImplicitTargetB[i]) + { + case TARGET_SCRIPT_COORDINATES: // B case filled in canCast but we need fill unit list base at A case + SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); + break; + default: + SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap); + SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); + break; + } + break; + } + + if( (m_spellInfo->EffectImplicitTargetA[i]==0 || m_spellInfo->EffectImplicitTargetA[i]==TARGET_EFFECT_SELECT) && + (m_spellInfo->EffectImplicitTargetB[i]==0 || m_spellInfo->EffectImplicitTargetB[i]==TARGET_EFFECT_SELECT) ) + { + // add here custom effects that need default target. + // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!! + switch(m_spellInfo->Effect[i]) + { + case SPELL_EFFECT_DUMMY: + { + switch(m_spellInfo->Id) + { + case 20577: // Cannibalize + { + // non-standard target selection + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); + float max_range = GetSpellMaxRange(srange); + + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + WorldObject* result = NULL; + + MaNGOS::CannibalizeObjectCheck u_check(m_caster, max_range); + MaNGOS::WorldObjectSearcher searcher(result, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + + if(!result) + { + TypeContainerVisitor, WorldTypeMapContainer > world_searcher(searcher); + cell_lock->Visit(cell_lock, world_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + } + + if(result) + { + switch(result->GetTypeId()) + { + case TYPEID_UNIT: + case TYPEID_PLAYER: + tmpUnitMap.push_back((Unit*)result); + break; + case TYPEID_CORPSE: + m_targets.setCorpseTarget((Corpse*)result); + if(Player* owner = ObjectAccessor::FindPlayer(((Corpse*)result)->GetOwnerGUID())) + tmpUnitMap.push_back(owner); + break; + } + } + else + { + // clear cooldown at fail + if(m_caster->GetTypeId()==TYPEID_PLAYER) + { + ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(m_spellInfo->Id); + data << uint64(m_caster->GetGUID()); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + + SendCastResult(SPELL_FAILED_NO_EDIBLE_CORPSES); + finish(false); + } + break; + } + default: + if(m_targets.getUnitTarget()) + tmpUnitMap.push_back(m_targets.getUnitTarget()); + break; + } + break; + } + case SPELL_EFFECT_RESURRECT: + case SPELL_EFFECT_PARRY: + case SPELL_EFFECT_BLOCK: + case SPELL_EFFECT_CREATE_ITEM: + case SPELL_EFFECT_TRIGGER_SPELL: + case SPELL_EFFECT_TRIGGER_MISSILE: + case SPELL_EFFECT_LEARN_SPELL: + case SPELL_EFFECT_SKILL_STEP: + case SPELL_EFFECT_PROFICIENCY: + case SPELL_EFFECT_SUMMON_POSSESSED: + case SPELL_EFFECT_SUMMON_OBJECT_WILD: + case SPELL_EFFECT_SELF_RESURRECT: + case SPELL_EFFECT_REPUTATION: + if(m_targets.getUnitTarget()) + tmpUnitMap.push_back(m_targets.getUnitTarget()); + break; + case SPELL_EFFECT_SUMMON_PLAYER: + if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->GetSelection()) + { + Player* target = objmgr.GetPlayer(((Player*)m_caster)->GetSelection()); + if(target) + tmpUnitMap.push_back(target); + } + break; + case SPELL_EFFECT_RESURRECT_NEW: + if(m_targets.getUnitTarget()) + tmpUnitMap.push_back(m_targets.getUnitTarget()); + if(m_targets.getCorpseTargetGUID()) + { + Corpse *corpse = ObjectAccessor::GetCorpse(*m_caster,m_targets.getCorpseTargetGUID()); + if(corpse) + { + Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID()); + if(owner) + tmpUnitMap.push_back(owner); + } + } + break; + case SPELL_EFFECT_SUMMON: + if(m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED || m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED2) + { + if(m_targets.getUnitTarget()) + tmpUnitMap.push_back(m_targets.getUnitTarget()); + } + else + tmpUnitMap.push_back(m_caster); + break; + case SPELL_EFFECT_SUMMON_CHANGE_ITEM: + case SPELL_EFFECT_SUMMON_WILD: + case SPELL_EFFECT_SUMMON_GUARDIAN: + case SPELL_EFFECT_TRANS_DOOR: + case SPELL_EFFECT_ADD_FARSIGHT: + case SPELL_EFFECT_STUCK: + case SPELL_EFFECT_DESTROY_ALL_TOTEMS: + case SPELL_EFFECT_SUMMON_DEMON: + case SPELL_EFFECT_SKILL: + tmpUnitMap.push_back(m_caster); + break; + case SPELL_EFFECT_LEARN_PET_SPELL: + if(Pet* pet = m_caster->GetPet()) + tmpUnitMap.push_back(pet); + break; + case SPELL_EFFECT_ENCHANT_ITEM: + case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: + case SPELL_EFFECT_DISENCHANT: + case SPELL_EFFECT_FEED_PET: + case SPELL_EFFECT_PROSPECTING: + if(m_targets.getItemTarget()) + AddItemTarget(m_targets.getItemTarget(), i); + break; + case SPELL_EFFECT_APPLY_AURA: + switch(m_spellInfo->EffectApplyAuraName[i]) + { + case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_SELF(1) (and present for other ranks for same spell for example) + case SPELL_AURA_ADD_PCT_MODIFIER: + tmpUnitMap.push_back(m_caster); + break; + default: // apply to target in other case + if(m_targets.getUnitTarget()) + tmpUnitMap.push_back(m_targets.getUnitTarget()); + break; + } + break; + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: + // AreaAura + if(m_spellInfo->Attributes == 0x9050000 || m_spellInfo->Attributes == 0x10000) + SetTargetMap(i,TARGET_AREAEFFECT_PARTY,tmpUnitMap); + break; + case SPELL_EFFECT_SKIN_PLAYER_CORPSE: + if(m_targets.getUnitTarget()) + { + tmpUnitMap.push_back(m_targets.getUnitTarget()); + } + else if (m_targets.getCorpseTargetGUID()) + { + Corpse *corpse = ObjectAccessor::GetCorpse(*m_caster,m_targets.getCorpseTargetGUID()); + if(corpse) + { + Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID()); + if(owner) + tmpUnitMap.push_back(owner); + } + } + break; + default: + break; + } + } + if(IsChanneledSpell(m_spellInfo) && !tmpUnitMap.empty()) + m_needAliveTargetMask |= (1<GetTypeId() == TYPEID_PLAYER) + { + Player *me = (Player*)m_caster; + for (std::list::const_iterator itr = tmpUnitMap.begin(); itr != tmpUnitMap.end(); itr++) + { + Unit *owner = (*itr)->GetOwner(); + Unit *u = owner ? owner : (*itr); + if(u!=m_caster && u->IsPvP() && (!me->duel || me->duel->opponent != u)) + { + me->UpdatePvP(true); + me->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); + break; + } + } + } + + for (std::list::iterator itr = tmpUnitMap.begin() ; itr != tmpUnitMap.end();) + { + if(!CheckTarget(*itr, i, false )) + { + itr = tmpUnitMap.erase(itr); + continue; + } + else + ++itr; + } + + for(std::list::iterator iunit= tmpUnitMap.begin();iunit != tmpUnitMap.end();++iunit) + AddUnitTarget((*iunit), i); + } +} + +void Spell::CleanupTargetList() +{ + m_UniqueTargetInfo.clear(); + m_UniqueGOTargetInfo.clear(); + m_UniqueItemInfo.clear(); + m_countOfHit = 0; + m_countOfMiss = 0; + m_delayMoment = 0; +} + +void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex) +{ + if( m_spellInfo->Effect[effIndex]==0 ) + return; + + uint64 targetGUID = pVictim->GetGUID(); + + // Lookup target in already in list + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + if (targetGUID == ihit->targetGUID) // Found in list + { + ihit->effectMask |= 1<SpellHitResult(pVictim, m_spellInfo, m_canReflect); + if (target.missCondition == SPELL_MISS_NONE) + ++m_countOfHit; + else + ++m_countOfMiss; + + // Spell have speed - need calculate incoming time + if (m_spellInfo->speed > 0.0f) + { + // calculate spell incoming interval + float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ()); + if (dist < 5.0f) dist = 5.0f; + target.timeDelay = (uint64) floor(dist / m_spellInfo->speed * 1000.0f); + + // Calculate minimum incoming time + if (m_delayMoment==0 || m_delayMoment>target.timeDelay) + m_delayMoment = target.timeDelay; + } + else + target.timeDelay = 0LL; + + // If target reflect spell back to caster + if (target.missCondition==SPELL_MISS_REFLECT) + { + // Calculate reflected spell result on caster + target.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, m_canReflect); + + if (target.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell + target.reflectResult = SPELL_MISS_PARRY; + + // Increase time interval for reflected spells by 1.5 + target.timeDelay+=target.timeDelay>>1; + } + else + target.reflectResult = SPELL_MISS_NONE; + + // Add target to list + m_UniqueTargetInfo.push_back(target); +} + +void Spell::AddUnitTarget(uint64 unitGUID, uint32 effIndex) +{ + Unit* unit = m_caster->GetGUID()==unitGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, unitGUID); + if (unit) + AddUnitTarget(unit, effIndex); +} + +void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex) +{ + if( m_spellInfo->Effect[effIndex]==0 ) + return; + + uint64 targetGUID = pVictim->GetGUID(); + + // Lookup target in already in list + for(std::list::iterator ihit= m_UniqueGOTargetInfo.begin();ihit != m_UniqueGOTargetInfo.end();++ihit) + { + if (targetGUID == ihit->targetGUID) // Found in list + { + ihit->effectMask |= 1<speed > 0.0f) + { + // calculate spell incoming interval + float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ()); + if (dist < 5.0f) dist = 5.0f; + target.timeDelay = (uint64) floor(dist / m_spellInfo->speed * 1000.0f); + if (m_delayMoment==0 || m_delayMoment>target.timeDelay) + m_delayMoment = target.timeDelay; + } + else + target.timeDelay = 0LL; + + ++m_countOfHit; + + // Add target to list + m_UniqueGOTargetInfo.push_back(target); +} + +void Spell::AddGOTarget(uint64 goGUID, uint32 effIndex) +{ + GameObject* go = ObjectAccessor::GetGameObject(*m_caster, goGUID); + if (go) + AddGOTarget(go, effIndex); +} + +void Spell::AddItemTarget(Item* pitem, uint32 effIndex) +{ + if( m_spellInfo->Effect[effIndex]==0 ) + return; + + // Lookup target in already in list + for(std::list::iterator ihit= m_UniqueItemInfo.begin();ihit != m_UniqueItemInfo.end();++ihit) + { + if (pitem == ihit->item) // Found in list + { + ihit->effectMask |= 1<GetTypeId()== TYPEID_PLAYER) + ((Player*)m_caster)->UpdateWeaponSkill(BASE_ATTACK); + + m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_MISS, m_spellInfo, m_IsTriggeredSpell); + break; + case SPELL_MISS_RESIST: + m_caster->ProcDamageAndSpell(unitTarget, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, damageSchoolMask, m_spellInfo, m_IsTriggeredSpell); + break; + case SPELL_MISS_DODGE: + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->UpdateDefense(); + + // Overpower + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARRIOR) + { + ((Player*) m_caster)->AddComboPoints(unitTarget, 1); + m_caster->StartReactiveTimer( REACTIVE_OVERPOWER ); + } + + // Riposte + if (unitTarget->getClass() != CLASS_ROGUE) + { + unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true); + unitTarget->StartReactiveTimer( REACTIVE_DEFENSE ); + } + + m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_DODGE, m_spellInfo, m_IsTriggeredSpell); + break; + case SPELL_MISS_PARRY: + // Update victim defense ? + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->UpdateDefense(); + // Mongoose bite - set only Counterattack here + if (unitTarget->getClass() == CLASS_HUNTER) + { + unitTarget->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true); + unitTarget->StartReactiveTimer( REACTIVE_HUNTER_PARRY ); + } + else + { + unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true); + unitTarget->StartReactiveTimer( REACTIVE_DEFENSE ); + } + m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_PARRY, m_spellInfo, m_IsTriggeredSpell); + break; + case SPELL_MISS_BLOCK: + unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true); + unitTarget->StartReactiveTimer( REACTIVE_DEFENSE ); + + m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_BLOCK, m_spellInfo, m_IsTriggeredSpell); + break; + // Trigger from this events not supported + case SPELL_MISS_EVADE: + case SPELL_MISS_IMMUNE: + case SPELL_MISS_IMMUNE2: + case SPELL_MISS_DEFLECT: + case SPELL_MISS_ABSORB: + // Trigger from reflects need do after get reflect result + case SPELL_MISS_REFLECT: + break; + default: + break; + } + } +} + +void Spell::DoAllEffectOnTarget(TargetInfo *target) +{ + if (target->processed) // Check target + return; + target->processed = true; // Target checked in apply effects procedure + + // Get mask of effects for target + uint32 mask = target->effectMask; + if (mask == 0) // No effects + return; + + Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID); + if (!unit) + return; + + SpellMissInfo missInfo = target->missCondition; + // Need init unitTarget by default unit (can changed in code on reflect) + // Or on missInfo!=SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem) + unitTarget = unit; + + if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target + DoSpellHitOnUnit(unit, mask); + else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit) + { + if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him + DoSpellHitOnUnit(m_caster, mask); + } + + // Do triggers only on miss/resist/parry/dodge + if (missInfo!=SPELL_MISS_NONE) + doTriggers(missInfo); + + // Call scripted function for AI if this spell is casted upon a creature (except pets) + if(IS_CREATURE_GUID(target->targetGUID)) + { + // cast at creature (or GO) quest objectives update at successful cast finished (+channel finished) + // ignore autorepeat/melee casts for speed (not exist quest for spells (hm... ) + if( m_caster->GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsNextMeleeSwingSpell() && !IsChannelActive() ) + ((Player*)m_caster)->CastedCreatureOrGO(unit->GetEntry(),unit->GetGUID(),m_spellInfo->Id); + + if(((Creature*)unit)->AI()) + ((Creature*)unit)->AI()->SpellHit(m_caster ,m_spellInfo); + } +} + +void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) +{ + if(!unit || !effectMask) + return; + + // Recheck immune (only for delayed spells) + if( m_spellInfo->speed && ( + unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo),true) || + unit->IsImmunedToSpell(m_spellInfo,true) )) + { + m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE); + return; + } + + if( m_caster != unit ) + { + if( !m_caster->IsFriendlyTo(unit) ) + { + // for delayed spells ignore not visible explicit target + if(m_spellInfo->speed > 0.0f && unit==m_targets.getUnitTarget() && !unit->isVisibleForOrDetect(m_caster,false)) + { + m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE); + return; + } + + // exclude Arcane Missiles Dummy Aura aura for now (attack on hit) + // TODO: find way to not need this? + if(!(m_spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && + m_spellInfo->SpellFamilyFlags & 0x800LL)) + { + unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) ) + { + if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED)) + unit->SetStandState(PLAYER_STATE_NONE); + + if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) + ((Creature*)unit)->AI()->AttackStart(m_caster); + + unit->SetInCombatWith(m_caster); + m_caster->SetInCombatWith(unit); + + if(Player *attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + m_caster->SetContestedPvP(attackedPlayer); + } + unit->AddThreat(m_caster, 0.0f); + } + } + } + else + { + // for delayed spells ignore negative spells (after duel end) for friendly targets + if(m_spellInfo->speed > 0.0f && !IsPositiveSpell(m_spellInfo->Id)) + { + m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE); + return; + } + + // assisting case, healing and resurrection + if(unit->hasUnitState(UNIT_STAT_ATTACK_PLAYER)) + m_caster->SetContestedPvP(); + if( unit->isInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) ) + { + m_caster->SetInCombatState(unit->GetCombatTimer() > 0); + unit->getHostilRefManager().threatAssist(m_caster, 0.0f); + } + } + } + + // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add + m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo,m_triggeredByAuraSpell); + m_diminishLevel = unit->GetDiminishing(m_diminishGroup); + // Increase Diminishing on unit, current informations for actually casts will use values above + if((GetDiminishingReturnsGroupType(m_diminishGroup) == DRTYPE_PLAYER && unit->GetTypeId() == TYPEID_PLAYER) || GetDiminishingReturnsGroupType(m_diminishGroup) == DRTYPE_ALL) + unit->IncrDiminishing(m_diminishGroup); + + for(uint32 effectNumber=0;effectNumber<3;effectNumber++) + { + if (effectMask & (1<DmgMultiplier[effectNumber]; + // Apply multiplier mods + if(Player* modOwner = m_originalCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier,this); + m_damageMultipliers[effectNumber] *= multiplier; + } + } + } +} + +void Spell::DoAllEffectOnTarget(GOTargetInfo *target) +{ + if (target->processed) // Check target + return; + target->processed = true; // Target checked in apply effects procedure + + uint32 effectMask = target->effectMask; + if(!effectMask) + return; + + GameObject* go = ObjectAccessor::GetGameObject(*m_caster, target->targetGUID); + if(!go) + return; + + for(uint32 effectNumber=0;effectNumber<3;effectNumber++) + if (effectMask & (1<GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsNextMeleeSwingSpell() && !IsChannelActive() ) + ((Player*)m_caster)->CastedCreatureOrGO(go->GetEntry(),go->GetGUID(),m_spellInfo->Id); +} + +void Spell::DoAllEffectOnTarget(ItemTargetInfo *target) +{ + uint32 effectMask = target->effectMask; + if(!target->item || !effectMask) + return; + + for(uint32 effectNumber=0;effectNumber<3;effectNumber++) + if (effectMask & (1<item, NULL, effectNumber); +} + +bool Spell::IsAliveUnitPresentInTargetList() +{ + // Not need check return true + if (m_needAliveTargetMask == 0) + return true; + + uint8 needAliveTargetMask = m_needAliveTargetMask; + + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + if( ihit->missCondition == SPELL_MISS_NONE && (needAliveTargetMask & ihit->effectMask) ) + { + Unit *unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); + + if (unit && unit->isAlive()) + needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target + } + } + + // is all effects from m_needAliveTargetMask have alive targets + return needAliveTargetMask==0; +} + +// Helper for Chain Healing +// Spell target first +// Raidmates then descending by injury suffered (MaxHealth - Health) +// Other players/mobs then descending by injury suffered (MaxHealth - Health) +struct ChainHealingOrder : public std::binary_function +{ + const Unit* MainTarget; + ChainHealingOrder(Unit const* Target) : MainTarget(Target) {}; + // functor for operator ">" + bool operator()(Unit const* _Left, Unit const* _Right) const + { + return (ChainHealingHash(_Left) < ChainHealingHash(_Right)); + } + int32 ChainHealingHash(Unit const* Target) const + { + if (Target == MainTarget) + return 0; + else if (Target->GetTypeId() == TYPEID_PLAYER && MainTarget->GetTypeId() == TYPEID_PLAYER && + ((Player const*)Target)->IsInSameRaidWith((Player const*)MainTarget)) + { + if (Target->GetHealth() == Target->GetMaxHealth()) + return 40000; + else + return 20000 - Target->GetMaxHealth() + Target->GetHealth(); + } + else + return 40000 - Target->GetMaxHealth() + Target->GetHealth(); + } +}; + +class ChainHealingFullHealth: std::unary_function +{ + public: + const Unit* MainTarget; + ChainHealingFullHealth(const Unit* Target) : MainTarget(Target) {}; + + bool operator()(const Unit* Target) + { + return (Target != MainTarget && Target->GetHealth() == Target->GetMaxHealth()); + } +}; + +// Helper for targets nearest to the spell target +// The spell target is always first unless there is a target at _completely_ the same position (unbelievable case) +struct TargetDistanceOrder : public std::binary_function +{ + const Unit* MainTarget; + TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {}; + // functor for operator ">" + bool operator()(const Unit* _Left, const Unit* _Right) const + { + return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right)); + } +}; + +void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) +{ + float radius; + if (m_spellInfo->EffectRadiusIndex[i]) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + else + radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); + + if(m_originalCaster) + if(Player* modOwner = m_originalCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius,this); + + uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i]; + if(m_originalCaster) + if(Player* modOwner = m_originalCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this); + + uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; + switch(cur) + { + case TARGET_TOTEM_EARTH: + case TARGET_TOTEM_WATER: + case TARGET_TOTEM_AIR: + case TARGET_TOTEM_FIRE: + case TARGET_SELF: + case TARGET_SELF2: + case TARGET_DYNAMIC_OBJECT: + case TARGET_AREAEFFECT_CUSTOM: + case TARGET_AREAEFFECT_CUSTOM_2: + case TARGET_SUMMON: + { + TagUnitMap.push_back(m_caster); + break; + } + case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA: + { + m_targets.m_targetMask = 0; + unMaxTargets = EffectChainTarget; + float max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; + + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + std::list tempUnitMap; + + { + MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range); + MaNGOS::UnitListSearcher searcher(tempUnitMap, u_check); + + TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); + TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + } + + if(tempUnitMap.empty()) + break; + + tempUnitMap.sort(TargetDistanceOrder(m_caster)); + + //Now to get us a random target that's in the initial range of the spell + uint32 t = 0; + std::list::iterator itr = tempUnitMap.begin(); + while(itr!= tempUnitMap.end() && (*itr)->GetDistance(m_caster) < radius) + ++t, ++itr; + + if(!t) + break; + + itr = tempUnitMap.begin(); + std::advance(itr, rand()%t); + Unit *pUnitTarget = *itr; + TagUnitMap.push_back(pUnitTarget); + + tempUnitMap.erase(itr); + + tempUnitMap.sort(TargetDistanceOrder(pUnitTarget)); + + t = unMaxTargets - 1; + Unit *prev = pUnitTarget; + std::list::iterator next = tempUnitMap.begin(); + + while(t && next != tempUnitMap.end() ) + { + if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + break; + + if(!prev->IsWithinLOSInMap(*next)) + { + ++next; + continue; + } + + prev = *next; + TagUnitMap.push_back(prev); + tempUnitMap.erase(next); + tempUnitMap.sort(TargetDistanceOrder(prev)); + next = tempUnitMap.begin(); + + --t; + } + }break; + case TARGET_PET: + { + Pet* tmpUnit = m_caster->GetPet(); + if (!tmpUnit) break; + TagUnitMap.push_back(tmpUnit); + break; + } + case TARGET_CHAIN_DAMAGE: + { + if (EffectChainTarget <= 1) + { + Unit* pUnitTarget = SelectMagnetTarget(); + if(pUnitTarget) + TagUnitMap.push_back(pUnitTarget); + } + else + { + Unit* pUnitTarget = m_targets.getUnitTarget(); + if(!pUnitTarget) + break; + + unMaxTargets = EffectChainTarget; + + float max_range; + if(m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE) + max_range = radius; // + else + //FIXME: This very like horrible hack and wrong for most spells + max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; + + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + Unit* originalCaster = GetOriginalCaster(); + if(originalCaster) + { + std::list tempUnitMap; + + { + MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range); + MaNGOS::UnitListSearcher searcher(tempUnitMap, u_check); + + TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); + TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + } + + tempUnitMap.sort(TargetDistanceOrder(pUnitTarget)); + + if(tempUnitMap.empty()) + break; + + if(*tempUnitMap.begin() == pUnitTarget) + tempUnitMap.erase(tempUnitMap.begin()); + + TagUnitMap.push_back(pUnitTarget); + uint32 t = unMaxTargets - 1; + Unit *prev = pUnitTarget; + std::list::iterator next = tempUnitMap.begin(); + + while(t && next != tempUnitMap.end() ) + { + if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + break; + + if(!prev->IsWithinLOSInMap(*next)) + { + ++next; + continue; + } + + prev = *next; + TagUnitMap.push_back(prev); + tempUnitMap.erase(next); + tempUnitMap.sort(TargetDistanceOrder(prev)); + next = tempUnitMap.begin(); + + --t; + } + } + } + }break; + case TARGET_ALL_ENEMY_IN_AREA: + { + }break; + case TARGET_ALL_ENEMY_IN_AREA_INSTANT: + { + // targets the ground, not the units in the area + if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) + { + CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + + // exclude caster (this can be important if this not original caster) + TagUnitMap.remove(m_caster); + } + }break; + case TARGET_DUELVSPLAYER_COORDINATES: + { + if(Unit* currentTarget = m_targets.getUnitTarget()) + { + m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ()); + TagUnitMap.push_back(currentTarget); + } + }break; + case TARGET_ALL_PARTY_AROUND_CASTER: + case TARGET_ALL_PARTY_AROUND_CASTER_2: + case TARGET_ALL_PARTY: + { + Player *pTarget = m_caster->GetCharmerOrOwnerPlayerOrPlayerItself(); + Group *pGroup = pTarget ? pTarget->GetGroup() : NULL; + + if(pGroup) + { + uint8 subgroup = pTarget->GetSubGroup(); + + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + + // IsHostileTo check duel and controlled by enemy + if( Target && Target->GetSubGroup()==subgroup && !m_caster->IsHostileTo(Target) ) + { + if( m_caster->IsWithinDistInMap(Target, radius) ) + TagUnitMap.push_back(Target); + + if(Pet* pet = Target->GetPet()) + if( m_caster->IsWithinDistInMap(pet, radius) ) + TagUnitMap.push_back(pet); + } + } + } + else + { + Unit* ownerOrSelf = pTarget ? pTarget : m_caster->GetCharmerOrOwnerOrSelf(); + if(ownerOrSelf==m_caster || m_caster->IsWithinDistInMap(ownerOrSelf, radius)) + TagUnitMap.push_back(ownerOrSelf); + if(Pet* pet = ownerOrSelf->GetPet()) + if( m_caster->IsWithinDistInMap(pet, radius) ) + TagUnitMap.push_back(pet); + } + }break; + case TARGET_RANDOM_RAID_MEMBER: + { + if (m_caster->GetTypeId() == TYPEID_PLAYER) + if(Player* target = ((Player*)m_caster)->GetNextRandomRaidMember(radius)) + TagUnitMap.push_back(target); + }break; + case TARGET_SINGLE_FRIEND: + case TARGET_SINGLE_FRIEND_2: + { + if(m_targets.getUnitTarget()) + TagUnitMap.push_back(m_targets.getUnitTarget()); + }break; + case TARGET_NONCOMBAT_PET: + { + if(Unit* target = m_targets.getUnitTarget()) + if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET) + TagUnitMap.push_back(target); + }break; + case TARGET_ALL_AROUND_CASTER: + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_SELF_CENTER,SPELL_TARGETS_AOE_DAMAGE); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + }break; + case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_SELF_CENTER,SPELL_TARGETS_FRIENDLY); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + }break; + case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: + { + CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_FRIENDLY); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + }break; + // TARGET_SINGLE_PARTY means that the spells can only be casted on a party member and not on the caster (some sceals, fire shield from imp, etc..) + case TARGET_SINGLE_PARTY: + { + Unit *target = m_targets.getUnitTarget(); + // Thoses spells apparently can't be casted on the caster. + if( target && target != m_caster) + { + // Can only be casted on group's members or its pets + Group *pGroup = NULL; + + Unit* owner = m_caster->GetCharmerOrOwner(); + Unit *targetOwner = target->GetCharmerOrOwner(); + if(owner) + { + if(owner->GetTypeId() == TYPEID_PLAYER) + { + if( target == owner ) + { + TagUnitMap.push_back(target); + break; + } + pGroup = ((Player*)owner)->GetGroup(); + } + } + else if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + if( targetOwner == m_caster && target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isPet()) + { + TagUnitMap.push_back(target); + break; + } + pGroup = ((Player*)m_caster)->GetGroup(); + } + + if(pGroup) + { + // Our target can also be a player's pet who's grouped with us or our pet. But can't be controlled player + if(targetOwner) + { + if( targetOwner->GetTypeId() == TYPEID_PLAYER && + target->GetTypeId()==TYPEID_UNIT && (((Creature*)target)->isPet()) && + target->GetOwnerGUID()==targetOwner->GetGUID() && + pGroup->IsMember(((Player*)targetOwner)->GetGUID())) + { + TagUnitMap.push_back(target); + } + } + // 1Our target can be a player who is on our group + else if (target->GetTypeId() == TYPEID_PLAYER && pGroup->IsMember(((Player*)target)->GetGUID())) + { + TagUnitMap.push_back(target); + } + } + } + }break; + case TARGET_GAMEOBJECT: + { + if(m_targets.getGOTarget()) + AddGOTarget(m_targets.getGOTarget(), i); + }break; + case TARGET_IN_FRONT_OF_CASTER: + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + bool inFront = m_spellInfo->SpellVisual != 3879; + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, inFront ? PUSH_IN_FRONT : PUSH_IN_BACK,SPELL_TARGETS_AOE_DAMAGE); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + }break; + case TARGET_DUELVSPLAYER: + { + Unit *target = m_targets.getUnitTarget(); + if(target) + { + if(m_caster->IsFriendlyTo(target)) + { + TagUnitMap.push_back(target); + } + else + { + Unit* pUnitTarget = SelectMagnetTarget(); + if(pUnitTarget) + TagUnitMap.push_back(pUnitTarget); + } + } + }break; + case TARGET_GAMEOBJECT_ITEM: + { + if(m_targets.getGOTargetGUID()) + AddGOTarget(m_targets.getGOTarget(), i); + else if(m_targets.getItemTarget()) + AddItemTarget(m_targets.getItemTarget(), i); + break; + } + case TARGET_MASTER: + { + if(Unit* owner = m_caster->GetCharmerOrOwner()) + TagUnitMap.push_back(owner); + break; + } + case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: + { + // targets the ground, not the units in the area + if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + } + }break; + case TARGET_MINION: + { + if(m_spellInfo->Effect[i] != SPELL_EFFECT_DUEL) + TagUnitMap.push_back(m_caster); + }break; + case TARGET_SINGLE_ENEMY: + { + Unit* pUnitTarget = SelectMagnetTarget(); + if(pUnitTarget) + TagUnitMap.push_back(pUnitTarget); + }break; + case TARGET_AREAEFFECT_PARTY: + { + Unit* owner = m_caster->GetCharmerOrOwner(); + Player *pTarget = NULL; + + if(owner) + { + TagUnitMap.push_back(m_caster); + if(owner->GetTypeId() == TYPEID_PLAYER) + pTarget = (Player*)owner; + } + else if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + if(Unit* target = m_targets.getUnitTarget()) + { + if( target->GetTypeId() != TYPEID_PLAYER) + { + if(((Creature*)target)->isPet()) + { + Unit *targetOwner = target->GetOwner(); + if(targetOwner->GetTypeId() == TYPEID_PLAYER) + pTarget = (Player*)targetOwner; + } + } + else + pTarget = (Player*)target; + } + } + + Group* pGroup = pTarget ? pTarget->GetGroup() : NULL; + + if(pGroup) + { + uint8 subgroup = pTarget->GetSubGroup(); + + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + + // IsHostileTo check duel and controlled by enemy + if(Target && Target->GetSubGroup()==subgroup && !m_caster->IsHostileTo(Target)) + { + if( pTarget->IsWithinDistInMap(Target, radius) ) + TagUnitMap.push_back(Target); + + if(Pet* pet = Target->GetPet()) + if( pTarget->IsWithinDistInMap(pet, radius) ) + TagUnitMap.push_back(pet); + } + } + } + else if (owner) + { + if(m_caster->IsWithinDistInMap(owner, radius)) + TagUnitMap.push_back(owner); + } + else if(pTarget) + { + TagUnitMap.push_back(pTarget); + + if(Pet* pet = pTarget->GetPet()) + if( m_caster->IsWithinDistInMap(pet, radius) ) + TagUnitMap.push_back(pet); + } + + }break; + case TARGET_SCRIPT: + { + if(m_targets.getUnitTarget()) + TagUnitMap.push_back(m_targets.getUnitTarget()); + if(m_targets.getItemTarget()) + AddItemTarget(m_targets.getItemTarget(), i); + }break; + case TARGET_SELF_FISHING: + { + TagUnitMap.push_back(m_caster); + }break; + case TARGET_CHAIN_HEAL: + { + Unit* pUnitTarget = m_targets.getUnitTarget(); + if(!pUnitTarget) + break; + + if (EffectChainTarget <= 1) + TagUnitMap.push_back(pUnitTarget); + else + { + unMaxTargets = EffectChainTarget; + float max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; + + std::list tempUnitMap; + + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, tempUnitMap, max_range, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + + } + + if(m_caster != pUnitTarget && std::find(tempUnitMap.begin(),tempUnitMap.end(),m_caster) == tempUnitMap.end() ) + tempUnitMap.push_front(m_caster); + + tempUnitMap.sort(TargetDistanceOrder(pUnitTarget)); + + if(tempUnitMap.empty()) + break; + + if(*tempUnitMap.begin() == pUnitTarget) + tempUnitMap.erase(tempUnitMap.begin()); + + TagUnitMap.push_back(pUnitTarget); + uint32 t = unMaxTargets - 1; + Unit *prev = pUnitTarget; + std::list::iterator next = tempUnitMap.begin(); + + while(t && next != tempUnitMap.end() ) + { + if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + break; + + if(!prev->IsWithinLOSInMap(*next)) + { + ++next; + continue; + } + + if((*next)->GetHealth() == (*next)->GetMaxHealth()) + { + next = tempUnitMap.erase(next); + continue; + } + + prev = *next; + TagUnitMap.push_back(prev); + tempUnitMap.erase(next); + tempUnitMap.sort(TargetDistanceOrder(prev)); + next = tempUnitMap.begin(); + + --t; + } + } + }break; + case TARGET_CURRENT_ENEMY_COORDINATES: + { + Unit* currentTarget = m_targets.getUnitTarget(); + if(currentTarget) + { + TagUnitMap.push_back(currentTarget); + m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ()); + if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA_INSTANT) + { + CellPair p(MaNGOS::ComputeCellPair(currentTarget->GetPositionX(), currentTarget->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius,PUSH_TARGET_CENTER, SPELL_TARGETS_AOE_DAMAGE); + TypeContainerVisitor world_notifier(notifier); + TypeContainerVisitor grid_notifier(notifier); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + } + } + }break; + case TARGET_AREAEFFECT_PARTY_AND_CLASS: + { + Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER + ? (Player*)m_targets.getUnitTarget() : NULL; + + Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL; + if(pGroup) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + + // IsHostileTo check duel and controlled by enemy + if( Target && targetPlayer->IsWithinDistInMap(Target, radius) && + targetPlayer->getClass() == Target->getClass() && + !m_caster->IsHostileTo(Target) ) + { + TagUnitMap.push_back(Target); + } + } + } + else if(m_targets.getUnitTarget()) + TagUnitMap.push_back(m_targets.getUnitTarget()); + break; + } + case TARGET_TABLE_X_Y_Z_COORDINATES: + { + SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id); + if(st) + { + if (st->target_mapId == m_caster->GetMapId()) + m_targets.setDestination(st->target_X, st->target_Y, st->target_Z); + + // if B==TARGET_TABLE_X_Y_Z_COORDINATES then A already fill all required targets + if (m_spellInfo->EffectImplicitTargetB[i] && m_spellInfo->EffectImplicitTargetB[i]!=TARGET_TABLE_X_Y_Z_COORDINATES) + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + SpellTargets targetB = SPELL_TARGETS_AOE_DAMAGE; + // Select friendly targets for positive effect + if (IsPositiveEffect(m_spellInfo->Id, i)) + targetB = SPELL_TARGETS_FRIENDLY; + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius,PUSH_DEST_CENTER, targetB); + + TypeContainerVisitor world_notifier(notifier); + TypeContainerVisitor grid_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + cell_lock->Visit(cell_lock, grid_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + } + } + else + sLog.outError( "SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id ); + }break; + case TARGET_BEHIND_VICTIM: + { + Unit *pTarget = m_caster->getVictim(); + if(!pTarget && m_caster->GetTypeId() == TYPEID_PLAYER) + pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection()); + + if(pTarget) + { + float _target_x, _target_y, _target_z; + pTarget->GetClosePoint(_target_x, _target_y, _target_z, m_caster->GetObjectSize(), CONTACT_DISTANCE, M_PI); + if(pTarget->IsWithinLOS(_target_x,_target_y,_target_z)) + m_targets.setDestination(_target_x, _target_y, _target_z); + } + }break; + default: + break; + } + + if (unMaxTargets && TagUnitMap.size() > unMaxTargets) + { + // make sure one unit is always removed per iteration + uint32 removed_utarget = 0; + for (std::list::iterator itr = TagUnitMap.begin(), next; itr != TagUnitMap.end(); itr = next) + { + next = itr; + ++next; + if (!*itr) continue; + if ((*itr) == m_targets.getUnitTarget()) + { + TagUnitMap.erase(itr); + removed_utarget = 1; + // break; + } + } + // remove random units from the map + while (TagUnitMap.size() > unMaxTargets - removed_utarget) + { + uint32 poz = urand(0, TagUnitMap.size()-1); + for (std::list::iterator itr = TagUnitMap.begin(); itr != TagUnitMap.end(); ++itr, --poz) + { + if (!*itr) continue; + if (!poz) + { + TagUnitMap.erase(itr); + break; + } + } + } + // the player's target will always be added to the map + if (removed_utarget && m_targets.getUnitTarget()) + TagUnitMap.push_back(m_targets.getUnitTarget()); + } +} + +void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura) +{ + m_targets = *targets; + + m_spellState = SPELL_STATE_PREPARING; + + m_castPositionX = m_caster->GetPositionX(); + m_castPositionY = m_caster->GetPositionY(); + m_castPositionZ = m_caster->GetPositionZ(); + m_castOrientation = m_caster->GetOrientation(); + + if(triggeredByAura) + m_triggeredByAuraSpell = triggeredByAura->GetSpellProto(); + + // create and add update event for this spell + SpellEvent* Event = new SpellEvent(this); + m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1)); + + //Prevent casting at cast another spell (ServerSide check) + if(m_caster->IsNonMeleeSpellCasted(false, true) && m_cast_count) + { + SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS); + finish(false); + return; + } + + // Fill cost data + m_powerCost = CalculatePowerCost(); + + uint8 result = CanCast(true); + if(result != 0 && !IsAutoRepeat()) //always cast autorepeat dummy for triggering + { + if(triggeredByAura) + { + SendChannelUpdate(0); + triggeredByAura->SetAuraDuration(0); + } + SendCastResult(result); + finish(false); + return; + } + + // calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail) + m_casttime = GetSpellCastTime(m_spellInfo, this); + + // set timer base at cast time + ReSetTimer(); + + // stealth must be removed at cast starting (at show channel bar) + // skip triggered spell (item equip spell casting and other not explicit character casts/item uses) + if ( !m_IsTriggeredSpell && isSpellBreakStealth(m_spellInfo) ) + { + m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + m_caster->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + } + + if(m_IsTriggeredSpell) + cast(true); + else + { + m_caster->SetCurrentCastedSpell( this ); + m_selfContainer = &(m_caster->m_currentSpells[GetCurrentContainer()]); + SendSpellStart(); + } +} + +void Spell::cancel() +{ + if(m_spellState == SPELL_STATE_FINISHED) + return; + + m_autoRepeat = false; + switch (m_spellState) + { + case SPELL_STATE_PREPARING: + case SPELL_STATE_DELAYED: + { + SendInterrupted(0); + SendCastResult(SPELL_FAILED_INTERRUPTED); + } break; + + case SPELL_STATE_CASTING: + { + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + if( ihit->missCondition == SPELL_MISS_NONE ) + { + Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); + if( unit && unit->isAlive() ) + unit->RemoveAurasDueToSpell(m_spellInfo->Id); + } + } + + m_caster->RemoveAurasDueToSpell(m_spellInfo->Id); + SendChannelUpdate(0); + SendInterrupted(0); + SendCastResult(SPELL_FAILED_INTERRUPTED); + } break; + + default: + { + } break; + } + + finish(false); + m_caster->RemoveDynObject(m_spellInfo->Id); + m_caster->RemoveGameObject(m_spellInfo->Id,true); +} + +void Spell::cast(bool skipCheck) +{ + uint8 castResult = 0; + + // update pointers base at GUIDs to prevent access to non-existed already object + UpdatePointers(); + + // cancel at lost main target unit + if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID()) + { + cancel(); + return; + } + + if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster) + m_caster->SetInFront(m_targets.getUnitTarget()); + + castResult = CheckPower(); + if(castResult != 0) + { + SendCastResult(castResult); + finish(false); + return; + } + + // triggered cast called from Spell::prepare where it was already checked + if(!skipCheck) + { + castResult = CanCast(false); + if(castResult != 0) + { + SendCastResult(castResult); + finish(false); + return; + } + } + + // Conflagrate - consumes immolate + if ((m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE) && m_targets.getUnitTarget()) + { + // for caster applied auras only + Unit::AuraList const &mPeriodic = m_targets.getUnitTarget()->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i) + { + if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) && + (*i)->GetCasterGUID()==m_caster->GetGUID() ) + { + m_targets.getUnitTarget()->RemoveAura((*i)->GetId(), (*i)->GetEffIndex()); + break; + } + } + } + + // traded items have trade slot instead of guid in m_itemTargetGUID + // set to real guid to be sent later to the client + m_targets.updateTradeSlotItem(); + + // CAST SPELL + SendSpellCooldown(); + + TakePower(); + TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot + FillTargetMap(); + + if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap + return; + + SendCastResult(castResult); + SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... + + // Pass cast spell event to handler (not send triggered by aura spells) + if (m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_RANGED && !m_triggeredByAuraSpell) + { + m_caster->ProcDamageAndSpell(m_targets.getUnitTarget(), PROC_FLAG_CAST_SPELL, PROC_FLAG_NONE, 0, SPELL_SCHOOL_MASK_NONE, m_spellInfo, m_IsTriggeredSpell); + + // update pointers base at GUIDs to prevent access to non-existed already object + UpdatePointers(); // pointers can be invalidate at triggered spell casting + } + + // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells + if (m_spellInfo->speed > 0.0f) + { + + // Remove used for cast item if need (it can be already NULL after TakeReagents call + // in case delayed spell remove item at cast delay start + TakeCastItem(); + + // Okay, maps created, now prepare flags + m_immediateHandled = false; + m_spellState = SPELL_STATE_DELAYED; + SetDelayStart(0); + } + else + { + // Immediate spell, no big deal + handle_immediate(); + } +} + +void Spell::handle_immediate() +{ + // start channeling if applicable + if(IsChanneledSpell(m_spellInfo)) + { + m_spellState = SPELL_STATE_CASTING; + SendChannelStart(GetSpellDuration(m_spellInfo)); + } + + // process immediate effects (items, ground, etc.) also initialize some variables + _handle_immediate_phase(); + + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + DoAllEffectOnTarget(&(*ihit)); + + for(std::list::iterator ihit= m_UniqueGOTargetInfo.begin();ihit != m_UniqueGOTargetInfo.end();++ihit) + DoAllEffectOnTarget(&(*ihit)); + + // spell is finished, perform some last features of the spell here + _handle_finish_phase(); + + // Remove used for cast item if need (it can be already NULL after TakeReagents call + TakeCastItem(); + + if(m_spellState != SPELL_STATE_CASTING) + finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell) +} + +uint64 Spell::handle_delayed(uint64 t_offset) +{ + uint64 next_time = 0; + + if (!m_immediateHandled) + { + _handle_immediate_phase(); + m_immediateHandled = true; + } + + // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases) + for(std::list::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();++ihit) + { + if (ihit->processed == false) + { + if ( ihit->timeDelay <= t_offset ) + DoAllEffectOnTarget(&(*ihit)); + else if( next_time == 0 || ihit->timeDelay < next_time ) + next_time = ihit->timeDelay; + } + } + + // now recheck gameobject targeting correctness + for(std::list::iterator ighit= m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end();++ighit) + { + if (ighit->processed == false) + { + if ( ighit->timeDelay <= t_offset ) + DoAllEffectOnTarget(&(*ighit)); + else if( next_time == 0 || ighit->timeDelay < next_time ) + next_time = ighit->timeDelay; + } + } + // All targets passed - need finish phase + if (next_time == 0) + { + // spell is finished, perform some last features of the spell here + _handle_finish_phase(); + + finish(true); // successfully finish spell cast + + // return zero, spell is finished now + return 0; + } + else + { + // spell is unfinished, return next execution time + return next_time; + } +} + +void Spell::_handle_immediate_phase() +{ + // handle some immediate features of the spell here + HandleThreatSpells(m_spellInfo->Id); + + m_needSpellLog = IsNeedSendToClient(); + for(uint32 j = 0;j<3;j++) + { + if(m_spellInfo->Effect[j]==0) + continue; + + // apply Send Event effect to ground in case empty target lists + if( m_spellInfo->Effect[j] == SPELL_EFFECT_SEND_EVENT && !HaveTargetsForEffect(j) ) + { + HandleEffects(NULL,NULL,NULL, j); + continue; + } + + // Don't do spell log, if is school damage spell + if(m_spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || m_spellInfo->Effect[j] == 0) + m_needSpellLog = false; + + uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[j]; + if(m_originalCaster) + if(Player* modOwner = m_originalCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this); + + // initialize multipliers + m_damageMultipliers[j] = 1.0f; + if( (m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_HEAL) && + (EffectChainTarget > 1) ) + m_applyMultiplierMask |= 1 << j; + } + + // initialize Diminishing Returns Data + m_diminishLevel = DIMINISHING_LEVEL_1; + m_diminishGroup = DIMINISHING_NONE; + + // process items + for(std::list::iterator ihit= m_UniqueItemInfo.begin();ihit != m_UniqueItemInfo.end();++ihit) + DoAllEffectOnTarget(&(*ihit)); + + // process ground + for(uint32 j = 0;j<3;j++) + { + // persistent area auras target only the ground + if(m_spellInfo->Effect[j] == SPELL_EFFECT_PERSISTENT_AREA_AURA) + HandleEffects(NULL,NULL,NULL, j); + } +} + +void Spell::_handle_finish_phase() +{ + // spell log + if(m_needSpellLog) + SendLogExecute(); +} + +void Spell::SendSpellCooldown() +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player* _player = (Player*)m_caster; + // Add cooldown for max (disable spell) + // Cooldown started on SendCooldownEvent call + if (m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + { + _player->AddSpellCooldown(m_spellInfo->Id, 0, time(NULL) - 1); + return; + } + + // init cooldown values + uint32 cat = 0; + int32 rec = -1; + int32 catrec = -1; + + // some special item spells without correct cooldown in SpellInfo + // cooldown information stored in item prototype + // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client. + + if(m_CastItem) + { + ItemPrototype const* proto = m_CastItem->GetProto(); + if(proto) + { + for(int idx = 0; idx < 5; ++idx) + { + if(proto->Spells[idx].SpellId == m_spellInfo->Id) + { + cat = proto->Spells[idx].SpellCategory; + rec = proto->Spells[idx].SpellCooldown; + catrec = proto->Spells[idx].SpellCategoryCooldown; + break; + } + } + } + } + + // if no cooldown found above then base at DBC data + if(rec < 0 && catrec < 0) + { + cat = m_spellInfo->Category; + rec = m_spellInfo->RecoveryTime; + catrec = m_spellInfo->CategoryRecoveryTime; + } + + // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK) + // prevent 0 cooldowns set by another way + if (rec <= 0 && catrec <= 0 && (cat == 76 || cat == 351)) + rec = _player->GetAttackTime(RANGED_ATTACK); + + // Now we have cooldown data (if found any), time to apply mods + if(rec > 0) + _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec, this); + + if(catrec > 0) + _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec, this); + + // replace negative cooldowns by 0 + if (rec < 0) rec = 0; + if (catrec < 0) catrec = 0; + + // no cooldown after applying spell mods + if( rec == 0 && catrec == 0) + return; + + time_t curTime = time(NULL); + + time_t catrecTime = catrec ? curTime+catrec/1000 : 0; // in secs + time_t recTime = rec ? curTime+rec/1000 : catrecTime;// in secs + + // self spell cooldown + if(recTime > 0) + _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, recTime); + + // category spells + if (catrec > 0) + { + SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat); + if(i_scstore != sSpellCategoryStore.end()) + { + for(SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset) + { + if(*i_scset == m_spellInfo->Id) // skip main spell, already handled above + continue; + + _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime); + } + } + } +} + +void Spell::update(uint32 difftime) +{ + // update pointers based at it's GUIDs + UpdatePointers(); + + if(m_targets.getUnitTargetGUID() && !m_targets.getUnitTarget()) + { + cancel(); + return; + } + + // check if the player caster has moved before the spell finished + if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && + (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && + (m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING))) + { + // always cancel for channeled spells + if( m_spellState == SPELL_STATE_CASTING ) + cancel(); + // don't cancel for melee, autorepeat, triggered and instant spells + else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) + cancel(); + } + + switch(m_spellState) + { + case SPELL_STATE_PREPARING: + { + if(m_timer) + { + if(difftime >= m_timer) + m_timer = 0; + else + m_timer -= difftime; + } + + if(m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat()) + cast(); + } break; + case SPELL_STATE_CASTING: + { + if(m_timer > 0) + { + if( m_caster->GetTypeId() == TYPEID_PLAYER ) + { + // check if player has jumped before the channeling finished + if(m_caster->HasUnitMovementFlag(MOVEMENTFLAG_JUMPING)) + cancel(); + + // check for incapacitating player states + if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED)) + cancel(); + + // check if player has turned if flag is set + if( m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation() ) + cancel(); + } + + // check if there are alive targets left + if (!IsAliveUnitPresentInTargetList()) + { + SendChannelUpdate(0); + finish(); + } + + if(difftime >= m_timer) + m_timer = 0; + else + m_timer -= difftime; + } + + if(m_timer == 0) + { + SendChannelUpdate(0); + + // channeled spell processed independently for quest targeting + // cast at creature (or GO) quest objectives update at successful cast channel finished + // ignore autorepeat/melee casts for speed (not exist quest for spells (hm... ) + if( m_caster->GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsNextMeleeSwingSpell() ) + { + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + TargetInfo* target = &*ihit; + if(!IS_CREATURE_GUID(target->targetGUID)) + continue; + + Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID); + if (unit==NULL) + continue; + + ((Player*)m_caster)->CastedCreatureOrGO(unit->GetEntry(),unit->GetGUID(),m_spellInfo->Id); + } + + for(std::list::iterator ihit= m_UniqueGOTargetInfo.begin();ihit != m_UniqueGOTargetInfo.end();++ihit) + { + GOTargetInfo* target = &*ihit; + + GameObject* go = ObjectAccessor::GetGameObject(*m_caster, target->targetGUID); + if(!go) + continue; + + ((Player*)m_caster)->CastedCreatureOrGO(go->GetEntry(),go->GetGUID(),m_spellInfo->Id); + } + } + + finish(); + } + } break; + default: + { + }break; + } +} + +void Spell::finish(bool ok) +{ + if(!m_caster) + return; + + if(m_spellState == SPELL_STATE_FINISHED) + return; + + m_spellState = SPELL_STATE_FINISHED; + + //remove spell mods + if (m_caster->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_caster)->RemoveSpellMods(this); + + // other code related only to successfully finished spells + if(!ok) + return; + + //handle SPELL_AURA_ADD_TARGET_TRIGGER auras + Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER); + for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i) + { + SpellEntry const *auraSpellInfo = (*i)->GetSpellProto(); + uint32 auraSpellIdx = (*i)->GetEffIndex(); + if (IsAffectedBy(auraSpellInfo, auraSpellIdx)) + { + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + if( ihit->effectMask & (1<GetGUID() let load auras at login and speedup most often case + Unit *unit = m_caster->GetGUID()== ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); + if (unit && unit->isAlive()) + { + // Calculate chance at that moment (can be depend for example from combo points) + int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(),unit); + + if(roll_chance_i(chance)) + m_caster->CastSpell(unit, auraSpellInfo->EffectTriggerSpell[auraSpellIdx], true, NULL, (*i)); + } + } + } + } + + if (IsMeleeAttackResetSpell()) + { + m_caster->resetAttackTimer(BASE_ATTACK); + if(m_caster->haveOffhandWeapon()) + m_caster->resetAttackTimer(OFF_ATTACK); + } + + /*if (IsRangedAttackResetSpell()) + m_caster->resetAttackTimer(RANGED_ATTACK);*/ + + // Clear combo at finish state + if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo)) + ((Player*)m_caster)->ClearComboPoints(); + + // call triggered spell only at successful cast (after clear combo points -> for add some if need) + if(!m_TriggerSpells.empty()) + TriggerSpell(); + + // Stop Attack for some spells + if( m_spellInfo->Attributes & SPELL_ATTR_STOP_ATTACK_TARGET ) + m_caster->AttackStop(); +} + +void Spell::SendCastResult(uint8 result) +{ + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time + return; + + if(result != 0) + { + WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); + data << uint32(m_spellInfo->Id); + data << uint8(result); // problem + data << uint8(m_cast_count); // single cast or multi 2.3 (0/1) + switch (result) + { + case SPELL_FAILED_REQUIRES_SPELL_FOCUS: + data << uint32(m_spellInfo->RequiresSpellFocus); + break; + case SPELL_FAILED_REQUIRES_AREA: + // hardcode areas limitation case + if( m_spellInfo->Id==41618 || m_spellInfo->Id==41620 ) + data << uint32(3842); + else if( m_spellInfo->Id==41617 || m_spellInfo->Id==41619 ) + data << uint32(3905); + // normal case + else + data << uint32(m_spellInfo->AreaId); + break; + case SPELL_FAILED_TOTEMS: + if(m_spellInfo->Totem[0]) + data << uint32(m_spellInfo->Totem[0]); + if(m_spellInfo->Totem[1]) + data << uint32(m_spellInfo->Totem[1]); + break; + case SPELL_FAILED_TOTEM_CATEGORY: + if(m_spellInfo->TotemCategory[0]) + data << uint32(m_spellInfo->TotemCategory[0]); + if(m_spellInfo->TotemCategory[1]) + data << uint32(m_spellInfo->TotemCategory[1]); + break; + case SPELL_FAILED_EQUIPPED_ITEM_CLASS: + data << uint32(m_spellInfo->EquippedItemClass); + data << uint32(m_spellInfo->EquippedItemSubClassMask); + data << uint32(m_spellInfo->EquippedItemInventoryTypeMask); + break; + } + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + else + { + WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4)); + data.append(m_caster->GetPackGUID()); + data << uint32(m_spellInfo->Id); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } +} + +void Spell::SendSpellStart() +{ + if(!IsNeedSendToClient()) + return; + + sLog.outDebug("Sending SMSG_SPELL_START id=%u",m_spellInfo->Id); + + uint16 castFlags = CAST_FLAG_UNKNOWN1; + if(IsRangedSpell()) + castFlags |= CAST_FLAG_AMMO; + + Unit * target; + if(!m_targets.getUnitTarget()) + target = m_caster; + else + target = m_targets.getUnitTarget(); + + WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2)); + if(m_CastItem) + data.append(m_CastItem->GetPackGUID()); + else + data.append(m_caster->GetPackGUID()); + + data.append(m_caster->GetPackGUID()); + data << uint32(m_spellInfo->Id); + data << uint8(m_cast_count); // single cast or multi 2.3 (0/1) + data << uint16(castFlags); + data << uint32(m_timer); + + m_targets.write(&data); + + if( castFlags & CAST_FLAG_AMMO ) + WriteAmmoToPacket(&data); + + m_caster->SendMessageToSet(&data, true); +} + +void Spell::SendSpellGo() +{ + // not send invisible spell casting + if(!IsNeedSendToClient()) + return; + + sLog.outDebug("Sending SMSG_SPELL_GO id=%u",m_spellInfo->Id); + + Unit * target; + if(!m_targets.getUnitTarget()) + target = m_caster; + else + target = m_targets.getUnitTarget(); + + uint16 castFlags = CAST_FLAG_UNKNOWN3; + if(IsRangedSpell()) + castFlags |= CAST_FLAG_AMMO; + + WorldPacket data(SMSG_SPELL_GO, 50); // guess size + if(m_CastItem) + data.append(m_CastItem->GetPackGUID()); + else + data.append(m_caster->GetPackGUID()); + + data.append(m_caster->GetPackGUID()); + data << uint32(m_spellInfo->Id); + data << uint16(castFlags); + data << uint32(getMSTime()); // timestamp + + WriteSpellGoTargets(&data); + + m_targets.write(&data); + + if( castFlags & CAST_FLAG_AMMO ) + WriteAmmoToPacket(&data); + + m_caster->SendMessageToSet(&data, true); +} + +void Spell::WriteAmmoToPacket( WorldPacket * data ) +{ + uint32 ammoInventoryType = 0; + uint32 ammoDisplayID = 0; + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK ); + if(pItem) + { + ammoInventoryType = pItem->GetProto()->InventoryType; + if( ammoInventoryType == INVTYPE_THROWN ) + ammoDisplayID = pItem->GetProto()->DisplayInfoID; + else + { + uint32 ammoID = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID); + if(ammoID) + { + ItemPrototype const *pProto = objmgr.GetItemPrototype( ammoID ); + if(pProto) + { + ammoDisplayID = pProto->DisplayInfoID; + ammoInventoryType = pProto->InventoryType; + } + } + else if(m_caster->GetDummyAura(46699)) // Requires No Ammo + { + ammoDisplayID = 5996; // normal arrow + ammoInventoryType = INVTYPE_AMMO; + } + } + } + } + // TODO: implement selection ammo data based at ranged weapon stored in equipmodel/equipinfo/equipslot fields + + *data << uint32(ammoDisplayID); + *data << uint32(ammoInventoryType); +} + +void Spell::WriteSpellGoTargets( WorldPacket * data ) +{ + *data << (uint8)m_countOfHit; + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits + *data << uint64(ihit->targetGUID); + + for(std::list::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit) + *data << uint64(ighit->targetGUID); // Always hits + + *data << (uint8)m_countOfMiss; + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss + { + *data << uint64(ihit->targetGUID); + *data << uint8(ihit->missCondition); + if( ihit->missCondition == SPELL_MISS_REFLECT ) + *data << uint8(ihit->reflectResult); + } + } +} + +void Spell::SendLogExecute() +{ + Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster; + + WorldPacket data(SMSG_SPELLLOGEXECUTE, (8+4+4+4+4+8)); + + if(m_caster->GetTypeId() == TYPEID_PLAYER) + data.append(m_caster->GetPackGUID()); + else + data.append(target->GetPackGUID()); + + data << uint32(m_spellInfo->Id); + uint32 count1 = 1; + data << uint32(count1); // count1 (effect count?) + for(uint32 i = 0; i < count1; ++i) + { + data << uint32(m_spellInfo->Effect[0]); // spell effect? + uint32 count2 = 1; + data << uint32(count2); // count2 (target count?) + for(uint32 j = 0; j < count2; ++j) + { + switch(m_spellInfo->Effect[0]) + { + case SPELL_EFFECT_POWER_DRAIN: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); + data << uint32(0); + data << float(0); + break; + case SPELL_EFFECT_ADD_EXTRA_ATTACKS: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); // count? + break; + case SPELL_EFFECT_INTERRUPT_CAST: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); // spellid + break; + case SPELL_EFFECT_DURABILITY_DAMAGE: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); + data << uint32(0); + break; + case SPELL_EFFECT_OPEN_LOCK: + case SPELL_EFFECT_OPEN_LOCK_ITEM: + if(Item *item = m_targets.getItemTarget()) + data.append(item->GetPackGUID()); + else + data << uint8(0); + break; + case SPELL_EFFECT_CREATE_ITEM: + data << uint32(m_spellInfo->EffectItemType[0]); + break; + case SPELL_EFFECT_SUMMON: + case SPELL_EFFECT_SUMMON_WILD: + case SPELL_EFFECT_SUMMON_GUARDIAN: + case SPELL_EFFECT_TRANS_DOOR: + case SPELL_EFFECT_SUMMON_PET: + case SPELL_EFFECT_SUMMON_POSSESSED: + case SPELL_EFFECT_SUMMON_TOTEM: + case SPELL_EFFECT_SUMMON_OBJECT_WILD: + case SPELL_EFFECT_CREATE_HOUSE: + case SPELL_EFFECT_DUEL: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: + case SPELL_EFFECT_SUMMON_PHANTASM: + case SPELL_EFFECT_SUMMON_CRITTER: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: + case SPELL_EFFECT_SUMMON_DEMON: + case SPELL_EFFECT_150: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else if(m_targets.getItemTargetGUID()) + data.appendPackGUID(m_targets.getItemTargetGUID()); + else if(GameObject *go = m_targets.getGOTarget()) + data.append(go->GetPackGUID()); + else + data << uint8(0); // guid + break; + case SPELL_EFFECT_FEED_PET: + data << uint32(m_targets.getItemTargetEntry()); + break; + case SPELL_EFFECT_DISMISS_PET: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + break; + default: + return; + } + } + } + + m_caster->SendMessageToSet(&data, true); +} + +void Spell::SendInterrupted(uint8 result) +{ + WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1)); + data.append(m_caster->GetPackGUID()); + data << m_spellInfo->Id; + data << result; + m_caster->SendMessageToSet(&data, true); + + data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4)); + data.append(m_caster->GetPackGUID()); + data << m_spellInfo->Id; + m_caster->SendMessageToSet(&data, true); +} + +void Spell::SendChannelUpdate(uint32 time) +{ + if(time == 0) + { + m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,0); + m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL,0); + } + + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data( MSG_CHANNEL_UPDATE, 8+4 ); + data.append(m_caster->GetPackGUID()); + data << time; + + ((Player*)m_caster)->GetSession()->SendPacket( &data ); +} + +void Spell::SendChannelStart(uint32 duration) +{ + WorldObject* target = NULL; + + // select first not rsusted target from target list for _0_ effect + if(!m_UniqueTargetInfo.empty()) + { + for(std::list::iterator itr= m_UniqueTargetInfo.begin();itr != m_UniqueTargetInfo.end();++itr) + { + if( (itr->effectMask & (1<<0)) && itr->reflectResult==SPELL_MISS_NONE && itr->targetGUID != m_caster->GetGUID()) + { + target = ObjectAccessor::GetUnit(*m_caster, itr->targetGUID); + break; + } + } + } + else if(!m_UniqueGOTargetInfo.empty()) + { + for(std::list::iterator itr= m_UniqueGOTargetInfo.begin();itr != m_UniqueGOTargetInfo.end();++itr) + { + if(itr->effectMask & (1<<0) ) + { + target = ObjectAccessor::GetGameObject(*m_caster, itr->targetGUID); + break; + } + } + } + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data( MSG_CHANNEL_START, (8+4+4) ); + data.append(m_caster->GetPackGUID()); + data << m_spellInfo->Id; + data << duration; + + ((Player*)m_caster)->GetSession()->SendPacket( &data ); + } + + m_timer = duration; + if(target) + m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID()); + m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellInfo->Id); +} + +void Spell::SendResurrectRequest(Player* target) +{ + WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+2+4)); + data << m_caster->GetGUID(); + data << uint32(1) << uint16(0) << uint32(1); + + target->GetSession()->SendPacket(&data); +} + +void Spell::SendPlaySpellVisual(uint32 SpellID) +{ + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); + data << m_caster->GetGUID(); + data << SpellID; + ((Player*)m_caster)->GetSession()->SendPacket(&data); +} + +void Spell::TakeCastItem() +{ + if(!m_CastItem || m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + // not remove cast item at triggered spell (equipping, weapon damage, etc) + if(m_IsTriggeredSpell) + return; + + ItemPrototype const *proto = m_CastItem->GetProto(); + + if(!proto) + { + // This code is to avoid a crash + // I'm not sure, if this is really an error, but I guess every item needs a prototype + sLog.outError("Cast item has no item prototype highId=%d, lowId=%d",m_CastItem->GetGUIDHigh(), m_CastItem->GetGUIDLow()); + return; + } + + bool expendable = false; + bool withoutCharges = false; + + for (int i = 0; i<5; i++) + { + if (proto->Spells[i].SpellId) + { + // item has limited charges + if (proto->Spells[i].SpellCharges) + { + if (proto->Spells[i].SpellCharges < 0) + expendable = true; + + int32 charges = m_CastItem->GetSpellCharges(i); + + // item has charges left + if (charges) + { + (charges > 0) ? --charges : ++charges; // abs(charges) less at 1 after use + if (proto->Stackable < 2) + m_CastItem->SetSpellCharges(i, charges); + m_CastItem->SetState(ITEM_CHANGED, (Player*)m_caster); + } + + // all charges used + withoutCharges = (charges == 0); + } + } + } + + if (expendable && withoutCharges) + { + uint32 count = 1; + ((Player*)m_caster)->DestroyItemCount(m_CastItem, count, true); + + // prevent crash at access to deleted m_targets.getItemTarget + if(m_CastItem==m_targets.getItemTarget()) + m_targets.setItemTarget(NULL); + + m_CastItem = NULL; + } +} + +void Spell::TakePower() +{ + if(m_CastItem || m_triggeredByAuraSpell) + return; + + // health as power used + if(m_spellInfo->powerType == POWER_HEALTH) + { + m_caster->ModifyHealth( -(int32)m_powerCost ); + return; + } + + if(m_spellInfo->powerType >= MAX_POWERS) + { + sLog.outError("Spell::TakePower: Unknown power type '%d'", m_spellInfo->powerType); + return; + } + + Powers powerType = Powers(m_spellInfo->powerType); + + m_caster->ModifyPower(powerType, -(int32)m_powerCost); + + // Set the five second timer + if (powerType == POWER_MANA && m_powerCost > 0) + m_caster->SetLastManaUse(getMSTime()); +} + +void Spell::TakeReagents() +{ + if(m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed. + return; + + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && + m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) + return; + + Player* p_caster = (Player*)m_caster; + + for(uint32 x=0;x<8;x++) + { + if(m_spellInfo->Reagent[x] <= 0) + continue; + + uint32 itemid = m_spellInfo->Reagent[x]; + uint32 itemcount = m_spellInfo->ReagentCount[x]; + + // if CastItem is also spell reagent + if (m_CastItem) + { + ItemPrototype const *proto = m_CastItem->GetProto(); + if( proto && proto->ItemId == itemid ) + { + for(int s=0;s<5;s++) + { + // CastItem will be used up and does not count as reagent + int32 charges = m_CastItem->GetSpellCharges(s); + if (proto->Spells[s].SpellCharges < 0 && abs(charges) < 2) + { + ++itemcount; + break; + } + } + + m_CastItem = NULL; + } + } + + // if getItemTarget is also spell reagent + if (m_targets.getItemTargetEntry()==itemid) + m_targets.setItemTarget(NULL); + + p_caster->DestroyItemCount(itemid, itemcount, true); + } +} + +void Spell::HandleThreatSpells(uint32 spellId) +{ + if(!m_targets.getUnitTarget() || !spellId) + return; + + if(!m_targets.getUnitTarget()->CanHaveThreatList()) + return; + + SpellThreatEntry const *threatSpell = sSpellThreatStore.LookupEntry(spellId); + if(!threatSpell) + return; + + m_targets.getUnitTarget()->AddThreat(m_caster, float(threatSpell->threat)); + + DEBUG_LOG("Spell %u, rank %u, added an additional %i threat", spellId, spellmgr.GetSpellRank(spellId), threatSpell->threat); +} + +void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float DamageMultiplier) +{ + unitTarget = pUnitTarget; + itemTarget = pItemTarget; + gameObjTarget = pGOTarget; + + uint8 eff = m_spellInfo->Effect[i]; + uint32 mechanic = m_spellInfo->EffectMechanic[i]; + + damage = int32(CalculateDamage((uint8)i,unitTarget)*DamageMultiplier); + + sLog.outDebug( "Spell: Effect : %u", eff); + + //Simply return. Do not display "immune" in red text on client + if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic)) + return; + + if(eff TOTAL_SPELL_EFFECTS ", eff); + if (m_CastItem) + EffectEnchantItemTmp(i); + else + { + sLog.outError("SPELL: unknown effect %u spell id %u\n", + eff, m_spellInfo->Id); + } + } + */ +} + +void Spell::TriggerSpell() +{ + for(TriggerSpells::iterator si=m_TriggerSpells.begin(); si!=m_TriggerSpells.end(); ++si) + { + Spell* spell = new Spell(m_caster, (*si), true, m_originalCasterGUID, this->m_selfContainer); + spell->prepare(&m_targets); // use original spell original targets + } +} + +uint8 Spell::CanCast(bool strict) +{ + // check cooldowns to prevent cheating + if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id)) + { + if(m_triggeredByAuraSpell) + return SPELL_FAILED_DONT_REPORT; + else + return SPELL_FAILED_NOT_READY; + } + + // only allow triggered spells if at an ended battleground + if( !m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER) + if(BattleGround * bg = ((Player*)m_caster)->GetBattleGround()) + if(bg->GetStatus() == STATUS_WAIT_LEAVE) + return SPELL_FAILED_DONT_REPORT; + + // only check at first call, Stealth auras are already removed at second call + // for now, ignore triggered spells + if( strict && !m_IsTriggeredSpell) + { + // Cannot be used in this stance/form + if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form)) + return shapeError; + + if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) + return SPELL_FAILED_ONLY_STEALTHED; + } + + // caster state requirements + if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState))) + return SPELL_FAILED_CASTER_AURASTATE; + if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot))) + return SPELL_FAILED_CASTER_AURASTATE; + + // cancel autorepeat spells if cast start when moving + // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code) + if( m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->isMoving() ) + { + // skip stuck spell to allow use it in falling case and apply spell limitations at movement + if( (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK) && + (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0) ) + return SPELL_FAILED_MOVING; + } + + Unit *target = m_targets.getUnitTarget(); + + if(target) + { + // target state requirements (not allowed state), apply to self also + if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot))) + return SPELL_FAILED_TARGET_AURASTATE; + + if(target != m_caster) + { + // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds + if(m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState))) + return SPELL_FAILED_TARGET_AURASTATE; + + // Not allow casting on flying player + if (target->isInFlight()) + return SPELL_FAILED_BAD_TARGETS; + + if(VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target)) + return SPELL_FAILED_LINE_OF_SIGHT; + + // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode + // this case can be triggered if rank not found (too low-level target for first rank) + if(m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo->Id) && !m_CastItem) + { + for(int i=0;i<3;i++) + { + if(IsPositiveEffect(m_spellInfo->Id, i) && m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA) + if(target->getLevel() + 10 < m_spellInfo->spellLevel) + return SPELL_FAILED_LOWLEVEL; + } + } + } + + // check pet presents + for(int j=0;j<3;j++) + { + if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_PET) + { + target = m_caster->GetPet(); + if(!target) + { + if(m_triggeredByAuraSpell) // not report pet not existence for triggered spells + return SPELL_FAILED_DONT_REPORT; + else + return SPELL_FAILED_NO_PET; + } + break; + } + } + + //check creature type + //ignore self casts (including area casts when caster selected as target) + if(target != m_caster) + { + if(!CheckTargetCreatureType(target)) + { + if(target->GetTypeId()==TYPEID_PLAYER) + return SPELL_FAILED_TARGET_IS_PLAYER; + else + return SPELL_FAILED_BAD_TARGETS; + } + } + + // TODO: this check can be applied and for player to prevent cheating when IsPositiveSpell will return always correct result. + // check target for pet/charmed casts (not self targeted), self targeted cast used for area effects and etc + if(m_caster != target && m_caster->GetTypeId()==TYPEID_UNIT && m_caster->GetCharmerOrOwnerGUID()) + { + // check correctness positive/negative cast target (pet cast real check and cheating check) + if(IsPositiveSpell(m_spellInfo->Id)) + { + if(m_caster->IsHostileTo(target)) + return SPELL_FAILED_BAD_TARGETS; + } + else + { + if(m_caster->IsFriendlyTo(target)) + return SPELL_FAILED_BAD_TARGETS; + } + } + + if(IsPositiveSpell(m_spellInfo->Id)) + { + if(target->IsImmunedToSpell(m_spellInfo,false)) + return SPELL_FAILED_TARGET_AURASTATE; + } + + //Must be behind the target. + if( m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(M_PI, m_caster) ) + { + SendInterrupted(2); + return SPELL_FAILED_NOT_BEHIND; + } + + //Target must be facing you. + if((m_spellInfo->Attributes == 0x150010) && !target->HasInArc(M_PI, m_caster) ) + { + SendInterrupted(2); + return SPELL_FAILED_NOT_INFRONT; + } + + // check if target is in combat + if (target != m_caster && (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET) && target->isInCombat()) + { + return SPELL_FAILED_TARGET_AFFECTING_COMBAT; + } + } + // Spell casted only on battleground + if((m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_BATTLEGROUND) && m_caster->GetTypeId()==TYPEID_PLAYER) + if(!((Player*)m_caster)->InBattleGround()) + return SPELL_FAILED_ONLY_BATTLEGROUNDS; + + // do not allow spells to be cast in arenas + // - with greater than 15 min CD without SPELL_ATTR_EX4_USABLE_IN_ARENA flag + // - with SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA flag + if( (m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA) || + GetSpellRecoveryTime(m_spellInfo) > 15 * MINUTE * 1000 && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA) ) + if(MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId())) + if(mapEntry->IsBattleArena()) + return SPELL_FAILED_NOT_IN_ARENA; + + // zone check + if(!IsSpellAllowedInLocation(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId())) + return SPELL_FAILED_REQUIRES_AREA; + + // not let players cast spells at mount (and let do it to creatures) + if( m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell && + !IsPassiveSpell(m_spellInfo->Id) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED) ) + { + if(m_caster->isInFlight()) + return SPELL_FAILED_NOT_FLYING; + else + return SPELL_FAILED_NOT_MOUNTED; + } + + // always (except passive spells) check items (focus object can be required for any type casts) + if(!IsPassiveSpell(m_spellInfo->Id)) + if(uint8 castResult = CheckItems()) + return castResult; + + //ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38 + if(m_UniqueTargetInfo.empty()) // skip second canCast apply (for delayed spells for example) + { + for(uint8 j = 0; j < 3; j++) + { + if( m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF || + m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ) + { + bool okDoo = false; + + SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id); + SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id); + if(lower==upper) + sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT or TARGET_SCRIPT_COORDINATES, but does not have record in `spell_script_target`",m_spellInfo->Id); + + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); + float range = GetSpellMaxRange(srange); + + Creature* creatureScriptTarget = NULL; + GameObject* goScriptTarget = NULL; + + for(SpellScriptTarget::const_iterator i_spellST = lower; i_spellST != upper; ++i_spellST) + { + switch(i_spellST->second.type) + { + case SPELL_TARGET_TYPE_GAMEOBJECT: + { + GameObject* p_GameObject = NULL; + + if(i_spellST->second.targetEntry) + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range); + MaNGOS::GameObjectLastSearcher checker(p_GameObject,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + + if(p_GameObject) + { + // remember found target and range, next attempt will find more near target with another entry + creatureScriptTarget = NULL; + goScriptTarget = p_GameObject; + range = go_check.GetLastRange(); + } + } + else if( focusObject ) //Focus Object + { + float frange = m_caster->GetDistance(focusObject); + if(range >= frange) + { + creatureScriptTarget = NULL; + goScriptTarget = focusObject; + range = frange; + } + } + break; + } + case SPELL_TARGET_TYPE_CREATURE: + case SPELL_TARGET_TYPE_DEAD: + default: + { + Creature *p_Creature = NULL; + + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); // Really don't know what is that??? + + MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range); + MaNGOS::CreatureLastSearcher searcher(p_Creature, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_creature_searcher, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + + if(p_Creature ) + { + creatureScriptTarget = p_Creature; + goScriptTarget = NULL; + range = u_check.GetLastRange(); + } + break; + } + } + } + + if(creatureScriptTarget) + { + // store coordinates for TARGET_SCRIPT_COORDINATES + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ) + { + m_targets.setDestination(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ()); + + if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) + AddUnitTarget(creatureScriptTarget, j); + } + // store explicit target for TARGET_SCRIPT + else + AddUnitTarget(creatureScriptTarget, j); + } + else if(goScriptTarget) + { + // store coordinates for TARGET_SCRIPT_COORDINATES + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ) + { + m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); + + if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) + AddGOTarget(goScriptTarget, j); + } + // store explicit target for TARGET_SCRIPT + else + AddGOTarget(goScriptTarget, j); + } + //Missing DB Entry or targets for this spellEffect. + else + { + // not report target not existence for triggered spells + if(m_triggeredByAuraSpell || m_IsTriggeredSpell) + return SPELL_FAILED_DONT_REPORT; + else + return SPELL_FAILED_BAD_TARGETS; + } + } + } + } + + if(uint8 castResult = CheckRange(strict)) + return castResult; + + { + if(uint8 castResult = CheckPower()) + return castResult; + } + + if(!m_triggeredByAuraSpell) // triggered spell not affected by stun/etc + if(uint8 castResult = CheckCasterAuras()) + return castResult; + + for (int i = 0; i < 3; i++) + { + // for effects of spells that have only one target + switch(m_spellInfo->Effect[i]) + { + case SPELL_EFFECT_DUMMY: + { + if(m_spellInfo->SpellIconID == 1648) // Execute + { + if(!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2) + return SPELL_FAILED_BAD_TARGETS; + } + else if (m_spellInfo->Id == 51582) // Rocket Boots Engaged + { + if(m_caster->IsInWater()) + return SPELL_FAILED_ONLY_ABOVEWATER; + } + else if(m_spellInfo->SpellIconID==156) // Holy Shock + { + // spell different for friends and enemies + // hart version required facing + if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, target )) + return SPELL_FAILED_UNIT_NOT_INFRONT; + } + break; + } + case SPELL_EFFECT_SCHOOL_DAMAGE: + { + // Hammer of Wrath + if(m_spellInfo->SpellVisual == 7250) + { + if (!m_targets.getUnitTarget()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + if(m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2) + return SPELL_FAILED_BAD_TARGETS; + } + break; + } + case SPELL_EFFECT_TAMECREATURE: + { + if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel()) + return SPELL_FAILED_HIGHLEVEL; + + CreatureInfo const *cinfo = ((Creature*)m_targets.getUnitTarget())->GetCreatureInfo(); + if( cinfo->type != CREATURE_TYPE_BEAST ) + return SPELL_FAILED_BAD_TARGETS; + + // use SMSG_PET_TAME_FAILURE? + if( !(cinfo->flag1 & 1) || !(cinfo->family) ) + return SPELL_FAILED_BAD_TARGETS; + + if(m_caster->GetPetGUID()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + + if(m_caster->GetCharmGUID()) + return SPELL_FAILED_ALREADY_HAVE_CHARM; + + break; + } + case SPELL_EFFECT_LEARN_SPELL: + { + if(m_spellInfo->EffectImplicitTargetA[i] != TARGET_PET) + break; + + Pet* pet = m_caster->GetPet(); + + if(!pet) + return SPELL_FAILED_NO_PET; + + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); + + if(!learn_spellproto) + return SPELL_FAILED_NOT_KNOWN; + + if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id)) + return SPELL_FAILED_TOO_MANY_SKILLS; + + if(m_spellInfo->spellLevel > pet->getLevel()) + return SPELL_FAILED_LOWLEVEL; + + if(!pet->HasTPForSpell(learn_spellproto->Id)) + return SPELL_FAILED_TRAINING_POINTS; + + break; + } + case SPELL_EFFECT_LEARN_PET_SPELL: + { + Pet* pet = m_caster->GetPet(); + + if(!pet) + return SPELL_FAILED_NO_PET; + + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); + + if(!learn_spellproto) + return SPELL_FAILED_NOT_KNOWN; + + if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id)) + return SPELL_FAILED_TOO_MANY_SKILLS; + + if(m_spellInfo->spellLevel > pet->getLevel()) + return SPELL_FAILED_LOWLEVEL; + + if(!pet->HasTPForSpell(learn_spellproto->Id)) + return SPELL_FAILED_TRAINING_POINTS; + + break; + } + case SPELL_EFFECT_FEED_PET: + { + if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_targets.getItemTarget() ) + return SPELL_FAILED_BAD_TARGETS; + + Pet* pet = m_caster->GetPet(); + + if(!pet) + return SPELL_FAILED_NO_PET; + + if(!pet->HaveInDiet(m_targets.getItemTarget()->GetProto())) + return SPELL_FAILED_WRONG_PET_FOOD; + + if(!pet->GetCurrentFoodBenefitLevel(m_targets.getItemTarget()->GetProto()->ItemLevel)) + return SPELL_FAILED_FOOD_LOWLEVEL; + + if(m_caster->isInCombat() || pet->isInCombat()) + return SPELL_FAILED_AFFECTING_COMBAT; + + break; + } + case SPELL_EFFECT_POWER_BURN: + case SPELL_EFFECT_POWER_DRAIN: + { + // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects) + if(m_caster->GetTypeId() == TYPEID_PLAYER) + if(Unit* target = m_targets.getUnitTarget()) + if(target!=m_caster && target->getPowerType()!=m_spellInfo->EffectMiscValue[i]) + return SPELL_FAILED_BAD_TARGETS; + break; + } + case SPELL_EFFECT_CHARGE: + { + if (m_caster->hasUnitState(UNIT_STAT_ROOT)) + return SPELL_FAILED_ROOTED; + + break; + } + case SPELL_EFFECT_SKINNING: + { + if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() != TYPEID_UNIT) + return SPELL_FAILED_BAD_TARGETS; + + if( !(m_targets.getUnitTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_SKINNABLE) ) + return SPELL_FAILED_TARGET_UNSKINNABLE; + + Creature* creature = (Creature*)m_targets.getUnitTarget(); + if ( creature->GetCreatureType() != CREATURE_TYPE_CRITTER && ( !creature->lootForBody || !creature->loot.empty() ) ) + { + return SPELL_FAILED_TARGET_NOT_LOOTED; + } + + uint32 skill; + if(creature->GetCreatureInfo()->flag1 & 256) + skill = SKILL_HERBALISM; // special case + else if(creature->GetCreatureInfo()->flag1 & 512) + skill = SKILL_MINING; // special case + else + skill = SKILL_SKINNING; // normal case + + int32 skillValue = ((Player*)m_caster)->GetSkillValue(skill); + int32 TargetLevel = m_targets.getUnitTarget()->getLevel(); + int32 ReqValue = (skillValue < 100 ? (TargetLevel-10)*10 : TargetLevel*5); + if (ReqValue > skillValue) + return SPELL_FAILED_LOW_CASTLEVEL; + + // chance for fail at orange skinning attempt + if( (m_selfContainer && (*m_selfContainer) == this) && + skillValue < sWorld.GetConfigMaxSkillValue() && + (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue-25, skillValue+37) ) + return SPELL_FAILED_TRY_AGAIN; + + break; + } + case SPELL_EFFECT_OPEN_LOCK_ITEM: + case SPELL_EFFECT_OPEN_LOCK: + { + if( m_spellInfo->EffectImplicitTargetA[i] != TARGET_GAMEOBJECT && + m_spellInfo->EffectImplicitTargetA[i] != TARGET_GAMEOBJECT_ITEM ) + break; + + if( m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc. + // we need a go target in case of TARGET_GAMEOBJECT + || m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT && !m_targets.getGOTarget() + // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM + || m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_ITEM && !m_targets.getGOTarget() && + (!m_targets.getItemTarget() || !m_targets.getItemTarget()->GetProto()->LockID || m_targets.getItemTarget()->GetOwner() != m_caster ) ) + return SPELL_FAILED_BAD_TARGETS; + + // In BattleGround players can use only flags and banners + if( ((Player*)m_caster)->InBattleGround() && + !((Player*)m_caster)->isAllowUseBattleGroundObject() ) + return SPELL_FAILED_TRY_AGAIN; + + // get the lock entry + LockEntry const *lockInfo = NULL; + if (GameObject* go=m_targets.getGOTarget()) + lockInfo = sLockStore.LookupEntry(go->GetLockId()); + else if(Item* itm=m_targets.getItemTarget()) + lockInfo = sLockStore.LookupEntry(itm->GetProto()->LockID); + + // check lock compatibility + if (lockInfo) + { + // check for lock - key pair (checked by client also, just prevent cheating + bool ok_key = false; + for(int it = 0; it < 5; ++it) + { + switch(lockInfo->keytype[it]) + { + case LOCK_KEY_NONE: + break; + case LOCK_KEY_ITEM: + { + if(lockInfo->key[it]) + { + if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it]) + ok_key =true; + break; + } + } + case LOCK_KEY_SKILL: + { + if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it]) + break; + + switch(lockInfo->key[it]) + { + case LOCKTYPE_HERBALISM: + if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM)) + ok_key =true; + break; + case LOCKTYPE_MINING: + if(((Player*)m_caster)->HasSkill(SKILL_MINING)) + ok_key =true; + break; + default: + ok_key =true; + break; + } + } + } + if(ok_key) + break; + } + + if(!ok_key) + return SPELL_FAILED_BAD_TARGETS; + } + + // chance for fail at orange mining/herb/LockPicking gathering attempt + if (!m_selfContainer || ((*m_selfContainer) != this)) + break; + + // get the skill value of the player + int32 SkillValue = 0; + bool canFailAtMax = true; + if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_HERBALISM) + { + SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_HERBALISM); + canFailAtMax = false; + } + else if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_MINING) + { + SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_MINING); + canFailAtMax = false; + } + else if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK) + SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_LOCKPICKING); + + // castitem check: rogue using skeleton keys. the skill values should not be added in this case. + if(m_CastItem) + SkillValue = 0; + + // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value) + SkillValue += m_currentBasePoints[i]+1; + + // get the required lock value + int32 ReqValue=0; + if (lockInfo) + { + // check for lock - key pair + bool ok = false; + for(int it = 0; it < 5; ++it) + { + if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it]) + { + // if so, we're good to go + ok = true; + break; + } + } + if(ok) + break; + + if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK) + ReqValue = lockInfo->requiredlockskill; + else + ReqValue = lockInfo->requiredminingskill; + } + + // skill doesn't meet the required value + if (ReqValue > SkillValue) + return SPELL_FAILED_LOW_CASTLEVEL; + + // chance for failure in orange gather / lockpick (gathering skill can't fail at maxskill) + if((canFailAtMax || SkillValue < sWorld.GetConfigMaxSkillValue()) && ReqValue > irand(SkillValue-25, SkillValue+37)) + return SPELL_FAILED_TRY_AGAIN; + + break; + } + case SPELL_EFFECT_SUMMON_DEAD_PET: + { + Creature *pet = m_caster->GetPet(); + if(!pet) + return SPELL_FAILED_NO_PET; + + if(pet->isAlive()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + + break; + } + // This is generic summon effect now and don't make this check for summon types similar + // SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN. + // These won't show up in m_caster->GetPetGUID() + case SPELL_EFFECT_SUMMON: + { + switch(m_spellInfo->EffectMiscValueB[i]) + { + case SUMMON_TYPE_POSESSED: + case SUMMON_TYPE_POSESSED2: + case SUMMON_TYPE_DEMON: + case SUMMON_TYPE_SUMMON: + { + if(m_caster->GetPetGUID()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + + if(m_caster->GetCharmGUID()) + return SPELL_FAILED_ALREADY_HAVE_CHARM; + break; + } + } + break; + } + // Don't make this check for SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN. + // These won't show up in m_caster->GetPetGUID() + case SPELL_EFFECT_SUMMON_POSSESSED: + case SPELL_EFFECT_SUMMON_PHANTASM: + case SPELL_EFFECT_SUMMON_DEMON: + { + if(m_caster->GetPetGUID()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + + if(m_caster->GetCharmGUID()) + return SPELL_FAILED_ALREADY_HAVE_CHARM; + + break; + } + case SPELL_EFFECT_SUMMON_PET: + { + if(m_caster->GetPetGUID()) //let warlock do a replacement summon + { + + Pet* pet = ((Player*)m_caster)->GetPet(); + + if (m_caster->GetTypeId()==TYPEID_PLAYER && m_caster->getClass()==CLASS_WARLOCK) + { + if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player) + pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID()); + } + else + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + } + + if(m_caster->GetCharmGUID()) + return SPELL_FAILED_ALREADY_HAVE_CHARM; + + break; + } + case SPELL_EFFECT_SUMMON_PLAYER: + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return SPELL_FAILED_BAD_TARGETS; + if(!((Player*)m_caster)->GetSelection()) + return SPELL_FAILED_BAD_TARGETS; + + Player* target = objmgr.GetPlayer(((Player*)m_caster)->GetSelection()); + if( !target || ((Player*)m_caster)==target || !target->IsInSameRaidWith((Player*)m_caster) ) + return SPELL_FAILED_BAD_TARGETS; + + // check if our map is dungeon + if( sMapStore.LookupEntry(m_caster->GetMapId())->IsDungeon() ) + { + InstanceTemplate const* instance = ObjectMgr::GetInstanceTemplate(m_caster->GetMapId()); + if(!instance) + return SPELL_FAILED_TARGET_NOT_IN_INSTANCE; + if ( instance->levelMin > target->getLevel() ) + return SPELL_FAILED_LOWLEVEL; + if ( instance->levelMax && instance->levelMax < target->getLevel() ) + return SPELL_FAILED_HIGHLEVEL; + } + break; + } + case SPELL_EFFECT_LEAP: + case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER: + { + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation()); + float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation()); + // teleport a bit above terrain level to avoid falling below it + float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx,fy,m_caster->GetPositionZ(),true); + if(fz <= INVALID_HEIGHT) // note: this also will prevent use effect in instances without vmaps height enabled + return SPELL_FAILED_TRY_AGAIN; + + float caster_pos_z = m_caster->GetPositionZ(); + // Control the caster to not climb or drop when +-fz > 8 + if(!(fz<=caster_pos_z+8 && fz>=caster_pos_z-8)) + return SPELL_FAILED_TRY_AGAIN; + + // not allow use this effect at battleground until battleground start + if(m_caster->GetTypeId()==TYPEID_PLAYER) + if(BattleGround const *bg = ((Player*)m_caster)->GetBattleGround()) + if(bg->GetStatus() != STATUS_IN_PROGRESS) + return SPELL_FAILED_TRY_AGAIN; + break; + } + case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF: + { + if (m_targets.getUnitTarget()==m_caster) + return SPELL_FAILED_BAD_TARGETS; + break; + } + default:break; + } + } + + for (int i = 0; i < 3; i++) + { + switch(m_spellInfo->EffectApplyAuraName[i]) + { + case SPELL_AURA_MOD_POSSESS: + case SPELL_AURA_MOD_CHARM: + { + if(m_caster->GetPetGUID()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + + if(m_caster->GetCharmGUID()) + return SPELL_FAILED_ALREADY_HAVE_CHARM; + + if(m_caster->GetCharmerGUID()) + return SPELL_FAILED_CHARMED; + + if(!m_targets.getUnitTarget()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + if(m_targets.getUnitTarget()->GetCharmerGUID()) + return SPELL_FAILED_CHARMED; + + if(int32(m_targets.getUnitTarget()->getLevel()) > CalculateDamage(i,m_targets.getUnitTarget())) + return SPELL_FAILED_HIGHLEVEL; + };break; + case SPELL_AURA_MOUNTED: + { + if (m_caster->IsInWater()) + return SPELL_FAILED_ONLY_ABOVEWATER; + + if (m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->GetTransport()) + return SPELL_FAILED_NO_MOUNTS_ALLOWED; + + // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells + if (m_caster->GetTypeId()==TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaId) + return SPELL_FAILED_NO_MOUNTS_ALLOWED; + + if (m_caster->GetAreaId()==35) + return SPELL_FAILED_NO_MOUNTS_ALLOWED; + + ShapeshiftForm form = m_caster->m_form; + if( form == FORM_CAT || form == FORM_TREE || form == FORM_TRAVEL || + form == FORM_AQUA || form == FORM_BEAR || form == FORM_DIREBEAR || + form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT || + form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN ) + return SPELL_FAILED_NOT_SHAPESHIFT; + + break; + } + case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS: + { + if(!m_targets.getUnitTarget()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + // can be casted at non-friendly unit or own pet/charm + if(m_caster->IsFriendlyTo(m_targets.getUnitTarget())) + return SPELL_FAILED_TARGET_FRIENDLY; + };break; + case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED: + case SPELL_AURA_FLY: + { + // not allow cast fly spells at old maps by players (all spells is self target) + if(m_caster->GetTypeId()==TYPEID_PLAYER) + { + if( !((Player*)m_caster)->isGameMaster() && + GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530) + return SPELL_FAILED_NOT_HERE; + } + };break; + case SPELL_AURA_PERIODIC_MANA_LEECH: + { + if (!m_targets.getUnitTarget()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + if (m_caster->GetTypeId()!=TYPEID_PLAYER || m_CastItem) + break; + + if(m_targets.getUnitTarget()->getPowerType()!=POWER_MANA) + return SPELL_FAILED_BAD_TARGETS; + break; + } + default:break; + } + } + + // all ok + return 0; +} + +int16 Spell::PetCanCast(Unit* target) +{ + if(!m_caster->isAlive()) + return SPELL_FAILED_CASTER_DEAD; + + if(m_caster->IsNonMeleeSpellCasted(false)) //prevent spellcast interuption by another spellcast + return SPELL_FAILED_SPELL_IN_PROGRESS; + if(m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo)) + return SPELL_FAILED_AFFECTING_COMBAT; + + if(m_caster->GetTypeId()==TYPEID_UNIT && (((Creature*)m_caster)->isPet() || m_caster->isCharmed())) + { + //dead owner (pets still alive when owners ressed?) + if(m_caster->GetCharmerOrOwner() && !m_caster->GetCharmerOrOwner()->isAlive()) + return SPELL_FAILED_CASTER_DEAD; + + if(!target && m_targets.getUnitTarget()) + target = m_targets.getUnitTarget(); + + bool need = false; + for(uint32 i = 0;i<3;i++) + { + if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES) + { + need = true; + if(!target) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + break; + } + } + if(need) + m_targets.setUnitTarget(target); + + Unit* _target = m_targets.getUnitTarget(); + + if(_target) //for target dead/target not valid + { + if(!_target->isAlive()) + return SPELL_FAILED_BAD_TARGETS; + + if(IsPositiveSpell(m_spellInfo->Id)) + { + if(m_caster->IsHostileTo(_target)) + return SPELL_FAILED_BAD_TARGETS; + } + else + { + bool duelvsplayertar = false; + for(int j=0;j<3;j++) + { + //TARGET_DUELVSPLAYER is positive AND negative + duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER); + } + if(m_caster->IsFriendlyTo(target) && !duelvsplayertar) + { + return SPELL_FAILED_BAD_TARGETS; + } + } + } + //cooldown + if(((Creature*)m_caster)->HasSpellCooldown(m_spellInfo->Id)) + return SPELL_FAILED_NOT_READY; + } + + uint16 result = CanCast(true); + if(result != 0) + return result; + else + return -1; //this allows to check spell fail 0, in combat +} + +uint8 Spell::CheckCasterAuras() const +{ + // Flag drop spells totally immuned to caster auras + // FIXME: find more nice check for all totally immuned spells + // AttributesEx3 & 0x10000000? + if(m_spellInfo->Id==23336 || m_spellInfo->Id==23334 || m_spellInfo->Id==34991) + return 0; + + uint8 school_immune = 0; + uint32 mechanic_immune = 0; + uint32 dispel_immune = 0; + + //Check if the spell grants school or mechanic immunity. + //We use bitmasks so the loop is done only once and not on every aura check below. + if ( m_spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY ) + { + for(int i = 0;i < 3; i ++) + { + if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) + school_immune |= uint32(m_spellInfo->EffectMiscValue[i]); + else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) + mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]); + else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) + dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i])); + } + //immune movement impairement and loss of control + if(m_spellInfo->Id==(uint32)42292) + mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; + } + + //Check whether the cast should be prevented by any state you might have. + uint8 prevented_reason = 0; + // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out + if(!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED) && m_caster->HasAuraType(SPELL_AURA_MOD_STUN)) + prevented_reason = SPELL_FAILED_STUNNED; + else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) + prevented_reason = SPELL_FAILED_CONFUSED; + else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) + prevented_reason = SPELL_FAILED_FLEEING; + else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE) + prevented_reason = SPELL_FAILED_SILENCED; + else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY) + prevented_reason = SPELL_FAILED_PACIFIED; + + // Attr must make flag drop spell totally immuned from all effects + if(prevented_reason) + { + if(school_immune || mechanic_immune || dispel_immune) + { + //Checking auras is needed now, because you are prevented by some state but the spell grants immunity. + Unit::AuraMap const& auras = m_caster->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) + { + if(itr->second) + { + if( GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune ) + continue; + if( GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune ) + continue; + if( (1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) + continue; + + //Make a second check for spell failed so the right SPELL_FAILED message is returned. + //That is needed when your casting is prevented by multiple states and you are only immune to some of them. + switch(itr->second->GetModifier()->m_auraname) + { + case SPELL_AURA_MOD_STUN: + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) + return SPELL_FAILED_STUNNED; + break; + case SPELL_AURA_MOD_CONFUSE: + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) + return SPELL_FAILED_CONFUSED; + break; + case SPELL_AURA_MOD_FEAR: + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) + return SPELL_FAILED_FLEEING; + break; + case SPELL_AURA_MOD_SILENCE: + case SPELL_AURA_MOD_PACIFY: + case SPELL_AURA_MOD_PACIFY_SILENCE: + if( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY) + return SPELL_FAILED_PACIFIED; + else if ( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE) + return SPELL_FAILED_SILENCED; + break; + } + } + } + } + //You are prevented from casting and the spell casted does not grant immunity. Return a failed error. + else + return prevented_reason; + } + return 0; // all ok +} + +bool Spell::CanAutoCast(Unit* target) +{ + uint64 targetguid = target->GetGUID(); + + for(uint32 j = 0;j<3;j++) + { + if(m_spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA) + { + if( m_spellInfo->StackAmount <= 1) + { + if( target->HasAura(m_spellInfo->Id, j) ) + return false; + } + else + { + if( target->GetAuras().count(Unit::spellEffectPair(m_spellInfo->Id, j)) >= m_spellInfo->StackAmount) + return false; + } + } + else if ( IsAreaAuraEffect( m_spellInfo->Effect[j] )) + { + if( target->HasAura(m_spellInfo->Id, j) ) + return false; + } + } + + int16 result = PetCanCast(target); + + if(result == -1 || result == SPELL_FAILED_UNIT_NOT_INFRONT) + { + FillTargetMap(); + //check if among target units, our WANTED target is as well (->only self cast spells return false) + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + if( ihit->targetGUID == targetguid ) + return true; + } + return false; //target invalid +} + +uint8 Spell::CheckRange(bool strict) +{ + float range_mod; + + // self cast doesn't need range checking -- also for Starshards fix + if (m_spellInfo->rangeIndex == 1) return 0; + + if (strict) //add radius of caster + range_mod = 1.25; + else //add radius of caster and ~5 yds "give" + range_mod = 6.25; + + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); + float max_range = GetSpellMaxRange(srange) + range_mod; + float min_range = GetSpellMinRange(srange); + + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this); + + Unit *target = m_targets.getUnitTarget(); + + if(target && target != m_caster) + { + // distance from target center in checks + float dist = m_caster->GetDistance(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ()); + if(dist > max_range) + return SPELL_FAILED_OUT_OF_RANGE; //0x5A; + if(dist < min_range) + return SPELL_FAILED_TOO_CLOSE; + if( m_caster->GetTypeId() == TYPEID_PLAYER && + (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc( M_PI, target ) ) + return SPELL_FAILED_UNIT_NOT_INFRONT; + } + + if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0) + { + float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); + if(dist > max_range) + return SPELL_FAILED_OUT_OF_RANGE; + if(dist < min_range) + return SPELL_FAILED_TOO_CLOSE; + } + + return 0; // ok +} + +int32 Spell::CalculatePowerCost() +{ + // item cast not used power + if(m_CastItem) + return 0; + + // Spell drain all exist power on cast (Only paladin lay of Hands) + if (m_spellInfo->AttributesEx & SPELL_ATTR_EX_DRAIN_ALL_POWER) + { + // If power type - health drain all + if (m_spellInfo->powerType == POWER_HEALTH) + return m_caster->GetHealth(); + // Else drain all power + if (m_spellInfo->powerType < MAX_POWERS) + return m_caster->GetPower(Powers(m_spellInfo->powerType)); + sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id); + return 0; + } + + // Base powerCost + int32 powerCost = m_spellInfo->manaCost; + // PCT cost from total amount + if (m_spellInfo->ManaCostPercentage) + { + switch (m_spellInfo->powerType) + { + // health as power used + case POWER_HEALTH: + powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetCreateHealth() / 100; + break; + case POWER_MANA: + powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetCreateMana() / 100; + break; + case POWER_RAGE: + case POWER_FOCUS: + case POWER_ENERGY: + case POWER_HAPPINESS: + // case POWER_RUNES: + powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100; + break; + default: + sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id); + return 0; + } + } + SpellSchools school = GetFirstSchoolInMask(m_spellSchoolMask); + // Flat mod from caster auras by spell school + powerCost += m_caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school); + // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost) + if ( m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_SPELL_VS_EXTEND_COST ) + powerCost += m_caster->GetAttackTime(OFF_ATTACK)/100; + // Apply cost mod by spell + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, powerCost, this); + + if(m_spellInfo->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION) + powerCost = int32(powerCost/ (1.117f* m_spellInfo->spellLevel / m_caster->getLevel() -0.1327f)); + + // PCT mod from user auras by school + powerCost = int32(powerCost * (1.0f+m_caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+school))); + if (powerCost < 0) + powerCost = 0; + return powerCost; +} + +uint8 Spell::CheckPower() +{ + // item cast not used power + if(m_CastItem) + return 0; + + // health as power used - need check health amount + if(m_spellInfo->powerType == POWER_HEALTH) + { + if(m_caster->GetHealth() <= m_powerCost) + return SPELL_FAILED_CASTER_AURASTATE; + return 0; + } + // Check valid power type + if( m_spellInfo->powerType >= MAX_POWERS ) + { + sLog.outError("Spell::CheckMana: Unknown power type '%d'", m_spellInfo->powerType); + return SPELL_FAILED_UNKNOWN; + } + // Check power amount + Powers powerType = Powers(m_spellInfo->powerType); + if(m_caster->GetPower(powerType) < m_powerCost) + return SPELL_FAILED_NO_POWER; + else + return 0; +} + +uint8 Spell::CheckItems() +{ + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return 0; + + uint32 itemid, itemcount; + Player* p_caster = (Player*)m_caster; + + if(m_CastItem) + { + itemid = m_CastItem->GetEntry(); + if( !p_caster->HasItemCount(itemid,1) ) + return SPELL_FAILED_ITEM_NOT_READY; + else + { + ItemPrototype const *proto = m_CastItem->GetProto(); + if(!proto) + return SPELL_FAILED_ITEM_NOT_READY; + + for (int i = 0; i<5; i++) + { + if (proto->Spells[i].SpellCharges) + { + if(m_CastItem->GetSpellCharges(i)==0) + return SPELL_FAILED_NO_CHARGES_REMAIN; + } + } + + uint32 ItemClass = proto->Class; + if (ItemClass == ITEM_CLASS_CONSUMABLE && m_targets.getUnitTarget()) + { + for (int i = 0; i < 3; i++) + { + // skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_PET) + continue; + + if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL) + if (m_targets.getUnitTarget()->GetHealth() == m_targets.getUnitTarget()->GetMaxHealth()) + return (uint8)SPELL_FAILED_ALREADY_AT_FULL_HEALTH; + + // Mana Potion, Rage Potion, Thistle Tea(Rogue), ... + if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENERGIZE) + { + if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) + return (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER; + + Powers power = Powers(m_spellInfo->EffectMiscValue[i]); + + if (m_targets.getUnitTarget()->GetPower(power) == m_targets.getUnitTarget()->GetMaxPower(power)) + return (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER; + } + } + } + } + } + + if(m_targets.getItemTargetGUID()) + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_BAD_TARGETS; + + if(!m_targets.getItemTarget()) + return SPELL_FAILED_ITEM_GONE; + + if(!m_targets.getItemTarget()->IsFitToSpellRequirements(m_spellInfo)) + return SPELL_FAILED_EQUIPPED_ITEM_CLASS; + } + // if not item target then required item must be equipped + else + { + if(m_caster->GetTypeId() == TYPEID_PLAYER && !((Player*)m_caster)->HasItemFitToSpellReqirements(m_spellInfo)) + return SPELL_FAILED_EQUIPPED_ITEM_CLASS; + } + + if(m_spellInfo->RequiresSpellFocus) + { + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + GameObject* ok = NULL; + MaNGOS::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus); + MaNGOS::GameObjectSearcher checker(ok,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); + + if(!ok) + return (uint8)SPELL_FAILED_REQUIRES_SPELL_FOCUS; + + focusObject = ok; // game object found in range + } + + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && + m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))) + { + for(uint32 i=0;i<8;i++) + { + if(m_spellInfo->Reagent[i] <= 0) + continue; + + itemid = m_spellInfo->Reagent[i]; + itemcount = m_spellInfo->ReagentCount[i]; + + // if CastItem is also spell reagent + if( m_CastItem && m_CastItem->GetEntry() == itemid ) + { + ItemPrototype const *proto = m_CastItem->GetProto(); + if(!proto) + return SPELL_FAILED_ITEM_NOT_READY; + for(int s=0;s<5;s++) + { + // CastItem will be used up and does not count as reagent + int32 charges = m_CastItem->GetSpellCharges(s); + if (proto->Spells[s].SpellCharges < 0 && abs(charges) < 2) + { + ++itemcount; + break; + } + } + } + if( !p_caster->HasItemCount(itemid,itemcount) ) + return (uint8)SPELL_FAILED_ITEM_NOT_READY; //0x54 + } + } + + uint32 totems = 2; + for(int i=0;i<2;++i) + { + if(m_spellInfo->Totem[i] != 0) + { + if( p_caster->HasItemCount(m_spellInfo->Totem[i],1) ) + { + totems -= 1; + continue; + } + }else + totems -= 1; + } + if(totems != 0) + return (uint8)SPELL_FAILED_TOTEMS; //0x7C + + //Check items for TotemCategory + uint32 TotemCategory = 2; + for(int i=0;i<2;++i) + { + if(m_spellInfo->TotemCategory[i] != 0) + { + if( p_caster->HasItemTotemCategory(m_spellInfo->TotemCategory[i]) ) + { + TotemCategory -= 1; + continue; + } + } + else + TotemCategory -= 1; + } + if(TotemCategory != 0) + return (uint8)SPELL_FAILED_TOTEM_CATEGORY; //0x7B + + for(int i = 0; i < 3; i++) + { + switch (m_spellInfo->Effect[i]) + { + case SPELL_EFFECT_CREATE_ITEM: + { + if (!m_IsTriggeredSpell && m_spellInfo->EffectItemType[i]) + { + ItemPosCountVec dest; + uint8 msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1 ); + if (msg != EQUIP_ERR_OK ) + { + p_caster->SendEquipError( msg, NULL, NULL ); + return SPELL_FAILED_DONT_REPORT; + } + } + break; + } + case SPELL_EFFECT_ENCHANT_ITEM: + { + Item* targetItem = m_targets.getItemTarget(); + if(!targetItem) + return SPELL_FAILED_ITEM_NOT_FOUND; + + if( targetItem->GetProto()->ItemLevel < m_spellInfo->baseLevel ) + return SPELL_FAILED_LOWLEVEL; + // Not allow enchant in trade slot for some enchant type + if( targetItem->GetOwner() != m_caster ) + { + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return SPELL_FAILED_ERROR; + if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND) + return SPELL_FAILED_NOT_TRADEABLE; + } + break; + } + case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: + { + Item *item = m_targets.getItemTarget(); + if(!item) + return SPELL_FAILED_ITEM_NOT_FOUND; + // Not allow enchant in trade slot for some enchant type + if( item->GetOwner() != m_caster ) + { + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return SPELL_FAILED_ERROR; + if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND) + return SPELL_FAILED_NOT_TRADEABLE; + } + break; + } + case SPELL_EFFECT_ENCHANT_HELD_ITEM: + // check item existence in effect code (not output errors at offhand hold item effect to main hand for example + break; + case SPELL_EFFECT_DISENCHANT: + { + if(!m_targets.getItemTarget()) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + + // prevent disenchanting in trade slot + if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() ) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + + ItemPrototype const* itemProto = m_targets.getItemTarget()->GetProto(); + if(!itemProto) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + + uint32 item_quality = itemProto->Quality; + // 2.0.x addon: Check player enchanting level agains the item desenchanting requirements + uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill; + if (item_disenchantskilllevel == uint32(-1)) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + if (item_disenchantskilllevel > p_caster->GetSkillValue(SKILL_ENCHANTING)) + return SPELL_FAILED_LOW_CASTLEVEL; + if(item_quality > 4 || item_quality < 2) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + if(itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + if (!itemProto->DisenchantID) + return SPELL_FAILED_CANT_BE_DISENCHANTED; + break; + } + case SPELL_EFFECT_PROSPECTING: + { + if(!m_targets.getItemTarget()) + return SPELL_FAILED_CANT_BE_PROSPECTED; + //ensure item is a prospectable ore + if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS) + return SPELL_FAILED_CANT_BE_PROSPECTED; + //prevent prospecting in trade slot + if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() ) + return SPELL_FAILED_CANT_BE_PROSPECTED; + //Check for enough skill in jewelcrafting + uint32 item_prospectingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank; + if(item_prospectingskilllevel >p_caster->GetSkillValue(SKILL_JEWELCRAFTING)) + return SPELL_FAILED_LOW_CASTLEVEL; + //make sure the player has the required ores in inventory + if(m_targets.getItemTarget()->GetCount() < 5) + return SPELL_FAILED_PROSPECT_NEED_MORE; + + if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry())) + return SPELL_FAILED_CANT_BE_PROSPECTED; + + break; + } + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER; + if( m_attackType != RANGED_ATTACK ) + break; + Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(m_attackType); + if(!pItem || pItem->IsBroken()) + return SPELL_FAILED_EQUIPPED_ITEM; + + switch(pItem->GetProto()->SubClass) + { + case ITEM_SUBCLASS_WEAPON_THROWN: + { + uint32 ammo = pItem->GetEntry(); + if( !((Player*)m_caster)->HasItemCount( ammo, 1 ) ) + return SPELL_FAILED_NO_AMMO; + }; break; + case ITEM_SUBCLASS_WEAPON_GUN: + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + { + uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID); + if(!ammo) + { + // Requires No Ammo + if(m_caster->GetDummyAura(46699)) + break; // skip other checks + + return SPELL_FAILED_NO_AMMO; + } + + ItemPrototype const *ammoProto = objmgr.GetItemPrototype( ammo ); + if(!ammoProto) + return SPELL_FAILED_NO_AMMO; + + if(ammoProto->Class != ITEM_CLASS_PROJECTILE) + return SPELL_FAILED_NO_AMMO; + + // check ammo ws. weapon compatibility + switch(pItem->GetProto()->SubClass) + { + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + if(ammoProto->SubClass!=ITEM_SUBCLASS_ARROW) + return SPELL_FAILED_NO_AMMO; + break; + case ITEM_SUBCLASS_WEAPON_GUN: + if(ammoProto->SubClass!=ITEM_SUBCLASS_BULLET) + return SPELL_FAILED_NO_AMMO; + break; + default: + return SPELL_FAILED_NO_AMMO; + } + + if( !((Player*)m_caster)->HasItemCount( ammo, 1 ) ) + return SPELL_FAILED_NO_AMMO; + }; break; + case ITEM_SUBCLASS_WEAPON_WAND: + default: + break; + } + break; + } + default:break; + } + } + + return uint8(0); +} + +void Spell::Delayed() +{ + if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + if (m_spellState == SPELL_STATE_DELAYED) + return; // spell is active and can't be time-backed + + // spells not loosing casting time ( slam, dynamites, bombs.. ) + if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)) + return; + + //check resist chance + int32 resistChance = 100; //must be initialized to 100 for percent modifiers + ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this); + resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100; + if (roll_chance_i(resistChance)) + return; + + int32 delaytime = GetNextDelayAtDamageMsTime(); + + if(int32(m_timer) + delaytime > m_casttime) + { + delaytime = m_casttime - m_timer; + m_timer = m_casttime; + } + else + m_timer += delaytime; + + sLog.outDetail("Spell %u partially interrupted for (%d) ms at damage",m_spellInfo->Id,delaytime); + + WorldPacket data(SMSG_SPELL_DELAYED, 8+4); + data.append(m_caster->GetPackGUID()); + data << uint32(delaytime); + + m_caster->SendMessageToSet(&data,true); +} + +void Spell::DelayedChannel() +{ + if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER || getState() != SPELL_STATE_CASTING) + return; + + //check resist chance + int32 resistChance = 100; //must be initialized to 100 for percent modifiers + ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this); + resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100; + if (roll_chance_i(resistChance)) + return; + + int32 delaytime = GetNextDelayAtDamageMsTime(); + + if(int32(m_timer) < delaytime) + { + delaytime = m_timer; + m_timer = 0; + } + else + m_timer -= delaytime; + + sLog.outDebug("Spell %u partially interrupted for %i ms, new duration: %u ms", m_spellInfo->Id, delaytime, m_timer); + + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + if ((*ihit).missCondition == SPELL_MISS_NONE) + { + Unit* unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); + if (unit) + { + for (int j=0;j<3;j++) + if( ihit->effectMask & (1<DelayAura(m_spellInfo->Id, j, delaytime); + } + + } + } + + for(int j = 0; j < 3; j++) + { + // partially interrupt persistent area auras + DynamicObject* dynObj = m_caster->GetDynObject(m_spellInfo->Id, j); + if(dynObj) + dynObj->Delay(delaytime); + } + + SendChannelUpdate(m_timer); +} + +void Spell::UpdatePointers() +{ + if(m_originalCasterGUID==m_caster->GetGUID()) + m_originalCaster = m_caster; + else + { + m_originalCaster = ObjectAccessor::GetUnit(*m_caster,m_originalCasterGUID); + if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL; + } + + m_targets.Update(m_caster); +} + +bool Spell::IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId) +{ + return spellmgr.IsAffectedBySpell(m_spellInfo,spellInfo->Id,effectId,spellInfo->EffectItemType[effectId]); +} + +bool Spell::CheckTargetCreatureType(Unit* target) const +{ + uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType; + + // Curse of Doom : not find another way to fix spell target check :/ + if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags == 0x0200000000LL) + { + // not allow cast at player + if(target->GetTypeId()==TYPEID_PLAYER) + return false; + + spellCreatureTargetMask = 0x7FF; + } + + // Dismiss Pet and Taming Lesson skipped + if(m_spellInfo->Id == 2641 || m_spellInfo->Id == 23356) + spellCreatureTargetMask = 0; + + if (spellCreatureTargetMask) + { + uint32 TargetCreatureType = target->GetCreatureTypeMask(); + + return !TargetCreatureType || (spellCreatureTargetMask & TargetCreatureType); + } + return true; +} + +CurrentSpellTypes Spell::GetCurrentContainer() +{ + if (IsNextMeleeSwingSpell()) + return(CURRENT_MELEE_SPELL); + else if (IsAutoRepeat()) + return(CURRENT_AUTOREPEAT_SPELL); + else if (IsChanneledSpell(m_spellInfo)) + return(CURRENT_CHANNELED_SPELL); + else + return(CURRENT_GENERIC_SPELL); +} + +bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase ) +{ + // Check targets for creature type mask and remove not appropriate (skip explicit self target case, maybe need other explicit targets) + if(m_spellInfo->EffectImplicitTargetA[eff]!=TARGET_SELF ) + { + if (!CheckTargetCreatureType(target)) + return false; + } + + // Check targets for not_selectable unit flag and remove + // A player can cast spells on his pet (or other controlled unit) though in any state + if (target != m_caster && target->GetCharmerOrOwnerGUID() != m_caster->GetGUID()) + { + // any unattackable target skipped + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return false; + + // unselectable targets skipped in all cases except TARGET_SCRIPT targeting + // in case TARGET_SCRIPT target selected by server always and can't be cheated + if( target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && + m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SCRIPT && + m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT ) + return false; + } + + //Check player targets and remove if in GM mode or GM invisibility (for not self casting case) + if( target != m_caster && target->GetTypeId()==TYPEID_PLAYER) + { + if(((Player*)target)->GetVisibility()==VISIBILITY_OFF) + return false; + + if(((Player*)target)->isGameMaster() && !IsPositiveSpell(m_spellInfo->Id)) + return false; + } + + //Check targets for LOS visibility (except spells without range limitations ) + switch(m_spellInfo->Effect[eff]) + { + case SPELL_EFFECT_SUMMON_PLAYER: // from anywhere + break; + case SPELL_EFFECT_DUMMY: + if(m_spellInfo->Id!=20577) // Cannibalize + break; + //fall through + case SPELL_EFFECT_RESURRECT_NEW: + // player far away, maybe his corpse near? + if(target!=m_caster && !target->IsWithinLOSInMap(m_caster)) + { + if(!m_targets.getCorpseTargetGUID()) + return false; + + Corpse *corpse = ObjectAccessor::GetCorpse(*m_caster,m_targets.getCorpseTargetGUID()); + if(!corpse) + return false; + + if(target->GetGUID()!=corpse->GetOwnerGUID()) + return false; + + if(!corpse->IsWithinLOSInMap(m_caster)) + return false; + } + + // all ok by some way or another, skip normal check + break; + default: // normal case + if(target!=m_caster && !target->IsWithinLOSInMap(m_caster)) + return false; + break; + } + + return true; +} + +Unit* Spell::SelectMagnetTarget() +{ + Unit* target = m_targets.getUnitTarget(); + + if(target && target->HasAuraType(SPELL_AURA_SPELL_MAGNET) && !(m_spellInfo->Attributes & 0x10)) + { + Unit::AuraList const& magnetAuras = target->GetAurasByType(SPELL_AURA_SPELL_MAGNET); + for(Unit::AuraList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr) + { + if(Unit* magnet = (*itr)->GetCaster()) + { + if(magnet->IsWithinLOSInMap(m_caster)) + { + target = magnet; + m_targets.setUnitTarget(target); + break; + } + } + } + } + + return target; +} + +bool Spell::IsNeedSendToClient() const +{ + return m_spellInfo->SpellVisual!=0 || IsChanneledSpell(m_spellInfo) || + m_spellInfo->speed > 0.0f || !m_triggeredByAuraSpell && !m_IsTriggeredSpell; +} + +bool Spell::HaveTargetsForEffect( uint8 effect ) const +{ + for(std::list::const_iterator itr= m_UniqueTargetInfo.begin();itr != m_UniqueTargetInfo.end();++itr) + if(itr->effectMask & (1<::const_iterator itr= m_UniqueGOTargetInfo.begin();itr != m_UniqueGOTargetInfo.end();++itr) + if(itr->effectMask & (1<::const_iterator itr= m_UniqueItemInfo.begin();itr != m_UniqueItemInfo.end();++itr) + if(itr->effectMask & (1<getState() != SPELL_STATE_FINISHED) + m_Spell->cancel(); + + if (m_Spell->IsDeletable()) + { + delete m_Spell; + } + else + { + sLog.outError("~SpellEvent: %s %u tried to delete non-deletable spell %u. Was not deleted, causes memory leak.", + (m_Spell->GetCaster()->GetTypeId()==TYPEID_PLAYER?"Player":"Creature"), m_Spell->GetCaster()->GetGUIDLow(),m_Spell->m_spellInfo->Id); + } +} + +bool SpellEvent::Execute(uint64 e_time, uint32 p_time) +{ + // update spell if it is not finished + if (m_Spell->getState() != SPELL_STATE_FINISHED) + m_Spell->update(p_time); + + // check spell state to process + switch (m_Spell->getState()) + { + case SPELL_STATE_FINISHED: + { + // spell was finished, check deletable state + if (m_Spell->IsDeletable()) + { + // check, if we do have unfinished triggered spells + + return(true); // spell is deletable, finish event + } + // event will be re-added automatically at the end of routine) + } break; + + case SPELL_STATE_CASTING: + { + // this spell is in channeled state, process it on the next update + // event will be re-added automatically at the end of routine) + } break; + + case SPELL_STATE_DELAYED: + { + // first, check, if we have just started + if (m_Spell->GetDelayStart() != 0) + { + // no, we aren't, do the typical update + // check, if we have channeled spell on our hands + if (IsChanneledSpell(m_Spell->m_spellInfo)) + { + // evented channeled spell is processed separately, casted once after delay, and not destroyed till finish + // check, if we have casting anything else except this channeled spell and autorepeat + if (m_Spell->GetCaster()->IsNonMeleeSpellCasted(false, true, true)) + { + // another non-melee non-delayed spell is casted now, abort + m_Spell->cancel(); + } + else + { + // do the action (pass spell to channeling state) + m_Spell->handle_immediate(); + } + // event will be re-added automatically at the end of routine) + } + else + { + // run the spell handler and think about what we can do next + uint64 t_offset = e_time - m_Spell->GetDelayStart(); + uint64 n_offset = m_Spell->handle_delayed(t_offset); + if (n_offset) + { + // re-add us to the queue + m_Spell->GetCaster()->m_Events.AddEvent(this, m_Spell->GetDelayStart() + n_offset, false); + return(false); // event not complete + } + // event complete + // finish update event will be re-added automatically at the end of routine) + } + } + else + { + // delaying had just started, record the moment + m_Spell->SetDelayStart(e_time); + // re-plan the event for the delay moment + m_Spell->GetCaster()->m_Events.AddEvent(this, e_time + m_Spell->GetDelayMoment(), false); + return(false); // event not complete + } + } break; + + default: + { + // all other states + // event will be re-added automatically at the end of routine) + } break; + } + + // spell processing not complete, plan event on the next update interval + m_Spell->GetCaster()->m_Events.AddEvent(this, e_time + 1, false); + return(false); // event not complete +} + +void SpellEvent::Abort(uint64 /*e_time*/) +{ + // oops, the spell we try to do is aborted + if (m_Spell->getState() != SPELL_STATE_FINISHED) + m_Spell->cancel(); +} diff --git a/src/game/Spell.h b/src/game/Spell.h new file mode 100644 index 000000000..093a91570 --- /dev/null +++ b/src/game/Spell.h @@ -0,0 +1,701 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SPELL_H +#define __SPELL_H + +#include "GridDefines.h" + +class WorldSession; +class Unit; +class DynamicObj; +class Player; +class GameObject; +class Group; +class Aura; + +enum SpellCastTargetFlags +{ + /*TARGET_FLAG_NONE = 0x0000, + TARGET_FLAG_SWIMMER = 0x0002, + TARGET_FLAG_ITEM = 0x0010, + TARGET_FLAG_SOURCE_AREA = 0x0020, + TARGET_FLAG_DEST_AREA = 0x0040, + TARGET_FLAG_UNKNOWN = 0x0080, + TARGET_FLAG_SELF = 0x0100, + TARGET_FLAG_PVP_CORPSE = 0x0200, + TARGET_FLAG_MASS_SPIRIT_HEAL = 0x0400, + TARGET_FLAG_BEAST_CORPSE = 0x0402, + TARGET_FLAG_OBJECT = 0x4000, + TARGET_FLAG_RESURRECTABLE = 0x8000*/ + + TARGET_FLAG_SELF = 0x00000000, + TARGET_FLAG_UNIT = 0x00000002, // pguid + TARGET_FLAG_ITEM = 0x00000010, // pguid + TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float + TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float + TARGET_FLAG_OBJECT_UNK = 0x00000080, // ? + TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid + TARGET_FLAG_OBJECT = 0x00000800, // pguid + TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid + TARGET_FLAG_STRING = 0x00002000, // string + TARGET_FLAG_UNK1 = 0x00004000, // ? + TARGET_FLAG_CORPSE = 0x00008000, // pguid + TARGET_FLAG_UNK2 = 0x00010000 // pguid +}; + +enum SpellCastFlags +{ + CAST_FLAG_UNKNOWN1 = 0x00000002, + CAST_FLAG_UNKNOWN2 = 0x00000010, + CAST_FLAG_AMMO = 0x00000020, + CAST_FLAG_UNKNOWN8 = 0x00000040, + CAST_FLAG_UNKNOWN9 = 0x00000080, + CAST_FLAG_UNKNOWN3 = 0x00000100, + CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk + CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk + CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk + CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk +}; + +enum SpellNotifyPushType +{ + PUSH_IN_FRONT, + PUSH_IN_BACK, + PUSH_SELF_CENTER, + PUSH_DEST_CENTER, + PUSH_TARGET_CENTER +}; + +bool IsQuestTameSpell(uint32 spellId); + +namespace MaNGOS +{ + struct SpellNotifierPlayer; + struct SpellNotifierCreatureAndPlayer; +} + +class SpellCastTargets +{ + public: + SpellCastTargets(); + ~SpellCastTargets(); + + bool read ( WorldPacket * data, Unit *caster ); + void write ( WorldPacket * data ); + + SpellCastTargets& operator=(const SpellCastTargets &target) + { + m_unitTarget = target.m_unitTarget; + m_itemTarget = target.m_itemTarget; + m_GOTarget = target.m_GOTarget; + + m_unitTargetGUID = target.m_unitTargetGUID; + m_GOTargetGUID = target.m_GOTargetGUID; + m_CorpseTargetGUID = target.m_CorpseTargetGUID; + m_itemTargetGUID = target.m_itemTargetGUID; + + m_itemTargetEntry = target.m_itemTargetEntry; + + m_srcX = target.m_srcX; + m_srcY = target.m_srcY; + m_srcZ = target.m_srcZ; + + m_destX = target.m_destX; + m_destY = target.m_destY; + m_destZ = target.m_destZ; + + m_strTarget = target.m_strTarget; + + m_targetMask = target.m_targetMask; + + return *this; + } + + uint64 getUnitTargetGUID() const { return m_unitTargetGUID; } + Unit *getUnitTarget() const { return m_unitTarget; } + void setUnitTarget(Unit *target); + void setDestination(float x, float y, float z); + + uint64 getGOTargetGUID() const { return m_GOTargetGUID; } + GameObject *getGOTarget() const { return m_GOTarget; } + void setGOTarget(GameObject *target); + + uint64 getCorpseTargetGUID() const { return m_CorpseTargetGUID; } + void setCorpseTarget(Corpse* corpse); + uint64 getItemTargetGUID() const { return m_itemTargetGUID; } + Item* getItemTarget() const { return m_itemTarget; } + uint32 getItemTargetEntry() const { return m_itemTargetEntry; } + void setItemTarget(Item* item); + void updateTradeSlotItem() + { + if(m_itemTarget && (m_targetMask & TARGET_FLAG_TRADE_ITEM)) + { + m_itemTargetGUID = m_itemTarget->GetGUID(); + m_itemTargetEntry = m_itemTarget->GetEntry(); + } + } + + bool IsEmpty() const { return m_GOTargetGUID==0 && m_unitTargetGUID==0 && m_itemTarget==0 && m_CorpseTargetGUID==0; } + + void Update(Unit* caster); + + float m_srcX, m_srcY, m_srcZ; + float m_destX, m_destY, m_destZ; + std::string m_strTarget; + + uint32 m_targetMask; + private: + // objects (can be used at spell creating and after Update at casting + Unit *m_unitTarget; + GameObject *m_GOTarget; + Item *m_itemTarget; + + // object GUID/etc, can be used always + uint64 m_unitTargetGUID; + uint64 m_GOTargetGUID; + uint64 m_CorpseTargetGUID; + uint64 m_itemTargetGUID; + uint32 m_itemTargetEntry; +}; + +enum SpellState +{ + SPELL_STATE_NULL = 0, + SPELL_STATE_PREPARING = 1, + SPELL_STATE_CASTING = 2, + SPELL_STATE_FINISHED = 3, + SPELL_STATE_IDLE = 4, + SPELL_STATE_DELAYED = 5 +}; + +#define SPELL_SPELL_CHANNEL_UPDATE_INTERVAL 1000 + +typedef std::multimap SpellTargetTimeMap; + +class Spell +{ + friend struct MaNGOS::SpellNotifierPlayer; + friend struct MaNGOS::SpellNotifierCreatureAndPlayer; + public: + + void EffectNULL(uint32 ); + void EffectUnused(uint32 ); + void EffectDistract(uint32 i); + void EffectPull(uint32 i); + void EffectSchoolDMG(uint32 i); + void EffectEnvirinmentalDMG(uint32 i); + void EffectInstaKill(uint32 i); + void EffectDummy(uint32 i); + void EffectTeleportUnits(uint32 i); + void EffectApplyAura(uint32 i); + void EffectSendEvent(uint32 i); + void EffectPowerBurn(uint32 i); + void EffectPowerDrain(uint32 i); + void EffectHeal(uint32 i); + void EffectHealthLeech(uint32 i); + void EffectQuestComplete(uint32 i); + void EffectCreateItem(uint32 i); + void EffectPersistentAA(uint32 i); + void EffectEnergize(uint32 i); + void EffectOpenLock(uint32 i); + void EffectSummonChangeItem(uint32 i); + void EffectOpenSecretSafe(uint32 i); + void EffectProficiency(uint32 i); + void EffectApplyAreaAura(uint32 i); + void EffectSummonType(uint32 i); + void EffectSummon(uint32 i); + void EffectLearnSpell(uint32 i); + void EffectDispel(uint32 i); + void EffectDualWield(uint32 i); + void EffectPickPocket(uint32 i); + void EffectAddFarsight(uint32 i); + void EffectSummonWild(uint32 i); + void EffectSummonGuardian(uint32 i); + void EffectHealMechanical(uint32 i); + void EffectTeleUnitsFaceCaster(uint32 i); + void EffectLearnSkill(uint32 i); + void EffectAddHonor(uint32 i); + void EffectTradeSkill(uint32 i); + void EffectEnchantItemPerm(uint32 i); + void EffectEnchantItemTmp(uint32 i); + void EffectTameCreature(uint32 i); + void EffectSummonPet(uint32 i); + void EffectLearnPetSpell(uint32 i); + void EffectWeaponDmg(uint32 i); + void EffectForceCast(uint32 i); + void EffectTriggerSpell(uint32 i); + void EffectTriggerMissileSpell(uint32 i); + void EffectThreat(uint32 i); + void EffectHealMaxHealth(uint32 i); + void EffectInterruptCast(uint32 i); + void EffectSummonObjectWild(uint32 i); + void EffectScriptEffect(uint32 i); + void EffectSanctuary(uint32 i); + void EffectAddComboPoints(uint32 i); + void EffectDuel(uint32 i); + void EffectStuck(uint32 i); + void EffectSummonPlayer(uint32 i); + void EffectActivateObject(uint32 i); + void EffectSummonTotem(uint32 i); + void EffectEnchantHeldItem(uint32 i); + void EffectSummonObject(uint32 i); + void EffectResurrect(uint32 i); + void EffectParry(uint32 i); + void EffectBlock(uint32 i); + void EffectMomentMove(uint32 i); + void EffectTransmitted(uint32 i); + void EffectDisEnchant(uint32 i); + void EffectInebriate(uint32 i); + void EffectFeedPet(uint32 i); + void EffectDismissPet(uint32 i); + void EffectReputation(uint32 i); + void EffectSelfResurrect(uint32 i); + void EffectSkinning(uint32 i); + void EffectCharge(uint32 i); + void EffectProspecting(uint32 i); + void EffectSendTaxi(uint32 i); + void EffectSummonCritter(uint32 i); + void EffectKnockBack(uint32 i); + void EffectPlayerPull(uint32 i); + void EffectDispelMechanic(uint32 i); + void EffectSummonDeadPet(uint32 i); + void EffectDestroyAllTotems(uint32 i); + void EffectDurabilityDamage(uint32 i); + void EffectSkill(uint32 i); + void EffectTaunt(uint32 i); + void EffectDurabilityDamagePCT(uint32 i); + void EffectModifyThreatPercent(uint32 i); + void EffectResurrectNew(uint32 i); + void EffectAddExtraAttacks(uint32 i); + void EffectSpiritHeal(uint32 i); + void EffectSkinPlayerCorpse(uint32 i); + void EffectSummonDemon(uint32 i); + void EffectStealBeneficialBuff(uint32 i); + void EffectUnlearnSpecialization(uint32 i); + void EffectHealPct(uint32 i); + void EffectEnergisePct(uint32 i); + void EffectTriggerSpellWithValue(uint32 i); + void EffectTriggerRitualOfSummoning(uint32 i); + void EffectKillCredit(uint32 i); + void EffectQuestFail(uint32 i); + + Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL ); + ~Spell(); + + void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL); + void cancel(); + void update(uint32 difftime); + void cast(bool skipCheck = false); + void finish(bool ok = true); + void TakePower(); + void TakeReagents(); + void TakeCastItem(); + void TriggerSpell(); + uint8 CanCast(bool strict); + int16 PetCanCast(Unit* target); + bool CanAutoCast(Unit* target); + + // handlers + void handle_immediate(); + uint64 handle_delayed(uint64 t_offset); + // handler helpers + void _handle_immediate_phase(); + void _handle_finish_phase(); + + uint8 CheckItems(); + uint8 CheckRange(bool strict); + uint8 CheckPower(); + uint8 CheckCasterAuras() const; + + int32 CalculateDamage(uint8 i, Unit* target) { return m_caster->CalculateSpellDamage(m_spellInfo,i,m_currentBasePoints[i],target); } + int32 CalculatePowerCost(); + + bool HaveTargetsForEffect(uint8 effect) const; + void Delayed(); + void DelayedChannel(); + inline uint32 getState() const { return m_spellState; } + void setState(uint32 state) { m_spellState = state; } + + void DoCreateItem(uint32 i, uint32 itemtype); + + void WriteSpellGoTargets( WorldPacket * data ); + void WriteAmmoToPacket( WorldPacket * data ); + void FillTargetMap(); + + void SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap); + + Unit* SelectMagnetTarget(); + bool CheckTarget( Unit* target, uint32 eff, bool hitPhase ); + + void SendCastResult(uint8 result); + void SendSpellStart(); + void SendSpellGo(); + void SendSpellCooldown(); + void SendLogExecute(); + void SendInterrupted(uint8 result); + void SendChannelUpdate(uint32 time); + void SendChannelStart(uint32 duration); + void SendResurrectRequest(Player* target); + void SendPlaySpellVisual(uint32 SpellID); + + void HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float DamageMultiplier = 1.0); + void HandleThreatSpells(uint32 spellId); + //void HandleAddAura(Unit* Target); + + SpellEntry const* m_spellInfo; + int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points + Item* m_CastItem; + uint8 m_cast_count; + SpellCastTargets m_targets; + + int32 GetCastTime() const { return m_casttime; } + bool IsAutoRepeat() const { return m_autoRepeat; } + void SetAutoRepeat(bool rep) { m_autoRepeat = rep; } + void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; } + bool IsNextMeleeSwingSpell() const + { + return m_spellInfo->Attributes & (SPELL_ATTR_ON_NEXT_SWING_1|SPELL_ATTR_ON_NEXT_SWING_2); + } + bool IsRangedSpell() const + { + return m_spellInfo->Attributes & SPELL_ATTR_RANGED; + } + bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; } + bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } + bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } + + bool IsDeletable() const { return m_deletable; } + void SetDeletable(bool deletable) { m_deletable = deletable; } + uint64 GetDelayStart() const { return m_delayStart; } + void SetDelayStart(uint64 m_time) { m_delayStart = m_time; } + uint64 GetDelayMoment() const { return m_delayMoment; } + + bool IsNeedSendToClient() const; + + CurrentSpellTypes GetCurrentContainer(); + + Unit* GetCaster() const { return m_caster; } + Unit* GetOriginalCaster() const { return m_originalCaster; } + int32 GetPowerCost() const { return m_powerCost; } + + void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) + + bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId); + + bool CheckTargetCreatureType(Unit* target) const; + + void AddTriggeredSpell(SpellEntry const* spell) { m_TriggerSpells.push_back(spell); } + + void CleanupTargetList(); + protected: + + void SendLoot(uint64 guid, LootType loottype); + + Unit* m_caster; + + uint64 m_originalCasterGUID; // real source of cast (aura caster/etc), used for spell targets selection + // e.g. damage around area spell trigered by victim aura and da,age emeies of aura caster + Unit* m_originalCaster; // cached pointer for m_originalCaster, updated at Spell::UpdatePointers() + + Spell** m_selfContainer; // pointer to our spell container (if applicable) + Spell** m_triggeringContainer; // pointer to container with spell that has triggered us + + //Spell data + SpellSchoolMask m_spellSchoolMask; // Spell school (can be overwrite for some spells (wand shoot for example) + WeaponAttackType m_attackType; // For weapon based attack + int32 m_powerCost; // Calculated spell cost initialized only in Spell::prepare + int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare + bool m_canReflect; // can reflect this spell? + bool m_autoRepeat; + + uint8 m_delayAtDamageCount; + int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; } + + // Delayed spells system + uint64 m_delayStart; // time of spell delay start, filled by event handler, zero = just started + uint64 m_delayMoment; // moment of next delay call, used internally + bool m_immediateHandled; // were immediate actions handled? (used by delayed spells only) + + // These vars are used in both delayed spell system and modified immediate spell system + bool m_deletable; // is the spell pending deletion or must be updated till permitted to delete? + bool m_needSpellLog; // need to send spell log? + uint8 m_applyMultiplierMask; // by effect: damage multiplier needed? + float m_damageMultipliers[3]; // by effect: damage multiplier + + // Current targets, to be used in SpellEffects (MUST BE USED ONLY IN SPELL EFFECTS) + Unit* unitTarget; + Item* itemTarget; + GameObject* gameObjTarget; + int32 damage; + + // this is set in Spell Hit, but used in Apply Aura handler + DiminishingLevels m_diminishLevel; + DiminishingGroup m_diminishGroup; + + // ------------------------------------------- + GameObject* focusObject; + + //****************************************** + // Spell trigger system + //****************************************** + void doTriggers(SpellMissInfo missInfo, uint32 damage=0, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NONE, uint32 block=0, uint32 absorb=0, bool crit=false); + + //***************************************** + // Spell target subsystem + //***************************************** + // Targets store structures and data + uint32 m_countOfHit; + uint32 m_countOfMiss; + struct TargetInfo + { + uint64 targetGUID; + uint64 timeDelay; + SpellMissInfo missCondition:8; + SpellMissInfo reflectResult:8; + uint8 effectMask:8; + bool processed:1; + }; + std::list m_UniqueTargetInfo; + uint8 m_needAliveTargetMask; // Mask req. alive targets + + struct GOTargetInfo + { + uint64 targetGUID; + uint64 timeDelay; + uint8 effectMask:8; + bool processed:1; + }; + std::list m_UniqueGOTargetInfo; + + struct ItemTargetInfo + { + Item *item; + uint8 effectMask; + }; + std::list m_UniqueItemInfo; + + void AddUnitTarget(Unit* target, uint32 effIndex); + void AddUnitTarget(uint64 unitGUID, uint32 effIndex); + void AddGOTarget(GameObject* target, uint32 effIndex); + void AddGOTarget(uint64 goGUID, uint32 effIndex); + void AddItemTarget(Item* target, uint32 effIndex); + void DoAllEffectOnTarget(TargetInfo *target); + void DoSpellHitOnUnit(Unit *unit, uint32 effectMask); + void DoAllEffectOnTarget(GOTargetInfo *target); + void DoAllEffectOnTarget(ItemTargetInfo *target); + bool IsAliveUnitPresentInTargetList(); + // ------------------------------------------- + + //List For Triggered Spells + typedef std::list TriggerSpells; + TriggerSpells m_TriggerSpells; + + uint32 m_spellState; + uint32 m_timer; + + float m_castPositionX; + float m_castPositionY; + float m_castPositionZ; + float m_castOrientation; + bool m_IsTriggeredSpell; + + // if need this can be replaced by Aura copy + // we can't store original aura link to prevent access to deleted auras + // and in same time need aura data and after aura deleting. + SpellEntry const* m_triggeredByAuraSpell; +}; + +enum ReplenishType +{ + REPLENISH_UNDEFINED = 0, + REPLENISH_HEALTH = 20, + REPLENISH_MANA = 21, + REPLENISH_RAGE = 22 +}; + +enum SpellTargets +{ + SPELL_TARGETS_HOSTILE, + SPELL_TARGETS_NOT_FRIENDLY, + SPELL_TARGETS_NOT_HOSTILE, + SPELL_TARGETS_FRIENDLY, + SPELL_TARGETS_AOE_DAMAGE +}; + +namespace MaNGOS +{ + struct MANGOS_DLL_DECL SpellNotifierPlayer + { + std::list &i_data; + Spell &i_spell; + const uint32& i_index; + float i_radius; + Unit* i_originalCaster; + + SpellNotifierPlayer(Spell &spell, std::list &data, const uint32 &i, float radius) + : i_data(data), i_spell(spell), i_index(i), i_radius(radius) + { + i_originalCaster = i_spell.GetOriginalCaster(); + } + + void Visit(PlayerMapType &m) + { + if(!i_originalCaster) + return; + + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + { + Player * pPlayer = itr->getSource(); + if( !pPlayer->isAlive() || pPlayer->isInFlight()) + continue; + + if( i_originalCaster->IsFriendlyTo(pPlayer) ) + continue; + + if( pPlayer->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius ) + i_data.push_back(pPlayer); + } + } + template void Visit(GridRefManager &) {} + }; + + struct MANGOS_DLL_DECL SpellNotifierCreatureAndPlayer + { + std::list *i_data; + Spell &i_spell; + const uint32& i_push_type; + float i_radius; + SpellTargets i_TargetType; + Unit* i_originalCaster; + + SpellNotifierCreatureAndPlayer(Spell &spell, std::list &data, float radius, const uint32 &type, + SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY) + : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType) + { + i_originalCaster = spell.GetOriginalCaster(); + } + + template inline void Visit(GridRefManager &m) + { + assert(i_data); + + if(!i_originalCaster) + return; + + for(typename GridRefManager::iterator itr = m.begin(); itr != m.end(); ++itr) + { + if( !itr->getSource()->isAlive() || (itr->getSource()->GetTypeId() == TYPEID_PLAYER && ((Player*)itr->getSource())->isInFlight())) + continue; + + switch (i_TargetType) + { + case SPELL_TARGETS_HOSTILE: + if (!itr->getSource()->isTargetableForAttack() || !i_originalCaster->IsHostileTo( itr->getSource() )) + continue; + break; + case SPELL_TARGETS_NOT_FRIENDLY: + if (!itr->getSource()->isTargetableForAttack() || i_originalCaster->IsFriendlyTo( itr->getSource() )) + continue; + break; + case SPELL_TARGETS_NOT_HOSTILE: + if (!itr->getSource()->isTargetableForAttack() || i_originalCaster->IsHostileTo( itr->getSource() )) + continue; + break; + case SPELL_TARGETS_FRIENDLY: + if (!itr->getSource()->isTargetableForAttack() || !i_originalCaster->IsFriendlyTo( itr->getSource() )) + continue; + break; + case SPELL_TARGETS_AOE_DAMAGE: + { + if(itr->getSource()->GetTypeId()==TYPEID_UNIT && ((Creature*)itr->getSource())->isTotem()) + continue; + if(!itr->getSource()->isTargetableForAttack()) + continue; + + Unit* check = i_originalCaster->GetCharmerOrOwnerOrSelf(); + + if( check->GetTypeId()==TYPEID_PLAYER ) + { + if (check->IsFriendlyTo( itr->getSource() )) + continue; + } + else + { + if (!check->IsHostileTo( itr->getSource() )) + continue; + } + } + break; + default: continue; + } + + switch(i_push_type) + { + case PUSH_IN_FRONT: + if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) + i_data->push_back(itr->getSource()); + break; + case PUSH_IN_BACK: + if(i_spell.GetCaster()->isInBack((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) + i_data->push_back(itr->getSource()); + break; + case PUSH_SELF_CENTER: + if(i_spell.GetCaster()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) + i_data->push_back(itr->getSource()); + break; + case PUSH_DEST_CENTER: + if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius )) + i_data->push_back(itr->getSource()); + break; + case PUSH_TARGET_CENTER: + if(i_spell.m_targets.getUnitTarget()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) + i_data->push_back(itr->getSource()); + break; + } + } + } + + #ifdef WIN32 + template<> inline void Visit(CorpseMapType & ) {} + template<> inline void Visit(GameObjectMapType & ) {} + template<> inline void Visit(DynamicObjectMapType & ) {} + #endif + }; + + #ifndef WIN32 + template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType& ) {} + template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType& ) {} + template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType& ) {} + #endif +} + +typedef void(Spell::*pEffect)(uint32 i); + +class SpellEvent : public BasicEvent +{ + public: + SpellEvent(Spell* spell); + virtual ~SpellEvent(); + + virtual bool Execute(uint64 e_time, uint32 p_time); + virtual void Abort(uint64 e_time); + protected: + Spell* m_Spell; +}; +#endif diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h new file mode 100644 index 000000000..7b6f72b5c --- /dev/null +++ b/src/game/SpellAuraDefines.h @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef MANGOS_SPELLAURADEFINES_H +#define MANGOS_SPELLAURADEFINES_H + +#define MAX_AURAS 56 +#define MAX_POSITIVE_AURAS 40 + +enum AURA_FLAGS +{ + AFLAG_NEGATIVE = 0x09, + AFLAG_POSITIVE = 0x1F, + AFLAG_MASK = 0xFF +}; + +//m_schoolAbsorb +enum DAMAGE_ABSORB_TYPE +{ + ALL_DAMAGE_ABSORB = -2, + ONLY_MAGIC_ABSORB = -1, +}; + +enum AuraType +{ + SPELL_AURA_NONE = 0, + SPELL_AURA_BIND_SIGHT = 1, + SPELL_AURA_MOD_POSSESS = 2, + SPELL_AURA_PERIODIC_DAMAGE = 3, + SPELL_AURA_DUMMY = 4, + SPELL_AURA_MOD_CONFUSE = 5, + SPELL_AURA_MOD_CHARM = 6, + SPELL_AURA_MOD_FEAR = 7, + SPELL_AURA_PERIODIC_HEAL = 8, + SPELL_AURA_MOD_ATTACKSPEED = 9, + SPELL_AURA_MOD_THREAT = 10, + SPELL_AURA_MOD_TAUNT = 11, + SPELL_AURA_MOD_STUN = 12, + SPELL_AURA_MOD_DAMAGE_DONE = 13, + SPELL_AURA_MOD_DAMAGE_TAKEN = 14, + SPELL_AURA_DAMAGE_SHIELD = 15, + SPELL_AURA_MOD_STEALTH = 16, + SPELL_AURA_MOD_DETECT = 17, + SPELL_AURA_MOD_INVISIBILITY = 18, + SPELL_AURA_MOD_INVISIBILITY_DETECTION = 19, + SPELL_AURA_OBS_MOD_HEALTH = 20, //20,21 unofficial + SPELL_AURA_OBS_MOD_MANA = 21, + SPELL_AURA_MOD_RESISTANCE = 22, + SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23, + SPELL_AURA_PERIODIC_ENERGIZE = 24, + SPELL_AURA_MOD_PACIFY = 25, + SPELL_AURA_MOD_ROOT = 26, + SPELL_AURA_MOD_SILENCE = 27, + SPELL_AURA_REFLECT_SPELLS = 28, + SPELL_AURA_MOD_STAT = 29, + SPELL_AURA_MOD_SKILL = 30, + SPELL_AURA_MOD_INCREASE_SPEED = 31, + SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32, + SPELL_AURA_MOD_DECREASE_SPEED = 33, + SPELL_AURA_MOD_INCREASE_HEALTH = 34, + SPELL_AURA_MOD_INCREASE_ENERGY = 35, + SPELL_AURA_MOD_SHAPESHIFT = 36, + SPELL_AURA_EFFECT_IMMUNITY = 37, + SPELL_AURA_STATE_IMMUNITY = 38, + SPELL_AURA_SCHOOL_IMMUNITY = 39, + SPELL_AURA_DAMAGE_IMMUNITY = 40, + SPELL_AURA_DISPEL_IMMUNITY = 41, + SPELL_AURA_PROC_TRIGGER_SPELL = 42, + SPELL_AURA_PROC_TRIGGER_DAMAGE = 43, + SPELL_AURA_TRACK_CREATURES = 44, + SPELL_AURA_TRACK_RESOURCES = 45, + SPELL_AURA_MOD_PARRY_SKILL = 46, + SPELL_AURA_MOD_PARRY_PERCENT = 47, + SPELL_AURA_MOD_DODGE_SKILL = 48, + SPELL_AURA_MOD_DODGE_PERCENT = 49, + SPELL_AURA_MOD_BLOCK_SKILL = 50, + SPELL_AURA_MOD_BLOCK_PERCENT = 51, + SPELL_AURA_MOD_CRIT_PERCENT = 52, + SPELL_AURA_PERIODIC_LEECH = 53, + SPELL_AURA_MOD_HIT_CHANCE = 54, + SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55, + SPELL_AURA_TRANSFORM = 56, + SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57, + SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58, + SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59, + SPELL_AURA_MOD_PACIFY_SILENCE = 60, + SPELL_AURA_MOD_SCALE = 61, + SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62, + SPELL_AURA_PERIODIC_MANA_FUNNEL = 63, + SPELL_AURA_PERIODIC_MANA_LEECH = 64, + SPELL_AURA_MOD_CASTING_SPEED = 65, + SPELL_AURA_FEIGN_DEATH = 66, + SPELL_AURA_MOD_DISARM = 67, + SPELL_AURA_MOD_STALKED = 68, + SPELL_AURA_SCHOOL_ABSORB = 69, + SPELL_AURA_EXTRA_ATTACKS = 70, + SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71, + SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT = 72, + SPELL_AURA_MOD_POWER_COST_SCHOOL = 73, + SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74, + SPELL_AURA_MOD_LANGUAGE = 75, + SPELL_AURA_FAR_SIGHT = 76, + SPELL_AURA_MECHANIC_IMMUNITY = 77, + SPELL_AURA_MOUNTED = 78, + SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79, + SPELL_AURA_MOD_PERCENT_STAT = 80, + SPELL_AURA_SPLIT_DAMAGE_PCT = 81, + SPELL_AURA_WATER_BREATHING = 82, + SPELL_AURA_MOD_BASE_RESISTANCE = 83, + SPELL_AURA_MOD_REGEN = 84, + SPELL_AURA_MOD_POWER_REGEN = 85, + SPELL_AURA_CHANNEL_DEATH_ITEM = 86, + SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87, + SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88, + SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89, + SPELL_AURA_MOD_RESIST_CHANCE = 90, + SPELL_AURA_MOD_DETECT_RANGE = 91, + SPELL_AURA_PREVENTS_FLEEING = 92, + SPELL_AURA_MOD_UNATTACKABLE = 93, + SPELL_AURA_INTERRUPT_REGEN = 94, + SPELL_AURA_GHOST = 95, + SPELL_AURA_SPELL_MAGNET = 96, + SPELL_AURA_MANA_SHIELD = 97, + SPELL_AURA_MOD_SKILL_TALENT = 98, + SPELL_AURA_MOD_ATTACK_POWER = 99, + SPELL_AURA_AURAS_VISIBLE = 100, + SPELL_AURA_MOD_RESISTANCE_PCT = 101, + SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS = 102, + SPELL_AURA_MOD_TOTAL_THREAT = 103, + SPELL_AURA_WATER_WALK = 104, + SPELL_AURA_FEATHER_FALL = 105, + SPELL_AURA_HOVER = 106, + SPELL_AURA_ADD_FLAT_MODIFIER = 107, + SPELL_AURA_ADD_PCT_MODIFIER = 108, + SPELL_AURA_ADD_TARGET_TRIGGER = 109, + SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110, + SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111, + SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112, + SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113, + SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114, + SPELL_AURA_MOD_HEALING = 115, + SPELL_AURA_MOD_REGEN_DURING_COMBAT = 116, + SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117, + SPELL_AURA_MOD_HEALING_PCT = 118, + SPELL_AURA_SHARE_PET_TRACKING = 119, + SPELL_AURA_UNTRACKABLE = 120, + SPELL_AURA_EMPATHY = 121, + SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122, + SPELL_AURA_MOD_TARGET_RESISTANCE = 123, + SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124, + SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125, + SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126, + SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127, + SPELL_AURA_MOD_POSSESS_PET = 128, + SPELL_AURA_MOD_SPEED_ALWAYS = 129, + SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130, + SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS = 131, + SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132, + SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133, + SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134, + SPELL_AURA_MOD_HEALING_DONE = 135, + SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136, + SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137, + SPELL_AURA_MOD_HASTE = 138, + SPELL_AURA_FORCE_REACTION = 139, + SPELL_AURA_MOD_RANGED_HASTE = 140, + SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141, + SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142, + SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143, + SPELL_AURA_SAFE_FALL = 144, + SPELL_AURA_CHARISMA = 145, + SPELL_AURA_PERSUADED = 146, + SPELL_AURA_ADD_CREATURE_IMMUNITY = 147, + SPELL_AURA_RETAIN_COMBO_POINTS = 148, + SPELL_AURA_RESIST_PUSHBACK = 149, // Resist Pushback + SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, + SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed + SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range + SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat + SPELL_AURA_MOD_STEALTH_LEVEL = 154, // Stealth Level Modifier + SPELL_AURA_MOD_WATER_BREATHING = 155, // Mod Water Breathing + SPELL_AURA_MOD_REPUTATION_GAIN = 156, // Mod Reputation Gain + SPELL_AURA_PET_DAMAGE_MULTI = 157, // Mod Pet Damage + SPELL_AURA_MOD_SHIELD_BLOCKVALUE = 158, + SPELL_AURA_NO_PVP_CREDIT = 159, + SPELL_AURA_MOD_AOE_AVOIDANCE = 160, + SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161, + SPELL_AURA_POWER_BURN_MANA = 162, + SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE = 163, + SPELL_AURA_164 = 164, + SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS = 165, + SPELL_AURA_MOD_ATTACK_POWER_PCT = 166, + SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT = 167, + SPELL_AURA_MOD_DAMAGE_DONE_VERSUS = 168, + SPELL_AURA_MOD_CRIT_PERCENT_VERSUS = 169, + SPELL_AURA_DETECT_AMORE = 170, + SPELL_AURA_MOD_SPEED_NOT_STACK = 171, + SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172, + SPELL_AURA_ALLOW_CHAMPION_SPELLS = 173, + SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT + SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175, + SPELL_AURA_SPIRIT_OF_REDEMPTION = 176, + SPELL_AURA_AOE_CHARM = 177, + SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178, + SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179, + SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180, + SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS = 181, // unused - possible flat spell crit damage versus + SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT = 182, + SPELL_AURA_MOD_CRITICAL_THREAT = 183, + SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE = 184, + SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE= 185, + SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE = 186, + SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE = 187, + SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE = 188, + SPELL_AURA_MOD_RATING = 189, + SPELL_AURA_MOD_FACTION_REPUTATION_GAIN = 190, + SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191, + SPELL_AURA_HASTE_MELEE = 192, + SPELL_AURA_MELEE_SLOW = 193, + SPELL_AURA_MOD_DEPRICATED_1 = 194, // not used now, old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT + SPELL_AURA_MOD_DEPRICATED_2 = 195, // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT + SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath + SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197, + SPELL_AURA_MOD_ALL_WEAPON_SKILLS = 198, + SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199, + SPELL_AURA_MOD_XP_PCT = 200, + SPELL_AURA_FLY = 201, + SPELL_AURA_IGNORE_COMBAT_RESULT = 202, + SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE = 203, + SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE = 204, + SPELL_AURA_205 = 205, // unused + SPELL_AURA_MOD_SPEED_MOUNTED = 206, // ? used in strange spells + SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 207, + SPELL_AURA_MOD_SPEED_FLIGHT = 208, + SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS = 209, + SPELL_AURA_210 = 210, // unused + SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK = 211, + SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT = 212, + SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT = 213, + SPELL_AURA_214 = 214, + SPELL_AURA_ARENA_PREPARATION = 215, + SPELL_AURA_HASTE_SPELLS = 216, + SPELL_AURA_217 = 217, + SPELL_AURA_HASTE_RANGED = 218, + SPELL_AURA_MOD_MANA_REGEN_FROM_STAT = 219, + SPELL_AURA_MOD_RATING_FROM_STAT = 220, + SPELL_AURA_221 = 221, + SPELL_AURA_222 = 222, + SPELL_AURA_223 = 223, + SPELL_AURA_224 = 224, + SPELL_AURA_PRAYER_OF_MENDING = 225, + SPELL_AURA_PERIODIC_DUMMY = 226, + SPELL_AURA_227 = 227, + SPELL_AURA_DETECT_STEALTH = 228, + SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229, + SPELL_AURA_230 = 230, + SPELL_AURA_231 = 231, + SPELL_AURA_MECHANIC_DURATION_MOD = 232, + SPELL_AURA_233 = 233, + SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234, + SPELL_AURA_MOD_DISPEL_RESIST = 235, + SPELL_AURA_236 = 236, + SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237, + SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238, + SPELL_AURA_MOD_SCALE_2 = 239, + SPELL_AURA_MOD_EXPERTISE = 240, + SPELL_AURA_FORCE_MOVE_FORWARD = 241, + SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242, + SPELL_AURA_243 = 243, + SPELL_AURA_COMPREHEND_LANGUAGE = 244, + SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245, + SPELL_AURA_246 = 246, + SPELL_AURA_247 = 247, + SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248, + SPELL_AURA_249 = 249, + SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250, + SPELL_AURA_MOD_ENEMY_DODGE = 251, + SPELL_AURA_252 = 252, + SPELL_AURA_253 = 253, + SPELL_AURA_254 = 254, + SPELL_AURA_255 = 255, + SPELL_AURA_256 = 256, + SPELL_AURA_257 = 257, + SPELL_AURA_258 = 258, + SPELL_AURA_259 = 259, + SPELL_AURA_260 = 260, + SPELL_AURA_261 = 261, + TOTAL_AURAS=262 +}; + +enum AreaAuraType +{ + AREA_AURA_PARTY, + AREA_AURA_FRIEND, + AREA_AURA_ENEMY, + AREA_AURA_PET, + AREA_AURA_OWNER +}; +#endif diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp new file mode 100644 index 000000000..26e77c85c --- /dev/null +++ b/src/game/SpellAuras.cpp @@ -0,0 +1,6360 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "UpdateMask.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Player.h" +#include "Unit.h" +#include "Spell.h" +#include "SpellAuras.h" +#include "DynamicObject.h" +#include "Group.h" +#include "UpdateData.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "Policies/SingletonImp.h" +#include "Totem.h" +#include "Creature.h" +#include "Formulas.h" +#include "BattleGround.h" +#include "CreatureAI.h" +#include "Util.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" + +#define NULL_AURA_SLOT 0xFF + +pAuraHandler AuraHandler[TOTAL_AURAS]= +{ + &Aura::HandleNULL, // 0 SPELL_AURA_NONE + &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT + &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS + &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE + &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY + &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE + &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM + &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR + &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL + &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED + &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT + &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT + &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN + &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE + &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage + &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH + &Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT + &Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY + &Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION + &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH + &Aura::HandleAuraModTotalManaPercentRegen, // 21 SPELL_AURA_OBS_MOD_MANA + &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE + &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL + &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE + &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY + &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT + &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE + &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult + &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT + &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL + &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED + &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED + &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED + &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH + &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY + &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT + &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY + &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY + &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY + &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY + &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY + &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell + &Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor + &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES + &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES + &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete? + &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT + &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete? + &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT + &Aura::HandleUnused, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete? + &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT + &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT + &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH + &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE + &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE + &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM + &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE + &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED + &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus + &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE + &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE + &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL + &Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete? + &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH + &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED + &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH + &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM + &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED + &Aura::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist + &Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect + &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL + &Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT + &Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL + &Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult + &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE + &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT + &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY + &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED + &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE + &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT + &Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT + &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING + &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE + &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN + &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN + &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM + &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT + &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT + &Aura::HandleUnused, // 90 SPELL_AURA_MOD_RESIST_CHANCE Useless + &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance + &Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING + &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE + &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll + &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST + &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget + &Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist + &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT + &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER + &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now + &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT + &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus + &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT + &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK + &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL + &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER + &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER + &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER + &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER + &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT + &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER + &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS + &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus + &Aura::HandleAuraHealing, //115 SPELL_AURA_MOD_HEALING + &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT + &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult + &Aura::HandleAuraHealingPct, //118 SPELL_AURA_MOD_HEALING_PCT + &Aura::HandleUnused, //119 SPELL_AURA_SHARE_PET_TRACKING useless + &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE + &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY + &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT + &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE + &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER + &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus + &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET + &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS + &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS + &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus + &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT + &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT + &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT + &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE + &Aura::HandleAuraHealingPct, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus + &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE + &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE + &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION + &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE + &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE + &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT + &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE + &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes + &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete? + &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete? + &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY + &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS + &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK + &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT + &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED + &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance + &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT + &Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL + &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING + &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN + &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI + &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE + &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell + &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemended in Unit::MagicSpellHitResult + &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT + &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA + &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE + &Aura::HandleUnused, //164 useless, only one test spell + &Aura::HandleAuraAttackPowerAttacker, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus + &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT + &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT + &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus + &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE only for Detect Amore spell + &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK + &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK + &Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell + &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus (by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT) + &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus + &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end + &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM + &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult + &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus + &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus + &Aura::HandleUnused, //181 SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS unused + &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT + &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT + &Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst + &Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst + &Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult + &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemended in Unit::GetUnitCriticalChance + &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance + &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING + &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN + &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED + &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE + &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) + &Aura::HandleUnused, //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT) + &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT) + &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN + &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance + &Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS + &Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult + &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP + &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode... + &Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst + &Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::DoAttackDamage + &Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::DoAttackDamage + &Aura::HandleNULL, //205 vulnerable to school dmg? + &Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED + &Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED + &Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive) + &Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS + &Aura::HandleNULL, //210 Commentator's Command + &Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK + &Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT + &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage + &Aura::HandleNULL, //214 Tamed Pet Passive + &Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION + &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS + &Aura::HandleUnused, //217 unused + &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED + &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT + &Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT + &Aura::HandleNULL, //221 ignored + &Aura::HandleUnused, //222 unused + &Aura::HandleNULL, //223 Cold Stare + &Aura::HandleUnused, //224 unused + &Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING + &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY + &Aura::HandleNULL, //227 periodic trigger spell + &Aura::HandleNoImmediateEffect, //228 stealth detection + &Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE + &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout + &Aura::HandleNULL, //231 + &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration + &Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue + &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration + &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult + &Aura::HandleUnused, //236 unused + &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus + &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus + &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61 + &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE + &Aura::HandleForceMoveForward, //241 Forces the player to move forward + &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING + &Aura::HandleUnused, //243 used by two test spells + &Aura::HandleComprehendLanguage, //244 Comprehend language + &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS + &Aura::HandleUnused, //246 unused + &Aura::HandleUnused, //247 unused + &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst + &Aura::HandleNULL, //249 + &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2 + &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE + &Aura::HandleUnused, //252 unused + &Aura::HandleUnused, //253 unused + &Aura::HandleUnused, //254 unused + &Aura::HandleUnused, //255 unused + &Aura::HandleUnused, //256 unused + &Aura::HandleUnused, //257 unused + &Aura::HandleUnused, //258 unused + &Aura::HandleUnused, //259 unused + &Aura::HandleUnused, //260 unused + &Aura::HandleNULL //261 SPELL_AURA_261 some phased state (44856 spell) +}; + +Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : +m_procCharges(0), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target), +m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS), +m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false), +m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false), +m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE) +{ + assert(target); + + assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element"); + + m_spellProto = spellproto; + + m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->EffectBasePoints[eff]; + + m_isPassive = IsPassiveSpell(GetId()); + m_positive = IsPositiveEffect(GetId(), m_effIndex); + + m_applyTime = time(NULL); + + int32 damage; + if(!caster) + { + m_caster_guid = target->GetGUID(); + damage = m_currentBasePoints+1; // stored value-1 + m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target); + } + else + { + m_caster_guid = caster->GetGUID(); + + damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target); + m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target); + + if (!damage && castItem && castItem->GetItemSuffixFactor()) + { + ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId())); + if(item_rand_suffix) + { + for (int k=0; k<3; k++) + { + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]); + if(pEnchant) + { + for (int t=0; t<3; t++) + if(pEnchant->spellid[t] == m_spellProto->Id) + { + damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 ); + break; + } + } + + if(damage) + break; + } + } + } + } + + if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0) + m_permanent = true; + + Player* modOwner = caster ? caster->GetSpellModOwner() : NULL; + + if(!m_permanent && modOwner) + modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration); + + m_duration = m_maxduration; + + if(modOwner) + modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer); + + sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage); + + m_effIndex = eff; + SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]); + + m_isDeathPersist = IsDeathPersistentSpell(m_spellProto); + + if(m_spellProto->procCharges) + { + m_procCharges = m_spellProto->procCharges; + + if(modOwner) + modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges); + } + else + m_procCharges = -1; + + m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances && + !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000)); +} + +Aura::~Aura() +{ +} + +AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +{ + m_isAreaAura = true; + + // caster==NULL in constructor args if target==caster in fact + Unit* caster_ptr = caster ? caster : target; + + m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex])); + if(Player* modOwner = caster_ptr->GetSpellModOwner()) + modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius); + + switch(spellproto->Effect[eff]) + { + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: + m_areaAuraType = AREA_AURA_PARTY; + if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) + m_modifier.m_auraname = SPELL_AURA_NONE; + break; + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: + m_areaAuraType = AREA_AURA_FRIEND; + break; + case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: + m_areaAuraType = AREA_AURA_ENEMY; + if(target == caster_ptr) + m_modifier.m_auraname = SPELL_AURA_NONE; // Do not do any effect on self + break; + case SPELL_EFFECT_APPLY_AREA_AURA_PET: + m_areaAuraType = AREA_AURA_PET; + break; + case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: + m_areaAuraType = AREA_AURA_OWNER; + if(target == caster_ptr) + m_modifier.m_auraname = SPELL_AURA_NONE; + break; + default: + sLog.outError("Wrong spell effect in AreaAura constructor"); + ASSERT(false); + break; + } +} + +AreaAura::~AreaAura() +{ +} + +PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +{ + m_isPersistent = true; +} + +PersistentAreaAura::~PersistentAreaAura() +{ +} + +SingleEnemyTargetAura::SingleEnemyTargetAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +{ + if (caster) + m_casters_target_guid = caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)caster)->GetSelection() : caster->GetUInt64Value(UNIT_FIELD_TARGET); + else + m_casters_target_guid = 0; +} + +SingleEnemyTargetAura::~SingleEnemyTargetAura() +{ +} + +Unit* SingleEnemyTargetAura::GetTriggerTarget() const +{ + return ObjectAccessor::GetUnit(*m_target, m_casters_target_guid); +} + +Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) +{ + if (IsAreaAuraEffect(spellproto->Effect[eff])) + return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem); + + uint32 triggeredSpellId = spellproto->EffectTriggerSpell[eff]; + + SpellEntry const* triggredSpellInfo = sSpellStore.LookupEntry(triggeredSpellId); + if (triggredSpellInfo) + for (int i = 0; i < 3; ++i) + if (triggredSpellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY) + return new SingleEnemyTargetAura(spellproto, eff, currentBasePoints, target, caster, castItem); + + return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem); +} + +Unit* Aura::GetCaster() const +{ + if(m_caster_guid==m_target->GetGUID()) + return m_target; + + //return ObjectAccessor::GetUnit(*m_target,m_caster_guid); + //must return caster even if it's in another grid/map + Unit *unit = ObjectAccessor::GetObjectInWorld(m_caster_guid, (Unit*)NULL); + return unit && unit->IsInWorld() ? unit : NULL; +} + +void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue) +{ + m_modifier.m_auraname = t; + m_modifier.m_amount = a; + m_modifier.m_miscvalue = miscValue; + m_modifier.periodictime = pt; +} + +void Aura::Update(uint32 diff) +{ + if (m_duration > 0) + { + m_duration -= diff; + if (m_duration < 0) + m_duration = 0; + m_timeCla -= diff; + + // GetEffIndex()==0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras + // all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0 + if(GetEffIndex()==0 && m_timeCla <= 0) + { + if(Unit* caster = GetCaster()) + { + Powers powertype = Powers(m_spellProto->powerType); + int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel(); + m_timeCla = 1000; + if (manaPerSecond) + { + if(powertype==POWER_HEALTH) + caster->ModifyHealth(-manaPerSecond); + else + caster->ModifyPower(powertype,-manaPerSecond); + } + } + } + } + + // Channeled aura required check distance from caster + if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID()) + { + Unit* caster = GetCaster(); + if(!caster) + { + m_target->RemoveAura(GetId(),GetEffIndex()); + return; + } + + // Get spell range + float radius; + SpellModOp mod; + if (m_spellProto->EffectRadiusIndex[GetEffIndex()]) + { + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()])); + mod = SPELLMOD_RADIUS; + } + else + { + radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)); + mod = SPELLMOD_RANGE; + } + + if(Player* modOwner = caster->GetSpellModOwner()) + modOwner->ApplySpellMod(GetId(), mod, radius,NULL); + + if(!caster->IsWithinDistInMap(m_target,radius)) + { + m_target->RemoveAura(GetId(),GetEffIndex()); + return; + } + } + + if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent)) + { + m_periodicTimer -= diff; + if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N + { + if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN || + m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN || + // Cannibalize, eating items and other spells + m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH || + // Eating items and other spells + m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA ) + { + ApplyModifier(true); + return; + } + // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls) + m_periodicTimer += m_modifier.periodictime; + + if(m_isTrigger) + TriggerSpell(); + else + PeriodicTick(); + } + } +} + +void AreaAura::Update(uint32 diff) +{ + // update for the caster of the aura + if(m_caster_guid == m_target->GetGUID()) + { + Unit* caster = m_target; + + if( !caster->hasUnitState(UNIT_STAT_ISOLATED) ) + { + Unit* owner = caster->GetCharmerOrOwner(); + if (!owner) + owner = caster; + std::list targets; + + switch(m_areaAuraType) + { + case AREA_AURA_PARTY: + { + Group *pGroup = NULL; + + if (owner->GetTypeId() == TYPEID_PLAYER) + pGroup = ((Player*)owner)->GetGroup(); + + if( pGroup) + { + uint8 subgroup = ((Player*)owner)->GetSubGroup(); + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + if(Target && Target->isAlive() && Target->GetSubGroup()==subgroup && caster->IsFriendlyTo(Target)) + { + if(caster->IsWithinDistInMap(Target, m_radius)) + targets.push_back(Target); + Pet *pet = Target->GetPet(); + if(pet && pet->isAlive() && caster->IsWithinDistInMap(pet, m_radius)) + targets.push_back(pet); + } + } + } + else + { + // add owner + if( owner != caster && caster->IsWithinDistInMap(owner, m_radius) ) + targets.push_back(owner); + // add caster's pet + Unit* pet = caster->GetPet(); + if( pet && caster->IsWithinDistInMap(pet, m_radius)) + targets.push_back(pet); + } + break; + } + case AREA_AURA_FRIEND: + { + CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(caster, owner, m_radius); + MaNGOS::UnitListSearcher searcher(targets, u_check); + TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); + TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster)); + cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster)); + break; + } + case AREA_AURA_ENEMY: + { + CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(caster, owner, m_radius); // No GetCharmer in searcher + MaNGOS::UnitListSearcher searcher(targets, u_check); + TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); + TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster)); + cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(caster->GetMapId(), caster)); + break; + } + case AREA_AURA_OWNER: + case AREA_AURA_PET: + { + if(owner != caster) + targets.push_back(owner); + break; + } + } + + for(std::list::iterator tIter = targets.begin(); tIter != targets.end(); tIter++) + { + if((*tIter)->HasAura(GetId(), m_effIndex)) + continue; + + if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel())) + { + int32 actualBasePoints = m_currentBasePoints; + // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?) + if(actualSpellInfo != GetSpellProto()) + actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex]; + AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, (*tIter), caster, NULL); + (*tIter)->AddAura(aur); + } + } + } + Aura::Update(diff); + } + else // aura at non-caster + { + Unit * tmp_target = m_target; + Unit* caster = GetCaster(); + uint32 tmp_spellId = GetId(), tmp_effIndex = m_effIndex; + + // WARNING: the aura may get deleted during the update + // DO NOT access its members after update! + Aura::Update(diff); + + // remove aura if out-of-range from caster (after teleport for example) + // or caster is isolated or caster no longer has the aura + // or caster is (no longer) friendly + bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true); + if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) || + !caster->IsWithinDistInMap(tmp_target, m_radius) || + !caster->HasAura(tmp_spellId, tmp_effIndex) || + caster->IsFriendlyTo(tmp_target) != needFriendly + ) + { + tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); + } + else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group + { + // not check group if target == owner or target == pet + if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID()) + { + Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); + + Group *pGroup = check ? check->GetGroup() : NULL; + if( pGroup ) + { + Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself(); + if(!checkTarget || !pGroup->SameSubGroup(check, checkTarget)) + tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); + } + else + tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); + } + } + else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER ) + { + if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() ) + tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); + } + } +} + +void PersistentAreaAura::Update(uint32 diff) +{ + bool remove = false; + + // remove the aura if its caster or the dynamic object causing it was removed + // or if the target moves too far from the dynamic object + Unit *caster = GetCaster(); + if (caster) + { + DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()); + if (dynObj) + { + if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius())) + remove = true; + } + else + remove = true; + } + else + remove = true; + + Unit *tmp_target = m_target; + uint32 tmp_id = GetId(), tmp_index = GetEffIndex(); + + // WARNING: the aura may get deleted during the update + // DO NOT access its members after update! + Aura::Update(diff); + + if(remove) + tmp_target->RemoveAura(tmp_id, tmp_index); +} + +void Aura::ApplyModifier(bool apply, bool Real) +{ + AuraType aura = m_modifier.m_auraname; + + m_in_use = true; + if(aura= MAX_AURAS || m_isPassive) + return; + + if( m_target->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5); + data << (uint8)m_auraSlot << (uint32)m_duration; + ((Player*)m_target)->SendDirectMessage(&data); + + data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4)); + data.append(m_target->GetPackGUID()); + data << uint8(m_auraSlot); + data << uint32(GetId()); + data << uint32(GetAuraMaxDuration()); + data << uint32(GetAuraDuration()); + ((Player*)m_target)->SendDirectMessage(&data); + } + + // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code + if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()) + return; + + Unit* caster = GetCaster(); + + if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target) + SendAuraDurationForCaster((Player*)caster); +} + +void Aura::SendAuraDurationForCaster(Player* caster) +{ + WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4)); + data.append(m_target->GetPackGUID()); + data << uint8(m_auraSlot); + data << uint32(GetId()); + data << uint32(GetAuraMaxDuration()); // full + data << uint32(GetAuraDuration()); // remain + caster->GetSession()->SendPacket(&data); +} + +void Aura::_AddAura() +{ + if (!GetId()) + return; + if(!m_target) + return; + + // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT + bool samespell = false; + bool secondaura = false; + uint8 slot = NULL_AURA_SLOT; + + for(uint8 i = 0; i < 3; i++) + { + Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i); + for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr) + { + // allow use single slot only by auras from same caster + if(itr->second->GetCasterGUID()==GetCasterGUID()) + { + samespell = true; + if (m_effIndex > itr->second->GetEffIndex()) + secondaura = true; + slot = itr->second->GetAuraSlot(); + break; + } + } + + if(samespell) + break; + } + + // not call total regen auras at adding + switch (m_modifier.m_auraname) + { + case SPELL_AURA_OBS_MOD_HEALTH: + case SPELL_AURA_OBS_MOD_MANA: + m_periodicTimer = m_modifier.periodictime; + break; + case SPELL_AURA_MOD_REGEN: + case SPELL_AURA_MOD_POWER_REGEN: + case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT: + m_periodicTimer = 5000; + break; + } + + // register aura + if (getDiminishGroup() != DIMINISHING_NONE ) + m_target->ApplyDiminishingAura(getDiminishGroup(),true); + + Unit* caster = GetCaster(); + + // passive auras (except totem auras) do not get placed in the slots + // area auras with SPELL_AURA_NONE are not shown on target + if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) && + (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster)) + { + if(!samespell) // new slot need + { + if (IsPositive()) // empty positive slot + { + for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++) + { + if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0) + { + slot = i; + break; + } + } + } + else // empty negative slot + { + for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++) + { + if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0) + { + slot = i; + break; + } + } + } + + SetAuraSlot( slot ); + + // Not update fields for not first spell's aura, all data already in fields + if(!secondaura) + { + if(slot < MAX_AURAS) // slot found + { + SetAura(slot, false); + SetAuraFlag(slot, true); + SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); + UpdateAuraCharges(); + + // update for out of range group members + m_target->UpdateAuraForGroup(slot); + } + + UpdateAuraDuration(); + } + } + else // use found slot + { + SetAuraSlot( slot ); + // Not recalculate stack count for second aura of the same spell + if (!secondaura) + UpdateSlotCounterAndDuration(true); + } + + // Update Seals information + if( IsSealSpell(GetSpellProto()) ) + m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); + + // Conflagrate aura state + if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4)) + m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true); + + if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID + && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10)) + { + m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true); + } + } +} + +void Aura::_RemoveAura() +{ + // Remove all triggered by aura spells vs unlimited duration + // except same aura replace case + if(m_removeMode!=AURA_REMOVE_BY_STACK) + CleanupTriggeredSpells(); + + Unit* caster = GetCaster(); + + if(caster && IsPersistent()) + { + DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()); + if (dynObj) + dynObj->RemoveAffected(m_target); + } + + // unregister aura + if (getDiminishGroup() != DIMINISHING_NONE ) + m_target->ApplyDiminishingAura(getDiminishGroup(),false); + + //passive auras do not get put in slots + // Note: but totem can be not accessible for aura target in time remove (to far for find in grid) + //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) + // return; + + uint8 slot = GetAuraSlot(); + + if(slot >= MAX_AURAS) // slot not set + return; + + if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0) + return; + + bool samespell = false; + bool sameaura = false; + + // find other aura in same slot (current already removed from list) + for(uint8 i = 0; i < 3; i++) + { + Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i); + for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr) + { + if(itr->second->GetAuraSlot()==slot) + { + samespell = true; + + if(GetEffIndex()==i) + sameaura = true; + + break; + } + } + if(samespell) + break; + } + + // only remove icon when the last aura of the spell is removed (current aura already removed from list) + if (!samespell) + { + SetAura(slot, true); + SetAuraFlag(slot, false); + SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); + + SetAuraApplication(slot, 0); + // update for out of range group members + m_target->UpdateAuraForGroup(slot); + + if( IsSealSpell(GetSpellProto()) ) + m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false); + + // Conflagrate aura state + if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4)) + m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false); + + // Swiftmend aura state + if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID + && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10)) + { + bool found = false; + Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + { + if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID + && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) ) + { + found = true; + break; + } + } + if(!found) + m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false); + } + + // reset cooldown state for spells + if(caster && caster->GetTypeId() == TYPEID_PLAYER) + { + if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE ) + ((Player*)caster)->SendCooldownEvent(GetSpellProto()); + } + } + else if(sameaura) // decrease count for spell, only for same aura effect, or this spell auras in remove proccess. + UpdateSlotCounterAndDuration(false); +} + +void Aura::SetAuraFlag(uint32 slot, bool add) +{ + uint32 index = slot / 4; + uint32 byte = (slot % 4) * 8; + uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index); + val &= ~((uint32)AFLAG_MASK << byte); + if(add) + { + if (IsPositive()) + val |= ((uint32)AFLAG_POSITIVE << byte); + else + val |= ((uint32)AFLAG_NEGATIVE << byte); + } + m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val); +} + +void Aura::SetAuraLevel(uint32 slot,uint32 level) +{ + uint32 index = slot / 4; + uint32 byte = (slot % 4) * 8; + uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index); + val &= ~(0xFF << byte); + val |= (level << byte); + m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val); +} + +void Aura::SetAuraApplication(uint32 slot, int8 count) +{ + uint32 index = slot / 4; + uint32 byte = (slot % 4) * 8; + uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index); + val &= ~(0xFF << byte); + val |= ((uint8(count)) << byte); + m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val); +} + +void Aura::UpdateSlotCounterAndDuration(bool add) +{ + uint8 slot = GetAuraSlot(); + if(slot >= MAX_AURAS) + return; + + // calculate amount of similar auras by same effect index (similar different spells) + int8 count = 0; + + // calculate auras and update durations in case aura adding + Unit::AuraList const& aura_list = m_target->GetAurasByType(GetModifier()->m_auraname); + for(Unit::AuraList::const_iterator i = aura_list.begin();i != aura_list.end(); ++i) + { + if( (*i)->GetId()==GetId() && (*i)->GetEffIndex()==m_effIndex && + (*i)->GetCasterGUID()==GetCasterGUID() ) + { + ++count; + + if(add) + (*i)->SetAuraDuration(GetAuraDuration()); + } + } + + // at aura add aura not added yet, at aura remove aura already removed + // in field stored (count-1) + if(!add) + --count; + + SetAuraApplication(slot, count); + + UpdateAuraDuration(); +} + +/*********************************************************/ +/*** BASIC AURA FUNCTION ***/ +/*********************************************************/ +void Aura::HandleAddModifier(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER || !Real) + return; + + SpellEntry const *spellInfo = GetSpellProto(); + if(!spellInfo) + return; + + if(m_modifier.m_miscvalue >= MAX_SPELLMOD) + return; + + if (apply) + { + // Add custom charges for some mod aura + switch (m_spellProto->Id) + { + case 17941: // Shadow Trance + case 22008: // Netherwind Focus + case 34936: // Backlash + m_procCharges = 1; + break; + } + + SpellModifier *mod = new SpellModifier; + mod->op = SpellModOp(m_modifier.m_miscvalue); + mod->value = m_modifier.m_amount; + mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types + mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; + + uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex); + + if (spellAffectMask) + mod->mask = spellAffectMask; + else + mod->mask = spellInfo->EffectItemType[m_effIndex]; + + if (m_procCharges > 0) + mod->charges = m_procCharges; + else + mod->charges = 0; + + m_spellmod = mod; + } + + uint64 spellFamilyMask = m_spellmod->mask; + + ((Player*)m_target)->AddSpellMod(m_spellmod, apply); + + // reapply some passive spells after add/remove related spellmods + if(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL)) + { + m_target->RemoveAurasDueToSpell(45471); + + if(apply) + m_target->CastSpell(m_target,45471,true); + } +} + +void Aura::TriggerSpell() +{ + Unit* caster = GetCaster(); + Unit* target = GetTriggerTarget(); + + if(!caster || !target) + return; + + // generic casting code with custom spells and target/caster customs + uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex]; + + uint64 originalCasterGUID = GetCasterGUID(); + + SpellEntry const *triggredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id); + SpellEntry const *auraSpellInfo = GetSpellProto(); + uint32 auraId = auraSpellInfo->Id; + + // specific code for cases with no trigger spell provided in field + if (triggredSpellInfo == NULL) + { + switch(auraSpellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + switch(auraId) + { + // Firestone Passive (1-5 rangs) + case 758: + case 17945: + case 17947: + case 17949: + case 27252: + { + if (caster->GetTypeId()!=TYPEID_PLAYER) + return; + Item* item = ((Player*)caster)->GetWeaponForAttack(BASE_ATTACK); + if (!item) + return; + uint32 enchant_id = 0; + switch (GetId()) + { + case 758: enchant_id = 1803; break; // Rank 1 + case 17945: enchant_id = 1823; break; // Rank 2 + case 17947: enchant_id = 1824; break; // Rank 3 + case 17949: enchant_id = 1825; break; // Rank 4 + case 27252: enchant_id = 2645; break; // Rank 5 + default: + return; + } + // remove old enchanting before applying new + ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false); + item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime+1000, 0); + // add new enchanting + ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true); + return; + } +// // Periodic Mana Burn +// case 812: break; +// // Polymorphic Ray +// case 6965: break; +// // Fire Nova (1-7 Rangs) +// case 8350: +// case 8508: +// case 8509: +// case 11312: +// case 11313: +// case 25540: +// case 25544: +// break; + // Thaumaturgy Channel + case 9712: trigger_spell_id = 21029; break; +// // Egan's Blaster +// case 17368: break; +// // Haunted +// case 18347: break; +// // Ranshalla Waiting +// case 18953: break; +// // Inferno +// case 19695: break; +// // Frostwolf Muzzle DND +// case 21794: break; +// // Alterac Ram Collar DND +// case 21866: break; +// // Celebras Waiting +// case 21916: break; + // Brood Affliction: Bronze + case 23170: + { + m_target->CastSpell(m_target, 23171, true, 0, this); + return; + } +// // Mark of Frost +// case 23184: break; + // Restoration + case 23493: + { + int32 heal = caster->GetMaxHealth() / 10; + caster->ModifyHealth( heal ); + caster->SendHealSpellLog(caster, 23493, heal); + + int32 mana = caster->GetMaxPower(POWER_MANA); + if (mana) + { + mana /= 10; + caster->ModifyPower( POWER_MANA, mana ); + caster->SendEnergizeSpellLog(caster, 23493, mana, POWER_MANA); + } + break; + } +// // Stoneclaw Totem Passive TEST +// case 23792: break; +// // Axe Flurry +// case 24018: break; +// // Mark of Arlokk +// case 24210: break; +// // Restoration +// case 24379: break; +// // Happy Pet +// case 24716: break; +// // Dream Fog +// case 24780: break; +// // Cannon Prep +// case 24832: break; +// // Shadow Bolt Whirl +// case 24834: break; +// // Stink Trap +// case 24918: break; +// // Mark of Nature +// case 25041: break; +// // Agro Drones +// case 25152: break; +// // Consume +// case 25371: break; +// // Pain Spike +// case 25572: break; +// // Rotate 360 +// case 26009: break; +// // Rotate -360 +// case 26136: break; +// // Consume +// case 26196: break; +// // Berserk +// case 26615: break; +// // Defile +// case 27177: break; +// // Teleport: IF/UC +// case 27601: break; +// // Five Fat Finger Exploding Heart Technique +// case 27673: break; +// // Nitrous Boost +// case 27746: break; +// // Steam Tank Passive +// case 27747: break; +// // Frost Blast +// case 27808: break; +// // Detonate Mana +// case 27819: break; +// // Controller Timer +// case 28095: break; +// // Stalagg Chain +// case 28096: break; +// // Stalagg Tesla Passive +// case 28097: break; +// // Feugen Tesla Passive +// case 28109: break; +// // Feugen Chain +// case 28111: break; +// // Mark of Didier +// case 28114: break; +// // Communique Timer, camp +// case 28346: break; +// // Icebolt +// case 28522: break; +// // Silithyst +// case 29519: break; +// // Inoculate Nestlewood Owlkin + case 29528: trigger_spell_id = 28713; break; +// // Overload +// case 29768: break; +// // Return Fire +// case 29788: break; +// // Return Fire +// case 29793: break; +// // Return Fire +// case 29794: break; +// // Guardian of Icecrown Passive +// case 29897: break; + // Feed Captured Animal + case 29917: trigger_spell_id = 29916; break; +// // Flame Wreath +// case 29946: break; +// // Flame Wreath +// case 29947: break; +// // Mind Exhaustion Passive +// case 30025: break; +// // Nether Beam - Serenity +// case 30401: break; + // Extract Gas + case 30427: + { + // move loot to player inventory and despawn target + if(caster->GetTypeId() ==TYPEID_PLAYER && + target->GetTypeId() == TYPEID_UNIT && + ((Creature*)target)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD) + { + Player* player = (Player*)caster; + Creature* creature = (Creature*)target; + // missing lootid has been reported on startup - just return + if (!creature->GetCreatureInfo()->SkinLootId) + { + return; + } + Loot *loot = &creature->loot; + loot->clear(); + loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL); + for(uint8 i=0;iitems.size();i++) + { + LootItem *item = loot->LootItemInSlot(i,player); + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count ); + if ( msg == EQUIP_ERR_OK ) + { + Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId); + + player->SendNewItem(newitem, uint32(item->count), false, false, true); + } + else + player->SendEquipError( msg, NULL, NULL ); + } + creature->setDeathState(JUST_DIED); + creature->RemoveCorpse(); + creature->SetHealth(0); // just for nice GM-mode view + } + return; + break; + } + // Quake + case 30576: trigger_spell_id = 30571; break; +// // Burning Maul +// case 30598: break; +// // Regeneration +// case 30799: +// case 30800: +// case 30801: +// break; +// // Despawn Self - Smoke cloud +// case 31269: break; +// // Time Rift Periodic +// case 31320: break; +// // Corrupt Medivh +// case 31326: break; + // Doom + case 31347: + { + m_target->CastSpell(m_target,31350,true); + m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + return; + } + // Spellcloth + case 31373: + { + // Summon Elemental after create item + caster->SummonCreature(17870, 0, 0, 0, caster->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0); + return; + } +// // Bloodmyst Tesla +// case 31611: break; +// // Doomfire +// case 31944: break; +// // Teleport Test +// case 32236: break; +// // Earthquake +// case 32686: break; +// // Possess +// case 33401: break; +// // Draw Shadows +// case 33563: break; +// // Murmur's Touch +// case 33711: break; + // Flame Quills + case 34229: + { + // cast 24 spells 34269-34289, 34314-34316 + for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id) + caster->CastSpell(m_target,spell_id,true); + for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id) + caster->CastSpell(m_target,spell_id,true); + return; + } +// // Gravity Lapse +// case 34480: break; +// // Tornado +// case 34683: break; +// // Frostbite Rotate +// case 34748: break; +// // Arcane Flurry +// case 34821: break; +// // Interrupt Shutdown +// case 35016: break; +// // Interrupt Shutdown +// case 35176: break; +// // Inferno +// case 35268: break; +// // Salaadin's Tesla +// case 35515: break; +// // Ethereal Channel (Red) +// case 35518: break; +// // Nether Vapor +// case 35879: break; +// // Dark Portal Storm +// case 36018: break; +// // Burning Maul +// case 36056: break; +// // Living Grove Defender Lifespan +// case 36061: break; +// // Professor Dabiri Talks +// case 36064: break; +// // Kael Gaining Power +// case 36091: break; +// // They Must Burn Bomb Aura +// case 36344: break; +// // They Must Burn Bomb Aura (self) +// case 36350: break; +// // Stolen Ravenous Ravager Egg +// case 36401: break; +// // Activated Cannon +// case 36410: break; +// // Stolen Ravenous Ravager Egg +// case 36418: break; +// // Enchanted Weapons +// case 36510: break; +// // Cursed Scarab Periodic +// case 36556: break; +// // Cursed Scarab Despawn Periodic +// case 36561: break; +// // Vision Guide +// case 36573: break; +// // Cannon Charging (platform) +// case 36785: break; +// // Cannon Charging (self) +// case 36860: break; + // Remote Toy + case 37027: trigger_spell_id = 37029; break; +// // Mark of Death +// case 37125: break; +// // Arcane Flurry +// case 37268: break; +// // Spout +// case 37429: break; +// // Spout +// case 37430: break; +// // Karazhan - Chess NPC AI, Snapshot timer +// case 37440: break; +// // Karazhan - Chess NPC AI, action timer +// case 37504: break; +// // Karazhan - Chess: Is Square OCCUPIED aura (DND) +// case 39400: break; +// // Banish +// case 37546: break; +// // Shriveling Gaze +// case 37589: break; +// // Fake Aggro Radius (2 yd) +// case 37815: break; +// // Corrupt Medivh +// case 37853: break; + // Eye of Grillok + case 38495: + { + m_target->CastSpell(m_target, 38530, true); + return; + } + // Absorb Eye of Grillok (Zezzak's Shard) + case 38554: + { + if(m_target->GetTypeId() != TYPEID_UNIT) + return; + + caster->CastSpell(caster, 38495, true); + + Creature* creatureTarget = (Creature*)m_target; + + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + return; + } +// // Magic Sucker Device timer +// case 38672: break; +// // Tomb Guarding Charging +// case 38751: break; +// // Murmur's Touch +// case 38794: break; +// // Activate Nether-wraith Beacon (31742 Nether-wraith Beacon item) +// case 39105: break; +// // Drain World Tree Visual +// case 39140: break; +// // Quest - Dustin's Undead Dragon Visual aura +// case 39259: break; +// // Hellfire - The Exorcism, Jules releases darkness, aura +// case 39306: break; +// // Inferno +// case 39346: break; +// // Enchanted Weapons +// case 39489: break; +// // Shadow Bolt Whirl +// case 39630: break; +// // Shadow Bolt Whirl +// case 39634: break; +// // Shadow Inferno +// case 39645: break; + // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam + case 39857: trigger_spell_id = 39856; break; +// // Soulgrinder Ritual Visual (Smashed) +// case 39974: break; +// // Simon Game Pre-game timer +// case 40041: break; +// // Knockdown Fel Cannon: The Aggro Check Aura +// case 40113: break; +// // Spirit Lance +// case 40157: break; +// // Demon Transform 2 +// case 40398: break; +// // Demon Transform 1 +// case 40511: break; +// // Ancient Flames +// case 40657: break; +// // Ethereal Ring Cannon: Cannon Aura +// case 40734: break; +// // Cage Trap +// case 40760: break; +// // Random Periodic +// case 40867: break; +// // Prismatic Shield +// case 40879: break; +// // Aura of Desire +// case 41350: break; +// // Dementia +// case 41404: break; +// // Chaos Form +// case 41629: break; +// // Alert Drums +// case 42177: break; +// // Spout +// case 42581: break; +// // Spout +// case 42582: break; +// // Return to the Spirit Realm +// case 44035: break; +// // Curse of Boundless Agony +// case 45050: break; +// // Earthquake +// case 46240: break; + // Personalized Weather + case 46736: trigger_spell_id = 46737; break; +// // Stay Submerged +// case 46981: break; +// // Dragonblight Ram +// case 47015: break; +// // Party G.R.E.N.A.D.E. +// case 51510: break; + default: + break; + } + break; + } + case SPELLFAMILY_MAGE: + { + switch(auraId) + { + // Invisibility + case 66: + { + if(!m_duration) + m_target->CastSpell(m_target, 32612, true, NULL, this); + return; + } + default: + break; + } + break; + } +// case SPELLFAMILY_WARRIOR: +// { +// switch(auraId) +// { +// // Wild Magic +// case 23410: break; +// // Corrupted Totems +// case 23425: break; +// default: +// break; +// } +// break; +// } +// case SPELLFAMILY_PRIEST: +// { +// switch(auraId) +// { +// // Blue Beam +// case 32930: break; +// // Fury of the Dreghood Elders +// case 35460: break; +// default: +// break; +// } + // break; + // } + case SPELLFAMILY_DRUID: + { + switch(auraId) + { + // Cat Form + // trigger_spell_id not set and unknown effect triggered in this case, ignoring for while + case 768: + return; + // Frenzied Regeneration + case 22842: + case 22895: + case 22896: + case 26999: + { + int32 LifePerRage = GetModifier()->m_amount; + + int32 lRage = m_target->GetPower(POWER_RAGE); + if(lRage > 100) // rage stored as rage*10 + lRage = 100; + m_target->ModifyPower(POWER_RAGE, -lRage); + int32 FRTriggerBasePoints = int32(lRage*LifePerRage/10); + m_target->CastCustomSpell(m_target,22845,&FRTriggerBasePoints,NULL,NULL,true,NULL,this); + return; + } + default: + break; + } + break; + } + +// case SPELLFAMILY_HUNTER: +// { +// switch(auraId) +// { +// //Frost Trap Aura +// case 13810: +// return; +// //Rizzle's Frost Trap +// case 39900: +// return; +// // Tame spells +// case 19597: // Tame Ice Claw Bear +// case 19676: // Tame Snow Leopard +// case 19677: // Tame Large Crag Boar +// case 19678: // Tame Adult Plainstrider +// case 19679: // Tame Prairie Stalker +// case 19680: // Tame Swoop +// case 19681: // Tame Dire Mottled Boar +// case 19682: // Tame Surf Crawler +// case 19683: // Tame Armored Scorpid +// case 19684: // Tame Webwood Lurker +// case 19685: // Tame Nightsaber Stalker +// case 19686: // Tame Strigid Screecher +// case 30100: // Tame Crazed Dragonhawk +// case 30103: // Tame Elder Springpaw +// case 30104: // Tame Mistbat +// case 30647: // Tame Barbed Crawler +// case 30648: // Tame Greater Timberstrider +// case 30652: // Tame Nightstalker +// return; +// default: +// break; +// } +// break; +// } + case SPELLFAMILY_SHAMAN: + { + switch(auraId) + { + // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield) + case 28820: + { + // Need remove self if Lightning Shield not active + Unit::AuraMap const& auras = target->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const* spell = itr->second->GetSpellProto(); + if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN && + spell->SpellFamilyFlags & 0x0000000000000400L) + return; + } + target->RemoveAurasDueToSpell(28820); + return; + } + // Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus) + case 38443: + { + bool all = true; + for(int i = 0; i < MAX_TOTEM; ++i) + { + if(!caster->m_TotemSlot[i]) + { + all = false; + break; + } + } + + if(all) + caster->CastSpell(caster,38437,true); + else + caster->RemoveAurasDueToSpell(38437); + return; + } + default: + break; + } + break; + } + default: + break; + } + // Reget trigger spell proto + triggredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id); + if(triggredSpellInfo == NULL) + { + sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex()); + return; + } + } + else + { + // Spell exist but require costum code + switch(auraId) + { + // Curse of Idiocy + case 1010: + { + // TODO: spell casted by result in correct way mostly + // BUT: + // 1) target show casting at each triggered cast: target don't must show casting animation for any triggered spell + // but must show affect apply like item casting + // 2) maybe aura must be replace by new with accumulative stat mods insteed stacking + + // prevent cast by triggered auras + if(m_caster_guid == m_target->GetGUID()) + return; + + // stop triggering after each affected stats lost > 90 + int32 intelectLoss = 0; + int32 spiritLoss = 0; + + Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT); + for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i) + { + if ((*i)->GetId() == 1010) + { + switch((*i)->GetModifier()->m_miscvalue) + { + case STAT_INTELLECT: intelectLoss += (*i)->GetModifier()->m_amount; break; + case STAT_SPIRIT: spiritLoss += (*i)->GetModifier()->m_amount; break; + default: break; + } + } + } + + if(intelectLoss <= -90 && spiritLoss <= -90) + return; + + caster = target; + originalCasterGUID = 0; + break; + } + // Mana Tide + case 16191: + { + caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID); + return; + } + } + } + // All ok cast by default case + Spell *spell = new Spell(caster, triggredSpellInfo, true, originalCasterGUID ); + + SpellCastTargets targets; + targets.setUnitTarget( target ); + + // if spell create dynamic object extract area from it + if(DynamicObject* dynObj = caster->GetDynObject(GetId())) + targets.setDestination(dynObj->GetPositionX(),dynObj->GetPositionY(),dynObj->GetPositionZ()); + + spell->prepare(&targets, this); +} + +/*********************************************************/ +/*** AURA EFFECTS ***/ +/*********************************************************/ + +void Aura::HandleAuraDummy(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + Unit* caster = GetCaster(); + + // AT APPLY + if(apply) + { + switch(GetId()) + { + case 1515: // Tame beast + // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness + if( caster && m_target->CanHaveThreatList()) + m_target->AddThreat(caster, 10.0f); + return; + case 13139: // net-o-matic + // root to self part of (root_target->charge->root_self sequence + if(caster) + caster->CastSpell(caster,13138,true,NULL,this); + return; + case 39850: // Rocket Blast + if(roll_chance_i(20)) // backfire stun + m_target->CastSpell(m_target, 51581, true, NULL, this); + return; + case 46354: // Blood Elf Illusion + if(caster) + { + switch(caster->getGender()) + { + case GENDER_FEMALE: + caster->CastSpell(m_target,46356,true,NULL,this); + break; + case GENDER_MALE: + caster->CastSpell(m_target,46355,true,NULL,this); + break; + default: + break; + } + } + return; + case 46699: // Requires No Ammo + if(m_target->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_target)->RemoveAmmo(); // not use ammo and not allow use + return; + } + + // Earth Shield + if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL)) + { + // prevent double apply bonuses + if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) + m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target); + return; + } + } + // AT REMOVE + else + { + if( m_target->GetTypeId() == TYPEID_PLAYER && + ( GetSpellProto()->Effect[0]==72 || GetSpellProto()->Effect[0]==6 && + ( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) ) + { + // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425 + m_target->SetUInt64Value(PLAYER_FARSIGHT, 0); + WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); + ((Player*)m_target)->GetSession()->SendPacket(&data); + return; + } + + if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target->isAlive()) + { + uint32 finalSpelId = 0; + switch(GetId()) + { + case 19548: finalSpelId = 19597; break; + case 19674: finalSpelId = 19677; break; + case 19687: finalSpelId = 19676; break; + case 19688: finalSpelId = 19678; break; + case 19689: finalSpelId = 19679; break; + case 19692: finalSpelId = 19680; break; + case 19693: finalSpelId = 19684; break; + case 19694: finalSpelId = 19681; break; + case 19696: finalSpelId = 19682; break; + case 19697: finalSpelId = 19683; break; + case 19699: finalSpelId = 19685; break; + case 19700: finalSpelId = 19686; break; + case 30646: finalSpelId = 30647; break; + case 30653: finalSpelId = 30648; break; + case 30654: finalSpelId = 30652; break; + case 30099: finalSpelId = 30100; break; + case 30102: finalSpelId = 30103; break; + case 30105: finalSpelId = 30104; break; + } + + if(finalSpelId) + caster->CastSpell(m_target,finalSpelId,true,NULL,this); + return; + } + // Dark Fiend + if(GetId()==45934) + { + // Kill target if dispeled + if (m_removeMode==AURA_REMOVE_BY_DISPEL) + m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + return; + } + + // Burning Winds + if(GetId()==46308) // casted only at creatures at spawn + { + m_target->CastSpell(m_target,47287,true,NULL,this); + return; + } + } + + // AT APPLY & REMOVE + + switch(m_spellProto->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + // Unstable Power + if( GetId()==24658 ) + { + uint32 spellId = 24659; + if (apply) + { + const SpellEntry *spell = sSpellStore.LookupEntry(spellId); + if (!spell) + return; + for (int i=0; i < spell->StackAmount; ++i) + caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID()); + return; + } + m_target->RemoveAurasDueToSpell(spellId); + return; + } + // Restless Strength + if( GetId()==24661 ) + { + uint32 spellId = 24662; + if (apply) + { + const SpellEntry *spell = sSpellStore.LookupEntry(spellId); + if (!spell) + return; + for (int i=0; i < spell->StackAmount; ++i) + caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID()); + return; + } + m_target->RemoveAurasDueToSpell(spellId); + return; + } + // Victorious + if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR) + { + m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply); + return; + } + //Summon Fire Elemental + if (GetId() == 40133 && caster) + { + Unit *owner = caster->GetOwner(); + if (owner && owner->GetTypeId() == TYPEID_PLAYER) + { + if(apply) + owner->CastSpell(owner,8985,true); + else + ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + } + return; + } + + //Summon Earth Elemental + if (GetId() == 40132 && caster) + { + Unit *owner = caster->GetOwner(); + if (owner && owner->GetTypeId() == TYPEID_PLAYER) + { + if(apply) + owner->CastSpell(owner,19704,true); + else + ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + } + return; + } + break; + } + case SPELLFAMILY_MAGE: + { + // Hypothermia + if( GetId()==41425 ) + { + m_target->ModifyAuraState(AURA_STATE_HYPOTHERMIA,apply); + return; + } + break; + } + case SPELLFAMILY_DRUID: + { + // Lifebloom + if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL ) + { + if ( apply ) + { + if ( caster ) + // prevent double apply bonuses + if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) + m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target); + } + else + { + // Final heal only on dispelled or duration end + if ( !(GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL) ) + return; + + // have a look if there is still some other Lifebloom dummy aura + Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); itr++) + if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && + (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL) + return; + + // final heal + m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID()); + } + return; + } + + // Predatory Strikes + if(m_target->GetTypeId()==TYPEID_PLAYER && GetSpellProto()->SpellIconID == 1563) + { + ((Player*)m_target)->UpdateAttackPowerAndDamage(); + return; + } + // Idol of the Emerald Queen + if ( GetId() == 34246 && m_target->GetTypeId()==TYPEID_PLAYER ) + { + if(apply) + { + SpellModifier *mod = new SpellModifier; + mod->op = SPELLMOD_DOT; + mod->value = m_modifier.m_amount/7; + mod->type = SPELLMOD_FLAT; + mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; + mod->mask = 0x001000000000LL; + mod->charges = 0; + + m_spellmod = mod; + } + + ((Player*)m_target)->AddSpellMod(m_spellmod, apply); + return; + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Improved Aspect of the Viper + if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER ) + { + if(apply) + { + // + effect value for Aspect of the Viper + SpellModifier *mod = new SpellModifier; + mod->op = SPELLMOD_EFFECT1; + mod->value = m_modifier.m_amount; + mod->type = SPELLMOD_FLAT; + mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; + mod->mask = 0x4000000000000LL; + mod->charges = 0; + + m_spellmod = mod; + } + + ((Player*)m_target)->AddSpellMod(m_spellmod, apply); + return; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + // Improved Weapon Totems + if( GetSpellProto()->SpellIconID == 57 && m_target->GetTypeId()==TYPEID_PLAYER ) + { + if(apply) + { + SpellModifier *mod = new SpellModifier; + mod->op = SPELLMOD_EFFECT1; + mod->value = m_modifier.m_amount; + mod->type = SPELLMOD_PCT; + mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; + switch (m_effIndex) + { + case 0: + mod->mask = 0x00200000000LL; // Windfury Totem + break; + case 1: + mod->mask = 0x00400000000LL; // Flametongue Totem + break; + } + mod->charges = 0; + + m_spellmod = mod; + } + + ((Player*)m_target)->AddSpellMod(m_spellmod, apply); + return; + } + break; + } + } + + // pet auras + if(PetAura const* petSpell = spellmgr.GetPetAura(GetId())) + { + if(apply) + m_target->AddPetAura(petSpell); + else + m_target->RemovePetAura(petSpell); + return; + } +} + +void Aura::HandleAuraPeriodicDummy(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + SpellEntry const*spell = GetSpellProto(); + switch( spell->SpellFamilyName) + { + case SPELLFAMILY_ROGUE: + { + // Master of Subtlety + if (spell->Id==31666 && !apply && Real) + { + m_target->RemoveAurasDueToSpell(31665); + break; + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Aspect of the Viper + if (spell->SpellFamilyFlags&0x0004000000000000LL) + { + // Update regen on remove + if (!apply && m_target->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_target)->UpdateManaRegen(); + break; + } + break; + } + } + + m_isPeriodic = apply; +} + +void Aura::HandleAuraMounted(bool apply, bool Real) +{ + if(apply) + { + CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue); + if(!ci) + { + sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue); + return; + } + + uint32 team = 0; + if (m_target->GetTypeId()==TYPEID_PLAYER) + team = ((Player*)m_target)->GetTeam(); + + uint32 display_id = objmgr.ChooseDisplayId(team,ci); + CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id); + if (minfo) + display_id = minfo->modelid; + + m_target->Mount(display_id); + } + else + { + m_target->Unmount(); + } +} + +void Aura::HandleAuraWaterWalk(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + WorldPacket data; + if(apply) + data.Initialize(SMSG_MOVE_WATER_WALK, 8+4); + else + data.Initialize(SMSG_MOVE_LAND_WALK, 8+4); + data.append(m_target->GetPackGUID()); + data << uint32(0); + m_target->SendMessageToSet(&data,true); +} + +void Aura::HandleAuraFeatherFall(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + WorldPacket data; + if(apply) + data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4); + else + data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4); + data.append(m_target->GetPackGUID()); + data << (uint32)0; + m_target->SendMessageToSet(&data,true); +} + +void Aura::HandleAuraHover(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + WorldPacket data; + if(apply) + data.Initialize(SMSG_MOVE_SET_HOVER, 8+4); + else + data.Initialize(SMSG_MOVE_UNSET_HOVER, 8+4); + data.append(m_target->GetPackGUID()); + data << uint32(0); + m_target->SendMessageToSet(&data,true); +} + +void Aura::HandleWaterBreathing(bool apply, bool Real) +{ + if(apply) + m_target->waterbreath = true; + else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty()) + { + m_target->waterbreath = false; + + // update for enable timer in case not moving target + if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld()) + { + ((Player*)m_target)->UpdateUnderwaterState(m_target->GetMap(),m_target->GetPositionX(),m_target->GetPositionY(),m_target->GetPositionZ()); + ((Player*)m_target)->HandleDrowning(); + } + } +} + +void Aura::HandleAuraModShapeshift(bool apply, bool Real) +{ + if(!Real) + return; + + uint32 modelid = 0; + Powers PowerType = POWER_MANA; + ShapeshiftForm form = ShapeshiftForm(m_modifier.m_miscvalue); + switch(form) + { + case FORM_CAT: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 892; + else + modelid = 8571; + PowerType = POWER_ENERGY; + break; + case FORM_TRAVEL: + modelid = 632; + break; + case FORM_AQUA: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 2428; + else + modelid = 2428; + break; + case FORM_BEAR: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 2281; + else + modelid = 2289; + PowerType = POWER_RAGE; + break; + case FORM_GHOUL: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 10045; + break; + case FORM_DIREBEAR: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 2281; + else + modelid = 2289; + PowerType = POWER_RAGE; + break; + case FORM_CREATUREBEAR: + modelid = 902; + break; + case FORM_GHOSTWOLF: + modelid = 4613; + break; + case FORM_FLIGHT: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 20857; + else + modelid = 20872; + break; + case FORM_MOONKIN: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 15374; + else + modelid = 15375; + break; + case FORM_FLIGHT_EPIC: + if(Player::TeamForRace(m_target->getRace())==ALLIANCE) + modelid = 21243; + else + modelid = 21244; + break; + case FORM_AMBIENT: + case FORM_SHADOW: + case FORM_STEALTH: + break; + case FORM_TREE: + modelid = 864; + break; + case FORM_BATTLESTANCE: + case FORM_BERSERKERSTANCE: + case FORM_DEFENSIVESTANCE: + PowerType = POWER_RAGE; + break; + case FORM_SPIRITOFREDEMPTION: + modelid = 16031; + break; + default: + sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue); + } + + // remove polymorph before changing display id to keep new display id + switch ( form ) + { + case FORM_CAT: + case FORM_TREE: + case FORM_TRAVEL: + case FORM_AQUA: + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_FLIGHT_EPIC: + case FORM_FLIGHT: + case FORM_MOONKIN: + // remove movement affects + m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); + m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED); + + // and polymorphic affects + if(m_target->IsPolymorphed()) + m_target->RemoveAurasDueToSpell(m_target->getTransForm()); + break; + default: + break; + } + + if(apply) + { + // remove other shapeshift before applying a new one + if(m_target->m_ShapeShiftFormSpellId) + { + m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId,this); + } + + m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form); + + if(modelid > 0) + { + m_target->SetDisplayId(modelid); + } + + if(PowerType != POWER_MANA) + { + // reset power to default values only at power change + if(m_target->getPowerType()!=PowerType) + m_target->setPowerType(PowerType); + + switch(form) + { + case FORM_CAT: + case FORM_BEAR: + case FORM_DIREBEAR: + { + // get furor proc chance + uint32 FurorChance = 0; + Unit::AuraList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i) + { + if ((*i)->GetSpellProto()->SpellIconID == 238) + { + FurorChance = (*i)->GetModifier()->m_amount; + break; + } + } + + if (m_modifier.m_miscvalue == FORM_CAT) + { + m_target->SetPower(POWER_ENERGY,0); + if(urand(1,100) <= FurorChance) + { + m_target->CastSpell(m_target,17099,true,NULL,this); + } + } + else + { + m_target->SetPower(POWER_RAGE,0); + if(urand(1,100) <= FurorChance) + { + m_target->CastSpell(m_target,17057,true,NULL,this); + } + } + break; + } + case FORM_BATTLESTANCE: + case FORM_DEFENSIVESTANCE: + case FORM_BERSERKERSTANCE: + { + uint32 Rage_val = 0; + // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch) + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + PlayerSpellMap const& sp_list = ((Player *)m_target)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + if(itr->second->state == PLAYERSPELL_REMOVED) continue; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139) + Rage_val += m_target->CalculateSpellDamage(spellInfo,0,spellInfo->EffectBasePoints[0],m_target) * 10; + } + } + + if (m_target->GetPower(POWER_RAGE) > Rage_val) + m_target->SetPower(POWER_RAGE,Rage_val); + break; + } + default: + break; + } + } + + m_target->m_ShapeShiftFormSpellId = GetId(); + m_target->m_form = form; + } + else + { + m_target->SetDisplayId(m_target->GetNativeDisplayId()); + m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE); + if(m_target->getClass() == CLASS_DRUID) + m_target->setPowerType(POWER_MANA); + m_target->m_ShapeShiftFormSpellId = 0; + m_target->m_form = FORM_NONE; + + switch(form) + { + // Nordrassil Harness - bonus + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_CAT: + { + if(Aura* dummy = m_target->GetDummyAura(37315) ) + m_target->CastSpell(m_target,37316,true,NULL,dummy); + break; + } + // Nordrassil Regalia - bonus + case FORM_MOONKIN: + { + if(Aura* dummy = m_target->GetDummyAura(37324) ) + m_target->CastSpell(m_target,37325,true,NULL,dummy); + break; + } + } + } + + // adding/removing linked auras + // add/remove the shapeshift aura's boosts + HandleShapeshiftBoosts(apply); + + if(m_target->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_target)->InitDataForForm(); +} + +void Aura::HandleAuraTransform(bool apply, bool Real) +{ + if (apply) + { + // special case (spell specific functionality) + if(m_modifier.m_miscvalue==0) + { + // player applied only + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + switch(GetId()) + { + // Orb of Deception + case 16739: + { + uint32 orb_model = m_target->GetNativeDisplayId(); + switch(orb_model) + { + // Troll Female + case 1479: m_target->SetDisplayId(10134); break; + // Troll Male + case 1478: m_target->SetDisplayId(10135); break; + // Tauren Male + case 59: m_target->SetDisplayId(10136); break; + // Human Male + case 49: m_target->SetDisplayId(10137); break; + // Human Female + case 50: m_target->SetDisplayId(10138); break; + // Orc Male + case 51: m_target->SetDisplayId(10139); break; + // Orc Female + case 52: m_target->SetDisplayId(10140); break; + // Dwarf Male + case 53: m_target->SetDisplayId(10141); break; + // Dwarf Female + case 54: m_target->SetDisplayId(10142); break; + // NightElf Male + case 55: m_target->SetDisplayId(10143); break; + // NightElf Female + case 56: m_target->SetDisplayId(10144); break; + // Undead Female + case 58: m_target->SetDisplayId(10145); break; + // Undead Male + case 57: m_target->SetDisplayId(10146); break; + // Tauren Female + case 60: m_target->SetDisplayId(10147); break; + // Gnome Male + case 1563: m_target->SetDisplayId(10148); break; + // Gnome Female + case 1564: m_target->SetDisplayId(10149); break; + // BloodElf Female + case 15475: m_target->SetDisplayId(17830); break; + // BloodElf Male + case 15476: m_target->SetDisplayId(17829); break; + // Dranei Female + case 16126: m_target->SetDisplayId(17828); break; + // Dranei Male + case 16125: m_target->SetDisplayId(17827); break; + default: break; + } + break; + } + // Murloc costume + case 42365: m_target->SetDisplayId(21723); break; + default: break; + } + } + else + { + CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue); + if(!ci) + { + //pig pink ^_^ + m_target->SetDisplayId(16358); + sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId()); + } + else + { + // Will use the default model here + m_target->SetDisplayId(ci->DisplayID_A); + + // Dragonmaw Illusion (set mount model also) + if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty()) + m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314); + } + m_target->setTransForm(GetId()); + } + + // polymorph case + if( Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed()) + { + // for players, start regeneration after 1s (in polymorph fast regeneration case) + // only if caster is Player (after patch 2.4.2) + if(IS_PLAYER_GUID(GetCasterGUID()) ) + ((Player*)m_target)->setRegenTimer(1000); + + //dismount polymorphed target (after patch 2.4.2) + if (m_target->IsMounted()) + m_target->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + } + } + else + { + Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM); + if(otherTransforms.empty()) + { + m_target->SetDisplayId(m_target->GetNativeDisplayId()); + m_target->setTransForm(0); + } + else + { + // look for other transform auras + Aura* handledAura = *otherTransforms.begin(); + for(Unit::AuraList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i) + { + // negative auras are prefered + if(!IsPositiveSpell((*i)->GetSpellProto()->Id)) + { + handledAura = *i; + break; + } + } + handledAura->ApplyModifier(true); + } + + // Dragonmaw Illusion (restore mount model) + if(GetId()==42016 && m_target->GetMountID()==16314) + { + if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty()) + { + uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue; + if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id)) + { + uint32 team = 0; + if (m_target->GetTypeId()==TYPEID_PLAYER) + team = ((Player*)m_target)->GetTeam(); + + uint32 display_id = objmgr.ChooseDisplayId(team,ci); + CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id); + if (minfo) + display_id = minfo->modelid; + + m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,display_id); + } + } + } + } +} + +void Aura::HandleForceReaction(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + if(!Real) + return; + + Player* player = (Player*)m_target; + + uint32 faction_id = m_modifier.m_miscvalue; + uint32 faction_rank = m_modifier.m_amount; + + if(apply) + player->m_forcedReactions[faction_id] = ReputationRank(faction_rank); + else + player->m_forcedReactions.erase(faction_id); + + WorldPacket data; + data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+player->m_forcedReactions.size()*(4+4)); + data << uint32(player->m_forcedReactions.size()); + for(ForcedReactions::const_iterator itr = player->m_forcedReactions.begin(); itr != player->m_forcedReactions.end(); ++itr) + { + data << uint32(itr->first); // faction_id (Faction.dbc) + data << uint32(itr->second); // reputation rank + } + player->SendDirectMessage(&data); +} + +void Aura::HandleAuraModSkill(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex]; + int32 points = GetModifier()->m_amount; + + ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_modifier.m_auraname==SPELL_AURA_MOD_SKILL_TALENT); + if(prot == SKILL_DEFENSE) + ((Player*)m_target)->UpdateDefenseBonusesMod(); +} + +void Aura::HandleChannelDeathItem(bool apply, bool Real) +{ + if(Real && !apply) + { + Unit* caster = GetCaster(); + Unit* victim = GetTarget(); + if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim || m_removeMode!=AURA_REMOVE_BY_DEATH) + return; + + SpellEntry const *spellInfo = GetSpellProto(); + if(spellInfo->EffectItemType[m_effIndex] == 0) + return; + + // Soul Shard only from non-grey units + if( spellInfo->EffectItemType[m_effIndex] == 6265 && + (victim->getLevel() <= MaNGOS::XP::GetGrayLevel(caster->getLevel()) || + victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) ) + return; + ItemPosCountVec dest; + uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 ); + if( msg != EQUIP_ERR_OK ) + { + ((Player*)caster)->SendEquipError( msg, NULL, NULL ); + return; + } + + Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true); + ((Player*)caster)->SendNewItem(newitem, 1, true, false); + } +} + +void Aura::HandleBindSight(bool apply, bool Real) +{ + Unit* caster = GetCaster(); + if(!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; + + caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0); +} + +void Aura::HandleFarSight(bool apply, bool Real) +{ + Unit* caster = GetCaster(); + if(!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; + + caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_modifier.m_miscvalue : 0); +} + +void Aura::HandleAuraTrackCreatures(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + if(apply) + m_target->RemoveNoStackAurasDueToAura(this); + m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 ); +} + +void Aura::HandleAuraTrackResources(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + if(apply) + m_target->RemoveNoStackAurasDueToAura(this); + m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 ); +} + +void Aura::HandleAuraTrackStealthed(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + if(apply) + m_target->RemoveNoStackAurasDueToAura(this); + + m_target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply); +} + +void Aura::HandleAuraModScale(bool apply, bool Real) +{ + m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply); +} + +void Aura::HandleModPossess(bool apply, bool Real) +{ + if(!Real) + return; + + if(m_target->getLevel() > m_modifier.m_amount) + return; + + // not possess yourself + if(GetCasterGUID() == m_target->GetGUID()) + return; + + Unit* caster = GetCaster(); + if(!caster) + return; + + if( apply ) + { + m_target->SetCharmerGUID(GetCasterGUID()); + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction()); + caster->SetCharm(m_target); + + m_target->CombatStop(); + m_target->DeleteThreatList(); + if(m_target->GetTypeId() == TYPEID_UNIT) + { + m_target->StopMoving(); + m_target->GetMotionMaster()->Clear(); + m_target->GetMotionMaster()->MoveIdle(); + CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target); + charmInfo->InitPossessCreateSpells(); + } + + if(caster->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)caster)->PossessSpellInitialize(); + } + } + else + { + m_target->SetCharmerGUID(0); + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)m_target)->setFactionForRace(m_target->getRace()); + } + else if(m_target->GetTypeId() == TYPEID_UNIT) + { + CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); + } + + caster->SetCharm(0); + + if(caster->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_PET_SPELLS, 8); + data << uint64(0); + ((Player*)caster)->GetSession()->SendPacket(&data); + } + if(m_target->GetTypeId() == TYPEID_UNIT) + { + ((Creature*)m_target)->AIM_Initialize(); + + if (((Creature*)m_target)->AI()) + ((Creature*)m_target)->AI()->AttackStart(caster); + } + } + if(caster->GetTypeId() == TYPEID_PLAYER) + caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0); +} + +void Aura::HandleModPossessPet(bool apply, bool Real) +{ + if(!Real) + return; + + Unit* caster = GetCaster(); + if(!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; + if(caster->GetPet() != m_target) + return; + + if(apply) + { + caster->SetUInt64Value(PLAYER_FARSIGHT, m_target->GetGUID()); + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + } + else + { + caster->SetUInt64Value(PLAYER_FARSIGHT, 0); + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + } +} + +void Aura::HandleModCharm(bool apply, bool Real) +{ + if(!Real) + return; + + // not charm yourself + if(GetCasterGUID() == m_target->GetGUID()) + return; + + Unit* caster = GetCaster(); + if(!caster) + return; + + if(int32(m_target->getLevel()) <= m_modifier.m_amount) + { + if( apply ) + { + m_target->SetCharmerGUID(GetCasterGUID()); + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction()); + m_target->CastStop(m_target==caster ? GetId() : 0); + caster->SetCharm(m_target); + + m_target->CombatStop(); + m_target->DeleteThreatList(); + + if(m_target->GetTypeId() == TYPEID_UNIT) + { + ((Creature*)m_target)->AIM_Initialize(); + CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target); + charmInfo->InitCharmCreateSpells(); + charmInfo->SetReactState( REACT_DEFENSIVE ); + + if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK) + { + CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); + if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) + { + //to prevent client crash + m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048); + //just to enable stat window + charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true); + //if charmed two demons the same session, the 2nd gets the 1st one's name + m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); + } + } + } + + if(caster->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)caster)->CharmSpellInitialize(); + } + } + else + { + m_target->SetCharmerGUID(0); + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)m_target)->setFactionForRace(m_target->getRace()); + } + else + { + CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); + + // restore faction + if(((Creature*)m_target)->isPet()) + { + if(Unit* owner = m_target->GetOwner()) + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction()); + else if(cinfo) + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); + } + else if(cinfo) // normal creature + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); + + // restore UNIT_FIELD_BYTES_0 + if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON) + { + CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon(); + if(cainfo && cainfo->bytes0 != 0) + m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0); + else + m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048); + + if(m_target->GetCharmInfo()) + m_target->GetCharmInfo()->SetPetNumber(0, true); + else + sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId()); + } + } + + caster->SetCharm(0); + + if(caster->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_PET_SPELLS, 8); + data << uint64(0); + ((Player*)caster)->GetSession()->SendPacket(&data); + } + if(m_target->GetTypeId() == TYPEID_UNIT) + { + ((Creature*)m_target)->AIM_Initialize(); + if (((Creature*)m_target)->AI()) + ((Creature*)m_target)->AI()->AttackStart(caster); + } + } + } +} + +void Aura::HandleModConfuse(bool apply, bool Real) +{ + if(!Real) + return; + + m_target->SetConfused(apply, GetCasterGUID(), GetId()); +} + +void Aura::HandleModFear(bool apply, bool Real) +{ + if (!Real) + return; + + m_target->SetFeared(apply, GetCasterGUID(), GetId()); +} + +void Aura::HandleFeignDeath(bool apply, bool Real) +{ + if(!Real) + return; + + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + if( apply ) + { + /* + WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9); + data<GetGUID(); + data<SendMessageToSet(&data,true); + */ + // blizz like 2.0.x + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6); + // blizz like 2.0.x + m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + // blizz like 2.0.x + m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + + m_target->addUnitState(UNIT_STAT_DIED); + m_target->CombatStop(); + + // prevent interrupt message + if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL]) + m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish(); + m_target->InterruptNonMeleeSpells(true); + m_target->getHostilRefManager().deleteReferences(); + } + else + { + /* + WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9); + data<GetGUID(); + data<SendMessageToSet(&data,true); + */ + // blizz like 2.0.x + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6); + // blizz like 2.0.x + m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + // blizz like 2.0.x + m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + + m_target->clearUnitState(UNIT_STAT_DIED); + } +} + +void Aura::HandleAuraModDisarm(bool apply, bool Real) +{ + if(!Real) + return; + + if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM)) + return; + + // not sure for it's correctness + if(apply) + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + else + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + + // only at real add/remove aura + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + + // main-hand attack speed already set to special value for feral form already and don't must chnage and reset at remove. + if (((Player *)m_target)->IsInFeralForm()) + return; + + if (apply) + m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME); + else + ((Player *)m_target)->SetRegularAttackTime(); + + m_target->UpdateDamagePhysical(BASE_ATTACK); +} + +void Aura::HandleAuraModStun(bool apply, bool Real) +{ + if(!Real) + return; + + if (apply) + { + m_target->addUnitState(UNIT_STAT_STUNNED); + m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0); + + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + m_target->CastStop(m_target->GetGUID() == GetCasterGUID() ? GetId() : 0); + + // Creature specific + if(m_target->GetTypeId() != TYPEID_PLAYER) + ((Creature*)m_target)->StopMoving(); + else + m_target->SetUnitMovementFlags(0); //Clear movement flags + + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8); + + data.append(m_target->GetPackGUID()); + data << uint32(0); + m_target->SendMessageToSet(&data,true); + } + else + { + // Real remove called after current aura remove from lists, check if other similar auras active + if(m_target->HasAuraType(SPELL_AURA_MOD_STUN)) + return; + + m_target->clearUnitState(UNIT_STAT_STUNNED); + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + + if(!m_target->hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect + { + if(m_target->getVictim() && m_target->isAlive()) + m_target->SetUInt64Value(UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() ); + + WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4); + data.append(m_target->GetPackGUID()); + data << uint32(0); + m_target->SendMessageToSet(&data,true); + } + + // Wyvern Sting + if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1721) + { + Unit* caster = GetCaster(); + if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) + return; + + uint32 spell_id = 0; + + switch(GetId()) + { + case 19386: spell_id = 24131; break; + case 24132: spell_id = 24134; break; + case 24133: spell_id = 24135; break; + case 27068: spell_id = 27069; break; + default: + sLog.outError("Spell selection called for unexpected original spell %u, new spell for this spell family?",GetId()); + return; + } + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id); + + if(!spellInfo) + return; + + caster->CastSpell(m_target,spellInfo,true,NULL,this); + return; + } + } +} + +void Aura::HandleModStealth(bool apply, bool Real) +{ + if(apply) + { + // drop flag at stealth in bg + if(Real && m_target->GetTypeId()==TYPEID_PLAYER && ((Player*)m_target)->InBattleGround()) + if(BattleGround *bg = ((Player*)m_target)->GetBattleGround()) + bg->EventPlayerDroppedFlag((Player*)m_target); + + // only at real aura add + if(Real) + { + m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02); + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000); + + // apply only if not in GM invisibility (and overwrite invisibility state) + if(m_target->GetVisibility()!=VISIBILITY_OFF) + { + m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); + } + + // for RACE_NIGHTELF stealth + if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580) + m_target->CastSpell(m_target, 21009, true, NULL, this); + } + } + else + { + // only at real aura remove + if(Real) + { + // for RACE_NIGHTELF stealth + if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580) + m_target->RemoveAurasDueToSpell(21009); + + // if last SPELL_AURA_MOD_STEALTH and no GM invisibility + if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF) + { + m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00); + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000); + + // restore invisibility if any + if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) + { + m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + } + else + m_target->SetVisibility(VISIBILITY_ON); + } + } + } + + // Master of Subtlety + Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + { + if ((*i)->GetSpellProto()->SpellIconID == 2114) + { + if (apply) + { + int32 bp = (*i)->GetModifier()->m_amount; + m_target->CastCustomSpell(m_target,31665,&bp,NULL,NULL,true); + } + else + m_target->CastSpell(m_target,31666,true); + break; + } + } +} + +void Aura::HandleInvisibility(bool apply, bool Real) +{ + if(apply) + { + m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue); + + if(Real && m_target->GetTypeId()==TYPEID_PLAYER) + { + // apply glow vision + m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); + + // drop flag at invisible in bg + if(((Player*)m_target)->InBattleGround()) + if(BattleGround *bg = ((Player*)m_target)->GetBattleGround()) + bg->EventPlayerDroppedFlag((Player*)m_target); + } + + // apply only if not in GM invisibility and not stealth + if(m_target->GetVisibility()==VISIBILITY_ON) + { + // Aura not added yet but visibility code expect temporary add aura + m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); + m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); + } + } + else + { + // recalculate value at modifier remove (current aura already removed) + m_target->m_invisibilityMask = 0; + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue); + + // only at real aura remove and if not have different invisibility auras. + if(Real && m_target->m_invisibilityMask==0) + { + // remove glow vision + if(m_target->GetTypeId() == TYPEID_PLAYER) + m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); + + // apply only if not in GM invisibility & not stealthed while invisible + if(m_target->GetVisibility()!=VISIBILITY_OFF) + { + // if have stealth aura then already have stealth visibility + if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) + m_target->SetVisibility(VISIBILITY_ON); + } + } + } +} + +void Aura::HandleInvisibilityDetect(bool apply, bool Real) +{ + if(apply) + { + m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue); + } + else + { + // recalculate value at modifier remove (current aura already removed) + m_target->m_detectInvisibilityMask = 0; + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue); + } + if(Real && m_target->GetTypeId()==TYPEID_PLAYER) + ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target); +} + +void Aura::HandleAuraModRoot(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + uint32 apply_stat = UNIT_STAT_ROOT; + if (apply) + { + m_target->addUnitState(UNIT_STAT_ROOT); + m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0); + // probably wrong + m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); + + //Save last orientation + if( m_target->getVictim() ) + m_target->SetOrientation(m_target->GetAngle(m_target->getVictim())); + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); + data.append(m_target->GetPackGUID()); + data << (uint32)2; + m_target->SendMessageToSet(&data,true); + + //Clear unit movement flags + m_target->SetUnitMovementFlags(0); + } + else + ((Creature *)m_target)->StopMoving(); + } + else + { + // Real remove called after current aura remove from lists, check if other similar auras active + if(m_target->HasAuraType(SPELL_AURA_MOD_ROOT)) + return; + + m_target->clearUnitState(UNIT_STAT_ROOT); + // probably wrong + m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); + + if(!m_target->hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect + { + if(m_target->getVictim() && m_target->isAlive()) + m_target->SetUInt64Value (UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() ); + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10); + data.append(m_target->GetPackGUID()); + data << (uint32)2; + m_target->SendMessageToSet(&data,true); + } + } + } +} + +void Aura::HandleAuraModSilence(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + if(apply) + { + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED); + // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE + for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++) + { + Spell* currentSpell = m_target->m_currentSpells[i]; + if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + { + uint32 state = currentSpell->getState(); + // Stop spells on prepere or casting state + if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING ) + { + currentSpell->cancel(); + currentSpell->SetDeletable(true); + m_target->m_currentSpells[i] = NULL; + } + } + } + + switch (GetId()) + { + // Arcane Torrent (Energy) + case 25046: + { + Unit * caster = GetCaster(); + if (!caster) + return; + + // Search Mana Tap auras on caster + int32 energy = 0; + Unit::AuraList const& m_dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i) + if ((*i)->GetId() == 28734) + ++energy; + if (energy) + { + energy *= 10; + caster->CastCustomSpell(caster, 25048, &energy, NULL, NULL, true); + caster->RemoveAurasDueToSpell(28734); + } + } + } + } + else + { + // Real remove called after current aura remove from lists, check if other similar auras active + if(m_target->HasAuraType(SPELL_AURA_MOD_SILENCE)) + return; + + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED); + } +} + +void Aura::HandleModThreat(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + if(!m_target->isAlive()) + return; + + Unit* caster = GetCaster(); + + if(!caster || !caster->isAlive()) + return; + + int level_diff = 0; + int multiplier = 0; + switch (GetId()) + { + // Arcane Shroud + case 26400: + level_diff = m_target->getLevel() - 60; + multiplier = 2; + break; + // The Eye of Diminution + case 28862: + level_diff = m_target->getLevel() - 60; + multiplier = 1; + break; + } + if (level_diff > 0) + m_modifier.m_amount += multiplier * level_diff; + + for(int8 x=0;x < MAX_SPELL_SCHOOL;x++) + { + if(m_modifier.m_miscvalue & int32(1<GetTypeId() == TYPEID_PLAYER) + ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? m_modifier.m_amount : -m_modifier.m_amount, apply); + } + } +} + +void Aura::HandleAuraModTotalThreat(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + if(!m_target->isAlive() || m_target->GetTypeId()!= TYPEID_PLAYER) + return; + + Unit* caster = GetCaster(); + + if(!caster || !caster->isAlive()) + return; + + float threatMod = 0.0f; + if(apply) + threatMod = float(m_modifier.m_amount); + else + threatMod = float(-m_modifier.m_amount); + + m_target->getHostilRefManager().threatAssist(caster, threatMod); +} + +void Aura::HandleModTaunt(bool apply, bool Real) +{ + // only at real add/remove aura + if(!Real) + return; + + if(!m_target->isAlive() || !m_target->CanHaveThreatList()) + return; + + Unit* caster = GetCaster(); + + if(!caster || !caster->isAlive() || caster->GetTypeId() != TYPEID_PLAYER) + return; + + if(apply) + { + m_target->TauntApply(caster); + } + else + { + // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat + m_target->TauntFadeOut(caster); + } +} + +/*********************************************************/ +/*** MODIFY SPEED ***/ +/*********************************************************/ +void Aura::HandleAuraModIncreaseSpeed(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + m_target->UpdateSpeed(MOVE_RUN, true); +} + +void Aura::HandleAuraModIncreaseMountedSpeed(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + m_target->UpdateSpeed(MOVE_RUN, true); +} + +void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + // Enable Fly mode for flying mounts + if (m_modifier.m_auraname == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) + { + WorldPacket data; + if(apply) + data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12); + else + data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12); + data.append(m_target->GetPackGUID()); + data << uint32(0); // unknown + m_target->SendMessageToSet(&data, true); + + //Players on flying mounts must be immune to polymorph + if (m_target->GetTypeId()==TYPEID_PLAYER) + m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply); + + // Dragonmaw Illusion (overwrite mount model, mounted aura already applied) + if( apply && m_target->HasAura(42016,0) && m_target->GetMountID()) + m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314); + } + + m_target->UpdateSpeed(MOVE_FLY, true); +} + +void Aura::HandleAuraModIncreaseSwimSpeed(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + m_target->UpdateSpeed(MOVE_SWIM, true); +} + +void Aura::HandleAuraModDecreaseSpeed(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + m_target->UpdateSpeed(MOVE_RUN, true); + m_target->UpdateSpeed(MOVE_SWIM, true); + m_target->UpdateSpeed(MOVE_FLY, true); +} + +void Aura::HandleAuraModUseNormalSpeed(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + m_target->UpdateSpeed(MOVE_RUN, true); + m_target->UpdateSpeed(MOVE_SWIM, true); + m_target->UpdateSpeed(MOVE_FLY, true); +} + +/*********************************************************/ +/*** IMMUNITY ***/ +/*********************************************************/ + +void Aura::HandleModMechanicImmunity(bool apply, bool Real) +{ + uint32 mechanic = 1 << m_modifier.m_miscvalue; + + //immune movement impairment and loss of control + if(GetId()==42292) + mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; + + if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + { + Unit::AuraMap& Auras = m_target->GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + { + next = iter; + ++next; + SpellEntry const *spell = iter->second->GetSpellProto(); + if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability + && !iter->second->IsPositive() // only remove negative spells + && spell->Id != GetId()) + { + //check for mechanic mask + if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic) + { + m_target->RemoveAurasDueToSpell(spell->Id); + if(Auras.empty()) + break; + else + next = Auras.begin(); + } + } + } + } + + m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply); + + // special cases + switch(m_modifier.m_miscvalue) + { + case MECHANIC_INVULNERABILITY: + m_target->ModifyAuraState(AURA_STATE_FORBEARANCE,apply); + break; + case MECHANIC_SHIELD: + m_target->ModifyAuraState(AURA_STATE_WEAKENED_SOUL,apply); + break; + } + + // Bestial Wrath + if ( GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1680) + { + // The Beast Within cast on owner if talent present + if ( Unit* owner = m_target->GetOwner() ) + { + // Search talent + Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i) + { + if ( (*i)->GetSpellProto()->SpellIconID == 2229 ) + { + if (apply) + owner->CastSpell(owner, 34471, true, 0, this); + else + owner->RemoveAurasDueToSpell(34471); + break; + } + } + } + } + + // The Beast Within and Bestial Wrath - immunity + if(GetId() == 19574 || GetId() == 34471) + { + if(apply) + { + m_target->CastSpell(m_target,24395,true); + m_target->CastSpell(m_target,24396,true); + m_target->CastSpell(m_target,24397,true); + m_target->CastSpell(m_target,26592,true); + } + else + { + m_target->RemoveAurasDueToSpell(24395); + m_target->RemoveAurasDueToSpell(24396); + m_target->RemoveAurasDueToSpell(24397); + m_target->RemoveAurasDueToSpell(26592); + } + } +} + +void Aura::HandleAuraModEffectImmunity(bool apply, bool Real) +{ + if(!apply) + { + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)m_target)->InBattleGround()) + { + BattleGround *bg = ((Player*)m_target)->GetBattleGround(); + if(bg) + { + switch(bg->GetTypeID()) + { + case BATTLEGROUND_AV: + { + break; + } + case BATTLEGROUND_WS: + { + // Warsong Flag, horde // Silverwing Flag, alliance + if(GetId() == 23333 || GetId() == 23335) + bg->EventPlayerDroppedFlag(((Player*)m_target)); + break; + } + case BATTLEGROUND_AB: + { + break; + } + case BATTLEGROUND_EY: + { + if(GetId() == 34976) + bg->EventPlayerDroppedFlag(((Player*)m_target)); + break; + } + } + } + } + } + } + + m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply); +} + +void Aura::HandleAuraModStateImmunity(bool apply, bool Real) +{ + if(apply && Real && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + { + Unit::AuraList const& auraList = m_target->GetAurasByType(AuraType(m_modifier.m_miscvalue)); + for(Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();) + { + if (auraList.front() != this) // skip itself aura (it already added) + { + m_target->RemoveAurasDueToSpell(auraList.front()->GetId()); + itr = auraList.begin(); + } + else + ++itr; + } + } + + m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply); +} + +void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real) +{ + m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply); + + if(Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + { + if(IsPositiveSpell(GetId())) //Only positive immunity removes auras + { + uint32 school_mask = m_modifier.m_miscvalue; + Unit::AuraMap& Auras = m_target->GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + { + next = iter; + ++next; + SpellEntry const *spell = iter->second->GetSpellProto(); + if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask + && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability + && !iter->second->IsPositive() //Don't remove positive spells + && spell->Id != GetId() ) //Don't remove self + { + m_target->RemoveAurasDueToSpell(spell->Id); + if(Auras.empty()) + break; + else + next = Auras.begin(); + } + } + } + } + if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH ) + { + if( apply ) + m_target->addUnitState(UNIT_STAT_ISOLATED); + else + m_target->clearUnitState(UNIT_STAT_ISOLATED); + } +} + +void Aura::HandleAuraModDmgImmunity(bool apply, bool Real) +{ + m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply); +} + +void Aura::HandleAuraModDispelImmunity(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(m_modifier.m_miscvalue), apply); +} + +void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real) +{ + if(!Real) + return; + + if(apply) + { + // some spell have charges by functionality not have its in spell data + switch (GetId()) + { + case 28200: // Ascendance (Talisman of Ascendance trinket) + m_procCharges = 6; + UpdateAuraCharges(); + break; + default: break; + } + } +} + +void Aura::HandleAuraModStalked(bool apply, bool Real) +{ + // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND + if(apply) + m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT); + else + m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT); +} + +/*********************************************************/ +/*** PERIODIC ***/ +/*********************************************************/ + +void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; + m_isTrigger = apply; + + // Curse of the Plaguebringer + if (!apply && m_spellProto->Id == 29213 && m_removeMode!=AURA_REMOVE_BY_DISPEL) + { + // Cast Wrath of the Plaguebringer if not dispelled + m_target->CastSpell(m_target, 29214, true, 0, this); + } +} + +void Aura::HandlePeriodicEnergize(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; +} + +void Aura::HandlePeriodicHeal(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; + + // only at real apply + if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE) + { + // provided m_target as original caster to prevent apply aura caster selection for this negative buff + m_target->CastSpell(m_target,11196,true,NULL,this,m_target->GetGUID()); + } + + // For prevent double apply bonuses + bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); + + if(!loading && apply) + { + switch (m_spellProto->SpellFamilyName) + { + case SPELLFAMILY_DRUID: + { + // Rejuvenation + if(m_spellProto->SpellFamilyFlags & 0x0000000000000010LL) + { + if(Unit* caster = GetCaster()) + { + Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k) + { + int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex]; + switch((*k)->GetModifier()->m_miscvalue) + { + case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura + case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura + { + m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount; + break; + } + } + } + } + } + } + } + } +} + +void Aura::HandlePeriodicDamage(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; + + // For prevent double apply bonuses + bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); + + Unit *caster = GetCaster(); + + switch (m_spellProto->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + // Pounce Bleed + if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0 ) + { + // $AP*0.18/6 bonus per tick + if (apply && !loading && caster) + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100); + return; + } + break; + } + case SPELLFAMILY_WARRIOR: + { + // Rend + if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL) + { + // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick + if (apply && !loading && caster) + { + float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); + int32 mws = caster->GetAttackTime(BASE_ATTACK); + float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE); + float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE); + // WARNING! in 3.0 multipler 0.00743f change to 0.6 + m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f); + } + return; + } + break; + } + case SPELLFAMILY_DRUID: + { + // Rake + if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL) + { + // $AP*0.06/3 bonus per tick + if (apply && !loading && caster) + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100); + return; + } + // Lacerate + if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL) + { + // $AP*0.05/5 bonus per tick + if (apply && !loading && caster) + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); + return; + } + // Rip + if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL) + { + // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, wheather 4 or 5 CPs are being used] + if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER) + { + uint8 cp = ((Player*)caster)->GetComboPoints(); + + // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs + Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + if((*itr)->GetId()==34241) + { + m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount; + break; + } + } + + if (cp > 4) cp = 4; + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100); + } + return; + } + break; + } + case SPELLFAMILY_ROGUE: + { + // Deadly poison aura state + if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100) + { + if(apply) + m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true); + else + { + // current aura already removed, search present of another + bool found = false; + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const* itr_spell = (*itr)->GetSpellProto(); + if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100) + { + found = true; + break; + } + } + // this has been last deadly poison aura + if(!found) + m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false); + } + return; + } + // Rupture + if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL) + { + // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP inrease the contribution from AP] + if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER) + { + uint8 cp = ((Player*)caster)->GetComboPoints(); + if (cp > 3) cp = 3; + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100); + } + return; + } + // Garrote + if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL) + { + // $AP*0.18/6 bonus per tick + if (apply && !loading && caster) + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100); + return; + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Serpent Sting + if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL) + { + // $RAP*0.1/5 bonus per tick + if (apply && !loading && caster) + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500); + return; + } + // Immolation Trap + if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678) + { + // $RAP*0.1/5 bonus per tick + if (apply && !loading && caster) + m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500); + return; + } + break; + } + case SPELLFAMILY_PALADIN: + { + // Consecration + if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL) + { + if (apply && !loading) + { + if(Unit* caster = GetCaster()) + { + Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k) + { + int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex]; + switch((*k)->GetModifier()->m_miscvalue) + { + case 5147: // Improved Consecration - Libram of the Eternal Rest + { + m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount; + break; + } + } + } + } + } + return; + } + break; + } + default: + break; + } +} + +void Aura::HandlePeriodicDamagePCT(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; +} + +void Aura::HandlePeriodicLeech(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; +} + +void Aura::HandlePeriodicManaLeech(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; +} + +/*********************************************************/ +/*** MODIFY STATS ***/ +/*********************************************************/ + +/********************************/ +/*** RESISTANCE ***/ +/********************************/ + +void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real) +{ + for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++) + { + if(m_modifier.m_miscvalue & int32(1<HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_modifier.m_amount), apply); + if(m_target->GetTypeId() == TYPEID_PLAYER) + m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply); + } + } +} + +void Aura::HandleAuraModResistance(bool apply, bool Real) +{ + for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++) + { + if(m_modifier.m_miscvalue & int32(1<HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_modifier.m_amount), apply); + if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet()) + m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply); + } + } + + // Faerie Fire (druid versions) + if( m_spellProto->SpellIconID == 109 && + m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && + m_spellProto->SpellFamilyFlags & 0x0000000000000400LL ) + { + m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply); + } +} + +void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real) +{ + // only players have base stats + if(m_target->GetTypeId() != TYPEID_PLAYER) + { + //pets only have base armor + if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)) + { + m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_modifier.m_amount), apply); + } + } + else + { + for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++) + { + if(m_modifier.m_miscvalue & int32(1<HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_modifier.m_amount), apply); + } + } + } +} + +void Aura::HandleModResistancePercent(bool apply, bool Real) +{ + for(int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++) + { + if(m_modifier.m_miscvalue & int32(1<HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply); + if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet()) + { + m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply); + m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply); + } + } + } +} + +void Aura::HandleModBaseResistance(bool apply, bool Real) +{ + // only players have base stats + if(m_target->GetTypeId() != TYPEID_PLAYER) + { + //only pets have base stats + if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)) + m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_modifier.m_amount), apply); + } + else + { + for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++) + if(m_modifier.m_miscvalue & (1<HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply); + } +} + +/********************************/ +/*** STAT ***/ +/********************************/ + +void Aura::HandleAuraModStat(bool apply, bool Real) +{ + if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4) + { + sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),m_modifier.m_miscvalue); + return; + } + + for(int32 i = STAT_STRENGTH; i < MAX_STATS; i++) + { + // -1 or -2 is all stats ( misc < -2 checked in function beginning ) + if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i) + { + //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply); + m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply); + if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet()) + m_target->ApplyStatBuffMod(Stats(i),m_modifier.m_amount,apply); + } + } +} + +void Aura::HandleModPercentStat(bool apply, bool Real) +{ + if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4) + { + sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid"); + return; + } + + // only players have base stats + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + + for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i) + { + if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1) + { + m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_modifier.m_amount), apply); + } + } +} + +void Aura::HandleModSpellDamagePercentFromStat(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + // Magic damage modifiers implemented in Unit::SpellDamageBonus + // This information for client side use only + // Recalculate bonus + ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); +} + +void Aura::HandleModSpellHealingPercentFromStat(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + // Recalculate bonus + ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); +} + +void Aura::HandleAuraModDispelResist(bool apply, bool Real) +{ + if(!Real || !apply) + return; + + if(GetId()==33206) + m_target->CastSpell(m_target,44416,true,NULL,this,GetCasterGUID()); +} + +void Aura::HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + // Magic damage modifiers implemented in Unit::SpellDamageBonus + // This information for client side use only + // Recalculate bonus + ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); +} + +void Aura::HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + // Recalculate bonus + ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); +} + +void Aura::HandleModHealingDone(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + // implemented in Unit::SpellHealingBonus + // this information is for client side only + ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); +} + +void Aura::HandleModTotalPercentStat(bool apply, bool Real) +{ + if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4) + { + sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid"); + return; + } + + //save current and max HP before applying aura + uint32 curHPValue = m_target->GetHealth(); + uint32 maxHPValue = m_target->GetMaxHealth(); + + for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++) + { + if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1) + { + m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply); + if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet()) + m_target->ApplyStatPercentBuffMod(Stats(i), m_modifier.m_amount, apply ); + } + } + + //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag) + if ((m_modifier.m_miscvalue == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10)) + { + // newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed + uint32 newHPValue = (m_target->GetMaxHealth() * curHPValue) / maxHPValue; + m_target->SetHealth(newHPValue); + } +} + +void Aura::HandleAuraModResistenceOfStatPercent(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + if(m_modifier.m_miscvalue != SPELL_SCHOOL_MASK_NORMAL) + { + // support required adding replace UpdateArmor by loop by UpdateResistence at intelect update + // and include in UpdateResistence same code as in UpdateArmor for aura mod apply. + sLog.outError("Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) need adding support for non-armor resistences!"); + return; + } + + // Recalculate Armor + m_target->UpdateArmor(); +} + +/********************************/ +/*** HEAL & ENERGIZE ***/ +/********************************/ +void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real) +{ + /* + Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic, + so this aura not fully working. + */ + if(apply) + { + if(!m_target->isAlive()) + return; + + if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState()) + m_target->SetStandState(PLAYER_STATE_SIT); + + if(m_periodicTimer <= 0) + { + m_periodicTimer += m_modifier.periodictime; + + if(m_target->GetHealth() < m_target->GetMaxHealth()) + { + // PeriodicTick can cast triggered spells with stats changes + PeriodicTick(); + } + } + } + + m_isPeriodic = apply; +} + +void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real) +{ + if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState()) + m_target->SetStandState(PLAYER_STATE_SIT); + if(apply) + { + if(m_modifier.periodictime == 0) + m_modifier.periodictime = 1000; + if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA) + { + m_periodicTimer += m_modifier.periodictime; + + if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA)) + { + // PeriodicTick can cast triggered spells with stats changes + PeriodicTick(); + } + } + } + + m_isPeriodic = apply; +} + +void Aura::HandleModRegen(bool apply, bool Real) // eating +{ + if(apply) + { + if(!m_target->isAlive()) + return; + + if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState()) + m_target->SetStandState(PLAYER_STATE_SIT); + + if(m_periodicTimer <= 0) + { + m_periodicTimer += 5000; + int32 gain = m_target->ModifyHealth(m_modifier.m_amount); + Unit *caster = GetCaster(); + if (caster) + { + SpellEntry const *spellProto = GetSpellProto(); + if (spellProto) + m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto); + } + } + } + + m_isPeriodic = apply; +} + +void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking +{ + if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState()) + m_target->SetStandState(PLAYER_STATE_SIT); + + if(apply && m_periodicTimer <= 0) + { + m_periodicTimer += 2000; + + Powers pt = m_target->getPowerType(); + if(int32(pt) != m_modifier.m_miscvalue) + return; + + if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED ) + { + // eating anim + m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT); + } + else if( GetId() == 20577 ) + { + // cannibalize anim + m_target->HandleEmoteCommand(398); + } + + // Warrior talent, gain 1 rage every 3 seconds while in combat + if(pt == POWER_RAGE && m_target->isInCombat()) + { + m_target->ModifyPower(pt, m_modifier.m_amount*10/17); + m_periodicTimer += 1000; + } + } + m_isPeriodic = apply; + if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA) + ((Player*)m_target)->UpdateManaRegen(); +} + +void Aura::HandleModPowerRegenPCT(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + + // Update manaregen value + if (m_modifier.m_miscvalue == POWER_MANA) + ((Player*)m_target)->UpdateManaRegen(); +} + +void Aura::HandleModManaRegen(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + + //Note: an increase in regen does NOT cause threat. + ((Player*)m_target)->UpdateManaRegen(); +} + +void Aura::HandleComprehendLanguage(bool apply, bool Real) +{ + if(apply) + m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG); + else + m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG); +} + +void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real) +{ + // Special case with temporary increase max/current health + switch(GetId()) + { + case 12976: // Warrior Last Stand triggered spell + case 28726: // Nightmare Seed ( Nightmare Seed ) + case 34511: // Valor (Bulwark of Kings, Bulwark of the Ancient Kings) + case 44055: // Tremendous Fortitude (Battlemaster's Alacrity) + { + if(Real) + { + if(apply) + { + m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply); + m_target->ModifyHealth(m_modifier.m_amount); + } + else + { + if (int32(m_target->GetHealth()) > m_modifier.m_amount) + m_target->ModifyHealth(-m_modifier.m_amount); + else + m_target->SetHealth(1); + m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply); + } + } + return; + } + } + + // generic case + m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real) +{ + uint32 oldhealth = m_target->GetHealth(); + double healthPercentage = (double)oldhealth / (double)m_target->GetMaxHealth(); + + m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply); + + // refresh percentage + if(oldhealth > 0) + { + uint32 newhealth = uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)); + if(newhealth==0) + newhealth = 1; + + m_target->SetHealth(newhealth); + } +} + +void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real) +{ + Powers powerType = m_target->getPowerType(); + if(int32(powerType) != m_modifier.m_miscvalue) + return; + + m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_VALUE, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool Real) +{ + Powers powerType = m_target->getPowerType(); + if(int32(powerType) != m_modifier.m_miscvalue) + return; + + m_target->HandleStatModifier(UnitMods(UNIT_MOD_POWER_START + powerType), TOTAL_PCT, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool Real) +{ + //m_target->ApplyMaxHealthPercentMod(m_modifier.m_amount,apply); + m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply); +} + +/********************************/ +/*** FIGHT ***/ +/********************************/ + +void Aura::HandleAuraModParryPercent(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + ((Player*)m_target)->UpdateParryPercentage(); +} + +void Aura::HandleAuraModDodgePercent(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + ((Player*)m_target)->UpdateDodgePercentage(); + //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount)); +} + +void Aura::HandleAuraModBlockPercent(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + ((Player*)m_target)->UpdateBlockPercentage(); + //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_modifier.m_amount)); +} + +void Aura::HandleAuraModRegenInterrupt(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + ((Player*)m_target)->UpdateManaRegen(); +} + +void Aura::HandleAuraModCritPercent(bool apply, bool Real) +{ + if(m_target->GetTypeId()!=TYPEID_PLAYER) + return; + + // apply item specific bonuses for already equipped weapon + if(Real) + { + for(int i = 0; i < MAX_ATTACK; ++i) + if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) + ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,WeaponAttackType(i),this,apply); + } + + // mods must be applied base at equipped weapon class and subclass comparison + // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask + // m_modifier.m_miscvalue comparison with item generated damage types + + if (GetSpellProto()->EquippedItemClass == -1) + { + ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply); + ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply); + ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply); + } + else + { + // done in Player::_ApplyWeaponDependentAuraMods + } +} + +void Aura::HandleModHitChance(bool apply, bool Real) +{ + m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount); + m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount); +} + +void Aura::HandleModSpellHitChance(bool apply, bool Real) +{ + m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount); +} + +void Aura::HandleModSpellCritChance(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)m_target)->UpdateAllSpellCritChances(); + } + else + { + m_target->m_baseSpellCritChance += apply ? m_modifier.m_amount:(-m_modifier.m_amount); + } +} + +void Aura::HandleModSpellCritChanceShool(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + for(int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school) + if (m_modifier.m_miscvalue & (1<UpdateSpellCritChance(school); +} + +/********************************/ +/*** ATTACK SPEED ***/ +/********************************/ + +void Aura::HandleModCastingSpeed(bool apply, bool Real) +{ + m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply); +} + +void Aura::HandleModMeleeRangedSpeedPct(bool apply, bool Real) +{ + m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply); +} + +void Aura::HandleModCombatSpeedPct(bool apply, bool Real) +{ + m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply); +} + +void Aura::HandleModAttackSpeed(bool apply, bool Real) +{ + if(!m_target->isAlive() ) + return; + + m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply); +} + +void Aura::HandleHaste(bool apply, bool Real) +{ + m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_modifier.m_amount,apply); + m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply); +} + +void Aura::HandleAuraModRangedHaste(bool apply, bool Real) +{ + m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply); +} + +void Aura::HandleRangedAmmoHaste(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply); +} + +/********************************/ +/*** ATTACK POWER ***/ +/********************************/ + +void Aura::HandleAuraModAttackPower(bool apply, bool Real) +{ + m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real) +{ + if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0) + return; + + m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraAttackPowerAttacker(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + Unit *caster = GetCaster(); + + if (!caster) + return; + + // Hunter's Mark + if (m_spellProto->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + { + // Check Improved Hunter's Mark bonus on caster + Unit::AuraList const& mOverrideClassScript = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + // mproved Hunter's Mark script from 5236 to 5240 + if (mod->m_miscvalue >= 5236 && mod->m_miscvalue <= 5240) + { + // Get amount of ranged bonus for this spell.. + int32 ranged_bonus = caster->CalculateSpellDamage(m_spellProto, 1, m_spellProto->EffectBasePoints[1], m_target); + // Set melee attack power bonus % from ranged depends from Improved mask aura + m_modifier.m_amount = mod->m_amount * ranged_bonus / 100; + m_currentBasePoints = m_modifier.m_amount; + break; + } + } + return; + } +} + +void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real) +{ + //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1 + m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real) +{ + if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0) + return; + + //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1 + m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0) + return; + + if(m_modifier.m_miscvalue != STAT_INTELLECT) + { + // support required adding UpdateAttackPowerAndDamage calls at stat update + sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intelect stats!"); + return; + } + + // Recalculate bonus + ((Player*)m_target)->UpdateAttackPowerAndDamage(true); +} + +/********************************/ +/*** DAMAGE BONUS ***/ +/********************************/ +void Aura::HandleModDamageDone(bool apply, bool Real) +{ + // apply item specific bonuses for already equipped weapon + if(Real && m_target->GetTypeId()==TYPEID_PLAYER) + { + for(int i = 0; i < MAX_ATTACK; ++i) + if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) + ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply); + } + + // m_modifier.m_miscvalue is bitmask of spell schools + // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL) + // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands + // 127 - full bitmask any damages + // + // mods must be applied base at equipped weapon class and subclass comparison + // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask + // m_modifier.m_miscvalue comparison with item generated damage types + + if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0) + { + // apply generic physical damage bonuses including wand case + if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER) + { + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply); + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply); + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply); + } + else + { + // done in Player::_ApplyWeaponDependentAuraMods + } + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + if(m_positive) + m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply); + else + m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply); + } + } + + // Skip non magic case for speedup + if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0) + return; + + if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 ) + { + // wand magic case (skip generic to all item spell bonuses) + // done in Player::_ApplyWeaponDependentAuraMods + + // Skip item specific requirements for not wand magic damage + return; + } + + // Magic damage modifiers implemented in Unit::SpellDamageBonus + // This information for client side use only + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + if(m_positive) + { + for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) + { + if((m_modifier.m_miscvalue & (1<ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_modifier.m_amount,apply); + } + } + else + { + for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) + { + if((m_modifier.m_miscvalue & (1<ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_modifier.m_amount,apply); + } + } + Pet* pet = m_target->GetPet(); + if(pet) + pet->UpdateAttackPowerAndDamage(); + } +} + +void Aura::HandleModDamagePercentDone(bool apply, bool Real) +{ + sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", m_modifier.m_miscvalue, m_positive ? 0 : 1); + + // apply item specific bonuses for already equipped weapon + if(Real && m_target->GetTypeId()==TYPEID_PLAYER) + { + for(int i = 0; i < MAX_ATTACK; ++i) + if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) + ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply); + } + + // m_modifier.m_miscvalue is bitmask of spell schools + // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL) + // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand + // 127 - full bitmask any damages + // + // mods must be applied base at equipped weapon class and subclass comparison + // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask + // m_modifier.m_miscvalue comparison with item generated damage types + + if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0) + { + // apply generic physical damage bonuses including wand case + if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER) + { + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_modifier.m_amount), apply); + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply); + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply); + } + else + { + // done in Player::_ApplyWeaponDependentAuraMods + } + // For show in client + if(m_target->GetTypeId() == TYPEID_PLAYER) + m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_modifier.m_amount/100.0f,apply); + } + + // Skip non magic case for speedup + if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0) + return; + + if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 ) + { + // wand magic case (skip generic to all item spell bonuses) + // done in Player::_ApplyWeaponDependentAuraMods + + // Skip item specific requirements for not wand magic damage + return; + } + + // Magic damage percent modifiers implemented in Unit::SpellDamageBonus + // Send info to client + if(m_target->GetTypeId() == TYPEID_PLAYER) + for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_modifier.m_amount/100.0f,apply); +} + +void Aura::HandleModOffhandDamagePercent(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + sLog.outDebug("AURA MOD OFFHAND DAMAGE"); + + m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply); +} + +/********************************/ +/*** POWER COST ***/ +/********************************/ + +void Aura::HandleModPowerCostPCT(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + float amount = m_modifier.m_amount/100.0f; + for(int i = 0; i < MAX_SPELL_SCHOOL; ++i) + if(m_modifier.m_miscvalue & (1<ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply); +} + +void Aura::HandleModPowerCost(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + for(int i = 0; i < MAX_SPELL_SCHOOL; ++i) + if(m_modifier.m_miscvalue & (1<ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_modifier.m_amount,apply); +} + +/*********************************************************/ +/*** OTHERS ***/ +/*********************************************************/ + +void Aura::HandleShapeshiftBoosts(bool apply) +{ + uint32 spellId = 0; + uint32 spellId2 = 0; + uint32 HotWSpellId = 0; + + switch(GetModifier()->m_miscvalue) + { + case FORM_CAT: + spellId = 3025; + HotWSpellId = 24900; + break; + case FORM_TREE: + spellId = 5420; + break; + case FORM_TRAVEL: + spellId = 5419; + break; + case FORM_AQUA: + spellId = 5421; + break; + case FORM_BEAR: + spellId = 1178; + spellId2 = 21178; + HotWSpellId = 24899; + break; + case FORM_DIREBEAR: + spellId = 9635; + spellId2 = 21178; + HotWSpellId = 24899; + break; + case FORM_BATTLESTANCE: + spellId = 21156; + break; + case FORM_DEFENSIVESTANCE: + spellId = 7376; + break; + case FORM_BERSERKERSTANCE: + spellId = 7381; + break; + case FORM_MOONKIN: + spellId = 24905; + // aura from effect trigger spell + spellId2 = 24907; + break; + case FORM_FLIGHT: + spellId = 33948; + break; + case FORM_FLIGHT_EPIC: + spellId = 40122; + spellId2 = 40121; + break; + case FORM_SPIRITOFREDEMPTION: + spellId = 27792; + spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation. + break; + case FORM_GHOSTWOLF: + case FORM_AMBIENT: + case FORM_GHOUL: + case FORM_SHADOW: + case FORM_STEALTH: + case FORM_CREATURECAT: + case FORM_CREATUREBEAR: + spellId = 0; + break; + } + + uint32 form = GetModifier()->m_miscvalue-1; + + if(apply) + { + if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this ); + if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this); + + if(m_target->GetTypeId() == TYPEID_PLAYER) + { + const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + if(itr->second->state == PLAYERSPELL_REMOVED) continue; + if(itr->first==spellId || itr->first==spellId2) continue; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue; + if (spellInfo->Stances & (1<CastSpell(m_target, itr->first, true, NULL, this); + } + //LotP + if (((Player*)m_target)->HasSpell(17007)) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932); + if (spellInfo && spellInfo->Stances & (1<CastSpell(m_target, 24932, true, NULL, this); + } + // HotW + if (HotWSpellId) + { + Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE); + for(Unit::AuraList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i) + { + if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetModifier()->m_miscvalue == 3) + { + int32 HotWMod = (*i)->GetModifier()->m_amount; + if(GetModifier()->m_miscvalue == FORM_CAT) + HotWMod /= 2; + + m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this); + break; + } + } + } + } + } + else + { + m_target->RemoveAurasDueToSpell(spellId); + m_target->RemoveAurasDueToSpell(spellId2); + + Unit::AuraMap& tAuras = m_target->GetAuras(); + for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) + { + if (itr->second->IsRemovedOnShapeLost()) + { + m_target->RemoveAurasDueToSpell(itr->second->GetId()); + itr = tAuras.begin(); + } + else + { + ++itr; + } + } + } + + /*double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth(); + m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/ +} + +void Aura::HandleAuraEmpathy(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_UNIT) + return; + + CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry()); + if(ci && ci->type == CREATURE_TYPE_BEAST) + { + m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply); + } +} + +void Aura::HandleAuraUntrackable(bool apply, bool Real) +{ + if(apply) + m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE); + else + m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE); +} + +void Aura::HandleAuraModPacify(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + if(apply) + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + else + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); +} + +void Aura::HandleAuraModPacifyAndSilence(bool apply, bool Real) +{ + HandleAuraModPacify(apply,Real); + HandleAuraModSilence(apply,Real); +} + +void Aura::HandleAuraGhost(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + if(apply) + { + m_target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST); + } + else + { + m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST); + } +} + +void Aura::HandleAuraAllowFlight(bool apply, bool Real) +{ + // all applied/removed only at real aura add/remove + if(!Real) + return; + + // allow fly + WorldPacket data; + if(apply) + data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12); + else + data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12); + data.append(m_target->GetPackGUID()); + data << uint32(0); // unk + m_target->SendMessageToSet(&data, true); +} + +void Aura::HandleModRating(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) + if (m_modifier.m_miscvalue & (1 << rating)) + ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_modifier.m_amount, apply); +} + +void Aura::HandleForceMoveForward(bool apply, bool Real) +{ + if(!Real || m_target->GetTypeId() != TYPEID_PLAYER) + return; + if(apply) + m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + else + m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); +} + +void Aura::HandleAuraModExpertise(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)m_target)->UpdateExpertise(BASE_ATTACK); + ((Player*)m_target)->UpdateExpertise(OFF_ATTACK); +} + +void Aura::HandleModTargetResistance(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + // applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage + + // show armor penetration + if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)) + m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_modifier.m_amount, apply); + + // show as spell penetration only full spell penetration bonuses (all resistances except armor and holy + if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL) + m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_modifier.m_amount, apply); +} + +//HandleNoImmediateEffect auras implementation to support new stat system +void Aura::HandleAuraHealing(bool apply, bool Real) +{ + //m_target->HandleStatModifier(UNIT_MOD_HEALING, TOTAL_VALUE, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraHealingPct(bool apply, bool Real) +{ + //m_target->HandleStatModifier(UNIT_MOD_HEALING, TOTAL_PCT, float(m_modifier.m_amount), apply); +} + +void Aura::HandleShieldBlockValue(bool apply, bool Real) +{ + BaseModType modType = FLAT_MOD; + if(m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT) + modType = PCT_MOD; + + if(m_target->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_modifier.m_amount), apply); +} + +void Aura::HandleAuraRetainComboPoints(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + Player *target = (Player*)m_target; + + // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler + // remove only if aura expire by time (in case combo points amount change aura removed without combo points lost) + if( !apply && m_duration==0 && target->GetComboTarget()) + if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget())) + target->AddComboPoints(unit, -m_modifier.m_amount); +} + +void Aura::HandleModUnattackable( bool Apply, bool Real ) +{ + if(Real && Apply) + m_target->CombatStop(); + + m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply); +} + +void Aura::HandleSpiritOfRedemption( bool apply, bool Real ) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + // prepare spirit state + if(apply) + { + if(m_target->GetTypeId()==TYPEID_PLAYER) + { + // disable breath/etc timers + ((Player*)m_target)->StopMirrorTimers(); + + // set stand state (expected in this form) + if(!m_target->IsStandState()) + m_target->SetStandState(PLAYER_STATE_NONE); + } + + m_target->SetHealth(1); + } + // die at aura end + else + m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, GetSpellProto(), false); +} + +void Aura::CleanupTriggeredSpells() +{ + uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()]; + if(!tSpellId) + return; + + SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId); + if(!tProto) + return; + + if(GetSpellDuration(tProto) != -1) + return; + + // needed for spell 43680, maybe others + // TODO: is there a spell flag, which can solve this in a more sophisticated way? + if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL && + GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()]) + return; + m_target->RemoveAurasDueToSpell(tSpellId); +} + +void Aura::HandleAuraPowerBurn(bool apply, bool Real) +{ + if (m_periodicTimer <= 0) + m_periodicTimer += m_modifier.periodictime; + + m_isPeriodic = apply; +} + +void Aura::HandleSchoolAbsorb(bool apply, bool Real) +{ + if(!Real) + return; + + // prevent double apply bonuses + if(apply && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())) + { + if(Unit* caster = GetCaster()) + { + float DoneActualBenefit = 0.0f; + switch(m_spellProto->SpellFamilyName) + { + case SPELLFAMILY_PRIEST: + if(m_spellProto->SpellFamilyFlags == 0x1) //PW:S + { + //+30% from +healing bonus + DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f; + break; + } + break; + case SPELLFAMILY_MAGE: + if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL) + { + //frost ward, fire ward, ice barrier + //+10% from +spd bonus + DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f; + break; + } + break; + case SPELLFAMILY_WARLOCK: + if(m_spellProto->SpellFamilyFlags == 0x00) + { + //shadow ward + //+10% from +spd bonus + DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f; + break; + } + break; + default: + break; + } + + DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto()); + + m_modifier.m_amount += (int32)DoneActualBenefit; + } + } +} + +void Aura::PeriodicTick() +{ + if(!m_target->isAlive()) + return; + + switch(m_modifier.m_auraname) + { + case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: + { + Unit *pCaster = GetCaster(); + if(!pCaster) + return; + + if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA && + pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE) + return; + + // Check for immune (not use charges) + if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto()))) + return; + + // some auras remove at specific health level or more + if(m_modifier.m_auraname==SPELL_AURA_PERIODIC_DAMAGE) + { + switch(GetId()) + { + case 43093: case 31956: case 38801: + case 35321: case 38363: case 39215: + if(m_target->GetHealth() == m_target->GetMaxHealth() ) + { + m_target->RemoveAurasDueToSpell(GetId()); + return; + } + break; + case 38772: + { + uint32 percent = + GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_DUMMY ? + pCaster->CalculateSpellDamage(GetSpellProto(),GetEffIndex()+1,GetSpellProto()->EffectBasePoints[GetEffIndex()+1],m_target) : + 100; + if(m_target->GetHealth()*100 >= m_target->GetMaxHealth()*percent ) + { + m_target->RemoveAurasDueToSpell(GetId()); + return; + } + break; + } + default: + break; + } + } + + uint32 absorb=0; + uint32 resist=0; + CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); + + // ignore non positive values (can be result apply spellmods to aura damage + uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + uint32 pdamage; + + if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE) + { + pdamage = amount; + + // Calculate armor mitigation if it is a physical spell + // But not for bleed mechanic spells + if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL && + GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED) + { + uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage); + cleanDamage.damage += pdamage - pdamageReductedArmor; + pdamage = pdamageReductedArmor; + } + + pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT); + + // Curse of Agony damage-per-tick calculation + if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544) + { + // 1..4 ticks, 1/2 from normal tick damage + if (m_duration>=((m_maxduration-m_modifier.periodictime)*2/3)) + pdamage = pdamage/2; + // 9..12 ticks, 3/2 from normal tick damage + else if(m_duration<((m_maxduration-m_modifier.periodictime)/3)) + pdamage += (pdamage+1)/2; // +1 prevent 0.5 damage possible lost at 1..4 ticks + // 5..8 ticks have normal tick damage + } + } + else + pdamage = uint32(m_target->GetMaxHealth()*amount/100); + + //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit + // Reduce dot damage from resilience for players + if (m_target->GetTypeId()==TYPEID_PLAYER) + pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage); + + pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist); + + sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u", + GetCasterGUID(), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb); + + WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size + data.append(m_target->GetPackGUID()); + data.appendPackGUID(GetCasterGUID()); + data << uint32(GetId()); + data << uint32(1); + data << uint32(m_modifier.m_auraname); + data << (uint32)pdamage; + data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x + data << (uint32)absorb; + data << (uint32)resist; + m_target->SendMessageToSet(&data,true); + + Unit* target = m_target; // aura can be deleted in DealDamage + SpellEntry const* spellProto = GetSpellProto(); + + pCaster->DealDamage(m_target, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true); + + // DO NOT ACCESS MEMBERS OF THE AURA FROM NOW ON (DealDamage can delete aura) + + pCaster->ProcDamageAndSpell(target, PROC_FLAG_HIT_SPELL, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), GetSpellSchoolMask(spellProto), spellProto); + break; + } + case SPELL_AURA_PERIODIC_LEECH: + { + Unit *pCaster = GetCaster(); + if(!pCaster) + return; + + if(!pCaster->isAlive()) + return; + + if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA && + pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE) + return; + + // Check for immune (not use charges) + if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto()))) + return; + + uint32 absorb=0; + uint32 resist=0; + CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); + + uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + //Calculate armor mitigation if it is a physical spell + if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL) + { + uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage); + cleanDamage.damage += pdamage - pdamageReductedArmor; + pdamage = pdamageReductedArmor; + } + + pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT); + + // talent Soul Siphon add bonus to Drain Life spells + if( GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x8) ) + { + // find talent max bonus percentage + Unit::AuraList const& mClassScriptAuras = pCaster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator i = mClassScriptAuras.begin(); i != mClassScriptAuras.end(); ++i) + { + if ((*i)->GetModifier()->m_miscvalue == 4992 || (*i)->GetModifier()->m_miscvalue == 4993) + { + if((*i)->GetEffIndex()!=1) + { + sLog.outError("Expected spell %u structure change, need code update",(*i)->GetId()); + break; + } + + // effect 1 m_amount + int32 maxPercent = (*i)->GetModifier()->m_amount; + // effect 0 m_amount + int32 stepPercent = pCaster->CalculateSpellDamage((*i)->GetSpellProto(),0,(*i)->GetSpellProto()->EffectBasePoints[0],pCaster); + + // count affliction effects and calc additional damage in percentage + int32 modPercent = 0; + Unit::AuraMap const& victimAuras = m_target->GetAuras(); + for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) + { + Aura* aura = itr->second; + if (aura->IsPositive())continue; + SpellEntry const* m_spell = aura->GetSpellProto(); + if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK) + continue; + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(m_spell->Id); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(m_spell->Id); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + if(_spell_idx->second->skillId == SKILL_AFFLICTION) + { + modPercent += stepPercent; + if (modPercent >= maxPercent) + { + modPercent = maxPercent; + break; + } + } + } + } + pdamage += (pdamage*modPercent/100); + break; + } + } + } + + //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit + // Reduce dot damage from resilience for players + if (m_target->GetTypeId()==TYPEID_PLAYER) + pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage); + + pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist); + + if(m_target->GetHealth() < pdamage) + pdamage = uint32(m_target->GetHealth()); + + sLog.outDetail("PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u", + GetCasterGUID(), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb); + + pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0); + + + Unit* target = m_target; // aura can be deleted in DealDamage + SpellEntry const* spellProto = GetSpellProto(); + float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1; + + uint32 new_damage = pCaster->DealDamage(m_target, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false); + + // DO NOT ACCESS MEMBERS OF THE AURA FROM NOW ON (DealDamage can delete aura) + + pCaster->ProcDamageAndSpell(target, PROC_FLAG_HIT_SPELL, PROC_FLAG_TAKE_DAMAGE, new_damage, GetSpellSchoolMask(spellProto), spellProto); + if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false)) + { + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + { + if (pCaster->m_currentSpells[i] && pCaster->m_currentSpells[i]->m_spellInfo->Id == spellProto->Id) + pCaster->m_currentSpells[i]->cancel(); + } + } + + + if(Player *modOwner = pCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); + + uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster); + + int32 gain = pCaster->ModifyHealth(heal); + pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto); + + pCaster->SendHealSpellLog(pCaster, spellProto->Id, heal); + break; + } + case SPELL_AURA_PERIODIC_HEAL: + case SPELL_AURA_OBS_MOD_HEALTH: + { + Unit *pCaster = GetCaster(); + if(!pCaster) + return; + + // heal for caster damage (must be alive) + if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive()) + return; + + // ignore non positive values (can be result apply spellmods to aura damage + uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + uint32 pdamage; + + if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH) + pdamage = uint32(m_target->GetMaxHealth() * amount/100); + else + pdamage = amount; + + pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target); + + sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u", + GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); + + WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size + data.append(m_target->GetPackGUID()); + data.appendPackGUID(GetCasterGUID()); + data << uint32(GetId()); + data << uint32(1); + data << uint32(m_modifier.m_auraname); + data << (uint32)pdamage; + m_target->SendMessageToSet(&data,true); + + int32 gain = m_target->ModifyHealth(pdamage); + + // add HoTs to amount healed in bgs + if( pCaster->GetTypeId() == TYPEID_PLAYER ) + if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() ) + bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain); + + //Do check before because m_modifier.auraName can be invalidate by DealDamage. + bool procSpell = (m_modifier.m_auraname == SPELL_AURA_PERIODIC_HEAL && m_target != pCaster); + + m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto()); + + Unit* target = m_target; // aura can be deleted in DealDamage + SpellEntry const* spellProto = GetSpellProto(); + bool haveCastItem = GetCastItemGUID()!=0; + + // heal for caster damage + if(m_target!=pCaster && spellProto->SpellVisual==163) + { + uint32 dmg = spellProto->manaPerSecond; + if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER) + { + pCaster->RemoveAurasDueToSpell(GetId()); + + // finish current generic/channeling spells, don't affect autorepeat + if(pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]) + { + pCaster->m_currentSpells[CURRENT_GENERIC_SPELL]->finish(); + } + if(pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]) + { + pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); + pCaster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); + } + } + else + { + pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false); + + CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); + pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true); + } + } + + // ignore item heals + if(procSpell && !haveCastItem) + pCaster->ProcDamageAndSpell(target,PROC_FLAG_HEAL, PROC_FLAG_HEALED, pdamage, SPELL_SCHOOL_MASK_NONE, spellProto); + break; + } + case SPELL_AURA_PERIODIC_MANA_LEECH: + { + Unit *pCaster = GetCaster(); + if(!pCaster) + return; + + if(!pCaster->isAlive()) + return; + + if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA && + pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE) + return; + + // Check for immune (not use charges) + if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto()))) + return; + + // ignore non positive values (can be result apply spellmods to aura damage + uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u", + GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); + + if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4) + break; + + Powers power = Powers(m_modifier.m_miscvalue); + + // power type might have changed between aura applying and tick (druid's shapeshift) + if(m_target->getPowerType() != power) + break; + + int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power); + + // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) + if (power == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER) + drain_amount -= ((Player*)m_target)->GetSpellCritDamageReduction(drain_amount); + + m_target->ModifyPower(power, -drain_amount); + + float gain_multiplier = 0; + + if(pCaster->GetMaxPower(power) > 0) + { + gain_multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()]; + + if(Player *modOwner = pCaster->GetSpellModOwner()) + modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier); + } + + WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size + data.append(m_target->GetPackGUID()); + data.appendPackGUID(GetCasterGUID()); + data << uint32(GetId()); + data << uint32(1); + data << uint32(m_modifier.m_auraname); + data << (uint32)power; // power type + data << (uint32)drain_amount; + data << (float)gain_multiplier; + m_target->SendMessageToSet(&data,true); + + int32 gain_amount = int32(drain_amount*gain_multiplier); + + if(gain_amount) + { + int32 gain = pCaster->ModifyPower(power,gain_amount); + m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto()); + } + break; + } + case SPELL_AURA_PERIODIC_ENERGIZE: + { + // ignore non positive values (can be result apply spellmods to aura damage + uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u", + GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); + + if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4) + break; + + Powers power = Powers(m_modifier.m_miscvalue); + + if(m_target->GetMaxPower(power) == 0) + break; + + WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size + data.append(m_target->GetPackGUID()); + data.appendPackGUID(GetCasterGUID()); + data << uint32(GetId()); + data << uint32(1); + data << uint32(m_modifier.m_auraname); + data << (uint32)power; // power type + data << (uint32)pdamage; + m_target->SendMessageToSet(&data,true); + + int32 gain = m_target->ModifyPower(power,pdamage); + + if(Unit* pCaster = GetCaster()) + m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto()); + break; + } + case SPELL_AURA_OBS_MOD_MANA: + { + // ignore non positive values (can be result apply spellmods to aura damage + uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100); + + sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u mana inflicted by %u", + GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); + + if(m_target->GetMaxPower(POWER_MANA) == 0) + break; + + WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size + data.append(m_target->GetPackGUID()); + data.appendPackGUID(GetCasterGUID()); + data << uint32(GetId()); + data << uint32(1); + data << uint32(m_modifier.m_auraname); + data << (uint32)0; // ? + data << (uint32)pdamage; + m_target->SendMessageToSet(&data,true); + + int32 gain = m_target->ModifyPower(POWER_MANA, pdamage); + + if(Unit* pCaster = GetCaster()) + m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto()); + break; + } + case SPELL_AURA_POWER_BURN_MANA: + { + Unit *pCaster = GetCaster(); + if(!pCaster) + return; + + // Check for immune (not use charges) + if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto()))) + return; + + int32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; + + Powers powerType = Powers(m_modifier.m_miscvalue); + + if(!m_target->isAlive() || m_target->getPowerType() != powerType) + return; + + // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) + if (powerType == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER) + pdamage -= ((Player*)m_target)->GetSpellCritDamageReduction(pdamage); + + uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage)); + + gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]); + + //maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG + pCaster->SpellNonMeleeDamageLog(m_target, GetId(), gain); + break; + } + // Here tick dummy auras + case SPELL_AURA_PERIODIC_DUMMY: + { + PeriodicDummyTick(); + break; + } + default: + break; + } +} + +void Aura::PeriodicDummyTick() +{ + SpellEntry const* spell = GetSpellProto(); + switch (spell->Id) + { + // Drink + case 430: + case 431: + case 432: + case 1133: + case 1135: + case 1137: + case 10250: + case 22734: + case 27089: + case 34291: + case 43706: + case 46755: + { + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus + Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN); + for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i) + { + if ((*i)->GetId() == GetId()) + { + // Get tick number + int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime; + // Default case (not on arenas) + if (tick == 0) + { + (*i)->GetModifier()->m_amount = m_modifier.m_amount; + ((Player*)m_target)->UpdateManaRegen(); + // Disable continue + m_isPeriodic = false; + } + return; + //********************************************** + // Code commended since arena patch not added + // This feature uses only in arenas + //********************************************** + // Here need increase mana regen per tick (6 second rule) + // on 0 tick - 0 (handled in 2 second) + // on 1 tick - 166% (handled in 4 second) + // on 2 tick - 133% (handled in 6 second) + // Not need update after 3 tick + /* + if (tick > 3) + return; + // Apply bonus for 0 - 3 tick + switch (tick) + { + case 0: // 0% + (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0; + break; + case 1: // 166% + (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3; + break; + case 2: // 133% + (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3; + break; + default: // 100% - normal regen + (*i)->GetModifier()->m_amount = m_modifier.m_amount; + break; + } + ((Player*)m_target)->UpdateManaRegen(); + return;*/ + } + } + return; + } +// // Panda +// case 19230: break; +// // Master of Subtlety +// case 31666: break; +// // Gossip NPC Periodic - Talk +// case 33208: break; +// // Gossip NPC Periodic - Despawn +// case 33209: break; +// // Force of Nature +// case 33831: break; + // Aspect of the Viper + case 34074: + { + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + // Should be manauser + if (m_target->getPowerType()!=POWER_MANA) + return; + Unit *caster = GetCaster(); + if (!caster) + return; + // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell) + int mana = m_target->GetPower(POWER_MANA); + int max_mana = m_target->GetMaxPower(POWER_MANA); + int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target); + float regen_pct = 1.20f - 1.1f * mana / max_mana; + if (regen_pct > 1.0f) regen_pct = 1.0f; + else if (regen_pct < 0.2f) regen_pct = 0.2f; + m_modifier.m_amount = int32 (base_regen * regen_pct); + ((Player*)m_target)->UpdateManaRegen(); + return; + } +// // Steal Weapon +// case 36207: break; +// // Simon Game START timer, (DND) +// case 39993: break; +// // Harpooner's Mark +// case 40084: break; +// // Knockdown Fel Cannon: break; The Aggro Burst +// case 40119: break; +// // Old Mount Spell +// case 40154: break; +// // Magnetic Pull +// case 40581: break; +// // Ethereal Ring: break; The Bolt Burst +// case 40801: break; +// // Crystal Prison +// case 40846: break; +// // Copy Weapon +// case 41054: break; +// // Ethereal Ring Visual, Lightning Aura +// case 41477: break; +// // Ethereal Ring Visual, Lightning Aura (Fork) +// case 41525: break; +// // Ethereal Ring Visual, Lightning Jumper Aura +// case 41567: break; +// // No Man's Land +// case 41955: break; +// // Headless Horseman - Fire +// case 42074: break; +// // Headless Horseman - Visual - Large Fire +// case 42075: break; +// // Headless Horseman - Start Fire, Periodic Aura +// case 42140: break; +// // Ram Speed Boost +// case 42152: break; +// // Headless Horseman - Fires Out Victory Aura +// case 42235: break; +// // Pumpkin Life Cycle +// case 42280: break; +// // Brewfest Request Chick Chuck Mug Aura +// case 42537: break; +// // Squashling +// case 42596: break; +// // Headless Horseman Climax, Head: Periodic +// case 42603: break; +// // Fire Bomb +// case 42621: break; +// // Headless Horseman - Conflagrate, Periodic Aura +// case 42637: break; +// // Headless Horseman - Create Pumpkin Treats Aura +// case 42774: break; +// // Headless Horseman Climax - Summoning Rhyme Aura +// case 42879: break; +// // Tricky Treat +// case 42919: break; +// // Giddyup! +// case 42924: break; +// // Ram - Trot +// case 42992: break; +// // Ram - Canter +// case 42993: break; +// // Ram - Gallop +// case 42994: break; +// // Ram Level - Neutral +// case 43310: break; +// // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17 +// case 43884: break; +// // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17 +// case 44000: break; +// // Energy Feedback +// case 44328: break; +// // Romantic Picnic +// case 45102: break; +// // Romantic Picnic +// case 45123: break; +// // Looking for Love +// case 45124: break; +// // Kite - Lightning Strike Kite Aura +// case 45197: break; +// // Rocket Chicken +// case 45202: break; +// // Copy Offhand Weapon +// case 45205: break; +// // Upper Deck - Kite - Lightning Periodic Aura +// case 45207: break; +// // Kite -Sky Lightning Strike Kite Aura +// case 45251: break; +// // Ribbon Pole Dancer Check Aura +// case 45390: break; +// // Holiday - Midsummer, Ribbon Pole Periodic Visual +// case 45406: break; +// // Parachute +// case 45472: break; +// // Alliance Flag, Extra Damage Debuff +// case 45898: break; +// // Horde Flag, Extra Damage Debuff +// case 45899: break; +// // Ahune - Summoning Rhyme Aura +// case 45926: break; +// // Ahune - Slippery Floor +// case 45945: break; +// // Ahune's Shield +// case 45954: break; +// // Nether Vapor Lightning +// case 45960: break; +// // Darkness +// case 45996: break; +// // Summon Blood Elves Periodic +// case 46041: break; +// // Transform Visual Missile Periodic +// case 46205: break; +// // Find Opening Beam End +// case 46333: break; +// // Ice Spear Control Aura +// case 46371: break; +// // Hailstone Chill +// case 46458: break; +// // Hailstone Chill, Internal +// case 46465: break; +// // Chill, Internal Shifter +// case 46549: break; +// // Summon Ice Spear Knockback Delayer +// case 46878: break; +// // Burninate Effect +// case 47214: break; +// // Fizzcrank Practice Parachute +// case 47228: break; +// // Send Mug Control Aura +// case 47369: break; +// // Direbrew's Disarm (precast) +// case 47407: break; +// // Mole Machine Port Schedule +// case 47489: break; +// // Mole Machine Portal Schedule +// case 49466: break; +// // Drink Coffee +// case 49472: break; +// // Listening to Music +// case 50493: break; +// // Love Rocket Barrage +// case 50530: break; + default: + break; + } +} + +void Aura::HandlePreventFleeing(bool apply, bool Real) +{ + if(!Real) + return; + + Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR); + if( !fearAuras.empty() ) + { + if (apply) + m_target->SetFeared(false, fearAuras.front()->GetCasterGUID()); + else + m_target->SetFeared(true); + } +} + +void Aura::HandleManaShield(bool apply, bool Real) +{ + if(!Real) + return; + + // prevent double apply bonuses + if(apply && (m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())) + { + if(Unit* caster = GetCaster()) + { + float DoneActualBenefit = 0.0f; + switch(m_spellProto->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + if(m_spellProto->SpellFamilyFlags & 0x8000) + { + // Mana Shield + // +50% from +spd bonus + DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.5f; + break; + } + break; + default: + break; + } + + DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto()); + + m_modifier.m_amount += (int32)DoneActualBenefit; + } + } +} + +void Aura::HandleArenaPreparation(bool apply, bool Real) +{ + if(!Real) + return; + + if(apply) + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION); + else + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION); +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h new file mode 100644 index 000000000..295981a2a --- /dev/null +++ b/src/game/SpellAuras.h @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef MANGOS_SPELLAURAS_H +#define MANGOS_SPELLAURAS_H + +#include "SpellAuraDefines.h" + +struct DamageManaShield +{ + uint32 m_spellId; + uint32 m_modType; + int32 m_schoolType; + uint32 m_totalAbsorb; + uint32 m_currAbsorb; +}; + +struct Modifier +{ + AuraType m_auraname; + int32 m_amount; + int32 m_miscvalue; + uint32 periodictime; +}; + +class Unit; +struct SpellEntry; +struct SpellModifier; +struct ProcTriggerSpell; + +// forward decl +class Aura; + +typedef void(Aura::*pAuraHandler)(bool Apply, bool Real); +// Real == true at aura add/remove +// Real == false at aura mod unapply/reapply; when adding/removing dependent aura/item/stat mods +// +// Code in aura handler can be guarded by if(Real) check if it should execution only at real add/remove of aura +// +// MAIN RULE: Code MUST NOT be guarded by if(Real) check if it modifies any stats +// (percent auras, stats mods, etc) +// Second rule: Code must be guarded by if(Real) check if it modifies object state (start/stop attack, send packets to client, etc) +// +// Other case choice: each code line moved under if(Real) check is mangos speedup, +// each setting object update field code line moved under if(Real) check is significant mangos speedup, and less server->client data sends +// each packet sending code moved under if(Real) check is _large_ mangos speedup, and lot less server->client data sends + +class MANGOS_DLL_SPEC Aura +{ + friend Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem); + + public: + //aura handlers + void HandleNULL(bool, bool) + { + // NOT IMPLEMENTED + } + void HandleUnused(bool, bool) + { + // NOT USED BY ANY SPELL OR USELESS + } + void HandleNoImmediateEffect(bool, bool) + { + // aura not have immediate effect at add/remove and handled by ID in other code place + } + void HandleBindSight(bool Apply, bool Real); + void HandleModPossess(bool Apply, bool Real); + void HandlePeriodicDamage(bool Apply, bool Real); + void HandleAuraDummy(bool Apply, bool Real); + void HandleAuraPeriodicDummy(bool apply, bool Real); + void HandleModConfuse(bool Apply, bool Real); + void HandleModCharm(bool Apply, bool Real); + void HandleModFear(bool Apply, bool Real); + void HandlePeriodicHeal(bool Apply, bool Real); + void HandleModAttackSpeed(bool Apply, bool Real); + void HandleModMeleeRangedSpeedPct(bool apply, bool Real); + void HandleModCombatSpeedPct(bool apply, bool Real); + void HandleModThreat(bool Apply, bool Real); + void HandleModTaunt(bool Apply, bool Real); + void HandleFeignDeath(bool Apply, bool Real); + void HandleAuraModDisarm(bool Apply, bool Real); + void HandleAuraModStalked(bool Apply, bool Real); + void HandleAuraWaterWalk(bool Apply, bool Real); + void HandleAuraFeatherFall(bool Apply, bool Real); + void HandleAuraHover(bool Apply, bool Real); + void HandleAddModifier(bool Apply, bool Real); + void HandleAuraModStun(bool Apply, bool Real); + void HandleModDamageDone(bool Apply, bool Real); + void HandleAuraUntrackable(bool Apply, bool Real); + void HandleAuraEmpathy(bool Apply, bool Real); + void HandleModOffhandDamagePercent(bool apply, bool Real); + void HandleAuraModRangedAttackPower(bool Apply, bool Real); + void HandleAuraModIncreaseEnergyPercent(bool Apply, bool Real); + void HandleAuraModIncreaseHealthPercent(bool Apply, bool Real); + void HandleAuraModRegenInterrupt(bool Apply, bool Real); + void HandleHaste(bool Apply, bool Real); + void HandlePeriodicTriggerSpell(bool Apply, bool Real); + void HandlePeriodicEnergize(bool Apply, bool Real); + void HandleAuraModResistanceExclusive(bool Apply, bool Real); + void HandleModStealth(bool Apply, bool Real); + void HandleInvisibility(bool Apply, bool Real); + void HandleInvisibilityDetect(bool Apply, bool Real); + void HandleAuraModTotalHealthPercentRegen(bool Apply, bool Real); + void HandleAuraModTotalManaPercentRegen(bool Apply, bool Real); + void HandleAuraModResistance(bool Apply, bool Real); + void HandleAuraModRoot(bool Apply, bool Real); + void HandleAuraModSilence(bool Apply, bool Real); + void HandleAuraModStat(bool Apply, bool Real); + void HandleAuraModIncreaseSpeed(bool Apply, bool Real); + void HandleAuraModIncreaseMountedSpeed(bool Apply, bool Real); + void HandleAuraModIncreaseFlightSpeed(bool Apply, bool Real); + void HandleAuraModDecreaseSpeed(bool Apply, bool Real); + void HandleAuraModUseNormalSpeed(bool Apply, bool Real); + void HandleAuraModIncreaseHealth(bool Apply, bool Real); + void HandleAuraModIncreaseEnergy(bool Apply, bool Real); + void HandleAuraModShapeshift(bool Apply, bool Real); + void HandleAuraModEffectImmunity(bool Apply, bool Real); + void HandleAuraModStateImmunity(bool Apply, bool Real); + void HandleAuraModSchoolImmunity(bool Apply, bool Real); + void HandleAuraModDmgImmunity(bool Apply, bool Real); + void HandleAuraModDispelImmunity(bool Apply, bool Real); + void HandleAuraProcTriggerSpell(bool Apply, bool Real); + void HandleAuraTrackCreatures(bool Apply, bool Real); + void HandleAuraTrackResources(bool Apply, bool Real); + void HandleAuraModParryPercent(bool Apply, bool Real); + void HandleAuraModDodgePercent(bool Apply, bool Real); + void HandleAuraModBlockPercent(bool Apply, bool Real); + void HandleAuraModCritPercent(bool Apply, bool Real); + void HandlePeriodicLeech(bool Apply, bool Real); + void HandleModHitChance(bool Apply, bool Real); + void HandleModSpellHitChance(bool Apply, bool Real); + void HandleAuraModScale(bool Apply, bool Real); + void HandlePeriodicManaLeech(bool Apply, bool Real); + void HandleModCastingSpeed(bool Apply, bool Real); + void HandleAuraMounted(bool Apply, bool Real); + void HandleWaterBreathing(bool Apply, bool Real); + void HandleModBaseResistance(bool Apply, bool Real); + void HandleModRegen(bool Apply, bool Real); + void HandleModPowerRegen(bool Apply, bool Real); + void HandleModPowerRegenPCT(bool Apply, bool Real); + void HandleChannelDeathItem(bool Apply, bool Real); + void HandlePeriodicDamagePCT(bool Apply, bool Real); + void HandleAuraModAttackPower(bool Apply, bool Real); + void HandleAuraTransform(bool Apply, bool Real); + void HandleModSpellCritChance(bool Apply, bool Real); + void HandleAuraModIncreaseSwimSpeed(bool Apply, bool Real); + void HandleModPowerCostPCT(bool Apply, bool Real); + void HandleModPowerCost(bool Apply, bool Real); + void HandleFarSight(bool Apply, bool Real); + void HandleModPossessPet(bool Apply, bool Real); + void HandleModMechanicImmunity(bool Apply, bool Real); + void HandleAuraModSkill(bool Apply, bool Real); + void HandleModDamagePercentDone(bool Apply, bool Real); + void HandleModPercentStat(bool Apply, bool Real); + void HandleModResistancePercent(bool Apply, bool Real); + void HandleAuraModBaseResistancePCT(bool Apply, bool Real); + void HandleModShieldBlockPCT(bool Apply, bool Real); + void HandleAuraTrackStealthed(bool Apply, bool Real); + void HandleModShieldBlock(bool Apply, bool Real); + void HandleForceReaction(bool Apply, bool Real); + void HandleAuraModRangedHaste(bool Apply, bool Real); + void HandleRangedAmmoHaste(bool Apply, bool Real); + void HandleModHealingDone(bool Apply, bool Real); + void HandleModTotalPercentStat(bool Apply, bool Real); + void HandleAuraModTotalThreat(bool Apply, bool Real); + void HandleModUnattackable(bool Apply, bool Real); + void HandleAuraModPacify(bool Apply, bool Real); + void HandleAuraGhost(bool Apply, bool Real); + void HandleAuraAllowFlight(bool Apply, bool Real); + void HandleModRating(bool apply, bool Real); + void HandleModTargetResistance(bool apply, bool Real); + void HandleAuraAttackPowerAttacker(bool apply, bool Real); + void HandleAuraModAttackPowerPercent(bool apply, bool Real); + void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real); + void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real); + void HandleSpiritOfRedemption(bool apply, bool Real); + void HandleAuraHealingPct(bool apply, bool Real); + void HandleModManaRegen(bool apply, bool Real); + void HandleComprehendLanguage(bool apply, bool Real); + void HandleAuraHealing(bool apply, bool Real); + void HandleShieldBlockValue(bool apply, bool Real); + void HandleModSpellCritChanceShool(bool apply, bool Real); + void HandleAuraRetainComboPoints(bool apply, bool Real); + void HandleModSpellDamagePercentFromStat(bool apply, bool Real); + void HandleModSpellHealingPercentFromStat(bool apply, bool Real); + void HandleAuraModDispelResist(bool apply, bool Real); + void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real); + void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real); + void HandleAuraModPacifyAndSilence(bool Apply, bool Real); + void HandleAuraModIncreaseMaxHealth(bool apply, bool Real); + void HandleAuraModExpertise(bool apply, bool Real); + void HandleForceMoveForward(bool apply, bool Real); + void HandleAuraModResistenceOfStatPercent(bool apply, bool Real); + void HandleAuraPowerBurn(bool apply, bool Real); + void HandleSchoolAbsorb(bool apply, bool Real); + void HandlePreventFleeing(bool apply, bool Real); + void HandleManaShield(bool apply, bool Real); + void HandleArenaPreparation(bool apply, bool Real); + + virtual ~Aura(); + + void SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue); + Modifier* GetModifier() {return &m_modifier;} + int32 GetMiscValue() {return m_spellProto->EffectMiscValue[m_effIndex];} + int32 GetMiscBValue() {return m_spellProto->EffectMiscValueB[m_effIndex];} + + SpellEntry const* GetSpellProto() const { return m_spellProto; } + uint32 GetId() const{ return m_spellProto->Id; } + uint64 GetCastItemGUID() const { return m_castItemGuid; } + uint32 GetEffIndex() const{ return m_effIndex; } + int32 GetBasePoints() const { return m_currentBasePoints; } + + int32 GetAuraMaxDuration() const { return m_maxduration; } + void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; } + int32 GetAuraDuration() const { return m_duration; } + void SetAuraDuration(int32 duration) { m_duration = duration; } + time_t GetAuraApplyTime() { return m_applyTime; } + void UpdateAuraDuration(); + void SendAuraDurationForCaster(Player* caster); + + uint64 const& GetCasterGUID() const { return m_caster_guid; } + Unit* GetCaster() const; + Unit* GetTarget() const { return m_target; } + void SetTarget(Unit* target) { m_target = target; } + void SetLoadedState(uint64 caster_guid,int32 damage,int32 maxduration,int32 duration,int32 charges) + { + m_caster_guid = caster_guid; + m_modifier.m_amount = damage; + m_maxduration = maxduration; + m_duration = duration; + m_procCharges = charges; + } + + uint8 GetAuraSlot() const { return m_auraSlot; } + void SetAuraSlot(uint8 slot) { m_auraSlot = slot; } + void UpdateAuraCharges() + { + uint8 slot = GetAuraSlot(); + + // only aura in slot with charges and without stack limitation + if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0) + SetAuraApplication(slot, m_procCharges - 1); + } + + bool IsPositive() { return m_positive; } + void SetNegative() { m_positive = false; } + void SetPositive() { m_positive = true; } + + bool IsPermanent() const { return m_permanent; } + bool IsAreaAura() const { return m_isAreaAura; } + bool IsPeriodic() const { return m_isPeriodic; } + bool IsTrigger() const { return m_isTrigger; } + bool IsPassive() const { return m_isPassive; } + bool IsPersistent() const { return m_isPersistent; } + bool IsDeathPersistent() const { return m_isDeathPersist; } + bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; } + bool IsInUse() const { return m_in_use;} + + virtual void Update(uint32 diff); + void ApplyModifier(bool apply, bool Real = false); + + void _AddAura(); + void _RemoveAura(); + + void TriggerSpell(); + + bool IsUpdated() { return m_updated; } + void SetUpdated(bool val) { m_updated = val; } + void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; } + + int32 m_procCharges; + + virtual Unit* GetTriggerTarget() const { return m_target; } + + // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras + void HandleShapeshiftBoosts(bool apply); + + // Allow Apply Aura Handler to modify and access m_AuraDRGroup + void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; } + DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; } + + void PeriodicTick(); + void PeriodicDummyTick(); + protected: + Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + + Modifier m_modifier; + SpellModifier *m_spellmod; + uint32 m_effIndex; + SpellEntry const *m_spellProto; + int32 m_currentBasePoints; // cache SpellEntry::EffectBasePoints and use for set custom base points + uint64 m_caster_guid; + Unit* m_target; + int32 m_maxduration; + int32 m_duration; + int32 m_timeCla; + uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted + time_t m_applyTime; + + AuraRemoveMode m_removeMode; + + uint8 m_auraSlot; + + bool m_positive:1; + bool m_permanent:1; + bool m_isPeriodic:1; + bool m_isTrigger:1; + bool m_isAreaAura:1; + bool m_isPassive:1; + bool m_isPersistent:1; + bool m_isDeathPersist:1; + bool m_isRemovedOnShapeLost:1; + bool m_updated:1; + bool m_in_use:1; // true while in Aura::ApplyModifier call + + int32 m_periodicTimer; + uint32 m_PeriodicEventId; + DiminishingGroup m_AuraDRGroup; + private: + void UpdateSlotCounterAndDuration(bool add); + void CleanupTriggeredSpells(); + void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); } + void SetAuraFlag(uint32 slot, bool add); + void SetAuraLevel(uint32 slot, uint32 level); + void SetAuraApplication(uint32 slot, int8 count); +}; + +class MANGOS_DLL_SPEC AreaAura : public Aura +{ + public: + AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + ~AreaAura(); + void Update(uint32 diff); + private: + float m_radius; + AreaAuraType m_areaAuraType; +}; + +class MANGOS_DLL_SPEC PersistentAreaAura : public Aura +{ + public: + PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + ~PersistentAreaAura(); + void Update(uint32 diff); +}; + +class MANGOS_DLL_SPEC SingleEnemyTargetAura : public Aura +{ + friend Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem); + + public: + ~SingleEnemyTargetAura(); + Unit* GetTriggerTarget() const; + + protected: + SingleEnemyTargetAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + uint64 m_casters_target_guid; +}; + +Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); +#endif diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp new file mode 100644 index 000000000..4f702da94 --- /dev/null +++ b/src/game/SpellEffects.cpp @@ -0,0 +1,6186 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "SharedDefines.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "UpdateMask.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Player.h" +#include "SkillExtraItems.h" +#include "Unit.h" +#include "CreatureAI.h" +#include "Spell.h" +#include "DynamicObject.h" +#include "SpellAuras.h" +#include "Group.h" +#include "UpdateData.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "SharedDefines.h" +#include "Pet.h" +#include "GameObject.h" +#include "GossipDef.h" +#include "Creature.h" +#include "Totem.h" +#include "CreatureAI.h" +#include "BattleGround.h" +#include "BattleGroundEY.h" +#include "BattleGroundWS.h" +#include "VMapFactory.h" +#include "Language.h" +#include "SocialMgr.h" +#include "Util.h" +#include "TemporarySummon.h" + +pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= +{ + &Spell::EffectNULL, // 0 + &Spell::EffectInstaKill, // 1 SPELL_EFFECT_INSTAKILL + &Spell::EffectSchoolDMG, // 2 SPELL_EFFECT_SCHOOL_DAMAGE + &Spell::EffectDummy, // 3 SPELL_EFFECT_DUMMY + &Spell::EffectUnused, // 4 SPELL_EFFECT_PORTAL_TELEPORT unused + &Spell::EffectTeleportUnits, // 5 SPELL_EFFECT_TELEPORT_UNITS + &Spell::EffectApplyAura, // 6 SPELL_EFFECT_APPLY_AURA + &Spell::EffectEnvirinmentalDMG, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE + &Spell::EffectPowerDrain, // 8 SPELL_EFFECT_POWER_DRAIN + &Spell::EffectHealthLeech, // 9 SPELL_EFFECT_HEALTH_LEECH + &Spell::EffectHeal, // 10 SPELL_EFFECT_HEAL + &Spell::EffectUnused, // 11 SPELL_EFFECT_BIND + &Spell::EffectNULL, // 12 SPELL_EFFECT_PORTAL + &Spell::EffectUnused, // 13 SPELL_EFFECT_RITUAL_BASE unused + &Spell::EffectUnused, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE unused + &Spell::EffectUnused, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL unused + &Spell::EffectQuestComplete, // 16 SPELL_EFFECT_QUEST_COMPLETE + &Spell::EffectWeaponDmg, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL + &Spell::EffectResurrect, // 18 SPELL_EFFECT_RESURRECT + &Spell::EffectAddExtraAttacks, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS + &Spell::EffectUnused, // 20 SPELL_EFFECT_DODGE one spell: Dodge + &Spell::EffectUnused, // 21 SPELL_EFFECT_EVADE one spell: Evade (DND) + &Spell::EffectParry, // 22 SPELL_EFFECT_PARRY + &Spell::EffectBlock, // 23 SPELL_EFFECT_BLOCK one spell: Block + &Spell::EffectCreateItem, // 24 SPELL_EFFECT_CREATE_ITEM + &Spell::EffectUnused, // 25 SPELL_EFFECT_WEAPON + &Spell::EffectUnused, // 26 SPELL_EFFECT_DEFENSE one spell: Defense + &Spell::EffectPersistentAA, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA + &Spell::EffectSummonType, // 28 SPELL_EFFECT_SUMMON + &Spell::EffectMomentMove, // 29 SPELL_EFFECT_LEAP + &Spell::EffectEnergize, // 30 SPELL_EFFECT_ENERGIZE + &Spell::EffectWeaponDmg, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE + &Spell::EffectTriggerMissileSpell, // 32 SPELL_EFFECT_TRIGGER_MISSILE + &Spell::EffectOpenLock, // 33 SPELL_EFFECT_OPEN_LOCK + &Spell::EffectSummonChangeItem, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM + &Spell::EffectApplyAreaAura, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY + &Spell::EffectLearnSpell, // 36 SPELL_EFFECT_LEARN_SPELL + &Spell::EffectUnused, // 37 SPELL_EFFECT_SPELL_DEFENSE one spell: SPELLDEFENSE (DND) + &Spell::EffectDispel, // 38 SPELL_EFFECT_DISPEL + &Spell::EffectUnused, // 39 SPELL_EFFECT_LANGUAGE + &Spell::EffectDualWield, // 40 SPELL_EFFECT_DUAL_WIELD + &Spell::EffectSummonWild, // 41 SPELL_EFFECT_SUMMON_WILD + &Spell::EffectSummonGuardian, // 42 SPELL_EFFECT_SUMMON_GUARDIAN + &Spell::EffectTeleUnitsFaceCaster, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER + &Spell::EffectLearnSkill, // 44 SPELL_EFFECT_SKILL_STEP + &Spell::EffectAddHonor, // 45 SPELL_EFFECT_ADD_HONOR honor/pvp related + &Spell::EffectNULL, // 46 SPELL_EFFECT_SPAWN we must spawn pet there + &Spell::EffectTradeSkill, // 47 SPELL_EFFECT_TRADE_SKILL + &Spell::EffectUnused, // 48 SPELL_EFFECT_STEALTH one spell: Base Stealth + &Spell::EffectUnused, // 49 SPELL_EFFECT_DETECT one spell: Detect + &Spell::EffectTransmitted, // 50 SPELL_EFFECT_TRANS_DOOR + &Spell::EffectUnused, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT unused + &Spell::EffectUnused, // 52 SPELL_EFFECT_GUARANTEE_HIT one spell: zzOLDCritical Shot + &Spell::EffectEnchantItemPerm, // 53 SPELL_EFFECT_ENCHANT_ITEM + &Spell::EffectEnchantItemTmp, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY + &Spell::EffectTameCreature, // 55 SPELL_EFFECT_TAMECREATURE + &Spell::EffectSummonPet, // 56 SPELL_EFFECT_SUMMON_PET + &Spell::EffectLearnPetSpell, // 57 SPELL_EFFECT_LEARN_PET_SPELL + &Spell::EffectWeaponDmg, // 58 SPELL_EFFECT_WEAPON_DAMAGE + &Spell::EffectOpenSecretSafe, // 59 SPELL_EFFECT_OPEN_LOCK_ITEM + &Spell::EffectProficiency, // 60 SPELL_EFFECT_PROFICIENCY + &Spell::EffectSendEvent, // 61 SPELL_EFFECT_SEND_EVENT + &Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN + &Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT + &Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL + &Spell::EffectUnused, // 65 SPELL_EFFECT_HEALTH_FUNNEL unused + &Spell::EffectUnused, // 66 SPELL_EFFECT_POWER_FUNNEL unused + &Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH + &Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST + &Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT + &Spell::EffectPull, // 70 SPELL_EFFECT_PULL one spell: Distract Move + &Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET + &Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT + &Spell::EffectSummonGuardian, // 73 SPELL_EFFECT_SUMMON_POSSESSED + &Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM + &Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit + &Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD + &Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT + &Spell::EffectUnused, // 78 SPELL_EFFECT_ATTACK + &Spell::EffectSanctuary, // 79 SPELL_EFFECT_SANCTUARY + &Spell::EffectAddComboPoints, // 80 SPELL_EFFECT_ADD_COMBO_POINTS + &Spell::EffectUnused, // 81 SPELL_EFFECT_CREATE_HOUSE one spell: Create House (TEST) + &Spell::EffectNULL, // 82 SPELL_EFFECT_BIND_SIGHT + &Spell::EffectDuel, // 83 SPELL_EFFECT_DUEL + &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK + &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER + &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT + &Spell::EffectSummonTotem, // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1 + &Spell::EffectSummonTotem, // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2 + &Spell::EffectSummonTotem, // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3 + &Spell::EffectSummonTotem, // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4 + &Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash + &Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM + &Spell::EffectUnused, // 93 SPELL_EFFECT_SUMMON_PHANTASM + &Spell::EffectSelfResurrect, // 94 SPELL_EFFECT_SELF_RESURRECT + &Spell::EffectSkinning, // 95 SPELL_EFFECT_SKINNING + &Spell::EffectCharge, // 96 SPELL_EFFECT_CHARGE + &Spell::EffectSummonCritter, // 97 SPELL_EFFECT_SUMMON_CRITTER + &Spell::EffectKnockBack, // 98 SPELL_EFFECT_KNOCK_BACK + &Spell::EffectDisEnchant, // 99 SPELL_EFFECT_DISENCHANT + &Spell::EffectInebriate, //100 SPELL_EFFECT_INEBRIATE + &Spell::EffectFeedPet, //101 SPELL_EFFECT_FEED_PET + &Spell::EffectDismissPet, //102 SPELL_EFFECT_DISMISS_PET + &Spell::EffectReputation, //103 SPELL_EFFECT_REPUTATION + &Spell::EffectSummonObject, //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 + &Spell::EffectSummonObject, //105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 + &Spell::EffectSummonObject, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + &Spell::EffectSummonObject, //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 + &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC + &Spell::EffectSummonDeadPet, //109 SPELL_EFFECT_SUMMON_DEAD_PET + &Spell::EffectDestroyAllTotems, //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS + &Spell::EffectDurabilityDamage, //111 SPELL_EFFECT_DURABILITY_DAMAGE + &Spell::EffectSummonDemon, //112 SPELL_EFFECT_SUMMON_DEMON + &Spell::EffectResurrectNew, //113 SPELL_EFFECT_RESURRECT_NEW + &Spell::EffectTaunt, //114 SPELL_EFFECT_ATTACK_ME + &Spell::EffectDurabilityDamagePCT, //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT + &Spell::EffectSkinPlayerCorpse, //116 SPELL_EFFECT_SKIN_PLAYER_CORPSE one spell: Remove Insignia, bg usage, required special corpse flags... + &Spell::EffectSpiritHeal, //117 SPELL_EFFECT_SPIRIT_HEAL one spell: Spirit Heal + &Spell::EffectSkill, //118 SPELL_EFFECT_SKILL professions and more + &Spell::EffectApplyAreaAura, //119 SPELL_EFFECT_APPLY_AREA_AURA_PET + &Spell::EffectUnused, //120 SPELL_EFFECT_TELEPORT_GRAVEYARD one spell: Graveyard Teleport Test + &Spell::EffectWeaponDmg, //121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG + &Spell::EffectUnused, //122 SPELL_EFFECT_122 unused + &Spell::EffectSendTaxi, //123 SPELL_EFFECT_SEND_TAXI taxi/flight related (misc value is taxi path id) + &Spell::EffectPlayerPull, //124 SPELL_EFFECT_PLAYER_PULL opposite of knockback effect (pulls player twoard caster) + &Spell::EffectModifyThreatPercent, //125 SPELL_EFFECT_MODIFY_THREAT_PERCENT + &Spell::EffectStealBeneficialBuff, //126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF spell steal effect? + &Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell + &Spell::EffectApplyAreaAura, //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND + &Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY + &Spell::EffectNULL, //130 SPELL_EFFECT_REDIRECT_THREAT + &Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells + &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value + &Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization + &Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry + &Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET + &Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT + &Spell::EffectEnergisePct, //137 SPELL_EFFECT_ENERGIZE_PCT + &Spell::EffectNULL, //138 SPELL_EFFECT_138 Leap + &Spell::EffectUnused, //139 SPELL_EFFECT_139 unused + &Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST + &Spell::EffectNULL, //141 SPELL_EFFECT_141 damage and reduce speed? + &Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE + &Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER + &Spell::EffectNULL, //144 SPELL_EFFECT_144 Spectral Blast + &Spell::EffectNULL, //145 SPELL_EFFECT_145 Black Hole Effect + &Spell::EffectUnused, //146 SPELL_EFFECT_146 unused + &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail + &Spell::EffectUnused, //148 SPELL_EFFECT_148 unused + &Spell::EffectNULL, //149 SPELL_EFFECT_149 swoop + &Spell::EffectUnused, //150 SPELL_EFFECT_150 unused + &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2 + &Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend + &Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry +}; + +void Spell::EffectNULL(uint32 /*i*/) +{ + sLog.outDebug("WORLD: Spell Effect DUMMY"); +} + +void Spell::EffectUnused(uint32 /*i*/) +{ + // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN MANGOS +} + +void Spell::EffectResurrectNew(uint32 i) +{ + if(!unitTarget || unitTarget->isAlive()) + return; + + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + if(!unitTarget->IsInWorld()) + return; + + Player* pTarget = ((Player*)unitTarget); + + if(pTarget->isRessurectRequested()) // already have one active request + return; + + uint32 health = damage; + uint32 mana = m_spellInfo->EffectMiscValue[i]; + pTarget->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana); + SendResurrectRequest(pTarget); +} + +void Spell::EffectInstaKill(uint32 /*i*/) +{ + if( !unitTarget || !unitTarget->isAlive() ) + return; + + // Demonic Sacrifice + if(m_spellInfo->Id==18788 && unitTarget->GetTypeId()==TYPEID_UNIT) + { + uint32 entry = unitTarget->GetEntry(); + uint32 spellID; + switch(entry) + { + case 416: spellID=18789; break; //imp + case 417: spellID=18792; break; //fellhunter + case 1860: spellID=18790; break; //void + case 1863: spellID=18791; break; //succubus + case 17252: spellID=35701; break; //fellguard + default: + sLog.outError("EffectInstaKill: Unhandled creature entry (%u) case.",entry); + return; + } + + m_caster->CastSpell(m_caster,spellID,true); + } + + if(m_caster==unitTarget) // prevent interrupt message + finish(); + + uint32 health = unitTarget->GetHealth(); + m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); +} + +void Spell::EffectEnvirinmentalDMG(uint32 i) +{ + uint32 absorb = 0; + uint32 resist = 0; + + // Note: this hack with damage replace required until GO casting not implemented + // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support + // currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc + damage = m_spellInfo->EffectBasePoints[i]+m_spellInfo->EffectBaseDice[i]; + + m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); + + m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, GetSpellSchoolMask(m_spellInfo), absorb, resist, false, 0, false); + if(m_caster->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_caster)->EnvironmentalDamage(m_caster->GetGUID(),DAMAGE_FIRE,damage); +} + +void Spell::EffectSchoolDMG(uint32 effect_idx) +{ + if( unitTarget && unitTarget->isAlive()) + { + switch(m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + //Gore + if(m_spellInfo->SpellIconID == 2269 ) + { + damage+= rand()%2 ? damage : 0; + } + + switch(m_spellInfo->Id) // better way to check unknown + { + // Meteor like spells (divided damage to targets) + case 24340: case 26558: case 28884: // Meteor + case 36837: case 38903: case 41276: // Meteor + case 26789: // Shard of the Fallen Star + case 31436: // Malevolent Cleave + case 35181: // Dive Bomb + case 40810: case 43267: case 43268: // Saber Lash + case 42384: // Brutal Swipe + case 45150: // Meteor Slash + { + uint32 count = 0; + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + if(ihit->effectMask & (1<GetHealth() / 2; + if(damage < 200) + damage = 200; + break; + } + } + break; + } + + case SPELLFAMILY_MAGE: + { + // Arcane Blast + if(m_spellInfo->SpellFamilyFlags & 0x20000000LL) + { + m_caster->CastSpell(m_caster,36032,true); + } + break; + } + case SPELLFAMILY_WARRIOR: + { + // Bloodthirst + if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL) + { + damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100); + } + // Shield Slam + else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) + damage += int32(m_caster->GetShieldBlockValue()); + // Victory Rush + else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL) + { + damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); + m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false); + } + break; + } + case SPELLFAMILY_WARLOCK: + { + // Incinerate Rank 1 & 2 + if((m_spellInfo->SpellFamilyFlags & 0x00004000000000LL) && m_spellInfo->SpellIconID==2128) + { + // Incinerate does more dmg (dmg*0.25) if the target is Immolated. + if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) + damage += int32(damage*0.25); + } + break; + } + case SPELLFAMILY_DRUID: + { + // Ferocious Bite + if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587) + { + // converts each extra point of energy into ($f1+$AP/630) additional damage + float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx]; + damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple); + m_caster->SetPower(POWER_ENERGY,0); + } + // Rake + else if(m_spellInfo->SpellFamilyFlags & 0x0000000000001000LL) + { + damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); + } + // Swipe + else if(m_spellInfo->SpellFamilyFlags & 0x0010000000000000LL) + { + damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.08f); + } + // Starfire + else if ( m_spellInfo->SpellFamilyFlags & 0x0004LL ) + { + Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i) + { + // Starfire Bonus (caster) + switch((*i)->GetModifier()->m_miscvalue) + { + case 5481: // Nordrassil Regalia - bonus + { + Unit::AuraList const& m_periodicDamageAuras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(Unit::AuraList::const_iterator itr = m_periodicDamageAuras.begin(); itr != m_periodicDamageAuras.end(); ++itr) + { + // Moonfire or Insect Swarm (target debuff from any casters) + if ( (*itr)->GetSpellProto()->SpellFamilyFlags & 0x00200002LL ) + { + int32 mod = (*i)->GetModifier()->m_amount; + damage += damage*mod/100; + break; + } + } + break; + } + case 5148: //Improved Starfire - Ivory Idol of the Moongoddes Aura + { + damage += (*i)->GetModifier()->m_amount; + break; + } + } + } + } + //Mangle Bonus for the initial damage of Lacerate and Rake + if((m_spellInfo->SpellFamilyFlags==0x0000000000001000LL && m_spellInfo->SpellIconID==494) || + (m_spellInfo->SpellFamilyFlags==0x0000010000000000LL && m_spellInfo->SpellIconID==2246)) + { + Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) + if((*i)->GetSpellProto()->SpellFamilyFlags & 0x0000044000000000LL && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID) + { + damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f); + break; + } + } + break; + } + case SPELLFAMILY_ROGUE: + { + // Envenom + if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x800000000LL)) + { + // consume from stack dozes not more that have combo-points + if(uint32 combo = ((Player*)m_caster)->GetComboPoints()) + { + // count consumed deadly poison doses at target + uint32 doses = 0; + + // remove consumed poison doses + Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;) + { + // Deadly poison (only attacker applied) + if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) && + (*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) + { + --combo; + ++doses; + + unitTarget->RemoveSingleAuraFromStack((*itr)->GetId(), (*itr)->GetEffIndex()); + + itr = auras.begin(); + } + else + ++itr; + } + + damage *= doses; + damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses); + + // Eviscerate and Envenom Bonus Damage (item set effect) + if(m_caster->GetDummyAura(37169)) + damage += ((Player*)m_caster)->GetComboPoints()*40; + } + } + // Eviscerate + else if((m_spellInfo->SpellFamilyFlags & 0x00020000LL) && m_caster->GetTypeId()==TYPEID_PLAYER) + { + if(uint32 combo = ((Player*)m_caster)->GetComboPoints()) + { + damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f); + + // Eviscerate and Envenom Bonus Damage (item set effect) + if(m_caster->GetDummyAura(37169)) + damage += combo*40; + } + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Mongoose Bite + if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342) + { + damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2); + } + // Arcane Shot + else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0) + { + damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15); + } + // Steady Shot + else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) + { + int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE)); + damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f); + } + //Explosive Trap Effect + else if(m_spellInfo->SpellFamilyFlags & 0x00000004) + { + damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1); + } + break; + } + case SPELLFAMILY_PALADIN: + { + //Judgement of Vengeance + if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292) + { + uint32 stacks = 0; + Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID()) + ++stacks; + if(!stacks) + //No damage if the target isn't affected by this + damage = -1; + else + damage *= stacks; + } + break; + } + } + + if(damage >= 0) + { + uint32 finalDamage; + if(m_originalCaster) // m_caster only passive source of cast + finalDamage = m_originalCaster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true); + else + finalDamage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true); + + // post effects + switch(m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_WARRIOR: + { + // Bloodthirst + if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL) + { + uint32 BTAura = 0; + switch(m_spellInfo->Id) + { + case 23881: BTAura = 23885; break; + case 23892: BTAura = 23886; break; + case 23893: BTAura = 23887; break; + case 23894: BTAura = 23888; break; + case 25251: BTAura = 25252; break; + case 30335: BTAura = 30339; break; + default: + sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id); + break; + } + + if (BTAura) + m_caster->CastSpell(m_caster,BTAura,true); + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Shadow Word: Death + if(finalDamage > 0 && (m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL) && unitTarget->isAlive()) + // deals damage equal to damage done to caster if victim is not killed + m_caster->SpellNonMeleeDamageLog( m_caster, m_spellInfo->Id, finalDamage, m_IsTriggeredSpell, false); + + break; + } + case SPELLFAMILY_PALADIN: + { + // Judgement of Blood + if(finalDamage > 0 && (m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL) && m_spellInfo->SpellIconID==153) + { + int32 damagePoint = finalDamage * 33 / 100; + m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true); + } + break; + } + } + } + } +} + +void Spell::EffectDummy(uint32 i) +{ + if(!unitTarget && !gameObjTarget && !itemTarget) + return; + + // selection by spell family + switch(m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + // Gnomish Poultryizer trinket + switch(m_spellInfo->Id ) + { + case 8063: // Deviate Fish + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + uint32 spell_id = 0; + switch(urand(1,5)) + { + case 1: spell_id = 8064; break; // Sleepy + case 2: spell_id = 8065; break; // Invigorate + case 3: spell_id = 8066; break; // Shrink + case 4: spell_id = 8067; break; // Party Time! + case 5: spell_id = 8068; break; // Healthy Spirit + } + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + case 8213: // Savory Deviate Delight + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + uint32 spell_id = 0; + switch(urand(1,2)) + { + // Flip Out - ninja + case 1: spell_id = (m_caster->getGender() == GENDER_MALE ? 8219 : 8220); break; + // Yaaarrrr - pirate + case 2: spell_id = (m_caster->getGender() == GENDER_MALE ? 8221 : 8222); break; + } + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + case 8593: // Symbol of life (restore creature to life) + case 31225: // Shimmering Vessel (restore creature to life) + { + if(!unitTarget || unitTarget->GetTypeId()!=TYPEID_UNIT) + return; + ((Creature*)unitTarget)->setDeathState(JUST_ALIVED); + return; + } + case 12162: // Deep wounds + case 12850: // (now good common check for this spells) + case 12868: + { + if(!unitTarget) + return; + + float damage; + // DW should benefit of attack power, damage percent mods etc. + // TODO: check if using offhand damage is correct and if it should be divided by 2 + if (m_caster->haveOffhandWeapon() && m_caster->getAttackTimer(BASE_ATTACK) > m_caster->getAttackTimer(OFF_ATTACK)) + damage = (m_caster->GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE))/2; + else + damage = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE))/2; + + switch (m_spellInfo->Id) + { + case 12850: damage *= 0.2f; break; + case 12162: damage *= 0.4f; break; + case 12868: damage *= 0.6f; break; + default: + sLog.outError("Spell::EffectDummy: Spell %u not handled in DW",m_spellInfo->Id); + return; + }; + + int32 deepWoundsDotBasePoints0 = int32(damage / 4); + m_caster->CastCustomSpell(unitTarget, 12721, &deepWoundsDotBasePoints0, NULL, NULL, true, NULL); + return; + } + case 12975: //Last Stand + { + int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3); + m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL); + return; + } + case 13120: // net-o-matic + { + if(!unitTarget) + return; + + uint32 spell_id = 0; + + uint32 roll = urand(0, 99); + + if(roll < 2) // 2% for 30 sec self root (off-like chance unknown) + spell_id = 16566; + else if(roll < 4) // 2% for 20 sec root, charge to target (off-like chance unknown) + spell_id = 13119; + else // normal root + spell_id = 13099; + + m_caster->CastSpell(unitTarget,spell_id,true,NULL); + return; + } + case 13567: // Dummy Trigger + { + // can be used for different aura triggreing, so select by aura + if(!m_triggeredByAuraSpell || !unitTarget) + return; + + switch(m_triggeredByAuraSpell->Id) + { + case 26467: // Persistent Shield + m_caster->CastCustomSpell(unitTarget, 26470, &damage, NULL, NULL, true); + break; + default: + sLog.outError("EffectDummy: Non-handled case for spell 13567 for triggered aura %u",m_triggeredByAuraSpell->Id); + break; + } + return; + } + case 14185: // Preparation Rogue + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + //immediately finishes the cooldown on certain Rogue abilities + const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + uint32 classspell = itr->first; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + + if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x26000000860LL)) + { + ((Player*)m_caster)->RemoveSpellCooldown(classspell); + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(classspell); + data << uint64(m_caster->GetGUID()); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + } + return; + } + case 15998: // Capture Worg Pup + case 29435: // Capture Female Kaliri Hatchling + { + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT) + return; + + Creature* creatureTarget = (Creature*)unitTarget; + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + return; + } + case 16589: // Noggenfogger Elixir + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + uint32 spell_id = 0; + switch(urand(1,3)) + { + case 1: spell_id = 16595; break; + case 2: spell_id = 16593; break; + default:spell_id = 16591; break; + } + + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + case 17251: // Spirit Healer Res + { + if(!unitTarget || !m_originalCaster) + return; + + if(m_originalCaster->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_SPIRIT_HEALER_CONFIRM, 8); + data << unitTarget->GetGUID(); + ((Player*)m_originalCaster)->GetSession()->SendPacket( &data ); + } + return; + } + case 17271: // Test Fetid Skull + { + if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + uint32 spell_id = roll_chance_i(50) ? 17269 : 17270; + + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + case 20577: // Cannibalize + if (unitTarget) + m_caster->CastSpell(m_caster,20578,false,NULL); + return; + case 23019: // Crystal Prison Dummy DND + { + if(!unitTarget || !unitTarget->isAlive() || unitTarget->GetTypeId() != TYPEID_UNIT || ((Creature*)unitTarget)->isPet()) + return; + + Creature* creatureTarget = (Creature*)unitTarget; + if(creatureTarget->isPet()) + return; + + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + + GameObject* pGameObj = new GameObject; + + Map *map = creatureTarget->GetMap(); + + if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 179644, map, + creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), + creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1) ) + { + delete pGameObj; + return; + } + + pGameObj->SetRespawnTime(creatureTarget->GetRespawnTime()-time(NULL)); + pGameObj->SetOwnerGUID(m_caster->GetGUID() ); + pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() ); + pGameObj->SetSpellId(m_spellInfo->Id); + + DEBUG_LOG("AddObject at SpellEfects.cpp EffectDummy\n"); + map->Add(pGameObj); + + WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); + data << uint64(pGameObj->GetGUID()); + m_caster->SendMessageToSet(&data,true); + + return; + } + case 23074: // Arc. Dragonling + if (!m_CastItem) return; + m_caster->CastSpell(m_caster,19804,true,m_CastItem); + return; + case 23075: // Mithril Mechanical Dragonling + if (!m_CastItem) return; + m_caster->CastSpell(m_caster,12749,true,m_CastItem); + return; + case 23076: // Mechanical Dragonling + if (!m_CastItem) return; + m_caster->CastSpell(m_caster,4073,true,m_CastItem); + return; + case 23133: // Gnomish Battle Chicken + if (!m_CastItem) return; + m_caster->CastSpell(m_caster,13166,true,m_CastItem); + return; + case 23448: // Ultrasafe Transporter: Gadgetzan - backfires + { + int32 r = irand(0, 119); + if ( r < 20 ) // 1/6 polymorph + m_caster->CastSpell(m_caster,23444,true); + else if ( r < 100 ) // 4/6 evil twin + m_caster->CastSpell(m_caster,23445,true); + else // 1/6 miss the target + m_caster->CastSpell(m_caster,36902,true); + return; + } + case 23453: // Ultrasafe Transporter: Gadgetzan + if ( roll_chance_i(50) ) // success + m_caster->CastSpell(m_caster,23441,true); + else // failure + m_caster->CastSpell(m_caster,23446,true); + return; + case 23645: // Hourglass Sand + m_caster->RemoveAurasDueToSpell(23170); + return; + case 23725: // Gift of Life (warrior bwl trinket) + m_caster->CastSpell(m_caster,23782,true); + m_caster->CastSpell(m_caster,23783,true); + return; + case 25860: // Reindeer Transformation + { + if (!m_caster->HasAuraType(SPELL_AURA_MOUNTED)) + return; + + float flyspeed = m_caster->GetSpeedRate(MOVE_FLY); + float speed = m_caster->GetSpeedRate(MOVE_RUN); + + m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + + //5 different spells used depending on mounted speed and if mount can fly or not + if (flyspeed >= 4.1f) + m_caster->CastSpell(m_caster, 44827, true); //310% flying Reindeer + else if (flyspeed >= 3.8f) + m_caster->CastSpell(m_caster, 44825, true); //280% flying Reindeer + else if (flyspeed >= 1.6f) + m_caster->CastSpell(m_caster, 44824, true); //60% flying Reindeer + else if (speed >= 2.0f) + m_caster->CastSpell(m_caster, 25859, true); //100% ground Reindeer + else + m_caster->CastSpell(m_caster, 25858, true); //60% ground Reindeer + + return; + } + //case 26074: // Holiday Cheer + // return; -- implemented at client side + case 28006: // Arcane Cloaking + { + if( unitTarget->GetTypeId() == TYPEID_PLAYER ) + m_caster->CastSpell(unitTarget,29294,true); + return; + } + case 28730: // Arcane Torrent (Mana) + { + int32 count = 0; + Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i) + if ((*i)->GetId() == 28734) + ++count; + if (count) + { + m_caster->RemoveAurasDueToSpell(28734); + int32 bp = damage * count; + m_caster->CastCustomSpell(m_caster, 28733, &bp, NULL, NULL, true); + } + return; + } + case 29200: // Purify Helboar Meat + { + if( m_caster->GetTypeId() != TYPEID_PLAYER ) + return; + + uint32 spell_id = roll_chance_i(50) ? 29277 : 29278; + + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + case 29858: // Soulshatter + if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT && unitTarget->IsHostileTo(m_caster)) + m_caster->CastSpell(unitTarget,32835,true); + return; + case 30458: // Nigh Invulnerability + if (!m_CastItem) return; + if(roll_chance_i(86)) // success + m_caster->CastSpell(m_caster, 30456, true, m_CastItem); + else // backfire in 14% casts + m_caster->CastSpell(m_caster, 30457, true, m_CastItem); + return; + case 30507: // Poultryizer + if (!m_CastItem) return; + if(roll_chance_i(80)) // success + m_caster->CastSpell(unitTarget, 30501, true, m_CastItem); + else // backfire 20% + m_caster->CastSpell(unitTarget, 30504, true, m_CastItem); + return; + case 33060: // Make a Wish + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + uint32 spell_id = 0; + + switch(urand(1,5)) + { + case 1: spell_id = 33053; break; + case 2: spell_id = 33057; break; + case 3: spell_id = 33059; break; + case 4: spell_id = 33062; break; + case 5: spell_id = 33064; break; + } + + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + case 35745: + { + uint32 spell_id; + switch(m_caster->GetAreaId()) + { + case 3900: spell_id = 35743; break; + case 3742: spell_id = 35744; break; + default: return; + } + + m_caster->CastSpell(m_caster,spell_id,true); + return; + } + case 37674: // Chaos Blast + if(unitTarget) + m_caster->CastSpell(unitTarget,37675,true); + return; + case 44875: // Complete Raptor Capture + { + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT) + return; + + Creature* creatureTarget = (Creature*)unitTarget; + + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + + //cast spell Raptor Capture Credit + m_caster->CastSpell(m_caster,42337,true,NULL); + return; + } + case 37573: //Temporal Phase Modulator + { + if(!unitTarget) + return; + + TemporarySummon* tempSummon = dynamic_cast(unitTarget); + if(!tempSummon) + return; + + uint32 health = tempSummon->GetHealth(); + const uint32 entry_list[6] = {21821, 21820, 21817}; + + float x = tempSummon->GetPositionX(); + float y = tempSummon->GetPositionY(); + float z = tempSummon->GetPositionZ(); + float o = tempSummon->GetOrientation(); + + tempSummon->UnSummon(); + + Creature* pCreature = m_caster->SummonCreature(entry_list[urand(0, 2)], x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000); + if (!pCreature) + return; + + pCreature->SetHealth(health); + + if(pCreature->AI()) + pCreature->AI()->AttackStart(m_caster); + + return; + } + case 34665: //Administer Antidote + { + if(!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER ) + return; + + if(!unitTarget) + return; + + TemporarySummon* tempSummon = dynamic_cast(unitTarget); + if(!tempSummon) + return; + + uint32 health = tempSummon->GetHealth(); + + float x = tempSummon->GetPositionX(); + float y = tempSummon->GetPositionY(); + float z = tempSummon->GetPositionZ(); + float o = tempSummon->GetOrientation(); + tempSummon->UnSummon(); + + Creature* pCreature = m_caster->SummonCreature(16992, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000); + if (!pCreature) + return; + + pCreature->SetHealth(health); + ((Player*)m_caster)->KilledMonster(16992,pCreature->GetGUID()); + + if (pCreature->AI()) + pCreature->AI()->AttackStart(m_caster); + + return; + } + case 44997: // Converting Sentry + { + //Converted Sentry Credit + m_caster->CastSpell(m_caster, 45009, true); + return; + } + case 45030: // Impale Emissary + { + // Emissary of Hate Credit + m_caster->CastSpell(m_caster, 45088, true); + return; + } + case 50243: // Teach Language + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + // spell has a 1/3 chance to trigger one of the below + if(roll_chance_i(66)) + return; + if(((Player*)m_caster)->GetTeam() == ALLIANCE) + { + // 1000001 - gnomish binary + m_caster->CastSpell(m_caster, 50242, true); + } + else + { + // 01001000 - goblin binary + m_caster->CastSpell(m_caster, 50246, true); + } + + return; + } + case 51582: //Rocket Boots Engaged (Rocket Boots Xtreme and Rocket Boots Xtreme Lite) + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + if(BattleGround* bg = ((Player*)m_caster)->GetBattleGround()) + bg->EventPlayerDroppedFlag((Player*)m_caster); + + m_caster->CastSpell(m_caster, 30452, true, NULL); + return; + } + } + + //All IconID Check in there + switch(m_spellInfo->SpellIconID) + { + // Berserking (troll racial traits) + case 1661: + { + uint32 healthPerc = uint32((float(m_caster->GetHealth())/m_caster->GetMaxHealth())*100); + int32 melee_mod = 10; + if (healthPerc <= 40) + melee_mod = 30; + if (healthPerc < 100 && healthPerc > 40) + melee_mod = 10+(100-healthPerc)/3; + + int32 hasteModBasePoints0 = melee_mod; // (EffectBasePoints[0]+1)-1+(5-melee_mod) = (melee_mod-1+1)-1+5-melee_mod = 5-1 + int32 hasteModBasePoints1 = (5-melee_mod); + int32 hasteModBasePoints2 = 5; + + // FIXME: custom spell required this aura state by some unknown reason, we not need remove it anyway + m_caster->ModifyAuraState(AURA_STATE_BERSERKING,true); + m_caster->CastCustomSpell(m_caster,26635,&hasteModBasePoints0,&hasteModBasePoints1,&hasteModBasePoints2,true,NULL); + return; + } + } + break; + case SPELLFAMILY_MAGE: + switch(m_spellInfo->Id ) + { + case 11958: // Cold Snap + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + // immediately finishes the cooldown on Frost spells + const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + if (itr->second->state == PLAYERSPELL_REMOVED) + continue; + + uint32 classspell = itr->first; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + + if( spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && + (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) && + spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0 ) + { + ((Player*)m_caster)->RemoveSpellCooldown(classspell); + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(classspell); + data << uint64(m_caster->GetGUID()); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + } + return; + } + case 32826: + { + if ( unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT ) + { + //Polymorph Cast Visual Rank 1 + const uint32 spell_list[6] = {32813, 32816, 32817, 32818, 32819, 32820}; + unitTarget->CastSpell( unitTarget, spell_list[urand(0, 5)], true); + } + return; + } + } + break; + case SPELLFAMILY_WARRIOR: + // Charge + if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867) + { + int32 chargeBasePoints0 = damage; + m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true); + return; + } + // Execute + if(m_spellInfo->SpellFamilyFlags & 0x20000000) + { + if(!unitTarget) + return; + + int32 basePoints0 = damage+int32(m_caster->GetPower(POWER_RAGE) * m_spellInfo->DmgMultiplier[i]); + m_caster->CastCustomSpell(unitTarget, 20647, &basePoints0, NULL, NULL, true, 0); + m_caster->SetPower(POWER_RAGE,0); + return; + } + if(m_spellInfo->Id==21977) //Warrior's Wrath + { + if(!unitTarget) + return; + + m_caster->CastSpell(unitTarget,21887,true); // spell mod + return; + } + break; + case SPELLFAMILY_WARLOCK: + //Life Tap (only it have this with dummy effect) + if (m_spellInfo->SpellFamilyFlags == 0x40000) + { + float cost = m_currentBasePoints[0]+1; + + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this); + + int32 dmg = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE); + + if(int32(m_caster->GetHealth()) > dmg) + { + // Shouldn't Appear in Combat Log + m_caster->ModifyHealth(-dmg); + + int32 mana = dmg; + + Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) + { + // only Imp. Life Tap have this in combination with dummy aura + if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208) + mana = ((*itr)->GetModifier()->m_amount + 100)* mana / 100; + } + + m_caster->CastCustomSpell(m_caster,31818,&mana,NULL,NULL,true,NULL); + + // Mana Feed + int32 manaFeedVal = m_caster->CalculateSpellDamage(m_spellInfo,1, m_spellInfo->EffectBasePoints[1],m_caster); + manaFeedVal = manaFeedVal * mana / 100; + if(manaFeedVal > 0) + m_caster->CastCustomSpell(m_caster,32553,&manaFeedVal,NULL,NULL,true,NULL); + } + else + SendCastResult(SPELL_FAILED_FIZZLE); + return; + } + break; + case SPELLFAMILY_PRIEST: + switch(m_spellInfo->Id ) + { + case 28598: // Touch of Weakness triggered spell + { + if(!unitTarget || !m_triggeredByAuraSpell) + return; + + uint32 spellid = 0; + switch(m_triggeredByAuraSpell->Id) + { + case 2652: spellid = 2943; break; // Rank 1 + case 19261: spellid = 19249; break; // Rank 2 + case 19262: spellid = 19251; break; // Rank 3 + case 19264: spellid = 19252; break; // Rank 4 + case 19265: spellid = 19253; break; // Rank 5 + case 19266: spellid = 19254; break; // Rank 6 + case 25461: spellid = 25460; break; // Rank 7 + default: + sLog.outError("Spell::EffectDummy: Spell 28598 triggered by unhandeled spell %u",m_triggeredByAuraSpell->Id); + return; + } + m_caster->CastSpell(unitTarget, spellid, true, NULL); + return; + } + } + break; + case SPELLFAMILY_DRUID: + switch(m_spellInfo->Id ) + { + case 5420: // Tree of Life passive + { + // Tree of Life area effect + int32 health_mod = int32(m_caster->GetStat(STAT_SPIRIT)/4); + m_caster->CastCustomSpell(m_caster,34123,&health_mod,NULL,NULL,true,NULL); + return; + } + } + break; + case SPELLFAMILY_ROGUE: + switch(m_spellInfo->Id ) + { + case 31231: // Cheat Death + { + m_caster->CastSpell(m_caster,45182,true); + return; + } + case 5938: // Shiv + { + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player *pCaster = ((Player*)m_caster); + + Item *item = pCaster->GetWeaponForAttack(OFF_ATTACK); + if(!item) + return; + + // all poison enchantments is temporary + uint32 enchant_id = item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT); + if(!enchant_id) + return; + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return; + + for (int s=0;s<3;s++) + { + if(pEnchant->type[s]!=ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) + continue; + + SpellEntry const* combatEntry = sSpellStore.LookupEntry(pEnchant->spellid[s]); + if(!combatEntry || combatEntry->Dispel != DISPEL_POISON) + continue; + + m_caster->CastSpell(unitTarget, combatEntry, true, item); + } + + m_caster->CastSpell(unitTarget, 5940, true); + return; + } + } + break; + case SPELLFAMILY_HUNTER: + // Steady Shot + if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) + { + if( !unitTarget || !unitTarget->isAlive()) + return; + + bool found = false; + + // check dazed affect + Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); + for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter) + { + if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0) + { + found = true; + break; + } + } + + if(found) + m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true); + return; + } + // Kill command + if(m_spellInfo->SpellFamilyFlags & 0x00080000000000LL) + { + if(m_caster->getClass()!=CLASS_HUNTER) + return; + + // clear hunter crit aura state + m_caster->ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE,false); + + // additional damage from pet to pet target + Pet* pet = m_caster->GetPet(); + if(!pet || !pet->getVictim()) + return; + + uint32 spell_id = 0; + switch (m_spellInfo->Id) + { + case 34026: spell_id = 34027; break; // rank 1 + default: + sLog.outError("Spell::EffectDummy: Spell %u not handled in KC",m_spellInfo->Id); + return; + } + + pet->CastSpell(pet->getVictim(), spell_id, true); + return; + } + + switch(m_spellInfo->Id) + { + case 23989: //Readiness talent + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + //immediately finishes the cooldown for hunter abilities + const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + uint32 classspell = itr->first; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + + if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0 ) + { + ((Player*)m_caster)->RemoveSpellCooldown(classspell); + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(classspell); + data << uint64(m_caster->GetGUID()); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + } + return; + } + case 37506: // Scatter Shot + { + if (m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + // break Auto Shot and autohit + m_caster->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + m_caster->AttackStop(); + ((Player*)m_caster)->SendAttackSwingCancelAttack(); + return; + } + } + break; + case SPELLFAMILY_PALADIN: + switch(m_spellInfo->SpellIconID) + { + case 156: // Holy Shock + { + if(!unitTarget) + return; + + int hurt = 0; + int heal = 0; + + switch(m_spellInfo->Id) + { + case 20473: hurt = 25912; heal = 25914; break; + case 20929: hurt = 25911; heal = 25913; break; + case 20930: hurt = 25902; heal = 25903; break; + case 27174: hurt = 27176; heal = 27175; break; + case 33072: hurt = 33073; heal = 33074; break; + default: + sLog.outError("Spell::EffectDummy: Spell %u not handled in HS",m_spellInfo->Id); + return; + } + + if(m_caster->IsFriendlyTo(unitTarget)) + m_caster->CastSpell(unitTarget, heal, true, 0); + else + m_caster->CastSpell(unitTarget, hurt, true, 0); + + return; + } + case 561: // Judgement of command + { + if(!unitTarget) + return; + + uint32 spell_id = m_currentBasePoints[i]+1; + SpellEntry const* spell_proto = sSpellStore.LookupEntry(spell_id); + if(!spell_proto) + return; + + if( !unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER) + { + // decreased damage (/2) for non-stunned target. + SpellModifier *mod = new SpellModifier; + mod->op = SPELLMOD_DAMAGE; + mod->value = -50; + mod->type = SPELLMOD_PCT; + mod->spellId = m_spellInfo->Id; + mod->effectId = i; + mod->lastAffected = NULL; + mod->mask = 0x0000020000000000LL; + mod->charges = 0; + + ((Player*)m_caster)->AddSpellMod(mod, true); + m_caster->CastSpell(unitTarget,spell_proto,true,NULL); + // mod deleted + ((Player*)m_caster)->AddSpellMod(mod, false); + } + else + m_caster->CastSpell(unitTarget,spell_proto,true,NULL); + + return; + } + } + + switch(m_spellInfo->Id) + { + case 31789: // Righteous Defense (step 1) + { + // 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target) + + // non-standard cast requirement check + if (!unitTarget || unitTarget->getAttackers().empty()) + { + // clear cooldown at fail + if(m_caster->GetTypeId()==TYPEID_PLAYER) + { + ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(m_spellInfo->Id); + data << uint64(m_caster->GetGUID()); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + + SendCastResult(SPELL_FAILED_TARGET_AFFECTING_COMBAT); + return; + } + + // Righteous Defense (step 2) (in old version 31980 dummy effect) + // Clear targets for eff 1 + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + ihit->effectMask &= ~(1<<1); + + // not empty (checked) + Unit::AttackerSet const& attackers = unitTarget->getAttackers(); + + // chance to be selected from list + float chance = 100.0f/attackers.size(); + uint32 count=0; + for(Unit::AttackerSet::const_iterator aItr = attackers.begin(); aItr != attackers.end() && count < 3; ++aItr) + { + if(!roll_chance_f(chance)) + continue; + ++count; + AddUnitTarget((*aItr), 1); + } + + // now let next effect cast spell at each target. + return; + } + case 37877: // Blessing of Faith + { + if(!unitTarget) + return; + + uint32 spell_id = 0; + switch(unitTarget->getClass()) + { + case CLASS_DRUID: spell_id = 37878; break; + case CLASS_PALADIN: spell_id = 37879; break; + case CLASS_PRIEST: spell_id = 37880; break; + case CLASS_SHAMAN: spell_id = 37881; break; + default: return; // ignore for not healing classes + } + + m_caster->CastSpell(m_caster,spell_id,true); + return; + } + } + break; + case SPELLFAMILY_SHAMAN: + //Shaman Rockbiter Weapon + if (m_spellInfo->SpellFamilyFlags == 0x400000) + { + uint32 spell_id = 0; + switch(m_spellInfo->Id) + { + case 8017: spell_id = 36494; break; // Rank 1 + case 8018: spell_id = 36750; break; // Rank 2 + case 8019: spell_id = 36755; break; // Rank 3 + case 10399: spell_id = 36759; break; // Rank 4 + case 16314: spell_id = 36763; break; // Rank 5 + case 16315: spell_id = 36766; break; // Rank 6 + case 16316: spell_id = 36771; break; // Rank 7 + case 25479: spell_id = 36775; break; // Rank 8 + case 25485: spell_id = 36499; break; // Rank 9 + default: + sLog.outError("Spell::EffectDummy: Spell %u not handled in RW",m_spellInfo->Id); + return; + } + + SpellEntry const *spellInfo = sSpellStore.LookupEntry( spell_id ); + + if(!spellInfo) + { + sLog.outError("WORLD: unknown spell id %i\n", spell_id); + return; + } + + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + for(int i = BASE_ATTACK; i <= OFF_ATTACK; ++i) + { + if(Item* item = ((Player*)m_caster)->GetWeaponForAttack(WeaponAttackType(i))) + { + if(item->IsFitToSpellRequirements(m_spellInfo)) + { + Spell *spell = new Spell(m_caster, spellInfo, true); + + // enchanting spell selected by calculated damage-per-sec in enchanting effect + // at calculation applied affect from Elemental Weapons talent + // real enchantment damage-1 + spell->m_currentBasePoints[1] = damage-1; + + SpellCastTargets targets; + targets.setItemTarget( item ); + spell->prepare(&targets); + } + } + } + return; + } + + if(m_spellInfo->Id == 39610) // Mana-Tide Totem effect + { + if(!unitTarget || unitTarget->getPowerType() != POWER_MANA) + return; + + // Regenerate 6% of Total Mana Every 3 secs + int32 EffectBasePoints0 = unitTarget->GetMaxPower(POWER_MANA) * damage / 100; + m_caster->CastCustomSpell(unitTarget,39609,&EffectBasePoints0,NULL,NULL,true,NULL,NULL,m_originalCasterGUID); + return; + } + + break; + } + + // pet auras + if(PetAura const* petSpell = spellmgr.GetPetAura(m_spellInfo->Id)) + { + m_caster->AddPetAura(petSpell); + return; + } +} + +void Spell::EffectTriggerSpellWithValue(uint32 i) +{ + uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[i]; + + // normal case + SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id ); + + if(!spellInfo) + { + sLog.outError("EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i\n", m_spellInfo->Id,triggered_spell_id); + return; + } + + int32 bp = damage; + m_caster->CastCustomSpell(unitTarget,triggered_spell_id,&bp,&bp,&bp,true,NULL,NULL,m_originalCasterGUID); +} + +void Spell::EffectTriggerRitualOfSummoning(uint32 i) +{ + uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[i]; + SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id ); + + if(!spellInfo) + { + sLog.outError("EffectTriggerRitualOfSummoning of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id); + return; + } + + finish(); + Spell *spell = new Spell(m_caster, spellInfo, true); + + SpellCastTargets targets; + targets.setUnitTarget( unitTarget); + spell->prepare(&targets); + + m_caster->SetCurrentCastedSpell(spell); + spell->m_selfContainer = &(m_caster->m_currentSpells[spell->GetCurrentContainer()]); + +} + +void Spell::EffectForceCast(uint32 i) +{ + if( !unitTarget ) + return; + + uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[i]; + + // normal case + SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id ); + + if(!spellInfo) + { + sLog.outError("EffectForceCast of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id); + return; + } + + unitTarget->CastSpell(unitTarget,spellInfo,true,NULL,NULL,m_originalCasterGUID); +} + +void Spell::EffectTriggerSpell(uint32 i) +{ + uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[i]; + + // special cases + switch(triggered_spell_id) + { + // Vanish + case 18461: + { + m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); + m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED); + m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_STALKED); + + // if this spell is given to NPC it must handle rest by it's own AI + if ( m_caster->GetTypeId() != TYPEID_PLAYER ) + return; + + // get highest rank of the Stealth spell + uint32 spellId = 0; + const PlayerSpellMap& sp_list = ((Player*)m_caster)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + // only highest rank is shown in spell book, so simply check if shown in spell book + if(!itr->second->active || itr->second->disabled || itr->second->state == PLAYERSPELL_REMOVED) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (!spellInfo) + continue; + + if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_STEALTH) + { + spellId = spellInfo->Id; + break; + } + } + + // no Stealth spell found + if (!spellId) + return; + + // reset cooldown on it if needed + if(((Player*)m_caster)->HasSpellCooldown(spellId)) + ((Player*)m_caster)->RemoveSpellCooldown(spellId); + + m_caster->CastSpell(m_caster, spellId, true); + return; + } + // just skip + case 23770: // Sayge's Dark Fortune of * + // not exist, common cooldown can be implemented in scripts if need. + return; + // Brittle Armor - (need add max stack of 24575 Brittle Armor) + case 29284: + { + const SpellEntry *spell = sSpellStore.LookupEntry(24575); + if (!spell) + return; + + for (int i=0; i < spell->StackAmount; ++i) + m_caster->CastSpell(unitTarget,spell->Id, true, m_CastItem, NULL, m_originalCasterGUID); + return; + } + // Mercurial Shield - (need add max stack of 26464 Mercurial Shield) + case 29286: + { + const SpellEntry *spell = sSpellStore.LookupEntry(26464); + if (!spell) + return; + + for (int i=0; i < spell->StackAmount; ++i) + m_caster->CastSpell(unitTarget,spell->Id, true, m_CastItem, NULL, m_originalCasterGUID); + return; + } + // Righteous Defense + case 31980: + { + m_caster->CastSpell(unitTarget, 31790, true,m_CastItem,NULL,m_originalCasterGUID); + return; + } + // Cloak of Shadows + case 35729 : + { + Unit::AuraMap& Auras = m_caster->GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter) + { + // remove all harmful spells on you... + if( // ignore positive and passive auras + !iter->second->IsPositive() && !iter->second->IsPassive() && + // ignore physical auras + (GetSpellSchoolMask(iter->second->GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)==0 && + // ignore immunity persistent spells + !( iter->second->GetSpellProto()->AttributesEx & 0x10000 ) ) + { + m_caster->RemoveAurasDueToSpell(iter->second->GetSpellProto()->Id); + iter = Auras.begin(); + } + } + return; + } + // Priest Shadowfiend (34433) need apply mana gain trigger aura on pet + case 41967: + { + if (Unit *pet = m_caster->GetPet()) + pet->CastSpell(pet, 28305, true); + return; + } + } + + // normal case + SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id ); + + if(!spellInfo) + { + sLog.outError("EffectTriggerSpell of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id); + return; + } + + // some triggered spells require specific equipment + if(spellInfo->EquippedItemClass >=0 && m_caster->GetTypeId()==TYPEID_PLAYER) + { + // main hand weapon required + if(spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND) + { + Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK); + + // skip spell if no weapon in slot or broken + if(!item || item->IsBroken() ) + return; + + // skip spell if weapon not fit to triggered spell + if(!item->IsFitToSpellRequirements(spellInfo)) + return; + } + + // offhand hand weapon required + if(spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND) + { + Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK); + + // skip spell if no weapon in slot or broken + if(!item || item->IsBroken() ) + return; + + // skip spell if weapon not fit to triggered spell + if(!item->IsFitToSpellRequirements(spellInfo)) + return; + } + } + + // some triggered spells must be casted instantly (for example, if next effect case instant kill caster) + bool instant = false; + for(uint32 j = i+1; j < 3; ++j) + { + if(m_spellInfo->Effect[j]==SPELL_EFFECT_INSTAKILL && m_spellInfo->EffectImplicitTargetA[j]==TARGET_SELF) + { + instant = true; + break; + } + } + + if(instant) + { + if (unitTarget) + m_caster->CastSpell(unitTarget,spellInfo,true,m_CastItem,NULL,m_originalCasterGUID); + } + else + m_TriggerSpells.push_back(spellInfo); +} + +void Spell::EffectTriggerMissileSpell(uint32 effect_idx) +{ + uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[effect_idx]; + + // normal case + SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id ); + + if(!spellInfo) + { + sLog.outError("EffectTriggerMissileSpell of spell %u: triggering unknown spell id %effect_idx", m_spellInfo->Id,triggered_spell_id); + return; + } + + if (m_CastItem) + DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); + + Spell *spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID ); + + SpellCastTargets targets; + targets.setDestination(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ); + spell->m_CastItem = m_CastItem; + spell->prepare(&targets, NULL); +} + +void Spell::EffectTeleportUnits(uint32 i) +{ + if(!unitTarget || unitTarget->isInFlight()) + return; + + switch (m_spellInfo->EffectImplicitTargetB[i]) + { + case TARGET_INNKEEPER_COORDINATES: + { + // Only players can teleport to innkeeper + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->TeleportTo(((Player*)unitTarget)->m_homebindMapId,((Player*)unitTarget)->m_homebindX,((Player*)unitTarget)->m_homebindY,((Player*)unitTarget)->m_homebindZ,unitTarget->GetOrientation(),unitTarget==m_caster ? TELE_TO_SPELL : 0); + return; + } + case TARGET_TABLE_X_Y_Z_COORDINATES: + { + // TODO: Only players can teleport? + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id); + if(!st) + { + sLog.outError( "Spell::EffectTeleportUnits - unknown Teleport coordinates for spell ID %u\n", m_spellInfo->Id ); + return; + } + ((Player*)unitTarget)->TeleportTo(st->target_mapId,st->target_X,st->target_Y,st->target_Z,st->target_Orientation,unitTarget==m_caster ? TELE_TO_SPELL : 0); + break; + } + case TARGET_BEHIND_VICTIM: + { + // Get selected target for player (or victim for units) + Unit *pTarget = NULL; + if(m_caster->GetTypeId() == TYPEID_PLAYER) + pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection()); + else + pTarget = m_caster->getVictim(); + // No target present - return + if (!pTarget) + return; + // Init dest coordinates + uint32 mapid = m_caster->GetMapId(); + float x = m_targets.m_destX; + float y = m_targets.m_destY; + float z = m_targets.m_destZ; + float orientation = pTarget->GetOrientation(); + // Teleport + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); + else + { + MapManager::Instance().GetMap(mapid, m_caster)->CreatureRelocation((Creature*)unitTarget, x, y, z, orientation); + WorldPacket data; + unitTarget->BuildTeleportAckMsg(&data, x, y, z, orientation); + unitTarget->SendMessageToSet(&data, false); + } + return; + } + default: + { + // If not exist data for dest location - return + if(!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) + { + sLog.outError( "Spell::EffectTeleportUnits - unknown EffectImplicitTargetB[%u] = %u for spell ID %u\n", i, m_spellInfo->EffectImplicitTargetB[i], m_spellInfo->Id ); + return; + } + // Init dest coordinates + uint32 mapid = m_caster->GetMapId(); + float x = m_targets.m_destX; + float y = m_targets.m_destY; + float z = m_targets.m_destZ; + float orientation = unitTarget->GetOrientation(); + // Teleport + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); + else + { + MapManager::Instance().GetMap(mapid, m_caster)->CreatureRelocation((Creature*)unitTarget, x, y, z, orientation); + WorldPacket data; + unitTarget->BuildTeleportAckMsg(&data, x, y, z, orientation); + unitTarget->SendMessageToSet(&data, false); + } + return; + } + } + + // post effects for TARGET_TABLE_X_Y_Z_COORDINATES + switch ( m_spellInfo->Id ) + { + // Dimensional Ripper - Everlook + case 23442: + { + int32 r = irand(0, 119); + if ( r >= 70 ) // 7/12 success + { + if ( r < 100 ) // 4/12 evil twin + m_caster->CastSpell(m_caster,23445,true); + else // 1/12 fire + m_caster->CastSpell(m_caster,23449,true); + } + return; + } + // Ultrasafe Transporter: Toshley's Station + case 36941: + { + if ( roll_chance_i(50) ) // 50% success + { + int32 rand_eff = urand(1,7); + switch ( rand_eff ) + { + case 1: + // soul split - evil + m_caster->CastSpell(m_caster,36900,true); + break; + case 2: + // soul split - good + m_caster->CastSpell(m_caster,36901,true); + break; + case 3: + // Increase the size + m_caster->CastSpell(m_caster,36895,true); + break; + case 4: + // Decrease the size + m_caster->CastSpell(m_caster,36893,true); + break; + case 5: + // Transform + { + if (((Player*)m_caster)->GetTeam() == ALLIANCE ) + m_caster->CastSpell(m_caster,36897,true); + else + m_caster->CastSpell(m_caster,36899,true); + break; + } + case 6: + // chicken + m_caster->CastSpell(m_caster,36940,true); + break; + case 7: + // evil twin + m_caster->CastSpell(m_caster,23445,true); + break; + } + } + return; + } + // Dimensional Ripper - Area 52 + case 36890: + { + if ( roll_chance_i(50) ) // 50% success + { + int32 rand_eff = urand(1,4); + switch ( rand_eff ) + { + case 1: + // soul split - evil + m_caster->CastSpell(m_caster,36900,true); + break; + case 2: + // soul split - good + m_caster->CastSpell(m_caster,36901,true); + break; + case 3: + // Increase the size + m_caster->CastSpell(m_caster,36895,true); + break; + case 4: + // Transform + { + if (((Player*)m_caster)->GetTeam() == ALLIANCE ) + m_caster->CastSpell(m_caster,36897,true); + else + m_caster->CastSpell(m_caster,36899,true); + break; + } + } + } + return; + } + } +} + +void Spell::EffectApplyAura(uint32 i) +{ + if(!unitTarget) + return; + + SpellImmuneList const& list = unitTarget->m_spellImmune[IMMUNITY_STATE]; + for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) + if(itr->type == m_spellInfo->EffectApplyAuraName[i]) + return; + + // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) + if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 && + (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) ) + return; + + Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster; + if(!caster) + return; + + sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]); + + Aura* Aur = CreateAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, caster, m_CastItem); + + // Now Reduce spell duration using data received at spell hit + int32 duration = Aur->GetAuraMaxDuration(); + unitTarget->ApplyDiminishingToDuration(m_diminishGroup,duration,m_caster,m_diminishLevel); + Aur->setDiminishGroup(m_diminishGroup); + + // if Aura removed and deleted, do not continue. + if(duration== 0 && !(Aur->IsPermanent())) + { + delete Aur; + return; + } + + if(duration != Aur->GetAuraMaxDuration()) + { + Aur->SetAuraMaxDuration(duration); + Aur->SetAuraDuration(duration); + } + + bool added = unitTarget->AddAura(Aur); + + // Aura not added and deleted in AddAura call; + if (!added) + return; + + // found crash at character loading, broken pointer to Aur... + // Aur was deleted in AddAura()... + if(!Aur) + return; + + // TODO Make a way so it works for every related spell! + if(unitTarget->GetTypeId()==TYPEID_PLAYER) // Negative buff should only be applied on players + { + uint32 spellId = 0; + if(m_spellInfo->CasterAuraStateNot==AURA_STATE_WEAKENED_SOUL || m_spellInfo->TargetAuraStateNot==AURA_STATE_WEAKENED_SOUL) + spellId = 6788; // Weakened Soul + else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_FORBEARANCE || m_spellInfo->TargetAuraStateNot==AURA_STATE_FORBEARANCE) + spellId = 25771; // Forbearance + else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_HYPOTHERMIA) + spellId = 41425; // Hypothermia + else if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages + spellId = 11196; // Recently Bandaged + else if( (m_spellInfo->AttributesEx & 0x20) && (m_spellInfo->AttributesEx2 & 0x20000) ) + spellId = 23230; // Blood Fury - Healing Reduction + + SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId); + if (AdditionalSpellInfo) + { + // applied at target by target + Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unitTarget,unitTarget, 0); + unitTarget->AddAura(AdditionalAura); + sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]); + } + } + + // Prayer of Mending (jump animation), we need formal caster instead original for correct animation + if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL)) + m_caster->CastSpell(unitTarget,41637,true,NULL,Aur); +} + +void Spell::EffectUnlearnSpecialization( uint32 i ) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player *_player = (Player*)unitTarget; + uint32 spellToUnlearn = m_spellInfo->EffectTriggerSpell[i]; + + _player->removeSpell(spellToUnlearn); + + sLog.outDebug( "Spell: Player %u have unlearned spell %u from NpcGUID: %u", _player->GetGUIDLow(), spellToUnlearn, m_caster->GetGUIDLow() ); +} + +void Spell::EffectPowerDrain(uint32 i) +{ + if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) + return; + + Powers drain_power = Powers(m_spellInfo->EffectMiscValue[i]); + + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + if(unitTarget->getPowerType() != drain_power) + return; + if(damage < 0) + return; + + uint32 curPower = unitTarget->GetPower(drain_power); + + //add spell damage bonus + damage=m_caster->SpellDamageBonus(unitTarget,m_spellInfo,uint32(damage),SPELL_DIRECT_DAMAGE); + + // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) + uint32 power = damage; + if ( drain_power == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER ) + power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power); + + int32 new_damage; + if(curPower < power) + new_damage = curPower; + else + new_damage = power; + + unitTarget->ModifyPower(drain_power,-new_damage); + + if(drain_power == POWER_MANA) + { + float manaMultiplier = m_spellInfo->EffectMultipleValue[i]; + if(manaMultiplier==0) + manaMultiplier = 1; + + if(Player *modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, manaMultiplier); + + int32 gain = int32(new_damage*manaMultiplier); + + m_caster->ModifyPower(POWER_MANA,gain); + //send log + m_caster->SendEnergizeSpellLog(m_caster, m_spellInfo->Id,gain,POWER_MANA,false); + } +} + +void Spell::EffectSendEvent(uint32 EffectIndex) +{ + if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->InBattleGround()) + { + BattleGround* bg = ((Player *)m_caster)->GetBattleGround(); + if(bg && bg->GetStatus() == STATUS_IN_PROGRESS) + { + switch(m_spellInfo->Id) + { + case 23333: // Pickup Horde Flag + /*do not uncomment . + if(bg->GetTypeID()==BATTLEGROUND_WS) + bg->EventPlayerClickedOnFlag((Player*)m_caster, this->gameObjTarget); + sLog.outDebug("Send Event Horde Flag Picked Up"); + break; + /* not used : + case 23334: // Drop Horde Flag + if(bg->GetTypeID()==BATTLEGROUND_WS) + bg->EventPlayerDroppedFlag((Player*)m_caster); + sLog.outDebug("Drop Horde Flag"); + break; + */ + case 23335: // Pickup Alliance Flag + /*do not uncomment ... (it will cause crash, because of null targetobject!) anyway this is a bad way to call that event, because it would cause recursion + if(bg->GetTypeID()==BATTLEGROUND_WS) + bg->EventPlayerClickedOnFlag((Player*)m_caster, this->gameObjTarget); + sLog.outDebug("Send Event Alliance Flag Picked Up"); + break; + /* not used : + case 23336: // Drop Alliance Flag + if(bg->GetTypeID()==BATTLEGROUND_WS) + bg->EventPlayerDroppedFlag((Player*)m_caster); + sLog.outDebug("Drop Alliance Flag"); + break; + case 23385: // Alliance Flag Returns + if(bg->GetTypeID()==BATTLEGROUND_WS) + bg->EventPlayerClickedOnFlag((Player*)m_caster, this->gameObjTarget); + sLog.outDebug("Alliance Flag Returned"); + break; + case 23386: // Horde Flag Returns + if(bg->GetTypeID()==BATTLEGROUND_WS) + bg->EventPlayerClickedOnFlag((Player*)m_caster, this->gameObjTarget); + sLog.outDebug("Horde Flag Returned"); + break;*/ + case 34976: + /* + if(bg->GetTypeID()==BATTLEGROUND_EY) + bg->EventPlayerClickedOnFlag((Player*)m_caster, this->gameObjTarget); + */ + break; + default: + sLog.outDebug("Unknown spellid %u in BG event", m_spellInfo->Id); + break; + } + } + } + sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id); + sWorld.ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject); +} + +void Spell::EffectPowerBurn(uint32 i) +{ + if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) + return; + + Powers powertype = Powers(m_spellInfo->EffectMiscValue[i]); + + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + if(unitTarget->getPowerType()!=powertype) + return; + if(damage < 0) + return; + + int32 curPower = int32(unitTarget->GetPower(powertype)); + + // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) + uint32 power = damage; + if ( powertype == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER ) + power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power); + + int32 new_damage = (curPower < power) ? curPower : power; + + unitTarget->ModifyPower(powertype,-new_damage); + float multiplier = m_spellInfo->EffectMultipleValue[i]; + + if(Player *modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); + + new_damage = int32(new_damage*multiplier); + m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, new_damage, m_IsTriggeredSpell, true); +} + +void Spell::EffectHeal( uint32 /*i*/ ) +{ + if( unitTarget && unitTarget->isAlive() && damage >= 0) + { + // Try to get original caster + Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster; + + // Skip if m_originalCaster not available + if (!caster) + return; + + int32 addhealth = damage; + + // Vessel of the Naaru (Vial of the Sunwell trinket) + if (m_spellInfo->Id == 45064) + { + // Amount of heal - depends from stacked Holy Energy + int damageAmount = 0; + Unit::AuraList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + if((*i)->GetId() == 45062) + damageAmount+=(*i)->GetModifier()->m_amount; + if (damageAmount) + m_caster->RemoveAurasDueToSpell(45062); + + addhealth += damageAmount; + } + // Swiftmend - consumes Regrowth or Rejuvenation + else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND)) + { + Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); + // find most short by duration + Aura *targetAura = NULL; + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + { + if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID + && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) ) + { + if(!targetAura || (*i)->GetAuraDuration() < targetAura->GetAuraDuration()) + targetAura = *i; + } + } + + if(!targetAura) + { + sLog.outError("Target(GUID:" I64FMTD ") has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID()); + return; + } + int idx = 0; + while(idx < 3) + { + if(targetAura->GetSpellProto()->EffectApplyAuraName[idx] == SPELL_AURA_PERIODIC_HEAL) + break; + idx++; + } + + int32 tickheal = caster->SpellHealingBonus(targetAura->GetSpellProto(), targetAura->GetModifier()->m_amount, DOT, unitTarget); + int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / targetAura->GetSpellProto()->EffectAmplitude[idx]; + unitTarget->RemoveAurasDueToSpell(targetAura->GetId()); + + addhealth += tickheal * tickcount; + } + else + addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget); + + bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask, m_attackType); + if (crit) + addhealth = caster->SpellCriticalBonus(m_spellInfo, addhealth, unitTarget); + caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, crit); + + int32 gain = unitTarget->ModifyHealth( int32(addhealth) ); + unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo); + + if(caster->GetTypeId()==TYPEID_PLAYER) + if(BattleGround *bg = ((Player*)caster)->GetBattleGround()) + bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain); + + // ignore item heals + if(m_CastItem) + return; + + uint32 procHealer = PROC_FLAG_HEAL; + if (crit) + procHealer |= PROC_FLAG_CRIT_HEAL; + + m_caster->ProcDamageAndSpell(unitTarget,procHealer,PROC_FLAG_HEALED,addhealth,SPELL_SCHOOL_MASK_NONE,m_spellInfo,m_IsTriggeredSpell); + } +} + +void Spell::EffectHealPct( uint32 /*i*/ ) +{ + if( unitTarget && unitTarget->isAlive() && damage >= 0) + { + // Try to get original caster + Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster; + + // Skip if m_originalCaster not available + if (!caster) + return; + + uint32 addhealth = unitTarget->GetMaxHealth() * damage / 100; + caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false); + + int32 gain = unitTarget->ModifyHealth( int32(addhealth) ); + unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo); + + if(caster->GetTypeId()==TYPEID_PLAYER) + if(BattleGround *bg = ((Player*)caster)->GetBattleGround()) + bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain); + } +} + +void Spell::EffectHealMechanical( uint32 /*i*/ ) +{ + // Mechanic creature type should be correctly checked by targetCreatureType field + if( unitTarget && unitTarget->isAlive() && damage >= 0) + { + // Try to get original caster + Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster; + + // Skip if m_originalCaster not available + if (!caster) + return; + + uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget); + caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false); + unitTarget->ModifyHealth( int32(damage) ); + } +} + +void Spell::EffectHealthLeech(uint32 i) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + if(damage < 0) + return; + + sLog.outDebug("HealthLeech :%i", damage); + + float multiplier = m_spellInfo->EffectMultipleValue[i]; + + if(Player *modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); + + int32 new_damage = int32(damage*multiplier); + uint32 curHealth = unitTarget->GetHealth(); + new_damage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, new_damage, m_IsTriggeredSpell, true); + if(curHealth < new_damage) + new_damage = curHealth; + + if(m_caster->isAlive()) + { + new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster); + + m_caster->ModifyHealth(new_damage); + + if(m_caster->GetTypeId() == TYPEID_PLAYER) + m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(new_damage)); + } +} + +void Spell::DoCreateItem(uint32 i, uint32 itemtype) +{ + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player* player = (Player*)unitTarget; + + uint32 newitemid = itemtype; + ItemPrototype const *pProto = objmgr.GetItemPrototype( newitemid ); + if(!pProto) + { + player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + + uint32 num_to_add; + + // TODO: maybe all this can be replaced by using correct calculated `damage` value + if(pProto->Class != ITEM_CLASS_CONSUMABLE || m_spellInfo->SpellFamilyName != SPELLFAMILY_MAGE) + { + int32 basePoints = m_currentBasePoints[i]; + int32 randomPoints = m_spellInfo->EffectDieSides[i]; + if (randomPoints) + num_to_add = basePoints + irand(1, randomPoints); + else + num_to_add = basePoints + 1; + } + else if (pProto->MaxCount == 1) + num_to_add = 1; + else if(player->getLevel() >= m_spellInfo->spellLevel) + { + int32 basePoints = m_currentBasePoints[i]; + float pointPerLevel = m_spellInfo->EffectRealPointsPerLevel[i]; + num_to_add = basePoints + 1 + uint32((player->getLevel() - m_spellInfo->spellLevel)*pointPerLevel); + } + else + num_to_add = 2; + + if (num_to_add < 1) + num_to_add = 1; + if (num_to_add > pProto->Stackable) + num_to_add = pProto->Stackable; + + // init items_count to 1, since 1 item will be created regardless of specialization + int items_count=1; + // the chance to create additional items + float additionalCreateChance=0.0f; + // the maximum number of created additional items + uint8 additionalMaxNum=0; + // get the chance and maximum number for creating extra items + if ( canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum) ) + { + // roll with this chance till we roll not to create or we create the max num + while ( roll_chance_f(additionalCreateChance) && items_count<=additionalMaxNum ) + ++items_count; + } + + // really will be created more items + num_to_add *= items_count; + + // can the player store the new item? + ItemPosCountVec dest; + uint32 no_space = 0; + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, newitemid, num_to_add, &no_space ); + if( msg != EQUIP_ERR_OK ) + { + // convert to possible store amount + if( msg == EQUIP_ERR_INVENTORY_FULL || msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS ) + num_to_add -= no_space; + else + { + // if not created by another reason from full inventory or unique items amount limitation + player->SendEquipError( msg, NULL, NULL ); + return; + } + } + + if(num_to_add) + { + // create the new item and store it + Item* pItem = player->StoreNewItem( dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid)); + + // was it successful? return error if not + if(!pItem) + { + player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + + // set the "Crafted by ..." property of the item + if( pItem->GetProto()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetProto()->Class != ITEM_CLASS_QUEST) + pItem->SetUInt32Value(ITEM_FIELD_CREATOR,player->GetGUIDLow()); + + // send info to the client + if(pItem) + player->SendNewItem(pItem, num_to_add, true, true); + + // we succeeded in creating at least one item, so a levelup is possible + player->UpdateCraftSkill(m_spellInfo->Id); + } + + // for battleground marks send by mail if not add all expected + if(no_space > 0 ) + { + BattleGroundTypeId bgType; + switch(m_spellInfo->Id) + { + case SPELL_AV_MARK_WINNER: + case SPELL_AV_MARK_LOSER: + bgType = BATTLEGROUND_AV; + break; + case SPELL_WS_MARK_WINNER: + case SPELL_WS_MARK_LOSER: + bgType = BATTLEGROUND_WS; + break; + case SPELL_AB_MARK_WINNER: + case SPELL_AB_MARK_LOSER: + bgType = BATTLEGROUND_AB; + break; + default: + return; + } + + if(BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgType)) + bg->SendRewardMarkByMail(player,newitemid,no_space); + } +} + +void Spell::EffectCreateItem(uint32 i) +{ + DoCreateItem(i,m_spellInfo->EffectItemType[i]); +} + +void Spell::EffectPersistentAA(uint32 i) +{ + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius); + + int32 duration = GetSpellDuration(m_spellInfo); + DynamicObject* dynObj = new DynamicObject; + if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius)) + { + delete dynObj; + return; + } + dynObj->SetUInt32Value(OBJECT_FIELD_TYPE, 65); + dynObj->SetUInt32Value(GAMEOBJECT_DISPLAYID, 368003); + dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x01eeeeee); + m_caster->AddDynObject(dynObj); + MapManager::Instance().GetMap(dynObj->GetMapId(), dynObj)->Add(dynObj); +} + +void Spell::EffectEnergize(uint32 i) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) + return; + + // Some level depends spells + int multipler = 0; + int level_diff = 0; + switch (m_spellInfo->Id) + { + // Restore Energy + case 9512: + level_diff = m_caster->getLevel() - 40; + multipler = 2; + break; + // Blood Fury + case 24571: + level_diff = m_caster->getLevel() - 60; + multipler = 10; + break; + // Burst of Energy + case 24532: + level_diff = m_caster->getLevel() - 60; + multipler = 4; + break; + default: + break; + } + + if (level_diff > 0) + damage -= multipler * level_diff; + + if(damage < 0) + return; + + Powers power = Powers(m_spellInfo->EffectMiscValue[i]); + + if(unitTarget->GetMaxPower(power) == 0) + return; + + unitTarget->ModifyPower(power,damage); + m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, damage, power); + + // Mad Alchemist's Potion + if (m_spellInfo->Id == 45051) + { + // find elixirs on target + uint32 elixir_mask = 0; + Unit::AuraMap& Auras = unitTarget->GetAuras(); + for(Unit::AuraMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr) + { + uint32 spell_id = itr->second->GetId(); + if(uint32 mask = spellmgr.GetSpellElixirMask(spell_id)) + elixir_mask |= mask; + } + + // get available elixir mask any not active type from battle/guardian (and flask if no any) + elixir_mask = (elixir_mask & ELIXIR_FLASK_MASK) ^ ELIXIR_FLASK_MASK; + + // get all available elixirs by mask and spell level + std::vector elixirs; + SpellElixirMap const& m_spellElixirs = spellmgr.GetSpellElixirMap(); + for(SpellElixirMap::const_iterator itr = m_spellElixirs.begin(); itr != m_spellElixirs.end(); ++itr) + { + if (itr->second & elixir_mask) + { + if (itr->second & (ELIXIR_UNSTABLE_MASK | ELIXIR_SHATTRATH_MASK)) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (spellInfo && (spellInfo->spellLevel < m_spellInfo->spellLevel || spellInfo->spellLevel > unitTarget->getLevel())) + continue; + + elixirs.push_back(itr->first); + } + } + + if (!elixirs.empty()) + { + // cast random elixir on target + uint32 rand_spell = urand(0,elixirs.size()-1); + m_caster->CastSpell(unitTarget,elixirs[rand_spell],true,m_CastItem); + } + } +} + +void Spell::EffectEnergisePct(uint32 i) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) + return; + + Powers power = Powers(m_spellInfo->EffectMiscValue[i]); + + uint32 maxPower = unitTarget->GetMaxPower(power); + if(maxPower == 0) + return; + + uint32 gain = damage * maxPower / 100; + unitTarget->ModifyPower(power, gain); + m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, damage, power); +} + +void Spell::SendLoot(uint64 guid, LootType loottype) +{ + Player* player = (Player*)m_caster; + if (!player) + return; + + if (gameObjTarget) + { + switch (gameObjTarget->GetGoType()) + { + case GAMEOBJECT_TYPE_DOOR: + case GAMEOBJECT_TYPE_BUTTON: + gameObjTarget->UseDoorOrButton(); + sWorld.ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget); + return; + + case GAMEOBJECT_TYPE_QUESTGIVER: + // start or end quest + player->PrepareQuestMenu(guid); + player->SendPreparedQuest(guid); + return; + + case GAMEOBJECT_TYPE_SPELL_FOCUS: + // triggering linked GO + if(uint32 trapEntry = gameObjTarget->GetGOInfo()->spellFocus.linkedTrapId) + gameObjTarget->TriggeringLinkedGameObject(trapEntry,m_caster); + return; + + case GAMEOBJECT_TYPE_GOOBER: + // goober_scripts can be triggered if the player don't have the quest + if (gameObjTarget->GetGOInfo()->goober.eventId) + { + sLog.outDebug("Goober ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->goober.eventId,gameObjTarget->GetDBTableGUIDLow()); + sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->goober.eventId, player, gameObjTarget); + } + + // cast goober spell + if (gameObjTarget->GetGOInfo()->goober.questId) + ///Quest require to be active for GO using + if(player->GetQuestStatus(gameObjTarget->GetGOInfo()->goober.questId) != QUEST_STATUS_INCOMPLETE) + return; + + gameObjTarget->AddUniqueUse(player); + gameObjTarget->SetLootState(GO_JUST_DEACTIVATED); + + //TODO? Objective counting called without spell check but with quest objective check + // if send spell id then this line will duplicate to spell casting call (double counting) + // So we or have this line and not required in quest_template have reqSpellIdN + // or must remove this line and required in DB have data in quest_template have reqSpellIdN for all quest using cases. + player->CastedCreatureOrGO(gameObjTarget->GetEntry(), gameObjTarget->GetGUID(), 0); + + // triggering linked GO + if(uint32 trapEntry = gameObjTarget->GetGOInfo()->goober.linkedTrapId) + gameObjTarget->TriggeringLinkedGameObject(trapEntry,m_caster); + + return; + + case GAMEOBJECT_TYPE_CHEST: + // TODO: possible must be moved to loot release (in different from linked triggering) + if (gameObjTarget->GetGOInfo()->chest.eventId) + { + sLog.outDebug("Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId,gameObjTarget->GetDBTableGUIDLow()); + sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget); + } + + // triggering linked GO + if(uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId) + gameObjTarget->TriggeringLinkedGameObject(trapEntry,m_caster); + + // Don't return, let loots been taken + } + } + + // Send loot + player->SendLoot(guid, loottype); +} + +void Spell::EffectOpenLock(uint32 /*i*/) +{ + if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER) + { + sLog.outDebug( "WORLD: Open Lock - No Player Caster!"); + return; + } + + Player* player = (Player*)m_caster; + + LootType loottype = LOOT_CORPSE; + uint32 lockId = 0; + uint64 guid = 0; + + // Get lockId + if(gameObjTarget) + { + GameObjectInfo const* goInfo = gameObjTarget->GetGOInfo(); + // Arathi Basin banner opening ! + if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune || + goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK ) + { + //isAllowUseBattleGroundObject() already called in CanCast() + // in battleground check + if(BattleGround *bg = player->GetBattleGround()) + { + // check if it's correct bg + if(bg && bg->GetTypeID() == BATTLEGROUND_AB) + bg->EventPlayerClickedOnFlag(player, gameObjTarget); + return; + } + } + else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND) + { + //isAllowUseBattleGroundObject() already called in CanCast() + // in battleground check + if(BattleGround *bg = player->GetBattleGround()) + { + if(bg->GetTypeID() == BATTLEGROUND_EY) + bg->EventPlayerClickedOnFlag(player, gameObjTarget); + return; + } + } + lockId = gameObjTarget->GetLockId(); + guid = gameObjTarget->GetGUID(); + } + else if(itemTarget) + { + lockId = itemTarget->GetProto()->LockID; + guid = itemTarget->GetGUID(); + } + else + { + sLog.outDebug( "WORLD: Open Lock - No GameObject/Item Target!"); + return; + } + + if(!lockId) // possible case for GO and maybe for items. + { + SendLoot(guid, loottype); + return; + } + + // Get LockInfo + LockEntry const *lockInfo = sLockStore.LookupEntry(lockId); + + if (!lockInfo) + { + sLog.outError( "Spell::EffectOpenLock: %s [guid = %u] has an unknown lockId: %u!", + (gameObjTarget ? "gameobject" : "item"), GUID_LOPART(guid), lockId); + SendCastResult(SPELL_FAILED_BAD_TARGETS); + return; + } + + // check key + for(int i = 0; i < 5; ++i) + { + // type==1 This means lockInfo->key[i] is an item + if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i]) + { + SendLoot(guid, loottype); + return; + } + } + + uint32 SkillId = 0; + // Check and skill-up skill + if( m_spellInfo->Effect[1] == SPELL_EFFECT_SKILL ) + SkillId = m_spellInfo->EffectMiscValue[1]; + // pickpocketing spells + else if( m_spellInfo->EffectMiscValue[0] == LOCKTYPE_PICKLOCK ) + SkillId = SKILL_LOCKPICKING; + + // skill bonus provided by casting spell (mostly item spells) + uint32 spellSkillBonus = uint32(m_currentBasePoints[0]+1); + + uint32 reqSkillValue = lockInfo->requiredminingskill; + + if(lockInfo->requiredlockskill) // required pick lock skill applying + { + if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?) + { + SendCastResult(SPELL_FAILED_FIZZLE); + return; + } + + reqSkillValue = lockInfo->requiredlockskill; + } + else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target + { + SendCastResult(SPELL_FAILED_BAD_TARGETS); + return; + } + + if ( SkillId ) + { + loottype = LOOT_SKINNING; + if ( player->GetSkillValue(SkillId) + spellSkillBonus < reqSkillValue ) + { + SendCastResult(SPELL_FAILED_LOW_CASTLEVEL); + return; + } + + // update skill if really known + uint32 SkillValue = player->GetPureSkillValue(SkillId); + if(SkillValue) // non only item base skill + { + if(gameObjTarget) + { + // Allow one skill-up until respawned + if ( !gameObjTarget->IsInSkillupList( player->GetGUIDLow() ) && + player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue) ) + gameObjTarget->AddToSkillupList( player->GetGUIDLow() ); + } + else if(itemTarget) + { + // Do one skill-up + uint32 SkillValue = player->GetPureSkillValue(SkillId); + player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue); + } + } + } + + SendLoot(guid, loottype); +} + +void Spell::EffectSummonChangeItem(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player *player = (Player*)m_caster; + + // applied only to using item + if(!m_CastItem) + return; + + // ... only to item in own inventory/bank/equip_slot + if(m_CastItem->GetOwnerGUID()!=player->GetGUID()) + return; + + uint32 newitemid = m_spellInfo->EffectItemType[i]; + if(!newitemid) + return; + + uint16 pos = m_CastItem->GetPos(); + + Item *pNewItem = Item::CreateItem( newitemid, 1, player); + if( !pNewItem ) + return; + + for(uint8 i= PERM_ENCHANTMENT_SLOT; i<=TEMP_ENCHANTMENT_SLOT; ++i) + { + if(m_CastItem->GetEnchantmentId(EnchantmentSlot(i))) + pNewItem->SetEnchantment(EnchantmentSlot(i), m_CastItem->GetEnchantmentId(EnchantmentSlot(i)), m_CastItem->GetEnchantmentDuration(EnchantmentSlot(i)), m_CastItem->GetEnchantmentCharges(EnchantmentSlot(i))); + } + + if(m_CastItem->GetUInt32Value(ITEM_FIELD_DURABILITY) < m_CastItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) + { + double loosePercent = 1 - m_CastItem->GetUInt32Value(ITEM_FIELD_DURABILITY) / double(m_CastItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); + player->DurabilityLoss(pNewItem, loosePercent); + } + + if( player->IsInventoryPos( pos ) ) + { + ItemPosCountVec dest; + uint8 msg = player->CanStoreItem( m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true ); + if( msg == EQUIP_ERR_OK ) + { + player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(),true); + + // prevent crash at access and unexpected charges counting with item update queue corrupt + if(m_CastItem==m_targets.getItemTarget()) + m_targets.setItemTarget(NULL); + + m_CastItem = NULL; + + player->StoreItem( dest, pNewItem, true); + return; + } + } + else if( player->IsBankPos ( pos ) ) + { + ItemPosCountVec dest; + uint8 msg = player->CanBankItem( m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true ); + if( msg == EQUIP_ERR_OK ) + { + player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(),true); + + // prevent crash at access and unexpected charges counting with item update queue corrupt + if(m_CastItem==m_targets.getItemTarget()) + m_targets.setItemTarget(NULL); + + m_CastItem = NULL; + + player->BankItem( dest, pNewItem, true); + return; + } + } + else if( player->IsEquipmentPos ( pos ) ) + { + uint16 dest; + uint8 msg = player->CanEquipItem( m_CastItem->GetSlot(), dest, pNewItem, true ); + if( msg == EQUIP_ERR_OK ) + { + player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(),true); + + // prevent crash at access and unexpected charges counting with item update queue corrupt + if(m_CastItem==m_targets.getItemTarget()) + m_targets.setItemTarget(NULL); + + m_CastItem = NULL; + + player->EquipItem( dest, pNewItem, true); + player->AutoUnequipOffhandIfNeed(); + return; + } + } + + // fail + delete pNewItem; +} + +void Spell::EffectOpenSecretSafe(uint32 i) +{ + EffectOpenLock(i); //no difference for now +} + +void Spell::EffectProficiency(uint32 /*i*/) +{ + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + Player *p_target = (Player*)unitTarget; + + uint32 subClassMask = m_spellInfo->EquippedItemSubClassMask; + if(m_spellInfo->EquippedItemClass == 2 && !(p_target->GetWeaponProficiency() & subClassMask)) + { + p_target->AddWeaponProficiency(subClassMask); + p_target->SendProficiency(uint8(0x02),p_target->GetWeaponProficiency()); + } + if(m_spellInfo->EquippedItemClass == 4 && !(p_target->GetArmorProficiency() & subClassMask)) + { + p_target->AddArmorProficiency(subClassMask); + p_target->SendProficiency(uint8(0x04),p_target->GetArmorProficiency()); + } +} + +void Spell::EffectApplyAreaAura(uint32 i) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + AreaAura* Aur = new AreaAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, m_caster, m_CastItem); + unitTarget->AddAura(Aur); +} + +void Spell::EffectSummonType(uint32 i) +{ + switch(m_spellInfo->EffectMiscValueB[i]) + { + case SUMMON_TYPE_GUARDIAN: + case SUMMON_TYPE_POSESSED: + case SUMMON_TYPE_POSESSED2: + EffectSummonGuardian(i); + break; + case SUMMON_TYPE_WILD: + EffectSummonWild(i); + break; + case SUMMON_TYPE_DEMON: + EffectSummonDemon(i); + break; + case SUMMON_TYPE_SUMMON: + EffectSummon(i); + break; + case SUMMON_TYPE_CRITTER: + case SUMMON_TYPE_CRITTER2: + case SUMMON_TYPE_CRITTER3: + EffectSummonCritter(i); + break; + case SUMMON_TYPE_TOTEM_SLOT1: + case SUMMON_TYPE_TOTEM_SLOT2: + case SUMMON_TYPE_TOTEM_SLOT3: + case SUMMON_TYPE_TOTEM_SLOT4: + case SUMMON_TYPE_TOTEM: + EffectSummonTotem(i); + break; + case SUMMON_TYPE_UNKNOWN1: + case SUMMON_TYPE_UNKNOWN2: + case SUMMON_TYPE_UNKNOWN3: + case SUMMON_TYPE_UNKNOWN4: + case SUMMON_TYPE_UNKNOWN5: + break; + default: + sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]); + break; + } +} + +void Spell::EffectSummon(uint32 i) +{ + if(m_caster->GetPetGUID()) + return; + + if(!unitTarget) + return; + uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; + if(!pet_entry) + return; + uint32 level = m_caster->getLevel(); + Pet* spawnCreature = new Pet(SUMMON_PET); + + if(spawnCreature->LoadPetFromDB(m_caster,pet_entry)) + { + // set timer for unsummon + int32 duration = GetSpellDuration(m_spellInfo); + if(duration > 0) + spawnCreature->SetDuration(duration); + + return; + } + + Map *map = m_caster->GetMap(); + uint32 pet_number = objmgr.GeneratePetNumber(); + if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),map,m_spellInfo->EffectMiscValue[i], pet_number)) + { + sLog.outErrorDb("Spell::EffectSummon: no such creature entry %u",m_spellInfo->EffectMiscValue[i]); + delete spawnCreature; + return; + } + + // Summon in dest location + float x,y,z; + if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + } + else + m_caster->GetClosePoint(x,y,z,spawnCreature->GetObjectSize()); + + spawnCreature->Relocate(x,y,z,-m_caster->GetOrientation()); + + if(!spawnCreature->IsPositionValid()) + { + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %d Y: ^%d)", spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY()); + delete spawnCreature; + return; + } + + // set timer for unsummon + int32 duration = GetSpellDuration(m_spellInfo); + if(duration > 0) + spawnCreature->SetDuration(duration); + + spawnCreature->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID()); + spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0); + spawnCreature->setPowerType(POWER_MANA); + spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); + spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0); + spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_0,2048); + spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); + spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); + spawnCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); + spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); + spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); + spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + + spawnCreature->InitStatsForLevel(level); + + spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false); + + spawnCreature->AIM_Initialize(); + spawnCreature->InitPetCreateSpells(); + spawnCreature->SetHealth(spawnCreature->GetMaxHealth()); + spawnCreature->SetPower(POWER_MANA, spawnCreature->GetMaxPower(POWER_MANA)); + + std::string name = m_caster->GetName(); + name.append(petTypeSuffix[spawnCreature->getPetType()]); + spawnCreature->SetName( name ); + + map->Add((Creature*)spawnCreature); + + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + m_caster->SetPet(spawnCreature); + spawnCreature->GetCharmInfo()->SetReactState( REACT_DEFENSIVE ); + spawnCreature->SavePetToDB(PET_SAVE_AS_CURRENT); + ((Player*)m_caster)->PetSpellInitialize(); + } +} + +void Spell::EffectLearnSpell(uint32 i) +{ + if(!unitTarget) + return; + + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + { + if(m_caster->GetTypeId() == TYPEID_PLAYER) + EffectLearnPetSpell(i); + + return; + } + + Player *player = (Player*)unitTarget; + + uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i]; + player->learnSpell(spellToLearn); + + sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() ); +} + +void Spell::EffectDispel(uint32 i) +{ + if(!unitTarget) + return; + + // Fill possible dispell list + std::vector dispel_list; + + // Create dispel mask by dispel type + uint32 dispel_type = m_spellInfo->EffectMiscValue[i]; + uint32 dispelMask = GetDispellMask( DispelType(dispel_type) ); + Unit::AuraMap const& auras = unitTarget->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + Aura *aur = (*itr).second; + if (aur && (1<GetSpellProto()->Dispel) & dispelMask) + { + if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC) + { + bool positive = true; + if (!aur->IsPositive()) + positive = false; + else + positive = (aur->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)==0; + + // do not remove positive auras if friendly target + // negative auras if non-friendly target + if(positive == unitTarget->IsFriendlyTo(m_caster)) + continue; + } + // Add aura to dispel list + dispel_list.push_back(aur); + } + } + // Ok if exist some buffs for dispel try dispel it + if (!dispel_list.empty()) + { + std::list < std::pair > success_list;// (spell_id,casterGuid) + std::list < uint32 > fail_list; // spell_id + int32 list_size = dispel_list.size(); + // Dispell N = damage buffs (or while exist buffs for dispel) + for (int32 count=0; count < damage && list_size > 0; ++count) + { + // Random select buff for dispel + Aura *aur = dispel_list[urand(0, list_size-1)]; + + SpellEntry const* spellInfo = aur->GetSpellProto(); + // Base dispel chance + // TODO: possible chance depend from spell level?? + int32 miss_chance = 0; + // Apply dispel mod from aura caster + if (Unit *caster = aur->GetCaster()) + { + if ( Player* modOwner = caster->GetSpellModOwner() ) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, this); + } + // Try dispel + if (roll_chance_i(miss_chance)) + fail_list.push_back(aur->GetId()); + else + success_list.push_back(std::pair(aur->GetId(),aur->GetCasterGUID())); + // Remove buff from list for prevent doubles + for (std::vector::iterator j = dispel_list.begin(); j != dispel_list.end(); ) + { + Aura *dispeled = *j; + if (dispeled->GetId() == aur->GetId() && dispeled->GetCasterGUID() == aur->GetCasterGUID()) + { + j = dispel_list.erase(j); + --list_size; + } + else + ++j; + } + } + // Send success log and really remove auras + if (!success_list.empty()) + { + int32 count = success_list.size(); + WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+1+4+count*5); + data.append(unitTarget->GetPackGUID()); // Victim GUID + data.append(m_caster->GetPackGUID()); // Caster GUID + data << uint32(m_spellInfo->Id); // Dispell spell id + data << uint8(0); // not used + data << uint32(count); // count + for (std::list >::iterator j = success_list.begin(); j != success_list.end(); ++j) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first); + data << uint32(spellInfo->Id); // Spell Id + data << uint8(0); // 0 - dispeled !=0 cleansed + unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster); + } + m_caster->SendMessageToSet(&data, true); + + // On succes dispel + // Devour Magic + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == 12) + { + uint32 heal_spell = 0; + switch (m_spellInfo->Id) + { + case 19505: heal_spell = 19658; break; + case 19731: heal_spell = 19732; break; + case 19734: heal_spell = 19733; break; + case 19736: heal_spell = 19735; break; + case 27276: heal_spell = 27278; break; + case 27277: heal_spell = 27279; break; + default: + sLog.outDebug("Spell for Devour Magic %d not handled in Spell::EffectDispel", m_spellInfo->Id); + break; + } + if (heal_spell) + m_caster->CastSpell(m_caster, heal_spell, true); + } + } + // Send fail log to client + if (!fail_list.empty()) + { + // Failed to dispell + WorldPacket data(SMSG_DISPEL_FAILED, 8+8+4+4*fail_list.size()); + data << uint64(m_caster->GetGUID()); // Caster GUID + data << uint64(unitTarget->GetGUID()); // Victim GUID + data << uint32(m_spellInfo->Id); // Dispell spell id + for (std::list< uint32 >::iterator j = fail_list.begin(); j != fail_list.end(); ++j) + data << uint32(*j); // Spell Id + m_caster->SendMessageToSet(&data, true); + } + } +} + +void Spell::EffectDualWield(uint32 /*i*/) +{ + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->SetCanDualWield(true); +} + +void Spell::EffectPull(uint32 /*i*/) +{ + // TODO: create a proper pull towards distract spell center for distract + sLog.outDebug("WORLD: Spell Effect DUMMY"); +} + +void Spell::EffectDistract(uint32 /*i*/) +{ + // Check for possible target + if (!unitTarget || unitTarget->isInCombat()) + return; + + // target must be OK to do this + if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING ) ) + return; + + float angle = unitTarget->GetAngle(m_targets.m_destX, m_targets.m_destY); + + if ( unitTarget->GetTypeId() == TYPEID_PLAYER ) + { + // For players just turn them + WorldPacket data; + ((Player*)unitTarget)->BuildTeleportAckMsg(&data, unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), angle); + ((Player*)unitTarget)->GetSession()->SendPacket( &data ); + ((Player*)unitTarget)->SetPosition(unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), angle, false); + } + else + { + // Set creature Distracted, Stop it, And turn it + unitTarget->SetOrientation(angle); + unitTarget->StopMoving(); + unitTarget->GetMotionMaster()->MoveDistract(damage*1000); + } +} + +void Spell::EffectPickPocket(uint32 /*i*/) +{ + if( m_caster->GetTypeId() != TYPEID_PLAYER ) + return; + + // victim must be creature and attackable + if( !unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || m_caster->IsFriendlyTo(unitTarget) ) + return; + + // victim have to be alive and humanoid or undead + if( unitTarget->isAlive() && (unitTarget->GetCreatureTypeMask() &CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) != 0) + { + int32 chance = 10 + int32(m_caster->getLevel()) - int32(unitTarget->getLevel()); + + if (chance > irand(0, 19)) + { + // Stealing successful + //sLog.outDebug("Sending loot from pickpocket"); + ((Player*)m_caster)->SendLoot(unitTarget->GetGUID(),LOOT_PICKPOCKETING); + } + else + { + // Reveal action + get attack + m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + if (((Creature*)unitTarget)->AI()) + ((Creature*)unitTarget)->AI()->AttackStart(m_caster); + } + } +} + +void Spell::EffectAddFarsight(uint32 i) +{ + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + int32 duration = GetSpellDuration(m_spellInfo); + DynamicObject* dynObj = new DynamicObject; + if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius)) + { + delete dynObj; + return; + } + dynObj->SetUInt32Value(OBJECT_FIELD_TYPE, 65); + dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002); + m_caster->AddDynObject(dynObj); + MapManager::Instance().GetMap(dynObj->GetMapId(), dynObj)->Add(dynObj); + m_caster->SetUInt64Value(PLAYER_FARSIGHT, dynObj->GetGUID()); +} + +void Spell::EffectSummonWild(uint32 i) +{ + uint32 creature_entry = m_spellInfo->EffectMiscValue[i]; + if(!creature_entry) + return; + + uint32 level = m_caster->getLevel(); + + // level of creature summoned using engineering item based at engineering skill level + if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem) + { + ItemPrototype const *proto = m_CastItem->GetProto(); + if(proto && proto->RequiredSkill == SKILL_ENGINERING) + { + uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING); + if(skill202) + { + level = skill202/5; + } + } + } + + // select center of summon position + float center_x = m_targets.m_destX; + float center_y = m_targets.m_destY; + float center_z = m_targets.m_destZ; + + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + + int32 amount = damage > 0 ? damage : 1; + + for(int32 count = 0; count < amount; ++count) + { + float px, py, pz; + // If dest location if present + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + // Summon 1 unit in dest location + if (count == 0) + { + px = m_targets.m_destX; + py = m_targets.m_destY; + pz = m_targets.m_destZ; + } + // Summon in random point all other units if location present + else + m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); + } + // Summon if dest location not present near caster + else + m_caster->GetClosePoint(px,py,pz,3.0f); + + int32 duration = GetSpellDuration(m_spellInfo); + + TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; + + m_caster->SummonCreature(creature_entry,px,py,pz,m_caster->GetOrientation(),summonType,duration); + } +} + +void Spell::EffectSummonGuardian(uint32 i) +{ + uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; + if(!pet_entry) + return; + + // Jewelery statue case (totem like) + if(m_spellInfo->SpellIconID==2056) + { + EffectSummonTotem(i); + return; + } + + // set timer for unsummon + int32 duration = GetSpellDuration(m_spellInfo); + + // Search old Guardian only for players (if casted spell not have duration or cooldown) + // FIXME: some guardians have control spell applied and controlled by player and anyway player can't summon in this time + // so this code hack in fact + if( m_caster->GetTypeId() == TYPEID_PLAYER && (duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0) ) + if(((Player*)m_caster)->HasGuardianWithEntry(pet_entry)) + return; // find old guardian, ignore summon + + // in another case summon new + uint32 level = m_caster->getLevel(); + + // level of pet summoned using engineering item based at engineering skill level + if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem) + { + ItemPrototype const *proto = m_CastItem->GetProto(); + if(proto && proto->RequiredSkill == SKILL_ENGINERING) + { + uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING); + if(skill202) + { + level = skill202/5; + } + } + } + + // select center of summon position + float center_x = m_targets.m_destX; + float center_y = m_targets.m_destY; + float center_z = m_targets.m_destZ; + + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + + int32 amount = damage > 0 ? damage : 1; + + for(int32 count = 0; count < amount; ++count) + { + Pet* spawnCreature = new Pet(GUARDIAN_PET); + + Map *map = m_caster->GetMap(); + uint32 pet_number = objmgr.GeneratePetNumber(); + if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map,m_spellInfo->EffectMiscValue[i], pet_number)) + { + sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]); + delete spawnCreature; + return; + } + + float px, py, pz; + // If dest location if present + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + // Summon 1 unit in dest location + if (count == 0) + { + px = m_targets.m_destX; + py = m_targets.m_destY; + pz = m_targets.m_destZ; + } + // Summon in random point all other units if location present + else + m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); + } + // Summon if dest location not present near caster + else + m_caster->GetClosePoint(px,py,pz,spawnCreature->GetObjectSize()); + + spawnCreature->Relocate(px,py,pz,m_caster->GetOrientation()); + + if(!spawnCreature->IsPositionValid()) + { + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %d Y: ^%d)", spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY()); + delete spawnCreature; + return; + } + + if(duration > 0) + spawnCreature->SetDuration(duration); + + spawnCreature->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID()); + spawnCreature->setPowerType(POWER_MANA); + spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0); + spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); + spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0); + spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); + spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); + spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); + spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + + spawnCreature->InitStatsForLevel(level); + spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false); + + spawnCreature->AIM_Initialize(); + + if(m_caster->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_caster)->AddGuardian(spawnCreature); + + map->Add((Creature*)spawnCreature); + } +} + +void Spell::EffectTeleUnitsFaceCaster(uint32 i) +{ + if(!unitTarget) + return; + + if(unitTarget->isInFlight()) + return; + + uint32 mapid = m_caster->GetMapId(); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + + float fx,fy,fz; + m_caster->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis); + + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, -m_caster->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); + else + MapManager::Instance().GetMap(mapid, m_caster)->CreatureRelocation((Creature*)m_caster, fx, fy, fz, -m_caster->GetOrientation()); +} + +void Spell::EffectLearnSkill(uint32 i) +{ + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + if(damage < 0) + return; + + uint32 skillid = m_spellInfo->EffectMiscValue[i]; + uint16 skillval = ((Player*)unitTarget)->GetPureSkillValue(skillid); + ((Player*)unitTarget)->SetSkill(skillid, skillval?skillval:1, damage*75); +} + +void Spell::EffectAddHonor(uint32 /*i*/) +{ + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + sLog.outDebug("SpellEffect::AddHonor called for spell_id %u , that rewards %d honor points to player: %u", m_spellInfo->Id, this->damage, ((Player*)unitTarget)->GetGUIDLow()); + + // TODO: find formula for honor reward based on player's level! + + // now fixed only for level 70 players: + if (((Player*)unitTarget)->getLevel() == 70) + ((Player*)unitTarget)->RewardHonor(NULL, 1, this->damage); +} + +void Spell::EffectTradeSkill(uint32 /*i*/) +{ + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + // uint32 skillid = m_spellInfo->EffectMiscValue[i]; + // uint16 skillmax = ((Player*)unitTarget)->(skillid); + // ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75); +} + +void Spell::EffectEnchantItemPerm(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + if (!itemTarget) + return; + + Player* p_caster = (Player*)m_caster; + + p_caster->UpdateCraftSkill(m_spellInfo->Id); + + if (m_spellInfo->EffectMiscValue[i]) + { + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return; + + // item can be in trade slot and have owner diff. from caster + Player* item_owner = itemTarget->GetOwner(); + if(!item_owner) + return; + + if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + sLog.outCommand("GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", + p_caster->GetName(),p_caster->GetSession()->GetAccountId(), + itemTarget->GetProto()->Name1,itemTarget->GetEntry(), + item_owner->GetName(),item_owner->GetSession()->GetAccountId()); + + // remove old enchanting before applying new if equipped + item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false); + + itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0); + + // add new enchanting if equipped + item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true); + } +} + +void Spell::EffectEnchantItemTmp(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player* p_caster = (Player*)m_caster; + + if(!itemTarget) + return; + + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + + // Shaman Rockbiter Weapon + if(i==0 && m_spellInfo->Effect[1]==SPELL_EFFECT_DUMMY) + { + int32 enchnting_damage = m_currentBasePoints[1]+1; + + // enchanting id selected by calculated damage-per-sec stored in Effect[1] base value + // with already applied percent bonus from Elemental Weapons talent + // Note: damage calculated (correctly) with rounding int32(float(v)) but + // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime + switch(enchnting_damage) + { + // Rank 1 + case 2: enchant_id = 29; break; // 0% [ 7% == 2, 14% == 2, 20% == 2] + // Rank 2 + case 4: enchant_id = 6; break; // 0% [ 7% == 4, 14% == 4] + case 5: enchant_id = 3025; break; // 20% + // Rank 3 + case 6: enchant_id = 1; break; // 0% [ 7% == 6, 14% == 6] + case 7: enchant_id = 3027; break; // 20% + // Rank 4 + case 9: enchant_id = 3032; break; // 0% [ 7% == 6] + case 10: enchant_id = 503; break; // 14% + case 11: enchant_id = 3031; break; // 20% + // Rank 5 + case 15: enchant_id = 3035; break; // 0% + case 16: enchant_id = 1663; break; // 7% + case 17: enchant_id = 3033; break; // 14% + case 18: enchant_id = 3034; break; // 20% + // Rank 6 + case 28: enchant_id = 3038; break; // 0% + case 29: enchant_id = 683; break; // 7% + case 31: enchant_id = 3036; break; // 14% + case 33: enchant_id = 3037; break; // 20% + // Rank 7 + case 40: enchant_id = 3041; break; // 0% + case 42: enchant_id = 1664; break; // 7% + case 45: enchant_id = 3039; break; // 14% + case 48: enchant_id = 3040; break; // 20% + // Rank 8 + case 49: enchant_id = 3044; break; // 0% + case 52: enchant_id = 2632; break; // 7% + case 55: enchant_id = 3042; break; // 14% + case 58: enchant_id = 3043; break; // 20% + // Rank 9 + case 62: enchant_id = 2633; break; // 0% + case 66: enchant_id = 3018; break; // 7% + case 70: enchant_id = 3019; break; // 14% + case 74: enchant_id = 3020; break; // 20% + default: + sLog.outError("Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW",enchnting_damage); + return; + } + } + + if (!enchant_id) + { + sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id",m_spellInfo->Id,i); + return; + } + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + { + sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id %u ",m_spellInfo->Id,i,enchant_id); + return; + } + + // select enchantment duration + uint32 duration; + + // rogue family enchantments exception by duration + if(m_spellInfo->Id==38615) + duration = 1800; // 30 mins + // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints) + else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE) + duration = 3600; // 1 hour + // shaman family enchantments + else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN) + duration = 1800; // 30 mins + // other cases with this SpellVisual already selected + else if(m_spellInfo->SpellVisual==215) + duration = 1800; // 30 mins + // some fishing pole bonuses + else if(m_spellInfo->SpellVisual==563) + duration = 600; // 10 mins + // shaman rockbiter enchantments + else if(m_spellInfo->SpellVisual==0) + duration = 1800; // 30 mins + else if(m_spellInfo->Id==29702) + duration = 300; // 5 mins + else if(m_spellInfo->Id==37360) + duration = 300; // 5 mins + // default case + else + duration = 3600; // 1 hour + + // item can be in trade slot and have owner diff. from caster + Player* item_owner = itemTarget->GetOwner(); + if(!item_owner) + return; + + if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + sLog.outCommand("GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)", + p_caster->GetName(),p_caster->GetSession()->GetAccountId(), + itemTarget->GetProto()->Name1,itemTarget->GetEntry(), + item_owner->GetName(),item_owner->GetSession()->GetAccountId()); + + // remove old enchanting before applying new if equipped + item_owner->ApplyEnchantment(itemTarget,TEMP_ENCHANTMENT_SLOT,false); + + itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration*1000, 0); + + // add new enchanting if equipped + item_owner->ApplyEnchantment(itemTarget,TEMP_ENCHANTMENT_SLOT,true); +} + +void Spell::EffectTameCreature(uint32 /*i*/) +{ + if(m_caster->GetPetGUID()) + return; + + if(!unitTarget) + return; + + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + return; + + Creature* creatureTarget = (Creature*)unitTarget; + + if(creatureTarget->isPet()) + return; + + if(m_caster->getClass() == CLASS_HUNTER) + { + // cast finish successfully + //SendChannelUpdate(0); + finish(); + + Pet* pet = new Pet(HUNTER_PET); + + if(!pet->CreateBaseAtCreature(creatureTarget)) + { + delete pet; + return; + } + + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + + pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); + pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); + pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); + pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + + if(!pet->InitStatsForLevel(creatureTarget->getLevel())) + { + sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); + delete pet; + return; + } + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); + + pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); + // this enables pet details window (Shift+P) + pet->AIM_Initialize(); + pet->InitPetCreateSpells(); + pet->SetHealth(pet->GetMaxHealth()); + + MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); + + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + m_caster->SetPet(pet); + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + ((Player*)m_caster)->PetSpellInitialize(); + } + } +} + +void Spell::EffectSummonPet(uint32 i) +{ + uint32 petentry = m_spellInfo->EffectMiscValue[i]; + + Pet *OldSummon = m_caster->GetPet(); + + // if pet requested type already exist + if( OldSummon ) + { + if(petentry == 0 || OldSummon->GetEntry() == petentry) + { + // pet in corpse state can't be summoned + if( OldSummon->isDead() ) + return; + + MapManager::Instance().GetMap(OldSummon->GetMapId(), OldSummon)->Remove((Creature*)OldSummon,false); + OldSummon->SetMapId(m_caster->GetMapId()); + + float px, py, pz; + m_caster->GetClosePoint(px, py, pz, OldSummon->GetObjectSize()); + + OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation()); + MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)->Add((Creature*)OldSummon); + + if(m_caster->GetTypeId() == TYPEID_PLAYER && OldSummon->isControlled() ) + { + ((Player*)m_caster)->PetSpellInitialize(); + } + return; + } + + if(m_caster->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_caster)->RemovePet(OldSummon,(OldSummon->getPetType()==HUNTER_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT),false); + else + return; + } + + Pet* NewSummon = new Pet; + + // petentry==0 for hunter "call pet" (current pet summoned if any) + if(NewSummon->LoadPetFromDB(m_caster,petentry)) + { + if(NewSummon->getPetType()==SUMMON_PET) + { + // Remove Demonic Sacrifice auras (known pet) + Unit::AuraList const& auraClassScripts = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator itr = auraClassScripts.begin();itr!=auraClassScripts.end();) + { + if((*itr)->GetModifier()->m_miscvalue==2228) + { + m_caster->RemoveAurasDueToSpell((*itr)->GetId()); + itr = auraClassScripts.begin(); + } + else + ++itr; + } + } + + return; + } + + // not error in case fail hunter call pet + if(!petentry) + { + delete NewSummon; + return; + } + + CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(petentry); + + if(!cInfo) + { + sLog.outError("EffectSummonPet: creature entry %u not found.",petentry); + delete NewSummon; + return; + } + + Map *map = m_caster->GetMap(); + uint32 pet_number = objmgr.GeneratePetNumber(); + if(!NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, petentry, pet_number)) + { + delete NewSummon; + return; + } + + float px, py, pz; + m_caster->GetClosePoint(px, py, pz, NewSummon->GetObjectSize()); + + NewSummon->Relocate(px, py, pz, m_caster->GetOrientation()); + + if(!NewSummon->IsPositionValid()) + { + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %d Y: ^%d)", NewSummon->GetGUIDLow(), NewSummon->GetEntry(), NewSummon->GetPositionX(), NewSummon->GetPositionY()); + delete NewSummon; + return; + } + + uint32 petlevel = m_caster->getLevel(); + NewSummon->setPetType(SUMMON_PET); + + uint32 faction = m_caster->getFaction(); + if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isTotem()) + { + Unit* owner = ((Totem*)m_caster)->GetOwner(); + if(owner) + faction = owner->getFaction(); + NewSummon->GetCharmInfo()->SetReactState(REACT_AGGRESSIVE); + } + + NewSummon->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); + NewSummon->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); + NewSummon->SetUInt32Value(UNIT_NPC_FLAGS , 0); + NewSummon->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction); + NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_0,2048); + NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_1,0); + NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,time(NULL)); + NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0); + NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); + NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + + NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true); + // this enables pet details window (Shift+P) + + // this enables popup window (pet dismiss, cancel), hunter pet additional flags set later + NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); + + NewSummon->InitStatsForLevel( petlevel); + NewSummon->InitPetCreateSpells(); + + if(NewSummon->getPetType()==SUMMON_PET) + { + // Remove Demonic Sacrifice auras (new pet) + Unit::AuraList const& auraClassScripts = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator itr = auraClassScripts.begin();itr!=auraClassScripts.end();) + { + if((*itr)->GetModifier()->m_miscvalue==2228) + { + m_caster->RemoveAurasDueToSpell((*itr)->GetId()); + itr = auraClassScripts.begin(); + } + else + ++itr; + } + + // generate new name for summon pet + std::string new_name=objmgr.GeneratePetName(petentry); + if(!new_name.empty()) + NewSummon->SetName(new_name); + } + else if(NewSummon->getPetType()==HUNTER_PET) + NewSummon->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED); + + NewSummon->AIM_Initialize(); + NewSummon->SetHealth(NewSummon->GetMaxHealth()); + NewSummon->SetPower(POWER_MANA, NewSummon->GetMaxPower(POWER_MANA)); + + map->Add((Creature*)NewSummon); + + m_caster->SetPet(NewSummon); + sLog.outDebug("New Pet has guid %u", NewSummon->GetGUIDLow()); + + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + NewSummon->SavePetToDB(PET_SAVE_AS_CURRENT); + ((Player*)m_caster)->PetSpellInitialize(); + } +} + +void Spell::EffectLearnPetSpell(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player *_player = (Player*)m_caster; + + Pet *pet = _player->GetPet(); + if(!pet) + return; + if(!pet->isAlive()) + return; + + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); + if(!learn_spellproto) + return; + + pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id)); + pet->learnSpell(learn_spellproto->Id); + + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + _player->PetSpellInitialize(); +} + +void Spell::EffectTaunt(uint32 /*i*/) +{ + // this effect use before aura Taunt apply for prevent taunt already attacking target + // for spell as marked "non effective at already attacking target" + if(unitTarget && unitTarget->GetTypeId() != TYPEID_PLAYER) + { + if(unitTarget->getVictim()==m_caster) + { + SendCastResult(SPELL_FAILED_DONT_REPORT); + return; + } + } + + // Also use this effect to set the taunter's threat to the taunted creature's highest value + if(unitTarget->CanHaveThreatList() && unitTarget->getThreatManager().getCurrentVictim()) + unitTarget->getThreatManager().addThreat(m_caster,unitTarget->getThreatManager().getCurrentVictim()->getThreat()); +} + +void Spell::EffectWeaponDmg(uint32 i) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + // multiple weapon dmg effect workaround + // execute only the last weapon damage + // and handle all effects at once + for (int j = 0; j < 3; j++) + { + switch(m_spellInfo->Effect[j]) + { + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + if (j < i) // we must calculate only at last weapon effect + return; + break; + } + } + + // some spell specific modifiers + bool customBonusDamagePercentMod = false; + float bonusDamagePercentMod = 1.0f; // applied to fixed effect damage bonus if set customBonusDamagePercentMod + float weaponDamagePercentMod = 1.0f; // applied to weapon damage (and to fixed effect damage bonus if customBonusDamagePercentMod not set + float totalDamagePercentMod = 1.0f; // applied to final bonus+weapon damage + bool normalized = false; + + int32 spell_bonus = 0; // bonus specific for spell + switch(m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_WARRIOR: + { + // Whirlwind, single only spell with 2 weapon white damage apply if have + if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x00000400000000LL)) + { + if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK,true)) + spell_bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized); + } + // Devastate bonus and sunder armor refresh + else if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508) + { + customBonusDamagePercentMod = true; + bonusDamagePercentMod = 0.0f; // only applied if auras found + + Unit::AuraList const& list = unitTarget->GetAurasByType(SPELL_AURA_MOD_RESISTANCE); + for(Unit::AuraList::const_iterator itr=list.begin();itr!=list.end();++itr) + { + SpellEntry const *proto = (*itr)->GetSpellProto(); + if(proto->SpellVisual == 406 && proto->SpellIconID == 565) + { + int32 duration = GetSpellDuration(proto); + (*itr)->SetAuraDuration(duration); + (*itr)->UpdateAuraDuration(); + bonusDamagePercentMod += 1.0f; // +100% + } + } + } + break; + } + case SPELLFAMILY_ROGUE: + { + // Ambush + if(m_spellInfo->SpellFamilyFlags & 0x00000200LL) + { + customBonusDamagePercentMod = true; + bonusDamagePercentMod = 2.5f; // 250% + } + // Mutilate (for each hand) + else if(m_spellInfo->SpellFamilyFlags & 0x600000000LL) + { + bool found = false; + // fast check + if(unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON)) + found = true; + // full aura scan + else + { + Unit::AuraMap const& auras = unitTarget->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + { + if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON) + { + found = true; + break; + } + } + } + + if(found) + totalDamagePercentMod *= 1.5f; // 150% if poisoned + } + break; + } + case SPELLFAMILY_PALADIN: + { + // Seal of Command - receive benefit from Spell Damage and Healing + if(m_spellInfo->SpellFamilyFlags & 0x00000002000000LL) + { + spell_bonus += int32(0.20f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo))); + spell_bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget)); + } + break; + } + case SPELLFAMILY_SHAMAN: + { + // Skyshatter Harness item set bonus + // Stormstrike + if(m_spellInfo->SpellFamilyFlags & 0x001000000000LL) + { + Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i) + { + // Stormstrike AP Buff + if ( (*i)->GetModifier()->m_miscvalue == 5634 ) + { + m_caster->CastSpell(m_caster,38430,true,NULL,*i); + break; + } + } + } + } + } + + int32 fixed_bonus = 0; + for (int j = 0; j < 3; j++) + { + switch(m_spellInfo->Effect[j]) + { + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + fixed_bonus += CalculateDamage(j,unitTarget); + break; + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + fixed_bonus += CalculateDamage(j,unitTarget); + normalized = true; + break; + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + weaponDamagePercentMod *= float(CalculateDamage(j,unitTarget)) / 100.0f; + + // applied only to prev.effects fixed damage + if(customBonusDamagePercentMod) + fixed_bonus = int32(fixed_bonus*bonusDamagePercentMod); + else + fixed_bonus = int32(fixed_bonus*weaponDamagePercentMod); + break; + default: + break; // not weapon damage effect, just skip + } + } + + // non-weapon damage + int32 bonus = spell_bonus + fixed_bonus; + + // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage + if(bonus) + { + UnitMods unitMod; + switch(m_attackType) + { + default: + case BASE_ATTACK: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; + case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; + case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; + } + + float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT); + bonus = int32(bonus*weapon_total_pct); + } + + // + weapon damage with applied weapon% dmg to base weapon damage in call + bonus += int32(m_caster->CalculateDamage(m_attackType, normalized)*weaponDamagePercentMod); + + // total damage + bonus = int32(bonus*totalDamagePercentMod); + + // prevent negative damage + uint32 eff_damage = uint32(bonus > 0 ? bonus : 0); + + const uint32 nohitMask = HITINFO_ABSORB | HITINFO_RESIST | HITINFO_MISS; + + uint32 hitInfo = 0; + VictimState victimState = VICTIMSTATE_NORMAL; + uint32 blocked_dmg = 0; + uint32 absorbed_dmg = 0; + uint32 resisted_dmg = 0; + CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); + + m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, m_spellSchoolMask, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, m_attackType, m_spellInfo, m_IsTriggeredSpell); + + if ((hitInfo & nohitMask) && m_attackType != RANGED_ATTACK) // not send ranged miss/etc + m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, m_spellSchoolMask, eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg); + + bool criticalhit = (hitInfo & HITINFO_CRITICALHIT); + m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, eff_damage, m_spellSchoolMask, absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit); + + if (eff_damage > (absorbed_dmg + resisted_dmg + blocked_dmg)) + { + eff_damage -= (absorbed_dmg + resisted_dmg + blocked_dmg); + } + else + { + cleanDamage.damage += eff_damage; + eff_damage = 0; + } + + // SPELL_SCHOOL_NORMAL use for weapon-like threat and rage calculation + m_caster->DealDamage(unitTarget, eff_damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, true); + + // Hemorrhage + if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & 0x2000000)) + { + if(m_caster->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_caster)->AddComboPoints(unitTarget, 1); + } + + // Mangle (Cat): CP + if(m_spellInfo->SpellFamilyName==SPELLFAMILY_DRUID && (m_spellInfo->SpellFamilyFlags==0x0000040000000000LL)) + { + if(m_caster->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_caster)->AddComboPoints(unitTarget,1); + } + + // take ammo + if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) + { + Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK ); + + // wands don't have ammo + if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND) + return; + + if( pItem->GetProto()->InventoryType == INVTYPE_THROWN ) + { + if(pItem->GetMaxStackCount()==1) + { + // decrease durability for non-stackable throw weapon + ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED); + } + else + { + // decrease items amount for stackable throw weapon + uint32 count = 1; + ((Player*)m_caster)->DestroyItemCount( pItem, count, true); + } + } + else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID)) + ((Player*)m_caster)->DestroyItemCount(ammo, 1, true); + } +} + +void Spell::EffectThreat(uint32 /*i*/) +{ + if(!unitTarget || !unitTarget->isAlive() || !m_caster->isAlive()) + return; + + if(!unitTarget->CanHaveThreatList()) + return; + + unitTarget->AddThreat(m_caster, float(damage)); +} + +void Spell::EffectHealMaxHealth(uint32 /*i*/) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + uint32 heal = m_caster->GetMaxHealth(); + + int32 gain = unitTarget->ModifyHealth(heal); + unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo); + + m_caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, heal); +} + +void Spell::EffectInterruptCast(uint32 /*i*/) +{ + if(!unitTarget) + return; + if(!unitTarget->isAlive()) + return; + + // TODO: not all spells that used this effect apply cooldown at school spells + // also exist case: apply cooldown to interrupted cast only and to all spells + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + { + if (unitTarget->m_currentSpells[i]) + { + // check if we can interrupt spell + if ( unitTarget->m_currentSpells[i]->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT && unitTarget->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE ) + { + unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), GetSpellDuration(m_spellInfo)); + unitTarget->InterruptSpell(i,false); + } + } + } +} + +void Spell::EffectSummonObjectWild(uint32 i) +{ + uint32 gameobject_id = m_spellInfo->EffectMiscValue[i]; + + GameObject* pGameObj = new GameObject; + + WorldObject* target = focusObject; + if( !target ) + target = m_caster; + + float x,y,z; + if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + } + else + m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE); + + Map *map = target->GetMap(); + + if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, + x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1)) + { + delete pGameObj; + return; + } + + int32 duration = GetSpellDuration(m_spellInfo); + pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); + pGameObj->SetSpellId(m_spellInfo->Id); + + if(pGameObj->GetGoType() != GAMEOBJECT_TYPE_FLAGDROP) // make dropped flag clickable for other players (not set owner guid (created by) for this)... + m_caster->AddGameObject(pGameObj); + map->Add(pGameObj); + + if(pGameObj->GetMapId() == 489 && pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP) //WS + { + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + Player *pl = (Player*)m_caster; + BattleGround* bg = ((Player *)m_caster)->GetBattleGround(); + if(bg && bg->GetTypeID()==BATTLEGROUND_WS && bg->GetStatus() == STATUS_IN_PROGRESS) + { + uint32 team = ALLIANCE; + + if(pl->GetTeam() == team) + team = HORDE; + + ((BattleGroundWS*)bg)->SetDroppedFlagGUID(pGameObj->GetGUID(),team); + } + } + } + + if(pGameObj->GetMapId() == 566 && pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP) //EY + { + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + BattleGround* bg = ((Player *)m_caster)->GetBattleGround(); + if(bg && bg->GetTypeID()==BATTLEGROUND_EY && bg->GetStatus() == STATUS_IN_PROGRESS) + { + ((BattleGroundEY*)bg)->SetDroppedFlagGUID(pGameObj->GetGUID()); + } + } + } + + if(uint32 linkedEntry = pGameObj->GetLinkedGameObjectEntry()) + { + GameObject* linkedGO = new GameObject; + if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map, + x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1)) + { + linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); + linkedGO->SetSpellId(m_spellInfo->Id); + + m_caster->AddGameObject(linkedGO); + map->Add(linkedGO); + } + else + { + delete linkedGO; + linkedGO = NULL; + return; + } + } +} + +void Spell::EffectScriptEffect(uint32 effIndex) +{ + // TODO: we must implement hunter pet summon at login there (spell 6962) + + // by spell id + switch(m_spellInfo->Id) + { + // Bending Shinbone + case 8856: + { + if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + uint32 spell_id = 0; + switch(urand(1,5)) + { + case 1: spell_id = 8854; break; + default: spell_id = 8855; break; + } + + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + + // Healthstone creating spells + case 6201: + case 6202: + case 5699: + case 11729: + case 11730: + case 27230: + { + uint32 itemtype; + uint32 rank = 0; + Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + { + if((*i)->GetId() == 18692) + { + rank = 1; + break; + } + else if((*i)->GetId() == 18693) + { + rank = 2; + break; + } + } + + static uint32 const itypes[6][3] = { + { 5512,19004,19005}, // Minor Healthstone + { 5511,19006,19007}, // Lesser Healthstone + { 5509,19008,19009}, // Healthstone + { 5510,19010,19011}, // Greater Healthstone + { 9421,19012,19013}, // Major Healthstone + {22103,22104,22105} // Master Healthstone + }; + + switch(m_spellInfo->Id) + { + case 6201: itemtype=itypes[0][rank];break; // Minor Healthstone + case 6202: itemtype=itypes[1][rank];break; // Lesser Healthstone + case 5699: itemtype=itypes[2][rank];break; // Healthstone + case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone + case 11730: itemtype=itypes[4][rank];break; // Major Healthstone + case 27230: itemtype=itypes[5][rank];break; // Master Healthstone + default: + return; + } + DoCreateItem( effIndex, itemtype ); + return; + } + // Brittle Armor - need remove one 24575 Brittle Armor aura + case 24590: + unitTarget->RemoveSingleAuraFromStack(24575, 0); + unitTarget->RemoveSingleAuraFromStack(24575, 1); + return; + // Mercurial Shield - need remove one 26464 Mercurial Shield aura + case 26465: + unitTarget->RemoveSingleAuraFromStack(26464, 0); + return; + // Orb teleport spells + case 25140: + case 25143: + case 25650: + case 25652: + case 29128: + case 29129: + case 35376: + case 35727: + { + if(!unitTarget) + return; + + uint32 spellid; + switch(m_spellInfo->Id) + { + case 25140: spellid = 32571; break; + case 25143: spellid = 32572; break; + case 25650: spellid = 30140; break; + case 25652: spellid = 30141; break; + case 29128: spellid = 32568; break; + case 29129: spellid = 32569; break; + case 35376: spellid = 25649; break; + case 35727: spellid = 35730; break; + default: + return; + } + + unitTarget->CastSpell(unitTarget,spellid,false); + return; + } + + // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) + case 22539: + case 22972: + case 22975: + case 22976: + case 22977: + case 22978: + case 22979: + case 22980: + case 22981: + case 22982: + case 22983: + case 22984: + case 22985: + { + if(!unitTarget || !unitTarget->isAlive()) + return; + + // Onyxia Scale Cloak + if(unitTarget->GetDummyAura(22683)) + return; + + // Shadow Flame + m_caster->CastSpell(unitTarget, 22682, true); + return; + } + break; + + // Summon Black Qiraji Battle Tank + case 26656: + { + if(!unitTarget) + return; + + // Prevent stacking of mounts + unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + + // Two separate mounts depending on area id (allows use both in and out of specific instance) + if (unitTarget->GetAreaId() == 3428) + unitTarget->CastSpell(unitTarget, 25863, false); + else + unitTarget->CastSpell(unitTarget, 26655, false); + break; + } + // Piccolo of the Flaming Fire + case 17512: + { + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); + break; + } + + // Dreaming Glory + case 28698: + { + if(!unitTarget) + return; + unitTarget->CastSpell(unitTarget, 28694, true); + break; + } + + // Netherbloom + case 28702: + { + if(!unitTarget) + return; + // 25% chance of casting a random buff + if(roll_chance_i(75)) + return; + + // triggered spells are 28703 to 28707 + // Note: some sources say, that there was the possibility of + // receiving a debuff. However, this seems to be removed by a patch. + const uint32 spellid = 28703; + + // don't overwrite an existing aura + for(uint8 i=0; i<5; i++) + if(unitTarget->HasAura(spellid+i, 0)) + return; + unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); + break; + } + + // Nightmare Vine + case 28720: + { + if(!unitTarget) + return; + // 25% chance of casting Nightmare Pollen + if(roll_chance_i(75)) + return; + unitTarget->CastSpell(unitTarget, 28721, true); + break; + } + + // Mirren's Drinking Hat + case 29830: + { + uint32 item = 0; + switch ( urand(1,6) ) + { + case 1: case 2: case 3: item = 23584; break;// Loch Modan Lager + case 4: case 5: item = 23585; break;// Stouthammer Lite + case 6: item = 23586; break;// Aerie Peak Pale Ale + } + if (item) + DoCreateItem(effIndex,item); + break; + } + // Improved Sprint + case 30918: + { + // Removes snares and roots. + uint32 mechanic_mask = (1<GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + { + next = iter; + ++next; + Aura *aur = iter->second; + if (!aur->IsPositive()) //only remove negative spells + { + // check for mechanic mask + if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) + { + unitTarget->RemoveAurasDueToSpell(aur->GetId()); + if(Auras.empty()) + break; + else + next = Auras.begin(); + } + } + } + break; + } + case 41126: // Flame Crash + { + if(!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, 41131, true); + break; + } + case 44876: // Force Cast - Portal Effect: Sunwell Isle + { + if(!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, 44870, true); + break; + } + + // Goblin Weather Machine + case 46203: + { + if(!unitTarget) + return; + + uint32 spellId; + switch(rand()%4) + { + case 0: + spellId=46740; + break; + case 1: + spellId=46739; + break; + case 2: + spellId=46738; + break; + case 3: + spellId=46736; + break; + } + unitTarget->CastSpell(unitTarget, spellId, true); + break; + } + //5,000 Gold + case 46642: + { + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->ModifyMoney(50000000); + + break; + } + } + + if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) + { + switch(m_spellInfo->SpellFamilyFlags) + { + // Judgement + case 0x800000: + { + if(!unitTarget || !unitTarget->isAlive()) + return; + uint32 spellId2 = 0; + + // all seals have aura dummy + Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) + { + SpellEntry const *spellInfo = (*itr)->GetSpellProto(); + + // search seal (all seals have judgement's aura dummy spell id in 2 effect + if ( !spellInfo || !IsSealSpell((*itr)->GetSpellProto()) || (*itr)->GetEffIndex() != 2 ) + continue; + + // must be calculated base at raw base points in spell proto, GetModifier()->m_value for S.Righteousness modified by SPELLMOD_DAMAGE + spellId2 = (*itr)->GetSpellProto()->EffectBasePoints[2]+1; + + if(spellId2 <= 1) + continue; + + // found, remove seal + m_caster->RemoveAurasDueToSpell((*itr)->GetId()); + + // Sanctified Judgement + Unit::AuraList const& m_auras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = m_auras.begin(); i != m_auras.end(); ++i) + { + if ((*i)->GetSpellProto()->SpellIconID == 205 && (*i)->GetSpellProto()->Attributes == 0x01D0LL) + { + int32 chance = (*i)->GetModifier()->m_amount; + if ( roll_chance_i(chance) ) + { + int32 mana = spellInfo->manaCost; + if ( Player* modOwner = m_caster->GetSpellModOwner() ) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, mana); + mana = int32(mana* 0.8f); + m_caster->CastCustomSpell(m_caster,31930,&mana,NULL,NULL,true,NULL,*i); + } + break; + } + } + + break; + } + + m_caster->CastSpell(unitTarget,spellId2,true); + return; + } + } + } + + // normal DB scripted effect + if(!unitTarget) + return; + + sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id); + sWorld.ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget); +} + +void Spell::EffectSanctuary(uint32 /*i*/) +{ + if(!unitTarget) + return; + //unitTarget->CombatStop(); + + unitTarget->CombatStop(); + unitTarget->getHostilRefManager().deleteReferences(); // stop all fighting + // Vanish allows to remove all threat and cast regular stealth so other spells can be used + if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_VANISH)) + { + ((Player *)m_caster)->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); + } +} + +void Spell::EffectAddComboPoints(uint32 /*i*/) +{ + if(!unitTarget) + return; + + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + if(damage <= 0) + return; + + ((Player*)m_caster)->AddComboPoints(unitTarget, damage); +} + +void Spell::EffectDuel(uint32 i) +{ + if(!m_caster || !unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player *caster = (Player*)m_caster; + Player *target = (Player*)unitTarget; + + // caster or target already have requested duel + if( caster->duel || target->duel || target->GetSocial()->HasIgnore(caster->GetGUIDLow()) ) + return; + + // Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities) + // Don't have to check the target's map since you cannot challenge someone across maps + if( caster->GetMapId() != 0 && caster->GetMapId() != 1 && caster->GetMapId() != 530) + { + SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here + return; + } + + AreaTableEntry const* casterAreaEntry = GetAreaEntryByAreaID(caster->GetZoneId()); + if(casterAreaEntry && (casterAreaEntry->flags & AREA_FLAG_CAPITAL) ) + { + SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here + return; + } + + AreaTableEntry const* targetAreaEntry = GetAreaEntryByAreaID(target->GetZoneId()); + if(targetAreaEntry && (targetAreaEntry->flags & AREA_FLAG_CAPITAL) ) + { + SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here + return; + } + + //CREATE DUEL FLAG OBJECT + GameObject* pGameObj = new GameObject; + + uint32 gameobject_id = m_spellInfo->EffectMiscValue[i]; + + Map *map = m_caster->GetMap(); + if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, + m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2 , + m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 , + m_caster->GetPositionZ(), + m_caster->GetOrientation(), 0, 0, 0, 0, 0, 1)) + { + delete pGameObj; + return; + } + + pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction() ); + pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1 ); + int32 duration = GetSpellDuration(m_spellInfo); + pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); + pGameObj->SetSpellId(m_spellInfo->Id); + + m_caster->AddGameObject(pGameObj); + map->Add(pGameObj); + //END + + // Send request + WorldPacket data(SMSG_DUEL_REQUESTED, 16); + data << pGameObj->GetGUID(); + data << caster->GetGUID(); + caster->GetSession()->SendPacket(&data); + target->GetSession()->SendPacket(&data); + + // create duel-info + DuelInfo *duel = new DuelInfo; + duel->initiator = caster; + duel->opponent = target; + duel->startTime = 0; + duel->startTimer = 0; + caster->duel = duel; + + DuelInfo *duel2 = new DuelInfo; + duel2->initiator = caster; + duel2->opponent = caster; + duel2->startTime = 0; + duel2->startTimer = 0; + target->duel = duel2; + + caster->SetUInt64Value(PLAYER_DUEL_ARBITER,pGameObj->GetGUID()); + target->SetUInt64Value(PLAYER_DUEL_ARBITER,pGameObj->GetGUID()); +} + +void Spell::EffectStuck(uint32 /*i*/) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + if(!sWorld.getConfig(CONFIG_CAST_UNSTUCK)) + return; + + Player* pTarget = (Player*)unitTarget; + + sLog.outDebug("Spell Effect: Stuck"); + sLog.outDetail("Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)", pTarget->GetName(), pTarget->GetGUIDLow(), m_caster->GetMapId(), m_caster->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ()); + + if(pTarget->isInFlight()) + return; + + // homebind location is loaded always + pTarget->TeleportTo(pTarget->m_homebindMapId,pTarget->m_homebindX,pTarget->m_homebindY,pTarget->m_homebindZ,pTarget->GetOrientation(), (unitTarget==m_caster ? TELE_TO_SPELL : 0)); + + // Stuck spell trigger Hearthstone cooldown + SpellEntry const *spellInfo = sSpellStore.LookupEntry(8690); + if(!spellInfo) + return; + Spell spell(pTarget,spellInfo,true,0); + spell.SendSpellCooldown(); +} + +void Spell::EffectSummonPlayer(uint32 /*i*/) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + // Evil Twin (ignore player summon, but hide this for summoner) + if(unitTarget->GetDummyAura(23445)) + return; + + float x,y,z; + m_caster->GetClosePoint(x,y,z,unitTarget->GetObjectSize()); + + ((Player*)unitTarget)->SetSummonPoint(m_caster->GetMapId(),x,y,z); + + WorldPacket data(SMSG_SUMMON_REQUEST, 8+4+4); + data << uint64(m_caster->GetGUID()); // summoner guid + data << uint32(m_caster->GetZoneId()); // summoner zone + data << uint32(MAX_PLAYER_SUMMON_DELAY*1000); // auto decline after msecs + ((Player*)unitTarget)->GetSession()->SendPacket(&data); +} + +static ScriptInfo generateActivateCommand() +{ + ScriptInfo si; + si.command = SCRIPT_COMMAND_ACTIVATE_OBJECT; + return si; +} + +void Spell::EffectActivateObject(uint32 effect_idx) +{ + if(!gameObjTarget) + return; + + static ScriptInfo activateCommand = generateActivateCommand(); + + int32 delay_secs = m_spellInfo->EffectMiscValue[effect_idx]; + + sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget); +} + +void Spell::EffectSummonTotem(uint32 i) +{ + uint8 slot = 0; + switch(m_spellInfo->EffectMiscValueB[i]) + { + case SUMMON_TYPE_TOTEM_SLOT1: slot = 0; break; + case SUMMON_TYPE_TOTEM_SLOT2: slot = 1; break; + case SUMMON_TYPE_TOTEM_SLOT3: slot = 2; break; + case SUMMON_TYPE_TOTEM_SLOT4: slot = 3; break; + // Battle standard case + case SUMMON_TYPE_TOTEM: slot = 254; break; + // jewelery statue case, like totem without slot + case SUMMON_TYPE_GUARDIAN: slot = 255; break; + default: return; + } + + if(slot < MAX_TOTEM) + { + uint64 guid = m_caster->m_TotemSlot[slot]; + if(guid != 0) + { + Creature *OldTotem = ObjectAccessor::GetCreature(*m_caster, guid); + if(OldTotem && OldTotem->isTotem()) + ((Totem*)OldTotem)->UnSummon(); + } + } + + uint32 team = 0; + if (m_caster->GetTypeId()==TYPEID_PLAYER) + team = ((Player*)m_caster)->GetTeam(); + + Totem* pTotem = new Totem; + + if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_spellInfo->EffectMiscValue[i], team )) + { + delete pTotem; + return; + } + + float angle = slot < MAX_TOTEM ? M_PI/MAX_TOTEM - (slot*2*M_PI/MAX_TOTEM) : 0; + + float x,y,z; + m_caster->GetClosePoint(x,y,z,pTotem->GetObjectSize(),2.0f,angle); + + // totem must be at same Z in case swimming caster and etc. + if( fabs( z - m_caster->GetPositionZ() ) > 5 ) + z = m_caster->GetPositionZ(); + + pTotem->Relocate(x, y, z, m_caster->GetOrientation()); + + if(slot < MAX_TOTEM) + m_caster->m_TotemSlot[slot] = pTotem->GetGUID(); + + pTotem->SetOwner(m_caster->GetGUID()); + pTotem->SetTypeBySummonSpell(m_spellInfo); // must be after Create call where m_spells initilized + + int32 duration=GetSpellDuration(m_spellInfo); + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id,SPELLMOD_DURATION, duration); + pTotem->SetDuration(duration); + + if (damage) // if not spell info, DB values used + { + pTotem->SetMaxHealth(damage); + pTotem->SetHealth(damage); + } + + pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id); + pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); + + pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true); + pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true); + + pTotem->Summon(m_caster); + + if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4); + data << uint8(slot); + data << uint64(pTotem->GetGUID()); + data << uint32(duration); + data << uint32(m_spellInfo->Id); + ((Player*)m_caster)->SendDirectMessage(&data); + } +} + +void Spell::EffectEnchantHeldItem(uint32 i) +{ + // this is only item spell effect applied to main-hand weapon of target player (players in area) + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player* item_owner = (Player*)unitTarget; + Item* item = item_owner->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + + if(!item ) + return; + + // must be equipped + if(!item ->IsEquipped()) + return; + + if (m_spellInfo->EffectMiscValue[i]) + { + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + int32 duration = GetSpellDuration(m_spellInfo); //Try duration index first .. + if(!duration) + duration = m_currentBasePoints[i]+1; //Base points after .. + if(!duration) + duration = 10; //10 seconds for enchants which don't have listed duration + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return; + + // Always go to temp enchantment slot + EnchantmentSlot slot = TEMP_ENCHANTMENT_SLOT; + + // Enchantment will not be applied if a different one already exists + if(item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id) + return; + + // Apply the temporary enchantment + item->SetEnchantment(slot, enchant_id, duration*1000, 0); + item_owner->ApplyEnchantment(item,slot,true); + } +} + +void Spell::EffectDisEnchant(uint32 /*i*/) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player* p_caster = (Player*)m_caster; + if(!itemTarget || !itemTarget->GetProto()->DisenchantID) + return; + + p_caster->UpdateCraftSkill(m_spellInfo->Id); + + ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(),LOOT_DISENCHANTING); + + // item will be removed at disenchanting end +} + +void Spell::EffectInebriate(uint32 /*i*/) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player *player = (Player*)unitTarget; + uint16 currentDrunk = player->GetDrunkValue(); + uint16 drunkMod = damage * 256; + if (currentDrunk + drunkMod > 0xFFFF) + currentDrunk = 0xFFFF; + else + currentDrunk += drunkMod; + player->SetDrunkValue(currentDrunk, m_CastItem?m_CastItem->GetEntry():0); +} + +void Spell::EffectFeedPet(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player *_player = (Player*)m_caster; + + if(!itemTarget) + return; + + Pet *pet = _player->GetPet(); + if(!pet) + return; + + if(!pet->isAlive()) + return; + + int32 benefit = pet->GetCurrentFoodBenefitLevel(itemTarget->GetProto()->ItemLevel); + if(benefit <= 0) + return; + + uint32 count = 1; + _player->DestroyItemCount(itemTarget,count,true); + // TODO: fix crash when a spell has two effects, both pointed at the same item target + + m_caster->CastCustomSpell(m_caster,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true); +} + +void Spell::EffectDismissPet(uint32 /*i*/) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Pet* pet = m_caster->GetPet(); + + // not let dismiss dead pet + if(!pet||!pet->isAlive()) + return; + + ((Player*)m_caster)->RemovePet(pet,PET_SAVE_NOT_IN_SLOT); +} + +void Spell::EffectSummonObject(uint32 i) +{ + uint32 go_id = m_spellInfo->EffectMiscValue[i]; + + uint8 slot = 0; + switch(m_spellInfo->Effect[i]) + { + case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: slot = 0; break; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: slot = 1; break; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: slot = 2; break; + case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: slot = 3; break; + default: return; + } + + uint64 guid = m_caster->m_ObjectSlot[slot]; + if(guid != 0) + { + GameObject* obj = NULL; + if( m_caster ) + obj = ObjectAccessor::GetGameObject(*m_caster, guid); + + if(obj) obj->Delete(); + m_caster->m_ObjectSlot[slot] = 0; + } + + GameObject* pGameObj = new GameObject; + + float rot2 = sin(m_caster->GetOrientation()/2); + float rot3 = cos(m_caster->GetOrientation()/2); + + float x,y,z; + // If dest location if present + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + } + // Summon in random point all other units if location present + else + m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE); + + Map *map = m_caster->GetMap(); + if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1)) + { + delete pGameObj; + return; + } + + pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL,m_caster->getLevel()); + int32 duration = GetSpellDuration(m_spellInfo); + pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); + pGameObj->SetSpellId(m_spellInfo->Id); + m_caster->AddGameObject(pGameObj); + + map->Add(pGameObj); + WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); + data << pGameObj->GetGUID(); + m_caster->SendMessageToSet(&data,true); + + m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID(); +} + +void Spell::EffectResurrect(uint32 i) +{ + if(!unitTarget) + return; + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + if(unitTarget->isAlive()) + return; + if(!unitTarget->IsInWorld()) + return; + + switch (m_spellInfo->Id) + { + // Defibrillate (Goblin Jumper Cables) have 33% chance on success + case 8342: + if (roll_chance_i(67)) + { + m_caster->CastSpell(m_caster, 8338, true, m_CastItem); + return; + } + break; + // Defibrillate (Goblin Jumper Cables XL) have 50% chance on success + case 22999: + if (roll_chance_i(50)) + { + m_caster->CastSpell(m_caster, 23055, true, m_CastItem); + return; + } + break; + default: + break; + } + + Player* pTarget = ((Player*)unitTarget); + + if(pTarget->isRessurectRequested()) // already have one active request + return; + + uint32 health = pTarget->GetMaxHealth() * damage / 100; + uint32 mana = pTarget->GetMaxPower(POWER_MANA) * damage / 100; + + pTarget->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana); + SendResurrectRequest(pTarget); +} + +void Spell::EffectAddExtraAttacks(uint32 /*i*/) +{ + if(!unitTarget || !unitTarget->isAlive()) + return; + + if( unitTarget->m_extraAttacks ) + return; + + unitTarget->m_extraAttacks = damage; +} + +void Spell::EffectParry(uint32 /*i*/) +{ + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)unitTarget)->SetCanParry(true); + } +} + +void Spell::EffectBlock(uint32 /*i*/) +{ + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->SetCanBlock(true); +} + +void Spell::EffectMomentMove(uint32 i) +{ + if(unitTarget->isInFlight()) + return; + + if( m_spellInfo->rangeIndex== 1) //self range + { + uint32 mapid = m_caster->GetMapId(); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + + // before caster + float fx,fy,fz; + unitTarget->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis); + float ox,oy,oz; + unitTarget->GetPosition(ox,oy,oz); + + float fx2,fy2,fz2; // getObjectHitPos overwrite last args in any result case + if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid, ox,oy,oz+0.5, fx,fy,oz+0.5,fx2,fy2,fz2, -0.5)) + { + fx = fx2; + fy = fy2; + fz = fz2; + unitTarget->UpdateGroundPositionZ(fx,fy,fz); + } + + if(unitTarget->GetTypeId() == TYPEID_PLAYER) + ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, unitTarget->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); + else + MapManager::Instance().GetMap(mapid, unitTarget)->CreatureRelocation((Creature*)unitTarget, fx, fy, fz, unitTarget->GetOrientation()); + } +} + +void Spell::EffectReputation(uint32 i) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player *_player = (Player*)unitTarget; + + int32 rep_change = m_currentBasePoints[i]+1; // field store reputation change -1 + + uint32 faction_id = m_spellInfo->EffectMiscValue[i]; + + FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); + + if(!factionEntry) + return; + + _player->ModifyFactionReputation(factionEntry,rep_change); +} + +void Spell::EffectQuestComplete(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player *_player = (Player*)m_caster; + + uint32 quest_id = m_spellInfo->EffectMiscValue[i]; + _player->AreaExploredOrEventHappens(quest_id); +} + +void Spell::EffectSelfResurrect(uint32 i) +{ + if(!unitTarget || unitTarget->isAlive()) + return; + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + if(!unitTarget->IsInWorld()) + return; + + uint32 health = 0; + uint32 mana = 0; + + // flat case + if(damage < 0) + { + health = uint32(-damage); + mana = m_spellInfo->EffectMiscValue[i]; + } + // percent case + else + { + health = uint32(damage/100.0f*unitTarget->GetMaxHealth()); + if(unitTarget->GetMaxPower(POWER_MANA) > 0) + mana = uint32(damage/100.0f*unitTarget->GetMaxPower(POWER_MANA)); + } + + Player *plr = ((Player*)unitTarget); + plr->ResurrectPlayer(0.0f); + + plr->SetHealth( health ); + plr->SetPower(POWER_MANA, mana ); + plr->SetPower(POWER_RAGE, 0 ); + plr->SetPower(POWER_ENERGY, plr->GetMaxPower(POWER_ENERGY) ); + + plr->SpawnCorpseBones(); + + plr->SaveToDB(); +} + +void Spell::EffectSkinning(uint32 /*i*/) +{ + if(unitTarget->GetTypeId() != TYPEID_UNIT ) + return; + if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Creature* creature = (Creature*) unitTarget; + int32 targetLevel = creature->getLevel(); + + uint32 skill; + if(creature->GetCreatureInfo()->flag1 & 256) + skill = SKILL_HERBALISM; // special case + else if(creature->GetCreatureInfo()->flag1 & 512) + skill = SKILL_MINING; // special case + else + skill = SKILL_SKINNING; // normal case + + ((Player*)m_caster)->SendLoot(creature->GetGUID(),LOOT_SKINNING); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + + int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel-10)*10 : targetLevel*5; + + int32 skillValue = ((Player*)m_caster)->GetPureSkillValue(skill); + + // Double chances for elites + ((Player*)m_caster)->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1 ); +} + +void Spell::EffectCharge(uint32 /*i*/) +{ + if(!unitTarget || !m_caster) + return; + + float x, y, z; + unitTarget->GetContactPoint(m_caster, x, y, z); + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + ((Creature *)unitTarget)->StopMoving(); + + // Only send MOVEMENTFLAG_WALK_MODE, client has strange issues with other move flags + m_caster->SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_WALK_MODE, 1); + + if(m_caster->GetTypeId() != TYPEID_PLAYER) + MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)->CreatureRelocation((Creature*)m_caster,x,y,z,m_caster->GetOrientation()); + + // not all charge effects used in negative spells + if ( !IsPositiveSpell(m_spellInfo->Id)) + m_caster->Attack(unitTarget,true); +} + +void Spell::EffectSummonCritter(uint32 i) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + Player* player = (Player*)m_caster; + + uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; + if(!pet_entry) + return; + + Pet* old_critter = player->GetMiniPet(); + + // for same pet just despawn + if(old_critter && old_critter->GetEntry() == pet_entry) + { + player->RemoveMiniPet(); + return; + } + + // despawn old pet before summon new + if(old_critter) + player->RemoveMiniPet(); + + // summon new pet + Pet* critter = new Pet(MINI_PET); + + Map *map = m_caster->GetMap(); + uint32 pet_number = objmgr.GeneratePetNumber(); + if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), + map, pet_entry, pet_number)) + { + sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry); + delete critter; + return; + } + + float x,y,z; + // If dest location if present + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + } + // Summon if dest location not present near caster + else + m_caster->GetClosePoint(x,y,z,critter->GetObjectSize()); + + critter->Relocate(x,y,z,m_caster->GetOrientation()); + + if(!critter->IsPositionValid()) + { + sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %d Y: ^%d)", critter->GetGUIDLow(), critter->GetEntry(), critter->GetPositionX(), critter->GetPositionY()); + delete critter; + return; + } + + critter->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID()); + critter->SetUInt64Value(UNIT_FIELD_CREATEDBY,m_caster->GetGUID()); + critter->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); + critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + + critter->AIM_Initialize(); + critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... + critter->SetMaxHealth(1); + critter->SetHealth(1); + critter->SetLevel(1); + + // set timer for unsummon + int32 duration = GetSpellDuration(m_spellInfo); + if(duration > 0) + critter->SetDuration(duration); + + std::string name = player->GetName(); + name.append(petTypeSuffix[critter->getPetType()]); + critter->SetName( name ); + player->SetMiniPet(critter); + + map->Add((Creature*)critter); +} + +void Spell::EffectKnockBack(uint32 i) +{ + if(!unitTarget || !m_caster) + return; + + // Effect only works on players + if(unitTarget->GetTypeId()!=TYPEID_PLAYER) + return; + + float vsin = sin(m_caster->GetAngle(unitTarget)); + float vcos = cos(m_caster->GetAngle(unitTarget)); + + WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); + data.append(unitTarget->GetPackGUID()); + data << uint32(0); // Sequence + data << float(vcos); // x direction + data << float(vsin); // y direction + data << float(m_spellInfo->EffectMiscValue[i])/10; // Horizontal speed + data << float(damage/-10); // Z Movement speed (vertical) + + ((Player*)unitTarget)->GetSession()->SendPacket(&data); +} + +void Spell::EffectSendTaxi(uint32 i) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(m_spellInfo->EffectMiscValue[i]); + if(!entry) + return; + + std::vector nodes; + + nodes.resize(2); + nodes[0] = entry->from; + nodes[1] = entry->to; + + uint32 mountid = 0; + switch(m_spellInfo->Id) + { + case 31606: //Stormcrow Amulet + mountid = 17447; + break; + case 45071: //Quest - Sunwell Daily - Dead Scar Bombing Run + case 45113: //Quest - Sunwell Daily - Ship Bombing Run + case 45353: //Quest - Sunwell Daily - Ship Bombing Run Return + mountid = 22840; + break; + case 34905: //Stealth Flight + mountid = 6851; + break; + } + + ((Player*)unitTarget)->ActivateTaxiPathTo(nodes,mountid); + +} + +void Spell::EffectPlayerPull(uint32 i) +{ + if(!unitTarget || !m_caster) + return; + + // Effect only works on players + if(unitTarget->GetTypeId()!=TYPEID_PLAYER) + return; + + float vsin = sin(unitTarget->GetAngle(m_caster)); + float vcos = cos(unitTarget->GetAngle(m_caster)); + + WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); + data.append(unitTarget->GetPackGUID()); + data << uint32(0); // Sequence + data << float(vcos); // x direction + data << float(vsin); // y direction + // Horizontal speed + data << float(damage ? damage : unitTarget->GetDistance2d(m_caster)); + data << float(m_spellInfo->EffectMiscValue[i])/-10; // Z Movement speed + + ((Player*)unitTarget)->GetSession()->SendPacket(&data); +} + +void Spell::EffectDispelMechanic(uint32 i) +{ + if(!unitTarget) + return; + + uint32 mechanic = m_spellInfo->EffectMiscValue[i]; + + Unit::AuraMap& Auras = unitTarget->GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + { + next = iter; + ++next; + SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); + if(spell->Mechanic == mechanic || spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic) + { + unitTarget->RemoveAurasDueToSpell(spell->Id); + if(Auras.empty()) + break; + else + next = Auras.begin(); + } + } + return; +} + +void Spell::EffectSummonDeadPet(uint32 /*i*/) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + Player *_player = (Player*)m_caster; + Pet *pet = _player->GetPet(); + if(!pet) + return; + if(pet->isAlive()) + return; + if(damage < 0) + return; + pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); + pet->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + pet->setDeathState( ALIVE ); + pet->clearUnitState(UNIT_STAT_ALL_STATE); + pet->SetHealth( uint32(pet->GetMaxHealth()*(float(damage)/100))); + + pet->AIM_Initialize(); + + _player->PetSpellInitialize(); + pet->SavePetToDB(PET_SAVE_AS_CURRENT); +} + +void Spell::EffectDestroyAllTotems(uint32 /*i*/) +{ + float mana = 0; + for(int slot = 0; slot < MAX_TOTEM; ++slot) + { + if(!m_caster->m_TotemSlot[slot]) + continue; + + Creature* totem = ObjectAccessor::GetCreature(*m_caster,m_caster->m_TotemSlot[slot]); + if(totem && totem->isTotem()) + { + uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL); + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id); + if(spellInfo) + mana += spellInfo->manaCost * damage / 100; + ((Totem*)totem)->UnSummon(); + } + } + + int32 gain = m_caster->ModifyPower(POWER_MANA,int32(mana)); + m_caster->SendEnergizeSpellLog(m_caster, m_spellInfo->Id, gain, POWER_MANA); +} + +void Spell::EffectDurabilityDamage(uint32 i) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + int32 slot = m_spellInfo->EffectMiscValue[i]; + + // FIXME: some spells effects have value -1/-2 + // Possibly its mean -1 all player equipped items and -2 all items + if(slot < 0) + { + ((Player*)unitTarget)->DurabilityPointsLossAll(damage,(slot < -1)); + return; + } + + // invalid slot value + if(slot >= INVENTORY_SLOT_BAG_END) + return; + + if(Item* item = ((Player*)unitTarget)->GetItemByPos(INVENTORY_SLOT_BAG_0,slot)) + ((Player*)unitTarget)->DurabilityPointsLoss(item,damage); +} + +void Spell::EffectDurabilityDamagePCT(uint32 i) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + int32 slot = m_spellInfo->EffectMiscValue[i]; + + // FIXME: some spells effects have value -1/-2 + // Possibly its mean -1 all player equipped items and -2 all items + if(slot < 0) + { + ((Player*)unitTarget)->DurabilityLossAll(double(damage)/100.0f,(slot < -1)); + return; + } + + // invalid slot value + if(slot >= INVENTORY_SLOT_BAG_END) + return; + + if(damage <= 0) + return; + + if(Item* item = ((Player*)unitTarget)->GetItemByPos(INVENTORY_SLOT_BAG_0,slot)) + ((Player*)unitTarget)->DurabilityLoss(item,double(damage)/100.0f); +} + +void Spell::EffectModifyThreatPercent(uint32 /*effIndex*/) +{ + if(!unitTarget) + return; + + unitTarget->getThreatManager().modifyThreatPercent(m_caster, damage); +} + +void Spell::EffectTransmitted(uint32 effIndex) +{ + uint32 name_id = m_spellInfo->EffectMiscValue[effIndex]; + + GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(name_id); + + if (!goinfo) + { + sLog.outErrorDb("Gameobject (Entry: %u) not exist and not created at spell (ID: %u) cast",name_id, m_spellInfo->Id); + return; + } + + float fx,fy,fz; + + if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + fx = m_targets.m_destX; + fy = m_targets.m_destY; + fz = m_targets.m_destZ; + } + //FIXME: this can be better check for most objects but still hack + else if(m_spellInfo->EffectRadiusIndex[effIndex] && m_spellInfo->speed==0) + { + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex])); + m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis); + } + else + { + float min_dis = GetSpellMinRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); + float max_dis = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); + float dis = rand_norm() * (max_dis - min_dis) + min_dis; + + m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis); + } + + Map *cMap = m_caster->GetMap(); + + if(goinfo->type==GAMEOBJECT_TYPE_FISHINGNODE) + { + if ( !cMap->IsInWater(fx,fy,fz-0.5f)) // Hack to prevent fishing bobber from failing to land on fishing hole + { // but this is not proper, we really need to ignore not materialized objects + SendCastResult(SPELL_FAILED_NOT_HERE); + SendChannelUpdate(0); + return; + } + + // replace by water level in this case + fz = cMap->GetWaterLevel(fx,fy); + } + // if gameobject is summoning object, it should be spawned right on caster's position + else if(goinfo->type==GAMEOBJECT_TYPE_SUMMONING_RITUAL) + { + m_caster->GetPosition(fx,fy,fz); + } + + GameObject* pGameObj = new GameObject; + + if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap, + fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1)) + { + delete pGameObj; + return; + } + + int32 duration = GetSpellDuration(m_spellInfo); + + switch(goinfo->type) + { + case GAMEOBJECT_TYPE_FISHINGNODE: + { + m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID()); + // Orientation3 + pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 ); + // Orientation4 + pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 ); + m_caster->AddGameObject(pGameObj); // will removed at spell cancel + + // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) + // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME) + int32 lastSec; + switch(urand(0, 3)) + { + case 0: lastSec = 3; break; + case 1: lastSec = 7; break; + case 2: lastSec = 13; break; + case 3: lastSec = 17; break; + } + + duration = duration - lastSec*1000 + FISHING_BOBBER_READY_TIME*1000; + break; + } + case GAMEOBJECT_TYPE_SUMMONING_RITUAL: + { + if(m_caster->GetTypeId()==TYPEID_PLAYER) + { + pGameObj->AddUniqueUse((Player*)m_caster); + m_caster->AddGameObject(pGameObj); // will removed at spell cancel + } + break; + } + case GAMEOBJECT_TYPE_FISHINGHOLE: + case GAMEOBJECT_TYPE_CHEST: + default: + { + break; + } + } + + pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); + + pGameObj->SetOwnerGUID(m_caster->GetGUID() ); + + pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() ); + pGameObj->SetSpellId(m_spellInfo->Id); + + DEBUG_LOG("AddObject at SpellEfects.cpp EffectTransmitted\n"); + //m_caster->AddGameObject(pGameObj); + //m_ObjToDel.push_back(pGameObj); + + cMap->Add(pGameObj); + + WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); + data << uint64(pGameObj->GetGUID()); + m_caster->SendMessageToSet(&data,true); + + if(uint32 linkedEntry = pGameObj->GetLinkedGameObjectEntry()) + { + GameObject* linkedGO = new GameObject; + if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap, + fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1)) + { + linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); + linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() ); + linkedGO->SetSpellId(m_spellInfo->Id); + linkedGO->SetOwnerGUID(m_caster->GetGUID() ); + + MapManager::Instance().GetMap(linkedGO->GetMapId(), linkedGO)->Add(linkedGO); + } + else + { + delete linkedGO; + linkedGO = NULL; + return; + } + } +} + +void Spell::EffectProspecting(uint32 /*i*/) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + Player* p_caster = (Player*)m_caster; + if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)) + return; + + if(itemTarget->GetCount() < 5) + return; + + if( sWorld.getConfig(CONFIG_SKILL_PROSPECTING)) + { + uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_JEWELCRAFTING); + uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank; + p_caster->UpdateGatherSkill(SKILL_JEWELCRAFTING, SkillValue, reqSkillValue); + } + + ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING); +} + +void Spell::EffectSkill(uint32 /*i*/) +{ + sLog.outDebug("WORLD: SkillEFFECT"); +} + +void Spell::EffectSummonDemon(uint32 i) +{ + float px = m_targets.m_destX; + float py = m_targets.m_destY; + float pz = m_targets.m_destZ; + + Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,3600000); + if (!Charmed) + return; + + // might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster? + Charmed->SetLevel(m_caster->getLevel()); + + // TODO: Add damage/mana/hp according to level + + if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon + { + // Enslave demon effect, without mana cost and cooldown + m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved + + // Inferno effect + Charmed->CastSpell(Charmed, 22703, true, 0); + } +} + +/* There is currently no need for this effect. We handle it in BattleGround.cpp + If we would handle the resurrection here, the spiritguide would instantly disappear as the + player revives, and so we wouldn't see the spirit heal visual effect on the npc. + This is why we use a half sec delay between the visual effect and the resurrection itself */ +void Spell::EffectSpiritHeal(uint32 /*i*/) +{ + /* + if(!unitTarget || unitTarget->isAlive()) + return; + if(unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + if(!unitTarget->IsInWorld()) + return; + + //m_spellInfo->EffectBasePoints[i]; == 99 (percent?) + //((Player*)unitTarget)->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA)); + ((Player*)unitTarget)->ResurrectPlayer(1.0f); + ((Player*)unitTarget)->SpawnCorpseBones(); + */ +} + +// remove insignia spell effect +void Spell::EffectSkinPlayerCorpse(uint32 /*i*/) +{ + sLog.outDebug("Effect: SkinPlayerCorpse"); + if ( (m_caster->GetTypeId() != TYPEID_PLAYER) || (unitTarget->GetTypeId() != TYPEID_PLAYER) || (unitTarget->isAlive()) ) + return; + + ((Player*)unitTarget)->RemovedInsignia( (Player*)m_caster ); +} + +void Spell::EffectStealBeneficialBuff(uint32 i) +{ + sLog.outDebug("Effect: StealBeneficialBuff"); + + if(!unitTarget || unitTarget==m_caster) // can't steal from self + return; + + std::vector steal_list; + // Create dispel mask by dispel type + uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) ); + Unit::AuraMap const& auras = unitTarget->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + Aura *aur = (*itr).second; + if (aur && (1<GetSpellProto()->Dispel) & dispelMask) + { + // Need check for passive? this + if (aur->IsPositive() && !aur->IsPassive()) + steal_list.push_back(aur); + } + } + // Ok if exist some buffs for dispel try dispel it + if (!steal_list.empty()) + { + std::list < std::pair > success_list; + int32 list_size = steal_list.size(); + // Dispell N = damage buffs (or while exist buffs for dispel) + for (int32 count=0; count < damage && list_size > 0; ++count) + { + // Random select buff for dispel + Aura *aur = steal_list[urand(0, list_size-1)]; + // Not use chance for steal + // TODO possible need do it + success_list.push_back( std::pair(aur->GetId(),aur->GetCasterGUID())); + + // Remove buff from list for prevent doubles + for (std::vector::iterator j = steal_list.begin(); j != steal_list.end(); ) + { + Aura *stealed = *j; + if (stealed->GetId() == aur->GetId() && stealed->GetCasterGUID() == aur->GetCasterGUID()) + { + j = steal_list.erase(j); + --list_size; + } + else + ++j; + } + } + // Really try steal and send log + if (!success_list.empty()) + { + int32 count = success_list.size(); + WorldPacket data(SMSG_SPELLSTEALLOG, 8+8+4+1+4+count*5); + data.append(unitTarget->GetPackGUID()); // Victim GUID + data.append(m_caster->GetPackGUID()); // Caster GUID + data << uint32(m_spellInfo->Id); // Dispell spell id + data << uint8(0); // not used + data << uint32(count); // count + for (std::list >::iterator j = success_list.begin(); j != success_list.end(); ++j) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first); + data << uint32(spellInfo->Id); // Spell Id + data << uint8(0); // 0 - steals !=0 transfers + unitTarget->RemoveAurasDueToSpellBySteal(spellInfo->Id, j->second, m_caster); + } + m_caster->SendMessageToSet(&data, true); + } + } +} + +void Spell::EffectKillCredit(uint32 i) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->KilledMonster(m_spellInfo->EffectMiscValue[i], 0); +} + +void Spell::EffectQuestFail(uint32 i) +{ + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]); +} diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp new file mode 100644 index 000000000..7d43e794b --- /dev/null +++ b/src/game/SpellHandler.cpp @@ -0,0 +1,466 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DBCStores.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Log.h" +#include "Opcodes.h" +#include "Spell.h" +#include "SpellAuras.h" +#include "BattleGround.h" +#include "MapManager.h" +#include "ScriptCalls.h" +#include "Totem.h" + +void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) +{ + // TODO: add targets.read() check + CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8); + + Player* pUser = _player; + uint8 bagIndex, slot; + uint8 spell_count; // number of spells at item, not used + uint8 cast_count; // next cast if exists (single or not) + uint64 item_guid; + + recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid; + + Item *pItem = pUser->GetItemByPos(bagIndex, slot); + if(!pItem) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + + if(pItem->GetGUID() != item_guid) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + + sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size()); + + ItemPrototype const *proto = pItem->GetProto(); + if(!proto) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); + return; + } + + // some item classes can be used only in equipped state + if(proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped()) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); + return; + } + + uint8 msg = pUser->CanUseItem(pItem); + if( msg != EQUIP_ERR_OK ) + { + pUser->SendEquipError( msg, pItem, NULL ); + return; + } + + // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB) + if( proto->Class == ITEM_CLASS_CONSUMABLE && + !(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) && + pUser->InArena()) + { + pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL); + return; + } + + if (pUser->isInCombat()) + { + for(int i = 0; i < 5; ++i) + { + if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(proto->Spells[i].SpellId)) + { + if (IsNonCombatSpell(spellInfo)) + { + pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL); + return; + } + } + } + } + + // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory) + if( pItem->GetProto()->Bonding == BIND_WHEN_USE || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM ) + { + if (!pItem->IsSoulBound()) + { + pItem->SetState(ITEM_CHANGED, pUser); + pItem->SetBinding( true ); + } + } + + SpellCastTargets targets; + if(!targets.read(&recvPacket, pUser)) + return; + + //Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state. + if(!Script->ItemUse(pUser,pItem,targets)) + { + // no script or script not process request by self + + // special learning case + if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) + { + uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN); + if(!spellInfo) + { + sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN); + pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL); + return; + } + + Spell *spell = new Spell(pUser, spellInfo, false); + spell->m_CastItem = pItem; + spell->m_cast_count = cast_count; //set count of casts + spell->m_currentBasePoints[0] = learning_spell_id; + spell->prepare(&targets); + return; + } + + // use triggered flag only for items with many spell casts and for not first cast + int count = 0; + + for(int i = 0; i < 5; ++i) + { + _Spell const& spellData = pItem->GetProto()->Spells[i]; + + // no spell + if(!spellData.SpellId) + continue; + + // wrong triggering type + if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId); + if(!spellInfo) + { + sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, spellData.SpellId); + continue; + } + + Spell *spell = new Spell(pUser, spellInfo, (count > 0)); + spell->m_CastItem = pItem; + spell->m_cast_count = cast_count; //set count of casts + spell->prepare(&targets); + + ++count; + } + } +} + +#define OPEN_CHEST 11437 +#define OPEN_SAFE 11535 +#define OPEN_CAGE 11792 +#define OPEN_BOOTY_CHEST 5107 +#define OPEN_STRONGBOX 8517 + +void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,1+1); + + sLog.outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i",recvPacket.size()); + + Player* pUser = _player; + uint8 bagIndex, slot; + + recvPacket >> bagIndex >> slot; + + sLog.outDetail("bagIndex: %u, slot: %u",bagIndex,slot); + + Item *pItem = pUser->GetItemByPos(bagIndex, slot); + if(!pItem) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + + ItemPrototype const *proto = pItem->GetProto(); + if(!proto) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); + return; + } + + // locked item + uint32 lockId = proto->LockID; + if(lockId) + { + LockEntry const *lockInfo = sLockStore.LookupEntry(lockId); + + if (!lockInfo) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL ); + sLog.outError( "WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", pItem->GetGUIDLow() , lockId); + return; + } + + // required picklocking + if(lockInfo->requiredlockskill || lockInfo->requiredminingskill) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL ); + return; + } + } + + if(pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))// wrapped? + { + QueryResult *result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow()); + if (result) + { + Field *fields = result->Fetch(); + uint32 entry = fields[0].GetUInt32(); + uint32 flags = fields[1].GetUInt32(); + + pItem->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0); + pItem->SetEntry(entry); + pItem->SetUInt32Value(ITEM_FIELD_FLAGS, flags); + pItem->SetState(ITEM_CHANGED, pUser); + delete result; + } + else + { + sLog.outError("Wrapped item %u don't have record in character_gifts table and will deleted", pItem->GetGUIDLow()); + pUser->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true); + return; + } + CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow()); + } + else + pUser->SendLoot(pItem->GetGUID(),LOOT_CORPSE); +} + +void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + uint64 guid; + uint32 spellId = OPEN_CHEST; + + recv_data >> guid; + + sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", guid); + GameObject *obj = ObjectAccessor::GetGameObject(*_player, guid); + + if(!obj) + return; + + if (Script->GOHello(_player, obj)) + return; + + obj->Use(_player); +} + +void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,4+1+2); + + uint32 spellId; + uint8 cast_count; + recvPacket >> spellId; + recvPacket >> cast_count; + + sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i", + spellId, cast_count, recvPacket.size()); + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); + + if(!spellInfo) + { + sLog.outError("WORLD: unknown spell id %u", spellId); + return; + } + + // not have spell or spell passive and not casted by client + if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) ) + { + //cheater? kick? ban? + return; + } + + // client provided targets + SpellCastTargets targets; + if(!targets.read(&recvPacket,_player)) + return; + + // auto-selection buff level base at target level (in spellInfo) + if(targets.getUnitTarget()) + { + SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel()); + + // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message + if(actualSpellInfo) + spellInfo = actualSpellInfo; + } + + Spell *spell = new Spell(_player, spellInfo, false); + spell->m_cast_count = cast_count; // set count of casts + spell->prepare(&targets); +} + +void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,4); + + uint32 spellId; + recvPacket >> spellId; + + //FIXME: hack, ignore unexpected client cancel Deadly Throw cast + if(spellId==26679) + return; + + if(_player->IsNonMeleeSpellCasted(false)) + _player->InterruptNonMeleeSpells(false,spellId); +} + +void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,4); + + uint32 spellId; + recvPacket >> spellId; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) + return; + + // not allow remove non positive spells and spells with attr SPELL_ATTR_CANT_CANCEL + if(!IsPositiveSpell(spellId) || (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)) + return; + + _player->RemoveAurasDueToSpellByCancel(spellId); + + if (spellId == 2584) // Waiting to resurrect spell cancel, we must remove player from resurrect queue + { + BattleGround *bg = _player->GetBattleGround(); + if(!bg) + return; + bg->RemovePlayerFromResurrectQueue(_player->GetGUID()); + } +} + +void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 8+4); + + uint64 guid; + uint32 spellId; + + recvPacket >> guid; + recvPacket >> spellId; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); + if(!spellInfo) + { + sLog.outError("WORLD: unknown PET spell id %u", spellId); + return; + } + + Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid); + + if(!pet) + { + sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid)) ); + return; + } + + if(pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm()) + { + sLog.outError( "HandlePetCancelAura.Pet %u isn't pet of player %s", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); + return; + } + + if(!pet->isAlive()) + { + pet->SendPetActionFeedback(FEEDBACK_PET_DEAD); + return; + } + + pet->RemoveAurasDueToSpell(spellId); + + pet->AddCreatureSpellCooldown(spellId); +} + +void WorldSession::HandleCancelGrowthAuraOpcode( WorldPacket& /*recvPacket*/) +{ + // nothing do +} + +void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*/) +{ + // may be better send SMSG_CANCEL_AUTO_REPEAT? + // cancel and prepare for deleting + _player->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); +} + +/// \todo Complete HandleCancelChanneling function +void WorldSession::HandleCancelChanneling( WorldPacket & /*recv_data */) +{ + /* + CHECK_PACKET_SIZE(recv_data, 4); + + uint32 spellid; + recv_data >> spellid; + */ +} + +void WorldSession::HandleTotemDestroy( WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket, 1); + + uint8 slotId; + + recvPacket >> slotId; + + if (slotId >= MAX_TOTEM) + return; + + if(!_player->m_TotemSlot[slotId]) + return; + + Creature* totem = ObjectAccessor::GetCreature(*_player,_player->m_TotemSlot[slotId]); + if(totem && totem->isTotem()) + ((Totem*)totem)->UnSummon(); +} + +void WorldSession::HandleSelfResOpcode( WorldPacket & /*recv_data*/ ) +{ + sLog.outDebug("WORLD: CMSG_SELF_RES"); // empty opcode + + if(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)); + if(spellInfo) + _player->CastSpell(_player,spellInfo,false,0); + + _player->SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); + } +} diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp new file mode 100644 index 000000000..93f8a9828 --- /dev/null +++ b/src/game/SpellMgr.cpp @@ -0,0 +1,2271 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "SpellMgr.h" +#include "ObjectMgr.h" +#include "SpellAuraDefines.h" +#include "ProgressBar.h" +#include "Database/DBCStores.h" +#include "World.h" +#include "Chat.h" +#include "Spell.h" + +SpellMgr::SpellMgr() +{ +} + +SpellMgr::~SpellMgr() +{ +} + +SpellMgr& SpellMgr::Instance() +{ + static SpellMgr spellMgr; + return spellMgr; +} + +int32 GetSpellDuration(SpellEntry const *spellInfo) +{ + if(!spellInfo) + return 0; + SpellDurationEntry const *du = sSpellDurationStore.LookupEntry(spellInfo->DurationIndex); + if(!du) + return 0; + return (du->Duration[0] == -1) ? -1 : abs(du->Duration[0]); +} + +int32 GetSpellMaxDuration(SpellEntry const *spellInfo) +{ + if(!spellInfo) + return 0; + SpellDurationEntry const *du = sSpellDurationStore.LookupEntry(spellInfo->DurationIndex); + if(!du) + return 0; + return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]); +} + +uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell) +{ + SpellCastTimesEntry const *spellCastTimeEntry = sSpellCastTimesStore.LookupEntry(spellInfo->CastingTimeIndex); + + // not all spells have cast time index and this is all is pasiive abilities + if(!spellCastTimeEntry) + return 0; + + int32 castTime = spellCastTimeEntry->CastTime; + + if (spell) + { + if(Player* modOwner = spell->GetCaster()->GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell); + + if( !(spellInfo->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_UNK5)) ) + castTime = int32(castTime * spell->GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED)); + else + { + if (spell->IsRangedSpell() && !spell->IsAutoRepeat()) + castTime = int32(castTime * spell->GetCaster()->m_modAttackSpeedPct[RANGED_ATTACK]); + } + } + + if (spellInfo->Attributes & SPELL_ATTR_RANGED && (!spell || !(spell->IsAutoRepeat()))) + castTime += 500; + + return (castTime > 0) ? uint32(castTime) : 0; +} + +bool IsPassiveSpell(uint32 spellId) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) + return false; + return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0; +} + +bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2) +{ + SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); + SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); + if(!spellInfo_1 || !spellInfo_2) return false; + if(spellInfo_1->Id == spellId_2) return false; + + if (spellInfo_1->Effect[effIndex_1] != spellInfo_2->Effect[effIndex_2] || + spellInfo_1->EffectItemType[effIndex_1] != spellInfo_2->EffectItemType[effIndex_2] || + spellInfo_1->EffectMiscValue[effIndex_1] != spellInfo_2->EffectMiscValue[effIndex_2] || + spellInfo_1->EffectApplyAuraName[effIndex_1] != spellInfo_2->EffectApplyAuraName[effIndex_2]) + return false; + + return true; +} + +int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2) +{ + SpellEntry const*spellInfo_1 = sSpellStore.LookupEntry(spellId_1); + SpellEntry const*spellInfo_2 = sSpellStore.LookupEntry(spellId_2); + if(!spellInfo_1 || !spellInfo_2) return 0; + if (spellId_1 == spellId_2) return 0; + + int32 diff = spellInfo_1->EffectBasePoints[effIndex_1] - spellInfo_2->EffectBasePoints[effIndex_2]; + if (spellInfo_1->EffectBasePoints[effIndex_1]+1 < 0 && spellInfo_2->EffectBasePoints[effIndex_2]+1 < 0) return -diff; + else return diff; +} + +SpellSpecific GetSpellSpecific(uint32 spellId) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + return SPELL_NORMAL; + + switch(spellInfo->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + { + // family flags 18(Molten), 25(Frost/Ice), 28(Mage) + if (spellInfo->SpellFamilyFlags & 0x12040000) + return SPELL_MAGE_ARMOR; + + if ((spellInfo->SpellFamilyFlags & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE) + return SPELL_MAGE_POLYMORPH; + + break; + } + case SPELLFAMILY_WARRIOR: + { + if (spellInfo->SpellFamilyFlags & 0x00008000010000LL) + return SPELL_POSITIVE_SHOUT; + + break; + } + case SPELLFAMILY_WARLOCK: + { + // only warlock curses have this + if (spellInfo->Dispel == DISPEL_CURSE) + return SPELL_CURSE; + + // family flag 37 (only part spells have family name) + if (spellInfo->SpellFamilyFlags & 0x2000000000LL) + return SPELL_WARLOCK_ARMOR; + + break; + } + case SPELLFAMILY_HUNTER: + { + // only hunter stings have this + if (spellInfo->Dispel == DISPEL_POISON) + return SPELL_STING; + + break; + } + case SPELLFAMILY_PALADIN: + { + if (IsSealSpell(spellInfo)) + return SPELL_SEAL; + + if (spellInfo->SpellFamilyFlags & 0x10000100LL) + return SPELL_BLESSING; + + if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200)) + return SPELL_JUDGEMENT; + + for (int i = 0; i < 3; i++) + { + // only paladin auras have this + if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY) + return SPELL_AURA; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + if (IsElementalShield(spellInfo)) + return SPELL_ELEMENTAL_SHIELD; + + break; + } + + case SPELLFAMILY_POTION: + return spellmgr.GetSpellElixirSpecific(spellInfo->Id); + } + + // only warlock armor/skin have this (in additional to family cases) + if( spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89) + { + return SPELL_WARLOCK_ARMOR; + } + + // only hunter aspects have this (but not all aspects in hunter family) + if( spellInfo->activeIconID == 122 && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NATURE) && + (spellInfo->Attributes & 0x50000) != 0 && (spellInfo->Attributes & 0x9000010) == 0) + { + return SPELL_ASPECT; + } + + for(int i = 0; i < 3; i++) + if( spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && ( + spellInfo->EffectApplyAuraName[i] == SPELL_AURA_TRACK_CREATURES || + spellInfo->EffectApplyAuraName[i] == SPELL_AURA_TRACK_RESOURCES || + spellInfo->EffectApplyAuraName[i] == SPELL_AURA_TRACK_STEALTHED ) ) + return SPELL_TRACKER; + + // elixirs can have different families, but potion most ofc. + if(SpellSpecific sp = spellmgr.GetSpellElixirSpecific(spellInfo->Id)) + return sp; + + return SPELL_NORMAL; +} + +bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2) +{ + switch(spellSpec1) + { + case SPELL_SEAL: + case SPELL_BLESSING: + case SPELL_AURA: + case SPELL_STING: + case SPELL_CURSE: + case SPELL_ASPECT: + case SPELL_TRACKER: + case SPELL_WARLOCK_ARMOR: + case SPELL_MAGE_ARMOR: + case SPELL_MAGE_POLYMORPH: + case SPELL_POSITIVE_SHOUT: + case SPELL_JUDGEMENT: + return spellSpec1==spellSpec2; + case SPELL_BATTLE_ELIXIR: + return spellSpec2==SPELL_BATTLE_ELIXIR + || spellSpec2==SPELL_FLASK_ELIXIR; + case SPELL_GUARDIAN_ELIXIR: + return spellSpec2==SPELL_GUARDIAN_ELIXIR + || spellSpec2==SPELL_FLASK_ELIXIR; + case SPELL_FLASK_ELIXIR: + return spellSpec2==SPELL_BATTLE_ELIXIR + || spellSpec2==SPELL_GUARDIAN_ELIXIR + || spellSpec2==SPELL_FLASK_ELIXIR; + default: + return false; + } +} + +bool IsPositiveTarget(uint32 targetA, uint32 targetB) +{ + // non-positive targets + switch(targetA) + { + case TARGET_CHAIN_DAMAGE: + case TARGET_ALL_ENEMY_IN_AREA: + case TARGET_ALL_ENEMY_IN_AREA_INSTANT: + case TARGET_IN_FRONT_OF_CASTER: + case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: + case TARGET_CURRENT_ENEMY_COORDINATES: + case TARGET_SINGLE_ENEMY: + return false; + case TARGET_ALL_AROUND_CASTER: + return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER); + default: + break; + } + if (targetB) + return IsPositiveTarget(targetB, 0); + return true; +} + +bool IsPositiveEffect(uint32 spellId, uint32 effIndex) +{ + SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId); + if (!spellproto) return false; + + switch(spellId) + { + case 23333: // BG spell + case 23335: // BG spell + case 34976: // BG spell + return true; + case 28441: // not positive dummy spell + case 37675: // Chaos Blast + return false; + } + + switch(spellproto->Effect[effIndex]) + { + // always positive effects (check before target checks that provided non-positive result in some case for positive effects) + case SPELL_EFFECT_HEAL: + case SPELL_EFFECT_LEARN_SPELL: + case SPELL_EFFECT_SKILL_STEP: + case SPELL_EFFECT_HEAL_PCT: + case SPELL_EFFECT_ENERGIZE_PCT: + return true; + + // non-positive aura use + case SPELL_EFFECT_APPLY_AURA: + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: + { + switch(spellproto->EffectApplyAuraName[effIndex]) + { + case SPELL_AURA_DUMMY: + { + // dummy aura can be positive or negative dependent from casted spell + switch(spellproto->Id) + { + case 13139: // net-o-matic special effect + case 23445: // evil twin + case 38637: // Nether Exhaustion (red) + case 38638: // Nether Exhaustion (green) + case 38639: // Nether Exhaustion (blue) + return false; + default: + break; + } + } break; + case SPELL_AURA_MOD_STAT: + case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative) + case SPELL_AURA_MOD_HEALING_DONE: + { + if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) < 0) + return false; + break; + } + case SPELL_AURA_ADD_TARGET_TRIGGER: + return true; + case SPELL_AURA_PERIODIC_TRIGGER_SPELL: + if(spellId != spellproto->EffectTriggerSpell[effIndex]) + { + uint32 spellTriggeredId = spellproto->EffectTriggerSpell[effIndex]; + SpellEntry const *spellTriggeredProto = sSpellStore.LookupEntry(spellTriggeredId); + + if(spellTriggeredProto) + { + // non-positive targets of main spell return early + for(int i = 0; i < 3; ++i) + { + // if non-positive trigger cast targeted to positive target this main cast is non-positive + // this will place this spell auras as debuffs + if(IsPositiveTarget(spellTriggeredProto->EffectImplicitTargetA[effIndex],spellTriggeredProto->EffectImplicitTargetB[effIndex]) && !IsPositiveEffect(spellTriggeredId,i)) + return false; + } + } + } + break; + case SPELL_AURA_PROC_TRIGGER_SPELL: + // many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example) + break; + case SPELL_AURA_MOD_STUN: //have positive and negative spells, we can't sort its correctly at this moment. + if(effIndex==0 && spellproto->Effect[1]==0 && spellproto->Effect[2]==0) + return false; // but all single stun aura spells is negative + + // Petrification + if(spellproto->Id == 17624) + return false; + break; + case SPELL_AURA_MOD_ROOT: + case SPELL_AURA_MOD_SILENCE: + case SPELL_AURA_GHOST: + case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_MOD_PACIFY_SILENCE: + case SPELL_AURA_MOD_STALKED: + case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: + return false; + case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also. + // part of negative spell if casted at self (prevent cancel) + if(spellproto->EffectImplicitTargetA[effIndex] == TARGET_SELF) + return false; + break; + case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also + // part of positive spell if casted at self + if(spellproto->EffectImplicitTargetA[effIndex] != TARGET_SELF) + return false; + // but not this if this first effect (don't found batter check) + if(spellproto->Attributes & 0x4000000 && effIndex==0) + return false; + break; + case SPELL_AURA_TRANSFORM: + // some spells negative + switch(spellproto->Id) + { + case 36897: // Transporter Malfunction (race mutation to horde) + case 36899: // Transporter Malfunction (race mutation to alliance) + return false; + } + break; + case SPELL_AURA_MOD_SCALE: + // some spells negative + switch(spellproto->Id) + { + case 36900: // Soul Split: Evil! + case 36901: // Soul Split: Good + case 36893: // Transporter Malfunction (decrease size case) + case 36895: // Transporter Malfunction (increase size case) + return false; + } + break; + case SPELL_AURA_MECHANIC_IMMUNITY: + { + // non-positive immunities + switch(spellproto->EffectMiscValue[effIndex]) + { + case MECHANIC_BANDAGE: + case MECHANIC_SHIELD: + case MECHANIC_MOUNT: + case MECHANIC_INVULNERABILITY: + return false; + default: + break; + } + } break; + case SPELL_AURA_ADD_FLAT_MODIFIER: // mods + case SPELL_AURA_ADD_PCT_MODIFIER: + { + // non-positive mods + switch(spellproto->EffectMiscValue[effIndex]) + { + case SPELLMOD_COST: // dependent from bas point sign (negative -> positive) + if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) > 0) + return false; + break; + default: + break; + } + } break; + case SPELL_AURA_MOD_HEALING_PCT: + if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) < 0) + return false; + break; + case SPELL_AURA_MOD_SKILL: + if(spellproto->EffectBasePoints[effIndex]+int32(spellproto->EffectBaseDice[effIndex]) < 0) + return false; + break; + case SPELL_AURA_FORCE_REACTION: + if(spellproto->Id==42792) // Recently Dropped Flag (prevent cancel) + return false; + break; + default: + break; + } + break; + } + default: + break; + } + + // non-positive targets + if(!IsPositiveTarget(spellproto->EffectImplicitTargetA[effIndex],spellproto->EffectImplicitTargetB[effIndex])) + return false; + + // AttributesEx check + if(spellproto->AttributesEx & (1<<7)) + return false; + + // ok, positive + return true; +} + +bool IsPositiveSpell(uint32 spellId) +{ + SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId); + if (!spellproto) return false; + + // spells with atleast one negative effect are considered negative + // some self-applied spells have negative effects but in self casting case negative check ignored. + for (int i = 0; i < 3; i++) + if (!IsPositiveEffect(spellId, i)) + return false; + return true; +} + +bool IsSingleTargetSpell(SpellEntry const *spellInfo) +{ + // all other single target spells have if it has AttributesEx5 + if ( spellInfo->AttributesEx5 & SPELL_ATTR_EX5_SINGLE_TARGET_SPELL ) + return true; + + // TODO - need found Judgements rule + switch(GetSpellSpecific(spellInfo->Id)) + { + case SPELL_JUDGEMENT: + return true; + } + + // single target triggered spell. + // Not real client side single target spell, but it' not triggered until prev. aura expired. + // This is allow store it in single target spells list for caster for spell proc checking + if(spellInfo->Id==38324) // Regeneration (triggered by 38299 (HoTs on Heals)) + return true; + + return false; +} + +bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2) +{ + // TODO - need better check + // Equal icon and spellfamily + if( spellInfo1->SpellFamilyName == spellInfo2->SpellFamilyName && + spellInfo1->SpellIconID == spellInfo2->SpellIconID ) + return true; + + // TODO - need found Judgements rule + SpellSpecific spec1 = GetSpellSpecific(spellInfo1->Id); + // spell with single target specific types + switch(spec1) + { + case SPELL_JUDGEMENT: + if(GetSpellSpecific(spellInfo2->Id) == spec1) + return true; + break; + } + + return false; +} + +uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form) +{ + // talents that learn spells can have stance requirements that need ignore + // (this requirement only for client-side stance show in talent description) + if( GetTalentSpellCost(spellInfo->Id) > 0 && + (spellInfo->Effect[0]==SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[1]==SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[2]==SPELL_EFFECT_LEARN_SPELL) ) + return 0; + + uint32 stanceMask = (form ? 1 << (form - 1) : 0); + + if (stanceMask & spellInfo->StancesNot) // can explicitly not be casted in this stance + return SPELL_FAILED_NOT_SHAPESHIFT; + + if (stanceMask & spellInfo->Stances) // can explicitly be casted in this stance + return 0; + + bool actAsShifted = false; + if (form > 0) + { + SpellShapeshiftEntry const *shapeInfo = sSpellShapeshiftStore.LookupEntry(form); + if (!shapeInfo) + { + sLog.outError("GetErrorAtShapeshiftedCast: unknown shapeshift %u", form); + return 0; + } + actAsShifted = !(shapeInfo->flags1 & 1); // shapeshift acts as normal form for spells + } + + if(actAsShifted) + { + if (spellInfo->Attributes & SPELL_ATTR_NOT_SHAPESHIFT) // not while shapeshifted + return SPELL_FAILED_NOT_SHAPESHIFT; + else if (spellInfo->Stances != 0) // needs other shapeshift + return SPELL_FAILED_ONLY_SHAPESHIFT; + } + else + { + // needs shapeshift + if(!(spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && spellInfo->Stances != 0) + return SPELL_FAILED_ONLY_SHAPESHIFT; + } + + return 0; +} + +void SpellMgr::LoadSpellTargetPositions() +{ + mSpellTargetPositions.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 2 3 4 5 + QueryResult *result = WorldDatabase.Query("SELECT id, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM spell_target_position"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell target coordinates", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + ++count; + + uint32 Spell_ID = fields[0].GetUInt32(); + + SpellTargetPosition st; + + st.target_mapId = fields[1].GetUInt32(); + st.target_X = fields[2].GetFloat(); + st.target_Y = fields[3].GetFloat(); + st.target_Z = fields[4].GetFloat(); + st.target_Orientation = fields[5].GetFloat(); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(Spell_ID); + if(!spellInfo) + { + sLog.outErrorDb("Spell (ID:%u) listed in `spell_target_position` does not exist.",Spell_ID); + continue; + } + + bool found = false; + for(int i = 0; i < 3; ++i) + { + if( spellInfo->EffectImplicitTargetA[i]==TARGET_TABLE_X_Y_Z_COORDINATES || spellInfo->EffectImplicitTargetB[i]==TARGET_TABLE_X_Y_Z_COORDINATES ) + { + found = true; + break; + } + } + if(!found) + { + sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` does not have target TARGET_TABLE_X_Y_Z_COORDINATES (17).",Spell_ID); + continue; + } + + MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId); + if(!mapEntry) + { + sLog.outErrorDb("Spell (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.",Spell_ID,st.target_mapId); + continue; + } + + if(st.target_X==0 && st.target_Y==0 && st.target_Z==0) + { + sLog.outErrorDb("Spell (ID:%u) target coordinates not provided.",Spell_ID); + continue; + } + + mSpellTargetPositions[Spell_ID] = st; + + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell teleport coordinates", count ); +} + +void SpellMgr::LoadSpellAffects() +{ + mSpellAffectMap.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 2 + QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell affect definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + uint16 entry = fields[0].GetUInt16(); + uint8 effectId = fields[1].GetUInt8(); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry); + + if (!spellInfo) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` does not exist", entry); + continue; + } + + if (effectId >= 3) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` have invalid effect index (%u)", entry,effectId); + continue; + } + + if( spellInfo->Effect[effectId] != SPELL_EFFECT_APPLY_AURA || + spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_FLAT_MODIFIER && + spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_PCT_MODIFIER && + spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER ) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` have not SPELL_AURA_ADD_FLAT_MODIFIER (%u) or SPELL_AURA_ADD_PCT_MODIFIER (%u) or SPELL_AURA_ADD_TARGET_TRIGGER (%u) for effect index (%u)", entry,SPELL_AURA_ADD_FLAT_MODIFIER,SPELL_AURA_ADD_PCT_MODIFIER,SPELL_AURA_ADD_TARGET_TRIGGER,effectId); + continue; + } + + uint64 spellAffectMask = fields[2].GetUInt64(); + + // Spell.dbc have own data for low part of SpellFamilyMask + if( spellInfo->EffectItemType[effectId]) + { + if(spellInfo->EffectItemType[effectId] == spellAffectMask) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectItemType%d) data for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId); + continue; + } + + // 24429 have wrong data in EffectItemType and overwrites by DB, possible bug in client + if(spellInfo->Id!=24429 && spellInfo->EffectItemType[effectId] != spellAffectMask) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` have different low part from EffectItemType%d for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId); + continue; + } + } + + mSpellAffectMap.insert(SpellAffectMap::value_type((entry<<8) + effectId,spellAffectMask)); + + ++count; + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell affect definitions", count ); + + /* + // Commented for now, as it still produces many errors (still quite many spells miss spell_affect) + for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(id); + if (!spellInfo) + continue; + + for (int effectId = 0; effectId < 3; ++effectId) + { + if( spellInfo->Effect[effectId] != SPELL_EFFECT_APPLY_AURA || + (spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_FLAT_MODIFIER && + spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_PCT_MODIFIER && + spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER) ) + continue; + + if(spellInfo->EffectItemType[effectId] != 0) + continue; + + if(mSpellAffectMap.find((id<<8) + effectId) != mSpellAffectMap.end()) + continue; + + sLog.outErrorDb("Spell %u (%s) misses spell_affect for effect %u",id,spellInfo->SpellName[sWorld.GetDBClang()], effectId); + } + } + */ +} + +bool SpellMgr::IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const +{ + // false for spellInfo == NULL + if (!spellInfo) + return false; + + SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId); + // false for affect_spell == NULL + if (!affect_spell) + return false; + + // False if spellFamily not equal + if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName) + return false; + + // If familyFlags == 0 + if (!familyFlags) + { + // Get it from spellAffect table + familyFlags = GetSpellAffectMask(spellId,effectId); + // false if familyFlags == 0 + if (!familyFlags) + return false; + } + + // true + if (familyFlags & spellInfo->SpellFamilyFlags) + return true; + + return false; +} + +void SpellMgr::LoadSpellProcEvents() +{ + mSpellProcEventMap.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 2 3 4 5 6 7 8 + QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown FROM spell_proc_event"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell proc event conditions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + uint16 entry = fields[0].GetUInt16(); + + if (!sSpellStore.LookupEntry(entry)) + { + sLog.outErrorDb("Spell %u listed in `spell_proc_event` does not exist", entry); + continue; + } + + SpellProcEventEntry spe; + + spe.schoolMask = fields[1].GetUInt32(); + spe.category = fields[2].GetUInt32(); + spe.skillId = fields[3].GetUInt32(); + spe.spellFamilyName = fields[4].GetUInt32(); + spe.spellFamilyMask = fields[5].GetUInt64(); + spe.procFlags = fields[6].GetUInt32(); + spe.ppmRate = fields[7].GetFloat(); + spe.cooldown = fields[8].GetUInt32(); + + mSpellProcEventMap[entry] = spe; + + ++count; + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell proc event conditions", count ); + + /* + // Commented for now, as it still produces many errors (still quite many spells miss spell_proc_event) + for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(id); + if (!spellInfo) + continue; + + bool found = false; + for (int effectId = 0; effectId < 3; ++effectId) + { + // at this moment check only SPELL_AURA_PROC_TRIGGER_SPELL + if( spellInfo->EffectApplyAuraName[effectId] == SPELL_AURA_PROC_TRIGGER_SPELL ) + { + found = true; + break; + } + } + + if(!found) + continue; + + if(GetSpellProcEvent(id)) + continue; + + sLog.outErrorDb("Spell %u (%s) misses spell_proc_event",id,spellInfo->SpellName[sWorld.GetDBClang()]); + } + */ +} + +bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags ) +{ + if((procFlags & spellProcEvent->procFlags) == 0) + return false; + + // Additional checks in case spell cast/hit/crit is the event + // Check (if set) school, category, skill line, spell talent mask + if(spellProcEvent->schoolMask && (!procSpell || (GetSpellSchoolMask(procSpell) & spellProcEvent->schoolMask) == 0)) + return false; + if(spellProcEvent->category && (!procSpell || procSpell->Category != spellProcEvent->category)) + return false; + if(spellProcEvent->skillId) + { + if (!procSpell) + return false; + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(procSpell->Id); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(procSpell->Id); + + bool found = false; + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + if(_spell_idx->second->skillId == spellProcEvent->skillId) + { + found = true; + break; + } + } + if (!found) + return false; + } + if(spellProcEvent->spellFamilyName && (!procSpell || spellProcEvent->spellFamilyName != procSpell->SpellFamilyName)) + return false; + if(spellProcEvent->spellFamilyMask && (!procSpell || (spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)) + return false; + + return true; +} + +void SpellMgr::LoadSpellElixirs() +{ + mSpellElixirs.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 + QueryResult *result = WorldDatabase.Query("SELECT entry, mask FROM spell_elixir"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell elixir definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + uint16 entry = fields[0].GetUInt16(); + uint8 mask = fields[1].GetUInt8(); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry); + + if (!spellInfo) + { + sLog.outErrorDb("Spell %u listed in `spell_elixir` does not exist", entry); + continue; + } + + mSpellElixirs[entry] = mask; + + ++count; + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell elixir definitions", count ); +} + +void SpellMgr::LoadSpellThreats() +{ + sSpellThreatStore.Free(); // for reload + + sSpellThreatStore.Load(); + + sLog.outString( ">> Loaded %u aggro generating spells", sSpellThreatStore.RecordCount ); + sLog.outString(); +} + +bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const +{ + SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); + if(!spellInfo_1 || !spellInfo_2) return false; + if(spellInfo_1->Id == spellId_2) return false; + + return GetFirstSpellInChain(spellInfo_1->Id)==GetFirstSpellInChain(spellId_2); +} + +bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo) +{ + if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH) + return false; + if(IsProfessionSpell(spellInfo->Id)) + return false; + + // All stance spells. if any better way, change it. + for (int i = 0; i < 3; i++) + { + // Paladin aura Spell + if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN + && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY) + return false; + // Druid form Spell + if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID + && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA + && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT) + return false; + // Rogue Stealth + if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE + && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA + && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT) + return false; + } + return true; +} + +bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const +{ + SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); + SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); + + if(!spellInfo_1 || !spellInfo_2) + return false; + + if(spellInfo_1->Id == spellId_2) + return false; + + //I think we don't check this correctly because i need a exception for spell: + //72,11327,18461...(called from 1856,1857...) Call Aura 16,31, after trigger another spell who call aura 77 and 77 remove 16 and 31, this should not happen. + if(spellInfo_2->SpellFamilyFlags == 2048) + return false; + + // Resurrection sickness + if((spellInfo_1->Id == SPELL_ID_PASSIVE_RESURRECTION_SICKNESS) != (spellInfo_2->Id==SPELL_ID_PASSIVE_RESURRECTION_SICKNESS)) + return false; + + // Specific spell family spells + switch(spellInfo_1->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + switch(spellInfo_2->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: // same family case + { + // Thunderfury + if( spellInfo_1->Id == 21992 && spellInfo_2->Id == 27648 || spellInfo_2->Id == 21992 && spellInfo_1->Id == 27648 ) + return false; + + // Lightning Speed (Mongoose) and Fury of the Crashing Waves (Tsunami Talisman) + if( spellInfo_1->Id == 28093 && spellInfo_2->Id == 42084 || + spellInfo_2->Id == 28093 && spellInfo_1->Id == 42084 ) + return false; + + // Soulstone Resurrection and Twisting Nether (resurrector) + if( spellInfo_1->SpellIconID == 92 && spellInfo_2->SpellIconID == 92 && ( + spellInfo_1->SpellVisual == 99 && spellInfo_2->SpellVisual == 0 || + spellInfo_2->SpellVisual == 99 && spellInfo_1->SpellVisual == 0 ) ) + return false; + + // Heart of the Wild and (Primal Instinct (Idol of Terror) triggering spell or Agility) + if( spellInfo_1->SpellIconID == 240 && spellInfo_2->SpellIconID == 240 && ( + spellInfo_1->SpellVisual == 0 && spellInfo_2->SpellVisual == 78 || + spellInfo_2->SpellVisual == 0 && spellInfo_1->SpellVisual == 78 ) ) + return false; + + // Personalized Weather (thunder effect should overwrite rainy aura) + if(spellInfo_1->SpellIconID == 2606 && spellInfo_2->SpellIconID == 2606) + return false; + + // Brood Affliction: Bronze + if( (spellInfo_1->Id == 23170 && spellInfo_2->Id == 23171) || + (spellInfo_2->Id == 23170 && spellInfo_1->Id == 23171) ) + return false; + + break; + } + case SPELLFAMILY_WARRIOR: + { + // Scroll of Protection and Defensive Stance (multi-family check) + if( spellInfo_1->SpellIconID == 276 && spellInfo_1->SpellVisual == 196 && spellInfo_2->Id == 71) + return false; + + // Improved Hamstring -> Hamstring (multi-family check) + if( (spellInfo_2->SpellFamilyFlags & 2) && spellInfo_1->Id == 23694 ) + return false; + + break; + } + case SPELLFAMILY_DRUID: + { + // Scroll of Stamina and Leader of the Pack (multi-family check) + if( spellInfo_1->SpellIconID == 312 && spellInfo_1->SpellVisual == 216 && spellInfo_2->Id == 24932 ) + return false; + + // Dragonmaw Illusion (multi-family check) + if (spellId_1 == 40216 && spellId_2 == 42016 ) + return false; + + break; + } + case SPELLFAMILY_ROGUE: + { + // Garrote-Silence -> Garrote (multi-family check) + if( spellInfo_1->SpellIconID == 498 && spellInfo_1->SpellVisual == 0 && spellInfo_2->SpellIconID == 498 ) + return false; + + break; + } + case SPELLFAMILY_HUNTER: + { + // Concussive Shot and Imp. Concussive Shot (multi-family check) + if( spellInfo_1->Id == 19410 && spellInfo_2->Id == 5116 ) + return false; + + // Improved Wing Clip -> Wing Clip (multi-family check) + if( (spellInfo_2->SpellFamilyFlags & 0x40) && spellInfo_1->Id == 19229 ) + return false; + break; + } + case SPELLFAMILY_PALADIN: + { + // Unstable Currents and other -> *Sanctity Aura (multi-family check) + if( spellInfo_2->SpellIconID==502 && spellInfo_1->SpellIconID==502 && spellInfo_1->SpellVisual==969 ) + return false; + + // *Band of Eternal Champion and Seal of Command(multi-family check) + if( spellId_1 == 35081 && spellInfo_2->SpellIconID==561 && spellInfo_2->SpellVisual==7992) + return false; + + break; + } + } + break; + case SPELLFAMILY_MAGE: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_MAGE ) + { + // Blizzard & Chilled (and some other stacked with blizzard spells + if( (spellInfo_1->SpellFamilyFlags & 0x80) && (spellInfo_2->SpellFamilyFlags & 0x100000) || + (spellInfo_2->SpellFamilyFlags & 0x80) && (spellInfo_1->SpellFamilyFlags & 0x100000) ) + return false; + + // Blink & Improved Blink + if( (spellInfo_1->SpellFamilyFlags & 0x0000000000010000LL) && (spellInfo_2->SpellVisual == 72 && spellInfo_2->SpellIconID == 1499) || + (spellInfo_2->SpellFamilyFlags & 0x0000000000010000LL) && (spellInfo_1->SpellVisual == 72 && spellInfo_1->SpellIconID == 1499) ) + return false; + } + // Detect Invisibility and Mana Shield (multi-family check) + if( spellInfo_2->Id == 132 && spellInfo_1->SpellIconID == 209 && spellInfo_1->SpellVisual == 968 ) + return false; + + // Combustion and Fire Protection Aura (multi-family check) + if( spellInfo_1->Id == 11129 && spellInfo_2->SpellIconID == 33 && spellInfo_2->SpellVisual == 321 ) + return false; + + break; + case SPELLFAMILY_WARLOCK: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_WARLOCK ) + { + // Siphon Life and Drain Life + if( spellInfo_1->SpellIconID == 152 && spellInfo_2->SpellIconID == 546 || + spellInfo_2->SpellIconID == 152 && spellInfo_1->SpellIconID == 546 ) + return false; + + //Corruption & Seed of corruption + if( spellInfo_1->SpellIconID == 313 && spellInfo_2->SpellIconID == 1932 || + spellInfo_2->SpellIconID == 313 && spellInfo_1->SpellIconID == 1932 ) + if(spellInfo_1->SpellVisual != 0 && spellInfo_2->SpellVisual != 0) + return true; // can't be stacked + + // Corruption and Unstable Affliction + if( spellInfo_1->SpellIconID == 313 && spellInfo_2->SpellIconID == 2039 || + spellInfo_2->SpellIconID == 313 && spellInfo_1->SpellIconID == 2039 ) + return false; + + // (Corruption or Unstable Affliction) and (Curse of Agony or Curse of Doom) + if( (spellInfo_1->SpellIconID == 313 || spellInfo_1->SpellIconID == 2039) && (spellInfo_2->SpellIconID == 544 || spellInfo_2->SpellIconID == 91) || + (spellInfo_2->SpellIconID == 313 || spellInfo_2->SpellIconID == 2039) && (spellInfo_1->SpellIconID == 544 || spellInfo_1->SpellIconID == 91) ) + return false; + } + // Detect Invisibility and Mana Shield (multi-family check) + if( spellInfo_1->Id == 132 && spellInfo_2->SpellIconID == 209 && spellInfo_2->SpellVisual == 968 ) + return false; + break; + case SPELLFAMILY_WARRIOR: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_WARRIOR ) + { + // Rend and Deep Wound + if( (spellInfo_1->SpellFamilyFlags & 0x20) && (spellInfo_2->SpellFamilyFlags & 0x1000000000LL) || + (spellInfo_2->SpellFamilyFlags & 0x20) && (spellInfo_1->SpellFamilyFlags & 0x1000000000LL) ) + return false; + + // Battle Shout and Rampage + if( (spellInfo_1->SpellIconID == 456 && spellInfo_2->SpellIconID == 2006) || + (spellInfo_2->SpellIconID == 456 && spellInfo_1->SpellIconID == 2006) ) + return false; + } + + // Hamstring -> Improved Hamstring (multi-family check) + if( (spellInfo_1->SpellFamilyFlags & 2) && spellInfo_2->Id == 23694 ) + return false; + + // Defensive Stance and Scroll of Protection (multi-family check) + if( spellInfo_1->Id == 71 && spellInfo_2->SpellIconID == 276 && spellInfo_2->SpellVisual == 196 ) + return false; + + // Bloodlust and Bloodthirst (multi-family check) + if( spellInfo_2->Id == 2825 && spellInfo_1->SpellIconID == 38 && spellInfo_1->SpellVisual == 0 ) + return false; + + break; + case SPELLFAMILY_PRIEST: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_PRIEST ) + { + //Devouring Plague and Shadow Vulnerability + if( (spellInfo_1->SpellFamilyFlags & 0x2000000) && (spellInfo_2->SpellFamilyFlags & 0x800000000LL) || + (spellInfo_2->SpellFamilyFlags & 0x2000000) && (spellInfo_1->SpellFamilyFlags & 0x800000000LL) ) + return false; + + //StarShards and Shadow Word: Pain + if( (spellInfo_1->SpellFamilyFlags & 0x200000) && (spellInfo_2->SpellFamilyFlags & 0x8000) || + (spellInfo_2->SpellFamilyFlags & 0x200000) && (spellInfo_1->SpellFamilyFlags & 0x8000) ) + return false; + } + break; + case SPELLFAMILY_DRUID: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_DRUID ) + { + //Omen of Clarity and Blood Frenzy + if( (spellInfo_1->SpellFamilyFlags == 0x0 && spellInfo_1->SpellIconID == 108) && (spellInfo_2->SpellFamilyFlags & 0x20000000000000LL) || + (spellInfo_2->SpellFamilyFlags == 0x0 && spellInfo_2->SpellIconID == 108) && (spellInfo_1->SpellFamilyFlags & 0x20000000000000LL) ) + return false; + + // Tree of Life (Shapeshift) and 34123 Tree of Life (Passive) + if ((spellId_1 == 33891 && spellId_2 == 34123) || + (spellId_2 == 33891 && spellId_1 == 34123)) + return false; + + // Wrath of Elune and Nature's Grace + if( spellInfo_1->Id == 16886 && spellInfo_2->Id == 46833 || spellInfo_2->Id == 16886 && spellInfo_1->Id == 46833 ) + return false; + + // Bear Rage (Feral T4 (2)) and Omen of Clarity + if( spellInfo_1->Id == 16864 && spellInfo_2->Id == 37306 || spellInfo_2->Id == 16864 && spellInfo_1->Id == 37306 ) + return false; + + // Cat Energy (Feral T4 (2)) and Omen of Clarity + if( spellInfo_1->Id == 16864 && spellInfo_2->Id == 37311 || spellInfo_2->Id == 16864 && spellInfo_1->Id == 37311 ) + return false; + } + + // Leader of the Pack and Scroll of Stamina (multi-family check) + if( spellInfo_1->Id == 24932 && spellInfo_2->SpellIconID == 312 && spellInfo_2->SpellVisual == 216 ) + return false; + + // Dragonmaw Illusion (multi-family check) + if (spellId_1 == 42016 && spellId_2 == 40216 ) + return false; + + break; + case SPELLFAMILY_ROGUE: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_ROGUE ) + { + // Master of Subtlety + if (spellId_1 == 31665 && spellId_2 == 31666 || spellId_1 == 31666 && spellId_2 == 31665 ) + return false; + } + + // Garrote -> Garrote-Silence (multi-family check) + if( spellInfo_1->SpellIconID == 498 && spellInfo_2->SpellIconID == 498 && spellInfo_2->SpellVisual == 0 ) + return false; + break; + case SPELLFAMILY_HUNTER: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_HUNTER ) + { + // Rapid Fire & Quick Shots + if( (spellInfo_1->SpellFamilyFlags & 0x20) && (spellInfo_2->SpellFamilyFlags & 0x20000000000LL) || + (spellInfo_2->SpellFamilyFlags & 0x20) && (spellInfo_1->SpellFamilyFlags & 0x20000000000LL) ) + return false; + + // Serpent Sting & (Immolation/Explosive Trap Effect) + if( (spellInfo_1->SpellFamilyFlags & 0x4) && (spellInfo_2->SpellFamilyFlags & 0x00000004000LL) || + (spellInfo_2->SpellFamilyFlags & 0x4) && (spellInfo_1->SpellFamilyFlags & 0x00000004000LL) ) + return false; + + // Bestial Wrath + if( spellInfo_1->SpellIconID == 1680 && spellInfo_2->SpellIconID == 1680 ) + return false; + } + + // Wing Clip -> Improved Wing Clip (multi-family check) + if( (spellInfo_1->SpellFamilyFlags & 0x40) && spellInfo_2->Id == 19229 ) + return false; + + // Concussive Shot and Imp. Concussive Shot (multi-family check) + if( spellInfo_2->Id == 19410 && spellInfo_1->Id == 5116 ) + return false; + break; + case SPELLFAMILY_PALADIN: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_PALADIN ) + { + // Paladin Seals + if( IsSealSpell(spellInfo_1) && IsSealSpell(spellInfo_2) ) + return true; + } + // Combustion and Fire Protection Aura (multi-family check) + if( spellInfo_2->Id == 11129 && spellInfo_1->SpellIconID == 33 && spellInfo_1->SpellVisual == 321 ) + return false; + + // *Sanctity Aura -> Unstable Currents and other (multi-family check) + if( spellInfo_1->SpellIconID==502 && spellInfo_2->SpellFamilyName == SPELLFAMILY_GENERIC && spellInfo_2->SpellIconID==502 && spellInfo_2->SpellVisual==969 ) + return false; + + // *Seal of Command and Band of Eternal Champion (multi-family check) + if( spellInfo_1->SpellIconID==561 && spellInfo_1->SpellVisual==7992 && spellId_2 == 35081) + return false; + break; + case SPELLFAMILY_SHAMAN: + if( spellInfo_2->SpellFamilyName == SPELLFAMILY_SHAMAN ) + { + // shaman shields + if( IsElementalShield(spellInfo_1) && IsElementalShield(spellInfo_2) ) + return true; + + // Windfury weapon + if( spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 && + spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags ) + return false; + } + // Bloodlust and Bloodthirst (multi-family check) + if( spellInfo_1->Id == 2825 && spellInfo_2->SpellIconID == 38 && spellInfo_2->SpellVisual == 0 ) + return false; + break; + default: + break; + } + + // more generic checks + if (spellInfo_1->SpellIconID == spellInfo_2->SpellIconID && + spellInfo_1->SpellIconID != 0 && spellInfo_2->SpellIconID != 0) + { + bool isModifier = false; + for (int i = 0; i < 3; i++) + { + if (spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_ADD_FLAT_MODIFIER || + spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_ADD_PCT_MODIFIER || + spellInfo_2->EffectApplyAuraName[i] == SPELL_AURA_ADD_FLAT_MODIFIER || + spellInfo_2->EffectApplyAuraName[i] == SPELL_AURA_ADD_PCT_MODIFIER ) + isModifier = true; + } + + if (!isModifier) + return true; + } + + if (IsRankSpellDueToSpell(spellInfo_1, spellId_2)) + return true; + + if (spellInfo_1->SpellFamilyName == 0 || spellInfo_2->SpellFamilyName == 0) + return false; + + if (spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) + return false; + + for (int i = 0; i < 3; ++i) + if (spellInfo_1->Effect[i] != spellInfo_2->Effect[i] || + spellInfo_1->EffectItemType[i] != spellInfo_2->EffectItemType[i] || + spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i] || + spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]) + return false; + + return true; +} + +bool SpellMgr::IsProfessionSpell(uint32 spellId) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + return false; + + if(spellInfo->Effect[1] != SPELL_EFFECT_SKILL) + return false; + + uint32 skill = spellInfo->EffectMiscValue[1]; + + return IsProfessionSkill(skill); +} + +bool SpellMgr::IsPrimaryProfessionSpell(uint32 spellId) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + return false; + + if(spellInfo->Effect[1] != SPELL_EFFECT_SKILL) + return false; + + uint32 skill = spellInfo->EffectMiscValue[1]; + + return IsPrimaryProfessionSkill(skill); +} + +bool SpellMgr::IsPrimaryProfessionFirstRankSpell(uint32 spellId) const +{ + return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId)==1; +} + +SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const +{ + // ignore passive spells + if(IsPassiveSpell(spellInfo->Id)) + return spellInfo; + + bool needRankSelection = false; + for(int i=0;i<3;i++) + { + if( IsPositiveEffect(spellInfo->Id, i) && ( + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY + ) ) + { + needRankSelection = true; + break; + } + } + + // not required + if(!needRankSelection) + return spellInfo; + + for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId)) + { + SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId); + if(!nextSpellInfo) + break; + + // if found appropriate level + if(playerLevel + 10 >= nextSpellInfo->spellLevel) + return nextSpellInfo; + + // one rank less then + } + + // not found + return NULL; +} + +void SpellMgr::LoadSpellChains() +{ + mSpellChains.clear(); // need for reload case + mSpellChainsNext.clear(); // need for reload case + + QueryResult *result = WorldDatabase.PQuery("SELECT spell_id, prev_spell, first_spell, rank, req_spell FROM spell_chain"); + if(result == NULL) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded 0 spell chain records" ); + sLog.outErrorDb("`spell_chains` table is empty!"); + return; + } + + uint32 count = 0; + + barGoLink bar( result->GetRowCount() ); + do + { + bar.step(); + Field *fields = result->Fetch(); + + uint32 spell_id = fields[0].GetUInt32(); + + SpellChainNode node; + node.prev = fields[1].GetUInt32(); + node.first = fields[2].GetUInt32(); + node.rank = fields[3].GetUInt8(); + node.req = fields[4].GetUInt32(); + + if(!sSpellStore.LookupEntry(spell_id)) + { + sLog.outErrorDb("Spell %u listed in `spell_chain` does not exist",spell_id); + continue; + } + + if(node.prev!=0 && !sSpellStore.LookupEntry(node.prev)) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not existed previous rank spell.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + if(!sSpellStore.LookupEntry(node.first)) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not existing first rank spell.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + // check basic spell chain data integrity (note: rank can be equal 0 or 1 for first/single spell) + if( (spell_id == node.first) != (node.rank <= 1) || + (spell_id == node.first) != (node.prev == 0) || + (node.rank <= 1) != (node.prev == 0) ) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not compatible chain data.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + if(node.req!=0 && !sSpellStore.LookupEntry(node.req)) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not existing required spell.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + // talents not required data in spell chain for work, but must be checked if present for intergrity + if(TalentSpellPos const* pos = GetTalentSpellPos(spell_id)) + { + if(node.rank!=pos->rank+1) + { + sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong rank.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + if(TalentEntry const* talentEntry = sTalentStore.LookupEntry(pos->talent_id)) + { + if(node.first!=talentEntry->RankID[0]) + { + sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong first rank spell.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + if(node.rank > 1 && node.prev != talentEntry->RankID[node.rank-1-1]) + { + sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong prev rank spell.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + + if(node.req!=talentEntry->DependsOnSpell) + { + sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong required spell.", + spell_id,node.prev,node.first,node.rank,node.req); + continue; + } + } + } + + mSpellChains[spell_id] = node; + + if(node.prev) + mSpellChainsNext.insert(SpellChainMapNext::value_type(node.prev,spell_id)); + + if(node.req) + mSpellChainsNext.insert(SpellChainMapNext::value_type(node.req,spell_id)); + + ++count; + } while( result->NextRow() ); + + // additional integrity checks + for(SpellChainMap::iterator i = mSpellChains.begin(); i != mSpellChains.end(); ++i) + { + if(i->second.prev) + { + SpellChainMap::iterator i_prev = mSpellChains.find(i->second.prev); + if(i_prev == mSpellChains.end()) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not found previous rank spell in table.", + i->first,i->second.prev,i->second.first,i->second.rank,i->second.req); + } + else if( i_prev->second.first != i->second.first ) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has different first spell in chain compared to previous rank spell (prev: %u, first: %u, rank: %d, req: %u).", + i->first,i->second.prev,i->second.first,i->second.rank,i->second.req, + i_prev->second.prev,i_prev->second.first,i_prev->second.rank,i_prev->second.req); + } + else if( i_prev->second.rank+1 != i->second.rank ) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has different rank compared to previous rank spell (prev: %u, first: %u, rank: %d, req: %u).", + i->first,i->second.prev,i->second.first,i->second.rank,i->second.req, + i_prev->second.prev,i_prev->second.first,i_prev->second.rank,i_prev->second.req); + } + } + + if(i->second.req) + { + SpellChainMap::iterator i_req = mSpellChains.find(i->second.req); + if(i_req == mSpellChains.end()) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has not found required rank spell in table.", + i->first,i->second.prev,i->second.first,i->second.rank,i->second.req); + } + else if( i_req->second.first == i->second.first ) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has required rank spell from same spell chain (prev: %u, first: %u, rank: %d, req: %u).", + i->first,i->second.prev,i->second.first,i->second.rank,i->second.req, + i_req->second.prev,i_req->second.first,i_req->second.rank,i_req->second.req); + } + else if( i_req->second.req ) + { + sLog.outErrorDb("Spell %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has required rank spell with required spell (prev: %u, first: %u, rank: %d, req: %u).", + i->first,i->second.prev,i->second.first,i->second.rank,i->second.req, + i_req->second.prev,i_req->second.first,i_req->second.rank,i_req->second.req); + } + } + } + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell chain records", count ); +} + +void SpellMgr::LoadSpellLearnSkills() +{ + mSpellLearnSkills.clear(); // need for reload case + + // search auto-learned skills and add its to map also for use in unlearn spells/talents + uint32 dbc_count = 0; + for(uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell) + { + SpellEntry const* entry = sSpellStore.LookupEntry(spell); + + if(!entry) + continue; + + for(int i = 0; i < 3; ++i) + { + if(entry->Effect[i]==SPELL_EFFECT_SKILL) + { + SpellLearnSkillNode dbc_node; + dbc_node.skill = entry->EffectMiscValue[i]; + if ( dbc_node.skill != SKILL_RIDING ) + dbc_node.value = 1; + else + dbc_node.value = (entry->EffectBasePoints[i]+1)*75; + dbc_node.maxvalue = (entry->EffectBasePoints[i]+1)*75; + + SpellLearnSkillNode const* db_node = GetSpellLearnSkill(spell); + + mSpellLearnSkills[spell] = dbc_node; + ++dbc_count; + break; + } + } + } + + sLog.outString(); + sLog.outString( ">> Loaded %u Spell Learn Skills from DBC", dbc_count ); +} + +void SpellMgr::LoadSpellLearnSpells() +{ + mSpellLearnSpells.clear(); // need for reload case + + QueryResult *result = WorldDatabase.PQuery("SELECT entry, SpellID FROM spell_learn_spell"); + if(!result) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded 0 spell learn spells" ); + sLog.outErrorDb("`spell_learn_spell` table is empty!"); + return; + } + + uint32 count = 0; + + barGoLink bar( result->GetRowCount() ); + do + { + bar.step(); + Field *fields = result->Fetch(); + + uint32 spell_id = fields[0].GetUInt32(); + + SpellLearnSpellNode node; + node.spell = fields[1].GetUInt32(); + node.autoLearned= false; + + if(!sSpellStore.LookupEntry(spell_id)) + { + sLog.outErrorDb("Spell %u listed in `spell_learn_spell` does not exist",spell_id); + continue; + } + + if(!sSpellStore.LookupEntry(node.spell)) + { + sLog.outErrorDb("Spell %u listed in `spell_learn_spell` does not exist",node.spell); + continue; + } + + mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spell_id,node)); + + ++count; + } while( result->NextRow() ); + + delete result; + + // search auto-learned spells and add its to map also for use in unlearn spells/talents + uint32 dbc_count = 0; + for(uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell) + { + SpellEntry const* entry = sSpellStore.LookupEntry(spell); + + if(!entry) + continue; + + for(int i = 0; i < 3; ++i) + { + if(entry->Effect[i]==SPELL_EFFECT_LEARN_SPELL) + { + SpellLearnSpellNode dbc_node; + dbc_node.spell = entry->EffectTriggerSpell[i]; + dbc_node.autoLearned = true; + + SpellLearnSpellMap::const_iterator db_node_begin = GetBeginSpellLearnSpell(spell); + SpellLearnSpellMap::const_iterator db_node_end = GetEndSpellLearnSpell(spell); + + bool found = false; + for(SpellLearnSpellMap::const_iterator itr = db_node_begin; itr != db_node_end; ++itr) + { + if(itr->second.spell == dbc_node.spell) + { + sLog.outErrorDb("Spell %u auto-learn spell %u in spell.dbc then the record in `spell_learn_spell` is redundant, please fix DB.", + spell,dbc_node.spell); + found = true; + break; + } + } + + if(!found) // add new spell-spell pair if not found + { + mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spell,dbc_node)); + ++dbc_count; + } + } + } + } + + sLog.outString(); + sLog.outString( ">> Loaded %u spell learn spells + %u found in DBC", count, dbc_count ); +} + +void SpellMgr::LoadSpellScriptTarget() +{ + mSpellScriptTarget.clear(); // need for reload case + + uint32 count = 0; + + QueryResult *result = WorldDatabase.Query("SELECT entry,type,targetEntry FROM spell_script_target"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 SpellScriptTarget. DB table `spell_script_target` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 spellId = fields[0].GetUInt32(); + uint32 type = fields[1].GetUInt32(); + uint32 targetEntry = fields[2].GetUInt32(); + + SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId); + + if(!spellProto) + { + sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not exist.",spellId,targetEntry); + continue; + } + + bool targetfound = false; + for(int i = 0; i <3; ++i) + { + if( spellProto->EffectImplicitTargetA[i]==TARGET_SCRIPT || + spellProto->EffectImplicitTargetB[i]==TARGET_SCRIPT || + spellProto->EffectImplicitTargetA[i]==TARGET_SCRIPT_COORDINATES || + spellProto->EffectImplicitTargetB[i]==TARGET_SCRIPT_COORDINATES ) + { + targetfound = true; + break; + } + } + if(!targetfound) + { + sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not have any implicit target TARGET_SCRIPT(38) or TARGET_SCRIPT_COORDINATES (46).",spellId,targetEntry); + continue; + } + + if( type >= MAX_SPELL_TARGET_TYPE ) + { + sLog.outErrorDb("Table `spell_script_target`: target type %u for TargetEntry %u is incorrect.",type,targetEntry); + continue; + } + + switch(type) + { + case SPELL_TARGET_TYPE_GAMEOBJECT: + { + if( targetEntry==0 ) + break; + + if(!sGOStorage.LookupEntry(targetEntry)) + { + sLog.outErrorDb("Table `spell_script_target`: gameobject template entry %u does not exist.",targetEntry); + continue; + } + break; + } + default: + { + if( targetEntry==0 ) + { + sLog.outErrorDb("Table `spell_script_target`: target entry == 0 for not GO target type (%u).",type); + continue; + } + if(!sCreatureStorage.LookupEntry(targetEntry)) + { + sLog.outErrorDb("Table `spell_script_target`: creature template entry %u does not exist.",targetEntry); + continue; + } + const CreatureInfo* cInfo = sCreatureStorage.LookupEntry(targetEntry); + + if(spellId == 30427 && !cInfo->SkinLootId) + { + sLog.outErrorDb("Table `spell_script_target` has creature %u as a target of spellid 30427, but this creature has no skinlootid. Gas extraction will not work!", cInfo->Entry); + continue; + } + break; + } + } + + mSpellScriptTarget.insert(SpellScriptTarget::value_type(spellId,SpellTargetEntry(SpellTargetType(type),targetEntry))); + + ++count; + } while (result->NextRow()); + + delete result; + + // Check all spells + /* Disabled (lot errors at this moment) + for(uint32 i = 1; i < sSpellStore.nCount; ++i) + { + SpellEntry const * spellInfo = sSpellStore.LookupEntry(i); + if(!spellInfo) + continue; + + bool found = false; + for(int j=0; j<3; ++j) + { + if( spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || spellInfo->EffectImplicitTargetA[j] != TARGET_SELF && spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT ) + { + SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(spellInfo->Id); + SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(spellInfo->Id); + if(lower==upper) + { + sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = %u (TARGET_SCRIPT), but does not have record in `spell_script_target`",spellInfo->Id,TARGET_SCRIPT); + break; // effects of spell + } + } + } + } + */ + + sLog.outString(); + sLog.outString(">> Loaded %u Spell Script Targets", count); +} + +void SpellMgr::LoadSpellPetAuras() +{ + mSpellPetAuraMap.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 2 + QueryResult *result = WorldDatabase.Query("SELECT spell, pet, aura FROM spell_pet_auras"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell pet auras", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + uint16 spell = fields[0].GetUInt16(); + uint16 pet = fields[1].GetUInt16(); + uint16 aura = fields[2].GetUInt16(); + + SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find(spell); + if(itr != mSpellPetAuraMap.end()) + { + itr->second.AddAura(pet, aura); + } + else + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if (!spellInfo) + { + sLog.outErrorDb("Spell %u listed in `spell_pet_auras` does not exist", spell); + continue; + } + int i = 0; + for(; i < 3; ++i) + if((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && + spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DUMMY) || + spellInfo->Effect[i] == SPELL_EFFECT_DUMMY) + break; + + if(i == 3) + { + sLog.outError("Spell %u listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell); + continue; + } + + SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(aura); + if (!spellInfo2) + { + sLog.outErrorDb("Aura %u listed in `spell_pet_auras` does not exist", aura); + continue; + } + + PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_PET, spellInfo->EffectBasePoints[i] + spellInfo->EffectBaseDice[i]); + mSpellPetAuraMap[spell] = pa; + } + + ++count; + } while( result->NextRow() ); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u spell pet auras", count ); +} + +/// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc +bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) +{ + // not exist + if(!spellInfo) + return false; + + bool need_check_reagents = false; + + // check effects + for(int i=0; i<3; ++i) + { + switch(spellInfo->Effect[i]) + { + case 0: + continue; + + // craft spell for crafting non-existed item (break client recipes list show) + case SPELL_EFFECT_CREATE_ITEM: + { + if(!ObjectMgr::GetItemPrototype( spellInfo->EffectItemType[i] )) + { + if(msg) + { + if(pl) + ChatHandler(pl).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...",spellInfo->Id,spellInfo->EffectItemType[i]); + else + sLog.outErrorDb("Craft spell %u create not-exist in DB item (Entry: %u) and then...",spellInfo->Id,spellInfo->EffectItemType[i]); + } + return false; + } + + need_check_reagents = true; + break; + } + case SPELL_EFFECT_LEARN_SPELL: + { + SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(spellInfo->EffectTriggerSpell[0]); + if( !IsSpellValid(spellInfo2,pl,msg) ) + { + if(msg) + { + if(pl) + ChatHandler(pl).PSendSysMessage("Spell %u learn to broken spell %u, and then...",spellInfo->Id,spellInfo->EffectTriggerSpell[0]); + else + sLog.outErrorDb("Spell %u learn to invalid spell %u, and then...",spellInfo->Id,spellInfo->EffectTriggerSpell[0]); + } + return false; + } + break; + } + } + } + + if(need_check_reagents) + { + for(int j = 0; j < 8; ++j) + { + if(spellInfo->Reagent[j] > 0 && !ObjectMgr::GetItemPrototype( spellInfo->Reagent[j] )) + { + if(msg) + { + if(pl) + ChatHandler(pl).PSendSysMessage("Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...",spellInfo->Id,spellInfo->Reagent[j]); + else + sLog.outErrorDb("Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...",spellInfo->Id,spellInfo->Reagent[j]); + } + return false; + } + } + } + + return true; +} + +bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id) +{ + // normal case + if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id ) + return false; + + // elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup) + if(spellInfo->SpellFamilyName==SPELLFAMILY_POTION) + { + if(uint32 mask = spellmgr.GetSpellElixirMask(spellInfo->Id)) + { + if(mask & ELIXIR_UNSTABLE_MASK) + { + // in the Blade's Edge Mountains Plateaus and Gruul's Lair. + return zone_id ==3522 || map_id==565; + } + if(mask & ELIXIR_UNSTABLE_MASK) + { + // in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple + // TODO: and the Sunwell Plateau + if(zone_id ==3607 || map_id==534 || map_id==564) + return true; + + MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); + if(!mapEntry) + return false; + + return mapEntry->multimap_id==206; + } + + // elixirs not have another limitations + return true; + } + } + + // special cases zone check (maps checked by multimap common id) + switch(spellInfo->Id) + { + case 41618: + case 41620: + { + MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); + if(!mapEntry) + return false; + + return mapEntry->multimap_id==206; + } + + case 41617: + case 41619: + { + MapEntry const* mapEntry = sMapStore.LookupEntry(map_id); + if(!mapEntry) + return false; + + return mapEntry->multimap_id==207; + } + // Dragonmaw Illusion + case 40216: + case 42016: + { + if ( area_id != 3759 && area_id != 3966 && area_id != 3939 ) + return false; + break; + } + } + + return true; +} + +void SpellMgr::LoadSkillLineAbilityMap() +{ + mSkillLineAbilityMap.clear(); + + uint32 count = 0; + + for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); i++) + { + SkillLineAbilityEntry const *SkillInfo = sSkillLineAbilityStore.LookupEntry(i); + if(!SkillInfo) + continue; + + mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->spellId,SkillInfo)); + ++count; + } + + sLog.outString(); + sLog.outString(">> Loaded %u SkillLineAbility MultiMap", count); +} + +DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered) +{ + // Explicit Diminishing Groups + switch(spellproto->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + { + // Polymorph + if ((spellproto->SpellFamilyFlags & 0x00001000000LL) && spellproto->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE) + return DIMINISHING_POLYMORPH; + break; + } + case SPELLFAMILY_ROGUE: + { + // Kidney Shot + if (spellproto->SpellFamilyFlags & 0x00000200000LL) + return DIMINISHING_KIDNEYSHOT; + // Blind + else if (spellproto->SpellFamilyFlags & 0x00001000000LL) + return DIMINISHING_BLIND_CYCLONE; + break; + } + case SPELLFAMILY_WARLOCK: + { + // Death Coil + if (spellproto->SpellFamilyFlags & 0x00000080000LL) + return DIMINISHING_DEATHCOIL; + // Fear + else if (spellproto->SpellFamilyFlags & 0x40840000000LL) + return DIMINISHING_WARLOCK_FEAR; + // Curses/etc + else if (spellproto->SpellFamilyFlags & 0x00080000000LL) + return DIMINISHING_LIMITONLY; + break; + } + case SPELLFAMILY_DRUID: + { + // Cyclone + if (spellproto->SpellFamilyFlags & 0x02000000000LL) + return DIMINISHING_BLIND_CYCLONE; + break; + } + case SPELLFAMILY_WARRIOR: + { + // Hamstring - limit duration to 10s in PvP + if (spellproto->SpellFamilyFlags & 0x00000000002LL) + return DIMINISHING_LIMITONLY; + break; + } + default: + break; + } + + // Get by mechanic + for (uint8 i=0;i<3;++i) + { + if (spellproto->Mechanic == MECHANIC_STUN || spellproto->EffectMechanic[i] == MECHANIC_STUN) + return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN; + else if (spellproto->Mechanic == MECHANIC_SLEEP || spellproto->EffectMechanic[i] == MECHANIC_SLEEP) + return DIMINISHING_SLEEP; + else if (spellproto->Mechanic == MECHANIC_ROOT || spellproto->EffectMechanic[i] == MECHANIC_ROOT) + return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT; + else if (spellproto->Mechanic == MECHANIC_FEAR || spellproto->EffectMechanic[i] == MECHANIC_FEAR) + return DIMINISHING_FEAR; + else if (spellproto->Mechanic == MECHANIC_CHARM || spellproto->EffectMechanic[i] == MECHANIC_CHARM) + return DIMINISHING_CHARM; + else if (spellproto->Mechanic == MECHANIC_SILENCE || spellproto->EffectMechanic[i] == MECHANIC_SILENCE) + return DIMINISHING_SILENCE; + else if (spellproto->Mechanic == MECHANIC_DISARM || spellproto->EffectMechanic[i] == MECHANIC_DISARM) + return DIMINISHING_DISARM; + else if (spellproto->Mechanic == MECHANIC_FREEZE || spellproto->EffectMechanic[i] == MECHANIC_FREEZE) + return DIMINISHING_FREEZE; + else if (spellproto->Mechanic == MECHANIC_KNOCKOUT|| spellproto->EffectMechanic[i] == MECHANIC_KNOCKOUT || + spellproto->Mechanic == MECHANIC_SAPPED || spellproto->EffectMechanic[i] == MECHANIC_SAPPED) + return DIMINISHING_KNOCKOUT; + else if (spellproto->Mechanic == MECHANIC_BANISH || spellproto->EffectMechanic[i] == MECHANIC_BANISH) + return DIMINISHING_BANISH; + } + + return DIMINISHING_NONE; +} + +bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group) +{ + switch(group) + { + case DIMINISHING_CONTROL_STUN: + case DIMINISHING_TRIGGER_STUN: + case DIMINISHING_KIDNEYSHOT: + case DIMINISHING_SLEEP: + case DIMINISHING_CONTROL_ROOT: + case DIMINISHING_TRIGGER_ROOT: + case DIMINISHING_FEAR: + case DIMINISHING_WARLOCK_FEAR: + case DIMINISHING_CHARM: + case DIMINISHING_POLYMORPH: + case DIMINISHING_FREEZE: + case DIMINISHING_KNOCKOUT: + case DIMINISHING_BLIND_CYCLONE: + case DIMINISHING_BANISH: + case DIMINISHING_LIMITONLY: + return true; + } + return false; +} + +DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group) +{ + switch(group) + { + case DIMINISHING_BLIND_CYCLONE: + case DIMINISHING_CONTROL_STUN: + case DIMINISHING_TRIGGER_STUN: + case DIMINISHING_KIDNEYSHOT: + return DRTYPE_ALL; + case DIMINISHING_SLEEP: + case DIMINISHING_CONTROL_ROOT: + case DIMINISHING_TRIGGER_ROOT: + case DIMINISHING_FEAR: + case DIMINISHING_CHARM: + case DIMINISHING_POLYMORPH: + case DIMINISHING_SILENCE: + case DIMINISHING_DISARM: + case DIMINISHING_DEATHCOIL: + case DIMINISHING_FREEZE: + case DIMINISHING_BANISH: + case DIMINISHING_WARLOCK_FEAR: + case DIMINISHING_KNOCKOUT: + return DRTYPE_PLAYER; + } + + return DRTYPE_NONE; +} diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h new file mode 100644 index 000000000..e67191b4d --- /dev/null +++ b/src/game/SpellMgr.h @@ -0,0 +1,863 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _SPELLMGR_H +#define _SPELLMGR_H + +// For static or at-server-startup loaded spell data +// For more high level function for sSpellStore data + +#include "SharedDefines.h" +#include "Database/DBCStructure.h" +#include "Database/SQLStorage.h" + +#include "Utilities/HashMap.h" +#include + +class Player; +class Spell; + +extern SQLStorage sSpellThreatStore; + +enum SpellFailedReason +{ + SPELL_FAILED_AFFECTING_COMBAT = 0x00, + SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01, + SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02, + SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03, + SPELL_FAILED_ALREADY_BEING_TAMED = 0x04, + SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05, + SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06, + SPELL_FAILED_ALREADY_OPEN = 0x07, + SPELL_FAILED_AURA_BOUNCED = 0x08, + SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09, + SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A, + SPELL_FAILED_BAD_TARGETS = 0x0B, + SPELL_FAILED_CANT_BE_CHARMED = 0x0C, + SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D, + SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E, + SPELL_FAILED_CANT_BE_PROSPECTED = 0x0F, + SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x10, + SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x11, + SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x12, + SPELL_FAILED_CANT_STEALTH = 0x13, + SPELL_FAILED_CASTER_AURASTATE = 0x14, + SPELL_FAILED_CASTER_DEAD = 0x15, + SPELL_FAILED_CHARMED = 0x16, + SPELL_FAILED_CHEST_IN_USE = 0x17, + SPELL_FAILED_CONFUSED = 0x18, + SPELL_FAILED_DONT_REPORT = 0x19, + SPELL_FAILED_EQUIPPED_ITEM = 0x1A, + SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1B, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1C, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1D, + SPELL_FAILED_ERROR = 0x1E, + SPELL_FAILED_FIZZLE = 0x1F, + SPELL_FAILED_FLEEING = 0x20, + SPELL_FAILED_FOOD_LOWLEVEL = 0x21, + SPELL_FAILED_HIGHLEVEL = 0x22, + SPELL_FAILED_HUNGER_SATIATED = 0x23, + SPELL_FAILED_IMMUNE = 0x24, + SPELL_FAILED_INTERRUPTED = 0x25, + SPELL_FAILED_INTERRUPTED_COMBAT = 0x26, + SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x27, + SPELL_FAILED_ITEM_GONE = 0x28, + SPELL_FAILED_ITEM_NOT_FOUND = 0x29, + SPELL_FAILED_ITEM_NOT_READY = 0x2A, + SPELL_FAILED_LEVEL_REQUIREMENT = 0x2B, + SPELL_FAILED_LINE_OF_SIGHT = 0x2C, + SPELL_FAILED_LOWLEVEL = 0x2D, + SPELL_FAILED_LOW_CASTLEVEL = 0x2E, + SPELL_FAILED_MAINHAND_EMPTY = 0x2F, + SPELL_FAILED_MOVING = 0x30, + SPELL_FAILED_NEED_AMMO = 0x31, + SPELL_FAILED_NEED_AMMO_POUCH = 0x32, + SPELL_FAILED_NEED_EXOTIC_AMMO = 0x33, + SPELL_FAILED_NOPATH = 0x34, + SPELL_FAILED_NOT_BEHIND = 0x35, + SPELL_FAILED_NOT_FISHABLE = 0x36, + SPELL_FAILED_NOT_FLYING = 0x37, + SPELL_FAILED_NOT_HERE = 0x38, + SPELL_FAILED_NOT_INFRONT = 0x39, + SPELL_FAILED_NOT_IN_CONTROL = 0x3A, + SPELL_FAILED_NOT_KNOWN = 0x3B, + SPELL_FAILED_NOT_MOUNTED = 0x3C, + SPELL_FAILED_NOT_ON_TAXI = 0x3D, + SPELL_FAILED_NOT_ON_TRANSPORT = 0x3E, + SPELL_FAILED_NOT_READY = 0x3F, + SPELL_FAILED_NOT_SHAPESHIFT = 0x40, + SPELL_FAILED_NOT_STANDING = 0x41, + SPELL_FAILED_NOT_TRADEABLE = 0x42, + SPELL_FAILED_NOT_TRADING = 0x43, + SPELL_FAILED_NOT_UNSHEATHED = 0x44, + SPELL_FAILED_NOT_WHILE_GHOST = 0x45, + SPELL_FAILED_NO_AMMO = 0x46, + SPELL_FAILED_NO_CHARGES_REMAIN = 0x47, + SPELL_FAILED_NO_CHAMPION = 0x48, + SPELL_FAILED_NO_COMBO_POINTS = 0x49, + SPELL_FAILED_NO_DUELING = 0x4A, + SPELL_FAILED_NO_ENDURANCE = 0x4B, + SPELL_FAILED_NO_FISH = 0x4C, + SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4D, + SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4E, + SPELL_FAILED_NO_PET = 0x4F, + SPELL_FAILED_NO_POWER = 0x50, + SPELL_FAILED_NOTHING_TO_DISPEL = 0x51, + SPELL_FAILED_NOTHING_TO_STEAL = 0x52, + SPELL_FAILED_ONLY_ABOVEWATER = 0x53, + SPELL_FAILED_ONLY_DAYTIME = 0x54, + SPELL_FAILED_ONLY_INDOORS = 0x55, + SPELL_FAILED_ONLY_MOUNTED = 0x56, + SPELL_FAILED_ONLY_NIGHTTIME = 0x57, + SPELL_FAILED_ONLY_OUTDOORS = 0x58, + SPELL_FAILED_ONLY_SHAPESHIFT = 0x59, + SPELL_FAILED_ONLY_STEALTHED = 0x5A, + SPELL_FAILED_ONLY_UNDERWATER = 0x5B, + SPELL_FAILED_OUT_OF_RANGE = 0x5C, + SPELL_FAILED_PACIFIED = 0x5D, + SPELL_FAILED_POSSESSED = 0x5E, + SPELL_FAILED_REAGENTS = 0x5F, + SPELL_FAILED_REQUIRES_AREA = 0x60, + SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x61, + SPELL_FAILED_ROOTED = 0x62, + SPELL_FAILED_SILENCED = 0x63, + SPELL_FAILED_SPELL_IN_PROGRESS = 0x64, + SPELL_FAILED_SPELL_LEARNED = 0x65, + SPELL_FAILED_SPELL_UNAVAILABLE = 0x66, + SPELL_FAILED_STUNNED = 0x67, + SPELL_FAILED_TARGETS_DEAD = 0x68, + SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x69, + SPELL_FAILED_TARGET_AURASTATE = 0x6A, + SPELL_FAILED_TARGET_DUELING = 0x6B, + SPELL_FAILED_TARGET_ENEMY = 0x6C, + SPELL_FAILED_TARGET_ENRAGED = 0x6D, + SPELL_FAILED_TARGET_FRIENDLY = 0x6E, + SPELL_FAILED_TARGET_IN_COMBAT = 0x6F, + SPELL_FAILED_TARGET_IS_PLAYER = 0x70, + SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x71, + SPELL_FAILED_TARGET_NOT_DEAD = 0x72, + SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x73, + SPELL_FAILED_TARGET_NOT_LOOTED = 0x74, + SPELL_FAILED_TARGET_NOT_PLAYER = 0x75, + SPELL_FAILED_TARGET_NO_POCKETS = 0x76, + SPELL_FAILED_TARGET_NO_WEAPONS = 0x77, + SPELL_FAILED_TARGET_UNSKINNABLE = 0x78, + SPELL_FAILED_THIRST_SATIATED = 0x79, + SPELL_FAILED_TOO_CLOSE = 0x7A, + SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7B, + SPELL_FAILED_TOTEM_CATEGORY = 0x7C, + SPELL_FAILED_TOTEMS = 0x7D, + SPELL_FAILED_TRAINING_POINTS = 0x7E, + SPELL_FAILED_TRY_AGAIN = 0x7F, + SPELL_FAILED_UNIT_NOT_BEHIND = 0x80, + SPELL_FAILED_UNIT_NOT_INFRONT = 0x81, + SPELL_FAILED_WRONG_PET_FOOD = 0x82, + SPELL_FAILED_NOT_WHILE_FATIGUED = 0x83, + SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x84, + SPELL_FAILED_NOT_WHILE_TRADING = 0x85, + SPELL_FAILED_TARGET_NOT_IN_RAID = 0x86, + SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x87, + SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x88, + SPELL_FAILED_PROSPECT_NEED_MORE = 0x89, + SPELL_FAILED_TARGET_FREEFORALL = 0x8A, + SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8B, + SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8C, + SPELL_FAILED_TARGET_NOT_GHOST = 0x8D, + SPELL_FAILED_TOO_MANY_SKILLS = 0x8E, + SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F, + SPELL_FAILED_WRONG_WEATHER = 0x90, + SPELL_FAILED_DAMAGE_IMMUNE = 0x91, + SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92, + SPELL_FAILED_PLAY_TIME = 0x93, + SPELL_FAILED_REPUTATION = 0x94, + SPELL_FAILED_MIN_SKILL = 0x95, + SPELL_FAILED_NOT_IN_ARENA = 0x96, + SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97, + SPELL_FAILED_NOT_ON_STEALTHED = 0x98, + SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99, + SPELL_FAILED_NOT_ON_MOUNTED = 0x9A, + SPELL_FAILED_TOO_SHALLOW = 0x9B, + SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C, + SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D, + SPELL_FAILED_BM_OR_INVISGOD = 0x9E, + SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F, + SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0, + SPELL_FAILED_NOT_IDLE = 0xA1, + SPELL_FAILED_NOT_INACTIVE = 0xA2, + SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3, + SPELL_FAILED_NO_PLAYTIME = 0xA4, + SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5, + SPELL_FAILED_ONLY_IN_ARENA = 0xA6, + SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7, + SPELL_FAILED_UNKNOWN = 0xA8, +}; + +enum SpellFamilyNames +{ + SPELLFAMILY_GENERIC = 0, + SPELLFAMILY_UNK1 = 1, // events, holidays + // 2 - unused + SPELLFAMILY_MAGE = 3, + SPELLFAMILY_WARRIOR = 4, + SPELLFAMILY_WARLOCK = 5, + SPELLFAMILY_PRIEST = 6, + SPELLFAMILY_DRUID = 7, + SPELLFAMILY_ROGUE = 8, + SPELLFAMILY_HUNTER = 9, + SPELLFAMILY_PALADIN = 10, + SPELLFAMILY_SHAMAN = 11, + SPELLFAMILY_UNK2 = 12, + SPELLFAMILY_POTION = 13, + // 14 - unused + SPELLFAMILY_DEATHKNIGHT = 15, + // 16 - unused + SPELLFAMILY_UNK3 = 17 +}; + +//Some SpellFamilyFlags +#define SPELLFAMILYFLAG_ROGUE_VANISH 0x000000800LL +#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x000400000LL +#define SPELLFAMILYFLAG_ROGUE_BACKSTAB 0x000800004LL +#define SPELLFAMILYFLAG_ROGUE_SAP 0x000000080LL +#define SPELLFAMILYFLAG_ROGUE_FEINT 0x008000000LL +#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x000200000LL +#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL + +// Spell clasification +enum SpellSpecific +{ + SPELL_NORMAL = 0, + SPELL_SEAL = 1, + SPELL_BLESSING = 2, + SPELL_AURA = 3, + SPELL_STING = 4, + SPELL_CURSE = 5, + SPELL_ASPECT = 6, + SPELL_TRACKER = 7, + SPELL_WARLOCK_ARMOR = 8, + SPELL_MAGE_ARMOR = 9, + SPELL_ELEMENTAL_SHIELD = 10, + SPELL_MAGE_POLYMORPH = 11, + SPELL_POSITIVE_SHOUT = 12, + SPELL_JUDGEMENT = 13, + SPELL_BATTLE_ELIXIR = 14, + SPELL_GUARDIAN_ELIXIR = 15, + SPELL_FLASK_ELIXIR = 16 +}; + +SpellSpecific GetSpellSpecific(uint32 spellId); + +// Different spell properties +inline float GetSpellRadius(SpellRadiusEntry const *radius) { return (radius ? radius->Radius : 0); } +uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL); +inline float GetSpellMinRange(SpellRangeEntry const *range) { return (range ? range->minRange : 0); } +inline float GetSpellMaxRange(SpellRangeEntry const *range) { return (range ? range->maxRange : 0); } +inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; } +int32 GetSpellDuration(SpellEntry const *spellInfo); +int32 GetSpellMaxDuration(SpellEntry const *spellInfo); + +inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect) +{ + for(int i= 0; i < 3; ++i) + if(spellInfo->Effect[i]==effect) + return true; + return false; +} + +bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); + +inline bool IsSealSpell(SpellEntry const *spellInfo) +{ + //Collection of all the seal family flags. No other paladin spell has any of those. + return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && + ( spellInfo->SpellFamilyFlags & 0x4000A000200LL ); +} + +inline bool IsElementalShield(SpellEntry const *spellInfo) +{ + // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus + return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552; +} + +int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); +bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2); +bool IsPassiveSpell(uint32 spellId); + +inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo) +{ + switch(spellInfo->Id) + { + case 40214: // Dragonmaw Illusion + case 35480: case 35481: case 35482: // Human Illusion + case 35483: case 39824: // Human Illusion + return true; + } + + return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_DEATH_PERSISTENT; +} + +inline bool IsNonCombatSpell(SpellEntry const *spellInfo) +{ + return (spellInfo->Attributes & SPELL_ATTR_CANT_USED_IN_COMBAT) != 0; +} + +bool IsPositiveSpell(uint32 spellId); +bool IsPositiveEffect(uint32 spellId, uint32 effIndex); +bool IsPositiveTarget(uint32 targetA, uint32 targetB); + +bool IsSingleTargetSpell(SpellEntry const *spellInfo); +bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2); + +bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id); + +inline bool IsAreaEffectTarget( Targets target ) +{ + switch (target ) + { + case TARGET_AREAEFFECT_CUSTOM: + case TARGET_ALL_ENEMY_IN_AREA: + case TARGET_ALL_ENEMY_IN_AREA_INSTANT: + case TARGET_ALL_PARTY_AROUND_CASTER: + case TARGET_ALL_AROUND_CASTER: + case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: + case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: + case TARGET_ALL_PARTY: + case TARGET_ALL_PARTY_AROUND_CASTER_2: + case TARGET_AREAEFFECT_PARTY: + case TARGET_AREAEFFECT_CUSTOM_2: + case TARGET_AREAEFFECT_PARTY_AND_CLASS: + case TARGET_IN_FRONT_OF_CASTER: + case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: + return true; + default: + break; + } + return false; +} + +inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo) +{ + if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[0]))) + return true; + if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[1])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[1]))) + return true; + if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[2])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[2]))) + return true; + return false; +} + +inline bool IsAreaAuraEffect(uint32 effect) +{ + if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || + effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND || + effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || + effect == SPELL_EFFECT_APPLY_AREA_AURA_PET || + effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER) + return true; + return false; +} + +inline bool IsDispelSpell(SpellEntry const *spellInfo) +{ + if (spellInfo->Effect[0] == SPELL_EFFECT_DISPEL || + spellInfo->Effect[1] == SPELL_EFFECT_DISPEL || + spellInfo->Effect[2] == SPELL_EFFECT_DISPEL ) + return true; + return false; +} +inline bool isSpellBreakStealth(SpellEntry const* spellInfo) +{ + return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH); +} + +uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form); + +inline bool IsChanneledSpell(SpellEntry const* spellInfo) +{ + return (spellInfo->AttributesEx & (SPELL_ATTR_EX_CHANNELED_1 | SPELL_ATTR_EX_CHANNELED_2)); +} + +inline bool NeedsComboPoints(SpellEntry const* spellInfo) +{ + return (spellInfo->AttributesEx & (SPELL_ATTR_EX_REQ_COMBO_POINTS1 | SPELL_ATTR_EX_REQ_COMBO_POINTS2)); +} + +inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo) +{ + return SpellSchoolMask(spellInfo->SchoolMask); +} + +inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect) +{ + uint32 mask = 0; + if (spellInfo->Mechanic) + mask |= 1<Mechanic; + if (spellInfo->EffectMechanic[effect]) + mask |= 1<EffectMechanic[effect]; + return mask; +} + +inline Mechanics GetEffectMechanic(SpellEntry const* spellInfo, int32 effect) +{ + if (spellInfo->EffectMechanic[effect]) + return Mechanics(spellInfo->EffectMechanic[effect]); + if (spellInfo->Mechanic) + return Mechanics(spellInfo->Mechanic); + return MECHANIC_NONE; +} + +inline uint32 GetDispellMask(DispelType dispel) +{ + // If dispell all + if (dispel == DISPEL_ALL) + return DISPEL_ALL_MASK; + else + return (1 << dispel); +} + +// Diminishing Returns interaction with spells +DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered); +bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group); +DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group); + +// Spell affects related declarations (accessed using SpellMgr functions) +typedef std::map SpellAffectMap; + +// Spell proc event related declarations (accessed using SpellMgr functions) +enum ProcFlags +{ + PROC_FLAG_NONE = 0x00000000, // None + PROC_FLAG_HIT_MELEE = 0x00000001, // On melee hit + PROC_FLAG_STRUCK_MELEE = 0x00000002, // On being struck melee + PROC_FLAG_KILL_XP_GIVER = 0x00000004, // On kill target giving XP or honor + PROC_FLAG_SPECIAL_DROP = 0x00000008, // + PROC_FLAG_DODGE = 0x00000010, // On dodge melee attack + PROC_FLAG_PARRY = 0x00000020, // On parry melee attack + PROC_FLAG_BLOCK = 0x00000040, // On block attack + PROC_FLAG_TOUCH = 0x00000080, // On being touched (for bombs, probably?) + PROC_FLAG_TARGET_LOW_HEALTH = 0x00000100, // On deal damage to enemy with 20% or less health + PROC_FLAG_LOW_HEALTH = 0x00000200, // On health dropped below 20% + PROC_FLAG_STRUCK_RANGED = 0x00000400, // On being struck ranged + PROC_FLAG_HIT_SPECIAL = 0x00000800, // (!)Removed, may be reassigned in future + PROC_FLAG_CRIT_MELEE = 0x00001000, // On crit melee + PROC_FLAG_STRUCK_CRIT_MELEE = 0x00002000, // On being critically struck in melee + PROC_FLAG_CAST_SPELL = 0x00004000, // On cast spell + PROC_FLAG_TAKE_DAMAGE = 0x00008000, // On take damage + PROC_FLAG_CRIT_SPELL = 0x00010000, // On crit spell + PROC_FLAG_HIT_SPELL = 0x00020000, // On hit spell + PROC_FLAG_STRUCK_CRIT_SPELL = 0x00040000, // On being critically struck by a spell + PROC_FLAG_HIT_RANGED = 0x00080000, // On getting ranged hit + PROC_FLAG_STRUCK_SPELL = 0x00100000, // On being struck by a spell + PROC_FLAG_TRAP = 0x00200000, // On trap activation (?) + PROC_FLAG_CRIT_RANGED = 0x00400000, // On getting ranged crit + PROC_FLAG_STRUCK_CRIT_RANGED = 0x00800000, // On being critically struck by a ranged attack + PROC_FLAG_RESIST_SPELL = 0x01000000, // On resist enemy spell + PROC_FLAG_TARGET_RESISTS = 0x02000000, // On enemy resisted spell + PROC_FLAG_TARGET_DODGE_OR_PARRY = 0x04000000, // On enemy dodges/parries + PROC_FLAG_HEAL = 0x08000000, // On heal + PROC_FLAG_CRIT_HEAL = 0x10000000, // On critical healing effect + PROC_FLAG_HEALED = 0x20000000, // On healing + PROC_FLAG_TARGET_BLOCK = 0x40000000, // On enemy blocks + PROC_FLAG_MISS = 0x80000000 // On miss melee attack +}; + +struct SpellProcEventEntry +{ + uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2 + uint32 category; // if nonzero - match proc condition based on candidate spell's category + uint32 skillId; // if nonzero - for matching proc condition based on candidate spell's skillId from SkillLineAbility.dbc (Shadow Bolt = Destruction) + uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value + uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) + uint32 procFlags; // bitmask for matching proc event + float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc + uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_ +}; + +typedef HM_NAMESPACE::hash_map SpellProcEventMap; + +#define ELIXIR_BATTLE_MASK 0x1 +#define ELIXIR_GUARDIAN_MASK 0x2 +#define ELIXIR_FLASK_MASK (ELIXIR_BATTLE_MASK|ELIXIR_GUARDIAN_MASK) +#define ELIXIR_UNSTABLE_MASK 0x4 +#define ELIXIR_SHATTRATH_MASK 0x8 + +typedef std::map SpellElixirMap; + +// Spell script target related declarations (accessed using SpellMgr functions) +enum SpellTargetType +{ + SPELL_TARGET_TYPE_GAMEOBJECT = 0, + SPELL_TARGET_TYPE_CREATURE = 1, + SPELL_TARGET_TYPE_DEAD = 2 +}; + +#define MAX_SPELL_TARGET_TYPE 3 + +struct SpellTargetEntry +{ + SpellTargetEntry(SpellTargetType type_,uint32 targetEntry_) : type(type_), targetEntry(targetEntry_) {} + SpellTargetType type; + uint32 targetEntry; +}; + +typedef std::multimap SpellScriptTarget; + +// coordinates for spells (accessed using SpellMgr functions) +struct SpellTargetPosition +{ + uint32 target_mapId; + float target_X; + float target_Y; + float target_Z; + float target_Orientation; +}; + +typedef HM_NAMESPACE::hash_map SpellTargetPositionMap; + +// Spell pet auras +class PetAura +{ + public: + PetAura() + { + auras.clear(); + } + + PetAura(uint16 petEntry, uint16 aura, bool _removeOnChangePet, int _damage) : + removeOnChangePet(_removeOnChangePet), damage(_damage) + { + auras[petEntry] = aura; + } + + uint16 GetAura(uint16 petEntry) const + { + std::map::const_iterator itr = auras.find(petEntry); + if(itr != auras.end()) + return itr->second; + else + { + std::map::const_iterator itr = auras.find(0); + if(itr != auras.end()) + return itr->second; + else + return 0; + } + } + + void AddAura(uint16 petEntry, uint16 aura) + { + auras[petEntry] = aura; + } + + bool IsRemovedOnChangePet() const + { + return removeOnChangePet; + } + + int32 GetDamage() const + { + return damage; + } + + private: + std::map auras; + bool removeOnChangePet; + int32 damage; +}; +typedef std::map SpellPetAuraMap; + +// Spell rank chain (accessed using SpellMgr functions) +struct SpellChainNode +{ + uint32 prev; + uint32 first; + uint32 req; + uint8 rank; +}; + +typedef HM_NAMESPACE::hash_map SpellChainMap; +typedef std::multimap SpellChainMapNext; + +// Spell learning properties (accessed using SpellMgr functions) +struct SpellLearnSkillNode +{ + uint32 skill; + uint32 value; // 0 - max skill value for player level + uint32 maxvalue; // 0 - max skill value for player level +}; + +typedef std::map SpellLearnSkillMap; + +struct SpellLearnSpellNode +{ + uint32 spell; + bool autoLearned; +}; + +typedef std::multimap SpellLearnSpellMap; + +typedef std::multimap SkillLineAbilityMap; + +inline bool IsPrimaryProfessionSkill(uint32 skill) +{ + SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill); + if(!pSkill) + return false; + + if(pSkill->categoryId != SKILL_CATEGORY_PROFESSION) + return false; + + return true; +} + +inline bool IsProfessionSkill(uint32 skill) +{ + return IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID; +} + +class SpellMgr +{ + // Constructors + public: + SpellMgr(); + ~SpellMgr(); + + // Accessors (const or static functions) + public: + // Spell affects + uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const + { + SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId); + if( itr != mSpellAffectMap.end( ) ) + return itr->second; + return 0; + } + + bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const; + + SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; } + + uint32 GetSpellElixirMask(uint32 spellid) const + { + SpellElixirMap::const_iterator itr = mSpellElixirs.find(spellid); + if(itr==mSpellElixirs.end()) + return 0x0; + + return itr->second; + } + + SpellSpecific GetSpellElixirSpecific(uint32 spellid) const + { + uint32 mask = GetSpellElixirMask(spellid); + if((mask & ELIXIR_FLASK_MASK)==ELIXIR_FLASK_MASK) + return SPELL_FLASK_ELIXIR; + else if(mask & ELIXIR_BATTLE_MASK) + return SPELL_BATTLE_ELIXIR; + else if(mask & ELIXIR_GUARDIAN_MASK) + return SPELL_GUARDIAN_ELIXIR; + else + return SPELL_NORMAL; + } + + // Spell proc events + SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const + { + SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId); + if( itr != mSpellProcEventMap.end( ) ) + return &itr->second; + return NULL; + } + + static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags ); + + // Spell target coordinates + SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const + { + SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find( spell_id ); + if( itr != mSpellTargetPositions.end( ) ) + return &itr->second; + return NULL; + } + + // Spell ranks chains + SpellChainNode const* GetSpellChainNode(uint32 spell_id) const + { + SpellChainMap::const_iterator itr = mSpellChains.find(spell_id); + if(itr == mSpellChains.end()) + return NULL; + + return &itr->second; + } + + uint32 GetFirstSpellInChain(uint32 spell_id) const + { + if(SpellChainNode const* node = GetSpellChainNode(spell_id)) + return node->first; + + return spell_id; + } + + uint32 GetPrevSpellInChain(uint32 spell_id) const + { + if(SpellChainNode const* node = GetSpellChainNode(spell_id)) + return node->prev; + + return 0; + } + + SpellChainMapNext const& GetSpellChainNext() const { return mSpellChainsNext; } + + // Note: not use rank for compare to spell ranks: spell chains isn't linear order + // Use IsHighRankOfSpell instead + uint8 GetSpellRank(uint32 spell_id) const + { + if(SpellChainNode const* node = GetSpellChainNode(spell_id)) + return node->rank; + + return 0; + } + + uint8 IsHighRankOfSpell(uint32 spell1,uint32 spell2) const + { + SpellChainMap::const_iterator itr = mSpellChains.find(spell1); + + uint32 rank2 = GetSpellRank(spell2); + + // not ordered correctly by rank value + if(itr == mSpellChains.end() || !rank2 || itr->second.rank <= rank2) + return false; + + // check present in same rank chain + for(; itr != mSpellChains.end(); itr = mSpellChains.find(itr->second.prev)) + if(itr->second.prev==spell2) + return true; + + return false; + } + + bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const; + static bool canStackSpellRanks(SpellEntry const *spellInfo); + bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const; + + SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const; + + // Spell learning + SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const + { + SpellLearnSkillMap::const_iterator itr = mSpellLearnSkills.find(spell_id); + if(itr != mSpellLearnSkills.end()) + return &itr->second; + else + return NULL; + } + + bool IsSpellLearnSpell(uint32 spell_id) const + { + return mSpellLearnSpells.count(spell_id)!=0; + } + + SpellLearnSpellMap::const_iterator GetBeginSpellLearnSpell(uint32 spell_id) const + { + return mSpellLearnSpells.lower_bound(spell_id); + } + + SpellLearnSpellMap::const_iterator GetEndSpellLearnSpell(uint32 spell_id) const + { + return mSpellLearnSpells.upper_bound(spell_id); + } + + bool IsSpellLearnToSpell(uint32 spell_id1,uint32 spell_id2) const + { + SpellLearnSpellMap::const_iterator b = GetBeginSpellLearnSpell(spell_id1); + SpellLearnSpellMap::const_iterator e = GetEndSpellLearnSpell(spell_id1); + for(SpellLearnSpellMap::const_iterator i = b; i != e; ++i) + if(i->second.spell==spell_id2) + return true; + return false; + } + + static bool IsProfessionSpell(uint32 spellId); + static bool IsPrimaryProfessionSpell(uint32 spellId); + bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const; + + // Spell script targets + SpellScriptTarget::const_iterator GetBeginSpellScriptTarget(uint32 spell_id) const + { + return mSpellScriptTarget.lower_bound(spell_id); + } + + SpellScriptTarget::const_iterator GetEndSpellScriptTarget(uint32 spell_id) const + { + return mSpellScriptTarget.upper_bound(spell_id); + } + + // Spell correctess for client using + static bool IsSpellValid(SpellEntry const * spellInfo, Player* pl = NULL, bool msg = true); + + SkillLineAbilityMap::const_iterator GetBeginSkillLineAbilityMap(uint32 spell_id) const + { + return mSkillLineAbilityMap.lower_bound(spell_id); + } + + SkillLineAbilityMap::const_iterator GetEndSkillLineAbilityMap(uint32 spell_id) const + { + return mSkillLineAbilityMap.upper_bound(spell_id); + } + + PetAura const* GetPetAura(uint16 spell_id) + { + SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find(spell_id); + if(itr != mSpellPetAuraMap.end()) + return &itr->second; + else + return NULL; + } + + // Modifiers + public: + static SpellMgr& Instance(); + + // Loading data at server startup + void LoadSpellChains(); + void LoadSpellLearnSkills(); + void LoadSpellLearnSpells(); + void LoadSpellScriptTarget(); + void LoadSpellAffects(); + void LoadSpellElixirs(); + void LoadSpellProcEvents(); + void LoadSpellTargetPositions(); + void LoadSpellThreats(); + void LoadSkillLineAbilityMap(); + void LoadSpellPetAuras(); + + private: + SpellScriptTarget mSpellScriptTarget; + SpellChainMap mSpellChains; + SpellChainMapNext mSpellChainsNext; + SpellLearnSkillMap mSpellLearnSkills; + SpellLearnSpellMap mSpellLearnSpells; + SpellTargetPositionMap mSpellTargetPositions; + SpellAffectMap mSpellAffectMap; + SpellElixirMap mSpellElixirs; + SpellProcEventMap mSpellProcEventMap; + SkillLineAbilityMap mSkillLineAbilityMap; + SpellPetAuraMap mSpellPetAuraMap; +}; + +#define spellmgr SpellMgr::Instance() +#endif diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp new file mode 100644 index 000000000..f2157017a --- /dev/null +++ b/src/game/StatSystem.cpp @@ -0,0 +1,965 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Unit.h" +#include "Player.h" +#include "Pet.h" +#include "Creature.h" +#include "SharedDefines.h" +#include "SpellAuras.h" + +/*####################################### +######## ######## +######## PLAYERS STAT SYSTEM ######## +######## ######## +#######################################*/ + +bool Player::UpdateStats(Stats stat) +{ + if(stat > STAT_SPIRIT) + return false; + + // value = ((base_value * base_pct) + total_value) * total_pct + float value = GetTotalStatValue(stat); + + SetStat(stat, int32(value)); + + if(stat == STAT_STAMINA || stat == STAT_INTELLECT) + { + Pet *pet = GetPet(); + if(pet) + pet->UpdateStats(stat); + } + + switch(stat) + { + case STAT_STRENGTH: + UpdateAttackPowerAndDamage(); + UpdateShieldBlockValue(); + break; + case STAT_AGILITY: + UpdateArmor(); + UpdateAttackPowerAndDamage(true); + if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT) + UpdateAttackPowerAndDamage(); + + UpdateAllCritPercentages(); + UpdateDodgePercentage(); + break; + + case STAT_STAMINA: UpdateMaxHealth(); break; + case STAT_INTELLECT: + UpdateMaxPower(POWER_MANA); + UpdateAllSpellCritChances(); + UpdateAttackPowerAndDamage(true); //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intelect currently + UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently + break; + + case STAT_SPIRIT: + break; + + default: + break; + } + UpdateSpellDamageAndHealingBonus(); + UpdateManaRegen(); + return true; +} + +void Player::UpdateSpellDamageAndHealingBonus() +{ + // Magic damage modifiers implemented in Unit::SpellDamageBonus + // This information for client side use only + // Get healing bonus for all schools + SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonus(SPELL_SCHOOL_MASK_ALL)); + // Get damage bonus for all schools + for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) + SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonus(SpellSchoolMask(1 << i))); +} + +bool Player::UpdateAllStats() +{ + for (int i = STAT_STRENGTH; i < MAX_STATS; i++) + { + float value = GetTotalStatValue(Stats(i)); + SetStat(Stats(i), (int32)value); + } + + UpdateAttackPowerAndDamage(); + UpdateAttackPowerAndDamage(true); + UpdateArmor(); + UpdateMaxHealth(); + + for(int i = POWER_MANA; i < MAX_POWERS; i++) + UpdateMaxPower(Powers(i)); + + UpdateAllCritPercentages(); + UpdateAllSpellCritChances(); + UpdateDefenseBonusesMod(); + UpdateShieldBlockValue(); + UpdateSpellDamageAndHealingBonus(); + UpdateManaRegen(); + UpdateExpertise(BASE_ATTACK); + UpdateExpertise(OFF_ATTACK); + for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++) + UpdateResistances(i); + + return true; +} + +void Player::UpdateResistances(uint32 school) +{ + if(school > SPELL_SCHOOL_NORMAL) + { + float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); + SetResistance(SpellSchools(school), int32(value)); + + Pet *pet = GetPet(); + if(pet) + pet->UpdateResistances(school); + } + else + UpdateArmor(); +} + +void Player::UpdateArmor() +{ + float value = 0.0f; + UnitMods unitMod = UNIT_MOD_ARMOR; + + value = GetModifierValue(unitMod, BASE_VALUE); // base armor (from items) + value *= GetModifierValue(unitMod, BASE_PCT); // armor percent from items + value += GetStat(STAT_AGILITY) * 2.0f; // armor bonus from stats + value += GetModifierValue(unitMod, TOTAL_VALUE); + + //add dynamic flat mods + AuraList const& mResbyIntellect = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT); + for(AuraList::const_iterator i = mResbyIntellect.begin();i != mResbyIntellect.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if(mod->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) + value += int32(GetStat(Stats((*i)->GetMiscBValue())) * mod->m_amount / 100.0f); + } + + value *= GetModifierValue(unitMod, TOTAL_PCT); + + SetArmor(int32(value)); + + Pet *pet = GetPet(); + if(pet) + pet->UpdateArmor(); +} + +float Player::GetHealthBonusFromStamina() +{ + float stamina = GetStat(STAT_STAMINA); + + float baseStam = stamina < 20 ? stamina : 20; + float moreStam = stamina - baseStam; + + return baseStam + (moreStam*10.0f); +} + +float Player::GetManaBonusFromIntellect() +{ + float intellect = GetStat(STAT_INTELLECT); + + float baseInt = intellect < 20 ? intellect : 20; + float moreInt = intellect - baseInt; + + return baseInt + (moreInt*15.0f); +} + +void Player::UpdateMaxHealth() +{ + UnitMods unitMod = UNIT_MOD_HEALTH; + + float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth(); + value *= GetModifierValue(unitMod, BASE_PCT); + value += GetModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina(); + value *= GetModifierValue(unitMod, TOTAL_PCT); + + SetMaxHealth((uint32)value); +} + +void Player::UpdateMaxPower(Powers power) +{ + UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); + + float bonusPower = (power == POWER_MANA) ? GetManaBonusFromIntellect() : 0; + + float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); + value *= GetModifierValue(unitMod, BASE_PCT); + value += GetModifierValue(unitMod, TOTAL_VALUE) + bonusPower; + value *= GetModifierValue(unitMod, TOTAL_PCT); + + SetMaxPower(power, uint32(value)); +} + +void Player::UpdateAttackPowerAndDamage(bool ranged ) +{ + float val2 = 0.0f; + float level = float(getLevel()); + + UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; + + uint16 index = UNIT_FIELD_ATTACK_POWER; + uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; + uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; + + if(ranged) + { + index = UNIT_FIELD_RANGED_ATTACK_POWER; + index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; + index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; + + switch(getClass()) + { + case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break; + case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; + case CLASS_WARRIOR:val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; + case CLASS_DRUID: + switch(m_form) + { + case FORM_CAT: + case FORM_BEAR: + case FORM_DIREBEAR: + val2 = 0.0f; break; + default: + val2 = GetStat(STAT_AGILITY) - 10.0f; break; + } + break; + default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; + } + } + else + { + switch(getClass()) + { + case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; + case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; + case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + case CLASS_DRUID: + { + //Check if Predatory Strikes is skilled + float mLevelMult = 0.0; + switch(m_form) + { + case FORM_CAT: + case FORM_BEAR: + case FORM_DIREBEAR: + case FORM_MOONKIN: + { + Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) + { + // Predatory Strikes + if ((*itr)->GetSpellProto()->SpellIconID == 1563) + { + mLevelMult = (*itr)->GetModifier()->m_amount / 100.0f; + break; + } + } + break; + } + } + + switch(m_form) + { + case FORM_CAT: + val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f; break; + case FORM_BEAR: + case FORM_DIREBEAR: + val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + case FORM_MOONKIN: + val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + default: + val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + } + break; + } + case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; + case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; + case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; + } + } + + SetModifierValue(unitMod, BASE_VALUE, val2); + + float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); + float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); + + //add dynamic flat mods + if( ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0) + { + AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); + for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) + attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); + } + + float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; + + SetUInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field + SetUInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field + SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field + + //automatically update weapon damage after attack power modification + if(ranged) + { + UpdateDamagePhysical(RANGED_ATTACK); + + Pet *pet = GetPet(); //update pet's AP + if(pet) + pet->UpdateAttackPowerAndDamage(); + } + else + { + UpdateDamagePhysical(BASE_ATTACK); + if(CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon + UpdateDamagePhysical(OFF_ATTACK); + } +} + +void Player::UpdateShieldBlockValue() +{ + SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue()); +} + +void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage) +{ + UnitMods unitMod; + UnitMods attPower; + + switch(attType) + { + case BASE_ATTACK: + default: + unitMod = UNIT_MOD_DAMAGE_MAINHAND; + attPower = UNIT_MOD_ATTACK_POWER; + break; + case OFF_ATTACK: + unitMod = UNIT_MOD_DAMAGE_OFFHAND; + attPower = UNIT_MOD_ATTACK_POWER; + break; + case RANGED_ATTACK: + unitMod = UNIT_MOD_DAMAGE_RANGED; + attPower = UNIT_MOD_ATTACK_POWER_RANGED; + break; + } + + float att_speed = GetAPMultiplier(attType,normalized); + + float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; + float base_pct = GetModifierValue(unitMod, BASE_PCT); + float total_value = GetModifierValue(unitMod, TOTAL_VALUE); + float total_pct = GetModifierValue(unitMod, TOTAL_PCT); + + float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); + float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); + + if (IsInFeralForm()) //check if player is druid and in cat or bear forms + { + uint32 lvl = getLevel(); + if ( lvl > 60 ) lvl = 60; + + weapon_mindamage = lvl*0.85*att_speed; + weapon_maxdamage = lvl*1.25*att_speed; + } + else if(!IsUseEquipedWeapon(attType==BASE_ATTACK)) //check if player not in form but still can't use weapon (broken/etc) + { + weapon_mindamage = BASE_MINDAMAGE; + weapon_maxdamage = BASE_MAXDAMAGE; + } + else if(attType == RANGED_ATTACK) //add ammo DPS to ranged damage + { + weapon_mindamage += GetAmmoDPS() * att_speed; + weapon_maxdamage += GetAmmoDPS() * att_speed; + } + + min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; + max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; +} + +void Player::UpdateDamagePhysical(WeaponAttackType attType) +{ + float mindamage; + float maxdamage; + + CalculateMinMaxDamage(attType,false,mindamage,maxdamage); + + switch(attType) + { + case BASE_ATTACK: + default: + SetStatFloatValue(UNIT_FIELD_MINDAMAGE,mindamage); + SetStatFloatValue(UNIT_FIELD_MAXDAMAGE,maxdamage); + break; + case OFF_ATTACK: + SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE,mindamage); + SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE,maxdamage); + break; + case RANGED_ATTACK: + SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,mindamage); + SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,maxdamage); + break; + } +} + +void Player::UpdateDefenseBonusesMod() +{ + UpdateBlockPercentage(); + UpdateParryPercentage(); + UpdateDodgePercentage(); +} + +void Player::UpdateBlockPercentage() +{ + // No block + float value = 0.0f; + if(CanBlock()) + { + // Base value + value = 5.0f; + // Modify value from defense skill + value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f; + // Increase from SPELL_AURA_MOD_BLOCK_PERCENT aura + value += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT); + // Increase from rating + value += GetRatingBonusValue(CR_BLOCK); + value = value < 0.0f ? 0.0f : value; + } + SetStatFloatValue(PLAYER_BLOCK_PERCENTAGE, value); +} + +void Player::UpdateCritPercentage(WeaponAttackType attType) +{ + BaseModGroup modGroup; + uint16 index; + CombatRating cr; + + switch(attType) + { + case OFF_ATTACK: + modGroup = OFFHAND_CRIT_PERCENTAGE; + index = PLAYER_OFFHAND_CRIT_PERCENTAGE; + cr = CR_CRIT_MELEE; + break; + case RANGED_ATTACK: + modGroup = RANGED_CRIT_PERCENTAGE; + index = PLAYER_RANGED_CRIT_PERCENTAGE; + cr = CR_CRIT_RANGED; + break; + case BASE_ATTACK: + default: + modGroup = CRIT_PERCENTAGE; + index = PLAYER_CRIT_PERCENTAGE; + cr = CR_CRIT_MELEE; + break; + } + + float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr); + // Modify crit from weapon skill and maximized defense skill of same level victim difference + value += (int32(GetWeaponSkillValue(attType)) - int32(GetMaxSkillValueForLevel())) * 0.04f; + value = value < 0.0f ? 0.0f : value; + SetStatFloatValue(index, value); +} + +void Player::UpdateAllCritPercentages() +{ + float value = GetMeleeCritFromAgility(); + + SetBaseModValue(CRIT_PERCENTAGE, PCT_MOD, value); + SetBaseModValue(OFFHAND_CRIT_PERCENTAGE, PCT_MOD, value); + SetBaseModValue(RANGED_CRIT_PERCENTAGE, PCT_MOD, value); + + UpdateCritPercentage(BASE_ATTACK); + UpdateCritPercentage(OFF_ATTACK); + UpdateCritPercentage(RANGED_ATTACK); +} + +void Player::UpdateParryPercentage() +{ + // No parry + float value = 0.0f; + if (CanParry()) + { + // Base parry + value = 5.0f; + // Modify value from defense skill + value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f; + // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura + value += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT); + // Parry from rating + value += GetRatingBonusValue(CR_PARRY); + value = value < 0.0f ? 0.0f : value; + } + SetStatFloatValue(PLAYER_PARRY_PERCENTAGE, value); +} + +void Player::UpdateDodgePercentage() +{ + // Dodge from agility + float value = GetDodgeFromAgility(); + // Modify value from defense skill + value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f; + // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura + value += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT); + // Dodge from rating + value += GetRatingBonusValue(CR_DODGE); + value = value < 0.0f ? 0.0f : value; + SetStatFloatValue(PLAYER_DODGE_PERCENTAGE, value); +} + +void Player::UpdateSpellCritChance(uint32 school) +{ + // For normal school set zero crit chance + if(school == SPELL_SCHOOL_NORMAL) + { + SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1, 0.0f); + return; + } + // For others recalculate it from: + float crit = 0.0f; + // Crit from Intellect + crit += GetSpellCritFromIntellect(); + // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE + crit += GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + // Increase crit by school from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL + crit += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, 1<GetSpellProto()->EquippedItemClass == -1) + expertise += (*itr)->GetModifier()->m_amount; + // item dependent spell + else if(weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto())) + expertise += (*itr)->GetModifier()->m_amount; + } + + if(expertise < 0) + expertise = 0; + + switch(attack) + { + case BASE_ATTACK: SetUInt32Value(PLAYER_EXPERTISE, expertise); break; + case OFF_ATTACK: SetUInt32Value(PLAYER_OFFHAND_EXPERTISE, expertise); break; + default: break; + } +} + +void Player::UpdateManaRegen() +{ + float Intellect = GetStat(STAT_INTELLECT); + // Mana regen from spirit and intellect + float power_regen = sqrt(Intellect) * OCTRegenMPPerSpirit(); + // Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT aura on spirit base regen + power_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA); + + // Mana regen from SPELL_AURA_MOD_POWER_REGEN aura + float power_regen_mp5 = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f; + + // Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura + AuraList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT); + for(AuraList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + power_regen_mp5 += GetStat(Stats(mod->m_miscvalue)) * mod->m_amount / 500.0f; + } + + // Bonus from some dummy auras + AuraList const& mDummyAuras = GetAurasByType(SPELL_AURA_PERIODIC_DUMMY); + for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + if((*i)->GetId() == 34074) // Aspect of the Viper + { + power_regen_mp5 += (*i)->GetModifier()->m_amount * Intellect / 500.0f; + // Add regen bonus from level in this dummy + power_regen_mp5 += getLevel() * 35 / 100; + } + + // Set regen rate in cast state apply only on spirit based regen + int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); + if (modManaRegenInterrupt > 100) + modManaRegenInterrupt = 100; + SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f); + + SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN, power_regen_mp5 + power_regen); +} + +void Player::_ApplyAllStatBonuses() +{ + SetCanModifyStats(false); + + _ApplyAllAuraMods(); + _ApplyAllItemMods(); + + SetCanModifyStats(true); + + UpdateAllStats(); +} + +void Player::_RemoveAllStatBonuses() +{ + SetCanModifyStats(false); + + _RemoveAllItemMods(); + _RemoveAllAuraMods(); + + SetCanModifyStats(true); + + UpdateAllStats(); +} + +/*####################################### +######## ######## +######## MOBS STAT SYSTEM ######## +######## ######## +#######################################*/ + +bool Creature::UpdateStats(Stats /*stat*/) +{ + return true; +} + +bool Creature::UpdateAllStats() +{ + UpdateMaxHealth(); + UpdateAttackPowerAndDamage(); + + for(int i = POWER_MANA; i < MAX_POWERS; ++i) + UpdateMaxPower(Powers(i)); + + for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) + UpdateResistances(i); + + return true; +} + +void Creature::UpdateResistances(uint32 school) +{ + if(school > SPELL_SCHOOL_NORMAL) + { + float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); + SetResistance(SpellSchools(school), int32(value)); + } + else + UpdateArmor(); +} + +void Creature::UpdateArmor() +{ + float value = GetTotalAuraModValue(UNIT_MOD_ARMOR); + SetArmor(int32(value)); +} + +void Creature::UpdateMaxHealth() +{ + float value = GetTotalAuraModValue(UNIT_MOD_HEALTH); + SetMaxHealth((uint32)value); +} + +void Creature::UpdateMaxPower(Powers power) +{ + UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); + + float value = GetTotalAuraModValue(unitMod); + SetMaxPower(power, uint32(value)); +} + +void Creature::UpdateAttackPowerAndDamage(bool ranged) +{ + if(ranged) + return; + + //automatically update weapon damage after attack power modification + UpdateDamagePhysical(BASE_ATTACK); +} + +void Creature::UpdateDamagePhysical(WeaponAttackType attType) +{ + if(attType > BASE_ATTACK) + return; + + UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; + + float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; + + float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; + float base_pct = GetModifierValue(unitMod, BASE_PCT); + float total_value = GetModifierValue(unitMod, TOTAL_VALUE); + float total_pct = GetModifierValue(unitMod, TOTAL_PCT); + + float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); + float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); + + float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct ; + float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct ; + + SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); + SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); +} + +/*####################################### +######## ######## +######## PETS STAT SYSTEM ######## +######## ######## +#######################################*/ + +bool Pet::UpdateStats(Stats stat) +{ + if(stat > STAT_SPIRIT) + return false; + + // value = ((base_value * base_pct) + total_value) * total_pct + float value = GetTotalStatValue(stat); + + Unit *owner = GetOwner(); + if ( stat == STAT_STAMINA ) + { + if(owner) + value += float(owner->GetStat(stat)) * 0.3f; + } + //warlock's and mage's pets gain 30% of owner's intellect + else if ( stat == STAT_INTELLECT && getPetType() == SUMMON_PET ) + { + if(owner && (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) ) + value += float(owner->GetStat(stat)) * 0.3f; + } + + SetStat(stat, int32(value)); + + switch(stat) + { + case STAT_STRENGTH: UpdateAttackPowerAndDamage(); break; + case STAT_AGILITY: UpdateArmor(); break; + case STAT_STAMINA: UpdateMaxHealth(); break; + case STAT_INTELLECT: UpdateMaxPower(POWER_MANA); break; + case STAT_SPIRIT: + default: + break; + } + + return true; +} + +bool Pet::UpdateAllStats() +{ + for (int i = STAT_STRENGTH; i < MAX_STATS; i++) + UpdateStats(Stats(i)); + + for(int i = POWER_MANA; i < MAX_POWERS; i++) + UpdateMaxPower(Powers(i)); + + for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++) + UpdateResistances(i); + + return true; +} + +void Pet::UpdateResistances(uint32 school) +{ + if(school > SPELL_SCHOOL_NORMAL) + { + float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); + + Unit *owner = GetOwner(); + // hunter and warlock pets gain 40% of owner's resistance + if(owner && (getPetType() == HUNTER_PET || getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)) + value += float(owner->GetResistance(SpellSchools(school))) * 0.4f; + + SetResistance(SpellSchools(school), int32(value)); + } + else + UpdateArmor(); +} + +void Pet::UpdateArmor() +{ + float value = 0.0f; + float bonus_armor = 0.0f; + UnitMods unitMod = UNIT_MOD_ARMOR; + + Unit *owner = GetOwner(); + // hunter and warlock pets gain 35% of owner's armor value + if(owner && (getPetType() == HUNTER_PET || getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)) + bonus_armor = 0.35f * float(owner->GetArmor()); + + value = GetModifierValue(unitMod, BASE_VALUE); + value *= GetModifierValue(unitMod, BASE_PCT); + value += GetStat(STAT_AGILITY) * 2.0f; + value += GetModifierValue(unitMod, TOTAL_VALUE) + bonus_armor; + value *= GetModifierValue(unitMod, TOTAL_PCT); + + SetArmor(int32(value)); +} + +void Pet::UpdateMaxHealth() +{ + UnitMods unitMod = UNIT_MOD_HEALTH; + float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA); + + float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth(); + value *= GetModifierValue(unitMod, BASE_PCT); + value += GetModifierValue(unitMod, TOTAL_VALUE) + stamina * 10.0f; + value *= GetModifierValue(unitMod, TOTAL_PCT); + + SetMaxHealth((uint32)value); +} + +void Pet::UpdateMaxPower(Powers power) +{ + UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); + float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f; + + float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); + value *= GetModifierValue(unitMod, BASE_PCT); + value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * 15.0f; + value *= GetModifierValue(unitMod, TOTAL_PCT); + + SetMaxPower(power, uint32(value)); +} + +void Pet::UpdateAttackPowerAndDamage(bool ranged) +{ + if(ranged) + return; + + float val = 0.0f; + float bonusAP = 0.0f; + UnitMods unitMod = UNIT_MOD_ATTACK_POWER; + + if(GetEntry() == 416) // imp's attack power + val = GetStat(STAT_STRENGTH) - 10.0f; + else + val = 2 * GetStat(STAT_STRENGTH) - 20.0f; + + Unit* owner = GetOwner(); + if( owner && owner->GetTypeId()==TYPEID_PLAYER) + { + if(getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power + { + bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f; + SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.125f)); + } + //demons benefit from warlocks shadow or fire damage + else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK) + { + int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); + int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW); + int32 maximum = (fire > shadow) ? fire : shadow; + if(maximum < 0) + maximum = 0; + SetBonusDamage( int32(maximum * 0.15f)); + bonusAP = maximum * 0.57f; + } + //water elementals benefit from mage's frost damage + else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_MAGE) + { + int32 frost = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FROST); + if(frost < 0) + frost = 0; + SetBonusDamage( int32(frost * 0.4f)); + } + } + + SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP); + + //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB + float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); + float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); + float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; + + //UNIT_FIELD_(RANGED)_ATTACK_POWER field + SetUInt32Value(UNIT_FIELD_ATTACK_POWER, (uint32)base_attPower); + //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field + SetUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (uint32)attPowerMod); + //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field + SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); + + //automatically update weapon damage after attack power modification + UpdateDamagePhysical(BASE_ATTACK); +} + +void Pet::UpdateDamagePhysical(WeaponAttackType attType) +{ + if(attType > BASE_ATTACK) + return; + + UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; + + float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; + + float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; + float base_pct = GetModifierValue(unitMod, BASE_PCT); + float total_value = GetModifierValue(unitMod, TOTAL_VALUE); + float total_pct = GetModifierValue(unitMod, TOTAL_PCT); + + float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); + float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); + + float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; + float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; + + // Pet's base damage changes depending on happiness + if (getPetType() == HUNTER_PET && attType == BASE_ATTACK) + { + switch(GetHappinessState()) + { + case HAPPY: + // 125% of normal damage + mindamage = mindamage * 1.25; + maxdamage = maxdamage * 1.25; + break; + case CONTENT: + // 100% of normal damage, nothing to modify + break; + case UNHAPPY: + // 75% of normal damage + mindamage = mindamage * 0.75; + maxdamage = maxdamage * 0.75; + break; + } + } + + SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); + SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); +} diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp new file mode 100644 index 000000000..53dc2acdc --- /dev/null +++ b/src/game/TargetedMovementGenerator.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ByteBuffer.h" +#include "TargetedMovementGenerator.h" +#include "Errors.h" +#include "Creature.h" +#include "MapManager.h" +#include "DestinationHolderImp.h" +#include "World.h" + +#define SMALL_ALPHA 0.05f + +#include +/* +struct StackCleaner +{ + Creature &i_creature; + StackCleaner(Creature &creature) : i_creature(creature) {} + void Done(void) { i_creature.StopMoving(); } + ~StackCleaner() + { + i_creature->Clear(); + } +}; +*/ + +template +void +TargetedMovementGenerator::_setTargetLocation(T &owner) +{ + if( !i_target.isValid() || !&owner ) + return; + + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) ) + return; + + // prevent redundant micro-movement for pets, other followers. + if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset)) + return; + + float x, y, z; + if(!i_offset) + { + // to nearest contact position + i_target->GetContactPoint( &owner, x, y, z ); + } + else + { + // to at i_offset distance from target and i_angle from target facing + i_target->GetClosePoint(x,y,z,owner.GetObjectSize(),i_offset,i_angle); + } + + /* + We MUST not check the distance difference and avoid setting the new location for smaller distances. + By that we risk having far too many GetContactPoint() calls freezing the whole system. + In TargetedMovementGenerator::Update() we check the distance to the target and at + some range we calculate a new position. The calculation takes some processor cycles due to vmaps. + If the distance to the target it too large to ignore, + but the distance to the new contact point is short enough to be ignored, + we will calculate a new contact point each update loop, but will never move to it. + The system will freeze. + ralf + + //We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize + float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE; + if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize ) + return; + */ + Traveller traveller(owner); + i_destinationHolder.SetDestination(traveller, x, y, z); + owner.addUnitState(UNIT_STAT_CHASE); + if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) + owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); +} + +template +void +TargetedMovementGenerator::Initialize(T &owner) +{ + if(!&owner) + return; + owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + + if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) + owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + + _setTargetLocation(owner); +} + +template +void +TargetedMovementGenerator::Finalize(T &owner) +{ + owner.clearUnitState(UNIT_STAT_CHASE); +} + +template +void +TargetedMovementGenerator::Reset(T &owner) +{ + Initialize(owner); +} + +template +bool +TargetedMovementGenerator::Update(T &owner, const uint32 & time_diff) +{ + if(!i_target.isValid()) + return false; + + if( !&owner || !owner.isAlive()) + return true; + + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) ) + return true; + + // prevent movement while casting spells with cast time or channel time + if ( owner.IsNonMeleeSpellCasted(false, false, true)) + { + if (!owner.IsStopped()) + owner.StopMoving(); + return true; + } + + // prevent crash after creature killed pet + if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget()) + return true; + + Traveller traveller(owner); + + if( !i_destinationHolder.HasDestination() ) + _setTargetLocation(owner); + if( owner.IsStopped() && !i_destinationHolder.HasArrived() ) + { + owner.addUnitState(UNIT_STAT_CHASE); + if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) + owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + + i_destinationHolder.StartTravel(traveller); + return true; + } + + if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false)) + { + // put targeted movement generators on a higher priority + if (owner.GetObjectSize()) + i_destinationHolder.ResetUpdate(50); + + float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE); + + //More distance let have better performance, less distance let have more sensitive reaction at target move. + + // try to counter precision differences + if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist) + { + owner.SetInFront(i_target.getTarget()); // Set new Angle For Map:: + _setTargetLocation(owner); //Calculate New Dest and Send data To Player + } + // Update the Angle of the target only for Map::, no need to send packet for player + else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) ) + owner.SetInFront(i_target.getTarget()); + + if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel ) + { + i_recalculateTravel = false; + //Angle update will take place into owner.StopMoving() + owner.SetInFront(i_target.getTarget()); + + owner.StopMoving(); + if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW)) + owner.Attack(i_target.getTarget(),true); + } + } + return true; +} + +template +Unit* +TargetedMovementGenerator::GetTarget() const +{ + return i_target.getTarget(); +} + +template void TargetedMovementGenerator::_setTargetLocation(Player &); +template void TargetedMovementGenerator::_setTargetLocation(Creature &); +template void TargetedMovementGenerator::Initialize(Player &); +template void TargetedMovementGenerator::Initialize(Creature &); +template void TargetedMovementGenerator::Finalize(Player &); +template void TargetedMovementGenerator::Finalize(Creature &); +template void TargetedMovementGenerator::Reset(Player &); +template void TargetedMovementGenerator::Reset(Creature &); +template bool TargetedMovementGenerator::Update(Player &, const uint32 &); +template bool TargetedMovementGenerator::Update(Creature &, const uint32 &); +template Unit* TargetedMovementGenerator::GetTarget() const; +template Unit* TargetedMovementGenerator::GetTarget() const; diff --git a/src/game/TargetedMovementGenerator.h b/src/game/TargetedMovementGenerator.h new file mode 100644 index 000000000..87fda16e9 --- /dev/null +++ b/src/game/TargetedMovementGenerator.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_TARGETEDMOVEMENTGENERATOR_H +#define MANGOS_TARGETEDMOVEMENTGENERATOR_H + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "Traveller.h" +#include "FollowerReference.h" + +class MANGOS_DLL_SPEC TargetedMovementGeneratorBase +{ + public: + TargetedMovementGeneratorBase(Unit &target) { i_target.link(&target, this); } + void stopFollowing() { } + protected: + FollowerReference i_target; +}; + +template +class MANGOS_DLL_SPEC TargetedMovementGenerator +: public MovementGeneratorMedium< T, TargetedMovementGenerator >, public TargetedMovementGeneratorBase +{ + public: + + TargetedMovementGenerator(Unit &target) + : TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0), i_recalculateTravel(false) {} + TargetedMovementGenerator(Unit &target, float offset, float angle) + : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle), i_recalculateTravel(false) {} + ~TargetedMovementGenerator() {} + + void Initialize(T &); + void Finalize(T &); + void Reset(T &); + bool Update(T &, const uint32 &); + MovementGeneratorType GetMovementGeneratorType() { return TARGETED_MOTION_TYPE; } + + Unit* GetTarget() const; + + bool GetDestination(float &x, float &y, float &z) const + { + if(!i_destinationHolder.HasDestination()) return false; + i_destinationHolder.GetDestination(x,y,z); + return true; + } + + void unitSpeedChanged() { i_recalculateTravel=true; } + private: + + void _setTargetLocation(T &); + + float i_offset; + float i_angle; + DestinationHolder< Traveller > i_destinationHolder; + bool i_recalculateTravel; +}; +#endif diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp new file mode 100644 index 000000000..76736227c --- /dev/null +++ b/src/game/TaxiHandler.cpp @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" +#include "Log.h" +#include "World.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "UpdateMask.h" +#include "Path.h" +#include "WaypointMovementGenerator.h" +#include "DestinationHolderImp.h" + +#include + +void WorldSession::HandleTaxiNodeStatusQueryOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug( "WORLD: Received CMSG_TAXINODE_STATUS_QUERY" ); + + uint64 guid; + + recv_data >> guid; + SendTaxiStatus( guid ); +} + +void WorldSession::SendTaxiStatus( uint64 guid ) +{ + // cheating checks + Creature *unit = ObjectAccessor::GetCreature(*_player, guid); + if (!unit) + { + sLog.outDebug( "WorldSession::SendTaxiStatus - Unit (GUID: %u) not found.", uint32(GUID_LOPART(guid)) ); + return; + } + + uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId()); + + // not found nearest + if(curloc == 0) + return; + + sLog.outDebug( "WORLD: current location %u ",curloc); + + WorldPacket data( SMSG_TAXINODE_STATUS, 9 ); + data << guid; + data << uint8( GetPlayer( )->m_taxi.IsTaximaskNodeKnown(curloc) ? 1 : 0 ); + SendPacket( &data ); + sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" ); +} + +void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8); + + sLog.outDebug( "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES" ); + + uint64 guid; + recv_data >> guid; + + // cheating checks + Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER); + if (!unit) + { + sLog.outDebug( "WORLD: HandleTaxiQueryAvailableNodesOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); + return; + } + + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + // unknown taxi node case + if( SendLearnNewTaxiNode(unit) ) + return; + + // known taxi node case + SendTaxiMenu( unit ); +} + +void WorldSession::SendTaxiMenu( Creature* unit ) +{ + // find current node + uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId()); + + if ( curloc == 0 ) + return; + + sLog.outDebug( "WORLD: CMSG_TAXINODE_STATUS_QUERY %u ",curloc); + + WorldPacket data( SMSG_SHOWTAXINODES, (4+8+4+8*4) ); + data << uint32( 1 ); + data << uint64( unit->GetGUID() ); + data << uint32( curloc ); + GetPlayer()->m_taxi.AppendTaximaskTo(data,GetPlayer()->isTaxiCheater()); + SendPacket( &data ); + + sLog.outDebug( "WORLD: Sent SMSG_SHOWTAXINODES" ); +} + +void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode ) +{ + // remove fake death + if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) + GetPlayer()->GetMotionMaster()->MovementExpired(false); + + GetPlayer()->Mount( MountId ); + GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path,pathNode); +} + +bool WorldSession::SendLearnNewTaxiNode( Creature* unit ) +{ + // find current node + uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId()); + + if ( curloc == 0 ) + return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result. + + if( GetPlayer()->m_taxi.SetTaximaskNode(curloc) ) + { + WorldPacket msg(SMSG_NEW_TAXI_PATH, 0); + SendPacket( &msg ); + + WorldPacket update( SMSG_TAXINODE_STATUS, 9 ); + update << uint64( unit->GetGUID() ); + update << uint8( 1 ); + SendPacket( &update ); + + return true; + } + else + return false; +} + +void WorldSession::HandleActivateTaxiFarOpcode ( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS" ); + + uint64 guid; + uint32 node_count, _totalcost; + + recv_data >> guid >> _totalcost >> node_count; + + Creature *npc = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER); + if (!npc) + { + sLog.outDebug( "WORLD: HandleActivateTaxiFarOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)) ); + return; + } + // recheck + CHECK_PACKET_SIZE(recv_data,8+4+4+node_count*4); + + std::vector nodes; + + for(uint32 i = 0; i < node_count; ++i) + { + uint32 node; + recv_data >> node; + nodes.push_back(node); + } + + if(nodes.empty()) + return; + + sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from %d to %d" ,nodes.front(),nodes.back()); + + GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc); +} + +void WorldSession::HandleTaxiNextDestinationOpcode(WorldPacket& /*recv_data*/) +{ + sLog.outDebug( "WORLD: Received CMSG_MOVE_SPLINE_DONE" ); + + // in taxi flight packet received in 2 case: + // 1) end taxi path in far (multi-node) flight + // 2) switch from one map to other in case multim-map taxi path + // we need proccess only (1) + uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination(); + if(!curDest) + return; + + TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest); + + // far teleport case + if(curDestNode && curDestNode->map_id != GetPlayer()->GetMapId()) + { + if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) + { + // short preparations to continue flight + FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); + + flight->SetCurrentNodeAfterTeleport(); + Path::PathNode const& node = flight->GetPath()[flight->GetCurrentNode()]; + flight->SkipCurrentNode(); + + GetPlayer()->TeleportTo(curDestNode->map_id,node.x,node.y,node.z,GetPlayer()->GetOrientation()); + } + return; + } + + uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination(); + if ( destinationnode > 0 ) // if more destinations to go + { + // current source node for next destination + uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource(); + + // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path) + if (GetPlayer()->isTaxiCheater()) + { + if(GetPlayer()->m_taxi.SetTaximaskNode(sourcenode)) + { + WorldPacket data(SMSG_NEW_TAXI_PATH, 0); + _player->GetSession()->SendPacket( &data ); + } + } + + sLog.outDebug( "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode ); + + uint16 MountId = objmgr.GetTaxiMount(sourcenode, GetPlayer()->GetTeam()); + + uint32 path, cost; + objmgr.GetTaxiPath( sourcenode, destinationnode, path, cost); + + if(path && MountId) + SendDoFlight( MountId, path, 1 ); // skip start fly node + else + GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next + } + else + GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node +} + +void WorldSession::HandleActivateTaxiOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data,8+4+4); + + sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI" ); + + uint64 guid; + std::vector nodes; + nodes.resize(2); + + recv_data >> guid >> nodes[0] >> nodes[1]; + sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI from %d to %d" ,nodes[0],nodes[1]); + Creature *npc = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER); + if (!npc) + { + sLog.outDebug( "WORLD: HandleActivateTaxiOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)) ); + return; + } + + GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc); +} diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp new file mode 100644 index 000000000..928cd3fe1 --- /dev/null +++ b/src/game/TemporarySummon.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "TemporarySummon.h" +#include "WorldPacket.h" +#include "MapManager.h" +#include "Log.h" +#include "ObjectAccessor.h" +#include "CreatureAI.h" + +TemporarySummon::TemporarySummon( uint64 summoner ) : +Creature(), m_type(TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN), m_timer(0), m_lifetime(0), m_summoner(summoner) +{ +} + +void TemporarySummon::Update( uint32 diff ) +{ + switch(m_type) + { + case TEMPSUMMON_MANUAL_DESPAWN: + break; + case TEMPSUMMON_TIMED_DESPAWN: + { + if (m_timer <= diff) + { + UnSummon(); + return; + } + + m_timer -= diff; + break; + } + case TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT: + { + if (!isInCombat()) + { + if (m_timer <= diff) + { + UnSummon(); + return; + } + + m_timer -= diff; + } + else if (m_timer != m_lifetime) + m_timer = m_lifetime; + + break; + } + + case TEMPSUMMON_CORPSE_TIMED_DESPAWN: + { + if ( m_deathState == CORPSE) + { + if (m_timer <= diff) + { + UnSummon(); + return; + } + + m_timer -= diff; + } + break; + } + case TEMPSUMMON_CORPSE_DESPAWN: + { + // if m_deathState is DEAD, CORPSE was skipped + if ( m_deathState == CORPSE || m_deathState == DEAD) + { + UnSummon(); + return; + } + + break; + } + case TEMPSUMMON_DEAD_DESPAWN: + { + if ( m_deathState == DEAD ) + { + UnSummon(); + return; + } + break; + } + case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN: + { + // if m_deathState is DEAD, CORPSE was skipped + if ( m_deathState == CORPSE || m_deathState == DEAD) + { + UnSummon(); + return; + } + + if (!isInCombat()) + { + if (m_timer <= diff) + { + UnSummon(); + return; + } + else + m_timer -= diff; + } + else if (m_timer != m_lifetime) + m_timer = m_lifetime; + break; + } + case TEMPSUMMON_TIMED_OR_DEAD_DESPAWN: + { + // if m_deathState is DEAD, CORPSE was skipped + if (m_deathState == DEAD) + { + UnSummon(); + return; + } + + if (!isInCombat() && isAlive() ) + { + if (m_timer <= diff) + { + UnSummon(); + return; + } + else + m_timer -= diff; + } + else if (m_timer != m_lifetime) + m_timer = m_lifetime; + break; + } + default: + UnSummon(); + sLog.outError("Temporary summoned creature (entry: %u) have unknown type %u of ",GetEntry(),m_type); + break; + } + + Creature::Update( diff ); +} + +void TemporarySummon::Summon(TempSummonType type, uint32 lifetime) +{ + m_type = type; + m_timer = lifetime; + m_lifetime = lifetime; + + MapManager::Instance().GetMap(GetMapId(), this)->Add((Creature*)this); + + AIM_Initialize(); +} + +void TemporarySummon::UnSummon() +{ + CombatStop(); + + CleanupsBeforeDelete(); + AddObjectToRemoveList(); + + Unit* sum = m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL; + if (sum && sum->GetTypeId() == TYPEID_UNIT && ((Creature*)sum)->AI()) + { + ((Creature*)sum)->AI()->SummonedCreatureDespawn(this); + } +} + +void TemporarySummon::SaveToDB() +{ +} diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h new file mode 100644 index 000000000..c49e1ad17 --- /dev/null +++ b/src/game/TemporarySummon.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_TEMPSUMMON_H +#define MANGOSSERVER_TEMPSUMMON_H + +#include "Creature.h" +#include "ObjectAccessor.h" + +class TemporarySummon : public Creature +{ + public: + explicit TemporarySummon(uint64 summoner = 0); + virtual ~TemporarySummon(){}; + void Update(uint32 time); + void Summon(TempSummonType type, uint32 lifetime); + void UnSummon(); + void SaveToDB(); + Unit* GetSummoner() const { return m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL; } + private: + TempSummonType m_type; + uint32 m_timer; + uint32 m_lifetime; + uint64 m_summoner; +}; +#endif diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp new file mode 100644 index 000000000..c6b8da1da --- /dev/null +++ b/src/game/ThreatManager.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ThreatManager.h" +#include "Unit.h" +#include "Creature.h" +#include "CreatureAI.h" +#include "Map.h" +#include "MapManager.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "UnitEvents.h" + +//============================================================== +//================= ThreatCalcHelper =========================== +//============================================================== + +// The pHatingUnit is not used yet +float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell) +{ + if(pThreatSpell) + { + if( Player* modOwner = pHatingUnit->GetSpellModOwner() ) + modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, pThreat); + } + + float threat = pHatedUnit->ApplyTotalThreatModifier(pThreat, schoolMask); + return threat; +} + +//============================================================ +//================= HostilReference ========================== +//============================================================ + +HostilReference::HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat) +{ + iThreat = pThreat; + iTempThreatModifyer = 0.0f; + link(pUnit, pThreatManager); + iUnitGuid = pUnit->GetGUID(); + iOnline = true; + iAccessible = true; +} + +//============================================================ +// Tell our refTo (target) object that we have a link +void HostilReference::targetObjectBuildLink() +{ + getTarget()->addHatedBy(this); +} + +//============================================================ +// Tell our refTo (taget) object, that the link is cut +void HostilReference::targetObjectDestroyLink() +{ + getTarget()->removeHatedBy(this); +} + +//============================================================ +// Tell our refFrom (source) object, that the link is cut (Target destroyed) + +void HostilReference::sourceObjectDestroyLink() +{ + setOnlineOfflineState(false); +} + +//============================================================ +// Inform the source, that the status of the reference changed + +void HostilReference::fireStatusChanged(const ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent) +{ + if(getSource()) + getSource()->processThreatEvent(&pThreatRefStatusChangeEvent); +} + +//============================================================ + +void HostilReference::addThreat(float pMod) +{ + iThreat += pMod; + // the threat is changed. Source and target unit have to be availabe + // if the link was cut before relink it again + if(!isOnline()) + updateOnlineStatus(); + if(pMod != 0.0f) + fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_THREAT_CHANGE, this, pMod)); + if(isValid() && pMod >= 0) + { + Unit* victim_owner = getTarget()->GetOwner(); + if(victim_owner && victim_owner->isAlive()) + getSource()->addThreat(victim_owner, 0.0f); // create a threat to the owner of a pet, if the pet attacks + } +} + +//============================================================ +// check, if source can reach target and set the status + +void HostilReference::updateOnlineStatus() +{ + bool online = false; + bool accessible = false; + + if(!isValid()) + { + Unit* target = ObjectAccessor::GetUnit(*getSourceUnit(), getUnitGuid()); + if(target) + link(target, getSource()); + } + // only check for online status if + // ref is valid + // target is no player or not gamemaster + // target is not in flight + if(isValid() && + ((getTarget()->GetTypeId() != TYPEID_PLAYER || !((Player*)getTarget())->isGameMaster()) || + !getTarget()->hasUnitState(UNIT_STAT_IN_FLIGHT))) + { + Creature* creature = (Creature* ) getSourceUnit(); + online = getTarget()->isInAccessablePlaceFor(creature); + if(!online) + { + if(creature->AI()->canReachByRangeAttack(getTarget())) + online = true; // not accessable but stays online + } + else + accessible = true; + + } + setAccessibleState(accessible); + setOnlineOfflineState(online); +} + +//============================================================ +// set the status and fire the event on status change + +void HostilReference::setOnlineOfflineState(bool pIsOnline) +{ + if(iOnline != pIsOnline) + { + iOnline = pIsOnline; + if(!iOnline) + setAccessibleState(false); // if not online that not accessable as well + fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_ONLINE_STATUS, this)); + } +} + +//============================================================ + +void HostilReference::setAccessibleState(bool pIsAccessible) +{ + if(iAccessible != pIsAccessible) + { + iAccessible = pIsAccessible; + fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_ASSECCIBLE_STATUS, this)); + } +} + +//============================================================ +// prepare the reference for deleting +// this is called be the target + +void HostilReference::removeReference() +{ + invalidate(); + fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_REMOVE_FROM_LIST, this)); +} + +//============================================================ + +Unit* HostilReference::getSourceUnit() +{ + return (getSource()->getOwner()); +} + +//============================================================ +//================ ThreatContainer =========================== +//============================================================ + +void ThreatContainer::clearReferences() +{ + for(std::list::iterator i = iThreatList.begin(); i != iThreatList.end(); i++) + { + (*i)->unlink(); + delete (*i); + } + iThreatList.clear(); +} + +//============================================================ +// Return the HostilReference of NULL, if not found +HostilReference* ThreatContainer::getReferenceByTarget(Unit* pVictim) +{ + HostilReference* result = NULL; + uint64 guid = pVictim->GetGUID(); + for(std::list::iterator i = iThreatList.begin(); i != iThreatList.end(); i++) + { + if((*i)->getUnitGuid() == guid) + { + result = (*i); + break; + } + } + + return result; +} + +//============================================================ +// Add the threat, if we find the reference + +HostilReference* ThreatContainer::addThreat(Unit* pVictim, float pThreat) +{ + HostilReference* ref = getReferenceByTarget(pVictim); + if(ref) + ref->addThreat(pThreat); + return ref; +} + +//============================================================ + +void ThreatContainer::modifyThreatPercent(Unit *pVictim, int32 pPercent) +{ + if(HostilReference* ref = getReferenceByTarget(pVictim)) + ref->addThreatPercent(pPercent); +} + +//============================================================ + +bool HostilReferenceSortPredicate(const HostilReference* lhs, const HostilReference* rhs) +{ + // std::list::sort ordering predicate must be: (Pred(x,y)&&Pred(y,x))==false + return lhs->getThreat() > rhs->getThreat(); // reverse sorting +} + +//============================================================ +// Check if the list is dirty and sort if necessary + +void ThreatContainer::update() +{ + if(iDirty && iThreatList.size() >1) + { + iThreatList.sort(HostilReferenceSortPredicate); + } + iDirty = false; +} + +//============================================================ +// return the next best victim +// could be the current victim + +HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilReference* pCurrentVictim) +{ + HostilReference* currentRef = NULL; + bool found = false; + for(std::list::iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found; ++iter) + { + currentRef = (*iter); + + Unit* target = currentRef->getTarget(); + assert(target); // if the ref has status online the target must be there ! + + if(!pAttacker->IsOutOfThreatArea(target)) // skip non attackable currently targets + { + if(pCurrentVictim) // select 1.3/1.1 better target in comparison current target + { + // list sorted and and we check current target, then this is best case + if(pCurrentVictim == currentRef || currentRef->getThreat() <= 1.1f * pCurrentVictim->getThreat() ) + { + currentRef = pCurrentVictim; // for second case + found = true; + break; + } + + if( currentRef->getThreat() > 1.3f * pCurrentVictim->getThreat() || + currentRef->getThreat() > 1.1f * pCurrentVictim->getThreat() && pAttacker->IsWithinDistInMap(target, ATTACK_DISTANCE) ) + { //implement 110% threat rule for targets in melee range + found = true; //and 130% rule for targets in ranged distances + break; //for selecting alive targets + } + } + else // select any + { + found = true; + break; + } + } + } + if(!found) + currentRef = NULL; + + return currentRef; +} + +//============================================================ +//=================== ThreatManager ========================== +//============================================================ + +ThreatManager::ThreatManager(Unit* owner) : iCurrentVictim(NULL), iOwner(owner) +{ +} + +//============================================================ + +void ThreatManager::clearReferences() +{ + iThreatContainer.clearReferences(); + iThreatOfflineContainer.clearReferences(); + iCurrentVictim = NULL; +} + +//============================================================ + +void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell) +{ + //function deals with adding threat and adding players and pets into ThreatList + //mobs, NPCs, guards have ThreatList and HateOfflineList + //players and pets have only InHateListOf + //HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.) + + if (pVictim == getOwner()) // only for same creatures :) + return; + + if(!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) ) + return; + + assert(getOwner()->GetTypeId()== TYPEID_UNIT); + + float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell); + + HostilReference* ref = iThreatContainer.addThreat(pVictim, threat); + // Ref is not in the online refs, search the offline refs next + if(!ref) + ref = iThreatOfflineContainer.addThreat(pVictim, threat); + + if(!ref) // there was no ref => create a new one + { + // threat has to be 0 here + HostilReference* hostilReference = new HostilReference(pVictim, this, 0); + iThreatContainer.addReference(hostilReference); + hostilReference->addThreat(threat); // now we add the real threat + if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) + hostilReference->setOnlineOfflineState(false); // GM is always offline + } +} + +//============================================================ + +void ThreatManager::modifyThreatPercent(Unit *pVictim, int32 pPercent) +{ + iThreatContainer.modifyThreatPercent(pVictim, pPercent); +} + +//============================================================ + +Unit* ThreatManager::getHostilTarget() +{ + iThreatContainer.update(); + HostilReference* nextVictim = iThreatContainer.selectNextVictim((Creature*) getOwner(), getCurrentVictim()); + setCurrentVictim(nextVictim); + return getCurrentVictim() != NULL ? getCurrentVictim()->getTarget() : NULL; +} + +//============================================================ + +float ThreatManager::getThreat(Unit *pVictim, bool pAlsoSearchOfflineList) +{ + float threat = 0.0f; + HostilReference* ref = iThreatContainer.getReferenceByTarget(pVictim); + if(!ref && pAlsoSearchOfflineList) + ref = iThreatOfflineContainer.getReferenceByTarget(pVictim); + if(ref) + threat = ref->getThreat(); + return threat; +} + +//============================================================ + +void ThreatManager::tauntApply(Unit* pTaunter) +{ + HostilReference* ref = iThreatContainer.getReferenceByTarget(pTaunter); + if(getCurrentVictim() && ref && (ref->getThreat() < getCurrentVictim()->getThreat())) + { + if(ref->getTempThreatModifyer() == 0.0f) + // Ok, temp threat is unused + ref->setTempThreat(getCurrentVictim()->getThreat()); + } +} + +//============================================================ + +void ThreatManager::tauntFadeOut(Unit *pTaunter) +{ + HostilReference* ref = iThreatContainer.getReferenceByTarget(pTaunter); + if(ref) + ref->resetTempThreat(); +} + +//============================================================ + +void ThreatManager::setCurrentVictim(HostilReference* pHostilReference) +{ + iCurrentVictim = pHostilReference; +} + +//============================================================ +// The hated unit is gone, dead or deleted +// return true, if the event is consumed + +bool ThreatManager::processThreatEvent(const UnitBaseEvent* pUnitBaseEvent) +{ + bool consumed = false; + + ThreatRefStatusChangeEvent* threatRefStatusChangeEvent; + HostilReference* hostilReference; + + threatRefStatusChangeEvent = (ThreatRefStatusChangeEvent*) pUnitBaseEvent; + threatRefStatusChangeEvent->setThreatManager(this); // now we can set the threat manager + hostilReference = threatRefStatusChangeEvent->getReference(); + + switch(pUnitBaseEvent->getType()) + { + case UEV_THREAT_REF_THREAT_CHANGE: + if((getCurrentVictim() == hostilReference && threatRefStatusChangeEvent->getFValue()<0.0f) || + (getCurrentVictim() != hostilReference && threatRefStatusChangeEvent->getFValue()>0.0f)) + setDirty(true); // the order in the threat list might have changed + break; + case UEV_THREAT_REF_ONLINE_STATUS: + if(!hostilReference->isOnline()) + { + if (hostilReference == getCurrentVictim()) + { + setCurrentVictim(NULL); + setDirty(true); + } + iThreatContainer.remove(hostilReference); + iThreatOfflineContainer.addReference(hostilReference); + } + else + { + if(getCurrentVictim() && hostilReference->getThreat() > (1.1f * getCurrentVictim()->getThreat())) + setDirty(true); + iThreatContainer.addReference(hostilReference); + iThreatOfflineContainer.remove(hostilReference); + } + break; + case UEV_THREAT_REF_REMOVE_FROM_LIST: + if (hostilReference == getCurrentVictim()) + { + setCurrentVictim(NULL); + setDirty(true); + } + if(hostilReference->isOnline()) + iThreatContainer.remove(hostilReference); + else + iThreatOfflineContainer.remove(hostilReference); + break; + } + return consumed; +} diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h new file mode 100644 index 000000000..e5e3fdcfa --- /dev/null +++ b/src/game/ThreatManager.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _THREATMANAGER +#define _THREATMANAGER + +#include "Common.h" +#include "SharedDefines.h" +#include "Utilities/LinkedReference/Reference.h" +#include "UnitEvents.h" + +#include + +//============================================================== + +class Unit; +class Creature; +class ThreatManager; +struct SpellEntry; + +//============================================================== +// Class to calculate the real threat based + +class ThreatCalcHelper +{ + public: + static float calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); +}; + +//============================================================== + +class MANGOS_DLL_SPEC HostilReference : public Reference +{ + private: + float iThreat; + float iTempThreatModifyer; // used for taunt + uint64 iUnitGuid; + bool iOnline; + bool iAccessible; + private: + // Inform the source, that the status of that reference was changed + void fireStatusChanged(const ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent); + + Unit* getSourceUnit(); + public: + HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat); + + //================================================= + void addThreat(float pMod); + + void setThreat(float pThreat) { addThreat(pThreat - getThreat()); } + + void addThreatPercent(int32 pPercent) { float tmpThreat = iThreat; tmpThreat = tmpThreat * (pPercent+100) / 100; addThreat(tmpThreat-iThreat); } + + float getThreat() const { return iThreat; } + + bool isOnline() const { return iOnline; } + + // The Unit might be in water and the creature can not enter the water, but has range attack + // in this case online = true, but accessable = false + bool isAccessable() const { return iAccessible; } + + // used for temporary setting a threat and reducting it later again. + // the threat modification is stored + void setTempThreat(float pThreat) { iTempThreatModifyer = pThreat - getThreat(); if(iTempThreatModifyer != 0.0f) addThreat(iTempThreatModifyer); } + + void resetTempThreat() + { + if(iTempThreatModifyer != 0.0f) + { + addThreat(-iTempThreatModifyer); iTempThreatModifyer = 0.0f; + } + } + + float getTempThreatModifyer() { return iTempThreatModifyer; } + + //================================================= + // check, if source can reach target and set the status + void updateOnlineStatus(); + + void setOnlineOfflineState(bool pIsOnline); + + void setAccessibleState(bool pIsAccessible); + //================================================= + + bool operator ==(const HostilReference& pHostilReference) const { return pHostilReference.getUnitGuid() == getUnitGuid(); } + + //================================================= + + uint64 getUnitGuid() const { return iUnitGuid; } + + //================================================= + // reference is not needed anymore. realy delete it ! + + void removeReference(); + + //================================================= + + HostilReference* next() { return ((HostilReference* ) Reference::next()); } + + //================================================= + + // Tell our refTo (target) object that we have a link + void targetObjectBuildLink(); + + // Tell our refTo (taget) object, that the link is cut + void targetObjectDestroyLink(); + + // Tell our refFrom (source) object, that the link is cut (Target destroyed) + void sourceObjectDestroyLink(); +}; + +//============================================================== +class ThreatManager; + +class MANGOS_DLL_SPEC ThreatContainer +{ + private: + std::list iThreatList; + bool iDirty; + protected: + friend class ThreatManager; + + void remove(HostilReference* pRef) { iThreatList.remove(pRef); } + void addReference(HostilReference* pHostilReference) { iThreatList.push_back(pHostilReference); } + void clearReferences(); + // Sort the list if necessary + void update(); + public: + ThreatContainer() { iDirty = false; } + ~ThreatContainer() { clearReferences(); } + + HostilReference* addThreat(Unit* pVictim, float pThreat); + + void modifyThreatPercent(Unit *pVictim, int32 percent); + + HostilReference* selectNextVictim(Creature* pAttacker, HostilReference* pCurrentVictim); + + void setDirty(bool pDirty) { iDirty = pDirty; } + + bool isDirty() { return iDirty; } + + bool empty() { return(iThreatList.empty()); } + + HostilReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); } + + HostilReference* getReferenceByTarget(Unit* pVictim); + + std::list& getThreatList() { return iThreatList; } +}; + +//================================================= + +class MANGOS_DLL_SPEC ThreatManager +{ + private: + HostilReference* iCurrentVictim; + Unit* iOwner; + ThreatContainer iThreatContainer; + ThreatContainer iThreatOfflineContainer; + public: + explicit ThreatManager(Unit *pOwner); + + ~ThreatManager() { clearReferences(); } + + void clearReferences(); + + void addThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); + void modifyThreatPercent(Unit *pVictim, int32 pPercent); + + float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false); + + bool isThreatListEmpty() { return iThreatContainer.empty();} + + bool processThreatEvent(const UnitBaseEvent* pUnitBaseEvent); + + HostilReference* getCurrentVictim() { return iCurrentVictim; } + + Unit* getOwner() { return iOwner; } + + Unit* getHostilTarget(); + + void tauntApply(Unit* pTaunter); + void tauntFadeOut(Unit *pTaunter); + + void setCurrentVictim(HostilReference* pHostilReference); + + void setDirty(bool pDirty) { iThreatContainer.setDirty(pDirty); } + + // methods to access the lists from the outside to do sume dirty manipulation (scriping and such) + // I hope they are used as little as possible. + inline std::list& getThreatList() { return iThreatContainer.getThreatList(); } + inline std::list& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); } + inline ThreatContainer& getOnlineContainer() { return iThreatContainer; } + inline ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; } +}; + +//================================================= +#endif diff --git a/src/game/Tools.h b/src/game/Tools.h new file mode 100644 index 000000000..e8ad44a22 --- /dev/null +++ b/src/game/Tools.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef MANGOS_TOOLS_H +#define MANGOS_TOOLS_H + +#include "Common.h" +#include "WorldPacket.h" + +bool readGUID(WorldPacket & data, uint64& guid); +void writeGUID(WorldPacket & data, uint64 & guid); +#endif diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp new file mode 100644 index 000000000..0e874ca15 --- /dev/null +++ b/src/game/Totem.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Totem.h" +#include "WorldPacket.h" +#include "MapManager.h" +#include "Log.h" +#include "Group.h" +#include "Player.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" + +Totem::Totem() : Creature() +{ + m_isTotem = true; + m_duration = 0; + m_type = TOTEM_PASSIVE; +} + +void Totem::Update( uint32 time ) +{ + Unit *owner = GetOwner(); + if (!owner || !owner->isAlive() || !this->isAlive()) + { + UnSummon(); // remove self + return; + } + + if (m_duration <= time) + { + UnSummon(); // remove self + return; + } + else + m_duration -= time; + + Creature::Update( time ); +} + +void Totem::Summon(Unit* owner) +{ + sLog.outDebug("AddObject at Totem.cpp line 49"); + + SetInstanceId(owner->GetInstanceId()); + owner->GetMap()->Add((Creature*)this); + + // select totem model in dependent from owner team + CreatureInfo const *cinfo = GetCreatureInfo(); + if(owner->GetTypeId()==TYPEID_PLAYER && cinfo) + { + if(((Player*)owner)->GetTeam()==HORDE) + SetDisplayId(cinfo->DisplayID_H); + else + SetDisplayId(cinfo->DisplayID_A); + } + + WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); + data << GetGUID(); + SendMessageToSet(&data,true); + + AIM_Initialize(); + + switch(m_type) + { + case TOTEM_PASSIVE: CastSpell(this, GetSpell(), true); break; + case TOTEM_STATUE: CastSpell(GetOwner(), GetSpell(), true); break; + default: break; + } +} + +void Totem::UnSummon() +{ + SendObjectDeSpawnAnim(GetGUID()); + + CombatStop(); + RemoveAurasDueToSpell(GetSpell()); + Unit *owner = this->GetOwner(); + if (owner) + { + // clear owenr's totem slot + for(int i = 0; i < MAX_TOTEM; ++i) + { + if(owner->m_TotemSlot[i]==GetGUID()) + { + owner->m_TotemSlot[i] = 0; + break; + } + } + + owner->RemoveAurasDueToSpell(GetSpell()); + + //remove aura all party members too + Group *pGroup = NULL; + if (owner->GetTypeId() == TYPEID_PLAYER) + { + // Not only the player can summon the totem (scripted AI) + pGroup = ((Player*)owner)->GetGroup(); + if (pGroup) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* Target = itr->getSource(); + if(Target && pGroup->SameSubGroup((Player*)owner, Target)) + Target->RemoveAurasDueToSpell(GetSpell()); + } + } + } + } + + CleanupsBeforeDelete(); + AddObjectToRemoveList(); +} + +void Totem::SetOwner(uint64 guid) +{ + SetUInt64Value(UNIT_FIELD_SUMMONEDBY, guid); + SetUInt64Value(UNIT_FIELD_CREATEDBY, guid); + Unit *owner = this->GetOwner(); + if (owner) + { + this->setFaction(owner->getFaction()); + this->SetLevel(owner->getLevel()); + } +} + +Unit *Totem::GetOwner() +{ + uint64 ownerid = GetOwnerGUID(); + if(!ownerid) + return NULL; + return ObjectAccessor::GetUnit(*this, ownerid); +} + +void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto) +{ + // Get spell casted by totem + SpellEntry const * totemSpell = sSpellStore.LookupEntry(GetSpell()); + if (totemSpell) + { + // If spell have cast time -> so its active totem + if (GetSpellCastTime(totemSpell)) + m_type = TOTEM_ACTIVE; + } + if(spellProto->SpellIconID==2056) + m_type = TOTEM_STATUE; //Jewelery statue +} diff --git a/src/game/Totem.h b/src/game/Totem.h new file mode 100644 index 000000000..1bfa7a027 --- /dev/null +++ b/src/game/Totem.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_TOTEM_H +#define MANGOSSERVER_TOTEM_H + +#include "Creature.h" + +enum TotemType +{ + TOTEM_PASSIVE = 0, + TOTEM_ACTIVE = 1, + TOTEM_STATUE = 2 +}; + +class Totem : public Creature +{ + public: + explicit Totem(); + virtual ~Totem(){}; + void Update( uint32 time ); + void Summon(Unit* owner); + void UnSummon(); + uint32 GetSpell() const { return m_spells[0]; } + uint32 GetTotemDuration() const { return m_duration; } + Unit *GetOwner(); + TotemType GetTotemType() const { return m_type; } + void SetTypeBySummonSpell(SpellEntry const * spellProto); + void SetDuration(uint32 dur) { m_duration = dur; } + void SetOwner(uint64 guid); + + bool UpdateStats(Stats /*stat*/) { return true; } + bool UpdateAllStats() { return true; } + void UpdateResistances(uint32 /*school*/) {} + void UpdateArmor() {} + void UpdateMaxHealth() {} + void UpdateMaxPower(Powers /*power*/) {} + void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {} + void UpdateDamagePhysical(WeaponAttackType /*attType*/) {} + + protected: + TotemType m_type; + uint32 m_duration; +}; +#endif diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp new file mode 100644 index 000000000..f3f280ce1 --- /dev/null +++ b/src/game/TotemAI.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "TotemAI.h" +#include "Totem.h" +#include "Creature.h" +#include "Player.h" +#include "Database/DBCStores.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "SpellMgr.h" + +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" + +int +TotemAI::Permissible(const Creature *creature) +{ + if( creature->isTotem() ) + return PERMIT_BASE_PROACTIVE; + + return PERMIT_BASE_NO; +} + +TotemAI::TotemAI(Creature &c) : i_totem(static_cast(c)), i_victimGuid(0) +{ +} + +void +TotemAI::MoveInLineOfSight(Unit *) +{ +} + +void TotemAI::EnterEvadeMode() +{ + i_totem.CombatStop(); +} + +void +TotemAI::UpdateAI(const uint32 /*diff*/) +{ + if (i_totem.GetTotemType() != TOTEM_ACTIVE) + return; + + if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false)) + return; + + // Search spell + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell()); + if (!spellInfo) + return; + + // Get spell rangy + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); + float max_range = GetSpellMaxRange(srange); + + // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems + + // pointer to appropriate target if found any + Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(i_totem, i_victimGuid) : NULL; + + // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end) + if( !victim || + !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) || + i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) ) + { + CellPair p(MaNGOS::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + victim = NULL; + + MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range); + MaNGOS::UnitLastSearcher checker(victim, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); + TypeContainerVisitor, WorldTypeMapContainer > world_object_checker(checker); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem)); + cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem)); + } + + // If have target + if (victim) + { + // remember + i_victimGuid = victim->GetGUID(); + + // attack + i_totem.SetInFront(victim); // client change orientation by self + i_totem.CastSpell(victim, i_totem.GetSpell(), false); + } + else + i_victimGuid = 0; +} + +bool +TotemAI::IsVisible(Unit *) const +{ + return false; +} + +void +TotemAI::AttackStart(Unit *) +{ +} diff --git a/src/game/TotemAI.h b/src/game/TotemAI.h new file mode 100644 index 000000000..6861e7ba0 --- /dev/null +++ b/src/game/TotemAI.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_TOTEMAI_H +#define MANGOS_TOTEMAI_H + +#include "CreatureAI.h" +#include "Timer.h" + +class Creature; +class Totem; + +class MANGOS_DLL_DECL TotemAI : public CreatureAI +{ + public: + + TotemAI(Creature &c); + + void MoveInLineOfSight(Unit *); + void AttackStart(Unit *); + void EnterEvadeMode(); + bool IsVisible(Unit *) const; + + void UpdateAI(const uint32); + static int Permissible(const Creature *); + + private: + Totem &i_totem; + uint64 i_victimGuid; +}; +#endif diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp new file mode 100644 index 000000000..f234c338e --- /dev/null +++ b/src/game/TradeHandler.cpp @@ -0,0 +1,634 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectAccessor.h" +#include "Log.h" +#include "Opcodes.h" +#include "Player.h" +#include "Item.h" +#include "SocialMgr.h" +#include "Language.h" + +enum TradeStatus +{ + TRADE_STATUS_BUSY = 0, + TRADE_STATUS_BEGIN_TRADE = 1, + TRADE_STATUS_OPEN_WINDOW = 2, + TRADE_STATUS_TRADE_CANCELED = 3, + TRADE_STATUS_TRADE_ACCEPT = 4, + TRADE_STATUS_BUSY_2 = 5, + TRADE_STATUS_NO_TARGET = 6, + TRADE_STATUS_BACK_TO_TRADE = 7, + TRADE_STATUS_TRADE_COMPLETE = 8, + // 9? + TRADE_STATUS_TARGET_TO_FAR = 10, + TRADE_STATUS_WRONG_FACTION = 11, + TRADE_STATUS_CLOSE_WINDOW = 12, + // 13? + TRADE_STATUS_IGNORE_YOU = 14, + TRADE_STATUS_YOU_STUNNED = 15, + TRADE_STATUS_TARGET_STUNNED = 16, + TRADE_STATUS_YOU_DEAD = 17, + TRADE_STATUS_TARGET_DEAD = 18, + TRADE_STATUS_YOU_LOGOUT = 19, + TRADE_STATUS_TARGET_LOGOUT = 20, + TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action + TRADE_STATUS_ONLY_CONJURED = 22 // You can only trade conjured items... (cross realm BG related). +}; + +void WorldSession::SendTradeStatus(uint32 status) +{ + WorldPacket data; + + switch(status) + { + case TRADE_STATUS_BEGIN_TRADE: + data.Initialize(SMSG_TRADE_STATUS, 4+8); + data << uint32(status); + data << uint64(0); + break; + case TRADE_STATUS_OPEN_WINDOW: + data.Initialize(SMSG_TRADE_STATUS, 4+4); + data << uint32(status); + data << uint32(0); // added in 2.4.0 + break; + case TRADE_STATUS_CLOSE_WINDOW: + data.Initialize(SMSG_TRADE_STATUS, 4+4+1+4); + data << uint32(status); + data << uint32(0); + data << uint8(0); + data << uint32(0); + break; + case TRADE_STATUS_ONLY_CONJURED: + data.Initialize(SMSG_TRADE_STATUS, 4+1); + data << uint32(status); + data << uint8(0); + break; + default: + data.Initialize(SMSG_TRADE_STATUS, 4); + data << uint32(status); + break; + } + + SendPacket(&data); +} + +void WorldSession::HandleIgnoreTradeOpcode(WorldPacket& /*recvPacket*/) +{ + sLog.outDebug( "WORLD: Ignore Trade %u",_player->GetGUIDLow()); + // recvPacket.print_storage(); +} + +void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/) +{ + sLog.outDebug( "WORLD: Busy Trade %u",_player->GetGUIDLow()); + // recvPacket.print_storage(); +} + +void WorldSession::SendUpdateTrade() +{ + Item *item = NULL; + + if( !_player || !_player->pTrader ) + return; + + // reset trade status + if (_player->acceptTrade) + { + _player->acceptTrade = false; + SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + } + + if (_player->pTrader->acceptTrade) + { + _player->pTrader->acceptTrade = false; + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + } + + WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100)); // guess size + data << (uint8 ) 1; // can be different (only seen 0 and 1) + data << (uint32) 0; // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?) + data << (uint32) TRADE_SLOT_COUNT; // trade slots count/number?, = next field in most cases + data << (uint32) TRADE_SLOT_COUNT; // trade slots count/number?, = prev field in most cases + data << (uint32) _player->pTrader->tradeGold; // trader gold + data << (uint32) 0; // spell casted on lowest slot item + + for(uint8 i = 0; i < TRADE_SLOT_COUNT; i++) + { + item = (_player->pTrader->tradeItems[i] != NULL_SLOT ? _player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i] ) : NULL); + + data << (uint8) i; // trade slot number, if not specified, then end of packet + + if(item) + { + data << (uint32) item->GetProto()->ItemId; // entry + // display id + data << (uint32) item->GetProto()->DisplayInfoID; + // stack count + data << (uint32) item->GetUInt32Value(ITEM_FIELD_STACK_COUNT); + data << (uint32) 0; // probably gift=1, created_by=0? + // gift creator + data << (uint64) item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR); + data << (uint32) item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT); + for(uint8 j = 0; j < 3; ++j) + data << (uint32) 0; // enchantment id (permanent/gems?) + // creator + data << (uint64) item->GetUInt64Value(ITEM_FIELD_CREATOR); + data << (uint32) item->GetSpellCharges(); // charges + data << (uint32) item->GetItemSuffixFactor(); // SuffixFactor + // random properties id + data << (uint32) item->GetItemRandomPropertyId(); + data << (uint32) item->GetProto()->LockID; // lock id + // max durability + data << (uint32) item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); + // durability + data << (uint32) item->GetUInt32Value(ITEM_FIELD_DURABILITY); + } + else + { + for(uint8 j = 0; j < 18; j++) + data << uint32(0); + } + } + SendPacket(&data); +} + +//============================================================== +// transfer the items to the players + +void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) +{ + for(int i=0; ipTrader->CanStoreItem( NULL_BAG, NULL_SLOT, traderDst, myItems[i], false ) == EQUIP_ERR_OK); + bool playerCanTrade = (hisItems[i]==NULL || _player->CanStoreItem( NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false ) == EQUIP_ERR_OK); + if(traderCanTrade && playerCanTrade ) + { + // Ok, if trade item exists and can be stored + // If we trade in both directions we had to check, if the trade will work before we actually do it + // A roll back is not possible after we stored it + if(myItems[i]) + { + // logging + sLog.outDebug("partner storing: %u",myItems[i]->GetGUIDLow()); + if( _player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + sLog.outCommand("GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", + _player->GetName(),_player->GetSession()->GetAccountId(), + myItems[i]->GetProto()->Name1,myItems[i]->GetEntry(),myItems[i]->GetCount(), + _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId()); + + // store + _player->pTrader->MoveItemToInventory( traderDst, myItems[i], true, true); + } + if(hisItems[i]) + { + // logging + sLog.outDebug("player storing: %u",hisItems[i]->GetGUIDLow()); + if( _player->pTrader->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + sLog.outCommand("GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", + _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId(), + hisItems[i]->GetProto()->Name1,hisItems[i]->GetEntry(),hisItems[i]->GetCount(), + _player->GetName(),_player->GetSession()->GetAccountId()); + + // store + _player->MoveItemToInventory( playerDst, hisItems[i], true, true); + } + } + else + { + // in case of fatal error log error message + // return the already removed items to the original owner + if(myItems[i]) + { + if(!traderCanTrade) + sLog.outError("trader can't store item: %u",myItems[i]->GetGUIDLow()); + if(_player->CanStoreItem( NULL_BAG, NULL_SLOT, playerDst, myItems[i], false ) == EQUIP_ERR_OK) + _player->MoveItemToInventory(playerDst, myItems[i], true, true); + else + sLog.outError("player can't take item back: %u",myItems[i]->GetGUIDLow()); + } + // return the already removed items to the original owner + if(hisItems[i]) + { + if(!playerCanTrade) + sLog.outError("player can't store item: %u",hisItems[i]->GetGUIDLow()); + if(_player->pTrader->CanStoreItem( NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false ) == EQUIP_ERR_OK) + _player->pTrader->MoveItemToInventory(traderDst, hisItems[i], true, true); + else + sLog.outError("trader can't take item back: %u",hisItems[i]->GetGUIDLow()); + } + } + } +} + +//============================================================== + +void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) +{ + Item *myItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; + Item *hisItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; + bool myCanCompleteTrade=true,hisCanCompleteTrade=true; + + if ( !GetPlayer()->pTrader ) + return; + + // not accept case incorrect money amount + if( _player->tradeGold > _player->GetMoney() ) + { + SendNotification(LANG_NOT_ENOUGH_GOLD); + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + _player->acceptTrade = false; + return; + } + + // not accept case incorrect money amount + if( _player->pTrader->tradeGold > _player->pTrader->GetMoney() ) + { + _player->pTrader->GetSession( )->SendNotification(LANG_NOT_ENOUGH_GOLD); + SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + _player->pTrader->acceptTrade = false; + return; + } + + // not accept if some items now can't be trade (cheating) + for(int i=0; itradeItems[i] != NULL_SLOT ) + { + if(Item* item =_player->GetItemByPos( _player->tradeItems[i] )) + { + if(!item->CanBeTraded()) + { + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; + } + } + } + if(_player->pTrader->tradeItems[i] != NULL_SLOT) + { + if(Item* item =_player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i]) ) + { + if(!item->CanBeTraded()) + { + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; + } + } + } + } + + _player->acceptTrade = true; + if (_player->pTrader->acceptTrade ) + { + // inform partner client + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + + // store items in local list and set 'in-trade' flag + for(int i=0; itradeItems[i] != NULL_SLOT ) + { + sLog.outDebug("player trade item bag: %u slot: %u",_player->tradeItems[i] >> 8, _player->tradeItems[i] & 255 ); + //Can return NULL + myItems[i]=_player->GetItemByPos( _player->tradeItems[i] ); + if (myItems[i]) + myItems[i]->SetInTrade(); + } + if(_player->pTrader->tradeItems[i] != NULL_SLOT) + { + sLog.outDebug("partner trade item bag: %u slot: %u",_player->pTrader->tradeItems[i] >> 8,_player->pTrader->tradeItems[i] & 255); + //Can return NULL + hisItems[i]=_player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i]); + if(hisItems[i]) + hisItems[i]->SetInTrade(); + } + } + + // test if item will fit in each inventory + hisCanCompleteTrade = (_player->pTrader->CanStoreItems( myItems,TRADE_SLOT_TRADED_COUNT )== EQUIP_ERR_OK); + myCanCompleteTrade = (_player->CanStoreItems( hisItems,TRADE_SLOT_TRADED_COUNT ) == EQUIP_ERR_OK); + + // clear 'in-trade' flag + for(int i=0; iSetInTrade(false); + if(hisItems[i]) hisItems[i]->SetInTrade(false); + } + + // in case of missing space report error + if(!myCanCompleteTrade) + { + SendNotification(LANG_NOT_FREE_TRADE_SLOTS); + GetPlayer( )->pTrader->GetSession( )->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); + SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + return; + } + else if (!hisCanCompleteTrade) + { + SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); + GetPlayer()->pTrader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS); + SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + return; + } + + // execute trade: 1. remove + for(int i=0; iSetUInt64Value( ITEM_FIELD_GIFTCREATOR,_player->GetGUID()); + _player->MoveItemFromInventory(_player->tradeItems[i] >> 8, _player->tradeItems[i] & 255, true); + } + if(hisItems[i]) + { + hisItems[i]->SetUInt64Value( ITEM_FIELD_GIFTCREATOR,_player->pTrader->GetGUID()); + _player->pTrader->MoveItemFromInventory(_player->pTrader->tradeItems[i] >> 8, _player->pTrader->tradeItems[i] & 255, true); + } + } + + // execute trade: 2. store + moveItems(myItems, hisItems); + + // logging money + if(sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + if( _player->GetSession()->GetSecurity() > SEC_PLAYER && _player->tradeGold > 0) + sLog.outCommand("GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", + _player->GetName(),_player->GetSession()->GetAccountId(), + _player->tradeGold, + _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId()); + if( _player->pTrader->GetSession()->GetSecurity() > SEC_PLAYER && _player->pTrader->tradeGold > 0) + sLog.outCommand("GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", + _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId(), + _player->pTrader->tradeGold, + _player->GetName(),_player->GetSession()->GetAccountId()); + } + + // update money + _player->ModifyMoney( -int32(_player->tradeGold) ); + _player->ModifyMoney(_player->pTrader->tradeGold ); + _player->pTrader->ModifyMoney( -int32(_player->pTrader->tradeGold) ); + _player->pTrader->ModifyMoney(_player->tradeGold ); + + _player->ClearTrade(); + _player->pTrader->ClearTrade(); + + // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards) + CharacterDatabase.BeginTransaction(); + _player->SaveInventoryAndGoldToDB(); + _player->pTrader->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); + + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); + SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); + + _player->pTrader->pTrader = NULL; + _player->pTrader = NULL; + } + else + { + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + } +} + +void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/) +{ + if ( !GetPlayer()->pTrader ) + return; + + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + _player->acceptTrade = false; +} + +void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/) +{ + if(!_player->pTrader) + return; + + _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); + _player->pTrader->ClearTrade(); + + SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); + _player->ClearTrade(); +} + +void WorldSession::SendCancelTrade() +{ + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); +} + +void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) +{ + // sended also after LOGOUT COMPLETE + if(_player) // needed because STATUS_AUTHED + _player->TradeCancel(true); +} + +void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,8); + + if( GetPlayer()->pTrader ) + return; + + uint64 ID; + + if( !GetPlayer()->isAlive() ) + { + SendTradeStatus(TRADE_STATUS_YOU_DEAD); + return; + } + + if( GetPlayer()->hasUnitState(UNIT_STAT_STUNNED) ) + { + SendTradeStatus(TRADE_STATUS_YOU_STUNNED); + return; + } + + if( isLogingOut() ) + { + SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); + return; + } + + if( GetPlayer()->isInFlight() ) + { + SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + return; + } + + recvPacket >> ID; + + Player* pOther = ObjectAccessor::FindPlayer( ID ); + + if( !pOther ) + { + SendTradeStatus(TRADE_STATUS_NO_TARGET); + return; + } + + if( pOther == GetPlayer() || pOther->pTrader ) + { + SendTradeStatus(TRADE_STATUS_BUSY); + return; + } + + if( !pOther->isAlive() ) + { + SendTradeStatus(TRADE_STATUS_TARGET_DEAD); + return; + } + + if( pOther->isInFlight() ) + { + SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + return; + } + + if( pOther->hasUnitState(UNIT_STAT_STUNNED) ) + { + SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); + return; + } + + if( pOther->GetSession()->isLogingOut() ) + { + SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); + return; + } + + if( pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()) ) + { + SendTradeStatus(TRADE_STATUS_IGNORE_YOU); + return; + } + + if(pOther->GetTeam() !=_player->GetTeam() ) + { + SendTradeStatus(TRADE_STATUS_WRONG_FACTION); + return; + } + + if( pOther->GetDistance2d( _player ) > 10.0f ) + { + SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + return; + } + + // OK start trade + _player->pTrader = pOther; + pOther->pTrader =_player; + + WorldPacket data(SMSG_TRADE_STATUS, 12); + data << (uint32) TRADE_STATUS_BEGIN_TRADE; + data << (uint64)_player->GetGUID(); + _player->pTrader->GetSession()->SendPacket(&data); +} + +void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,4); + + if(!_player->pTrader) + return; + + uint32 gold; + + recvPacket >> gold; + + // gold can be incorrect, but this is checked at trade finished. + _player->tradeGold = gold; + + _player->pTrader->GetSession()->SendUpdateTrade(); +} + +void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,1+1+1); + + if(!_player->pTrader) + return; + + // send update + uint8 tradeSlot; + uint8 bag; + uint8 slot; + + recvPacket >> tradeSlot; + recvPacket >> bag; + recvPacket >> slot; + + // invalid slot number + if(tradeSlot >= TRADE_SLOT_COUNT) + { + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; + } + + // check cheating, can't fail with correct client operations + Item* item = _player->GetItemByPos(bag,slot); + if(!item || tradeSlot!=TRADE_SLOT_NONTRADED && !item->CanBeTraded()) + { + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; + } + + uint16 pos = (bag << 8) | slot; + + // prevent place single item into many trade slots using cheating and client bugs + for(int i = 0; i < TRADE_SLOT_COUNT; ++i) + { + if(_player->tradeItems[i]==pos) + { + // cheating attempt + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; + } + } + + _player->tradeItems[tradeSlot] = pos; + + _player->pTrader->GetSession()->SendUpdateTrade(); +} + +void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket) +{ + CHECK_PACKET_SIZE(recvPacket,1); + + if(!_player->pTrader) + return; + + uint8 tradeSlot; + recvPacket >> tradeSlot; + + // invalid slot number + if(tradeSlot >= TRADE_SLOT_COUNT) + return; + + _player->tradeItems[tradeSlot] = NULL_SLOT; + + _player->pTrader->GetSession()->SendUpdateTrade(); +} diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp new file mode 100644 index 000000000..a8a4abc0a --- /dev/null +++ b/src/game/Transports.cpp @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" + +#include "Transports.h" +#include "MapManager.h" +#include "ObjectMgr.h" +#include "Path.h" + +#include "WorldPacket.h" +#include "Database/DBCStores.h" +#include "ProgressBar.h" + +void MapManager::LoadTransports() +{ + QueryResult *result = WorldDatabase.Query("SELECT entry, name, period FROM transports"); + + uint32 count = 0; + + if( !result ) + { + barGoLink bar( 1 ); + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u transports", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Transport *t = new Transport; + + Field *fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + std::string name = fields[1].GetCppString(); + t->m_period = fields[2].GetUInt32(); + + const GameObjectInfo *goinfo = objmgr.GetGameObjectInfo(entry); + + if(!goinfo) + { + sLog.outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template missing", entry, name.c_str()); + delete t; + continue; + } + + if(goinfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT) + { + sLog.outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template type wrong", entry, name.c_str()); + delete t; + continue; + } + + // sLog.outString("Loading transport %d between %s, %s", entry, name.c_str(), goinfo->name); + + std::set mapsUsed; + + if(!t->GenerateWaypoints(goinfo->moTransport.taxiPathId, mapsUsed)) + // skip transports with empty waypoints list + { + sLog.outErrorDb("Transport (path id %u) path size = 0. Transport ignored, check DBC files or transport GO data0 field.",goinfo->moTransport.taxiPathId); + delete t; + continue; + } + + t->m_name = goinfo->name; + + float x, y, z, o; + uint32 mapid; + x = t->m_WayPoints[0].x; y = t->m_WayPoints[0].y; z = t->m_WayPoints[0].z; mapid = t->m_WayPoints[0].mapid; o = 1; + + // creates the Gameobject + if(!t->Create(entry, mapid, x, y, z, o, 100, 0)) + { + delete t; + continue; + } + + m_Transports.insert(t); + + for (std::set::iterator i = mapsUsed.begin(); i != mapsUsed.end(); ++i) + m_TransportsByMap[*i].insert(t); + + //If we someday decide to use the grid to track transports, here: + //MapManager::Instance().LoadGrid(mapid,x,y,true); + //MapManager::Instance().GetMap(t->GetMapId())->Add((GameObject *)t); + ++count; + } while(result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u transports", count ); + + // check transport data DB integrity + result = WorldDatabase.PQuery("SELECT gameobject.guid,gameobject.id,transports.name FROM gameobject,transports WHERE gameobject.id = transports.entry"); + if(result) // wrong data found + { + do + { + Field *fields = result->Fetch(); + + uint32 guid = fields[0].GetUInt32(); + uint32 entry = fields[1].GetUInt32(); + std::string name = fields[2].GetCppString(); + sLog.outErrorDb("Transport %u '%s' have record (GUID: %u) in `gameobject`. Transports DON'T must have any records in `gameobject` or its behavior will be unpredictable/bugged.",entry,name.c_str(),guid); + } + while(result->NextRow()); + + delete result; + } +} + +Transport::Transport() : GameObject() +{ + // 2.3.2 - 0x5A + m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); +} + +bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) +{ + Relocate(x,y,z,ang); + + SetMapId(mapid); + + if(!IsPositionValid()) + { + sLog.outError("ERROR: Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %d Y: ^%d)",guidlow,x,y); + return false; + } + + Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); + + GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(guidlow); + + if (!goinfo) + { + sLog.outErrorDb("Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f",guidlow, mapid, x, y, z, ang); + return false; + } + + m_goInfo = goinfo; + + SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); + + SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); + SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); + + SetEntry(goinfo->id); + + SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); + + SetGoState(1); + SetGoType(GameobjectTypes(goinfo->type)); + + SetGoAnimProgress(animprogress); + if(dynflags) + SetUInt32Value(GAMEOBJECT_DYN_FLAGS, dynflags); + + return true; +} + +struct keyFrame +{ + keyFrame(float _x, float _y, float _z, uint32 _mapid, int _actionflag, int _delay) + { + x = _x; y = _y; z = _z; mapid = _mapid; actionflag = _actionflag; delay = _delay; distFromPrev = -1; distSinceStop = -1; distUntilStop = -1; + tFrom = 0; tTo = 0; + } + + float x; + float y; + float z; + uint32 mapid; + int actionflag; + int delay; + float distSinceStop; + float distUntilStop; + float distFromPrev; + float tFrom, tTo; +}; + +bool Transport::GenerateWaypoints(uint32 pathid, std::set &mapids) +{ + TransportPath path; + objmgr.GetTransportPathNodes(pathid, path); + + if (path.Empty()) + return false; + + std::vector keyFrames; + int mapChange = 0; + mapids.clear(); + for (size_t i = 1; i < path.Size() - 1; i++) + { + if (mapChange == 0) + { + if ((path[i].mapid == path[i+1].mapid)) + { + keyFrame k(path[i].x, path[i].y, path[i].z, path[i].mapid, path[i].actionFlag, path[i].delay); + keyFrames.push_back(k); + mapids.insert(k.mapid); + } + else + { + mapChange = 1; + } + } + else + { + --mapChange; + } + } + + int lastStop = -1; + int firstStop = -1; + + // first cell is arrived at by teleportation :S + keyFrames[0].distFromPrev = 0; + if (keyFrames[0].actionflag == 2) + { + lastStop = 0; + } + + // find the rest of the distances between key points + for (size_t i = 1; i < keyFrames.size(); i++) + { + if ((keyFrames[i].actionflag == 1) || (keyFrames[i].mapid != keyFrames[i-1].mapid)) + { + keyFrames[i].distFromPrev = 0; + } + else + { + keyFrames[i].distFromPrev = + sqrt(pow(keyFrames[i].x - keyFrames[i - 1].x, 2) + + pow(keyFrames[i].y - keyFrames[i - 1].y, 2) + + pow(keyFrames[i].z - keyFrames[i - 1].z, 2)); + } + if (keyFrames[i].actionflag == 2) + { + // remember first stop frame + if(firstStop == -1) + firstStop = i; + lastStop = i; + } + } + + float tmpDist = 0; + for (size_t i = 0; i < keyFrames.size(); i++) + { + int j = (i + lastStop) % keyFrames.size(); + if (keyFrames[j].actionflag == 2) + tmpDist = 0; + else + tmpDist += keyFrames[j].distFromPrev; + keyFrames[j].distSinceStop = tmpDist; + } + + for (int i = int(keyFrames.size()) - 1; i >= 0; i--) + { + int j = (i + (firstStop+1)) % keyFrames.size(); + tmpDist += keyFrames[(j + 1) % keyFrames.size()].distFromPrev; + keyFrames[j].distUntilStop = tmpDist; + if (keyFrames[j].actionflag == 2) + tmpDist = 0; + } + + for (size_t i = 0; i < keyFrames.size(); i++) + { + if (keyFrames[i].distSinceStop < (30 * 30 * 0.5f)) + keyFrames[i].tFrom = sqrt(2 * keyFrames[i].distSinceStop); + else + keyFrames[i].tFrom = ((keyFrames[i].distSinceStop - (30 * 30 * 0.5f)) / 30) + 30; + + if (keyFrames[i].distUntilStop < (30 * 30 * 0.5f)) + keyFrames[i].tTo = sqrt(2 * keyFrames[i].distUntilStop); + else + keyFrames[i].tTo = ((keyFrames[i].distUntilStop - (30 * 30 * 0.5f)) / 30) + 30; + + keyFrames[i].tFrom *= 1000; + keyFrames[i].tTo *= 1000; + } + + // for (int i = 0; i < keyFrames.size(); i++) { + // sLog.outString("%f, %f, %f, %f, %f, %f, %f", keyFrames[i].x, keyFrames[i].y, keyFrames[i].distUntilStop, keyFrames[i].distSinceStop, keyFrames[i].distFromPrev, keyFrames[i].tFrom, keyFrames[i].tTo); + // } + + // Now we're completely set up; we can move along the length of each waypoint at 100 ms intervals + // speed = max(30, t) (remember x = 0.5s^2, and when accelerating, a = 1 unit/s^2 + int t = 0; + bool teleport = false; + if (keyFrames[keyFrames.size() - 1].mapid != keyFrames[0].mapid) + teleport = true; + + WayPoint pos(keyFrames[0].mapid, keyFrames[0].x, keyFrames[0].y, keyFrames[0].z, teleport); + m_WayPoints[0] = pos; + t += keyFrames[0].delay * 1000; + + uint32 cM = keyFrames[0].mapid; + for (size_t i = 0; i < keyFrames.size() - 1; i++) + { + float d = 0; + float tFrom = keyFrames[i].tFrom; + float tTo = keyFrames[i].tTo; + + // keep the generation of all these points; we use only a few now, but may need the others later + if (((d < keyFrames[i + 1].distFromPrev) && (tTo > 0))) + { + while ((d < keyFrames[i + 1].distFromPrev) && (tTo > 0)) + { + tFrom += 100; + tTo -= 100; + + if (d > 0) + { + float newX, newY, newZ; + newX = keyFrames[i].x + (keyFrames[i + 1].x - keyFrames[i].x) * d / keyFrames[i + 1].distFromPrev; + newY = keyFrames[i].y + (keyFrames[i + 1].y - keyFrames[i].y) * d / keyFrames[i + 1].distFromPrev; + newZ = keyFrames[i].z + (keyFrames[i + 1].z - keyFrames[i].z) * d / keyFrames[i + 1].distFromPrev; + + bool teleport = false; + if (keyFrames[i].mapid != cM) + { + teleport = true; + cM = keyFrames[i].mapid; + } + + // sLog.outString("T: %d, D: %f, x: %f, y: %f, z: %f", t, d, newX, newY, newZ); + WayPoint pos(keyFrames[i].mapid, newX, newY, newZ, teleport); + if (teleport) + m_WayPoints[t] = pos; + } + + if (tFrom < tTo) // caught in tFrom dock's "gravitational pull" + { + if (tFrom <= 30000) + { + d = 0.5f * (tFrom / 1000) * (tFrom / 1000); + } + else + { + d = 0.5f * 30 * 30 + 30 * ((tFrom - 30000) / 1000); + } + d = d - keyFrames[i].distSinceStop; + } + else + { + if (tTo <= 30000) + { + d = 0.5f * (tTo / 1000) * (tTo / 1000); + } + else + { + d = 0.5f * 30 * 30 + 30 * ((tTo - 30000) / 1000); + } + d = keyFrames[i].distUntilStop - d; + } + t += 100; + } + t -= 100; + } + + if (keyFrames[i + 1].tFrom > keyFrames[i + 1].tTo) + t += 100 - ((long)keyFrames[i + 1].tTo % 100); + else + t += (long)keyFrames[i + 1].tTo % 100; + + bool teleport = false; + if ((keyFrames[i + 1].actionflag == 1) || (keyFrames[i + 1].mapid != keyFrames[i].mapid)) + { + teleport = true; + cM = keyFrames[i + 1].mapid; + } + + WayPoint pos(keyFrames[i + 1].mapid, keyFrames[i + 1].x, keyFrames[i + 1].y, keyFrames[i + 1].z, teleport); + + // sLog.outString("T: %d, x: %f, y: %f, z: %f, t:%d", t, pos.x, pos.y, pos.z, teleport); + + //if (teleport) + m_WayPoints[t] = pos; + + t += keyFrames[i + 1].delay * 1000; + // sLog.outString("------"); + } + + uint32 timer = t; + + // sLog.outDetail(" Generated %d waypoints, total time %u.", m_WayPoints.size(), timer); + + m_curr = m_WayPoints.begin(); + m_curr = GetNextWayPoint(); + m_next = GetNextWayPoint(); + m_pathTime = timer; + + m_nextNodeTime = m_curr->first; + + return true; +} + +Transport::WayPointMap::iterator Transport::GetNextWayPoint() +{ + WayPointMap::iterator iter = m_curr; + ++iter; + if (iter == m_WayPoints.end()) + iter = m_WayPoints.begin(); + return iter; +} + +void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z) +{ + //MapManager::Instance().GetMap(oldMapid)->Remove((GameObject *)this, false); + SetMapId(newMapid); + //MapManager::Instance().LoadGrid(newMapid,x,y,true); + Relocate(x, y, z); + //MapManager::Instance().GetMap(newMapid)->Add((GameObject *)this); + + for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();) + { + PlayerSet::iterator it2 = itr; + ++itr; + + Player *plr = *it2; + if(!plr) + { + m_passengers.erase(it2); + continue; + } + + if (plr->isDead() && !plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + { + plr->ResurrectPlayer(1.0); + } + plr->TeleportTo(newMapid, x, y, z, GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT); + + //WorldPacket data(SMSG_811, 4); + //data << uint32(0); + //plr->GetSession()->SendPacket(&data); + } +} + +bool Transport::AddPassenger(Player* passenger) +{ + if (m_passengers.find(passenger) == m_passengers.end()) + { + sLog.outDetail("Player %s boarded transport %s.", passenger->GetName(), this->m_name.c_str()); + m_passengers.insert(passenger); + } + return true; +} + +bool Transport::RemovePassenger(Player* passenger) +{ + if (m_passengers.find(passenger) != m_passengers.end()) + { + sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), this->m_name.c_str()); + m_passengers.erase(passenger); + } + return true; +} + +void Transport::Update(uint32 /*p_time*/) +{ + if (m_WayPoints.size() <= 1) + return; + + m_timer = getMSTime() % m_period; + while (((m_timer - m_curr->first) % m_pathTime) > ((m_next->first - m_curr->first) % m_pathTime)) + { + m_curr = GetNextWayPoint(); + m_next = GetNextWayPoint(); + + // first check help in case client-server transport coordinates de-synchronization + if (m_curr->second.mapid != GetMapId() || m_curr->second.teleport) + { + TeleportTransport(m_curr->second.mapid, m_curr->second.x, m_curr->second.y, m_curr->second.z); + } + else + { + //MapManager::Instance().GetMap(m_curr->second.mapid)->GameobjectRelocation((GameObject *)this, m_curr->second.x, m_curr->second.y, m_curr->second.z, this->m_orientation); + Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z); + } + + /* + for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();) + { + PlayerSet::iterator it2 = itr; + ++itr; + //(*it2)->SetPosition( m_curr->second.x + (*it2)->GetTransOffsetX(), m_curr->second.y + (*it2)->GetTransOffsetY(), m_curr->second.z + (*it2)->GetTransOffsetZ(), (*it2)->GetTransOffsetO() ); + } + */ + + m_nextNodeTime = m_curr->first; + + if (m_curr == m_WayPoints.begin() && (sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0) + sLog.outDetail(" ************ BEGIN ************** %s", this->m_name.c_str()); + + // MapManager::Instance().GetMap(m_curr->second.mapid)->Add(&this); // -> // ->Add(t); + //MapManager::Instance().GetMap(m_curr->second.mapid)->Remove((GameObject *)this, false); // -> // ->Add(t); + //MapManager::Instance().GetMap(m_curr->second.mapid)->Add((GameObject *)this); // -> // ->Add(t); + + if ((sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0) + sLog.outDetail("%s moved to %f %f %f %d", this->m_name.c_str(), m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid); + } +} diff --git a/src/game/Transports.h b/src/game/Transports.h new file mode 100644 index 000000000..ab48ee9a9 --- /dev/null +++ b/src/game/Transports.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TRANSPORTS_H +#define TRANSPORTS_H + +#include "GameObject.h" + +#include +#include +#include + +class TransportPath +{ + public: + struct PathNode + { + uint32 mapid; + float x,y,z; + uint32 actionFlag; + uint32 delay; + }; + + inline void SetLength(const unsigned int sz) + { + i_nodes.resize( sz ); + } + + inline unsigned int Size(void) const { return i_nodes.size(); } + inline bool Empty(void) const { return i_nodes.empty(); } + inline void Resize(unsigned int sz) { i_nodes.resize(sz); } + inline void Clear(void) { i_nodes.clear(); } + inline PathNode* GetNodes(void) { return static_cast(&i_nodes[0]); } + + PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; } + const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; } + + protected: + std::vector i_nodes; +}; + +class Transport : private GameObject +{ + public: + explicit Transport(); + + // prevent using Transports as normal GO, but allow call some inherited functions + using GameObject::IsTransport; + using GameObject::GetEntry; + using GameObject::GetGUID; + using GameObject::GetGUIDLow; + using GameObject::GetMapId; + using GameObject::GetPositionX; + using GameObject::GetPositionY; + using GameObject::GetPositionZ; + using GameObject::BuildCreateUpdateBlockForPlayer; + using GameObject::BuildOutOfRangeUpdateBlock; + + bool Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags); + bool GenerateWaypoints(uint32 pathid, std::set &mapids); + void Update(uint32 p_time); + bool AddPassenger(Player* passenger); + bool RemovePassenger(Player* passenger); + + typedef std::set PlayerSet; + PlayerSet const& GetPassengers() const { return m_passengers; } + + std::string m_name; + private: + struct WayPoint + { + WayPoint() : mapid(0), x(0), y(0), z(0), teleport(false) {} + WayPoint(uint32 _mapid, float _x, float _y, float _z, bool _teleport) : + mapid(_mapid), x(_x), y(_y), z(_z), teleport(_teleport) {} + uint32 mapid; + float x; + float y; + float z; + bool teleport; + }; + + typedef std::map WayPointMap; + + WayPointMap::iterator m_curr; + WayPointMap::iterator m_next; + uint32 m_pathTime; + uint32 m_timer; + + PlayerSet m_passengers; + + public: + WayPointMap m_WayPoints; + uint32 m_nextNodeTime; + uint32 m_period; + + private: + void TeleportTransport(uint32 newMapid, float x, float y, float z); + WayPointMap::iterator GetNextWayPoint(); +}; +#endif diff --git a/src/game/Traveller.h b/src/game/Traveller.h new file mode 100644 index 000000000..a1479d93c --- /dev/null +++ b/src/game/Traveller.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_TRAVELLER_H +#define MANGOS_TRAVELLER_H + +#include "MapManager.h" +#include "Creature.h" +#include "Player.h" +#include + +/** Traveller is a wrapper for units (creatures or players) that + * travel from point A to point B using the destination holder. + */ +#define PLAYER_FLIGHT_SPEED 32.0f + +template +struct MANGOS_DLL_DECL Traveller +{ + T &i_traveller; + Traveller(T &t) : i_traveller(t) {} + Traveller(const Traveller &obj) : i_traveller(obj) {} + Traveller& operator=(const Traveller &obj) + { + this->~Traveller(); + new (this) Traveller(obj); + return *this; + } + + operator T&(void) { return i_traveller; } + operator const T&(void) { return i_traveller; } + inline float GetPositionX() const { return i_traveller.GetPositionX(); } + inline float GetPositionY() const { return i_traveller.GetPositionY(); } + inline float GetPositionZ() const { return i_traveller.GetPositionZ(); } + inline T& GetTraveller(void) { return i_traveller; } + + float Speed(void) { assert(false); return 0.0f; } + void Relocation(float x, float y, float z, float orientation) {} + void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); } + void MoveTo(float x, float y, float z, uint32 t) {} +}; + +// specialization for creatures +template<> +inline float Traveller::Speed() +{ + return i_traveller.GetSpeed( i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN); +} + +template<> +inline void Traveller::Relocation(float x, float y, float z, float orientation) +{ + MapManager::Instance().GetMap(i_traveller.GetMapId(), &i_traveller)->CreatureRelocation(&i_traveller, x, y, z, orientation); +} + +template<> +inline void Traveller::MoveTo(float x, float y, float z, uint32 t) +{ + i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0); +} + +// specialization for players +template<> +inline float Traveller::Speed() +{ + if (i_traveller.isInFlight()) + return PLAYER_FLIGHT_SPEED; + else + return i_traveller.GetSpeed(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN); +} + +template<> +inline void Traveller::Relocation(float x, float y, float z, float orientation) +{ + MapManager::Instance().GetMap(i_traveller.GetMapId(), &i_traveller)->PlayerRelocation(&i_traveller, x, y, z, orientation); +} + +template<> +inline void Traveller::MoveTo(float x, float y, float z, uint32 t) +{ + //Only send MOVEMENTFLAG_WALK_MODE, client has strange issues with other move flags + i_traveller.SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_WALK_MODE, t); +} + +typedef Traveller CreatureTraveller; +typedef Traveller PlayerTraveller; +#endif diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp new file mode 100644 index 000000000..9343f6606 --- /dev/null +++ b/src/game/Unit.cpp @@ -0,0 +1,10817 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Log.h" +#include "Opcodes.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Unit.h" +#include "QuestDef.h" +#include "Player.h" +#include "Creature.h" +#include "Spell.h" +#include "Group.h" +#include "SpellAuras.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "CreatureAI.h" +#include "Formulas.h" +#include "Pet.h" +#include "Util.h" +#include "Totem.h" +#include "BattleGround.h" +#include "InstanceSaveMgr.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "Path.h" + +#include + +float baseMoveSpeed[MAX_MOVE_TYPE] = +{ + 2.5f, // MOVE_WALK + 7.0f, // MOVE_RUN + 1.25f, // MOVE_WALKBACK + 4.722222f, // MOVE_SWIM + 4.5f, // MOVE_SWIMBACK + 3.141594f, // MOVE_TURN + 7.0f, // MOVE_FLY + 4.5f, // MOVE_FLYBACK +}; + +// auraTypes contains attacker auras capable of proc'ing cast auras +static Unit::AuraTypeSet GenerateAttakerProcCastAuraTypes() +{ + static Unit::AuraTypeSet auraTypes; + auraTypes.insert(SPELL_AURA_DUMMY); + auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL); + auraTypes.insert(SPELL_AURA_MOD_HASTE); + auraTypes.insert(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + return auraTypes; +} + +// auraTypes contains victim auras capable of proc'ing cast auras +static Unit::AuraTypeSet GenerateVictimProcCastAuraTypes() +{ + static Unit::AuraTypeSet auraTypes; + auraTypes.insert(SPELL_AURA_DUMMY); + auraTypes.insert(SPELL_AURA_PRAYER_OF_MENDING); + auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL); + return auraTypes; +} + +// auraTypes contains auras capable of proc effect/damage (but not cast) for attacker +static Unit::AuraTypeSet GenerateAttakerProcEffectAuraTypes() +{ + static Unit::AuraTypeSet auraTypes; + auraTypes.insert(SPELL_AURA_MOD_DAMAGE_DONE); + auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE); + auraTypes.insert(SPELL_AURA_MOD_CASTING_SPEED); + auraTypes.insert(SPELL_AURA_MOD_RATING); + return auraTypes; +} + +// auraTypes contains auras capable of proc effect/damage (but not cast) for victim +static Unit::AuraTypeSet GenerateVictimProcEffectAuraTypes() +{ + static Unit::AuraTypeSet auraTypes; + auraTypes.insert(SPELL_AURA_MOD_RESISTANCE); + auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE); + auraTypes.insert(SPELL_AURA_MOD_PARRY_PERCENT); + auraTypes.insert(SPELL_AURA_MOD_BLOCK_PERCENT); + auraTypes.insert(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + return auraTypes; +} + +static Unit::AuraTypeSet attackerProcCastAuraTypes = GenerateAttakerProcCastAuraTypes(); +static Unit::AuraTypeSet attackerProcEffectAuraTypes = GenerateAttakerProcEffectAuraTypes(); + +static Unit::AuraTypeSet victimProcCastAuraTypes = GenerateVictimProcCastAuraTypes(); +static Unit::AuraTypeSet victimProcEffectAuraTypes = GenerateVictimProcEffectAuraTypes(); + +// auraTypes contains auras capable of proc'ing for attacker and victim +static Unit::AuraTypeSet GenerateProcAuraTypes() +{ + Unit::AuraTypeSet auraTypes; + auraTypes.insert(attackerProcCastAuraTypes.begin(),attackerProcCastAuraTypes.end()); + auraTypes.insert(attackerProcEffectAuraTypes.begin(),attackerProcEffectAuraTypes.end()); + auraTypes.insert(victimProcCastAuraTypes.begin(),victimProcCastAuraTypes.end()); + auraTypes.insert(victimProcEffectAuraTypes.begin(),victimProcEffectAuraTypes.end()); + return auraTypes; +} + +static Unit::AuraTypeSet procAuraTypes = GenerateProcAuraTypes(); + +bool IsPassiveStackableSpell( uint32 spellId ) +{ + if(!IsPassiveSpell(spellId)) + return false; + + SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId); + if(!spellProto) + return false; + + for(int j = 0; j < 3; ++j) + { + if(std::find(procAuraTypes.begin(),procAuraTypes.end(),spellProto->EffectApplyAuraName[j])!=procAuraTypes.end()) + return false; + } + + return true; +} + +Unit::Unit() +: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this) +{ + m_objectType |= TYPEMASK_UNIT; + m_objectTypeId = TYPEID_UNIT; + // 2.3.2 - 0x70 + m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION); + + m_attackTimer[BASE_ATTACK] = 0; + m_attackTimer[OFF_ATTACK] = 0; + m_attackTimer[RANGED_ATTACK] = 0; + m_modAttackSpeedPct[BASE_ATTACK] = 1.0f; + m_modAttackSpeedPct[OFF_ATTACK] = 1.0f; + m_modAttackSpeedPct[RANGED_ATTACK] = 1.0f; + + m_extraAttacks = 0; + + m_state = 0; + m_form = FORM_NONE; + m_deathState = ALIVE; + + for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) + m_currentSpells[i] = NULL; + + m_addDmgOnce = 0; + + for(int i = 0; i < MAX_TOTEM; ++i) + m_TotemSlot[i] = 0; + + m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0; + //m_Aura = NULL; + //m_AurasCheck = 2000; + //m_removeAuraTimer = 4; + //tmpAura = NULL; + waterbreath = false; + + m_Visibility = VISIBILITY_ON; + + m_detectInvisibilityMask = 0; + m_invisibilityMask = 0; + m_transform = 0; + m_ShapeShiftFormSpellId = 0; + m_canModifyStats = false; + + for (int i = 0; i < MAX_SPELL_IMMUNITY; i++) + m_spellImmune[i].clear(); + for (int i = 0; i < UNIT_MOD_END; i++) + { + m_auraModifiersGroup[i][BASE_VALUE] = 0.0f; + m_auraModifiersGroup[i][BASE_PCT] = 1.0f; + m_auraModifiersGroup[i][TOTAL_VALUE] = 0.0f; + m_auraModifiersGroup[i][TOTAL_PCT] = 1.0f; + } + // implement 50% base damage from offhand + m_auraModifiersGroup[UNIT_MOD_DAMAGE_OFFHAND][TOTAL_PCT] = 0.5f; + + for (int i = 0; i < 3; i++) + { + m_weaponDamage[i][MINDAMAGE] = BASE_MINDAMAGE; + m_weaponDamage[i][MAXDAMAGE] = BASE_MAXDAMAGE; + } + for (int i = 0; i < MAX_STATS; i++) + m_createStats[i] = 0.0f; + + m_attacking = NULL; + m_modMeleeHitChance = 0.0f; + m_modRangedHitChance = 0.0f; + m_modSpellHitChance = 0.0f; + m_baseSpellCritChance = 5; + + m_CombatTimer = 0; + m_lastManaUse = 0; + + //m_victimThreat = 0.0f; + for (int i = 0; i < MAX_SPELL_SCHOOL; ++i) + m_threatModifier[i] = 1.0f; + m_isSorted = true; + for (int i = 0; i < MAX_MOVE_TYPE; ++i) + m_speed_rate[i] = 1.0f; + + m_removedAuras = 0; + m_charmInfo = NULL; + m_unit_movement_flags = 0; + + // remove aurastates allowing special moves + for(int i=0; i < MAX_REACTIVE; ++i) + m_reactiveTimer[i] = 0; +} + +Unit::~Unit() +{ + // set current spells as deletable + for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) + { + // spell may be safely deleted now + if (m_currentSpells[i]) m_currentSpells[i]->SetDeletable(true); + m_currentSpells[i] = NULL; + } + + RemoveAllGameObjects(); + RemoveAllDynObjects(); + + if(m_charmInfo) delete m_charmInfo; +} + +void Unit::Update( uint32 p_time ) +{ + /*if(p_time > m_AurasCheck) + { + m_AurasCheck = 2000; + _UpdateAura(); + }else + m_AurasCheck -= p_time;*/ + + // WARNING! Order of execution here is important, do not change. + // Spells must be processed with event system BEFORE they go to _UpdateSpells. + // Or else we may have some SPELL_STATE_FINISHED spells stalled in pointers, that is bad. + m_Events.Update( p_time ); + _UpdateSpells( p_time ); + + // update combat timer only for players and pets + if (isInCombat() && (GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet() || ((Creature*)this)->isCharmed())) + { + // Check UNIT_STAT_MELEE_ATTACKING or UNIT_STAT_CHASE (without UNIT_STAT_FOLLOW in this case) so pets can reach far away + // targets without stopping half way there and running off. + // These flags are reset after target dies or another command is given. + if( m_HostilRefManager.isEmpty() ) + { + // m_CombatTimer set at aura start and it will be freeze until aura removing + if ( m_CombatTimer <= p_time ) + ClearInCombat(); + else + m_CombatTimer -= p_time; + } + } + + if(uint32 base_att = getAttackTimer(BASE_ATTACK)) + { + setAttackTimer(BASE_ATTACK, (p_time >= base_att ? 0 : base_att - p_time) ); + } + + // update abilities available only for fraction of time + UpdateReactives( p_time ); + + ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, GetHealth() < GetMaxHealth()*0.20f); + ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, GetHealth() < GetMaxHealth()*0.35f); + + i_motionMaster.UpdateMotion(p_time); +} + +bool Unit::haveOffhandWeapon() const +{ + if(GetTypeId() == TYPEID_PLAYER) + return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true); + else + return false; +} + +void Unit::SendMonsterMoveWithSpeedToCurrentDestination(Player* player) +{ + float x, y, z; + if(GetMotionMaster()->GetDestination(x, y, z)) + SendMonsterMoveWithSpeed(x, y, z, GetUnitMovementFlags(), 0, player); +} + +void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 MovementFlags, uint32 transitTime, Player* player) +{ + if (!transitTime) + { + float dx = x - GetPositionX(); + float dy = y - GetPositionY(); + float dz = z - GetPositionZ(); + + float dist = ((dx*dx) + (dy*dy) + (dz*dz)); + if(dist<0) + dist = 0; + else + dist = sqrt(dist); + + double speed = GetSpeed((MovementFlags & MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN); + if(speed<=0) + speed = 2.5f; + speed *= 0.001f; + transitTime = static_cast(dist / speed + 0.5); + } + //float orientation = (float)atan2((double)dy, (double)dx); + SendMonsterMove(x, y, z, 0, MovementFlags, transitTime, player); +} + +void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player) +{ + WorldPacket data( SMSG_MONSTER_MOVE, (41 + GetPackGUID().size()) ); + data.append(GetPackGUID()); + + // Point A, starting location + data << GetPositionX() << GetPositionY() << GetPositionZ(); + // unknown field - unrelated to orientation + // seems to increment about 1000 for every 1.7 seconds + // for now, we'll just use mstime + data << getMSTime(); + + data << uint8(type); // unknown + switch(type) + { + case 0: // normal packet + break; + case 1: // stop packet + SendMessageToSet( &data, true ); + return; + case 2: // not used currently + data << float(0); + data << float(0); + data << float(0); + break; + case 3: // not used currently + data << uint64(0); // probably target guid + break; + case 4: // not used currently + data << float(0); // probably orientation + break; + } + + //Movement Flags (0x0 = walk, 0x100 = run, 0x200 = fly/swim) + data << uint32(MovementFlags); + + data << Time; // Time in between points + data << uint32(1); // 1 single waypoint + data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B + + if(player) + player->GetSession()->SendPacket(&data); + else + SendMessageToSet( &data, true ); +} + +void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags) +{ + uint32 traveltime = uint32(path.GetTotalLength(start, end) * 32); + + uint32 pathSize = end-start; + + WorldPacket data( SMSG_MONSTER_MOVE, (GetPackGUID().size()+4+4+4+4+1+4+4+4+pathSize*4*3) ); + data.append(GetPackGUID()); + data << GetPositionX( ) + << GetPositionY( ) + << GetPositionZ( ); + data << GetOrientation( ); + data << uint8( 0 ); + data << uint32( MovementFlags ); + data << uint32( traveltime ); + data << uint32( pathSize ); + data.append( (char*)path.GetNodes(start), pathSize * 4 * 3 ); + + //WPAssert( data.size() == 37 + pathnodes.Size( ) * 4 * 3 ); + SendMessageToSet(&data, true); +} + +void Unit::resetAttackTimer(WeaponAttackType type) +{ + m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); +} + +bool Unit::canReachWithAttack(Unit *pVictim) const +{ + assert(pVictim); + float reach = GetFloatValue(UNIT_FIELD_COMBATREACH); + if( reach <= 0.0f ) + reach = 1.0f; + return IsWithinDistInMap(pVictim, reach); +} + +void Unit::RemoveSpellsCausingAura(AuraType auraType) +{ + if (auraType >= TOTAL_AURAS) return; + AuraList::iterator iter, next; + for (iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end(); iter = next) + { + next = iter; + ++next; + + if (*iter) + { + RemoveAurasDueToSpell((*iter)->GetId()); + if (!m_modAuras[auraType].empty()) + next = m_modAuras[auraType].begin(); + else + return; + } + } +} + +bool Unit::HasAuraType(AuraType auraType) const +{ + return (!m_modAuras[auraType].empty()); +} + +/* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */ +void Unit::RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage) +{ + if(!HasAuraType(auraType)) + return; + + // The chance to dispell an aura depends on the damage taken with respect to the casters level. + uint32 max_dmg = getLevel() > 8 ? 25 * getLevel() - 150 : 50; + float chance = float(damage) / max_dmg * 100.0f; + if (roll_chance_f(chance)) + RemoveSpellsCausingAura(auraType); +} + +uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss) +{ + if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode()) + return 0; + + //You don't lose health from damage taken from another player while in a sanctuary + //You still see it in the combat log though + if(pVictim != this && GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) + { + const AreaTableEntry *area = GetAreaEntryByAreaID(pVictim->GetAreaId()); + if(area && area->flags & AREA_FLAG_SANCTUARY) //sanctuary + return 0; + } + + // remove affects from victim (including from 0 damage and DoTs) + if(pVictim != this) + pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + // remove affects from attacker at any non-DoT damage (including 0 damage) + if( damagetype != DOT) + { + RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); + + if(pVictim != this) + RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY); + + if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED)) + pVictim->SetStandState(PLAYER_STATE_NONE); + } + + //Script Event damage Deal + if( GetTypeId()== TYPEID_UNIT && ((Creature *)this)->AI()) + ((Creature *)this)->AI()->DamageDeal(pVictim, damage); + //Script Event damage taken + if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() ) + ((Creature *)pVictim)->AI()->DamageTaken(this, damage); + + if(!damage) + { + // Rage from physical damage received . + if(cleanDamage && cleanDamage->damage && (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) && pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE)) + ((Player*)pVictim)->RewardRage(cleanDamage->damage, 0, false); + + return 0; + } + + pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_FEAR, damage); + // root type spells do not dispell the root effect + if(!spellProto || spellProto->Mechanic != MECHANIC_ROOT) + pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage); + + if(pVictim->GetTypeId() != TYPEID_PLAYER) + { + // no xp,health if type 8 /critters/ + if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER) + { + pVictim->setDeathState(JUST_DIED); + pVictim->SetHealth(0); + + // allow loot only if has loot_id in creature_template + CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo(); + if(cInfo && cInfo->lootid) + pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + // some critters required for quests + if(GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID()); + + return damage; + } + + if(!pVictim->isInCombat() && ((Creature*)pVictim)->AI()) + ((Creature*)pVictim)->AI()->AttackStart(this); + } + + DEBUG_LOG("DealDamageStart"); + + uint32 health = pVictim->GetHealth(); + sLog.outDetail("deal dmg:%d to health:%d ",damage,health); + + // duel ends when player has 1 or less hp + bool duel_hasEnded = false; + if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->duel && damage >= (health-1)) + { + // prevent kill only if killed in duel and killed by opponent or opponent controlled creature + if(((Player*)pVictim)->duel->opponent==this || ((Player*)pVictim)->duel->opponent->GetGUID() == GetOwnerGUID()) + damage = health-1; + + duel_hasEnded = true; + } + //Get in CombatState + if(pVictim != this && damagetype != DOT) + { + SetInCombatWith(pVictim); + pVictim->SetInCombatWith(this); + + if(Player* attackedPlayer = pVictim->GetCharmerOrOwnerPlayerOrPlayerItself()) + SetContestedPvP(attackedPlayer); + } + + // Rage from Damage made (only from direct weapon damage) + if( cleanDamage && damagetype==DIRECT_DAMAGE && this != pVictim && GetTypeId() == TYPEID_PLAYER && (getPowerType() == POWER_RAGE)) + { + uint32 weaponSpeedHitFactor; + + switch(cleanDamage->attackType) + { + case BASE_ATTACK: + { + if(cleanDamage->hitOutCome == MELEE_HIT_CRIT) + weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 7); + else + weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f); + + ((Player*)this)->RewardRage(damage, weaponSpeedHitFactor, true); + + break; + } + case OFF_ATTACK: + { + if(cleanDamage->hitOutCome == MELEE_HIT_CRIT) + weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f); + else + weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 1.75f); + + ((Player*)this)->RewardRage(damage, weaponSpeedHitFactor, true); + + break; + } + case RANGED_ATTACK: + break; + } + } + + if(pVictim->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)pVictim)->InBattleGround()) + { + Player *killer = ((Player*)this); + if(killer != ((Player*)pVictim)) + if(BattleGround *bg = killer->GetBattleGround()) + bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage); + } + } + + if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->isPet() && !((Creature*)pVictim)->hasLootRecipient()) + ((Creature*)pVictim)->SetLootRecipient(this); + if (health <= damage) + { + // battleground things + if(pVictim->GetTypeId() == TYPEID_PLAYER && (((Player*)pVictim)->InBattleGround())) + { + Player *killed = ((Player*)pVictim); + Player *killer = NULL; + if(GetTypeId() == TYPEID_PLAYER) + killer = ((Player*)this); + else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) + { + Unit *owner = GetOwner(); + if(owner && owner->GetTypeId() == TYPEID_PLAYER) + killer = ((Player*)owner); + } + + if(killer) + if(BattleGround *bg = killed->GetBattleGround()) + bg->HandleKillPlayer(killed, killer); // drop flags and etc + } + + DEBUG_LOG("DealDamage: victim just died"); + + // find player: owner of controlled `this` or `this` itself maybe + Player *player = GetCharmerOrOwnerPlayerOrPlayerItself(); + + if(pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->GetLootRecipient()) + player = ((Creature*)pVictim)->GetLootRecipient(); + // Reward player, his pets, and group/raid members + // call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop) + if(player && player!=pVictim) + if(player->RewardPlayerAndGroupAtKill(pVictim)) + player->ProcDamageAndSpell(pVictim,PROC_FLAG_KILL_XP_GIVER,PROC_FLAG_NONE); + + DEBUG_LOG("DealDamageAttackStop"); + + // stop combat + pVictim->CombatStop(); + pVictim->getHostilRefManager().deleteReferences(); + + bool damageFromSpiritOfRedemtionTalent = spellProto && spellProto->Id == 27795; + + // if talent known but not triggered (check priest class for speedup check) + Aura* spiritOfRedemtionTalentReady = NULL; + if( !damageFromSpiritOfRedemtionTalent && // not called from SPELL_AURA_SPIRIT_OF_REDEMPTION + pVictim->GetTypeId()==TYPEID_PLAYER && pVictim->getClass()==CLASS_PRIEST ) + { + AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr) + { + if((*itr)->GetSpellProto()->SpellIconID==1654) + { + spiritOfRedemtionTalentReady = *itr; + break; + } + } + } + + DEBUG_LOG("SET JUST_DIED"); + if(!spiritOfRedemtionTalentReady) + pVictim->setDeathState(JUST_DIED); + + DEBUG_LOG("DealDamageHealth1"); + + if(spiritOfRedemtionTalentReady) + { + // save value before aura remove + uint32 ressSpellId = pVictim->GetUInt32Value(PLAYER_SELF_RES_SPELL); + if(!ressSpellId) + ressSpellId = ((Player*)pVictim)->GetResurrectionSpellId(); + + //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers) + pVictim->RemoveAllAurasOnDeath(); + + // restore for use at real death + pVictim->SetUInt32Value(PLAYER_SELF_RES_SPELL,ressSpellId); + + // FORM_SPIRITOFREDEMPTION and related auras + pVictim->CastSpell(pVictim,27827,true,NULL,spiritOfRedemtionTalentReady); + } + else + pVictim->SetHealth(0); + + // remember victim PvP death for corpse type and corpse reclaim delay + // at original death (not at SpiritOfRedemtionTalent timeout) + if( pVictim->GetTypeId()==TYPEID_PLAYER && !damageFromSpiritOfRedemtionTalent ) + ((Player*)pVictim)->SetPvPDeath(player!=NULL); + + // Call KilledUnit for creatures + if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) + ((Creature*)this)->AI()->KilledUnit(pVictim); + + // 10% durability loss on death + // clean InHateListOf + if (pVictim->GetTypeId() == TYPEID_PLAYER) + { + // only if not player and not controlled by player pet. And not at BG + if (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround()) + { + DEBUG_LOG("We are dead, loosing 10 percents durability"); + ((Player*)pVictim)->DurabilityLossAll(0.10f,false); + // durability lost message + WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); + ((Player*)pVictim)->GetSession()->SendPacket(&data); + } + } + else // creature died + { + DEBUG_LOG("DealDamageNotPlayer"); + Creature *cVictim = (Creature*)pVictim; + + if(!cVictim->isPet()) + { + cVictim->DeleteThreatList(); + cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + // Call creature just died function + if (cVictim->AI()) + cVictim->AI()->JustDied(this); + + // Dungeon specific stuff, only applies to players killing creatures + if(cVictim->GetInstanceId()) + { + Map *m = cVictim->GetMap(); + Player *creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself(); + // TODO: do instance binding anyway if the charmer/owner is offline + + if(m->IsDungeon() && creditedPlayer) + { + if(m->IsRaid() || m->IsHeroic()) + { + if(cVictim->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) + ((InstanceMap *)m)->PermBindAllPlayers(creditedPlayer); + } + else + { + // the reset time is set but not added to the scheduler + // until the players leave the instance + time_t resettime = cVictim->GetRespawnTimeEx() + 2 * HOUR; + if(InstanceSave *save = sInstanceSaveManager.GetInstanceSave(cVictim->GetInstanceId())) + if(save->GetResetTime() < resettime) save->SetResetTime(resettime); + } + } + } + } + + // last damage from non duel opponent or opponent controlled creature + if(duel_hasEnded) + { + assert(pVictim->GetTypeId()==TYPEID_PLAYER); + Player *he = (Player*)pVictim; + + assert(he->duel); + + he->duel->opponent->CombatStopWithPets(true); + he->CombatStopWithPets(true); + + he->DuelComplete(DUEL_INTERUPTED); + } + } + else // if (health <= damage) + { + DEBUG_LOG("DealDamageAlive"); + + pVictim->ModifyHealth(- (int32)damage); + + // Check if health is below 20% (apply damage before to prevent case when after ProcDamageAndSpell health < damage + if(pVictim->GetHealth()*5 < pVictim->GetMaxHealth()) + { + uint32 procVictim = PROC_FLAG_NONE; + + // if just dropped below 20% (for CheatDeath) + if((pVictim->GetHealth()+damage)*5 > pVictim->GetMaxHealth()) + procVictim = PROC_FLAG_LOW_HEALTH; + + ProcDamageAndSpell(pVictim,PROC_FLAG_TARGET_LOW_HEALTH,procVictim); + } + + if(damagetype != DOT) + { + if(getVictim()) + { + // if have target and damage pVictim just call AI recation + if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI()) + ((Creature*)pVictim)->AI()->AttackedBy(this); + } + else + { + // if not have main target then attack state with target (including AI call) + //start melee attacks only after melee hit + Attack(pVictim,(damagetype == DIRECT_DAMAGE)); + } + } + + // polymorphed and other negative transformed cases + if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED)) + pVictim->RemoveAurasDueToSpell(pVictim->getTransForm()); + + if(damagetype == DIRECT_DAMAGE|| damagetype == SPELL_DIRECT_DAMAGE) + pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE); + + if (pVictim->GetTypeId() != TYPEID_PLAYER) + { + if(spellProto && IsDamageToThreatSpell(spellProto)) + pVictim->AddThreat(this, damage*2, damageSchoolMask, spellProto); + else + pVictim->AddThreat(this, damage, damageSchoolMask, spellProto); + } + else // victim is a player + { + // Rage from damage received + if(this != pVictim && pVictim->getPowerType() == POWER_RAGE) + { + uint32 rage_damage = damage + (cleanDamage ? cleanDamage->damage : 0); + ((Player*)pVictim)->RewardRage(rage_damage, 0, false); + } + + // random durability for items (HIT TAKEN) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_DAMAGE))) + { + EquipmentSlots slot = EquipmentSlots(urand(0,EQUIPMENT_SLOT_END-1)); + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(slot); + } + } + + if(GetTypeId()==TYPEID_PLAYER) + { + // random durability for items (HIT DONE) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_DAMAGE))) + { + EquipmentSlots slot = EquipmentSlots(urand(0,EQUIPMENT_SLOT_END-1)); + ((Player*)this)->DurabilityPointLossForEquipSlot(slot); + } + } + + // TODO: Store auras by interrupt flag to speed this up. + AuraMap& vAuras = pVictim->GetAuras(); + for (AuraMap::iterator i = vAuras.begin(), next; i != vAuras.end(); i = next) + { + const SpellEntry *se = i->second->GetSpellProto(); + next = i; ++next; + if( se->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DAMAGE ) + { + bool remove = true; + if (se->procFlags & (1<<3)) + { + if (!roll_chance_i(se->procChance)) + remove = false; + } + if (remove) + { + pVictim->RemoveAurasDueToSpell(i->second->GetId()); + // FIXME: this may cause the auras with proc chance to be rerolled several times + next = vAuras.begin(); + } + } + } + + if (damagetype != NODAMAGE && damage && pVictim->GetTypeId() == TYPEID_PLAYER) + { + if( damagetype != DOT ) + { + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + { + // skip channeled spell (processed differently below) + if (i == CURRENT_CHANNELED_SPELL) + continue; + + if(Spell* spell = pVictim->m_currentSpells[i]) + if(spell->getState() == SPELL_STATE_PREPARING) + spell->Delayed(); + } + } + + if(Spell* spell = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]) + { + if (spell->getState() == SPELL_STATE_CASTING) + { + uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags; + if( channelInterruptFlags & CHANNEL_FLAG_DELAY ) + { + if(pVictim!=this) //don't shorten the duration of channeling if you damage yourself + spell->DelayedChannel(); + } + else if( (channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) ) + { + sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id); + pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL); + } + } + else if (spell->getState() == SPELL_STATE_DELAYED) + // break channeled spell in delayed state on damage + { + sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id); + pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL); + } + } + } + + // last damage from duel opponent + if(duel_hasEnded) + { + assert(pVictim->GetTypeId()==TYPEID_PLAYER); + Player *he = (Player*)pVictim; + + assert(he->duel); + + he->SetHealth(1); + + he->duel->opponent->CombatStopWithPets(true); + he->CombatStopWithPets(true); + + he->CastSpell(he, 7267, true); // beg + he->DuelComplete(DUEL_WON); + } + } + + DEBUG_LOG("DealDamageEnd returned %d damage", damage); + + return damage; +} + +void Unit::CastStop(uint32 except_spellid) +{ + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id!=except_spellid) + InterruptSpell(i,false); +} + +void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); + + if(!spellInfo) + { + sLog.outError("CastSpell: unknown spell id %i by caster: %s %u)", spellId,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + return; + } + + CastSpell(Victim,spellInfo,triggered,castItem,triggredByAura, originalCaster); +} + +void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster) +{ + if(!spellInfo) + { + sLog.outError("CastSpell: unknown spell by caster: %s %u)", (GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + return; + } + + if (castItem) + DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); + + if(!originalCaster && triggredByAura) + originalCaster = triggredByAura->GetCasterGUID(); + + Spell *spell = new Spell(this, spellInfo, triggered, originalCaster ); + + SpellCastTargets targets; + targets.setUnitTarget( Victim ); + spell->m_CastItem = castItem; + spell->prepare(&targets, triggredByAura); +} + +void Unit::CastCustomSpell(Unit* Victim,uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); + + if(!spellInfo) + { + sLog.outError("CastCustomSpell: unknown spell id %i\n", spellId); + return; + } + + CastCustomSpell(Victim,spellInfo,bp0,bp1,bp2,triggered,castItem,triggredByAura, originalCaster); +} + +void Unit::CastCustomSpell(Unit* Victim,SpellEntry const *spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster) +{ + if(!spellInfo) + { + sLog.outError("CastCustomSpell: unknown spell"); + return; + } + + if (castItem) + DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); + + if(!originalCaster && triggredByAura) + originalCaster = triggredByAura->GetCasterGUID(); + + Spell *spell = new Spell(this, spellInfo, triggered, originalCaster); + + if(bp0) + spell->m_currentBasePoints[0] = *bp0-int32(spellInfo->EffectBaseDice[0]); + + if(bp1) + spell->m_currentBasePoints[1] = *bp1-int32(spellInfo->EffectBaseDice[1]); + + if(bp2) + spell->m_currentBasePoints[2] = *bp2-int32(spellInfo->EffectBaseDice[2]); + + SpellCastTargets targets; + targets.setUnitTarget( Victim ); + spell->m_CastItem = castItem; + spell->prepare(&targets, triggredByAura); +} + +// used for scripting +void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); + + if(!spellInfo) + { + sLog.outError("CastSpell(x,y,z): unknown spell id %i by caster: %s %u)", spellId,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + return; + } + + CastSpell(x, y, z,spellInfo,triggered,castItem,triggredByAura, originalCaster); +} + +// used for scripting +void Unit::CastSpell(float x, float y, float z, SpellEntry const *spellInfo, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster) +{ + if(!spellInfo) + { + sLog.outError("CastSpell(x,y,z): unknown spell by caster: %s %u)", (GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + return; + } + + if (castItem) + DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); + + if(!originalCaster && triggredByAura) + originalCaster = triggredByAura->GetCasterGUID(); + + Spell *spell = new Spell(this, spellInfo, triggered, originalCaster ); + + SpellCastTargets targets; + targets.setDestination(x, y, z); + spell->m_CastItem = castItem; + spell->prepare(&targets, triggredByAura); +} + +void Unit::DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit, bool isTriggeredSpell) +{ + // TODO this in only generic way, check for exceptions + DEBUG_LOG("DealFlatDamage (BEFORE) >> DMG:%u", *damage); + + // Per-damage calss calculation + switch (spellInfo->DmgClass) + { + // Melee and Ranged Spells + case SPELL_DAMAGE_CLASS_RANGED: + case SPELL_DAMAGE_CLASS_MELEE: + { + // Calculate physical outcome + MeleeHitOutcome outcome = RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo); + + //Used to store the Hit Outcome + cleanDamage->hitOutCome = outcome; + + // Return miss/evade first (sends miss message) + switch(outcome) + { + case MELEE_HIT_EVADE: + { + SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_EVADES,0); + *damage = 0; + return; + } + case MELEE_HIT_MISS: + { + SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_NORMAL,0); + *damage = 0; + + if(GetTypeId()== TYPEID_PLAYER) + ((Player*)this)->UpdateWeaponSkill(BASE_ATTACK); + + CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,MELEE_HIT_MISS,spellInfo,isTriggeredSpell); + return; + } + } + + // Hitinfo, Victimstate + uint32 hitInfo = HITINFO_NORMALSWING; + VictimState victimState = VICTIMSTATE_NORMAL; + + // Physical Damage + if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL ) + { + uint32 modDamage=*damage; + + // apply spellmod to Done damage + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_DAMAGE, *damage); + + //Calculate armor mitigation + uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage); + + // random durability for main hand weapon (ABSORB) + if(damageAfterArmor < *damage) + if(pVictim->GetTypeId() == TYPEID_PLAYER) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK))); + + cleanDamage->damage += *damage - damageAfterArmor; + *damage = damageAfterArmor; + } + // Magical Damage + else + { + // Calculate damage bonus + *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE); + } + + // Classify outcome + switch (outcome) + { + case MELEE_HIT_BLOCK_CRIT: + case MELEE_HIT_CRIT: + { + uint32 bonusDmg = *damage; + + // Apply crit_damage bonus + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, bonusDmg); + + uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS); + for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + bonusDmg = uint32(bonusDmg * ((*i)->GetModifier()->m_amount+100.0f)/100.0f); + + *damage += bonusDmg; + + // Resilience - reduce crit damage + if (pVictim->GetTypeId()==TYPEID_PLAYER) + { + uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage); + cleanDamage->damage += resilienceReduction; + *damage -= resilienceReduction; + } + + *crit = true; + hitInfo |= HITINFO_CRITICALHIT; + + ModifyAuraState(AURA_STATE_CRIT, true); + StartReactiveTimer( REACTIVE_CRIT ); + + if(getClass()==CLASS_HUNTER) + { + ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true); + StartReactiveTimer( REACTIVE_HUNTER_CRIT ); + } + + if ( outcome == MELEE_HIT_BLOCK_CRIT ) + { + uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue()); + if (blocked_amount >= *damage) + { + hitInfo |= HITINFO_SWINGNOHITSOUND; + victimState = VICTIMSTATE_BLOCKS; + cleanDamage->damage += *damage; // To Help Calculate Rage + *damage = 0; + } + else + { + // To Help Calculate Rage + cleanDamage->damage += blocked_amount; + *damage = *damage - blocked_amount; + } + + pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + { + // Update defense + ((Player*)pVictim)->UpdateDefense(); + + // random durability for main hand weapon (BLOCK) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); + } + } + break; + } + case MELEE_HIT_PARRY: + { + cleanDamage->damage += *damage; // To Help Calculate Rage + *damage = 0; + victimState = VICTIMSTATE_PARRY; + + // Counter-attack ( explained in Unit::DoAttackDamage() ) + if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN) ) + { + // Get attack timers + float offtime = float(pVictim->getAttackTimer(OFF_ATTACK)); + float basetime = float(pVictim->getAttackTimer(BASE_ATTACK)); + + // Reduce attack time + if (pVictim->haveOffhandWeapon() && offtime < basetime) + { + float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20; + float percent60 = 3 * percent20; + if(offtime > percent20 && offtime <= percent60) + { + pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20)); + } + else if(offtime > percent60) + { + offtime -= 2 * percent20; + pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime)); + } + } + else + { + float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20; + float percent60 = 3 * percent20; + if(basetime > percent20 && basetime <= percent60) + { + pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20)); + } + else if(basetime > percent60) + { + basetime -= 2 * percent20; + pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime)); + } + } + } + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + { + // Update victim defense ? + ((Player*)pVictim)->UpdateDefense(); + + // random durability for main hand weapon (PARRY) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND); + } + + // Set parry flags + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); + + // Mongoose bite - set only Counterattack here + if (pVictim->getClass() == CLASS_HUNTER) + { + pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true); + pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY ); + } + else + { + pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + } + break; + } + case MELEE_HIT_DODGE: + { + if(pVictim->GetTypeId() == TYPEID_PLAYER) + ((Player*)pVictim)->UpdateDefense(); + + cleanDamage->damage += *damage; // To Help Calculate Rage + *damage = 0; + hitInfo |= HITINFO_SWINGNOHITSOUND; + victimState = VICTIMSTATE_DODGE; + + // Set dodge flags + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); + + // Overpower + if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) + { + ((Player*)this)->AddComboPoints(pVictim, 1); + StartReactiveTimer( REACTIVE_OVERPOWER ); + } + + // Riposte + if (pVictim->getClass() != CLASS_ROGUE) + { + pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + } + break; + } + case MELEE_HIT_BLOCK: + { + uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue()); + if (blocked_amount >= *damage) + { + hitInfo |= HITINFO_SWINGNOHITSOUND; + victimState = VICTIMSTATE_BLOCKS; + cleanDamage->damage += *damage; // To Help Calculate Rage + *damage = 0; + } + else + { + // To Help Calculate Rage + cleanDamage->damage += blocked_amount; + *damage = *damage - blocked_amount; + } + + pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + { + // Update defense + ((Player*)pVictim)->UpdateDefense(); + + // random durability for main hand weapon (BLOCK) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); + } + break; + } + case MELEE_HIT_EVADE: // already processed early + case MELEE_HIT_MISS: // already processed early + case MELEE_HIT_GLANCING: + case MELEE_HIT_CRUSHING: + case MELEE_HIT_NORMAL: + break; + } + + // do all damage=0 cases here + if(*damage == 0) + CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,outcome,spellInfo,isTriggeredSpell); + + break; + } + // Magical Attacks + case SPELL_DAMAGE_CLASS_NONE: + case SPELL_DAMAGE_CLASS_MAGIC: + { + // Calculate damage bonus + *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE); + + *crit = isSpellCrit(pVictim, spellInfo, GetSpellSchoolMask(spellInfo), BASE_ATTACK); + if (*crit) + { + *damage = SpellCriticalBonus(spellInfo, *damage, pVictim); + + // Resilience - reduce crit damage + if (pVictim && pVictim->GetTypeId()==TYPEID_PLAYER) + { + uint32 damage_reduction = ((Player *)pVictim)->GetSpellCritDamageReduction(*damage); + if(*damage > damage_reduction) + *damage -= damage_reduction; + else + *damage = 0; + } + + cleanDamage->hitOutCome = MELEE_HIT_CRIT; + } + // spell proc all magic damage==0 case in this function + if(*damage == 0) + { + // Procflags + uint32 procAttacker = PROC_FLAG_HIT_SPELL; + uint32 procVictim = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE); + + ProcDamageAndSpell(pVictim, procAttacker, procVictim, 0, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell); + } + + break; + } + } + + // TODO this in only generic way, check for exceptions + DEBUG_LOG("DealFlatDamage (AFTER) >> DMG:%u", *damage); +} + +uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage) +{ + if(!this || !pVictim) + return 0; + if(!this->isAlive() || !pVictim->isAlive()) + return 0; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); + if(!spellInfo) + return 0; + + CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL); + bool crit = false; + + if (useSpellDamage) + DealFlatDamage(pVictim, spellInfo, &damage, &cleanDamage, &crit, isTriggeredSpell); + + // If we actually dealt some damage (spell proc's for 0 damage (normal and magic) called in DealFlatDamage) + if(damage > 0) + { + // Calculate absorb & resists + uint32 absorb = 0; + uint32 resist = 0; + + CalcAbsorbResist(pVictim,GetSpellSchoolMask(spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); + + //No more damage left, target absorbed and/or resisted all damage + if (damage > absorb + resist) + damage -= absorb + resist; //Remove Absorbed and Resisted from damage actually dealt + else + { + uint32 HitInfo = HITINFO_SWINGNOHITSOUND; + + if (absorb) + HitInfo |= HITINFO_ABSORB; + if (resist) + { + HitInfo |= HITINFO_RESIST; + ProcDamageAndSpell(pVictim, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, GetSpellSchoolMask(spellInfo), spellInfo,isTriggeredSpell); + } + + //Send resist + SendAttackStateUpdate(HitInfo, pVictim, 1, GetSpellSchoolMask(spellInfo), damage, absorb,resist,VICTIMSTATE_NORMAL,0); + return 0; + } + + // Deal damage done + damage = DealDamage(pVictim, damage, &cleanDamage, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellInfo), spellInfo, true); + + // Send damage log + sLog.outDetail("SpellNonMeleeDamageLog: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u,absorb is %u,resist is %u", + GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, spellID, absorb,resist); + + // Actual log sent to client + SendSpellNonMeleeDamageLog(pVictim, spellID, damage, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit); + + // Procflags + uint32 procAttacker = PROC_FLAG_HIT_SPELL; + uint32 procVictim = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE); + + if (crit) + { + procAttacker |= PROC_FLAG_CRIT_SPELL; + procVictim |= PROC_FLAG_STRUCK_CRIT_SPELL; + } + + ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell); + + return damage; + } + else + { + // all spell proc for 0 normal and magic damage called in DealFlatDamage + + //Check for rage + if(cleanDamage.damage) + // Rage from damage received. + if(pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE)) + ((Player*)pVictim)->RewardRage(cleanDamage.damage, 0, false); + + return 0; + } +} + +void Unit::HandleEmoteCommand(uint32 anim_id) +{ + WorldPacket data( SMSG_EMOTE, 12 ); + data << anim_id << GetGUID(); + WPAssert(data.size() == 12); + + SendMessageToSet(&data, true); +} + +uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage) +{ + uint32 newdamage = 0; + float armor = pVictim->GetArmor(); + // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura + armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL); + + if (armor<0.0f) armor=0.0f; + + float tmpvalue = 0.0f; + if(getLevel() <= 59) //Level 1-59 + tmpvalue = armor / (armor + 400.0f + 85.0f * getLevel()); + else if(getLevel() < 70) //Level 60-69 + tmpvalue = armor / (armor - 22167.5f + 467.5f * getLevel()); + else //Level 70+ + tmpvalue = armor / (armor + 10557.5f); + + if(tmpvalue < 0.0f) + tmpvalue = 0.0f; + if(tmpvalue > 0.75f) + tmpvalue = 0.75f; + newdamage = uint32(damage - (damage * tmpvalue)); + + return (newdamage > 1) ? newdamage : 1; +} + +void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist) +{ + if(!pVictim || !pVictim->isAlive() || !damage) + return; + + // Magic damage, check for resists + if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL)==0) + { + // Get base victim resistance for school + float tmpvalue2 = (float)pVictim->GetResistance(GetFirstSchoolInMask(schoolMask)); + // Ignore resistance by self SPELL_AURA_MOD_TARGET_RESISTANCE aura + tmpvalue2 += (float)GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask); + + tmpvalue2 *= (float)(0.15f / getLevel()); + if (tmpvalue2 < 0.0f) + tmpvalue2 = 0.0f; + if (tmpvalue2 > 0.75f) + tmpvalue2 = 0.75f; + uint32 ran = urand(0, 100); + uint32 faq[4] = {24,6,4,6}; + uint8 m = 0; + float Binom = 0.0f; + for (uint8 i = 0; i < 4; i++) + { + Binom += 2400 *( powf(tmpvalue2, i) * powf( (1-tmpvalue2), (4-i)))/faq[i]; + if (ran > Binom ) + ++m; + else + break; + } + if (damagetype == DOT && m == 4) + *resist += uint32(damage - 1); + else + *resist += uint32(damage * m / 4); + if(*resist > damage) + *resist = damage; + } + else + *resist = 0; + + int32 RemainingDamage = damage - *resist; + + // absorb without mana cost + int32 reflectDamage = 0; + Aura* reflectAura = NULL; + AuraList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB); + for(AuraList::const_iterator i = vSchoolAbsorb.begin(), next; i != vSchoolAbsorb.end() && RemainingDamage > 0; i = next) + { + next = i; ++next; + + if (((*i)->GetModifier()->m_miscvalue & schoolMask)==0) + continue; + + // Cheat Death + if((*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && (*i)->GetSpellProto()->SpellIconID == 2109) + { + if (((Player*)pVictim)->HasSpellCooldown(31231)) + continue; + if (pVictim->GetHealth() <= RemainingDamage) + { + int32 chance = (*i)->GetModifier()->m_amount; + if (roll_chance_i(chance)) + { + pVictim->CastSpell(pVictim,31231,true); + ((Player*)pVictim)->AddSpellCooldown(31231,0,time(NULL)+60); + + // with health > 10% lost health until health==10%, in other case no losses + uint32 health10 = pVictim->GetMaxHealth()/10; + RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0; + } + } + continue; + } + + int32 currentAbsorb; + + //Reflective Shield + if ((pVictim != this) && (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && (*i)->GetSpellProto()->SpellFamilyFlags == 0x1) + { + if(Unit* caster = (*i)->GetCaster()) + { + AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k) + { + switch((*k)->GetModifier()->m_miscvalue) + { + case 5065: // Rank 1 + case 5064: // Rank 2 + case 5063: // Rank 3 + case 5062: // Rank 4 + case 5061: // Rank 5 + { + if(RemainingDamage >= (*i)->GetModifier()->m_amount) + reflectDamage = (*i)->GetModifier()->m_amount * (*k)->GetModifier()->m_amount/100; + else + reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100; + reflectAura = *i; + + } break; + default: break; + } + + if(reflectDamage) + break; + } + } + } + + if (RemainingDamage >= (*i)->GetModifier()->m_amount) + { + currentAbsorb = (*i)->GetModifier()->m_amount; + pVictim->RemoveAurasDueToSpell((*i)->GetId()); + next = vSchoolAbsorb.begin(); + } + else + { + currentAbsorb = RemainingDamage; + (*i)->GetModifier()->m_amount -= RemainingDamage; + } + + RemainingDamage -= currentAbsorb; + } + // do not cast spells while looping auras; auras can get invalid otherwise + if (reflectDamage) + pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, reflectAura); + + // absorb by mana cost + AuraList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD); + for(AuraList::const_iterator i = vManaShield.begin(), next; i != vManaShield.end() && RemainingDamage > 0; i = next) + { + next = i; ++next; + + // check damage school mask + if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0) + continue; + + int32 currentAbsorb; + if (RemainingDamage >= (*i)->GetModifier()->m_amount) + currentAbsorb = (*i)->GetModifier()->m_amount; + else + currentAbsorb = RemainingDamage; + + float manaMultiplier = (*i)->GetSpellProto()->EffectMultipleValue[(*i)->GetEffIndex()]; + if(Player *modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod((*i)->GetId(), SPELLMOD_MULTIPLE_VALUE, manaMultiplier); + + int32 maxAbsorb = int32(pVictim->GetPower(POWER_MANA) / manaMultiplier); + if (currentAbsorb > maxAbsorb) + currentAbsorb = maxAbsorb; + + (*i)->GetModifier()->m_amount -= currentAbsorb; + if((*i)->GetModifier()->m_amount <= 0) + { + pVictim->RemoveAurasDueToSpell((*i)->GetId()); + next = vManaShield.begin(); + } + + int32 manaReduction = int32(currentAbsorb * manaMultiplier); + pVictim->ApplyPowerMod(POWER_MANA, manaReduction, false); + + RemainingDamage -= currentAbsorb; + } + + AuraList const& vSplitDamageFlat = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_FLAT); + for(AuraList::const_iterator i = vSplitDamageFlat.begin(), next; i != vSplitDamageFlat.end() && RemainingDamage >= 0; i = next) + { + next = i; ++next; + + // check damage school mask + if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0) + continue; + + // Damage can be splitted only if aura has an alive caster + Unit *caster = (*i)->GetCaster(); + if(!caster || caster == pVictim || !caster->IsInWorld() || !caster->isAlive()) + continue; + + int32 currentAbsorb; + if (RemainingDamage >= (*i)->GetModifier()->m_amount) + currentAbsorb = (*i)->GetModifier()->m_amount; + else + currentAbsorb = RemainingDamage; + + RemainingDamage -= currentAbsorb; + + SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, currentAbsorb, schoolMask, 0, 0, false, 0, false); + + CleanDamage cleanDamage = CleanDamage(currentAbsorb, BASE_ATTACK, MELEE_HIT_NORMAL); + DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false); + } + + AuraList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT); + for(AuraList::const_iterator i = vSplitDamagePct.begin(), next; i != vSplitDamagePct.end() && RemainingDamage >= 0; i = next) + { + next = i; ++next; + + // check damage school mask + if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0) + continue; + + // Damage can be splitted only if aura has an alive caster + Unit *caster = (*i)->GetCaster(); + if(!caster || caster == pVictim || !caster->IsInWorld() || !caster->isAlive()) + continue; + + int32 splitted = int32(RemainingDamage * (*i)->GetModifier()->m_amount / 100.0f); + + RemainingDamage -= splitted; + + SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, 0, 0, false, 0, false); + + CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL); + DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false); + } + + *absorb = damage - RemainingDamage - *resist; +} + +void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell) +{ + MeleeHitOutcome outcome; + + // If is casted Melee spell, calculate like physical + if(!spellCasted) + outcome = RollMeleeOutcomeAgainst (pVictim, attType); + else + outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted); + + if(outcome == MELEE_HIT_MISS ||outcome == MELEE_HIT_DODGE ||outcome == MELEE_HIT_BLOCK ||outcome == MELEE_HIT_PARRY) + pVictim->AddThreat(this, 0.0f); + switch(outcome) + { + case MELEE_HIT_EVADE: + { + *hitInfo |= HITINFO_MISS; + *damage = 0; + cleanDamage->damage = 0; + return; + } + case MELEE_HIT_MISS: + { + *hitInfo |= HITINFO_MISS; + *damage = 0; + cleanDamage->damage = 0; + if(GetTypeId()== TYPEID_PLAYER) + ((Player*)this)->UpdateWeaponSkill(attType); + return; + } + } + + /// If this is a creature and it attacks from behind it has a probability to daze it's victim + if( (outcome==MELEE_HIT_CRIT || outcome==MELEE_HIT_CRUSHING || outcome==MELEE_HIT_NORMAL || outcome==MELEE_HIT_GLANCING) && + GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this) ) + { + // -probability is between 0% and 40% + // 20% base chance + float Probability = 20; + + //there is a newbie protection, at level 10 just 7% base chance; assuming linear function + if( pVictim->getLevel() < 30 ) + Probability = 0.65f*pVictim->getLevel()+0.5; + + uint32 VictimDefense=pVictim->GetDefenseSkillValue(this); + uint32 AttackerMeleeSkill=GetUnitMeleeSkill(pVictim); + + Probability *= AttackerMeleeSkill/(float)VictimDefense; + + if(Probability > 40.0f) + Probability = 40.0f; + + if(roll_chance_f(Probability)) + CastSpell(pVictim, 1604, true); + } + + //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL + if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) + { + uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage); + + // random durability for main hand weapon (ABSORB) + if(damageAfterArmor < *damage) + if(pVictim->GetTypeId() == TYPEID_PLAYER) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK))); + + cleanDamage->damage += *damage - damageAfterArmor; + *damage = damageAfterArmor; + } + + if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER ) + ((Player*)this)->UpdateCombatSkills(pVictim, attType, outcome, false); + + if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) + ((Player*)pVictim)->UpdateCombatSkills(this, attType, outcome, true); + + switch (outcome) + { + case MELEE_HIT_BLOCK_CRIT: + case MELEE_HIT_CRIT: + { + //*hitInfo = 0xEA; + // 0xEA + *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8; + + // Crit bonus calc + uint32 crit_bonus; + crit_bonus = *damage; + + // Apply crit_damage bonus for melee spells + if (spellCasted) + { + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); + + uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS); + for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + crit_bonus = uint32(crit_bonus * ((*i)->GetModifier()->m_amount+100.0f)/100.0f); + } + + *damage += crit_bonus; + + uint32 resilienceReduction = 0; + + if(attType == RANGED_ATTACK) + { + int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); + *damage = int32((*damage) * float((100.0f + mod)/100.0f)); + // Resilience - reduce crit damage + if (pVictim->GetTypeId()==TYPEID_PLAYER) + resilienceReduction = ((Player*)pVictim)->GetRangedCritDamageReduction(*damage); + } + else + { + int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE); + mod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE); + *damage = int32((*damage) * float((100.0f + mod)/100.0f)); + // Resilience - reduce crit damage + if (pVictim->GetTypeId()==TYPEID_PLAYER) + resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage); + } + + *damage -= resilienceReduction; + cleanDamage->damage += resilienceReduction; + + if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER ) + ((Player*)this)->UpdateWeaponSkill(attType); + + ModifyAuraState(AURA_STATE_CRIT, true); + StartReactiveTimer( REACTIVE_CRIT ); + + if(getClass()==CLASS_HUNTER) + { + ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true); + StartReactiveTimer( REACTIVE_HUNTER_CRIT ); + } + + if ( outcome == MELEE_HIT_BLOCK_CRIT ) + { + *blocked_amount = pVictim->GetShieldBlockValue(); + + if (pVictim->GetUnitBlockChance()) + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD); + else + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); + + //Only set VICTIMSTATE_BLOCK on a full block + if (*blocked_amount >= uint32(*damage)) + { + *victimState = VICTIMSTATE_BLOCKS; + *blocked_amount = uint32(*damage); + } + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + { + // Update defense + ((Player*)pVictim)->UpdateDefense(); + + // random durability for main hand weapon (BLOCK) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); + } + + pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + break; + } + + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL); + break; + } + case MELEE_HIT_PARRY: + { + if(attType == RANGED_ATTACK) //range attack - no parry + { + outcome = MELEE_HIT_NORMAL; + break; + } + + cleanDamage->damage += *damage; + *damage = 0; + *victimState = VICTIMSTATE_PARRY; + + // instant (maybe with small delay) counter attack + { + float offtime = float(pVictim->getAttackTimer(OFF_ATTACK)); + float basetime = float(pVictim->getAttackTimer(BASE_ATTACK)); + + // after parry nearest next attack time will reduced at %40 from full attack time. + // The delay cannot be reduced to less than 20% of your weapon base swing delay. + if (pVictim->haveOffhandWeapon() && offtime < basetime) + { + float percent20 = pVictim->GetAttackTime(OFF_ATTACK)*0.20; + float percent60 = 3*percent20; + // set to 20% if in range 20%...20+40% of full time + if(offtime > percent20 && offtime <= percent60) + { + pVictim->setAttackTimer(OFF_ATTACK,uint32(percent20)); + } + // decrease at %40 from full time + else if(offtime > percent60) + { + offtime -= 2*percent20; + pVictim->setAttackTimer(OFF_ATTACK,uint32(offtime)); + } + // ELSE not changed + } + else + { + float percent20 = pVictim->GetAttackTime(BASE_ATTACK)*0.20; + float percent60 = 3*percent20; + // set to 20% if in range 20%...20+40% of full time + if(basetime > percent20 && basetime <= percent60) + { + pVictim->setAttackTimer(BASE_ATTACK,uint32(percent20)); + } + // decrease at %40 from full time + else if(basetime > percent60) + { + basetime -= 2*percent20; + pVictim->setAttackTimer(BASE_ATTACK,uint32(basetime)); + } + // ELSE not changed + } + } + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + { + // Update victim defense ? + ((Player*)pVictim)->UpdateDefense(); + + // random durability for main hand weapon (PARRY) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND); + } + + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); + + if (pVictim->getClass() == CLASS_HUNTER) + { + pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true); + pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY ); + } + else + { + pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + } + + CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); + return; + } + case MELEE_HIT_DODGE: + { + if(attType == RANGED_ATTACK) //range attack - no dodge + { + outcome = MELEE_HIT_NORMAL; + break; + } + + cleanDamage->damage += *damage; + *damage = 0; + *victimState = VICTIMSTATE_DODGE; + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + ((Player*)pVictim)->UpdateDefense(); + + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); + + if (pVictim->getClass() != CLASS_ROGUE) // Riposte + { + pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + } + + // Overpower + if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) + { + ((Player*)this)->AddComboPoints(pVictim, 1); + StartReactiveTimer( REACTIVE_OVERPOWER ); + } + + CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); + return; + } + case MELEE_HIT_BLOCK: + { + *blocked_amount = pVictim->GetShieldBlockValue(); + + if (pVictim->GetUnitBlockChance()) + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD); + else + pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); + + //Only set VICTIMSTATE_BLOCK on a full block + if (*blocked_amount >= uint32(*damage)) + { + *victimState = VICTIMSTATE_BLOCKS; + *blocked_amount = uint32(*damage); + } + + if(pVictim->GetTypeId() == TYPEID_PLAYER) + { + // Update defense + ((Player*)pVictim)->UpdateDefense(); + + // random durability for main hand weapon (BLOCK) + if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) + ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); + } + + pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true); + pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); + + break; + } + case MELEE_HIT_GLANCING: + { + float reducePercent = 1.0f; //damage factor + + // calculate base values and mods + float baseLowEnd = 1.3; + float baseHighEnd = 1.2; + switch(getClass()) // lowering base values for casters + { + case CLASS_SHAMAN: + case CLASS_PRIEST: + case CLASS_MAGE: + case CLASS_WARLOCK: + case CLASS_DRUID: + baseLowEnd -= 0.7; + baseHighEnd -= 0.3; + break; + } + + float maxLowEnd = 0.6; + switch(getClass()) // upper for melee classes + { + case CLASS_WARRIOR: + case CLASS_ROGUE: + maxLowEnd = 0.91; //If the attacker is a melee class then instead the lower value of 0.91 + } + + // calculate values + int32 diff = int32(pVictim->GetDefenseSkillValue(this)) - int32(GetWeaponSkillValue(attType,pVictim)); + float lowEnd = baseLowEnd - ( 0.05f * diff ); + float highEnd = baseHighEnd - ( 0.03f * diff ); + + // apply max/min bounds + if ( lowEnd < 0.01f ) //the low end must not go bellow 0.01f + lowEnd = 0.01f; + else if ( lowEnd > maxLowEnd ) //the smaller value of this and 0.6 is kept as the low end + lowEnd = maxLowEnd; + + if ( highEnd < 0.2f ) //high end limits + highEnd = 0.2f; + if ( highEnd > 0.99f ) + highEnd = 0.99f; + + if(lowEnd > highEnd) // prevent negative range size + lowEnd = highEnd; + + reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd ); + + *damage = uint32(reducePercent * *damage); + cleanDamage->damage += *damage; + *hitInfo |= HITINFO_GLANCING; + break; + } + case MELEE_HIT_CRUSHING: + { + // 150% normal damage + *damage += (*damage / 2); + cleanDamage->damage = *damage; + *hitInfo |= HITINFO_CRUSHING; + // TODO: victimState, victim animation? + break; + } + default: + break; + } + + // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block + if(*victimState != VICTIMSTATE_BLOCKS) + { + MeleeDamageBonus(pVictim, damage,attType,spellCasted); + CalcAbsorbResist(pVictim, damageSchoolMask, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage); + } + + if (*absorbDamage) *hitInfo |= HITINFO_ABSORB; + if (*resistDamage) *hitInfo |= HITINFO_RESIST; + + cleanDamage->damage += *blocked_amount; + + if (*damage <= *absorbDamage + *resistDamage + *blocked_amount) + { + //*hitInfo = 0x00010020; + //*hitInfo |= HITINFO_SWINGNOHITSOUND; + //*damageType = 0; + CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); + return; + } + + // update at damage Judgement aura duration that applied by attacker at victim + if(*damage) + { + AuraMap const& vAuras = pVictim->GetAuras(); + for(AuraMap::const_iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr) + { + SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); + if( (spellInfo->AttributesEx3 & 0x40000) && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && + ((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) ) + { + (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); + (*itr).second->UpdateAuraDuration(); + } + } + } + + CastMeleeProcDamageAndSpell(pVictim, (*damage - *absorbDamage - *resistDamage - *blocked_amount), damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); + + // victim's damage shield + // yet another hack to fix crashes related to the aura getting removed during iteration + std::set alreadyDone; + uint32 removedAuras = pVictim->m_removedAuras; + AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD); + for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next) + { + ++next; + if (alreadyDone.find(*i) == alreadyDone.end()) + { + alreadyDone.insert(*i); + pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifier()->m_amount, false, false); + if (pVictim->m_removedAuras > removedAuras) + { + removedAuras = pVictim->m_removedAuras; + next = vDamageShields.begin(); + } + } + } +} + +void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra ) +{ + if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) ) + return; + + if (!pVictim->isAlive()) + return; + + if(IsNonMeleeSpellCasted(false)) + return; + + uint32 hitInfo; + if (attType == BASE_ATTACK) + hitInfo = HITINFO_NORMALSWING2; + else if (attType == OFF_ATTACK) + hitInfo = HITINFO_LEFTSWING; + else + return; // ignore ranaged case + + uint32 extraAttacks = m_extraAttacks; + + // melee attack spell casted at main hand attack only + if (attType == BASE_ATTACK && m_currentSpells[CURRENT_MELEE_SPELL]) + { + m_currentSpells[CURRENT_MELEE_SPELL]->cast(); + + // not recent extra attack only at any non extra attack (melee spell case) + if(!extra && extraAttacks) + { + while(m_extraAttacks) + { + AttackerStateUpdate(pVictim, BASE_ATTACK, true); + if(m_extraAttacks > 0) + --m_extraAttacks; + } + } + + return; + } + + VictimState victimState = VICTIMSTATE_NORMAL; + + CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); + uint32 blocked_dmg = 0; + uint32 absorbed_dmg = 0; + uint32 resisted_dmg = 0; + + SpellSchoolMask meleeSchoolMask = GetMeleeDamageSchoolMask(); + + if(pVictim->IsImmunedToDamage(meleeSchoolMask,true)) // use charges + { + SendAttackStateUpdate (HITINFO_NORMALSWING, pVictim, 1, meleeSchoolMask, 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0); + + // not recent extra attack only at any non extra attack (miss case) + if(!extra && extraAttacks) + { + while(m_extraAttacks) + { + AttackerStateUpdate(pVictim, BASE_ATTACK, true); + if(m_extraAttacks > 0) + --m_extraAttacks; + } + } + + return; + } + + uint32 damage = CalculateDamage (attType, false); + + DoAttackDamage (pVictim, &damage, &cleanDamage, &blocked_dmg, meleeSchoolMask, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType); + + if (hitInfo & HITINFO_MISS) + //send miss + SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchoolMask, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg); + else + { + //do animation + SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchoolMask, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg); + + if (damage > (absorbed_dmg + resisted_dmg + blocked_dmg)) + damage -= (absorbed_dmg + resisted_dmg + blocked_dmg); + else + damage = 0; + + DealDamage (pVictim, damage, &cleanDamage, DIRECT_DAMAGE, meleeSchoolMask, NULL, true); + + if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive()) + { + for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i),pVictim,attType); + } + } + + if (GetTypeId() == TYPEID_PLAYER) + DEBUG_LOG("AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", + GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, absorbed_dmg, blocked_dmg, resisted_dmg); + else + DEBUG_LOG("AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", + GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, absorbed_dmg, blocked_dmg, resisted_dmg); + + // extra attack only at any non extra attack (normal case) + if(!extra && extraAttacks) + { + while(m_extraAttacks) + { + AttackerStateUpdate(pVictim, BASE_ATTACK, true); + if(m_extraAttacks > 0) + --m_extraAttacks; + } + } +} + +MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo) +{ + // Miss chance based on melee + float miss_chance = MeleeMissChanceCalc(pVictim, attType); + + // Critical hit chance + float crit_chance = GetUnitCriticalChance(attType, pVictim); + // this is to avoid compiler issue when declaring variables inside if + float block_chance, parry_chance, dodge_chance; + + // cannot be dodged/parried/blocked + if(spellInfo->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK) + { + block_chance = 0.0f; + parry_chance = 0.0f; + dodge_chance = 0.0f; + } + else + { + // parry can be avoided only by some abilites + parry_chance = pVictim->GetUnitParryChance(); + // block might be bypassed by it as well + block_chance = pVictim->GetUnitBlockChance(); + // stunned target cannot dodge and this is check in GetUnitDodgeChance() + dodge_chance = pVictim->GetUnitDodgeChance(); + } + + // Only players can have Talent&Spell bonuses + if (GetTypeId() == TYPEID_PLAYER) + { + // Increase from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL aura + crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, spellInfo->SchoolMask); + + if( dodge_chance != 0.0f ) // if dodge chance is already 0, ignore talents fpr speed + { + AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); + for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i) + { + // can't be dodged rogue finishing move + if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE) + { + if(spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE)) + { + dodge_chance = 0.0f; + break; + } + } + } + } + } + + // Spellmods + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance); + + DEBUG_LOG("PHYSICAL OUTCOME: miss %f crit %f dodge %f parry %f block %f",miss_chance,crit_chance,dodge_chance,parry_chance, block_chance); + + return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100),int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), true); +} + +MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const +{ + // This is only wrapper + + // Miss chance based on melee + float miss_chance = MeleeMissChanceCalc(pVictim, attType); + + // Critical hit chance + float crit_chance = GetUnitCriticalChance(attType, pVictim); + + // stunned target cannot dodge and this is check in GetUnitDodgeChance() (returned 0 in this case) + float dodge_chance = pVictim->GetUnitDodgeChance(); + float block_chance = pVictim->GetUnitBlockChance(); + float parry_chance = pVictim->GetUnitParryChance(); + + // Useful if want to specify crit & miss chances for melee, else it could be removed + DEBUG_LOG("MELEE OUTCOME: miss %f crit %f dodge %f parry %f block %f", miss_chance,crit_chance,dodge_chance,parry_chance,block_chance); + + return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100), int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), false); +} + +MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const +{ + if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode()) + return MELEE_HIT_EVADE; + + int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(pVictim); + int32 victimMaxSkillValueForLevel = pVictim->GetMaxSkillValueForLevel(this); + + int32 attackerWeaponSkill = GetWeaponSkillValue(attType,pVictim); + int32 victimDefenseSkill = pVictim->GetDefenseSkillValue(this); + + // bonus from skills is 0.04% + int32 skillBonus = 4 * ( attackerWeaponSkill - victimMaxSkillValueForLevel ); + int32 skillBonus2 = 4 * ( attackerMaxSkillValueForLevel - victimDefenseSkill ); + int32 sum = 0, tmp = 0; + int32 roll = urand (0, 10000); + + DEBUG_LOG ("RollMeleeOutcomeAgainst: skill bonus of %d for attacker", skillBonus); + DEBUG_LOG ("RollMeleeOutcomeAgainst: rolled %d, miss %d, dodge %d, parry %d, block %d, crit %d", + roll, miss_chance, dodge_chance, parry_chance, block_chance, crit_chance); + + tmp = miss_chance; + + if (tmp > 0 && roll < (sum += tmp )) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: MISS"); + return MELEE_HIT_MISS; + } + + // always crit against a sitting target (except 0 crit chance) + if( pVictim->GetTypeId() == TYPEID_PLAYER && crit_chance > 0 && !pVictim->IsStandState() ) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: CRIT (sitting victim)"); + return MELEE_HIT_CRIT; + } + + // Dodge chance + + // only players can't dodge if attacker is behind + if (pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->HasInArc(M_PI,this)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: attack came from behind and victim was a player."); + } + else + { + // Reduce dodge chance by attacker expertise rating + if (GetTypeId() == TYPEID_PLAYER) + dodge_chance -= int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType)*100); + + // Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE + dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE); + + tmp = dodge_chance; + if ( (tmp > 0) // check if unit _can_ dodge + && ((tmp -= skillBonus) > 0) + && roll < (sum += tmp)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: DODGE <%d, %d)", sum-tmp, sum); + return MELEE_HIT_DODGE; + } + } + + // parry & block chances + + // check if attack comes from behind, nobody can parry or block if attacker is behind + if (!pVictim->HasInArc(M_PI,this)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: attack came from behind."); + } + else + { + // Reduce parry chance by attacker expertise rating + if (GetTypeId() == TYPEID_PLAYER) + parry_chance-= int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType)*100); + + if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY) ) + { + int32 tmp = int32(parry_chance); + if ( (tmp > 0) // check if unit _can_ parry + && ((tmp -= skillBonus) > 0) + && (roll < (sum += tmp))) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: PARRY <%d, %d)", sum-tmp, sum); + return MELEE_HIT_PARRY; + } + } + + if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK) ) + { + tmp = block_chance; + if ( (tmp > 0) // check if unit _can_ block + && ((tmp -= skillBonus) > 0) + && (roll < (sum += tmp))) + { + // Critical chance + tmp = crit_chance + skillBonus2; + if ( GetTypeId() == TYPEID_PLAYER && SpellCasted && tmp > 0 ) + { + if ( roll_chance_i(tmp/100)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCKED CRIT"); + return MELEE_HIT_BLOCK_CRIT; + } + } + DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCK <%d, %d)", sum-tmp, sum); + return MELEE_HIT_BLOCK; + } + } + } + + // Critical chance + tmp = crit_chance + skillBonus2; + + if (tmp > 0 && roll < (sum += tmp)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: CRIT <%d, %d)", sum-tmp, sum); + return MELEE_HIT_CRIT; + } + + // Max 40% chance to score a glancing blow against mobs that are higher level (can do only players and pets and not with ranged weapon) + if( attType != RANGED_ATTACK && !SpellCasted && + (GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet()) && + pVictim->GetTypeId() != TYPEID_PLAYER && !((Creature*)pVictim)->isPet() && + getLevel() < pVictim->getLevelForTarget(this) ) + { + // cap possible value (with bonuses > max skill) + int32 skill = attackerWeaponSkill; + int32 maxskill = attackerMaxSkillValueForLevel; + skill = (skill > maxskill) ? maxskill : skill; + + tmp = (10 + (victimDefenseSkill - skill)) * 100; + tmp = tmp > 4000 ? 4000 : tmp; + if (roll < (sum += tmp)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: GLANCING <%d, %d)", sum-4000, sum); + return MELEE_HIT_GLANCING; + } + } + + if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() ) + { + // mobs can score crushing blows if they're 3 or more levels above victim + // or when their weapon skill is 15 or more above victim's defense skill + tmp = victimDefenseSkill; + int32 tmpmax = victimMaxSkillValueForLevel; + // having defense above your maximum (from items, talents etc.) has no effect + tmp = tmp > tmpmax ? tmpmax : tmp; + // tmp = mob's level * 5 - player's current defense skill + tmp = attackerMaxSkillValueForLevel - tmp; + if(tmp >= 15) + { + // add 2% chance per lacking skill point, min. is 15% + tmp = tmp * 200 - 1500; + if (roll < (sum += tmp)) + { + DEBUG_LOG ("RollMeleeOutcomeAgainst: CRUSHING <%d, %d)", sum-tmp, sum); + return MELEE_HIT_CRUSHING; + } + } + } + + DEBUG_LOG ("RollMeleeOutcomeAgainst: NORMAL"); + return MELEE_HIT_NORMAL; +} + +uint32 Unit::CalculateDamage (WeaponAttackType attType, bool normalized) +{ + float min_damage, max_damage; + + if (normalized && GetTypeId()==TYPEID_PLAYER) + ((Player*)this)->CalculateMinMaxDamage(attType,normalized,min_damage, max_damage); + else + { + switch (attType) + { + case RANGED_ATTACK: + min_damage = GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); + max_damage = GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); + break; + case BASE_ATTACK: + min_damage = GetFloatValue(UNIT_FIELD_MINDAMAGE); + max_damage = GetFloatValue(UNIT_FIELD_MAXDAMAGE); + break; + case OFF_ATTACK: + min_damage = GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); + max_damage = GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); + break; + // Just for good manner + default: + min_damage = 0.0f; + max_damage = 0.0f; + break; + } + } + + if (min_damage > max_damage) + { + std::swap(min_damage,max_damage); + } + + if(max_damage == 0.0f) + max_damage = 5.0f; + + return urand((uint32)min_damage, (uint32)max_damage); +} + +float Unit::CalculateLevelPenalty(SpellEntry const* spellProto) const +{ + if(spellProto->spellLevel <= 0) + return 1.0f; + + float LvlPenalty = 0.0f; + + if(spellProto->spellLevel < 20) + LvlPenalty = 20.0f - spellProto->spellLevel * 3.75f; + float LvlFactor = (float(spellProto->spellLevel) + 6.0f) / float(getLevel()); + if(LvlFactor > 1.0f) + LvlFactor = 1.0f; + + return (100.0f - LvlPenalty) * LvlFactor / 100.0f; +} + +void Unit::SendAttackStart(Unit* pVictim) +{ + WorldPacket data( SMSG_ATTACKSTART, 16 ); + data << GetGUID(); + data << pVictim->GetGUID(); + + SendMessageToSet(&data, true); + DEBUG_LOG( "WORLD: Sent SMSG_ATTACKSTART" ); +} + +void Unit::SendAttackStop(Unit* victim) +{ + if(!victim) + return; + + WorldPacket data( SMSG_ATTACKSTOP, (4+16) ); // we guess size + data.append(GetPackGUID()); + data.append(victim->GetPackGUID()); // can be 0x00... + data << uint32(0); // can be 0x1 + SendMessageToSet(&data, true); + sLog.outDetail("%s %u stopped attacking %s %u", (GetTypeId()==TYPEID_PLAYER ? "player" : "creature"), GetGUIDLow(), (victim->GetTypeId()==TYPEID_PLAYER ? "player" : "creature"),victim->GetGUIDLow()); + + /*if(victim->GetTypeId() == TYPEID_UNIT) + ((Creature*)victim)->AI().EnterEvadeMode(this);*/ +} + +/* +// Melee based spells can be miss, parry or dodge on this step +// Crit or block - determined on damage calculation phase! (and can be both in some time) +float Unit::MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell) +{ + // Calculate hit chance (more correct for chance mod) + int32 HitChance; + + // PvP - PvE melee chances + int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7; + int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim); + if(leveldif < 3) + HitChance = 95 - leveldif; + else + HitChance = 93 - (leveldif - 2) * lchance; + + // Hit chance depends from victim auras + if(attType == RANGED_ATTACK) + HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE); + else + HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE); + + // Spellmod from SPELLMOD_RESIST_MISS_CHANCE + if(Player *modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, HitChance); + + // Miss = 100 - hit + float miss_chance= 100.0f - HitChance; + + // Bonuses from attacker aura and ratings + if (attType == RANGED_ATTACK) + miss_chance -= m_modRangedHitChance; + else + miss_chance -= m_modMeleeHitChance; + + // bonus from skills is 0.04% + miss_chance -= skillDiff * 0.04f; + + // Limit miss chance from 0 to 60% + if (miss_chance < 0.0f) + return 0.0f; + if (miss_chance > 60.0f) + return 60.0f; + return miss_chance; +} + +// Melee based spells hit result calculations +SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) +{ + WeaponAttackType attType = BASE_ATTACK; + + if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) + attType = RANGED_ATTACK; + + // bonus from skills is 0.04% per skill Diff + int32 attackerWeaponSkill = int32(GetWeaponSkillValue(attType,pVictim)); + int32 skillDiff = attackerWeaponSkill - int32(pVictim->GetMaxSkillValueForLevel(this)); + int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this)); + + uint32 roll = urand (0, 10000); + uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell)*100.0f); + + // Roll miss + uint32 tmp = missChance; + if (roll < tmp) + return SPELL_MISS_MISS; + + // Same spells cannot be parry/dodge + if (spell->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK) + return SPELL_MISS_NONE; + + // Ranged attack can`t miss too + if (attType == RANGED_ATTACK) + return SPELL_MISS_NONE; + + bool attackFromBehind = !pVictim->HasInArc(M_PI,this); + + // Roll dodge + int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4; + // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE + dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE); + + // Reduce dodge chance by attacker expertise rating + if (GetTypeId() == TYPEID_PLAYER) + dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f); + if (dodgeChance < 0) + dodgeChance = 0; + + // Can`t dodge from behind in PvP (but its possible in PvE) + if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER && attackFromBehind) + dodgeChance = 0; + + // Rogue talent`s cant be dodged + AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); + for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i) + { + if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE) // can't be dodged rogue finishing move + { + if(spell->SpellFamilyName==SPELLFAMILY_ROGUE && (spell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE)) + { + dodgeChance = 0; + break; + } + } + } + + tmp += dodgeChance; + if (roll < tmp) + return SPELL_MISS_DODGE; + + // Roll parry + int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f) - skillDiff * 4; + // Reduce parry chance by attacker expertise rating + if (GetTypeId() == TYPEID_PLAYER) + parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f); + // Can`t parry from behind + if (parryChance < 0 || attackFromBehind) + parryChance = 0; + + tmp += parryChance; + if (roll < tmp) + return SPELL_MISS_PARRY; + + return SPELL_MISS_NONE; +}*/ + +// TODO need use unit spell resistances in calculations +SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell) +{ + // Can`t miss on dead target (on skinning for example) + if (!pVictim->isAlive()) + return SPELL_MISS_NONE; + + SpellSchoolMask schoolMask = GetSpellSchoolMask(spell); + // PvP - PvE spell misschances per leveldif > 2 + int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 7 : 11; + int32 leveldif = int32(pVictim->getLevelForTarget(this)) - int32(getLevelForTarget(pVictim)); + + // Base hit chance from attacker and victim levels + int32 modHitChance; + if(leveldif < 3) + modHitChance = 96 - leveldif; + else + modHitChance = 94 - (leveldif - 2) * lchance; + + // Spellmod from SPELLMOD_RESIST_MISS_CHANCE + if(Player *modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance); + // Increase from attacker SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT auras + modHitChance+=GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT, schoolMask); + // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras + modHitChance+= pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask); + // Reduce spell hit chance for Area of effect spells from victim SPELL_AURA_MOD_AOE_AVOIDANCE aura + if (IsAreaOfEffectSpell(spell)) + modHitChance-=pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE); + // Reduce spell hit chance for dispel mechanic spells from victim SPELL_AURA_MOD_DISPEL_RESIST + if (IsDispelSpell(spell)) + modHitChance-=pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_DISPEL_RESIST); + // Chance resist mechanic (select max value from every mechanic spell effect) + int32 resist_mech = 0; + // Get effects mechanic and chance + for(int eff = 0; eff < 3; ++eff) + { + int32 effect_mech = GetEffectMechanic(spell, eff); + if (effect_mech) + { + int32 temp = pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech); + if (resist_mech < temp) + resist_mech = temp; + } + } + // Apply mod + modHitChance-=resist_mech; + + // Chance resist debuff + modHitChance-=pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)); + + int32 HitChance = modHitChance * 100; + // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings + HitChance += int32(m_modSpellHitChance*100.0f); + + // Decrease hit chance from victim rating bonus + if (pVictim->GetTypeId()==TYPEID_PLAYER) + HitChance -= int32(((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_SPELL)*100.0f); + + if (HitChance < 100) HitChance = 100; + if (HitChance > 9900) HitChance = 9900; + + uint32 rand = urand(0,10000); + if (rand > HitChance) + return SPELL_MISS_RESIST; + return SPELL_MISS_NONE; +} + +SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool CanReflect) +{ + // Return evade for units in evade mode + if (pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode()) + return SPELL_MISS_EVADE; + + // Check for immune (use charges) + if (pVictim->IsImmunedToSpell(spell,true)) + return SPELL_MISS_IMMUNE; + + // All positive spells can`t miss + // TODO: client not show miss log for this spells - so need find info for this in dbc and use it! + if (IsPositiveSpell(spell->Id)) + return SPELL_MISS_NONE; + + // Check for immune (use charges) + if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell),true)) + return SPELL_MISS_IMMUNE; + + // Try victim reflect spell + if (CanReflect) + { + // specialized first + Unit::AuraList const& mReflectSpellsSchool = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL); + for(Unit::AuraList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i) + { + if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spell)) + { + int32 reflectchance = (*i)->GetModifier()->m_amount; + if (reflectchance > 0 && roll_chance_i(reflectchance)) + { + if((*i)->m_procCharges > 0) + { + --(*i)->m_procCharges; + if((*i)->m_procCharges==0) + pVictim->RemoveAurasDueToSpell((*i)->GetId()); + } + return SPELL_MISS_REFLECT; + } + } + } + + // generic reflection + Unit::AuraList const& mReflectSpells = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS); + for(Unit::AuraList::const_iterator i = mReflectSpells.begin(); i != mReflectSpells.end(); ++i) + { + int32 reflectchance = (*i)->GetModifier()->m_amount; + if (reflectchance > 0 && roll_chance_i(reflectchance)) + { + if((*i)->m_procCharges > 0) + { + --(*i)->m_procCharges; + if((*i)->m_procCharges==0) + pVictim->RemoveAurasDueToSpell((*i)->GetId()); + } + return SPELL_MISS_REFLECT; + } + } + } + + // Temporary solution for melee based spells and spells vs SPELL_SCHOOL_NORMAL (hit result calculated after) + for (int i=0;i<3;i++) + { + if (spell->Effect[i] == SPELL_EFFECT_WEAPON_DAMAGE || + spell->Effect[i] == SPELL_EFFECT_WEAPON_PERCENT_DAMAGE || + spell->Effect[i] == SPELL_EFFECT_NORMALIZED_WEAPON_DMG || + spell->Effect[i] == SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL) + return SPELL_MISS_NONE; + } + + // TODO need use this code for spell hit result calculation + // now code commented for compotability + switch (spell->DmgClass) + { + case SPELL_DAMAGE_CLASS_RANGED: + case SPELL_DAMAGE_CLASS_MELEE: +// return MeleeSpellHitResult(pVictim, spell); + return SPELL_MISS_NONE; + case SPELL_DAMAGE_CLASS_NONE: + case SPELL_DAMAGE_CLASS_MAGIC: + return MagicSpellHitResult(pVictim, spell); + } + return SPELL_MISS_NONE; +} + +float Unit::MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const +{ + if(!pVictim) + return 0.0f; + + // Base misschance 5% + float misschance = 5.0f; + + // DualWield - Melee spells and physical dmg spells - 5% , white damage 24% + if (haveOffhandWeapon() && attType != RANGED_ATTACK) + { + bool isNormal = false; + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + { + if( m_currentSpells[i] && (GetSpellSchoolMask(m_currentSpells[i]->m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL) ) + { + isNormal = true; + break; + } + } + if (isNormal || m_currentSpells[CURRENT_MELEE_SPELL]) + { + misschance = 5.0f; + } + else + { + misschance = 24.0f; + } + } + + // PvP : PvE melee misschances per leveldif > 2 + int32 chance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7; + + int32 leveldif = int32(pVictim->getLevelForTarget(this)) - int32(getLevelForTarget(pVictim)); + if(leveldif < 0) + leveldif = 0; + + // Hit chance from attacker based on ratings and auras + float m_modHitChance; + if (attType == RANGED_ATTACK) + m_modHitChance = m_modRangedHitChance; + else + m_modHitChance = m_modMeleeHitChance; + + if(leveldif < 3) + misschance += (leveldif - m_modHitChance); + else + misschance += ((leveldif - 2) * chance - m_modHitChance); + + // Hit chance for victim based on ratings + if (pVictim->GetTypeId()==TYPEID_PLAYER) + { + if (attType == RANGED_ATTACK) + misschance += ((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_RANGED); + else + misschance += ((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_MELEE); + } + + // Modify miss chance by victim auras + if(attType == RANGED_ATTACK) + misschance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE); + else + misschance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE); + + // Modify miss chance from skill difference ( bonus from skills is 0.04% ) + int32 skillBonus = int32(GetWeaponSkillValue(attType,pVictim)) - int32(pVictim->GetDefenseSkillValue(this)); + misschance -= skillBonus * 0.04f; + + // Limit miss chance from 0 to 60% + if ( misschance < 0.0f) + return 0.0f; + if ( misschance > 60.0f) + return 60.0f; + + return misschance; +} + +uint32 Unit::GetDefenseSkillValue(Unit const* target) const +{ + if(GetTypeId() == TYPEID_PLAYER) + { + // in PvP use full skill instead current skill value + uint32 value = (target && target->GetTypeId() == TYPEID_PLAYER) + ? ((Player*)this)->GetMaxSkillValue(SKILL_DEFENSE) + : ((Player*)this)->GetSkillValue(SKILL_DEFENSE); + value += uint32(((Player*)this)->GetRatingBonusValue(CR_DEFENSE_SKILL)); + return value; + } + else + return GetUnitMeleeSkill(target); +} + +float Unit::GetUnitDodgeChance() const +{ + if(hasUnitState(UNIT_STAT_STUNNED)) + return 0.0f; + if( GetTypeId() == TYPEID_PLAYER ) + return GetFloatValue(PLAYER_DODGE_PERCENTAGE); + else + { + if(((Creature const*)this)->isTotem()) + return 0.0f; + else + { + float dodge = 5.0f; + dodge += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT); + return dodge > 0.0f ? dodge : 0.0f; + } + } +} + +float Unit::GetUnitParryChance() const +{ + if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNNED)) + return 0.0f; + + float chance = 0.0f; + + if(GetTypeId() == TYPEID_PLAYER) + { + Player const* player = (Player const*)this; + if(player->CanParry() ) + { + Item *tmpitem = player->GetWeaponForAttack(BASE_ATTACK,true); + if(!tmpitem) + tmpitem = player->GetWeaponForAttack(OFF_ATTACK,true); + + if(tmpitem) + chance = GetFloatValue(PLAYER_PARRY_PERCENTAGE); + } + } + else if(GetTypeId() == TYPEID_UNIT) + { + if(GetCreatureType() == CREATURE_TYPE_HUMANOID) + { + chance = 5.0f; + chance += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT); + } + } + + return chance > 0.0f ? chance : 0.0f; +} + +float Unit::GetUnitBlockChance() const +{ + if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNNED)) + return 0.0f; + + if(GetTypeId() == TYPEID_PLAYER) + { + Player const* player = (Player const*)this; + if(player->CanBlock() ) + { + Item *tmpitem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + if(tmpitem && !tmpitem->IsBroken() && tmpitem->GetProto()->Block) + return GetFloatValue(PLAYER_BLOCK_PERCENTAGE); + } + // is player but has no block ability or no not broken shield equiped + return 0.0f; + } + else + { + if(((Creature const*)this)->isTotem()) + return 0.0f; + else + { + float block = 5.0f; + block += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT); + return block > 0.0f ? block : 0.0f; + } + } +} + +float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const +{ + float crit; + + if(GetTypeId() == TYPEID_PLAYER) + { + switch(attackType) + { + case BASE_ATTACK: + crit = GetFloatValue( PLAYER_CRIT_PERCENTAGE ); + break; + case OFF_ATTACK: + crit = GetFloatValue( PLAYER_OFFHAND_CRIT_PERCENTAGE ); + break; + case RANGED_ATTACK: + crit = GetFloatValue( PLAYER_RANGED_CRIT_PERCENTAGE ); + break; + // Just for good manner + default: + crit = 0.0f; + break; + } + } + else + { + crit = 5.0f; + crit += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PERCENT); + } + + // flat aura mods + if(attackType == RANGED_ATTACK) + crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE); + else + crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE); + + crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE); + + // reduce crit chance from Rating for players + if (pVictim->GetTypeId()==TYPEID_PLAYER) + { + if (attackType==RANGED_ATTACK) + crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_RANGED); + else + crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE); + } + + if (crit < 0.0f) + crit = 0.0f; + return crit; +} + +uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target) const +{ + uint32 value = 0; + if(GetTypeId() == TYPEID_PLAYER) + { + Item* item = ((Player*)this)->GetWeaponForAttack(attType,true); + + // feral or unarmed skill only for base attack + if(attType != BASE_ATTACK && !item ) + return 0; + + if(((Player*)this)->IsInFeralForm()) + return GetMaxSkillValueForLevel(); // always maximized SKILL_FERAL_COMBAT in fact + + // weaon skill or (unarmed for base attack) + uint32 skill = item ? item->GetSkill() : SKILL_UNARMED; + + // in PvP use full skill instead current skill value + value = (target && target->GetTypeId() == TYPEID_PLAYER) + ? ((Player*)this)->GetMaxSkillValue(skill) + : ((Player*)this)->GetSkillValue(skill); + // Modify value from ratings + value += uint32(((Player*)this)->GetRatingBonusValue(CR_WEAPON_SKILL)); + switch (attType) + { + case BASE_ATTACK: value+=uint32(((Player*)this)->GetRatingBonusValue(CR_WEAPON_SKILL_MAINHAND));break; + case OFF_ATTACK: value+=uint32(((Player*)this)->GetRatingBonusValue(CR_WEAPON_SKILL_OFFHAND));break; + case RANGED_ATTACK: value+=uint32(((Player*)this)->GetRatingBonusValue(CR_WEAPON_SKILL_RANGED));break; + } + } + else + value = GetUnitMeleeSkill(target); + return value; +} + +void Unit::_UpdateSpells( uint32 time ) +{ + if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]) + _UpdateAutoRepeatSpell(); + + // remove finished spells from current pointers + for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) + { + if (m_currentSpells[i] && m_currentSpells[i]->getState() == SPELL_STATE_FINISHED) + { + m_currentSpells[i]->SetDeletable(true); // spell may be safely deleted now + m_currentSpells[i] = NULL; // remove pointer + } + } + + // TODO: Find a better way to prevent crash when multiple auras are removed. + m_removedAuras = 0; + for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i) + if ((*i).second) + (*i).second->SetUpdated(false); + + for (AuraMap::iterator i = m_Auras.begin(), next; i != m_Auras.end(); i = next) + { + next = i; + ++next; + if ((*i).second) + { + // prevent double update + if ((*i).second->IsUpdated()) + continue; + (*i).second->SetUpdated(true); + (*i).second->Update( time ); + // several auras can be deleted due to update + if (m_removedAuras) + { + if (m_Auras.empty()) break; + next = m_Auras.begin(); + m_removedAuras = 0; + } + } + } + + for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();) + { + if ((*i).second) + { + if ( !(*i).second->GetAuraDuration() && !((*i).second->IsPermanent() || ((*i).second->IsPassive())) ) + { + RemoveAura(i); + } + else + { + ++i; + } + } + else + { + ++i; + } + } + + if(!m_gameObj.empty()) + { + std::list::iterator ite1, dnext1; + for (ite1 = m_gameObj.begin(); ite1 != m_gameObj.end(); ite1 = dnext1) + { + dnext1 = ite1; + //(*i)->Update( difftime ); + if( !(*ite1)->isSpawned() ) + { + (*ite1)->SetOwnerGUID(0); + (*ite1)->SetRespawnTime(0); + (*ite1)->Delete(); + dnext1 = m_gameObj.erase(ite1); + } + else + ++dnext1; + } + } +} + +void Unit::_UpdateAutoRepeatSpell() +{ + //check "realtime" interrupts + if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true) ) + { + // cancel wand shoot + if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351) + InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + m_AutoRepeatFirstCast = true; + return; + } + + //apply delay + if ( m_AutoRepeatFirstCast && getAttackTimer(RANGED_ATTACK) < 500 ) + setAttackTimer(RANGED_ATTACK,500); + m_AutoRepeatFirstCast = false; + + //castroutine + if (isAttackReady(RANGED_ATTACK)) + { + // Check if able to cast + if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true)) + { + InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + return; + } + + // we want to shoot + Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, true, 0); + spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets)); + + // all went good, reset attack + resetAttackTimer(RANGED_ATTACK); + } +} + +void Unit::SetCurrentCastedSpell( Spell * pSpell ) +{ + assert(pSpell); // NULL may be never passed here, use InterruptSpell or InterruptNonMeleeSpells + + uint32 CSpellType = pSpell->GetCurrentContainer(); + + pSpell->SetDeletable(false); // spell will not be deleted until gone from current pointers + if (pSpell == m_currentSpells[CSpellType]) return; // avoid breaking self + + // break same type spell if it is not delayed + InterruptSpell(CSpellType,false); + + // special breakage effects: + switch (CSpellType) + { + case CURRENT_GENERIC_SPELL: + { + // generic spells always break channeled not delayed spells + InterruptSpell(CURRENT_CHANNELED_SPELL,false); + + // autorepeat breaking + if ( m_currentSpells[CURRENT_AUTOREPEAT_SPELL] ) + { + // break autorepeat if not Auto Shot + if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351) + InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + m_AutoRepeatFirstCast = true; + } + } break; + + case CURRENT_CHANNELED_SPELL: + { + // channel spells always break generic non-delayed and any channeled spells + InterruptSpell(CURRENT_GENERIC_SPELL,false); + InterruptSpell(CURRENT_CHANNELED_SPELL); + + // it also does break autorepeat if not Auto Shot + if ( m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && + m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351 ) + InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + } break; + + case CURRENT_AUTOREPEAT_SPELL: + { + // only Auto Shoot does not break anything + if (pSpell->m_spellInfo->Category == 351) + { + // generic autorepeats break generic non-delayed and channeled non-delayed spells + InterruptSpell(CURRENT_GENERIC_SPELL,false); + InterruptSpell(CURRENT_CHANNELED_SPELL,false); + } + // special action: set first cast flag + m_AutoRepeatFirstCast = true; + } break; + + default: + { + // other spell types don't break anything now + } break; + } + + // current spell (if it is still here) may be safely deleted now + if (m_currentSpells[CSpellType]) + m_currentSpells[CSpellType]->SetDeletable(true); + + // set new current spell + m_currentSpells[CSpellType] = pSpell; +} + +void Unit::InterruptSpell(uint32 spellType, bool withDelayed) +{ + assert(spellType < CURRENT_MAX_SPELL); + + if(m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) ) + { + // send autorepeat cancel message for autorepeat spells + if (spellType == CURRENT_AUTOREPEAT_SPELL) + { + if(GetTypeId()==TYPEID_PLAYER) + ((Player*)this)->SendAutoRepeatCancel(); + } + + if (m_currentSpells[spellType]->getState() != SPELL_STATE_FINISHED) + m_currentSpells[spellType]->cancel(); + m_currentSpells[spellType]->SetDeletable(true); + m_currentSpells[spellType] = NULL; + } +} + +bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat) const +{ + // We don't do loop here to explicitly show that melee spell is excluded. + // Maybe later some special spells will be excluded too. + + // generic spells are casted when they are not finished and not delayed + if ( m_currentSpells[CURRENT_GENERIC_SPELL] && + (m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) && + (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) ) + return(true); + + // channeled spells may be delayed, but they are still considered casted + else if ( !skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] && + (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) ) + return(true); + + // autorepeat spells may be finished or delayed, but they are still considered casted + else if ( !skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL] ) + return(true); + + return(false); +} + +void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) +{ + // generic spells are interrupted if they are not finished or delayed + if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id)) + { + if ( (m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) && + (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) ) + m_currentSpells[CURRENT_GENERIC_SPELL]->cancel(); + m_currentSpells[CURRENT_GENERIC_SPELL]->SetDeletable(true); + m_currentSpells[CURRENT_GENERIC_SPELL] = NULL; + } + + // autorepeat spells are interrupted if they are not finished or delayed + if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id)) + { + // send disable autorepeat packet in any case + if(GetTypeId()==TYPEID_PLAYER) + ((Player*)this)->SendAutoRepeatCancel(); + + if ( (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_FINISHED) && + (withDelayed || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_DELAYED) ) + m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->cancel(); + m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetDeletable(true); + m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL; + } + + // channeled spells are interrupted if they are not finished, even if they are delayed + if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id)) + { + if (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) + m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(); + m_currentSpells[CURRENT_CHANNELED_SPELL]->SetDeletable(true); + m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL; + } +} + +Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const +{ + for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) + if(m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id==spell_id) + return m_currentSpells[i]; + return NULL; +} + +bool Unit::isInFront(Unit const* target, float distance, float arc) const +{ + return IsWithinDistInMap(target, distance) && HasInArc( arc, target ); +} + +void Unit::SetInFront(Unit const* target) +{ + SetOrientation(GetAngle(target)); +} + +bool Unit::isInBack(Unit const* target, float distance, float arc) const +{ + return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target ); +} + +bool Unit::isInAccessablePlaceFor(Creature const* c) const +{ + if(IsInWater()) + return c->canSwim(); + else + return c->canWalk() || c->canFly(); +} + +bool Unit::IsInWater() const +{ + return MapManager::Instance().GetBaseMap(GetMapId())->IsInWater(GetPositionX(),GetPositionY(), GetPositionZ()); +} + +bool Unit::IsUnderWater() const +{ + return MapManager::Instance().GetBaseMap(GetMapId())->IsUnderWater(GetPositionX(),GetPositionY(),GetPositionZ()); +} + +void Unit::DeMorph() +{ + SetDisplayId(GetNativeDisplayId()); +} + +int32 Unit::GetTotalAuraModifier(AuraType auratype) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + modifier += (*i)->GetModifier()->m_amount; + + return modifier; +} + +float Unit::GetTotalAuraMultiplier(AuraType auratype) const +{ + float multipler = 1.0f; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + multipler *= (100.0f + (*i)->GetModifier()->m_amount)/100.0f; + + return multipler; +} + +int32 Unit::GetMaxPositiveAuraModifier(AuraType auratype) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + if ((*i)->GetModifier()->m_amount > modifier) + modifier = (*i)->GetModifier()->m_amount; + + return modifier; +} + +int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + if ((*i)->GetModifier()->m_amount < modifier) + modifier = (*i)->GetModifier()->m_amount; + + return modifier; +} + +int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue & misc_mask) + modifier += mod->m_amount; + } + return modifier; +} + +float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const +{ + float multipler = 1.0f; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue & misc_mask) + multipler *= (100.0f + mod->m_amount)/100.0f; + } + return multipler; +} + +int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue & misc_mask && mod->m_amount > modifier) + modifier = mod->m_amount; + } + + return modifier; +} + +int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue & misc_mask && mod->m_amount < modifier) + modifier = mod->m_amount; + } + + return modifier; +} + +int32 Unit::GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue == misc_value) + modifier += mod->m_amount; + } + return modifier; +} + +float Unit::GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const +{ + float multipler = 1.0f; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue == misc_value) + multipler *= (100.0f + mod->m_amount)/100.0f; + } + return multipler; +} + +int32 Unit::GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue == misc_value && mod->m_amount > modifier) + modifier = mod->m_amount; + } + + return modifier; +} + +int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const +{ + int32 modifier = 0; + + AuraList const& mTotalAuraList = GetAurasByType(auratype); + for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i) + { + Modifier* mod = (*i)->GetModifier(); + if (mod->m_miscvalue == misc_value && mod->m_amount < modifier) + modifier = mod->m_amount; + } + + return modifier; +} + +bool Unit::AddAura(Aura *Aur) +{ + // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) + if( !isAlive() && Aur->GetId() != 20584 && Aur->GetId() != 8326 && Aur->GetId() != 2584 && + (GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) ) + { + delete Aur; + return false; + } + + if(Aur->GetTarget() != this) + { + sLog.outError("Aura (spell %u eff %u) add to aura list of %s (lowguid: %u) but Aura target is %s (lowguid: %u)", + Aur->GetId(),Aur->GetEffIndex(),(GetTypeId()==TYPEID_PLAYER?"player":"creature"),GetGUIDLow(), + (Aur->GetTarget()->GetTypeId()==TYPEID_PLAYER?"player":"creature"),Aur->GetTarget()->GetGUIDLow()); + delete Aur; + return false; + } + + SpellEntry const* aurSpellInfo = Aur->GetSpellProto(); + + spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex()); + AuraMap::iterator i = m_Auras.find( spair ); + + // take out same spell + if (i != m_Auras.end()) + { + // passive and persistent auras can stack with themselves any number of times + if (!Aur->IsPassive() && !Aur->IsPersistent()) + { + // replace aura if next will > spell StackAmount + if(aurSpellInfo->StackAmount) + { + if(m_Auras.count(spair) >= aurSpellInfo->StackAmount) + RemoveAura(i,AURA_REMOVE_BY_STACK); + } + // if StackAmount==0 not allow auras from same caster + else + { + for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2) + { + if(i2->second->GetCasterGUID()==Aur->GetCasterGUID()) + { + // can be only single (this check done at _each_ aura add + RemoveAura(i2,AURA_REMOVE_BY_STACK); + break; + } + + bool stop = false; + switch(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]) + { + // DoT/HoT/etc + case SPELL_AURA_PERIODIC_DAMAGE: // allow stack + case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: + case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_PERIODIC_HEAL: + case SPELL_AURA_OBS_MOD_HEALTH: + case SPELL_AURA_PERIODIC_MANA_LEECH: + case SPELL_AURA_PERIODIC_ENERGIZE: + case SPELL_AURA_OBS_MOD_MANA: + case SPELL_AURA_POWER_BURN_MANA: + break; + default: // not allow + // can be only single (this check done at _each_ aura add + RemoveAura(i2,AURA_REMOVE_BY_STACK); + stop = true; + break; + } + + if(stop) + break; + } + } + } + } + + // passive auras stack with all (except passive spell proc auras) + if ((!Aur->IsPassive() || !IsPassiveStackableSpell(Aur->GetId())) && + !(Aur->GetId() == 20584 || Aur->GetId() == 8326)) + { + if (!RemoveNoStackAurasDueToAura(Aur)) + { + delete Aur; + return false; // couldnt remove conflicting aura with higher rank + } + } + + // update single target auras list (before aura add to aura list, to prevent unexpected remove recently added aura) + if (IsSingleTargetSpell(aurSpellInfo) && Aur->GetTarget()) + { + // caster pointer can be deleted in time aura remove, find it by guid at each iteration + for(;;) + { + Unit* caster = Aur->GetCaster(); + if(!caster) // caster deleted and not required adding scAura + break; + + bool restart = false; + AuraList& scAuras = caster->GetSingleCastAuras(); + for(AuraList::iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr) + { + if( (*itr)->GetTarget() != Aur->GetTarget() && + IsSingleTargetSpells((*itr)->GetSpellProto(),aurSpellInfo) ) + { + if ((*itr)->IsInUse()) + { + sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for IsSingleTargetSpell", (*itr)->GetId(), (*itr)->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + continue; + } + (*itr)->GetTarget()->RemoveAura((*itr)->GetId(), (*itr)->GetEffIndex()); + restart = true; + break; + } + } + + if(!restart) + { + // done + scAuras.push_back(Aur); + break; + } + } + } + + // add aura, register in lists and arrays + Aur->_AddAura(); + m_Auras.insert(AuraMap::value_type(spellEffectPair(Aur->GetId(), Aur->GetEffIndex()), Aur)); + if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) + { + m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur); + } + + Aur->ApplyModifier(true,true); + sLog.outDebug("Aura %u now is in use", Aur->GetModifier()->m_auraname); + return true; +} + +void Unit::RemoveRankAurasDueToSpell(uint32 spellId) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + return; + AuraMap::iterator i,next; + for (i = m_Auras.begin(); i != m_Auras.end(); i = next) + { + next = i; + ++next; + uint32 i_spellId = (*i).second->GetId(); + if((*i).second && i_spellId && i_spellId != spellId) + { + if(spellmgr.IsRankSpellDueToSpell(spellInfo,i_spellId)) + { + RemoveAurasDueToSpell(i_spellId); + + if( m_Auras.empty() ) + break; + else + next = m_Auras.begin(); + } + } + } +} + +bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) +{ + if (!Aur) + return false; + + SpellEntry const* spellProto = Aur->GetSpellProto(); + if (!spellProto) + return false; + + uint32 spellId = Aur->GetId(); + uint32 effIndex = Aur->GetEffIndex(); + + SpellSpecific spellId_spec = GetSpellSpecific(spellId); + + AuraMap::iterator i,next; + for (i = m_Auras.begin(); i != m_Auras.end(); i = next) + { + next = i; + ++next; + if (!(*i).second) continue; + + SpellEntry const* i_spellProto = (*i).second->GetSpellProto(); + + if (!i_spellProto) + continue; + + uint32 i_spellId = i_spellProto->Id; + + if(IsPassiveSpell(i_spellId)) + { + if(IsPassiveStackableSpell(i_spellId)) + continue; + + // passive non-stackable spells not stackable only with another rank of same spell + if (!spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) + continue; + } + + uint32 i_effIndex = (*i).second->GetEffIndex(); + + if(i_spellId == spellId) continue; + + bool is_triggered_by_spell = false; + // prevent triggered aura of removing aura that triggered it + for(int j = 0; j < 3; ++j) + if (i_spellProto->EffectTriggerSpell[j] == spellProto->Id) + is_triggered_by_spell = true; + if (is_triggered_by_spell) continue; + + for(int j = 0; j < 3; ++j) + { + // prevent remove dummy triggered spells at next effect aura add + switch(spellProto->Effect[j]) // main spell auras added added after triggred spell + { + case SPELL_EFFECT_DUMMY: + switch(spellId) + { + case 5420: if(i_spellId==34123) is_triggered_by_spell = true; break; + } + break; + } + + if(is_triggered_by_spell) + break; + + // prevent remove form main spell by triggred passive spells + switch(i_spellProto->EffectApplyAuraName[j]) // main aura added before triggered spell + { + case SPELL_AURA_MOD_SHAPESHIFT: + switch(i_spellId) + { + case 24858: if(spellId==24905) is_triggered_by_spell = true; break; + case 33891: if(spellId==5420 || spellId==34123) is_triggered_by_spell = true; break; + case 34551: if(spellId==22688) is_triggered_by_spell = true; break; + } + break; + } + } + + if(!is_triggered_by_spell) + { + SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId); + + bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec); + + if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) + { + // cannot remove higher rank + if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId)) + if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) + return false; + + // Its a parent aura (create this aura in ApplyModifier) + if ((*i).second->IsInUse()) + { + sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + continue; + } + RemoveAurasDueToSpell(i_spellId); + + if( m_Auras.empty() ) + break; + else + next = m_Auras.begin(); + } + else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) ) + { + // Its a parent aura (create this aura in ApplyModifier) + if ((*i).second->IsInUse()) + { + sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + continue; + } + RemoveAurasDueToSpell(i_spellId); + + if( m_Auras.empty() ) + break; + else + next = m_Auras.begin(); + } + // Potions stack aura by aura (elixirs/flask already checked) + else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION ) + { + if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex)) + { + if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) + return false; // cannot remove higher rank + + // Its a parent aura (create this aura in ApplyModifier) + if ((*i).second->IsInUse()) + { + sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + continue; + } + RemoveAura(i); + next = i; + } + } + } + } + return true; +} + +void Unit::RemoveAura(uint32 spellId, uint32 effindex, Aura* except) +{ + spellEffectPair spair = spellEffectPair(spellId, effindex); + for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);) + { + if(iter->second!=except) + { + RemoveAura(iter); + iter = m_Auras.lower_bound(spair); + } + else + ++iter; + } +} + +void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler) +{ + for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + { + Aura *aur = iter->second; + if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) + { + // Custom dispel case + // Unstable Affliction + if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & 0x010000000000LL)) + { + int32 damage = aur->GetModifier()->m_amount*9; + uint64 caster_guid = aur->GetCasterGUID(); + + // Remove aura + RemoveAura(iter, AURA_REMOVE_BY_DISPEL); + + // backfire damage and silence + dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,caster_guid); + + iter = m_Auras.begin(); // iterator can be invalidate at cast if self-dispel + } + else + RemoveAura(iter, AURA_REMOVE_BY_DISPEL); + } + else + ++iter; + } +} + +void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer) +{ + for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + { + Aura *aur = iter->second; + if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) + { + int32 basePoints = aur->GetBasePoints(); + // construct the new aura for the attacker + Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), &basePoints, stealer); + if(!new_aur) + continue; + + // set its duration and maximum duration + // max duration 2 minutes (in msecs) + int32 dur = aur->GetAuraDuration(); + const int32 max_dur = 2*MINUTE*1000; + new_aur->SetAuraMaxDuration( max_dur > dur ? dur : max_dur ); + new_aur->SetAuraDuration( max_dur > dur ? dur : max_dur ); + + // add the new aura to stealer + stealer->AddAura(new_aur); + + // Remove aura as dispel + RemoveAura(iter, AURA_REMOVE_BY_DISPEL); + } + else + ++iter; + } +} + +void Unit::RemoveAurasDueToSpellByCancel(uint32 spellId) +{ + for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + { + if (iter->second->GetId() == spellId) + RemoveAura(iter, AURA_REMOVE_BY_CANCEL); + else + ++iter; + } +} + +void Unit::RemoveAurasWithDispelType( DispelType type ) +{ + // Create dispel mask by dispel type + uint32 dispelMask = GetDispellMask(type); + // Dispel all existing auras vs current dispell type + AuraMap& auras = GetAuras(); + for(AuraMap::iterator itr = auras.begin(); itr != auras.end(); ) + { + SpellEntry const* spell = itr->second->GetSpellProto(); + if( (1<Dispel) & dispelMask ) + { + // Dispel aura + RemoveAurasDueToSpell(spell->Id); + itr = auras.begin(); + } + else + ++itr; + } +} + +void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex) +{ + AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); + if(iter != m_Auras.end()) + RemoveAura(iter); +} + +void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except) +{ + for (int i = 0; i < 3; ++i) + RemoveAura(spellId,i,except); +} + +void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId) +{ + for (int k=0; k < 3; ++k) + { + spellEffectPair spair = spellEffectPair(spellId, k); + for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);) + { + if (iter->second->GetCastItemGUID() == castItem->GetGUID()) + { + RemoveAura(iter); + iter = m_Auras.upper_bound(spair); // overwrite by more appropriate + } + else + ++iter; + } + } +} + +void Unit::RemoveAurasWithInterruptFlags(uint32 flags) +{ + for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + { + if (iter->second->GetSpellProto()->AuraInterruptFlags & flags) + RemoveAura(iter); + else + ++iter; + } +} + +void Unit::RemoveNotOwnSingleTargetAuras() +{ + // single target auras from other casters + for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + { + if (iter->second->GetCasterGUID()!=GetGUID() && IsSingleTargetSpell(iter->second->GetSpellProto())) + RemoveAura(iter); + else + ++iter; + } + + // single target auras at other targets + AuraList& scAuras = GetSingleCastAuras(); + for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end(); ) + { + Aura* aura = *iter; + if (aura->GetTarget()!=this) + { + scAuras.erase(iter); // explicitly remove, instead waiting remove in RemoveAura + aura->GetTarget()->RemoveAura(aura->GetId(),aura->GetEffIndex()); + iter = scAuras.begin(); + } + else + ++iter; + } + +} + +void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) +{ + if (IsSingleTargetSpell((*i).second->GetSpellProto())) + { + if(Unit* caster = (*i).second->GetCaster()) + { + AuraList& scAuras = caster->GetSingleCastAuras(); + scAuras.remove((*i).second); + } + else + { + sLog.outError("Couldn't find the caster of the single target aura, may crash later!"); + assert(false); + } + } + + if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS) + { + m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); + } + + // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) + Aura* Aur = i->second; + // Set remove mode + Aur->SetRemoveMode(mode); + // some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura + // remove aura from list before to prevent deleting it before + m_Auras.erase(i); + ++m_removedAuras; // internal count used by unit update + + // Status unsummoned at aura remove + Totem* statue = NULL; + if(IsChanneledSpell(Aur->GetSpellProto())) + if(Unit* caster = Aur->GetCaster()) + if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) + statue = ((Totem*)caster); + + sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); + Aur->ApplyModifier(false,true); + Aur->_RemoveAura(); + delete Aur; + + if(statue) + statue->UnSummon(); + + // only way correctly remove all auras from list + if( m_Auras.empty() ) + i = m_Auras.end(); + else + i = m_Auras.begin(); +} + +void Unit::RemoveAllAuras() +{ + while (!m_Auras.empty()) + { + AuraMap::iterator iter = m_Auras.begin(); + RemoveAura(iter); + } +} + +void Unit::RemoveAllAurasOnDeath() +{ + // used just after dieing to remove all visible auras + // and disable the mods for the passive ones + for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) + { + if (!iter->second->IsPassive() && !iter->second->IsDeathPersistent()) + RemoveAura(iter, AURA_REMOVE_BY_DEATH); + else + ++iter; + } +} + +void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime) +{ + AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); + if (iter != m_Auras.end()) + { + if (iter->second->GetAuraDuration() < delaytime) + iter->second->SetAuraDuration(0); + else + iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime); + iter->second->UpdateAuraDuration(); + sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration()); + } +} + +void Unit::_RemoveAllAuraMods() +{ + for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i) + { + (*i).second->ApplyModifier(false); + } +} + +void Unit::_ApplyAllAuraMods() +{ + for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i) + { + (*i).second->ApplyModifier(true); + } +} + +Aura* Unit::GetAura(uint32 spellId, uint32 effindex) +{ + AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); + if (iter != m_Auras.end()) + return iter->second; + return NULL; +} + +void Unit::AddDynObject(DynamicObject* dynObj) +{ + m_dynObjGUIDs.push_back(dynObj->GetGUID()); +} + +void Unit::RemoveDynObject(uint32 spellid) +{ + if(m_dynObjGUIDs.empty()) + return; + for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();) + { + DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this,*m_dynObjGUIDs.begin()); + if(!dynObj) + { + i = m_dynObjGUIDs.erase(i); + } + else if(spellid == 0 || dynObj->GetSpellId() == spellid) + { + dynObj->Delete(); + i = m_dynObjGUIDs.erase(i); + } + else + ++i; + } +} + +void Unit::RemoveAllDynObjects() +{ + while(!m_dynObjGUIDs.empty()) + { + DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this,*m_dynObjGUIDs.begin()); + if(dynObj) + dynObj->Delete(); + m_dynObjGUIDs.erase(m_dynObjGUIDs.begin()); + } +} + +DynamicObject * Unit::GetDynObject(uint32 spellId, uint32 effIndex) +{ + for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();) + { + DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this,*m_dynObjGUIDs.begin()); + if(!dynObj) + { + i = m_dynObjGUIDs.erase(i); + continue; + } + + if (dynObj->GetSpellId() == spellId && dynObj->GetEffIndex() == effIndex) + return dynObj; + ++i; + } + return NULL; +} + +DynamicObject * Unit::GetDynObject(uint32 spellId) +{ + for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();) + { + DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this,*m_dynObjGUIDs.begin()); + if(!dynObj) + { + i = m_dynObjGUIDs.erase(i); + continue; + } + + if (dynObj->GetSpellId() == spellId) + return dynObj; + ++i; + } + return NULL; +} + +void Unit::AddGameObject(GameObject* gameObj) +{ + assert(gameObj && gameObj->GetOwnerGUID()==0); + m_gameObj.push_back(gameObj); + gameObj->SetOwnerGUID(GetGUID()); +} + +void Unit::RemoveGameObject(GameObject* gameObj, bool del) +{ + assert(gameObj && gameObj->GetOwnerGUID()==GetGUID()); + + // GO created by some spell + if ( GetTypeId()==TYPEID_PLAYER && gameObj->GetSpellId() ) + { + SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId()); + // Need activate spell use for owner + if (createBySpell && createBySpell->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + ((Player*)this)->SendCooldownEvent(createBySpell); + } + gameObj->SetOwnerGUID(0); + m_gameObj.remove(gameObj); + if(del) + { + gameObj->SetRespawnTime(0); + gameObj->Delete(); + } +} + +void Unit::RemoveGameObject(uint32 spellid, bool del) +{ + if(m_gameObj.empty()) + return; + std::list::iterator i, next; + for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next) + { + next = i; + if(spellid == 0 || (*i)->GetSpellId() == spellid) + { + (*i)->SetOwnerGUID(0); + if(del) + { + (*i)->SetRespawnTime(0); + (*i)->Delete(); + } + + next = m_gameObj.erase(i); + } + else + ++next; + } +} + +void Unit::RemoveAllGameObjects() +{ + // remove references to unit + for(std::list::iterator i = m_gameObj.begin(); i != m_gameObj.end();) + { + (*i)->SetOwnerGUID(0); + (*i)->SetRespawnTime(0); + (*i)->Delete(); + i = m_gameObj.erase(i); + } +} + +void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit) +{ + sLog.outDebug("Sending: SMSG_SPELLNONMELEEDAMAGELOG"); + WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+4+4+1+4+4+1+1+4+4+1)); // we guess size + data.append(target->GetPackGUID()); + data.append(GetPackGUID()); + data << uint32(SpellID); + data << uint32(Damage-AbsorbedDamage-Resist-Blocked); + data << uint8(damageSchoolMask); // spell school + data << uint32(AbsorbedDamage); // AbsorbedDamage + data << uint32(Resist); // resist + data << uint8(PhysicalDamage); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name + data << uint8(0); // unk isFromAura + data << uint32(Blocked); // blocked + data << uint32(CriticalHit ? 0x27 : 0x25); // hitType, flags: 0x2 - SPELL_HIT_TYPE_CRIT, 0x10 - replace caster? + data << uint8(0); // isDebug? + SendMessageToSet( &data, true ); +} + +void Unit::SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo) +{ + WorldPacket data(SMSG_SPELLLOGMISS, (4+8+1+4+8+1)); + data << uint32(spellID); + data << uint64(GetGUID()); + data << uint8(0); // can be 0 or 1 + data << uint32(1); // target count + // for(i = 0; i < target count; ++i) + data << uint64(target->GetGUID()); // target GUID + data << uint8(missInfo); + // end loop + SendMessageToSet(&data, true); +} + +void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount) +{ + sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE"); + + WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size + data << (uint32)HitInfo; + data.append(GetPackGUID()); + data.append(target->GetPackGUID()); + data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); + + data << (uint8)SwingType; // count? + + // for(i = 0; i < SwingType; ++i) + data << (uint32)damageSchoolMask; + data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount); + // still need to double check damage + data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); + data << (uint32)AbsorbDamage; + data << (uint32)Resist; + // end loop + + data << (uint32)TargetState; + + if( AbsorbDamage == 0 ) //also 0x3E8 = 0x3E8, check when that happens + data << (uint32)0; + else + data << (uint32)-1; + + data << (uint32)0; + data << (uint32)BlockedAmount; + + SendMessageToSet( &data, true ); +} + +void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType) +{ + sLog.outDebug("ProcDamageAndSpell: attacker flags are 0x%x, victim flags 0x%x", procAttacker, procVictim); + if(procSpell) + sLog.outDebug("ProcDamageAndSpell: invoked due to spell id %u %s", procSpell->Id, (isTriggeredSpell?"(triggered)":"")); + + // Assign melee/ranged proc flags for magic attacks, that are actually melee/ranged abilities + // not assign for spell proc triggered spell to prevent infinity (or unexpacted 2-3 times) melee damage spell proc call with melee damage effect + // That is the question though if it's fully correct + if(procSpell && !isTriggeredSpell) + { + if(procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE) + { + if(procAttacker & PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_MELEE; + if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_MELEE; + if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_MELEE; + if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_MELEE; + attType = BASE_ATTACK; // Melee abilities are assumed to be dealt with mainhand weapon + } + else if (procSpell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) + { + if(procAttacker & PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_RANGED; + if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_RANGED; + if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_RANGED; + if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_RANGED; + attType = RANGED_ATTACK; + } + } + if(damage && (procVictim & (PROC_FLAG_STRUCK_MELEE|PROC_FLAG_STRUCK_RANGED|PROC_FLAG_STRUCK_SPELL))) + procVictim |= (PROC_FLAG_TAKE_DAMAGE|PROC_FLAG_TOUCH); + + // Not much to do if no flags are set. + if (procAttacker) + { + // procces auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set + ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcEffectAuraTypes,attType, procSpell, damage, damageSchoolMask); + ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcCastAuraTypes,attType, procSpell, damage, damageSchoolMask); + } + + // Now go on with a victim's events'n'auras + // Not much to do if no flags are set or there is no victim + if(pVictim && pVictim->isAlive() && procVictim) + { + // procces auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set + pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcEffectAuraTypes,attType,procSpell, damage, damageSchoolMask); + pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcCastAuraTypes,attType,procSpell, damage, damageSchoolMask); + } +} + +void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchoolMask damageSchoolMask, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted, bool isTriggeredSpell) +{ + if(!pVictim) + return; + + uint32 procAttacker = PROC_FLAG_NONE; + uint32 procVictim = PROC_FLAG_NONE; + + switch(outcome) + { + case MELEE_HIT_EVADE: + return; + case MELEE_HIT_MISS: + if(attType == BASE_ATTACK || attType == OFF_ATTACK) + { + procAttacker = PROC_FLAG_MISS; + } + break; + case MELEE_HIT_BLOCK_CRIT: + case MELEE_HIT_CRIT: + if(spellCasted && attType == BASE_ATTACK) + { + procAttacker |= PROC_FLAG_CRIT_SPELL; + procVictim |= PROC_FLAG_STRUCK_CRIT_SPELL; + if ( outcome == MELEE_HIT_BLOCK_CRIT ) + { + procVictim |= PROC_FLAG_BLOCK; + procAttacker |= PROC_FLAG_TARGET_BLOCK; + } + } + else if(attType == BASE_ATTACK || attType == OFF_ATTACK) + { + procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE; + procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE; + } + else + { + procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED; + procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED; + } + break; + case MELEE_HIT_PARRY: + procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY; + procVictim = PROC_FLAG_PARRY; + break; + case MELEE_HIT_BLOCK: + procAttacker = PROC_FLAG_TARGET_BLOCK; + procVictim = PROC_FLAG_BLOCK; + break; + case MELEE_HIT_DODGE: + procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY; + procVictim = PROC_FLAG_DODGE; + break; + case MELEE_HIT_CRUSHING: + if(attType == BASE_ATTACK || attType == OFF_ATTACK) + { + procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE; + procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE; + } + else + { + procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED; + procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED; + } + break; + default: + if(attType == BASE_ATTACK || attType == OFF_ATTACK) + { + procAttacker = PROC_FLAG_HIT_MELEE; + procVictim = PROC_FLAG_STRUCK_MELEE; + } + else + { + procAttacker = PROC_FLAG_HIT_RANGED; + procVictim = PROC_FLAG_STRUCK_RANGED; + } + break; + } + + if(damage > 0) + procVictim |= PROC_FLAG_TAKE_DAMAGE; + + if(procAttacker != PROC_FLAG_NONE || procVictim != PROC_FLAG_NONE) + ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType); +} + +bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 cooldown) +{ + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = 0; + Unit* target = pVictim; + int32 basepoints0 = 0; + + switch(hasteSpell->SpellFamilyName) + { + case SPELLFAMILY_ROGUE: + { + switch(hasteSpell->Id) + { + // Blade Flurry + case 13877: + case 33735: + { + target = SelectNearbyTarget(); + if(!target) + return false; + basepoints0 = damage; + triggered_spell_id = 22482; + break; + } + } + break; + } + } + + // processed charge only counting case + if(!triggered_spell_id) + return true; + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",hasteSpell->Id,triggered_spell_id); + return false; + } + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + if(basepoints0) + CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + else + CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown) +{ + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = 0; + Unit* target = pVictim; + int32 basepoints0 = 0; + + switch(dummySpell->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + switch (dummySpell->Id) + { + // Eye of Eye + case 9799: + case 25988: + { + // prevent damage back from weapon special attacks + if (!procSpell || procSpell->DmgClass != SPELL_DAMAGE_CLASS_MAGIC ) + return false; + + // return damage % to attacker but < 50% own total health + basepoints0 = triggeredByAura->GetModifier()->m_amount*int32(damage)/100; + if(basepoints0 > GetMaxHealth()/2) + basepoints0 = GetMaxHealth()/2; + + triggered_spell_id = 25997; + break; + } + // Sweeping Strikes + case 12328: + case 18765: + case 35429: + { + // prevent chain of triggred spell from same triggred spell + if(procSpell && procSpell->Id==26654) + return false; + + target = SelectNearbyTarget(); + if(!target) + return false; + + triggered_spell_id = 26654; + break; + } + // Unstable Power + case 24658: + { + if (!procSpell || procSpell->Id == 24659) + return false; + // Need remove one 24659 aura + RemoveSingleAuraFromStack(24659, 0); + RemoveSingleAuraFromStack(24659, 1); + return true; + } + // Restless Strength + case 24661: + { + // Need remove one 24662 aura + RemoveSingleAuraFromStack(24662, 0); + return true; + } + // Adaptive Warding (Frostfire Regalia set) + case 28764: + { + if(!procSpell) + return false; + + // find Mage Armor + bool found = false; + AuraList const& mRegenInterupt = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); + for(AuraList::const_iterator iter = mRegenInterupt.begin(); iter != mRegenInterupt.end(); ++iter) + { + if(SpellEntry const* iterSpellProto = (*iter)->GetSpellProto()) + { + if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & 0x10000000)) + { + found=true; + break; + } + } + } + if(!found) + return false; + + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + case SPELL_SCHOOL_NORMAL: + case SPELL_SCHOOL_HOLY: + return false; // ignored + case SPELL_SCHOOL_FIRE: triggered_spell_id = 28765; break; + case SPELL_SCHOOL_NATURE: triggered_spell_id = 28768; break; + case SPELL_SCHOOL_FROST: triggered_spell_id = 28766; break; + case SPELL_SCHOOL_SHADOW: triggered_spell_id = 28769; break; + case SPELL_SCHOOL_ARCANE: triggered_spell_id = 28770; break; + default: + return false; + } + + target = this; + break; + } + // Obsidian Armor (Justice Bearer`s Pauldrons shoulder) + case 27539: + { + if(!procSpell) + return false; + + // not from DoT + bool found = false; + for(int j = 0; j < 3; ++j) + { + if(procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE||procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE_PERCENT) + { + found = true; + break; + } + } + if(found) + return false; + + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + case SPELL_SCHOOL_NORMAL: + return false; // ignore + case SPELL_SCHOOL_HOLY: triggered_spell_id = 27536; break; + case SPELL_SCHOOL_FIRE: triggered_spell_id = 27533; break; + case SPELL_SCHOOL_NATURE: triggered_spell_id = 27538; break; + case SPELL_SCHOOL_FROST: triggered_spell_id = 27534; break; + case SPELL_SCHOOL_SHADOW: triggered_spell_id = 27535; break; + case SPELL_SCHOOL_ARCANE: triggered_spell_id = 27540; break; + default: + return false; + } + + target = this; + break; + } + // Mana Leech (Passive) (Priest Pet Aura) + case 28305: + { + // Cast on owner + target = GetOwner(); + if(!target) + return false; + + basepoints0 = int32(damage * 2.5f); // manaregen + triggered_spell_id = 34650; + break; + } + // Mark of Malice + case 33493: + { + // Cast finish spell at last charge + if (triggeredByAura->m_procCharges > 1) + return false; + + target = this; + triggered_spell_id = 33494; + break; + } + // Twisted Reflection (boss spell) + case 21063: + triggered_spell_id = 21064; + break; + // Vampiric Aura (boss spell) + case 38196: + { + basepoints0 = 3 * damage; // 300% + if (basepoints0 < 0) + return false; + + triggered_spell_id = 31285; + target = this; + break; + } + // Aura of Madness (Darkmoon Card: Madness trinket) + //===================================================== + // 39511 Sociopath: +35 strength (Paladin, Rogue, Druid, Warrior) + // 40997 Delusional: +70 attack power (Rogue, Hunter, Paladin, Warrior, Druid) + // 40998 Kleptomania: +35 agility (Warrior, Rogue, Paladin, Hunter, Druid) + // 40999 Megalomania: +41 damage/healing (Druid, Shaman, Priest, Warlock, Mage, Paladin) + // 41002 Paranoia: +35 spell/melee/ranged crit strike rating (All classes) + // 41005 Manic: +35 haste (spell, melee and ranged) (All classes) + // 41009 Narcissism: +35 intellect (Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter) + // 41011 Martyr Complex: +35 stamina (All classes) + // 41406 Dementia: Every 5 seconds either gives you +5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) + // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) + case 39446: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Select class defined buff + switch (getClass()) + { + case CLASS_PALADIN: // 39511,40997,40998,40999,41002,41005,41009,41011,41409 + case CLASS_DRUID: // 39511,40997,40998,40999,41002,41005,41009,41011,41409 + { + uint32 RandomSpell[]={39511,40997,40998,40999,41002,41005,41009,41011,41409}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + case CLASS_ROGUE: // 39511,40997,40998,41002,41005,41011 + case CLASS_WARRIOR: // 39511,40997,40998,41002,41005,41011 + { + uint32 RandomSpell[]={39511,40997,40998,41002,41005,41011}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + case CLASS_PRIEST: // 40999,41002,41005,41009,41011,41406,41409 + case CLASS_SHAMAN: // 40999,41002,41005,41009,41011,41406,41409 + case CLASS_MAGE: // 40999,41002,41005,41009,41011,41406,41409 + case CLASS_WARLOCK: // 40999,41002,41005,41009,41011,41406,41409 + { + uint32 RandomSpell[]={40999,41002,41005,41009,41011,41406,41409}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + case CLASS_HUNTER: // 40997,40999,41002,41005,41009,41011,41406,41409 + { + uint32 RandomSpell[]={40997,40999,41002,41005,41009,41011,41406,41409}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + default: + return false; + } + + target = this; + if (roll_chance_i(10)) + ((Player*)this)->Say("This is Madness!", LANG_UNIVERSAL); + break; + } + /* + // TODO: need find item for aura and triggered spells + // Sunwell Exalted Caster Neck (??? neck) + // cast ??? Light's Wrath if Exalted by Aldor + // cast ??? Arcane Bolt if Exalted by Scryers*/ + case 46569: + return false; // disable for while + /* + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = ??? + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = ??? + break; + } + return false; + }/**/ + // Sunwell Exalted Caster Neck (Shattered Sun Pendant of Acumen neck) + // cast 45479 Light's Wrath if Exalted by Aldor + // cast 45429 Arcane Bolt if Exalted by Scryers + case 45481: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45479; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45429; + break; + } + return false; + } + // Sunwell Exalted Melee Neck (Shattered Sun Pendant of Might neck) + // cast 45480 Light's Strength if Exalted by Aldor + // cast 45428 Arcane Strike if Exalted by Scryers + case 45482: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45480; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45428; + break; + } + return false; + } + // Sunwell Exalted Tank Neck (Shattered Sun Pendant of Resolve neck) + // cast 45431 Arcane Insight if Exalted by Aldor + // cast 45432 Light's Ward if Exalted by Scryers + case 45483: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45432; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45431; + break; + } + return false; + } + // Sunwell Exalted Healer Neck (Shattered Sun Pendant of Restoration neck) + // cast 45478 Light's Salvation if Exalted by Aldor + // cast 45430 Arcane Surge if Exalted by Scryers + case 45484: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45478; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45430; + break; + } + return false; + } + } + break; + } + case SPELLFAMILY_MAGE: + { + // Magic Absorption + if (dummySpell->SpellIconID == 459) // only this spell have SpellIconID == 459 and dummy aura + { + if (getPowerType() != POWER_MANA) + return false; + + // mana reward + basepoints0 = (triggeredByAura->GetModifier()->m_amount * GetMaxPower(POWER_MANA) / 100); + target = this; + triggered_spell_id = 29442; + break; + } + // Master of Elements + if (dummySpell->SpellIconID == 1920) + { + if(!procSpell) + return false; + + // mana cost save + basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100; + if( basepoints0 <=0 ) + return false; + + target = this; + triggered_spell_id = 29077; + break; + } + switch(dummySpell->Id) + { + // Ignite + case 11119: + case 11120: + case 12846: + case 12847: + case 12848: + { + switch (dummySpell->Id) + { + case 11119: basepoints0 = int32(0.04f*damage); break; + case 11120: basepoints0 = int32(0.08f*damage); break; + case 12846: basepoints0 = int32(0.12f*damage); break; + case 12847: basepoints0 = int32(0.16f*damage); break; + case 12848: basepoints0 = int32(0.20f*damage); break; + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (IG)",dummySpell->Id); + return false; + } + + triggered_spell_id = 12654; + break; + } + // Combustion + case 11129: + { + //last charge and crit + if( triggeredByAura->m_procCharges <= 1 && (procFlag & PROC_FLAG_CRIT_SPELL) ) + { + RemoveAurasDueToSpell(28682); //-> remove Combustion auras + return true; // charge counting (will removed) + } + + CastSpell(this, 28682, true, castItem, triggeredByAura); + return(procFlag & PROC_FLAG_CRIT_SPELL);// charge update only at crit hits, no hidden cooldowns + } + } + break; + } + case SPELLFAMILY_WARRIOR: + { + // Retaliation + if(dummySpell->SpellFamilyFlags==0x0000000800000000LL) + { + // check attack comes not from behind + if (!HasInArc(M_PI, pVictim)) + return false; + + triggered_spell_id = 22858; + break; + } + break; + } + case SPELLFAMILY_WARLOCK: + { + // Seed of Corruption + if (dummySpell->SpellFamilyFlags & 0x0000001000000000LL) + { + Modifier* mod = triggeredByAura->GetModifier(); + // if damage is more than need or target die from damage deal finish spell + // FIX ME: not triggered currently at death + if( mod->m_amount <= damage || GetHealth() <= damage ) + { + // remember guid before aura delete + uint64 casterGuid = triggeredByAura->GetCasterGUID(); + + // Remove aura (before cast for prevent infinite loop handlers) + RemoveAurasDueToSpell(triggeredByAura->GetId()); + + // Cast finish spell (triggeredByAura already not exist!) + CastSpell(this, 27285, true, castItem, NULL, casterGuid); + return true; // no hidden cooldown + } + + // Damage counting + mod->m_amount-=damage; + return true; + } + // Seed of Corruption (Mobs cast) - no die req + if (dummySpell->SpellFamilyFlags == 0x00LL && dummySpell->SpellIconID == 1932) + { + Modifier* mod = triggeredByAura->GetModifier(); + // if damage is more than need deal finish spell + if( mod->m_amount <= damage ) + { + // remember guid before aura delete + uint64 casterGuid = triggeredByAura->GetCasterGUID(); + + // Remove aura (before cast for prevent infinite loop handlers) + RemoveAurasDueToSpell(triggeredByAura->GetId()); + + // Cast finish spell (triggeredByAura already not exist!) + CastSpell(this, 32865, true, castItem, NULL, casterGuid); + return true; // no hidden cooldown + } + // Damage counting + mod->m_amount-=damage; + return true; + } + switch(dummySpell->Id) + { + // Nightfall + case 18094: + case 18095: + { + target = this; + triggered_spell_id = 17941; + break; + } + //Soul Leech + case 30293: + case 30295: + case 30296: + { + // health + basepoints0 = int32(damage*triggeredByAura->GetModifier()->m_amount/100); + target = this; + triggered_spell_id = 30294; + break; + } + // Shadowflame (Voidheart Raiment set bonus) + case 37377: + { + triggered_spell_id = 37379; + break; + } + // Pet Healing (Corruptor Raiment or Rift Stalker Armor) + case 37381: + { + target = GetPet(); + if(!target) + return false; + + // heal amount + basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100; + triggered_spell_id = 37382; + break; + } + // Shadowflame Hellfire (Voidheart Raiment set bonus) + case 39437: + { + triggered_spell_id = 37378; + break; + } + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Vampiric Touch + if( dummySpell->SpellFamilyFlags & 0x0000040000000000LL ) + { + if(!pVictim || !pVictim->isAlive()) + return false; + + // pVictim is caster of aura + if(triggeredByAura->GetCasterGUID() != pVictim->GetGUID()) + return false; + + // energize amount + basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100; + pVictim->CastCustomSpell(pVictim,34919,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + return true; // no hidden cooldown + } + switch(dummySpell->Id) + { + // Vampiric Embrace + case 15286: + { + if(!pVictim || !pVictim->isAlive()) + return false; + + // pVictim is caster of aura + if(triggeredByAura->GetCasterGUID() != pVictim->GetGUID()) + return false; + + // heal amount + basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100; + pVictim->CastCustomSpell(pVictim,15290,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + return true; // no hidden cooldown + } + // Priest Tier 6 Trinket (Ashtongue Talisman of Acumen) + case 40438: + { + // Shadow Word: Pain + if( procSpell->SpellFamilyFlags & 0x0000000000008000LL ) + triggered_spell_id = 40441; + // Renew + else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL ) + triggered_spell_id = 40440; + else + return false; + + target = this; + break; + } + // Oracle Healing Bonus ("Garments of the Oracle" set) + case 26169: + { + // heal amount + basepoints0 = int32(damage * 10/100); + target = this; + triggered_spell_id = 26170; + break; + } + // Frozen Shadoweave (Shadow's Embrace set) warning! its not only priest set + case 39372: + { + if(!procSpell || (GetSpellSchoolMask(procSpell) & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW))==0 ) + return false; + + // heal amount + basepoints0 = int32(damage * 2 / 100); + target = this; + triggered_spell_id = 39373; + break; + } + // Vestments of Faith (Priest Tier 3) - 4 pieces bonus + case 28809: + { + triggered_spell_id = 28810; + break; + } + } + break; + } + case SPELLFAMILY_DRUID: + { + switch(dummySpell->Id) + { + // Healing Touch (Dreamwalker Raiment set) + case 28719: + { + // mana back + basepoints0 = int32(procSpell->manaCost * 30 / 100); + target = this; + triggered_spell_id = 28742; + break; + } + // Healing Touch Refund (Idol of Longevity trinket) + case 28847: + { + target = this; + triggered_spell_id = 28848; + break; + } + // Mana Restore (Malorne Raiment set / Malorne Regalia set) + case 37288: + case 37295: + { + target = this; + triggered_spell_id = 37238; + break; + } + // Druid Tier 6 Trinket + case 40442: + { + float chance; + + // Starfire + if( procSpell->SpellFamilyFlags & 0x0000000000000004LL ) + { + triggered_spell_id = 40445; + chance = 25.f; + } + // Rejuvenation + else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL ) + { + triggered_spell_id = 40446; + chance = 25.f; + } + // Mangle (cat/bear) + else if( procSpell->SpellFamilyFlags & 0x0000044000000000LL ) + { + triggered_spell_id = 40452; + chance = 40.f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + target = this; + break; + } + // Maim Interrupt + case 44835: + { + // Deadly Interrupt Effect + triggered_spell_id = 32747; + break; + } + } + break; + } + case SPELLFAMILY_ROGUE: + { + switch(dummySpell->Id) + { + // Deadly Throw Interrupt + case 32748: + { + // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw + if(this == pVictim) + return false; + + triggered_spell_id = 32747; + break; + } + } + // Quick Recovery + if( dummySpell->SpellIconID == 2116 ) + { + if(!procSpell) + return false; + + // only rogue's finishing moves (maybe need additional checks) + if( procSpell->SpellFamilyName!=SPELLFAMILY_ROGUE || + (procSpell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE) == 0) + return false; + + // energy cost save + basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100; + if(basepoints0 <= 0) + return false; + + target = this; + triggered_spell_id = 31663; + break; + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Thrill of the Hunt + if ( dummySpell->SpellIconID == 2236 ) + { + if(!procSpell) + return false; + + // mana cost save + basepoints0 = procSpell->manaCost * 40/100; + if(basepoints0 <= 0) + return false; + + target = this; + triggered_spell_id = 34720; + break; + } + break; + } + case SPELLFAMILY_PALADIN: + { + // Seal of Righteousness - melee proc dummy + if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0) + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + uint32 spellId; + switch (triggeredByAura->GetId()) + { + case 21084: spellId = 25742; break; // Rank 1 + case 20287: spellId = 25740; break; // Rank 2 + case 20288: spellId = 25739; break; // Rank 3 + case 20289: spellId = 25738; break; // Rank 4 + case 20290: spellId = 25737; break; // Rank 5 + case 20291: spellId = 25736; break; // Rank 6 + case 20292: spellId = 25735; break; // Rank 7 + case 20293: spellId = 25713; break; // Rank 8 + case 27155: spellId = 27156; break; // Rank 9 + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled possibly SoR (Id = %u)", triggeredByAura->GetId()); + return false; + } + Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + float speed = (item ? item->GetProto()->Delay : BASE_ATTACK_TIME)/1000.0f; + + float damageBasePoints; + if(item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON) + // two hand weapon + damageBasePoints=1.20f*triggeredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f + 1; + else + // one hand weapon/no weapon + damageBasePoints=0.85f*ceil(triggeredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f) - 1; + + int32 damagePoint = int32(damageBasePoints + 0.03f * (GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE)+GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE))/2.0f) + 1; + + // apply damage bonuses manually + if(damagePoint >= 0) + damagePoint = SpellDamageBonus(pVictim, dummySpell, damagePoint, SPELL_DIRECT_DAMAGE); + + CastCustomSpell(pVictim,spellId,&damagePoint,NULL,NULL,true,NULL, triggeredByAura); + return true; // no hidden cooldown + } + // Seal of Blood do damage trigger + if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL) + { + switch(triggeredByAura->GetEffIndex()) + { + case 0: + // prevent chain triggering + if(procSpell && procSpell->Id==31893 ) + return false; + + triggered_spell_id = 31893; + break; + case 1: + { + // damage + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + target = this; + triggered_spell_id = 32221; + break; + } + } + } + + switch(dummySpell->Id) + { + // Holy Power (Redemption Armor set) + case 28789: + { + if(!pVictim) + return false; + + // Set class defined buff + switch (pVictim->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + triggered_spell_id = 28795; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + triggered_spell_id = 28793; // Increases the friendly target's spell damage and healing by up to $s1 for $d. + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + triggered_spell_id = 28791; // Increases the friendly target's attack power by $s1 for $d. + break; + case CLASS_WARRIOR: + triggered_spell_id = 28790; // Increases the friendly target's armor + break; + default: + return false; + } + break; + } + //Seal of Vengeance + case 31801: + { + if(effIndex != 0) // effect 1,2 used by seal unleashing code + return false; + + triggered_spell_id = 31803; + break; + } + // Spiritual Att. + case 31785: + case 33776: + { + // if healed by another unit (pVictim) + if(this == pVictim) + return false; + + // heal amount + basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100; + target = this; + triggered_spell_id = 31786; + break; + } + // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) + case 40470: + { + if( !procSpell ) + return false; + + float chance; + + // Flash of light/Holy light + if( procSpell->SpellFamilyFlags & 0x00000000C0000000LL) + { + triggered_spell_id = 40471; + chance = 15.f; + } + // Judgement + else if( procSpell->SpellFamilyFlags & 0x0000000000800000LL ) + { + triggered_spell_id = 40472; + chance = 50.f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + break; + } + } + break; + } + case SPELLFAMILY_SHAMAN: + { + switch(dummySpell->Id) + { + // Totemic Power (The Earthshatterer set) + case 28823: + { + if( !pVictim ) + return false; + + // Set class defined buff + switch (pVictim->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + triggered_spell_id = 28824; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + triggered_spell_id = 28825; // Increases the friendly target's spell damage and healing by up to $s1 for $d. + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + triggered_spell_id = 28826; // Increases the friendly target's attack power by $s1 for $d. + break; + case CLASS_WARRIOR: + triggered_spell_id = 28827; // Increases the friendly target's armor + break; + default: + return false; + } + break; + } + // Lesser Healing Wave (Totem of Flowing Water Relic) + case 28849: + { + target = this; + triggered_spell_id = 28850; + break; + } + // Windfury Weapon (Passive) 1-5 Ranks + case 33757: + { + if(GetTypeId()!=TYPEID_PLAYER) + return false; + + if(!castItem || !castItem->IsEquipped()) + return false; + + // custom cooldown processing case + if( cooldown && ((Player*)this)->HasSpellCooldown(dummySpell->Id)) + return false; + + uint32 spellId; + switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT))) + { + case 283: spellId = 33757; break; //1 Rank + case 284: spellId = 33756; break; //2 Rank + case 525: spellId = 33755; break; //3 Rank + case 1669:spellId = 33754; break; //4 Rank + case 2636:spellId = 33727; break; //5 Rank + default: + { + sLog.outError("Unit::HandleDummyAuraProc: non handled item enchantment (rank?) %u for spell id: %u (Windfury)", + castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)),dummySpell->Id); + return false; + } + } + + SpellEntry const* windfurySpellEntry = sSpellStore.LookupEntry(spellId); + if(!windfurySpellEntry) + { + sLog.outError("Unit::HandleDummyAuraProc: non existed spell id: %u (Windfury)",spellId); + return false; + } + + int32 extra_attack_power = CalculateSpellDamage(windfurySpellEntry,0,windfurySpellEntry->EffectBasePoints[0],pVictim); + + // Off-Hand case + if ( castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND ) + { + // Value gained from additional AP + basepoints0 = int32(extra_attack_power/14.0f * GetAttackTime(OFF_ATTACK)/1000/2); + triggered_spell_id = 33750; + } + // Main-Hand case + else + { + // Value gained from additional AP + basepoints0 = int32(extra_attack_power/14.0f * GetAttackTime(BASE_ATTACK)/1000); + triggered_spell_id = 25504; + } + + // apply cooldown before cast to prevent processing itself + if( cooldown ) + ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); + + // Attack Twice + for ( uint32 i = 0; i<2; ++i ) + CastCustomSpell(pVictim,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + + return true; + } + // Shaman Tier 6 Trinket + case 40463: + { + if( !procSpell ) + return false; + + float chance; + if (procSpell->SpellFamilyFlags & 0x0000000000000001LL) + { + triggered_spell_id = 40465; // Lightning Bolt + chance = 15.f; + } + else if (procSpell->SpellFamilyFlags & 0x0000000000000080LL) + { + triggered_spell_id = 40465; // Lesser Healing Wave + chance = 10.f; + } + else if (procSpell->SpellFamilyFlags & 0x0000001000000000LL) + { + triggered_spell_id = 40466; // Stormstrike + chance = 50.f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + target = this; + break; + } + } + + // Earth Shield + if(dummySpell->SpellFamilyFlags==0x40000000000LL) + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // heal + basepoints0 = triggeredByAura->GetModifier()->m_amount; + target = this; + triggered_spell_id = 379; + break; + } + // Lightning Overload + if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura + { + if(!procSpell || GetTypeId() != TYPEID_PLAYER || !pVictim ) + return false; + + // custom cooldown processing case + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(dummySpell->Id)) + return false; + + uint32 spellId = 0; + // Every Lightning Bolt and Chain Lightning spell have dublicate vs half damage and zero cost + switch (procSpell->Id) + { + // Lightning Bolt + case 403: spellId = 45284; break; // Rank 1 + case 529: spellId = 45286; break; // Rank 2 + case 548: spellId = 45287; break; // Rank 3 + case 915: spellId = 45288; break; // Rank 4 + case 943: spellId = 45289; break; // Rank 5 + case 6041: spellId = 45290; break; // Rank 6 + case 10391: spellId = 45291; break; // Rank 7 + case 10392: spellId = 45292; break; // Rank 8 + case 15207: spellId = 45293; break; // Rank 9 + case 15208: spellId = 45294; break; // Rank 10 + case 25448: spellId = 45295; break; // Rank 11 + case 25449: spellId = 45296; break; // Rank 12 + // Chain Lightning + case 421: spellId = 45297; break; // Rank 1 + case 930: spellId = 45298; break; // Rank 2 + case 2860: spellId = 45299; break; // Rank 3 + case 10605: spellId = 45300; break; // Rank 4 + case 25439: spellId = 45301; break; // Rank 5 + case 25442: spellId = 45302; break; // Rank 6 + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id); + return false; + } + // No thread generated mod + SpellModifier *mod = new SpellModifier; + mod->op = SPELLMOD_THREAT; + mod->value = -100; + mod->type = SPELLMOD_PCT; + mod->spellId = dummySpell->Id; + mod->effectId = 0; + mod->lastAffected = NULL; + mod->mask = 0x0000000000000003LL; + mod->charges = 0; + ((Player*)this)->AddSpellMod(mod, true); + + // Remove cooldown (Chain Lightning - have Category Recovery time) + if (procSpell->SpellFamilyFlags & 0x0000000000000002LL) + ((Player*)this)->RemoveSpellCooldown(spellId); + + // Hmmm.. in most case spells alredy set half basepoints but... + // Lightning Bolt (2-10 rank) have full basepoint and half bonus from level + // As on wiki: + // BUG: Rank 2 to 10 (and maybe 11) of Lightning Bolt will proc another Bolt with FULL damage (not halved). This bug is known and will probably be fixed soon. + // So - no add changes :) + CastSpell(pVictim, spellId, true, castItem, triggeredByAura); + + ((Player*)this)->AddSpellMod(mod, false); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); + + return true; + } + break; + } + default: + break; + } + + // processed charge only counting case + if(!triggered_spell_id) + return true; + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleDummyAuraProc: Spell %u have not existed triggered spell %u",dummySpell->Id,triggered_spell_id); + return false; + } + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + if(basepoints0) + CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + else + CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attackType, uint32 cooldown) +{ + SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto(); + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; + Unit* target = !(procFlags & PROC_FLAG_HEAL) && IsPositiveSpell(triggered_spell_id) ? this : pVictim; + int32 basepoints0 = 0; + + switch(auraSpellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + switch(auraSpellInfo->Id) + { + // Aegis of Preservation + case 23780: + //Aegis Heal (instead non-existed triggered spell) + triggered_spell_id = 23781; + target = this; + break; + // Elune's Touch (moonkin mana restore) + case 24905: + { + // Elune's Touch (instead non-existed triggered spell) + triggered_spell_id = 33926; + basepoints0 = int32(0.3f * GetTotalAttackPowerValue(BASE_ATTACK)); + target = this; + break; + } + // Enlightenment + case 29601: + { + // only for cast with mana price + if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0) + return false; + break; // fall through to normal cast + } + // Health Restore + case 33510: + { + // at melee hit call std triggered spell + if(procFlags & PROC_FLAG_HIT_MELEE) + break; // fall through to normal cast + + // Mark of Conquest - else (at range hit) called custom case + triggered_spell_id = 39557; + target = this; + break; + } + // Shaleskin + case 36576: + return true; // nothing to do + // Forgotten Knowledge (Blade of Wizardry) + case 38319: + // only for harmful enemy targeted spell + if(!pVictim || pVictim==this || !procSpell || IsPositiveSpell(procSpell->Id)) + return false; + break; // fall through to normal cast + // Aura of Wrath (Darkmoon Card: Wrath trinket bonus) + case 39442: + { + // proc only at non-crit hits + if(procFlags & (PROC_FLAG_CRIT_MELEE|PROC_FLAG_CRIT_RANGED|PROC_FLAG_CRIT_SPELL)) + return false; + break; // fall through to normal cast + } + // Augment Pain (Timbal's Focusing Crystal trinket bonus) + case 45054: + { + if(!procSpell) + return false; + + //only periodic damage can trigger spell + bool found = false; + for(int j = 0; j < 3; ++j) + { + if( procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE || + procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE_PERCENT || + procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_LEECH ) + { + found = true; + break; + } + } + if(!found) + return false; + + break; // fall through to normal cast + } + // Evasive Maneuvers (Commendation of Kael'thas) + case 45057: + { + // damage taken that reduces below 35% health + // does NOT mean you must have been >= 35% before + if (int32(GetHealth())-int32(damage) >= int32(GetMaxHealth()*0.35f)) + return false; + break; // fall through to normal cast + } + } + + switch(triggered_spell_id) + { + // Setup + case 15250: + { + // applied only for main target + if(!pVictim || pVictim != getVictim()) + return false; + + // continue normal case + break; + } + // Shamanistic Rage triggered spell + case 30824: + basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK)*triggeredByAura->GetModifier()->m_amount/100); + break; + } + break; + } + case SPELLFAMILY_MAGE: + { + switch(auraSpellInfo->SpellIconID) + { + // Blazing Speed + case 2127: + //Blazing Speed (instead non-existed triggered spell) + triggered_spell_id = 31643; + target = this; + break; + } + switch(auraSpellInfo->Id) + { + // Persistent Shield (Scarab Brooch) + case 26467: + basepoints0 = int32(damage * 0.15f); + break; + } + break; + } + case SPELLFAMILY_WARRIOR: + { + //Rampage + if((auraSpellInfo->SpellFamilyFlags & 0x100000) && auraSpellInfo->SpellIconID==2006) + { + //all ranks have effect[0]==AURA (Proc Trigger Spell, non-existed) + //and effect[1]==TriggerSpell + if(auraSpellInfo->Effect[1]!=SPELL_EFFECT_TRIGGER_SPELL) + { + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have wrong effect in RM",triggeredByAura->GetSpellProto()->Id); + return false; + } + triggered_spell_id = auraSpellInfo->EffectTriggerSpell[1]; + break; // fall through to normal cast + } + break; + } + case SPELLFAMILY_WARLOCK: + { + // Pyroclasm + if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000 && auraSpellInfo->SpellIconID==1137) + { + // last case for Hellfire that damage caster also but don't must stun caster + if( pVictim == this ) + return false; + + // custom chnace + float chance = 0; + switch (triggeredByAura->GetId()) + { + case 18096: chance = 13.0f; break; + case 18073: chance = 26.0f; break; + } + if (!roll_chance_f(chance)) + return false; + + // Pyroclasm (instead non-existed triggered spell) + triggered_spell_id = 18093; + target = pVictim; + break; + } + // Drain Soul + if(auraSpellInfo->SpellFamilyFlags & 0x0000000000004000) + { + bool found = false; + Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); + for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) + { + //Improved Drain Soul + if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113) + { + int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this); + basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100; + + // Drain Soul + triggered_spell_id = 18371; + target = this; + found = true; + break; + } + } + if(!found) + return false; + break; // fall through to normal cast + } + break; + } + case SPELLFAMILY_PRIEST: + { + //Blessed Recovery + if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL && auraSpellInfo->SpellIconID==1875) + { + switch (triggeredByAura->GetSpellProto()->Id) + { + case 27811: triggered_spell_id = 27813; break; + case 27815: triggered_spell_id = 27817; break; + case 27816: triggered_spell_id = 27818; break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR",triggeredByAura->GetSpellProto()->Id); + return false; + } + + int32 heal_amount = damage * triggeredByAura->GetModifier()->m_amount / 100; + basepoints0 = heal_amount/3; + target = this; + break; + } + // Shadowguard + if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958) + { + switch(triggeredByAura->GetSpellProto()->Id) + { + case 18137: + triggered_spell_id = 28377; break; // Rank 1 + case 19308: + triggered_spell_id = 28378; break; // Rank 2 + case 19309: + triggered_spell_id = 28379; break; // Rank 3 + case 19310: + triggered_spell_id = 28380; break; // Rank 4 + case 19311: + triggered_spell_id = 28381; break; // Rank 5 + case 19312: + triggered_spell_id = 28382; break; // Rank 6 + case 25477: + triggered_spell_id = 28385; break; // Rank 7 + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG",triggeredByAura->GetSpellProto()->Id); + return false; + } + target = pVictim; + break; + } + break; + } + case SPELLFAMILY_DRUID: + { + switch(auraSpellInfo->Id) + { + // Leader of the Pack (triggering Improved Leader of the Pack heal) + case 24932: + { + if (triggeredByAura->GetModifier()->m_amount == 0) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100; + triggered_spell_id = 34299; + break; + }; + // Druid Forms Trinket (Druid Tier5 Trinket, triggers different spells per Form) + case 37336: + { + switch(m_form) + { + case FORM_BEAR: + case FORM_DIREBEAR: + triggered_spell_id=37340; break;// Ursine Blessing + case FORM_CAT: + triggered_spell_id=37341; break;// Feline Blessing + case FORM_TREE: + triggered_spell_id=37342; break;// Slyvan Blessing + case FORM_MOONKIN: + triggered_spell_id=37343; break;// Lunar Blessing + case FORM_NONE: + triggered_spell_id=37344; break;// Cenarion Blessing (for caster form, except FORM_MOONKIN) + default: + return false; + } + + target = this; + break; + } + } + break; + } + case SPELLFAMILY_ROGUE: + { + if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000LL) + { + switch(auraSpellInfo->SpellIconID) + { + // Combat Potency + case 2260: + { + // skip non offhand attacks + if(attackType!=OFF_ATTACK) + return false; + break; // fall through to normal cast + } + } + } + break; + } + case SPELLFAMILY_PALADIN: + { + if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL) + { + switch(auraSpellInfo->Id) + { + // Lightning Capacitor + case 37657: + { + // trinket ProcTriggerSpell but for safe checks for player + if(!castItem || !pVictim || !pVictim->isAlive() || GetTypeId()!=TYPEID_PLAYER) + return false; + + if(((Player*)this)->HasSpellCooldown(37657)) + return false; + + // stacking + CastSpell(this, 37658, true, castItem, triggeredByAura); + // 2.5s cooldown before it can stack again, current system allow 1 sec step in cooldown + ((Player*)this)->AddSpellCooldown(37657,0,time(NULL)+(roll_chance_i(50) ? 2 : 3)); + + // counting + uint32 count = 0; + AuraList const& dummyAura = GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator itr = dummyAura.begin(); itr != dummyAura.end(); ++itr) + if((*itr)->GetId()==37658) + ++count; + + // release at 3 aura in stack + if(count <= 2) + return true; // main triggered spell casted anyway + + RemoveAurasDueToSpell(37658); + CastSpell(pVictim, 37661, true, castItem, triggeredByAura); + return true; + } + // Healing Discount + case 37705: + // Healing Trance (instead non-existed triggered spell) + triggered_spell_id = 37706; + target = this; + break; + // HoTs on Heals (Fel Reaver's Piston trinket) + case 38299: + { + // at direct heal effect + if(!procSpell || !IsSpellHaveEffect(procSpell,SPELL_EFFECT_HEAL)) + return false; + + // single proc at time + AuraList const& scAuras = GetSingleCastAuras(); + for(AuraList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr) + if((*itr)->GetId()==triggered_spell_id) + return false; + + // positive cast at victim instead self + target = pVictim; + break; + } + } + switch(auraSpellInfo->SpellIconID) + { + case 241: + { + switch(auraSpellInfo->EffectTriggerSpell[0]) + { + //Illumination + case 18350: + { + if(!procSpell) + return false; + + // procspell is triggered spell but we need mana cost of original casted spell + uint32 originalSpellId = procSpell->Id; + + // Holy Shock + if(procSpell->SpellFamilyName == SPELLFAMILY_PALADIN) + { + if(procSpell->SpellFamilyFlags & 0x0001000000000000LL) + { + switch(procSpell->Id) + { + case 25914: originalSpellId = 20473; break; + case 25913: originalSpellId = 20929; break; + case 25903: originalSpellId = 20930; break; + case 27175: originalSpellId = 27174; break; + case 33074: originalSpellId = 33072; break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id); + return false; + } + } + } + + SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); + if(!originalSpell) + { + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId); + return false; + } + + // percent stored in effect 1 (class scripts) base points + int32 percent = auraSpellInfo->EffectBasePoints[1]+1; + + basepoints0 = originalSpell->manaCost*percent/100; + triggered_spell_id = 20272; + target = this; + break; + } + } + break; + } + } + } + if(auraSpellInfo->SpellFamilyFlags & 0x00080000) + { + switch(auraSpellInfo->SpellIconID) + { + //Judgement of Wisdom (overwrite non existing triggered spell call in spell.dbc + case 206: + { + if(!pVictim || !pVictim->isAlive()) + return false; + + uint32 spell = 0; + switch(triggeredByAura->GetSpellProto()->Id) + { + case 20186: + triggered_spell_id = 20268; // Rank 1 + break; + case 20354: + triggered_spell_id = 20352; // Rank 2 + break; + case 20355: + triggered_spell_id = 20353; // Rank 3 + break; + case 27164: + triggered_spell_id = 27165; // Rank 4 + break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoW",triggeredByAura->GetSpellProto()->Id); + return false; + } + + pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID()); + return true; // no hidden cooldown + } + //Judgement of Light + case 299: + { + if(!pVictim || !pVictim->isAlive()) + return false; + + // overwrite non existing triggered spell call in spell.dbc + uint32 spell = 0; + switch(triggeredByAura->GetSpellProto()->Id) + { + case 20185: + triggered_spell_id = 20267; // Rank 1 + break; + case 20344: + triggered_spell_id = 20341; // Rank 2 + break; + case 20345: + triggered_spell_id = 20342; // Rank 3 + break; + case 20346: + triggered_spell_id = 20343; // Rank 4 + break; + case 27162: + triggered_spell_id = 27163; // Rank 5 + break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoL",triggeredByAura->GetSpellProto()->Id); + return false; + } + pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID()); + return true; // no hidden cooldown + } + } + } + // custom check for proc spell + switch(auraSpellInfo->Id) + { + // Bonus Healing (item spell) + case 40971: + { + if(!pVictim || !pVictim->isAlive()) + return false; + + // bonus if health < 50% + if(pVictim->GetHealth() >= pVictim->GetMaxHealth()*triggeredByAura->GetModifier()->m_amount/100) + return false; + + // cast at target positive spell + target = pVictim; + break; + } + } + switch(triggered_spell_id) + { + // Seal of Command + case 20424: + // prevent chain of triggered spell from same triggered spell + if(procSpell && procSpell->Id==20424) + return false; + break; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000) + { + switch(auraSpellInfo->SpellIconID) + { + case 19: + { + switch(auraSpellInfo->Id) + { + case 23551: // Lightning Shield - Tier2: 8 pieces proc shield + { + // Lightning Shield (overwrite non existing triggered spell call in spell.dbc) + triggered_spell_id = 23552; + target = pVictim; + break; + } + case 23552: // Lightning Shield - trigger shield damage + { + // Lightning Shield (overwrite non existing triggered spell call in spell.dbc) + triggered_spell_id = 27635; + target = pVictim; + break; + } + } + break; + } + // Mana Surge (Shaman T1 bonus) + case 87: + { + if(!procSpell) + return false; + + basepoints0 = procSpell->manaCost * 35/100; + triggered_spell_id = 23571; + target = this; + break; + } + //Nature's Guardian + case 2013: + { + if(GetTypeId()!=TYPEID_PLAYER) + return false; + + // damage taken that reduces below 30% health + // does NOT mean you must have been >= 30% before + if (10*(int32(GetHealth())-int32(damage)) >= 3*GetMaxHealth()) + return false; + + triggered_spell_id = 31616; + + // need check cooldown now + if( cooldown && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100; + target = this; + if(pVictim && pVictim->isAlive()) + pVictim->getThreatManager().modifyThreatPercent(this,-10); + break; + } + } + } + + // Water Shield (we can't set cooldown for main spell - it's player casted spell + if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358) + { + target = this; + break; + } + + // Lightning Shield + if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37) + { + // overwrite non existing triggered spell call in spell.dbc + switch(triggeredByAura->GetSpellProto()->Id) + { + case 324: + triggered_spell_id = 26364; break; // Rank 1 + case 325: + triggered_spell_id = 26365; break; // Rank 2 + case 905: + triggered_spell_id = 26366; break; // Rank 3 + case 945: + triggered_spell_id = 26367; break; // Rank 4 + case 8134: + triggered_spell_id = 26369; break; // Rank 5 + case 10431: + triggered_spell_id = 26370; break; // Rank 6 + case 10432: + triggered_spell_id = 26363; break; // Rank 7 + case 25469: + triggered_spell_id = 26371; break; // Rank 8 + case 25472: + triggered_spell_id = 26372; break; // Rank 9 + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield",triggeredByAura->GetSpellProto()->Id); + return false; + } + + target = pVictim; + break; + } + break; + } + } + + // standard non-dummy case + if(!triggered_spell_id) + { + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex()); + return false; + } + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have not existed EffectTriggered[%d]=%u, not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex(),triggered_spell_id); + return false; + } + + // not allow proc extra attack spell at extra attack + if( m_extraAttacks && IsSpellHaveEffect(triggerEntry,SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if(basepoints0) + CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + else + CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) +{ + if(!pVictim || !pVictim->isAlive()) + return false; + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = 0; + + switch(scriptId) + { + case 836: // Improved Blizzard (Rank 1) + { + if( !procSpell || procSpell->SpellVisual!=9487 ) + return false; + triggered_spell_id = 12484; + break; + } + case 988: // Improved Blizzard (Rank 2) + { + if( !procSpell || procSpell->SpellVisual!=9487 ) + return false; + triggered_spell_id = 12485; + break; + } + case 989: // Improved Blizzard (Rank 3) + { + if( !procSpell || procSpell->SpellVisual!=9487 ) + return false; + triggered_spell_id = 12486; + break; + } + case 4086: // Improved Mend Pet (Rank 1) + case 4087: // Improved Mend Pet (Rank 2) + { + int32 chance = triggeredByAura->GetSpellProto()->EffectBasePoints[triggeredByAura->GetEffIndex()]; + if(!roll_chance_i(chance)) + return false; + + triggered_spell_id = 24406; + break; + } + case 4533: // Dreamwalker Raiment 2 pieces bonus + { + // Chance 50% + if (!roll_chance_i(50)) + return false; + + switch (pVictim->getPowerType()) + { + case POWER_MANA: triggered_spell_id = 28722; break; + case POWER_RAGE: triggered_spell_id = 28723; break; + case POWER_ENERGY: triggered_spell_id = 28724; break; + default: + return false; + } + break; + } + case 4537: // Dreamwalker Raiment 6 pieces bonus + triggered_spell_id = 28750; // Blessing of the Claw + break; + case 5497: // Improved Mana Gems (Serpent-Coil Braid) + triggered_spell_id = 37445; // Mana Surge + break; + } + + // not processed + if(!triggered_spell_id) + return false; + + // standard non-dummy case + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleOverrideClassScriptAuraProc: Spell %u triggering for class script id %u",triggered_spell_id,scriptId); + return false; + } + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + CastSpell(pVictim, triggered_spell_id, true, castItem, triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +void Unit::setPowerType(Powers new_powertype) +{ + SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype); + + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); + } + } + + switch(new_powertype) + { + default: + case POWER_MANA: + break; + case POWER_RAGE: + SetMaxPower(POWER_RAGE,GetCreatePowers(POWER_RAGE)); + SetPower( POWER_RAGE,0); + break; + case POWER_FOCUS: + SetMaxPower(POWER_FOCUS,GetCreatePowers(POWER_FOCUS)); + SetPower( POWER_FOCUS,GetCreatePowers(POWER_FOCUS)); + break; + case POWER_ENERGY: + SetMaxPower(POWER_ENERGY,GetCreatePowers(POWER_ENERGY)); + SetPower( POWER_ENERGY,0); + break; + case POWER_HAPPINESS: + SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); + SetPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); + break; + } +} + +FactionTemplateEntry const* Unit::getFactionTemplateEntry() const +{ + FactionTemplateEntry const* entry = sFactionTemplateStore.LookupEntry(getFaction()); + if(!entry) + { + static uint64 guid = 0; // prevent repeating spam same faction problem + + if(GetGUID() != guid) + { + if(GetTypeId() == TYPEID_PLAYER) + sLog.outError("Player %s have invalid faction (faction template id) #%u", ((Player*)this)->GetName(), getFaction()); + else + sLog.outError("Creature (template id: %u) have invalid faction (faction template id) #%u", ((Creature*)this)->GetCreatureInfo()->Entry, getFaction()); + guid = GetGUID(); + } + } + return entry; +} + +bool Unit::IsHostileTo(Unit const* unit) const +{ + // always non-hostile to self + if(unit==this) + return false; + + // always non-hostile to GM in GM mode + if(unit->GetTypeId()==TYPEID_PLAYER && ((Player const*)unit)->isGameMaster()) + return false; + + // always hostile to enemy + if(getVictim()==unit || unit->getVictim()==this) + return true; + + // test pet/charm masters instead pers/charmeds + Unit const* testerOwner = GetCharmerOrOwner(); + Unit const* targetOwner = unit->GetCharmerOrOwner(); + + // always hostile to owner's enemy + if(testerOwner && (testerOwner->getVictim()==unit || unit->getVictim()==testerOwner)) + return true; + + // always hostile to enemy owner + if(targetOwner && (getVictim()==targetOwner || targetOwner->getVictim()==this)) + return true; + + // always hostile to owner of owner's enemy + if(testerOwner && targetOwner && (testerOwner->getVictim()==targetOwner || targetOwner->getVictim()==testerOwner)) + return true; + + Unit const* tester = testerOwner ? testerOwner : this; + Unit const* target = targetOwner ? targetOwner : unit; + + // always non-hostile to target with common owner, or to owner/pet + if(tester==target) + return false; + + // special cases (Duel, etc) + if(tester->GetTypeId()==TYPEID_PLAYER && target->GetTypeId()==TYPEID_PLAYER) + { + Player const* pTester = (Player const*)tester; + Player const* pTarget = (Player const*)target; + + // Duel + if(pTester->duel && pTester->duel->opponent == pTarget && pTester->duel->startTime != 0) + return true; + + // Group + if(pTester->GetGroup() && pTester->GetGroup()==pTarget->GetGroup()) + return false; + + // Sanctuary + if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY)) + return false; + + // PvP FFA state + if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP)) + return true; + + //= PvP states + // Green/Blue (can't attack) + if(pTester->GetTeam()==pTarget->GetTeam()) + return false; + + // Red (can attack) if true, Blue/Yellow (can't attack) in another case + return pTester->IsPvP() && pTarget->IsPvP(); + } + + // faction base cases + FactionTemplateEntry const*tester_faction = tester->getFactionTemplateEntry(); + FactionTemplateEntry const*target_faction = target->getFactionTemplateEntry(); + if(!tester_faction || !target_faction) + return false; + + if(target->isAttackingPlayer() && tester->IsContestedGuard()) + return true; + + // PvC forced reaction and reputation case + if(tester->GetTypeId()==TYPEID_PLAYER) + { + // forced reaction + ForcedReactions::const_iterator forceItr = ((Player*)tester)->m_forcedReactions.find(target_faction->faction); + if(forceItr!=((Player*)tester)->m_forcedReactions.end()) + return forceItr->second <= REP_HOSTILE; + + // if faction have reputation then hostile state for tester at 100% dependent from at_war state + if(FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction)) + if(raw_target_faction->reputationListID >=0) + if(FactionState const* factionState = ((Player*)tester)->GetFactionState(raw_target_faction)) + return (factionState->Flags & FACTION_FLAG_AT_WAR); + } + // CvP forced reaction and reputation case + else if(target->GetTypeId()==TYPEID_PLAYER) + { + // forced reaction + ForcedReactions::const_iterator forceItr = ((Player const*)target)->m_forcedReactions.find(tester_faction->faction); + if(forceItr!=((Player const*)target)->m_forcedReactions.end()) + return forceItr->second <= REP_HOSTILE; + + // apply reputation state + FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction); + if(raw_tester_faction && raw_tester_faction->reputationListID >=0 ) + return ((Player const*)target)->GetReputationRank(raw_tester_faction) <= REP_HOSTILE; + } + + // common faction based case (CvC,PvC,CvP) + return tester_faction->IsHostileTo(*target_faction); +} + +bool Unit::IsFriendlyTo(Unit const* unit) const +{ + // always friendly to self + if(unit==this) + return true; + + // always friendly to GM in GM mode + if(unit->GetTypeId()==TYPEID_PLAYER && ((Player const*)unit)->isGameMaster()) + return true; + + // always non-friendly to enemy + if(getVictim()==unit || unit->getVictim()==this) + return false; + + // test pet/charm masters instead pers/charmeds + Unit const* testerOwner = GetCharmerOrOwner(); + Unit const* targetOwner = unit->GetCharmerOrOwner(); + + // always non-friendly to owner's enemy + if(testerOwner && (testerOwner->getVictim()==unit || unit->getVictim()==testerOwner)) + return false; + + // always non-friendly to enemy owner + if(targetOwner && (getVictim()==targetOwner || targetOwner->getVictim()==this)) + return false; + + // always non-friendly to owner of owner's enemy + if(testerOwner && targetOwner && (testerOwner->getVictim()==targetOwner || targetOwner->getVictim()==testerOwner)) + return false; + + Unit const* tester = testerOwner ? testerOwner : this; + Unit const* target = targetOwner ? targetOwner : unit; + + // always friendly to target with common owner, or to owner/pet + if(tester==target) + return true; + + // special cases (Duel) + if(tester->GetTypeId()==TYPEID_PLAYER && target->GetTypeId()==TYPEID_PLAYER) + { + Player const* pTester = (Player const*)tester; + Player const* pTarget = (Player const*)target; + + // Duel + if(pTester->duel && pTester->duel->opponent == target && pTester->duel->startTime != 0) + return false; + + // Group + if(pTester->GetGroup() && pTester->GetGroup()==pTarget->GetGroup()) + return true; + + // Sanctuary + if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY)) + return true; + + // PvP FFA state + if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP)) + return false; + + //= PvP states + // Green/Blue (non-attackable) + if(pTester->GetTeam()==pTarget->GetTeam()) + return true; + + // Blue (friendly/non-attackable) if not PVP, or Yellow/Red in another case (attackable) + return !pTarget->IsPvP(); + } + + // faction base cases + FactionTemplateEntry const*tester_faction = tester->getFactionTemplateEntry(); + FactionTemplateEntry const*target_faction = target->getFactionTemplateEntry(); + if(!tester_faction || !target_faction) + return false; + + if(target->isAttackingPlayer() && tester->IsContestedGuard()) + return false; + + // PvC forced reaction and reputation case + if(tester->GetTypeId()==TYPEID_PLAYER) + { + // forced reaction + ForcedReactions::const_iterator forceItr = ((Player const*)tester)->m_forcedReactions.find(target_faction->faction); + if(forceItr!=((Player const*)tester)->m_forcedReactions.end()) + return forceItr->second >= REP_FRIENDLY; + + // if faction have reputation then friendly state for tester at 100% dependent from at_war state + if(FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction)) + if(raw_target_faction->reputationListID >=0) + if(FactionState const* FactionState = ((Player*)tester)->GetFactionState(raw_target_faction)) + return !(FactionState->Flags & FACTION_FLAG_AT_WAR); + } + // CvP forced reaction and reputation case + else if(target->GetTypeId()==TYPEID_PLAYER) + { + // forced reaction + ForcedReactions::const_iterator forceItr = ((Player const*)target)->m_forcedReactions.find(tester_faction->faction); + if(forceItr!=((Player const*)target)->m_forcedReactions.end()) + return forceItr->second >= REP_FRIENDLY; + + // apply reputation state + if(FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction)) + if(raw_tester_faction->reputationListID >=0 ) + return ((Player const*)target)->GetReputationRank(raw_tester_faction) >= REP_FRIENDLY; + } + + // common faction based case (CvC,PvC,CvP) + return tester_faction->IsFriendlyTo(*target_faction); +} + +bool Unit::IsHostileToPlayers() const +{ + FactionTemplateEntry const* my_faction = getFactionTemplateEntry(); + if(!my_faction) + return false; + + FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction); + if(raw_faction && raw_faction->reputationListID >=0 ) + return false; + + return my_faction->IsHostileToPlayers(); +} + +bool Unit::IsNeutralToAll() const +{ + FactionTemplateEntry const* my_faction = getFactionTemplateEntry(); + if(!my_faction) + return true; + + FactionEntry const* raw_faction = sFactionStore.LookupEntry(my_faction->faction); + if(raw_faction && raw_faction->reputationListID >=0 ) + return false; + + return my_faction->IsNeutralToAll(); +} + +bool Unit::Attack(Unit *victim, bool meleeAttack) +{ + if(!victim || victim == this) + return false; + + // dead units can neither attack nor be attacked + if(!isAlive() || !victim->isAlive()) + return false; + + // player cannot attack in mount state + if(GetTypeId()==TYPEID_PLAYER && IsMounted()) + return false; + + // nobody can attack GM in GM-mode + if(victim->GetTypeId()==TYPEID_PLAYER) + { + if(((Player*)victim)->isGameMaster()) + return false; + } + else + { + if(((Creature*)victim)->IsInEvadeMode()) + return false; + } + + // remove SPELL_AURA_MOD_UNATTACKABLE at attack (in case non-interruptible spells stun aura applied also that not let attack) + if(HasAuraType(SPELL_AURA_MOD_UNATTACKABLE)) + RemoveSpellsCausingAura(SPELL_AURA_MOD_UNATTACKABLE); + + if (m_attacking) + { + if (m_attacking == victim) + { + // switch to melee attack from ranged/magic + if( meleeAttack && !hasUnitState(UNIT_STAT_MELEE_ATTACKING) ) + { + addUnitState(UNIT_STAT_MELEE_ATTACKING); + SendAttackStart(victim); + return true; + } + return false; + } + AttackStop(); + } + + //Set our target + SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); + + if(meleeAttack) + addUnitState(UNIT_STAT_MELEE_ATTACKING); + m_attacking = victim; + m_attacking->_addAttacker(this); + + if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI()) + ((Creature*)m_attacking)->AI()->AttackedBy(this); + + if(GetTypeId()==TYPEID_UNIT) + { + WorldPacket data(SMSG_AI_REACTION, 12); + data << GetGUID(); + data << uint32(AI_REACTION_AGGRO); // Aggro sound + ((WorldObject*)this)->SendMessageToSet(&data, true); + + ((Creature*)this)->CallAssistence(); + ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ()); + } + + // delay offhand weapon attack to next attack time + if(haveOffhandWeapon()) + resetAttackTimer(OFF_ATTACK); + + if(meleeAttack) + SendAttackStart(victim); + + return true; +} + +bool Unit::AttackStop() +{ + if (!m_attacking) + return false; + + Unit* victim = m_attacking; + + m_attacking->_removeAttacker(this); + m_attacking = NULL; + + //Clear our target + SetUInt64Value(UNIT_FIELD_TARGET, 0); + + clearUnitState(UNIT_STAT_MELEE_ATTACKING); + + InterruptSpell(CURRENT_MELEE_SPELL); + + if( GetTypeId()==TYPEID_UNIT ) + { + // reset call assistance + ((Creature*)this)->SetNoCallAssistence(false); + } + + SendAttackStop(victim); + + return true; +} + +void Unit::CombatStop(bool cast) +{ + if(cast& IsNonMeleeSpellCasted(false)) + InterruptNonMeleeSpells(false); + + AttackStop(); + RemoveAllAttackers(); + if( GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel + ClearInCombat(); +} + +void Unit::CombatStopWithPets(bool cast) +{ + CombatStop(cast); + if(Pet* pet = GetPet()) + pet->CombatStop(cast); + if(Unit* charm = GetCharm()) + charm->CombatStop(cast); + if(GetTypeId()==TYPEID_PLAYER) + { + GuardianPetList const& guardians = ((Player*)this)->GetGuardians(); + for(GuardianPetList::const_iterator itr = guardians.begin(); itr != guardians.end(); ++itr) + if(Unit* guardian = Unit::GetUnit(*this,*itr)) + guardian->CombatStop(cast); + } +} + +bool Unit::isAttackingPlayer() const +{ + if(hasUnitState(UNIT_STAT_ATTACK_PLAYER)) + return true; + + Pet* pet = GetPet(); + if(pet && pet->isAttackingPlayer()) + return true; + + Unit* charmed = GetCharm(); + if(charmed && charmed->isAttackingPlayer()) + return true; + + for (int8 i = 0; i < MAX_TOTEM; i++) + { + if(m_TotemSlot[i]) + { + Creature *totem = ObjectAccessor::GetCreature(*this, m_TotemSlot[i]); + if(totem && totem->isAttackingPlayer()) + return true; + } + } + + return false; +} + +void Unit::RemoveAllAttackers() +{ + while (!m_attackers.empty()) + { + AttackerSet::iterator iter = m_attackers.begin(); + if(!(*iter)->AttackStop()) + { + sLog.outError("WORLD: Unit has an attacker that isnt attacking it!"); + m_attackers.erase(iter); + } + } +} + +void Unit::ModifyAuraState(AuraState flag, bool apply) +{ + if (apply) + { + if (!HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1))) + { + SetFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); + if(GetTypeId() == TYPEID_PLAYER) + { + const PlayerSpellMap& sp_list = ((Player*)this)->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + if(itr->second->state == PLAYERSPELL_REMOVED) continue; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (!spellInfo || !IsPassiveSpell(itr->first)) continue; + if (spellInfo->CasterAuraState == flag) + CastSpell(this, itr->first, true, NULL); + } + } + } + } + else + { + if (HasFlag(UNIT_FIELD_AURASTATE,1<<(flag-1))) + { + RemoveFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); + Unit::AuraMap& tAuras = GetAuras(); + for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) + { + SpellEntry const* spellProto = (*itr).second->GetSpellProto(); + if (spellProto->CasterAuraState == flag) + { + // exceptions (applied at state but not removed at state change) + // Rampage + if(spellProto->SpellIconID==2006 && spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && spellProto->SpellFamilyFlags==0x100000) + { + ++itr; + continue; + } + + RemoveAura(itr); + } + else + ++itr; + } + } + } +} + +Unit *Unit::GetOwner() const +{ + uint64 ownerid = GetOwnerGUID(); + if(!ownerid) + return NULL; + return ObjectAccessor::GetUnit(*this, ownerid); +} + +Unit *Unit::GetCharmer() const +{ + if(uint64 charmerid = GetCharmerGUID()) + return ObjectAccessor::GetUnit(*this, charmerid); + return NULL; +} + +Player* Unit::GetCharmerOrOwnerPlayerOrPlayerItself() +{ + uint64 guid = GetCharmerOrOwnerGUID(); + if(IS_PLAYER_GUID(guid)) + return ObjectAccessor::GetPlayer(*this, guid); + + return GetTypeId()==TYPEID_PLAYER ? (Player*)this : NULL; +} + +Pet* Unit::GetPet() const +{ + if(uint64 pet_guid = GetPetGUID()) + { + if(Pet* pet = ObjectAccessor::GetPet(pet_guid)) + return pet; + + sLog.outError("Unit::GetPet: Pet %u not exist.",GUID_LOPART(pet_guid)); + const_cast(this)->SetPet(0); + } + + return NULL; +} + +Unit* Unit::GetCharm() const +{ + if(uint64 charm_guid = GetCharmGUID()) + { + if(Unit* pet = ObjectAccessor::GetUnit(*this, charm_guid)) + return pet; + + sLog.outError("Unit::GetCharm: Charmed creature %u not exist.",GUID_LOPART(charm_guid)); + const_cast(this)->SetCharm(0); + } + + return NULL; +} + +void Unit::SetPet(Pet* pet) +{ + SetUInt64Value(UNIT_FIELD_SUMMON,pet ? pet->GetGUID() : 0); + + // FIXME: hack, speed must be set only at follow + if(pet) + for(int i = 0; i < MAX_MOVE_TYPE; ++i) + pet->SetSpeed(UnitMoveType(i),m_speed_rate[i],true); +} + +void Unit::SetCharm(Unit* charmed) +{ + SetUInt64Value(UNIT_FIELD_CHARM,charmed ? charmed->GetGUID() : 0); +} + +void Unit::UnsummonAllTotems() +{ + for (int8 i = 0; i < MAX_TOTEM; ++i) + { + if(!m_TotemSlot[i]) + continue; + + Creature *OldTotem = ObjectAccessor::GetCreature(*this, m_TotemSlot[i]); + if (OldTotem && OldTotem->isTotem()) + ((Totem*)OldTotem)->UnSummon(); + } +} + +void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical) +{ + // we guess size + WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+1)); + data.append(pVictim->GetPackGUID()); + data.append(GetPackGUID()); + data << uint32(SpellID); + data << uint32(Damage); + data << uint8(critical ? 1 : 0); + data << uint8(0); // unused in client? + SendMessageToSet(&data, true); +} + +void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype, bool critical) +{ + WorldPacket data(SMSG_SPELLENERGIZELOG, (8+8+4+4+4+1)); + data.append(pVictim->GetPackGUID()); + data.append(GetPackGUID()); + data << uint32(SpellID); + data << uint32(powertype); + data << uint32(Damage); + //data << uint8(critical ? 1 : 0); // removed in 2.4.0 + SendMessageToSet(&data, true); +} + +uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype) +{ + if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE ) + return pdamage; + + int32 BonusDamage = 0; + if( GetTypeId()==TYPEID_UNIT ) + { + // Pets just add their bonus damage to their spell damage + // note that their spell damage is just gain of their own auras + if (((Creature*)this)->isPet()) + { + BonusDamage = ((Pet*)this)->GetBonusDamage(); + } + // For totems get damage bonus from owner (statue isn't totem in fact) + else if (((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE) + { + if(Unit* owner = GetOwner()) + return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype); + } + } + + // Damage Done + uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); + + // Taken/Done fixed damage bonus auras + int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto))+BonusDamage; + int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); + + // Damage over Time spells bonus calculation + float DotFactor = 1.0f; + if(damagetype == DOT) + { + int32 DotDuration = GetSpellDuration(spellProto); + // 200% limit + if(DotDuration > 0) + { + if(DotDuration > 30000) DotDuration = 30000; + if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f; + int x = 0; + for(int j = 0; j < 3; j++) + { + if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && ( + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE || + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) ) + { + x = j; + break; + } + } + int DotTicks = 6; + if(spellProto->EffectAmplitude[x] != 0) + DotTicks = DotDuration / spellProto->EffectAmplitude[x]; + if(DotTicks) + { + DoneAdvertisedBenefit /= DotTicks; + TakenAdvertisedBenefit /= DotTicks; + } + } + } + + // Taken/Done total percent damage auras + float DoneTotalMod = 1.0f; + float TakenTotalMod = 1.0f; + + // ..done + AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) + { + if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) && + (*i)->GetSpellProto()->EquippedItemClass == -1 && + // -1 == any item class (not wand then) + (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 ) + // 0 == any inventory type (not wand then) + { + DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + } + } + + uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); + for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + + // ..taken + AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i) + if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) ) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + + // .. taken pct: scripted (increases damage of * against targets *) + AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + { + switch((*i)->GetModifier()->m_miscvalue) + { + //Molten Fury + case 4920: case 4919: + if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT)) + TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; break; + } + } + + // .. taken pct: dummy auras + AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) + { + switch((*i)->GetSpellProto()->SpellIconID) + { + //Cheat Death + case 2109: + if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) ) + { + if(pVictim->GetTypeId() != TYPEID_PLAYER) + continue; + float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4; + if (mod < (*i)->GetModifier()->m_amount) + mod = (*i)->GetModifier()->m_amount; + TakenTotalMod *= (mod+100.0f)/100.0f; + } + break; + //Mangle + case 2312: + for(int j=0;j<3;j++) + { + if(GetEffectMechanic(spellProto, j)==MECHANIC_BLEED) + { + TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; + break; + } + } + break; + } + } + + // Distribute Damage over multiple effects, reduce by AoE + CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); + + // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing + for(int j = 0; j < 3; ++j) + { + if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH || + spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH ) + { + CastingTime /= 2; + break; + } + } + + switch(spellProto->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + // Ignite - do not modify, it is (8*Rank)% damage of procing Spell + if(spellProto->Id==12654) + { + return pdamage; + } + // Ice Lance + else if((spellProto->SpellFamilyFlags & 0x20000LL) && spellProto->SpellIconID == 186) + { + CastingTime /= 3; // applied 1/3 bonuses in case generic target + if(pVictim->isFrozen()) // and compensate this for frozen target. + TakenTotalMod *= 3.0f; + } + // Pyroblast - 115% of Fire Damage, DoT - 20% of Fire Damage + else if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 184 ) + { + DotFactor = damagetype == DOT ? 0.2f : 1.0f; + CastingTime = damagetype == DOT ? 3500 : 4025; + } + // Fireball - 100% of Fire Damage, DoT - 0% of Fire Damage + else if((spellProto->SpellFamilyFlags & 0x1LL) && spellProto->SpellIconID == 185) + { + CastingTime = 3500; + DotFactor = damagetype == DOT ? 0.0f : 1.0f; + } + // Molten armor + else if (spellProto->SpellFamilyFlags & 0x0000000800000000LL) + { + CastingTime = 0; + } + // Arcane Missiles triggered spell + else if ((spellProto->SpellFamilyFlags & 0x200000LL) && spellProto->SpellIconID == 225) + { + CastingTime = 1000; + } + // Blizzard triggered spell + else if ((spellProto->SpellFamilyFlags & 0x80080LL) && spellProto->SpellIconID == 285) + { + CastingTime = 500; + } + break; + case SPELLFAMILY_WARLOCK: + // Life Tap + if((spellProto->SpellFamilyFlags & 0x40000LL) && spellProto->SpellIconID == 208) + { + CastingTime = 2800; // 80% from +shadow damage + DoneTotalMod = 1.0f; + TakenTotalMod = 1.0f; + } + // Dark Pact + else if((spellProto->SpellFamilyFlags & 0x80000000LL) && spellProto->SpellIconID == 154 && GetPetGUID()) + { + CastingTime = 3360; // 96% from +shadow damage + DoneTotalMod = 1.0f; + TakenTotalMod = 1.0f; + } + // Soul Fire - 115% of Fire Damage + else if((spellProto->SpellFamilyFlags & 0x8000000000LL) && spellProto->SpellIconID == 184) + { + CastingTime = 4025; + } + // Curse of Agony - 120% of Shadow Damage + else if((spellProto->SpellFamilyFlags & 0x0000000400LL) && spellProto->SpellIconID == 544) + { + DotFactor = 1.2f; + } + // Drain Mana - 0% of Shadow Damage + else if((spellProto->SpellFamilyFlags & 0x10LL) && spellProto->SpellIconID == 548) + { + CastingTime = 0; + } + // Drain Soul 214.3% + else if ((spellProto->SpellFamilyFlags & 0x4000LL) && spellProto->SpellIconID == 113 ) + { + CastingTime = 7500; + } + // Hellfire + else if ((spellProto->SpellFamilyFlags & 0x40LL) && spellProto->SpellIconID == 937) + { + CastingTime = damagetype == DOT ? 5000 : 500; // self damage seems to be so + } + // Unstable Affliction - 180% + else if (spellProto->Id == 31117 && spellProto->SpellIconID == 232) + { + CastingTime = 6300; + } + // Corruption 93% + else if ((spellProto->SpellFamilyFlags & 0x2LL) && spellProto->SpellIconID == 313) + { + DotFactor = 0.93f; + } + break; + case SPELLFAMILY_PALADIN: + // Consecration - 95% of Holy Damage + if((spellProto->SpellFamilyFlags & 0x20LL) && spellProto->SpellIconID == 51) + { + DotFactor = 0.95f; + CastingTime = 3500; + } + // Seal of Righteousness - 10.2%/9.8% ( based on weapon type ) of Holy Damage, multiplied by weapon speed + else if((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 25) + { + Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + float wspeed = GetAttackTime(BASE_ATTACK)/1000.0f; + + if( item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON) + CastingTime = uint32(wspeed*3500*0.102f); + else + CastingTime = uint32(wspeed*3500*0.098f); + } + // Judgement of Righteousness - 73% + else if ((spellProto->SpellFamilyFlags & 1024) && spellProto->SpellIconID == 25) + { + CastingTime = 2555; + } + // Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications + else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2292) + { + DotFactor = 0.17f; + CastingTime = 3500; + } + // Holy shield - 5% of Holy Damage + else if ((spellProto->SpellFamilyFlags & 0x4000000000LL) && spellProto->SpellIconID == 453) + { + CastingTime = 175; + } + // Blessing of Sanctuary - 0% + else if ((spellProto->SpellFamilyFlags & 0x10000000LL) && spellProto->SpellIconID == 29) + { + CastingTime = 0; + } + // Seal of Righteousness trigger - already computed for parent spell + else if ( spellProto->SpellFamilyName==SPELLFAMILY_PALADIN && spellProto->SpellIconID==25 && spellProto->AttributesEx4 & 0x00800000LL ) + { + return pdamage; + } + break; + case SPELLFAMILY_SHAMAN: + // totem attack + if (spellProto->SpellFamilyFlags & 0x000040000000LL) + { + if (spellProto->SpellIconID == 33) // Fire Nova totem attack must be 21.4%(untested) + CastingTime = 749; // ignore CastingTime and use as modifier + else if (spellProto->SpellIconID == 680) // Searing Totem attack 8% + CastingTime = 280; // ignore CastingTime and use as modifier + else if (spellProto->SpellIconID == 37) // Magma totem attack must be 6.67%(untested) + CastingTime = 234; // ignore CastingTimePenalty and use as modifier + } + // Lightning Shield (and proc shield from T2 8 pieces bonus ) 33% per charge + else if( (spellProto->SpellFamilyFlags & 0x00000000400LL) || spellProto->Id == 23552) + CastingTime = 1155; // ignore CastingTimePenalty and use as modifier + break; + case SPELLFAMILY_PRIEST: + // Mana Burn - 0% of Shadow Damage + if((spellProto->SpellFamilyFlags & 0x10LL) && spellProto->SpellIconID == 212) + { + CastingTime = 0; + } + // Mind Flay - 59% of Shadow Damage + else if((spellProto->SpellFamilyFlags & 0x800000LL) && spellProto->SpellIconID == 548) + { + CastingTime = 2065; + } + // Holy Fire - 86.71%, DoT - 16.5% + else if ((spellProto->SpellFamilyFlags & 0x100000LL) && spellProto->SpellIconID == 156) + { + DotFactor = damagetype == DOT ? 0.165f : 1.0f; + CastingTime = damagetype == DOT ? 3500 : 3035; + } + // Shadowguard - 28% per charge + else if ((spellProto->SpellFamilyFlags & 0x2000000LL) && spellProto->SpellIconID == 19) + { + CastingTime = 980; + } + // Touch of Weakeness - 10% + else if ((spellProto->SpellFamilyFlags & 0x80000LL) && spellProto->SpellIconID == 1591) + { + CastingTime = 350; + } + // Reflective Shield (back damage) - 0% (other spells fit to check not have damage effects/auras) + else if (spellProto->SpellFamilyFlags == 0 && spellProto->SpellIconID == 566) + { + CastingTime = 0; + } + // Holy Nova - 14% + else if ((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 1874) + { + CastingTime = 500; + } + break; + case SPELLFAMILY_DRUID: + // Hurricane triggered spell + if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 220) + { + CastingTime = 500; + } + break; + case SPELLFAMILY_WARRIOR: + case SPELLFAMILY_HUNTER: + case SPELLFAMILY_ROGUE: + CastingTime = 0; + break; + default: + break; + } + + float LvlPenalty = CalculateLevelPenalty(spellProto); + + // Spellmod SpellDamage + float SpellModSpellDamage = 100.0f; + + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage); + + SpellModSpellDamage /= 100.0f; + + float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; + float TakenActualBenefit = TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty; + + float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod; + + // Add flat bonus from spell damage versus + tmpDamage += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask); + + // apply spellmod to Done damage + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); + + tmpDamage = (tmpDamage+TakenActualBenefit)*TakenTotalMod; + + if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() ) + tmpDamage *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank); + + return tmpDamage > 0 ? uint32(tmpDamage) : 0; +} + +int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) +{ + int32 DoneAdvertisedBenefit = 0; + + // ..done + AuraList const& mDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE); + for(AuraList::const_iterator i = mDamageDone.begin();i != mDamageDone.end(); ++i) + if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0 && + (*i)->GetSpellProto()->EquippedItemClass == -1 && + // -1 == any item class (not wand then) + (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 ) + // 0 == any inventory type (not wand then) + DoneAdvertisedBenefit += (*i)->GetModifier()->m_amount; + + if (GetTypeId() == TYPEID_PLAYER) + { + // Damage bonus from stats + AuraList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT); + for(AuraList::const_iterator i = mDamageDoneOfStatPercent.begin();i != mDamageDoneOfStatPercent.end(); ++i) + { + if((*i)->GetModifier()->m_miscvalue & schoolMask) + { + SpellEntry const* iSpellProto = (*i)->GetSpellProto(); + uint8 eff = (*i)->GetEffIndex(); + + // stat used dependent from next effect aura SPELL_AURA_MOD_SPELL_HEALING presence and misc value (stat index) + Stats usedStat = STAT_INTELLECT; + if(eff < 2 && iSpellProto->EffectApplyAuraName[eff+1]==SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT) + usedStat = Stats(iSpellProto->EffectMiscValue[eff+1]); + + DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifier()->m_amount / 100.0f); + } + } + // ... and attack power + AuraList const& mDamageDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER); + for(AuraList::const_iterator i =mDamageDonebyAP.begin();i != mDamageDonebyAP.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue & schoolMask) + DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifier()->m_amount / 100.0f); + + } + return DoneAdvertisedBenefit; +} + +int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim) +{ + uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + + int32 TakenAdvertisedBenefit = 0; + // ..done (for creature type by mask) in taken + AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); + for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount; + + // ..taken + AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN); + for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) + if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0) + TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount; + + return TakenAdvertisedBenefit; +} + +bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) +{ + // not criting spell + if((spellProto->AttributesEx2 & SPELL_ATTR_EX2_CANT_CRIT)) + return false; + + float crit_chance = 0.0f; + switch(spellProto->DmgClass) + { + case SPELL_DAMAGE_CLASS_NONE: + return false; + case SPELL_DAMAGE_CLASS_MAGIC: + { + if (schoolMask & SPELL_SCHOOL_MASK_NORMAL) + crit_chance = 0.0f; + // For other schools + else if (GetTypeId() == TYPEID_PLAYER) + crit_chance = GetFloatValue( PLAYER_SPELL_CRIT_PERCENTAGE1 + GetFirstSchoolInMask(schoolMask)); + else + { + crit_chance = m_baseSpellCritChance; + crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask); + } + // taken + if (pVictim && !IsPositiveSpell(spellProto->Id)) + { + // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE + crit_chance += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE, schoolMask); + // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE + crit_chance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE); + // Modify by player victim resilience + if (pVictim->GetTypeId() == TYPEID_PLAYER) + crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL); + // scripted (increase crit chance ... against ... target by x% + if(pVictim->isFrozen()) // Shatter + { + AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + { + switch((*i)->GetModifier()->m_miscvalue) + { + case 849: crit_chance+= 10.0f; break; //Shatter Rank 1 + case 910: crit_chance+= 20.0f; break; //Shatter Rank 2 + case 911: crit_chance+= 30.0f; break; //Shatter Rank 3 + case 912: crit_chance+= 40.0f; break; //Shatter Rank 4 + case 913: crit_chance+= 50.0f; break; //Shatter Rank 5 + } + } + } + } + break; + } + case SPELL_DAMAGE_CLASS_MELEE: + case SPELL_DAMAGE_CLASS_RANGED: + { + if (pVictim) + { + crit_chance = GetUnitCriticalChance(attackType, pVictim); + crit_chance+= (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f; + crit_chance+= GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask); + } + break; + } + default: + return false; + } + // percent done + // only players use intelligence for critical chance computations + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance); + + crit_chance = crit_chance > 0.0f ? crit_chance : 0.0f; + if (roll_chance_f(crit_chance)) + return true; + return false; +} + +uint32 Unit::SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim) +{ + // Calculate critical bonus + int32 crit_bonus; + switch(spellProto->DmgClass) + { + case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100% + case SPELL_DAMAGE_CLASS_RANGED: + // TODO: write here full calculation for melee/ranged spells + crit_bonus = damage; + break; + default: + crit_bonus = damage / 2; // for spells is 50% + break; + } + + // adds additional damage to crit_bonus (from talents) + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); + + if(pVictim) + { + uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + crit_bonus = int32(crit_bonus * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask)); + } + + if(crit_bonus > 0) + damage += crit_bonus; + + return damage; +} + +uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim) +{ + // For totems get healing bonus from owner (statue isn't totem in fact) + if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE) + if(Unit* owner = GetOwner()) + return owner->SpellHealingBonus(spellProto, healamount, damagetype, pVictim); + + // Healing Done + + // These Spells are doing fixed amount of healing (TODO found less hack-like check) + if(spellProto->Id == 15290 || spellProto->Id == 39373 || spellProto->Id == 33778 || spellProto->Id == 379 || spellProto->Id == 38395) + return healamount; + + int32 AdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto)); + uint32 CastingTime = GetSpellCastTime(spellProto); + + // Healing Taken + AdvertisedBenefit += SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); + + // Blessing of Light dummy effects healing taken from Holy Light and Flash of Light + if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && (spellProto->SpellFamilyFlags & 0x00000000C0000000LL)) + { + AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + { + if((*i)->GetSpellProto()->SpellVisual == 9180) + { + // Flash of Light + if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1) + AdvertisedBenefit += (*i)->GetModifier()->m_amount; + // Holy Light + else if ((spellProto->SpellFamilyFlags & 0x0000000080000000LL) && (*i)->GetEffIndex() == 0) + AdvertisedBenefit += (*i)->GetModifier()->m_amount; + } + } + } + + float ActualBenefit = 0.0f; + + if (AdvertisedBenefit != 0) + { + // Healing over Time spells + float DotFactor = 1.0f; + if(damagetype == DOT) + { + int32 DotDuration = GetSpellDuration(spellProto); + if(DotDuration > 0) + { + // 200% limit + if(DotDuration > 30000) DotDuration = 30000; + if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f; + int x = 0; + for(int j = 0; j < 3; j++) + { + if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && ( + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL || + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) ) + { + x = j; + break; + } + } + int DotTicks = 6; + if(spellProto->EffectAmplitude[x] != 0) + DotTicks = DotDuration / spellProto->EffectAmplitude[x]; + if(DotTicks) + AdvertisedBenefit /= DotTicks; + } + } + + // distribute healing to all effects, reduce AoE damage + CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); + + // 0% bonus for damage and healing spells for leech spells from healing bonus + for(int j = 0; j < 3; ++j) + { + if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH || + spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH ) + { + CastingTime = 0; + break; + } + } + + // Exception + switch (spellProto->SpellFamilyName) + { + case SPELLFAMILY_SHAMAN: + // Healing stream from totem (add 6% per tick from hill bonus owner) + if (spellProto->SpellFamilyFlags & 0x000000002000LL) + CastingTime = 210; + // Earth Shield 30% per charge + else if (spellProto->SpellFamilyFlags & 0x40000000000LL) + CastingTime = 1050; + break; + case SPELLFAMILY_DRUID: + // Lifebloom + if (spellProto->SpellFamilyFlags & 0x1000000000LL) + { + CastingTime = damagetype == DOT ? 3500 : 1200; + DotFactor = damagetype == DOT ? 0.519f : 1.0f; + } + // Tranquility triggered spell + else if (spellProto->SpellFamilyFlags & 0x80LL) + CastingTime = 667; + // Rejuvenation + else if (spellProto->SpellFamilyFlags & 0x10LL) + DotFactor = 0.845f; + // Regrowth + else if (spellProto->SpellFamilyFlags & 0x40LL) + { + DotFactor = damagetype == DOT ? 0.705f : 1.0f; + CastingTime = damagetype == DOT ? 3500 : 1010; + } + break; + case SPELLFAMILY_PRIEST: + // Holy Nova - 14% + if ((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 1874) + CastingTime = 500; + break; + case SPELLFAMILY_PALADIN: + // Seal and Judgement of Light + if ( spellProto->SpellFamilyFlags & 0x100040000LL ) + CastingTime = 0; + break; + case SPELLFAMILY_WARRIOR: + case SPELLFAMILY_ROGUE: + case SPELLFAMILY_HUNTER: + CastingTime = 0; + break; + } + + float LvlPenalty = CalculateLevelPenalty(spellProto); + + // Spellmod SpellDamage + float SpellModSpellDamage = 100.0f; + + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage); + + SpellModSpellDamage /= 100.0f; + + ActualBenefit = (float)AdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; + } + + // use float as more appropriate for negative values and percent applying + float heal = healamount + ActualBenefit; + + // TODO: check for ALL/SPELLS type + // Healing done percent + AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); + for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i) + heal *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f; + + // apply spellmod to Done amount + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); + + // Healing Wave cast + if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags & 0x0000000000000040LL) + { + // Search for Healing Way on Victim (stack up to 3 time) + int32 pctMod = 0; + Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr) + if((*itr)->GetId() == 29203) + pctMod += (*itr)->GetModifier()->m_amount; + // Apply bonus + if (pctMod) + heal = heal * (100 + pctMod) / 100; + } + + // Healing taken percent + float minval = pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + if(minval) + heal *= (100.0f + minval) / 100.0f; + + float maxval = pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + if(maxval) + heal *= (100.0f + maxval) / 100.0f; + + if (heal < 0) heal = 0; + + return uint32(heal); +} + +int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) +{ + int32 AdvertisedBenefit = 0; + + AuraList const& mHealingDone = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE); + for(AuraList::const_iterator i = mHealingDone.begin();i != mHealingDone.end(); ++i) + if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0) + AdvertisedBenefit += (*i)->GetModifier()->m_amount; + + // Healing bonus of spirit, intellect and strength + if (GetTypeId() == TYPEID_PLAYER) + { + // Healing bonus from stats + AuraList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT); + for(AuraList::const_iterator i = mHealingDoneOfStatPercent.begin();i != mHealingDoneOfStatPercent.end(); ++i) + { + // stat used dependent from misc value (stat index) + Stats usedStat = Stats((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()]); + AdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifier()->m_amount / 100.0f); + } + + // ... and attack power + AuraList const& mHealingDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER); + for(AuraList::const_iterator i = mHealingDonebyAP.begin();i != mHealingDonebyAP.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue & schoolMask) + AdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifier()->m_amount / 100.0f); + } + return AdvertisedBenefit; +} + +int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim) +{ + int32 AdvertisedBenefit = 0; + AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING); + for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) + if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0) + AdvertisedBenefit += (*i)->GetModifier()->m_amount; + return AdvertisedBenefit; +} + +bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask, bool useCharges) +{ + // no charges dependent checks + SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; + for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) + if(itr->type & shoolMask) + return true; + + // charges dependent checks + SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE]; + for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr) + { + if(itr->type & shoolMask) + { + if(useCharges) + { + AuraList const& auraDamageImmunity = GetAurasByType(SPELL_AURA_DAMAGE_IMMUNITY); + for(AuraList::const_iterator auraItr = auraDamageImmunity.begin(); auraItr != auraDamageImmunity.end(); ++auraItr) + { + if((*auraItr)->GetId()==itr->spellId) + { + if((*auraItr)->m_procCharges > 0) + { + --(*auraItr)->m_procCharges; + if((*auraItr)->m_procCharges==0) + RemoveAurasDueToSpell(itr->spellId); + } + break; + } + } + } + return true; + } + } + + return false; +} + +bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges) +{ + if (!spellInfo) + return false; + + // no charges first + + //FIX ME this hack: don't get feared if stunned + if (spellInfo->Mechanic == MECHANIC_FEAR ) + { + if ( hasUnitState(UNIT_STAT_STUNNED) ) + return true; + } + + // not have spells with charges currently + SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL]; + for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr) + if(itr->type == spellInfo->Dispel) + return true; + + if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)) // unaffected by school immunity + { + // not have spells with charges currently + SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; + for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) + if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) && + (itr->type & GetSpellSchoolMask(spellInfo)) ) + return true; + } + + // charges dependent checks + + SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; + for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + { + if(itr->type == spellInfo->Mechanic) + { + if(useCharges) + { + AuraList const& auraMechImmunity = GetAurasByType(SPELL_AURA_MECHANIC_IMMUNITY); + for(AuraList::const_iterator auraItr = auraMechImmunity.begin(); auraItr != auraMechImmunity.end(); ++auraItr) + { + if((*auraItr)->GetId()==itr->spellId) + { + if((*auraItr)->m_procCharges > 0) + { + --(*auraItr)->m_procCharges; + if((*auraItr)->m_procCharges==0) + RemoveAurasDueToSpell(itr->spellId); + } + break; + } + } + } + return true; + } + } + + return false; +} + +bool Unit::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const +{ + //If m_immuneToEffect type contain this effect type, IMMUNE effect. + SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; + for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr) + if(itr->type == effect) + return true; + + SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; + for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + if(itr->type == mechanic) + return true; + + return false; +} + +bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const +{ + if(!spellInfo) + return false; + + uint32 family = spellInfo->SpellFamilyName; + uint64 flags = spellInfo->SpellFamilyFlags; + + if((family == 5 && flags == 256) || //Searing Pain + (family == 6 && flags == 8192) || //Mind Blast + (family == 11 && flags == 1048576)) //Earth Shock + return true; + + return false; +} + +void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attType, SpellEntry const *spellProto) +{ + if(!pVictim) + return; + + if(*pdamage == 0) + return; + + uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + + // Taken/Done fixed damage bonus auras + int32 DoneFlatBenefit = 0; + int32 TakenFlatBenefit = 0; + + // ..done (for creature type by mask) in taken + AuraList const& mDamageDoneCreature = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); + for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + DoneFlatBenefit += (*i)->GetModifier()->m_amount; + + // ..done + // SPELL_AURA_MOD_DAMAGE_DONE included in weapon damage + + // ..done (base at attack power for marked target and base at attack power for creature type) + int32 APbonus = 0; + if(attType == RANGED_ATTACK) + { + APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS); + + // ..done (base at attack power and creature type) + AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS); + for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + APbonus += (*i)->GetModifier()->m_amount; + } + else + { + APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS); + + // ..done (base at attack power and creature type) + AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS); + for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + APbonus += (*i)->GetModifier()->m_amount; + } + + if (APbonus!=0) // Can be negative + { + bool normalized = false; + if(spellProto) + { + for (uint8 i = 0; i<3;i++) + { + if (spellProto->Effect[i] == SPELL_EFFECT_NORMALIZED_WEAPON_DMG) + { + normalized = true; + break; + } + } + } + + DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType,normalized)); + } + + // ..taken + AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN); + for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) + if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) + TakenFlatBenefit += (*i)->GetModifier()->m_amount; + + if(attType!=RANGED_ATTACK) + TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN); + else + TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN); + + // Done/Taken total percent damage auras + float DoneTotalMod = 1; + float TakenTotalMod = 1; + + // ..done + // SPELL_AURA_MOD_DAMAGE_PERCENT_DONE included in weapon damage + // SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT included in weapon damage + + AuraList const& mDamageDoneVersus = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); + for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + + // ..taken + AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i) + if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + + // .. taken pct: dummy auras + AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) + { + switch((*i)->GetSpellProto()->SpellIconID) + { + //Cheat Death + case 2109: + if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) + { + if(pVictim->GetTypeId() != TYPEID_PLAYER) + continue; + float mod = ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*(-8.0f); + if (mod < (*i)->GetModifier()->m_amount) + mod = (*i)->GetModifier()->m_amount; + TakenTotalMod *= (mod+100.0f)/100.0f; + } + break; + //Mangle + case 2312: + if(spellProto==NULL) + break; + // Should increase Shred (initial Damage of Lacerate and Rake handled in Spell::EffectSchoolDMG) + if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags==0x00008000LL)) + TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; + break; + } + } + + // .. taken pct: class scripts + AuraList const& mclassScritAuras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(AuraList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i) + { + switch((*i)->GetMiscValue()) + { + case 6427: case 6428: // Dirty Deeds + if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) + { + Aura* eff0 = GetAura((*i)->GetId(),0); + if(!eff0 || (*i)->GetEffIndex()!=1) + { + sLog.outError("Spell structure of DD (%u) changed.",(*i)->GetId()); + continue; + } + + // effect 0 have expected value but in negative state + TakenTotalMod *= (-eff0->GetModifier()->m_amount+100.0f)/100.0f; + } + break; + } + } + + if(attType != RANGED_ATTACK) + { + AuraList const& mModMeleeDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT); + for(AuraList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + } + else + { + AuraList const& mModRangedDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT); + for(AuraList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + } + + float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod; + + // apply spellmod to Done damage + if(spellProto) + { + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); + } + + tmpDamage = (tmpDamage + TakenFlatBenefit)*TakenTotalMod; + + // bonus result can be negative + *pdamage = tmpDamage > 0 ? uint32(tmpDamage) : 0; +} + +void Unit::ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply) +{ + if (apply) + { + for (SpellImmuneList::iterator itr = m_spellImmune[op].begin(), next; itr != m_spellImmune[op].end(); itr = next) + { + next = itr; ++next; + if(itr->type == type) + { + m_spellImmune[op].erase(itr); + next = m_spellImmune[op].begin(); + } + } + SpellImmune Immune; + Immune.spellId = spellId; + Immune.type = type; + m_spellImmune[op].push_back(Immune); + } + else + { + for (SpellImmuneList::iterator itr = m_spellImmune[op].begin(); itr != m_spellImmune[op].end(); ++itr) + { + if(itr->spellId == spellId) + { + m_spellImmune[op].erase(itr); + break; + } + } + } + +} + +void Unit::ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType type, bool apply) +{ + ApplySpellImmune(spellProto->Id,IMMUNITY_DISPEL, type, apply); + + if (apply && spellProto->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + RemoveAurasWithDispelType(type); +} + +float Unit::GetWeaponProcChance() const +{ + // normalized proc chance for weapon attack speed + // (odd formulae...) + if(isAttackReady(BASE_ATTACK)) + return (GetAttackTime(BASE_ATTACK) * 1.8f / 1000.0f); + else if (haveOffhandWeapon() && isAttackReady(OFF_ATTACK)) + return (GetAttackTime(OFF_ATTACK) * 1.6f / 1000.0f); + return 0; +} + +float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const +{ + // proc per minute chance calculation + if (PPM <= 0) return 0.0f; + uint32 result = uint32((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60)) + return result; +} + +void Unit::Mount(uint32 mount) +{ + if(!mount) + return; + + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNTING); + + SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount); + + SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); + + // unsummon pet + if(GetTypeId() == TYPEID_PLAYER) + { + Pet* pet = GetPet(); + if(pet) + { + if(pet->isControlled()) + { + ((Player*)this)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber()); + ((Player*)this)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL)); + } + + ((Player*)this)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT); + } + else + ((Player*)this)->SetTemporaryUnsummonedPetNumber(0); + } +} + +void Unit::Unmount() +{ + if(!IsMounted()) + return; + + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_MOUNTED); + + SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); + RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); + + // only resummon old pet if the player is already added to a map + // this prevents adding a pet to a not created map which would otherwise cause a crash + // (it could probably happen when logging in after a previous crash) + if(GetTypeId() == TYPEID_PLAYER && IsInWorld() && ((Player*)this)->GetTemporaryUnsummonedPetNumber() && isAlive()) + { + Pet* NewPet = new Pet; + if(!NewPet->LoadPetFromDB(this, 0, ((Player*)this)->GetTemporaryUnsummonedPetNumber(), true)) + delete NewPet; + + ((Player*)this)->SetTemporaryUnsummonedPetNumber(0); + } +} + +void Unit::SetInCombatWith(Unit* enemy) +{ + Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf(); + if(eOwner->IsPvP()) + { + SetInCombatState(true); + return; + } + + //check for duel + if(eOwner->GetTypeId() == TYPEID_PLAYER && ((Player*)eOwner)->duel) + { + Unit const* myOwner = GetCharmerOrOwnerOrSelf(); + if(((Player const*)eOwner)->duel->opponent == myOwner) + { + SetInCombatState(true); + return; + } + } + SetInCombatState(false); +} + +void Unit::SetInCombatState(bool PvP) +{ + // only alive units can be in combat + if(!isAlive()) + return; + + if(PvP) + m_CombatTimer = 5000; + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + + if(isCharmed() || (GetTypeId()!=TYPEID_PLAYER && ((Creature*)this)->isPet())) + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); +} + +void Unit::ClearInCombat() +{ + m_CombatTimer = 0; + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + + if(isCharmed() || (GetTypeId()!=TYPEID_PLAYER && ((Creature*)this)->isPet())) + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); + + // Player's state will be cleared in Player::UpdateContestedPvP + if(GetTypeId()!=TYPEID_PLAYER) + clearUnitState(UNIT_STAT_ATTACK_PLAYER); +} + +bool Unit::isTargetableForAttack() const +{ + if (GetTypeId()==TYPEID_PLAYER && ((Player *)this)->isGameMaster()) + return false; + + if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) + return false; + + return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; +} + +int32 Unit::ModifyHealth(int32 dVal) +{ + int32 gain = 0; + + if(dVal==0) + return 0; + + int32 curHealth = (int32)GetHealth(); + + int32 val = dVal + curHealth; + if(val <= 0) + { + SetHealth(0); + return -curHealth; + } + + int32 maxHealth = (int32)GetMaxHealth(); + + if(val < maxHealth) + { + SetHealth(val); + gain = val - curHealth; + } + else if(curHealth != maxHealth) + { + SetHealth(maxHealth); + gain = maxHealth - curHealth; + } + + return gain; +} + +int32 Unit::ModifyPower(Powers power, int32 dVal) +{ + int32 gain = 0; + + if(dVal==0) + return 0; + + int32 curPower = (int32)GetPower(power); + + int32 val = dVal + curPower; + if(val <= 0) + { + SetPower(power,0); + return -curPower; + } + + int32 maxPower = (int32)GetMaxPower(power); + + if(val < maxPower) + { + SetPower(power,val); + gain = val - curPower; + } + else if(curPower != maxPower) + { + SetPower(power,maxPower); + gain = maxPower - curPower; + } + + return gain; +} + +bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList) const +{ + if(!u) + return false; + + // Always can see self + if (u==this) + return true; + + // player visible for other player if not logout and at same transport + // including case when player is out of world + bool at_same_transport = + GetTypeId() == TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER && + !((Player*)this)->GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() && + !((Player*)this)->GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() && + ((Player*)this)->GetTransport() && ((Player*)this)->GetTransport() == ((Player*)u)->GetTransport(); + + // not in world + if(!at_same_transport && (!IsInWorld() || !u->IsInWorld())) + return false; + + // forbidden to seen (at GM respawn command) + if(m_Visibility==VISIBILITY_RESPAWN) + return false; + + // always seen by owner + if(GetCharmerOrOwnerGUID()==u->GetGUID()) + return true; + + // Grid dead/alive checks + if( u->GetTypeId()==TYPEID_PLAYER) + { + // non visible at grid for any stealth state + if(!IsVisibleInGridForPlayer((Player *)u)) + return false; + + // if player is dead then he can't detect anyone in anycases + if(!u->isAlive()) + detect = false; + } + else + { + // all dead creatures/players not visible for any creatures + if(!u->isAlive() || !isAlive()) + return false; + } + + // different visible distance checks + if(u->isInFlight()) // what see player in flight + { + // use object grey distance for all (only see objects any way) + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } + else if(!isAlive()) // distance for show body + { + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) + return false; + } + else if(GetTypeId()==TYPEID_PLAYER) // distance for show player + { + if(u->GetTypeId()==TYPEID_PLAYER) + { + // Players far than max visible distance for player or not in our map are not visible too + if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else + { + // Units far than max visible distance for creature or not in our map are not visible too + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + } + else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed + { + // Pet/charmed far than max visible distance for player or not in our map are not visible too + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + else // distance for show creature + { + // Units far than max visible distance for creature or not in our map are not visible too + if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) + return false; + } + + // Visible units, always are visible for all units, except for units under invisibility + if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0) + return true; + + // GMs see any players, not higher GMs and all units + if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster()) + { + if(GetTypeId() == TYPEID_PLAYER) + return ((Player *)this)->GetSession()->GetSecurity() <= ((Player *)u)->GetSession()->GetSecurity(); + else + return true; + } + + // non faction visibility non-breakable for non-GMs + if (m_Visibility == VISIBILITY_OFF) + return false; + + // raw invisibility + bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask !=0); + + // detectable invisibility case + if( invisible && ( + // Invisible units, always are visible for units under same invisibility type + (m_invisibilityMask & u->m_invisibilityMask)!=0 || + // Invisible units, always are visible for unit that can detect this invisibility (have appropriate level for detect) + u->canDetectInvisibilityOf(this) || + // Units that can detect invisibility always are visible for units that can be detected + canDetectInvisibilityOf(u) )) + { + invisible = false; + } + + // special cases for always overwrite invisibility/stealth + if(invisible || m_Visibility == VISIBILITY_GROUP_STEALTH) + { + // non-hostile case + if (!u->IsHostileTo(this)) + { + // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting) + if(GetTypeId()==TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER) + { + if(((Player*)this)->IsGroupVisibleFor(((Player*)u))) + return true; + + // else apply same rules as for hostile case (detecting check for stealth) + } + } + // hostile case + else + { + // Hunter mark functionality + AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED); + for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) + if((*iter)->GetCasterGUID()==u->GetGUID()) + return true; + + // else apply detecting check for stealth + } + + // none other cases for detect invisibility, so invisible + if(invisible) + return false; + + // else apply stealth detecting check + } + + // unit got in stealth in this moment and must ignore old detected state + if (m_Visibility == VISIBILITY_GROUP_NO_DETECT) + return false; + + // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible + if (m_Visibility != VISIBILITY_GROUP_STEALTH) + return true; + + // NOW ONLY STEALTH CASE + + // stealth and detected and visible for some seconds + if (u->GetTypeId() == TYPEID_PLAYER && ((Player*)u)->m_DetectInvTimer > 300 && ((Player*)u)->HaveAtClient(this)) + return true; + + //if in non-detect mode then invisible for unit + if (!detect) + return false; + + // Special cases + + // If is attacked then stealth is lost, some creature can use stealth too + if( !getAttackers().empty() ) + return true; + + // If there is collision rogue is seen regardless of level difference + // TODO: check sizes in DB + float distance = GetDistance(u); + if (distance < 0.24f) + return true; + + //If a mob or player is stunned he will not be able to detect stealth + if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this)) + return false; + + // Creature can detect target only in aggro radius + if(u->GetTypeId() != TYPEID_PLAYER) + { + //Always invisible from back and out of aggro range + bool isInFront = u->isInFront(this,((Creature const*)u)->GetAttackDistance(this)); + if(!isInFront) + return false; + } + else + { + //Always invisible from back + bool isInFront = u->isInFront(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); + if(!isInFront) + return false; + } + + // if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los + if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH)) + { + //Calculation if target is in front + + //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5) + float visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f); + + //Visible distance is modified by + //-Level Diff (every level diff = 1.0f in visible distance) + visibleDistance += int32(u->getLevelForTarget(this)) - int32(this->getLevelForTarget(u)); + + //This allows to check talent tree and will add addition stealth dependent on used points) + int32 stealthMod = GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL); + if(stealthMod < 0) + stealthMod = 0; + + //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia) + //based on wowwiki every 5 mod we have 1 more level diff in calculation + visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f; + + if(distance > visibleDistance) + return false; + } + + // Now check is target visible with LoS + float ox,oy,oz; + u->GetPosition(ox,oy,oz); + return IsWithinLOS(ox,oy,oz); +} + +void Unit::SetVisibility(UnitVisibility x) +{ + m_Visibility = x; + + if(IsInWorld()) + { + Map *m = MapManager::Instance().GetMap(GetMapId(), this); + + if(GetTypeId()==TYPEID_PLAYER) + m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); + else + m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); + } +} + +bool Unit::canDetectInvisibilityOf(Unit const* u) const +{ + if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask)) + { + for(uint32 i = 0; i < 10; ++i) + { + if(((1 << i) & mask)==0) + continue; + + // find invisibility level + uint32 invLevel = 0; + Unit::AuraList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY); + for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr) + if(((*itr)->GetModifier()->m_miscvalue)==i && invLevel < (*itr)->GetModifier()->m_amount) + invLevel = (*itr)->GetModifier()->m_amount; + + // find invisibility detect level + uint32 detectLevel = 0; + Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION); + for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr) + if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount) + detectLevel = (*itr)->GetModifier()->m_amount; + + if(i==6 && GetTypeId()==TYPEID_PLAYER) // special drunk detection case + { + detectLevel = ((Player*)this)->GetDrunkValue(); + } + + if(invLevel <= detectLevel) + return true; + } + } + + return false; +} + +void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) +{ + int32 main_speed_mod = 0; + float stack_bonus = 1.0f; + float non_stack_bonus = 1.0f; + + switch(mtype) + { + case MOVE_WALK: + return; + case MOVE_RUN: + { + if (IsMounted()) // Use on mount auras + { + main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED); + stack_bonus = GetTotalAuraMultiplier(SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS); + non_stack_bonus = (100.0f + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK))/100.0f; + } + else + { + main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SPEED); + stack_bonus = GetTotalAuraMultiplier(SPELL_AURA_MOD_SPEED_ALWAYS); + non_stack_bonus = (100.0f + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_SPEED_NOT_STACK))/100.0f; + } + break; + } + case MOVE_WALKBACK: + return; + case MOVE_SWIM: + { + main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); + break; + } + case MOVE_SWIMBACK: + return; + case MOVE_FLY: + { + if (IsMounted()) // Use on mount auras + main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED); + else // Use not mount (shapeshift for example) auras (should stack) + main_speed_mod = GetTotalAuraModifier(SPELL_AURA_MOD_SPEED_FLIGHT); + stack_bonus = GetTotalAuraMultiplier(SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS); + non_stack_bonus = (100.0 + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK))/100.0f; + break; + } + case MOVE_FLYBACK: + return; + default: + sLog.outError("Unit::UpdateSpeed: Unsupported move type (%d)", mtype); + return; + } + + float bonus = non_stack_bonus > stack_bonus ? non_stack_bonus : stack_bonus; + // now we ready for speed calculation + float speed = main_speed_mod ? bonus*(100.0f + main_speed_mod)/100.0f : bonus; + + switch(mtype) + { + case MOVE_RUN: + case MOVE_SWIM: + case MOVE_FLY: + { + // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need + // TODO: possible affect only on MOVE_RUN + if(int32 normalization = GetMaxPositiveAuraModifier(SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED)) + { + // Use speed from aura + float max_speed = normalization / baseMoveSpeed[mtype]; + if (speed > max_speed) + speed = max_speed; + } + break; + } + default: + break; + } + + // Apply strongest slow aura mod to speed + int32 slow = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); + if (slow) + speed *=(100.0f + slow)/100.0f; + SetSpeed(mtype, speed, forced); +} + +float Unit::GetSpeed( UnitMoveType mtype ) const +{ + return m_speed_rate[mtype]*baseMoveSpeed[mtype]; +} + +void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) +{ + if (rate < 0) + rate = 0.0f; + + // Update speed only on change + if (m_speed_rate[mtype] == rate) + return; + + m_speed_rate[mtype] = rate; + + propagateSpeedChange(); + + // Send speed change packet only for player + if (GetTypeId()!=TYPEID_PLAYER) + return; + + WorldPacket data; + if(!forced) + { + switch(mtype) + { + case MOVE_WALK: + data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_RUN: + data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_WALKBACK: + data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_SWIM: + data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_SWIMBACK: + data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_TURN: + data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_FLY: + data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + case MOVE_FLYBACK: + data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); + break; + default: + sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype); + return; + } + + data.append(GetPackGUID()); + data << uint32(0); //movement flags + data << uint8(0); //unk + data << uint32(getMSTime()); + data << float(GetPositionX()); + data << float(GetPositionY()); + data << float(GetPositionZ()); + data << float(GetOrientation()); + data << uint32(0); //flag unk + data << float(GetSpeed(mtype)); + SendMessageToSet( &data, true ); + } + else + { + // register forced speed changes for WorldSession::HandleForceSpeedChangeAck + // and do it only for real sent packets and use run for run/mounted as client expected + ++((Player*)this)->m_forced_speed_changes[mtype]; + switch(mtype) + { + case MOVE_WALK: + data.Initialize(SMSG_FORCE_WALK_SPEED_CHANGE, 16); + break; + case MOVE_RUN: + data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE, 17); + break; + case MOVE_WALKBACK: + data.Initialize(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, 16); + break; + case MOVE_SWIM: + data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, 16); + break; + case MOVE_SWIMBACK: + data.Initialize(SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, 16); + break; + case MOVE_TURN: + data.Initialize(SMSG_FORCE_TURN_RATE_CHANGE, 16); + break; + case MOVE_FLY: + data.Initialize(SMSG_FORCE_FLIGHT_SPEED_CHANGE, 16); + break; + case MOVE_FLYBACK: + data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16); + break; + default: + sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype); + return; + } + data.append(GetPackGUID()); + data << (uint32)0; + if (mtype == MOVE_RUN) + data << uint8(0); // new 2.1.0 + data << float(GetSpeed(mtype)); + SendMessageToSet( &data, true ); + } + if(Pet* pet = GetPet()) + pet->SetSpeed(MOVE_RUN, m_speed_rate[mtype],forced); +} + +void Unit::SetHover(bool on) +{ + if(on) + CastSpell(this,11010,true); + else + RemoveAurasDueToSpell(11010); +} + +void Unit::setDeathState(DeathState s) +{ + if (s != ALIVE && s!= JUST_ALIVED) + { + CombatStop(); + DeleteThreatList(); + ClearComboPointHolders(); // any combo points pointed to unit lost at it death + + if(IsNonMeleeSpellCasted(false)) + InterruptNonMeleeSpells(false); + } + + if (s == JUST_DIED) + { + RemoveAllAurasOnDeath(); + UnsummonAllTotems(); + + ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false); + ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false); + // remove aurastates allowing special moves + ClearAllReactives(); + ClearDiminishings(); + } + else if(s == JUST_ALIVED) + { + RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + } + + if (m_deathState != ALIVE && s == ALIVE) + { + //_ApplyAllAuraMods(); + } + m_deathState = s; +} + +/*######################################## +######## ######## +######## AGGRO SYSTEM ######## +######## ######## +########################################*/ +bool Unit::CanHaveThreatList() const +{ + // only creatures can have threat list + if( GetTypeId() != TYPEID_UNIT ) + return false; + + // only alive units can have threat list + if( !isAlive() ) + return false; + + // pets and totems can not have threat list + if( ((Creature*)this)->isPet() || ((Creature*)this)->isTotem() ) + return false; + + return true; +} + +//====================================================================== + +float Unit::ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask) +{ + if(!HasAuraType(SPELL_AURA_MOD_THREAT)) + return threat; + + SpellSchools school = GetFirstSchoolInMask(schoolMask); + + return threat * m_threatModifier[school]; +} + +//====================================================================== + +void Unit::AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask, SpellEntry const *threatSpell) +{ + // Only mobs can manage threat lists + if(CanHaveThreatList()) + m_ThreatManager.addThreat(pVictim, threat, schoolMask, threatSpell); +} + +//====================================================================== + +void Unit::DeleteThreatList() +{ + m_ThreatManager.clearReferences(); +} + +//====================================================================== + +void Unit::TauntApply(Unit* taunter) +{ + assert(GetTypeId()== TYPEID_UNIT); + + if(!taunter || (taunter->GetTypeId() == TYPEID_PLAYER && ((Player*)taunter)->isGameMaster())) + return; + + if(!CanHaveThreatList()) + return; + + Unit *target = getVictim(); + if(target && target == taunter) + return; + + SetInFront(taunter); + if (((Creature*)this)->AI()) + ((Creature*)this)->AI()->AttackStart(taunter); + + m_ThreatManager.tauntApply(taunter); +} + +//====================================================================== + +void Unit::TauntFadeOut(Unit *taunter) +{ + assert(GetTypeId()== TYPEID_UNIT); + + if(!taunter || (taunter->GetTypeId() == TYPEID_PLAYER && ((Player*)taunter)->isGameMaster())) + return; + + if(!CanHaveThreatList()) + return; + + Unit *target = getVictim(); + if(!target || target != taunter) + return; + + if(m_ThreatManager.isThreatListEmpty()) + { + if(((Creature*)this)->AI()) + ((Creature*)this)->AI()->EnterEvadeMode(); + return; + } + + m_ThreatManager.tauntFadeOut(taunter); + target = m_ThreatManager.getHostilTarget(); + + if (target && target != taunter) + { + SetInFront(target); + if (((Creature*)this)->AI()) + ((Creature*)this)->AI()->AttackStart(target); + } +} + +//====================================================================== + +bool Unit::SelectHostilTarget() +{ + //function provides main threat functionality + //next-victim-selection algorithm and evade mode are called + //threat list sorting etc. + + assert(GetTypeId()== TYPEID_UNIT); + Unit* target = NULL; + + //This function only useful once AI has been initilazied + if (!((Creature*)this)->AI()) + return false; + + if(!m_ThreatManager.isThreatListEmpty()) + { + if(!HasAuraType(SPELL_AURA_MOD_TAUNT)) + { + target = m_ThreatManager.getHostilTarget(); + } + } + + if(target) + { + if(!hasUnitState(UNIT_STAT_STUNNED)) + SetInFront(target); + ((Creature*)this)->AI()->AttackStart(target); + return true; + } + + // no target but something prevent go to evade mode + if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_TAUNT) ) + return false; + + // last case when creature don't must go to evade mode: + // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list + // for example at owner command to pet attack some far away creature + // Note: creature not have targeted movement generator but have attacker in this case + if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE ) + { + for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) + { + if( (*itr)->IsInMap(this) && (*itr)->isTargetableForAttack() && (*itr)->isInAccessablePlaceFor((Creature*)this) ) + return false; + } + } + + // enter in evade mode in other case + ((Creature*)this)->AI()->EnterEvadeMode(); + + return false; +} + +//====================================================================== +//====================================================================== +//====================================================================== + +int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 effBasePoints, Unit const* target) +{ + Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL; + + uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0; + + int32 level = int32(getLevel()) - int32(spellProto->spellLevel); + if (level > spellProto->maxLevel && spellProto->maxLevel > 0) + level = spellProto->maxLevel; + + float basePointsPerLevel = spellProto->EffectRealPointsPerLevel[effect_index]; + float randomPointsPerLevel = spellProto->EffectDicePerLevel[effect_index]; + int32 basePoints = int32(effBasePoints + level * basePointsPerLevel); + int32 randomPoints = int32(spellProto->EffectDieSides[effect_index] + level * randomPointsPerLevel); + float comboDamage = spellProto->EffectPointsPerComboPoint[effect_index]; + + // prevent random generator from getting confused by spells casted with Unit::CastCustomSpell + int32 randvalue = spellProto->EffectBaseDice[effect_index] >= randomPoints ? spellProto->EffectBaseDice[effect_index]:irand(spellProto->EffectBaseDice[effect_index], randomPoints); + int32 value = basePoints + randvalue; + //random damage + if(comboDamage != 0 && unitPlayer && target && (target->GetGUID() == unitPlayer->GetComboTarget())) + value += (int32)(comboDamage * comboPoints); + + if(Player* modOwner = GetSpellModOwner()) + { + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_ALL_EFFECTS, value); + switch(effect_index) + { + case 0: + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_EFFECT1, value); + break; + case 1: + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_EFFECT2, value); + break; + case 2: + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_EFFECT3, value); + break; + } + } + + if(spellProto->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION && spellProto->spellLevel && + spellProto->Effect[effect_index] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && + spellProto->Effect[effect_index] != SPELL_EFFECT_KNOCK_BACK) + value = int32(value*0.25f*exp(getLevel()*(70-spellProto->spellLevel)/1000.0f)); + + return value; +} + +int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target) +{ + Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL; + + uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0; + + int32 minduration = GetSpellDuration(spellProto); + int32 maxduration = GetSpellMaxDuration(spellProto); + + int32 duration; + + if( minduration != -1 && minduration != maxduration ) + duration = minduration + int32((maxduration - minduration) * comboPoints / 5); + else + duration = minduration; + + if (duration > 0) + { + int32 mechanic = GetEffectMechanic(spellProto, effect_index); + // Find total mod value (negative bonus) + int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic); + // Find max mod (negative bonus) + int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic); + + int32 durationMod = 0; + // Select strongest negative mod + if (durationMod_always > durationMod_not_stack) + durationMod = durationMod_not_stack; + else + durationMod = durationMod_always; + + if (durationMod != 0) + duration = int32(int64(duration) * (100+durationMod) /100); + + if (duration < 0) duration = 0; + } + + return duration; +} + +DiminishingLevels Unit::GetDiminishing(DiminishingGroup group) +{ + for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i) + { + if(i->DRGroup != group) + continue; + + if(!i->hitCount) + return DIMINISHING_LEVEL_1; + + if(!i->hitTime) + return DIMINISHING_LEVEL_1; + + // If last spell was casted more than 15 seconds ago - reset the count. + if(i->stack==0 && getMSTimeDiff(i->hitTime,getMSTime()) > 15000) + { + i->hitCount = DIMINISHING_LEVEL_1; + return DIMINISHING_LEVEL_1; + } + // or else increase the count. + else + { + return DiminishingLevels(i->hitCount); + } + } + return DIMINISHING_LEVEL_1; +} + +void Unit::IncrDiminishing(DiminishingGroup group) +{ + // Checking for existing in the table + bool IsExist = false; + for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i) + { + if(i->DRGroup != group) + continue; + + IsExist = true; + if(i->hitCount < DIMINISHING_LEVEL_IMMUNE) + i->hitCount += 1; + + break; + } + + if(!IsExist) + m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2)); +} + +void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level) +{ + if(duration == -1 || group == DIMINISHING_NONE || caster->IsFriendlyTo(this) ) + return; + + // Duration of crowd control abilities on pvp target is limited by 10 sec. (2.2.0) + if(duration > 10000 && IsDiminishingReturnsGroupDurationLimited(group)) + { + // test pet/charm masters instead pets/charmeds + Unit const* targetOwner = GetCharmerOrOwner(); + Unit const* casterOwner = caster->GetCharmerOrOwner(); + + Unit const* target = targetOwner ? targetOwner : this; + Unit const* source = casterOwner ? casterOwner : caster; + + if(target->GetTypeId() == TYPEID_PLAYER && source->GetTypeId() == TYPEID_PLAYER) + duration = 10000; + } + + float mod = 1.0f; + + // Some diminishings applies to mobs too (for example, Stun) + if((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER && GetTypeId() == TYPEID_PLAYER) || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL) + { + DiminishingLevels diminish = Level; + switch(diminish) + { + case DIMINISHING_LEVEL_1: break; + case DIMINISHING_LEVEL_2: mod = 0.5f; break; + case DIMINISHING_LEVEL_3: mod = 0.25f; break; + case DIMINISHING_LEVEL_IMMUNE: mod = 0.0f;break; + default: break; + } + } + + duration = int32(duration * mod); +} + +void Unit::ApplyDiminishingAura( DiminishingGroup group, bool apply ) +{ + // Checking for existing in the table + for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i) + { + if(i->DRGroup != group) + continue; + + i->hitTime = getMSTime(); + + if(apply) + i->stack += 1; + else if(i->stack) + i->stack -= 1; + + break; + } +} + +Unit* Unit::GetUnit(WorldObject& object, uint64 guid) +{ + return ObjectAccessor::GetUnit(object,guid); +} + +bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const +{ + return isVisibleForOrDetect(u,false,inVisibleList); +} + +uint32 Unit::GetCreatureType() const +{ + if(GetTypeId() == TYPEID_PLAYER) + { + SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(((Player*)this)->m_form); + if(ssEntry && ssEntry->creatureType > 0) + return ssEntry->creatureType; + else + return CREATURE_TYPE_HUMANOID; + } + else + return ((Creature*)this)->GetCreatureInfo()->type; +} + +/*####################################### +######## ######## +######## STAT SYSTEM ######## +######## ######## +#######################################*/ + +bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply) +{ + if(unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END) + { + sLog.outError("ERROR in HandleStatModifier(): nonexisted UnitMods or wrong UnitModifierType!"); + return false; + } + + float val = 1.0f; + + switch(modifierType) + { + case BASE_VALUE: + case TOTAL_VALUE: + m_auraModifiersGroup[unitMod][modifierType] += apply ? amount : -amount; + break; + case BASE_PCT: + case TOTAL_PCT: + if(amount <= -100.0f) //small hack-fix for -100% modifiers + amount = -200.0f; + + val = (100.0f + amount) / 100.0f; + m_auraModifiersGroup[unitMod][modifierType] *= apply ? val : (1.0f/val); + break; + + default: + break; + } + + if(!CanModifyStats()) + return false; + + switch(unitMod) + { + case UNIT_MOD_STAT_STRENGTH: + case UNIT_MOD_STAT_AGILITY: + case UNIT_MOD_STAT_STAMINA: + case UNIT_MOD_STAT_INTELLECT: + case UNIT_MOD_STAT_SPIRIT: UpdateStats(GetStatByAuraGroup(unitMod)); break; + + case UNIT_MOD_ARMOR: UpdateArmor(); break; + case UNIT_MOD_HEALTH: UpdateMaxHealth(); break; + + case UNIT_MOD_MANA: + case UNIT_MOD_RAGE: + case UNIT_MOD_FOCUS: + case UNIT_MOD_ENERGY: + case UNIT_MOD_HAPPINESS: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break; + + case UNIT_MOD_RESISTANCE_HOLY: + case UNIT_MOD_RESISTANCE_FIRE: + case UNIT_MOD_RESISTANCE_NATURE: + case UNIT_MOD_RESISTANCE_FROST: + case UNIT_MOD_RESISTANCE_SHADOW: + case UNIT_MOD_RESISTANCE_ARCANE: UpdateResistances(GetSpellSchoolByAuraGroup(unitMod)); break; + + case UNIT_MOD_ATTACK_POWER: UpdateAttackPowerAndDamage(); break; + case UNIT_MOD_ATTACK_POWER_RANGED: UpdateAttackPowerAndDamage(true); break; + + case UNIT_MOD_DAMAGE_MAINHAND: UpdateDamagePhysical(BASE_ATTACK); break; + case UNIT_MOD_DAMAGE_OFFHAND: UpdateDamagePhysical(OFF_ATTACK); break; + case UNIT_MOD_DAMAGE_RANGED: UpdateDamagePhysical(RANGED_ATTACK); break; + + default: + break; + } + + return true; +} + +float Unit::GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const +{ + if( unitMod >= UNIT_MOD_END || modifierType >= MODIFIER_TYPE_END) + { + sLog.outError("ERROR: trial to access nonexisted modifier value from UnitMods!"); + return 0.0f; + } + + if(modifierType == TOTAL_PCT && m_auraModifiersGroup[unitMod][modifierType] <= 0.0f) + return 0.0f; + + return m_auraModifiersGroup[unitMod][modifierType]; +} + +float Unit::GetTotalStatValue(Stats stat) const +{ + UnitMods unitMod = UnitMods(UNIT_MOD_STAT_START + stat); + + if(m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f) + return 0.0f; + + // value = ((base_value * base_pct) + total_value) * total_pct + float value = m_auraModifiersGroup[unitMod][BASE_VALUE] + GetCreateStat(stat); + value *= m_auraModifiersGroup[unitMod][BASE_PCT]; + value += m_auraModifiersGroup[unitMod][TOTAL_VALUE]; + value *= m_auraModifiersGroup[unitMod][TOTAL_PCT]; + + return value; +} + +float Unit::GetTotalAuraModValue(UnitMods unitMod) const +{ + if(unitMod >= UNIT_MOD_END) + { + sLog.outError("ERROR: trial to access nonexisted UnitMods in GetTotalAuraModValue()!"); + return 0.0f; + } + + if(m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f) + return 0.0f; + + float value = m_auraModifiersGroup[unitMod][BASE_VALUE]; + value *= m_auraModifiersGroup[unitMod][BASE_PCT]; + value += m_auraModifiersGroup[unitMod][TOTAL_VALUE]; + value *= m_auraModifiersGroup[unitMod][TOTAL_PCT]; + + return value; +} + +SpellSchools Unit::GetSpellSchoolByAuraGroup(UnitMods unitMod) const +{ + SpellSchools school = SPELL_SCHOOL_NORMAL; + + switch(unitMod) + { + case UNIT_MOD_RESISTANCE_HOLY: school = SPELL_SCHOOL_HOLY; break; + case UNIT_MOD_RESISTANCE_FIRE: school = SPELL_SCHOOL_FIRE; break; + case UNIT_MOD_RESISTANCE_NATURE: school = SPELL_SCHOOL_NATURE; break; + case UNIT_MOD_RESISTANCE_FROST: school = SPELL_SCHOOL_FROST; break; + case UNIT_MOD_RESISTANCE_SHADOW: school = SPELL_SCHOOL_SHADOW; break; + case UNIT_MOD_RESISTANCE_ARCANE: school = SPELL_SCHOOL_ARCANE; break; + + default: + break; + } + + return school; +} + +Stats Unit::GetStatByAuraGroup(UnitMods unitMod) const +{ + Stats stat = STAT_STRENGTH; + + switch(unitMod) + { + case UNIT_MOD_STAT_STRENGTH: stat = STAT_STRENGTH; break; + case UNIT_MOD_STAT_AGILITY: stat = STAT_AGILITY; break; + case UNIT_MOD_STAT_STAMINA: stat = STAT_STAMINA; break; + case UNIT_MOD_STAT_INTELLECT: stat = STAT_INTELLECT; break; + case UNIT_MOD_STAT_SPIRIT: stat = STAT_SPIRIT; break; + + default: + break; + } + + return stat; +} + +Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const +{ + Powers power = POWER_MANA; + + switch(unitMod) + { + case UNIT_MOD_MANA: power = POWER_MANA; break; + case UNIT_MOD_RAGE: power = POWER_RAGE; break; + case UNIT_MOD_FOCUS: power = POWER_FOCUS; break; + case UNIT_MOD_ENERGY: power = POWER_ENERGY; break; + case UNIT_MOD_HAPPINESS: power = POWER_HAPPINESS; break; + + default: + break; + } + + return power; +} + +float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const +{ + UnitMods unitMod = (attType == RANGED_ATTACK) ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; + + float val = GetTotalAuraModValue(unitMod); + if(val < 0.0f) + val = 0.0f; + + return val; +} + +float Unit::GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const +{ + if (attType == OFF_ATTACK && !haveOffhandWeapon()) + return 0.0f; + + return m_weaponDamage[attType][type]; +} + +void Unit::SetLevel(uint32 lvl) +{ + SetUInt32Value(UNIT_FIELD_LEVEL, lvl); + + // group update + if ((GetTypeId() == TYPEID_PLAYER) && ((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_LEVEL); +} + +void Unit::SetHealth(uint32 val) +{ + uint32 maxHealth = GetMaxHealth(); + if(maxHealth < val) + val = maxHealth; + + SetUInt32Value(UNIT_FIELD_HEALTH, val); + + // group update + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_HP); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP); + } + } +} + +void Unit::SetMaxHealth(uint32 val) +{ + uint32 health = GetHealth(); + SetUInt32Value(UNIT_FIELD_MAXHEALTH, val); + + // group update + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_HP); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP); + } + } + + if(val < health) + SetHealth(val); +} + +void Unit::SetPower(Powers power, uint32 val) +{ + uint32 maxPower = GetMaxPower(power); + if(maxPower < val) + val = maxPower; + + SetStatInt32Value(UNIT_FIELD_POWER1 + power, val); + + // group update + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); + } + + // Update the pet's character sheet with happiness damage bonus + if(pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS) + { + pet->UpdateDamagePhysical(BASE_ATTACK); + } + } +} + +void Unit::SetMaxPower(Powers power, uint32 val) +{ + uint32 cur_power = GetPower(power); + SetStatInt32Value(UNIT_FIELD_MAXPOWER1 + power, val); + + // group update + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER); + } + } + + if(val < cur_power) + SetPower(power, val); +} + +void Unit::ApplyPowerMod(Powers power, uint32 val, bool apply) +{ + ApplyModUInt32Value(UNIT_FIELD_POWER1+power, val, apply); + + // group update + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); + } + } +} + +void Unit::ApplyMaxPowerMod(Powers power, uint32 val, bool apply) +{ + ApplyModUInt32Value(UNIT_FIELD_MAXPOWER1+power, val, apply); + + // group update + if(GetTypeId() == TYPEID_PLAYER) + { + if(((Player*)this)->GetGroup()) + ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER); + } + else if(((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER); + } + } +} + +void Unit::ApplyAuraProcTriggerDamage( Aura* aura, bool apply ) +{ + AuraList& tAuraProcTriggerDamage = m_modAuras[SPELL_AURA_PROC_TRIGGER_DAMAGE]; + if(apply) + tAuraProcTriggerDamage.push_back(aura); + else + tAuraProcTriggerDamage.remove(aura); +} + +uint32 Unit::GetCreatePowers( Powers power ) const +{ + // POWER_FOCUS and POWER_HAPPINESS only have hunter pet + switch(power) + { + case POWER_MANA: return GetCreateMana(); + case POWER_RAGE: return 1000; + case POWER_FOCUS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 100); + case POWER_ENERGY: return 100; + case POWER_HAPPINESS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 1050000); + } + + return 0; +} + +void Unit::AddToWorld() +{ + Object::AddToWorld(); +} + +void Unit::RemoveFromWorld() +{ + // cleanup + if(IsInWorld()) + { + RemoveNotOwnSingleTargetAuras(); + } + + Object::RemoveFromWorld(); +} + +void Unit::CleanupsBeforeDelete() +{ + if(m_uint32Values) // only for fully created object + { + InterruptNonMeleeSpells(true); + m_Events.KillAllEvents(); + CombatStop(); + ClearComboPointHolders(); + DeleteThreatList(); + getHostilRefManager().setOnlineOfflineState(false); + RemoveAllAuras(); + RemoveAllGameObjects(); + RemoveAllDynObjects(); + GetMotionMaster()->Clear(false); // remove different non-standard movement generators. + } + RemoveFromWorld(); +} + +CharmInfo* Unit::InitCharmInfo(Unit *charm) +{ + if(!m_charmInfo) + m_charmInfo = new CharmInfo(charm); + return m_charmInfo; +} + +CharmInfo::CharmInfo(Unit* unit) +: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_ReactSate(REACT_PASSIVE), m_petnumber(0) +{ + for(int i =0; i<4; ++i) + { + m_charmspells[i].spellId = 0; + m_charmspells[i].active = ACT_DISABLED; + } +} + +void CharmInfo::InitPetActionBar() +{ + // the first 3 SpellOrActions are attack, follow and stay + for(uint32 i = 0; i < 3; i++) + { + PetActionBar[i].Type = ACT_COMMAND; + PetActionBar[i].SpellOrAction = COMMAND_ATTACK - i; + + PetActionBar[i + 7].Type = ACT_REACTION; + PetActionBar[i + 7].SpellOrAction = COMMAND_ATTACK - i; + } + for(uint32 i=0; i < 4; i++) + { + PetActionBar[i + 3].Type = ACT_DISABLED; + PetActionBar[i + 3].SpellOrAction = 0; + } +} + +void CharmInfo::InitEmptyActionBar() +{ + for(uint32 x = 1; x < 10; ++x) + { + PetActionBar[x].Type = ACT_CAST; + PetActionBar[x].SpellOrAction = 0; + } + PetActionBar[0].Type = ACT_COMMAND; + PetActionBar[0].SpellOrAction = COMMAND_ATTACK; +} + +void CharmInfo::InitPossessCreateSpells() +{ + if(m_unit->GetTypeId() == TYPEID_PLAYER) + return; + + InitEmptyActionBar(); //charm action bar + + for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) + { + if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x])) + m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true); + else + AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_CAST); + } +} + +void CharmInfo::InitCharmCreateSpells() +{ + if(m_unit->GetTypeId() == TYPEID_PLAYER) //charmed players don't have spells + { + InitEmptyActionBar(); + return; + } + + InitPetActionBar(); + + for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) + { + uint32 spellId = ((Creature*)m_unit)->m_spells[x]; + m_charmspells[x].spellId = spellId; + + if(!spellId) + continue; + + if (IsPassiveSpell(spellId)) + { + m_unit->CastSpell(m_unit, spellId, true); + m_charmspells[x].active = ACT_PASSIVE; + } + else + { + ActiveStates newstate; + bool onlyselfcast = true; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + + if(!spellInfo) onlyselfcast = false; + for(uint32 i = 0;i<3 && onlyselfcast;++i) //non existent spell will not make any problems as onlyselfcast would be false -> break right away + { + if(spellInfo->EffectImplicitTargetA[i] != TARGET_SELF && spellInfo->EffectImplicitTargetA[i] != 0) + onlyselfcast = false; + } + + if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable + newstate = ACT_DISABLED; + else + newstate = ACT_CAST; + + AddSpellToAB(0, spellId, newstate); + } + } +} + +bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate) +{ + for(uint8 i = 0; i < 10; i++) + { + if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid) + { + PetActionBar[i].SpellOrAction = newid; + if(!oldid) + { + if(newstate == ACT_DECIDE) + PetActionBar[i].Type = ACT_DISABLED; + else + PetActionBar[i].Type = newstate; + } + + return true; + } + } + return false; +} + +void CharmInfo::ToggleCreatureAutocast(uint32 spellid, bool apply) +{ + if(IsPassiveSpell(spellid)) + return; + + for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) + { + if(spellid == m_charmspells[x].spellId) + { + m_charmspells[x].active = apply ? ACT_ENABLED : ACT_DISABLED; + } + } +} + +void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow) +{ + m_petnumber = petnumber; + if(statwindow) + m_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, m_petnumber); + else + m_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0); +} + +bool Unit::isFrozen() const +{ + AuraList const& mRoot = GetAurasByType(SPELL_AURA_MOD_ROOT); + for(AuraList::const_iterator i = mRoot.begin(); i != mRoot.end(); ++i) + if( GetSpellSchoolMask((*i)->GetSpellProto()) & SPELL_SCHOOL_MASK_FROST) + return true; + return false; +} + +struct ProcTriggeredData +{ + ProcTriggeredData(SpellEntry const * _spellInfo, uint32 _spellParam, Aura* _triggeredByAura, uint32 _cooldown) + : spellInfo(_spellInfo), spellParam(_spellParam), triggeredByAura(_triggeredByAura), + triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())), + cooldown(_cooldown) + {} + + SpellEntry const * spellInfo; + uint32 spellParam; + Aura* triggeredByAura; + Unit::spellEffectPair triggeredByAura_SpellPair; + uint32 cooldown; +}; + +typedef std::list< ProcTriggeredData > ProcTriggeredList; + +void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask ) +{ + for(AuraTypeSet::const_iterator aur = procAuraTypes.begin(); aur != procAuraTypes.end(); ++aur) + { + // List of spells (effects) that proceed. Spell prototype and aura-specific value (damage for TRIGGER_DAMAGE) + ProcTriggeredList procTriggered; + + AuraList const& auras = GetAurasByType(*aur); + for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) + { + next = i; ++next; + + SpellEntry const *spellProto = (*i)->GetSpellProto(); + if(!spellProto) + continue; + + SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id); + if(!spellProcEvent) + { + // used to prevent spam in log about same non-handled spells + static std::set nonHandledSpellProcSet; + + if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end()) + { + sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's")); + nonHandledSpellProcSet.insert(spellProto->Id); + } + + // spell.dbc use totally different flags, that only can create problems if used. + continue; + } + + // Check spellProcEvent data requirements + if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag)) + continue; + + // Check if current equipment allows aura to proc + if(!isVictim && GetTypeId() == TYPEID_PLAYER ) + { + if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) + { + Item *item = ((Player*)this)->GetWeaponForAttack(attType,true); + + if(!item || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + continue; + } + else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) + { + // Check if player is wearing shield + Item *item = ((Player*)this)->GetShield(true); + if(!item || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + continue; + } + } + + float chance = (float)spellProto->procChance; + + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); + + if(!isVictim && spellProcEvent->ppmRate != 0) + { + uint32 WeaponSpeed = GetAttackTime(attType); + chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); + } + + if(roll_chance_f(chance)) + { + uint32 cooldown = spellProcEvent->cooldown; + + uint32 i_spell_eff = (*i)->GetEffIndex(); + + int32 i_spell_param; + switch(*aur) + { + case SPELL_AURA_PROC_TRIGGER_SPELL: + i_spell_param = procFlag; + break; + case SPELL_AURA_DUMMY: + case SPELL_AURA_PRAYER_OF_MENDING: + case SPELL_AURA_MOD_HASTE: + i_spell_param = i_spell_eff; + break; + case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: + i_spell_param = (*i)->GetModifier()->m_miscvalue; + break; + default: + i_spell_param = (*i)->GetModifier()->m_amount; + break; + } + + procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) ); + } + } + + // Handle effects proceed this time + for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i) + { + // Some auras can be deleted in function called in this loop (except first, ofc) + // Until storing auras in std::multimap to hard check deleting by another way + if(i != procTriggered.begin()) + { + bool found = false; + AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); + AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); + for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) + { + if(itr->second==i->triggeredByAura) + { + found = true; + break; + } + } + + if(!found) + { + sLog.outError("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler",*aur,i->triggeredByAura_SpellPair.first,i->triggeredByAura_SpellPair.second); + sLog.outError("It can be deleted one from early proccesed auras:"); + for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2) + sLog.outError(" Spell aura %u (id:%u effect:%u)",*aur,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second); + sLog.outError(" "); + continue; + } + } + + // save charges existence before processing to prevent crash at access to deleted triggered aura after + bool triggeredByAuraWithCharges = i->triggeredByAura->m_procCharges > 0; + + bool casted = false; + switch(*aur) + { + case SPELL_AURA_PROC_TRIGGER_SPELL: + { + sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); + casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown); + break; + } + case SPELL_AURA_PROC_TRIGGER_DAMAGE: + { + sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", i->spellParam, i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); + uint32 damage = i->spellParam; + SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true); + casted = true; + break; + } + case SPELL_AURA_DUMMY: + { + sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); + casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); + break; + } + case SPELL_AURA_PRAYER_OF_MENDING: + { + sLog.outDebug("ProcDamageAndSpell(mending): casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); + + // aura can be deleted at casts + int32 heal = i->triggeredByAura->GetModifier()->m_amount; + uint64 caster_guid = i->triggeredByAura->GetCasterGUID(); + + // jumps + int32 jumps = i->triggeredByAura->m_procCharges-1; + + // current aura expire + i->triggeredByAura->m_procCharges = 1; // will removed at next charges decrease + + // next target selection + if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) + { + Aura* aura = i->triggeredByAura; + + SpellEntry const* spellProto = aura->GetSpellProto(); + uint32 effIdx = aura->GetEffIndex(); + + float radius; + if (spellProto->EffectRadiusIndex[effIdx]) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); + else + radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); + + if(Player* caster = ((Player*)aura->GetCaster())) + { + caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); + + if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) + { + // aura will applied from caster, but spell casted from current aura holder + SpellModifier *mod = new SpellModifier; + mod->op = SPELLMOD_CHARGES; + mod->value = jumps-5; // negative + mod->type = SPELLMOD_FLAT; + mod->spellId = spellProto->Id; + mod->effectId = effIdx; + mod->lastAffected = NULL; + mod->mask = spellProto->SpellFamilyFlags; + mod->charges = 0; + + caster->AddSpellMod(mod, true); + CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID()); + caster->AddSpellMod(mod, false); + } + } + } + + // heal + CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); + casted = true; + break; + } + case SPELL_AURA_MOD_HASTE: + { + sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); + casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown); + break; + } + case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: + { + // nothing do, just charges counter + // but count only in case appropriate school damage + casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; + break; + } + case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: + { + sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId()); + casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown); + break; + } + default: + { + // nothing do, just charges counter + casted = true; + break; + } + } + + // Update charge (aura can be removed by triggers) + if(casted && triggeredByAuraWithCharges) + { + // need found aura (can be dropped by triggers) + AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); + AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); + for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) + { + if(itr->second == i->triggeredByAura) + { + if(i->triggeredByAura->m_procCharges > 0) + i->triggeredByAura->m_procCharges -= 1; + + i->triggeredByAura->UpdateAuraCharges(); + break; + } + } + } + } + + // Safely remove auras with zero charges + for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) + { + next = i; ++next; + if((*i)->m_procCharges == 0) + { + RemoveAurasDueToSpell((*i)->GetId()); + next = auras.begin(); + } + } + } +} + +SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const +{ + return SPELL_SCHOOL_MASK_NORMAL; +} + +Player* Unit::GetSpellModOwner() +{ + if(GetTypeId()==TYPEID_PLAYER) + return (Player*)this; + if(((Creature*)this)->isPet() || ((Creature*)this)->isTotem()) + { + Unit* owner = GetOwner(); + if(owner && owner->GetTypeId()==TYPEID_PLAYER) + return (Player*)owner; + } + return NULL; +} + +///----------Pet responses methods----------------- +void Unit::SendPetCastFail(uint32 spellid, uint8 msg) +{ + Unit *owner = GetCharmerOrOwner(); + if(!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_PET_CAST_FAILED, (4+1)); + data << uint32(spellid); + data << uint8(msg); + ((Player*)owner)->GetSession()->SendPacket(&data); +} + +void Unit::SendPetActionFeedback (uint8 msg) +{ + Unit* owner = GetOwner(); + if(!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_PET_ACTION_FEEDBACK, 1); + data << uint8(msg); + ((Player*)owner)->GetSession()->SendPacket(&data); +} + +void Unit::SendPetTalk (uint32 pettalk) +{ + Unit* owner = GetOwner(); + if(!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_PET_ACTION_SOUND, 8+4); + data << uint64(GetGUID()); + data << uint32(pettalk); + ((Player*)owner)->GetSession()->SendPacket(&data); +} + +void Unit::SendPetSpellCooldown (uint32 spellid, time_t cooltime) +{ + Unit* owner = GetOwner(); + if(!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4); + data << uint64(GetGUID()); + data << uint8(0x0); // flags (0x1, 0x2) + data << uint32(spellid); + data << uint32(cooltime); + + ((Player*)owner)->GetSession()->SendPacket(&data); +} + +void Unit::SendPetClearCooldown (uint32 spellid) +{ + Unit* owner = GetOwner(); + if(!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(spellid); + data << uint64(GetGUID()); + ((Player*)owner)->GetSession()->SendPacket(&data); +} + +void Unit::SendPetAIReaction(uint64 guid) +{ + Unit* owner = GetOwner(); + if(!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + WorldPacket data(SMSG_AI_REACTION, 12); + data << uint64(guid) << uint32(00000002); + ((Player*)owner)->GetSession()->SendPacket(&data); +} + +///----------End of Pet responses methods---------- + +void Unit::StopMoving() +{ + clearUnitState(UNIT_STAT_MOVING); + + // send explicit stop packet + // rely on vmaps here because for exemple stormwind is in air + float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); + //if (fabs(GetPositionZ() - z) < 2.0f) + // Relocate(GetPositionX(), GetPositionY(), z); + Relocate(GetPositionX(), GetPositionY(),GetPositionZ()); + + SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), 0, true, 0); + + // update position and orientation; + WorldPacket data; + BuildHeartBeatMsg(&data); + SendMessageToSet(&data,false); +} + +void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID) +{ + if( apply ) + { + if(HasAuraType(SPELL_AURA_PREVENTS_FLEEING)) + return; + + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); + + GetMotionMaster()->MovementExpired(false); + CastStop(GetGUID()==casterGUID ? spellID : 0); + + Unit* caster = ObjectAccessor::GetUnit(*this,casterGUID); + + GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing + } + else + { + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); + + GetMotionMaster()->MovementExpired(false); + + if( GetTypeId() != TYPEID_PLAYER && isAlive() ) + { + // restore appropriate movement generator + if(getVictim()) + GetMotionMaster()->MoveChase(getVictim()); + else + GetMotionMaster()->Initialize(); + + // attack caster if can + Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL); + if(caster && caster != getVictim() && ((Creature*)this)->AI()) + ((Creature*)this)->AI()->AttackStart(caster); + } + } + + if (GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->SetClientControl(this, !apply); +} + +void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID) +{ + if( apply ) + { + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); + + CastStop(GetGUID()==casterGUID ? spellID : 0); + + GetMotionMaster()->MoveConfused(); + } + else + { + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); + + GetMotionMaster()->MovementExpired(false); + + if (GetTypeId() == TYPEID_UNIT) + { + // if in combat restore movement generator + if(getVictim()) + GetMotionMaster()->MoveChase(getVictim()); + } + } + + if(GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->SetClientControl(this, !apply); +} + +bool Unit::IsSitState() const +{ + uint8 s = getStandState(); + return s == PLAYER_STATE_SIT_CHAIR || s == PLAYER_STATE_SIT_LOW_CHAIR || + s == PLAYER_STATE_SIT_MEDIUM_CHAIR || s == PLAYER_STATE_SIT_HIGH_CHAIR || + s == PLAYER_STATE_SIT; +} + +bool Unit::IsStandState() const +{ + uint8 s = getStandState(); + return !IsSitState() && s != PLAYER_STATE_SLEEP && s != PLAYER_STATE_KNEEL; +} + +void Unit::SetStandState(uint8 state) +{ + SetByteValue(UNIT_FIELD_BYTES_1, 0, state); + + if (IsStandState()) + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_SEATED); + + if(GetTypeId()==TYPEID_PLAYER) + { + WorldPacket data(SMSG_STANDSTATE_UPDATE, 1); + data << (uint8)state; + ((Player*)this)->GetSession()->SendPacket(&data); + } +} + +bool Unit::IsPolymorphed() const +{ + return GetSpellSpecific(getTransForm())==SPELL_MAGE_POLYMORPH; +} + +void Unit::SetDisplayId(uint32 modelId) +{ + SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId); + + if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(!pet->isControlled()) + return; + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); + } +} + +void Unit::ClearComboPointHolders() +{ + while(!m_ComboPointHolders.empty()) + { + uint32 lowguid = *m_ComboPointHolders.begin(); + + Player* plr = objmgr.GetPlayer(MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER)); + if(plr && plr->GetComboTarget()==GetGUID()) // recheck for safe + plr->ClearComboPoints(); // remove also guid from m_ComboPointHolders; + else + m_ComboPointHolders.erase(lowguid); // or remove manually + } +} + +void Unit::ClearAllReactives() +{ + + for(int i=0; i < MAX_REACTIVE; ++i) + m_reactiveTimer[i] = 0; + + if (HasAuraState( AURA_STATE_DEFENSE)) + ModifyAuraState(AURA_STATE_DEFENSE, false); + if (getClass() == CLASS_HUNTER && HasAuraState( AURA_STATE_HUNTER_PARRY)) + ModifyAuraState(AURA_STATE_HUNTER_PARRY, false); + if (HasAuraState( AURA_STATE_CRIT)) + ModifyAuraState(AURA_STATE_CRIT, false); + if (getClass() == CLASS_HUNTER && HasAuraState( AURA_STATE_HUNTER_CRIT_STRIKE) ) + ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false); + + if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->ClearComboPoints(); +} + +void Unit::UpdateReactives( uint32 p_time ) +{ + for(int i = 0; i < MAX_REACTIVE; ++i) + { + ReactiveType reactive = ReactiveType(i); + + if(!m_reactiveTimer[reactive]) + continue; + + if ( m_reactiveTimer[reactive] <= p_time) + { + m_reactiveTimer[reactive] = 0; + + switch ( reactive ) + { + case REACTIVE_DEFENSE: + if (HasAuraState(AURA_STATE_DEFENSE)) + ModifyAuraState(AURA_STATE_DEFENSE, false); + break; + case REACTIVE_HUNTER_PARRY: + if ( getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY)) + ModifyAuraState(AURA_STATE_HUNTER_PARRY, false); + break; + case REACTIVE_CRIT: + if (HasAuraState(AURA_STATE_CRIT)) + ModifyAuraState(AURA_STATE_CRIT, false); + break; + case REACTIVE_HUNTER_CRIT: + if ( getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_CRIT_STRIKE) ) + ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false); + break; + case REACTIVE_OVERPOWER: + if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->ClearComboPoints(); + break; + default: + break; + } + } + else + { + m_reactiveTimer[reactive] -= p_time; + } + } +} + +Unit* Unit::SelectNearbyTarget() const +{ + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + std::list targets; + + { + MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, ATTACK_DISTANCE); + MaNGOS::UnitListSearcher searcher(targets, u_check); + + TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); + TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_unit_searcher, *MapManager::Instance().GetMap(GetMapId(), this)); + cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(GetMapId(), this)); + } + + // remove current target + if(getVictim()) + targets.remove(getVictim()); + + // remove not LoS targets + for(std::list::iterator tIter = targets.begin(); tIter != targets.end();) + { + if(!IsWithinLOSInMap(*tIter)) + { + std::list::iterator tIter2 = tIter; + ++tIter; + targets.erase(tIter2); + } + else + ++tIter; + } + + // no appropriate targets + if(targets.empty()) + return NULL; + + // select random + uint32 rIdx = urand(0,targets.size()-1); + std::list::const_iterator tcIter = targets.begin(); + for(uint32 i = 0; i < rIdx; ++i) + ++tcIter; + + return *tcIter; +} + +void Unit::ApplyAttackTimePercentMod( WeaponAttackType att,float val, bool apply ) +{ + if(val > 0) + { + ApplyPercentModFloatVar(m_modAttackSpeedPct[att], val, !apply); + ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att,val,!apply); + } + else + { + ApplyPercentModFloatVar(m_modAttackSpeedPct[att], -val, apply); + ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att,-val,apply); + } +} + +void Unit::ApplyCastTimePercentMod(float val, bool apply ) +{ + if(val > 0) + ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,val,!apply); + else + ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,-val,apply); +} + +uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime ) +{ + if (CastingTime > 7000) CastingTime = 7000; + if (CastingTime < 1500) CastingTime = 1500; + + if(damagetype == DOT && !IsChanneledSpell(spellProto)) + CastingTime = 3500; + + int32 overTime = 0; + uint8 effects = 0; + bool DirectDamage = false; + bool AreaEffect = false; + + for ( uint32 i=0; i<3;i++) + { + switch ( spellProto->Effect[i] ) + { + case SPELL_EFFECT_SCHOOL_DAMAGE: + case SPELL_EFFECT_POWER_DRAIN: + case SPELL_EFFECT_HEALTH_LEECH: + case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE: + case SPELL_EFFECT_POWER_BURN: + case SPELL_EFFECT_HEAL: + DirectDamage = true; + break; + case SPELL_EFFECT_APPLY_AURA: + switch ( spellProto->EffectApplyAuraName[i] ) + { + case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_HEAL: + case SPELL_AURA_PERIODIC_LEECH: + if ( GetSpellDuration(spellProto) ) + overTime = GetSpellDuration(spellProto); + break; + default: + // -5% per additional effect + ++effects; + break; + } + default: + break; + } + + if(IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetA[i])) || IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetB[i]))) + AreaEffect = true; + } + + // Combined Spells with Both Over Time and Direct Damage + if ( overTime > 0 && CastingTime > 0 && DirectDamage ) + { + // mainly for DoTs which are 3500 here otherwise + uint32 OriginalCastTime = GetSpellCastTime(spellProto); + if (OriginalCastTime > 7000) OriginalCastTime = 7000; + if (OriginalCastTime < 1500) OriginalCastTime = 1500; + // Portion to Over Time + float PtOT = (overTime / 15000.f) / ((overTime / 15000.f) + (OriginalCastTime / 3500.f)); + + if ( damagetype == DOT ) + CastingTime = uint32(CastingTime * PtOT); + else if ( PtOT < 1.0f ) + CastingTime = uint32(CastingTime * (1 - PtOT)); + else + CastingTime = 0; + } + + // Area Effect Spells receive only half of bonus + if ( AreaEffect ) + CastingTime /= 2; + + // -5% of total per any additional effect + for ( uint8 i=0; i 175 ) + { + CastingTime -= 175; + } + else + { + CastingTime = 0; + break; + } + } + + return CastingTime; +} + +void Unit::UpdateAuraForGroup(uint8 slot) +{ + if(GetTypeId() == TYPEID_PLAYER) + { + Player* player = (Player*)this; + if(player->GetGroup()) + { + player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS); + player->SetAuraUpdateMask(slot); + } + } + else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) + { + Pet *pet = ((Pet*)this); + if(pet->isControlled()) + { + Unit *owner = GetOwner(); + if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) + { + ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS); + pet->SetAuraUpdateMask(slot); + } + } + } +} + +float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) +{ + if (!normalized || GetTypeId() != TYPEID_PLAYER) + return float(GetAttackTime(attType))/1000.0f; + + Item *Weapon = ((Player*)this)->GetWeaponForAttack(attType); + if (!Weapon) + return 2.4; // fist attack + + switch (Weapon->GetProto()->InventoryType) + { + case INVTYPE_2HWEAPON: + return 3.3; + case INVTYPE_RANGED: + case INVTYPE_RANGEDRIGHT: + case INVTYPE_THROWN: + return 2.8; + case INVTYPE_WEAPON: + case INVTYPE_WEAPONMAINHAND: + case INVTYPE_WEAPONOFFHAND: + default: + return Weapon->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_DAGGER ? 1.7 : 2.4; + } +} + +Aura* Unit::GetDummyAura( uint32 spell_id ) const +{ + Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) + if ((*itr)->GetId() == spell_id) + return *itr; + + return NULL; +} + +bool Unit::IsUnderLastManaUseEffect() const +{ + return getMSTimeDiff(m_lastManaUse,getMSTime()) < 5000; +} + +void Unit::SetContestedPvP(Player *attackedPlayer) +{ + Player* player = GetCharmerOrOwnerPlayerOrPlayerItself(); + + if(!player || attackedPlayer && (attackedPlayer == player || player->duel && player->duel->opponent == attackedPlayer)) + return; + + player->SetContestedPvPTimer(30000); + if(!player->hasUnitState(UNIT_STAT_ATTACK_PLAYER)) + { + player->addUnitState(UNIT_STAT_ATTACK_PLAYER); + player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP); + // call MoveInLineOfSight for nearby contested guards + SetVisibility(GetVisibility()); + } + if(!hasUnitState(UNIT_STAT_ATTACK_PLAYER)) + { + addUnitState(UNIT_STAT_ATTACK_PLAYER); + // call MoveInLineOfSight for nearby contested guards + SetVisibility(GetVisibility()); + } +} + +void Unit::AddPetAura(PetAura const* petSpell) +{ + m_petAuras.insert(petSpell); + if(Pet* pet = GetPet()) + pet->CastPetAura(petSpell); +} + +void Unit::RemovePetAura(PetAura const* petSpell) +{ + m_petAuras.erase(petSpell); + if(Pet* pet = GetPet()) + pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry())); +} diff --git a/src/game/Unit.h b/src/game/Unit.h new file mode 100644 index 000000000..c4495a282 --- /dev/null +++ b/src/game/Unit.h @@ -0,0 +1,1339 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __UNIT_H +#define __UNIT_H + +#include "Common.h" +#include "Object.h" +#include "Opcodes.h" +#include "Mthread.h" +#include "SpellAuraDefines.h" +#include "UpdateFields.h" +#include "SharedDefines.h" +#include "ThreatManager.h" +#include "HostilRefManager.h" +#include "FollowerReference.h" +#include "FollowerRefManager.h" +#include "Utilities/EventProcessor.h" +#include "MotionMaster.h" +#include "Database/DBCStructure.h" +#include + +enum SpellInterruptFlags +{ + SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, + SPELL_INTERRUPT_FLAG_DAMAGE = 0x02, + SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, + SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, + //SPELL_INTERRUPT_FLAG_TURNING = 0x10 // not turning - maybe _complete_ interrupt on direct damage? +}; + +enum SpellChannelInterruptFlags +{ + CHANNEL_FLAG_DAMAGE = 0x0002, + CHANNEL_FLAG_MOVEMENT = 0x0008, + CHANNEL_FLAG_TURNING = 0x0010, + CHANNEL_FLAG_DAMAGE2 = 0x0080, + CHANNEL_FLAG_DELAY = 0x4000 +}; + +enum SpellAuraInterruptFlags +{ + AURA_INTERRUPT_FLAG_UNK0 = 0x00000001, // 0 removed when getting hit by a negative spell? + AURA_INTERRUPT_FLAG_DAMAGE = 0x00000002, // 1 removed by any damage + AURA_INTERRUPT_FLAG_UNK2 = 0x00000004, // 2 + AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement + AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning + AURA_INTERRUPT_FLAG_ENTER_COMBAT = 0x00000020, // 5 removed by entering combat + AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by unmounting + AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water + AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water + AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing + AURA_INTERRUPT_FLAG_UNK10 = 0x00000400, // 10 + AURA_INTERRUPT_FLAG_UNK11 = 0x00000800, // 11 + AURA_INTERRUPT_FLAG_UNK12 = 0x00001000, // 12 removed by attack? + AURA_INTERRUPT_FLAG_UNK13 = 0x00002000, // 13 + AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14 + AURA_INTERRUPT_FLAG_UNK15 = 0x00008000, // 15 removed by casting a spell? + AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16 + AURA_INTERRUPT_FLAG_MOUNTING = 0x00020000, // 17 removed by mounting + AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up + AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported + AURA_INTERRUPT_FLAG_UNK20 = 0x00100000, // 20 + AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21 + AURA_INTERRUPT_FLAG_UNK22 = 0x00400000, // 22 + AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat + AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000 // 24 removed by any direct damage +}; + +enum SpellModOp +{ + SPELLMOD_DAMAGE = 0, + SPELLMOD_DURATION = 1, + SPELLMOD_THREAT = 2, + SPELLMOD_EFFECT1 = 3, + SPELLMOD_CHARGES = 4, + SPELLMOD_RANGE = 5, + SPELLMOD_RADIUS = 6, + SPELLMOD_CRITICAL_CHANCE = 7, + SPELLMOD_ALL_EFFECTS = 8, + SPELLMOD_NOT_LOSE_CASTING_TIME = 9, + SPELLMOD_CASTING_TIME = 10, + SPELLMOD_COOLDOWN = 11, + SPELLMOD_EFFECT2 = 12, + // spellmod 13 unused + SPELLMOD_COST = 14, + SPELLMOD_CRIT_DAMAGE_BONUS = 15, + SPELLMOD_RESIST_MISS_CHANCE = 16, + SPELLMOD_JUMP_TARGETS = 17, + SPELLMOD_CHANCE_OF_SUCCESS = 18, + SPELLMOD_ACTIVATION_TIME = 19, + SPELLMOD_EFFECT_PAST_FIRST = 20, + SPELLMOD_CASTING_TIME_OLD = 21, + SPELLMOD_DOT = 22, + SPELLMOD_EFFECT3 = 23, + SPELLMOD_SPELL_BONUS_DAMAGE = 24, + // spellmod 25, 26 unused + SPELLMOD_MULTIPLE_VALUE = 27, + SPELLMOD_RESIST_DISPEL_CHANCE = 28 +}; + +#define MAX_SPELLMOD 32 + +enum SpellFacingFlags +{ + SPELL_FACING_FLAG_INFRONT = 0x0001 +}; + +#define BASE_MINDAMAGE 1.0f +#define BASE_MAXDAMAGE 2.0f +#define BASE_ATTACK_TIME 2000 + +// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2 +enum ShapeshiftForm +{ + FORM_NONE = 0x00, + FORM_CAT = 0x01, + FORM_TREE = 0x02, + FORM_TRAVEL = 0x03, + FORM_AQUA = 0x04, + FORM_BEAR = 0x05, + FORM_AMBIENT = 0x06, + FORM_GHOUL = 0x07, + FORM_DIREBEAR = 0x08, + FORM_CREATUREBEAR = 0x0E, + FORM_CREATURECAT = 0x0F, + FORM_GHOSTWOLF = 0x10, + FORM_BATTLESTANCE = 0x11, + FORM_DEFENSIVESTANCE = 0x12, + FORM_BERSERKERSTANCE = 0x13, + FORM_TEST = 0x14, + FORM_ZOMBIE = 0x15, + FORM_FLIGHT_EPIC = 0x1B, + FORM_SHADOW = 0x1C, + FORM_FLIGHT = 0x1D, + FORM_STEALTH = 0x1E, + FORM_MOONKIN = 0x1F, + FORM_SPIRITOFREDEMPTION = 0x20 +}; + +// low byte ( 0 from 0..3 ) of UNIT_FIELD_BYTES_2 +enum SheathState +{ + SHEATH_STATE_UNARMED = 0, // non prepared weapon + SHEATH_STATE_MELEE = 1, // prepared melee weapon + SHEATH_STATE_RANGED = 2 // prepared ranged weapon +}; + +// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitBytes2_Flags +{ + UNIT_BYTE2_FLAG_UNK0 = 0x01, + UNIT_BYTE2_FLAG_UNK1 = 0x02, + UNIT_BYTE2_FLAG_UNK2 = 0x04, + UNIT_BYTE2_FLAG_UNK3 = 0x08, + UNIT_BYTE2_FLAG_AURAS = 0x10, // show possitive auras as positive, and allow its dispel + UNIT_BYTE2_FLAG_UNK5 = 0x20, + UNIT_BYTE2_FLAG_UNK6 = 0x40, + UNIT_BYTE2_FLAG_UNK7 = 0x80 +}; + +// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitRename +{ + UNIT_RENAME_NOT_ALLOWED = 0x02, + UNIT_RENAME_ALLOWED = 0x03 +}; + +#define CREATURE_MAX_SPELLS 4 + +enum Swing +{ + NOSWING = 0, + SINGLEHANDEDSWING = 1, + TWOHANDEDSWING = 2 +}; + +enum VictimState +{ + VICTIMSTATE_UNKNOWN1 = 0, + VICTIMSTATE_NORMAL = 1, + VICTIMSTATE_DODGE = 2, + VICTIMSTATE_PARRY = 3, + VICTIMSTATE_INTERRUPT = 4, + VICTIMSTATE_BLOCKS = 5, + VICTIMSTATE_EVADES = 6, + VICTIMSTATE_IS_IMMUNE = 7, + VICTIMSTATE_DEFLECTS = 8 +}; + +enum HitInfo +{ + HITINFO_NORMALSWING = 0x00000000, + HITINFO_UNK1 = 0x00000001, // req correct packet structure + HITINFO_NORMALSWING2 = 0x00000002, + HITINFO_LEFTSWING = 0x00000004, + HITINFO_MISS = 0x00000010, + HITINFO_ABSORB = 0x00000020, // plays absorb sound + HITINFO_RESIST = 0x00000040, // resisted atleast some damage + HITINFO_CRITICALHIT = 0x00000080, + HITINFO_UNK2 = 0x00000100, // wotlk? + HITINFO_UNK3 = 0x00002000, // wotlk? + HITINFO_GLANCING = 0x00004000, + HITINFO_CRUSHING = 0x00008000, + HITINFO_NOACTION = 0x00010000, + HITINFO_SWINGNOHITSOUND = 0x00080000 +}; + +//i would like to remove this: (it is defined in item.h +enum InventorySlot +{ + NULL_BAG = 0, + NULL_SLOT = 255 +}; + +struct FactionTemplateEntry; +struct Modifier; +struct SpellEntry; +struct SpellEntryExt; + +class Aura; +class Creature; +class Spell; +class DynamicObject; +class GameObject; +class Item; +class Pet; +class Path; +class PetAura; + +struct SpellImmune +{ + uint32 type; + uint32 spellId; +}; + +typedef std::list SpellImmuneList; + +enum UnitModifierType +{ + BASE_VALUE = 0, + BASE_PCT = 1, + TOTAL_VALUE = 2, + TOTAL_PCT = 3, + MODIFIER_TYPE_END = 4 +}; + +enum WeaponDamageRange +{ + MINDAMAGE, + MAXDAMAGE +}; + +enum DamageTypeToSchool +{ + RESISTANCE, + DAMAGE_DEALT, + DAMAGE_TAKEN +}; + +enum AuraRemoveMode +{ + AURA_REMOVE_BY_DEFAULT, + AURA_REMOVE_BY_STACK, // at replace by semillar aura + AURA_REMOVE_BY_CANCEL, + AURA_REMOVE_BY_DISPEL, + AURA_REMOVE_BY_DEATH +}; + +enum UnitMods +{ + UNIT_MOD_STAT_STRENGTH, // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_SPIRIT must be in existed order, it's accessed by index values of Stats enum. + UNIT_MOD_STAT_AGILITY, + UNIT_MOD_STAT_STAMINA, + UNIT_MOD_STAT_INTELLECT, + UNIT_MOD_STAT_SPIRIT, + UNIT_MOD_HEALTH, + UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existed order, it's accessed by index values of Powers enum. + UNIT_MOD_RAGE, + UNIT_MOD_FOCUS, + UNIT_MOD_ENERGY, + UNIT_MOD_HAPPINESS, + UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum. + UNIT_MOD_RESISTANCE_HOLY, + UNIT_MOD_RESISTANCE_FIRE, + UNIT_MOD_RESISTANCE_NATURE, + UNIT_MOD_RESISTANCE_FROST, + UNIT_MOD_RESISTANCE_SHADOW, + UNIT_MOD_RESISTANCE_ARCANE, + UNIT_MOD_ATTACK_POWER, + UNIT_MOD_ATTACK_POWER_RANGED, + UNIT_MOD_DAMAGE_MAINHAND, + UNIT_MOD_DAMAGE_OFFHAND, + UNIT_MOD_DAMAGE_RANGED, + UNIT_MOD_END, + // synonyms + UNIT_MOD_STAT_START = UNIT_MOD_STAT_STRENGTH, + UNIT_MOD_STAT_END = UNIT_MOD_STAT_SPIRIT + 1, + UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR, + UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1, + UNIT_MOD_POWER_START = UNIT_MOD_MANA, + UNIT_MOD_POWER_END = UNIT_MOD_HAPPINESS + 1 +}; + +enum BaseModGroup +{ + CRIT_PERCENTAGE, + RANGED_CRIT_PERCENTAGE, + OFFHAND_CRIT_PERCENTAGE, + SHIELD_BLOCK_VALUE, + BASEMOD_END +}; + +enum BaseModType +{ + FLAT_MOD, + PCT_MOD +}; + +#define MOD_END (PCT_MOD+1) + +enum DeathState +{ + ALIVE = 0, + JUST_DIED = 1, + CORPSE = 2, + DEAD = 3, + JUST_ALIVED = 4 +}; + +enum UnitState +{ + UNIT_STAT_DIED = 0x0001, + UNIT_STAT_MELEE_ATTACKING = 0x0002, // player is melee attacking someone + //UNIT_STAT_MELEE_ATTACK_BY = 0x0004, // player is melee attack by someone + UNIT_STAT_STUNNED = 0x0008, + UNIT_STAT_ROAMING = 0x0010, + UNIT_STAT_CHASE = 0x0020, + UNIT_STAT_SEARCHING = 0x0040, + UNIT_STAT_FLEEING = 0x0080, + UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING), + UNIT_STAT_IN_FLIGHT = 0x0100, // player is in flight mode + UNIT_STAT_FOLLOW = 0x0200, + UNIT_STAT_ROOT = 0x0400, + UNIT_STAT_CONFUSED = 0x0800, + UNIT_STAT_DISTRACTED = 0x1000, + UNIT_STAT_ISOLATED = 0x2000, // area auras do not affect other players + UNIT_STAT_ATTACK_PLAYER = 0x4000, + UNIT_STAT_ALL_STATE = 0xffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) +}; + +enum UnitMoveType +{ + MOVE_WALK = 0, + MOVE_RUN = 1, + MOVE_WALKBACK = 2, + MOVE_SWIM = 3, + MOVE_SWIMBACK = 4, + MOVE_TURN = 5, + MOVE_FLY = 6, + MOVE_FLYBACK = 7 +}; + +#define MAX_MOVE_TYPE 8 + +extern float baseMoveSpeed[MAX_MOVE_TYPE]; + +enum WeaponAttackType +{ + BASE_ATTACK = 0, + OFF_ATTACK = 1, + RANGED_ATTACK = 2 +}; + +#define MAX_ATTACK 3 + +enum CombatRating +{ + CR_WEAPON_SKILL = 0, + CR_DEFENSE_SKILL = 1, + CR_DODGE = 2, + CR_PARRY = 3, + CR_BLOCK = 4, + CR_HIT_MELEE = 5, + CR_HIT_RANGED = 6, + CR_HIT_SPELL = 7, + CR_CRIT_MELEE = 8, + CR_CRIT_RANGED = 9, + CR_CRIT_SPELL = 10, + CR_HIT_TAKEN_MELEE = 11, + CR_HIT_TAKEN_RANGED = 12, + CR_HIT_TAKEN_SPELL = 13, + CR_CRIT_TAKEN_MELEE = 14, + CR_CRIT_TAKEN_RANGED = 15, + CR_CRIT_TAKEN_SPELL = 16, + CR_HASTE_MELEE = 17, + CR_HASTE_RANGED = 18, + CR_HASTE_SPELL = 19, + CR_WEAPON_SKILL_MAINHAND = 20, + CR_WEAPON_SKILL_OFFHAND = 21, + CR_WEAPON_SKILL_RANGED = 22, + CR_EXPERTISE = 23 +}; + +#define MAX_COMBAT_RATING 24 + +enum DamageEffectType +{ + DIRECT_DAMAGE = 0, // used for normal weapon damage (not for class abilities or spells) + SPELL_DIRECT_DAMAGE = 1, // spell/class abilities damage + DOT = 2, + HEAL = 3, + NODAMAGE = 4, // used also in case when damage applied to health but not applied to spell channelInterruptFlags/etc + SELF_DAMAGE = 5 +}; + +enum UnitVisibility +{ + VISIBILITY_OFF = 0, // absolute, not detectable, GM-like, can see all other + VISIBILITY_ON = 1, + VISIBILITY_GROUP_STEALTH = 2, // detect chance, seen and can see group members + VISIBILITY_GROUP_INVISIBILITY = 3, // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) + VISIBILITY_GROUP_NO_DETECT = 4, // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break + VISIBILITY_RESPAWN = 5 // special totally not detectable visibility for force delete object at respawn command +}; + +// Value masks for UNIT_FIELD_FLAGS +enum UnitFlags +{ + UNIT_FLAG_UNKNOWN7 = 0x00000001, + UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable + UNIT_FLAG_DISABLE_MOVE = 0x00000004, + UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state + UNIT_FLAG_RENAME = 0x00000010, + UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP + UNIT_FLAG_UNKNOWN9 = 0x00000040, + UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE + UNIT_FLAG_UNKNOWN2 = 0x00000100, // 2.0.8 + UNIT_FLAG_UNKNOWN11 = 0x00000200, + UNIT_FLAG_LOOTING = 0x00000400, // loot animation + UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 + UNIT_FLAG_PVP = 0x00001000, + UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 + UNIT_FLAG_UNKNOWN4 = 0x00004000, // 2.0.8 + UNIT_FLAG_UNKNOWN13 = 0x00008000, + UNIT_FLAG_UNKNOWN14 = 0x00010000, + UNIT_FLAG_PACIFIED = 0x00020000, + UNIT_FLAG_DISABLE_ROTATE = 0x00040000, // stunned, 2.1.1 + UNIT_FLAG_IN_COMBAT = 0x00080000, + UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag + UNIT_FLAG_DISARMED = 0x00200000, // disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. + UNIT_FLAG_CONFUSED = 0x00400000, + UNIT_FLAG_FLEEING = 0x00800000, + UNIT_FLAG_UNKNOWN5 = 0x01000000, // used in spell Eyes of the Beast for pet... + UNIT_FLAG_NOT_SELECTABLE = 0x02000000, + UNIT_FLAG_SKINNABLE = 0x04000000, + UNIT_FLAG_MOUNT = 0x08000000, + UNIT_FLAG_UNKNOWN17 = 0x10000000, + UNIT_FLAG_UNKNOWN6 = 0x20000000, // used in Feing Death spell + UNIT_FLAG_SHEATHE = 0x40000000 +}; + +// Value masks for UNIT_FIELD_FLAGS_2 +enum UnitFlags2 +{ + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_COMPREHEND_LANG= 0x00000008, + UNIT_FLAG2_FORCE_MOVE = 0x00000040 +}; + +/// Non Player Character flags +enum NPCFlags +{ + UNIT_NPC_FLAG_NONE = 0x00000000, + UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100% + UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok + UNIT_NPC_FLAG_UNK1 = 0x00000004, + UNIT_NPC_FLAG_UNK2 = 0x00000008, + UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100% + UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // 100% + UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // 100% + UNIT_NPC_FLAG_VENDOR = 0x00000080, // 100% + UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // 100%, general goods vendor + UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // 100% + UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // guessed + UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // 100% + UNIT_NPC_FLAG_REPAIR = 0x00001000, // 100% + UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // 100% + UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // guessed + UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // guessed + UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // 100% + UNIT_NPC_FLAG_BANKER = 0x00020000, // 100% + UNIT_NPC_FLAG_PETITIONER = 0x00040000, // 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions + UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // 100% + UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // 100% + UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // 100% + UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% + UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode + UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) + UNIT_NPC_FLAG_GUARD = 0x10000000, // custom flag for guards +}; + +enum MovementFlags +{ + MOVEMENTFLAG_NONE = 0x00000000, + MOVEMENTFLAG_FORWARD = 0x00000001, + MOVEMENTFLAG_BACKWARD = 0x00000002, + MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, + MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, + MOVEMENTFLAG_LEFT = 0x00000010, + MOVEMENTFLAG_RIGHT = 0x00000020, + MOVEMENTFLAG_PITCH_UP = 0x00000040, + MOVEMENTFLAG_PITCH_DOWN = 0x00000080, + MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking + MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures + MOVEMENTFLAG_LEVITATING = 0x00000400, + MOVEMENTFLAG_FLY_UNK1 = 0x00000800, + MOVEMENTFLAG_JUMPING = 0x00001000, + MOVEMENTFLAG_UNK4 = 0x00002000, + MOVEMENTFLAG_FALLING = 0x00004000, + // 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000 + MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also + MOVEMENTFLAG_FLY_UP = 0x00400000, + MOVEMENTFLAG_CAN_FLY = 0x00800000, + MOVEMENTFLAG_FLYING = 0x01000000, + MOVEMENTFLAG_FLYING2 = 0x02000000, // Actual flying mode + MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths + MOVEMENTFLAG_SPLINE2 = 0x08000000, // used for flight paths + MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water + MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive) + MOVEMENTFLAG_UNK3 = 0x40000000 +}; + +enum DiminishingLevels +{ + DIMINISHING_LEVEL_1 = 0, + DIMINISHING_LEVEL_2 = 1, + DIMINISHING_LEVEL_3 = 2, + DIMINISHING_LEVEL_IMMUNE = 3 +}; + +struct DiminishingReturn +{ + DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count) : DRGroup(group), hitTime(t), hitCount(count), stack(0) {} + + DiminishingGroup DRGroup:16; + uint16 stack:16; + uint32 hitTime; + uint32 hitCount; +}; + +enum MeleeHitOutcome +{ + MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY, + MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL, MELEE_HIT_BLOCK_CRIT +}; +struct CleanDamage +{ + CleanDamage(uint32 _damage, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) : + damage(_damage), attackType(_attackType), hitOutCome(_hitOutCome) {} + + uint32 damage; + WeaponAttackType attackType; + MeleeHitOutcome hitOutCome; +}; + +struct UnitActionBarEntry +{ + uint32 Type; + uint32 SpellOrAction; +}; + +#define MAX_DECLINED_NAME_CASES 5 + +struct DeclinedName +{ + std::string name[MAX_DECLINED_NAME_CASES]; +}; + +enum CurrentSpellTypes +{ + CURRENT_MELEE_SPELL = 0, + CURRENT_FIRST_NON_MELEE_SPELL = 1, // just counter + CURRENT_GENERIC_SPELL = 1, + CURRENT_AUTOREPEAT_SPELL = 2, + CURRENT_CHANNELED_SPELL = 3, + CURRENT_MAX_SPELL = 4 // just counter +}; + +enum ActiveStates +{ + ACT_ENABLED = 0xC100, + ACT_DISABLED = 0x8100, + ACT_COMMAND = 0x0700, + ACT_REACTION = 0x0600, + ACT_CAST = 0x0100, + ACT_PASSIVE = 0x0000, + ACT_DECIDE = 0x0001 +}; + +enum ReactStates +{ + REACT_PASSIVE = 0, + REACT_DEFENSIVE = 1, + REACT_AGGRESSIVE = 2 +}; + +enum CommandStates +{ + COMMAND_STAY = 0, + COMMAND_FOLLOW = 1, + COMMAND_ATTACK = 2, + COMMAND_ABANDON = 3 +}; + +struct CharmSpellEntry +{ + uint16 spellId; + uint16 active; +}; + +struct CharmInfo +{ + public: + explicit CharmInfo(Unit* unit); + uint32 GetPetNumber() const { return m_petnumber; } + void SetPetNumber(uint32 petnumber, bool statwindow); + + void SetCommandState(CommandStates st) { m_CommandState = st; } + CommandStates GetCommandState() { return m_CommandState; } + bool HasCommandState(CommandStates state) { return (m_CommandState == state); } + void SetReactState(ReactStates st) { m_ReactSate = st; } + ReactStates GetReactState() { return m_ReactSate; } + bool HasReactState(ReactStates state) { return (m_ReactSate == state); } + + void InitPossessCreateSpells(); + void InitCharmCreateSpells(); + void InitPetActionBar(); + void InitEmptyActionBar(); + //return true if successful + bool AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate = ACT_DECIDE); + void ToggleCreatureAutocast(uint32 spellid, bool apply); + + UnitActionBarEntry* GetActionBarEntry(uint8 index) { return &(PetActionBar[index]); } + CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); } + private: + Unit* m_unit; + UnitActionBarEntry PetActionBar[10]; + CharmSpellEntry m_charmspells[4]; + CommandStates m_CommandState; + ReactStates m_ReactSate; + uint32 m_petnumber; +}; + +// for clearing special attacks +#define REACTIVE_TIMER_START 4000 + +enum ReactiveType +{ + REACTIVE_DEFENSE = 1, + REACTIVE_HUNTER_PARRY = 2, + REACTIVE_CRIT = 3, + REACTIVE_HUNTER_CRIT = 4, + REACTIVE_OVERPOWER = 5 +}; + +#define MAX_REACTIVE 6 +#define MAX_TOTEM 4 + +// delay time next attack to prevent client attack animation problems +#define ATTACK_DISPLAY_DELAY 200 + +class MANGOS_DLL_SPEC Unit : public WorldObject +{ + public: + typedef std::set AttackerSet; + typedef std::pair spellEffectPair; + typedef std::multimap< spellEffectPair, Aura*> AuraMap; + typedef std::list AuraList; + typedef std::list Diminishing; + typedef std::set AuraTypeSet; + typedef std::set ComboPointHolderSet; + + virtual ~Unit ( ); + + void AddToWorld(); + void RemoveFromWorld(); + + void CleanupsBeforeDelete(); // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units) + + DiminishingLevels GetDiminishing(DiminishingGroup group); + void IncrDiminishing(DiminishingGroup group); + void ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level); + void ApplyDiminishingAura(DiminishingGroup group, bool apply); + void ClearDiminishings() { m_Diminishing.clear(); } + + virtual void Update( uint32 time ); + + void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; } + void resetAttackTimer(WeaponAttackType type = BASE_ATTACK); + uint32 getAttackTimer(WeaponAttackType type) const { return m_attackTimer[type]; } + bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; } + bool haveOffhandWeapon() const; + bool canReachWithAttack(Unit *pVictim) const; + uint32 m_extraAttacks; + + void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*) + { + AttackerSet::iterator itr = m_attackers.find(pAttacker); + if(itr == m_attackers.end()) + m_attackers.insert(pAttacker); + } + void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop() + { + AttackerSet::iterator itr = m_attackers.find(pAttacker); + if(itr != m_attackers.end()) + m_attackers.erase(itr); + } + Unit * getAttackerForHelper() // If someone wants to help, who to give them + { + if (getVictim() != NULL) + return getVictim(); + + if (!m_attackers.empty()) + return *(m_attackers.begin()); + + return NULL; + } + bool Attack(Unit *victim, bool meleeAttack); + void CastStop(uint32 except_spellid = 0); + bool AttackStop(); + void RemoveAllAttackers(); + AttackerSet const& getAttackers() const { return m_attackers; } + bool isAttackingPlayer() const; + Unit* getVictim() const { return m_attacking; } + void CombatStop(bool cast = false); + void CombatStopWithPets(bool cast = false); + Unit* SelectNearbyTarget() const; + + void addUnitState(uint32 f) { m_state |= f; } + bool hasUnitState(const uint32 f) const { return (m_state & f); } + void clearUnitState(uint32 f) { m_state &= ~f; } + bool CanFreeMove() const + { + return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT | + UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0; + } + + uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); } + virtual uint32 getLevelForTarget(Unit const* /*target*/) const { return getLevel(); } + void SetLevel(uint32 lvl); + uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); } + uint32 getRaceMask() const { return 1 << (getRace()-1); } + uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); } + uint32 getClassMask() const { return 1 << (getClass()-1); } + uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); } + + float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0+stat)); } + void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0+stat, val); } + uint32 GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; } + void SetArmor(int32 val) { SetResistance(SPELL_SCHOOL_NORMAL, val); } + + uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(UNIT_FIELD_RESISTANCES+school); } + void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES+school,val); } + + uint32 GetHealth() const { return GetUInt32Value(UNIT_FIELD_HEALTH); } + uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); } + void SetHealth( uint32 val); + void SetMaxHealth(uint32 val); + int32 ModifyHealth(int32 val); + + Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); } + void setPowerType(Powers power); + uint32 GetPower( Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); } + uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); } + void SetPower( Powers power, uint32 val); + void SetMaxPower(Powers power, uint32 val); + int32 ModifyPower(Powers power, int32 val); + void ApplyPowerMod(Powers power, uint32 val, bool apply); + void ApplyMaxPowerMod(Powers power, uint32 val, bool apply); + + uint32 GetAttackTime(WeaponAttackType att) const { return (uint32)(GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att)/m_modAttackSpeedPct[att]); } + void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME+att,val*m_modAttackSpeedPct[att]); } + void ApplyAttackTimePercentMod(WeaponAttackType att,float val, bool apply); + void ApplyCastTimePercentMod(float val, bool apply); + + // faction template id + uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); } + void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction ); } + FactionTemplateEntry const* getFactionTemplateEntry() const; + bool IsHostileTo(Unit const* unit) const; + bool IsHostileToPlayers() const; + bool IsFriendlyTo(Unit const* unit) const; + bool IsNeutralToAll() const; + bool IsContestedGuard() const + { + if(FactionTemplateEntry const* entry = getFactionTemplateEntry()) + return entry->IsContestedGuardFaction(); + + return false; + } + bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); } + void SetPvP(bool state) { if(state) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); } + uint32 GetCreatureType() const; + uint32 GetCreatureTypeMask() const + { + uint32 creatureType = GetCreatureType(); + return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0; + } + + uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); } + bool IsSitState() const; + bool IsStandState() const; + void SetStandState(uint8 state); + + bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); } + uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); } + void Mount(uint32 mount); + void Unmount(); + + uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } + uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss); + void DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit = false, bool isTriggeredSpell = false); + void DoAttackDamage(Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false); + + void CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchoolMask damageSchoolMask, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false); + void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage = 0, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NONE, SpellEntry const *procSpell = NULL, bool isTriggeredSpell = false, WeaponAttackType attType = BASE_ATTACK); + void HandleEmoteCommand(uint32 anim_id); + void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false ); + + float MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const; + SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell); + SpellMissInfo SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool canReflect = false); + + float GetUnitDodgeChance() const; + float GetUnitParryChance() const; + float GetUnitBlockChance() const; + float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const; + + virtual uint32 GetShieldBlockValue() const =0; + uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } + uint32 GetDefenseSkillValue(Unit const* target = NULL) const; + uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const; + float GetWeaponProcChance() const; + float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const; + MeleeHitOutcome RollPhysicalOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo); + MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const; + MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const; + + bool isVendor() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ); } + bool isTrainer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER ); } + bool isQuestGiver() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER ); } + bool isGossip() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP ); } + bool isTaxi() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_FLIGHTMASTER ); } + bool isGuildMaster() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PETITIONER ); } + bool isBattleMaster() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BATTLEMASTER ); } + bool isBanker() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER ); } + bool isInnkeeper() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER ); } + bool isSpiritHealer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER ); } + bool isSpiritGuide() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE ); } + bool isTabardDesigner()const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER ); } + bool isAuctioner() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER ); } + bool isArmorer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR ); } + bool isServiceProvider() const + { + return HasFlag( UNIT_NPC_FLAGS, + UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER | + UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER | + UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_GUARD | UNIT_NPC_FLAG_SPIRITHEALER | + UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER ); + } + bool isSpiritService() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE ); } + + //Need fix or use this + bool isGuard() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GUARD); } + + bool isInFlight() const { return hasUnitState(UNIT_STAT_IN_FLIGHT); } + + bool isInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); } + void SetInCombatState(bool PvP); + void SetInCombatWith(Unit* enemy); + void ClearInCombat(); + uint32 GetCombatTimer() const { return m_CombatTimer; } + + bool HasAuraType(AuraType auraType) const; + bool HasAura(uint32 spellId, uint32 effIndex) const + { return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end(); } + + bool virtual HasSpell(uint32 /*spellID*/) const { return false; } + + bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); } + bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); } + bool isFeared() const { return HasAuraType(SPELL_AURA_MOD_FEAR); } + bool isInRoots() const { return HasAuraType(SPELL_AURA_MOD_ROOT); } + bool IsPolymorphed() const; + + bool isFrozen() const; + + void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage); + + bool isTargetableForAttack() const; + virtual bool IsInWater() const; + virtual bool IsUnderWater() const; + bool isInAccessablePlaceFor(Creature const* c) const; + + void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical = false); + void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype, bool critical = false); + uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell = false, bool useSpellDamage = true); + void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(Unit* Victim,SpellEntry const *spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(float x, float y, float z, SpellEntry const *spellInfo, bool triggered, Item *castItem = NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0); + + bool IsDamageToThreatSpell(SpellEntry const * spellInfo) const; + + void DeMorph(); + + void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount); + void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false); + void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo); + + void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); + void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags); + void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 MovementFlags, uint32 transitTime = 0, Player* player = NULL); + void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); + + virtual void MoveOutOfRange(Player &) { }; + + bool isAlive() const { return (m_deathState == ALIVE); }; + bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); }; + DeathState getDeathState() { return m_deathState; }; + virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet + + uint64 const& GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); } + uint64 GetPetGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); } + uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); } + uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); } + void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); } + + uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); } + uint64 GetCharmerOrOwnerOrOwnGUID() const + { + if(uint64 guid = GetCharmerOrOwnerGUID()) + return guid; + return GetGUID(); + } + bool isCharmedOwnedByPlayerOrPlayer() const { return IS_PLAYER_GUID(GetCharmerOrOwnerOrOwnGUID()); } + + Player* GetSpellModOwner(); + + Unit* GetOwner() const; + Pet* GetPet() const; + Unit* GetCharmer() const; + Unit* GetCharm() const; + Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); } + Unit* GetCharmerOrOwnerOrSelf() + { + if(Unit* u = GetCharmerOrOwner()) + return u; + + return this; + } + Player* GetCharmerOrOwnerPlayerOrPlayerItself(); + + void SetPet(Pet* pet); + void SetCharm(Unit* pet); + bool isCharmed() const { return GetCharmerGUID() != 0; } + + CharmInfo* GetCharmInfo() { return m_charmInfo; } + CharmInfo* InitCharmInfo(Unit* charm); + + bool AddAura(Aura *aur); + + void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL); + void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex); + void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL); + void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); + void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); + void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); + void RemoveAurasDueToSpellByCancel(uint32 spellId); + void RemoveNotOwnSingleTargetAuras(); + + void RemoveSpellsCausingAura(AuraType auraType); + void RemoveRankAurasDueToSpell(uint32 spellId); + bool RemoveNoStackAurasDueToAura(Aura *Aur); + void RemoveAurasWithInterruptFlags(uint32 flags); + void RemoveAurasWithDispelType( DispelType type ); + + void RemoveAllAuras(); + void RemoveAllAurasOnDeath(); + void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime); + + float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); } + void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); } + void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModSignedFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } + void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } + void InitStatBuffMods() + { + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_POSSTAT0+i, 0); + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_NEGSTAT0+i, 0); + } + void ApplyStatBuffMod(Stats stat, float val, bool apply) { ApplyModSignedFloatValue((val > 0 ? UNIT_FIELD_POSSTAT0+stat : UNIT_FIELD_NEGSTAT0+stat), val, apply); } + void ApplyStatPercentBuffMod(Stats stat, float val, bool apply) + { + ApplyPercentModFloatValue(UNIT_FIELD_POSSTAT0+stat, val, apply); + ApplyPercentModFloatValue(UNIT_FIELD_NEGSTAT0+stat, val, apply); + } + void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; } + void SetCreateHealth(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_HEALTH, val); } + uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); } + void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); } + uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); } + uint32 GetCreatePowers(Powers power) const; + float GetPosStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_POSSTAT0+stat); } + float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); } + float GetCreateStat(Stats stat) const { return m_createStats[stat]; } + + void SetCurrentCastedSpell(Spell * pSpell); + virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } + void InterruptSpell(uint32 spellType, bool withDelayed = true); + + // set withDelayed to true to account delayed spells as casted + // delayed+channeled spells are always accounted as casted + // we can skip channeled or delayed checks using flags + bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false) const; + + // set withDelayed to true to interrupt delayed spells too + // delayed+channeled spells are always interrupted + void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0); + + Spell* FindCurrentSpellBySpellId(uint32 spell_id) const; + + Spell* m_currentSpells[CURRENT_MAX_SPELL]; + + uint32 m_addDmgOnce; + uint64 m_TotemSlot[MAX_TOTEM]; + uint64 m_ObjectSlot[4]; + uint32 m_detectInvisibilityMask; + uint32 m_invisibilityMask; + uint32 m_ShapeShiftFormSpellId; + ShapeshiftForm m_form; + float m_modMeleeHitChance; + float m_modRangedHitChance; + float m_modSpellHitChance; + int32 m_baseSpellCritChance; + + float m_threatModifier[MAX_SPELL_SCHOOL]; + float m_modAttackSpeedPct[3]; + + // Event handler + EventProcessor m_Events; + + // stat system + bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply); + void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; } + float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const; + float GetTotalStatValue(Stats stat) const; + float GetTotalAuraModValue(UnitMods unitMod) const; + SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const; + Stats GetStatByAuraGroup(UnitMods unitMod) const; + Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const; + bool CanModifyStats() const { return m_canModifyStats; } + void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; } + virtual bool UpdateStats(Stats stat) = 0; + virtual bool UpdateAllStats() = 0; + virtual void UpdateResistances(uint32 school) = 0; + virtual void UpdateArmor() = 0; + virtual void UpdateMaxHealth() = 0; + virtual void UpdateMaxPower(Powers power) = 0; + virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0; + virtual void UpdateDamagePhysical(WeaponAttackType attType) = 0; + float GetTotalAttackPowerValue(WeaponAttackType attType) const; + float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const; + void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } + + bool isInFront(Unit const* target,float distance, float arc = M_PI) const; + void SetInFront(Unit const* target); + bool isInBack(Unit const* target, float distance, float arc = M_PI) const; + + // Visibility system + UnitVisibility GetVisibility() const { return m_Visibility; } + void SetVisibility(UnitVisibility x); + + // common function for visibility checks for player/creatures with detection code + bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const; + bool canDetectInvisibilityOf(Unit const* u) const; + + // virtual functions for all world objects types + bool isVisibleForInState(Player const* u, bool inVisibleList) const; + // function for low level grid visibility checks in player/creature cases + virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0; + + bool waterbreath; + AuraList & GetSingleCastAuras() { return m_scAuras; } + AuraList const& GetSingleCastAuras() const { return m_scAuras; } + SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; + + // Threat related methodes + bool CanHaveThreatList() const; + void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); + float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL); + void DeleteThreatList(); + bool SelectHostilTarget(); + void TauntApply(Unit* pVictim); + void TauntFadeOut(Unit *taunter); + ThreatManager& getThreatManager() { return m_ThreatManager; } + void addHatedBy(HostilReference* pHostilReference) { m_HostilRefManager.insertFirst(pHostilReference); }; + void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ } + HostilRefManager& getHostilRefManager() { return m_HostilRefManager; } + + Aura* GetAura(uint32 spellId, uint32 effindex); + AuraMap & GetAuras() { return m_Auras; } + AuraMap const& GetAuras() const { return m_Auras; } + AuraList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; } + void ApplyAuraProcTriggerDamage(Aura* aura, bool apply); + + int32 GetTotalAuraModifier(AuraType auratype) const; + float GetTotalAuraMultiplier(AuraType auratype) const; + int32 GetMaxPositiveAuraModifier(AuraType auratype) const; + int32 GetMaxNegativeAuraModifier(AuraType auratype) const; + + int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; + float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const; + int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; + int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; + + int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; + float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const; + int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; + int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; + + Aura* GetDummyAura(uint32 spell_id) const; + + uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } + void SetDisplayId(uint32 modelId); + uint32 GetNativeDisplayId() { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } + void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } + void setTransForm(uint32 spellid) { m_transform = spellid;} + uint32 getTransForm() const { return m_transform;} + void AddDynObject(DynamicObject* dynObj); + void RemoveDynObject(uint32 spellid); + void RemoveDynObjectWithGUID(uint64 guid) { m_dynObjGUIDs.remove(guid); } + void RemoveAllDynObjects(); + void AddGameObject(GameObject* gameObj); + void RemoveGameObject(GameObject* gameObj, bool del); + void RemoveGameObject(uint32 spellid, bool del); + void RemoveAllGameObjects(); + DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex); + DynamicObject *GetDynObject(uint32 spellId); + uint32 CalculateDamage(WeaponAttackType attType, bool normalized); + float GetAPMultiplier(WeaponAttackType attType, bool normalized); + void ModifyAuraState(AuraState flag, bool apply); + bool HasAuraState(AuraState flag) const { return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); } + void UnsummonAllTotems(); + int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask); + int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask); + int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); + int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); + uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype); + uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim); + bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType); + uint32 SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); + + void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; } + bool IsUnderLastManaUseEffect() const; + + void SetContestedPvP(Player *attackedPlayer = NULL); + + void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL); + uint32 GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime ); + + void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); + void ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType type, bool apply); + virtual bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false); + // redefined in Creature + bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask, bool useCharges = false); + virtual bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const; + // redefined in Creature + + uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage); + void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist); + + void UpdateSpeed(UnitMoveType mtype, bool forced); + float GetSpeed( UnitMoveType mtype ) const; + float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; } + void SetSpeed(UnitMoveType mtype, float rate, bool forced = false); + + void SetHover(bool on); + bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); } + + void _RemoveAllAuraMods(); + void _ApplyAllAuraMods(); + + int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target); + int32 CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target); + float CalculateLevelPenalty(SpellEntry const* spellProto) const; + + void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } + void removeFollower(FollowerReference* /*pRef*/ ) { /* nothing to do yet */ } + static Unit* GetUnit(WorldObject& object, uint64 guid); + + MotionMaster* GetMotionMaster() { return &i_motionMaster; } + + bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); } + void StopMoving(); + + void AddUnitMovementFlag(uint32 f) { m_unit_movement_flags |= f; } + void RemoveUnitMovementFlag(uint32 f) + { + uint32 oldval = m_unit_movement_flags; + m_unit_movement_flags = oldval & ~f; + } + uint32 HasUnitMovementFlag(uint32 f) const { return m_unit_movement_flags & f; } + uint32 GetUnitMovementFlags() const { return m_unit_movement_flags; } + void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; } + + void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0); + void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0); + + void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); } + void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); } + void ClearComboPointHolders(); + + ///----------Pet responses methods----------------- + void SendPetCastFail(uint32 spellid, uint8 msg); + void SendPetActionFeedback (uint8 msg); + void SendPetTalk (uint32 pettalk); + void SendPetSpellCooldown (uint32 spellid, time_t cooltime); + void SendPetClearCooldown (uint32 spellid); + void SendPetAIReaction(uint64 guid); + ///----------End of Pet responses methods---------- + + void propagateSpeedChange() { GetMotionMaster()->propagateSpeedChange(); } + + // reactive attacks + void ClearAllReactives(); + void StartReactiveTimer( ReactiveType reactive ) { m_reactiveTimer[reactive] = REACTIVE_TIMER_START;} + void UpdateReactives(uint32 p_time); + + // group updates + void UpdateAuraForGroup(uint8 slot); + + // pet auras + typedef std::set PetAuraSet; + PetAuraSet m_petAuras; + void AddPetAura(PetAura const* petSpell); + void RemovePetAura(PetAura const* petSpell); + + protected: + explicit Unit (); + + void _UpdateSpells(uint32 time); + + void _UpdateAutoRepeatSpell(); + bool m_AutoRepeatFirstCast; + + uint32 m_attackTimer[MAX_ATTACK]; + + float m_createStats[MAX_STATS]; + + AttackerSet m_attackers; + Unit* m_attacking; + + DeathState m_deathState; + + AuraMap m_Auras; + + std::list m_scAuras; // casted singlecast auras + + typedef std::list DynObjectGUIDs; + DynObjectGUIDs m_dynObjGUIDs; + + std::list m_gameObj; + bool m_isSorted; + uint32 m_transform; + uint32 m_removedAuras; + + AuraList m_modAuras[TOTAL_AURAS]; + float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]; + float m_weaponDamage[MAX_ATTACK][2]; + bool m_canModifyStats; + //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem + + float m_speed_rate[MAX_MOVE_TYPE]; + + CharmInfo *m_charmInfo; + + virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; + + MotionMaster i_motionMaster; + uint32 m_unit_movement_flags; + + uint32 m_reactiveTimer[MAX_REACTIVE]; + + private: + void SendAttackStop(Unit* victim); // only from AttackStop(Unit*) + void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*) + + void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask ); + bool HandleDummyAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggredByAura, SpellEntry const * procSpell, uint32 procFlag,uint32 cooldown); + bool HandleProcTriggerSpell(Unit *pVictim,uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attType,uint32 cooldown); + bool HandleHasteAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggredByAura, SpellEntry const * procSpell, uint32 procFlag,uint32 cooldown); + bool HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell,uint32 cooldown); + + uint32 m_state; // Even derived shouldn't modify + uint32 m_CombatTimer; + uint32 m_lastManaUse; // msecs + + UnitVisibility m_Visibility; + + Diminishing m_Diminishing; + // Manage all Units threatening us + ThreatManager m_ThreatManager; + // Manage all Units that are threatened by us + HostilRefManager m_HostilRefManager; + + FollowerRefManager m_FollowingRefManager; + + ComboPointHolderSet m_ComboPointHolders; +}; +#endif diff --git a/src/game/UnitEvents.h b/src/game/UnitEvents.h new file mode 100644 index 000000000..0359d7c36 --- /dev/null +++ b/src/game/UnitEvents.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _UNITEVENTS +#define _UNITEVENTS + +#include "Common.h" + +class ThreatContainer; +class ThreatManager; +class HostilReference; + +//============================================================== +//============================================================== + +enum UNIT_EVENT_TYPE +{ + // Player/Pet changed on/offline status + UEV_THREAT_REF_ONLINE_STATUS = 1<<0, + + // Threat for Player/Pet changed + UEV_THREAT_REF_THREAT_CHANGE = 1<<1, + + // Player/Pet will be removed from list (dead) [for internal use] + UEV_THREAT_REF_REMOVE_FROM_LIST = 1<<2, + + // Player/Pet entered/left water or some other place where it is/was not accessible for the creature + UEV_THREAT_REF_ASSECCIBLE_STATUS = 1<<3, + + // Threat list is going to be sorted (if dirty flag is set) + UEV_THREAT_SORT_LIST = 1<<4, + + // New target should be fetched, could tbe the current target as well + UEV_THREAT_SET_NEXT_TARGET = 1<<5, + + // A new victim (target) was set. Could be NULL + UEV_THREAT_VICTIM_CHANGED = 1<<6, + + // Future use + //UEV_UNIT_KILLED = 1<<7, + + //Future use + //UEV_UNIT_HEALTH_CHANGE = 1<<8, +}; + +#define UEV_THREAT_REF_EVENT_MASK ( UEV_THREAT_REF_ONLINE_STATUS | UEV_THREAT_REF_THREAT_CHANGE | UEV_THREAT_REF_REMOVE_FROM_LIST | UEV_THREAT_REF_ASSECCIBLE_STATUS) +#define UEV_THREAT_MANAGER_EVENT_MASK (UEV_THREAT_SORT_LIST | UEV_THREAT_SET_NEXT_TARGET | UEV_THREAT_VICTIM_CHANGED) +#define UEV_ALL_EVENT_MASK (0xffffffff) + +// Future use +//#define UEV_UNIT_EVENT_MASK (UEV_UNIT_KILLED | UEV_UNIT_HEALTH_CHANGE) + +//============================================================== + +class MANGOS_DLL_SPEC UnitBaseEvent +{ + private: + uint32 iType; + public: + UnitBaseEvent(uint32 pType) { iType = pType; } + uint32 getType() const { return iType; } + bool matchesTypeMask(uint32 pMask) const { return iType & pMask; } + + void setType(uint32 pType) { iType = pType; } + +}; + +//============================================================== + +class MANGOS_DLL_SPEC ThreatRefStatusChangeEvent : public UnitBaseEvent +{ + private: + HostilReference* iHostilReference; + union + { + float iFValue; + int32 iIValue; + bool iBValue; + }; + ThreatManager* iThreatManager; + public: + ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType) { iHostilReference = NULL; } + + ThreatRefStatusChangeEvent(uint32 pType, HostilReference* pHostilReference) : UnitBaseEvent(pType) { iHostilReference = pHostilReference; } + + ThreatRefStatusChangeEvent(uint32 pType, HostilReference* pHostilReference, float pValue) : UnitBaseEvent(pType) { iHostilReference = pHostilReference; iFValue = pValue; } + + ThreatRefStatusChangeEvent(uint32 pType, HostilReference* pHostilReference, bool pValue) : UnitBaseEvent(pType) { iHostilReference = pHostilReference; iBValue = pValue; } + + int32 getIValue() const { return iIValue; } + + float getFValue() const { return iFValue; } + + bool getBValue() const { return iBValue; } + + void setBValue(bool pValue) { iBValue = pValue; } + + HostilReference* getReference() const { return iHostilReference; } + + void setThreatManager(ThreatManager* pThreatManager) { iThreatManager = pThreatManager; } + + ThreatManager* getThreatManager() const { return iThreatManager; } +}; + +//============================================================== + +class MANGOS_DLL_SPEC ThreatManagerEvent : public ThreatRefStatusChangeEvent +{ + private: + ThreatContainer* iThreatContainer; + public: + ThreatManagerEvent(uint32 pType) : ThreatRefStatusChangeEvent(pType) {} + ThreatManagerEvent(uint32 pType, HostilReference* pHostilReference) : ThreatRefStatusChangeEvent(pType, pHostilReference) {} + + void setThreatContainer(ThreatContainer* pThreatContainer) { iThreatContainer = pThreatContainer; } + + ThreatContainer* getThreatContainer() const { return iThreatContainer; } +}; + +//============================================================== +#endif diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp new file mode 100644 index 000000000..6e1fc3030 --- /dev/null +++ b/src/game/UpdateData.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "ByteBuffer.h" +#include "WorldPacket.h" +#include "UpdateData.h" +#include "Log.h" +#include "Opcodes.h" +#include "World.h" +#include + +UpdateData::UpdateData() : m_blockCount(0) +{ +} + +void UpdateData::AddOutOfRangeGUID(std::set& guids) +{ + m_outOfRangeGUIDs.insert(guids.begin(),guids.end()); +} + +void UpdateData::AddOutOfRangeGUID(const uint64 &guid) +{ + m_outOfRangeGUIDs.insert(guid); +} + +void UpdateData::AddUpdateBlock(const ByteBuffer &block) +{ + m_data.append(block); + ++m_blockCount; +} + +void UpdateData::Compress(void* dst, uint32 *dst_size, void* src, int src_size) +{ + z_stream c_stream; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + // default Z_BEST_SPEED (1) + int z_res = deflateInit(&c_stream, sWorld.getConfig(CONFIG_COMPRESSION)); + if (z_res != Z_OK) + { + sLog.outError("Can't compress update packet (zlib: deflateInit) Error code: %i (%s)",z_res,zError(z_res)); + *dst_size = 0; + return; + } + + c_stream.next_out = (Bytef*)dst; + c_stream.avail_out = *dst_size; + c_stream.next_in = (Bytef*)src; + c_stream.avail_in = (uInt)src_size; + + z_res = deflate(&c_stream, Z_NO_FLUSH); + if (z_res != Z_OK) + { + sLog.outError("Can't compress update packet (zlib: deflate) Error code: %i (%s)",z_res,zError(z_res)); + *dst_size = 0; + return; + } + + if (c_stream.avail_in != 0) + { + sLog.outError("Can't compress update packet (zlib: deflate not greedy)"); + *dst_size = 0; + return; + } + + z_res = deflate(&c_stream, Z_FINISH); + if (z_res != Z_STREAM_END) + { + sLog.outError("Can't compress update packet (zlib: deflate should report Z_STREAM_END instead %i (%s)",z_res,zError(z_res)); + *dst_size = 0; + return; + } + + z_res = deflateEnd(&c_stream); + if (z_res != Z_OK) + { + sLog.outError("Can't compress update packet (zlib: deflateEnd) Error code: %i (%s)",z_res,zError(z_res)); + *dst_size = 0; + return; + } + + *dst_size = c_stream.total_out; +} + +bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport) +{ + ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8); + + buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount); + buf << (uint8) (hasTransport ? 1 : 0); + + if(!m_outOfRangeGUIDs.empty()) + { + buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS; + buf << (uint32) m_outOfRangeGUIDs.size(); + + for(std::set::const_iterator i = m_outOfRangeGUIDs.begin(); + i != m_outOfRangeGUIDs.end(); i++) + { + //buf.appendPackGUID(*i); + buf << (uint8)0xFF; + buf << (uint64) *i; + } + } + + buf.append(m_data); + + packet->clear(); + + if (m_data.size() > 50 ) + { + uint32 destsize = buf.size() + buf.size()/10 + 16; + packet->resize( destsize ); + + packet->put(0, (uint32)buf.size()); + + Compress(const_cast(packet->contents()) + sizeof(uint32), + &destsize, + (void*)buf.contents(), + buf.size()); + if (destsize == 0) + return false; + + packet->resize( destsize + sizeof(uint32) ); + packet->SetOpcode( SMSG_COMPRESSED_UPDATE_OBJECT ); + } + else + { + packet->append( buf ); + packet->SetOpcode( SMSG_UPDATE_OBJECT ); + } + + return true; +} + +void UpdateData::Clear() +{ + m_data.clear(); + m_outOfRangeGUIDs.clear(); + m_blockCount = 0; +} diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h new file mode 100644 index 000000000..54ef734dc --- /dev/null +++ b/src/game/UpdateData.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __UPDATEDATA_H +#define __UPDATEDATA_H + +class WorldPacket; + +enum OBJECT_UPDATE_TYPE +{ + UPDATETYPE_VALUES = 0, + UPDATETYPE_MOVEMENT = 1, + UPDATETYPE_CREATE_OBJECT = 2, + UPDATETYPE_CREATE_OBJECT2 = 3, + UPDATETYPE_OUT_OF_RANGE_OBJECTS = 4, + UPDATETYPE_NEAR_OBJECTS = 5 +}; + +enum OBJECT_UPDATE_FLAGS +{ + UPDATEFLAG_NONE = 0x00, + UPDATEFLAG_SELF = 0x01, + UPDATEFLAG_TRANSPORT = 0x02, + UPDATEFLAG_FULLGUID = 0x04, + UPDATEFLAG_LOWGUID = 0x08, + UPDATEFLAG_HIGHGUID = 0x10, + UPDATEFLAG_LIVING = 0x20, + UPDATEFLAG_HASPOSITION = 0x40 +}; + +class UpdateData +{ + public: + UpdateData(); + + void AddOutOfRangeGUID(std::set& guids); + void AddOutOfRangeGUID(const uint64 &guid); + void AddUpdateBlock(const ByteBuffer &block); + bool BuildPacket(WorldPacket *packet, bool hasTransport = false); + bool HasData() { return m_blockCount > 0 || !m_outOfRangeGUIDs.empty(); } + void Clear(); + + std::set const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; } + + protected: + uint32 m_blockCount; + std::set m_outOfRangeGUIDs; + ByteBuffer m_data; + + void Compress(void* dst, uint32 *dst_size, void* src, int src_size); +}; +#endif diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h new file mode 100644 index 000000000..1fba2467c --- /dev/null +++ b/src/game/UpdateFields.h @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _UPDATEFIELDS_AUTO_H +#define _UPDATEFIELDS_AUTO_H + +// Auto generated for version 2, 4, 3, 8606 + +enum EObjectFields +{ + OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC + OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE + OBJECT_END = 0x0006, +}; + +enum EItemFields +{ + ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT = OBJECT_END + 0x0010, // Size: 33, Type: INT, Flags: PUBLIC + ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0033, // Size: 1, Type: INT, Flags: OWNER_ONLY + ITEM_FIELD_DURABILITY = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_END = OBJECT_END + 0x0036, +}; + +enum EContainerFields +{ + CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC + CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE + CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC + CONTAINER_END = ITEM_END + 0x004A, +}; + +enum EUnitFields +{ + UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CREATEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_TARGET = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_PERSUADED = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_HEALTH = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_FIELD_POWER1 = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER2 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER3 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER4 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER5 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_LEVEL = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BYTES_0 = OBJECT_END + 0x001E, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_SLOT_DISPLAY = OBJECT_END + 0x001F, // Size: 3, Type: INT, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_INFO = OBJECT_END + 0x0022, // Size: 6, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_FLAGS = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_AURA = OBJECT_END + 0x002A, // Size: 56, Type: INT, Flags: PUBLIC + UNIT_FIELD_AURAFLAGS = OBJECT_END + 0x0062, // Size: 14, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_AURALEVELS = OBJECT_END + 0x0070, // Size: 14, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_AURAAPPLICATIONS = OBJECT_END + 0x007E, // Size: 14, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_AURASTATE = OBJECT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x008D, // Size: 2, Type: INT, Flags: PUBLIC + UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x008F, // Size: 1, Type: INT, Flags: PRIVATE + UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0090, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0091, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0095, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0096, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0097, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0098, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0099, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_PETNUMBER = OBJECT_END + 0x009A, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x009C, // Size: 1, Type: INT, Flags: OWNER_ONLY + UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x009D, // Size: 1, Type: INT, Flags: OWNER_ONLY + UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x009E, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_CHANNEL_SPELL = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_MOD_CAST_SPEED = OBJECT_END + 0x00A0, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_CREATED_BY_SPELL = OBJECT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_NPC_FLAGS = OBJECT_END + 0x00A2, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_NPC_EMOTESTATE = OBJECT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_TRAINING_POINTS = OBJECT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: OWNER_ONLY + UNIT_FIELD_STAT0 = OBJECT_END + 0x00A5, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT1 = OBJECT_END + 0x00A6, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT2 = OBJECT_END + 0x00A7, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT3 = OBJECT_END + 0x00A8, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT4 = OBJECT_END + 0x00A9, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x00AA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x00AB, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x00AC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x00AD, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x00AE, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x00AF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x00B0, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x00B1, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x00B2, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x00B3, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RESISTANCES = OBJECT_END + 0x00B4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x00BB, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x00C2, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_BASE_MANA = OBJECT_END + 0x00C9, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x00CA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_BYTES_2 = OBJECT_END + 0x00CB, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x00CC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x00CD, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00CE, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x00CF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x00D0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00D1, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x00D2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x00D3, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x00D4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x00DB, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x00E2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_PADDING = OBJECT_END + 0x00E3, // Size: 1, Type: INT, Flags: NONE + UNIT_END = OBJECT_END + 0x00E4, + + PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_2_4 = UNIT_END + 0x0011, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0012, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0014, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_3_4 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x0017, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_4_4 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x001C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_5_4 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0020, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_6_4 = UNIT_END + 0x0021, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x0024, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_7_4 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x0026, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x0028, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_8_4 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x002A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x002B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x002C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_9_4 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x002F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0030, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_10_4 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x0034, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_11_4 = UNIT_END + 0x0035, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0038, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_12_4 = UNIT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x003A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x003C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_13_4 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x003E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x003F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x0040, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_14_4 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_15_4 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0048, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_16_4 = UNIT_END + 0x0049, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x004C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_17_4 = UNIT_END + 0x004D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x004E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0050, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_18_4 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0054, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_19_4 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x0058, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_20_4 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x005C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_21_4 = UNIT_END + 0x005D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0060, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_22_4 = UNIT_END + 0x0061, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0062, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x0064, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_23_4 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x0066, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x0067, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x0068, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_24_4 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x006B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_25_4 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_VISIBLE_ITEM_1_CREATOR = UNIT_END + 0x006E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x007E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0080, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x008E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0090, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x009E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00AE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00BC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00BD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00BE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00C0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00CC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00CE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00D0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00DC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00DE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00E0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00EC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00EE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x00F0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x00FC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0100, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x010E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0110, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x011E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0120, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x012C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x012E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0130, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x013C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x013D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x013E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x0140, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x014C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x014D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x014E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x0150, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x015C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x015D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x015E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x0160, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x016C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x016D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x016E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0170, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x017C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x017D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x017E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x0180, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x018C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x0190, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x019C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x019D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_CHOSEN_TITLE = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_FIELD_PAD_0 = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: NONE + PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01A0, // Size: 46, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01CE, // Size: 32, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x01EE, // Size: 56, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0226, // Size: 14, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0234, // Size: 24, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x024C, // Size: 64, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x028C, // Size: 36, Type: LONG, Flags: PRIVATE + PLAYER_FARSIGHT = UNIT_END + 0x02B0, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x02B2, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER_XP = UNIT_END + 0x02B4, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x02B5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x02B6, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_CREATURES = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_RESOURCES = UNIT_END + 0x0439, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x043A, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x043B, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x043C, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_EXPERTISE = UNIT_END + 0x043D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x043E, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x043F, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0440, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0441, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0442, // Size: 7, Type: FLOAT, Flags: PRIVATE + PLAYER_SHIELD_BLOCK = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x044A, // Size: 128, Type: BYTES, Flags: PRIVATE + PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x04CA, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COINAGE = UNIT_END + 0x04CB, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x04CC, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x04D3, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x04DA, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x04E4, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_AMMO_ID = UNIT_END + 0x04E5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SELF_RES_SPELL = UNIT_END + 0x04E6, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x04E8, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x04F4, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x0500, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0501, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0502, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0503, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0x0504, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0505, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0506, // Size: 24, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x051E, // Size: 18, Type: INT, Flags: PRIVATE + PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0530, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0531, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x0532, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x0533, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0534, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0535, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_END = UNIT_END + 0x054E, +}; + +enum EGameObjectFields +{ + OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_STATE = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_POS_X = OBJECT_END + 0x0009, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_POS_Y = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_POS_Z = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_FACING = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_DYN_FLAGS = OBJECT_END + 0x000D, // Size: 1, Type: INT, Flags: DYNAMIC + GAMEOBJECT_FACTION = OBJECT_END + 0x000E, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_TYPE_ID = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_LEVEL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_ARTKIT = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_ANIMPROGRESS = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: DYNAMIC + GAMEOBJECT_PADDING = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: NONE + GAMEOBJECT_END = OBJECT_END + 0x0014, +}; + +enum EDynamicObjectFields +{ + DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC + DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC + DYNAMICOBJECT_POS_X = OBJECT_END + 0x0005, // Size: 1, Type: FLOAT, Flags: PUBLIC + DYNAMICOBJECT_POS_Y = OBJECT_END + 0x0006, // Size: 1, Type: FLOAT, Flags: PUBLIC + DYNAMICOBJECT_POS_Z = OBJECT_END + 0x0007, // Size: 1, Type: FLOAT, Flags: PUBLIC + DYNAMICOBJECT_FACING = OBJECT_END + 0x0008, // Size: 1, Type: FLOAT, Flags: PUBLIC + DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC + DYNAMICOBJECT_END = OBJECT_END + 0x000A, +}; + +enum ECorpseFields +{ + CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + CORPSE_FIELD_FACING = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC + CORPSE_FIELD_POS_X = OBJECT_END + 0x0005, // Size: 1, Type: FLOAT, Flags: PUBLIC + CORPSE_FIELD_POS_Y = OBJECT_END + 0x0006, // Size: 1, Type: FLOAT, Flags: PUBLIC + CORPSE_FIELD_POS_Z = OBJECT_END + 0x0007, // Size: 1, Type: FLOAT, Flags: PUBLIC + CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC + CORPSE_FIELD_ITEM = OBJECT_END + 0x0009, // Size: 19, Type: INT, Flags: PUBLIC + CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x001C, // Size: 1, Type: BYTES, Flags: PUBLIC + CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x001D, // Size: 1, Type: BYTES, Flags: PUBLIC + CORPSE_FIELD_GUILD = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC + CORPSE_FIELD_FLAGS = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC + CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: DYNAMIC + CORPSE_FIELD_PAD = OBJECT_END + 0x0021, // Size: 1, Type: INT, Flags: NONE + CORPSE_END = OBJECT_END + 0x0022, +}; +#endif diff --git a/src/game/UpdateMask.h b/src/game/UpdateMask.h new file mode 100644 index 000000000..14a31f2ac --- /dev/null +++ b/src/game/UpdateMask.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __UPDATEMASK_H +#define __UPDATEMASK_H + +#include "UpdateFields.h" +#include "Errors.h" + +class UpdateMask +{ + public: + UpdateMask( ) : mCount( 0 ), mBlocks( 0 ), mUpdateMask( 0 ) { } + UpdateMask( const UpdateMask& mask ) : mUpdateMask( 0 ) { *this = mask; } + + ~UpdateMask( ) + { + if(mUpdateMask) + delete [] mUpdateMask; + } + + inline void SetBit (uint32 index) + { + ( (uint8 *)mUpdateMask )[ index >> 3 ] |= 1 << ( index & 0x7 ); + } + + inline void UnsetBit (uint32 index) + { + ( (uint8 *)mUpdateMask )[ index >> 3 ] &= (0xff ^ (1 << ( index & 0x7 ) ) ); + } + + inline bool GetBit (uint32 index) + { + return ( ( (uint8 *)mUpdateMask)[ index >> 3 ] & ( 1 << ( index & 0x7 ) )) != 0; + } + + inline uint32 GetBlockCount() { return mBlocks; } + inline uint32 GetLength() { return mBlocks << 2; } + inline uint32 GetCount() { return mCount; } + inline uint8* GetMask() { return (uint8*)mUpdateMask; } + + inline void SetCount (uint32 valuesCount) + { + if(mUpdateMask) + delete [] mUpdateMask; + + mCount = valuesCount; + mBlocks = (valuesCount + 31) / 32; + + mUpdateMask = new uint32[mBlocks]; + memset(mUpdateMask, 0, mBlocks << 2); + } + + inline void Clear() + { + if (mUpdateMask) + memset(mUpdateMask, 0, mBlocks << 2); + } + + inline UpdateMask& operator = ( const UpdateMask& mask ) + { + SetCount(mask.mCount); + memcpy(mUpdateMask, mask.mUpdateMask, mBlocks << 2); + + return *this; + } + + inline void operator &= ( const UpdateMask& mask ) + { + ASSERT(mask.mCount <= mCount); + for (uint32 i = 0; i < mBlocks; i++) + mUpdateMask[i] &= mask.mUpdateMask[i]; + } + + inline void operator |= ( const UpdateMask& mask ) + { + ASSERT(mask.mCount <= mCount); + for (uint32 i = 0; i < mBlocks; i++) + mUpdateMask[i] |= mask.mUpdateMask[i]; + } + + inline UpdateMask operator & ( const UpdateMask& mask ) const + { + ASSERT(mask.mCount <= mCount); + + UpdateMask newmask; + newmask = *this; + newmask &= mask; + + return newmask; + } + + inline UpdateMask operator | ( const UpdateMask& mask ) const + { + ASSERT(mask.mCount <= mCount); + + UpdateMask newmask; + newmask = *this; + newmask |= mask; + + return newmask; + } + + private: + uint32 mCount; + uint32 mBlocks; + uint32 *mUpdateMask; +}; +#endif diff --git a/src/game/VoiceChatHandler.cpp b/src/game/VoiceChatHandler.cpp new file mode 100644 index 000000000..a3100ed1f --- /dev/null +++ b/src/game/VoiceChatHandler.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Opcodes.h" +#include "Log.h" + +void WorldSession::HandleVoiceSettingsOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: CMSG_VOICE_SETTINGS"); + // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled + recv_data.hexlike(); +} + +void WorldSession::HandleChannelEnableVoiceOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: CMSG_CHANNEL_ENABLE_VOICE"); + // Enable Voice button in channel context menu + recv_data.hexlike(); +} + +void WorldSession::HandleChannelVoiceChatQuery( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: CMSG_CHANNEL_VOICE_CHAT_QUERY"); + // uint32, string + recv_data.hexlike(); +} diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp new file mode 100644 index 000000000..f157234fa --- /dev/null +++ b/src/game/WaypointManager.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Database/DatabaseEnv.h" +#include "GridDefines.h" +#include "Policies/SingletonImp.h" +#include "WaypointManager.h" +#include "ProgressBar.h" +#include "MapManager.h" + +INSTANTIATE_SINGLETON_1(WaypointManager); + +bool WaypointBehavior::isEmpty() +{ + return emote == 0 && spell == 0 && model1 == 0 && model2 == 0 && text[0].empty() && + text[1].empty() && text[2].empty() && text[3].empty() && text[4].empty(); +} + +WaypointBehavior::WaypointBehavior(const WaypointBehavior &b) +{ + emote = b.emote; spell = b.spell; model1 = b.model1; model2 = b.model2; + text[0] = b.text[0]; text[1] = b.text[1]; text[2] = b.text[2]; + text[3] = b.text[3]; text[4] = b.text[4]; +} + +void WaypointManager::Load() +{ + Cleanup(); + + uint32 total_paths = 0; + uint32 total_nodes = 0; + uint32 total_behaviors = 0; + + QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id"); + if(result) + { + total_paths = result->GetRowCount(); + barGoLink bar( total_paths ); + do + { + Field *fields = result->Fetch(); + uint32 id = fields[0].GetUInt32(); + uint32 count = fields[1].GetUInt32(); + m_pathMap[id].resize(count); + + total_nodes += count; + bar.step(); + } while( result->NextRow() ); + delete result; + } + + result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id, point FROM creature_movement"); + if(result) + { + barGoLink bar( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + uint32 point = fields[15].GetUInt32(); + uint32 id = fields[14].GetUInt32(); + + WaypointPath &path = m_pathMap[id]; + // the cleanup queries make sure the following is true + assert(point >= 1 && point <= path.size()); + WaypointNode &node = path[point-1]; + + node.x = fields[0].GetFloat(); + node.y = fields[1].GetFloat(); + node.z = fields[2].GetFloat(); + node.orientation = fields[3].GetFloat(); + node.delay = fields[6].GetUInt16(); + + // prevent using invalid coordinates + if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation)) + { + QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id); + if(result1) sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %d, Y: %d).", id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y); + else sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %d, Y: %d).", id, point, node.x, node.y); + + MaNGOS::NormalizeMapCoord(node.x); + MaNGOS::NormalizeMapCoord(node.y); + if(result1) + { + node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z); + delete result1; + } + WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point); + } + + WaypointBehavior be; + be.model1 = fields[4].GetUInt32(); + be.model2 = fields[5].GetUInt32(); + be.emote = fields[7].GetUInt32(); + be.spell = fields[8].GetUInt32(); + be.text[0] = fields[9].GetCppString(); + be.text[1] = fields[10].GetCppString(); + be.text[2] = fields[11].GetCppString(); + be.text[3] = fields[12].GetCppString(); + be.text[4] = fields[13].GetCppString(); + + // save memory by not storing empty behaviors + if(!be.isEmpty()) + { + node.behavior = new WaypointBehavior(be); + ++total_behaviors; + } + else + node.behavior = NULL; + bar.step(); + } while( result->NextRow() ); + delete result; + } + sLog.outString( ">> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors); +} + +void WaypointManager::Cleanup() +{ + // check if points need to be renumbered and do it + if(QueryResult *result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1")) + { + delete result; + WorldDatabase.DirectExecute("CREATE TEMPORARY TABLE temp LIKE creature_movement"); + WorldDatabase.DirectExecute("INSERT INTO temp SELECT * FROM creature_movement"); + WorldDatabase.DirectExecute("ALTER TABLE creature_movement DROP PRIMARY KEY"); + WorldDatabase.DirectExecute("UPDATE creature_movement AS T SET point = (SELECT COUNT(*) FROM temp WHERE id = T.id AND point <= T.point)"); + WorldDatabase.DirectExecute("ALTER TABLE creature_movement ADD PRIMARY KEY (id, point)"); + WorldDatabase.DirectExecute("DROP TABLE temp"); + assert(!(result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1"))); + } +} + +void WaypointManager::Unload() +{ + for(WaypointPathMap::iterator itr = m_pathMap.begin(); itr != m_pathMap.end(); ++itr) + _clearPath(itr->second); + m_pathMap.clear(); +} + +void WaypointManager::_clearPath(WaypointPath &path) +{ + for(WaypointPath::iterator itr = path.begin(); itr != path.end(); ++itr) + if(itr->behavior) + delete itr->behavior; + path.clear(); +} + +/// - Insert after the last point +void WaypointManager::AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid) +{ + _addNode(id, GetLastPoint(id, 0) + 1, x, y, z, o, delay, wpGuid); +} + +/// - Insert after a certain point +void WaypointManager::AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid) +{ + for(uint32 i = GetLastPoint(id, 0); i > point; i--) + WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point+1 WHERE id='%u' AND point='%u'", id, i); + + _addNode(id, point + 1, x, y, z, o, delay, wpGuid); +} + +/// - Insert without checking for collision +void WaypointManager::_addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid) +{ + if(point == 0) return; // counted from 1 in the DB + WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z,orientation,wpguid,waittime) VALUES ('%u','%u','%f', '%f', '%f', '%f', '%d', '%d')", id, point, x, y, z, o, wpGuid, delay); + WaypointPathMap::iterator itr = m_pathMap.find(id); + if(itr == m_pathMap.end()) + itr = m_pathMap.insert(WaypointPathMap::value_type(id, WaypointPath())).first; + itr->second.insert(itr->second.begin() + (point - 1), WaypointNode(x, y, z, o, delay, NULL)); +} + +uint32 WaypointManager::GetLastPoint(uint32 id, uint32 default_notfound) +{ + uint32 point = default_notfound; + /*QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'", id); + if( result ) + { + point = (*result)[0].GetUInt32()+1; + delete result; + }*/ + WaypointPathMap::iterator itr = m_pathMap.find(id); + if(itr != m_pathMap.end() && itr->second.size() != 0) + point = itr->second.size(); + return point; +} + +void WaypointManager::DeleteNode(uint32 id, uint32 point) +{ + if(point == 0) return; // counted from 1 in the DB + WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u' AND point='%u'", id, point); + WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point-1 WHERE id='%u' AND point>'%u'", id, point); + WaypointPathMap::iterator itr = m_pathMap.find(id); + if(itr != m_pathMap.end() && point <= itr->second.size()) + itr->second.erase(itr->second.begin() + (point-1)); +} + +void WaypointManager::DeletePath(uint32 id) +{ + WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u'", id); + WaypointPathMap::iterator itr = m_pathMap.find(id); + if(itr != m_pathMap.end()) + _clearPath(itr->second); + // the path is not removed from the map, just cleared + // WMGs have pointers to the path, so deleting them would crash + // this wastes some memory, but these functions are + // only meant to be called by GM commands +} + +void WaypointManager::SetNodePosition(uint32 id, uint32 point, float x, float y, float z) +{ + if(point == 0) return; // counted from 1 in the DB + WorldDatabase.PExecuteLog("UPDATE creature_movement SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'", x, y, z, id, point); + WaypointPathMap::iterator itr = m_pathMap.find(id); + if(itr != m_pathMap.end() && point <= itr->second.size()) + { + itr->second[point-1].x = x; + itr->second[point-1].y = y; + itr->second[point-1].z = z; + } +} + +void WaypointManager::SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text) +{ + if(point == 0) return; // counted from 1 in the DB + if(!text_field) return; + std::string field = text_field; + WorldDatabase.escape_string(field); + + if(!text) + { + WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s=NULL WHERE id='%u' AND point='%u'", field.c_str(), id, point); + } + else + { + std::string text2 = text; + WorldDatabase.escape_string(text2); + WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s='%s' WHERE id='%u' AND point='%u'", field.c_str(), text2.c_str(), id, point); + } + + WaypointPathMap::iterator itr = m_pathMap.find(id); + if(itr != m_pathMap.end() && point <= itr->second.size()) + { + WaypointNode &node = itr->second[point-1]; + if(!node.behavior) node.behavior = new WaypointBehavior(); + + if(field == "text1") node.behavior->text[0] = text ? text : ""; + if(field == "text2") node.behavior->text[1] = text ? text : ""; + if(field == "text3") node.behavior->text[2] = text ? text : ""; + if(field == "text4") node.behavior->text[3] = text ? text : ""; + if(field == "text5") node.behavior->text[4] = text ? text : ""; + if(field == "emote") node.behavior->emote = text ? atoi(text) : 0; + if(field == "spell") node.behavior->spell = text ? atoi(text) : 0; + if(field == "model1") node.behavior->model1 = text ? atoi(text) : 0; + if(field == "model2") node.behavior->model2 = text ? atoi(text) : 0; + } +} diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h new file mode 100644 index 000000000..9a6940cc7 --- /dev/null +++ b/src/game/WaypointManager.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_WAYPOINTMANAGER_H +#define MANGOS_WAYPOINTMANAGER_H + +#include +#include +#include "Utilities/HashMap.h" + +struct WaypointBehavior +{ + uint32 emote; + uint32 spell; + std::string text[5]; + uint32 model1; + uint32 model2; + + bool isEmpty(); + WaypointBehavior() {} + WaypointBehavior(const WaypointBehavior &b); +}; + +struct WaypointNode +{ + float x; + float y; + float z; + float orientation; + uint32 delay; + WaypointBehavior * behavior; + WaypointNode() {} + WaypointNode(float _x, float _y, float _z, float _o, uint32 _delay, WaypointBehavior * _behavior) + : x(_x), y(_y), z(_z), orientation(_o), delay(_delay), behavior(_behavior) {} +}; + +typedef std::vector WaypointPath; + +class WaypointManager +{ + public: + WaypointManager() {} + ~WaypointManager() { Unload(); } + + void Load(); + void Unload(); + + void Cleanup(); + + WaypointPath *GetPath(uint32 id) + { + WaypointPathMap::iterator itr = m_pathMap.find(id); + return itr != m_pathMap.end() ? &itr->second : NULL; + } + + void AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid); + void AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid); + uint32 GetLastPoint(uint32 id, uint32 default_notfound); + void DeleteNode(uint32 id, uint32 point); + void DeletePath(uint32 id); + void SetNodePosition(uint32 id, uint32 point, float x, float y, float z); + void SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text); + + private: + void _addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid); + void _clearPath(WaypointPath &path); + + typedef HM_NAMESPACE::hash_map WaypointPathMap; + WaypointPathMap m_pathMap; +}; + +#define WaypointMgr MaNGOS::Singleton::Instance() + +#endif diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp new file mode 100644 index 000000000..b4f79b4be --- /dev/null +++ b/src/game/WaypointMovementGenerator.cpp @@ -0,0 +1,651 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* +creature_movement Table + +alter table creature_movement add `text1` varchar(255) default NULL; +alter table creature_movement add `text2` varchar(255) default NULL; +alter table creature_movement add `text3` varchar(255) default NULL; +alter table creature_movement add `text4` varchar(255) default NULL; +alter table creature_movement add `text5` varchar(255) default NULL; +alter table creature_movement add `emote` int(10) unsigned default '0'; +alter table creature_movement add `spell` int(5) unsigned default '0'; +alter table creature_movement add `wpguid` int(11) default '0'; + +*/ + +#include + +#include "WaypointMovementGenerator.h" +#include "ObjectMgr.h" +#include "Creature.h" +#include "DestinationHolderImp.h" +#include "CreatureAI.h" +#include "WaypointManager.h" + +#include + +//-----------------------------------------------// +void +WaypointMovementGenerator::LoadPath(Creature &c) +{ + sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow()); + + i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow()); + if(!i_path) + { + sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s(%d) doesn't have waypoint path", c.GetName(), c.GetDBTableGUIDLow()); + return; + } + + uint32 node_count = i_path->size(); + i_hasDone.resize(node_count); + for(uint32 i = 0; i < node_count-1; i++) + i_hasDone[i] = false; + + // to prevent a misbehaviour inside "update" + // update is always called with the next wp - but the wpSys needs the current + // so when the routine is called the first time, wpSys gets the last waypoint + // and this prevents the system from performing text/emote, etc + i_hasDone[node_count - 1] = true; +} + +void +WaypointMovementGenerator::ClearWaypoints() +{ + i_path = NULL; +} + +void +WaypointMovementGenerator::Initialize() +{ +} + +bool +WaypointMovementGenerator::Update(Creature &creature, const uint32 &diff) +{ + if(!&creature) + return true; + + // Waypoint movement can be switched on/off + // This is quite handy for escort quests and other stuff + if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) + return true; + + // prevent a crash at empty waypoint path. + if(!i_path || i_path->empty()) + return true; + + // i_path was modified by chat commands for example + if(i_path->size() != i_hasDone.size()) + i_hasDone.resize(i_path->size()); + if(i_currentNode >= i_path->size()) + i_currentNode = 0; + + CreatureTraveller traveller(creature); + + i_nextMoveTime.Update(diff); + i_destinationHolder.UpdateTraveller(traveller, diff, false, true); + + // creature has been stoped in middle of the waypoint segment + if (!i_destinationHolder.HasArrived() && creature.IsStopped()) + { + if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it + { + SetStopedByPlayer(false); + // Now we re-set destination to same node and start travel + creature.addUnitState(UNIT_STAT_ROAMING); + if (creature.canFly()) + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + const WaypointNode &node = i_path->at(i_currentNode); + i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); + i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); + } + else // if( !i_nextMoveTime.Passed()) + { // unexpected end of timer && creature stopped && not at end of segment + if (!IsStopedByPlayer()) + { // Put 30 seconds delay + i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); + i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); + SetStopedByPlayer(true); // Mark we did it + } + } + return true; // Abort here this update + } + + if( creature.IsStopped()) + { + uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; + + if (!i_hasDone[idx]) + { + if (i_path->at(idx).orientation !=100) + creature.SetOrientation(i_path->at(idx).orientation); + + if(WaypointBehavior *behavior = i_path->at(idx).behavior) + { + if(behavior->emote != 0) + creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote); + if(behavior->spell != 0) + creature.CastSpell(&creature,behavior->spell, false); + if(behavior->model1 != 0) + creature.SetDisplayId(behavior->model1); + if(!behavior->text[0].empty()) + { + // Only one text is set + if( !behavior->text[1].empty() ) + { + // Select one from max 5 texts (0 and 1 laready checked) + int i = 2; + for( ; i < 5; ++i ) + if( behavior->text[i].empty() ) + break; + + creature.Say(behavior->text[rand() % i].c_str(), 0, 0); + } + else + creature.Say(behavior->text[0].c_str(), 0, 0); + } + + i_hasDone[idx] = true; + MovementInform(creature); + } // wpBehaviour found + } // HasDone == false + } // i_creature.IsStopped() + + if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player + { + if( creature.IsStopped() ) // If stopped then begin a new move segment + { + creature.addUnitState(UNIT_STAT_ROAMING); + if (creature.canFly()) + creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + const WaypointNode &node = i_path->at(i_currentNode); + i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); + i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); + uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; + + if (i_path->at(idx).orientation !=100) + creature.SetOrientation(i_path->at(idx).orientation); + + if(WaypointBehavior *behavior = i_path->at(idx).behavior ) + { + i_hasDone[idx] = false; + if(behavior->model2 != 0) + creature.SetDisplayId(behavior->model2); + + creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + } + } + else // If not stopped then stop it and set the reset of TimeTracker to waittime + { + creature.StopMoving(); + SetStopedByPlayer(false); + i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); + ++i_currentNode; + if( i_currentNode >= i_path->size() ) + i_currentNode = 0; + } + } + return true; +} + +void WaypointMovementGenerator::MovementInform(Creature &unit) +{ + if(unit.AI()) + unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); +} + +//----------------------------------------------------// +void +FlightPathMovementGenerator::LoadPath(Player &) +{ + objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds); +} + +uint32 +FlightPathMovementGenerator::GetPathAtMapEnd() const +{ + if(i_currentNode >= i_mapIds.size()) + return i_mapIds.size(); + + uint32 curMapId = i_mapIds[i_currentNode]; + for(uint32 i = i_currentNode; i < i_mapIds.size(); ++i) + { + if(i_mapIds[i] != curMapId) + return i; + } + + return i_mapIds.size(); +} + +void +FlightPathMovementGenerator::Initialize(Player &player) +{ + player.getHostilRefManager().setOnlineOfflineState(false); + player.addUnitState(UNIT_STAT_IN_FLIGHT); + player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + LoadPath(player); + Traveller traveller(player); + // do not send movement, it was sent already + i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false); + + player.SendMonsterMoveByPath(GetPath(),GetCurrentNode(),GetPathAtMapEnd(),MOVEMENTFLAG_WALK_MODE|MOVEMENTFLAG_ONTRANSPORT); +} + +void FlightPathMovementGenerator::Finalize(Player & player) +{ + + float x, y, z; + i_destinationHolder.GetLocationNow(player.GetMapId(), x, y, z); + player.SetPosition(x, y, z, player.GetOrientation()); + + player.clearUnitState(UNIT_STAT_IN_FLIGHT); + player.Unmount(); + player.RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + + if(player.m_taxi.empty()) + { + player.getHostilRefManager().setOnlineOfflineState(true); + if(player.pvpInfo.inHostileArea) + player.CastSpell(&player, 2479, true); + + player.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); + player.StopMoving(); + } +} + +bool +FlightPathMovementGenerator::Update(Player &player, const uint32 &diff) +{ + if( MovementInProgress() ) + { + Traveller traveller(player); + if( i_destinationHolder.UpdateTraveller(traveller, diff, false) ) + { + i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE); + if( i_destinationHolder.HasArrived() ) + { + uint32 curMap = i_mapIds[i_currentNode]; + ++i_currentNode; + if( MovementInProgress() ) + { + DEBUG_LOG("loading node %u for player %s", i_currentNode, player.GetName()); + if(i_mapIds[i_currentNode]==curMap) + { + // do not send movement, it was sent already + i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false); + } + return true; + } + //else HasArrived() + } + else + return true; + } + else + return true; + } + + // we have arrived at the end of the path + return false; +} + +void +FlightPathMovementGenerator::SetCurrentNodeAfterTeleport() +{ + if(i_mapIds.empty()) + return; + + uint32 map0 = i_mapIds[0]; + for(int i = 1; i < i_mapIds.size(); ++i) + { + if(i_mapIds[i]!=map0) + { + i_currentNode = i; + return; + } + } +} + +// +// Unique1's ASTAR Pathfinding Code... For future use & reference... +// + +#ifdef __PATHFINDING__ + +int GetFCost(int to, int num, int parentNum, float *gcost); // Below... + +int ShortenASTARRoute(short int *pathlist, int number) +{ // Wrote this to make the routes a little smarter (shorter)... No point looping back to the same places... Unique1 + short int temppathlist[MAX_PATHLIST_NODES]; + int count = 0; + // int count2 = 0; + int temp, temp2; + int link; + int upto = 0; + + for (temp = number; temp >= 0; temp--) + { + qboolean shortened = qfalse; + + for (temp2 = 0; temp2 < temp; temp2++) + { + for (link = 0; link < nodes[pathlist[temp]].enodenum; link++) + { + if (nodes[pathlist[temp]].links[link].flags & PATH_BLOCKED) + continue; + + //if ((bot->client->ps.eFlags & EF_TANK) && nodes[bot->current_node].links[link].flags & PATH_NOTANKS) //if this path is blocked, skip it + // continue; + + //if (nodes[nodes[pathlist[temp]].links[link].targetNode].origin[2] > nodes[pathlist[temp]].origin[2] + 32) + // continue; + + if (nodes[pathlist[temp]].links[link].targetNode == pathlist[temp2]) + { // Found a shorter route... + //if (OrgVisible(nodes[pathlist[temp2]].origin, nodes[pathlist[temp]].origin, -1)) + { + temppathlist[count] = pathlist[temp2]; + temp = temp2; + ++count; + shortened = qtrue; + } + } + } + } + + if (!shortened) + { + temppathlist[count] = pathlist[temp]; + ++count; + } + } + + upto = count; + + for (temp = 0; temp < count; temp++) + { + pathlist[temp] = temppathlist[upto]; + --upto; + } + + G_Printf("ShortenASTARRoute: Path size reduced from %i to %i nodes...n", number, count); + return count; +} + +/* +=========================================================================== +CreatePathAStar +This function uses the A* pathfinding algorithm to determine the +shortest path between any two nodes. +It's fairly complex, so I'm not really going to explain it much. +Look up A* and binary heaps for more info. +pathlist stores the ideal path between the nodes, in reverse order, +and the return value is the number of nodes in that path +=========================================================================== +*/ +int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist) +{ + //all the data we have to hold...since we can't do dynamic allocation, has to be MAX_NODES + //we can probably lower this later - eg, the open list should never have more than at most a few dozen items on it + short int openlist[MAX_NODES+1]; //add 1 because it's a binary heap, and they don't use 0 - 1 is the first used index + float gcost[MAX_NODES]; + int fcost[MAX_NODES]; + char list[MAX_NODES]; //0 is neither, 1 is open, 2 is closed - char because it's the smallest data type + short int parent[MAX_NODES]; + + short int numOpen = 0; + short int atNode, temp, newnode=-1; + qboolean found = qfalse; + int count = -1; + float gc; + int i, u, v, m; + vec3_t vec; + + //clear out all the arrays + memset(openlist, 0, sizeof(short int)*(MAX_NODES+1)); + memset(fcost, 0, sizeof(int)*MAX_NODES); + memset(list, 0, sizeof(char)*MAX_NODES); + memset(parent, 0, sizeof(short int)*MAX_NODES); + memset(gcost, -1, sizeof(float)*MAX_NODES); + + //make sure we have valid data before calculating everything + if ((from == NODE_INVALID) || (to == NODE_INVALID) || (from >= MAX_NODES) || (to >= MAX_NODES) || (from == to)) + return -1; + + openlist[1] = from; //add the starting node to the open list + ++numOpen; + gcost[from] = 0; //its f and g costs are obviously 0 + fcost[from] = 0; + + while (1) + { + if (numOpen != 0) //if there are still items in the open list + { + //pop the top item off of the list + atNode = openlist[1]; + list[atNode] = 2; //put the node on the closed list so we don't check it again + --numOpen; + + openlist[1] = openlist[numOpen+1]; //move the last item in the list to the top position + v = 1; + + //this while loop reorders the list so that the new lowest fcost is at the top again + while (1) + { + u = v; + if ((2*u+1) < numOpen) //if both children exist + { + if (fcost[openlist[u]] >= fcost[openlist[2*u]]) + v = 2*u; + if (fcost[openlist[v]] >= fcost[openlist[2*u+1]]) + v = 2*u+1; + } + else + { + if ((2*u) < numOpen) //if only one child exists + { + if (fcost[openlist[u]] >= fcost[openlist[2*u]]) + v = 2*u; + } + } + + if (u != v) //if they're out of order, swap this item with its parent + { + temp = openlist[u]; + openlist[u] = openlist[v]; + openlist[v] = temp; + } + else + break; + } + + for (i = 0; i < nodes[atNode].enodenum; i++) //loop through all the links for this node + { + newnode = nodes[atNode].links[i].targetNode; + + //if this path is blocked, skip it + if (nodes[atNode].links[i].flags & PATH_BLOCKED) + continue; + //if this path is blocked, skip it + if (bot->client && (bot->client->ps.eFlags & EF_TANK) && nodes[atNode].links[i].flags & PATH_NOTANKS) + continue; + //skip any unreachable nodes + if (bot->client && (nodes[newnode].type & NODE_ALLY_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_ALLIES)) + continue; + if (bot->client && (nodes[newnode].type & NODE_AXIS_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_AXIS)) + continue; + + if (list[newnode] == 2) //if this node is on the closed list, skip it + continue; + + if (list[newnode] != 1) //if this node is not already on the open list + { + openlist[++numOpen] = newnode; //add the new node to the open list + list[newnode] = 1; + parent[newnode] = atNode; //record the node's parent + + if (newnode == to) //if we've found the goal, don't keep computing paths! + break; //this will break the 'for' and go all the way to 'if (list[to] == 1)' + + //store it's f cost value + fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost); + + //this loop re-orders the heap so that the lowest fcost is at the top + m = numOpen; + while (m != 1) //while this item isn't at the top of the heap already + { + //if it has a lower fcost than its parent + if (fcost[openlist[m]] <= fcost[openlist[m/2]]) + { + temp = openlist[m/2]; + openlist[m/2] = openlist[m]; + openlist[m] = temp; //swap them + m /= 2; + } + else + break; + } + } + else //if this node is already on the open list + { + gc = gcost[atNode]; + VectorSubtract(nodes[newnode].origin, nodes[atNode].origin, vec); + gc += VectorLength(vec); //calculate what the gcost would be if we reached this node along the current path + + if (gc < gcost[newnode]) //if the new gcost is less (ie, this path is shorter than what we had before) + { + parent[newnode] = atNode; //set the new parent for this node + gcost[newnode] = gc; //and the new g cost + + for (i = 1; i < numOpen; i++) //loop through all the items on the open list + { + if (openlist[i] == newnode) //find this node in the list + { + //calculate the new fcost and store it + fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost); + + //reorder the list again, with the lowest fcost item on top + m = i; + while (m != 1) + { + //if the item has a lower fcost than it's parent + if (fcost[openlist[m]] < fcost[openlist[m/2]]) + { + temp = openlist[m/2]; + openlist[m/2] = openlist[m]; + openlist[m] = temp; //swap them + m /= 2; + } + else + break; + } + break; //exit the 'for' loop because we already changed this node + } //if + } //for + } //if (gc < gcost[newnode]) + } //if (list[newnode] != 1) --> else + } //for (loop through links) + } //if (numOpen != 0) + else + { + found = qfalse; //there is no path between these nodes + break; + } + + if (list[to] == 1) //if the destination node is on the open list, we're done + { + found = qtrue; + break; + } + } //while (1) + + if (found == qtrue) //if we found a path + { + //G_Printf("%s - path found!n", bot->client->pers.netname); + count = 0; + + temp = to; //start at the end point + while (temp != from) //travel along the path (backwards) until we reach the starting point + { + pathlist[count++] = temp; //add the node to the pathlist and increment the count + temp = parent[temp]; //move to the parent of this node to continue the path + } + + pathlist[count++] = from; //add the beginning node to the end of the pathlist + + #ifdef __BOT_SHORTEN_ROUTING__ + count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1 + #endif //__BOT_SHORTEN_ROUTING__ + } + else + { + //G_Printf("^1*** ^4BOT DEBUG^5: (CreatePathAStar) There is no route between node ^7%i^5 and node ^7%i^5.n", from, to); + count = CreateDumbRoute(from, to, pathlist); + + if (count > 0) + { + #ifdef __BOT_SHORTEN_ROUTING__ + count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1 + #endif //__BOT_SHORTEN_ROUTING__ + return count; + } + } + + return count; //return the number of nodes in the path, -1 if not found +} + +/* +=========================================================================== +GetFCost +Utility function used by A* pathfinding to calculate the +cost to move between nodes towards a goal. Using the A* +algorithm F = G + H, G here is the distance along the node +paths the bot must travel, and H is the straight-line distance +to the goal node. +Returned as an int because more precision is unnecessary and it +will slightly speed up heap access +=========================================================================== +*/ +int GetFCost(int to, int num, int parentNum, float *gcost) +{ + float gc = 0; + float hc = 0; + vec3_t v; + + if (gcost[num] == -1) + { + if (parentNum != -1) + { + gc = gcost[parentNum]; + VectorSubtract(nodes[num].origin, nodes[parentNum].origin, v); + gc += VectorLength(v); + } + gcost[num] = gc; + } + else + gc = gcost[num]; + + VectorSubtract(nodes[to].origin, nodes[num].origin, v); + hc = VectorLength(v); + + return (int)(gc + hc); +} +#endif //__PATHFINDING__ diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h new file mode 100644 index 000000000..bcd14d893 --- /dev/null +++ b/src/game/WaypointMovementGenerator.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_WAYPOINTMOVEMENTGENERATOR_H +#define MANGOS_WAYPOINTMOVEMENTGENERATOR_H + +/** @page PathMovementGenerator is used to generate movements + * of waypoints and flight paths. Each serves the purpose + * of generate activities so that it generates updated + * packets for the players. + */ + +#include "MovementGenerator.h" +#include "DestinationHolder.h" +#include "WaypointManager.h" +#include "Path.h" +#include "Traveller.h" + +#include "Player.h" + +#include +#include + +#define FLIGHT_TRAVEL_UPDATE 100 +#define STOP_TIME_FOR_PLAYER 3 * 60 * 1000 // 3 Minutes + +template +class MANGOS_DLL_SPEC PathMovementBase +{ + public: + PathMovementBase() : i_currentNode(0) {} + virtual ~PathMovementBase() {}; + + inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); } + + // template pattern, not defined .. override required + void LoadPath(T &); + void ReloadPath(T &); + uint32 GetCurrentNode() const { return i_currentNode; } + + bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; } + protected: + uint32 i_currentNode; + DestinationHolder< Traveller > i_destinationHolder; + P i_path; +}; + +/** WaypointMovementGenerator loads a series of way points + * from the DB and apply it to the creature's movement generator. + * Hence, the creature will move according to its predefined way points. + */ + +template +class MANGOS_DLL_SPEC WaypointMovementGenerator; + +template<> +class MANGOS_DLL_SPEC WaypointMovementGenerator +: public MovementGeneratorMedium< Creature, WaypointMovementGenerator >, +public PathMovementBase +{ + TimeTrackerSmall i_nextMoveTime; + std::vector i_hasDone; + public: + WaypointMovementGenerator(Creature &) : i_nextMoveTime(0) {} + ~WaypointMovementGenerator() { ClearWaypoints(); } + void Initialize(Creature &u) + { + i_nextMoveTime.Reset(0); // TODO: check the lower bound (0 is probably too small) + u.StopMoving(); + LoadPath(u); + } + void Finalize(Creature &) {} + void Reset(Creature &u) { ReloadPath(u); } + bool Update(Creature &u, const uint32 &diff); + + void MovementInform(Creature &); + + MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; } + + // now path movement implmementation + void LoadPath(Creature &c); + void ReloadPath(Creature &c) { ClearWaypoints(); LoadPath(c); } + + // Player stoping creature + bool IsStopedByPlayer() { return b_StopedByPlayer; } + void SetStopedByPlayer(bool val) { b_StopedByPlayer = val; } + + // statics + static void Initialize(void); + private: + void ClearWaypoints(); + bool b_StopedByPlayer; +}; + +/** FlightPathMovementGenerator generates movement of the player for the paths + * and hence generates ground and activities for the player. + */ +class MANGOS_DLL_SPEC FlightPathMovementGenerator +: public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, +public PathMovementBase +{ + uint32 i_pathId; + std::vector i_mapIds; + public: + explicit FlightPathMovementGenerator(uint32 id, uint32 startNode = 0) : i_pathId(id) { i_currentNode = startNode; } + void Initialize(Player &); + void Finalize(Player &); + void Reset(Player &) {} + bool Update(Player &, const uint32 &); + MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; } + + void LoadPath(Player &); + void ReloadPath(Player &) { /* don't reload flight path */ } + + Path& GetPath() { return i_path; } + uint32 GetPathAtMapEnd() const; + inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); } + void SetCurrentNodeAfterTeleport(); + void SkipCurrentNode() { ++i_currentNode; } +}; +#endif diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp new file mode 100644 index 000000000..0a4fe9edb --- /dev/null +++ b/src/game/Weather.cpp @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup world +*/ + +#include "Weather.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Player.h" +#include "World.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "Util.h" + +/// Create the Weather object +Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone(zone), m_weatherChances(weatherChances) +{ + m_timer.SetInterval(sWorld.getConfig(CONFIG_INTERVAL_CHANGEWEATHER)); + m_type = WEATHER_TYPE_FINE; + m_grade = 0; + + sLog.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (1000*MINUTE)) ); +} + +/// Launch a weather update +bool Weather::Update(time_t diff) +{ + if (m_timer.GetCurrent()>=0) + m_timer.Update(diff); + else m_timer.SetCurrent(0); + + ///- If the timer has passed, ReGenerate the weather + if(m_timer.Passed()) + { + m_timer.Reset(); + // update only if Regenerate has changed the weather + if(ReGenerate()) + { + ///- Weather will be removed if not updated (no players in zone anymore) + if(!UpdateWeather()) + return false; + } + } + return true; +} + +/// Calculate the new weather +bool Weather::ReGenerate() +{ + if (!m_weatherChances) + { + m_type = WEATHER_TYPE_FINE; + m_grade = 0.0f; + return false; + } + + /// Weather statistics: + ///- 30% - no change + ///- 30% - weather gets better (if not fine) or change weather type + ///- 30% - weather worsens (if not fine) + ///- 10% - radical change (if not fine) + uint32 u = urand(0, 99); + + if (u < 30) + return false; + + // remember old values + WeatherType old_type = m_type; + float old_grade = m_grade; + + //78 days between January 1st and March 20nd; 365/4=91 days by season + // season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html + time_t gtime = sWorld.GetGameTime(); + struct tm * ltime = localtime(>ime); + uint32 season = ((ltime->tm_yday - 78 + 365)/91)%4; + + static char const* seasonName[WEATHER_SEASONS] = { "spring", "summer", "fall", "winter" }; + + sLog.outDebug("Generating a change in %s weather for zone %u.", seasonName[season], m_zone); + + if ((u < 60) && (m_grade < 0.33333334f)) // Get fair + { + m_type = WEATHER_TYPE_FINE; + m_grade = 0.0f; + } + + if ((u < 60) && (m_type != WEATHER_TYPE_FINE)) // Get better + { + m_grade -= 0.33333334f; + return true; + } + + if ((u < 90) && (m_type != WEATHER_TYPE_FINE)) // Get worse + { + m_grade += 0.33333334f; + return true; + } + + if (m_type != WEATHER_TYPE_FINE) + { + /// Radical change: + ///- if light -> heavy + ///- if medium -> change weather type + ///- if heavy -> 50% light, 50% change weather type + + if (m_grade < 0.33333334f) + { + m_grade = 0.9999f; // go nuts + return true; + } + else + { + if (m_grade > 0.6666667f) + { + // Severe change, but how severe? + uint32 rnd = urand(0,99); + if (rnd < 50) + { + m_grade -= 0.6666667f; + return true; + } + } + m_type = WEATHER_TYPE_FINE; // clear up + m_grade = 0; + } + } + + // At this point, only weather that isn't doing anything remains but that have weather data + uint32 chance1 = m_weatherChances->data[season].rainChance; + uint32 chance2 = chance1+ m_weatherChances->data[season].snowChance; + uint32 chance3 = chance2+ m_weatherChances->data[season].stormChance; + + uint32 rnd = urand(0, 99); + if(rnd <= chance1) + m_type = WEATHER_TYPE_RAIN; + else if(rnd <= chance2) + m_type = WEATHER_TYPE_SNOW; + else if(rnd <= chance3) + m_type = WEATHER_TYPE_STORM; + else + m_type = WEATHER_TYPE_FINE; + + /// New weather statistics (if not fine): + ///- 85% light + ///- 7% medium + ///- 7% heavy + /// If fine 100% sun (no fog) + + if (m_type == WEATHER_TYPE_FINE) + { + m_grade = 0.0f; + } + else if (u < 90) + { + m_grade = rand_norm() * 0.3333f; + } + else + { + // Severe change, but how severe? + rnd = urand(0, 99); + if (rnd < 50) + m_grade = rand_norm() * 0.3333f + 0.3334f; + else + m_grade = rand_norm() * 0.3333f + 0.6667f; + } + + // return true only in case weather changes + return m_type != old_type || m_grade != old_grade; +} + +void Weather::SendWeatherUpdateToPlayer(Player *player) +{ + WorldPacket data( SMSG_WEATHER, (4+4+4) ); + + data << uint32(GetWeatherState()) << (float)m_grade << uint8(0); + player->GetSession()->SendPacket( &data ); +} + +void Weather::SendFineWeatherUpdateToPlayer(Player *player) +{ + WorldPacket data( SMSG_WEATHER, (4+4+4) ); + + data << (uint32)WEATHER_STATE_FINE << (float)0.0f << uint8(0); + player->GetSession()->SendPacket( &data ); +} + +/// Send the new weather to all players in the zone +bool Weather::UpdateWeather() +{ + Player* player = sWorld.FindPlayerInZone(m_zone); + if(!player) + return false; + + ///- Send the weather packet to all players in this zone + if (m_grade >= 1) + m_grade = 0.9999f; + else if (m_grade < 0) + m_grade = 0.0001f; + + WeatherState state = GetWeatherState(); + + WorldPacket data( SMSG_WEATHER, (4+4+4) ); + data << uint32(state) << (float)m_grade << uint8(0); + player->SendMessageToSet( &data, true ); + + ///- Log the event + char const* wthstr; + switch(state) + { + case WEATHER_STATE_LIGHT_RAIN: + wthstr = "light rain"; + break; + case WEATHER_STATE_MEDIUM_RAIN: + wthstr = "medium rain"; + break; + case WEATHER_STATE_HEAVY_RAIN: + wthstr = "heavy rain"; + break; + case WEATHER_STATE_LIGHT_SNOW: + wthstr = "light snow"; + break; + case WEATHER_STATE_MEDIUM_SNOW: + wthstr = "medium snow"; + break; + case WEATHER_STATE_HEAVY_SNOW: + wthstr = "heavy snow"; + break; + case WEATHER_STATE_LIGHT_SANDSTORM: + wthstr = "light sandstorm"; + break; + case WEATHER_STATE_MEDIUM_SANDSTORM: + wthstr = "medium sandstorm"; + break; + case WEATHER_STATE_HEAVY_SANDSTORM: + wthstr = "heavy sandstorm"; + break; + case WEATHER_STATE_THUNDERS: + wthstr = "thunders"; + break; + case WEATHER_STATE_BLACKRAIN: + wthstr = "blackrain"; + break; + case WEATHER_STATE_FINE: + default: + wthstr = "fine"; + break; + } + sLog.outDetail("Change the weather of zone %u to %s.", m_zone, wthstr); + + return true; +} + +/// Set the weather +void Weather::SetWeather(WeatherType type, float grade) +{ + if(m_type == type && m_grade == grade) + return; + + m_type = type; + m_grade = grade; + UpdateWeather(); +} + +/// Get the sound number associated with the current weather +WeatherState Weather::GetWeatherState() const +{ + if (m_grade<0.27f) + return WEATHER_STATE_FINE; + + switch(m_type) + { + case WEATHER_TYPE_RAIN: + if(m_grade<0.40f) + return WEATHER_STATE_LIGHT_RAIN; + else if(m_grade<0.70f) + return WEATHER_STATE_MEDIUM_RAIN; + else + return WEATHER_STATE_HEAVY_RAIN; + case WEATHER_TYPE_SNOW: + if(m_grade<0.40f) + return WEATHER_STATE_LIGHT_SNOW; + else if(m_grade<0.70f) + return WEATHER_STATE_MEDIUM_SNOW; + else + return WEATHER_STATE_HEAVY_SNOW; + case WEATHER_TYPE_STORM: + if(m_grade<0.40f) + return WEATHER_STATE_LIGHT_SANDSTORM; + else if(m_grade<0.70f) + return WEATHER_STATE_MEDIUM_SANDSTORM; + else + return WEATHER_STATE_HEAVY_SANDSTORM; + case WEATHER_TYPE_BLACKRAIN: + return WEATHER_STATE_BLACKRAIN; + case WEATHER_TYPE_THUNDERS: + return WEATHER_STATE_THUNDERS; + case WEATHER_TYPE_FINE: + default: + return WEATHER_STATE_FINE; + } +} diff --git a/src/game/Weather.h b/src/game/Weather.h new file mode 100644 index 000000000..2ed41783a --- /dev/null +++ b/src/game/Weather.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup world +/// @{ +/// \file + +#ifndef __WEATHER_H +#define __WEATHER_H + +#include "Common.h" +#include "SharedDefines.h" +#include "Timer.h" + +class Player; + +enum WeatherState +{ + WEATHER_STATE_FINE = 0, + WEATHER_STATE_LIGHT_RAIN = 3, + WEATHER_STATE_MEDIUM_RAIN = 4, + WEATHER_STATE_HEAVY_RAIN = 5, + WEATHER_STATE_LIGHT_SNOW = 6, + WEATHER_STATE_MEDIUM_SNOW = 7, + WEATHER_STATE_HEAVY_SNOW = 8, + WEATHER_STATE_LIGHT_SANDSTORM = 22, + WEATHER_STATE_MEDIUM_SANDSTORM = 41, + WEATHER_STATE_HEAVY_SANDSTORM = 42, + WEATHER_STATE_THUNDERS = 86, + WEATHER_STATE_BLACKRAIN = 90 +}; + +struct WeatherZoneChances; + +/// Weather for one zone +class Weather +{ + public: + Weather(uint32 zone, WeatherZoneChances const* weatherChances); + ~Weather() { }; + bool ReGenerate(); + bool UpdateWeather(); + void SendWeatherUpdateToPlayer(Player *player); + static void SendFineWeatherUpdateToPlayer(Player *player); + void SetWeather(WeatherType type, float grade); + /// For which zone is this weather? + uint32 GetZone() { return m_zone; }; + bool Update(time_t diff); + private: + WeatherState GetWeatherState() const; + uint32 m_zone; + WeatherType m_type; + float m_grade; + IntervalTimer m_timer; + WeatherZoneChances const* m_weatherChances; +}; +#endif diff --git a/src/game/World.cpp b/src/game/World.cpp new file mode 100644 index 000000000..708525f83 --- /dev/null +++ b/src/game/World.cpp @@ -0,0 +1,2570 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup world +*/ + +#include "Common.h" +//#include "WorldSocket.h" +#include "Database/DatabaseEnv.h" +#include "Config/ConfigEnv.h" +#include "SystemConfig.h" +#include "Log.h" +#include "Opcodes.h" +#include "WorldSession.h" +#include "WorldPacket.h" +#include "Weather.h" +#include "Player.h" +#include "SkillExtraItems.h" +#include "SkillDiscovery.h" +#include "World.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Chat.h" +#include "Database/DBCStores.h" +#include "LootMgr.h" +#include "ItemEnchantmentMgr.h" +#include "MapManager.h" +#include "ScriptCalls.h" +#include "CreatureAIRegistry.h" +#include "Policies/SingletonImp.h" +#include "BattleGroundMgr.h" +#include "TemporarySummon.h" +#include "WaypointMovementGenerator.h" +#include "VMapFactory.h" +#include "GlobalEvents.h" +#include "GameEvent.h" +#include "Database/DatabaseImpl.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "InstanceSaveMgr.h" +#include "WaypointManager.h" +#include "Util.h" + +INSTANTIATE_SINGLETON_1( World ); + +volatile bool World::m_stopEvent = false; +volatile uint32 World::m_worldLoopCounter = 0; + +float World::m_MaxVisibleDistanceForCreature = DEFAULT_VISIBILITY_DISTANCE; +float World::m_MaxVisibleDistanceForPlayer = DEFAULT_VISIBILITY_DISTANCE; +float World::m_MaxVisibleDistanceForObject = DEFAULT_VISIBILITY_DISTANCE; +float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE; +float World::m_VisibleUnitGreyDistance = 0; +float World::m_VisibleObjectGreyDistance = 0; + +// ServerMessages.dbc +enum ServerMessageType +{ + SERVER_MSG_SHUTDOWN_TIME = 1, + SERVER_MSG_RESTART_TIME = 2, + SERVER_MSG_STRING = 3, + SERVER_MSG_SHUTDOWN_CANCELLED = 4, + SERVER_MSG_RESTART_CANCELLED = 5 +}; + +struct ScriptAction +{ + uint64 sourceGUID; + uint64 targetGUID; + uint64 ownerGUID; // owner of source if source is item + ScriptInfo const* script; // pointer to static script data +}; + +/// World constructor +World::World() +{ + m_playerLimit = 0; + m_allowMovement = true; + m_ShutdownMask = 0; + m_ShutdownTimer = 0; + m_gameTime=time(NULL); + m_startTime=m_gameTime; + m_maxActiveSessionCount = 0; + m_maxQueuedSessionCount = 0; + m_resultQueue = NULL; + m_NextDailyQuestReset = 0; + + m_defaultDbcLocale = LOCALE_enUS; + m_availableDbcLocaleMask = 0; +} + +/// World destructor +World::~World() +{ + ///- Empty the kicked session set + for (std::set::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr) + delete *itr; + + m_kicked_sessions.clear(); + + ///- Empty the WeatherMap + for (WeatherMap::iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr) + delete itr->second; + + m_weathers.clear(); + + VMAP::VMapFactory::clear(); + + if(m_resultQueue) delete m_resultQueue; + + //TODO free addSessQueue +} + +/// Find a player in a specified zone +Player* World::FindPlayerInZone(uint32 zone) +{ + ///- circle through active sessions and return the first player found in the zone + SessionMap::iterator itr; + for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + { + if(!itr->second) + continue; + Player *player = itr->second->GetPlayer(); + if(!player) + continue; + if( player->IsInWorld() && player->GetZoneId() == zone ) + { + // Used by the weather system. We return the player to broadcast the change weather message to him and all players in the zone. + return player; + } + } + return NULL; +} + +/// Find a session by its id +WorldSession* World::FindSession(uint32 id) const +{ + SessionMap::const_iterator itr = m_sessions.find(id); + + if(itr != m_sessions.end()) + return itr->second; // also can return NULL for kicked session + else + return NULL; +} + +/// Remove a given session +bool World::RemoveSession(uint32 id) +{ + ///- Find the session, kick the user, but we can't delete session at this moment to prevent iterator invalidation + SessionMap::iterator itr = m_sessions.find(id); + + if(itr != m_sessions.end() && itr->second) + { + if (itr->second->PlayerLoading()) + return false; + itr->second->KickPlayer(); + } + + return true; +} + +void World::AddSession(WorldSession* s) +{ + addSessQueue.add(s); +} + +void +World::AddSession_ (WorldSession* s) +{ + ASSERT (s); + + //NOTE - Still there is race condition in WorldSession* being used in the Sockets + + ///- kick already loaded player with same account (if any) and remove session + ///- if player is in loading and want to load again, return + if (!RemoveSession (s->GetAccountId ())) + { + s->KickPlayer (); + m_kicked_sessions.insert (s); + return; + } + + WorldSession* old = m_sessions[s->GetAccountId ()]; + m_sessions[s->GetAccountId ()] = s; + + // if session already exist, prepare to it deleting at next world update + // NOTE - KickPlayer() should be called on "old" in RemoveSession() + if (old) + m_kicked_sessions.insert (old); + + uint32 Sessions = GetActiveAndQueuedSessionCount (); + uint32 pLimit = GetPlayerAmountLimit (); + uint32 QueueSize = GetQueueSize (); //number of players in the queue + bool inQueue = false; + //so we don't count the user trying to + //login as a session and queue the socket that we are using + --Sessions; + + if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER ) + { + AddQueuedPlayer (s); + UpdateMaxSessionCounters (); + sLog.outDetail ("PlayerQueue: Account id %u is in Queue Position (%u).", s->GetAccountId (), ++QueueSize); + return; + } + + WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); + packet << uint8 (AUTH_OK); + packet << uint32 (0); // unknown random value... + packet << uint8 (0); + packet << uint32 (0); + packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account + s->SendPacket (&packet); + + UpdateMaxSessionCounters (); + + // Updates the population + if (pLimit > 0) + { + float popu = GetActiveSessionCount (); //updated number of users on the server + popu /= pLimit; + popu *= 2; + loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID); + sLog.outDetail ("Server Population (%f).", popu); + } +} + +int32 World::GetQueuePos(WorldSession* sess) +{ + uint32 position = 1; + + for(Queue::iterator iter = m_QueuedPlayer.begin(); iter != m_QueuedPlayer.end(); ++iter, ++position) + if((*iter) == sess) + return position; + + return 0; +} + +void World::AddQueuedPlayer(WorldSession* sess) +{ + m_QueuedPlayer.push_back (sess); + + // The 1st SMSG_AUTH_RESPONSE needs to contain other info too. + WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); + packet << uint8 (AUTH_WAIT_QUEUE); + packet << uint32 (0); // unknown random value... + packet << uint8 (0); + packet << uint32 (0); + packet << uint8 (sess->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account + packet << uint32(GetQueuePos (sess)); + sess->SendPacket (&packet); + + //sess->SendAuthWaitQue (GetQueuePos (sess)); +} + +void World::RemoveQueuedPlayer(WorldSession* sess) +{ + // sessions count including queued to remove (if removed_session set) + uint32 sessions = GetActiveSessionCount(); + + uint32 position = 1; + Queue::iterator iter = m_QueuedPlayer.begin(); + + // if session not queued then we need decrease sessions count (Remove socked callet before session removing from session list) + bool decrease_session = true; + + // search to remove and count skipped positions + for(;iter != m_QueuedPlayer.end(); ++iter, ++position) + { + if(*iter==sess) + { + Queue::iterator iter2 = iter; + ++iter; + m_QueuedPlayer.erase(iter2); + decrease_session = false; // removing queued session + break; + } + } + + // iter point to next socked after removed or end() + // position store position of removed socket and then new position next socket after removed + + // decrease for case session queued for removing + if(decrease_session && sessions) + --sessions; + + // accept first in queue + if( (!m_playerLimit || sessions < m_playerLimit) && !m_QueuedPlayer.empty() ) + { + WorldSession * socket = m_QueuedPlayer.front(); + socket->SendAuthWaitQue(0); + m_QueuedPlayer.pop_front(); + + // update iter to point first queued socket or end() if queue is empty now + iter = m_QueuedPlayer.begin(); + position = 1; + } + + // update position from iter to end() + // iter point to first not updated socket, position store new position + for(; iter != m_QueuedPlayer.end(); ++iter, ++position) + (*iter)->SendAuthWaitQue(position); +} + +/// Find a Weather object by the given zoneid +Weather* World::FindWeather(uint32 id) const +{ + WeatherMap::const_iterator itr = m_weathers.find(id); + + if(itr != m_weathers.end()) + return itr->second; + else + return 0; +} + +/// Remove a Weather object for the given zoneid +void World::RemoveWeather(uint32 id) +{ + // not called at the moment. Kept for completeness + WeatherMap::iterator itr = m_weathers.find(id); + + if(itr != m_weathers.end()) + { + delete itr->second; + m_weathers.erase(itr); + } +} + +/// Add a Weather object to the list +Weather* World::AddWeather(uint32 zone_id) +{ + WeatherZoneChances const* weatherChances = objmgr.GetWeatherChances(zone_id); + + // zone not have weather, ignore + if(!weatherChances) + return NULL; + + Weather* w = new Weather(zone_id,weatherChances); + m_weathers[w->GetZone()] = w; + w->ReGenerate(); + w->UpdateWeather(); + return w; +} + +/// Initialize config values +void World::LoadConfigSettings(bool reload) +{ + if(reload) + { + if(!sConfig.Reload()) + { + sLog.outError("World settings reload fail: can't read settings from %s.",sConfig.GetFilename().c_str()); + return; + } + } + + ///- Read the version of the configuration file and warn the user in case of emptiness or mismatch + uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); + if(!confVersion) + { + sLog.outError("*****************************************************************************"); + sLog.outError(" WARNING: mangosd.conf does not include a ConfVersion variable."); + sLog.outError(" Your configuration file may be out of date!"); + sLog.outError("*****************************************************************************"); + clock_t pause = 3000 + clock(); + while (pause > clock()); + } + else + { + if (confVersion < _MANGOSDCONFVERSION) + { + sLog.outError("*****************************************************************************"); + sLog.outError(" WARNING: Your mangosd.conf version indicates your conf file is out of date!"); + sLog.outError(" Please check for updates, as your current default values may cause"); + sLog.outError(" unexpected behavior."); + sLog.outError("*****************************************************************************"); + clock_t pause = 3000 + clock(); + while (pause > clock()); + } + } + + ///- Read the player limit and the Message of the day from the config file + SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT), true ); + SetMotd( sConfig.GetStringDefault("Motd", "Welcome to the Massive Network Game Object Server." ) ); + + ///- Read all rates from the config file + rate_values[RATE_HEALTH] = sConfig.GetFloatDefault("Rate.Health", 1); + if(rate_values[RATE_HEALTH] < 0) + { + sLog.outError("Rate.Health (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_HEALTH]); + rate_values[RATE_HEALTH] = 1; + } + rate_values[RATE_POWER_MANA] = sConfig.GetFloatDefault("Rate.Mana", 1); + if(rate_values[RATE_POWER_MANA] < 0) + { + sLog.outError("Rate.Mana (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]); + rate_values[RATE_POWER_MANA] = 1; + } + rate_values[RATE_POWER_RAGE_INCOME] = sConfig.GetFloatDefault("Rate.Rage.Income", 1); + rate_values[RATE_POWER_RAGE_LOSS] = sConfig.GetFloatDefault("Rate.Rage.Loss", 1); + if(rate_values[RATE_POWER_RAGE_LOSS] < 0) + { + sLog.outError("Rate.Rage.Loss (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]); + rate_values[RATE_POWER_RAGE_LOSS] = 1; + } + rate_values[RATE_POWER_FOCUS] = sConfig.GetFloatDefault("Rate.Focus", 1.0f); + rate_values[RATE_LOYALTY] = sConfig.GetFloatDefault("Rate.Loyalty", 1.0f); + rate_values[RATE_SKILL_DISCOVERY] = sConfig.GetFloatDefault("Rate.Skill.Discovery", 1.0f); + rate_values[RATE_DROP_ITEM_POOR] = sConfig.GetFloatDefault("Rate.Drop.Item.Poor", 1.0f); + rate_values[RATE_DROP_ITEM_NORMAL] = sConfig.GetFloatDefault("Rate.Drop.Item.Normal", 1.0f); + rate_values[RATE_DROP_ITEM_UNCOMMON] = sConfig.GetFloatDefault("Rate.Drop.Item.Uncommon", 1.0f); + rate_values[RATE_DROP_ITEM_RARE] = sConfig.GetFloatDefault("Rate.Drop.Item.Rare", 1.0f); + rate_values[RATE_DROP_ITEM_EPIC] = sConfig.GetFloatDefault("Rate.Drop.Item.Epic", 1.0f); + rate_values[RATE_DROP_ITEM_LEGENDARY] = sConfig.GetFloatDefault("Rate.Drop.Item.Legendary", 1.0f); + rate_values[RATE_DROP_ITEM_ARTIFACT] = sConfig.GetFloatDefault("Rate.Drop.Item.Artifact", 1.0f); + rate_values[RATE_DROP_ITEM_REFERENCED] = sConfig.GetFloatDefault("Rate.Drop.Item.Referenced", 1.0f); + rate_values[RATE_DROP_MONEY] = sConfig.GetFloatDefault("Rate.Drop.Money", 1.0f); + rate_values[RATE_XP_KILL] = sConfig.GetFloatDefault("Rate.XP.Kill", 1.0f); + rate_values[RATE_XP_QUEST] = sConfig.GetFloatDefault("Rate.XP.Quest", 1.0f); + rate_values[RATE_XP_EXPLORE] = sConfig.GetFloatDefault("Rate.XP.Explore", 1.0f); + rate_values[RATE_XP_PAST_70] = sConfig.GetFloatDefault("Rate.XP.PastLevel70", 1.0f); + rate_values[RATE_REPUTATION_GAIN] = sConfig.GetFloatDefault("Rate.Reputation.Gain", 1.0f); + rate_values[RATE_CREATURE_NORMAL_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Normal.Damage", 1.0f); + rate_values[RATE_CREATURE_ELITE_ELITE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.Elite.Damage", 1.0f); + rate_values[RATE_CREATURE_ELITE_RAREELITE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.RAREELITE.Damage", 1.0f); + rate_values[RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.WORLDBOSS.Damage", 1.0f); + rate_values[RATE_CREATURE_ELITE_RARE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.RARE.Damage", 1.0f); + rate_values[RATE_CREATURE_NORMAL_HP] = sConfig.GetFloatDefault("Rate.Creature.Normal.HP", 1.0f); + rate_values[RATE_CREATURE_ELITE_ELITE_HP] = sConfig.GetFloatDefault("Rate.Creature.Elite.Elite.HP", 1.0f); + rate_values[RATE_CREATURE_ELITE_RAREELITE_HP] = sConfig.GetFloatDefault("Rate.Creature.Elite.RAREELITE.HP", 1.0f); + rate_values[RATE_CREATURE_ELITE_WORLDBOSS_HP] = sConfig.GetFloatDefault("Rate.Creature.Elite.WORLDBOSS.HP", 1.0f); + rate_values[RATE_CREATURE_ELITE_RARE_HP] = sConfig.GetFloatDefault("Rate.Creature.Elite.RARE.HP", 1.0f); + rate_values[RATE_CREATURE_NORMAL_SPELLDAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Normal.SpellDamage", 1.0f); + rate_values[RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.Elite.SpellDamage", 1.0f); + rate_values[RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.RAREELITE.SpellDamage", 1.0f); + rate_values[RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.WORLDBOSS.SpellDamage", 1.0f); + rate_values[RATE_CREATURE_ELITE_RARE_SPELLDAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.RARE.SpellDamage", 1.0f); + rate_values[RATE_CREATURE_AGGRO] = sConfig.GetFloatDefault("Rate.Creature.Aggro", 1.0f); + rate_values[RATE_REST_INGAME] = sConfig.GetFloatDefault("Rate.Rest.InGame", 1.0f); + rate_values[RATE_REST_OFFLINE_IN_TAVERN_OR_CITY] = sConfig.GetFloatDefault("Rate.Rest.Offline.InTavernOrCity", 1.0f); + rate_values[RATE_REST_OFFLINE_IN_WILDERNESS] = sConfig.GetFloatDefault("Rate.Rest.Offline.InWilderness", 1.0f); + rate_values[RATE_DAMAGE_FALL] = sConfig.GetFloatDefault("Rate.Damage.Fall", 1.0f); + rate_values[RATE_AUCTION_TIME] = sConfig.GetFloatDefault("Rate.Auction.Time", 1.0f); + rate_values[RATE_AUCTION_DEPOSIT] = sConfig.GetFloatDefault("Rate.Auction.Deposit", 1.0f); + rate_values[RATE_AUCTION_CUT] = sConfig.GetFloatDefault("Rate.Auction.Cut", 1.0f); + rate_values[RATE_HONOR] = sConfig.GetFloatDefault("Rate.Honor",1.0f); + rate_values[RATE_MINING_AMOUNT] = sConfig.GetFloatDefault("Rate.Mining.Amount",1.0f); + rate_values[RATE_MINING_NEXT] = sConfig.GetFloatDefault("Rate.Mining.Next",1.0f); + rate_values[RATE_INSTANCE_RESET_TIME] = sConfig.GetFloatDefault("Rate.InstanceResetTime",1.0f); + rate_values[RATE_TALENT] = sConfig.GetFloatDefault("Rate.Talent",1.0f); + if(rate_values[RATE_TALENT] < 0.0f) + { + sLog.outError("Rate.Talent (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_TALENT]); + rate_values[RATE_TALENT] = 1.0f; + } + rate_values[RATE_CORPSE_DECAY_LOOTED] = sConfig.GetFloatDefault("Rate.Corpse.Decay.Looted",0.1f); + + rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = sConfig.GetFloatDefault("TargetPosRecalculateRange",1.5f); + if(rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] < CONTACT_DISTANCE) + { + sLog.outError("TargetPosRecalculateRange (%f) must be >= %f. Using %f instead.",rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],CONTACT_DISTANCE,CONTACT_DISTANCE); + rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = CONTACT_DISTANCE; + } + else if(rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] > ATTACK_DISTANCE) + { + sLog.outError("TargetPosRecalculateRange (%f) must be <= %f. Using %f instead.",rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],ATTACK_DISTANCE,ATTACK_DISTANCE); + rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = ATTACK_DISTANCE; + } + + rate_values[RATE_DURABILITY_LOSS_DAMAGE] = sConfig.GetFloatDefault("DurabilityLossChance.Damage",0.5f); + if(rate_values[RATE_DURABILITY_LOSS_DAMAGE] < 0.0f) + { + sLog.outError("DurabilityLossChance.Damage (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_DURABILITY_LOSS_DAMAGE]); + rate_values[RATE_DURABILITY_LOSS_DAMAGE] = 0.0f; + } + rate_values[RATE_DURABILITY_LOSS_ABSORB] = sConfig.GetFloatDefault("DurabilityLossChance.Absorb",0.5f); + if(rate_values[RATE_DURABILITY_LOSS_ABSORB] < 0.0f) + { + sLog.outError("DurabilityLossChance.Absorb (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_DURABILITY_LOSS_ABSORB]); + rate_values[RATE_DURABILITY_LOSS_ABSORB] = 0.0f; + } + rate_values[RATE_DURABILITY_LOSS_PARRY] = sConfig.GetFloatDefault("DurabilityLossChance.Parry",0.05f); + if(rate_values[RATE_DURABILITY_LOSS_PARRY] < 0.0f) + { + sLog.outError("DurabilityLossChance.Parry (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_DURABILITY_LOSS_PARRY]); + rate_values[RATE_DURABILITY_LOSS_PARRY] = 0.0f; + } + rate_values[RATE_DURABILITY_LOSS_BLOCK] = sConfig.GetFloatDefault("DurabilityLossChance.Block",0.05f); + if(rate_values[RATE_DURABILITY_LOSS_BLOCK] < 0.0f) + { + sLog.outError("DurabilityLossChance.Block (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_DURABILITY_LOSS_BLOCK]); + rate_values[RATE_DURABILITY_LOSS_BLOCK] = 0.0f; + } + + ///- Read other configuration items from the config file + + m_configs[CONFIG_COMPRESSION] = sConfig.GetIntDefault("Compression", 1); + if(m_configs[CONFIG_COMPRESSION] < 1 || m_configs[CONFIG_COMPRESSION] > 9) + { + sLog.outError("Compression level (%i) must be in range 1..9. Using default compression level (1).",m_configs[CONFIG_COMPRESSION]); + m_configs[CONFIG_COMPRESSION] = 1; + } + m_configs[CONFIG_ADDON_CHANNEL] = sConfig.GetBoolDefault("AddonChannel", true); + m_configs[CONFIG_GRID_UNLOAD] = sConfig.GetBoolDefault("GridUnload", true); + m_configs[CONFIG_INTERVAL_SAVE] = sConfig.GetIntDefault("PlayerSaveInterval", 900000); + + m_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfig.GetIntDefault("GridCleanUpDelay", 300000); + if(m_configs[CONFIG_INTERVAL_GRIDCLEAN] < MIN_GRID_DELAY) + { + sLog.outError("GridCleanUpDelay (%i) must be greater %u. Use this minimal value.",m_configs[CONFIG_INTERVAL_GRIDCLEAN],MIN_GRID_DELAY); + m_configs[CONFIG_INTERVAL_GRIDCLEAN] = MIN_GRID_DELAY; + } + if(reload) + MapManager::Instance().SetGridCleanUpDelay(m_configs[CONFIG_INTERVAL_GRIDCLEAN]); + + m_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfig.GetIntDefault("MapUpdateInterval", 100); + if(m_configs[CONFIG_INTERVAL_MAPUPDATE] < MIN_MAP_UPDATE_DELAY) + { + sLog.outError("MapUpdateInterval (%i) must be greater %u. Use this minimal value.",m_configs[CONFIG_INTERVAL_MAPUPDATE],MIN_MAP_UPDATE_DELAY); + m_configs[CONFIG_INTERVAL_MAPUPDATE] = MIN_MAP_UPDATE_DELAY; + } + if(reload) + MapManager::Instance().SetMapUpdateInterval(m_configs[CONFIG_INTERVAL_MAPUPDATE]); + + m_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfig.GetIntDefault("ChangeWeatherInterval", 600000); + + if(reload) + { + uint32 val = sConfig.GetIntDefault("WorldServerPort", DEFAULT_WORLDSERVER_PORT); + if(val!=m_configs[CONFIG_PORT_WORLD]) + sLog.outError("WorldServerPort option can't be changed at mangosd.conf reload, using current value (%u).",m_configs[CONFIG_PORT_WORLD]); + } + else + m_configs[CONFIG_PORT_WORLD] = sConfig.GetIntDefault("WorldServerPort", DEFAULT_WORLDSERVER_PORT); + + if(reload) + { + uint32 val = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME); + if(val!=m_configs[CONFIG_SOCKET_SELECTTIME]) + sLog.outError("SocketSelectTime option can't be changed at mangosd.conf reload, using current value (%u).",m_configs[DEFAULT_SOCKET_SELECT_TIME]); + } + else + m_configs[CONFIG_SOCKET_SELECTTIME] = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME); + + m_configs[CONFIG_TCP_NO_DELAY] = sConfig.GetBoolDefault("TcpNoDelay", false); + m_configs[CONFIG_GROUP_XP_DISTANCE] = sConfig.GetIntDefault("MaxGroupXPDistance", 74); + /// \todo Add MonsterSight and GuarderSight (with meaning) in mangosd.conf or put them as define + m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 50); + m_configs[CONFIG_SIGHT_GUARDER] = sConfig.GetIntDefault("GuarderSight", 50); + + if(reload) + { + uint32 val = sConfig.GetIntDefault("GameType", 0); + if(val!=m_configs[CONFIG_GAME_TYPE]) + sLog.outError("GameType option can't be changed at mangosd.conf reload, using current value (%u).",m_configs[CONFIG_GAME_TYPE]); + } + else + m_configs[CONFIG_GAME_TYPE] = sConfig.GetIntDefault("GameType", 0); + + if(reload) + { + uint32 val = sConfig.GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT); + if(val!=m_configs[CONFIG_REALM_ZONE]) + sLog.outError("RealmZone option can't be changed at mangosd.conf reload, using current value (%u).",m_configs[CONFIG_REALM_ZONE]); + } + else + m_configs[CONFIG_REALM_ZONE] = sConfig.GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT); + + m_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = sConfig.GetBoolDefault("AllowTwoSide.Accounts", false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Chat",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Channel",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Group",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Guild",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Auction",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Mail",false); + m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false); + m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false); + m_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfig.GetIntDefault("StrictPlayerNames", 0); + m_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfig.GetIntDefault("StrictCharterNames", 0); + m_configs[CONFIG_STRICT_PET_NAMES] = sConfig.GetIntDefault("StrictPetNames", 0); + + m_configs[CONFIG_CHARACTERS_CREATING_DISABLED] = sConfig.GetIntDefault("CharactersCreatingDisabled", 0); + + m_configs[CONFIG_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("CharactersPerRealm", 10); + if(m_configs[CONFIG_CHARACTERS_PER_REALM] < 1 || m_configs[CONFIG_CHARACTERS_PER_REALM] > 10) + { + sLog.outError("CharactersPerRealm (%i) must be in range 1..10. Set to 10.",m_configs[CONFIG_CHARACTERS_PER_REALM]); + m_configs[CONFIG_CHARACTERS_PER_REALM] = 10; + } + + // must be after CONFIG_CHARACTERS_PER_REALM + m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = sConfig.GetIntDefault("CharactersPerAccount", 50); + if(m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] < m_configs[CONFIG_CHARACTERS_PER_REALM]) + { + sLog.outError("CharactersPerAccount (%i) can't be less than CharactersPerRealm (%i).",m_configs[CONFIG_CHARACTERS_PER_ACCOUNT],m_configs[CONFIG_CHARACTERS_PER_REALM]); + m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_configs[CONFIG_CHARACTERS_PER_REALM]; + } + + m_configs[CONFIG_SKIP_CINEMATICS] = sConfig.GetIntDefault("SkipCinematics", 0); + if(m_configs[CONFIG_SKIP_CINEMATICS] < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2) + { + sLog.outError("SkipCinematics (%i) must be in range 0..2. Set to 0.",m_configs[CONFIG_SKIP_CINEMATICS]); + m_configs[CONFIG_SKIP_CINEMATICS] = 0; + } + + if(reload) + { + uint32 val = sConfig.GetIntDefault("MaxPlayerLevel", 60); + if(val!=m_configs[CONFIG_MAX_PLAYER_LEVEL]) + sLog.outError("MaxPlayerLevel option can't be changed at mangosd.conf reload, using current value (%u).",m_configs[CONFIG_MAX_PLAYER_LEVEL]); + } + else + m_configs[CONFIG_MAX_PLAYER_LEVEL] = sConfig.GetIntDefault("MaxPlayerLevel", 60); + if(m_configs[CONFIG_MAX_PLAYER_LEVEL] > 255) + { + sLog.outError("MaxPlayerLevel (%i) must be in range 1..255. Set to 255.",m_configs[CONFIG_MAX_PLAYER_LEVEL]); + m_configs[CONFIG_MAX_PLAYER_LEVEL] = 255; + } + + m_configs[CONFIG_START_PLAYER_LEVEL] = sConfig.GetIntDefault("StartPlayerLevel", 1); + if(m_configs[CONFIG_START_PLAYER_LEVEL] < 1) + { + sLog.outError("StartPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 1.",m_configs[CONFIG_START_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); + m_configs[CONFIG_START_PLAYER_LEVEL] = 1; + } + else if(m_configs[CONFIG_START_PLAYER_LEVEL] > m_configs[CONFIG_MAX_PLAYER_LEVEL]) + { + sLog.outError("StartPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",m_configs[CONFIG_START_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); + m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL]; + } + m_configs[CONFIG_MAX_HONOR_POINTS] = sConfig.GetIntDefault("MaxHonorPoints", 75000); + m_configs[CONFIG_MAX_ARENA_POINTS] = sConfig.GetIntDefault("MaxArenaPoints", 5000); + + m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", false); + m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false); + + m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true); + m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", true); + m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false); + + m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true); + m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfig.GetIntDefault("Instance.ResetTimeHour", 4); + m_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfig.GetIntDefault("Instance.UnloadDelay", 1800000); + + m_configs[CONFIG_MAX_PRIMARY_TRADE_SKILL] = sConfig.GetIntDefault("MaxPrimaryTradeSkill", 2); + m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9); + if(m_configs[CONFIG_MIN_PETITION_SIGNS] > 9) + { + sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.",m_configs[CONFIG_MIN_PETITION_SIGNS]); + m_configs[CONFIG_MIN_PETITION_SIGNS] = 9; + } + + m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState",2); + m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets",2); + m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat",2); + m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo",2); + + m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList",false); + m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false); + m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false); + + m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0); + + m_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfig.GetIntDefault("MailDeliveryDelay",HOUR); + + m_configs[CONFIG_UPTIME_UPDATE] = sConfig.GetIntDefault("UpdateUptimeInterval", 10); + if(m_configs[CONFIG_UPTIME_UPDATE]<=0) + { + sLog.outError("UpdateUptimeInterval (%i) must be > 0, set to default 10.",m_configs[CONFIG_UPTIME_UPDATE]); + m_configs[CONFIG_UPTIME_UPDATE] = 10; + } + if(reload) + { + m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*1000); + m_timers[WUPDATE_UPTIME].Reset(); + } + + m_configs[CONFIG_SKILL_CHANCE_ORANGE] = sConfig.GetIntDefault("SkillChance.Orange",100); + m_configs[CONFIG_SKILL_CHANCE_YELLOW] = sConfig.GetIntDefault("SkillChance.Yellow",75); + m_configs[CONFIG_SKILL_CHANCE_GREEN] = sConfig.GetIntDefault("SkillChance.Green",25); + m_configs[CONFIG_SKILL_CHANCE_GREY] = sConfig.GetIntDefault("SkillChance.Grey",0); + + m_configs[CONFIG_SKILL_CHANCE_MINING_STEPS] = sConfig.GetIntDefault("SkillChance.MiningSteps",75); + m_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS] = sConfig.GetIntDefault("SkillChance.SkinningSteps",75); + + m_configs[CONFIG_SKILL_PROSPECTING] = sConfig.GetBoolDefault("SkillChance.Prospecting",false); + + m_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfig.GetIntDefault("SkillGain.Crafting", 1); + if(m_configs[CONFIG_SKILL_GAIN_CRAFTING] < 0) + { + sLog.outError("SkillGain.Crafting (%i) can't be negative. Set to 1.",m_configs[CONFIG_SKILL_GAIN_CRAFTING]); + m_configs[CONFIG_SKILL_GAIN_CRAFTING] = 1; + } + + m_configs[CONFIG_SKILL_GAIN_DEFENSE] = sConfig.GetIntDefault("SkillGain.Defense", 1); + if(m_configs[CONFIG_SKILL_GAIN_DEFENSE] < 0) + { + sLog.outError("SkillGain.Defense (%i) can't be negative. Set to 1.",m_configs[CONFIG_SKILL_GAIN_DEFENSE]); + m_configs[CONFIG_SKILL_GAIN_DEFENSE] = 1; + } + + m_configs[CONFIG_SKILL_GAIN_GATHERING] = sConfig.GetIntDefault("SkillGain.Gathering", 1); + if(m_configs[CONFIG_SKILL_GAIN_GATHERING] < 0) + { + sLog.outError("SkillGain.Gathering (%i) can't be negative. Set to 1.",m_configs[CONFIG_SKILL_GAIN_GATHERING]); + m_configs[CONFIG_SKILL_GAIN_GATHERING] = 1; + } + + m_configs[CONFIG_SKILL_GAIN_WEAPON] = sConfig.GetIntDefault("SkillGain.Weapon", 1); + if(m_configs[CONFIG_SKILL_GAIN_WEAPON] < 0) + { + sLog.outError("SkillGain.Weapon (%i) can't be negative. Set to 1.",m_configs[CONFIG_SKILL_GAIN_WEAPON]); + m_configs[CONFIG_SKILL_GAIN_WEAPON] = 1; + } + + m_configs[CONFIG_MAX_OVERSPEED_PINGS] = sConfig.GetIntDefault("MaxOverspeedPings",2); + if(m_configs[CONFIG_MAX_OVERSPEED_PINGS] != 0 && m_configs[CONFIG_MAX_OVERSPEED_PINGS] < 2) + { + sLog.outError("MaxOverspeedPings (%i) must be in range 2..infinity (or 0 to disable check. Set to 2.",m_configs[CONFIG_MAX_OVERSPEED_PINGS]); + m_configs[CONFIG_MAX_OVERSPEED_PINGS] = 2; + } + + m_configs[CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY] = sConfig.GetBoolDefault("SaveRespawnTimeImmediately",true); + m_configs[CONFIG_WEATHER] = sConfig.GetBoolDefault("ActivateWeather",true); + + if(reload) + { + uint32 val = sConfig.GetIntDefault("Expansion",1); + if(val!=m_configs[CONFIG_EXPANSION]) + sLog.outError("Expansion option can't be changed at mangosd.conf reload, using current value (%u).",m_configs[CONFIG_EXPANSION]); + } + else + m_configs[CONFIG_EXPANSION] = sConfig.GetIntDefault("Expansion",1); + + m_configs[CONFIG_CHATFLOOD_MESSAGE_COUNT] = sConfig.GetIntDefault("ChatFlood.MessageCount",10); + m_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = sConfig.GetIntDefault("ChatFlood.MessageDelay",1); + m_configs[CONFIG_CHATFLOOD_MUTE_TIME] = sConfig.GetIntDefault("ChatFlood.MuteTime",10); + + m_configs[CONFIG_EVENT_ANNOUNCE] = sConfig.GetIntDefault("Event.Announce",0); + + m_configs[CONFIG_CREATURE_FAMILY_ASSISTEMCE_RADIUS] = sConfig.GetIntDefault("CreatureFamilyAssistenceRadius",10); + + m_configs[CONFIG_WORLD_BOSS_LEVEL_DIFF] = sConfig.GetIntDefault("WorldBossLevelDiff",3); + + // note: disable value (-1) will assigned as 0xFFFFFFF, to prevent overflow at calculations limit it to max possible player level (255) + m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.LowLevelHideDiff",4); + if(m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] > 255) + m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = 255; + m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.HighLevelHideDiff",7); + if(m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] > 255) + m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = 255; + + m_configs[CONFIG_DETECT_POS_COLLISION] = sConfig.GetBoolDefault("DetectPosCollision", true); + + m_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfig.GetBoolDefault("Channel.RestrictedLfg", true); + m_configs[CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL] = sConfig.GetBoolDefault("Channel.SilentlyGMJoin", false); + + m_configs[CONFIG_TALENTS_INSPECTING] = sConfig.GetBoolDefault("TalentsInspecting", true); + m_configs[CONFIG_CHAT_FAKE_MESSAGE_PREVENTING] = sConfig.GetBoolDefault("ChatFakeMessagePreventing", false); + + m_configs[CONFIG_CORPSE_DECAY_NORMAL] = sConfig.GetIntDefault("Corpse.Decay.NORMAL", 60); + m_configs[CONFIG_CORPSE_DECAY_RARE] = sConfig.GetIntDefault("Corpse.Decay.RARE", 300); + m_configs[CONFIG_CORPSE_DECAY_ELITE] = sConfig.GetIntDefault("Corpse.Decay.ELITE", 300); + m_configs[CONFIG_CORPSE_DECAY_RAREELITE] = sConfig.GetIntDefault("Corpse.Decay.RAREELITE", 300); + m_configs[CONFIG_CORPSE_DECAY_WORLDBOSS] = sConfig.GetIntDefault("Corpse.Decay.WORLDBOSS", 3600); + + m_configs[CONFIG_DEATH_SICKNESS_LEVEL] = sConfig.GetIntDefault("Death.SicknessLevel", 11); + m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvP", true); + m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvE", true); + + m_configs[CONFIG_THREAT_RADIUS] = sConfig.GetIntDefault("ThreatRadius", 100); + + // always use declined names in the russian client + m_configs[CONFIG_DECLINED_NAMES_USED] = + (m_configs[CONFIG_REALM_ZONE] == REALM_ZONE_RUSSIAN) ? true : sConfig.GetBoolDefault("DeclinedNames", false); + + m_configs[CONFIG_LISTEN_RANGE_SAY] = sConfig.GetIntDefault("ListenRange.Say", 25); + m_configs[CONFIG_LISTEN_RANGE_TEXTEMOTE] = sConfig.GetIntDefault("ListenRange.TextEmote", 25); + m_configs[CONFIG_LISTEN_RANGE_YELL] = sConfig.GetIntDefault("ListenRange.Yell", 300); + + m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1); + if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) + { + sLog.outError("Visibility.Distance.Grey.Unit can't be greater %f",MAX_VISIBILITY_DISTANCE); + m_VisibleUnitGreyDistance = MAX_VISIBILITY_DISTANCE; + } + m_VisibleObjectGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Object", 10); + if(m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE) + { + sLog.outError("Visibility.Distance.Grey.Object can't be greater %f",MAX_VISIBILITY_DISTANCE); + m_VisibleObjectGreyDistance = MAX_VISIBILITY_DISTANCE; + } + + m_MaxVisibleDistanceForCreature = sConfig.GetFloatDefault("Visibility.Distance.Creature", DEFAULT_VISIBILITY_DISTANCE); + if(m_MaxVisibleDistanceForCreature < 45*sWorld.getRate(RATE_CREATURE_AGGRO)) + { + sLog.outError("Visibility.Distance.Creature can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO)); + m_MaxVisibleDistanceForCreature = 45*sWorld.getRate(RATE_CREATURE_AGGRO); + } + else if(m_MaxVisibleDistanceForCreature + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) + { + sLog.outError("Visibility. Distance .Creature can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance); + m_MaxVisibleDistanceForCreature = MAX_VISIBILITY_DISTANCE-m_VisibleUnitGreyDistance; + } + m_MaxVisibleDistanceForPlayer = sConfig.GetFloatDefault("Visibility.Distance.Player", DEFAULT_VISIBILITY_DISTANCE); + if(m_MaxVisibleDistanceForPlayer < 45*sWorld.getRate(RATE_CREATURE_AGGRO)) + { + sLog.outError("Visibility.Distance.Player can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO)); + m_MaxVisibleDistanceForPlayer = 45*sWorld.getRate(RATE_CREATURE_AGGRO); + } + else if(m_MaxVisibleDistanceForPlayer + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) + { + sLog.outError("Visibility.Distance.Player can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance); + m_MaxVisibleDistanceForPlayer = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance; + } + m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Gameobject", DEFAULT_VISIBILITY_DISTANCE); + if(m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE) + { + sLog.outError("Visibility.Distance.Object can't be less max aggro radius %f",float(INTERACTION_DISTANCE)); + m_MaxVisibleDistanceForObject = INTERACTION_DISTANCE; + } + else if(m_MaxVisibleDistanceForObject + m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE) + { + sLog.outError("Visibility.Distance.Object can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance); + m_MaxVisibleDistanceForObject = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance; + } + m_MaxVisibleDistanceInFlight = sConfig.GetFloatDefault("Visibility.Distance.InFlight", DEFAULT_VISIBILITY_DISTANCE); + if(m_MaxVisibleDistanceInFlight + m_VisibleObjectGreyDistance > MAX_VISIBILITY_DISTANCE) + { + sLog.outError("Visibility.Distance.InFlight can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance); + m_MaxVisibleDistanceInFlight = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance; + } + + ///- Read the "Data" directory from the config file + std::string dataPath = sConfig.GetStringDefault("DataDir","./"); + if( dataPath.at(dataPath.length()-1)!='/' && dataPath.at(dataPath.length()-1)!='\\' ) + dataPath.append("/"); + + if(reload) + { + if(dataPath!=m_dataPath) + sLog.outError("DataDir option can't be changed at mangosd.conf reload, using current value (%s).",m_dataPath.c_str()); + } + else + { + m_dataPath = dataPath; + sLog.outString("Using DataDir %s",m_dataPath.c_str()); + } + + bool enableLOS = sConfig.GetBoolDefault("vmap.enableLOS", false); + bool enableHeight = sConfig.GetBoolDefault("vmap.enableHeight", false); + std::string ignoreMapIds = sConfig.GetStringDefault("vmap.ignoreMapIds", ""); + std::string ignoreSpellIds = sConfig.GetStringDefault("vmap.ignoreSpellIds", ""); + VMAP::VMapFactory::createOrGetVMapManager()->setEnableLineOfSightCalc(enableLOS); + VMAP::VMapFactory::createOrGetVMapManager()->setEnableHeightCalc(enableHeight); + VMAP::VMapFactory::createOrGetVMapManager()->preventMapsFromBeingUsed(ignoreMapIds.c_str()); + VMAP::VMapFactory::preventSpellsFromBeingTestedForLoS(ignoreSpellIds.c_str()); + sLog.outString( "WORLD: VMap support included. LineOfSight:%i, getHeight:%i",enableLOS, enableHeight); + sLog.outString( "WORLD: VMap data directory is: %svmaps",m_dataPath.c_str()); + sLog.outString( "WORLD: VMap config keys are: vmap.enableLOS, vmap.enableHeight, vmap.ignoreMapIds, vmap.ignoreSpellIds"); +} + +/// Initialize the World +void World::SetInitialWorldSettings() +{ + ///- Initialize the random number generator + srand((unsigned int)time(NULL)); + + ///- Initialize config settings + LoadConfigSettings(); + + ///- Init highest guids before any table loading to prevent using not initialized guids in some code. + objmgr.SetHighestGuids(); + + ///- Check the existence of the map files for all races' startup areas. + if( !MapManager::ExistMapAndVMap(0,-6240.32f, 331.033f) + ||!MapManager::ExistMapAndVMap(0,-8949.95f,-132.493f) + ||!MapManager::ExistMapAndVMap(0,-8949.95f,-132.493f) + ||!MapManager::ExistMapAndVMap(1,-618.518f,-4251.67f) + ||!MapManager::ExistMapAndVMap(0, 1676.35f, 1677.45f) + ||!MapManager::ExistMapAndVMap(1, 10311.3f, 832.463f) + ||!MapManager::ExistMapAndVMap(1,-2917.58f,-257.98f) + ||m_configs[CONFIG_EXPANSION] && ( + !MapManager::ExistMapAndVMap(530,10349.6f,-6357.29f) || !MapManager::ExistMapAndVMap(530,-3961.64f,-13931.2f) ) ) + { + sLog.outError("Correct *.map files not found in path '%smaps' or *.vmap/*vmdir files in '%svmaps'. Please place *.map/*.vmap/*.vmdir files in appropriate directories or correct the DataDir value in the mangosd.conf file.",m_dataPath.c_str(),m_dataPath.c_str()); + exit(1); + } + + ///- Loading strings. Getting no records means core load has to be canceled because no error message can be output. + sLog.outString( "" ); + sLog.outString( "Loading MaNGOS strings..." ); + if (!objmgr.LoadMangosStrings()) + exit(1); // Error message displayed in function already + + ///- Update the realm entry in the database with the realm type from the config file + //No SQL injection as values are treated as integers + + // not send custom type REALM_FFA_PVP to realm list + uint32 server_type = IsFFAPvPRealm() ? REALM_TYPE_PVP : getConfig(CONFIG_GAME_TYPE); + uint32 realm_zone = getConfig(CONFIG_REALM_ZONE); + loginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); + + ///- Remove the bones after a restart + CharacterDatabase.PExecute("DELETE FROM corpse WHERE corpse_type = '0'"); + + ///- Load the DBC files + sLog.outString("Initialize data stores..."); + LoadDBCStores(m_dataPath); + DetectDBCLang(); + + sLog.outString( "Loading InstanceTemplate" ); + objmgr.LoadInstanceTemplate(); + + sLog.outString( "Loading SkillLineAbilityMultiMap Data..." ); + spellmgr.LoadSkillLineAbilityMap(); + + ///- Clean up and pack instances + sLog.outString( "Cleaning up instances..." ); + sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables + + sLog.outString( "Packing instances..." ); + sInstanceSaveManager.PackInstances(); + + sLog.outString( "Loading Localization strings..." ); + objmgr.LoadCreatureLocales(); + objmgr.LoadGameObjectLocales(); + objmgr.LoadItemLocales(); + objmgr.LoadQuestLocales(); + objmgr.LoadNpcTextLocales(); + objmgr.LoadPageTextLocales(); + objmgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) + + sLog.outString( "Loading Page Texts..." ); + objmgr.LoadPageTexts(); + + sLog.outString( "Loading Game Object Templates..." ); // must be after LoadPageTexts + objmgr.LoadGameobjectInfo(); + + sLog.outString( "Loading Spell Chain Data..." ); + spellmgr.LoadSpellChains(); + + sLog.outString( "Loading Spell Elixir types..." ); + spellmgr.LoadSpellElixirs(); + + sLog.outString( "Loading Spell Learn Skills..." ); + spellmgr.LoadSpellLearnSkills(); // must be after LoadSpellChains + + sLog.outString( "Loading Spell Learn Spells..." ); + spellmgr.LoadSpellLearnSpells(); + + sLog.outString( "Loading Spell Proc Event conditions..." ); + spellmgr.LoadSpellProcEvents(); + + sLog.outString( "Loading Aggro Spells Definitions..."); + spellmgr.LoadSpellThreats(); + + sLog.outString( "Loading NPC Texts..." ); + objmgr.LoadGossipText(); + + sLog.outString( "Loading Item Random Enchantments Table..." ); + LoadRandomEnchantmentsTable(); + + sLog.outString( "Loading Items..." ); // must be after LoadRandomEnchantmentsTable and LoadPageTexts + objmgr.LoadItemPrototypes(); + + sLog.outString( "Loading Item Texts..." ); + objmgr.LoadItemTexts(); + + sLog.outString( "Loading Creature Model Based Info Data..." ); + objmgr.LoadCreatureModelInfo(); + + sLog.outString( "Loading Equipment templates..."); + objmgr.LoadEquipmentTemplates(); + + sLog.outString( "Loading Creature templates..." ); + objmgr.LoadCreatureTemplates(); + + sLog.outString( "Loading SpellsScriptTarget..."); + spellmgr.LoadSpellScriptTarget(); // must be after LoadCreatureTemplates and LoadGameobjectInfo + + sLog.outString( "Loading Creature Reputation OnKill Data..." ); + objmgr.LoadReputationOnKill(); + + sLog.outString( "Loading Pet Create Spells..." ); + objmgr.LoadPetCreateSpells(); + + sLog.outString( "Loading Creature Data..." ); + objmgr.LoadCreatures(); + + sLog.outString( "Loading Creature Addon Data..." ); + objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures() + + sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances() + objmgr.LoadCreatureRespawnTimes(); + + sLog.outString( "Loading Gameobject Data..." ); + objmgr.LoadGameobjects(); + + sLog.outString( "Loading Gameobject Respawn Data..." ); // must be after PackInstances() + objmgr.LoadGameobjectRespawnTimes(); + + sLog.outString( "Loading Game Event Data..."); + gameeventmgr.LoadFromDB(); + + sLog.outString( "Loading Weather Data..." ); + objmgr.LoadWeatherZoneChances(); + + sLog.outString( "Loading Quests..." ); + objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables + + sLog.outString( "Loading Quests Relations..." ); + objmgr.LoadQuestRelations(); // must be after quest load + + sLog.outString( "Loading AreaTrigger definitions..." ); + objmgr.LoadAreaTriggerTeleports(); // must be after item template load + + sLog.outString( "Loading Quest Area Triggers..." ); + objmgr.LoadQuestAreaTriggers(); // must be after LoadQuests + + sLog.outString( "Loading Tavern Area Triggers..." ); + objmgr.LoadTavernAreaTriggers(); + + sLog.outString( "Loading AreaTrigger script names..." ); + objmgr.LoadAreaTriggerScripts(); + + sLog.outString( "Loading Graveyard-zone links..."); + objmgr.LoadGraveyardZones(); + + sLog.outString( "Loading Spell target coordinates..." ); + spellmgr.LoadSpellTargetPositions(); + + sLog.outString( "Loading SpellAffect definitions..." ); + spellmgr.LoadSpellAffects(); + + sLog.outString( "Loading spell pet auras..." ); + spellmgr.LoadSpellPetAuras(); + + sLog.outString( "Loading player Create Info & Level Stats..." ); + objmgr.LoadPlayerInfo(); + + sLog.outString( "Loading Exploration BaseXP Data..." ); + objmgr.LoadExplorationBaseXP(); + + sLog.outString( "Loading Pet Name Parts..." ); + objmgr.LoadPetNames(); + + sLog.outString( "Loading the max pet number..." ); + objmgr.LoadPetNumber(); + + sLog.outString( "Loading pet level stats..." ); + objmgr.LoadPetLevelInfo(); + + sLog.outString( "Loading Player Corpses..." ); + objmgr.LoadCorpses(); + + sLog.outString( "Loading Loot Tables..." ); + LoadLootTables(); + + sLog.outString( "Loading Skill Discovery Table..." ); + LoadSkillDiscoveryTable(); + + sLog.outString( "Loading Skill Extra Item Table..." ); + LoadSkillExtraItemTable(); + + sLog.outString( "Loading Skill Fishing base level requirements..." ); + objmgr.LoadFishingBaseSkillLevel(); + + ///- Load dynamic data tables from the database + sLog.outString( "Loading Auctions..." ); + objmgr.LoadAuctionItems(); + objmgr.LoadAuctions(); + + sLog.outString( "Loading Guilds..." ); + objmgr.LoadGuilds(); + + sLog.outString( "Loading ArenaTeams..." ); + objmgr.LoadArenaTeams(); + + sLog.outString( "Loading Groups..." ); + objmgr.LoadGroups(); + + sLog.outString( "Loading ReservedNames..." ); + objmgr.LoadReservedPlayersNames(); + + sLog.outString( "Loading GameObject for quests..." ); + objmgr.LoadGameObjectForQuests(); + + sLog.outString( "Loading BattleMasters..." ); + objmgr.LoadBattleMastersEntry(); + + sLog.outString( "Loading GameTeleports..." ); + objmgr.LoadGameTele(); + + sLog.outString( "Loading Npc Text Id..." ); + objmgr.LoadNpcTextId(); // must be after load Creature and NpcText + + sLog.outString( "Loading vendors..." ); + objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate + + sLog.outString( "Loading trainers..." ); + objmgr.LoadTrainerSpell(); // must be after load CreatureTemplate + + sLog.outString( "Loading Waypoints..." ); + WaypointMgr.Load(); + + ///- Handle outdated emails (delete/return) + sLog.outString( "Returning old mails..." ); + objmgr.ReturnOrDeleteOldMails(false); + + ///- Load and initialize scripts + sLog.outString( "Loading Scripts..." ); + objmgr.LoadQuestStartScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate + objmgr.LoadQuestEndScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate + objmgr.LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data) + objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data) + objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data) + + sLog.outString( "Initializing Scripts..." ); + if(!LoadScriptingModule()) + exit(1); + + ///- Initialize game time and timers + sLog.outString( "DEBUG:: Initialize game time and timers" ); + m_gameTime = time(NULL); + m_startTime=m_gameTime; + + tm local; + time_t curr; + time(&curr); + local=*(localtime(&curr)); // dereference and assign + char isoDate[128]; + sprintf( isoDate, "%04d-%02d-%02d %02d:%02d:%02d", + local.tm_year+1900, local.tm_mon+1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); + + WorldDatabase.PExecute("INSERT INTO uptime (startstring, starttime, uptime) VALUES('%s', %ld, 0)", isoDate, m_startTime ); + + m_timers[WUPDATE_OBJECTS].SetInterval(0); + m_timers[WUPDATE_SESSIONS].SetInterval(0); + m_timers[WUPDATE_WEATHERS].SetInterval(1000); + m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*1000); //set auction update interval to 1 minute + m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*1000); + //Update "uptime" table based on configuration entry in minutes. + m_timers[WUPDATE_CORPSES].SetInterval(20*MINUTE*1000); //erase corpses every 20 minutes + + //to set mailtimer to return mails every day between 4 and 5 am + //mailtimer is increased when updating auctions + //one second is 1000 -(tested on win system) + mail_timer = ((((localtime( &m_gameTime )->tm_hour + 20) % 24)* HOUR * 1000) / m_timers[WUPDATE_AUCTIONS].GetInterval() ); + //1440 + mail_timer_expires = ( (DAY * 1000) / (m_timers[WUPDATE_AUCTIONS].GetInterval())); + sLog.outDebug("Mail timer set to: %u, mail return is called every %u minutes", mail_timer, mail_timer_expires); + + ///- Initilize static helper structures + AIRegistry::Initialize(); + WaypointMovementGenerator::Initialize(); + Player::InitVisibleBits(); + + ///- Initialize MapManager + sLog.outString( "Starting Map System" ); + MapManager::Instance().Initialize(); + + ///- Initialize Battlegrounds + sLog.outString( "Starting BattleGround System" ); + sBattleGroundMgr.CreateInitialBattleGrounds(); + + //Not sure if this can be moved up in the sequence (with static data loading) as it uses MapManager + sLog.outString( "Loading Transports..." ); + MapManager::Instance().LoadTransports(); + + sLog.outString("Deleting expired bans..." ); + loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + sLog.outString("Calculate next daily quest reset time..." ); + InitDailyQuestResetTime(); + + sLog.outString("Starting Game Event system..." ); + uint32 nextGameEvent = gameeventmgr.Initialize(); + m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event + + sLog.outString( "WORLD: World initialized" ); +} + +void World::DetectDBCLang() +{ + uint32 m_lang_confid = sConfig.GetIntDefault("DBC.Locale", 255); + + if(m_lang_confid != 255 && m_lang_confid >= MAX_LOCALE) + { + sLog.outError("Incorrect DBC.Locale! Must be >= 0 and < %d (set to 0)",MAX_LOCALE); + m_lang_confid = LOCALE_enUS; + } + + ChrRacesEntry const* race = sChrRacesStore.LookupEntry(1); + + std::string availableLocalsStr; + + int default_locale = MAX_LOCALE; + for (int i = MAX_LOCALE-1; i >= 0; --i) + { + if ( strlen(race->name[i]) > 0) // check by race names + { + default_locale = i; + m_availableDbcLocaleMask |= (1 << i); + availableLocalsStr += localeNames[i]; + availableLocalsStr += " "; + } + } + + if( default_locale != m_lang_confid && m_lang_confid < MAX_LOCALE && + (m_availableDbcLocaleMask & (1 << m_lang_confid)) ) + { + default_locale = m_lang_confid; + } + + if(default_locale >= MAX_LOCALE) + { + sLog.outError("Unable to determine your DBC Locale! (corrupt DBC?)"); + exit(1); + } + + m_defaultDbcLocale = LocaleConstant(default_locale); + + sLog.outString("Using %s DBC Locale as default. All available DBC locales: %s",localeNames[m_defaultDbcLocale],availableLocalsStr.empty() ? "" : availableLocalsStr.c_str()); +} + +/// Update the World ! +void World::Update(time_t diff) +{ + ///- Update the different timers + for(int i = 0; i < WUPDATE_COUNT; i++) + if(m_timers[i].GetCurrent()>=0) + m_timers[i].Update(diff); + else m_timers[i].SetCurrent(0); + + ///- Update the game time and check for shutdown time + _UpdateGameTime(); + + /// Handle daily quests reset time + if(m_gameTime > m_NextDailyQuestReset) + { + ResetDailyQuests(); + m_NextDailyQuestReset += DAY; + } + + ///
  • Handle auctions when the timer has passed + if (m_timers[WUPDATE_AUCTIONS].Passed()) + { + m_timers[WUPDATE_AUCTIONS].Reset(); + + ///- Update mails (return old mails with item, or delete them) + //(tested... works on win) + if (++mail_timer > mail_timer_expires) + { + mail_timer = 0; + objmgr.ReturnOrDeleteOldMails(true); + } + + AuctionHouseObject* AuctionMap; + for (int i = 0; i < 3; i++) + { + switch (i) + { + case 0: + AuctionMap = objmgr.GetAuctionsMap( 6 );//horde + break; + case 1: + AuctionMap = objmgr.GetAuctionsMap( 2 );//alliance + break; + case 2: + AuctionMap = objmgr.GetAuctionsMap( 7 );//neutral + break; + } + + ///- Handle expired auctions + AuctionHouseObject::AuctionEntryMap::iterator itr,next; + for (itr = AuctionMap->GetAuctionsBegin(); itr != AuctionMap->GetAuctionsEnd();itr = next) + { + next = itr; + ++next; + if (m_gameTime > (itr->second->time)) + { + ///- Either cancel the auction if there was no bidder + if (itr->second->bidder == 0) + { + objmgr.SendAuctionExpiredMail( itr->second ); + } + ///- Or perform the transaction + else + { + //we should send an "item sold" message if the seller is online + //we send the item to the winner + //we send the money to the seller + objmgr.SendAuctionSuccessfulMail( itr->second ); + objmgr.SendAuctionWonMail( itr->second ); + } + + ///- In any case clear the auction + //No SQL injection (Id is integer) + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",itr->second->Id); + objmgr.RemoveAItem(itr->second->item_guidlow); + delete itr->second; + AuctionMap->RemoveAuction(itr->first); + } + } + } + } + + ///
  • Handle session updates when the timer has passed + if (m_timers[WUPDATE_SESSIONS].Passed()) + { + m_timers[WUPDATE_SESSIONS].Reset(); + + UpdateSessions(diff); + } + + ///
  • Handle weather updates when the timer has passed + if (m_timers[WUPDATE_WEATHERS].Passed()) + { + m_timers[WUPDATE_WEATHERS].Reset(); + + ///- Send an update signal to Weather objects + WeatherMap::iterator itr, next; + for (itr = m_weathers.begin(); itr != m_weathers.end(); itr = next) + { + next = itr; + ++next; + + ///- and remove Weather objects for zones with no player + //As interval > WorldTick + if(!itr->second->Update(m_timers[WUPDATE_WEATHERS].GetInterval())) + { + delete itr->second; + m_weathers.erase(itr); + } + } + } + ///
  • Update uptime table + if (m_timers[WUPDATE_UPTIME].Passed()) + { + uint32 tmpDiff = (m_gameTime - m_startTime); + uint32 maxClientsNum = sWorld.GetMaxActiveSessionCount(); + + m_timers[WUPDATE_UPTIME].Reset(); + WorldDatabase.PExecute("UPDATE uptime SET uptime = %d, maxplayers = %d WHERE starttime = " I64FMTD, tmpDiff, maxClientsNum, uint64(m_startTime)); + } + + ///
  • Handle all other objects + if (m_timers[WUPDATE_OBJECTS].Passed()) + { + m_timers[WUPDATE_OBJECTS].Reset(); + ///- Update objects when the timer has passed (maps, transport, creatures,...) + MapManager::Instance().Update(diff); // As interval = 0 + + ///- Process necessary scripts + if (!m_scriptSchedule.empty()) + ScriptsProcess(); + + sBattleGroundMgr.Update(diff); + } + + // execute callbacks from sql queries that were queued recently + UpdateResultQueue(); + + ///- Erase corpses once every 20 minutes + if (m_timers[WUPDATE_CORPSES].Passed()) + { + m_timers[WUPDATE_CORPSES].Reset(); + + CorpsesErase(); + } + + ///- Process Game events when necessary + if (m_timers[WUPDATE_EVENTS].Passed()) + { + m_timers[WUPDATE_EVENTS].Reset(); // to give time for Update() to be processed + uint32 nextGameEvent = gameeventmgr.Update(); + m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); + m_timers[WUPDATE_EVENTS].Reset(); + } + + ///
+ ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove" + MapManager::Instance().DoDelayedMovesAndRemoves(); + + // update the instance reset times + sInstanceSaveManager.Update(); + + // And last, but not least handle the issued cli commands + ProcessCliCommands(); +} + +/// Put scripts in the execution queue +void World::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target) +{ + ///- Find the script map + ScriptMapMap::const_iterator s = scripts.find(id); + if (s == scripts.end()) + return; + + // prepare static data + uint64 sourceGUID = source->GetGUID(); + uint64 targetGUID = target ? target->GetGUID() : (uint64)0; + uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0; + + ///- Schedule script execution for all scripts in the script map + ScriptMap const *s2 = &(s->second); + bool immedScript = false; + for (ScriptMap::const_iterator iter = s2->begin(); iter != s2->end(); ++iter) + { + ScriptAction sa; + sa.sourceGUID = sourceGUID; + sa.targetGUID = targetGUID; + sa.ownerGUID = ownerGUID; + + sa.script = &iter->second; + m_scriptSchedule.insert(std::pair(m_gameTime + iter->first, sa)); + if (iter->first == 0) + immedScript = true; + } + ///- If one of the effects should be immediate, launch the script execution + if (immedScript) + ScriptsProcess(); +} + +void World::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target) +{ + // NOTE: script record _must_ exist until command executed + + // prepare static data + uint64 sourceGUID = source->GetGUID(); + uint64 targetGUID = target ? target->GetGUID() : (uint64)0; + uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0; + + ScriptAction sa; + sa.sourceGUID = sourceGUID; + sa.targetGUID = targetGUID; + sa.ownerGUID = ownerGUID; + + sa.script = &script; + m_scriptSchedule.insert(std::pair(m_gameTime + delay, sa)); + + ///- If effects should be immediate, launch the script execution + if(delay == 0) + ScriptsProcess(); +} + +/// Process queued scripts +void World::ScriptsProcess() +{ + if (m_scriptSchedule.empty()) + return; + + ///- Process overdue queued scripts + std::multimap::iterator iter = m_scriptSchedule.begin(); + // ok as multimap is a *sorted* associative container + while (!m_scriptSchedule.empty() && (iter->first <= m_gameTime)) + { + ScriptAction const& step = iter->second; + + Object* source = NULL; + + if(step.sourceGUID) + { + switch(GUID_HIPART(step.sourceGUID)) + { + case HIGHGUID_ITEM: + // case HIGHGUID_CONTAINER: ==HIGHGUID_ITEM + { + Player* player = HashMapHolder::Find(step.ownerGUID); + if(player) + source = player->GetItemByGuid(step.sourceGUID); + break; + } + case HIGHGUID_UNIT: + source = HashMapHolder::Find(step.sourceGUID); + break; + case HIGHGUID_PET: + source = HashMapHolder::Find(step.sourceGUID); + break; + case HIGHGUID_PLAYER: + source = HashMapHolder::Find(step.sourceGUID); + break; + case HIGHGUID_GAMEOBJECT: + source = HashMapHolder::Find(step.sourceGUID); + break; + case HIGHGUID_CORPSE: + source = HashMapHolder::Find(step.sourceGUID); + break; + default: + sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.sourceGUID)); + break; + } + } + + Object* target = NULL; + + if(step.targetGUID) + { + switch(GUID_HIPART(step.targetGUID)) + { + case HIGHGUID_UNIT: + target = HashMapHolder::Find(step.targetGUID); + break; + case HIGHGUID_PET: + target = HashMapHolder::Find(step.targetGUID); + break; + case HIGHGUID_PLAYER: // empty GUID case also + target = HashMapHolder::Find(step.targetGUID); + break; + case HIGHGUID_GAMEOBJECT: + target = HashMapHolder::Find(step.targetGUID); + break; + case HIGHGUID_CORPSE: + target = HashMapHolder::Find(step.targetGUID); + break; + default: + sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.targetGUID)); + break; + } + } + + switch (step.script->command) + { + case SCRIPT_COMMAND_TALK: + { + if(!source) + { + sLog.outError("SCRIPT_COMMAND_TALK call for NULL creature."); + break; + } + + if(source->GetTypeId()!=TYPEID_UNIT) + { + sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + if(step.script->datalong > 3) + { + sLog.outError("SCRIPT_COMMAND_TALK invalid chat type (%u), skipping.",step.script->datalong); + break; + } + + uint64 unit_target = target ? target->GetGUID() : 0; + + //datalong 0=normal say, 1=whisper, 2=yell, 3=emote text + switch(step.script->datalong) + { + case 0: // Say + ((Creature *)source)->Say(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target); + break; + case 1: // Whisper + if(!unit_target) + { + sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong); + break; + } + ((Creature *)source)->Whisper(step.script->datatext.c_str(),unit_target); + break; + case 2: // Yell + ((Creature *)source)->Yell(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target); + break; + case 3: // Emote text + ((Creature *)source)->TextEmote(step.script->datatext.c_str(), unit_target); + break; + default: + break; // must be already checked at load + } + break; + } + + case SCRIPT_COMMAND_EMOTE: + if(!source) + { + sLog.outError("SCRIPT_COMMAND_EMOTE call for NULL creature."); + break; + } + + if(source->GetTypeId()!=TYPEID_UNIT) + { + sLog.outError("SCRIPT_COMMAND_EMOTE call for non-creature (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + ((Creature *)source)->HandleEmoteCommand(step.script->datalong); + break; + case SCRIPT_COMMAND_FIELD_SET: + if(!source) + { + sLog.outError("SCRIPT_COMMAND_FIELD_SET call for NULL object."); + break; + } + if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount()) + { + sLog.outError("SCRIPT_COMMAND_FIELD_SET call for wrong field %u (max count: %u) in object (TypeId: %u).", + step.script->datalong,source->GetValuesCount(),source->GetTypeId()); + break; + } + + source->SetUInt32Value(step.script->datalong, step.script->datalong2); + break; + case SCRIPT_COMMAND_MOVE_TO: + if(!source) + { + sLog.outError("SCRIPT_COMMAND_MOVE_TO call for NULL creature."); + break; + } + + if(source->GetTypeId()!=TYPEID_UNIT) + { + sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + ((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, ((Unit *)source)->GetUnitMovementFlags(), step.script->datalong2 ); + MapManager::Instance().GetMap(((Unit *)source)->GetMapId(), ((Unit *)source))->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0); + break; + case SCRIPT_COMMAND_FLAG_SET: + if(!source) + { + sLog.outError("SCRIPT_COMMAND_FLAG_SET call for NULL object."); + break; + } + if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount()) + { + sLog.outError("SCRIPT_COMMAND_FLAG_SET call for wrong field %u (max count: %u) in object (TypeId: %u).", + step.script->datalong,source->GetValuesCount(),source->GetTypeId()); + break; + } + + source->SetFlag(step.script->datalong, step.script->datalong2); + break; + case SCRIPT_COMMAND_FLAG_REMOVE: + if(!source) + { + sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for NULL object."); + break; + } + if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount()) + { + sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for wrong field %u (max count: %u) in object (TypeId: %u).", + step.script->datalong,source->GetValuesCount(),source->GetTypeId()); + break; + } + + source->RemoveFlag(step.script->datalong, step.script->datalong2); + break; + + case SCRIPT_COMMAND_TELEPORT_TO: + { + // accept player in any one from target/source arg + if (!target && !source) + { + sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for NULL object."); + break; + } + + // must be only Player + if((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER)) + { + sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0); + break; + } + + Player* pSource = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source; + + pSource->TeleportTo(step.script->datalong, step.script->x, step.script->y, step.script->z, step.script->o); + break; + } + + case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: + { + if(!step.script->datalong) // creature not specified + { + sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL creature."); + break; + } + + if(!source) + { + sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL world object."); + break; + } + + WorldObject* summoner = dynamic_cast(source); + + if(!summoner) + { + sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + float x = step.script->x; + float y = step.script->y; + float z = step.script->z; + float o = step.script->o; + + Creature* pCreature = summoner->SummonCreature(step.script->datalong, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,step.script->datalong2); + if (!pCreature) + { + sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON failed for creature (entry: %u).",step.script->datalong); + break; + } + + break; + } + + case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT: + { + if(!step.script->datalong) // gameobject not specified + { + sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL gameobject."); + break; + } + + if(!source) + { + sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL world object."); + break; + } + + WorldObject* summoner = dynamic_cast(source); + + if(!summoner) + { + sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + GameObject *go = NULL; + int32 time_to_despawn = step.script->datalong2<5 ? 5 : (int32)step.script->datalong2; + + CellPair p(MaNGOS::ComputeCellPair(summoner->GetPositionX(), summoner->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong); + MaNGOS::GameObjectSearcher checker(go,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(summoner->GetMapId(), summoner)); + + if ( !go ) + { + sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT failed for gameobject(guid: %u).", step.script->datalong); + break; + } + + if( go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE || + go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE || + go->GetGoType()==GAMEOBJECT_TYPE_DOOR || + go->GetGoType()==GAMEOBJECT_TYPE_BUTTON || + go->GetGoType()==GAMEOBJECT_TYPE_TRAP ) + { + sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT can not be used with gameobject of type %u (guid: %u).", uint32(go->GetGoType()), step.script->datalong); + break; + } + + if( go->isSpawned() ) + break; //gameobject already spawned + + go->SetLootState(GO_READY); + go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds + + MapManager::Instance().GetMap(go->GetMapId(), go)->Add(go); + break; + } + case SCRIPT_COMMAND_OPEN_DOOR: + { + if(!step.script->datalong) // door not specified + { + sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL door."); + break; + } + + if(!source) + { + sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL unit."); + break; + } + + if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player) + { + sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + Unit* caster = (Unit*)source; + + GameObject *door = NULL; + int32 time_to_close = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2; + + CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong); + MaNGOS::GameObjectSearcher checker(door,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(caster->GetMapId(), (Unit*)source)); + + if ( !door ) + { + sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for gameobject(guid: %u).", step.script->datalong); + break; + } + if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR ) + { + sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for non-door(GoType: %u).", door->GetGoType()); + break; + } + + if( !door->GetGoState() ) + break; //door already open + + door->UseDoorOrButton(time_to_close); + + if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON) + ((GameObject*)target)->UseDoorOrButton(time_to_close); + break; + } + case SCRIPT_COMMAND_CLOSE_DOOR: + { + if(!step.script->datalong) // guid for door not specified + { + sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL door."); + break; + } + + if(!source) + { + sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL unit."); + break; + } + + if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player) + { + sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + Unit* caster = (Unit*)source; + + GameObject *door = NULL; + int32 time_to_open = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2; + + CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + + MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong); + MaNGOS::GameObjectSearcher checker(door,go_check); + + TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(caster->GetMapId(), (Unit*)source)); + + if ( !door ) + { + sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for gameobject(guid: %u).", step.script->datalong); + break; + } + if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR ) + { + sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for non-door(GoType: %u).", door->GetGoType()); + break; + } + + if( door->GetGoState() ) + break; //door already closed + + door->UseDoorOrButton(time_to_open); + + if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON) + ((GameObject*)target)->UseDoorOrButton(time_to_open); + + break; + } + case SCRIPT_COMMAND_QUEST_EXPLORED: + { + if(!source) + { + sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL source."); + break; + } + + if(!target) + { + sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL target."); + break; + } + + // when script called for item spell casting then target == (unit or GO) and source is player + WorldObject* worldObject; + Player* player; + + if(target->GetTypeId()==TYPEID_PLAYER) + { + if(source->GetTypeId()!=TYPEID_UNIT && source->GetTypeId()!=TYPEID_GAMEOBJECT) + { + sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + worldObject = (WorldObject*)source; + player = (Player*)target; + } + else + { + if(target->GetTypeId()!=TYPEID_UNIT && target->GetTypeId()!=TYPEID_GAMEOBJECT) + { + sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",target->GetTypeId()); + break; + } + + if(source->GetTypeId()!=TYPEID_PLAYER) + { + sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-player(TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + worldObject = (WorldObject*)target; + player = (Player*)source; + } + + // quest id and flags checked at script loading + if( (worldObject->GetTypeId()!=TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) && + (step.script->datalong2==0 || worldObject->IsWithinDistInMap(player,float(step.script->datalong2))) ) + player->AreaExploredOrEventHappens(step.script->datalong); + else + player->FailQuest(step.script->datalong); + + break; + } + + case SCRIPT_COMMAND_ACTIVATE_OBJECT: + { + if(!source) + { + sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT must have source caster."); + break; + } + + if(!source->isType(TYPEMASK_UNIT)) + { + sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT source caster isn't unit (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + if(!target) + { + sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for NULL gameobject."); + break; + } + + if(target->GetTypeId()!=TYPEID_GAMEOBJECT) + { + sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for non-gameobject (TypeId: %u), skipping.",target->GetTypeId()); + break; + } + + Unit* caster = (Unit*)source; + + GameObject *go = (GameObject*)target; + + go->Use(caster); + break; + } + + case SCRIPT_COMMAND_REMOVE_AURA: + { + Object* cmdTarget = step.script->datalong2 ? source : target; + + if(!cmdTarget) + { + sLog.outError("SCRIPT_COMMAND_REMOVE_AURA call for NULL %s.",step.script->datalong2 ? "source" : "target"); + break; + } + + if(!cmdTarget->isType(TYPEMASK_UNIT)) + { + sLog.outError("SCRIPT_COMMAND_REMOVE_AURA %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId()); + break; + } + + ((Unit*)cmdTarget)->RemoveAurasDueToSpell(step.script->datalong); + break; + } + + case SCRIPT_COMMAND_CAST_SPELL: + { + if(!source) + { + sLog.outError("SCRIPT_COMMAND_CAST_SPELL must have source caster."); + break; + } + + if(!source->isType(TYPEMASK_UNIT)) + { + sLog.outError("SCRIPT_COMMAND_CAST_SPELL source caster isn't unit (TypeId: %u), skipping.",source->GetTypeId()); + break; + } + + Object* cmdTarget = step.script->datalong2 ? source : target; + + if(!cmdTarget) + { + sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 ? "source" : "target"); + break; + } + + if(!cmdTarget->isType(TYPEMASK_UNIT)) + { + sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId()); + break; + } + + Unit* spellTarget = (Unit*)cmdTarget; + + //TODO: when GO cast implemented, code below must be updated accordingly to also allow GO spell cast + ((Unit*)source)->CastSpell(spellTarget,step.script->datalong,false); + + break; + } + + default: + sLog.outError("Unknown script command %u called.",step.script->command); + break; + } + + m_scriptSchedule.erase(iter); + + iter = m_scriptSchedule.begin(); + } + return; +} + +/// Send a packet to all players (except self if mentioned) +void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team) +{ + SessionMap::iterator itr; + for (itr = m_sessions.begin(); itr != m_sessions.end(); itr++) + { + if (itr->second && + itr->second->GetPlayer() && + itr->second->GetPlayer()->IsInWorld() && + itr->second != self && + (team == 0 || itr->second->GetPlayer()->GetTeam() == team) ) + { + itr->second->SendPacket(packet); + } + } +} + +/// Send a System Message to all players (except self if mentioned) +void World::SendWorldText(int32 string_id, ...) +{ + std::vector > data_cache; // 0 = default, i => i-1 locale index + + for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + { + if(!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld() ) + continue; + + uint32 loc_idx = itr->second->GetSessionDbLocaleIndex(); + uint32 cache_idx = loc_idx+1; + + std::vector* data_list; + + // create if not cached yet + if(data_cache.size() < cache_idx+1 || data_cache[cache_idx].empty()) + { + if(data_cache.size() < cache_idx+1) + data_cache.resize(cache_idx+1); + + data_list = &data_cache[cache_idx]; + + char const* text = objmgr.GetMangosString(string_id,loc_idx); + + char buf[1000]; + + va_list argptr; + va_start( argptr, string_id ); + vsnprintf( buf,1000, text, argptr ); + va_end( argptr ); + + char* pos = &buf[0]; + + while(char* line = ChatHandler::LineFromMessage(pos)) + { + WorldPacket* data = new WorldPacket(); + ChatHandler::FillMessageData(data, NULL, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, 0, line, NULL); + data_list->push_back(data); + } + } + else + data_list = &data_cache[cache_idx]; + + for(int i = 0; i < data_list->size(); ++i) + itr->second->SendPacket((*data_list)[i]); + } + + // free memory + for(int i = 0; i < data_cache.size(); ++i) + for(int j = 0; j < data_cache[i].size(); ++j) + delete data_cache[i][j]; +} + +/// Send a packet to all players (or players selected team) in the zone (except self if mentioned) +void World::SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self, uint32 team) +{ + SessionMap::iterator itr; + for (itr = m_sessions.begin(); itr != m_sessions.end(); itr++) + { + if (itr->second && + itr->second->GetPlayer() && + itr->second->GetPlayer()->IsInWorld() && + itr->second->GetPlayer()->GetZoneId() == zone && + itr->second != self && + (team == 0 || itr->second->GetPlayer()->GetTeam() == team) ) + { + itr->second->SendPacket(packet); + } + } +} + +/// Send a System Message to all players in the zone (except self if mentioned) +void World::SendZoneText(uint32 zone, const char* text, WorldSession *self, uint32 team) +{ + WorldPacket data; + ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, 0, text, NULL); + SendZoneMessage(zone, &data, self,team); +} + +/// Kick (and save) all players +void World::KickAll() +{ + // session not removed at kick and will removed in next update tick + for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + itr->second->KickPlayer(); +} + +/// Kick (and save) all players with security level less `sec` +void World::KickAllLess(AccountTypes sec) +{ + // session not removed at kick and will removed in next update tick + for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + if(itr->second->GetSecurity() < sec) + itr->second->KickPlayer(); +} + +/// Kick all queued players +void World::KickAllQueued() +{ + // session not removed at kick and will removed in next update tick + //TODO here +// for (Queue::iterator itr = m_QueuedPlayer.begin(); itr != m_QueuedPlayer.end(); ++itr) +// if(WorldSession* session = (*itr)->GetSession()) +// session->KickPlayer(); + + m_QueuedPlayer.empty(); +} + +/// Kick (and save) the designated player +bool World::KickPlayer(std::string playerName) +{ + SessionMap::iterator itr; + + // session not removed at kick and will removed in next update tick + for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + { + if(!itr->second) + continue; + Player *player = itr->second->GetPlayer(); + if(!player) + continue; + if( player->IsInWorld() ) + { + if (playerName == player->GetName()) + { + itr->second->KickPlayer(); + return true; + } + } + } + return false; +} + +/// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban +uint8 World::BanAccount(std::string type, std::string nameOrIP, std::string duration, std::string reason, std::string author) +{ + loginDatabase.escape_string(nameOrIP); + loginDatabase.escape_string(reason); + std::string safe_author=author; + loginDatabase.escape_string(safe_author); + + if(type != "ip" && !normalizePlayerName(nameOrIP)) + return BAN_NOTFOUND; // Nobody to ban + + uint32 duration_secs = TimeStringToSecs(duration); + QueryResult *resultAccounts = NULL; //used for kicking + + ///- Update the database with ban information + + if(type=="ip") + { + //No SQL injection as strings are escaped + resultAccounts = loginDatabase.PQuery("SELECT id FROM account WHERE last_ip = '%s'",nameOrIP.c_str()); + loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+%u,'%s','%s')",nameOrIP.c_str(),duration_secs,safe_author.c_str(),reason.c_str()); + } + else if(type=="account") + { + //No SQL injection as string is escaped + resultAccounts = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",nameOrIP.c_str()); + } + else if(type=="character") + { + //No SQL injection as string is escaped + resultAccounts = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'",nameOrIP.c_str()); + } + else + return BAN_SYNTAX_ERROR; //Syntax problem + + if(!resultAccounts) + if(type=="ip") + return BAN_SUCCESS; // ip correctly banned but nobody affected (yet) + else + return BAN_NOTFOUND; // Nobody to ban + + ///- Disconnect all affected players (for IP it can be several) + do + { + Field* fieldsAccount = resultAccounts->Fetch(); + uint32 account = fieldsAccount->GetUInt32(); + + if(type != "ip") + //No SQL injection as strings are escaped + loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+%u, '%s', '%s', '1')", + account,duration_secs,safe_author.c_str(),reason.c_str()); + + WorldSession* sess = FindSession(account); + if( sess ) + if(std::string(sess->GetPlayerName()) != author) + sess->KickPlayer(); + } + while( resultAccounts->NextRow() ); + + delete resultAccounts; + return BAN_SUCCESS; +} + +/// Remove a ban from an account or IP address +bool World::RemoveBanAccount(std::string type, std::string nameOrIP) +{ + if(type == "ip") + { + loginDatabase.escape_string(nameOrIP); + loginDatabase.PExecute("DELETE FROM ip_banned WHERE ip = '%s'",nameOrIP.c_str()); + } + else + { + uint32 account=0; + if(type == "account") + { + //NO SQL injection as name is escaped + loginDatabase.escape_string(nameOrIP); + QueryResult *resultAccounts = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",nameOrIP.c_str()); + if(!resultAccounts) + return false; + Field* fieldsAccount = resultAccounts->Fetch(); + account = fieldsAccount->GetUInt32(); + + delete resultAccounts; + } + else if(type == "character") + { + if(!normalizePlayerName(nameOrIP)) + return false; + + //NO SQL injection as name is escaped + loginDatabase.escape_string(nameOrIP); + QueryResult *resultAccounts = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'",nameOrIP.c_str()); + if(!resultAccounts) + return false; + Field* fieldsAccount = resultAccounts->Fetch(); + account = fieldsAccount->GetUInt32(); + + delete resultAccounts; + } + if(!account) + return false; + //NO SQL injection as account is uint32 + loginDatabase.PExecute("UPDATE account_banned SET active = '0' WHERE id = '%u'",account); + } + return true; +} + +/// Update the game time +void World::_UpdateGameTime() +{ + ///- update the time + time_t thisTime = time(NULL); + uint32 elapsed = uint32(thisTime - m_gameTime); + m_gameTime = thisTime; + + ///- if there is a shutdown timer + if(m_ShutdownTimer > 0 && elapsed > 0) + { + ///- ... and it is overdue, stop the world (set m_stopEvent) + if( m_ShutdownTimer <= elapsed ) + { + if(!(m_ShutdownMask & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount()==0) + m_stopEvent = true; + else + m_ShutdownTimer = 1; // minimum timer value to wait idle state + } + ///- ... else decrease it and if necessary display a shutdown countdown to the users + else + { + m_ShutdownTimer -= elapsed; + + ShutdownMsg(); + } + } +} + +/// Shutdown the server +void World::ShutdownServ(uint32 time, uint32 options) +{ + m_ShutdownMask = options; + + ///- If the shutdown time is 0, set m_stopEvent (except if shutdown is 'idle' with remaining sessions) + if(time==0) + { + if(!(options & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount()==0) + m_stopEvent = true; + else + m_ShutdownTimer = 1; //So that the session count is re-evaluated at next world tick + } + ///- Else set the shutdown timer and warn users + else + { + m_ShutdownTimer = time; + ShutdownMsg(true); + } +} + +/// Display a shutdown message to the user(s) +void World::ShutdownMsg(bool show, Player* player) +{ + // not show messages for idle shutdown mode + if(m_ShutdownMask & SHUTDOWN_MASK_IDLE) + return; + + ///- Display a message every 12 hours, hours, 5 minutes, minute, 5 seconds and finally seconds + if ( show || + (m_ShutdownTimer < 10) || + // < 30 sec; every 5 sec + (m_ShutdownTimer<30 && (m_ShutdownTimer % 5 )==0) || + // < 5 min ; every 1 min + (m_ShutdownTimer<5*MINUTE && (m_ShutdownTimer % MINUTE )==0) || + // < 30 min ; every 5 min + (m_ShutdownTimer<30*MINUTE && (m_ShutdownTimer % (5*MINUTE))==0) || + // < 12 h ; every 1 h + (m_ShutdownTimer<12*HOUR && (m_ShutdownTimer % HOUR )==0) || + // > 12 h ; every 12 h + (m_ShutdownTimer>12*HOUR && (m_ShutdownTimer % (12*HOUR) )==0)) + { + std::string str = secsToTimeString(m_ShutdownTimer); + + uint32 msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_TIME : SERVER_MSG_SHUTDOWN_TIME; + + SendServerMessage(msgid,str.c_str(),player); + DEBUG_LOG("Server is %s in %s",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown"),str.c_str()); + } +} + +/// Cancel a planned server shutdown +void World::ShutdownCancel() +{ + if(!m_ShutdownTimer) + return; + + uint32 msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED; + + m_ShutdownMask = 0; + m_ShutdownTimer = 0; + SendServerMessage(msgid); + + DEBUG_LOG("Server %s cancelled.",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown")); +} + +/// Send a server message to the user(s) +void World::SendServerMessage(uint32 type, const char *text, Player* player) +{ + WorldPacket data(SMSG_SERVER_MESSAGE, 50); // guess size + data << uint32(type); + if(type <= SERVER_MSG_STRING) + data << text; + + if(player) + player->GetSession()->SendPacket(&data); + else + SendGlobalMessage( &data ); +} + +void World::UpdateSessions( time_t diff ) +{ + while(!addSessQueue.empty()) + { + WorldSession* sess = addSessQueue.next (); + AddSession_ (sess); + } + + ///- Delete kicked sessions at add new session + for (std::set::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr) + delete *itr; + m_kicked_sessions.clear(); + + ///- Then send an update signal to remaining ones + for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next) + { + next = itr; + ++next; + + if(!itr->second) + continue; + + ///- and remove not active sessions from the list + if(!itr->second->Update(diff)) // As interval = 0 + { + delete itr->second; + m_sessions.erase(itr); + } + } +} + +// This handles the issued and queued CLI commands +void World::ProcessCliCommands() +{ + if (cliCmdQueue.empty()) return; + + CliCommandHolder *command; + pPrintf p_zprintf; + while (!cliCmdQueue.empty()) + { + sLog.outDebug("CLI command under processing..."); + command = cliCmdQueue.next(); + command->Execute(); + p_zprintf=command->GetOutputMethod(); + delete command; + } + // print the console message here so it looks right + p_zprintf("mangos>"); +} + +void World::InitResultQueue() +{ + m_resultQueue = new SqlResultQueue; + CharacterDatabase.SetResultQueue(m_resultQueue); +} + +void World::UpdateResultQueue() +{ + m_resultQueue->Update(); +} + +void World::UpdateRealmCharCount(uint32 accountId) +{ + CharacterDatabase.AsyncPQuery(this, &World::_UpdateRealmCharCount, accountId, + "SELECT COUNT(guid) FROM characters WHERE account = '%u'", accountId); +} + +void World::_UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId) +{ + if (resultCharCount) + { + Field *fields = resultCharCount->Fetch(); + uint32 charCount = fields[0].GetUInt32(); + delete resultCharCount; + loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", accountId, realmID); + loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charCount, accountId, realmID); + } +} + +void World::InitDailyQuestResetTime() +{ + time_t mostRecentQuestTime; + + QueryResult* result = CharacterDatabase.Query("SELECT MAX(time) FROM character_queststatus_daily"); + if(result) + { + Field *fields = result->Fetch(); + + mostRecentQuestTime = (time_t)fields[0].GetUInt64(); + delete result; + } + else + mostRecentQuestTime = 0; + + // client built-in time for reset is 6:00 AM + // FIX ME: client not show day start time + time_t curTime = time(NULL); + tm localTm = *localtime(&curTime); + localTm.tm_hour = 6; + localTm.tm_min = 0; + localTm.tm_sec = 0; + + // current day reset time + time_t curDayResetTime = mktime(&localTm); + + // last reset time before current moment + time_t resetTime = (curTime < curDayResetTime) ? curDayResetTime - DAY : curDayResetTime; + + // need reset (if we have quest time before last reset time (not processed by some reason) + if(mostRecentQuestTime && mostRecentQuestTime <= resetTime) + m_NextDailyQuestReset = mostRecentQuestTime; + else + { + // plan next reset time + m_NextDailyQuestReset = (curTime >= curDayResetTime) ? curDayResetTime + DAY : curDayResetTime; + } +} + +void World::ResetDailyQuests() +{ + sLog.outDetail("Daily quests reset for all characters."); + CharacterDatabase.Execute("DELETE FROM character_queststatus_daily"); + for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + if(itr->second->GetPlayer()) + itr->second->GetPlayer()->ResetDailyQuestStatus(); +} + +void World::SetPlayerLimit( int32 limit, bool needUpdate ) +{ + if(limit < -SEC_ADMINISTRATOR) + limit = -SEC_ADMINISTRATOR; + + // lock update need + bool db_update_need = needUpdate || (limit < 0) != (m_playerLimit < 0) || (limit < 0 && m_playerLimit < 0 && limit != m_playerLimit); + + m_playerLimit = limit; + + if(db_update_need) + loginDatabase.PExecute("UPDATE realmlist SET allowedSecurityLevel = '%u' WHERE id = '%d'",uint8(GetPlayerSecurityLimit()),realmID); +} + +void World::UpdateMaxSessionCounters() +{ + m_maxActiveSessionCount = std::max(m_maxActiveSessionCount,uint32(m_sessions.size()-m_QueuedPlayer.size())); + m_maxQueuedSessionCount = std::max(m_maxQueuedSessionCount,uint32(m_QueuedPlayer.size())); +} diff --git a/src/game/World.h b/src/game/World.h new file mode 100644 index 000000000..74a3a5e53 --- /dev/null +++ b/src/game/World.h @@ -0,0 +1,540 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup world The World +/// @{ +/// \file + +#ifndef __WORLD_H +#define __WORLD_H + +#include "Common.h" +#include "Timer.h" +#include "Policies/Singleton.h" + +#include +#include +#include + +class Object; +class WorldPacket; +class WorldSession; +class Player; +class Weather; +struct ScriptAction; +struct ScriptInfo; +class CliCommandHolder; +class SqlResultQueue; +class QueryResult; +class WorldSocket; + +enum ShutdownMask +{ + SHUTDOWN_MASK_RESTART = 1, + SHUTDOWN_MASK_IDLE = 2, +}; + +/// Timers for different object refresh rates +enum WorldTimers +{ + WUPDATE_OBJECTS = 0, + WUPDATE_SESSIONS = 1, + WUPDATE_AUCTIONS = 2, + WUPDATE_WEATHERS = 3, + WUPDATE_UPTIME = 4, + WUPDATE_CORPSES = 5, + WUPDATE_EVENTS = 6, + WUPDATE_COUNT = 7 +}; + +/// Configuration elements +enum WorldConfigs +{ + CONFIG_COMPRESSION = 0, + CONFIG_GRID_UNLOAD, + CONFIG_INTERVAL_SAVE, + CONFIG_INTERVAL_GRIDCLEAN, + CONFIG_INTERVAL_MAPUPDATE, + CONFIG_INTERVAL_CHANGEWEATHER, + CONFIG_PORT_WORLD, + CONFIG_SOCKET_SELECTTIME, + CONFIG_GROUP_XP_DISTANCE, + CONFIG_SIGHT_MONSTER, + CONFIG_SIGHT_GUARDER, + CONFIG_GAME_TYPE, + CONFIG_REALM_ZONE, + CONFIG_ALLOW_TWO_SIDE_ACCOUNTS, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL, + CONFIG_ALLOW_TWO_SIDE_WHO_LIST, + CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, + CONFIG_STRICT_PLAYER_NAMES, + CONFIG_STRICT_CHARTER_NAMES, + CONFIG_STRICT_PET_NAMES, + CONFIG_CHARACTERS_CREATING_DISABLED, + CONFIG_CHARACTERS_PER_ACCOUNT, + CONFIG_CHARACTERS_PER_REALM, + CONFIG_SKIP_CINEMATICS, + CONFIG_MAX_PLAYER_LEVEL, + CONFIG_START_PLAYER_LEVEL, + CONFIG_MAX_HONOR_POINTS, + CONFIG_MAX_ARENA_POINTS, + CONFIG_INSTANCE_IGNORE_LEVEL, + CONFIG_INSTANCE_IGNORE_RAID, + CONFIG_BATTLEGROUND_CAST_DESERTER, + CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE, + CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY, + CONFIG_INSTANCE_RESET_TIME_HOUR, + CONFIG_INSTANCE_UNLOAD_DELAY, + CONFIG_CAST_UNSTUCK, + CONFIG_MAX_PRIMARY_TRADE_SKILL, + CONFIG_MIN_PETITION_SIGNS, + CONFIG_GM_LOGIN_STATE, + CONFIG_GM_ACCEPT_TICKETS, + CONFIG_GM_CHAT, + CONFIG_GM_WISPERING_TO, + CONFIG_GM_IN_GM_LIST, + CONFIG_GM_IN_WHO_LIST, + CONFIG_GM_LOG_TRADE, + CONFIG_GROUP_VISIBILITY, + CONFIG_MAIL_DELIVERY_DELAY, + CONFIG_UPTIME_UPDATE, + CONFIG_SKILL_CHANCE_ORANGE, + CONFIG_SKILL_CHANCE_YELLOW, + CONFIG_SKILL_CHANCE_GREEN, + CONFIG_SKILL_CHANCE_GREY, + CONFIG_SKILL_CHANCE_MINING_STEPS, + CONFIG_SKILL_CHANCE_SKINNING_STEPS, + CONFIG_SKILL_PROSPECTING, + CONFIG_SKILL_GAIN_CRAFTING, + CONFIG_SKILL_GAIN_DEFENSE, + CONFIG_SKILL_GAIN_GATHERING, + CONFIG_SKILL_GAIN_WEAPON, + CONFIG_MAX_OVERSPEED_PINGS, + CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY, + CONFIG_WEATHER, + CONFIG_EXPANSION, + CONFIG_CHATFLOOD_MESSAGE_COUNT, + CONFIG_CHATFLOOD_MESSAGE_DELAY, + CONFIG_CHATFLOOD_MUTE_TIME, + CONFIG_EVENT_ANNOUNCE, + CONFIG_CREATURE_FAMILY_ASSISTEMCE_RADIUS, + CONFIG_WORLD_BOSS_LEVEL_DIFF, + CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF, + CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF, + CONFIG_DETECT_POS_COLLISION, + CONFIG_RESTRICTED_LFG_CHANNEL, + CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL, + CONFIG_TALENTS_INSPECTING, + CONFIG_CHAT_FAKE_MESSAGE_PREVENTING, + CONFIG_TCP_NO_DELAY, + CONFIG_CORPSE_DECAY_NORMAL, + CONFIG_CORPSE_DECAY_RARE, + CONFIG_CORPSE_DECAY_ELITE, + CONFIG_CORPSE_DECAY_RAREELITE, + CONFIG_CORPSE_DECAY_WORLDBOSS, + CONFIG_ADDON_CHANNEL, + CONFIG_DEATH_SICKNESS_LEVEL, + CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP, + CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE, + CONFIG_THREAT_RADIUS, + CONFIG_DECLINED_NAMES_USED, + CONFIG_LISTEN_RANGE_SAY, + CONFIG_LISTEN_RANGE_TEXTEMOTE, + CONFIG_LISTEN_RANGE_YELL, + CONFIG_VALUE_COUNT +}; + +/// Server rates +enum Rates +{ + RATE_HEALTH=0, + RATE_POWER_MANA, + RATE_POWER_RAGE_INCOME, + RATE_POWER_RAGE_LOSS, + RATE_POWER_FOCUS, + RATE_SKILL_DISCOVERY, + RATE_DROP_ITEM_POOR, + RATE_DROP_ITEM_NORMAL, + RATE_DROP_ITEM_UNCOMMON, + RATE_DROP_ITEM_RARE, + RATE_DROP_ITEM_EPIC, + RATE_DROP_ITEM_LEGENDARY, + RATE_DROP_ITEM_ARTIFACT, + RATE_DROP_ITEM_REFERENCED, + RATE_DROP_MONEY, + RATE_XP_KILL, + RATE_XP_QUEST, + RATE_XP_EXPLORE, + RATE_XP_PAST_70, + RATE_REPUTATION_GAIN, + RATE_CREATURE_NORMAL_HP, + RATE_CREATURE_ELITE_ELITE_HP, + RATE_CREATURE_ELITE_RAREELITE_HP, + RATE_CREATURE_ELITE_WORLDBOSS_HP, + RATE_CREATURE_ELITE_RARE_HP, + RATE_CREATURE_NORMAL_DAMAGE, + RATE_CREATURE_ELITE_ELITE_DAMAGE, + RATE_CREATURE_ELITE_RAREELITE_DAMAGE, + RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE, + RATE_CREATURE_ELITE_RARE_DAMAGE, + RATE_CREATURE_NORMAL_SPELLDAMAGE, + RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE, + RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE, + RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE, + RATE_CREATURE_ELITE_RARE_SPELLDAMAGE, + RATE_CREATURE_AGGRO, + RATE_REST_INGAME, + RATE_REST_OFFLINE_IN_TAVERN_OR_CITY, + RATE_REST_OFFLINE_IN_WILDERNESS, + RATE_DAMAGE_FALL, + RATE_AUCTION_TIME, + RATE_AUCTION_DEPOSIT, + RATE_AUCTION_CUT, + RATE_HONOR, + RATE_MINING_AMOUNT, + RATE_MINING_NEXT, + RATE_TALENT, + RATE_LOYALTY, + RATE_CORPSE_DECAY_LOOTED, + RATE_INSTANCE_RESET_TIME, + RATE_TARGET_POS_RECALCULATION_RANGE, + RATE_DURABILITY_LOSS_DAMAGE, + RATE_DURABILITY_LOSS_PARRY, + RATE_DURABILITY_LOSS_ABSORB, + RATE_DURABILITY_LOSS_BLOCK, + MAX_RATES +}; + +/// Type of server +enum RealmType +{ + REALM_TYPE_NORMAL = 0, + REALM_TYPE_PVP = 1, + REALM_TYPE_NORMAL2 = 4, + REALM_TYPE_RP = 6, + REALM_TYPE_RPPVP = 8, + REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries + // replaced by REALM_PVP in realm list +}; + +enum RealmZone +{ + REALM_ZONE_UNKNOWN = 0, // any language + REALM_ZONE_DEVELOPMENT = 1, // any language + REALM_ZONE_UNITED_STATES = 2, // extended-Latin + REALM_ZONE_OCEANIC = 3, // extended-Latin + REALM_ZONE_LATIN_AMERICA = 4, // extended-Latin + REALM_ZONE_TOURNAMENT_5 = 5, // basic-Latin at create, any at login + REALM_ZONE_KOREA = 6, // East-Asian + REALM_ZONE_TOURNAMENT_7 = 7, // basic-Latin at create, any at login + REALM_ZONE_ENGLISH = 8, // extended-Latin + REALM_ZONE_GERMAN = 9, // extended-Latin + REALM_ZONE_FRENCH = 10, // extended-Latin + REALM_ZONE_SPANISH = 11, // extended-Latin + REALM_ZONE_RUSSIAN = 12, // Cyrillic + REALM_ZONE_TOURNAMENT_13 = 13, // basic-Latin at create, any at login + REALM_ZONE_TAIWAN = 14, // East-Asian + REALM_ZONE_TOURNAMENT_15 = 15, // basic-Latin at create, any at login + REALM_ZONE_CHINA = 16, // East-Asian + REALM_ZONE_CN1 = 17, // basic-Latin at create, any at login + REALM_ZONE_CN2 = 18, // basic-Latin at create, any at login + REALM_ZONE_CN3 = 19, // basic-Latin at create, any at login + REALM_ZONE_CN4 = 20, // basic-Latin at create, any at login + REALM_ZONE_CN5 = 21, // basic-Latin at create, any at login + REALM_ZONE_CN6 = 22, // basic-Latin at create, any at login + REALM_ZONE_CN7 = 23, // basic-Latin at create, any at login + REALM_ZONE_CN8 = 24, // basic-Latin at create, any at login + REALM_ZONE_TOURNAMENT_25 = 25, // basic-Latin at create, any at login + REALM_ZONE_TEST_SERVER = 26, // any language + REALM_ZONE_TOURNAMENT_27 = 27, // basic-Latin at create, any at login + REALM_ZONE_QA_SERVER = 28, // any language + REALM_ZONE_CN9 = 29 // basic-Latin at create, any at login +}; + +/// Ban function return codes +enum BanReturn +{ + BAN_SUCCESS, + BAN_SYNTAX_ERROR, + BAN_NOTFOUND +}; + +// DB scripting commands +#define SCRIPT_COMMAND_TALK 0 // source = unit, target=any, datalong ( 0=say, 1=whisper, 2=yell, 3=emote text) +#define SCRIPT_COMMAND_EMOTE 1 // source = unit, datalong = anim_id +#define SCRIPT_COMMAND_FIELD_SET 2 // source = any, datalong = field_id, datalog2 = value +#define SCRIPT_COMMAND_MOVE_TO 3 // source = Creature, datalog2 = time, x/y/z +#define SCRIPT_COMMAND_FLAG_SET 4 // source = any, datalong = field_id, datalog2 = bitmask +#define SCRIPT_COMMAND_FLAG_REMOVE 5 // source = any, datalong = field_id, datalog2 = bitmask +#define SCRIPT_COMMAND_TELEPORT_TO 6 // source or target with Player, datalong = map_id, x/y/z +#define SCRIPT_COMMAND_QUEST_EXPLORED 7 // one from source or target must be Player, another GO/Creature, datalong=quest_id, datalong2=distance or 0 +#define SCRIPT_COMMAND_RESPAWN_GAMEOBJECT 9 // source = any (summoner), datalong=db_guid, datalong2=despawn_delay +#define SCRIPT_COMMAND_TEMP_SUMMON_CREATURE 10 // source = any (summoner), datalong=creature entry, datalong2=despawn_delay +#define SCRIPT_COMMAND_OPEN_DOOR 11 // source = unit, datalong=db_guid, datalong2=reset_delay +#define SCRIPT_COMMAND_CLOSE_DOOR 12 // source = unit, datalong=db_guid, datalong2=reset_delay +#define SCRIPT_COMMAND_ACTIVATE_OBJECT 13 // source = unit, target=GO +#define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id +#define SCRIPT_COMMAND_CAST_SPELL 15 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id + +/// CLI related stuff, define here to prevent cyclic dependancies + +typedef int(* pPrintf)(const char*,...); +typedef void(* pCliFunc)(char *,pPrintf); + +/// Command Template class +struct CliCommand +{ + char const * cmd; + pCliFunc Func; + char const * description; +}; + +/// Storage class for commands issued for delayed execution +class CliCommandHolder +{ + private: + const CliCommand *cmd; + char *args; + pPrintf m_zprintf; + public: + CliCommandHolder(const CliCommand *command, const char *arguments, pPrintf p_zprintf) + : cmd(command), m_zprintf(p_zprintf) + { + size_t len = strlen(arguments)+1; + args = new char[len]; + memcpy(args, arguments, len); + } + ~CliCommandHolder() { delete[] args; } + void Execute() const { cmd->Func(args, m_zprintf); } + pPrintf GetOutputMethod() const {return (m_zprintf);} +}; + +/// The World +class World +{ + public: + static volatile bool m_stopEvent; + static volatile uint32 m_worldLoopCounter; + + World(); + ~World(); + + WorldSession* FindSession(uint32 id) const; + void AddSession(WorldSession *s); + bool RemoveSession(uint32 id); + /// Get the number of current active sessions + void UpdateMaxSessionCounters(); + uint32 GetActiveAndQueuedSessionCount() const { return m_sessions.size(); } + uint32 GetActiveSessionCount() const { return m_sessions.size() - m_QueuedPlayer.size(); } + uint32 GetQueuedSessionCount() const { return m_QueuedPlayer.size(); } + /// Get the maximum number of parallel sessions on the server since last reboot + uint32 GetMaxQueuedSessionCount() const { return m_maxQueuedSessionCount; } + uint32 GetMaxActiveSessionCount() const { return m_maxActiveSessionCount; } + Player* FindPlayerInZone(uint32 zone); + + Weather* FindWeather(uint32 id) const; + Weather* AddWeather(uint32 zone_id); + void RemoveWeather(uint32 zone_id); + + /// Get the active session server limit (or security level limitations) + uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; } + AccountTypes GetPlayerSecurityLimit() const { return m_playerLimit <= 0 ? AccountTypes(-m_playerLimit) : SEC_PLAYER; } + + /// Set the active session server limit (or security level limitation) + void SetPlayerLimit(int32 limit, bool needUpdate = false); + + //player Queue + typedef std::list Queue; + void AddQueuedPlayer(WorldSession*); + void RemoveQueuedPlayer(WorldSession*); + int32 GetQueuePos(WorldSession*); + uint32 GetQueueSize() const { return m_QueuedPlayer.size(); } + + /// \todo Actions on m_allowMovement still to be implemented + /// Is movement allowed? + bool getAllowMovement() const { return m_allowMovement; } + /// Allow/Disallow object movements + void SetAllowMovement(bool allow) { m_allowMovement = allow; } + + /// Set a new Message of the Day + void SetMotd(std::string motd) { m_motd = motd; } + /// Get the current Message of the Day + const char* GetMotd() const { return m_motd.c_str(); } + + uint32 GetDefaultDbcLocale() const { return m_defaultDbcLocale; } + + /// Get the path where data (dbc, maps) are stored on disk + std::string GetDataPath() const { return m_dataPath; } + + /// When server started? + time_t const& GetStartTime() const { return m_startTime; } + /// What time is it? + time_t const& GetGameTime() const { return m_gameTime; } + /// Uptime (in secs) + uint32 GetUptime() const { return uint32(m_gameTime - m_startTime); } + + /// Get the maximum skill level a player can reach + uint16 GetConfigMaxSkillValue() const + { + uint32 lvl = getConfig(CONFIG_MAX_PLAYER_LEVEL); + return lvl > 60 ? 300 + ((lvl - 60) * 75) / 10 : lvl*5; + } + + void SetInitialWorldSettings(); + void LoadConfigSettings(bool reload = false); + + void SendWorldText(int32 string_id, ...); + void SendGlobalMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0); + void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0); + void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0); + void SendServerMessage(uint32 type, const char *text = "", Player* player = NULL); + + /// Are we in the middle of a shutdown? + uint32 GetShutdownMask() const { return m_ShutdownMask; } + bool IsShutdowning() const { return m_ShutdownTimer > 0; } + void ShutdownServ(uint32 time, uint32 options = 0); + void ShutdownCancel(); + void ShutdownMsg(bool show = false, Player* player = NULL); + + void Update(time_t diff); + + void UpdateSessions( time_t diff ); + /// Set a server rate (see #Rates) + void setRate(Rates rate,float value) { rate_values[rate]=value; } + /// Get a server rate (see #Rates) + float getRate(Rates rate) const { return rate_values[rate]; } + + /// Set a server configuration element (see #WorldConfigs) + void setConfig(uint32 index,uint32 value) + { + if(index > const& scripts, uint32 id, Object* source, Object* target); + void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target); + bool IsScriptScheduled() const { return !m_scriptSchedule.empty(); } + + // for max speed access + static float GetMaxVisibleDistanceForCreature() { return m_MaxVisibleDistanceForCreature; } + static float GetMaxVisibleDistanceForPlayer() { return m_MaxVisibleDistanceForPlayer; } + static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; } + static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; } + static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; } + static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; } + + void ProcessCliCommands(); + void QueueCliCommand(CliCommandHolder* command) { cliCmdQueue.add(command); } + + void UpdateResultQueue(); + void InitResultQueue(); + + void UpdateRealmCharCount(uint32 accid); + + LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const { if(m_availableDbcLocaleMask & (1 << locale)) return locale; else return m_defaultDbcLocale; } + protected: + void _UpdateGameTime(); + void ScriptsProcess(); + // callback for UpdateRealmCharacters + void _UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId); + + void InitDailyQuestResetTime(); + void ResetDailyQuests(); + private: + time_t m_startTime; + time_t m_gameTime; + IntervalTimer m_timers[WUPDATE_COUNT]; + uint32 mail_timer; + uint32 mail_timer_expires; + + typedef HM_NAMESPACE::hash_map WeatherMap; + WeatherMap m_weathers; + typedef HM_NAMESPACE::hash_map SessionMap; + SessionMap m_sessions; + std::set m_kicked_sessions; + uint32 m_maxActiveSessionCount; + uint32 m_maxQueuedSessionCount; + + std::multimap m_scriptSchedule; + + float rate_values[MAX_RATES]; + uint32 m_configs[CONFIG_VALUE_COUNT]; + int32 m_playerLimit; + LocaleConstant m_defaultDbcLocale; // from config for one from loaded DBC locales + uint32 m_availableDbcLocaleMask; // by loaded DBC + void DetectDBCLang(); + bool m_allowMovement; + std::string m_motd; + std::string m_dataPath; + + uint32 m_ShutdownTimer; + uint32 m_ShutdownMask; + + // for max speed access + static float m_MaxVisibleDistanceForCreature; + static float m_MaxVisibleDistanceForPlayer; + static float m_MaxVisibleDistanceForObject; + static float m_MaxVisibleDistanceInFlight; + static float m_VisibleUnitGreyDistance; + static float m_VisibleObjectGreyDistance; + + // CLI command holder to be thread safe + ZThread::LockedQueue cliCmdQueue; + SqlResultQueue *m_resultQueue; + + // next daily quests reset time + time_t m_NextDailyQuestReset; + + //Player Queue + Queue m_QueuedPlayer; + + //sessions that are added async + void AddSession_(WorldSession* s); + ZThread::LockedQueue addSessQueue; +}; + +extern uint32 realmID; + +#define sWorld MaNGOS::Singleton::Instance() +#endif +/// @} diff --git a/src/game/WorldLog.cpp b/src/game/WorldLog.cpp new file mode 100644 index 000000000..062da0d5b --- /dev/null +++ b/src/game/WorldLog.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup u2w +*/ + +#include "WorldLog.h" +#include "Policies/SingletonImp.h" +#include "Config/ConfigEnv.h" + +#define CLASS_LOCK MaNGOS::ClassLevelLockable +INSTANTIATE_SINGLETON_2(WorldLog, CLASS_LOCK); +INSTANTIATE_CLASS_MUTEX(WorldLog, ZThread::FastMutex); + +#define WORLD_LOG_FILE_STRING "world.log" + +/// Open the log file (if specified so in the configuration file) +void WorldLog::Initialize() +{ + std::string logsDir = sConfig.GetStringDefault("LogsDir",""); + + if(!logsDir.empty()) + { + if((logsDir.at(logsDir.length()-1)!='/') && (logsDir.at(logsDir.length()-1)!='\\')) + logsDir.append("/"); + } + + std::string logname = sConfig.GetStringDefault("WorldLogFile", ""); + if(!logname.empty()) + { + i_file = fopen((logsDir+logname).c_str(), "w"); + } +} + +#define sWorldLog WorldLog::Instance() diff --git a/src/game/WorldLog.h b/src/game/WorldLog.h new file mode 100644 index 000000000..e9309e4d1 --- /dev/null +++ b/src/game/WorldLog.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup u2w +/// @{ +/// \file + +#ifndef MANGOS_WORLDLOG_H +#define MANGOS_WORLDLOG_H + +#include "Common.h" +#include "Policies/Singleton.h" +#include "Errors.h" + +#include + +/// %Log packets to a file +class MANGOS_DLL_DECL WorldLog : public MaNGOS::Singleton > +{ + friend class MaNGOS::OperatorNew; + WorldLog() : i_file(NULL) { Initialize(); } + WorldLog(const WorldLog &); + WorldLog& operator=(const WorldLog &); + typedef MaNGOS::ClassLevelLockable::Lock Guard; + + /// Close the file in destructor + ~WorldLog() + { + if( i_file != NULL ) + fclose(i_file); + i_file = NULL; + } + + public: + void Initialize(); + /// Is the world logger active? + inline bool LogWorld(void) const { return (i_file != NULL); } + /// %Log to the file + inline void Log(char const *fmt, ...) + { + if( LogWorld() ) + { + Guard guard(*this); + ASSERT(i_file); + + va_list args; + va_start(args, fmt); + vfprintf(i_file, fmt, args); + va_end(args); + + fflush(i_file); + } + } + + private: + FILE *i_file; +}; + +#define sWorldLog WorldLog::Instance() +#endif +/// @} diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp new file mode 100644 index 000000000..d448bdff2 --- /dev/null +++ b/src/game/WorldSession.cpp @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup u2w +*/ + +#include "WorldSocket.h" +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "Opcodes.h" +#include "WorldSocket.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Player.h" +#include "ObjectMgr.h" +#include "Group.h" +#include "Guild.h" +#include "World.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "BattleGroundMgr.h" +#include "Language.h" // for CMSG_CANCEL_MOUNT_AURA handler +#include "Chat.h" +#include "SocialMgr.h" + +/// WorldSession constructor +WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale) : +LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time), +_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion), +m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)), +_logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0) +{ + if (sock) + { + m_Address = sock->GetRemoteAddress (); + sock->AddReference (); + } +} + +/// WorldSession destructor +WorldSession::~WorldSession() +{ + ///- unload player if not unloaded + if(_player) + LogoutPlayer(true); + + /// - If have unclosed socket, close it + if (m_Socket) + { + m_Socket->CloseSocket (); + m_Socket->RemoveReference (); + m_Socket = NULL; + } + + ///- empty incoming packet queue + while(!_recvQueue.empty()) + { + WorldPacket *packet = _recvQueue.next(); + delete packet; + } + + sWorld.RemoveQueuedPlayer(this); +} + +void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const +{ + sLog.outError("Client (account %u) send packet %s (%u) with size %u but expected %u (attempt crash server?), skipped", + GetAccountId(),LookupOpcodeName(packet.GetOpcode()),packet.GetOpcode(),packet.size(),size); +} + +/// Get the player name +char const* WorldSession::GetPlayerName() const +{ + return GetPlayer() ? GetPlayer()->GetName() : ""; +} + +/// Send a packet to the client +void WorldSession::SendPacket(WorldPacket const* packet) +{ + if (!m_Socket) + return; + #ifdef MANGOS_DEBUG + // Code for network use statistic + static uint64 sendPacketCount = 0; + static uint64 sendPacketBytes = 0; + + static time_t firstTime = time(NULL); + static time_t lastTime = firstTime; // next 60 secs start time + + static uint64 sendLastPacketCount = 0; + static uint64 sendLastPacketBytes = 0; + + time_t cur_time = time(NULL); + + if((cur_time - lastTime) < 60) + { + sendPacketCount+=1; + sendPacketBytes+=packet->size(); + + sendLastPacketCount+=1; + sendLastPacketBytes+=packet->size(); + } + else + { + uint64 minTime = uint64(cur_time - lastTime); + uint64 fullTime = uint64(lastTime - firstTime); + sLog.outDetail("Send all time packets count: " I64FMTD " bytes: " I64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u",sendPacketCount,sendPacketBytes,float(sendPacketCount)/fullTime,float(sendPacketBytes)/fullTime,uint32(fullTime)); + sLog.outDetail("Send last min packets count: " I64FMTD " bytes: " I64FMTD " avr.count/sec: %f avr.bytes/sec: %f",sendLastPacketCount,sendLastPacketBytes,float(sendLastPacketCount)/minTime,float(sendLastPacketBytes)/minTime); + + lastTime = cur_time; + sendLastPacketCount = 1; + sendLastPacketBytes = packet->wpos(); // wpos is real written size + } +#endif // !MANGOS_DEBUG + + if (m_Socket->SendPacket (*packet) == -1) + { + m_Socket->CloseSocket (); + } +} + +/// Add an incoming packet to the queue +void WorldSession::QueuePacket(WorldPacket* new_packet) +{ + _recvQueue.add(new_packet); +} + +/// Logging helper for unexpected opcodes +void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason) +{ + sLog.outError( "SESSION: received unexpected opcode %s (0x%.4X) %s", + LookupOpcodeName(packet->GetOpcode()), + packet->GetOpcode(), + reason); +} + +/// Update the WorldSession (triggered by World update) +bool WorldSession::Update(uint32 /*diff*/) +{ + if (m_Socket) + if (m_Socket->IsClosed ()) + { + m_Socket->RemoveReference (); + m_Socket = NULL; + } + + WorldPacket *packet; + + ///- Retrieve packets from the receive queue and call the appropriate handlers + /// \todo Is there a way to consolidate the OpcondeHandlerTable and the g_worldOpcodeNames to only maintain 1 list? + /// answer : there is a way, but this is better, because it would use redundant RAM + while (!_recvQueue.empty()) + { + packet = _recvQueue.next(); + + /*#if 1 + sLog.outError( "MOEP: %s (0x%.4X)", + LookupOpcodeName(packet->GetOpcode()), + packet->GetOpcode()); + #endif*/ + + if(packet->GetOpcode() >= NUM_MSG_TYPES) + { + sLog.outError( "SESSION: received non-existed opcode %s (0x%.4X)", + LookupOpcodeName(packet->GetOpcode()), + packet->GetOpcode()); + } + else + { + OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()]; + switch (opHandle.status) + { + case STATUS_LOGGEDIN: + if(!_player) + { + // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets + if(!m_playerRecentlyLogout) + logUnexpectedOpcode(packet, "the player has not logged in yet"); + } + else if(_player->IsInWorld()) + (this->*opHandle.handler)(*packet); + // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer + break; + case STATUS_TRANSFER_PENDING: + if(!_player) + logUnexpectedOpcode(packet, "the player has not logged in yet"); + else if(_player->IsInWorld()) + logUnexpectedOpcode(packet, "the player is still in world"); + else + (this->*opHandle.handler)(*packet); + break; + case STATUS_AUTHED: + m_playerRecentlyLogout = false; + (this->*opHandle.handler)(*packet); + break; + case STATUS_NEVER: + sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)", + LookupOpcodeName(packet->GetOpcode()), + packet->GetOpcode()); + break; + } + } + + delete packet; + } + + ///- If necessary, log the player out + time_t currTime = time(NULL); + if (!m_Socket || (ShouldLogOut(currTime) && !m_playerLoading)) + LogoutPlayer(true); + + if (!m_Socket) + return false; //Will remove this session from the world session map + + return true; +} + +/// %Log the player out +void WorldSession::LogoutPlayer(bool Save) +{ + // finish pending transfers before starting the logout + while(_player && _player->IsBeingTeleported()) + HandleMoveWorldportAckOpcode(); + + m_playerLogout = true; + + if (_player) + { + ///- If the player just died before logging out, make him appear as a ghost + //FIXME: logout must be delayed in case lost connection with client in time of combat + if (_player->GetDeathTimer()) + { + _player->getHostilRefManager().deleteReferences(); + _player->BuildPlayerRepop(); + _player->RepopAtGraveyard(); + } + else if (!_player->getAttackers().empty()) + { + _player->CombatStop(); + _player->getHostilRefManager().setOnlineOfflineState(false); + _player->RemoveAllAurasOnDeath(); + + // build set of player who attack _player or who have pet attacking of _player + std::set aset; + for(Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) + { + Unit* owner = (*itr)->GetOwner(); // including player controlled case + if(owner) + { + if(owner->GetTypeId()==TYPEID_PLAYER) + aset.insert((Player*)owner); + } + else + if((*itr)->GetTypeId()==TYPEID_PLAYER) + aset.insert((Player*)(*itr)); + } + + _player->SetPvPDeath(!aset.empty()); + _player->KillPlayer(); + _player->BuildPlayerRepop(); + _player->RepopAtGraveyard(); + + // give honor to all attackers from set like group case + for(std::set::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) + (*itr)->RewardHonor(_player,aset.size()); + + // give bg rewards and update counters like kill by first from attackers + // this can't be called for all attackers. + if(!aset.empty()) + if(BattleGround *bg = _player->GetBattleGround()) + bg->HandleKillPlayer(_player,*aset.begin()); + } + else if(_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) + { + // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION + _player->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); + //_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time + _player->KillPlayer(); + _player->BuildPlayerRepop(); + _player->RepopAtGraveyard(); + } + + ///- Remove player from battleground (teleport to entrance) + if(_player->InBattleGround()) + _player->LeaveBattleground(); + + for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + { + if(int32 bgTypeId = _player->GetBattleGroundQueueId(i)) + { + _player->RemoveBattleGroundQueueId(bgTypeId); + sBattleGroundMgr.m_BattleGroundQueues[ bgTypeId ].RemovePlayer(_player->GetGUID(), true); + } + } + + ///- Reset the online field in the account table + // no point resetting online in character table here as Player::SaveToDB() will set it to 1 since player has not been removed from world at this stage + //No SQL injection as AccountID is uint32 + loginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = '%u'", GetAccountId()); + + ///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members + Guild *guild = objmgr.GetGuildById(_player->GetGuildId()); + if(guild) + { + guild->LoadPlayerStatsByGuid(_player->GetGUID()); + guild->UpdateLogoutTime(_player->GetGUID()); + + WorldPacket data(SMSG_GUILD_EVENT, (1+1+12+8)); // name limited to 12 in character table. + data<<(uint8)GE_SIGNED_OFF; + data<<(uint8)1; + data<<_player->GetName(); + data<<_player->GetGUID(); + guild->BroadcastPacket(&data); + } + + ///- Remove pet + _player->RemovePet(NULL,PET_SAVE_AS_CURRENT, true); + + ///- empty buyback items and save the player in the database + // some save parts only correctly work in case player present in map/player_lists (pets, etc) + if(Save) + { + uint32 eslot; + for(int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; j++) + { + eslot = j - BUYBACK_SLOT_START; + _player->SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1+eslot*2,0); + _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1+eslot,0); + _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1+eslot,0); + } + _player->SaveToDB(); + } + + ///- Leave all channels before player delete... + _player->CleanupChannels(); + + ///- If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group. + _player->UninviteFromGroup(); + + // remove player from the group if he is: + // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) + if(_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket) + _player->RemoveFromGroup(); + + ///- Remove the player from the world + // the player may not be in the world when logging out + // e.g if he got disconnected during a transfer to another map + // calls to GetMap in this case may cause crashes + if(_player->IsInWorld()) MapManager::Instance().GetMap(_player->GetMapId(), _player)->Remove(_player, false); + // RemoveFromWorld does cleanup that requires the player to be in the accessor + ObjectAccessor::Instance().RemoveObject(_player); + + ///- Send update to group + if(_player->GetGroup()) + _player->GetGroup()->SendUpdate(); + + ///- Broadcast a logout message to the player's friends + sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), "", true); + + ///- Delete the player object + _player->CleanupsBeforeDelete(); // do some cleanup before deleting to prevent crash at crossreferences to already deleted data + + delete _player; + _player = NULL; + + ///- Send the 'logout complete' packet to the client + WorldPacket data( SMSG_LOGOUT_COMPLETE, 0 ); + SendPacket( &data ); + + ///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline + //No SQL injection as AccountId is uint32 + CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", GetAccountId()); + sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" ); + } + + m_playerLogout = false; + m_playerRecentlyLogout = true; + LogoutRequest(0); +} + +/// Kick a player out of the World +void WorldSession::KickPlayer() +{ + if (m_Socket) + { + m_Socket->CloseSocket (); + } +} + +/// Cancel channeling handler + +void WorldSession::SendAreaTriggerMessage(const char* Text, ...) +{ + va_list ap; + char szStr [1024]; + szStr[0] = '\0'; + + va_start(ap, Text); + vsnprintf( szStr, 1024, Text, ap ); + va_end(ap); + + uint32 length = strlen(szStr)+1; + WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4+length); + data << length; + data << szStr; + SendPacket(&data); +} + +void WorldSession::SendNotification(const char *format,...) +{ + if(format) + { + va_list ap; + char szStr [1024]; + szStr[0] = '\0'; + va_start(ap, format); + vsnprintf( szStr, 1024, format, ap ); + va_end(ap); + + WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1)); + data << szStr; + SendPacket(&data); + } +} + +void WorldSession::SendNotification(int32 string_id,...) +{ + char const* format = GetMangosString(string_id); + if(format) + { + va_list ap; + char szStr [1024]; + szStr[0] = '\0'; + va_start(ap, format); + vsnprintf( szStr, 1024, format, ap ); + va_end(ap); + + WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1)); + data << szStr; + SendPacket(&data); + } +} + +const char * WorldSession::GetMangosString( int32 entry ) +{ + return objmgr.GetMangosString(entry,GetSessionDbLocaleIndex()); +} + +void WorldSession::Handle_NULL( WorldPacket& recvPacket ) +{ + sLog.outError( "SESSION: received unhandled opcode %s (0x%.4X)", + LookupOpcodeName(recvPacket.GetOpcode()), + recvPacket.GetOpcode()); +} + +void WorldSession::Handle_EarlyProccess( WorldPacket& recvPacket ) +{ + sLog.outError( "SESSION: received opcode %s (0x%.4X) that must be proccessed in WorldSocket::OnRead", + LookupOpcodeName(recvPacket.GetOpcode()), + recvPacket.GetOpcode()); +} + +void WorldSession::Handle_ServerSide( WorldPacket& recvPacket ) +{ + sLog.outError( "SESSION: received sever-side opcode %s (0x%.4X)", + LookupOpcodeName(recvPacket.GetOpcode()), + recvPacket.GetOpcode()); +} + +void WorldSession::Handle_Depricated( WorldPacket& recvPacket ) +{ + sLog.outError( "SESSION: received depricated opcode %s (0x%.4X)", + LookupOpcodeName(recvPacket.GetOpcode()), + recvPacket.GetOpcode()); +} + +void WorldSession::SendAuthWaitQue(uint32 position) + { + if(position == 0) + { + WorldPacket packet( SMSG_AUTH_RESPONSE, 1 ); + packet << uint8( AUTH_OK ); + SendPacket(&packet); + } + else + { + WorldPacket packet( SMSG_AUTH_RESPONSE, 5 ); + packet << uint8( AUTH_WAIT_QUEUE ); + packet << uint32 (position); + SendPacket(&packet); + } + } + + diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h new file mode 100644 index 000000000..45b6bed27 --- /dev/null +++ b/src/game/WorldSession.h @@ -0,0 +1,646 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup u2w +/// @{ +/// \file + +#ifndef __WORLDSESSION_H +#define __WORLDSESSION_H + +#include "Common.h" + +class MailItemsInfo; +struct ItemPrototype; +struct AuctionEntry; +struct DeclinedName; + +class Creature; +class Item; +class Object; +class Player; +class Unit; +class WorldPacket; +class WorldSocket; +class WorldSession; +class QueryResult; +class LoginQueryHolder; +class CharacterHandler; + +#define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S)); + +enum PartyOperation +{ + PARTY_OP_INVITE = 0, + PARTY_OP_LEAVE = 2 +}; + +enum PartyResult +{ + PARTY_RESULT_OK = 0, + PARTY_RESULT_CANT_FIND_TARGET = 1, + PARTY_RESULT_NOT_IN_YOUR_PARTY = 2, + PARTY_RESULT_NOT_IN_YOUR_INSTANCE = 3, + PARTY_RESULT_PARTY_FULL = 4, + PARTY_RESULT_ALREADY_IN_GROUP = 5, + PARTY_RESULT_YOU_NOT_IN_GROUP = 6, + PARTY_RESULT_YOU_NOT_LEADER = 7, + PARTY_RESULT_TARGET_UNFRIENDLY = 8, + PARTY_RESULT_TARGET_IGNORE_YOU = 9, + PARTY_RESULT_INVITE_RESTRICTED = 13 +}; + +/// Player session in the World +class MANGOS_DLL_SPEC WorldSession +{ + friend class CharacterHandler; + public: + WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale); + ~WorldSession(); + + bool PlayerLoading() const { return m_playerLoading; } + bool PlayerLogout() const { return m_playerLogout; } + + void SizeError(WorldPacket const& packet, uint32 size) const; + + void SendPacket(WorldPacket const* packet); + void SendNotification(const char *format,...) ATTR_PRINTF(2,3); + void SendNotification(int32 string_id,...); + void SendPetNameInvalid(uint32 error, std::string name, DeclinedName *declinedName); + void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type); + void SendPartyResult(PartyOperation operation, std::string member, PartyResult res); + void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3); + + uint32 GetSecurity() const { return _security; } + uint32 GetAccountId() const { return _accountId; } + Player* GetPlayer() const { return _player; } + char const* GetPlayerName() const; + void SetSecurity(uint32 security) { _security = security; } + std::string& GetRemoteAddress() { return m_Address; } + void SetPlayer(Player *plr) { _player = plr; } + uint8 Expansion() const { return m_expansion; } + + /// Is the user engaged in a log out process? + bool isLogingOut() const { return _logoutTime || m_playerLogout; } + + /// Engage the logout process for the user + void LogoutRequest(time_t requestTime) + { + _logoutTime = requestTime; + } + + /// Is logout cooldown expired? + bool ShouldLogOut(time_t currTime) const + { + return (_logoutTime > 0 && currTime >= _logoutTime + 20); + } + + void LogoutPlayer(bool Save); + void KickPlayer(); + + void QueuePacket(WorldPacket* new_packet); + bool Update(uint32 diff); + + /// Handle the authentication waiting queue (to be completed) + void SendAuthWaitQue(uint32 position); + + //void SendTestCreatureQueryOpcode( uint32 entry, uint64 guid, uint32 testvalue ); + void SendNameQueryOpcode(Player* p); + void SendNameQueryOpcodeFromDB(uint64 guid); + static void SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32 accountId); + + void SendTrainerList( uint64 guid ); + void SendTrainerList( uint64 guid,std::string strTitle ); + void SendListInventory( uint64 guid ); + void SendShowBank( uint64 guid ); + void SendTabardVendorActivate( uint64 guid ); + void SendSpiritResurrect(); + void SendBindPoint(Creature* npc); + void SendGMTicketGetTicket(uint32 status, char const* text); + + void SendAttackStop(Unit const* enemy); + + void SendBattlegGroundList( uint64 guid, uint32 bgTypeId ); + + void SendTradeStatus(uint32 status); + void SendCancelTrade(); + + void SendStablePet(uint64 guid ); + void SendPetitionQueryOpcode( uint64 petitionguid); + void SendUpdateTrade(); + + //pet + void SendPetNameQuery(uint64 guid, uint32 petnumber); + + //mail + //used with item_page table + bool SendItemInfo( uint32 itemid, WorldPacket data ); + static void SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, std::string subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint32 COD, uint16 mailTemplateId = 0); + static void SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 received_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay = 0, uint16 mailTemplateId = 0); + + //auction + void SendAuctionHello( uint64 guid, Creature * unit ); + void SendAuctionCommandResult( uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0); + void SendAuctionBidderNotification( uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template); + void SendAuctionOwnerNotification( AuctionEntry * auction ); + bool SendAuctionInfo(WorldPacket & data, AuctionEntry* auction); + void SendAuctionOutbiddedMail( AuctionEntry * auction, uint32 newPrice ); + void SendAuctionCancelledToBidderMail( AuctionEntry* auction ); + + //Item Enchantment + void SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID); + void SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid,uint32 slot,uint32 Duration); + + //Taxi + void SendTaxiStatus( uint64 guid ); + void SendTaxiMenu( Creature* unit ); + void SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode = 0 ); + bool SendLearnNewTaxiNode( Creature* unit ); + + // Guild/Arena Team + void SendGuildCommandResult(uint32 typecmd,std::string str,uint32 cmdresult); + void SendArenaTeamCommandResult(uint32 unk1, std::string str1, std::string str2, uint32 unk3); + void BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, std::string str1, std::string str2, std::string str3); + void SendNotInArenaTeamPacket(uint8 type); + void SendPetitionShowList( uint64 guid ); + void SendSaveGuildEmblem( uint32 msg ); + + // Looking For Group + // TRUE values set by client sending CMSG_LFG_SET_AUTOJOIN and CMSG_LFM_CLEAR_AUTOFILL before player login + bool LookingForGroup_auto_join; + bool LookingForGroup_auto_add; + + void BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data); + + void DoLootRelease( uint64 lguid ); + + // Account mute time + time_t m_muteTime; + + // Locales + LocaleConstant GetSessionDbcLocale() { return m_sessionDbcLocale; } + int GetSessionDbLocaleIndex() { return m_sessionDbLocaleIndex; } + const char *GetMangosString(int32 entry); + + uint32 GetLatency() const { return m_latency; } + void SetLatency(uint32 latency) { m_latency = latency; } + uint32 getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus); + + public: // opcodes handlers + + void Handle_NULL(WorldPacket& recvPacket); // not used + void Handle_EarlyProccess( WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnRead + void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client + void Handle_Depricated(WorldPacket& recvPacket); // never used anymore by client + + void HandleCharEnumOpcode(WorldPacket& recvPacket); + void HandleCharDeleteOpcode(WorldPacket& recvPacket); + void HandleCharCreateOpcode(WorldPacket& recvPacket); + void HandlePlayerLoginOpcode(WorldPacket& recvPacket); + void HandleCharEnum(QueryResult * result); + void HandlePlayerLogin(LoginQueryHolder * holder); + + // played time + void HandlePlayedTime(WorldPacket& recvPacket); + + // new + void HandleMoveUnRootAck(WorldPacket& recvPacket); + void HandleMoveRootAck(WorldPacket& recvPacket); + void HandleLookingForGroup(WorldPacket& recvPacket); + + // new inspect + void HandleInspectOpcode(WorldPacket& recvPacket); + + // new party stats + void HandleInspectHonorStatsOpcode(WorldPacket& recvPacket); + + void HandleMoveWaterWalkAck(WorldPacket& recvPacket); + void HandleFeatherFallAck(WorldPacket &recv_data); + + void HandleMoveHoverAck( WorldPacket & recv_data ); + + void HandleMountSpecialAnimOpcode(WorldPacket &recvdata); + + // character view + void HandleToggleHelmOpcode(WorldPacket& recv_data); + void HandleToggleCloakOpcode(WorldPacket& recv_data); + + // repair + void HandleRepairItemOpcode(WorldPacket& recvPacket); + + // Knockback + void HandleMoveKnockBackAck(WorldPacket& recvPacket); + + void HandleMoveTeleportAck(WorldPacket& recvPacket); + void HandleForceSpeedChangeAck( WorldPacket & recv_data ); + + void HandlePingOpcode(WorldPacket& recvPacket); + void HandleAuthSessionOpcode(WorldPacket& recvPacket); + void HandleRepopRequestOpcode(WorldPacket& recvPacket); + void HandleAutostoreLootItemOpcode(WorldPacket& recvPacket); + void HandleLootMoneyOpcode(WorldPacket& recvPacket); + void HandleLootOpcode(WorldPacket& recvPacket); + void HandleLootReleaseOpcode(WorldPacket& recvPacket); + void HandleLootMasterGiveOpcode(WorldPacket& recvPacket); + void HandleWhoOpcode(WorldPacket& recvPacket); + void HandleLogoutRequestOpcode(WorldPacket& recvPacket); + void HandlePlayerLogoutOpcode(WorldPacket& recvPacket); + void HandleLogoutCancelOpcode(WorldPacket& recvPacket); + void HandleGMTicketGetTicketOpcode(WorldPacket& recvPacket); + void HandleGMTicketCreateOpcode(WorldPacket& recvPacket); + void HandleGMTicketSystemStatusOpcode(WorldPacket& recvPacket); + + void HandleGMTicketDeleteOpcode(WorldPacket& recvPacket); + void HandleGMTicketUpdateTextOpcode(WorldPacket& recvPacket); + + void HandleGMSurveySubmit(WorldPacket& recvPacket); + + void HandleTogglePvP(WorldPacket& recvPacket); + + void HandleZoneUpdateOpcode(WorldPacket& recvPacket); + void HandleSetTargetOpcode(WorldPacket& recvPacket); + void HandleSetSelectionOpcode(WorldPacket& recvPacket); + void HandleStandStateChangeOpcode(WorldPacket& recvPacket); + void HandleEmoteOpcode(WorldPacket& recvPacket); + void HandleFriendListOpcode(WorldPacket& recvPacket); + void HandleAddFriendOpcode(WorldPacket& recvPacket); + void HandleDelFriendOpcode(WorldPacket& recvPacket); + void HandleAddIgnoreOpcode(WorldPacket& recvPacket); + void HandleDelIgnoreOpcode(WorldPacket& recvPacket); + void HandleSetFriendNoteOpcode(WorldPacket& recvPacket); + void HandleBugOpcode(WorldPacket& recvPacket); + void HandleSetAmmoOpcode(WorldPacket& recvPacket); + void HandleItemNameQueryOpcode(WorldPacket& recvPacket); + + void HandleAreaTriggerOpcode(WorldPacket& recvPacket); + + void HandleSetFactionAtWar( WorldPacket & recv_data ); + void HandleSetFactionCheat( WorldPacket & recv_data ); + void HandleSetWatchedFactionIndexOpcode(WorldPacket & recv_data); + void HandleSetWatchedFactionInactiveOpcode(WorldPacket & recv_data); + + void HandleUpdateAccountData(WorldPacket& recvPacket); + void HandleRequestAccountData(WorldPacket& recvPacket); + void HandleSetActionButtonOpcode(WorldPacket& recvPacket); + + void HandleGameObjectUseOpcode(WorldPacket& recPacket); + void HandleMeetingStoneInfo(WorldPacket& recPacket); + + void HandleNameQueryOpcode(WorldPacket& recvPacket); + + void HandleQueryTimeOpcode(WorldPacket& recvPacket); + + void HandleCreatureQueryOpcode(WorldPacket& recvPacket); + + void HandleGameObjectQueryOpcode(WorldPacket& recvPacket); + + void HandleMoveWorldportAckOpcode(WorldPacket& recvPacket); + void HandleMoveWorldportAckOpcode(); // for server-side calls + + void HandleMovementOpcodes(WorldPacket& recvPacket); + void HandleSetActiveMoverOpcode(WorldPacket &recv_data); + void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data); + + void HandleRequestRaidInfoOpcode( WorldPacket & recv_data ); + + void HandleBattlefieldStatusOpcode(WorldPacket &recv_data); + void HandleBattleMasterHelloOpcode(WorldPacket &recv_data); + + void HandleGroupInviteOpcode(WorldPacket& recvPacket); + //void HandleGroupCancelOpcode(WorldPacket& recvPacket); + void HandleGroupAcceptOpcode(WorldPacket& recvPacket); + void HandleGroupDeclineOpcode(WorldPacket& recvPacket); + void HandleGroupUninviteNameOpcode(WorldPacket& recvPacket); + void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket); + void HandleGroupUninvite(uint64 guid, std::string name); + void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); + void HandleGroupLeaveOpcode(WorldPacket& recvPacket); + void HandleGroupPassOnLootOpcode( WorldPacket &recv_data ); + void HandleLootMethodOpcode(WorldPacket& recvPacket); + void HandleLootRoll( WorldPacket &recv_data ); + void HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ); + void HandleRaidIconTargetOpcode( WorldPacket & recv_data ); + void HandleRaidReadyCheckOpcode( WorldPacket & recv_data ); + void HandleRaidReadyCheckFinishOpcode( WorldPacket & recv_data ); + void HandleRaidConvertOpcode( WorldPacket & recv_data ); + void HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data ); + void HandleGroupAssistantOpcode( WorldPacket & recv_data ); + void HandleGroupPromoteOpcode( WorldPacket & recv_data ); + + void HandlePetitionBuyOpcode(WorldPacket& recv_data); + void HandlePetitionShowSignOpcode(WorldPacket& recv_data); + void HandlePetitionQueryOpcode(WorldPacket& recv_data); + void HandlePetitionRenameOpcode(WorldPacket& recv_data); + void HandlePetitionSignOpcode(WorldPacket& recv_data); + void HandlePetitionDeclineOpcode(WorldPacket& recv_data); + void HandleOfferPetitionOpcode(WorldPacket& recv_data); + void HandleTurnInPetitionOpcode(WorldPacket& recv_data); + + void HandleGuildQueryOpcode(WorldPacket& recvPacket); + void HandleGuildCreateOpcode(WorldPacket& recvPacket); + void HandleGuildInviteOpcode(WorldPacket& recvPacket); + void HandleGuildRemoveOpcode(WorldPacket& recvPacket); + void HandleGuildAcceptOpcode(WorldPacket& recvPacket); + void HandleGuildDeclineOpcode(WorldPacket& recvPacket); + void HandleGuildInfoOpcode(WorldPacket& recvPacket); + void HandleGuildEventLogOpcode(WorldPacket& recvPacket); + void HandleGuildRosterOpcode(WorldPacket& recvPacket); + void HandleGuildPromoteOpcode(WorldPacket& recvPacket); + void HandleGuildDemoteOpcode(WorldPacket& recvPacket); + void HandleGuildLeaveOpcode(WorldPacket& recvPacket); + void HandleGuildDisbandOpcode(WorldPacket& recvPacket); + void HandleGuildLeaderOpcode(WorldPacket& recvPacket); + void HandleGuildMOTDOpcode(WorldPacket& recvPacket); + void HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket); + void HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket); + void HandleGuildRankOpcode(WorldPacket& recvPacket); + void HandleGuildAddRankOpcode(WorldPacket& recvPacket); + void HandleGuildDelRankOpcode(WorldPacket& recvPacket); + void HandleGuildChangeInfoOpcode(WorldPacket& recvPacket); + void HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket); + + void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket); + void HandleTaxiQueryAvailableNodesOpcode(WorldPacket& recvPacket); + void HandleActivateTaxiOpcode(WorldPacket& recvPacket); + void HandleActivateTaxiFarOpcode(WorldPacket& recvPacket); + void HandleTaxiNextDestinationOpcode(WorldPacket& recvPacket); + + void HandleTabardVendorActivateOpcode(WorldPacket& recvPacket); + void HandleBankerActivateOpcode(WorldPacket& recvPacket); + void HandleBuyBankSlotOpcode(WorldPacket& recvPacket); + void HandleTrainerListOpcode(WorldPacket& recvPacket); + void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket); + void HandlePetitionShowListOpcode(WorldPacket& recvPacket); + void HandleGossipHelloOpcode(WorldPacket& recvPacket); + void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket); + void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket); + void HandleNpcTextQueryOpcode(WorldPacket& recvPacket); + void HandleBinderActivateOpcode(WorldPacket& recvPacket); + void HandleListStabledPetsOpcode(WorldPacket& recvPacket); + void HandleStablePet(WorldPacket& recvPacket); + void HandleUnstablePet(WorldPacket& recvPacket); + void HandleBuyStableSlot(WorldPacket& recvPacket); + void HandleStableRevivePet(WorldPacket& recvPacket); + void HandleStableSwapPet(WorldPacket& recvPacket); + + void HandleDuelAcceptedOpcode(WorldPacket& recvPacket); + void HandleDuelCancelledOpcode(WorldPacket& recvPacket); + + void HandleAcceptTradeOpcode(WorldPacket& recvPacket); + void HandleBeginTradeOpcode(WorldPacket& recvPacket); + void HandleBusyTradeOpcode(WorldPacket& recvPacket); + void HandleCancelTradeOpcode(WorldPacket& recvPacket); + void HandleClearTradeItemOpcode(WorldPacket& recvPacket); + void HandleIgnoreTradeOpcode(WorldPacket& recvPacket); + void HandleInitiateTradeOpcode(WorldPacket& recvPacket); + void HandleSetTradeGoldOpcode(WorldPacket& recvPacket); + void HandleSetTradeItemOpcode(WorldPacket& recvPacket); + void HandleUnacceptTradeOpcode(WorldPacket& recvPacket); + + void HandleAuctionHelloOpcode(WorldPacket& recvPacket); + void HandleAuctionListItems( WorldPacket & recv_data ); + void HandleAuctionListBidderItems( WorldPacket & recv_data ); + void HandleAuctionSellItem( WorldPacket & recv_data ); + void HandleAuctionRemoveItem( WorldPacket & recv_data ); + void HandleAuctionListOwnerItems( WorldPacket & recv_data ); + void HandleAuctionPlaceBid( WorldPacket & recv_data ); + + void HandleGetMail( WorldPacket & recv_data ); + void HandleSendMail( WorldPacket & recv_data ); + void HandleTakeMoney( WorldPacket & recv_data ); + void HandleTakeItem( WorldPacket & recv_data ); + void HandleMarkAsRead( WorldPacket & recv_data ); + void HandleReturnToSender( WorldPacket & recv_data ); + void HandleMailDelete( WorldPacket & recv_data ); + void HandleItemTextQuery( WorldPacket & recv_data); + void HandleMailCreateTextItem(WorldPacket & recv_data ); + void HandleMsgQueryNextMailtime(WorldPacket & recv_data ); + void HandleCancelChanneling(WorldPacket & recv_data ); + + void SendItemPageInfo( ItemPrototype *itemProto ); + void HandleSplitItemOpcode(WorldPacket& recvPacket); + void HandleSwapInvItemOpcode(WorldPacket& recvPacket); + void HandleDestroyItemOpcode(WorldPacket& recvPacket); + void HandleAutoEquipItemOpcode(WorldPacket& recvPacket); + void HandleItemQuerySingleOpcode(WorldPacket& recvPacket); + void HandleSellItemOpcode(WorldPacket& recvPacket); + void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket); + void HandleBuyItemOpcode(WorldPacket& recvPacket); + void HandleListInventoryOpcode(WorldPacket& recvPacket); + void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket); + void HandleReadItem(WorldPacket& recvPacket); + void HandleAutoEquipItemSlotOpcode(WorldPacket & recvPacket); + void HandleSwapItem( WorldPacket & recvPacket); + void HandleBuybackItem(WorldPacket & recvPacket); + void HandleAutoBankItemOpcode(WorldPacket& recvPacket); + void HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket); + void HandleWrapItemOpcode(WorldPacket& recvPacket); + + void HandleAttackSwingOpcode(WorldPacket& recvPacket); + void HandleAttackStopOpcode(WorldPacket& recvPacket); + void HandleSetSheathedOpcode(WorldPacket& recvPacket); + + void HandleUseItemOpcode(WorldPacket& recvPacket); + void HandleOpenItemOpcode(WorldPacket& recvPacket); + void HandleCastSpellOpcode(WorldPacket& recvPacket); + void HandleCancelCastOpcode(WorldPacket& recvPacket); + void HandleCancelAuraOpcode(WorldPacket& recvPacket); + void HandleCancelGrowthAuraOpcode(WorldPacket& recvPacket); + void HandleCancelAutoRepeatSpellOpcode(WorldPacket& recvPacket); + + void HandleLearnTalentOpcode(WorldPacket& recvPacket); + void HandleTalentWipeOpcode(WorldPacket& recvPacket); + void HandleUnlearnSkillOpcode(WorldPacket& recvPacket); + + void HandleQuestgiverStatusQueryOpcode(WorldPacket& recvPacket); + void HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& recvPacket); + void HandleQuestgiverHelloOpcode(WorldPacket& recvPacket); + void HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvPacket); + void HandleQuestgiverQuestQueryOpcode(WorldPacket& recvPacket); + void HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket); + void HandleQuestgiverRequestRewardOpcode(WorldPacket& recvPacket); + void HandleQuestQueryOpcode(WorldPacket& recvPacket); + void HandleQuestgiverCancel(WorldPacket& recv_data ); + void HandleQuestLogSwapQuest(WorldPacket& recv_data ); + void HandleQuestLogRemoveQuest(WorldPacket& recv_data); + void HandleQuestConfirmAccept(WorldPacket& recv_data); + void HandleQuestComplete(WorldPacket& recv_data); + void HandleQuestAutoLaunch(WorldPacket& recvPacket); + void HandleQuestPushToParty(WorldPacket& recvPacket); + void HandleQuestPushResult(WorldPacket& recvPacket); + + void HandleMessagechatOpcode(WorldPacket& recvPacket); + void HandleTextEmoteOpcode(WorldPacket& recvPacket); + void HandleChatIgnoredOpcode(WorldPacket& recvPacket); + + void HandleCorpseReclaimOpcode( WorldPacket& recvPacket ); + void HandleCorpseQueryOpcode( WorldPacket& recvPacket ); + void HandleResurrectResponseOpcode(WorldPacket& recvPacket); + void HandleSummonResponseOpcode(WorldPacket& recv_data); + + void HandleChannelJoin(WorldPacket& recvPacket); + void HandleChannelLeave(WorldPacket& recvPacket); + void HandleChannelList(WorldPacket& recvPacket); + void HandleChannelPassword(WorldPacket& recvPacket); + void HandleChannelSetOwner(WorldPacket& recvPacket); + void HandleChannelOwner(WorldPacket& recvPacket); + void HandleChannelModerator(WorldPacket& recvPacket); + void HandleChannelUnmoderator(WorldPacket& recvPacket); + void HandleChannelMute(WorldPacket& recvPacket); + void HandleChannelUnmute(WorldPacket& recvPacket); + void HandleChannelInvite(WorldPacket& recvPacket); + void HandleChannelKick(WorldPacket& recvPacket); + void HandleChannelBan(WorldPacket& recvPacket); + void HandleChannelUnban(WorldPacket& recvPacket); + void HandleChannelAnnounce(WorldPacket& recvPacket); + void HandleChannelModerate(WorldPacket& recvPacket); + void HandleChannelRosterQuery(WorldPacket& recvPacket); + void HandleChannelInfoQuery(WorldPacket& recvPacket); + void HandleChannelJoinNotify(WorldPacket& recvPacket); + + void HandleCompleteCinema(WorldPacket& recvPacket); + void HandleNextCinematicCamera(WorldPacket& recvPacket); + + void HandlePageQuerySkippedOpcode(WorldPacket& recvPacket); + void HandlePageQueryOpcode(WorldPacket& recvPacket); + + void HandleTutorialFlag ( WorldPacket & recv_data ); + void HandleTutorialClear( WorldPacket & recv_data ); + void HandleTutorialReset( WorldPacket & recv_data ); + + //Pet + void HandlePetAction( WorldPacket & recv_data ); + void HandlePetNameQuery( WorldPacket & recv_data ); + void HandlePetSetAction( WorldPacket & recv_data ); + void HandlePetAbandon( WorldPacket & recv_data ); + void HandlePetRename( WorldPacket & recv_data ); + void HandlePetCancelAuraOpcode( WorldPacket& recvPacket ); + void HandlePetUnlearnOpcode( WorldPacket& recvPacket ); + void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ); + void HandlePetCastSpellOpcode( WorldPacket& recvPacket ); + + void HandleSetActionBar(WorldPacket& recv_data); + + void HandleChangePlayerNameOpcode(WorldPacket& recv_data); + void HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data); + + void HandleTotemDestroy(WorldPacket& recv_data); + + //BattleGround + void HandleBattleGroundHelloOpcode(WorldPacket &recv_data); + void HandleBattleGroundJoinOpcode(WorldPacket &recv_data); + void HandleBattleGroundPlayerPositionsOpcode(WorldPacket& recv_data); + void HandleBattleGroundPVPlogdataOpcode( WorldPacket &recv_data ); + void HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ); + void HandleBattleGroundListOpcode( WorldPacket &recv_data ); + void HandleBattleGroundLeaveOpcode( WorldPacket &recv_data ); + void HandleBattleGroundArenaJoin( WorldPacket &recv_data ); + void HandleBattleGroundReportAFK( WorldPacket &recv_data ); + + void HandleWardenDataOpcode(WorldPacket& recv_data); + void HandleWorldTeleportOpcode(WorldPacket& recv_data); + void HandleMinimapPingOpcode(WorldPacket& recv_data); + void HandleRandomRollOpcode(WorldPacket& recv_data); + void HandleFarSightOpcode(WorldPacket& recv_data); + void HandleSetLfgOpcode(WorldPacket& recv_data); + void HandleDungeonDifficultyOpcode(WorldPacket& recv_data); + void HandleMoveFlyModeChangeAckOpcode(WorldPacket& recv_data); + void HandleLfgAutoJoinOpcode(WorldPacket& recv_data); + void HandleLfgCancelAutoJoinOpcode(WorldPacket& recv_data); + void HandleLfmAutoAddMembersOpcode(WorldPacket& recv_data); + void HandleLfmCancelAutoAddmembersOpcode(WorldPacket& recv_data); + void HandleLfgClearOpcode(WorldPacket& recv_data); + void HandleLfmSetNoneOpcode(WorldPacket& recv_data); + void HandleLfmSetOpcode(WorldPacket& recv_data); + void HandleLfgSetCommentOpcode(WorldPacket& recv_data); + void HandleNewUnknownOpcode(WorldPacket& recv_data); + void HandleChooseTitleOpcode(WorldPacket& recv_data); + void HandleRealmStateRequestOpcode(WorldPacket& recv_data); + void HandleAllowMoveAckOpcode(WorldPacket& recv_data); + void HandleWhoisOpcode(WorldPacket& recv_data); + void HandleResetInstancesOpcode(WorldPacket& recv_data); + + // Arena Team + void HandleInspectArenaStatsOpcode(WorldPacket& recv_data); + void HandleArenaTeamQueryOpcode(WorldPacket& recv_data); + void HandleArenaTeamRosterOpcode(WorldPacket& recv_data); + void HandleArenaTeamAddMemberOpcode(WorldPacket& recv_data); + void HandleArenaTeamInviteAcceptOpcode(WorldPacket& recv_data); + void HandleArenaTeamInviteDeclineOpcode(WorldPacket& recv_data); + void HandleArenaTeamLeaveOpcode(WorldPacket& recv_data); + void HandleArenaTeamRemoveFromTeamOpcode(WorldPacket& recv_data); + void HandleArenaTeamDisbandOpcode(WorldPacket& recv_data); + void HandleArenaTeamPromoteToCaptainOpcode(WorldPacket& recv_data); + + void HandleAreaSpiritHealerQueryOpcode(WorldPacket& recv_data); + void HandleAreaSpiritHealerQueueOpcode(WorldPacket& recv_data); + void HandleDismountOpcode(WorldPacket& recv_data); + void HandleSelfResOpcode(WorldPacket& recv_data); + void HandleReportSpamOpcode(WorldPacket& recv_data); + void HandleRequestPetInfoOpcode(WorldPacket& recv_data); + + // Socket gem + void HandleSocketOpcode(WorldPacket& recv_data); + + void HandleCancelTempItemEnchantmentOpcode(WorldPacket& recv_data); + + void HandleChannelEnableVoiceOpcode(WorldPacket & recv_data); + void HandleVoiceSettingsOpcode(WorldPacket& recv_data); + void HandleChannelVoiceChatQuery(WorldPacket& recv_data); + void HandleSetTaxiBenchmarkOpcode(WorldPacket& recv_data); + + // Guild Bank + void HandleGuildBankGetRights(WorldPacket& recv_data); + void HandleGuildBankGetMoneyAmount(WorldPacket& recv_data); + void HandleGuildBankQuery(WorldPacket& recv_data); + void HandleGuildBankTabColon(WorldPacket& recv_data); + void HandleGuildBankLog(WorldPacket& recv_data); + void HandleGuildBankDeposit(WorldPacket& recv_data); + void HandleGuildBankWithdraw(WorldPacket& recv_data); + void HandleGuildBankDepositItem(WorldPacket& recv_data); + void HandleGuildBankModifyTab(WorldPacket& recv_data); + void HandleGuildBankBuyTab(WorldPacket& recv_data); + void HandleGuildBankTabText(WorldPacket& recv_data); + void HandleGuildBankSetTabText(WorldPacket& recv_data); + private: + // private trade methods + void moveItems(Item* myItems[], Item* hisItems[]); + + // logging helper + void logUnexpectedOpcode(WorldPacket *packet, const char * reason); + + Player *_player; + WorldSocket *m_Socket; + std::string m_Address; + + uint32 _security; + uint32 _accountId; + uint8 m_expansion; + + time_t _logoutTime; + bool m_playerLoading; // code processed in LoginPlayer + bool m_playerLogout; // code processed in LogoutPlayer + bool m_playerRecentlyLogout; + LocaleConstant m_sessionDbcLocale; + int m_sessionDbLocaleIndex; + uint32 m_latency; + + ZThread::LockedQueue _recvQueue; +}; +#endif +/// @} diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp new file mode 100644 index 000000000..4189d84be --- /dev/null +++ b/src/game/WorldSocket.cpp @@ -0,0 +1,1022 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "WorldSocket.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Util.h" +#include "World.h" +#include "WorldPacket.h" +#include "SharedDefines.h" +#include "ByteBuffer.h" +#include "AddonHandler.h" +#include "Opcodes.h" +#include "Database/DatabaseEnv.h" +#include "Auth/Sha1.h" +#include "WorldSession.h" +#include "WorldSocketMgr.h" +#include "Log.h" +#include "WorldLog.h" + +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct ServerPktHeader +{ + uint16 size; + uint16 cmd; +}; + +struct ClientPktHeader +{ + uint16 size; + uint32 cmd; +}; + +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif + +WorldSocket::WorldSocket (void) : +WorldHandler (), +m_Session (0), +m_RecvWPct (0), +m_RecvPct (), +m_Header (sizeof (ClientPktHeader)), +m_OutBuffer (0), +m_OutBufferSize (65536), +m_OutActive (false), +m_Seed (static_cast (rand32 ())), +m_OverSpeedPings (0), +m_LastPingTime (ACE_Time_Value::zero) +{ + this->reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED); +} + +WorldSocket::~WorldSocket (void) +{ + if (m_RecvWPct) + delete m_RecvWPct; + + if (m_OutBuffer) + m_OutBuffer->release (); + + this->closing_ = true; + + this->peer ().close (); + + WorldPacket* pct; + while (m_PacketQueue.dequeue_head (pct) == 0) + delete pct; +} + +bool WorldSocket::IsClosed (void) const +{ + return this->closing_; +} + +void WorldSocket::CloseSocket (void) +{ + { + ACE_GUARD (LockType, Guard, m_OutBufferLock); + + if (this->closing_) + return; + + this->closing_ = true; + + this->peer ().close_writer (); + } + + { + ACE_GUARD (LockType, Guard, m_SessionLock); + + m_Session = NULL; + } +} + +const std::string& WorldSocket::GetRemoteAddress (void) const +{ + return m_Address; +} + +int WorldSocket::SendPacket (const WorldPacket& pct) +{ + ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1); + + if (this->closing_) + return -1; + + // Dump outgoing packet. + if (sWorldLog.LogWorld ()) + { + sWorldLog.Log ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n", + (uint32) get_handle (), + pct.size (), + LookupOpcodeName (pct.GetOpcode ()), + pct.GetOpcode ()); + + uint32 p = 0; + while (p < pct.size ()) + { + for (uint32 j = 0; j < 16 && p < pct.size (); j++) + sWorldLog.Log ("%.2X ", const_cast(pct)[p++]); + + sWorldLog.Log ("\n"); + } + + sWorldLog.Log ("\n\n"); + } + + if (iSendPacket (pct) == -1) + { + WorldPacket* npct; + + ACE_NEW_RETURN (npct, WorldPacket (pct), -1); + + // NOTE maybe check of the size of the queue can be good ? + // to make it bounded instead of unbounded + if (m_PacketQueue.enqueue_tail (npct) == -1) + { + delete npct; + sLog.outError ("WorldSocket::SendPacket: m_PacketQueue.enqueue_tail failed"); + return -1; + } + } + + return 0; +} + +long WorldSocket::AddReference (void) +{ + return static_cast (this->add_reference ()); +} + +long WorldSocket::RemoveReference (void) +{ + return static_cast (this->remove_reference ()); +} + +int WorldSocket::open (void *a) +{ + ACE_UNUSED_ARG (a); + + // Prevent double call to this func. + if (m_OutBuffer) + return -1; + + // This will also prevent the socket from being Updated + // while we are initializing it. + m_OutActive = true; + + // Hook for the manager. + if (sWorldSocketMgr->OnSocketOpen (this) == -1) + return -1; + + // Allocate the buffer. + ACE_NEW_RETURN (m_OutBuffer, ACE_Message_Block (m_OutBufferSize), -1); + + // Store peer address. + ACE_INET_Addr remote_addr; + + if (this->peer ().get_remote_addr (remote_addr) == -1) + { + sLog.outError ("WorldSocket::open: peer ().get_remote_addr errno = %s", ACE_OS::strerror (errno)); + return -1; + } + + m_Address = remote_addr.get_host_addr (); + + // Send startup packet. + WorldPacket packet (SMSG_AUTH_CHALLENGE, 4); + packet << m_Seed; + + if (SendPacket (packet) == -1) + return -1; + + // Register with ACE Reactor + if (this->reactor ()->register_handler(this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::WRITE_MASK) == -1) + { + sLog.outError ("WorldSocket::open: unable to register client handler errno = %s", ACE_OS::strerror (errno)); + return -1; + } + + // reactor takes care of the socket from now on + this->remove_reference (); + + return 0; +} + +int WorldSocket::close (int) +{ + this->shutdown (); + + this->closing_ = true; + + this->remove_reference (); + + return 0; +} + +int WorldSocket::handle_input (ACE_HANDLE) +{ + if (this->closing_) + return -1; + + switch (this->handle_input_missing_data ()) + { + case -1 : + { + if ((errno == EWOULDBLOCK) || + (errno == EAGAIN)) + { + return this->Update (); // interesting line ,isnt it ? + } + + DEBUG_LOG ("WorldSocket::handle_input: Peer error closing connection errno = %s", ACE_OS::strerror (errno)); + + errno = ECONNRESET; + return -1; + } + case 0: + { + DEBUG_LOG ("WorldSocket::handle_input: Peer has closed connection\n"); + + errno = ECONNRESET; + return -1; + } + case 1: + return 1; + default: + return this->Update (); // another interesting line ;) + } + + ACE_NOTREACHED(return -1); +} + +int WorldSocket::handle_output (ACE_HANDLE) +{ + ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1); + + if (this->closing_) + return -1; + + const size_t send_len = m_OutBuffer->length (); + + if (send_len == 0) + return this->cancel_wakeup_output (Guard); + +#ifdef MSG_NOSIGNAL + ssize_t n = this->peer ().send (m_OutBuffer->rd_ptr (), send_len, MSG_NOSIGNAL); +#else + ssize_t n = this->peer ().send (m_OutBuffer->rd_ptr (), send_len); +#endif // MSG_NOSIGNAL + + if (n == 0) + return -1; + else if (n == -1) + { + if (errno == EWOULDBLOCK || errno == EAGAIN) + return this->schedule_wakeup_output (Guard); + + return -1; + } + else if (n < send_len) //now n > 0 + { + m_OutBuffer->rd_ptr (static_cast (n)); + + // move the data to the base of the buffer + m_OutBuffer->crunch (); + + return this->schedule_wakeup_output (Guard); + } + else //now n == send_len + { + m_OutBuffer->reset (); + + if (!iFlushPacketQueue ()) + return this->cancel_wakeup_output (Guard); + else + return this->schedule_wakeup_output (Guard); + } + + ACE_NOTREACHED (return 0); +} + +int WorldSocket::handle_close (ACE_HANDLE h, ACE_Reactor_Mask) +{ + // Critical section + { + ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1); + + this->closing_ = true; + + if (h == ACE_INVALID_HANDLE) + this->peer ().close_writer (); + } + + // Critical section + { + ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); + + m_Session = NULL; + } + + return 0; +} + +int WorldSocket::Update (void) +{ + if (this->closing_) + return -1; + + if (m_OutActive || m_OutBuffer->length () == 0) + return 0; + + return this->handle_output (this->get_handle ()); +} + +int WorldSocket::handle_input_header (void) +{ + ACE_ASSERT (m_RecvWPct == NULL); + + ACE_ASSERT (m_Header.length () == sizeof (ClientPktHeader)); + + m_Crypt.DecryptRecv ((ACE_UINT8*) m_Header.rd_ptr (), sizeof (ClientPktHeader)); + + ClientPktHeader& header = *((ClientPktHeader*) m_Header.rd_ptr ()); + + header.size = ACE_NTOHS (header.size); + +#if ACE_BYTE_ORDER == ACE_BIG_ENDIAN + header.cmd = ACE_SWAP_LONG (header.cmd) +#endif // ACE_BIG_ENDIAN + + if ((header.size < 4) || + (header.size > 10240) || + (header.cmd < 0) || + (header.cmd > 10240) + ) + { + sLog.outError ("WorldSocket::handle_input_header: client sent mailformed packet size = %d , cmd = %d", + header.size, + header.cmd); + + errno = EINVAL; + return -1; + } + + header.size -= 4; + + ACE_NEW_RETURN (m_RecvWPct, WorldPacket ((uint16) header.cmd, header.size), -1); + + if(header.size > 0) + { + m_RecvWPct->resize (header.size); + m_RecvPct.base ((char*) m_RecvWPct->contents (), m_RecvWPct->size ()); + } + else + { + ACE_ASSERT(m_RecvPct.space() == 0); + } + + return 0; +} + +int WorldSocket::handle_input_payload (void) +{ + // set errno properly here on error !!! + // now have a header and payload + + ACE_ASSERT (m_RecvPct.space () == 0); + ACE_ASSERT (m_Header.space () == 0); + ACE_ASSERT (m_RecvWPct != NULL); + + const int ret = this->ProcessIncoming (m_RecvWPct); + + m_RecvPct.base (NULL, 0); + m_RecvPct.reset (); + m_RecvWPct = NULL; + + m_Header.reset (); + + if (ret == -1) + errno = EINVAL; + + return ret; +} + +int WorldSocket::handle_input_missing_data (void) +{ + char buf [1024]; + + ACE_Data_Block db ( sizeof (buf), + ACE_Message_Block::MB_DATA, + buf, + 0, + 0, + ACE_Message_Block::DONT_DELETE, + 0); + + ACE_Message_Block message_block(&db, + ACE_Message_Block::DONT_DELETE, + 0); + + const size_t recv_size = message_block.space (); + + const ssize_t n = this->peer ().recv (message_block.wr_ptr (), + recv_size); + + if (n <= 0) + return n; + + message_block.wr_ptr (n); + + while (message_block.length () > 0) + { + if (m_Header.space () > 0) + { + //need to recieve the header + const size_t to_header = (message_block.length () > m_Header.space () ? m_Header.space () : message_block.length ()); + m_Header.copy (message_block.rd_ptr (), to_header); + message_block.rd_ptr (to_header); + + if (m_Header.space () > 0) + { + //couldnt recieve the whole header this time + ACE_ASSERT (message_block.length () == 0); + errno = EWOULDBLOCK; + return -1; + } + + //we just recieved nice new header + if (this->handle_input_header () == -1) + { + ACE_ASSERT ((errno != EWOULDBLOCK) && (errno != EAGAIN)); + return -1; + } + } + + // Its possible on some error situations that this happens + // for example on closing when epoll recieves more chunked data and stuff + // hope this is not hack ,as proper m_RecvWPct is asserted around + if (!m_RecvWPct) + { + sLog.outError ("Forsing close on input m_RecvWPct = NULL"); + errno = EINVAL; + return -1; + } + + // We have full readed header, now check the data payload + if (m_RecvPct.space () > 0) + { + //need more data in the payload + const size_t to_data = (message_block.length () > m_RecvPct.space () ? m_RecvPct.space () : message_block.length ()); + m_RecvPct.copy (message_block.rd_ptr (), to_data); + message_block.rd_ptr (to_data); + + if (m_RecvPct.space () > 0) + { + //couldnt recieve the whole data this time + ACE_ASSERT (message_block.length () == 0); + errno = EWOULDBLOCK; + return -1; + } + } + + //just recieved fresh new payload + if (this->handle_input_payload () == -1) + { + ACE_ASSERT ((errno != EWOULDBLOCK) && (errno != EAGAIN)); + return -1; + } + } + + return n == recv_size ? 1 : 2; +} + +int WorldSocket::cancel_wakeup_output (GuardType& g) +{ + if (!m_OutActive) + return 0; + + m_OutActive = false; + + g.release (); + + if (this->reactor ()->cancel_wakeup + (this, ACE_Event_Handler::WRITE_MASK) == -1) + { + // would be good to store errno from reactor with errno guard + sLog.outError ("WorldSocket::cancel_wakeup_output"); + return -1; + } + + return 0; +} + +int WorldSocket::schedule_wakeup_output (GuardType& g) +{ + if (m_OutActive) + return 0; + + m_OutActive = true; + + g.release (); + + if (this->reactor ()->schedule_wakeup + (this, ACE_Event_Handler::WRITE_MASK) == -1) + { + sLog.outError ("WorldSocket::schedule_wakeup_output"); + return -1; + } + + return 0; +} + +int WorldSocket::ProcessIncoming (WorldPacket* new_pct) +{ + ACE_ASSERT (new_pct); + + // manage memory ;) + ACE_Auto_Ptr aptr (new_pct); + + const ACE_UINT16 opcode = new_pct->GetOpcode (); + + if (this->closing_) + return -1; + + // dump recieved packet + if (sWorldLog.LogWorld ()) + { + sWorldLog.Log ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n", + (uint32) get_handle (), + new_pct->size (), + LookupOpcodeName (new_pct->GetOpcode ()), + new_pct->GetOpcode ()); + + uint32 p = 0; + while (p < new_pct->size ()) + { + for (uint32 j = 0; j < 16 && p < new_pct->size (); j++) + sWorldLog.Log ("%.2X ", (*new_pct)[p++]); + sWorldLog.Log ("\n"); + } + sWorldLog.Log ("\n\n"); + } + + // like one switch ;) + if (opcode == CMSG_PING) + { + return HandlePing (*new_pct); + } + else if (opcode == CMSG_AUTH_SESSION) + { + if (m_Session) + { + sLog.outError ("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again"); + return -1; + } + + return HandleAuthSession (*new_pct); + } + else if (opcode == CMSG_KEEP_ALIVE) + { + DEBUG_LOG ("CMSG_KEEP_ALIVE ,size: %d", new_pct->size ()); + + return 0; + } + else + { + ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); + + if (m_Session != NULL) + { + // OK ,give the packet to WorldSession + aptr.release (); + // WARNINIG here we call it with locks held. + // Its possible to cause deadlock if QueuePacket calls back + m_Session->QueuePacket (new_pct); + return 0; + } + else + { + sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = ", opcode); + return -1; + } + } + + ACE_NOTREACHED (return 0); +} + +int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) +{ + // NOTE: ATM the socket is singlethreaded, have this in mind ... + uint8 digest[20]; + uint32 clientSeed; + uint32 unk2; + uint32 BuiltNumberClient; + uint32 id, security; + uint8 expansion = 0; + LocaleConstant locale; + std::string account; + Sha1Hash sha1; + BigNumber v, s, g, N, x, I; + WorldPacket packet, SendAddonPacked; + + BigNumber K; + + if (recvPacket.size () < (4 + 4 + 1 + 4 + 20)) + { + sLog.outError ("WorldSocket::HandleAuthSession: wrong packet size"); + return -1; + } + + // Read the content of the packet + recvPacket >> BuiltNumberClient; // for now no use + recvPacket >> unk2; + recvPacket >> account; + + if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20)) + { + sLog.outError ("WorldSocket::HandleAuthSession: wrong packet size second check"); + return -1; + } + + recvPacket >> clientSeed; + recvPacket.read (digest, 20); + + DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u", + BuiltNumberClient, + unk2, + account.c_str (), + clientSeed); + + // Get the account information from the realmd database + std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below + loginDatabase.escape_string (safe_account); + // No SQL injection, username escaped. + + QueryResult *result = + loginDatabase.PQuery ("SELECT " + "id, " //0 + "gmlevel, " //1 + "sessionkey, " //2 + "last_ip, " //3 + "locked, " //4 + "sha_pass_hash, " //5 + "v, " //6 + "s, " //7 + "expansion, " //8 + "mutetime, " //9 + "locale " //10 + "FROM account " + "WHERE username = '%s'", + safe_account.c_str ()); + + // Stop if the account is not found + if (!result) + { + packet.Initialize (SMSG_AUTH_RESPONSE, 1); + packet << uint8 (AUTH_UNKNOWN_ACCOUNT); + + SendPacket (packet); + + sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); + return -1; + } + + Field* fields = result->Fetch (); + + expansion = fields[8].GetUInt8 () && sWorld.getConfig (CONFIG_EXPANSION) > 0; + + N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); + g.SetDword (7); + I.SetHexStr (fields[5].GetString ()); + + //In case of leading zeros in the I hash, restore them + uint8 mDigest[SHA_DIGEST_LENGTH]; + memset (mDigest, 0, SHA_DIGEST_LENGTH); + + if (I.GetNumBytes () <= SHA_DIGEST_LENGTH) + memcpy (mDigest, I.AsByteArray (), I.GetNumBytes ()); + + std::reverse (mDigest, mDigest + SHA_DIGEST_LENGTH); + + s.SetHexStr (fields[7].GetString ()); + sha1.UpdateData (s.AsByteArray (), s.GetNumBytes ()); + sha1.UpdateData (mDigest, SHA_DIGEST_LENGTH); + sha1.Finalize (); + x.SetBinary (sha1.GetDigest (), sha1.GetLength ()); + v = g.ModExp (x, N); + + const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free() + const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free() + const char* vold = fields[6].GetString (); + + DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v_old: %s v_new: %s", + sStr, + vold, + vStr); + + loginDatabase.PExecute ("UPDATE account " + "SET " + "v = '0', " + "s = '0' " + "WHERE username = '%s'", + safe_account.c_str ()); + + if (!vold || strcmp (vStr, vold)) + { + packet.Initialize (SMSG_AUTH_RESPONSE, 1); + packet << uint8 (AUTH_UNKNOWN_ACCOUNT); + SendPacket (packet); + delete result; + OPENSSL_free ((void*) sStr); + OPENSSL_free ((void*) vStr); + + sLog.outBasic ("WorldSocket::HandleAuthSession: User not logged."); + return -1; + } + + OPENSSL_free ((void*) sStr); + OPENSSL_free ((void*) vStr); + + ///- Re-check ip locking (same check as in realmd). + if (fields[4].GetUInt8 () == 1) // if ip is locked + { + if (strcmp (fields[3].GetString (), GetRemoteAddress ().c_str ())) + { + packet.Initialize (SMSG_AUTH_RESPONSE, 1); + packet << uint8 (AUTH_FAILED); + SendPacket (packet); + + delete result; + sLog.outBasic ("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); + return -1; + } + } + + id = fields[0].GetUInt32 (); + security = fields[1].GetUInt16 (); + K.SetHexStr (fields[2].GetString ()); + + time_t mutetime = time_t (fields[9].GetUInt64 ()); + + locale = LocaleConstant (fields[10].GetUInt8 ()); + if (locale >= MAX_LOCALE) + locale = LOCALE_enUS; + + delete result; + + // Re-check account ban (same check as in realmd) + QueryResult *banresult = + loginDatabase.PQuery ("SELECT " + "bandate, " + "unbandate " + "FROM account_banned " + "WHERE id = '%u' " + "AND active = 1", + id); + + if (banresult) // if account banned + { + packet.Initialize (SMSG_AUTH_RESPONSE, 1); + packet << uint8 (AUTH_BANNED); + SendPacket (packet); + + delete banresult; + + sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); + return -1; + } + + // Check locked state for server + AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit (); + + if (allowedAccountType > SEC_PLAYER && security < allowedAccountType) + { + WorldPacket Packet (SMSG_AUTH_RESPONSE, 1); + Packet << uint8 (AUTH_UNAVAILABLE); + + SendPacket (packet); + + sLog.outBasic ("WorldSocket::HandleAuthSession: User tryes to login but his security level is not enough"); + return -1; + } + + // Check that Key and account name are the same on client and server + Sha1Hash sha; + + uint32 t = 0; + uint32 seed = m_Seed; + + sha.UpdateData (account); + sha.UpdateData ((uint8 *) & t, 4); + sha.UpdateData ((uint8 *) & clientSeed, 4); + sha.UpdateData ((uint8 *) & seed, 4); + sha.UpdateBigNumbers (&K, NULL); + sha.Finalize (); + + if (memcmp (sha.GetDigest (), digest, 20)) + { + packet.Initialize (SMSG_AUTH_RESPONSE, 1); + packet << uint8 (AUTH_FAILED); + + SendPacket (packet); + + sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); + return -1; + } + + std::string address = this->GetRemoteAddress (); + + DEBUG_LOG ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", + account.c_str (), + address.c_str ()); + + // Update the last_ip in the database + // No SQL injection, username escaped. + loginDatabase.escape_string (address); + + loginDatabase.PExecute ("UPDATE account " + "SET last_ip = '%s' " + "WHERE username = '%s'", + address.c_str (), + safe_account.c_str ()); + + // NOTE ATM the socket is singlethreaded, have this in mind ... + ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1); + + m_Crypt.SetKey (&K); + m_Crypt.Init (); + + // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec + ACE_OS::sleep (ACE_Time_Value (0, 10000)); + + sWorld.AddSession (this->m_Session); + + // Create and send the Addon packet + if (sAddOnHandler.BuildAddonPacket (&recvPacket, &SendAddonPacked)) + SendPacket (SendAddonPacked); + + return 0; +} + +int WorldSocket::HandlePing (WorldPacket& recvPacket) +{ + uint32 ping; + uint32 latency; + + if (recvPacket.size () < 8) + { + sLog.outError ("WorldSocket::_HandlePing wrong packet size"); + return -1; + } + + // Get the ping packet content + recvPacket >> ping; + recvPacket >> latency; + + if (m_LastPingTime == ACE_Time_Value::zero) + m_LastPingTime = ACE_OS::gettimeofday (); // for 1st ping + else + { + ACE_Time_Value cur_time = ACE_OS::gettimeofday (); + ACE_Time_Value diff_time (cur_time); + diff_time -= m_LastPingTime; + m_LastPingTime = cur_time; + + if (diff_time < ACE_Time_Value (27)) + { + ++m_OverSpeedPings; + + uint32 max_count = sWorld.getConfig (CONFIG_MAX_OVERSPEED_PINGS); + + if (max_count && m_OverSpeedPings > max_count) + { + ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); + + if (m_Session && m_Session->GetSecurity () == SEC_PLAYER) + { + sLog.outError ("WorldSocket::HandlePing: Player kicked for " + "overspeeded pings adress = %s", + GetRemoteAddress ().c_str ()); + + return -1; + } + } + } + else + m_OverSpeedPings = 0; + } + + // critical section + { + ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); + + if (m_Session) + m_Session->SetLatency (latency); + else + { + sLog.outError ("WorldSocket::HandlePing: peer sent CMSG_PING, " + "but is not authenticated or got recently kicked," + " adress = %s", + this->GetRemoteAddress ().c_str ()); + return -1; + } + } + + WorldPacket packet (SMSG_PONG, 4); + packet << ping; + return this->SendPacket (packet); +} + +int WorldSocket::iSendPacket (const WorldPacket& pct) +{ + if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader)) + { + errno = ENOBUFS; + return -1; + } + + ServerPktHeader header; + + header.cmd = pct.GetOpcode (); + +#if ACE_BYTE_ORDER == ACE_BIG_ENDIAN + header.cmd = ACE_SWAP_WORD (header.cmd) +#endif + + header.size = (uint16) pct.size () + 2; + header.size = ACE_HTONS (header.size); + + m_Crypt.EncryptSend ((uint8*) & header, sizeof (header)); + + if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1) + ACE_ASSERT (false); + + if (!pct.empty ()) + if (m_OutBuffer->copy ((char*) pct.contents (), pct.size ()) == -1) + ACE_ASSERT (false); + + return 0; +} + +bool WorldSocket::iFlushPacketQueue () +{ + WorldPacket *pct; + bool haveone = false; + + while (m_PacketQueue.dequeue_head (pct) == 0) + { + if (iSendPacket (*pct) == -1) + { + if (m_PacketQueue.enqueue_head (pct) == -1) + { + delete pct; + sLog.outError ("WorldSocket::iFlushPacketQueue m_PacketQueue->enqueue_head"); + return false; + } + + break; + } + else + { + haveone = true; + delete pct; + } + } + + return haveone; +} diff --git a/src/game/WorldSocket.h b/src/game/WorldSocket.h new file mode 100644 index 000000000..afce966d8 --- /dev/null +++ b/src/game/WorldSocket.h @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \addtogroup u2w User to World Communication + * @{ + * \file WorldSocket.h + * \author Derex + */ + +#ifndef _WORLDSOCKET_H +#define _WORLDSOCKET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Common.h" +#include "Auth/AuthCrypt.h" + +class ACE_Message_Block; +class WorldPacket; +class WorldSession; + +/// Handler that can communicate over stream sockets. +typedef ACE_Svc_Handler WorldHandler; + +/** + * WorldSocket. + * + * This class is responsible for the comunication with + * remote clients. + * Most methods return -1 on failure. + * The class uses refferece counting. + * + * For output the class uses one buffer (64K usually) and + * a queue where it stores packet if there is no place on + * the queue. The reason this is done, is because the server + * does realy a lot of small-size writes to it, and it doesn't + * scale well to allocate memory for every. When something is + * writen to the output buffer the socket is not immideately + * activated for output (again for the same reason), there + * is 10ms celling (thats why there is Update() method). + * This concept is simmilar to TCP_CORK, but TCP_CORK + * usses 200ms celling. As result overhead generated by + * sending packets from "producer" threads is minimal, + * and doing a lot of writes with small size is tollerated. + * + * The calls to Upate () method are managed by WorldSocketMgr + * and ReactorRunnable. + * + * For input ,the class uses one 1024 bytes buffer on stack + * to which it does recv() calls. And then recieved data is + * distributed where its needed. 1024 matches pritey well the + * traffic generated by client for now. + * + * The input/output do speculative reads/writes (AKA it tryes + * to read all data avaible in the kernel buffer or tryes to + * write everything avaible in userspace buffer), + * which is ok for using with Level and Edge Trigered IO + * notification. + * + */ +class WorldSocket : protected WorldHandler +{ +public: + /// Declare some friends + friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >; + friend class WorldSocketMgr; + friend class ReactorRunnable; + + /// Declare the acceptor for this class + typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor; + + /// Mutex type used for various syncronizations. + typedef ACE_Thread_Mutex LockType; + typedef ACE_Guard GuardType; + + /// Queue for storing packets for which there is no space. + typedef ACE_Unbounded_Queue< WorldPacket* > PacketQueueT; + + /// Check if socket is closed. + bool IsClosed (void) const; + + /// Close the socket. + void CloseSocket (void); + + /// Get address of connected peer. + const std::string& GetRemoteAddress (void) const; + + /// Send A packet on the socket, this function is reentrant. + /// @param pct packet to send + /// @return -1 of failure + int SendPacket (const WorldPacket& pct); + + /// Add refference to this object. + long AddReference (void); + + /// Remove refference to this object. + long RemoveReference (void); + +protected: + /// things called by ACE framework. + WorldSocket (void); + virtual ~WorldSocket (void); + + /// Called on open ,the void* is the acceptor. + virtual int open (void *); + + /// Called on failures inside of the acceptor, don't call from your code. + virtual int close (int); + + /// Called when we can read from the socket. + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + + /// Called when the socket can write. + virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE); + + /// Called when connection is closed or error happens. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Called by WorldSocketMgr/ReactorRunnable. + int Update (void); + +private: + /// Helper functions for processing incoming data. + int handle_input_header (void); + int handle_input_payload (void); + int handle_input_missing_data (void); + + /// Help functions to mark/unmark the socket for output. + /// @param g the guard is for m_OutBufferLock, the function will release it + int cancel_wakeup_output (GuardType& g); + int schedule_wakeup_output (GuardType& g); + + /// process one incoming packet. + /// @param new_pct received packet ,note that you need to delete it. + int ProcessIncoming (WorldPacket* new_pct); + + /// Called by ProcessIncoming() on CMSG_AUTH_SESSION. + int HandleAuthSession (WorldPacket& recvPacket); + + /// Called by ProcessIncoming() on CMSG_PING. + int HandlePing (WorldPacket& recvPacket); + + /// Try to write WorldPacket to m_OutBuffer ,return -1 if no space + /// Need to be called with m_OutBufferLock lock held + int iSendPacket (const WorldPacket& pct); + + /// Flush m_PacketQueue if there are packets in it + /// Need to be called with m_OutBufferLock lock held + /// @return true if it wrote to the buffer ( AKA you need + /// to mark the socket for output ). + bool iFlushPacketQueue (); + +private: + /// Time in which the last ping was received + ACE_Time_Value m_LastPingTime; + + /// Keep track of overspeed pings ,to prevent ping flood. + uint32 m_OverSpeedPings; + + /// Address of the remote peer + std::string m_Address; + + /// Class used for managing encryption of the headers + AuthCrypt m_Crypt; + + /// Mutex lock to protect m_Session + LockType m_SessionLock; + + /// Session to which recieved packets are routed + WorldSession* m_Session; + + /// here are stored the fragmens of the recieved data + WorldPacket* m_RecvWPct; + + /// This block actually refers to m_RecvWPct contents, + /// which alows easy and safe writing to it. + /// It wont free memory when its deleted. m_RecvWPct takes care of freeing. + ACE_Message_Block m_RecvPct; + + /// Fragment of the recieved header. + ACE_Message_Block m_Header; + + /// Mutex for protecting otuput related data. + LockType m_OutBufferLock; + + /// Buffer used for writing output. + ACE_Message_Block *m_OutBuffer; + + /// Size of the m_OutBuffer. + size_t m_OutBufferSize; + + /// Here are stored packets for which there was no space on m_OutBuffer, + /// this alows not-to kick player if its buffer is overflowed. + PacketQueueT m_PacketQueue; + + /// True if the socket is registered with the reactor for output + bool m_OutActive; + + uint32 m_Seed; +}; + +#endif /* _WORLDSOCKET_H */ + +/// @} diff --git a/src/game/WorldSocketMgr.cpp b/src/game/WorldSocketMgr.cpp new file mode 100644 index 000000000..341030c6d --- /dev/null +++ b/src/game/WorldSocketMgr.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2005-2008,2007 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file WorldSocketMgr.cpp + * \ingroup u2w + * \author Derex + */ + +#include "WorldSocketMgr.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Log.h" +#include "Common.h" +#include "Config/ConfigEnv.h" +#include "Database/DatabaseEnv.h" +#include "WorldSocket.h" + +/** + * This is a helper class to WorldSocketMgr ,that manages + * network threads, and assigning connections from acceptor thread + * to other network threads + */ +class ReactorRunnable : protected ACE_Task_Base +{ +public: + + ReactorRunnable () : + m_ThreadId (-1), + m_Connections (0), + m_Reactor (0) + { + ACE_Reactor_Impl* imp = 0; + +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + imp = new ACE_Dev_Poll_Reactor (); + + imp->max_notify_iterations (128); + imp->restart (1); +#else + imp = new ACE_TP_Reactor (); + imp->max_notify_iterations (128); +#endif + + m_Reactor = new ACE_Reactor (imp, 1); + } + + virtual + ~ReactorRunnable () + { + this->Stop (); + this->Wait (); + + if (m_Reactor) + delete m_Reactor; + } + + void + Stop () + { + m_Reactor->end_reactor_event_loop (); + } + + int + Start () + { + if (m_ThreadId != -1) + return -1; + + return (m_ThreadId = this->activate ()); + } + + void + Wait () + { + ACE_Task_Base::wait (); + } + + long + Connections () + { + return static_cast (m_Connections.value ()); + } + + int + AddSocket (WorldSocket* sock) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, Guard, m_NewSockets_Lock, -1); + + ++m_Connections; + sock->AddReference(); + sock->reactor (m_Reactor); + m_NewSockets.insert (sock); + + return 0; + } + + ACE_Reactor* GetReactor () + { + return m_Reactor; + } + +protected: + + void + AddNewSockets () + { + ACE_GUARD (ACE_Thread_Mutex, Guard, m_NewSockets_Lock); + + if (m_NewSockets.empty ()) + return; + + for (SocketSet::iterator i = m_NewSockets.begin (); i != m_NewSockets.end (); ++i) + { + WorldSocket* sock = (*i); + + if (sock->IsClosed ()) + { + sock->RemoveReference (); + --m_Connections; + } + else + m_Sockets.insert (sock); + } + + m_NewSockets.clear (); + } + + virtual int + svc (void) + { + DEBUG_LOG ("Network Thread Starting"); + + WorldDatabase.ThreadStart (); + + ACE_ASSERT (m_Reactor); + + SocketSet::iterator i, t; + + while (!m_Reactor->reactor_event_loop_done ()) + { + // dont be too smart to move this outside the loop + // the run_reactor_event_loop will modify interval + ACE_Time_Value interval (0, 10000); + + if (m_Reactor->run_reactor_event_loop (interval) == -1) + break; + + AddNewSockets (); + + for (i = m_Sockets.begin (); i != m_Sockets.end ();) + { + if ((*i)->Update () == -1) + { + t = i; + i++; + (*t)->CloseSocket (); + (*t)->RemoveReference (); + --m_Connections; + m_Sockets.erase (t); + } + else + i++; + } + } + + WorldDatabase.ThreadEnd (); + + DEBUG_LOG ("Network Thread Exitting"); + + return 0; + } + +private: + typedef ACE_Atomic_Op AtomicInt; + typedef std::set SocketSet; + + ACE_Reactor* m_Reactor; + AtomicInt m_Connections; + int m_ThreadId; + + SocketSet m_Sockets; + + SocketSet m_NewSockets; + ACE_Thread_Mutex m_NewSockets_Lock; +}; + + + +WorldSocketMgr::WorldSocketMgr () : +m_NetThreadsCount (0), +m_NetThreads (0), +m_SockOutKBuff (-1), +m_SockOutUBuff (65536), +m_UseNoDelay (true), +m_Acceptor (0) {} + +WorldSocketMgr::~WorldSocketMgr () +{ + if (m_NetThreads) + delete [] m_NetThreads; + + if(m_Acceptor) + delete m_Acceptor; +} + +int +WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address) +{ + m_UseNoDelay = sConfig.GetBoolDefault ("Network.TcpNodelay", true); + + int num_threads = sConfig.GetIntDefault ("Network.Threads", 1); + + if (num_threads <= 0) + { + sLog.outError ("Network.Threads is wrong in your config file"); + return -1; + } + + m_NetThreadsCount = static_cast (num_threads + 1); + + m_NetThreads = new ReactorRunnable[m_NetThreadsCount]; + + sLog.outBasic ("Max alowed socket connections %d",ACE::max_handles ()); + + m_SockOutKBuff = sConfig.GetIntDefault ("Network.OutKBuff", -1); // -1 means use default + + m_SockOutUBuff = sConfig.GetIntDefault ("Network.OutUBuff", 65536); + + if ( m_SockOutUBuff <= 0 ) + { + sLog.outError ("Network.OutUBuff is wrong in your config file"); + return -1; + } + + WorldSocket::Acceptor *acc = new WorldSocket::Acceptor; + m_Acceptor = acc; + + ACE_INET_Addr listen_addr (port, address); + + if (acc->open (listen_addr, m_NetThreads[0].GetReactor (), ACE_NONBLOCK) == -1) + { + sLog.outError ("Failed to open acceptor ,check if the port is free"); + return -1; + } + + for (size_t i = 0; i < m_NetThreadsCount; ++i) + m_NetThreads[i].Start (); + + return 0; +} + +int +WorldSocketMgr::StartNetwork (ACE_UINT16 port, const char* address) +{ + if (!sLog.IsOutDebug ()) + ACE_Log_Msg::instance ()->priority_mask (LM_ERROR, ACE_Log_Msg::PROCESS); + + if (this->StartReactiveIO (port, address) == -1) + return -1; + + return 0; +} + +void +WorldSocketMgr::StopNetwork () +{ + if (m_Acceptor) + { + WorldSocket::Acceptor* acc = dynamic_cast (m_Acceptor); + + if (acc) + acc->close (); + } + + if (m_NetThreadsCount != 0) + { + for (size_t i = 0; i < m_NetThreadsCount; ++i) + m_NetThreads[i].Stop (); + } + + this->Wait (); +} + +void +WorldSocketMgr::Wait () +{ + if (m_NetThreadsCount != 0) + { + for (size_t i = 0; i < m_NetThreadsCount; ++i) + m_NetThreads[i].Wait (); + } +} + +int +WorldSocketMgr::OnSocketOpen (WorldSocket* sock) +{ + // set some options here + if (m_SockOutKBuff >= 0) + if (sock->peer ().set_option (SOL_SOCKET, + SO_SNDBUF, + (void*) & m_SockOutKBuff, + sizeof (int)) == -1 && errno != ENOTSUP) + { + sLog.outError ("WorldSocketMgr::OnSocketOpen set_option SO_SNDBUF"); + return -1; + } + + static const int ndoption = 1; + + // Set TCP_NODELAY. + if (m_UseNoDelay) + if (sock->peer ().set_option (ACE_IPPROTO_TCP, + TCP_NODELAY, + (void*) & ndoption, + sizeof (int)) == -1) + { + sLog.outError ("WorldSocketMgr::OnSocketOpen: peer ().set_option TCP_NODELAY errno = %s", ACE_OS::strerror (errno)); + return -1; + } + + sock->m_OutBufferSize = static_cast (m_SockOutUBuff); + + // we skip the Acceptor Thread + size_t min = 1; + + ACE_ASSERT (m_NetThreadsCount >= 1); + + for (size_t i = 1; i < m_NetThreadsCount; ++i) + if (m_NetThreads[i].Connections () < m_NetThreads[min].Connections ()) + min = i; + + return m_NetThreads[min].AddSocket (sock); + + return 0; +} + +WorldSocketMgr* +WorldSocketMgr::Instance () +{ + return ACE_Singleton::instance(); +} diff --git a/src/game/WorldSocketMgr.h b/src/game/WorldSocketMgr.h new file mode 100644 index 000000000..07595c820 --- /dev/null +++ b/src/game/WorldSocketMgr.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2005-2008,2007 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \addtogroup u2w User to World Communication + * @{ + * \file WorldSocketMgr.h + * \author Derex + */ + +#ifndef __WORLDSOCKETMGR_H +#define __WORLDSOCKETMGR_H + +#include +#include +#include + +class WorldSocket; +class ReactorRunnable; +class ACE_Event_Handler; + +/// Manages all sockets connected to peers and network threads +class WorldSocketMgr +{ +public: + friend class WorldSocket; + friend class ACE_Singleton; + + /// Start network, listen at address:port . + int StartNetwork (ACE_UINT16 port, const char* address); + + /// Stops all network threads, It will wait for all running threads . + void StopNetwork (); + + /// Wait untill all network threads have "joined" . + void Wait (); + + /// Make this class singleton . + static WorldSocketMgr* Instance (); + +private: + int OnSocketOpen(WorldSocket* sock); + + int StartReactiveIO(ACE_UINT16 port, const char* address); + +private: + WorldSocketMgr (); + virtual ~WorldSocketMgr (); + + ReactorRunnable* m_NetThreads; + size_t m_NetThreadsCount; + + int m_SockOutKBuff; + int m_SockOutUBuff; + bool m_UseNoDelay; + + ACE_Event_Handler* m_Acceptor; +}; + +#define sWorldSocketMgr WorldSocketMgr::Instance () + + +#endif +/// @} diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp new file mode 100644 index 000000000..83754be27 --- /dev/null +++ b/src/game/debugcmds.cpp @@ -0,0 +1,517 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "Player.h" +#include "Opcodes.h" +#include "Chat.h" +#include "Log.h" +#include "Unit.h" +#include "ObjectAccessor.h" +#include "GossipDef.h" +#include "Language.h" +#include "MapManager.h" +#include + +bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/) +{ + Object *obj = getSelectedUnit(); + + if(!obj) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + return true; + } + + SendSysMessage(LANG_NOT_IMPLEMENTED); + + return true; +} + +bool ChatHandler::HandleDebugSpellFailCommand(const char* args) +{ + if(!args) + return false; + + char* px = strtok((char*)args, " "); + if(!px) + return false; + + uint8 failnum = (uint8)atoi(px); + + WorldPacket data(SMSG_CAST_FAILED, 5); + data << (uint32)133; + data << failnum; + m_session->SendPacket(&data); + + return true; +} + +bool ChatHandler::HandleSetPoiCommand(const char* args) +{ + Player *pPlayer = m_session->GetPlayer(); + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + return true; + } + + if(!args) + return false; + + char* icon_text = strtok((char*)args, " "); + char* flags_text = strtok(NULL, " "); + if(!icon_text || !flags_text) + return false; + + uint32 icon = atol(icon_text); + if ( icon < 0 ) + icon = 0; + + uint32 flags = atol(flags_text); + + sLog.outDetail("Command : POI, NPC = %u, icon = %u flags = %u", target->GetGUIDLow(), icon,flags); + pPlayer->PlayerTalkClass->SendPointOfInterest(target->GetPositionX(), target->GetPositionY(), Poi_Icon(icon), flags, 30, "Test POI"); + return true; +} + +bool ChatHandler::HandleEquipErrorCommand(const char* args) +{ + if(!args) + return false; + + uint8 msg = atoi(args); + m_session->GetPlayer()->SendEquipError(msg, 0, 0); + return true; +} + +bool ChatHandler::HandleSellErrorCommand(const char* args) +{ + if(!args) + return false; + + uint8 msg = atoi(args); + m_session->GetPlayer()->SendSellError(msg, 0, 0, 0); + return true; +} + +bool ChatHandler::HandleBuyErrorCommand(const char* args) +{ + if(!args) + return false; + + uint8 msg = atoi(args); + m_session->GetPlayer()->SendBuyError(msg, 0, 0, 0); + return true; +} + +bool ChatHandler::HandleSendOpcodeCommand(const char* args) +{ + Unit *unit = getSelectedUnit(); + if (!unit || (unit->GetTypeId() != TYPEID_PLAYER)) + unit = m_session->GetPlayer(); + + std::ifstream ifs("opcode.txt"); + if(ifs.bad()) + return false; + + uint32 opcode; + ifs >> opcode; + + WorldPacket data(opcode, 0); + + while(!ifs.eof()) + { + std::string type; + ifs >> type; + + if(type == "uint8") + { + uint8 val1; + ifs >> val1; + data << val1; + } + else if(type == "uint16") + { + uint16 val2; + ifs >> val2; + data << val2; + } + else if(type == "uint32") + { + uint32 val3; + ifs >> val3; + data << val3; + } + else if(type == "uint64") + { + uint64 val4; + ifs >> val4; + data << val4; + } + else if(type == "float") + { + float val5; + ifs >> val5; + data << val5; + } + else if(type == "string") + { + std::string val6; + ifs >> val6; + data << val6; + } + else if(type == "pguid") + { + data.append(unit->GetPackGUID()); + } + else + { + sLog.outDebug("Sending opcode: unknown type %s", type.c_str()); + } + } + ifs.close(); + sLog.outDebug("Sending opcode %u", data.GetOpcode()); + data.hexlike(); + ((Player*)unit)->GetSession()->SendPacket(&data); + PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName()); + return true; +} + +bool ChatHandler::HandleUpdateWorldStateCommand(const char* args) +{ + char* w = strtok((char*)args, " "); + char* s = strtok(NULL, " "); + + if (!w || !s) + return false; + + uint32 world = (uint32)atoi(w); + uint32 state = (uint32)atoi(s); + m_session->GetPlayer()->SendUpdateWorldState(world, state); + return true; +} + +bool ChatHandler::HandlePlaySound2Command(const char* args) +{ + if(!args) + return false; + + uint32 soundid = atoi(args); + m_session->GetPlayer()->PlaySound(soundid, false); + return true; +} + +//Send notification in channel +bool ChatHandler::HandleSendChannelNotifyCommand(const char* args) +{ + if(!args) + return false; + + const char *name = "test"; + uint8 code = atoi(args); + + WorldPacket data(SMSG_CHANNEL_NOTIFY, (1+10)); + data << code; // notify type + data << name; // channel name + data << uint32(0); + data << uint32(0); + m_session->SendPacket(&data); + return true; +} + +//Send notification in chat +bool ChatHandler::HandleSendChatMsgCommand(const char* args) +{ + if(!args) + return false; + + const char *msg = "testtest"; + uint8 type = atoi(args); + WorldPacket data; + ChatHandler::FillMessageData(&data, m_session, type, 0, "chan", m_session->GetPlayer()->GetGUID(), msg, m_session->GetPlayer()); + m_session->SendPacket(&data); + return true; +} + +bool ChatHandler::HandleSendQuestPartyMsgCommand(const char* args) +{ + uint32 msg = atol((char*)args); + if (msg >= 0) + m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), msg); + return true; +} + +bool ChatHandler::HandleGetLootRecipient(const char* args) +{ + Creature* target = getSelectedCreature(); + if(!target) + return false; + + PSendSysMessage("loot recipient: %s", target->hasLootRecipient()?(target->GetLootRecipient()?target->GetLootRecipient()->GetName():"offline"):"no loot recipient"); + return true; +} + +bool ChatHandler::HandleSendQuestInvalidMsgCommand(const char* args) +{ + uint32 msg = atol((char*)args); + if (msg >= 0) + m_session->GetPlayer()->SendCanTakeQuestResponse(msg); + return true; +} + +bool ChatHandler::HandleGetItemState(const char* args) +{ + if (!args) + return false; + + std::string state_str = args; + + ItemUpdateState state = ITEM_UNCHANGED; + bool list_queue = false, check_all = false; + if (state_str == "unchanged") state = ITEM_UNCHANGED; + else if (state_str == "changed") state = ITEM_CHANGED; + else if (state_str == "new") state = ITEM_NEW; + else if (state_str == "removed") state = ITEM_REMOVED; + else if (state_str == "queue") list_queue = true; + else if (state_str == "check_all") check_all = true; + else return false; + + Player* player = getSelectedPlayer(); + if (!player) player = m_session->GetPlayer(); + + if (!list_queue && !check_all) + { + state_str = "The player has the following " + state_str + " items: "; + SendSysMessage(state_str.c_str()); + for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + { + if(i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END) + continue; + + Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (!item) continue; + if (!item->IsBag()) + { + if (item->GetState() == state) + PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID())); + } + else + { + Bag *bag = (Bag*)item; + const ItemPrototype *proto = bag->GetProto(); + for (uint8 j = 0; j < proto->ContainerSlots; ++j) + { + Item* item = bag->GetItemByPos(j); + if (item && item->GetState() == state) + PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID())); + } + } + } + } + + if (list_queue) + { + std::vector &updateQueue = player->GetItemUpdateQueue(); + for(size_t i = 0; i < updateQueue.size(); i++) + { + Item *item = updateQueue[i]; + if(!item) continue; + + Bag *container = item->GetContainer(); + uint8 bag_slot = container ? container->GetSlot() : uint8(INVENTORY_SLOT_BAG_0); + + std::string st; + switch(item->GetState()) + { + case ITEM_UNCHANGED: st = "unchanged"; break; + case ITEM_CHANGED: st = "changed"; break; + case ITEM_NEW: st = "new"; break; + case ITEM_REMOVED: st = "removed"; break; + } + + PSendSysMessage("bag: %d slot: %d guid: %d - state: %s", bag_slot, item->GetSlot(), item->GetGUIDLow(), st.c_str()); + } + if (updateQueue.empty()) + PSendSysMessage("updatequeue empty"); + } + + if (check_all) + { + bool error = false; + std::vector &updateQueue = player->GetItemUpdateQueue(); + for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + { + if(i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END) + continue; + + Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (!item) continue; + + if (item->GetSlot() != i) + { + PSendSysMessage("item at slot %d, guid %d has an incorrect slot value: %d", i, item->GetGUIDLow(), item->GetSlot()); + error = true; continue; + } + + if (item->GetOwnerGUID() != player->GetGUID()) + { + PSendSysMessage("for the item at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow()); + error = true; continue; + } + + if (Bag *container = item->GetContainer()) + { + PSendSysMessage("item at slot: %d guid: %d has a container (slot: %d, guid: %d) but shouldnt!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow()); + error = true; continue; + } + + if (item->IsInUpdateQueue()) + { + uint16 qp = item->GetQueuePos(); + if (qp > updateQueue.size()) + { + PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", item->GetSlot(), item->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] == NULL) + { + PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", item->GetSlot(), item->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] != item) + { + PSendSysMessage("item at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", item->GetSlot(), item->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow()); + error = true; continue; + } + } + else if (item->GetState() != ITEM_UNCHANGED) + { + PSendSysMessage("item at slot: %d guid: %d is not in queue but should be (state: %d)!", item->GetSlot(), item->GetGUIDLow(), item->GetState()); + error = true; continue; + } + + if(item->IsBag()) + { + Bag *bag = (Bag*)item; + const ItemPrototype *proto = bag->GetProto(); + for (uint8 j = 0; j < proto->ContainerSlots; ++j) + { + Item* item = bag->GetItemByPos(j); + if (!item) continue; + + if (item->GetSlot() != j) + { + PSendSysMessage("the item in bag %d slot %d, guid %d has an incorrect slot value: %d", bag->GetSlot(), j, item->GetGUIDLow(), item->GetSlot()); + error = true; continue; + } + + if (item->GetOwnerGUID() != player->GetGUID()) + { + PSendSysMessage("for the item in bag %d at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow()); + error = true; continue; + } + + Bag *container = item->GetContainer(); + if (!container) + { + PSendSysMessage("the item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow()); + error = true; continue; + } + + if (container != bag) + { + PSendSysMessage("the item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow()); + error = true; continue; + } + + if (item->IsInUpdateQueue()) + { + uint16 qp = item->GetQueuePos(); + if (qp > updateQueue.size()) + { + PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] == NULL) + { + PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] != item) + { + PSendSysMessage("item in bag: %d at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow()); + error = true; continue; + } + } + else if (item->GetState() != ITEM_UNCHANGED) + { + PSendSysMessage("item in bag: %d at slot: %d guid: %d is not in queue but should be (state: %d)!", bag->GetSlot(), item->GetSlot(), item->GetGUIDLow(), item->GetState()); + error = true; continue; + } + } + } + } + + for(size_t i = 0; i < updateQueue.size(); i++) + { + Item *item = updateQueue[i]; + if(!item) continue; + + if (item->GetOwnerGUID() != player->GetGUID()) + { + PSendSysMessage("queue(%d): for the an item (guid %d), the owner's guid (%d) and player's guid (%d) don't match!", i, item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow()); + error = true; continue; + } + + if (item->GetQueuePos() != i) + { + PSendSysMessage("queue(%d): for the an item (guid %d), the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow()); + error = true; continue; + } + + if (item->GetState() == ITEM_REMOVED) continue; + Item *test = player->GetItemByPos( item->GetBagSlot(), item->GetSlot()); + + if (test == NULL) + { + PSendSysMessage("queue(%d): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have an item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow()); + error = true; continue; + } + + if (test != item) + { + PSendSysMessage("queue(%d): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow()); + error = true; continue; + } + } + if (!error) + SendSysMessage("All OK!"); + } + + return true; +} diff --git a/src/game/tools.cpp b/src/game/tools.cpp new file mode 100644 index 000000000..f5ebde52d --- /dev/null +++ b/src/game/tools.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Tools.h" + +// THIS CAN BE A LOT FASTER +bool readGUID(WorldPacket & data, uint64& guid) +{ + if(data.rpos()+1 > data.size()) + return false; + + uint8 guidmark=0; + uint8 bit; + uint8 shiftdata=0x1; + uint64 Temp=0; + + guid = 0; + + data >> guidmark; + for(int i=0;i<8;i++) + { + if(guidmark & shiftdata) + { + Temp = 0; + + if(data.rpos()+1 > data.size()) + return false; + + data >> bit; + Temp = bit; + Temp <<= i*8; + guid |= Temp; + } + shiftdata=shiftdata<<1; + } + + return true; +} + +void writeGUID(WorldPacket & data, uint64 & guid) +{ + uint8 RAWmask = 0; + uint8 PackedGuid[8] = {0,0,0,0,0,0,0,0}; + + int j = 1; + uint8 * test = (uint8*)&guid; + + if (*test) + { + PackedGuid[j] = *test; + RAWmask |= 1; + ++j; + } + if (*(test+1)) + { + PackedGuid[j] = *(test+1); + RAWmask |= 2; + ++j; + } + if (*(test+2)) + { + PackedGuid[j] = *(test+2); + RAWmask |= 4; + ++j; + } + if (*(test+3)) + { + PackedGuid[j] = *(test+3); + RAWmask |= 8; + ++j; + } + if (*(test+4)) + { + PackedGuid[j] = *(test+4); + RAWmask |= 16; + ++j; + } + if (*(test+5)) + { + PackedGuid[j] = *(test+5); + RAWmask |= 32; + ++j; + } + if (*(test+6)) + { + PackedGuid[j] = *(test+6); + RAWmask |= 64; + ++j; + } + if (*(test+7)) + { + PackedGuid[j] = *(test+7); + RAWmask |= 128; + ++j; + } + PackedGuid[0] = RAWmask; + + data.append(PackedGuid,j); +} diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp new file mode 100644 index 000000000..9a31ce60d --- /dev/null +++ b/src/mangosd/CliRunnable.cpp @@ -0,0 +1,1265 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup mangosd +/// @{ +/// \file + +#include "Common.h" +#include "Language.h" +#include "Log.h" +#include "World.h" +#include "ScriptCalls.h" +#include "GlobalEvents.h" +#include "ObjectMgr.h" +#include "WorldSession.h" +#include "SystemConfig.h" +#include "Config/ConfigEnv.h" +#include "Util.h" +#include "AccountMgr.h" +#include "CliRunnable.h" +#include "MapManager.h" +#include "PlayerDump.h" +#include "Player.h" + +//CliCommand and CliCommandHolder are defined in World.h to avoid cyclic deps + +//func prototypes must be defined + +void CliHelp(char*,pPrintf); +void CliInfo(char*,pPrintf); +void CliBan(char*,pPrintf); +void CliBanList(char*,pPrintf); +void CliRemoveBan(char*,pPrintf); +void CliSetGM(char*,pPrintf); +void CliListGM(char*,pPrintf); +void CliVersion(char*,pPrintf); +void CliExit(char*,pPrintf); +void CliIdleRestart(char*,pPrintf zprintf); +void CliRestart(char*,pPrintf zprintf); +void CliIdleShutdown(char*,pPrintf zprintf); +void CliShutdown(char*,pPrintf zprintf); +void CliBroadcast(char*,pPrintf); +void CliCreate(char*,pPrintf); +void CliDelete(char*,pPrintf); +void CliCharDelete(char *,pPrintf); +void CliLoadScripts(char*,pPrintf); +void CliKick(char*,pPrintf); +void CliTele(char*,pPrintf); +void CliMotd(char*,pPrintf); +void CliCorpses(char*,pPrintf); +void CliSetLogLevel(char*,pPrintf); +void CliUpTime(char*,pPrintf); +void CliSetAddon(char*,pPrintf); +void CliWritePlayerDump(char*,pPrintf); +void CliLoadPlayerDump(char*,pPrintf); +void CliSave(char*,pPrintf); +void CliSend(char*,pPrintf); +void CliPLimit(char*,pPrintf); +void CliSetPassword(char*,pPrintf); +/// Table of known commands +const CliCommand Commands[]= +{ + {"help", & CliHelp,"Display this help message"}, + {"broadcast", & CliBroadcast,"Announce in-game message"}, + {"create", & CliCreate,"Create account"}, + {"delete", & CliDelete,"Delete account and characters"}, + {"chardelete", & CliCharDelete,"Delete character"}, + {"info", & CliInfo,"Display Server infomation"}, + {"uptime", & CliUpTime, "Displays the server uptime"}, + {"motd", & CliMotd,"Change or display motd"}, + {"kick", & CliKick,"Kick user"}, + {"ban", & CliBan,"Ban account|ip"}, + {"listbans", & CliBanList,"List bans"}, + {"unban", & CliRemoveBan,"Remove ban from account|ip"}, + {"setgm", & CliSetGM,"Edit user privileges"}, + {"setpass", & CliSetPassword,"Set password for account"}, + {"setaddon", & CliSetAddon,"Set user expansion addon level allowed"}, + {"listgm", & CliListGM,"Display user privileges"}, + {"loadscripts", & CliLoadScripts,"Load script library"}, + {"setloglevel", & CliSetLogLevel,"Set Log Level"}, + {"corpses", & CliCorpses,"Manually call corpses erase global even code"}, + {"version", & CliVersion,"Display server version"}, + {"idlerestart", & CliIdleRestart,"Restart server with some delay when there are no active connections remaining"}, + {"restart", & CliRestart,"Restart server with some delay"}, + {"idleshutdown", & CliIdleShutdown,"Shutdown server with some delay when there are no active connections remaining"}, + {"shutdown", & CliShutdown,"Shutdown server with some delay"}, + {"exit", & CliExit,"Shutdown server NOW"}, + {"writepdump", &CliWritePlayerDump,"Write a player dump to a file"}, + {"loadpdump", &CliLoadPlayerDump,"Load a player dump from a file"}, + {"saveall", &CliSave,"Save all players"}, + {"send", &CliSend,"Send message to a player"}, + {"tele", &CliTele,"Teleport player to location"}, + {"plimit", &CliPLimit,"Show or set player login limitations"} +}; +/// \todo Need some pragma pack? Else explain why in a comment. +#define CliTotalCmds sizeof(Commands)/sizeof(CliCommand) + +#if PLATFORM == PLATFORM_WINDOWS +int utf8printf(const char* str,...) +{ + UTF8PRINTF(stdout,str,1); + return 0; +} +#define UTF8ZPRINTF utf8printf +#else +#define UTF8ZPRINTF printf +#endif + +/// Create a character dump file +void CliWritePlayerDump(char*command,pPrintf zprintf) +{ + char * file = strtok(command, " "); + char * p2 = strtok(NULL, " "); + if(!file || !p2) + { + zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); + return; + } + + std::string name; + if(!consoleToUtf8(p2,name)) // convert from console encoding to utf8 + return; + + if(!normalizePlayerName(name)) + { + zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); + return; + } + + uint32 guid = objmgr.GetPlayerGUIDByName(name); + if(!guid) + guid = atoi(p2); + + if(!guid) + { + zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); + return; + } + + PlayerDumpWriter().WriteDump(file, guid); +} + +/// Load a character from a dump file +void CliLoadPlayerDump(char*command,pPrintf zprintf) +{ + char * file = strtok(command, " "); + char * acc = strtok(NULL, " "); + if (!file ||!acc) + { + zprintf("Syntax is: loadpdump $filename $account ($newname) ($newguid)\r\n"); + return; + } + + uint32 account_id = objmgr.GetAccountByAccountName(acc); + if(!account_id) + { + account_id = atoi(acc); + if(account_id) + { + std::string acc_name; + if(!objmgr.GetAccountNameByAccount(account_id,acc_name)) + { + zprintf("Failed to load the character! Account not exist.\r\n"); + return; + } + } + else + { + zprintf("Failed to load the character! Account not exist.\r\n"); + return; + } + } + + char * name_str = strtok(NULL, " "); + char * guid_str = name_str ? strtok(NULL, " ") : NULL; + + uint32 guid = guid_str ? atoi(guid_str) : 0; + + std::string name; + if(name_str) + { + if(!consoleToUtf8(name_str,name)) // convert from console encoding to utf8 + return; + + if(!normalizePlayerName(name)) + { + zprintf("Syntax is: loadpdump $filename $account ($newname) ($newguid)\r\n"); + return; + } + } + + if(PlayerDumpReader().LoadDump(file, account_id, name, guid)) + zprintf("Character loaded successfully!\r\n"); + else + zprintf("Failed to load the character!\r\n"); +} + +/// Reload the scripts and notify the players +void CliLoadScripts(char*command,pPrintf zprintf) +{ + char const *del=strtok(command," "); + if (!del) + del=""; + if(!LoadScriptingModule(del)) // Error report is already done by LoadScriptingModule + return; + + sWorld.SendWorldText(LANG_SCRIPTS_RELOADED); +} + +/// Delete a user account and all associated characters in this realm +/// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account +void CliDelete(char*command,pPrintf zprintf) +{ + ///- Get the account name from the command line + char *account_name_str=strtok(command," "); + if(!account_name_str) + { + // \r\n is used because this function can also be called from RA + zprintf("Syntax is: delete $account\r\n"); + return; + } + + std::string account_name; + if(!consoleToUtf8(account_name_str,account_name)) // convert from console encoding to utf8 + return; + + AccountOpResult result = accmgr.DeleteAccount(accmgr.GetId(account_name)); + switch(result) + { + case AOR_OK: + zprintf("We deleted account: %s\r\n",account_name.c_str()); + break; + case AOR_NAME_NOT_EXIST: + zprintf("User %s does not exist\r\n",account_name.c_str()); + break; + case AOR_DB_INTERNAL_ERROR: + zprintf("User %s NOT deleted (probably sql file format was updated)\r\n",account_name.c_str()); + break; + default: + zprintf("User %s NOT deleted (unknown error)\r\n",account_name.c_str()); + break; + } +} + +void CliCharDelete(char*command,pPrintf zprintf) +{ + char *character_name_str = strtok(command," "); + + if(!character_name_str) + { + zprintf("Syntax is: chardelete $character_name\r\n"); + return; + } + + std::string character_name; + if(!consoleToUtf8(character_name_str,character_name)) // convert from console encoding to utf8 + return; + + if(!normalizePlayerName(character_name)) + { + zprintf("Syntax is: chardelete $character_name\r\n"); + return; + } + + Player *player = objmgr.GetPlayer(character_name.c_str()); + + uint64 character_guid; + uint32 account_id; + + if(player) + { + character_guid = player->GetGUID(); + account_id = player->GetSession()->GetAccountId(); + player->GetSession()->KickPlayer(); + } + else + { + character_guid = objmgr.GetPlayerGUIDByName(character_name); + if(!character_guid) + { + zprintf("Player %s not found!\r\n",character_name.c_str()); + return; + } + + account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); + } + + Player::DeleteFromDB(character_guid, account_id, true); + zprintf("Player %s (Guid: %u AccountId: %u) deleted\r\n",character_name.c_str(),GUID_LOPART(character_guid),account_id); +} + +/// Broadcast a message to the World +void CliBroadcast(char *text,pPrintf zprintf) +{ + std::string textUtf8; + if(!consoleToUtf8(text,textUtf8)) // convert from console encoding to utf8 + return; + + sWorld.SendWorldText(LANG_SYSTEMMESSAGE,textUtf8.c_str()); + zprintf("Broadcasting to the world: %s\r\n",textUtf8.c_str()); +} + +/// Print the list of commands and associated description +void CliHelp(char*,pPrintf zprintf) +{ + for (unsigned int x=0;x 0"); + + if (!resultDB) + return; + + ///- Display the list of account/characters online + zprintf("=====================================================================\r\n"); + zprintf("| Account | Character | IP | GM | TBC |\r\n"); + zprintf("=====================================================================\r\n"); + + ///- Circle through accounts + do + { + Field *fieldsDB = resultDB->Fetch(); + std::string name = fieldsDB[0].GetCppString(); + uint32 account = fieldsDB[1].GetUInt32(); + + ///- Get the username, last IP and GM level of each account + // No SQL injection. account is uint32. + // 0 1 2 3 + QueryResult *resultLogin = loginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account); + + if(resultLogin) + { + Field *fieldsLogin = resultLogin->Fetch(); + zprintf("|%15s| %20s | %15s |%4d|%5d|\r\n", + fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32()); + + delete resultLogin; + } + else + zprintf("| | %20s | |||\r\n",name.c_str()); + + }while(resultDB->NextRow()); + + delete resultDB; + + zprintf("=====================================================================\r\n"); +} + +/// Display a list of banned accounts and ip addresses +void CliBanList(char*,pPrintf zprintf) +{ + bool found = false; + ///- Get the list of banned accounts and display them + QueryResult *result = loginDatabase.Query("SELECT id,username FROM account WHERE id IN (SELECT id FROM account_banned WHERE active = 1)"); + if(result) + { + found = true; + + zprintf("Currently Banned Accounts:\r\n"); + zprintf("===============================================================================\r\n"); + zprintf("| Account | BanDate | UnbanDate | Banned By | Ban Reason |\r\n"); + do + { + zprintf("-------------------------------------------------------------------------------\r\n"); + Field *fields = result->Fetch(); + // No SQL injection. id is uint32. + QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u AND active = 1 ORDER BY unbandate", fields[0].GetUInt32()); + if (banInfo) + { + Field *fields2 = banInfo->Fetch(); + do + { + time_t t_ban = fields2[0].GetUInt64(); + tm* aTm_ban = localtime(&t_ban); + zprintf("|%-15.15s|", fields[1].GetString()); + zprintf("%02d-%02d-%02d %02d:%02d|", aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min); + if ( fields2[0].GetUInt64() == fields2[1].GetUInt64() ) + zprintf(" permanent |"); + else + { + time_t t_unban = fields2[1].GetUInt64(); + tm* aTm_unban = localtime(&t_unban); + zprintf("%02d-%02d-%02d %02d:%02d|",aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min); + } + zprintf("%-15.15s|%-15.15s|\r\n",fields2[2].GetString(),fields2[3].GetString()); + }while ( banInfo->NextRow() ); + delete banInfo; + } + }while( result->NextRow() ); + zprintf("===============================================================================\r\n"); + delete result; + } + + ///- Get the list of banned IP addresses and display them + result = loginDatabase.Query( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) ORDER BY unbandate" ); + if(result) + { + found = true; + + zprintf("Currently Banned IPs:\r\n"); + zprintf("===============================================================================\r\n"); + zprintf("| IP | BanDate | UnbanDate | Banned By | Ban Reason |\r\n"); + do + { + zprintf("-------------------------------------------------------------------------------\r\n"); + Field *fields = result->Fetch(); + time_t t_ban = fields[1].GetUInt64(); + tm* aTm_ban = localtime(&t_ban); + zprintf("|%-15.15s|", fields[0].GetString()); + zprintf("%02d-%02d-%02d %02d:%02d|", aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min); + if ( fields[1].GetUInt64() == fields[2].GetUInt64() ) + zprintf(" permanent |"); + else + { + time_t t_unban = fields[2].GetUInt64(); + tm* aTm_unban = localtime(&t_unban); + zprintf("%02d-%02d-%02d %02d:%02d|", aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min); + } + zprintf("%-15.15s|%-15.15s|\r\n", fields[3].GetString(), fields[4].GetString()); + }while( result->NextRow() ); + zprintf("===============================================================================\r\n"); + delete result; + } + + if(!found) + zprintf("We do not have banned users\r\n"); +} + +/// Ban an IP address or a user account +void CliBan(char*command,pPrintf zprintf) +{ + ///- Get the command parameter + char* type_str = strtok((char*)command, " "); + char* nameOrIP_str = strtok(NULL, " "); + char* duration_str = strtok(NULL," "); + char* reason_str = strtok(NULL,""); + + if(!type_str||!nameOrIP_str||!duration_str||!reason_str)// ?!? input of single char "0"-"9" wouldn't detect when with: || !atoi(duration) + { + zprintf("Syntax: ban account|ip|character $AccountOrIpOrCharacter $duration[s|m|h|d] $reason \r\n"); + return; + } + + std::string type; + if(!consoleToUtf8(type_str,type)) // convert from console encoding to utf8 + return; + + std::string nameOrIP; + if(!consoleToUtf8(nameOrIP_str,nameOrIP)) // convert from console encoding to utf8 + return; + + std::string duration; + if(!consoleToUtf8(duration_str,duration)) // convert from console encoding to utf8 + return; + + std::string reason; + if(!consoleToUtf8(reason_str,reason)) // convert from console encoding to utf8 + return; + + switch (sWorld.BanAccount(type, nameOrIP, duration, reason, "Set by console.")) + { + case BAN_SUCCESS: + if(atoi(duration_str)>0) + zprintf("%s is banned for %s. Reason: %s.\r\n",nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration_str),true,false).c_str(),reason.c_str()); + else + zprintf("%s is banned permanently. Reason: %s.\r\n",nameOrIP.c_str(),reason.c_str()); + break; + case BAN_NOTFOUND: + zprintf("%s %s not found\r\n", type.c_str(), nameOrIP.c_str()); + break; + case BAN_SYNTAX_ERROR: + zprintf("Syntax: ban account|ip|character $AccountOrIpOrCharacter $duration[s|m|h|d] $reason \r\n"); + break; + } +} + +/// Display %MaNGOS version +void CliVersion(char*,pPrintf zprintf) +{ + //<--maybe better append to info cmd + zprintf( "%s (world-daemon)\r\n", _FULLVERSION ); +} + +/// Unban an IP adress or a user account +void CliRemoveBan(char *command,pPrintf zprintf) +{ + ///- Get the command parameter + char *type_str = strtok(command," "); + char *nameorip_str = strtok(NULL," "); + if(!nameorip_str||!type_str) + { + zprintf("Syntax is: unban account|ip|character $nameorip\r\n"); + return; + } + + std::string type; + if(!consoleToUtf8(type_str,type)) // convert from console encoding to utf8 + return; + + std::string nameorip; + if(!consoleToUtf8(nameorip_str,nameorip)) // convert from console encoding to utf8 + return; + + if (!sWorld.RemoveBanAccount(type, nameorip)) + zprintf("%s %s not found\r\n", type.c_str(), nameorip.c_str()); + else + zprintf("We removed ban from %s: %s\r\n",type_str,nameorip.c_str()); +} + +/// Display the list of GMs +void CliListGM(char*,pPrintf zprintf) +{ + + ///- Get the accounts with GM Level >0 + Field *fields; + + QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" ); + if(result) + { + + zprintf("Current gamemasters:\r\n"); + zprintf("========================\r\n"); + zprintf("| Account | GM |\r\n"); + zprintf("========================\r\n"); + + ///- Circle through them. Display username and GM level + do + { + fields = result->Fetch(); + zprintf("|%15s|", fields[0].GetString()); + zprintf("%6s|\r\n",fields[1].GetString()); + }while( result->NextRow() ); + + zprintf("========================\r\n"); + delete result; + } + else + { + zprintf("No gamemasters\r\n"); + } +} + +/// Set the GM level of an account +void CliSetGM(char *command,pPrintf zprintf) +{ + ///- Get the command line arguments + char *szAcc = strtok(command," "); + char *szLevel = strtok(NULL," "); + + if(!szAcc||!szLevel) //wrong syntax 'setgm' without name + { + zprintf("Syntax is: setgm $account $number (0 - normal, 3 - gamemaster)>\r\n"); + return; + } + + //wow it's ok,let's hope it was integer given + int lev=atoi(szLevel); //get int anyway (0 if error) + + std::string safe_account_name; + if(!consoleToUtf8(szAcc,safe_account_name)) // convert from console encoding to utf8 + return; + + ///- Convert Account name to Upper Format + AccountMgr::normilizeString(safe_account_name); + + ///- Escape the account name to allow quotes in names + loginDatabase.escape_string(safe_account_name); + + ///- Try to find the account, then update the GM level + // No SQL injection (account name is escaped) + QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",safe_account_name.c_str()); + + if (result) + { + Field *fields = result->Fetch(); + uint32 account_id = fields[0].GetUInt32(); + delete result; + + WorldSession* session = sWorld.FindSession(account_id); + if(session) + session->SetSecurity(lev); + + // No SQL injection (account name is escaped) + loginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); + zprintf("We set %s gmlevel %d\r\n",safe_account_name.c_str(),lev); + } + else + { + zprintf("No account %s found\r\n",safe_account_name.c_str()); + } +} + +/// Set password for account +void CliSetPassword(char *command,pPrintf zprintf) +{ + ///- Get the command line arguments + char *szAcc = strtok(command," "); + char *szPassword1 = strtok(NULL," "); + char *szPassword2 = strtok(NULL," "); + + if(!szAcc||!szPassword1 || !szPassword2) + { + zprintf("Syntax is: setpass $account $password $password\r\n"); + return; + } + + std::string account_name; + if(!consoleToUtf8(szAcc,account_name)) // convert from console encoding to utf8 + return; + + std::string pass1; + if(!consoleToUtf8(szPassword1,pass1)) // convert from console encoding to utf8 + return; + + std::string pass2; + if(!consoleToUtf8(szPassword2,pass2)) // convert from console encoding to utf8 + return; + + uint32 acc_id = accmgr.GetId(szAcc); + if (!acc_id) + { + zprintf("Account '%s' does not exist!\r\n", account_name.c_str()); + return; + } + + if (pass1 != pass2) + { + zprintf("Password does not match the confirm password, password not changed!\r\n"); + return; + } + + AccountOpResult result = accmgr.ChangePassword(acc_id, pass1); + + switch(result) + { + case AOR_OK: + zprintf("The password was changed for account '%s' (ID: %u).\r\n",account_name.c_str(),acc_id); + break; + case AOR_PASS_TOO_LONG: + zprintf("Password can't be longer than 16 characters (client limit), password not changed!\r\n"); + break; + case AOR_NAME_NOT_EXIST: + zprintf("Account '%s' does not exist!\r\n", account_name.c_str()); + break; + case AOR_DB_INTERNAL_ERROR: + zprintf("Password not changed! (probably sql file format was updated)\r\n"); + break; + default: + zprintf("Password not changed! (unknown error\r\n"); + break; + } +} + +/// Create an account +void CliCreate(char *command,pPrintf zprintf) +{ + //I see no need in this function (why would an admin personally create accounts + //instead of using account registration page or accessing db directly?) + //but still let it be + + ///- %Parse the command line arguments + char *szAcc = strtok(command, " "); + char *szPassword = strtok(NULL, " "); + if(!szAcc || !szPassword) + { + zprintf("Syntax is: create $username $password\r\n"); + return; + } + + std::string account_name; + if(!consoleToUtf8(szAcc,account_name)) // convert from console encoding to utf8 + return; + + std::string password; + if(!consoleToUtf8(szPassword,password)) // convert from console encoding to utf8 + return; + + AccountOpResult result = accmgr.CreateAccount(account_name, password); + switch(result) + { + case AOR_OK: + zprintf("User %s with password %s created successfully\r\n",account_name.c_str(),password.c_str()); + break; + case AOR_NAME_TOO_LONG: + zprintf("Username %s is too long\r\n", account_name.c_str()); + break; + case AOR_NAME_ALREDY_EXIST: + zprintf("User %s already exists\r\n",account_name.c_str()); + break; + case AOR_DB_INTERNAL_ERROR: + zprintf("User %s with password %s NOT created (probably sql file format was updated)\r\n",account_name.c_str(),password.c_str()); + break; + default: + zprintf("User %s with password %s NOT created (unknown error)\r\n",account_name.c_str(),password.c_str()); + break; + } +} + +/// Command parser and dispatcher +void ParseCommand( pPrintf zprintf, char* input) +{ + unsigned int x; + bool bSuccess=false; + if (!input) + return; + + unsigned int l=strlen(input); + char *supposedCommand=NULL,* arguments=(char*)(""); + if(l) + { + ///- Get the command and the arguments + supposedCommand = strtok(input," "); + if (supposedCommand) + { + if (l>strlen(supposedCommand)) + arguments=&input[strlen(supposedCommand)+1]; + + ///- Circle through the command table and, if found, put the command in the queue + for ( x=0;x"); +} + +/// Kick a character out of the realm +void CliKick(char*command,pPrintf zprintf) +{ + char *kickName = strtok(command, " "); + + if (!kickName) + { + zprintf("Syntax is: kick $charactername\r\n"); + return; + } + + std::string name; + if(!consoleToUtf8(kickName,name)) // convert from console encoding to utf8 + return; + + if(!normalizePlayerName(name)) + return; + + sWorld.KickPlayer(name); +} + +/// Teleport a character to location +void CliTele(char*command,pPrintf zprintf) +{ + char *charName = strtok(command, " "); + char *locName = strtok(NULL, " "); + + if (!charName || !locName) + { + zprintf("Syntax is: tele $charactername $location\r\n"); + return; + } + + std::string name = charName; + if(!consoleToUtf8(charName,name)) // convert from console encoding to utf8 + return; + + if(!normalizePlayerName(name)) + return; + + std::string location; + if(!consoleToUtf8(locName,location)) // convert from console encoding to utf8 + return; + + WorldDatabase.escape_string(location); + QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM game_tele WHERE name = '%s'",location.c_str()); + if (!result) + { + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_COMMAND_TELE_NOTFOUND),"\r\n"); + return; + } + + Field *fields = result->Fetch(); + float x = fields[0].GetFloat(); + float y = fields[1].GetFloat(); + float z = fields[2].GetFloat(); + float ort = fields[3].GetFloat(); + int mapid = fields[4].GetUInt16(); + delete result; + + if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) + { + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_INVALID_TARGET_COORD),"\r\n",x,y,mapid); + return; + } + + Player *chr = objmgr.GetPlayer(name.c_str()); + if (chr) + { + + if(chr->IsBeingTeleported()==true) + { + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_IS_TELEPORTED),"\r\n",chr->GetName()); + return; + } + + if(chr->isInFlight()) + { + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_CHAR_IN_FLIGHT),"\r\n",chr->GetName()); + return; + } + + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_TELEPORTING_TO),"\r\n",chr->GetName(),"", location.c_str()); + + chr->SaveRecallPosition(); + + chr->TeleportTo(mapid,x,y,z,chr->GetOrientation()); + } + else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str())) + { + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_TELEPORTING_TO),"\r\n",name.c_str(), objmgr.GetMangosStringForDBCLocale(LANG_OFFLINE), location.c_str()); + Player::SavePositionInDB(mapid,x,y,z,ort,MapManager::Instance().GetZoneId(mapid,x,y),guid); + } + else + zprintf(objmgr.GetMangosStringForDBCLocale(LANG_NO_PLAYER),"\r\n",name.c_str()); +} + +/// Display/Define the 'Message of the day' for the realm +void CliMotd(char*command,pPrintf zprintf) +{ + + if (strlen(command) == 0) + { + zprintf("Current Message of the day: \r\n%s\r\n", sWorld.GetMotd()); + return; + } + else + { + std::string commandUtf8; + if(!consoleToUtf8(command,commandUtf8)) // convert from console encoding to utf8 + return; + + sWorld.SetMotd(commandUtf8); + zprintf("Message of the day changed to:\r\n%s\r\n", commandUtf8.c_str()); + } +} + +/// Comment me +/// \todo What is CorpsesErase for? +void CliCorpses(char*,pPrintf) +{ + CorpsesErase(); +} + +/// Set the level of logging +void CliSetLogLevel(char*command,pPrintf zprintf) +{ + char *NewLevel = strtok(command, " "); + if (!NewLevel) + { + zprintf("Syntax is: setloglevel $loglevel\r\n"); + return; + } + sLog.SetLogLevel(NewLevel); +} + +/// Display the server uptime +void CliUpTime(char*,pPrintf zprintf) +{ + uint32 uptime = sWorld.GetUptime(); + std::string suptime = secsToTimeString(uptime,true,(uptime > 86400)); + zprintf("Server has been up for: %s\r\n", suptime.c_str()); +} + +/// Set/Unset the expansion level for an account +void CliSetAddon(char *command,pPrintf zprintf) +{ + ///- Get the command line arguments + char *szAcc = strtok(command," "); + char *szExp = strtok(NULL," "); + + if(!szAcc||!szExp) + { + zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); + return; + } + + int lev=atoi(szExp); //get int anyway (0 if error) + + if(lev < 0) + { + zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); + return; + } + + ///- Escape the account name to allow quotes in names + std::string safe_account_name; + if(!consoleToUtf8(szAcc,safe_account_name)) // convert from console encoding to utf8 + return; + + ///- Convert Account name to Upper Format + AccountMgr::normilizeString(safe_account_name); + + ///- Escape the account name to allow quotes in names + loginDatabase.escape_string(safe_account_name); + + // No SQL injection (account name is escaped) + QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'",safe_account_name.c_str()); + + if (result) + { + // No SQL injection (account name is escaped) + loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); + zprintf("We set %s to expansion allowed %d\r\n",safe_account_name.c_str(),lev); + + delete result; + } + else + { + zprintf("No account %s found\r\n",safe_account_name.c_str()); + } +} + +/// Save all players +void CliSave(char*,pPrintf zprintf) +{ + ///- Save players + ObjectAccessor::Instance().SaveAllPlayers(); + zprintf( objmgr.GetMangosStringForDBCLocale(LANG_PLAYERS_SAVED) ); + + ///- Send a message + sWorld.SendWorldText(LANG_PLAYERS_SAVED); +} + +/// Send a message to a player in game +void CliSend(char *playerN,pPrintf zprintf) +{ + ///- Get the command line arguments + char* name_str = strtok((char*)playerN, " "); + char* msg_str = strtok(NULL, ""); + + if(!name_str || !msg_str) + { + zprintf("Syntax: send $player $message (Player name is case sensitive)\r\n"); + return; + } + + std::string name; + if(!consoleToUtf8(name_str,name)) // convert from console encoding to utf8 + return; + + std::string msg; + if(!consoleToUtf8(msg_str,msg)) // convert from console encoding to utf8 + return; + + if(!normalizePlayerName(name)) + { + zprintf("Syntax: send $player $message (Player name is case sensitive)\r\n"); + return; + } + + ///- Find the player and check that he is not logging out. + Player *rPlayer = objmgr.GetPlayer(name.c_str()); + if(!rPlayer) + { + zprintf("Player %s not found!\r\n", name.c_str()); + return; + } + + if (rPlayer->GetSession()->isLogingOut()) + { + zprintf("Cannot send message while player %s is logging out!\r\n",name.c_str()); + return; + } + + ///- Send the message + //Use SendAreaTriggerMessage for fastest delivery. + rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg.c_str()); + rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); + + //Confirmation message + zprintf("Message '%s' sent to %s\r\n",msg.c_str(), name.c_str()); +} + +void CliPLimit(char *args,pPrintf zprintf) +{ + if(*args) + { + char* param = strtok((char*)args, " "); + if(!param || !*param) + return; + + int l = strlen(param); + + if( strncmp(param,"player",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_PLAYER); + else if(strncmp(param,"moderator",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_MODERATOR); + else if(strncmp(param,"gamemaster",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_GAMEMASTER); + else if(strncmp(param,"administrator",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); + else if(strncmp(param,"reset",l) == 0 ) + sWorld.SetPlayerLimit(sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT)); + else + { + int val = atoi(param); + if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR; + + sWorld.SetPlayerLimit(val); + } + + // kick all low security level players + if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER) + sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); + } + + uint32 pLimit = sWorld.GetPlayerAmountLimit(); + AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); + char const* secName = ""; + switch(allowedAccountType) + { + case SEC_PLAYER: secName = "Player"; break; + case SEC_MODERATOR: secName = "Moderator"; break; + case SEC_GAMEMASTER: secName = "Gamemaster"; break; + case SEC_ADMINISTRATOR: secName = "Administrator"; break; + default: secName = ""; break; + } + + zprintf("Player limits: amount %u, min. security level %s.\r\n",pLimit,secName); +} + +/// @} + +#ifdef linux +// Non-blocking keypress detector, when return pressed, return 1, else always return 0 +int kb_hit_return() +{ + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); +} +#endif + +/// %Thread start +void CliRunnable::run() +{ + ///- Init new SQL thread for the world database (one connection call enough) + WorldDatabase.ThreadStart(); // let thread do safe mySQL requests + + char commandbuf[256]; + + ///- Display the list of available CLI functions then beep + sLog.outString(); + /// \todo Shoudn't we use here also the sLog singleton? + CliHelp(NULL,&UTF8ZPRINTF); + + if(sConfig.GetBoolDefault("BeepAtStart", true)) + { + printf("\a"); // \a = Alert + } + + // print this here the first time + // later it will be printed after command queue updates + printf("mangos>"); + + ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it + while (!World::m_stopEvent) + { + fflush(stdout); + #ifdef linux + while (!kb_hit_return() && !World::m_stopEvent) + // With this, we limit CLI to 10commands/second + usleep(100); + if (World::m_stopEvent) + break; + #endif + char *command = fgets(commandbuf,sizeof(commandbuf),stdin); + if (command != NULL) + { + for(int x=0;command[x];x++) + if(command[x]=='\r'||command[x]=='\n') + { + command[x]=0; + break; + } + //// \todo Shoudn't we use here also the sLog singleton? + ParseCommand(&UTF8ZPRINTF,command); + } + else if (feof(stdin)) + { + World::m_stopEvent = true; + } + } + + ///- End the database thread + WorldDatabase.ThreadEnd(); // free mySQL thread resources +} diff --git a/src/mangosd/CliRunnable.h b/src/mangosd/CliRunnable.h new file mode 100644 index 000000000..4f8d394d5 --- /dev/null +++ b/src/mangosd/CliRunnable.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup mangosd +/// @{ +/// \file + +#ifndef __CLIRUNNABLE_H +#define __CLIRUNNABLE_H + +/// Command Line Interface handling thread +class CliRunnable : public ZThread::Runnable +{ + public: + void run(); +}; +#endif +/// @} diff --git a/src/mangosd/Main.cpp b/src/mangosd/Main.cpp new file mode 100644 index 000000000..9b289ea5d --- /dev/null +++ b/src/mangosd/Main.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup mangosd Mangos Daemon +/// @{ +/// \file + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Config/ConfigEnv.h" +#include "Log.h" +#include "Master.h" +#include "SystemConfig.h" + +#ifdef WIN32 +#include "ServiceWin32.h" +char serviceName[] = "mangosd"; +char serviceLongName[] = "MaNGOS world service"; +char serviceDescription[] = "Massive Network Game Object Server"; +/* + * -1 - not in service mode + * 0 - stopped + * 1 - running + * 2 - paused + */ +int m_ServiceStatus = -1; +#endif + +DatabaseType WorldDatabase; ///< Accessor to the world database +DatabaseType CharacterDatabase; ///< Accessor to the character database +DatabaseType loginDatabase; ///< Accessor to the realm/login database + +uint32 realmID; ///< Id of the realm + +/// Print out the usage string for this program on the console. +void usage(const char *prog) +{ + sLog.outString("Usage: \n %s []\n" + " -c config_file use config_file as configuration file\n\r" + #ifdef WIN32 + " Running as service functions:\n\r" + " --service run as service\n\r" + " -s install install service\n\r" + " -s uninstall uninstall service\n\r" + #endif + ,prog); +} + +/// Launch the mangos server +extern int main(int argc, char **argv) +{ + // - Construct Memory Manager Instance + MaNGOS::Singleton::Instance(); + + //char *leak = new char[1000]; // test leak detection + + ///- Command line parsing to get the configuration file name + char const* cfg_file = _MANGOSD_CONFIG; + int c=1; + while( c < argc ) + { + if( strcmp(argv[c],"-c") == 0) + { + if( ++c >= argc ) + { + sLog.outError("Runtime-Error: -c option requires an input argument"); + usage(argv[0]); + return 1; + } + else + cfg_file = argv[c]; + } + + #ifdef WIN32 + //////////// + //Services// + //////////// + if( strcmp(argv[c],"-s") == 0) + { + if( ++c >= argc ) + { + sLog.outError("Runtime-Error: -s option requires an input argument"); + usage(argv[0]); + return 1; + } + if( strcmp(argv[c],"install") == 0) + { + if (WinServiceInstall()) + sLog.outString("Installing service"); + return 1; + } + else if( strcmp(argv[c],"uninstall") == 0) + { + if(WinServiceUninstall()) + sLog.outString("Uninstalling service"); + return 1; + } + else + { + sLog.outError("Runtime-Error: unsupported option %s",argv[c]); + usage(argv[0]); + return 1; + } + } + if( strcmp(argv[c],"--service") == 0) + { + WinServiceRun(); + } + //// + #endif + ++c; + } + + if (!sConfig.SetSource(cfg_file)) + { + sLog.outError("Could not find configuration file %s.", cfg_file); + return 1; + } + sLog.outString("Using configuration file %s.", cfg_file); + + ///- and run the 'Master' + /// \todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd? + return sMaster.Run(); + + // at sMaster return function exist with codes + // 0 - normal shutdown + // 1 - shutdown at error + // 2 - restart command used, this code can be used by restarter for restart mangosd +} + +/// @} diff --git a/src/mangosd/Makefile.am b/src/mangosd/Makefile.am new file mode 100644 index 000000000..5bd99268c --- /dev/null +++ b/src/mangosd/Makefile.am @@ -0,0 +1,60 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../game -I$(srcdir) + +## Build world list daemon as standalone program +bin_PROGRAMS = mangos-worldd +mangos_worldd_SOURCES = \ + CliRunnable.cpp \ + CliRunnable.h \ + Main.cpp \ + Master.cpp \ + Master.h \ + RASocket.cpp \ + RASocket.h \ + WorldRunnable.cpp \ + WorldRunnable.h + +## Link world daemon against the shared library +mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a +mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic + +## Additional files to include when running 'make dist' +# Include world daemon configuration +EXTRA_DIST = \ + mangosd.conf.dist + +## Additional files to install +sysconf_DATA = \ + mangosd.conf.dist + +install-data-hook: + @list='$(sysconf_DATA)'; for p in $$list; do \ + dest=`echo $$p | sed -e s/.dist//`; \ + if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \ + echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \ + else \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \ + fi; \ + done + +clean-local: + rm -f $(sysconf_DATA) diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp new file mode 100644 index 000000000..84019a853 --- /dev/null +++ b/src/mangosd/Master.cpp @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup mangosd +*/ + +#include + +#include "WorldSocketMgr.h" +#include "Common.h" +#include "Master.h" +#include "WorldSocket.h" +#include "WorldRunnable.h" +#include "World.h" +#include "Log.h" +#include "Timer.h" +#include "Policies/SingletonImp.h" +#include "SystemConfig.h" +#include "Config/ConfigEnv.h" +#include "Database/DatabaseEnv.h" +#include "CliRunnable.h" +#include "RASocket.h" +#include "ScriptCalls.h" +#include "Util.h" + +#include "sockets/TcpSocket.h" +#include "sockets/Utility.h" +#include "sockets/Parse.h" +#include "sockets/Socket.h" +#include "sockets/SocketHandler.h" +#include "sockets/ListenSocket.h" + +#ifdef WIN32 +#include "ServiceWin32.h" +extern int m_ServiceStatus; +#endif + +/// \todo Warning disabling not useful under VC++2005. Can somebody say on which compiler it is useful? +#pragma warning(disable:4305) + +INSTANTIATE_SINGLETON_1( Master ); + +volatile uint32 Master::m_masterLoopCounter = 0; + +class FreezeDetectorRunnable : public ZThread::Runnable +{ +public: + FreezeDetectorRunnable() { _delaytime = 0; } + uint32 m_loops, m_lastchange; + uint32 w_loops, w_lastchange; + uint32 _delaytime; + void SetDelayTime(uint32 t) { _delaytime = t; } + void run(void) + { + if(!_delaytime) + return; + sLog.outString("Starting up anti-freeze thread (%u seconds max stuck time)...",_delaytime/1000); + m_loops = 0; + w_loops = 0; + m_lastchange = 0; + w_lastchange = 0; + while(!World::m_stopEvent) + { + ZThread::Thread::sleep(1000); + uint32 curtime = getMSTime(); + //DEBUG_LOG("anti-freeze: time=%u, counters=[%u; %u]",curtime,Master::m_masterLoopCounter,World::m_worldLoopCounter); + + // There is no Master anymore + // TODO: clear the rest of the code +// // normal work +// if(m_loops != Master::m_masterLoopCounter) +// { +// m_lastchange = curtime; +// m_loops = Master::m_masterLoopCounter; +// } +// // possible freeze +// else if(getMSTimeDiff(m_lastchange,curtime) > _delaytime) +// { +// sLog.outError("Main/Sockets Thread hangs, kicking out server!"); +// *((uint32 volatile*)NULL) = 0; // bang crash +// } + + // normal work + if(w_loops != World::m_worldLoopCounter) + { + w_lastchange = curtime; + w_loops = World::m_worldLoopCounter; + } + // possible freeze + else if(getMSTimeDiff(w_lastchange,curtime) > _delaytime) + { + sLog.outError("World Thread hangs, kicking out server!"); + *((uint32 volatile*)NULL) = 0; // bang crash + } + } + sLog.outString("Anti-freeze thread exiting without problems."); + } +}; + +class RARunnable : public ZThread::Runnable +{ +public: + uint32 numLoops, loopCounter; + + RARunnable () + { + uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); + numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime)); + loopCounter = 0; + } + + void + checkping () + { + // ping if need + if ((++loopCounter) == numLoops) + { + loopCounter = 0; + sLog.outDetail ("Ping MySQL to keep connection alive"); + delete WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1"); + delete loginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1"); + delete CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1"); + } + } + + void + run (void) + { + SocketHandler h; + + // Launch the RA listener socket + ListenSocket RAListenSocket (h); + bool usera = sConfig.GetBoolDefault ("Ra.Enable", false); + + if (usera) + { + port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443); + std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0"); + ipaddr_t raip; + if (!Utility::u2ip (stringip, raip)) + sLog.outError ("MaNGOS RA can not bind to ip %s", stringip.c_str ()); + else if (RAListenSocket.Bind (raip, raport)) + sLog.outError ("MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str ()); + else + { + h.Add (&RAListenSocket); + + sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ()); + } + } + + // Socket Selet time is in microseconds , not miliseconds!! + uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); + + // if use ra spend time waiting for io, if not use ra ,just sleep + if (usera) + while (!World::m_stopEvent) + { + h.Select (0, socketSelecttime); + checkping (); + } + else + while (!World::m_stopEvent) + { + ZThread::Thread::sleep (static_cast (socketSelecttime / 1000)); + checkping (); + } + } +}; + +Master::Master() +{ +} + +Master::~Master() +{ +} + +/// Main function +int Master::Run() +{ + sLog.outString( "%s (world-daemon)", _FULLVERSION ); + sLog.outString( " to stop.\n\n" ); + + sLog.outTitle( "MM MM MM MM MMMMM MMMM MMMMM"); + sLog.outTitle( "MM MM MM MM MMM MMM MM MM MMM MMM"); + sLog.outTitle( "MMM MMM MMM MM MMM MMM MM MM MMM"); + sLog.outTitle( "MM M MM MMMM MM MMM MM MM MMM"); + sLog.outTitle( "MM M MM MMMMM MM MMMM MMM MM MM MMM"); + sLog.outTitle( "MM M MM M MMM MM MMM MMMMMMM MM MM MMM"); + sLog.outTitle( "MM MM MMM MM MM MM MMM MM MM MMM"); + sLog.outTitle( "MM MM MMMMMMM MM MM MMM MMM MM MM MMM MMM"); + sLog.outTitle( "MM MM MM MMM MM MM MMMMMM MMMM MMMMM"); + sLog.outTitle( " MM MMM http://getmangos.com"); + sLog.outTitle( " MMMMMM\n\n"); + + /// worldd PID file creation + std::string pidfile = sConfig.GetStringDefault("PidFile", ""); + if(!pidfile.empty()) + { + uint32 pid = CreatePIDFile(pidfile); + if( !pid ) + { + sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); + return 1; + } + + sLog.outString( "Daemon PID: %u\n", pid ); + } + + ///- Start the databases + if (!_StartDB()) + return 1; + + ///- Initialize the World + sWorld.SetInitialWorldSettings(); + + ///- Catch termination signals + _HookSignals(); + + ///- Launch WorldRunnable thread + ZThread::Thread t(new WorldRunnable); + t.setPriority ((ZThread::Priority )2); + + // set server online + loginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID); + +#ifdef WIN32 + if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) +#else + if (sConfig.GetBoolDefault("Console.Enable", true)) +#endif + { + ///- Launch CliRunnable thread + ZThread::Thread td1(new CliRunnable); + } + + ZThread::Thread td2(new RARunnable); + + ///- Handle affinity for multiple processors and process priority on Windows + #ifdef WIN32 + { + HANDLE hProcess = GetCurrentProcess(); + + uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); + if(Aff > 0) + { + ULONG_PTR appAff; + ULONG_PTR sysAff; + + if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) + { + ULONG_PTR curAff = Aff & appAff; // remove non accessible processors + + if(!curAff ) + { + sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for mangosd. Accessible processors bitmask (hex): %x",Aff,appAff); + } + else + { + if(SetProcessAffinityMask(hProcess,curAff)) + sLog.outString("Using processors (bitmask, hex): %x", curAff); + else + sLog.outError("Can't set used processors (hex): %x",curAff); + } + } + sLog.outString(); + } + + bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); + +// if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/) + if(Prio) + { + if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) + sLog.outString("mangosd process priority class set to HIGH"); + else + sLog.outError("ERROR: Can't set mangosd process priority class."); + sLog.outString(); + } + } + #endif + + uint32 realCurrTime, realPrevTime; + realCurrTime = realPrevTime = getMSTime(); + + uint32 socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME); + + // maximum counter for next ping + uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / socketSelecttime)); + uint32 loopCounter = 0; + + ///- Start up freeze catcher thread + uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0); + if(freeze_delay) + { + FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable(); + fdr->SetDelayTime(freeze_delay*1000); + ZThread::Thread t(fdr); + t.setPriority(ZThread::High); + } + + ///- Launch the world listener socket + port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD); + std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0"); + + if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1) + { + sLog.outError ("Failed to start network"); + World::m_stopEvent = true; + // go down and shutdown the server + } + + sWorldSocketMgr->Wait (); + + // set server offline + loginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID); + + ///- Remove signal handling before leaving + _UnhookSignals(); + + // when the main thread closes the singletons get unloaded + // since worldrunnable uses them, it will crash if unloaded after master + t.wait(); + td2.wait (); + + ///- Clean database before leaving + clearOnlineAccounts(); + + ///- Wait for delay threads to end + CharacterDatabase.HaltDelayThread(); + WorldDatabase.HaltDelayThread(); + loginDatabase.HaltDelayThread(); + + sLog.outString( "Halting process..." ); + + #ifdef WIN32 + if (sConfig.GetBoolDefault("Console.Enable", true)) + { + // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) + //_exit(1); + // send keyboard input to safely unblock the CLI thread + INPUT_RECORD b[5]; + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + b[0].EventType = KEY_EVENT; + b[0].Event.KeyEvent.bKeyDown = TRUE; + b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; + b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; + b[0].Event.KeyEvent.wRepeatCount = 1; + + b[1].EventType = KEY_EVENT; + b[1].Event.KeyEvent.bKeyDown = FALSE; + b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; + b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; + b[1].Event.KeyEvent.wRepeatCount = 1; + + b[2].EventType = KEY_EVENT; + b[2].Event.KeyEvent.bKeyDown = TRUE; + b[2].Event.KeyEvent.dwControlKeyState = 0; + b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; + b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + b[2].Event.KeyEvent.wRepeatCount = 1; + b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; + + b[3].EventType = KEY_EVENT; + b[3].Event.KeyEvent.bKeyDown = FALSE; + b[3].Event.KeyEvent.dwControlKeyState = 0; + b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; + b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; + b[3].Event.KeyEvent.wRepeatCount = 1; + DWORD numb; + BOOL ret = WriteConsoleInput(hStdIn, b, 4, &numb); + } + #endif + + // for some unknown reason, unloading scripts here and not in worldrunnable + // fixes a memory leak related to detaching threads from the module + UnloadScriptingModule(); + + return sWorld.GetShutdownMask() & SHUTDOWN_MASK_RESTART ? 2 : 0; +} + +/// Initialize connection to the databases +bool Master::_StartDB() +{ + ///- Get world database info from configuration file + std::string dbstring; + if(!sConfig.GetString("WorldDatabaseInfo", &dbstring)) + { + sLog.outError("Database not specified in configuration file"); + return false; + } + sLog.outString("World Database: %s", dbstring.c_str()); + + ///- Initialise the world database + if(!WorldDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to world database %s",dbstring.c_str()); + return false; + } + + if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring)) + { + sLog.outError("Character Database not specified in configuration file"); + return false; + } + sLog.outString("Character Database: %s", dbstring.c_str()); + + ///- Initialise the Character database + if(!CharacterDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to Character database %s",dbstring.c_str()); + return false; + } + + ///- Get login database info from configuration file + if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) + { + sLog.outError("Login database not specified in configuration file"); + return false; + } + + ///- Initialise the login database + sLog.outString("Login Database: %s", dbstring.c_str() ); + if(!loginDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to login database %s",dbstring.c_str()); + return false; + } + + ///- Get the realm Id from the configuration file + realmID = sConfig.GetIntDefault("RealmID", 0); + if(!realmID) + { + sLog.outError("Realm ID not defined in configuration file"); + return false; + } + sLog.outString("Realm running as realm ID %d", realmID); + + ///- Clean the database before starting + clearOnlineAccounts(); + + QueryResult* result = WorldDatabase.Query("SELECT version FROM db_version LIMIT 1"); + if(result) + { + Field* fields = result->Fetch(); + + sLog.outString("Using %s", fields[0].GetString()); + delete result; + } + else + sLog.outString("Using unknown world database."); + + return true; +} + +/// Clear 'online' status for all accounts with characters in this realm +void Master::clearOnlineAccounts() +{ + // Cleanup online status for characters hosted at current realm + /// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'? + loginDatabase.PExecute( + "UPDATE account SET online = 0 WHERE online > 0 " + "AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID); + + + CharacterDatabase.Execute("UPDATE characters SET online = 0"); +} + +/// Handle termination signals +/** Put the World::m_stopEvent to 'true' if a termination signal is caught **/ +void Master::_OnSignal(int s) +{ + switch (s) + { + case SIGINT: + case SIGTERM: + #ifdef _WIN32 + case SIGBREAK: + #endif + World::m_stopEvent = true; + break; + } + + signal(s, _OnSignal); +} + +/// Define hook '_OnSignal' for all termination signals +void Master::_HookSignals() +{ + signal(SIGINT, _OnSignal); + signal(SIGTERM, _OnSignal); + #ifdef _WIN32 + signal(SIGBREAK, _OnSignal); + #endif +} + +/// Unhook the signals before leaving +void Master::_UnhookSignals() +{ + signal(SIGINT, 0); + signal(SIGTERM, 0); + #ifdef _WIN32 + signal(SIGBREAK, 0); + #endif +} diff --git a/src/mangosd/Master.h b/src/mangosd/Master.h new file mode 100644 index 000000000..23644118a --- /dev/null +++ b/src/mangosd/Master.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup mangosd +/// @{ +/// \file + +#ifndef _MASTER_H +#define _MASTER_H + +#include "Common.h" +#include "Policies/Singleton.h" + +/// Start the server +class Master +{ + public: + Master(); + ~Master(); + int Run(); + static volatile uint32 m_masterLoopCounter; + + private: + bool _StartDB(); + + void _HookSignals(); + void _UnhookSignals(); + static void _OnSignal(int s); + + void clearOnlineAccounts(); +}; + +#define sMaster MaNGOS::Singleton::Instance() +#endif +/// @} diff --git a/src/mangosd/RASocket.cpp b/src/mangosd/RASocket.cpp new file mode 100644 index 000000000..b881b9a2a --- /dev/null +++ b/src/mangosd/RASocket.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup mangosd +*/ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "RASocket.h" +#include "World.h" +#include "Config/ConfigEnv.h" +#include "Util.h" +#include "AccountMgr.h" + +/// \todo Make this thread safe if in the future 2 admins should be able to log at the same time. +SOCKET r; + +#define dropclient {Sendf("I'm busy right now, come back later."); \ + SetCloseAndDelete(); \ + return; \ + } + +uint32 iSession=0; ///< Session number (incremented each time a new connection is made) +unsigned int iUsers=0; ///< Number of active administrators + +typedef int(* pPrintf)(const char*,...); + +void ParseCommand(pPrintf zprintf, char*command); + +/// RASocket constructor +RASocket::RASocket(ISocketHandler &h): TcpSocket(h) +{ + + ///- Increment the session number + iSess =iSession++ ; + + ///- Get the config parameters + bSecure = sConfig.GetBoolDefault( "RA.Secure", true ); + iMinLevel = sConfig.GetIntDefault( "RA.MinLevel", 3 ); + + ///- Initialize buffer and data + iInputLength=0; + buff=new char[RA_BUFF_SIZE]; + stage=NONE; +} + +/// RASocket destructor +RASocket::~RASocket() +{ + ///- Delete buffer and decrease active admins count + delete [] buff; + + sLog.outRALog("Connection was closed.\n"); + + if(stage==OK) + iUsers--; +} + +/// Accept an incoming connection +void RASocket::OnAccept() +{ + std::string ss=GetRemoteAddress(); + sLog.outRALog("Incoming connection from %s.\n",ss.c_str()); + ///- If there is already an active admin, drop the connection + if(iUsers) + dropclient + + ///- Else print Motd + Sendf("%s\r\n",sWorld.GetMotd()); +} + +/// Read data from the network +void RASocket::OnRead() +{ + ///- Read data and check input length + TcpSocket::OnRead(); + + unsigned int sz=ibuf.GetLength(); + if(iInputLength+sz>=RA_BUFF_SIZE) + { + sLog.outRALog("Input buffer overflow, possible DOS attack.\n"); + SetCloseAndDelete(); + return; + } + + ///- If there is already an active admin (other than you), drop the connection + if(stage!=OK && iUsers) + dropclient + + char *inp = new char [sz+1]; + ibuf.Read(inp,sz); + + /// \todo Can somebody explain this 'Linux bugfix'? + if(stage==NONE) + if(sz>4) //linux remote telnet + if(memcmp(inp ,"USER ",5)) + { + delete [] inp;return; + printf("lin bugfix"); + } //linux bugfix + + ///- Discard data after line break or line feed + bool gotenter=false; + unsigned int y=0; + for(;y
  • If the input is 'USER ' + case NONE: + if(!memcmp(buff,"USER ",5)) //got "USER" cmd + { + szLogin=&buff[5]; + + ///- Get the gmlevel and password from the account table + std::string login = szLogin; + + ///- Convert Account name to Upper Format + AccountMgr::normilizeString(login); + + ///- Escape the Login to allow quotes in names + loginDatabase.escape_string(login); + + QueryResult* result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE username = '%s'",login.c_str()); + + ///- If the user is not found, deny access + if(!result) + { + Sendf("-No such user.\r\n"); + sLog.outRALog("User %s does not exist.\n",szLogin.c_str()); + if(bSecure)SetCloseAndDelete(); + } + else + { + Field *fields = result->Fetch(); + + //szPass=fields[0].GetString(); + + ///- if gmlevel is too low, deny access + if(fields[0].GetUInt32() If the input is 'PASS ' (and the user already gave his username) + case LG: + if(!memcmp(buff,"PASS ",5)) //got "PASS" cmd + { //login+pass ok + ///- If password is correct, increment the number of active administrators + std::string login = szLogin; + std::string pw = &buff[5]; + + AccountMgr::normilizeString(login); + AccountMgr::normilizeString(pw); + loginDatabase.escape_string(login); + loginDatabase.escape_string(pw); + + QueryResult *check = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", login.c_str(), pw.c_str()); + if(check) + { + delete check; + r=GetSocket(); + stage=OK; + ++iUsers; + + Sendf("+Logged in.\r\n"); + sLog.outRALog("User %s has logged in.\n",szLogin.c_str()); + Sendf("mangos>"); + } + else + { + ///- Else deny access + Sendf("-Wrong pass.\r\n"); + sLog.outRALog("User %s has failed to log in.\n",szLogin.c_str()); + if(bSecure)SetCloseAndDelete(); + } + } + break; + ///
  • If user is logged, parse and execute the command + case OK: + if(strlen(buff)) + { + sLog.outRALog("Got '%s' cmd.\n",buff); + ParseCommand(&RASocket::zprintf , buff); + } + else + Sendf("mangos>"); + break; + /// + }; + + } +} + +/// Output function +int RASocket::zprintf( const char * szText, ... ) +{ + if( !szText ) return 0; + va_list ap; + va_start(ap, szText); + /// \todo Remove buffer length here. Can be >1024 (e.g. list of users) + char *megabuffer=new char[1024]; + unsigned int sz=vsnprintf(megabuffer,1024,szText,ap); + #ifdef RA_CRYPT + Encrypt(megabuffer,sz); + #endif + + send(r,megabuffer,sz,0); + delete [] megabuffer; + va_end(ap); + return 0; +} diff --git a/src/mangosd/RASocket.h b/src/mangosd/RASocket.h new file mode 100644 index 000000000..83dcfcdaa --- /dev/null +++ b/src/mangosd/RASocket.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup mangosd +/// @{ +/// \file + +#ifndef _RASOCKET_H +#define _RASOCKET_H + +#include "Common.h" +#include "sockets/TcpSocket.h" + +#define RA_BUFF_SIZE 1024 + +class ISocketHandler; + +/// Remote Administration socket +class RASocket: public TcpSocket +{ + public: + + RASocket(ISocketHandler& h); + ~RASocket(); + + void OnAccept(); + void OnRead(); + + private: + + char * buff; + std::string szLogin; + uint32 iSess; + unsigned int iInputLength; + bool bLog; + bool bSecure; //kick on wrong pass, non exist. user, user with no priv + //will protect from DOS, bruteforce attacks + //some 'smart' protection must be added for more scurity + uint8 iMinLevel; + enum + { + NONE, //initial value + LG, //only login was entered + OK, //both login and pass were given, and they are correct and user have enough priv. + }stage; + + static int zprintf( const char * szText, ... ); +}; +#endif +/// @} diff --git a/src/mangosd/WorldRunnable.cpp b/src/mangosd/WorldRunnable.cpp new file mode 100644 index 000000000..62878a1ee --- /dev/null +++ b/src/mangosd/WorldRunnable.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup mangosd +*/ + +#include "WorldSocketMgr.h" +#include "Common.h" +#include "World.h" +#include "WorldRunnable.h" +#include "Timer.h" +#include "ObjectAccessor.h" +#include "MapManager.h" + +#include "Database/DatabaseEnv.h" + +#ifdef WIN32 +#define WORLD_SLEEP_CONST 50 +#else +#define WORLD_SLEEP_CONST 100 //Is this still needed?? [On linux some time ago not working 50ms] +#endif + +/// Heartbeat for the World +void WorldRunnable::run() +{ + ///- Init new SQL thread for the world database + WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough) + sWorld.InitResultQueue(); + + uint32 realCurrTime = 0; + uint32 realPrevTime = getMSTime(); + + uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST + + ///- While we have not World::m_stopEvent, update the world + while (!World::m_stopEvent) + { + ++World::m_worldLoopCounter; + realCurrTime = getMSTime(); + + uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime); + + sWorld.Update( diff ); + realPrevTime = realCurrTime; + + // diff (D0) include time of previous sleep (d0) + tick time (t0) + // we want that next d1 + t1 == WORLD_SLEEP_CONST + // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement + // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0 + if (diff <= WORLD_SLEEP_CONST+prevSleepTime) + { + prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; + ZThread::Thread::sleep(prevSleepTime); + } + else + prevSleepTime = 0; + } + + sWorld.KickAllQueued(); // kick all queued players (and prevent its login at kick in game players) + sWorld.KickAll(); // save and kick all players + sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call + + sWorldSocketMgr->StopNetwork(); + + MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory) + + ///- End the database thread + WorldDatabase.ThreadEnd(); // free mySQL thread resources +} diff --git a/src/mangosd/WorldRunnable.h b/src/mangosd/WorldRunnable.h new file mode 100644 index 000000000..f1086f90e --- /dev/null +++ b/src/mangosd/WorldRunnable.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup mangosd +/// @{ +/// \file + +#ifndef __WORLDRUNNABLE_H +#define __WORLDRUNNABLE_H + +/// Heartbeat thread for the World +class WorldRunnable : public ZThread::Runnable +{ + public: + void run(); +}; +#endif +/// @} diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in new file mode 100644 index 000000000..954f544fa --- /dev/null +++ b/src/mangosd/mangosd.conf.dist.in @@ -0,0 +1,1086 @@ +##################################### +# MaNGOS Configuration file # +##################################### +ConfVersion=2008080101 + +################################################################################################################### +# CONNECTIONS AND DIRECTORIES +# +# RealmID +# RealmID must match the realmlist inside the realmd database +# +# DataDir +# Data directory setting. +# Important: DataDir needs to be quoted, as it is a string which may contain space characters. +# Example: "@prefix@/share/mangos" +# +# LogsDir +# Logs directory setting. +# Important: Logs dir must exists, or all logs need to be disabled +# Default: "" - no log directory prefix, if used log names isn't absolute path +# then logs will be stored in current directory for run program. +# +# +# LoginDatabaseInfo +# WorldDatabaseInfo +# CharacterDatabaseInfo +# Database connection settings for the world server. +# Default: hostname;port;username;password;database +# .;somenumber;username;password;database - use named pipes at Windows +# Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini +# .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux +# Unix sockets: experimental, not tested +# +# MaxPingTime +# Settings for maximum database-ping interval (minutes between pings) +# +# WorldServerPort +# Default WorldServerPort +# +# BindIP +# Bind World Server to IP/hostname +# +################################################################################################################### + +RealmID = 1 +DataDir = "." +LogsDir = "" +LoginDatabaseInfo = "127.0.0.1;3306;root;mangos;realmd" +WorldDatabaseInfo = "127.0.0.1;3306;root;mangos;mangos" +CharacterDatabaseInfo = "127.0.0.1;3306;root;mangos;characters" +MaxPingTime = 30 +WorldServerPort = 8085 +BindIP = "0.0.0.0" + +################################################################################################################### +# PERFORMANCE SETINGS +# +# UseProcessors +# Used processors mask for multi-processors system (Used only at Windows) +# Default: 0 (selected by OS) +# number (bitmask value of selected processors) +# +# ProcessPriority +# Process priority setting (Used only at Windows) +# Default: 1 (HIGH) +# 0 (Normal) +# +# Compression +# Compression level for update packages sent to client (1..9) +# Default: 1 (speed) +# 9 (best compression) +# +# TcpNoDelay +# TCP Nagle algorithm setting +# Default: 0 (enable Nagle algorithm, less traffic, more latency) +# 1 (TCP_NO_DELAY, disable Nagle algorithm, more traffic but less latency) +# +# PlayerLimit +# Maximum number of players in the world. Excluding Mods, GM's and Admins +# Default: 100 +# 0 (for infinite players) +# -1 (for Mods, GM's and Admins only) +# -2 (for GM's and Admins only) +# -3 (for Admins only) +# +# SaveRespawnTimeImmediately +# Save respawn time for creatures at death and for gameobjects at use/open +# Default: 1 (save creature/gameobject respawn time without waiting grid unload) +# 0 (save creature/gameobject respawn time at grid unload) +# +# MaxOverspeedPings +# Maximum overspeed ping count before player kick (minimum is 2, 0 used for disable check) +# Default: 2 +# +# GridUnload +# Unload grids (if you have lot memory you can disable it to speed up player move to new grids second time) +# Default: 1 (unload grids) +# 0 (do not unload grids) +# +# SocketSelectTime +# Socket select time (in milliseconds) +# Default: 10000 +# +# GridCleanUpDelay +# Grid clean up delay (in milliseconds) +# Default: 300000 (5 min) +# +# MapUpdateInterval +# Map update interval (in milliseconds) +# Default: 100 +# +# ChangeWeatherInterval +# Weather update interval (in milliseconds) +# Default: 600000 (10 min) +# +# PlayerSaveInterval +# Player save interval (in milliseconds) +# Default: 900000 (15 min) +# +# vmap.enableLOS +# vmap.enableHeight +# Enable/Disable VMmap support for line of sight and height calculation +# Default: 1 (true) +# 0 (false) +# +# vmap.ignoreMapIds +# Map id that will be ignored by VMaps +# List of ids with delimiter ',' +# If more then one id is defined and spaces are included, the string has to be enclosed by " +# Example: "369,0,1,530" +# +# vmap.ignoreSpellIds +# These spells are ignored for LoS calculation +# List of ids with delimiter ',' +# +# DetectPosCollision +# Check final move position, summon position, etc for visible collision with other objects or +# wall (wall only if vmaps are enabled) +# Default: 1 (enable, required more CPU power usage) +# 0 (disable, less nice position selection but will less CPU power usage) +# +# TargetPosRecalculateRange +# Max distance from movement target point (+moving unit size) and targeted object (+size) +# after that new target movmeent point calculated. Max: melee attack range (5), min: contact range (0.5) +# More distance let have better performence, less distance let have more sensitive reaction at target move. +# Default: 1.5 +# +# UpdateUptimeInterval +# Update realm uptime period in minutes (for save data in 'uptime' table). Must be > 0 +# Default: 10 (minutes) +# +# MaxCoreStuckTime +# Periodically check if the process got freezed, if this is the case force crash after the specified +# amount of seconds. Must be > 0. Recommended > 10 secs if you use this. +# Default: 0 (Disabled) +# +# AddonChannel +# Permit/disable the use of the addon channel through the server +# (some client side addons can stop work correctly with disabled addon channel) +# Default: 1 (permit addon channel) +# 0 (do not permit addon channel) +# +################################################################################################################### + +UseProcessors = 0 +ProcessPriority = 1 +Compression = 1 +TcpNoDelay = 0 +PlayerLimit = 100 +SaveRespawnTimeImmediately = 1 +MaxOverspeedPings = 2 +GridUnload = 1 +SocketSelectTime = 10000 +GridCleanUpDelay = 300000 +MapUpdateInterval = 100 +ChangeWeatherInterval = 600000 +PlayerSaveInterval = 900000 +vmap.enableLOS = 0 +vmap.enableHeight = 0 +vmap.ignoreMapIds = "369" +vmap.ignoreSpellIds = "7720" +DetectPosCollision = 1 +TargetPosRecalculateRange = 1.5 +UpdateUptimeInterval = 10 +MaxCoreStuckTime = 0 +AddonChannel = 1 + +################################################################################################################### +# SERVER LOGGING +# +# LogSQL +# Enable logging of GM commands - all SQL code will be written to a log file +# All commands are written to a file: YYYY-MM-DD_logSQL.sql +# If a new day starts (00:00:00) then a new file is created - the old file will not be deleted. +# Default: 1 - Write SQL code to logfile +# 0 - Do not log +# +# PidFile +# World daemon PID file +# Default: "" - do not create PID file +# "./worldd.pid" - create PID file (recommended name) +# +# LogLevel +# Server console level of logging +# 0 = Minimum; 1 = Basic&Error; 2 = Detail; 3 = Full/Debug +# Default: 3 +# +# LogTime +# Include time in server console output [hh:mm:ss] +# Default: 0 (no time) +# 1 (print time) +# +# LogFile +# Logfile name +# Default: "Server.log" +# "" - Empty name disable creating log file +# +# LogTimestamp +# Logfile with timestamp of server start in name +# Default: 0 - no timestamp in name +# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +# LogFileLevel +# Server file level of logging +# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug +# Default: 0 +# +# LogFilter_TransportMoves +# LogFilter_CreatureMoves +# LogFilter_VisibilityChanges +# Log filters +# Default: 1 - not include with any log level +# 0 - include in log if log level permit +# +# WorldLogFile +# Packet logging file for the worldserver +# Default: "world.log" +# +# DBErrorLogFile +# Log file of DB errors detected at server run +# Default: "DBErrors.log" +# +# CharLogFile +# Character operations logfile name +# Default: "Char.log" +# "" - Empty name disable creating log file +# +# CharLogTimestamp +# Logfile with timestamp of server start in name +# Default: 0 - no timestamp in name +# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +# CharLogDump +# Write character dump before deleting in Char.log +# For restoration, cut character data from log starting from +# line == START DUMP == to line == END DUMP == (without its) in file and load it using loadpdump command +# Default: 0 - don't include dumping chars to log +# 1 - include dumping chars to log +# +# GmLogFile +# Log file of gm commands +# Default: "" (Disable) +# +# GmLogTimestamp +# Logfile with timestamp of server start in name +# Default: 0 - no timestamp in name +# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +# RaLogFile +# Log file of RA commands +# Default: "Ra.log" +# "" - Empty name for disable +# +# LogColors +# Color for messages (format "normal_color details_color debug_color error_color") +# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY, +# 8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE +# Default: "" - none colors +# Example: "13 7 11 9" +# +################################################################################################################### + +LogSQL = 1 +PidFile = "" +LogLevel = 3 +LogTime = 0 +LogFile = "Server.log" +LogTimestamp = 0 +LogFileLevel = 0 +LogFilter_TransportMoves = 1 +LogFilter_CreatureMoves = 1 +LogFilter_VisibilityChanges = 1 +WorldLogFile = "world.log" +DBErrorLogFile = "DBErrors.log" +CharLogFile = "Char.log" +CharLogTimestamp = 0 +CharLogDump = 0 +GmLogFile = "" +GmLogTimestamp = 0 +RaLogFile = "" +LogColors = "" + +################################################################################################################### +# SERVER SETTINGS +# +# GameType +# Server realm style +# 0 = NORMAL;1 = PVP; 4 = NORMAL; 6 = RP; 8 = RPPVP +# also custom type: 16 FFA_PVP (free for all pvp mode like arena PvP in all zones except rest +# activated places and sanctuaries) +# +# RealmZone +# Server realm zone (set allowed alphabet in character names/etc). See also Strict*Names options. +# +# 1 Development - any language (Default) +# 2 United States - extended-Latin +# 3 Oceanic - extended-Latin +# 4 Latin America - extended-Latin +# 5 Tournament - basic-Latin at create, any at login +# 6 Korea - East-Asian +# 7 Tournament - basic-Latin at create, any at login +# 8 English - extended-Latin +# 9 German - extended-Latin +# 10 French - extended-Latin +# 11 Spanish - extended-Latin +# 12 Russian - Cyrillic +# 13 Tournament - basic-Latin at create, any at login +# 14 Taiwan - East-Asian +# 15 Tournament - basic-Latin at create, any at login +# 16 China - East-Asian +# 17 CN1 - basic-Latin at create, any at login +# 18 CN2 - basic-Latin at create, any at login +# 19 CN3 - basic-Latin at create, any at login +# 20 CN4 - basic-Latin at create, any at login +# 21 CN5 - basic-Latin at create, any at login +# 22 CN6 - basic-Latin at create, any at login +# 23 CN7 - basic-Latin at create, any at login +# 24 CN8 - basic-Latin at create, any at login +# 25 Tournament - basic-Latin at create, any at login +# 26 Test Server - any language +# 27 Tournament - basic-Latin at create, any at login +# 28 QA Server - any language +# 29 CN9 - basic-Latin at create, any at login +# +# Expansion +# Allow server use content from expansion +# 2 - check expansion 2 maps existence, and if client support expansion 2 and account have +# expansion 2 setting then allow visit expansion 2 maps, allow create new class character) +# Default: 1 - check expansion 1 maps existence, and if client support expansion 1 and account have +# expansion 1 setting then allow visit expansion 1 maps, allow create new races character) +# 0 - not check expansion maps existence, not allow wisit its, not allow create new race or new class +# characters, ignore account expansion setting) +# +# DBC.Locale +# DBC Language Settings +# 0 = English; 1 = Korean; 2 = French; 3 = German; 4 = Chinese; 5 = Taiwanese; 6 = Spanish; 7 = Spanish Mexico +# 8 = Russian; 255 = Auto Detect (Default) +# +# DeclinedNames +# Allow russian clients to set and use declined names +# Default: 0 - do not use declined names, except when the Russian RealmZone is set +# 1 - use declined names +# +# StrictPlayerNames +# Limit player name to language specific symbols set, not allow create characters, and set rename request and disconnect at not allowed symbols name +# Default: 0 disable (but limited server timezone dependent client check) +# 1 basic latin characters (strict) +# 2 realm zone specific (strict). See RealmZone setting. +# Note: In any case if you want correctly see character name at client this client must have apporopriate fonts +# (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts). +# 3 basic latin characters + server timezone specific +# +# StrictCharterNames +# Limit guild/arena team charter names to language specific symbols set, not allow create charters with allowed symbols in name +# Default: 0 disable +# 1 basic latin characters (strict) +# 2 realm zone specific (strict). See RealmZone setting. +# Note: In any case if you want correctly see character name at client this client must have apporopriate fonts +# (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts). +# 3 basic latin characters + server timezone specific +# +# StrictPetNames +# Limit pet names to language specific symbols set +# Default: 0 disable +# 1 basic latin characters (strict) +# 2 realm zone specific (strict). See RealmZone setting. +# Note: In any case if you want correctly see character name at client this client must have apporopriate fonts +# (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts). +# 3 basic latin characters + server timezone specific +# +# CharactersCreatingDisabled +# Disable characters creating for specific team or any (non-player accounts not affected) +# Default: 0 - enabled +# 1 - disabled only for Alliance +# 2 - disabled only for Horde +# 3 - disabled for both teams +# +# CharactersPerAccount +# Limit numbers of characters per account (at all realms). +# Note: this setting limit character creating at _current_ realm base at characters amount at all realms +# Default: 50 +# The number must be >= CharactersPerRealm +# +# CharactersPerRealm +# Limit numbers of characters for account at realm +# Default: 10 (client limitation) +# The number must be between 1 and 10 +# +# SkipCinematics +# Disable in-game script movie at first character's login(allows to prevent buggy intro in case of custom start location coordinates) +# Default: 0 - show intro for each new characrer +# 1 - show intro only for first character of selected race +# 2 - disable intro show in all cases +# +# MaxPlayerLevel +# Max level that can be reached by player for experience (in range from 1 to 255). +# Change not recommended +# Default: 70 +# +# MaxHonorPoints +# Max honor points that player can have. +# Default: 75000 +# +# MaxArenaPoints +# Max arena points that player can have. +# Default: 5000 +# +# StartPlayerLevel +# Staring level that have character at creating (in range 1 to MaxPlayerLevel) +# Default: 1 +# +# ActivateWeather +# Activate weather system +# Default: 1 (true) +# 0 (false) +# +# Battleground.CastDeserter +# Cast or not Deserter spell at player who leave battleground in progress +# Default: 1 (true) +# 0 (false) +# +# Battleground.QueueAnnouncer.Enable +# Enable queue announcer posting to chat +# Default: 1 (true) +# 0 (false) +# +# Battleground.QueueAnnouncer.PlayerOnly +# Enable queue announcer posting to chat +# Default: 0 (false) +# 1 (true) +# +# CastUnstuck +# Allow cast or not Unstuck spell at .start or client Help option use +# Default: 1 (true) +# 0 (false) +# +# Instance.IgnoreLevel +# Ignore level requirement to enter instance +# Default: 0 (false) +# 1 (true) +# +# Instance.IgnoreRaid +# Ignore raid requirement to enter instance +# Default: 0 (false) +# 1 (true) +# +# Instance.ResetTimeHour +# The hour of the day (0-23) when the global instance resets occur. +# Default: 4 +# +# Instance.UnloadDelay +# Unload the instance map from memory after some time if no players are inside. +# Default: 1800000 (miliseconds, i.e 30 minutes) +# 0 (instance maps are kept in memory until they are reset) +# +# Quests.LowLevelHideDiff +# Quest level difference to hide for player low level quests: +# if player_level > quest_level + LowLevelQuestsHideDiff then quest "!" mark not show for quest giver +# Default: 4 +# -1 (show all available quests marks) +# +# Quests.HighLevelHideDiff +# Quest level difference to hide for player high level quests: +# if player_level < quest_min_level - HighLevelQuestsHideDiff then quest "!" mark not show for quest giver +# Default: 7 +# -1 (show all available quests marks) +# +# MaxPrimaryTradeSkill +# Max count that player can learn the primary trade skill. +# Default: 2 +# Max : 10 +# +# MinPetitionSigns +# Min signatures count to creating guild (0..9). +# Default: 9 +# +# MaxGroupXPDistance +# Max distance to creature for group memeber to get XP at creature death. +# Default: 74 +# +# MailDeliveryDelay +# Mail delivery delay time for item sending +# Default: 3600 sec (1 hour) +# +# SkillChance.Prospecting +# For prospecting skillup not possible by default, but can be allowed as custom setting +# Default: 0 - no skilups +# 1 - skilups possible +# +# Event.Announce +# Default: 0 (false) +# 1 (true) +# +# BeepAtStart +# Beep at mangosd start finished (mostly work only at Unix/Linux systems) +# Default: 1 (true) +# 0 (false) +# +# Motd +# Message of the Day. Displayed at worldlogin for every user ('@' for a newline). +# +################################################################################################################### + +GameType = 1 +RealmZone = 1 +Expansion = 1 +DBC.Locale = 255 +DeclinedNames = 0 +StrictPlayerNames = 0 +StrictCharterNames = 0 +StrictPetNames = 0 +CharactersCreatingDisabled = 0 +CharactersPerAccount = 50 +CharactersPerRealm = 10 +SkipCinematics = 0 +MaxPlayerLevel = 70 +MaxHonorPoints = 75000 +MaxArenaPoints = 5000 +StartPlayerLevel = 1 +ActivateWeather = 1 +Battleground.CastDeserter = 1 +Battleground.QueueAnnouncer.Enable = 1 +Battleground.QueueAnnouncer.PlayerOnly = 0 +CastUnstuck = 1 +Instance.IgnoreLevel = 0 +Instance.IgnoreRaid = 0 +Instance.ResetTimeHour = 4 +Instance.UnloadDelay = 1800000 +Quests.LowLevelHideDiff = 4 +Quests.HighLevelHideDiff = 7 +MaxPrimaryTradeSkill = 2 +MinPetitionSigns = 9 +MaxGroupXPDistance = 74 +MailDeliveryDelay = 3600 +SkillChance.Prospecting = 0 +Event.Announce = 0 +BeepAtStart = 1 +Motd = "Welcome to the Massive Network Game Object Server." + +################################################################################################################### +# PLAYER INTERACTION +# +# AllowTwoSide.Accounts +# Allow or not accounts to create characters in the 2 teams in any game type. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# AllowTwoSide.Interaction.Chat +# AllowTwoSide.Interaction.Channel +# AllowTwoSide.Interaction.Group +# AllowTwoSide.Interaction.Guild +# AllowTwoSide.Interaction.Auction +# AllowTwoSide.Interaction.Mail +# Allow or not common :chat(say,yell);channel(chat)group(join)guild(join);merge all auction houses for players from +# different teams, send mail to different team. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# AllowTwoSide.WhoList +# Allow or not show player from both team in who list. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# AllowTwoSide.AddFriend +# Allow or not adding friends from other team in friend list. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# TalentsInspecting +# Allow other players see character talents in inspect dialog (Characters in Gamemaster mode can +# inspect talents always) +# Default: 1 (allow) +# 0 (not allow) +# +################################################################################################################### + +AllowTwoSide.Accounts = 0 +AllowTwoSide.Interaction.Chat = 0 +AllowTwoSide.Interaction.Channel = 0 +AllowTwoSide.Interaction.Group = 0 +AllowTwoSide.Interaction.Guild = 0 +AllowTwoSide.Interaction.Auction = 0 +AllowTwoSide.Interaction.Mail = 0 +AllowTwoSide.WhoList = 0 +AllowTwoSide.AddFriend = 0 +TalentsInspecting = 1 + +################################################################################################################### +# CREATURE SETTINGS +# +# ThreatRadius +# Radius for creature to evade after being pulled away from combat start point +# If ThreatRadius is less than creature aggro radius then aggro radius will be used +# Default: 100 yards +# +# Rate.Creature.Aggro +# Aggro radius percent or off. +# Default: 1 - 100% +# 1.5 - 150% +# 0 - off (0%) +# +# CreatureFamilyAssistenceRadius +# Creature family assistence radius +# Default: 10 +# 0 - off +# +# WorldBossLevelDiff +# Difference for boss dynamic level with target +# Default: 3 +# +# Corpse.Decay.NORMAL +# Corpse.Decay.RARE +# Corpse.Decay.ELITE +# Corpse.Decay.RAREELITE +# Corpse.Decay.WORLDBOSS +# Seconds until creature corpse will decay without being looted or skinned. +# Default: 60, 300, 300, 300, 3600 +# +# Rate.Corpse.Decay.Looted +# Controls how long the creature corpse stays after it had been looted, as a multiplier of its Corpse.Decay.* config. +# Default: 0.1 +# +# Rate.Creature.Normal.Damage +# Rate.Creature.Elite.Elite.Damage +# Rate.Creature.Elite.RAREELITE.Damage +# Rate.Creature.Elite.WORLDBOSS.Damage +# Rate.Creature.Elite.RARE.Damage +# Creature Damage Rates. +# Examples: 2 - creatures will damage 2x, 1.7 - 1.7x. +# +# Rate.Creature.Normal.SpellDamage +# Rate.Creature.Elite.Elite.SpellDamage +# Rate.Creature.Elite.RAREELITE.SpellDamage +# Rate.Creature.Elite.WORLDBOSS.SpellDamag +# Rate.Creature.Elite.RARE.SpellDamage +# Creature Spell Damage Rates. +# Examples: 2 - creatures will damage with spells 2x, 1.7 - 1.7x. +# +# Rate.Creature.Normal.HP +# Rate.Creature.Elite.Elite.HP +# Rate.Creature.Elite.RAREELITE.HP +# Rate.Creature.Elite.WORLDBOSS.HP +# Rate.Creature.Elite.RARE.HP +# Creature Health Ammount Modifier. +# Examples: 2 - creatures have 2x health, 1.7 - 1.7x. +# +# ListenRange.Say +# Distance from player to listen text that creature (or other world object) say +# Default: 25 +# +# ListenRange.TextEmote +# Distance from player to listen textemote that creature (or other world object) say +# Default: 25 +# +# ListenRange.Yell +# Distance from player to listen text that creature (or other world object) yell +# Default: 300 +# +################################################################################################################### + +ThreatRadius = 100 +Rate.Creature.Aggro = 1 +CreatureFamilyAssistenceRadius = 10 +WorldBossLevelDiff = 3 +Corpse.Decay.NORMAL = 60 +Corpse.Decay.RARE = 300 +Corpse.Decay.ELITE = 300 +Corpse.Decay.RAREELITE = 300 +Corpse.Decay.WORLDBOSS = 3600 +Rate.Corpse.Decay.Looted = 0.1 +Rate.Creature.Normal.Damage = 1 +Rate.Creature.Elite.Elite.Damage = 1 +Rate.Creature.Elite.RAREELITE.Damage = 1 +Rate.Creature.Elite.WORLDBOSS.Damage = 1 +Rate.Creature.Elite.RARE.Damage = 1 +Rate.Creature.Normal.SpellDamage = 1 +Rate.Creature.Elite.Elite.SpellDamage = 1 +Rate.Creature.Elite.RAREELITE.SpellDamage = 1 +Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1 +Rate.Creature.Elite.RARE.SpellDamage = 1 +Rate.Creature.Normal.HP = 1 +Rate.Creature.Elite.Elite.HP = 1 +Rate.Creature.Elite.RAREELITE.HP = 1 +Rate.Creature.Elite.WORLDBOSS.HP = 1 +Rate.Creature.Elite.RARE.HP = 1 +ListenRange.Say = 40 +ListenRange.TextEmote = 40 +ListenRange.Yell = 300 + +################################################################################################################### +# CHAT SETTINGS +# +# ChatFakeMessagePreventing +# Chat protection from creating fake messages using a lot spaces (other invisible symbols), +# not applied to addon language messages, but can prevent working old addons +# that use normal languages for sending data to another clients. +# Default: 0 (disible fake messages preventing) +# 1 (enabled fake messages preventing) +# +# ChatFlood.MessageCount +# Chat anti-flood protection, haste message count to activate protection +# Default: 10 +# 0 (disible anti-flood protection) +# +# ChatFlood.MessageDelay +# Chat anti-flood protection, minimum message delay to count message +# Default: 1 (in secs) +# +# ChatFlood.MuteTime +# Chat anti-flood protection, mute time at activation flood protection (not saved) +# Default: 10 (in secs) +# +# Channel.RestrictedLfg +# Restrict use LookupForGroup channel only registered in LFG tool players +# Default: 1 (allow join to channel only if active in LFG) +# 0 (allow join to channel in any time) +# +# Channel.SilentlyGMJoin +# Silently join GM characters (security level > 1) to channels +# Default: 0 (join announcement in normal way) +# 1 (GM join without announcement) +# +################################################################################################################### + +ChatFakeMessagePreventing = 0 +ChatFlood.MessageCount = 10 +ChatFlood.MessageDelay = 1 +ChatFlood.MuteTime = 10 +Channel.RestrictedLfg = 1 +Channel.SilentlyGMJoin = 0 + +################################################################################################################### +# GAME MASTER SETTINGS +# +# GM.LoginState +# GM mode at login +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.AcceptTickets +# Is GM accepting tickets from player by default or not. +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.Chat +# GM chat mode at login +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.WhisperingTo +# Is GM accepting whispers from player by default or not. +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.InGMList +# Is GM showed in GM list (if visible) in non-GM state (.gmoff) +# Default: 0 (false) +# 1 (true) +# +# GM.InWhoList +# Is GM showed in who list (if visible). +# Default: 0 (false) +# 1 (true) +# +# GM.LogTrade +# Include GM trade and trade slot enchanting operations in GM log if it enable +# Default: 1 (include) +# 0 (not include) +# +################################################################################################################### + +GM.LoginState = 2 +GM.AcceptTickets = 2 +GM.Chat = 2 +GM.WhisperingTo = 2 +GM.InGMList = 0 +GM.InWhoList = 0 +GM.LogTrade = 1 + +################################################################################################################### +# VISIBILITY AND RADIUSES +# +# Visibility.GroupMode +# Group visibility modes +# Default: 0 (standard setting: only members from same group can 100% auto detect invisible player) +# 1 (raid members 100% auto detect invisible player from same raid) +# 2 (players from same team can 100% auto detect invisible player) +# +# Visibility.Distance.Creature +# Visibility.Distance.Player +# Visibility distance for different in game object +# Max limited by active player zone: ~ 166 +# Min limit dependent from objects +# Default: 66 (cell size) +# Min limit is max aggro radius (45) * Rate.Creature.Aggro +# +# Visibility.Distance.Object +# Visible distance for gameobject, dynobject, bodies, corpses, bones +# Min limit is iteraction distance (5) +# +# Visibility.Distance.InFlight +# Visible distance for player in flight +# Min limit is 0 (not show any objects) +# +# Visibility.Distance.Grey.Unit +# Visibility grey distance for creatures/players (fast changing objects) +# addition to appropriate object type Visibility.Distance.* use in case visibility removing to +# object (except corpse around distences) If � is distance and G is grey distance then object +# make visible if distance to it <= D but make non visible if distance > D+G +# Default: 1 (yard) +# +# Visibility.Distance.Grey.Object +# Visibility grey distance for dynobjects/gameobjects/corpses/creature bodies +# Default: 10 (yards) +# +# +################################################################################################################### + +Visibility.GroupMode = 0 +Visibility.Distance.Creature = 66 +Visibility.Distance.Player = 66 +Visibility.Distance.Object = 66 +Visibility.Distance.InFlight = 66 +Visibility.Distance.Grey.Unit = 1 +Visibility.Distance.Grey.Object = 10 + +################################################################################################################### +# SERVER RATES +# +# Rate.Health +# Rate.Mana +# Rate.Rage.Income +# Rate.Rage.Loss +# Rate.Focus +# Rate.Loyalty +# Health and power regeneration and rage income from damage. +# Default: 1 +# +# Rate.Skill.Discovery +# Skill Discovery Rates +# Default: 1 +# +# Rate.Drop.Item.Poor +# Rate.Drop.Item.Normal +# Rate.Drop.Item.Uncommon +# Rate.Drop.Item.Rare +# Rate.Drop.Item.Epic +# Rate.Drop.Item.Legendary +# Rate.Drop.Item.Artifact +# Rate.Drop.Item.Referenced +# Rate.Drop.Money +# Drop rates (items by quality and money) +# Default: 1 +# +# Rate.Drop.Money +# Drop rates +# Default: 1 +# +# Rate.XP.Kill +# Rate.XP.Quest +# Rate.XP.Explore +# XP rates +# Default: 1 +# +# Rate.XP.PastLevel70 +# XP needed per level past 70 (Rates below 1 not recommended) +# Default: 1 +# +# Rate.Rest.InGame +# Rate.Rest.Offline.InTavernOrCity +# Rate.Rest.Offline.InWilderness +# Resting points grow rates (1 - normal, 2 - double rate, 0.5 - half rate, etc) from standard values +# +# Rate.Damage.Fall +# Damage after fall rate. (1 - standard, 2 - double damage, 0.5 - half damage, etc) +# +# Rate.Auction.Time +# Rate.Auction.Deposit +# Rate.Auction.Cut +# Auction rates (auction time, deposit get at auction start, auction cut from price at auction end) +# +# Rate.Honor +# Honor gain rate +# +# Rate.Mining.Amount +# Rate.Mining.Next +# Mining Rates (Mining.Amount changes minimum/maximum usetimes of a deposit, +# Mining.Next changes chance to have next use of a deposit) +# +# Rate.Talent +# Talent Point rates +# Default: 1 +# +# Rate.Reputation.Gain +# Reputation Gain rate +# Default: 1 +# +# Rate.InstanceResetTime +# Multiplier for the number of days in between global raid/heroic instance resets. +# Default: 1 +# +# SkillGain.Crafting +# SkillGain.Defense +# SkillGain.Gathering +# SkillGain.Weapon +# crafting/defense/gathering/weapon skills gain at skill grow (1,2,...) +# Default: 1 +# +# SkillChance.Orange +# SkillChance.Yellow +# SkillChance.Green +# SkillChance.Grey +# Skill chance values (0..100) +# Default: 100-75-25-0 +# +# SkillChance.MiningSteps +# SkillChance.SkinningSteps +# For skinning and Mining chance decrease with skill level. +# Default: 0 - no decrease +# 75 - in 2 times each 75 skill points +# +# DurabilityLossChance.Damage +# Chance lost one from equiped items durability point at damage apply or receive. +# Default: 0.5 (100/0.5 = 200) Each 200 damage apply one from 19 possible equipped items +# +# DurabilityLossChance.Absorb +# Chance lost one from armor items durability point at damage absorb. +# Default: 0.5 (100/0.5 = 200) Each 200 absorbs apply one from 15 possible armor equipped items +# +# DurabilityLossChance.Parry +# Chance lost weapon durability point at parry. +# Default: 0.05 (100/0.05 = 2000) Each 2000 parry attacks main weapon lost point +# +# DurabilityLossChance.Block +# Chance lost sheild durability point at damage block. +# Default: 0.05 (100/0.05 = 2000) Each 2000 partly or full blocked attacks shield lost point +# +# Death.SicknessLevel +# Starting Character start gain sickness at spirit resurrection (1 min) +# Default: 11 +# -10 - character will have full time (10min) sickness at 1 level +# maxplayerlevel+1 - chaarcter will not have sickess at any level +# +# Death.CorpseReclaimDelay.PvP +# Death.CorpseReclaimDelay.PvE +# Enabled/disabled increase corpse reclaim delay at often PvP/PvE deaths +# Default: 1 (enabled) +# 0 (disabled) +# +################################################################################################################### + +Rate.Health = 1 +Rate.Mana = 1 +Rate.Rage.Income = 1 +Rate.Rage.Loss = 1 +Rate.Focus = 1 +Rate.Loyalty = 1 +Rate.Skill.Discovery = 1 +Rate.Drop.Item.Poor = 1 +Rate.Drop.Item.Normal = 1 +Rate.Drop.Item.Uncommon = 1 +Rate.Drop.Item.Rare = 1 +Rate.Drop.Item.Epic = 1 +Rate.Drop.Item.Legendary = 1 +Rate.Drop.Item.Artifact = 1 +Rate.Drop.Item.Referenced = 1 +Rate.Drop.Money = 1 +Rate.XP.Kill = 1 +Rate.XP.Quest = 1 +Rate.XP.Explore = 1 +Rate.XP.PastLevel70 = 1 +Rate.Rest.InGame = 1 +Rate.Rest.Offline.InTavernOrCity = 1 +Rate.Rest.Offline.InWilderness = 1 +Rate.Damage.Fall = 1 +Rate.Auction.Time = 1 +Rate.Auction.Deposit = 1 +Rate.Auction.Cut = 1 +Rate.Honor = 1 +Rate.Mining.Amount = 1 +Rate.Mining.Next = 1 +Rate.Talent = 1 +Rate.Reputation.Gain = 1 +Rate.InstanceResetTime = 1 +SkillGain.Crafting = 1 +SkillGain.Defense = 1 +SkillGain.Gathering = 1 +SkillGain.Weapon = 1 +SkillChance.Orange = 100 +SkillChance.Yellow = 75 +SkillChance.Green = 25 +SkillChance.Grey = 0 +SkillChance.MiningSteps = 0 +SkillChance.SkinningSteps = 0 +DurabilityLossChance.Damage = 0.5 +DurabilityLossChance.Absorb = 0.5 +DurabilityLossChance.Parry = 0.05 +DurabilityLossChance.Block = 0.05 +Death.SicknessLevel = 11 +Death.CorpseReclaimDelay.PvP = 1 +Death.CorpseReclaimDelay.PvE = 1 + +################################################################################################################### +# +# Network config +# +# Threads: Number of threads for network, recommend 1 thread per 1000 connections. +# Default: 1 +# +# OutKBuff: The size of the output kernel buffer used ( SO_SNDBUF socket option, tcp manual ). +# Default: -1 (Use system default setting) +# +# OutUBuff: Userspace buffer for output. This is amount of memory reserved per each connection. +# Default: 65536 +# +# TcpNoDelay: +# TCP Nagle algorithm setting +# Default: 0 (enable Nagle algorithm, less traffic, more latency) +# 1 (TCP_NO_DELAY, disable Nagle algorithm, more traffic but less latency) +# +# +# +################################################################################################################### + +Network.Threads = 1 +Network.OutKBuff = -1 +Network.OutUBuff = 65536 +Network.TcpNodelay = 1 + +################################################################################################################### +# CONSOLE AND REMOTE ACCESS +# +# Console.Enable +# Enable console +# Default: 1 - on +# 0 - off +# +# Ra.Enable +# Enable remote console +# Default: 0 - off +# 1 - on +# +# Ra.IP +# Default remote console ip address, use 0.0.0.0 for every address +# +# Ra.Port +# Default remote console port +# +# Ra.MinLevel +# Minimum level that's required to login,3 by default +# +# Ra.Secure +# Kick client on wrong pass +# +################################################################################################################### + +Console.Enable = 1 +Ra.Enable = 0 +Ra.IP = 0.0.0.0 +Ra.Port = 3443 +Ra.MinLevel = 3 +Ra.Secure = 1 diff --git a/src/mangosd/mangosd.ico b/src/mangosd/mangosd.ico new file mode 100644 index 000000000..27cee2ca0 Binary files /dev/null and b/src/mangosd/mangosd.ico differ diff --git a/src/mangosd/mangosd.rc b/src/mangosd/mangosd.rc new file mode 100644 index 000000000..43fcf5bbb --- /dev/null +++ b/src/mangosd/mangosd.rc @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +IDI_APPICON ICON DISCARDABLE "mangosd.ico" diff --git a/src/mangosd/monitor-mangosd b/src/mangosd/monitor-mangosd new file mode 100755 index 000000000..a740ae5e8 --- /dev/null +++ b/src/mangosd/monitor-mangosd @@ -0,0 +1,18 @@ +#!/bin/bash +# Massive Network Game Object Server +# Monitoring Script + +pid=`ps ax | awk '($5 ~ /mangos-worldd/) { print $1 }'` +cpu=`top -b -n 1 -p $pid | awk '($12 ~ /mangos-worldd/) { print $9 }'` +#echo $pid +#echo $cpu +intcpu=${cpu%.*} +#echo $intcpu +if [ "$intcpu" -gt "95" ] +then + kill -9 $pid + echo "Killed MaNGOS for exceeding it's cpu limit." + echo `date` ", Killed MaNGOS for $intcpu% CPU Usage." >> serverlog +else + echo "MaNGOS Passes the cpu test." +fi diff --git a/src/mangosd/run-mangosd b/src/mangosd/run-mangosd new file mode 100755 index 000000000..2287e516c --- /dev/null +++ b/src/mangosd/run-mangosd @@ -0,0 +1,14 @@ +#!/bin/bash +# Massive Network Game Object Server +# autorestart Script + +while : +do + echo "MaNGOS daemon restarted" + echo `date` >> crash.log & + ./mangosd | tail -n 20 >> crash.log + echo " " >> crash.log & + pid=`ps ax | awk '($5 ~ /mangosd/) { print $1 }'` + wait $pid + echo `date` ", MaNGOS daemon crashed and restarted." >> serverlog +done diff --git a/src/realmd/AuthCodes.h b/src/realmd/AuthCodes.h new file mode 100644 index 000000000..9e84f82a3 --- /dev/null +++ b/src/realmd/AuthCodes.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup realmd +*/ + +#ifndef _AUTHCODES_H +#define _AUTHCODES_H + +enum eAuthResults +{ + REALM_AUTH_SUCCESS = 0x00, + REALM_AUTH_FAILURE = 0x01, ///< Unable to connect + REALM_AUTH_UNKNOWN1 = 0x02, ///< Unable to connect + REALM_AUTH_ACCOUNT_BANNED = 0x03, ///< This account has been closed and is no longer available for use. Please go to /banned.html for further information. + REALM_AUTH_NO_MATCH = 0x04, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information + REALM_AUTH_UNKNOWN2 = 0x05, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information + REALM_AUTH_ACCOUNT_IN_USE = 0x06, ///< This account is already logged into . Please check the spelling and try again. + REALM_AUTH_PREPAID_TIME_LIMIT = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing + REALM_AUTH_SERVER_FULL = 0x08, ///< Could not log in to at this time. Please try again later. + REALM_AUTH_WRONG_BUILD_NUMBER = 0x09, ///< Unable to validate game version. This may be caused by file corruption or interference of another program. Please visit for more information and possible solutions to this issue. + REALM_AUTH_UPDATE_CLIENT = 0x0a, ///< Downloading + REALM_AUTH_UNKNOWN3 = 0x0b, ///< Unable to connect + REALM_AUTH_ACCOUNT_FREEZED = 0x0c, ///< This account has been temporarily suspended. Please go to /banned.html for further information + REALM_AUTH_UNKNOWN4 = 0x0d, ///< Unable to connect + REALM_AUTH_UNKNOWN5 = 0x0e, ///< Connected. + REALM_AUTH_PARENTAL_CONTROL = 0x0f ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at +}; + +enum LoginResult +{ + LOGIN_OK = 0x00, + LOGIN_FAILED = 0x01, + LOGIN_FAILED2 = 0x02, + LOGIN_BANNED = 0x03, + LOGIN_UNKNOWN_ACCOUNT = 0x04, + LOGIN_UNKNOWN_ACCOUNT3 = 0x05, + LOGIN_ALREADYONLINE = 0x06, + LOGIN_NOTIME = 0x07, + LOGIN_DBBUSY = 0x08, + LOGIN_BADVERSION = 0x09, + LOGIN_DOWNLOAD_FILE = 0x0A, + LOGIN_FAILED3 = 0x0B, + LOGIN_SUSPENDED = 0x0C, + LOGIN_FAILED4 = 0x0D, + LOGIN_CONNECTED = 0x0E, + LOGIN_PARENTALCONTROL = 0x0F, + LOGIN_LOCKED_ENFORCED = 0x10, +}; + +// we need to stick to 1 version or half of the stuff will work for someone +// others will not and opposite +// will only support WoW and WoW:TBC 2.4.3 client build 8606... + +#define EXPECTED_MANGOS_CLIENT_BUILD {8606, 0} + +#endif diff --git a/src/realmd/AuthSocket.cpp b/src/realmd/AuthSocket.cpp new file mode 100644 index 000000000..f06ab733a --- /dev/null +++ b/src/realmd/AuthSocket.cpp @@ -0,0 +1,975 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup realmd +*/ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "ByteBuffer.h" +#include "Config/ConfigEnv.h" +#include "Log.h" +#include "RealmList.h" +#include "AuthSocket.h" +#include "AuthCodes.h" +#include +#include "Auth/Sha1.h" +//#include "Util.h" -- for commented utf8ToUpperOnlyLatin + +extern RealmList m_realmList; + +extern DatabaseType dbRealmServer; + +#define ChunkSize 2048 + +enum eAuthCmd +{ + //AUTH_NO_CMD = 0xFF, + AUTH_LOGON_CHALLENGE = 0x00, + AUTH_LOGON_PROOF = 0x01, + //AUTH_RECONNECT_CHALLENGE = 0x02, + //AUTH_RECONNECT_PROOF = 0x03, + //update srv =4 + REALM_LIST = 0x10, + XFER_INITIATE = 0x30, + XFER_DATA = 0x31, + XFER_ACCEPT = 0x32, + XFER_RESUME = 0x33, + XFER_CANCEL = 0x34 +}; + +enum eStatus +{ + STATUS_CONNECTED = 0, + STATUS_AUTHED +}; + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some paltform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +typedef struct AUTH_LOGON_CHALLENGE_C +{ + uint8 cmd; + uint8 error; + uint16 size; + uint8 gamename[4]; + uint8 version1; + uint8 version2; + uint8 version3; + uint16 build; + uint8 platform[4]; + uint8 os[4]; + uint8 country[4]; + uint32 timezone_bias; + uint32 ip; + uint8 I_len; + uint8 I[1]; +} sAuthLogonChallenge_C; + +//typedef sAuthLogonChallenge_C sAuthReconnectChallenge_C; +/* +typedef struct +{ + uint8 cmd; + uint8 error; + uint8 unk2; + uint8 B[32]; + uint8 g_len; + uint8 g[1]; + uint8 N_len; + uint8 N[32]; + uint8 s[32]; + uint8 unk3[16]; +} sAuthLogonChallenge_S; +*/ + +typedef struct AUTH_LOGON_PROOF_C +{ + uint8 cmd; + uint8 A[32]; + uint8 M1[20]; + uint8 crc_hash[20]; + uint8 number_of_keys; + uint8 unk; // Added in 1.12.x client branch +} sAuthLogonProof_C; +/* +typedef struct +{ + uint16 unk1; + uint32 unk2; + uint8 unk3[4]; + uint16 unk4[20]; +} sAuthLogonProofKey_C; +*/ +typedef struct AUTH_LOGON_PROOF_S +{ + uint8 cmd; + uint8 error; + uint8 M2[20]; + uint32 unk1; + uint32 unk2; + uint16 unk3; +} sAuthLogonProof_S; + +typedef struct XFER_INIT +{ + uint8 cmd; // XFER_INITIATE + uint8 fileNameLen; // strlen(fileName); + uint8 fileName[1]; // fileName[fileNameLen] + uint64 file_size; // file size (bytes) + uint8 md5[MD5_DIGEST_LENGTH]; // MD5 +}XFER_INIT; + +typedef struct XFER_DATA +{ + uint8 opcode; + uint16 data_size; + uint8 data[ChunkSize]; +}XFER_DATA_STRUCT; + +typedef struct AuthHandler +{ + eAuthCmd cmd; + uint32 status; + bool (AuthSocket::*handler)(void); +}AuthHandler; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform +#if defined( __GNUC__ ) +#pragma pack() +#else +#pragma pack(pop) +#endif + +/// Launch a thread to transfer a patch to the client +class PatcherRunnable: public ZThread::Runnable +{ + public: + PatcherRunnable(class AuthSocket *); + void run(); + + private: + AuthSocket * mySocket; +}; + +typedef struct PATCH_INFO +{ + uint8 md5[MD5_DIGEST_LENGTH]; +}PATCH_INFO; + +/// Caches MD5 hash of client patches present on the server +class Patcher +{ + public: + typedef std::map Patches; + ~Patcher(); + Patcher(); + Patches::const_iterator begin() const { return _patches.begin(); } + Patches::const_iterator end() const { return _patches.end(); } + void LoadPatchMD5(char*); + bool GetHash(char * pat,uint8 mymd5[16]); + + private: + void LoadPatchesInfo(); + Patches _patches; +}; + +const AuthHandler table[] = +{ + { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge}, + { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof }, + { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList }, + { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept }, + { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume }, + { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel } +}; + +#define AUTH_TOTAL_COMMANDS sizeof(table)/sizeof(AuthHandler) + +///Holds the MD5 hash of client patches present on the server +Patcher PatchesCache; + +/// Constructor - set the N and g values for SRP6 +AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h) +{ + N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); + g.SetDword(7); + _authed = false; + pPatch=NULL; + + _accountSecurityLevel = SEC_PLAYER; +} + +/// Close patch file descriptor before leaving +AuthSocket::~AuthSocket() +{ + if(pPatch) + fclose(pPatch); +} + +/// Accept the connection and set the s random value for SRP6 +void AuthSocket::OnAccept() +{ + sLog.outBasic("Accepting connection from '%s:%d'", + GetRemoteAddress().c_str(), GetRemotePort()); + + s.SetRand(s_BYTE_SIZE * 8); +} + +/// Read the packet from the client +void AuthSocket::OnRead() +{ + ///- Read the packet + TcpSocket::OnRead(); + uint8 _cmd; + while (1) + { + if (!ibuf.GetLength()) + return; + + ///- Get the command out of it + ibuf.SoftRead((char *)&_cmd, 1); // UQ1: No longer exists in new net code ??? + //ibuf.Read((char *)&_cmd, 1); + /*char *command = (char *)malloc(1); + + ibuf.Read(command, 1); + + _cmd = (uint8)command;*/ + // assert(0); + size_t i; + + ///- Circle through known commands and call the correct command handler + for (i=0;i buf; + buf.resize(4); + + ibuf.Read((char *)&buf[0], 4); + + EndianConvert(*((uint16*)(buf[0]))); + uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; + DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining); + + if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining)) + return false; + + //No big fear of memory outage (size is int16, i.e. < 65536) + buf.resize(remaining + buf.size() + 1); + buf[buf.size() - 1] = 0; + sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; + + // BigEndian code, nop in little endian case + // size already converted + EndianConvert(*((uint32*)(&ch->gamename[0]))); + EndianConvert(ch->build); + EndianConvert(*((uint32*)(&ch->platform[0]))); + EndianConvert(*((uint32*)(&ch->os[0]))); + EndianConvert(*((uint32*)(&ch->country[0]))); + EndianConvert(ch->timezone_bias); + EndianConvert(ch->ip); + + ///- Read the remaining of the packet + ibuf.Read((char *)&buf[4], remaining); + DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); + DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); + + ByteBuffer pkt; + + _login = (const char*)ch->I; + + ///- Normalize account name + //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form + + //Escape the user login to avoid further SQL injection + //Memory will be freed on AuthSocket object destruction + _safelogin=_login; + dbRealmServer.escape_string(_safelogin); + + ///- Check if the client has one of the expected version numbers + bool valid_version=false; + int accepted_versions[]=EXPECTED_MANGOS_CLIENT_BUILD; + for(int i=0;accepted_versions[i];i++) + if(ch->build==accepted_versions[i]) + { + valid_version=true; + break; + } + + ///
    • if this is a valid version + if(valid_version) + { + pkt << (uint8) AUTH_LOGON_CHALLENGE; + pkt << (uint8) 0x00; + + ///- Verify that this IP is not in the ip_banned table + // No SQL injection possible (paste the IP address as passed by the socket) + dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + std::string address = GetRemoteAddress(); + dbRealmServer.escape_string(address); + QueryResult *result = dbRealmServer.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); + if(result) + { + pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; + sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ()); + delete result; + } + else + { + ///- Get the account details from the account table + // No SQL injection (escaped user name) + + result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ()); + if( result ) + { + ///- If the IP is 'locked', check that the player comes indeed from the correct IP address + bool locked = false; + if((*result)[2].GetUInt8() == 1) // if ip is locked + { + DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); + DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str()); + if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) ) + { + DEBUG_LOG("[AuthChallenge] Account IP differs"); + pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; + locked=true; + } + else + { + DEBUG_LOG("[AuthChallenge] Account IP matches"); + } + } + else + { + DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); + } + + if (!locked) + { + //set expired bans to inactive + dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + ///- If the account is banned, reject the logon attempt + QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); + if(banresult) + { + if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) + { + pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; + sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); + } + else + { + pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; + sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); + } + + delete banresult; + } + else + { + ///- Get the password from the account table, upper it, and make the SRP6 calculation + std::string rI = (*result)[0].GetCppString(); + _SetVSFields(rI); + + b.SetRand(19 * 8); + BigNumber gmod=g.ModExp(b, N); + B = ((v * 3) + gmod) % N; + + ASSERT(gmod.GetNumBytes() <= 32); + + BigNumber unk3; + unk3.SetRand(16*8); + + ///- Fill the response packet with the result + pkt << (uint8)REALM_AUTH_SUCCESS; + + // B may be calculated < 32B so we force minnimal length to 32B + pkt.append(B.AsByteArray(32), 32); // 32 bytes + pkt << (uint8)1; + pkt.append(g.AsByteArray(), 1); + pkt << (uint8)32; + pkt.append(N.AsByteArray(), 32); + pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes + pkt.append(unk3.AsByteArray(), 16); + pkt << (uint8)0; // Added in 1.12.x client branch + + uint8 secLevel = (*result)[4].GetUInt8(); + _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; + + std::string localeName; + localeName.resize(4); + for(int i = 0; i <4; ++i) + localeName[i] = ch->country[4-i-1]; + + _localization = GetLocaleByName(localeName); + + sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], _localization); + } + } + delete result; + } + else //no account + { + pkt<< (uint8) REALM_AUTH_NO_MATCH; + } + } + } //valid version + else + ///
    • else + { + ///- Check if we have the apropriate patch on the disk + char tmp[64]; + // No buffer overflow (fixed length of arguments) + sprintf(tmp,"./patches/%d%c%c%c%c.mpq",ch->build,ch->country[3], + ch->country[2],ch->country[1],ch->country[0]); + // This will be closed at the destruction of the AuthSocket (client deconnection) + FILE *pFile=fopen(tmp,"rb"); + if(!pFile) + { + pkt << (uint8) AUTH_LOGON_CHALLENGE; + pkt << (uint8) 0x00; + pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER; + DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", ch->build); + DEBUG_LOG("[AuthChallenge] Patch %s not found",tmp); + }else + { //have patch + pPatch=pFile; + XFER_INIT xferh; + + ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it) + if(PatchesCache.GetHash(tmp,(uint8*)&xferh.md5)) + { + DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s",tmp); + } + else + { //calculate patch md5 + printf("\n[AuthChallenge] Patch info for %s was not cached.",tmp); + PatchesCache.LoadPatchMD5(tmp); + PatchesCache.GetHash(tmp,(uint8*)&xferh.md5); + } + + ///- Send a packet to the client with the file length and MD5 hash + uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT}; + SendBuf((const char*)data,sizeof(data)); + + memcpy(&xferh,"0\x05Patch",7); + xferh.cmd=XFER_INITIATE; + fseek(pPatch,0,SEEK_END); + xferh.file_size=ftell(pPatch); + + SendBuf((const char*)&xferh,sizeof(xferh)); + return true; + } + } + ///
    + SendBuf((char const*)pkt.contents(), pkt.size()); + return true; +} + +/// Logon Proof command handler +bool AuthSocket::_HandleLogonProof() +{ + DEBUG_LOG("Entering _HandleLogonProof"); + ///- Read the packet + if (ibuf.GetLength() < sizeof(sAuthLogonProof_C)) + return false; + + sAuthLogonProof_C lp; + ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C)); + + ///- Continue the SRP6 calculation based on data received from the client + BigNumber A; + A.SetBinary(lp.A, 32); + + Sha1Hash sha; + sha.UpdateBigNumbers(&A, &B, NULL); + sha.Finalize(); + BigNumber u; + u.SetBinary(sha.GetDigest(), 20); + BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); + + uint8 t[32]; + uint8 t1[16]; + uint8 vK[40]; + memcpy(t, S.AsByteArray(), 32); + for (int i = 0; i < 16; i++) + { + t1[i] = t[i*2]; + } + sha.Initialize(); + sha.UpdateData(t1, 16); + sha.Finalize(); + for (int i = 0; i < 20; i++) + { + vK[i*2] = sha.GetDigest()[i]; + } + for (int i = 0; i < 16; i++) + { + t1[i] = t[i*2+1]; + } + sha.Initialize(); + sha.UpdateData(t1, 16); + sha.Finalize(); + for (int i = 0; i < 20; i++) + { + vK[i*2+1] = sha.GetDigest()[i]; + } + K.SetBinary(vK, 40); + + uint8 hash[20]; + + sha.Initialize(); + sha.UpdateBigNumbers(&N, NULL); + sha.Finalize(); + memcpy(hash, sha.GetDigest(), 20); + sha.Initialize(); + sha.UpdateBigNumbers(&g, NULL); + sha.Finalize(); + for (int i = 0; i < 20; i++) + { + hash[i] ^= sha.GetDigest()[i]; + } + BigNumber t3; + t3.SetBinary(hash, 20); + + sha.Initialize(); + sha.UpdateData(_login); + sha.Finalize(); + uint8 t4[SHA_DIGEST_LENGTH]; + memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); + + sha.Initialize(); + sha.UpdateBigNumbers(&t3, NULL); + sha.UpdateData(t4, SHA_DIGEST_LENGTH); + sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); + sha.Finalize(); + BigNumber M; + M.SetBinary(sha.GetDigest(), 20); + + ///- Check if SRP6 results match (password is correct), else send an error + if (!memcmp(M.AsByteArray(), lp.M1, 20)) + { + sLog.outBasic("User '%s' successfully authenticated", _login.c_str()); + + ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account + // No SQL injection (escaped user name) and IP address as received by socket + const char* K_hex = K.AsHexStr(); + dbRealmServer.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), _localization, _safelogin.c_str() ); + OPENSSL_free((void*)K_hex); + + ///- Finish SRP6 and send the final result to the client + sha.Initialize(); + sha.UpdateBigNumbers(&A, &M, &K, NULL); + sha.Finalize(); + + sAuthLogonProof_S proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk1 = 0x00800000; + proof.unk2 = 0x00; + proof.unk3 = 0x00; + + SendBuf((char *)&proof, sizeof(proof)); + + ///- Set _authed to true! + _authed = true; + } + else + { + char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0}; + SendBuf(data,sizeof(data)); + sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ()); + + uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); + if(MaxWrongPassCount > 0) + { + //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP + dbRealmServer.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str()); + + if(QueryResult *loginfail = dbRealmServer.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str())) + { + Field* fields = loginfail->Fetch(); + uint32 failed_logins = fields[1].GetUInt32(); + + if( failed_logins >= MaxWrongPassCount ) + { + uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); + bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); + + if(WrongPassBanType) + { + uint32 acc_id = fields[0].GetUInt32(); + dbRealmServer.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)", + acc_id, WrongPassBanTime); + sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", + _login.c_str(), WrongPassBanTime, failed_logins); + } + else + { + std::string current_ip = GetRemoteAddress(); + dbRealmServer.escape_string(current_ip); + dbRealmServer.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')", + current_ip.c_str(), WrongPassBanTime); + sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", + current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); + } + } + delete loginfail; + } + } + } + return true; +} + +/// %Realm List command handler +bool AuthSocket::_HandleRealmList() +{ + DEBUG_LOG("Entering _HandleRealmList"); + if (ibuf.GetLength() < 5) + return false; + + ibuf.Remove(5); + + ///- Get the user id (else close the connection) + // No SQL injection (escaped user name) + + QueryResult *result = dbRealmServer.PQuery("SELECT id,sha_pass_hash FROM account WHERE username = '%s'",_safelogin.c_str()); + if(!result) + { + sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str()); + SetCloseAndDelete(); + return false; + } + + uint32 id = (*result)[0].GetUInt32(); + std::string rI = (*result)[1].GetCppString(); + delete result; + + ///- Update realm list if need + m_realmList.UpdateIfNeed(); + + ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) + ByteBuffer pkt; + pkt << (uint32) 0; + pkt << (uint16) m_realmList.size(); + RealmList::RealmMap::const_iterator i; + for( i = m_realmList.begin(); i != m_realmList.end(); i++ ) + { + uint8 AmountOfCharacters; + + // No SQL injection. id of realm is controlled by the database. + result = dbRealmServer.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id); + if( result ) + { + Field *fields = result->Fetch(); + AmountOfCharacters = fields[0].GetUInt8(); + delete result; + } + else + AmountOfCharacters = 0; + + uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + + pkt << i->second.icon; // realm type + pkt << lock; // if 1, then realm locked + pkt << i->second.color; // if 2, then realm is offline + pkt << i->first; + pkt << i->second.address; + pkt << i->second.populationLevel; + pkt << AmountOfCharacters; + pkt << i->second.timezone; // realm category + pkt << (uint8) 0x2C; // unk, may be realm number/id? + } + pkt << (uint8) 0x10; + pkt << (uint8) 0x00; + + ByteBuffer hdr; + hdr << (uint8) REALM_LIST; + hdr << (uint16)pkt.size(); + hdr.append(pkt); + + SendBuf((char const*)hdr.contents(), hdr.size()); + + // Set check field before possible relogin to realm + _SetVSFields(rI); + return true; +} + +/// Resume patch transfer +bool AuthSocket::_HandleXferResume() +{ + DEBUG_LOG("Entering _HandleXferResume"); + ///- Check packet length and patch existence + if (ibuf.GetLength()<9 || !pPatch) + { + sLog.outError("Error while resuming patch transfer (wrong packet)"); + return false; + } + + ///- Launch a PatcherRunnable thread starting at given patch file offset + uint64 start; + ibuf.Remove(1); + ibuf.Read((char*)&start,sizeof(start)); + fseek(pPatch,start,0); + + ZThread::Thread u(new PatcherRunnable(this)); + return true; +} + +/// Cancel patch transfer +bool AuthSocket::_HandleXferCancel() +{ + DEBUG_LOG("Entering _HandleXferCancel"); + + ///- Close and delete the socket + ibuf.Remove(1); //clear input buffer + + //ZThread::Thread::sleep(15); + SetCloseAndDelete(); + + return true; +} + +/// Accept patch transfer +bool AuthSocket::_HandleXferAccept() +{ + DEBUG_LOG("Entering _HandleXferAccept"); + + ///- Check packet length and patch existence + if (!pPatch) + { + sLog.outError("Error while accepting patch transfer (wrong packet)"); + return false; + } + + ///- Launch a PatcherRunnable thread, starting at the begining of the patch file + ibuf.Remove(1); //clear input buffer + fseek(pPatch,0,0); + + ZThread::Thread u(new PatcherRunnable(this)); + + return true; +} + +/// Check if there is lag on the connection to the client +bool AuthSocket::IsLag() +{ + return (TCP_BUFSIZE_READ-GetOutputLength()< 2*ChunkSize); +} + +PatcherRunnable::PatcherRunnable(class AuthSocket * as) +{ + mySocket=as; +} + +/// Send content of patch file to the client +void PatcherRunnable::run() +{ + XFER_DATA_STRUCT xfdata; + xfdata.opcode = XFER_DATA; + + while(!feof(mySocket->pPatch) && mySocket->Ready()) + { + ///- Wait until output buffer is reasonably empty + while(mySocket->Ready() && mySocket->IsLag()) + { + ZThread::Thread::sleep(1); + } + ///- And send content of the patch file to the client + xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch); + mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize)); + } +} + +/// Preload MD5 hashes of existing patch files on server +#ifndef _WIN32 +#include +#include +void Patcher::LoadPatchesInfo() +{ + DIR * dirp; + //int errno; + struct dirent * dp; + dirp = opendir("./patches/"); + if(!dirp) + return; + while (dirp) + { + errno = 0; + if ((dp = readdir(dirp)) != NULL) + { + int l=strlen(dp->d_name); + if(l<8)continue; + if(!memcmp(&dp->d_name[l-4],".mpq",4)) + LoadPatchMD5(dp->d_name); + } + else + { + if(errno != 0) + { + closedir(dirp); + return; + } + break; + } + } + + if(dirp) + closedir(dirp); +} + +#else +void Patcher::LoadPatchesInfo() +{ + WIN32_FIND_DATA fil; + HANDLE hFil=FindFirstFile("./patches/*.mpq",&fil); + if(hFil==INVALID_HANDLE_VALUE) + return; //no patches were found + + LoadPatchMD5(fil.cFileName); + + while(FindNextFile(hFil,&fil)) + LoadPatchMD5(fil.cFileName); +} +#endif + +/// Calculate and store MD5 hash for a given patch file +void Patcher::LoadPatchMD5(char * szFileName) +{ + ///- Try to open the patch file + std::string path = "./patches/"; + path += szFileName; + FILE * pPatch=fopen(path.c_str(),"rb"); + sLog.outDebug("Loading patch info from %s\n",path.c_str()); + if(!pPatch) + { + sLog.outError("Error loading patch %s\n",path.c_str()); + return; + } + + ///- Calculate the MD5 hash + MD5_CTX ctx; + MD5_Init(&ctx); + uint8* buf = new uint8[512*1024]; + + while (!feof(pPatch)) + { + size_t read = fread(buf, 1, 512*1024, pPatch); + MD5_Update(&ctx, buf, read); + } + delete [] buf; + fclose(pPatch); + + ///- Store the result in the internal patch hash map + _patches[path] = new PATCH_INFO; + MD5_Final((uint8 *)&_patches[path]->md5 , &ctx); +} + +/// Get cached MD5 hash for a given patch file +bool Patcher::GetHash(char * pat,uint8 mymd5[16]) +{ + for( Patches::iterator i = _patches.begin(); i != _patches.end(); i++ ) + if(!stricmp(pat,i->first.c_str () )) + { + memcpy(mymd5,i->second->md5,16); + return true; + } + + return false; +} + +/// Launch the patch hashing mechanism on object creation +Patcher::Patcher() +{ + LoadPatchesInfo(); +} + +/// Empty and delete the patch map on termination +Patcher::~Patcher() +{ + for(Patches::iterator i = _patches.begin(); i != _patches.end(); i++ ) + delete i->second; +} diff --git a/src/realmd/AuthSocket.h b/src/realmd/AuthSocket.h new file mode 100644 index 000000000..cb59d2ec5 --- /dev/null +++ b/src/realmd/AuthSocket.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup realmd +/// @{ +/// \file + +#ifndef _AUTHSOCKET_H +#define _AUTHSOCKET_H + +#include "Common.h" +#include "Auth/BigNumber.h" +#include "sockets/TcpSocket.h" +#include "sockets/SocketHandler.h" +#include "sockets/ListenSocket.h" +#include "sockets/Utility.h" +#include "sockets/Parse.h" +#include "sockets/Socket.h" + +/// Handle login commands +class AuthSocket: public TcpSocket +{ + public: + const static int s_BYTE_SIZE = 32; + + AuthSocket(ISocketHandler& h); + ~AuthSocket(); + + void OnAccept(); + void OnRead(); + + bool _HandleLogonChallenge(); + bool _HandleLogonProof(); + bool _HandleRealmList(); + //data transfer handle for patch + + bool _HandleXferResume(); + bool _HandleXferCancel(); + bool _HandleXferAccept(); + + void _SetVSFields(std::string rI); + + FILE *pPatch; + bool IsLag(); + + private: + + BigNumber N, s, g, v; + BigNumber b, B; + BigNumber K; + + bool _authed; + + std::string _login; + std::string _safelogin; + uint8 _localization; + AccountTypes _accountSecurityLevel; +}; +#endif +/// @} diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp new file mode 100644 index 000000000..b9d53af17 --- /dev/null +++ b/src/realmd/Main.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup realmd Realm Daemon +/// @{ +/// \file + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "RealmList.h" + +#include "Config/ConfigEnv.h" +#include "Log.h" +#include "sockets/ListenSocket.h" +#include "AuthSocket.h" +#include "SystemConfig.h" +#include "Util.h" + +#ifdef WIN32 +#include "ServiceWin32.h" +char serviceName[] = "realmd"; +char serviceLongName[] = "MaNGOS realmd service"; +char serviceDescription[] = "Massive Network Game Object Server"; +/* + * -1 - not in service mode + * 0 - stopped + * 1 - running + * 2 - paused + */ +int m_ServiceStatus = -1; +#endif + +bool StartDB(std::string &dbstring); +void UnhookSignals(); +void HookSignals(); + +bool stopEvent = false; ///< Setting it to true stops the server +RealmList m_realmList; ///< Holds the list of realms for this server + +DatabaseType dbRealmServer; ///< Accessor to the realm server database + +/// Print out the usage string for this program on the console. +void usage(const char *prog) +{ + sLog.outString("Usage: \n %s []\n" + " -c config_file use config_file as configuration file\n\r" + #ifdef WIN32 + " Running as service functions:\n\r" + " --service run as service\n\r" + " -s install install service\n\r" + " -s uninstall uninstall service\n\r" + #endif + ,prog); +} + +/// Launch the realm server +extern int main(int argc, char **argv) +{ + ///- Command line parsing to get the configuration file name + char const* cfg_file = _REALMD_CONFIG; + int c=1; + while( c < argc ) + { + if( strcmp(argv[c],"-c") == 0) + { + if( ++c >= argc ) + { + sLog.outError("Runtime-Error: -c option requires an input argument"); + usage(argv[0]); + return 1; + } + else + cfg_file = argv[c]; + } + + #ifdef WIN32 + //////////// + //Services// + //////////// + if( strcmp(argv[c],"-s") == 0) + { + if( ++c >= argc ) + { + sLog.outError("Runtime-Error: -s option requires an input argument"); + usage(argv[0]); + return 1; + } + if( strcmp(argv[c],"install") == 0) + { + if (WinServiceInstall()) + sLog.outString("Installing service"); + return 1; + } + else if( strcmp(argv[c],"uninstall") == 0) + { + if(WinServiceUninstall()) + sLog.outString("Uninstalling service"); + return 1; + } + else + { + sLog.outError("Runtime-Error: unsupported option %s",argv[c]); + usage(argv[0]); + return 1; + } + } + if( strcmp(argv[c],"--service") == 0) + { + WinServiceRun(); + } + //// + #endif + ++c; + } + + if (!sConfig.SetSource(cfg_file)) + { + sLog.outError("Could not find configuration file %s.", cfg_file); + return 1; + } + sLog.outString("Using configuration file %s.", cfg_file); + + ///- Check the version of the configuration file + uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); + if (confVersion < _REALMDCONFVERSION) + { + sLog.outError("*****************************************************************************"); + sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); + sLog.outError(" Please check for updates, as your current default values may cause"); + sLog.outError(" strange behavior."); + sLog.outError("*****************************************************************************"); + clock_t pause = 3000 + clock(); + + while (pause > clock()) {} + } + + sLog.outString( "%s (realm-daemon)", _FULLVERSION ); + sLog.outString( " to stop.\n" ); + + /// realmd PID file creation + std::string pidfile = sConfig.GetStringDefault("PidFile", ""); + if(!pidfile.empty()) + { + uint32 pid = CreatePIDFile(pidfile); + if( !pid ) + { + sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); + return 1; + } + + sLog.outString( "Daemon PID: %u\n", pid ); + } + + ///- Initialize the database connection + std::string dbstring; + if(!StartDB(dbstring)) + return 1; + + ///- Get the list of realms for the server + m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); + if (m_realmList.size() == 0) + { + sLog.outError("No valid realms specified."); + return 1; + } + + ///- Launch the listening network socket + port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT ); + std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); + + SocketHandler h; + ListenSocket authListenSocket(h); + if ( authListenSocket.Bind(bind_ip.c_str(),rmport)) + { + sLog.outError( "MaNGOS realmd can not bind to %s:%d",bind_ip.c_str(), rmport ); + return 1; + } + + h.Add(&authListenSocket); + + ///- Catch termination signals + HookSignals(); + + ///- Handle affinity for multiple processors and process priority on Windows + #ifdef WIN32 + { + HANDLE hProcess = GetCurrentProcess(); + + uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); + if(Aff > 0) + { + ULONG_PTR appAff; + ULONG_PTR sysAff; + + if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) + { + ULONG_PTR curAff = Aff & appAff; // remove non accessible processors + + if(!curAff ) + { + sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); + } + else + { + if(SetProcessAffinityMask(hProcess,curAff)) + sLog.outString("Using processors (bitmask, hex): %x", curAff); + else + sLog.outError("Can't set used processors (hex): %x", curAff); + } + } + sLog.outString(); + } + + bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); + + if(Prio) + { + if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) + sLog.outString("realmd process priority class set to HIGH"); + else + sLog.outError("ERROR: Can't set realmd process priority class."); + sLog.outString(); + } + } + #endif + + // maximum counter for next ping + uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); + uint32 loopCounter = 0; + + ///- Wait for termination signal + while (!stopEvent) + { + + h.Select(0, 100000); + + if( (++loopCounter) == numLoops ) + { + loopCounter = 0; + sLog.outDetail("Ping MySQL to keep connection alive"); + delete dbRealmServer.Query("SELECT 1 FROM realmlist LIMIT 1"); + } +#ifdef WIN32 + if (m_ServiceStatus == 0) stopEvent = true; + while (m_ServiceStatus == 2) Sleep(1000); +#endif + } + + ///- Wait for the delay thread to exit + dbRealmServer.HaltDelayThread(); + + ///- Remove signal handling before leaving + UnhookSignals(); + + sLog.outString( "Halting process..." ); + return 0; +} + +/// Handle termination signals +/** Put the global variable stopEvent to 'true' if a termination signal is caught **/ +void OnSignal(int s) +{ + switch (s) + { + case SIGINT: + case SIGTERM: + stopEvent = true; + break; + #ifdef _WIN32 + case SIGBREAK: + stopEvent = true; + break; + #endif + } + + signal(s, OnSignal); +} + +/// Initialize connection to the database +bool StartDB(std::string &dbstring) +{ + if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) + { + sLog.outError("Database not specified"); + return false; + } + + sLog.outString("Database: %s", dbstring.c_str() ); + if(!dbRealmServer.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to database"); + return false; + } + + return true; +} + +/// Define hook 'OnSignal' for all termination signals +void HookSignals() +{ + signal(SIGINT, OnSignal); + signal(SIGTERM, OnSignal); + #ifdef _WIN32 + signal(SIGBREAK, OnSignal); + #endif +} + +/// Unhook the signals before leaving +void UnhookSignals() +{ + signal(SIGINT, 0); + signal(SIGTERM, 0); + #ifdef _WIN32 + signal(SIGBREAK, 0); + #endif +} + +/// @} diff --git a/src/realmd/Makefile.am b/src/realmd/Makefile.am new file mode 100644 index 000000000..dd85d3b80 --- /dev/null +++ b/src/realmd/Makefile.am @@ -0,0 +1,57 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir) + +## Build realm list daemon as standalone program +bin_PROGRAMS = mangos-realmd +mangos_realmd_SOURCES = \ + AuthCodes.h \ + AuthSocket.cpp \ + AuthSocket.h \ + Main.cpp \ + RealmList.cpp \ + RealmList.h + +## Link realm list daemon against the shared library +mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la +mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L$(libdir) $(MANGOS_LIBS) + +## Additional files to include when running 'make dist' +# Include realm list daemon configuration +EXTRA_DIST = \ + realmd.conf.dist + +## Additional files to install +sysconf_DATA = \ + realmd.conf.dist + +install-data-hook: + @list='$(sysconf_DATA)'; for p in $$list; do \ + dest=`echo $$p | sed -e s/.dist//`; \ + if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \ + echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \ + else \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \ + fi; \ + done + +clean-local: + rm -f $(sysconf_DATA) diff --git a/src/realmd/RealmList.cpp b/src/realmd/RealmList.cpp new file mode 100644 index 000000000..ab511310c --- /dev/null +++ b/src/realmd/RealmList.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** \file + \ingroup realmd +*/ + +#include "Common.h" +#include "RealmList.h" +#include "Policies/SingletonImp.h" +#include "Database/DatabaseEnv.h" + +INSTANTIATE_SINGLETON_1( RealmList ); + +extern DatabaseType dbRealmServer; + +RealmList::RealmList( ) : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)) +{ +} + +/// Load the realm list from the database +void RealmList::Initialize(uint32 updateInterval) +{ + m_UpdateInterval = updateInterval; + + ///- Get the content of the realmlist table in the database + UpdateRealms(true); +} + +void RealmList::UpdateRealm( uint32 ID, std::string name, std::string address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu) +{ + ///- Create new if not exist or update existed + Realm& realm = m_realms[name]; + + realm.m_ID = ID; + realm.name = name; + realm.icon = icon; + realm.color = color; + realm.timezone = timezone; + realm.allowedSecurityLevel = allowedSecurityLevel; + realm.populationLevel = popu; + + ///- Append port to IP address. + std::ostringstream ss; + ss << address << ":" << port; + realm.address = ss.str(); +} + +void RealmList::UpdateIfNeed() +{ + // maybe disabled or updated recently + if(!m_UpdateInterval || m_NextUpdateTime > time(NULL)) + return; + + m_NextUpdateTime = time(NULL) + m_UpdateInterval; + + // Clears Realm list + m_realms.clear(); + + // Get the content of the realmlist table in the database + UpdateRealms(false); +} + +void RealmList::UpdateRealms(bool init) +{ + sLog.outDetail("Updating Realm List..."); + + QueryResult *result = dbRealmServer.Query( "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population FROM realmlist WHERE color <> 3 ORDER BY name" ); + + ///- Circle through results and add them to the realm map + if(result) + { + do + { + Field *fields = result->Fetch(); + + uint8 allowedSecurityLevel = fields[7].GetUInt8(); + + UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat() ); + if(init) + sLog.outString("Added realm \"%s\".", fields[1].GetString()); + } while( result->NextRow() ); + delete result; + } +} diff --git a/src/realmd/RealmList.h b/src/realmd/RealmList.h new file mode 100644 index 000000000..4c3717970 --- /dev/null +++ b/src/realmd/RealmList.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup realmd +/// @{ +/// \file + +#ifndef _REALMLIST_H +#define _REALMLIST_H + +#include "Common.h" + +/// Storage object for a realm +struct Realm +{ + std::string name; + std::string address; + uint8 icon; + uint8 color; + uint8 timezone; + uint32 m_ID; + AccountTypes allowedSecurityLevel; + float populationLevel; +}; + +/// Storage object for the list of realms on the server +class RealmList +{ + public: + typedef std::map RealmMap; + + RealmList(); + ~RealmList() {} + + void Initialize(uint32 updateInterval); + + void UpdateIfNeed(); + + RealmMap::const_iterator begin() const { return m_realms.begin(); } + RealmMap::const_iterator end() const { return m_realms.end(); } + uint32 size() const { return m_realms.size(); } + private: + void UpdateRealms(bool init); + void UpdateRealm( uint32 ID, std::string name, std::string address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu); + private: + RealmMap m_realms; ///< Internal map of realms + uint32 m_UpdateInterval; + time_t m_NextUpdateTime; +}; +#endif +/// @} diff --git a/src/realmd/realmd.conf.dist.in b/src/realmd/realmd.conf.dist.in new file mode 100644 index 000000000..da62747a8 --- /dev/null +++ b/src/realmd/realmd.conf.dist.in @@ -0,0 +1,116 @@ +############################################ +# MaNGOS realmd configuration file # +############################################ +ConfVersion=2007062001 + +################################################################################################################### +# REALMD SETTINGS +# +# LoginDatabaseInfo +# Database connection settings for the realm server. +# Default: hostname;port;username;password;database +# .;somenumber;username;password;database - use named pipes at Windows +# Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini +# .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux +# Unix sockets: experimental, not tested +# +# LogsDir +# Logs directory setting. +# Important: Logs dir must exists, or all logs be disable +# Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be +# stored in current directory for run program. +# +# MaxPingTime +# Settings for maximum database-ping interval (minutes between pings) +# +# RealmServerPort +# Default RealmServerPort +# +# BindIP +# Bind Realm Server to IP/hostname +# +# PidFile +# Realmd daemon PID file +# Default: "" - do not create PID file +# "./realmd.pid" - create PID file (recommended name) +# +# LogLevel +# Server console level of logging +# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug +# Default: 0 +# +# LogTime +# Include time in server console output [hh:mm:ss] +# Default: 0 (no time) +# 1 (print time) +# +# LogFile +# Logfile name +# Default: "Realmd.log" +# "" - empty name disable creating log file +# +# LogTimestamp +# Logfile with timestamp of server start in name +# Default: 0 - no timestamp in name +# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +# LogFileLevel +# Server file level of logging +# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug +# Default: 0 +# +# LogColors +# Color for messages (format "normal_color details_color debug_color error_color) +# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY, +# 8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE +# Default: "" - none colors +# "13 7 11 9" - for example :) +# +# UseProcessors +# Used processors mask for multi-processors system (Used only at Windows) +# Default: 0 (selected by OS) +# number (bitmask value of selected processors) +# +# ProcessPriority +# Process proirity setting (Used only at Windows) +# Default: 1 (HIGH) +# 0 (Normal) +# +# RealmsStateUpdateDelay +# Realm list Update up delay (updated at realm list request if delay expired). +# Default: 20 +# 0 (Disabled) +# +# WrongPass.MaxCount +# Number of login attemps with wrong password before the account or IP is banned +# Default: 0 (Never ban) +# +# WrongPass.BanTime +# Duration of the ban in seconds (0 means permanent ban) +# Default: 600 +# +# WrongPass.BanType +# Ban the IP or account on which login is attempted +# Default: 0 (Ban IP) +# 1 (Ban Account) +# +################################################################################################################### + +LoginDatabaseInfo = "127.0.0.1;3306;root;mangos;realmd" +LogsDir = "" +MaxPingTime = 30 +RealmServerPort = 3724 +BindIP = "0.0.0.0" +PidFile = "" +LogLevel = 0 +LogTime = 0 +LogFile = "Realmd.log" +LogTimestamp = 0 +LogFileLevel = 0 +LogColors = "" +UseProcessors = 0 +ProcessPriority = 1 +RealmsStateUpdateDelay = 20 +WrongPass.MaxCount = 0 +WrongPass.BanTime = 600 +WrongPass.BanType = 0 diff --git a/src/realmd/realmd.ico b/src/realmd/realmd.ico new file mode 100644 index 000000000..27cee2ca0 Binary files /dev/null and b/src/realmd/realmd.ico differ diff --git a/src/realmd/realmd.rc b/src/realmd/realmd.rc new file mode 100644 index 000000000..4ce3301fb --- /dev/null +++ b/src/realmd/realmd.rc @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +IDI_APPICON ICON DISCARDABLE "realmd.ico" diff --git a/src/shared/Auth/AuthCrypt.cpp b/src/shared/Auth/AuthCrypt.cpp new file mode 100644 index 000000000..7631248bb --- /dev/null +++ b/src/shared/Auth/AuthCrypt.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "AuthCrypt.h" +#include "Hmac.h" + +AuthCrypt::AuthCrypt() +{ + _initialized = false; +} + +void AuthCrypt::Init() +{ + _send_i = _send_j = _recv_i = _recv_j = 0; + _initialized = true; +} + +void AuthCrypt::DecryptRecv(uint8 *data, size_t len) +{ + if (!_initialized) return; + if (len < CRYPTED_RECV_LEN) return; + + for (size_t t = 0; t < CRYPTED_RECV_LEN; t++) + { + _recv_i %= _key.size(); + uint8 x = (data[t] - _recv_j) ^ _key[_recv_i]; + ++_recv_i; + _recv_j = data[t]; + data[t] = x; + } +} + +void AuthCrypt::EncryptSend(uint8 *data, size_t len) +{ + if (!_initialized) return; + if (len < CRYPTED_SEND_LEN) return; + + for (size_t t = 0; t < CRYPTED_SEND_LEN; t++) + { + _send_i %= _key.size(); + uint8 x = (data[t] ^ _key[_send_i]) + _send_j; + ++_send_i; + data[t] = _send_j = x; + } +} + +void AuthCrypt::SetKey(BigNumber *bn) +{ + uint8 *key = new uint8[SHA_DIGEST_LENGTH]; + GenerateKey(key, bn); + _key.resize(SHA_DIGEST_LENGTH); + std::copy(key, key + SHA_DIGEST_LENGTH, _key.begin()); + delete key; +} + +AuthCrypt::~AuthCrypt() +{ +} + +void AuthCrypt::GenerateKey(uint8 *key, BigNumber *bn) +{ + HmacHash hash; + hash.UpdateBigNumber(bn); + hash.Finalize(); + memcpy(key, hash.GetDigest(), SHA_DIGEST_LENGTH); +} diff --git a/src/shared/Auth/AuthCrypt.h b/src/shared/Auth/AuthCrypt.h new file mode 100644 index 000000000..9d9779d77 --- /dev/null +++ b/src/shared/Auth/AuthCrypt.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AUTHCRYPT_H +#define _AUTHCRYPT_H + +#include +#include + +class BigNumber; + +class AuthCrypt +{ + public: + AuthCrypt(); + ~AuthCrypt(); + + const static size_t CRYPTED_SEND_LEN = 4; + const static size_t CRYPTED_RECV_LEN = 6; + + void Init(); + + void SetKey(BigNumber *); + + void DecryptRecv(uint8 *, size_t); + void EncryptSend(uint8 *, size_t); + + bool IsInitialized() { return _initialized; } + + static void GenerateKey(uint8 *, BigNumber *); + + private: + std::vector _key; + uint8 _send_i, _send_j, _recv_i, _recv_j; + bool _initialized; +}; +#endif diff --git a/src/shared/Auth/BigNumber.cpp b/src/shared/Auth/BigNumber.cpp new file mode 100644 index 000000000..6bd2181ed --- /dev/null +++ b/src/shared/Auth/BigNumber.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Auth/BigNumber.h" +#include +#include + +BigNumber::BigNumber() +{ + _bn = BN_new(); + _array = NULL; +} + +BigNumber::BigNumber(const BigNumber &bn) +{ + _bn = BN_dup(bn._bn); + _array = NULL; +} + +BigNumber::BigNumber(uint32 val) +{ + _bn = BN_new(); + BN_set_word(_bn, val); + _array = NULL; +} + +BigNumber::~BigNumber() +{ + BN_free(_bn); + if(_array) delete[] _array; +} + +void BigNumber::SetDword(uint32 val) +{ + BN_set_word(_bn, val); +} + +void BigNumber::SetQword(uint64 val) +{ + BN_add_word(_bn, (uint32)(val >> 32)); + BN_lshift(_bn, _bn, 32); + BN_add_word(_bn, (uint32)(val & 0xFFFFFFFF)); +} + +void BigNumber::SetBinary(const uint8 *bytes, int len) +{ + uint8 t[1000]; + for (int i = 0; i < len; i++) t[i] = bytes[len - 1 - i]; + BN_bin2bn(t, len, _bn); +} + +void BigNumber::SetHexStr(const char *str) +{ + BN_hex2bn(&_bn, str); +} + +void BigNumber::SetRand(int numbits) +{ + BN_rand(_bn, numbits, 0, 1); +} + +BigNumber BigNumber::operator=(const BigNumber &bn) +{ + BN_copy(_bn, bn._bn); + return *this; +} + +BigNumber BigNumber::operator+=(const BigNumber &bn) +{ + BN_add(_bn, _bn, bn._bn); + return *this; +} + +BigNumber BigNumber::operator-=(const BigNumber &bn) +{ + BN_sub(_bn, _bn, bn._bn); + return *this; +} + +BigNumber BigNumber::operator*=(const BigNumber &bn) +{ + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + BN_mul(_bn, _bn, bn._bn, bnctx); + BN_CTX_free(bnctx); + + return *this; +} + +BigNumber BigNumber::operator/=(const BigNumber &bn) +{ + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + BN_div(_bn, NULL, _bn, bn._bn, bnctx); + BN_CTX_free(bnctx); + + return *this; +} + +BigNumber BigNumber::operator%=(const BigNumber &bn) +{ + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + BN_mod(_bn, _bn, bn._bn, bnctx); + BN_CTX_free(bnctx); + + return *this; +} + +BigNumber BigNumber::Exp(const BigNumber &bn) +{ + BigNumber ret; + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + BN_exp(ret._bn, _bn, bn._bn, bnctx); + BN_CTX_free(bnctx); + + return ret; +} + +BigNumber BigNumber::ModExp(const BigNumber &bn1, const BigNumber &bn2) +{ + BigNumber ret; + BN_CTX *bnctx; + + bnctx = BN_CTX_new(); + BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx); + BN_CTX_free(bnctx); + + return ret; +} + +int BigNumber::GetNumBytes(void) +{ + return BN_num_bytes(_bn); +} + +uint32 BigNumber::AsDword() +{ + return (uint32)BN_get_word(_bn); +} + +uint8 *BigNumber::AsByteArray(int minSize) +{ + int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes(); + + if (_array) + { + delete[] _array; + _array = NULL; + } + _array = new uint8[length]; + + // If we need more bytes than length of BigNumber set the rest to 0 + if (length > GetNumBytes()) + memset((void*)_array, 0, length); + + BN_bn2bin(_bn, (unsigned char *)_array); + + std::reverse(_array, _array + length); + + return _array; +} + +ByteBuffer BigNumber::AsByteBuffer() +{ + ByteBuffer ret(GetNumBytes()); + ret.append(AsByteArray(), GetNumBytes()); + return ret; +} + +std::vector BigNumber::AsByteVector() +{ + std::vector ret; + ret.resize(GetNumBytes()); + memcpy(&ret[0], AsByteArray(), GetNumBytes()); + return ret; +} + +const char *BigNumber::AsHexStr() +{ + return BN_bn2hex(_bn); +} + +const char *BigNumber::AsDecStr() +{ + return BN_bn2dec(_bn); +} diff --git a/src/shared/Auth/BigNumber.h b/src/shared/Auth/BigNumber.h new file mode 100644 index 000000000..9614b1e53 --- /dev/null +++ b/src/shared/Auth/BigNumber.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AUTH_BIGNUMBER_H +#define _AUTH_BIGNUMBER_H + +#include "Common.h" +#include "ByteBuffer.h" + +struct bignum_st; + +class BigNumber +{ + public: + BigNumber(); + BigNumber(const BigNumber &bn); + BigNumber(uint32); + ~BigNumber(); + + void SetDword(uint32); + void SetQword(uint64); + void SetBinary(const uint8 *bytes, int len); + void SetHexStr(const char *str); + + void SetRand(int numbits); + + BigNumber operator=(const BigNumber &bn); + + BigNumber operator+=(const BigNumber &bn); + BigNumber operator+(const BigNumber &bn) + { + BigNumber t(*this); + return t += bn; + } + BigNumber operator-=(const BigNumber &bn); + BigNumber operator-(const BigNumber &bn) + { + BigNumber t(*this); + return t -= bn; + } + BigNumber operator*=(const BigNumber &bn); + BigNumber operator*(const BigNumber &bn) + { + BigNumber t(*this); + return t *= bn; + } + BigNumber operator/=(const BigNumber &bn); + BigNumber operator/(const BigNumber &bn) + { + BigNumber t(*this); + return t /= bn; + } + BigNumber operator%=(const BigNumber &bn); + BigNumber operator%(const BigNumber &bn) + { + BigNumber t(*this); + return t %= bn; + } + + BigNumber ModExp(const BigNumber &bn1, const BigNumber &bn2); + BigNumber Exp(const BigNumber &); + + int GetNumBytes(void); + + struct bignum_st *BN() { return _bn; } + + uint32 AsDword(); + uint8* AsByteArray(int minSize = 0); + ByteBuffer AsByteBuffer(); + std::vector AsByteVector(); + + const char *AsHexStr(); + const char *AsDecStr(); + + private: + struct bignum_st *_bn; + uint8 *_array; +}; +#endif diff --git a/src/shared/Auth/Hmac.cpp b/src/shared/Auth/Hmac.cpp new file mode 100644 index 000000000..048853107 --- /dev/null +++ b/src/shared/Auth/Hmac.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Auth/Hmac.h" +#include "BigNumber.h" + +HmacHash::HmacHash() +{ + uint8 temp[SEED_KEY_SIZE] = { 0x38, 0xA7, 0x83, 0x15, 0xF8, 0x92, 0x25, 0x30, 0x71, 0x98, 0x67, 0xB1, 0x8C, 0x4, 0xE2, 0xAA }; + memcpy(&m_key, &temp, SEED_KEY_SIZE); + HMAC_CTX_init(&m_ctx); + HMAC_Init_ex(&m_ctx, &m_key, SEED_KEY_SIZE, EVP_sha1(), NULL); +} + +HmacHash::~HmacHash() +{ + memset(&m_key, 0x00, SEED_KEY_SIZE); + HMAC_CTX_cleanup(&m_ctx); +} + +void HmacHash::UpdateBigNumber(BigNumber *bn) +{ + UpdateData(bn->AsByteArray(), bn->GetNumBytes()); +} + +void HmacHash::UpdateData(const uint8 *data, int length) +{ + HMAC_Update(&m_ctx, data, length); +} + +void HmacHash::Initialize() +{ + HMAC_Init_ex(&m_ctx, &m_key, SEED_KEY_SIZE, EVP_sha1(), NULL); +} + +void HmacHash::Finalize() +{ + uint32 length = 0; + HMAC_Final(&m_ctx, m_digest, &length); + ASSERT(length == SHA_DIGEST_LENGTH) +} diff --git a/src/shared/Auth/Hmac.h b/src/shared/Auth/Hmac.h new file mode 100644 index 000000000..db825010b --- /dev/null +++ b/src/shared/Auth/Hmac.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AUTH_HMAC_H +#define _AUTH_HMAC_H + +#include "Common.h" +#include +#include + +class BigNumber; + +#define SEED_KEY_SIZE 16 + +class HmacHash +{ + public: + HmacHash(); + ~HmacHash(); + void UpdateBigNumber(BigNumber *bn); + void UpdateData(const uint8 *data, int length); + void Initialize(); + void Finalize(); + uint8 *GetDigest() { return m_digest; }; + int GetLength() { return SHA_DIGEST_LENGTH; }; + private: + HMAC_CTX m_ctx; + uint8 m_key[SEED_KEY_SIZE]; + uint8 m_digest[SHA_DIGEST_LENGTH]; +}; +#endif diff --git a/src/shared/Auth/Makefile.am b/src/shared/Auth/Makefile.am new file mode 100644 index 000000000..db87acbee --- /dev/null +++ b/src/shared/Auth/Makefile.am @@ -0,0 +1,39 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite + +## Build MaNGOS shared library and its parts as convenience library. +# All libraries will be convenience libraries. Might be changed to shared +# later. +noinst_LIBRARIES = libmangosauth.a + +libmangosauth_a_SOURCES = \ + AuthCrypt.cpp \ + AuthCrypt.h \ + BigNumber.cpp \ + BigNumber.h \ + Hmac.cpp \ + Hmac.h \ + Sha1.cpp \ + Sha1.h \ + md5.c \ + md5.h diff --git a/src/shared/Auth/Sha1.cpp b/src/shared/Auth/Sha1.cpp new file mode 100644 index 000000000..1f8b83e4d --- /dev/null +++ b/src/shared/Auth/Sha1.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Auth/Sha1.h" +#include + +Sha1Hash::Sha1Hash() +{ + SHA1_Init(&mC); +} + +Sha1Hash::~Sha1Hash() +{ + SHA1_Init(&mC); +} + +void Sha1Hash::UpdateData(const uint8 *dta, int len) +{ + SHA1_Update(&mC, dta, len); +} + +void Sha1Hash::UpdateData(const std::string &str) +{ + UpdateData((uint8 const*)str.c_str(), str.length()); +} + +void Sha1Hash::UpdateBigNumbers(BigNumber *bn0, ...) +{ + va_list v; + BigNumber *bn; + + va_start(v, bn0); + bn = bn0; + while (bn) + { + UpdateData(bn->AsByteArray(), bn->GetNumBytes()); + bn = va_arg(v, BigNumber *); + } + va_end(v); +} + +void Sha1Hash::Initialize() +{ + SHA1_Init(&mC); +} + +void Sha1Hash::Finalize(void) +{ + SHA1_Final(mDigest, &mC); +} diff --git a/src/shared/Auth/Sha1.h b/src/shared/Auth/Sha1.h new file mode 100644 index 000000000..6a50d8bd9 --- /dev/null +++ b/src/shared/Auth/Sha1.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AUTH_SHA1_H +#define _AUTH_SHA1_H + +#include "Common.h" +#include +#include +#include "Auth/BigNumber.h" + +class Sha1Hash +{ + public: + Sha1Hash(); + ~Sha1Hash(); + + void UpdateFinalizeBigNumbers(BigNumber *bn0, ...); + void UpdateBigNumbers(BigNumber *bn0, ...); + + void UpdateData(const uint8 *dta, int len); + void UpdateData(const std::string &str); + + void Initialize(); + void Finalize(); + + uint8 *GetDigest(void) { return mDigest; }; + int GetLength(void) { return SHA_DIGEST_LENGTH; }; + + BigNumber GetBigNumber(); + + private: + SHA_CTX mC; + uint8 mDigest[SHA_DIGEST_LENGTH]; +}; +#endif diff --git a/src/shared/Auth/md5.c b/src/shared/Auth/md5.c new file mode 100644 index 000000000..3e9735e2d --- /dev/null +++ b/src/shared/Auth/md5.c @@ -0,0 +1,385 @@ +/* + Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +L. Peter Deutsch +ghost@aladdin.com + +*/ +/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + +The original and principal author of md5.c is L. Peter Deutsch +. Other authors are noted in the change history +that follows (in reverse chronological order): + +2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order +either statically or dynamically; added missing #include +in library. +2002-03-11 lpd Corrected argument list for main(), and added int return +type, in test program and T value program. +2002-02-21 lpd Added missing #include in test program. +2000-07-03 lpd Patched to eliminate warnings about "constant is +unsigned in ANSI C, signed in traditional"; made test program +self-checking. +1999-11-04 lpd Edited comments slightly for automatic TOC extraction. +1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). +1999-05-03 lpd Original version. +*/ + +#include "md5.h" +#include + +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef ARCH_IS_BIG_ENDIAN +# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +#else +# define BYTE_ORDER 0 +#endif + +#define T_MASK ((md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + +static void +md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +{ + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; + #if BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + md5_word_t X[16]; + #else + /* Define storage for little-endian or both types of CPUs. */ + md5_word_t xbuf[16]; + const md5_word_t *X; + #endif + + { + #if BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ + #endif + #if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const md5_byte_t *)0) & 3)) + { + /* data are properly aligned */ + X = (const md5_word_t *)data; + } + else + { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } + #endif + #if BYTE_ORDER == 0 + else /* dynamic big-endian */ + #endif + #if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t *xp = data; + int i; + + # if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ + # else + # define xbuf X /* (static only) */ + # endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } + #endif + } + + #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ + #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); + #undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); + #undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + #define H(x, y, z) ((x) ^ (y) ^ (z)) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); + #undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + #define I(x, y, z) ((y) ^ ((x) | ~(z))) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); + #undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +void +md5_init(md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +void +md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) +{ + const md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + ++pms->count[1]; + + /* Process an initial partial block. */ + if (offset) + { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +md5_finish(md5_state_t *pms, md5_byte_t digest[16]) +{ + static const md5_byte_t pad[64] = + { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/src/shared/Auth/md5.h b/src/shared/Auth/md5.h new file mode 100644 index 000000000..fa2937e13 --- /dev/null +++ b/src/shared/Auth/md5.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +L. Peter Deutsch +ghost@aladdin.com + +*/ +/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + +The original and principal author of md5.h is L. Peter Deutsch +. Other authors are noted in the change history +that follows (in reverse chronological order): + +2002-04-13 lpd Removed support for non-ANSI compilers; removed +references to Ghostscript; clarified derivation from RFC 1321; +now handles byte order either statically or dynamically. +1999-11-04 lpd Edited comments slightly for automatic TOC extraction. +1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); +added conditionalization for C++ compilation from Martin +Purschke . +1999-05-03 lpd Original version. +*/ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct md5_state_s +{ + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ +} md5_state_t; + +#ifdef __cplusplus +extern "C" +{ + #endif + + /* Initialize the algorithm. */ + void md5_init(md5_state_t *pms); + + /* Append a string to the message. */ + void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + + /* Finish the message and return the digest. */ + void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + + #ifdef __cplusplus +} /* end extern "C" */ +#endif +#endif /* md5_INCLUDED */ diff --git a/src/shared/Base.cpp b/src/shared/Base.cpp new file mode 100644 index 000000000..9929cd41f --- /dev/null +++ b/src/shared/Base.cpp @@ -0,0 +1,67 @@ +/* + Base class interface + Copyright (C) 1998,1999 by Andrew Zabolotny + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "Base.h" + +Base::~Base () +{ +} + +/** + * Decrement object's reference count; as soon as the last reference + * to the object is removed, it is destroyed. + */ + +void Base::DecRef () +{ + if (!--RefCount) + delete this; +} + +/** + * Object initialization. The initial reference count is set to one; + * this means if you call DecRef() immediately after creating the object, + * it will be destroyed. + */ +Base::Base () +{ + RefCount = 1; +} + +/** + * Increment reference count. + * Every time when you copy a pointer to a object and store it for + * later use you MUST call IncRef() on it; this will allow to keep + * objects as long as they are referenced by some entity. + */ +void Base::IncRef () +{ + ++RefCount; + +} + +/** + * Query number of references to this object. + * I would rather prefer to have the reference counter strictly private, + * but sometimes, mostly for debugging, such a function can help. + */ +int Base::GetRefCount () +{ + return RefCount; +} diff --git a/src/shared/Base.h b/src/shared/Base.h new file mode 100644 index 000000000..d5907fdf4 --- /dev/null +++ b/src/shared/Base.h @@ -0,0 +1,54 @@ +/* + Base class interface + Copyright (C) 1998,1999 by Andrew Zabolotny + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __BASE_H__ +#define __BASE_H__ + +#include "Common.h" + +/** + * This class is intended to be a base class for every other class. + * It defines the basic interface available for any object. + */ +class Base +{ + private: + /// Object reference count + int RefCount; + + protected: + /** + * Destroy this object. Destructor is virtual, because class contains + * virtual methods; also it is private because it is never intended + * to be called directly; use DecRef() instead: when reference counter + * reaches zero, the object will be destroyed. + */ + virtual ~Base (); + + public: + + Base (); + + void IncRef (); + + void DecRef (); + int GetRefCount (); + +}; +#endif // __BASE_H__ diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h new file mode 100644 index 000000000..4f001c526 --- /dev/null +++ b/src/shared/ByteBuffer.h @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _BYTEBUFFER_H +#define _BYTEBUFFER_H + +#include "Common.h" +#include "Errors.h" +#include "Log.h" +#include "Utilities/ByteConverter.h" + +class ByteBuffer +{ + public: + const static size_t DEFAULT_SIZE = 0x1000; + + // constructor + ByteBuffer(): _rpos(0), _wpos(0) + { + _storage.reserve(DEFAULT_SIZE); + } + // constructor + ByteBuffer(size_t res): _rpos(0), _wpos(0) + { + _storage.reserve(res); + } + // copy constructor + ByteBuffer(const ByteBuffer &buf): _rpos(buf._rpos), _wpos(buf._wpos), _storage(buf._storage) { } + + void clear() + { + _storage.clear(); + _rpos = _wpos = 0; + } + + template void append(T value) + { + EndianConvert(value); + append((uint8 *)&value, sizeof(value)); + } + + template void put(size_t pos,T value) + { + EndianConvert(value); + put(pos,(uint8 *)&value,sizeof(value)); + } + + ByteBuffer &operator<<(uint8 value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(uint16 value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(uint32 value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(uint64 value) + { + append(value); + return *this; + } + + // signed as in 2e complement + ByteBuffer &operator<<(int8 value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(int16 value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(int32 value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(int64 value) + { + append(value); + return *this; + } + + // floating points + ByteBuffer &operator<<(float value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(double value) + { + append(value); + return *this; + } + ByteBuffer &operator<<(const std::string &value) + { + append((uint8 const *)value.c_str(), value.length()); + append((uint8)0); + return *this; + } + ByteBuffer &operator<<(const char *str) + { + append((uint8 const *)str, str ? strlen(str) : 0); + append((uint8)0); + return *this; + } + + ByteBuffer &operator>>(bool &value) + { + value = read() > 0 ? true : false; + return *this; + } + + ByteBuffer &operator>>(uint8 &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(uint16 &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(uint32 &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(uint64 &value) + { + value = read(); + return *this; + } + + //signed as in 2e complement + ByteBuffer &operator>>(int8 &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(int16 &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(int32 &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(int64 &value) + { + value = read(); + return *this; + } + + ByteBuffer &operator>>(float &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(double &value) + { + value = read(); + return *this; + } + ByteBuffer &operator>>(std::string& value) + { + value.clear(); + while (rpos() < size()) // prevent crash at wrong string format in packet + { + char c=read(); + if (c==0) + break; + value+=c; + } + return *this; + } + + uint8 operator[](size_t pos) const + { + return read(pos); + } + + size_t rpos() const { return _rpos; } + + size_t rpos(size_t rpos_) + { + _rpos = rpos_; + return _rpos; + }; + + size_t wpos() const { return _wpos; } + + size_t wpos(size_t wpos_) + { + _wpos = wpos_; + return _wpos; + } + + template T read() + { + T r=read(_rpos); + _rpos += sizeof(T); + return r; + }; + template T read(size_t pos) const + { + ASSERT(pos + sizeof(T) <= size() || PrintPosError(false,pos,sizeof(T))); + T val = *((T const*)&_storage[pos]); + EndianConvert(val); + return val; + } + + void read(uint8 *dest, size_t len) + { + ASSERT(_rpos + len <= size() || PrintPosError(false,_rpos,len)); + memcpy(dest, &_storage[_rpos], len); + _rpos += len; + } + + const uint8 *contents() const { return &_storage[0]; } + + size_t size() const { return _storage.size(); } + bool empty() const { return _storage.empty(); } + + void resize(size_t newsize) + { + _storage.resize(newsize); + _rpos = 0; + _wpos = size(); + }; + void reserve(size_t ressize) + { + if (ressize > size()) _storage.reserve(ressize); + }; + + void append(const std::string& str) + { + append((uint8 const*)str.c_str(),str.size() + 1); + } + void append(const char *src, size_t cnt) + { + return append((const uint8 *)src, cnt); + } + template + void append(const T *src, size_t cnt) + { + return append((const uint8 *)src, cnt*sizeof(T)); + } + void append(const uint8 *src, size_t cnt) + { + if (!cnt) return; + + ASSERT(size() < 10000000); + + if (_storage.size() < _wpos + cnt) + _storage.resize(_wpos + cnt); + memcpy(&_storage[_wpos], src, cnt); + _wpos += cnt; + } + void append(const ByteBuffer& buffer) + { + if(buffer.size()) append(buffer.contents(),buffer.size()); + } + + void appendPackGUID(uint64 guid) + { + size_t mask_position = wpos(); + *this << uint8(0); + for(uint8 i = 0; i < 8; i++) + { + if(guid & 0xFF) + { + _storage[mask_position] |= uint8(1<>= 8; + } + } + + void put(size_t pos, const uint8 *src, size_t cnt) + { + ASSERT(pos + cnt <= size() || PrintPosError(true,pos,cnt)); + memcpy(&_storage[pos], src, cnt); + } + void print_storage() const + { + if(!sLog.IsOutDebug()) // optimize disabled debug output + return; + + sLog.outDebug("STORAGE_SIZE: %u", size() ); + for(uint32 i = 0; i < size(); i++) + sLog.outDebugInLine("%u - ", read(i) ); + sLog.outDebug(" "); + } + + void textlike() const + { + if(!sLog.IsOutDebug()) // optimize disabled debug output + return; + + sLog.outDebug("STORAGE_SIZE: %u", size() ); + for(uint32 i = 0; i < size(); i++) + sLog.outDebugInLine("%c", read(i) ); + sLog.outDebug(" "); + } + + void hexlike() const + { + if(!sLog.IsOutDebug()) // optimize disabled debug output + return; + + uint32 j = 1, k = 1; + sLog.outDebug("STORAGE_SIZE: %u", size() ); + + if(sLog.IsIncludeTime()) + sLog.outDebugInLine(" "); + + for(uint32 i = 0; i < size(); i++) + { + if ((i == (j*8)) && ((i != (k*16)))) + { + if (read(i) < 0x0F) + { + sLog.outDebugInLine("| 0%X ", read(i) ); + } + else + { + sLog.outDebugInLine("| %X ", read(i) ); + } + ++j; + } + else if (i == (k*16)) + { + if (read(i) < 0x0F) + { + sLog.outDebugInLine("\n"); + if(sLog.IsIncludeTime()) + sLog.outDebugInLine(" "); + + sLog.outDebugInLine("0%X ", read(i) ); + } + else + { + sLog.outDebugInLine("\n"); + if(sLog.IsIncludeTime()) + sLog.outDebugInLine(" "); + + sLog.outDebugInLine("%X ", read(i) ); + } + + ++k; + ++j; + } + else + { + if (read(i) < 0x0F) + { + sLog.outDebugInLine("0%X ", read(i) ); + } + else + { + sLog.outDebugInLine("%X ", read(i) ); + } + } + } + sLog.outDebugInLine("\n"); + } + + protected: + bool PrintPosError(bool add, size_t pos, size_t esize) const + { + sLog.outError("ERROR: Attempt %s in ByteBuffer (pos: %u size: %u) value with size: %u",(add ? "put" : "get"),pos, size(), esize); + + // assert must fail after function call + return false; + } + + size_t _rpos, _wpos; + std::vector _storage; +}; + +template ByteBuffer &operator<<(ByteBuffer &b, std::vector v) +{ + b << (uint32)v.size(); + for (typename std::vector::iterator i = v.begin(); i != v.end(); i++) + { + b << *i; + } + return b; +} + +template ByteBuffer &operator>>(ByteBuffer &b, std::vector &v) +{ + uint32 vsize; + b >> vsize; + v.clear(); + while(vsize--) + { + T t; + b >> t; + v.push_back(t); + } + return b; +} + +template ByteBuffer &operator<<(ByteBuffer &b, std::list v) +{ + b << (uint32)v.size(); + for (typename std::list::iterator i = v.begin(); i != v.end(); i++) + { + b << *i; + } + return b; +} + +template ByteBuffer &operator>>(ByteBuffer &b, std::list &v) +{ + uint32 vsize; + b >> vsize; + v.clear(); + while(vsize--) + { + T t; + b >> t; + v.push_back(t); + } + return b; +} + +template ByteBuffer &operator<<(ByteBuffer &b, std::map &m) +{ + b << (uint32)m.size(); + for (typename std::map::iterator i = m.begin(); i != m.end(); i++) + { + b << i->first << i->second; + } + return b; +} + +template ByteBuffer &operator>>(ByteBuffer &b, std::map &m) +{ + uint32 msize; + b >> msize; + m.clear(); + while(msize--) + { + K k; + V v; + b >> k >> v; + m.insert(make_pair(k, v)); + } + return b; +} +#endif diff --git a/src/shared/Common.cpp b/src/shared/Common.cpp new file mode 100644 index 000000000..d667d9d26 --- /dev/null +++ b/src/shared/Common.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" + +char const* localeNames[MAX_LOCALE] = { + "enUS", + "koKR", + "frFR", + "deDE", + "zhCN", + "zhTW", + "esES", + "esMX", + "ruRU" +}; + +LocaleConstant GetLocaleByName(std::string name) +{ + for(uint32 i = 0; i < MAX_LOCALE; ++i) + if(name==localeNames[i]) + return LocaleConstant(i); + + return LOCALE_enUS; // including enGB case +} diff --git a/src/shared/Common.h b/src/shared/Common.h new file mode 100644 index 000000000..20d99b3de --- /dev/null +++ b/src/shared/Common.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_COMMON_H +#define MANGOSSERVER_COMMON_H + +// config.h needs to be included 1st +#ifdef HAVE_CONFIG_H +#ifdef PACKAGE +#undef PACKAGE +#endif //PACKAGE +#ifdef PACKAGE_BUGREPORT +#undef PACKAGE_BUGREPORT +#endif //PACKAGE_BUGREPORT +#ifdef PACKAGE_NAME +#undef PACKAGE_NAME +#endif //PACKAGE_NAME +#ifdef PACKAGE_STRING +#undef PACKAGE_STRING +#endif //PACKAGE_STRING +#ifdef PACKAGE_TARNAME +#undef PACKAGE_TARNAME +#endif //PACKAGE_TARNAME +#ifdef PACKAGE_VERSION +#undef PACKAGE_VERSION +#endif //PACKAGE_VERSION +#ifdef VERSION +#undef VERSION +#endif //VERSION +# include "config.h" +#undef PACKAGE +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef VERSION +#endif //HAVE_CONFIG_H + +#include "Platform/Define.h" + +#if COMPILER == COMPILER_MICROSOFT + +#pragma warning(disable:4996) + +#ifndef __SHOW_STUPID_WARNINGS__ + +#pragma warning(disable:4244) + +#pragma warning(disable:4267) + +#pragma warning(disable:4800) + +#pragma warning(disable:4018) + +#pragma warning(disable:4311) + +#pragma warning(disable:4305) + +#pragma warning(disable:4005) +#endif // __SHOW_STUPID_WARNINGS__ +#endif // __GNUC__ + +// must be the first thing to include for it to work +#include "MemoryLeaks.h" + +#include "Utilities/HashMap.h" +#include +#include +#include +#include +#include +#include +#include + +#if PLATFORM == PLATFORM_WINDOWS +#define STRCASECMP stricmp +#else +#define STRCASECMP strcasecmp +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if PLATFORM == PLATFORM_WINDOWS +# define FD_SETSIZE 4096 +# include +// XP winver - needed to compile with standard leak check in MemoryLeaks.h +// uncomment later if needed +//#define _WIN32_WINNT 0x0501 +# include +//#undef WIN32_WINNT +#else +# include +# include +# include +# include +# include +# include +#endif + +#if COMPILER == COMPILER_MICROSOFT + +#include + +#define I64FMT "%016I64X" +#define I64FMTD "%I64u" +#define SI64FMTD "%I64d" +#define snprintf _snprintf +#define atoll __atoi64 +#define vsnprintf _vsnprintf +#define strdup _strdup +#define finite(X) _finite(X) + +#else + +#define stricmp strcasecmp +#define strnicmp strncasecmp +#define I64FMT "%016llX" +#define I64FMTD "%llu" +#define SI64FMTD "%lld" +#endif + +inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; } + +#define atol(a) strtoul( a, NULL, 10) + +#define STRINGIZE(a) #a + +enum TimeConstants +{ + MINUTE = 60, + HOUR = MINUTE*60, + DAY = HOUR*24, + MONTH = DAY*30 +}; + +enum AccountTypes +{ + SEC_PLAYER = 0, + SEC_MODERATOR = 1, + SEC_GAMEMASTER = 2, + SEC_ADMINISTRATOR = 3 +}; + +enum LocaleConstant +{ + LOCALE_enUS = 0, + LOCALE_koKR = 1, + LOCALE_frFR = 2, + LOCALE_deDE = 3, + LOCALE_zhCN = 4, + LOCALE_zhTW = 5, + LOCALE_esES = 6, + LOCALE_esMX = 7, + LOCALE_ruRU = 8 +}; + +#define MAX_LOCALE 9 + +extern char const* localeNames[MAX_LOCALE]; + +LocaleConstant GetLocaleByName(std::string name); + +// we always use stdlibc++ std::max/std::min, undefine some not C++ standard defines (Win API and some pother platforms) +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#endif diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp new file mode 100644 index 000000000..f76e4abd9 --- /dev/null +++ b/src/shared/Config/Config.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ConfigEnv.h" +#include "Policies/SingletonImp.h" + +INSTANTIATE_SINGLETON_1(Config); + +Config::Config() : mIgnoreCase(true), mConf(NULL) +{ +} + + +Config::~Config() +{ + delete mConf; +} + + +bool Config::SetSource(const char *file, bool ignorecase) +{ + mIgnoreCase = ignorecase; + mFilename = file; + + return Reload(); +} + +bool Config::Reload() +{ + delete mConf; + + mConf = new DOTCONFDocument(mIgnoreCase ? + DOTCONFDocument::CASEINSENSETIVE : + DOTCONFDocument::CASESENSETIVE); + + if (mConf->setContent(mFilename.c_str()) == -1) + { + delete mConf; + mConf = NULL; + return false; + } + + return true; +} + +bool Config::GetString(const char* name, std::string *value) +{ + if(!mConf) + return false; + + DOTCONFDocumentNode const *node = mConf->findNode(name); + if(!node || !node->getValue()) + return false; + + *value = node->getValue(); + + return true; +} + +bool Config::GetString(const char* name, char const **value) +{ + if(!mConf) + return false; + + DOTCONFDocumentNode const *node = mConf->findNode(name); + if(!node || !node->getValue()) + return false; + + *value = node->getValue(); + + return true; +} + + +std::string Config::GetStringDefault(const char* name, const char* def) +{ + if(!mConf) + return std::string(def); + + DOTCONFDocumentNode const *node = mConf->findNode(name); + if(!node || !node->getValue()) + return std::string(def); + + return std::string(node->getValue()); +} + + +bool Config::GetBool(const char* name, bool *value) +{ + if(!mConf) + return false; + + DOTCONFDocumentNode const *node = mConf->findNode(name); + if(!node || !node->getValue()) + return false; + + const char* str = node->getValue(); + if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || + strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 || + strcmp(str, "1") == 0) + { + *value = true; + } + else + *value = false; + + return true; +} + + +bool Config::GetBoolDefault(const char* name, const bool def) +{ + bool val; + return GetBool(name, &val) ? val : def; +} + + +bool Config::GetInt(const char* name, int *value) +{ + if(!mConf) + return false; + + DOTCONFDocumentNode const *node = mConf->findNode(name); + if(!node || !node->getValue()) + return false; + + *value = atoi(node->getValue()); + + return true; +} + + +bool Config::GetFloat(const char* name, float *value) +{ + if(!mConf) + return false; + + DOTCONFDocumentNode const *node = mConf->findNode(name); + if(!node || !node->getValue()) + return false; + + *value = atof(node->getValue()); + + return true; +} + + +int Config::GetIntDefault(const char* name, const int def) +{ + int val; + return GetInt(name, &val) ? val : def; +} + + +float Config::GetFloatDefault(const char* name, const float def) +{ + float val; + return (GetFloat(name, &val) ? val : def); +} diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h new file mode 100644 index 000000000..efbfd1d1f --- /dev/null +++ b/src/shared/Config/Config.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#include +#include "Platform/Define.h" + +class DOTCONFDocument; + +class MANGOS_DLL_SPEC Config +{ + public: + Config(); + ~Config(); + + bool SetSource(const char *file, bool ignorecase = true); + bool Reload(); + + bool GetString(const char* name, std::string *value); + bool GetString(const char* name, char const **value); + std::string GetStringDefault(const char* name, const char* def); + + bool GetBool(const char* name, bool *value); + bool GetBoolDefault(const char* name, const bool def = false); + + bool GetInt(const char* name, int *value); + int GetIntDefault(const char* name, const int def); + + bool GetFloat(const char* name, float *value); + float GetFloatDefault(const char* name, const float def); + + std::string GetFilename() const { return mFilename; } + private: + std::string mFilename; + bool mIgnoreCase; + DOTCONFDocument *mConf; +}; + +#define sConfig MaNGOS::Singleton::Instance() + +#endif diff --git a/src/shared/Config/ConfigEnv.h b/src/shared/Config/ConfigEnv.h new file mode 100644 index 000000000..de5dbe6a0 --- /dev/null +++ b/src/shared/Config/ConfigEnv.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if !defined(CONFIGENVIRONMENT_H) + +#define CONFIGENVIRONMENT_H + +#include "Common.h" +#include "dotconfpp/dotconfpp.h" +#include "Config.h" +#include "Log.h" + +#endif diff --git a/src/shared/Config/ConfigLibrary.vcproj b/src/shared/Config/ConfigLibrary.vcproj new file mode 100644 index 000000000..a8f1fc322 --- /dev/null +++ b/src/shared/Config/ConfigLibrary.vcproj @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/shared/Config/Makefile.am b/src/shared/Config/Makefile.am new file mode 100644 index 000000000..c33c8e456 --- /dev/null +++ b/src/shared/Config/Makefile.am @@ -0,0 +1,40 @@ +# Copyright (C) 2005-2008 MaNGOS +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite + +## Build MaNGOS shared library and its parts as convenience library. +# All libraries will be convenience libraries. Might be changed to shared +# later. +noinst_LIBRARIES = libmangosconfig.a + +libmangosconfig_a_SOURCES = \ + dotconfpp/dotconfpp.cpp \ + dotconfpp/dotconfpp.h \ + dotconfpp/mempool.cpp \ + dotconfpp/mempool.h \ + Config.cpp \ + Config.h \ + ConfigEnv.h + +# VC++ project workspace for dotconfpp +EXTRA_DIST = \ + ConfigLibrary.vcproj diff --git a/src/shared/Config/dotconfpp/dotconfpp.cpp b/src/shared/Config/dotconfpp/dotconfpp.cpp new file mode 100644 index 000000000..60008747a --- /dev/null +++ b/src/shared/Config/dotconfpp/dotconfpp.cpp @@ -0,0 +1,583 @@ + +#include "Common.h" + +#include "dotconfpp.h" + +#if !defined(R_OK) +#define R_OK 04 +#endif + +DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), + values(NULL), valuesCount(0), + name(NULL), lineNum(0), fileName(NULL), closed(true) +{ +} + +DOTCONFDocumentNode::~DOTCONFDocumentNode() +{ + free(name); + if(values != NULL){ + for(int i = 0 ; i < valuesCount; i++){ + free(values[i]); + } + free(values); + } +} + +void DOTCONFDocumentNode::pushValue(char * _value) +{ + ++valuesCount; + values = (char**)realloc(values, valuesCount*sizeof(char*)); + values[valuesCount-1] = strdup(_value); +} + +const char* DOTCONFDocumentNode::getValue(int index) const +{ + if(index >= valuesCount){ + return NULL; + } + return values[index]; +} + +DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity): + mempool(NULL), + curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL) +{ + if(caseSensitivity == CASESENSETIVE){ + cmp_func = strcmp; + } else { + cmp_func = strcasecmp; + } + + mempool = new AsyncDNSMemPool(1024); + mempool->initialize(); +} + +DOTCONFDocument::~DOTCONFDocument() +{ + for(std::list::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){ + delete(*i); + } + for(std::list::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){ + free(*i); + } + for(std::list::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){ + free(*i); + } + free(fileName); + delete mempool; +} + +int DOTCONFDocument::cleanupLine(char * line) +{ + char * start = line; + char * bg = line; + bool multiline = false; + bool concat = false; + char * word = NULL; + + if(!words.empty() && quoted) + concat = true; + + while(*line){ + if((*line == '#' || *line == ';') && !quoted){ + *bg = 0; + if(strlen(start)){ + + if(concat){ + word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + strcpy(word, words.back()); + strcat(word, start); + words.pop_back(); + concat = false; + } else { + word = mempool->strdup(start); + } + words.push_back(word); + } + break; + } + if(*line == '=' && !quoted){ + *line = ' ';continue; + } + + // Allowing \" in there causes problems with directory paths + // like "C:\MaNGOS\" + //if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){ + if(*line == '\\' && (*(line+1) == '\'')) { + *bg++ = *(line+1); + line+=2; continue; + } + if(*line == '\\' && *(line+1) == 'n'){ + *bg++ = '\n'; + line+=2; continue; + } + if(*line == '\\' && *(line+1) == 'r'){ + *bg++ = '\r'; + line+=2; continue; + } + if(*line == '\\' && (*(line+1) == '\n' || *(line+1) == '\r')){ + *bg = 0; + if(strlen(start)){ + + if(concat){ + word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + strcpy(word, words.back()); + strcat(word, start); + words.pop_back(); + concat = false; + } else { + word = mempool->strdup(start); + } + words.push_back(word); + } + multiline = true; + break; + } + if(*line == '"' || *line == '\''){ + quoted = !quoted; + ++line; continue; + } + if(isspace(*line) && !quoted){ + *bg++ = 0; + if(strlen(start)){ + + if(concat){ + word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + strcpy(word, words.back()); + strcat(word, start); + words.pop_back(); + concat = false; + } else { + word = mempool->strdup(start); + } + words.push_back(word); + } + start = bg; + while(isspace(*++line)) {} + + continue; + } + *bg++ = *line++; + } + + if(quoted && !multiline){ + error(curLine, fileName, "unterminated quote"); + return -1; + } + + return multiline?1:0; +} + +int DOTCONFDocument::parseLine() +{ + char * word = NULL; + char * nodeName = NULL; + char * nodeValue = NULL; + DOTCONFDocumentNode * tagNode = NULL; + bool newNode = false; + + for(std::list::iterator i = words.begin(); i != words.end(); i++) { + word = *i; + + if(*word == '<'){ + newNode = true; + } + + if(newNode){ + nodeValue = NULL; + nodeName = NULL; + newNode = false; + } + + size_t wordLen = strlen(word); + if(word[wordLen-1] == '>'){ + word[wordLen-1] = 0; + newNode = true; + } + + if(nodeName == NULL){ + nodeName = word; + bool closed = true; + if(*nodeName == '<'){ + if(*(nodeName+1) != '/'){ + ++nodeName; + closed = false; + } else { + nodeName+=2; + std::list::reverse_iterator itr=nodeTree.rbegin(); + for(; itr!=nodeTree.rend(); ++itr){ + if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){ + (*itr)->closed = true; + curParent = (*itr)->parentNode; + curPrev = *itr; + break; + } + } + if(itr==nodeTree.rend()){ + error(curLine, fileName, "not matched closing tag ", nodeName); + return -1; + } + continue; + } + } + tagNode = new DOTCONFDocumentNode; + tagNode->name = strdup(nodeName); + tagNode->document = this; + tagNode->fileName = processedFiles.back(); + tagNode->lineNum = curLine; + tagNode->closed = closed; + if(!nodeTree.empty()){ + DOTCONFDocumentNode * prev = nodeTree.back(); + if(prev->closed){ + + curPrev->nextNode = tagNode; + tagNode->previousNode = curPrev; + tagNode->parentNode = curParent; + + } else { + prev->childNode = tagNode; + tagNode->parentNode = prev; + curParent = prev; + } + } + nodeTree.push_back(tagNode); + curPrev = tagNode; + } else { + nodeValue = word; + tagNode->pushValue(nodeValue); + } + } + + return 0; +} +int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) +{ + char str[512]; + int ret = 0; + curLine = 0; + curParent = _parent; + + quoted = false; + size_t slen = 0; + + while(fgets(str, 511, file)){ + ++curLine; + slen = strlen(str); + if( slen >= 510 ){ + error(curLine, fileName, "warning: line too long"); + } + if(str[slen-1] != '\n'){ + str[slen] = '\n'; + str[slen+1] = 0; + } + if((ret = cleanupLine(str)) == -1){ + break; + } + if(ret == 0){ + if(!words.empty()){ + ret = parseLine(); + mempool->free(); + words.clear(); + if(ret == -1){ + break; + } + } + } + } + + return ret; +} + +int DOTCONFDocument::checkConfig(const std::list::iterator & from) +{ + int ret = 0; + + DOTCONFDocumentNode * tagNode = NULL; + int vi = 0; + for(std::list::iterator i = from; i != nodeTree.end(); i++){ + tagNode = *i; + if(!tagNode->closed){ + error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name); + ret = -1; + break; + } + vi = 0; + while( vi < tagNode->valuesCount ){ + + if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){ + ret = macroSubstitute(tagNode, vi ); + mempool->free(); + if(ret == -1){ + break; + } + } + ++vi; + } + if(ret == -1){ + break; + } + } + + return ret; +} + +int DOTCONFDocument::setContent(const char * _fileName) +{ + int ret = 0; + char realpathBuf[PATH_MAX]; + + if(realpath(_fileName, realpathBuf) == NULL){ + error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno)); + return -1; + } + + fileName = strdup(realpathBuf); + + processedFiles.push_back(strdup(realpathBuf)); + + if(( file = fopen(fileName, "r")) == NULL){ + error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno)); + return -1; + } + + ret = parseFile(); + + (void) fclose(file); + + if(!ret){ + + if( (ret = checkConfig(nodeTree.begin())) == -1){ + return -1; + } + + std::list::iterator from; + DOTCONFDocumentNode * tagNode = NULL; + int vi = 0; + for(std::list::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ + tagNode = *i; + if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){ + vi = 0; + while( vi < tagNode->valuesCount ){ + if(access(tagNode->values[vi], R_OK) == -1){ + error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno)); + return -1; + } + if(realpath(tagNode->values[vi], realpathBuf) == NULL){ + error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", tagNode->values[vi], strerror(errno)); + return -1; + } + + bool processed = false; + for(std::list::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){ + if(!strcmp(*itInode, realpathBuf)){ + processed = true; + break; + } + } + if(processed){ + break; + } + + processedFiles.push_back(strdup(realpathBuf)); + + file = fopen(tagNode->values[vi], "r"); + if(file == NULL){ + error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno)); + return -1; + } + + fileName = strdup(realpathBuf); + from = nodeTree.end(); --from; + + ret = parseFile(); + (void) fclose(file); + if(ret == -1) + return -1; + if(checkConfig(++from) == -1){ + return -1; + } + ++vi; + } + } + } + + + if(!requiredOptions.empty()) + ret = checkRequiredOptions(); + } + + return ret; +} + +int DOTCONFDocument::checkRequiredOptions() +{ + for(std::list::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){ + bool matched = false; + for(std::list::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ + if(!cmp_func((*i)->name, *ci)){ + matched = true; + break; + } + } + if(!matched){ + error(0, NULL, "required option '%s' not specified", *ci); + return -1; + } + } + return 0; +} + +void DOTCONFDocument::error(int lineNum, const char * fileName_, const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + + size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50; + char * buf = (char*)mempool->alloc(len); + + if(lineNum) + (void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); + else + (void) snprintf(buf, len, "DOTCONF++: %s\n", fmt); + + (void) vfprintf(stderr, buf, args); + + va_end(args); +} + +char * DOTCONFDocument::getSubstitution(char * macro, int lineNum) +{ + char * buf = NULL; + char * variable = macro+2; + + char * endBr = strchr(macro, '}'); + + if(!endBr){ + error(lineNum, fileName, "unterminated '{'"); + return NULL; + } + *endBr = 0; + + char * defaultValue = strchr(variable, ':'); + + if(defaultValue){ + *defaultValue++ = 0; + if(*defaultValue != '-'){ + error(lineNum, fileName, "incorrect macro substitution syntax"); + return NULL; + } + ++defaultValue; + if(*defaultValue == '"' || *defaultValue == '\''){ + ++defaultValue; + defaultValue[strlen(defaultValue)-1] = 0; + } + } else { + defaultValue = NULL; + } + + char * subs = getenv(variable); + if( subs ){ + buf = mempool->strdup(subs); + } else { + std::list::iterator i = nodeTree.begin(); + DOTCONFDocumentNode * tagNode = NULL; + for(; i!=nodeTree.end(); i++){ + tagNode = *i; + if(!cmp_func(tagNode->name, variable)){ + if(tagNode->valuesCount != 0){ + buf = mempool->strdup(tagNode->values[0]); + break; + } + } + } + if( i == nodeTree.end() ){ + if( defaultValue ){ + buf = mempool->strdup(defaultValue); + } else { + error(lineNum, fileName, "substitution not found and default value not given"); + return NULL; + } + } + } + return buf; +} + +int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex) +{ + int ret = 0; + char * macro = tagNode->values[valueIndex]; + size_t valueLen = strlen(tagNode->values[valueIndex])+1; + char * value = (char*)mempool->alloc(valueLen); + char * v = value; + char * subs = NULL; + + while(*macro){ + if(*macro == '$' && *(macro+1) == '{'){ + char * m = strchr(macro, '}'); + subs = getSubstitution(macro, tagNode->lineNum); + if(subs == NULL){ + ret = -1; + break; + } + macro = m + 1; + *v = 0; + v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen); + strcpy(v, value); + value = strcat(v, subs); + v = value + strlen(value); + continue; + } + *v++ = *macro++; + } + *v = 0; + + free(tagNode->values[valueIndex]); + tagNode->values[valueIndex] = strdup(value); + return ret; +} + +const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const +{ + if ( !nodeTree.empty() ) { + return *nodeTree.begin(); + } else { + return NULL; + } +} + +const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const +{ + + + std::list::const_iterator i = nodeTree.begin(); + + if(startNode == NULL) + startNode = parentNode; + + if(startNode != NULL){ + while( i != nodeTree.end() && (*i) != startNode ){ + ++i; + } + if( i != nodeTree.end() ) ++i; + } + + for(; i!=nodeTree.end(); i++){ + + if((*i)->parentNode != parentNode){ + continue; + } + if(!cmp_func(nodeName, (*i)->name)){ + return *i; + } + } + return NULL; +} + +void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames) +{ + while(*requiredOptionNames){ + requiredOptions.push_back(strdup( *requiredOptionNames )); + ++requiredOptionNames; + } +} diff --git a/src/shared/Config/dotconfpp/dotconfpp.h b/src/shared/Config/dotconfpp/dotconfpp.h new file mode 100644 index 000000000..15c4f7fcd --- /dev/null +++ b/src/shared/Config/dotconfpp/dotconfpp.h @@ -0,0 +1,110 @@ + + + +#ifndef DOTCONFPP_H +#define DOTCONFPP_H + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef WIN32 +#define PATH_MAX _MAX_PATH +#define snprintf _snprintf +#define strcasecmp stricmp +#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH) +#include +#else +#include +#include +#include +#include +#endif + +#include "mempool.h" + +class DOTCONFDocument; + +class DOTCONFDocumentNode +{ +friend class DOTCONFDocument; +private: + DOTCONFDocumentNode * previousNode; + DOTCONFDocumentNode * nextNode; + DOTCONFDocumentNode * parentNode; + DOTCONFDocumentNode * childNode; + char ** values; + int valuesCount; + char * name; + const DOTCONFDocument * document; + int lineNum; + char * fileName; + bool closed; + + void pushValue(char * _value); + +public: + DOTCONFDocumentNode(); + ~DOTCONFDocumentNode(); + + const char * getConfigurationFileName()const { return fileName; } + int getConfigurationLineNumber() const { return lineNum; } + + const DOTCONFDocumentNode * getNextNode() const { return nextNode; } + const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; } + const DOTCONFDocumentNode * getParentNode() const { return parentNode; } + const DOTCONFDocumentNode * getChildNode() const { return childNode; } + const char* getValue(int index = 0) const; + const char * getName() const { return name; } + const DOTCONFDocument * getDocument() const { return document; } +}; + +class DOTCONFDocument +{ +public: + enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE }; +protected: + AsyncDNSMemPool * mempool; +private: + DOTCONFDocumentNode * curParent; + DOTCONFDocumentNode * curPrev; + int curLine; + bool quoted; + std::list nodeTree; + std::list requiredOptions; + std::list processedFiles; + FILE * file; + char * fileName; + std::list words; + int (*cmp_func)(const char *, const char *); + + int checkRequiredOptions(); + int parseLine(); + int parseFile(DOTCONFDocumentNode * _parent = NULL); + int checkConfig(const std::list::iterator & from); + int cleanupLine(char * line); + char * getSubstitution(char * macro, int lineNum); + int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex); + +protected: + virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5); + +public: + DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE); + virtual ~DOTCONFDocument(); + + int setContent(const char * _fileName); + + void setRequiredOptionNames(const char ** requiredOptionNames); + const DOTCONFDocumentNode * getFirstNode() const; + const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const; +}; + +#endif diff --git a/src/shared/Config/dotconfpp/mempool.cpp b/src/shared/Config/dotconfpp/mempool.cpp new file mode 100644 index 000000000..cf589ffb2 --- /dev/null +++ b/src/shared/Config/dotconfpp/mempool.cpp @@ -0,0 +1,100 @@ + + + +#include "mempool.h" + +AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size): + pool(NULL), pos(0), size(_size) +{ + pool = ::malloc(size); +} + +AsyncDNSMemPool::PoolChunk::~PoolChunk() +{ + ::free(pool); +} + +AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize): + chunks(NULL), chunksCount(0), defaultSize(_defaultSize), + poolUsage(0), poolUsageCounter(0) +{ +} + +AsyncDNSMemPool::~AsyncDNSMemPool() +{ + for(size_t i = 0; isize - chunk->pos) >= size){ + chunk->pos += size; + return ((char*)chunk->pool) + chunk->pos - size; + } + } + addNewChunk(size); + chunks[chunksCount-1]->pos = size; + return chunks[chunksCount-1]->pool; +} + +void AsyncDNSMemPool::free() +{ + size_t pu = 0; + size_t psz = 0; + ++poolUsageCounter; + + for(size_t i = 0; ipos; + psz += chunks[i]->size; + chunks[i]->pos = 0; + } + poolUsage=(poolUsage>pu)?poolUsage:pu; + + if(poolUsageCounter >= 10 && chunksCount > 1){ + psz -= chunks[chunksCount-1]->size; + if(poolUsage < psz){ + --chunksCount; + delete chunks[chunksCount]; + } + poolUsage = 0; + poolUsageCounter = 0; + } +} + +void * AsyncDNSMemPool::calloc(size_t size) +{ + return ::memset(this->alloc(size), 0, size); +} + +char * AsyncDNSMemPool::strdup(const char *str) +{ + return ::strcpy((char*)this->alloc(strlen(str)+1), str); +} diff --git a/src/shared/Config/dotconfpp/mempool.h b/src/shared/Config/dotconfpp/mempool.h new file mode 100644 index 000000000..04bd1e006 --- /dev/null +++ b/src/shared/Config/dotconfpp/mempool.h @@ -0,0 +1,46 @@ + + + +#ifndef ASYNC_DNS_MEMPOOL_H +#define ASYNC_DNS_MEMPOOL_H + +#include +#include +#include + +#undef free +#undef calloc +#undef strdup + +class AsyncDNSMemPool +{ +private: + struct PoolChunk { + void * pool; + size_t pos; + size_t size; + + PoolChunk(size_t _size); + ~PoolChunk(); + }; + PoolChunk ** chunks; + size_t chunksCount; + size_t defaultSize; + + size_t poolUsage; + size_t poolUsageCounter; + + void addNewChunk(size_t size); + +public: + AsyncDNSMemPool(size_t _defaultSize = 4096); + virtual ~AsyncDNSMemPool(); + + int initialize(); + void free(); + void * alloc(size_t size); + void * calloc(size_t size); + char * strdup(const char *str); +}; + +#endif diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h new file mode 100644 index 000000000..6ad7fdb12 --- /dev/null +++ b/src/shared/Database/DBCEnums.h @@ -0,0 +1,104 @@ +/* +* Copyright (C) 2005-2008 MaNGOS +* +* 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 2 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, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef DBCENUMS_H +#define DBCENUMS_H + +enum AreaTeams +{ + AREATEAM_NONE = 0, + AREATEAM_ALLY = 2, + AREATEAM_HORDE = 4 +}; + +enum AreaFlags +{ + AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring) + AREA_FLAG_UNK1 = 0x00000002, // unknown, (only Naxxramas and Razorfen Downs) + AREA_FLAG_UNK2 = 0x00000004, // Only used on development map + AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // slave capital city flag? + AREA_FLAG_UNK3 = 0x00000010, // unknown + AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag? + AREA_FLAG_UNK4 = 0x00000040, // many zones have this flag + AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas + AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag + AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?) + AREA_FLAG_OUTLAND = 0x00000400, // outland zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag) + AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled) + AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway + AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 2.4.2) + AREA_FLAG_OUTLAND2 = 0x00004000, // outland zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag) + AREA_FLAG_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area) + AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only + AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 2.4.2) + AREA_FLAG_UNK5 = 0x00040000, // just used for Amani Pass, Hatchet Hills + AREA_FLAG_LOWLEVEL = 0x00100000 // used for some starting areas with area_level <=15 +}; + +enum FactionTemplateFlags +{ + FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats +}; + +enum FactionMasks +{ + FACTION_MASK_PLAYER = 1, // any player + FACTION_MASK_ALLIANCE = 2, // player or creature from alliance team + FACTION_MASK_HORDE = 4, // player or creature from horde team + FACTION_MASK_MONSTER = 8 // aggressive creature from monster team + // if none flags set then non-aggressive creature +}; + +enum MapTypes +{ + MAP_COMMON = 0, + MAP_INSTANCE = 1, + MAP_RAID = 2, + MAP_BATTLEGROUND = 3, + MAP_ARENA = 4 +}; + +enum AbilytyLearnType +{ + ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1, + ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2 +}; + +enum ItemEnchantmentType +{ + ITEM_ENCHANTMENT_TYPE_NONE = 0, + ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1, + ITEM_ENCHANTMENT_TYPE_DAMAGE = 2, + ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3, + ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4, + ITEM_ENCHANTMENT_TYPE_STAT = 5, + ITEM_ENCHANTMENT_TYPE_TOTEM = 6 +}; + +enum TotemCategoryType +{ + TOTEM_CATEGORY_TYPE_KNIFE = 1, + TOTEM_CATEGORY_TYPE_TOTEM = 2, + TOTEM_CATEGORY_TYPE_ROD = 3, + TOTEM_CATEGORY_TYPE_PICK = 21, + TOTEM_CATEGORY_TYPE_STONE = 22, + TOTEM_CATEGORY_TYPE_HAMMER = 23, + TOTEM_CATEGORY_TYPE_SPANNER = 24 +}; + +#endif diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp new file mode 100644 index 000000000..ca9951b2d --- /dev/null +++ b/src/shared/Database/DBCStores.cpp @@ -0,0 +1,637 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "DBCStores.h" +//#include "DataStore.h" +#include "Policies/SingletonImp.h" +#include "Log.h" +#include "ProgressBar.h" + +#include "DBCfmt.cpp" + +#include + +typedef std::map AreaFlagByAreaID; +typedef std::map AreaFlagByMapID; + +DBCStorage sAreaStore(AreaTableEntryfmt); +static AreaFlagByAreaID sAreaFlagByAreaID; +static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files + +DBCStorage sAreaTriggerStore(AreaTriggerEntryfmt); +DBCStorage sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); +DBCStorage sBattlemasterListStore(BattlemasterListEntryfmt); +DBCStorage sCharTitlesStore(CharTitlesEntryfmt); +DBCStorage sChatChannelsStore(ChatChannelsEntryfmt); +DBCStorage sChrClassesStore(ChrClassesEntryfmt); +DBCStorage sChrRacesStore(ChrRacesEntryfmt); +DBCStorage sCreatureDisplayInfoStore(CreatureDisplayInfofmt); +DBCStorage sCreatureFamilyStore(CreatureFamilyfmt); +DBCStorage sCreatureSpellDataStore(CreatureSpellDatafmt); + +DBCStorage sDurabilityQualityStore(DurabilityQualityfmt); +DBCStorage sDurabilityCostsStore(DurabilityCostsfmt); + +DBCStorage sEmotesTextStore(EmoteEntryfmt); + +typedef std::map FactionTeamMap; +static FactionTeamMap sFactionTeamMap; +DBCStorage sFactionStore(FactionEntryfmt); +DBCStorage sFactionTemplateStore(FactionTemplateEntryfmt); + +DBCStorage sGemPropertiesStore(GemPropertiesEntryfmt); + +DBCStorage sGtCombatRatingsStore(GtCombatRatingsfmt); +DBCStorage sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt); +DBCStorage sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt); +DBCStorage sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt); +DBCStorage sGtChanceToSpellCritStore(GtChanceToSpellCritfmt); +DBCStorage sGtOCTRegenHPStore(GtOCTRegenHPfmt); +//DBCStorage sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently +DBCStorage sGtRegenHPPerSptStore(GtRegenHPPerSptfmt); +DBCStorage sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); +DBCStorage sItemStore(Itemfmt); +//DBCStorage sItemCondExtCostsStore(ItemCondExtCostsEntryfmt); +//DBCStorage sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently +DBCStorage sItemExtendedCostStore(ItemExtendedCostEntryfmt); +DBCStorage sItemRandomPropertiesStore(ItemRandomPropertiesfmt); +DBCStorage sItemRandomSuffixStore(ItemRandomSuffixfmt); +DBCStorage sItemSetStore(ItemSetEntryfmt); + +DBCStorage sLockStore(LockEntryfmt); + +DBCStorage sMailTemplateStore(MailTemplateEntryfmt); +DBCStorage sMapStore(MapEntryfmt); + +DBCStorage sQuestSortStore(QuestSortEntryfmt); + +DBCStorage sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); + +DBCStorage sSkillLineStore(SkillLinefmt); +DBCStorage sSkillLineAbilityStore(SkillLineAbilityfmt); + +DBCStorage sSoundEntriesStore(SoundEntriesfmt); + +DBCStorage sSpellItemEnchantmentStore(SpellItemEnchantmentfmt); +DBCStorage sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt); +DBCStorage sSpellStore(SpellEntryfmt); +SpellCategoryStore sSpellCategoryStore; +PetFamilySpellsStore sPetFamilySpellsStore; + +DBCStorage sSpellCastTimesStore(SpellCastTimefmt); +DBCStorage sSpellDurationStore(SpellDurationfmt); +DBCStorage sSpellFocusObjectStore(SpellFocusObjectfmt); +DBCStorage sSpellRadiusStore(SpellRadiusfmt); +DBCStorage sSpellRangeStore(SpellRangefmt); +DBCStorage sSpellShapeshiftStore(SpellShapeshiftfmt); +DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); +DBCStorage sTalentStore(TalentEntryfmt); +TalentSpellPosMap sTalentSpellPosMap; +DBCStorage sTalentTabStore(TalentTabEntryfmt); + +// store absolute bit position for first rank for talent inspect +typedef std::map TalentInspectMap; +static TalentInspectMap sTalentPosInInspect; +static TalentInspectMap sTalentTabSizeInInspect; +static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3]; + +DBCStorage sTaxiNodesStore(TaxiNodesEntryfmt); +TaxiMask sTaxiNodesMask; + +// DBC used only for initialization sTaxiPathSetBySource at startup. +TaxiPathSetBySource sTaxiPathSetBySource; +DBCStorage sTaxiPathStore(TaxiPathEntryfmt); + +// DBC used only for initialization sTaxiPathSetBySource at startup. +TaxiPathNodesByPath sTaxiPathNodesByPath; + +static DBCStorage sTaxiPathNodeStore(TaxiPathNodeEntryfmt); +DBCStorage sTotemCategoryStore(TotemCategoryEntryfmt); +DBCStorage sWorldMapAreaStore(WorldMapAreaEntryfmt); +DBCStorage sWorldSafeLocsStore(WorldSafeLocsEntryfmt); + +typedef std::list StoreProblemList; + +static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, std::string filename) +{ + sLog.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize); + + // assert must fail after function call + return false; +} + +template +inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage& storage, std::string dbc_path, std::string filename) +{ + // compatibility format and C++ structure sizes + assert(DBCFile::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFile::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename)); + + std::string dbc_filename = dbc_path + filename; + if(storage.Load(dbc_filename.c_str())) + { + bar.step(); + for(uint8 i = 0; i < MAX_LOCALE; ++i) + { + if(!(availableDbcLocales & (1 << i))) + continue; + + std::string dbc_filename_loc = dbc_path + localeNames[i] + "/" + filename; + if(!storage.LoadStringsFrom(dbc_filename_loc.c_str())) + availableDbcLocales &= ~(1<DBC records + sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); + + // fill MapId->DBC records ( skip sub zones and continents ) + if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 ) + sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); + } + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc"); + for (uint32 i=0;iteam) + { + SimpleFactionsList &flist = sFactionTeamMap[faction->team]; + flist.push_back(i); + } + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc"); + for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) + { + SpellEntry const * spell = sSpellStore.LookupEntry(i); + if(spell && spell->Category) + sSpellCategoryStore[spell->Category].insert(i); + + // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields + // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view + #if MANGOS_ENDIAN == MANGOS_BIGENDIAN + std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1)); + #endif + } + + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + { + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); + + if(!skillLine) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); + + if(spellInfo && (spellInfo->Attributes & 0x1D0) == 0x1D0) + { + for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) + { + CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); + if(!cFamily) + continue; + + if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) + continue; + + sPetFamilySpellsStore[i].insert(spellInfo->Id); + } + } + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); + + // create talent spells set + for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) continue; + for (int j = 0; j < 5; j++) + if(talentInfo->RankID[j]) + sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); + + // preper fast data access to bit pos of talent ranks for use at inspecting + { + // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect + // store in with (row,col,talent)->size key for correct sorting by (row,col) + typedef std::map TalentBitSize; + TalentBitSize sTalentBitSize; + for(uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + if(!talentTabInfo) + continue; + + // find talent rank + uint32 curtalent_maxrank = 0; + for(uint32 k = 5; k > 0; --k) + { + if(talentInfo->RankID[k-1]) + { + curtalent_maxrank = k; + break; + } + } + + sTalentBitSize[(talentInfo->Row<<24) + (talentInfo->Col<<16)+talentInfo->TalentID] = curtalent_maxrank; + sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; + } + + // now have all max ranks (and then bit amount used for store talent ranks in inspect) + for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) + { + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId ); + if(!talentTabInfo) + continue; + + // store class talent tab pages + uint32 cls = 1; + for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < 12 /*MAX_CLASSES*/;m <<=1, ++cls) {} + + sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; + + // add total amount bits for first rank starting from talent tab first talent rank pos. + uint32 pos = 0; + for(TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) + { + uint32 talentId = itr->first & 0xFFFF; + TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId ); + if(!talentInfo) + continue; + + if(talentInfo->TalentTab != talentTabId) + continue; + + sTalentPosInInspect[talentId] = pos; + pos+= itr->second; + } + } + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); + + // Initialize global taxinodes mask + memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); + for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) + { + if(sTaxiNodesStore.LookupEntry(i)) + { + uint8 field = (uint8)((i - 1) / 32); + uint32 submask = 1<<((i-1)%32); + sTaxiNodesMask[field] |= submask; + } + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); + for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) + if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) + sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); + uint32 pathCount = sTaxiPathStore.GetNumRows(); + + //## TaxiPathNode.dbc ## Loaded only for initialization different structures + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); + // Calculate path nodes count + std::vector pathLength; + pathLength.resize(pathCount); // 0 and some other indexes not used + for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) + if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) + ++pathLength[entry->path]; + // Set path length + sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used + for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) + sTaxiPathNodesByPath[i].resize(pathLength[i]); + // fill data + for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) + if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) + sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay); + sTaxiPathNodeStore.Clear(); + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); + + // error checks + if(bad_dbc_files.size() >= DBCFilesCount ) + { + sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); + exit(1); + } + else if(!bad_dbc_files.empty() ) + { + std::string str; + for(std::list::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) + str += *i + "\n"; + + sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",bad_dbc_files.size(),DBCFilesCount,str.c_str()); + exit(1); + } + + // check at up-to-date DBC files (53085 is last added spell in 2.4.3) + // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3) + // check at up-to-date DBC files (598 is last map added in 2.4.3) + // check at up-to-date DBC files (1127 is last gem property added in 2.4.3) + // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3) + // check at up-to-date DBC files (71 is last char title added in 2.4.3) + // check at up-to-date DBC files (1768 is last area added in 2.4.3) + if( !sSpellStore.LookupEntry(53085) || + !sSkillLineAbilityStore.LookupEntry(17514) || + !sMapStore.LookupEntry(598) || + !sGemPropertiesStore.LookupEntry(1127) || + !sItemExtendedCostStore.LookupEntry(2425) || + !sCharTitlesStore.LookupEntry(71) || + !sAreaStore.LookupEntry(1768) ) + { + sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); + exit(1); + } + + sLog.outString(); + sLog.outString( ">> Loaded %d data stores", DBCFilesCount ); + sLog.outString(); +} + +SimpleFactionsList const* GetFactionTeamList(uint32 faction) +{ + FactionTeamMap::const_iterator itr = sFactionTeamMap.find(faction); + if(itr==sFactionTeamMap.end()) + return NULL; + return &itr->second; +} + +char* GetPetName(uint32 petfamily, uint32 dbclang) +{ + if(!petfamily) + return NULL; + CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(petfamily); + if(!pet_family) + return NULL; + return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL; +} + +TalentSpellPos const* GetTalentSpellPos(uint32 spellId) +{ + TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId); + if(itr==sTalentSpellPosMap.end()) + return NULL; + + return &itr->second; +} + +uint32 GetTalentSpellCost(uint32 spellId) +{ + if(TalentSpellPos const* pos = GetTalentSpellPos(spellId)) + return pos->rank+1; + + return 0; +} + +AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id) +{ + AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id); + if(i == sAreaFlagByAreaID.end()) + return NULL; + + return sAreaStore.LookupEntry(i->second); +} + +AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id) +{ + if(area_flag) + return sAreaStore.LookupEntry(area_flag); + + if(MapEntry const* mapEntry = sMapStore.LookupEntry(map_id)) + return GetAreaEntryByAreaID(mapEntry->linked_zone); + + return NULL; +} + +uint32 GetAreaFlagByMapId(uint32 mapid) +{ + AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid); + if(i == sAreaFlagByMapID.end()) + return 0; + else + return i->second; +} + +uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) +{ + if(mapid != 530) // speed for most cases + return mapid; + + if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) + return wma->virtual_map_id >= 0 ? wma->virtual_map_id : wma->map_id; + + return mapid; +} + +ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) +{ + mapid = GetVirtualMapForMapAndZone(mapid,zoneId); + if(mapid < 2) + return CONTENT_1_60; + + MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); + if(!mapEntry) + return CONTENT_1_60; + + switch(mapEntry->Expansion()) + { + default: return CONTENT_1_60; + case 1: return CONTENT_61_70; + case 2: return CONTENT_71_80; + } +} + +ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) +{ + // not sorted, numbering index from 0 + for(uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) + { + ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i); + if(ch && ch->ChannelID == channel_id) + return ch; + } + return NULL; +} + +bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) +{ + if(requiredTotemCategoryId==0) + return true; + if(itemTotemCategoryId==0) + return false; + + TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId); + if(!itemEntry) + return false; + TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId); + if(!reqEntry) + return false; + + if(itemEntry->categoryType!=reqEntry->categoryType) + return false; + + return (itemEntry->categoryMask & reqEntry->categoryMask)==reqEntry->categoryMask; +} + +void Zone2MapCoordinates(float& x,float& y,uint32 zone) +{ + WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); + + // if not listed then map coordinates (instance) + if(!maEntry) + return; + + std::swap(x,y); // at client map coords swapped + x = x*((maEntry->x2-maEntry->x1)/100)+maEntry->x1; + y = y*((maEntry->y2-maEntry->y1)/100)+maEntry->y1; // client y coord from top to down +} + +void Map2ZoneCoordinates(float& x,float& y,uint32 zone) +{ + WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); + + // if not listed then map coordinates (instance) + if(!maEntry) + return; + + x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100); + y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down + std::swap(x,y); // client have map coords swapped +} + +uint32 GetTalentInspectBitPosInTab(uint32 talentId) +{ + TalentInspectMap::const_iterator itr = sTalentPosInInspect.find(talentId); + if(itr == sTalentPosInInspect.end()) + return 0; + + return itr->second; +} + +uint32 GetTalentTabInspectBitSize(uint32 talentTabId) +{ + TalentInspectMap::const_iterator itr = sTalentTabSizeInInspect.find(talentTabId); + if(itr == sTalentTabSizeInInspect.end()) + return 0; + + return itr->second; +} + +uint32 const* GetTalentTabPages(uint32 cls) +{ + return sTalentTabPages[cls]; +} + +// script support functions +MANGOS_DLL_SPEC DBCStorage const* GetSoundEntriesStore() { return &sSoundEntriesStore; } +MANGOS_DLL_SPEC DBCStorage const* GetSpellStore() { return &sSpellStore; } +MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore() { return &sSpellRangeStore; } diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h new file mode 100644 index 000000000..041281e5a --- /dev/null +++ b/src/shared/Database/DBCStores.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DBCSTORES_H +#define DBCSTORES_H + +#include "Common.h" +//#include "DataStore.h" +#include "dbcfile.h" +#include "DBCStructure.h" + +#include + +typedef std::list SimpleFactionsList; + +SimpleFactionsList const* GetFactionTeamList(uint32 faction); +char* GetPetName(uint32 petfamily, uint32 dbclang); +uint32 GetTalentSpellCost(uint32 spellId); +TalentSpellPos const* GetTalentSpellPos(uint32 spellId); + +AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id); +AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id); +uint32 GetAreaFlagByMapId(uint32 mapid); + +uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); + +enum ContentLevels +{ + CONTENT_1_60 = 0, + CONTENT_61_70, + CONTENT_71_80 +}; +ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); + +ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id); + +bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); + +void Zone2MapCoordinates(float& x,float& y,uint32 zone); +void Map2ZoneCoordinates(float& x,float& y,uint32 zone); + +uint32 GetTalentInspectBitPosInTab(uint32 talentId); +uint32 GetTalentTabInspectBitSize(uint32 talentTabId); +uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls); + +template +class DBCStorage +{ + typedef std::list StringPoolList; + public: + explicit DBCStorage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { } + ~DBCStorage() { Clear(); } + + T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; } + uint32 GetNumRows() const { return nCount; } + char const* GetFormat() const { return fmt; } + uint32 GetFieldCount() const { return fieldCount; } + + bool Load(char const* fn) + { + DBCFile dbc; + // Check if load was sucessful, only then continue + if(!dbc.Load(fn, fmt)) + return false; + + fieldCount = dbc.GetCols(); + m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable); + m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable)); + + // error in dbc file at loading if NULL + return indexTable!=NULL; + } + + bool LoadStringsFrom(char const* fn) + { + // DBC must be already loaded using Load + if(!indexTable) + return false; + + DBCFile dbc; + // Check if load was successful, only then continue + if(!dbc.Load(fn, fmt)) + return false; + + m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable)); + + return true; + } + + void Clear() + { + if (!indexTable) + return; + + delete[] ((char*)indexTable); + indexTable = NULL; + delete[] ((char*)m_dataTable); + m_dataTable = NULL; + + while(!m_stringPoolList.empty()) + { + delete[] m_stringPoolList.front(); + m_stringPoolList.pop_front(); + } + nCount = 0; + } + + private: + uint32 nCount; + uint32 fieldCount; + char const* fmt; + T** indexTable; + T* m_dataTable; + StringPoolList m_stringPoolList; +}; + +extern DBCStorage sAreaStore;// recommend access using functions +extern DBCStorage sAreaTriggerStore; +extern DBCStorage sBankBagSlotPricesStore; +extern DBCStorage sBattlemasterListStore; +//extern DBCStorage sChatChannelsStore; -- accessed using function, no usable index +extern DBCStorage sCharTitlesStore; +extern DBCStorage sChrClassesStore; +extern DBCStorage sChrRacesStore; +extern DBCStorage sCreatureDisplayInfoStore; +extern DBCStorage sCreatureFamilyStore; +extern DBCStorage sCreatureSpellDataStore; +extern DBCStorage sDurabilityCostsStore; +extern DBCStorage sDurabilityQualityStore; +extern DBCStorage sEmotesTextStore; +extern DBCStorage sFactionStore; +extern DBCStorage sFactionTemplateStore; +extern DBCStorage sGemPropertiesStore; + +extern DBCStorage sGtCombatRatingsStore; +extern DBCStorage sGtChanceToMeleeCritBaseStore; +extern DBCStorage sGtChanceToMeleeCritStore; +extern DBCStorage sGtChanceToSpellCritBaseStore; +extern DBCStorage sGtChanceToSpellCritStore; +extern DBCStorage sGtOCTRegenHPStore; +//extern DBCStorage sGtOCTRegenMPStore; -- not used currently +extern DBCStorage sGtRegenHPPerSptStore; +extern DBCStorage sGtRegenMPPerSptStore; +extern DBCStorage sItemStore; +//extern DBCStorage sItemDisplayInfoStore; -- not used currently +extern DBCStorage sItemExtendedCostStore; +extern DBCStorage sItemRandomPropertiesStore; +extern DBCStorage sItemRandomSuffixStore; +extern DBCStorage sItemSetStore; +extern DBCStorage sLockStore; +extern DBCStorage sMailTemplateStore; +extern DBCStorage sMapStore; +extern DBCStorage sQuestSortStore; +extern DBCStorage sRandomPropertiesPointsStore; +extern DBCStorage sSkillLineStore; +extern DBCStorage sSkillLineAbilityStore; +extern DBCStorage sSoundEntriesStore; +extern DBCStorage sSpellCastTimesStore; +extern DBCStorage sSpellDurationStore; +extern DBCStorage sSpellFocusObjectStore; +extern DBCStorage sSpellItemEnchantmentStore; +extern DBCStorage sSpellItemEnchantmentConditionStore; +extern SpellCategoryStore sSpellCategoryStore; +extern PetFamilySpellsStore sPetFamilySpellsStore; +extern DBCStorage sSpellRadiusStore; +extern DBCStorage sSpellRangeStore; +extern DBCStorage sSpellShapeshiftStore; +extern DBCStorage sSpellStore; +extern DBCStorage sStableSlotPricesStore; +extern DBCStorage sTalentStore; +extern DBCStorage sTalentTabStore; +extern DBCStorage sTaxiNodesStore; +extern DBCStorage sTaxiPathStore; +extern TaxiMask sTaxiNodesMask; +extern TaxiPathSetBySource sTaxiPathSetBySource; +extern TaxiPathNodesByPath sTaxiPathNodesByPath; +extern DBCStorage sTotemCategoryStore; +//extern DBCStorage sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates +extern DBCStorage sWorldSafeLocsStore; + +void LoadDBCStores(std::string dataPath); + +// script support functions +MANGOS_DLL_SPEC DBCStorage const* GetSoundEntriesStore(); +MANGOS_DLL_SPEC DBCStorage const* GetSpellStore(); +MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore(); +#endif diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h new file mode 100644 index 000000000..1e8698e5f --- /dev/null +++ b/src/shared/Database/DBCStructure.h @@ -0,0 +1,868 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DBCSTRUCTURE_H +#define DBCSTRUCTURE_H + +#include "DBCEnums.h" +#include "Platform/Define.h" + +#include +#include +#include + +// Structures using to access raw DBC data and required packing to portability + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct AreaTableEntry +{ + uint32 ID; // 0 + uint32 mapid; // 1 + uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area + uint32 exploreFlag; // 3, main index + uint32 flags; // 4, unknown value but 312 for all cities + // 5-9 unused + int32 area_level; // 10 + char* area_name[16]; // 11-26 + // 27, string flags, unused + uint32 team; // 28 +}; + +struct AreaTriggerEntry +{ + uint32 id; // 0 + uint32 mapid; // 1 + float x; // 2 + float y; // 3 + float z; // 4 + float radius; // 5 + float box_x; // 6 extent x edge + float box_y; // 7 extent y edge + float box_z; // 8 extent z edge + float box_orientation; // 9 extent rotation by about z axis +}; + +struct BankBagSlotPricesEntry +{ + uint32 ID; + uint32 price; +}; + +struct BattlemasterListEntry +{ + uint32 id; // 0 + uint32 mapid[3]; // 1-3 mapid + // 4-8 unused + uint32 type; // 9 (3 - BG, 4 - arena) + uint32 minlvl; // 10 + uint32 maxlvl; // 11 + uint32 maxplayersperteam; // 12 + // 13-14 unused + char* name[16]; // 15-30 + // 31 string flag, unused + // 32 unused +}; + +struct CharTitlesEntry +{ + uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() + //uint32 unk1; // 1 flags? + //char* name[16]; // 2-17, unused + // 18 string flag, unused + //char* name2[16]; // 19-34, unused + // 35 string flag, unused + uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<